summaryrefslogtreecommitdiffstats
path: root/include/linux/irqreturn.h
blob: 881883c2009dfe0b2100697d9bc15ed2d344765f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* irqreturn.h */
#ifndef _LINUX_IRQRETURN_H
#define _LINUX_IRQRETURN_H

/*
 * For 2.4.x compatibility, 2.4.x can use
 *
 *	typedef void irqreturn_t;
 *	#define IRQ_NONE
 *	#define IRQ_HANDLED
 *	#define IRQ_RETVAL(x)
 *
 * To mix old-style and new-style irq handler returns.
 *
 * IRQ_NONE means we didn't handle it.
 * IRQ_HANDLED means that we did have a valid interrupt and handled it.
 * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
 */
typedef int irqreturn_t;

#define IRQ_NONE	(0)
#define IRQ_HANDLED	(1)
#define IRQ_RETVAL(x)	((x) != 0)

#endif
e00ba0d73def6645d0f2fa906ee3e8'>drivers/acpi/Kconfig10
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c130
-rw-r--r--drivers/acpi/acpi_extlog.c56
-rw-r--r--drivers/acpi/acpi_lpss.c10
-rw-r--r--drivers/acpi/acpi_pnp.c10
-rw-r--r--drivers/acpi/acpi_processor.c2
-rw-r--r--drivers/acpi/acpica/Makefile10
-rw-r--r--drivers/acpi/acpica/acapps.h9
-rw-r--r--drivers/acpi/acpica/acdebug.h3
-rw-r--r--drivers/acpi/acpica/acglobal.h8
-rw-r--r--drivers/acpi/acpica/aclocal.h18
-rw-r--r--drivers/acpi/acpica/acpredef.h16
-rw-r--r--drivers/acpi/acpica/acutils.h48
-rw-r--r--drivers/acpi/acpica/evgpe.c32
-rw-r--r--drivers/acpi/acpica/evxfgpe.c61
-rw-r--r--drivers/acpi/acpica/exdebug.c11
-rw-r--r--drivers/acpi/acpica/exdump.c6
-rw-r--r--drivers/acpi/acpica/exfield.c26
-rw-r--r--drivers/acpi/acpica/hwregs.c3
-rw-r--r--drivers/acpi/acpica/nsobject.c10
-rw-r--r--drivers/acpi/acpica/utbuffer.c128
-rw-r--r--drivers/acpi/acpica/utcopy.c6
-rw-r--r--drivers/acpi/acpica/utdebug.c26
-rw-r--r--drivers/acpi/acpica/utdecode.c32
-rw-r--r--drivers/acpi/acpica/utfileio.c331
-rw-r--r--drivers/acpi/acpica/utglobal.c146
-rw-r--r--drivers/acpi/acpica/uthex.c100
-rw-r--r--drivers/acpi/acpica/utinit.c145
-rw-r--r--drivers/acpi/acpica/utprint.c664
-rw-r--r--drivers/acpi/acpica/utuuid.c96
-rw-r--r--drivers/acpi/apei/Kconfig8
-rw-r--r--drivers/acpi/apei/apei-base.c13
-rw-r--r--drivers/acpi/apei/apei-internal.h10
-rw-r--r--drivers/acpi/apei/ghes.c205
-rw-r--r--drivers/acpi/apei/hest.c29
-rw-r--r--drivers/acpi/battery.c40
-rw-r--r--drivers/acpi/blacklist.c68
-rw-r--r--drivers/acpi/bus.c3
-rw-r--r--drivers/acpi/button.c25
-rw-r--r--drivers/acpi/device_pm.c148
-rw-r--r--drivers/acpi/ec.c164
-rw-r--r--drivers/acpi/internal.h7
-rw-r--r--drivers/acpi/osl.c4
-rw-r--r--drivers/acpi/pci_root.c2
-rw-r--r--drivers/acpi/processor_core.c200
-rw-r--r--drivers/acpi/processor_pdc.c206
-rw-r--r--drivers/acpi/resource.c10
-rw-r--r--drivers/acpi/scan.c33
-rw-r--r--drivers/acpi/sleep.c5
-rw-r--r--drivers/acpi/video.c142
-rw-r--r--drivers/acpi/video_detect.c8
-rw-r--r--drivers/amba/tegra-ahb.c3
-rw-r--r--drivers/ata/Kconfig10
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/acard-ahci.c2
-rw-r--r--drivers/ata/ahci.c4
-rw-r--r--drivers/ata/ahci.h21
-rw-r--r--drivers/ata/ahci_da850.c3
-rw-r--r--drivers/ata/ahci_imx.c225
-rw-r--r--drivers/ata/ahci_mvebu.c3
-rw-r--r--drivers/ata/ahci_platform.c8
-rw-r--r--drivers/ata/ahci_st.c4
-rw-r--r--drivers/ata/ahci_sunxi.c8
-rw-r--r--drivers/ata/ahci_tegra.c376
-rw-r--r--drivers/ata/ahci_xgene.c89
-rw-r--r--drivers/ata/libahci.c26
-rw-r--r--drivers/ata/libahci_platform.c212
-rw-r--r--drivers/ata/libata-core.c84
-rw-r--r--drivers/ata/libata-eh.c9
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_ep93xx.c2
-rw-r--r--drivers/ata/pata_samsung_cf.c13
-rw-r--r--drivers/ata/sata_fsl.c5
-rw-r--r--drivers/ata/sata_highbank.c2
-rw-r--r--drivers/ata/sata_sil24.c4
-rw-r--r--drivers/atm/eni.c4
-rw-r--r--drivers/base/Kconfig29
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/component.c192
-rw-r--r--drivers/base/devres.c55
-rw-r--r--drivers/base/dma-contiguous.c220
-rw-r--r--drivers/base/firmware_class.c77
-rw-r--r--drivers/base/memory.c30
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/platform.c74
-rw-r--r--drivers/base/power/main.c5
-rw-r--r--drivers/base/regmap/regmap.c13
-rw-r--r--drivers/base/reservation.c39
-rw-r--r--drivers/bcma/Makefile1
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c2
-rw-r--r--drivers/bcma/driver_gpio.c1
-rw-r--r--drivers/bcma/driver_pcie2.c175
-rw-r--r--drivers/bcma/host_pci.c2
-rw-r--r--drivers/bcma/main.c8
-rw-r--r--drivers/bcma/scan.c22
-rw-r--r--drivers/bcma/sprom.c43
-rw-r--r--drivers/block/drbd/drbd_nl.c6
-rw-r--r--drivers/block/zram/zram_drv.c88
-rw-r--r--drivers/block/zram/zram_drv.h29
-rw-r--r--drivers/bluetooth/Kconfig12
-rw-r--r--drivers/bluetooth/ath3k.c37
-rw-r--r--drivers/bluetooth/btmrvl_drv.h4
-rw-r--r--drivers/bluetooth/btmrvl_main.c73
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c21
-rw-r--r--drivers/bluetooth/btmrvl_sdio.h2
-rw-r--r--drivers/bluetooth/btusb.c222
-rw-r--r--drivers/bluetooth/hci_h5.c5
-rw-r--r--drivers/bluetooth/hci_ldisc.c25
-rw-r--r--drivers/bluetooth/hci_uart.h1
-rw-r--r--drivers/bluetooth/hci_vhci.c34
-rw-r--r--drivers/bus/arm-cci.c3
-rw-r--r--drivers/bus/brcmstb_gisb.c6
-rw-r--r--drivers/bus/imx-weim.c4
-rw-r--r--drivers/char/agp/frontend.c15
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/dsp56k.c2
-rw-r--r--drivers/char/hangcheck-timer.c33
-rw-r--r--drivers/char/hw_random/core.c114
-rw-r--r--drivers/char/hw_random/virtio-rng.c10
-rw-r--r--drivers/char/i8k.c127
-rw-r--r--drivers/char/pcmcia/synclink_cs.c4
-rw-r--r--drivers/char/random.c332
-rw-r--r--drivers/char/tpm/tpm-interface.c73
-rw-r--r--drivers/char/tpm/tpm_eventlog.c4
-rw-r--r--drivers/char/tpm/tpm_i2c_stm_st33.c1
-rw-r--r--drivers/char/tpm/tpm_tis.c31
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c1
-rw-r--r--drivers/clk/Kconfig7
-rw-r--r--drivers/clk/Makefile5
-rw-r--r--drivers/clk/at91/clk-main.c1
-rw-r--r--drivers/clk/clk-clps711x.c192
-rw-r--r--drivers/clk/clk-composite.c79
-rw-r--r--drivers/clk/clk-conf.c144
-rw-r--r--drivers/clk/clk-palmas.c307
-rw-r--r--drivers/clk/clk-ppc-corenet.c2
-rw-r--r--drivers/clk/clk-s2mps11.c40
-rw-r--r--drivers/clk/clk.c134
-rw-r--r--drivers/clk/clkdev.c5
-rw-r--r--drivers/clk/mvebu/clk-cpu.c80
-rw-r--r--drivers/clk/qcom/Kconfig25
-rw-r--r--drivers/clk/qcom/Makefile3
-rw-r--r--drivers/clk/qcom/clk-pll.c15
-rw-r--r--drivers/clk/qcom/clk-pll.h2
-rw-r--r--drivers/clk/qcom/clk-rcg.c51
-rw-r--r--drivers/clk/qcom/clk-rcg.h1
-rw-r--r--drivers/clk/qcom/common.c39
-rw-r--r--drivers/clk/qcom/common.h6
-rw-r--r--drivers/clk/qcom/gcc-apq8084.c3611
-rw-r--r--drivers/clk/qcom/gcc-ipq806x.c2424
-rw-r--r--drivers/clk/qcom/gcc-msm8960.c583
-rw-r--r--drivers/clk/qcom/mmcc-apq8084.c3352
-rw-r--r--drivers/clk/qcom/mmcc-msm8960.c528
-rw-r--r--drivers/clk/qcom/mmcc-msm8974.c10
-rw-r--r--drivers/clk/rockchip/Makefile6
-rw-r--r--drivers/clk/rockchip/clk-pll.c431
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c672
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c717
-rw-r--r--drivers/clk/rockchip/clk.c244
-rw-r--r--drivers/clk/rockchip/clk.h347
-rw-r--r--drivers/clk/rockchip/softrst.c118
-rw-r--r--drivers/clk/samsung/Makefile2
-rw-r--r--drivers/clk/samsung/clk-exynos-clkout.c153
-rw-r--r--drivers/clk/samsung/clk-exynos3250.c43
-rw-r--r--drivers/clk/samsung/clk-exynos4.c247
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c6
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5410.c2
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c152
-rw-r--r--drivers/clk/samsung/clk-exynos5440.c4
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c11
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c2
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c2
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c8
-rw-r--r--drivers/clk/samsung/clk-s5pv210-audss.c241
-rw-r--r--drivers/clk/samsung/clk-s5pv210.c856
-rw-r--r--drivers/clk/samsung/clk.c21
-rw-r--r--drivers/clk/samsung/clk.h4
-rw-r--r--drivers/clk/spear/spear1310_clock.c6
-rw-r--r--drivers/clk/spear/spear1340_clock.c2
-rw-r--r--drivers/clk/spear/spear3xx_clock.c16
-rw-r--r--drivers/clk/st/Makefile2
-rw-r--r--drivers/clk/st/clk-flexgen.c331
-rw-r--r--drivers/clk/st/clkgen-fsyn.c223
-rw-r--r--drivers/clk/st/clkgen-mux.c12
-rw-r--r--drivers/clk/st/clkgen-pll.c94
-rw-r--r--drivers/clk/sunxi/Makefile4
-rw-r--r--drivers/clk/sunxi/clk-a20-gmac.c2
-rw-r--r--drivers/clk/sunxi/clk-factors.c2
-rw-r--r--drivers/clk/sunxi/clk-factors.h1
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0-gates.c78
-rw-r--r--drivers/clk/sunxi/clk-sun6i-apb0.c2
-rw-r--r--drivers/clk/sunxi/clk-sun6i-ar100.c4
-rw-r--r--drivers/clk/sunxi/clk-sun8i-apb0.c68
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c129
-rw-r--r--drivers/clk/tegra/clk-periph-gate.c3
-rw-r--r--drivers/clk/tegra/clk-pll.c19
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c4
-rw-r--r--drivers/clk/tegra/clk-tegra114.c31
-rw-r--r--drivers/clk/tegra/clk-tegra124.c10
-rw-r--r--drivers/clk/tegra/clk-tegra30.c5
-rw-r--r--drivers/clk/tegra/clk.c9
-rw-r--r--drivers/clk/ti/apll.c8
-rw-r--r--drivers/clk/ti/clk-7xx.c18
-rw-r--r--drivers/clk/ti/dpll.c5
-rw-r--r--drivers/clk/ti/mux.c2
-rw-r--r--drivers/clk/versatile/Makefile3
-rw-r--r--drivers/clk/versatile/clk-versatile.c (renamed from drivers/clk/versatile/clk-integrator.c)38
-rw-r--r--drivers/clocksource/Kconfig14
-rw-r--r--drivers/clocksource/Makefile3
-rw-r--r--drivers/clocksource/arm_global_timer.c2
-rw-r--r--drivers/clocksource/clps711x-timer.c131
-rw-r--r--drivers/clocksource/exynos_mct.c75
-rw-r--r--drivers/clocksource/mtk_timer.c261
-rw-r--r--drivers/clocksource/pxa_timer.c227
-rw-r--r--drivers/clocksource/sh_cmt.c233
-rw-r--r--drivers/clocksource/sh_mtu2.c146
-rw-r--r--drivers/clocksource/sh_tmu.c127
-rw-r--r--drivers/clocksource/tegra20_timer.c13
-rw-r--r--drivers/clocksource/timer-marco.c3
-rw-r--r--drivers/clocksource/timer-prima2.c3
-rw-r--r--drivers/connector/cn_proc.c36
-rw-r--r--drivers/cpufreq/Kconfig.arm3
-rw-r--r--drivers/cpufreq/Makefile2
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c7
-rw-r--r--drivers/cpufreq/cpufreq.c68
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c11
-rw-r--r--drivers/cpufreq/freq_table.c12
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c35
-rw-r--r--drivers/cpufreq/intel_pstate.c164
-rw-r--r--drivers/cpufreq/loongson2_cpufreq.c6
-rw-r--r--drivers/cpufreq/powernow-k6.c1
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c18
-rw-r--r--drivers/cpufreq/s3c2410-cpufreq.c2
-rw-r--r--drivers/cpufreq/s3c2412-cpufreq.c3
-rw-r--r--drivers/cpufreq/s3c2440-cpufreq.c3
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c1
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c131
-rw-r--r--drivers/cpufreq/sa1110-cpufreq.c2
-rw-r--r--drivers/cpuidle/Kconfig7
-rw-r--r--drivers/cpuidle/Kconfig.arm15
-rw-r--r--drivers/cpuidle/Makefile2
-rw-r--r--drivers/cpuidle/cpuidle-armada-370-xp.c93
-rw-r--r--drivers/cpuidle/cpuidle-big_little.c12
-rw-r--r--drivers/cpuidle/cpuidle-mvebu-v7.c150
-rw-r--r--drivers/cpuidle/cpuidle-powernv.c16
-rw-r--r--drivers/cpuidle/cpuidle.c2
-rw-r--r--drivers/cpuidle/driver.c11
-rw-r--r--drivers/cpuidle/governors/ladder.c4
-rw-r--r--drivers/cpuidle/governors/menu.c3
-rw-r--r--drivers/cpuidle/sysfs.c2
-rw-r--r--drivers/crypto/Kconfig20
-rw-r--r--drivers/crypto/Makefile2
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c2
-rw-r--r--drivers/crypto/atmel-sha.c9
-rw-r--r--drivers/crypto/atmel-tdes.c8
-rw-r--r--drivers/crypto/caam/caamalg.c80
-rw-r--r--drivers/crypto/caam/caamhash.c186
-rw-r--r--drivers/crypto/caam/caamrng.c79
-rw-r--r--drivers/crypto/caam/ctrl.c76
-rw-r--r--drivers/crypto/caam/desc.h1
-rw-r--r--drivers/crypto/caam/intern.h1
-rw-r--r--drivers/crypto/caam/jr.c14
-rw-r--r--drivers/crypto/caam/regs.h105
-rw-r--r--drivers/crypto/ccp/Makefile5
-rw-r--r--drivers/crypto/ccp/ccp-dev.c34
-rw-r--r--drivers/crypto/ccp/ccp-dev.h14
-rw-r--r--drivers/crypto/ccp/ccp-ops.c26
-rw-r--r--drivers/crypto/ccp/ccp-pci.c39
-rw-r--r--drivers/crypto/ccp/ccp-platform.c230
-rw-r--r--drivers/crypto/nx/nx-842.c2
-rw-r--r--drivers/crypto/qat/Kconfig23
-rw-r--r--drivers/crypto/qat/Makefile2
-rw-r--r--drivers/crypto/qat/qat_common/Makefile14
-rw-r--r--drivers/crypto/qat/qat_common/adf_accel_devices.h205
-rw-r--r--drivers/crypto/qat/qat_common/adf_accel_engine.c168
-rw-r--r--drivers/crypto/qat/qat_common/adf_aer.c259
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg.c361
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg.h87
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_common.h100
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_strings.h83
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_user.h94
-rw-r--r--drivers/crypto/qat/qat_common/adf_common_drv.h192
-rw-r--r--drivers/crypto/qat/qat_common/adf_ctl_drv.c490
-rw-r--r--drivers/crypto/qat/qat_common/adf_dev_mgr.c215
-rw-r--r--drivers/crypto/qat/qat_common/adf_init.c388
-rw-r--r--drivers/crypto/qat/qat_common/adf_transport.c567
-rw-r--r--drivers/crypto/qat/qat_common/adf_transport.h63
-rw-r--r--drivers/crypto/qat/qat_common/adf_transport_access_macros.h160
-rw-r--r--drivers/crypto/qat/qat_common/adf_transport_debug.c304
-rw-r--r--drivers/crypto/qat/qat_common/adf_transport_internal.h118
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_fw.h316
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h131
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_fw_la.h404
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_fw_loader_handle.h78
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_hal.h125
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_hw.h305
-rw-r--r--drivers/crypto/qat/qat_common/icp_qat_uclo.h377
-rw-r--r--drivers/crypto/qat/qat_common/qat_algs.c1038
-rw-r--r--drivers/crypto/qat/qat_common/qat_crypto.c284
-rw-r--r--drivers/crypto/qat/qat_common/qat_crypto.h83
-rw-r--r--drivers/crypto/qat/qat_common/qat_hal.c1393
-rw-r--r--drivers/crypto/qat/qat_common/qat_uclo.c1181
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/Makefile8
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_admin.c144
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c214
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h86
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_drv.c449
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_drv.h67
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c159
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/adf_isr.c266
-rw-r--r--drivers/crypto/qat/qat_dh895xcc/qat_admin.c107
-rw-r--r--drivers/crypto/qce/Makefile6
-rw-r--r--drivers/crypto/qce/ablkcipher.c431
-rw-r--r--drivers/crypto/qce/cipher.h68
-rw-r--r--drivers/crypto/qce/common.c438
-rw-r--r--drivers/crypto/qce/common.h102
-rw-r--r--drivers/crypto/qce/core.c286
-rw-r--r--drivers/crypto/qce/core.h68
-rw-r--r--drivers/crypto/qce/dma.c186
-rw-r--r--drivers/crypto/qce/dma.h58
-rw-r--r--drivers/crypto/qce/regs-v5.h334
-rw-r--r--drivers/crypto/qce/sha.c588
-rw-r--r--drivers/crypto/qce/sha.h81
-rw-r--r--drivers/crypto/ux500/cryp/cryp_core.c25
-rw-r--r--drivers/devfreq/Kconfig1
-rw-r--r--drivers/dma-buf/Makefile1
-rw-r--r--drivers/dma-buf/dma-buf.c (renamed from drivers/base/dma-buf.c)168
-rw-r--r--drivers/dma-buf/fence.c431
-rw-r--r--drivers/dma-buf/reservation.c477
-rw-r--r--drivers/dma-buf/seqno-fence.c73
-rw-r--r--drivers/dma/Kconfig18
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/cppi41.c13
-rw-r--r--drivers/dma/edma.c1
-rw-r--r--drivers/dma/imx-sdma.c22
-rw-r--r--drivers/dma/mic_x100_dma.c774
-rw-r--r--drivers/dma/mic_x100_dma.h286
-rw-r--r--drivers/edac/Kconfig8
-rw-r--r--drivers/edac/Makefile1
-rw-r--r--drivers/edac/edac_mc.c3
-rw-r--r--drivers/edac/edac_module.c2
-rw-r--r--drivers/edac/ie31200_edac.c536
-rw-r--r--drivers/edac/mce_amd.c44
-rw-r--r--drivers/edac/x38_edac.c15
-rw-r--r--drivers/extcon/Kconfig38
-rw-r--r--drivers/extcon/Makefile7
-rw-r--r--drivers/extcon/extcon-adc-jack.c1
-rw-r--r--drivers/extcon/extcon-arizona.c74
-rw-r--r--drivers/extcon/extcon-class.c2
-rw-r--r--drivers/extcon/extcon-gpio.c1
-rw-r--r--drivers/extcon/extcon-max14577.c5
-rw-r--r--drivers/extcon/extcon-max77693.c41
-rw-r--r--drivers/extcon/extcon-max8997.c5
-rw-r--r--drivers/extcon/extcon-palmas.c3
-rw-r--r--drivers/extcon/extcon-sm5502.c724
-rw-r--r--drivers/firewire/Kconfig1
-rw-r--r--drivers/firewire/core-cdev.c6
-rw-r--r--drivers/firewire/net.c3
-rw-r--r--drivers/firewire/ohci.c4
-rw-r--r--drivers/firmware/efi/Kconfig6
-rw-r--r--drivers/firmware/efi/Makefile4
-rw-r--r--drivers/firmware/efi/cper.c212
-rw-r--r--drivers/firmware/efi/efi.c62
-rw-r--r--drivers/firmware/efi/efivars.c1
-rw-r--r--drivers/firmware/efi/libstub/Makefile26
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c (renamed from drivers/firmware/efi/arm-stub.c)32
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c (renamed from drivers/firmware/efi/efi-stub-helper.c)74
-rw-r--r--drivers/firmware/efi/libstub/efistub.h42
-rw-r--r--drivers/firmware/efi/libstub/fdt.c (renamed from drivers/firmware/efi/fdt.c)30
-rw-r--r--drivers/firmware/efi/reboot.c56
-rw-r--r--drivers/firmware/efi/runtime-wrappers.c161
-rw-r--r--drivers/firmware/memmap.c6
-rw-r--r--drivers/gpio/Kconfig13
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-crystalcove.c380
-rw-r--r--drivers/gpio/gpio-mcp23s08.c6
-rw-r--r--drivers/gpio/gpio-rcar.c1
-rw-r--r--drivers/gpio/gpio-samsung.c965
-rw-r--r--drivers/gpu/drm/Kconfig3
-rw-r--r--drivers/gpu/drm/Makefile8
-rw-r--r--drivers/gpu/drm/armada/armada_510.c23
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c193
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.h11
-rw-r--r--drivers/gpu/drm/armada/armada_drm.h13
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c245
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c4
-rw-r--r--drivers/gpu/drm/armada/armada_gem.c2
-rw-r--r--drivers/gpu/drm/armada/armada_output.c4
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h2
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c6
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c16
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c2
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c7
-rw-r--r--drivers/gpu/drm/bochs/bochs_kms.c17
-rw-r--r--drivers/gpu/drm/bochs/bochs_mm.c2
-rw-r--r--drivers/gpu/drm/bridge/ptn3460.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c6
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c14
-rw-r--r--drivers/gpu/drm/drm_buffer.c6
-rw-r--r--drivers/gpu/drm/drm_bufs.c17
-rw-r--r--drivers/gpu/drm/drm_context.c102
-rw-r--r--drivers/gpu/drm/drm_crtc.c604
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c1
-rw-r--r--drivers/gpu/drm/drm_debugfs.c182
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c2715
-rw-r--r--[-rwxr-xr-x]drivers/gpu/drm/drm_drv.c1190
-rw-r--r--drivers/gpu/drm/drm_edid.c11
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c5
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c115
-rw-r--r--drivers/gpu/drm/drm_fops.c85
-rw-r--r--drivers/gpu/drm/drm_gem.c29
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c2
-rw-r--r--drivers/gpu/drm/drm_hashtab.c2
-rw-r--r--drivers/gpu/drm/drm_info.c2
-rw-r--r--drivers/gpu/drm/drm_ioctl.c372
-rw-r--r--drivers/gpu/drm/drm_irq.c16
-rw-r--r--drivers/gpu/drm/drm_legacy.h51
-rw-r--r--drivers/gpu/drm/drm_lock.c1
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c14
-rw-r--r--drivers/gpu/drm/drm_of.c67
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c7
-rw-r--r--drivers/gpu/drm/drm_prime.c8
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c9
-rw-r--r--drivers/gpu/drm/drm_rect.c140
-rw-r--r--drivers/gpu/drm/drm_stub.c805
-rw-r--r--drivers/gpu/drm/drm_sysfs.c92
-rw-r--r--drivers/gpu/drm/exynos/Kconfig2
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c117
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c21
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h7
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c285
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c277
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c259
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_rotator.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c38
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c57
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c4
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_dp.c4
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c4
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c4
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c5
-rw-r--r--drivers/gpu/drm/gma500/gtt.c2
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_output.c4
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c1
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c2
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c4
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c4
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c402
-rw-r--r--drivers/gpu/drm/i915/Kconfig12
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/i915_cmd_parser.c3
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c425
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c78
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c70
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h193
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c153
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c149
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c308
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c64
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h5
-rw-r--r--drivers/gpu/drm/i915/i915_gem_render_state.c161
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c148
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c149
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c122
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c650
-rw-r--r--drivers/gpu/drm/i915/i915_params.c15
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h553
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c57
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c5
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c38
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c474
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1508
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c789
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c548
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h157
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c86
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.h1
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.c22
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_cmd.h1
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_panel_vbt.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_pll.c81
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c10
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c37
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c102
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c54
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c27
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c12
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c22
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c176
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c979
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate.h2
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen6.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen7.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen8.c1
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c491
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h92
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c10
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c44
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c212
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c16
-rw-r--r--drivers/gpu/drm/msm/Kconfig1
-rw-r--r--drivers/gpu/drm/msm/adreno/a2xx.xml.h58
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx.xml.h296
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c7
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.h5
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_common.xml.h56
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c14
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h239
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.xml.h4
-rw-r--r--drivers/gpu/drm/msm/dsi/mmss_cc.xml.h4
-rw-r--r--drivers/gpu/drm/msm/dsi/sfpb.xml.h4
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c69
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.xml.h109
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_connector.c27
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c377
-rw-r--r--drivers/gpu/drm/msm/hdmi/qfprom.xml.h4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c25
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h431
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c159
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h25
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp_common.xml.h4
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c91
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c49
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c17
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c12
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c31
-rw-r--r--drivers/gpu/drm/msm/msm_mmu.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/temp.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c20
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c3
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c4
-rw-r--r--drivers/gpu/drm/omapdrm/omap_dmm_tiler.c6
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h7
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c4
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c33
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c21
-rw-r--r--drivers/gpu/drm/panel/Kconfig7
-rw-r--r--drivers/gpu/drm/panel/panel-ld9040.c21
-rw-r--r--drivers/gpu/drm/panel/panel-s6e8aa0.c29
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c203
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c7
-rw-r--r--drivers/gpu/drm/qxl/qxl_irq.c3
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.h4
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c8
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c14
-rw-r--r--drivers/gpu/drm/radeon/atombios_encoders.c26
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c15
-rw-r--r--drivers/gpu/drm/radeon/ci_smc.c39
-rw-r--r--drivers/gpu/drm/radeon/cik.c730
-rw-r--r--drivers/gpu/drm/radeon/cik_sdma.c247
-rw-r--r--drivers/gpu/drm/radeon/cikd.h2
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c16
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c38
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c4
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h1
-rw-r--r--drivers/gpu/drm/radeon/kv_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/ni.c1
-rw-r--r--drivers/gpu/drm/radeon/ni_dma.c178
-rw-r--r--drivers/gpu/drm/radeon/ni_dpm.c2
-rw-r--r--drivers/gpu/drm/radeon/r100.c62
-rw-r--r--drivers/gpu/drm/radeon/r300.c13
-rw-r--r--drivers/gpu/drm/radeon/r600.c25
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon.h150
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c79
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h77
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c93
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c389
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c109
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c273
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c38
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c58
-rw-r--r--drivers/gpu/drm/radeon/radeon_ib.c319
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c39
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h19
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c63
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c287
-rw-r--r--drivers/gpu/drm/radeon/radeon_sa.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_trace.h22
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.c167
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.h71
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_vce.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c333
-rw-r--r--drivers/gpu/drm/radeon/rs400.c14
-rw-r--r--drivers/gpu/drm/radeon/rs600.c17
-rw-r--r--drivers/gpu/drm/radeon/rv515.c5
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c6
-rw-r--r--drivers/gpu/drm/radeon/si.c467
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c172
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.c152
-rw-r--r--drivers/gpu/drm/radeon/si_dpm.h5
-rw-r--r--drivers/gpu/drm/radeon/si_smc.c62
-rw-r--r--drivers/gpu/drm/radeon/sislands_smc.h3
-rw-r--r--drivers/gpu/drm/radeon/trinity_dpm.c11
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c2
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c13
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vgacon.c4
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c6
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c2
-rw-r--r--drivers/gpu/drm/sti/Kconfig14
-rw-r--r--drivers/gpu/drm/sti/Makefile21
-rw-r--r--drivers/gpu/drm/sti/NOTES58
-rw-r--r--drivers/gpu/drm/sti/sti_compositor.c281
-rw-r--r--drivers/gpu/drm/sti/sti_compositor.h90
-rw-r--r--drivers/gpu/drm/sti/sti_drm_crtc.c421
-rw-r--r--drivers/gpu/drm/sti/sti_drm_crtc.h22
-rw-r--r--drivers/gpu/drm/sti/sti_drm_drv.c241
-rw-r--r--drivers/gpu/drm/sti/sti_drm_drv.h29
-rw-r--r--drivers/gpu/drm/sti/sti_drm_plane.c195
-rw-r--r--drivers/gpu/drm/sti/sti_drm_plane.h18
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c549
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.h16
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c794
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c810
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.h88
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c336
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h14
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c211
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h14
-rw-r--r--drivers/gpu/drm/sti/sti_layer.c197
-rw-r--r--drivers/gpu/drm/sti/sti_layer.h123
-rw-r--r--drivers/gpu/drm/sti/sti_mixer.c249
-rw-r--r--drivers/gpu/drm/sti/sti_mixer.h54
-rw-r--r--drivers/gpu/drm/sti/sti_tvout.c648
-rw-r--r--drivers/gpu/drm/sti/sti_vid.c138
-rw-r--r--drivers/gpu/drm/sti/sti_vid.h12
-rw-r--r--drivers/gpu/drm/sti/sti_vtac.c215
-rw-r--r--drivers/gpu/drm/sti/sti_vtg.c366
-rw-r--r--drivers/gpu/drm/sti/sti_vtg.h28
-rw-r--r--drivers/gpu/drm/tegra/dc.c123
-rw-r--r--drivers/gpu/drm/tegra/dc.h5
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c1
-rw-r--r--drivers/gpu/drm/tegra/drm.c216
-rw-r--r--drivers/gpu/drm/tegra/drm.h11
-rw-r--r--drivers/gpu/drm/tegra/dsi.c4
-rw-r--r--drivers/gpu/drm/tegra/fb.c66
-rw-r--r--drivers/gpu/drm/tegra/gem.c7
-rw-r--r--drivers/gpu/drm/tegra/gem.h16
-rw-r--r--drivers/gpu/drm/tegra/gr2d.c1
-rw-r--r--drivers/gpu/drm/tegra/gr3d.c4
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c1
-rw-r--r--drivers/gpu/drm/tegra/output.c6
-rw-r--r--drivers/gpu/drm/tegra/sor.c24
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c15
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.h1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c41
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_slave.c29
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c37
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c20
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c3
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_module.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_object.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c31
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc_dma.c34
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c13
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c5
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c8
-rw-r--r--drivers/gpu/drm/udl/udl_main.c15
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c21
-rw-r--r--drivers/gpu/drm/vmwgfx/Makefile3
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c341
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_context.c38
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c9
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h78
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c227
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c12
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_marker.c44
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_shader.c396
-rw-r--r--drivers/gpu/host1x/job.c22
-rw-r--r--drivers/gpu/vga/vgaarb.c40
-rw-r--r--drivers/hid/Kconfig34
-rw-r--r--drivers/hid/Makefile3
-rw-r--r--drivers/hid/hid-core.c12
-rw-r--r--drivers/hid/hid-cp2112.c111
-rw-r--r--drivers/hid/hid-gt683r.c321
-rw-r--r--drivers/hid/hid-huion.c265
-rw-r--r--drivers/hid/hid-hyperv.c6
-rw-r--r--drivers/hid/hid-ids.h11
-rw-r--r--drivers/hid/hid-lenovo-tpkbd.c462
-rw-r--r--drivers/hid/hid-lenovo.c708
-rw-r--r--drivers/hid/hid-picolcd_cir.c2
-rw-r--r--drivers/hid/hid-picolcd_debugfs.c9
-rw-r--r--drivers/hid/hid-rmi.c69
-rw-r--r--drivers/hid/hid-roccat-lua.c2
-rw-r--r--drivers/hid/hid-sensor-hub.c25
-rw-r--r--drivers/hid/hid-sony.c132
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c15
-rw-r--r--drivers/hid/usbhid/hid-core.c8
-rw-r--r--drivers/hid/usbhid/hid-quirks.c6
-rw-r--r--drivers/hsi/clients/ssi_protocol.c4
-rw-r--r--drivers/hsi/controllers/omap_ssi.c14
-rw-r--r--drivers/hsi/controllers/omap_ssi_port.c15
-rw-r--r--drivers/hv/channel.c6
-rw-r--r--drivers/hv/connection.c8
-rw-r--r--drivers/hv/hv_fcopy.c2
-rw-r--r--drivers/hv/hv_kvp.c17
-rw-r--r--drivers/hv/hv_util.c2
-rw-r--r--drivers/hwmon/Kconfig57
-rw-r--r--drivers/hwmon/Makefile4
-rw-r--r--drivers/hwmon/ad7414.c57
-rw-r--r--drivers/hwmon/ad7418.c133
-rw-r--r--drivers/hwmon/adc128d818.c28
-rw-r--r--drivers/hwmon/adm1021.c189
-rw-r--r--drivers/hwmon/adm1025.c231
-rw-r--r--drivers/hwmon/adm1026.c588
-rw-r--r--drivers/hwmon/adm1029.c211
-rw-r--r--drivers/hwmon/adm1031.c357
-rw-r--r--drivers/hwmon/adm9240.c339
-rw-r--r--drivers/hwmon/ads1015.c2
-rw-r--r--drivers/hwmon/ads7828.c52
-rw-r--r--drivers/hwmon/adt7411.c59
-rw-r--r--drivers/hwmon/adt7462.c142
-rw-r--r--drivers/hwmon/adt7470.c169
-rw-r--r--drivers/hwmon/amc6821.c399
-rw-r--r--drivers/hwmon/asc7621.c14
-rw-r--r--drivers/hwmon/asus_atk0110.c2
-rw-r--r--drivers/hwmon/atxp1.c76
-rw-r--r--drivers/hwmon/da9052-hwmon.c2
-rw-r--r--drivers/hwmon/da9055-hwmon.c2
-rw-r--r--drivers/hwmon/ds620.c60
-rw-r--r--drivers/hwmon/emc1403.c2
-rw-r--r--drivers/hwmon/emc2103.c104
-rw-r--r--drivers/hwmon/emc6w201.c64
-rw-r--r--drivers/hwmon/fam15h_power.c54
-rw-r--r--drivers/hwmon/g760a.c84
-rw-r--r--drivers/hwmon/g762.c78
-rw-r--r--drivers/hwmon/gl518sm.c319
-rw-r--r--drivers/hwmon/gl520sm.c353
-rw-r--r--drivers/hwmon/gpio-fan.c19
-rw-r--r--drivers/hwmon/hih6130.c88
-rw-r--r--drivers/hwmon/htu21.c69
-rw-r--r--drivers/hwmon/ibmaem.c6
-rw-r--r--drivers/hwmon/ibmpowernv.c363
-rw-r--r--drivers/hwmon/lineage-pem.c66
-rw-r--r--drivers/hwmon/lm63.c27
-rw-r--r--drivers/hwmon/lm75.c8
-rw-r--r--drivers/hwmon/lm77.c11
-rw-r--r--drivers/hwmon/lm78.c100
-rw-r--r--drivers/hwmon/lm85.c660
-rw-r--r--drivers/hwmon/lm93.c154
-rw-r--r--drivers/hwmon/ltc2945.c2
-rw-r--r--drivers/hwmon/ltc4222.c2
-rw-r--r--drivers/hwmon/ltc4260.c2
-rw-r--r--drivers/hwmon/max16065.c5
-rw-r--r--drivers/hwmon/max1668.c2
-rw-r--r--drivers/hwmon/max6639.c2
-rw-r--r--drivers/hwmon/max6697.c16
-rw-r--r--drivers/hwmon/nct6775.c14
-rw-r--r--drivers/hwmon/ntc_thermistor.c52
-rw-r--r--drivers/hwmon/pmbus/Kconfig13
-rw-r--r--drivers/hwmon/pmbus/Makefile1
-rw-r--r--drivers/hwmon/pmbus/pmbus.c1
-rw-r--r--drivers/hwmon/pmbus/tps40422.c64
-rw-r--r--drivers/hwmon/powr1220.c391
-rw-r--r--drivers/hwmon/pwm-fan.c193
-rw-r--r--drivers/hwmon/sht21.c82
-rw-r--r--drivers/hwmon/sis5595.c2
-rw-r--r--drivers/hwmon/smm665.c44
-rw-r--r--drivers/hwmon/smsc47m1.c115
-rw-r--r--drivers/hwmon/smsc47m192.c236
-rw-r--r--drivers/hwmon/thmc50.c212
-rw-r--r--drivers/hwmon/tmp103.c206
-rw-r--r--drivers/hwmon/tmp421.c39
-rw-r--r--drivers/hwmon/twl4030-madc-hwmon.c38
-rw-r--r--drivers/hwmon/w83791d.c15
-rw-r--r--drivers/hwmon/w83l786ng.c289
-rw-r--r--drivers/hwmon/wm831x-hwmon.c72
-rw-r--r--drivers/hwmon/wm8350-hwmon.c50
-rw-r--r--drivers/i2c/busses/i2c-cros-ec-tunnel.c17
-rw-r--r--drivers/i2c/busses/i2c-sun6i-p2wi.c1
-rw-r--r--drivers/i2c/i2c-core.c5
-rw-r--r--drivers/i2c/muxes/Kconfig1
-rw-r--r--drivers/ide/Kconfig5
-rw-r--r--drivers/ide/au1xxx-ide.c13
-rw-r--r--drivers/ide/ide-probe.c8
-rw-r--r--drivers/ide/ide_platform.c13
-rw-r--r--drivers/iio/accel/Kconfig12
-rw-r--r--drivers/iio/accel/Makefile1
-rw-r--r--drivers/iio/accel/bma180.c8
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c7
-rw-r--r--drivers/iio/accel/kxcjk-1013.c764
-rw-r--r--drivers/iio/accel/mma8452.c14
-rw-r--r--drivers/iio/accel/st_accel_core.c12
-rw-r--r--drivers/iio/accel/st_accel_i2c.c51
-rw-r--r--drivers/iio/adc/Kconfig19
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/ad7291.c (renamed from drivers/staging/iio/adc/ad7291.c)111
-rw-r--r--drivers/iio/adc/ad7298.c21
-rw-r--r--drivers/iio/adc/ad7476.c5
-rw-r--r--drivers/iio/adc/ad7887.c21
-rw-r--r--drivers/iio/adc/ad799x.c509
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c2
-rw-r--r--drivers/iio/adc/at91_adc.c2
-rw-r--r--drivers/iio/adc/exynos_adc.c335
-rw-r--r--drivers/iio/adc/max1027.c521
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c2
-rw-r--r--drivers/iio/adc/xilinx-xadc-core.c2
-rw-r--r--drivers/iio/adc/xilinx-xadc-events.c6
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c5
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c64
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_i2c.c30
-rw-r--r--drivers/iio/dac/Kconfig10
-rw-r--r--drivers/iio/dac/Makefile1
-rw-r--r--drivers/iio/dac/ad5504.c16
-rw-r--r--drivers/iio/dac/ad5624r_spi.c5
-rw-r--r--drivers/iio/dac/ad5686.c3
-rw-r--r--drivers/iio/dac/ad5791.c29
-rw-r--r--drivers/iio/dac/mcp4922.c216
-rw-r--r--drivers/iio/gyro/adis16260.c124
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c7
-rw-r--r--drivers/iio/gyro/itg3200_core.c101
-rw-r--r--drivers/iio/gyro/st_gyro_core.c12
-rw-r--r--drivers/iio/gyro/st_gyro_i2c.c39
-rw-r--r--drivers/iio/imu/adis16400_buffer.c3
-rw-r--r--drivers/iio/imu/adis16400_core.c78
-rw-r--r--drivers/iio/imu/adis16480.c82
-rw-r--r--drivers/iio/industrialio-buffer.c7
-rw-r--r--drivers/iio/industrialio-core.c4
-rw-r--r--drivers/iio/industrialio-event.c4
-rw-r--r--drivers/iio/industrialio-trigger.c8
-rw-r--r--drivers/iio/inkern.c6
-rw-r--r--drivers/iio/light/Kconfig24
-rw-r--r--drivers/iio/light/Makefile2
-rw-r--r--drivers/iio/light/cm32181.c11
-rw-r--r--drivers/iio/light/gp2ap020a00f.c2
-rw-r--r--drivers/iio/light/hid-sensor-als.c7
-rw-r--r--drivers/iio/light/hid-sensor-prox.c7
-rw-r--r--drivers/iio/light/isl29125.c347
-rw-r--r--drivers/iio/light/tcs3414.c405
-rw-r--r--drivers/iio/light/tcs3472.c11
-rw-r--r--drivers/iio/magnetometer/Kconfig10
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak09911.c326
-rw-r--r--drivers/iio/magnetometer/ak8975.c58
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c209
-rw-r--r--drivers/iio/magnetometer/st_magn_core.c12
-rw-r--r--drivers/iio/magnetometer/st_magn_i2c.c23
-rw-r--r--drivers/iio/pressure/Kconfig10
-rw-r--r--drivers/iio/pressure/Makefile1
-rw-r--r--drivers/iio/pressure/hid-sensor-press.c7
-rw-r--r--drivers/iio/pressure/st_pressure_core.c27
-rw-r--r--drivers/iio/pressure/st_pressure_i2c.c23
-rw-r--r--drivers/iio/pressure/t5403.c275
-rw-r--r--drivers/iio/proximity/as3935.c2
-rw-r--r--drivers/iio/trigger/iio-trig-interrupt.c3
-rw-r--r--drivers/iio/trigger/iio-trig-sysfs.c2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c2
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c126
-rw-r--r--drivers/infiniband/hw/cxgb4/cq.c14
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c210
-rw-r--r--drivers/infiniband/hw/cxgb4/ev.c55
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h42
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c14
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c113
-rw-r--r--drivers/infiniband/hw/cxgb4/t4.h19
-rw-r--r--drivers/infiniband/hw/cxgb4/t4fw_ri_api.h1
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c48
-rw-r--r--drivers/infiniband/hw/mlx5/mad.c6
-rw-r--r--drivers/infiniband/hw/mlx5/main.c295
-rw-r--r--drivers/infiniband/hw/mlx5/mem.c2
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h14
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c48
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c90
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c26
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c4
-rw-r--r--drivers/input/evdev.c7
-rw-r--r--drivers/input/input.c6
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c70
-rw-r--r--drivers/input/keyboard/lm8323.c22
-rw-r--r--drivers/input/keyboard/st-keyscan.c2
-rw-r--r--drivers/input/misc/sirfsoc-onkey.c2
-rw-r--r--drivers/input/misc/sparcspkr.c22
-rw-r--r--drivers/input/mouse/synaptics.c5
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/tablet/wacom_wac.c28
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c5
-rw-r--r--drivers/iommu/Kconfig13
-rw-r--r--drivers/iommu/Makefile2
-rw-r--r--drivers/iommu/amd_iommu.c224
-rw-r--r--drivers/iommu/amd_iommu_init.c38
-rw-r--r--drivers/iommu/amd_iommu_types.h10
-rw-r--r--drivers/iommu/amd_iommu_v2.c107
-rw-r--r--drivers/iommu/arm-smmu.c495
-rw-r--r--drivers/iommu/dmar.c40
-rw-r--r--drivers/iommu/exynos-iommu.c2
-rw-r--r--drivers/iommu/fsl_pamu.c10
-rw-r--r--drivers/iommu/fsl_pamu_domain.c91
-rw-r--r--drivers/iommu/intel-iommu.c874
-rw-r--r--drivers/iommu/intel_irq_remapping.c60
-rw-r--r--drivers/iommu/iommu-sysfs.c134
-rw-r--r--drivers/iommu/iommu.c201
-rw-r--r--drivers/iommu/ipmmu-vmsa.c2
-rw-r--r--drivers/iommu/msm_iommu.c2
-rw-r--r--drivers/iommu/omap-iommu-debug.c114
-rw-r--r--drivers/iommu/omap-iommu.c15
-rw-r--r--drivers/iommu/omap-iommu.h8
-rw-r--r--drivers/iommu/omap-iovmm.c791
-rw-r--r--drivers/iommu/pci.h29
-rw-r--r--drivers/iommu/shmobile-iommu.c2
-rw-r--r--drivers/iommu/tegra-gart.c2
-rw-r--r--drivers/iommu/tegra-smmu.c5
-rw-r--r--drivers/ipack/carriers/tpci200.c2
-rw-r--r--drivers/ipack/devices/ipoctal.c20
-rw-r--r--drivers/irqchip/Kconfig24
-rw-r--r--drivers/irqchip/Makefile6
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c17
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.c254
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.h39
-rw-r--r--drivers/irqchip/irq-atmel-aic.c262
-rw-r--r--drivers/irqchip/irq-atmel-aic5.c353
-rw-r--r--drivers/irqchip/irq-brcmstb-l2.c2
-rw-r--r--drivers/irqchip/irq-crossbar.c168
-rw-r--r--drivers/irqchip/irq-gic-common.c115
-rw-r--r--drivers/irqchip/irq-gic-common.h29
-rw-r--r--drivers/irqchip/irq-gic-v3.c692
-rw-r--r--drivers/irqchip/irq-gic.c68
-rw-r--r--drivers/irqchip/irq-nvic.c13
-rw-r--r--drivers/irqchip/irq-or1k-pic.c182
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c18
-rw-r--r--drivers/irqchip/spear-shirq.c304
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c1
-rw-r--r--drivers/isdn/hisax/l3ni1.c14
-rw-r--r--drivers/isdn/i4l/isdn_net.c7
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c46
-rw-r--r--drivers/isdn/pcbit/drv.c4
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/led-class.c19
-rw-r--r--drivers/leds/led-core.c11
-rw-r--r--drivers/leds/leds-ipaq-micro.c141
-rw-r--r--drivers/leds/leds-lm3530.c20
-rw-r--r--drivers/leds/leds-lm3533.c20
-rw-r--r--drivers/leds/leds-lm355x.c21
-rw-r--r--drivers/leds/leds-lm3642.c30
-rw-r--r--drivers/leds/leds-lp55xx-common.c20
-rw-r--r--drivers/leds/leds-max8997.c16
-rw-r--r--drivers/leds/leds-netxbig.c31
-rw-r--r--drivers/leds/leds-ns2.c16
-rw-r--r--drivers/leds/leds-pca963x.c28
-rw-r--r--drivers/leds/leds-ss4200.c14
-rw-r--r--drivers/leds/leds-wm831x-status.c23
-rw-r--r--drivers/lguest/core.c7
-rw-r--r--drivers/macintosh/via-pmu-backlight.c6
-rw-r--r--drivers/md/dm-bufio.c43
-rw-r--r--drivers/md/dm-cache-metadata.c9
-rw-r--r--drivers/md/dm-cache-target.c13
-rw-r--r--drivers/md/dm-crypt.c4
-rw-r--r--drivers/md/dm-io.c22
-rw-r--r--drivers/md/dm-mpath.c5
-rw-r--r--drivers/md/dm-snap.c10
-rw-r--r--drivers/md/dm-thin-metadata.c9
-rw-r--r--drivers/md/dm-zero.c4
-rw-r--r--drivers/md/dm.c15
-rw-r--r--drivers/md/md.c15
-rw-r--r--drivers/media/Kconfig12
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c14
-rw-r--r--drivers/media/common/siano/Kconfig3
-rw-r--r--drivers/media/common/siano/smsir.c2
-rw-r--r--drivers/media/dvb-core/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c36
-rw-r--r--drivers/media/dvb-core/dvb_frontend.h6
-rw-r--r--drivers/media/dvb-core/dvb_net.c3
-rw-r--r--drivers/media/dvb-core/dvbdev.h4
-rw-r--r--drivers/media/dvb-frontends/Kconfig18
-rw-r--r--drivers/media/dvb-frontends/Makefile7
-rw-r--r--drivers/media/dvb-frontends/af9013.c1
-rw-r--r--drivers/media/dvb-frontends/au8522_decoder.c180
-rw-r--r--drivers/media/dvb-frontends/au8522_priv.h2
-rw-r--r--drivers/media/dvb-frontends/cxd2820r.h6
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_c.c1
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t.c1
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t2.c1
-rw-r--r--drivers/media/dvb-frontends/dib0090.c15
-rw-r--r--drivers/media/dvb-frontends/dib7000m.c5
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c433
-rw-r--r--drivers/media/dvb-frontends/dib7000p.h131
-rw-r--r--drivers/media/dvb-frontends/dib8000.c732
-rw-r--r--drivers/media/dvb-frontends/dib8000.h150
-rw-r--r--drivers/media/dvb-frontends/dib9000.c13
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c228
-rw-r--r--drivers/media/dvb-frontends/drxd.h1
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c3
-rw-r--r--drivers/media/dvb-frontends/m88ds3103.c85
-rw-r--r--drivers/media/dvb-frontends/m88ds3103_priv.h2
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c35
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.c (renamed from drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c)100
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.h (renamed from drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h)0
-rw-r--r--drivers/media/dvb-frontends/si2165.c1040
-rw-r--r--drivers/media/dvb-frontends/si2165.h62
-rw-r--r--drivers/media/dvb-frontends/si2165_priv.h23
-rw-r--r--drivers/media/dvb-frontends/si2168.c278
-rw-r--r--drivers/media/dvb-frontends/si2168_priv.h9
-rw-r--r--drivers/media/dvb-frontends/stb6100_cfg.h42
-rw-r--r--drivers/media/dvb-frontends/stb6100_proc.h34
-rw-r--r--drivers/media/dvb-frontends/stv0367.c9
-rw-r--r--drivers/media/dvb-frontends/tda10071.c12
-rw-r--r--drivers/media/dvb-frontends/tda10071_priv.h1
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.c2
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd_maps.h8
-rw-r--r--drivers/media/dvb-frontends/tda8261_cfg.h30
-rw-r--r--drivers/media/i2c/Kconfig1
-rw-r--r--drivers/media/i2c/adv7180.c1
-rw-r--r--drivers/media/i2c/adv7604.c5
-rw-r--r--drivers/media/i2c/ir-kbd-i2c.c95
-rw-r--r--drivers/media/i2c/mt9v032.c170
-rw-r--r--drivers/media/i2c/noon010pc30.c1
-rw-r--r--drivers/media/i2c/s5k4ecgx.c1
-rw-r--r--drivers/media/i2c/s5k5baf.c2
-rw-r--r--drivers/media/i2c/s5k6a3.c1
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c17
-rw-r--r--drivers/media/i2c/soc_camera/mt9m001.c6
-rw-r--r--drivers/media/i2c/soc_camera/mt9m111.c12
-rw-r--r--drivers/media/i2c/soc_camera/mt9t031.c6
-rw-r--r--drivers/media/i2c/soc_camera/mt9v022.c4
-rw-r--r--drivers/media/i2c/tvp5150.c35
-rw-r--r--drivers/media/media-device.c2
-rw-r--r--drivers/media/parport/bw-qcam.c3
-rw-r--r--drivers/media/parport/c-qcam.c1
-rw-r--r--drivers/media/parport/pms.c1
-rw-r--r--drivers/media/parport/w9966.c1
-rw-r--r--drivers/media/pci/Kconfig1
-rw-r--r--drivers/media/pci/Makefile1
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/pci/bt8xx/bttv-input.c78
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h2
-rw-r--r--drivers/media/pci/cx18/cx18-alsa.h1
-rw-r--r--drivers/media/pci/cx18/cx18-ioctl.c1
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c1
-rw-r--r--drivers/media/pci/cx23885/Kconfig2
-rw-r--r--drivers/media/pci/cx23885/cx23885-417.c8
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c61
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c175
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c11
-rw-r--r--drivers/media/pci/cx23885/cx23885.h2
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c4
-rw-r--r--drivers/media/pci/cx88/cx88-core.c1
-rw-r--r--drivers/media/pci/cx88/cx88-input.c38
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c35
-rw-r--r--drivers/media/pci/dm1105/dm1105.c3
-rw-r--r--drivers/media/pci/ivtv/ivtv-controls.c4
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.c9
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c3
-rw-r--r--drivers/media/pci/ivtv/ivtv-streams.c1
-rw-r--r--drivers/media/pci/meye/meye.c3
-rw-r--r--drivers/media/pci/ngene/ngene-core.c7
-rw-r--r--drivers/media/pci/saa7134/saa7134-core.c1
-rw-r--r--drivers/media/pci/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c86
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c2
-rw-r--r--drivers/media/pci/saa7164/saa7164-dvb.c32
-rw-r--r--drivers/media/pci/solo6x10/Kconfig (renamed from drivers/staging/media/solo6x10/Kconfig)3
-rw-r--r--drivers/media/pci/solo6x10/Makefile (renamed from drivers/staging/media/solo6x10/Makefile)2
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-core.c (renamed from drivers/staging/media/solo6x10/solo6x10-core.c)6
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-disp.c (renamed from drivers/staging/media/solo6x10/solo6x10-disp.c)20
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-eeprom.c (renamed from drivers/staging/media/solo6x10/solo6x10-eeprom.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-enc.c (renamed from drivers/staging/media/solo6x10/solo6x10-enc.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-g723.c (renamed from drivers/staging/media/solo6x10/solo6x10-g723.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-gpio.c (renamed from drivers/staging/media/solo6x10/solo6x10-gpio.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-i2c.c (renamed from drivers/staging/media/solo6x10/solo6x10-i2c.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-jpeg.h (renamed from drivers/staging/media/solo6x10/solo6x10-jpeg.h)6
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-offsets.h (renamed from drivers/staging/media/solo6x10/solo6x10-offsets.h)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-p2m.c (renamed from drivers/staging/media/solo6x10/solo6x10-p2m.c)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-regs.h (renamed from drivers/staging/media/solo6x10/solo6x10-regs.h)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-tw28.c (renamed from drivers/staging/media/solo6x10/solo6x10-tw28.c)5
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-tw28.h (renamed from drivers/staging/media/solo6x10/solo6x10-tw28.h)4
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c (renamed from drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c)207
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2.c (renamed from drivers/staging/media/solo6x10/solo6x10-v4l2.c)9
-rw-r--r--drivers/media/pci/solo6x10/solo6x10.h (renamed from drivers/staging/media/solo6x10/solo6x10.h)30
-rw-r--r--drivers/media/pci/sta2x11/sta2x11_vip.c2
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c10
-rw-r--r--drivers/media/pci/zoran/zr36050.h1
-rw-r--r--drivers/media/platform/Kconfig7
-rw-r--r--drivers/media/platform/arv.c1
-rw-r--r--drivers/media/platform/blackfin/bfin_capture.c9
-rw-r--r--drivers/media/platform/blackfin/ppi.c25
-rw-r--r--drivers/media/platform/coda.c1518
-rw-r--r--drivers/media/platform/coda.h115
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c5
-rw-r--r--drivers/media/platform/davinci/vpbe_display.c1
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c1
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c249
-rw-r--r--drivers/media/platform/davinci/vpif_capture.h11
-rw-r--r--drivers/media/platform/davinci/vpif_display.c5
-rw-r--r--drivers/media/platform/m2m-deinterlace.c7
-rw-r--r--drivers/media/platform/mem2mem_testdev.c1
-rw-r--r--drivers/media/platform/omap/omap_vout.c2
-rw-r--r--drivers/media/platform/s3c-camif/camif-capture.c3
-rw-r--r--drivers/media/platform/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c660
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h32
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c487
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h60
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-regs.h247
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c17
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h11
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c49
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c9
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c24
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c2
-rw-r--r--drivers/media/platform/sh_veu.c2
-rw-r--r--drivers/media/platform/soc_camera/Kconfig18
-rw-r--r--drivers/media/platform/soc_camera/Makefile1
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c90
-rw-r--r--drivers/media/platform/soc_camera/mx1_camera.c866
-rw-r--r--drivers/media/platform/soc_camera/pxa_camera.c81
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c82
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c141
-rw-r--r--drivers/media/platform/vino.c5
-rw-r--r--drivers/media/platform/vivi.c11
-rw-r--r--drivers/media/platform/vsp1/vsp1.h14
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c85
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.h9
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c22
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c42
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h10
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c72
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c107
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c63
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.h6
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c219
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.h11
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c72
-rw-r--r--drivers/media/radio/dsbr100.c1
-rw-r--r--drivers/media/radio/radio-cadet.c1
-rw-r--r--drivers/media/radio/radio-isa.c1
-rw-r--r--drivers/media/radio/radio-keene.c3
-rw-r--r--drivers/media/radio/radio-ma901.c1
-rw-r--r--drivers/media/radio/radio-miropcm20.c304
-rw-r--r--drivers/media/radio/radio-mr800.c3
-rw-r--r--drivers/media/radio/radio-raremono.c1
-rw-r--r--drivers/media/radio/radio-sf16fmi.c1
-rw-r--r--drivers/media/radio/radio-si476x.c1
-rw-r--r--drivers/media/radio/radio-tea5764.c1
-rw-r--r--drivers/media/radio/radio-tea5777.c1
-rw-r--r--drivers/media/radio/radio-timb.c1
-rw-r--r--drivers/media/radio/si470x/radio-si470x-usb.c1
-rw-r--r--drivers/media/radio/si4713/radio-platform-si4713.c1
-rw-r--r--drivers/media/radio/si4713/radio-usb-si4713.c1
-rw-r--r--drivers/media/radio/si4713/si4713.c80
-rw-r--r--drivers/media/radio/si4713/si4713.h9
-rw-r--r--drivers/media/radio/tea575x.c1
-rw-r--r--drivers/media/rc/Kconfig32
-rw-r--r--drivers/media/rc/Makefile5
-rw-r--r--drivers/media/rc/ati_remote.c159
-rw-r--r--drivers/media/rc/ene_ir.c2
-rw-r--r--drivers/media/rc/fintek-cir.c6
-rw-r--r--drivers/media/rc/gpio-ir-recv.c4
-rw-r--r--drivers/media/rc/iguanair.c2
-rw-r--r--drivers/media/rc/img-ir/img-ir-core.c5
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.c31
-rw-r--r--drivers/media/rc/img-ir/img-ir-hw.h8
-rw-r--r--drivers/media/rc/img-ir/img-ir-jvc.c9
-rw-r--r--drivers/media/rc/img-ir/img-ir-nec.c9
-rw-r--r--drivers/media/rc/img-ir/img-ir-raw.c5
-rw-r--r--drivers/media/rc/img-ir/img-ir-raw.h5
-rw-r--r--drivers/media/rc/img-ir/img-ir-sanyo.c9
-rw-r--r--drivers/media/rc/img-ir/img-ir-sharp.c9
-rw-r--r--drivers/media/rc/img-ir/img-ir-sony.c17
-rw-r--r--drivers/media/rc/img-ir/img-ir.h5
-rw-r--r--drivers/media/rc/imon.c20
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c4
-rw-r--r--drivers/media/rc/ir-lirc-codec.c2
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c2
-rw-r--r--drivers/media/rc/ir-nec-decoder.c4
-rw-r--r--drivers/media/rc/ir-rc5-decoder.c85
-rw-r--r--drivers/media/rc/ir-rc5-sz-decoder.c154
-rw-r--r--drivers/media/rc/ir-rc6-decoder.c43
-rw-r--r--drivers/media/rc/ir-sanyo-decoder.c4
-rw-r--r--drivers/media/rc/ir-sharp-decoder.c4
-rw-r--r--drivers/media/rc/ir-sony-decoder.c16
-rw-r--r--drivers/media/rc/ir-xmp-decoder.c225
-rw-r--r--drivers/media/rc/ite-cir.c6
-rw-r--r--drivers/media/rc/keymaps/rc-ati-x10.c92
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c68
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c112
-rw-r--r--drivers/media/rc/keymaps/rc-streamzap.c4
-rw-r--r--drivers/media/rc/mceusb.c33
-rw-r--r--drivers/media/rc/nuvoton-cir.c6
-rw-r--r--drivers/media/rc/rc-core-priv.h20
-rw-r--r--drivers/media/rc/rc-ir-raw.c (renamed from drivers/media/rc/ir-raw.c)12
-rw-r--r--drivers/media/rc/rc-loopback.c2
-rw-r--r--drivers/media/rc/rc-main.c301
-rw-r--r--drivers/media/rc/redrat3.c2
-rw-r--r--drivers/media/rc/st_rc.c2
-rw-r--r--drivers/media/rc/streamzap.c12
-rw-r--r--drivers/media/rc/sunxi-cir.c318
-rw-r--r--drivers/media/rc/ttusbir.c2
-rw-r--r--drivers/media/rc/winbond-cir.c2
-rw-r--r--drivers/media/tuners/Kconfig11
-rw-r--r--drivers/media/tuners/Makefile1
-rw-r--r--drivers/media/tuners/msi001.c (renamed from drivers/staging/media/msi3101/msi001.c)2
-rw-r--r--drivers/media/tuners/r820t.c3
-rw-r--r--drivers/media/tuners/si2157.c257
-rw-r--r--drivers/media/tuners/si2157.h7
-rw-r--r--drivers/media/tuners/si2157_priv.h9
-rw-r--r--drivers/media/tuners/tuner-xc2028.c1
-rw-r--r--drivers/media/tuners/xc4000.c48
-rw-r--r--drivers/media/tuners/xc5000.c164
-rw-r--r--drivers/media/usb/Kconfig7
-rw-r--r--drivers/media/usb/Makefile3
-rw-r--r--drivers/media/usb/airspy/Kconfig10
-rw-r--r--drivers/media/usb/airspy/Makefile1
-rw-r--r--drivers/media/usb/airspy/airspy.c1132
-rw-r--r--drivers/media/usb/au0828/Kconfig8
-rw-r--r--drivers/media/usb/au0828/Makefile4
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c7
-rw-r--r--drivers/media/usb/au0828/au0828-core.c25
-rw-r--r--drivers/media/usb/au0828/au0828-i2c.c37
-rw-r--r--drivers/media/usb/au0828/au0828-input.c386
-rw-r--r--drivers/media/usb/au0828/au0828-video.c62
-rw-r--r--drivers/media/usb/au0828/au0828.h11
-rw-r--r--drivers/media/usb/cpia2/cpia2_v4l.c1
-rw-r--r--drivers/media/usb/cx231xx/Kconfig2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-417.c3
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-avcore.c1
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c403
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-core.c3
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c105
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-input.c22
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c10
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c14
-rw-r--r--drivers/media/usb/cx231xx/cx231xx.h2
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig1
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c18
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c68
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c3
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c25
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c14
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c34
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c14
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig3
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c233
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h2
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c45
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c636
-rw-r--r--drivers/media/usb/dvb-usb/dibusb.h2
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c21
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c2
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c8
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c2
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c6
-rw-r--r--drivers/media/usb/em28xx/em28xx-camera.c4
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c3
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c40
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c6
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c106
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c116
-rw-r--r--drivers/media/usb/em28xx/em28xx.h8
-rw-r--r--drivers/media/usb/go7007/Kconfig (renamed from drivers/staging/media/go7007/Kconfig)0
-rw-r--r--drivers/media/usb/go7007/Makefile (renamed from drivers/staging/media/go7007/Makefile)4
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c (renamed from drivers/staging/media/go7007/go7007-driver.c)133
-rw-r--r--drivers/media/usb/go7007/go7007-fw.c (renamed from drivers/staging/media/go7007/go7007-fw.c)32
-rw-r--r--drivers/media/usb/go7007/go7007-i2c.c (renamed from drivers/staging/media/go7007/go7007-i2c.c)4
-rw-r--r--drivers/media/usb/go7007/go7007-loader.c (renamed from drivers/staging/media/go7007/go7007-loader.c)4
-rw-r--r--drivers/media/usb/go7007/go7007-priv.h (renamed from drivers/staging/media/go7007/go7007-priv.h)20
-rw-r--r--drivers/media/usb/go7007/go7007-usb.c (renamed from drivers/staging/media/go7007/go7007-usb.c)4
-rw-r--r--drivers/media/usb/go7007/go7007-v4l2.c (renamed from drivers/staging/media/go7007/go7007-v4l2.c)322
-rw-r--r--drivers/media/usb/go7007/s2250-board.c (renamed from drivers/staging/media/go7007/s2250-board.c)9
-rw-r--r--drivers/media/usb/go7007/snd-go7007.c (renamed from drivers/staging/media/go7007/snd-go7007.c)4
-rw-r--r--drivers/media/usb/gspca/autogain_functions.c4
-rw-r--r--drivers/media/usb/gspca/gspca.c29
-rw-r--r--drivers/media/usb/gspca/gspca.h1
-rw-r--r--drivers/media/usb/gspca/kinect.c98
-rw-r--r--drivers/media/usb/gspca/pac7302.c9
-rw-r--r--drivers/media/usb/gspca/sonixb.c2
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c10
-rw-r--r--drivers/media/usb/msi2500/Kconfig5
-rw-r--r--drivers/media/usb/msi2500/Makefile1
-rw-r--r--drivers/media/usb/msi2500/msi2500.c (renamed from drivers/staging/media/msi3101/sdr-msi3101.c)818
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c12
-rw-r--r--drivers/media/usb/pwc/pwc-if.c1
-rw-r--r--drivers/media/usb/s2255/s2255drv.c1
-rw-r--r--drivers/media/usb/stk1160/stk1160-v4l.c1
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.c3
-rw-r--r--drivers/media/usb/tlg2300/pd-main.c2
-rw-r--r--drivers/media/usb/tlg2300/pd-radio.c1
-rw-r--r--drivers/media/usb/tlg2300/pd-video.c1
-rw-r--r--drivers/media/usb/tm6000/tm6000-input.c55
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c3
-rw-r--r--drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c3
-rw-r--r--drivers/media/usb/usbtv/usbtv-core.c2
-rw-r--r--drivers/media/usb/usbtv/usbtv-video.c1
-rw-r--r--drivers/media/usb/usbvision/usbvision-core.c16
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c1
-rw-r--r--drivers/media/usb/zr364xx/zr364xx.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c6
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c19
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c971
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c14
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-fh.c13
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c239
-rw-r--r--drivers/media/v4l2-core/v4l2-mem2mem.c11
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c125
-rw-r--r--drivers/media/v4l2-core/videobuf-dma-sg.c62
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c129
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c10
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/fsl-corenet-cf.c251
-rw-r--r--drivers/message/fusion/mptbase.c23
-rw-r--r--drivers/message/fusion/mptbase.h4
-rw-r--r--drivers/message/fusion/mptctl.c18
-rw-r--r--drivers/message/fusion/mptfc.c9
-rw-r--r--drivers/message/fusion/mptsas.c76
-rw-r--r--drivers/message/fusion/mptsas.h2
-rw-r--r--drivers/message/fusion/mptscsih.c31
-rw-r--r--drivers/message/fusion/mptscsih.h4
-rw-r--r--drivers/message/fusion/mptspi.c5
-rw-r--r--drivers/message/i2o/i2o_scsi.c11
-rw-r--r--drivers/mfd/88pm805.c2
-rw-r--r--drivers/mfd/88pm860x-core.c37
-rw-r--r--drivers/mfd/88pm860x-i2c.c3
-rw-r--r--drivers/mfd/Kconfig26
-rw-r--r--drivers/mfd/Makefile7
-rw-r--r--drivers/mfd/aat2870-core.c5
-rw-r--r--drivers/mfd/ab3100-core.c54
-rw-r--r--drivers/mfd/ab8500-core.c49
-rw-r--r--drivers/mfd/ab8500-debugfs.c308
-rw-r--r--drivers/mfd/arizona-core.c53
-rw-r--r--drivers/mfd/arizona-i2c.c5
-rw-r--r--drivers/mfd/arizona-irq.c29
-rw-r--r--drivers/mfd/arizona-spi.c3
-rw-r--r--drivers/mfd/arizona.h5
-rw-r--r--drivers/mfd/asic3.c12
-rw-r--r--drivers/mfd/cros_ec.c97
-rw-r--r--drivers/mfd/cros_ec_i2c.c44
-rw-r--r--drivers/mfd/cros_ec_spi.c64
-rw-r--r--drivers/mfd/da9063-core.c6
-rw-r--r--drivers/mfd/da9063-i2c.c134
-rw-r--r--drivers/mfd/dm355evm_msp.c2
-rw-r--r--drivers/mfd/ezx-pcap.c3
-rw-r--r--drivers/mfd/htc-i2cpld.c5
-rw-r--r--drivers/mfd/intel_msic.c2
-rw-r--r--drivers/mfd/intel_soc_pmic_core.c170
-rw-r--r--drivers/mfd/intel_soc_pmic_core.h32
-rw-r--r--drivers/mfd/intel_soc_pmic_crc.c158
-rw-r--r--drivers/mfd/ipaq-micro.c8
-rw-r--r--drivers/mfd/kempld-core.c10
-rw-r--r--drivers/mfd/lp8788-irq.c2
-rw-r--r--drivers/mfd/max77686-irq.c319
-rw-r--r--drivers/mfd/max77686.c329
-rw-r--r--drivers/mfd/max77693-irq.c336
-rw-r--r--drivers/mfd/max77693.c210
-rw-r--r--drivers/mfd/max8925-core.c2
-rw-r--r--drivers/mfd/max8925-i2c.c2
-rw-r--r--drivers/mfd/mc13xxx-core.c310
-rw-r--r--drivers/mfd/mc13xxx.h11
-rw-r--r--drivers/mfd/mcp-core.c1
-rw-r--r--drivers/mfd/omap-usb-host.c2
-rw-r--r--drivers/mfd/palmas.c233
-rw-r--r--drivers/mfd/pcf50633-core.c18
-rw-r--r--drivers/mfd/pm8921-core.c4
-rw-r--r--drivers/mfd/rtsx_pcr.c76
-rw-r--r--drivers/mfd/sec-core.c82
-rw-r--r--drivers/mfd/sec-irq.c110
-rw-r--r--drivers/mfd/si476x-cmd.c12
-rw-r--r--drivers/mfd/stmpe-i2c.c4
-rw-r--r--drivers/mfd/stmpe.c2
-rw-r--r--drivers/mfd/stmpe.h2
-rw-r--r--drivers/mfd/sun6i-prcm.c30
-rw-r--r--drivers/mfd/tc3589x.c2
-rw-r--r--drivers/mfd/tc6387xb.c7
-rw-r--r--drivers/mfd/tps6105x.c17
-rw-r--r--drivers/mfd/tps65910.c10
-rw-r--r--drivers/mfd/tps65912-spi.c3
-rw-r--r--drivers/mfd/twl4030-irq.c6
-rw-r--r--drivers/mfd/twl6030-irq.c4
-rw-r--r--drivers/mfd/twl6040.c2
-rw-r--r--drivers/mfd/wm5102-tables.c8
-rw-r--r--drivers/mfd/wm5110-tables.c245
-rw-r--r--drivers/mfd/wm8350-i2c.c8
-rw-r--r--drivers/mfd/wm8350-irq.c3
-rw-r--r--drivers/mfd/wm8994-regmap.c64
-rw-r--r--drivers/mfd/wm8997-tables.c16
-rw-r--r--drivers/misc/atmel-ssc.c13
-rw-r--r--drivers/misc/bh1770glc.c35
-rw-r--r--drivers/misc/bh1780gli.c33
-rw-r--r--drivers/misc/carma/carma-fpga.c5
-rw-r--r--drivers/misc/dummy-irq.c1
-rw-r--r--drivers/misc/fuse/Makefile1
-rw-r--r--drivers/misc/genwqe/Kconfig6
-rw-r--r--drivers/misc/genwqe/card_base.c217
-rw-r--r--drivers/misc/genwqe/card_base.h2
-rw-r--r--drivers/misc/genwqe/card_ddcb.c28
-rw-r--r--drivers/misc/genwqe/card_debugfs.c7
-rw-r--r--drivers/misc/genwqe/card_dev.c5
-rw-r--r--drivers/misc/genwqe/card_sysfs.c25
-rw-r--r--drivers/misc/genwqe/card_utils.c20
-rw-r--r--drivers/misc/genwqe/genwqe_driver.h2
-rw-r--r--drivers/misc/ioc4.c7
-rw-r--r--drivers/misc/lattice-ecp3-config.c16
-rw-r--r--drivers/misc/lkdtm.c1
-rw-r--r--drivers/misc/mei/client.c17
-rw-r--r--drivers/misc/mei/hw-me-regs.h1
-rw-r--r--drivers/misc/mei/hw-me.c54
-rw-r--r--drivers/misc/mei/hw-txe.c32
-rw-r--r--drivers/misc/mei/main.c148
-rw-r--r--drivers/misc/mei/mei_dev.h12
-rw-r--r--drivers/misc/mei/pci-me.c6
-rw-r--r--drivers/misc/mei/pci-txe.c4
-rw-r--r--drivers/misc/mic/Kconfig21
-rw-r--r--drivers/misc/mic/Makefile1
-rw-r--r--drivers/misc/mic/bus/Makefile5
-rw-r--r--drivers/misc/mic/bus/mic_bus.c218
-rw-r--r--drivers/misc/mic/card/mic_device.c23
-rw-r--r--drivers/misc/mic/card/mic_device.h9
-rw-r--r--drivers/misc/mic/card/mic_virtio.c7
-rw-r--r--drivers/misc/mic/card/mic_x100.c62
-rw-r--r--drivers/misc/mic/host/mic_boot.c83
-rw-r--r--drivers/misc/mic/host/mic_device.h24
-rw-r--r--drivers/misc/mic/host/mic_intr.c121
-rw-r--r--drivers/misc/mic/host/mic_intr.h27
-rw-r--r--drivers/misc/mic/host/mic_main.c7
-rw-r--r--drivers/misc/mic/host/mic_virtio.c187
-rw-r--r--drivers/misc/mic/host/mic_virtio.h21
-rw-r--r--drivers/misc/mic/host/mic_x100.c8
-rw-r--r--drivers/misc/sgi-xp/xpnet.c3
-rw-r--r--drivers/misc/ti-st/st_kim.c8
-rw-r--r--drivers/misc/vexpress-syscfg.c4
-rw-r--r--drivers/misc/vmw_vmci/vmci_guest.c2
-rw-r--r--drivers/mmc/host/au1xmmc.c198
-rw-r--r--drivers/mmc/host/rtsx_pci_sdmmc.c133
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c43
-rw-r--r--drivers/mtd/devices/elm.c2
-rw-r--r--drivers/mtd/nand/au1550nd.c29
-rw-r--r--drivers/mtd/nand/nand_base.c6
-rw-r--r--drivers/mtd/onenand/Kconfig4
-rw-r--r--drivers/mtd/onenand/samsung.c25
-rw-r--r--drivers/mtd/ubi/fastmap.c4
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/Makefile10
-rw-r--r--drivers/net/arcnet/arcnet.c3
-rw-r--r--drivers/net/bonding/bond_3ad.c185
-rw-r--r--drivers/net/bonding/bond_alb.c146
-rw-r--r--drivers/net/bonding/bond_alb.h8
-rw-r--r--drivers/net/bonding/bond_debugfs.c6
-rw-r--r--drivers/net/bonding/bond_main.c537
-rw-r--r--drivers/net/bonding/bond_netlink.c32
-rw-r--r--drivers/net/bonding/bond_options.c228
-rw-r--r--drivers/net/bonding/bond_procfs.c4
-rw-r--r--drivers/net/bonding/bond_sysfs.c3
-rw-r--r--drivers/net/bonding/bond_sysfs_slave.c4
-rw-r--r--drivers/net/bonding/bonding.h22
-rw-r--r--drivers/net/caif/caif_serial.c3
-rw-r--r--drivers/net/caif/caif_spi.c4
-rw-r--r--drivers/net/caif/caif_virtio.c2
-rw-r--r--drivers/net/can/c_can/c_can_platform.c46
-rw-r--r--drivers/net/can/dev.c2
-rw-r--r--drivers/net/can/sja1000/sja1000.c27
-rw-r--r--drivers/net/can/slcan.c2
-rw-r--r--drivers/net/cris/eth_v10.c1
-rw-r--r--drivers/net/dummy.c2
-rw-r--r--drivers/net/eql.c3
-rw-r--r--drivers/net/ethernet/8390/lib8390.c2
-rw-r--r--drivers/net/ethernet/8390/mac8390.c8
-rw-r--r--drivers/net/ethernet/adi/Kconfig3
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.c79
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.h3
-rw-r--r--drivers/net/ethernet/allwinner/sun4i-emac.c6
-rw-r--r--drivers/net/ethernet/amd/Kconfig13
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c363
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c149
-rw-r--r--drivers/net/ethernet/amd/declance.c12
-rw-r--r--drivers/net/ethernet/amd/xgbe/Makefile4
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-common.h121
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dcb.c270
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c7
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-desc.c32
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c780
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c728
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c74
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c69
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-mdio.c107
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-ptp.c285
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h151
-rw-r--r--drivers/net/ethernet/arc/emac.h4
-rw-r--r--drivers/net/ethernet/arc/emac_main.c11
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.c2
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_hw.c1
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c1
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl2.c3
-rw-r--r--drivers/net/ethernet/broadcom/Kconfig8
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c532
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.h14
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c9
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.h5
-rw-r--r--drivers/net/ethernet/broadcom/bnx2_fw.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h10
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c67
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c45
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c11
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c264
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h35
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c78
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h23
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c10
-rw-r--r--drivers/net/ethernet/broadcom/cnic.h3
-rw-r--r--drivers/net/ethernet/broadcom/cnic_defs.h3
-rw-r--r--drivers/net/ethernet/broadcom/cnic_if.h3
-rw-r--r--drivers/net/ethernet/broadcom/genet/Makefile2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c594
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h32
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c206
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c44
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c22
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c2
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad_ethtool.c6
-rw-r--r--drivers/net/ethernet/brocade/bna/cna_fwimg.c4
-rw-r--r--drivers/net/ethernet/cadence/macb.c419
-rw-r--r--drivers/net/ethernet/cadence/macb.h53
-rw-r--r--drivers/net/ethernet/chelsio/Kconfig11
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/Makefile1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h37
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c971
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h141
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c484
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h14
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c37
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c364
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_msg.h7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h17
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h99
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c38
-rw-r--r--drivers/net/ethernet/cirrus/cs89x0.c32
-rw-r--r--drivers/net/ethernet/cisco/enic/Makefile2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h40
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_api.c4
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_clsf.c284
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_clsf.h37
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.c80
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.h4
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_ethtool.c125
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c245
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_res.c1
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.c65
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_devcmd.h5
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_enet.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.h122
-rw-r--r--drivers/net/ethernet/davicom/dm9000.c6
-rw-r--r--drivers/net/ethernet/dec/tulip/de4x5.c1
-rw-r--r--drivers/net/ethernet/dnet.c46
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h17
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c297
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h54
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c29
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c272
-rw-r--r--drivers/net/ethernet/freescale/fec.h10
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c381
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fec.c1
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-scc.c1
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.c6
-rw-r--r--drivers/net/ethernet/freescale/xgmac_mdio.c4
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_ethtool.c3
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_hw.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/82571.c4
-rw-r--r--drivers/net/ethernet/intel/e1000e/defines.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c2
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c21
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h4
-rw-r--r--drivers/net/ethernet/intel/e1000e/mac.c1
-rw-r--r--drivers/net/ethernet/intel/e1000e/manage.c5
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c55
-rw-r--r--drivers/net/ethernet/intel/e1000e/nvm.c4
-rw-r--r--drivers/net/ethernet/intel/i40e/Makefile1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h72
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c132
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.h39
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c482
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c29
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c551
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_fcoe.c1561
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_fcoe.h128
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_hmc.h4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c249
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h28
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c753
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c520
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_osdep.h3
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h31
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ptp.c135
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_register.h5011
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c190
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h16
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h213
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c40
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c119
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.h39
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_common.c2
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_hmc.h4
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h28
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_register.h5011
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c9
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.h7
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_type.h74
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c6
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c86
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c44
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c9
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h18
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h3
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c66
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h12
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c47
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c213
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c315
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c580
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c39
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c46
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c24
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c74
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c117
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c582
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c16
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c31
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h20
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c216
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.h1
-rw-r--r--drivers/net/ethernet/marvell/Kconfig8
-rw-r--r--drivers/net/ethernet/marvell/Makefile1
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c4
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c6426
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_cq.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c64
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c38
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c24
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_selftest.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c47
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c69
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c28
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c279
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/alloc.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mad.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c292
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mr.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/port.c2
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c59
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.c1
-rw-r--r--drivers/net/ethernet/octeon/octeon_mgmt.c25
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c18
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c58
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c36
-rw-r--r--drivers/net/ethernet/realtek/r8169.c247
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c20
-rw-r--r--drivers/net/ethernet/sfc/ef10.c14
-rw-r--r--drivers/net/ethernet/sfc/efx.c67
-rw-r--r--drivers/net/ethernet/sfc/efx.h5
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c59
-rw-r--r--drivers/net/ethernet/sfc/falcon.c9
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c11
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h154
-rw-r--r--drivers/net/ethernet/sfc/nic.h13
-rw-r--r--drivers/net/ethernet/sfc/rx.c12
-rw-r--r--drivers/net/ethernet/sfc/selftest.c5
-rw-r--r--drivers/net/ethernet/sfc/siena.c9
-rw-r--r--drivers/net/ethernet/sfc/tx.c28
-rw-r--r--drivers/net/ethernet/sis/sis900.c1
-rw-r--r--drivers/net/ethernet/smsc/smc911x.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h47
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c69
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c136
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c27
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c42
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c67
-rw-r--r--drivers/net/ethernet/sun/niu.c1
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c42
-rw-r--r--drivers/net/ethernet/ti/Kconfig4
-rw-r--r--drivers/net/ethernet/ti/cpmac.c279
-rw-r--r--drivers/net/ethernet/ti/cpsw.c45
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c12
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h4
-rw-r--r--drivers/net/ethernet/ti/cpts.c24
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c21
-rw-r--r--drivers/net/ethernet/ti/tlan.c224
-rw-r--r--drivers/net/ethernet/ti/tlan.h5
-rw-r--r--drivers/net/ethernet/tile/tilegx.c4
-rw-r--r--drivers/net/ethernet/tile/tilepro.c3
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.c10
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c2
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_emaclite.c2
-rw-r--r--drivers/net/fddi/defxx.c159
-rw-r--r--drivers/net/fddi/defxx.h2
-rw-r--r--drivers/net/hamradio/6pack.c3
-rw-r--r--drivers/net/hamradio/baycom_epp.c2
-rw-r--r--drivers/net/hamradio/bpqether.c4
-rw-r--r--drivers/net/hamradio/dmascc.c4
-rw-r--r--drivers/net/hamradio/hdlcdrv.c2
-rw-r--r--drivers/net/hamradio/mkiss.c3
-rw-r--r--drivers/net/hamradio/scc.c2
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/hyperv/hyperv_net.h5
-rw-r--r--drivers/net/hyperv/netvsc.c15
-rw-r--r--drivers/net/hyperv/netvsc_drv.c41
-rw-r--r--drivers/net/hyperv/rndis_filter.c21
-rw-r--r--drivers/net/ieee802154/Kconfig12
-rw-r--r--drivers/net/ieee802154/Makefile1
-rw-r--r--drivers/net/ieee802154/at86rf230.c1464
-rw-r--r--drivers/net/ieee802154/cc2520.c1039
-rw-r--r--drivers/net/ieee802154/fakehard.c3
-rw-r--r--drivers/net/ieee802154/mrf24j40.c115
-rw-r--r--drivers/net/ifb.c4
-rw-r--r--drivers/net/irda/au1k_ir.c48
-rw-r--r--drivers/net/irda/kingsun-sir.c4
-rw-r--r--drivers/net/loopback.c2
-rw-r--r--drivers/net/macvlan.c1
-rw-r--r--drivers/net/phy/amd-xgbe-phy.c136
-rw-r--r--drivers/net/phy/dp83640.c245
-rw-r--r--drivers/net/phy/mdio_bus.c44
-rw-r--r--drivers/net/phy/micrel.c22
-rw-r--r--drivers/net/phy/phy.c83
-rw-r--r--drivers/net/phy/phy_device.c17
-rw-r--r--drivers/net/phy/spi_ks8995.c26
-rw-r--r--drivers/net/ppp/ppp_generic.c57
-rw-r--r--drivers/net/ppp/pppoe.c2
-rw-r--r--drivers/net/slip/slhc.c1
-rw-r--r--drivers/net/slip/slip.c2
-rw-r--r--drivers/net/team/team.c8
-rw-r--r--drivers/net/team/team_mode_loadbalance.c18
-rw-r--r--drivers/net/tun.c3
-rw-r--r--drivers/net/usb/Kconfig13
-rw-r--r--drivers/net/usb/ax88179_178a.c264
-rw-r--r--drivers/net/usb/cdc-phonet.c2
-rw-r--r--drivers/net/usb/cdc_ether.c16
-rw-r--r--drivers/net/usb/cdc_subset.c27
-rw-r--r--drivers/net/usb/hso.c54
-rw-r--r--drivers/net/usb/huawei_cdc_ncm.c3
-rw-r--r--drivers/net/usb/qmi_wwan.c3
-rw-r--r--drivers/net/usb/r8152.c52
-rw-r--r--drivers/net/usb/smsc95xx.c14
-rw-r--r--drivers/net/usb/usbnet.c8
-rw-r--r--drivers/net/veth.c29
-rw-r--r--drivers/net/virtio_net.c67
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c2
-rw-r--r--drivers/net/vxlan.c146
-rw-r--r--drivers/net/wan/dlci.c5
-rw-r--r--drivers/net/wan/farsync.c112
-rw-r--r--drivers/net/wan/hdlc.c3
-rw-r--r--drivers/net/wan/hdlc_fr.c5
-rw-r--r--drivers/net/wan/lapbether.c4
-rw-r--r--drivers/net/wan/sbni.c7
-rw-r--r--drivers/net/wan/sdla.c3
-rw-r--r--drivers/net/wan/x25_asy.c10
-rw-r--r--drivers/net/wimax/i2400m/usb.c2
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/airo.c6
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c11
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c18
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c73
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c20
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h13
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c140
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c52
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c99
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c28
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c8
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c31
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h3
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c8
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c16
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h36
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c32
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c91
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c17
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c7
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c72
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h201
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h162
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c97
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c685
-rw-r--r--drivers/net/wireless/ath/ath9k/common-beacon.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c892
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c144
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c1
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c1
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c68
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c361
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c64
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c53
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c1
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c39
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h36
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c59
-rw-r--r--drivers/net/wireless/b43/Kconfig31
-rw-r--r--drivers/net/wireless/b43/Makefile6
-rw-r--r--drivers/net/wireless/b43/main.c459
-rw-r--r--drivers/net/wireless/b43/main.h1
-rw-r--r--drivers/net/wireless/b43/phy_a.c2
-rw-r--r--drivers/net/wireless/b43/phy_a.h4
-rw-r--r--drivers/net/wireless/b43/phy_common.c26
-rw-r--r--drivers/net/wireless/b43/phy_common.h12
-rw-r--r--drivers/net/wireless/b43/phy_ht.c2
-rw-r--r--drivers/net/wireless/b43/phy_lcn.c35
-rw-r--r--drivers/net/wireless/b43/phy_n.c1461
-rw-r--r--drivers/net/wireless/b43/phy_n.h15
-rw-r--r--drivers/net/wireless/b43/radio_2057.c540
-rw-r--r--drivers/net/wireless/b43/radio_2057.h76
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c626
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h4
-rw-r--r--drivers/net/wireless/b43/xmit.c7
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile11
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c20
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c43
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/btcoex.c38
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c36
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.c273
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.h69
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c196
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h110
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c25
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c283
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.c136
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/feature.h86
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.c501
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.h84
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c100
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c1397
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h40
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/of.c56
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/of.h22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c1846
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h31
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h16
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c256
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.c115
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.h64
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1078
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c37
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c1
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h71
-rw-r--r--drivers/net/wireless/cw1200/fwio.c1
-rw-r--r--drivers/net/wireless/cw1200/scan.c3
-rw-r--r--drivers/net/wireless/cw1200/scan.h2
-rw-r--r--drivers/net/wireless/cw1200/sta.c3
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.c6
-rw-r--r--drivers/net/wireless/iwlegacy/common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig25
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h67
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c99
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c513
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c1257
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c324
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h222
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h256
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h78
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c131
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c804
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h150
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c35
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c128
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c38
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c96
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c599
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c98
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c162
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c35
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c65
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h7
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c339
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c1
-rw-r--r--drivers/net/wireless/libertas/Kconfig2
-rw-r--r--drivers/net/wireless/libertas/cmd.c1
-rw-r--r--drivers/net/wireless/libertas/main.c2
-rw-r--r--drivers/net/wireless/libertas/mesh.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c83
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c2
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h2
-rw-r--r--drivers/net/wireless/mwifiex/11h.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c5
-rw-r--r--drivers/net/wireless/mwifiex/11n.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c3
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c29
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h2
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/README32
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c67
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h2
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c2
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c47
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c95
-rw-r--r--drivers/net/wireless/mwifiex/decl.h2
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c85
-rw-r--r--drivers/net/wireless/mwifiex/fw.h4
-rw-r--r--drivers/net/wireless/mwifiex/ie.c2
-rw-r--r--drivers/net/wireless/mwifiex/init.c15
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/mwifiex/join.c10
-rw-r--r--drivers/net/wireless/mwifiex/main.c25
-rw-r--r--drivers/net/wireless/mwifiex/main.h34
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c189
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h12
-rw-r--r--drivers/net/wireless/mwifiex/scan.c2
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c235
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h14
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c18
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c3
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c32
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c3
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c7
-rw-r--r--drivers/net/wireless/mwifiex/usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/usb.h2
-rw-r--r--drivers/net/wireless/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mwifiex/util.h2
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c11
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
-rw-r--r--drivers/net/wireless/mwl8k.c5
-rw-r--r--drivers/net/wireless/orinoco/Kconfig4
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1
-rw-r--r--drivers/net/wireless/p54/p54spi.c2
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c1
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_core.c85
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_debugfs.c10
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c143
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c239
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_pkt.c17
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c6
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio_ops.c8
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c88
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h12
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h25
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c69
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c32
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c21
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c78
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8180.h1
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h2
-rw-r--r--drivers/net/wireless/rtlwifi/core.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/reg.h1
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c3
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c2
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c20
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.c89
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.h19
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.c65
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c34
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.c16
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.c7
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/Makefile2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c23
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h6
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h27
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c108
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/vendor_cmd.c197
-rw-r--r--drivers/net/wireless/ti/wlcore/vendor_cmd.h45
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h10
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h20
-rw-r--r--drivers/net/wireless/zd1211rw/Kconfig4
-rw-r--r--drivers/net/xen-netback/common.h30
-rw-r--r--drivers/net/xen-netback/interface.c74
-rw-r--r--drivers/net/xen-netback/netback.c196
-rw-r--r--drivers/net/xen-netback/xenbus.c178
-rw-r--r--drivers/net/xen-netfront.c89
-rw-r--r--drivers/nfc/Kconfig2
-rw-r--r--drivers/nfc/Makefile3
-rw-r--r--drivers/nfc/st21nfca/Makefile2
-rw-r--r--drivers/nfc/st21nfca/i2c.c9
-rw-r--r--drivers/nfc/st21nfca/st21nfca.c272
-rw-r--r--drivers/nfc/st21nfca/st21nfca.h26
-rw-r--r--drivers/nfc/st21nfca/st21nfca_dep.c661
-rw-r--r--drivers/nfc/st21nfca/st21nfca_dep.h43
-rw-r--r--drivers/nfc/st21nfcb/Kconfig22
-rw-r--r--drivers/nfc/st21nfcb/Makefile8
-rw-r--r--drivers/nfc/st21nfcb/i2c.c462
-rw-r--r--drivers/nfc/st21nfcb/ndlc.c298
-rw-r--r--drivers/nfc/st21nfcb/ndlc.h55
-rw-r--r--drivers/nfc/st21nfcb/st21nfcb.c129
-rw-r--r--drivers/nfc/st21nfcb/st21nfcb.h38
-rw-r--r--drivers/of/address.c36
-rw-r--r--drivers/of/fdt.c81
-rw-r--r--drivers/of/of_mdio.c34
-rw-r--r--drivers/parport/Kconfig12
-rw-r--r--drivers/pci/host/pci-host-generic.c2
-rw-r--r--drivers/pci/host/pci-mvebu.c2
-rw-r--r--drivers/pci/host/pci-tegra.c7
-rw-r--r--drivers/pci/host/pcie-rcar.c158
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c33
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c3
-rw-r--r--drivers/pci/hotplug/pciehp.h3
-rw-r--r--drivers/pci/hotplug/pciehp_core.c7
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c101
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c4
-rw-r--r--drivers/pci/msi.c141
-rw-r--r--drivers/pci/pci-acpi.c76
-rw-r--r--drivers/pci/pci-driver.c18
-rw-r--r--drivers/pci/pci-label.c18
-rw-r--r--drivers/pci/pci.c28
-rw-r--r--drivers/pci/pcie/aer/Kconfig1
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c4
-rw-r--r--drivers/pci/pcie/portdrv_pci.c4
-rw-r--r--drivers/pci/quirks.c106
-rw-r--r--drivers/pci/setup-bus.c2
-rw-r--r--drivers/pci/setup-res.c75
-rw-r--r--drivers/pcmcia/Kconfig12
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.c2
-rw-r--r--drivers/pcmcia/i82092.c2
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c1168
-rw-r--r--drivers/pcmcia/pd6729.c2
-rw-r--r--drivers/pcmcia/sa1111_jornada720.c10
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c2
-rw-r--r--drivers/pcmcia/yenta_socket.c2
-rw-r--r--drivers/phy/Kconfig100
-rw-r--r--drivers/phy/Makefile8
-rw-r--r--drivers/phy/phy-bcm-kona-usb2.c2
-rw-r--r--drivers/phy/phy-berlin-sata.c284
-rw-r--r--drivers/phy/phy-core.c63
-rw-r--r--drivers/phy/phy-exynos-dp-video.c7
-rw-r--r--drivers/phy/phy-exynos-mipi-video.c7
-rw-r--r--drivers/phy/phy-exynos4x12-usb2.c125
-rw-r--r--drivers/phy/phy-exynos5-usbdrd.c9
-rw-r--r--drivers/phy/phy-exynos5250-sata.c2
-rw-r--r--drivers/phy/phy-exynos5250-usb2.c2
-rw-r--r--drivers/phy/phy-hix5hd2-sata.c192
-rw-r--r--drivers/phy/phy-miphy365x.c636
-rw-r--r--drivers/phy/phy-mvebu-sata.c2
-rw-r--r--drivers/phy/phy-omap-control.c52
-rw-r--r--drivers/phy/phy-omap-usb2.c13
-rw-r--r--drivers/phy/phy-qcom-apq8064-sata.c289
-rw-r--r--drivers/phy/phy-qcom-ipq806x-sata.c211
-rw-r--r--drivers/phy/phy-s5pv210-usb2.c187
-rw-r--r--drivers/phy/phy-samsung-usb2.c16
-rw-r--r--drivers/phy/phy-samsung-usb2.h6
-rw-r--r--drivers/phy/phy-spear1310-miphy.c2
-rw-r--r--drivers/phy/phy-spear1340-miphy.c2
-rw-r--r--drivers/phy/phy-sun4i-usb.c7
-rw-r--r--drivers/phy/phy-ti-pipe3.c107
-rw-r--r--drivers/phy/phy-twl4030-usb.c2
-rw-r--r--drivers/phy/phy-xgene.c2
-rw-r--r--drivers/pinctrl/Kconfig123
-rw-r--r--drivers/pinctrl/Makefile25
-rw-r--r--drivers/pinctrl/berlin/berlin.c2
-rw-r--r--drivers/pinctrl/core.c24
-rw-r--r--drivers/pinctrl/nomadik/Kconfig51
-rw-r--r--drivers/pinctrl/nomadik/Makefile10
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8500.c (renamed from drivers/pinctrl/pinctrl-ab8500.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8505.c (renamed from drivers/pinctrl/pinctrl-ab8505.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab8540.c (renamed from drivers/pinctrl/pinctrl-ab8540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-ab9540.c (renamed from drivers/pinctrl/pinctrl-ab9540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-abx500.c (renamed from drivers/pinctrl/pinctrl-abx500.c)19
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-abx500.h (renamed from drivers/pinctrl/pinctrl-abx500.h)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c (renamed from drivers/pinctrl/pinctrl-nomadik-db8500.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c (renamed from drivers/pinctrl/pinctrl-nomadik-db8540.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c (renamed from drivers/pinctrl/pinctrl-nomadik-stn8815.c)0
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.c (renamed from drivers/pinctrl/pinctrl-nomadik.c)18
-rw-r--r--drivers/pinctrl/nomadik/pinctrl-nomadik.h (renamed from drivers/pinctrl/pinctrl-nomadik.h)0
-rw-r--r--drivers/pinctrl/pinctrl-adi2.c41
-rw-r--r--drivers/pinctrl/pinctrl-as3722.c11
-rw-r--r--drivers/pinctrl/pinctrl-at91.c27
-rw-r--r--drivers/pinctrl/pinctrl-baytrail.c103
-rw-r--r--drivers/pinctrl/pinctrl-bcm281xx.c2
-rw-r--r--drivers/pinctrl/pinctrl-bcm2835.c11
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c10
-rw-r--r--drivers/pinctrl/pinctrl-imx.c2
-rw-r--r--drivers/pinctrl/pinctrl-imx1-core.c2
-rw-r--r--drivers/pinctrl/pinctrl-imx1.c279
-rw-r--r--drivers/pinctrl/pinctrl-imx27.c52
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c401
-rw-r--r--drivers/pinctrl/pinctrl-single.c61
-rw-r--r--drivers/pinctrl/pinctrl-st.c17
-rw-r--r--drivers/pinctrl/pinctrl-tb10x.c17
-rw-r--r--drivers/pinctrl/pinctrl-tegra-xusb.c973
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c13
-rw-r--r--drivers/pinctrl/pinctrl-tz1090-pdc.c28
-rw-r--r--drivers/pinctrl/pinctrl-tz1090.c58
-rw-r--r--drivers/pinctrl/pinctrl-u300.c14
-rw-r--r--drivers/pinctrl/pinmux.c4
-rw-r--r--drivers/pinctrl/qcom/Kconfig42
-rw-r--r--drivers/pinctrl/qcom/Makefile6
-rw-r--r--drivers/pinctrl/qcom/pinctrl-apq8064.c (renamed from drivers/pinctrl/pinctrl-apq8064.c)19
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ipq8064.c (renamed from drivers/pinctrl/pinctrl-ipq8064.c)17
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.c (renamed from drivers/pinctrl/pinctrl-msm.c)42
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.h (renamed from drivers/pinctrl/pinctrl-msm.h)0
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm8960.c1282
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm8x74.c (renamed from drivers/pinctrl/pinctrl-msm8x74.c)29
-rw-r--r--drivers/pinctrl/samsung/Kconfig28
-rw-r--r--drivers/pinctrl/samsung/Makefile7
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c (renamed from drivers/pinctrl/pinctrl-exynos.c)307
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.h (renamed from drivers/pinctrl/pinctrl-exynos.h)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos5440.c (renamed from drivers/pinctrl/pinctrl-exynos5440.c)10
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c24xx.c (renamed from drivers/pinctrl/pinctrl-s3c24xx.c)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-s3c64xx.c (renamed from drivers/pinctrl/pinctrl-s3c64xx.c)0
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.c (renamed from drivers/pinctrl/pinctrl-samsung.c)728
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.h (renamed from drivers/pinctrl/pinctrl-samsung.h)18
-rw-r--r--drivers/pinctrl/sh-pfc/gpio.c9
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-r8a7791.c417
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-sh73a0.c11
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c22
-rw-r--r--drivers/pinctrl/sirf/pinctrl-sirf.c10
-rw-r--r--drivers/pinctrl/spear/Kconfig1
-rw-r--r--drivers/pinctrl/spear/pinctrl-plgpio.c84
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c7
-rw-r--r--drivers/pinctrl/sunxi/Kconfig24
-rw-r--r--drivers/pinctrl/sunxi/Makefile2
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c4
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c217
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c1
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c142
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c593
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.c191
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sunxi.h44
-rw-r--r--drivers/pinctrl/vt8500/pinctrl-wmt.c21
-rw-r--r--drivers/platform/x86/samsung-q10.c6
-rw-r--r--drivers/pnp/pnpacpi/core.c92
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/bq2415x_charger.c8
-rw-r--r--drivers/power/bq27x00_battery.c28
-rw-r--r--drivers/power/ipaq_micro_battery.c290
-rw-r--r--drivers/power/power_supply_core.c3
-rw-r--r--drivers/power/power_supply_sysfs.c4
-rw-r--r--drivers/power/reset/Kconfig17
-rw-r--r--drivers/power/reset/Makefile2
-rw-r--r--drivers/power/reset/brcmstb-reboot.c120
-rw-r--r--drivers/power/reset/gpio-poweroff.c52
-rw-r--r--drivers/power/reset/hisi-reboot.c67
-rw-r--r--drivers/power/reset/restart-poweroff.c2
-rw-r--r--drivers/power/rx51_battery.c90
-rw-r--r--drivers/power/tps65090-charger.c76
-rw-r--r--drivers/power/twl4030_charger.c44
-rw-r--r--drivers/ptp/ptp_chardev.c9
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c8
-rw-r--r--drivers/ras/Kconfig2
-rw-r--r--drivers/ras/Makefile1
-rw-r--r--drivers/ras/debugfs.c56
-rw-r--r--drivers/ras/ras.c29
-rw-r--r--drivers/regulator/88pm800.c1
-rw-r--r--drivers/regulator/Kconfig14
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/ab8500.c38
-rw-r--r--drivers/regulator/act8865-regulator.c329
-rw-r--r--drivers/regulator/arizona-ldo1.c2
-rw-r--r--drivers/regulator/as3722-regulator.c4
-rw-r--r--drivers/regulator/bcm590xx-regulator.c16
-rw-r--r--drivers/regulator/core.c126
-rw-r--r--drivers/regulator/da9211-regulator.c368
-rw-r--r--drivers/regulator/da9211-regulator.h271
-rw-r--r--drivers/regulator/lp872x.c9
-rw-r--r--drivers/regulator/lp8755.c23
-rw-r--r--drivers/regulator/ltc3589.c2
-rw-r--r--drivers/regulator/max77693.c12
-rw-r--r--drivers/regulator/max8952.c34
-rw-r--r--drivers/regulator/mc13xxx-regulator-core.c37
-rw-r--r--drivers/regulator/mc13xxx.h1
-rw-r--r--drivers/regulator/palmas-regulator.c1104
-rw-r--r--drivers/regulator/s2mps11.c323
-rw-r--r--drivers/regulator/s5m8767.c4
-rw-r--r--drivers/regulator/tps65090-regulator.c76
-rw-r--r--drivers/regulator/tps65217-regulator.c4
-rw-r--r--drivers/regulator/tps65218-regulator.c52
-rw-r--r--drivers/regulator/tps6586x-regulator.c129
-rw-r--r--drivers/regulator/twl-regulator.c13
-rw-r--r--drivers/rtc/rtc-au1xxx.c18
-rw-r--r--drivers/rtc/rtc-da9063.c54
-rw-r--r--drivers/rtc/rtc-max77686.c27
-rw-r--r--drivers/s390/block/dasd.c196
-rw-r--r--drivers/s390/block/dasd_eckd.c30
-rw-r--r--drivers/s390/block/dasd_int.h5
-rw-r--r--drivers/s390/block/dasd_ioctl.c33
-rw-r--r--drivers/s390/char/con3215.c32
-rw-r--r--drivers/s390/char/raw3270.c1
-rw-r--r--drivers/s390/cio/qdio_setup.c53
-rw-r--r--drivers/s390/crypto/ap_bus.c9
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/ctcm_main.c6
-rw-r--r--drivers/s390/net/netiucv.c2
-rw-r--r--drivers/s390/net/qeth_core.h15
-rw-r--r--drivers/s390/net/qeth_core_main.c200
-rw-r--r--drivers/s390/net/qeth_core_mpc.h17
-rw-r--r--drivers/s390/net/qeth_core_sys.c38
-rw-r--r--drivers/s390/net/qeth_l2_main.c6
-rw-r--r--drivers/s390/net/qeth_l3_main.c3
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c3
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c49
-rw-r--r--drivers/s390/scsi/zfcp_unit.c4
-rw-r--r--drivers/sbus/char/bbc_envctrl.c6
-rw-r--r--drivers/sbus/char/bbc_i2c.c11
-rw-r--r--drivers/sbus/char/display7seg.c10
-rw-r--r--drivers/scsi/3w-xxxx.h4
-rw-r--r--drivers/scsi/53c700.c7
-rw-r--r--drivers/scsi/Kconfig61
-rw-r--r--drivers/scsi/Makefile5
-rw-r--r--drivers/scsi/NCR5380.c31
-rw-r--r--drivers/scsi/NCR53c406a.c4
-rw-r--r--drivers/scsi/a100u2w.c2
-rw-r--r--drivers/scsi/aacraid/linit.c2
-rw-r--r--drivers/scsi/advansys.c6
-rw-r--r--drivers/scsi/aha152x.c6
-rw-r--r--drivers/scsi/aic7xxx/aic7770_osm.c3
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.h2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c6
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c3
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_proc.c2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c11
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c3
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_proc.c2
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c8
-rw-r--r--drivers/scsi/arm/acornscsi.c14
-rw-r--r--drivers/scsi/arm/fas216.c11
-rw-r--r--drivers/scsi/arm/queue.c3
-rw-r--r--drivers/scsi/atari_NCR5380.c62
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c2
-rw-r--r--drivers/scsi/be2iscsi/be_main.c2
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c24
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c6
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h2
-rw-r--r--drivers/scsi/bfa/bfad.c62
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c16
-rw-r--r--drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h13
-rw-r--r--drivers/scsi/bnx2fc/Kconfig4
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h7
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_constants.h13
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_debug.c13
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_debug.h13
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_els.c3
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c27
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_hwi.c3
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_io.c9
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_tgt.c3
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_constants.h6
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_hsi.h6
-rw-r--r--drivers/scsi/bnx2i/Kconfig4
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h6
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c6
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c14
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c15
-rw-r--r--drivers/scsi/bnx2i/bnx2i_sysfs.c6
-rw-r--r--drivers/scsi/ch.c30
-rw-r--r--drivers/scsi/csiostor/csio_scsi.c24
-rw-r--r--drivers/scsi/cxgbi/cxgb4i/cxgb4i.c363
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c243
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.h23
-rw-r--r--drivers/scsi/dc395x.c51
-rw-r--r--drivers/scsi/dpt_i2o.c38
-rw-r--r--drivers/scsi/dpti.h6
-rw-r--r--drivers/scsi/eata.c4
-rw-r--r--drivers/scsi/fnic/fnic_isr.c4
-rw-r--r--drivers/scsi/fnic/fnic_scsi.c20
-rw-r--r--drivers/scsi/g_NCR5380.c2
-rw-r--r--drivers/scsi/hosts.c50
-rw-r--r--drivers/scsi/hpsa.c37
-rw-r--r--drivers/scsi/hptiop.c2
-rw-r--r--drivers/scsi/ibmvscsi/Makefile1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c477
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h268
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c13
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c1001
-rw-r--r--drivers/scsi/in2000.c6
-rw-r--r--drivers/scsi/isci/init.c2
-rw-r--r--drivers/scsi/libiscsi.c12
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c16
-rw-r--r--drivers/scsi/libsrp.c447
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c36
-rw-r--r--drivers/scsi/megaraid.c6
-rw-r--r--drivers/scsi/megaraid/mega_common.h2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c4
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c75
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c83
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c75
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_scsih.c92
-rw-r--r--drivers/scsi/mvsas/mv_sas.c24
-rw-r--r--drivers/scsi/ncr53c8xx.c2
-rw-r--r--drivers/scsi/ncr53c8xx.h4
-rw-r--r--drivers/scsi/nsp32.c2
-rw-r--r--drivers/scsi/pas16.c2
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c2
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c2
-rw-r--r--drivers/scsi/pm8001/pm8001_ctl.c11
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c65
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c53
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.c38
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h2
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c48
-rw-r--r--drivers/scsi/pmcraid.c2
-rw-r--r--drivers/scsi/ps3rom.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h18
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c11
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_mr.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c48
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c17
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h4
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c22
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c6
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c20
-rw-r--r--drivers/scsi/qlogicfas.c2
-rw-r--r--drivers/scsi/qlogicpti.c2
-rw-r--r--drivers/scsi/scsi.c132
-rw-r--r--drivers/scsi/scsi_debug.c1483
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_error.c206
-rw-r--r--drivers/scsi/scsi_ioctl.c17
-rw-r--r--drivers/scsi/scsi_lib.c943
-rw-r--r--drivers/scsi/scsi_priv.h5
-rw-r--r--drivers/scsi/scsi_proc.c2
-rw-r--r--drivers/scsi/scsi_scan.c187
-rw-r--r--drivers/scsi/scsi_sysfs.c45
-rw-r--r--drivers/scsi/scsi_tgt_if.c399
-rw-r--r--drivers/scsi/scsi_tgt_lib.c661
-rw-r--r--drivers/scsi/scsi_tgt_priv.h32
-rw-r--r--drivers/scsi/scsi_trace.c16
-rw-r--r--drivers/scsi/scsi_transport_fc.c21
-rw-r--r--drivers/scsi/scsi_transport_fc_internal.h26
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c8
-rw-r--r--drivers/scsi/scsi_transport_sas.c2
-rw-r--r--drivers/scsi/scsi_transport_srp.c18
-rw-r--r--drivers/scsi/scsi_transport_srp_internal.h25
-rw-r--r--drivers/scsi/sd.c225
-rw-r--r--drivers/scsi/sd.h3
-rw-r--r--drivers/scsi/sg.c657
-rw-r--r--drivers/scsi/sr.c70
-rw-r--r--drivers/scsi/sr.h5
-rw-r--r--drivers/scsi/sr_ioctl.c26
-rw-r--r--drivers/scsi/sr_vendor.c36
-rw-r--r--drivers/scsi/st.c605
-rw-r--r--drivers/scsi/storvsc_drv.c123
-rw-r--r--drivers/scsi/sun3_NCR5380.c57
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h2
-rw-r--r--drivers/scsi/tmscsim.c6
-rw-r--r--drivers/scsi/u14-34f.c10
-rw-r--r--drivers/scsi/ufs/ufs.h38
-rw-r--r--drivers/scsi/ufs/ufshcd-pci.c26
-rw-r--r--drivers/scsi/ufs/ufshcd.c427
-rw-r--r--drivers/scsi/ufs/ufshci.h5
-rw-r--r--drivers/scsi/virtio_scsi.c101
-rw-r--r--drivers/scsi/vmw_pvscsi.c2
-rw-r--r--drivers/scsi/wd33c93.c33
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/tegra/Makefile4
-rw-r--r--drivers/soc/tegra/common.c30
-rw-r--r--drivers/soc/tegra/fuse/Makefile8
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c163
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra20.c215
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra30.c224
-rw-r--r--drivers/soc/tegra/fuse/fuse.h71
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra114.c110
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra124.c168
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra20.c110
-rw-r--r--drivers/soc/tegra/fuse/speedo-tegra30.c288
-rw-r--r--drivers/soc/tegra/fuse/tegra-apbmisc.c115
-rw-r--r--drivers/soc/tegra/pmc.c957
-rw-r--r--drivers/spi/Kconfig16
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-adi-v3.c5
-rw-r--r--drivers/spi/spi-atmel.c22
-rw-r--r--drivers/spi/spi-au1550.c72
-rw-r--r--drivers/spi/spi-cadence.c37
-rw-r--r--drivers/spi/spi-clps711x.c2
-rw-r--r--drivers/spi/spi-davinci.c72
-rw-r--r--drivers/spi/spi-dw-mmio.c19
-rw-r--r--drivers/spi/spi-efm32.c8
-rw-r--r--drivers/spi/spi-falcon.c2
-rw-r--r--drivers/spi/spi-fsl-lib.c2
-rw-r--r--drivers/spi/spi-fsl-spi.c2
-rw-r--r--drivers/spi/spi-omap-100k.c2
-rw-r--r--drivers/spi/spi-omap-uwire.c11
-rw-r--r--drivers/spi/spi-omap2-mcspi.c14
-rw-r--r--drivers/spi/spi-orion.c78
-rw-r--r--drivers/spi/spi-pl022.c2
-rw-r--r--drivers/spi/spi-qup.c36
-rw-r--r--drivers/spi/spi-rockchip.c837
-rw-r--r--drivers/spi/spi-rspi.c45
-rw-r--r--drivers/spi/spi-s3c64xx.c76
-rw-r--r--drivers/spi/spi-sh-hspi.c2
-rw-r--r--drivers/spi/spi-sh-msiof.c527
-rw-r--r--drivers/spi/spi-sh.c15
-rw-r--r--drivers/spi/spi-topcliff-pch.c12
-rw-r--r--drivers/spi/spi-xilinx.c2
-rw-r--r--drivers/spi/spi.c17
-rw-r--r--drivers/spmi/spmi.c1
-rw-r--r--drivers/ssb/pci.c113
-rw-r--r--drivers/staging/Kconfig32
-rw-r--r--drivers/staging/Makefile17
-rw-r--r--drivers/staging/android/Kconfig3
-rw-r--r--drivers/staging/android/Makefile2
-rw-r--r--drivers/staging/android/alarm-dev.c2
-rw-r--r--drivers/staging/android/binder.c229
-rw-r--r--drivers/staging/android/ion/Kconfig2
-rw-r--r--drivers/staging/android/ion/ion.c3
-rw-r--r--drivers/staging/android/ion/ion.h1
-rw-r--r--drivers/staging/android/ion/ion_chunk_heap.c2
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c9
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c71
-rw-r--r--drivers/staging/android/logger.c7
-rw-r--r--drivers/staging/android/sw_sync.c6
-rw-r--r--drivers/staging/android/sync.c916
-rw-r--r--drivers/staging/android/sync.h79
-rw-r--r--drivers/staging/android/sync_debug.c252
-rw-r--r--drivers/staging/android/timed_gpio.c15
-rw-r--r--drivers/staging/android/timed_output.c4
-rw-r--r--drivers/staging/android/trace/sync.h12
-rw-r--r--drivers/staging/bcm/Bcmchar.c2
-rw-r--r--drivers/staging/bcm/CmHost.c3
-rw-r--r--drivers/staging/bcm/DDRInit.c338
-rw-r--r--drivers/staging/bcm/HandleControlPacket.c24
-rw-r--r--drivers/staging/bcm/IPv6Protocol.c217
-rw-r--r--drivers/staging/bcm/InterfaceDld.c1
-rw-r--r--drivers/staging/bcm/InterfaceInit.c304
-rw-r--r--drivers/staging/bcm/InterfaceMisc.c126
-rw-r--r--drivers/staging/bcm/InterfaceRx.c206
-rw-r--r--drivers/staging/bcm/InterfaceTx.c185
-rw-r--r--drivers/staging/bcm/LeakyBucket.c312
-rw-r--r--drivers/staging/bcm/Misc.c27
-rw-r--r--drivers/staging/bcm/PHSModule.c1099
-rw-r--r--drivers/staging/bcm/PHSModule.h25
-rw-r--r--drivers/staging/bcm/Prototypes.h89
-rw-r--r--drivers/staging/bcm/Qos.c1053
-rw-r--r--drivers/staging/bcm/Queue.h46
-rw-r--r--drivers/staging/bcm/TODO4
-rw-r--r--drivers/staging/bcm/Transmit.c88
-rw-r--r--drivers/staging/bcm/hostmibs.c62
-rw-r--r--drivers/staging/bcm/led_control.c668
-rw-r--r--drivers/staging/bcm/led_control.h16
-rw-r--r--drivers/staging/bcm/nvm.c146
-rw-r--r--drivers/staging/board/Kconfig9
-rw-r--r--drivers/staging/board/Makefile2
-rw-r--r--drivers/staging/board/TODO2
-rw-r--r--drivers/staging/board/board.c41
-rw-r--r--drivers/staging/board/board.h20
-rw-r--r--drivers/staging/board/kzm9d.c19
-rw-r--r--drivers/staging/ced1401/Kconfig6
-rw-r--r--drivers/staging/ced1401/Makefile3
-rw-r--r--drivers/staging/ced1401/TODO10
-rw-r--r--drivers/staging/ced1401/ced_ioc.c1494
-rw-r--r--drivers/staging/ced1401/ced_ioctl.h336
-rw-r--r--drivers/staging/ced1401/machine.h119
-rw-r--r--drivers/staging/ced1401/usb1401.c1582
-rw-r--r--drivers/staging/ced1401/usb1401.h246
-rw-r--r--drivers/staging/ced1401/use1401.h288
-rw-r--r--drivers/staging/ced1401/use14_ioc.h299
-rw-r--r--drivers/staging/ced1401/userspace/use1401.c3035
-rw-r--r--drivers/staging/comedi/Kconfig24
-rw-r--r--drivers/staging/comedi/comedi.h127
-rw-r--r--drivers/staging/comedi/comedi_compat32.c28
-rw-r--r--drivers/staging/comedi/comedi_compat32.h3
-rw-r--r--drivers/staging/comedi/comedi_fops.c93
-rw-r--r--drivers/staging/comedi/comedi_internal.h1
-rw-r--r--drivers/staging/comedi/comedidev.h152
-rw-r--r--drivers/staging/comedi/drivers.c9
-rw-r--r--drivers/staging/comedi/drivers/8253.h6
-rw-r--r--drivers/staging/comedi/drivers/8255.c3
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c27
-rw-r--r--drivers/staging/comedi/drivers/Makefile4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c10
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h20
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c9
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c7
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c321
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c228
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c391
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c11
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c8
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c84
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c101
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c161
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c148
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c22
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c5
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c15
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c11
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c3
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h8
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c3
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.h13
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_common.c45
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_pci.c45
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c591
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.h42
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236_common.c206
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c7
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c26
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c1310
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci236.c161
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci263.c11
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c24
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c154
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c3
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c6
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c4
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c87
-rw-r--r--drivers/staging/comedi/drivers/das08.c3
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c4
-rw-r--r--drivers/staging/comedi/drivers/das16.c16
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c13
-rw-r--r--drivers/staging/comedi/drivers/das1800.c120
-rw-r--r--drivers/staging/comedi/drivers/das800.c3
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c13
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c4
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c12
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c4
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1351
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c117
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c1
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c44
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c94
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c68
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c5
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c66
-rw-r--r--drivers/staging/comedi/drivers/me4000.c1
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c67
-rw-r--r--drivers/staging/comedi/drivers/mf6x4.c47
-rw-r--r--drivers/staging/comedi/drivers/mite.c46
-rw-r--r--drivers/staging/comedi/drivers/mite.h136
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c5
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c8
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c154
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c797
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c67
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c68
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c254
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c392
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c14
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c89
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c231
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h7
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c51
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c4866
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c107
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c374
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c775
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h187
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1687
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h4
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h387
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c140
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c2
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c11
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c21
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c2
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c118
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c9
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c18
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c12
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c207
-rw-r--r--drivers/staging/comedi/drivers/rti800.c4
-rw-r--r--drivers/staging/comedi/drivers/s526.c6
-rw-r--r--drivers/staging/comedi/drivers/s626.c890
-rw-r--r--drivers/staging/comedi/drivers/s626.h28
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c112
-rw-r--r--drivers/staging/comedi/drivers/skel.c9
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c3
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c12
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c8
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c14
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c1
-rw-r--r--drivers/staging/cptm1217/clearpad_tm1217.c15
-rw-r--r--drivers/staging/crystalhd/Kconfig6
-rw-r--r--drivers/staging/crystalhd/Makefile6
-rw-r--r--drivers/staging/crystalhd/TODO15
-rw-r--r--drivers/staging/crystalhd/bc_dts_defs.h572
-rw-r--r--drivers/staging/crystalhd/bc_dts_glob_lnx.h300
-rw-r--r--drivers/staging/crystalhd/bcm_70012_regs.h758
-rw-r--r--drivers/staging/crystalhd/crystalhd.h13
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.c1066
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.h92
-rw-r--r--drivers/staging/crystalhd/crystalhd_fw_if.h370
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.c2458
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.h407
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.c782
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.h93
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.c1044
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.h232
-rw-r--r--drivers/staging/cxt1e1/Kconfig21
-rw-r--r--drivers/staging/cxt1e1/Makefile18
-rw-r--r--drivers/staging/cxt1e1/comet.c596
-rw-r--r--drivers/staging/cxt1e1/comet.h353
-rw-r--r--drivers/staging/cxt1e1/comet_tables.c538
-rw-r--r--drivers/staging/cxt1e1/comet_tables.h61
-rw-r--r--drivers/staging/cxt1e1/functions.c318
-rw-r--r--drivers/staging/cxt1e1/hwprobe.c382
-rw-r--r--drivers/staging/cxt1e1/libsbew.h549
-rw-r--r--drivers/staging/cxt1e1/linux.c1142
-rw-r--r--drivers/staging/cxt1e1/musycc.c1720
-rw-r--r--drivers/staging/cxt1e1/musycc.h427
-rw-r--r--drivers/staging/cxt1e1/pmc93x6_eeprom.c532
-rw-r--r--drivers/staging/cxt1e1/pmc93x6_eeprom.h39
-rw-r--r--drivers/staging/cxt1e1/pmcc4.h108
-rw-r--r--drivers/staging/cxt1e1/pmcc4_cpld.h91
-rw-r--r--drivers/staging/cxt1e1/pmcc4_defs.h68
-rw-r--r--drivers/staging/cxt1e1/pmcc4_drv.c1613
-rw-r--r--drivers/staging/cxt1e1/pmcc4_ioctls.h65
-rw-r--r--drivers/staging/cxt1e1/pmcc4_private.h295
-rw-r--r--drivers/staging/cxt1e1/pmcc4_sysdep.h63
-rw-r--r--drivers/staging/cxt1e1/sbe_bid.h47
-rw-r--r--drivers/staging/cxt1e1/sbe_promformat.h130
-rw-r--r--drivers/staging/cxt1e1/sbecom_inline_linux.h193
-rw-r--r--drivers/staging/cxt1e1/sbecrc.c133
-rw-r--r--drivers/staging/cxt1e1/sbeid.c205
-rw-r--r--drivers/staging/cxt1e1/sbeproc.c219
-rw-r--r--drivers/staging/cxt1e1/sbeproc.h42
-rw-r--r--drivers/staging/cxt1e1/sbew_ioc.h81
-rw-r--r--drivers/staging/dgap/dgap.c662
-rw-r--r--drivers/staging/dgap/dgap.h2
-rw-r--r--drivers/staging/dgnc/Makefile2
-rw-r--r--drivers/staging/dgnc/dgnc_cls.c14
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c19
-rw-r--r--drivers/staging/dgnc/dgnc_driver.h57
-rw-r--r--drivers/staging/dgnc/dgnc_neo.c1
-rw-r--r--drivers/staging/dgnc/dgnc_sysfs.c20
-rw-r--r--drivers/staging/dgnc/dgnc_trace.c185
-rw-r--r--drivers/staging/dgnc/dgnc_trace.h44
-rw-r--r--drivers/staging/dgnc/dgnc_tty.c53
-rw-r--r--drivers/staging/dgnc/digi.h35
-rw-r--r--drivers/staging/dgrp/Kconfig9
-rw-r--r--drivers/staging/dgrp/Makefile12
-rw-r--r--drivers/staging/dgrp/README2
-rw-r--r--drivers/staging/dgrp/TODO13
-rw-r--r--drivers/staging/dgrp/dgrp_common.c169
-rw-r--r--drivers/staging/dgrp/dgrp_common.h150
-rw-r--r--drivers/staging/dgrp/dgrp_dpa_ops.c534
-rw-r--r--drivers/staging/dgrp/dgrp_driver.c105
-rw-r--r--drivers/staging/dgrp/dgrp_mon_ops.c327
-rw-r--r--drivers/staging/dgrp/dgrp_net_ops.c3666
-rw-r--r--drivers/staging/dgrp/dgrp_ports_ops.c156
-rw-r--r--drivers/staging/dgrp/dgrp_specproc.c541
-rw-r--r--drivers/staging/dgrp/dgrp_sysfs.c558
-rw-r--r--drivers/staging/dgrp/dgrp_tty.c3337
-rw-r--r--drivers/staging/dgrp/digirp.h129
-rw-r--r--drivers/staging/dgrp/drp.h693
-rw-r--r--drivers/staging/emxx_udc/Kconfig10
-rw-r--r--drivers/staging/emxx_udc/Makefile1
-rw-r--r--drivers/staging/emxx_udc/TODO4
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.c3520
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.h653
-rw-r--r--drivers/staging/et131x/et131x.c26
-rw-r--r--drivers/staging/et131x/et131x.h46
-rw-r--r--drivers/staging/frontier/Kconfig5
-rw-r--r--drivers/staging/frontier/Makefile2
-rw-r--r--drivers/staging/frontier/README47
-rw-r--r--drivers/staging/frontier/TODO9
-rw-r--r--drivers/staging/frontier/alphatrack.c849
-rw-r--r--drivers/staging/frontier/alphatrack.h78
-rw-r--r--drivers/staging/frontier/tranzport.c973
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/Makefile3
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000.h2
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c4
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c4
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c211
-rw-r--r--drivers/staging/ft1000/ft1000-usb/Makefile2
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_debug.c6
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_hw.c25
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_proc.c241
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_usb.c8
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_usb.h5
-rw-r--r--drivers/staging/ft1000/ft1000.h2
-rw-r--r--drivers/staging/fwserial/fwserial.c6
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c4
-rw-r--r--drivers/staging/gdm724x/gdm_tty.c5
-rw-r--r--drivers/staging/gdm724x/gdm_usb.c40
-rw-r--r--drivers/staging/gdm724x/netlink_k.c2
-rw-r--r--drivers/staging/gdm72xx/Kconfig19
-rw-r--r--drivers/staging/gdm72xx/gdm_qos.c61
-rw-r--r--drivers/staging/gdm72xx/gdm_qos.h18
-rw-r--r--drivers/staging/gdm72xx/gdm_sdio.c107
-rw-r--r--drivers/staging/gdm72xx/gdm_sdio.h6
-rw-r--r--drivers/staging/gdm72xx/gdm_usb.c121
-rw-r--r--drivers/staging/gdm72xx/gdm_usb.h6
-rw-r--r--drivers/staging/gdm72xx/gdm_wimax.c382
-rw-r--r--drivers/staging/gdm72xx/gdm_wimax.h17
-rw-r--r--drivers/staging/gdm72xx/hci.h22
-rw-r--r--drivers/staging/gdm72xx/netlink_k.h7
-rw-r--r--drivers/staging/gdm72xx/sdio_boot.h6
-rw-r--r--drivers/staging/gdm72xx/usb_boot.c10
-rw-r--r--drivers/staging/gdm72xx/usb_boot.h6
-rw-r--r--drivers/staging/gdm72xx/usb_ids.h6
-rw-r--r--drivers/staging/gdm72xx/wm_ioctl.h7
-rw-r--r--drivers/staging/goldfish/goldfish_audio.c65
-rw-r--r--drivers/staging/iio/Documentation/generic_buffer.c9
-rw-r--r--drivers/staging/iio/Documentation/iio_event_monitor.c8
-rw-r--r--drivers/staging/iio/Documentation/iio_utils.h6
-rw-r--r--drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs11
-rw-r--r--drivers/staging/iio/Documentation/trigger.txt2
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c14
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c11
-rw-r--r--drivers/staging/iio/accel/adis16204_core.c12
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c18
-rw-r--r--drivers/staging/iio/accel/adis16240_core.c12
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c2
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c6
-rw-r--r--drivers/staging/iio/adc/Kconfig9
-rw-r--r--drivers/staging/iio/adc/Makefile1
-rw-r--r--drivers/staging/iio/adc/ad7291.h12
-rw-r--r--drivers/staging/iio/adc/ad7606_par.c37
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c2
-rw-r--r--drivers/staging/iio/frequency/ad9832.c16
-rw-r--r--drivers/staging/iio/frequency/ad9850.c6
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c2
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig30
-rw-r--r--drivers/staging/iio/magnetometer/Makefile4
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.h59
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_core.c (renamed from drivers/staging/iio/magnetometer/hmc5843.c)266
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_i2c.c104
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843_spi.c100
-rw-r--r--drivers/staging/iio/meter/ade7758_trigger.c2
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c33
-rw-r--r--drivers/staging/iio/trigger/iio-trig-periodic-rtc.c29
-rw-r--r--drivers/staging/imx-drm/imx-drm-core.c63
-rw-r--r--drivers/staging/keucr/Kconfig14
-rw-r--r--drivers/staging/keucr/Makefile13
-rw-r--r--drivers/staging/keucr/TODO12
-rw-r--r--drivers/staging/keucr/common.h7
-rw-r--r--drivers/staging/keucr/init.c333
-rw-r--r--drivers/staging/keucr/init.h518
-rw-r--r--drivers/staging/keucr/scsiglue.c467
-rw-r--r--drivers/staging/keucr/scsiglue.h10
-rw-r--r--drivers/staging/keucr/smcommon.h29
-rw-r--r--drivers/staging/keucr/smil.h288
-rw-r--r--drivers/staging/keucr/smilecc.c211
-rw-r--r--drivers/staging/keucr/smilmain.c760
-rw-r--r--drivers/staging/keucr/smilsub.c679
-rw-r--r--drivers/staging/keucr/smscsi.c194
-rw-r--r--drivers/staging/keucr/transport.c865
-rw-r--r--drivers/staging/keucr/transport.h73
-rw-r--r--drivers/staging/keucr/usb.c642
-rw-r--r--drivers/staging/keucr/usb.h240
-rw-r--r--drivers/staging/line6/driver.c2
-rw-r--r--drivers/staging/lustre/Makefile2
-rw-r--r--drivers/staging/lustre/TODO3
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/bitmap.h1
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/curproc.h2
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs.h55
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h10
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h2
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h18
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h33
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h17
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h4
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_private.h43
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_time.h29
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/kp30.h93
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h67
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h38
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h84
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h204
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h11
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h82
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h72
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h149
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h36
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h22
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/lucache.h16
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/params_tree.h164
-rw-r--r--drivers/staging/lustre/include/linux/lnet/api-support.h8
-rw-r--r--drivers/staging/lustre/include/linux/lnet/api.h5
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h50
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h23
-rw-r--r--drivers/staging/lustre/include/linux/lnet/linux/api-support.h1
-rw-r--r--drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h5
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h2
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lnet.h6
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lnetctl.h22
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lnetst.h6
-rw-r--r--drivers/staging/lustre/include/linux/lnet/ptllnd.h3
-rw-r--r--drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h3
-rw-r--r--drivers/staging/lustre/include/linux/lnet/socklnd.h4
-rw-r--r--drivers/staging/lustre/include/linux/lnet/types.h4
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c39
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h22
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c11
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/Makefile4
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c98
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h46
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c43
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h4
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c12
-rw-r--r--drivers/staging/lustre/lnet/lnet/Makefile3
-rw-r--r--drivers/staging/lustre/lnet/lnet/acceptor.c28
-rw-r--r--drivers/staging/lustre/lnet/lnet/api-ni.c34
-rw-r--r--drivers/staging/lustre/lnet/lnet/config.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-eq.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-md.c12
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-me.c15
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c108
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-msg.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-ptl.c18
-rw-r--r--drivers/staging/lustre/lnet/lnet/lo.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/module.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/peer.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c23
-rw-r--r--drivers/staging/lustre/lnet/lnet/router_proc.c84
-rw-r--r--drivers/staging/lustre/lnet/selftest/Makefile2
-rw-r--r--drivers/staging/lustre/lnet/selftest/brw_test.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conctl.c8
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c16
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.h10
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c16
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.h10
-rw-r--r--drivers/staging/lustre/lnet/selftest/framework.c12
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.c14
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.h2
-rw-r--r--drivers/staging/lustre/lnet/selftest/selftest.h12
-rw-r--r--drivers/staging/lustre/lnet/selftest/timer.c16
-rw-r--r--drivers/staging/lustre/lnet/selftest/timer.h2
-rw-r--r--drivers/staging/lustre/lustre/Kconfig1
-rw-r--r--drivers/staging/lustre/lustre/fid/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_internal.h8
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_lib.c6
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_request.c38
-rw-r--r--drivers/staging/lustre/lustre/fid/lproc_fid.c32
-rw-r--r--drivers/staging/lustre/lustre/fld/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_cache.c34
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_internal.h12
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_request.c54
-rw-r--r--drivers/staging/lustre/lustre/fld/lproc_fld.c25
-rw-r--r--drivers/staging/lustre/lustre/include/cl_object.h8
-rw-r--r--drivers/staging/lustre/lustre/include/dt_object.h8
-rw-r--r--drivers/staging/lustre/lustre/include/interval_tree.h2
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lprocfs_status.h2
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_acl.h2
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_compat25.h4
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h10
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_lib.h4
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lustre_lite.h10
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lvfs.h6
-rw-r--r--drivers/staging/lustre/lustre/include/linux/lvfs_linux.h9
-rw-r--r--drivers/staging/lustre/lustre/include/linux/obd.h4
-rw-r--r--drivers/staging/lustre/lustre/include/linux/obd_support.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lprocfs_status.h21
-rw-r--r--drivers/staging/lustre/lustre/include/lu_object.h6
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_idl.h17
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_user.h14
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_acl.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_capa.h14
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_cfg.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_debug.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_disk.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_dlm.h28
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_export.h16
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fid.h6
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fld.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fsfilt.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_handles.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_idmap.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_import.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lib.h30
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_lite.h14
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_log.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mdc.h16
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_mds.h12
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_net.h58
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_quota.h8
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_req_layout.h2
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_sec.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lvfs.h6
-rw-r--r--drivers/staging/lustre/lustre/include/md_object.h2
-rw-r--r--drivers/staging/lustre/lustre/include/obd.h21
-rw-r--r--drivers/staging/lustre/lustre/include/obd_cksum.h4
-rw-r--r--drivers/staging/lustre/lustre/include/obd_class.h32
-rw-r--r--drivers/staging/lustre/lustre/include/obd_ost.h6
-rw-r--r--drivers/staging/lustre/lustre/include/obd_support.h23
-rw-r--r--drivers/staging/lustre/lustre/lclient/glimpse.c28
-rw-r--r--drivers/staging/lustre/lustre/lclient/lcommon_cl.c37
-rw-r--r--drivers/staging/lustre/lustre/lclient/lcommon_misc.c16
-rw-r--r--drivers/staging/lustre/lustre/ldlm/interval_tree.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/l_lock.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_extent.c16
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_flock.c14
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c7
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lib.c46
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lock.c53
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c15
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_plain.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_pool.c38
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_request.c38
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_resource.c39
-rw-r--r--drivers/staging/lustre/lustre/libcfs/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/libcfs/debug.c10
-rw-r--r--drivers/staging/lustre/lustre/libcfs/fail.c12
-rw-r--r--drivers/staging/lustre/lustre/libcfs/hash.c6
-rw-r--r--drivers/staging/lustre/lustre/libcfs/heap.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_lock.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_mem.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_string.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c5
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c4
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.h (renamed from drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h)20
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c6
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-module.c16
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c6
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c94
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c31
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c6
-rw-r--r--drivers/staging/lustre/lustre/libcfs/module.c11
-rw-r--r--drivers/staging/lustre/lustre/libcfs/nidstrings.c9
-rw-r--r--drivers/staging/lustre/lustre/libcfs/prng.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/tracefile.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/tracefile.h2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/upcall_cache.c26
-rw-r--r--drivers/staging/lustre/lustre/libcfs/workitem.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/llite/dcache.c16
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c62
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c24
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_capa.c24
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_close.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h26
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c52
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_mmap.c6
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_nfs.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_rmtacl.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/lloop.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c79
-rw-r--r--drivers/staging/lustre/lustre/llite/namei.c14
-rw-r--r--drivers/staging/lustre/lustre/llite/remote_perm.c14
-rw-r--r--drivers/staging/lustre/lustre/llite/rw.c15
-rw-r--r--drivers/staging/lustre/lustre/llite/rw26.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/statahead.c30
-rw-r--r--drivers/staging/lustre/lustre/llite/super25.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/symlink.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_dev.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c10
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_lock.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_object.c6
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_page.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr.c11
-rw-r--r--drivers/staging/lustre/lustre/llite/xattr_cache.c8
-rw-r--r--drivers/staging/lustre/lustre/lmv/Makefile2
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_fld.c20
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_intent.c17
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c30
-rw-r--r--drivers/staging/lustre/lustre/lmv/lproc_lmv.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/Makefile4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_cl_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_dev.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_ea.c8
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_internal.h8
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_io.c6
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_merge.c31
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_obd.c52
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_offset.c6
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pack.c12
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pool.c10
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_request.c43
-rw-r--r--drivers/staging/lustre/lustre/lov/lproc_lov.c8
-rw-r--r--drivers/staging/lustre/lustre/lvfs/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/lvfs/fsfilt.c4
-rw-r--r--drivers/staging/lustre/lustre/lvfs/lvfs_lib.c4
-rw-r--r--drivers/staging/lustre/lustre/lvfs/lvfs_linux.c18
-rw-r--r--drivers/staging/lustre/lustre/mdc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/mdc/lproc_mdc.c48
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_lib.c4
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_locks.c18
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_reint.c6
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_request.c34
-rw-r--r--drivers/staging/lustre/lustre/mgc/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/mgc/libmgc.c12
-rw-r--r--drivers/staging/lustre/lustre/mgc/lproc_mgc.c4
-rw-r--r--drivers/staging/lustre/lustre/mgc/mgc_internal.h16
-rw-r--r--drivers/staging/lustre/lustre/mgc/mgc_request.c29
-rw-r--r--drivers/staging/lustre/lustre/obdclass/Makefile3
-rw-r--r--drivers/staging/lustre/lustre/obdclass/acl.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/capa.c23
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_io.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_lock.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c15
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_page.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/class_obd.c56
-rw-r--r--drivers/staging/lustre/lustre/obdclass/debug.c24
-rw-r--r--drivers/staging/lustre/lustre/obdclass/dt_object.c22
-rw-r--r--drivers/staging/lustre/lustre/obdclass/genops.c16
-rw-r--r--drivers/staging/lustre/lustre/obdclass/idmap.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linkea.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c20
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c98
-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_ioctl.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_lvfs.c50
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_obd.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_osd.c22
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_swab.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_test.c12
-rw-r--r--drivers/staging/lustre/lustre/obdclass/local_storage.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/local_storage.h8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_status.c48
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_object.c18
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_ref.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lu_ucred.c8
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_handles.c14
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lustre_peer.c14
-rw-r--r--drivers/staging/lustre/lustre/obdclass/md_attrs.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/mea.c6
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_config.c22
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_mount.c32
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obdo.c8
-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.c34
-rw-r--r--drivers/staging/lustre/lustre/obdecho/echo_client.c40
-rw-r--r--drivers/staging/lustre/lustre/obdecho/lproc_echo.c16
-rw-r--r--drivers/staging/lustre/lustre/osc/Makefile4
-rw-r--r--drivers/staging/lustre/lustre/osc/lproc_osc.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c13
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cl_internal.h14
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_dev.c16
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_io.c4
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_lock.c17
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_object.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_page.c6
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_quota.c2
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c93
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/Makefile5
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/client.c92
-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.c27
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/Makefile8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_api.h179
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h84
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_bulk.c505
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_cli_upcall.c446
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h193
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_generic_token.c296
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_internal.h526
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c1409
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5.h163
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c1786
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_mech_switch.c358
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_pipefs.c1233
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_rawobj.c242
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/gss_svc_upcall.c1093
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c220
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c2889
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/import.c89
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/layout.c16
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/llog_client.c8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/llog_net.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c29
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/niobuf.c49
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/nrs.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c14
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pack_generic.c38
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pers.c10
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pinger.c26
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h6
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c8
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c19
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/recover.c26
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec.c42
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c40
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_config.c24
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_gc.c16
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c20
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_null.c21
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_plain.c22
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/service.c84
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/wiretest.c8
-rw-r--r--drivers/staging/media/Kconfig10
-rw-r--r--drivers/staging/media/Makefile5
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.c22
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h1
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipeif.c5
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_resizer.c4
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c1
-rw-r--r--drivers/staging/media/go7007/README137
-rw-r--r--drivers/staging/media/go7007/go7007.h40
-rw-r--r--drivers/staging/media/go7007/go7007.txt478
-rw-r--r--drivers/staging/media/go7007/saa7134-go7007.c567
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c6
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c9
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c32
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c37
-rw-r--r--drivers/staging/media/lirc/lirc_sir.c301
-rw-r--r--drivers/staging/media/msi3101/Kconfig10
-rw-r--r--drivers/staging/media/msi3101/Makefile2
-rw-r--r--drivers/staging/media/omap4iss/Kconfig2
-rw-r--r--drivers/staging/media/omap4iss/iss.c86
-rw-r--r--drivers/staging/media/omap4iss/iss.h2
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c2
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c22
-rw-r--r--drivers/staging/media/rtl2832u_sdr/Kconfig7
-rw-r--r--drivers/staging/media/rtl2832u_sdr/Makefile6
-rw-r--r--drivers/staging/media/sn9c102/Kconfig17
-rw-r--r--drivers/staging/media/sn9c102/Makefile15
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.h214
-rw-r--r--drivers/staging/media/sn9c102/sn9c102.txt592
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_config.h86
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_core.c3465
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_devtable.h145
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131d.c269
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_hv7131r.c369
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0343.c352
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mi0360.c453
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_mt9v111.c260
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7630.c634
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_ov7660.c546
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas106b.c308
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_pas202bcb.c340
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_sensor.h307
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c154
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5110d.c119
-rw-r--r--drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c165
-rw-r--r--drivers/staging/media/solo6x10/TODO15
-rw-r--r--drivers/staging/netlogic/xlr_net.c1
-rw-r--r--drivers/staging/nokia_h4p/nokia_core.c1
-rw-r--r--drivers/staging/nvec/nvec.c17
-rw-r--r--drivers/staging/nvec/nvec_paz00.c1
-rw-r--r--drivers/staging/nvec/nvec_power.c1
-rw-r--r--drivers/staging/nvec/nvec_ps2.c2
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.c69
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c79
-rw-r--r--drivers/staging/octeon/ethernet-mem.c11
-rw-r--r--drivers/staging/octeon/ethernet-rgmii.c23
-rw-r--r--drivers/staging/octeon/ethernet-sgmii.c87
-rw-r--r--drivers/staging/octeon/ethernet-xaui.c84
-rw-r--r--drivers/staging/octeon/ethernet.c2
-rw-r--r--drivers/staging/octeon/octeon-ethernet.h4
-rw-r--r--drivers/staging/panel/panel.c9
-rw-r--r--drivers/staging/phison/Kconfig5
-rw-r--r--drivers/staging/phison/Makefile1
-rw-r--r--drivers/staging/phison/phison.c94
-rw-r--r--drivers/staging/quickstart/Kconfig10
-rw-r--r--drivers/staging/quickstart/Makefile1
-rw-r--r--drivers/staging/quickstart/quickstart.c458
-rw-r--r--drivers/staging/rtl8188eu/Kconfig8
-rw-r--r--drivers/staging/rtl8188eu/Makefile9
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c60
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_br_ext.c1191
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_cmd.c909
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_debug.c28
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_efuse.c1509
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ieee80211.c262
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_io.c301
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ioctl_set.c480
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_iol.c14
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_led.c52
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme.c216
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c3224
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mp.c995
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mp_ioctl.c1430
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_p2p.c2041
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_pwrctrl.c171
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_recv.c80
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_security.c59
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_sreset.c19
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_sta_mgt.c54
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_wlan_util.c19
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_xmit.c252
-rw-r--r--drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c10
-rw-r--r--drivers/staging/rtl8188eu/hal/HalPhyRf.c49
-rw-r--r--drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c99
-rw-r--r--drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c7
-rw-r--r--drivers/staging/rtl8188eu/hal/hal_com.c60
-rw-r--r--drivers/staging/rtl8188eu/hal/hal_intf.c67
-rw-r--r--drivers/staging/rtl8188eu/hal/odm.c28
-rw-r--r--drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c2
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c107
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_dm.c8
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c1395
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_mp.c854
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c26
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c2
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c2
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c80
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_led.c15
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c6
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c33
-rw-r--r--drivers/staging/rtl8188eu/hal/usb_halinit.c560
-rw-r--r--drivers/staging/rtl8188eu/hal/usb_ops_linux.c684
-rw-r--r--drivers/staging/rtl8188eu/include/Hal8188EReg.h46
-rw-r--r--drivers/staging/rtl8188eu/include/HalPhyRf.h30
-rw-r--r--drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h2
-rw-r--r--drivers/staging/rtl8188eu/include/cmd_osdep.h32
-rw-r--r--drivers/staging/rtl8188eu/include/drv_types.h78
-rw-r--r--drivers/staging/rtl8188eu/include/hal_com.h4
-rw-r--r--drivers/staging/rtl8188eu/include/hal_intf.h46
-rw-r--r--drivers/staging/rtl8188eu/include/ieee80211.h13
-rw-r--r--drivers/staging/rtl8188eu/include/odm_precomp.h4
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_intf.h38
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_service.h178
-rw-r--r--drivers/staging/rtl8188eu/include/recv_osdep.h3
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_cmd.h5
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_hal.h14
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_sreset.h31
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_xmit.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_br_ext.h66
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_cmd.h612
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_debug.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_efuse.h51
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_io.h343
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_ioctl_set.h8
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_iol.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme.h28
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme_ext.h93
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mp.h495
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mp_ioctl.h340
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_p2p.h135
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_security.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_sreset.h5
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_version.h1
-rw-r--r--drivers/staging/rtl8188eu/include/sta_info.h15
-rw-r--r--drivers/staging/rtl8188eu/include/usb_ops.h114
-rw-r--r--drivers/staging/rtl8188eu/include/usb_ops_linux.h42
-rw-r--r--drivers/staging/rtl8188eu/include/usb_osintf.h45
-rw-r--r--drivers/staging/rtl8188eu/include/usb_vendor_req.h52
-rw-r--r--drivers/staging/rtl8188eu/include/wlan_bssdef.h4
-rw-r--r--drivers/staging/rtl8188eu/os_dep/ioctl_linux.c5151
-rw-r--r--drivers/staging/rtl8188eu/os_dep/mlme_linux.c64
-rw-r--r--drivers/staging/rtl8188eu/os_dep/os_intfs.c111
-rw-r--r--drivers/staging/rtl8188eu/os_dep/osdep_service.c287
-rw-r--r--drivers/staging/rtl8188eu/os_dep/recv_linux.c28
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_intf.c255
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c646
-rw-r--r--drivers/staging/rtl8188eu/os_dep/xmit_linux.c5
-rw-r--r--drivers/staging/rtl8192e/dot11d.c8
-rw-r--r--drivers/staging/rtl8192e/rtllib_module.c5
-rw-r--r--drivers/staging/rtl8192e/rtllib_rx.c3
-rw-r--r--drivers/staging/rtl8192ee/Kconfig1
-rw-r--r--drivers/staging/rtl8192ee/base.c5
-rw-r--r--drivers/staging/rtl8192ee/base.h4
-rw-r--r--drivers/staging/rtl8192ee/btcoexist/halbtc8821a2ant.c2
-rw-r--r--drivers/staging/rtl8192ee/btcoexist/halbtcoutsrc.h2
-rw-r--r--drivers/staging/rtl8192ee/pci.c2
-rw-r--r--drivers/staging/rtl8192ee/rtl8192ee/trx.c4
-rw-r--r--drivers/staging/rtl8192ee/rtl8192ee/trx.h2
-rw-r--r--drivers/staging/rtl8192ee/wifi.h2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211.h10
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c8
-rw-r--r--drivers/staging/rtl8192u/r8180_93cx6.c15
-rw-r--r--drivers/staging/rtl8192u/r8180_93cx6.h11
-rw-r--r--drivers/staging/rtl8192u/r8190_rtl8256.c169
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c548
-rw-r--r--drivers/staging/rtl8192u/r8192U_wx.c159
-rw-r--r--drivers/staging/rtl8192u/r819xU_phy.c25
-rw-r--r--drivers/staging/rtl8712/drv_types.h3
-rw-r--r--drivers/staging/rtl8712/hal_init.c2
-rw-r--r--drivers/staging/rtl8712/ieee80211.h4
-rw-r--r--drivers/staging/rtl8712/mlme_linux.c3
-rw-r--r--drivers/staging/rtl8712/os_intfs.c3
-rw-r--r--drivers/staging/rtl8712/osdep_service.h82
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.c6
-rw-r--r--drivers/staging/rtl8712/rtl8712_led.c4
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.c57
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.c20
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.c114
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.h2
-rw-r--r--drivers/staging/rtl8712/rtl871x_io.c12
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c31
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_set.c6
-rw-r--r--drivers/staging/rtl8712/rtl871x_led.h2
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c64
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp.c8
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.c10
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.h4
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.c18
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c51
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c56
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.h6
-rw-r--r--drivers/staging/rtl8712/usb_intf.c40
-rw-r--r--drivers/staging/rtl8723au/Makefile4
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ap.c205
-rw-r--r--drivers/staging/rtl8723au/core/rtw_cmd.c42
-rw-r--r--drivers/staging/rtl8723au/core/rtw_efuse.c31
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ieee80211.c348
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ioctl_set.c425
-rw-r--r--drivers/staging/rtl8723au/core/rtw_mlme.c541
-rw-r--r--drivers/staging/rtl8723au/core/rtw_mlme_ext.c1747
-rw-r--r--drivers/staging/rtl8723au/core/rtw_pwrctrl.c56
-rw-r--r--drivers/staging/rtl8723au/core/rtw_recv.c8
-rw-r--r--drivers/staging/rtl8723au/core/rtw_sreset.c49
-rw-r--r--drivers/staging/rtl8723au/core/rtw_sta_mgt.c63
-rw-r--r--drivers/staging/rtl8723au/core/rtw_wlan_util.c418
-rw-r--r--drivers/staging/rtl8723au/core/rtw_xmit.c12
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c160
-rw-r--r--drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c5
-rw-r--r--drivers/staging/rtl8723au/hal/hal_com.c36
-rw-r--r--drivers/staging/rtl8723au/hal/odm.c429
-rw-r--r--drivers/staging/rtl8723au/hal/odm_HWConfig.c68
-rw-r--r--drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c58
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c5
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_cmd.c89
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_dm.c81
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c125
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c28
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c13
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_sreset.c19
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_xmit.c21
-rw-r--r--drivers/staging/rtl8723au/hal/usb_halinit.c162
-rw-r--r--drivers/staging/rtl8723au/hal/usb_ops_linux.c317
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723APhyCfg.h1
-rw-r--r--drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h6
-rw-r--r--drivers/staging/rtl8723au/include/drv_types.h15
-rw-r--r--drivers/staging/rtl8723au/include/hal_com.h3
-rw-r--r--drivers/staging/rtl8723au/include/hal_intf.h5
-rw-r--r--drivers/staging/rtl8723au/include/ieee80211.h109
-rw-r--r--drivers/staging/rtl8723au/include/ioctl_cfg80211.h3
-rw-r--r--drivers/staging/rtl8723au/include/odm.h102
-rw-r--r--drivers/staging/rtl8723au/include/odm_HWConfig.h17
-rw-r--r--drivers/staging/rtl8723au/include/odm_RegConfig8723A.h6
-rw-r--r--drivers/staging/rtl8723au/include/odm_RegDefine11AC.h49
-rw-r--r--drivers/staging/rtl8723au/include/odm_interface.h11
-rw-r--r--drivers/staging/rtl8723au/include/odm_precomp.h1
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_cmd.h2
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_dm.h4
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_hal.h5
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_spec.h10
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_sreset.h1
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_xmit.h1
-rw-r--r--drivers/staging/rtl8723au/include/rtw_ap.h3
-rw-r--r--drivers/staging/rtl8723au/include/rtw_debug.h2
-rw-r--r--drivers/staging/rtl8723au/include/rtw_event.h2
-rw-r--r--drivers/staging/rtl8723au/include/rtw_ht.h4
-rw-r--r--drivers/staging/rtl8723au/include/rtw_ioctl_set.h32
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme.h50
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme_ext.h37
-rw-r--r--drivers/staging/rtl8723au/include/rtw_pwrctrl.h20
-rw-r--r--drivers/staging/rtl8723au/include/rtw_rf.h11
-rw-r--r--drivers/staging/rtl8723au/include/rtw_security.h3
-rw-r--r--drivers/staging/rtl8723au/include/rtw_sreset.h20
-rw-r--r--drivers/staging/rtl8723au/include/sta_info.h2
-rw-r--r--drivers/staging/rtl8723au/include/usb_ops_linux.h14
-rw-r--r--drivers/staging/rtl8723au/include/wifi.h71
-rw-r--r--drivers/staging/rtl8723au/include/wlan_bssdef.h6
-rw-r--r--drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c1105
-rw-r--r--drivers/staging/rtl8723au/os_dep/mlme_linux.c1
-rw-r--r--drivers/staging/rtl8723au/os_dep/os_intfs.c19
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_intf.c97
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_ops_linux.c10
-rw-r--r--drivers/staging/rtl8821ae/Kconfig1
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c14
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h2
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h2
-rw-r--r--drivers/staging/rtl8821ae/cam.c7
-rw-r--r--drivers/staging/rtl8821ae/pci.c2
-rw-r--r--drivers/staging/rtl8821ae/ps.c6
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c17
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hw.c2
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/reg.h1
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/sw.c4
-rw-r--r--drivers/staging/rtl8821ae/wifi.h2
-rw-r--r--drivers/staging/rts5208/debug.h43
-rw-r--r--drivers/staging/rts5208/ms.c126
-rw-r--r--drivers/staging/rts5208/rtsx.c10
-rw-r--r--drivers/staging/rts5208/rtsx.h1
-rw-r--r--drivers/staging/rts5208/rtsx_card.c73
-rw-r--r--drivers/staging/rts5208/rtsx_card.h1
-rw-r--r--drivers/staging/rts5208/rtsx_chip.c133
-rw-r--r--drivers/staging/rts5208/rtsx_chip.h5
-rw-r--r--drivers/staging/rts5208/rtsx_scsi.c44
-rw-r--r--drivers/staging/rts5208/rtsx_scsi.h2
-rw-r--r--drivers/staging/rts5208/rtsx_transport.c55
-rw-r--r--drivers/staging/rts5208/sd.c185
-rw-r--r--drivers/staging/rts5208/spi.c7
-rw-r--r--drivers/staging/rts5208/trace.h10
-rw-r--r--drivers/staging/rts5208/xd.c104
-rw-r--r--drivers/staging/sep/Kconfig11
-rw-r--r--drivers/staging/sep/Makefile3
-rw-r--r--drivers/staging/sep/TODO3
-rw-r--r--drivers/staging/sep/sep_crypto.c3962
-rw-r--r--drivers/staging/sep/sep_crypto.h359
-rw-r--r--drivers/staging/sep/sep_dev.h162
-rw-r--r--drivers/staging/sep/sep_driver_api.h402
-rw-r--r--drivers/staging/sep/sep_driver_config.h298
-rw-r--r--drivers/staging/sep/sep_driver_hw_defs.h56
-rw-r--r--drivers/staging/sep/sep_main.c4452
-rw-r--r--drivers/staging/sep/sep_trace_events.h193
-rw-r--r--drivers/staging/serqt_usb2/Kconfig9
-rw-r--r--drivers/staging/serqt_usb2/Makefile1
-rw-r--r--drivers/staging/serqt_usb2/serqt_usb2.c1528
-rw-r--r--drivers/staging/silicom/Kconfig45
-rw-r--r--drivers/staging/silicom/Makefile6
-rw-r--r--drivers/staging/silicom/README14
-rw-r--r--drivers/staging/silicom/TODO8
-rw-r--r--drivers/staging/silicom/bits.h56
-rw-r--r--drivers/staging/silicom/bp_ioctl.h140
-rw-r--r--drivers/staging/silicom/bp_mod.h711
-rw-r--r--drivers/staging/silicom/bpctl_mod.c7530
-rw-r--r--drivers/staging/silicom/bypass.h202
-rw-r--r--drivers/staging/silicom/bypasslib/Makefile6
-rw-r--r--drivers/staging/silicom/bypasslib/bp_ioctl.h198
-rw-r--r--drivers/staging/silicom/bypasslib/bplibk.h36
-rw-r--r--drivers/staging/silicom/bypasslib/bypass.c536
-rw-r--r--drivers/staging/silicom/bypasslib/libbp_sd.h532
-rw-r--r--drivers/staging/silicom/libbp_sd.h550
-rw-r--r--drivers/staging/skein/skein_iv.h26
-rw-r--r--drivers/staging/slicoss/slicoss.c22
-rw-r--r--drivers/staging/speakup/TODO2
-rw-r--r--drivers/staging/speakup/main.c2
-rw-r--r--drivers/staging/speakup/speakup_dectlk.c2
-rw-r--r--drivers/staging/tidspbridge/Documentation/CONTRIBUTORS45
-rw-r--r--drivers/staging/tidspbridge/Documentation/README70
-rw-r--r--drivers/staging/tidspbridge/Documentation/error-codes157
-rw-r--r--drivers/staging/tidspbridge/Kconfig69
-rw-r--r--drivers/staging/tidspbridge/Makefile32
-rw-r--r--drivers/staging/tidspbridge/TODO18
-rw-r--r--drivers/staging/tidspbridge/core/_cmm.h45
-rw-r--r--drivers/staging/tidspbridge/core/_deh.h35
-rw-r--r--drivers/staging/tidspbridge/core/_msg_sm.h142
-rw-r--r--drivers/staging/tidspbridge/core/_tiomap.h382
-rw-r--r--drivers/staging/tidspbridge/core/_tiomap_pwr.h85
-rw-r--r--drivers/staging/tidspbridge/core/chnl_sm.c907
-rw-r--r--drivers/staging/tidspbridge/core/dsp-clock.c391
-rw-r--r--drivers/staging/tidspbridge/core/io_sm.c2245
-rw-r--r--drivers/staging/tidspbridge/core/msg_sm.c564
-rw-r--r--drivers/staging/tidspbridge/core/sync.c121
-rw-r--r--drivers/staging/tidspbridge/core/tiomap3430.c1811
-rw-r--r--drivers/staging/tidspbridge/core/tiomap3430_pwr.c556
-rw-r--r--drivers/staging/tidspbridge/core/tiomap_io.c438
-rw-r--r--drivers/staging/tidspbridge/core/tiomap_io.h104
-rw-r--r--drivers/staging/tidspbridge/core/ue_deh.c272
-rw-r--r--drivers/staging/tidspbridge/core/wdt.c143
-rw-r--r--drivers/staging/tidspbridge/dynload/cload.c1952
-rw-r--r--drivers/staging/tidspbridge/dynload/dload_internal.h344
-rw-r--r--drivers/staging/tidspbridge/dynload/doff.h354
-rw-r--r--drivers/staging/tidspbridge/dynload/getsection.c407
-rw-r--r--drivers/staging/tidspbridge/dynload/header.h49
-rw-r--r--drivers/staging/tidspbridge/dynload/module_list.h159
-rw-r--r--drivers/staging/tidspbridge/dynload/params.h226
-rw-r--r--drivers/staging/tidspbridge/dynload/reloc.c484
-rw-r--r--drivers/staging/tidspbridge/dynload/reloc_table.h102
-rw-r--r--drivers/staging/tidspbridge/dynload/reloc_table_c6000.c257
-rw-r--r--drivers/staging/tidspbridge/dynload/tramp.c1143
-rw-r--r--drivers/staging/tidspbridge/dynload/tramp_table_c6000.c164
-rw-r--r--drivers/staging/tidspbridge/gen/gh.c141
-rw-r--r--drivers/staging/tidspbridge/hw/EasiGlobal.h41
-rw-r--r--drivers/staging/tidspbridge/hw/MMUAccInt.h76
-rw-r--r--drivers/staging/tidspbridge/hw/MMURegAcM.h225
-rw-r--r--drivers/staging/tidspbridge/hw/hw_defs.h58
-rw-r--r--drivers/staging/tidspbridge/hw/hw_mmu.c487
-rw-r--r--drivers/staging/tidspbridge/hw/hw_mmu.h160
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h177
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/brddefs.h37
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h61
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/chnl.h80
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/chnldefs.h63
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h85
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/clk.h101
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/cmm.h337
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h104
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/cod.h329
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dbdcd.h358
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h78
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dbdefs.h488
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dbll.h56
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dblldefs.h431
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dev.h620
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/devdefs.h26
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/disp.h186
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dmm.h71
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/drv.h468
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h467
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspapi.h167
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspchnl.h72
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspdefs.h1048
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspdeh.h43
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspdrv.h60
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspio.h41
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspioctl.h68
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dspmsg.h56
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h490
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/getsection.h108
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/gh.h32
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/host_os.h57
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/io.h80
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/io_sm.h160
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h144
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/memdefs.h30
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/mgr.h205
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h45
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/msg.h59
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/msgdefs.h29
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/nldr.h55
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h259
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/node.h524
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/nodedefs.h28
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/nodepriv.h181
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/ntfy.h217
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/proc.h591
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/procpriv.h25
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/pwr.h113
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h41
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/rmm.h156
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/rms_sh.h86
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/rmstypes.h24
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/strm.h306
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/strmdefs.h44
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/sync.h119
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/uuidutil.h24
-rw-r--r--drivers/staging/tidspbridge/include/dspbridge/wdt.h79
-rw-r--r--drivers/staging/tidspbridge/pmgr/chnl.c115
-rw-r--r--drivers/staging/tidspbridge/pmgr/chnlobj.h46
-rw-r--r--drivers/staging/tidspbridge/pmgr/cmm.c915
-rw-r--r--drivers/staging/tidspbridge/pmgr/cod.c537
-rw-r--r--drivers/staging/tidspbridge/pmgr/dbll.c1421
-rw-r--r--drivers/staging/tidspbridge/pmgr/dev.c969
-rw-r--r--drivers/staging/tidspbridge/pmgr/dmm.c487
-rw-r--r--drivers/staging/tidspbridge/pmgr/dspapi.c1843
-rw-r--r--drivers/staging/tidspbridge/pmgr/io.c93
-rw-r--r--drivers/staging/tidspbridge/pmgr/ioobj.h38
-rw-r--r--drivers/staging/tidspbridge/pmgr/msg.c91
-rw-r--r--drivers/staging/tidspbridge/pmgr/msgobj.h38
-rw-r--r--drivers/staging/tidspbridge/rmgr/dbdcd.c1483
-rw-r--r--drivers/staging/tidspbridge/rmgr/disp.c655
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c816
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv_interface.c648
-rw-r--r--drivers/staging/tidspbridge/rmgr/dspdrv.c139
-rw-r--r--drivers/staging/tidspbridge/rmgr/mgr.c352
-rw-r--r--drivers/staging/tidspbridge/rmgr/nldr.c1860
-rw-r--r--drivers/staging/tidspbridge/rmgr/node.c3029
-rw-r--r--drivers/staging/tidspbridge/rmgr/proc.c1833
-rw-r--r--drivers/staging/tidspbridge/rmgr/pwr.c176
-rw-r--r--drivers/staging/tidspbridge/rmgr/rmm.c456
-rw-r--r--drivers/staging/tidspbridge/rmgr/strm.c733
-rw-r--r--drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset101
-rw-r--r--drivers/staging/unisys/Kconfig2
-rw-r--r--drivers/staging/unisys/channels/Kconfig2
-rw-r--r--drivers/staging/unisys/channels/Makefile2
-rw-r--r--drivers/staging/unisys/channels/channel.c8
-rw-r--r--drivers/staging/unisys/channels/chanstub.c4
-rw-r--r--drivers/staging/unisys/channels/chanstub.h4
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/channel.h158
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/controlframework.h26
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h250
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/diagchannel.h62
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/iochannel.h160
-rw-r--r--drivers/staging/unisys/common-spar/include/channels/vbuschannel.h50
-rw-r--r--drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h42
-rw-r--r--drivers/staging/unisys/common-spar/include/vmcallinterface.h26
-rw-r--r--drivers/staging/unisys/include/commontypes.h85
-rw-r--r--drivers/staging/unisys/include/guestlinuxdebug.h20
-rw-r--r--drivers/staging/unisys/include/uisqueue.h98
-rw-r--r--drivers/staging/unisys/include/uisutils.h94
-rw-r--r--drivers/staging/unisys/include/vbushelper.h8
-rw-r--r--drivers/staging/unisys/uislib/Makefile3
-rw-r--r--drivers/staging/unisys/uislib/uislib.c86
-rw-r--r--drivers/staging/unisys/uislib/uisqueue.c10
-rw-r--r--drivers/staging/unisys/uislib/uisutils.c15
-rw-r--r--drivers/staging/unisys/virthba/Makefile3
-rw-r--r--drivers/staging/unisys/virthba/virthba.c222
-rw-r--r--drivers/staging/unisys/virtpci/Makefile3
-rw-r--r--drivers/staging/unisys/virtpci/virtpci.c353
-rw-r--r--drivers/staging/unisys/virtpci/virtpci.h6
-rw-r--r--drivers/staging/unisys/visorchannel/Makefile2
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel.h16
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel_funcs.c34
-rw-r--r--drivers/staging/unisys/visorchipset/Makefile5
-rw-r--r--drivers/staging/unisys/visorchipset/controlvm.h27
-rw-r--r--drivers/staging/unisys/visorchipset/controlvm_direct.c62
-rw-r--r--drivers/staging/unisys/visorchipset/file.c4
-rw-r--r--drivers/staging/unisys/visorchipset/parser.c6
-rw-r--r--drivers/staging/unisys/visorchipset/parser.h4
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset.h90
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_main.c1146
-rw-r--r--drivers/staging/unisys/visorutil/Makefile1
-rw-r--r--drivers/staging/unisys/visorutil/memregion_direct.c2
-rw-r--r--drivers/staging/usbip/stub_main.c10
-rw-r--r--drivers/staging/usbip/stub_rx.c1
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c7
-rw-r--r--drivers/staging/usbip/vhci_hcd.c3
-rw-r--r--drivers/staging/usbip/vhci_rx.c2
-rw-r--r--drivers/staging/vme/devices/vme_pio2_core.c12
-rw-r--r--drivers/staging/vme/devices/vme_pio2_gpio.c6
-rw-r--r--drivers/staging/vme/devices/vme_user.c4
-rw-r--r--drivers/staging/vt6655/80211hdr.h7
-rw-r--r--drivers/staging/vt6655/80211mgr.c37
-rw-r--r--drivers/staging/vt6655/80211mgr.h38
-rw-r--r--drivers/staging/vt6655/IEEE11h.c175
-rw-r--r--drivers/staging/vt6655/IEEE11h.h10
-rw-r--r--drivers/staging/vt6655/aes_ccmp.c1
-rw-r--r--drivers/staging/vt6655/aes_ccmp.h9
-rw-r--r--drivers/staging/vt6655/baseband.c350
-rw-r--r--drivers/staging/vt6655/baseband.h36
-rw-r--r--drivers/staging/vt6655/bssdb.c74
-rw-r--r--drivers/staging/vt6655/bssdb.h28
-rw-r--r--drivers/staging/vt6655/card.c40
-rw-r--r--drivers/staging/vt6655/card.h18
-rw-r--r--drivers/staging/vt6655/channel.h4
-rw-r--r--drivers/staging/vt6655/country.h1
-rw-r--r--drivers/staging/vt6655/datarate.c37
-rw-r--r--drivers/staging/vt6655/datarate.h28
-rw-r--r--drivers/staging/vt6655/desc.h185
-rw-r--r--drivers/staging/vt6655/device.h78
-rw-r--r--drivers/staging/vt6655/device_cfg.h5
-rw-r--r--drivers/staging/vt6655/device_main.c779
-rw-r--r--drivers/staging/vt6655/dpc.c48
-rw-r--r--drivers/staging/vt6655/dpc.h10
-rw-r--r--drivers/staging/vt6655/hostap.c48
-rw-r--r--drivers/staging/vt6655/hostap.h8
-rw-r--r--drivers/staging/vt6655/iocmd.h25
-rw-r--r--drivers/staging/vt6655/ioctl.c8
-rw-r--r--drivers/staging/vt6655/ioctl.h8
-rw-r--r--drivers/staging/vt6655/iowpa.h10
-rw-r--r--drivers/staging/vt6655/iwctl.c134
-rw-r--r--drivers/staging/vt6655/iwctl.h18
-rw-r--r--drivers/staging/vt6655/key.c33
-rw-r--r--drivers/staging/vt6655/key.h25
-rw-r--r--drivers/staging/vt6655/mac.c104
-rw-r--r--drivers/staging/vt6655/mac.h107
-rw-r--r--drivers/staging/vt6655/mib.h45
-rw-r--r--drivers/staging/vt6655/michael.h6
-rw-r--r--drivers/staging/vt6655/power.c9
-rw-r--r--drivers/staging/vt6655/power.h9
-rw-r--r--drivers/staging/vt6655/rc4.c1
-rw-r--r--drivers/staging/vt6655/rf.c20
-rw-r--r--drivers/staging/vt6655/rf.h8
-rw-r--r--drivers/staging/vt6655/rxtx.c26
-rw-r--r--drivers/staging/vt6655/srom.c24
-rw-r--r--drivers/staging/vt6655/srom.h24
-rw-r--r--drivers/staging/vt6655/tcrc.c2
-rw-r--r--drivers/staging/vt6655/upc.h52
-rw-r--r--drivers/staging/vt6655/vntwifi.c19
-rw-r--r--drivers/staging/vt6655/wcmd.c39
-rw-r--r--drivers/staging/vt6655/wcmd.h15
-rw-r--r--drivers/staging/vt6655/wmgr.c89
-rw-r--r--drivers/staging/vt6655/wmgr.h12
-rw-r--r--drivers/staging/vt6655/wpa.c10
-rw-r--r--drivers/staging/vt6655/wpactl.c8
-rw-r--r--drivers/staging/vt6656/80211hdr.h324
-rw-r--r--drivers/staging/vt6656/80211mgr.c861
-rw-r--r--drivers/staging/vt6656/80211mgr.h808
-rw-r--r--drivers/staging/vt6656/Kconfig4
-rw-r--r--drivers/staging/vt6656/Makefile13
-rw-r--r--drivers/staging/vt6656/baseband.c1034
-rw-r--r--drivers/staging/vt6656/baseband.h19
-rw-r--r--drivers/staging/vt6656/bssdb.c1466
-rw-r--r--drivers/staging/vt6656/bssdb.h276
-rw-r--r--drivers/staging/vt6656/card.c384
-rw-r--r--drivers/staging/vt6656/card.h48
-rw-r--r--drivers/staging/vt6656/channel.c549
-rw-r--r--drivers/staging/vt6656/channel.h9
-rw-r--r--drivers/staging/vt6656/country.h162
-rw-r--r--drivers/staging/vt6656/datarate.c364
-rw-r--r--drivers/staging/vt6656/datarate.h76
-rw-r--r--drivers/staging/vt6656/desc.h2
-rw-r--r--drivers/staging/vt6656/device.h544
-rw-r--r--drivers/staging/vt6656/dpc.c999
-rw-r--r--drivers/staging/vt6656/dpc.h11
-rw-r--r--drivers/staging/vt6656/firmware.c78
-rw-r--r--drivers/staging/vt6656/firmware.h6
-rw-r--r--drivers/staging/vt6656/int.c213
-rw-r--r--drivers/staging/vt6656/int.h4
-rw-r--r--drivers/staging/vt6656/iocmd.h38
-rw-r--r--drivers/staging/vt6656/iowpa.h75
-rw-r--r--drivers/staging/vt6656/iwctl.c1802
-rw-r--r--drivers/staging/vt6656/iwctl.h138
-rw-r--r--drivers/staging/vt6656/key.c789
-rw-r--r--drivers/staging/vt6656/key.h79
-rw-r--r--drivers/staging/vt6656/mac.c37
-rw-r--r--drivers/staging/vt6656/mac.h708
-rw-r--r--drivers/staging/vt6656/main_usb.c1608
-rw-r--r--drivers/staging/vt6656/michael.c167
-rw-r--r--drivers/staging/vt6656/michael.h52
-rw-r--r--drivers/staging/vt6656/power.c254
-rw-r--r--drivers/staging/vt6656/power.h17
-rw-r--r--drivers/staging/vt6656/rc4.c87
-rw-r--r--drivers/staging/vt6656/rc4.h46
-rw-r--r--drivers/staging/vt6656/rf.c1303
-rw-r--r--drivers/staging/vt6656/rf.h11
-rw-r--r--drivers/staging/vt6656/rxtx.c2408
-rw-r--r--drivers/staging/vt6656/rxtx.h36
-rw-r--r--drivers/staging/vt6656/tether.c60
-rw-r--r--drivers/staging/vt6656/tether.h101
-rw-r--r--drivers/staging/vt6656/tkip.c246
-rw-r--r--drivers/staging/vt6656/tkip.h45
-rw-r--r--drivers/staging/vt6656/tmacro.h52
-rw-r--r--drivers/staging/vt6656/usbpipe.c321
-rw-r--r--drivers/staging/vt6656/usbpipe.h7
-rw-r--r--drivers/staging/vt6656/vntconfiguration.dat6
-rw-r--r--drivers/staging/vt6656/wcmd.c1066
-rw-r--r--drivers/staging/vt6656/wcmd.h91
-rw-r--r--drivers/staging/vt6656/wctl.c244
-rw-r--r--drivers/staging/vt6656/wctl.h94
-rw-r--r--drivers/staging/vt6656/wmgr.c4362
-rw-r--r--drivers/staging/vt6656/wmgr.h397
-rw-r--r--drivers/staging/vt6656/wpa.c314
-rw-r--r--drivers/staging/vt6656/wpa.h72
-rw-r--r--drivers/staging/vt6656/wpa2.c235
-rw-r--r--drivers/staging/vt6656/wpa2.h53
-rw-r--r--drivers/staging/vt6656/wpactl.c247
-rw-r--r--drivers/staging/vt6656/wpactl.h47
-rw-r--r--drivers/staging/winbond/Kconfig11
-rw-r--r--drivers/staging/winbond/Makefile15
-rw-r--r--drivers/staging/winbond/TODO12
-rw-r--r--drivers/staging/winbond/core.h61
-rw-r--r--drivers/staging/winbond/localpara.h311
-rw-r--r--drivers/staging/winbond/mac_structures.h71
-rw-r--r--drivers/staging/winbond/mds.c650
-rw-r--r--drivers/staging/winbond/mds_f.h22
-rw-r--r--drivers/staging/winbond/mds_s.h130
-rw-r--r--drivers/staging/winbond/mto.c167
-rw-r--r--drivers/staging/winbond/mto.h134
-rw-r--r--drivers/staging/winbond/phy_calibration.c1317
-rw-r--r--drivers/staging/winbond/phy_calibration.h85
-rw-r--r--drivers/staging/winbond/reg.c2328
-rw-r--r--drivers/staging/winbond/sme_api.h191
-rw-r--r--drivers/staging/winbond/wb35reg.c806
-rw-r--r--drivers/staging/winbond/wb35reg_f.h65
-rw-r--r--drivers/staging/winbond/wb35reg_s.h240
-rw-r--r--drivers/staging/winbond/wb35rx.c358
-rw-r--r--drivers/staging/winbond/wb35rx_f.h15
-rw-r--r--drivers/staging/winbond/wb35rx_s.h44
-rw-r--r--drivers/staging/winbond/wb35tx.c290
-rw-r--r--drivers/staging/winbond/wb35tx_f.h22
-rw-r--r--drivers/staging/winbond/wb35tx_s.h39
-rw-r--r--drivers/staging/winbond/wbhal.h513
-rw-r--r--drivers/staging/winbond/wbusb.c853
-rw-r--r--drivers/staging/wlags49_h2/Kconfig11
-rw-r--r--drivers/staging/wlags49_h2/Makefile53
-rw-r--r--drivers/staging/wlags49_h2/README.ubuntu180
-rw-r--r--drivers/staging/wlags49_h2/README.wlags49641
-rw-r--r--drivers/staging/wlags49_h2/TODO33
-rw-r--r--drivers/staging/wlags49_h2/WARNING.txt3
-rw-r--r--drivers/staging/wlags49_h2/ap_h2.c3337
-rw-r--r--drivers/staging/wlags49_h2/ap_h25.c4094
-rw-r--r--drivers/staging/wlags49_h2/debug.h199
-rw-r--r--drivers/staging/wlags49_h2/dhf.c380
-rw-r--r--drivers/staging/wlags49_h2/dhf.h225
-rw-r--r--drivers/staging/wlags49_h2/dhfcfg.h158
-rw-r--r--drivers/staging/wlags49_h2/hcf.c4748
-rw-r--r--drivers/staging/wlags49_h2/hcf.h394
-rw-r--r--drivers/staging/wlags49_h2/hcfcfg.h785
-rw-r--r--drivers/staging/wlags49_h2/hcfdef.h752
-rw-r--r--drivers/staging/wlags49_h2/man/wlags49.4734
-rw-r--r--drivers/staging/wlags49_h2/mdd.h1155
-rw-r--r--drivers/staging/wlags49_h2/mmd.c250
-rw-r--r--drivers/staging/wlags49_h2/mmd.h77
-rw-r--r--drivers/staging/wlags49_h2/sta_h2.c4480
-rw-r--r--drivers/staging/wlags49_h2/sta_h25.c5255
-rw-r--r--drivers/staging/wlags49_h2/wl_cs.c440
-rw-r--r--drivers/staging/wlags49_h2/wl_cs.h89
-rw-r--r--drivers/staging/wlags49_h2/wl_enc.c217
-rw-r--r--drivers/staging/wlags49_h2/wl_enc.h118
-rw-r--r--drivers/staging/wlags49_h2/wl_if.h221
-rw-r--r--drivers/staging/wlags49_h2/wl_internal.h1040
-rw-r--r--drivers/staging/wlags49_h2/wl_main.c3702
-rw-r--r--drivers/staging/wlags49_h2/wl_main.h138
-rw-r--r--drivers/staging/wlags49_h2/wl_netdev.c1951
-rw-r--r--drivers/staging/wlags49_h2/wl_netdev.h154
-rw-r--r--drivers/staging/wlags49_h2/wl_priv.c1928
-rw-r--r--drivers/staging/wlags49_h2/wl_priv.h127
-rw-r--r--drivers/staging/wlags49_h2/wl_profile.c995
-rw-r--r--drivers/staging/wlags49_h2/wl_profile.h87
-rw-r--r--drivers/staging/wlags49_h2/wl_util.c1367
-rw-r--r--drivers/staging/wlags49_h2/wl_util.h96
-rw-r--r--drivers/staging/wlags49_h2/wl_version.h146
-rw-r--r--drivers/staging/wlags49_h2/wl_wext.c3794
-rw-r--r--drivers/staging/wlags49_h2/wl_wext.h88
-rw-r--r--drivers/staging/wlags49_h25/Kconfig11
-rw-r--r--drivers/staging/wlags49_h25/Makefile52
-rw-r--r--drivers/staging/wlags49_h25/README.txt30
-rw-r--r--drivers/staging/wlags49_h25/TODO33
-rw-r--r--drivers/staging/wlags49_h25/ap_h25.c2
-rw-r--r--drivers/staging/wlags49_h25/debug.h2
-rw-r--r--drivers/staging/wlags49_h25/dhf.c2
-rw-r--r--drivers/staging/wlags49_h25/dhf.h2
-rw-r--r--drivers/staging/wlags49_h25/dhfcfg.h2
-rw-r--r--drivers/staging/wlags49_h25/hcf.c2
-rw-r--r--drivers/staging/wlags49_h25/hcf.h2
-rw-r--r--drivers/staging/wlags49_h25/hcfcfg.h2
-rw-r--r--drivers/staging/wlags49_h25/hcfdef.h2
-rw-r--r--drivers/staging/wlags49_h25/mdd.h2
-rw-r--r--drivers/staging/wlags49_h25/mmd.c2
-rw-r--r--drivers/staging/wlags49_h25/mmd.h2
-rw-r--r--drivers/staging/wlags49_h25/sta_h25.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_cs.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_cs.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_enc.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_enc.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_if.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_internal.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_main.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_main.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_netdev.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_netdev.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_priv.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_priv.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_profile.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_profile.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_util.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_util.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_version.h2
-rw-r--r--drivers/staging/wlags49_h25/wl_wext.c2
-rw-r--r--drivers/staging/wlags49_h25/wl_wext.h2
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c2
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c19
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c1
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c42
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h1
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c2
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c42
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c7
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c7
-rw-r--r--drivers/staging/xillybus/README23
-rw-r--r--drivers/staging/xillybus/xillybus.h48
-rw-r--r--drivers/staging/xillybus/xillybus_core.c541
-rw-r--r--drivers/staging/xillybus/xillybus_of.c72
-rw-r--r--drivers/staging/xillybus/xillybus_pcie.c66
-rw-r--r--drivers/target/loopback/tcm_loop.c2
-rw-r--r--drivers/target/target_core_pscsi.c12
-rw-r--r--drivers/target/target_core_tpg.c4
-rw-r--r--drivers/thermal/imx_thermal.c18
-rw-r--r--drivers/thermal/of-thermal.c7
-rw-r--r--drivers/thermal/thermal_hwmon.c33
-rw-r--r--drivers/thermal/ti-soc-thermal/ti-bandgap.c2
-rw-r--r--drivers/thunderbolt/Kconfig13
-rw-r--r--drivers/thunderbolt/Makefile3
-rw-r--r--drivers/thunderbolt/cap.c116
-rw-r--r--drivers/thunderbolt/ctl.c731
-rw-r--r--drivers/thunderbolt/ctl.h75
-rw-r--r--drivers/thunderbolt/eeprom.c449
-rw-r--r--drivers/thunderbolt/nhi.c675
-rw-r--r--drivers/thunderbolt/nhi.h114
-rw-r--r--drivers/thunderbolt/nhi_regs.h101
-rw-r--r--drivers/thunderbolt/path.c215
-rw-r--r--drivers/thunderbolt/switch.c507
-rw-r--r--drivers/thunderbolt/tb.c436
-rw-r--r--drivers/thunderbolt/tb.h271
-rw-r--r--drivers/thunderbolt/tb_regs.h213
-rw-r--r--drivers/thunderbolt/tunnel_pci.c232
-rw-r--r--drivers/thunderbolt/tunnel_pci.h30
-rw-r--r--drivers/tty/cyclades.c2
-rw-r--r--drivers/tty/ipwireless/tty.c5
-rw-r--r--drivers/tty/n_gsm.c22
-rw-r--r--drivers/tty/pty.c21
-rw-r--r--drivers/tty/serial/21285.c5
-rw-r--r--drivers/tty/serial/8250/8250.h2
-rw-r--r--drivers/tty/serial/8250/8250_core.c230
-rw-r--r--drivers/tty/serial/8250/8250_dw.c190
-rw-r--r--drivers/tty/serial/8250/8250_fsl.c3
-rw-r--r--drivers/tty/serial/8250/8250_pci.c6
-rw-r--r--drivers/tty/serial/Kconfig4
-rw-r--r--drivers/tty/serial/altera_jtaguart.c19
-rw-r--r--drivers/tty/serial/altera_uart.c13
-rw-r--r--drivers/tty/serial/amba-pl010.c48
-rw-r--r--drivers/tty/serial/amba-pl011.c30
-rw-r--r--drivers/tty/serial/apbuart.c6
-rw-r--r--drivers/tty/serial/ar933x_uart.c5
-rw-r--r--drivers/tty/serial/arc_uart.c339
-rw-r--r--drivers/tty/serial/atmel_serial.c8
-rw-r--r--drivers/tty/serial/bfin_sport_uart.c17
-rw-r--r--drivers/tty/serial/bfin_uart.c22
-rw-r--r--drivers/tty/serial/clps711x.c1
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart_core.c9
-rw-r--r--drivers/tty/serial/crisv10.c15
-rw-r--r--drivers/tty/serial/dz.c6
-rw-r--r--drivers/tty/serial/efm32-uart.c14
-rw-r--r--drivers/tty/serial/fsl_lpuart.c689
-rw-r--r--drivers/tty/serial/icom.c6
-rw-r--r--drivers/tty/serial/imx.c3
-rw-r--r--drivers/tty/serial/ioc3_serial.c1
-rw-r--r--drivers/tty/serial/ioc4_serial.c1
-rw-r--r--drivers/tty/serial/ip22zilog.c2
-rw-r--r--drivers/tty/serial/jsm/jsm_tty.c6
-rw-r--r--drivers/tty/serial/kgdb_nmi.c36
-rw-r--r--drivers/tty/serial/lantiq.c8
-rw-r--r--drivers/tty/serial/lpc32xx_hs.c7
-rw-r--r--drivers/tty/serial/m32r_sio.c8
-rw-r--r--drivers/tty/serial/max310x.c1
-rw-r--r--drivers/tty/serial/mcf.c11
-rw-r--r--drivers/tty/serial/men_z135_uart.c6
-rw-r--r--drivers/tty/serial/mpsc.c5
-rw-r--r--drivers/tty/serial/mrst_max3110.c5
-rw-r--r--drivers/tty/serial/msm_serial.c32
-rw-r--r--drivers/tty/serial/msm_serial.h4
-rw-r--r--drivers/tty/serial/mux.c11
-rw-r--r--drivers/tty/serial/mxs-auart.c6
-rw-r--r--drivers/tty/serial/nwpserial.c6
-rw-r--r--drivers/tty/serial/pch_uart.c9
-rw-r--r--drivers/tty/serial/pmac_zilog.c3
-rw-r--r--drivers/tty/serial/pxa.c2
-rw-r--r--drivers/tty/serial/samsung.c48
-rw-r--r--drivers/tty/serial/sc16is7xx.c10
-rw-r--r--drivers/tty/serial/sccnxp.c6
-rw-r--r--drivers/tty/serial/serial-tegra.c4
-rw-r--r--drivers/tty/serial/serial_core.c59
-rw-r--r--drivers/tty/serial/serial_txx9.c7
-rw-r--r--drivers/tty/serial/sh-sci.c94
-rw-r--r--drivers/tty/serial/sirfsoc_uart.c3
-rw-r--r--drivers/tty/serial/sirfsoc_uart.h2
-rw-r--r--drivers/tty/serial/sn_console.c10
-rw-r--r--drivers/tty/serial/st-asc.c20
-rw-r--r--drivers/tty/serial/sunhv.c6
-rw-r--r--drivers/tty/serial/sunsab.c19
-rw-r--r--drivers/tty/serial/sunzilog.c2
-rw-r--r--drivers/tty/serial/tilegx.c10
-rw-r--r--drivers/tty/serial/timbuart.c6
-rw-r--r--drivers/tty/serial/uartlite.c6
-rw-r--r--drivers/tty/serial/ucc_uart.c11
-rw-r--r--drivers/tty/serial/xilinx_uartps.c6
-rw-r--r--drivers/tty/synclink.c10
-rw-r--r--drivers/tty/synclink_gt.c10
-rw-r--r--drivers/tty/synclinkmp.c11
-rw-r--r--drivers/tty/sysrq.c2
-rw-r--r--drivers/tty/tty_io.c39
-rw-r--r--drivers/tty/tty_port.c43
-rw-r--r--drivers/uio/uio_pruss.c37
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c3
-rw-r--r--drivers/usb/chipidea/debug.c4
-rw-r--r--drivers/usb/chipidea/udc.c11
-rw-r--r--drivers/usb/class/usbtmc.c2
-rw-r--r--drivers/usb/core/config.c11
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/driver.c7
-rw-r--r--drivers/usb/core/hcd-pci.c2
-rw-r--r--drivers/usb/core/hcd.c4
-rw-r--r--drivers/usb/core/hub.c113
-rw-r--r--drivers/usb/core/hub.h2
-rw-r--r--drivers/usb/core/port.c21
-rw-r--r--drivers/usb/core/quirks.c7
-rw-r--r--drivers/usb/core/urb.c1
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/dwc2/gadget.c12
-rw-r--r--drivers/usb/dwc3/Kconfig8
-rw-r--r--drivers/usb/dwc3/core.c51
-rw-r--r--drivers/usb/dwc3/core.h13
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c189
-rw-r--r--drivers/usb/dwc3/gadget.c15
-rw-r--r--drivers/usb/dwc3/host.c14
-rw-r--r--drivers/usb/gadget/Kconfig824
-rw-r--r--drivers/usb/gadget/Makefile101
-rw-r--r--drivers/usb/gadget/composite.c1
-rw-r--r--drivers/usb/gadget/configfs.c41
-rw-r--r--drivers/usb/gadget/configfs.h1
-rw-r--r--drivers/usb/gadget/function/Makefile34
-rw-r--r--drivers/usb/gadget/function/f_acm.c (renamed from drivers/usb/gadget/f_acm.c)0
-rw-r--r--drivers/usb/gadget/function/f_ecm.c (renamed from drivers/usb/gadget/f_ecm.c)0
-rw-r--r--drivers/usb/gadget/function/f_eem.c (renamed from drivers/usb/gadget/f_eem.c)22
-rw-r--r--drivers/usb/gadget/function/f_fs.c (renamed from drivers/usb/gadget/f_fs.c)364
-rw-r--r--drivers/usb/gadget/function/f_hid.c (renamed from drivers/usb/gadget/f_hid.c)0
-rw-r--r--drivers/usb/gadget/function/f_loopback.c (renamed from drivers/usb/gadget/f_loopback.c)0
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c (renamed from drivers/usb/gadget/f_mass_storage.c)0
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.h (renamed from drivers/usb/gadget/f_mass_storage.h)0
-rw-r--r--drivers/usb/gadget/function/f_midi.c (renamed from drivers/usb/gadget/f_midi.c)0
-rw-r--r--drivers/usb/gadget/function/f_ncm.c (renamed from drivers/usb/gadget/f_ncm.c)480
-rw-r--r--drivers/usb/gadget/function/f_obex.c (renamed from drivers/usb/gadget/f_obex.c)0
-rw-r--r--drivers/usb/gadget/function/f_phonet.c (renamed from drivers/usb/gadget/f_phonet.c)3
-rw-r--r--drivers/usb/gadget/function/f_rndis.c (renamed from drivers/usb/gadget/f_rndis.c)10
-rw-r--r--drivers/usb/gadget/function/f_serial.c (renamed from drivers/usb/gadget/f_serial.c)0
-rw-r--r--drivers/usb/gadget/function/f_sourcesink.c (renamed from drivers/usb/gadget/f_sourcesink.c)0
-rw-r--r--drivers/usb/gadget/function/f_subset.c (renamed from drivers/usb/gadget/f_subset.c)0
-rw-r--r--drivers/usb/gadget/function/f_uac1.c (renamed from drivers/usb/gadget/f_uac1.c)0
-rw-r--r--drivers/usb/gadget/function/f_uac2.c (renamed from drivers/usb/gadget/f_uac2.c)24
-rw-r--r--drivers/usb/gadget/function/f_uvc.c (renamed from drivers/usb/gadget/f_uvc.c)0
-rw-r--r--drivers/usb/gadget/function/f_uvc.h (renamed from drivers/usb/gadget/f_uvc.h)0
-rw-r--r--drivers/usb/gadget/function/g_zero.h (renamed from drivers/usb/gadget/g_zero.h)0
-rw-r--r--drivers/usb/gadget/function/ndis.h (renamed from drivers/usb/gadget/ndis.h)0
-rw-r--r--drivers/usb/gadget/function/rndis.c (renamed from drivers/usb/gadget/rndis.c)0
-rw-r--r--drivers/usb/gadget/function/rndis.h (renamed from drivers/usb/gadget/rndis.h)0
-rw-r--r--drivers/usb/gadget/function/storage_common.c (renamed from drivers/usb/gadget/storage_common.c)0
-rw-r--r--drivers/usb/gadget/function/storage_common.h (renamed from drivers/usb/gadget/storage_common.h)0
-rw-r--r--drivers/usb/gadget/function/u_ecm.h (renamed from drivers/usb/gadget/u_ecm.h)0
-rw-r--r--drivers/usb/gadget/function/u_eem.h (renamed from drivers/usb/gadget/u_eem.h)0
-rw-r--r--drivers/usb/gadget/function/u_ether.c (renamed from drivers/usb/gadget/u_ether.c)22
-rw-r--r--drivers/usb/gadget/function/u_ether.h (renamed from drivers/usb/gadget/u_ether.h)2
-rw-r--r--drivers/usb/gadget/function/u_ether_configfs.h (renamed from drivers/usb/gadget/u_ether_configfs.h)0
-rw-r--r--drivers/usb/gadget/function/u_fs.h (renamed from drivers/usb/gadget/u_fs.h)7
-rw-r--r--drivers/usb/gadget/function/u_gether.h (renamed from drivers/usb/gadget/u_gether.h)0
-rw-r--r--drivers/usb/gadget/function/u_ncm.h (renamed from drivers/usb/gadget/u_ncm.h)0
-rw-r--r--drivers/usb/gadget/function/u_phonet.h (renamed from drivers/usb/gadget/u_phonet.h)0
-rw-r--r--drivers/usb/gadget/function/u_rndis.h (renamed from drivers/usb/gadget/u_rndis.h)0
-rw-r--r--drivers/usb/gadget/function/u_serial.c (renamed from drivers/usb/gadget/u_serial.c)0
-rw-r--r--drivers/usb/gadget/function/u_serial.h (renamed from drivers/usb/gadget/u_serial.h)0
-rw-r--r--drivers/usb/gadget/function/u_uac1.c (renamed from drivers/usb/gadget/u_uac1.c)0
-rw-r--r--drivers/usb/gadget/function/u_uac1.h (renamed from drivers/usb/gadget/u_uac1.h)0
-rw-r--r--drivers/usb/gadget/function/uvc.h (renamed from drivers/usb/gadget/uvc.h)0
-rw-r--r--drivers/usb/gadget/function/uvc_queue.c (renamed from drivers/usb/gadget/uvc_queue.c)0
-rw-r--r--drivers/usb/gadget/function/uvc_queue.h (renamed from drivers/usb/gadget/uvc_queue.h)0
-rw-r--r--drivers/usb/gadget/function/uvc_v4l2.c (renamed from drivers/usb/gadget/uvc_v4l2.c)0
-rw-r--r--drivers/usb/gadget/function/uvc_video.c (renamed from drivers/usb/gadget/uvc_video.c)0
-rw-r--r--drivers/usb/gadget/legacy/Kconfig475
-rw-r--r--drivers/usb/gadget/legacy/Makefile44
-rw-r--r--drivers/usb/gadget/legacy/acm_ms.c (renamed from drivers/usb/gadget/acm_ms.c)14
-rw-r--r--drivers/usb/gadget/legacy/audio.c (renamed from drivers/usb/gadget/audio.c)12
-rw-r--r--drivers/usb/gadget/legacy/cdc2.c (renamed from drivers/usb/gadget/cdc2.c)14
-rw-r--r--drivers/usb/gadget/legacy/dbgp.c (renamed from drivers/usb/gadget/dbgp.c)0
-rw-r--r--drivers/usb/gadget/legacy/ether.c (renamed from drivers/usb/gadget/ether.c)14
-rw-r--r--drivers/usb/gadget/legacy/g_ffs.c (renamed from drivers/usb/gadget/g_ffs.c)2
-rw-r--r--drivers/usb/gadget/legacy/gmidi.c (renamed from drivers/usb/gadget/gmidi.c)13
-rw-r--r--drivers/usb/gadget/legacy/hid.c (renamed from drivers/usb/gadget/hid.c)0
-rw-r--r--drivers/usb/gadget/legacy/inode.c (renamed from drivers/usb/gadget/inode.c)7
-rw-r--r--drivers/usb/gadget/legacy/mass_storage.c (renamed from drivers/usb/gadget/mass_storage.c)0
-rw-r--r--drivers/usb/gadget/legacy/multi.c (renamed from drivers/usb/gadget/multi.c)13
-rw-r--r--drivers/usb/gadget/legacy/ncm.c (renamed from drivers/usb/gadget/ncm.c)14
-rw-r--r--drivers/usb/gadget/legacy/nokia.c (renamed from drivers/usb/gadget/nokia.c)12
-rw-r--r--drivers/usb/gadget/legacy/printer.c (renamed from drivers/usb/gadget/printer.c)0
-rw-r--r--drivers/usb/gadget/legacy/serial.c (renamed from drivers/usb/gadget/serial.c)0
-rw-r--r--drivers/usb/gadget/legacy/tcm_usb_gadget.c (renamed from drivers/usb/gadget/tcm_usb_gadget.c)0
-rw-r--r--drivers/usb/gadget/legacy/tcm_usb_gadget.h (renamed from drivers/usb/gadget/tcm_usb_gadget.h)0
-rw-r--r--drivers/usb/gadget/legacy/webcam.c (renamed from drivers/usb/gadget/webcam.c)15
-rw-r--r--drivers/usb/gadget/legacy/zero.c (renamed from drivers/usb/gadget/zero.c)14
-rw-r--r--drivers/usb/gadget/net2280.c2905
-rw-r--r--drivers/usb/gadget/net2280.h308
-rw-r--r--drivers/usb/gadget/u_os_desc.h59
-rw-r--r--drivers/usb/gadget/udc/Kconfig385
-rw-r--r--drivers/usb/gadget/udc/Makefile31
-rw-r--r--drivers/usb/gadget/udc/amd5536udc.c (renamed from drivers/usb/gadget/amd5536udc.c)0
-rw-r--r--drivers/usb/gadget/udc/amd5536udc.h (renamed from drivers/usb/gadget/amd5536udc.h)0
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c (renamed from drivers/usb/gadget/at91_udc.c)0
-rw-r--r--drivers/usb/gadget/udc/at91_udc.h (renamed from drivers/usb/gadget/at91_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.c (renamed from drivers/usb/gadget/atmel_usba_udc.c)2
-rw-r--r--drivers/usb/gadget/udc/atmel_usba_udc.h (renamed from drivers/usb/gadget/atmel_usba_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/bcm63xx_udc.c (renamed from drivers/usb/gadget/bcm63xx_udc.c)0
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c (renamed from drivers/usb/gadget/dummy_hcd.c)0
-rw-r--r--drivers/usb/gadget/udc/fotg210-udc.c (renamed from drivers/usb/gadget/fotg210-udc.c)0
-rw-r--r--drivers/usb/gadget/udc/fotg210.h (renamed from drivers/usb/gadget/fotg210.h)0
-rw-r--r--drivers/usb/gadget/udc/fsl_mxc_udc.c (renamed from drivers/usb/gadget/fsl_mxc_udc.c)2
-rw-r--r--drivers/usb/gadget/udc/fsl_qe_udc.c (renamed from drivers/usb/gadget/fsl_qe_udc.c)19
-rw-r--r--drivers/usb/gadget/udc/fsl_qe_udc.h (renamed from drivers/usb/gadget/fsl_qe_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/fsl_udc_core.c (renamed from drivers/usb/gadget/fsl_udc_core.c)19
-rw-r--r--drivers/usb/gadget/udc/fsl_usb2_udc.h (renamed from drivers/usb/gadget/fsl_usb2_udc.h)3
-rw-r--r--drivers/usb/gadget/udc/fusb300_udc.c (renamed from drivers/usb/gadget/fusb300_udc.c)4
-rw-r--r--drivers/usb/gadget/udc/fusb300_udc.h (renamed from drivers/usb/gadget/fusb300_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/gadget_chips.h (renamed from drivers/usb/gadget/gadget_chips.h)0
-rw-r--r--drivers/usb/gadget/udc/goku_udc.c (renamed from drivers/usb/gadget/goku_udc.c)0
-rw-r--r--drivers/usb/gadget/udc/goku_udc.h (renamed from drivers/usb/gadget/goku_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/gr_udc.c (renamed from drivers/usb/gadget/gr_udc.c)7
-rw-r--r--drivers/usb/gadget/udc/gr_udc.h (renamed from drivers/usb/gadget/gr_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/lpc32xx_udc.c (renamed from drivers/usb/gadget/lpc32xx_udc.c)7
-rw-r--r--drivers/usb/gadget/udc/m66592-udc.c (renamed from drivers/usb/gadget/m66592-udc.c)4
-rw-r--r--drivers/usb/gadget/udc/m66592-udc.h (renamed from drivers/usb/gadget/m66592-udc.h)0
-rw-r--r--drivers/usb/gadget/udc/mv_u3d.h (renamed from drivers/usb/gadget/mv_u3d.h)0
-rw-r--r--drivers/usb/gadget/udc/mv_u3d_core.c (renamed from drivers/usb/gadget/mv_u3d_core.c)0
-rw-r--r--drivers/usb/gadget/udc/mv_udc.h (renamed from drivers/usb/gadget/mv_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/mv_udc_core.c (renamed from drivers/usb/gadget/mv_udc_core.c)4
-rw-r--r--drivers/usb/gadget/udc/net2272.c (renamed from drivers/usb/gadget/net2272.c)2
-rw-r--r--drivers/usb/gadget/udc/net2272.h (renamed from drivers/usb/gadget/net2272.h)0
-rw-r--r--drivers/usb/gadget/udc/net2280.c3827
-rw-r--r--drivers/usb/gadget/udc/net2280.h403
-rw-r--r--drivers/usb/gadget/udc/omap_udc.c (renamed from drivers/usb/gadget/omap_udc.c)5
-rw-r--r--drivers/usb/gadget/udc/omap_udc.h (renamed from drivers/usb/gadget/omap_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/pch_udc.c (renamed from drivers/usb/gadget/pch_udc.c)0
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.c (renamed from drivers/usb/gadget/pxa25x_udc.c)75
-rw-r--r--drivers/usb/gadget/udc/pxa25x_udc.h (renamed from drivers/usb/gadget/pxa25x_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/pxa27x_udc.c (renamed from drivers/usb/gadget/pxa27x_udc.c)6
-rw-r--r--drivers/usb/gadget/udc/pxa27x_udc.h (renamed from drivers/usb/gadget/pxa27x_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.c (renamed from drivers/usb/gadget/r8a66597-udc.c)92
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.h (renamed from drivers/usb/gadget/r8a66597-udc.h)0
-rw-r--r--drivers/usb/gadget/udc/s3c-hsudc.c (renamed from drivers/usb/gadget/s3c-hsudc.c)0
-rw-r--r--drivers/usb/gadget/udc/s3c2410_udc.c (renamed from drivers/usb/gadget/s3c2410_udc.c)8
-rw-r--r--drivers/usb/gadget/udc/s3c2410_udc.h (renamed from drivers/usb/gadget/s3c2410_udc.h)0
-rw-r--r--drivers/usb/gadget/udc/udc-core.c (renamed from drivers/usb/gadget/udc-core.c)0
-rw-r--r--drivers/usb/host/Kconfig10
-rw-r--r--drivers/usb/host/Makefile3
-rw-r--r--drivers/usb/host/ehci-exynos.c2
-rw-r--r--drivers/usb/host/ehci-mem.c2
-rw-r--r--drivers/usb/host/ehci-msm.c2
-rw-r--r--drivers/usb/host/ehci-pci.c25
-rw-r--r--drivers/usb/host/ehci-spear.c2
-rw-r--r--drivers/usb/host/ehci-tegra.c67
-rw-r--r--drivers/usb/host/fhci-dbg.c8
-rw-r--r--drivers/usb/host/fotg210-hcd.c48
-rw-r--r--drivers/usb/host/max3421-hcd.c48
-rw-r--r--drivers/usb/host/ohci-dbg.c9
-rw-r--r--drivers/usb/host/ohci-exynos.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c381
-rw-r--r--drivers/usb/host/ohci-hub.c11
-rw-r--r--drivers/usb/host/ohci-mem.c1
-rw-r--r--drivers/usb/host/ohci-q.c262
-rw-r--r--drivers/usb/host/ohci-spear.c2
-rw-r--r--drivers/usb/host/ohci.h23
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c48
-rw-r--r--drivers/usb/host/uhci-grlib.c31
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-platform.c22
-rw-r--r--drivers/usb/host/xhci-hub.c5
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci-plat.c52
-rw-r--r--drivers/usb/host/xhci-rcar.c148
-rw-r--r--drivers/usb/host/xhci-rcar.h27
-rw-r--r--drivers/usb/host/xhci-ring.c13
-rw-r--r--drivers/usb/host/xhci.c170
-rw-r--r--drivers/usb/host/xhci.h2
-rw-r--r--drivers/usb/misc/Kconfig7
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/lvstest.c460
-rw-r--r--drivers/usb/misc/usb3503.c37
-rw-r--r--drivers/usb/musb/blackfin.c20
-rw-r--r--drivers/usb/musb/davinci.c20
-rw-r--r--drivers/usb/musb/jz4740.c3
-rw-r--r--drivers/usb/musb/musb_am335x.c23
-rw-r--r--drivers/usb/musb/musb_core.c43
-rw-r--r--drivers/usb/musb/musb_core.h12
-rw-r--r--drivers/usb/musb/musb_cppi41.c72
-rw-r--r--drivers/usb/musb/musb_dma.h1
-rw-r--r--drivers/usb/musb/musb_dsps.c113
-rw-r--r--drivers/usb/musb/musb_host.c19
-rw-r--r--drivers/usb/musb/musb_regs.h7
-rw-r--r--drivers/usb/musb/tusb6010.c16
-rw-r--r--drivers/usb/musb/ux500.c29
-rw-r--r--drivers/usb/phy/phy-am335x.c12
-rw-r--r--drivers/usb/phy/phy-gpio-vbus-usb.c45
-rw-r--r--drivers/usb/phy/phy-msm-usb.c16
-rw-r--r--drivers/usb/phy/phy-tegra-usb.c11
-rw-r--r--drivers/usb/phy/phy.c2
-rw-r--r--drivers/usb/renesas_usbhs/Makefile2
-rw-r--r--drivers/usb/renesas_usbhs/common.c66
-rw-r--r--drivers/usb/renesas_usbhs/common.h2
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c8
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c2
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c11
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h1
-rw-r--r--drivers/usb/renesas_usbhs/rcar2.c77
-rw-r--r--drivers/usb/renesas_usbhs/rcar2.h4
-rw-r--r--drivers/usb/serial/cp210x.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c94
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h22
-rw-r--r--drivers/usb/serial/kl5kusb105.c30
-rw-r--r--drivers/usb/serial/mos7840.c5
-rw-r--r--drivers/usb/serial/option.c28
-rw-r--r--drivers/usb/storage/Kconfig6
-rw-r--r--drivers/usb/storage/ene_ub6250.c4
-rw-r--r--drivers/usb/storage/scsiglue.c4
-rw-r--r--drivers/usb/storage/sddr09.c4
-rw-r--r--drivers/usb/storage/uas-detect.h40
-rw-r--r--drivers/usb/storage/uas.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/usb/storage/usb.c10
-rw-r--r--drivers/uwb/whci.c2
-rw-r--r--drivers/vfio/Makefile1
-rw-r--r--drivers/vfio/pci/vfio_pci.c18
-rw-r--r--drivers/vfio/vfio_iommu_spapr_tce.c17
-rw-r--r--drivers/vfio/vfio_spapr_eeh.c87
-rw-r--r--drivers/video/backlight/Kconfig9
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/aat2870_bl.c6
-rw-r--r--drivers/video/backlight/ams369fg06.c6
-rw-r--r--drivers/video/backlight/backlight.c2
-rw-r--r--drivers/video/backlight/bd6107.c6
-rw-r--r--drivers/video/backlight/gpio_backlight.c6
-rw-r--r--drivers/video/backlight/ipaq_micro_bl.c83
-rw-r--r--drivers/video/backlight/jornada720_lcd.c37
-rw-r--r--drivers/video/backlight/ld9040.c6
-rw-r--r--drivers/video/backlight/lp855x_bl.c6
-rw-r--r--drivers/video/backlight/lp8788_bl.c6
-rw-r--r--drivers/video/backlight/lv5207lp.c6
-rw-r--r--drivers/video/backlight/pandora_bl.c6
-rw-r--r--drivers/video/backlight/pwm_bl.c13
-rw-r--r--drivers/video/backlight/s6e63m0.c6
-rw-r--r--drivers/video/backlight/tps65217_bl.c6
-rw-r--r--drivers/video/fbdev/Kconfig10
-rw-r--r--drivers/video/fbdev/Makefile1
-rw-r--r--drivers/video/fbdev/amba-clcd-versatile.c182
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c2
-rw-r--r--drivers/video/fbdev/aty/aty128fb.c6
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c6
-rw-r--r--drivers/video/fbdev/aty/radeon_backlight.c6
-rw-r--r--drivers/video/fbdev/au1100fb.c39
-rw-r--r--drivers/video/fbdev/au1100fb.h1
-rw-r--r--drivers/video/fbdev/au1200fb.c81
-rw-r--r--drivers/video/fbdev/bfin_adv7393fb.c2
-rw-r--r--drivers/video/fbdev/efifb.c39
-rw-r--r--drivers/video/fbdev/exynos/s6e8ax0.c6
-rw-r--r--drivers/video/fbdev/nvidia/nv_backlight.c6
-rw-r--r--drivers/video/fbdev/omap2/dss/omapdss-boot-init.c8
-rw-r--r--drivers/video/fbdev/riva/fbdev.c6
-rw-r--r--drivers/video/fbdev/s3c-fb.c65
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.c2
-rw-r--r--drivers/vme/bridges/vme_ca91cx42.h1
-rw-r--r--drivers/w1/masters/ds1wm.c2
-rw-r--r--drivers/w1/masters/ds2482.c2
-rw-r--r--drivers/w1/masters/ds2490.c50
-rw-r--r--drivers/w1/masters/mxc_w1.c64
-rw-r--r--drivers/w1/slaves/Kconfig8
-rw-r--r--drivers/w1/slaves/Makefile1
-rw-r--r--drivers/w1/slaves/w1_ds2406.c168
-rw-r--r--drivers/w1/slaves/w1_ds2760.c3
-rw-r--r--drivers/w1/w1.c10
-rw-r--r--drivers/w1/w1_family.c2
-rw-r--r--drivers/w1/w1_family.h1
-rw-r--r--drivers/w1/w1_int.c19
-rw-r--r--drivers/w1/w1_log.h4
-rw-r--r--drivers/w1/w1_netlink.c3
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/dw_wdt.c3
-rw-r--r--drivers/watchdog/imx2_wdt.c7
-rw-r--r--drivers/watchdog/lantiq_wdt.c5
-rw-r--r--drivers/watchdog/octeon-wdt-main.c62
-rw-r--r--drivers/watchdog/shwdt.c5
-rw-r--r--drivers/watchdog/sunxi_wdt.c29
-rw-r--r--drivers/xen/Kconfig4
-rw-r--r--drivers/xen/Makefile3
-rw-r--r--drivers/xen/balloon.c12
-rw-r--r--drivers/xen/efi.c368
-rw-r--r--drivers/xen/events/events_base.c2
-rw-r--r--drivers/xen/events/events_fifo.c55
-rw-r--r--drivers/xen/grant-table.c314
-rw-r--r--drivers/xen/manage.c5
-rw-r--r--drivers/xen/xen-pciback/xenbus.c1
-rw-r--r--drivers/zorro/names.c4
4415 files changed, 223111 insertions, 327956 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 0e87a34b6472..622fa266b29e 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -176,4 +176,8 @@ source "drivers/powercap/Kconfig"
source "drivers/mcb/Kconfig"
+source "drivers/ras/Kconfig"
+
+source "drivers/thunderbolt/Kconfig"
+
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index f98b50d8251d..ebee55537a05 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ nfc/
+obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
obj-$(CONFIG_NUBUS) += nubus/
obj-y += macintosh/
obj-$(CONFIG_IDE) += ide/
@@ -158,3 +159,5 @@ obj-$(CONFIG_NTB) += ntb/
obj-$(CONFIG_FMC) += fmc/
obj-$(CONFIG_POWERCAP) += powercap/
obj-$(CONFIG_MCB) += mcb/
+obj-$(CONFIG_RAS) += ras/
+obj-$(CONFIG_THUNDERBOLT) += thunderbolt/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index a34a22841002..d0f3265fb85d 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -42,6 +42,12 @@ menuconfig ACPI
if ACPI
+config ACPI_LEGACY_TABLES_LOOKUP
+ bool
+
+config ARCH_MIGHT_HAVE_ACPI_PDC
+ bool
+
config ACPI_SLEEP
bool
depends on SUSPEND || HIBERNATION
@@ -370,6 +376,7 @@ config ACPI_EXTLOG
tristate "Extended Error Log support"
depends on X86_MCE && X86_LOCAL_APIC
select UEFI_CPER
+ select RAS
default n
help
Certain usages such as Predictive Failure Analysis (PFA) require
@@ -384,6 +391,7 @@ config ACPI_EXTLOG
Enhanced MCA Logging allows firmware to provide additional error
information to system software, synchronous with MCE or CMCI. This
- driver adds support for that functionality.
+ driver adds support for that functionality with corresponding
+ tracepoint which carries that information to userspace.
endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index ea55e0179f81..505d4d79fe3e 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,6 +36,7 @@ acpi-y += scan.o
acpi-y += resource.o
acpi-y += acpi_processor.o
acpi-y += processor_core.o
+acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index c67f6f5ad611..36b0e61f9c09 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -30,6 +30,10 @@
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/delay.h>
+#ifdef CONFIG_ACPI_PROCFS_POWER
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#endif
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/acpi.h>
@@ -52,6 +56,7 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI AC Adapter Driver");
MODULE_LICENSE("GPL");
+
static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device);
static void acpi_ac_notify(struct acpi_device *device, u32 event);
@@ -67,6 +72,13 @@ static int acpi_ac_resume(struct device *dev);
#endif
static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
+#ifdef CONFIG_ACPI_PROCFS_POWER
+extern struct proc_dir_entry *acpi_lock_ac_dir(void);
+extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
+static int acpi_ac_open_fs(struct inode *inode, struct file *file);
+#endif
+
+
static int ac_sleep_before_get_state_ms;
static struct acpi_driver acpi_ac_driver = {
@@ -91,6 +103,16 @@ struct acpi_ac {
#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
+#ifdef CONFIG_ACPI_PROCFS_POWER
+static const struct file_operations acpi_ac_fops = {
+ .owner = THIS_MODULE,
+ .open = acpi_ac_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
/* --------------------------------------------------------------------------
AC Adapter Management
-------------------------------------------------------------------------- */
@@ -143,6 +165,83 @@ static enum power_supply_property ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
};
+#ifdef CONFIG_ACPI_PROCFS_POWER
+/* --------------------------------------------------------------------------
+ FS Interface (/proc)
+ -------------------------------------------------------------------------- */
+
+static struct proc_dir_entry *acpi_ac_dir;
+
+static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
+{
+ struct acpi_ac *ac = seq->private;
+
+
+ if (!ac)
+ return 0;
+
+ if (acpi_ac_get_state(ac)) {
+ seq_puts(seq, "ERROR: Unable to read AC Adapter state\n");
+ return 0;
+ }
+
+ seq_puts(seq, "state: ");
+ switch (ac->state) {
+ case ACPI_AC_STATUS_OFFLINE:
+ seq_puts(seq, "off-line\n");
+ break;
+ case ACPI_AC_STATUS_ONLINE:
+ seq_puts(seq, "on-line\n");
+ break;
+ default:
+ seq_puts(seq, "unknown\n");
+ break;
+ }
+
+ return 0;
+}
+
+static int acpi_ac_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, acpi_ac_seq_show, PDE_DATA(inode));
+}
+
+static int acpi_ac_add_fs(struct acpi_ac *ac)
+{
+ struct proc_dir_entry *entry = NULL;
+
+ printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded,"
+ " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
+ if (!acpi_device_dir(ac->device)) {
+ acpi_device_dir(ac->device) =
+ proc_mkdir(acpi_device_bid(ac->device), acpi_ac_dir);
+ if (!acpi_device_dir(ac->device))
+ return -ENODEV;
+ }
+
+ /* 'state' [R] */
+ entry = proc_create_data(ACPI_AC_FILE_STATE,
+ S_IRUGO, acpi_device_dir(ac->device),
+ &acpi_ac_fops, ac);
+ if (!entry)
+ return -ENODEV;
+ return 0;
+}
+
+static int acpi_ac_remove_fs(struct acpi_ac *ac)
+{
+
+ if (acpi_device_dir(ac->device)) {
+ remove_proc_entry(ACPI_AC_FILE_STATE,
+ acpi_device_dir(ac->device));
+ remove_proc_entry(acpi_device_bid(ac->device), acpi_ac_dir);
+ acpi_device_dir(ac->device) = NULL;
+ }
+
+ return 0;
+}
+#endif
+
/* --------------------------------------------------------------------------
Driver Model
-------------------------------------------------------------------------- */
@@ -243,6 +342,11 @@ static int acpi_ac_add(struct acpi_device *device)
goto end;
ac->charger.name = acpi_device_bid(device);
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ result = acpi_ac_add_fs(ac);
+ if (result)
+ goto end;
+#endif
ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger.properties = ac_props;
ac->charger.num_properties = ARRAY_SIZE(ac_props);
@@ -258,8 +362,12 @@ static int acpi_ac_add(struct acpi_device *device)
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(&ac->battery_nb);
end:
- if (result)
+ if (result) {
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ acpi_ac_remove_fs(ac);
+#endif
kfree(ac);
+ }
dmi_check_system(ac_dmi_table);
return result;
@@ -303,6 +411,10 @@ static int acpi_ac_remove(struct acpi_device *device)
power_supply_unregister(&ac->charger);
unregister_acpi_notifier(&ac->battery_nb);
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ acpi_ac_remove_fs(ac);
+#endif
+
kfree(ac);
return 0;
@@ -315,9 +427,20 @@ static int __init acpi_ac_init(void)
if (acpi_disabled)
return -ENODEV;
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ acpi_ac_dir = acpi_lock_ac_dir();
+ if (!acpi_ac_dir)
+ return -ENODEV;
+#endif
+
+
result = acpi_bus_register_driver(&acpi_ac_driver);
- if (result < 0)
+ if (result < 0) {
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ acpi_unlock_ac_dir(acpi_ac_dir);
+#endif
return -ENODEV;
+ }
return 0;
}
@@ -325,6 +448,9 @@ static int __init acpi_ac_init(void)
static void __exit acpi_ac_exit(void)
{
acpi_bus_unregister_driver(&acpi_ac_driver);
+#ifdef CONFIG_ACPI_PROCFS_POWER
+ acpi_unlock_ac_dir(acpi_ac_dir);
+#endif
}
module_init(acpi_ac_init);
module_exit(acpi_ac_exit);
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 185334114d71..b3842ffc19ba 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -12,10 +12,12 @@
#include <linux/cper.h>
#include <linux/ratelimit.h>
#include <linux/edac.h>
+#include <linux/ras.h>
#include <asm/cpu.h>
#include <asm/mce.h>
#include "apei/apei-internal.h"
+#include <ras/ras_event.h>
#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */
@@ -69,11 +71,11 @@ static u32 l1_percpu_entry;
#define ELOG_ENTRY_ADDR(phyaddr) \
(phyaddr - elog_base + (u8 *)elog_addr)
-static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
+static struct acpi_hest_generic_status *extlog_elog_entry_check(int cpu, int bank)
{
int idx;
u64 data;
- struct acpi_generic_status *estatus;
+ struct acpi_hest_generic_status *estatus;
WARN_ON(cpu < 0);
idx = ELOG_IDX(cpu, bank);
@@ -82,7 +84,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
return NULL;
data &= EXT_ELOG_ENTRY_MASK;
- estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data);
+ estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data);
/* if no valid data in elog entry, just return */
if (estatus->block_status == 0)
@@ -92,7 +94,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
}
static void __print_extlog_rcd(const char *pfx,
- struct acpi_generic_status *estatus, int cpu)
+ struct acpi_hest_generic_status *estatus, int cpu)
{
static atomic_t seqno;
unsigned int curr_seqno;
@@ -111,7 +113,7 @@ static void __print_extlog_rcd(const char *pfx,
}
static int print_extlog_rcd(const char *pfx,
- struct acpi_generic_status *estatus, int cpu)
+ struct acpi_hest_generic_status *estatus, int cpu)
{
/* Not more than 2 messages every 5 seconds */
static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
@@ -137,8 +139,12 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
struct mce *mce = (struct mce *)data;
int bank = mce->bank;
int cpu = mce->extcpu;
- struct acpi_generic_status *estatus;
- int rc;
+ struct acpi_hest_generic_status *estatus, *tmp;
+ struct acpi_hest_generic_data *gdata;
+ const uuid_le *fru_id = &NULL_UUID_LE;
+ char *fru_text = "";
+ uuid_le *sec_type;
+ static u32 err_seq;
estatus = extlog_elog_entry_check(cpu, bank);
if (estatus == NULL)
@@ -148,8 +154,29 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
/* clear record status to enable BIOS to update it again */
estatus->block_status = 0;
- rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu);
+ tmp = (struct acpi_hest_generic_status *)elog_buf;
+
+ if (!ras_userspace_consumers()) {
+ print_extlog_rcd(NULL, tmp, cpu);
+ goto out;
+ }
+
+ /* log event via trace */
+ err_seq++;
+ gdata = (struct acpi_hest_generic_data *)(tmp + 1);
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+ fru_id = (uuid_le *)gdata->fru_id;
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+ fru_text = gdata->fru_text;
+ sec_type = (uuid_le *)gdata->section_type;
+ if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
+ struct cper_sec_mem_err *mem = (void *)(gdata + 1);
+ if (gdata->error_data_length >= sizeof(*mem))
+ trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
+ (u8)gdata->error_severity);
+ }
+out:
return NOTIFY_STOP;
}
@@ -196,19 +223,16 @@ static int __init extlog_init(void)
u64 cap;
int rc;
+ rdmsrl(MSR_IA32_MCG_CAP, cap);
+
+ if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr())
+ return -ENODEV;
+
if (get_edac_report_status() == EDAC_REPORTING_FORCE) {
pr_warn("Not loading eMCA, error reporting force-enabled through EDAC.\n");
return -EPERM;
}
- rc = -ENODEV;
- rdmsrl(MSR_IA32_MCG_CAP, cap);
- if (!(cap & MCG_ELOG_P))
- return rc;
-
- if (!extlog_get_l1addr())
- return rc;
-
rc = -EINVAL;
/* get L1 header to fetch necessary information */
l1_hdr_size = sizeof(struct extlog_l1_head);
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 9cb65b0e7597..ce06149088c5 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -113,6 +113,14 @@ static void lpss_i2c_setup(struct lpss_private_data *pdata)
writel(val, pdata->mmio_base + offset);
}
+static struct lpss_device_desc wpt_dev_desc = {
+ .clk_required = true,
+ .prv_offset = 0x800,
+ .ltr_required = true,
+ .clk_divider = true,
+ .clk_gate = true,
+};
+
static struct lpss_device_desc lpt_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
@@ -226,6 +234,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT3437", },
+ { "INT3438", LPSS_ADDR(wpt_dev_desc) },
+
{ }
};
diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c
index 6703c1fd993a..996fa1959eea 100644
--- a/drivers/acpi/acpi_pnp.c
+++ b/drivers/acpi/acpi_pnp.c
@@ -12,8 +12,11 @@
#include <linux/acpi.h>
#include <linux/module.h>
+#include <linux/ctype.h>
static const struct acpi_device_id acpi_pnp_device_ids[] = {
+ /* soc_button_array */
+ {"PNP0C40"},
/* pata_isapnp */
{"PNP0600"}, /* Generic ESDI/IDE/ATA compatible hard disk controller */
/* floppy */
@@ -318,11 +321,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
{""},
};
-static bool is_hex_digit(char c)
-{
- return (c >= 0 && c <= '9') || (c >= 'A' && c <= 'F');
-}
-
static bool matching_id(char *idstr, char *list_id)
{
int i;
@@ -333,7 +331,7 @@ static bool matching_id(char *idstr, char *list_id)
for (i = 3; i < 7; i++) {
char c = toupper(idstr[i]);
- if (!is_hex_digit(c)
+ if (!isxdigit(c)
|| (list_id[i] != 'X' && c != toupper(list_id[i])))
return false;
}
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
index 1c085742644f..1fdf5e07a1c7 100644
--- a/drivers/acpi/acpi_processor.c
+++ b/drivers/acpi/acpi_processor.c
@@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
pr->apic_id = apic_id;
cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
- if (!cpu0_initialized && !acpi_lapic) {
+ if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
cpu0_initialized = 1;
/* Handle UP system running SMP kernel, with no LAPIC in MADT */
if ((cpu_index == -1) && (num_online_cpus() == 1))
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 8bb43f06e11f..c1a963581dc0 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -2,7 +2,7 @@
# Makefile for ACPICA Core interpreter
#
-ccflags-y := -Os
+ccflags-y := -Os -DBUILDING_ACPICA
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
# use acpi.o to put all files here into acpi.o modparam namespace
@@ -157,6 +157,7 @@ acpi-y += \
uterror.o \
uteval.o \
utglobal.o \
+ uthex.o \
utids.o \
utinit.o \
utlock.o \
@@ -175,5 +176,10 @@ acpi-y += \
utxferror.o \
utxfmutex.o
-acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o
+acpi-$(ACPI_FUTURE_USAGE) += \
+ utcache.o \
+ utfileio.o \
+ utprint.o \
+ uttrack.o \
+ utuuid.o
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
index 8698ffba6f39..3d2c88289da9 100644
--- a/drivers/acpi/acpica/acapps.h
+++ b/drivers/acpi/acpica/acapps.h
@@ -79,10 +79,13 @@
/* Macros for usage messages */
#define ACPI_USAGE_HEADER(usage) \
- printf ("Usage: %s\nOptions:\n", usage);
+ acpi_os_printf ("Usage: %s\nOptions:\n", usage);
+
+#define ACPI_USAGE_TEXT(description) \
+ acpi_os_printf (description);
#define ACPI_OPTION(name, description) \
- printf (" %-18s%s\n", name, description);
+ acpi_os_printf (" %-18s%s\n", name, description);
#define FILE_SUFFIX_DISASSEMBLY "dsl"
#define ACPI_TABLE_FILE_SUFFIX ".dat"
@@ -102,7 +105,7 @@ extern char *acpi_gbl_optarg;
/*
* cmfsize - Common get file size function
*/
-u32 cm_get_file_size(FILE * file);
+u32 cm_get_file_size(ACPI_FILE file);
#ifndef ACPI_DUMP_APP
/*
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index 68a91eb0fa48..1d026ff1683f 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename);
acpi_status
acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table);
-acpi_status
-acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table);
-
/*
* dbhistry - debugger HISTORY command
*/
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 115eedcade1e..ebf02cc10a43 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer);
*
****************************************************************************/
-ACPI_GLOBAL(u8, acpi_gbl_db_output_flags);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT);
#ifdef ACPI_DISASSEMBLER
@@ -362,6 +362,12 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects);
#ifdef ACPI_APPLICATION
ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
+ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL);
+
+/* Print buffer */
+
+ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock); /* For print buffer */
+ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]);
#endif /* ACPI_APPLICATION */
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 91f801a2e689..1f9aba5fb81f 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -730,12 +730,13 @@ union acpi_parse_value {
#define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */
#define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */
#define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */
-#define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */
-#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */
-#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */
-#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */
-#define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */
-#define ACPI_DASM_IGNORE 0x0A /* Not used at this time */
+#define ACPI_DASM_UUID 0x05 /* Buffer is a UUID/GUID */
+#define ACPI_DASM_EISAID 0x06 /* Integer is an EISAID */
+#define ACPI_DASM_MATCHOP 0x07 /* Parent opcode is a Match() operator */
+#define ACPI_DASM_LNOT_PREFIX 0x08 /* Start of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_LNOT_SUFFIX 0x09 /* End of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_HID_STRING 0x0A /* String is a _HID or _CID */
+#define ACPI_DASM_IGNORE 0x0B /* Not used at this time */
/*
* Generic operation (for example: If, While, Store)
@@ -1154,4 +1155,9 @@ struct ah_device_id {
char *description;
};
+struct ah_uuid {
+ char *description;
+ char *string;
+};
+
#endif /* __ACLOCAL_H__ */
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index bd08817cafd8..bd3908d26c4f 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -105,6 +105,11 @@
* count = 0 (optional)
* (Used for _DLM)
*
+ * ACPI_PTYPE2_UUID_PAIR: Each subpackage is preceded by a UUID Buffer. The UUID
+ * defines the format of the package. Zero-length parent package is
+ * allowed.
+ * (Used for _DSD)
+ *
*****************************************************************************/
enum acpi_return_package_types {
@@ -117,7 +122,8 @@ enum acpi_return_package_types {
ACPI_PTYPE2_FIXED = 7,
ACPI_PTYPE2_MIN = 8,
ACPI_PTYPE2_REV_FIXED = 9,
- ACPI_PTYPE2_FIX_VAR = 10
+ ACPI_PTYPE2_FIX_VAR = 10,
+ ACPI_PTYPE2_UUID_PAIR = 11
};
/* Support macros for users of the predefined info table */
@@ -364,6 +370,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
{{"_CBA", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* See PCI firmware spec 3.0 */
+ {{"_CCA", METHOD_0ARGS,
+ METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* ACPI 5.1 */
+
{{"_CDM", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},
@@ -436,6 +445,11 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
{{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER),
METHOD_NO_RETURN_VALUE}},
+ {{"_DSD", METHOD_0ARGS,
+ METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */
+ PACKAGE_INFO(ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1,
+ ACPI_RTYPE_PACKAGE, 1, 0),
+
{{"_DSM",
METHOD_4ARGS(ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER,
ACPI_TYPE_PACKAGE),
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 1e256c5bda20..486d342e74b6 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[];
#ifdef ACPI_ASL_COMPILER
#include <stdio.h>
-extern FILE *acpi_gbl_output_file;
#define ACPI_MSG_REDIRECT_BEGIN \
FILE *output_file = acpi_gbl_output_file; \
@@ -195,6 +194,8 @@ char *acpi_ut_get_event_name(u32 event_id);
char acpi_ut_hex_to_ascii_char(u64 integer, u32 position);
+u8 acpi_ut_ascii_char_to_hex(int hex_char);
+
u8 acpi_ut_valid_object_type(acpi_object_type type);
/*
@@ -211,6 +212,8 @@ void acpi_ut_subsystem_shutdown(void);
acpi_size acpi_ut_strlen(const char *string);
+char *acpi_ut_strchr(const char *string, int ch);
+
char *acpi_ut_strcpy(char *dst_string, const char *src_string);
char *acpi_ut_strncpy(char *dst_string,
@@ -257,7 +260,7 @@ extern const u8 _acpi_ctype[];
#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
#define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
#define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
-#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU))
+#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
#endif /* !ACPI_USE_SYSTEM_CLIBRARY */
@@ -352,6 +355,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);
void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset);
+#ifdef ACPI_APPLICATION
+void
+acpi_ut_dump_buffer_to_file(ACPI_FILE file,
+ u8 *buffer,
+ u32 count, u32 display, u32 base_offset);
+#endif
+
void acpi_ut_report_error(char *module_name, u32 line_number);
void acpi_ut_report_info(char *module_name, u32 line_number);
@@ -394,6 +404,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
u8 method_count, u8 *out_values);
/*
+ * utfileio - file operations
+ */
+#ifdef ACPI_APPLICATION
+acpi_status
+acpi_ut_read_table_from_file(char *filename, struct acpi_table_header **table);
+#endif
+
+/*
* utids - device ID support
*/
acpi_status
@@ -743,4 +761,30 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);
const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
+const char *acpi_ah_match_uuid(u8 *data);
+
+/*
+ * utprint - printf/vprintf output functions
+ */
+const char *acpi_ut_scan_number(const char *string, u64 *number_ptr);
+
+const char *acpi_ut_print_number(char *string, u64 number);
+
+int
+acpi_ut_vsnprintf(char *string,
+ acpi_size size, const char *format, va_list args);
+
+int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...);
+
+#ifdef ACPI_APPLICATION
+int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args);
+
+int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...);
+#endif
+
+/*
+ * utuuid -- UUID support functions
+ */
+void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer);
+
#endif /* _ACUTILS_H */
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index 48f70013b488..e4ba4dec86af 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -698,21 +698,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
}
/*
- * If edge-triggered, clear the GPE status bit now. Note that
- * level-triggered events are cleared after the GPE is serviced.
- */
- if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_EDGE_TRIGGERED) {
- status = acpi_hw_clear_gpe(gpe_event_info);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "Unable to clear GPE %02X",
- gpe_number));
- return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
- }
- }
-
- /*
* Always disable the GPE so that it does not keep firing before
* any asynchronous activity completes (either from the execution
* of a GPE method or an asynchronous GPE handler.)
@@ -729,6 +714,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
}
/*
+ * If edge-triggered, clear the GPE status bit now. Note that
+ * level-triggered events are cleared after the GPE is serviced.
+ */
+ if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+ ACPI_GPE_EDGE_TRIGGERED) {
+ status = acpi_hw_clear_gpe(gpe_event_info);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Unable to clear GPE %02X",
+ gpe_number));
+ (void)acpi_hw_low_set_gpe(gpe_event_info,
+ ACPI_GPE_CONDITIONAL_ENABLE);
+ return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
+ }
+ }
+
+ /*
* Dispatch the GPE to either an installed handler or the control
* method associated with this GPE (_Lxx or _Exx). If a handler
* exists, we invoke it and do not attempt to run the method.
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index cb534faf5369..0cf159cc6e6d 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
- /* Ensure that we have a valid GPE number */
-
+ /*
+ * Ensure that we have a valid GPE number and that there is some way
+ * of handling the GPE (handler or a GPE method). In other words, we
+ * won't allow a valid GPE to be enabled if there is no way to handle it.
+ */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) {
- status = acpi_ev_add_gpe_reference(gpe_event_info);
+ if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
+ ACPI_GPE_DISPATCH_NONE) {
+ status = acpi_ev_add_gpe_reference(gpe_event_info);
+ } else {
+ status = AE_NO_HANDLER;
+ }
}
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
@@ -179,6 +187,53 @@ ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
/*******************************************************************************
*
+ * FUNCTION: acpi_mark_gpe_for_wake
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
+ * gpe_number - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
+ * sets the ACPI_GPE_CAN_WAKE flag.
+ *
+ * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
+ * there won't be any notify handlers installed for device wake notifications
+ * from the given GPE (one example is a button GPE in Linux). For these cases,
+ * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
+ * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
+ * setup implicit wake notification for it (since there's no handler method).
+ *
+ ******************************************************************************/
+acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
+{
+ struct acpi_gpe_event_info *gpe_event_info;
+ acpi_status status = AE_BAD_PARAMETER;
+ acpi_cpu_flags flags;
+
+ ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (gpe_event_info) {
+
+ /* Mark the GPE as a possible wake event */
+
+ gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
+ status = AE_OK;
+ }
+
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_setup_gpe_for_wake
*
* PARAMETERS: wake_device - Device associated with the GPE (via _PRW)
diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c
index 4cfc3d3b5c97..6fbfad47518c 100644
--- a/drivers/acpi/acpica/exdebug.c
+++ b/drivers/acpi/acpica/exdebug.c
@@ -75,6 +75,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
u32 level, u32 index)
{
u32 i;
+ u32 timer;
ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
@@ -86,11 +87,19 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
}
/*
+ * We will emit the current timer value (in microseconds) with each
+ * debug output. Only need the lower 26 bits. This allows for 67
+ * million microseconds or 67 seconds before rollover.
+ */
+ timer = ((u32)acpi_os_get_timer() / 10); /* (100 nanoseconds to microseconds) */
+ timer &= 0x03FFFFFF;
+
+ /*
* Print line header as long as we are not in the middle of an
* object display
*/
if (!((level > 0) && index == 0)) {
- acpi_os_printf("[ACPI Debug] %*s", level, " ");
+ acpi_os_printf("[ACPI Debug %.8u] %*s", timer, level, " ");
}
/* Display the index for package output only */
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index 925202acc3e4..0f23c3f2678e 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -494,7 +494,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
}
}
- acpi_os_printf("\n", next);
+ acpi_os_printf("\n");
break;
case ACPI_EXD_HDLR_LIST:
@@ -528,7 +528,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
}
}
- acpi_os_printf("\n", next);
+ acpi_os_printf("\n");
break;
case ACPI_EXD_RGN_LIST:
@@ -562,7 +562,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
}
}
- acpi_os_printf("\n", next);
+ acpi_os_printf("\n");
break;
case ACPI_EXD_NODE:
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index 12878e1982f7..6907ce0c704c 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
/*******************************************************************************
*
- * FUNCTION: acpi_get_serial_access_bytes
+ * FUNCTION: acpi_ex_get_serial_access_length
*
* PARAMETERS: accessor_type - The type of the protocol indicated by region
* field access attributes
@@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
case AML_FIELD_ATTRIB_BLOCK_CALL:
default:
- length = ACPI_GSBUS_BUFFER_SIZE;
+ length = ACPI_GSBUS_BUFFER_SIZE - 2;
break;
}
@@ -186,12 +186,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
access_length);
/*
- * Add additional 2 bytes for modeled generic_serial_bus data buffer:
- * typedef struct {
- * BYTEStatus; // Byte 0 of the data buffer
- * BYTELength; // Byte 1 of the data buffer
- * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
- * }
+ * Add additional 2 bytes for the generic_serial_bus data buffer:
+ *
+ * Status; (Byte 0 of the data buffer)
+ * Length; (Byte 1 of the data buffer)
+ * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
*/
length += 2;
function = ACPI_READ | (accessor_type << 16);
@@ -368,12 +367,11 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
access_length);
/*
- * Add additional 2 bytes for modeled generic_serial_bus data buffer:
- * typedef struct {
- * BYTEStatus; // Byte 0 of the data buffer
- * BYTELength; // Byte 1 of the data buffer
- * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
- * }
+ * Add additional 2 bytes for the generic_serial_bus data buffer:
+ *
+ * Status; (Byte 0 of the data buffer)
+ * Length; (Byte 1 of the data buffer)
+ * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
*/
length += 2;
function = ACPI_WRITE | (accessor_type << 16);
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index e0fd9b4978cd..a4c34d2c556b 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(status)) {
goto exit;
+ }
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index fe54a8c73b8c..a42ee9d6970d 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -237,6 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
(node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object;
}
+
+ /*
+ * Detach the object from any data objects (which are still held by
+ * the namespace node)
+ */
+ if (obj_desc->common.next_object &&
+ ((obj_desc->common.next_object)->common.type ==
+ ACPI_TYPE_LOCAL_DATA)) {
+ obj_desc->common.next_object = NULL;
+ }
}
/* Reset the node type to untyped */
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c
index 3c1699740653..038ea887f562 100644
--- a/drivers/acpi/acpica/utbuffer.c
+++ b/drivers/acpi/acpica/utbuffer.c
@@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
acpi_ut_dump_buffer(buffer, count, display, 0);
}
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_dump_buffer_to_file
+ *
+ * PARAMETERS: file - File descriptor
+ * buffer - Buffer to dump
+ * count - Amount to dump, in bytes
+ * display - BYTE, WORD, DWORD, or QWORD display:
+ * DB_BYTE_DISPLAY
+ * DB_WORD_DISPLAY
+ * DB_DWORD_DISPLAY
+ * DB_QWORD_DISPLAY
+ * base_offset - Beginning buffer offset (display only)
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii to a file.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_dump_buffer_to_file(ACPI_FILE file,
+ u8 *buffer, u32 count, u32 display, u32 base_offset)
+{
+ u32 i = 0;
+ u32 j;
+ u32 temp32;
+ u8 buf_char;
+
+ if (!buffer) {
+ acpi_ut_file_printf(file,
+ "Null Buffer Pointer in DumpBuffer!\n");
+ return;
+ }
+
+ if ((count < 4) || (count & 0x01)) {
+ display = DB_BYTE_DISPLAY;
+ }
+
+ /* Nasty little dump buffer routine! */
+
+ while (i < count) {
+
+ /* Print current offset */
+
+ acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i));
+
+ /* Print 16 hex chars */
+
+ for (j = 0; j < 16;) {
+ if (i + j >= count) {
+
+ /* Dump fill spaces */
+
+ acpi_ut_file_printf(file, "%*s",
+ ((display * 2) + 1), " ");
+ j += display;
+ continue;
+ }
+
+ switch (display) {
+ case DB_BYTE_DISPLAY:
+ default: /* Default is BYTE display */
+
+ acpi_ut_file_printf(file, "%02X ",
+ buffer[(acpi_size) i + j]);
+ break;
+
+ case DB_WORD_DISPLAY:
+
+ ACPI_MOVE_16_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
+ acpi_ut_file_printf(file, "%04X ", temp32);
+ break;
+
+ case DB_DWORD_DISPLAY:
+
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
+ acpi_ut_file_printf(file, "%08X ", temp32);
+ break;
+
+ case DB_QWORD_DISPLAY:
+
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j]);
+ acpi_ut_file_printf(file, "%08X", temp32);
+
+ ACPI_MOVE_32_TO_32(&temp32,
+ &buffer[(acpi_size) i + j +
+ 4]);
+ acpi_ut_file_printf(file, "%08X ", temp32);
+ break;
+ }
+
+ j += display;
+ }
+
+ /*
+ * Print the ASCII equivalent characters but watch out for the bad
+ * unprintable ones (printable chars are 0x20 through 0x7E)
+ */
+ acpi_ut_file_printf(file, " ");
+ for (j = 0; j < 16; j++) {
+ if (i + j >= count) {
+ acpi_ut_file_printf(file, "\n");
+ return;
+ }
+
+ buf_char = buffer[(acpi_size) i + j];
+ if (ACPI_IS_PRINT(buf_char)) {
+ acpi_ut_file_printf(file, "%c", buf_char);
+ } else {
+ acpi_ut_file_printf(file, ".");
+ }
+ }
+
+ /* Done with that line. */
+
+ acpi_ut_file_printf(file, "\n");
+ i += 16;
+ }
+
+ return;
+}
+#endif
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index 270c16464dd9..ff601c0f7c7a 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
}
+ /* Delete the allocated object if copy failed */
+
+ if (ACPI_FAILURE(status)) {
+ acpi_ut_remove_reference(*dest_desc);
+ }
+
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index 21a20ac5b1e1..e516254c63b2 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number,
}
#endif
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_log_error
+ *
+ * PARAMETERS: format - Printf format field
+ * ... - Optional printf arguments
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print error message to the console, used by applications.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ (void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args);
+ va_end(args);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_log_error)
+#endif
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
index 90ec37c473c6..40e923e675fc 100644
--- a/drivers/acpi/acpica/utdecode.c
+++ b/drivers/acpi/acpica/utdecode.c
@@ -88,33 +88,6 @@ const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = {
/*******************************************************************************
*
- * FUNCTION: acpi_ut_hex_to_ascii_char
- *
- * PARAMETERS: integer - Contains the hex digit
- * position - bit position of the digit within the
- * integer (multiple of 4)
- *
- * RETURN: The converted Ascii character
- *
- * DESCRIPTION: Convert a hex digit to an Ascii character
- *
- ******************************************************************************/
-
-/* Hex to ASCII conversion table */
-
-static const char acpi_gbl_hex_to_ascii[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
-{
-
- return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
-}
-
-/*******************************************************************************
- *
* FUNCTION: acpi_ut_get_region_name
*
* PARAMETERS: Space ID - ID for the region
@@ -475,7 +448,8 @@ static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = {
/* 09 */ "Device PLD Check",
/* 0A */ "Reserved",
/* 0B */ "System Locality Update",
- /* 0C */ "Shutdown Request"
+ /* 0C */ "Shutdown Request",
+ /* 0D */ "System Resource Affinity Update"
};
static const char *acpi_gbl_device_notify[4] = {
@@ -502,7 +476,7 @@ static const char *acpi_gbl_thermal_notify[4] = {
const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type)
{
- /* 00 - 0C are common to all object types */
+ /* 00 - 0D are common to all object types */
if (notify_value <= ACPI_NOTIFY_MAX) {
return (acpi_gbl_generic_notify[notify_value]);
diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c
new file mode 100644
index 000000000000..4e263a8cc6f0
--- /dev/null
+++ b/drivers/acpi/acpica/utfileio.c
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ *
+ * Module Name: utfileio - simple file I/O routines
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any 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.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "actables.h"
+#include "acapps.h"
+
+#ifdef ACPI_ASL_COMPILER
+#include "aslcompiler.h"
+#endif
+
+#define _COMPONENT ACPI_CA_DEBUGGER
+ACPI_MODULE_NAME("utfileio")
+
+#ifdef ACPI_APPLICATION
+/* Local prototypes */
+static acpi_status
+acpi_ut_check_text_mode_corruption(u8 *table,
+ u32 table_length, u32 file_length);
+
+static acpi_status
+acpi_ut_read_table(FILE * fp,
+ struct acpi_table_header **table, u32 *table_length);
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_check_text_mode_corruption
+ *
+ * PARAMETERS: table - Table buffer
+ * table_length - Length of table from the table header
+ * file_length - Length of the file that contains the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Check table for text mode file corruption where all linefeed
+ * characters (LF) have been replaced by carriage return linefeed
+ * pairs (CR/LF).
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length)
+{
+ u32 i;
+ u32 pairs = 0;
+
+ if (table_length != file_length) {
+ ACPI_WARNING((AE_INFO,
+ "File length (0x%X) is not the same as the table length (0x%X)",
+ file_length, table_length));
+ }
+
+ /* Scan entire table to determine if each LF has been prefixed with a CR */
+
+ for (i = 1; i < file_length; i++) {
+ if (table[i] == 0x0A) {
+ if (table[i - 1] != 0x0D) {
+
+ /* The LF does not have a preceding CR, table not corrupted */
+
+ return (AE_OK);
+ } else {
+ /* Found a CR/LF pair */
+
+ pairs++;
+ }
+ i++;
+ }
+ }
+
+ if (!pairs) {
+ return (AE_OK);
+ }
+
+ /*
+ * Entire table scanned, each CR is part of a CR/LF pair --
+ * meaning that the table was treated as a text file somewhere.
+ *
+ * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
+ * original table are left untouched by the text conversion process --
+ * meaning that we cannot simply replace CR/LF pairs with LFs.
+ */
+ acpi_os_printf("Table has been corrupted by text mode conversion\n");
+ acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs);
+ acpi_os_printf("Table cannot be repaired!\n");
+ return (AE_BAD_VALUE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_read_table
+ *
+ * PARAMETERS: fp - File that contains table
+ * table - Return value, buffer with table
+ * table_length - Return value, length of table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the DSDT from the file pointer
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ut_read_table(FILE * fp,
+ struct acpi_table_header **table, u32 *table_length)
+{
+ struct acpi_table_header table_header;
+ u32 actual;
+ acpi_status status;
+ u32 file_size;
+ u8 standard_header = TRUE;
+ s32 count;
+
+ /* Get the file size */
+
+ file_size = cm_get_file_size(fp);
+ if (file_size == ACPI_UINT32_MAX) {
+ return (AE_ERROR);
+ }
+
+ if (file_size < 4) {
+ return (AE_BAD_HEADER);
+ }
+
+ /* Read the signature */
+
+ fseek(fp, 0, SEEK_SET);
+
+ count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
+ if (count != sizeof(struct acpi_table_header)) {
+ acpi_os_printf("Could not read the table header\n");
+ return (AE_BAD_HEADER);
+ }
+
+ /* The RSDP table does not have standard ACPI header */
+
+ if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
+ *table_length = file_size;
+ standard_header = FALSE;
+ } else {
+
+#if 0
+ /* Validate the table header/length */
+
+ status = acpi_tb_validate_table_header(&table_header);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_printf("Table header is invalid!\n");
+ return (status);
+ }
+#endif
+
+ /* File size must be at least as long as the Header-specified length */
+
+ if (table_header.length > file_size) {
+ acpi_os_printf
+ ("TableHeader length [0x%X] greater than the input file size [0x%X]\n",
+ table_header.length, file_size);
+
+#ifdef ACPI_ASL_COMPILER
+ status = fl_check_for_ascii(fp, NULL, FALSE);
+ if (ACPI_SUCCESS(status)) {
+ acpi_os_printf
+ ("File appears to be ASCII only, must be binary\n");
+ }
+#endif
+ return (AE_BAD_HEADER);
+ }
+#ifdef ACPI_OBSOLETE_CODE
+ /* We only support a limited number of table types */
+
+ if (!ACPI_COMPARE_NAME
+ ((char *)table_header.signature, ACPI_SIG_DSDT)
+ && !ACPI_COMPARE_NAME((char *)table_header.signature,
+ ACPI_SIG_PSDT)
+ && !ACPI_COMPARE_NAME((char *)table_header.signature,
+ ACPI_SIG_SSDT)) {
+ acpi_os_printf
+ ("Table signature [%4.4s] is invalid or not supported\n",
+ (char *)table_header.signature);
+ ACPI_DUMP_BUFFER(&table_header,
+ sizeof(struct acpi_table_header));
+ return (AE_ERROR);
+ }
+#endif
+
+ *table_length = table_header.length;
+ }
+
+ /* Allocate a buffer for the table */
+
+ *table = acpi_os_allocate((size_t) file_size);
+ if (!*table) {
+ acpi_os_printf
+ ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
+ table_header.signature, *table_length);
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get the rest of the table */
+
+ fseek(fp, 0, SEEK_SET);
+ actual = fread(*table, 1, (size_t) file_size, fp);
+ if (actual == file_size) {
+ if (standard_header) {
+
+ /* Now validate the checksum */
+
+ status = acpi_tb_verify_checksum((void *)*table,
+ ACPI_CAST_PTR(struct
+ acpi_table_header,
+ *table)->
+ length);
+
+ if (status == AE_BAD_CHECKSUM) {
+ status =
+ acpi_ut_check_text_mode_corruption((u8 *)
+ *table,
+ file_size,
+ (*table)->
+ length);
+ return (status);
+ }
+ }
+ return (AE_OK);
+ }
+
+ if (actual > 0) {
+ acpi_os_printf("Warning - reading table, asked for %X got %X\n",
+ file_size, actual);
+ return (AE_OK);
+ }
+
+ acpi_os_printf("Error - could not read the table file\n");
+ acpi_os_free(*table);
+ *table = NULL;
+ *table_length = 0;
+ return (AE_ERROR);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_read_table_from_file
+ *
+ * PARAMETERS: filename - File where table is located
+ * table - Where a pointer to the table is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get an ACPI table from a file
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
+{
+ FILE *file;
+ u32 file_size;
+ u32 table_length;
+ acpi_status status = AE_ERROR;
+
+ /* Open the file, get current size */
+
+ file = fopen(filename, "rb");
+ if (!file) {
+ perror("Could not open input file");
+ return (status);
+ }
+
+ file_size = cm_get_file_size(file);
+ if (file_size == ACPI_UINT32_MAX) {
+ goto exit;
+ }
+
+ /* Get the entire file */
+
+ fprintf(stderr,
+ "Loading Acpi table from file %10s - Length %.8u (%06X)\n",
+ filename, file_size, file_size);
+
+ status = acpi_ut_read_table(file, table, &table_length);
+ if (ACPI_FAILURE(status)) {
+ acpi_os_printf("Could not get table from the file\n");
+ }
+
+exit:
+ fclose(file);
+ return (status);
+}
+
+#endif
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index d69be3cb3fae..77ceac715f28 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
};
#endif /* !ACPI_REDUCED_HARDWARE */
-/*******************************************************************************
- *
- * FUNCTION: acpi_ut_init_globals
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
- * initialization should be initialized here. This allows for
- * a warm restart.
- *
- ******************************************************************************/
-
-acpi_status acpi_ut_init_globals(void)
-{
- acpi_status status;
- u32 i;
-
- ACPI_FUNCTION_TRACE(ut_init_globals);
-
- /* Create all memory caches */
-
- status = acpi_ut_create_caches();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- /* Address Range lists */
-
- for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
- acpi_gbl_address_range_list[i] = NULL;
- }
-
- /* Mutex locked flags */
-
- for (i = 0; i < ACPI_NUM_MUTEX; i++) {
- acpi_gbl_mutex_info[i].mutex = NULL;
- acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
- acpi_gbl_mutex_info[i].use_count = 0;
- }
-
- for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
- acpi_gbl_owner_id_mask[i] = 0;
- }
-
- /* Last owner_ID is never valid */
-
- acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
-
- /* Event counters */
-
- acpi_method_count = 0;
- acpi_sci_count = 0;
- acpi_gpe_count = 0;
-
- for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
- acpi_fixed_event_count[i] = 0;
- }
-
-#if (!ACPI_REDUCED_HARDWARE)
-
- /* GPE/SCI support */
-
- acpi_gbl_all_gpes_initialized = FALSE;
- acpi_gbl_gpe_xrupt_list_head = NULL;
- acpi_gbl_gpe_fadt_blocks[0] = NULL;
- acpi_gbl_gpe_fadt_blocks[1] = NULL;
- acpi_current_gpe_count = 0;
-
- acpi_gbl_global_event_handler = NULL;
- acpi_gbl_sci_handler_list = NULL;
-
-#endif /* !ACPI_REDUCED_HARDWARE */
-
- /* Global handlers */
-
- acpi_gbl_global_notify[0].handler = NULL;
- acpi_gbl_global_notify[1].handler = NULL;
- acpi_gbl_exception_handler = NULL;
- acpi_gbl_init_handler = NULL;
- acpi_gbl_table_handler = NULL;
- acpi_gbl_interface_handler = NULL;
-
- /* Global Lock support */
-
- acpi_gbl_global_lock_semaphore = NULL;
- acpi_gbl_global_lock_mutex = NULL;
- acpi_gbl_global_lock_acquired = FALSE;
- acpi_gbl_global_lock_handle = 0;
- acpi_gbl_global_lock_present = FALSE;
-
- /* Miscellaneous variables */
-
- acpi_gbl_DSDT = NULL;
- acpi_gbl_cm_single_step = FALSE;
- acpi_gbl_shutdown = FALSE;
- acpi_gbl_ns_lookup_count = 0;
- acpi_gbl_ps_find_count = 0;
- acpi_gbl_acpi_hardware_present = TRUE;
- acpi_gbl_last_owner_id_index = 0;
- acpi_gbl_next_owner_id_offset = 0;
- acpi_gbl_trace_dbg_level = 0;
- acpi_gbl_trace_dbg_layer = 0;
- acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
- acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
- acpi_gbl_osi_mutex = NULL;
- acpi_gbl_reg_methods_executed = FALSE;
-
- /* Hardware oriented */
-
- acpi_gbl_events_initialized = FALSE;
- acpi_gbl_system_awake_and_running = TRUE;
-
- /* Namespace */
-
- acpi_gbl_module_code_list = NULL;
- acpi_gbl_root_node = NULL;
- acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
- acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
- acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
- acpi_gbl_root_node_struct.parent = NULL;
- acpi_gbl_root_node_struct.child = NULL;
- acpi_gbl_root_node_struct.peer = NULL;
- acpi_gbl_root_node_struct.object = NULL;
-
-#ifdef ACPI_DISASSEMBLER
- acpi_gbl_external_list = NULL;
- acpi_gbl_num_external_methods = 0;
- acpi_gbl_resolved_external_methods = 0;
-#endif
-
-#ifdef ACPI_DEBUG_OUTPUT
- acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
-#endif
-
-#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- acpi_gbl_display_final_mem_stats = FALSE;
- acpi_gbl_disable_mem_tracking = FALSE;
-#endif
-
- ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
-
- return_ACPI_STATUS(AE_OK);
-}
-
/* Public globals */
ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
diff --git a/drivers/acpi/acpica/uthex.c b/drivers/acpi/acpica/uthex.c
new file mode 100644
index 000000000000..9afa9441b183
--- /dev/null
+++ b/drivers/acpi/acpica/uthex.c
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ * Module Name: uthex -- Hex/ASCII support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any 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.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_COMPILER
+ACPI_MODULE_NAME("uthex")
+
+/* Hex to ASCII conversion table */
+static char acpi_gbl_hex_to_ascii[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 'E', 'F'
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_hex_to_ascii_char
+ *
+ * PARAMETERS: integer - Contains the hex digit
+ * position - bit position of the digit within the
+ * integer (multiple of 4)
+ *
+ * RETURN: The converted Ascii character
+ *
+ * DESCRIPTION: Convert a hex digit to an Ascii character
+ *
+ ******************************************************************************/
+
+char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
+{
+
+ return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_hex_char_to_value
+ *
+ * PARAMETERS: ascii_char - Hex character in Ascii
+ *
+ * RETURN: The binary value of the ascii/hex character
+ *
+ * DESCRIPTION: Perform ascii-to-hex translation
+ *
+ ******************************************************************************/
+
+u8 acpi_ut_ascii_char_to_hex(int hex_char)
+{
+
+ if (hex_char <= 0x39) {
+ return ((u8)(hex_char - 0x30));
+ }
+
+ if (hex_char <= 0x46) {
+ return ((u8)(hex_char - 0x37));
+ }
+
+ return ((u8)(hex_char - 0x57));
+}
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
index 5f56fc49021e..77120ec9ea86 100644
--- a/drivers/acpi/acpica/utinit.c
+++ b/drivers/acpi/acpica/utinit.c
@@ -102,6 +102,151 @@ static void acpi_ut_free_gpe_lists(void)
}
#endif /* !ACPI_REDUCED_HARDWARE */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_init_globals
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize ACPICA globals. All globals that require specific
+ * initialization should be initialized here. This allows for
+ * a warm restart.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_init_globals(void)
+{
+ acpi_status status;
+ u32 i;
+
+ ACPI_FUNCTION_TRACE(ut_init_globals);
+
+ /* Create all memory caches */
+
+ status = acpi_ut_create_caches();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /* Address Range lists */
+
+ for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
+ acpi_gbl_address_range_list[i] = NULL;
+ }
+
+ /* Mutex locked flags */
+
+ for (i = 0; i < ACPI_NUM_MUTEX; i++) {
+ acpi_gbl_mutex_info[i].mutex = NULL;
+ acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
+ acpi_gbl_mutex_info[i].use_count = 0;
+ }
+
+ for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
+ acpi_gbl_owner_id_mask[i] = 0;
+ }
+
+ /* Last owner_ID is never valid */
+
+ acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
+
+ /* Event counters */
+
+ acpi_method_count = 0;
+ acpi_sci_count = 0;
+ acpi_gpe_count = 0;
+
+ for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
+ acpi_fixed_event_count[i] = 0;
+ }
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+ /* GPE/SCI support */
+
+ acpi_gbl_all_gpes_initialized = FALSE;
+ acpi_gbl_gpe_xrupt_list_head = NULL;
+ acpi_gbl_gpe_fadt_blocks[0] = NULL;
+ acpi_gbl_gpe_fadt_blocks[1] = NULL;
+ acpi_current_gpe_count = 0;
+
+ acpi_gbl_global_event_handler = NULL;
+ acpi_gbl_sci_handler_list = NULL;
+
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+ /* Global handlers */
+
+ acpi_gbl_global_notify[0].handler = NULL;
+ acpi_gbl_global_notify[1].handler = NULL;
+ acpi_gbl_exception_handler = NULL;
+ acpi_gbl_init_handler = NULL;
+ acpi_gbl_table_handler = NULL;
+ acpi_gbl_interface_handler = NULL;
+
+ /* Global Lock support */
+
+ acpi_gbl_global_lock_semaphore = NULL;
+ acpi_gbl_global_lock_mutex = NULL;
+ acpi_gbl_global_lock_acquired = FALSE;
+ acpi_gbl_global_lock_handle = 0;
+ acpi_gbl_global_lock_present = FALSE;
+
+ /* Miscellaneous variables */
+
+ acpi_gbl_DSDT = NULL;
+ acpi_gbl_cm_single_step = FALSE;
+ acpi_gbl_shutdown = FALSE;
+ acpi_gbl_ns_lookup_count = 0;
+ acpi_gbl_ps_find_count = 0;
+ acpi_gbl_acpi_hardware_present = TRUE;
+ acpi_gbl_last_owner_id_index = 0;
+ acpi_gbl_next_owner_id_offset = 0;
+ acpi_gbl_trace_dbg_level = 0;
+ acpi_gbl_trace_dbg_layer = 0;
+ acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
+ acpi_gbl_osi_mutex = NULL;
+ acpi_gbl_reg_methods_executed = FALSE;
+
+ /* Hardware oriented */
+
+ acpi_gbl_events_initialized = FALSE;
+ acpi_gbl_system_awake_and_running = TRUE;
+
+ /* Namespace */
+
+ acpi_gbl_module_code_list = NULL;
+ acpi_gbl_root_node = NULL;
+ acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
+ acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
+ acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
+ acpi_gbl_root_node_struct.parent = NULL;
+ acpi_gbl_root_node_struct.child = NULL;
+ acpi_gbl_root_node_struct.peer = NULL;
+ acpi_gbl_root_node_struct.object = NULL;
+
+#ifdef ACPI_DISASSEMBLER
+ acpi_gbl_external_list = NULL;
+ acpi_gbl_num_external_methods = 0;
+ acpi_gbl_resolved_external_methods = 0;
+#endif
+
+#ifdef ACPI_DEBUG_OUTPUT
+ acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
+#endif
+
+#ifdef ACPI_DBG_TRACK_ALLOCATIONS
+ acpi_gbl_display_final_mem_stats = FALSE;
+ acpi_gbl_disable_mem_tracking = FALSE;
+#endif
+
+ ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
+
+ return_ACPI_STATUS(AE_OK);
+}
+
/******************************************************************************
*
* FUNCTION: acpi_ut_terminate
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c
new file mode 100644
index 000000000000..0ce3f5a0dd67
--- /dev/null
+++ b/drivers/acpi/acpica/utprint.c
@@ -0,0 +1,664 @@
+/******************************************************************************
+ *
+ * Module Name: utprint - Formatted printing routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any 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.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utprint")
+
+#define ACPI_FORMAT_SIGN 0x01
+#define ACPI_FORMAT_SIGN_PLUS 0x02
+#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04
+#define ACPI_FORMAT_ZERO 0x08
+#define ACPI_FORMAT_LEFT 0x10
+#define ACPI_FORMAT_UPPER 0x20
+#define ACPI_FORMAT_PREFIX 0x40
+/* Local prototypes */
+static acpi_size
+acpi_ut_bound_string_length(const char *string, acpi_size count);
+
+static char *acpi_ut_bound_string_output(char *string, const char *end, char c);
+
+static char *acpi_ut_format_number(char *string,
+ char *end,
+ u64 number,
+ u8 base, s32 width, s32 precision, u8 type);
+
+static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper);
+
+/* Module globals */
+
+static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef";
+static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF";
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_bound_string_length
+ *
+ * PARAMETERS: string - String with boundary
+ * count - Boundary of the string
+ *
+ * RETURN: Length of the string. Less than or equal to Count.
+ *
+ * DESCRIPTION: Calculate the length of a string with boundary.
+ *
+ ******************************************************************************/
+
+static acpi_size
+acpi_ut_bound_string_length(const char *string, acpi_size count)
+{
+ u32 length = 0;
+
+ while (*string && count) {
+ length++;
+ string++;
+ count--;
+ }
+
+ return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_bound_string_output
+ *
+ * PARAMETERS: string - String with boundary
+ * end - Boundary of the string
+ * c - Character to be output to the string
+ *
+ * RETURN: Updated position for next valid character
+ *
+ * DESCRIPTION: Output a character into a string with boundary check.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_bound_string_output(char *string, const char *end, char c)
+{
+
+ if (string < end) {
+ *string = c;
+ }
+
+ ++string;
+ return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_put_number
+ *
+ * PARAMETERS: string - Buffer to hold reverse-ordered string
+ * number - Integer to be converted
+ * base - Base of the integer
+ * upper - Whether or not using upper cased digits
+ *
+ * RETURN: Updated position for next valid character
+ *
+ * DESCRIPTION: Convert an integer into a string, note that, the string holds a
+ * reversed ordered number without the trailing zero.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper)
+{
+ const char *digits;
+ u64 digit_index;
+ char *pos;
+
+ pos = string;
+ digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits;
+
+ if (number == 0) {
+ *(pos++) = '0';
+ } else {
+ while (number) {
+ (void)acpi_ut_divide(number, base, &number,
+ &digit_index);
+ *(pos++) = digits[digit_index];
+ }
+ }
+
+ /* *(Pos++) = '0'; */
+ return (pos);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_scan_number
+ *
+ * PARAMETERS: string - String buffer
+ * number_ptr - Where the number is returned
+ *
+ * RETURN: Updated position for next valid character
+ *
+ * DESCRIPTION: Scan a string for a decimal integer.
+ *
+ ******************************************************************************/
+
+const char *acpi_ut_scan_number(const char *string, u64 *number_ptr)
+{
+ u64 number = 0;
+
+ while (ACPI_IS_DIGIT(*string)) {
+ number *= 10;
+ number += *(string++) - '0';
+ }
+
+ *number_ptr = number;
+ return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_print_number
+ *
+ * PARAMETERS: string - String buffer
+ * number - The number to be converted
+ *
+ * RETURN: Updated position for next valid character
+ *
+ * DESCRIPTION: Print a decimal integer into a string.
+ *
+ ******************************************************************************/
+
+const char *acpi_ut_print_number(char *string, u64 number)
+{
+ char ascii_string[20];
+ const char *pos1;
+ char *pos2;
+
+ pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE);
+ pos2 = string;
+
+ while (pos1 != ascii_string) {
+ *(pos2++) = *(--pos1);
+ }
+
+ *pos2 = 0;
+ return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_format_number
+ *
+ * PARAMETERS: string - String buffer with boundary
+ * end - Boundary of the string
+ * number - The number to be converted
+ * base - Base of the integer
+ * width - Field width
+ * precision - Precision of the integer
+ * type - Special printing flags
+ *
+ * RETURN: Updated position for next valid character
+ *
+ * DESCRIPTION: Print an integer into a string with any base and any precision.
+ *
+ ******************************************************************************/
+
+static char *acpi_ut_format_number(char *string,
+ char *end,
+ u64 number,
+ u8 base, s32 width, s32 precision, u8 type)
+{
+ char *pos;
+ char sign;
+ char zero;
+ u8 need_prefix;
+ u8 upper;
+ s32 i;
+ char reversed_string[66];
+
+ /* Parameter validation */
+
+ if (base < 2 || base > 16) {
+ return (NULL);
+ }
+
+ if (type & ACPI_FORMAT_LEFT) {
+ type &= ~ACPI_FORMAT_ZERO;
+ }
+
+ need_prefix = ((type & ACPI_FORMAT_PREFIX)
+ && base != 10) ? TRUE : FALSE;
+ upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE;
+ zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' ';
+
+ /* Calculate size according to sign and prefix */
+
+ sign = '\0';
+ if (type & ACPI_FORMAT_SIGN) {
+ if ((s64) number < 0) {
+ sign = '-';
+ number = -(s64) number;
+ width--;
+ } else if (type & ACPI_FORMAT_SIGN_PLUS) {
+ sign = '+';
+ width--;
+ } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) {
+ sign = ' ';
+ width--;
+ }
+ }
+ if (need_prefix) {
+ width--;
+ if (base == 16) {
+ width--;
+ }
+ }
+
+ /* Generate full string in reverse order */
+
+ pos = acpi_ut_put_number(reversed_string, number, base, upper);
+ i = ACPI_PTR_DIFF(pos, reversed_string);
+
+ /* Printing 100 using %2d gives "100", not "00" */
+
+ if (i > precision) {
+ precision = i;
+ }
+
+ width -= precision;
+
+ /* Output the string */
+
+ if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) {
+ while (--width >= 0) {
+ string = acpi_ut_bound_string_output(string, end, ' ');
+ }
+ }
+ if (sign) {
+ string = acpi_ut_bound_string_output(string, end, sign);
+ }
+ if (need_prefix) {
+ string = acpi_ut_bound_string_output(string, end, '0');
+ if (base == 16) {
+ string = acpi_ut_bound_string_output(string, end,
+ upper ? 'X' : 'x');
+ }
+ }
+ if (!(type & ACPI_FORMAT_LEFT)) {
+ while (--width >= 0) {
+ string = acpi_ut_bound_string_output(string, end, zero);
+ }
+ }
+
+ while (i <= --precision) {
+ string = acpi_ut_bound_string_output(string, end, '0');
+ }
+ while (--i >= 0) {
+ string = acpi_ut_bound_string_output(string, end,
+ reversed_string[i]);
+ }
+ while (--width >= 0) {
+ string = acpi_ut_bound_string_output(string, end, ' ');
+ }
+
+ return (string);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_vsnprintf
+ *
+ * PARAMETERS: string - String with boundary
+ * size - Boundary of the string
+ * format - Standard printf format
+ * args - Argument list
+ *
+ * RETURN: Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a string using argument list pointer.
+ *
+ ******************************************************************************/
+
+int
+acpi_ut_vsnprintf(char *string,
+ acpi_size size, const char *format, va_list args)
+{
+ u8 base = 10;
+ u8 type = 0;
+ s32 width = -1;
+ s32 precision = -1;
+ char qualifier = 0;
+ u64 number;
+ char *pos;
+ char *end;
+ char c;
+ const char *s;
+ const void *p;
+ s32 length;
+ int i;
+
+ pos = string;
+ end = string + size;
+
+ for (; *format; ++format) {
+ if (*format != '%') {
+ pos = acpi_ut_bound_string_output(pos, end, *format);
+ continue;
+ }
+
+ /* Process sign */
+
+ do {
+ ++format;
+ if (*format == '#') {
+ type |= ACPI_FORMAT_PREFIX;
+ } else if (*format == '0') {
+ type |= ACPI_FORMAT_ZERO;
+ } else if (*format == '+') {
+ type |= ACPI_FORMAT_SIGN_PLUS;
+ } else if (*format == ' ') {
+ type |= ACPI_FORMAT_SIGN_PLUS_SPACE;
+ } else if (*format == '-') {
+ type |= ACPI_FORMAT_LEFT;
+ } else {
+ break;
+ }
+ } while (1);
+
+ /* Process width */
+
+ width = -1;
+ if (ACPI_IS_DIGIT(*format)) {
+ format = acpi_ut_scan_number(format, &number);
+ width = (s32) number;
+ } else if (*format == '*') {
+ ++format;
+ width = va_arg(args, int);
+ if (width < 0) {
+ width = -width;
+ type |= ACPI_FORMAT_LEFT;
+ }
+ }
+
+ /* Process precision */
+
+ precision = -1;
+ if (*format == '.') {
+ ++format;
+ if (ACPI_IS_DIGIT(*format)) {
+ format = acpi_ut_scan_number(format, &number);
+ precision = (s32) number;
+ } else if (*format == '*') {
+ ++format;
+ precision = va_arg(args, int);
+ }
+ if (precision < 0) {
+ precision = 0;
+ }
+ }
+
+ /* Process qualifier */
+
+ qualifier = -1;
+ if (*format == 'h' || *format == 'l' || *format == 'L') {
+ qualifier = *format;
+ ++format;
+
+ if (qualifier == 'l' && *format == 'l') {
+ qualifier = 'L';
+ ++format;
+ }
+ }
+
+ switch (*format) {
+ case '%':
+
+ pos = acpi_ut_bound_string_output(pos, end, '%');
+ continue;
+
+ case 'c':
+
+ if (!(type & ACPI_FORMAT_LEFT)) {
+ while (--width > 0) {
+ pos =
+ acpi_ut_bound_string_output(pos,
+ end,
+ ' ');
+ }
+ }
+
+ c = (char)va_arg(args, int);
+ pos = acpi_ut_bound_string_output(pos, end, c);
+
+ while (--width > 0) {
+ pos =
+ acpi_ut_bound_string_output(pos, end, ' ');
+ }
+ continue;
+
+ case 's':
+
+ s = va_arg(args, char *);
+ if (!s) {
+ s = "<NULL>";
+ }
+ length = acpi_ut_bound_string_length(s, precision);
+ if (!(type & ACPI_FORMAT_LEFT)) {
+ while (length < width--) {
+ pos =
+ acpi_ut_bound_string_output(pos,
+ end,
+ ' ');
+ }
+ }
+ for (i = 0; i < length; ++i) {
+ pos = acpi_ut_bound_string_output(pos, end, *s);
+ ++s;
+ }
+ while (length < width--) {
+ pos =
+ acpi_ut_bound_string_output(pos, end, ' ');
+ }
+ continue;
+
+ case 'o':
+
+ base = 8;
+ break;
+
+ case 'X':
+
+ type |= ACPI_FORMAT_UPPER;
+
+ case 'x':
+
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+
+ type |= ACPI_FORMAT_SIGN;
+
+ case 'u':
+
+ break;
+
+ case 'p':
+
+ if (width == -1) {
+ width = 2 * sizeof(void *);
+ type |= ACPI_FORMAT_ZERO;
+ }
+
+ p = va_arg(args, void *);
+ pos = acpi_ut_format_number(pos, end,
+ ACPI_TO_INTEGER(p), 16,
+ width, precision, type);
+ continue;
+
+ default:
+
+ pos = acpi_ut_bound_string_output(pos, end, '%');
+ if (*format) {
+ pos =
+ acpi_ut_bound_string_output(pos, end,
+ *format);
+ } else {
+ --format;
+ }
+ continue;
+ }
+
+ if (qualifier == 'L') {
+ number = va_arg(args, u64);
+ if (type & ACPI_FORMAT_SIGN) {
+ number = (s64) number;
+ }
+ } else if (qualifier == 'l') {
+ number = va_arg(args, unsigned long);
+ if (type & ACPI_FORMAT_SIGN) {
+ number = (s32) number;
+ }
+ } else if (qualifier == 'h') {
+ number = (u16)va_arg(args, int);
+ if (type & ACPI_FORMAT_SIGN) {
+ number = (s16) number;
+ }
+ } else {
+ number = va_arg(args, unsigned int);
+ if (type & ACPI_FORMAT_SIGN) {
+ number = (signed int)number;
+ }
+ }
+
+ pos = acpi_ut_format_number(pos, end, number, base,
+ width, precision, type);
+ }
+
+ if (size > 0) {
+ if (pos < end) {
+ *pos = '\0';
+ } else {
+ end[-1] = '\0';
+ }
+ }
+
+ return (ACPI_PTR_DIFF(pos, string));
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_snprintf
+ *
+ * PARAMETERS: string - String with boundary
+ * size - Boundary of the string
+ * Format, ... - Standard printf format
+ *
+ * RETURN: Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a string.
+ *
+ ******************************************************************************/
+
+int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
+{
+ va_list args;
+ int length;
+
+ va_start(args, format);
+ length = acpi_ut_vsnprintf(string, size, format, args);
+ va_end(args);
+
+ return (length);
+}
+
+#ifdef ACPI_APPLICATION
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_file_vprintf
+ *
+ * PARAMETERS: file - File descriptor
+ * format - Standard printf format
+ * args - Argument list
+ *
+ * RETURN: Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a file using argument list pointer.
+ *
+ ******************************************************************************/
+
+int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
+{
+ acpi_cpu_flags flags;
+ int length;
+
+ flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
+ length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
+ sizeof(acpi_gbl_print_buffer), format, args);
+
+ (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
+ acpi_os_release_lock(acpi_gbl_print_lock, flags);
+
+ return (length);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_file_printf
+ *
+ * PARAMETERS: file - File descriptor
+ * Format, ... - Standard printf format
+ *
+ * RETURN: Number of bytes actually written.
+ *
+ * DESCRIPTION: Formatted output to a file.
+ *
+ ******************************************************************************/
+
+int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
+{
+ va_list args;
+ int length;
+
+ va_start(args, format);
+ length = acpi_ut_file_vprintf(file, format, args);
+ va_end(args);
+
+ return (length);
+}
+#endif
diff --git a/drivers/acpi/acpica/utuuid.c b/drivers/acpi/acpica/utuuid.c
new file mode 100644
index 000000000000..4dc33130f134
--- /dev/null
+++ b/drivers/acpi/acpica/utuuid.c
@@ -0,0 +1,96 @@
+/******************************************************************************
+ *
+ * Module Name: utuuid -- UUID support functions
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, Intel Corp.
+ * 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,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any 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.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_COMPILER
+ACPI_MODULE_NAME("utuuid")
+
+/*
+ * UUID support functions.
+ *
+ * This table is used to convert an input UUID ascii string to a 16 byte
+ * buffer and the reverse. The table maps a UUID buffer index 0-15 to
+ * the index within the 36-byte UUID string where the associated 2-byte
+ * hex value can be found.
+ *
+ * 36-byte UUID strings are of the form:
+ * aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+ * Where aa-pp are one byte hex numbers, made up of two hex digits
+ *
+ * Note: This table is basically the inverse of the string-to-offset table
+ * found in the ACPI spec in the description of the to_UUID macro.
+ */
+const u8 acpi_gbl_map_to_uuid_offset[UUID_BUFFER_LENGTH] = {
+ 6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34
+};
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_convert_string_to_uuid
+ *
+ * PARAMETERS: in_string - 36-byte formatted UUID string
+ * uuid_buffer - Where the 16-byte UUID buffer is returned
+ *
+ * RETURN: None. Output data is returned in the uuid_buffer
+ *
+ * DESCRIPTION: Convert a 36-byte formatted UUID string to 16-byte UUID buffer
+ *
+ ******************************************************************************/
+
+void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer)
+{
+ u32 i;
+
+ for (i = 0; i < UUID_BUFFER_LENGTH; i++) {
+ uuid_buffer[i] =
+ (acpi_ut_ascii_char_to_hex
+ (in_string[acpi_gbl_map_to_uuid_offset[i]]) << 4);
+
+ uuid_buffer[i] |=
+ acpi_ut_ascii_char_to_hex(in_string
+ [acpi_gbl_map_to_uuid_offset[i] +
+ 1]);
+ }
+}
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index c4dac7150960..b0140c8fc733 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -1,9 +1,15 @@
+config HAVE_ACPI_APEI
+ bool
+
+config HAVE_ACPI_APEI_NMI
+ bool
+
config ACPI_APEI
bool "ACPI Platform Error Interface (APEI)"
select MISC_FILESYSTEMS
select PSTORE
select UEFI_CPER
- depends on X86
+ depends on HAVE_ACPI_APEI
help
APEI allows to report errors (for example from the chipset)
to the operating system. This improves NMI handling
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 8678dfe5366b..2cd7bdd6c8b3 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -745,6 +745,19 @@ struct dentry *apei_get_debugfs_dir(void)
}
EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
+int __weak arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr,
+ void *data)
+{
+ return 1;
+}
+EXPORT_SYMBOL_GPL(arch_apei_enable_cmcff);
+
+void __weak arch_apei_report_mem_error(int sev,
+ struct cper_sec_mem_err *mem_err)
+{
+}
+EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
+
int apei_osc_setup(void)
{
static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index e5bcd919d4e6..16129c78b489 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -121,11 +121,11 @@ struct dentry;
struct dentry *apei_get_debugfs_dir(void);
#define apei_estatus_for_each_section(estatus, section) \
- for (section = (struct acpi_generic_data *)(estatus + 1); \
+ for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)estatus < estatus->data_length; \
section = (void *)(section+1) + section->error_data_length)
-static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
+static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)
{
if (estatus->raw_data_length)
return estatus->raw_data_offset + \
@@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
}
void cper_estatus_print(const char *pfx,
- const struct acpi_generic_status *estatus);
-int cper_estatus_check_header(const struct acpi_generic_status *estatus);
-int cper_estatus_check(const struct acpi_generic_status *estatus);
+ const struct acpi_hest_generic_status *estatus);
+int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus);
+int cper_estatus_check(const struct acpi_hest_generic_status *estatus);
int apei_osc_setup(void);
#endif
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index dab7cb7349df..fc5f780bb61d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -47,11 +47,11 @@
#include <linux/genalloc.h>
#include <linux/pci.h>
#include <linux/aer.h>
+#include <linux/nmi.h>
#include <acpi/ghes.h>
-#include <asm/mce.h>
+#include <acpi/apei.h>
#include <asm/tlbflush.h>
-#include <asm/nmi.h>
#include "apei-internal.h"
@@ -74,20 +74,18 @@
#define GHES_ESTATUS_CACHE_LEN(estatus_len) \
(sizeof(struct ghes_estatus_cache) + (estatus_len))
#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \
- ((struct acpi_generic_status *) \
+ ((struct acpi_hest_generic_status *) \
((struct ghes_estatus_cache *)(estatus_cache) + 1))
#define GHES_ESTATUS_NODE_LEN(estatus_len) \
(sizeof(struct ghes_estatus_node) + (estatus_len))
#define GHES_ESTATUS_FROM_NODE(estatus_node) \
- ((struct acpi_generic_status *) \
+ ((struct acpi_hest_generic_status *) \
((struct ghes_estatus_node *)(estatus_node) + 1))
bool ghes_disable;
module_param_named(disable, ghes_disable, bool, 0);
-static int ghes_panic_timeout __read_mostly = 30;
-
/*
* All error sources notified with SCI shares one notifier function,
* so they need to be linked and checked one by one. This is applied
@@ -97,16 +95,9 @@ static int ghes_panic_timeout __read_mostly = 30;
* list changing, not for traversing.
*/
static LIST_HEAD(ghes_sci);
-static LIST_HEAD(ghes_nmi);
static DEFINE_MUTEX(ghes_list_mutex);
/*
- * NMI may be triggered on any CPU, so ghes_nmi_lock is used for
- * mutual exclusion.
- */
-static DEFINE_RAW_SPINLOCK(ghes_nmi_lock);
-
-/*
* Because the memory area used to transfer hardware error information
* from BIOS to Linux can be determined only in NMI, IRQ or timer
* handler, but general ioremap can not be used in atomic context, so
@@ -114,12 +105,16 @@ static DEFINE_RAW_SPINLOCK(ghes_nmi_lock);
*/
/*
- * Two virtual pages are used, one for NMI context, the other for
- * IRQ/PROCESS context
+ * Two virtual pages are used, one for IRQ/PROCESS context, the other for
+ * NMI context (optionally).
*/
-#define GHES_IOREMAP_PAGES 2
-#define GHES_IOREMAP_NMI_PAGE(base) (base)
-#define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE)
+#ifdef CONFIG_HAVE_ACPI_APEI_NMI
+#define GHES_IOREMAP_PAGES 2
+#else
+#define GHES_IOREMAP_PAGES 1
+#endif
+#define GHES_IOREMAP_IRQ_PAGE(base) (base)
+#define GHES_IOREMAP_NMI_PAGE(base) ((base) + PAGE_SIZE)
/* virtual memory area for atomic ioremap */
static struct vm_struct *ghes_ioremap_area;
@@ -130,18 +125,8 @@ static struct vm_struct *ghes_ioremap_area;
static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi);
static DEFINE_SPINLOCK(ghes_ioremap_lock_irq);
-/*
- * printk is not safe in NMI context. So in NMI handler, we allocate
- * required memory from lock-less memory allocator
- * (ghes_estatus_pool), save estatus into it, put them into lock-less
- * list (ghes_estatus_llist), then delay printk into IRQ context via
- * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record
- * required pool size by all NMI error source.
- */
static struct gen_pool *ghes_estatus_pool;
static unsigned long ghes_estatus_pool_size_request;
-static struct llist_head ghes_estatus_llist;
-static struct irq_work ghes_proc_irq_work;
struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
static atomic_t ghes_estatus_cache_alloced;
@@ -192,7 +177,7 @@ static void ghes_iounmap_nmi(void __iomem *vaddr_ptr)
BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base));
unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
- __flush_tlb_one(vaddr);
+ arch_apei_flush_tlb_one(vaddr);
}
static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
@@ -202,7 +187,7 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base));
unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
- __flush_tlb_one(vaddr);
+ arch_apei_flush_tlb_one(vaddr);
}
static int ghes_estatus_pool_init(void)
@@ -249,11 +234,6 @@ static int ghes_estatus_pool_expand(unsigned long len)
return 0;
}
-static void ghes_estatus_pool_shrink(unsigned long len)
-{
- ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
-}
-
static struct ghes *ghes_new(struct acpi_hest_generic *generic)
{
struct ghes *ghes;
@@ -408,7 +388,7 @@ static void ghes_clear_estatus(struct ghes *ghes)
ghes->flags &= ~GHES_TO_CLEAR;
}
-static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
+static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
{
#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
unsigned long pfn;
@@ -441,10 +421,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
}
static void ghes_do_proc(struct ghes *ghes,
- const struct acpi_generic_status *estatus)
+ const struct acpi_hest_generic_status *estatus)
{
int sev, sec_sev;
- struct acpi_generic_data *gdata;
+ struct acpi_hest_generic_data *gdata;
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
@@ -455,9 +435,7 @@ static void ghes_do_proc(struct ghes *ghes,
mem_err = (struct cper_sec_mem_err *)(gdata+1);
ghes_edac_report_mem_error(ghes, sev, mem_err);
-#ifdef CONFIG_X86_MCE
- apei_mce_report_mem_error(sev, mem_err);
-#endif
+ arch_apei_report_mem_error(sev, mem_err);
ghes_handle_memory_failure(gdata, sev);
}
#ifdef CONFIG_ACPI_APEI_PCIEAER
@@ -498,7 +476,7 @@ static void ghes_do_proc(struct ghes *ghes,
static void __ghes_print_estatus(const char *pfx,
const struct acpi_hest_generic *generic,
- const struct acpi_generic_status *estatus)
+ const struct acpi_hest_generic_status *estatus)
{
static atomic_t seqno;
unsigned int curr_seqno;
@@ -520,7 +498,7 @@ static void __ghes_print_estatus(const char *pfx,
static int ghes_print_estatus(const char *pfx,
const struct acpi_hest_generic *generic,
- const struct acpi_generic_status *estatus)
+ const struct acpi_hest_generic_status *estatus)
{
/* Not more than 2 messages every 5 seconds */
static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
@@ -542,13 +520,13 @@ static int ghes_print_estatus(const char *pfx,
* GHES error status reporting throttle, to report more kinds of
* errors, instead of just most frequently occurred errors.
*/
-static int ghes_estatus_cached(struct acpi_generic_status *estatus)
+static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
{
u32 len;
int i, cached = 0;
unsigned long long now;
struct ghes_estatus_cache *cache;
- struct acpi_generic_status *cache_estatus;
+ struct acpi_hest_generic_status *cache_estatus;
len = cper_estatus_len(estatus);
rcu_read_lock();
@@ -573,12 +551,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus)
static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
struct acpi_hest_generic *generic,
- struct acpi_generic_status *estatus)
+ struct acpi_hest_generic_status *estatus)
{
int alloced;
u32 len, cache_len;
struct ghes_estatus_cache *cache;
- struct acpi_generic_status *cache_estatus;
+ struct acpi_hest_generic_status *cache_estatus;
alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
@@ -621,7 +599,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
static void ghes_estatus_cache_add(
struct acpi_hest_generic *generic,
- struct acpi_generic_status *estatus)
+ struct acpi_hest_generic_status *estatus)
{
int i, slot = -1, count;
unsigned long long now, duration, period, max_period = 0;
@@ -734,6 +712,32 @@ static int ghes_notify_sci(struct notifier_block *this,
return ret;
}
+static struct notifier_block ghes_notifier_sci = {
+ .notifier_call = ghes_notify_sci,
+};
+
+#ifdef CONFIG_HAVE_ACPI_APEI_NMI
+/*
+ * printk is not safe in NMI context. So in NMI handler, we allocate
+ * required memory from lock-less memory allocator
+ * (ghes_estatus_pool), save estatus into it, put them into lock-less
+ * list (ghes_estatus_llist), then delay printk into IRQ context via
+ * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record
+ * required pool size by all NMI error source.
+ */
+static struct llist_head ghes_estatus_llist;
+static struct irq_work ghes_proc_irq_work;
+
+/*
+ * NMI may be triggered on any CPU, so ghes_nmi_lock is used for
+ * mutual exclusion.
+ */
+static DEFINE_RAW_SPINLOCK(ghes_nmi_lock);
+
+static LIST_HEAD(ghes_nmi);
+
+static int ghes_panic_timeout __read_mostly = 30;
+
static struct llist_node *llist_nodes_reverse(struct llist_node *llnode)
{
struct llist_node *next, *tail = NULL;
@@ -753,7 +757,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
struct llist_node *llnode, *next;
struct ghes_estatus_node *estatus_node;
struct acpi_hest_generic *generic;
- struct acpi_generic_status *estatus;
+ struct acpi_hest_generic_status *estatus;
u32 len, node_len;
llnode = llist_del_all(&ghes_estatus_llist);
@@ -786,7 +790,7 @@ static void ghes_print_queued_estatus(void)
struct llist_node *llnode;
struct ghes_estatus_node *estatus_node;
struct acpi_hest_generic *generic;
- struct acpi_generic_status *estatus;
+ struct acpi_hest_generic_status *estatus;
u32 len, node_len;
llnode = llist_del_all(&ghes_estatus_llist);
@@ -845,7 +849,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
u32 len, node_len;
struct ghes_estatus_node *estatus_node;
- struct acpi_generic_status *estatus;
+ struct acpi_hest_generic_status *estatus;
#endif
if (!(ghes->flags & GHES_TO_CLEAR))
continue;
@@ -877,10 +881,6 @@ out:
return ret;
}
-static struct notifier_block ghes_notifier_sci = {
- .notifier_call = ghes_notify_sci,
-};
-
static unsigned long ghes_esource_prealloc_size(
const struct acpi_hest_generic *generic)
{
@@ -896,11 +896,71 @@ static unsigned long ghes_esource_prealloc_size(
return prealloc_size;
}
+static void ghes_estatus_pool_shrink(unsigned long len)
+{
+ ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
+}
+
+static void ghes_nmi_add(struct ghes *ghes)
+{
+ unsigned long len;
+
+ len = ghes_esource_prealloc_size(ghes->generic);
+ ghes_estatus_pool_expand(len);
+ mutex_lock(&ghes_list_mutex);
+ if (list_empty(&ghes_nmi))
+ register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
+ list_add_rcu(&ghes->list, &ghes_nmi);
+ mutex_unlock(&ghes_list_mutex);
+}
+
+static void ghes_nmi_remove(struct ghes *ghes)
+{
+ unsigned long len;
+
+ mutex_lock(&ghes_list_mutex);
+ list_del_rcu(&ghes->list);
+ if (list_empty(&ghes_nmi))
+ unregister_nmi_handler(NMI_LOCAL, "ghes");
+ mutex_unlock(&ghes_list_mutex);
+ /*
+ * To synchronize with NMI handler, ghes can only be
+ * freed after NMI handler finishes.
+ */
+ synchronize_rcu();
+ len = ghes_esource_prealloc_size(ghes->generic);
+ ghes_estatus_pool_shrink(len);
+}
+
+static void ghes_nmi_init_cxt(void)
+{
+ init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq);
+}
+#else /* CONFIG_HAVE_ACPI_APEI_NMI */
+static inline void ghes_nmi_add(struct ghes *ghes)
+{
+ pr_err(GHES_PFX "ID: %d, trying to add NMI notification which is not supported!\n",
+ ghes->generic->header.source_id);
+ BUG();
+}
+
+static inline void ghes_nmi_remove(struct ghes *ghes)
+{
+ pr_err(GHES_PFX "ID: %d, trying to remove NMI notification which is not supported!\n",
+ ghes->generic->header.source_id);
+ BUG();
+}
+
+static inline void ghes_nmi_init_cxt(void)
+{
+}
+#endif /* CONFIG_HAVE_ACPI_APEI_NMI */
+
static int ghes_probe(struct platform_device *ghes_dev)
{
struct acpi_hest_generic *generic;
struct ghes *ghes = NULL;
- unsigned long len;
+
int rc = -EINVAL;
generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data;
@@ -911,7 +971,13 @@ static int ghes_probe(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_POLLED:
case ACPI_HEST_NOTIFY_EXTERNAL:
case ACPI_HEST_NOTIFY_SCI:
+ break;
case ACPI_HEST_NOTIFY_NMI:
+ if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
+ pr_warn(GHES_PFX "Generic hardware error source: %d notified via NMI interrupt is not supported!\n",
+ generic->header.source_id);
+ goto err;
+ }
break;
case ACPI_HEST_NOTIFY_LOCAL:
pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n",
@@ -925,7 +991,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
rc = -EIO;
if (generic->error_block_length <
- sizeof(struct acpi_generic_status)) {
+ sizeof(struct acpi_hest_generic_status)) {
pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
generic->error_block_length,
generic->header.source_id);
@@ -972,14 +1038,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
mutex_unlock(&ghes_list_mutex);
break;
case ACPI_HEST_NOTIFY_NMI:
- len = ghes_esource_prealloc_size(generic);
- ghes_estatus_pool_expand(len);
- mutex_lock(&ghes_list_mutex);
- if (list_empty(&ghes_nmi))
- register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0,
- "ghes");
- list_add_rcu(&ghes->list, &ghes_nmi);
- mutex_unlock(&ghes_list_mutex);
+ ghes_nmi_add(ghes);
break;
default:
BUG();
@@ -1001,7 +1060,6 @@ static int ghes_remove(struct platform_device *ghes_dev)
{
struct ghes *ghes;
struct acpi_hest_generic *generic;
- unsigned long len;
ghes = platform_get_drvdata(ghes_dev);
generic = ghes->generic;
@@ -1022,18 +1080,7 @@ static int ghes_remove(struct platform_device *ghes_dev)
mutex_unlock(&ghes_list_mutex);
break;
case ACPI_HEST_NOTIFY_NMI:
- mutex_lock(&ghes_list_mutex);
- list_del_rcu(&ghes->list);
- if (list_empty(&ghes_nmi))
- unregister_nmi_handler(NMI_LOCAL, "ghes");
- mutex_unlock(&ghes_list_mutex);
- /*
- * To synchronize with NMI handler, ghes can only be
- * freed after NMI handler finishes.
- */
- synchronize_rcu();
- len = ghes_esource_prealloc_size(generic);
- ghes_estatus_pool_shrink(len);
+ ghes_nmi_remove(ghes);
break;
default:
BUG();
@@ -1077,7 +1124,7 @@ static int __init ghes_init(void)
return -EINVAL;
}
- init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq);
+ ghes_nmi_init_cxt();
rc = ghes_ioremap_init();
if (rc)
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index f5e37f32c71f..06e9b411a0a2 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -36,7 +36,6 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <acpi/apei.h>
-#include <asm/mce.h>
#include "apei-internal.h"
@@ -128,33 +127,7 @@ EXPORT_SYMBOL_GPL(apei_hest_parse);
*/
static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data)
{
-#ifdef CONFIG_X86_MCE
- int i;
- struct acpi_hest_ia_corrected *cmc;
- struct acpi_hest_ia_error_bank *mc_bank;
-
- if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
- return 0;
-
- cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
- if (!cmc->enabled)
- return 0;
-
- /*
- * We expect HEST to provide a list of MC banks that report errors
- * in firmware first mode. Otherwise, return non-zero value to
- * indicate that we are done parsing HEST.
- */
- if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) || !cmc->num_hardware_banks)
- return 1;
-
- pr_info(HEST_PFX "Enabling Firmware First mode for corrected errors.\n");
-
- mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
- for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
- mce_disable_bank(mc_bank->bank_number);
-#endif
- return 1;
+ return arch_apei_enable_cmcff(hest_hdr, data);
}
struct ghes_arr {
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 0d7116f34b95..48bcf38a0ea8 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -534,6 +534,20 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
" invalid.\n");
}
+ /*
+ * When fully charged, some batteries wrongly report
+ * capacity_now = design_capacity instead of = full_charge_capacity
+ */
+ if (battery->capacity_now > battery->full_charge_capacity
+ && battery->full_charge_capacity != ACPI_BATTERY_VALUE_UNKNOWN) {
+ battery->capacity_now = battery->full_charge_capacity;
+ if (battery->capacity_now != battery->design_capacity)
+ printk_once(KERN_WARNING FW_BUG
+ "battery: reported current charge level (%d) "
+ "is higher than reported maximum charge level (%d).\n",
+ battery->capacity_now, battery->full_charge_capacity);
+ }
+
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
&& battery->capacity_now >= 0 && battery->capacity_now <= 100)
battery->capacity_now = (battery->capacity_now *
@@ -1151,6 +1165,28 @@ static struct dmi_system_id bat_dmi_table[] = {
{},
};
+/*
+ * Some machines'(E,G Lenovo Z480) ECs are not stable
+ * during boot up and this causes battery driver fails to be
+ * probed due to failure of getting battery information
+ * from EC sometimes. After several retries, the operation
+ * may work. So add retry code here and 20ms sleep between
+ * every retries.
+ */
+static int acpi_battery_update_retry(struct acpi_battery *battery)
+{
+ int retry, ret;
+
+ for (retry = 5; retry; retry--) {
+ ret = acpi_battery_update(battery, false);
+ if (!ret)
+ break;
+
+ msleep(20);
+ }
+ return ret;
+}
+
static int acpi_battery_add(struct acpi_device *device)
{
int result = 0;
@@ -1169,9 +1205,11 @@ static int acpi_battery_add(struct acpi_device *device)
mutex_init(&battery->sysfs_lock);
if (acpi_has_method(battery->device->handle, "_BIX"))
set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
- result = acpi_battery_update(battery, false);
+
+ result = acpi_battery_update_retry(battery);
if (result)
goto fail;
+
#ifdef CONFIG_ACPI_PROCFS_POWER
result = acpi_battery_add_fs(device);
#endif
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 3d8413d02a97..36eb42e3b0bb 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -247,75 +247,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
},
/*
- * The following machines have broken backlight support when reporting
- * the Windows 2012 OSI, so disable it until their support is fixed.
+ * These machines will power on immediately after shutdown when
+ * reporting the Windows 2012 OSI.
*/
{
.callback = dmi_disable_osi_win8,
- .ident = "ASUS Zenbook Prime UX31A",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
- DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "ThinkPad Edge E530",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "ThinkPad Edge E530",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "ThinkPad Edge E530",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Acer Aspire V5-573G",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "Acer Aspire V5-572G",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "ThinkPad T431s",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
- .ident = "ThinkPad T430",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
- },
- },
- {
- .callback = dmi_disable_osi_win8,
.ident = "Dell Inspiron 7737",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c5bc8cfe09fa..8581f5b84f48 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -477,9 +477,6 @@ static int __init acpi_bus_init_irq(void)
return 0;
}
-u8 acpi_gbl_permanent_mmap;
-
-
void __init acpi_early_init(void)
{
acpi_status status;
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index db35594d4df7..6d5d1832a588 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev);
static int acpi_button_resume(struct device *dev);
#else
+#define acpi_button_suspend NULL
#define acpi_button_resume NULL
#endif
-static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);
+static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
static struct acpi_driver acpi_button_driver = {
.name = "button",
@@ -102,6 +104,7 @@ struct acpi_button {
struct input_dev *input;
char phys[32]; /* for input device */
unsigned long pushed;
+ bool suspended;
};
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device);
} else {
- int keycode = test_bit(KEY_SLEEP, input->keybit) ?
- KEY_SLEEP : KEY_POWER;
+ int keycode;
+
+ pm_wakeup_event(&device->dev, 0);
+ if (button->suspended)
+ break;
+ keycode = test_bit(KEY_SLEEP, input->keybit) ?
+ KEY_SLEEP : KEY_POWER;
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
- pm_wakeup_event(&device->dev, 0);
acpi_bus_generate_netlink_event(
device->pnp.device_class,
dev_name(&device->dev),
@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
}
#ifdef CONFIG_PM_SLEEP
+static int acpi_button_suspend(struct device *dev)
+{
+ struct acpi_device *device = to_acpi_device(dev);
+ struct acpi_button *button = acpi_driver_data(device);
+
+ button->suspended = true;
+ return 0;
+}
+
static int acpi_button_resume(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
+ button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(device);
return 0;
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 49a51277f81d..67075f800e34 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -367,29 +367,61 @@ EXPORT_SYMBOL(acpi_bus_power_manageable);
#ifdef CONFIG_PM
static DEFINE_MUTEX(acpi_pm_notifier_lock);
+static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
+{
+ struct acpi_device *adev;
+
+ if (val != ACPI_NOTIFY_DEVICE_WAKE)
+ return;
+
+ adev = acpi_bus_get_acpi_device(handle);
+ if (!adev)
+ return;
+
+ mutex_lock(&acpi_pm_notifier_lock);
+
+ if (adev->wakeup.flags.notifier_present) {
+ __pm_wakeup_event(adev->wakeup.ws, 0);
+ if (adev->wakeup.context.work.func)
+ queue_pm_work(&adev->wakeup.context.work);
+ }
+
+ mutex_unlock(&acpi_pm_notifier_lock);
+
+ acpi_bus_put_acpi_device(adev);
+}
+
/**
- * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
- * @adev: ACPI device to add the notifier for.
- * @context: Context information to pass to the notifier routine.
+ * acpi_add_pm_notifier - Register PM notify handler for given ACPI device.
+ * @adev: ACPI device to add the notify handler for.
+ * @dev: Device to generate a wakeup event for while handling the notification.
+ * @work_func: Work function to execute when handling the notification.
*
* NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
* PM wakeup events. For example, wakeup events may be generated for bridges
* if one of the devices below the bridge is signaling wakeup, even if the
* bridge itself doesn't have a wakeup GPE associated with it.
*/
-acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
- acpi_notify_handler handler, void *context)
+acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
+ void (*work_func)(struct work_struct *work))
{
acpi_status status = AE_ALREADY_EXISTS;
+ if (!dev && !work_func)
+ return AE_BAD_PARAMETER;
+
mutex_lock(&acpi_pm_notifier_lock);
if (adev->wakeup.flags.notifier_present)
goto out;
- status = acpi_install_notify_handler(adev->handle,
- ACPI_SYSTEM_NOTIFY,
- handler, context);
+ adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev));
+ adev->wakeup.context.dev = dev;
+ if (work_func)
+ INIT_WORK(&adev->wakeup.context.work, work_func);
+
+ status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY,
+ acpi_pm_notify_handler, NULL);
if (ACPI_FAILURE(status))
goto out;
@@ -404,8 +436,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
* acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
* @adev: ACPI device to remove the notifier from.
*/
-acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
- acpi_notify_handler handler)
+acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
{
acpi_status status = AE_BAD_PARAMETER;
@@ -416,10 +447,17 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
status = acpi_remove_notify_handler(adev->handle,
ACPI_SYSTEM_NOTIFY,
- handler);
+ acpi_pm_notify_handler);
if (ACPI_FAILURE(status))
goto out;
+ if (adev->wakeup.context.work.func) {
+ cancel_work_sync(&adev->wakeup.context.work);
+ adev->wakeup.context.work.func = NULL;
+ }
+ adev->wakeup.context.dev = NULL;
+ wakeup_source_unregister(adev->wakeup.ws);
+
adev->wakeup.flags.notifier_present = false;
out:
@@ -558,7 +596,6 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
*/
int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
{
- acpi_handle handle = ACPI_HANDLE(dev);
struct acpi_device *adev;
int ret, d_min, d_max;
@@ -573,8 +610,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
d_max_in = ACPI_STATE_D3_HOT;
}
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+ adev = ACPI_COMPANION(dev);
+ if (!adev) {
+ dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
return -ENODEV;
}
@@ -600,26 +638,25 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
}
EXPORT_SYMBOL(acpi_pm_device_sleep_state);
-#ifdef CONFIG_PM_RUNTIME
/**
- * acpi_wakeup_device - Wakeup notification handler for ACPI devices.
- * @handle: ACPI handle of the device the notification is for.
- * @event: Type of the signaled event.
- * @context: Device corresponding to @handle.
+ * acpi_pm_notify_work_func - ACPI devices wakeup notification work function.
+ * @work: Work item to handle.
*/
-static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
+static void acpi_pm_notify_work_func(struct work_struct *work)
{
- struct device *dev = context;
+ struct device *dev;
- if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) {
+ dev = container_of(work, struct acpi_device_wakeup_context, work)->dev;
+ if (dev) {
pm_wakeup_event(dev, 0);
pm_runtime_resume(dev);
}
}
/**
- * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device.
- * @adev: ACPI device to enable/disable the remote wakeup for.
+ * acpi_device_wakeup - Enable/disable wakeup functionality for device.
+ * @adev: ACPI device to enable/disable wakeup functionality for.
+ * @target_state: State the system is transitioning into.
* @enable: Whether to enable or disable the wakeup functionality.
*
* Enable/disable the GPE associated with @adev so that it can generate
@@ -629,7 +666,8 @@ static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context)
* Callers must ensure that @adev is a valid ACPI device node before executing
* this function.
*/
-int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
+static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state,
+ bool enable)
{
struct acpi_device_wakeup *wakeup = &adev->wakeup;
@@ -637,7 +675,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
acpi_status res;
int error;
- error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0);
+ error = acpi_enable_wakeup_device_power(adev, target_state);
if (error)
return error;
@@ -653,6 +691,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
return 0;
}
+#ifdef CONFIG_PM_RUNTIME
/**
* acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
* @dev: Device to enable/disable the platform to wake up.
@@ -661,63 +700,42 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable)
int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
{
struct acpi_device *adev;
- acpi_handle handle;
if (!device_run_wake(phys_dev))
return -EINVAL;
- handle = ACPI_HANDLE(phys_dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_dbg(phys_dev, "ACPI handle without context in %s!\n",
- __func__);
+ adev = ACPI_COMPANION(phys_dev);
+ if (!adev) {
+ dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
return -ENODEV;
}
- return __acpi_device_run_wake(adev, enable);
+ return acpi_device_wakeup(adev, enable, ACPI_STATE_S0);
}
EXPORT_SYMBOL(acpi_pm_device_run_wake);
-#else
-static inline void acpi_wakeup_device(acpi_handle handle, u32 event,
- void *context) {}
#endif /* CONFIG_PM_RUNTIME */
#ifdef CONFIG_PM_SLEEP
/**
- * __acpi_device_sleep_wake - Enable or disable device to wake up the system.
- * @dev: Device to enable/desible to wake up the system.
- * @target_state: System state the device is supposed to wake up from.
- * @enable: Whether to enable or disable @dev to wake up the system.
- */
-int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state,
- bool enable)
-{
- return enable ?
- acpi_enable_wakeup_device_power(adev, target_state) :
- acpi_disable_wakeup_device_power(adev);
-}
-
-/**
* acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
* @dev: Device to enable/desible to wake up the system from sleep states.
* @enable: Whether to enable or disable @dev to wake up the system.
*/
int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
{
- acpi_handle handle;
struct acpi_device *adev;
int error;
if (!device_can_wakeup(dev))
return -EINVAL;
- handle = ACPI_HANDLE(dev);
- if (!handle || acpi_bus_get_device(handle, &adev)) {
- dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
+ adev = ACPI_COMPANION(dev);
+ if (!adev) {
+ dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
return -ENODEV;
}
- error = __acpi_device_sleep_wake(adev, acpi_target_system_state(),
- enable);
+ error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
if (!error)
dev_info(dev, "System wakeup %s by ACPI\n",
enable ? "enabled" : "disabled");
@@ -775,13 +793,13 @@ int acpi_dev_runtime_suspend(struct device *dev)
remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) >
PM_QOS_FLAGS_NONE;
- error = __acpi_device_run_wake(adev, remote_wakeup);
+ error = acpi_device_wakeup(adev, ACPI_STATE_S0, remote_wakeup);
if (remote_wakeup && error)
return -EAGAIN;
error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
if (error)
- __acpi_device_run_wake(adev, false);
+ acpi_device_wakeup(adev, ACPI_STATE_S0, false);
return error;
}
@@ -804,7 +822,7 @@ int acpi_dev_runtime_resume(struct device *dev)
return 0;
error = acpi_dev_pm_full_power(adev);
- __acpi_device_run_wake(adev, false);
+ acpi_device_wakeup(adev, ACPI_STATE_S0, false);
return error;
}
EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -860,13 +878,13 @@ int acpi_dev_suspend_late(struct device *dev)
target_state = acpi_target_system_state();
wakeup = device_may_wakeup(dev);
- error = __acpi_device_sleep_wake(adev, target_state, wakeup);
+ error = acpi_device_wakeup(adev, target_state, wakeup);
if (wakeup && error)
return error;
error = acpi_dev_pm_low_power(dev, adev, target_state);
if (error)
- __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+ acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false);
return error;
}
@@ -889,7 +907,7 @@ int acpi_dev_resume_early(struct device *dev)
return 0;
error = acpi_dev_pm_full_power(adev);
- __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false);
+ acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false);
return error;
}
EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
@@ -1048,11 +1066,11 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
if (dev->pm_domain)
return -EEXIST;
- acpi_add_pm_notifier(adev, acpi_wakeup_device, dev);
+ acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func);
dev->pm_domain = &acpi_general_pm_domain;
if (power_on) {
acpi_dev_pm_full_power(adev);
- __acpi_device_run_wake(adev, false);
+ acpi_device_wakeup(adev, ACPI_STATE_S0, false);
}
return 0;
}
@@ -1076,7 +1094,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
if (adev && dev->pm_domain == &acpi_general_pm_domain) {
dev->pm_domain = NULL;
- acpi_remove_pm_notifier(adev, acpi_wakeup_device);
+ acpi_remove_pm_notifier(adev);
if (power_off) {
/*
* If the device's PM QoS resume latency limit or flags
@@ -1086,7 +1104,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off)
*/
dev_pm_qos_hide_latency_limit(dev);
dev_pm_qos_hide_flags(dev);
- __acpi_device_run_wake(adev, false);
+ acpi_device_wakeup(adev, ACPI_STATE_S0, false);
acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0);
}
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ad11ba4a412d..a66ab658abbc 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1,11 +1,14 @@
/*
- * ec.c - ACPI Embedded Controller Driver (v2.1)
+ * ec.c - ACPI Embedded Controller Driver (v2.2)
*
- * Copyright (C) 2006-2008 Alexey Starikovskiy <astarikovskiy@suse.de>
- * Copyright (C) 2006 Denis Sadykov <denis.m.sadykov@intel.com>
- * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
- * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2001-2014 Intel Corporation
+ * Author: 2014 Lv Zheng <lv.zheng@intel.com>
+ * 2006, 2007 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ * 2006 Denis Sadykov <denis.m.sadykov@intel.com>
+ * 2004 Luming Yu <luming.yu@intel.com>
+ * 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ * 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2008 Alexey Starikovskiy <astarikovskiy@suse.de>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -52,6 +55,7 @@
/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
+#define ACPI_EC_FLAG_CMD 0x08 /* Input buffer contains a command */
#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
@@ -78,6 +82,9 @@ enum {
EC_FLAGS_BLOCKED, /* Transactions are blocked */
};
+#define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */
+#define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */
+
/* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
module_param(ec_delay, uint, 0644);
@@ -109,7 +116,7 @@ struct transaction {
u8 ri;
u8 wlen;
u8 rlen;
- bool done;
+ u8 flags;
};
struct acpi_ec *boot_ec, *first_ec;
@@ -127,83 +134,104 @@ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
{
u8 x = inb(ec->command_addr);
- pr_debug("---> status = 0x%2.2x\n", x);
+ pr_debug("EC_SC(R) = 0x%2.2x "
+ "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n",
+ x,
+ !!(x & ACPI_EC_FLAG_SCI),
+ !!(x & ACPI_EC_FLAG_BURST),
+ !!(x & ACPI_EC_FLAG_CMD),
+ !!(x & ACPI_EC_FLAG_IBF),
+ !!(x & ACPI_EC_FLAG_OBF));
return x;
}
static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
{
u8 x = inb(ec->data_addr);
- pr_debug("---> data = 0x%2.2x\n", x);
+ pr_debug("EC_DATA(R) = 0x%2.2x\n", x);
return x;
}
static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
{
- pr_debug("<--- command = 0x%2.2x\n", command);
+ pr_debug("EC_SC(W) = 0x%2.2x\n", command);
outb(command, ec->command_addr);
}
static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
{
- pr_debug("<--- data = 0x%2.2x\n", data);
+ pr_debug("EC_DATA(W) = 0x%2.2x\n", data);
outb(data, ec->data_addr);
}
-static int ec_transaction_done(struct acpi_ec *ec)
+static int ec_transaction_completed(struct acpi_ec *ec)
{
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&ec->lock, flags);
- if (!ec->curr || ec->curr->done)
+ if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
ret = 1;
spin_unlock_irqrestore(&ec->lock, flags);
return ret;
}
-static void start_transaction(struct acpi_ec *ec)
+static bool advance_transaction(struct acpi_ec *ec)
{
- ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
- ec->curr->done = false;
- acpi_ec_write_cmd(ec, ec->curr->command);
-}
-
-static void advance_transaction(struct acpi_ec *ec, u8 status)
-{
- unsigned long flags;
struct transaction *t;
+ u8 status;
+ bool wakeup = false;
- spin_lock_irqsave(&ec->lock, flags);
+ pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK");
+ status = acpi_ec_read_status(ec);
t = ec->curr;
if (!t)
- goto unlock;
- if (t->wlen > t->wi) {
- if ((status & ACPI_EC_FLAG_IBF) == 0)
- acpi_ec_write_data(ec,
- t->wdata[t->wi++]);
- else
- goto err;
- } else if (t->rlen > t->ri) {
- if ((status & ACPI_EC_FLAG_OBF) == 1) {
- t->rdata[t->ri++] = acpi_ec_read_data(ec);
- if (t->rlen == t->ri)
- t->done = true;
+ goto err;
+ if (t->flags & ACPI_EC_COMMAND_POLL) {
+ if (t->wlen > t->wi) {
+ if ((status & ACPI_EC_FLAG_IBF) == 0)
+ acpi_ec_write_data(ec, t->wdata[t->wi++]);
+ else
+ goto err;
+ } else if (t->rlen > t->ri) {
+ if ((status & ACPI_EC_FLAG_OBF) == 1) {
+ t->rdata[t->ri++] = acpi_ec_read_data(ec);
+ if (t->rlen == t->ri) {
+ t->flags |= ACPI_EC_COMMAND_COMPLETE;
+ wakeup = true;
+ }
+ } else
+ goto err;
+ } else if (t->wlen == t->wi &&
+ (status & ACPI_EC_FLAG_IBF) == 0) {
+ t->flags |= ACPI_EC_COMMAND_COMPLETE;
+ wakeup = true;
+ }
+ return wakeup;
+ } else {
+ if ((status & ACPI_EC_FLAG_IBF) == 0) {
+ acpi_ec_write_cmd(ec, t->command);
+ t->flags |= ACPI_EC_COMMAND_POLL;
} else
goto err;
- } else if (t->wlen == t->wi &&
- (status & ACPI_EC_FLAG_IBF) == 0)
- t->done = true;
- goto unlock;
+ return wakeup;
+ }
err:
/*
* If SCI bit is set, then don't think it's a false IRQ
* otherwise will take a not handled IRQ as a false one.
*/
- if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
- ++t->irq_count;
+ if (!(status & ACPI_EC_FLAG_SCI)) {
+ if (in_interrupt() && t)
+ ++t->irq_count;
+ }
+ return wakeup;
+}
-unlock:
- spin_unlock_irqrestore(&ec->lock, flags);
+static void start_transaction(struct acpi_ec *ec)
+{
+ ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
+ ec->curr->flags = 0;
+ (void)advance_transaction(ec);
}
static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
@@ -228,15 +256,17 @@ static int ec_poll(struct acpi_ec *ec)
/* don't sleep with disabled interrupts */
if (EC_FLAGS_MSI || irqs_disabled()) {
udelay(ACPI_EC_MSI_UDELAY);
- if (ec_transaction_done(ec))
+ if (ec_transaction_completed(ec))
return 0;
} else {
if (wait_event_timeout(ec->wait,
- ec_transaction_done(ec),
+ ec_transaction_completed(ec),
msecs_to_jiffies(1)))
return 0;
}
- advance_transaction(ec, acpi_ec_read_status(ec));
+ spin_lock_irqsave(&ec->lock, flags);
+ (void)advance_transaction(ec);
+ spin_unlock_irqrestore(&ec->lock, flags);
} while (time_before(jiffies, delay));
pr_debug("controller reset, restart transaction\n");
spin_lock_irqsave(&ec->lock, flags);
@@ -268,23 +298,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
return ret;
}
-static int ec_check_ibf0(struct acpi_ec *ec)
-{
- u8 status = acpi_ec_read_status(ec);
- return (status & ACPI_EC_FLAG_IBF) == 0;
-}
-
-static int ec_wait_ibf0(struct acpi_ec *ec)
-{
- unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
- /* interrupt wait manually if GPE mode is not active */
- while (time_before(jiffies, delay))
- if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
- msecs_to_jiffies(1)))
- return 0;
- return -ETIME;
-}
-
static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
{
int status;
@@ -305,12 +318,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
goto unlock;
}
}
- if (ec_wait_ibf0(ec)) {
- pr_err("input buffer is not empty, "
- "aborting transaction\n");
- status = -ETIME;
- goto end;
- }
pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n",
t->command, t->wdata ? t->wdata[0] : 0);
/* disable GPE during transaction if storm is detected */
@@ -334,7 +341,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
}
pr_debug("transaction end\n");
-end:
if (ec->global_lock)
acpi_release_global_lock(glk);
unlock:
@@ -634,17 +640,14 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
u32 gpe_number, void *data)
{
+ unsigned long flags;
struct acpi_ec *ec = data;
- u8 status = acpi_ec_read_status(ec);
- pr_debug("~~~> interrupt, status:0x%02x\n", status);
-
- advance_transaction(ec, status);
- if (ec_transaction_done(ec) &&
- (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
+ spin_lock_irqsave(&ec->lock, flags);
+ if (advance_transaction(ec))
wake_up(&ec->wait);
- ec_check_sci(ec, acpi_ec_read_status(ec));
- }
+ spin_unlock_irqrestore(&ec->lock, flags);
+ ec_check_sci(ec, acpi_ec_read_status(ec));
return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
}
@@ -1066,8 +1069,10 @@ int __init acpi_ec_ecdt_probe(void)
/* fall through */
}
- if (EC_FLAGS_SKIP_DSDT_SCAN)
+ if (EC_FLAGS_SKIP_DSDT_SCAN) {
+ kfree(saved_ec);
return -ENODEV;
+ }
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
@@ -1105,6 +1110,7 @@ install:
}
error:
kfree(boot_ec);
+ kfree(saved_ec);
boot_ec = NULL;
return -ENODEV;
}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 7de5b603f272..4c5cf77e7576 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
int type, unsigned long long sta);
void acpi_device_add_finalize(struct acpi_device *device);
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
-int acpi_bind_one(struct device *dev, struct acpi_device *adev);
-int acpi_unbind_one(struct device *dev);
bool acpi_device_is_present(struct acpi_device *adev);
bool acpi_device_is_battery(struct acpi_device *adev);
@@ -108,7 +106,12 @@ int acpi_power_transition(struct acpi_device *device, int state);
int acpi_device_update_power(struct acpi_device *device, int *state_p);
int acpi_wakeup_device_init(void);
+
+#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
void acpi_early_processor_set_pdc(void);
+#else
+static inline void acpi_early_processor_set_pdc(void) {}
+#endif
/* --------------------------------------------------------------------------
Embedded Controller
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index bad25b070fe0..3abe9b223ba7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -259,12 +259,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
"System description tables not found\n");
return 0;
}
- } else {
+ } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
acpi_physical_address pa = 0;
acpi_find_root_pointer(&pa);
return pa;
}
+
+ return 0;
}
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d388f13d48b4..e6ae603ed1a1 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (no_aspm)
pcie_no_aspm();
- pci_acpi_add_bus_pm_notifier(device, root->bus);
+ pci_acpi_add_bus_pm_notifier(device);
if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 71e2065639a6..e32321ce9a5c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -4,17 +4,11 @@
*
* Alex Chiang <achiang@hp.com>
* - Unified x86/ia64 implementations
- * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
- * - Added _PDC for platforms with Intel CPUs
*/
#include <linux/export.h>
-#include <linux/dmi.h>
-#include <linux/slab.h>
#include <linux/acpi.h>
#include <acpi/processor.h>
-#include "internal.h"
-
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_core");
@@ -135,6 +129,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
map_lapic_id(header, acpi_id, &apic_id);
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
map_lsapic_id(header, type, acpi_id, &apic_id);
+ } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+ map_x2apic_id(header, type, acpi_id, &apic_id);
}
exit:
@@ -208,195 +204,3 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
return acpi_map_cpuid(apic_id, acpi_id);
}
EXPORT_SYMBOL_GPL(acpi_get_cpuid);
-
-static bool __init processor_physically_present(acpi_handle handle)
-{
- int cpuid, type;
- u32 acpi_id;
- acpi_status status;
- acpi_object_type acpi_type;
- unsigned long long tmp;
- union acpi_object object = { 0 };
- struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
-
- status = acpi_get_type(handle, &acpi_type);
- if (ACPI_FAILURE(status))
- return false;
-
- switch (acpi_type) {
- case ACPI_TYPE_PROCESSOR:
- status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
- if (ACPI_FAILURE(status))
- return false;
- acpi_id = object.processor.proc_id;
- break;
- case ACPI_TYPE_DEVICE:
- status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
- if (ACPI_FAILURE(status))
- return false;
- acpi_id = tmp;
- break;
- default:
- return false;
- }
-
- type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
- cpuid = acpi_get_cpuid(handle, type, acpi_id);
-
- if (cpuid == -1)
- return false;
-
- return true;
-}
-
-static void acpi_set_pdc_bits(u32 *buf)
-{
- buf[0] = ACPI_PDC_REVISION_ID;
- buf[1] = 1;
-
- /* Enable coordination with firmware's _TSD info */
- buf[2] = ACPI_PDC_SMP_T_SWCOORD;
-
- /* Twiddle arch-specific bits needed for _PDC */
- arch_acpi_set_pdc_bits(buf);
-}
-
-static struct acpi_object_list *acpi_processor_alloc_pdc(void)
-{
- struct acpi_object_list *obj_list;
- union acpi_object *obj;
- u32 *buf;
-
- /* allocate and initialize pdc. It will be used later. */
- obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
- if (!obj_list) {
- printk(KERN_ERR "Memory allocation error\n");
- return NULL;
- }
-
- obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
- if (!obj) {
- printk(KERN_ERR "Memory allocation error\n");
- kfree(obj_list);
- return NULL;
- }
-
- buf = kmalloc(12, GFP_KERNEL);
- if (!buf) {
- printk(KERN_ERR "Memory allocation error\n");
- kfree(obj);
- kfree(obj_list);
- return NULL;
- }
-
- acpi_set_pdc_bits(buf);
-
- obj->type = ACPI_TYPE_BUFFER;
- obj->buffer.length = 12;
- obj->buffer.pointer = (u8 *) buf;
- obj_list->count = 1;
- obj_list->pointer = obj;
-
- return obj_list;
-}
-
-/*
- * _PDC is required for a BIOS-OS handshake for most of the newer
- * ACPI processor features.
- */
-static acpi_status
-acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
-{
- acpi_status status = AE_OK;
-
- if (boot_option_idle_override == IDLE_NOMWAIT) {
- /*
- * If mwait is disabled for CPU C-states, the C2C3_FFH access
- * mode will be disabled in the parameter of _PDC object.
- * Of course C1_FFH access mode will also be disabled.
- */
- union acpi_object *obj;
- u32 *buffer = NULL;
-
- obj = pdc_in->pointer;
- buffer = (u32 *)(obj->buffer.pointer);
- buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
-
- }
- status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
-
- if (ACPI_FAILURE(status))
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Could not evaluate _PDC, using legacy perf. control.\n"));
-
- return status;
-}
-
-void acpi_processor_set_pdc(acpi_handle handle)
-{
- struct acpi_object_list *obj_list;
-
- if (arch_has_acpi_pdc() == false)
- return;
-
- obj_list = acpi_processor_alloc_pdc();
- if (!obj_list)
- return;
-
- acpi_processor_eval_pdc(handle, obj_list);
-
- kfree(obj_list->pointer->buffer.pointer);
- kfree(obj_list->pointer);
- kfree(obj_list);
-}
-
-static acpi_status __init
-early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
- if (processor_physically_present(handle) == false)
- return AE_OK;
-
- acpi_processor_set_pdc(handle);
- return AE_OK;
-}
-
-#if defined(CONFIG_X86) || defined(CONFIG_IA64)
-static int __init set_no_mwait(const struct dmi_system_id *id)
-{
- pr_notice(PREFIX "%s detected - disabling mwait for CPU C-states\n",
- id->ident);
- boot_option_idle_override = IDLE_NOMWAIT;
- return 0;
-}
-
-static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
- {
- set_no_mwait, "Extensa 5220", {
- DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
- DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
- DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
- {},
-};
-
-static void __init processor_dmi_check(void)
-{
- /*
- * Check whether the system is DMI table. If yes, OSPM
- * should not use mwait for CPU-states.
- */
- dmi_check_system(processor_idle_dmi_table);
-}
-#else
-static inline void processor_dmi_check(void) {}
-#endif
-
-void __init acpi_early_processor_set_pdc(void)
-{
- processor_dmi_check();
-
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- early_init_pdc, NULL, NULL, NULL);
- acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
-}
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
new file mode 100644
index 000000000000..e5dd80800930
--- /dev/null
+++ b/drivers/acpi/processor_pdc.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2005 Intel Corporation
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * - Added _PDC for platforms with Intel CPUs
+ */
+
+#define pr_fmt(fmt) "ACPI: " fmt
+
+#include <linux/dmi.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#include "internal.h"
+
+#define _COMPONENT ACPI_PROCESSOR_COMPONENT
+ACPI_MODULE_NAME("processor_pdc");
+
+static bool __init processor_physically_present(acpi_handle handle)
+{
+ int cpuid, type;
+ u32 acpi_id;
+ acpi_status status;
+ acpi_object_type acpi_type;
+ unsigned long long tmp;
+ union acpi_object object = { 0 };
+ struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+
+ status = acpi_get_type(handle, &acpi_type);
+ if (ACPI_FAILURE(status))
+ return false;
+
+ switch (acpi_type) {
+ case ACPI_TYPE_PROCESSOR:
+ status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
+ if (ACPI_FAILURE(status))
+ return false;
+ acpi_id = object.processor.proc_id;
+ break;
+ case ACPI_TYPE_DEVICE:
+ status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
+ if (ACPI_FAILURE(status))
+ return false;
+ acpi_id = tmp;
+ break;
+ default:
+ return false;
+ }
+
+ type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+ cpuid = acpi_get_cpuid(handle, type, acpi_id);
+
+ if (cpuid == -1)
+ return false;
+
+ return true;
+}
+
+static void acpi_set_pdc_bits(u32 *buf)
+{
+ buf[0] = ACPI_PDC_REVISION_ID;
+ buf[1] = 1;
+
+ /* Enable coordination with firmware's _TSD info */
+ buf[2] = ACPI_PDC_SMP_T_SWCOORD;
+
+ /* Twiddle arch-specific bits needed for _PDC */
+ arch_acpi_set_pdc_bits(buf);
+}
+
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
+{
+ struct acpi_object_list *obj_list;
+ union acpi_object *obj;
+ u32 *buf;
+
+ /* allocate and initialize pdc. It will be used later. */
+ obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+ if (!obj_list)
+ goto out;
+
+ obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+ if (!obj) {
+ kfree(obj_list);
+ goto out;
+ }
+
+ buf = kmalloc(12, GFP_KERNEL);
+ if (!buf) {
+ kfree(obj);
+ kfree(obj_list);
+ goto out;
+ }
+
+ acpi_set_pdc_bits(buf);
+
+ obj->type = ACPI_TYPE_BUFFER;
+ obj->buffer.length = 12;
+ obj->buffer.pointer = (u8 *) buf;
+ obj_list->count = 1;
+ obj_list->pointer = obj;
+
+ return obj_list;
+out:
+ pr_err("Memory allocation error\n");
+ return NULL;
+}
+
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+static acpi_status
+acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
+{
+ acpi_status status = AE_OK;
+
+ if (boot_option_idle_override == IDLE_NOMWAIT) {
+ /*
+ * If mwait is disabled for CPU C-states, the C2C3_FFH access
+ * mode will be disabled in the parameter of _PDC object.
+ * Of course C1_FFH access mode will also be disabled.
+ */
+ union acpi_object *obj;
+ u32 *buffer = NULL;
+
+ obj = pdc_in->pointer;
+ buffer = (u32 *)(obj->buffer.pointer);
+ buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
+
+ }
+ status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
+
+ if (ACPI_FAILURE(status))
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Could not evaluate _PDC, using legacy perf. control.\n"));
+
+ return status;
+}
+
+void acpi_processor_set_pdc(acpi_handle handle)
+{
+ struct acpi_object_list *obj_list;
+
+ if (arch_has_acpi_pdc() == false)
+ return;
+
+ obj_list = acpi_processor_alloc_pdc();
+ if (!obj_list)
+ return;
+
+ acpi_processor_eval_pdc(handle, obj_list);
+
+ kfree(obj_list->pointer->buffer.pointer);
+ kfree(obj_list->pointer);
+ kfree(obj_list);
+}
+
+static acpi_status __init
+early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ if (processor_physically_present(handle) == false)
+ return AE_OK;
+
+ acpi_processor_set_pdc(handle);
+ return AE_OK;
+}
+
+static int __init set_no_mwait(const struct dmi_system_id *id)
+{
+ pr_notice("%s detected - disabling mwait for CPU C-states\n",
+ id->ident);
+ boot_option_idle_override = IDLE_NOMWAIT;
+ return 0;
+}
+
+static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
+ {
+ set_no_mwait, "Extensa 5220", {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+ DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
+ {},
+};
+
+static void __init processor_dmi_check(void)
+{
+ /*
+ * Check whether the system is DMI table. If yes, OSPM
+ * should not use mwait for CPU-states.
+ */
+ dmi_check_system(processor_idle_dmi_table);
+}
+
+void __init acpi_early_processor_set_pdc(void)
+{
+ processor_dmi_check();
+
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ early_init_pdc, NULL, NULL, NULL);
+ acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
+}
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index 0bdacc5e26a3..2ba8f02ced36 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -77,7 +77,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
switch (ares->type) {
case ACPI_RESOURCE_TYPE_MEMORY24:
memory24 = &ares->data.memory24;
- if (!memory24->address_length)
+ if (!memory24->minimum && !memory24->address_length)
return false;
acpi_dev_get_memresource(res, memory24->minimum,
memory24->address_length,
@@ -85,7 +85,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
break;
case ACPI_RESOURCE_TYPE_MEMORY32:
memory32 = &ares->data.memory32;
- if (!memory32->address_length)
+ if (!memory32->minimum && !memory32->address_length)
return false;
acpi_dev_get_memresource(res, memory32->minimum,
memory32->address_length,
@@ -93,7 +93,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
fixed_memory32 = &ares->data.fixed_memory32;
- if (!fixed_memory32->address_length)
+ if (!fixed_memory32->address && !fixed_memory32->address_length)
return false;
acpi_dev_get_memresource(res, fixed_memory32->address,
fixed_memory32->address_length,
@@ -150,7 +150,7 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
switch (ares->type) {
case ACPI_RESOURCE_TYPE_IO:
io = &ares->data.io;
- if (!io->address_length)
+ if (!io->minimum && !io->address_length)
return false;
acpi_dev_get_ioresource(res, io->minimum,
io->address_length,
@@ -158,7 +158,7 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
break;
case ACPI_RESOURCE_TYPE_FIXED_IO:
fixed_io = &ares->data.fixed_io;
- if (!fixed_io->address_length)
+ if (!fixed_io->address && !fixed_io->address_length)
return false;
acpi_dev_get_ioresource(res, fixed_io->address,
fixed_io->address_length,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f775fa0d850f..5d592e17d760 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -77,7 +77,9 @@ void acpi_initialize_hp_context(struct acpi_device *adev,
void (*uevent)(struct acpi_device *, u32))
{
acpi_lock_hp_context();
- acpi_set_hp_context(adev, hp, notify, uevent, NULL);
+ hp->notify = notify;
+ hp->uevent = uevent;
+ acpi_set_hp_context(adev, hp);
acpi_unlock_hp_context();
}
EXPORT_SYMBOL_GPL(acpi_initialize_hp_context);
@@ -1421,14 +1423,13 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
wakeup->sleep_state = sleep_state;
}
}
- acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
out:
kfree(buffer.pointer);
return err;
}
-static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
+static void acpi_wakeup_gpe_init(struct acpi_device *device)
{
struct acpi_device_id button_device_ids[] = {
{"PNP0C0C", 0},
@@ -1436,29 +1437,33 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
{"PNP0C0E", 0},
{"", 0},
};
+ struct acpi_device_wakeup *wakeup = &device->wakeup;
acpi_status status;
acpi_event_status event_status;
- device->wakeup.flags.notifier_present = 0;
+ wakeup->flags.notifier_present = 0;
/* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) {
- device->wakeup.flags.run_wake = 1;
+ wakeup->flags.run_wake = 1;
if (!acpi_match_device_ids(device, &button_device_ids[1])) {
/* Do not use Lid/sleep button for S5 wakeup */
- if (device->wakeup.sleep_state == ACPI_STATE_S5)
- device->wakeup.sleep_state = ACPI_STATE_S4;
+ if (wakeup->sleep_state == ACPI_STATE_S5)
+ wakeup->sleep_state = ACPI_STATE_S4;
}
+ acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
device_set_wakeup_capable(&device->dev, true);
return;
}
- status = acpi_get_gpe_status(device->wakeup.gpe_device,
- device->wakeup.gpe_number,
- &event_status);
- if (status == AE_OK)
- device->wakeup.flags.run_wake =
- !!(event_status & ACPI_EVENT_FLAG_HANDLE);
+ acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
+ wakeup->gpe_number);
+ status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
+ &event_status);
+ if (ACPI_FAILURE(status))
+ return;
+
+ wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE);
}
static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
@@ -1478,7 +1483,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
device->wakeup.flags.valid = 1;
device->wakeup.prepare_count = 0;
- acpi_bus_set_run_wake_flags(device);
+ acpi_wakeup_gpe_init(device);
/* Call _PSW/_DSW object to disable its ability to wake the sleeping
* system for the ACPI device with the _PRW object.
* The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index b3e3cc73ba79..54da4a3fe65e 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
static void acpi_sleep_dmi_check(void)
{
+ int year;
+
+ if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
+ acpi_nvs_nosave_s3();
+
dmi_check_system(acpisleep_dmi_table);
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index fb9ffe9adc64..826884392e6b 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -68,7 +68,7 @@ MODULE_AUTHOR("Bruno Ducrot");
MODULE_DESCRIPTION("ACPI Video Driver");
MODULE_LICENSE("GPL");
-static bool brightness_switch_enabled;
+static bool brightness_switch_enabled = 1;
module_param(brightness_switch_enabled, bool, 0644);
/*
@@ -204,6 +204,8 @@ struct acpi_video_device {
struct acpi_video_device_flags flags;
struct acpi_video_device_cap cap;
struct list_head entry;
+ struct delayed_work switch_brightness_work;
+ int switch_brightness_event;
struct acpi_video_bus *video;
struct acpi_device *dev;
struct acpi_video_device_brightness *brightness;
@@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current(
unsigned long long *level, bool raw);
static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event);
-static int acpi_video_switch_brightness(struct acpi_video_device *device,
- int event);
+static void acpi_video_switch_brightness(struct work_struct *work);
static bool acpi_video_use_native_backlight(void)
{
@@ -241,13 +242,14 @@ static bool acpi_video_use_native_backlight(void)
return use_native_backlight_dmi;
}
-static bool acpi_video_verify_backlight_support(void)
+bool acpi_video_verify_backlight_support(void)
{
if (acpi_osi_is_win8() && acpi_video_use_native_backlight() &&
backlight_device_registered(BACKLIGHT_RAW))
return false;
return acpi_video_backlight_support();
}
+EXPORT_SYMBOL_GPL(acpi_video_verify_backlight_support);
/* backlight device sysfs support */
static int acpi_video_get_brightness(struct backlight_device *bd)
@@ -274,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd)
int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd = bl_get_data(bd);
+ cancel_delayed_work(&vd->switch_brightness_work);
return acpi_video_device_lcd_set_level(vd,
vd->brightness->levels[request_level]);
}
@@ -460,6 +463,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
},
{
.callback = video_set_use_native_backlight,
+ .ident = "ThinkPad X230",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
.ident = "ThinkPad T430 and T430s",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -468,10 +479,42 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
},
{
.callback = video_set_use_native_backlight,
- .ident = "ThinkPad X230",
+ .ident = "ThinkPad T430",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
- DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "ThinkPad T431s",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "ThinkPad Edge E530",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "ThinkPad Edge E530",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "ThinkPad Edge E530",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
},
},
{
@@ -563,6 +606,38 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
},
},
{
+ .callback = video_set_use_native_backlight,
+ .ident = "Acer TravelMate B113",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "Acer Aspire V5-572G",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "Acer Aspire V5-573G",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
+ .ident = "ASUS Zenbook Prime UX31A",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
+ },
+ },
+ {
.callback = video_set_use_native_backlight,
.ident = "HP ProBook 4340s",
.matches = {
@@ -572,6 +647,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
},
{
.callback = video_set_use_native_backlight,
+ .ident = "HP ProBook 4540s",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP ProBook 4540s"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
.ident = "HP ProBook 2013 models",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
@@ -590,6 +673,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
},
{
.callback = video_set_use_native_backlight,
+ .ident = "HP EliteBook 2014 models",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "),
+ DMI_MATCH(DMI_PRODUCT_NAME, " G2"),
+ },
+ },
+ {
+ .callback = video_set_use_native_backlight,
.ident = "HP ZBook 14",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
@@ -1171,6 +1263,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
data->device_id = device_id;
data->video = video;
data->dev = device;
+ INIT_DELAYED_WORK(&data->switch_brightness_work,
+ acpi_video_switch_brightness);
attribute = acpi_video_get_device_attr(video, device_id);
@@ -1393,15 +1487,18 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
}
-static int
-acpi_video_switch_brightness(struct acpi_video_device *device, int event)
+static void
+acpi_video_switch_brightness(struct work_struct *work)
{
+ struct acpi_video_device *device = container_of(to_delayed_work(work),
+ struct acpi_video_device, switch_brightness_work);
unsigned long long level_current, level_next;
+ int event = device->switch_brightness_event;
int result = -EINVAL;
/* no warning message if acpi_backlight=vendor or a quirk is used */
if (!acpi_video_verify_backlight_support())
- return 0;
+ return;
if (!device->brightness)
goto out;
@@ -1423,8 +1520,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
out:
if (result)
printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
-
- return result;
}
int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
@@ -1592,6 +1687,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
return;
}
+static void brightness_switch_event(struct acpi_video_device *video_device,
+ u32 event)
+{
+ if (!brightness_switch_enabled)
+ return;
+
+ video_device->switch_brightness_event = event;
+ schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10);
+}
+
static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_video_device *video_device = data;
@@ -1609,28 +1714,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
- if (brightness_switch_enabled)
- acpi_video_switch_brightness(video_device, event);
+ brightness_switch_event(video_device, event);
keycode = KEY_BRIGHTNESS_CYCLE;
break;
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
- if (brightness_switch_enabled)
- acpi_video_switch_brightness(video_device, event);
+ brightness_switch_event(video_device, event);
keycode = KEY_BRIGHTNESSUP;
break;
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
- if (brightness_switch_enabled)
- acpi_video_switch_brightness(video_device, event);
+ brightness_switch_event(video_device, event);
keycode = KEY_BRIGHTNESSDOWN;
break;
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
- if (brightness_switch_enabled)
- acpi_video_switch_brightness(video_device, event);
+ brightness_switch_event(video_device, event);
keycode = KEY_BRIGHTNESS_ZERO;
break;
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
- if (brightness_switch_enabled)
- acpi_video_switch_brightness(video_device, event);
+ brightness_switch_event(video_device, event);
keycode = KEY_DISPLAY_OFF;
break;
default:
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 33e3db548a29..c42feb2bacd0 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -166,6 +166,14 @@ static struct dmi_system_id video_detect_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
},
},
+ {
+ .callback = video_detect_force_vendor,
+ .ident = "Dell Inspiron 5737",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"),
+ },
+ },
{ },
};
diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c
index 558a239954e8..d8961ef4d2e7 100644
--- a/drivers/amba/tegra-ahb.c
+++ b/drivers/amba/tegra-ahb.c
@@ -25,7 +25,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <linux/tegra-ahb.h>
+
+#include <soc/tegra/ahb.h>
#define DRV_NAME "tegra-ahb"
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 7671dbac6015..e1b92788c225 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -16,6 +16,7 @@ menuconfig ATA
depends on BLOCK
depends on !(M32R || M68K || S390) || BROKEN
select SCSI
+ select GLOB
---help---
If you want to use an ATA hard disk, ATA tape drive, ATA CD-ROM or
any other ATA device under Linux, say Y and make sure that you know
@@ -141,6 +142,15 @@ config AHCI_SUNXI
If unsure, say N.
+config AHCI_TEGRA
+ tristate "NVIDIA Tegra124 AHCI SATA support"
+ depends on ARCH_TEGRA
+ help
+ This option enables support for the NVIDIA Tegra124 SoC's
+ onboard AHCI SATA.
+
+ If unsure, say N.
+
config AHCI_XGENE
tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
depends on PHY_XGENE
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 5a02aeecef5b..ae41107afc1f 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o
+obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o
obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o libahci.o libahci_platform.o
# SFF w/ custom DMA
diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c
index 0cd7c7a39e5b..25d0ac32e721 100644
--- a/drivers/ata/acard-ahci.c
+++ b/drivers/ata/acard-ahci.c
@@ -441,7 +441,7 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
/* save initial config */
- ahci_save_initial_config(&pdev->dev, hpriv, 0, 0);
+ ahci_save_initial_config(&pdev->dev, hpriv);
/* prepare host */
if (hpriv->cap & HOST_CAP_NCQ)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index dae5607e1115..a29f8012fb08 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -456,6 +456,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Promise */
{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
+ { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */
/* Asmedia */
{ PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */
@@ -525,8 +526,7 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
"Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
}
- ahci_save_initial_config(&pdev->dev, hpriv, force_port_map,
- mask_port_map);
+ ahci_save_initial_config(&pdev->dev, hpriv);
}
static int ahci_pci_reset_controller(struct ata_host *host)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 05882e4445a6..59ae0ee00149 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -53,7 +53,7 @@
enum {
AHCI_MAX_PORTS = 32,
- AHCI_MAX_CLKS = 3,
+ AHCI_MAX_CLKS = 4,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_MAX_CMDS = 32,
@@ -316,8 +316,12 @@ struct ahci_port_priv {
};
struct ahci_host_priv {
- void __iomem * mmio; /* bus-independent mem map */
+ /* Input fields */
unsigned int flags; /* AHCI_HFLAG_* */
+ u32 force_port_map; /* force port map */
+ u32 mask_port_map; /* mask out particular bits */
+
+ void __iomem * mmio; /* bus-independent mem map */
u32 cap; /* cap to use */
u32 cap2; /* cap2 to use */
u32 port_map; /* port map to use */
@@ -330,7 +334,12 @@ struct ahci_host_priv {
bool got_runtime_pm; /* Did we do pm_runtime_get? */
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
struct regulator *target_pwr; /* Optional */
- struct phy *phy; /* If platform uses phy */
+ /*
+ * If platform uses PHYs. There is a 1:1 relation between the port number and
+ * the PHY position in this array.
+ */
+ struct phy **phys;
+ unsigned nports; /* Number of ports */
void *plat_data; /* Other platform data */
/*
* Optional ahci_start_engine override, if not set this gets set to the
@@ -361,9 +370,7 @@ unsigned int ahci_dev_classify(struct ata_port *ap);
void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
void ahci_save_initial_config(struct device *dev,
- struct ahci_host_priv *hpriv,
- unsigned int force_port_map,
- unsigned int mask_port_map);
+ struct ahci_host_priv *hpriv);
void ahci_init_controller(struct ata_host *host);
int ahci_reset_controller(struct ata_host *host);
@@ -371,7 +378,9 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
int pmp, unsigned long deadline,
int (*check_ready)(struct ata_link *link));
+unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
int ahci_stop_engine(struct ata_port *ap);
+void ahci_start_fis_rx(struct ata_port *ap);
void ahci_start_engine(struct ata_port *ap);
int ahci_check_ready(struct ata_link *link);
int ahci_kick_engine(struct ata_port *ap);
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
index 2b77d53bccf8..ad1e71ec10cf 100644
--- a/drivers/ata/ahci_da850.c
+++ b/drivers/ata/ahci_da850.c
@@ -85,8 +85,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
da850_sata_init(dev, pwrdn_reg, hpriv->mmio);
- rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info,
- 0, 0, 0);
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_da850_port_info);
if (rc)
goto disable_resources;
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 3a901520c62b..f3970b4ed889 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -58,10 +58,13 @@ enum ahci_imx_type {
struct imx_ahci_priv {
struct platform_device *ahci_pdev;
enum ahci_imx_type type;
+ struct clk *sata_clk;
+ struct clk *sata_ref_clk;
struct clk *ahb_clk;
struct regmap *gpr;
bool no_device;
bool first_time;
+ u32 phy_params;
};
static int ahci_imx_hotplug;
@@ -224,7 +227,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
return ret;
}
- ret = ahci_platform_enable_clks(hpriv);
+ ret = clk_prepare_enable(imxpriv->sata_ref_clk);
if (ret < 0)
goto disable_regulator;
@@ -246,14 +249,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
IMX6Q_GPR13_SATA_TX_LVL_MASK |
IMX6Q_GPR13_SATA_MPLL_CLK_EN |
IMX6Q_GPR13_SATA_TX_EDGE_RATE,
- IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB |
- IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
- IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
- IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
- IMX6Q_GPR13_SATA_MPLL_SS_EN |
- IMX6Q_GPR13_SATA_TX_ATTEN_9_16 |
- IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB |
- IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
+ imxpriv->phy_params);
regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
IMX6Q_GPR13_SATA_MPLL_CLK_EN,
IMX6Q_GPR13_SATA_MPLL_CLK_EN);
@@ -263,7 +259,7 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
ret = imx_sata_phy_reset(hpriv);
if (ret) {
dev_err(dev, "failed to reset phy: %d\n", ret);
- goto disable_regulator;
+ goto disable_clk;
}
}
@@ -271,6 +267,8 @@ static int imx_sata_enable(struct ahci_host_priv *hpriv)
return 0;
+disable_clk:
+ clk_disable_unprepare(imxpriv->sata_ref_clk);
disable_regulator:
if (hpriv->target_pwr)
regulator_disable(hpriv->target_pwr);
@@ -291,7 +289,7 @@ static void imx_sata_disable(struct ahci_host_priv *hpriv)
!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
}
- ahci_platform_disable_clks(hpriv);
+ clk_disable_unprepare(imxpriv->sata_ref_clk);
if (hpriv->target_pwr)
regulator_disable(hpriv->target_pwr);
@@ -324,6 +322,9 @@ static void ahci_imx_error_handler(struct ata_port *ap)
writel(reg_val | IMX_P0PHYCR_TEST_PDDQ, mmio + IMX_P0PHYCR);
imx_sata_disable(hpriv);
imxpriv->no_device = true;
+
+ dev_info(ap->dev, "no device found, disabling link.\n");
+ dev_info(ap->dev, "pass " MODULE_PARAM_PREFIX ".hotplug=1 to enable hotplug\n");
}
static int ahci_imx_softreset(struct ata_link *link, unsigned int *class,
@@ -364,6 +365,165 @@ static const struct of_device_id imx_ahci_of_match[] = {
};
MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
+struct reg_value {
+ u32 of_value;
+ u32 reg_value;
+};
+
+struct reg_property {
+ const char *name;
+ const struct reg_value *values;
+ size_t num_values;
+ u32 def_value;
+ u32 set_value;
+};
+
+static const struct reg_value gpr13_tx_level[] = {
+ { 937, IMX6Q_GPR13_SATA_TX_LVL_0_937_V },
+ { 947, IMX6Q_GPR13_SATA_TX_LVL_0_947_V },
+ { 957, IMX6Q_GPR13_SATA_TX_LVL_0_957_V },
+ { 966, IMX6Q_GPR13_SATA_TX_LVL_0_966_V },
+ { 976, IMX6Q_GPR13_SATA_TX_LVL_0_976_V },
+ { 986, IMX6Q_GPR13_SATA_TX_LVL_0_986_V },
+ { 996, IMX6Q_GPR13_SATA_TX_LVL_0_996_V },
+ { 1005, IMX6Q_GPR13_SATA_TX_LVL_1_005_V },
+ { 1015, IMX6Q_GPR13_SATA_TX_LVL_1_015_V },
+ { 1025, IMX6Q_GPR13_SATA_TX_LVL_1_025_V },
+ { 1035, IMX6Q_GPR13_SATA_TX_LVL_1_035_V },
+ { 1045, IMX6Q_GPR13_SATA_TX_LVL_1_045_V },
+ { 1054, IMX6Q_GPR13_SATA_TX_LVL_1_054_V },
+ { 1064, IMX6Q_GPR13_SATA_TX_LVL_1_064_V },
+ { 1074, IMX6Q_GPR13_SATA_TX_LVL_1_074_V },
+ { 1084, IMX6Q_GPR13_SATA_TX_LVL_1_084_V },
+ { 1094, IMX6Q_GPR13_SATA_TX_LVL_1_094_V },
+ { 1104, IMX6Q_GPR13_SATA_TX_LVL_1_104_V },
+ { 1113, IMX6Q_GPR13_SATA_TX_LVL_1_113_V },
+ { 1123, IMX6Q_GPR13_SATA_TX_LVL_1_123_V },
+ { 1133, IMX6Q_GPR13_SATA_TX_LVL_1_133_V },
+ { 1143, IMX6Q_GPR13_SATA_TX_LVL_1_143_V },
+ { 1152, IMX6Q_GPR13_SATA_TX_LVL_1_152_V },
+ { 1162, IMX6Q_GPR13_SATA_TX_LVL_1_162_V },
+ { 1172, IMX6Q_GPR13_SATA_TX_LVL_1_172_V },
+ { 1182, IMX6Q_GPR13_SATA_TX_LVL_1_182_V },
+ { 1191, IMX6Q_GPR13_SATA_TX_LVL_1_191_V },
+ { 1201, IMX6Q_GPR13_SATA_TX_LVL_1_201_V },
+ { 1211, IMX6Q_GPR13_SATA_TX_LVL_1_211_V },
+ { 1221, IMX6Q_GPR13_SATA_TX_LVL_1_221_V },
+ { 1230, IMX6Q_GPR13_SATA_TX_LVL_1_230_V },
+ { 1240, IMX6Q_GPR13_SATA_TX_LVL_1_240_V }
+};
+
+static const struct reg_value gpr13_tx_boost[] = {
+ { 0, IMX6Q_GPR13_SATA_TX_BOOST_0_00_DB },
+ { 370, IMX6Q_GPR13_SATA_TX_BOOST_0_37_DB },
+ { 740, IMX6Q_GPR13_SATA_TX_BOOST_0_74_DB },
+ { 1110, IMX6Q_GPR13_SATA_TX_BOOST_1_11_DB },
+ { 1480, IMX6Q_GPR13_SATA_TX_BOOST_1_48_DB },
+ { 1850, IMX6Q_GPR13_SATA_TX_BOOST_1_85_DB },
+ { 2220, IMX6Q_GPR13_SATA_TX_BOOST_2_22_DB },
+ { 2590, IMX6Q_GPR13_SATA_TX_BOOST_2_59_DB },
+ { 2960, IMX6Q_GPR13_SATA_TX_BOOST_2_96_DB },
+ { 3330, IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB },
+ { 3700, IMX6Q_GPR13_SATA_TX_BOOST_3_70_DB },
+ { 4070, IMX6Q_GPR13_SATA_TX_BOOST_4_07_DB },
+ { 4440, IMX6Q_GPR13_SATA_TX_BOOST_4_44_DB },
+ { 4810, IMX6Q_GPR13_SATA_TX_BOOST_4_81_DB },
+ { 5280, IMX6Q_GPR13_SATA_TX_BOOST_5_28_DB },
+ { 5750, IMX6Q_GPR13_SATA_TX_BOOST_5_75_DB }
+};
+
+static const struct reg_value gpr13_tx_atten[] = {
+ { 8, IMX6Q_GPR13_SATA_TX_ATTEN_8_16 },
+ { 9, IMX6Q_GPR13_SATA_TX_ATTEN_9_16 },
+ { 10, IMX6Q_GPR13_SATA_TX_ATTEN_10_16 },
+ { 12, IMX6Q_GPR13_SATA_TX_ATTEN_12_16 },
+ { 14, IMX6Q_GPR13_SATA_TX_ATTEN_14_16 },
+ { 16, IMX6Q_GPR13_SATA_TX_ATTEN_16_16 },
+};
+
+static const struct reg_value gpr13_rx_eq[] = {
+ { 500, IMX6Q_GPR13_SATA_RX_EQ_VAL_0_5_DB },
+ { 1000, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_0_DB },
+ { 1500, IMX6Q_GPR13_SATA_RX_EQ_VAL_1_5_DB },
+ { 2000, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_0_DB },
+ { 2500, IMX6Q_GPR13_SATA_RX_EQ_VAL_2_5_DB },
+ { 3000, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB },
+ { 3500, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_5_DB },
+ { 4000, IMX6Q_GPR13_SATA_RX_EQ_VAL_4_0_DB },
+};
+
+static const struct reg_property gpr13_props[] = {
+ {
+ .name = "fsl,transmit-level-mV",
+ .values = gpr13_tx_level,
+ .num_values = ARRAY_SIZE(gpr13_tx_level),
+ .def_value = IMX6Q_GPR13_SATA_TX_LVL_1_025_V,
+ }, {
+ .name = "fsl,transmit-boost-mdB",
+ .values = gpr13_tx_boost,
+ .num_values = ARRAY_SIZE(gpr13_tx_boost),
+ .def_value = IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB,
+ }, {
+ .name = "fsl,transmit-atten-16ths",
+ .values = gpr13_tx_atten,
+ .num_values = ARRAY_SIZE(gpr13_tx_atten),
+ .def_value = IMX6Q_GPR13_SATA_TX_ATTEN_9_16,
+ }, {
+ .name = "fsl,receive-eq-mdB",
+ .values = gpr13_rx_eq,
+ .num_values = ARRAY_SIZE(gpr13_rx_eq),
+ .def_value = IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB,
+ }, {
+ .name = "fsl,no-spread-spectrum",
+ .def_value = IMX6Q_GPR13_SATA_MPLL_SS_EN,
+ .set_value = 0,
+ },
+};
+
+static u32 imx_ahci_parse_props(struct device *dev,
+ const struct reg_property *prop, size_t num)
+{
+ struct device_node *np = dev->of_node;
+ u32 reg_value = 0;
+ int i, j;
+
+ for (i = 0; i < num; i++, prop++) {
+ u32 of_val;
+
+ if (prop->num_values == 0) {
+ if (of_property_read_bool(np, prop->name))
+ reg_value |= prop->set_value;
+ else
+ reg_value |= prop->def_value;
+ continue;
+ }
+
+ if (of_property_read_u32(np, prop->name, &of_val)) {
+ dev_info(dev, "%s not specified, using %08x\n",
+ prop->name, prop->def_value);
+ reg_value |= prop->def_value;
+ continue;
+ }
+
+ for (j = 0; j < prop->num_values; j++) {
+ if (prop->values[j].of_value == of_val) {
+ dev_info(dev, "%s value %u, using %08x\n",
+ prop->name, of_val, prop->values[j].reg_value);
+ reg_value |= prop->values[j].reg_value;
+ break;
+ }
+ }
+
+ if (j == prop->num_values) {
+ dev_err(dev, "DT property %s is not a valid value\n",
+ prop->name);
+ reg_value |= prop->def_value;
+ }
+ }
+
+ return reg_value;
+}
+
static int imx_ahci_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -385,6 +545,19 @@ static int imx_ahci_probe(struct platform_device *pdev)
imxpriv->no_device = false;
imxpriv->first_time = true;
imxpriv->type = (enum ahci_imx_type)of_id->data;
+
+ imxpriv->sata_clk = devm_clk_get(dev, "sata");
+ if (IS_ERR(imxpriv->sata_clk)) {
+ dev_err(dev, "can't get sata clock.\n");
+ return PTR_ERR(imxpriv->sata_clk);
+ }
+
+ imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
+ if (IS_ERR(imxpriv->sata_ref_clk)) {
+ dev_err(dev, "can't get sata_ref clock.\n");
+ return PTR_ERR(imxpriv->sata_ref_clk);
+ }
+
imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
if (IS_ERR(imxpriv->ahb_clk)) {
dev_err(dev, "can't get ahb clock.\n");
@@ -392,6 +565,8 @@ static int imx_ahci_probe(struct platform_device *pdev)
}
if (imxpriv->type == AHCI_IMX6Q) {
+ u32 reg_value;
+
imxpriv->gpr = syscon_regmap_lookup_by_compatible(
"fsl,imx6q-iomuxc-gpr");
if (IS_ERR(imxpriv->gpr)) {
@@ -399,6 +574,15 @@ static int imx_ahci_probe(struct platform_device *pdev)
"failed to find fsl,imx6q-iomux-gpr regmap\n");
return PTR_ERR(imxpriv->gpr);
}
+
+ reg_value = imx_ahci_parse_props(dev, gpr13_props,
+ ARRAY_SIZE(gpr13_props));
+
+ imxpriv->phy_params =
+ IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M |
+ IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F |
+ IMX6Q_GPR13_SATA_SPD_MODE_3P0G |
+ reg_value;
}
hpriv = ahci_platform_get_resources(pdev);
@@ -407,10 +591,14 @@ static int imx_ahci_probe(struct platform_device *pdev)
hpriv->plat_data = imxpriv;
- ret = imx_sata_enable(hpriv);
+ ret = clk_prepare_enable(imxpriv->sata_clk);
if (ret)
return ret;
+ ret = imx_sata_enable(hpriv);
+ if (ret)
+ goto disable_clk;
+
/*
* Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
* and IP vendor specific register IMX_TIMER1MS.
@@ -432,19 +620,26 @@ static int imx_ahci_probe(struct platform_device *pdev)
reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
writel(reg_val, hpriv->mmio + IMX_TIMER1MS);
- ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info,
- 0, 0, 0);
+ ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info);
if (ret)
- imx_sata_disable(hpriv);
+ goto disable_sata;
+
+ return 0;
+disable_sata:
+ imx_sata_disable(hpriv);
+disable_clk:
+ clk_disable_unprepare(imxpriv->sata_clk);
return ret;
}
static void ahci_imx_host_stop(struct ata_host *host)
{
struct ahci_host_priv *hpriv = host->private_data;
+ struct imx_ahci_priv *imxpriv = hpriv->plat_data;
imx_sata_disable(hpriv);
+ clk_disable_unprepare(imxpriv->sata_clk);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
index fd3dfd733b84..68672d2692ee 100644
--- a/drivers/ata/ahci_mvebu.c
+++ b/drivers/ata/ahci_mvebu.c
@@ -88,8 +88,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
ahci_mvebu_mbus_config(hpriv, dram);
ahci_mvebu_regret_option(hpriv);
- rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info,
- 0, 0, 0);
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info);
if (rc)
goto disable_resources;
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index ebe505c17763..f61ddb9146d6 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -34,7 +34,6 @@ static int ahci_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ahci_platform_data *pdata = dev_get_platdata(dev);
struct ahci_host_priv *hpriv;
- unsigned long hflags = 0;
int rc;
hpriv = ahci_platform_get_resources(pdev);
@@ -58,10 +57,9 @@ static int ahci_probe(struct platform_device *pdev)
}
if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
- hflags |= AHCI_HFLAG_NO_FBS;
+ hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
- rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info,
- hflags, 0, 0);
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info);
if (rc)
goto pdata_exit;
@@ -78,6 +76,8 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
ahci_platform_resume);
static const struct of_device_id ahci_of_match[] = {
+ { .compatible = "generic-ahci", },
+ /* Keep the following compatibles for device tree compatibility */
{ .compatible = "snps,spear-ahci", },
{ .compatible = "snps,exynos5440-ahci", },
{ .compatible = "ibm,476gtr-ahci", },
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
index 2595598df9ce..835d6eea84fd 100644
--- a/drivers/ata/ahci_st.c
+++ b/drivers/ata/ahci_st.c
@@ -166,7 +166,7 @@ static int st_ahci_probe(struct platform_device *pdev)
if (err)
return err;
- err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info, 0, 0, 0);
+ err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info);
if (err) {
ahci_platform_disable_resources(hpriv);
return err;
@@ -221,7 +221,7 @@ static int st_ahci_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume);
-static struct of_device_id st_ahci_match[] = {
+static const struct of_device_id st_ahci_match[] = {
{ .compatible = "st,ahci", },
{},
};
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
index 02002f125bd4..e44d675a30ec 100644
--- a/drivers/ata/ahci_sunxi.c
+++ b/drivers/ata/ahci_sunxi.c
@@ -167,7 +167,6 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
- unsigned long hflags;
int rc;
hpriv = ahci_platform_get_resources(pdev);
@@ -184,11 +183,10 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
if (rc)
goto disable_resources;
- hflags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
- AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
+ hpriv->flags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
+ AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
- rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info,
- hflags, 0, 0);
+ rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info);
if (rc)
goto disable_resources;
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
new file mode 100644
index 000000000000..fc3df47fca35
--- /dev/null
+++ b/drivers/ata/ahci_tegra.c
@@ -0,0 +1,376 @@
+/*
+ * drivers/ata/ahci_tegra.c
+ *
+ * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Author:
+ * Mikko Perttunen <mperttunen@nvidia.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/ahci_platform.h>
+#include <linux/reset.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/tegra-powergate.h>
+#include <linux/regulator/consumer.h>
+#include "ahci.h"
+
+#define SATA_CONFIGURATION_0 0x180
+#define SATA_CONFIGURATION_EN_FPCI BIT(0)
+
+#define SCFG_OFFSET 0x1000
+
+#define T_SATA0_CFG_1 0x04
+#define T_SATA0_CFG_1_IO_SPACE BIT(0)
+#define T_SATA0_CFG_1_MEMORY_SPACE BIT(1)
+#define T_SATA0_CFG_1_BUS_MASTER BIT(2)
+#define T_SATA0_CFG_1_SERR BIT(8)
+
+#define T_SATA0_CFG_9 0x24
+#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT 13
+
+#define SATA_FPCI_BAR5 0x94
+#define SATA_FPCI_BAR5_START_SHIFT 4
+
+#define SATA_INTR_MASK 0x188
+#define SATA_INTR_MASK_IP_INT_MASK BIT(16)
+
+#define T_SATA0_AHCI_HBA_CAP_BKDR 0x300
+
+#define T_SATA0_BKDOOR_CC 0x4a4
+
+#define T_SATA0_CFG_SATA 0x54c
+#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12)
+
+#define T_SATA0_CFG_MISC 0x550
+
+#define T_SATA0_INDEX 0x680
+
+#define T_SATA0_CHX_PHY_CTRL1_GEN1 0x690
+#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK 0xff
+#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT 0
+#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK (0xff << 8)
+#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT 8
+
+#define T_SATA0_CHX_PHY_CTRL1_GEN2 0x694
+#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK 0xff
+#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT 0
+#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK (0xff << 12)
+#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT 12
+
+#define T_SATA0_CHX_PHY_CTRL2 0x69c
+#define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1 0x23
+
+#define T_SATA0_CHX_PHY_CTRL11 0x6d0
+#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16)
+
+#define FUSE_SATA_CALIB 0x124
+#define FUSE_SATA_CALIB_MASK 0x3
+
+struct sata_pad_calibration {
+ u8 gen1_tx_amp;
+ u8 gen1_tx_peak;
+ u8 gen2_tx_amp;
+ u8 gen2_tx_peak;
+};
+
+static const struct sata_pad_calibration tegra124_pad_calibration[] = {
+ {0x18, 0x04, 0x18, 0x0a},
+ {0x0e, 0x04, 0x14, 0x0a},
+ {0x0e, 0x07, 0x1a, 0x0e},
+ {0x14, 0x0e, 0x1a, 0x0e},
+};
+
+struct tegra_ahci_priv {
+ struct platform_device *pdev;
+ void __iomem *sata_regs;
+ struct reset_control *sata_rst;
+ struct reset_control *sata_oob_rst;
+ struct reset_control *sata_cold_rst;
+ /* Needs special handling, cannot use ahci_platform */
+ struct clk *sata_clk;
+ struct regulator_bulk_data supplies[5];
+};
+
+static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
+{
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(tegra->supplies),
+ tegra->supplies);
+ if (ret)
+ return ret;
+
+ ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
+ tegra->sata_clk,
+ tegra->sata_rst);
+ if (ret)
+ goto disable_regulators;
+
+ reset_control_assert(tegra->sata_oob_rst);
+ reset_control_assert(tegra->sata_cold_rst);
+
+ ret = ahci_platform_enable_resources(hpriv);
+ if (ret)
+ goto disable_power;
+
+ reset_control_deassert(tegra->sata_cold_rst);
+ reset_control_deassert(tegra->sata_oob_rst);
+
+ return 0;
+
+disable_power:
+ clk_disable_unprepare(tegra->sata_clk);
+
+ tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+
+disable_regulators:
+ regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
+
+ return ret;
+}
+
+static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
+{
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+
+ ahci_platform_disable_resources(hpriv);
+
+ reset_control_assert(tegra->sata_rst);
+ reset_control_assert(tegra->sata_oob_rst);
+ reset_control_assert(tegra->sata_cold_rst);
+
+ clk_disable_unprepare(tegra->sata_clk);
+ tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+
+ regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
+}
+
+static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
+{
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+ int ret;
+ unsigned int val;
+ struct sata_pad_calibration calib;
+
+ ret = tegra_ahci_power_on(hpriv);
+ if (ret) {
+ dev_err(&tegra->pdev->dev,
+ "failed to power on AHCI controller: %d\n", ret);
+ return ret;
+ }
+
+ val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
+ val |= SATA_CONFIGURATION_EN_FPCI;
+ writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
+
+ /* Pad calibration */
+
+ /* FIXME Always use calibration 0. Change this to read the calibration
+ * fuse once the fuse driver has landed. */
+ val = 0;
+
+ calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
+
+ writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
+
+ val = readl(tegra->sata_regs +
+ SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
+ val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
+ val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
+ val |= calib.gen1_tx_amp <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+ val |= calib.gen1_tx_peak <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+ writel(val, tegra->sata_regs + SCFG_OFFSET +
+ T_SATA0_CHX_PHY_CTRL1_GEN1);
+
+ val = readl(tegra->sata_regs +
+ SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
+ val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
+ val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
+ val |= calib.gen2_tx_amp <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+ val |= calib.gen2_tx_peak <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+ writel(val, tegra->sata_regs + SCFG_OFFSET +
+ T_SATA0_CHX_PHY_CTRL1_GEN2);
+
+ writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
+ tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
+ writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
+ tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
+
+ writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
+
+ /* Program controller device ID */
+
+ val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+ val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
+ writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+
+ writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
+
+ val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+ val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
+ writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+
+ /* Enable IO & memory access, bus master mode */
+
+ val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
+ val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
+ T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR;
+ writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
+
+ /* Program SATA MMIO */
+
+ writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT,
+ tegra->sata_regs + SATA_FPCI_BAR5);
+
+ writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT,
+ tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
+
+ /* Unmask SATA interrupts */
+
+ val = readl(tegra->sata_regs + SATA_INTR_MASK);
+ val |= SATA_INTR_MASK_IP_INT_MASK;
+ writel(val, tegra->sata_regs + SATA_INTR_MASK);
+
+ return 0;
+}
+
+static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
+{
+ tegra_ahci_power_off(hpriv);
+}
+
+static void tegra_ahci_host_stop(struct ata_host *host)
+{
+ struct ahci_host_priv *hpriv = host->private_data;
+
+ tegra_ahci_controller_deinit(hpriv);
+}
+
+static struct ata_port_operations ahci_tegra_port_ops = {
+ .inherits = &ahci_ops,
+ .host_stop = tegra_ahci_host_stop,
+};
+
+static const struct ata_port_info ahci_tegra_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_tegra_port_ops,
+};
+
+static const struct of_device_id tegra_ahci_of_match[] = {
+ { .compatible = "nvidia,tegra124-ahci" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
+
+static int tegra_ahci_probe(struct platform_device *pdev)
+{
+ struct ahci_host_priv *hpriv;
+ struct tegra_ahci_priv *tegra;
+ struct resource *res;
+ int ret;
+
+ hpriv = ahci_platform_get_resources(pdev);
+ if (IS_ERR(hpriv))
+ return PTR_ERR(hpriv);
+
+ tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
+ if (!tegra)
+ return -ENOMEM;
+
+ hpriv->plat_data = tegra;
+
+ tegra->pdev = pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(tegra->sata_regs))
+ return PTR_ERR(tegra->sata_regs);
+
+ tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
+ if (IS_ERR(tegra->sata_rst)) {
+ dev_err(&pdev->dev, "Failed to get sata reset\n");
+ return PTR_ERR(tegra->sata_rst);
+ }
+
+ tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
+ if (IS_ERR(tegra->sata_oob_rst)) {
+ dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
+ return PTR_ERR(tegra->sata_oob_rst);
+ }
+
+ tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
+ if (IS_ERR(tegra->sata_cold_rst)) {
+ dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
+ return PTR_ERR(tegra->sata_cold_rst);
+ }
+
+ tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
+ if (IS_ERR(tegra->sata_clk)) {
+ dev_err(&pdev->dev, "Failed to get sata clock\n");
+ return PTR_ERR(tegra->sata_clk);
+ }
+
+ tegra->supplies[0].supply = "avdd";
+ tegra->supplies[1].supply = "hvdd";
+ tegra->supplies[2].supply = "vddio";
+ tegra->supplies[3].supply = "target-5v";
+ tegra->supplies[4].supply = "target-12v";
+
+ ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(tegra->supplies),
+ tegra->supplies);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to get regulators\n");
+ return ret;
+ }
+
+ ret = tegra_ahci_controller_init(hpriv);
+ if (ret)
+ return ret;
+
+ ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info);
+ if (ret)
+ goto deinit_controller;
+
+ return 0;
+
+deinit_controller:
+ tegra_ahci_controller_deinit(hpriv);
+
+ return ret;
+};
+
+static struct platform_driver tegra_ahci_driver = {
+ .probe = tegra_ahci_probe,
+ .remove = ata_platform_remove_one,
+ .driver = {
+ .name = "tegra-ahci",
+ .of_match_table = tegra_ahci_of_match,
+ },
+ /* LP0 suspend support not implemented */
+};
+module_platform_driver(tegra_ahci_driver);
+
+MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
+MODULE_DESCRIPTION("Tegra124 AHCI SATA driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 042a9bb45c86..bc281115490b 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -67,6 +67,9 @@
#define PORTAXICFG 0x000000bc
#define PORTAXICFG_OUTTRANS_SET(dst, src) \
(((dst) & ~0x00f00000) | (((u32)(src) << 0x14) & 0x00f00000))
+#define PORTRANSCFG 0x000000c8
+#define PORTRANSCFG_RXWM_SET(dst, src) \
+ (((dst) & ~0x0000007f) | (((u32)(src)) & 0x0000007f))
/* SATA host controller AXI CSR */
#define INT_SLV_TMOMASK 0x00000010
@@ -78,6 +81,7 @@
struct xgene_ahci_context {
struct ahci_host_priv *hpriv;
struct device *dev;
+ u8 last_cmd[MAX_AHCI_CHN_PERCTR]; /* tracking the last command issued*/
void __iomem *csr_core; /* Core CSR address of IP */
void __iomem *csr_diag; /* Diag CSR address of IP */
void __iomem *csr_axi; /* AXI CSR address of IP */
@@ -98,20 +102,62 @@ static int xgene_ahci_init_memram(struct xgene_ahci_context *ctx)
}
/**
+ * xgene_ahci_restart_engine - Restart the dma engine.
+ * @ap : ATA port of interest
+ *
+ * Restarts the dma engine inside the controller.
+ */
+static int xgene_ahci_restart_engine(struct ata_port *ap)
+{
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+
+ ahci_stop_engine(ap);
+ ahci_start_fis_rx(ap);
+ hpriv->start_engine(ap);
+
+ return 0;
+}
+
+/**
+ * xgene_ahci_qc_issue - Issue commands to the device
+ * @qc: Command to issue
+ *
+ * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot
+ * clear the BSY bit after receiving the PIO setup FIS. This results in the dma
+ * state machine goes into the CMFatalErrorUpdate state and locks up. By
+ * restarting the dma engine, it removes the controller out of lock up state.
+ */
+static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct ahci_host_priv *hpriv = ap->host->private_data;
+ struct xgene_ahci_context *ctx = hpriv->plat_data;
+ int rc = 0;
+
+ if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA))
+ xgene_ahci_restart_engine(ap);
+
+ rc = ahci_qc_issue(qc);
+
+ /* Save the last command issued */
+ ctx->last_cmd[ap->port_no] = qc->tf.command;
+
+ return rc;
+}
+
+/**
* xgene_ahci_read_id - Read ID data from the specified device
* @dev: device
* @tf: proposed taskfile
* @id: data buffer
*
* This custom read ID function is required due to the fact that the HW
- * does not support DEVSLP and the controller state machine may get stuck
- * after processing the ID query command.
+ * does not support DEVSLP.
*/
static unsigned int xgene_ahci_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id)
{
u32 err_mask;
- void __iomem *port_mmio = ahci_port_base(dev->link->ap);
err_mask = ata_do_dev_read_id(dev, tf, id);
if (err_mask)
@@ -133,16 +179,6 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev,
*/
id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8);
- /*
- * Due to HW errata, restart the port if no other command active.
- * Otherwise the controller may get stuck.
- */
- if (!readl(port_mmio + PORT_CMD_ISSUE)) {
- writel(PORT_CMD_FIS_RX, port_mmio + PORT_CMD);
- readl(port_mmio + PORT_CMD); /* Force a barrier */
- writel(PORT_CMD_FIS_RX | PORT_CMD_START, port_mmio + PORT_CMD);
- readl(port_mmio + PORT_CMD); /* Force a barrier */
- }
return 0;
}
@@ -160,11 +196,11 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
/* Disable fix rate */
writel(0x0001fffe, mmio + PORTPHY1CFG);
readl(mmio + PORTPHY1CFG); /* Force a barrier */
- writel(0x5018461c, mmio + PORTPHY2CFG);
+ writel(0x28183219, mmio + PORTPHY2CFG);
readl(mmio + PORTPHY2CFG); /* Force a barrier */
- writel(0x1c081907, mmio + PORTPHY3CFG);
+ writel(0x13081008, mmio + PORTPHY3CFG);
readl(mmio + PORTPHY3CFG); /* Force a barrier */
- writel(0x1c080815, mmio + PORTPHY4CFG);
+ writel(0x00480815, mmio + PORTPHY4CFG);
readl(mmio + PORTPHY4CFG); /* Force a barrier */
/* Set window negotiation */
val = readl(mmio + PORTPHY5CFG);
@@ -176,6 +212,10 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
val = PORTAXICFG_OUTTRANS_SET(val, 0xe); /* Set outstanding */
writel(val, mmio + PORTAXICFG);
readl(mmio + PORTAXICFG); /* Force a barrier */
+ /* Set the watermark threshold of the receive FIFO */
+ val = readl(mmio + PORTRANSCFG);
+ val = PORTRANSCFG_RXWM_SET(val, 0x30);
+ writel(val, mmio + PORTRANSCFG);
}
/**
@@ -300,6 +340,7 @@ static struct ata_port_operations xgene_ahci_ops = {
.host_stop = xgene_ahci_host_stop,
.hardreset = xgene_ahci_hardreset,
.read_id = xgene_ahci_read_id,
+ .qc_issue = xgene_ahci_qc_issue,
};
static const struct ata_port_info xgene_ahci_port_info = {
@@ -381,7 +422,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct xgene_ahci_context *ctx;
struct resource *res;
- unsigned long hflags;
int rc;
hpriv = ahci_platform_get_resources(pdev);
@@ -440,20 +480,9 @@ static int xgene_ahci_probe(struct platform_device *pdev)
/* Configure the host controller */
xgene_ahci_hw_init(hpriv);
- /*
- * Setup DMA mask. This is preliminary until the DMA range is sorted
- * out.
- */
- rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
- if (rc) {
- dev_err(dev, "Unable to set dma mask\n");
- goto disable_resources;
- }
-
- hflags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
+ hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ;
- rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info,
- hflags, 0, 0);
+ rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
if (rc)
goto disable_resources;
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 40ea583d3610..b784e9de426a 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -68,7 +68,6 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
-static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
static int ahci_port_start(struct ata_port *ap);
static void ahci_port_stop(struct ata_port *ap);
@@ -383,8 +382,6 @@ static ssize_t ahci_show_em_supported(struct device *dev,
* ahci_save_initial_config - Save and fixup initial config values
* @dev: target AHCI device
* @hpriv: host private area to store config values
- * @force_port_map: force port map to a specified value
- * @mask_port_map: mask out particular bits from port map
*
* Some registers containing configuration info might be setup by
* BIOS and might be cleared on reset. This function saves the
@@ -399,10 +396,7 @@ static ssize_t ahci_show_em_supported(struct device *dev,
* LOCKING:
* None.
*/
-void ahci_save_initial_config(struct device *dev,
- struct ahci_host_priv *hpriv,
- unsigned int force_port_map,
- unsigned int mask_port_map)
+void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
{
void __iomem *mmio = hpriv->mmio;
u32 cap, cap2, vers, port_map;
@@ -469,17 +463,17 @@ void ahci_save_initial_config(struct device *dev,
cap &= ~HOST_CAP_FBS;
}
- if (force_port_map && port_map != force_port_map) {
+ if (hpriv->force_port_map && port_map != hpriv->force_port_map) {
dev_info(dev, "forcing port_map 0x%x -> 0x%x\n",
- port_map, force_port_map);
- port_map = force_port_map;
+ port_map, hpriv->force_port_map);
+ port_map = hpriv->force_port_map;
}
- if (mask_port_map) {
+ if (hpriv->mask_port_map) {
dev_warn(dev, "masking port_map 0x%x -> 0x%x\n",
port_map,
- port_map & mask_port_map);
- port_map &= mask_port_map;
+ port_map & hpriv->mask_port_map);
+ port_map &= hpriv->mask_port_map;
}
/* cross check port_map and cap.n_ports */
@@ -620,7 +614,7 @@ int ahci_stop_engine(struct ata_port *ap)
}
EXPORT_SYMBOL_GPL(ahci_stop_engine);
-static void ahci_start_fis_rx(struct ata_port *ap)
+void ahci_start_fis_rx(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
struct ahci_host_priv *hpriv = ap->host->private_data;
@@ -646,6 +640,7 @@ static void ahci_start_fis_rx(struct ata_port *ap)
/* flush */
readl(port_mmio + PORT_CMD);
}
+EXPORT_SYMBOL_GPL(ahci_start_fis_rx);
static int ahci_stop_fis_rx(struct ata_port *ap)
{
@@ -1945,7 +1940,7 @@ irqreturn_t ahci_interrupt(int irq, void *dev_instance)
}
EXPORT_SYMBOL_GPL(ahci_interrupt);
-static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
+unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
void __iomem *port_mmio = ahci_port_base(ap);
@@ -1974,6 +1969,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
return 0;
}
+EXPORT_SYMBOL_GPL(ahci_qc_issue);
static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
{
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index 3a5b4ed25a4f..5b92c290e6c6 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -39,6 +39,67 @@ static struct scsi_host_template ahci_platform_sht = {
};
/**
+ * ahci_platform_enable_phys - Enable PHYs
+ * @hpriv: host private area to store config values
+ *
+ * This function enables all the PHYs found in hpriv->phys, if any.
+ * If a PHY fails to be enabled, it disables all the PHYs already
+ * enabled in reverse order and returns an error.
+ *
+ * RETURNS:
+ * 0 on success otherwise a negative error code
+ */
+int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
+{
+ int rc, i;
+
+ for (i = 0; i < hpriv->nports; i++) {
+ if (!hpriv->phys[i])
+ continue;
+
+ rc = phy_init(hpriv->phys[i]);
+ if (rc)
+ goto disable_phys;
+
+ rc = phy_power_on(hpriv->phys[i]);
+ if (rc) {
+ phy_exit(hpriv->phys[i]);
+ goto disable_phys;
+ }
+ }
+
+ return 0;
+
+disable_phys:
+ while (--i >= 0) {
+ phy_power_off(hpriv->phys[i]);
+ phy_exit(hpriv->phys[i]);
+ }
+ return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_enable_phys);
+
+/**
+ * ahci_platform_disable_phys - Disable PHYs
+ * @hpriv: host private area to store config values
+ *
+ * This function disables all PHYs found in hpriv->phys.
+ */
+void ahci_platform_disable_phys(struct ahci_host_priv *hpriv)
+{
+ int i;
+
+ for (i = 0; i < hpriv->nports; i++) {
+ if (!hpriv->phys[i])
+ continue;
+
+ phy_power_off(hpriv->phys[i]);
+ phy_exit(hpriv->phys[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(ahci_platform_disable_phys);
+
+/**
* ahci_platform_enable_clks - Enable platform clocks
* @hpriv: host private area to store config values
*
@@ -92,7 +153,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
* following order:
* 1) Regulator
* 2) Clocks (through ahci_platform_enable_clks)
- * 3) Phy
+ * 3) Phys
*
* If resource enabling fails at any point the previous enabled resources
* are disabled in reverse order.
@@ -114,17 +175,9 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
if (rc)
goto disable_regulator;
- if (hpriv->phy) {
- rc = phy_init(hpriv->phy);
- if (rc)
- goto disable_clks;
-
- rc = phy_power_on(hpriv->phy);
- if (rc) {
- phy_exit(hpriv->phy);
- goto disable_clks;
- }
- }
+ rc = ahci_platform_enable_phys(hpriv);
+ if (rc)
+ goto disable_clks;
return 0;
@@ -144,16 +197,13 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
*
* This function disables all ahci_platform managed resources in the
* following order:
- * 1) Phy
+ * 1) Phys
* 2) Clocks (through ahci_platform_disable_clks)
* 3) Regulator
*/
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
{
- if (hpriv->phy) {
- phy_power_off(hpriv->phy);
- phy_exit(hpriv->phy);
- }
+ ahci_platform_disable_phys(hpriv);
ahci_platform_disable_clks(hpriv);
@@ -187,7 +237,7 @@ static void ahci_platform_put_resources(struct device *dev, void *res)
* 2) regulator for controlling the targets power (optional)
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
* or for non devicetree enabled platforms a single clock
- * 4) phy (optional)
+ * 4) phys (optional)
*
* RETURNS:
* The allocated ahci_host_priv on success, otherwise an ERR_PTR value
@@ -197,7 +247,9 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
struct clk *clk;
- int i, rc = -ENOMEM;
+ struct device_node *child;
+ int i, enabled_ports = 0, rc = -ENOMEM;
+ u32 mask_port_map = 0;
if (!devres_open_group(dev, NULL, GFP_KERNEL))
return ERR_PTR(-ENOMEM);
@@ -246,23 +298,89 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
hpriv->clks[i] = clk;
}
- hpriv->phy = devm_phy_get(dev, "sata-phy");
- if (IS_ERR(hpriv->phy)) {
- rc = PTR_ERR(hpriv->phy);
- switch (rc) {
- case -ENODEV:
- case -ENOSYS:
- /* continue normally */
- hpriv->phy = NULL;
- break;
+ hpriv->nports = of_get_child_count(dev->of_node);
- case -EPROBE_DEFER:
+ if (hpriv->nports) {
+ hpriv->phys = devm_kzalloc(dev,
+ hpriv->nports * sizeof(*hpriv->phys),
+ GFP_KERNEL);
+ if (!hpriv->phys) {
+ rc = -ENOMEM;
goto err_out;
+ }
+
+ for_each_child_of_node(dev->of_node, child) {
+ u32 port;
+
+ if (!of_device_is_available(child))
+ continue;
+
+ if (of_property_read_u32(child, "reg", &port)) {
+ rc = -EINVAL;
+ goto err_out;
+ }
- default:
- dev_err(dev, "couldn't get sata-phy\n");
+ if (port >= hpriv->nports) {
+ dev_warn(dev, "invalid port number %d\n", port);
+ continue;
+ }
+
+ mask_port_map |= BIT(port);
+
+ hpriv->phys[port] = devm_of_phy_get(dev, child, NULL);
+ if (IS_ERR(hpriv->phys[port])) {
+ rc = PTR_ERR(hpriv->phys[port]);
+ dev_err(dev,
+ "couldn't get PHY in node %s: %d\n",
+ child->name, rc);
+ goto err_out;
+ }
+
+ enabled_ports++;
+ }
+ if (!enabled_ports) {
+ dev_warn(dev, "No port enabled\n");
+ rc = -ENODEV;
goto err_out;
}
+
+ if (!hpriv->mask_port_map)
+ hpriv->mask_port_map = mask_port_map;
+ } else {
+ /*
+ * If no sub-node was found, keep this for device tree
+ * compatibility
+ */
+ struct phy *phy = devm_phy_get(dev, "sata-phy");
+ if (!IS_ERR(phy)) {
+ hpriv->phys = devm_kzalloc(dev, sizeof(*hpriv->phys),
+ GFP_KERNEL);
+ if (!hpriv->phys) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
+ hpriv->phys[0] = phy;
+ hpriv->nports = 1;
+ } else {
+ rc = PTR_ERR(phy);
+ switch (rc) {
+ case -ENOSYS:
+ /* No PHY support. Check if PHY is required. */
+ if (of_find_property(dev->of_node, "phys", NULL)) {
+ dev_err(dev, "couldn't get sata-phy: ENOSYS\n");
+ goto err_out;
+ }
+ case -ENODEV:
+ /* continue normally */
+ hpriv->phys = NULL;
+ break;
+
+ default:
+ goto err_out;
+
+ }
+ }
}
pm_runtime_enable(dev);
@@ -283,12 +401,9 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
* @pdev: platform device pointer for the host
* @hpriv: ahci-host private data for the host
* @pi_template: template for the ata_port_info to use
- * @host_flags: ahci host flags used in ahci_host_priv
- * @force_port_map: param passed to ahci_save_initial_config
- * @mask_port_map: param passed to ahci_save_initial_config
*
* This function does all the usual steps needed to bring up an
- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
+ * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
* must be initialized / enabled before calling this.
*
* RETURNS:
@@ -296,10 +411,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
*/
int ahci_platform_init_host(struct platform_device *pdev,
struct ahci_host_priv *hpriv,
- const struct ata_port_info *pi_template,
- unsigned long host_flags,
- unsigned int force_port_map,
- unsigned int mask_port_map)
+ const struct ata_port_info *pi_template)
{
struct device *dev = &pdev->dev;
struct ata_port_info pi = *pi_template;
@@ -314,10 +426,9 @@ int ahci_platform_init_host(struct platform_device *pdev,
}
/* prepare host */
- pi.private_data = (void *)host_flags;
- hpriv->flags |= host_flags;
+ pi.private_data = (void *)(unsigned long)hpriv->flags;
- ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
+ ahci_save_initial_config(dev, hpriv);
if (hpriv->cap & HOST_CAP_NCQ)
pi.flags |= ATA_FLAG_NCQ;
@@ -364,6 +475,19 @@ int ahci_platform_init_host(struct platform_device *pdev,
ap->ops = &ata_dummy_port_ops;
}
+ if (hpriv->cap & HOST_CAP_64) {
+ rc = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ if (rc) {
+ rc = dma_coerce_mask_and_coherent(dev,
+ DMA_BIT_MASK(32));
+ if (rc) {
+ dev_err(dev, "Failed to enable 64-bit DMA.\n");
+ return rc;
+ }
+ dev_warn(dev, "Enable 32-bit DMA instead of 64-bit.\n");
+ }
+ }
+
rc = ahci_reset_controller(host);
if (rc)
return rc;
@@ -394,7 +518,7 @@ static void ahci_host_stop(struct ata_host *host)
* @dev: device pointer for the host
*
* This function does all the usual steps needed to suspend an
- * ahci-platform host, note any necessary resources (ie clks, phy, etc.)
+ * ahci-platform host, note any necessary resources (ie clks, phys, etc.)
* must be disabled after calling this.
*
* RETURNS:
@@ -431,7 +555,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
* @dev: device pointer for the host
*
* This function does all the usual steps needed to resume an ahci-platform
- * host, note any necessary resources (ie clks, phy, etc.) must be
+ * host, note any necessary resources (ie clks, phys, etc.) must be
* initialized / enabled before calling this.
*
* RETURNS:
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 18d97d5c7d90..dbdc5d32343f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -59,6 +59,7 @@
#include <linux/async.h>
#include <linux/log2.h>
#include <linux/slab.h>
+#include <linux/glob.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -4250,73 +4251,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ }
};
-/**
- * glob_match - match a text string against a glob-style pattern
- * @text: the string to be examined
- * @pattern: the glob-style pattern to be matched against
- *
- * Either/both of text and pattern can be empty strings.
- *
- * Match text against a glob-style pattern, with wildcards and simple sets:
- *
- * ? matches any single character.
- * * matches any run of characters.
- * [xyz] matches a single character from the set: x, y, or z.
- * [a-d] matches a single character from the range: a, b, c, or d.
- * [a-d0-9] matches a single character from either range.
- *
- * The special characters ?, [, -, or *, can be matched using a set, eg. [*]
- * Behaviour with malformed patterns is undefined, though generally reasonable.
- *
- * Sample patterns: "SD1?", "SD1[0-5]", "*R0", "SD*1?[012]*xx"
- *
- * This function uses one level of recursion per '*' in pattern.
- * Since it calls _nothing_ else, and has _no_ explicit local variables,
- * this will not cause stack problems for any reasonable use here.
- *
- * RETURNS:
- * 0 on match, 1 otherwise.
- */
-static int glob_match (const char *text, const char *pattern)
-{
- do {
- /* Match single character or a '?' wildcard */
- if (*text == *pattern || *pattern == '?') {
- if (!*pattern++)
- return 0; /* End of both strings: match */
- } else {
- /* Match single char against a '[' bracketed ']' pattern set */
- if (!*text || *pattern != '[')
- break; /* Not a pattern set */
- while (*++pattern && *pattern != ']' && *text != *pattern) {
- if (*pattern == '-' && *(pattern - 1) != '[')
- if (*text > *(pattern - 1) && *text < *(pattern + 1)) {
- ++pattern;
- break;
- }
- }
- if (!*pattern || *pattern == ']')
- return 1; /* No match */
- while (*pattern && *pattern++ != ']');
- }
- } while (*++text && *pattern);
-
- /* Match any run of chars against a '*' wildcard */
- if (*pattern == '*') {
- if (!*++pattern)
- return 0; /* Match: avoid recursion at end of pattern */
- /* Loop to handle additional pattern chars after the wildcard */
- while (*text) {
- if (glob_match(text, pattern) == 0)
- return 0; /* Remainder matched */
- ++text; /* Absorb (match) this char and try again */
- }
- }
- if (!*text && !*pattern)
- return 0; /* End of both strings: match */
- return 1; /* No match */
-}
-
static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
{
unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -4327,10 +4261,10 @@ static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
while (ad->model_num) {
- if (!glob_match(model_num, ad->model_num)) {
+ if (glob_match(model_num, ad->model_num)) {
if (ad->model_rev == NULL)
return ad->horkage;
- if (!glob_match(model_rev, ad->model_rev))
+ if (glob_match(model_rev, ad->model_rev))
return ad->horkage;
}
ad++;
@@ -4787,6 +4721,10 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
* ata_qc_new - Request an available ATA command, for queueing
* @ap: target port
*
+ * Some ATA host controllers may implement a queue depth which is less
+ * than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
+ * the hardware limitation.
+ *
* LOCKING:
* None.
*/
@@ -4794,14 +4732,15 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{
struct ata_queued_cmd *qc = NULL;
+ unsigned int max_queue = ap->host->n_tags;
unsigned int i, tag;
/* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
- for (i = 0; i < ATA_MAX_QUEUE; i++) {
- tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+ for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
+ tag = tag < max_queue ? tag : 0;
/* the last tag is reserved for internal command. */
if (tag == ATA_TAG_INTERNAL)
@@ -6088,6 +6027,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
{
spin_lock_init(&host->lock);
mutex_init(&host->eh_mutex);
+ host->n_tags = ATA_MAX_QUEUE - 1;
host->dev = dev;
host->ops = ops;
}
@@ -6169,6 +6109,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
{
int i, rc;
+ host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
+
/* host must have been started */
if (!(host->flags & ATA_HOST_STARTED)) {
dev_err(host->dev, "BUG: trying to register unstarted host\n");
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 6760fc4e85b8..dad83df555c4 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1811,7 +1811,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
case ATA_DEV_ATA:
if (err & ATA_ICRC)
qc->err_mask |= AC_ERR_ATA_BUS;
- if (err & ATA_UNC)
+ if (err & (ATA_UNC | ATA_AMNF))
qc->err_mask |= AC_ERR_MEDIA;
if (err & ATA_IDNF)
qc->err_mask |= AC_ERR_INVALID;
@@ -2556,11 +2556,12 @@ static void ata_eh_link_report(struct ata_link *link)
}
if (cmd->command != ATA_CMD_PACKET &&
- (res->feature & (ATA_ICRC | ATA_UNC | ATA_IDNF |
- ATA_ABORTED)))
- ata_dev_err(qc->dev, "error: { %s%s%s%s}\n",
+ (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF |
+ ATA_IDNF | ATA_ABORTED)))
+ ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",
res->feature & ATA_ICRC ? "ICRC " : "",
res->feature & ATA_UNC ? "UNC " : "",
+ res->feature & ATA_AMNF ? "AMNF " : "",
res->feature & ATA_IDNF ? "IDNF " : "",
res->feature & ATA_ABORTED ? "ABRT " : "");
#endif
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 72691fd93948..0586f66d70fa 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3945,7 +3945,7 @@ void ata_scsi_hotplug(struct work_struct *work)
* Zero.
*/
int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun)
+ unsigned int id, u64 lun)
{
struct ata_port *ap = ata_shost_to_port(shost);
unsigned long flags;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 45b5ab3a95d5..5f4e0cca56ec 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -144,7 +144,7 @@ extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap);
extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun);
+ unsigned int id, u64 lun);
/* libata-eh.c */
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c
index 6ad5c072ce34..4d37c5415fc7 100644
--- a/drivers/ata/pata_ep93xx.c
+++ b/drivers/ata/pata_ep93xx.c
@@ -915,7 +915,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev)
struct ep93xx_pata_data *drv_data;
struct ata_host *host;
struct ata_port *ap;
- unsigned int irq;
+ int irq;
struct resource *mem_res;
void __iomem *ide_base;
int err;
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c
index fb528831fb92..2578fc16960a 100644
--- a/drivers/ata/pata_samsung_cf.c
+++ b/drivers/ata/pata_samsung_cf.c
@@ -54,7 +54,6 @@
enum s3c_cpu_type {
TYPE_S3C64XX,
- TYPE_S5PC100,
TYPE_S5PV210,
};
@@ -476,10 +475,6 @@ static void pata_s3c_hwinit(struct s3c_ide_info *info,
writel(0x1b, info->ide_addr + S3C_ATA_IRQ_MSK);
break;
- case TYPE_S5PC100:
- pata_s3c_cfg_mode(info->sfr_addr);
- /* FALLTHROUGH */
-
case TYPE_S5PV210:
/* Configure as little endian */
pata_s3c_set_endian(info->ide_addr, 0);
@@ -549,11 +544,6 @@ static int __init pata_s3c_probe(struct platform_device *pdev)
info->sfr_addr = info->ide_addr + 0x1800;
info->ide_addr += 0x1900;
info->fifo_status_reg = 0x94;
- } else if (cpu_type == TYPE_S5PC100) {
- ap->ops = &pata_s5p_port_ops;
- info->sfr_addr = info->ide_addr + 0x1800;
- info->ide_addr += 0x1900;
- info->fifo_status_reg = 0x84;
} else {
ap->ops = &pata_s5p_port_ops;
info->fifo_status_reg = 0x84;
@@ -653,9 +643,6 @@ static struct platform_device_id pata_s3c_driver_ids[] = {
.name = "s3c64xx-pata",
.driver_data = TYPE_S3C64XX,
}, {
- .name = "s5pc100-pata",
- .driver_data = TYPE_S5PC100,
- }, {
.name = "s5pv210-pata",
.driver_data = TYPE_S5PV210,
},
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 616a6d2ac20c..07bc7e4dbd04 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -734,13 +734,12 @@ static int sata_fsl_port_start(struct ata_port *ap)
if (!pp)
return -ENOMEM;
- mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
- GFP_KERNEL);
+ mem = dma_zalloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
if (!mem) {
kfree(pp);
return -ENOMEM;
}
- memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ);
pp->cmdslot = mem;
pp->cmdslot_paddr = mem_dma;
diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c
index 65965cf5af06..da3bc2709c63 100644
--- a/drivers/ata/sata_highbank.c
+++ b/drivers/ata/sata_highbank.c
@@ -512,7 +512,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
return rc;
- ahci_save_initial_config(dev, hpriv, 0, 0);
+ ahci_save_initial_config(dev, hpriv);
/* prepare host */
if (hpriv->cap & HOST_CAP_NCQ)
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 0534890f118a..d81b20ddb527 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1154,8 +1154,8 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
status = readl(host_base + HOST_IRQ_STAT);
if (status == 0xffffffff) {
- printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
- "PCI fault or device removal?\n");
+ dev_err(host->dev, "IRQ status == 0xffffffff, "
+ "PCI fault or device removal?\n");
goto out;
}
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index b1955ba40d63..d65975aba4ec 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2155,7 +2155,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
if (!tx->send) continue;
if (!--left) {
- return sprintf(page,"tx[%d]: 0x%ld-0x%ld "
+ return sprintf(page, "tx[%d]: 0x%lx-0x%lx "
"(%6ld bytes), rsv %d cps, shp %d cps%s\n",i,
(unsigned long) (tx->send - eni_dev->ram),
tx->send-eni_dev->ram+tx->words*4-1,tx->words*4,
@@ -2181,7 +2181,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
if (--left) continue;
length = sprintf(page,"vcc %4d: ",vcc->vci);
if (eni_vcc->rx) {
- length += sprintf(page+length,"0x%ld-0x%ld "
+ length += sprintf(page+length, "0x%lx-0x%lx "
"(%6ld bytes)",
(unsigned long) (eni_vcc->recv - eni_dev->ram),
eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 23b8726962af..4e7f0ff83ae7 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -149,15 +149,21 @@ config EXTRA_FIRMWARE_DIR
some other directory containing the firmware files.
config FW_LOADER_USER_HELPER
+ bool
+
+config FW_LOADER_USER_HELPER_FALLBACK
bool "Fallback user-helper invocation for firmware loading"
depends on FW_LOADER
- default y
+ select FW_LOADER_USER_HELPER
help
This option enables / disables the invocation of user-helper
(e.g. udev) for loading firmware files as a fallback after the
direct file loading in kernel fails. The user-mode helper is
no longer required unless you have a special firmware file that
- resides in a non-standard path.
+ resides in a non-standard path. Moreover, the udev support has
+ been deprecated upstream.
+
+ If you are unsure about this, say N here.
config DEBUG_DRIVER
bool "Driver Core verbose debug messages"
@@ -208,6 +214,15 @@ config DMA_SHARED_BUFFER
APIs extension; the file's descriptor can then be passed on to other
driver.
+config FENCE_TRACE
+ bool "Enable verbose FENCE_TRACE messages"
+ depends on DMA_SHARED_BUFFER
+ help
+ Enable the FENCE_TRACE printks. This will add extra
+ spam to the console log, but will make it easier to diagnose
+ lockup related problems for dma-buffers shared across multiple
+ devices.
+
config DMA_CMA
bool "DMA Contiguous Memory Allocator"
depends on HAVE_DMA_CONTIGUOUS && CMA
@@ -274,16 +289,6 @@ config CMA_ALIGNMENT
If unsure, leave the default value "8".
-config CMA_AREAS
- int "Maximum count of the CMA device-private areas"
- default 7
- help
- CMA allows to create CMA areas for particular devices. This parameter
- sets the maximum number of such device private CMA areas in the
- system.
-
- If unsure, leave the default value "7".
-
endif
endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 04b314e0fa51..4aab26ec0292 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
-obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o reservation.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
diff --git a/drivers/base/component.c b/drivers/base/component.c
index c4778995cd72..f748430bb654 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -18,6 +18,15 @@
#include <linux/mutex.h>
#include <linux/slab.h>
+struct component_match {
+ size_t alloc;
+ size_t num;
+ struct {
+ void *data;
+ int (*fn)(struct device *, void *);
+ } compare[0];
+};
+
struct master {
struct list_head node;
struct list_head components;
@@ -25,6 +34,7 @@ struct master {
const struct component_master_ops *ops;
struct device *dev;
+ struct component_match *match;
};
struct component {
@@ -69,6 +79,11 @@ static void component_detach_master(struct master *master, struct component *c)
c->master = NULL;
}
+/*
+ * Add a component to a master, finding the component via the compare
+ * function and compare data. This is safe to call for duplicate matches
+ * and will not result in the same component being added multiple times.
+ */
int component_master_add_child(struct master *master,
int (*compare)(struct device *, void *), void *compare_data)
{
@@ -76,11 +91,12 @@ int component_master_add_child(struct master *master,
int ret = -ENXIO;
list_for_each_entry(c, &component_list, node) {
- if (c->master)
+ if (c->master && c->master != master)
continue;
if (compare(c->dev, compare_data)) {
- component_attach_master(master, c);
+ if (!c->master)
+ component_attach_master(master, c);
ret = 0;
break;
}
@@ -90,6 +106,34 @@ int component_master_add_child(struct master *master,
}
EXPORT_SYMBOL_GPL(component_master_add_child);
+static int find_components(struct master *master)
+{
+ struct component_match *match = master->match;
+ size_t i;
+ int ret = 0;
+
+ if (!match) {
+ /*
+ * Search the list of components, looking for components that
+ * belong to this master, and attach them to the master.
+ */
+ return master->ops->add_components(master->dev, master);
+ }
+
+ /*
+ * Scan the array of match functions and attach
+ * any components which are found to this master.
+ */
+ for (i = 0; i < match->num; i++) {
+ ret = component_master_add_child(master,
+ match->compare[i].fn,
+ match->compare[i].data);
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
/* Detach all attached components from this master */
static void master_remove_components(struct master *master)
{
@@ -113,44 +157,44 @@ static void master_remove_components(struct master *master)
static int try_to_bring_up_master(struct master *master,
struct component *component)
{
- int ret = 0;
+ int ret;
- if (!master->bound) {
- /*
- * Search the list of components, looking for components that
- * belong to this master, and attach them to the master.
- */
- if (master->ops->add_components(master->dev, master)) {
- /* Failed to find all components */
- master_remove_components(master);
- ret = 0;
- goto out;
- }
+ if (master->bound)
+ return 0;
- if (component && component->master != master) {
- master_remove_components(master);
- ret = 0;
- goto out;
- }
+ /*
+ * Search the list of components, looking for components that
+ * belong to this master, and attach them to the master.
+ */
+ if (find_components(master)) {
+ /* Failed to find all components */
+ ret = 0;
+ goto out;
+ }
- if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
- ret = -ENOMEM;
- goto out;
- }
+ if (component && component->master != master) {
+ ret = 0;
+ goto out;
+ }
- /* Found all components */
- ret = master->ops->bind(master->dev);
- if (ret < 0) {
- devres_release_group(master->dev, NULL);
- dev_info(master->dev, "master bind failed: %d\n", ret);
- master_remove_components(master);
- goto out;
- }
+ if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto out;
+ }
- master->bound = true;
- ret = 1;
+ /* Found all components */
+ ret = master->ops->bind(master->dev);
+ if (ret < 0) {
+ devres_release_group(master->dev, NULL);
+ dev_info(master->dev, "master bind failed: %d\n", ret);
+ goto out;
}
+
+ master->bound = true;
+ return 1;
+
out:
+ master_remove_components(master);
return ret;
}
@@ -180,18 +224,89 @@ static void take_down_master(struct master *master)
master_remove_components(master);
}
-int component_master_add(struct device *dev,
- const struct component_master_ops *ops)
+static size_t component_match_size(size_t num)
+{
+ return offsetof(struct component_match, compare[num]);
+}
+
+static struct component_match *component_match_realloc(struct device *dev,
+ struct component_match *match, size_t num)
+{
+ struct component_match *new;
+
+ if (match && match->alloc == num)
+ return match;
+
+ new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
+ if (!new)
+ return ERR_PTR(-ENOMEM);
+
+ if (match) {
+ memcpy(new, match, component_match_size(min(match->num, num)));
+ devm_kfree(dev, match);
+ } else {
+ new->num = 0;
+ }
+
+ new->alloc = num;
+
+ return new;
+}
+
+/*
+ * Add a component to be matched.
+ *
+ * The match array is first created or extended if necessary.
+ */
+void component_match_add(struct device *dev, struct component_match **matchptr,
+ int (*compare)(struct device *, void *), void *compare_data)
+{
+ struct component_match *match = *matchptr;
+
+ if (IS_ERR(match))
+ return;
+
+ if (!match || match->num == match->alloc) {
+ size_t new_size = match ? match->alloc + 16 : 15;
+
+ match = component_match_realloc(dev, match, new_size);
+
+ *matchptr = match;
+
+ if (IS_ERR(match))
+ return;
+ }
+
+ match->compare[match->num].fn = compare;
+ match->compare[match->num].data = compare_data;
+ match->num++;
+}
+EXPORT_SYMBOL(component_match_add);
+
+int component_master_add_with_match(struct device *dev,
+ const struct component_master_ops *ops,
+ struct component_match *match)
{
struct master *master;
int ret;
+ if (ops->add_components && match)
+ return -EINVAL;
+
+ if (match) {
+ /* Reallocate the match array for its true size */
+ match = component_match_realloc(dev, match, match->num);
+ if (IS_ERR(match))
+ return PTR_ERR(match);
+ }
+
master = kzalloc(sizeof(*master), GFP_KERNEL);
if (!master)
return -ENOMEM;
master->dev = dev;
master->ops = ops;
+ master->match = match;
INIT_LIST_HEAD(&master->components);
/* Add to the list of available masters. */
@@ -209,6 +324,13 @@ int component_master_add(struct device *dev,
return ret < 0 ? ret : 0;
}
+EXPORT_SYMBOL_GPL(component_master_add_with_match);
+
+int component_master_add(struct device *dev,
+ const struct component_master_ops *ops)
+{
+ return component_master_add_with_match(dev, ops, NULL);
+}
EXPORT_SYMBOL_GPL(component_master_add);
void component_master_del(struct device *dev,
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 52302946770f..69d9b0c89a01 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -817,6 +817,61 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp)
EXPORT_SYMBOL_GPL(devm_kstrdup);
/**
+ * devm_kvasprintf - Allocate resource managed space
+ * for the formatted string.
+ * @dev: Device to allocate memory for
+ * @gfp: the GFP mask used in the devm_kmalloc() call when
+ * allocating memory
+ * @fmt: the formatted string to duplicate
+ * @ap: the list of tokens to be placed in the formatted string
+ * RETURNS:
+ * Pointer to allocated string on success, NULL on failure.
+ */
+char *devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt,
+ va_list ap)
+{
+ unsigned int len;
+ char *p;
+ va_list aq;
+
+ va_copy(aq, ap);
+ len = vsnprintf(NULL, 0, fmt, aq);
+ va_end(aq);
+
+ p = devm_kmalloc(dev, len+1, gfp);
+ if (!p)
+ return NULL;
+
+ vsnprintf(p, len+1, fmt, ap);
+
+ return p;
+}
+EXPORT_SYMBOL(devm_kvasprintf);
+
+/**
+ * devm_kasprintf - Allocate resource managed space
+ * and copy an existing formatted string into that
+ * @dev: Device to allocate memory for
+ * @gfp: the GFP mask used in the devm_kmalloc() call when
+ * allocating memory
+ * @fmt: the string to duplicate
+ * RETURNS:
+ * Pointer to allocated string on success, NULL on failure.
+ */
+char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...)
+{
+ va_list ap;
+ char *p;
+
+ va_start(ap, fmt);
+ p = devm_kvasprintf(dev, gfp, fmt, ap);
+ va_end(ap);
+
+ return p;
+}
+EXPORT_SYMBOL_GPL(devm_kasprintf);
+
+/**
* devm_kfree - Resource-managed kfree
* @dev: Device this memory belongs to
* @p: Memory to free
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 6467c919c509..6606abdf880c 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -24,23 +24,9 @@
#include <linux/memblock.h>
#include <linux/err.h>
-#include <linux/mm.h>
-#include <linux/mutex.h>
-#include <linux/page-isolation.h>
#include <linux/sizes.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <linux/mm_types.h>
#include <linux/dma-contiguous.h>
-
-struct cma {
- unsigned long base_pfn;
- unsigned long count;
- unsigned long *bitmap;
- struct mutex lock;
-};
-
-struct cma *dma_contiguous_default_area;
+#include <linux/cma.h>
#ifdef CONFIG_CMA_SIZE_MBYTES
#define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
@@ -48,6 +34,8 @@ struct cma *dma_contiguous_default_area;
#define CMA_SIZE_MBYTES 0
#endif
+struct cma *dma_contiguous_default_area;
+
/*
* Default global CMA area size can be defined in kernel's .config.
* This is useful mainly for distro maintainers to create a kernel
@@ -154,65 +142,6 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
}
}
-static DEFINE_MUTEX(cma_mutex);
-
-static int __init cma_activate_area(struct cma *cma)
-{
- int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
- unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
- unsigned i = cma->count >> pageblock_order;
- struct zone *zone;
-
- cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-
- if (!cma->bitmap)
- return -ENOMEM;
-
- WARN_ON_ONCE(!pfn_valid(pfn));
- zone = page_zone(pfn_to_page(pfn));
-
- do {
- unsigned j;
- base_pfn = pfn;
- for (j = pageblock_nr_pages; j; --j, pfn++) {
- WARN_ON_ONCE(!pfn_valid(pfn));
- /*
- * alloc_contig_range requires the pfn range
- * specified to be in the same zone. Make this
- * simple by forcing the entire CMA resv range
- * to be in the same zone.
- */
- if (page_zone(pfn_to_page(pfn)) != zone)
- goto err;
- }
- init_cma_reserved_pageblock(pfn_to_page(base_pfn));
- } while (--i);
-
- mutex_init(&cma->lock);
- return 0;
-
-err:
- kfree(cma->bitmap);
- return -EINVAL;
-}
-
-static struct cma cma_areas[MAX_CMA_AREAS];
-static unsigned cma_area_count;
-
-static int __init cma_init_reserved_areas(void)
-{
- int i;
-
- for (i = 0; i < cma_area_count; i++) {
- int ret = cma_activate_area(&cma_areas[i]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-core_initcall(cma_init_reserved_areas);
-
/**
* dma_contiguous_reserve_area() - reserve custom contiguous area
* @size: Size of the reserved area (in bytes),
@@ -234,72 +163,17 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
phys_addr_t limit, struct cma **res_cma,
bool fixed)
{
- struct cma *cma = &cma_areas[cma_area_count];
- phys_addr_t alignment;
- int ret = 0;
-
- pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
- (unsigned long)size, (unsigned long)base,
- (unsigned long)limit);
-
- /* Sanity checks */
- if (cma_area_count == ARRAY_SIZE(cma_areas)) {
- pr_err("Not enough slots for CMA reserved regions!\n");
- return -ENOSPC;
- }
-
- if (!size)
- return -EINVAL;
-
- /* Sanitise input arguments */
- alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
- base = ALIGN(base, alignment);
- size = ALIGN(size, alignment);
- limit &= ~(alignment - 1);
-
- /* Reserve memory */
- if (base && fixed) {
- if (memblock_is_region_reserved(base, size) ||
- memblock_reserve(base, size) < 0) {
- ret = -EBUSY;
- goto err;
- }
- } else {
- phys_addr_t addr = memblock_alloc_range(size, alignment, base,
- limit);
- if (!addr) {
- ret = -ENOMEM;
- goto err;
- } else {
- base = addr;
- }
- }
-
- /*
- * Each reserved area must be initialised later, when more kernel
- * subsystems (like slab allocator) are available.
- */
- cma->base_pfn = PFN_DOWN(base);
- cma->count = size >> PAGE_SHIFT;
- *res_cma = cma;
- cma_area_count++;
+ int ret;
- pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
- (unsigned long)base);
+ ret = cma_declare_contiguous(base, size, limit, 0, 0, fixed, res_cma);
+ if (ret)
+ return ret;
/* Architecture specific contiguous memory fixup. */
- dma_contiguous_early_fixup(base, size);
- return 0;
-err:
- pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
- return ret;
-}
+ dma_contiguous_early_fixup(cma_get_base(*res_cma),
+ cma_get_size(*res_cma));
-static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
-{
- mutex_lock(&cma->lock);
- bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
- mutex_unlock(&cma->lock);
+ return 0;
}
/**
@@ -316,62 +190,10 @@ static void clear_cma_bitmap(struct cma *cma, unsigned long pfn, int count)
struct page *dma_alloc_from_contiguous(struct device *dev, int count,
unsigned int align)
{
- unsigned long mask, pfn, pageno, start = 0;
- struct cma *cma = dev_get_cma_area(dev);
- struct page *page = NULL;
- int ret;
-
- if (!cma || !cma->count)
- return NULL;
-
if (align > CONFIG_CMA_ALIGNMENT)
align = CONFIG_CMA_ALIGNMENT;
- pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
- count, align);
-
- if (!count)
- return NULL;
-
- mask = (1 << align) - 1;
-
-
- for (;;) {
- mutex_lock(&cma->lock);
- pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
- start, count, mask);
- if (pageno >= cma->count) {
- mutex_unlock(&cma->lock);
- break;
- }
- bitmap_set(cma->bitmap, pageno, count);
- /*
- * It's safe to drop the lock here. We've marked this region for
- * our exclusive use. If the migration fails we will take the
- * lock again and unmark it.
- */
- mutex_unlock(&cma->lock);
-
- pfn = cma->base_pfn + pageno;
- mutex_lock(&cma_mutex);
- ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
- mutex_unlock(&cma_mutex);
- if (ret == 0) {
- page = pfn_to_page(pfn);
- break;
- } else if (ret != -EBUSY) {
- clear_cma_bitmap(cma, pfn, count);
- break;
- }
- clear_cma_bitmap(cma, pfn, count);
- pr_debug("%s(): memory range at %p is busy, retrying\n",
- __func__, pfn_to_page(pfn));
- /* try again with a bit different memory target */
- start = pageno + mask + 1;
- }
-
- pr_debug("%s(): returned %p\n", __func__, page);
- return page;
+ return cma_alloc(dev_get_cma_area(dev), count, align);
}
/**
@@ -387,23 +209,5 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
bool dma_release_from_contiguous(struct device *dev, struct page *pages,
int count)
{
- struct cma *cma = dev_get_cma_area(dev);
- unsigned long pfn;
-
- if (!cma || !pages)
- return false;
-
- pr_debug("%s(page %p)\n", __func__, (void *)pages);
-
- pfn = page_to_pfn(pages);
-
- if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
- return false;
-
- VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
-
- free_contig_range(pfn, count);
- clear_cma_bitmap(cma, pfn, count);
-
- return true;
+ return cma_release(dev_get_cma_area(dev), pages, count);
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d276e33880be..bf424305f3dc 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -28,6 +28,7 @@
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/reboot.h>
+#include <linux/security.h>
#include <generated/utsrelease.h>
@@ -100,10 +101,16 @@ static inline long firmware_loading_timeout(void)
#define FW_OPT_UEVENT (1U << 0)
#define FW_OPT_NOWAIT (1U << 1)
#ifdef CONFIG_FW_LOADER_USER_HELPER
-#define FW_OPT_FALLBACK (1U << 2)
+#define FW_OPT_USERHELPER (1U << 2)
#else
-#define FW_OPT_FALLBACK 0
+#define FW_OPT_USERHELPER 0
#endif
+#ifdef CONFIG_FW_LOADER_USER_HELPER_FALLBACK
+#define FW_OPT_FALLBACK FW_OPT_USERHELPER
+#else
+#define FW_OPT_FALLBACK 0
+#endif
+#define FW_OPT_NO_WARN (1U << 3)
struct firmware_cache {
/* firmware_buf instance will be added into the below list */
@@ -279,26 +286,15 @@ static const char * const fw_path[] = {
module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
-/* Don't inline this: 'struct kstat' is biggish */
-static noinline_for_stack int fw_file_size(struct file *file)
-{
- struct kstat st;
- if (vfs_getattr(&file->f_path, &st))
- return -1;
- if (!S_ISREG(st.mode))
- return -1;
- if (st.size != (int)st.size)
- return -1;
- return st.size;
-}
-
static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
{
int size;
char *buf;
int rc;
- size = fw_file_size(file);
+ if (!S_ISREG(file_inode(file)->i_mode))
+ return -EINVAL;
+ size = i_size_read(file_inode(file));
if (size <= 0)
return -EINVAL;
buf = vmalloc(size);
@@ -308,12 +304,17 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
if (rc != size) {
if (rc > 0)
rc = -EIO;
- vfree(buf);
- return rc;
+ goto fail;
}
+ rc = security_kernel_fw_from_file(file, buf, size);
+ if (rc)
+ goto fail;
fw_buf->data = buf;
fw_buf->size = size;
return 0;
+fail:
+ vfree(buf);
+ return rc;
}
static int fw_get_filesystem_firmware(struct device *device,
@@ -617,6 +618,7 @@ static ssize_t firmware_loading_store(struct device *dev,
{
struct firmware_priv *fw_priv = to_firmware_priv(dev);
struct firmware_buf *fw_buf;
+ ssize_t written = count;
int loading = simple_strtol(buf, NULL, 10);
int i;
@@ -640,6 +642,8 @@ static ssize_t firmware_loading_store(struct device *dev,
break;
case 0:
if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) {
+ int rc;
+
set_bit(FW_STATUS_DONE, &fw_buf->status);
clear_bit(FW_STATUS_LOADING, &fw_buf->status);
@@ -649,10 +653,23 @@ static ssize_t firmware_loading_store(struct device *dev,
* see the mapped 'buf->data' once the loading
* is completed.
* */
- if (fw_map_pages_buf(fw_buf))
+ rc = fw_map_pages_buf(fw_buf);
+ if (rc)
dev_err(dev, "%s: map pages failed\n",
__func__);
+ else
+ rc = security_kernel_fw_from_file(NULL,
+ fw_buf->data, fw_buf->size);
+
+ /*
+ * Same logic as fw_load_abort, only the DONE bit
+ * is ignored and we set ABORT only on failure.
+ */
list_del_init(&fw_buf->pending_list);
+ if (rc) {
+ set_bit(FW_STATUS_ABORT, &fw_buf->status);
+ written = rc;
+ }
complete_all(&fw_buf->completion);
break;
}
@@ -666,7 +683,7 @@ static ssize_t firmware_loading_store(struct device *dev,
}
out:
mutex_unlock(&fw_lock);
- return count;
+ return written;
}
static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
@@ -718,7 +735,7 @@ out:
static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
{
struct firmware_buf *buf = fw_priv->buf;
- int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
+ int pages_needed = PAGE_ALIGN(min_size) >> PAGE_SHIFT;
/* If the array of pages is too small, grow it... */
if (buf->page_array_size < pages_needed) {
@@ -911,7 +928,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
wait_for_completion(&buf->completion);
cancel_delayed_work_sync(&fw_priv->timeout_work);
- if (!buf->data)
+ if (is_fw_load_aborted(buf))
+ retval = -EAGAIN;
+ else if (!buf->data)
retval = -ENOMEM;
device_remove_file(f_dev, &dev_attr_loading);
@@ -1111,10 +1130,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
ret = fw_get_filesystem_firmware(device, fw->priv);
if (ret) {
- if (opt_flags & FW_OPT_FALLBACK) {
+ if (!(opt_flags & FW_OPT_NO_WARN))
dev_warn(device,
- "Direct firmware load failed with error %d\n",
- ret);
+ "Direct firmware load for %s failed with error %d\n",
+ name, ret);
+ if (opt_flags & FW_OPT_USERHELPER) {
dev_warn(device, "Falling back to user helper\n");
ret = fw_load_from_user_helper(fw, name, device,
opt_flags, timeout);
@@ -1171,7 +1191,6 @@ request_firmware(const struct firmware **firmware_p, const char *name,
}
EXPORT_SYMBOL(request_firmware);
-#ifdef CONFIG_FW_LOADER_USER_HELPER
/**
* request_firmware: - load firmware directly without usermode helper
* @firmware_p: pointer to firmware image
@@ -1188,12 +1207,12 @@ int request_firmware_direct(const struct firmware **firmware_p,
{
int ret;
__module_get(THIS_MODULE);
- ret = _request_firmware(firmware_p, name, device, FW_OPT_UEVENT);
+ ret = _request_firmware(firmware_p, name, device,
+ FW_OPT_UEVENT | FW_OPT_NO_WARN);
module_put(THIS_MODULE);
return ret;
}
EXPORT_SYMBOL_GPL(request_firmware_direct);
-#endif
/**
* release_firmware: - release the resource associated with a firmware image
@@ -1277,7 +1296,7 @@ request_firmware_nowait(
fw_work->context = context;
fw_work->cont = cont;
fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK |
- (uevent ? FW_OPT_UEVENT : 0);
+ (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
if (!try_module_get(module)) {
kfree(fw_work);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 89f752dd8465..a2e13e250bba 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -284,7 +284,7 @@ static int memory_subsys_online(struct device *dev)
* attribute and need to set the online_type.
*/
if (mem->online_type < 0)
- mem->online_type = ONLINE_KEEP;
+ mem->online_type = MMOP_ONLINE_KEEP;
ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
@@ -315,23 +315,23 @@ store_mem_state(struct device *dev,
if (ret)
return ret;
- if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
- online_type = ONLINE_KERNEL;
- else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
- online_type = ONLINE_MOVABLE;
- else if (!strncmp(buf, "online", min_t(int, count, 6)))
- online_type = ONLINE_KEEP;
- else if (!strncmp(buf, "offline", min_t(int, count, 7)))
- online_type = -1;
+ if (sysfs_streq(buf, "online_kernel"))
+ online_type = MMOP_ONLINE_KERNEL;
+ else if (sysfs_streq(buf, "online_movable"))
+ online_type = MMOP_ONLINE_MOVABLE;
+ else if (sysfs_streq(buf, "online"))
+ online_type = MMOP_ONLINE_KEEP;
+ else if (sysfs_streq(buf, "offline"))
+ online_type = MMOP_OFFLINE;
else {
ret = -EINVAL;
goto err;
}
switch (online_type) {
- case ONLINE_KERNEL:
- case ONLINE_MOVABLE:
- case ONLINE_KEEP:
+ case MMOP_ONLINE_KERNEL:
+ case MMOP_ONLINE_MOVABLE:
+ case MMOP_ONLINE_KEEP:
/*
* mem->online_type is not protected so there can be a
* race here. However, when racing online, the first
@@ -342,7 +342,7 @@ store_mem_state(struct device *dev,
mem->online_type = online_type;
ret = device_online(&mem->dev);
break;
- case -1:
+ case MMOP_OFFLINE:
ret = device_offline(&mem->dev);
break;
default:
@@ -406,7 +406,9 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
int i, ret;
unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
- phys_addr = simple_strtoull(buf, NULL, 0);
+ ret = kstrtoull(buf, 0, &phys_addr);
+ if (ret)
+ return ret;
if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
return -EINVAL;
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 8f7ed9933a7c..c6d3ae05f1ca 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -126,7 +126,7 @@ static ssize_t node_read_meminfo(struct device *dev,
nid, K(node_page_state(nid, NR_FILE_PAGES)),
nid, K(node_page_state(nid, NR_FILE_MAPPED)),
nid, K(node_page_state(nid, NR_ANON_PAGES)),
- nid, K(node_page_state(nid, NR_SHMEM)),
+ nid, K(i.sharedram),
nid, node_page_state(nid, NR_KERNEL_STACK) *
THREAD_SIZE / 1024,
nid, K(node_page_state(nid, NR_PAGETABLE)),
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 9e9227e1762d..ab4f4ce02722 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -23,6 +23,8 @@
#include <linux/pm_runtime.h>
#include <linux/idr.h>
#include <linux/acpi.h>
+#include <linux/clk/clk-conf.h>
+#include <linux/limits.h>
#include "base.h"
#include "power/power.h"
@@ -89,8 +91,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
return dev->archdata.irqs[num];
#else
struct resource *r;
- if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
- return of_irq_get(dev->dev.of_node, num);
+ if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
+ int ret;
+
+ ret = of_irq_get(dev->dev.of_node, num);
+ if (ret >= 0 || ret == -EPROBE_DEFER)
+ return ret;
+ }
r = platform_get_resource(dev, IORESOURCE_IRQ, num);
@@ -133,8 +140,13 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name)
{
struct resource *r;
- if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
- return of_irq_get_byname(dev->dev.of_node, name);
+ if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
+ int ret;
+
+ ret = of_irq_get_byname(dev->dev.of_node, name);
+ if (ret >= 0 || ret == -EPROBE_DEFER)
+ return ret;
+ }
r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
return r ? r->start : -ENXIO;
@@ -165,7 +177,7 @@ EXPORT_SYMBOL_GPL(platform_add_devices);
struct platform_object {
struct platform_device pdev;
- char name[1];
+ char name[];
};
/**
@@ -191,6 +203,7 @@ static void platform_device_release(struct device *dev)
kfree(pa->pdev.dev.platform_data);
kfree(pa->pdev.mfd_cell);
kfree(pa->pdev.resource);
+ kfree(pa->pdev.driver_override);
kfree(pa);
}
@@ -206,7 +219,7 @@ struct platform_device *platform_device_alloc(const char *name, int id)
{
struct platform_object *pa;
- pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
+ pa = kzalloc(sizeof(*pa) + strlen(name) + 1, GFP_KERNEL);
if (pa) {
strcpy(pa->name, name);
pa->pdev.name = pa->name;
@@ -489,6 +502,10 @@ static int platform_drv_probe(struct device *_dev)
struct platform_device *dev = to_platform_device(_dev);
int ret;
+ ret = of_clk_set_defaults(_dev->of_node, false);
+ if (ret < 0)
+ return ret;
+
acpi_dev_pm_attach(_dev, true);
ret = drv->probe(dev);
@@ -698,8 +715,49 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
}
static DEVICE_ATTR_RO(modalias);
+static ssize_t driver_override_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ char *driver_override, *old = pdev->driver_override, *cp;
+
+ if (count > PATH_MAX)
+ return -EINVAL;
+
+ driver_override = kstrndup(buf, count, GFP_KERNEL);
+ if (!driver_override)
+ return -ENOMEM;
+
+ cp = strchr(driver_override, '\n');
+ if (cp)
+ *cp = '\0';
+
+ if (strlen(driver_override)) {
+ pdev->driver_override = driver_override;
+ } else {
+ kfree(driver_override);
+ pdev->driver_override = NULL;
+ }
+
+ kfree(old);
+
+ return count;
+}
+
+static ssize_t driver_override_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return sprintf(buf, "%s\n", pdev->driver_override);
+}
+static DEVICE_ATTR_RW(driver_override);
+
+
static struct attribute *platform_dev_attrs[] = {
&dev_attr_modalias.attr,
+ &dev_attr_driver_override.attr,
NULL,
};
ATTRIBUTE_GROUPS(platform_dev);
@@ -755,6 +813,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
+ /* When driver_override is set, only bind to the matching driver */
+ if (pdev->driver_override)
+ return !strcmp(pdev->driver_override, drv->name);
+
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index bf412961a934..b67d9aef9fe4 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -465,6 +465,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
* device_resume_noirq - Execute an "early resume" callback for given device.
* @dev: Device to handle.
* @state: PM transition of the system being carried out.
+ * @async: If true, the device is being resumed asynchronously.
*
* The driver of @dev will not receive interrupts while this function is being
* executed.
@@ -594,6 +595,7 @@ static void dpm_resume_noirq(pm_message_t state)
* device_resume_early - Execute an "early resume" callback for given device.
* @dev: Device to handle.
* @state: PM transition of the system being carried out.
+ * @async: If true, the device is being resumed asynchronously.
*
* Runtime PM is disabled for @dev while this function is being executed.
*/
@@ -1004,6 +1006,7 @@ static pm_message_t resume_event(pm_message_t sleep_state)
* device_suspend_noirq - Execute a "late suspend" callback for given device.
* @dev: Device to handle.
* @state: PM transition of the system being carried out.
+ * @async: If true, the device is being suspended asynchronously.
*
* The driver of @dev will not receive interrupts while this function is being
* executed.
@@ -1144,6 +1147,7 @@ static int dpm_suspend_noirq(pm_message_t state)
* device_suspend_late - Execute a "late suspend" callback for given device.
* @dev: Device to handle.
* @state: PM transition of the system being carried out.
+ * @async: If true, the device is being suspended asynchronously.
*
* Runtime PM is disabled for @dev while this function is being executed.
*/
@@ -1298,6 +1302,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
* @dev: Device to suspend.
* @state: PM transition of the system being carried out.
* @cb: Suspend callback to execute.
+ * @info: string description of caller.
*/
static int legacy_suspend(struct device *dev, pm_message_t state,
int (*cb)(struct device *dev, pm_message_t state),
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 74d8c0672cf6..78f43fb2fe84 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1073,6 +1073,19 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name)
}
EXPORT_SYMBOL_GPL(dev_get_regmap);
+/**
+ * regmap_get_device(): Obtain the device from a regmap
+ *
+ * @map: Register map to operate on.
+ *
+ * Returns the underlying device that the regmap has been created for.
+ */
+struct device *regmap_get_device(struct regmap *map)
+{
+ return map->dev;
+}
+EXPORT_SYMBOL_GPL(regmap_get_device);
+
static int _regmap_select_page(struct regmap *map, unsigned int *reg,
struct regmap_range_node *range,
unsigned int val_num)
diff --git a/drivers/base/reservation.c b/drivers/base/reservation.c
deleted file mode 100644
index a73fbf3b8e56..000000000000
--- a/drivers/base/reservation.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Canonical Ltd
- *
- * Based on bo.c which bears the following copyright notice,
- * but is dual licensed:
- *
- * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
- */
-
-#include <linux/reservation.h>
-#include <linux/export.h>
-
-DEFINE_WW_CLASS(reservation_ww_class);
-EXPORT_SYMBOL(reservation_ww_class);
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 734b32f09c0a..91290f7f61b8 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -3,6 +3,7 @@ bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
bcma-y += driver_pci.o
+bcma-y += driver_pcie2.o
bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index 5081a8c439cc..fe0d48cb1778 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -603,6 +603,8 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
tmp = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
break;
+ case BCMA_CHIP_ID_BCM43131:
+ case BCMA_CHIP_ID_BCM43217:
case BCMA_CHIP_ID_BCM43227:
case BCMA_CHIP_ID_BCM43228:
case BCMA_CHIP_ID_BCM43428:
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index d7f81ad56b8a..aec9f850b4a8 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -220,6 +220,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
#endif
switch (cc->core->bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM5357:
+ case BCMA_CHIP_ID_BCM53572:
chip->ngpio = 32;
break;
default:
diff --git a/drivers/bcma/driver_pcie2.c b/drivers/bcma/driver_pcie2.c
new file mode 100644
index 000000000000..e4be537b0c66
--- /dev/null
+++ b/drivers/bcma/driver_pcie2.c
@@ -0,0 +1,175 @@
+/*
+ * Broadcom specific AMBA
+ * PCIe Gen 2 Core
+ *
+ * Copyright 2014, Broadcom Corporation
+ * Copyright 2014, Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+/**************************************************
+ * R/W ops.
+ **************************************************/
+
+#if 0
+static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr)
+{
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
+ pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR);
+ return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
+}
+#endif
+
+static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr,
+ u32 val)
+{
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val);
+}
+
+/**************************************************
+ * Init.
+ **************************************************/
+
+static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2,
+ bool enable)
+{
+ u32 val;
+
+ /* restore back to default */
+ val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
+ val |= PCIE2_CLKC_DLYPERST;
+ val &= ~PCIE2_CLKC_DISSPROMLD;
+ if (enable) {
+ val &= ~PCIE2_CLKC_DLYPERST;
+ val |= PCIE2_CLKC_DISSPROMLD;
+ }
+ pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val);
+ /* flush */
+ return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
+}
+
+static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2)
+{
+ /* LTR0 */
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c);
+ /* LTR1 */
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864);
+ /* LTR2 */
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003);
+}
+
+static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2)
+{
+ u8 core_rev = pcie2->core->id.rev;
+ u32 devstsctr2;
+
+ if (core_rev < 2 || core_rev == 10 || core_rev > 13)
+ return;
+
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
+ PCIE2_CAP_DEVSTSCTRL2_OFFSET);
+ devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
+ if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) {
+ /* force the right LTR values */
+ bcma_core_pcie2_set_ltr_vals(pcie2);
+
+ /* TODO:
+ si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */
+
+ /* enable the LTR */
+ devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB;
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
+ PCIE2_CAP_DEVSTSCTRL2_OFFSET);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2);
+
+ /* set the LTR state to be active */
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
+ PCIE2_LTR_ACTIVE);
+ usleep_range(1000, 2000);
+
+ /* set the LTR state to be sleep */
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
+ PCIE2_LTR_SLEEP);
+ usleep_range(1000, 2000);
+ }
+}
+
+static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2)
+{
+ u8 core_rev = pcie2->core->id.rev;
+ bool pciewar160, pciewar162;
+
+ pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11;
+ pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 ||
+ core_rev == 9 || core_rev == 11;
+
+ if (!pciewar160 && !pciewar162)
+ return;
+
+/* TODO */
+#if 0
+ pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL,
+ PCIE_DISABLE_L1CLK_GATING);
+#if 0
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
+ PCIEGEN2_COE_PVT_TL_CTRL_0);
+ pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA,
+ ~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT));
+#endif
+#endif
+}
+
+static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2)
+{
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP);
+ pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f);
+}
+
+static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2)
+{
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0);
+}
+
+static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2)
+{
+ struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc;
+ u8 core_rev = pcie2->core->id.rev;
+ u32 alp_khz, pm_value;
+
+ if (core_rev <= 13) {
+ alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000;
+ pm_value = (1000000 * 2) / alp_khz;
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
+ PCIE2_PVT_REG_PM_CLK_PERIOD);
+ pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value);
+ }
+}
+
+void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
+{
+ struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
+ u32 tmp;
+
+ tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
+ if ((tmp & 0xe) >> 1 == 2)
+ bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
+
+ /* TODO: Do we need pcie_reqsize? */
+
+ if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
+ bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
+ bcma_core_pcie2_hw_ltr_war(pcie2);
+ pciedev_crwlpciegen2(pcie2);
+ pciedev_reg_pm_clk_period(pcie2);
+ pciedev_crwlpciegen2_180(pcie2);
+ pciedev_crwlpciegen2_182(pcie2);
+}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index e333305363aa..294a7dd25190 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -279,6 +279,8 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ 0, },
};
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 34ea4c588d36..0ff8d58831ef 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -132,6 +132,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
case BCMA_CORE_CHIPCOMMON:
case BCMA_CORE_PCI:
case BCMA_CORE_PCIE:
+ case BCMA_CORE_PCIE2:
case BCMA_CORE_MIPS_74K:
case BCMA_CORE_4706_MAC_GBIT_COMMON:
continue;
@@ -281,6 +282,13 @@ int bcma_bus_register(struct bcma_bus *bus)
bcma_core_pci_init(&bus->drv_pci[1]);
}
+ /* Init PCIe Gen 2 core */
+ core = bcma_find_core_unit(bus, BCMA_CORE_PCIE2, 0);
+ if (core) {
+ bus->drv_pcie2.core = core;
+ bcma_core_pcie2_init(&bus->drv_pcie2);
+ }
+
/* Init GBIT MAC COMMON core */
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
if (core) {
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 37768401d113..b4764c6bcf17 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -32,17 +32,17 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = {
{ BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
{ BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
{ BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
- { BCMA_CORE_PCIEG2, "PCIe Gen 2" },
- { BCMA_CORE_DMA, "DMA" },
- { BCMA_CORE_SDIO3, "SDIO3" },
- { BCMA_CORE_USB20, "USB 2.0" },
- { BCMA_CORE_USB30, "USB 3.0" },
- { BCMA_CORE_A9JTAG, "ARM Cortex A9 JTAG" },
- { BCMA_CORE_DDR23, "Denali DDR2/DDR3 memory controller" },
- { BCMA_CORE_ROM, "ROM" },
- { BCMA_CORE_NAND, "NAND flash controller" },
- { BCMA_CORE_QSPI, "SPI flash controller" },
- { BCMA_CORE_CHIPCOMMON_B, "Chipcommon B" },
+ { BCMA_CORE_NS_PCIEG2, "PCIe Gen 2" },
+ { BCMA_CORE_NS_DMA, "DMA" },
+ { BCMA_CORE_NS_SDIO3, "SDIO3" },
+ { BCMA_CORE_NS_USB20, "USB 2.0" },
+ { BCMA_CORE_NS_USB30, "USB 3.0" },
+ { BCMA_CORE_NS_A9JTAG, "ARM Cortex A9 JTAG" },
+ { BCMA_CORE_NS_DDR23, "Denali DDR2/DDR3 memory controller" },
+ { BCMA_CORE_NS_ROM, "ROM" },
+ { BCMA_CORE_NS_NAND, "NAND flash controller" },
+ { BCMA_CORE_NS_QSPI, "SPI flash controller" },
+ { BCMA_CORE_NS_CHIPCOMMON_B, "Chipcommon B" },
{ BCMA_CORE_ARMCA9, "ARM Cortex A9 core (ihost)" },
{ BCMA_CORE_AMEMC, "AMEMC (DDR)" },
{ BCMA_CORE_ALTA, "ALTA (I2S)" },
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 72bf4540f565..efb037f9c98a 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
SPEX(_field[7], _offset + 14, _mask, _shift); \
} while (0)
+static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
+{
+ u16 v;
+ u8 gain;
+
+ v = in[SPOFF(offset)];
+ gain = (v & mask) >> shift;
+ if (gain == 0xFF) {
+ gain = 8; /* If unset use 2dBm */
+ } else {
+ /* Q5.2 Fractional part is stored in 0xC0 */
+ gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
+ }
+
+ return (s8)gain;
+}
+
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
{
u16 v, o;
@@ -381,14 +398,22 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
/* Extract the antenna gain values. */
- SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
- SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
- SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
- SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
+ bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN0,
+ SSB_SPROM8_AGAIN0_SHIFT);
+ bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN1,
+ SSB_SPROM8_AGAIN1_SHIFT);
+ bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN2,
+ SSB_SPROM8_AGAIN2_SHIFT);
+ bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN3,
+ SSB_SPROM8_AGAIN3_SHIFT);
SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
SSB_SPROM8_LEDDC_ON_SHIFT);
@@ -509,6 +534,8 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
/* for these chips OTP is always available */
present = true;
break;
+ case BCMA_CHIP_ID_BCM43131:
+ case BCMA_CHIP_ID_BCM43217:
case BCMA_CHIP_ID_BCM43227:
case BCMA_CHIP_ID_BCM43228:
case BCMA_CHIP_ID_BCM43428:
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 1b35c45c92b7..3f2e16738080 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -544,6 +544,12 @@ void conn_try_outdate_peer_async(struct drbd_connection *connection)
struct task_struct *opa;
kref_get(&connection->kref);
+ /* We may just have force_sig()'ed this thread
+ * to get it out of some blocking network function.
+ * Clear signals; otherwise kthread_run(), which internally uses
+ * wait_on_completion_killable(), will mistake our pending signal
+ * for a new fatal signal and fail. */
+ flush_signals(current);
opa = kthread_run(_try_outdate_peer_async, connection, "drbd_async_h");
if (IS_ERR(opa)) {
drbd_err(connection, "out of mem, failed to invoke fence-peer helper\n");
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 48eccb350180..dfa4024c448a 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -183,19 +183,32 @@ static ssize_t comp_algorithm_store(struct device *dev,
static int zram_test_flag(struct zram_meta *meta, u32 index,
enum zram_pageflags flag)
{
- return meta->table[index].flags & BIT(flag);
+ return meta->table[index].value & BIT(flag);
}
static void zram_set_flag(struct zram_meta *meta, u32 index,
enum zram_pageflags flag)
{
- meta->table[index].flags |= BIT(flag);
+ meta->table[index].value |= BIT(flag);
}
static void zram_clear_flag(struct zram_meta *meta, u32 index,
enum zram_pageflags flag)
{
- meta->table[index].flags &= ~BIT(flag);
+ meta->table[index].value &= ~BIT(flag);
+}
+
+static size_t zram_get_obj_size(struct zram_meta *meta, u32 index)
+{
+ return meta->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1);
+}
+
+static void zram_set_obj_size(struct zram_meta *meta,
+ u32 index, size_t size)
+{
+ unsigned long flags = meta->table[index].value >> ZRAM_FLAG_SHIFT;
+
+ meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size;
}
static inline int is_partial_io(struct bio_vec *bvec)
@@ -255,7 +268,6 @@ static struct zram_meta *zram_meta_alloc(u64 disksize)
goto free_table;
}
- rwlock_init(&meta->tb_lock);
return meta;
free_table:
@@ -304,7 +316,12 @@ static void handle_zero_page(struct bio_vec *bvec)
flush_dcache_page(page);
}
-/* NOTE: caller should hold meta->tb_lock with write-side */
+
+/*
+ * To protect concurrent access to the same index entry,
+ * caller should hold this table index entry's bit_spinlock to
+ * indicate this index entry is accessing.
+ */
static void zram_free_page(struct zram *zram, size_t index)
{
struct zram_meta *meta = zram->meta;
@@ -324,11 +341,12 @@ static void zram_free_page(struct zram *zram, size_t index)
zs_free(meta->mem_pool, handle);
- atomic64_sub(meta->table[index].size, &zram->stats.compr_data_size);
+ atomic64_sub(zram_get_obj_size(meta, index),
+ &zram->stats.compr_data_size);
atomic64_dec(&zram->stats.pages_stored);
meta->table[index].handle = 0;
- meta->table[index].size = 0;
+ zram_set_obj_size(meta, index, 0);
}
static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
@@ -337,14 +355,14 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
unsigned char *cmem;
struct zram_meta *meta = zram->meta;
unsigned long handle;
- u16 size;
+ size_t size;
- read_lock(&meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
handle = meta->table[index].handle;
- size = meta->table[index].size;
+ size = zram_get_obj_size(meta, index);
if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) {
- read_unlock(&meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
clear_page(mem);
return 0;
}
@@ -355,7 +373,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
else
ret = zcomp_decompress(zram->comp, cmem, size, mem);
zs_unmap_object(meta->mem_pool, handle);
- read_unlock(&meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
/* Should NEVER happen. Return bio error if it does. */
if (unlikely(ret)) {
@@ -376,14 +394,14 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
struct zram_meta *meta = zram->meta;
page = bvec->bv_page;
- read_lock(&meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
if (unlikely(!meta->table[index].handle) ||
zram_test_flag(meta, index, ZRAM_ZERO)) {
- read_unlock(&meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
handle_zero_page(bvec);
return 0;
}
- read_unlock(&meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
if (is_partial_io(bvec))
/* Use a temporary buffer to decompress the page */
@@ -461,10 +479,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
if (page_zero_filled(uncmem)) {
kunmap_atomic(user_mem);
/* Free memory associated with this sector now. */
- write_lock(&zram->meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
zram_free_page(zram, index);
zram_set_flag(meta, index, ZRAM_ZERO);
- write_unlock(&zram->meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
atomic64_inc(&zram->stats.zero_pages);
ret = 0;
@@ -514,12 +532,12 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
* Free memory associated with this sector
* before overwriting unused sectors.
*/
- write_lock(&zram->meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
zram_free_page(zram, index);
meta->table[index].handle = handle;
- meta->table[index].size = clen;
- write_unlock(&zram->meta->tb_lock);
+ zram_set_obj_size(meta, index, clen);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
/* Update stats */
atomic64_add(clen, &zram->stats.compr_data_size);
@@ -560,6 +578,7 @@ static void zram_bio_discard(struct zram *zram, u32 index,
int offset, struct bio *bio)
{
size_t n = bio->bi_iter.bi_size;
+ struct zram_meta *meta = zram->meta;
/*
* zram manages data in physical block size units. Because logical block
@@ -580,13 +599,9 @@ static void zram_bio_discard(struct zram *zram, u32 index,
}
while (n >= PAGE_SIZE) {
- /*
- * Discard request can be large so the lock hold times could be
- * lengthy. So take the lock once per page.
- */
- write_lock(&zram->meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
zram_free_page(zram, index);
- write_unlock(&zram->meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
index++;
n -= PAGE_SIZE;
}
@@ -624,7 +639,16 @@ static void zram_reset_device(struct zram *zram, bool reset_capacity)
zram->disksize = 0;
if (reset_capacity)
set_capacity(zram->disk, 0);
+
up_write(&zram->init_lock);
+
+ /*
+ * Revalidate disk out of the init_lock to avoid lockdep splat.
+ * It's okay because disk's capacity is protected by init_lock
+ * so that revalidate_disk always sees up-to-date capacity.
+ */
+ if (reset_capacity)
+ revalidate_disk(zram->disk);
}
static ssize_t disksize_store(struct device *dev,
@@ -665,6 +689,14 @@ static ssize_t disksize_store(struct device *dev,
zram->disksize = disksize;
set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
up_write(&zram->init_lock);
+
+ /*
+ * Revalidate disk out of the init_lock to avoid lockdep splat.
+ * It's okay because disk's capacity is protected by init_lock
+ * so that revalidate_disk always sees up-to-date capacity.
+ */
+ revalidate_disk(zram->disk);
+
return len;
out_destroy_comp:
@@ -804,9 +836,9 @@ static void zram_slot_free_notify(struct block_device *bdev,
zram = bdev->bd_disk->private_data;
meta = zram->meta;
- write_lock(&meta->tb_lock);
+ bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value);
zram_free_page(zram, index);
- write_unlock(&meta->tb_lock);
+ bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
atomic64_inc(&zram->stats.notify_free);
}
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 7f21c145e317..5b0afde729cd 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -43,7 +43,6 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
/*-- End of configurable params */
#define SECTOR_SHIFT 9
-#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
#define ZRAM_LOGICAL_BLOCK_SHIFT 12
@@ -51,10 +50,24 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
#define ZRAM_SECTOR_PER_LOGICAL_BLOCK \
(1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT))
-/* Flags for zram pages (table[page_no].flags) */
+
+/*
+ * The lower ZRAM_FLAG_SHIFT bits of table.value is for
+ * object size (excluding header), the higher bits is for
+ * zram_pageflags.
+ *
+ * zram is mainly used for memory efficiency so we want to keep memory
+ * footprint small so we can squeeze size and flags into a field.
+ * The lower ZRAM_FLAG_SHIFT bits is for object size (excluding header),
+ * the higher bits is for zram_pageflags.
+ */
+#define ZRAM_FLAG_SHIFT 24
+
+/* Flags for zram pages (table[page_no].value) */
enum zram_pageflags {
/* Page consists entirely of zeros */
- ZRAM_ZERO,
+ ZRAM_ZERO = ZRAM_FLAG_SHIFT + 1,
+ ZRAM_ACCESS, /* page in now accessed */
__NR_ZRAM_PAGEFLAGS,
};
@@ -62,11 +75,10 @@ enum zram_pageflags {
/*-- Data structures */
/* Allocated for each disk page */
-struct table {
+struct zram_table_entry {
unsigned long handle;
- u16 size; /* object size (excluding header) */
- u8 flags;
-} __aligned(4);
+ unsigned long value;
+};
struct zram_stats {
atomic64_t compr_data_size; /* compressed size of pages stored */
@@ -81,8 +93,7 @@ struct zram_stats {
};
struct zram_meta {
- rwlock_t tb_lock; /* protect table */
- struct table *table;
+ struct zram_table_entry *table;
struct zs_pool *mem_pool;
};
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index f5ce64e03fd7..fa7fd62ddffa 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -30,8 +30,8 @@ config BT_HCIUART
help
Bluetooth HCI UART driver.
This driver is required if you want to use Bluetooth devices with
- serial port interface. You will also need this driver if you have
- UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
+ serial port interface. You will also need this driver if you have
+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
adapter and BrainBoxes Bluetooth PC Card.
Say Y here to compile support for Bluetooth UART devices into the
@@ -41,9 +41,9 @@ config BT_HCIUART_H4
bool "UART (H4) protocol support"
depends on BT_HCIUART
help
- UART (H4) is serial protocol for communication between Bluetooth
- device and host. This protocol is required for most Bluetooth devices
- with UART interface, including PCMCIA and CF cards.
+ UART (H4) is serial protocol for communication between Bluetooth
+ device and host. This protocol is required for most Bluetooth devices
+ with UART interface, including PCMCIA and CF cards.
Say Y here to compile support for HCI UART (H4) protocol.
@@ -52,7 +52,7 @@ config BT_HCIUART_BCSP
depends on BT_HCIUART
select BITREVERSE
help
- BCSP (BlueCore Serial Protocol) is serial protocol for communication
+ BCSP (BlueCore Serial Protocol) is serial protocol for communication
between Bluetooth device and host. This protocol is required for non
USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
CF cards.
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index f98380648cb3..a0d7355ef127 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/usb.h>
+#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#define VERSION "1.0"
@@ -50,12 +51,12 @@
#define ATH3K_NAME_LEN 0xFF
struct ath3k_version {
- unsigned int rom_version;
- unsigned int build_version;
- unsigned int ram_version;
- unsigned char ref_clock;
- unsigned char reserved[0x07];
-};
+ __le32 rom_version;
+ __le32 build_version;
+ __le32 ram_version;
+ __u8 ref_clock;
+ __u8 reserved[7];
+} __packed;
static const struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
@@ -90,7 +91,6 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0) },
{ USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
- { USB_DEVICE(0x0CF3, 0x3005) },
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) },
@@ -104,6 +104,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) },
+ { USB_DEVICE(0x13d3, 0x3432) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
@@ -140,7 +141,6 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
@@ -154,6 +154,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
@@ -290,10 +291,10 @@ static int ath3k_load_fwfile(struct usb_device *udev,
sent += size;
count -= size;
+ pipe = usb_sndbulkpipe(udev, 0x02);
+
while (count) {
size = min_t(uint, count, BULK_SIZE);
- pipe = usb_sndbulkpipe(udev, 0x02);
-
memcpy(send_buf, firmware->data + sent, size);
err = usb_bulk_msg(udev, pipe, send_buf, size,
@@ -349,7 +350,8 @@ static int ath3k_load_patch(struct usb_device *udev)
unsigned char fw_state;
char filename[ATH3K_NAME_LEN] = {0};
const struct firmware *firmware;
- struct ath3k_version fw_version, pt_version;
+ struct ath3k_version fw_version;
+ __u32 pt_rom_version, pt_build_version;
int ret;
ret = ath3k_get_state(udev, &fw_state);
@@ -370,7 +372,7 @@ static int ath3k_load_patch(struct usb_device *udev)
}
snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
- le32_to_cpu(fw_version.rom_version));
+ le32_to_cpu(fw_version.rom_version));
ret = request_firmware(&firmware, filename, &udev->dev);
if (ret < 0) {
@@ -378,12 +380,13 @@ static int ath3k_load_patch(struct usb_device *udev)
return ret;
}
- pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
- pt_version.build_version = *(int *)
- (firmware->data + firmware->size - 4);
+ pt_rom_version = get_unaligned_le32(firmware->data +
+ firmware->size - 8);
+ pt_build_version = get_unaligned_le32(firmware->data +
+ firmware->size - 4);
- if ((pt_version.rom_version != fw_version.rom_version) ||
- (pt_version.build_version <= fw_version.build_version)) {
+ if (pt_rom_version != le32_to_cpu(fw_version.rom_version) ||
+ pt_build_version <= le32_to_cpu(fw_version.build_version)) {
BT_ERR("Patch file version did not match with firmware");
release_firmware(firmware);
return -EINVAL;
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index dc79f88f8717..38ad66289ad6 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -68,6 +68,7 @@ struct btmrvl_adapter {
u8 hs_state;
u8 wakeup_tries;
wait_queue_head_t cmd_wait_q;
+ wait_queue_head_t event_hs_wait_q;
u8 cmd_complete;
bool is_suspended;
};
@@ -89,6 +90,8 @@ struct btmrvl_private {
#define MRVL_VENDOR_PKT 0xFE
/* Vendor specific Bluetooth commands */
+#define BT_CMD_PSCAN_WIN_REPORT_ENABLE 0xFC03
+#define BT_CMD_SET_BDADDR 0xFC22
#define BT_CMD_AUTO_SLEEP_MODE 0xFC23
#define BT_CMD_HOST_SLEEP_CONFIG 0xFC59
#define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A
@@ -143,6 +146,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
+int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
int btmrvl_enable_ps(struct btmrvl_private *priv);
int btmrvl_prepare_command(struct btmrvl_private *priv);
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index e9dbddb0b8f1..1d7db2064889 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -114,6 +114,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode)
adapter->ps_state = PS_SLEEP;
+ wake_up_interruptible(&adapter->event_hs_wait_q);
BT_DBG("HS ACTIVATED!");
} else {
BT_DBG("HS Enable failed");
@@ -214,6 +215,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
}
EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
+int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd)
+{
+ struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+ int ret;
+
+ if (!card->support_pscan_win_report)
+ return 0;
+
+ ret = btmrvl_send_sync_cmd(priv, BT_CMD_PSCAN_WIN_REPORT_ENABLE,
+ &subcmd, 1);
+ if (ret)
+ BT_ERR("PSCAN_WIN_REPORT_ENABLE command failed: %#x", ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(btmrvl_pscan_window_reporting);
+
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
{
int ret;
@@ -253,11 +271,31 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
int btmrvl_enable_hs(struct btmrvl_private *priv)
{
+ struct btmrvl_adapter *adapter = priv->adapter;
int ret;
ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
- if (ret)
+ if (ret) {
BT_ERR("Host sleep enable command failed\n");
+ return ret;
+ }
+
+ ret = wait_event_interruptible_timeout(adapter->event_hs_wait_q,
+ adapter->hs_state,
+ msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED));
+ if (ret < 0) {
+ BT_ERR("event_hs_wait_q terminated (%d): %d,%d,%d",
+ ret, adapter->hs_state, adapter->ps_state,
+ adapter->wakeup_tries);
+ } else if (!ret) {
+ BT_ERR("hs_enable timeout: %d,%d,%d", adapter->hs_state,
+ adapter->ps_state, adapter->wakeup_tries);
+ ret = -ETIMEDOUT;
+ } else {
+ BT_DBG("host sleep enabled: %d,%d,%d", adapter->hs_state,
+ adapter->ps_state, adapter->wakeup_tries);
+ ret = 0;
+ }
return ret;
}
@@ -358,6 +396,7 @@ static void btmrvl_init_adapter(struct btmrvl_private *priv)
}
init_waitqueue_head(&priv->adapter->cmd_wait_q);
+ init_waitqueue_head(&priv->adapter->event_hs_wait_q);
}
static void btmrvl_free_adapter(struct btmrvl_private *priv)
@@ -489,6 +528,8 @@ static int btmrvl_setup(struct hci_dev *hdev)
btmrvl_cal_data_dt(priv);
+ btmrvl_pscan_window_reporting(priv, 0x01);
+
priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv);
@@ -498,6 +539,29 @@ static int btmrvl_setup(struct hci_dev *hdev)
return 0;
}
+static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+ struct sk_buff *skb;
+ long ret;
+ u8 buf[8];
+
+ buf[0] = MRVL_VENDOR_PKT;
+ buf[1] = sizeof(bdaddr_t);
+ memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
+
+ skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
+ HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: changing btmrvl device address failed (%ld)",
+ hdev->name, ret);
+ return ret;
+ }
+ kfree_skb(skb);
+
+ return 0;
+}
+
/*
* This function handles the event generated by firmware, rx data
* received from firmware, and tx data sent from kernel.
@@ -591,6 +655,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame;
hdev->setup = btmrvl_setup;
+ hdev->set_bdaddr = btmrvl_set_bdaddr;
hdev->dev_type = priv->btmrvl_dev.dev_type;
@@ -645,12 +710,17 @@ struct btmrvl_private *btmrvl_add_card(void *card)
init_waitqueue_head(&priv->main_thread.wait_q);
priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
&priv->main_thread, "btmrvl_main_service");
+ if (IS_ERR(priv->main_thread.task))
+ goto err_thread;
priv->btmrvl_dev.card = card;
priv->btmrvl_dev.tx_dnld_rdy = true;
return priv;
+err_thread:
+ btmrvl_free_adapter(priv);
+
err_adapter:
kfree(priv);
@@ -666,6 +736,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv)
hdev = priv->btmrvl_dev.hcidev;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
+ wake_up_interruptible(&priv->adapter->event_hs_wait_q);
kthread_stop(priv->main_thread.task);
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 9dedca516ff5..3e683b153259 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -108,6 +108,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
.reg = &btmrvl_reg_8688,
+ .support_pscan_win_report = false,
.sd_blksz_fw_dl = 64,
};
@@ -115,6 +116,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
.reg = &btmrvl_reg_87xx,
+ .support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
};
@@ -122,6 +124,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
.reg = &btmrvl_reg_87xx,
+ .support_pscan_win_report = false,
.sd_blksz_fw_dl = 256,
};
@@ -129,6 +132,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin",
.reg = &btmrvl_reg_88xx,
+ .support_pscan_win_report = true,
.sd_blksz_fw_dl = 256,
};
@@ -1067,6 +1071,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
card->firmware = data->firmware;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
+ card->support_pscan_win_report = data->support_pscan_win_report;
}
if (btmrvl_sdio_register_dev(card) < 0) {
@@ -1164,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev)
}
priv = card->priv;
+ hcidev = priv->btmrvl_dev.hcidev;
+ BT_DBG("%s: SDIO suspend", hcidev->name);
+ hci_suspend_dev(hcidev);
+ skb_queue_purge(&priv->adapter->tx_queue);
if (priv->adapter->hs_state != HS_ACTIVATED) {
if (btmrvl_enable_hs(priv)) {
@@ -1171,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev)
return -EBUSY;
}
}
- hcidev = priv->btmrvl_dev.hcidev;
- BT_DBG("%s: SDIO suspend", hcidev->name);
- hci_suspend_dev(hcidev);
- skb_queue_purge(&priv->adapter->tx_queue);
priv->adapter->is_suspended = true;
@@ -1216,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev)
return 0;
}
- priv->adapter->is_suspended = false;
- hcidev = priv->btmrvl_dev.hcidev;
- BT_DBG("%s: SDIO resume", hcidev->name);
- hci_resume_dev(hcidev);
priv->hw_wakeup_firmware(priv);
priv->adapter->hs_state = HS_DEACTIVATED;
+ hcidev = priv->btmrvl_dev.hcidev;
BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
+ priv->adapter->is_suspended = false;
+ BT_DBG("%s: SDIO resume", hcidev->name);
+ hci_resume_dev(hcidev);
return 0;
}
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index d4dd3b0fa53d..453559f98a75 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -89,6 +89,7 @@ struct btmrvl_sdio_card {
const char *helper;
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
+ bool support_pscan_win_report;
u16 sd_blksz_fw_dl;
u8 rx_unit;
struct btmrvl_private *priv;
@@ -98,6 +99,7 @@ struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
const struct btmrvl_sdio_card_reg *reg;
+ const bool support_pscan_win_report;
u16 sd_blksz_fw_dl;
};
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index a1c80b0c7663..292c38e8aa17 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -30,9 +30,6 @@
#define VERSION "0.6"
-static bool ignore_dga;
-static bool ignore_csr;
-static bool ignore_sniffer;
static bool disable_scofix;
static bool force_scofix;
@@ -49,7 +46,9 @@ static struct usb_driver btusb_driver;
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100
-#define BTUSB_BCM_PATCHRAM 0x200
+#define BTUSB_INTEL_BOOT 0x200
+#define BTUSB_BCM_PATCHRAM 0x400
+#define BTUSB_MARVELL 0x800
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@@ -115,12 +114,19 @@ static const struct usb_device_id btusb_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
+ /* ASUSTek Computer - Broadcom based */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0b05, 0xff, 0x01, 0x01) },
+
/* Belkin F8065bf - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
/* IMC Networks - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
+ /* Intel Bluetooth USB Bootloader (RAM module) */
+ { USB_DEVICE(0x8087, 0x0a5a),
+ .driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
+
{ } /* Terminating entry */
};
@@ -162,7 +168,6 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@ -176,6 +181,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -229,15 +235,21 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
/* CSR BlueCore Bluetooth Sniffer */
- { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
+ { USB_DEVICE(0x0a12, 0x0002),
+ .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Frontline ComProbe Bluetooth Sniffer */
- { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
+ { USB_DEVICE(0x16d3, 0x0002),
+ .driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC },
/* Intel Bluetooth device */
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
+ /* Marvell device */
+ { USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
+ { USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
+
{ } /* Terminating entry */
};
@@ -1183,6 +1195,51 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
return 0;
}
+#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}})
+
+static int btusb_check_bdaddr_intel(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+ struct hci_rp_read_bd_addr *rp;
+
+ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+ HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ BT_ERR("%s reading Intel device address failed (%ld)",
+ hdev->name, PTR_ERR(skb));
+ return PTR_ERR(skb);
+ }
+
+ if (skb->len != sizeof(*rp)) {
+ BT_ERR("%s Intel device address length mismatch", hdev->name);
+ kfree_skb(skb);
+ return -EIO;
+ }
+
+ rp = (struct hci_rp_read_bd_addr *) skb->data;
+ if (rp->status) {
+ BT_ERR("%s Intel device address result failed (%02x)",
+ hdev->name, rp->status);
+ kfree_skb(skb);
+ return -bt_to_errno(rp->status);
+ }
+
+ /* For some Intel based controllers, the default Bluetooth device
+ * address 00:03:19:9E:8B:00 can be found. These controllers are
+ * fully operational, but have the danger of duplicate addresses
+ * and that in turn can cause problems with Bluetooth operation.
+ */
+ if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) {
+ BT_ERR("%s found Intel default device address (%pMR)",
+ hdev->name, &rp->bdaddr);
+ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+ }
+
+ kfree_skb(skb);
+
+ return 0;
+}
+
static int btusb_setup_intel(struct hci_dev *hdev)
{
struct sk_buff *skb;
@@ -1255,6 +1312,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_INFO("%s: Intel device is already patched. patch num: %02x",
hdev->name, ver->fw_patch_num);
kfree_skb(skb);
+ btusb_check_bdaddr_intel(hdev);
return 0;
}
@@ -1267,6 +1325,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
fw = btusb_setup_intel_get_fw(hdev, ver);
if (!fw) {
kfree_skb(skb);
+ btusb_check_bdaddr_intel(hdev);
return 0;
}
fw_ptr = fw->data;
@@ -1346,6 +1405,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
hdev->name);
+ btusb_check_bdaddr_intel(hdev);
return 0;
exit_mfg_disable:
@@ -1360,6 +1420,8 @@ exit_mfg_disable:
kfree_skb(skb);
BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
+
+ btusb_check_bdaddr_intel(hdev);
return 0;
exit_mfg_deactivate:
@@ -1380,9 +1442,52 @@ exit_mfg_deactivate:
BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
hdev->name);
+ btusb_check_bdaddr_intel(hdev);
+ return 0;
+}
+
+static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+ struct sk_buff *skb;
+ long ret;
+
+ skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: changing Intel device address failed (%ld)",
+ hdev->name, ret);
+ return ret;
+ }
+ kfree_skb(skb);
+
return 0;
}
+static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
+ const bdaddr_t *bdaddr)
+{
+ struct sk_buff *skb;
+ u8 buf[8];
+ long ret;
+
+ buf[0] = 0xfe;
+ buf[1] = sizeof(bdaddr_t);
+ memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));
+
+ skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: changing Marvell device address failed (%ld)",
+ hdev->name, ret);
+ return ret;
+ }
+ kfree_skb(skb);
+
+ return 0;
+}
+
+#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
+
static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
@@ -1396,6 +1501,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
u16 opcode;
struct sk_buff *skb;
struct hci_rp_read_local_version *ver;
+ struct hci_rp_read_bd_addr *bda;
long ret;
snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
@@ -1405,8 +1511,7 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
ret = request_firmware(&fw, fw_name, &hdev->dev);
if (ret < 0) {
- BT_INFO("%s: BCM: patch %s not found", hdev->name,
- fw_name);
+ BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
return 0;
}
@@ -1525,12 +1630,67 @@ reset_fw:
ver->lmp_ver, ver->lmp_subver);
kfree_skb(skb);
+ /* Read BD Address */
+ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+ HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: HCI_OP_READ_BD_ADDR failed (%ld)",
+ hdev->name, ret);
+ goto done;
+ }
+
+ if (skb->len != sizeof(*bda)) {
+ BT_ERR("%s: HCI_OP_READ_BD_ADDR event length mismatch",
+ hdev->name);
+ kfree_skb(skb);
+ ret = -EIO;
+ goto done;
+ }
+
+ bda = (struct hci_rp_read_bd_addr *) skb->data;
+ if (bda->status) {
+ BT_ERR("%s: HCI_OP_READ_BD_ADDR error status (%02x)",
+ hdev->name, bda->status);
+ kfree_skb(skb);
+ ret = -bt_to_errno(bda->status);
+ goto done;
+ }
+
+ /* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
+ * with no configured address.
+ */
+ if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
+ BT_INFO("%s: BCM: using default device address (%pMR)",
+ hdev->name, &bda->bdaddr);
+ set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
+ }
+
+ kfree_skb(skb);
+
done:
release_firmware(fw);
return ret;
}
+static int btusb_set_bdaddr_bcm(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+ struct sk_buff *skb;
+ long ret;
+
+ skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
+ if (IS_ERR(skb)) {
+ ret = PTR_ERR(skb);
+ BT_ERR("%s: BCM: Change address command failed (%ld)",
+ hdev->name, ret);
+ return ret;
+ }
+ kfree_skb(skb);
+
+ return 0;
+}
+
static int btusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -1555,15 +1715,6 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info == BTUSB_IGNORE)
return -ENODEV;
- if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
- return -ENODEV;
-
- if (ignore_csr && id->driver_info & BTUSB_CSR)
- return -ENODEV;
-
- if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
- return -ENODEV;
-
if (id->driver_info & BTUSB_ATH3012) {
struct usb_device *udev = interface_to_usbdev(intf);
@@ -1636,11 +1787,21 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
- if (id->driver_info & BTUSB_BCM_PATCHRAM)
+ if (id->driver_info & BTUSB_BCM_PATCHRAM) {
hdev->setup = btusb_setup_bcm_patchram;
+ hdev->set_bdaddr = btusb_set_bdaddr_bcm;
+ }
- if (id->driver_info & BTUSB_INTEL)
+ if (id->driver_info & BTUSB_INTEL) {
hdev->setup = btusb_setup_intel;
+ hdev->set_bdaddr = btusb_set_bdaddr_intel;
+ }
+
+ if (id->driver_info & BTUSB_MARVELL)
+ hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+
+ if (id->driver_info & BTUSB_INTEL_BOOT)
+ set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
@@ -1680,8 +1841,18 @@ static int btusb_probe(struct usb_interface *intf,
/* New sniffer firmware has crippled HCI interface */
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+ }
- data->isoc = NULL;
+ if (id->driver_info & BTUSB_INTEL_BOOT) {
+ /* A bug in the bootloader causes that interrupt interface is
+ * only enabled after receiving SetInterface(0, AltSetting=0).
+ */
+ err = usb_set_interface(data->udev, 0, 0);
+ if (err < 0) {
+ BT_ERR("failed to set interface 0, alt 0 %d", err);
+ hci_free_dev(hdev);
+ return err;
+ }
}
if (data->isoc) {
@@ -1846,15 +2017,6 @@ static struct usb_driver btusb_driver = {
module_usb_driver(btusb_driver);
-module_param(ignore_dga, bool, 0644);
-MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
-
-module_param(ignore_csr, bool, 0644);
-MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
-
-module_param(ignore_sniffer, bool, 0644);
-MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
-
module_param(disable_scofix, bool, 0644);
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 04680ead9275..caacb422995d 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -355,10 +355,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
static int h5_rx_crc(struct hci_uart *hu, unsigned char c)
{
- struct h5 *h5 = hu->priv;
-
h5_complete_rx_pkt(hu);
- h5_reset_rx(h5);
return 0;
}
@@ -373,7 +370,6 @@ static int h5_rx_payload(struct hci_uart *hu, unsigned char c)
h5->rx_pending = 2;
} else {
h5_complete_rx_pkt(hu);
- h5_reset_rx(h5);
}
return 0;
@@ -406,6 +402,7 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
BT_ERR("Non-link packet received in non-active state");
h5_reset_rx(h5);
+ return 0;
}
h5->rx_func = h5_rx_payload;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index e00f8f5b5c8e..dc487b5d1156 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -431,6 +431,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+ if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
+ set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
+
if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
@@ -477,6 +480,22 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
return 0;
}
+static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags)
+{
+ unsigned long valid_flags = BIT(HCI_UART_RAW_DEVICE) |
+ BIT(HCI_UART_RESET_ON_INIT) |
+ BIT(HCI_UART_CREATE_AMP) |
+ BIT(HCI_UART_INIT_PENDING) |
+ BIT(HCI_UART_EXT_CONFIG);
+
+ if ((flags & ~valid_flags))
+ return -EINVAL;
+
+ hu->hdev_flags = flags;
+
+ return 0;
+}
+
/* hci_uart_tty_ioctl()
*
* Process IOCTL system call for the tty device.
@@ -520,14 +539,16 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
return -EUNATCH;
case HCIUARTGETDEVICE:
- if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
+ if (test_bit(HCI_UART_REGISTERED, &hu->flags))
return hu->hdev->id;
return -EUNATCH;
case HCIUARTSETFLAGS:
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
return -EBUSY;
- hu->hdev_flags = arg;
+ err = hci_uart_set_flags(hu, arg);
+ if (err)
+ return err;
break;
case HCIUARTGETFLAGS:
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 12df101ca942..247488edcbf9 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -48,6 +48,7 @@
#define HCI_UART_RESET_ON_INIT 1
#define HCI_UART_CREATE_AMP 2
#define HCI_UART_INIT_PENDING 3
+#define HCI_UART_EXT_CONFIG 4
struct hci_uart;
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index add1c6a72063..5bb5872ffee6 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -40,7 +40,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-#define VERSION "1.4"
+#define VERSION "1.5"
static bool amp;
@@ -95,10 +95,21 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}
-static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
+static int vhci_create_device(struct vhci_data *data, __u8 opcode)
{
struct hci_dev *hdev;
struct sk_buff *skb;
+ __u8 dev_type;
+
+ /* bits 0-1 are dev_type (BR/EDR or AMP) */
+ dev_type = opcode & 0x03;
+
+ if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
+ return -EINVAL;
+
+ /* bits 2-5 are reserved (must be zero) */
+ if (opcode & 0x3c)
+ return -EINVAL;
skb = bt_skb_alloc(4, GFP_KERNEL);
if (!skb)
@@ -121,6 +132,14 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
hdev->flush = vhci_flush;
hdev->send = vhci_send_frame;
+ /* bit 6 is for external configuration */
+ if (opcode & 0x40)
+ set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
+
+ /* bit 7 is for raw device */
+ if (opcode & 0x80)
+ set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
@@ -132,7 +151,7 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
*skb_put(skb, 1) = 0xff;
- *skb_put(skb, 1) = dev_type;
+ *skb_put(skb, 1) = opcode;
put_unaligned_le16(hdev->id, skb_put(skb, 2));
skb_queue_tail(&data->readq, skb);
@@ -146,7 +165,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
{
size_t len = iov_length(iov, count);
struct sk_buff *skb;
- __u8 pkt_type, dev_type;
+ __u8 pkt_type, opcode;
unsigned long i;
int ret;
@@ -190,7 +209,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
cancel_delayed_work_sync(&data->open_timeout);
- dev_type = *((__u8 *) skb->data);
+ opcode = *((__u8 *) skb->data);
skb_pull(skb, 1);
if (skb->len > 0) {
@@ -200,10 +219,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
kfree_skb(skb);
- if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
- return -EINVAL;
-
- ret = vhci_create_device(data, dev_type);
+ ret = vhci_create_device(data, opcode);
break;
default:
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 5a86da97a70b..7af78df241f2 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -397,7 +397,8 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev)
hw_counter = &event->hw;
/* Did this counter overflow? */
- if (!pmu_read_register(idx, CCI_PMU_OVRFLW) & CCI_PMU_OVRFLW_FLAG)
+ if (!(pmu_read_register(idx, CCI_PMU_OVRFLW) &
+ CCI_PMU_OVRFLW_FLAG))
continue;
pmu_write_register(CCI_PMU_OVRFLW_FLAG, idx, CCI_PMU_OVRFLW);
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
index 6159b7752a64..f2cd6a2d40b4 100644
--- a/drivers/bus/brcmstb_gisb.c
+++ b/drivers/bus/brcmstb_gisb.c
@@ -212,9 +212,9 @@ static int brcmstb_gisb_arb_probe(struct platform_device *pdev)
mutex_init(&gdev->lock);
INIT_LIST_HEAD(&gdev->next);
- gdev->base = devm_request_and_ioremap(&pdev->dev, r);
- if (!gdev->base)
- return -ENOMEM;
+ gdev->base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(gdev->base))
+ return PTR_ERR(gdev->base);
err = devm_request_irq(&pdev->dev, timeout_irq,
brcmstb_gisb_timeout_handler, 0, pdev->name,
diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
index f8ee13c7bf7b..75c9681f8021 100644
--- a/drivers/bus/imx-weim.c
+++ b/drivers/bus/imx-weim.c
@@ -162,7 +162,9 @@ static int __init weim_parse_dt(struct platform_device *pdev,
}
}
- ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ ret = of_platform_populate(pdev->dev.of_node,
+ of_default_bus_match_table,
+ NULL, &pdev->dev);
if (ret)
dev_err(&pdev->dev, "%s fail to create devices.\n",
pdev->dev.of_node->full_name);
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index b29703324e94..09f17eb73486 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -710,19 +710,6 @@ static int agp_open(struct inode *inode, struct file *file)
return 0;
}
-
-static ssize_t agp_read(struct file *file, char __user *buf,
- size_t count, loff_t * ppos)
-{
- return -EINVAL;
-}
-
-static ssize_t agp_write(struct file *file, const char __user *buf,
- size_t count, loff_t * ppos)
-{
- return -EINVAL;
-}
-
static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg)
{
struct agp_info userinfo;
@@ -1047,8 +1034,6 @@ static const struct file_operations agp_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
- .read = agp_read,
- .write = agp_write,
.unlocked_ioctl = agp_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_agp_ioctl,
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index 8fedbc250414..a6cef548e01e 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -259,7 +259,7 @@ static int bsr_add_node(struct device_node *bn)
}
cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev,
- cur, cur->bsr_name);
+ cur, "%s", cur->bsr_name);
if (IS_ERR(cur->bsr_device)) {
printk(KERN_ERR "device_create failed for %s\n",
cur->bsr_name);
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 01a5ca7425d7..8bf70e8c3f79 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -383,7 +383,7 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd,
return put_user(status, &hf->status);
}
case DSP56K_HOST_CMD:
- if (arg > 31 || arg < 0)
+ if (arg > 31)
return -EINVAL;
mutex_lock(&dsp56k_mutex);
dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index f953c96efc86..ebc4c73d8ca4 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -49,7 +49,7 @@
#include <asm/uaccess.h>
#include <linux/sysrq.h>
#include <linux/timer.h>
-#include <linux/time.h>
+#include <linux/hrtimer.h>
#define VERSION_STR "0.9.1"
@@ -117,24 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot);
__setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
#endif /* not MODULE */
-#if defined(CONFIG_S390)
-# define HAVE_MONOTONIC
-# define TIMER_FREQ 1000000000ULL
-#else
-# define TIMER_FREQ 1000000000ULL
-#endif
-
-#ifdef HAVE_MONOTONIC
-extern unsigned long long monotonic_clock(void);
-#else
-static inline unsigned long long monotonic_clock(void)
-{
- struct timespec ts;
- getrawmonotonic(&ts);
- return timespec_to_ns(&ts);
-}
-#endif /* HAVE_MONOTONIC */
-
+#define TIMER_FREQ 1000000000ULL
/* Last time scheduled */
static unsigned long long hangcheck_tsc, hangcheck_tsc_margin;
@@ -143,12 +126,11 @@ static void hangcheck_fire(unsigned long);
static DEFINE_TIMER(hangcheck_ticktock, hangcheck_fire, 0, 0);
-
static void hangcheck_fire(unsigned long data)
{
unsigned long long cur_tsc, tsc_diff;
- cur_tsc = monotonic_clock();
+ cur_tsc = ktime_get_ns();
if (cur_tsc > hangcheck_tsc)
tsc_diff = cur_tsc - hangcheck_tsc;
@@ -177,7 +159,7 @@ static void hangcheck_fire(unsigned long data)
tsc_diff, tsc_diff - hangcheck_tick*TIMER_FREQ);
#endif
mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ));
- hangcheck_tsc = monotonic_clock();
+ hangcheck_tsc = ktime_get_ns();
}
@@ -185,16 +167,11 @@ static int __init hangcheck_init(void)
{
printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n",
VERSION_STR, hangcheck_tick, hangcheck_margin);
-#if defined (HAVE_MONOTONIC)
- printk("Hangcheck: Using monotonic_clock().\n");
-#else
- printk("Hangcheck: Using getrawmonotonic().\n");
-#endif /* HAVE_MONOTONIC */
hangcheck_tsc_margin =
(unsigned long long)(hangcheck_margin + hangcheck_tick);
hangcheck_tsc_margin *= (unsigned long long)TIMER_FREQ;
- hangcheck_tsc = monotonic_clock();
+ hangcheck_tsc = ktime_get_ns();
mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ));
return 0;
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 334601cc81cf..6e02ec103cc7 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -38,6 +38,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
+#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/random.h>
@@ -50,21 +51,67 @@
static struct hwrng *current_rng;
+static struct task_struct *hwrng_fill;
static LIST_HEAD(rng_list);
static DEFINE_MUTEX(rng_mutex);
static int data_avail;
-static u8 *rng_buffer;
+static u8 *rng_buffer, *rng_fillbuf;
+static unsigned short current_quality;
+static unsigned short default_quality; /* = 0; default to "off" */
+
+module_param(current_quality, ushort, 0644);
+MODULE_PARM_DESC(current_quality,
+ "current hwrng entropy estimation per mill");
+module_param(default_quality, ushort, 0644);
+MODULE_PARM_DESC(default_quality,
+ "default entropy content of hwrng per mill");
+
+static void start_khwrngd(void);
+
+static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
+ int wait);
static size_t rng_buffer_size(void)
{
return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
}
+static void add_early_randomness(struct hwrng *rng)
+{
+ unsigned char bytes[16];
+ int bytes_read;
+
+ /*
+ * Currently only virtio-rng cannot return data during device
+ * probe, and that's handled in virtio-rng.c itself. If there
+ * are more such devices, this call to rng_get_data can be
+ * made conditional here instead of doing it per-device.
+ */
+ bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
+ if (bytes_read > 0)
+ add_device_randomness(bytes, bytes_read);
+}
+
static inline int hwrng_init(struct hwrng *rng)
{
- if (!rng->init)
- return 0;
- return rng->init(rng);
+ if (rng->init) {
+ int ret;
+
+ ret = rng->init(rng);
+ if (ret)
+ return ret;
+ }
+ add_early_randomness(rng);
+
+ current_quality = rng->quality ? : default_quality;
+ current_quality &= 1023;
+
+ if (current_quality == 0 && hwrng_fill)
+ kthread_stop(hwrng_fill);
+ if (current_quality > 0 && !hwrng_fill)
+ start_khwrngd();
+
+ return 0;
}
static inline void hwrng_cleanup(struct hwrng *rng)
@@ -300,12 +347,40 @@ err_misc_dereg:
goto out;
}
+static int hwrng_fillfn(void *unused)
+{
+ long rc;
+
+ while (!kthread_should_stop()) {
+ if (!current_rng)
+ break;
+ rc = rng_get_data(current_rng, rng_fillbuf,
+ rng_buffer_size(), 1);
+ if (rc <= 0) {
+ pr_warn("hwrng: no data available\n");
+ msleep_interruptible(10000);
+ continue;
+ }
+ add_hwgenerator_randomness((void *)rng_fillbuf, rc,
+ rc * current_quality * 8 >> 10);
+ }
+ hwrng_fill = NULL;
+ return 0;
+}
+
+static void start_khwrngd(void)
+{
+ hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
+ if (hwrng_fill == ERR_PTR(-ENOMEM)) {
+ pr_err("hwrng_fill thread creation failed");
+ hwrng_fill = NULL;
+ }
+}
+
int hwrng_register(struct hwrng *rng)
{
int err = -EINVAL;
struct hwrng *old_rng, *tmp;
- unsigned char bytes[16];
- int bytes_read;
if (rng->name == NULL ||
(rng->data_read == NULL && rng->read == NULL))
@@ -320,6 +395,13 @@ int hwrng_register(struct hwrng *rng)
if (!rng_buffer)
goto out_unlock;
}
+ if (!rng_fillbuf) {
+ rng_fillbuf = kmalloc(rng_buffer_size(), GFP_KERNEL);
+ if (!rng_fillbuf) {
+ kfree(rng_buffer);
+ goto out_unlock;
+ }
+ }
/* Must not register two RNGs with the same name. */
err = -EEXIST;
@@ -347,9 +429,17 @@ int hwrng_register(struct hwrng *rng)
INIT_LIST_HEAD(&rng->list);
list_add_tail(&rng->list, &rng_list);
- bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
- if (bytes_read > 0)
- add_device_randomness(bytes, bytes_read);
+ if (old_rng && !rng->init) {
+ /*
+ * Use a new device's input to add some randomness to
+ * the system. If this rng device isn't going to be
+ * used right away, its init function hasn't been
+ * called yet; so only use the randomness from devices
+ * that don't need an init callback.
+ */
+ add_early_randomness(rng);
+ }
+
out_unlock:
mutex_unlock(&rng_mutex);
out:
@@ -375,8 +465,11 @@ void hwrng_unregister(struct hwrng *rng)
current_rng = NULL;
}
}
- if (list_empty(&rng_list))
+ if (list_empty(&rng_list)) {
unregister_miscdev();
+ if (hwrng_fill)
+ kthread_stop(hwrng_fill);
+ }
mutex_unlock(&rng_mutex);
}
@@ -387,6 +480,7 @@ static void __exit hwrng_exit(void)
mutex_lock(&rng_mutex);
BUG_ON(current_rng);
kfree(rng_buffer);
+ kfree(rng_fillbuf);
mutex_unlock(&rng_mutex);
}
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index f3e71501de54..e9b15bc18b4d 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -38,6 +38,8 @@ struct virtrng_info {
int index;
};
+static bool probe_done;
+
static void random_recv_done(struct virtqueue *vq)
{
struct virtrng_info *vi = vq->vdev->priv;
@@ -67,6 +69,13 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
int ret;
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+ /*
+ * Don't ask host for data till we're setup. This call can
+ * happen during hwrng_register(), after commit d9e7972619.
+ */
+ if (unlikely(!probe_done))
+ return 0;
+
if (!vi->busy) {
vi->busy = true;
init_completion(&vi->have_data);
@@ -137,6 +146,7 @@ static int probe_common(struct virtio_device *vdev)
return err;
}
+ probe_done = true;
return 0;
}
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index d915707d2ba1..65525c7e903c 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -65,6 +65,8 @@ static char bios_version[4];
static struct device *i8k_hwmon_dev;
static u32 i8k_hwmon_flags;
static int i8k_fan_mult;
+static int i8k_pwm_mult;
+static int i8k_fan_max = I8K_FAN_HIGH;
#define I8K_HWMON_HAVE_TEMP1 (1 << 0)
#define I8K_HWMON_HAVE_TEMP2 (1 << 1)
@@ -97,6 +99,10 @@ static int fan_mult = I8K_FAN_MULT;
module_param(fan_mult, int, 0);
MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with");
+static int fan_max = I8K_FAN_HIGH;
+module_param(fan_max, int, 0);
+MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed");
+
static int i8k_open_fs(struct inode *inode, struct file *file);
static long i8k_ioctl(struct file *, unsigned int, unsigned long);
@@ -138,7 +144,9 @@ static int i8k_smm(struct smm_regs *regs)
if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
return -ENOMEM;
cpumask_copy(old_mask, &current->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(0));
+ rc = set_cpus_allowed_ptr(current, cpumask_of(0));
+ if (rc)
+ goto out;
if (smp_processor_id() != 0) {
rc = -EBUSY;
goto out;
@@ -274,7 +282,7 @@ static int i8k_set_fan(int fan, int speed)
{
struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
- speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+ speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed);
regs.ebx = (fan & 0xff) | (speed << 8);
return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
@@ -519,7 +527,7 @@ static ssize_t i8k_hwmon_show_pwm(struct device *dev,
status = i8k_get_fan_status(index);
if (status < 0)
return -EIO;
- return sprintf(buf, "%d\n", clamp_val(status * 128, 0, 255));
+ return sprintf(buf, "%d\n", clamp_val(status * i8k_pwm_mult, 0, 255));
}
static ssize_t i8k_hwmon_set_pwm(struct device *dev,
@@ -533,7 +541,7 @@ static ssize_t i8k_hwmon_set_pwm(struct device *dev,
err = kstrtoul(buf, 10, &val);
if (err)
return err;
- val = clamp_val(DIV_ROUND_CLOSEST(val, 128), 0, 2);
+ val = clamp_val(DIV_ROUND_CLOSEST(val, i8k_pwm_mult), 0, i8k_fan_max);
mutex_lock(&i8k_mutex);
err = i8k_set_fan(index, val);
@@ -542,20 +550,6 @@ static ssize_t i8k_hwmon_set_pwm(struct device *dev,
return err < 0 ? -EIO : count;
}
-static ssize_t i8k_hwmon_show_label(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- static const char *labels[3] = {
- "CPU",
- "Left Fan",
- "Right Fan",
- };
- int index = to_sensor_dev_attr(devattr)->index;
-
- return sprintf(buf, "%s\n", labels[index]);
-}
-
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
@@ -568,41 +562,34 @@ static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
I8K_FAN_RIGHT);
static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
i8k_hwmon_set_pwm, I8K_FAN_RIGHT);
-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
static struct attribute *i8k_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */
- &sensor_dev_attr_temp1_label.dev_attr.attr, /* 1 */
- &sensor_dev_attr_temp2_input.dev_attr.attr, /* 2 */
- &sensor_dev_attr_temp3_input.dev_attr.attr, /* 3 */
- &sensor_dev_attr_temp4_input.dev_attr.attr, /* 4 */
- &sensor_dev_attr_fan1_input.dev_attr.attr, /* 5 */
- &sensor_dev_attr_pwm1.dev_attr.attr, /* 6 */
- &sensor_dev_attr_fan1_label.dev_attr.attr, /* 7 */
- &sensor_dev_attr_fan2_input.dev_attr.attr, /* 8 */
- &sensor_dev_attr_pwm2.dev_attr.attr, /* 9 */
- &sensor_dev_attr_fan2_label.dev_attr.attr, /* 10 */
+ &sensor_dev_attr_temp2_input.dev_attr.attr, /* 1 */
+ &sensor_dev_attr_temp3_input.dev_attr.attr, /* 2 */
+ &sensor_dev_attr_temp4_input.dev_attr.attr, /* 3 */
+ &sensor_dev_attr_fan1_input.dev_attr.attr, /* 4 */
+ &sensor_dev_attr_pwm1.dev_attr.attr, /* 5 */
+ &sensor_dev_attr_fan2_input.dev_attr.attr, /* 6 */
+ &sensor_dev_attr_pwm2.dev_attr.attr, /* 7 */
NULL
};
static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
int index)
{
- if ((index == 0 || index == 1) &&
- !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
+ if (index == 0 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
return 0;
- if (index == 2 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
+ if (index == 1 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
return 0;
- if (index == 3 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
+ if (index == 2 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
return 0;
- if (index == 4 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
+ if (index == 3 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
return 0;
- if (index >= 5 && index <= 7 &&
+ if (index >= 4 && index <= 5 &&
!(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
return 0;
- if (index >= 8 && index <= 10 &&
+ if (index >= 6 && index <= 7 &&
!(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
return 0;
@@ -657,6 +644,37 @@ static int __init i8k_init_hwmon(void)
return 0;
}
+struct i8k_config_data {
+ int fan_mult;
+ int fan_max;
+};
+
+enum i8k_configs {
+ DELL_LATITUDE_D520,
+ DELL_PRECISION_490,
+ DELL_STUDIO,
+ DELL_XPS_M140,
+};
+
+static const struct i8k_config_data i8k_config_data[] = {
+ [DELL_LATITUDE_D520] = {
+ .fan_mult = 1,
+ .fan_max = I8K_FAN_TURBO,
+ },
+ [DELL_PRECISION_490] = {
+ .fan_mult = 1,
+ .fan_max = I8K_FAN_TURBO,
+ },
+ [DELL_STUDIO] = {
+ .fan_mult = 1,
+ .fan_max = I8K_FAN_HIGH,
+ },
+ [DELL_XPS_M140] = {
+ .fan_mult = 1,
+ .fan_max = I8K_FAN_HIGH,
+ },
+};
+
static struct dmi_system_id i8k_dmi_table[] __initdata = {
{
.ident = "Dell Inspiron",
@@ -680,6 +698,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
},
},
{
+ .ident = "Dell Latitude D520",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"),
+ },
+ .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520],
+ },
+ {
.ident = "Dell Latitude 2",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
@@ -701,6 +727,15 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
},
},
{
+ .ident = "Dell Precision 490",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME,
+ "Precision WorkStation 490"),
+ },
+ .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490],
+ },
+ {
.ident = "Dell Precision",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
@@ -727,7 +762,7 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
},
- .driver_data = (void *)1, /* fan multiplier override */
+ .driver_data = (void *)&i8k_config_data[DELL_STUDIO],
},
{
.ident = "Dell XPS M140",
@@ -735,7 +770,7 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
},
- .driver_data = (void *)1, /* fan multiplier override */
+ .driver_data = (void *)&i8k_config_data[DELL_XPS_M140],
},
{ }
};
@@ -775,9 +810,17 @@ static int __init i8k_probe(void)
}
i8k_fan_mult = fan_mult;
+ i8k_fan_max = fan_max ? : I8K_FAN_HIGH; /* Must not be 0 */
id = dmi_first_match(i8k_dmi_table);
- if (id && fan_mult == I8K_FAN_MULT && id->driver_data)
- i8k_fan_mult = (unsigned long)id->driver_data;
+ if (id && id->driver_data) {
+ const struct i8k_config_data *conf = id->driver_data;
+
+ if (fan_mult == I8K_FAN_MULT && conf->fan_mult)
+ i8k_fan_mult = conf->fan_mult;
+ if (fan_max == I8K_FAN_HIGH && conf->fan_max)
+ i8k_fan_max = conf->fan_max;
+ }
+ i8k_pwm_mult = DIV_ROUND_UP(255, i8k_fan_max);
return 0;
}
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 8320abd1ef14..0ea9986059af 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2347,8 +2347,6 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp)
printk("%s(%d):mgslpc_close(%s) entry, count=%d\n",
__FILE__, __LINE__, info->device_name, port->count);
- WARN_ON(!port->count);
-
if (tty_port_close_start(port, tty, filp) == 0)
goto cleanup;
@@ -2510,7 +2508,7 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp)
__FILE__, __LINE__, tty->driver->name, port->count);
/* If port is closing, signal caller to try again */
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING){
+ if (port->flags & ASYNC_CLOSING){
wait_event_interruptible_tty(tty, port->close_wait,
!(port->flags & ASYNC_CLOSING));
retval = ((port->flags & ASYNC_HUP_NOTIFY) ?
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0a7ac0a7b252..c18d41db83d8 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -250,6 +250,7 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
+#include <linux/kthread.h>
#include <linux/percpu.h>
#include <linux/cryptohash.h>
#include <linux/fips.h>
@@ -257,6 +258,8 @@
#include <linux/kmemcheck.h>
#include <linux/workqueue.h>
#include <linux/irq.h>
+#include <linux/syscalls.h>
+#include <linux/completion.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
@@ -267,6 +270,8 @@
#define CREATE_TRACE_POINTS
#include <trace/events/random.h>
+/* #define ADD_INTERRUPT_BENCH */
+
/*
* Configuration information
*/
@@ -401,6 +406,7 @@ static struct poolinfo {
*/
static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+static DECLARE_WAIT_QUEUE_HEAD(urandom_init_wait);
static struct fasync_struct *fasync;
/**********************************************************************
@@ -481,9 +487,9 @@ static __u32 const twist_table[8] = {
* the entropy is concentrated in the low-order bits.
*/
static void _mix_pool_bytes(struct entropy_store *r, const void *in,
- int nbytes, __u8 out[64])
+ int nbytes)
{
- unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
+ unsigned long i, tap1, tap2, tap3, tap4, tap5;
int input_rotate;
int wordmask = r->poolinfo->poolwords - 1;
const char *bytes = in;
@@ -495,9 +501,8 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in,
tap4 = r->poolinfo->tap4;
tap5 = r->poolinfo->tap5;
- smp_rmb();
- input_rotate = ACCESS_ONCE(r->input_rotate);
- i = ACCESS_ONCE(r->add_ptr);
+ input_rotate = r->input_rotate;
+ i = r->add_ptr;
/* mix one byte at a time to simplify size handling and churn faster */
while (nbytes--) {
@@ -524,39 +529,33 @@ static void _mix_pool_bytes(struct entropy_store *r, const void *in,
input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
}
- ACCESS_ONCE(r->input_rotate) = input_rotate;
- ACCESS_ONCE(r->add_ptr) = i;
- smp_wmb();
-
- if (out)
- for (j = 0; j < 16; j++)
- ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
+ r->input_rotate = input_rotate;
+ r->add_ptr = i;
}
static void __mix_pool_bytes(struct entropy_store *r, const void *in,
- int nbytes, __u8 out[64])
+ int nbytes)
{
trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_);
- _mix_pool_bytes(r, in, nbytes, out);
+ _mix_pool_bytes(r, in, nbytes);
}
static void mix_pool_bytes(struct entropy_store *r, const void *in,
- int nbytes, __u8 out[64])
+ int nbytes)
{
unsigned long flags;
trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
spin_lock_irqsave(&r->lock, flags);
- _mix_pool_bytes(r, in, nbytes, out);
+ _mix_pool_bytes(r, in, nbytes);
spin_unlock_irqrestore(&r->lock, flags);
}
struct fast_pool {
__u32 pool[4];
unsigned long last;
- unsigned short count;
- unsigned char rotate;
- unsigned char last_timer_intr;
+ unsigned short reg_idx;
+ unsigned char count;
};
/*
@@ -564,25 +563,29 @@ struct fast_pool {
* collector. It's hardcoded for an 128 bit pool and assumes that any
* locks that might be needed are taken by the caller.
*/
-static void fast_mix(struct fast_pool *f, __u32 input[4])
+static void fast_mix(struct fast_pool *f)
{
- __u32 w;
- unsigned input_rotate = f->rotate;
-
- w = rol32(input[0], input_rotate) ^ f->pool[0] ^ f->pool[3];
- f->pool[0] = (w >> 3) ^ twist_table[w & 7];
- input_rotate = (input_rotate + 14) & 31;
- w = rol32(input[1], input_rotate) ^ f->pool[1] ^ f->pool[0];
- f->pool[1] = (w >> 3) ^ twist_table[w & 7];
- input_rotate = (input_rotate + 7) & 31;
- w = rol32(input[2], input_rotate) ^ f->pool[2] ^ f->pool[1];
- f->pool[2] = (w >> 3) ^ twist_table[w & 7];
- input_rotate = (input_rotate + 7) & 31;
- w = rol32(input[3], input_rotate) ^ f->pool[3] ^ f->pool[2];
- f->pool[3] = (w >> 3) ^ twist_table[w & 7];
- input_rotate = (input_rotate + 7) & 31;
-
- f->rotate = input_rotate;
+ __u32 a = f->pool[0], b = f->pool[1];
+ __u32 c = f->pool[2], d = f->pool[3];
+
+ a += b; c += d;
+ b = rol32(a, 6); d = rol32(c, 27);
+ d ^= a; b ^= c;
+
+ a += b; c += d;
+ b = rol32(a, 16); d = rol32(c, 14);
+ d ^= a; b ^= c;
+
+ a += b; c += d;
+ b = rol32(a, 6); d = rol32(c, 27);
+ d ^= a; b ^= c;
+
+ a += b; c += d;
+ b = rol32(a, 16); d = rol32(c, 14);
+ d ^= a; b ^= c;
+
+ f->pool[0] = a; f->pool[1] = b;
+ f->pool[2] = c; f->pool[3] = d;
f->count++;
}
@@ -641,7 +644,7 @@ retry:
} while (unlikely(entropy_count < pool_size-2 && pnfrac));
}
- if (entropy_count < 0) {
+ if (unlikely(entropy_count < 0)) {
pr_warn("random: negative entropy/overflow: pool %s count %d\n",
r->name, entropy_count);
WARN_ON(1);
@@ -657,6 +660,7 @@ retry:
r->entropy_total = 0;
if (r == &nonblocking_pool) {
prandom_reseed_late();
+ wake_up_interruptible(&urandom_init_wait);
pr_notice("random: %s pool is initialized\n", r->name);
}
}
@@ -739,13 +743,13 @@ void add_device_randomness(const void *buf, unsigned int size)
trace_add_device_randomness(size, _RET_IP_);
spin_lock_irqsave(&input_pool.lock, flags);
- _mix_pool_bytes(&input_pool, buf, size, NULL);
- _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
+ _mix_pool_bytes(&input_pool, buf, size);
+ _mix_pool_bytes(&input_pool, &time, sizeof(time));
spin_unlock_irqrestore(&input_pool.lock, flags);
spin_lock_irqsave(&nonblocking_pool.lock, flags);
- _mix_pool_bytes(&nonblocking_pool, buf, size, NULL);
- _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL);
+ _mix_pool_bytes(&nonblocking_pool, buf, size);
+ _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time));
spin_unlock_irqrestore(&nonblocking_pool.lock, flags);
}
EXPORT_SYMBOL(add_device_randomness);
@@ -778,7 +782,7 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
sample.cycles = random_get_entropy();
sample.num = num;
r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
- mix_pool_bytes(r, &sample, sizeof(sample), NULL);
+ mix_pool_bytes(r, &sample, sizeof(sample));
/*
* Calculate number of bits of randomness we probably added.
@@ -835,6 +839,38 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
static DEFINE_PER_CPU(struct fast_pool, irq_randomness);
+#ifdef ADD_INTERRUPT_BENCH
+static unsigned long avg_cycles, avg_deviation;
+
+#define AVG_SHIFT 8 /* Exponential average factor k=1/256 */
+#define FIXED_1_2 (1 << (AVG_SHIFT-1))
+
+static void add_interrupt_bench(cycles_t start)
+{
+ long delta = random_get_entropy() - start;
+
+ /* Use a weighted moving average */
+ delta = delta - ((avg_cycles + FIXED_1_2) >> AVG_SHIFT);
+ avg_cycles += delta;
+ /* And average deviation */
+ delta = abs(delta) - ((avg_deviation + FIXED_1_2) >> AVG_SHIFT);
+ avg_deviation += delta;
+}
+#else
+#define add_interrupt_bench(x)
+#endif
+
+static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs)
+{
+ __u32 *ptr = (__u32 *) regs;
+
+ if (regs == NULL)
+ return 0;
+ if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32))
+ f->reg_idx = 0;
+ return *(ptr + f->reg_idx++);
+}
+
void add_interrupt_randomness(int irq, int irq_flags)
{
struct entropy_store *r;
@@ -842,55 +878,52 @@ void add_interrupt_randomness(int irq, int irq_flags)
struct pt_regs *regs = get_irq_regs();
unsigned long now = jiffies;
cycles_t cycles = random_get_entropy();
- __u32 input[4], c_high, j_high;
+ __u32 c_high, j_high;
__u64 ip;
unsigned long seed;
- int credit;
+ int credit = 0;
+ if (cycles == 0)
+ cycles = get_reg(fast_pool, regs);
c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
j_high = (sizeof(now) > 4) ? now >> 32 : 0;
- input[0] = cycles ^ j_high ^ irq;
- input[1] = now ^ c_high;
+ fast_pool->pool[0] ^= cycles ^ j_high ^ irq;
+ fast_pool->pool[1] ^= now ^ c_high;
ip = regs ? instruction_pointer(regs) : _RET_IP_;
- input[2] = ip;
- input[3] = ip >> 32;
+ fast_pool->pool[2] ^= ip;
+ fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 :
+ get_reg(fast_pool, regs);
- fast_mix(fast_pool, input);
+ fast_mix(fast_pool);
+ add_interrupt_bench(cycles);
- if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ))
+ if ((fast_pool->count < 64) &&
+ !time_after(now, fast_pool->last + HZ))
return;
- fast_pool->last = now;
-
r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
- __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool), NULL);
+ if (!spin_trylock(&r->lock))
+ return;
- /*
- * If we don't have a valid cycle counter, and we see
- * back-to-back timer interrupts, then skip giving credit for
- * any entropy, otherwise credit 1 bit.
- */
- credit = 1;
- if (cycles == 0) {
- if (irq_flags & __IRQF_TIMER) {
- if (fast_pool->last_timer_intr)
- credit = 0;
- fast_pool->last_timer_intr = 1;
- } else
- fast_pool->last_timer_intr = 0;
- }
+ fast_pool->last = now;
+ __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool));
/*
* If we have architectural seed generator, produce a seed and
- * add it to the pool. For the sake of paranoia count it as
- * 50% entropic.
+ * add it to the pool. For the sake of paranoia don't let the
+ * architectural seed generator dominate the input from the
+ * interrupt noise.
*/
if (arch_get_random_seed_long(&seed)) {
- __mix_pool_bytes(r, &seed, sizeof(seed), NULL);
- credit += sizeof(seed) * 4;
+ __mix_pool_bytes(r, &seed, sizeof(seed));
+ credit = 1;
}
+ spin_unlock(&r->lock);
+
+ fast_pool->count = 0;
- credit_entropy_bits(r, credit);
+ /* award one bit for the contents of the fast pool */
+ credit_entropy_bits(r, credit + 1);
}
#ifdef CONFIG_BLOCK
@@ -922,6 +955,11 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes);
static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
{
+ if (!r->pull ||
+ r->entropy_count >= (nbytes << (ENTROPY_SHIFT + 3)) ||
+ r->entropy_count > r->poolinfo->poolfracbits)
+ return;
+
if (r->limit == 0 && random_min_urandom_seed) {
unsigned long now = jiffies;
@@ -930,10 +968,8 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
return;
r->last_pulled = now;
}
- if (r->pull &&
- r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) &&
- r->entropy_count < r->poolinfo->poolfracbits)
- _xfer_secondary_pool(r, nbytes);
+
+ _xfer_secondary_pool(r, nbytes);
}
static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
@@ -953,7 +989,7 @@ static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
bytes = extract_entropy(r->pull, tmp, bytes,
random_read_wakeup_bits / 8, rsvd_bytes);
- mix_pool_bytes(r, tmp, bytes, NULL);
+ mix_pool_bytes(r, tmp, bytes);
credit_entropy_bits(r, bytes*8);
}
@@ -981,7 +1017,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
int reserved)
{
int entropy_count, orig;
- size_t ibytes;
+ size_t ibytes, nfrac;
BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
@@ -999,7 +1035,17 @@ retry:
}
if (ibytes < min)
ibytes = 0;
- if ((entropy_count -= ibytes << (ENTROPY_SHIFT + 3)) < 0)
+
+ if (unlikely(entropy_count < 0)) {
+ pr_warn("random: negative entropy count: pool %s count %d\n",
+ r->name, entropy_count);
+ WARN_ON(1);
+ entropy_count = 0;
+ }
+ nfrac = ibytes << (ENTROPY_SHIFT + 3);
+ if ((size_t) entropy_count > nfrac)
+ entropy_count -= nfrac;
+ else
entropy_count = 0;
if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
@@ -1029,7 +1075,6 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
unsigned long l[LONGS(20)];
} hash;
__u32 workspace[SHA_WORKSPACE_WORDS];
- __u8 extract[64];
unsigned long flags;
/*
@@ -1058,15 +1103,9 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
* brute-forcing the feedback as hard as brute-forcing the
* hash.
*/
- __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract);
+ __mix_pool_bytes(r, hash.w, sizeof(hash.w));
spin_unlock_irqrestore(&r->lock, flags);
- /*
- * To avoid duplicates, we atomically extract a portion of the
- * pool while mixing, and hash one final time.
- */
- sha_transform(hash.w, extract, workspace);
- memset(extract, 0, sizeof(extract));
memset(workspace, 0, sizeof(workspace));
/*
@@ -1150,13 +1189,14 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
{
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
+ int large_request = (nbytes > 256);
trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, 0, 0);
while (nbytes) {
- if (need_resched()) {
+ if (large_request && need_resched()) {
if (signal_pending(current)) {
if (ret == 0)
ret = -ERESTARTSYS;
@@ -1253,14 +1293,14 @@ static void init_std_data(struct entropy_store *r)
unsigned long rv;
r->last_pulled = jiffies;
- mix_pool_bytes(r, &now, sizeof(now), NULL);
+ mix_pool_bytes(r, &now, sizeof(now));
for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_seed_long(&rv) &&
!arch_get_random_long(&rv))
rv = random_get_entropy();
- mix_pool_bytes(r, &rv, sizeof(rv), NULL);
+ mix_pool_bytes(r, &rv, sizeof(rv));
}
- mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
+ mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
}
/*
@@ -1299,39 +1339,8 @@ void rand_initialize_disk(struct gendisk *disk)
}
#endif
-/*
- * Attempt an emergency refill using arch_get_random_seed_long().
- *
- * As with add_interrupt_randomness() be paranoid and only
- * credit the output as 50% entropic.
- */
-static int arch_random_refill(void)
-{
- const unsigned int nlongs = 64; /* Arbitrary number */
- unsigned int n = 0;
- unsigned int i;
- unsigned long buf[nlongs];
-
- if (!arch_has_random_seed())
- return 0;
-
- for (i = 0; i < nlongs; i++) {
- if (arch_get_random_seed_long(&buf[n]))
- n++;
- }
-
- if (n) {
- unsigned int rand_bytes = n * sizeof(unsigned long);
-
- mix_pool_bytes(&input_pool, buf, rand_bytes, NULL);
- credit_entropy_bits(&input_pool, rand_bytes*4);
- }
-
- return n;
-}
-
static ssize_t
-random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+_random_read(int nonblock, char __user *buf, size_t nbytes)
{
ssize_t n;
@@ -1350,12 +1359,7 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
return n;
/* Pool is (near) empty. Maybe wait and retry. */
-
- /* First try an emergency refill */
- if (arch_random_refill())
- continue;
-
- if (file->f_flags & O_NONBLOCK)
+ if (nonblock)
return -EAGAIN;
wait_event_interruptible(random_read_wait,
@@ -1367,6 +1371,12 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
}
static ssize_t
+random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+{
+ return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes);
+}
+
+static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
int ret;
@@ -1376,6 +1386,7 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
"with %d bits of entropy available\n",
current->comm, nonblocking_pool.entropy_total);
+ nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool),
@@ -1413,7 +1424,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
count -= bytes;
p += bytes;
- mix_pool_bytes(r, buf, bytes, NULL);
+ mix_pool_bytes(r, buf, bytes);
cond_resched();
}
@@ -1509,6 +1520,29 @@ const struct file_operations urandom_fops = {
.llseek = noop_llseek,
};
+SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count,
+ unsigned int, flags)
+{
+ if (flags & ~(GRND_NONBLOCK|GRND_RANDOM))
+ return -EINVAL;
+
+ if (count > INT_MAX)
+ count = INT_MAX;
+
+ if (flags & GRND_RANDOM)
+ return _random_read(flags & GRND_NONBLOCK, buf, count);
+
+ if (unlikely(nonblocking_pool.initialized == 0)) {
+ if (flags & GRND_NONBLOCK)
+ return -EAGAIN;
+ wait_event_interruptible(urandom_init_wait,
+ nonblocking_pool.initialized);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ }
+ return urandom_read(NULL, buf, count, NULL);
+}
+
/***************************************************************
* Random UUID interface
*
@@ -1652,6 +1686,22 @@ struct ctl_table random_table[] = {
.mode = 0444,
.proc_handler = proc_do_uuid,
},
+#ifdef ADD_INTERRUPT_BENCH
+ {
+ .procname = "add_interrupt_avg_cycles",
+ .data = &avg_cycles,
+ .maxlen = sizeof(avg_cycles),
+ .mode = 0444,
+ .proc_handler = proc_doulongvec_minmax,
+ },
+ {
+ .procname = "add_interrupt_avg_deviation",
+ .data = &avg_deviation,
+ .maxlen = sizeof(avg_deviation),
+ .mode = 0444,
+ .proc_handler = proc_doulongvec_minmax,
+ },
+#endif
{ }
};
#endif /* CONFIG_SYSCTL */
@@ -1708,3 +1758,23 @@ randomize_range(unsigned long start, unsigned long end, unsigned long len)
return 0;
return PAGE_ALIGN(get_random_int() % range + start);
}
+
+/* Interface for in-kernel drivers of true hardware RNGs.
+ * Those devices may produce endless random bits and will be throttled
+ * when our pool is full.
+ */
+void add_hwgenerator_randomness(const char *buffer, size_t count,
+ size_t entropy)
+{
+ struct entropy_store *poolp = &input_pool;
+
+ /* Suspend writing if we're above the trickle threshold.
+ * We'll be woken up again once below random_write_wakeup_thresh,
+ * or when the calling thread is about to terminate.
+ */
+ wait_event_interruptible(random_write_wait, kthread_should_stop() ||
+ ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
+ mix_pool_bytes(poolp, buffer, count);
+ credit_entropy_bits(poolp, entropy);
+}
+EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 62e10fd1e1cb..6af17002a115 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -491,11 +491,10 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
int tpm_get_timeouts(struct tpm_chip *chip)
{
struct tpm_cmd_t tpm_cmd;
- struct timeout_t *timeout_cap;
+ unsigned long new_timeout[4];
+ unsigned long old_timeout[4];
struct duration_t *duration_cap;
ssize_t rc;
- u32 timeout;
- unsigned int scale = 1;
tpm_cmd.header.in = tpm_getcap_header;
tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
@@ -529,25 +528,46 @@ int tpm_get_timeouts(struct tpm_chip *chip)
!= sizeof(tpm_cmd.header.out) + sizeof(u32) + 4 * sizeof(u32))
return -EINVAL;
- timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
- /* Don't overwrite default if value is 0 */
- timeout = be32_to_cpu(timeout_cap->a);
- if (timeout && timeout < 1000) {
- /* timeouts in msec rather usec */
- scale = 1000;
- chip->vendor.timeout_adjusted = true;
+ old_timeout[0] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.a);
+ old_timeout[1] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.b);
+ old_timeout[2] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.c);
+ old_timeout[3] = be32_to_cpu(tpm_cmd.params.getcap_out.cap.timeout.d);
+ memcpy(new_timeout, old_timeout, sizeof(new_timeout));
+
+ /*
+ * Provide ability for vendor overrides of timeout values in case
+ * of misreporting.
+ */
+ if (chip->ops->update_timeouts != NULL)
+ chip->vendor.timeout_adjusted =
+ chip->ops->update_timeouts(chip, new_timeout);
+
+ if (!chip->vendor.timeout_adjusted) {
+ /* Don't overwrite default if value is 0 */
+ if (new_timeout[0] != 0 && new_timeout[0] < 1000) {
+ int i;
+
+ /* timeouts in msec rather usec */
+ for (i = 0; i != ARRAY_SIZE(new_timeout); i++)
+ new_timeout[i] *= 1000;
+ chip->vendor.timeout_adjusted = true;
+ }
+ }
+
+ /* Report adjusted timeouts */
+ if (chip->vendor.timeout_adjusted) {
+ dev_info(chip->dev,
+ HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
+ old_timeout[0], new_timeout[0],
+ old_timeout[1], new_timeout[1],
+ old_timeout[2], new_timeout[2],
+ old_timeout[3], new_timeout[3]);
}
- if (timeout)
- chip->vendor.timeout_a = usecs_to_jiffies(timeout * scale);
- timeout = be32_to_cpu(timeout_cap->b);
- if (timeout)
- chip->vendor.timeout_b = usecs_to_jiffies(timeout * scale);
- timeout = be32_to_cpu(timeout_cap->c);
- if (timeout)
- chip->vendor.timeout_c = usecs_to_jiffies(timeout * scale);
- timeout = be32_to_cpu(timeout_cap->d);
- if (timeout)
- chip->vendor.timeout_d = usecs_to_jiffies(timeout * scale);
+
+ chip->vendor.timeout_a = usecs_to_jiffies(new_timeout[0]);
+ chip->vendor.timeout_b = usecs_to_jiffies(new_timeout[1]);
+ chip->vendor.timeout_c = usecs_to_jiffies(new_timeout[2]);
+ chip->vendor.timeout_d = usecs_to_jiffies(new_timeout[3]);
duration:
tpm_cmd.header.in = tpm_getcap_header;
@@ -991,13 +1011,13 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
int err, total = 0, retries = 5;
u8 *dest = out;
+ if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
+ return -EINVAL;
+
chip = tpm_chip_find_get(chip_num);
if (chip == NULL)
return -ENODEV;
- if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
- return -EINVAL;
-
do {
tpm_cmd.header.in = tpm_getrandom_header;
tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
@@ -1016,6 +1036,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
num_bytes -= recd;
} while (retries-- && total < max);
+ tpm_chip_put(chip);
return total ? total : -EIO;
}
EXPORT_SYMBOL_GPL(tpm_get_random);
@@ -1095,7 +1116,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
goto del_misc;
if (tpm_add_ppi(&dev->kobj))
- goto del_misc;
+ goto del_sysfs;
chip->bios_dir = tpm_bios_log_setup(chip->devname);
@@ -1106,6 +1127,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
return chip;
+del_sysfs:
+ tpm_sysfs_del_device(chip);
del_misc:
tpm_dev_del_device(chip);
put_device:
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c
index 59f7cb28260b..3a56a131586c 100644
--- a/drivers/char/tpm/tpm_eventlog.c
+++ b/drivers/char/tpm/tpm_eventlog.c
@@ -235,7 +235,6 @@ static int tpm_bios_measurements_release(struct inode *inode,
static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
{
int len = 0;
- int i;
char *eventname;
struct tcpa_event *event = v;
unsigned char *event_entry =
@@ -251,8 +250,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
seq_printf(m, "%2d ", event->pcr_index);
/* 2nd: SHA1 */
- for (i = 0; i < 20; i++)
- seq_printf(m, "%02x", event->pcr_value[i]);
+ seq_printf(m, "%20phN", event->pcr_value);
/* 3rd: event type identifier */
seq_printf(m, " %02x", event->event_type);
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c
index 3b7bf2162898..4669e3713428 100644
--- a/drivers/char/tpm/tpm_i2c_stm_st33.c
+++ b/drivers/char/tpm/tpm_i2c_stm_st33.c
@@ -714,6 +714,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
tpm_get_timeouts(chip);
+ tpm_do_selftest(chip);
dev_info(chip->dev, "TPM I2C Initialized\n");
return 0;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index a9ed2270c25d..2c46734b266d 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -373,6 +373,36 @@ out_err:
return rc;
}
+struct tis_vendor_timeout_override {
+ u32 did_vid;
+ unsigned long timeout_us[4];
+};
+
+static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = {
+ /* Atmel 3204 */
+ { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000),
+ (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },
+};
+
+static bool tpm_tis_update_timeouts(struct tpm_chip *chip,
+ unsigned long *timeout_cap)
+{
+ int i;
+ u32 did_vid;
+
+ did_vid = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
+
+ for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) {
+ if (vendor_timeout_overrides[i].did_vid != did_vid)
+ continue;
+ memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us,
+ sizeof(vendor_timeout_overrides[i].timeout_us));
+ return true;
+ }
+
+ return false;
+}
+
/*
* Early probing for iTPM with STS_DATA_EXPECT flaw.
* Try sending command without itpm flag set and if that
@@ -437,6 +467,7 @@ static const struct tpm_class_ops tpm_tis = {
.recv = tpm_tis_recv,
.send = tpm_tis_send,
.cancel = tpm_tis_ready,
+ .update_timeouts = tpm_tis_update_timeouts,
.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
.req_canceled = tpm_tis_req_canceled,
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index f6345f932e46..9b1a5ac4881d 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -661,6 +661,7 @@ static int hwicap_setup(struct device *dev, int id,
drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size);
if (!drvdata->base_address) {
dev_err(dev, "ioremap() failed\n");
+ retval = -ENOMEM;
goto failed2;
}
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 9f9c5ae5359b..cfd3af7b2cbd 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -102,6 +102,13 @@ config COMMON_CLK_KEYSTONE
Supports clock drivers for Keystone based SOCs. These SOCs have local
a power sleep control module that gate the clock to the IPs and PLLs.
+config COMMON_CLK_PALMAS
+ tristate "Clock driver for TI Palmas devices"
+ depends on MFD_PALMAS
+ ---help---
+ This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO
+ using common clock framework.
+
source "drivers/clk/qcom/Kconfig"
endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 567f10259029..f537a0b1f798 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -9,12 +9,16 @@ obj-$(CONFIG_COMMON_CLK) += clk-gate.o
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
+ifeq ($(CONFIG_OF), y)
+obj-$(CONFIG_COMMON_CLK) += clk-conf.o
+endif
# hardware specific clock types
# please keep this section sorted lexicographically by file/directory path name
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
+obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
@@ -22,6 +26,7 @@ obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
+obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 733306131b99..59fa3cc96c9e 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -388,6 +388,7 @@ static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc,
if (parent_rate)
return parent_rate;
+ pr_warn("Main crystal frequency not set, using approximate value\n");
tmp = pmc_read(pmc, AT91_CKGR_MCFR);
if (!(tmp & AT91_PMC_MAINRDY))
return 0;
diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c
new file mode 100644
index 000000000000..715eec1a9902
--- /dev/null
+++ b/drivers/clk/clk-clps711x.c
@@ -0,0 +1,192 @@
+/*
+ * Cirrus Logic CLPS711X CLK driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mfd/syscon/clps711x.h>
+
+#include <dt-bindings/clock/clps711x-clock.h>
+
+#define CLPS711X_SYSCON1 (0x0100)
+#define CLPS711X_SYSCON2 (0x1100)
+#define CLPS711X_SYSFLG2 (CLPS711X_SYSCON2 + SYSFLG_OFFSET)
+#define CLPS711X_PLLR (0xa5a8)
+
+#define CLPS711X_EXT_FREQ (13000000)
+#define CLPS711X_OSC_FREQ (3686400)
+
+static const struct clk_div_table spi_div_table[] = {
+ { .val = 0, .div = 32, },
+ { .val = 1, .div = 8, },
+ { .val = 2, .div = 2, },
+ { .val = 3, .div = 1, },
+};
+
+static const struct clk_div_table timer_div_table[] = {
+ { .val = 0, .div = 256, },
+ { .val = 1, .div = 1, },
+};
+
+struct clps711x_clk {
+ struct clk_onecell_data clk_data;
+ spinlock_t lock;
+ struct clk *clks[CLPS711X_CLK_MAX];
+};
+
+static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
+ u32 fref)
+{
+ u32 tmp, f_cpu, f_pll, f_bus, f_tim, f_pwm, f_spi;
+ struct clps711x_clk *clps711x_clk;
+ unsigned i;
+
+ if (!base)
+ return ERR_PTR(-ENOMEM);
+
+ clps711x_clk = kzalloc(sizeof(*clps711x_clk), GFP_KERNEL);
+ if (!clps711x_clk)
+ return ERR_PTR(-ENOMEM);
+
+ spin_lock_init(&clps711x_clk->lock);
+
+ /* Read PLL multiplier value and sanity check */
+ tmp = readl(base + CLPS711X_PLLR) >> 24;
+ if (((tmp >= 10) && (tmp <= 50)) || !fref)
+ f_pll = DIV_ROUND_UP(CLPS711X_OSC_FREQ * tmp, 2);
+ else
+ f_pll = fref;
+
+ tmp = readl(base + CLPS711X_SYSFLG2);
+ if (tmp & SYSFLG2_CKMODE) {
+ f_cpu = CLPS711X_EXT_FREQ;
+ f_bus = CLPS711X_EXT_FREQ;
+ f_spi = DIV_ROUND_CLOSEST(CLPS711X_EXT_FREQ, 96);
+ f_pll = 0;
+ f_pwm = DIV_ROUND_CLOSEST(CLPS711X_EXT_FREQ, 128);
+ } else {
+ f_cpu = f_pll;
+ if (f_cpu > 36864000)
+ f_bus = DIV_ROUND_UP(f_cpu, 2);
+ else
+ f_bus = 36864000 / 2;
+ f_spi = DIV_ROUND_CLOSEST(f_cpu, 576);
+ f_pwm = DIV_ROUND_CLOSEST(f_cpu, 768);
+ }
+
+ if (tmp & SYSFLG2_CKMODE) {
+ if (readl(base + CLPS711X_SYSCON2) & SYSCON2_OSTB)
+ f_tim = DIV_ROUND_CLOSEST(CLPS711X_EXT_FREQ, 26);
+ else
+ f_tim = DIV_ROUND_CLOSEST(CLPS711X_EXT_FREQ, 24);
+ } else
+ f_tim = DIV_ROUND_CLOSEST(f_cpu, 144);
+
+ tmp = readl(base + CLPS711X_SYSCON1);
+ /* Timer1 in free running mode.
+ * Counter will wrap around to 0xffff when it underflows
+ * and will continue to count down.
+ */
+ tmp &= ~(SYSCON1_TC1M | SYSCON1_TC1S);
+ /* Timer2 in prescale mode.
+ * Value writen is automatically re-loaded when
+ * the counter underflows.
+ */
+ tmp |= SYSCON1_TC2M | SYSCON1_TC2S;
+ writel(tmp, base + CLPS711X_SYSCON1);
+
+ clps711x_clk->clks[CLPS711X_CLK_DUMMY] =
+ clk_register_fixed_rate(NULL, "dummy", NULL, CLK_IS_ROOT, 0);
+ clps711x_clk->clks[CLPS711X_CLK_CPU] =
+ clk_register_fixed_rate(NULL, "cpu", NULL, CLK_IS_ROOT, f_cpu);
+ clps711x_clk->clks[CLPS711X_CLK_BUS] =
+ clk_register_fixed_rate(NULL, "bus", NULL, CLK_IS_ROOT, f_bus);
+ clps711x_clk->clks[CLPS711X_CLK_PLL] =
+ clk_register_fixed_rate(NULL, "pll", NULL, CLK_IS_ROOT, f_pll);
+ clps711x_clk->clks[CLPS711X_CLK_TIMERREF] =
+ clk_register_fixed_rate(NULL, "timer_ref", NULL, CLK_IS_ROOT,
+ f_tim);
+ clps711x_clk->clks[CLPS711X_CLK_TIMER1] =
+ clk_register_divider_table(NULL, "timer1", "timer_ref", 0,
+ base + CLPS711X_SYSCON1, 5, 1, 0,
+ timer_div_table, &clps711x_clk->lock);
+ clps711x_clk->clks[CLPS711X_CLK_TIMER2] =
+ clk_register_divider_table(NULL, "timer2", "timer_ref", 0,
+ base + CLPS711X_SYSCON1, 7, 1, 0,
+ timer_div_table, &clps711x_clk->lock);
+ clps711x_clk->clks[CLPS711X_CLK_PWM] =
+ clk_register_fixed_rate(NULL, "pwm", NULL, CLK_IS_ROOT, f_pwm);
+ clps711x_clk->clks[CLPS711X_CLK_SPIREF] =
+ clk_register_fixed_rate(NULL, "spi_ref", NULL, CLK_IS_ROOT,
+ f_spi);
+ clps711x_clk->clks[CLPS711X_CLK_SPI] =
+ clk_register_divider_table(NULL, "spi", "spi_ref", 0,
+ base + CLPS711X_SYSCON1, 16, 2, 0,
+ spi_div_table, &clps711x_clk->lock);
+ clps711x_clk->clks[CLPS711X_CLK_UART] =
+ clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
+ clps711x_clk->clks[CLPS711X_CLK_TICK] =
+ clk_register_fixed_rate(NULL, "tick", NULL, CLK_IS_ROOT, 64);
+
+ for (i = 0; i < CLPS711X_CLK_MAX; i++)
+ if (IS_ERR(clps711x_clk->clks[i]))
+ pr_err("clk %i: register failed with %ld\n",
+ i, PTR_ERR(clps711x_clk->clks[i]));
+
+ return clps711x_clk;
+}
+
+void __init clps711x_clk_init(void __iomem *base)
+{
+ struct clps711x_clk *clps711x_clk;
+
+ clps711x_clk = _clps711x_clk_init(base, 73728000);
+
+ BUG_ON(IS_ERR(clps711x_clk));
+
+ /* Clocksource */
+ clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER1],
+ NULL, "clps711x-timer.0");
+ clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER2],
+ NULL, "clps711x-timer.1");
+
+ /* Drivers */
+ clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_PWM],
+ NULL, "clps711x-pwm");
+ clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
+ NULL, "clps711x-uart.0");
+ clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
+ NULL, "clps711x-uart.1");
+}
+
+#ifdef CONFIG_OF
+static void __init clps711x_clk_init_dt(struct device_node *np)
+{
+ void __iomem *base = of_iomap(np, 0);
+ struct clps711x_clk *clps711x_clk;
+ u32 fref = 0;
+
+ WARN_ON(of_property_read_u32(np, "startup-frequency", &fref));
+
+ clps711x_clk = _clps711x_clk_init(base, fref);
+ BUG_ON(IS_ERR(clps711x_clk));
+
+ clps711x_clk->clk_data.clks = clps711x_clk->clks;
+ clps711x_clk->clk_data.clk_num = CLPS711X_CLK_MAX;
+ of_clk_add_provider(np, of_clk_src_onecell_get,
+ &clps711x_clk->clk_data);
+}
+CLK_OF_DECLARE(clps711x, "cirrus,clps711x-clk", clps711x_clk_init_dt);
+#endif
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 57a078e06efe..b9355daf8065 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -64,11 +64,56 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk_hw *rate_hw = composite->rate_hw;
struct clk_hw *mux_hw = composite->mux_hw;
+ struct clk *parent;
+ unsigned long parent_rate;
+ long tmp_rate, best_rate = 0;
+ unsigned long rate_diff;
+ unsigned long best_rate_diff = ULONG_MAX;
+ int i;
if (rate_hw && rate_ops && rate_ops->determine_rate) {
rate_hw->clk = hw->clk;
return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
best_parent_p);
+ } else if (rate_hw && rate_ops && rate_ops->round_rate &&
+ mux_hw && mux_ops && mux_ops->set_parent) {
+ *best_parent_p = NULL;
+
+ if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) {
+ *best_parent_p = clk_get_parent(mux_hw->clk);
+ *best_parent_rate = __clk_get_rate(*best_parent_p);
+
+ return rate_ops->round_rate(rate_hw, rate,
+ best_parent_rate);
+ }
+
+ for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) {
+ parent = clk_get_parent_by_index(mux_hw->clk, i);
+ if (!parent)
+ continue;
+
+ parent_rate = __clk_get_rate(parent);
+
+ tmp_rate = rate_ops->round_rate(rate_hw, rate,
+ &parent_rate);
+ if (tmp_rate < 0)
+ continue;
+
+ rate_diff = abs(rate - tmp_rate);
+
+ if (!rate_diff || !*best_parent_p
+ || best_rate_diff > rate_diff) {
+ *best_parent_p = parent;
+ *best_parent_rate = parent_rate;
+ best_rate_diff = rate_diff;
+ best_rate = tmp_rate;
+ }
+
+ if (!rate_diff)
+ return rate;
+ }
+
+ return best_rate;
} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
mux_hw->clk = hw->clk;
return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -162,7 +207,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
clk_composite_ops = &composite->ops;
if (mux_hw && mux_ops) {
- if (!mux_ops->get_parent || !mux_ops->set_parent) {
+ if (!mux_ops->get_parent) {
clk = ERR_PTR(-EINVAL);
goto err;
}
@@ -170,7 +215,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->mux_hw = mux_hw;
composite->mux_ops = mux_ops;
clk_composite_ops->get_parent = clk_composite_get_parent;
- clk_composite_ops->set_parent = clk_composite_set_parent;
+ if (mux_ops->set_parent)
+ clk_composite_ops->set_parent = clk_composite_set_parent;
if (mux_ops->determine_rate)
clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
@@ -180,24 +226,27 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
clk = ERR_PTR(-EINVAL);
goto err;
}
+ clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
- /* .round_rate is a prerequisite for .set_rate */
- if (rate_ops->round_rate) {
- clk_composite_ops->round_rate = clk_composite_round_rate;
- if (rate_ops->set_rate) {
- clk_composite_ops->set_rate = clk_composite_set_rate;
- }
- } else {
- WARN(rate_ops->set_rate,
- "%s: missing round_rate op is required\n",
- __func__);
+ if (rate_ops->determine_rate)
+ clk_composite_ops->determine_rate =
+ clk_composite_determine_rate;
+ else if (rate_ops->round_rate)
+ clk_composite_ops->round_rate =
+ clk_composite_round_rate;
+
+ /* .set_rate requires either .round_rate or .determine_rate */
+ if (rate_ops->set_rate) {
+ if (rate_ops->determine_rate || rate_ops->round_rate)
+ clk_composite_ops->set_rate =
+ clk_composite_set_rate;
+ else
+ WARN(1, "%s: missing round_rate op is required\n",
+ __func__);
}
composite->rate_hw = rate_hw;
composite->rate_ops = rate_ops;
- clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
- if (rate_ops->determine_rate)
- clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (gate_hw && gate_ops) {
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
new file mode 100644
index 000000000000..aad4796aa3ed
--- /dev/null
+++ b/drivers/clk/clk-conf.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.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.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/clk-conf.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include "clk.h"
+
+static int __set_clk_parents(struct device_node *node, bool clk_supplier)
+{
+ struct of_phandle_args clkspec;
+ int index, rc, num_parents;
+ struct clk *clk, *pclk;
+
+ num_parents = of_count_phandle_with_args(node, "assigned-clock-parents",
+ "#clock-cells");
+ if (num_parents == -EINVAL)
+ pr_err("clk: invalid value of clock-parents property at %s\n",
+ node->full_name);
+
+ for (index = 0; index < num_parents; index++) {
+ rc = of_parse_phandle_with_args(node, "assigned-clock-parents",
+ "#clock-cells", index, &clkspec);
+ if (rc < 0) {
+ /* skip empty (null) phandles */
+ if (rc == -ENOENT)
+ continue;
+ else
+ return rc;
+ }
+ if (clkspec.np == node && !clk_supplier)
+ return 0;
+ pclk = of_clk_get_by_clkspec(&clkspec);
+ if (IS_ERR(pclk)) {
+ pr_warn("clk: couldn't get parent clock %d for %s\n",
+ index, node->full_name);
+ return PTR_ERR(pclk);
+ }
+
+ rc = of_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", index, &clkspec);
+ if (rc < 0)
+ goto err;
+ if (clkspec.np == node && !clk_supplier) {
+ rc = 0;
+ goto err;
+ }
+ clk = of_clk_get_by_clkspec(&clkspec);
+ if (IS_ERR(clk)) {
+ pr_warn("clk: couldn't get parent clock %d for %s\n",
+ index, node->full_name);
+ rc = PTR_ERR(clk);
+ goto err;
+ }
+
+ rc = clk_set_parent(clk, pclk);
+ if (rc < 0)
+ pr_err("clk: failed to reparent %s to %s: %d\n",
+ __clk_get_name(clk), __clk_get_name(pclk), rc);
+ clk_put(clk);
+ clk_put(pclk);
+ }
+ return 0;
+err:
+ clk_put(pclk);
+ return rc;
+}
+
+static int __set_clk_rates(struct device_node *node, bool clk_supplier)
+{
+ struct of_phandle_args clkspec;
+ struct property *prop;
+ const __be32 *cur;
+ int rc, index = 0;
+ struct clk *clk;
+ u32 rate;
+
+ of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
+ if (rate) {
+ rc = of_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", index, &clkspec);
+ if (rc < 0) {
+ /* skip empty (null) phandles */
+ if (rc == -ENOENT)
+ continue;
+ else
+ return rc;
+ }
+ if (clkspec.np == node && !clk_supplier)
+ return 0;
+
+ clk = of_clk_get_by_clkspec(&clkspec);
+ if (IS_ERR(clk)) {
+ pr_warn("clk: couldn't get clock %d for %s\n",
+ index, node->full_name);
+ return PTR_ERR(clk);
+ }
+
+ rc = clk_set_rate(clk, rate);
+ if (rc < 0)
+ pr_err("clk: couldn't set %s clock rate: %d\n",
+ __clk_get_name(clk), rc);
+ clk_put(clk);
+ }
+ index++;
+ }
+ return 0;
+}
+
+/**
+ * of_clk_set_defaults() - parse and set assigned clocks configuration
+ * @node: device node to apply clock settings for
+ * @clk_supplier: true if clocks supplied by @node should also be considered
+ *
+ * This function parses 'assigned-{clocks/clock-parents/clock-rates}' properties
+ * and sets any specified clock parents and rates. The @clk_supplier argument
+ * should be set to true if @node may be also a clock supplier of any clock
+ * listed in its 'assigned-clocks' or 'assigned-clock-parents' properties.
+ * If @clk_supplier is false the function exits returnning 0 as soon as it
+ * determines the @node is also a supplier of any of the clocks.
+ */
+int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
+{
+ int rc;
+
+ if (!node)
+ return 0;
+
+ rc = __set_clk_parents(node, clk_supplier);
+ if (rc < 0)
+ return rc;
+
+ return __set_clk_rates(node, clk_supplier);
+}
+EXPORT_SYMBOL_GPL(of_clk_set_defaults);
diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c
new file mode 100644
index 000000000000..781630e1372b
--- /dev/null
+++ b/drivers/clk/clk-palmas.c
@@ -0,0 +1,307 @@
+/*
+ * Clock driver for Palmas device.
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ * Copyright (c) 2013-2014 Texas Instruments, Inc.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ * Peter Ujfalusi <peter.ujfalusi@ti.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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/palmas.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1 1
+#define PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2 2
+#define PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP 3
+
+struct palmas_clk32k_desc {
+ const char *clk_name;
+ unsigned int control_reg;
+ unsigned int enable_mask;
+ unsigned int sleep_mask;
+ unsigned int sleep_reqstr_id;
+ int delay;
+};
+
+struct palmas_clock_info {
+ struct device *dev;
+ struct clk *clk;
+ struct clk_hw hw;
+ struct palmas *palmas;
+ struct palmas_clk32k_desc *clk_desc;
+ int ext_control_pin;
+};
+
+static inline struct palmas_clock_info *to_palmas_clks_info(struct clk_hw *hw)
+{
+ return container_of(hw, struct palmas_clock_info, hw);
+}
+
+static unsigned long palmas_clks_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return 32768;
+}
+
+static int palmas_clks_prepare(struct clk_hw *hw)
+{
+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
+ int ret;
+
+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
+ cinfo->clk_desc->control_reg,
+ cinfo->clk_desc->enable_mask,
+ cinfo->clk_desc->enable_mask);
+ if (ret < 0)
+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
+ cinfo->clk_desc->control_reg, ret);
+ else if (cinfo->clk_desc->delay)
+ udelay(cinfo->clk_desc->delay);
+
+ return ret;
+}
+
+static void palmas_clks_unprepare(struct clk_hw *hw)
+{
+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
+ int ret;
+
+ /*
+ * Clock can be disabled through external pin if it is externally
+ * controlled.
+ */
+ if (cinfo->ext_control_pin)
+ return;
+
+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
+ cinfo->clk_desc->control_reg,
+ cinfo->clk_desc->enable_mask, 0);
+ if (ret < 0)
+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
+ cinfo->clk_desc->control_reg, ret);
+}
+
+static int palmas_clks_is_prepared(struct clk_hw *hw)
+{
+ struct palmas_clock_info *cinfo = to_palmas_clks_info(hw);
+ int ret;
+ u32 val;
+
+ if (cinfo->ext_control_pin)
+ return 1;
+
+ ret = palmas_read(cinfo->palmas, PALMAS_RESOURCE_BASE,
+ cinfo->clk_desc->control_reg, &val);
+ if (ret < 0) {
+ dev_err(cinfo->dev, "Reg 0x%02x read failed, %d\n",
+ cinfo->clk_desc->control_reg, ret);
+ return ret;
+ }
+ return !!(val & cinfo->clk_desc->enable_mask);
+}
+
+static struct clk_ops palmas_clks_ops = {
+ .prepare = palmas_clks_prepare,
+ .unprepare = palmas_clks_unprepare,
+ .is_prepared = palmas_clks_is_prepared,
+ .recalc_rate = palmas_clks_recalc_rate,
+};
+
+struct palmas_clks_of_match_data {
+ struct clk_init_data init;
+ struct palmas_clk32k_desc desc;
+};
+
+static struct palmas_clks_of_match_data palmas_of_clk32kg = {
+ .init = {
+ .name = "clk32kg",
+ .ops = &palmas_clks_ops,
+ .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+ },
+ .desc = {
+ .clk_name = "clk32kg",
+ .control_reg = PALMAS_CLK32KG_CTRL,
+ .enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE,
+ .sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP,
+ .sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KG,
+ .delay = 200,
+ },
+};
+
+static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
+ .init = {
+ .name = "clk32kgaudio",
+ .ops = &palmas_clks_ops,
+ .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
+ },
+ .desc = {
+ .clk_name = "clk32kgaudio",
+ .control_reg = PALMAS_CLK32KGAUDIO_CTRL,
+ .enable_mask = PALMAS_CLK32KG_CTRL_MODE_ACTIVE,
+ .sleep_mask = PALMAS_CLK32KG_CTRL_MODE_SLEEP,
+ .sleep_reqstr_id = PALMAS_EXTERNAL_REQSTR_ID_CLK32KGAUDIO,
+ .delay = 200,
+ },
+};
+
+static struct of_device_id palmas_clks_of_match[] = {
+ {
+ .compatible = "ti,palmas-clk32kg",
+ .data = &palmas_of_clk32kg,
+ },
+ {
+ .compatible = "ti,palmas-clk32kgaudio",
+ .data = &palmas_of_clk32kgaudio,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, palmas_clks_of_match);
+
+static void palmas_clks_get_clk_data(struct platform_device *pdev,
+ struct palmas_clock_info *cinfo)
+{
+ struct device_node *node = pdev->dev.of_node;
+ unsigned int prop;
+ int ret;
+
+ ret = of_property_read_u32(node, "ti,external-sleep-control",
+ &prop);
+ if (ret)
+ return;
+
+ switch (prop) {
+ case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE1:
+ prop = PALMAS_EXT_CONTROL_ENABLE1;
+ break;
+ case PALMAS_CLOCK_DT_EXT_CONTROL_ENABLE2:
+ prop = PALMAS_EXT_CONTROL_ENABLE2;
+ break;
+ case PALMAS_CLOCK_DT_EXT_CONTROL_NSLEEP:
+ prop = PALMAS_EXT_CONTROL_NSLEEP;
+ break;
+ default:
+ dev_warn(&pdev->dev, "%s: Invalid ext control option: %u\n",
+ node->name, prop);
+ prop = 0;
+ break;
+ }
+ cinfo->ext_control_pin = prop;
+}
+
+static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
+{
+ int ret;
+
+ ret = palmas_update_bits(cinfo->palmas, PALMAS_RESOURCE_BASE,
+ cinfo->clk_desc->control_reg,
+ cinfo->clk_desc->sleep_mask, 0);
+ if (ret < 0) {
+ dev_err(cinfo->dev, "Reg 0x%02x update failed, %d\n",
+ cinfo->clk_desc->control_reg, ret);
+ return ret;
+ }
+
+ if (cinfo->ext_control_pin) {
+ ret = clk_prepare(cinfo->clk);
+ if (ret < 0) {
+ dev_err(cinfo->dev, "Clock prep failed, %d\n", ret);
+ return ret;
+ }
+
+ ret = palmas_ext_control_req_config(cinfo->palmas,
+ cinfo->clk_desc->sleep_reqstr_id,
+ cinfo->ext_control_pin, true);
+ if (ret < 0) {
+ dev_err(cinfo->dev, "Ext config for %s failed, %d\n",
+ cinfo->clk_desc->clk_name, ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+static int palmas_clks_probe(struct platform_device *pdev)
+{
+ struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
+ struct device_node *node = pdev->dev.of_node;
+ struct palmas_clks_of_match_data *match_data;
+ const struct of_device_id *match;
+ struct palmas_clock_info *cinfo;
+ struct clk *clk;
+ int ret;
+
+ match = of_match_device(palmas_clks_of_match, &pdev->dev);
+ match_data = (struct palmas_clks_of_match_data *)match->data;
+
+ cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL);
+ if (!cinfo)
+ return -ENOMEM;
+
+ palmas_clks_get_clk_data(pdev, cinfo);
+ platform_set_drvdata(pdev, cinfo);
+
+ cinfo->dev = &pdev->dev;
+ cinfo->palmas = palmas;
+
+ cinfo->clk_desc = &match_data->desc;
+ cinfo->hw.init = &match_data->init;
+ clk = devm_clk_register(&pdev->dev, &cinfo->hw);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ dev_err(&pdev->dev, "Fail to register clock %s, %d\n",
+ match_data->desc.clk_name, ret);
+ return ret;
+ }
+
+ cinfo->clk = clk;
+ ret = palmas_clks_init_configure(cinfo);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Clock config failed, %d\n", ret);
+ return ret;
+ }
+
+ ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk);
+ if (ret < 0)
+ dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret);
+ return ret;
+}
+
+static int palmas_clks_remove(struct platform_device *pdev)
+{
+ of_clk_del_provider(pdev->dev.of_node);
+ return 0;
+}
+
+static struct platform_driver palmas_clks_driver = {
+ .driver = {
+ .name = "palmas-clk",
+ .owner = THIS_MODULE,
+ .of_match_table = palmas_clks_of_match,
+ },
+ .probe = palmas_clks_probe,
+ .remove = palmas_clks_remove,
+};
+
+module_platform_driver(palmas_clks_driver);
+
+MODULE_DESCRIPTION("Clock driver for Palmas Series Devices");
+MODULE_ALIAS("platform:palmas-clk");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c
index 8b284be4efa4..8e58edfeeb37 100644
--- a/drivers/clk/clk-ppc-corenet.c
+++ b/drivers/clk/clk-ppc-corenet.c
@@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = {
{}
};
-static struct platform_driver ppc_corenet_clk_driver = {
+static struct platform_driver ppc_corenet_clk_driver __initdata = {
.driver = {
.name = "ppc_corenet_clock",
.owner = THIS_MODULE,
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c
index 9b7b5859a420..b7797fb12e12 100644
--- a/drivers/clk/clk-s2mps11.c
+++ b/drivers/clk/clk-s2mps11.c
@@ -46,7 +46,6 @@ struct s2mps11_clk {
struct clk *clk;
struct clk_lookup *lookup;
u32 mask;
- bool enabled;
unsigned int reg;
};
@@ -63,8 +62,6 @@ static int s2mps11_clk_prepare(struct clk_hw *hw)
ret = regmap_update_bits(s2mps11->iodev->regmap_pmic,
s2mps11->reg,
s2mps11->mask, s2mps11->mask);
- if (!ret)
- s2mps11->enabled = true;
return ret;
}
@@ -76,32 +73,32 @@ static void s2mps11_clk_unprepare(struct clk_hw *hw)
ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg,
s2mps11->mask, ~s2mps11->mask);
-
- if (!ret)
- s2mps11->enabled = false;
}
-static int s2mps11_clk_is_enabled(struct clk_hw *hw)
+static int s2mps11_clk_is_prepared(struct clk_hw *hw)
{
+ int ret;
+ u32 val;
struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
- return s2mps11->enabled;
+ ret = regmap_read(s2mps11->iodev->regmap_pmic,
+ s2mps11->reg, &val);
+ if (ret < 0)
+ return -EINVAL;
+
+ return val & s2mps11->mask;
}
static unsigned long s2mps11_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
- if (s2mps11->enabled)
- return 32768;
- else
- return 0;
+ return 32768;
}
static struct clk_ops s2mps11_clk_ops = {
.prepare = s2mps11_clk_prepare,
.unprepare = s2mps11_clk_unprepare,
- .is_enabled = s2mps11_clk_is_enabled,
+ .is_prepared = s2mps11_clk_is_prepared,
.recalc_rate = s2mps11_clk_recalc_rate,
};
@@ -169,7 +166,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
unsigned int s2mps11_reg;
struct clk_init_data *clks_init;
int i, ret = 0;
- u32 val;
s2mps11_clks = devm_kzalloc(&pdev->dev, sizeof(*s2mps11_clk) *
S2MPS11_CLKS_NUM, GFP_KERNEL);
@@ -214,13 +210,6 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
s2mps11_clk->mask = 1 << i;
s2mps11_clk->reg = s2mps11_reg;
- ret = regmap_read(s2mps11_clk->iodev->regmap_pmic,
- s2mps11_clk->reg, &val);
- if (ret < 0)
- goto err_reg;
-
- s2mps11_clk->enabled = val & s2mps11_clk->mask;
-
s2mps11_clk->clk = devm_clk_register(&pdev->dev,
&s2mps11_clk->hw);
if (IS_ERR(s2mps11_clk->clk)) {
@@ -230,16 +219,13 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
goto err_reg;
}
- s2mps11_clk->lookup = devm_kzalloc(&pdev->dev,
- sizeof(struct clk_lookup), GFP_KERNEL);
+ s2mps11_clk->lookup = clkdev_alloc(s2mps11_clk->clk,
+ s2mps11_name(s2mps11_clk), NULL);
if (!s2mps11_clk->lookup) {
ret = -ENOMEM;
goto err_lup;
}
- s2mps11_clk->lookup->con_id = s2mps11_name(s2mps11_clk);
- s2mps11_clk->lookup->clk = s2mps11_clk->clk;
-
clkdev_add(s2mps11_clk->lookup);
}
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 8b73edef151d..b76fa69b44cb 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -10,6 +10,7 @@
*/
#include <linux/clk-private.h>
+#include <linux/clk/clk-conf.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
@@ -98,9 +99,19 @@ static void clk_enable_unlock(unsigned long flags)
#include <linux/debugfs.h>
static struct dentry *rootdir;
-static struct dentry *orphandir;
static int inited = 0;
+static struct hlist_head *all_lists[] = {
+ &clk_root_list,
+ &clk_orphan_list,
+ NULL,
+};
+
+static struct hlist_head *orphan_list[] = {
+ &clk_orphan_list,
+ NULL,
+};
+
static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
{
if (!c)
@@ -130,17 +141,16 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk *c,
static int clk_summary_show(struct seq_file *s, void *data)
{
struct clk *c;
+ struct hlist_head **lists = (struct hlist_head **)s->private;
seq_puts(s, " clock enable_cnt prepare_cnt rate accuracy\n");
seq_puts(s, "--------------------------------------------------------------------------------\n");
clk_prepare_lock();
- hlist_for_each_entry(c, &clk_root_list, child_node)
- clk_summary_show_subtree(s, c, 0);
-
- hlist_for_each_entry(c, &clk_orphan_list, child_node)
- clk_summary_show_subtree(s, c, 0);
+ for (; *lists; lists++)
+ hlist_for_each_entry(c, *lists, child_node)
+ clk_summary_show_subtree(s, c, 0);
clk_prepare_unlock();
@@ -193,21 +203,19 @@ static int clk_dump(struct seq_file *s, void *data)
{
struct clk *c;
bool first_node = true;
+ struct hlist_head **lists = (struct hlist_head **)s->private;
seq_printf(s, "{");
clk_prepare_lock();
- hlist_for_each_entry(c, &clk_root_list, child_node) {
- if (!first_node)
- seq_printf(s, ",");
- first_node = false;
- clk_dump_subtree(s, c, 0);
- }
-
- hlist_for_each_entry(c, &clk_orphan_list, child_node) {
- seq_printf(s, ",");
- clk_dump_subtree(s, c, 0);
+ for (; *lists; lists++) {
+ hlist_for_each_entry(c, *lists, child_node) {
+ if (!first_node)
+ seq_puts(s, ",");
+ first_node = false;
+ clk_dump_subtree(s, c, 0);
+ }
}
clk_prepare_unlock();
@@ -276,9 +284,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
if (!d)
goto err_out;
- if (clk->ops->debug_init)
- if (clk->ops->debug_init(clk->hw, clk->dentry))
+ if (clk->ops->debug_init) {
+ ret = clk->ops->debug_init(clk->hw, clk->dentry);
+ if (ret)
goto err_out;
+ }
ret = 0;
goto out;
@@ -305,7 +315,7 @@ static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry)
goto out;
hlist_for_each_entry(child, &clk->children, child_node)
- clk_debug_create_subtree(child, clk->dentry);
+ clk_debug_create_subtree(child, pdentry);
ret = 0;
out:
@@ -325,31 +335,12 @@ out:
*/
static int clk_debug_register(struct clk *clk)
{
- struct clk *parent;
- struct dentry *pdentry;
int ret = 0;
if (!inited)
goto out;
- parent = clk->parent;
-
- /*
- * Check to see if a clk is a root clk. Also check that it is
- * safe to add this clk to debugfs
- */
- if (!parent)
- if (clk->flags & CLK_IS_ROOT)
- pdentry = rootdir;
- else
- pdentry = orphandir;
- else
- if (parent->dentry)
- pdentry = parent->dentry;
- else
- goto out;
-
- ret = clk_debug_create_subtree(clk, pdentry);
+ ret = clk_debug_create_subtree(clk, rootdir);
out:
return ret;
@@ -370,38 +361,17 @@ static void clk_debug_unregister(struct clk *clk)
debugfs_remove_recursive(clk->dentry);
}
-/**
- * clk_debug_reparent - reparent clk node in the debugfs clk tree
- * @clk: the clk being reparented
- * @new_parent: the new clk parent, may be NULL
- *
- * Rename clk entry in the debugfs clk tree if debugfs has been
- * initialized. Otherwise it bails out early since the debugfs clk tree
- * will be created lazily by clk_debug_init as part of a late_initcall.
- *
- * Caller must hold prepare_lock.
- */
-static void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
+struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode,
+ void *data, const struct file_operations *fops)
{
- struct dentry *d;
- struct dentry *new_parent_d;
-
- if (!inited)
- return;
+ struct dentry *d = NULL;
- if (new_parent)
- new_parent_d = new_parent->dentry;
- else
- new_parent_d = orphandir;
+ if (clk->dentry)
+ d = debugfs_create_file(name, mode, clk->dentry, data, fops);
- d = debugfs_rename(clk->dentry->d_parent, clk->dentry,
- new_parent_d, clk->name);
- if (d)
- clk->dentry = d;
- else
- pr_debug("%s: failed to rename debugfs entry for %s\n",
- __func__, clk->name);
+ return d;
}
+EXPORT_SYMBOL_GPL(clk_debugfs_add_file);
/**
* clk_debug_init - lazily create the debugfs clk tree visualization
@@ -425,19 +395,24 @@ static int __init clk_debug_init(void)
if (!rootdir)
return -ENOMEM;
- d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, NULL,
+ d = debugfs_create_file("clk_summary", S_IRUGO, rootdir, &all_lists,
&clk_summary_fops);
if (!d)
return -ENOMEM;
- d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, NULL,
+ d = debugfs_create_file("clk_dump", S_IRUGO, rootdir, &all_lists,
&clk_dump_fops);
if (!d)
return -ENOMEM;
- orphandir = debugfs_create_dir("orphans", rootdir);
+ d = debugfs_create_file("clk_orphan_summary", S_IRUGO, rootdir,
+ &orphan_list, &clk_summary_fops);
+ if (!d)
+ return -ENOMEM;
- if (!orphandir)
+ d = debugfs_create_file("clk_orphan_dump", S_IRUGO, rootdir,
+ &orphan_list, &clk_dump_fops);
+ if (!d)
return -ENOMEM;
clk_prepare_lock();
@@ -446,7 +421,7 @@ static int __init clk_debug_init(void)
clk_debug_create_subtree(clk, rootdir);
hlist_for_each_entry(clk, &clk_orphan_list, child_node)
- clk_debug_create_subtree(clk, orphandir);
+ clk_debug_create_subtree(clk, rootdir);
inited = 1;
@@ -1284,9 +1259,6 @@ static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
clk_disable(old_parent);
__clk_unprepare(old_parent);
}
-
- /* update debugfs with new clk tree topology */
- clk_debug_reparent(clk, parent);
}
static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
@@ -1683,7 +1655,6 @@ out:
void __clk_reparent(struct clk *clk, struct clk *new_parent)
{
clk_reparent(clk, new_parent);
- clk_debug_reparent(clk, new_parent);
__clk_recalc_accuracies(clk);
__clk_recalc_rates(clk, POST_RATE_CHANGE);
}
@@ -2414,6 +2385,7 @@ int of_clk_add_provider(struct device_node *np,
void *data)
{
struct of_clk_provider *cp;
+ int ret;
cp = kzalloc(sizeof(struct of_clk_provider), GFP_KERNEL);
if (!cp)
@@ -2428,7 +2400,11 @@ int of_clk_add_provider(struct device_node *np,
mutex_unlock(&of_clk_mutex);
pr_debug("Added clock from %s\n", np->full_name);
- return 0;
+ ret = of_clk_set_defaults(np, true);
+ if (ret < 0)
+ of_clk_del_provider(np);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(of_clk_add_provider);
@@ -2605,7 +2581,10 @@ void __init of_clk_init(const struct of_device_id *matches)
list_for_each_entry_safe(clk_provider, next,
&clk_provider_list, node) {
if (force || parent_ready(clk_provider->np)) {
+
clk_provider->clk_init_cb(clk_provider->np);
+ of_clk_set_defaults(clk_provider->np, true);
+
list_del(&clk_provider->node);
kfree(clk_provider);
is_init_done = true;
@@ -2620,7 +2599,6 @@ void __init of_clk_init(const struct of_device_id *matches)
*/
if (!is_init_done)
force = true;
-
}
}
#endif
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index f890b901c6bc..da4bda8b7fc7 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -101,8 +101,9 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
if (!IS_ERR(clk))
break;
else if (name && index >= 0) {
- pr_err("ERROR: could not get clock %s:%s(%i)\n",
- np->full_name, name ? name : "", index);
+ if (PTR_ERR(clk) != -EPROBE_DEFER)
+ pr_err("ERROR: could not get clock %s:%s(%i)\n",
+ np->full_name, name ? name : "", index);
return clk;
}
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
index 8ebf757d29e2..3821a88077ea 100644
--- a/drivers/clk/mvebu/clk-cpu.c
+++ b/drivers/clk/mvebu/clk-cpu.c
@@ -16,10 +16,19 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/delay.h>
+#include <linux/mvebu-pmsu.h>
+#include <asm/smp_plat.h>
-#define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0
-#define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC
-#define SYS_CTRL_CLK_DIVIDER_MASK 0x3F
+#define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0
+#define SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL 0xff
+#define SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT 8
+#define SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET 0x8
+#define SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT 16
+#define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC
+#define SYS_CTRL_CLK_DIVIDER_MASK 0x3F
+
+#define PMU_DFS_RATIO_SHIFT 16
+#define PMU_DFS_RATIO_MASK 0x3F
#define MAX_CPU 4
struct cpu_clk {
@@ -28,6 +37,7 @@ struct cpu_clk {
const char *clk_name;
const char *parent_name;
void __iomem *reg_base;
+ void __iomem *pmu_dfs;
};
static struct clk **clks;
@@ -62,8 +72,9 @@ static long clk_cpu_round_rate(struct clk_hw *hwclk, unsigned long rate,
return *parent_rate / div;
}
-static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
- unsigned long parent_rate)
+static int clk_cpu_off_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+
{
struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
u32 reg, div;
@@ -95,6 +106,58 @@ static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
return 0;
}
+static int clk_cpu_on_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ u32 reg;
+ unsigned long fabric_div, target_div, cur_rate;
+ struct cpu_clk *cpuclk = to_cpu_clk(hwclk);
+
+ /*
+ * PMU DFS registers are not mapped, Device Tree does not
+ * describes them. We cannot change the frequency dynamically.
+ */
+ if (!cpuclk->pmu_dfs)
+ return -ENODEV;
+
+ cur_rate = __clk_get_rate(hwclk->clk);
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL2_OFFSET);
+ fabric_div = (reg >> SYS_CTRL_CLK_DIVIDER_CTRL2_NBCLK_RATIO_SHIFT) &
+ SYS_CTRL_CLK_DIVIDER_MASK;
+
+ /* Frequency is going up */
+ if (rate == 2 * cur_rate)
+ target_div = fabric_div / 2;
+ /* Frequency is going down */
+ else
+ target_div = fabric_div;
+
+ if (target_div == 0)
+ target_div = 1;
+
+ reg = readl(cpuclk->pmu_dfs);
+ reg &= ~(PMU_DFS_RATIO_MASK << PMU_DFS_RATIO_SHIFT);
+ reg |= (target_div << PMU_DFS_RATIO_SHIFT);
+ writel(reg, cpuclk->pmu_dfs);
+
+ reg = readl(cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+ reg |= (SYS_CTRL_CLK_DIVIDER_CTRL_RESET_ALL <<
+ SYS_CTRL_CLK_DIVIDER_CTRL_RESET_SHIFT);
+ writel(reg, cpuclk->reg_base + SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET);
+
+ return mvebu_pmsu_dfs_request(cpuclk->cpu);
+}
+
+static int clk_cpu_set_rate(struct clk_hw *hwclk, unsigned long rate,
+ unsigned long parent_rate)
+{
+ if (__clk_is_enabled(hwclk->clk))
+ return clk_cpu_on_set_rate(hwclk, rate, parent_rate);
+ else
+ return clk_cpu_off_set_rate(hwclk, rate, parent_rate);
+}
+
static const struct clk_ops cpu_ops = {
.recalc_rate = clk_cpu_recalc_rate,
.round_rate = clk_cpu_round_rate,
@@ -105,6 +168,7 @@ static void __init of_cpu_clk_setup(struct device_node *node)
{
struct cpu_clk *cpuclk;
void __iomem *clock_complex_base = of_iomap(node, 0);
+ void __iomem *pmu_dfs_base = of_iomap(node, 1);
int ncpus = 0;
struct device_node *dn;
@@ -114,6 +178,10 @@ static void __init of_cpu_clk_setup(struct device_node *node)
return;
}
+ if (pmu_dfs_base == NULL)
+ pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n",
+ __func__);
+
for_each_node_by_type(dn, "cpu")
ncpus++;
@@ -146,6 +214,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
cpuclk[cpu].clk_name = clk_name;
cpuclk[cpu].cpu = cpu;
cpuclk[cpu].reg_base = clock_complex_base;
+ if (pmu_dfs_base)
+ cpuclk[cpu].pmu_dfs = pmu_dfs_base + 4 * cpu;
cpuclk[cpu].hw.init = &init;
init.name = cpuclk[cpu].clk_name;
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 7f696b7d4422..1107351ed346 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -4,6 +4,31 @@ config COMMON_CLK_QCOM
select REGMAP_MMIO
select RESET_CONTROLLER
+config APQ_GCC_8084
+ tristate "APQ8084 Global Clock Controller"
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the global clock controller on apq8084 devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2c, USB, SD/eMMC, SATA, PCIe, etc.
+
+config APQ_MMCC_8084
+ tristate "APQ8084 Multimedia Clock Controller"
+ select APQ_GCC_8084
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the multimedia clock controller on apq8084 devices.
+ Say Y if you want to support multimedia devices such as display,
+ graphics, video encode/decode, camera, etc.
+
+config IPQ_GCC_806X
+ tristate "IPQ806x Global Clock Controller"
+ depends on COMMON_CLK_QCOM
+ help
+ Support for the global clock controller on ipq806x devices.
+ Say Y if you want to use peripheral devices such as UART, SPI,
+ i2c, USB, SD/eMMC, etc.
+
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 689e05bf4f95..783cfb24faa4 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -8,6 +8,9 @@ clk-qcom-y += clk-rcg2.o
clk-qcom-y += clk-branch.o
clk-qcom-y += reset.o
+obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
+obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
+obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
diff --git a/drivers/clk/qcom/clk-pll.c b/drivers/clk/qcom/clk-pll.c
index 0f927c538613..9db03d3b1657 100644
--- a/drivers/clk/qcom/clk-pll.c
+++ b/drivers/clk/qcom/clk-pll.c
@@ -166,7 +166,7 @@ const struct clk_ops clk_pll_vote_ops = {
EXPORT_SYMBOL_GPL(clk_pll_vote_ops);
static void
-clk_pll_set_fsm_mode(struct clk_pll *pll, struct regmap *regmap)
+clk_pll_set_fsm_mode(struct clk_pll *pll, struct regmap *regmap, u8 lock_count)
{
u32 val;
u32 mask;
@@ -175,7 +175,7 @@ clk_pll_set_fsm_mode(struct clk_pll *pll, struct regmap *regmap)
regmap_update_bits(regmap, pll->mode_reg, PLL_VOTE_FSM_RESET, 0);
/* Program bias count and lock count */
- val = 1 << PLL_BIAS_COUNT_SHIFT;
+ val = 1 << PLL_BIAS_COUNT_SHIFT | lock_count << PLL_LOCK_COUNT_SHIFT;
mask = PLL_BIAS_COUNT_MASK << PLL_BIAS_COUNT_SHIFT;
mask |= PLL_LOCK_COUNT_MASK << PLL_LOCK_COUNT_SHIFT;
regmap_update_bits(regmap, pll->mode_reg, mask, val);
@@ -212,11 +212,20 @@ static void clk_pll_configure(struct clk_pll *pll, struct regmap *regmap,
regmap_update_bits(regmap, pll->config_reg, mask, val);
}
+void clk_pll_configure_sr(struct clk_pll *pll, struct regmap *regmap,
+ const struct pll_config *config, bool fsm_mode)
+{
+ clk_pll_configure(pll, regmap, config);
+ if (fsm_mode)
+ clk_pll_set_fsm_mode(pll, regmap, 8);
+}
+EXPORT_SYMBOL_GPL(clk_pll_configure_sr);
+
void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap,
const struct pll_config *config, bool fsm_mode)
{
clk_pll_configure(pll, regmap, config);
if (fsm_mode)
- clk_pll_set_fsm_mode(pll, regmap);
+ clk_pll_set_fsm_mode(pll, regmap, 0);
}
EXPORT_SYMBOL_GPL(clk_pll_configure_sr_hpm_lp);
diff --git a/drivers/clk/qcom/clk-pll.h b/drivers/clk/qcom/clk-pll.h
index 0775a99ca768..3003e9962472 100644
--- a/drivers/clk/qcom/clk-pll.h
+++ b/drivers/clk/qcom/clk-pll.h
@@ -60,6 +60,8 @@ struct pll_config {
u32 aux_output_mask;
};
+void clk_pll_configure_sr(struct clk_pll *pll, struct regmap *regmap,
+ const struct pll_config *config, bool fsm_mode);
void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap,
const struct pll_config *config, bool fsm_mode);
diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
index abfc2b675aea..b638c5846dbf 100644
--- a/drivers/clk/qcom/clk-rcg.c
+++ b/drivers/clk/qcom/clk-rcg.c
@@ -417,20 +417,25 @@ static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
}
-static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
+static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *p_rate, struct clk **p)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
- const struct freq_tbl *f;
+ const struct freq_tbl *f = rcg->freq_tbl;
+
+ *p = clk_get_parent_by_index(hw->clk, f->src);
+ *p_rate = __clk_round_rate(*p, rate);
+
+ return *p_rate;
+}
+
+static int __clk_rcg_set_rate(struct clk_rcg *rcg, const struct freq_tbl *f)
+{
u32 ns, md, ctl;
struct mn *mn = &rcg->mn;
u32 mask = 0;
unsigned int reset_reg;
- f = find_freq(rcg->freq_tbl, rate);
- if (!f)
- return -EINVAL;
-
if (rcg->mn.reset_in_cc)
reset_reg = rcg->clkr.enable_reg;
else
@@ -466,6 +471,27 @@ static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_rcg *rcg = to_clk_rcg(hw);
+ const struct freq_tbl *f;
+
+ f = find_freq(rcg->freq_tbl, rate);
+ if (!f)
+ return -EINVAL;
+
+ return __clk_rcg_set_rate(rcg, f);
+}
+
+static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_rcg *rcg = to_clk_rcg(hw);
+
+ return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
+}
+
static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
@@ -503,6 +529,17 @@ const struct clk_ops clk_rcg_ops = {
};
EXPORT_SYMBOL_GPL(clk_rcg_ops);
+const struct clk_ops clk_rcg_bypass_ops = {
+ .enable = clk_enable_regmap,
+ .disable = clk_disable_regmap,
+ .get_parent = clk_rcg_get_parent,
+ .set_parent = clk_rcg_set_parent,
+ .recalc_rate = clk_rcg_recalc_rate,
+ .determine_rate = clk_rcg_bypass_determine_rate,
+ .set_rate = clk_rcg_bypass_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
+
const struct clk_ops clk_dyn_rcg_ops = {
.enable = clk_enable_regmap,
.is_enabled = clk_is_enabled_regmap,
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
index b9ec11dfd1b4..ba0523cefd2e 100644
--- a/drivers/clk/qcom/clk-rcg.h
+++ b/drivers/clk/qcom/clk-rcg.h
@@ -95,6 +95,7 @@ struct clk_rcg {
};
extern const struct clk_ops clk_rcg_ops;
+extern const struct clk_ops clk_rcg_bypass_ops;
#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr)
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index 9b5a1cfc6b91..eeb3eea01f4c 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -27,30 +27,35 @@ struct qcom_cc {
struct clk *clks[];
};
-int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
+struct regmap *
+qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
{
void __iomem *base;
struct resource *res;
+ struct device *dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return ERR_CAST(base);
+
+ return devm_regmap_init_mmio(dev, base, desc->config);
+}
+EXPORT_SYMBOL_GPL(qcom_cc_map);
+
+int qcom_cc_really_probe(struct platform_device *pdev,
+ const struct qcom_cc_desc *desc, struct regmap *regmap)
+{
int i, ret;
struct device *dev = &pdev->dev;
struct clk *clk;
struct clk_onecell_data *data;
struct clk **clks;
- struct regmap *regmap;
struct qcom_reset_controller *reset;
struct qcom_cc *cc;
size_t num_clks = desc->num_clks;
struct clk_regmap **rclks = desc->clks;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(dev, res);
- if (IS_ERR(base))
- return PTR_ERR(base);
-
- regmap = devm_regmap_init_mmio(dev, base, desc->config);
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
GFP_KERNEL);
if (!cc)
@@ -91,6 +96,18 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
return ret;
}
+EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
+
+int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
+{
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return qcom_cc_really_probe(pdev, desc, regmap);
+}
EXPORT_SYMBOL_GPL(qcom_cc_probe);
void qcom_cc_remove(struct platform_device *pdev)
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 2c3cfc860348..2765e9d3da97 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -17,6 +17,7 @@ struct platform_device;
struct regmap_config;
struct clk_regmap;
struct qcom_reset_map;
+struct regmap;
struct qcom_cc_desc {
const struct regmap_config *config;
@@ -26,6 +27,11 @@ struct qcom_cc_desc {
size_t num_resets;
};
+extern struct regmap *qcom_cc_map(struct platform_device *pdev,
+ const struct qcom_cc_desc *desc);
+extern int qcom_cc_really_probe(struct platform_device *pdev,
+ const struct qcom_cc_desc *desc,
+ struct regmap *regmap);
extern int qcom_cc_probe(struct platform_device *pdev,
const struct qcom_cc_desc *desc);
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c
new file mode 100644
index 000000000000..ee52eb1c838a
--- /dev/null
+++ b/drivers/clk/qcom/gcc-apq8084.c
@@ -0,0 +1,3611 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-apq8084.h>
+#include <dt-bindings/reset/qcom,gcc-apq8084.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+
+#define P_XO 0
+#define P_GPLL0 1
+#define P_GPLL1 1
+#define P_GPLL4 2
+#define P_PCIE_0_1_PIPE_CLK 1
+#define P_SATA_ASIC0_CLK 1
+#define P_SATA_RX_CLK 1
+#define P_SLEEP_CLK 1
+
+static const u8 gcc_xo_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_GPLL0] = 1,
+};
+
+static const char *gcc_xo_gpll0[] = {
+ "xo",
+ "gpll0_vote",
+};
+
+static const u8 gcc_xo_gpll0_gpll4_map[] = {
+ [P_XO] = 0,
+ [P_GPLL0] = 1,
+ [P_GPLL4] = 5,
+};
+
+static const char *gcc_xo_gpll0_gpll4[] = {
+ "xo",
+ "gpll0_vote",
+ "gpll4_vote",
+};
+
+static const u8 gcc_xo_sata_asic0_map[] = {
+ [P_XO] = 0,
+ [P_SATA_ASIC0_CLK] = 2,
+};
+
+static const char *gcc_xo_sata_asic0[] = {
+ "xo",
+ "sata_asic0_clk",
+};
+
+static const u8 gcc_xo_sata_rx_map[] = {
+ [P_XO] = 0,
+ [P_SATA_RX_CLK] = 2,
+};
+
+static const char *gcc_xo_sata_rx[] = {
+ "xo",
+ "sata_rx_clk",
+};
+
+static const u8 gcc_xo_pcie_map[] = {
+ [P_XO] = 0,
+ [P_PCIE_0_1_PIPE_CLK] = 2,
+};
+
+static const char *gcc_xo_pcie[] = {
+ "xo",
+ "pcie_pipe",
+};
+
+static const u8 gcc_xo_pcie_sleep_map[] = {
+ [P_XO] = 0,
+ [P_SLEEP_CLK] = 6,
+};
+
+static const char *gcc_xo_pcie_sleep[] = {
+ "xo",
+ "sleep_clk_src",
+};
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+static struct clk_pll gpll0 = {
+ .l_reg = 0x0004,
+ .m_reg = 0x0008,
+ .n_reg = 0x000c,
+ .config_reg = 0x0014,
+ .mode_reg = 0x0000,
+ .status_reg = 0x001c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll0",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll0_vote = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll0_vote",
+ .parent_names = (const char *[]){ "gpll0" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_rcg2 config_noc_clk_src = {
+ .cmd_rcgr = 0x0150,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "config_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 periph_noc_clk_src = {
+ .cmd_rcgr = 0x0190,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "periph_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 system_noc_clk_src = {
+ .cmd_rcgr = 0x0120,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "system_noc_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_pll gpll1 = {
+ .l_reg = 0x0044,
+ .m_reg = 0x0048,
+ .n_reg = 0x004c,
+ .config_reg = 0x0054,
+ .mode_reg = 0x0040,
+ .status_reg = 0x005c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll1",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll1_vote = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll1_vote",
+ .parent_names = (const char *[]){ "gpll1" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll gpll4 = {
+ .l_reg = 0x1dc4,
+ .m_reg = 0x1dc8,
+ .n_reg = 0x1dcc,
+ .config_reg = 0x1dd4,
+ .mode_reg = 0x1dc0,
+ .status_reg = 0x1ddc,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gpll4",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap gpll4_vote = {
+ .enable_reg = 0x1480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll4_vote",
+ .parent_names = (const char *[]){ "gpll4" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_axi_clk[] = {
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ F(240000000, P_GPLL0, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ufs_axi_clk_src = {
+ .cmd_rcgr = 0x1d64,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_ufs_axi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ufs_axi_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = {
+ F(125000000, P_GPLL0, 1, 5, 24),
+ { }
+};
+
+static struct clk_rcg2 usb30_master_clk_src = {
+ .cmd_rcgr = 0x03d4,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb30_master_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb30_master_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_sec_master_clk[] = {
+ F(125000000, P_GPLL0, 1, 5, 24),
+ { }
+};
+
+static struct clk_rcg2 usb30_sec_master_clk_src = {
+ .cmd_rcgr = 0x1bd4,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb30_sec_master_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb30_sec_master_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_usb30_sec_mock_utmi_clk = {
+ .halt_reg = 0x1bd0,
+ .clkr = {
+ .enable_reg = 0x1bd0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_sec_mock_utmi_clk",
+ .parent_names = (const char *[]){
+ "usb30_sec_mock_utmi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_sec_sleep_clk = {
+ .halt_reg = 0x1bcc,
+ .clkr = {
+ .enable_reg = 0x1bcc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_sec_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0660,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup1_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk[] = {
+ F(960000, P_XO, 10, 1, 2),
+ F(4800000, P_XO, 4, 0, 0),
+ F(9600000, P_XO, 2, 0, 0),
+ F(15000000, P_GPLL0, 10, 1, 4),
+ F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+ .cmd_rcgr = 0x064c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup1_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x06e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup2_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+ .cmd_rcgr = 0x06cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup2_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0760,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup3_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+ .cmd_rcgr = 0x074c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup3_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x07e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup4_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+ .cmd_rcgr = 0x07cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup4_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0860,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup5_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+ .cmd_rcgr = 0x084c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup5_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x08e0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup6_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+ .cmd_rcgr = 0x08cc,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_qup6_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] = {
+ F(3686400, P_GPLL0, 1, 96, 15625),
+ F(7372800, P_GPLL0, 1, 192, 15625),
+ F(14745600, P_GPLL0, 1, 384, 15625),
+ F(16000000, P_GPLL0, 5, 2, 15),
+ F(19200000, P_XO, 1, 0, 0),
+ F(24000000, P_GPLL0, 5, 1, 5),
+ F(32000000, P_GPLL0, 1, 4, 75),
+ F(40000000, P_GPLL0, 15, 0, 0),
+ F(46400000, P_GPLL0, 1, 29, 375),
+ F(48000000, P_GPLL0, 12.5, 0, 0),
+ F(51200000, P_GPLL0, 1, 32, 375),
+ F(56000000, P_GPLL0, 1, 7, 75),
+ F(58982400, P_GPLL0, 1, 1536, 15625),
+ F(60000000, P_GPLL0, 10, 0, 0),
+ F(63160000, P_GPLL0, 9.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+ .cmd_rcgr = 0x068c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+ .cmd_rcgr = 0x070c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+ .cmd_rcgr = 0x078c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+ .cmd_rcgr = 0x080c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+ .cmd_rcgr = 0x088c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart5_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+ .cmd_rcgr = 0x090c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp1_uart6_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x09a0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup1_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+ .cmd_rcgr = 0x098c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup1_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0a20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup2_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0a0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup2_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0aa0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup3_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0a8c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup3_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0b20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup4_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0b0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup4_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0ba0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup5_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0b8c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup5_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = {
+ .cmd_rcgr = 0x0c20,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_i2c_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup6_i2c_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = {
+ .cmd_rcgr = 0x0c0c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_qup1_6_spi_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_qup6_spi_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+ .cmd_rcgr = 0x09cc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+ .cmd_rcgr = 0x0a4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart3_apps_clk_src = {
+ .cmd_rcgr = 0x0acc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart4_apps_clk_src = {
+ .cmd_rcgr = 0x0b4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart5_apps_clk_src = {
+ .cmd_rcgr = 0x0bcc,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart5_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 blsp2_uart6_apps_clk_src = {
+ .cmd_rcgr = 0x0c4c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "blsp2_uart6_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ce1_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(85710000, P_GPLL0, 7, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(171430000, P_GPLL0, 3.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ce1_clk_src = {
+ .cmd_rcgr = 0x1050,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ce1_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ce2_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(85710000, P_GPLL0, 7, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(171430000, P_GPLL0, 3.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ce2_clk_src = {
+ .cmd_rcgr = 0x1090,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_ce2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ce2_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_ce3_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(85710000, P_GPLL0, 7, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(171430000, P_GPLL0, 3.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 ce3_clk_src = {
+ .cmd_rcgr = 0x1d10,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_ce3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ce3_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_gp_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+ .cmd_rcgr = 0x1904,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_gp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp1_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+ .cmd_rcgr = 0x1944,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_gp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp2_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+ .cmd_rcgr = 0x1984,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_gp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gp3_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_1_aux_clk[] = {
+ F(1010000, P_XO, 1, 1, 19),
+ { }
+};
+
+static struct clk_rcg2 pcie_0_aux_clk_src = {
+ .cmd_rcgr = 0x1b2c,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_pcie_sleep_map,
+ .freq_tbl = ftbl_gcc_pcie_0_1_aux_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcie_0_aux_clk_src",
+ .parent_names = gcc_xo_pcie_sleep,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 pcie_1_aux_clk_src = {
+ .cmd_rcgr = 0x1bac,
+ .mnd_width = 16,
+ .hid_width = 5,
+ .parent_map = gcc_xo_pcie_sleep_map,
+ .freq_tbl = ftbl_gcc_pcie_0_1_aux_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcie_1_aux_clk_src",
+ .parent_names = gcc_xo_pcie_sleep,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_1_pipe_clk[] = {
+ F(125000000, P_PCIE_0_1_PIPE_CLK, 1, 0, 0),
+ F(250000000, P_PCIE_0_1_PIPE_CLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 pcie_0_pipe_clk_src = {
+ .cmd_rcgr = 0x1b18,
+ .hid_width = 5,
+ .parent_map = gcc_xo_pcie_map,
+ .freq_tbl = ftbl_gcc_pcie_0_1_pipe_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcie_0_pipe_clk_src",
+ .parent_names = gcc_xo_pcie,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 pcie_1_pipe_clk_src = {
+ .cmd_rcgr = 0x1b98,
+ .hid_width = 5,
+ .parent_map = gcc_xo_pcie_map,
+ .freq_tbl = ftbl_gcc_pcie_0_1_pipe_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pcie_1_pipe_clk_src",
+ .parent_names = gcc_xo_pcie,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk[] = {
+ F(60000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+ .cmd_rcgr = 0x0cd0,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_pdm2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pdm2_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sata_asic0_clk[] = {
+ F(75000000, P_SATA_ASIC0_CLK, 1, 0, 0),
+ F(150000000, P_SATA_ASIC0_CLK, 1, 0, 0),
+ F(300000000, P_SATA_ASIC0_CLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sata_asic0_clk_src = {
+ .cmd_rcgr = 0x1c94,
+ .hid_width = 5,
+ .parent_map = gcc_xo_sata_asic0_map,
+ .freq_tbl = ftbl_gcc_sata_asic0_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sata_asic0_clk_src",
+ .parent_names = gcc_xo_sata_asic0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sata_pmalive_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sata_pmalive_clk_src = {
+ .cmd_rcgr = 0x1c80,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sata_pmalive_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sata_pmalive_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sata_rx_clk[] = {
+ F(75000000, P_SATA_RX_CLK, 1, 0, 0),
+ F(150000000, P_SATA_RX_CLK, 1, 0, 0),
+ F(300000000, P_SATA_RX_CLK, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sata_rx_clk_src = {
+ .cmd_rcgr = 0x1ca8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_sata_rx_map,
+ .freq_tbl = ftbl_gcc_sata_rx_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sata_rx_clk_src",
+ .parent_names = gcc_xo_sata_rx,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sata_rx_oob_clk[] = {
+ F(100000000, P_GPLL0, 6, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sata_rx_oob_clk_src = {
+ .cmd_rcgr = 0x1c5c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sata_rx_oob_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sata_rx_oob_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_4_apps_clk[] = {
+ F(144000, P_XO, 16, 3, 25),
+ F(400000, P_XO, 12, 1, 4),
+ F(20000000, P_GPLL0, 15, 1, 2),
+ F(25000000, P_GPLL0, 12, 1, 2),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(192000000, P_GPLL4, 4, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ F(384000000, P_GPLL4, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+ .cmd_rcgr = 0x04d0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_gpll4_map,
+ .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc1_apps_clk_src",
+ .parent_names = gcc_xo_gpll0_gpll4,
+ .num_parents = 3,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+ .cmd_rcgr = 0x0510,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc2_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc3_apps_clk_src = {
+ .cmd_rcgr = 0x0550,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc3_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 sdcc4_apps_clk_src = {
+ .cmd_rcgr = 0x0590,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "sdcc4_apps_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_tsif_ref_clk[] = {
+ F(105000, P_XO, 2, 1, 91),
+ { }
+};
+
+static struct clk_rcg2 tsif_ref_clk_src = {
+ .cmd_rcgr = 0x0d90,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_tsif_ref_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "tsif_ref_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = {
+ F(60000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+ .cmd_rcgr = 0x03e8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb30_mock_utmi_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_sec_mock_utmi_clk[] = {
+ F(125000000, P_GPLL0, 1, 5, 24),
+ { }
+};
+
+static struct clk_rcg2 usb30_sec_mock_utmi_clk_src = {
+ .cmd_rcgr = 0x1be8,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb30_sec_mock_utmi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb30_sec_mock_utmi_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
+ F(75000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hs_system_clk_src = {
+ .cmd_rcgr = 0x0490,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hs_system_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hsic_clk[] = {
+ F(480000000, P_GPLL1, 1, 0, 0),
+ { }
+};
+
+static u8 usb_hsic_clk_src_map[] = {
+ [P_XO] = 0,
+ [P_GPLL1] = 4,
+};
+
+static struct clk_rcg2 usb_hsic_clk_src = {
+ .cmd_rcgr = 0x0440,
+ .hid_width = 5,
+ .parent_map = usb_hsic_clk_src_map,
+ .freq_tbl = ftbl_gcc_usb_hsic_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hsic_clk_src",
+ .parent_names = (const char *[]){
+ "xo",
+ "gpll1_vote",
+ },
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hsic_ahb_clk_src[] = {
+ F(60000000, P_GPLL1, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hsic_ahb_clk_src = {
+ .cmd_rcgr = 0x046c,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = usb_hsic_clk_src_map,
+ .freq_tbl = ftbl_gcc_usb_hsic_ahb_clk_src,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hsic_ahb_clk_src",
+ .parent_names = (const char *[]){
+ "xo",
+ "gpll1_vote",
+ },
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hsic_io_cal_clk[] = {
+ F(9600000, P_XO, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hsic_io_cal_clk_src = {
+ .cmd_rcgr = 0x0458,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_hsic_io_cal_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hsic_io_cal_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_mock_utmi_clk = {
+ .halt_reg = 0x1f14,
+ .clkr = {
+ .enable_reg = 0x1f14,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_mock_utmi_clk",
+ .parent_names = (const char *[]){
+ "usb_hsic_mock_utmi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hsic_mock_utmi_clk[] = {
+ F(60000000, P_GPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hsic_mock_utmi_clk_src = {
+ .cmd_rcgr = 0x1f00,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_hsic_mock_utmi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hsic_mock_utmi_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 1,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static const struct freq_tbl ftbl_gcc_usb_hsic_system_clk[] = {
+ F(75000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 usb_hsic_system_clk_src = {
+ .cmd_rcgr = 0x041c,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_gcc_usb_hsic_system_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "usb_hsic_system_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch gcc_bam_dma_ahb_clk = {
+ .halt_reg = 0x0d44,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(12),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_bam_dma_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+ .halt_reg = 0x05c4,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(17),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+ .halt_reg = 0x0648,
+ .clkr = {
+ .enable_reg = 0x0648,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup1_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup1_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+ .halt_reg = 0x0644,
+ .clkr = {
+ .enable_reg = 0x0644,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup1_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup1_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+ .halt_reg = 0x06c8,
+ .clkr = {
+ .enable_reg = 0x06c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup2_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup2_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+ .halt_reg = 0x06c4,
+ .clkr = {
+ .enable_reg = 0x06c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup2_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup2_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+ .halt_reg = 0x0748,
+ .clkr = {
+ .enable_reg = 0x0748,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup3_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup3_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+ .halt_reg = 0x0744,
+ .clkr = {
+ .enable_reg = 0x0744,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup3_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup3_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+ .halt_reg = 0x07c8,
+ .clkr = {
+ .enable_reg = 0x07c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup4_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup4_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+ .halt_reg = 0x07c4,
+ .clkr = {
+ .enable_reg = 0x07c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup4_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup4_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+ .halt_reg = 0x0848,
+ .clkr = {
+ .enable_reg = 0x0848,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup5_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup5_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+ .halt_reg = 0x0844,
+ .clkr = {
+ .enable_reg = 0x0844,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup5_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup5_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+ .halt_reg = 0x08c8,
+ .clkr = {
+ .enable_reg = 0x08c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup6_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup6_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+ .halt_reg = 0x08c4,
+ .clkr = {
+ .enable_reg = 0x08c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_qup6_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_qup6_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+ .halt_reg = 0x0684,
+ .clkr = {
+ .enable_reg = 0x0684,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart1_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+ .halt_reg = 0x0704,
+ .clkr = {
+ .enable_reg = 0x0704,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart2_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+ .halt_reg = 0x0784,
+ .clkr = {
+ .enable_reg = 0x0784,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart3_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+ .halt_reg = 0x0804,
+ .clkr = {
+ .enable_reg = 0x0804,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart4_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart5_apps_clk = {
+ .halt_reg = 0x0884,
+ .clkr = {
+ .enable_reg = 0x0884,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart5_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart5_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp1_uart6_apps_clk = {
+ .halt_reg = 0x0904,
+ .clkr = {
+ .enable_reg = 0x0904,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp1_uart6_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp1_uart6_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+ .halt_reg = 0x0944,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(15),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+ .halt_reg = 0x0988,
+ .clkr = {
+ .enable_reg = 0x0988,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup1_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup1_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+ .halt_reg = 0x0984,
+ .clkr = {
+ .enable_reg = 0x0984,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup1_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup1_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+ .halt_reg = 0x0a08,
+ .clkr = {
+ .enable_reg = 0x0a08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup2_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup2_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+ .halt_reg = 0x0a04,
+ .clkr = {
+ .enable_reg = 0x0a04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup2_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup2_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+ .halt_reg = 0x0a88,
+ .clkr = {
+ .enable_reg = 0x0a88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup3_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup3_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+ .halt_reg = 0x0a84,
+ .clkr = {
+ .enable_reg = 0x0a84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup3_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup3_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+ .halt_reg = 0x0b08,
+ .clkr = {
+ .enable_reg = 0x0b08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup4_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup4_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+ .halt_reg = 0x0b04,
+ .clkr = {
+ .enable_reg = 0x0b04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup4_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup4_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = {
+ .halt_reg = 0x0b88,
+ .clkr = {
+ .enable_reg = 0x0b88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup5_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup5_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = {
+ .halt_reg = 0x0b84,
+ .clkr = {
+ .enable_reg = 0x0b84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup5_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup5_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = {
+ .halt_reg = 0x0c08,
+ .clkr = {
+ .enable_reg = 0x0c08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup6_i2c_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup6_i2c_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = {
+ .halt_reg = 0x0c04,
+ .clkr = {
+ .enable_reg = 0x0c04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_qup6_spi_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_qup6_spi_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+ .halt_reg = 0x09c4,
+ .clkr = {
+ .enable_reg = 0x09c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart1_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+ .halt_reg = 0x0a44,
+ .clkr = {
+ .enable_reg = 0x0a44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart2_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart3_apps_clk = {
+ .halt_reg = 0x0ac4,
+ .clkr = {
+ .enable_reg = 0x0ac4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart3_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart4_apps_clk = {
+ .halt_reg = 0x0b44,
+ .clkr = {
+ .enable_reg = 0x0b44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart4_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart5_apps_clk = {
+ .halt_reg = 0x0bc4,
+ .clkr = {
+ .enable_reg = 0x0bc4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart5_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart5_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_blsp2_uart6_apps_clk = {
+ .halt_reg = 0x0c44,
+ .clkr = {
+ .enable_reg = 0x0c44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_blsp2_uart6_apps_clk",
+ .parent_names = (const char *[]){
+ "blsp2_uart6_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+ .halt_reg = 0x0e04,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(10),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_boot_rom_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce1_ahb_clk = {
+ .halt_reg = 0x104c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(3),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce1_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce1_axi_clk = {
+ .halt_reg = 0x1048,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce1_axi_clk",
+ .parent_names = (const char *[]){
+ "system_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce1_clk = {
+ .halt_reg = 0x1050,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(5),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce1_clk",
+ .parent_names = (const char *[]){
+ "ce1_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce2_ahb_clk = {
+ .halt_reg = 0x108c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce2_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce2_axi_clk = {
+ .halt_reg = 0x1088,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce2_axi_clk",
+ .parent_names = (const char *[]){
+ "system_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce2_clk = {
+ .halt_reg = 0x1090,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce2_clk",
+ .parent_names = (const char *[]){
+ "ce2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce3_ahb_clk = {
+ .halt_reg = 0x1d0c,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1d0c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce3_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce3_axi_clk = {
+ .halt_reg = 0x1088,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1d08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce3_axi_clk",
+ .parent_names = (const char *[]){
+ "system_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ce3_clk = {
+ .halt_reg = 0x1090,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1d04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ce3_clk",
+ .parent_names = (const char *[]){
+ "ce3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+ .halt_reg = 0x1900,
+ .clkr = {
+ .enable_reg = 0x1900,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp1_clk",
+ .parent_names = (const char *[]){
+ "gp1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+ .halt_reg = 0x1940,
+ .clkr = {
+ .enable_reg = 0x1940,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp2_clk",
+ .parent_names = (const char *[]){
+ "gp2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+ .halt_reg = 0x1980,
+ .clkr = {
+ .enable_reg = 0x1980,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_gp3_clk",
+ .parent_names = (const char *[]){
+ "gp3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ocmem_noc_cfg_ahb_clk = {
+ .halt_reg = 0x0248,
+ .clkr = {
+ .enable_reg = 0x0248,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ocmem_noc_cfg_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+ .halt_reg = 0x1b10,
+ .clkr = {
+ .enable_reg = 0x1b10,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_aux_clk",
+ .parent_names = (const char *[]){
+ "pcie_0_aux_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+ .halt_reg = 0x1b0c,
+ .clkr = {
+ .enable_reg = 0x1b0c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_cfg_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+ .halt_reg = 0x1b08,
+ .clkr = {
+ .enable_reg = 0x1b08,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_mstr_axi_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+ .halt_reg = 0x1b14,
+ .clkr = {
+ .enable_reg = 0x1b14,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_pipe_clk",
+ .parent_names = (const char *[]){
+ "pcie_0_pipe_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+ .halt_reg = 0x1b04,
+ .clkr = {
+ .enable_reg = 0x1b04,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_0_slv_axi_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_1_aux_clk = {
+ .halt_reg = 0x1b90,
+ .clkr = {
+ .enable_reg = 0x1b90,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_aux_clk",
+ .parent_names = (const char *[]){
+ "pcie_1_aux_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
+ .halt_reg = 0x1b8c,
+ .clkr = {
+ .enable_reg = 0x1b8c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_cfg_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+ .halt_reg = 0x1b88,
+ .clkr = {
+ .enable_reg = 0x1b88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_mstr_axi_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_1_pipe_clk = {
+ .halt_reg = 0x1b94,
+ .clkr = {
+ .enable_reg = 0x1b94,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_pipe_clk",
+ .parent_names = (const char *[]){
+ "pcie_1_pipe_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+ .halt_reg = 0x1b84,
+ .clkr = {
+ .enable_reg = 0x1b84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pcie_1_slv_axi_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+ .halt_reg = 0x0ccc,
+ .clkr = {
+ .enable_reg = 0x0ccc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pdm2_clk",
+ .parent_names = (const char *[]){
+ "pdm2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+ .halt_reg = 0x0cc4,
+ .clkr = {
+ .enable_reg = 0x0cc4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_pdm_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_periph_noc_usb_hsic_ahb_clk = {
+ .halt_reg = 0x01a4,
+ .clkr = {
+ .enable_reg = 0x01a4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_periph_noc_usb_hsic_ahb_clk",
+ .parent_names = (const char *[]){
+ "usb_hsic_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+ .halt_reg = 0x0d04,
+ .halt_check = BRANCH_HALT_VOTED,
+ .clkr = {
+ .enable_reg = 0x1484,
+ .enable_mask = BIT(13),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_prng_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_asic0_clk = {
+ .halt_reg = 0x1c54,
+ .clkr = {
+ .enable_reg = 0x1c54,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_asic0_clk",
+ .parent_names = (const char *[]){
+ "sata_asic0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_axi_clk = {
+ .halt_reg = 0x1c44,
+ .clkr = {
+ .enable_reg = 0x1c44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_axi_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_cfg_ahb_clk = {
+ .halt_reg = 0x1c48,
+ .clkr = {
+ .enable_reg = 0x1c48,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_cfg_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_pmalive_clk = {
+ .halt_reg = 0x1c50,
+ .clkr = {
+ .enable_reg = 0x1c50,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_pmalive_clk",
+ .parent_names = (const char *[]){
+ "sata_pmalive_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_rx_clk = {
+ .halt_reg = 0x1c58,
+ .clkr = {
+ .enable_reg = 0x1c58,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_rx_clk",
+ .parent_names = (const char *[]){
+ "sata_rx_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sata_rx_oob_clk = {
+ .halt_reg = 0x1c4c,
+ .clkr = {
+ .enable_reg = 0x1c4c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sata_rx_oob_clk",
+ .parent_names = (const char *[]){
+ "sata_rx_oob_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+ .halt_reg = 0x04c8,
+ .clkr = {
+ .enable_reg = 0x04c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+ .halt_reg = 0x04c4,
+ .clkr = {
+ .enable_reg = 0x04c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_apps_clk",
+ .parent_names = (const char *[]){
+ "sdcc1_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_cdccal_ff_clk = {
+ .halt_reg = 0x04e8,
+ .clkr = {
+ .enable_reg = 0x04e8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_cdccal_ff_clk",
+ .parent_names = (const char *[]){
+ "xo"
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = {
+ .halt_reg = 0x04e4,
+ .clkr = {
+ .enable_reg = 0x04e4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc1_cdccal_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src"
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+ .halt_reg = 0x0508,
+ .clkr = {
+ .enable_reg = 0x0508,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc2_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+ .halt_reg = 0x0504,
+ .clkr = {
+ .enable_reg = 0x0504,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc2_apps_clk",
+ .parent_names = (const char *[]){
+ "sdcc2_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc3_ahb_clk = {
+ .halt_reg = 0x0548,
+ .clkr = {
+ .enable_reg = 0x0548,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc3_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc3_apps_clk = {
+ .halt_reg = 0x0544,
+ .clkr = {
+ .enable_reg = 0x0544,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc3_apps_clk",
+ .parent_names = (const char *[]){
+ "sdcc3_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc4_ahb_clk = {
+ .halt_reg = 0x0588,
+ .clkr = {
+ .enable_reg = 0x0588,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc4_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sdcc4_apps_clk = {
+ .halt_reg = 0x0584,
+ .clkr = {
+ .enable_reg = 0x0584,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sdcc4_apps_clk",
+ .parent_names = (const char *[]){
+ "sdcc4_apps_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sys_noc_ufs_axi_clk = {
+ .halt_reg = 0x013c,
+ .clkr = {
+ .enable_reg = 0x013c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sys_noc_ufs_axi_clk",
+ .parent_names = (const char *[]){
+ "ufs_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_axi_clk = {
+ .halt_reg = 0x0108,
+ .clkr = {
+ .enable_reg = 0x0108,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sys_noc_usb3_axi_clk",
+ .parent_names = (const char *[]){
+ "usb30_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_sec_axi_clk = {
+ .halt_reg = 0x0138,
+ .clkr = {
+ .enable_reg = 0x0138,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_sys_noc_usb3_sec_axi_clk",
+ .parent_names = (const char *[]){
+ "usb30_sec_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_tsif_ahb_clk = {
+ .halt_reg = 0x0d84,
+ .clkr = {
+ .enable_reg = 0x0d84,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_tsif_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_tsif_inactivity_timers_clk = {
+ .halt_reg = 0x0d8c,
+ .clkr = {
+ .enable_reg = 0x0d8c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_tsif_inactivity_timers_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_tsif_ref_clk = {
+ .halt_reg = 0x0d88,
+ .clkr = {
+ .enable_reg = 0x0d88,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_tsif_ref_clk",
+ .parent_names = (const char *[]){
+ "tsif_ref_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_ahb_clk = {
+ .halt_reg = 0x1d48,
+ .clkr = {
+ .enable_reg = 0x1d48,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_ahb_clk",
+ .parent_names = (const char *[]){
+ "config_noc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_axi_clk = {
+ .halt_reg = 0x1d44,
+ .clkr = {
+ .enable_reg = 0x1d44,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_axi_clk",
+ .parent_names = (const char *[]){
+ "ufs_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_rx_cfg_clk = {
+ .halt_reg = 0x1d50,
+ .clkr = {
+ .enable_reg = 0x1d50,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_rx_cfg_clk",
+ .parent_names = (const char *[]){
+ "ufs_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
+ .halt_reg = 0x1d5c,
+ .clkr = {
+ .enable_reg = 0x1d5c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_rx_symbol_0_clk",
+ .parent_names = (const char *[]){
+ "ufs_rx_symbol_0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
+ .halt_reg = 0x1d60,
+ .clkr = {
+ .enable_reg = 0x1d60,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_rx_symbol_1_clk",
+ .parent_names = (const char *[]){
+ "ufs_rx_symbol_1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_tx_cfg_clk = {
+ .halt_reg = 0x1d4c,
+ .clkr = {
+ .enable_reg = 0x1d4c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_tx_cfg_clk",
+ .parent_names = (const char *[]){
+ "ufs_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
+ .halt_reg = 0x1d54,
+ .clkr = {
+ .enable_reg = 0x1d54,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_tx_symbol_0_clk",
+ .parent_names = (const char *[]){
+ "ufs_tx_symbol_0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_ufs_tx_symbol_1_clk = {
+ .halt_reg = 0x1d58,
+ .clkr = {
+ .enable_reg = 0x1d58,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_ufs_tx_symbol_1_clk",
+ .parent_names = (const char *[]){
+ "ufs_tx_symbol_1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb2a_phy_sleep_clk = {
+ .halt_reg = 0x04ac,
+ .clkr = {
+ .enable_reg = 0x04ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb2a_phy_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb2b_phy_sleep_clk = {
+ .halt_reg = 0x04b4,
+ .clkr = {
+ .enable_reg = 0x04b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb2b_phy_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+ .halt_reg = 0x03c8,
+ .clkr = {
+ .enable_reg = 0x03c8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_master_clk",
+ .parent_names = (const char *[]){
+ "usb30_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_sec_master_clk = {
+ .halt_reg = 0x1bc8,
+ .clkr = {
+ .enable_reg = 0x1bc8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_sec_master_clk",
+ .parent_names = (const char *[]){
+ "usb30_sec_master_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+ .halt_reg = 0x03d0,
+ .clkr = {
+ .enable_reg = 0x03d0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_mock_utmi_clk",
+ .parent_names = (const char *[]){
+ "usb30_mock_utmi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+ .halt_reg = 0x03cc,
+ .clkr = {
+ .enable_reg = 0x03cc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb30_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_ahb_clk = {
+ .halt_reg = 0x0488,
+ .clkr = {
+ .enable_reg = 0x0488,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hs_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_inactivity_timers_clk = {
+ .halt_reg = 0x048c,
+ .clkr = {
+ .enable_reg = 0x048c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hs_inactivity_timers_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hs_system_clk = {
+ .halt_reg = 0x0484,
+ .clkr = {
+ .enable_reg = 0x0484,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hs_system_clk",
+ .parent_names = (const char *[]){
+ "usb_hs_system_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_ahb_clk = {
+ .halt_reg = 0x0408,
+ .clkr = {
+ .enable_reg = 0x0408,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_ahb_clk",
+ .parent_names = (const char *[]){
+ "periph_noc_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_clk = {
+ .halt_reg = 0x0410,
+ .clkr = {
+ .enable_reg = 0x0410,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_clk",
+ .parent_names = (const char *[]){
+ "usb_hsic_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_io_cal_clk = {
+ .halt_reg = 0x0414,
+ .clkr = {
+ .enable_reg = 0x0414,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_io_cal_clk",
+ .parent_names = (const char *[]){
+ "usb_hsic_io_cal_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_io_cal_sleep_clk = {
+ .halt_reg = 0x0418,
+ .clkr = {
+ .enable_reg = 0x0418,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_io_cal_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_usb_hsic_system_clk = {
+ .halt_reg = 0x040c,
+ .clkr = {
+ .enable_reg = 0x040c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_usb_hsic_system_clk",
+ .parent_names = (const char *[]){
+ "usb_hsic_system_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap *gcc_apq8084_clocks[] = {
+ [GPLL0] = &gpll0.clkr,
+ [GPLL0_VOTE] = &gpll0_vote,
+ [GPLL1] = &gpll1.clkr,
+ [GPLL1_VOTE] = &gpll1_vote,
+ [GPLL4] = &gpll4.clkr,
+ [GPLL4_VOTE] = &gpll4_vote,
+ [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
+ [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
+ [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
+ [UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
+ [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+ [USB30_SEC_MASTER_CLK_SRC] = &usb30_sec_master_clk_src.clkr,
+ [USB_HSIC_AHB_CLK_SRC] = &usb_hsic_ahb_clk_src.clkr,
+ [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+ [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+ [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+ [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+ [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+ [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+ [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+ [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+ [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+ [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr,
+ [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr,
+ [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr,
+ [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr,
+ [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr,
+ [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr,
+ [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr,
+ [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr,
+ [BLSP2_QUP5_I2C_APPS_CLK_SRC] = &blsp2_qup5_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP5_SPI_APPS_CLK_SRC] = &blsp2_qup5_spi_apps_clk_src.clkr,
+ [BLSP2_QUP6_I2C_APPS_CLK_SRC] = &blsp2_qup6_i2c_apps_clk_src.clkr,
+ [BLSP2_QUP6_SPI_APPS_CLK_SRC] = &blsp2_qup6_spi_apps_clk_src.clkr,
+ [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr,
+ [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr,
+ [BLSP2_UART3_APPS_CLK_SRC] = &blsp2_uart3_apps_clk_src.clkr,
+ [BLSP2_UART4_APPS_CLK_SRC] = &blsp2_uart4_apps_clk_src.clkr,
+ [BLSP2_UART5_APPS_CLK_SRC] = &blsp2_uart5_apps_clk_src.clkr,
+ [BLSP2_UART6_APPS_CLK_SRC] = &blsp2_uart6_apps_clk_src.clkr,
+ [CE1_CLK_SRC] = &ce1_clk_src.clkr,
+ [CE2_CLK_SRC] = &ce2_clk_src.clkr,
+ [CE3_CLK_SRC] = &ce3_clk_src.clkr,
+ [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+ [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+ [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+ [PCIE_0_AUX_CLK_SRC] = &pcie_0_aux_clk_src.clkr,
+ [PCIE_0_PIPE_CLK_SRC] = &pcie_0_pipe_clk_src.clkr,
+ [PCIE_1_AUX_CLK_SRC] = &pcie_1_aux_clk_src.clkr,
+ [PCIE_1_PIPE_CLK_SRC] = &pcie_1_pipe_clk_src.clkr,
+ [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+ [SATA_ASIC0_CLK_SRC] = &sata_asic0_clk_src.clkr,
+ [SATA_PMALIVE_CLK_SRC] = &sata_pmalive_clk_src.clkr,
+ [SATA_RX_CLK_SRC] = &sata_rx_clk_src.clkr,
+ [SATA_RX_OOB_CLK_SRC] = &sata_rx_oob_clk_src.clkr,
+ [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+ [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+ [SDCC3_APPS_CLK_SRC] = &sdcc3_apps_clk_src.clkr,
+ [SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr,
+ [TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
+ [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+ [USB30_SEC_MOCK_UTMI_CLK_SRC] = &usb30_sec_mock_utmi_clk_src.clkr,
+ [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr,
+ [USB_HSIC_CLK_SRC] = &usb_hsic_clk_src.clkr,
+ [USB_HSIC_IO_CAL_CLK_SRC] = &usb_hsic_io_cal_clk_src.clkr,
+ [USB_HSIC_MOCK_UTMI_CLK_SRC] = &usb_hsic_mock_utmi_clk_src.clkr,
+ [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_clk_src.clkr,
+ [GCC_BAM_DMA_AHB_CLK] = &gcc_bam_dma_ahb_clk.clkr,
+ [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+ [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
+ [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+ [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+ [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+ [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+ [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr,
+ [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr,
+ [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr,
+ [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+ [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP5_I2C_APPS_CLK] = &gcc_blsp2_qup5_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP5_SPI_APPS_CLK] = &gcc_blsp2_qup5_spi_apps_clk.clkr,
+ [GCC_BLSP2_QUP6_I2C_APPS_CLK] = &gcc_blsp2_qup6_i2c_apps_clk.clkr,
+ [GCC_BLSP2_QUP6_SPI_APPS_CLK] = &gcc_blsp2_qup6_spi_apps_clk.clkr,
+ [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr,
+ [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr,
+ [GCC_BLSP2_UART3_APPS_CLK] = &gcc_blsp2_uart3_apps_clk.clkr,
+ [GCC_BLSP2_UART4_APPS_CLK] = &gcc_blsp2_uart4_apps_clk.clkr,
+ [GCC_BLSP2_UART5_APPS_CLK] = &gcc_blsp2_uart5_apps_clk.clkr,
+ [GCC_BLSP2_UART6_APPS_CLK] = &gcc_blsp2_uart6_apps_clk.clkr,
+ [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+ [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr,
+ [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr,
+ [GCC_CE1_CLK] = &gcc_ce1_clk.clkr,
+ [GCC_CE2_AHB_CLK] = &gcc_ce2_ahb_clk.clkr,
+ [GCC_CE2_AXI_CLK] = &gcc_ce2_axi_clk.clkr,
+ [GCC_CE2_CLK] = &gcc_ce2_clk.clkr,
+ [GCC_CE3_AHB_CLK] = &gcc_ce3_ahb_clk.clkr,
+ [GCC_CE3_AXI_CLK] = &gcc_ce3_axi_clk.clkr,
+ [GCC_CE3_CLK] = &gcc_ce3_clk.clkr,
+ [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+ [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+ [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+ [GCC_OCMEM_NOC_CFG_AHB_CLK] = &gcc_ocmem_noc_cfg_ahb_clk.clkr,
+ [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+ [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+ [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+ [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+ [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+ [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr,
+ [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr,
+ [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr,
+ [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr,
+ [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr,
+ [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+ [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+ [GCC_PERIPH_NOC_USB_HSIC_AHB_CLK] = &gcc_periph_noc_usb_hsic_ahb_clk.clkr,
+ [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+ [GCC_SATA_ASIC0_CLK] = &gcc_sata_asic0_clk.clkr,
+ [GCC_SATA_AXI_CLK] = &gcc_sata_axi_clk.clkr,
+ [GCC_SATA_CFG_AHB_CLK] = &gcc_sata_cfg_ahb_clk.clkr,
+ [GCC_SATA_PMALIVE_CLK] = &gcc_sata_pmalive_clk.clkr,
+ [GCC_SATA_RX_CLK] = &gcc_sata_rx_clk.clkr,
+ [GCC_SATA_RX_OOB_CLK] = &gcc_sata_rx_oob_clk.clkr,
+ [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+ [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+ [GCC_SDCC1_CDCCAL_FF_CLK] = &gcc_sdcc1_cdccal_ff_clk.clkr,
+ [GCC_SDCC1_CDCCAL_SLEEP_CLK] = &gcc_sdcc1_cdccal_sleep_clk.clkr,
+ [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+ [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+ [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr,
+ [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
+ [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
+ [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
+ [GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr,
+ [GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr,
+ [GCC_SYS_NOC_USB3_SEC_AXI_CLK] = &gcc_sys_noc_usb3_sec_axi_clk.clkr,
+ [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
+ [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr,
+ [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
+ [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr,
+ [GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr,
+ [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr,
+ [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr,
+ [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
+ [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr,
+ [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr,
+ [GCC_UFS_TX_SYMBOL_1_CLK] = &gcc_ufs_tx_symbol_1_clk.clkr,
+ [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr,
+ [GCC_USB2B_PHY_SLEEP_CLK] = &gcc_usb2b_phy_sleep_clk.clkr,
+ [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+ [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+ [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+ [GCC_USB30_SEC_MASTER_CLK] = &gcc_usb30_sec_master_clk.clkr,
+ [GCC_USB30_SEC_MOCK_UTMI_CLK] = &gcc_usb30_sec_mock_utmi_clk.clkr,
+ [GCC_USB30_SEC_SLEEP_CLK] = &gcc_usb30_sec_sleep_clk.clkr,
+ [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
+ [GCC_USB_HS_INACTIVITY_TIMERS_CLK] = &gcc_usb_hs_inactivity_timers_clk.clkr,
+ [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
+ [GCC_USB_HSIC_AHB_CLK] = &gcc_usb_hsic_ahb_clk.clkr,
+ [GCC_USB_HSIC_CLK] = &gcc_usb_hsic_clk.clkr,
+ [GCC_USB_HSIC_IO_CAL_CLK] = &gcc_usb_hsic_io_cal_clk.clkr,
+ [GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr,
+ [GCC_USB_HSIC_MOCK_UTMI_CLK] = &gcc_usb_hsic_mock_utmi_clk.clkr,
+ [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_apq8084_resets[] = {
+ [GCC_SYSTEM_NOC_BCR] = { 0x0100 },
+ [GCC_CONFIG_NOC_BCR] = { 0x0140 },
+ [GCC_PERIPH_NOC_BCR] = { 0x0180 },
+ [GCC_IMEM_BCR] = { 0x0200 },
+ [GCC_MMSS_BCR] = { 0x0240 },
+ [GCC_QDSS_BCR] = { 0x0300 },
+ [GCC_USB_30_BCR] = { 0x03c0 },
+ [GCC_USB3_PHY_BCR] = { 0x03fc },
+ [GCC_USB_HS_HSIC_BCR] = { 0x0400 },
+ [GCC_USB_HS_BCR] = { 0x0480 },
+ [GCC_USB2A_PHY_BCR] = { 0x04a8 },
+ [GCC_USB2B_PHY_BCR] = { 0x04b0 },
+ [GCC_SDCC1_BCR] = { 0x04c0 },
+ [GCC_SDCC2_BCR] = { 0x0500 },
+ [GCC_SDCC3_BCR] = { 0x0540 },
+ [GCC_SDCC4_BCR] = { 0x0580 },
+ [GCC_BLSP1_BCR] = { 0x05c0 },
+ [GCC_BLSP1_QUP1_BCR] = { 0x0640 },
+ [GCC_BLSP1_UART1_BCR] = { 0x0680 },
+ [GCC_BLSP1_QUP2_BCR] = { 0x06c0 },
+ [GCC_BLSP1_UART2_BCR] = { 0x0700 },
+ [GCC_BLSP1_QUP3_BCR] = { 0x0740 },
+ [GCC_BLSP1_UART3_BCR] = { 0x0780 },
+ [GCC_BLSP1_QUP4_BCR] = { 0x07c0 },
+ [GCC_BLSP1_UART4_BCR] = { 0x0800 },
+ [GCC_BLSP1_QUP5_BCR] = { 0x0840 },
+ [GCC_BLSP1_UART5_BCR] = { 0x0880 },
+ [GCC_BLSP1_QUP6_BCR] = { 0x08c0 },
+ [GCC_BLSP1_UART6_BCR] = { 0x0900 },
+ [GCC_BLSP2_BCR] = { 0x0940 },
+ [GCC_BLSP2_QUP1_BCR] = { 0x0980 },
+ [GCC_BLSP2_UART1_BCR] = { 0x09c0 },
+ [GCC_BLSP2_QUP2_BCR] = { 0x0a00 },
+ [GCC_BLSP2_UART2_BCR] = { 0x0a40 },
+ [GCC_BLSP2_QUP3_BCR] = { 0x0a80 },
+ [GCC_BLSP2_UART3_BCR] = { 0x0ac0 },
+ [GCC_BLSP2_QUP4_BCR] = { 0x0b00 },
+ [GCC_BLSP2_UART4_BCR] = { 0x0b40 },
+ [GCC_BLSP2_QUP5_BCR] = { 0x0b80 },
+ [GCC_BLSP2_UART5_BCR] = { 0x0bc0 },
+ [GCC_BLSP2_QUP6_BCR] = { 0x0c00 },
+ [GCC_BLSP2_UART6_BCR] = { 0x0c40 },
+ [GCC_PDM_BCR] = { 0x0cc0 },
+ [GCC_PRNG_BCR] = { 0x0d00 },
+ [GCC_BAM_DMA_BCR] = { 0x0d40 },
+ [GCC_TSIF_BCR] = { 0x0d80 },
+ [GCC_TCSR_BCR] = { 0x0dc0 },
+ [GCC_BOOT_ROM_BCR] = { 0x0e00 },
+ [GCC_MSG_RAM_BCR] = { 0x0e40 },
+ [GCC_TLMM_BCR] = { 0x0e80 },
+ [GCC_MPM_BCR] = { 0x0ec0 },
+ [GCC_MPM_AHB_RESET] = { 0x0ec4, 1 },
+ [GCC_MPM_NON_AHB_RESET] = { 0x0ec4, 2 },
+ [GCC_SEC_CTRL_BCR] = { 0x0f40 },
+ [GCC_SPMI_BCR] = { 0x0fc0 },
+ [GCC_SPDM_BCR] = { 0x1000 },
+ [GCC_CE1_BCR] = { 0x1040 },
+ [GCC_CE2_BCR] = { 0x1080 },
+ [GCC_BIMC_BCR] = { 0x1100 },
+ [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x1240 },
+ [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x1248 },
+ [GCC_PNOC_BUS_TIMEOUT0_BCR] = { 0x1280 },
+ [GCC_PNOC_BUS_TIMEOUT1_BCR] = { 0x1288 },
+ [GCC_PNOC_BUS_TIMEOUT2_BCR] = { 0x1290 },
+ [GCC_PNOC_BUS_TIMEOUT3_BCR] = { 0x1298 },
+ [GCC_PNOC_BUS_TIMEOUT4_BCR] = { 0x12a0 },
+ [GCC_CNOC_BUS_TIMEOUT0_BCR] = { 0x12c0 },
+ [GCC_CNOC_BUS_TIMEOUT1_BCR] = { 0x12c8 },
+ [GCC_CNOC_BUS_TIMEOUT2_BCR] = { 0x12d0 },
+ [GCC_CNOC_BUS_TIMEOUT3_BCR] = { 0x12d8 },
+ [GCC_CNOC_BUS_TIMEOUT4_BCR] = { 0x12e0 },
+ [GCC_CNOC_BUS_TIMEOUT5_BCR] = { 0x12e8 },
+ [GCC_CNOC_BUS_TIMEOUT6_BCR] = { 0x12f0 },
+ [GCC_DEHR_BCR] = { 0x1300 },
+ [GCC_RBCPR_BCR] = { 0x1380 },
+ [GCC_MSS_RESTART] = { 0x1680 },
+ [GCC_LPASS_RESTART] = { 0x16c0 },
+ [GCC_WCSS_RESTART] = { 0x1700 },
+ [GCC_VENUS_RESTART] = { 0x1740 },
+ [GCC_COPSS_SMMU_BCR] = { 0x1a40 },
+ [GCC_SPSS_BCR] = { 0x1a80 },
+ [GCC_PCIE_0_BCR] = { 0x1ac0 },
+ [GCC_PCIE_0_PHY_BCR] = { 0x1b00 },
+ [GCC_PCIE_1_BCR] = { 0x1b40 },
+ [GCC_PCIE_1_PHY_BCR] = { 0x1b80 },
+ [GCC_USB_30_SEC_BCR] = { 0x1bc0 },
+ [GCC_USB3_SEC_PHY_BCR] = { 0x1bfc },
+ [GCC_SATA_BCR] = { 0x1c40 },
+ [GCC_CE3_BCR] = { 0x1d00 },
+ [GCC_UFS_BCR] = { 0x1d40 },
+ [GCC_USB30_PHY_COM_BCR] = { 0x1e80 },
+};
+
+static const struct regmap_config gcc_apq8084_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x1fc0,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_apq8084_desc = {
+ .config = &gcc_apq8084_regmap_config,
+ .clks = gcc_apq8084_clocks,
+ .num_clks = ARRAY_SIZE(gcc_apq8084_clocks),
+ .resets = gcc_apq8084_resets,
+ .num_resets = ARRAY_SIZE(gcc_apq8084_resets),
+};
+
+static const struct of_device_id gcc_apq8084_match_table[] = {
+ { .compatible = "qcom,gcc-apq8084" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gcc_apq8084_match_table);
+
+static int gcc_apq8084_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ struct device *dev = &pdev->dev;
+
+ /* Temporary until RPM clocks supported */
+ clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clk = clk_register_fixed_rate(dev, "sleep_clk_src", NULL,
+ CLK_IS_ROOT, 32768);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return qcom_cc_probe(pdev, &gcc_apq8084_desc);
+}
+
+static int gcc_apq8084_remove(struct platform_device *pdev)
+{
+ qcom_cc_remove(pdev);
+ return 0;
+}
+
+static struct platform_driver gcc_apq8084_driver = {
+ .probe = gcc_apq8084_probe,
+ .remove = gcc_apq8084_remove,
+ .driver = {
+ .name = "gcc-apq8084",
+ .owner = THIS_MODULE,
+ .of_match_table = gcc_apq8084_match_table,
+ },
+};
+
+static int __init gcc_apq8084_init(void)
+{
+ return platform_driver_register(&gcc_apq8084_driver);
+}
+core_initcall(gcc_apq8084_init);
+
+static void __exit gcc_apq8084_exit(void)
+{
+ platform_driver_unregister(&gcc_apq8084_driver);
+}
+module_exit(gcc_apq8084_exit);
+
+MODULE_DESCRIPTION("QCOM GCC APQ8084 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-apq8084");
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
new file mode 100644
index 000000000000..4032e510d9aa
--- /dev/null
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -0,0 +1,2424 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+
+static struct clk_pll pll3 = {
+ .l_reg = 0x3164,
+ .m_reg = 0x3168,
+ .n_reg = 0x316c,
+ .config_reg = 0x3174,
+ .mode_reg = 0x3160,
+ .status_reg = 0x3178,
+ .status_bit = 16,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pll3",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_pll pll8 = {
+ .l_reg = 0x3144,
+ .m_reg = 0x3148,
+ .n_reg = 0x314c,
+ .config_reg = 0x3154,
+ .mode_reg = 0x3140,
+ .status_reg = 0x3158,
+ .status_bit = 16,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pll8",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap pll8_vote = {
+ .enable_reg = 0x34c0,
+ .enable_mask = BIT(8),
+ .hw.init = &(struct clk_init_data){
+ .name = "pll8_vote",
+ .parent_names = (const char *[]){ "pll8" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll pll14 = {
+ .l_reg = 0x31c4,
+ .m_reg = 0x31c8,
+ .n_reg = 0x31cc,
+ .config_reg = 0x31d4,
+ .mode_reg = 0x31c0,
+ .status_reg = 0x31d8,
+ .status_bit = 16,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pll14",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap pll14_vote = {
+ .enable_reg = 0x34c0,
+ .enable_mask = BIT(14),
+ .hw.init = &(struct clk_init_data){
+ .name = "pll14_vote",
+ .parent_names = (const char *[]){ "pll14" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+#define P_PXO 0
+#define P_PLL8 1
+#define P_PLL3 1
+#define P_PLL0 2
+#define P_CXO 2
+
+static const u8 gcc_pxo_pll8_map[] = {
+ [P_PXO] = 0,
+ [P_PLL8] = 3,
+};
+
+static const char *gcc_pxo_pll8[] = {
+ "pxo",
+ "pll8_vote",
+};
+
+static const u8 gcc_pxo_pll8_cxo_map[] = {
+ [P_PXO] = 0,
+ [P_PLL8] = 3,
+ [P_CXO] = 5,
+};
+
+static const char *gcc_pxo_pll8_cxo[] = {
+ "pxo",
+ "pll8_vote",
+ "cxo",
+};
+
+static const u8 gcc_pxo_pll3_map[] = {
+ [P_PXO] = 0,
+ [P_PLL3] = 1,
+};
+
+static const u8 gcc_pxo_pll3_sata_map[] = {
+ [P_PXO] = 0,
+ [P_PLL3] = 6,
+};
+
+static const char *gcc_pxo_pll3[] = {
+ "pxo",
+ "pll3",
+};
+
+static const u8 gcc_pxo_pll8_pll0[] = {
+ [P_PXO] = 0,
+ [P_PLL8] = 3,
+ [P_PLL0] = 2,
+};
+
+static const char *gcc_pxo_pll8_pll0_map[] = {
+ "pxo",
+ "pll8_vote",
+ "pll0",
+};
+
+static struct freq_tbl clk_tbl_gsbi_uart[] = {
+ { 1843200, P_PLL8, 2, 6, 625 },
+ { 3686400, P_PLL8, 2, 12, 625 },
+ { 7372800, P_PLL8, 2, 24, 625 },
+ { 14745600, P_PLL8, 2, 48, 625 },
+ { 16000000, P_PLL8, 4, 1, 6 },
+ { 24000000, P_PLL8, 4, 1, 4 },
+ { 32000000, P_PLL8, 4, 1, 3 },
+ { 40000000, P_PLL8, 1, 5, 48 },
+ { 46400000, P_PLL8, 1, 29, 240 },
+ { 48000000, P_PLL8, 4, 1, 2 },
+ { 51200000, P_PLL8, 1, 2, 15 },
+ { 56000000, P_PLL8, 1, 7, 48 },
+ { 58982400, P_PLL8, 1, 96, 625 },
+ { 64000000, P_PLL8, 2, 1, 3 },
+ { }
+};
+
+static struct clk_rcg gsbi1_uart_src = {
+ .ns_reg = 0x29d4,
+ .md_reg = 0x29d0,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x29d4,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi1_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi1_uart_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x29d4,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi1_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi1_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi2_uart_src = {
+ .ns_reg = 0x29f4,
+ .md_reg = 0x29f0,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x29f4,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi2_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi2_uart_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 8,
+ .clkr = {
+ .enable_reg = 0x29f4,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi2_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi2_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi4_uart_src = {
+ .ns_reg = 0x2a34,
+ .md_reg = 0x2a30,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x2a34,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi4_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi4_uart_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 26,
+ .clkr = {
+ .enable_reg = 0x2a34,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi4_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi4_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi5_uart_src = {
+ .ns_reg = 0x2a54,
+ .md_reg = 0x2a50,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x2a54,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi5_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi5_uart_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 22,
+ .clkr = {
+ .enable_reg = 0x2a54,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi5_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi5_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi6_uart_src = {
+ .ns_reg = 0x2a74,
+ .md_reg = 0x2a70,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x2a74,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi6_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi6_uart_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 18,
+ .clkr = {
+ .enable_reg = 0x2a74,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi6_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi6_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi7_uart_src = {
+ .ns_reg = 0x2a94,
+ .md_reg = 0x2a90,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_uart,
+ .clkr = {
+ .enable_reg = 0x2a94,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi7_uart_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi7_uart_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 14,
+ .clkr = {
+ .enable_reg = 0x2a94,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi7_uart_clk",
+ .parent_names = (const char *[]){
+ "gsbi7_uart_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct freq_tbl clk_tbl_gsbi_qup[] = {
+ { 1100000, P_PXO, 1, 2, 49 },
+ { 5400000, P_PXO, 1, 1, 5 },
+ { 10800000, P_PXO, 1, 2, 5 },
+ { 15060000, P_PLL8, 1, 2, 51 },
+ { 24000000, P_PLL8, 4, 1, 4 },
+ { 25600000, P_PLL8, 1, 1, 15 },
+ { 27000000, P_PXO, 1, 0, 0 },
+ { 48000000, P_PLL8, 4, 1, 2 },
+ { 51200000, P_PLL8, 1, 2, 15 },
+ { }
+};
+
+static struct clk_rcg gsbi1_qup_src = {
+ .ns_reg = 0x29cc,
+ .md_reg = 0x29c8,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x29cc,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi1_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi1_qup_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 11,
+ .clkr = {
+ .enable_reg = 0x29cc,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi1_qup_clk",
+ .parent_names = (const char *[]){ "gsbi1_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi2_qup_src = {
+ .ns_reg = 0x29ec,
+ .md_reg = 0x29e8,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x29ec,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi2_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi2_qup_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 6,
+ .clkr = {
+ .enable_reg = 0x29ec,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi2_qup_clk",
+ .parent_names = (const char *[]){ "gsbi2_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi4_qup_src = {
+ .ns_reg = 0x2a2c,
+ .md_reg = 0x2a28,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x2a2c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi4_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi4_qup_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 24,
+ .clkr = {
+ .enable_reg = 0x2a2c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi4_qup_clk",
+ .parent_names = (const char *[]){ "gsbi4_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi5_qup_src = {
+ .ns_reg = 0x2a4c,
+ .md_reg = 0x2a48,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x2a4c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi5_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi5_qup_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 20,
+ .clkr = {
+ .enable_reg = 0x2a4c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi5_qup_clk",
+ .parent_names = (const char *[]){ "gsbi5_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi6_qup_src = {
+ .ns_reg = 0x2a6c,
+ .md_reg = 0x2a68,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x2a6c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi6_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi6_qup_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 16,
+ .clkr = {
+ .enable_reg = 0x2a6c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi6_qup_clk",
+ .parent_names = (const char *[]){ "gsbi6_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gsbi7_qup_src = {
+ .ns_reg = 0x2a8c,
+ .md_reg = 0x2a88,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_gsbi_qup,
+ .clkr = {
+ .enable_reg = 0x2a8c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi7_qup_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ },
+};
+
+static struct clk_branch gsbi7_qup_clk = {
+ .halt_reg = 0x2fd0,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x2a8c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi7_qup_clk",
+ .parent_names = (const char *[]){ "gsbi7_qup_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch gsbi1_h_clk = {
+ .hwcg_reg = 0x29c0,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fcc,
+ .halt_bit = 13,
+ .clkr = {
+ .enable_reg = 0x29c0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch gsbi2_h_clk = {
+ .hwcg_reg = 0x29e0,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fcc,
+ .halt_bit = 9,
+ .clkr = {
+ .enable_reg = 0x29e0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi2_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch gsbi4_h_clk = {
+ .hwcg_reg = 0x2a20,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd0,
+ .halt_bit = 27,
+ .clkr = {
+ .enable_reg = 0x2a20,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi4_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch gsbi5_h_clk = {
+ .hwcg_reg = 0x2a40,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd0,
+ .halt_bit = 23,
+ .clkr = {
+ .enable_reg = 0x2a40,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi5_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch gsbi6_h_clk = {
+ .hwcg_reg = 0x2a60,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd0,
+ .halt_bit = 19,
+ .clkr = {
+ .enable_reg = 0x2a60,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi6_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch gsbi7_h_clk = {
+ .hwcg_reg = 0x2a80,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd0,
+ .halt_bit = 15,
+ .clkr = {
+ .enable_reg = 0x2a80,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "gsbi7_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_gp[] = {
+ { 12500000, P_PXO, 2, 0, 0 },
+ { 25000000, P_PXO, 1, 0, 0 },
+ { 64000000, P_PLL8, 2, 1, 3 },
+ { 76800000, P_PLL8, 1, 1, 5 },
+ { 96000000, P_PLL8, 4, 0, 0 },
+ { 128000000, P_PLL8, 3, 0, 0 },
+ { 192000000, P_PLL8, 2, 0, 0 },
+ { }
+};
+
+static struct clk_rcg gp0_src = {
+ .ns_reg = 0x2d24,
+ .md_reg = 0x2d00,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_cxo_map,
+ },
+ .freq_tbl = clk_tbl_gp,
+ .clkr = {
+ .enable_reg = 0x2d24,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp0_src",
+ .parent_names = gcc_pxo_pll8_cxo,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_PARENT_GATE,
+ },
+ }
+};
+
+static struct clk_branch gp0_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_bit = 7,
+ .clkr = {
+ .enable_reg = 0x2d24,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp0_clk",
+ .parent_names = (const char *[]){ "gp0_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gp1_src = {
+ .ns_reg = 0x2d44,
+ .md_reg = 0x2d40,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_cxo_map,
+ },
+ .freq_tbl = clk_tbl_gp,
+ .clkr = {
+ .enable_reg = 0x2d44,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp1_src",
+ .parent_names = gcc_pxo_pll8_cxo,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch gp1_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_bit = 6,
+ .clkr = {
+ .enable_reg = 0x2d44,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp1_clk",
+ .parent_names = (const char *[]){ "gp1_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg gp2_src = {
+ .ns_reg = 0x2d64,
+ .md_reg = 0x2d60,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_cxo_map,
+ },
+ .freq_tbl = clk_tbl_gp,
+ .clkr = {
+ .enable_reg = 0x2d64,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp2_src",
+ .parent_names = gcc_pxo_pll8_cxo,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch gp2_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_bit = 5,
+ .clkr = {
+ .enable_reg = 0x2d64,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "gp2_clk",
+ .parent_names = (const char *[]){ "gp2_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch pmem_clk = {
+ .hwcg_reg = 0x25a0,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fc8,
+ .halt_bit = 20,
+ .clkr = {
+ .enable_reg = 0x25a0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pmem_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_rcg prng_src = {
+ .ns_reg = 0x2e80,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .clkr = {
+ .hw.init = &(struct clk_init_data){
+ .name = "prng_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ },
+ },
+};
+
+static struct clk_branch prng_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 10,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(10),
+ .hw.init = &(struct clk_init_data){
+ .name = "prng_clk",
+ .parent_names = (const char *[]){ "prng_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_sdc[] = {
+ { 144000, P_PXO, 5, 18,625 },
+ { 400000, P_PLL8, 4, 1, 240 },
+ { 16000000, P_PLL8, 4, 1, 6 },
+ { 17070000, P_PLL8, 1, 2, 45 },
+ { 20210000, P_PLL8, 1, 1, 19 },
+ { 24000000, P_PLL8, 4, 1, 4 },
+ { 48000000, P_PLL8, 4, 1, 2 },
+ { 64000000, P_PLL8, 3, 1, 2 },
+ { 96000000, P_PLL8, 4, 0, 0 },
+ { 192000000, P_PLL8, 2, 0, 0 },
+ { }
+};
+
+static struct clk_rcg sdc1_src = {
+ .ns_reg = 0x282c,
+ .md_reg = 0x2828,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_sdc,
+ .clkr = {
+ .enable_reg = 0x282c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc1_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch sdc1_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 6,
+ .clkr = {
+ .enable_reg = 0x282c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc1_clk",
+ .parent_names = (const char *[]){ "sdc1_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg sdc3_src = {
+ .ns_reg = 0x286c,
+ .md_reg = 0x2868,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_sdc,
+ .clkr = {
+ .enable_reg = 0x286c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc3_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch sdc3_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 4,
+ .clkr = {
+ .enable_reg = 0x286c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc3_clk",
+ .parent_names = (const char *[]){ "sdc3_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch sdc1_h_clk = {
+ .hwcg_reg = 0x2820,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fc8,
+ .halt_bit = 11,
+ .clkr = {
+ .enable_reg = 0x2820,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sdc3_h_clk = {
+ .hwcg_reg = 0x2860,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fc8,
+ .halt_bit = 9,
+ .clkr = {
+ .enable_reg = 0x2860,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sdc3_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_tsif_ref[] = {
+ { 105000, P_PXO, 1, 1, 256 },
+ { }
+};
+
+static struct clk_rcg tsif_ref_src = {
+ .ns_reg = 0x2710,
+ .md_reg = 0x270c,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 16,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_tsif_ref,
+ .clkr = {
+ .enable_reg = 0x2710,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "tsif_ref_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch tsif_ref_clk = {
+ .halt_reg = 0x2fd4,
+ .halt_bit = 5,
+ .clkr = {
+ .enable_reg = 0x2710,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "tsif_ref_clk",
+ .parent_names = (const char *[]){ "tsif_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch tsif_h_clk = {
+ .hwcg_reg = 0x2700,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd4,
+ .halt_bit = 7,
+ .clkr = {
+ .enable_reg = 0x2700,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "tsif_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch dma_bam_h_clk = {
+ .hwcg_reg = 0x25c0,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fc8,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x25c0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "dma_bam_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch adm0_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "adm0_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch adm0_pbus_clk = {
+ .hwcg_reg = 0x2208,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fdc,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 11,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(3),
+ .hw.init = &(struct clk_init_data){
+ .name = "adm0_pbus_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pmic_arb0_h_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 22,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(8),
+ .hw.init = &(struct clk_init_data){
+ .name = "pmic_arb0_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pmic_arb1_h_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 21,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "pmic_arb1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pmic_ssbi2_clk = {
+ .halt_reg = 0x2fd8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 23,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "pmic_ssbi2_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch rpm_msg_ram_h_clk = {
+ .hwcg_reg = 0x27e0,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fd8,
+ .halt_check = BRANCH_HALT_VOTED,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x3080,
+ .enable_mask = BIT(6),
+ .hw.init = &(struct clk_init_data){
+ .name = "rpm_msg_ram_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_pcie_ref[] = {
+ { 100000000, P_PLL3, 12, 0, 0 },
+ { }
+};
+
+static struct clk_rcg pcie_ref_src = {
+ .ns_reg = 0x3860,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_map,
+ },
+ .freq_tbl = clk_tbl_pcie_ref,
+ .clkr = {
+ .enable_reg = 0x3860,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_ref_src",
+ .parent_names = gcc_pxo_pll3,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch pcie_ref_src_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 30,
+ .clkr = {
+ .enable_reg = 0x3860,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_ref_src_clk",
+ .parent_names = (const char *[]){ "pcie_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch pcie_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 13,
+ .clkr = {
+ .enable_reg = 0x22c0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_aux_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x22c8,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_aux_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_h_clk = {
+ .halt_reg = 0x2fd4,
+ .halt_bit = 8,
+ .clkr = {
+ .enable_reg = 0x22cc,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_phy_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 29,
+ .clkr = {
+ .enable_reg = 0x22d0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_phy_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_rcg pcie1_ref_src = {
+ .ns_reg = 0x3aa0,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_map,
+ },
+ .freq_tbl = clk_tbl_pcie_ref,
+ .clkr = {
+ .enable_reg = 0x3aa0,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_ref_src",
+ .parent_names = gcc_pxo_pll3,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch pcie1_ref_src_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 27,
+ .clkr = {
+ .enable_reg = 0x3aa0,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_ref_src_clk",
+ .parent_names = (const char *[]){ "pcie1_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch pcie1_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 10,
+ .clkr = {
+ .enable_reg = 0x3a80,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie1_aux_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 28,
+ .clkr = {
+ .enable_reg = 0x3a88,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_aux_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie1_h_clk = {
+ .halt_reg = 0x2fd4,
+ .halt_bit = 9,
+ .clkr = {
+ .enable_reg = 0x3a8c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie1_phy_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 26,
+ .clkr = {
+ .enable_reg = 0x3a90,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie1_phy_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_rcg pcie2_ref_src = {
+ .ns_reg = 0x3ae0,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_map,
+ },
+ .freq_tbl = clk_tbl_pcie_ref,
+ .clkr = {
+ .enable_reg = 0x3ae0,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_ref_src",
+ .parent_names = gcc_pxo_pll3,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch pcie2_ref_src_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 24,
+ .clkr = {
+ .enable_reg = 0x3ae0,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_ref_src_clk",
+ .parent_names = (const char *[]){ "pcie2_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch pcie2_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 9,
+ .clkr = {
+ .enable_reg = 0x3ac0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie2_aux_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 25,
+ .clkr = {
+ .enable_reg = 0x3ac8,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_aux_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie2_h_clk = {
+ .halt_reg = 0x2fd4,
+ .halt_bit = 10,
+ .clkr = {
+ .enable_reg = 0x3acc,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie2_phy_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 23,
+ .clkr = {
+ .enable_reg = 0x3ad0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie2_phy_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_sata_ref[] = {
+ { 100000000, P_PLL3, 12, 0, 0 },
+ { }
+};
+
+static struct clk_rcg sata_ref_src = {
+ .ns_reg = 0x2c08,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll3_sata_map,
+ },
+ .freq_tbl = clk_tbl_sata_ref,
+ .clkr = {
+ .enable_reg = 0x2c08,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_ref_src",
+ .parent_names = gcc_pxo_pll3,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch sata_rxoob_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 20,
+ .clkr = {
+ .enable_reg = 0x2c0c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_rxoob_clk",
+ .parent_names = (const char *[]){ "sata_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch sata_pmalive_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 19,
+ .clkr = {
+ .enable_reg = 0x2c10,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_pmalive_clk",
+ .parent_names = (const char *[]){ "sata_ref_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch sata_phy_ref_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 18,
+ .clkr = {
+ .enable_reg = 0x2c14,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_phy_ref_clk",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ },
+ },
+};
+
+static struct clk_branch sata_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x2c20,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sata_h_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 21,
+ .clkr = {
+ .enable_reg = 0x2c00,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sfab_sata_s_h_clk = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 14,
+ .clkr = {
+ .enable_reg = 0x2480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sfab_sata_s_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sata_phy_cfg_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 14,
+ .clkr = {
+ .enable_reg = 0x2c40,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_phy_cfg_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_usb30_master[] = {
+ { 125000000, P_PLL0, 1, 5, 32 },
+ { }
+};
+
+static struct clk_rcg usb30_master_clk_src = {
+ .ns_reg = 0x3b2c,
+ .md_reg = 0x3b28,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0,
+ },
+ .freq_tbl = clk_tbl_usb30_master,
+ .clkr = {
+ .enable_reg = 0x3b2c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_master_ref_src",
+ .parent_names = gcc_pxo_pll8_pll0_map,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch usb30_0_branch_clk = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 22,
+ .clkr = {
+ .enable_reg = 0x3b24,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_0_branch_clk",
+ .parent_names = (const char *[]){ "usb30_master_ref_src", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch usb30_1_branch_clk = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 17,
+ .clkr = {
+ .enable_reg = 0x3b34,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_1_branch_clk",
+ .parent_names = (const char *[]){ "usb30_master_ref_src", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_usb30_utmi[] = {
+ { 60000000, P_PLL8, 1, 5, 32 },
+ { }
+};
+
+static struct clk_rcg usb30_utmi_clk = {
+ .ns_reg = 0x3b44,
+ .md_reg = 0x3b40,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0,
+ },
+ .freq_tbl = clk_tbl_usb30_utmi,
+ .clkr = {
+ .enable_reg = 0x3b44,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_utmi_clk",
+ .parent_names = gcc_pxo_pll8_pll0_map,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch usb30_0_utmi_clk_ctl = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 21,
+ .clkr = {
+ .enable_reg = 0x3b48,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_0_utmi_clk_ctl",
+ .parent_names = (const char *[]){ "usb30_utmi_clk", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch usb30_1_utmi_clk_ctl = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 15,
+ .clkr = {
+ .enable_reg = 0x3b4c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb30_1_utmi_clk_ctl",
+ .parent_names = (const char *[]){ "usb30_utmi_clk", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_usb[] = {
+ { 60000000, P_PLL8, 1, 5, 32 },
+ { }
+};
+
+static struct clk_rcg usb_hs1_xcvr_clk_src = {
+ .ns_reg = 0x290C,
+ .md_reg = 0x2908,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0,
+ },
+ .freq_tbl = clk_tbl_usb,
+ .clkr = {
+ .enable_reg = 0x2968,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs1_xcvr_src",
+ .parent_names = gcc_pxo_pll8_pll0_map,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch usb_hs1_xcvr_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 17,
+ .clkr = {
+ .enable_reg = 0x290c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs1_xcvr_clk",
+ .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch usb_hs1_h_clk = {
+ .hwcg_reg = 0x2900,
+ .hwcg_bit = 6,
+ .halt_reg = 0x2fc8,
+ .halt_bit = 1,
+ .clkr = {
+ .enable_reg = 0x2900,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_rcg usb_fs1_xcvr_clk_src = {
+ .ns_reg = 0x2968,
+ .md_reg = 0x2964,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll0,
+ },
+ .freq_tbl = clk_tbl_usb,
+ .clkr = {
+ .enable_reg = 0x2968,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_fs1_xcvr_src",
+ .parent_names = gcc_pxo_pll8_pll0_map,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch usb_fs1_xcvr_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 17,
+ .clkr = {
+ .enable_reg = 0x2968,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_fs1_xcvr_clk",
+ .parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch usb_fs1_sys_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 18,
+ .clkr = {
+ .enable_reg = 0x296c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_fs1_sys_clk",
+ .parent_names = (const char *[]){ "usb_fs1_xcvr_src", },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch usb_fs1_h_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 19,
+ .clkr = {
+ .enable_reg = 0x2960,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_fs1_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_regmap *gcc_ipq806x_clks[] = {
+ [PLL3] = &pll3.clkr,
+ [PLL8] = &pll8.clkr,
+ [PLL8_VOTE] = &pll8_vote,
+ [PLL14] = &pll14.clkr,
+ [PLL14_VOTE] = &pll14_vote,
+ [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
+ [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
+ [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
+ [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
+ [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
+ [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
+ [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
+ [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
+ [GSBI6_UART_SRC] = &gsbi6_uart_src.clkr,
+ [GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr,
+ [GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
+ [GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
+ [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
+ [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
+ [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
+ [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
+ [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
+ [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
+ [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
+ [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
+ [GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr,
+ [GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr,
+ [GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
+ [GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
+ [GP0_SRC] = &gp0_src.clkr,
+ [GP0_CLK] = &gp0_clk.clkr,
+ [GP1_SRC] = &gp1_src.clkr,
+ [GP1_CLK] = &gp1_clk.clkr,
+ [GP2_SRC] = &gp2_src.clkr,
+ [GP2_CLK] = &gp2_clk.clkr,
+ [PMEM_A_CLK] = &pmem_clk.clkr,
+ [PRNG_SRC] = &prng_src.clkr,
+ [PRNG_CLK] = &prng_clk.clkr,
+ [SDC1_SRC] = &sdc1_src.clkr,
+ [SDC1_CLK] = &sdc1_clk.clkr,
+ [SDC3_SRC] = &sdc3_src.clkr,
+ [SDC3_CLK] = &sdc3_clk.clkr,
+ [TSIF_REF_SRC] = &tsif_ref_src.clkr,
+ [TSIF_REF_CLK] = &tsif_ref_clk.clkr,
+ [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
+ [GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
+ [GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
+ [GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
+ [GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
+ [GSBI6_H_CLK] = &gsbi6_h_clk.clkr,
+ [GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
+ [TSIF_H_CLK] = &tsif_h_clk.clkr,
+ [SDC1_H_CLK] = &sdc1_h_clk.clkr,
+ [SDC3_H_CLK] = &sdc3_h_clk.clkr,
+ [ADM0_CLK] = &adm0_clk.clkr,
+ [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
+ [PCIE_A_CLK] = &pcie_a_clk.clkr,
+ [PCIE_AUX_CLK] = &pcie_aux_clk.clkr,
+ [PCIE_H_CLK] = &pcie_h_clk.clkr,
+ [PCIE_PHY_CLK] = &pcie_phy_clk.clkr,
+ [SFAB_SATA_S_H_CLK] = &sfab_sata_s_h_clk.clkr,
+ [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
+ [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
+ [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
+ [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
+ [SATA_H_CLK] = &sata_h_clk.clkr,
+ [SATA_CLK_SRC] = &sata_ref_src.clkr,
+ [SATA_RXOOB_CLK] = &sata_rxoob_clk.clkr,
+ [SATA_PMALIVE_CLK] = &sata_pmalive_clk.clkr,
+ [SATA_PHY_REF_CLK] = &sata_phy_ref_clk.clkr,
+ [SATA_A_CLK] = &sata_a_clk.clkr,
+ [SATA_PHY_CFG_CLK] = &sata_phy_cfg_clk.clkr,
+ [PCIE_ALT_REF_SRC] = &pcie_ref_src.clkr,
+ [PCIE_ALT_REF_CLK] = &pcie_ref_src_clk.clkr,
+ [PCIE_1_A_CLK] = &pcie1_a_clk.clkr,
+ [PCIE_1_AUX_CLK] = &pcie1_aux_clk.clkr,
+ [PCIE_1_H_CLK] = &pcie1_h_clk.clkr,
+ [PCIE_1_PHY_CLK] = &pcie1_phy_clk.clkr,
+ [PCIE_1_ALT_REF_SRC] = &pcie1_ref_src.clkr,
+ [PCIE_1_ALT_REF_CLK] = &pcie1_ref_src_clk.clkr,
+ [PCIE_2_A_CLK] = &pcie2_a_clk.clkr,
+ [PCIE_2_AUX_CLK] = &pcie2_aux_clk.clkr,
+ [PCIE_2_H_CLK] = &pcie2_h_clk.clkr,
+ [PCIE_2_PHY_CLK] = &pcie2_phy_clk.clkr,
+ [PCIE_2_ALT_REF_SRC] = &pcie2_ref_src.clkr,
+ [PCIE_2_ALT_REF_CLK] = &pcie2_ref_src_clk.clkr,
+ [USB30_MASTER_SRC] = &usb30_master_clk_src.clkr,
+ [USB30_0_MASTER_CLK] = &usb30_0_branch_clk.clkr,
+ [USB30_1_MASTER_CLK] = &usb30_1_branch_clk.clkr,
+ [USB30_UTMI_SRC] = &usb30_utmi_clk.clkr,
+ [USB30_0_UTMI_CLK] = &usb30_0_utmi_clk_ctl.clkr,
+ [USB30_1_UTMI_CLK] = &usb30_1_utmi_clk_ctl.clkr,
+ [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
+ [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_clk_src.clkr,
+ [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
+ [USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr,
+ [USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
+ [USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
+ [USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_ipq806x_resets[] = {
+ [QDSS_STM_RESET] = { 0x2060, 6 },
+ [AFAB_SMPSS_S_RESET] = { 0x20b8, 2 },
+ [AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 },
+ [AFAB_SMPSS_M0_RESET] = { 0x20b8, 0 },
+ [AFAB_EBI1_CH0_RESET] = { 0x20c0, 7 },
+ [AFAB_EBI1_CH1_RESET] = { 0x20c4, 7 },
+ [SFAB_ADM0_M0_RESET] = { 0x21e0, 7 },
+ [SFAB_ADM0_M1_RESET] = { 0x21e4, 7 },
+ [SFAB_ADM0_M2_RESET] = { 0x21e8, 7 },
+ [ADM0_C2_RESET] = { 0x220c, 4 },
+ [ADM0_C1_RESET] = { 0x220c, 3 },
+ [ADM0_C0_RESET] = { 0x220c, 2 },
+ [ADM0_PBUS_RESET] = { 0x220c, 1 },
+ [ADM0_RESET] = { 0x220c, 0 },
+ [QDSS_CLKS_SW_RESET] = { 0x2260, 5 },
+ [QDSS_POR_RESET] = { 0x2260, 4 },
+ [QDSS_TSCTR_RESET] = { 0x2260, 3 },
+ [QDSS_HRESET_RESET] = { 0x2260, 2 },
+ [QDSS_AXI_RESET] = { 0x2260, 1 },
+ [QDSS_DBG_RESET] = { 0x2260, 0 },
+ [SFAB_PCIE_M_RESET] = { 0x22d8, 1 },
+ [SFAB_PCIE_S_RESET] = { 0x22d8, 0 },
+ [PCIE_EXT_RESET] = { 0x22dc, 6 },
+ [PCIE_PHY_RESET] = { 0x22dc, 5 },
+ [PCIE_PCI_RESET] = { 0x22dc, 4 },
+ [PCIE_POR_RESET] = { 0x22dc, 3 },
+ [PCIE_HCLK_RESET] = { 0x22dc, 2 },
+ [PCIE_ACLK_RESET] = { 0x22dc, 0 },
+ [SFAB_LPASS_RESET] = { 0x23a0, 7 },
+ [SFAB_AFAB_M_RESET] = { 0x23e0, 7 },
+ [AFAB_SFAB_M0_RESET] = { 0x2420, 7 },
+ [AFAB_SFAB_M1_RESET] = { 0x2424, 7 },
+ [SFAB_SATA_S_RESET] = { 0x2480, 7 },
+ [SFAB_DFAB_M_RESET] = { 0x2500, 7 },
+ [DFAB_SFAB_M_RESET] = { 0x2520, 7 },
+ [DFAB_SWAY0_RESET] = { 0x2540, 7 },
+ [DFAB_SWAY1_RESET] = { 0x2544, 7 },
+ [DFAB_ARB0_RESET] = { 0x2560, 7 },
+ [DFAB_ARB1_RESET] = { 0x2564, 7 },
+ [PPSS_PROC_RESET] = { 0x2594, 1 },
+ [PPSS_RESET] = { 0x2594, 0 },
+ [DMA_BAM_RESET] = { 0x25c0, 7 },
+ [SPS_TIC_H_RESET] = { 0x2600, 7 },
+ [SFAB_CFPB_M_RESET] = { 0x2680, 7 },
+ [SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
+ [TSIF_H_RESET] = { 0x2700, 7 },
+ [CE1_H_RESET] = { 0x2720, 7 },
+ [CE1_CORE_RESET] = { 0x2724, 7 },
+ [CE1_SLEEP_RESET] = { 0x2728, 7 },
+ [CE2_H_RESET] = { 0x2740, 7 },
+ [CE2_CORE_RESET] = { 0x2744, 7 },
+ [SFAB_SFPB_M_RESET] = { 0x2780, 7 },
+ [SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
+ [RPM_PROC_RESET] = { 0x27c0, 7 },
+ [PMIC_SSBI2_RESET] = { 0x280c, 12 },
+ [SDC1_RESET] = { 0x2830, 0 },
+ [SDC2_RESET] = { 0x2850, 0 },
+ [SDC3_RESET] = { 0x2870, 0 },
+ [SDC4_RESET] = { 0x2890, 0 },
+ [USB_HS1_RESET] = { 0x2910, 0 },
+ [USB_HSIC_RESET] = { 0x2934, 0 },
+ [USB_FS1_XCVR_RESET] = { 0x2974, 1 },
+ [USB_FS1_RESET] = { 0x2974, 0 },
+ [GSBI1_RESET] = { 0x29dc, 0 },
+ [GSBI2_RESET] = { 0x29fc, 0 },
+ [GSBI3_RESET] = { 0x2a1c, 0 },
+ [GSBI4_RESET] = { 0x2a3c, 0 },
+ [GSBI5_RESET] = { 0x2a5c, 0 },
+ [GSBI6_RESET] = { 0x2a7c, 0 },
+ [GSBI7_RESET] = { 0x2a9c, 0 },
+ [SPDM_RESET] = { 0x2b6c, 0 },
+ [SEC_CTRL_RESET] = { 0x2b80, 7 },
+ [TLMM_H_RESET] = { 0x2ba0, 7 },
+ [SFAB_SATA_M_RESET] = { 0x2c18, 0 },
+ [SATA_RESET] = { 0x2c1c, 0 },
+ [TSSC_RESET] = { 0x2ca0, 7 },
+ [PDM_RESET] = { 0x2cc0, 12 },
+ [MPM_H_RESET] = { 0x2da0, 7 },
+ [MPM_RESET] = { 0x2da4, 0 },
+ [SFAB_SMPSS_S_RESET] = { 0x2e00, 7 },
+ [PRNG_RESET] = { 0x2e80, 12 },
+ [SFAB_CE3_M_RESET] = { 0x36c8, 1 },
+ [SFAB_CE3_S_RESET] = { 0x36c8, 0 },
+ [CE3_SLEEP_RESET] = { 0x36d0, 7 },
+ [PCIE_1_M_RESET] = { 0x3a98, 1 },
+ [PCIE_1_S_RESET] = { 0x3a98, 0 },
+ [PCIE_1_EXT_RESET] = { 0x3a9c, 6 },
+ [PCIE_1_PHY_RESET] = { 0x3a9c, 5 },
+ [PCIE_1_PCI_RESET] = { 0x3a9c, 4 },
+ [PCIE_1_POR_RESET] = { 0x3a9c, 3 },
+ [PCIE_1_HCLK_RESET] = { 0x3a9c, 2 },
+ [PCIE_1_ACLK_RESET] = { 0x3a9c, 0 },
+ [PCIE_2_M_RESET] = { 0x3ad8, 1 },
+ [PCIE_2_S_RESET] = { 0x3ad8, 0 },
+ [PCIE_2_EXT_RESET] = { 0x3adc, 6 },
+ [PCIE_2_PHY_RESET] = { 0x3adc, 5 },
+ [PCIE_2_PCI_RESET] = { 0x3adc, 4 },
+ [PCIE_2_POR_RESET] = { 0x3adc, 3 },
+ [PCIE_2_HCLK_RESET] = { 0x3adc, 2 },
+ [PCIE_2_ACLK_RESET] = { 0x3adc, 0 },
+ [SFAB_USB30_S_RESET] = { 0x3b54, 1 },
+ [SFAB_USB30_M_RESET] = { 0x3b54, 0 },
+ [USB30_0_PORT2_HS_PHY_RESET] = { 0x3b50, 5 },
+ [USB30_0_MASTER_RESET] = { 0x3b50, 4 },
+ [USB30_0_SLEEP_RESET] = { 0x3b50, 3 },
+ [USB30_0_UTMI_PHY_RESET] = { 0x3b50, 2 },
+ [USB30_0_POWERON_RESET] = { 0x3b50, 1 },
+ [USB30_0_PHY_RESET] = { 0x3b50, 0 },
+ [USB30_1_MASTER_RESET] = { 0x3b58, 4 },
+ [USB30_1_SLEEP_RESET] = { 0x3b58, 3 },
+ [USB30_1_UTMI_PHY_RESET] = { 0x3b58, 2 },
+ [USB30_1_POWERON_RESET] = { 0x3b58, 1 },
+ [USB30_1_PHY_RESET] = { 0x3b58, 0 },
+ [NSSFB0_RESET] = { 0x3b60, 6 },
+ [NSSFB1_RESET] = { 0x3b60, 7 },
+};
+
+static const struct regmap_config gcc_ipq806x_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x3e40,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_ipq806x_desc = {
+ .config = &gcc_ipq806x_regmap_config,
+ .clks = gcc_ipq806x_clks,
+ .num_clks = ARRAY_SIZE(gcc_ipq806x_clks),
+ .resets = gcc_ipq806x_resets,
+ .num_resets = ARRAY_SIZE(gcc_ipq806x_resets),
+};
+
+static const struct of_device_id gcc_ipq806x_match_table[] = {
+ { .compatible = "qcom,gcc-ipq8064" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, gcc_ipq806x_match_table);
+
+static int gcc_ipq806x_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ struct device *dev = &pdev->dev;
+
+ /* Temporary until RPM clocks supported */
+ clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clk = clk_register_fixed_rate(dev, "pxo", NULL, CLK_IS_ROOT, 25000000);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return qcom_cc_probe(pdev, &gcc_ipq806x_desc);
+}
+
+static int gcc_ipq806x_remove(struct platform_device *pdev)
+{
+ qcom_cc_remove(pdev);
+ return 0;
+}
+
+static struct platform_driver gcc_ipq806x_driver = {
+ .probe = gcc_ipq806x_probe,
+ .remove = gcc_ipq806x_remove,
+ .driver = {
+ .name = "gcc-ipq806x",
+ .owner = THIS_MODULE,
+ .of_match_table = gcc_ipq806x_match_table,
+ },
+};
+
+static int __init gcc_ipq806x_init(void)
+{
+ return platform_driver_register(&gcc_ipq806x_driver);
+}
+core_initcall(gcc_ipq806x_init);
+
+static void __exit gcc_ipq806x_exit(void)
+{
+ platform_driver_unregister(&gcc_ipq806x_driver);
+}
+module_exit(gcc_ipq806x_exit);
+
+MODULE_DESCRIPTION("QCOM GCC IPQ806x Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-ipq806x");
diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
index f4ffd91901f8..007534f7a2d7 100644
--- a/drivers/clk/qcom/gcc-msm8960.c
+++ b/drivers/clk/qcom/gcc-msm8960.c
@@ -104,6 +104,7 @@ static struct clk_regmap pll14_vote = {
#define P_PXO 0
#define P_PLL8 1
+#define P_PLL3 2
#define P_CXO 2
static const u8 gcc_pxo_pll8_map[] = {
@@ -128,6 +129,18 @@ static const char *gcc_pxo_pll8_cxo[] = {
"cxo",
};
+static const u8 gcc_pxo_pll8_pll3_map[] = {
+ [P_PXO] = 0,
+ [P_PLL8] = 3,
+ [P_PLL3] = 6,
+};
+
+static const char *gcc_pxo_pll8_pll3[] = {
+ "pxo",
+ "pll8_vote",
+ "pll3",
+};
+
static struct freq_tbl clk_tbl_gsbi_uart[] = {
{ 1843200, P_PLL8, 2, 6, 625 },
{ 3686400, P_PLL8, 2, 12, 625 },
@@ -1928,6 +1941,104 @@ static struct clk_branch usb_hs1_xcvr_clk = {
},
};
+static struct clk_rcg usb_hs3_xcvr_src = {
+ .ns_reg = 0x370c,
+ .md_reg = 0x3708,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_usb,
+ .clkr = {
+ .enable_reg = 0x370c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs3_xcvr_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch usb_hs3_xcvr_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 30,
+ .clkr = {
+ .enable_reg = 0x370c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs3_xcvr_clk",
+ .parent_names = (const char *[]){ "usb_hs3_xcvr_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_rcg usb_hs4_xcvr_src = {
+ .ns_reg = 0x372c,
+ .md_reg = 0x3728,
+ .mn = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 7,
+ .mnctr_mode_shift = 5,
+ .n_val_shift = 16,
+ .m_val_shift = 16,
+ .width = 8,
+ },
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 2,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_map,
+ },
+ .freq_tbl = clk_tbl_usb,
+ .clkr = {
+ .enable_reg = 0x372c,
+ .enable_mask = BIT(11),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs4_xcvr_src",
+ .parent_names = gcc_pxo_pll8,
+ .num_parents = 2,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ }
+};
+
+static struct clk_branch usb_hs4_xcvr_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 2,
+ .clkr = {
+ .enable_reg = 0x372c,
+ .enable_mask = BIT(9),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs4_xcvr_clk",
+ .parent_names = (const char *[]){ "usb_hs4_xcvr_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
static struct clk_rcg usb_hsic_xcvr_fs_src = {
.ns_reg = 0x2928,
.md_reg = 0x2924,
@@ -2456,6 +2567,34 @@ static struct clk_branch usb_hs1_h_clk = {
},
};
+static struct clk_branch usb_hs3_h_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x3700,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs3_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch usb_hs4_h_clk = {
+ .halt_reg = 0x2fc8,
+ .halt_bit = 7,
+ .clkr = {
+ .enable_reg = 0x3720,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "usb_hs4_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
static struct clk_branch usb_hsic_h_clk = {
.halt_reg = 0x2fcc,
.halt_bit = 28,
@@ -2582,6 +2721,244 @@ static struct clk_branch adm0_pbus_clk = {
},
};
+static struct freq_tbl clk_tbl_ce3[] = {
+ { 48000000, P_PLL8, 8 },
+ { 100000000, P_PLL3, 12 },
+ { 120000000, P_PLL3, 10 },
+ { }
+};
+
+static struct clk_rcg ce3_src = {
+ .ns_reg = 0x36c0,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll3_map,
+ },
+ .freq_tbl = clk_tbl_ce3,
+ .clkr = {
+ .enable_reg = 0x2c08,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce3_src",
+ .parent_names = gcc_pxo_pll8_pll3,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch ce3_core_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 5,
+ .clkr = {
+ .enable_reg = 0x36c4,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce3_core_clk",
+ .parent_names = (const char *[]){ "ce3_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch ce3_h_clk = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 16,
+ .clkr = {
+ .enable_reg = 0x36c4,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "ce3_h_clk",
+ .parent_names = (const char *[]){ "ce3_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static const struct freq_tbl clk_tbl_sata_ref[] = {
+ { 48000000, P_PLL8, 8, 0, 0 },
+ { 100000000, P_PLL3, 12, 0, 0 },
+ { }
+};
+
+static struct clk_rcg sata_clk_src = {
+ .ns_reg = 0x2c08,
+ .p = {
+ .pre_div_shift = 3,
+ .pre_div_width = 4,
+ },
+ .s = {
+ .src_sel_shift = 0,
+ .parent_map = gcc_pxo_pll8_pll3_map,
+ },
+ .freq_tbl = clk_tbl_sata_ref,
+ .clkr = {
+ .enable_reg = 0x2c08,
+ .enable_mask = BIT(7),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_clk_src",
+ .parent_names = gcc_pxo_pll8_pll3,
+ .num_parents = 3,
+ .ops = &clk_rcg_ops,
+ .flags = CLK_SET_RATE_GATE,
+ },
+ },
+};
+
+static struct clk_branch sata_rxoob_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 26,
+ .clkr = {
+ .enable_reg = 0x2c0c,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_rxoob_clk",
+ .parent_names = (const char *[]){ "sata_clk_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch sata_pmalive_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 25,
+ .clkr = {
+ .enable_reg = 0x2c10,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_pmalive_clk",
+ .parent_names = (const char *[]){ "sata_clk_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch sata_phy_ref_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 24,
+ .clkr = {
+ .enable_reg = 0x2c14,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_phy_ref_clk",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ },
+ },
+};
+
+static struct clk_branch sata_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x2c20,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sata_h_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 27,
+ .clkr = {
+ .enable_reg = 0x2c00,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sfab_sata_s_h_clk = {
+ .halt_reg = 0x2fc4,
+ .halt_bit = 14,
+ .clkr = {
+ .enable_reg = 0x2480,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sfab_sata_s_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch sata_phy_cfg_clk = {
+ .halt_reg = 0x2fcc,
+ .halt_bit = 12,
+ .clkr = {
+ .enable_reg = 0x2c40,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "sata_phy_cfg_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_phy_ref_clk = {
+ .halt_reg = 0x2fdc,
+ .halt_bit = 29,
+ .clkr = {
+ .enable_reg = 0x22d0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_phy_ref_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_h_clk = {
+ .halt_reg = 0x2fd4,
+ .halt_bit = 8,
+ .clkr = {
+ .enable_reg = 0x22cc,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_h_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
+static struct clk_branch pcie_a_clk = {
+ .halt_reg = 0x2fc0,
+ .halt_bit = 13,
+ .clkr = {
+ .enable_reg = 0x22c0,
+ .enable_mask = BIT(4),
+ .hw.init = &(struct clk_init_data){
+ .name = "pcie_a_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
static struct clk_branch pmic_arb0_h_clk = {
.halt_reg = 0x2fd8,
.halt_check = BRANCH_HALT_VOTED,
@@ -2869,13 +3246,205 @@ static const struct qcom_reset_map gcc_msm8960_resets[] = {
};
static struct clk_regmap *gcc_apq8064_clks[] = {
+ [PLL3] = &pll3.clkr,
[PLL8] = &pll8.clkr,
[PLL8_VOTE] = &pll8_vote,
+ [PLL14] = &pll14.clkr,
+ [PLL14_VOTE] = &pll14_vote,
+ [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
+ [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
+ [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
+ [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
+ [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr,
+ [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr,
+ [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
+ [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
+ [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
+ [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
+ [GSBI6_UART_SRC] = &gsbi6_uart_src.clkr,
+ [GSBI6_UART_CLK] = &gsbi6_uart_clk.clkr,
[GSBI7_UART_SRC] = &gsbi7_uart_src.clkr,
[GSBI7_UART_CLK] = &gsbi7_uart_clk.clkr,
+ [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
+ [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
+ [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
+ [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
+ [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr,
+ [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr,
+ [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
+ [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
+ [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
+ [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
+ [GSBI6_QUP_SRC] = &gsbi6_qup_src.clkr,
+ [GSBI6_QUP_CLK] = &gsbi6_qup_clk.clkr,
[GSBI7_QUP_SRC] = &gsbi7_qup_src.clkr,
[GSBI7_QUP_CLK] = &gsbi7_qup_clk.clkr,
+ [GP0_SRC] = &gp0_src.clkr,
+ [GP0_CLK] = &gp0_clk.clkr,
+ [GP1_SRC] = &gp1_src.clkr,
+ [GP1_CLK] = &gp1_clk.clkr,
+ [GP2_SRC] = &gp2_src.clkr,
+ [GP2_CLK] = &gp2_clk.clkr,
+ [PMEM_A_CLK] = &pmem_clk.clkr,
+ [PRNG_SRC] = &prng_src.clkr,
+ [PRNG_CLK] = &prng_clk.clkr,
+ [SDC1_SRC] = &sdc1_src.clkr,
+ [SDC1_CLK] = &sdc1_clk.clkr,
+ [SDC2_SRC] = &sdc2_src.clkr,
+ [SDC2_CLK] = &sdc2_clk.clkr,
+ [SDC3_SRC] = &sdc3_src.clkr,
+ [SDC3_CLK] = &sdc3_clk.clkr,
+ [SDC4_SRC] = &sdc4_src.clkr,
+ [SDC4_CLK] = &sdc4_clk.clkr,
+ [TSIF_REF_SRC] = &tsif_ref_src.clkr,
+ [TSIF_REF_CLK] = &tsif_ref_clk.clkr,
+ [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr,
+ [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
+ [USB_HS3_XCVR_SRC] = &usb_hs3_xcvr_src.clkr,
+ [USB_HS3_XCVR_CLK] = &usb_hs3_xcvr_clk.clkr,
+ [USB_HS4_XCVR_SRC] = &usb_hs4_xcvr_src.clkr,
+ [USB_HS4_XCVR_CLK] = &usb_hs4_xcvr_clk.clkr,
+ [USB_HSIC_XCVR_FS_SRC] = &usb_hsic_xcvr_fs_src.clkr,
+ [USB_HSIC_XCVR_FS_CLK] = &usb_hsic_xcvr_fs_clk.clkr,
+ [USB_HSIC_SYSTEM_CLK] = &usb_hsic_system_clk.clkr,
+ [USB_HSIC_HSIC_CLK] = &usb_hsic_hsic_clk.clkr,
+ [USB_HSIC_HSIO_CAL_CLK] = &usb_hsic_hsio_cal_clk.clkr,
+ [USB_FS1_XCVR_FS_SRC] = &usb_fs1_xcvr_fs_src.clkr,
+ [USB_FS1_XCVR_FS_CLK] = &usb_fs1_xcvr_fs_clk.clkr,
+ [USB_FS1_SYSTEM_CLK] = &usb_fs1_system_clk.clkr,
+ [SATA_H_CLK] = &sata_h_clk.clkr,
+ [SATA_CLK_SRC] = &sata_clk_src.clkr,
+ [SATA_RXOOB_CLK] = &sata_rxoob_clk.clkr,
+ [SATA_PMALIVE_CLK] = &sata_pmalive_clk.clkr,
+ [SATA_PHY_REF_CLK] = &sata_phy_ref_clk.clkr,
+ [SATA_PHY_CFG_CLK] = &sata_phy_cfg_clk.clkr,
+ [SATA_A_CLK] = &sata_a_clk.clkr,
+ [SFAB_SATA_S_H_CLK] = &sfab_sata_s_h_clk.clkr,
+ [CE3_SRC] = &ce3_src.clkr,
+ [CE3_CORE_CLK] = &ce3_core_clk.clkr,
+ [CE3_H_CLK] = &ce3_h_clk.clkr,
+ [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
+ [GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
+ [GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
+ [GSBI3_H_CLK] = &gsbi3_h_clk.clkr,
+ [GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
+ [GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
+ [GSBI6_H_CLK] = &gsbi6_h_clk.clkr,
[GSBI7_H_CLK] = &gsbi7_h_clk.clkr,
+ [TSIF_H_CLK] = &tsif_h_clk.clkr,
+ [USB_FS1_H_CLK] = &usb_fs1_h_clk.clkr,
+ [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
+ [USB_HSIC_H_CLK] = &usb_hsic_h_clk.clkr,
+ [USB_HS3_H_CLK] = &usb_hs3_h_clk.clkr,
+ [USB_HS4_H_CLK] = &usb_hs4_h_clk.clkr,
+ [SDC1_H_CLK] = &sdc1_h_clk.clkr,
+ [SDC2_H_CLK] = &sdc2_h_clk.clkr,
+ [SDC3_H_CLK] = &sdc3_h_clk.clkr,
+ [SDC4_H_CLK] = &sdc4_h_clk.clkr,
+ [ADM0_CLK] = &adm0_clk.clkr,
+ [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
+ [PCIE_A_CLK] = &pcie_a_clk.clkr,
+ [PCIE_PHY_REF_CLK] = &pcie_phy_ref_clk.clkr,
+ [PCIE_H_CLK] = &pcie_h_clk.clkr,
+ [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
+ [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
+ [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
+ [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_apq8064_resets[] = {
+ [QDSS_STM_RESET] = { 0x2060, 6 },
+ [AFAB_SMPSS_S_RESET] = { 0x20b8, 2 },
+ [AFAB_SMPSS_M1_RESET] = { 0x20b8, 1 },
+ [AFAB_SMPSS_M0_RESET] = { 0x20b8 },
+ [AFAB_EBI1_CH0_RESET] = { 0x20c0, 7 },
+ [AFAB_EBI1_CH1_RESET] = { 0x20c4, 7},
+ [SFAB_ADM0_M0_RESET] = { 0x21e0, 7 },
+ [SFAB_ADM0_M1_RESET] = { 0x21e4, 7 },
+ [SFAB_ADM0_M2_RESET] = { 0x21e8, 7 },
+ [ADM0_C2_RESET] = { 0x220c, 4},
+ [ADM0_C1_RESET] = { 0x220c, 3},
+ [ADM0_C0_RESET] = { 0x220c, 2},
+ [ADM0_PBUS_RESET] = { 0x220c, 1 },
+ [ADM0_RESET] = { 0x220c },
+ [QDSS_CLKS_SW_RESET] = { 0x2260, 5 },
+ [QDSS_POR_RESET] = { 0x2260, 4 },
+ [QDSS_TSCTR_RESET] = { 0x2260, 3 },
+ [QDSS_HRESET_RESET] = { 0x2260, 2 },
+ [QDSS_AXI_RESET] = { 0x2260, 1 },
+ [QDSS_DBG_RESET] = { 0x2260 },
+ [SFAB_PCIE_M_RESET] = { 0x22d8, 1 },
+ [SFAB_PCIE_S_RESET] = { 0x22d8 },
+ [PCIE_EXT_PCI_RESET] = { 0x22dc, 6 },
+ [PCIE_PHY_RESET] = { 0x22dc, 5 },
+ [PCIE_PCI_RESET] = { 0x22dc, 4 },
+ [PCIE_POR_RESET] = { 0x22dc, 3 },
+ [PCIE_HCLK_RESET] = { 0x22dc, 2 },
+ [PCIE_ACLK_RESET] = { 0x22dc },
+ [SFAB_USB3_M_RESET] = { 0x2360, 7 },
+ [SFAB_RIVA_M_RESET] = { 0x2380, 7 },
+ [SFAB_LPASS_RESET] = { 0x23a0, 7 },
+ [SFAB_AFAB_M_RESET] = { 0x23e0, 7 },
+ [AFAB_SFAB_M0_RESET] = { 0x2420, 7 },
+ [AFAB_SFAB_M1_RESET] = { 0x2424, 7 },
+ [SFAB_SATA_S_RESET] = { 0x2480, 7 },
+ [SFAB_DFAB_M_RESET] = { 0x2500, 7 },
+ [DFAB_SFAB_M_RESET] = { 0x2520, 7 },
+ [DFAB_SWAY0_RESET] = { 0x2540, 7 },
+ [DFAB_SWAY1_RESET] = { 0x2544, 7 },
+ [DFAB_ARB0_RESET] = { 0x2560, 7 },
+ [DFAB_ARB1_RESET] = { 0x2564, 7 },
+ [PPSS_PROC_RESET] = { 0x2594, 1 },
+ [PPSS_RESET] = { 0x2594},
+ [DMA_BAM_RESET] = { 0x25c0, 7 },
+ [SPS_TIC_H_RESET] = { 0x2600, 7 },
+ [SFAB_CFPB_M_RESET] = { 0x2680, 7 },
+ [SFAB_CFPB_S_RESET] = { 0x26c0, 7 },
+ [TSIF_H_RESET] = { 0x2700, 7 },
+ [CE1_H_RESET] = { 0x2720, 7 },
+ [CE1_CORE_RESET] = { 0x2724, 7 },
+ [CE1_SLEEP_RESET] = { 0x2728, 7 },
+ [CE2_H_RESET] = { 0x2740, 7 },
+ [CE2_CORE_RESET] = { 0x2744, 7 },
+ [SFAB_SFPB_M_RESET] = { 0x2780, 7 },
+ [SFAB_SFPB_S_RESET] = { 0x27a0, 7 },
+ [RPM_PROC_RESET] = { 0x27c0, 7 },
+ [PMIC_SSBI2_RESET] = { 0x280c, 12 },
+ [SDC1_RESET] = { 0x2830 },
+ [SDC2_RESET] = { 0x2850 },
+ [SDC3_RESET] = { 0x2870 },
+ [SDC4_RESET] = { 0x2890 },
+ [USB_HS1_RESET] = { 0x2910 },
+ [USB_HSIC_RESET] = { 0x2934 },
+ [USB_FS1_XCVR_RESET] = { 0x2974, 1 },
+ [USB_FS1_RESET] = { 0x2974 },
+ [GSBI1_RESET] = { 0x29dc },
+ [GSBI2_RESET] = { 0x29fc },
+ [GSBI3_RESET] = { 0x2a1c },
+ [GSBI4_RESET] = { 0x2a3c },
+ [GSBI5_RESET] = { 0x2a5c },
+ [GSBI6_RESET] = { 0x2a7c },
+ [GSBI7_RESET] = { 0x2a9c },
+ [SPDM_RESET] = { 0x2b6c },
+ [TLMM_H_RESET] = { 0x2ba0, 7 },
+ [SATA_SFAB_M_RESET] = { 0x2c18 },
+ [SATA_RESET] = { 0x2c1c },
+ [GSS_SLP_RESET] = { 0x2c60, 7 },
+ [GSS_RESET] = { 0x2c64 },
+ [TSSC_RESET] = { 0x2ca0, 7 },
+ [PDM_RESET] = { 0x2cc0, 12 },
+ [MPM_H_RESET] = { 0x2da0, 7 },
+ [MPM_RESET] = { 0x2da4 },
+ [SFAB_SMPSS_S_RESET] = { 0x2e00, 7 },
+ [PRNG_RESET] = { 0x2e80, 12 },
+ [RIVA_RESET] = { 0x35e0 },
+ [CE3_H_RESET] = { 0x36c4, 7 },
+ [SFAB_CE3_M_RESET] = { 0x36c8, 1 },
+ [SFAB_CE3_S_RESET] = { 0x36c8 },
+ [CE3_RESET] = { 0x36cc, 7 },
+ [CE3_SLEEP_RESET] = { 0x36d0, 7 },
+ [USB_HS3_RESET] = { 0x3710 },
+ [USB_HS4_RESET] = { 0x3730 },
};
static const struct regmap_config gcc_msm8960_regmap_config = {
@@ -2886,6 +3455,14 @@ static const struct regmap_config gcc_msm8960_regmap_config = {
.fast_io = true,
};
+static const struct regmap_config gcc_apq8064_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x3880,
+ .fast_io = true,
+};
+
static const struct qcom_cc_desc gcc_msm8960_desc = {
.config = &gcc_msm8960_regmap_config,
.clks = gcc_msm8960_clks,
@@ -2895,11 +3472,11 @@ static const struct qcom_cc_desc gcc_msm8960_desc = {
};
static const struct qcom_cc_desc gcc_apq8064_desc = {
- .config = &gcc_msm8960_regmap_config,
+ .config = &gcc_apq8064_regmap_config,
.clks = gcc_apq8064_clks,
.num_clks = ARRAY_SIZE(gcc_apq8064_clks),
- .resets = gcc_msm8960_resets,
- .num_resets = ARRAY_SIZE(gcc_msm8960_resets),
+ .resets = gcc_apq8064_resets,
+ .num_resets = ARRAY_SIZE(gcc_apq8064_resets),
};
static const struct of_device_id gcc_msm8960_match_table[] = {
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
new file mode 100644
index 000000000000..751eea376a2b
--- /dev/null
+++ b/drivers/clk/qcom/mmcc-apq8084.c
@@ -0,0 +1,3352 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,mmcc-apq8084.h>
+#include <dt-bindings/reset/qcom,mmcc-apq8084.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+
+#define P_XO 0
+#define P_MMPLL0 1
+#define P_EDPLINK 1
+#define P_MMPLL1 2
+#define P_HDMIPLL 2
+#define P_GPLL0 3
+#define P_EDPVCO 3
+#define P_MMPLL4 4
+#define P_DSI0PLL 4
+#define P_DSI0PLL_BYTE 4
+#define P_MMPLL2 4
+#define P_MMPLL3 4
+#define P_GPLL1 5
+#define P_DSI1PLL 5
+#define P_DSI1PLL_BYTE 5
+#define P_MMSLEEP 6
+
+static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_GPLL0] = 5,
+};
+
+static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = {
+ "xo",
+ "mmpll0_vote",
+ "mmpll1_vote",
+ "mmss_gpll0_vote",
+};
+
+static const u8 mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_HDMIPLL] = 4,
+ [P_GPLL0] = 5,
+ [P_DSI0PLL] = 2,
+ [P_DSI1PLL] = 3,
+};
+
+static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
+ "xo",
+ "mmpll0_vote",
+ "hdmipll",
+ "mmss_gpll0_vote",
+ "dsi0pll",
+ "dsi1pll",
+};
+
+static const u8 mmcc_xo_mmpll0_1_2_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_GPLL0] = 5,
+ [P_MMPLL2] = 3,
+};
+
+static const char *mmcc_xo_mmpll0_1_2_gpll0[] = {
+ "xo",
+ "mmpll0_vote",
+ "mmpll1_vote",
+ "mmss_gpll0_vote",
+ "mmpll2",
+};
+
+static const u8 mmcc_xo_mmpll0_1_3_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_GPLL0] = 5,
+ [P_MMPLL3] = 3,
+};
+
+static const char *mmcc_xo_mmpll0_1_3_gpll0[] = {
+ "xo",
+ "mmpll0_vote",
+ "mmpll1_vote",
+ "mmss_gpll0_vote",
+ "mmpll3",
+};
+
+static const u8 mmcc_xo_dsi_hdmi_edp_map[] = {
+ [P_XO] = 0,
+ [P_EDPLINK] = 4,
+ [P_HDMIPLL] = 3,
+ [P_EDPVCO] = 5,
+ [P_DSI0PLL] = 1,
+ [P_DSI1PLL] = 2,
+};
+
+static const char *mmcc_xo_dsi_hdmi_edp[] = {
+ "xo",
+ "edp_link_clk",
+ "hdmipll",
+ "edp_vco_div",
+ "dsi0pll",
+ "dsi1pll",
+};
+
+static const u8 mmcc_xo_dsi_hdmi_edp_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_EDPLINK] = 4,
+ [P_HDMIPLL] = 3,
+ [P_GPLL0] = 5,
+ [P_DSI0PLL] = 1,
+ [P_DSI1PLL] = 2,
+};
+
+static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = {
+ "xo",
+ "edp_link_clk",
+ "hdmipll",
+ "gpll0_vote",
+ "dsi0pll",
+ "dsi1pll",
+};
+
+static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_EDPLINK] = 4,
+ [P_HDMIPLL] = 3,
+ [P_GPLL0] = 5,
+ [P_DSI0PLL_BYTE] = 1,
+ [P_DSI1PLL_BYTE] = 2,
+};
+
+static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
+ "xo",
+ "edp_link_clk",
+ "hdmipll",
+ "gpll0_vote",
+ "dsi0pllbyte",
+ "dsi1pllbyte",
+};
+
+static const u8 mmcc_xo_mmpll0_1_4_gpll0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_GPLL0] = 5,
+ [P_MMPLL4] = 3,
+};
+
+static const char *mmcc_xo_mmpll0_1_4_gpll0[] = {
+ "xo",
+ "mmpll0",
+ "mmpll1",
+ "mmpll4",
+ "gpll0",
+};
+
+static const u8 mmcc_xo_mmpll0_1_4_gpll1_0_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_MMPLL4] = 3,
+ [P_GPLL0] = 5,
+ [P_GPLL1] = 4,
+};
+
+static const char *mmcc_xo_mmpll0_1_4_gpll1_0[] = {
+ "xo",
+ "mmpll0",
+ "mmpll1",
+ "mmpll4",
+ "gpll1",
+ "gpll0",
+};
+
+static const u8 mmcc_xo_mmpll0_1_4_gpll1_0_sleep_map[] = {
+ [P_XO] = 0,
+ [P_MMPLL0] = 1,
+ [P_MMPLL1] = 2,
+ [P_MMPLL4] = 3,
+ [P_GPLL0] = 5,
+ [P_GPLL1] = 4,
+ [P_MMSLEEP] = 6,
+};
+
+static const char *mmcc_xo_mmpll0_1_4_gpll1_0_sleep[] = {
+ "xo",
+ "mmpll0",
+ "mmpll1",
+ "mmpll4",
+ "gpll1",
+ "gpll0",
+ "sleep_clk_src",
+};
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+static struct clk_pll mmpll0 = {
+ .l_reg = 0x0004,
+ .m_reg = 0x0008,
+ .n_reg = 0x000c,
+ .config_reg = 0x0014,
+ .mode_reg = 0x0000,
+ .status_reg = 0x001c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmpll0",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap mmpll0_vote = {
+ .enable_reg = 0x0100,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmpll0_vote",
+ .parent_names = (const char *[]){ "mmpll0" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll mmpll1 = {
+ .l_reg = 0x0044,
+ .m_reg = 0x0048,
+ .n_reg = 0x004c,
+ .config_reg = 0x0050,
+ .mode_reg = 0x0040,
+ .status_reg = 0x005c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmpll1",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_regmap mmpll1_vote = {
+ .enable_reg = 0x0100,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmpll1_vote",
+ .parent_names = (const char *[]){ "mmpll1" },
+ .num_parents = 1,
+ .ops = &clk_pll_vote_ops,
+ },
+};
+
+static struct clk_pll mmpll2 = {
+ .l_reg = 0x4104,
+ .m_reg = 0x4108,
+ .n_reg = 0x410c,
+ .config_reg = 0x4110,
+ .mode_reg = 0x4100,
+ .status_reg = 0x411c,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmpll2",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_pll mmpll3 = {
+ .l_reg = 0x0084,
+ .m_reg = 0x0088,
+ .n_reg = 0x008c,
+ .config_reg = 0x0090,
+ .mode_reg = 0x0080,
+ .status_reg = 0x009c,
+ .status_bit = 17,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmpll3",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_pll mmpll4 = {
+ .l_reg = 0x00a4,
+ .m_reg = 0x00a8,
+ .n_reg = 0x00ac,
+ .config_reg = 0x00b0,
+ .mode_reg = 0x0080,
+ .status_reg = 0x00bc,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmpll4",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static struct clk_rcg2 mmss_ahb_clk_src = {
+ .cmd_rcgr = 0x5000,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmss_ahb_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mmss_axi_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(37500000, P_GPLL0, 16, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(75000000, P_GPLL0, 8, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(333430000, P_MMPLL1, 3.5, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ F(466800000, P_MMPLL1, 2.5, 0, 0),
+};
+
+static struct clk_rcg2 mmss_axi_clk_src = {
+ .cmd_rcgr = 0x5040,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_mmss_axi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mmss_axi_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_ocmemnoc_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(37500000, P_GPLL0, 16, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(75000000, P_GPLL0, 8, 0, 0),
+ F(109090000, P_GPLL0, 5.5, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+};
+
+static struct clk_rcg2 ocmemnoc_clk_src = {
+ .cmd_rcgr = 0x5090,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_ocmemnoc_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "ocmemnoc_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_csi0_3_clk[] = {
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+ .cmd_rcgr = 0x3090,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_csi0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+ .cmd_rcgr = 0x3100,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_csi0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi1_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi2_clk_src = {
+ .cmd_rcgr = 0x3160,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_csi0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi2_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi3_clk_src = {
+ .cmd_rcgr = 0x31c0,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_csi0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi3_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_vfe_vfe0_1_clk[] = {
+ F(37500000, P_GPLL0, 16, 0, 0),
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(60000000, P_GPLL0, 10, 0, 0),
+ F(80000000, P_GPLL0, 7.5, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(109090000, P_GPLL0, 5.5, 0, 0),
+ F(133330000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(266670000, P_MMPLL0, 3, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ F(465000000, P_MMPLL4, 2, 0, 0),
+ F(600000000, P_GPLL0, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+ .cmd_rcgr = 0x3600,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_vfe_vfe0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vfe0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 vfe1_clk_src = {
+ .cmd_rcgr = 0x3620,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_vfe_vfe0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vfe1_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_mdp_clk[] = {
+ F(37500000, P_GPLL0, 16, 0, 0),
+ F(60000000, P_GPLL0, 10, 0, 0),
+ F(75000000, P_GPLL0, 8, 0, 0),
+ F(85710000, P_GPLL0, 7, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(160000000, P_MMPLL0, 5, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(300000000, P_GPLL0, 2, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+ .cmd_rcgr = 0x2040,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_dsi_hdmi_gpll0_map,
+ .freq_tbl = ftbl_mdss_mdp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mdp_clk_src",
+ .parent_names = mmcc_xo_mmpll0_dsi_hdmi_gpll0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+ .cmd_rcgr = 0x4000,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_2_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "gfx3d_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_2_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_jpeg_jpeg0_2_clk[] = {
+ F(75000000, P_GPLL0, 8, 0, 0),
+ F(133330000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_GPLL0, 3, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(266670000, P_MMPLL0, 3, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+ .cmd_rcgr = 0x3500,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "jpeg0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 jpeg1_clk_src = {
+ .cmd_rcgr = 0x3520,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "jpeg1_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 jpeg2_clk_src = {
+ .cmd_rcgr = 0x3540,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_jpeg_jpeg0_2_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "jpeg2_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl pixel_freq_tbl[] = {
+ { .src = P_DSI0PLL },
+ { }
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+ .cmd_rcgr = 0x2000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
+ .freq_tbl = pixel_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pclk0_clk_src",
+ .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_pixel_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+ .cmd_rcgr = 0x2020,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
+ .freq_tbl = pixel_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pclk1_clk_src",
+ .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_pixel_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct freq_tbl ftbl_venus0_vcodec0_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(133330000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ F(266670000, P_MMPLL0, 3, 0, 0),
+ F(465000000, P_MMPLL3, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+ .cmd_rcgr = 0x1000,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_3_gpll0_map,
+ .freq_tbl = ftbl_venus0_vcodec0_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vcodec0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_3_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_avsync_vp_clk[] = {
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vp_clk_src = {
+ .cmd_rcgr = 0x2430,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_avsync_vp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vp_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_cci_cci_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+ .cmd_rcgr = 0x3300,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_map,
+ .freq_tbl = ftbl_camss_cci_cci_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "cci_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_gp0_1_clk[] = {
+ F(10000, P_XO, 16, 1, 120),
+ F(24000, P_XO, 16, 1, 50),
+ F(6000000, P_GPLL0, 10, 1, 10),
+ F(12000000, P_GPLL0, 10, 1, 5),
+ F(13000000, P_GPLL0, 4, 13, 150),
+ F(24000000, P_GPLL0, 5, 1, 5),
+ { }
+};
+
+static struct clk_rcg2 camss_gp0_clk_src = {
+ .cmd_rcgr = 0x3420,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_sleep_map,
+ .freq_tbl = ftbl_camss_gp0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "camss_gp0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0_sleep,
+ .num_parents = 7,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 camss_gp1_clk_src = {
+ .cmd_rcgr = 0x3450,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_sleep_map,
+ .freq_tbl = ftbl_camss_gp0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "camss_gp1_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0_sleep,
+ .num_parents = 7,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_mclk0_3_clk[] = {
+ F(4800000, P_XO, 4, 0, 0),
+ F(6000000, P_GPLL0, 10, 1, 10),
+ F(8000000, P_GPLL0, 15, 1, 5),
+ F(9600000, P_XO, 2, 0, 0),
+ F(16000000, P_MMPLL0, 10, 1, 5),
+ F(19200000, P_XO, 1, 0, 0),
+ F(24000000, P_GPLL0, 5, 1, 5),
+ F(32000000, P_MMPLL0, 5, 1, 5),
+ F(48000000, P_GPLL0, 12.5, 0, 0),
+ F(64000000, P_MMPLL0, 12.5, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+ .cmd_rcgr = 0x3360,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_map,
+ .freq_tbl = ftbl_camss_mclk0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk0_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+ .cmd_rcgr = 0x3390,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_map,
+ .freq_tbl = ftbl_camss_mclk0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk1_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 mclk2_clk_src = {
+ .cmd_rcgr = 0x33c0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_map,
+ .freq_tbl = ftbl_camss_mclk0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk2_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 mclk3_clk_src = {
+ .cmd_rcgr = 0x33f0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll1_0_map,
+ .freq_tbl = ftbl_camss_mclk0_3_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "mclk3_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll1_0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_phy0_2_csi0_2phytimer_clk[] = {
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+ .cmd_rcgr = 0x3000,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi0phytimer_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+ .cmd_rcgr = 0x3030,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi1phytimer_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 csi2phytimer_clk_src = {
+ .cmd_rcgr = 0x3060,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_phy0_2_csi0_2phytimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "csi2phytimer_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_camss_vfe_cpp_clk[] = {
+ F(133330000, P_GPLL0, 4.5, 0, 0),
+ F(266670000, P_MMPLL0, 3, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ F(372000000, P_MMPLL4, 2.5, 0, 0),
+ F(465000000, P_MMPLL4, 2, 0, 0),
+ F(600000000, P_GPLL0, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+ .cmd_rcgr = 0x3640,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_1_4_gpll0_map,
+ .freq_tbl = ftbl_camss_vfe_cpp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "cpp_clk_src",
+ .parent_names = mmcc_xo_mmpll0_1_4_gpll0,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl byte_freq_tbl[] = {
+ { .src = P_DSI0PLL_BYTE },
+ { }
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+ .cmd_rcgr = 0x2120,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
+ .freq_tbl = byte_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "byte0_clk_src",
+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_byte_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+ .cmd_rcgr = 0x2140,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
+ .freq_tbl = byte_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "byte1_clk_src",
+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_byte_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_edpaux_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 edpaux_clk_src = {
+ .cmd_rcgr = 0x20e0,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_mdss_edpaux_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "edpaux_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_edplink_clk[] = {
+ F(135000000, P_EDPLINK, 2, 0, 0),
+ F(270000000, P_EDPLINK, 11, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 edplink_clk_src = {
+ .cmd_rcgr = 0x20c0,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
+ .freq_tbl = ftbl_mdss_edplink_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "edplink_clk_src",
+ .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct freq_tbl edp_pixel_freq_tbl[] = {
+ { .src = P_EDPVCO },
+ { }
+};
+
+static struct clk_rcg2 edppixel_clk_src = {
+ .cmd_rcgr = 0x20a0,
+ .mnd_width = 8,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsi_hdmi_edp_map,
+ .freq_tbl = edp_pixel_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "edppixel_clk_src",
+ .parent_names = mmcc_xo_dsi_hdmi_edp,
+ .num_parents = 6,
+ .ops = &clk_edp_pixel_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_esc0_1_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+ .cmd_rcgr = 0x2160,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
+ .freq_tbl = ftbl_mdss_esc0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "esc0_clk_src",
+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+ .cmd_rcgr = 0x2180,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
+ .freq_tbl = ftbl_mdss_esc0_1_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "esc1_clk_src",
+ .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl extpclk_freq_tbl[] = {
+ { .src = P_HDMIPLL },
+ { }
+};
+
+static struct clk_rcg2 extpclk_clk_src = {
+ .cmd_rcgr = 0x2060,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
+ .freq_tbl = extpclk_freq_tbl,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "extpclk_clk_src",
+ .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
+ .num_parents = 6,
+ .ops = &clk_byte_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_hdmi_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 hdmi_clk_src = {
+ .cmd_rcgr = 0x2100,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_mdss_hdmi_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "hdmi_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mdss_vsync_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+ .cmd_rcgr = 0x2080,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_mdss_vsync_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vsync_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_mmss_rbcpr_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 rbcpr_clk_src = {
+ .cmd_rcgr = 0x4060,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_mmss_rbcpr_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "rbcpr_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_oxili_rbbmtimer_clk[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 rbbmtimer_clk_src = {
+ .cmd_rcgr = 0x4090,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_oxili_rbbmtimer_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "rbbmtimer_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_vpu_maple_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(133330000, P_GPLL0, 4.5, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ F(266670000, P_MMPLL0, 3, 0, 0),
+ F(465000000, P_MMPLL3, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 maple_clk_src = {
+ .cmd_rcgr = 0x1320,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_vpu_maple_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "maple_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_vpu_vdp_clk[] = {
+ F(50000000, P_GPLL0, 12, 0, 0),
+ F(100000000, P_GPLL0, 6, 0, 0),
+ F(200000000, P_MMPLL0, 4, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vdp_clk_src = {
+ .cmd_rcgr = 0x1300,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_vpu_vdp_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vdp_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct freq_tbl ftbl_vpu_bus_clk[] = {
+ F(40000000, P_GPLL0, 15, 0, 0),
+ F(80000000, P_MMPLL0, 10, 0, 0),
+ { }
+};
+
+static struct clk_rcg2 vpu_bus_clk_src = {
+ .cmd_rcgr = 0x1340,
+ .hid_width = 5,
+ .parent_map = mmcc_xo_mmpll0_mmpll1_gpll0_map,
+ .freq_tbl = ftbl_vpu_bus_clk,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "vpu_bus_clk_src",
+ .parent_names = mmcc_xo_mmpll0_mmpll1_gpll0,
+ .num_parents = 4,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_branch mmss_cxo_clk = {
+ .halt_reg = 0x5104,
+ .clkr = {
+ .enable_reg = 0x5104,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_cxo_clk",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_sleepclk_clk = {
+ .halt_reg = 0x5100,
+ .clkr = {
+ .enable_reg = 0x5100,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_sleepclk_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_ahb_clk = {
+ .halt_reg = 0x2414,
+ .clkr = {
+ .enable_reg = 0x2414,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_edppixel_clk = {
+ .halt_reg = 0x2418,
+ .clkr = {
+ .enable_reg = 0x2418,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_edppixel_clk",
+ .parent_names = (const char *[]){
+ "edppixel_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_extpclk_clk = {
+ .halt_reg = 0x2410,
+ .clkr = {
+ .enable_reg = 0x2410,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_extpclk_clk",
+ .parent_names = (const char *[]){
+ "extpclk_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_pclk0_clk = {
+ .halt_reg = 0x241c,
+ .clkr = {
+ .enable_reg = 0x241c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_pclk0_clk",
+ .parent_names = (const char *[]){
+ "pclk0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_pclk1_clk = {
+ .halt_reg = 0x2420,
+ .clkr = {
+ .enable_reg = 0x2420,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_pclk1_clk",
+ .parent_names = (const char *[]){
+ "pclk1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch avsync_vp_clk = {
+ .halt_reg = 0x2404,
+ .clkr = {
+ .enable_reg = 0x2404,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "avsync_vp_clk",
+ .parent_names = (const char *[]){
+ "vp_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_ahb_clk = {
+ .halt_reg = 0x348c,
+ .clkr = {
+ .enable_reg = 0x348c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_cci_cci_ahb_clk = {
+ .halt_reg = 0x3348,
+ .clkr = {
+ .enable_reg = 0x3348,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_cci_cci_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_cci_cci_clk = {
+ .halt_reg = 0x3344,
+ .clkr = {
+ .enable_reg = 0x3344,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_cci_cci_clk",
+ .parent_names = (const char *[]){
+ "cci_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi0_ahb_clk = {
+ .halt_reg = 0x30bc,
+ .clkr = {
+ .enable_reg = 0x30bc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi0_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi0_clk = {
+ .halt_reg = 0x30b4,
+ .clkr = {
+ .enable_reg = 0x30b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi0_clk",
+ .parent_names = (const char *[]){
+ "csi0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi0phy_clk = {
+ .halt_reg = 0x30c4,
+ .clkr = {
+ .enable_reg = 0x30c4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi0phy_clk",
+ .parent_names = (const char *[]){
+ "csi0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi0pix_clk = {
+ .halt_reg = 0x30e4,
+ .clkr = {
+ .enable_reg = 0x30e4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi0pix_clk",
+ .parent_names = (const char *[]){
+ "csi0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi0rdi_clk = {
+ .halt_reg = 0x30d4,
+ .clkr = {
+ .enable_reg = 0x30d4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi0rdi_clk",
+ .parent_names = (const char *[]){
+ "csi0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi1_ahb_clk = {
+ .halt_reg = 0x3128,
+ .clkr = {
+ .enable_reg = 0x3128,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi1_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi1_clk = {
+ .halt_reg = 0x3124,
+ .clkr = {
+ .enable_reg = 0x3124,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi1_clk",
+ .parent_names = (const char *[]){
+ "csi1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi1phy_clk = {
+ .halt_reg = 0x3134,
+ .clkr = {
+ .enable_reg = 0x3134,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi1phy_clk",
+ .parent_names = (const char *[]){
+ "csi1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi1pix_clk = {
+ .halt_reg = 0x3154,
+ .clkr = {
+ .enable_reg = 0x3154,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi1pix_clk",
+ .parent_names = (const char *[]){
+ "csi1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi1rdi_clk = {
+ .halt_reg = 0x3144,
+ .clkr = {
+ .enable_reg = 0x3144,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi1rdi_clk",
+ .parent_names = (const char *[]){
+ "csi1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi2_ahb_clk = {
+ .halt_reg = 0x3188,
+ .clkr = {
+ .enable_reg = 0x3188,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi2_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi2_clk = {
+ .halt_reg = 0x3184,
+ .clkr = {
+ .enable_reg = 0x3184,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi2_clk",
+ .parent_names = (const char *[]){
+ "csi2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi2phy_clk = {
+ .halt_reg = 0x3194,
+ .clkr = {
+ .enable_reg = 0x3194,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi2phy_clk",
+ .parent_names = (const char *[]){
+ "csi2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi2pix_clk = {
+ .halt_reg = 0x31b4,
+ .clkr = {
+ .enable_reg = 0x31b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi2pix_clk",
+ .parent_names = (const char *[]){
+ "csi2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi2rdi_clk = {
+ .halt_reg = 0x31a4,
+ .clkr = {
+ .enable_reg = 0x31a4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi2rdi_clk",
+ .parent_names = (const char *[]){
+ "csi2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi3_ahb_clk = {
+ .halt_reg = 0x31e8,
+ .clkr = {
+ .enable_reg = 0x31e8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi3_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi3_clk = {
+ .halt_reg = 0x31e4,
+ .clkr = {
+ .enable_reg = 0x31e4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi3_clk",
+ .parent_names = (const char *[]){
+ "csi3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi3phy_clk = {
+ .halt_reg = 0x31f4,
+ .clkr = {
+ .enable_reg = 0x31f4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi3phy_clk",
+ .parent_names = (const char *[]){
+ "csi3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi3pix_clk = {
+ .halt_reg = 0x3214,
+ .clkr = {
+ .enable_reg = 0x3214,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi3pix_clk",
+ .parent_names = (const char *[]){
+ "csi3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi3rdi_clk = {
+ .halt_reg = 0x3204,
+ .clkr = {
+ .enable_reg = 0x3204,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi3rdi_clk",
+ .parent_names = (const char *[]){
+ "csi3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi_vfe0_clk = {
+ .halt_reg = 0x3704,
+ .clkr = {
+ .enable_reg = 0x3704,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi_vfe0_clk",
+ .parent_names = (const char *[]){
+ "vfe0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_csi_vfe1_clk = {
+ .halt_reg = 0x3714,
+ .clkr = {
+ .enable_reg = 0x3714,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_csi_vfe1_clk",
+ .parent_names = (const char *[]){
+ "vfe1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_gp0_clk = {
+ .halt_reg = 0x3444,
+ .clkr = {
+ .enable_reg = 0x3444,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_gp0_clk",
+ .parent_names = (const char *[]){
+ "camss_gp0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_gp1_clk = {
+ .halt_reg = 0x3474,
+ .clkr = {
+ .enable_reg = 0x3474,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_gp1_clk",
+ .parent_names = (const char *[]){
+ "camss_gp1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_ispif_ahb_clk = {
+ .halt_reg = 0x3224,
+ .clkr = {
+ .enable_reg = 0x3224,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_ispif_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_jpeg_jpeg0_clk = {
+ .halt_reg = 0x35a8,
+ .clkr = {
+ .enable_reg = 0x35a8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_jpeg_jpeg0_clk",
+ .parent_names = (const char *[]){
+ "jpeg0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_jpeg_jpeg1_clk = {
+ .halt_reg = 0x35ac,
+ .clkr = {
+ .enable_reg = 0x35ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_jpeg_jpeg1_clk",
+ .parent_names = (const char *[]){
+ "jpeg1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_jpeg_jpeg2_clk = {
+ .halt_reg = 0x35b0,
+ .clkr = {
+ .enable_reg = 0x35b0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_jpeg_jpeg2_clk",
+ .parent_names = (const char *[]){
+ "jpeg2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_jpeg_jpeg_ahb_clk = {
+ .halt_reg = 0x35b4,
+ .clkr = {
+ .enable_reg = 0x35b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_jpeg_jpeg_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_jpeg_jpeg_axi_clk = {
+ .halt_reg = 0x35b8,
+ .clkr = {
+ .enable_reg = 0x35b8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_jpeg_jpeg_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_mclk0_clk = {
+ .halt_reg = 0x3384,
+ .clkr = {
+ .enable_reg = 0x3384,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_mclk0_clk",
+ .parent_names = (const char *[]){
+ "mclk0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_mclk1_clk = {
+ .halt_reg = 0x33b4,
+ .clkr = {
+ .enable_reg = 0x33b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_mclk1_clk",
+ .parent_names = (const char *[]){
+ "mclk1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_mclk2_clk = {
+ .halt_reg = 0x33e4,
+ .clkr = {
+ .enable_reg = 0x33e4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_mclk2_clk",
+ .parent_names = (const char *[]){
+ "mclk2_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_mclk3_clk = {
+ .halt_reg = 0x3414,
+ .clkr = {
+ .enable_reg = 0x3414,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_mclk3_clk",
+ .parent_names = (const char *[]){
+ "mclk3_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_micro_ahb_clk = {
+ .halt_reg = 0x3494,
+ .clkr = {
+ .enable_reg = 0x3494,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_micro_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_phy0_csi0phytimer_clk = {
+ .halt_reg = 0x3024,
+ .clkr = {
+ .enable_reg = 0x3024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_phy0_csi0phytimer_clk",
+ .parent_names = (const char *[]){
+ "csi0phytimer_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_phy1_csi1phytimer_clk = {
+ .halt_reg = 0x3054,
+ .clkr = {
+ .enable_reg = 0x3054,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_phy1_csi1phytimer_clk",
+ .parent_names = (const char *[]){
+ "csi1phytimer_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_phy2_csi2phytimer_clk = {
+ .halt_reg = 0x3084,
+ .clkr = {
+ .enable_reg = 0x3084,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_phy2_csi2phytimer_clk",
+ .parent_names = (const char *[]){
+ "csi2phytimer_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_top_ahb_clk = {
+ .halt_reg = 0x3484,
+ .clkr = {
+ .enable_reg = 0x3484,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_top_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_cpp_ahb_clk = {
+ .halt_reg = 0x36b4,
+ .clkr = {
+ .enable_reg = 0x36b4,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_cpp_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_cpp_clk = {
+ .halt_reg = 0x36b0,
+ .clkr = {
+ .enable_reg = 0x36b0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_cpp_clk",
+ .parent_names = (const char *[]){
+ "cpp_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_vfe0_clk = {
+ .halt_reg = 0x36a8,
+ .clkr = {
+ .enable_reg = 0x36a8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_vfe0_clk",
+ .parent_names = (const char *[]){
+ "vfe0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_vfe1_clk = {
+ .halt_reg = 0x36ac,
+ .clkr = {
+ .enable_reg = 0x36ac,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_vfe1_clk",
+ .parent_names = (const char *[]){
+ "vfe1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_vfe_ahb_clk = {
+ .halt_reg = 0x36b8,
+ .clkr = {
+ .enable_reg = 0x36b8,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_vfe_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch camss_vfe_vfe_axi_clk = {
+ .halt_reg = 0x36bc,
+ .clkr = {
+ .enable_reg = 0x36bc,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "camss_vfe_vfe_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_ahb_clk = {
+ .halt_reg = 0x2308,
+ .clkr = {
+ .enable_reg = 0x2308,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_axi_clk = {
+ .halt_reg = 0x2310,
+ .clkr = {
+ .enable_reg = 0x2310,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_byte0_clk = {
+ .halt_reg = 0x233c,
+ .clkr = {
+ .enable_reg = 0x233c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_byte0_clk",
+ .parent_names = (const char *[]){
+ "byte0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_byte1_clk = {
+ .halt_reg = 0x2340,
+ .clkr = {
+ .enable_reg = 0x2340,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_byte1_clk",
+ .parent_names = (const char *[]){
+ "byte1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_edpaux_clk = {
+ .halt_reg = 0x2334,
+ .clkr = {
+ .enable_reg = 0x2334,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_edpaux_clk",
+ .parent_names = (const char *[]){
+ "edpaux_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_edplink_clk = {
+ .halt_reg = 0x2330,
+ .clkr = {
+ .enable_reg = 0x2330,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_edplink_clk",
+ .parent_names = (const char *[]){
+ "edplink_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_edppixel_clk = {
+ .halt_reg = 0x232c,
+ .clkr = {
+ .enable_reg = 0x232c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_edppixel_clk",
+ .parent_names = (const char *[]){
+ "edppixel_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_esc0_clk = {
+ .halt_reg = 0x2344,
+ .clkr = {
+ .enable_reg = 0x2344,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_esc0_clk",
+ .parent_names = (const char *[]){
+ "esc0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_esc1_clk = {
+ .halt_reg = 0x2348,
+ .clkr = {
+ .enable_reg = 0x2348,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_esc1_clk",
+ .parent_names = (const char *[]){
+ "esc1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_extpclk_clk = {
+ .halt_reg = 0x2324,
+ .clkr = {
+ .enable_reg = 0x2324,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_extpclk_clk",
+ .parent_names = (const char *[]){
+ "extpclk_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_hdmi_ahb_clk = {
+ .halt_reg = 0x230c,
+ .clkr = {
+ .enable_reg = 0x230c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_hdmi_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_hdmi_clk = {
+ .halt_reg = 0x2338,
+ .clkr = {
+ .enable_reg = 0x2338,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_hdmi_clk",
+ .parent_names = (const char *[]){
+ "hdmi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_mdp_clk = {
+ .halt_reg = 0x231c,
+ .clkr = {
+ .enable_reg = 0x231c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_mdp_clk",
+ .parent_names = (const char *[]){
+ "mdp_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_mdp_lut_clk = {
+ .halt_reg = 0x2320,
+ .clkr = {
+ .enable_reg = 0x2320,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_mdp_lut_clk",
+ .parent_names = (const char *[]){
+ "mdp_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_pclk0_clk = {
+ .halt_reg = 0x2314,
+ .clkr = {
+ .enable_reg = 0x2314,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_pclk0_clk",
+ .parent_names = (const char *[]){
+ "pclk0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_pclk1_clk = {
+ .halt_reg = 0x2318,
+ .clkr = {
+ .enable_reg = 0x2318,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_pclk1_clk",
+ .parent_names = (const char *[]){
+ "pclk1_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mdss_vsync_clk = {
+ .halt_reg = 0x2328,
+ .clkr = {
+ .enable_reg = 0x2328,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mdss_vsync_clk",
+ .parent_names = (const char *[]){
+ "vsync_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_rbcpr_ahb_clk = {
+ .halt_reg = 0x4088,
+ .clkr = {
+ .enable_reg = 0x4088,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_rbcpr_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_rbcpr_clk = {
+ .halt_reg = 0x4084,
+ .clkr = {
+ .enable_reg = 0x4084,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_rbcpr_clk",
+ .parent_names = (const char *[]){
+ "rbcpr_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_ahb_clk = {
+ .halt_reg = 0x0230,
+ .clkr = {
+ .enable_reg = 0x0230,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_ahb_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_axi_clk = {
+ .halt_reg = 0x0210,
+ .clkr = {
+ .enable_reg = 0x0210,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_axi_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_csi0_clk = {
+ .halt_reg = 0x023c,
+ .clkr = {
+ .enable_reg = 0x023c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_csi0_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_csi0_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_gfx3d_clk = {
+ .halt_reg = 0x022c,
+ .clkr = {
+ .enable_reg = 0x022c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_gfx3d_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_gfx3d_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_jpeg0_clk = {
+ .halt_reg = 0x0204,
+ .clkr = {
+ .enable_reg = 0x0204,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_jpeg0_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_jpeg0_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_jpeg1_clk = {
+ .halt_reg = 0x0208,
+ .clkr = {
+ .enable_reg = 0x0208,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_jpeg1_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_jpeg1_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_jpeg2_clk = {
+ .halt_reg = 0x0224,
+ .clkr = {
+ .enable_reg = 0x0224,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_jpeg2_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_jpeg2_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_mdp_clk = {
+ .halt_reg = 0x020c,
+ .clkr = {
+ .enable_reg = 0x020c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_mdp_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_mdp_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_pclk0_clk = {
+ .halt_reg = 0x0234,
+ .clkr = {
+ .enable_reg = 0x0234,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_pclk0_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_pclk0_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_pclk1_clk = {
+ .halt_reg = 0x0228,
+ .clkr = {
+ .enable_reg = 0x0228,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_pclk1_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_pclk1_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_vcodec0_clk = {
+ .halt_reg = 0x0214,
+ .clkr = {
+ .enable_reg = 0x0214,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_vcodec0_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_vcodec0_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_vfe0_clk = {
+ .halt_reg = 0x0218,
+ .clkr = {
+ .enable_reg = 0x0218,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_vfe0_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_vfe0_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_vfe1_clk = {
+ .halt_reg = 0x021c,
+ .clkr = {
+ .enable_reg = 0x021c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_vfe1_clk",
+ .parent_names = (const char *[]){
+ "mmss_spdm_vfe1_div_clk",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_rm_axi_clk = {
+ .halt_reg = 0x0304,
+ .clkr = {
+ .enable_reg = 0x0304,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_rm_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_spdm_rm_ocmemnoc_clk = {
+ .halt_reg = 0x0308,
+ .clkr = {
+ .enable_reg = 0x0308,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_spdm_rm_ocmemnoc_clk",
+ .parent_names = (const char *[]){
+ "ocmemnoc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+
+static struct clk_branch mmss_misc_ahb_clk = {
+ .halt_reg = 0x502c,
+ .clkr = {
+ .enable_reg = 0x502c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_misc_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_mmssnoc_ahb_clk = {
+ .halt_reg = 0x5024,
+ .clkr = {
+ .enable_reg = 0x5024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_mmssnoc_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+ },
+};
+
+static struct clk_branch mmss_mmssnoc_bto_ahb_clk = {
+ .halt_reg = 0x5028,
+ .clkr = {
+ .enable_reg = 0x5028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_mmssnoc_bto_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+ },
+};
+
+static struct clk_branch mmss_mmssnoc_axi_clk = {
+ .halt_reg = 0x506c,
+ .clkr = {
+ .enable_reg = 0x506c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_mmssnoc_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch mmss_s0_axi_clk = {
+ .halt_reg = 0x5064,
+ .clkr = {
+ .enable_reg = 0x5064,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "mmss_s0_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .ops = &clk_branch2_ops,
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+ },
+ },
+};
+
+static struct clk_branch ocmemcx_ahb_clk = {
+ .halt_reg = 0x405c,
+ .clkr = {
+ .enable_reg = 0x405c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "ocmemcx_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch ocmemcx_ocmemnoc_clk = {
+ .halt_reg = 0x4058,
+ .clkr = {
+ .enable_reg = 0x4058,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "ocmemcx_ocmemnoc_clk",
+ .parent_names = (const char *[]){
+ "ocmemnoc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch oxili_ocmemgx_clk = {
+ .halt_reg = 0x402c,
+ .clkr = {
+ .enable_reg = 0x402c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "oxili_ocmemgx_clk",
+ .parent_names = (const char *[]){
+ "gfx3d_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch oxili_gfx3d_clk = {
+ .halt_reg = 0x4028,
+ .clkr = {
+ .enable_reg = 0x4028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "oxili_gfx3d_clk",
+ .parent_names = (const char *[]){
+ "gfx3d_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch oxili_rbbmtimer_clk = {
+ .halt_reg = 0x40b0,
+ .clkr = {
+ .enable_reg = 0x40b0,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "oxili_rbbmtimer_clk",
+ .parent_names = (const char *[]){
+ "rbbmtimer_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch oxilicx_ahb_clk = {
+ .halt_reg = 0x403c,
+ .clkr = {
+ .enable_reg = 0x403c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "oxilicx_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_ahb_clk = {
+ .halt_reg = 0x1030,
+ .clkr = {
+ .enable_reg = 0x1030,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_axi_clk = {
+ .halt_reg = 0x1034,
+ .clkr = {
+ .enable_reg = 0x1034,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_core0_vcodec_clk = {
+ .halt_reg = 0x1048,
+ .clkr = {
+ .enable_reg = 0x1048,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_core0_vcodec_clk",
+ .parent_names = (const char *[]){
+ "vcodec0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_core1_vcodec_clk = {
+ .halt_reg = 0x104c,
+ .clkr = {
+ .enable_reg = 0x104c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_core1_vcodec_clk",
+ .parent_names = (const char *[]){
+ "vcodec0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_ocmemnoc_clk = {
+ .halt_reg = 0x1038,
+ .clkr = {
+ .enable_reg = 0x1038,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_ocmemnoc_clk",
+ .parent_names = (const char *[]){
+ "ocmemnoc_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch venus0_vcodec0_clk = {
+ .halt_reg = 0x1028,
+ .clkr = {
+ .enable_reg = 0x1028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "venus0_vcodec0_clk",
+ .parent_names = (const char *[]){
+ "vcodec0_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_ahb_clk = {
+ .halt_reg = 0x1430,
+ .clkr = {
+ .enable_reg = 0x1430,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_ahb_clk",
+ .parent_names = (const char *[]){
+ "mmss_ahb_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_axi_clk = {
+ .halt_reg = 0x143c,
+ .clkr = {
+ .enable_reg = 0x143c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_axi_clk",
+ .parent_names = (const char *[]){
+ "mmss_axi_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_bus_clk = {
+ .halt_reg = 0x1440,
+ .clkr = {
+ .enable_reg = 0x1440,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_bus_clk",
+ .parent_names = (const char *[]){
+ "vpu_bus_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_cxo_clk = {
+ .halt_reg = 0x1434,
+ .clkr = {
+ .enable_reg = 0x1434,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_cxo_clk",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_maple_clk = {
+ .halt_reg = 0x142c,
+ .clkr = {
+ .enable_reg = 0x142c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_maple_clk",
+ .parent_names = (const char *[]){
+ "maple_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_sleep_clk = {
+ .halt_reg = 0x1438,
+ .clkr = {
+ .enable_reg = 0x1438,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_sleep_clk",
+ .parent_names = (const char *[]){
+ "sleep_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch vpu_vdp_clk = {
+ .halt_reg = 0x1428,
+ .clkr = {
+ .enable_reg = 0x1428,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu_vdp_clk",
+ .parent_names = (const char *[]){
+ "vdp_clk_src",
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static const struct pll_config mmpll1_config = {
+ .l = 60,
+ .m = 25,
+ .n = 32,
+ .vco_val = 0x0,
+ .vco_mask = 0x3 << 20,
+ .pre_div_val = 0x0,
+ .pre_div_mask = 0x7 << 12,
+ .post_div_val = 0x0,
+ .post_div_mask = 0x3 << 8,
+ .mn_ena_mask = BIT(24),
+ .main_output_mask = BIT(0),
+};
+
+static const struct pll_config mmpll3_config = {
+ .l = 48,
+ .m = 7,
+ .n = 16,
+ .vco_val = 0x0,
+ .vco_mask = 0x3 << 20,
+ .pre_div_val = 0x0,
+ .pre_div_mask = 0x7 << 12,
+ .post_div_val = 0x0,
+ .post_div_mask = 0x3 << 8,
+ .mn_ena_mask = BIT(24),
+ .main_output_mask = BIT(0),
+ .aux_output_mask = BIT(1),
+};
+
+static struct clk_regmap *mmcc_apq8084_clocks[] = {
+ [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
+ [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
+ [MMPLL0] = &mmpll0.clkr,
+ [MMPLL0_VOTE] = &mmpll0_vote,
+ [MMPLL1] = &mmpll1.clkr,
+ [MMPLL1_VOTE] = &mmpll1_vote,
+ [MMPLL2] = &mmpll2.clkr,
+ [MMPLL3] = &mmpll3.clkr,
+ [MMPLL4] = &mmpll4.clkr,
+ [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+ [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+ [CSI2_CLK_SRC] = &csi2_clk_src.clkr,
+ [CSI3_CLK_SRC] = &csi3_clk_src.clkr,
+ [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
+ [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+ [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
+ [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+ [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+ [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+ [OCMEMNOC_CLK_SRC] = &ocmemnoc_clk_src.clkr,
+ [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+ [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+ [JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr,
+ [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr,
+ [EDPPIXEL_CLK_SRC] = &edppixel_clk_src.clkr,
+ [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr,
+ [VP_CLK_SRC] = &vp_clk_src.clkr,
+ [CCI_CLK_SRC] = &cci_clk_src.clkr,
+ [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
+ [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
+ [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+ [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+ [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr,
+ [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr,
+ [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+ [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+ [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr,
+ [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+ [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+ [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+ [EDPAUX_CLK_SRC] = &edpaux_clk_src.clkr,
+ [EDPLINK_CLK_SRC] = &edplink_clk_src.clkr,
+ [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+ [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+ [HDMI_CLK_SRC] = &hdmi_clk_src.clkr,
+ [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+ [RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
+ [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
+ [MAPLE_CLK_SRC] = &maple_clk_src.clkr,
+ [VDP_CLK_SRC] = &vdp_clk_src.clkr,
+ [VPU_BUS_CLK_SRC] = &vpu_bus_clk_src.clkr,
+ [MMSS_CXO_CLK] = &mmss_cxo_clk.clkr,
+ [MMSS_SLEEPCLK_CLK] = &mmss_sleepclk_clk.clkr,
+ [AVSYNC_AHB_CLK] = &avsync_ahb_clk.clkr,
+ [AVSYNC_EDPPIXEL_CLK] = &avsync_edppixel_clk.clkr,
+ [AVSYNC_EXTPCLK_CLK] = &avsync_extpclk_clk.clkr,
+ [AVSYNC_PCLK0_CLK] = &avsync_pclk0_clk.clkr,
+ [AVSYNC_PCLK1_CLK] = &avsync_pclk1_clk.clkr,
+ [AVSYNC_VP_CLK] = &avsync_vp_clk.clkr,
+ [CAMSS_AHB_CLK] = &camss_ahb_clk.clkr,
+ [CAMSS_CCI_CCI_AHB_CLK] = &camss_cci_cci_ahb_clk.clkr,
+ [CAMSS_CCI_CCI_CLK] = &camss_cci_cci_clk.clkr,
+ [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr,
+ [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr,
+ [CAMSS_CSI0PHY_CLK] = &camss_csi0phy_clk.clkr,
+ [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr,
+ [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr,
+ [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr,
+ [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr,
+ [CAMSS_CSI1PHY_CLK] = &camss_csi1phy_clk.clkr,
+ [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr,
+ [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr,
+ [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr,
+ [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr,
+ [CAMSS_CSI2PHY_CLK] = &camss_csi2phy_clk.clkr,
+ [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr,
+ [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr,
+ [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr,
+ [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr,
+ [CAMSS_CSI3PHY_CLK] = &camss_csi3phy_clk.clkr,
+ [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr,
+ [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr,
+ [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr,
+ [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr,
+ [CAMSS_GP0_CLK] = &camss_gp0_clk.clkr,
+ [CAMSS_GP1_CLK] = &camss_gp1_clk.clkr,
+ [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr,
+ [CAMSS_JPEG_JPEG0_CLK] = &camss_jpeg_jpeg0_clk.clkr,
+ [CAMSS_JPEG_JPEG1_CLK] = &camss_jpeg_jpeg1_clk.clkr,
+ [CAMSS_JPEG_JPEG2_CLK] = &camss_jpeg_jpeg2_clk.clkr,
+ [CAMSS_JPEG_JPEG_AHB_CLK] = &camss_jpeg_jpeg_ahb_clk.clkr,
+ [CAMSS_JPEG_JPEG_AXI_CLK] = &camss_jpeg_jpeg_axi_clk.clkr,
+ [CAMSS_MCLK0_CLK] = &camss_mclk0_clk.clkr,
+ [CAMSS_MCLK1_CLK] = &camss_mclk1_clk.clkr,
+ [CAMSS_MCLK2_CLK] = &camss_mclk2_clk.clkr,
+ [CAMSS_MCLK3_CLK] = &camss_mclk3_clk.clkr,
+ [CAMSS_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr,
+ [CAMSS_PHY0_CSI0PHYTIMER_CLK] = &camss_phy0_csi0phytimer_clk.clkr,
+ [CAMSS_PHY1_CSI1PHYTIMER_CLK] = &camss_phy1_csi1phytimer_clk.clkr,
+ [CAMSS_PHY2_CSI2PHYTIMER_CLK] = &camss_phy2_csi2phytimer_clk.clkr,
+ [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr,
+ [CAMSS_VFE_CPP_AHB_CLK] = &camss_vfe_cpp_ahb_clk.clkr,
+ [CAMSS_VFE_CPP_CLK] = &camss_vfe_cpp_clk.clkr,
+ [CAMSS_VFE_VFE0_CLK] = &camss_vfe_vfe0_clk.clkr,
+ [CAMSS_VFE_VFE1_CLK] = &camss_vfe_vfe1_clk.clkr,
+ [CAMSS_VFE_VFE_AHB_CLK] = &camss_vfe_vfe_ahb_clk.clkr,
+ [CAMSS_VFE_VFE_AXI_CLK] = &camss_vfe_vfe_axi_clk.clkr,
+ [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr,
+ [MDSS_AXI_CLK] = &mdss_axi_clk.clkr,
+ [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr,
+ [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr,
+ [MDSS_EDPAUX_CLK] = &mdss_edpaux_clk.clkr,
+ [MDSS_EDPLINK_CLK] = &mdss_edplink_clk.clkr,
+ [MDSS_EDPPIXEL_CLK] = &mdss_edppixel_clk.clkr,
+ [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr,
+ [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr,
+ [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr,
+ [MDSS_HDMI_AHB_CLK] = &mdss_hdmi_ahb_clk.clkr,
+ [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr,
+ [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr,
+ [MDSS_MDP_LUT_CLK] = &mdss_mdp_lut_clk.clkr,
+ [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr,
+ [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr,
+ [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr,
+ [MMSS_RBCPR_AHB_CLK] = &mmss_rbcpr_ahb_clk.clkr,
+ [MMSS_RBCPR_CLK] = &mmss_rbcpr_clk.clkr,
+ [MMSS_SPDM_AHB_CLK] = &mmss_spdm_ahb_clk.clkr,
+ [MMSS_SPDM_AXI_CLK] = &mmss_spdm_axi_clk.clkr,
+ [MMSS_SPDM_CSI0_CLK] = &mmss_spdm_csi0_clk.clkr,
+ [MMSS_SPDM_GFX3D_CLK] = &mmss_spdm_gfx3d_clk.clkr,
+ [MMSS_SPDM_JPEG0_CLK] = &mmss_spdm_jpeg0_clk.clkr,
+ [MMSS_SPDM_JPEG1_CLK] = &mmss_spdm_jpeg1_clk.clkr,
+ [MMSS_SPDM_JPEG2_CLK] = &mmss_spdm_jpeg2_clk.clkr,
+ [MMSS_SPDM_MDP_CLK] = &mmss_spdm_mdp_clk.clkr,
+ [MMSS_SPDM_PCLK0_CLK] = &mmss_spdm_pclk0_clk.clkr,
+ [MMSS_SPDM_PCLK1_CLK] = &mmss_spdm_pclk1_clk.clkr,
+ [MMSS_SPDM_VCODEC0_CLK] = &mmss_spdm_vcodec0_clk.clkr,
+ [MMSS_SPDM_VFE0_CLK] = &mmss_spdm_vfe0_clk.clkr,
+ [MMSS_SPDM_VFE1_CLK] = &mmss_spdm_vfe1_clk.clkr,
+ [MMSS_SPDM_RM_AXI_CLK] = &mmss_spdm_rm_axi_clk.clkr,
+ [MMSS_SPDM_RM_OCMEMNOC_CLK] = &mmss_spdm_rm_ocmemnoc_clk.clkr,
+ [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr,
+ [MMSS_MMSSNOC_AHB_CLK] = &mmss_mmssnoc_ahb_clk.clkr,
+ [MMSS_MMSSNOC_BTO_AHB_CLK] = &mmss_mmssnoc_bto_ahb_clk.clkr,
+ [MMSS_MMSSNOC_AXI_CLK] = &mmss_mmssnoc_axi_clk.clkr,
+ [MMSS_S0_AXI_CLK] = &mmss_s0_axi_clk.clkr,
+ [OCMEMCX_AHB_CLK] = &ocmemcx_ahb_clk.clkr,
+ [OCMEMCX_OCMEMNOC_CLK] = &ocmemcx_ocmemnoc_clk.clkr,
+ [OXILI_OCMEMGX_CLK] = &oxili_ocmemgx_clk.clkr,
+ [OXILI_GFX3D_CLK] = &oxili_gfx3d_clk.clkr,
+ [OXILI_RBBMTIMER_CLK] = &oxili_rbbmtimer_clk.clkr,
+ [OXILICX_AHB_CLK] = &oxilicx_ahb_clk.clkr,
+ [VENUS0_AHB_CLK] = &venus0_ahb_clk.clkr,
+ [VENUS0_AXI_CLK] = &venus0_axi_clk.clkr,
+ [VENUS0_CORE0_VCODEC_CLK] = &venus0_core0_vcodec_clk.clkr,
+ [VENUS0_CORE1_VCODEC_CLK] = &venus0_core1_vcodec_clk.clkr,
+ [VENUS0_OCMEMNOC_CLK] = &venus0_ocmemnoc_clk.clkr,
+ [VENUS0_VCODEC0_CLK] = &venus0_vcodec0_clk.clkr,
+ [VPU_AHB_CLK] = &vpu_ahb_clk.clkr,
+ [VPU_AXI_CLK] = &vpu_axi_clk.clkr,
+ [VPU_BUS_CLK] = &vpu_bus_clk.clkr,
+ [VPU_CXO_CLK] = &vpu_cxo_clk.clkr,
+ [VPU_MAPLE_CLK] = &vpu_maple_clk.clkr,
+ [VPU_SLEEP_CLK] = &vpu_sleep_clk.clkr,
+ [VPU_VDP_CLK] = &vpu_vdp_clk.clkr,
+};
+
+static const struct qcom_reset_map mmcc_apq8084_resets[] = {
+ [MMSS_SPDM_RESET] = { 0x0200 },
+ [MMSS_SPDM_RM_RESET] = { 0x0300 },
+ [VENUS0_RESET] = { 0x1020 },
+ [VPU_RESET] = { 0x1400 },
+ [MDSS_RESET] = { 0x2300 },
+ [AVSYNC_RESET] = { 0x2400 },
+ [CAMSS_PHY0_RESET] = { 0x3020 },
+ [CAMSS_PHY1_RESET] = { 0x3050 },
+ [CAMSS_PHY2_RESET] = { 0x3080 },
+ [CAMSS_CSI0_RESET] = { 0x30b0 },
+ [CAMSS_CSI0PHY_RESET] = { 0x30c0 },
+ [CAMSS_CSI0RDI_RESET] = { 0x30d0 },
+ [CAMSS_CSI0PIX_RESET] = { 0x30e0 },
+ [CAMSS_CSI1_RESET] = { 0x3120 },
+ [CAMSS_CSI1PHY_RESET] = { 0x3130 },
+ [CAMSS_CSI1RDI_RESET] = { 0x3140 },
+ [CAMSS_CSI1PIX_RESET] = { 0x3150 },
+ [CAMSS_CSI2_RESET] = { 0x3180 },
+ [CAMSS_CSI2PHY_RESET] = { 0x3190 },
+ [CAMSS_CSI2RDI_RESET] = { 0x31a0 },
+ [CAMSS_CSI2PIX_RESET] = { 0x31b0 },
+ [CAMSS_CSI3_RESET] = { 0x31e0 },
+ [CAMSS_CSI3PHY_RESET] = { 0x31f0 },
+ [CAMSS_CSI3RDI_RESET] = { 0x3200 },
+ [CAMSS_CSI3PIX_RESET] = { 0x3210 },
+ [CAMSS_ISPIF_RESET] = { 0x3220 },
+ [CAMSS_CCI_RESET] = { 0x3340 },
+ [CAMSS_MCLK0_RESET] = { 0x3380 },
+ [CAMSS_MCLK1_RESET] = { 0x33b0 },
+ [CAMSS_MCLK2_RESET] = { 0x33e0 },
+ [CAMSS_MCLK3_RESET] = { 0x3410 },
+ [CAMSS_GP0_RESET] = { 0x3440 },
+ [CAMSS_GP1_RESET] = { 0x3470 },
+ [CAMSS_TOP_RESET] = { 0x3480 },
+ [CAMSS_AHB_RESET] = { 0x3488 },
+ [CAMSS_MICRO_RESET] = { 0x3490 },
+ [CAMSS_JPEG_RESET] = { 0x35a0 },
+ [CAMSS_VFE_RESET] = { 0x36a0 },
+ [CAMSS_CSI_VFE0_RESET] = { 0x3700 },
+ [CAMSS_CSI_VFE1_RESET] = { 0x3710 },
+ [OXILI_RESET] = { 0x4020 },
+ [OXILICX_RESET] = { 0x4030 },
+ [OCMEMCX_RESET] = { 0x4050 },
+ [MMSS_RBCRP_RESET] = { 0x4080 },
+ [MMSSNOCAHB_RESET] = { 0x5020 },
+ [MMSSNOCAXI_RESET] = { 0x5060 },
+};
+
+static const struct regmap_config mmcc_apq8084_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x5104,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc mmcc_apq8084_desc = {
+ .config = &mmcc_apq8084_regmap_config,
+ .clks = mmcc_apq8084_clocks,
+ .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks),
+ .resets = mmcc_apq8084_resets,
+ .num_resets = ARRAY_SIZE(mmcc_apq8084_resets),
+};
+
+static const struct of_device_id mmcc_apq8084_match_table[] = {
+ { .compatible = "qcom,mmcc-apq8084" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mmcc_apq8084_match_table);
+
+static int mmcc_apq8084_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct regmap *regmap;
+
+ ret = qcom_cc_probe(pdev, &mmcc_apq8084_desc);
+ if (ret)
+ return ret;
+
+ regmap = dev_get_regmap(&pdev->dev, NULL);
+ clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
+ clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
+
+ return 0;
+}
+
+static int mmcc_apq8084_remove(struct platform_device *pdev)
+{
+ qcom_cc_remove(pdev);
+ return 0;
+}
+
+static struct platform_driver mmcc_apq8084_driver = {
+ .probe = mmcc_apq8084_probe,
+ .remove = mmcc_apq8084_remove,
+ .driver = {
+ .name = "mmcc-apq8084",
+ .owner = THIS_MODULE,
+ .of_match_table = mmcc_apq8084_match_table,
+ },
+};
+module_platform_driver(mmcc_apq8084_driver);
+
+MODULE_DESCRIPTION("QCOM MMCC APQ8084 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:mmcc-apq8084");
diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c
index 12f3c0b64fcd..2e80a219b8ea 100644
--- a/drivers/clk/qcom/mmcc-msm8960.c
+++ b/drivers/clk/qcom/mmcc-msm8960.c
@@ -37,6 +37,9 @@
#define P_PLL8 1
#define P_PLL2 2
#define P_PLL3 3
+#define P_PLL15 3
+
+#define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
static u8 mmcc_pxo_pll8_pll2_map[] = {
[P_PXO] = 0,
@@ -57,10 +60,24 @@ static u8 mmcc_pxo_pll8_pll2_pll3_map[] = {
[P_PLL3] = 3,
};
-static const char *mmcc_pxo_pll8_pll2_pll3[] = {
+static const char *mmcc_pxo_pll8_pll2_pll15[] = {
"pxo",
+ "pll8_vote",
"pll2",
+ "pll15",
+};
+
+static u8 mmcc_pxo_pll8_pll2_pll15_map[] = {
+ [P_PXO] = 0,
+ [P_PLL8] = 2,
+ [P_PLL2] = 1,
+ [P_PLL15] = 3,
+};
+
+static const char *mmcc_pxo_pll8_pll2_pll3[] = {
+ "pxo",
"pll8_vote",
+ "pll2",
"pll3",
};
@@ -80,6 +97,36 @@ static struct clk_pll pll2 = {
},
};
+static struct clk_pll pll15 = {
+ .l_reg = 0x33c,
+ .m_reg = 0x340,
+ .n_reg = 0x344,
+ .config_reg = 0x348,
+ .mode_reg = 0x338,
+ .status_reg = 0x350,
+ .status_bit = 16,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "pll15",
+ .parent_names = (const char *[]){ "pxo" },
+ .num_parents = 1,
+ .ops = &clk_pll_ops,
+ },
+};
+
+static const struct pll_config pll15_config = {
+ .l = 33,
+ .m = 1,
+ .n = 3,
+ .vco_val = 0x2 << 16,
+ .vco_mask = 0x3 << 16,
+ .pre_div_val = 0x0,
+ .pre_div_mask = BIT(19),
+ .post_div_val = 0x0,
+ .post_div_mask = 0x3 << 20,
+ .mn_ena_mask = BIT(22),
+ .main_output_mask = BIT(23),
+};
+
static struct freq_tbl clk_tbl_cam[] = {
{ 6000000, P_PLL8, 4, 1, 16 },
{ 8000000, P_PLL8, 4, 1, 12 },
@@ -710,18 +757,18 @@ static struct clk_branch csiphy2_timer_clk = {
};
static struct freq_tbl clk_tbl_gfx2d[] = {
- { 27000000, P_PXO, 1, 0 },
- { 48000000, P_PLL8, 1, 8 },
- { 54857000, P_PLL8, 1, 7 },
- { 64000000, P_PLL8, 1, 6 },
- { 76800000, P_PLL8, 1, 5 },
- { 96000000, P_PLL8, 1, 4 },
- { 128000000, P_PLL8, 1, 3 },
- { 145455000, P_PLL2, 2, 11 },
- { 160000000, P_PLL2, 1, 5 },
- { 177778000, P_PLL2, 2, 9 },
- { 200000000, P_PLL2, 1, 4 },
- { 228571000, P_PLL2, 2, 7 },
+ F_MN( 27000000, P_PXO, 1, 0),
+ F_MN( 48000000, P_PLL8, 1, 8),
+ F_MN( 54857000, P_PLL8, 1, 7),
+ F_MN( 64000000, P_PLL8, 1, 6),
+ F_MN( 76800000, P_PLL8, 1, 5),
+ F_MN( 96000000, P_PLL8, 1, 4),
+ F_MN(128000000, P_PLL8, 1, 3),
+ F_MN(145455000, P_PLL2, 2, 11),
+ F_MN(160000000, P_PLL2, 1, 5),
+ F_MN(177778000, P_PLL2, 2, 9),
+ F_MN(200000000, P_PLL2, 1, 4),
+ F_MN(228571000, P_PLL2, 2, 7),
{ }
};
@@ -842,22 +889,43 @@ static struct clk_branch gfx2d1_clk = {
};
static struct freq_tbl clk_tbl_gfx3d[] = {
- { 27000000, P_PXO, 1, 0 },
- { 48000000, P_PLL8, 1, 8 },
- { 54857000, P_PLL8, 1, 7 },
- { 64000000, P_PLL8, 1, 6 },
- { 76800000, P_PLL8, 1, 5 },
- { 96000000, P_PLL8, 1, 4 },
- { 128000000, P_PLL8, 1, 3 },
- { 145455000, P_PLL2, 2, 11 },
- { 160000000, P_PLL2, 1, 5 },
- { 177778000, P_PLL2, 2, 9 },
- { 200000000, P_PLL2, 1, 4 },
- { 228571000, P_PLL2, 2, 7 },
- { 266667000, P_PLL2, 1, 3 },
- { 300000000, P_PLL3, 1, 4 },
- { 320000000, P_PLL2, 2, 5 },
- { 400000000, P_PLL2, 1, 2 },
+ F_MN( 27000000, P_PXO, 1, 0),
+ F_MN( 48000000, P_PLL8, 1, 8),
+ F_MN( 54857000, P_PLL8, 1, 7),
+ F_MN( 64000000, P_PLL8, 1, 6),
+ F_MN( 76800000, P_PLL8, 1, 5),
+ F_MN( 96000000, P_PLL8, 1, 4),
+ F_MN(128000000, P_PLL8, 1, 3),
+ F_MN(145455000, P_PLL2, 2, 11),
+ F_MN(160000000, P_PLL2, 1, 5),
+ F_MN(177778000, P_PLL2, 2, 9),
+ F_MN(200000000, P_PLL2, 1, 4),
+ F_MN(228571000, P_PLL2, 2, 7),
+ F_MN(266667000, P_PLL2, 1, 3),
+ F_MN(300000000, P_PLL3, 1, 4),
+ F_MN(320000000, P_PLL2, 2, 5),
+ F_MN(400000000, P_PLL2, 1, 2),
+ { }
+};
+
+static struct freq_tbl clk_tbl_gfx3d_8064[] = {
+ F_MN( 27000000, P_PXO, 0, 0),
+ F_MN( 48000000, P_PLL8, 1, 8),
+ F_MN( 54857000, P_PLL8, 1, 7),
+ F_MN( 64000000, P_PLL8, 1, 6),
+ F_MN( 76800000, P_PLL8, 1, 5),
+ F_MN( 96000000, P_PLL8, 1, 4),
+ F_MN(128000000, P_PLL8, 1, 3),
+ F_MN(145455000, P_PLL2, 2, 11),
+ F_MN(160000000, P_PLL2, 1, 5),
+ F_MN(177778000, P_PLL2, 2, 9),
+ F_MN(192000000, P_PLL8, 1, 2),
+ F_MN(200000000, P_PLL2, 1, 4),
+ F_MN(228571000, P_PLL2, 2, 7),
+ F_MN(266667000, P_PLL2, 1, 3),
+ F_MN(320000000, P_PLL2, 2, 5),
+ F_MN(400000000, P_PLL2, 1, 2),
+ F_MN(450000000, P_PLL15, 1, 2),
{ }
};
@@ -897,12 +965,19 @@ static struct clk_dyn_rcg gfx3d_src = {
.hw.init = &(struct clk_init_data){
.name = "gfx3d_src",
.parent_names = mmcc_pxo_pll8_pll2_pll3,
- .num_parents = 3,
+ .num_parents = 4,
.ops = &clk_dyn_rcg_ops,
},
},
};
+static const struct clk_init_data gfx3d_8064_init = {
+ .name = "gfx3d_src",
+ .parent_names = mmcc_pxo_pll8_pll2_pll15,
+ .num_parents = 4,
+ .ops = &clk_dyn_rcg_ops,
+};
+
static struct clk_branch gfx3d_clk = {
.halt_reg = 0x01c8,
.halt_bit = 4,
@@ -919,6 +994,91 @@ static struct clk_branch gfx3d_clk = {
},
};
+static struct freq_tbl clk_tbl_vcap[] = {
+ F_MN( 27000000, P_PXO, 0, 0),
+ F_MN( 54860000, P_PLL8, 1, 7),
+ F_MN( 64000000, P_PLL8, 1, 6),
+ F_MN( 76800000, P_PLL8, 1, 5),
+ F_MN(128000000, P_PLL8, 1, 3),
+ F_MN(160000000, P_PLL2, 1, 5),
+ F_MN(200000000, P_PLL2, 1, 4),
+ { }
+};
+
+static struct clk_dyn_rcg vcap_src = {
+ .ns_reg = 0x021c,
+ .md_reg[0] = 0x01ec,
+ .md_reg[1] = 0x0218,
+ .mn[0] = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 23,
+ .mnctr_mode_shift = 9,
+ .n_val_shift = 18,
+ .m_val_shift = 4,
+ .width = 4,
+ },
+ .mn[1] = {
+ .mnctr_en_bit = 5,
+ .mnctr_reset_bit = 22,
+ .mnctr_mode_shift = 6,
+ .n_val_shift = 14,
+ .m_val_shift = 4,
+ .width = 4,
+ },
+ .s[0] = {
+ .src_sel_shift = 3,
+ .parent_map = mmcc_pxo_pll8_pll2_map,
+ },
+ .s[1] = {
+ .src_sel_shift = 0,
+ .parent_map = mmcc_pxo_pll8_pll2_map,
+ },
+ .mux_sel_bit = 11,
+ .freq_tbl = clk_tbl_vcap,
+ .clkr = {
+ .enable_reg = 0x0178,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "vcap_src",
+ .parent_names = mmcc_pxo_pll8_pll2,
+ .num_parents = 3,
+ .ops = &clk_dyn_rcg_ops,
+ },
+ },
+};
+
+static struct clk_branch vcap_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 15,
+ .clkr = {
+ .enable_reg = 0x0178,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "vcap_clk",
+ .parent_names = (const char *[]){ "vcap_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch vcap_npl_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 25,
+ .clkr = {
+ .enable_reg = 0x0178,
+ .enable_mask = BIT(13),
+ .hw.init = &(struct clk_init_data){
+ .name = "vcap_npl_clk",
+ .parent_names = (const char *[]){ "vcap_src" },
+ .num_parents = 1,
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
static struct freq_tbl clk_tbl_ijpeg[] = {
{ 27000000, P_PXO, 1, 0, 0 },
{ 36570000, P_PLL8, 1, 2, 21 },
@@ -995,7 +1155,7 @@ static struct clk_rcg jpegd_src = {
.ns_reg = 0x00ac,
.p = {
.pre_div_shift = 12,
- .pre_div_width = 2,
+ .pre_div_width = 4,
},
.s = {
.src_sel_shift = 0,
@@ -1115,7 +1275,7 @@ static struct clk_branch mdp_lut_clk = {
.enable_reg = 0x016c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
- .parent_names = (const char *[]){ "mdp_clk" },
+ .parent_names = (const char *[]){ "mdp_src" },
.num_parents = 1,
.name = "mdp_lut_clk",
.ops = &clk_branch_ops,
@@ -1209,7 +1369,7 @@ static struct clk_branch rot_clk = {
static u8 mmcc_pxo_hdmi_map[] = {
[P_PXO] = 0,
- [P_HDMI_PLL] = 2,
+ [P_HDMI_PLL] = 3,
};
static const char *mmcc_pxo_hdmi[] = {
@@ -1218,12 +1378,7 @@ static const char *mmcc_pxo_hdmi[] = {
};
static struct freq_tbl clk_tbl_tv[] = {
- { 25200000, P_HDMI_PLL, 1, 0, 0 },
- { 27000000, P_HDMI_PLL, 1, 0, 0 },
- { 27030000, P_HDMI_PLL, 1, 0, 0 },
- { 74250000, P_HDMI_PLL, 1, 0, 0 },
- { 108000000, P_HDMI_PLL, 1, 0, 0 },
- { 148500000, P_HDMI_PLL, 1, 0, 0 },
+ { .src = P_HDMI_PLL, .pre_div = 1 },
{ }
};
@@ -1254,7 +1409,7 @@ static struct clk_rcg tv_src = {
.name = "tv_src",
.parent_names = mmcc_pxo_hdmi,
.num_parents = 2,
- .ops = &clk_rcg_ops,
+ .ops = &clk_rcg_bypass_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
@@ -1326,6 +1481,38 @@ static struct clk_branch hdmi_tv_clk = {
},
};
+static struct clk_branch rgb_tv_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 27,
+ .clkr = {
+ .enable_reg = 0x0124,
+ .enable_mask = BIT(14),
+ .hw.init = &(struct clk_init_data){
+ .parent_names = tv_src_name,
+ .num_parents = 1,
+ .name = "rgb_tv_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
+static struct clk_branch npl_tv_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 26,
+ .clkr = {
+ .enable_reg = 0x0124,
+ .enable_mask = BIT(16),
+ .hw.init = &(struct clk_init_data){
+ .parent_names = tv_src_name,
+ .num_parents = 1,
+ .name = "npl_tv_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+ },
+};
+
static struct clk_branch hdmi_app_clk = {
.halt_reg = 0x01cc,
.halt_bit = 25,
@@ -1342,15 +1529,15 @@ static struct clk_branch hdmi_app_clk = {
};
static struct freq_tbl clk_tbl_vcodec[] = {
- { 27000000, P_PXO, 1, 0 },
- { 32000000, P_PLL8, 1, 12 },
- { 48000000, P_PLL8, 1, 8 },
- { 54860000, P_PLL8, 1, 7 },
- { 96000000, P_PLL8, 1, 4 },
- { 133330000, P_PLL2, 1, 6 },
- { 200000000, P_PLL2, 1, 4 },
- { 228570000, P_PLL2, 2, 7 },
- { 266670000, P_PLL2, 1, 3 },
+ F_MN( 27000000, P_PXO, 1, 0),
+ F_MN( 32000000, P_PLL8, 1, 12),
+ F_MN( 48000000, P_PLL8, 1, 8),
+ F_MN( 54860000, P_PLL8, 1, 7),
+ F_MN( 96000000, P_PLL8, 1, 4),
+ F_MN(133330000, P_PLL2, 1, 6),
+ F_MN(200000000, P_PLL2, 1, 4),
+ F_MN(228570000, P_PLL2, 2, 7),
+ F_MN(266670000, P_PLL2, 1, 3),
{ }
};
@@ -1701,6 +1888,22 @@ static struct clk_branch rot_axi_clk = {
},
};
+static struct clk_branch vcap_axi_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 20,
+ .hwcg_reg = 0x0244,
+ .hwcg_bit = 11,
+ .clkr = {
+ .enable_reg = 0x0244,
+ .enable_mask = BIT(12),
+ .hw.init = &(struct clk_init_data){
+ .name = "vcap_axi_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
static struct clk_branch vpe_axi_clk = {
.hwcg_reg = 0x0020,
.hwcg_bit = 27,
@@ -2003,6 +2206,20 @@ static struct clk_branch tv_enc_ahb_clk = {
},
};
+static struct clk_branch vcap_ahb_clk = {
+ .halt_reg = 0x0240,
+ .halt_bit = 23,
+ .clkr = {
+ .enable_reg = 0x0248,
+ .enable_mask = BIT(1),
+ .hw.init = &(struct clk_init_data){
+ .name = "vcap_ahb_clk",
+ .ops = &clk_branch_ops,
+ .flags = CLK_IS_ROOT,
+ },
+ },
+};
+
static struct clk_branch vcodec_ahb_clk = {
.hwcg_reg = 0x0038,
.hwcg_bit = 26,
@@ -2215,6 +2432,175 @@ static const struct qcom_reset_map mmcc_msm8960_resets[] = {
[CSI_RDI2_RESET] = { 0x0214 },
};
+static struct clk_regmap *mmcc_apq8064_clks[] = {
+ [AMP_AHB_CLK] = &amp_ahb_clk.clkr,
+ [DSI2_S_AHB_CLK] = &dsi2_s_ahb_clk.clkr,
+ [JPEGD_AHB_CLK] = &jpegd_ahb_clk.clkr,
+ [DSI_S_AHB_CLK] = &dsi_s_ahb_clk.clkr,
+ [DSI2_M_AHB_CLK] = &dsi2_m_ahb_clk.clkr,
+ [VPE_AHB_CLK] = &vpe_ahb_clk.clkr,
+ [SMMU_AHB_CLK] = &smmu_ahb_clk.clkr,
+ [HDMI_M_AHB_CLK] = &hdmi_m_ahb_clk.clkr,
+ [VFE_AHB_CLK] = &vfe_ahb_clk.clkr,
+ [ROT_AHB_CLK] = &rot_ahb_clk.clkr,
+ [VCODEC_AHB_CLK] = &vcodec_ahb_clk.clkr,
+ [MDP_AHB_CLK] = &mdp_ahb_clk.clkr,
+ [DSI_M_AHB_CLK] = &dsi_m_ahb_clk.clkr,
+ [CSI_AHB_CLK] = &csi_ahb_clk.clkr,
+ [MMSS_IMEM_AHB_CLK] = &mmss_imem_ahb_clk.clkr,
+ [IJPEG_AHB_CLK] = &ijpeg_ahb_clk.clkr,
+ [HDMI_S_AHB_CLK] = &hdmi_s_ahb_clk.clkr,
+ [GFX3D_AHB_CLK] = &gfx3d_ahb_clk.clkr,
+ [JPEGD_AXI_CLK] = &jpegd_axi_clk.clkr,
+ [GMEM_AXI_CLK] = &gmem_axi_clk.clkr,
+ [MDP_AXI_CLK] = &mdp_axi_clk.clkr,
+ [MMSS_IMEM_AXI_CLK] = &mmss_imem_axi_clk.clkr,
+ [IJPEG_AXI_CLK] = &ijpeg_axi_clk.clkr,
+ [GFX3D_AXI_CLK] = &gfx3d_axi_clk.clkr,
+ [VCODEC_AXI_CLK] = &vcodec_axi_clk.clkr,
+ [VFE_AXI_CLK] = &vfe_axi_clk.clkr,
+ [VPE_AXI_CLK] = &vpe_axi_clk.clkr,
+ [ROT_AXI_CLK] = &rot_axi_clk.clkr,
+ [VCODEC_AXI_A_CLK] = &vcodec_axi_a_clk.clkr,
+ [VCODEC_AXI_B_CLK] = &vcodec_axi_b_clk.clkr,
+ [CSI0_SRC] = &csi0_src.clkr,
+ [CSI0_CLK] = &csi0_clk.clkr,
+ [CSI0_PHY_CLK] = &csi0_phy_clk.clkr,
+ [CSI1_SRC] = &csi1_src.clkr,
+ [CSI1_CLK] = &csi1_clk.clkr,
+ [CSI1_PHY_CLK] = &csi1_phy_clk.clkr,
+ [CSI2_SRC] = &csi2_src.clkr,
+ [CSI2_CLK] = &csi2_clk.clkr,
+ [CSI2_PHY_CLK] = &csi2_phy_clk.clkr,
+ [CSI_PIX_CLK] = &csi_pix_clk.clkr,
+ [CSI_RDI_CLK] = &csi_rdi_clk.clkr,
+ [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr,
+ [HDMI_APP_CLK] = &hdmi_app_clk.clkr,
+ [CSI_PIX1_CLK] = &csi_pix1_clk.clkr,
+ [CSI_RDI2_CLK] = &csi_rdi2_clk.clkr,
+ [CSI_RDI1_CLK] = &csi_rdi1_clk.clkr,
+ [GFX3D_SRC] = &gfx3d_src.clkr,
+ [GFX3D_CLK] = &gfx3d_clk.clkr,
+ [IJPEG_SRC] = &ijpeg_src.clkr,
+ [IJPEG_CLK] = &ijpeg_clk.clkr,
+ [JPEGD_SRC] = &jpegd_src.clkr,
+ [JPEGD_CLK] = &jpegd_clk.clkr,
+ [MDP_SRC] = &mdp_src.clkr,
+ [MDP_CLK] = &mdp_clk.clkr,
+ [MDP_LUT_CLK] = &mdp_lut_clk.clkr,
+ [ROT_SRC] = &rot_src.clkr,
+ [ROT_CLK] = &rot_clk.clkr,
+ [TV_DAC_CLK] = &tv_dac_clk.clkr,
+ [HDMI_TV_CLK] = &hdmi_tv_clk.clkr,
+ [MDP_TV_CLK] = &mdp_tv_clk.clkr,
+ [TV_SRC] = &tv_src.clkr,
+ [VCODEC_SRC] = &vcodec_src.clkr,
+ [VCODEC_CLK] = &vcodec_clk.clkr,
+ [VFE_SRC] = &vfe_src.clkr,
+ [VFE_CLK] = &vfe_clk.clkr,
+ [VFE_CSI_CLK] = &vfe_csi_clk.clkr,
+ [VPE_SRC] = &vpe_src.clkr,
+ [VPE_CLK] = &vpe_clk.clkr,
+ [CAMCLK0_SRC] = &camclk0_src.clkr,
+ [CAMCLK0_CLK] = &camclk0_clk.clkr,
+ [CAMCLK1_SRC] = &camclk1_src.clkr,
+ [CAMCLK1_CLK] = &camclk1_clk.clkr,
+ [CAMCLK2_SRC] = &camclk2_src.clkr,
+ [CAMCLK2_CLK] = &camclk2_clk.clkr,
+ [CSIPHYTIMER_SRC] = &csiphytimer_src.clkr,
+ [CSIPHY2_TIMER_CLK] = &csiphy2_timer_clk.clkr,
+ [CSIPHY1_TIMER_CLK] = &csiphy1_timer_clk.clkr,
+ [CSIPHY0_TIMER_CLK] = &csiphy0_timer_clk.clkr,
+ [PLL2] = &pll2.clkr,
+ [RGB_TV_CLK] = &rgb_tv_clk.clkr,
+ [NPL_TV_CLK] = &npl_tv_clk.clkr,
+ [VCAP_AHB_CLK] = &vcap_ahb_clk.clkr,
+ [VCAP_AXI_CLK] = &vcap_axi_clk.clkr,
+ [VCAP_SRC] = &vcap_src.clkr,
+ [VCAP_CLK] = &vcap_clk.clkr,
+ [VCAP_NPL_CLK] = &vcap_npl_clk.clkr,
+ [PLL15] = &pll15.clkr,
+};
+
+static const struct qcom_reset_map mmcc_apq8064_resets[] = {
+ [GFX3D_AXI_RESET] = { 0x0208, 17 },
+ [VCAP_AXI_RESET] = { 0x0208, 16 },
+ [VPE_AXI_RESET] = { 0x0208, 15 },
+ [IJPEG_AXI_RESET] = { 0x0208, 14 },
+ [MPD_AXI_RESET] = { 0x0208, 13 },
+ [VFE_AXI_RESET] = { 0x0208, 9 },
+ [SP_AXI_RESET] = { 0x0208, 8 },
+ [VCODEC_AXI_RESET] = { 0x0208, 7 },
+ [ROT_AXI_RESET] = { 0x0208, 6 },
+ [VCODEC_AXI_A_RESET] = { 0x0208, 5 },
+ [VCODEC_AXI_B_RESET] = { 0x0208, 4 },
+ [FAB_S3_AXI_RESET] = { 0x0208, 3 },
+ [FAB_S2_AXI_RESET] = { 0x0208, 2 },
+ [FAB_S1_AXI_RESET] = { 0x0208, 1 },
+ [FAB_S0_AXI_RESET] = { 0x0208 },
+ [SMMU_GFX3D_ABH_RESET] = { 0x020c, 31 },
+ [SMMU_VPE_AHB_RESET] = { 0x020c, 30 },
+ [SMMU_VFE_AHB_RESET] = { 0x020c, 29 },
+ [SMMU_ROT_AHB_RESET] = { 0x020c, 28 },
+ [SMMU_VCODEC_B_AHB_RESET] = { 0x020c, 27 },
+ [SMMU_VCODEC_A_AHB_RESET] = { 0x020c, 26 },
+ [SMMU_MDP1_AHB_RESET] = { 0x020c, 25 },
+ [SMMU_MDP0_AHB_RESET] = { 0x020c, 24 },
+ [SMMU_JPEGD_AHB_RESET] = { 0x020c, 23 },
+ [SMMU_IJPEG_AHB_RESET] = { 0x020c, 22 },
+ [APU_AHB_RESET] = { 0x020c, 18 },
+ [CSI_AHB_RESET] = { 0x020c, 17 },
+ [TV_ENC_AHB_RESET] = { 0x020c, 15 },
+ [VPE_AHB_RESET] = { 0x020c, 14 },
+ [FABRIC_AHB_RESET] = { 0x020c, 13 },
+ [GFX3D_AHB_RESET] = { 0x020c, 10 },
+ [HDMI_AHB_RESET] = { 0x020c, 9 },
+ [MSSS_IMEM_AHB_RESET] = { 0x020c, 8 },
+ [IJPEG_AHB_RESET] = { 0x020c, 7 },
+ [DSI_M_AHB_RESET] = { 0x020c, 6 },
+ [DSI_S_AHB_RESET] = { 0x020c, 5 },
+ [JPEGD_AHB_RESET] = { 0x020c, 4 },
+ [MDP_AHB_RESET] = { 0x020c, 3 },
+ [ROT_AHB_RESET] = { 0x020c, 2 },
+ [VCODEC_AHB_RESET] = { 0x020c, 1 },
+ [VFE_AHB_RESET] = { 0x020c, 0 },
+ [SMMU_VCAP_AHB_RESET] = { 0x0200, 3 },
+ [VCAP_AHB_RESET] = { 0x0200, 2 },
+ [DSI2_M_AHB_RESET] = { 0x0200, 1 },
+ [DSI2_S_AHB_RESET] = { 0x0200, 0 },
+ [CSIPHY2_RESET] = { 0x0210, 31 },
+ [CSI_PIX1_RESET] = { 0x0210, 30 },
+ [CSIPHY0_RESET] = { 0x0210, 29 },
+ [CSIPHY1_RESET] = { 0x0210, 28 },
+ [CSI_RDI_RESET] = { 0x0210, 27 },
+ [CSI_PIX_RESET] = { 0x0210, 26 },
+ [DSI2_RESET] = { 0x0210, 25 },
+ [VFE_CSI_RESET] = { 0x0210, 24 },
+ [MDP_RESET] = { 0x0210, 21 },
+ [AMP_RESET] = { 0x0210, 20 },
+ [JPEGD_RESET] = { 0x0210, 19 },
+ [CSI1_RESET] = { 0x0210, 18 },
+ [VPE_RESET] = { 0x0210, 17 },
+ [MMSS_FABRIC_RESET] = { 0x0210, 16 },
+ [VFE_RESET] = { 0x0210, 15 },
+ [GFX3D_RESET] = { 0x0210, 12 },
+ [HDMI_RESET] = { 0x0210, 11 },
+ [MMSS_IMEM_RESET] = { 0x0210, 10 },
+ [IJPEG_RESET] = { 0x0210, 9 },
+ [CSI0_RESET] = { 0x0210, 8 },
+ [DSI_RESET] = { 0x0210, 7 },
+ [VCODEC_RESET] = { 0x0210, 6 },
+ [MDP_TV_RESET] = { 0x0210, 4 },
+ [MDP_VSYNC_RESET] = { 0x0210, 3 },
+ [ROT_RESET] = { 0x0210, 2 },
+ [TV_HDMI_RESET] = { 0x0210, 1 },
+ [VCAP_NPL_RESET] = { 0x0214, 4 },
+ [VCAP_RESET] = { 0x0214, 3 },
+ [CSI2_RESET] = { 0x0214, 2 },
+ [CSI_RDI1_RESET] = { 0x0214, 1 },
+ [CSI_RDI2_RESET] = { 0x0214 },
+};
+
static const struct regmap_config mmcc_msm8960_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -2223,6 +2609,14 @@ static const struct regmap_config mmcc_msm8960_regmap_config = {
.fast_io = true,
};
+static const struct regmap_config mmcc_apq8064_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x350,
+ .fast_io = true,
+};
+
static const struct qcom_cc_desc mmcc_msm8960_desc = {
.config = &mmcc_msm8960_regmap_config,
.clks = mmcc_msm8960_clks,
@@ -2231,15 +2625,47 @@ static const struct qcom_cc_desc mmcc_msm8960_desc = {
.num_resets = ARRAY_SIZE(mmcc_msm8960_resets),
};
+static const struct qcom_cc_desc mmcc_apq8064_desc = {
+ .config = &mmcc_apq8064_regmap_config,
+ .clks = mmcc_apq8064_clks,
+ .num_clks = ARRAY_SIZE(mmcc_apq8064_clks),
+ .resets = mmcc_apq8064_resets,
+ .num_resets = ARRAY_SIZE(mmcc_apq8064_resets),
+};
+
static const struct of_device_id mmcc_msm8960_match_table[] = {
- { .compatible = "qcom,mmcc-msm8960" },
+ { .compatible = "qcom,mmcc-msm8960", .data = &mmcc_msm8960_desc },
+ { .compatible = "qcom,mmcc-apq8064", .data = &mmcc_apq8064_desc },
{ }
};
MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table);
static int mmcc_msm8960_probe(struct platform_device *pdev)
{
- return qcom_cc_probe(pdev, &mmcc_msm8960_desc);
+ const struct of_device_id *match;
+ struct regmap *regmap;
+ bool is_8064;
+ struct device *dev = &pdev->dev;
+
+ match = of_match_device(mmcc_msm8960_match_table, dev);
+ if (!match)
+ return -EINVAL;
+
+ is_8064 = of_device_is_compatible(dev->of_node, "qcom,mmcc-apq8064");
+ if (is_8064) {
+ gfx3d_src.freq_tbl = clk_tbl_gfx3d_8064;
+ gfx3d_src.clkr.hw.init = &gfx3d_8064_init;
+ gfx3d_src.s[0].parent_map = mmcc_pxo_pll8_pll2_pll15_map;
+ gfx3d_src.s[1].parent_map = mmcc_pxo_pll8_pll2_pll15_map;
+ }
+
+ regmap = qcom_cc_map(pdev, match->data);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_pll_configure_sr(&pll15, regmap, &pll15_config, false);
+
+ return qcom_cc_really_probe(pdev, match->data, regmap);
}
static int mmcc_msm8960_remove(struct platform_device *pdev)
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index c65b90515872..bc8f519c47aa 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -2547,18 +2547,16 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
static int mmcc_msm8974_probe(struct platform_device *pdev)
{
- int ret;
struct regmap *regmap;
- ret = qcom_cc_probe(pdev, &mmcc_msm8974_desc);
- if (ret)
- return ret;
+ regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
- regmap = dev_get_regmap(&pdev->dev, NULL);
clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
- return 0;
+ return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
}
static int mmcc_msm8974_remove(struct platform_device *pdev)
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 8d3aefad2e73..ee6b077381e1 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -3,3 +3,9 @@
#
obj-y += clk-rockchip.o
+obj-y += clk.o
+obj-y += clk-pll.o
+obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
+
+obj-y += clk-rk3188.o
+obj-y += clk-rk3288.o
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
new file mode 100644
index 000000000000..f2a1c7abf4d9
--- /dev/null
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <asm/div64.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include "clk.h"
+
+#define PLL_MODE_MASK 0x3
+#define PLL_MODE_SLOW 0x0
+#define PLL_MODE_NORM 0x1
+#define PLL_MODE_DEEP 0x2
+
+struct rockchip_clk_pll {
+ struct clk_hw hw;
+
+ struct clk_mux pll_mux;
+ const struct clk_ops *pll_mux_ops;
+
+ struct notifier_block clk_nb;
+ bool rate_change_remuxed;
+
+ void __iomem *reg_base;
+ int lock_offset;
+ unsigned int lock_shift;
+ enum rockchip_pll_type type;
+ const struct rockchip_pll_rate_table *rate_table;
+ unsigned int rate_count;
+ spinlock_t *lock;
+};
+
+#define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw)
+#define to_rockchip_clk_pll_nb(nb) \
+ container_of(nb, struct rockchip_clk_pll, clk_nb)
+
+static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
+ struct rockchip_clk_pll *pll, unsigned long rate)
+{
+ const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++) {
+ if (rate == rate_table[i].rate)
+ return &rate_table[i];
+ }
+
+ return NULL;
+}
+
+static long rockchip_pll_round_rate(struct clk_hw *hw,
+ unsigned long drate, unsigned long *prate)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ const struct rockchip_pll_rate_table *rate_table = pll->rate_table;
+ int i;
+
+ /* Assumming rate_table is in descending order */
+ for (i = 0; i < pll->rate_count; i++) {
+ if (drate >= rate_table[i].rate)
+ return rate_table[i].rate;
+ }
+
+ /* return minimum supported value */
+ return rate_table[i - 1].rate;
+}
+
+/*
+ * Wait for the pll to reach the locked state.
+ * The calling set_rate function is responsible for making sure the
+ * grf regmap is available.
+ */
+static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+ struct regmap *grf = rockchip_clk_get_grf();
+ unsigned int val;
+ int delay = 24000000, ret;
+
+ while (delay > 0) {
+ ret = regmap_read(grf, pll->lock_offset, &val);
+ if (ret) {
+ pr_err("%s: failed to read pll lock status: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (val & BIT(pll->lock_shift))
+ return 0;
+ delay--;
+ }
+
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
+ return -ETIMEDOUT;
+}
+
+/**
+ * Set pll mux when changing the pll rate.
+ * This makes sure to move the pll mux away from the actual pll before
+ * changing its rate and back to the original parent after the change.
+ */
+static int rockchip_pll_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll_nb(nb);
+ struct clk_mux *pll_mux = &pll->pll_mux;
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+ int cur_parent;
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
+ if (cur_parent == PLL_MODE_NORM) {
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
+ pll->rate_change_remuxed = 1;
+ }
+ break;
+ case POST_RATE_CHANGE:
+ if (pll->rate_change_remuxed) {
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
+ pll->rate_change_remuxed = 0;
+ }
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+/**
+ * PLL used in RK3066, RK3188 and RK3288
+ */
+
+#define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1)
+
+#define RK3066_PLLCON(i) (i * 0x4)
+#define RK3066_PLLCON0_OD_MASK 0xf
+#define RK3066_PLLCON0_OD_SHIFT 0
+#define RK3066_PLLCON0_NR_MASK 0x3f
+#define RK3066_PLLCON0_NR_SHIFT 8
+#define RK3066_PLLCON1_NF_MASK 0x1fff
+#define RK3066_PLLCON1_NF_SHIFT 0
+#define RK3066_PLLCON2_BWADJ_MASK 0xfff
+#define RK3066_PLLCON2_BWADJ_SHIFT 0
+#define RK3066_PLLCON3_RESET (1 << 5)
+#define RK3066_PLLCON3_PWRDOWN (1 << 1)
+#define RK3066_PLLCON3_BYPASS (1 << 0)
+
+static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long prate)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ u64 nf, nr, no, rate64 = prate;
+ u32 pllcon;
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
+ if (pllcon & RK3066_PLLCON3_BYPASS) {
+ pr_debug("%s: pll %s is bypassed\n", __func__,
+ __clk_get_name(hw->clk));
+ return prate;
+ }
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+ nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
+
+ pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+ nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
+ no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
+
+ rate64 *= (nf + 1);
+ do_div(rate64, nr + 1);
+ do_div(rate64, no + 1);
+
+ return (unsigned long)rate64;
+}
+
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+ unsigned long prate)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ const struct rockchip_pll_rate_table *rate;
+ unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
+ struct regmap *grf = rockchip_clk_get_grf();
+ int ret;
+
+ if (IS_ERR(grf)) {
+ pr_debug("%s: grf regmap not available, aborting rate change\n",
+ __func__);
+ return PTR_ERR(grf);
+ }
+
+ pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+ __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
+
+ /* Get required rate settings from table */
+ rate = rockchip_get_pll_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+ drate, __clk_get_name(hw->clk));
+ return -EINVAL;
+ }
+
+ pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
+ __func__, rate->rate, rate->nr, rate->no, rate->nf);
+
+ /* enter reset mode */
+ writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0),
+ pll->reg_base + RK3066_PLLCON(3));
+
+ /* update pll values */
+ writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK,
+ RK3066_PLLCON0_NR_SHIFT) |
+ HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK,
+ RK3066_PLLCON0_OD_SHIFT),
+ pll->reg_base + RK3066_PLLCON(0));
+
+ writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK,
+ RK3066_PLLCON1_NF_SHIFT),
+ pll->reg_base + RK3066_PLLCON(1));
+ writel_relaxed(HIWORD_UPDATE(rate->bwadj, RK3066_PLLCON2_BWADJ_MASK,
+ RK3066_PLLCON2_BWADJ_SHIFT),
+ pll->reg_base + RK3066_PLLCON(2));
+
+ /* leave reset and wait the reset_delay */
+ writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0),
+ pll->reg_base + RK3066_PLLCON(3));
+ udelay(RK3066_PLL_RESET_DELAY(rate->nr));
+
+ /* wait for the pll to lock */
+ ret = rockchip_pll_wait_lock(pll);
+ if (ret) {
+ pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
+ __func__, old_rate);
+ rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+ }
+
+ return ret;
+}
+
+static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+ writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0),
+ pll->reg_base + RK3066_PLLCON(3));
+
+ return 0;
+}
+
+static void rockchip_rk3066_pll_disable(struct clk_hw *hw)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+
+ writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN,
+ RK3066_PLLCON3_PWRDOWN, 0),
+ pll->reg_base + RK3066_PLLCON(3));
+}
+
+static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
+{
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+ u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3));
+
+ return !(pllcon & RK3066_PLLCON3_PWRDOWN);
+}
+
+static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
+ .recalc_rate = rockchip_rk3066_pll_recalc_rate,
+ .enable = rockchip_rk3066_pll_enable,
+ .disable = rockchip_rk3066_pll_disable,
+ .is_enabled = rockchip_rk3066_pll_is_enabled,
+};
+
+static const struct clk_ops rockchip_rk3066_pll_clk_ops = {
+ .recalc_rate = rockchip_rk3066_pll_recalc_rate,
+ .round_rate = rockchip_pll_round_rate,
+ .set_rate = rockchip_rk3066_pll_set_rate,
+ .enable = rockchip_rk3066_pll_enable,
+ .disable = rockchip_rk3066_pll_disable,
+ .is_enabled = rockchip_rk3066_pll_is_enabled,
+};
+
+/*
+ * Common registering of pll clocks
+ */
+
+struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
+ const char *name, const char **parent_names, u8 num_parents,
+ void __iomem *base, int con_offset, int grf_lock_offset,
+ int lock_shift, int mode_offset, int mode_shift,
+ struct rockchip_pll_rate_table *rate_table,
+ spinlock_t *lock)
+{
+ const char *pll_parents[3];
+ struct clk_init_data init;
+ struct rockchip_clk_pll *pll;
+ struct clk_mux *pll_mux;
+ struct clk *pll_clk, *mux_clk;
+ char pll_name[20];
+ int ret;
+
+ if (num_parents != 2) {
+ pr_err("%s: needs two parent clocks\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* name the actual pll */
+ snprintf(pll_name, sizeof(pll_name), "pll_%s", name);
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = pll_name;
+
+ /* keep all plls untouched for now */
+ init.flags = CLK_IGNORE_UNUSED;
+
+ init.parent_names = &parent_names[0];
+ init.num_parents = 1;
+
+ if (rate_table) {
+ int len;
+
+ /* find count of rates in rate_table */
+ for (len = 0; rate_table[len].rate != 0; )
+ len++;
+
+ pll->rate_count = len;
+ pll->rate_table = kmemdup(rate_table,
+ pll->rate_count *
+ sizeof(struct rockchip_pll_rate_table),
+ GFP_KERNEL);
+ WARN(!pll->rate_table,
+ "%s: could not allocate rate table for %s\n",
+ __func__, name);
+ }
+
+ switch (pll_type) {
+ case pll_rk3066:
+ if (!pll->rate_table)
+ init.ops = &rockchip_rk3066_pll_clk_norate_ops;
+ else
+ init.ops = &rockchip_rk3066_pll_clk_ops;
+ break;
+ default:
+ pr_warn("%s: Unknown pll type for pll clk %s\n",
+ __func__, name);
+ }
+
+ pll->hw.init = &init;
+ pll->type = pll_type;
+ pll->reg_base = base + con_offset;
+ pll->lock_offset = grf_lock_offset;
+ pll->lock_shift = lock_shift;
+ pll->lock = lock;
+ pll->clk_nb.notifier_call = rockchip_pll_notifier_cb;
+
+ pll_clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(pll_clk)) {
+ pr_err("%s: failed to register pll clock %s : %ld\n",
+ __func__, name, PTR_ERR(pll_clk));
+ mux_clk = pll_clk;
+ goto err_pll;
+ }
+
+ ret = clk_notifier_register(pll_clk, &pll->clk_nb);
+ if (ret) {
+ pr_err("%s: failed to register clock notifier for %s : %d\n",
+ __func__, name, ret);
+ mux_clk = ERR_PTR(ret);
+ goto err_pll_notifier;
+ }
+
+ /* create the mux on top of the real pll */
+ pll->pll_mux_ops = &clk_mux_ops;
+ pll_mux = &pll->pll_mux;
+
+ /* the actual muxing is xin24m, pll-output, xin32k */
+ pll_parents[0] = parent_names[0];
+ pll_parents[1] = pll_name;
+ pll_parents[2] = parent_names[1];
+
+ init.name = name;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.ops = pll->pll_mux_ops;
+ init.parent_names = pll_parents;
+ init.num_parents = ARRAY_SIZE(pll_parents);
+
+ pll_mux->reg = base + mode_offset;
+ pll_mux->shift = mode_shift;
+ pll_mux->mask = PLL_MODE_MASK;
+ pll_mux->flags = 0;
+ pll_mux->lock = lock;
+ pll_mux->hw.init = &init;
+
+ if (pll_type == pll_rk3066)
+ pll_mux->flags |= CLK_MUX_HIWORD_MASK;
+
+ mux_clk = clk_register(NULL, &pll_mux->hw);
+ if (IS_ERR(mux_clk))
+ goto err_mux;
+
+ return mux_clk;
+
+err_mux:
+ ret = clk_notifier_unregister(pll_clk, &pll->clk_nb);
+ if (ret) {
+ pr_err("%s: could not unregister clock notifier in error path : %d\n",
+ __func__, ret);
+ return mux_clk;
+ }
+err_pll_notifier:
+ clk_unregister(pll_clk);
+err_pll:
+ kfree(pll);
+ return mux_clk;
+}
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
new file mode 100644
index 000000000000..a83a6d8d0fb6
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/rk3188-cru-common.h>
+#include "clk.h"
+
+#define RK3188_GRF_SOC_STATUS 0xac
+
+enum rk3188_plls {
+ apll, cpll, dpll, gpll,
+};
+
+struct rockchip_pll_rate_table rk3188_pll_rates[] = {
+ RK3066_PLL_RATE(2208000000, 1, 92, 1),
+ RK3066_PLL_RATE(2184000000, 1, 91, 1),
+ RK3066_PLL_RATE(2160000000, 1, 90, 1),
+ RK3066_PLL_RATE(2136000000, 1, 89, 1),
+ RK3066_PLL_RATE(2112000000, 1, 88, 1),
+ RK3066_PLL_RATE(2088000000, 1, 87, 1),
+ RK3066_PLL_RATE(2064000000, 1, 86, 1),
+ RK3066_PLL_RATE(2040000000, 1, 85, 1),
+ RK3066_PLL_RATE(2016000000, 1, 84, 1),
+ RK3066_PLL_RATE(1992000000, 1, 83, 1),
+ RK3066_PLL_RATE(1968000000, 1, 82, 1),
+ RK3066_PLL_RATE(1944000000, 1, 81, 1),
+ RK3066_PLL_RATE(1920000000, 1, 80, 1),
+ RK3066_PLL_RATE(1896000000, 1, 79, 1),
+ RK3066_PLL_RATE(1872000000, 1, 78, 1),
+ RK3066_PLL_RATE(1848000000, 1, 77, 1),
+ RK3066_PLL_RATE(1824000000, 1, 76, 1),
+ RK3066_PLL_RATE(1800000000, 1, 75, 1),
+ RK3066_PLL_RATE(1776000000, 1, 74, 1),
+ RK3066_PLL_RATE(1752000000, 1, 73, 1),
+ RK3066_PLL_RATE(1728000000, 1, 72, 1),
+ RK3066_PLL_RATE(1704000000, 1, 71, 1),
+ RK3066_PLL_RATE(1680000000, 1, 70, 1),
+ RK3066_PLL_RATE(1656000000, 1, 69, 1),
+ RK3066_PLL_RATE(1632000000, 1, 68, 1),
+ RK3066_PLL_RATE(1608000000, 1, 67, 1),
+ RK3066_PLL_RATE(1560000000, 1, 65, 1),
+ RK3066_PLL_RATE(1512000000, 1, 63, 1),
+ RK3066_PLL_RATE(1488000000, 1, 62, 1),
+ RK3066_PLL_RATE(1464000000, 1, 61, 1),
+ RK3066_PLL_RATE(1440000000, 1, 60, 1),
+ RK3066_PLL_RATE(1416000000, 1, 59, 1),
+ RK3066_PLL_RATE(1392000000, 1, 58, 1),
+ RK3066_PLL_RATE(1368000000, 1, 57, 1),
+ RK3066_PLL_RATE(1344000000, 1, 56, 1),
+ RK3066_PLL_RATE(1320000000, 1, 55, 1),
+ RK3066_PLL_RATE(1296000000, 1, 54, 1),
+ RK3066_PLL_RATE(1272000000, 1, 53, 1),
+ RK3066_PLL_RATE(1248000000, 1, 52, 1),
+ RK3066_PLL_RATE(1224000000, 1, 51, 1),
+ RK3066_PLL_RATE(1200000000, 1, 50, 1),
+ RK3066_PLL_RATE(1188000000, 2, 99, 1),
+ RK3066_PLL_RATE(1176000000, 1, 49, 1),
+ RK3066_PLL_RATE(1128000000, 1, 47, 1),
+ RK3066_PLL_RATE(1104000000, 1, 46, 1),
+ RK3066_PLL_RATE(1008000000, 1, 84, 2),
+ RK3066_PLL_RATE( 912000000, 1, 76, 2),
+ RK3066_PLL_RATE( 891000000, 8, 594, 2),
+ RK3066_PLL_RATE( 888000000, 1, 74, 2),
+ RK3066_PLL_RATE( 816000000, 1, 68, 2),
+ RK3066_PLL_RATE( 798000000, 2, 133, 2),
+ RK3066_PLL_RATE( 792000000, 1, 66, 2),
+ RK3066_PLL_RATE( 768000000, 1, 64, 2),
+ RK3066_PLL_RATE( 742500000, 8, 495, 2),
+ RK3066_PLL_RATE( 696000000, 1, 58, 2),
+ RK3066_PLL_RATE( 600000000, 1, 50, 2),
+ RK3066_PLL_RATE( 594000000, 2, 198, 4),
+ RK3066_PLL_RATE( 552000000, 1, 46, 2),
+ RK3066_PLL_RATE( 504000000, 1, 84, 4),
+ RK3066_PLL_RATE( 456000000, 1, 76, 4),
+ RK3066_PLL_RATE( 408000000, 1, 68, 4),
+ RK3066_PLL_RATE( 384000000, 2, 128, 4),
+ RK3066_PLL_RATE( 360000000, 1, 60, 4),
+ RK3066_PLL_RATE( 312000000, 1, 52, 4),
+ RK3066_PLL_RATE( 300000000, 1, 50, 4),
+ RK3066_PLL_RATE( 297000000, 2, 198, 8),
+ RK3066_PLL_RATE( 252000000, 1, 84, 8),
+ RK3066_PLL_RATE( 216000000, 1, 72, 8),
+ RK3066_PLL_RATE( 148500000, 2, 99, 8),
+ RK3066_PLL_RATE( 126000000, 1, 84, 16),
+ RK3066_PLL_RATE( 48000000, 1, 64, 32),
+ { /* sentinel */ },
+};
+
+PNAME(mux_pll_p) = { "xin24m", "xin32k" };
+PNAME(mux_armclk_p) = { "apll", "gpll_armclk" };
+PNAME(mux_ddrphy_p) = { "dpll", "gpll_ddr" };
+PNAME(mux_pll_src_gpll_cpll_p) = { "gpll", "cpll" };
+PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
+PNAME(mux_aclk_cpu_p) = { "apll", "gpll" };
+PNAME(mux_sclk_cif0_p) = { "cif0_pre", "xin24m" };
+PNAME(mux_sclk_i2s0_p) = { "i2s0_pre", "i2s0_frac", "xin12m" };
+PNAME(mux_sclk_spdif_p) = { "spdif_src", "spdif_frac", "xin12m" };
+PNAME(mux_sclk_uart0_p) = { "uart0_pre", "uart0_frac", "xin24m" };
+PNAME(mux_sclk_uart1_p) = { "uart1_pre", "uart1_frac", "xin24m" };
+PNAME(mux_sclk_uart2_p) = { "uart2_pre", "uart2_frac", "xin24m" };
+PNAME(mux_sclk_uart3_p) = { "uart3_pre", "uart3_frac", "xin24m" };
+PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" };
+PNAME(mux_mac_p) = { "gpll", "dpll" };
+PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" };
+
+static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = {
+ [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
+ RK2928_MODE_CON, 0, 6, rk3188_pll_rates),
+ [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
+ RK2928_MODE_CON, 4, 5, NULL),
+ [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8),
+ RK2928_MODE_CON, 8, 7, rk3188_pll_rates),
+ [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
+ RK2928_MODE_CON, 12, 8, rk3188_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+/* 2 ^ (val + 1) */
+static struct clk_div_table div_core_peri_t[] = {
+ { .val = 0, .div = 2 },
+ { .val = 1, .div = 4 },
+ { .val = 2, .div = 8 },
+ { .val = 3, .div = 16 },
+ { /* sentinel */ },
+};
+
+static struct rockchip_clk_branch common_clk_branches[] __initdata = {
+ /*
+ * Clock-Architecture Diagram 2
+ */
+
+ GATE(0, "gpll_armclk", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS),
+
+ /* these two are set by the cpuclk and should not be changed */
+ COMPOSITE_NOMUX_DIVTBL(CORE_PERI, "core_peri", "armclk", 0,
+ RK2928_CLKSEL_CON(0), 6, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
+ div_core_peri_t, RK2928_CLKGATE_CON(0), 0, GFLAGS),
+
+ COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 9, GFLAGS),
+ GATE(0, "hclk_vepu", "aclk_vepu", 0,
+ RK2928_CLKGATE_CON(3), 10, GFLAGS),
+ COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 11, GFLAGS),
+ GATE(0, "hclk_vdpu", "aclk_vdpu", 0,
+ RK2928_CLKGATE_CON(3), 12, GFLAGS),
+
+ GATE(0, "gpll_ddr", "gpll", 0,
+ RK2928_CLKGATE_CON(1), 7, GFLAGS),
+ COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0,
+ RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK2928_CLKGATE_CON(0), 2, GFLAGS),
+
+ GATE(0, "aclk_cpu", "aclk_cpu_pre", 0,
+ RK2928_CLKGATE_CON(0), 3, GFLAGS),
+
+ DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0,
+ RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+ GATE(0, "atclk_cpu", "pclk_cpu_pre", 0,
+ RK2928_CLKGATE_CON(0), 6, GFLAGS),
+ GATE(0, "pclk_cpu", "pclk_cpu_pre", 0,
+ RK2928_CLKGATE_CON(0), 5, GFLAGS),
+ DIV(0, "hclk_cpu_pre", "aclk_cpu_pre", 0,
+ RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+ COMPOSITE_NOMUX(0, "hclk_ahb2apb", "hclk_cpu_pre", 0,
+ RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK2928_CLKGATE_CON(4), 9, GFLAGS),
+ GATE(0, "hclk_cpu", "hclk_cpu_pre", 0,
+ RK2928_CLKGATE_CON(0), 4, GFLAGS),
+
+ COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 0, GFLAGS),
+ COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(31), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK2928_CLKGATE_CON(1), 4, GFLAGS),
+
+ GATE(0, "aclk_peri", "aclk_peri_pre", 0,
+ RK2928_CLKGATE_CON(2), 1, GFLAGS),
+ COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_pre", 0,
+ RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK2928_CLKGATE_CON(2), 2, GFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_pre", 0,
+ RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK2928_CLKGATE_CON(2), 3, GFLAGS),
+
+ MUX(0, "cif_src", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(29), 0, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "cif0_pre", "cif_src", 0,
+ RK2928_CLKSEL_CON(29), 1, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 7, GFLAGS),
+ MUX(SCLK_CIF0, "sclk_cif0", mux_sclk_cif0_p, 0,
+ RK2928_CLKSEL_CON(29), 7, 1, MFLAGS),
+
+ GATE(0, "pclkin_cif0", "ext_cif0", 0,
+ RK2928_CLKGATE_CON(3), 3, GFLAGS),
+
+ /*
+ * the 480m are generated inside the usb block from these clocks,
+ * but they are also a source for the hsicphy clock.
+ */
+ GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0,
+ RK2928_CLKGATE_CON(1), 5, GFLAGS),
+ GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0,
+ RK2928_CLKGATE_CON(1), 6, GFLAGS),
+
+ COMPOSITE(0, "mac_src", mux_mac_p, 0,
+ RK2928_CLKSEL_CON(21), 0, 1, MFLAGS, 8, 5, DFLAGS,
+ RK2928_CLKGATE_CON(2), 5, GFLAGS),
+ MUX(SCLK_MAC, "sclk_macref", mux_sclk_macref_p, CLK_SET_RATE_PARENT,
+ RK2928_CLKSEL_CON(21), 4, 1, MFLAGS),
+ GATE(0, "sclk_mac_lbtest", "sclk_macref",
+ RK2928_CLKGATE_CON(2), 12, 0, GFLAGS),
+
+ COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0,
+ RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(2), 6, GFLAGS),
+ COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src",
+ RK2928_CLKSEL_CON(23), 0,
+ RK2928_CLKGATE_CON(2), 7, 0, GFLAGS),
+ MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0,
+ RK2928_CLKSEL_CON(22), 4, 2, MFLAGS),
+
+ COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0,
+ RK2928_CLKSEL_CON(24), 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(2), 8, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 4
+ */
+
+ GATE(SCLK_SMC, "sclk_smc", "hclk_peri",
+ RK2928_CLKGATE_CON(2), 4, 0, GFLAGS),
+
+ COMPOSITE_NOMUX(SCLK_SPI0, "sclk_spi0", "pclk_peri", 0,
+ RK2928_CLKSEL_CON(25), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(2), 9, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_SPI1, "sclk_spi1", "pclk_peri", 0,
+ RK2928_CLKSEL_CON(25), 8, 7, DFLAGS,
+ RK2928_CLKGATE_CON(2), 10, GFLAGS),
+
+ COMPOSITE_NOMUX(SCLK_SDMMC, "sclk_sdmmc", "hclk_peri", 0,
+ RK2928_CLKSEL_CON(11), 0, 6, DFLAGS,
+ RK2928_CLKGATE_CON(2), 11, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_SDIO, "sclk_sdio", "hclk_peri", 0,
+ RK2928_CLKSEL_CON(12), 0, 6, DFLAGS,
+ RK2928_CLKGATE_CON(2), 13, GFLAGS),
+ COMPOSITE_NOMUX(SCLK_EMMC, "sclk_emmc", "hclk_peri", 0,
+ RK2928_CLKSEL_CON(12), 8, 6, DFLAGS,
+ RK2928_CLKGATE_CON(2), 14, GFLAGS),
+
+ MUX(0, "uart_src", mux_pll_src_gpll_cpll_p, 0,
+ RK2928_CLKSEL_CON(12), 15, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0,
+ RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(1), 8, GFLAGS),
+ COMPOSITE_FRAC(0, "uart0_frac", "uart0_pre", 0,
+ RK2928_CLKSEL_CON(17), 0,
+ RK2928_CLKGATE_CON(1), 9, GFLAGS),
+ MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0,
+ RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0,
+ RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(1), 10, GFLAGS),
+ COMPOSITE_FRAC(0, "uart1_frac", "uart1_pre", 0,
+ RK2928_CLKSEL_CON(18), 0,
+ RK2928_CLKGATE_CON(1), 11, GFLAGS),
+ MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0,
+ RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0,
+ RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(1), 12, GFLAGS),
+ COMPOSITE_FRAC(0, "uart2_frac", "uart2_pre", 0,
+ RK2928_CLKSEL_CON(19), 0,
+ RK2928_CLKGATE_CON(1), 13, GFLAGS),
+ MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0,
+ RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0,
+ RK2928_CLKSEL_CON(16), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(1), 14, GFLAGS),
+ COMPOSITE_FRAC(0, "uart3_frac", "uart3_pre", 0,
+ RK2928_CLKSEL_CON(20), 0,
+ RK2928_CLKGATE_CON(1), 15, GFLAGS),
+ MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0,
+ RK2928_CLKSEL_CON(16), 8, 2, MFLAGS),
+
+ GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS),
+
+ GATE(SCLK_TIMER0, "timer0", "xin24m", 0, RK2928_CLKGATE_CON(1), 0, GFLAGS),
+ GATE(SCLK_TIMER1, "timer1", "xin24m", 0, RK2928_CLKGATE_CON(1), 1, GFLAGS),
+
+ /* clk_core_pre gates */
+ GATE(0, "core_dbg", "armclk", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS),
+
+ /* aclk_cpu gates */
+ GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS),
+ GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS),
+ GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS),
+
+ /* hclk_cpu gates */
+ GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS),
+ GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
+ GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS),
+ GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS),
+ /* hclk_ahb2apb is part of a clk branch */
+ GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS),
+ GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS),
+ GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS),
+ GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS),
+ GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS),
+ GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS),
+
+ /* hclk_peri gates */
+ GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS),
+ GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS),
+ GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS),
+ GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
+ GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
+ GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS),
+ GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS),
+ GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS),
+ GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS),
+ GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
+ GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
+ GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 12, GFLAGS),
+
+ /* aclk_lcdc0_pre gates */
+ GATE(0, "aclk_vio0", "aclk_lcdc0_pre", 0, RK2928_CLKGATE_CON(6), 13, GFLAGS),
+ GATE(ACLK_LCDC0, "aclk_lcdc0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS),
+ GATE(ACLK_CIF0, "aclk_cif0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 5, GFLAGS),
+ GATE(ACLK_IPP, "aclk_ipp", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 8, GFLAGS),
+
+ /* aclk_lcdc1_pre gates */
+ GATE(0, "aclk_vio1", "aclk_lcdc1_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS),
+ GATE(ACLK_LCDC1, "aclk_lcdc1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 3, GFLAGS),
+ GATE(ACLK_RGA, "aclk_rga", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 11, GFLAGS),
+
+ /* atclk_cpu gates */
+ GATE(0, "atclk", "atclk_cpu", 0, RK2928_CLKGATE_CON(9), 3, GFLAGS),
+ GATE(0, "trace", "atclk_cpu", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS),
+
+ /* pclk_cpu gates */
+ GATE(PCLK_PWM01, "pclk_pwm01", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS),
+ GATE(PCLK_TIMER0, "pclk_timer0", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS),
+ GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
+ GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
+ GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
+ GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
+ GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
+ GATE(PCLK_EFUSE, "pclk_efuse", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS),
+ GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 3, GFLAGS),
+ GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
+ GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
+ GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
+ GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS),
+ GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS),
+
+ /* aclk_peri */
+ GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
+ GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS),
+ GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS),
+ GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS),
+ GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS),
+
+ /* pclk_peri gates */
+ GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS),
+ GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS),
+ GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
+ GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
+ GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 13, GFLAGS),
+ GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
+ GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS),
+ GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
+ GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS),
+ GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS),
+ GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
+ GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS),
+};
+
+PNAME(mux_rk3066_lcdc0_p) = { "dclk_lcdc0_src", "xin27m" };
+PNAME(mux_rk3066_lcdc1_p) = { "dclk_lcdc1_src", "xin27m" };
+PNAME(mux_sclk_cif1_p) = { "cif1_pre", "xin24m" };
+PNAME(mux_sclk_i2s1_p) = { "i2s1_pre", "i2s1_frac", "xin12m" };
+PNAME(mux_sclk_i2s2_p) = { "i2s2_pre", "i2s2_frac", "xin12m" };
+
+static struct clk_div_table div_aclk_cpu_t[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 8 },
+ { /* sentinel */ },
+};
+
+static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
+ COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0,
+ RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 0, 5, DFLAGS),
+ DIVTBL(0, "aclk_cpu_pre", "armclk", 0,
+ RK2928_CLKSEL_CON(1), 0, 3, DFLAGS, div_aclk_cpu_t),
+
+ GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0,
+ RK2928_CLKGATE_CON(9), 4, GFLAGS),
+
+ COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0,
+ RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(2), 0, GFLAGS),
+
+ COMPOSITE(0, "dclk_lcdc0_src", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(3), 1, GFLAGS),
+ MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, 0,
+ RK2928_CLKSEL_CON(27), 4, 1, MFLAGS),
+ COMPOSITE(0, "dclk_lcdc1_src", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(3), 2, GFLAGS),
+ MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, 0,
+ RK2928_CLKSEL_CON(28), 4, 1, MFLAGS),
+
+ COMPOSITE_NOMUX(0, "cif1_pre", "cif_src", 0,
+ RK2928_CLKSEL_CON(29), 8, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 8, GFLAGS),
+ MUX(SCLK_CIF1, "sclk_cif1", mux_sclk_cif1_p, 0,
+ RK2928_CLKSEL_CON(29), 15, 1, MFLAGS),
+
+ GATE(0, "pclkin_cif1", "ext_cif1", 0,
+ RK2928_CLKGATE_CON(3), 4, GFLAGS),
+
+ COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(33), 8, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 13, GFLAGS),
+ GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_src", 0,
+ RK2928_CLKGATE_CON(5), 15, GFLAGS),
+
+ GATE(SCLK_TIMER2, "timer2", "xin24m", 0,
+ RK2928_CLKGATE_CON(3), 2, GFLAGS),
+
+ COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0,
+ RK2928_CLKSEL_CON(34), 0, 16, DFLAGS,
+ RK2928_CLKGATE_CON(2), 15, GFLAGS),
+
+ MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0,
+ RK2928_CLKSEL_CON(2), 15, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(2), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 7, GFLAGS),
+ COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+ RK2928_CLKSEL_CON(6), 0,
+ RK2928_CLKGATE_CON(0), 8, GFLAGS),
+ MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
+ RK2928_CLKSEL_CON(2), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 9, GFLAGS),
+ COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_pre", 0,
+ RK2928_CLKSEL_CON(7), 0,
+ RK2928_CLKGATE_CON(0), 10, GFLAGS),
+ MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0,
+ RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(4), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 11, GFLAGS),
+ COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_pre", 0,
+ RK2928_CLKSEL_CON(8), 0,
+ RK2928_CLKGATE_CON(0), 12, GFLAGS),
+ MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0,
+ RK2928_CLKSEL_CON(4), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 13, GFLAGS),
+ COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
+ RK2928_CLKSEL_CON(9), 0,
+ RK2928_CLKGATE_CON(0), 14, GFLAGS),
+ MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
+ RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
+
+ GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
+ GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
+ GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
+ GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
+
+ GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
+
+ GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS),
+
+ GATE(PCLK_TIMER1, "pclk_timer1", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 8, GFLAGS),
+ GATE(PCLK_TIMER2, "pclk_timer2", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
+ GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS),
+ GATE(PCLK_UART0, "pclk_uart0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
+ GATE(PCLK_UART1, "pclk_uart1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
+
+ GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
+ GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 13, GFLAGS),
+};
+
+static struct clk_div_table div_rk3188_aclk_core_t[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 8 },
+ { /* sentinel */ },
+};
+
+PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1",
+ "gpll", "cpll" };
+
+static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
+ COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0,
+ RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 9, 5, DFLAGS),
+ COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0,
+ RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+ div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS),
+
+ /* do not source aclk_cpu_pre from the apll, to keep complexity down */
+ COMPOSITE_NOGATE(0, "aclk_cpu_pre", mux_aclk_cpu_p, CLK_SET_RATE_NO_REPARENT,
+ RK2928_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS),
+
+ GATE(CORE_L2C, "core_l2c", "armclk", 0,
+ RK2928_CLKGATE_CON(9), 4, GFLAGS),
+
+ COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(2), 0, GFLAGS),
+
+ COMPOSITE(DCLK_LCDC0, "dclk_lcdc0", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(3), 1, GFLAGS),
+ COMPOSITE(DCLK_LCDC1, "dclk_lcdc1", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK2928_CLKGATE_CON(3), 2, GFLAGS),
+
+ COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0,
+ RK2928_CLKSEL_CON(34), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK2928_CLKGATE_CON(3), 15, GFLAGS),
+ GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_src", 0,
+ RK2928_CLKGATE_CON(9), 7, GFLAGS),
+
+ GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 4, GFLAGS),
+ GATE(SCLK_TIMER3, "timer3", "xin24m", 0, RK2928_CLKGATE_CON(1), 2, GFLAGS),
+ GATE(SCLK_TIMER4, "timer4", "xin24m", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
+ GATE(SCLK_TIMER5, "timer5", "xin24m", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
+ GATE(SCLK_TIMER6, "timer6", "xin24m", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
+
+ COMPOSITE_NODIV(0, "sclk_hsicphy_480m", mux_hsicphy_p, 0,
+ RK2928_CLKSEL_CON(30), 0, 2, DFLAGS,
+ RK2928_CLKGATE_CON(3), 6, GFLAGS),
+ DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0,
+ RK2928_CLKGATE_CON(11), 8, 6, DFLAGS),
+
+ MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0,
+ RK2928_CLKSEL_CON(2), 15, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 9, GFLAGS),
+ COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+ RK2928_CLKSEL_CON(7), 0,
+ RK2928_CLKGATE_CON(0), 10, GFLAGS),
+ MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
+ RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(13), 13, GFLAGS),
+ COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
+ RK2928_CLKSEL_CON(9), 0,
+ RK2928_CLKGATE_CON(0), 14, GFLAGS),
+ MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
+ RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
+
+ GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
+ GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
+
+ GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
+ GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
+
+ GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS),
+
+ GATE(PCLK_UART0, "pclk_uart0", "hclk_ahb2apb", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
+ GATE(PCLK_UART1, "pclk_uart1", "hclk_ahb2apb", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
+
+ GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
+};
+
+static void __init rk3188_common_clk_init(struct device_node *np)
+{
+ void __iomem *reg_base;
+ struct clk *clk;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru region\n", __func__);
+ return;
+ }
+
+ rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+
+ /* xin12m is created by an cru-internal divider */
+ clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
+ if (IS_ERR(clk))
+ pr_warn("%s: could not register clock xin12m: %ld\n",
+ __func__, PTR_ERR(clk));
+
+ clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
+ if (IS_ERR(clk))
+ pr_warn("%s: could not register clock usb480m: %ld\n",
+ __func__, PTR_ERR(clk));
+
+ rockchip_clk_register_plls(rk3188_pll_clks,
+ ARRAY_SIZE(rk3188_pll_clks),
+ RK3188_GRF_SOC_STATUS);
+ rockchip_clk_register_branches(common_clk_branches,
+ ARRAY_SIZE(common_clk_branches));
+
+ rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
+ ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
+
+static void __init rk3066a_clk_init(struct device_node *np)
+{
+ rk3188_common_clk_init(np);
+ rockchip_clk_register_branches(rk3066a_clk_branches,
+ ARRAY_SIZE(rk3066a_clk_branches));
+}
+CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
+
+static void __init rk3188a_clk_init(struct device_node *np)
+{
+ rk3188_common_clk_init(np);
+ rockchip_clk_register_branches(rk3188_clk_branches,
+ ARRAY_SIZE(rk3188_clk_branches));
+}
+CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
+
+static void __init rk3188_clk_init(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(rk3188_pll_clks); i++) {
+ struct rockchip_pll_clock *pll = &rk3188_pll_clks[i];
+ struct rockchip_pll_rate_table *rate;
+
+ if (!pll->rate_table)
+ continue;
+
+ rate = pll->rate_table;
+ while (rate->rate > 0) {
+ rate->bwadj = 0;
+ rate++;
+ }
+ }
+
+ rk3188a_clk_init(np);
+}
+CLK_OF_DECLARE(rk3188_cru, "rockchip,rk3188-cru", rk3188_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
new file mode 100644
index 000000000000..0d8c6c59a75e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include "clk.h"
+
+#define RK3288_GRF_SOC_CON(x) (0x244 + x * 4)
+#define RK3288_GRF_SOC_STATUS 0x280
+
+enum rk3288_plls {
+ apll, dpll, cpll, gpll, npll,
+};
+
+struct rockchip_pll_rate_table rk3288_pll_rates[] = {
+ RK3066_PLL_RATE(2208000000, 1, 92, 1),
+ RK3066_PLL_RATE(2184000000, 1, 91, 1),
+ RK3066_PLL_RATE(2160000000, 1, 90, 1),
+ RK3066_PLL_RATE(2136000000, 1, 89, 1),
+ RK3066_PLL_RATE(2112000000, 1, 88, 1),
+ RK3066_PLL_RATE(2088000000, 1, 87, 1),
+ RK3066_PLL_RATE(2064000000, 1, 86, 1),
+ RK3066_PLL_RATE(2040000000, 1, 85, 1),
+ RK3066_PLL_RATE(2016000000, 1, 84, 1),
+ RK3066_PLL_RATE(1992000000, 1, 83, 1),
+ RK3066_PLL_RATE(1968000000, 1, 82, 1),
+ RK3066_PLL_RATE(1944000000, 1, 81, 1),
+ RK3066_PLL_RATE(1920000000, 1, 80, 1),
+ RK3066_PLL_RATE(1896000000, 1, 79, 1),
+ RK3066_PLL_RATE(1872000000, 1, 78, 1),
+ RK3066_PLL_RATE(1848000000, 1, 77, 1),
+ RK3066_PLL_RATE(1824000000, 1, 76, 1),
+ RK3066_PLL_RATE(1800000000, 1, 75, 1),
+ RK3066_PLL_RATE(1776000000, 1, 74, 1),
+ RK3066_PLL_RATE(1752000000, 1, 73, 1),
+ RK3066_PLL_RATE(1728000000, 1, 72, 1),
+ RK3066_PLL_RATE(1704000000, 1, 71, 1),
+ RK3066_PLL_RATE(1680000000, 1, 70, 1),
+ RK3066_PLL_RATE(1656000000, 1, 69, 1),
+ RK3066_PLL_RATE(1632000000, 1, 68, 1),
+ RK3066_PLL_RATE(1608000000, 1, 67, 1),
+ RK3066_PLL_RATE(1560000000, 1, 65, 1),
+ RK3066_PLL_RATE(1512000000, 1, 63, 1),
+ RK3066_PLL_RATE(1488000000, 1, 62, 1),
+ RK3066_PLL_RATE(1464000000, 1, 61, 1),
+ RK3066_PLL_RATE(1440000000, 1, 60, 1),
+ RK3066_PLL_RATE(1416000000, 1, 59, 1),
+ RK3066_PLL_RATE(1392000000, 1, 58, 1),
+ RK3066_PLL_RATE(1368000000, 1, 57, 1),
+ RK3066_PLL_RATE(1344000000, 1, 56, 1),
+ RK3066_PLL_RATE(1320000000, 1, 55, 1),
+ RK3066_PLL_RATE(1296000000, 1, 54, 1),
+ RK3066_PLL_RATE(1272000000, 1, 53, 1),
+ RK3066_PLL_RATE(1248000000, 1, 52, 1),
+ RK3066_PLL_RATE(1224000000, 1, 51, 1),
+ RK3066_PLL_RATE(1200000000, 1, 50, 1),
+ RK3066_PLL_RATE(1188000000, 2, 99, 1),
+ RK3066_PLL_RATE(1176000000, 1, 49, 1),
+ RK3066_PLL_RATE(1128000000, 1, 47, 1),
+ RK3066_PLL_RATE(1104000000, 1, 46, 1),
+ RK3066_PLL_RATE(1008000000, 1, 84, 2),
+ RK3066_PLL_RATE( 912000000, 1, 76, 2),
+ RK3066_PLL_RATE( 891000000, 8, 594, 2),
+ RK3066_PLL_RATE( 888000000, 1, 74, 2),
+ RK3066_PLL_RATE( 816000000, 1, 68, 2),
+ RK3066_PLL_RATE( 798000000, 2, 133, 2),
+ RK3066_PLL_RATE( 792000000, 1, 66, 2),
+ RK3066_PLL_RATE( 768000000, 1, 64, 2),
+ RK3066_PLL_RATE( 742500000, 8, 495, 2),
+ RK3066_PLL_RATE( 696000000, 1, 58, 2),
+ RK3066_PLL_RATE( 600000000, 1, 50, 2),
+ RK3066_PLL_RATE( 594000000, 2, 198, 4),
+ RK3066_PLL_RATE( 552000000, 1, 46, 2),
+ RK3066_PLL_RATE( 504000000, 1, 84, 4),
+ RK3066_PLL_RATE( 456000000, 1, 76, 4),
+ RK3066_PLL_RATE( 408000000, 1, 68, 4),
+ RK3066_PLL_RATE( 384000000, 2, 128, 4),
+ RK3066_PLL_RATE( 360000000, 1, 60, 4),
+ RK3066_PLL_RATE( 312000000, 1, 52, 4),
+ RK3066_PLL_RATE( 300000000, 1, 50, 4),
+ RK3066_PLL_RATE( 297000000, 2, 198, 8),
+ RK3066_PLL_RATE( 252000000, 1, 84, 8),
+ RK3066_PLL_RATE( 216000000, 1, 72, 8),
+ RK3066_PLL_RATE( 148500000, 2, 99, 8),
+ RK3066_PLL_RATE( 126000000, 1, 84, 16),
+ RK3066_PLL_RATE( 48000000, 1, 64, 32),
+ { /* sentinel */ },
+};
+
+PNAME(mux_pll_p) = { "xin24m", "xin32k" };
+PNAME(mux_armclk_p) = { "apll_core", "gpll_core" };
+PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
+PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
+
+PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
+PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
+PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
+PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" };
+
+PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
+PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
+PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
+PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" };
+PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" };
+PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" };
+PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
+PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
+PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
+PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" };
+PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" };
+PNAME(mux_cif_out_p) = { "cif_src", "xin24m" };
+PNAME(mux_macref_p) = { "mac_src", "ext_gmac" };
+PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
+PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
+PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
+
+PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1",
+ "sclk_otgphy2" };
+PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
+PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" };
+
+static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = {
+ [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0),
+ RK3288_MODE_CON, 0, 6, rk3288_pll_rates),
+ [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4),
+ RK3288_MODE_CON, 4, 5, NULL),
+ [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8),
+ RK3288_MODE_CON, 8, 7, rk3288_pll_rates),
+ [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12),
+ RK3288_MODE_CON, 12, 8, rk3288_pll_rates),
+ [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16),
+ RK3288_MODE_CON, 14, 9, NULL),
+};
+
+static struct clk_div_table div_hclk_cpu_t[] = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 3, .div = 4 },
+ { /* sentinel */},
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
+ /*
+ * Clock-Architecture Diagram 1
+ */
+
+ GATE(0, "apll_core", "apll", 0,
+ RK3288_CLKGATE_CON(0), 1, GFLAGS),
+ GATE(0, "gpll_core", "gpll", 0,
+ RK3288_CLKGATE_CON(0), 2, GFLAGS),
+ COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0,
+ RK3288_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS),
+
+ COMPOSITE_NOMUX(0, "armcore0", "armclk", 0,
+ RK3288_CLKSEL_CON(36), 0, 3, DFLAGS,
+ RK3288_CLKGATE_CON(12), 0, GFLAGS),
+ COMPOSITE_NOMUX(0, "armcore1", "armclk", 0,
+ RK3288_CLKSEL_CON(36), 4, 3, DFLAGS,
+ RK3288_CLKGATE_CON(12), 1, GFLAGS),
+ COMPOSITE_NOMUX(0, "armcore2", "armclk", 0,
+ RK3288_CLKSEL_CON(36), 8, 3, DFLAGS,
+ RK3288_CLKGATE_CON(12), 2, GFLAGS),
+ COMPOSITE_NOMUX(0, "armcore3", "armclk", 0,
+ RK3288_CLKSEL_CON(36), 12, 3, DFLAGS,
+ RK3288_CLKGATE_CON(12), 3, GFLAGS),
+ COMPOSITE_NOMUX(0, "l2ram", "armclk", 0,
+ RK3288_CLKSEL_CON(37), 0, 3, DFLAGS,
+ RK3288_CLKGATE_CON(12), 4, GFLAGS),
+ COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0,
+ RK3288_CLKSEL_CON(0), 0, 4, DFLAGS,
+ RK3288_CLKGATE_CON(12), 5, GFLAGS),
+ COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0,
+ RK3288_CLKSEL_CON(0), 4, 4, DFLAGS,
+ RK3288_CLKGATE_CON(12), 6, GFLAGS),
+ COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
+ RK3288_CLKSEL_CON(37), 4, 5, DFLAGS,
+ RK3288_CLKGATE_CON(12), 7, GFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0,
+ RK3288_CLKSEL_CON(37), 9, 5, DFLAGS,
+ RK3288_CLKGATE_CON(12), 8, GFLAGS),
+ GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
+ RK3288_CLKGATE_CON(12), 9, GFLAGS),
+ GATE(0, "cs_dbg", "pclk_dbg_pre", 0,
+ RK3288_CLKGATE_CON(12), 10, GFLAGS),
+ GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0,
+ RK3288_CLKGATE_CON(12), 11, GFLAGS),
+
+ GATE(0, "dpll_ddr", "dpll", 0,
+ RK3288_CLKGATE_CON(0), 8, GFLAGS),
+ GATE(0, "gpll_ddr", "gpll", 0,
+ RK3288_CLKGATE_CON(0), 9, GFLAGS),
+ COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0,
+ RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2,
+ DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+
+ GATE(0, "gpll_aclk_cpu", "gpll", 0,
+ RK3288_CLKGATE_CON(0), 10, GFLAGS),
+ GATE(0, "cpll_aclk_cpu", "cpll", 0,
+ RK3288_CLKGATE_CON(0), 11, GFLAGS),
+ COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
+ RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS),
+ DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0,
+ RK3288_CLKSEL_CON(1), 0, 3, DFLAGS),
+ GATE(0, "aclk_cpu", "aclk_cpu_pre", 0,
+ RK3288_CLKGATE_CON(0), 3, GFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_cpu", "aclk_cpu_pre", 0,
+ RK3288_CLKSEL_CON(1), 12, 3, DFLAGS,
+ RK3288_CLKGATE_CON(0), 5, GFLAGS),
+ COMPOSITE_NOMUX_DIVTBL(0, "hclk_cpu", "aclk_cpu_pre", 0,
+ RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t,
+ RK3288_CLKGATE_CON(0), 4, GFLAGS),
+ GATE(0, "c2c_host", "aclk_cpu_src", 0,
+ RK3288_CLKGATE_CON(13), 8, GFLAGS),
+ COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0,
+ RK3288_CLKSEL_CON(26), 6, 2, DFLAGS,
+ RK3288_CLKGATE_CON(5), 4, GFLAGS),
+ GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0,
+ RK3288_CLKGATE_CON(0), 7, GFLAGS),
+
+ COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(4), 1, GFLAGS),
+ COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", 0,
+ RK3288_CLKSEL_CON(8), 0,
+ RK3288_CLKGATE_CON(4), 2, GFLAGS),
+ MUX(0, "i2s_pre", mux_i2s_pre_p, 0,
+ RK3288_CLKSEL_CON(4), 8, 2, MFLAGS),
+ COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, 0,
+ RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
+ RK3288_CLKGATE_CON(4), 0, GFLAGS),
+ GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", 0,
+ RK3288_CLKGATE_CON(4), 3, GFLAGS),
+
+ MUX(0, "spdif_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(5), 15, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", 0,
+ RK3288_CLKSEL_CON(5), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(4), 4, GFLAGS),
+ COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
+ RK3288_CLKSEL_CON(9), 0,
+ RK3288_CLKGATE_CON(4), 5, GFLAGS),
+ COMPOSITE_NODIV(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
+ RK3288_CLKSEL_CON(5), 8, 2, MFLAGS,
+ RK3288_CLKGATE_CON(4), 6, GFLAGS),
+ COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0,
+ RK3288_CLKSEL_CON(40), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(4), 7, GFLAGS),
+ COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0,
+ RK3288_CLKSEL_CON(41), 0,
+ RK3288_CLKGATE_CON(4), 8, GFLAGS),
+ COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0,
+ RK3288_CLKSEL_CON(40), 8, 2, MFLAGS,
+ RK3288_CLKGATE_CON(4), 9, GFLAGS),
+
+ GATE(0, "sclk_acc_efuse", "xin24m", 0,
+ RK3288_CLKGATE_CON(0), 12, GFLAGS),
+
+ GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 0, GFLAGS),
+ GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 1, GFLAGS),
+ GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 2, GFLAGS),
+ GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 3, GFLAGS),
+ GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 4, GFLAGS),
+ GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
+ RK3288_CLKGATE_CON(1), 5, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 2
+ */
+
+ COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(32), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 9, GFLAGS),
+ COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 11, GFLAGS),
+
+ COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 0, GFLAGS),
+ DIV(0, "hclk_vio", "aclk_vio0", 0,
+ RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
+ COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 2, GFLAGS),
+
+ COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(30), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 5, GFLAGS),
+ COMPOSITE(0, "sclk_rga", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(3), 4, GFLAGS),
+
+ COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS,
+ RK3288_CLKGATE_CON(3), 1, GFLAGS),
+ COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS,
+ RK3288_CLKGATE_CON(3), 3, GFLAGS),
+
+ COMPOSITE_NODIV(0, "sclk_edp_24m", mux_edp_24m_p, 0,
+ RK3288_CLKSEL_CON(28), 15, 1, MFLAGS,
+ RK3288_CLKGATE_CON(3), 12, GFLAGS),
+ COMPOSITE(0, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3288_CLKGATE_CON(3), 13, GFLAGS),
+
+ COMPOSITE(0, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3288_CLKGATE_CON(3), 14, GFLAGS),
+ COMPOSITE(0, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS,
+ RK3288_CLKGATE_CON(3), 15, GFLAGS),
+
+ GATE(0, "sclk_hdmi_hdcp", "xin24m", 0,
+ RK3288_CLKGATE_CON(5), 12, GFLAGS),
+ GATE(0, "sclk_hdmi_cec", "xin32k", 0,
+ RK3288_CLKGATE_CON(5), 11, GFLAGS),
+
+ COMPOSITE(0, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(39), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(13), 13, GFLAGS),
+ DIV(0, "hclk_hevc", "aclk_hevc", 0,
+ RK3288_CLKSEL_CON(40), 12, 2, DFLAGS),
+
+ COMPOSITE(0, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(13), 14, GFLAGS),
+ COMPOSITE(0, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(13), 15, GFLAGS),
+
+ COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(26), 8, 1, MFLAGS,
+ RK3288_CLKGATE_CON(3), 7, GFLAGS),
+ COMPOSITE_NOGATE(0, "sclk_vip_out", mux_cif_out_p, 0,
+ RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS),
+
+ DIV(0, "pclk_pd_alive", "gpll", 0,
+ RK3288_CLKSEL_CON(33), 8, 5, DFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0,
+ RK3288_CLKSEL_CON(33), 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(5), 8, GFLAGS),
+
+ COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
+ RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(5), 7, GFLAGS),
+
+ COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(2), 0, GFLAGS),
+ COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_src", 0,
+ RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK3288_CLKGATE_CON(2), 3, GFLAGS),
+ COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_src", 0,
+ RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+ RK3288_CLKGATE_CON(2), 2, GFLAGS),
+ GATE(0, "aclk_peri", "aclk_peri_src", 0,
+ RK3288_CLKGATE_CON(2), 1, GFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 3
+ */
+
+ COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(2), 9, GFLAGS),
+ COMPOSITE(SCLK_SPI1, "sclk_spi1", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(25), 15, 1, MFLAGS, 8, 7, DFLAGS,
+ RK3288_CLKGATE_CON(2), 10, GFLAGS),
+ COMPOSITE(SCLK_SPI2, "sclk_spi2", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(39), 7, 1, MFLAGS, 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(2), 11, GFLAGS),
+
+ COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0,
+ RK3288_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3288_CLKGATE_CON(13), 0, GFLAGS),
+ COMPOSITE(SCLK_SDIO0, "sclk_sdio0", mux_mmc_src_p, 0,
+ RK3288_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 6, DFLAGS,
+ RK3288_CLKGATE_CON(13), 1, GFLAGS),
+ COMPOSITE(SCLK_SDIO1, "sclk_sdio1", mux_mmc_src_p, 0,
+ RK3288_CLKSEL_CON(34), 14, 2, MFLAGS, 8, 6, DFLAGS,
+ RK3288_CLKGATE_CON(13), 2, GFLAGS),
+ COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
+ RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS,
+ RK3288_CLKGATE_CON(13), 3, GFLAGS),
+
+ COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0,
+ RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(4), 11, GFLAGS),
+ COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0,
+ RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(4), 10, GFLAGS),
+
+ GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0,
+ RK3288_CLKGATE_CON(13), 4, GFLAGS),
+ GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0,
+ RK3288_CLKGATE_CON(13), 5, GFLAGS),
+ GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0,
+ RK3288_CLKGATE_CON(13), 6, GFLAGS),
+ GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0,
+ RK3288_CLKGATE_CON(13), 7, GFLAGS),
+
+ COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0,
+ RK3288_CLKSEL_CON(2), 0, 6, DFLAGS,
+ RK3288_CLKGATE_CON(2), 7, GFLAGS),
+
+ COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0,
+ RK3288_CLKSEL_CON(24), 8, 8, DFLAGS,
+ RK3288_CLKGATE_CON(2), 8, GFLAGS),
+
+ GATE(SCLK_PS2C, "sclk_ps2c", "xin24m", 0,
+ RK3288_CLKGATE_CON(5), 13, GFLAGS),
+
+ COMPOSITE(SCLK_NANDC0, "sclk_nandc0", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(38), 7, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3288_CLKGATE_CON(5), 5, GFLAGS),
+ COMPOSITE(SCLK_NANDC1, "sclk_nandc1", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(5), 6, GFLAGS),
+
+ COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0,
+ RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(1), 8, GFLAGS),
+ COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
+ RK3288_CLKSEL_CON(17), 0,
+ RK3288_CLKGATE_CON(1), 9, GFLAGS),
+ MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, 0,
+ RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
+ MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
+ RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(1), 10, GFLAGS),
+ COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", 0,
+ RK3288_CLKSEL_CON(18), 0,
+ RK3288_CLKGATE_CON(1), 11, GFLAGS),
+ MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, 0,
+ RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
+ RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(1), 12, GFLAGS),
+ COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", 0,
+ RK3288_CLKSEL_CON(19), 0,
+ RK3288_CLKGATE_CON(1), 13, GFLAGS),
+ MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, 0,
+ RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
+ RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(1), 14, GFLAGS),
+ COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", 0,
+ RK3288_CLKSEL_CON(20), 0,
+ RK3288_CLKGATE_CON(1), 15, GFLAGS),
+ MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, 0,
+ RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
+ COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
+ RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
+ RK3288_CLKGATE_CON(2), 12, GFLAGS),
+ COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", 0,
+ RK3288_CLKSEL_CON(7), 0,
+ RK3288_CLKGATE_CON(2), 13, GFLAGS),
+ MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0,
+ RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
+
+ COMPOSITE(0, "mac_src", mux_pll_src_npll_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
+ RK3288_CLKGATE_CON(2), 5, GFLAGS),
+ MUX(0, "macref", mux_macref_p, 0,
+ RK3288_CLKSEL_CON(21), 4, 1, MFLAGS),
+ GATE(0, "sclk_macref_out", "macref", 0,
+ RK3288_CLKGATE_CON(5), 3, GFLAGS),
+ GATE(SCLK_MACREF, "sclk_macref", "macref", 0,
+ RK3288_CLKGATE_CON(5), 2, GFLAGS),
+ GATE(SCLK_MAC_RX, "sclk_mac_rx", "macref", 0,
+ RK3288_CLKGATE_CON(5), 0, GFLAGS),
+ GATE(SCLK_MAC_TX, "sclk_mac_tx", "macref", 0,
+ RK3288_CLKGATE_CON(5), 1, GFLAGS),
+
+ COMPOSITE(0, "hsadc_src", mux_pll_src_cpll_gpll_p, 0,
+ RK3288_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
+ RK3288_CLKGATE_CON(2), 6, GFLAGS),
+ MUX(SCLK_HSADC, "sclk_hsadc_out", mux_hsadcout_p, 0,
+ RK3288_CLKSEL_CON(22), 4, 1, MFLAGS),
+
+ GATE(0, "jtag", "ext_jtag", 0,
+ RK3288_CLKGATE_CON(4), 14, GFLAGS),
+
+ COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
+ RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
+ RK3288_CLKGATE_CON(5), 15, GFLAGS),
+ COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
+ RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
+ RK3288_CLKGATE_CON(3), 6, GFLAGS),
+ GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
+ RK3288_CLKGATE_CON(13), 9, GFLAGS),
+ DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0,
+ RK3288_CLKSEL_CON(11), 8, 6, DFLAGS),
+ MUX(SCLK_HSICPHY12M, "sclk_hsicphy12m", mux_hsicphy12m_p, 0,
+ RK3288_CLKSEL_CON(22), 4, 1, MFLAGS),
+
+ /*
+ * Clock-Architecture Diagram 4
+ */
+
+ /* aclk_cpu gates */
+ GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS),
+ GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS),
+ GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS),
+ GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS),
+ GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS),
+ GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS),
+ GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS),
+ GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS),
+
+ /* hclk_cpu gates */
+ GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS),
+ GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS),
+ GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS),
+ GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS),
+ GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS),
+
+ /* pclk_cpu gates */
+ GATE(PCLK_PWM, "pclk_pwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 0, GFLAGS),
+ GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS),
+ GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS),
+ GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS),
+ GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS),
+ GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS),
+ GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS),
+ GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS),
+ GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS),
+ GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
+ GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
+ GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
+ GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
+
+ /* ddrctrl [DDR Controller PHY clock] gates */
+ GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS),
+ GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS),
+
+ /* ddrphy gates */
+ GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS),
+ GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS),
+
+ /* aclk_peri gates */
+ GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS),
+ GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
+ GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS),
+ GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS),
+ GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
+ GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
+
+ /* hclk_peri gates */
+ GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS),
+ GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS),
+ GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS),
+ GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS),
+ GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS),
+ GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS),
+ GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS),
+ GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS),
+ GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS),
+ GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS),
+ GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS),
+ GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS),
+ GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 3, GFLAGS),
+ GATE(HCLK_SDIO0, "hclk_sdio0", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 4, GFLAGS),
+ GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 5, GFLAGS),
+ GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 6, GFLAGS),
+ GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 7, GFLAGS),
+ GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS),
+
+ /* pclk_peri gates */
+ GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS),
+ GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS),
+ GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS),
+ GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS),
+ GATE(PCLK_PS2C, "pclk_ps2c", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 7, GFLAGS),
+ GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 8, GFLAGS),
+ GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 9, GFLAGS),
+ GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 15, GFLAGS),
+ GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 11, GFLAGS),
+ GATE(PCLK_UART4, "pclk_uart4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 12, GFLAGS),
+ GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 13, GFLAGS),
+ GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 14, GFLAGS),
+ GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 1, GFLAGS),
+ GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 2, GFLAGS),
+ GATE(PCLK_SIM, "pclk_sim", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 3, GFLAGS),
+ GATE(PCLK_I2C5, "pclk_i2c5", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 0, GFLAGS),
+ GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK3288_CLKGATE_CON(8), 1, GFLAGS),
+
+ GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS),
+ GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
+ GATE(0, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
+ GATE(0, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
+ GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
+
+ /* sclk_gpu gates */
+ GATE(ACLK_GPU, "aclk_gpu", "sclk_gpu", 0, RK3288_CLKGATE_CON(18), 0, GFLAGS),
+
+ /* pclk_pd_alive gates */
+ GATE(PCLK_GPIO8, "pclk_gpio8", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 8, GFLAGS),
+ GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 7, GFLAGS),
+ GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 1, GFLAGS),
+ GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 2, GFLAGS),
+ GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 3, GFLAGS),
+ GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS),
+ GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
+ GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
+ GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS),
+ GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS),
+
+ /* pclk_pd_pmu gates */
+ GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS),
+ GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS),
+ GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS),
+ GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS),
+ GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
+
+ /* hclk_vio gates */
+ GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS),
+ GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
+ GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
+ GATE(0, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS),
+ GATE(0, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS),
+ GATE(0, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
+ GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
+ GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
+ GATE(0, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS),
+ GATE(0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS),
+ GATE(0, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS),
+ GATE(0, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS),
+ GATE(0, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS),
+ GATE(0, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS),
+ GATE(0, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS),
+ GATE(0, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS),
+
+ /* aclk_vio0 gates */
+ GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
+ GATE(0, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
+ GATE(0, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS),
+ GATE(0, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
+
+ /* aclk_vio1 gates */
+ GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
+ GATE(0, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
+ GATE(0, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS),
+
+ /* aclk_rga_pre gates */
+ GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
+ GATE(0, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS),
+
+ /*
+ * Other ungrouped clocks.
+ */
+
+ GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS),
+ GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS),
+};
+
+static void __init rk3288_clk_init(struct device_node *np)
+{
+ void __iomem *reg_base;
+ struct clk *clk;
+
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru region\n", __func__);
+ return;
+ }
+
+ rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+
+ /* xin12m is created by an cru-internal divider */
+ clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
+ if (IS_ERR(clk))
+ pr_warn("%s: could not register clock xin12m: %ld\n",
+ __func__, PTR_ERR(clk));
+
+
+ clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
+ if (IS_ERR(clk))
+ pr_warn("%s: could not register clock usb480m: %ld\n",
+ __func__, PTR_ERR(clk));
+
+ rockchip_clk_register_plls(rk3288_pll_clks,
+ ARRAY_SIZE(rk3288_pll_clks),
+ RK3288_GRF_SOC_STATUS);
+ rockchip_clk_register_branches(rk3288_clk_branches,
+ ARRAY_SIZE(rk3288_clk_branches));
+
+ rockchip_register_softrst(np, 9, reg_base + RK3288_SOFTRST_CON(0),
+ ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
+CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
new file mode 100644
index 000000000000..278cf9dd1e23
--- /dev/null
+++ b/drivers/clk/rockchip/clk.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on
+ *
+ * samsung/clk.c
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.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/slab.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include "clk.h"
+
+/**
+ * Register a clock branch.
+ * Most clock branches have a form like
+ *
+ * src1 --|--\
+ * |M |--[GATE]-[DIV]-
+ * src2 --|--/
+ *
+ * sometimes without one of those components.
+ */
+struct clk *rockchip_clk_register_branch(const char *name,
+ const char **parent_names, u8 num_parents, void __iomem *base,
+ int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
+ u8 div_shift, u8 div_width, u8 div_flags,
+ struct clk_div_table *div_table, int gate_offset,
+ u8 gate_shift, u8 gate_flags, unsigned long flags,
+ spinlock_t *lock)
+{
+ struct clk *clk;
+ struct clk_mux *mux = NULL;
+ struct clk_gate *gate = NULL;
+ struct clk_divider *div = NULL;
+ const struct clk_ops *mux_ops = NULL, *div_ops = NULL,
+ *gate_ops = NULL;
+
+ if (num_parents > 1) {
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->reg = base + muxdiv_offset;
+ mux->shift = mux_shift;
+ mux->mask = BIT(mux_width) - 1;
+ mux->flags = mux_flags;
+ mux->lock = lock;
+ mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
+ : &clk_mux_ops;
+ }
+
+ if (gate_offset >= 0) {
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->flags = gate_flags;
+ gate->reg = base + gate_offset;
+ gate->bit_idx = gate_shift;
+ gate->lock = lock;
+ gate_ops = &clk_gate_ops;
+ }
+
+ if (div_width > 0) {
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ div->flags = div_flags;
+ div->reg = base + muxdiv_offset;
+ div->shift = div_shift;
+ div->width = div_width;
+ div->lock = lock;
+ div->table = div_table;
+ div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+ ? &clk_divider_ro_ops
+ : &clk_divider_ops;
+ }
+
+ clk = clk_register_composite(NULL, name, parent_names, num_parents,
+ mux ? &mux->hw : NULL, mux_ops,
+ div ? &div->hw : NULL, div_ops,
+ gate ? &gate->hw : NULL, gate_ops,
+ flags);
+
+ return clk;
+}
+
+static DEFINE_SPINLOCK(clk_lock);
+static struct clk **clk_table;
+static void __iomem *reg_base;
+static struct clk_onecell_data clk_data;
+static struct device_node *cru_node;
+static struct regmap *grf;
+
+void __init rockchip_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks)
+{
+ reg_base = base;
+ cru_node = np;
+ grf = ERR_PTR(-EPROBE_DEFER);
+
+ clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+ if (!clk_table)
+ pr_err("%s: could not allocate clock lookup table\n", __func__);
+
+ clk_data.clks = clk_table;
+ clk_data.clk_num = nr_clks;
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+struct regmap *rockchip_clk_get_grf(void)
+{
+ if (IS_ERR(grf))
+ grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf");
+ return grf;
+}
+
+void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
+{
+ if (clk_table && id)
+ clk_table[id] = clk;
+}
+
+void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list,
+ unsigned int nr_pll, int grf_lock_offset)
+{
+ struct clk *clk;
+ int idx;
+
+ for (idx = 0; idx < nr_pll; idx++, list++) {
+ clk = rockchip_clk_register_pll(list->type, list->name,
+ list->parent_names, list->num_parents,
+ reg_base, list->con_offset, grf_lock_offset,
+ list->lock_shift, list->mode_offset,
+ list->mode_shift, list->rate_table, &clk_lock);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ list->name);
+ continue;
+ }
+
+ rockchip_clk_add_lookup(clk, list->id);
+ }
+}
+
+void __init rockchip_clk_register_branches(
+ struct rockchip_clk_branch *list,
+ unsigned int nr_clk)
+{
+ struct clk *clk = NULL;
+ unsigned int idx;
+ unsigned long flags;
+
+ for (idx = 0; idx < nr_clk; idx++, list++) {
+ flags = list->flags;
+
+ /* catch simple muxes */
+ switch (list->branch_type) {
+ case branch_mux:
+ clk = clk_register_mux(NULL, list->name,
+ list->parent_names, list->num_parents,
+ flags, reg_base + list->muxdiv_offset,
+ list->mux_shift, list->mux_width,
+ list->mux_flags, &clk_lock);
+ break;
+ case branch_divider:
+ if (list->div_table)
+ clk = clk_register_divider_table(NULL,
+ list->name, list->parent_names[0],
+ flags, reg_base + list->muxdiv_offset,
+ list->div_shift, list->div_width,
+ list->div_flags, list->div_table,
+ &clk_lock);
+ else
+ clk = clk_register_divider(NULL, list->name,
+ list->parent_names[0], flags,
+ reg_base + list->muxdiv_offset,
+ list->div_shift, list->div_width,
+ list->div_flags, &clk_lock);
+ break;
+ case branch_fraction_divider:
+ /* unimplemented */
+ continue;
+ break;
+ case branch_gate:
+ flags |= CLK_SET_RATE_PARENT;
+
+ /* keep all gates untouched for now */
+ flags |= CLK_IGNORE_UNUSED;
+
+ clk = clk_register_gate(NULL, list->name,
+ list->parent_names[0], flags,
+ reg_base + list->gate_offset,
+ list->gate_shift, list->gate_flags, &clk_lock);
+ break;
+ case branch_composite:
+ /* keep all gates untouched for now */
+ flags |= CLK_IGNORE_UNUSED;
+
+ clk = rockchip_clk_register_branch(list->name,
+ list->parent_names, list->num_parents,
+ reg_base, list->muxdiv_offset, list->mux_shift,
+ list->mux_width, list->mux_flags,
+ list->div_shift, list->div_width,
+ list->div_flags, list->div_table,
+ list->gate_offset, list->gate_shift,
+ list->gate_flags, flags, &clk_lock);
+ break;
+ }
+
+ /* none of the cases above matched */
+ if (!clk) {
+ pr_err("%s: unknown clock type %d\n",
+ __func__, list->branch_type);
+ continue;
+ }
+
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock %s: %ld\n",
+ __func__, list->name, PTR_ERR(clk));
+ continue;
+ }
+
+ rockchip_clk_add_lookup(clk, list->id);
+ }
+}
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
new file mode 100644
index 000000000000..887cbdeca2aa
--- /dev/null
+++ b/drivers/clk/rockchip/clk.h
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on
+ *
+ * samsung/clk.h
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.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.
+ */
+
+#ifndef CLK_ROCKCHIP_CLK_H
+#define CLK_ROCKCHIP_CLK_H
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#define HIWORD_UPDATE(val, mask, shift) \
+ ((val) << (shift) | (mask) << ((shift) + 16))
+
+/* register positions shared by RK2928, RK3066 and RK3188 */
+#define RK2928_PLL_CON(x) (x * 0x4)
+#define RK2928_MODE_CON 0x40
+#define RK2928_CLKSEL_CON(x) (x * 0x4 + 0x44)
+#define RK2928_CLKGATE_CON(x) (x * 0x4 + 0xd0)
+#define RK2928_GLB_SRST_FST 0x100
+#define RK2928_GLB_SRST_SND 0x104
+#define RK2928_SOFTRST_CON(x) (x * 0x4 + 0x110)
+#define RK2928_MISC_CON 0x134
+
+#define RK3288_PLL_CON(x) RK2928_PLL_CON(x)
+#define RK3288_MODE_CON 0x50
+#define RK3288_CLKSEL_CON(x) (x * 0x4 + 0x60)
+#define RK3288_CLKGATE_CON(x) (x * 0x4 + 0x160)
+#define RK3288_GLB_SRST_FST 0x1b0
+#define RK3288_GLB_SRST_SND 0x1b4
+#define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8)
+#define RK3288_MISC_CON 0x1e8
+
+enum rockchip_pll_type {
+ pll_rk3066,
+};
+
+#define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \
+{ \
+ .rate = _rate##U, \
+ .nr = _nr, \
+ .nf = _nf, \
+ .no = _no, \
+ .bwadj = (_nf >> 1), \
+}
+
+struct rockchip_pll_rate_table {
+ unsigned long rate;
+ unsigned int nr;
+ unsigned int nf;
+ unsigned int no;
+ unsigned int bwadj;
+};
+
+/**
+ * struct rockchip_pll_clock: information about pll clock
+ * @id: platform specific id of the clock.
+ * @name: name of this pll clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @con_offset: offset of the register for configuring the PLL.
+ * @mode_offset: offset of the register for configuring the PLL-mode.
+ * @mode_shift: offset inside the mode-register for the mode of this pll.
+ * @lock_shift: offset inside the lock register for the lock status.
+ * @type: Type of PLL to be registered.
+ * @rate_table: Table of usable pll rates
+ */
+struct rockchip_pll_clock {
+ unsigned int id;
+ const char *name;
+ const char **parent_names;
+ u8 num_parents;
+ unsigned long flags;
+ int con_offset;
+ int mode_offset;
+ int mode_shift;
+ int lock_shift;
+ enum rockchip_pll_type type;
+ struct rockchip_pll_rate_table *rate_table;
+};
+
+#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \
+ _lshift, _rtable) \
+ { \
+ .id = _id, \
+ .type = _type, \
+ .name = _name, \
+ .parent_names = _pnames, \
+ .num_parents = ARRAY_SIZE(_pnames), \
+ .flags = CLK_GET_RATE_NOCACHE | _flags, \
+ .con_offset = _con, \
+ .mode_offset = _mode, \
+ .mode_shift = _mshift, \
+ .lock_shift = _lshift, \
+ .rate_table = _rtable, \
+ }
+
+struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
+ const char *name, const char **parent_names, u8 num_parents,
+ void __iomem *base, int con_offset, int grf_lock_offset,
+ int lock_shift, int reg_mode, int mode_shift,
+ struct rockchip_pll_rate_table *rate_table,
+ spinlock_t *lock);
+
+#define PNAME(x) static const char *x[] __initconst
+
+enum rockchip_clk_branch_type {
+ branch_composite,
+ branch_mux,
+ branch_divider,
+ branch_fraction_divider,
+ branch_gate,
+};
+
+struct rockchip_clk_branch {
+ unsigned int id;
+ enum rockchip_clk_branch_type branch_type;
+ const char *name;
+ const char **parent_names;
+ u8 num_parents;
+ unsigned long flags;
+ int muxdiv_offset;
+ u8 mux_shift;
+ u8 mux_width;
+ u8 mux_flags;
+ u8 div_shift;
+ u8 div_width;
+ u8 div_flags;
+ struct clk_div_table *div_table;
+ int gate_offset;
+ u8 gate_shift;
+ u8 gate_flags;
+};
+
+#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
+ df, go, gs, gf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_composite, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .mux_shift = ms, \
+ .mux_width = mw, \
+ .mux_flags = mf, \
+ .div_shift = ds, \
+ .div_width = dw, \
+ .div_flags = df, \
+ .gate_offset = go, \
+ .gate_shift = gs, \
+ .gate_flags = gf, \
+ }
+
+#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \
+ go, gs, gf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_composite, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .div_shift = ds, \
+ .div_width = dw, \
+ .div_flags = df, \
+ .gate_offset = go, \
+ .gate_shift = gs, \
+ .gate_flags = gf, \
+ }
+
+#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
+ df, dt, go, gs, gf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_composite, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .div_shift = ds, \
+ .div_width = dw, \
+ .div_flags = df, \
+ .div_table = dt, \
+ .gate_offset = go, \
+ .gate_shift = gs, \
+ .gate_flags = gf, \
+ }
+
+#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \
+ go, gs, gf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_composite, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .mux_shift = ms, \
+ .mux_width = mw, \
+ .mux_flags = mf, \
+ .gate_offset = go, \
+ .gate_shift = gs, \
+ .gate_flags = gf, \
+ }
+
+#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
+ ds, dw, df) \
+ { \
+ .id = _id, \
+ .branch_type = branch_composite, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .mux_shift = ms, \
+ .mux_width = mw, \
+ .mux_flags = mf, \
+ .div_shift = ds, \
+ .div_width = dw, \
+ .div_flags = df, \
+ .gate_offset = -1, \
+ }
+
+#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
+ { \
+ .id = _id, \
+ .branch_type = branch_fraction_divider, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .muxdiv_offset = mo, \
+ .div_shift = 16, \
+ .div_width = 16, \
+ .div_flags = df, \
+ .gate_offset = go, \
+ .gate_shift = gs, \
+ .gate_flags = gf, \
+ }
+
+#define MUX(_id, cname, pnames, f, o, s, w, mf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_mux, \
+ .name = cname, \
+ .parent_names = pnames, \
+ .num_parents = ARRAY_SIZE(pnames), \
+ .flags = f, \
+ .muxdiv_offset = o, \
+ .mux_shift = s, \
+ .mux_width = w, \
+ .mux_flags = mf, \
+ .gate_offset = -1, \
+ }
+
+#define DIV(_id, cname, pname, f, o, s, w, df) \
+ { \
+ .id = _id, \
+ .branch_type = branch_divider, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .muxdiv_offset = o, \
+ .div_shift = s, \
+ .div_width = w, \
+ .div_flags = df, \
+ .gate_offset = -1, \
+ }
+
+#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \
+ { \
+ .id = _id, \
+ .branch_type = branch_divider, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .muxdiv_offset = o, \
+ .div_shift = s, \
+ .div_width = w, \
+ .div_flags = df, \
+ .div_table = dt, \
+ }
+
+#define GATE(_id, cname, pname, f, o, b, gf) \
+ { \
+ .id = _id, \
+ .branch_type = branch_gate, \
+ .name = cname, \
+ .parent_names = (const char *[]){ pname }, \
+ .num_parents = 1, \
+ .flags = f, \
+ .gate_offset = o, \
+ .gate_shift = b, \
+ .gate_flags = gf, \
+ }
+
+
+void rockchip_clk_init(struct device_node *np, void __iomem *base,
+ unsigned long nr_clks);
+struct regmap *rockchip_clk_get_grf(void);
+void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
+void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
+ unsigned int nr_clk);
+void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list,
+ unsigned int nr_pll, int grf_lock_offset);
+
+#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
+
+#ifdef CONFIG_RESET_CONTROLLER
+void rockchip_register_softrst(struct device_node *np,
+ unsigned int num_regs,
+ void __iomem *base, u8 flags);
+#else
+static inline void rockchip_register_softrst(struct device_node *np,
+ unsigned int num_regs,
+ void __iomem *base, u8 flags)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c
new file mode 100644
index 000000000000..552f7bb15bc5
--- /dev/null
+++ b/drivers/clk/rockchip/softrst.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.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.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_softrst {
+ struct reset_controller_dev rcdev;
+ void __iomem *reg_base;
+ int num_regs;
+ int num_per_reg;
+ u8 flags;
+ spinlock_t lock;
+};
+
+static int rockchip_softrst_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rockchip_softrst *softrst = container_of(rcdev,
+ struct rockchip_softrst,
+ rcdev);
+ int bank = id / softrst->num_per_reg;
+ int offset = id % softrst->num_per_reg;
+
+ if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+ writel(BIT(offset) | (BIT(offset) << 16),
+ softrst->reg_base + (bank * 4));
+ } else {
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&softrst->lock, flags);
+
+ reg = readl(softrst->reg_base + (bank * 4));
+ writel(reg | BIT(offset), softrst->reg_base + (bank * 4));
+
+ spin_unlock_irqrestore(&softrst->lock, flags);
+ }
+
+ return 0;
+}
+
+static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct rockchip_softrst *softrst = container_of(rcdev,
+ struct rockchip_softrst,
+ rcdev);
+ int bank = id / softrst->num_per_reg;
+ int offset = id % softrst->num_per_reg;
+
+ if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+ writel((BIT(offset) << 16), softrst->reg_base + (bank * 4));
+ } else {
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&softrst->lock, flags);
+
+ reg = readl(softrst->reg_base + (bank * 4));
+ writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4));
+
+ spin_unlock_irqrestore(&softrst->lock, flags);
+ }
+
+ return 0;
+}
+
+static struct reset_control_ops rockchip_softrst_ops = {
+ .assert = rockchip_softrst_assert,
+ .deassert = rockchip_softrst_deassert,
+};
+
+void __init rockchip_register_softrst(struct device_node *np,
+ unsigned int num_regs,
+ void __iomem *base, u8 flags)
+{
+ struct rockchip_softrst *softrst;
+ int ret;
+
+ softrst = kzalloc(sizeof(*softrst), GFP_KERNEL);
+ if (!softrst)
+ return;
+
+ spin_lock_init(&softrst->lock);
+
+ softrst->reg_base = base;
+ softrst->flags = flags;
+ softrst->num_regs = num_regs;
+ softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16
+ : 32;
+
+ softrst->rcdev.owner = THIS_MODULE;
+ softrst->rcdev.nr_resets = num_regs * softrst->num_per_reg;
+ softrst->rcdev.ops = &rockchip_softrst_ops;
+ softrst->rcdev.of_node = np;
+ ret = reset_controller_register(&softrst->rcdev);
+ if (ret) {
+ pr_err("%s: could not register reset controller, %d\n",
+ __func__, ret);
+ kfree(softrst);
+ }
+};
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 69e81773164e..6fb4bc602e8a 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -11,8 +11,10 @@ obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
+obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
+obj-$(CONFIG_ARCH_S5PV210) += clk-s5pv210.o clk-s5pv210-audss.o
diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c
new file mode 100644
index 000000000000..3a7cb2506731
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos-clkout.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Figa <t.figa@samsung.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.
+ *
+ * Clock driver for Exynos clock output
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#define EXYNOS_CLKOUT_NR_CLKS 1
+#define EXYNOS_CLKOUT_PARENTS 32
+
+#define EXYNOS_PMU_DEBUG_REG 0xa00
+#define EXYNOS_CLKOUT_DISABLE_SHIFT 0
+#define EXYNOS_CLKOUT_MUX_SHIFT 8
+#define EXYNOS4_CLKOUT_MUX_MASK 0xf
+#define EXYNOS5_CLKOUT_MUX_MASK 0x1f
+
+struct exynos_clkout {
+ struct clk_gate gate;
+ struct clk_mux mux;
+ spinlock_t slock;
+ struct clk_onecell_data data;
+ struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS];
+ void __iomem *reg;
+ u32 pmu_debug_save;
+};
+
+static struct exynos_clkout *clkout;
+
+static int exynos_clkout_suspend(void)
+{
+ clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG);
+
+ return 0;
+}
+
+static void exynos_clkout_resume(void)
+{
+ writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG);
+}
+
+static struct syscore_ops exynos_clkout_syscore_ops = {
+ .suspend = exynos_clkout_suspend,
+ .resume = exynos_clkout_resume,
+};
+
+static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
+{
+ const char *parent_names[EXYNOS_CLKOUT_PARENTS];
+ struct clk *parents[EXYNOS_CLKOUT_PARENTS];
+ int parent_count;
+ int ret;
+ int i;
+
+ clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+ if (!clkout)
+ return;
+
+ spin_lock_init(&clkout->slock);
+
+ parent_count = 0;
+ for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i) {
+ char name[] = "clkoutXX";
+
+ snprintf(name, sizeof(name), "clkout%d", i);
+ parents[i] = of_clk_get_by_name(node, name);
+ if (IS_ERR(parents[i])) {
+ parent_names[i] = "none";
+ continue;
+ }
+
+ parent_names[i] = __clk_get_name(parents[i]);
+ parent_count = i + 1;
+ }
+
+ if (!parent_count)
+ goto free_clkout;
+
+ clkout->reg = of_iomap(node, 0);
+ if (!clkout->reg)
+ goto clks_put;
+
+ clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+ clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT;
+ clkout->gate.flags = CLK_GATE_SET_TO_DISABLE;
+ clkout->gate.lock = &clkout->slock;
+
+ clkout->mux.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+ clkout->mux.mask = mux_mask;
+ clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
+ clkout->mux.lock = &clkout->slock;
+
+ clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
+ parent_names, parent_count, &clkout->mux.hw,
+ &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
+ &clk_gate_ops, CLK_SET_RATE_PARENT
+ | CLK_SET_RATE_NO_REPARENT);
+ if (IS_ERR(clkout->clk_table[0]))
+ goto err_unmap;
+
+ clkout->data.clks = clkout->clk_table;
+ clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS;
+ ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data);
+ if (ret)
+ goto err_clk_unreg;
+
+ register_syscore_ops(&exynos_clkout_syscore_ops);
+
+ return;
+
+err_clk_unreg:
+ clk_unregister(clkout->clk_table[0]);
+err_unmap:
+ iounmap(clkout->reg);
+clks_put:
+ for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i)
+ if (!IS_ERR(parents[i]))
+ clk_put(parents[i]);
+free_clkout:
+ kfree(clkout);
+
+ pr_err("%s: failed to register clkout clock\n", __func__);
+}
+
+static void __init exynos4_clkout_init(struct device_node *node)
+{
+ exynos_clkout_init(node, EXYNOS4_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos4210_clkout, "samsung,exynos4210-pmu",
+ exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4212_clkout, "samsung,exynos4212-pmu",
+ exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4412_clkout, "samsung,exynos4412-pmu",
+ exynos4_clkout_init);
+
+static void __init exynos5_clkout_init(struct device_node *node)
+{
+ exynos_clkout_init(node, EXYNOS5_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu",
+ exynos5_clkout_init);
+CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu",
+ exynos5_clkout_init);
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 7a17bd40d1dd..dc85f8e7a2d7 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -87,6 +87,22 @@
#define SRC_CPU 0x14200
#define DIV_CPU0 0x14500
#define DIV_CPU1 0x14504
+#define PWR_CTRL1 0x15020
+#define PWR_CTRL2 0x15024
+
+/* Below definitions are used for PWR_CTRL settings */
+#define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28)
+#define PWR_CTRL1_CORE1_DOWN_RATIO(x) (((x) & 0x7) << 16)
+#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9)
+#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8)
+#define PWR_CTRL1_USE_CORE3_WFE (1 << 7)
+#define PWR_CTRL1_USE_CORE2_WFE (1 << 6)
+#define PWR_CTRL1_USE_CORE1_WFE (1 << 5)
+#define PWR_CTRL1_USE_CORE0_WFE (1 << 4)
+#define PWR_CTRL1_USE_CORE3_WFI (1 << 3)
+#define PWR_CTRL1_USE_CORE2_WFI (1 << 2)
+#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
+#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
/* list of PLLs to be registered */
enum exynos3250_plls {
@@ -168,6 +184,8 @@ static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
SRC_CPU,
DIV_CPU0,
DIV_CPU1,
+ PWR_CTRL1,
+ PWR_CTRL2,
};
static int exynos3250_clk_suspend(void)
@@ -748,6 +766,27 @@ static struct samsung_pll_clock exynos3250_plls[nr_plls] __initdata = {
UPLL_LOCK, UPLL_CON0, NULL),
};
+static void __init exynos3_core_down_clock(void)
+{
+ unsigned int tmp;
+
+ /*
+ * Enable arm clock down (in idle) and set arm divider
+ * ratios in WFI/WFE state.
+ */
+ tmp = (PWR_CTRL1_CORE2_DOWN_RATIO(7) | PWR_CTRL1_CORE1_DOWN_RATIO(7) |
+ PWR_CTRL1_DIV2_DOWN_EN | PWR_CTRL1_DIV1_DOWN_EN |
+ PWR_CTRL1_USE_CORE1_WFE | PWR_CTRL1_USE_CORE0_WFE |
+ PWR_CTRL1_USE_CORE1_WFI | PWR_CTRL1_USE_CORE0_WFI);
+ __raw_writel(tmp, reg_base + PWR_CTRL1);
+
+ /*
+ * Disable the clock up feature on Exynos4x12, in case it was
+ * enabled by bootloader.
+ */
+ __raw_writel(0x0, reg_base + PWR_CTRL2);
+}
+
static void __init exynos3250_cmu_init(struct device_node *np)
{
struct samsung_clk_provider *ctx;
@@ -775,6 +814,10 @@ static void __init exynos3250_cmu_init(struct device_node *np)
samsung_clk_register_div(ctx, div_clks, ARRAY_SIZE(div_clks));
samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks));
+ exynos3_core_down_clock();
+
exynos3250_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4f150c9dd38c..ac163d7f5bc3 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -25,10 +25,12 @@
#define DIV_LEFTBUS 0x4500
#define GATE_IP_LEFTBUS 0x4800
#define E4X12_GATE_IP_IMAGE 0x4930
+#define CLKOUT_CMU_LEFTBUS 0x4a00
#define SRC_RIGHTBUS 0x8200
#define DIV_RIGHTBUS 0x8500
#define GATE_IP_RIGHTBUS 0x8800
#define E4X12_GATE_IP_PERIR 0x8960
+#define CLKOUT_CMU_RIGHTBUS 0x8a00
#define EPLL_LOCK 0xc010
#define VPLL_LOCK 0xc020
#define EPLL_CON0 0xc110
@@ -98,6 +100,7 @@
#define GATE_IP_PERIL 0xc950
#define E4210_GATE_IP_PERIR 0xc960
#define GATE_BLOCK 0xc970
+#define CLKOUT_CMU_TOP 0xca00
#define E4X12_MPLL_LOCK 0x10008
#define E4X12_MPLL_CON0 0x10108
#define SRC_DMC 0x10200
@@ -105,6 +108,7 @@
#define DIV_DMC0 0x10500
#define DIV_DMC1 0x10504
#define GATE_IP_DMC 0x10900
+#define CLKOUT_CMU_DMC 0x10a00
#define APLL_LOCK 0x14000
#define E4210_MPLL_LOCK 0x14008
#define APLL_CON0 0x14100
@@ -114,11 +118,28 @@
#define DIV_CPU1 0x14504
#define GATE_SCLK_CPU 0x14800
#define GATE_IP_CPU 0x14900
+#define CLKOUT_CMU_CPU 0x14a00
+#define PWR_CTRL1 0x15020
+#define E4X12_PWR_CTRL2 0x15024
#define E4X12_DIV_ISP0 0x18300
#define E4X12_DIV_ISP1 0x18304
#define E4X12_GATE_ISP0 0x18800
#define E4X12_GATE_ISP1 0x18804
+/* Below definitions are used for PWR_CTRL settings */
+#define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28)
+#define PWR_CTRL1_CORE1_DOWN_RATIO(x) (((x) & 0x7) << 16)
+#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9)
+#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8)
+#define PWR_CTRL1_USE_CORE3_WFE (1 << 7)
+#define PWR_CTRL1_USE_CORE2_WFE (1 << 6)
+#define PWR_CTRL1_USE_CORE1_WFE (1 << 5)
+#define PWR_CTRL1_USE_CORE0_WFE (1 << 4)
+#define PWR_CTRL1_USE_CORE3_WFI (1 << 3)
+#define PWR_CTRL1_USE_CORE2_WFI (1 << 2)
+#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
+#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
+
/* the exynos4 soc type */
enum exynos4_soc {
EXYNOS4210,
@@ -155,6 +176,7 @@ static unsigned long exynos4210_clk_save[] __initdata = {
E4210_GATE_IP_LCD1,
E4210_GATE_IP_PERIR,
E4210_MPLL_CON0,
+ PWR_CTRL1,
};
static unsigned long exynos4x12_clk_save[] __initdata = {
@@ -164,6 +186,8 @@ static unsigned long exynos4x12_clk_save[] __initdata = {
E4X12_DIV_ISP,
E4X12_DIV_CAM1,
E4X12_MPLL_CON0,
+ PWR_CTRL1,
+ E4X12_PWR_CTRL2,
};
static unsigned long exynos4_clk_pll_regs[] __initdata = {
@@ -242,6 +266,11 @@ static unsigned long exynos4_clk_regs[] __initdata = {
DIV_CPU1,
GATE_SCLK_CPU,
GATE_IP_CPU,
+ CLKOUT_CMU_LEFTBUS,
+ CLKOUT_CMU_RIGHTBUS,
+ CLKOUT_CMU_TOP,
+ CLKOUT_CMU_DMC,
+ CLKOUT_CMU_CPU,
};
static const struct samsung_clk_reg_dump src_mask_suspend[] = {
@@ -397,10 +426,32 @@ PNAME(mout_audio2_p4210) = { "cdclk2", "none", "sclk_hdmi24m",
"sclk_epll", "sclk_vpll", };
PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
+PNAME(mout_pwi_p4210) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "sclk_usbphy1", "sclk_hdmiphy", "none",
+ "sclk_epll", "sclk_vpll" };
+PNAME(clkout_left_p4210) = { "sclk_mpll_div_2", "sclk_apll_div_2",
+ "div_gdl", "div_gpl" };
+PNAME(clkout_right_p4210) = { "sclk_mpll_div_2", "sclk_apll_div_2",
+ "div_gdr", "div_gpr" };
+PNAME(clkout_top_p4210) = { "fout_epll", "fout_vpll", "sclk_hdmi24m",
+ "sclk_usbphy0", "sclk_usbphy1", "sclk_hdmiphy",
+ "cdclk0", "cdclk1", "cdclk2", "spdif_extclk",
+ "aclk160", "aclk133", "aclk200", "aclk100",
+ "sclk_mfc", "sclk_g3d", "sclk_g2d",
+ "cam_a_pclk", "cam_b_pclk", "s_rxbyteclkhs0_2l",
+ "s_rxbyteclkhs0_4l" };
+PNAME(clkout_dmc_p4210) = { "div_dmcd", "div_dmcp", "div_acp_pclk", "div_dmc",
+ "div_dphy", "none", "div_pwi" };
+PNAME(clkout_cpu_p4210) = { "fout_apll_div_2", "none", "fout_mpll_div_2",
+ "none", "arm_clk_div_2", "div_corem0",
+ "div_corem1", "div_corem0", "div_atb",
+ "div_periph", "div_pclk_dbg", "div_hpm" };
/* Exynos 4x12-specific parent groups */
PNAME(mout_mpll_user_p4x12) = { "fin_pll", "sclk_mpll", };
PNAME(mout_core_p4x12) = { "mout_apll", "mout_mpll_user_c", };
+PNAME(mout_gdl_p4x12) = { "mout_mpll_user_l", "sclk_apll", };
+PNAME(mout_gdr_p4x12) = { "mout_mpll_user_r", "sclk_apll", };
PNAME(sclk_ampll_p4x12) = { "mout_mpll_user_t", "sclk_apll", };
PNAME(group1_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
"none", "sclk_hdmiphy", "mout_mpll_user_t",
@@ -418,6 +469,32 @@ PNAME(aclk_p4412) = { "mout_mpll_user_t", "sclk_apll", };
PNAME(mout_user_aclk400_mcuisp_p4x12) = {"fin_pll", "div_aclk400_mcuisp", };
PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", };
PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
+PNAME(mout_pwi_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "none", "sclk_hdmiphy", "sclk_mpll",
+ "sclk_epll", "sclk_vpll" };
+PNAME(clkout_left_p4x12) = { "sclk_mpll_user_l_div_2", "sclk_apll_div_2",
+ "div_gdl", "div_gpl" };
+PNAME(clkout_right_p4x12) = { "sclk_mpll_user_r_div_2", "sclk_apll_div_2",
+ "div_gdr", "div_gpr" };
+PNAME(clkout_top_p4x12) = { "fout_epll", "fout_vpll", "sclk_hdmi24m",
+ "sclk_usbphy0", "none", "sclk_hdmiphy",
+ "cdclk0", "cdclk1", "cdclk2", "spdif_extclk",
+ "aclk160", "aclk133", "aclk200", "aclk100",
+ "sclk_mfc", "sclk_g3d", "aclk400_mcuisp",
+ "cam_a_pclk", "cam_b_pclk", "s_rxbyteclkhs0_2l",
+ "s_rxbyteclkhs0_4l", "rx_half_byte_clk_csis0",
+ "rx_half_byte_clk_csis1", "div_jpeg",
+ "sclk_pwm_isp", "sclk_spi0_isp",
+ "sclk_spi1_isp", "sclk_uart_isp",
+ "sclk_mipihsi", "sclk_hdmi", "sclk_fimd0",
+ "sclk_pcm0" };
+PNAME(clkout_dmc_p4x12) = { "div_dmcd", "div_dmcp", "aclk_acp", "div_acp_pclk",
+ "div_dmc", "div_dphy", "fout_mpll_div_2",
+ "div_pwi", "none", "div_c2c", "div_c2c_aclk" };
+PNAME(clkout_cpu_p4x12) = { "fout_apll_div_2", "none", "none", "none",
+ "arm_clk_div_2", "div_corem0", "div_corem1",
+ "div_cores", "div_atb", "div_periph",
+ "div_pclk_dbg", "div_hpm" };
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
@@ -436,6 +513,24 @@ static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata =
FRATE(0, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
};
+static struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_apll_div_2", "sclk_apll", 1, 2, 0),
+ FFACTOR(0, "fout_mpll_div_2", "fout_mpll", 1, 2, 0),
+ FFACTOR(0, "fout_apll_div_2", "fout_apll", 1, 2, 0),
+ FFACTOR(0, "arm_clk_div_2", "arm_clk", 1, 2, 0),
+};
+
+static struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_mpll_div_2", "sclk_mpll", 1, 2, 0),
+};
+
+static struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_mpll_user_l_div_2", "mout_mpll_user_l", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_r_div_2", "mout_mpll_user_r", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_t_div_2", "mout_mpll_user_t", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_c_div_2", "mout_mpll_user_c", 1, 2, 0),
+};
+
/* list of mux clocks supported in all exynos4 soc's */
static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
@@ -451,6 +546,9 @@ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
MUX(0, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1),
MUX(CLK_SCLK_EPLL, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1),
MUX(0, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1),
+
+ MUX(0, "mout_dmc_bus", sclk_ampll_p4210, SRC_DMC, 4, 1),
+ MUX(0, "mout_dphy", sclk_ampll_p4210, SRC_DMC, 8, 1),
};
/* list of mux clocks supported in exynos4210 soc */
@@ -459,6 +557,14 @@ static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
};
static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
+ MUX(0, "mout_gdl", sclk_ampll_p4210, SRC_LEFTBUS, 0, 1),
+ MUX(0, "mout_clkout_leftbus", clkout_left_p4210,
+ CLKOUT_CMU_LEFTBUS, 0, 5),
+
+ MUX(0, "mout_gdr", sclk_ampll_p4210, SRC_RIGHTBUS, 0, 1),
+ MUX(0, "mout_clkout_rightbus", clkout_right_p4210,
+ CLKOUT_CMU_RIGHTBUS, 0, 5),
+
MUX(0, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
MUX(0, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
MUX(0, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1),
@@ -472,6 +578,7 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1),
MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4210, SRC_CPU, 16, 1),
+ MUX(0, "mout_hpm", mout_core_p4210, SRC_CPU, 20, 1),
MUX(CLK_SCLK_VPLL, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1),
MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
@@ -503,12 +610,30 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4),
MUX(0, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4),
MUX(0, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4),
+ MUX(0, "mout_clkout_top", clkout_top_p4210, CLKOUT_CMU_TOP, 0, 5),
+
+ MUX(0, "mout_pwi", mout_pwi_p4210, SRC_DMC, 16, 4),
+ MUX(0, "mout_clkout_dmc", clkout_dmc_p4210, CLKOUT_CMU_DMC, 0, 5),
+
+ MUX(0, "mout_clkout_cpu", clkout_cpu_p4210, CLKOUT_CMU_CPU, 0, 5),
};
/* list of mux clocks supported in exynos4x12 soc */
static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
+ MUX(0, "mout_mpll_user_l", mout_mpll_p, SRC_LEFTBUS, 4, 1),
+ MUX(0, "mout_gdl", mout_gdl_p4x12, SRC_LEFTBUS, 0, 1),
+ MUX(0, "mout_clkout_leftbus", clkout_left_p4x12,
+ CLKOUT_CMU_LEFTBUS, 0, 5),
+
+ MUX(0, "mout_mpll_user_r", mout_mpll_p, SRC_RIGHTBUS, 4, 1),
+ MUX(0, "mout_gdr", mout_gdr_p4x12, SRC_RIGHTBUS, 0, 1),
+ MUX(0, "mout_clkout_rightbus", clkout_right_p4x12,
+ CLKOUT_CMU_RIGHTBUS, 0, 5),
+
MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p4x12,
SRC_CPU, 24, 1),
+ MUX(0, "mout_clkout_cpu", clkout_cpu_p4x12, CLKOUT_CMU_CPU, 0, 5),
+
MUX(0, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
MUX(0, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p4x12,
@@ -531,6 +656,7 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1),
MUX(CLK_SCLK_VPLL, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1),
MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
+ MUX(0, "mout_hpm", mout_core_p4x12, SRC_CPU, 20, 1),
MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
MUX(CLK_MOUT_FIMC2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
@@ -565,15 +691,39 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(0, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
MUX(0, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
MUX(0, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
+ MUX(0, "mout_clkout_top", clkout_top_p4x12, CLKOUT_CMU_TOP, 0, 5),
+
+ MUX(0, "mout_c2c", sclk_ampll_p4210, SRC_DMC, 0, 1),
+ MUX(0, "mout_pwi", mout_pwi_p4x12, SRC_DMC, 16, 4),
MUX(0, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1),
MUX(0, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1),
MUX(0, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1),
+ MUX(0, "mout_clkout_dmc", clkout_dmc_p4x12, CLKOUT_CMU_DMC, 0, 5),
};
/* list of divider clocks supported in all exynos4 soc's */
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
+ DIV(0, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
+ DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
+ DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
+ CLKOUT_CMU_LEFTBUS, 8, 6),
+
+ DIV(0, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
+ DIV(0, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
+ DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
+ CLKOUT_CMU_RIGHTBUS, 8, 6),
+
DIV(0, "div_core", "mout_core", DIV_CPU0, 0, 3),
+ DIV(0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
+ DIV(0, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
+ DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3),
+ DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3),
+ DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3),
DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
+ DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
+ DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
+ DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6),
+
DIV(0, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
DIV(0, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4),
DIV(0, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4),
@@ -631,6 +781,16 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
CLK_SET_RATE_PARENT, 0),
DIV_F(0, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8,
CLK_SET_RATE_PARENT, 0),
+ DIV(0, "div_clkout_top", "mout_clkout_top", CLKOUT_CMU_TOP, 8, 6),
+
+ DIV(0, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
+ DIV(0, "div_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
+ DIV(0, "div_dphy", "mout_dphy", DIV_DMC0, 8, 3),
+ DIV(0, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
+ DIV(0, "div_dmcd", "div_dmc", DIV_DMC0, 16, 3),
+ DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
+ DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
+ DIV(0, "div_clkout_dmc", "mout_clkout_dmc", CLKOUT_CMU_DMC, 8, 6),
};
/* list of divider clocks supported in exynos4210 soc */
@@ -671,6 +831,8 @@ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
8, 3, CLK_GET_RATE_NOCACHE, 0),
DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
+ DIV(0, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
+ DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};
/* list of gate clocks supported in all exynos4 soc's */
@@ -680,6 +842,8 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
* the device name and clock alias names specified below for some
* of the clocks can be removed.
*/
+ GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0),
+ GATE(CLK_PPMURIGHT, "ppmuright", "aclk200", GATE_IP_RIGHTBUS, 1, 0, 0),
GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0,
0),
@@ -695,11 +859,13 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
GATE(CLK_SROMC, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0),
GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0,
CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_PPMUG3D, "ppmug3d", "aclk200", GATE_IP_G3D, 1, 0, 0),
GATE(CLK_USB_DEVICE, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0),
GATE(CLK_ONENAND, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0),
GATE(CLK_NFCON, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0),
GATE(CLK_GPS, "gps", "aclk133", GATE_IP_GPS, 0, 0, 0),
GATE(CLK_SMMU_GPS, "smmu_gps", "aclk133", GATE_IP_GPS, 1, 0, 0),
+ GATE(CLK_PPMUGPS, "ppmugps", "aclk200", GATE_IP_GPS, 2, 0, 0),
GATE(CLK_SLIMBUS, "slimbus", "aclk100", GATE_IP_PERIL, 25, 0, 0),
GATE(CLK_SCLK_CAM0, "sclk_cam0", "div_cam0", GATE_SCLK_CAM, 4,
CLK_SET_RATE_PARENT, 0),
@@ -781,19 +947,24 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
0, 0),
GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk160", GATE_IP_CAM, 11,
0, 0),
+ GATE(CLK_PPMUCAMIF, "ppmucamif", "aclk160", GATE_IP_CAM, 16, 0, 0),
GATE(CLK_PIXELASYNCM0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0),
GATE(CLK_PIXELASYNCM1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0),
GATE(CLK_SMMU_TV, "smmu_tv", "aclk160", GATE_IP_TV, 4,
0, 0),
+ GATE(CLK_PPMUTV, "ppmutv", "aclk160", GATE_IP_TV, 5, 0, 0),
GATE(CLK_MFC, "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0),
GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk100", GATE_IP_MFC, 1,
0, 0),
GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk100", GATE_IP_MFC, 2,
0, 0),
+ GATE(CLK_PPMUMFC_L, "ppmumfc_l", "aclk100", GATE_IP_MFC, 3, 0, 0),
+ GATE(CLK_PPMUMFC_R, "ppmumfc_r", "aclk100", GATE_IP_MFC, 4, 0, 0),
GATE(CLK_FIMD0, "fimd0", "aclk160", GATE_IP_LCD0, 0,
0, 0),
GATE(CLK_SMMU_FIMD0, "smmu_fimd0", "aclk160", GATE_IP_LCD0, 4,
0, 0),
+ GATE(CLK_PPMULCD0, "ppmulcd0", "aclk160", GATE_IP_LCD0, 5, 0, 0),
GATE(CLK_PDMA0, "pdma0", "aclk133", GATE_IP_FSYS, 0,
0, 0),
GATE(CLK_PDMA1, "pdma1", "aclk133", GATE_IP_FSYS, 1,
@@ -806,6 +977,7 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
0, 0),
GATE(CLK_SDMMC3, "sdmmc3", "aclk133", GATE_IP_FSYS, 8,
0, 0),
+ GATE(CLK_PPMUFILE, "ppmufile", "aclk133", GATE_IP_FSYS, 17, 0, 0),
GATE(CLK_UART0, "uart0", "aclk100", GATE_IP_PERIL, 0,
0, 0),
GATE(CLK_UART1, "uart1", "aclk100", GATE_IP_PERIL, 1,
@@ -852,6 +1024,21 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
0, 0),
GATE(CLK_AC97, "ac97", "aclk100", GATE_IP_PERIL, 27,
0, 0),
+ GATE(CLK_PPMUDMC0, "ppmudmc0", "aclk133", GATE_IP_DMC, 8, 0, 0),
+ GATE(CLK_PPMUDMC1, "ppmudmc1", "aclk133", GATE_IP_DMC, 9, 0, 0),
+ GATE(CLK_PPMUCPU, "ppmucpu", "aclk133", GATE_IP_DMC, 10, 0, 0),
+ GATE(CLK_PPMUACP, "ppmuacp", "aclk133", GATE_IP_DMC, 16, 0, 0),
+
+ GATE(CLK_OUT_LEFTBUS, "clkout_leftbus", "div_clkout_leftbus",
+ CLKOUT_CMU_LEFTBUS, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_RIGHTBUS, "clkout_rightbus", "div_clkout_rightbus",
+ CLKOUT_CMU_RIGHTBUS, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_TOP, "clkout_top", "div_clkout_top",
+ CLKOUT_CMU_TOP, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_DMC, "clkout_dmc", "div_clkout_dmc",
+ CLKOUT_CMU_DMC, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_CPU, "clkout_cpu", "div_clkout_cpu",
+ CLKOUT_CMU_CPU, 16, CLK_SET_RATE_PARENT, 0),
};
/* list of gate clocks supported in exynos4210 soc */
@@ -863,6 +1050,9 @@ static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk200", E4210_GATE_IP_IMAGE, 3, 0, 0),
GATE(CLK_SMMU_MDMA, "smmu_mdma", "aclk200", E4210_GATE_IP_IMAGE, 5, 0,
0),
+ GATE(CLK_PPMUIMAGE, "ppmuimage", "aclk200", E4210_GATE_IP_IMAGE, 9, 0,
+ 0),
+ GATE(CLK_PPMULCD1, "ppmulcd1", "aclk160", E4210_GATE_IP_LCD1, 5, 0, 0),
GATE(CLK_PCIE_PHY, "pcie_phy", "aclk133", GATE_IP_FSYS, 2, 0, 0),
GATE(CLK_SATA_PHY, "sata_phy", "aclk133", GATE_IP_FSYS, 3, 0, 0),
GATE(CLK_SATA, "sata", "aclk133", GATE_IP_FSYS, 10, 0, 0),
@@ -906,6 +1096,8 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
GATE(CLK_MDMA, "mdma", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0),
GATE(CLK_SMMU_MDMA, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0,
0),
+ GATE(CLK_PPMUIMAGE, "ppmuimage", "aclk200", E4X12_GATE_IP_IMAGE, 9, 0,
+ 0),
GATE(CLK_MIPI_HSI, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0),
GATE(CLK_CHIPID, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0),
GATE(CLK_SYSREG, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1,
@@ -925,21 +1117,13 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
GATE(CLK_RTC, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15,
0, 0),
GATE(CLK_KEYIF, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0),
- GATE(CLK_SCLK_PWM_ISP, "sclk_pwm_isp", "div_pwm_isp",
- E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPI0_ISP, "sclk_spi0_isp", "div_spi0_isp_pre",
- E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_SPI1_ISP, "sclk_spi1_isp", "div_spi1_isp_pre",
- E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "div_uart_isp",
- E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0),
- GATE(CLK_PWM_ISP_SCLK, "pwm_isp_sclk", "sclk_pwm_isp",
+ GATE(CLK_PWM_ISP_SCLK, "pwm_isp_sclk", "div_pwm_isp",
E4X12_GATE_IP_ISP, 0, 0, 0),
- GATE(CLK_SPI0_ISP_SCLK, "spi0_isp_sclk", "sclk_spi0_isp",
+ GATE(CLK_SPI0_ISP_SCLK, "spi0_isp_sclk", "div_spi0_isp_pre",
E4X12_GATE_IP_ISP, 1, 0, 0),
- GATE(CLK_SPI1_ISP_SCLK, "spi1_isp_sclk", "sclk_spi1_isp",
+ GATE(CLK_SPI1_ISP_SCLK, "spi1_isp_sclk", "div_spi1_isp_pre",
E4X12_GATE_IP_ISP, 2, 0, 0),
- GATE(CLK_UART_ISP_SCLK, "uart_isp_sclk", "sclk_uart_isp",
+ GATE(CLK_UART_ISP_SCLK, "uart_isp_sclk", "div_uart_isp",
E4X12_GATE_IP_ISP, 3, 0, 0),
GATE(CLK_WDT, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0),
GATE(CLK_PCM0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2,
@@ -1070,7 +1254,7 @@ static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx)
}
-static struct of_device_id ext_clk_match[] __initdata = {
+static const struct of_device_id ext_clk_match[] __initconst = {
{ .compatible = "samsung,clock-xxti", .data = (void *)0, },
{ .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
{},
@@ -1172,6 +1356,32 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
VPLL_LOCK, VPLL_CON0, NULL),
};
+static void __init exynos4_core_down_clock(enum exynos4_soc soc)
+{
+ unsigned int tmp;
+
+ /*
+ * Enable arm clock down (in idle) and set arm divider
+ * ratios in WFI/WFE state.
+ */
+ tmp = (PWR_CTRL1_CORE2_DOWN_RATIO(7) | PWR_CTRL1_CORE1_DOWN_RATIO(7) |
+ PWR_CTRL1_DIV2_DOWN_EN | PWR_CTRL1_DIV1_DOWN_EN |
+ PWR_CTRL1_USE_CORE1_WFE | PWR_CTRL1_USE_CORE0_WFE |
+ PWR_CTRL1_USE_CORE1_WFI | PWR_CTRL1_USE_CORE0_WFI);
+ /* On Exynos4412 enable it also on core 2 and 3 */
+ if (num_possible_cpus() == 4)
+ tmp |= PWR_CTRL1_USE_CORE3_WFE | PWR_CTRL1_USE_CORE2_WFE |
+ PWR_CTRL1_USE_CORE3_WFI | PWR_CTRL1_USE_CORE2_WFI;
+ __raw_writel(tmp, reg_base + PWR_CTRL1);
+
+ /*
+ * Disable the clock up feature on Exynos4x12, in case it was
+ * enabled by bootloader.
+ */
+ if (exynos4_soc == EXYNOS4X12)
+ __raw_writel(0x0, reg_base + E4X12_PWR_CTRL2);
+}
+
/* register exynos4 clocks */
static void __init exynos4_clk_init(struct device_node *np,
enum exynos4_soc soc)
@@ -1232,6 +1442,8 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4_div_clks));
samsung_clk_register_gate(ctx, exynos4_gate_clks,
ARRAY_SIZE(exynos4_gate_clks));
+ samsung_clk_register_fixed_factor(ctx, exynos4_fixed_factor_clks,
+ ARRAY_SIZE(exynos4_fixed_factor_clks));
if (exynos4_soc == EXYNOS4210) {
samsung_clk_register_fixed_rate(ctx, exynos4210_fixed_rate_clks,
@@ -1244,6 +1456,9 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4210_gate_clks));
samsung_clk_register_alias(ctx, exynos4210_aliases,
ARRAY_SIZE(exynos4210_aliases));
+ samsung_clk_register_fixed_factor(ctx,
+ exynos4210_fixed_factor_clks,
+ ARRAY_SIZE(exynos4210_fixed_factor_clks));
} else {
samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
ARRAY_SIZE(exynos4x12_mux_clks));
@@ -1253,13 +1468,19 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4x12_gate_clks));
samsung_clk_register_alias(ctx, exynos4x12_aliases,
ARRAY_SIZE(exynos4x12_aliases));
+ samsung_clk_register_fixed_factor(ctx,
+ exynos4x12_fixed_factor_clks,
+ ARRAY_SIZE(exynos4x12_fixed_factor_clks));
}
samsung_clk_register_alias(ctx, exynos4_aliases,
ARRAY_SIZE(exynos4_aliases));
+ exynos4_core_down_clock(soc);
exynos4_clk_sleep_init();
+ samsung_clk_of_add_provider(np, ctx);
+
pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
"\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 1fad4c5e3f5d..70ec3d2608a1 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -661,7 +661,7 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0),
GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0),
GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub",
- GATE_IP_DISP1, 2, 0, 0),
+ GATE_IP_DISP1, 9, 0, 0),
GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub",
GATE_IP_DISP1, 8, 0, 0),
GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0),
@@ -748,7 +748,7 @@ static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
VPLL_LOCK, VPLL_CON0, NULL),
};
-static struct of_device_id ext_clk_match[] __initdata = {
+static const struct of_device_id ext_clk_match[] __initconst = {
{ .compatible = "samsung,clock-xxti", .data = (void *)0, },
{ },
};
@@ -820,6 +820,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
exynos5250_clk_sleep_init();
+ samsung_clk_of_add_provider(np, ctx);
+
pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
_get_rate("div_arm2"));
}
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 64596ba58df1..ce3de97e5f11 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -206,6 +206,8 @@ void __init exynos5260_cmu_register_one(struct device_node *np,
if (cmu->clk_regs)
exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
cmu->nr_clk_regs);
+
+ samsung_clk_of_add_provider(np, ctx);
}
diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c
index c9505ab9ee70..231475bc2b99 100644
--- a/drivers/clk/samsung/clk-exynos5410.c
+++ b/drivers/clk/samsung/clk-exynos5410.c
@@ -204,6 +204,8 @@ static void __init exynos5410_clk_init(struct device_node *np)
samsung_clk_register_gate(ctx, exynos5410_gate_clks,
ARRAY_SIZE(exynos5410_gate_clks));
+ samsung_clk_of_add_provider(np, ctx);
+
pr_debug("Exynos5410: clock setup completed.\n");
}
CLK_OF_DECLARE(exynos5410_clk, "samsung,exynos5410-clock", exynos5410_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 9d7d7eed03fd..848d602efc06 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -28,6 +28,7 @@
#define GATE_BUS_CPU 0x700
#define GATE_SCLK_CPU 0x800
#define CLKOUT_CMU_CPU 0xa00
+#define SRC_MASK_CPERI 0x4300
#define GATE_IP_G2D 0x8800
#define CPLL_LOCK 0x10020
#define DPLL_LOCK 0x10030
@@ -70,6 +71,8 @@
#define SRC_TOP11 0x10284
#define SRC_TOP12 0x10288
#define SRC_TOP13 0x1028c /* 5800 specific */
+#define SRC_MASK_TOP0 0x10300
+#define SRC_MASK_TOP1 0x10304
#define SRC_MASK_TOP2 0x10308
#define SRC_MASK_TOP7 0x1031c
#define SRC_MASK_DISP10 0x1032c
@@ -77,6 +80,7 @@
#define SRC_MASK_FSYS 0x10340
#define SRC_MASK_PERIC0 0x10350
#define SRC_MASK_PERIC1 0x10354
+#define SRC_MASK_ISP 0x10370
#define DIV_TOP0 0x10500
#define DIV_TOP1 0x10504
#define DIV_TOP2 0x10508
@@ -98,6 +102,7 @@
#define DIV2_RATIO0 0x10590
#define DIV4_RATIO 0x105a0
#define GATE_BUS_TOP 0x10700
+#define GATE_BUS_DISP1 0x10728
#define GATE_BUS_GEN 0x1073c
#define GATE_BUS_FSYS0 0x10740
#define GATE_BUS_FSYS2 0x10748
@@ -190,6 +195,10 @@ static unsigned long exynos5x_clk_regs[] __initdata = {
SRC_MASK_FSYS,
SRC_MASK_PERIC0,
SRC_MASK_PERIC1,
+ SRC_MASK_TOP0,
+ SRC_MASK_TOP1,
+ SRC_MASK_MAU,
+ SRC_MASK_ISP,
SRC_ISP,
DIV_TOP0,
DIV_TOP1,
@@ -208,6 +217,7 @@ static unsigned long exynos5x_clk_regs[] __initdata = {
SCLK_DIV_ISP1,
DIV2_RATIO0,
DIV4_RATIO,
+ GATE_BUS_DISP1,
GATE_BUS_TOP,
GATE_BUS_GEN,
GATE_BUS_FSYS0,
@@ -249,6 +259,22 @@ static unsigned long exynos5800_clk_regs[] __initdata = {
GATE_IP_CAM,
};
+static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
+ { .offset = SRC_MASK_CPERI, .value = 0xffffffff, },
+ { .offset = SRC_MASK_TOP0, .value = 0x11111111, },
+ { .offset = SRC_MASK_TOP1, .value = 0x11101111, },
+ { .offset = SRC_MASK_TOP2, .value = 0x11111110, },
+ { .offset = SRC_MASK_TOP7, .value = 0x00111100, },
+ { .offset = SRC_MASK_DISP10, .value = 0x11111110, },
+ { .offset = SRC_MASK_MAU, .value = 0x10000000, },
+ { .offset = SRC_MASK_FSYS, .value = 0x11111110, },
+ { .offset = SRC_MASK_PERIC0, .value = 0x11111110, },
+ { .offset = SRC_MASK_PERIC1, .value = 0x11111100, },
+ { .offset = SRC_MASK_ISP, .value = 0x11111000, },
+ { .offset = GATE_BUS_DISP1, .value = 0xffffffff, },
+ { .offset = GATE_IP_PERIC, .value = 0xffffffff, },
+};
+
static int exynos5420_clk_suspend(void)
{
samsung_clk_save(reg_base, exynos5x_save,
@@ -258,6 +284,9 @@ static int exynos5420_clk_suspend(void)
samsung_clk_save(reg_base, exynos5800_save,
ARRAY_SIZE(exynos5800_clk_regs));
+ samsung_clk_restore(reg_base, exynos5420_set_clksrc,
+ ARRAY_SIZE(exynos5420_set_clksrc));
+
return 0;
}
@@ -631,7 +660,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP4, 16, 1),
MUX(0, "mout_user_aclk266", mout_user_aclk266_p, SRC_TOP4, 20, 1),
MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1),
- MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1),
+ MUX(CLK_MOUT_USER_ACLK333, "mout_user_aclk333", mout_user_aclk333_p,
+ SRC_TOP4, 28, 1),
MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p,
SRC_TOP5, 0, 1),
@@ -684,7 +714,8 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
SRC_TOP11, 12, 1),
MUX(0, "mout_sw_aclk266", mout_sw_aclk266_p, SRC_TOP11, 20, 1),
MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1),
- MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1),
+ MUX(CLK_MOUT_SW_ACLK333, "mout_sw_aclk333", mout_sw_aclk333_p,
+ SRC_TOP11, 28, 1),
MUX(0, "mout_sw_aclk400_disp1", mout_sw_aclk400_disp1_p,
SRC_TOP12, 4, 1),
@@ -890,8 +921,6 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen",
GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0),
- GATE(CLK_ACLK66_PERIC, "aclk66_peric", "mout_user_aclk66_peric",
- GATE_BUS_TOP, 11, CLK_IGNORE_UNUSED, 0),
GATE(0, "aclk266_isp", "mout_user_aclk266_isp",
GATE_BUS_TOP, 13, 0, 0),
GATE(0, "aclk166", "mout_user_aclk166",
@@ -994,34 +1023,61 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
/* PERIC Block */
- GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_IP_PERIC, 0, 0, 0),
- GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_IP_PERIC, 1, 0, 0),
- GATE(CLK_UART2, "uart2", "aclk66_peric", GATE_IP_PERIC, 2, 0, 0),
- GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_IP_PERIC, 3, 0, 0),
- GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_IP_PERIC, 6, 0, 0),
- GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_IP_PERIC, 7, 0, 0),
- GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_IP_PERIC, 8, 0, 0),
- GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_IP_PERIC, 9, 0, 0),
- GATE(CLK_USI0, "usi0", "aclk66_peric", GATE_IP_PERIC, 10, 0, 0),
- GATE(CLK_USI1, "usi1", "aclk66_peric", GATE_IP_PERIC, 11, 0, 0),
- GATE(CLK_USI2, "usi2", "aclk66_peric", GATE_IP_PERIC, 12, 0, 0),
- GATE(CLK_USI3, "usi3", "aclk66_peric", GATE_IP_PERIC, 13, 0, 0),
- GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_IP_PERIC, 14, 0, 0),
- GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_IP_PERIC, 15, 0, 0),
- GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_IP_PERIC, 16, 0, 0),
- GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_IP_PERIC, 17, 0, 0),
- GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_IP_PERIC, 18, 0, 0),
- GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_IP_PERIC, 20, 0, 0),
- GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_IP_PERIC, 21, 0, 0),
- GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_IP_PERIC, 22, 0, 0),
- GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_IP_PERIC, 23, 0, 0),
- GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_IP_PERIC, 24, 0, 0),
- GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_IP_PERIC, 26, 0, 0),
- GATE(CLK_USI4, "usi4", "aclk66_peric", GATE_IP_PERIC, 28, 0, 0),
- GATE(CLK_USI5, "usi5", "aclk66_peric", GATE_IP_PERIC, 30, 0, 0),
- GATE(CLK_USI6, "usi6", "aclk66_peric", GATE_IP_PERIC, 31, 0, 0),
-
- GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0),
+ GATE(CLK_UART0, "uart0", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 0, 0, 0),
+ GATE(CLK_UART1, "uart1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 1, 0, 0),
+ GATE(CLK_UART2, "uart2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 2, 0, 0),
+ GATE(CLK_UART3, "uart3", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 3, 0, 0),
+ GATE(CLK_I2C0, "i2c0", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 6, 0, 0),
+ GATE(CLK_I2C1, "i2c1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 7, 0, 0),
+ GATE(CLK_I2C2, "i2c2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 8, 0, 0),
+ GATE(CLK_I2C3, "i2c3", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 9, 0, 0),
+ GATE(CLK_USI0, "usi0", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 10, 0, 0),
+ GATE(CLK_USI1, "usi1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 11, 0, 0),
+ GATE(CLK_USI2, "usi2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 12, 0, 0),
+ GATE(CLK_USI3, "usi3", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 13, 0, 0),
+ GATE(CLK_I2C_HDMI, "i2c_hdmi", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 14, 0, 0),
+ GATE(CLK_TSADC, "tsadc", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 15, 0, 0),
+ GATE(CLK_SPI0, "spi0", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 16, 0, 0),
+ GATE(CLK_SPI1, "spi1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 17, 0, 0),
+ GATE(CLK_SPI2, "spi2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 18, 0, 0),
+ GATE(CLK_I2S1, "i2s1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 20, 0, 0),
+ GATE(CLK_I2S2, "i2s2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 21, 0, 0),
+ GATE(CLK_PCM1, "pcm1", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 22, 0, 0),
+ GATE(CLK_PCM2, "pcm2", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 23, 0, 0),
+ GATE(CLK_PWM, "pwm", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 24, 0, 0),
+ GATE(CLK_SPDIF, "spdif", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 26, 0, 0),
+ GATE(CLK_USI4, "usi4", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 28, 0, 0),
+ GATE(CLK_USI5, "usi5", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 30, 0, 0),
+ GATE(CLK_USI6, "usi6", "mout_user_aclk66_peric",
+ GATE_IP_PERIC, 31, 0, 0),
+
+ GATE(CLK_KEYIF, "keyif", "mout_user_aclk66_peric",
+ GATE_BUS_PERIC, 22, 0, 0),
/* PERIS Block */
GATE(CLK_CHIPID, "chipid", "aclk66_psgen",
@@ -1142,6 +1198,28 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
};
+static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] = {
+ PLL_35XX_RATE(2000000000, 250, 3, 0),
+ PLL_35XX_RATE(1900000000, 475, 6, 0),
+ PLL_35XX_RATE(1800000000, 225, 3, 0),
+ PLL_35XX_RATE(1700000000, 425, 6, 0),
+ PLL_35XX_RATE(1600000000, 200, 3, 0),
+ PLL_35XX_RATE(1500000000, 250, 4, 0),
+ PLL_35XX_RATE(1400000000, 175, 3, 0),
+ PLL_35XX_RATE(1300000000, 325, 6, 0),
+ PLL_35XX_RATE(1200000000, 200, 2, 1),
+ PLL_35XX_RATE(1100000000, 275, 3, 1),
+ PLL_35XX_RATE(1000000000, 250, 3, 1),
+ PLL_35XX_RATE(900000000, 150, 2, 1),
+ PLL_35XX_RATE(800000000, 200, 3, 1),
+ PLL_35XX_RATE(700000000, 175, 3, 1),
+ PLL_35XX_RATE(600000000, 200, 2, 2),
+ PLL_35XX_RATE(500000000, 250, 3, 2),
+ PLL_35XX_RATE(400000000, 200, 3, 2),
+ PLL_35XX_RATE(300000000, 200, 2, 3),
+ PLL_35XX_RATE(200000000, 200, 3, 3),
+};
+
static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
[apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
APLL_CON0, NULL),
@@ -1167,7 +1245,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
KPLL_CON0, NULL),
};
-static struct of_device_id ext_clk_match[] __initdata = {
+static const struct of_device_id ext_clk_match[] __initconst = {
{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
{ },
};
@@ -1195,6 +1273,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5x_fixed_rate_ext_clks),
ext_clk_match);
+
+ if (_get_rate("fin_pll") == 24 * MHZ) {
+ exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
+ exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
+ }
+
samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls),
reg_base);
samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks,
@@ -1226,6 +1310,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
}
exynos5420_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
static void __init exynos5420_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
index 647f1440aa6a..00d1d00a41de 100644
--- a/drivers/clk/samsung/clk-exynos5440.c
+++ b/drivers/clk/samsung/clk-exynos5440.c
@@ -84,7 +84,7 @@ static struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
GATE(CLK_CS250_O, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
};
-static struct of_device_id ext_clk_match[] __initdata = {
+static const struct of_device_id ext_clk_match[] __initconst = {
{ .compatible = "samsung,clock-xtal", .data = (void *)0, },
{},
};
@@ -123,6 +123,8 @@ static void __init exynos5440_clk_init(struct device_node *np)
samsung_clk_register_gate(ctx, exynos5440_gate_clks,
ARRAY_SIZE(exynos5440_gate_clks));
+ samsung_clk_of_add_provider(np, ctx);
+
pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
pr_info("exynos5440 clock initialization complete\n");
}
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index ba0716801db2..5d2f03461bc5 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -152,6 +152,11 @@ struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
ALIAS(HCLK, NULL, "hclk"),
ALIAS(MPLL, NULL, "mpll"),
ALIAS(FCLK, NULL, "fclk"),
+ ALIAS(PCLK, NULL, "watchdog"),
+ ALIAS(PCLK_SDI, NULL, "sdi"),
+ ALIAS(HCLK_NAND, NULL, "nand"),
+ ALIAS(PCLK_I2S, NULL, "iis"),
+ ALIAS(PCLK_I2C, NULL, "i2c"),
};
/* S3C2410 specific clocks */
@@ -378,7 +383,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
if (!np)
s3c2410_common_clk_register_fixed_ext(ctx, xti_f);
- if (current_soc == 2410) {
+ if (current_soc == S3C2410) {
if (_get_rate("xti") == 12 * MHZ) {
s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
@@ -432,7 +437,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
samsung_clk_register_fixed_factor(ctx, s3c2410_ffactor,
ARRAY_SIZE(s3c2410_ffactor));
samsung_clk_register_alias(ctx, s3c2410_aliases,
- ARRAY_SIZE(s3c2410_common_aliases));
+ ARRAY_SIZE(s3c2410_aliases));
break;
case S3C2440:
samsung_clk_register_mux(ctx, s3c2440_muxes,
@@ -461,6 +466,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
}
s3c2410_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
static void __init s3c2410_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index 23e4313f625e..34af09f6a155 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -265,6 +265,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
ARRAY_SIZE(s3c2412_aliases));
s3c2412_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
static void __init s3c2412_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index c4bbdabebaa4..c92f853fca9f 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -445,6 +445,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
}
s3c2443_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
static void __init s3c2416_clk_init(struct device_node *np)
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index efa16ee592c8..0f590e5550cb 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -418,8 +418,10 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
- ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
- ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
+ ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi_busclk0"),
+ ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi_busclk2"),
+ ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi_busclk0"),
+ ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi_busclk2"),
ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
@@ -516,6 +518,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
ARRAY_SIZE(s3c64xx_clock_aliases));
s3c64xx_clk_sleep_init();
+ samsung_clk_of_add_provider(np, ctx);
+
pr_info("%s clocks: apll = %lu, mpll = %lu\n"
"\tepll = %lu, arm_clk = %lu\n",
is_s3c6400 ? "S3C6400" : "S3C6410",
diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c
new file mode 100644
index 000000000000..a8053b4aca56
--- /dev/null
+++ b/drivers/clk/samsung/clk-s5pv210-audss.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014 Tomasz Figa <t.figa@samsung.com>
+ *
+ * Based on Exynos Audio Subsystem Clock Controller driver:
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Author: Padmavathi Venna <padma.v@samsung.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.
+ *
+ * Driver for Audio Subsystem Clock Controller of S5PV210-compatible SoCs.
+*/
+
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/s5pv210-audss.h>
+
+static DEFINE_SPINLOCK(lock);
+static struct clk **clk_table;
+static void __iomem *reg_base;
+static struct clk_onecell_data clk_data;
+
+#define ASS_CLK_SRC 0x0
+#define ASS_CLK_DIV 0x4
+#define ASS_CLK_GATE 0x8
+
+#ifdef CONFIG_PM_SLEEP
+static unsigned long reg_save[][2] = {
+ {ASS_CLK_SRC, 0},
+ {ASS_CLK_DIV, 0},
+ {ASS_CLK_GATE, 0},
+};
+
+static int s5pv210_audss_clk_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(reg_save); i++)
+ reg_save[i][1] = readl(reg_base + reg_save[i][0]);
+
+ return 0;
+}
+
+static void s5pv210_audss_clk_resume(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(reg_save); i++)
+ writel(reg_save[i][1], reg_base + reg_save[i][0]);
+}
+
+static struct syscore_ops s5pv210_audss_clk_syscore_ops = {
+ .suspend = s5pv210_audss_clk_suspend,
+ .resume = s5pv210_audss_clk_resume,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+/* register s5pv210_audss clocks */
+static int s5pv210_audss_clk_probe(struct platform_device *pdev)
+{
+ int i, ret = 0;
+ struct resource *res;
+ const char *mout_audss_p[2];
+ const char *mout_i2s_p[3];
+ const char *hclk_p;
+ struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(reg_base)) {
+ dev_err(&pdev->dev, "failed to map audss registers\n");
+ return PTR_ERR(reg_base);
+ }
+
+ clk_table = devm_kzalloc(&pdev->dev,
+ sizeof(struct clk *) * AUDSS_MAX_CLKS,
+ GFP_KERNEL);
+ if (!clk_table)
+ return -ENOMEM;
+
+ clk_data.clks = clk_table;
+ clk_data.clk_num = AUDSS_MAX_CLKS;
+
+ hclk = devm_clk_get(&pdev->dev, "hclk");
+ if (IS_ERR(hclk)) {
+ dev_err(&pdev->dev, "failed to get hclk clock\n");
+ return PTR_ERR(hclk);
+ }
+
+ pll_in = devm_clk_get(&pdev->dev, "fout_epll");
+ if (IS_ERR(pll_in)) {
+ dev_err(&pdev->dev, "failed to get fout_epll clock\n");
+ return PTR_ERR(pll_in);
+ }
+
+ sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio0");
+ if (IS_ERR(sclk_audio)) {
+ dev_err(&pdev->dev, "failed to get sclk_audio0 clock\n");
+ return PTR_ERR(sclk_audio);
+ }
+
+ /* iiscdclk0 is an optional external I2S codec clock */
+ cdclk = devm_clk_get(&pdev->dev, "iiscdclk0");
+ pll_ref = devm_clk_get(&pdev->dev, "xxti");
+
+ if (!IS_ERR(pll_ref))
+ mout_audss_p[0] = __clk_get_name(pll_ref);
+ else
+ mout_audss_p[0] = "xxti";
+ mout_audss_p[1] = __clk_get_name(pll_in);
+ clk_table[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
+ mout_audss_p, ARRAY_SIZE(mout_audss_p),
+ CLK_SET_RATE_NO_REPARENT,
+ reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
+
+ mout_i2s_p[0] = "mout_audss";
+ if (!IS_ERR(cdclk))
+ mout_i2s_p[1] = __clk_get_name(cdclk);
+ else
+ mout_i2s_p[1] = "iiscdclk0";
+ mout_i2s_p[2] = __clk_get_name(sclk_audio);
+ clk_table[CLK_MOUT_I2S_A] = clk_register_mux(NULL, "mout_i2s_audss",
+ mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
+ CLK_SET_RATE_NO_REPARENT,
+ reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
+
+ clk_table[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL,
+ "dout_aud_bus", "mout_audss", 0,
+ reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
+ clk_table[CLK_DOUT_I2S_A] = clk_register_divider(NULL, "dout_i2s_audss",
+ "mout_i2s_audss", 0, reg_base + ASS_CLK_DIV,
+ 4, 4, 0, &lock);
+
+ clk_table[CLK_I2S] = clk_register_gate(NULL, "i2s_audss",
+ "dout_i2s_audss", CLK_SET_RATE_PARENT,
+ reg_base + ASS_CLK_GATE, 6, 0, &lock);
+
+ hclk_p = __clk_get_name(hclk);
+
+ clk_table[CLK_HCLK_I2S] = clk_register_gate(NULL, "hclk_i2s_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 5, 0, &lock);
+ clk_table[CLK_HCLK_UART] = clk_register_gate(NULL, "hclk_uart_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 4, 0, &lock);
+ clk_table[CLK_HCLK_HWA] = clk_register_gate(NULL, "hclk_hwa_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 3, 0, &lock);
+ clk_table[CLK_HCLK_DMA] = clk_register_gate(NULL, "hclk_dma_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 2, 0, &lock);
+ clk_table[CLK_HCLK_BUF] = clk_register_gate(NULL, "hclk_buf_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 1, 0, &lock);
+ clk_table[CLK_HCLK_RP] = clk_register_gate(NULL, "hclk_rp_audss",
+ hclk_p, CLK_IGNORE_UNUSED,
+ reg_base + ASS_CLK_GATE, 0, 0, &lock);
+
+ for (i = 0; i < clk_data.clk_num; i++) {
+ if (IS_ERR(clk_table[i])) {
+ dev_err(&pdev->dev, "failed to register clock %d\n", i);
+ ret = PTR_ERR(clk_table[i]);
+ goto unregister;
+ }
+ }
+
+ ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
+ &clk_data);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add clock provider\n");
+ goto unregister;
+ }
+
+#ifdef CONFIG_PM_SLEEP
+ register_syscore_ops(&s5pv210_audss_clk_syscore_ops);
+#endif
+
+ return 0;
+
+unregister:
+ for (i = 0; i < clk_data.clk_num; i++) {
+ if (!IS_ERR(clk_table[i]))
+ clk_unregister(clk_table[i]);
+ }
+
+ return ret;
+}
+
+static int s5pv210_audss_clk_remove(struct platform_device *pdev)
+{
+ int i;
+
+ of_clk_del_provider(pdev->dev.of_node);
+
+ for (i = 0; i < clk_data.clk_num; i++) {
+ if (!IS_ERR(clk_table[i]))
+ clk_unregister(clk_table[i]);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id s5pv210_audss_clk_of_match[] = {
+ { .compatible = "samsung,s5pv210-audss-clock", },
+ {},
+};
+
+static struct platform_driver s5pv210_audss_clk_driver = {
+ .driver = {
+ .name = "s5pv210-audss-clk",
+ .owner = THIS_MODULE,
+ .of_match_table = s5pv210_audss_clk_of_match,
+ },
+ .probe = s5pv210_audss_clk_probe,
+ .remove = s5pv210_audss_clk_remove,
+};
+
+static int __init s5pv210_audss_clk_init(void)
+{
+ return platform_driver_register(&s5pv210_audss_clk_driver);
+}
+core_initcall(s5pv210_audss_clk_init);
+
+static void __exit s5pv210_audss_clk_exit(void)
+{
+ platform_driver_unregister(&s5pv210_audss_clk_driver);
+}
+module_exit(s5pv210_audss_clk_exit);
+
+MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
+MODULE_DESCRIPTION("S5PV210 Audio Subsystem Clock Controller");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:s5pv210-audss-clk");
diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c
new file mode 100644
index 000000000000..d270a2084644
--- /dev/null
+++ b/drivers/clk/samsung/clk-s5pv210.c
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Author: Mateusz Krawczuk <m.krawczuk@partner.samsung.com>
+ *
+ * Based on clock drivers for S3C64xx and Exynos4 SoCs.
+ *
+ * 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.
+ *
+ * Common Clock Framework support for all S5PC110/S5PV210 SoCs.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+#include <dt-bindings/clock/s5pv210.h>
+
+/* S5PC110/S5PV210 clock controller register offsets */
+#define APLL_LOCK 0x0000
+#define MPLL_LOCK 0x0008
+#define EPLL_LOCK 0x0010
+#define VPLL_LOCK 0x0020
+#define APLL_CON0 0x0100
+#define APLL_CON1 0x0104
+#define MPLL_CON 0x0108
+#define EPLL_CON0 0x0110
+#define EPLL_CON1 0x0114
+#define VPLL_CON 0x0120
+#define CLK_SRC0 0x0200
+#define CLK_SRC1 0x0204
+#define CLK_SRC2 0x0208
+#define CLK_SRC3 0x020c
+#define CLK_SRC4 0x0210
+#define CLK_SRC5 0x0214
+#define CLK_SRC6 0x0218
+#define CLK_SRC_MASK0 0x0280
+#define CLK_SRC_MASK1 0x0284
+#define CLK_DIV0 0x0300
+#define CLK_DIV1 0x0304
+#define CLK_DIV2 0x0308
+#define CLK_DIV3 0x030c
+#define CLK_DIV4 0x0310
+#define CLK_DIV5 0x0314
+#define CLK_DIV6 0x0318
+#define CLK_DIV7 0x031c
+#define CLK_GATE_MAIN0 0x0400
+#define CLK_GATE_MAIN1 0x0404
+#define CLK_GATE_MAIN2 0x0408
+#define CLK_GATE_PERI0 0x0420
+#define CLK_GATE_PERI1 0x0424
+#define CLK_GATE_SCLK0 0x0440
+#define CLK_GATE_SCLK1 0x0444
+#define CLK_GATE_IP0 0x0460
+#define CLK_GATE_IP1 0x0464
+#define CLK_GATE_IP2 0x0468
+#define CLK_GATE_IP3 0x046c
+#define CLK_GATE_IP4 0x0470
+#define CLK_GATE_BLOCK 0x0480
+#define CLK_GATE_IP5 0x0484
+#define CLK_OUT 0x0500
+#define MISC 0xe000
+#define OM_STAT 0xe100
+
+/* IDs of PLLs available on S5PV210/S5P6442 SoCs */
+enum {
+ apll,
+ mpll,
+ epll,
+ vpll,
+};
+
+/* IDs of external clocks (used for legacy boards) */
+enum {
+ xxti,
+ xusbxti,
+};
+
+static void __iomem *reg_base;
+
+#ifdef CONFIG_PM_SLEEP
+static struct samsung_clk_reg_dump *s5pv210_clk_dump;
+
+/* List of registers that need to be preserved across suspend/resume. */
+static unsigned long s5pv210_clk_regs[] __initdata = {
+ CLK_SRC0,
+ CLK_SRC1,
+ CLK_SRC2,
+ CLK_SRC3,
+ CLK_SRC4,
+ CLK_SRC5,
+ CLK_SRC6,
+ CLK_SRC_MASK0,
+ CLK_SRC_MASK1,
+ CLK_DIV0,
+ CLK_DIV1,
+ CLK_DIV2,
+ CLK_DIV3,
+ CLK_DIV4,
+ CLK_DIV5,
+ CLK_DIV6,
+ CLK_DIV7,
+ CLK_GATE_MAIN0,
+ CLK_GATE_MAIN1,
+ CLK_GATE_MAIN2,
+ CLK_GATE_PERI0,
+ CLK_GATE_PERI1,
+ CLK_GATE_SCLK0,
+ CLK_GATE_SCLK1,
+ CLK_GATE_IP0,
+ CLK_GATE_IP1,
+ CLK_GATE_IP2,
+ CLK_GATE_IP3,
+ CLK_GATE_IP4,
+ CLK_GATE_IP5,
+ CLK_GATE_BLOCK,
+ APLL_LOCK,
+ MPLL_LOCK,
+ EPLL_LOCK,
+ VPLL_LOCK,
+ APLL_CON0,
+ APLL_CON1,
+ MPLL_CON,
+ EPLL_CON0,
+ EPLL_CON1,
+ VPLL_CON,
+ CLK_OUT,
+};
+
+static int s5pv210_clk_suspend(void)
+{
+ samsung_clk_save(reg_base, s5pv210_clk_dump,
+ ARRAY_SIZE(s5pv210_clk_regs));
+ return 0;
+}
+
+static void s5pv210_clk_resume(void)
+{
+ samsung_clk_restore(reg_base, s5pv210_clk_dump,
+ ARRAY_SIZE(s5pv210_clk_regs));
+}
+
+static struct syscore_ops s5pv210_clk_syscore_ops = {
+ .suspend = s5pv210_clk_suspend,
+ .resume = s5pv210_clk_resume,
+};
+
+static void s5pv210_clk_sleep_init(void)
+{
+ s5pv210_clk_dump =
+ samsung_clk_alloc_reg_dump(s5pv210_clk_regs,
+ ARRAY_SIZE(s5pv210_clk_regs));
+ if (!s5pv210_clk_dump) {
+ pr_warn("%s: Failed to allocate sleep save data\n", __func__);
+ return;
+ }
+
+ register_syscore_ops(&s5pv210_clk_syscore_ops);
+}
+#else
+static inline void s5pv210_clk_sleep_init(void) { }
+#endif
+
+/* Mux parent lists. */
+static const char *fin_pll_p[] __initconst = {
+ "xxti",
+ "xusbxti"
+};
+
+static const char *mout_apll_p[] __initconst = {
+ "fin_pll",
+ "fout_apll"
+};
+
+static const char *mout_mpll_p[] __initconst = {
+ "fin_pll",
+ "fout_mpll"
+};
+
+static const char *mout_epll_p[] __initconst = {
+ "fin_pll",
+ "fout_epll"
+};
+
+static const char *mout_vpllsrc_p[] __initconst = {
+ "fin_pll",
+ "sclk_hdmi27m"
+};
+
+static const char *mout_vpll_p[] __initconst = {
+ "mout_vpllsrc",
+ "fout_vpll"
+};
+
+static const char *mout_group1_p[] __initconst = {
+ "dout_a2m",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll"
+};
+
+static const char *mout_group2_p[] __initconst = {
+ "xxti",
+ "xusbxti",
+ "sclk_hdmi27m",
+ "sclk_usbphy0",
+ "sclk_usbphy1",
+ "sclk_hdmiphy",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_audio0_p[] __initconst = {
+ "xxti",
+ "pcmcdclk0",
+ "sclk_hdmi27m",
+ "sclk_usbphy0",
+ "sclk_usbphy1",
+ "sclk_hdmiphy",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_audio1_p[] __initconst = {
+ "i2scdclk1",
+ "pcmcdclk1",
+ "sclk_hdmi27m",
+ "sclk_usbphy0",
+ "sclk_usbphy1",
+ "sclk_hdmiphy",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_audio2_p[] __initconst = {
+ "i2scdclk2",
+ "pcmcdclk2",
+ "sclk_hdmi27m",
+ "sclk_usbphy0",
+ "sclk_usbphy1",
+ "sclk_hdmiphy",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_spdif_p[] __initconst = {
+ "dout_audio0",
+ "dout_audio1",
+ "dout_audio3",
+};
+
+static const char *mout_group3_p[] __initconst = {
+ "mout_apll",
+ "mout_mpll"
+};
+
+static const char *mout_group4_p[] __initconst = {
+ "mout_mpll",
+ "dout_a2m"
+};
+
+static const char *mout_flash_p[] __initconst = {
+ "dout_hclkd",
+ "dout_hclkp"
+};
+
+static const char *mout_dac_p[] __initconst = {
+ "mout_vpll",
+ "sclk_hdmiphy"
+};
+
+static const char *mout_hdmi_p[] __initconst = {
+ "sclk_hdmiphy",
+ "dout_tblk"
+};
+
+static const char *mout_mixer_p[] __initconst = {
+ "mout_dac",
+ "mout_hdmi"
+};
+
+static const char *mout_vpll_6442_p[] __initconst = {
+ "fin_pll",
+ "fout_vpll"
+};
+
+static const char *mout_mixer_6442_p[] __initconst = {
+ "mout_vpll",
+ "dout_mixer"
+};
+
+static const char *mout_d0sync_6442_p[] __initconst = {
+ "mout_dsys",
+ "div_apll"
+};
+
+static const char *mout_d1sync_6442_p[] __initconst = {
+ "mout_psys",
+ "div_apll"
+};
+
+static const char *mout_group2_6442_p[] __initconst = {
+ "fin_pll",
+ "none",
+ "none",
+ "sclk_usbphy0",
+ "none",
+ "none",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_audio0_6442_p[] __initconst = {
+ "fin_pll",
+ "pcmcdclk0",
+ "none",
+ "sclk_usbphy0",
+ "none",
+ "none",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+};
+
+static const char *mout_audio1_6442_p[] __initconst = {
+ "i2scdclk1",
+ "pcmcdclk1",
+ "none",
+ "sclk_usbphy0",
+ "none",
+ "none",
+ "mout_mpll",
+ "mout_epll",
+ "mout_vpll",
+ "fin_pll",
+};
+
+static const char *mout_clksel_p[] __initconst = {
+ "fout_apll_clkout",
+ "fout_mpll_clkout",
+ "fout_epll",
+ "fout_vpll",
+ "sclk_usbphy0",
+ "sclk_usbphy1",
+ "sclk_hdmiphy",
+ "rtc",
+ "rtc_tick",
+ "dout_hclkm",
+ "dout_pclkm",
+ "dout_hclkd",
+ "dout_pclkd",
+ "dout_hclkp",
+ "dout_pclkp",
+ "dout_apll_clkout",
+ "dout_hpm",
+ "xxti",
+ "xusbxti",
+ "div_dclk"
+};
+
+static const char *mout_clksel_6442_p[] __initconst = {
+ "fout_apll_clkout",
+ "fout_mpll_clkout",
+ "fout_epll",
+ "fout_vpll",
+ "sclk_usbphy0",
+ "none",
+ "none",
+ "rtc",
+ "rtc_tick",
+ "none",
+ "none",
+ "dout_hclkd",
+ "dout_pclkd",
+ "dout_hclkp",
+ "dout_pclkp",
+ "dout_apll_clkout",
+ "none",
+ "fin_pll",
+ "none",
+ "div_dclk"
+};
+
+static const char *mout_clkout_p[] __initconst = {
+ "dout_clkout",
+ "none",
+ "xxti",
+ "xusbxti"
+};
+
+/* Common fixed factor clocks. */
+static struct samsung_fixed_factor_clock ffactor_clks[] __initdata = {
+ FFACTOR(FOUT_APLL_CLKOUT, "fout_apll_clkout", "fout_apll", 1, 4, 0),
+ FFACTOR(FOUT_MPLL_CLKOUT, "fout_mpll_clkout", "fout_mpll", 1, 2, 0),
+ FFACTOR(DOUT_APLL_CLKOUT, "dout_apll_clkout", "dout_apll", 1, 4, 0),
+};
+
+/* PLL input mux (fin_pll), which needs to be registered before PLLs. */
+static struct samsung_mux_clock early_mux_clks[] __initdata = {
+ MUX_F(FIN_PLL, "fin_pll", fin_pll_p, OM_STAT, 0, 1,
+ CLK_MUX_READ_ONLY, 0),
+};
+
+/* Common clock muxes. */
+static struct samsung_mux_clock mux_clks[] __initdata = {
+ MUX(MOUT_FLASH, "mout_flash", mout_flash_p, CLK_SRC0, 28, 1),
+ MUX(MOUT_PSYS, "mout_psys", mout_group4_p, CLK_SRC0, 24, 1),
+ MUX(MOUT_DSYS, "mout_dsys", mout_group4_p, CLK_SRC0, 20, 1),
+ MUX(MOUT_MSYS, "mout_msys", mout_group3_p, CLK_SRC0, 16, 1),
+ MUX(MOUT_EPLL, "mout_epll", mout_epll_p, CLK_SRC0, 8, 1),
+ MUX(MOUT_MPLL, "mout_mpll", mout_mpll_p, CLK_SRC0, 4, 1),
+ MUX(MOUT_APLL, "mout_apll", mout_apll_p, CLK_SRC0, 0, 1),
+
+ MUX(MOUT_CLKOUT, "mout_clkout", mout_clkout_p, MISC, 8, 2),
+};
+
+/* S5PV210-specific clock muxes. */
+static struct samsung_mux_clock s5pv210_mux_clks[] __initdata = {
+ MUX(MOUT_VPLL, "mout_vpll", mout_vpll_p, CLK_SRC0, 12, 1),
+
+ MUX(MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, CLK_SRC1, 28, 1),
+ MUX(MOUT_CSIS, "mout_csis", mout_group2_p, CLK_SRC1, 24, 4),
+ MUX(MOUT_FIMD, "mout_fimd", mout_group2_p, CLK_SRC1, 20, 4),
+ MUX(MOUT_CAM1, "mout_cam1", mout_group2_p, CLK_SRC1, 16, 4),
+ MUX(MOUT_CAM0, "mout_cam0", mout_group2_p, CLK_SRC1, 12, 4),
+ MUX(MOUT_DAC, "mout_dac", mout_dac_p, CLK_SRC1, 8, 1),
+ MUX(MOUT_MIXER, "mout_mixer", mout_mixer_p, CLK_SRC1, 4, 1),
+ MUX(MOUT_HDMI, "mout_hdmi", mout_hdmi_p, CLK_SRC1, 0, 1),
+
+ MUX(MOUT_G2D, "mout_g2d", mout_group1_p, CLK_SRC2, 8, 2),
+ MUX(MOUT_MFC, "mout_mfc", mout_group1_p, CLK_SRC2, 4, 2),
+ MUX(MOUT_G3D, "mout_g3d", mout_group1_p, CLK_SRC2, 0, 2),
+
+ MUX(MOUT_FIMC2, "mout_fimc2", mout_group2_p, CLK_SRC3, 20, 4),
+ MUX(MOUT_FIMC1, "mout_fimc1", mout_group2_p, CLK_SRC3, 16, 4),
+ MUX(MOUT_FIMC0, "mout_fimc0", mout_group2_p, CLK_SRC3, 12, 4),
+
+ MUX(MOUT_UART3, "mout_uart3", mout_group2_p, CLK_SRC4, 28, 4),
+ MUX(MOUT_UART2, "mout_uart2", mout_group2_p, CLK_SRC4, 24, 4),
+ MUX(MOUT_UART1, "mout_uart1", mout_group2_p, CLK_SRC4, 20, 4),
+ MUX(MOUT_UART0, "mout_uart0", mout_group2_p, CLK_SRC4, 16, 4),
+ MUX(MOUT_MMC3, "mout_mmc3", mout_group2_p, CLK_SRC4, 12, 4),
+ MUX(MOUT_MMC2, "mout_mmc2", mout_group2_p, CLK_SRC4, 8, 4),
+ MUX(MOUT_MMC1, "mout_mmc1", mout_group2_p, CLK_SRC4, 4, 4),
+ MUX(MOUT_MMC0, "mout_mmc0", mout_group2_p, CLK_SRC4, 0, 4),
+
+ MUX(MOUT_PWM, "mout_pwm", mout_group2_p, CLK_SRC5, 12, 4),
+ MUX(MOUT_SPI1, "mout_spi1", mout_group2_p, CLK_SRC5, 4, 4),
+ MUX(MOUT_SPI0, "mout_spi0", mout_group2_p, CLK_SRC5, 0, 4),
+
+ MUX(MOUT_DMC0, "mout_dmc0", mout_group1_p, CLK_SRC6, 24, 2),
+ MUX(MOUT_PWI, "mout_pwi", mout_group2_p, CLK_SRC6, 20, 4),
+ MUX(MOUT_HPM, "mout_hpm", mout_group3_p, CLK_SRC6, 16, 1),
+ MUX(MOUT_SPDIF, "mout_spdif", mout_spdif_p, CLK_SRC6, 12, 2),
+ MUX(MOUT_AUDIO2, "mout_audio2", mout_audio2_p, CLK_SRC6, 8, 4),
+ MUX(MOUT_AUDIO1, "mout_audio1", mout_audio1_p, CLK_SRC6, 4, 4),
+ MUX(MOUT_AUDIO0, "mout_audio0", mout_audio0_p, CLK_SRC6, 0, 4),
+
+ MUX(MOUT_CLKSEL, "mout_clksel", mout_clksel_p, CLK_OUT, 12, 5),
+};
+
+/* S5P6442-specific clock muxes. */
+static struct samsung_mux_clock s5p6442_mux_clks[] __initdata = {
+ MUX(MOUT_VPLL, "mout_vpll", mout_vpll_6442_p, CLK_SRC0, 12, 1),
+
+ MUX(MOUT_FIMD, "mout_fimd", mout_group2_6442_p, CLK_SRC1, 20, 4),
+ MUX(MOUT_CAM1, "mout_cam1", mout_group2_6442_p, CLK_SRC1, 16, 4),
+ MUX(MOUT_CAM0, "mout_cam0", mout_group2_6442_p, CLK_SRC1, 12, 4),
+ MUX(MOUT_MIXER, "mout_mixer", mout_mixer_6442_p, CLK_SRC1, 4, 1),
+
+ MUX(MOUT_D0SYNC, "mout_d0sync", mout_d0sync_6442_p, CLK_SRC2, 28, 1),
+ MUX(MOUT_D1SYNC, "mout_d1sync", mout_d1sync_6442_p, CLK_SRC2, 24, 1),
+
+ MUX(MOUT_FIMC2, "mout_fimc2", mout_group2_6442_p, CLK_SRC3, 20, 4),
+ MUX(MOUT_FIMC1, "mout_fimc1", mout_group2_6442_p, CLK_SRC3, 16, 4),
+ MUX(MOUT_FIMC0, "mout_fimc0", mout_group2_6442_p, CLK_SRC3, 12, 4),
+
+ MUX(MOUT_UART2, "mout_uart2", mout_group2_6442_p, CLK_SRC4, 24, 4),
+ MUX(MOUT_UART1, "mout_uart1", mout_group2_6442_p, CLK_SRC4, 20, 4),
+ MUX(MOUT_UART0, "mout_uart0", mout_group2_6442_p, CLK_SRC4, 16, 4),
+ MUX(MOUT_MMC2, "mout_mmc2", mout_group2_6442_p, CLK_SRC4, 8, 4),
+ MUX(MOUT_MMC1, "mout_mmc1", mout_group2_6442_p, CLK_SRC4, 4, 4),
+ MUX(MOUT_MMC0, "mout_mmc0", mout_group2_6442_p, CLK_SRC4, 0, 4),
+
+ MUX(MOUT_PWM, "mout_pwm", mout_group2_6442_p, CLK_SRC5, 12, 4),
+ MUX(MOUT_SPI0, "mout_spi0", mout_group2_6442_p, CLK_SRC5, 0, 4),
+
+ MUX(MOUT_AUDIO1, "mout_audio1", mout_audio1_6442_p, CLK_SRC6, 4, 4),
+ MUX(MOUT_AUDIO0, "mout_audio0", mout_audio0_6442_p, CLK_SRC6, 0, 4),
+
+ MUX(MOUT_CLKSEL, "mout_clksel", mout_clksel_6442_p, CLK_OUT, 12, 5),
+};
+
+/* S5PV210-specific fixed rate clocks generated inside the SoC. */
+static struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initdata = {
+ FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
+ FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+ FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+ FRATE(SCLK_USBPHY1, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* S5P6442-specific fixed rate clocks generated inside the SoC. */
+static struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initdata = {
+ FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 30000000),
+};
+
+/* Common clock dividers. */
+static struct samsung_div_clock div_clks[] __initdata = {
+ DIV(DOUT_PCLKP, "dout_pclkp", "dout_hclkp", CLK_DIV0, 28, 3),
+ DIV(DOUT_PCLKD, "dout_pclkd", "dout_hclkd", CLK_DIV0, 20, 3),
+ DIV(DOUT_A2M, "dout_a2m", "mout_apll", CLK_DIV0, 4, 3),
+ DIV(DOUT_APLL, "dout_apll", "mout_msys", CLK_DIV0, 0, 3),
+
+ DIV(DOUT_FIMD, "dout_fimd", "mout_fimd", CLK_DIV1, 20, 4),
+ DIV(DOUT_CAM1, "dout_cam1", "mout_cam1", CLK_DIV1, 16, 4),
+ DIV(DOUT_CAM0, "dout_cam0", "mout_cam0", CLK_DIV1, 12, 4),
+
+ DIV(DOUT_FIMC2, "dout_fimc2", "mout_fimc2", CLK_DIV3, 20, 4),
+ DIV(DOUT_FIMC1, "dout_fimc1", "mout_fimc1", CLK_DIV3, 16, 4),
+ DIV(DOUT_FIMC0, "dout_fimc0", "mout_fimc0", CLK_DIV3, 12, 4),
+
+ DIV(DOUT_UART2, "dout_uart2", "mout_uart2", CLK_DIV4, 24, 4),
+ DIV(DOUT_UART1, "dout_uart1", "mout_uart1", CLK_DIV4, 20, 4),
+ DIV(DOUT_UART0, "dout_uart0", "mout_uart0", CLK_DIV4, 16, 4),
+ DIV(DOUT_MMC2, "dout_mmc2", "mout_mmc2", CLK_DIV4, 8, 4),
+ DIV(DOUT_MMC1, "dout_mmc1", "mout_mmc1", CLK_DIV4, 4, 4),
+ DIV(DOUT_MMC0, "dout_mmc0", "mout_mmc0", CLK_DIV4, 0, 4),
+
+ DIV(DOUT_PWM, "dout_pwm", "mout_pwm", CLK_DIV5, 12, 4),
+ DIV(DOUT_SPI0, "dout_spi0", "mout_spi0", CLK_DIV5, 0, 4),
+
+ DIV(DOUT_FLASH, "dout_flash", "mout_flash", CLK_DIV6, 12, 3),
+ DIV(DOUT_AUDIO1, "dout_audio1", "mout_audio1", CLK_DIV6, 4, 4),
+ DIV(DOUT_AUDIO0, "dout_audio0", "mout_audio0", CLK_DIV6, 0, 4),
+
+ DIV(DOUT_CLKOUT, "dout_clkout", "mout_clksel", CLK_OUT, 20, 4),
+};
+
+/* S5PV210-specific clock dividers. */
+static struct samsung_div_clock s5pv210_div_clks[] __initdata = {
+ DIV(DOUT_HCLKP, "dout_hclkp", "mout_psys", CLK_DIV0, 24, 4),
+ DIV(DOUT_HCLKD, "dout_hclkd", "mout_dsys", CLK_DIV0, 16, 4),
+ DIV(DOUT_PCLKM, "dout_pclkm", "dout_hclkm", CLK_DIV0, 12, 3),
+ DIV(DOUT_HCLKM, "dout_hclkm", "dout_apll", CLK_DIV0, 8, 3),
+
+ DIV(DOUT_CSIS, "dout_csis", "mout_csis", CLK_DIV1, 28, 4),
+ DIV(DOUT_TBLK, "dout_tblk", "mout_vpll", CLK_DIV1, 0, 4),
+
+ DIV(DOUT_G2D, "dout_g2d", "mout_g2d", CLK_DIV2, 8, 4),
+ DIV(DOUT_MFC, "dout_mfc", "mout_mfc", CLK_DIV2, 4, 4),
+ DIV(DOUT_G3D, "dout_g3d", "mout_g3d", CLK_DIV2, 0, 4),
+
+ DIV(DOUT_UART3, "dout_uart3", "mout_uart3", CLK_DIV4, 28, 4),
+ DIV(DOUT_MMC3, "dout_mmc3", "mout_mmc3", CLK_DIV4, 12, 4),
+
+ DIV(DOUT_SPI1, "dout_spi1", "mout_spi1", CLK_DIV5, 4, 4),
+
+ DIV(DOUT_DMC0, "dout_dmc0", "mout_dmc0", CLK_DIV6, 28, 4),
+ DIV(DOUT_PWI, "dout_pwi", "mout_pwi", CLK_DIV6, 24, 4),
+ DIV(DOUT_HPM, "dout_hpm", "dout_copy", CLK_DIV6, 20, 3),
+ DIV(DOUT_COPY, "dout_copy", "mout_hpm", CLK_DIV6, 16, 3),
+ DIV(DOUT_AUDIO2, "dout_audio2", "mout_audio2", CLK_DIV6, 8, 4),
+
+ DIV(DOUT_DPM, "dout_dpm", "dout_pclkp", CLK_DIV7, 8, 7),
+ DIV(DOUT_DVSEM, "dout_dvsem", "dout_pclkp", CLK_DIV7, 0, 7),
+};
+
+/* S5P6442-specific clock dividers. */
+static struct samsung_div_clock s5p6442_div_clks[] __initdata = {
+ DIV(DOUT_HCLKP, "dout_hclkp", "mout_d1sync", CLK_DIV0, 24, 4),
+ DIV(DOUT_HCLKD, "dout_hclkd", "mout_d0sync", CLK_DIV0, 16, 4),
+
+ DIV(DOUT_MIXER, "dout_mixer", "mout_vpll", CLK_DIV1, 0, 4),
+};
+
+/* Common clock gates. */
+static struct samsung_gate_clock gate_clks[] __initdata = {
+ GATE(CLK_ROTATOR, "rotator", "dout_hclkd", CLK_GATE_IP0, 29, 0, 0),
+ GATE(CLK_FIMC2, "fimc2", "dout_hclkd", CLK_GATE_IP0, 26, 0, 0),
+ GATE(CLK_FIMC1, "fimc1", "dout_hclkd", CLK_GATE_IP0, 25, 0, 0),
+ GATE(CLK_FIMC0, "fimc0", "dout_hclkd", CLK_GATE_IP0, 24, 0, 0),
+ GATE(CLK_PDMA0, "pdma0", "dout_hclkp", CLK_GATE_IP0, 3, 0, 0),
+ GATE(CLK_MDMA, "mdma", "dout_hclkd", CLK_GATE_IP0, 2, 0, 0),
+
+ GATE(CLK_SROMC, "sromc", "dout_hclkp", CLK_GATE_IP1, 26, 0, 0),
+ GATE(CLK_NANDXL, "nandxl", "dout_hclkp", CLK_GATE_IP1, 24, 0, 0),
+ GATE(CLK_USB_OTG, "usb_otg", "dout_hclkp", CLK_GATE_IP1, 16, 0, 0),
+ GATE(CLK_TVENC, "tvenc", "dout_hclkd", CLK_GATE_IP1, 10, 0, 0),
+ GATE(CLK_MIXER, "mixer", "dout_hclkd", CLK_GATE_IP1, 9, 0, 0),
+ GATE(CLK_VP, "vp", "dout_hclkd", CLK_GATE_IP1, 8, 0, 0),
+ GATE(CLK_FIMD, "fimd", "dout_hclkd", CLK_GATE_IP1, 0, 0, 0),
+
+ GATE(CLK_HSMMC2, "hsmmc2", "dout_hclkp", CLK_GATE_IP2, 18, 0, 0),
+ GATE(CLK_HSMMC1, "hsmmc1", "dout_hclkp", CLK_GATE_IP2, 17, 0, 0),
+ GATE(CLK_HSMMC0, "hsmmc0", "dout_hclkp", CLK_GATE_IP2, 16, 0, 0),
+ GATE(CLK_MODEMIF, "modemif", "dout_hclkp", CLK_GATE_IP2, 9, 0, 0),
+ GATE(CLK_SECSS, "secss", "dout_hclkp", CLK_GATE_IP2, 0, 0, 0),
+
+ GATE(CLK_PCM1, "pcm1", "dout_pclkp", CLK_GATE_IP3, 29, 0, 0),
+ GATE(CLK_PCM0, "pcm0", "dout_pclkp", CLK_GATE_IP3, 28, 0, 0),
+ GATE(CLK_TSADC, "tsadc", "dout_pclkp", CLK_GATE_IP3, 24, 0, 0),
+ GATE(CLK_PWM, "pwm", "dout_pclkp", CLK_GATE_IP3, 23, 0, 0),
+ GATE(CLK_WDT, "watchdog", "dout_pclkp", CLK_GATE_IP3, 22, 0, 0),
+ GATE(CLK_KEYIF, "keyif", "dout_pclkp", CLK_GATE_IP3, 21, 0, 0),
+ GATE(CLK_UART2, "uart2", "dout_pclkp", CLK_GATE_IP3, 19, 0, 0),
+ GATE(CLK_UART1, "uart1", "dout_pclkp", CLK_GATE_IP3, 18, 0, 0),
+ GATE(CLK_UART0, "uart0", "dout_pclkp", CLK_GATE_IP3, 17, 0, 0),
+ GATE(CLK_SYSTIMER, "systimer", "dout_pclkp", CLK_GATE_IP3, 16, 0, 0),
+ GATE(CLK_RTC, "rtc", "dout_pclkp", CLK_GATE_IP3, 15, 0, 0),
+ GATE(CLK_SPI0, "spi0", "dout_pclkp", CLK_GATE_IP3, 12, 0, 0),
+ GATE(CLK_I2C2, "i2c2", "dout_pclkp", CLK_GATE_IP3, 9, 0, 0),
+ GATE(CLK_I2C0, "i2c0", "dout_pclkp", CLK_GATE_IP3, 7, 0, 0),
+ GATE(CLK_I2S1, "i2s1", "dout_pclkp", CLK_GATE_IP3, 5, 0, 0),
+ GATE(CLK_I2S0, "i2s0", "dout_pclkp", CLK_GATE_IP3, 4, 0, 0),
+
+ GATE(CLK_SECKEY, "seckey", "dout_pclkp", CLK_GATE_IP4, 3, 0, 0),
+ GATE(CLK_CHIPID, "chipid", "dout_pclkp", CLK_GATE_IP4, 0, 0, 0),
+
+ GATE(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", CLK_SRC_MASK0, 25,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", CLK_SRC_MASK0, 24,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_PWM, "sclk_pwm", "dout_pwm", CLK_SRC_MASK0, 19,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_SPI0, "sclk_spi0", "dout_spi0", CLK_SRC_MASK0, 16,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_UART2, "sclk_uart2", "dout_uart2", CLK_SRC_MASK0, 14,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_UART1, "sclk_uart1", "dout_uart1", CLK_SRC_MASK0, 13,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_UART0, "sclk_uart0", "dout_uart0", CLK_SRC_MASK0, 12,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", CLK_SRC_MASK0, 10,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", CLK_SRC_MASK0, 9,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", CLK_SRC_MASK0, 8,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_FIMD, "sclk_fimd", "dout_fimd", CLK_SRC_MASK0, 5,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_CAM1, "sclk_cam1", "dout_cam1", CLK_SRC_MASK0, 4,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_CAM0, "sclk_cam0", "dout_cam0", CLK_SRC_MASK0, 3,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_MIXER, "sclk_mixer", "mout_mixer", CLK_SRC_MASK0, 1,
+ CLK_SET_RATE_PARENT, 0),
+
+ GATE(SCLK_FIMC2, "sclk_fimc2", "dout_fimc2", CLK_SRC_MASK1, 4,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_FIMC1, "sclk_fimc1", "dout_fimc1", CLK_SRC_MASK1, 3,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_FIMC0, "sclk_fimc0", "dout_fimc0", CLK_SRC_MASK1, 2,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+/* S5PV210-specific clock gates. */
+static struct samsung_gate_clock s5pv210_gate_clks[] __initdata = {
+ GATE(CLK_CSIS, "clk_csis", "dout_hclkd", CLK_GATE_IP0, 31, 0, 0),
+ GATE(CLK_MFC, "mfc", "dout_hclkm", CLK_GATE_IP0, 16, 0, 0),
+ GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0),
+ GATE(CLK_G3D, "g3d", "dout_hclkm", CLK_GATE_IP0, 8, 0, 0),
+ GATE(CLK_IMEM, "imem", "dout_hclkm", CLK_GATE_IP0, 5, 0, 0),
+ GATE(CLK_PDMA1, "pdma1", "dout_hclkp", CLK_GATE_IP0, 4, 0, 0),
+
+ GATE(CLK_NFCON, "nfcon", "dout_hclkp", CLK_GATE_IP1, 28, 0, 0),
+ GATE(CLK_CFCON, "cfcon", "dout_hclkp", CLK_GATE_IP1, 25, 0, 0),
+ GATE(CLK_USB_HOST, "usb_host", "dout_hclkp", CLK_GATE_IP1, 17, 0, 0),
+ GATE(CLK_HDMI, "hdmi", "dout_hclkd", CLK_GATE_IP1, 11, 0, 0),
+ GATE(CLK_DSIM, "dsim", "dout_pclkd", CLK_GATE_IP1, 2, 0, 0),
+
+ GATE(CLK_TZIC3, "tzic3", "dout_hclkm", CLK_GATE_IP2, 31, 0, 0),
+ GATE(CLK_TZIC2, "tzic2", "dout_hclkm", CLK_GATE_IP2, 30, 0, 0),
+ GATE(CLK_TZIC1, "tzic1", "dout_hclkm", CLK_GATE_IP2, 29, 0, 0),
+ GATE(CLK_TZIC0, "tzic0", "dout_hclkm", CLK_GATE_IP2, 28, 0, 0),
+ GATE(CLK_TSI, "tsi", "dout_hclkd", CLK_GATE_IP2, 20, 0, 0),
+ GATE(CLK_HSMMC3, "hsmmc3", "dout_hclkp", CLK_GATE_IP2, 19, 0, 0),
+ GATE(CLK_JTAG, "jtag", "dout_hclkp", CLK_GATE_IP2, 11, 0, 0),
+ GATE(CLK_CORESIGHT, "coresight", "dout_pclkp", CLK_GATE_IP2, 8, 0, 0),
+ GATE(CLK_SDM, "sdm", "dout_pclkm", CLK_GATE_IP2, 1, 0, 0),
+
+ GATE(CLK_PCM2, "pcm2", "dout_pclkp", CLK_GATE_IP3, 30, 0, 0),
+ GATE(CLK_UART3, "uart3", "dout_pclkp", CLK_GATE_IP3, 20, 0, 0),
+ GATE(CLK_SPI1, "spi1", "dout_pclkp", CLK_GATE_IP3, 13, 0, 0),
+ GATE(CLK_I2C_HDMI_PHY, "i2c_hdmi_phy", "dout_pclkd",
+ CLK_GATE_IP3, 11, 0, 0),
+ GATE(CLK_I2C1, "i2c1", "dout_pclkd", CLK_GATE_IP3, 10, 0, 0),
+ GATE(CLK_I2S2, "i2s2", "dout_pclkp", CLK_GATE_IP3, 6, 0, 0),
+ GATE(CLK_AC97, "ac97", "dout_pclkp", CLK_GATE_IP3, 1, 0, 0),
+ GATE(CLK_SPDIF, "spdif", "dout_pclkp", CLK_GATE_IP3, 0, 0, 0),
+
+ GATE(CLK_TZPC3, "tzpc.3", "dout_pclkd", CLK_GATE_IP4, 8, 0, 0),
+ GATE(CLK_TZPC2, "tzpc.2", "dout_pclkd", CLK_GATE_IP4, 7, 0, 0),
+ GATE(CLK_TZPC1, "tzpc.1", "dout_pclkp", CLK_GATE_IP4, 6, 0, 0),
+ GATE(CLK_TZPC0, "tzpc.0", "dout_pclkm", CLK_GATE_IP4, 5, 0, 0),
+ GATE(CLK_IEM_APC, "iem_apc", "dout_pclkp", CLK_GATE_IP4, 2, 0, 0),
+ GATE(CLK_IEM_IEC, "iem_iec", "dout_pclkp", CLK_GATE_IP4, 1, 0, 0),
+
+ GATE(CLK_JPEG, "jpeg", "dout_hclkd", CLK_GATE_IP5, 29, 0, 0),
+
+ GATE(SCLK_SPDIF, "sclk_spdif", "mout_spdif", CLK_SRC_MASK0, 27,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", CLK_SRC_MASK0, 26,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_SPI1, "sclk_spi1", "dout_spi1", CLK_SRC_MASK0, 17,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_UART3, "sclk_uart3", "dout_uart3", CLK_SRC_MASK0, 15,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_MMC3, "sclk_mmc3", "dout_mmc3", CLK_SRC_MASK0, 11,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_CSIS, "sclk_csis", "dout_csis", CLK_SRC_MASK0, 6,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_DAC, "sclk_dac", "mout_dac", CLK_SRC_MASK0, 2,
+ CLK_SET_RATE_PARENT, 0),
+ GATE(SCLK_HDMI, "sclk_hdmi", "mout_hdmi", CLK_SRC_MASK0, 0,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+/* S5P6442-specific clock gates. */
+static struct samsung_gate_clock s5p6442_gate_clks[] __initdata = {
+ GATE(CLK_JPEG, "jpeg", "dout_hclkd", CLK_GATE_IP0, 28, 0, 0),
+ GATE(CLK_MFC, "mfc", "dout_hclkd", CLK_GATE_IP0, 16, 0, 0),
+ GATE(CLK_G2D, "g2d", "dout_hclkd", CLK_GATE_IP0, 12, 0, 0),
+ GATE(CLK_G3D, "g3d", "dout_hclkd", CLK_GATE_IP0, 8, 0, 0),
+ GATE(CLK_IMEM, "imem", "dout_hclkd", CLK_GATE_IP0, 5, 0, 0),
+
+ GATE(CLK_ETB, "etb", "dout_hclkd", CLK_GATE_IP1, 31, 0, 0),
+ GATE(CLK_ETM, "etm", "dout_hclkd", CLK_GATE_IP1, 30, 0, 0),
+
+ GATE(CLK_I2C1, "i2c1", "dout_pclkp", CLK_GATE_IP3, 8, 0, 0),
+
+ GATE(SCLK_DAC, "sclk_dac", "mout_vpll", CLK_SRC_MASK0, 2,
+ CLK_SET_RATE_PARENT, 0),
+};
+
+/*
+ * Clock aliases for legacy clkdev look-up.
+ * NOTE: Needed only to support legacy board files.
+ */
+static struct samsung_clock_alias s5pv210_aliases[] = {
+ ALIAS(DOUT_APLL, NULL, "armclk"),
+ ALIAS(DOUT_HCLKM, NULL, "hclk_msys"),
+ ALIAS(MOUT_DMC0, NULL, "sclk_dmc0"),
+};
+
+/* S5PV210-specific PLLs. */
+static struct samsung_pll_clock s5pv210_pll_clks[] __initdata = {
+ [apll] = PLL(pll_4508, FOUT_APLL, "fout_apll", "fin_pll",
+ APLL_LOCK, APLL_CON0, NULL),
+ [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll",
+ MPLL_LOCK, MPLL_CON, NULL),
+ [epll] = PLL(pll_4600, FOUT_EPLL, "fout_epll", "fin_pll",
+ EPLL_LOCK, EPLL_CON0, NULL),
+ [vpll] = PLL(pll_4502, FOUT_VPLL, "fout_vpll", "mout_vpllsrc",
+ VPLL_LOCK, VPLL_CON, NULL),
+};
+
+/* S5P6442-specific PLLs. */
+static struct samsung_pll_clock s5p6442_pll_clks[] __initdata = {
+ [apll] = PLL(pll_4502, FOUT_APLL, "fout_apll", "fin_pll",
+ APLL_LOCK, APLL_CON0, NULL),
+ [mpll] = PLL(pll_4502, FOUT_MPLL, "fout_mpll", "fin_pll",
+ MPLL_LOCK, MPLL_CON, NULL),
+ [epll] = PLL(pll_4500, FOUT_EPLL, "fout_epll", "fin_pll",
+ EPLL_LOCK, EPLL_CON0, NULL),
+ [vpll] = PLL(pll_4500, FOUT_VPLL, "fout_vpll", "fin_pll",
+ VPLL_LOCK, VPLL_CON, NULL),
+};
+
+static void __init __s5pv210_clk_init(struct device_node *np,
+ unsigned long xxti_f,
+ unsigned long xusbxti_f,
+ bool is_s5p6442)
+{
+ struct samsung_clk_provider *ctx;
+
+ ctx = samsung_clk_init(np, reg_base, NR_CLKS);
+ if (!ctx)
+ panic("%s: unable to allocate context.\n", __func__);
+
+ samsung_clk_register_mux(ctx, early_mux_clks,
+ ARRAY_SIZE(early_mux_clks));
+
+ if (is_s5p6442) {
+ samsung_clk_register_fixed_rate(ctx, s5p6442_frate_clks,
+ ARRAY_SIZE(s5p6442_frate_clks));
+ samsung_clk_register_pll(ctx, s5p6442_pll_clks,
+ ARRAY_SIZE(s5p6442_pll_clks), reg_base);
+ samsung_clk_register_mux(ctx, s5p6442_mux_clks,
+ ARRAY_SIZE(s5p6442_mux_clks));
+ samsung_clk_register_div(ctx, s5p6442_div_clks,
+ ARRAY_SIZE(s5p6442_div_clks));
+ samsung_clk_register_gate(ctx, s5p6442_gate_clks,
+ ARRAY_SIZE(s5p6442_gate_clks));
+ } else {
+ samsung_clk_register_fixed_rate(ctx, s5pv210_frate_clks,
+ ARRAY_SIZE(s5pv210_frate_clks));
+ samsung_clk_register_pll(ctx, s5pv210_pll_clks,
+ ARRAY_SIZE(s5pv210_pll_clks), reg_base);
+ samsung_clk_register_mux(ctx, s5pv210_mux_clks,
+ ARRAY_SIZE(s5pv210_mux_clks));
+ samsung_clk_register_div(ctx, s5pv210_div_clks,
+ ARRAY_SIZE(s5pv210_div_clks));
+ samsung_clk_register_gate(ctx, s5pv210_gate_clks,
+ ARRAY_SIZE(s5pv210_gate_clks));
+ }
+
+ samsung_clk_register_mux(ctx, mux_clks, ARRAY_SIZE(mux_clks));
+ samsung_clk_register_div(ctx, div_clks, ARRAY_SIZE(div_clks));
+ samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks));
+
+ samsung_clk_register_fixed_factor(ctx, ffactor_clks,
+ ARRAY_SIZE(ffactor_clks));
+
+ samsung_clk_register_alias(ctx, s5pv210_aliases,
+ ARRAY_SIZE(s5pv210_aliases));
+
+ s5pv210_clk_sleep_init();
+
+ pr_info("%s clocks: mout_apll = %ld, mout_mpll = %ld\n"
+ "\tmout_epll = %ld, mout_vpll = %ld\n",
+ is_s5p6442 ? "S5P6442" : "S5PV210",
+ _get_rate("mout_apll"), _get_rate("mout_mpll"),
+ _get_rate("mout_epll"), _get_rate("mout_vpll"));
+}
+
+static void __init s5pv210_clk_dt_init(struct device_node *np)
+{
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+
+ __s5pv210_clk_init(np, 0, 0, false);
+}
+CLK_OF_DECLARE(s5pv210_clk, "samsung,s5pv210-clock", s5pv210_clk_dt_init);
+
+static void __init s5p6442_clk_dt_init(struct device_node *np)
+{
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+
+ __s5pv210_clk_init(np, 0, 0, true);
+}
+CLK_OF_DECLARE(s5p6442_clk, "samsung,s5p6442-clock", s5p6442_clk_dt_init);
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index 49629c71c9e7..deab84d9f37d 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -53,7 +53,6 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
{
struct samsung_clk_provider *ctx;
struct clk **clk_table;
- int ret;
int i;
ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL);
@@ -72,17 +71,19 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
ctx->clk_data.clk_num = nr_clks;
spin_lock_init(&ctx->lock);
- if (!np)
- return ctx;
-
- ret = of_clk_add_provider(np, of_clk_src_onecell_get,
- &ctx->clk_data);
- if (ret)
- panic("could not register clock provide\n");
-
return ctx;
}
+void __init samsung_clk_of_add_provider(struct device_node *np,
+ struct samsung_clk_provider *ctx)
+{
+ if (np) {
+ if (of_clk_add_provider(np, of_clk_src_onecell_get,
+ &ctx->clk_data))
+ panic("could not register clk provider\n");
+ }
+}
+
/* add a clock instance to the clock lookup table used for dt based lookup */
void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk,
unsigned int id)
@@ -284,7 +285,7 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx,
struct samsung_fixed_rate_clock *fixed_rate_clk,
unsigned int nr_fixed_rate_clk,
- struct of_device_id *clk_matches)
+ const struct of_device_id *clk_matches)
{
const struct of_device_id *match;
struct device_node *clk_np;
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 9693b80d924f..66ab36b5cef1 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -327,11 +327,13 @@ struct samsung_pll_clock {
extern struct samsung_clk_provider *__init samsung_clk_init(
struct device_node *np, void __iomem *base,
unsigned long nr_clks);
+extern void __init samsung_clk_of_add_provider(struct device_node *np,
+ struct samsung_clk_provider *ctx);
extern void __init samsung_clk_of_register_fixed_ext(
struct samsung_clk_provider *ctx,
struct samsung_fixed_rate_clock *fixed_rate_clk,
unsigned int nr_fixed_rate_clk,
- struct of_device_id *clk_matches);
+ const struct of_device_id *clk_matches);
extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
struct clk *clk, unsigned int id);
diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c
index 65894f7687ed..4daa5977793a 100644
--- a/drivers/clk/spear/spear1310_clock.c
+++ b/drivers/clk/spear/spear1310_clock.c
@@ -742,19 +742,19 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB,
0, &_lock);
- clk_register_clkdev(clk, NULL, "dw_pcie.0");
+ clk_register_clkdev(clk, NULL, "b1000000.pcie");
clk_register_clkdev(clk, NULL, "b1000000.ahci");
clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB,
0, &_lock);
- clk_register_clkdev(clk, NULL, "dw_pcie.1");
+ clk_register_clkdev(clk, NULL, "b1800000.pcie");
clk_register_clkdev(clk, NULL, "b1800000.ahci");
clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0,
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB,
0, &_lock);
- clk_register_clkdev(clk, NULL, "dw_pcie.2");
+ clk_register_clkdev(clk, NULL, "b4000000.pcie");
clk_register_clkdev(clk, NULL, "b4000000.ahci");
clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index fe835c1845fe..5a5c6648308d 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -839,7 +839,7 @@ void __init spear1340_clk_init(void __iomem *misc_base)
clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0,
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB,
0, &_lock);
- clk_register_clkdev(clk, NULL, "dw_pcie");
+ clk_register_clkdev(clk, NULL, "b1000000.pcie");
clk_register_clkdev(clk, NULL, "b1000000.ahci");
clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c
index c2d204315546..bb5f387774e2 100644
--- a/drivers/clk/spear/spear3xx_clock.c
+++ b/drivers/clk/spear/spear3xx_clock.c
@@ -211,7 +211,7 @@ static inline void spear310_clk_init(void) { }
/* array of all spear 320 clock lookups */
#ifdef CONFIG_MACH_SPEAR320
-#define SPEAR320_CONTROL_REG (soc_config_base + 0x0000)
+#define SPEAR320_CONTROL_REG (soc_config_base + 0x0010)
#define SPEAR320_EXT_CTRL_REG (soc_config_base + 0x0018)
#define SPEAR320_UARTX_PCLK_MASK 0x1
@@ -245,7 +245,8 @@ static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk",
"ras_syn0_gclk", };
static const char *uartx_parents[] = { "ras_syn1_gclk", "ras_apb_clk", };
-static void __init spear320_clk_init(void __iomem *soc_config_base)
+static void __init spear320_clk_init(void __iomem *soc_config_base,
+ struct clk *ras_apb_clk)
{
struct clk *clk;
@@ -342,6 +343,8 @@ static void __init spear320_clk_init(void __iomem *soc_config_base)
SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK,
0, &_lock);
clk_register_clkdev(clk, NULL, "a3000000.serial");
+ /* Enforce ras_apb_clk */
+ clk_set_parent(clk, ras_apb_clk);
clk = clk_register_mux(NULL, "uart2_clk", uartx_parents,
ARRAY_SIZE(uartx_parents),
@@ -349,6 +352,8 @@ static void __init spear320_clk_init(void __iomem *soc_config_base)
SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT,
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
clk_register_clkdev(clk, NULL, "a4000000.serial");
+ /* Enforce ras_apb_clk */
+ clk_set_parent(clk, ras_apb_clk);
clk = clk_register_mux(NULL, "uart3_clk", uartx_parents,
ARRAY_SIZE(uartx_parents),
@@ -379,12 +384,12 @@ static void __init spear320_clk_init(void __iomem *soc_config_base)
clk_register_clkdev(clk, NULL, "60100000.serial");
}
#else
-static inline void spear320_clk_init(void __iomem *soc_config_base) { }
+static inline void spear320_clk_init(void __iomem *sb, struct clk *rc) { }
#endif
void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_base)
{
- struct clk *clk, *clk1;
+ struct clk *clk, *clk1, *ras_apb_clk;
clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
32000);
@@ -613,6 +618,7 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
clk = clk_register_gate(NULL, "ras_apb_clk", "apb_clk", 0, RAS_CLK_ENB,
RAS_APB_CLK_ENB, 0, &_lock);
clk_register_clkdev(clk, "ras_apb_clk", NULL);
+ ras_apb_clk = clk;
clk = clk_register_gate(NULL, "ras_32k_clk", "osc_32k_clk", 0,
RAS_CLK_ENB, RAS_32K_CLK_ENB, 0, &_lock);
@@ -659,5 +665,5 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
else if (of_machine_is_compatible("st,spear310"))
spear310_clk_init();
else if (of_machine_is_compatible("st,spear320"))
- spear320_clk_init(soc_config_base);
+ spear320_clk_init(soc_config_base, ras_apb_clk);
}
diff --git a/drivers/clk/st/Makefile b/drivers/clk/st/Makefile
index c7455ffdbdf7..ede7b2f13092 100644
--- a/drivers/clk/st/Makefile
+++ b/drivers/clk/st/Makefile
@@ -1 +1 @@
-obj-y += clkgen-mux.o clkgen-pll.o clkgen-fsyn.o
+obj-y += clkgen-mux.o clkgen-pll.o clkgen-fsyn.o clk-flexgen.o
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
new file mode 100644
index 000000000000..2282cef9f2ff
--- /dev/null
+++ b/drivers/clk/st/clk-flexgen.c
@@ -0,0 +1,331 @@
+/*
+ * clk-flexgen.c
+ *
+ * Copyright (C) ST-Microelectronics SA 2013
+ * Author: Maxime Coquelin <maxime.coquelin@st.com> for ST-Microelectronics.
+ * License terms: GNU General Public License (GPL), version 2 */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+struct flexgen {
+ struct clk_hw hw;
+
+ /* Crossbar */
+ struct clk_mux mux;
+ /* Pre-divisor's gate */
+ struct clk_gate pgate;
+ /* Pre-divisor */
+ struct clk_divider pdiv;
+ /* Final divisor's gate */
+ struct clk_gate fgate;
+ /* Final divisor */
+ struct clk_divider fdiv;
+};
+
+#define to_flexgen(_hw) container_of(_hw, struct flexgen, hw)
+
+static int flexgen_enable(struct clk_hw *hw)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *pgate_hw = &flexgen->pgate.hw;
+ struct clk_hw *fgate_hw = &flexgen->fgate.hw;
+
+ pgate_hw->clk = hw->clk;
+ fgate_hw->clk = hw->clk;
+
+ clk_gate_ops.enable(pgate_hw);
+
+ clk_gate_ops.enable(fgate_hw);
+
+ pr_debug("%s: flexgen output enabled\n", __clk_get_name(hw->clk));
+ return 0;
+}
+
+static void flexgen_disable(struct clk_hw *hw)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *fgate_hw = &flexgen->fgate.hw;
+
+ /* disable only the final gate */
+ fgate_hw->clk = hw->clk;
+
+ clk_gate_ops.disable(fgate_hw);
+
+ pr_debug("%s: flexgen output disabled\n", __clk_get_name(hw->clk));
+}
+
+static int flexgen_is_enabled(struct clk_hw *hw)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *fgate_hw = &flexgen->fgate.hw;
+
+ fgate_hw->clk = hw->clk;
+
+ if (!clk_gate_ops.is_enabled(fgate_hw))
+ return 0;
+
+ return 1;
+}
+
+static u8 flexgen_get_parent(struct clk_hw *hw)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *mux_hw = &flexgen->mux.hw;
+
+ mux_hw->clk = hw->clk;
+
+ return clk_mux_ops.get_parent(mux_hw);
+}
+
+static int flexgen_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *mux_hw = &flexgen->mux.hw;
+
+ mux_hw->clk = hw->clk;
+
+ return clk_mux_ops.set_parent(mux_hw, index);
+}
+
+static inline unsigned long
+clk_best_div(unsigned long parent_rate, unsigned long rate)
+{
+ return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1);
+}
+
+static long flexgen_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long div;
+
+ /* Round div according to exact prate and wished rate */
+ div = clk_best_div(*prate, rate);
+
+ if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
+ *prate = rate * div;
+ return rate;
+ }
+
+ return *prate / div;
+}
+
+unsigned long flexgen_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
+ struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
+ unsigned long mid_rate;
+
+ pdiv_hw->clk = hw->clk;
+ fdiv_hw->clk = hw->clk;
+
+ mid_rate = clk_divider_ops.recalc_rate(pdiv_hw, parent_rate);
+
+ return clk_divider_ops.recalc_rate(fdiv_hw, mid_rate);
+}
+
+static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct flexgen *flexgen = to_flexgen(hw);
+ struct clk_hw *pdiv_hw = &flexgen->pdiv.hw;
+ struct clk_hw *fdiv_hw = &flexgen->fdiv.hw;
+ unsigned long primary_div = 0;
+ int ret = 0;
+
+ pdiv_hw->clk = hw->clk;
+ fdiv_hw->clk = hw->clk;
+
+ primary_div = clk_best_div(parent_rate, rate);
+
+ clk_divider_ops.set_rate(fdiv_hw, parent_rate, parent_rate);
+ ret = clk_divider_ops.set_rate(pdiv_hw, rate, rate * primary_div);
+
+ return ret;
+}
+
+static const struct clk_ops flexgen_ops = {
+ .enable = flexgen_enable,
+ .disable = flexgen_disable,
+ .is_enabled = flexgen_is_enabled,
+ .get_parent = flexgen_get_parent,
+ .set_parent = flexgen_set_parent,
+ .round_rate = flexgen_round_rate,
+ .recalc_rate = flexgen_recalc_rate,
+ .set_rate = flexgen_set_rate,
+};
+
+struct clk *clk_register_flexgen(const char *name,
+ const char **parent_names, u8 num_parents,
+ void __iomem *reg, spinlock_t *lock, u32 idx,
+ unsigned long flexgen_flags) {
+ struct flexgen *fgxbar;
+ struct clk *clk;
+ struct clk_init_data init;
+ u32 xbar_shift;
+ void __iomem *xbar_reg, *fdiv_reg;
+
+ fgxbar = kzalloc(sizeof(struct flexgen), GFP_KERNEL);
+ if (!fgxbar)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &flexgen_ops;
+ init.flags = CLK_IS_BASIC | flexgen_flags;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ xbar_reg = reg + 0x18 + (idx & ~0x3);
+ xbar_shift = (idx % 4) * 0x8;
+ fdiv_reg = reg + 0x164 + idx * 4;
+
+ /* Crossbar element config */
+ fgxbar->mux.lock = lock;
+ fgxbar->mux.mask = BIT(6) - 1;
+ fgxbar->mux.reg = xbar_reg;
+ fgxbar->mux.shift = xbar_shift;
+ fgxbar->mux.table = NULL;
+
+
+ /* Pre-divider's gate config (in xbar register)*/
+ fgxbar->pgate.lock = lock;
+ fgxbar->pgate.reg = xbar_reg;
+ fgxbar->pgate.bit_idx = xbar_shift + 6;
+
+ /* Pre-divider config */
+ fgxbar->pdiv.lock = lock;
+ fgxbar->pdiv.reg = reg + 0x58 + idx * 4;
+ fgxbar->pdiv.width = 10;
+
+ /* Final divider's gate config */
+ fgxbar->fgate.lock = lock;
+ fgxbar->fgate.reg = fdiv_reg;
+ fgxbar->fgate.bit_idx = 6;
+
+ /* Final divider config */
+ fgxbar->fdiv.lock = lock;
+ fgxbar->fdiv.reg = fdiv_reg;
+ fgxbar->fdiv.width = 6;
+
+ fgxbar->hw.init = &init;
+
+ clk = clk_register(NULL, &fgxbar->hw);
+ if (IS_ERR(clk))
+ kfree(fgxbar);
+ else
+ pr_debug("%s: parent %s rate %u\n",
+ __clk_get_name(clk),
+ __clk_get_name(clk_get_parent(clk)),
+ (unsigned int)clk_get_rate(clk));
+ return clk;
+}
+
+static const char ** __init flexgen_get_parents(struct device_node *np,
+ int *num_parents)
+{
+ const char **parents;
+ int nparents, i;
+
+ nparents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
+ if (WARN_ON(nparents <= 0))
+ return NULL;
+
+ parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL);
+ if (!parents)
+ return NULL;
+
+ for (i = 0; i < nparents; i++)
+ parents[i] = of_clk_get_parent_name(np, i);
+
+ *num_parents = nparents;
+ return parents;
+}
+
+void __init st_of_flexgen_setup(struct device_node *np)
+{
+ struct device_node *pnode;
+ void __iomem *reg;
+ struct clk_onecell_data *clk_data;
+ const char **parents;
+ int num_parents, i;
+ spinlock_t *rlock = NULL;
+ unsigned long flex_flags = 0;
+
+ pnode = of_get_parent(np);
+ if (!pnode)
+ return;
+
+ reg = of_iomap(pnode, 0);
+ if (!reg)
+ return;
+
+ parents = flexgen_get_parents(np, &num_parents);
+ if (!parents)
+ return;
+
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ goto err;
+
+ clk_data->clk_num = of_property_count_strings(np ,
+ "clock-output-names");
+ if (clk_data->clk_num <= 0) {
+ pr_err("%s: Failed to get number of output clocks (%d)",
+ __func__, clk_data->clk_num);
+ goto err;
+ }
+
+ clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
+ GFP_KERNEL);
+ if (!clk_data->clks)
+ goto err;
+
+ rlock = kzalloc(sizeof(spinlock_t), GFP_KERNEL);
+ if (!rlock)
+ goto err;
+
+ for (i = 0; i < clk_data->clk_num; i++) {
+ struct clk *clk;
+ const char *clk_name;
+
+ if (of_property_read_string_index(np, "clock-output-names",
+ i, &clk_name)) {
+ break;
+ }
+
+ /*
+ * If we read an empty clock name then the output is unused
+ */
+ if (*clk_name == '\0')
+ continue;
+
+ clk = clk_register_flexgen(clk_name, parents, num_parents,
+ reg, rlock, i, flex_flags);
+
+ if (IS_ERR(clk))
+ goto err;
+
+ clk_data->clks[i] = clk;
+ }
+
+ kfree(parents);
+ of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+
+ return;
+
+err:
+ if (clk_data)
+ kfree(clk_data->clks);
+ kfree(clk_data);
+ kfree(parents);
+ kfree(rlock);
+}
+CLK_OF_DECLARE(flexgen, "st,flexgen", st_of_flexgen_setup);
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index 4f53ee0778d9..af94ed82cfcb 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -41,7 +41,7 @@ struct stm_fs {
unsigned long nsdiv;
};
-static struct stm_fs fs216c65_rtbl[] = {
+static const struct stm_fs fs216c65_rtbl[] = {
{ .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 312.5 Khz */
{ .mdiv = 0x17, .pe = 0x25ed, .sdiv = 0x1, .nsdiv = 0 }, /* 27 MHz */
{ .mdiv = 0x1a, .pe = 0x7b36, .sdiv = 0x2, .nsdiv = 1 }, /* 36.87 MHz */
@@ -49,31 +49,86 @@ static struct stm_fs fs216c65_rtbl[] = {
{ .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x1, .nsdiv = 1 }, /* 108 MHz */
};
-static struct stm_fs fs432c65_rtbl[] = {
- { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 625 Khz */
- { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x2, .nsdiv = 1 }, /* 108 MHz */
- { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x0, .nsdiv = 1 }, /* 297 MHz */
+static const struct stm_fs fs432c65_rtbl[] = {
+ { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 625 Khz */
+ { .mdiv = 0x13, .pe = 0x777c, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */
+ { .mdiv = 0x19, .pe = 0x4d35, .sdiv = 0x2, .nsdiv = 0 }, /* 25.200 MHz */
+ { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x4, .nsdiv = 1 }, /* 27.000 MHz */
+ { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x2, .nsdiv = 0 }, /* 27.027 MHz */
+ { .mdiv = 0x16, .pe = 0x3359, .sdiv = 0x2, .nsdiv = 0 }, /* 28.320 MHz */
+ { .mdiv = 0x1f, .pe = 0x2083, .sdiv = 0x3, .nsdiv = 1 }, /* 30.240 MHz */
+ { .mdiv = 0x1e, .pe = 0x430d, .sdiv = 0x3, .nsdiv = 1 }, /* 31.500 MHz */
+ { .mdiv = 0x17, .pe = 0x0, .sdiv = 0x3, .nsdiv = 1 }, /* 40.000 MHz */
+ { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 0 }, /* 49.500 MHz */
+ { .mdiv = 0x13, .pe = 0x6667, .sdiv = 0x3, .nsdiv = 1 }, /* 50.000 MHz */
+ { .mdiv = 0x10, .pe = 0x1ee6, .sdiv = 0x3, .nsdiv = 1 }, /* 57.284 MHz */
+ { .mdiv = 0x1d, .pe = 0x3b14, .sdiv = 0x2, .nsdiv = 1 }, /* 65.000 MHz */
+ { .mdiv = 0x12, .pe = 0x7c65, .sdiv = 0x1, .nsdiv = 0 }, /* 71.000 MHz */
+ { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x2, .nsdiv = 1 }, /* 74.176 MHz */
+ { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x2, .nsdiv = 1 }, /* 74.250 MHz */
+ { .mdiv = 0x19, .pe = 0x3334, .sdiv = 0x2, .nsdiv = 1 }, /* 75.000 MHz */
+ { .mdiv = 0x18, .pe = 0x5138, .sdiv = 0x2, .nsdiv = 1 }, /* 78.800 MHz */
+ { .mdiv = 0x1d, .pe = 0x77d, .sdiv = 0x0, .nsdiv = 0 }, /* 85.500 MHz */
+ { .mdiv = 0x1c, .pe = 0x13d5, .sdiv = 0x0, .nsdiv = 0 }, /* 88.750 MHz */
+ { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x2, .nsdiv = 1 }, /* 108.000 MHz */
+ { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x0, .nsdiv = 0 }, /* 108.108 MHz */
+ { .mdiv = 0x10, .pe = 0x6e26, .sdiv = 0x2, .nsdiv = 1 }, /* 118.963 MHz */
+ { .mdiv = 0x15, .pe = 0x3e63, .sdiv = 0x0, .nsdiv = 0 }, /* 119.000 MHz */
+ { .mdiv = 0x1c, .pe = 0x471d, .sdiv = 0x1, .nsdiv = 1 }, /* 135.000 MHz */
+ { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x1, .nsdiv = 1 }, /* 148.352 MHz */
+ { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 1 }, /* 148.500 MHz */
+ { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x0, .nsdiv = 1 }, /* 297 MHz */
};
-static struct stm_fs fs660c32_rtbl[] = {
- { .mdiv = 0x01, .pe = 0x2aaa, .sdiv = 0x8, .nsdiv = 0 }, /* 600 KHz */
- { .mdiv = 0x02, .pe = 0x3d33, .sdiv = 0x0, .nsdiv = 0 }, /* 148.5 Mhz */
- { .mdiv = 0x13, .pe = 0x5bcc, .sdiv = 0x0, .nsdiv = 1 }, /* 297 Mhz */
- { .mdiv = 0x0e, .pe = 0x1025, .sdiv = 0x0, .nsdiv = 1 }, /* 333 Mhz */
- { .mdiv = 0x0b, .pe = 0x715f, .sdiv = 0x0, .nsdiv = 1 }, /* 350 Mhz */
+static const struct stm_fs fs660c32_rtbl[] = {
+ { .mdiv = 0x14, .pe = 0x376b, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */
+ { .mdiv = 0x14, .pe = 0x30c3, .sdiv = 0x4, .nsdiv = 1 }, /* 25.200 MHz */
+ { .mdiv = 0x10, .pe = 0x71c7, .sdiv = 0x4, .nsdiv = 1 }, /* 27.000 MHz */
+ { .mdiv = 0x00, .pe = 0x47af, .sdiv = 0x3, .nsdiv = 0 }, /* 27.027 MHz */
+ { .mdiv = 0x0e, .pe = 0x4e1a, .sdiv = 0x4, .nsdiv = 1 }, /* 28.320 MHz */
+ { .mdiv = 0x0b, .pe = 0x534d, .sdiv = 0x4, .nsdiv = 1 }, /* 30.240 MHz */
+ { .mdiv = 0x17, .pe = 0x6fbf, .sdiv = 0x2, .nsdiv = 0 }, /* 31.500 MHz */
+ { .mdiv = 0x01, .pe = 0x0, .sdiv = 0x4, .nsdiv = 1 }, /* 40.000 MHz */
+ { .mdiv = 0x15, .pe = 0x2aab, .sdiv = 0x3, .nsdiv = 1 }, /* 49.500 MHz */
+ { .mdiv = 0x14, .pe = 0x6666, .sdiv = 0x3, .nsdiv = 1 }, /* 50.000 MHz */
+ { .mdiv = 0x1d, .pe = 0x395f, .sdiv = 0x1, .nsdiv = 0 }, /* 57.284 MHz */
+ { .mdiv = 0x08, .pe = 0x4ec5, .sdiv = 0x3, .nsdiv = 1 }, /* 65.000 MHz */
+ { .mdiv = 0x05, .pe = 0x1770, .sdiv = 0x3, .nsdiv = 1 }, /* 71.000 MHz */
+ { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x3, .nsdiv = 1 }, /* 74.176 MHz */
+ { .mdiv = 0x0f, .pe = 0x3426, .sdiv = 0x1, .nsdiv = 0 }, /* 74.250 MHz */
+ { .mdiv = 0x0e, .pe = 0x7777, .sdiv = 0x1, .nsdiv = 0 }, /* 75.000 MHz */
+ { .mdiv = 0x01, .pe = 0x4053, .sdiv = 0x3, .nsdiv = 1 }, /* 78.800 MHz */
+ { .mdiv = 0x09, .pe = 0x15b5, .sdiv = 0x1, .nsdiv = 0 }, /* 85.500 MHz */
+ { .mdiv = 0x1b, .pe = 0x3f19, .sdiv = 0x2, .nsdiv = 1 }, /* 88.750 MHz */
+ { .mdiv = 0x10, .pe = 0x71c7, .sdiv = 0x2, .nsdiv = 1 }, /* 108.000 MHz */
+ { .mdiv = 0x00, .pe = 0x47af, .sdiv = 0x1, .nsdiv = 0 }, /* 108.108 MHz */
+ { .mdiv = 0x0c, .pe = 0x3118, .sdiv = 0x2, .nsdiv = 1 }, /* 118.963 MHz */
+ { .mdiv = 0x0c, .pe = 0x2f54, .sdiv = 0x2, .nsdiv = 1 }, /* 119.000 MHz */
+ { .mdiv = 0x07, .pe = 0xe39, .sdiv = 0x2, .nsdiv = 1 }, /* 135.000 MHz */
+ { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x2, .nsdiv = 1 }, /* 148.352 MHz */
+ { .mdiv = 0x0f, .pe = 0x3426, .sdiv = 0x0, .nsdiv = 0 }, /* 148.500 MHz */
+ { .mdiv = 0x03, .pe = 0x4ba7, .sdiv = 0x1, .nsdiv = 1 }, /* 296.704 MHz */
+ { .mdiv = 0x03, .pe = 0x471c, .sdiv = 0x1, .nsdiv = 1 }, /* 297.000 MHz */
+ { .mdiv = 0x00, .pe = 0x295f, .sdiv = 0x1, .nsdiv = 1 }, /* 326.700 MHz */
+ { .mdiv = 0x1f, .pe = 0x3633, .sdiv = 0x0, .nsdiv = 1 }, /* 333.000 MHz */
+ { .mdiv = 0x1c, .pe = 0x0, .sdiv = 0x0, .nsdiv = 1 }, /* 352.000 Mhz */
};
struct clkgen_quadfs_data {
bool reset_present;
bool bwfilter_present;
bool lockstatus_present;
+ bool powerup_polarity;
+ bool standby_polarity;
bool nsdiv_present;
+ bool nrst_present;
struct clkgen_field ndiv;
struct clkgen_field ref_bw;
struct clkgen_field nreset;
struct clkgen_field npda;
struct clkgen_field lock_status;
+ struct clkgen_field nrst[QUADFS_MAX_CHAN];
struct clkgen_field nsb[QUADFS_MAX_CHAN];
struct clkgen_field en[QUADFS_MAX_CHAN];
struct clkgen_field mdiv[QUADFS_MAX_CHAN];
@@ -82,9 +137,9 @@ struct clkgen_quadfs_data {
struct clkgen_field nsdiv[QUADFS_MAX_CHAN];
const struct clk_ops *pll_ops;
- struct stm_fs *rtbl;
+ const struct stm_fs *rtbl;
u8 rtbl_cnt;
- int (*get_rate)(unsigned long , struct stm_fs *,
+ int (*get_rate)(unsigned long , const struct stm_fs *,
unsigned long *);
};
@@ -94,11 +149,11 @@ static const struct clk_ops st_quadfs_fs216c65_ops;
static const struct clk_ops st_quadfs_fs432c65_ops;
static const struct clk_ops st_quadfs_fs660c32_ops;
-static int clk_fs216c65_get_rate(unsigned long, struct stm_fs *,
+static int clk_fs216c65_get_rate(unsigned long, const struct stm_fs *,
unsigned long *);
-static int clk_fs432c65_get_rate(unsigned long, struct stm_fs *,
+static int clk_fs432c65_get_rate(unsigned long, const struct stm_fs *,
unsigned long *);
-static int clk_fs660c32_dig_get_rate(unsigned long, struct stm_fs *,
+static int clk_fs660c32_dig_get_rate(unsigned long, const struct stm_fs *,
unsigned long *);
/*
* Values for all of the standalone instances of this clock
@@ -106,7 +161,7 @@ static int clk_fs660c32_dig_get_rate(unsigned long, struct stm_fs *,
* that the individual channel standby control bits (nsb) are in the
* first register along with the PLL control bits.
*/
-static struct clkgen_quadfs_data st_fs216c65_416 = {
+static const struct clkgen_quadfs_data st_fs216c65_416 = {
/* 416 specific */
.npda = CLKGEN_FIELD(0x0, 0x1, 14),
.nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
@@ -143,7 +198,7 @@ static struct clkgen_quadfs_data st_fs216c65_416 = {
.get_rate = clk_fs216c65_get_rate,
};
-static struct clkgen_quadfs_data st_fs432c65_416 = {
+static const struct clkgen_quadfs_data st_fs432c65_416 = {
.npda = CLKGEN_FIELD(0x0, 0x1, 14),
.nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
CLKGEN_FIELD(0x0, 0x1, 11),
@@ -179,7 +234,7 @@ static struct clkgen_quadfs_data st_fs432c65_416 = {
.get_rate = clk_fs432c65_get_rate,
};
-static struct clkgen_quadfs_data st_fs660c32_E_416 = {
+static const struct clkgen_quadfs_data st_fs660c32_E_416 = {
.npda = CLKGEN_FIELD(0x0, 0x1, 14),
.nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
CLKGEN_FIELD(0x0, 0x1, 11),
@@ -215,7 +270,7 @@ static struct clkgen_quadfs_data st_fs660c32_E_416 = {
.get_rate = clk_fs660c32_dig_get_rate,
};
-static struct clkgen_quadfs_data st_fs660c32_F_416 = {
+static const struct clkgen_quadfs_data st_fs660c32_F_416 = {
.npda = CLKGEN_FIELD(0x0, 0x1, 14),
.nsb = { CLKGEN_FIELD(0x0, 0x1, 10),
CLKGEN_FIELD(0x0, 0x1, 11),
@@ -251,6 +306,91 @@ static struct clkgen_quadfs_data st_fs660c32_F_416 = {
.get_rate = clk_fs660c32_dig_get_rate,
};
+static const struct clkgen_quadfs_data st_fs660c32_C_407 = {
+ .nrst_present = true,
+ .nrst = { CLKGEN_FIELD(0x2f0, 0x1, 0),
+ CLKGEN_FIELD(0x2f0, 0x1, 1),
+ CLKGEN_FIELD(0x2f0, 0x1, 2),
+ CLKGEN_FIELD(0x2f0, 0x1, 3) },
+ .npda = CLKGEN_FIELD(0x2f0, 0x1, 12),
+ .nsb = { CLKGEN_FIELD(0x2f0, 0x1, 8),
+ CLKGEN_FIELD(0x2f0, 0x1, 9),
+ CLKGEN_FIELD(0x2f0, 0x1, 10),
+ CLKGEN_FIELD(0x2f0, 0x1, 11) },
+ .nsdiv_present = true,
+ .nsdiv = { CLKGEN_FIELD(0x304, 0x1, 24),
+ CLKGEN_FIELD(0x308, 0x1, 24),
+ CLKGEN_FIELD(0x30c, 0x1, 24),
+ CLKGEN_FIELD(0x310, 0x1, 24) },
+ .mdiv = { CLKGEN_FIELD(0x304, 0x1f, 15),
+ CLKGEN_FIELD(0x308, 0x1f, 15),
+ CLKGEN_FIELD(0x30c, 0x1f, 15),
+ CLKGEN_FIELD(0x310, 0x1f, 15) },
+ .en = { CLKGEN_FIELD(0x2fc, 0x1, 0),
+ CLKGEN_FIELD(0x2fc, 0x1, 1),
+ CLKGEN_FIELD(0x2fc, 0x1, 2),
+ CLKGEN_FIELD(0x2fc, 0x1, 3) },
+ .ndiv = CLKGEN_FIELD(0x2f4, 0x7, 16),
+ .pe = { CLKGEN_FIELD(0x304, 0x7fff, 0),
+ CLKGEN_FIELD(0x308, 0x7fff, 0),
+ CLKGEN_FIELD(0x30c, 0x7fff, 0),
+ CLKGEN_FIELD(0x310, 0x7fff, 0) },
+ .sdiv = { CLKGEN_FIELD(0x304, 0xf, 20),
+ CLKGEN_FIELD(0x308, 0xf, 20),
+ CLKGEN_FIELD(0x30c, 0xf, 20),
+ CLKGEN_FIELD(0x310, 0xf, 20) },
+ .lockstatus_present = true,
+ .lock_status = CLKGEN_FIELD(0x2A0, 0x1, 24),
+ .powerup_polarity = 1,
+ .standby_polarity = 1,
+ .pll_ops = &st_quadfs_pll_c32_ops,
+ .rtbl = fs660c32_rtbl,
+ .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
+ .get_rate = clk_fs660c32_dig_get_rate,
+};
+
+static const struct clkgen_quadfs_data st_fs660c32_D_407 = {
+ .nrst_present = true,
+ .nrst = { CLKGEN_FIELD(0x2a0, 0x1, 0),
+ CLKGEN_FIELD(0x2a0, 0x1, 1),
+ CLKGEN_FIELD(0x2a0, 0x1, 2),
+ CLKGEN_FIELD(0x2a0, 0x1, 3) },
+ .ndiv = CLKGEN_FIELD(0x2a4, 0x7, 16),
+ .pe = { CLKGEN_FIELD(0x2b4, 0x7fff, 0),
+ CLKGEN_FIELD(0x2b8, 0x7fff, 0),
+ CLKGEN_FIELD(0x2bc, 0x7fff, 0),
+ CLKGEN_FIELD(0x2c0, 0x7fff, 0) },
+ .sdiv = { CLKGEN_FIELD(0x2b4, 0xf, 20),
+ CLKGEN_FIELD(0x2b8, 0xf, 20),
+ CLKGEN_FIELD(0x2bc, 0xf, 20),
+ CLKGEN_FIELD(0x2c0, 0xf, 20) },
+ .npda = CLKGEN_FIELD(0x2a0, 0x1, 12),
+ .nsb = { CLKGEN_FIELD(0x2a0, 0x1, 8),
+ CLKGEN_FIELD(0x2a0, 0x1, 9),
+ CLKGEN_FIELD(0x2a0, 0x1, 10),
+ CLKGEN_FIELD(0x2a0, 0x1, 11) },
+ .nsdiv_present = true,
+ .nsdiv = { CLKGEN_FIELD(0x2b4, 0x1, 24),
+ CLKGEN_FIELD(0x2b8, 0x1, 24),
+ CLKGEN_FIELD(0x2bc, 0x1, 24),
+ CLKGEN_FIELD(0x2c0, 0x1, 24) },
+ .mdiv = { CLKGEN_FIELD(0x2b4, 0x1f, 15),
+ CLKGEN_FIELD(0x2b8, 0x1f, 15),
+ CLKGEN_FIELD(0x2bc, 0x1f, 15),
+ CLKGEN_FIELD(0x2c0, 0x1f, 15) },
+ .en = { CLKGEN_FIELD(0x2ac, 0x1, 0),
+ CLKGEN_FIELD(0x2ac, 0x1, 1),
+ CLKGEN_FIELD(0x2ac, 0x1, 2),
+ CLKGEN_FIELD(0x2ac, 0x1, 3) },
+ .lockstatus_present = true,
+ .lock_status = CLKGEN_FIELD(0x2A0, 0x1, 24),
+ .powerup_polarity = 1,
+ .standby_polarity = 1,
+ .pll_ops = &st_quadfs_pll_c32_ops,
+ .rtbl = fs660c32_rtbl,
+ .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl),
+ .get_rate = clk_fs660c32_dig_get_rate,};
+
/**
* DOC: A Frequency Synthesizer that multiples its input clock by a fixed factor
*
@@ -308,7 +448,7 @@ static int quadfs_pll_enable(struct clk_hw *hw)
/*
* Power up the PLL
*/
- CLKGEN_WRITE(pll, npda, 1);
+ CLKGEN_WRITE(pll, npda, !pll->data->powerup_polarity);
if (pll->lock)
spin_unlock_irqrestore(pll->lock, flags);
@@ -335,7 +475,7 @@ static void quadfs_pll_disable(struct clk_hw *hw)
* Powerdown the PLL and then put block into soft reset if we have
* reset control.
*/
- CLKGEN_WRITE(pll, npda, 0);
+ CLKGEN_WRITE(pll, npda, pll->data->powerup_polarity);
if (pll->data->reset_present)
CLKGEN_WRITE(pll, nreset, 0);
@@ -611,7 +751,10 @@ static int quadfs_fsynth_enable(struct clk_hw *hw)
if (fs->lock)
spin_lock_irqsave(fs->lock, flags);
- CLKGEN_WRITE(fs, nsb[fs->chan], 1);
+ CLKGEN_WRITE(fs, nsb[fs->chan], !fs->data->standby_polarity);
+
+ if (fs->data->nrst_present)
+ CLKGEN_WRITE(fs, nrst[fs->chan], 0);
if (fs->lock)
spin_unlock_irqrestore(fs->lock, flags);
@@ -631,7 +774,7 @@ static void quadfs_fsynth_disable(struct clk_hw *hw)
if (fs->lock)
spin_lock_irqsave(fs->lock, flags);
- CLKGEN_WRITE(fs, nsb[fs->chan], 0);
+ CLKGEN_WRITE(fs, nsb[fs->chan], !fs->data->standby_polarity);
if (fs->lock)
spin_unlock_irqrestore(fs->lock, flags);
@@ -645,12 +788,12 @@ static int quadfs_fsynth_is_enabled(struct clk_hw *hw)
pr_debug("%s: %s enable bit = 0x%x\n",
__func__, __clk_get_name(hw->clk), nsb);
- return !!nsb;
+ return fs->data->standby_polarity ? !nsb : !!nsb;
}
#define P15 (uint64_t)(1 << 15)
-static int clk_fs216c65_get_rate(unsigned long input, struct stm_fs *fs,
+static int clk_fs216c65_get_rate(unsigned long input, const struct stm_fs *fs,
unsigned long *rate)
{
uint64_t res;
@@ -670,7 +813,7 @@ static int clk_fs216c65_get_rate(unsigned long input, struct stm_fs *fs,
return 0;
}
-static int clk_fs432c65_get_rate(unsigned long input, struct stm_fs *fs,
+static int clk_fs432c65_get_rate(unsigned long input, const struct stm_fs *fs,
unsigned long *rate)
{
uint64_t res;
@@ -693,7 +836,7 @@ static int clk_fs432c65_get_rate(unsigned long input, struct stm_fs *fs,
#define P20 (uint64_t)(1 << 20)
static int clk_fs660c32_dig_get_rate(unsigned long input,
- struct stm_fs *fs, unsigned long *rate)
+ const struct stm_fs *fs, unsigned long *rate)
{
unsigned long s = (1 << fs->sdiv);
unsigned long ns;
@@ -749,7 +892,7 @@ static long quadfs_find_best_rate(struct clk_hw *hw, unsigned long drate,
{
struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
int (*clk_fs_get_rate)(unsigned long ,
- struct stm_fs *, unsigned long *);
+ const struct stm_fs *, unsigned long *);
struct stm_fs prev_params;
unsigned long prev_rate, rate = 0;
unsigned long diff_rate, prev_diff_rate = ~0;
@@ -793,7 +936,7 @@ static unsigned long quadfs_recalc_rate(struct clk_hw *hw,
unsigned long rate = 0;
struct stm_fs params;
int (*clk_fs_get_rate)(unsigned long ,
- struct stm_fs *, unsigned long *);
+ const struct stm_fs *, unsigned long *);
clk_fs_get_rate = fs->data->get_rate;
@@ -917,19 +1060,31 @@ static struct clk * __init st_clk_register_quadfs_fsynth(
static struct of_device_id quadfs_of_match[] = {
{
.compatible = "st,stih416-quadfs216",
- .data = (void *)&st_fs216c65_416
+ .data = &st_fs216c65_416
},
{
.compatible = "st,stih416-quadfs432",
- .data = (void *)&st_fs432c65_416
+ .data = &st_fs432c65_416
},
{
.compatible = "st,stih416-quadfs660-E",
- .data = (void *)&st_fs660c32_E_416
+ .data = &st_fs660c32_E_416
},
{
.compatible = "st,stih416-quadfs660-F",
- .data = (void *)&st_fs660c32_F_416
+ .data = &st_fs660c32_F_416
+ },
+ {
+ .compatible = "st,stih407-quadfs660-C",
+ .data = &st_fs660c32_C_407
+ },
+ {
+ .compatible = "st,stih407-quadfs660-D",
+ .data = &st_fs660c32_D_407
+ },
+ {
+ .compatible = "st,stih407-quadfs660-D",
+ .data = (void *)&st_fs660c32_D_407
},
{}
};
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index a329906d1e81..79dc40b5cc68 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -580,6 +580,11 @@ static struct clkgen_mux_data stih416_a9_mux_data = {
.shift = 0,
.width = 2,
};
+static struct clkgen_mux_data stih407_a9_mux_data = {
+ .offset = 0x1a4,
+ .shift = 1,
+ .width = 2,
+};
static struct of_device_id mux_of_match[] = {
{
@@ -610,6 +615,10 @@ static struct of_device_id mux_of_match[] = {
.compatible = "st,stih416-clkgen-a9-mux",
.data = &stih416_a9_mux_data,
},
+ {
+ .compatible = "st,stih407-clkgen-a9-mux",
+ .data = &stih407_a9_mux_data,
+ },
{}
};
@@ -765,7 +774,8 @@ void __init st_of_clkgen_vcc_setup(struct device_node *np)
div->reg = reg + VCC_DIV_OFFSET;
div->shift = 2 * i;
div->width = 2;
- div->flags = CLK_DIVIDER_POWER_OF_TWO;
+ div->flags = CLK_DIVIDER_POWER_OF_TWO |
+ CLK_DIVIDER_ROUND_CLOSEST;
mux->reg = reg + VCC_MUX_OFFSET;
mux->shift = 2 * i;
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index d8b9b1a2aeda..29769d79e306 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -59,7 +59,7 @@ static const struct clk_ops st_pll800c65_ops;
static const struct clk_ops stm_pll3200c32_ops;
static const struct clk_ops st_pll1200c32_ops;
-static struct clkgen_pll_data st_pll1600c65_ax = {
+static const struct clkgen_pll_data st_pll1600c65_ax = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
.locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
.mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0),
@@ -67,7 +67,7 @@ static struct clkgen_pll_data st_pll1600c65_ax = {
.ops = &st_pll1600c65_ops
};
-static struct clkgen_pll_data st_pll800c65_ax = {
+static const struct clkgen_pll_data st_pll800c65_ax = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
.locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
.mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0),
@@ -76,7 +76,7 @@ static struct clkgen_pll_data st_pll800c65_ax = {
.ops = &st_pll800c65_ops
};
-static struct clkgen_pll_data st_pll3200c32_a1x_0 = {
+static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 31),
.locked_status = CLKGEN_FIELD(0x4, 0x1, 31),
.ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0),
@@ -93,7 +93,7 @@ static struct clkgen_pll_data st_pll3200c32_a1x_0 = {
.ops = &stm_pll3200c32_ops,
};
-static struct clkgen_pll_data st_pll3200c32_a1x_1 = {
+static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
.pdn_status = CLKGEN_FIELD(0xC, 0x1, 31),
.locked_status = CLKGEN_FIELD(0x10, 0x1, 31),
.ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0),
@@ -111,7 +111,7 @@ static struct clkgen_pll_data st_pll3200c32_a1x_1 = {
};
/* 415 specific */
-static struct clkgen_pll_data st_pll3200c32_a9_415 = {
+static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
.locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
.ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9),
@@ -122,7 +122,7 @@ static struct clkgen_pll_data st_pll3200c32_a9_415 = {
.ops = &stm_pll3200c32_ops,
};
-static struct clkgen_pll_data st_pll3200c32_ddr_415 = {
+static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
.locked_status = CLKGEN_FIELD(0x100, 0x1, 0),
.ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
@@ -135,7 +135,7 @@ static struct clkgen_pll_data st_pll3200c32_ddr_415 = {
.ops = &stm_pll3200c32_ops,
};
-static struct clkgen_pll_data st_pll1200c32_gpu_415 = {
+static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
.pdn_status = CLKGEN_FIELD(0x144, 0x1, 3),
.locked_status = CLKGEN_FIELD(0x168, 0x1, 0),
.ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
@@ -146,7 +146,7 @@ static struct clkgen_pll_data st_pll1200c32_gpu_415 = {
};
/* 416 specific */
-static struct clkgen_pll_data st_pll3200c32_a9_416 = {
+static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
.locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
.ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
@@ -157,7 +157,7 @@ static struct clkgen_pll_data st_pll3200c32_a9_416 = {
.ops = &stm_pll3200c32_ops,
};
-static struct clkgen_pll_data st_pll3200c32_ddr_416 = {
+static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
.pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
.locked_status = CLKGEN_FIELD(0x10C, 0x1, 0),
.ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
@@ -170,7 +170,7 @@ static struct clkgen_pll_data st_pll3200c32_ddr_416 = {
.ops = &stm_pll3200c32_ops,
};
-static struct clkgen_pll_data st_pll1200c32_gpu_416 = {
+static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
.pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3),
.locked_status = CLKGEN_FIELD(0x90C, 0x1, 0),
.ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
@@ -180,6 +180,54 @@ static struct clkgen_pll_data st_pll1200c32_gpu_416 = {
.ops = &st_pll1200c32_ops,
};
+static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
+ /* 407 A0 */
+ .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
+ .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
+ .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
+ .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
+ .num_odfs = 1,
+ .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
+ .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
+ .ops = &stm_pll3200c32_ops,
+};
+
+static const struct clkgen_pll_data st_pll3200c32_407_c0_0 = {
+ /* 407 C0 PLL0 */
+ .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
+ .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
+ .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
+ .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
+ .num_odfs = 1,
+ .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
+ .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
+ .ops = &stm_pll3200c32_ops,
+};
+
+static const struct clkgen_pll_data st_pll3200c32_407_c0_1 = {
+ /* 407 C0 PLL1 */
+ .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8),
+ .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24),
+ .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16),
+ .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0),
+ .num_odfs = 1,
+ .odf = { CLKGEN_FIELD(0x2dc, C32_ODF_MASK, 0) },
+ .odf_gate = { CLKGEN_FIELD(0x2dc, 0x1, 6) },
+ .ops = &stm_pll3200c32_ops,
+};
+
+static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
+ /* 407 A9 */
+ .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
+ .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
+ .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0),
+ .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25),
+ .num_odfs = 1,
+ .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) },
+ .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
+ .ops = &stm_pll3200c32_ops,
+};
+
/**
* DOC: Clock Generated by PLL, rate set and enabled by bootloader
*
@@ -450,9 +498,8 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
* PLL0 HS (high speed) output
*/
clk_data->clks[0] = clkgen_pll_register(parent_name,
- &st_pll1600c65_ax,
- reg + CLKGENAx_PLL0_OFFSET,
- clk_name);
+ (struct clkgen_pll_data *) &st_pll1600c65_ax,
+ reg + CLKGENAx_PLL0_OFFSET, clk_name);
if (IS_ERR(clk_data->clks[0]))
goto err;
@@ -480,9 +527,8 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
* PLL1 output
*/
clk_data->clks[2] = clkgen_pll_register(parent_name,
- &st_pll800c65_ax,
- reg + CLKGENAx_PLL1_OFFSET,
- clk_name);
+ (struct clkgen_pll_data *) &st_pll800c65_ax,
+ reg + CLKGENAx_PLL1_OFFSET, clk_name);
if (IS_ERR(clk_data->clks[2]))
goto err;
@@ -572,6 +618,22 @@ static struct of_device_id c32_pll_of_match[] = {
.compatible = "st,stih416-plls-c32-ddr",
.data = &st_pll3200c32_ddr_416,
},
+ {
+ .compatible = "st,stih407-plls-c32-a0",
+ .data = &st_pll3200c32_407_a0,
+ },
+ {
+ .compatible = "st,stih407-plls-c32-c0_0",
+ .data = &st_pll3200c32_407_c0_0,
+ },
+ {
+ .compatible = "st,stih407-plls-c32-c0_1",
+ .data = &st_pll3200c32_407_c0_1,
+ },
+ {
+ .compatible = "st,stih407-plls-c32-a9",
+ .data = &st_pll3200c32_407_a9,
+ },
{}
};
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 762fd64dbd1f..6850cba35871 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -6,4 +6,6 @@ obj-y += clk-sunxi.o clk-factors.o
obj-y += clk-a10-hosc.o
obj-y += clk-a20-gmac.o
-obj-$(CONFIG_MFD_SUN6I_PRCM) += clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o
+obj-$(CONFIG_MFD_SUN6I_PRCM) += \
+ clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
+ clk-sun8i-apb0.o
diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c
index 633ddc4389ef..5296fd6dd7b3 100644
--- a/drivers/clk/sunxi/clk-a20-gmac.c
+++ b/drivers/clk/sunxi/clk-a20-gmac.c
@@ -60,7 +60,7 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
struct clk_gate *gate;
const char *clk_name = node->name;
const char *parents[SUN7I_A20_GMAC_PARENTS];
- void *reg;
+ void __iomem *reg;
if (of_property_read_string(node, "clock-output-names", &clk_name))
return;
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 3806d97e529b..2057c8ac648f 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -62,7 +62,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
p = FACTOR_GET(config->pshift, config->pwidth, reg);
/* Calculate the rate */
- rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+ rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1);
return rate;
}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 02e1a43ebac7..d2d0efa39379 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -15,6 +15,7 @@ struct clk_factors_config {
u8 mwidth;
u8 pshift;
u8 pwidth;
+ u8 n_start;
};
struct clk_factors {
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
index 44cd27c5c401..e10d0521ec76 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
@@ -9,81 +9,93 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
#define SUN6I_APB0_GATES_MAX_SIZE 32
+struct gates_data {
+ DECLARE_BITMAP(mask, SUN6I_APB0_GATES_MAX_SIZE);
+};
+
+static const struct gates_data sun6i_a31_apb0_gates __initconst = {
+ .mask = {0x7F},
+};
+
+static const struct gates_data sun8i_a23_apb0_gates __initconst = {
+ .mask = {0x5D},
+};
+
+static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
+ { .compatible = "allwinner,sun6i-a31-apb0-gates-clk", .data = &sun6i_a31_apb0_gates },
+ { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
+ { /* sentinel */ }
+};
+
static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct clk_onecell_data *clk_data;
+ const struct of_device_id *device;
+ const struct gates_data *data;
const char *clk_parent;
const char *clk_name;
struct resource *r;
void __iomem *reg;
- int gate_id;
int ngates;
int i;
+ int j = 0;
+
+ if (!np)
+ return -ENODEV;
+
+ device = of_match_device(sun6i_a31_apb0_gates_clk_dt_ids, &pdev->dev);
+ if (!device)
+ return -ENODEV;
+ data = device->data;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(&pdev->dev, r);
- if (!reg)
+ if (IS_ERR(reg))
return PTR_ERR(reg);
clk_parent = of_clk_get_parent_name(np, 0);
if (!clk_parent)
return -EINVAL;
- ngates = of_property_count_strings(np, "clock-output-names");
- if (ngates < 0)
- return ngates;
-
- if (!ngates || ngates > SUN6I_APB0_GATES_MAX_SIZE)
- return -EINVAL;
-
clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
- clk_data->clks = devm_kzalloc(&pdev->dev,
- SUN6I_APB0_GATES_MAX_SIZE *
- sizeof(struct clk *),
- GFP_KERNEL);
+ /* Worst-case size approximation and memory allocation */
+ ngates = find_last_bit(data->mask, SUN6I_APB0_GATES_MAX_SIZE);
+ clk_data->clks = devm_kcalloc(&pdev->dev, (ngates + 1),
+ sizeof(struct clk *), GFP_KERNEL);
if (!clk_data->clks)
return -ENOMEM;
- for (i = 0; i < ngates; i++) {
+ for_each_set_bit(i, data->mask, SUN6I_APB0_GATES_MAX_SIZE) {
of_property_read_string_index(np, "clock-output-names",
- i, &clk_name);
+ j, &clk_name);
- gate_id = i;
- of_property_read_u32_index(np, "clock-indices", i, &gate_id);
+ clk_data->clks[i] = clk_register_gate(&pdev->dev, clk_name,
+ clk_parent, 0, reg, i,
+ 0, NULL);
+ WARN_ON(IS_ERR(clk_data->clks[i]));
+ clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
- WARN_ON(gate_id >= SUN6I_APB0_GATES_MAX_SIZE);
- if (gate_id >= SUN6I_APB0_GATES_MAX_SIZE)
- continue;
-
- clk_data->clks[gate_id] = clk_register_gate(&pdev->dev,
- clk_name,
- clk_parent, 0,
- reg, gate_id,
- 0, NULL);
- WARN_ON(IS_ERR(clk_data->clks[gate_id]));
+ j++;
}
- clk_data->clk_num = ngates;
+ clk_data->clk_num = ngates + 1;
return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
}
-const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
- { .compatible = "allwinner,sun6i-a31-apb0-gates-clk" },
- { /* sentinel */ }
-};
-
static struct platform_driver sun6i_a31_apb0_gates_clk_driver = {
.driver = {
.name = "sun6i-a31-apb0-gates-clk",
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c
index 11f17c34c2ae..1fa23371c8c6 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0.c
@@ -57,7 +57,7 @@ static int sun6i_a31_apb0_clk_probe(struct platform_device *pdev)
return of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
-const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
+static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-apb0-clk" },
{ /* sentinel */ }
};
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index f73cc051f0dd..eca8ca025b6a 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -160,7 +160,7 @@ static int ar100_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
-struct clk_ops ar100_ops = {
+static struct clk_ops ar100_ops = {
.recalc_rate = ar100_recalc_rate,
.determine_rate = ar100_determine_rate,
.set_parent = ar100_set_parent,
@@ -213,7 +213,7 @@ static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev)
return of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
-const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
+static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-ar100-clk" },
{ /* sentinel */ }
};
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
new file mode 100644
index 000000000000..1f5ba9b4b8cd
--- /dev/null
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 Chen-Yu Tsai
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * Allwinner A23 APB0 clock driver
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Based on clk-sun6i-apb0.c
+ * Allwinner A31 APB0 clock driver
+ *
+ * Copyright (C) 2014 Free Electrons
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const char *clk_name = np->name;
+ const char *clk_parent;
+ struct resource *r;
+ void __iomem *reg;
+ struct clk *clk;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ reg = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ clk_parent = of_clk_get_parent_name(np, 0);
+ if (!clk_parent)
+ return -EINVAL;
+
+ of_property_read_string(np, "clock-output-names", &clk_name);
+
+ /* The A23 APB0 clock is a standard 2 bit wide divider clock */
+ clk = clk_register_divider(&pdev->dev, clk_name, clk_parent, 0, reg,
+ 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ return of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
+ { .compatible = "allwinner,sun8i-a23-apb0-clk" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver sun8i_a23_apb0_clk_driver = {
+ .driver = {
+ .name = "sun8i-a23-apb0-clk",
+ .owner = THIS_MODULE,
+ .of_match_table = sun8i_a23_apb0_clk_dt_ids,
+ },
+ .probe = sun8i_a23_apb0_clk_probe,
+};
+module_platform_driver(sun8i_a23_apb0_clk_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_DESCRIPTION("Allwinner A23 APB0 clock Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index fb2ce8440f0e..b654b7b1d137 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -164,6 +164,54 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
}
/**
+ * sun8i_a23_get_pll1_factors() - calculates n, k, m, p factors for PLL1
+ * PLL1 rate is calculated as follows
+ * rate = (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
+ * parent_rate is always 24Mhz
+ */
+
+static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate,
+ u8 *n, u8 *k, u8 *m, u8 *p)
+{
+ u8 div;
+
+ /* Normalize value to a 6M multiple */
+ div = *freq / 6000000;
+ *freq = 6000000 * div;
+
+ /* we were called to round the frequency, we can now return */
+ if (n == NULL)
+ return;
+
+ /* m is always zero for pll1 */
+ *m = 0;
+
+ /* k is 1 only on these cases */
+ if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
+ *k = 1;
+ else
+ *k = 0;
+
+ /* p will be 2 for divs under 20 and odd divs under 32 */
+ if (div < 20 || (div < 32 && (div & 1)))
+ *p = 2;
+
+ /* p will be 1 for even divs under 32, divs under 40 and odd pairs
+ * of divs between 40-62 */
+ else if (div < 40 || (div < 64 && (div & 2)))
+ *p = 1;
+
+ /* any other entries have p = 0 */
+ else
+ *p = 0;
+
+ /* calculate a suitable n based on k and p */
+ div <<= *p;
+ div /= (*k + 1);
+ *n = div / 4 - 1;
+}
+
+/**
* sun4i_get_pll5_factors() - calculates n, k factors for PLL5
* PLL5 rate is calculated as follows
* rate = parent_rate * n * (k + 1)
@@ -422,6 +470,18 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
.mwidth = 2,
};
+static struct clk_factors_config sun8i_a23_pll1_config = {
+ .nshift = 8,
+ .nwidth = 5,
+ .kshift = 4,
+ .kwidth = 2,
+ .mshift = 0,
+ .mwidth = 2,
+ .pshift = 16,
+ .pwidth = 2,
+ .n_start = 1,
+};
+
static struct clk_factors_config sun4i_pll5_config = {
.nshift = 8,
.nwidth = 5,
@@ -471,6 +531,12 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = {
.getter = sun6i_a31_get_pll1_factors,
};
+static const struct factors_data sun8i_a23_pll1_data __initconst = {
+ .enable = 31,
+ .table = &sun8i_a23_pll1_config,
+ .getter = sun8i_a23_get_pll1_factors,
+};
+
static const struct factors_data sun7i_a20_pll4_data __initconst = {
.enable = 31,
.table = &sun4i_pll5_config,
@@ -527,7 +593,7 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
struct clk_hw *mux_hw = NULL;
const char *clk_name = node->name;
const char *parents[SUNXI_MAX_PARENTS];
- void *reg;
+ void __iomem *reg;
int i = 0;
reg = of_iomap(node, 0);
@@ -632,7 +698,7 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
struct clk *clk;
const char *clk_name = node->name;
const char *parents[SUNXI_MAX_PARENTS];
- void *reg;
+ void __iomem *reg;
int i = 0;
reg = of_iomap(node, 0);
@@ -664,6 +730,7 @@ struct div_data {
u8 shift;
u8 pow;
u8 width;
+ const struct clk_div_table *table;
};
static const struct div_data sun4i_axi_data __initconst = {
@@ -672,6 +739,23 @@ static const struct div_data sun4i_axi_data __initconst = {
.width = 2,
};
+static const struct clk_div_table sun8i_a23_axi_table[] __initconst = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 4 },
+ { .val = 5, .div = 4 },
+ { .val = 6, .div = 4 },
+ { .val = 7, .div = 4 },
+ { } /* sentinel */
+};
+
+static const struct div_data sun8i_a23_axi_data __initconst = {
+ .width = 3,
+ .table = sun8i_a23_axi_table,
+};
+
static const struct div_data sun4i_ahb_data __initconst = {
.shift = 4,
.pow = 1,
@@ -696,7 +780,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
struct clk *clk;
const char *clk_name = node->name;
const char *clk_parent;
- void *reg;
+ void __iomem *reg;
reg = of_iomap(node, 0);
@@ -704,10 +788,10 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
of_property_read_string(node, "clock-output-names", &clk_name);
- clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
- reg, data->shift, data->width,
- data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
- &clk_lock);
+ clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0,
+ reg, data->shift, data->width,
+ data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
+ data->table, &clk_lock);
if (clk) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, clk_name, NULL);
@@ -804,6 +888,10 @@ static const struct gates_data sun7i_a20_ahb_gates_data __initconst = {
.mask = { 0x12f77fff, 0x16ff3f },
};
+static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = {
+ .mask = {0x25386742, 0x2505111},
+};
+
static const struct gates_data sun4i_apb0_gates_data __initconst = {
.mask = {0x4EF},
};
@@ -836,6 +924,10 @@ static const struct gates_data sun6i_a31_apb1_gates_data __initconst = {
.mask = {0x3031},
};
+static const struct gates_data sun8i_a23_apb1_gates_data __initconst = {
+ .mask = {0x3021},
+};
+
static const struct gates_data sun6i_a31_apb2_gates_data __initconst = {
.mask = {0x3F000F},
};
@@ -844,6 +936,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
.mask = { 0xff80ff },
};
+static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
+ .mask = {0x1F0007},
+};
+
static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
.mask = {0x1C0},
.reset_mask = 0x07,
@@ -866,11 +962,10 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
struct gates_reset_data *reset_data;
const char *clk_parent;
const char *clk_name;
- void *reg;
+ void __iomem *reg;
int qty;
int i = 0;
int j = 0;
- int ignore;
reg = of_iomap(node, 0);
@@ -891,14 +986,12 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
of_property_read_string_index(node, "clock-output-names",
j, &clk_name);
- /* No driver claims this clock, but it should remain gated */
- ignore = !strcmp("ahb_sdram", clk_name) ? CLK_IGNORE_UNUSED : 0;
-
clk_data->clks[i] = clk_register_gate(NULL, clk_name,
- clk_parent, ignore,
+ clk_parent, 0,
reg + 4 * (i/32), i % 32,
0, &clk_lock);
WARN_ON(IS_ERR(clk_data->clks[i]));
+ clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
j++;
}
@@ -991,7 +1084,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
struct clk_gate *gate = NULL;
struct clk_fixed_factor *fix_factor;
struct clk_divider *divider;
- void *reg;
+ void __iomem *reg;
int i = 0;
int flags, clkflags;
@@ -1102,6 +1195,7 @@ free_clkdata:
static const struct of_device_id clk_factors_match[] __initconst = {
{.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,},
{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
+ {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
{.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
{.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
{.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
@@ -1113,6 +1207,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
/* Matches for divider clocks */
static const struct of_device_id clk_div_match[] __initconst = {
{.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,},
+ {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,},
{.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,},
{.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,},
{.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
@@ -1142,6 +1237,7 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,},
{.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
{.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
{.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
@@ -1151,7 +1247,9 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
{.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
{.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
{.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,},
@@ -1202,6 +1300,7 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
static const char *sun4i_a10_critical_clocks[] __initdata = {
"pll5_ddr",
+ "ahb_sdram",
};
static void __init sun4i_a10_init_clocks(struct device_node *node)
@@ -1214,6 +1313,7 @@ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks)
static const char *sun5i_critical_clocks[] __initdata = {
"mbus",
"pll5_ddr",
+ "ahb_sdram",
};
static void __init sun5i_init_clocks(struct device_node *node)
@@ -1236,3 +1336,4 @@ static void __init sun6i_init_clocks(struct device_node *node)
ARRAY_SIZE(sun6i_critical_clocks));
}
CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
+CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
index 507015314827..0aa8830ae7cc 100644
--- a/drivers/clk/tegra/clk-periph-gate.c
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -20,7 +20,8 @@
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
-#include <linux/tegra-soc.h>
+
+#include <soc/tegra/fuse.h>
#include "clk.h"
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 637b62ccc91e..c7c6d8fb32fb 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -110,6 +110,12 @@
#define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
#define XUSBIO_PLL_CFG0_SEQ_START_STATE BIT(25)
+#define SATA_PLL_CFG0 0x490
+#define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
+#define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2)
+#define SATA_PLL_CFG0_SEQ_ENABLE BIT(24)
+#define SATA_PLL_CFG0_SEQ_START_STATE BIT(25)
+
#define PLLE_MISC_PLLE_PTS BIT(8)
#define PLLE_MISC_IDDQ_SW_VALUE BIT(13)
#define PLLE_MISC_IDDQ_SW_CTRL BIT(14)
@@ -1361,6 +1367,19 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw)
val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
pll_writel(val, XUSBIO_PLL_CFG0, pll);
+ /* Enable hw control of SATA pll */
+ val = pll_readl(SATA_PLL_CFG0, pll);
+ val &= ~SATA_PLL_CFG0_PADPLL_RESET_SWCTL;
+ val |= SATA_PLL_CFG0_PADPLL_USE_LOCKDET;
+ val |= SATA_PLL_CFG0_SEQ_START_STATE;
+ pll_writel(val, SATA_PLL_CFG0, pll);
+
+ udelay(1);
+
+ val = pll_readl(SATA_PLL_CFG0, pll);
+ val |= SATA_PLL_CFG0_SEQ_ENABLE;
+ pll_writel(val, SATA_PLL_CFG0, pll);
+
out:
if (pll->lock)
spin_unlock_irqrestore(pll->lock, flags);
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index adf6b814b5bc..37f32c49674e 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -469,7 +469,7 @@ static struct tegra_periph_init_data periph_clks[] = {
MUX("sata", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SATA, 124, TEGRA_PERIPH_ON_APB, tegra_clk_sata),
MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1),
MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1),
- MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2),
+ MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 165, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2),
MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1_8),
MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2_8),
MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3_8),
@@ -487,7 +487,7 @@ static struct tegra_periph_init_data periph_clks[] = {
MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2),
MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3),
MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm),
- MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8),
+ MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8),
MUX8("isp", mux_pllm_pllc_pllp_plla_clkm_pllc4, CLK_SOURCE_ISP, 23, TEGRA_PERIPH_ON_APB, tegra_clk_isp_8),
MUX8("entropy", mux_pllp_clkm1, CLK_SOURCE_ENTROPY, 149, 0, tegra_clk_entropy),
MUX8("hdmi_audio", mux_pllp3_pllc_clkm, CLK_SOURCE_HDMI_AUDIO, 176, TEGRA_PERIPH_NO_RESET, tegra_clk_hdmi_audio),
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index b9c8ba258ef0..f760f31d05c4 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -151,6 +151,13 @@
/* Tegra CPU clock and reset control regs */
#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
+#define MUX8(_name, _parents, _offset, \
+ _clk_num, _gate_flags, _clk_id) \
+ TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\
+ 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\
+ _clk_num, _gate_flags, _clk_id, _parents##_idx, 0,\
+ NULL)
+
#ifdef CONFIG_PM_SLEEP
static struct cpu_clk_suspend_context {
u32 clk_csite_src;
@@ -777,7 +784,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
[tegra_clk_spdif_in] = { .dt_id = TEGRA114_CLK_SPDIF_IN, .present = true },
[tegra_clk_spdif_out] = { .dt_id = TEGRA114_CLK_SPDIF_OUT, .present = true },
[tegra_clk_vi_8] = { .dt_id = TEGRA114_CLK_VI, .present = true },
- [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA114_CLK_VI_SENSOR, .present = true },
[tegra_clk_fuse] = { .dt_id = TEGRA114_CLK_FUSE, .present = true },
[tegra_clk_fuse_burn] = { .dt_id = TEGRA114_CLK_FUSE_BURN, .present = true },
[tegra_clk_clk_32k] = { .dt_id = TEGRA114_CLK_CLK_32K, .present = true },
@@ -923,6 +929,13 @@ static struct tegra_devclk devclks[] __initdata = {
{ .dev_id = "timer", .dt_id = TEGRA114_CLK_TIMER },
};
+static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = {
+ "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0"
+};
+static u32 mux_pllm_pllc2_c_c3_pllp_plla_idx[] = {
+ [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
+};
+
static struct clk **clks;
static unsigned long osc_freq;
@@ -1178,10 +1191,18 @@ static void __init tegra114_pll_init(void __iomem *clk_base,
clks[TEGRA114_CLK_PLL_E_OUT0] = clk;
}
+#define CLK_SOURCE_VI_SENSOR 0x1a8
+
+static struct tegra_periph_init_data tegra_periph_clk_list[] = {
+ MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, TEGRA_PERIPH_NO_RESET, TEGRA114_CLK_VI_SENSOR),
+};
+
static __init void tegra114_periph_clk_init(void __iomem *clk_base,
void __iomem *pmc_base)
{
struct clk *clk;
+ struct tegra_periph_init_data *data;
+ int i;
/* xusb_ss_div2 */
clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
@@ -1209,6 +1230,14 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
clk_base + CLK_SOURCE_EMC,
29, 3, 0, NULL);
+ for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
+ data = &tegra_periph_clk_list[i];
+ clk = tegra_clk_register_periph(data->name,
+ data->p.parent_names, data->num_parents,
+ &data->periph, clk_base, data->offset, data->flags);
+ clks[data->clk_id] = clk;
+ }
+
tegra_periph_clk_init(clk_base, pmc_base, tegra114_clks,
&pll_p_params);
}
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 80efe51fdcdf..9525c684d149 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -869,7 +869,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
[tegra_clk_spdif_in] = { .dt_id = TEGRA124_CLK_SPDIF_IN, .present = true },
[tegra_clk_spdif_out] = { .dt_id = TEGRA124_CLK_SPDIF_OUT, .present = true },
[tegra_clk_vi_9] = { .dt_id = TEGRA124_CLK_VI, .present = true },
- [tegra_clk_vi_sensor] = { .dt_id = TEGRA124_CLK_VI_SENSOR, .present = true },
+ [tegra_clk_vi_sensor_8] = { .dt_id = TEGRA124_CLK_VI_SENSOR, .present = true },
[tegra_clk_fuse] = { .dt_id = TEGRA124_CLK_FUSE, .present = true },
[tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true },
[tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true },
@@ -1369,6 +1369,14 @@ static struct tegra_clk_init_table init_table[] __initdata = {
{TEGRA124_CLK_XUSB_HS_SRC, TEGRA124_CLK_PLL_U_60M, 60000000, 0},
{TEGRA124_CLK_XUSB_FALCON_SRC, TEGRA124_CLK_PLL_RE_OUT, 224000000, 0},
{TEGRA124_CLK_XUSB_HOST_SRC, TEGRA124_CLK_PLL_RE_OUT, 112000000, 0},
+ {TEGRA124_CLK_SATA, TEGRA124_CLK_PLL_P, 104000000, 0},
+ {TEGRA124_CLK_SATA_OOB, TEGRA124_CLK_PLL_P, 204000000, 0},
+ {TEGRA124_CLK_EMC, TEGRA124_CLK_CLK_MAX, 0, 1},
+ {TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
+ {TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1},
+ {TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1},
+ {TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0},
+ {TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},
/* This MUST be the last entry. */
{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
};
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 8b10c38b6e3c..5bbacd01094f 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -22,8 +22,11 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk/tegra.h>
-#include <linux/tegra-powergate.h>
+
+#include <soc/tegra/pmc.h>
+
#include <dt-bindings/clock/tegra30-car.h>
+
#include "clk.h"
#include "clk-id.h"
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index c0a7d7723510..f87c609e8f72 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -19,7 +19,8 @@
#include <linux/of.h>
#include <linux/clk/tegra.h>
#include <linux/reset-controller.h>
-#include <linux/tegra-soc.h>
+
+#include <soc/tegra/fuse.h>
#include "clk.h"
@@ -277,6 +278,12 @@ void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
for (i = 0; i < num; i++, dev_clks++)
clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id,
dev_clks->dev_id);
+
+ for (i = 0; i < clk_num; i++) {
+ if (!IS_ERR_OR_NULL(clks[i]))
+ clk_register_clkdev(clks[i], __clk_get_name(clks[i]),
+ "tegra-clk-debug");
+ }
}
struct clk ** __init tegra_lookup_dt_id(int clk_id,
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 5428c9c547cd..72d97279eae1 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -77,13 +77,11 @@ static int dra7_apll_enable(struct clk_hw *hw)
if (i == MAX_APLL_WAIT_TRIES) {
pr_warn("clock: %s failed transition to '%s'\n",
clk_name, (state) ? "locked" : "bypassed");
- } else {
+ r = -EBUSY;
+ } else
pr_debug("clock: %s transition to '%s' in %d loops\n",
clk_name, (state) ? "locked" : "bypassed", i);
- r = 0;
- }
-
return r;
}
@@ -338,7 +336,7 @@ static void __init of_omap2_apll_setup(struct device_node *node)
const char *parent_name;
u32 val;
- ad = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+ ad = kzalloc(sizeof(*ad), GFP_KERNEL);
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
init = kzalloc(sizeof(*init), GFP_KERNEL);
diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c
index e1581335937d..62ac8f6e480c 100644
--- a/drivers/clk/ti/clk-7xx.c
+++ b/drivers/clk/ti/clk-7xx.c
@@ -16,8 +16,9 @@
#include <linux/clkdev.h>
#include <linux/clk/ti.h>
-#define DRA7_DPLL_ABE_DEFFREQ 361267200
+#define DRA7_DPLL_ABE_DEFFREQ 180633600
#define DRA7_DPLL_GMAC_DEFFREQ 1000000000
+#define DRA7_DPLL_USB_DEFFREQ 960000000
static struct ti_dt_clk dra7xx_clks[] = {
@@ -322,10 +323,25 @@ int __init dra7xx_dt_clk_init(void)
if (rc)
pr_err("%s: failed to configure ABE DPLL!\n", __func__);
+ dpll_ck = clk_get_sys(NULL, "dpll_abe_m2x2_ck");
+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ * 2);
+ if (rc)
+ pr_err("%s: failed to configure ABE DPLL m2x2!\n", __func__);
+
dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck");
rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ);
if (rc)
pr_err("%s: failed to configure GMAC DPLL!\n", __func__);
+ dpll_ck = clk_get_sys(NULL, "dpll_usb_ck");
+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_USB_DEFFREQ);
+ if (rc)
+ pr_err("%s: failed to configure USB DPLL!\n", __func__);
+
+ dpll_ck = clk_get_sys(NULL, "dpll_usb_m2_ck");
+ rc = clk_set_rate(dpll_ck, DRA7_DPLL_USB_DEFFREQ/2);
+ if (rc)
+ pr_err("%s: failed to set USB_DPLL M2 OUT\n", __func__);
+
return rc;
}
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index abd956d5f838..79791e1bf282 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -161,7 +161,8 @@ cleanup:
}
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
- defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX)
+ defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
+ defined(CONFIG_SOC_AM43XX)
/**
* ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
* @node: device node for this clock
@@ -322,7 +323,7 @@ CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
of_ti_omap4_dpll_x2_setup);
#endif
-#ifdef CONFIG_SOC_AM33XX
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
{
ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c
index 0197a478720c..e9d650e51287 100644
--- a/drivers/clk/ti/mux.c
+++ b/drivers/clk/ti/mux.c
@@ -160,7 +160,7 @@ static void of_mux_clk_setup(struct device_node *node)
u8 clk_mux_flags = 0;
u32 mask = 0;
u32 shift = 0;
- u32 flags = 0;
+ u32 flags = CLK_SET_RATE_NO_REPARENT;
num_parents = of_clk_get_parent_count(node);
if (num_parents < 2) {
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
index fd449f9b006d..162e519cb0f9 100644
--- a/drivers/clk/versatile/Makefile
+++ b/drivers/clk/versatile/Makefile
@@ -1,6 +1,5 @@
# Makefile for Versatile-specific clocks
-obj-$(CONFIG_ICST) += clk-icst.o
-obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o
+obj-$(CONFIG_ICST) += clk-icst.o clk-versatile.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o
obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-versatile.c
index 734c4b8fe6ab..a76981e88cb6 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-versatile.c
@@ -1,5 +1,6 @@
/*
- * Clock driver for the ARM Integrator/AP and Integrator/CP boards
+ * Clock driver for the ARM Integrator/AP, Integrator/CP, Versatile AB and
+ * Versatile PB boards.
* Copyright (C) 2012 Linus Walleij
*
* This program is free software; you can redistribute it and/or modify
@@ -17,6 +18,9 @@
#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
+#define VERSATILE_SYS_OSCCLCD_OFFSET 0x1c
+#define VERSATILE_SYS_LOCK_OFFSET 0x20
+
/* Base offset for the core module */
static void __iomem *cm_base;
@@ -37,11 +41,27 @@ static const struct clk_icst_desc __initdata cm_auxosc_desc = {
.lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
};
-static void __init of_integrator_cm_osc_setup(struct device_node *np)
+static const struct icst_params versatile_auxosc_params = {
+ .vco_max = ICST307_VCO_MAX,
+ .vco_min = ICST307_VCO_MIN,
+ .vd_min = 4 + 8,
+ .vd_max = 511 + 8,
+ .rd_min = 1 + 2,
+ .rd_max = 127 + 2,
+ .s2div = icst307_s2div,
+ .idx2s = icst307_idx2s,
+};
+
+static const struct clk_icst_desc versatile_auxosc_desc __initconst = {
+ .params = &versatile_auxosc_params,
+ .vco_offset = VERSATILE_SYS_OSCCLCD_OFFSET,
+ .lock_offset = VERSATILE_SYS_LOCK_OFFSET,
+};
+static void __init cm_osc_setup(struct device_node *np,
+ const struct clk_icst_desc *desc)
{
struct clk *clk = ERR_PTR(-EINVAL);
const char *clk_name = np->name;
- const struct clk_icst_desc *desc = &cm_auxosc_desc;
const char *parent_name;
if (!cm_base) {
@@ -65,5 +85,17 @@ static void __init of_integrator_cm_osc_setup(struct device_node *np)
if (!IS_ERR(clk))
of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
+
+static void __init of_integrator_cm_osc_setup(struct device_node *np)
+{
+ cm_osc_setup(np, &cm_auxosc_desc);
+}
CLK_OF_DECLARE(integrator_cm_auxosc_clk,
"arm,integrator-cm-auxosc", of_integrator_cm_osc_setup);
+
+static void __init of_versatile_cm_osc_setup(struct device_node *np)
+{
+ cm_osc_setup(np, &versatile_auxosc_desc);
+}
+CLK_OF_DECLARE(versatile_cm_auxosc_clk,
+ "arm,versatile-cm-auxosc", of_versatile_cm_osc_setup);
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 065131cbfcc0..cfd6519df661 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -1,3 +1,5 @@
+menu "Clock Source drivers"
+
config CLKSRC_OF
bool
@@ -125,6 +127,7 @@ config CLKSRC_METAG_GENERIC
config CLKSRC_EXYNOS_MCT
def_bool y if ARCH_EXYNOS
+ depends on !ARM64
help
Support for Multi Core Timer controller on Exynos SoCs.
@@ -149,6 +152,11 @@ config VF_PIT_TIMER
config SYS_SUPPORTS_SH_CMT
bool
+config MTK_TIMER
+ select CLKSRC_OF
+ select CLKSRC_MMIO
+ bool
+
config SYS_SUPPORTS_SH_MTU2
bool
@@ -173,7 +181,7 @@ config SH_TIMER_MTU2
default SYS_SUPPORTS_SH_MTU2
help
This enables build of a clockevent driver for the Multi-Function
- Timer Pulse Unit 2 (TMU2) hardware available on SoCs from Renesas.
+ Timer Pulse Unit 2 (MTU2) hardware available on SoCs from Renesas.
This hardware comes with 16 bit-timer registers.
config SH_TIMER_TMU
@@ -187,7 +195,7 @@ config SH_TIMER_TMU
config EM_TIMER_STI
bool "Renesas STI timer driver" if COMPILE_TEST
- depends on GENERIC_CLOCKEVENTS
+ depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
default SYS_SUPPORTS_EM_STI
help
This enables build of a clocksource and clockevent driver for
@@ -207,3 +215,5 @@ config CLKSRC_VERSATILE
counter available in the "System Registers" block of
ARM Versatile, RealView and Versatile Express reference
platforms.
+
+endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 800b1303c236..7fd9fd1dff42 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,9 +16,11 @@ obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
obj-$(CONFIG_ORION_TIMER) += time-orion.o
obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
+obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o
obj-$(CONFIG_ARCH_MARCO) += timer-marco.o
obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o
obj-$(CONFIG_ARCH_MXS) += mxs_timer.o
+obj-$(CONFIG_ARCH_PXA) += pxa_timer.o
obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o
obj-$(CONFIG_ARCH_U300) += timer-u300.o
obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o
@@ -34,6 +36,7 @@ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
+obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index 60e5a170c4d2..e6833771a716 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -250,7 +250,7 @@ static void __init global_timer_of_register(struct device_node *np)
* fire when the timer value is greater than or equal to. In previous
* revisions the comparators fired when the timer value was equal to.
*/
- if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9
+ if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9
&& (read_cpuid_id() & 0xf0000f) < 0x200000) {
pr_warn("global-timer: non support for this cpu version.\n");
return;
diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c
new file mode 100644
index 000000000000..d83ec1f2fddc
--- /dev/null
+++ b/drivers/clocksource/clps711x-timer.c
@@ -0,0 +1,131 @@
+/*
+ * Cirrus Logic CLPS711X clocksource driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+
+enum {
+ CLPS711X_CLKSRC_CLOCKSOURCE,
+ CLPS711X_CLKSRC_CLOCKEVENT,
+};
+
+static void __iomem *tcd;
+
+static u64 notrace clps711x_sched_clock_read(void)
+{
+ return ~readw(tcd);
+}
+
+static int __init _clps711x_clksrc_init(struct clk *clock, void __iomem *base)
+{
+ unsigned long rate;
+
+ if (!base)
+ return -ENOMEM;
+ if (IS_ERR(clock))
+ return PTR_ERR(clock);
+
+ rate = clk_get_rate(clock);
+
+ tcd = base;
+
+ clocksource_mmio_init(tcd, "clps711x-clocksource", rate, 300, 16,
+ clocksource_mmio_readw_down);
+
+ sched_clock_register(clps711x_sched_clock_read, 16, rate);
+
+ return 0;
+}
+
+static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static void clps711x_clockevent_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base,
+ unsigned int irq)
+{
+ struct clock_event_device *clkevt;
+ unsigned long rate;
+
+ if (!irq)
+ return -EINVAL;
+ if (!base)
+ return -ENOMEM;
+ if (IS_ERR(clock))
+ return PTR_ERR(clock);
+
+ clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL);
+ if (!clkevt)
+ return -ENOMEM;
+
+ rate = clk_get_rate(clock);
+
+ /* Set Timer prescaler */
+ writew(DIV_ROUND_CLOSEST(rate, HZ), base);
+
+ clkevt->name = "clps711x-clockevent";
+ clkevt->rating = 300;
+ clkevt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_C3STOP;
+ clkevt->set_mode = clps711x_clockevent_set_mode;
+ clkevt->cpumask = cpumask_of(0);
+ clockevents_config_and_register(clkevt, HZ, 0, 0);
+
+ return request_irq(irq, clps711x_timer_interrupt, IRQF_TIMER,
+ "clps711x-timer", clkevt);
+}
+
+void __init clps711x_clksrc_init(void __iomem *tc1_base, void __iomem *tc2_base,
+ unsigned int irq)
+{
+ struct clk *tc1 = clk_get_sys("clps711x-timer.0", NULL);
+ struct clk *tc2 = clk_get_sys("clps711x-timer.1", NULL);
+
+ BUG_ON(_clps711x_clksrc_init(tc1, tc1_base));
+ BUG_ON(_clps711x_clkevt_init(tc2, tc2_base, irq));
+}
+
+#ifdef CONFIG_CLKSRC_OF
+static void __init clps711x_timer_init(struct device_node *np)
+{
+ unsigned int irq = irq_of_parse_and_map(np, 0);
+ struct clk *clock = of_clk_get(np, 0);
+ void __iomem *base = of_iomap(np, 0);
+
+ switch (of_alias_get_id(np, "timer")) {
+ case CLPS711X_CLKSRC_CLOCKSOURCE:
+ BUG_ON(_clps711x_clksrc_init(clock, base));
+ break;
+ case CLPS711X_CLKSRC_CLOCKEVENT:
+ BUG_ON(_clps711x_clkevt_init(clock, base, irq));
+ break;
+ default:
+ break;
+ }
+}
+CLOCKSOURCE_OF_DECLARE(clps711x, "cirrus,clps711x-timer", clps711x_timer_init);
+#endif
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index f71d55f5e6e5..9403061a2acc 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -94,7 +94,7 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset)
u32 mask;
u32 i;
- __raw_writel(value, reg_base + offset);
+ writel_relaxed(value, reg_base + offset);
if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) {
stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
@@ -144,8 +144,8 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset)
/* Wait maximum 1 ms until written values are applied */
for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
- if (__raw_readl(reg_base + stat_addr) & mask) {
- __raw_writel(mask, reg_base + stat_addr);
+ if (readl_relaxed(reg_base + stat_addr) & mask) {
+ writel_relaxed(mask, reg_base + stat_addr);
return;
}
@@ -157,25 +157,53 @@ static void exynos4_mct_frc_start(void)
{
u32 reg;
- reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+ reg = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
reg |= MCT_G_TCON_START;
exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
}
-static cycle_t exynos4_frc_read(struct clocksource *cs)
+/**
+ * exynos4_read_count_64 - Read all 64-bits of the global counter
+ *
+ * This will read all 64-bits of the global counter taking care to make sure
+ * that the upper and lower half match. Note that reading the MCT can be quite
+ * slow (hundreds of nanoseconds) so you should use the 32-bit (lower half
+ * only) version when possible.
+ *
+ * Returns the number of cycles in the global counter.
+ */
+static u64 exynos4_read_count_64(void)
{
unsigned int lo, hi;
- u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
+ u32 hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U);
do {
hi = hi2;
- lo = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L);
- hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
+ lo = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L);
+ hi2 = readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_U);
} while (hi != hi2);
return ((cycle_t)hi << 32) | lo;
}
+/**
+ * exynos4_read_count_32 - Read the lower 32-bits of the global counter
+ *
+ * This will read just the lower 32-bits of the global counter. This is marked
+ * as notrace so it can be used by the scheduler clock.
+ *
+ * Returns the number of cycles in the global counter (lower 32 bits).
+ */
+static u32 notrace exynos4_read_count_32(void)
+{
+ return readl_relaxed(reg_base + EXYNOS4_MCT_G_CNT_L);
+}
+
+static cycle_t exynos4_frc_read(struct clocksource *cs)
+{
+ return exynos4_read_count_32();
+}
+
static void exynos4_frc_resume(struct clocksource *cs)
{
exynos4_mct_frc_start();
@@ -185,31 +213,44 @@ struct clocksource mct_frc = {
.name = "mct-frc",
.rating = 400,
.read = exynos4_frc_read,
- .mask = CLOCKSOURCE_MASK(64),
+ .mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.resume = exynos4_frc_resume,
};
static u64 notrace exynos4_read_sched_clock(void)
{
- return exynos4_frc_read(&mct_frc);
+ return exynos4_read_count_32();
+}
+
+static struct delay_timer exynos4_delay_timer;
+
+static cycles_t exynos4_read_current_timer(void)
+{
+ BUILD_BUG_ON_MSG(sizeof(cycles_t) != sizeof(u32),
+ "cycles_t needs to move to 32-bit for ARM64 usage");
+ return exynos4_read_count_32();
}
static void __init exynos4_clocksource_init(void)
{
exynos4_mct_frc_start();
+ exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer;
+ exynos4_delay_timer.freq = clk_rate;
+ register_current_timer_delay(&exynos4_delay_timer);
+
if (clocksource_register_hz(&mct_frc, clk_rate))
panic("%s: can't register clocksource\n", mct_frc.name);
- sched_clock_register(exynos4_read_sched_clock, 64, clk_rate);
+ sched_clock_register(exynos4_read_sched_clock, 32, clk_rate);
}
static void exynos4_mct_comp0_stop(void)
{
unsigned int tcon;
- tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+ tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
@@ -222,14 +263,14 @@ static void exynos4_mct_comp0_start(enum clock_event_mode mode,
unsigned int tcon;
cycle_t comp_cycle;
- tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+ tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
if (mode == CLOCK_EVT_MODE_PERIODIC) {
tcon |= MCT_G_TCON_COMP0_AUTO_INC;
exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
}
- comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
+ comp_cycle = exynos4_read_count_64() + cycles;
exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
@@ -311,7 +352,7 @@ static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
unsigned long offset = mevt->base + MCT_L_TCON_OFFSET;
- tmp = __raw_readl(reg_base + offset);
+ tmp = readl_relaxed(reg_base + offset);
if (tmp & mask) {
tmp &= ~mask;
exynos4_mct_write(tmp, offset);
@@ -333,7 +374,7 @@ static void exynos4_mct_tick_start(unsigned long cycles,
/* enable MCT tick interrupt */
exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
- tmp = __raw_readl(reg_base + mevt->base + MCT_L_TCON_OFFSET);
+ tmp = readl_relaxed(reg_base + mevt->base + MCT_L_TCON_OFFSET);
tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
MCT_L_TCON_INTERVAL_MODE;
exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
@@ -385,7 +426,7 @@ static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
exynos4_mct_tick_stop(mevt);
/* Clear the MCT tick interrupt */
- if (__raw_readl(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
+ if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
return 1;
} else {
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
new file mode 100644
index 000000000000..32a3d25795d3
--- /dev/null
+++ b/drivers/clocksource/mtk_timer.c
@@ -0,0 +1,261 @@
+/*
+ * Mediatek SoCs General-Purpose Timer handling.
+ *
+ * Copyright (C) 2014 Matthias Brugger
+ *
+ * Matthias Brugger <matthias.bgg@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.
+ *
+ * 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/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+
+#define GPT_IRQ_EN_REG 0x00
+#define GPT_IRQ_ENABLE(val) BIT((val) - 1)
+#define GPT_IRQ_ACK_REG 0x08
+#define GPT_IRQ_ACK(val) BIT((val) - 1)
+
+#define TIMER_CTRL_REG(val) (0x10 * (val))
+#define TIMER_CTRL_OP(val) (((val) & 0x3) << 4)
+#define TIMER_CTRL_OP_ONESHOT (0)
+#define TIMER_CTRL_OP_REPEAT (1)
+#define TIMER_CTRL_OP_FREERUN (3)
+#define TIMER_CTRL_CLEAR (2)
+#define TIMER_CTRL_ENABLE (1)
+#define TIMER_CTRL_DISABLE (0)
+
+#define TIMER_CLK_REG(val) (0x04 + (0x10 * (val)))
+#define TIMER_CLK_SRC(val) (((val) & 0x1) << 4)
+#define TIMER_CLK_SRC_SYS13M (0)
+#define TIMER_CLK_SRC_RTC32K (1)
+#define TIMER_CLK_DIV1 (0x0)
+#define TIMER_CLK_DIV2 (0x1)
+
+#define TIMER_CNT_REG(val) (0x08 + (0x10 * (val)))
+#define TIMER_CMP_REG(val) (0x0C + (0x10 * (val)))
+
+#define GPT_CLK_EVT 1
+#define GPT_CLK_SRC 2
+
+struct mtk_clock_event_device {
+ void __iomem *gpt_base;
+ u32 ticks_per_jiffy;
+ struct clock_event_device dev;
+};
+
+static inline struct mtk_clock_event_device *to_mtk_clk(
+ struct clock_event_device *c)
+{
+ return container_of(c, struct mtk_clock_event_device, dev);
+}
+
+static void mtk_clkevt_time_stop(struct mtk_clock_event_device *evt, u8 timer)
+{
+ u32 val;
+
+ val = readl(evt->gpt_base + TIMER_CTRL_REG(timer));
+ writel(val & ~TIMER_CTRL_ENABLE, evt->gpt_base +
+ TIMER_CTRL_REG(timer));
+}
+
+static void mtk_clkevt_time_setup(struct mtk_clock_event_device *evt,
+ unsigned long delay, u8 timer)
+{
+ writel(delay, evt->gpt_base + TIMER_CMP_REG(timer));
+}
+
+static void mtk_clkevt_time_start(struct mtk_clock_event_device *evt,
+ bool periodic, u8 timer)
+{
+ u32 val;
+
+ /* Acknowledge interrupt */
+ writel(GPT_IRQ_ACK(timer), evt->gpt_base + GPT_IRQ_ACK_REG);
+
+ val = readl(evt->gpt_base + TIMER_CTRL_REG(timer));
+
+ /* Clear 2 bit timer operation mode field */
+ val &= ~TIMER_CTRL_OP(0x3);
+
+ if (periodic)
+ val |= TIMER_CTRL_OP(TIMER_CTRL_OP_REPEAT);
+ else
+ val |= TIMER_CTRL_OP(TIMER_CTRL_OP_ONESHOT);
+
+ writel(val | TIMER_CTRL_ENABLE | TIMER_CTRL_CLEAR,
+ evt->gpt_base + TIMER_CTRL_REG(timer));
+}
+
+static void mtk_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ struct mtk_clock_event_device *evt = to_mtk_clk(clk);
+
+ mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
+ mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Timer is enabled in set_next_event */
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ /* No more interrupts will occur as source is disabled */
+ break;
+ }
+}
+
+static int mtk_clkevt_next_event(unsigned long event,
+ struct clock_event_device *clk)
+{
+ struct mtk_clock_event_device *evt = to_mtk_clk(clk);
+
+ mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
+ mtk_clkevt_time_setup(evt, event, GPT_CLK_EVT);
+ mtk_clkevt_time_start(evt, false, GPT_CLK_EVT);
+
+ return 0;
+}
+
+static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
+{
+ struct mtk_clock_event_device *evt = dev_id;
+
+ /* Acknowledge timer0 irq */
+ writel(GPT_IRQ_ACK(GPT_CLK_EVT), evt->gpt_base + GPT_IRQ_ACK_REG);
+ evt->dev.event_handler(&evt->dev);
+
+ return IRQ_HANDLED;
+}
+
+static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
+{
+ /* Disable all interrupts */
+ writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
+ /* Acknowledge all interrupts */
+ writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
+}
+
+static void
+mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
+{
+ writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
+ evt->gpt_base + TIMER_CTRL_REG(timer));
+
+ writel(TIMER_CLK_SRC(TIMER_CLK_SRC_SYS13M) | TIMER_CLK_DIV1,
+ evt->gpt_base + TIMER_CLK_REG(timer));
+
+ writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
+
+ writel(TIMER_CTRL_OP(option) | TIMER_CTRL_ENABLE,
+ evt->gpt_base + TIMER_CTRL_REG(timer));
+}
+
+static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
+{
+ u32 val;
+
+ val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
+ writel(val | GPT_IRQ_ENABLE(timer),
+ evt->gpt_base + GPT_IRQ_EN_REG);
+}
+
+static void __init mtk_timer_init(struct device_node *node)
+{
+ struct mtk_clock_event_device *evt;
+ struct resource res;
+ unsigned long rate = 0;
+ struct clk *clk;
+
+ evt = kzalloc(sizeof(*evt), GFP_KERNEL);
+ if (!evt) {
+ pr_warn("Can't allocate mtk clock event driver struct");
+ return;
+ }
+
+ evt->dev.name = "mtk_tick";
+ evt->dev.rating = 300;
+ evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+ evt->dev.set_mode = mtk_clkevt_mode;
+ evt->dev.set_next_event = mtk_clkevt_next_event;
+ evt->dev.cpumask = cpu_possible_mask;
+
+ evt->gpt_base = of_io_request_and_map(node, 0, "mtk-timer");
+ if (IS_ERR(evt->gpt_base)) {
+ pr_warn("Can't get resource\n");
+ return;
+ }
+
+ evt->dev.irq = irq_of_parse_and_map(node, 0);
+ if (evt->dev.irq <= 0) {
+ pr_warn("Can't parse IRQ");
+ goto err_mem;
+ }
+
+ clk = of_clk_get(node, 0);
+ if (IS_ERR(clk)) {
+ pr_warn("Can't get timer clock");
+ goto err_irq;
+ }
+
+ if (clk_prepare_enable(clk)) {
+ pr_warn("Can't prepare clock");
+ goto err_clk_put;
+ }
+ rate = clk_get_rate(clk);
+
+ if (request_irq(evt->dev.irq, mtk_timer_interrupt,
+ IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
+ pr_warn("failed to setup irq %d\n", evt->dev.irq);
+ goto err_clk_disable;
+ }
+
+ evt->ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
+
+ mtk_timer_global_reset(evt);
+
+ /* Configure clock source */
+ mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
+ clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
+ node->name, rate, 300, 32, clocksource_mmio_readl_up);
+
+ /* Configure clock event */
+ mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
+ mtk_timer_enable_irq(evt, GPT_CLK_EVT);
+
+ clockevents_config_and_register(&evt->dev, rate, 0x3,
+ 0xffffffff);
+ return;
+
+err_clk_disable:
+ clk_disable_unprepare(clk);
+err_clk_put:
+ clk_put(clk);
+err_irq:
+ irq_dispose_mapping(evt->dev.irq);
+err_mem:
+ iounmap(evt->gpt_base);
+ of_address_to_resource(node, 0, &res);
+ release_mem_region(res.start, resource_size(&res));
+}
+CLOCKSOURCE_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_timer_init);
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/pxa_timer.c
new file mode 100644
index 000000000000..941f3f344e08
--- /dev/null
+++ b/drivers/clocksource/pxa_timer.c
@@ -0,0 +1,227 @@
+/*
+ * arch/arm/mach-pxa/time.c
+ *
+ * PXA clocksource, clockevents, and OST interrupt handlers.
+ * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>.
+ *
+ * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
+ * by MontaVista Software, Inc. (Nico, your code rocks!)
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#include <asm/div64.h>
+
+#define OSMR0 0x00 /* OS Timer 0 Match Register */
+#define OSMR1 0x04 /* OS Timer 1 Match Register */
+#define OSMR2 0x08 /* OS Timer 2 Match Register */
+#define OSMR3 0x0C /* OS Timer 3 Match Register */
+
+#define OSCR 0x10 /* OS Timer Counter Register */
+#define OSSR 0x14 /* OS Timer Status Register */
+#define OWER 0x18 /* OS Timer Watchdog Enable Register */
+#define OIER 0x1C /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
+
+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
+
+/*
+ * This is PXA's sched_clock implementation. This has a resolution
+ * of at least 308 ns and a maximum value of 208 days.
+ *
+ * The return value is guaranteed to be monotonic in that range as
+ * long as there is always less than 582 seconds between successive
+ * calls to sched_clock() which should always be the case in practice.
+ */
+
+#define timer_readl(reg) readl_relaxed(timer_base + (reg))
+#define timer_writel(val, reg) writel_relaxed((val), timer_base + (reg))
+
+static void __iomem *timer_base;
+
+static u64 notrace pxa_read_sched_clock(void)
+{
+ return timer_readl(OSCR);
+}
+
+
+#define MIN_OSCR_DELTA 16
+
+static irqreturn_t
+pxa_ost0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* Disarm the compare/match, signal the event. */
+ timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
+ timer_writel(OSSR_M0, OSSR);
+ c->event_handler(c);
+
+ return IRQ_HANDLED;
+}
+
+static int
+pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+ unsigned long next, oscr;
+
+ timer_writel(timer_readl(OIER) | OIER_E0, OIER);
+ next = timer_readl(OSCR) + delta;
+ timer_writel(next, OSMR0);
+ oscr = timer_readl(OSCR);
+
+ return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+}
+
+static void
+pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
+ timer_writel(OSSR_M0, OSSR);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* initializing, released, or preparing for suspend */
+ timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
+ timer_writel(OSSR_M0, OSSR);
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+}
+
+#ifdef CONFIG_PM
+static unsigned long osmr[4], oier, oscr;
+
+static void pxa_timer_suspend(struct clock_event_device *cedev)
+{
+ osmr[0] = timer_readl(OSMR0);
+ osmr[1] = timer_readl(OSMR1);
+ osmr[2] = timer_readl(OSMR2);
+ osmr[3] = timer_readl(OSMR3);
+ oier = timer_readl(OIER);
+ oscr = timer_readl(OSCR);
+}
+
+static void pxa_timer_resume(struct clock_event_device *cedev)
+{
+ /*
+ * Ensure that we have at least MIN_OSCR_DELTA between match
+ * register 0 and the OSCR, to guarantee that we will receive
+ * the one-shot timer interrupt. We adjust OSMR0 in preference
+ * to OSCR to guarantee that OSCR is monotonically incrementing.
+ */
+ if (osmr[0] - oscr < MIN_OSCR_DELTA)
+ osmr[0] += MIN_OSCR_DELTA;
+
+ timer_writel(osmr[0], OSMR0);
+ timer_writel(osmr[1], OSMR1);
+ timer_writel(osmr[2], OSMR2);
+ timer_writel(osmr[3], OSMR3);
+ timer_writel(oier, OIER);
+ timer_writel(oscr, OSCR);
+}
+#else
+#define pxa_timer_suspend NULL
+#define pxa_timer_resume NULL
+#endif
+
+static struct clock_event_device ckevt_pxa_osmr0 = {
+ .name = "osmr0",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = pxa_osmr0_set_next_event,
+ .set_mode = pxa_osmr0_set_mode,
+ .suspend = pxa_timer_suspend,
+ .resume = pxa_timer_resume,
+};
+
+static struct irqaction pxa_ost0_irq = {
+ .name = "ost0",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = pxa_ost0_interrupt,
+ .dev_id = &ckevt_pxa_osmr0,
+};
+
+static void pxa_timer_common_init(int irq, unsigned long clock_tick_rate)
+{
+ timer_writel(0, OIER);
+ timer_writel(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
+
+ sched_clock_register(pxa_read_sched_clock, 32, clock_tick_rate);
+
+ ckevt_pxa_osmr0.cpumask = cpumask_of(0);
+
+ setup_irq(irq, &pxa_ost0_irq);
+
+ clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200,
+ 32, clocksource_mmio_readl_up);
+ clockevents_config_and_register(&ckevt_pxa_osmr0, clock_tick_rate,
+ MIN_OSCR_DELTA * 2, 0x7fffffff);
+}
+
+static void __init pxa_timer_dt_init(struct device_node *np)
+{
+ struct clk *clk;
+ int irq;
+
+ /* timer registers are shared with watchdog timer */
+ timer_base = of_iomap(np, 0);
+ if (!timer_base)
+ panic("%s: unable to map resource\n", np->name);
+
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ pr_crit("%s: unable to get clk\n", np->name);
+ return;
+ }
+ clk_prepare_enable(clk);
+
+ /* we are only interested in OS-timer0 irq */
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq <= 0) {
+ pr_crit("%s: unable to parse OS-timer0 irq\n", np->name);
+ return;
+ }
+
+ pxa_timer_common_init(irq, clk_get_rate(clk));
+}
+CLOCKSOURCE_OF_DECLARE(pxa_timer, "marvell,pxa-timer", pxa_timer_dt_init);
+
+/*
+ * Legacy timer init for non device-tree boards.
+ */
+void __init pxa_timer_nodt_init(int irq, void __iomem *base,
+ unsigned long clock_tick_rate)
+{
+ struct clk *clk;
+
+ timer_base = base;
+ clk = clk_get(NULL, "OSTIMER0");
+ if (clk && !IS_ERR(clk))
+ clk_prepare_enable(clk);
+ else
+ pr_crit("%s: unable to get clk\n", __func__);
+
+ pxa_timer_common_init(irq, clock_tick_rate);
+}
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index dfa780396b91..2bd13b53b727 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -24,6 +24,7 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
@@ -114,14 +115,15 @@ struct sh_cmt_device {
struct platform_device *pdev;
const struct sh_cmt_info *info;
- bool legacy;
- void __iomem *mapbase_ch;
void __iomem *mapbase;
struct clk *clk;
+ raw_spinlock_t lock; /* Protect the shared start/stop register */
+
struct sh_cmt_channel *channels;
unsigned int num_channels;
+ unsigned int hw_channels;
bool has_clockevent;
bool has_clocksource;
@@ -301,14 +303,12 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_channel *ch,
return v2;
}
-static DEFINE_RAW_SPINLOCK(sh_cmt_lock);
-
static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
{
unsigned long flags, value;
/* start stop register shared by multiple timer channels */
- raw_spin_lock_irqsave(&sh_cmt_lock, flags);
+ raw_spin_lock_irqsave(&ch->cmt->lock, flags);
value = sh_cmt_read_cmstr(ch);
if (start)
@@ -317,7 +317,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
value &= ~(1 << ch->timer_bit);
sh_cmt_write_cmstr(ch, value);
- raw_spin_unlock_irqrestore(&sh_cmt_lock, flags);
+ raw_spin_unlock_irqrestore(&ch->cmt->lock, flags);
}
static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
@@ -792,7 +792,7 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
int irq;
int ret;
- irq = platform_get_irq(ch->cmt->pdev, ch->cmt->legacy ? 0 : ch->index);
+ irq = platform_get_irq(ch->cmt->pdev, ch->index);
if (irq < 0) {
dev_err(&ch->cmt->pdev->dev, "ch%u: failed to get irq\n",
ch->index);
@@ -863,33 +863,26 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
* Compute the address of the channel control register block. For the
* timers with a per-channel start/stop register, compute its address
* as well.
- *
- * For legacy configuration the address has been mapped explicitly.
*/
- if (cmt->legacy) {
- ch->ioctrl = cmt->mapbase_ch;
- } else {
- switch (cmt->info->model) {
- case SH_CMT_16BIT:
- ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
- break;
- case SH_CMT_32BIT:
- case SH_CMT_48BIT:
- ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
- break;
- case SH_CMT_32BIT_FAST:
- /*
- * The 32-bit "fast" timer has a single channel at hwidx
- * 5 but is located at offset 0x40 instead of 0x60 for
- * some reason.
- */
- ch->ioctrl = cmt->mapbase + 0x40;
- break;
- case SH_CMT_48BIT_GEN2:
- ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
- ch->ioctrl = ch->iostart + 0x10;
- break;
- }
+ switch (cmt->info->model) {
+ case SH_CMT_16BIT:
+ ch->ioctrl = cmt->mapbase + 2 + ch->hwidx * 6;
+ break;
+ case SH_CMT_32BIT:
+ case SH_CMT_48BIT:
+ ch->ioctrl = cmt->mapbase + 0x10 + ch->hwidx * 0x10;
+ break;
+ case SH_CMT_32BIT_FAST:
+ /*
+ * The 32-bit "fast" timer has a single channel at hwidx 5 but
+ * is located at offset 0x40 instead of 0x60 for some reason.
+ */
+ ch->ioctrl = cmt->mapbase + 0x40;
+ break;
+ case SH_CMT_48BIT_GEN2:
+ ch->iostart = cmt->mapbase + ch->hwidx * 0x100;
+ ch->ioctrl = ch->iostart + 0x10;
+ break;
}
if (cmt->info->width == (sizeof(ch->max_match_value) * 8))
@@ -900,12 +893,7 @@ static int sh_cmt_setup_channel(struct sh_cmt_channel *ch, unsigned int index,
ch->match_value = ch->max_match_value;
raw_spin_lock_init(&ch->lock);
- if (cmt->legacy) {
- ch->timer_bit = ch->hwidx;
- } else {
- ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2
- ? 0 : ch->hwidx;
- }
+ ch->timer_bit = cmt->info->model == SH_CMT_48BIT_GEN2 ? 0 : ch->hwidx;
ret = sh_cmt_register(ch, dev_name(&cmt->pdev->dev),
clockevent, clocksource);
@@ -938,75 +926,65 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt)
return 0;
}
-static int sh_cmt_map_memory_legacy(struct sh_cmt_device *cmt)
-{
- struct sh_timer_config *cfg = cmt->pdev->dev.platform_data;
- struct resource *res, *res2;
-
- /* map memory, let mapbase_ch point to our channel */
- res = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&cmt->pdev->dev, "failed to get I/O memory\n");
- return -ENXIO;
- }
-
- cmt->mapbase_ch = ioremap_nocache(res->start, resource_size(res));
- if (cmt->mapbase_ch == NULL) {
- dev_err(&cmt->pdev->dev, "failed to remap I/O memory\n");
- return -ENXIO;
- }
-
- /* optional resource for the shared timer start/stop register */
- res2 = platform_get_resource(cmt->pdev, IORESOURCE_MEM, 1);
-
- /* map second resource for CMSTR */
- cmt->mapbase = ioremap_nocache(res2 ? res2->start :
- res->start - cfg->channel_offset,
- res2 ? resource_size(res2) : 2);
- if (cmt->mapbase == NULL) {
- dev_err(&cmt->pdev->dev, "failed to remap I/O second memory\n");
- iounmap(cmt->mapbase_ch);
- return -ENXIO;
- }
-
- /* identify the model based on the resources */
- if (resource_size(res) == 6)
- cmt->info = &sh_cmt_info[SH_CMT_16BIT];
- else if (res2 && (resource_size(res2) == 4))
- cmt->info = &sh_cmt_info[SH_CMT_48BIT_GEN2];
- else
- cmt->info = &sh_cmt_info[SH_CMT_32BIT];
+static const struct platform_device_id sh_cmt_id_table[] = {
+ { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
+ { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
+ { "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
+ { "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
+ { "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
- return 0;
-}
+static const struct of_device_id sh_cmt_of_table[] __maybe_unused = {
+ { .compatible = "renesas,cmt-32", .data = &sh_cmt_info[SH_CMT_32BIT] },
+ { .compatible = "renesas,cmt-32-fast", .data = &sh_cmt_info[SH_CMT_32BIT_FAST] },
+ { .compatible = "renesas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] },
+ { .compatible = "renesas,cmt-48-gen2", .data = &sh_cmt_info[SH_CMT_48BIT_GEN2] },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
-static void sh_cmt_unmap_memory(struct sh_cmt_device *cmt)
+static int sh_cmt_parse_dt(struct sh_cmt_device *cmt)
{
- iounmap(cmt->mapbase);
- if (cmt->mapbase_ch)
- iounmap(cmt->mapbase_ch);
+ struct device_node *np = cmt->pdev->dev.of_node;
+
+ return of_property_read_u32(np, "renesas,channels-mask",
+ &cmt->hw_channels);
}
static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
{
- struct sh_timer_config *cfg = pdev->dev.platform_data;
- const struct platform_device_id *id = pdev->id_entry;
- unsigned int hw_channels;
+ unsigned int mask;
+ unsigned int i;
int ret;
memset(cmt, 0, sizeof(*cmt));
cmt->pdev = pdev;
+ raw_spin_lock_init(&cmt->lock);
+
+ if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+ const struct of_device_id *id;
+
+ id = of_match_node(sh_cmt_of_table, pdev->dev.of_node);
+ cmt->info = id->data;
- if (!cfg) {
+ ret = sh_cmt_parse_dt(cmt);
+ if (ret < 0)
+ return ret;
+ } else if (pdev->dev.platform_data) {
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+ const struct platform_device_id *id = pdev->id_entry;
+
+ cmt->info = (const struct sh_cmt_info *)id->driver_data;
+ cmt->hw_channels = cfg->channels_mask;
+ } else {
dev_err(&cmt->pdev->dev, "missing platform data\n");
return -ENXIO;
}
- cmt->info = (const struct sh_cmt_info *)id->driver_data;
- cmt->legacy = cmt->info ? false : true;
-
/* Get hold of clock. */
- cmt->clk = clk_get(&cmt->pdev->dev, cmt->legacy ? "cmt_fck" : "fck");
+ cmt->clk = clk_get(&cmt->pdev->dev, "fck");
if (IS_ERR(cmt->clk)) {
dev_err(&cmt->pdev->dev, "cannot get clock\n");
return PTR_ERR(cmt->clk);
@@ -1016,28 +994,13 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
if (ret < 0)
goto err_clk_put;
- /*
- * Map the memory resource(s). We need to support both the legacy
- * platform device configuration (with one device per channel) and the
- * new version (with multiple channels per device).
- */
- if (cmt->legacy)
- ret = sh_cmt_map_memory_legacy(cmt);
- else
- ret = sh_cmt_map_memory(cmt);
-
+ /* Map the memory resource(s). */
+ ret = sh_cmt_map_memory(cmt);
if (ret < 0)
goto err_clk_unprepare;
/* Allocate and setup the channels. */
- if (cmt->legacy) {
- cmt->num_channels = 1;
- hw_channels = 0;
- } else {
- cmt->num_channels = hweight8(cfg->channels_mask);
- hw_channels = cfg->channels_mask;
- }
-
+ cmt->num_channels = hweight8(cmt->hw_channels);
cmt->channels = kzalloc(cmt->num_channels * sizeof(*cmt->channels),
GFP_KERNEL);
if (cmt->channels == NULL) {
@@ -1045,35 +1008,21 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
goto err_unmap;
}
- if (cmt->legacy) {
- ret = sh_cmt_setup_channel(&cmt->channels[0],
- cfg->timer_bit, cfg->timer_bit,
- cfg->clockevent_rating != 0,
- cfg->clocksource_rating != 0, cmt);
+ /*
+ * Use the first channel as a clock event device and the second channel
+ * as a clock source. If only one channel is available use it for both.
+ */
+ for (i = 0, mask = cmt->hw_channels; i < cmt->num_channels; ++i) {
+ unsigned int hwidx = ffs(mask) - 1;
+ bool clocksource = i == 1 || cmt->num_channels == 1;
+ bool clockevent = i == 0;
+
+ ret = sh_cmt_setup_channel(&cmt->channels[i], i, hwidx,
+ clockevent, clocksource, cmt);
if (ret < 0)
goto err_unmap;
- } else {
- unsigned int mask = hw_channels;
- unsigned int i;
- /*
- * Use the first channel as a clock event device and the second
- * channel as a clock source. If only one channel is available
- * use it for both.
- */
- for (i = 0; i < cmt->num_channels; ++i) {
- unsigned int hwidx = ffs(mask) - 1;
- bool clocksource = i == 1 || cmt->num_channels == 1;
- bool clockevent = i == 0;
-
- ret = sh_cmt_setup_channel(&cmt->channels[i], i, hwidx,
- clockevent, clocksource,
- cmt);
- if (ret < 0)
- goto err_unmap;
-
- mask &= ~(1 << hwidx);
- }
+ mask &= ~(1 << hwidx);
}
platform_set_drvdata(pdev, cmt);
@@ -1082,7 +1031,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
err_unmap:
kfree(cmt->channels);
- sh_cmt_unmap_memory(cmt);
+ iounmap(cmt->mapbase);
err_clk_unprepare:
clk_unprepare(cmt->clk);
err_clk_put:
@@ -1132,22 +1081,12 @@ static int sh_cmt_remove(struct platform_device *pdev)
return -EBUSY; /* cannot unregister clockevent and clocksource */
}
-static const struct platform_device_id sh_cmt_id_table[] = {
- { "sh_cmt", 0 },
- { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] },
- { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] },
- { "sh-cmt-32-fast", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT_FAST] },
- { "sh-cmt-48", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT] },
- { "sh-cmt-48-gen2", (kernel_ulong_t)&sh_cmt_info[SH_CMT_48BIT_GEN2] },
- { }
-};
-MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
-
static struct platform_driver sh_cmt_device_driver = {
.probe = sh_cmt_probe,
.remove = sh_cmt_remove,
.driver = {
.name = "sh_cmt",
+ .of_match_table = of_match_ptr(sh_cmt_of_table),
},
.id_table = sh_cmt_id_table,
};
diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c
index 188d4e092efc..3d88698cf2b8 100644
--- a/drivers/clocksource/sh_mtu2.c
+++ b/drivers/clocksource/sh_mtu2.c
@@ -23,6 +23,7 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
@@ -37,7 +38,6 @@ struct sh_mtu2_channel {
unsigned int index;
void __iomem *base;
- int irq;
struct clock_event_device ced;
};
@@ -48,15 +48,14 @@ struct sh_mtu2_device {
void __iomem *mapbase;
struct clk *clk;
+ raw_spinlock_t lock; /* Protect the shared registers */
+
struct sh_mtu2_channel *channels;
unsigned int num_channels;
- bool legacy;
bool has_clockevent;
};
-static DEFINE_RAW_SPINLOCK(sh_mtu2_lock);
-
#define TSTR -1 /* shared register */
#define TCR 0 /* channel register */
#define TMDR 1 /* channel register */
@@ -162,12 +161,8 @@ static inline unsigned long sh_mtu2_read(struct sh_mtu2_channel *ch, int reg_nr)
{
unsigned long offs;
- if (reg_nr == TSTR) {
- if (ch->mtu->legacy)
- return ioread8(ch->mtu->mapbase);
- else
- return ioread8(ch->mtu->mapbase + 0x280);
- }
+ if (reg_nr == TSTR)
+ return ioread8(ch->mtu->mapbase + 0x280);
offs = mtu2_reg_offs[reg_nr];
@@ -182,12 +177,8 @@ static inline void sh_mtu2_write(struct sh_mtu2_channel *ch, int reg_nr,
{
unsigned long offs;
- if (reg_nr == TSTR) {
- if (ch->mtu->legacy)
- return iowrite8(value, ch->mtu->mapbase);
- else
- return iowrite8(value, ch->mtu->mapbase + 0x280);
- }
+ if (reg_nr == TSTR)
+ return iowrite8(value, ch->mtu->mapbase + 0x280);
offs = mtu2_reg_offs[reg_nr];
@@ -202,7 +193,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_channel *ch, int start)
unsigned long flags, value;
/* start stop register shared by multiple timer channels */
- raw_spin_lock_irqsave(&sh_mtu2_lock, flags);
+ raw_spin_lock_irqsave(&ch->mtu->lock, flags);
value = sh_mtu2_read(ch, TSTR);
if (start)
@@ -211,7 +202,7 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_channel *ch, int start)
value &= ~(1 << ch->index);
sh_mtu2_write(ch, TSTR, value);
- raw_spin_unlock_irqrestore(&sh_mtu2_lock, flags);
+ raw_spin_unlock_irqrestore(&ch->mtu->lock, flags);
}
static int sh_mtu2_enable(struct sh_mtu2_channel *ch)
@@ -331,7 +322,6 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
const char *name)
{
struct clock_event_device *ced = &ch->ced;
- int ret;
ced->name = name;
ced->features = CLOCK_EVT_FEAT_PERIODIC;
@@ -344,24 +334,12 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_channel *ch,
dev_info(&ch->mtu->pdev->dev, "ch%u: used for clock events\n",
ch->index);
clockevents_register_device(ced);
-
- ret = request_irq(ch->irq, sh_mtu2_interrupt,
- IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
- dev_name(&ch->mtu->pdev->dev), ch);
- if (ret) {
- dev_err(&ch->mtu->pdev->dev, "ch%u: failed to request irq %d\n",
- ch->index, ch->irq);
- return;
- }
}
-static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name,
- bool clockevent)
+static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name)
{
- if (clockevent) {
- ch->mtu->has_clockevent = true;
- sh_mtu2_register_clockevent(ch, name);
- }
+ ch->mtu->has_clockevent = true;
+ sh_mtu2_register_clockevent(ch, name);
return 0;
}
@@ -372,40 +350,32 @@ static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index,
static const unsigned int channel_offsets[] = {
0x300, 0x380, 0x000,
};
- bool clockevent;
+ char name[6];
+ int irq;
+ int ret;
ch->mtu = mtu;
- if (mtu->legacy) {
- struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
-
- clockevent = cfg->clockevent_rating != 0;
-
- ch->irq = platform_get_irq(mtu->pdev, 0);
- ch->base = mtu->mapbase - cfg->channel_offset;
- ch->index = cfg->timer_bit;
- } else {
- char name[6];
-
- clockevent = true;
-
- sprintf(name, "tgi%ua", index);
- ch->irq = platform_get_irq_byname(mtu->pdev, name);
- ch->base = mtu->mapbase + channel_offsets[index];
- ch->index = index;
- }
-
- if (ch->irq < 0) {
+ sprintf(name, "tgi%ua", index);
+ irq = platform_get_irq_byname(mtu->pdev, name);
+ if (irq < 0) {
/* Skip channels with no declared interrupt. */
- if (!mtu->legacy)
- return 0;
+ return 0;
+ }
- dev_err(&mtu->pdev->dev, "ch%u: failed to get irq\n",
- ch->index);
- return ch->irq;
+ ret = request_irq(irq, sh_mtu2_interrupt,
+ IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
+ dev_name(&ch->mtu->pdev->dev), ch);
+ if (ret) {
+ dev_err(&ch->mtu->pdev->dev, "ch%u: failed to request irq %d\n",
+ index, irq);
+ return ret;
}
- return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev), clockevent);
+ ch->base = mtu->mapbase + channel_offsets[index];
+ ch->index = index;
+
+ return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev));
}
static int sh_mtu2_map_memory(struct sh_mtu2_device *mtu)
@@ -422,46 +392,21 @@ static int sh_mtu2_map_memory(struct sh_mtu2_device *mtu)
if (mtu->mapbase == NULL)
return -ENXIO;
- /*
- * In legacy platform device configuration (with one device per channel)
- * the resource points to the channel base address.
- */
- if (mtu->legacy) {
- struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
- mtu->mapbase += cfg->channel_offset;
- }
-
return 0;
}
-static void sh_mtu2_unmap_memory(struct sh_mtu2_device *mtu)
-{
- if (mtu->legacy) {
- struct sh_timer_config *cfg = mtu->pdev->dev.platform_data;
- mtu->mapbase -= cfg->channel_offset;
- }
-
- iounmap(mtu->mapbase);
-}
-
static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
struct platform_device *pdev)
{
- struct sh_timer_config *cfg = pdev->dev.platform_data;
- const struct platform_device_id *id = pdev->id_entry;
unsigned int i;
int ret;
mtu->pdev = pdev;
- mtu->legacy = id->driver_data;
- if (mtu->legacy && !cfg) {
- dev_err(&mtu->pdev->dev, "missing platform data\n");
- return -ENXIO;
- }
+ raw_spin_lock_init(&mtu->lock);
/* Get hold of clock. */
- mtu->clk = clk_get(&mtu->pdev->dev, mtu->legacy ? "mtu2_fck" : "fck");
+ mtu->clk = clk_get(&mtu->pdev->dev, "fck");
if (IS_ERR(mtu->clk)) {
dev_err(&mtu->pdev->dev, "cannot get clock\n");
return PTR_ERR(mtu->clk);
@@ -479,10 +424,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
}
/* Allocate and setup the channels. */
- if (mtu->legacy)
- mtu->num_channels = 1;
- else
- mtu->num_channels = 3;
+ mtu->num_channels = 3;
mtu->channels = kzalloc(sizeof(*mtu->channels) * mtu->num_channels,
GFP_KERNEL);
@@ -491,16 +433,10 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
goto err_unmap;
}
- if (mtu->legacy) {
- ret = sh_mtu2_setup_channel(&mtu->channels[0], 0, mtu);
+ for (i = 0; i < mtu->num_channels; ++i) {
+ ret = sh_mtu2_setup_channel(&mtu->channels[i], i, mtu);
if (ret < 0)
goto err_unmap;
- } else {
- for (i = 0; i < mtu->num_channels; ++i) {
- ret = sh_mtu2_setup_channel(&mtu->channels[i], i, mtu);
- if (ret < 0)
- goto err_unmap;
- }
}
platform_set_drvdata(pdev, mtu);
@@ -509,7 +445,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
err_unmap:
kfree(mtu->channels);
- sh_mtu2_unmap_memory(mtu);
+ iounmap(mtu->mapbase);
err_clk_unprepare:
clk_unprepare(mtu->clk);
err_clk_put:
@@ -560,17 +496,23 @@ static int sh_mtu2_remove(struct platform_device *pdev)
}
static const struct platform_device_id sh_mtu2_id_table[] = {
- { "sh_mtu2", 1 },
{ "sh-mtu2", 0 },
{ },
};
MODULE_DEVICE_TABLE(platform, sh_mtu2_id_table);
+static const struct of_device_id sh_mtu2_of_table[] __maybe_unused = {
+ { .compatible = "renesas,mtu2" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sh_mtu2_of_table);
+
static struct platform_driver sh_mtu2_device_driver = {
.probe = sh_mtu2_probe,
.remove = sh_mtu2_remove,
.driver = {
.name = "sh_mtu2",
+ .of_match_table = of_match_ptr(sh_mtu2_of_table),
},
.id_table = sh_mtu2_id_table,
};
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 6bd17a8f3dd4..0f665b8f2461 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -24,6 +24,7 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
@@ -32,7 +33,6 @@
#include <linux/spinlock.h>
enum sh_tmu_model {
- SH_TMU_LEGACY,
SH_TMU,
SH_TMU_SH3,
};
@@ -62,6 +62,8 @@ struct sh_tmu_device {
enum sh_tmu_model model;
+ raw_spinlock_t lock; /* Protect the shared start/stop register */
+
struct sh_tmu_channel *channels;
unsigned int num_channels;
@@ -69,8 +71,6 @@ struct sh_tmu_device {
bool has_clocksource;
};
-static DEFINE_RAW_SPINLOCK(sh_tmu_lock);
-
#define TSTR -1 /* shared register */
#define TCOR 0 /* channel register */
#define TCNT 1 /* channel register */
@@ -91,8 +91,6 @@ static inline unsigned long sh_tmu_read(struct sh_tmu_channel *ch, int reg_nr)
if (reg_nr == TSTR) {
switch (ch->tmu->model) {
- case SH_TMU_LEGACY:
- return ioread8(ch->tmu->mapbase);
case SH_TMU_SH3:
return ioread8(ch->tmu->mapbase + 2);
case SH_TMU:
@@ -115,8 +113,6 @@ static inline void sh_tmu_write(struct sh_tmu_channel *ch, int reg_nr,
if (reg_nr == TSTR) {
switch (ch->tmu->model) {
- case SH_TMU_LEGACY:
- return iowrite8(value, ch->tmu->mapbase);
case SH_TMU_SH3:
return iowrite8(value, ch->tmu->mapbase + 2);
case SH_TMU:
@@ -137,7 +133,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_channel *ch, int start)
unsigned long flags, value;
/* start stop register shared by multiple timer channels */
- raw_spin_lock_irqsave(&sh_tmu_lock, flags);
+ raw_spin_lock_irqsave(&ch->tmu->lock, flags);
value = sh_tmu_read(ch, TSTR);
if (start)
@@ -146,7 +142,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_channel *ch, int start)
value &= ~(1 << ch->index);
sh_tmu_write(ch, TSTR, value);
- raw_spin_unlock_irqrestore(&sh_tmu_lock, flags);
+ raw_spin_unlock_irqrestore(&ch->tmu->lock, flags);
}
static int __sh_tmu_enable(struct sh_tmu_channel *ch)
@@ -476,27 +472,12 @@ static int sh_tmu_channel_setup(struct sh_tmu_channel *ch, unsigned int index,
return 0;
ch->tmu = tmu;
+ ch->index = index;
- if (tmu->model == SH_TMU_LEGACY) {
- struct sh_timer_config *cfg = tmu->pdev->dev.platform_data;
-
- /*
- * The SH3 variant (SH770x, SH7705, SH7710 and SH7720) maps
- * channel registers blocks at base + 2 + 12 * index, while all
- * other variants map them at base + 4 + 12 * index. We can
- * compute the index by just dividing by 12, the 2 bytes or 4
- * bytes offset being hidden by the integer division.
- */
- ch->index = cfg->channel_offset / 12;
- ch->base = tmu->mapbase + cfg->channel_offset;
- } else {
- ch->index = index;
-
- if (tmu->model == SH_TMU_SH3)
- ch->base = tmu->mapbase + 4 + ch->index * 12;
- else
- ch->base = tmu->mapbase + 8 + ch->index * 12;
- }
+ if (tmu->model == SH_TMU_SH3)
+ ch->base = tmu->mapbase + 4 + ch->index * 12;
+ else
+ ch->base = tmu->mapbase + 8 + ch->index * 12;
ch->irq = platform_get_irq(tmu->pdev, index);
if (ch->irq < 0) {
@@ -526,46 +507,53 @@ static int sh_tmu_map_memory(struct sh_tmu_device *tmu)
if (tmu->mapbase == NULL)
return -ENXIO;
- /*
- * In legacy platform device configuration (with one device per channel)
- * the resource points to the channel base address.
- */
- if (tmu->model == SH_TMU_LEGACY) {
- struct sh_timer_config *cfg = tmu->pdev->dev.platform_data;
- tmu->mapbase -= cfg->channel_offset;
- }
-
return 0;
}
-static void sh_tmu_unmap_memory(struct sh_tmu_device *tmu)
+static int sh_tmu_parse_dt(struct sh_tmu_device *tmu)
{
- if (tmu->model == SH_TMU_LEGACY) {
- struct sh_timer_config *cfg = tmu->pdev->dev.platform_data;
- tmu->mapbase += cfg->channel_offset;
+ struct device_node *np = tmu->pdev->dev.of_node;
+
+ tmu->model = SH_TMU;
+ tmu->num_channels = 3;
+
+ of_property_read_u32(np, "#renesas,channels", &tmu->num_channels);
+
+ if (tmu->num_channels != 2 && tmu->num_channels != 3) {
+ dev_err(&tmu->pdev->dev, "invalid number of channels %u\n",
+ tmu->num_channels);
+ return -EINVAL;
}
- iounmap(tmu->mapbase);
+ return 0;
}
static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)
{
- struct sh_timer_config *cfg = pdev->dev.platform_data;
- const struct platform_device_id *id = pdev->id_entry;
unsigned int i;
int ret;
- if (!cfg) {
+ tmu->pdev = pdev;
+
+ raw_spin_lock_init(&tmu->lock);
+
+ if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+ ret = sh_tmu_parse_dt(tmu);
+ if (ret < 0)
+ return ret;
+ } else if (pdev->dev.platform_data) {
+ const struct platform_device_id *id = pdev->id_entry;
+ struct sh_timer_config *cfg = pdev->dev.platform_data;
+
+ tmu->model = id->driver_data;
+ tmu->num_channels = hweight8(cfg->channels_mask);
+ } else {
dev_err(&tmu->pdev->dev, "missing platform data\n");
return -ENXIO;
}
- tmu->pdev = pdev;
- tmu->model = id->driver_data;
-
/* Get hold of clock. */
- tmu->clk = clk_get(&tmu->pdev->dev,
- tmu->model == SH_TMU_LEGACY ? "tmu_fck" : "fck");
+ tmu->clk = clk_get(&tmu->pdev->dev, "fck");
if (IS_ERR(tmu->clk)) {
dev_err(&tmu->pdev->dev, "cannot get clock\n");
return PTR_ERR(tmu->clk);
@@ -583,11 +571,6 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)
}
/* Allocate and setup the channels. */
- if (tmu->model == SH_TMU_LEGACY)
- tmu->num_channels = 1;
- else
- tmu->num_channels = hweight8(cfg->channels_mask);
-
tmu->channels = kzalloc(sizeof(*tmu->channels) * tmu->num_channels,
GFP_KERNEL);
if (tmu->channels == NULL) {
@@ -595,23 +578,15 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)
goto err_unmap;
}
- if (tmu->model == SH_TMU_LEGACY) {
- ret = sh_tmu_channel_setup(&tmu->channels[0], 0,
- cfg->clockevent_rating != 0,
- cfg->clocksource_rating != 0, tmu);
+ /*
+ * Use the first channel as a clock event device and the second channel
+ * as a clock source.
+ */
+ for (i = 0; i < tmu->num_channels; ++i) {
+ ret = sh_tmu_channel_setup(&tmu->channels[i], i,
+ i == 0, i == 1, tmu);
if (ret < 0)
goto err_unmap;
- } else {
- /*
- * Use the first channel as a clock event device and the second
- * channel as a clock source.
- */
- for (i = 0; i < tmu->num_channels; ++i) {
- ret = sh_tmu_channel_setup(&tmu->channels[i], i,
- i == 0, i == 1, tmu);
- if (ret < 0)
- goto err_unmap;
- }
}
platform_set_drvdata(pdev, tmu);
@@ -620,7 +595,7 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)
err_unmap:
kfree(tmu->channels);
- sh_tmu_unmap_memory(tmu);
+ iounmap(tmu->mapbase);
err_clk_unprepare:
clk_unprepare(tmu->clk);
err_clk_put:
@@ -671,18 +646,24 @@ static int sh_tmu_remove(struct platform_device *pdev)
}
static const struct platform_device_id sh_tmu_id_table[] = {
- { "sh_tmu", SH_TMU_LEGACY },
{ "sh-tmu", SH_TMU },
{ "sh-tmu-sh3", SH_TMU_SH3 },
{ }
};
MODULE_DEVICE_TABLE(platform, sh_tmu_id_table);
+static const struct of_device_id sh_tmu_of_table[] __maybe_unused = {
+ { .compatible = "renesas,tmu" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, sh_tmu_of_table);
+
static struct platform_driver sh_tmu_device_driver = {
.probe = sh_tmu_probe,
.remove = sh_tmu_remove,
.driver = {
.name = "sh_tmu",
+ .of_match_table = of_match_ptr(sh_tmu_of_table),
},
.id_table = sh_tmu_id_table,
};
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index d1869f02051c..d2616ef16770 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -27,6 +27,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
+#include <linux/delay.h>
#include <asm/mach/time.h>
#include <asm/smp_twd.h>
@@ -53,6 +54,8 @@ static void __iomem *rtc_base;
static struct timespec persistent_ts;
static u64 persistent_ms, last_persistent_ms;
+static struct delay_timer tegra_delay_timer;
+
#define timer_writel(value, reg) \
__raw_writel(value, timer_reg_base + (reg))
#define timer_readl(reg) \
@@ -139,6 +142,11 @@ static void tegra_read_persistent_clock(struct timespec *ts)
*ts = *tsp;
}
+static unsigned long tegra_delay_timer_read_counter_long(void)
+{
+ return readl(timer_reg_base + TIMERUS_CNTR_1US);
+}
+
static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = (struct clock_event_device *)dev_id;
@@ -206,6 +214,11 @@ static void __init tegra20_init_timer(struct device_node *np)
BUG();
}
+ tegra_delay_timer.read_current_timer =
+ tegra_delay_timer_read_counter_long;
+ tegra_delay_timer.freq = 1000000;
+ register_current_timer_delay(&tegra_delay_timer);
+
ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
if (ret) {
pr_err("Failed to register timer IRQ: %d\n", ret);
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c
index dbd30398222a..330e93064692 100644
--- a/drivers/clocksource/timer-marco.c
+++ b/drivers/clocksource/timer-marco.c
@@ -260,6 +260,9 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np)
clk = of_clk_get(np, 0);
BUG_ON(IS_ERR(clk));
+
+ BUG_ON(clk_prepare_enable(clk));
+
rate = clk_get_rate(clk);
BUG_ON(rate < MARCO_CLOCK_FREQ);
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c
index a722aac7ac02..ce18d570e1cd 100644
--- a/drivers/clocksource/timer-prima2.c
+++ b/drivers/clocksource/timer-prima2.c
@@ -200,6 +200,9 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
clk = of_clk_get(np, 0);
BUG_ON(IS_ERR(clk));
+
+ BUG_ON(clk_prepare_enable(clk));
+
rate = clk_get_rate(clk);
BUG_ON(rate < PRIMA2_CLOCK_FREQ);
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index ccdd4c7e748b..15d06fcf0b50 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -69,7 +69,6 @@ void proc_fork_connector(struct task_struct *task)
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
struct task_struct *parent;
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -79,8 +78,7 @@ void proc_fork_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_FORK;
rcu_read_lock();
parent = rcu_dereference(task->real_parent);
@@ -102,7 +100,6 @@ void proc_exec_connector(struct task_struct *task)
{
struct cn_msg *msg;
struct proc_event *ev;
- struct timespec ts;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -112,8 +109,7 @@ void proc_exec_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_EXEC;
ev->event_data.exec.process_pid = task->pid;
ev->event_data.exec.process_tgid = task->tgid;
@@ -130,7 +126,6 @@ void proc_id_connector(struct task_struct *task, int which_id)
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
const struct cred *cred;
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -156,8 +151,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
}
rcu_read_unlock();
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
msg->ack = 0; /* not used */
@@ -170,7 +164,6 @@ void proc_sid_connector(struct task_struct *task)
{
struct cn_msg *msg;
struct proc_event *ev;
- struct timespec ts;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -180,8 +173,7 @@ void proc_sid_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_SID;
ev->event_data.sid.process_pid = task->pid;
ev->event_data.sid.process_tgid = task->tgid;
@@ -197,7 +189,6 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
{
struct cn_msg *msg;
struct proc_event *ev;
- struct timespec ts;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -207,8 +198,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_PTRACE;
ev->event_data.ptrace.process_pid = task->pid;
ev->event_data.ptrace.process_tgid = task->tgid;
@@ -232,7 +222,6 @@ void proc_comm_connector(struct task_struct *task)
{
struct cn_msg *msg;
struct proc_event *ev;
- struct timespec ts;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
if (atomic_read(&proc_event_num_listeners) < 1)
@@ -242,8 +231,7 @@ void proc_comm_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_COMM;
ev->event_data.comm.process_pid = task->pid;
ev->event_data.comm.process_tgid = task->tgid;
@@ -261,7 +249,6 @@ void proc_coredump_connector(struct task_struct *task)
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
@@ -270,8 +257,7 @@ void proc_coredump_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_COREDUMP;
ev->event_data.coredump.process_pid = task->pid;
ev->event_data.coredump.process_tgid = task->tgid;
@@ -288,7 +274,6 @@ void proc_exit_connector(struct task_struct *task)
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
@@ -297,8 +282,7 @@ void proc_exit_connector(struct task_struct *task)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->what = PROC_EVENT_EXIT;
ev->event_data.exit.process_pid = task->pid;
ev->event_data.exit.process_tgid = task->tgid;
@@ -325,7 +309,6 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
struct cn_msg *msg;
struct proc_event *ev;
__u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
if (atomic_read(&proc_event_num_listeners) < 1)
return;
@@ -334,8 +317,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
ev = (struct proc_event *)msg->data;
memset(&ev->event_data, 0, sizeof(ev->event_data));
msg->seq = rcvd_seq;
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
- ev->timestamp_ns = timespec_to_ns(&ts);
+ ev->timestamp_ns = ktime_get_ns();
ev->cpu = -1;
ev->what = PROC_EVENT_NONE;
ev->event_data.ack.err = err;
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index ebac67115009..7364a538e056 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -104,6 +104,7 @@ config ARM_IMX6Q_CPUFREQ
tristate "Freescale i.MX6 cpufreq support"
depends on ARCH_MXC
depends on REGULATOR_ANATOP
+ select PM_OPP
help
This adds cpufreq driver support for Freescale i.MX6 series SoCs.
@@ -118,7 +119,7 @@ config ARM_INTEGRATOR
If in doubt, say Y.
config ARM_KIRKWOOD_CPUFREQ
- def_bool MACH_KIRKWOOD
+ def_bool ARCH_KIRKWOOD || MACH_KIRKWOOD
help
This adds the CPUFreq driver for Marvell Kirkwood
SoCs.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 738c8b7b17dc..db6d9a2fea4d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -49,7 +49,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
# LITTLE drivers, so that it is probed last.
obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o
-obj-$(CONFIG_ARCH_DAVINCI_DA850) += davinci-cpufreq.o
+obj-$(CONFIG_ARCH_DAVINCI) += davinci-cpufreq.o
obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index ee1ae303a07c..86beda9f950b 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -152,11 +152,8 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
goto out_put_reg;
}
- ret = of_init_opp_table(cpu_dev);
- if (ret) {
- pr_err("failed to init OPP table: %d\n", ret);
- goto out_put_clk;
- }
+ /* OPPs might be populated at runtime, don't check for error here */
+ of_init_opp_table(cpu_dev);
ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
if (ret) {
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 62259d27f03e..d9fdeddcef96 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1076,10 +1076,20 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
kfree(policy);
}
-static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
+static int update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu,
+ struct device *cpu_dev)
{
+ int ret;
+
if (WARN_ON(cpu == policy->cpu))
- return;
+ return 0;
+
+ /* Move kobject to the new policy->cpu */
+ ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
+ if (ret) {
+ pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
+ return ret;
+ }
down_write(&policy->rwsem);
@@ -1090,6 +1100,8 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_UPDATE_POLICY_CPU, policy);
+
+ return 0;
}
static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
@@ -1154,7 +1166,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
* by invoking update_policy_cpu().
*/
if (recover_policy && cpu != policy->cpu)
- update_policy_cpu(policy, cpu);
+ WARN_ON(update_policy_cpu(policy, cpu, dev));
else
policy->cpu = cpu;
@@ -1307,38 +1319,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
return __cpufreq_add_dev(dev, sif);
}
-static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
- unsigned int old_cpu)
-{
- struct device *cpu_dev;
- int ret;
-
- /* first sibling now owns the new sysfs dir */
- cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));
-
- sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
- ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
- if (ret) {
- pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
-
- down_write(&policy->rwsem);
- cpumask_set_cpu(old_cpu, policy->cpus);
- up_write(&policy->rwsem);
-
- ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
- "cpufreq");
-
- return -EINVAL;
- }
-
- return cpu_dev->id;
-}
-
static int __cpufreq_remove_dev_prepare(struct device *dev,
struct subsys_interface *sif)
{
unsigned int cpu = dev->id, cpus;
- int new_cpu, ret;
+ int ret;
unsigned long flags;
struct cpufreq_policy *policy;
@@ -1378,14 +1363,23 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
if (cpu != policy->cpu) {
sysfs_remove_link(&dev->kobj, "cpufreq");
} else if (cpus > 1) {
- new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu);
- if (new_cpu >= 0) {
- update_policy_cpu(policy, new_cpu);
+ /* Nominate new CPU */
+ int new_cpu = cpumask_any_but(policy->cpus, cpu);
+ struct device *cpu_dev = get_cpu_device(new_cpu);
- if (!cpufreq_suspended)
- pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
- __func__, new_cpu, cpu);
+ sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
+ ret = update_policy_cpu(policy, new_cpu, cpu_dev);
+ if (ret) {
+ if (sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
+ "cpufreq"))
+ pr_err("%s: Failed to restore kobj link to cpu:%d\n",
+ __func__, cpu_dev->id);
+ return ret;
}
+
+ if (!cpufreq_suspended)
+ pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
+ __func__, new_cpu, cpu);
} else if (cpufreq_driver->stop_cpu && cpufreq_driver->setpolicy) {
cpufreq_driver->stop_cpu(policy);
}
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 18d409189092..ad3f38fd3eb9 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -170,21 +170,24 @@ static void od_check_cpu(int cpu, unsigned int load)
dbs_freq_increase(policy, policy->max);
} else {
/* Calculate the next frequency proportional to load */
- unsigned int freq_next;
- freq_next = load * policy->cpuinfo.max_freq / 100;
+ unsigned int freq_next, min_f, max_f;
+
+ min_f = policy->cpuinfo.min_freq;
+ max_f = policy->cpuinfo.max_freq;
+ freq_next = min_f + load * (max_f - min_f) / 100;
/* No longer fully busy, reset rate_mult */
dbs_info->rate_mult = 1;
if (!od_tuners->powersave_bias) {
__cpufreq_driver_target(policy, freq_next,
- CPUFREQ_RELATION_L);
+ CPUFREQ_RELATION_C);
return;
}
freq_next = od_ops.powersave_bias_target(policy, freq_next,
CPUFREQ_RELATION_L);
- __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
+ __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
}
}
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 1632981c4b25..df14766a8e06 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -117,7 +117,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
.frequency = 0,
};
struct cpufreq_frequency_table *pos;
- unsigned int freq, i = 0;
+ unsigned int freq, diff, i = 0;
pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
target_freq, relation, policy->cpu);
@@ -127,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
suboptimal.frequency = ~0;
break;
case CPUFREQ_RELATION_L:
+ case CPUFREQ_RELATION_C:
optimal.frequency = ~0;
break;
}
@@ -168,6 +169,15 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
}
}
break;
+ case CPUFREQ_RELATION_C:
+ diff = abs(freq - target_freq);
+ if (diff < optimal.frequency ||
+ (diff == optimal.frequency &&
+ freq > table[optimal.driver_data].frequency)) {
+ optimal.frequency = diff;
+ optimal.driver_data = i;
+ }
+ break;
}
}
if (optimal.driver_data > i) {
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index af366c21d4b4..c2d30765bf3d 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -66,10 +66,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
/* scaling up? scale voltage before frequency */
if (new_freq > old_freq) {
- ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
- if (ret) {
- dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
- return ret;
+ if (!IS_ERR(pu_reg)) {
+ ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
+ if (ret) {
+ dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
+ return ret;
+ }
}
ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
if (ret) {
@@ -121,10 +123,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
ret = 0;
}
- ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
- if (ret) {
- dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
- ret = 0;
+ if (!IS_ERR(pu_reg)) {
+ ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
+ if (ret) {
+ dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
+ ret = 0;
+ }
}
}
@@ -182,9 +186,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
}
arm_reg = regulator_get(cpu_dev, "arm");
- pu_reg = regulator_get(cpu_dev, "pu");
+ pu_reg = regulator_get_optional(cpu_dev, "pu");
soc_reg = regulator_get(cpu_dev, "soc");
- if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
+ if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) {
dev_err(cpu_dev, "failed to get regulators\n");
ret = -ENOENT;
goto put_reg;
@@ -268,9 +272,11 @@ soc_opp_out:
ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
if (ret > 0)
transition_latency += ret * 1000;
- ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
- if (ret > 0)
- transition_latency += ret * 1000;
+ if (!IS_ERR(pu_reg)) {
+ ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
+ if (ret > 0)
+ transition_latency += ret * 1000;
+ }
/*
* OPP is maintained in order of increasing frequency, and
@@ -327,7 +333,8 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev)
cpufreq_unregister_driver(&imx6q_cpufreq_driver);
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
regulator_put(arm_reg);
- regulator_put(pu_reg);
+ if (!IS_ERR(pu_reg))
+ regulator_put(pu_reg);
regulator_put(soc_reg);
clk_put(arm_clk);
clk_put(pll1_sys_clk);
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 924bb2d42b1c..c5eac949760d 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -37,7 +37,6 @@
#define BYT_TURBO_RATIOS 0x66c
#define BYT_TURBO_VIDS 0x66d
-
#define FRAC_BITS 8
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
#define fp_toint(X) ((X) >> FRAC_BITS)
@@ -50,7 +49,7 @@ static inline int32_t mul_fp(int32_t x, int32_t y)
static inline int32_t div_fp(int32_t x, int32_t y)
{
- return div_s64((int64_t)x << FRAC_BITS, (int64_t)y);
+ return div_s64((int64_t)x << FRAC_BITS, y);
}
struct sample {
@@ -128,6 +127,7 @@ static struct pstate_funcs pstate_funcs;
struct perf_limits {
int no_turbo;
+ int turbo_disabled;
int max_perf_pct;
int min_perf_pct;
int32_t max_perf;
@@ -147,7 +147,7 @@ static struct perf_limits limits = {
};
static inline void pid_reset(struct _pid *pid, int setpoint, int busy,
- int deadband, int integral) {
+ int deadband, int integral) {
pid->setpoint = setpoint;
pid->deadband = deadband;
pid->integral = int_tofp(integral);
@@ -166,7 +166,6 @@ static inline void pid_i_gain_set(struct _pid *pid, int percent)
static inline void pid_d_gain_set(struct _pid *pid, int percent)
{
-
pid->d_gain = div_fp(int_tofp(percent), int_tofp(100));
}
@@ -206,16 +205,13 @@ static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu)
pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct);
pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct);
- pid_reset(&cpu->pid,
- pid_params.setpoint,
- 100,
- pid_params.deadband,
- 0);
+ pid_reset(&cpu->pid, pid_params.setpoint, 100, pid_params.deadband, 0);
}
static inline void intel_pstate_reset_all_pid(void)
{
unsigned int cpu;
+
for_each_online_cpu(cpu) {
if (all_cpu_data[cpu])
intel_pstate_busy_pid_reset(all_cpu_data[cpu]);
@@ -229,13 +225,13 @@ static int pid_param_set(void *data, u64 val)
intel_pstate_reset_all_pid();
return 0;
}
+
static int pid_param_get(void *data, u64 *val)
{
*val = *(u32 *)data;
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get,
- pid_param_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(fops_pid_param, pid_param_get, pid_param_set, "%llu\n");
struct pid_param {
char *name;
@@ -252,9 +248,9 @@ static struct pid_param pid_files[] = {
{NULL, NULL}
};
-static struct dentry *debugfs_parent;
-static void intel_pstate_debug_expose_params(void)
+static void __init intel_pstate_debug_expose_params(void)
{
+ struct dentry *debugfs_parent;
int i = 0;
debugfs_parent = debugfs_create_dir("pstate_snb", NULL);
@@ -262,8 +258,8 @@ static void intel_pstate_debug_expose_params(void)
return;
while (pid_files[i].name) {
debugfs_create_file(pid_files[i].name, 0660,
- debugfs_parent, pid_files[i].value,
- &fops_pid_param);
+ debugfs_parent, pid_files[i].value,
+ &fops_pid_param);
i++;
}
}
@@ -279,23 +275,28 @@ static void intel_pstate_debug_expose_params(void)
}
static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
unsigned int input;
int ret;
+
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
limits.no_turbo = clamp_t(int, input, 0 , 1);
-
+ if (limits.turbo_disabled) {
+ pr_warn("Turbo disabled by BIOS or unavailable on processor\n");
+ limits.no_turbo = limits.turbo_disabled;
+ }
return count;
}
static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
unsigned int input;
int ret;
+
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
@@ -303,14 +304,16 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
limits.max_sysfs_pct = clamp_t(int, input, 0 , 100);
limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
+
return count;
}
static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
unsigned int input;
int ret;
+
ret = sscanf(buf, "%u", &input);
if (ret != 1)
return -EINVAL;
@@ -338,17 +341,16 @@ static struct attribute *intel_pstate_attributes[] = {
static struct attribute_group intel_pstate_attr_group = {
.attrs = intel_pstate_attributes,
};
-static struct kobject *intel_pstate_kobject;
-static void intel_pstate_sysfs_expose_params(void)
+static void __init intel_pstate_sysfs_expose_params(void)
{
+ struct kobject *intel_pstate_kobject;
int rc;
intel_pstate_kobject = kobject_create_and_add("intel_pstate",
&cpu_subsys.dev_root->kobj);
BUG_ON(!intel_pstate_kobject);
- rc = sysfs_create_group(intel_pstate_kobject,
- &intel_pstate_attr_group);
+ rc = sysfs_create_group(intel_pstate_kobject, &intel_pstate_attr_group);
BUG_ON(rc);
}
@@ -356,22 +358,25 @@ static void intel_pstate_sysfs_expose_params(void)
static int byt_get_min_pstate(void)
{
u64 value;
+
rdmsrl(BYT_RATIOS, value);
- return (value >> 8) & 0x3F;
+ return (value >> 8) & 0x7F;
}
static int byt_get_max_pstate(void)
{
u64 value;
+
rdmsrl(BYT_RATIOS, value);
- return (value >> 16) & 0x3F;
+ return (value >> 16) & 0x7F;
}
static int byt_get_turbo_pstate(void)
{
u64 value;
+
rdmsrl(BYT_TURBO_RATIOS, value);
- return value & 0x3F;
+ return value & 0x7F;
}
static void byt_set_pstate(struct cpudata *cpudata, int pstate)
@@ -381,7 +386,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate)
u32 vid;
val = pstate << 8;
- if (limits.no_turbo)
+ if (limits.no_turbo && !limits.turbo_disabled)
val |= (u64)1 << 32;
vid_fp = cpudata->vid.min + mul_fp(
@@ -403,10 +408,9 @@ static void byt_get_vid(struct cpudata *cpudata)
{
u64 value;
-
rdmsrl(BYT_VIDS, value);
- cpudata->vid.min = int_tofp((value >> 8) & 0x3f);
- cpudata->vid.max = int_tofp((value >> 16) & 0x3f);
+ cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
+ cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
cpudata->vid.ratio = div_fp(
cpudata->vid.max - cpudata->vid.min,
int_tofp(cpudata->pstate.max_pstate -
@@ -416,10 +420,10 @@ static void byt_get_vid(struct cpudata *cpudata)
cpudata->vid.turbo = value & 0x7f;
}
-
static int core_get_min_pstate(void)
{
u64 value;
+
rdmsrl(MSR_PLATFORM_INFO, value);
return (value >> 40) & 0xFF;
}
@@ -427,6 +431,7 @@ static int core_get_min_pstate(void)
static int core_get_max_pstate(void)
{
u64 value;
+
rdmsrl(MSR_PLATFORM_INFO, value);
return (value >> 8) & 0xFF;
}
@@ -435,9 +440,10 @@ static int core_get_turbo_pstate(void)
{
u64 value;
int nont, ret;
+
rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
nont = core_get_max_pstate();
- ret = ((value) & 255);
+ ret = (value) & 255;
if (ret <= nont)
ret = nont;
return ret;
@@ -448,7 +454,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate)
u64 val;
val = pstate << 8;
- if (limits.no_turbo)
+ if (limits.no_turbo && !limits.turbo_disabled)
val |= (u64)1 << 32;
wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val);
@@ -489,12 +495,12 @@ static struct cpu_defaults byt_params = {
},
};
-
static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
{
int max_perf = cpu->pstate.turbo_pstate;
int max_perf_adj;
int min_perf;
+
if (limits.no_turbo)
max_perf = cpu->pstate.max_pstate;
@@ -503,8 +509,7 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
cpu->pstate.min_pstate, cpu->pstate.turbo_pstate);
min_perf = fp_toint(mul_fp(int_tofp(max_perf), limits.min_perf));
- *min = clamp_t(int, min_perf,
- cpu->pstate.min_pstate, max_perf);
+ *min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
}
static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
@@ -525,21 +530,6 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
pstate_funcs.set(cpu, pstate);
}
-static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
-{
- int target;
- target = cpu->pstate.current_pstate + steps;
-
- intel_pstate_set_pstate(cpu, target);
-}
-
-static inline void intel_pstate_pstate_decrease(struct cpudata *cpu, int steps)
-{
- int target;
- target = cpu->pstate.current_pstate - steps;
- intel_pstate_set_pstate(cpu, target);
-}
-
static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
{
cpu->pstate.min_pstate = pstate_funcs.get_min();
@@ -555,13 +545,9 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
{
struct sample *sample = &cpu->sample;
int64_t core_pct;
- int32_t rem;
core_pct = int_tofp(sample->aperf) * int_tofp(100);
- core_pct = div_u64_rem(core_pct, int_tofp(sample->mperf), &rem);
-
- if ((rem << 1) >= int_tofp(sample->mperf))
- core_pct += 1;
+ core_pct = div64_u64(core_pct, int_tofp(sample->mperf));
sample->freq = fp_toint(
mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct));
@@ -572,12 +558,12 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu)
static inline void intel_pstate_sample(struct cpudata *cpu)
{
u64 aperf, mperf;
+ unsigned long flags;
+ local_irq_save(flags);
rdmsrl(MSR_IA32_APERF, aperf);
rdmsrl(MSR_IA32_MPERF, mperf);
-
- aperf = aperf >> FRAC_BITS;
- mperf = mperf >> FRAC_BITS;
+ local_irq_restore(flags);
cpu->last_sample_time = cpu->sample.time;
cpu->sample.time = ktime_get();
@@ -594,10 +580,9 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
{
- int sample_time, delay;
+ int delay;
- sample_time = pid_params.sample_rate_ms;
- delay = msecs_to_jiffies(sample_time);
+ delay = msecs_to_jiffies(pid_params.sample_rate_ms);
mod_timer_pinned(&cpu->timer, jiffies + delay);
}
@@ -612,12 +597,12 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu)
current_pstate = int_tofp(cpu->pstate.current_pstate);
core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
- sample_time = (pid_params.sample_rate_ms * USEC_PER_MSEC);
+ sample_time = pid_params.sample_rate_ms * USEC_PER_MSEC;
duration_us = (u32) ktime_us_delta(cpu->sample.time,
- cpu->last_sample_time);
+ cpu->last_sample_time);
if (duration_us > sample_time * 3) {
sample_ratio = div_fp(int_tofp(sample_time),
- int_tofp(duration_us));
+ int_tofp(duration_us));
core_busy = mul_fp(core_busy, sample_ratio);
}
@@ -628,20 +613,15 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
{
int32_t busy_scaled;
struct _pid *pid;
- signed int ctl = 0;
- int steps;
+ signed int ctl;
pid = &cpu->pid;
busy_scaled = intel_pstate_get_scaled_busy(cpu);
ctl = pid_calc(pid, busy_scaled);
- steps = abs(ctl);
-
- if (ctl < 0)
- intel_pstate_pstate_increase(cpu, steps);
- else
- intel_pstate_pstate_decrease(cpu, steps);
+ /* Negative values of ctl increase the pstate and vice versa */
+ intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl);
}
static void intel_pstate_timer_func(unsigned long __data)
@@ -696,14 +676,12 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
cpu = all_cpu_data[cpunum];
- intel_pstate_get_cpu_pstates(cpu);
-
cpu->cpu = cpunum;
+ intel_pstate_get_cpu_pstates(cpu);
init_timer_deferrable(&cpu->timer);
cpu->timer.function = intel_pstate_timer_func;
- cpu->timer.data =
- (unsigned long)cpu;
+ cpu->timer.data = (unsigned long)cpu;
cpu->timer.expires = jiffies + HZ/100;
intel_pstate_busy_pid_reset(cpu);
intel_pstate_sample(cpu);
@@ -741,14 +719,14 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
limits.min_perf = int_tofp(1);
limits.max_perf_pct = 100;
limits.max_perf = int_tofp(1);
- limits.no_turbo = 0;
+ limits.no_turbo = limits.turbo_disabled;
return 0;
}
limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100);
limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
- limits.max_policy_pct = policy->max * 100 / policy->cpuinfo.max_freq;
+ limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq;
limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100);
limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
@@ -760,8 +738,8 @@ static int intel_pstate_verify_policy(struct cpufreq_policy *policy)
{
cpufreq_verify_within_cpu_limits(policy);
- if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
- (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
+ if (policy->policy != CPUFREQ_POLICY_POWERSAVE &&
+ policy->policy != CPUFREQ_POLICY_PERFORMANCE)
return -EINVAL;
return 0;
@@ -784,6 +762,7 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
{
struct cpudata *cpu;
int rc;
+ u64 misc_en;
rc = intel_pstate_init_cpu(policy->cpu);
if (rc)
@@ -791,8 +770,13 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
cpu = all_cpu_data[policy->cpu];
- if (!limits.no_turbo &&
- limits.min_perf_pct == 100 && limits.max_perf_pct == 100)
+ rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
+ if (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ||
+ cpu->pstate.max_pstate == cpu->pstate.turbo_pstate) {
+ limits.turbo_disabled = 1;
+ limits.no_turbo = 1;
+ }
+ if (limits.min_perf_pct == 100 && limits.max_perf_pct == 100)
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
else
policy->policy = CPUFREQ_POLICY_POWERSAVE;
@@ -830,8 +814,8 @@ static int intel_pstate_msrs_not_valid(void)
rdmsrl(MSR_IA32_MPERF, mperf);
if (!pstate_funcs.get_max() ||
- !pstate_funcs.get_min() ||
- !pstate_funcs.get_turbo())
+ !pstate_funcs.get_min() ||
+ !pstate_funcs.get_turbo())
return -ENODEV;
rdmsrl(MSR_IA32_APERF, tmp);
@@ -913,14 +897,14 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void)
struct acpi_table_header hdr;
struct hw_vendor_info *v_info;
- if (acpi_disabled
- || ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr)))
+ if (acpi_disabled ||
+ ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr)))
return false;
for (v_info = vendor_info; v_info->valid; v_info++) {
- if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE)
- && !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE)
- && intel_pstate_no_acpi_pss())
+ if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE) &&
+ !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) &&
+ intel_pstate_no_acpi_pss())
return true;
}
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
index d4add8621944..9fa177206032 100644
--- a/drivers/cpufreq/loongson2_cpufreq.c
+++ b/drivers/cpufreq/loongson2_cpufreq.c
@@ -148,9 +148,9 @@ static void loongson2_cpu_wait(void)
u32 cpu_freq;
spin_lock_irqsave(&loongson2_wait_lock, flags);
- cpu_freq = LOONGSON_CHIPCFG0;
- LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */
- LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */
+ cpu_freq = LOONGSON_CHIPCFG(0);
+ LOONGSON_CHIPCFG(0) &= ~0x7; /* Put CPU into wait mode */
+ LOONGSON_CHIPCFG(0) = cpu_freq; /* Restore CPU state */
spin_unlock_irqrestore(&loongson2_wait_lock, flags);
local_irq_enable();
}
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index c8012bc86910..f91027259c3c 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -55,6 +55,7 @@ static const struct {
unsigned freq;
unsigned mult;
} usual_frequency_table[] = {
+ { 350000, 35 }, // 100 * 3.5
{ 400000, 40 }, // 100 * 4
{ 450000, 45 }, // 100 * 4.5
{ 475000, 50 }, // 95 * 5
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index bb1d08dc8cc8..379c0837f5a9 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -28,6 +28,7 @@
#include <linux/of.h>
#include <asm/cputhreads.h>
+#include <asm/firmware.h>
#include <asm/reg.h>
#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
@@ -98,7 +99,11 @@ static int init_powernv_pstates(void)
return -ENODEV;
}
- WARN_ON(len_ids != len_freqs);
+ if (len_ids != len_freqs) {
+ pr_warn("Entries in ibm,pstate-ids and "
+ "ibm,pstate-frequencies-mhz does not match\n");
+ }
+
nr_pstates = min(len_ids, len_freqs) / sizeof(u32);
if (!nr_pstates) {
pr_warn("No PStates found\n");
@@ -131,7 +136,12 @@ static unsigned int pstate_id_to_freq(int pstate_id)
int i;
i = powernv_pstate_info.max - pstate_id;
- BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0);
+ if (i >= powernv_pstate_info.nr_pstates || i < 0) {
+ pr_warn("PState id %d outside of PState table, "
+ "reporting nominal id %d instead\n",
+ pstate_id, powernv_pstate_info.nominal);
+ i = powernv_pstate_info.max - powernv_pstate_info.nominal;
+ }
return powernv_freqs[i].frequency;
}
@@ -321,6 +331,10 @@ static int __init powernv_cpufreq_init(void)
{
int rc = 0;
+ /* Don't probe on pseries (guest) platforms */
+ if (!firmware_has_feature(FW_FEATURE_OPALv3))
+ return -ENODEV;
+
/* Discover pstates from device tree and init */
rc = init_powernv_pstates();
if (rc) {
diff --git a/drivers/cpufreq/s3c2410-cpufreq.c b/drivers/cpufreq/s3c2410-cpufreq.c
index cfa0dd8723ec..b8e5da8e188b 100644
--- a/drivers/cpufreq/s3c2410-cpufreq.c
+++ b/drivers/cpufreq/s3c2410-cpufreq.c
@@ -26,7 +26,6 @@
#include <mach/regs-clock.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include <plat/cpu-freq-core.h>
/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
@@ -104,7 +103,6 @@ static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
.calc_iotiming = s3c2410_iotiming_calc,
.set_iotiming = s3c2410_iotiming_set,
.get_iotiming = s3c2410_iotiming_get,
- .resume_clocks = s3c2410_setup_clocks,
.set_fvco = s3c2410_set_fvco,
.set_refresh = s3c2410_cpufreq_setrefresh,
diff --git a/drivers/cpufreq/s3c2412-cpufreq.c b/drivers/cpufreq/s3c2412-cpufreq.c
index 4645b4898996..eb262133fef2 100644
--- a/drivers/cpufreq/s3c2412-cpufreq.c
+++ b/drivers/cpufreq/s3c2412-cpufreq.c
@@ -28,7 +28,6 @@
#include <mach/s3c2412.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include <plat/cpu-freq-core.h>
/* our clock resources. */
@@ -188,8 +187,6 @@ static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
.set_iotiming = s3c2412_iotiming_set,
.get_iotiming = s3c2412_iotiming_get,
- .resume_clocks = s3c2412_setup_clocks,
-
.debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
};
diff --git a/drivers/cpufreq/s3c2440-cpufreq.c b/drivers/cpufreq/s3c2440-cpufreq.c
index f84ed10755b5..0129f5c70a61 100644
--- a/drivers/cpufreq/s3c2440-cpufreq.c
+++ b/drivers/cpufreq/s3c2440-cpufreq.c
@@ -29,7 +29,6 @@
#include <plat/cpu.h>
#include <plat/cpu-freq-core.h>
-#include <plat/clock.h>
static struct clk *xtal;
static struct clk *fclk;
@@ -262,8 +261,6 @@ static struct s3c_cpufreq_info s3c2440_cpufreq_info = {
.calc_divs = s3c2440_cpufreq_calcdivs,
.calc_freqtable = s3c2440_cpufreq_calctable,
- .resume_clocks = s3c244x_setup_clocks,
-
.debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
};
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c
index 227ebf7c1eea..d00f1cee4509 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -27,7 +27,6 @@
#include <asm/mach/map.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include <plat/cpu-freq-core.h>
#include <mach/regs-clock.h>
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index 19a10b89fef7..9a68225a757e 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -16,11 +16,70 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regulator/consumer.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
+static void __iomem *clk_base;
+static void __iomem *dmc_base[2];
+
+#define S5P_CLKREG(x) (clk_base + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_APLL_CON S5P_CLKREG(0x100)
+#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
+#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
+#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
+#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
+#define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000)
+#define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004)
+#define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100)
+#define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104)
+
+#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
+
+/* CLKSRC0 */
+#define S5P_CLKSRC0_MUX200_SHIFT (16)
+#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
+#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
+#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
+
+/* CLKSRC2 */
+#define S5P_CLKSRC2_G3D_SHIFT (0)
+#define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT)
+#define S5P_CLKSRC2_MFC_SHIFT (4)
+#define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT (0)
+#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT (4)
+#define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_HCLK200_SHIFT (8)
+#define S5P_CLKDIV0_HCLK200_MASK (0x7 << S5P_CLKDIV0_HCLK200_SHIFT)
+#define S5P_CLKDIV0_PCLK100_SHIFT (12)
+#define S5P_CLKDIV0_PCLK100_MASK (0x7 << S5P_CLKDIV0_PCLK100_SHIFT)
+#define S5P_CLKDIV0_HCLK166_SHIFT (16)
+#define S5P_CLKDIV0_HCLK166_MASK (0xF << S5P_CLKDIV0_HCLK166_SHIFT)
+#define S5P_CLKDIV0_PCLK83_SHIFT (20)
+#define S5P_CLKDIV0_PCLK83_MASK (0x7 << S5P_CLKDIV0_PCLK83_SHIFT)
+#define S5P_CLKDIV0_HCLK133_SHIFT (24)
+#define S5P_CLKDIV0_HCLK133_MASK (0xF << S5P_CLKDIV0_HCLK133_SHIFT)
+#define S5P_CLKDIV0_PCLK66_SHIFT (28)
+#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
+
+/* CLKDIV2 */
+#define S5P_CLKDIV2_G3D_SHIFT (0)
+#define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT)
+#define S5P_CLKDIV2_MFC_SHIFT (4)
+#define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT)
+
+/* CLKDIV6 */
+#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
+#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
static struct clk *dmc0_clk;
static struct clk *dmc1_clk;
@@ -142,9 +201,9 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
void __iomem *reg = NULL;
if (ch == DMC0) {
- reg = (S5P_VA_DMC0 + 0x30);
+ reg = (dmc_base[0] + 0x30);
} else if (ch == DMC1) {
- reg = (S5P_VA_DMC1 + 0x30);
+ reg = (dmc_base[1] + 0x30);
} else {
printk(KERN_ERR "Cannot find DMC port\n");
return;
@@ -472,7 +531,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
* check_mem_type : This driver only support LPDDR & LPDDR2.
* other memory type is not supported.
*/
- mem_type = check_mem_type(S5P_VA_DMC0);
+ mem_type = check_mem_type(dmc_base[0]);
if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
@@ -481,10 +540,10 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
}
/* Find current refresh counter and frequency each DMC */
- s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
+ s5pv210_dram_conf[0].refresh = (__raw_readl(dmc_base[0] + 0x30) * 1000);
s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
- s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
+ s5pv210_dram_conf[1].refresh = (__raw_readl(dmc_base[1] + 0x30) * 1000);
s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
policy->suspend_freq = SLEEP_FREQ;
@@ -527,8 +586,55 @@ static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
.notifier_call = s5pv210_cpufreq_reboot_notifier_event,
};
-static int __init s5pv210_cpufreq_init(void)
+static int s5pv210_cpufreq_probe(struct platform_device *pdev)
{
+ struct device_node *np;
+ int id;
+
+ /*
+ * HACK: This is a temporary workaround to get access to clock
+ * and DMC controller registers directly and remove static mappings
+ * and dependencies on platform headers. It is necessary to enable
+ * S5PV210 multi-platform support and will be removed together with
+ * this whole driver as soon as S5PV210 gets migrated to use
+ * cpufreq-cpu0 driver.
+ */
+ np = of_find_compatible_node(NULL, NULL, "samsung,s5pv210-clock");
+ if (!np) {
+ pr_err("%s: failed to find clock controller DT node\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ clk_base = of_iomap(np, 0);
+ if (!clk_base) {
+ pr_err("%s: failed to map clock registers\n", __func__);
+ return -EFAULT;
+ }
+
+ for_each_compatible_node(np, NULL, "samsung,s5pv210-dmc") {
+ id = of_alias_get_id(np, "dmc");
+ if (id < 0 || id >= ARRAY_SIZE(dmc_base)) {
+ pr_err("%s: failed to get alias of dmc node '%s'\n",
+ __func__, np->name);
+ return id;
+ }
+
+ dmc_base[id] = of_iomap(np, 0);
+ if (!dmc_base[id]) {
+ pr_err("%s: failed to map dmc%d registers\n",
+ __func__, id);
+ return -EFAULT;
+ }
+ }
+
+ for (id = 0; id < ARRAY_SIZE(dmc_base); ++id) {
+ if (!dmc_base[id]) {
+ pr_err("%s: failed to find dmc%d node\n", __func__, id);
+ return -ENODEV;
+ }
+ }
+
arm_regulator = regulator_get(NULL, "vddarm");
if (IS_ERR(arm_regulator)) {
pr_err("failed to get regulator vddarm");
@@ -547,4 +653,11 @@ static int __init s5pv210_cpufreq_init(void)
return cpufreq_register_driver(&s5pv210_driver);
}
-late_initcall(s5pv210_cpufreq_init);
+static struct platform_driver s5pv210_cpufreq_platdrv = {
+ .driver = {
+ .name = "s5pv210-cpufreq",
+ .owner = THIS_MODULE,
+ },
+ .probe = s5pv210_cpufreq_probe,
+};
+module_platform_driver(s5pv210_cpufreq_platdrv);
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c
index 546376719d8f..b5befc211172 100644
--- a/drivers/cpufreq/sa1110-cpufreq.c
+++ b/drivers/cpufreq/sa1110-cpufreq.c
@@ -349,7 +349,7 @@ static int __init sa1110_clk_init(void)
name = "K4S641632D";
if (machine_is_h3100())
name = "KM416S4030CT";
- if (machine_is_jornada720())
+ if (machine_is_jornada720() || machine_is_h3600())
name = "K4S281632B-1H";
if (machine_is_nanoengine())
name = "MT48LC8M16A2TG-75";
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 1b96fb91d32c..32748c36c477 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -15,12 +15,7 @@ config CPU_IDLE
if CPU_IDLE
config CPU_IDLE_MULTIPLE_DRIVERS
- bool "Support multiple cpuidle drivers"
- default n
- help
- Allows the cpuidle framework to use different drivers for each CPU.
- This is useful if you have a system with different CPU latencies and
- states. If unsure say N.
+ bool
config CPU_IDLE_GOV_LADDER
bool "Ladder governor (for periodic timer tick)"
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index b6d69e899f5d..38cff69ffe06 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -1,15 +1,10 @@
#
# ARM CPU Idle drivers
#
-config ARM_ARMADA_370_XP_CPUIDLE
- bool "CPU Idle Driver for Armada 370/XP family processors"
- depends on ARCH_MVEBU
- help
- Select this to enable cpuidle on Armada 370/XP processors.
-
config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
- depends on ARCH_VEXPRESS_TC2_PM
+ depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
+ depends on MCPM
select ARM_CPU_SUSPEND
select CPU_IDLE_MULTIPLE_DRIVERS
help
@@ -61,3 +56,9 @@ config ARM_EXYNOS_CPUIDLE
depends on ARCH_EXYNOS
help
Select this to enable cpuidle for Exynos processors
+
+config ARM_MVEBU_V7_CPUIDLE
+ bool "CPU Idle Driver for mvebu v7 family processors"
+ depends on ARCH_MVEBU
+ help
+ Select this to enable cpuidle on Armada 370, 38x and XP processors.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index d8bb1ff72561..11edb31c55e9 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
##################################################################################
# ARM SoC drivers
-obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o
+obj-$(CONFIG_ARM_MVEBU_V7_CPUIDLE) += cpuidle-mvebu-v7.o
obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o
obj-$(CONFIG_ARM_CLPS711X_CPUIDLE) += cpuidle-clps711x.o
obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o
diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c
deleted file mode 100644
index a5fba0287bfb..000000000000
--- a/drivers/cpuidle/cpuidle-armada-370-xp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Marvell Armada 370 and Armada XP SoC cpuidle driver
- *
- * Copyright (C) 2014 Marvell
- *
- * Nadav Haklai <nadavh@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
- * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
- */
-
-#include <linux/cpu_pm.h>
-#include <linux/cpuidle.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/suspend.h>
-#include <linux/platform_device.h>
-#include <asm/cpuidle.h>
-
-#define ARMADA_370_XP_MAX_STATES 3
-#define ARMADA_370_XP_FLAG_DEEP_IDLE 0x10000
-
-static int (*armada_370_xp_cpu_suspend)(int);
-
-static int armada_370_xp_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_driver *drv,
- int index)
-{
- int ret;
- bool deepidle = false;
- cpu_pm_enter();
-
- if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE)
- deepidle = true;
-
- ret = armada_370_xp_cpu_suspend(deepidle);
- if (ret)
- return ret;
-
- cpu_pm_exit();
-
- return index;
-}
-
-static struct cpuidle_driver armada_370_xp_idle_driver = {
- .name = "armada_370_xp_idle",
- .states[0] = ARM_CPUIDLE_WFI_STATE,
- .states[1] = {
- .enter = armada_370_xp_enter_idle,
- .exit_latency = 10,
- .power_usage = 50,
- .target_residency = 100,
- .flags = CPUIDLE_FLAG_TIME_VALID,
- .name = "Idle",
- .desc = "CPU power down",
- },
- .states[2] = {
- .enter = armada_370_xp_enter_idle,
- .exit_latency = 100,
- .power_usage = 5,
- .target_residency = 1000,
- .flags = CPUIDLE_FLAG_TIME_VALID |
- ARMADA_370_XP_FLAG_DEEP_IDLE,
- .name = "Deep idle",
- .desc = "CPU and L2 Fabric power down",
- },
- .state_count = ARMADA_370_XP_MAX_STATES,
-};
-
-static int armada_370_xp_cpuidle_probe(struct platform_device *pdev)
-{
-
- armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data);
- return cpuidle_register(&armada_370_xp_idle_driver, NULL);
-}
-
-static struct platform_driver armada_370_xp_cpuidle_plat_driver = {
- .driver = {
- .name = "cpuidle-armada-370-xp",
- .owner = THIS_MODULE,
- },
- .probe = armada_370_xp_cpuidle_probe,
-};
-
-module_platform_driver(armada_370_xp_cpuidle_plat_driver);
-
-MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP cpu idle driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c
index b45fc6249041..344d79fa3407 100644
--- a/drivers/cpuidle/cpuidle-big_little.c
+++ b/drivers/cpuidle/cpuidle-big_little.c
@@ -163,14 +163,24 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id)
return 0;
}
+static const struct of_device_id compatible_machine_match[] = {
+ { .compatible = "arm,vexpress,v2p-ca15_a7" },
+ { .compatible = "samsung,exynos5420" },
+ {},
+};
+
static int __init bl_idle_init(void)
{
int ret;
+ struct device_node *root = of_find_node_by_path("/");
+
+ if (!root)
+ return -ENODEV;
/*
* Initialize the driver just for a compliant set of machines
*/
- if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7"))
+ if (!of_match_node(compatible_machine_match, root))
return -ENODEV;
/*
* For now the differentiation between little and big cores
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c
new file mode 100644
index 000000000000..45371bb16214
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-mvebu-v7.c
@@ -0,0 +1,150 @@
+/*
+ * Marvell Armada 370, 38x and XP SoC cpuidle driver
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Nadav Haklai <nadavh@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <asm/cpuidle.h>
+
+#define MVEBU_V7_FLAG_DEEP_IDLE 0x10000
+
+static int (*mvebu_v7_cpu_suspend)(int);
+
+static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv,
+ int index)
+{
+ int ret;
+ bool deepidle = false;
+ cpu_pm_enter();
+
+ if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
+ deepidle = true;
+
+ ret = mvebu_v7_cpu_suspend(deepidle);
+ if (ret)
+ return ret;
+
+ cpu_pm_exit();
+
+ return index;
+}
+
+static struct cpuidle_driver armadaxp_idle_driver = {
+ .name = "armada_xp_idle",
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[1] = {
+ .enter = mvebu_v7_enter_idle,
+ .exit_latency = 10,
+ .power_usage = 50,
+ .target_residency = 100,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "MV CPU IDLE",
+ .desc = "CPU power down",
+ },
+ .states[2] = {
+ .enter = mvebu_v7_enter_idle,
+ .exit_latency = 100,
+ .power_usage = 5,
+ .target_residency = 1000,
+ .flags = CPUIDLE_FLAG_TIME_VALID |
+ MVEBU_V7_FLAG_DEEP_IDLE,
+ .name = "MV CPU DEEP IDLE",
+ .desc = "CPU and L2 Fabric power down",
+ },
+ .state_count = 3,
+};
+
+static struct cpuidle_driver armada370_idle_driver = {
+ .name = "armada_370_idle",
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[1] = {
+ .enter = mvebu_v7_enter_idle,
+ .exit_latency = 100,
+ .power_usage = 5,
+ .target_residency = 1000,
+ .flags = (CPUIDLE_FLAG_TIME_VALID |
+ MVEBU_V7_FLAG_DEEP_IDLE),
+ .name = "Deep Idle",
+ .desc = "CPU and L2 Fabric power down",
+ },
+ .state_count = 2,
+};
+
+static struct cpuidle_driver armada38x_idle_driver = {
+ .name = "armada_38x_idle",
+ .states[0] = ARM_CPUIDLE_WFI_STATE,
+ .states[1] = {
+ .enter = mvebu_v7_enter_idle,
+ .exit_latency = 10,
+ .power_usage = 5,
+ .target_residency = 100,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "Idle",
+ .desc = "CPU and SCU power down",
+ },
+ .state_count = 2,
+};
+
+static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
+{
+ mvebu_v7_cpu_suspend = pdev->dev.platform_data;
+
+ if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-xp"))
+ return cpuidle_register(&armadaxp_idle_driver, NULL);
+ else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-370"))
+ return cpuidle_register(&armada370_idle_driver, NULL);
+ else if (!strcmp(pdev->dev.driver->name, "cpuidle-armada-38x"))
+ return cpuidle_register(&armada38x_idle_driver, NULL);
+ else
+ return -EINVAL;
+}
+
+static struct platform_driver armadaxp_cpuidle_plat_driver = {
+ .driver = {
+ .name = "cpuidle-armada-xp",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvebu_v7_cpuidle_probe,
+};
+
+module_platform_driver(armadaxp_cpuidle_plat_driver);
+
+static struct platform_driver armada370_cpuidle_plat_driver = {
+ .driver = {
+ .name = "cpuidle-armada-370",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvebu_v7_cpuidle_probe,
+};
+
+module_platform_driver(armada370_cpuidle_plat_driver);
+
+static struct platform_driver armada38x_cpuidle_plat_driver = {
+ .driver = {
+ .name = "cpuidle-armada-38x",
+ .owner = THIS_MODULE,
+ },
+ .probe = mvebu_v7_cpuidle_probe,
+};
+
+module_platform_driver(armada38x_cpuidle_plat_driver);
+
+MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 74f5788d50b1..a64be578dab2 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -160,10 +160,10 @@ static int powernv_cpuidle_driver_init(void)
static int powernv_add_idle_states(void)
{
struct device_node *power_mgt;
- struct property *prop;
int nr_idle_states = 1; /* Snooze */
int dt_idle_states;
- u32 *flags;
+ const __be32 *idle_state_flags;
+ u32 len_flags, flags;
int i;
/* Currently we have snooze statically defined */
@@ -174,18 +174,18 @@ static int powernv_add_idle_states(void)
return nr_idle_states;
}
- prop = of_find_property(power_mgt, "ibm,cpu-idle-state-flags", NULL);
- if (!prop) {
+ idle_state_flags = of_get_property(power_mgt, "ibm,cpu-idle-state-flags", &len_flags);
+ if (!idle_state_flags) {
pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n");
return nr_idle_states;
}
- dt_idle_states = prop->length / sizeof(u32);
- flags = (u32 *) prop->value;
+ dt_idle_states = len_flags / sizeof(u32);
for (i = 0; i < dt_idle_states; i++) {
- if (flags[i] & IDLE_USE_INST_NAP) {
+ flags = be32_to_cpu(idle_state_flags[i]);
+ if (flags & IDLE_USE_INST_NAP) {
/* Add NAP state */
strcpy(powernv_states[nr_idle_states].name, "Nap");
strcpy(powernv_states[nr_idle_states].desc, "Nap");
@@ -196,7 +196,7 @@ static int powernv_add_idle_states(void)
nr_idle_states++;
}
- if (flags[i] & IDLE_USE_INST_SLEEP) {
+ if (flags & IDLE_USE_INST_SLEEP) {
/* Add FASTSLEEP state */
strcpy(powernv_states[nr_idle_states].name, "FastSleep");
strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index cb7019977c50..ee9df5e3f5eb 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -119,11 +119,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
ktime_t time_start, time_end;
s64 diff;
+ trace_cpu_idle_rcuidle(index, dev->cpu);
time_start = ktime_get();
entered_state = target_state->enter(dev, drv, index);
time_end = ktime_get();
+ trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
if (!cpuidle_state_is_coupled(dev, drv, entered_state))
local_irq_enable();
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index 9634f20e3926..e431d11abf8d 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -182,10 +182,6 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
static int poll_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index)
{
- ktime_t t1, t2;
- s64 diff;
-
- t1 = ktime_get();
local_irq_enable();
if (!current_set_polling_and_test()) {
while (!need_resched())
@@ -193,13 +189,6 @@ static int poll_idle(struct cpuidle_device *dev,
}
current_clr_polling();
- t2 = ktime_get();
- diff = ktime_to_us(ktime_sub(t2, t1));
- if (diff > INT_MAX)
- diff = INT_MAX;
-
- dev->last_residency = (int) diff;
-
return index;
}
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index 9f08e8cce1af..044ee0df5871 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -144,7 +144,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
- for (i = 0; i < drv->state_count; i++) {
+ for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
state = &drv->states[i];
lstate = &ldev->states[i];
@@ -156,7 +156,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
if (i < drv->state_count - 1)
lstate->threshold.promotion_time = state->exit_latency;
- if (i > 0)
+ if (i > CPUIDLE_DRIVER_STATE_START)
lstate->threshold.demotion_time = state->exit_latency;
}
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index c4f80c15a48d..ae5a42595e1c 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -35,7 +35,6 @@
#define RESOLUTION 1024
#define DECAY 8
#define MAX_INTERESTING 50000
-#define STDDEV_THRESH 400
/*
@@ -399,7 +398,7 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
*
* Any measured amount of time will include the exit latency.
* Since we are interested in when the wakeup begun, not when it
- * was completed, we must substract the exit latency. However, if
+ * was completed, we must subtract the exit latency. However, if
* the measured amount of time is less than the exit latency,
* assume the state was never reached and the exit latency is 0.
*/
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index efe2f175168f..97c5903b4606 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -445,7 +445,7 @@ static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
#define define_one_driver_ro(_name, show) \
static struct cpuidle_driver_attr attr_driver_##_name = \
- __ATTR(_name, 0644, show, NULL)
+ __ATTR(_name, 0444, show, NULL)
struct cpuidle_driver_kobj {
struct cpuidle_driver *drv;
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 02f177aeb16c..2fb0fdfc87df 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -391,7 +391,7 @@ config CRYPTO_DEV_ATMEL_SHA
config CRYPTO_DEV_CCP
bool "Support for AMD Cryptographic Coprocessor"
- depends on X86 && PCI
+ depends on (X86 && PCI) || ARM64
default n
help
The AMD Cryptographic Coprocessor provides hardware support
@@ -418,4 +418,22 @@ config CRYPTO_DEV_MXS_DCP
To compile this driver as a module, choose M here: the module
will be called mxs-dcp.
+source "drivers/crypto/qat/Kconfig"
+
+config CRYPTO_DEV_QCE
+ tristate "Qualcomm crypto engine accelerator"
+ depends on (ARCH_QCOM || COMPILE_TEST) && HAS_DMA && HAS_IOMEM
+ select CRYPTO_AES
+ select CRYPTO_DES
+ select CRYPTO_ECB
+ select CRYPTO_CBC
+ select CRYPTO_XTS
+ select CRYPTO_CTR
+ select CRYPTO_ALGAPI
+ select CRYPTO_BLKCIPHER
+ help
+ This driver supports Qualcomm crypto engine accelerator
+ hardware. To compile this driver as a module, choose M here. The
+ module will be called qcrypto.
+
endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 482f090d16d0..3924f93d5774 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -23,3 +23,5 @@ obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
+obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/
+obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
index 37f9cc98ba17..e4c6c58fbb03 100644
--- a/drivers/crypto/amcc/crypto4xx_core.c
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1292,7 +1292,7 @@ static struct platform_driver crypto4xx_driver = {
.of_match_table = crypto4xx_match,
},
.probe = crypto4xx_probe,
- .remove = crypto4xx_remove,
+ .remove = __exit_p(crypto4xx_remove),
};
module_platform_driver(crypto4xx_driver);
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 0618be06b9fb..9a4f69eaa5e0 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -1353,7 +1353,6 @@ static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pd
GFP_KERNEL);
if (!pdata->dma_slave) {
dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
- devm_kfree(&pdev->dev, pdata);
return ERR_PTR(-ENOMEM);
}
@@ -1375,7 +1374,8 @@ static int atmel_sha_probe(struct platform_device *pdev)
unsigned long sha_phys_size;
int err;
- sha_dd = kzalloc(sizeof(struct atmel_sha_dev), GFP_KERNEL);
+ sha_dd = devm_kzalloc(&pdev->dev, sizeof(struct atmel_sha_dev),
+ GFP_KERNEL);
if (sha_dd == NULL) {
dev_err(dev, "unable to alloc data struct.\n");
err = -ENOMEM;
@@ -1490,8 +1490,6 @@ clk_err:
free_irq(sha_dd->irq, sha_dd);
res_err:
tasklet_kill(&sha_dd->done_task);
- kfree(sha_dd);
- sha_dd = NULL;
sha_dd_err:
dev_err(dev, "initialization failed.\n");
@@ -1523,9 +1521,6 @@ static int atmel_sha_remove(struct platform_device *pdev)
if (sha_dd->irq >= 0)
free_irq(sha_dd->irq, sha_dd);
- kfree(sha_dd);
- sha_dd = NULL;
-
return 0;
}
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
index 6cde5b530c69..d3a9041938ea 100644
--- a/drivers/crypto/atmel-tdes.c
+++ b/drivers/crypto/atmel-tdes.c
@@ -1337,7 +1337,6 @@ static struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *p
GFP_KERNEL);
if (!pdata->dma_slave) {
dev_err(&pdev->dev, "could not allocate memory for dma_slave\n");
- devm_kfree(&pdev->dev, pdata);
return ERR_PTR(-ENOMEM);
}
@@ -1359,7 +1358,7 @@ static int atmel_tdes_probe(struct platform_device *pdev)
unsigned long tdes_phys_size;
int err;
- tdes_dd = kzalloc(sizeof(struct atmel_tdes_dev), GFP_KERNEL);
+ tdes_dd = devm_kmalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL);
if (tdes_dd == NULL) {
dev_err(dev, "unable to alloc data struct.\n");
err = -ENOMEM;
@@ -1483,8 +1482,6 @@ tdes_irq_err:
res_err:
tasklet_kill(&tdes_dd->done_task);
tasklet_kill(&tdes_dd->queue_task);
- kfree(tdes_dd);
- tdes_dd = NULL;
tdes_dd_err:
dev_err(dev, "initialization failed.\n");
@@ -1519,9 +1516,6 @@ static int atmel_tdes_remove(struct platform_device *pdev)
if (tdes_dd->irq >= 0)
free_irq(tdes_dd->irq, tdes_dd);
- kfree(tdes_dd);
- tdes_dd = NULL;
-
return 0;
}
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index c09ce1f040d3..a80ea853701d 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -97,6 +97,13 @@ static inline void append_dec_op1(u32 *desc, u32 type)
{
u32 *jump_cmd, *uncond_jump_cmd;
+ /* DK bit is valid only for AES */
+ if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
+ append_operation(desc, type | OP_ALG_AS_INITFINAL |
+ OP_ALG_DECRYPT);
+ return;
+ }
+
jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
append_operation(desc, type | OP_ALG_AS_INITFINAL |
OP_ALG_DECRYPT);
@@ -786,7 +793,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
desc_bytes(desc),
DMA_TO_DEVICE);
- if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
+ if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
dev_err(jrdev, "unable to map shared descriptor\n");
return -ENOMEM;
}
@@ -1313,8 +1320,13 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
DMA_FROM_DEVICE, dst_chained);
}
- /* Check if data are contiguous */
iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Check if data are contiguous */
if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
iv_dma || src_nents || iv_dma + ivsize !=
sg_dma_address(req->src)) {
@@ -1345,8 +1357,6 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
desc_bytes;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
*all_contig_ptr = all_contig;
sec4_sg_index = 0;
@@ -1369,6 +1379,12 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
sg_to_sec4_sg_last(req->dst, dst_nents,
edesc->sec4_sg + sec4_sg_index, 0);
}
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }
return edesc;
}
@@ -1494,8 +1510,13 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
DMA_FROM_DEVICE, dst_chained);
}
- /* Check if data are contiguous */
iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Check if data are contiguous */
if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
iv_dma || src_nents || iv_dma + ivsize != sg_dma_address(req->src))
contig &= ~GIV_SRC_CONTIG;
@@ -1534,8 +1555,6 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
desc_bytes;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
*contig_ptr = contig;
sec4_sg_index = 0;
@@ -1559,6 +1578,12 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
sg_to_sec4_sg_last(req->dst, dst_nents,
edesc->sec4_sg + sec4_sg_index, 0);
}
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }
return edesc;
}
@@ -1650,11 +1675,16 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
DMA_FROM_DEVICE, dst_chained);
}
+ iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
/*
* Check if iv can be contiguous with source and destination.
* If so, include it. If not, create scatterlist.
*/
- iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
iv_contig = true;
else
@@ -1693,6 +1723,11 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
edesc->iv_dma = iv_dma;
#ifdef DEBUG
@@ -2441,8 +2476,37 @@ static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
static int __init caam_algapi_init(void)
{
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+ struct device *ctrldev;
+ void *priv;
int i = 0, err = 0;
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev) {
+ of_node_put(dev_node);
+ return -ENODEV;
+ }
+
+ ctrldev = &pdev->dev;
+ priv = dev_get_drvdata(ctrldev);
+ of_node_put(dev_node);
+
+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
+
+
INIT_LIST_HEAD(&alg_list);
/* register crypto algorithms the device supports */
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 0d9284ef96a8..b464d03ebf40 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -137,13 +137,20 @@ struct caam_hash_state {
/* Common job descriptor seq in/out ptr routines */
/* Map state->caam_ctx, and append seq_out_ptr command that points to it */
-static inline void map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
- struct caam_hash_state *state,
- int ctx_len)
+static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
+ struct caam_hash_state *state,
+ int ctx_len)
{
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx,
ctx_len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(jrdev, state->ctx_dma)) {
+ dev_err(jrdev, "unable to map ctx\n");
+ return -ENOMEM;
+ }
+
append_seq_out_ptr(desc, state->ctx_dma, ctx_len, 0);
+
+ return 0;
}
/* Map req->result, and append seq_out_ptr command that points to it */
@@ -201,14 +208,19 @@ try_buf_map_to_sec4_sg(struct device *jrdev, struct sec4_sg_entry *sec4_sg,
}
/* Map state->caam_ctx, and add it to link table */
-static inline void ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
- struct caam_hash_state *state,
- int ctx_len,
- struct sec4_sg_entry *sec4_sg,
- u32 flag)
+static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
+ struct caam_hash_state *state, int ctx_len,
+ struct sec4_sg_entry *sec4_sg, u32 flag)
{
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag);
+ if (dma_mapping_error(jrdev, state->ctx_dma)) {
+ dev_err(jrdev, "unable to map ctx\n");
+ return -ENOMEM;
+ }
+
dma_to_sec4_sg_one(sec4_sg, state->ctx_dma, ctx_len, 0);
+
+ return 0;
}
/* Common shared descriptor commands */
@@ -487,11 +499,11 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
digestsize, 1);
#endif
}
- *keylen = digestsize;
-
dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE);
dma_unmap_single(jrdev, dst_dma, digestsize, DMA_FROM_DEVICE);
+ *keylen = digestsize;
+
kfree(desc);
return ret;
@@ -706,7 +718,7 @@ static void ahash_done_ctx_src(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);
- ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_TO_DEVICE);
kfree(edesc);
#ifdef DEBUG
@@ -741,7 +753,7 @@ static void ahash_done_ctx_dst(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);
- ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_FROM_DEVICE);
kfree(edesc);
#ifdef DEBUG
@@ -808,12 +820,11 @@ static int ahash_update_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes,
- DMA_TO_DEVICE);
- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
- edesc->sec4_sg, DMA_BIDIRECTIONAL);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_BIDIRECTIONAL);
+ if (ret)
+ return ret;
state->buf_dma = try_buf_map_to_sec4_sg(jrdev,
edesc->sec4_sg + 1,
@@ -839,6 +850,14 @@ static int ahash_update_ctx(struct ahash_request *req)
init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER |
HDR_REVERSE);
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
+
append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len +
to_hash, LDST_SGF);
@@ -911,23 +930,34 @@ static int ahash_final_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
edesc->src_nents = 0;
- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg,
- DMA_TO_DEVICE);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_TO_DEVICE);
+ if (ret)
+ return ret;
state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
buf, state->buf_dma, buflen,
last_buflen);
(edesc->sec4_sg + sec4_sg_bytes - 1)->len |= SEC4_SG_LEN_FIN;
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
+
append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + buflen,
LDST_SGF);
edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -989,11 +1019,11 @@ static int ahash_finup_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg,
- DMA_TO_DEVICE);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_TO_DEVICE);
+ if (ret)
+ return ret;
state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
buf, state->buf_dma, buflen,
@@ -1002,11 +1032,22 @@ static int ahash_finup_ctx(struct ahash_request *req)
src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg +
sec4_sg_src_index, chained);
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
+
append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len +
buflen + req->nbytes, LDST_SGF);
edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1056,8 +1097,7 @@ static int ahash_digest(struct ahash_request *req)
}
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
+ edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->src_nents = src_nents;
edesc->chained = chained;
@@ -1067,6 +1107,12 @@ static int ahash_digest(struct ahash_request *req)
if (src_nents) {
sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
src_dma = edesc->sec4_sg_dma;
options = LDST_SGF;
} else {
@@ -1077,6 +1123,10 @@ static int ahash_digest(struct ahash_request *req)
edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1125,11 +1175,19 @@ static int ahash_final_no_ctx(struct ahash_request *req)
init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);
state->buf_dma = dma_map_single(jrdev, buf, buflen, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, state->buf_dma)) {
+ dev_err(jrdev, "unable to map src\n");
+ return -ENOMEM;
+ }
append_seq_in_ptr(desc, state->buf_dma, buflen, 0);
edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
edesc->src_nents = 0;
#ifdef DEBUG
@@ -1197,9 +1255,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes,
- DMA_TO_DEVICE);
+ edesc->dst_dma = 0;
state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg,
buf, *buflen);
@@ -1216,9 +1272,19 @@ static int ahash_update_no_ctx(struct ahash_request *req)
init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER |
HDR_REVERSE);
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
+
append_seq_in_ptr(desc, edesc->sec4_sg_dma, to_hash, LDST_SGF);
- map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ if (ret)
+ return ret;
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1297,8 +1363,6 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes, DMA_TO_DEVICE);
state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, buf,
state->buf_dma, buflen,
@@ -1307,11 +1371,22 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
src_map_to_sec4_sg(jrdev, req->src, src_nents, edesc->sec4_sg + 1,
chained);
+ edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
+ sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
+
append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen +
req->nbytes, LDST_SGF);
edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1380,13 +1455,19 @@ static int ahash_update_first(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
- edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
- sec4_sg_bytes,
- DMA_TO_DEVICE);
+ edesc->dst_dma = 0;
if (src_nents) {
sg_to_sec4_sg_last(req->src, src_nents,
edesc->sec4_sg, 0);
+ edesc->sec4_sg_dma = dma_map_single(jrdev,
+ edesc->sec4_sg,
+ sec4_sg_bytes,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
src_dma = edesc->sec4_sg_dma;
options = LDST_SGF;
} else {
@@ -1404,7 +1485,9 @@ static int ahash_update_first(struct ahash_request *req)
append_seq_in_ptr(desc, src_dma, to_hash, options);
- map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ if (ret)
+ return ret;
#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1453,6 +1536,7 @@ static int ahash_init(struct ahash_request *req)
state->final = ahash_final_no_ctx;
state->current_buf = 0;
+ state->buf_dma = 0;
return 0;
}
@@ -1787,8 +1871,36 @@ caam_hash_alloc(struct caam_hash_template *template,
static int __init caam_algapi_hash_init(void)
{
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+ struct device *ctrldev;
+ void *priv;
int i = 0, err = 0;
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev) {
+ of_node_put(dev_node);
+ return -ENODEV;
+ }
+
+ ctrldev = &pdev->dev;
+ priv = dev_get_drvdata(ctrldev);
+ of_node_put(dev_node);
+
+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
+
INIT_LIST_HEAD(&hash_list);
/* register crypto algorithms the device supports */
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index 8c07d3153f12..ae31e555793c 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -185,7 +185,7 @@ static int caam_read(struct hwrng *rng, void *data, size_t max, bool wait)
max - copied_idx, false);
}
-static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx)
+static inline int rng_create_sh_desc(struct caam_rng_ctx *ctx)
{
struct device *jrdev = ctx->jrdev;
u32 *desc = ctx->sh_desc;
@@ -203,13 +203,18 @@ static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx)
ctx->sh_desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "rng shdesc@: ", DUMP_PREFIX_ADDRESS, 16, 4,
desc, desc_bytes(desc), 1);
#endif
+ return 0;
}
-static inline void rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
+static inline int rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
{
struct device *jrdev = ctx->jrdev;
struct buf_data *bd = &ctx->bufs[buf_id];
@@ -220,12 +225,17 @@ static inline void rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
HDR_REVERSE);
bd->addr = dma_map_single(jrdev, bd->buf, RN_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(jrdev, bd->addr)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
append_seq_out_ptr_intlen(desc, bd->addr, RN_BUF_SIZE, 0);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "rng job desc@: ", DUMP_PREFIX_ADDRESS, 16, 4,
desc, desc_bytes(desc), 1);
#endif
+ return 0;
}
static void caam_cleanup(struct hwrng *rng)
@@ -242,24 +252,44 @@ static void caam_cleanup(struct hwrng *rng)
rng_unmap_ctx(rng_ctx);
}
-static void caam_init_buf(struct caam_rng_ctx *ctx, int buf_id)
+static int caam_init_buf(struct caam_rng_ctx *ctx, int buf_id)
{
struct buf_data *bd = &ctx->bufs[buf_id];
+ int err;
+
+ err = rng_create_job_desc(ctx, buf_id);
+ if (err)
+ return err;
- rng_create_job_desc(ctx, buf_id);
atomic_set(&bd->empty, BUF_EMPTY);
submit_job(ctx, buf_id == ctx->current_buf);
wait_for_completion(&bd->filled);
+
+ return 0;
}
-static void caam_init_rng(struct caam_rng_ctx *ctx, struct device *jrdev)
+static int caam_init_rng(struct caam_rng_ctx *ctx, struct device *jrdev)
{
+ int err;
+
ctx->jrdev = jrdev;
- rng_create_sh_desc(ctx);
+
+ err = rng_create_sh_desc(ctx);
+ if (err)
+ return err;
+
ctx->current_buf = 0;
ctx->cur_buf_idx = 0;
- caam_init_buf(ctx, 0);
- caam_init_buf(ctx, 1);
+
+ err = caam_init_buf(ctx, 0);
+ if (err)
+ return err;
+
+ err = caam_init_buf(ctx, 1);
+ if (err)
+ return err;
+
+ return 0;
}
static struct hwrng caam_rng = {
@@ -278,6 +308,35 @@ static void __exit caam_rng_exit(void)
static int __init caam_rng_init(void)
{
struct device *dev;
+ struct device_node *dev_node;
+ struct platform_device *pdev;
+ struct device *ctrldev;
+ void *priv;
+ int err;
+
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+ if (!dev_node) {
+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+ if (!dev_node)
+ return -ENODEV;
+ }
+
+ pdev = of_find_device_by_node(dev_node);
+ if (!pdev) {
+ of_node_put(dev_node);
+ return -ENODEV;
+ }
+
+ ctrldev = &pdev->dev;
+ priv = dev_get_drvdata(ctrldev);
+ of_node_put(dev_node);
+
+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
dev = caam_jr_alloc();
if (IS_ERR(dev)) {
@@ -287,7 +346,9 @@ static int __init caam_rng_init(void)
rng_ctx = kmalloc(sizeof(struct caam_rng_ctx), GFP_DMA);
if (!rng_ctx)
return -ENOMEM;
- caam_init_rng(rng_ctx, dev);
+ err = caam_init_rng(rng_ctx, dev);
+ if (err)
+ return err;
dev_info(dev, "registering rng-caam\n");
return hwrng_register(&caam_rng);
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 1c38f86bf63a..3cade79ea41e 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -5,6 +5,7 @@
* Copyright 2008-2012 Freescale Semiconductor, Inc.
*/
+#include <linux/device.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
@@ -87,6 +88,17 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
/* Set the bit to request direct access to DECO0 */
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+
+ if (ctrlpriv->virt_en == 1) {
+ setbits32(&topregs->ctrl.deco_rsr, DECORSR_JR0);
+
+ while (!(rd_reg32(&topregs->ctrl.deco_rsr) & DECORSR_VALID) &&
+ --timeout)
+ cpu_relax();
+
+ timeout = 100000;
+ }
+
setbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
while (!(rd_reg32(&topregs->ctrl.deco_rq) & DECORR_DEN0) &&
@@ -129,6 +141,9 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
*status = rd_reg32(&topregs->deco.op_status_hi) &
DECO_OP_STATUS_HI_ERR_MASK;
+ if (ctrlpriv->virt_en == 1)
+ clrbits32(&topregs->ctrl.deco_rsr, DECORSR_JR0);
+
/* Mark the DECO as free */
clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
@@ -295,9 +310,6 @@ static int caam_remove(struct platform_device *pdev)
/* Unmap controller region */
iounmap(&topregs->ctrl);
- kfree(ctrlpriv->jrpdev);
- kfree(ctrlpriv);
-
return ret;
}
@@ -380,9 +392,11 @@ static int caam_probe(struct platform_device *pdev)
#ifdef CONFIG_DEBUG_FS
struct caam_perfmon *perfmon;
#endif
- u64 cha_vid;
+ u32 scfgr, comp_params;
+ u32 cha_vid_ls;
- ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
+ ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(struct caam_drv_private),
+ GFP_KERNEL);
if (!ctrlpriv)
return -ENOMEM;
@@ -413,13 +427,40 @@ static int caam_probe(struct platform_device *pdev)
setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE |
(sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
+ /*
+ * Read the Compile Time paramters and SCFGR to determine
+ * if Virtualization is enabled for this platform
+ */
+ comp_params = rd_reg32(&topregs->ctrl.perfmon.comp_parms_ms);
+ scfgr = rd_reg32(&topregs->ctrl.scfgr);
+
+ ctrlpriv->virt_en = 0;
+ if (comp_params & CTPR_MS_VIRT_EN_INCL) {
+ /* VIRT_EN_INCL = 1 & VIRT_EN_POR = 1 or
+ * VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SCFGR_VIRT_EN = 1
+ */
+ if ((comp_params & CTPR_MS_VIRT_EN_POR) ||
+ (!(comp_params & CTPR_MS_VIRT_EN_POR) &&
+ (scfgr & SCFGR_VIRT_EN)))
+ ctrlpriv->virt_en = 1;
+ } else {
+ /* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
+ if (comp_params & CTPR_MS_VIRT_EN_POR)
+ ctrlpriv->virt_en = 1;
+ }
+
+ if (ctrlpriv->virt_en == 1)
+ setbits32(&topregs->ctrl.jrstart, JRSTART_JR0_START |
+ JRSTART_JR1_START | JRSTART_JR2_START |
+ JRSTART_JR3_START);
+
if (sizeof(dma_addr_t) == sizeof(u64))
if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
- dma_set_mask(dev, DMA_BIT_MASK(40));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
else
- dma_set_mask(dev, DMA_BIT_MASK(36));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
else
- dma_set_mask(dev, DMA_BIT_MASK(32));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
/*
* Detect and enable JobRs
@@ -432,8 +473,9 @@ static int caam_probe(struct platform_device *pdev)
of_device_is_compatible(np, "fsl,sec4.0-job-ring"))
rspec++;
- ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
- GFP_KERNEL);
+ ctrlpriv->jrpdev = devm_kzalloc(&pdev->dev,
+ sizeof(struct platform_device *) * rspec,
+ GFP_KERNEL);
if (ctrlpriv->jrpdev == NULL) {
iounmap(&topregs->ctrl);
return -ENOMEM;
@@ -456,8 +498,9 @@ static int caam_probe(struct platform_device *pdev)
}
/* Check to see if QI present. If so, enable */
- ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) &
- CTPR_QI_MASK);
+ ctrlpriv->qi_present =
+ !!(rd_reg32(&topregs->ctrl.perfmon.comp_parms_ms) &
+ CTPR_MS_QI_MASK);
if (ctrlpriv->qi_present) {
ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi;
/* This is all that's required to physically enable QI */
@@ -471,13 +514,13 @@ static int caam_probe(struct platform_device *pdev)
return -ENOMEM;
}
- cha_vid = rd_reg64(&topregs->ctrl.perfmon.cha_id);
+ cha_vid_ls = rd_reg32(&topregs->ctrl.perfmon.cha_id_ls);
/*
* If SEC has RNG version >= 4 and RNG state handle has not been
* already instantiated, do RNG instantiation
*/
- if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
+ if ((cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
ctrlpriv->rng4_sh_init =
rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
/*
@@ -531,7 +574,8 @@ static int caam_probe(struct platform_device *pdev)
/* NOTE: RTIC detection ought to go here, around Si time */
- caam_id = rd_reg64(&topregs->ctrl.perfmon.caam_id);
+ caam_id = (u64)rd_reg32(&topregs->ctrl.perfmon.caam_id_ms) << 32 |
+ (u64)rd_reg32(&topregs->ctrl.perfmon.caam_id_ls);
/* Report "alive" for developer to see */
dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
@@ -547,7 +591,7 @@ static int caam_probe(struct platform_device *pdev)
*/
perfmon = (struct caam_perfmon __force *)&ctrl->perfmon;
- ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL);
+ ctrlpriv->dfs_root = debugfs_create_dir(dev_name(dev), NULL);
ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
/* Controller-level - performance monitor counters */
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 7e4500f18df6..d397ff9d56fd 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -321,7 +321,6 @@ struct sec4_sg_entry {
/* Continue - Not the last FIFO store to come */
#define FIFOST_CONT_SHIFT 23
#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
-#define FIFOST_CONT_MASK (1 << FIFOST_CONT_SHIFT)
/*
* Extended Length - use 32-bit extended length that
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 6d85fcc5bd0a..97363db4e56e 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -82,6 +82,7 @@ struct caam_drv_private {
u8 total_jobrs; /* Total Job Rings in device */
u8 qi_present; /* Nonzero if QI present in device */
int secvio_irq; /* Security violation interrupt number */
+ int virt_en; /* Virtualization enabled in CAAM */
#define RNG4_MAX_HANDLES 2
/* RNG4 block */
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 1d80bd3636c5..4d18e27ffa9e 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -453,8 +453,8 @@ static int caam_jr_probe(struct platform_device *pdev)
int error;
jrdev = &pdev->dev;
- jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
- GFP_KERNEL);
+ jrpriv = devm_kmalloc(jrdev, sizeof(struct caam_drv_private_jr),
+ GFP_KERNEL);
if (!jrpriv)
return -ENOMEM;
@@ -476,21 +476,19 @@ static int caam_jr_probe(struct platform_device *pdev)
if (sizeof(dma_addr_t) == sizeof(u64))
if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
- dma_set_mask(jrdev, DMA_BIT_MASK(40));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(40));
else
- dma_set_mask(jrdev, DMA_BIT_MASK(36));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(36));
else
- dma_set_mask(jrdev, DMA_BIT_MASK(32));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(32));
/* Identify the interrupt */
jrpriv->irq = irq_of_parse_and_map(nprop, 0);
/* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */
- if (error) {
- kfree(jrpriv);
+ if (error)
return error;
- }
jrpriv->dev = jrdev;
spin_lock(&driver_data.jr_alloc_lock);
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index cbde8b95a6f8..f48e344ffc39 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -84,6 +84,7 @@
#endif
#ifndef CONFIG_64BIT
+#ifdef __BIG_ENDIAN
static inline void wr_reg64(u64 __iomem *reg, u64 data)
{
wr_reg32((u32 __iomem *)reg, (data & 0xffffffff00000000ull) >> 32);
@@ -95,6 +96,21 @@ static inline u64 rd_reg64(u64 __iomem *reg)
return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) |
((u64)rd_reg32((u32 __iomem *)reg + 1));
}
+#else
+#ifdef __LITTLE_ENDIAN
+static inline void wr_reg64(u64 __iomem *reg, u64 data)
+{
+ wr_reg32((u32 __iomem *)reg + 1, (data & 0xffffffff00000000ull) >> 32);
+ wr_reg32((u32 __iomem *)reg, data & 0x00000000ffffffffull);
+}
+
+static inline u64 rd_reg64(u64 __iomem *reg)
+{
+ return (((u64)rd_reg32((u32 __iomem *)reg + 1)) << 32) |
+ ((u64)rd_reg32((u32 __iomem *)reg));
+}
+#endif
+#endif
#endif
/*
@@ -114,45 +130,45 @@ struct jr_outentry {
*/
/* Number of DECOs */
-#define CHA_NUM_DECONUM_SHIFT 56
-#define CHA_NUM_DECONUM_MASK (0xfull << CHA_NUM_DECONUM_SHIFT)
+#define CHA_NUM_MS_DECONUM_SHIFT 24
+#define CHA_NUM_MS_DECONUM_MASK (0xfull << CHA_NUM_MS_DECONUM_SHIFT)
/* CHA Version IDs */
-#define CHA_ID_AES_SHIFT 0
-#define CHA_ID_AES_MASK (0xfull << CHA_ID_AES_SHIFT)
+#define CHA_ID_LS_AES_SHIFT 0
+#define CHA_ID_LS_AES_MASK (0xfull << CHA_ID_LS_AES_SHIFT)
-#define CHA_ID_DES_SHIFT 4
-#define CHA_ID_DES_MASK (0xfull << CHA_ID_DES_SHIFT)
+#define CHA_ID_LS_DES_SHIFT 4
+#define CHA_ID_LS_DES_MASK (0xfull << CHA_ID_LS_DES_SHIFT)
-#define CHA_ID_ARC4_SHIFT 8
-#define CHA_ID_ARC4_MASK (0xfull << CHA_ID_ARC4_SHIFT)
+#define CHA_ID_LS_ARC4_SHIFT 8
+#define CHA_ID_LS_ARC4_MASK (0xfull << CHA_ID_LS_ARC4_SHIFT)
-#define CHA_ID_MD_SHIFT 12
-#define CHA_ID_MD_MASK (0xfull << CHA_ID_MD_SHIFT)
+#define CHA_ID_LS_MD_SHIFT 12
+#define CHA_ID_LS_MD_MASK (0xfull << CHA_ID_LS_MD_SHIFT)
-#define CHA_ID_RNG_SHIFT 16
-#define CHA_ID_RNG_MASK (0xfull << CHA_ID_RNG_SHIFT)
+#define CHA_ID_LS_RNG_SHIFT 16
+#define CHA_ID_LS_RNG_MASK (0xfull << CHA_ID_LS_RNG_SHIFT)
-#define CHA_ID_SNW8_SHIFT 20
-#define CHA_ID_SNW8_MASK (0xfull << CHA_ID_SNW8_SHIFT)
+#define CHA_ID_LS_SNW8_SHIFT 20
+#define CHA_ID_LS_SNW8_MASK (0xfull << CHA_ID_LS_SNW8_SHIFT)
-#define CHA_ID_KAS_SHIFT 24
-#define CHA_ID_KAS_MASK (0xfull << CHA_ID_KAS_SHIFT)
+#define CHA_ID_LS_KAS_SHIFT 24
+#define CHA_ID_LS_KAS_MASK (0xfull << CHA_ID_LS_KAS_SHIFT)
-#define CHA_ID_PK_SHIFT 28
-#define CHA_ID_PK_MASK (0xfull << CHA_ID_PK_SHIFT)
+#define CHA_ID_LS_PK_SHIFT 28
+#define CHA_ID_LS_PK_MASK (0xfull << CHA_ID_LS_PK_SHIFT)
-#define CHA_ID_CRC_SHIFT 32
-#define CHA_ID_CRC_MASK (0xfull << CHA_ID_CRC_SHIFT)
+#define CHA_ID_MS_CRC_SHIFT 0
+#define CHA_ID_MS_CRC_MASK (0xfull << CHA_ID_MS_CRC_SHIFT)
-#define CHA_ID_SNW9_SHIFT 36
-#define CHA_ID_SNW9_MASK (0xfull << CHA_ID_SNW9_SHIFT)
+#define CHA_ID_MS_SNW9_SHIFT 4
+#define CHA_ID_MS_SNW9_MASK (0xfull << CHA_ID_MS_SNW9_SHIFT)
-#define CHA_ID_DECO_SHIFT 56
-#define CHA_ID_DECO_MASK (0xfull << CHA_ID_DECO_SHIFT)
+#define CHA_ID_MS_DECO_SHIFT 24
+#define CHA_ID_MS_DECO_MASK (0xfull << CHA_ID_MS_DECO_SHIFT)
-#define CHA_ID_JR_SHIFT 60
-#define CHA_ID_JR_MASK (0xfull << CHA_ID_JR_SHIFT)
+#define CHA_ID_MS_JR_SHIFT 28
+#define CHA_ID_MS_JR_MASK (0xfull << CHA_ID_MS_JR_SHIFT)
struct sec_vid {
u16 ip_id;
@@ -172,10 +188,14 @@ struct caam_perfmon {
u64 rsvd[13];
/* CAAM Hardware Instantiation Parameters fa0-fbf */
- u64 cha_rev; /* CRNR - CHA Revision Number */
-#define CTPR_QI_SHIFT 57
-#define CTPR_QI_MASK (0x1ull << CTPR_QI_SHIFT)
- u64 comp_parms; /* CTPR - Compile Parameters Register */
+ u32 cha_rev_ms; /* CRNR - CHA Rev No. Most significant half*/
+ u32 cha_rev_ls; /* CRNR - CHA Rev No. Least significant half*/
+#define CTPR_MS_QI_SHIFT 25
+#define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT)
+#define CTPR_MS_VIRT_EN_INCL 0x00000001
+#define CTPR_MS_VIRT_EN_POR 0x00000002
+ u32 comp_parms_ms; /* CTPR - Compile Parameters Register */
+ u32 comp_parms_ls; /* CTPR - Compile Parameters Register */
u64 rsvd1[2];
/* CAAM Global Status fc0-fdf */
@@ -189,9 +209,12 @@ struct caam_perfmon {
/* Component Instantiation Parameters fe0-fff */
u32 rtic_id; /* RVID - RTIC Version ID */
u32 ccb_id; /* CCBVID - CCB Version ID */
- u64 cha_id; /* CHAVID - CHA Version ID */
- u64 cha_num; /* CHANUM - CHA Number */
- u64 caam_id; /* CAAMVID - CAAM Version ID */
+ u32 cha_id_ms; /* CHAVID - CHA Version ID Most Significant*/
+ u32 cha_id_ls; /* CHAVID - CHA Version ID Least Significant*/
+ u32 cha_num_ms; /* CHANUM - CHA Number Most Significant */
+ u32 cha_num_ls; /* CHANUM - CHA Number Least Significant*/
+ u32 caam_id_ms; /* CAAMVID - CAAM Version ID MS */
+ u32 caam_id_ls; /* CAAMVID - CAAM Version ID LS */
};
/* LIODN programming for DMA configuration */
@@ -304,9 +327,12 @@ struct caam_ctrl {
/* Bus Access Configuration Section 010-11f */
/* Read/Writable */
struct masterid jr_mid[4]; /* JRxLIODNR - JobR LIODN setup */
- u32 rsvd3[12];
+ u32 rsvd3[11];
+ u32 jrstart; /* JRSTART - Job Ring Start Register */
struct masterid rtic_mid[4]; /* RTICxLIODNR - RTIC LIODN setup */
- u32 rsvd4[7];
+ u32 rsvd4[5];
+ u32 deco_rsr; /* DECORSR - Deco Request Source */
+ u32 rsvd11;
u32 deco_rq; /* DECORR - DECO Request */
struct partid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */
u32 rsvd5[22];
@@ -347,7 +373,10 @@ struct caam_ctrl {
#define MCFGR_DMA_RESET 0x10000000
#define MCFGR_LONG_PTR 0x00010000 /* Use >32-bit desc addressing */
#define SCFGR_RDBENABLE 0x00000400
+#define SCFGR_VIRT_EN 0x00008000
#define DECORR_RQD0ENABLE 0x00000001 /* Enable DECO0 for direct access */
+#define DECORSR_JR0 0x00000001 /* JR to supply TZ, SDID, ICID */
+#define DECORSR_VALID 0x80000000
#define DECORR_DEN0 0x00010000 /* DECO0 available for access*/
/* AXI read cache control */
@@ -365,6 +394,12 @@ struct caam_ctrl {
#define MCFGR_AXIPRI 0x00000008 /* Assert AXI priority sideband */
#define MCFGR_BURST_64 0x00000001 /* Max burst size */
+/* JRSTART register offsets */
+#define JRSTART_JR0_START 0x00000001 /* Start Job ring 0 */
+#define JRSTART_JR1_START 0x00000002 /* Start Job ring 1 */
+#define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */
+#define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */
+
/*
* caam_job_ring - direct job ring setup
* 1-4 possible per instantiation, base + 1000/2000/3000/4000
diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
index d3505a018720..7f592d8d07bb 100644
--- a/drivers/crypto/ccp/Makefile
+++ b/drivers/crypto/ccp/Makefile
@@ -1,6 +1,11 @@
obj-$(CONFIG_CRYPTO_DEV_CCP_DD) += ccp.o
ccp-objs := ccp-dev.o ccp-ops.o
+ifdef CONFIG_X86
ccp-objs += ccp-pci.o
+endif
+ifdef CONFIG_ARM64
+ccp-objs += ccp-platform.o
+endif
obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
ccp-crypto-objs := ccp-crypto-main.o \
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c
index 2c7816149b01..a7d110652a74 100644
--- a/drivers/crypto/ccp/ccp-dev.c
+++ b/drivers/crypto/ccp/ccp-dev.c
@@ -20,7 +20,9 @@
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/cpu.h>
+#ifdef CONFIG_X86
#include <asm/cpu_device_id.h>
+#endif
#include <linux/ccp.h>
#include "ccp-dev.h"
@@ -360,6 +362,12 @@ int ccp_init(struct ccp_device *ccp)
/* Build queue interrupt mask (two interrupts per queue) */
qim |= cmd_q->int_ok | cmd_q->int_err;
+#ifdef CONFIG_ARM64
+ /* For arm64 set the recommended queue cache settings */
+ iowrite32(ccp->axcache, ccp->io_regs + CMD_Q_CACHE_BASE +
+ (CMD_Q_CACHE_INC * i));
+#endif
+
dev_dbg(dev, "queue #%u available\n", i);
}
if (ccp->cmd_q_count == 0) {
@@ -558,12 +566,15 @@ bool ccp_queues_suspended(struct ccp_device *ccp)
}
#endif
+#ifdef CONFIG_X86
static const struct x86_cpu_id ccp_support[] = {
{ X86_VENDOR_AMD, 22, },
};
+#endif
static int __init ccp_mod_init(void)
{
+#ifdef CONFIG_X86
struct cpuinfo_x86 *cpuinfo = &boot_cpu_data;
int ret;
@@ -589,12 +600,30 @@ static int __init ccp_mod_init(void)
break;
}
+#endif
+
+#ifdef CONFIG_ARM64
+ int ret;
+
+ ret = ccp_platform_init();
+ if (ret)
+ return ret;
+
+ /* Don't leave the driver loaded if init failed */
+ if (!ccp_get_device()) {
+ ccp_platform_exit();
+ return -ENODEV;
+ }
+
+ return 0;
+#endif
return -ENODEV;
}
static void __exit ccp_mod_exit(void)
{
+#ifdef CONFIG_X86
struct cpuinfo_x86 *cpuinfo = &boot_cpu_data;
switch (cpuinfo->x86) {
@@ -602,6 +631,11 @@ static void __exit ccp_mod_exit(void)
ccp_pci_exit();
break;
}
+#endif
+
+#ifdef CONFIG_ARM64
+ ccp_platform_exit();
+#endif
}
module_init(ccp_mod_init);
diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h
index 7ec536e702ec..62ff35a6b9ec 100644
--- a/drivers/crypto/ccp/ccp-dev.h
+++ b/drivers/crypto/ccp/ccp-dev.h
@@ -23,8 +23,6 @@
#include <linux/hw_random.h>
-#define IO_OFFSET 0x20000
-
#define MAX_DMAPOOL_NAME_LEN 32
#define MAX_HW_QUEUES 5
@@ -32,6 +30,9 @@
#define TRNG_RETRIES 10
+#define CACHE_NONE 0x00
+#define CACHE_WB_NO_ALLOC 0xb7
+
/****** Register Mappings ******/
#define Q_MASK_REG 0x000
@@ -50,7 +51,7 @@
#define CMD_Q_INT_STATUS_BASE 0x214
#define CMD_Q_STATUS_INCR 0x20
-#define CMD_Q_CACHE 0x228
+#define CMD_Q_CACHE_BASE 0x228
#define CMD_Q_CACHE_INC 0x20
#define CMD_Q_ERROR(__qs) ((__qs) & 0x0000003f);
@@ -194,6 +195,7 @@ struct ccp_device {
void *dev_specific;
int (*get_irq)(struct ccp_device *ccp);
void (*free_irq)(struct ccp_device *ccp);
+ unsigned int irq;
/*
* I/O area used for device communication. The register mapping
@@ -254,12 +256,18 @@ struct ccp_device {
/* Suspend support */
unsigned int suspending;
wait_queue_head_t suspend_queue;
+
+ /* DMA caching attribute support */
+ unsigned int axcache;
};
int ccp_pci_init(void);
void ccp_pci_exit(void);
+int ccp_platform_init(void);
+void ccp_platform_exit(void);
+
struct ccp_device *ccp_alloc_struct(struct device *dev);
int ccp_init(struct ccp_device *ccp);
void ccp_destroy(struct ccp_device *ccp);
diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c
index 9ae006d69df4..8729364261d7 100644
--- a/drivers/crypto/ccp/ccp-ops.c
+++ b/drivers/crypto/ccp/ccp-ops.c
@@ -1606,7 +1606,7 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
goto e_ksb;
ccp_reverse_set_dm_area(&exp, rsa->exp, rsa->exp_len, CCP_KSB_BYTES,
- true);
+ false);
ret = ccp_copy_to_ksb(cmd_q, &exp, op.jobid, op.ksb_key,
CCP_PASSTHRU_BYTESWAP_NOOP);
if (ret) {
@@ -1623,10 +1623,10 @@ static int ccp_run_rsa_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
goto e_exp;
ccp_reverse_set_dm_area(&src, rsa->mod, rsa->mod_len, CCP_KSB_BYTES,
- true);
+ false);
src.address += o_len; /* Adjust the address for the copy operation */
ccp_reverse_set_dm_area(&src, rsa->src, rsa->src_len, CCP_KSB_BYTES,
- true);
+ false);
src.address -= o_len; /* Reset the address to original value */
/* Prepare the output area for the operation */
@@ -1841,20 +1841,20 @@ static int ccp_run_ecc_mm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
/* Copy the ECC modulus */
ccp_reverse_set_dm_area(&src, ecc->mod, ecc->mod_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
/* Copy the first operand */
ccp_reverse_set_dm_area(&src, ecc->u.mm.operand_1,
ecc->u.mm.operand_1_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
if (ecc->function != CCP_ECC_FUNCTION_MINV_384BIT) {
/* Copy the second operand */
ccp_reverse_set_dm_area(&src, ecc->u.mm.operand_2,
ecc->u.mm.operand_2_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
}
@@ -1960,17 +1960,17 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
/* Copy the ECC modulus */
ccp_reverse_set_dm_area(&src, ecc->mod, ecc->mod_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
/* Copy the first point X and Y coordinate */
ccp_reverse_set_dm_area(&src, ecc->u.pm.point_1.x,
ecc->u.pm.point_1.x_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
ccp_reverse_set_dm_area(&src, ecc->u.pm.point_1.y,
ecc->u.pm.point_1.y_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
/* Set the first point Z coordianate to 1 */
@@ -1981,11 +1981,11 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
/* Copy the second point X and Y coordinate */
ccp_reverse_set_dm_area(&src, ecc->u.pm.point_2.x,
ecc->u.pm.point_2.x_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
ccp_reverse_set_dm_area(&src, ecc->u.pm.point_2.y,
ecc->u.pm.point_2.y_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
/* Set the second point Z coordianate to 1 */
@@ -1995,14 +1995,14 @@ static int ccp_run_ecc_pm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd)
/* Copy the Domain "a" parameter */
ccp_reverse_set_dm_area(&src, ecc->u.pm.domain_a,
ecc->u.pm.domain_a_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
if (ecc->function == CCP_ECC_FUNCTION_PMUL_384BIT) {
/* Copy the scalar value */
ccp_reverse_set_dm_area(&src, ecc->u.pm.scalar,
ecc->u.pm.scalar_len,
- CCP_ECC_OPERAND_SIZE, true);
+ CCP_ECC_OPERAND_SIZE, false);
src.address += CCP_ECC_OPERAND_SIZE;
}
}
diff --git a/drivers/crypto/ccp/ccp-pci.c b/drivers/crypto/ccp/ccp-pci.c
index 0d746236df5e..180cc87b4dbb 100644
--- a/drivers/crypto/ccp/ccp-pci.c
+++ b/drivers/crypto/ccp/ccp-pci.c
@@ -12,8 +12,10 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/device.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
+#include <linux/dma-mapping.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -24,6 +26,8 @@
#include "ccp-dev.h"
#define IO_BAR 2
+#define IO_OFFSET 0x20000
+
#define MSIX_VECTORS 2
struct ccp_msix {
@@ -89,7 +93,8 @@ static int ccp_get_msi_irq(struct ccp_device *ccp)
if (ret)
return ret;
- ret = request_irq(pdev->irq, ccp_irq_handler, 0, "ccp", dev);
+ ccp->irq = pdev->irq;
+ ret = request_irq(ccp->irq, ccp_irq_handler, 0, "ccp", dev);
if (ret) {
dev_notice(dev, "unable to allocate MSI IRQ (%d)\n", ret);
goto e_msi;
@@ -136,7 +141,7 @@ static void ccp_free_irqs(struct ccp_device *ccp)
dev);
pci_disable_msix(pdev);
} else {
- free_irq(pdev->irq, dev);
+ free_irq(ccp->irq, dev);
pci_disable_msi(pdev);
}
}
@@ -147,21 +152,12 @@ static int ccp_find_mmio_area(struct ccp_device *ccp)
struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
resource_size_t io_len;
unsigned long io_flags;
- int bar;
io_flags = pci_resource_flags(pdev, IO_BAR);
io_len = pci_resource_len(pdev, IO_BAR);
if ((io_flags & IORESOURCE_MEM) && (io_len >= (IO_OFFSET + 0x800)))
return IO_BAR;
- for (bar = 0; bar < PCI_STD_RESOURCE_END; bar++) {
- io_flags = pci_resource_flags(pdev, bar);
- io_len = pci_resource_len(pdev, bar);
- if ((io_flags & IORESOURCE_MEM) &&
- (io_len >= (IO_OFFSET + 0x800)))
- return bar;
- }
-
return -EIO;
}
@@ -214,20 +210,13 @@ static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
ccp->io_regs = ccp->io_map + IO_OFFSET;
- ret = dma_set_mask(dev, DMA_BIT_MASK(48));
- if (ret == 0) {
- ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(48));
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+ if (ret) {
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret) {
- dev_err(dev,
- "pci_set_consistent_dma_mask failed (%d)\n",
+ dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
ret);
- goto e_bar0;
- }
- } else {
- ret = dma_set_mask(dev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(dev, "pci_set_dma_mask failed (%d)\n", ret);
- goto e_bar0;
+ goto e_iomap;
}
}
@@ -235,13 +224,13 @@ static int ccp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = ccp_init(ccp);
if (ret)
- goto e_bar0;
+ goto e_iomap;
dev_notice(dev, "enabled\n");
return 0;
-e_bar0:
+e_iomap:
pci_iounmap(pdev, ccp->io_map);
e_device:
diff --git a/drivers/crypto/ccp/ccp-platform.c b/drivers/crypto/ccp/ccp-platform.c
new file mode 100644
index 000000000000..b0a2806908f1
--- /dev/null
+++ b/drivers/crypto/ccp/ccp-platform.c
@@ -0,0 +1,230 @@
+/*
+ * AMD Cryptographic Coprocessor (CCP) driver
+ *
+ * Copyright (C) 2014 Advanced Micro Devices, Inc.
+ *
+ * Author: Tom Lendacky <thomas.lendacky@amd.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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/ccp.h>
+#include <linux/of.h>
+
+#include "ccp-dev.h"
+
+
+static int ccp_get_irq(struct ccp_device *ccp)
+{
+ struct device *dev = ccp->dev;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ int ret;
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ return ret;
+
+ ccp->irq = ret;
+ ret = request_irq(ccp->irq, ccp_irq_handler, 0, "ccp", dev);
+ if (ret) {
+ dev_notice(dev, "unable to allocate IRQ (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ccp_get_irqs(struct ccp_device *ccp)
+{
+ struct device *dev = ccp->dev;
+ int ret;
+
+ ret = ccp_get_irq(ccp);
+ if (!ret)
+ return 0;
+
+ /* Couldn't get an interrupt */
+ dev_notice(dev, "could not enable interrupts (%d)\n", ret);
+
+ return ret;
+}
+
+static void ccp_free_irqs(struct ccp_device *ccp)
+{
+ struct device *dev = ccp->dev;
+
+ free_irq(ccp->irq, dev);
+}
+
+static struct resource *ccp_find_mmio_area(struct ccp_device *ccp)
+{
+ struct device *dev = ccp->dev;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct resource *ior;
+
+ ior = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (ior && (resource_size(ior) >= 0x800))
+ return ior;
+
+ return NULL;
+}
+
+static int ccp_platform_probe(struct platform_device *pdev)
+{
+ struct ccp_device *ccp;
+ struct device *dev = &pdev->dev;
+ struct resource *ior;
+ int ret;
+
+ ret = -ENOMEM;
+ ccp = ccp_alloc_struct(dev);
+ if (!ccp)
+ goto e_err;
+
+ ccp->dev_specific = NULL;
+ ccp->get_irq = ccp_get_irqs;
+ ccp->free_irq = ccp_free_irqs;
+
+ ior = ccp_find_mmio_area(ccp);
+ ccp->io_map = devm_ioremap_resource(dev, ior);
+ if (IS_ERR(ccp->io_map)) {
+ ret = PTR_ERR(ccp->io_map);
+ goto e_free;
+ }
+ ccp->io_regs = ccp->io_map;
+
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+ *(dev->dma_mask) = DMA_BIT_MASK(48);
+ dev->coherent_dma_mask = DMA_BIT_MASK(48);
+
+ if (of_property_read_bool(dev->of_node, "dma-coherent"))
+ ccp->axcache = CACHE_WB_NO_ALLOC;
+ else
+ ccp->axcache = CACHE_NONE;
+
+ dev_set_drvdata(dev, ccp);
+
+ ret = ccp_init(ccp);
+ if (ret)
+ goto e_free;
+
+ dev_notice(dev, "enabled\n");
+
+ return 0;
+
+e_free:
+ kfree(ccp);
+
+e_err:
+ dev_notice(dev, "initialization failed\n");
+ return ret;
+}
+
+static int ccp_platform_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ccp_device *ccp = dev_get_drvdata(dev);
+
+ ccp_destroy(ccp);
+
+ kfree(ccp);
+
+ dev_notice(dev, "disabled\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ccp_platform_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct device *dev = &pdev->dev;
+ struct ccp_device *ccp = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int i;
+
+ spin_lock_irqsave(&ccp->cmd_lock, flags);
+
+ ccp->suspending = 1;
+
+ /* Wake all the queue kthreads to prepare for suspend */
+ for (i = 0; i < ccp->cmd_q_count; i++)
+ wake_up_process(ccp->cmd_q[i].kthread);
+
+ spin_unlock_irqrestore(&ccp->cmd_lock, flags);
+
+ /* Wait for all queue kthreads to say they're done */
+ while (!ccp_queues_suspended(ccp))
+ wait_event_interruptible(ccp->suspend_queue,
+ ccp_queues_suspended(ccp));
+
+ return 0;
+}
+
+static int ccp_platform_resume(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ccp_device *ccp = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int i;
+
+ spin_lock_irqsave(&ccp->cmd_lock, flags);
+
+ ccp->suspending = 0;
+
+ /* Wake up all the kthreads */
+ for (i = 0; i < ccp->cmd_q_count; i++) {
+ ccp->cmd_q[i].suspended = 0;
+ wake_up_process(ccp->cmd_q[i].kthread);
+ }
+
+ spin_unlock_irqrestore(&ccp->cmd_lock, flags);
+
+ return 0;
+}
+#endif
+
+static const struct of_device_id ccp_platform_ids[] = {
+ { .compatible = "amd,ccp-seattle-v1a" },
+ { },
+};
+
+static struct platform_driver ccp_platform_driver = {
+ .driver = {
+ .name = "AMD Cryptographic Coprocessor",
+ .owner = THIS_MODULE,
+ .of_match_table = ccp_platform_ids,
+ },
+ .probe = ccp_platform_probe,
+ .remove = ccp_platform_remove,
+#ifdef CONFIG_PM
+ .suspend = ccp_platform_suspend,
+ .resume = ccp_platform_resume,
+#endif
+};
+
+int ccp_platform_init(void)
+{
+ return platform_driver_register(&ccp_platform_driver);
+}
+
+void ccp_platform_exit(void)
+{
+ platform_driver_unregister(&ccp_platform_driver);
+}
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c
index 502edf0a2933..544f6d327ede 100644
--- a/drivers/crypto/nx/nx-842.c
+++ b/drivers/crypto/nx/nx-842.c
@@ -1247,7 +1247,7 @@ static struct vio_device_id nx842_driver_ids[] = {
static struct vio_driver nx842_driver = {
.name = MODULE_NAME,
.probe = nx842_probe,
- .remove = nx842_remove,
+ .remove = __exit_p(nx842_remove),
.get_desired_dma = nx842_get_desired_dma,
.id_table = nx842_driver_ids,
};
diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
new file mode 100644
index 000000000000..49bede2a9f77
--- /dev/null
+++ b/drivers/crypto/qat/Kconfig
@@ -0,0 +1,23 @@
+config CRYPTO_DEV_QAT
+ tristate
+ select CRYPTO_AEAD
+ select CRYPTO_AUTHENC
+ select CRYPTO_ALGAPI
+ select CRYPTO_AES
+ select CRYPTO_CBC
+ select CRYPTO_SHA1
+ select CRYPTO_SHA256
+ select CRYPTO_SHA512
+ select FW_LOADER
+
+config CRYPTO_DEV_QAT_DH895xCC
+ tristate "Support for Intel(R) DH895xCC"
+ depends on X86 && PCI
+ default n
+ select CRYPTO_DEV_QAT
+ help
+ Support for Intel(R) DH895xcc with Intel(R) QuickAssist Technology
+ for accelerating crypto and compression workloads.
+
+ To compile this as a module, choose M here: the module
+ will be called qat_dh895xcc.
diff --git a/drivers/crypto/qat/Makefile b/drivers/crypto/qat/Makefile
new file mode 100644
index 000000000000..d11481be225e
--- /dev/null
+++ b/drivers/crypto/qat/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_QAT) += qat_common/
+obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc/
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
new file mode 100644
index 000000000000..e0424dc382fe
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -0,0 +1,14 @@
+obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
+intel_qat-objs := adf_cfg.o \
+ adf_ctl_drv.o \
+ adf_dev_mgr.o \
+ adf_init.o \
+ adf_accel_engine.o \
+ adf_aer.o \
+ adf_transport.o \
+ qat_crypto.o \
+ qat_algs.o \
+ qat_uclo.o \
+ qat_hal.o
+
+intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
new file mode 100644
index 000000000000..9282381b03ce
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -0,0 +1,205 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_ACCEL_DEVICES_H_
+#define ADF_ACCEL_DEVICES_H_
+#include <linux/module.h>
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/io.h>
+#include "adf_cfg_common.h"
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define ADF_DH895XCC_DEVICE_NAME "dh895xcc"
+#define ADF_DH895XCC_PCI_DEVICE_ID 0x435
+#define ADF_DH895XCC_PMISC_BAR 1
+#define ADF_DH895XCC_ETR_BAR 2
+#define ADF_PCI_MAX_BARS 3
+#define ADF_DEVICE_NAME_LENGTH 32
+#define ADF_ETR_MAX_RINGS_PER_BANK 16
+#define ADF_MAX_MSIX_VECTOR_NAME 16
+#define ADF_DEVICE_NAME_PREFIX "qat_"
+
+enum adf_accel_capabilities {
+ ADF_ACCEL_CAPABILITIES_NULL = 0,
+ ADF_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC = 1,
+ ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC = 2,
+ ADF_ACCEL_CAPABILITIES_CIPHER = 4,
+ ADF_ACCEL_CAPABILITIES_AUTHENTICATION = 8,
+ ADF_ACCEL_CAPABILITIES_COMPRESSION = 32,
+ ADF_ACCEL_CAPABILITIES_LZS_COMPRESSION = 64,
+ ADF_ACCEL_CAPABILITIES_RANDOM_NUMBER = 128
+};
+
+struct adf_bar {
+ resource_size_t base_addr;
+ void __iomem *virt_addr;
+ resource_size_t size;
+} __packed;
+
+struct adf_accel_msix {
+ struct msix_entry *entries;
+ char **names;
+} __packed;
+
+struct adf_accel_pci {
+ struct pci_dev *pci_dev;
+ struct adf_accel_msix msix_entries;
+ struct adf_bar pci_bars[ADF_PCI_MAX_BARS];
+ uint8_t revid;
+ uint8_t sku;
+} __packed;
+
+enum dev_state {
+ DEV_DOWN = 0,
+ DEV_UP
+};
+
+enum dev_sku_info {
+ DEV_SKU_1 = 0,
+ DEV_SKU_2,
+ DEV_SKU_3,
+ DEV_SKU_4,
+ DEV_SKU_UNKNOWN,
+};
+
+static inline const char *get_sku_info(enum dev_sku_info info)
+{
+ switch (info) {
+ case DEV_SKU_1:
+ return "SKU1";
+ case DEV_SKU_2:
+ return "SKU2";
+ case DEV_SKU_3:
+ return "SKU3";
+ case DEV_SKU_4:
+ return "SKU4";
+ case DEV_SKU_UNKNOWN:
+ default:
+ break;
+ }
+ return "Unknown SKU";
+}
+
+struct adf_hw_device_class {
+ const char *name;
+ const enum adf_device_type type;
+ uint32_t instances;
+} __packed;
+
+struct adf_cfg_device_data;
+struct adf_accel_dev;
+struct adf_etr_data;
+struct adf_etr_ring_data;
+
+struct adf_hw_device_data {
+ struct adf_hw_device_class *dev_class;
+ uint32_t (*get_accel_mask)(uint32_t fuse);
+ uint32_t (*get_ae_mask)(uint32_t fuse);
+ uint32_t (*get_misc_bar_id)(struct adf_hw_device_data *self);
+ uint32_t (*get_etr_bar_id)(struct adf_hw_device_data *self);
+ uint32_t (*get_num_aes)(struct adf_hw_device_data *self);
+ uint32_t (*get_num_accels)(struct adf_hw_device_data *self);
+ enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self);
+ void (*hw_arb_ring_enable)(struct adf_etr_ring_data *ring);
+ void (*hw_arb_ring_disable)(struct adf_etr_ring_data *ring);
+ int (*alloc_irq)(struct adf_accel_dev *accel_dev);
+ void (*free_irq)(struct adf_accel_dev *accel_dev);
+ void (*enable_error_correction)(struct adf_accel_dev *accel_dev);
+ const char *fw_name;
+ uint32_t pci_dev_id;
+ uint32_t fuses;
+ uint32_t accel_capabilities_mask;
+ uint16_t accel_mask;
+ uint16_t ae_mask;
+ uint16_t tx_rings_mask;
+ uint8_t tx_rx_gap;
+ uint8_t instance_id;
+ uint8_t num_banks;
+ uint8_t num_accel;
+ uint8_t num_logical_accel;
+ uint8_t num_engines;
+} __packed;
+
+/* CSR write macro */
+#define ADF_CSR_WR(csr_base, csr_offset, val) \
+ __raw_writel(val, csr_base + csr_offset)
+
+/* CSR read macro */
+#define ADF_CSR_RD(csr_base, csr_offset) __raw_readl(csr_base + csr_offset)
+
+#define GET_DEV(accel_dev) ((accel_dev)->accel_pci_dev.pci_dev->dev)
+#define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars)
+#define GET_HW_DATA(accel_dev) (accel_dev->hw_device)
+#define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks)
+#define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines)
+#define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev
+
+struct adf_admin_comms;
+struct icp_qat_fw_loader_handle;
+struct adf_fw_loader_data {
+ struct icp_qat_fw_loader_handle *fw_loader;
+ const struct firmware *uof_fw;
+};
+
+struct adf_accel_dev {
+ struct adf_etr_data *transport;
+ struct adf_hw_device_data *hw_device;
+ struct adf_cfg_device_data *cfg;
+ struct adf_fw_loader_data *fw_loader;
+ struct adf_admin_comms *admin;
+ struct list_head crypto_list;
+ unsigned long status;
+ atomic_t ref_count;
+ struct dentry *debugfs_dir;
+ struct list_head list;
+ struct module *owner;
+ uint8_t accel_id;
+ uint8_t numa_node;
+ struct adf_accel_pci accel_pci_dev;
+} __packed;
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_accel_engine.c b/drivers/crypto/qat/qat_common/adf_accel_engine.c
new file mode 100644
index 000000000000..c77453b900a3
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_accel_engine.c
@@ -0,0 +1,168 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/firmware.h>
+#include <linux/pci.h>
+#include "adf_cfg.h"
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "icp_qat_uclo.h"
+
+int adf_ae_fw_load(struct adf_accel_dev *accel_dev)
+{
+ struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
+ struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+ void *uof_addr;
+ uint32_t uof_size;
+
+ if (request_firmware(&loader_data->uof_fw, hw_device->fw_name,
+ &accel_dev->accel_pci_dev.pci_dev->dev)) {
+ pr_err("QAT: Failed to load firmware %s\n", hw_device->fw_name);
+ return -EFAULT;
+ }
+
+ uof_size = loader_data->uof_fw->size;
+ uof_addr = (void *)loader_data->uof_fw->data;
+ if (qat_uclo_map_uof_obj(loader_data->fw_loader, uof_addr, uof_size)) {
+ pr_err("QAT: Failed to map UOF\n");
+ goto out_err;
+ }
+ if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) {
+ pr_err("QAT: Failed to map UOF\n");
+ goto out_err;
+ }
+ return 0;
+
+out_err:
+ release_firmware(loader_data->uof_fw);
+ return -EFAULT;
+}
+
+int adf_ae_fw_release(struct adf_accel_dev *accel_dev)
+{
+ struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
+
+ release_firmware(loader_data->uof_fw);
+ qat_uclo_del_uof_obj(loader_data->fw_loader);
+ qat_hal_deinit(loader_data->fw_loader);
+ loader_data->fw_loader = NULL;
+ return 0;
+}
+
+int adf_ae_start(struct adf_accel_dev *accel_dev)
+{
+ struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
+
+ for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
+ if (hw_data->ae_mask & (1 << ae)) {
+ qat_hal_start(loader_data->fw_loader, ae, 0xFF);
+ ae_ctr++;
+ }
+ }
+ pr_info("QAT: qat_dev%d started %d acceleration engines\n",
+ accel_dev->accel_id, ae_ctr);
+ return 0;
+}
+
+int adf_ae_stop(struct adf_accel_dev *accel_dev)
+{
+ struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
+
+ for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
+ if (hw_data->ae_mask & (1 << ae)) {
+ qat_hal_stop(loader_data->fw_loader, ae, 0xFF);
+ ae_ctr++;
+ }
+ }
+ pr_info("QAT: qat_dev%d stopped %d acceleration engines\n",
+ accel_dev->accel_id, ae_ctr);
+ return 0;
+}
+
+static int adf_ae_reset(struct adf_accel_dev *accel_dev, int ae)
+{
+ struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
+
+ qat_hal_reset(loader_data->fw_loader);
+ if (qat_hal_clr_reset(loader_data->fw_loader))
+ return -EFAULT;
+
+ return 0;
+}
+
+int adf_ae_init(struct adf_accel_dev *accel_dev)
+{
+ struct adf_fw_loader_data *loader_data;
+
+ loader_data = kzalloc(sizeof(*loader_data), GFP_KERNEL);
+ if (!loader_data)
+ return -ENOMEM;
+
+ accel_dev->fw_loader = loader_data;
+ if (qat_hal_init(accel_dev)) {
+ pr_err("QAT: Failed to init the AEs\n");
+ kfree(loader_data);
+ return -EFAULT;
+ }
+ if (adf_ae_reset(accel_dev, 0)) {
+ pr_err("QAT: Failed to reset the AEs\n");
+ qat_hal_deinit(loader_data->fw_loader);
+ kfree(loader_data);
+ return -EFAULT;
+ }
+ return 0;
+}
+
+int adf_ae_shutdown(struct adf_accel_dev *accel_dev)
+{
+ kfree(accel_dev->fw_loader);
+ accel_dev->fw_loader = NULL;
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
new file mode 100644
index 000000000000..c29d4c3926bf
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_aer.c
@@ -0,0 +1,259 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/aer.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+
+static struct workqueue_struct *device_reset_wq;
+
+static pci_ers_result_t adf_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+
+ pr_info("QAT: Acceleration driver hardware error detected.\n");
+ if (!accel_dev) {
+ pr_err("QAT: Can't find acceleration device\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ if (state == pci_channel_io_perm_failure) {
+ pr_err("QAT: Can't recover from device error\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/* reset dev data */
+struct adf_reset_dev_data {
+ int mode;
+ struct adf_accel_dev *accel_dev;
+ struct completion compl;
+ struct work_struct reset_work;
+};
+
+#define PPDSTAT_OFFSET 0x7E
+static void adf_dev_restore(struct adf_accel_dev *accel_dev)
+{
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+ struct pci_dev *parent = pdev->bus->self;
+ uint16_t ppdstat = 0, bridge_ctl = 0;
+ int pending = 0;
+
+ pr_info("QAT: Reseting device qat_dev%d\n", accel_dev->accel_id);
+ pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat);
+ pending = ppdstat & PCI_EXP_DEVSTA_TRPND;
+ if (pending) {
+ int ctr = 0;
+
+ do {
+ msleep(100);
+ pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat);
+ pending = ppdstat & PCI_EXP_DEVSTA_TRPND;
+ } while (pending && ctr++ < 10);
+ }
+
+ if (pending)
+ pr_info("QAT: Transaction still in progress. Proceeding\n");
+
+ pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl);
+ bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET;
+ pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
+ msleep(100);
+ bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+ pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
+ msleep(100);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
+}
+
+static void adf_device_reset_worker(struct work_struct *work)
+{
+ struct adf_reset_dev_data *reset_data =
+ container_of(work, struct adf_reset_dev_data, reset_work);
+ struct adf_accel_dev *accel_dev = reset_data->accel_dev;
+
+ adf_dev_restarting_notify(accel_dev);
+ adf_dev_stop(accel_dev);
+ adf_dev_restore(accel_dev);
+ if (adf_dev_start(accel_dev)) {
+ /* The device hanged and we can't restart it so stop here */
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
+ kfree(reset_data);
+ WARN(1, "QAT: device restart failed. Device is unusable\n");
+ return;
+ }
+ adf_dev_restarted_notify(accel_dev);
+ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+
+ /* The dev is back alive. Notify the caller if in sync mode */
+ if (reset_data->mode == ADF_DEV_RESET_SYNC)
+ complete(&reset_data->compl);
+ else
+ kfree(reset_data);
+}
+
+static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
+ enum adf_dev_reset_mode mode)
+{
+ struct adf_reset_dev_data *reset_data;
+
+ if (adf_dev_started(accel_dev) &&
+ !test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
+ return 0;
+
+ set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+ reset_data = kzalloc(sizeof(*reset_data), GFP_ATOMIC);
+ if (!reset_data)
+ return -ENOMEM;
+ reset_data->accel_dev = accel_dev;
+ init_completion(&reset_data->compl);
+ reset_data->mode = mode;
+ INIT_WORK(&reset_data->reset_work, adf_device_reset_worker);
+ queue_work(device_reset_wq, &reset_data->reset_work);
+
+ /* If in sync mode wait for the result */
+ if (mode == ADF_DEV_RESET_SYNC) {
+ int ret = 0;
+ /* Maximum device reset time is 10 seconds */
+ unsigned long wait_jiffies = msecs_to_jiffies(10000);
+ unsigned long timeout = wait_for_completion_timeout(
+ &reset_data->compl, wait_jiffies);
+ if (!timeout) {
+ pr_err("QAT: Reset device timeout expired\n");
+ ret = -EFAULT;
+ }
+ kfree(reset_data);
+ return ret;
+ }
+ return 0;
+}
+
+static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
+{
+ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+
+ if (!accel_dev) {
+ pr_err("QAT: Can't find acceleration device\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+ if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC))
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+static void adf_resume(struct pci_dev *pdev)
+{
+ pr_info("QAT: Acceleration driver reset completed\n");
+ pr_info("QAT: Device is up and runnig\n");
+}
+
+static struct pci_error_handlers adf_err_handler = {
+ .error_detected = adf_error_detected,
+ .slot_reset = adf_slot_reset,
+ .resume = adf_resume,
+};
+
+/**
+ * adf_enable_aer() - Enable Advance Error Reporting for acceleration device
+ * @accel_dev: Pointer to acceleration device.
+ * @adf: PCI device driver owning the given acceleration device.
+ *
+ * Function enables PCI Advance Error Reporting for the
+ * QAT acceleration device accel_dev.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf)
+{
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+
+ adf->err_handler = &adf_err_handler;
+ pci_enable_pcie_error_reporting(pdev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_enable_aer);
+
+/**
+ * adf_disable_aer() - Enable Advance Error Reporting for acceleration device
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function disables PCI Advance Error Reporting for the
+ * QAT acceleration device accel_dev.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: void
+ */
+void adf_disable_aer(struct adf_accel_dev *accel_dev)
+{
+ struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+
+ pci_disable_pcie_error_reporting(pdev);
+}
+EXPORT_SYMBOL_GPL(adf_disable_aer);
+
+int adf_init_aer(void)
+{
+ device_reset_wq = create_workqueue("qat_device_reset_wq");
+ return (device_reset_wq == NULL) ? -EFAULT : 0;
+}
+
+void adf_exit_aer(void)
+{
+ if (device_reset_wq)
+ destroy_workqueue(device_reset_wq);
+ device_reset_wq = NULL;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_cfg.c b/drivers/crypto/qat/qat_common/adf_cfg.c
new file mode 100644
index 000000000000..aba7f1d043fb
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg.c
@@ -0,0 +1,361 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include "adf_accel_devices.h"
+#include "adf_cfg.h"
+
+static DEFINE_MUTEX(qat_cfg_read_lock);
+
+static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos)
+{
+ struct adf_cfg_device_data *dev_cfg = sfile->private;
+
+ mutex_lock(&qat_cfg_read_lock);
+ return seq_list_start(&dev_cfg->sec_list, *pos);
+}
+
+static int qat_dev_cfg_show(struct seq_file *sfile, void *v)
+{
+ struct list_head *list;
+ struct adf_cfg_section *sec =
+ list_entry(v, struct adf_cfg_section, list);
+
+ seq_printf(sfile, "[%s]\n", sec->name);
+ list_for_each(list, &sec->param_head) {
+ struct adf_cfg_key_val *ptr =
+ list_entry(list, struct adf_cfg_key_val, list);
+ seq_printf(sfile, "%s = %s\n", ptr->key, ptr->val);
+ }
+ return 0;
+}
+
+static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos)
+{
+ struct adf_cfg_device_data *dev_cfg = sfile->private;
+
+ return seq_list_next(v, &dev_cfg->sec_list, pos);
+}
+
+static void qat_dev_cfg_stop(struct seq_file *sfile, void *v)
+{
+ mutex_unlock(&qat_cfg_read_lock);
+}
+
+static const struct seq_operations qat_dev_cfg_sops = {
+ .start = qat_dev_cfg_start,
+ .next = qat_dev_cfg_next,
+ .stop = qat_dev_cfg_stop,
+ .show = qat_dev_cfg_show
+};
+
+static int qat_dev_cfg_open(struct inode *inode, struct file *file)
+{
+ int ret = seq_open(file, &qat_dev_cfg_sops);
+
+ if (!ret) {
+ struct seq_file *seq_f = file->private_data;
+
+ seq_f->private = inode->i_private;
+ }
+ return ret;
+}
+
+static const struct file_operations qat_dev_cfg_fops = {
+ .open = qat_dev_cfg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+/**
+ * adf_cfg_dev_add() - Create an acceleration device configuration table.
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function creates a configuration table for the given acceleration device.
+ * The table stores device specific config values.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
+{
+ struct adf_cfg_device_data *dev_cfg_data;
+
+ dev_cfg_data = kzalloc(sizeof(*dev_cfg_data), GFP_KERNEL);
+ if (!dev_cfg_data)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&dev_cfg_data->sec_list);
+ init_rwsem(&dev_cfg_data->lock);
+ accel_dev->cfg = dev_cfg_data;
+
+ /* accel_dev->debugfs_dir should always be non-NULL here */
+ dev_cfg_data->debug = debugfs_create_file("dev_cfg", S_IRUSR,
+ accel_dev->debugfs_dir,
+ dev_cfg_data,
+ &qat_dev_cfg_fops);
+ if (!dev_cfg_data->debug) {
+ pr_err("QAT: Failed to create qat cfg debugfs entry.\n");
+ kfree(dev_cfg_data);
+ accel_dev->cfg = NULL;
+ return -EFAULT;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_cfg_dev_add);
+
+static void adf_cfg_section_del_all(struct list_head *head);
+
+void adf_cfg_del_all(struct adf_accel_dev *accel_dev)
+{
+ struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
+
+ down_write(&dev_cfg_data->lock);
+ adf_cfg_section_del_all(&dev_cfg_data->sec_list);
+ up_write(&dev_cfg_data->lock);
+}
+
+/**
+ * adf_cfg_dev_remove() - Clears acceleration device configuration table.
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function removes configuration table from the given acceleration device
+ * and frees all allocated memory.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: void
+ */
+void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
+{
+ struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
+
+ down_write(&dev_cfg_data->lock);
+ adf_cfg_section_del_all(&dev_cfg_data->sec_list);
+ up_write(&dev_cfg_data->lock);
+ debugfs_remove(dev_cfg_data->debug);
+ kfree(dev_cfg_data);
+ accel_dev->cfg = NULL;
+}
+EXPORT_SYMBOL_GPL(adf_cfg_dev_remove);
+
+static void adf_cfg_keyval_add(struct adf_cfg_key_val *new,
+ struct adf_cfg_section *sec)
+{
+ list_add_tail(&new->list, &sec->param_head);
+}
+
+static void adf_cfg_keyval_del_all(struct list_head *head)
+{
+ struct list_head *list_ptr, *tmp;
+
+ list_for_each_prev_safe(list_ptr, tmp, head) {
+ struct adf_cfg_key_val *ptr =
+ list_entry(list_ptr, struct adf_cfg_key_val, list);
+ list_del(list_ptr);
+ kfree(ptr);
+ }
+}
+
+static void adf_cfg_section_del_all(struct list_head *head)
+{
+ struct adf_cfg_section *ptr;
+ struct list_head *list, *tmp;
+
+ list_for_each_prev_safe(list, tmp, head) {
+ ptr = list_entry(list, struct adf_cfg_section, list);
+ adf_cfg_keyval_del_all(&ptr->param_head);
+ list_del(list);
+ kfree(ptr);
+ }
+}
+
+static struct adf_cfg_key_val *adf_cfg_key_value_find(struct adf_cfg_section *s,
+ const char *key)
+{
+ struct list_head *list;
+
+ list_for_each(list, &s->param_head) {
+ struct adf_cfg_key_val *ptr =
+ list_entry(list, struct adf_cfg_key_val, list);
+ if (!strcmp(ptr->key, key))
+ return ptr;
+ }
+ return NULL;
+}
+
+static struct adf_cfg_section *adf_cfg_sec_find(struct adf_accel_dev *accel_dev,
+ const char *sec_name)
+{
+ struct adf_cfg_device_data *cfg = accel_dev->cfg;
+ struct list_head *list;
+
+ list_for_each(list, &cfg->sec_list) {
+ struct adf_cfg_section *ptr =
+ list_entry(list, struct adf_cfg_section, list);
+ if (!strcmp(ptr->name, sec_name))
+ return ptr;
+ }
+ return NULL;
+}
+
+static int adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
+ const char *sec_name,
+ const char *key_name,
+ char *val)
+{
+ struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
+ struct adf_cfg_key_val *keyval = NULL;
+
+ if (sec)
+ keyval = adf_cfg_key_value_find(sec, key_name);
+ if (keyval) {
+ memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ return 0;
+ }
+ return -1;
+}
+
+/**
+ * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
+ * @accel_dev: Pointer to acceleration device.
+ * @section_name: Name of the section where the param will be added
+ * @key: The key string
+ * @val: Value pain for the given @key
+ * @type: Type - string, int or address
+ *
+ * Function adds configuration key - value entry in the appropriate section
+ * in the given acceleration device
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
+ const char *section_name,
+ const char *key, const void *val,
+ enum adf_cfg_val_type type)
+{
+ struct adf_cfg_device_data *cfg = accel_dev->cfg;
+ struct adf_cfg_key_val *key_val;
+ struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev,
+ section_name);
+ if (!section)
+ return -EFAULT;
+
+ key_val = kzalloc(sizeof(*key_val), GFP_KERNEL);
+ if (!key_val)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&key_val->list);
+ strlcpy(key_val->key, key, sizeof(key_val->key));
+
+ if (type == ADF_DEC) {
+ snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
+ "%ld", (*((long *)val)));
+ } else if (type == ADF_STR) {
+ strlcpy(key_val->val, (char *)val, sizeof(key_val->val));
+ } else if (type == ADF_HEX) {
+ snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
+ "0x%lx", (unsigned long)val);
+ } else {
+ pr_err("QAT: Unknown type given.\n");
+ kfree(key_val);
+ return -1;
+ }
+ key_val->type = type;
+ down_write(&cfg->lock);
+ adf_cfg_keyval_add(key_val, section);
+ up_write(&cfg->lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param);
+
+/**
+ * adf_cfg_section_add() - Add config section entry to config table.
+ * @accel_dev: Pointer to acceleration device.
+ * @name: Name of the section
+ *
+ * Function adds configuration section where key - value entries
+ * will be stored.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
+{
+ struct adf_cfg_device_data *cfg = accel_dev->cfg;
+ struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
+
+ if (sec)
+ return 0;
+
+ sec = kzalloc(sizeof(*sec), GFP_KERNEL);
+ if (!sec)
+ return -ENOMEM;
+
+ strlcpy(sec->name, name, sizeof(sec->name));
+ INIT_LIST_HEAD(&sec->param_head);
+ down_write(&cfg->lock);
+ list_add_tail(&sec->list, &cfg->sec_list);
+ up_write(&cfg->lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_cfg_section_add);
+
+int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
+ const char *section, const char *name,
+ char *value)
+{
+ struct adf_cfg_device_data *cfg = accel_dev->cfg;
+ int ret;
+
+ down_read(&cfg->lock);
+ ret = adf_cfg_key_val_get(accel_dev, section, name, value);
+ up_read(&cfg->lock);
+ return ret;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_cfg.h b/drivers/crypto/qat/qat_common/adf_cfg.h
new file mode 100644
index 000000000000..6a9c6f6b5ec9
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg.h
@@ -0,0 +1,87 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_CFG_H_
+#define ADF_CFG_H_
+
+#include <linux/list.h>
+#include <linux/rwsem.h>
+#include <linux/debugfs.h>
+#include "adf_accel_devices.h"
+#include "adf_cfg_common.h"
+#include "adf_cfg_strings.h"
+
+struct adf_cfg_key_val {
+ char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+ enum adf_cfg_val_type type;
+ struct list_head list;
+};
+
+struct adf_cfg_section {
+ char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
+ struct list_head list;
+ struct list_head param_head;
+};
+
+struct adf_cfg_device_data {
+ struct list_head sec_list;
+ struct dentry *debug;
+ struct rw_semaphore lock;
+};
+
+int adf_cfg_dev_add(struct adf_accel_dev *accel_dev);
+void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev);
+int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name);
+void adf_cfg_del_all(struct adf_accel_dev *accel_dev);
+int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
+ const char *section_name,
+ const char *key, const void *val,
+ enum adf_cfg_val_type type);
+int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
+ const char *section, const char *name, char *value);
+
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_common.h b/drivers/crypto/qat/qat_common/adf_cfg_common.h
new file mode 100644
index 000000000000..88b82187ac35
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_common.h
@@ -0,0 +1,100 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_CFG_COMMON_H_
+#define ADF_CFG_COMMON_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define ADF_CFG_MAX_STR_LEN 64
+#define ADF_CFG_MAX_KEY_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
+#define ADF_CFG_MAX_VAL_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
+#define ADF_CFG_MAX_SECTION_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
+#define ADF_CFG_BASE_DEC 10
+#define ADF_CFG_BASE_HEX 16
+#define ADF_CFG_ALL_DEVICES 0xFE
+#define ADF_CFG_NO_DEVICE 0xFF
+#define ADF_CFG_AFFINITY_WHATEVER 0xFF
+#define MAX_DEVICE_NAME_SIZE 32
+#define ADF_MAX_DEVICES 32
+
+enum adf_cfg_val_type {
+ ADF_DEC,
+ ADF_HEX,
+ ADF_STR
+};
+
+enum adf_device_type {
+ DEV_UNKNOWN = 0,
+ DEV_DH895XCC,
+};
+
+struct adf_dev_status_info {
+ enum adf_device_type type;
+ uint8_t accel_id;
+ uint8_t instance_id;
+ uint8_t num_ae;
+ uint8_t num_accel;
+ uint8_t num_logical_accel;
+ uint8_t banks_per_accel;
+ uint8_t state;
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t fun;
+ char name[MAX_DEVICE_NAME_SIZE];
+};
+
+#define ADF_CTL_IOC_MAGIC 'a'
+#define IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS _IOW(ADF_CTL_IOC_MAGIC, 0, \
+ struct adf_user_cfg_ctl_data)
+#define IOCTL_STOP_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 1, \
+ struct adf_user_cfg_ctl_data)
+#define IOCTL_START_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 2, \
+ struct adf_user_cfg_ctl_data)
+#define IOCTL_STATUS_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 3, uint32_t)
+#define IOCTL_GET_NUM_DEVICES _IOW(ADF_CTL_IOC_MAGIC, 4, int32_t)
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
new file mode 100644
index 000000000000..c7ac758ebc90
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
@@ -0,0 +1,83 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_CFG_STRINGS_H_
+#define ADF_CFG_STRINGS_H_
+
+#define ADF_GENERAL_SEC "GENERAL"
+#define ADF_KERNEL_SEC "KERNEL"
+#define ADF_ACCEL_SEC "Accelerator"
+#define ADF_NUM_CY "NumberCyInstances"
+#define ADF_NUM_DC "NumberDcInstances"
+#define ADF_RING_SYM_SIZE "NumConcurrentSymRequests"
+#define ADF_RING_ASYM_SIZE "NumConcurrentAsymRequests"
+#define ADF_RING_DC_SIZE "NumConcurrentRequests"
+#define ADF_RING_ASYM_TX "RingAsymTx"
+#define ADF_RING_SYM_TX "RingSymTx"
+#define ADF_RING_RND_TX "RingNrbgTx"
+#define ADF_RING_ASYM_RX "RingAsymRx"
+#define ADF_RING_SYM_RX "RinSymRx"
+#define ADF_RING_RND_RX "RingNrbgRx"
+#define ADF_RING_DC_TX "RingTx"
+#define ADF_RING_DC_RX "RingRx"
+#define ADF_ETRMGR_BANK "Bank"
+#define ADF_RING_BANK_NUM "BankNumber"
+#define ADF_CY "Cy"
+#define ADF_DC "Dc"
+#define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled"
+#define ADF_ETRMGR_COALESCING_ENABLED_FORMAT \
+ ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCING_ENABLED
+#define ADF_ETRMGR_COALESCE_TIMER "InterruptCoalescingTimerNs"
+#define ADF_ETRMGR_COALESCE_TIMER_FORMAT \
+ ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCE_TIMER
+#define ADF_ETRMGR_COALESCING_MSG_ENABLED "InterruptCoalescingNumResponses"
+#define ADF_ETRMGR_COALESCING_MSG_ENABLED_FORMAT \
+ ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCING_MSG_ENABLED
+#define ADF_ETRMGR_CORE_AFFINITY "CoreAffinity"
+#define ADF_ETRMGR_CORE_AFFINITY_FORMAT \
+ ADF_ETRMGR_BANK"%d"ADF_ETRMGR_CORE_AFFINITY
+#define ADF_ACCEL_STR "Accelerator%d"
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_user.h b/drivers/crypto/qat/qat_common/adf_cfg_user.h
new file mode 100644
index 000000000000..0c38a155a865
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_user.h
@@ -0,0 +1,94 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_CFG_USER_H_
+#define ADF_CFG_USER_H_
+
+#include "adf_cfg_common.h"
+#include "adf_cfg_strings.h"
+
+struct adf_user_cfg_key_val {
+ char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+ union {
+ char *user_val_ptr;
+ uint64_t padding1;
+ };
+ union {
+ struct adf_user_cfg_key_val *prev;
+ uint64_t padding2;
+ };
+ union {
+ struct adf_user_cfg_key_val *next;
+ uint64_t padding3;
+ };
+ enum adf_cfg_val_type type;
+};
+
+struct adf_user_cfg_section {
+ char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
+ union {
+ struct adf_user_cfg_key_val *params;
+ uint64_t padding1;
+ };
+ union {
+ struct adf_user_cfg_section *prev;
+ uint64_t padding2;
+ };
+ union {
+ struct adf_user_cfg_section *next;
+ uint64_t padding3;
+ };
+};
+
+struct adf_user_cfg_ctl_data {
+ union {
+ struct adf_user_cfg_section *config_section;
+ uint64_t padding;
+ };
+ uint8_t device_id;
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
new file mode 100644
index 000000000000..5e8f9d431e5d
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -0,0 +1,192 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_DRV_H
+#define ADF_DRV_H
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include "adf_accel_devices.h"
+#include "icp_qat_fw_loader_handle.h"
+#include "icp_qat_hal.h"
+
+#define ADF_STATUS_RESTARTING 0
+#define ADF_STATUS_STARTING 1
+#define ADF_STATUS_CONFIGURED 2
+#define ADF_STATUS_STARTED 3
+#define ADF_STATUS_AE_INITIALISED 4
+#define ADF_STATUS_AE_UCODE_LOADED 5
+#define ADF_STATUS_AE_STARTED 6
+#define ADF_STATUS_ORPHAN_TH_RUNNING 7
+#define ADF_STATUS_IRQ_ALLOCATED 8
+
+enum adf_dev_reset_mode {
+ ADF_DEV_RESET_ASYNC = 0,
+ ADF_DEV_RESET_SYNC
+};
+
+enum adf_event {
+ ADF_EVENT_INIT = 0,
+ ADF_EVENT_START,
+ ADF_EVENT_STOP,
+ ADF_EVENT_SHUTDOWN,
+ ADF_EVENT_RESTARTING,
+ ADF_EVENT_RESTARTED,
+};
+
+struct service_hndl {
+ int (*event_hld)(struct adf_accel_dev *accel_dev,
+ enum adf_event event);
+ unsigned long init_status;
+ unsigned long start_status;
+ char *name;
+ struct list_head list;
+ int admin;
+};
+
+int adf_service_register(struct service_hndl *service);
+int adf_service_unregister(struct service_hndl *service);
+
+int adf_dev_init(struct adf_accel_dev *accel_dev);
+int adf_dev_start(struct adf_accel_dev *accel_dev);
+int adf_dev_stop(struct adf_accel_dev *accel_dev);
+int adf_dev_shutdown(struct adf_accel_dev *accel_dev);
+
+int adf_ctl_dev_register(void);
+void adf_ctl_dev_unregister(void);
+int adf_processes_dev_register(void);
+void adf_processes_dev_unregister(void);
+
+int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev);
+void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev);
+struct list_head *adf_devmgr_get_head(void);
+struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id);
+struct adf_accel_dev *adf_devmgr_get_first(void);
+struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev);
+int adf_devmgr_verify_id(uint32_t id);
+void adf_devmgr_get_num_dev(uint32_t *num);
+int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev);
+int adf_dev_started(struct adf_accel_dev *accel_dev);
+int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev);
+int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev);
+int adf_ae_init(struct adf_accel_dev *accel_dev);
+int adf_ae_shutdown(struct adf_accel_dev *accel_dev);
+int adf_ae_fw_load(struct adf_accel_dev *accel_dev);
+int adf_ae_fw_release(struct adf_accel_dev *accel_dev);
+int adf_ae_start(struct adf_accel_dev *accel_dev);
+int adf_ae_stop(struct adf_accel_dev *accel_dev);
+
+int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf);
+void adf_disable_aer(struct adf_accel_dev *accel_dev);
+int adf_init_aer(void);
+void adf_exit_aer(void);
+
+int adf_dev_get(struct adf_accel_dev *accel_dev);
+void adf_dev_put(struct adf_accel_dev *accel_dev);
+int adf_dev_in_use(struct adf_accel_dev *accel_dev);
+int adf_init_etr_data(struct adf_accel_dev *accel_dev);
+void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev);
+int qat_crypto_register(void);
+int qat_crypto_unregister(void);
+struct qat_crypto_instance *qat_crypto_get_instance_node(int node);
+void qat_crypto_put_instance(struct qat_crypto_instance *inst);
+void qat_alg_callback(void *resp);
+int qat_algs_init(void);
+void qat_algs_exit(void);
+int qat_algs_register(void);
+int qat_algs_unregister(void);
+
+int qat_hal_init(struct adf_accel_dev *accel_dev);
+void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle);
+void qat_hal_start(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
+ unsigned int ctx_mask);
+void qat_hal_stop(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
+ unsigned int ctx_mask);
+void qat_hal_reset(struct icp_qat_fw_loader_handle *handle);
+int qat_hal_clr_reset(struct icp_qat_fw_loader_handle *handle);
+void qat_hal_set_live_ctx(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask);
+int qat_hal_set_ae_lm_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, enum icp_qat_uof_regtype lm_type,
+ unsigned char mode);
+int qat_hal_set_ae_ctx_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char mode);
+int qat_hal_set_ae_nn_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char mode);
+void qat_hal_set_pc(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask, unsigned int upc);
+void qat_hal_wr_uwords(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int uaddr,
+ unsigned int words_num, uint64_t *uword);
+void qat_hal_wr_umem(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
+ unsigned int uword_addr, unsigned int words_num,
+ unsigned int *data);
+int qat_hal_get_ins_num(void);
+int qat_hal_batch_wr_lm(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae,
+ struct icp_qat_uof_batch_init *lm_init_header);
+int qat_hal_init_gpr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata);
+int qat_hal_init_wr_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata);
+int qat_hal_init_rd_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata);
+int qat_hal_init_nn(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ unsigned short reg_num, unsigned int regdata);
+int qat_hal_wr_lm(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned short lm_addr, unsigned int value);
+int qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle);
+void qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle);
+int qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle,
+ void *addr_ptr, int mem_size);
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
new file mode 100644
index 000000000000..d97069b8a8e4
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
@@ -0,0 +1,490 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_cfg.h"
+#include "adf_cfg_common.h"
+#include "adf_cfg_user.h"
+
+#define DEVICE_NAME "qat_adf_ctl"
+
+static DEFINE_MUTEX(adf_ctl_lock);
+static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations adf_ctl_ops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = adf_ctl_ioctl,
+ .compat_ioctl = adf_ctl_ioctl,
+};
+
+struct adf_ctl_drv_info {
+ unsigned int major;
+ struct cdev drv_cdev;
+ struct class *drv_class;
+};
+
+static struct adf_ctl_drv_info adt_ctl_drv;
+
+static void adf_chr_drv_destroy(void)
+{
+ device_destroy(adt_ctl_drv.drv_class, MKDEV(adt_ctl_drv.major, 0));
+ cdev_del(&adt_ctl_drv.drv_cdev);
+ class_destroy(adt_ctl_drv.drv_class);
+ unregister_chrdev_region(MKDEV(adt_ctl_drv.major, 0), 1);
+}
+
+static int adf_chr_drv_create(void)
+{
+ dev_t dev_id;
+ struct device *drv_device;
+
+ if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
+ pr_err("QAT: unable to allocate chrdev region\n");
+ return -EFAULT;
+ }
+
+ adt_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME);
+ if (IS_ERR(adt_ctl_drv.drv_class)) {
+ pr_err("QAT: class_create failed for adf_ctl\n");
+ goto err_chrdev_unreg;
+ }
+ adt_ctl_drv.major = MAJOR(dev_id);
+ cdev_init(&adt_ctl_drv.drv_cdev, &adf_ctl_ops);
+ if (cdev_add(&adt_ctl_drv.drv_cdev, dev_id, 1)) {
+ pr_err("QAT: cdev add failed\n");
+ goto err_class_destr;
+ }
+
+ drv_device = device_create(adt_ctl_drv.drv_class, NULL,
+ MKDEV(adt_ctl_drv.major, 0),
+ NULL, DEVICE_NAME);
+ if (!drv_device) {
+ pr_err("QAT: failed to create device\n");
+ goto err_cdev_del;
+ }
+ return 0;
+err_cdev_del:
+ cdev_del(&adt_ctl_drv.drv_cdev);
+err_class_destr:
+ class_destroy(adt_ctl_drv.drv_class);
+err_chrdev_unreg:
+ unregister_chrdev_region(dev_id, 1);
+ return -EFAULT;
+}
+
+static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
+ unsigned long arg)
+{
+ struct adf_user_cfg_ctl_data *cfg_data;
+
+ cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
+ if (!cfg_data)
+ return -ENOMEM;
+
+ /* Initialize device id to NO DEVICE as 0 is a valid device id */
+ cfg_data->device_id = ADF_CFG_NO_DEVICE;
+
+ if (copy_from_user(cfg_data, (void __user *)arg, sizeof(*cfg_data))) {
+ pr_err("QAT: failed to copy from user cfg_data.\n");
+ kfree(cfg_data);
+ return -EIO;
+ }
+
+ *ctl_data = cfg_data;
+ return 0;
+}
+
+static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
+ const char *section,
+ const struct adf_user_cfg_key_val *key_val)
+{
+ if (key_val->type == ADF_HEX) {
+ long *ptr = (long *)key_val->val;
+ long val = *ptr;
+
+ if (adf_cfg_add_key_value_param(accel_dev, section,
+ key_val->key, (void *)val,
+ key_val->type)) {
+ pr_err("QAT: failed to add keyvalue.\n");
+ return -EFAULT;
+ }
+ } else {
+ if (adf_cfg_add_key_value_param(accel_dev, section,
+ key_val->key, key_val->val,
+ key_val->type)) {
+ pr_err("QAT: failed to add keyvalue.\n");
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
+ struct adf_user_cfg_ctl_data *ctl_data)
+{
+ struct adf_user_cfg_key_val key_val;
+ struct adf_user_cfg_key_val *params_head;
+ struct adf_user_cfg_section section, *section_head;
+
+ section_head = ctl_data->config_section;
+
+ while (section_head) {
+ if (copy_from_user(&section, (void __user *)section_head,
+ sizeof(*section_head))) {
+ pr_err("QAT: failed to copy section info\n");
+ goto out_err;
+ }
+
+ if (adf_cfg_section_add(accel_dev, section.name)) {
+ pr_err("QAT: failed to add section.\n");
+ goto out_err;
+ }
+
+ params_head = section_head->params;
+
+ while (params_head) {
+ if (copy_from_user(&key_val, (void __user *)params_head,
+ sizeof(key_val))) {
+ pr_err("QAT: Failed to copy keyvalue.\n");
+ goto out_err;
+ }
+ if (adf_add_key_value_data(accel_dev, section.name,
+ &key_val)) {
+ goto out_err;
+ }
+ params_head = key_val.next;
+ }
+ section_head = section.next;
+ }
+ return 0;
+out_err:
+ adf_cfg_del_all(accel_dev);
+ return -EFAULT;
+}
+
+static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+ struct adf_user_cfg_ctl_data *ctl_data;
+ struct adf_accel_dev *accel_dev;
+
+ ret = adf_ctl_alloc_resources(&ctl_data, arg);
+ if (ret)
+ return ret;
+
+ accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
+ if (!accel_dev) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (adf_dev_started(accel_dev)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (adf_copy_key_value_data(accel_dev, ctl_data)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
+out:
+ kfree(ctl_data);
+ return ret;
+}
+
+static int adf_ctl_is_device_in_use(int id)
+{
+ struct list_head *itr, *head = adf_devmgr_get_head();
+
+ list_for_each(itr, head) {
+ struct adf_accel_dev *dev =
+ list_entry(itr, struct adf_accel_dev, list);
+
+ if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
+ if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
+ pr_info("QAT: device qat_dev%d is busy\n",
+ dev->accel_id);
+ return -EBUSY;
+ }
+ }
+ }
+ return 0;
+}
+
+static int adf_ctl_stop_devices(uint32_t id)
+{
+ struct list_head *itr, *head = adf_devmgr_get_head();
+ int ret = 0;
+
+ list_for_each(itr, head) {
+ struct adf_accel_dev *accel_dev =
+ list_entry(itr, struct adf_accel_dev, list);
+ if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
+ if (!adf_dev_started(accel_dev))
+ continue;
+
+ if (adf_dev_stop(accel_dev)) {
+ pr_err("QAT: Failed to stop qat_dev%d\n", id);
+ ret = -EFAULT;
+ }
+ }
+ }
+ return ret;
+}
+
+static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+ struct adf_user_cfg_ctl_data *ctl_data;
+
+ ret = adf_ctl_alloc_resources(&ctl_data, arg);
+ if (ret)
+ return ret;
+
+ if (adf_devmgr_verify_id(ctl_data->device_id)) {
+ pr_err("QAT: Device %d not found\n", ctl_data->device_id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ ret = adf_ctl_is_device_in_use(ctl_data->device_id);
+ if (ret)
+ goto out;
+
+ if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
+ pr_info("QAT: Stopping all acceleration devices.\n");
+ else
+ pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
+ ctl_data->device_id);
+
+ ret = adf_ctl_stop_devices(ctl_data->device_id);
+ if (ret)
+ pr_err("QAT: failed to stop device.\n");
+out:
+ kfree(ctl_data);
+ return ret;
+}
+
+static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+ struct adf_user_cfg_ctl_data *ctl_data;
+ struct adf_accel_dev *accel_dev;
+
+ ret = adf_ctl_alloc_resources(&ctl_data, arg);
+ if (ret)
+ return ret;
+
+ accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
+ if (!accel_dev) {
+ pr_err("QAT: Device %d not found\n", ctl_data->device_id);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!adf_dev_started(accel_dev)) {
+ pr_info("QAT: Starting acceleration device qat_dev%d.\n",
+ ctl_data->device_id);
+ ret = adf_dev_start(accel_dev);
+ } else {
+ pr_info("QAT: Acceleration device qat_dev%d already started.\n",
+ ctl_data->device_id);
+ }
+ if (ret) {
+ pr_err("QAT: Failed to start qat_dev%d\n", ctl_data->device_id);
+ adf_dev_stop(accel_dev);
+ }
+out:
+ kfree(ctl_data);
+ return ret;
+}
+
+static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ uint32_t num_devices = 0;
+
+ adf_devmgr_get_num_dev(&num_devices);
+ if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct adf_hw_device_data *hw_data;
+ struct adf_dev_status_info dev_info;
+ struct adf_accel_dev *accel_dev;
+
+ if (copy_from_user(&dev_info, (void __user *)arg,
+ sizeof(struct adf_dev_status_info))) {
+ pr_err("QAT: failed to copy from user.\n");
+ return -EFAULT;
+ }
+
+ accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
+ if (!accel_dev) {
+ pr_err("QAT: Device %d not found\n", dev_info.accel_id);
+ return -ENODEV;
+ }
+ hw_data = accel_dev->hw_device;
+ dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
+ dev_info.num_ae = hw_data->get_num_aes(hw_data);
+ dev_info.num_accel = hw_data->get_num_accels(hw_data);
+ dev_info.num_logical_accel = hw_data->num_logical_accel;
+ dev_info.banks_per_accel = hw_data->num_banks
+ / hw_data->num_logical_accel;
+ strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
+ dev_info.instance_id = hw_data->instance_id;
+ dev_info.type = hw_data->dev_class->type;
+ dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
+ dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
+ dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
+
+ if (copy_to_user((void __user *)arg, &dev_info,
+ sizeof(struct adf_dev_status_info))) {
+ pr_err("QAT: failed to copy status.\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ int ret;
+
+ if (mutex_lock_interruptible(&adf_ctl_lock))
+ return -EFAULT;
+
+ switch (cmd) {
+ case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
+ ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
+ break;
+
+ case IOCTL_STOP_ACCEL_DEV:
+ ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
+ break;
+
+ case IOCTL_START_ACCEL_DEV:
+ ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
+ break;
+
+ case IOCTL_GET_NUM_DEVICES:
+ ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
+ break;
+
+ case IOCTL_STATUS_ACCEL_DEV:
+ ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
+ break;
+ default:
+ pr_err("QAT: Invalid ioclt\n");
+ ret = -EFAULT;
+ break;
+ }
+ mutex_unlock(&adf_ctl_lock);
+ return ret;
+}
+
+static int __init adf_register_ctl_device_driver(void)
+{
+ mutex_init(&adf_ctl_lock);
+
+ if (qat_algs_init())
+ goto err_algs_init;
+
+ if (adf_chr_drv_create())
+ goto err_chr_dev;
+
+ if (adf_init_aer())
+ goto err_aer;
+
+ if (qat_crypto_register())
+ goto err_crypto_register;
+
+ return 0;
+
+err_crypto_register:
+ adf_exit_aer();
+err_aer:
+ adf_chr_drv_destroy();
+err_chr_dev:
+ qat_algs_exit();
+err_algs_init:
+ mutex_destroy(&adf_ctl_lock);
+ return -EFAULT;
+}
+
+static void __exit adf_unregister_ctl_device_driver(void)
+{
+ adf_chr_drv_destroy();
+ adf_exit_aer();
+ qat_crypto_unregister();
+ qat_algs_exit();
+ mutex_destroy(&adf_ctl_lock);
+}
+
+module_init(adf_register_ctl_device_driver);
+module_exit(adf_unregister_ctl_device_driver);
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel");
+MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
+MODULE_ALIAS("intel_qat");
diff --git a/drivers/crypto/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
new file mode 100644
index 000000000000..ae71555c0868
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
@@ -0,0 +1,215 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/mutex.h>
+#include <linux/list.h>
+#include "adf_cfg.h"
+#include "adf_common_drv.h"
+
+static LIST_HEAD(accel_table);
+static DEFINE_MUTEX(table_lock);
+static uint32_t num_devices;
+
+/**
+ * adf_devmgr_add_dev() - Add accel_dev to the acceleration framework
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function adds acceleration device to the acceleration framework.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev)
+{
+ struct list_head *itr;
+
+ if (num_devices == ADF_MAX_DEVICES) {
+ pr_err("QAT: Only support up to %d devices\n", ADF_MAX_DEVICES);
+ return -EFAULT;
+ }
+
+ mutex_lock(&table_lock);
+ list_for_each(itr, &accel_table) {
+ struct adf_accel_dev *ptr =
+ list_entry(itr, struct adf_accel_dev, list);
+
+ if (ptr == accel_dev) {
+ mutex_unlock(&table_lock);
+ return -EEXIST;
+ }
+ }
+ atomic_set(&accel_dev->ref_count, 0);
+ list_add_tail(&accel_dev->list, &accel_table);
+ accel_dev->accel_id = num_devices++;
+ mutex_unlock(&table_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_devmgr_add_dev);
+
+struct list_head *adf_devmgr_get_head(void)
+{
+ return &accel_table;
+}
+
+/**
+ * adf_devmgr_rm_dev() - Remove accel_dev from the acceleration framework.
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function removes acceleration device from the acceleration framework.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: void
+ */
+void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev)
+{
+ mutex_lock(&table_lock);
+ list_del(&accel_dev->list);
+ num_devices--;
+ mutex_unlock(&table_lock);
+}
+EXPORT_SYMBOL_GPL(adf_devmgr_rm_dev);
+
+struct adf_accel_dev *adf_devmgr_get_first(void)
+{
+ struct adf_accel_dev *dev = NULL;
+
+ if (!list_empty(&accel_table))
+ dev = list_first_entry(&accel_table, struct adf_accel_dev,
+ list);
+ return dev;
+}
+
+/**
+ * adf_devmgr_pci_to_accel_dev() - Get accel_dev associated with the pci_dev.
+ * @accel_dev: Pointer to pci device.
+ *
+ * Function returns acceleration device associated with the given pci device.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: pinter to accel_dev or NULL if not found.
+ */
+struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev)
+{
+ struct list_head *itr;
+
+ list_for_each(itr, &accel_table) {
+ struct adf_accel_dev *ptr =
+ list_entry(itr, struct adf_accel_dev, list);
+
+ if (ptr->accel_pci_dev.pci_dev == pci_dev) {
+ mutex_unlock(&table_lock);
+ return ptr;
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(adf_devmgr_pci_to_accel_dev);
+
+struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id)
+{
+ struct list_head *itr;
+
+ list_for_each(itr, &accel_table) {
+ struct adf_accel_dev *ptr =
+ list_entry(itr, struct adf_accel_dev, list);
+
+ if (ptr->accel_id == id) {
+ mutex_unlock(&table_lock);
+ return ptr;
+ }
+ }
+ return NULL;
+}
+
+int adf_devmgr_verify_id(uint32_t id)
+{
+ if (id == ADF_CFG_ALL_DEVICES)
+ return 0;
+
+ if (adf_devmgr_get_dev_by_id(id))
+ return 0;
+
+ return -ENODEV;
+}
+
+void adf_devmgr_get_num_dev(uint32_t *num)
+{
+ struct list_head *itr;
+
+ *num = 0;
+ list_for_each(itr, &accel_table) {
+ (*num)++;
+ }
+}
+
+int adf_dev_in_use(struct adf_accel_dev *accel_dev)
+{
+ return atomic_read(&accel_dev->ref_count) != 0;
+}
+
+int adf_dev_get(struct adf_accel_dev *accel_dev)
+{
+ if (atomic_add_return(1, &accel_dev->ref_count) == 1)
+ if (!try_module_get(accel_dev->owner))
+ return -EFAULT;
+ return 0;
+}
+
+void adf_dev_put(struct adf_accel_dev *accel_dev)
+{
+ if (atomic_sub_return(1, &accel_dev->ref_count) == 0)
+ module_put(accel_dev->owner);
+}
+
+int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev)
+{
+ return test_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+}
+
+int adf_dev_started(struct adf_accel_dev *accel_dev)
+{
+ return test_bit(ADF_STATUS_STARTED, &accel_dev->status);
+}
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
new file mode 100644
index 000000000000..5c0e47a00a87
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -0,0 +1,388 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include "adf_accel_devices.h"
+#include "adf_cfg.h"
+#include "adf_common_drv.h"
+
+static LIST_HEAD(service_table);
+static DEFINE_MUTEX(service_lock);
+
+static void adf_service_add(struct service_hndl *service)
+{
+ mutex_lock(&service_lock);
+ list_add(&service->list, &service_table);
+ mutex_unlock(&service_lock);
+}
+
+/**
+ * adf_service_register() - Register acceleration service in the accel framework
+ * @service: Pointer to the service
+ *
+ * Function adds the acceleration service to the acceleration framework.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_service_register(struct service_hndl *service)
+{
+ service->init_status = 0;
+ service->start_status = 0;
+ adf_service_add(service);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_service_register);
+
+static void adf_service_remove(struct service_hndl *service)
+{
+ mutex_lock(&service_lock);
+ list_del(&service->list);
+ mutex_unlock(&service_lock);
+}
+
+/**
+ * adf_service_unregister() - Unregister acceleration service from the framework
+ * @service: Pointer to the service
+ *
+ * Function remove the acceleration service from the acceleration framework.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_service_unregister(struct service_hndl *service)
+{
+ if (service->init_status || service->start_status) {
+ pr_err("QAT: Could not remove active service\n");
+ return -EFAULT;
+ }
+ adf_service_remove(service);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_service_unregister);
+
+/**
+ * adf_dev_start() - Start acceleration service for the given accel device
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function notifies all the registered services that the acceleration device
+ * is ready to be used.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_dev_start(struct adf_accel_dev *accel_dev)
+{
+ struct service_hndl *service;
+ struct list_head *list_itr;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+
+ if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
+ pr_info("QAT: Device not configured\n");
+ return -EFAULT;
+ }
+ set_bit(ADF_STATUS_STARTING, &accel_dev->status);
+
+ if (adf_ae_init(accel_dev)) {
+ pr_err("QAT: Failed to initialise Acceleration Engine\n");
+ return -EFAULT;
+ }
+ set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
+
+ if (adf_ae_fw_load(accel_dev)) {
+ pr_err("QAT: Failed to load acceleration FW\n");
+ adf_ae_fw_release(accel_dev);
+ return -EFAULT;
+ }
+ set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
+
+ if (hw_data->alloc_irq(accel_dev)) {
+ pr_err("QAT: Failed to allocate interrupts\n");
+ return -EFAULT;
+ }
+ set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
+
+ /*
+ * Subservice initialisation is divided into two stages: init and start.
+ * This is to facilitate any ordering dependencies between services
+ * prior to starting any of the accelerators.
+ */
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
+ pr_err("QAT: Failed to initialise service %s\n",
+ service->name);
+ return -EFAULT;
+ }
+ set_bit(accel_dev->accel_id, &service->init_status);
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
+ pr_err("QAT: Failed to initialise service %s\n",
+ service->name);
+ return -EFAULT;
+ }
+ set_bit(accel_dev->accel_id, &service->init_status);
+ }
+
+ hw_data->enable_error_correction(accel_dev);
+
+ if (adf_ae_start(accel_dev)) {
+ pr_err("QAT: AE Start Failed\n");
+ return -EFAULT;
+ }
+ set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
+
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_START)) {
+ pr_err("QAT: Failed to start service %s\n",
+ service->name);
+ return -EFAULT;
+ }
+ set_bit(accel_dev->accel_id, &service->start_status);
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_START)) {
+ pr_err("QAT: Failed to start service %s\n",
+ service->name);
+ return -EFAULT;
+ }
+ set_bit(accel_dev->accel_id, &service->start_status);
+ }
+
+ clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
+ set_bit(ADF_STATUS_STARTED, &accel_dev->status);
+
+ if (qat_algs_register()) {
+ pr_err("QAT: Failed to register crypto algs\n");
+ set_bit(ADF_STATUS_STARTING, &accel_dev->status);
+ clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
+ return -EFAULT;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_dev_start);
+
+/**
+ * adf_dev_stop() - Stop acceleration service for the given accel device
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function notifies all the registered services that the acceleration device
+ * is shuting down.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_dev_stop(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct service_hndl *service;
+ struct list_head *list_itr;
+ int ret, wait = 0;
+
+ if (!adf_dev_started(accel_dev) &&
+ !test_bit(ADF_STATUS_STARTING, &accel_dev->status)) {
+ return 0;
+ }
+ clear_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
+ clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
+ clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
+
+ if (qat_algs_unregister())
+ pr_err("QAT: Failed to unregister crypto algs\n");
+
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (!test_bit(accel_dev->accel_id, &service->start_status))
+ continue;
+ ret = service->event_hld(accel_dev, ADF_EVENT_STOP);
+ if (!ret) {
+ clear_bit(accel_dev->accel_id, &service->start_status);
+ } else if (ret == -EAGAIN) {
+ wait = 1;
+ clear_bit(accel_dev->accel_id, &service->start_status);
+ }
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (!test_bit(accel_dev->accel_id, &service->start_status))
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_STOP))
+ pr_err("QAT: Failed to shutdown service %s\n",
+ service->name);
+ else
+ clear_bit(accel_dev->accel_id, &service->start_status);
+ }
+
+ if (wait)
+ msleep(100);
+
+ if (adf_dev_started(accel_dev)) {
+ if (adf_ae_stop(accel_dev))
+ pr_err("QAT: failed to stop AE\n");
+ else
+ clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
+ }
+
+ if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
+ if (adf_ae_fw_release(accel_dev))
+ pr_err("QAT: Failed to release the ucode\n");
+ else
+ clear_bit(ADF_STATUS_AE_UCODE_LOADED,
+ &accel_dev->status);
+ }
+
+ if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
+ if (adf_ae_shutdown(accel_dev))
+ pr_err("QAT: Failed to shutdown Accel Engine\n");
+ else
+ clear_bit(ADF_STATUS_AE_INITIALISED,
+ &accel_dev->status);
+ }
+
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (!test_bit(accel_dev->accel_id, &service->init_status))
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
+ pr_err("QAT: Failed to shutdown service %s\n",
+ service->name);
+ else
+ clear_bit(accel_dev->accel_id, &service->init_status);
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (!test_bit(accel_dev->accel_id, &service->init_status))
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
+ pr_err("QAT: Failed to shutdown service %s\n",
+ service->name);
+ else
+ clear_bit(accel_dev->accel_id, &service->init_status);
+ }
+
+ if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
+ hw_data->free_irq(accel_dev);
+ clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
+ }
+
+ /* Delete configuration only if not restarting */
+ if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
+ adf_cfg_del_all(accel_dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(adf_dev_stop);
+
+int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
+{
+ struct service_hndl *service;
+ struct list_head *list_itr;
+
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
+ pr_err("QAT: Failed to restart service %s.\n",
+ service->name);
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
+ pr_err("QAT: Failed to restart service %s.\n",
+ service->name);
+ }
+ return 0;
+}
+
+int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
+{
+ struct service_hndl *service;
+ struct list_head *list_itr;
+
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
+ pr_err("QAT: Failed to restart service %s.\n",
+ service->name);
+ }
+ list_for_each(list_itr, &service_table) {
+ service = list_entry(list_itr, struct service_hndl, list);
+ if (!service->admin)
+ continue;
+ if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
+ pr_err("QAT: Failed to restart service %s.\n",
+ service->name);
+ }
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_transport.c b/drivers/crypto/qat/qat_common/adf_transport.c
new file mode 100644
index 000000000000..5f3fa45348b4
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_transport.c
@@ -0,0 +1,567 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/delay.h>
+#include "adf_accel_devices.h"
+#include "adf_transport_internal.h"
+#include "adf_transport_access_macros.h"
+#include "adf_cfg.h"
+#include "adf_common_drv.h"
+
+static inline uint32_t adf_modulo(uint32_t data, uint32_t shift)
+{
+ uint32_t div = data >> shift;
+ uint32_t mult = div << shift;
+
+ return data - mult;
+}
+
+static inline int adf_check_ring_alignment(uint64_t addr, uint64_t size)
+{
+ if (((size - 1) & addr) != 0)
+ return -EFAULT;
+ return 0;
+}
+
+static int adf_verify_ring_size(uint32_t msg_size, uint32_t msg_num)
+{
+ int i = ADF_MIN_RING_SIZE;
+
+ for (; i <= ADF_MAX_RING_SIZE; i++)
+ if ((msg_size * msg_num) == ADF_SIZE_TO_RING_SIZE_IN_BYTES(i))
+ return i;
+
+ return ADF_DEFAULT_RING_SIZE;
+}
+
+static int adf_reserve_ring(struct adf_etr_bank_data *bank, uint32_t ring)
+{
+ spin_lock(&bank->lock);
+ if (bank->ring_mask & (1 << ring)) {
+ spin_unlock(&bank->lock);
+ return -EFAULT;
+ }
+ bank->ring_mask |= (1 << ring);
+ spin_unlock(&bank->lock);
+ return 0;
+}
+
+static void adf_unreserve_ring(struct adf_etr_bank_data *bank, uint32_t ring)
+{
+ spin_lock(&bank->lock);
+ bank->ring_mask &= ~(1 << ring);
+ spin_unlock(&bank->lock);
+}
+
+static void adf_enable_ring_irq(struct adf_etr_bank_data *bank, uint32_t ring)
+{
+ spin_lock_bh(&bank->lock);
+ bank->irq_mask |= (1 << ring);
+ spin_unlock_bh(&bank->lock);
+ WRITE_CSR_INT_COL_EN(bank->csr_addr, bank->bank_number, bank->irq_mask);
+ WRITE_CSR_INT_COL_CTL(bank->csr_addr, bank->bank_number,
+ bank->irq_coalesc_timer);
+}
+
+static void adf_disable_ring_irq(struct adf_etr_bank_data *bank, uint32_t ring)
+{
+ spin_lock_bh(&bank->lock);
+ bank->irq_mask &= ~(1 << ring);
+ spin_unlock_bh(&bank->lock);
+ WRITE_CSR_INT_COL_EN(bank->csr_addr, bank->bank_number, bank->irq_mask);
+}
+
+int adf_send_message(struct adf_etr_ring_data *ring, uint32_t *msg)
+{
+ if (atomic_add_return(1, ring->inflights) >
+ ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size)) {
+ atomic_dec(ring->inflights);
+ return -EAGAIN;
+ }
+ spin_lock_bh(&ring->lock);
+ memcpy(ring->base_addr + ring->tail, msg,
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size));
+
+ ring->tail = adf_modulo(ring->tail +
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size),
+ ADF_RING_SIZE_MODULO(ring->ring_size));
+ WRITE_CSR_RING_TAIL(ring->bank->csr_addr, ring->bank->bank_number,
+ ring->ring_number, ring->tail);
+ spin_unlock_bh(&ring->lock);
+ return 0;
+}
+
+static int adf_handle_response(struct adf_etr_ring_data *ring)
+{
+ uint32_t msg_counter = 0;
+ uint32_t *msg = (uint32_t *)(ring->base_addr + ring->head);
+
+ while (*msg != ADF_RING_EMPTY_SIG) {
+ ring->callback((uint32_t *)msg);
+ *msg = ADF_RING_EMPTY_SIG;
+ ring->head = adf_modulo(ring->head +
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size),
+ ADF_RING_SIZE_MODULO(ring->ring_size));
+ msg_counter++;
+ msg = (uint32_t *)(ring->base_addr + ring->head);
+ }
+ if (msg_counter > 0) {
+ WRITE_CSR_RING_HEAD(ring->bank->csr_addr,
+ ring->bank->bank_number,
+ ring->ring_number, ring->head);
+ atomic_sub(msg_counter, ring->inflights);
+ }
+ return 0;
+}
+
+static void adf_configure_tx_ring(struct adf_etr_ring_data *ring)
+{
+ uint32_t ring_config = BUILD_RING_CONFIG(ring->ring_size);
+
+ WRITE_CSR_RING_CONFIG(ring->bank->csr_addr, ring->bank->bank_number,
+ ring->ring_number, ring_config);
+}
+
+static void adf_configure_rx_ring(struct adf_etr_ring_data *ring)
+{
+ uint32_t ring_config =
+ BUILD_RESP_RING_CONFIG(ring->ring_size,
+ ADF_RING_NEAR_WATERMARK_512,
+ ADF_RING_NEAR_WATERMARK_0);
+
+ WRITE_CSR_RING_CONFIG(ring->bank->csr_addr, ring->bank->bank_number,
+ ring->ring_number, ring_config);
+}
+
+static int adf_init_ring(struct adf_etr_ring_data *ring)
+{
+ struct adf_etr_bank_data *bank = ring->bank;
+ struct adf_accel_dev *accel_dev = bank->accel_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint64_t ring_base;
+ uint32_t ring_size_bytes =
+ ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size);
+
+ ring_size_bytes = ADF_RING_SIZE_BYTES_MIN(ring_size_bytes);
+ ring->base_addr = dma_alloc_coherent(&GET_DEV(accel_dev),
+ ring_size_bytes, &ring->dma_addr,
+ GFP_KERNEL);
+ if (!ring->base_addr)
+ return -ENOMEM;
+
+ memset(ring->base_addr, 0x7F, ring_size_bytes);
+ /* The base_addr has to be aligned to the size of the buffer */
+ if (adf_check_ring_alignment(ring->dma_addr, ring_size_bytes)) {
+ pr_err("QAT: Ring address not aligned\n");
+ dma_free_coherent(&GET_DEV(accel_dev), ring_size_bytes,
+ ring->base_addr, ring->dma_addr);
+ return -EFAULT;
+ }
+
+ if (hw_data->tx_rings_mask & (1 << ring->ring_number))
+ adf_configure_tx_ring(ring);
+
+ else
+ adf_configure_rx_ring(ring);
+
+ ring_base = BUILD_RING_BASE_ADDR(ring->dma_addr, ring->ring_size);
+ WRITE_CSR_RING_BASE(ring->bank->csr_addr, ring->bank->bank_number,
+ ring->ring_number, ring_base);
+ spin_lock_init(&ring->lock);
+ return 0;
+}
+
+static void adf_cleanup_ring(struct adf_etr_ring_data *ring)
+{
+ uint32_t ring_size_bytes =
+ ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size);
+ ring_size_bytes = ADF_RING_SIZE_BYTES_MIN(ring_size_bytes);
+
+ if (ring->base_addr) {
+ memset(ring->base_addr, 0x7F, ring_size_bytes);
+ dma_free_coherent(&GET_DEV(ring->bank->accel_dev),
+ ring_size_bytes, ring->base_addr,
+ ring->dma_addr);
+ }
+}
+
+int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
+ uint32_t bank_num, uint32_t num_msgs,
+ uint32_t msg_size, const char *ring_name,
+ adf_callback_fn callback, int poll_mode,
+ struct adf_etr_ring_data **ring_ptr)
+{
+ struct adf_etr_data *transport_data = accel_dev->transport;
+ struct adf_etr_bank_data *bank;
+ struct adf_etr_ring_data *ring;
+ char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+ uint32_t ring_num;
+ int ret;
+
+ if (bank_num >= GET_MAX_BANKS(accel_dev)) {
+ pr_err("QAT: Invalid bank number\n");
+ return -EFAULT;
+ }
+ if (msg_size > ADF_MSG_SIZE_TO_BYTES(ADF_MAX_MSG_SIZE)) {
+ pr_err("QAT: Invalid msg size\n");
+ return -EFAULT;
+ }
+ if (ADF_MAX_INFLIGHTS(adf_verify_ring_size(msg_size, num_msgs),
+ ADF_BYTES_TO_MSG_SIZE(msg_size)) < 2) {
+ pr_err("QAT: Invalid ring size for given msg size\n");
+ return -EFAULT;
+ }
+ if (adf_cfg_get_param_value(accel_dev, section, ring_name, val)) {
+ pr_err("QAT: Section %s, no such entry : %s\n",
+ section, ring_name);
+ return -EFAULT;
+ }
+ if (kstrtouint(val, 10, &ring_num)) {
+ pr_err("QAT: Can't get ring number\n");
+ return -EFAULT;
+ }
+
+ bank = &transport_data->banks[bank_num];
+ if (adf_reserve_ring(bank, ring_num)) {
+ pr_err("QAT: Ring %d, %s already exists.\n",
+ ring_num, ring_name);
+ return -EFAULT;
+ }
+ ring = &bank->rings[ring_num];
+ ring->ring_number = ring_num;
+ ring->bank = bank;
+ ring->callback = callback;
+ ring->msg_size = ADF_BYTES_TO_MSG_SIZE(msg_size);
+ ring->ring_size = adf_verify_ring_size(msg_size, num_msgs);
+ ring->head = 0;
+ ring->tail = 0;
+ atomic_set(ring->inflights, 0);
+ ret = adf_init_ring(ring);
+ if (ret)
+ goto err;
+
+ /* Enable HW arbitration for the given ring */
+ accel_dev->hw_device->hw_arb_ring_enable(ring);
+
+ if (adf_ring_debugfs_add(ring, ring_name)) {
+ pr_err("QAT: Couldn't add ring debugfs entry\n");
+ ret = -EFAULT;
+ goto err;
+ }
+
+ /* Enable interrupts if needed */
+ if (callback && (!poll_mode))
+ adf_enable_ring_irq(bank, ring->ring_number);
+ *ring_ptr = ring;
+ return 0;
+err:
+ adf_cleanup_ring(ring);
+ adf_unreserve_ring(bank, ring_num);
+ accel_dev->hw_device->hw_arb_ring_disable(ring);
+ return ret;
+}
+
+void adf_remove_ring(struct adf_etr_ring_data *ring)
+{
+ struct adf_etr_bank_data *bank = ring->bank;
+ struct adf_accel_dev *accel_dev = bank->accel_dev;
+
+ /* Disable interrupts for the given ring */
+ adf_disable_ring_irq(bank, ring->ring_number);
+
+ /* Clear PCI config space */
+ WRITE_CSR_RING_CONFIG(bank->csr_addr, bank->bank_number,
+ ring->ring_number, 0);
+ WRITE_CSR_RING_BASE(bank->csr_addr, bank->bank_number,
+ ring->ring_number, 0);
+ adf_ring_debugfs_rm(ring);
+ adf_unreserve_ring(bank, ring->ring_number);
+ /* Disable HW arbitration for the given ring */
+ accel_dev->hw_device->hw_arb_ring_disable(ring);
+ adf_cleanup_ring(ring);
+}
+
+static void adf_ring_response_handler(struct adf_etr_bank_data *bank)
+{
+ uint32_t empty_rings, i;
+
+ empty_rings = READ_CSR_E_STAT(bank->csr_addr, bank->bank_number);
+ empty_rings = ~empty_rings & bank->irq_mask;
+
+ for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; ++i) {
+ if (empty_rings & (1 << i))
+ adf_handle_response(&bank->rings[i]);
+ }
+}
+
+/**
+ * adf_response_handler() - Bottom half handler response handler
+ * @bank_addr: Address of a ring bank for with the BH was scheduled.
+ *
+ * Function is the bottom half handler for the response from acceleration
+ * device. There is one handler for every ring bank. Function checks all
+ * communication rings in the bank.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: void
+ */
+void adf_response_handler(unsigned long bank_addr)
+{
+ struct adf_etr_bank_data *bank = (void *)bank_addr;
+
+ /* Handle all the responses nad reenable IRQs */
+ adf_ring_response_handler(bank);
+ WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, bank->bank_number,
+ bank->irq_mask);
+}
+EXPORT_SYMBOL_GPL(adf_response_handler);
+
+static inline int adf_get_cfg_int(struct adf_accel_dev *accel_dev,
+ const char *section, const char *format,
+ uint32_t key, uint32_t *value)
+{
+ char key_buf[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ char val_buf[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+
+ snprintf(key_buf, ADF_CFG_MAX_KEY_LEN_IN_BYTES, format, key);
+
+ if (adf_cfg_get_param_value(accel_dev, section, key_buf, val_buf))
+ return -EFAULT;
+
+ if (kstrtouint(val_buf, 10, value))
+ return -EFAULT;
+ return 0;
+}
+
+static void adf_enable_coalesc(struct adf_etr_bank_data *bank,
+ const char *section, uint32_t bank_num_in_accel)
+{
+ if (adf_get_cfg_int(bank->accel_dev, section,
+ ADF_ETRMGR_COALESCE_TIMER_FORMAT,
+ bank_num_in_accel, &bank->irq_coalesc_timer))
+ bank->irq_coalesc_timer = ADF_COALESCING_DEF_TIME;
+
+ if (ADF_COALESCING_MAX_TIME < bank->irq_coalesc_timer ||
+ ADF_COALESCING_MIN_TIME > bank->irq_coalesc_timer)
+ bank->irq_coalesc_timer = ADF_COALESCING_DEF_TIME;
+}
+
+static int adf_init_bank(struct adf_accel_dev *accel_dev,
+ struct adf_etr_bank_data *bank,
+ uint32_t bank_num, void __iomem *csr_addr)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct adf_etr_ring_data *ring;
+ struct adf_etr_ring_data *tx_ring;
+ uint32_t i, coalesc_enabled;
+
+ memset(bank, 0, sizeof(*bank));
+ bank->bank_number = bank_num;
+ bank->csr_addr = csr_addr;
+ bank->accel_dev = accel_dev;
+ spin_lock_init(&bank->lock);
+
+ /* Enable IRQ coalescing always. This will allow to use
+ * the optimised flag and coalesc register.
+ * If it is disabled in the config file just use min time value */
+ if (adf_get_cfg_int(accel_dev, "Accelerator0",
+ ADF_ETRMGR_COALESCING_ENABLED_FORMAT,
+ bank_num, &coalesc_enabled) && coalesc_enabled)
+ adf_enable_coalesc(bank, "Accelerator0", bank_num);
+ else
+ bank->irq_coalesc_timer = ADF_COALESCING_MIN_TIME;
+
+ for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
+ WRITE_CSR_RING_CONFIG(csr_addr, bank_num, i, 0);
+ WRITE_CSR_RING_BASE(csr_addr, bank_num, i, 0);
+ ring = &bank->rings[i];
+ if (hw_data->tx_rings_mask & (1 << i)) {
+ ring->inflights = kzalloc_node(sizeof(atomic_t),
+ GFP_KERNEL,
+ accel_dev->numa_node);
+ if (!ring->inflights)
+ goto err;
+ } else {
+ if (i < hw_data->tx_rx_gap) {
+ pr_err("QAT: Invalid tx rings mask config\n");
+ goto err;
+ }
+ tx_ring = &bank->rings[i - hw_data->tx_rx_gap];
+ ring->inflights = tx_ring->inflights;
+ }
+ }
+ if (adf_bank_debugfs_add(bank)) {
+ pr_err("QAT: Failed to add bank debugfs entry\n");
+ goto err;
+ }
+
+ WRITE_CSR_INT_SRCSEL(csr_addr, bank_num);
+ return 0;
+err:
+ for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
+ ring = &bank->rings[i];
+ if (hw_data->tx_rings_mask & (1 << i) && ring->inflights)
+ kfree(ring->inflights);
+ }
+ return -ENOMEM;
+}
+
+/**
+ * adf_init_etr_data() - Initialize transport rings for acceleration device
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function is the initializes the communications channels (rings) to the
+ * acceleration device accel_dev.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: 0 on success, error code othewise.
+ */
+int adf_init_etr_data(struct adf_accel_dev *accel_dev)
+{
+ struct adf_etr_data *etr_data;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ void __iomem *csr_addr;
+ uint32_t size;
+ uint32_t num_banks = 0;
+ int i, ret;
+
+ etr_data = kzalloc_node(sizeof(*etr_data), GFP_KERNEL,
+ accel_dev->numa_node);
+ if (!etr_data)
+ return -ENOMEM;
+
+ num_banks = GET_MAX_BANKS(accel_dev);
+ size = num_banks * sizeof(struct adf_etr_bank_data);
+ etr_data->banks = kzalloc_node(size, GFP_KERNEL, accel_dev->numa_node);
+ if (!etr_data->banks) {
+ ret = -ENOMEM;
+ goto err_bank;
+ }
+
+ accel_dev->transport = etr_data;
+ i = hw_data->get_etr_bar_id(hw_data);
+ csr_addr = accel_dev->accel_pci_dev.pci_bars[i].virt_addr;
+
+ /* accel_dev->debugfs_dir should always be non-NULL here */
+ etr_data->debug = debugfs_create_dir("transport",
+ accel_dev->debugfs_dir);
+ if (!etr_data->debug) {
+ pr_err("QAT: Unable to create transport debugfs entry\n");
+ ret = -ENOENT;
+ goto err_bank_debug;
+ }
+
+ for (i = 0; i < num_banks; i++) {
+ ret = adf_init_bank(accel_dev, &etr_data->banks[i], i,
+ csr_addr);
+ if (ret)
+ goto err_bank_all;
+ }
+
+ return 0;
+
+err_bank_all:
+ debugfs_remove(etr_data->debug);
+err_bank_debug:
+ kfree(etr_data->banks);
+err_bank:
+ kfree(etr_data);
+ accel_dev->transport = NULL;
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adf_init_etr_data);
+
+static void cleanup_bank(struct adf_etr_bank_data *bank)
+{
+ uint32_t i;
+
+ for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
+ struct adf_accel_dev *accel_dev = bank->accel_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct adf_etr_ring_data *ring = &bank->rings[i];
+
+ if (bank->ring_mask & (1 << i))
+ adf_cleanup_ring(ring);
+
+ if (hw_data->tx_rings_mask & (1 << i))
+ kfree(ring->inflights);
+ }
+ adf_bank_debugfs_rm(bank);
+ memset(bank, 0, sizeof(*bank));
+}
+
+static void adf_cleanup_etr_handles(struct adf_accel_dev *accel_dev)
+{
+ struct adf_etr_data *etr_data = accel_dev->transport;
+ uint32_t i, num_banks = GET_MAX_BANKS(accel_dev);
+
+ for (i = 0; i < num_banks; i++)
+ cleanup_bank(&etr_data->banks[i]);
+}
+
+/**
+ * adf_cleanup_etr_data() - Clear transport rings for acceleration device
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function is the clears the communications channels (rings) of the
+ * acceleration device accel_dev.
+ * To be used by QAT device specific drivers.
+ *
+ * Return: void
+ */
+void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev)
+{
+ struct adf_etr_data *etr_data = accel_dev->transport;
+
+ if (etr_data) {
+ adf_cleanup_etr_handles(accel_dev);
+ debugfs_remove(etr_data->debug);
+ kfree(etr_data->banks);
+ kfree(etr_data);
+ accel_dev->transport = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(adf_cleanup_etr_data);
diff --git a/drivers/crypto/qat/qat_common/adf_transport.h b/drivers/crypto/qat/qat_common/adf_transport.h
new file mode 100644
index 000000000000..386485bd9c95
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_transport.h
@@ -0,0 +1,63 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_TRANSPORT_H
+#define ADF_TRANSPORT_H
+
+#include "adf_accel_devices.h"
+
+struct adf_etr_ring_data;
+
+typedef void (*adf_callback_fn)(void *resp_msg);
+
+int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
+ uint32_t bank_num, uint32_t num_mgs, uint32_t msg_size,
+ const char *ring_name, adf_callback_fn callback,
+ int poll_mode, struct adf_etr_ring_data **ring_ptr);
+
+int adf_send_message(struct adf_etr_ring_data *ring, uint32_t *msg);
+void adf_remove_ring(struct adf_etr_ring_data *ring);
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_transport_access_macros.h b/drivers/crypto/qat/qat_common/adf_transport_access_macros.h
new file mode 100644
index 000000000000..91d88d676580
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_transport_access_macros.h
@@ -0,0 +1,160 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_TRANSPORT_ACCESS_MACROS_H
+#define ADF_TRANSPORT_ACCESS_MACROS_H
+
+#include "adf_accel_devices.h"
+#define ADF_BANK_INT_SRC_SEL_MASK_0 0x4444444CUL
+#define ADF_BANK_INT_SRC_SEL_MASK_X 0x44444444UL
+#define ADF_RING_CSR_RING_CONFIG 0x000
+#define ADF_RING_CSR_RING_LBASE 0x040
+#define ADF_RING_CSR_RING_UBASE 0x080
+#define ADF_RING_CSR_RING_HEAD 0x0C0
+#define ADF_RING_CSR_RING_TAIL 0x100
+#define ADF_RING_CSR_E_STAT 0x14C
+#define ADF_RING_CSR_INT_SRCSEL 0x174
+#define ADF_RING_CSR_INT_SRCSEL_2 0x178
+#define ADF_RING_CSR_INT_COL_EN 0x17C
+#define ADF_RING_CSR_INT_COL_CTL 0x180
+#define ADF_RING_CSR_INT_FLAG_AND_COL 0x184
+#define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000
+#define ADF_RING_BUNDLE_SIZE 0x1000
+#define ADF_RING_CONFIG_NEAR_FULL_WM 0x0A
+#define ADF_RING_CONFIG_NEAR_EMPTY_WM 0x05
+#define ADF_COALESCING_MIN_TIME 0x1FF
+#define ADF_COALESCING_MAX_TIME 0xFFFFF
+#define ADF_COALESCING_DEF_TIME 0x27FF
+#define ADF_RING_NEAR_WATERMARK_512 0x08
+#define ADF_RING_NEAR_WATERMARK_0 0x00
+#define ADF_RING_EMPTY_SIG 0x7F7F7F7F
+
+/* Valid internal ring size values */
+#define ADF_RING_SIZE_128 0x01
+#define ADF_RING_SIZE_256 0x02
+#define ADF_RING_SIZE_512 0x03
+#define ADF_RING_SIZE_4K 0x06
+#define ADF_RING_SIZE_16K 0x08
+#define ADF_RING_SIZE_4M 0x10
+#define ADF_MIN_RING_SIZE ADF_RING_SIZE_128
+#define ADF_MAX_RING_SIZE ADF_RING_SIZE_4M
+#define ADF_DEFAULT_RING_SIZE ADF_RING_SIZE_16K
+
+/* Valid internal msg size values internal */
+#define ADF_MSG_SIZE_32 0x01
+#define ADF_MSG_SIZE_64 0x02
+#define ADF_MSG_SIZE_128 0x04
+#define ADF_MIN_MSG_SIZE ADF_MSG_SIZE_32
+#define ADF_MAX_MSG_SIZE ADF_MSG_SIZE_128
+
+/* Size to bytes conversion macros for ring and msg values */
+#define ADF_MSG_SIZE_TO_BYTES(SIZE) (SIZE << 5)
+#define ADF_BYTES_TO_MSG_SIZE(SIZE) (SIZE >> 5)
+#define ADF_SIZE_TO_RING_SIZE_IN_BYTES(SIZE) ((1 << (SIZE - 1)) << 7)
+#define ADF_RING_SIZE_IN_BYTES_TO_SIZE(SIZE) ((1 << (SIZE - 1)) >> 7)
+
+/* Minimum ring bufer size for memory allocation */
+#define ADF_RING_SIZE_BYTES_MIN(SIZE) ((SIZE < ADF_RING_SIZE_4K) ? \
+ ADF_RING_SIZE_4K : SIZE)
+#define ADF_RING_SIZE_MODULO(SIZE) (SIZE + 0x6)
+#define ADF_MAX_INFLIGHTS(RING_SIZE, MSG_SIZE) \
+ ((((1 << (RING_SIZE - 1)) << 4) >> MSG_SIZE) - 1)
+#define BUILD_RING_CONFIG(size) \
+ ((ADF_RING_NEAR_WATERMARK_0 << ADF_RING_CONFIG_NEAR_FULL_WM) \
+ | (ADF_RING_NEAR_WATERMARK_0 << ADF_RING_CONFIG_NEAR_EMPTY_WM) \
+ | size)
+#define BUILD_RESP_RING_CONFIG(size, watermark_nf, watermark_ne) \
+ ((watermark_nf << ADF_RING_CONFIG_NEAR_FULL_WM) \
+ | (watermark_ne << ADF_RING_CONFIG_NEAR_EMPTY_WM) \
+ | size)
+#define BUILD_RING_BASE_ADDR(addr, size) \
+ ((addr >> 6) & (0xFFFFFFFFFFFFFFFFULL << size))
+#define READ_CSR_RING_HEAD(csr_base_addr, bank, ring) \
+ ADF_CSR_RD(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_HEAD + (ring << 2))
+#define READ_CSR_RING_TAIL(csr_base_addr, bank, ring) \
+ ADF_CSR_RD(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_TAIL + (ring << 2))
+#define READ_CSR_E_STAT(csr_base_addr, bank) \
+ ADF_CSR_RD(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_E_STAT)
+#define WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_CONFIG + (ring << 2), value)
+#define WRITE_CSR_RING_BASE(csr_base_addr, bank, ring, value) \
+do { \
+ uint32_t l_base = 0, u_base = 0; \
+ l_base = (uint32_t)(value & 0xFFFFFFFF); \
+ u_base = (uint32_t)((value & 0xFFFFFFFF00000000ULL) >> 32); \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_LBASE + (ring << 2), l_base); \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_UBASE + (ring << 2), u_base); \
+} while (0)
+#define WRITE_CSR_RING_HEAD(csr_base_addr, bank, ring, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_HEAD + (ring << 2), value)
+#define WRITE_CSR_RING_TAIL(csr_base_addr, bank, ring, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_RING_TAIL + (ring << 2), value)
+#define WRITE_CSR_INT_SRCSEL(csr_base_addr, bank) \
+do { \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_INT_SRCSEL, ADF_BANK_INT_SRC_SEL_MASK_0); \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_INT_SRCSEL_2, ADF_BANK_INT_SRC_SEL_MASK_X); \
+} while (0)
+#define WRITE_CSR_INT_COL_EN(csr_base_addr, bank, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_INT_COL_EN, value)
+#define WRITE_CSR_INT_COL_CTL(csr_base_addr, bank, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_INT_COL_CTL, \
+ ADF_RING_CSR_INT_COL_CTL_ENABLE | value)
+#define WRITE_CSR_INT_FLAG_AND_COL(csr_base_addr, bank, value) \
+ ADF_CSR_WR(csr_base_addr, (ADF_RING_BUNDLE_SIZE * bank) + \
+ ADF_RING_CSR_INT_FLAG_AND_COL, value)
+#endif
diff --git a/drivers/crypto/qat/qat_common/adf_transport_debug.c b/drivers/crypto/qat/qat_common/adf_transport_debug.c
new file mode 100644
index 000000000000..6b6974553514
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_transport_debug.c
@@ -0,0 +1,304 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include "adf_accel_devices.h"
+#include "adf_transport_internal.h"
+#include "adf_transport_access_macros.h"
+
+static DEFINE_MUTEX(ring_read_lock);
+static DEFINE_MUTEX(bank_read_lock);
+
+static void *adf_ring_start(struct seq_file *sfile, loff_t *pos)
+{
+ struct adf_etr_ring_data *ring = sfile->private;
+
+ mutex_lock(&ring_read_lock);
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+ if (*pos >= (ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size) /
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size)))
+ return NULL;
+
+ return ring->base_addr +
+ (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) * (*pos)++);
+}
+
+static void *adf_ring_next(struct seq_file *sfile, void *v, loff_t *pos)
+{
+ struct adf_etr_ring_data *ring = sfile->private;
+
+ if (*pos >= (ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size) /
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size)))
+ return NULL;
+
+ return ring->base_addr +
+ (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) * (*pos)++);
+}
+
+static int adf_ring_show(struct seq_file *sfile, void *v)
+{
+ struct adf_etr_ring_data *ring = sfile->private;
+ struct adf_etr_bank_data *bank = ring->bank;
+ uint32_t *msg = v;
+ void __iomem *csr = ring->bank->csr_addr;
+ int i, x;
+
+ if (v == SEQ_START_TOKEN) {
+ int head, tail, empty;
+
+ head = READ_CSR_RING_HEAD(csr, bank->bank_number,
+ ring->ring_number);
+ tail = READ_CSR_RING_TAIL(csr, bank->bank_number,
+ ring->ring_number);
+ empty = READ_CSR_E_STAT(csr, bank->bank_number);
+
+ seq_puts(sfile, "------- Ring configuration -------\n");
+ seq_printf(sfile, "ring num %d, bank num %d\n",
+ ring->ring_number, ring->bank->bank_number);
+ seq_printf(sfile, "head %x, tail %x, empty: %d\n",
+ head, tail, (empty & 1 << ring->ring_number)
+ >> ring->ring_number);
+ seq_printf(sfile, "ring size %d, msg size %d\n",
+ ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size),
+ ADF_MSG_SIZE_TO_BYTES(ring->msg_size));
+ seq_puts(sfile, "----------- Ring data ------------\n");
+ return 0;
+ }
+ seq_printf(sfile, "%p:", msg);
+ x = 0;
+ i = 0;
+ for (; i < (ADF_MSG_SIZE_TO_BYTES(ring->msg_size) >> 2); i++) {
+ seq_printf(sfile, " %08X", *(msg + i));
+ if ((ADF_MSG_SIZE_TO_BYTES(ring->msg_size) >> 2) != i + 1 &&
+ (++x == 8)) {
+ seq_printf(sfile, "\n%p:", msg + i + 1);
+ x = 0;
+ }
+ }
+ seq_puts(sfile, "\n");
+ return 0;
+}
+
+static void adf_ring_stop(struct seq_file *sfile, void *v)
+{
+ mutex_unlock(&ring_read_lock);
+}
+
+static const struct seq_operations adf_ring_sops = {
+ .start = adf_ring_start,
+ .next = adf_ring_next,
+ .stop = adf_ring_stop,
+ .show = adf_ring_show
+};
+
+static int adf_ring_open(struct inode *inode, struct file *file)
+{
+ int ret = seq_open(file, &adf_ring_sops);
+
+ if (!ret) {
+ struct seq_file *seq_f = file->private_data;
+
+ seq_f->private = inode->i_private;
+ }
+ return ret;
+}
+
+static const struct file_operations adf_ring_debug_fops = {
+ .open = adf_ring_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name)
+{
+ struct adf_etr_ring_debug_entry *ring_debug;
+ char entry_name[8];
+
+ ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL);
+ if (!ring_debug)
+ return -ENOMEM;
+
+ strlcpy(ring_debug->ring_name, name, sizeof(ring_debug->ring_name));
+ snprintf(entry_name, sizeof(entry_name), "ring_%02d",
+ ring->ring_number);
+
+ ring_debug->debug = debugfs_create_file(entry_name, S_IRUSR,
+ ring->bank->bank_debug_dir,
+ ring, &adf_ring_debug_fops);
+ if (!ring_debug->debug) {
+ pr_err("QAT: Failed to create ring debug entry.\n");
+ kfree(ring_debug);
+ return -EFAULT;
+ }
+ ring->ring_debug = ring_debug;
+ return 0;
+}
+
+void adf_ring_debugfs_rm(struct adf_etr_ring_data *ring)
+{
+ if (ring->ring_debug) {
+ debugfs_remove(ring->ring_debug->debug);
+ kfree(ring->ring_debug);
+ ring->ring_debug = NULL;
+ }
+}
+
+static void *adf_bank_start(struct seq_file *sfile, loff_t *pos)
+{
+ mutex_lock(&bank_read_lock);
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+ if (*pos >= ADF_ETR_MAX_RINGS_PER_BANK)
+ return NULL;
+
+ return pos;
+}
+
+static void *adf_bank_next(struct seq_file *sfile, void *v, loff_t *pos)
+{
+ if (++(*pos) >= ADF_ETR_MAX_RINGS_PER_BANK)
+ return NULL;
+
+ return pos;
+}
+
+static int adf_bank_show(struct seq_file *sfile, void *v)
+{
+ struct adf_etr_bank_data *bank = sfile->private;
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(sfile, "------- Bank %d configuration -------\n",
+ bank->bank_number);
+ } else {
+ int ring_id = *((int *)v) - 1;
+ struct adf_etr_ring_data *ring = &bank->rings[ring_id];
+ void __iomem *csr = bank->csr_addr;
+ int head, tail, empty;
+
+ if (!(bank->ring_mask & 1 << ring_id))
+ return 0;
+
+ head = READ_CSR_RING_HEAD(csr, bank->bank_number,
+ ring->ring_number);
+ tail = READ_CSR_RING_TAIL(csr, bank->bank_number,
+ ring->ring_number);
+ empty = READ_CSR_E_STAT(csr, bank->bank_number);
+
+ seq_printf(sfile,
+ "ring num %02d, head %04x, tail %04x, empty: %d\n",
+ ring->ring_number, head, tail,
+ (empty & 1 << ring->ring_number) >>
+ ring->ring_number);
+ }
+ return 0;
+}
+
+static void adf_bank_stop(struct seq_file *sfile, void *v)
+{
+ mutex_unlock(&bank_read_lock);
+}
+
+static const struct seq_operations adf_bank_sops = {
+ .start = adf_bank_start,
+ .next = adf_bank_next,
+ .stop = adf_bank_stop,
+ .show = adf_bank_show
+};
+
+static int adf_bank_open(struct inode *inode, struct file *file)
+{
+ int ret = seq_open(file, &adf_bank_sops);
+
+ if (!ret) {
+ struct seq_file *seq_f = file->private_data;
+
+ seq_f->private = inode->i_private;
+ }
+ return ret;
+}
+
+static const struct file_operations adf_bank_debug_fops = {
+ .open = adf_bank_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+int adf_bank_debugfs_add(struct adf_etr_bank_data *bank)
+{
+ struct adf_accel_dev *accel_dev = bank->accel_dev;
+ struct dentry *parent = accel_dev->transport->debug;
+ char name[8];
+
+ snprintf(name, sizeof(name), "bank_%02d", bank->bank_number);
+ bank->bank_debug_dir = debugfs_create_dir(name, parent);
+ if (!bank->bank_debug_dir) {
+ pr_err("QAT: Failed to create bank debug dir.\n");
+ return -EFAULT;
+ }
+
+ bank->bank_debug_cfg = debugfs_create_file("config", S_IRUSR,
+ bank->bank_debug_dir, bank,
+ &adf_bank_debug_fops);
+ if (!bank->bank_debug_cfg) {
+ pr_err("QAT: Failed to create bank debug entry.\n");
+ debugfs_remove(bank->bank_debug_dir);
+ return -EFAULT;
+ }
+ return 0;
+}
+
+void adf_bank_debugfs_rm(struct adf_etr_bank_data *bank)
+{
+ debugfs_remove(bank->bank_debug_cfg);
+ debugfs_remove(bank->bank_debug_dir);
+}
diff --git a/drivers/crypto/qat/qat_common/adf_transport_internal.h b/drivers/crypto/qat/qat_common/adf_transport_internal.h
new file mode 100644
index 000000000000..f854bac276b0
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_transport_internal.h
@@ -0,0 +1,118 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_TRANSPORT_INTRN_H
+#define ADF_TRANSPORT_INTRN_H
+
+#include <linux/interrupt.h>
+#include <linux/atomic.h>
+#include <linux/spinlock_types.h>
+#include "adf_transport.h"
+
+struct adf_etr_ring_debug_entry {
+ char ring_name[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ struct dentry *debug;
+};
+
+struct adf_etr_ring_data {
+ void *base_addr;
+ atomic_t *inflights;
+ spinlock_t lock; /* protects ring data struct */
+ adf_callback_fn callback;
+ struct adf_etr_bank_data *bank;
+ dma_addr_t dma_addr;
+ uint16_t head;
+ uint16_t tail;
+ uint8_t ring_number;
+ uint8_t ring_size;
+ uint8_t msg_size;
+ uint8_t reserved;
+ struct adf_etr_ring_debug_entry *ring_debug;
+} __packed;
+
+struct adf_etr_bank_data {
+ struct adf_etr_ring_data rings[ADF_ETR_MAX_RINGS_PER_BANK];
+ struct tasklet_struct resp_hanlder;
+ void __iomem *csr_addr;
+ struct adf_accel_dev *accel_dev;
+ uint32_t irq_coalesc_timer;
+ uint16_t ring_mask;
+ uint16_t irq_mask;
+ spinlock_t lock; /* protects bank data struct */
+ struct dentry *bank_debug_dir;
+ struct dentry *bank_debug_cfg;
+ uint32_t bank_number;
+} __packed;
+
+struct adf_etr_data {
+ struct adf_etr_bank_data *banks;
+ struct dentry *debug;
+};
+
+void adf_response_handler(unsigned long bank_addr);
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+int adf_bank_debugfs_add(struct adf_etr_bank_data *bank);
+void adf_bank_debugfs_rm(struct adf_etr_bank_data *bank);
+int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name);
+void adf_ring_debugfs_rm(struct adf_etr_ring_data *ring);
+#else
+static inline int adf_bank_debugfs_add(struct adf_etr_bank_data *bank)
+{
+ return 0;
+}
+
+#define adf_bank_debugfs_rm(bank) do {} while (0)
+
+static inline int adf_ring_debugfs_add(struct adf_etr_ring_data *ring,
+ const char *name)
+{
+ return 0;
+}
+
+#define adf_ring_debugfs_rm(ring) do {} while (0)
+#endif
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw.h b/drivers/crypto/qat/qat_common/icp_qat_fw.h
new file mode 100644
index 000000000000..f1e30e24a419
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw.h
@@ -0,0 +1,316 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef _ICP_QAT_FW_H_
+#define _ICP_QAT_FW_H_
+#include <linux/types.h>
+#include "icp_qat_hw.h"
+
+#define QAT_FIELD_SET(flags, val, bitpos, mask) \
+{ (flags) = (((flags) & (~((mask) << (bitpos)))) | \
+ (((val) & (mask)) << (bitpos))) ; }
+
+#define QAT_FIELD_GET(flags, bitpos, mask) \
+ (((flags) >> (bitpos)) & (mask))
+
+#define ICP_QAT_FW_REQ_DEFAULT_SZ 128
+#define ICP_QAT_FW_RESP_DEFAULT_SZ 32
+#define ICP_QAT_FW_COMN_ONE_BYTE_SHIFT 8
+#define ICP_QAT_FW_COMN_SINGLE_BYTE_MASK 0xFF
+#define ICP_QAT_FW_NUM_LONGWORDS_1 1
+#define ICP_QAT_FW_NUM_LONGWORDS_2 2
+#define ICP_QAT_FW_NUM_LONGWORDS_3 3
+#define ICP_QAT_FW_NUM_LONGWORDS_4 4
+#define ICP_QAT_FW_NUM_LONGWORDS_5 5
+#define ICP_QAT_FW_NUM_LONGWORDS_6 6
+#define ICP_QAT_FW_NUM_LONGWORDS_7 7
+#define ICP_QAT_FW_NUM_LONGWORDS_10 10
+#define ICP_QAT_FW_NUM_LONGWORDS_13 13
+#define ICP_QAT_FW_NULL_REQ_SERV_ID 1
+
+enum icp_qat_fw_comn_resp_serv_id {
+ ICP_QAT_FW_COMN_RESP_SERV_NULL,
+ ICP_QAT_FW_COMN_RESP_SERV_CPM_FW,
+ ICP_QAT_FW_COMN_RESP_SERV_DELIMITER
+};
+
+enum icp_qat_fw_comn_request_id {
+ ICP_QAT_FW_COMN_REQ_NULL = 0,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_PKE = 3,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA = 4,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_DMA = 7,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_COMP = 9,
+ ICP_QAT_FW_COMN_REQ_DELIMITER
+};
+
+struct icp_qat_fw_comn_req_hdr_cd_pars {
+ union {
+ struct {
+ uint64_t content_desc_addr;
+ uint16_t content_desc_resrvd1;
+ uint8_t content_desc_params_sz;
+ uint8_t content_desc_hdr_resrvd2;
+ uint32_t content_desc_resrvd3;
+ } s;
+ struct {
+ uint32_t serv_specif_fields[4];
+ } s1;
+ } u;
+};
+
+struct icp_qat_fw_comn_req_mid {
+ uint64_t opaque_data;
+ uint64_t src_data_addr;
+ uint64_t dest_data_addr;
+ uint32_t src_length;
+ uint32_t dst_length;
+};
+
+struct icp_qat_fw_comn_req_cd_ctrl {
+ uint32_t content_desc_ctrl_lw[ICP_QAT_FW_NUM_LONGWORDS_5];
+};
+
+struct icp_qat_fw_comn_req_hdr {
+ uint8_t resrvd1;
+ uint8_t service_cmd_id;
+ uint8_t service_type;
+ uint8_t hdr_flags;
+ uint16_t serv_specif_flags;
+ uint16_t comn_req_flags;
+};
+
+struct icp_qat_fw_comn_req_rqpars {
+ uint32_t serv_specif_rqpars_lw[ICP_QAT_FW_NUM_LONGWORDS_13];
+};
+
+struct icp_qat_fw_comn_req {
+ struct icp_qat_fw_comn_req_hdr comn_hdr;
+ struct icp_qat_fw_comn_req_hdr_cd_pars cd_pars;
+ struct icp_qat_fw_comn_req_mid comn_mid;
+ struct icp_qat_fw_comn_req_rqpars serv_specif_rqpars;
+ struct icp_qat_fw_comn_req_cd_ctrl cd_ctrl;
+};
+
+struct icp_qat_fw_comn_error {
+ uint8_t xlat_err_code;
+ uint8_t cmp_err_code;
+};
+
+struct icp_qat_fw_comn_resp_hdr {
+ uint8_t resrvd1;
+ uint8_t service_id;
+ uint8_t response_type;
+ uint8_t hdr_flags;
+ struct icp_qat_fw_comn_error comn_error;
+ uint8_t comn_status;
+ uint8_t cmd_id;
+};
+
+struct icp_qat_fw_comn_resp {
+ struct icp_qat_fw_comn_resp_hdr comn_hdr;
+ uint64_t opaque_data;
+ uint32_t resrvd[ICP_QAT_FW_NUM_LONGWORDS_4];
+};
+
+#define ICP_QAT_FW_COMN_REQ_FLAG_SET 1
+#define ICP_QAT_FW_COMN_REQ_FLAG_CLR 0
+#define ICP_QAT_FW_COMN_VALID_FLAG_BITPOS 7
+#define ICP_QAT_FW_COMN_VALID_FLAG_MASK 0x1
+#define ICP_QAT_FW_COMN_HDR_RESRVD_FLD_MASK 0x7F
+
+#define ICP_QAT_FW_COMN_OV_SRV_TYPE_GET(icp_qat_fw_comn_req_hdr_t) \
+ icp_qat_fw_comn_req_hdr_t.service_type
+
+#define ICP_QAT_FW_COMN_OV_SRV_TYPE_SET(icp_qat_fw_comn_req_hdr_t, val) \
+ icp_qat_fw_comn_req_hdr_t.service_type = val
+
+#define ICP_QAT_FW_COMN_OV_SRV_CMD_ID_GET(icp_qat_fw_comn_req_hdr_t) \
+ icp_qat_fw_comn_req_hdr_t.service_cmd_id
+
+#define ICP_QAT_FW_COMN_OV_SRV_CMD_ID_SET(icp_qat_fw_comn_req_hdr_t, val) \
+ icp_qat_fw_comn_req_hdr_t.service_cmd_id = val
+
+#define ICP_QAT_FW_COMN_HDR_VALID_FLAG_GET(hdr_t) \
+ ICP_QAT_FW_COMN_VALID_FLAG_GET(hdr_t.hdr_flags)
+
+#define ICP_QAT_FW_COMN_HDR_VALID_FLAG_SET(hdr_t, val) \
+ ICP_QAT_FW_COMN_VALID_FLAG_SET(hdr_t, val)
+
+#define ICP_QAT_FW_COMN_VALID_FLAG_GET(hdr_flags) \
+ QAT_FIELD_GET(hdr_flags, \
+ ICP_QAT_FW_COMN_VALID_FLAG_BITPOS, \
+ ICP_QAT_FW_COMN_VALID_FLAG_MASK)
+
+#define ICP_QAT_FW_COMN_HDR_RESRVD_FLD_GET(hdr_flags) \
+ (hdr_flags & ICP_QAT_FW_COMN_HDR_RESRVD_FLD_MASK)
+
+#define ICP_QAT_FW_COMN_VALID_FLAG_SET(hdr_t, val) \
+ QAT_FIELD_SET((hdr_t.hdr_flags), (val), \
+ ICP_QAT_FW_COMN_VALID_FLAG_BITPOS, \
+ ICP_QAT_FW_COMN_VALID_FLAG_MASK)
+
+#define ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(valid) \
+ (((valid) & ICP_QAT_FW_COMN_VALID_FLAG_MASK) << \
+ ICP_QAT_FW_COMN_VALID_FLAG_BITPOS)
+
+#define QAT_COMN_PTR_TYPE_BITPOS 0
+#define QAT_COMN_PTR_TYPE_MASK 0x1
+#define QAT_COMN_CD_FLD_TYPE_BITPOS 1
+#define QAT_COMN_CD_FLD_TYPE_MASK 0x1
+#define QAT_COMN_PTR_TYPE_FLAT 0x0
+#define QAT_COMN_PTR_TYPE_SGL 0x1
+#define QAT_COMN_CD_FLD_TYPE_64BIT_ADR 0x0
+#define QAT_COMN_CD_FLD_TYPE_16BYTE_DATA 0x1
+
+#define ICP_QAT_FW_COMN_FLAGS_BUILD(cdt, ptr) \
+ ((((cdt) & QAT_COMN_CD_FLD_TYPE_MASK) << QAT_COMN_CD_FLD_TYPE_BITPOS) \
+ | (((ptr) & QAT_COMN_PTR_TYPE_MASK) << QAT_COMN_PTR_TYPE_BITPOS))
+
+#define ICP_QAT_FW_COMN_PTR_TYPE_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_COMN_PTR_TYPE_BITPOS, QAT_COMN_PTR_TYPE_MASK)
+
+#define ICP_QAT_FW_COMN_CD_FLD_TYPE_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_COMN_CD_FLD_TYPE_BITPOS, \
+ QAT_COMN_CD_FLD_TYPE_MASK)
+
+#define ICP_QAT_FW_COMN_PTR_TYPE_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_COMN_PTR_TYPE_BITPOS, \
+ QAT_COMN_PTR_TYPE_MASK)
+
+#define ICP_QAT_FW_COMN_CD_FLD_TYPE_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_COMN_CD_FLD_TYPE_BITPOS, \
+ QAT_COMN_CD_FLD_TYPE_MASK)
+
+#define ICP_QAT_FW_COMN_NEXT_ID_BITPOS 4
+#define ICP_QAT_FW_COMN_NEXT_ID_MASK 0xF0
+#define ICP_QAT_FW_COMN_CURR_ID_BITPOS 0
+#define ICP_QAT_FW_COMN_CURR_ID_MASK 0x0F
+
+#define ICP_QAT_FW_COMN_NEXT_ID_GET(cd_ctrl_hdr_t) \
+ ((((cd_ctrl_hdr_t)->next_curr_id) & ICP_QAT_FW_COMN_NEXT_ID_MASK) \
+ >> (ICP_QAT_FW_COMN_NEXT_ID_BITPOS))
+
+#define ICP_QAT_FW_COMN_NEXT_ID_SET(cd_ctrl_hdr_t, val) \
+ { ((cd_ctrl_hdr_t)->next_curr_id) = ((((cd_ctrl_hdr_t)->next_curr_id) \
+ & ICP_QAT_FW_COMN_CURR_ID_MASK) | \
+ ((val << ICP_QAT_FW_COMN_NEXT_ID_BITPOS) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK)); }
+
+#define ICP_QAT_FW_COMN_CURR_ID_GET(cd_ctrl_hdr_t) \
+ (((cd_ctrl_hdr_t)->next_curr_id) & ICP_QAT_FW_COMN_CURR_ID_MASK)
+
+#define ICP_QAT_FW_COMN_CURR_ID_SET(cd_ctrl_hdr_t, val) \
+ { ((cd_ctrl_hdr_t)->next_curr_id) = ((((cd_ctrl_hdr_t)->next_curr_id) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK) | \
+ ((val) & ICP_QAT_FW_COMN_CURR_ID_MASK)); }
+
+#define QAT_COMN_RESP_CRYPTO_STATUS_BITPOS 7
+#define QAT_COMN_RESP_CRYPTO_STATUS_MASK 0x1
+#define QAT_COMN_RESP_CMP_STATUS_BITPOS 5
+#define QAT_COMN_RESP_CMP_STATUS_MASK 0x1
+#define QAT_COMN_RESP_XLAT_STATUS_BITPOS 4
+#define QAT_COMN_RESP_XLAT_STATUS_MASK 0x1
+#define QAT_COMN_RESP_CMP_END_OF_LAST_BLK_BITPOS 3
+#define QAT_COMN_RESP_CMP_END_OF_LAST_BLK_MASK 0x1
+
+#define ICP_QAT_FW_COMN_RESP_STATUS_BUILD(crypto, comp, xlat, eolb) \
+ ((((crypto) & QAT_COMN_RESP_CRYPTO_STATUS_MASK) << \
+ QAT_COMN_RESP_CRYPTO_STATUS_BITPOS) | \
+ (((comp) & QAT_COMN_RESP_CMP_STATUS_MASK) << \
+ QAT_COMN_RESP_CMP_STATUS_BITPOS) | \
+ (((xlat) & QAT_COMN_RESP_XLAT_STATUS_MASK) << \
+ QAT_COMN_RESP_XLAT_STATUS_BITPOS) | \
+ (((eolb) & QAT_COMN_RESP_CMP_END_OF_LAST_BLK_MASK) << \
+ QAT_COMN_RESP_CMP_END_OF_LAST_BLK_BITPOS))
+
+#define ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(status) \
+ QAT_FIELD_GET(status, QAT_COMN_RESP_CRYPTO_STATUS_BITPOS, \
+ QAT_COMN_RESP_CRYPTO_STATUS_MASK)
+
+#define ICP_QAT_FW_COMN_RESP_CMP_STAT_GET(status) \
+ QAT_FIELD_GET(status, QAT_COMN_RESP_CMP_STATUS_BITPOS, \
+ QAT_COMN_RESP_CMP_STATUS_MASK)
+
+#define ICP_QAT_FW_COMN_RESP_XLAT_STAT_GET(status) \
+ QAT_FIELD_GET(status, QAT_COMN_RESP_XLAT_STATUS_BITPOS, \
+ QAT_COMN_RESP_XLAT_STATUS_MASK)
+
+#define ICP_QAT_FW_COMN_RESP_CMP_END_OF_LAST_BLK_FLAG_GET(status) \
+ QAT_FIELD_GET(status, QAT_COMN_RESP_CMP_END_OF_LAST_BLK_BITPOS, \
+ QAT_COMN_RESP_CMP_END_OF_LAST_BLK_MASK)
+
+#define ICP_QAT_FW_COMN_STATUS_FLAG_OK 0
+#define ICP_QAT_FW_COMN_STATUS_FLAG_ERROR 1
+#define ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_CLR 0
+#define ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_SET 1
+#define ERR_CODE_NO_ERROR 0
+#define ERR_CODE_INVALID_BLOCK_TYPE -1
+#define ERR_CODE_NO_MATCH_ONES_COMP -2
+#define ERR_CODE_TOO_MANY_LEN_OR_DIS -3
+#define ERR_CODE_INCOMPLETE_LEN -4
+#define ERR_CODE_RPT_LEN_NO_FIRST_LEN -5
+#define ERR_CODE_RPT_GT_SPEC_LEN -6
+#define ERR_CODE_INV_LIT_LEN_CODE_LEN -7
+#define ERR_CODE_INV_DIS_CODE_LEN -8
+#define ERR_CODE_INV_LIT_LEN_DIS_IN_BLK -9
+#define ERR_CODE_DIS_TOO_FAR_BACK -10
+#define ERR_CODE_OVERFLOW_ERROR -11
+#define ERR_CODE_SOFT_ERROR -12
+#define ERR_CODE_FATAL_ERROR -13
+#define ERR_CODE_SSM_ERROR -14
+#define ERR_CODE_ENDPOINT_ERROR -15
+
+enum icp_qat_fw_slice {
+ ICP_QAT_FW_SLICE_NULL = 0,
+ ICP_QAT_FW_SLICE_CIPHER = 1,
+ ICP_QAT_FW_SLICE_AUTH = 2,
+ ICP_QAT_FW_SLICE_DRAM_RD = 3,
+ ICP_QAT_FW_SLICE_DRAM_WR = 4,
+ ICP_QAT_FW_SLICE_COMP = 5,
+ ICP_QAT_FW_SLICE_XLAT = 6,
+ ICP_QAT_FW_SLICE_DELIMITER
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
new file mode 100644
index 000000000000..72a59faa9005
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
@@ -0,0 +1,131 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef _ICP_QAT_FW_INIT_ADMIN_H_
+#define _ICP_QAT_FW_INIT_ADMIN_H_
+
+#include "icp_qat_fw.h"
+
+enum icp_qat_fw_init_admin_cmd_id {
+ ICP_QAT_FW_INIT_ME = 0,
+ ICP_QAT_FW_TRNG_ENABLE = 1,
+ ICP_QAT_FW_TRNG_DISABLE = 2,
+ ICP_QAT_FW_CONSTANTS_CFG = 3,
+ ICP_QAT_FW_STATUS_GET = 4,
+ ICP_QAT_FW_COUNTERS_GET = 5,
+ ICP_QAT_FW_LOOPBACK = 6,
+ ICP_QAT_FW_HEARTBEAT_SYNC = 7,
+ ICP_QAT_FW_HEARTBEAT_GET = 8
+};
+
+enum icp_qat_fw_init_admin_resp_status {
+ ICP_QAT_FW_INIT_RESP_STATUS_SUCCESS = 0,
+ ICP_QAT_FW_INIT_RESP_STATUS_FAIL
+};
+
+struct icp_qat_fw_init_admin_req {
+ uint16_t init_cfg_sz;
+ uint8_t resrvd1;
+ uint8_t init_admin_cmd_id;
+ uint32_t resrvd2;
+ uint64_t opaque_data;
+ uint64_t init_cfg_ptr;
+ uint64_t resrvd3;
+};
+
+struct icp_qat_fw_init_admin_resp_hdr {
+ uint8_t flags;
+ uint8_t resrvd1;
+ uint8_t status;
+ uint8_t init_admin_cmd_id;
+};
+
+struct icp_qat_fw_init_admin_resp_pars {
+ union {
+ uint32_t resrvd1[ICP_QAT_FW_NUM_LONGWORDS_4];
+ struct {
+ uint32_t version_patch_num;
+ uint8_t context_id;
+ uint8_t ae_id;
+ uint16_t resrvd1;
+ uint64_t resrvd2;
+ } s1;
+ struct {
+ uint64_t req_rec_count;
+ uint64_t resp_sent_count;
+ } s2;
+ } u;
+};
+
+struct icp_qat_fw_init_admin_resp {
+ struct icp_qat_fw_init_admin_resp_hdr init_resp_hdr;
+ union {
+ uint32_t resrvd2;
+ struct {
+ uint16_t version_minor_num;
+ uint16_t version_major_num;
+ } s;
+ } u;
+ uint64_t opaque_data;
+ struct icp_qat_fw_init_admin_resp_pars init_resp_pars;
+};
+
+#define ICP_QAT_FW_COMN_HEARTBEAT_OK 0
+#define ICP_QAT_FW_COMN_HEARTBEAT_BLOCKED 1
+#define ICP_QAT_FW_COMN_HEARTBEAT_FLAG_BITPOS 0
+#define ICP_QAT_FW_COMN_HEARTBEAT_FLAG_MASK 0x1
+#define ICP_QAT_FW_COMN_STATUS_RESRVD_FLD_MASK 0xFE
+#define ICP_QAT_FW_COMN_HEARTBEAT_HDR_FLAG_GET(hdr_t) \
+ ICP_QAT_FW_COMN_HEARTBEAT_FLAG_GET(hdr_t.flags)
+
+#define ICP_QAT_FW_COMN_HEARTBEAT_HDR_FLAG_SET(hdr_t, val) \
+ ICP_QAT_FW_COMN_HEARTBEAT_FLAG_SET(hdr_t, val)
+
+#define ICP_QAT_FW_COMN_HEARTBEAT_FLAG_GET(flags) \
+ QAT_FIELD_GET(flags, \
+ ICP_QAT_FW_COMN_HEARTBEAT_FLAG_BITPOS, \
+ ICP_QAT_FW_COMN_HEARTBEAT_FLAG_MASK)
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_la.h b/drivers/crypto/qat/qat_common/icp_qat_fw_la.h
new file mode 100644
index 000000000000..c8d26697e8ea
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_la.h
@@ -0,0 +1,404 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef _ICP_QAT_FW_LA_H_
+#define _ICP_QAT_FW_LA_H_
+#include "icp_qat_fw.h"
+
+enum icp_qat_fw_la_cmd_id {
+ ICP_QAT_FW_LA_CMD_CIPHER = 0,
+ ICP_QAT_FW_LA_CMD_AUTH = 1,
+ ICP_QAT_FW_LA_CMD_CIPHER_HASH = 2,
+ ICP_QAT_FW_LA_CMD_HASH_CIPHER = 3,
+ ICP_QAT_FW_LA_CMD_TRNG_GET_RANDOM = 4,
+ ICP_QAT_FW_LA_CMD_TRNG_TEST = 5,
+ ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE = 6,
+ ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE = 7,
+ ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE = 8,
+ ICP_QAT_FW_LA_CMD_MGF1 = 9,
+ ICP_QAT_FW_LA_CMD_AUTH_PRE_COMP = 10,
+ ICP_QAT_FW_LA_CMD_CIPHER_PRE_COMP = 11,
+ ICP_QAT_FW_LA_CMD_DELIMITER = 12
+};
+
+#define ICP_QAT_FW_LA_ICV_VER_STATUS_PASS ICP_QAT_FW_COMN_STATUS_FLAG_OK
+#define ICP_QAT_FW_LA_ICV_VER_STATUS_FAIL ICP_QAT_FW_COMN_STATUS_FLAG_ERROR
+#define ICP_QAT_FW_LA_TRNG_STATUS_PASS ICP_QAT_FW_COMN_STATUS_FLAG_OK
+#define ICP_QAT_FW_LA_TRNG_STATUS_FAIL ICP_QAT_FW_COMN_STATUS_FLAG_ERROR
+
+struct icp_qat_fw_la_bulk_req {
+ struct icp_qat_fw_comn_req_hdr comn_hdr;
+ struct icp_qat_fw_comn_req_hdr_cd_pars cd_pars;
+ struct icp_qat_fw_comn_req_mid comn_mid;
+ struct icp_qat_fw_comn_req_rqpars serv_specif_rqpars;
+ struct icp_qat_fw_comn_req_cd_ctrl cd_ctrl;
+};
+
+#define ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS 1
+#define ICP_QAT_FW_LA_GCM_IV_LEN_NOT_12_OCTETS 0
+#define QAT_FW_LA_ZUC_3G_PROTO_FLAG_BITPOS 12
+#define ICP_QAT_FW_LA_ZUC_3G_PROTO 1
+#define QAT_FW_LA_ZUC_3G_PROTO_FLAG_MASK 0x1
+#define QAT_LA_GCM_IV_LEN_FLAG_BITPOS 11
+#define QAT_LA_GCM_IV_LEN_FLAG_MASK 0x1
+#define ICP_QAT_FW_LA_DIGEST_IN_BUFFER 1
+#define ICP_QAT_FW_LA_NO_DIGEST_IN_BUFFER 0
+#define QAT_LA_DIGEST_IN_BUFFER_BITPOS 10
+#define QAT_LA_DIGEST_IN_BUFFER_MASK 0x1
+#define ICP_QAT_FW_LA_SNOW_3G_PROTO 4
+#define ICP_QAT_FW_LA_GCM_PROTO 2
+#define ICP_QAT_FW_LA_CCM_PROTO 1
+#define ICP_QAT_FW_LA_NO_PROTO 0
+#define QAT_LA_PROTO_BITPOS 7
+#define QAT_LA_PROTO_MASK 0x7
+#define ICP_QAT_FW_LA_CMP_AUTH_RES 1
+#define ICP_QAT_FW_LA_NO_CMP_AUTH_RES 0
+#define QAT_LA_CMP_AUTH_RES_BITPOS 6
+#define QAT_LA_CMP_AUTH_RES_MASK 0x1
+#define ICP_QAT_FW_LA_RET_AUTH_RES 1
+#define ICP_QAT_FW_LA_NO_RET_AUTH_RES 0
+#define QAT_LA_RET_AUTH_RES_BITPOS 5
+#define QAT_LA_RET_AUTH_RES_MASK 0x1
+#define ICP_QAT_FW_LA_UPDATE_STATE 1
+#define ICP_QAT_FW_LA_NO_UPDATE_STATE 0
+#define QAT_LA_UPDATE_STATE_BITPOS 4
+#define QAT_LA_UPDATE_STATE_MASK 0x1
+#define ICP_QAT_FW_CIPH_AUTH_CFG_OFFSET_IN_CD_SETUP 0
+#define ICP_QAT_FW_CIPH_AUTH_CFG_OFFSET_IN_SHRAM_CP 1
+#define QAT_LA_CIPH_AUTH_CFG_OFFSET_BITPOS 3
+#define QAT_LA_CIPH_AUTH_CFG_OFFSET_MASK 0x1
+#define ICP_QAT_FW_CIPH_IV_64BIT_PTR 0
+#define ICP_QAT_FW_CIPH_IV_16BYTE_DATA 1
+#define QAT_LA_CIPH_IV_FLD_BITPOS 2
+#define QAT_LA_CIPH_IV_FLD_MASK 0x1
+#define ICP_QAT_FW_LA_PARTIAL_NONE 0
+#define ICP_QAT_FW_LA_PARTIAL_START 1
+#define ICP_QAT_FW_LA_PARTIAL_MID 3
+#define ICP_QAT_FW_LA_PARTIAL_END 2
+#define QAT_LA_PARTIAL_BITPOS 0
+#define QAT_LA_PARTIAL_MASK 0x3
+#define ICP_QAT_FW_LA_FLAGS_BUILD(zuc_proto, gcm_iv_len, auth_rslt, proto, \
+ cmp_auth, ret_auth, update_state, \
+ ciph_iv, ciphcfg, partial) \
+ (((zuc_proto & QAT_FW_LA_ZUC_3G_PROTO_FLAG_MASK) << \
+ QAT_FW_LA_ZUC_3G_PROTO_FLAG_BITPOS) | \
+ ((gcm_iv_len & QAT_LA_GCM_IV_LEN_FLAG_MASK) << \
+ QAT_LA_GCM_IV_LEN_FLAG_BITPOS) | \
+ ((auth_rslt & QAT_LA_DIGEST_IN_BUFFER_MASK) << \
+ QAT_LA_DIGEST_IN_BUFFER_BITPOS) | \
+ ((proto & QAT_LA_PROTO_MASK) << \
+ QAT_LA_PROTO_BITPOS) | \
+ ((cmp_auth & QAT_LA_CMP_AUTH_RES_MASK) << \
+ QAT_LA_CMP_AUTH_RES_BITPOS) | \
+ ((ret_auth & QAT_LA_RET_AUTH_RES_MASK) << \
+ QAT_LA_RET_AUTH_RES_BITPOS) | \
+ ((update_state & QAT_LA_UPDATE_STATE_MASK) << \
+ QAT_LA_UPDATE_STATE_BITPOS) | \
+ ((ciph_iv & QAT_LA_CIPH_IV_FLD_MASK) << \
+ QAT_LA_CIPH_IV_FLD_BITPOS) | \
+ ((ciphcfg & QAT_LA_CIPH_AUTH_CFG_OFFSET_MASK) << \
+ QAT_LA_CIPH_AUTH_CFG_OFFSET_BITPOS) | \
+ ((partial & QAT_LA_PARTIAL_MASK) << \
+ QAT_LA_PARTIAL_BITPOS))
+
+#define ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_CIPH_IV_FLD_BITPOS, \
+ QAT_LA_CIPH_IV_FLD_MASK)
+
+#define ICP_QAT_FW_LA_CIPH_AUTH_CFG_OFFSET_FLAG_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_CIPH_AUTH_CFG_OFFSET_BITPOS, \
+ QAT_LA_CIPH_AUTH_CFG_OFFSET_MASK)
+
+#define ICP_QAT_FW_LA_ZUC_3G_PROTO_FLAG_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_FW_LA_ZUC_3G_PROTO_FLAG_BITPOS, \
+ QAT_FW_LA_ZUC_3G_PROTO_FLAG_MASK)
+
+#define ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_GCM_IV_LEN_FLAG_BITPOS, \
+ QAT_LA_GCM_IV_LEN_FLAG_MASK)
+
+#define ICP_QAT_FW_LA_PROTO_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_PROTO_BITPOS, QAT_LA_PROTO_MASK)
+
+#define ICP_QAT_FW_LA_CMP_AUTH_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_CMP_AUTH_RES_BITPOS, \
+ QAT_LA_CMP_AUTH_RES_MASK)
+
+#define ICP_QAT_FW_LA_RET_AUTH_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_RET_AUTH_RES_BITPOS, \
+ QAT_LA_RET_AUTH_RES_MASK)
+
+#define ICP_QAT_FW_LA_DIGEST_IN_BUFFER_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_DIGEST_IN_BUFFER_BITPOS, \
+ QAT_LA_DIGEST_IN_BUFFER_MASK)
+
+#define ICP_QAT_FW_LA_UPDATE_STATE_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_UPDATE_STATE_BITPOS, \
+ QAT_LA_UPDATE_STATE_MASK)
+
+#define ICP_QAT_FW_LA_PARTIAL_GET(flags) \
+ QAT_FIELD_GET(flags, QAT_LA_PARTIAL_BITPOS, \
+ QAT_LA_PARTIAL_MASK)
+
+#define ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_CIPH_IV_FLD_BITPOS, \
+ QAT_LA_CIPH_IV_FLD_MASK)
+
+#define ICP_QAT_FW_LA_CIPH_AUTH_CFG_OFFSET_FLAG_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_CIPH_AUTH_CFG_OFFSET_BITPOS, \
+ QAT_LA_CIPH_AUTH_CFG_OFFSET_MASK)
+
+#define ICP_QAT_FW_LA_ZUC_3G_PROTO_FLAG_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_FW_LA_ZUC_3G_PROTO_FLAG_BITPOS, \
+ QAT_FW_LA_ZUC_3G_PROTO_FLAG_MASK)
+
+#define ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_GCM_IV_LEN_FLAG_BITPOS, \
+ QAT_LA_GCM_IV_LEN_FLAG_MASK)
+
+#define ICP_QAT_FW_LA_PROTO_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_PROTO_BITPOS, \
+ QAT_LA_PROTO_MASK)
+
+#define ICP_QAT_FW_LA_CMP_AUTH_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_CMP_AUTH_RES_BITPOS, \
+ QAT_LA_CMP_AUTH_RES_MASK)
+
+#define ICP_QAT_FW_LA_RET_AUTH_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_RET_AUTH_RES_BITPOS, \
+ QAT_LA_RET_AUTH_RES_MASK)
+
+#define ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_DIGEST_IN_BUFFER_BITPOS, \
+ QAT_LA_DIGEST_IN_BUFFER_MASK)
+
+#define ICP_QAT_FW_LA_UPDATE_STATE_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_UPDATE_STATE_BITPOS, \
+ QAT_LA_UPDATE_STATE_MASK)
+
+#define ICP_QAT_FW_LA_PARTIAL_SET(flags, val) \
+ QAT_FIELD_SET(flags, val, QAT_LA_PARTIAL_BITPOS, \
+ QAT_LA_PARTIAL_MASK)
+
+struct icp_qat_fw_cipher_req_hdr_cd_pars {
+ union {
+ struct {
+ uint64_t content_desc_addr;
+ uint16_t content_desc_resrvd1;
+ uint8_t content_desc_params_sz;
+ uint8_t content_desc_hdr_resrvd2;
+ uint32_t content_desc_resrvd3;
+ } s;
+ struct {
+ uint32_t cipher_key_array[ICP_QAT_FW_NUM_LONGWORDS_4];
+ } s1;
+ } u;
+};
+
+struct icp_qat_fw_cipher_auth_req_hdr_cd_pars {
+ union {
+ struct {
+ uint64_t content_desc_addr;
+ uint16_t content_desc_resrvd1;
+ uint8_t content_desc_params_sz;
+ uint8_t content_desc_hdr_resrvd2;
+ uint32_t content_desc_resrvd3;
+ } s;
+ struct {
+ uint32_t cipher_key_array[ICP_QAT_FW_NUM_LONGWORDS_4];
+ } sl;
+ } u;
+};
+
+struct icp_qat_fw_cipher_cd_ctrl_hdr {
+ uint8_t cipher_state_sz;
+ uint8_t cipher_key_sz;
+ uint8_t cipher_cfg_offset;
+ uint8_t next_curr_id;
+ uint8_t cipher_padding_sz;
+ uint8_t resrvd1;
+ uint16_t resrvd2;
+ uint32_t resrvd3[ICP_QAT_FW_NUM_LONGWORDS_3];
+};
+
+struct icp_qat_fw_auth_cd_ctrl_hdr {
+ uint32_t resrvd1;
+ uint8_t resrvd2;
+ uint8_t hash_flags;
+ uint8_t hash_cfg_offset;
+ uint8_t next_curr_id;
+ uint8_t resrvd3;
+ uint8_t outer_prefix_sz;
+ uint8_t final_sz;
+ uint8_t inner_res_sz;
+ uint8_t resrvd4;
+ uint8_t inner_state1_sz;
+ uint8_t inner_state2_offset;
+ uint8_t inner_state2_sz;
+ uint8_t outer_config_offset;
+ uint8_t outer_state1_sz;
+ uint8_t outer_res_sz;
+ uint8_t outer_prefix_offset;
+};
+
+struct icp_qat_fw_cipher_auth_cd_ctrl_hdr {
+ uint8_t cipher_state_sz;
+ uint8_t cipher_key_sz;
+ uint8_t cipher_cfg_offset;
+ uint8_t next_curr_id_cipher;
+ uint8_t cipher_padding_sz;
+ uint8_t hash_flags;
+ uint8_t hash_cfg_offset;
+ uint8_t next_curr_id_auth;
+ uint8_t resrvd1;
+ uint8_t outer_prefix_sz;
+ uint8_t final_sz;
+ uint8_t inner_res_sz;
+ uint8_t resrvd2;
+ uint8_t inner_state1_sz;
+ uint8_t inner_state2_offset;
+ uint8_t inner_state2_sz;
+ uint8_t outer_config_offset;
+ uint8_t outer_state1_sz;
+ uint8_t outer_res_sz;
+ uint8_t outer_prefix_offset;
+};
+
+#define ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED 1
+#define ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED 0
+#define ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX 240
+#define ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET \
+ (sizeof(struct icp_qat_fw_la_cipher_req_params_t))
+#define ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET (0)
+
+struct icp_qat_fw_la_cipher_req_params {
+ uint32_t cipher_offset;
+ uint32_t cipher_length;
+ union {
+ uint32_t cipher_IV_array[ICP_QAT_FW_NUM_LONGWORDS_4];
+ struct {
+ uint64_t cipher_IV_ptr;
+ uint64_t resrvd1;
+ } s;
+ } u;
+};
+
+struct icp_qat_fw_la_auth_req_params {
+ uint32_t auth_off;
+ uint32_t auth_len;
+ union {
+ uint64_t auth_partial_st_prefix;
+ uint64_t aad_adr;
+ } u1;
+ uint64_t auth_res_addr;
+ union {
+ uint8_t inner_prefix_sz;
+ uint8_t aad_sz;
+ } u2;
+ uint8_t resrvd1;
+ uint8_t hash_state_sz;
+ uint8_t auth_res_sz;
+} __packed;
+
+struct icp_qat_fw_la_auth_req_params_resrvd_flds {
+ uint32_t resrvd[ICP_QAT_FW_NUM_LONGWORDS_6];
+ union {
+ uint8_t inner_prefix_sz;
+ uint8_t aad_sz;
+ } u2;
+ uint8_t resrvd1;
+ uint16_t resrvd2;
+};
+
+struct icp_qat_fw_la_resp {
+ struct icp_qat_fw_comn_resp_hdr comn_resp;
+ uint64_t opaque_data;
+ uint32_t resrvd[ICP_QAT_FW_NUM_LONGWORDS_4];
+};
+
+#define ICP_QAT_FW_CIPHER_NEXT_ID_GET(cd_ctrl_hdr_t) \
+ ((((cd_ctrl_hdr_t)->next_curr_id_cipher) & \
+ ICP_QAT_FW_COMN_NEXT_ID_MASK) >> (ICP_QAT_FW_COMN_NEXT_ID_BITPOS))
+
+#define ICP_QAT_FW_CIPHER_NEXT_ID_SET(cd_ctrl_hdr_t, val) \
+{ (cd_ctrl_hdr_t)->next_curr_id_cipher = \
+ ((((cd_ctrl_hdr_t)->next_curr_id_cipher) \
+ & ICP_QAT_FW_COMN_CURR_ID_MASK) | \
+ ((val << ICP_QAT_FW_COMN_NEXT_ID_BITPOS) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK)) }
+
+#define ICP_QAT_FW_CIPHER_CURR_ID_GET(cd_ctrl_hdr_t) \
+ (((cd_ctrl_hdr_t)->next_curr_id_cipher) \
+ & ICP_QAT_FW_COMN_CURR_ID_MASK)
+
+#define ICP_QAT_FW_CIPHER_CURR_ID_SET(cd_ctrl_hdr_t, val) \
+{ (cd_ctrl_hdr_t)->next_curr_id_cipher = \
+ ((((cd_ctrl_hdr_t)->next_curr_id_cipher) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK) | \
+ ((val) & ICP_QAT_FW_COMN_CURR_ID_MASK)) }
+
+#define ICP_QAT_FW_AUTH_NEXT_ID_GET(cd_ctrl_hdr_t) \
+ ((((cd_ctrl_hdr_t)->next_curr_id_auth) & ICP_QAT_FW_COMN_NEXT_ID_MASK) \
+ >> (ICP_QAT_FW_COMN_NEXT_ID_BITPOS))
+
+#define ICP_QAT_FW_AUTH_NEXT_ID_SET(cd_ctrl_hdr_t, val) \
+{ (cd_ctrl_hdr_t)->next_curr_id_auth = \
+ ((((cd_ctrl_hdr_t)->next_curr_id_auth) \
+ & ICP_QAT_FW_COMN_CURR_ID_MASK) | \
+ ((val << ICP_QAT_FW_COMN_NEXT_ID_BITPOS) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK)) }
+
+#define ICP_QAT_FW_AUTH_CURR_ID_GET(cd_ctrl_hdr_t) \
+ (((cd_ctrl_hdr_t)->next_curr_id_auth) \
+ & ICP_QAT_FW_COMN_CURR_ID_MASK)
+
+#define ICP_QAT_FW_AUTH_CURR_ID_SET(cd_ctrl_hdr_t, val) \
+{ (cd_ctrl_hdr_t)->next_curr_id_auth = \
+ ((((cd_ctrl_hdr_t)->next_curr_id_auth) \
+ & ICP_QAT_FW_COMN_NEXT_ID_MASK) | \
+ ((val) & ICP_QAT_FW_COMN_CURR_ID_MASK)) }
+
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_loader_handle.h b/drivers/crypto/qat/qat_common/icp_qat_fw_loader_handle.h
new file mode 100644
index 000000000000..5e1aa40c0404
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_loader_handle.h
@@ -0,0 +1,78 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef __ICP_QAT_FW_LOADER_HANDLE_H__
+#define __ICP_QAT_FW_LOADER_HANDLE_H__
+#include "icp_qat_uclo.h"
+
+struct icp_qat_fw_loader_ae_data {
+ unsigned int state;
+ unsigned int ustore_size;
+ unsigned int free_addr;
+ unsigned int free_size;
+ unsigned int live_ctx_mask;
+};
+
+struct icp_qat_fw_loader_hal_handle {
+ struct icp_qat_fw_loader_ae_data aes[ICP_QAT_UCLO_MAX_AE];
+ unsigned int ae_mask;
+ unsigned int slice_mask;
+ unsigned int revision_id;
+ unsigned int ae_max_num;
+ unsigned int upc_mask;
+ unsigned int max_ustore;
+};
+
+struct icp_qat_fw_loader_handle {
+ struct icp_qat_fw_loader_hal_handle *hal_handle;
+ void *obj_handle;
+ void __iomem *hal_sram_addr_v;
+ void __iomem *hal_cap_g_ctl_csr_addr_v;
+ void __iomem *hal_cap_ae_xfer_csr_addr_v;
+ void __iomem *hal_cap_ae_local_csr_addr_v;
+ void __iomem *hal_ep_csr_addr_v;
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_hal.h b/drivers/crypto/qat/qat_common/icp_qat_hal.h
new file mode 100644
index 000000000000..85b6d241ea82
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_hal.h
@@ -0,0 +1,125 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef __ICP_QAT_HAL_H
+#define __ICP_QAT_HAL_H
+#include "icp_qat_fw_loader_handle.h"
+
+enum hal_global_csr {
+ MISC_CONTROL = 0x04,
+ ICP_RESET = 0x0c,
+ ICP_GLOBAL_CLK_ENABLE = 0x50
+};
+
+enum hal_ae_csr {
+ USTORE_ADDRESS = 0x000,
+ USTORE_DATA_LOWER = 0x004,
+ USTORE_DATA_UPPER = 0x008,
+ ALU_OUT = 0x010,
+ CTX_ARB_CNTL = 0x014,
+ CTX_ENABLES = 0x018,
+ CC_ENABLE = 0x01c,
+ CSR_CTX_POINTER = 0x020,
+ CTX_STS_INDIRECT = 0x040,
+ ACTIVE_CTX_STATUS = 0x044,
+ CTX_SIG_EVENTS_INDIRECT = 0x048,
+ CTX_SIG_EVENTS_ACTIVE = 0x04c,
+ CTX_WAKEUP_EVENTS_INDIRECT = 0x050,
+ LM_ADDR_0_INDIRECT = 0x060,
+ LM_ADDR_1_INDIRECT = 0x068,
+ INDIRECT_LM_ADDR_0_BYTE_INDEX = 0x0e0,
+ INDIRECT_LM_ADDR_1_BYTE_INDEX = 0x0e8,
+ FUTURE_COUNT_SIGNAL_INDIRECT = 0x078,
+ TIMESTAMP_LOW = 0x0c0,
+ TIMESTAMP_HIGH = 0x0c4,
+ PROFILE_COUNT = 0x144,
+ SIGNATURE_ENABLE = 0x150,
+ AE_MISC_CONTROL = 0x160,
+ LOCAL_CSR_STATUS = 0x180,
+};
+
+#define UA_ECS (0x1 << 31)
+#define ACS_ABO_BITPOS 31
+#define ACS_ACNO 0x7
+#define CE_ENABLE_BITPOS 0x8
+#define CE_LMADDR_0_GLOBAL_BITPOS 16
+#define CE_LMADDR_1_GLOBAL_BITPOS 17
+#define CE_NN_MODE_BITPOS 20
+#define CE_REG_PAR_ERR_BITPOS 25
+#define CE_BREAKPOINT_BITPOS 27
+#define CE_CNTL_STORE_PARITY_ERROR_BITPOS 29
+#define CE_INUSE_CONTEXTS_BITPOS 31
+#define CE_NN_MODE (0x1 << CE_NN_MODE_BITPOS)
+#define CE_INUSE_CONTEXTS (0x1 << CE_INUSE_CONTEXTS_BITPOS)
+#define XCWE_VOLUNTARY (0x1)
+#define LCS_STATUS (0x1)
+#define MMC_SHARE_CS_BITPOS 2
+#define GLOBAL_CSR 0xA00
+
+#define SET_CAP_CSR(handle, csr, val) \
+ ADF_CSR_WR(handle->hal_cap_g_ctl_csr_addr_v, csr, val)
+#define GET_CAP_CSR(handle, csr) \
+ ADF_CSR_RD(handle->hal_cap_g_ctl_csr_addr_v, csr)
+#define SET_GLB_CSR(handle, csr, val) SET_CAP_CSR(handle, csr + GLOBAL_CSR, val)
+#define GET_GLB_CSR(handle, csr) GET_CAP_CSR(handle, GLOBAL_CSR + csr)
+#define AE_CSR(handle, ae) \
+ (handle->hal_cap_ae_local_csr_addr_v + \
+ ((ae & handle->hal_handle->ae_mask) << 12))
+#define AE_CSR_ADDR(handle, ae, csr) (AE_CSR(handle, ae) + (0x3ff & csr))
+#define SET_AE_CSR(handle, ae, csr, val) \
+ ADF_CSR_WR(AE_CSR_ADDR(handle, ae, csr), 0, val)
+#define GET_AE_CSR(handle, ae, csr) ADF_CSR_RD(AE_CSR_ADDR(handle, ae, csr), 0)
+#define AE_XFER(handle, ae) \
+ (handle->hal_cap_ae_xfer_csr_addr_v + \
+ ((ae & handle->hal_handle->ae_mask) << 12))
+#define AE_XFER_ADDR(handle, ae, reg) (AE_XFER(handle, ae) + \
+ ((reg & 0xff) << 2))
+#define SET_AE_XFER(handle, ae, reg, val) \
+ ADF_CSR_WR(AE_XFER_ADDR(handle, ae, reg), 0, val)
+#define SRAM_WRITE(handle, addr, val) \
+ ADF_CSR_WR(handle->hal_sram_addr_v, addr, val)
+#define SRAM_READ(handle, addr) ADF_CSR_RD(handle->hal_sram_addr_v, addr)
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_hw.h b/drivers/crypto/qat/qat_common/icp_qat_hw.h
new file mode 100644
index 000000000000..5031f8c10d75
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_hw.h
@@ -0,0 +1,305 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef _ICP_QAT_HW_H_
+#define _ICP_QAT_HW_H_
+
+enum icp_qat_hw_ae_id {
+ ICP_QAT_HW_AE_0 = 0,
+ ICP_QAT_HW_AE_1 = 1,
+ ICP_QAT_HW_AE_2 = 2,
+ ICP_QAT_HW_AE_3 = 3,
+ ICP_QAT_HW_AE_4 = 4,
+ ICP_QAT_HW_AE_5 = 5,
+ ICP_QAT_HW_AE_6 = 6,
+ ICP_QAT_HW_AE_7 = 7,
+ ICP_QAT_HW_AE_8 = 8,
+ ICP_QAT_HW_AE_9 = 9,
+ ICP_QAT_HW_AE_10 = 10,
+ ICP_QAT_HW_AE_11 = 11,
+ ICP_QAT_HW_AE_DELIMITER = 12
+};
+
+enum icp_qat_hw_qat_id {
+ ICP_QAT_HW_QAT_0 = 0,
+ ICP_QAT_HW_QAT_1 = 1,
+ ICP_QAT_HW_QAT_2 = 2,
+ ICP_QAT_HW_QAT_3 = 3,
+ ICP_QAT_HW_QAT_4 = 4,
+ ICP_QAT_HW_QAT_5 = 5,
+ ICP_QAT_HW_QAT_DELIMITER = 6
+};
+
+enum icp_qat_hw_auth_algo {
+ ICP_QAT_HW_AUTH_ALGO_NULL = 0,
+ ICP_QAT_HW_AUTH_ALGO_SHA1 = 1,
+ ICP_QAT_HW_AUTH_ALGO_MD5 = 2,
+ ICP_QAT_HW_AUTH_ALGO_SHA224 = 3,
+ ICP_QAT_HW_AUTH_ALGO_SHA256 = 4,
+ ICP_QAT_HW_AUTH_ALGO_SHA384 = 5,
+ ICP_QAT_HW_AUTH_ALGO_SHA512 = 6,
+ ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC = 7,
+ ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC = 8,
+ ICP_QAT_HW_AUTH_ALGO_AES_F9 = 9,
+ ICP_QAT_HW_AUTH_ALGO_GALOIS_128 = 10,
+ ICP_QAT_HW_AUTH_ALGO_GALOIS_64 = 11,
+ ICP_QAT_HW_AUTH_ALGO_KASUMI_F9 = 12,
+ ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2 = 13,
+ ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3 = 14,
+ ICP_QAT_HW_AUTH_RESERVED_1 = 15,
+ ICP_QAT_HW_AUTH_RESERVED_2 = 16,
+ ICP_QAT_HW_AUTH_ALGO_SHA3_256 = 17,
+ ICP_QAT_HW_AUTH_RESERVED_3 = 18,
+ ICP_QAT_HW_AUTH_ALGO_SHA3_512 = 19,
+ ICP_QAT_HW_AUTH_ALGO_DELIMITER = 20
+};
+
+enum icp_qat_hw_auth_mode {
+ ICP_QAT_HW_AUTH_MODE0 = 0,
+ ICP_QAT_HW_AUTH_MODE1 = 1,
+ ICP_QAT_HW_AUTH_MODE2 = 2,
+ ICP_QAT_HW_AUTH_MODE_DELIMITER = 3
+};
+
+struct icp_qat_hw_auth_config {
+ uint32_t config;
+ uint32_t reserved;
+};
+
+#define QAT_AUTH_MODE_BITPOS 4
+#define QAT_AUTH_MODE_MASK 0xF
+#define QAT_AUTH_ALGO_BITPOS 0
+#define QAT_AUTH_ALGO_MASK 0xF
+#define QAT_AUTH_CMP_BITPOS 8
+#define QAT_AUTH_CMP_MASK 0x7F
+#define QAT_AUTH_SHA3_PADDING_BITPOS 16
+#define QAT_AUTH_SHA3_PADDING_MASK 0x1
+#define QAT_AUTH_ALGO_SHA3_BITPOS 22
+#define QAT_AUTH_ALGO_SHA3_MASK 0x3
+#define ICP_QAT_HW_AUTH_CONFIG_BUILD(mode, algo, cmp_len) \
+ (((mode & QAT_AUTH_MODE_MASK) << QAT_AUTH_MODE_BITPOS) | \
+ ((algo & QAT_AUTH_ALGO_MASK) << QAT_AUTH_ALGO_BITPOS) | \
+ (((algo >> 4) & QAT_AUTH_ALGO_SHA3_MASK) << \
+ QAT_AUTH_ALGO_SHA3_BITPOS) | \
+ (((((algo == ICP_QAT_HW_AUTH_ALGO_SHA3_256) || \
+ (algo == ICP_QAT_HW_AUTH_ALGO_SHA3_512)) ? 1 : 0) \
+ & QAT_AUTH_SHA3_PADDING_MASK) << QAT_AUTH_SHA3_PADDING_BITPOS) | \
+ ((cmp_len & QAT_AUTH_CMP_MASK) << QAT_AUTH_CMP_BITPOS))
+
+struct icp_qat_hw_auth_counter {
+ __be32 counter;
+ uint32_t reserved;
+};
+
+#define QAT_AUTH_COUNT_MASK 0xFFFFFFFF
+#define QAT_AUTH_COUNT_BITPOS 0
+#define ICP_QAT_HW_AUTH_COUNT_BUILD(val) \
+ (((val) & QAT_AUTH_COUNT_MASK) << QAT_AUTH_COUNT_BITPOS)
+
+struct icp_qat_hw_auth_setup {
+ struct icp_qat_hw_auth_config auth_config;
+ struct icp_qat_hw_auth_counter auth_counter;
+};
+
+#define QAT_HW_DEFAULT_ALIGNMENT 8
+#define QAT_HW_ROUND_UP(val, n) (((val) + ((n)-1)) & (~(n-1)))
+#define ICP_QAT_HW_NULL_STATE1_SZ 32
+#define ICP_QAT_HW_MD5_STATE1_SZ 16
+#define ICP_QAT_HW_SHA1_STATE1_SZ 20
+#define ICP_QAT_HW_SHA224_STATE1_SZ 32
+#define ICP_QAT_HW_SHA256_STATE1_SZ 32
+#define ICP_QAT_HW_SHA3_256_STATE1_SZ 32
+#define ICP_QAT_HW_SHA384_STATE1_SZ 64
+#define ICP_QAT_HW_SHA512_STATE1_SZ 64
+#define ICP_QAT_HW_SHA3_512_STATE1_SZ 64
+#define ICP_QAT_HW_SHA3_224_STATE1_SZ 28
+#define ICP_QAT_HW_SHA3_384_STATE1_SZ 48
+#define ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ 16
+#define ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ 16
+#define ICP_QAT_HW_AES_F9_STATE1_SZ 32
+#define ICP_QAT_HW_KASUMI_F9_STATE1_SZ 16
+#define ICP_QAT_HW_GALOIS_128_STATE1_SZ 16
+#define ICP_QAT_HW_SNOW_3G_UIA2_STATE1_SZ 8
+#define ICP_QAT_HW_ZUC_3G_EIA3_STATE1_SZ 8
+#define ICP_QAT_HW_NULL_STATE2_SZ 32
+#define ICP_QAT_HW_MD5_STATE2_SZ 16
+#define ICP_QAT_HW_SHA1_STATE2_SZ 20
+#define ICP_QAT_HW_SHA224_STATE2_SZ 32
+#define ICP_QAT_HW_SHA256_STATE2_SZ 32
+#define ICP_QAT_HW_SHA3_256_STATE2_SZ 0
+#define ICP_QAT_HW_SHA384_STATE2_SZ 64
+#define ICP_QAT_HW_SHA512_STATE2_SZ 64
+#define ICP_QAT_HW_SHA3_512_STATE2_SZ 0
+#define ICP_QAT_HW_SHA3_224_STATE2_SZ 0
+#define ICP_QAT_HW_SHA3_384_STATE2_SZ 0
+#define ICP_QAT_HW_AES_XCBC_MAC_KEY_SZ 16
+#define ICP_QAT_HW_AES_CBC_MAC_KEY_SZ 16
+#define ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ 16
+#define ICP_QAT_HW_F9_IK_SZ 16
+#define ICP_QAT_HW_F9_FK_SZ 16
+#define ICP_QAT_HW_KASUMI_F9_STATE2_SZ (ICP_QAT_HW_F9_IK_SZ + \
+ ICP_QAT_HW_F9_FK_SZ)
+#define ICP_QAT_HW_AES_F9_STATE2_SZ ICP_QAT_HW_KASUMI_F9_STATE2_SZ
+#define ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ 24
+#define ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ 32
+#define ICP_QAT_HW_GALOIS_H_SZ 16
+#define ICP_QAT_HW_GALOIS_LEN_A_SZ 8
+#define ICP_QAT_HW_GALOIS_E_CTR0_SZ 16
+
+struct icp_qat_hw_auth_sha512 {
+ struct icp_qat_hw_auth_setup inner_setup;
+ uint8_t state1[ICP_QAT_HW_SHA512_STATE1_SZ];
+ struct icp_qat_hw_auth_setup outer_setup;
+ uint8_t state2[ICP_QAT_HW_SHA512_STATE2_SZ];
+};
+
+struct icp_qat_hw_auth_algo_blk {
+ struct icp_qat_hw_auth_sha512 sha;
+};
+
+#define ICP_QAT_HW_GALOIS_LEN_A_BITPOS 0
+#define ICP_QAT_HW_GALOIS_LEN_A_MASK 0xFFFFFFFF
+
+enum icp_qat_hw_cipher_algo {
+ ICP_QAT_HW_CIPHER_ALGO_NULL = 0,
+ ICP_QAT_HW_CIPHER_ALGO_DES = 1,
+ ICP_QAT_HW_CIPHER_ALGO_3DES = 2,
+ ICP_QAT_HW_CIPHER_ALGO_AES128 = 3,
+ ICP_QAT_HW_CIPHER_ALGO_AES192 = 4,
+ ICP_QAT_HW_CIPHER_ALGO_AES256 = 5,
+ ICP_QAT_HW_CIPHER_ALGO_ARC4 = 6,
+ ICP_QAT_HW_CIPHER_ALGO_KASUMI = 7,
+ ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2 = 8,
+ ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3 = 9,
+ ICP_QAT_HW_CIPHER_DELIMITER = 10
+};
+
+enum icp_qat_hw_cipher_mode {
+ ICP_QAT_HW_CIPHER_ECB_MODE = 0,
+ ICP_QAT_HW_CIPHER_CBC_MODE = 1,
+ ICP_QAT_HW_CIPHER_CTR_MODE = 2,
+ ICP_QAT_HW_CIPHER_F8_MODE = 3,
+ ICP_QAT_HW_CIPHER_XTS_MODE = 6,
+ ICP_QAT_HW_CIPHER_MODE_DELIMITER = 7
+};
+
+struct icp_qat_hw_cipher_config {
+ uint32_t val;
+ uint32_t reserved;
+};
+
+enum icp_qat_hw_cipher_dir {
+ ICP_QAT_HW_CIPHER_ENCRYPT = 0,
+ ICP_QAT_HW_CIPHER_DECRYPT = 1,
+};
+
+enum icp_qat_hw_cipher_convert {
+ ICP_QAT_HW_CIPHER_NO_CONVERT = 0,
+ ICP_QAT_HW_CIPHER_KEY_CONVERT = 1,
+};
+
+#define QAT_CIPHER_MODE_BITPOS 4
+#define QAT_CIPHER_MODE_MASK 0xF
+#define QAT_CIPHER_ALGO_BITPOS 0
+#define QAT_CIPHER_ALGO_MASK 0xF
+#define QAT_CIPHER_CONVERT_BITPOS 9
+#define QAT_CIPHER_CONVERT_MASK 0x1
+#define QAT_CIPHER_DIR_BITPOS 8
+#define QAT_CIPHER_DIR_MASK 0x1
+#define QAT_CIPHER_MODE_F8_KEY_SZ_MULT 2
+#define QAT_CIPHER_MODE_XTS_KEY_SZ_MULT 2
+#define ICP_QAT_HW_CIPHER_CONFIG_BUILD(mode, algo, convert, dir) \
+ (((mode & QAT_CIPHER_MODE_MASK) << QAT_CIPHER_MODE_BITPOS) | \
+ ((algo & QAT_CIPHER_ALGO_MASK) << QAT_CIPHER_ALGO_BITPOS) | \
+ ((convert & QAT_CIPHER_CONVERT_MASK) << QAT_CIPHER_CONVERT_BITPOS) | \
+ ((dir & QAT_CIPHER_DIR_MASK) << QAT_CIPHER_DIR_BITPOS))
+#define ICP_QAT_HW_DES_BLK_SZ 8
+#define ICP_QAT_HW_3DES_BLK_SZ 8
+#define ICP_QAT_HW_NULL_BLK_SZ 8
+#define ICP_QAT_HW_AES_BLK_SZ 16
+#define ICP_QAT_HW_KASUMI_BLK_SZ 8
+#define ICP_QAT_HW_SNOW_3G_BLK_SZ 8
+#define ICP_QAT_HW_ZUC_3G_BLK_SZ 8
+#define ICP_QAT_HW_NULL_KEY_SZ 256
+#define ICP_QAT_HW_DES_KEY_SZ 8
+#define ICP_QAT_HW_3DES_KEY_SZ 24
+#define ICP_QAT_HW_AES_128_KEY_SZ 16
+#define ICP_QAT_HW_AES_192_KEY_SZ 24
+#define ICP_QAT_HW_AES_256_KEY_SZ 32
+#define ICP_QAT_HW_AES_128_F8_KEY_SZ (ICP_QAT_HW_AES_128_KEY_SZ * \
+ QAT_CIPHER_MODE_F8_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_192_F8_KEY_SZ (ICP_QAT_HW_AES_192_KEY_SZ * \
+ QAT_CIPHER_MODE_F8_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_256_F8_KEY_SZ (ICP_QAT_HW_AES_256_KEY_SZ * \
+ QAT_CIPHER_MODE_F8_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_128_XTS_KEY_SZ (ICP_QAT_HW_AES_128_KEY_SZ * \
+ QAT_CIPHER_MODE_XTS_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_256_XTS_KEY_SZ (ICP_QAT_HW_AES_256_KEY_SZ * \
+ QAT_CIPHER_MODE_XTS_KEY_SZ_MULT)
+#define ICP_QAT_HW_KASUMI_KEY_SZ 16
+#define ICP_QAT_HW_KASUMI_F8_KEY_SZ (ICP_QAT_HW_KASUMI_KEY_SZ * \
+ QAT_CIPHER_MODE_F8_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_128_XTS_KEY_SZ (ICP_QAT_HW_AES_128_KEY_SZ * \
+ QAT_CIPHER_MODE_XTS_KEY_SZ_MULT)
+#define ICP_QAT_HW_AES_256_XTS_KEY_SZ (ICP_QAT_HW_AES_256_KEY_SZ * \
+ QAT_CIPHER_MODE_XTS_KEY_SZ_MULT)
+#define ICP_QAT_HW_ARC4_KEY_SZ 256
+#define ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ 16
+#define ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ 16
+#define ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ 16
+#define ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ 16
+#define ICP_QAT_HW_MODE_F8_NUM_REG_TO_CLEAR 2
+#define INIT_SHRAM_CONSTANTS_TABLE_SZ 1024
+
+struct icp_qat_hw_cipher_aes256_f8 {
+ struct icp_qat_hw_cipher_config cipher_config;
+ uint8_t key[ICP_QAT_HW_AES_256_F8_KEY_SZ];
+};
+
+struct icp_qat_hw_cipher_algo_blk {
+ struct icp_qat_hw_cipher_aes256_f8 aes;
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/icp_qat_uclo.h b/drivers/crypto/qat/qat_common/icp_qat_uclo.h
new file mode 100644
index 000000000000..2132a8cbc4ec
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/icp_qat_uclo.h
@@ -0,0 +1,377 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef __ICP_QAT_UCLO_H__
+#define __ICP_QAT_UCLO_H__
+
+#define ICP_QAT_AC_C_CPU_TYPE 0x00400000
+#define ICP_QAT_UCLO_MAX_AE 12
+#define ICP_QAT_UCLO_MAX_CTX 8
+#define ICP_QAT_UCLO_MAX_UIMAGE (ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX)
+#define ICP_QAT_UCLO_MAX_USTORE 0x4000
+#define ICP_QAT_UCLO_MAX_XFER_REG 128
+#define ICP_QAT_UCLO_MAX_GPR_REG 128
+#define ICP_QAT_UCLO_MAX_NN_REG 128
+#define ICP_QAT_UCLO_MAX_LMEM_REG 1024
+#define ICP_QAT_UCLO_AE_ALL_CTX 0xff
+#define ICP_QAT_UOF_OBJID_LEN 8
+#define ICP_QAT_UOF_FID 0xc6c2
+#define ICP_QAT_UOF_MAJVER 0x4
+#define ICP_QAT_UOF_MINVER 0x11
+#define ICP_QAT_UOF_NN_MODE_NOTCARE 0xff
+#define ICP_QAT_UOF_OBJS "UOF_OBJS"
+#define ICP_QAT_UOF_STRT "UOF_STRT"
+#define ICP_QAT_UOF_GTID "UOF_GTID"
+#define ICP_QAT_UOF_IMAG "UOF_IMAG"
+#define ICP_QAT_UOF_IMEM "UOF_IMEM"
+#define ICP_QAT_UOF_MSEG "UOF_MSEG"
+#define ICP_QAT_UOF_LOCAL_SCOPE 1
+#define ICP_QAT_UOF_INIT_EXPR 0
+#define ICP_QAT_UOF_INIT_REG 1
+#define ICP_QAT_UOF_INIT_REG_CTX 2
+#define ICP_QAT_UOF_INIT_EXPR_ENDIAN_SWAP 3
+
+#define ICP_QAT_CTX_MODE(ae_mode) ((ae_mode) & 0xf)
+#define ICP_QAT_NN_MODE(ae_mode) (((ae_mode) >> 0x4) & 0xf)
+#define ICP_QAT_SHARED_USTORE_MODE(ae_mode) (((ae_mode) >> 0xb) & 0x1)
+#define RELOADABLE_CTX_SHARED_MODE(ae_mode) (((ae_mode) >> 0xc) & 0x1)
+
+#define ICP_QAT_LOC_MEM0_MODE(ae_mode) (((ae_mode) >> 0x8) & 0x1)
+#define ICP_QAT_LOC_MEM1_MODE(ae_mode) (((ae_mode) >> 0x9) & 0x1)
+
+enum icp_qat_uof_mem_region {
+ ICP_QAT_UOF_SRAM_REGION = 0x0,
+ ICP_QAT_UOF_LMEM_REGION = 0x3,
+ ICP_QAT_UOF_UMEM_REGION = 0x5
+};
+
+enum icp_qat_uof_regtype {
+ ICP_NO_DEST,
+ ICP_GPA_REL,
+ ICP_GPA_ABS,
+ ICP_GPB_REL,
+ ICP_GPB_ABS,
+ ICP_SR_REL,
+ ICP_SR_RD_REL,
+ ICP_SR_WR_REL,
+ ICP_SR_ABS,
+ ICP_SR_RD_ABS,
+ ICP_SR_WR_ABS,
+ ICP_DR_REL,
+ ICP_DR_RD_REL,
+ ICP_DR_WR_REL,
+ ICP_DR_ABS,
+ ICP_DR_RD_ABS,
+ ICP_DR_WR_ABS,
+ ICP_LMEM,
+ ICP_LMEM0,
+ ICP_LMEM1,
+ ICP_NEIGH_REL,
+};
+
+struct icp_qat_uclo_page {
+ struct icp_qat_uclo_encap_page *encap_page;
+ struct icp_qat_uclo_region *region;
+ unsigned int flags;
+};
+
+struct icp_qat_uclo_region {
+ struct icp_qat_uclo_page *loaded;
+ struct icp_qat_uclo_page *page;
+};
+
+struct icp_qat_uclo_aeslice {
+ struct icp_qat_uclo_region *region;
+ struct icp_qat_uclo_page *page;
+ struct icp_qat_uclo_page *cur_page[ICP_QAT_UCLO_MAX_CTX];
+ struct icp_qat_uclo_encapme *encap_image;
+ unsigned int ctx_mask_assigned;
+ unsigned int new_uaddr[ICP_QAT_UCLO_MAX_CTX];
+};
+
+struct icp_qat_uclo_aedata {
+ unsigned int slice_num;
+ unsigned int eff_ustore_size;
+ struct icp_qat_uclo_aeslice ae_slices[ICP_QAT_UCLO_MAX_CTX];
+};
+
+struct icp_qat_uof_encap_obj {
+ char *beg_uof;
+ struct icp_qat_uof_objhdr *obj_hdr;
+ struct icp_qat_uof_chunkhdr *chunk_hdr;
+ struct icp_qat_uof_varmem_seg *var_mem_seg;
+};
+
+struct icp_qat_uclo_encap_uwblock {
+ unsigned int start_addr;
+ unsigned int words_num;
+ uint64_t micro_words;
+};
+
+struct icp_qat_uclo_encap_page {
+ unsigned int def_page;
+ unsigned int page_region;
+ unsigned int beg_addr_v;
+ unsigned int beg_addr_p;
+ unsigned int micro_words_num;
+ unsigned int uwblock_num;
+ struct icp_qat_uclo_encap_uwblock *uwblock;
+};
+
+struct icp_qat_uclo_encapme {
+ struct icp_qat_uof_image *img_ptr;
+ struct icp_qat_uclo_encap_page *page;
+ unsigned int ae_reg_num;
+ struct icp_qat_uof_ae_reg *ae_reg;
+ unsigned int init_regsym_num;
+ struct icp_qat_uof_init_regsym *init_regsym;
+ unsigned int sbreak_num;
+ struct icp_qat_uof_sbreak *sbreak;
+ unsigned int uwords_num;
+};
+
+struct icp_qat_uclo_init_mem_table {
+ unsigned int entry_num;
+ struct icp_qat_uof_initmem *init_mem;
+};
+
+struct icp_qat_uclo_objhdr {
+ char *file_buff;
+ unsigned int checksum;
+ unsigned int size;
+};
+
+struct icp_qat_uof_strtable {
+ unsigned int table_len;
+ unsigned int reserved;
+ uint64_t strings;
+};
+
+struct icp_qat_uclo_objhandle {
+ unsigned int prod_type;
+ unsigned int prod_rev;
+ struct icp_qat_uclo_objhdr *obj_hdr;
+ struct icp_qat_uof_encap_obj encap_uof_obj;
+ struct icp_qat_uof_strtable str_table;
+ struct icp_qat_uclo_encapme ae_uimage[ICP_QAT_UCLO_MAX_UIMAGE];
+ struct icp_qat_uclo_aedata ae_data[ICP_QAT_UCLO_MAX_AE];
+ struct icp_qat_uclo_init_mem_table init_mem_tab;
+ struct icp_qat_uof_batch_init *lm_init_tab[ICP_QAT_UCLO_MAX_AE];
+ struct icp_qat_uof_batch_init *umem_init_tab[ICP_QAT_UCLO_MAX_AE];
+ int uimage_num;
+ int uword_in_bytes;
+ int global_inited;
+ unsigned int ae_num;
+ unsigned int ustore_phy_size;
+ void *obj_buf;
+ uint64_t *uword_buf;
+};
+
+struct icp_qat_uof_uword_block {
+ unsigned int start_addr;
+ unsigned int words_num;
+ unsigned int uword_offset;
+ unsigned int reserved;
+};
+
+struct icp_qat_uof_filehdr {
+ unsigned short file_id;
+ unsigned short reserved1;
+ char min_ver;
+ char maj_ver;
+ unsigned short reserved2;
+ unsigned short max_chunks;
+ unsigned short num_chunks;
+};
+
+struct icp_qat_uof_filechunkhdr {
+ char chunk_id[ICP_QAT_UOF_OBJID_LEN];
+ unsigned int checksum;
+ unsigned int offset;
+ unsigned int size;
+};
+
+struct icp_qat_uof_objhdr {
+ unsigned int cpu_type;
+ unsigned short min_cpu_ver;
+ unsigned short max_cpu_ver;
+ short max_chunks;
+ short num_chunks;
+ unsigned int reserved1;
+ unsigned int reserved2;
+};
+
+struct icp_qat_uof_chunkhdr {
+ char chunk_id[ICP_QAT_UOF_OBJID_LEN];
+ unsigned int offset;
+ unsigned int size;
+};
+
+struct icp_qat_uof_memvar_attr {
+ unsigned int offset_in_byte;
+ unsigned int value;
+};
+
+struct icp_qat_uof_initmem {
+ unsigned int sym_name;
+ char region;
+ char scope;
+ unsigned short reserved1;
+ unsigned int addr;
+ unsigned int num_in_bytes;
+ unsigned int val_attr_num;
+};
+
+struct icp_qat_uof_init_regsym {
+ unsigned int sym_name;
+ char init_type;
+ char value_type;
+ char reg_type;
+ unsigned char ctx;
+ unsigned int reg_addr;
+ unsigned int value;
+};
+
+struct icp_qat_uof_varmem_seg {
+ unsigned int sram_base;
+ unsigned int sram_size;
+ unsigned int sram_alignment;
+ unsigned int sdram_base;
+ unsigned int sdram_size;
+ unsigned int sdram_alignment;
+ unsigned int sdram1_base;
+ unsigned int sdram1_size;
+ unsigned int sdram1_alignment;
+ unsigned int scratch_base;
+ unsigned int scratch_size;
+ unsigned int scratch_alignment;
+};
+
+struct icp_qat_uof_gtid {
+ char tool_id[ICP_QAT_UOF_OBJID_LEN];
+ int tool_ver;
+ unsigned int reserved1;
+ unsigned int reserved2;
+};
+
+struct icp_qat_uof_sbreak {
+ unsigned int page_num;
+ unsigned int virt_uaddr;
+ unsigned char sbreak_type;
+ unsigned char reg_type;
+ unsigned short reserved1;
+ unsigned int addr_offset;
+ unsigned int reg_addr;
+};
+
+struct icp_qat_uof_code_page {
+ unsigned int page_region;
+ unsigned int page_num;
+ unsigned char def_page;
+ unsigned char reserved2;
+ unsigned short reserved1;
+ unsigned int beg_addr_v;
+ unsigned int beg_addr_p;
+ unsigned int neigh_reg_tab_offset;
+ unsigned int uc_var_tab_offset;
+ unsigned int imp_var_tab_offset;
+ unsigned int imp_expr_tab_offset;
+ unsigned int code_area_offset;
+};
+
+struct icp_qat_uof_image {
+ unsigned int img_name;
+ unsigned int ae_assigned;
+ unsigned int ctx_assigned;
+ unsigned int cpu_type;
+ unsigned int entry_address;
+ unsigned int fill_pattern[2];
+ unsigned int reloadable_size;
+ unsigned char sensitivity;
+ unsigned char reserved;
+ unsigned short ae_mode;
+ unsigned short max_ver;
+ unsigned short min_ver;
+ unsigned short image_attrib;
+ unsigned short reserved2;
+ unsigned short page_region_num;
+ unsigned short numpages;
+ unsigned int reg_tab_offset;
+ unsigned int init_reg_sym_tab;
+ unsigned int sbreak_tab;
+ unsigned int app_metadata;
+};
+
+struct icp_qat_uof_objtable {
+ unsigned int entry_num;
+};
+
+struct icp_qat_uof_ae_reg {
+ unsigned int name;
+ unsigned int vis_name;
+ unsigned short type;
+ unsigned short addr;
+ unsigned short access_mode;
+ unsigned char visible;
+ unsigned char reserved1;
+ unsigned short ref_count;
+ unsigned short reserved2;
+ unsigned int xo_id;
+};
+
+struct icp_qat_uof_code_area {
+ unsigned int micro_words_num;
+ unsigned int uword_block_tab;
+};
+
+struct icp_qat_uof_batch_init {
+ unsigned int ae;
+ unsigned int addr;
+ unsigned int *value;
+ unsigned int size;
+ struct icp_qat_uof_batch_init *next;
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
new file mode 100644
index 000000000000..59df48872955
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_algs.c
@@ -0,0 +1,1038 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/module.h>
+#include <linux/slab.h>
+#include <linux/crypto.h>
+#include <crypto/aead.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include <crypto/hash.h>
+#include <crypto/algapi.h>
+#include <crypto/authenc.h>
+#include <crypto/rng.h>
+#include <linux/dma-mapping.h>
+#include "adf_accel_devices.h"
+#include "adf_transport.h"
+#include "adf_common_drv.h"
+#include "qat_crypto.h"
+#include "icp_qat_hw.h"
+#include "icp_qat_fw.h"
+#include "icp_qat_fw_la.h"
+
+#define QAT_AES_HW_CONFIG_ENC(alg) \
+ ICP_QAT_HW_CIPHER_CONFIG_BUILD(ICP_QAT_HW_CIPHER_CBC_MODE, alg, \
+ ICP_QAT_HW_CIPHER_NO_CONVERT, \
+ ICP_QAT_HW_CIPHER_ENCRYPT)
+
+#define QAT_AES_HW_CONFIG_DEC(alg) \
+ ICP_QAT_HW_CIPHER_CONFIG_BUILD(ICP_QAT_HW_CIPHER_CBC_MODE, alg, \
+ ICP_QAT_HW_CIPHER_KEY_CONVERT, \
+ ICP_QAT_HW_CIPHER_DECRYPT)
+
+static atomic_t active_dev;
+
+struct qat_alg_buf {
+ uint32_t len;
+ uint32_t resrvd;
+ uint64_t addr;
+} __packed;
+
+struct qat_alg_buf_list {
+ uint64_t resrvd;
+ uint32_t num_bufs;
+ uint32_t num_mapped_bufs;
+ struct qat_alg_buf bufers[];
+} __packed __aligned(64);
+
+/* Common content descriptor */
+struct qat_alg_cd {
+ union {
+ struct qat_enc { /* Encrypt content desc */
+ struct icp_qat_hw_cipher_algo_blk cipher;
+ struct icp_qat_hw_auth_algo_blk hash;
+ } qat_enc_cd;
+ struct qat_dec { /* Decrytp content desc */
+ struct icp_qat_hw_auth_algo_blk hash;
+ struct icp_qat_hw_cipher_algo_blk cipher;
+ } qat_dec_cd;
+ };
+} __aligned(64);
+
+#define MAX_AUTH_STATE_SIZE sizeof(struct icp_qat_hw_auth_algo_blk)
+
+struct qat_auth_state {
+ uint8_t data[MAX_AUTH_STATE_SIZE];
+} __aligned(64);
+
+struct qat_alg_session_ctx {
+ struct qat_alg_cd *enc_cd;
+ dma_addr_t enc_cd_paddr;
+ struct qat_alg_cd *dec_cd;
+ dma_addr_t dec_cd_paddr;
+ struct qat_auth_state *auth_hw_state_enc;
+ dma_addr_t auth_state_enc_paddr;
+ struct qat_auth_state *auth_hw_state_dec;
+ dma_addr_t auth_state_dec_paddr;
+ struct icp_qat_fw_la_bulk_req enc_fw_req_tmpl;
+ struct icp_qat_fw_la_bulk_req dec_fw_req_tmpl;
+ struct qat_crypto_instance *inst;
+ struct crypto_tfm *tfm;
+ struct crypto_shash *hash_tfm;
+ enum icp_qat_hw_auth_algo qat_hash_alg;
+ uint8_t salt[AES_BLOCK_SIZE];
+ spinlock_t lock; /* protects qat_alg_session_ctx struct */
+};
+
+static int get_current_node(void)
+{
+ return cpu_data(current_thread_info()->cpu).phys_proc_id;
+}
+
+static int qat_get_inter_state_size(enum icp_qat_hw_auth_algo qat_hash_alg)
+{
+ switch (qat_hash_alg) {
+ case ICP_QAT_HW_AUTH_ALGO_SHA1:
+ return ICP_QAT_HW_SHA1_STATE1_SZ;
+ case ICP_QAT_HW_AUTH_ALGO_SHA256:
+ return ICP_QAT_HW_SHA256_STATE1_SZ;
+ case ICP_QAT_HW_AUTH_ALGO_SHA512:
+ return ICP_QAT_HW_SHA512_STATE1_SZ;
+ default:
+ return -EFAULT;
+ };
+ return -EFAULT;
+}
+
+static int qat_alg_do_precomputes(struct icp_qat_hw_auth_algo_blk *hash,
+ struct qat_alg_session_ctx *ctx,
+ const uint8_t *auth_key,
+ unsigned int auth_keylen, uint8_t *auth_state)
+{
+ struct {
+ struct shash_desc shash;
+ char ctx[crypto_shash_descsize(ctx->hash_tfm)];
+ } desc;
+ struct sha1_state sha1;
+ struct sha256_state sha256;
+ struct sha512_state sha512;
+ int block_size = crypto_shash_blocksize(ctx->hash_tfm);
+ int digest_size = crypto_shash_digestsize(ctx->hash_tfm);
+ uint8_t *ipad = auth_state;
+ uint8_t *opad = ipad + block_size;
+ __be32 *hash_state_out;
+ __be64 *hash512_state_out;
+ int i, offset;
+
+ desc.shash.tfm = ctx->hash_tfm;
+ desc.shash.flags = 0x0;
+
+ if (auth_keylen > block_size) {
+ char buff[SHA512_BLOCK_SIZE];
+ int ret = crypto_shash_digest(&desc.shash, auth_key,
+ auth_keylen, buff);
+ if (ret)
+ return ret;
+
+ memcpy(ipad, buff, digest_size);
+ memcpy(opad, buff, digest_size);
+ memset(ipad + digest_size, 0, block_size - digest_size);
+ memset(opad + digest_size, 0, block_size - digest_size);
+ } else {
+ memcpy(ipad, auth_key, auth_keylen);
+ memcpy(opad, auth_key, auth_keylen);
+ memset(ipad + auth_keylen, 0, block_size - auth_keylen);
+ memset(opad + auth_keylen, 0, block_size - auth_keylen);
+ }
+
+ for (i = 0; i < block_size; i++) {
+ char *ipad_ptr = ipad + i;
+ char *opad_ptr = opad + i;
+ *ipad_ptr ^= 0x36;
+ *opad_ptr ^= 0x5C;
+ }
+
+ if (crypto_shash_init(&desc.shash))
+ return -EFAULT;
+
+ if (crypto_shash_update(&desc.shash, ipad, block_size))
+ return -EFAULT;
+
+ hash_state_out = (__be32 *)hash->sha.state1;
+ hash512_state_out = (__be64 *)hash_state_out;
+
+ switch (ctx->qat_hash_alg) {
+ case ICP_QAT_HW_AUTH_ALGO_SHA1:
+ if (crypto_shash_export(&desc.shash, &sha1))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 2; i++, hash_state_out++)
+ *hash_state_out = cpu_to_be32(*(sha1.state + i));
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA256:
+ if (crypto_shash_export(&desc.shash, &sha256))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 2; i++, hash_state_out++)
+ *hash_state_out = cpu_to_be32(*(sha256.state + i));
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA512:
+ if (crypto_shash_export(&desc.shash, &sha512))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 3; i++, hash512_state_out++)
+ *hash512_state_out = cpu_to_be64(*(sha512.state + i));
+ break;
+ default:
+ return -EFAULT;
+ }
+
+ if (crypto_shash_init(&desc.shash))
+ return -EFAULT;
+
+ if (crypto_shash_update(&desc.shash, opad, block_size))
+ return -EFAULT;
+
+ offset = round_up(qat_get_inter_state_size(ctx->qat_hash_alg), 8);
+ hash_state_out = (__be32 *)(hash->sha.state1 + offset);
+ hash512_state_out = (__be64 *)hash_state_out;
+
+ switch (ctx->qat_hash_alg) {
+ case ICP_QAT_HW_AUTH_ALGO_SHA1:
+ if (crypto_shash_export(&desc.shash, &sha1))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 2; i++, hash_state_out++)
+ *hash_state_out = cpu_to_be32(*(sha1.state + i));
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA256:
+ if (crypto_shash_export(&desc.shash, &sha256))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 2; i++, hash_state_out++)
+ *hash_state_out = cpu_to_be32(*(sha256.state + i));
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA512:
+ if (crypto_shash_export(&desc.shash, &sha512))
+ return -EFAULT;
+ for (i = 0; i < digest_size >> 3; i++, hash512_state_out++)
+ *hash512_state_out = cpu_to_be64(*(sha512.state + i));
+ break;
+ default:
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void qat_alg_init_common_hdr(struct icp_qat_fw_comn_req_hdr *header)
+{
+ header->hdr_flags =
+ ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET);
+ header->service_type = ICP_QAT_FW_COMN_REQ_CPM_FW_LA;
+ header->comn_req_flags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_CD_FLD_TYPE_64BIT_ADR,
+ QAT_COMN_PTR_TYPE_SGL);
+ ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_DIGEST_IN_BUFFER);
+ ICP_QAT_FW_LA_PARTIAL_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_PARTIAL_NONE);
+ ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(header->serv_specif_flags,
+ ICP_QAT_FW_CIPH_IV_16BYTE_DATA);
+ ICP_QAT_FW_LA_PROTO_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_NO_PROTO);
+ ICP_QAT_FW_LA_UPDATE_STATE_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_NO_UPDATE_STATE);
+}
+
+static int qat_alg_init_enc_session(struct qat_alg_session_ctx *ctx,
+ int alg, struct crypto_authenc_keys *keys)
+{
+ struct crypto_aead *aead_tfm = __crypto_aead_cast(ctx->tfm);
+ unsigned int digestsize = crypto_aead_crt(aead_tfm)->authsize;
+ struct qat_enc *enc_ctx = &ctx->enc_cd->qat_enc_cd;
+ struct icp_qat_hw_cipher_algo_blk *cipher = &enc_ctx->cipher;
+ struct icp_qat_hw_auth_algo_blk *hash =
+ (struct icp_qat_hw_auth_algo_blk *)((char *)enc_ctx +
+ sizeof(struct icp_qat_hw_auth_setup) + keys->enckeylen);
+ struct icp_qat_fw_la_bulk_req *req_tmpl = &ctx->enc_fw_req_tmpl;
+ struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars;
+ struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr;
+ void *ptr = &req_tmpl->cd_ctrl;
+ struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr;
+ struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr;
+ struct icp_qat_fw_la_auth_req_params *auth_param =
+ (struct icp_qat_fw_la_auth_req_params *)
+ ((char *)&req_tmpl->serv_specif_rqpars +
+ sizeof(struct icp_qat_fw_la_cipher_req_params));
+
+ /* CD setup */
+ cipher->aes.cipher_config.val = QAT_AES_HW_CONFIG_ENC(alg);
+ memcpy(cipher->aes.key, keys->enckey, keys->enckeylen);
+ hash->sha.inner_setup.auth_config.config =
+ ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1,
+ ctx->qat_hash_alg, digestsize);
+ hash->sha.inner_setup.auth_counter.counter =
+ cpu_to_be32(crypto_shash_blocksize(ctx->hash_tfm));
+
+ if (qat_alg_do_precomputes(hash, ctx, keys->authkey, keys->authkeylen,
+ (uint8_t *)ctx->auth_hw_state_enc))
+ return -EFAULT;
+
+ /* Request setup */
+ qat_alg_init_common_hdr(header);
+ header->service_cmd_id = ICP_QAT_FW_LA_CMD_CIPHER_HASH;
+ ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_RET_AUTH_RES);
+ ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
+ cd_pars->u.s.content_desc_addr = ctx->enc_cd_paddr;
+ cd_pars->u.s.content_desc_params_sz = sizeof(struct qat_alg_cd) >> 3;
+
+ /* Cipher CD config setup */
+ cipher_cd_ctrl->cipher_key_sz = keys->enckeylen >> 3;
+ cipher_cd_ctrl->cipher_state_sz = AES_BLOCK_SIZE >> 3;
+ cipher_cd_ctrl->cipher_cfg_offset = 0;
+ ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
+ ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_AUTH);
+ /* Auth CD config setup */
+ hash_cd_ctrl->hash_cfg_offset = ((char *)hash - (char *)cipher) >> 3;
+ hash_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;
+ hash_cd_ctrl->inner_res_sz = digestsize;
+ hash_cd_ctrl->final_sz = digestsize;
+
+ switch (ctx->qat_hash_alg) {
+ case ICP_QAT_HW_AUTH_ALGO_SHA1:
+ hash_cd_ctrl->inner_state1_sz =
+ round_up(ICP_QAT_HW_SHA1_STATE1_SZ, 8);
+ hash_cd_ctrl->inner_state2_sz =
+ round_up(ICP_QAT_HW_SHA1_STATE2_SZ, 8);
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA256:
+ hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA256_STATE1_SZ;
+ hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA256_STATE2_SZ;
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA512:
+ hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA512_STATE1_SZ;
+ hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA512_STATE2_SZ;
+ break;
+ default:
+ break;
+ }
+ hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset +
+ ((sizeof(struct icp_qat_hw_auth_setup) +
+ round_up(hash_cd_ctrl->inner_state1_sz, 8)) >> 3);
+ auth_param->u1.auth_partial_st_prefix = ctx->auth_state_enc_paddr +
+ sizeof(struct icp_qat_hw_auth_counter) +
+ round_up(hash_cd_ctrl->inner_state1_sz, 8);
+ ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_AUTH);
+ ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_DRAM_WR);
+ return 0;
+}
+
+static int qat_alg_init_dec_session(struct qat_alg_session_ctx *ctx,
+ int alg, struct crypto_authenc_keys *keys)
+{
+ struct crypto_aead *aead_tfm = __crypto_aead_cast(ctx->tfm);
+ unsigned int digestsize = crypto_aead_crt(aead_tfm)->authsize;
+ struct qat_dec *dec_ctx = &ctx->dec_cd->qat_dec_cd;
+ struct icp_qat_hw_auth_algo_blk *hash = &dec_ctx->hash;
+ struct icp_qat_hw_cipher_algo_blk *cipher =
+ (struct icp_qat_hw_cipher_algo_blk *)((char *)dec_ctx +
+ sizeof(struct icp_qat_hw_auth_setup) +
+ roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2);
+ struct icp_qat_fw_la_bulk_req *req_tmpl = &ctx->dec_fw_req_tmpl;
+ struct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars;
+ struct icp_qat_fw_comn_req_hdr *header = &req_tmpl->comn_hdr;
+ void *ptr = &req_tmpl->cd_ctrl;
+ struct icp_qat_fw_cipher_cd_ctrl_hdr *cipher_cd_ctrl = ptr;
+ struct icp_qat_fw_auth_cd_ctrl_hdr *hash_cd_ctrl = ptr;
+ struct icp_qat_fw_la_auth_req_params *auth_param =
+ (struct icp_qat_fw_la_auth_req_params *)
+ ((char *)&req_tmpl->serv_specif_rqpars +
+ sizeof(struct icp_qat_fw_la_cipher_req_params));
+
+ /* CD setup */
+ cipher->aes.cipher_config.val = QAT_AES_HW_CONFIG_DEC(alg);
+ memcpy(cipher->aes.key, keys->enckey, keys->enckeylen);
+ hash->sha.inner_setup.auth_config.config =
+ ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1,
+ ctx->qat_hash_alg,
+ digestsize);
+ hash->sha.inner_setup.auth_counter.counter =
+ cpu_to_be32(crypto_shash_blocksize(ctx->hash_tfm));
+
+ if (qat_alg_do_precomputes(hash, ctx, keys->authkey, keys->authkeylen,
+ (uint8_t *)ctx->auth_hw_state_dec))
+ return -EFAULT;
+
+ /* Request setup */
+ qat_alg_init_common_hdr(header);
+ header->service_cmd_id = ICP_QAT_FW_LA_CMD_HASH_CIPHER;
+ ICP_QAT_FW_LA_RET_AUTH_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_NO_RET_AUTH_RES);
+ ICP_QAT_FW_LA_CMP_AUTH_SET(header->serv_specif_flags,
+ ICP_QAT_FW_LA_CMP_AUTH_RES);
+ cd_pars->u.s.content_desc_addr = ctx->dec_cd_paddr;
+ cd_pars->u.s.content_desc_params_sz = sizeof(struct qat_alg_cd) >> 3;
+
+ /* Cipher CD config setup */
+ cipher_cd_ctrl->cipher_key_sz = keys->enckeylen >> 3;
+ cipher_cd_ctrl->cipher_state_sz = AES_BLOCK_SIZE >> 3;
+ cipher_cd_ctrl->cipher_cfg_offset =
+ (sizeof(struct icp_qat_hw_auth_setup) +
+ roundup(crypto_shash_digestsize(ctx->hash_tfm), 8) * 2) >> 3;
+ ICP_QAT_FW_COMN_CURR_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
+ ICP_QAT_FW_COMN_NEXT_ID_SET(cipher_cd_ctrl, ICP_QAT_FW_SLICE_DRAM_WR);
+
+ /* Auth CD config setup */
+ hash_cd_ctrl->hash_cfg_offset = 0;
+ hash_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;
+ hash_cd_ctrl->inner_res_sz = digestsize;
+ hash_cd_ctrl->final_sz = digestsize;
+
+ switch (ctx->qat_hash_alg) {
+ case ICP_QAT_HW_AUTH_ALGO_SHA1:
+ hash_cd_ctrl->inner_state1_sz =
+ round_up(ICP_QAT_HW_SHA1_STATE1_SZ, 8);
+ hash_cd_ctrl->inner_state2_sz =
+ round_up(ICP_QAT_HW_SHA1_STATE2_SZ, 8);
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA256:
+ hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA256_STATE1_SZ;
+ hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA256_STATE2_SZ;
+ break;
+ case ICP_QAT_HW_AUTH_ALGO_SHA512:
+ hash_cd_ctrl->inner_state1_sz = ICP_QAT_HW_SHA512_STATE1_SZ;
+ hash_cd_ctrl->inner_state2_sz = ICP_QAT_HW_SHA512_STATE2_SZ;
+ break;
+ default:
+ break;
+ }
+
+ hash_cd_ctrl->inner_state2_offset = hash_cd_ctrl->hash_cfg_offset +
+ ((sizeof(struct icp_qat_hw_auth_setup) +
+ round_up(hash_cd_ctrl->inner_state1_sz, 8)) >> 3);
+ auth_param->u1.auth_partial_st_prefix = ctx->auth_state_enc_paddr +
+ sizeof(struct icp_qat_hw_auth_counter) +
+ round_up(hash_cd_ctrl->inner_state1_sz, 8);
+ auth_param->auth_res_sz = digestsize;
+ ICP_QAT_FW_COMN_CURR_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_AUTH);
+ ICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
+ return 0;
+}
+
+static int qat_alg_init_sessions(struct qat_alg_session_ctx *ctx,
+ const uint8_t *key, unsigned int keylen)
+{
+ struct crypto_authenc_keys keys;
+ int alg;
+
+ if (crypto_rng_get_bytes(crypto_default_rng, ctx->salt, AES_BLOCK_SIZE))
+ return -EFAULT;
+
+ if (crypto_authenc_extractkeys(&keys, key, keylen))
+ goto bad_key;
+
+ switch (keys.enckeylen) {
+ case AES_KEYSIZE_128:
+ alg = ICP_QAT_HW_CIPHER_ALGO_AES128;
+ break;
+ case AES_KEYSIZE_192:
+ alg = ICP_QAT_HW_CIPHER_ALGO_AES192;
+ break;
+ case AES_KEYSIZE_256:
+ alg = ICP_QAT_HW_CIPHER_ALGO_AES256;
+ break;
+ default:
+ goto bad_key;
+ break;
+ }
+
+ if (qat_alg_init_enc_session(ctx, alg, &keys))
+ goto error;
+
+ if (qat_alg_init_dec_session(ctx, alg, &keys))
+ goto error;
+
+ return 0;
+bad_key:
+ crypto_tfm_set_flags(ctx->tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+error:
+ return -EFAULT;
+}
+
+static int qat_alg_setkey(struct crypto_aead *tfm, const uint8_t *key,
+ unsigned int keylen)
+{
+ struct qat_alg_session_ctx *ctx = crypto_aead_ctx(tfm);
+ struct device *dev;
+
+ spin_lock(&ctx->lock);
+ if (ctx->enc_cd) {
+ /* rekeying */
+ dev = &GET_DEV(ctx->inst->accel_dev);
+ memset(ctx->enc_cd, 0, sizeof(struct qat_alg_cd));
+ memset(ctx->dec_cd, 0, sizeof(struct qat_alg_cd));
+ memset(ctx->auth_hw_state_enc, 0,
+ sizeof(struct qat_auth_state));
+ memset(ctx->auth_hw_state_dec, 0,
+ sizeof(struct qat_auth_state));
+ memset(&ctx->enc_fw_req_tmpl, 0,
+ sizeof(struct icp_qat_fw_la_bulk_req));
+ memset(&ctx->dec_fw_req_tmpl, 0,
+ sizeof(struct icp_qat_fw_la_bulk_req));
+ } else {
+ /* new key */
+ int node = get_current_node();
+ struct qat_crypto_instance *inst =
+ qat_crypto_get_instance_node(node);
+ if (!inst) {
+ spin_unlock(&ctx->lock);
+ return -EINVAL;
+ }
+
+ dev = &GET_DEV(inst->accel_dev);
+ ctx->inst = inst;
+ ctx->enc_cd = dma_zalloc_coherent(dev,
+ sizeof(struct qat_alg_cd),
+ &ctx->enc_cd_paddr,
+ GFP_ATOMIC);
+ if (!ctx->enc_cd) {
+ spin_unlock(&ctx->lock);
+ return -ENOMEM;
+ }
+ ctx->dec_cd = dma_zalloc_coherent(dev,
+ sizeof(struct qat_alg_cd),
+ &ctx->dec_cd_paddr,
+ GFP_ATOMIC);
+ if (!ctx->dec_cd) {
+ spin_unlock(&ctx->lock);
+ goto out_free_enc;
+ }
+ ctx->auth_hw_state_enc =
+ dma_zalloc_coherent(dev, sizeof(struct qat_auth_state),
+ &ctx->auth_state_enc_paddr,
+ GFP_ATOMIC);
+ if (!ctx->auth_hw_state_enc) {
+ spin_unlock(&ctx->lock);
+ goto out_free_dec;
+ }
+ ctx->auth_hw_state_dec =
+ dma_zalloc_coherent(dev, sizeof(struct qat_auth_state),
+ &ctx->auth_state_dec_paddr,
+ GFP_ATOMIC);
+ if (!ctx->auth_hw_state_dec) {
+ spin_unlock(&ctx->lock);
+ goto out_free_auth_enc;
+ }
+ }
+ spin_unlock(&ctx->lock);
+ if (qat_alg_init_sessions(ctx, key, keylen))
+ goto out_free_all;
+
+ return 0;
+
+out_free_all:
+ dma_free_coherent(dev, sizeof(struct qat_auth_state),
+ ctx->auth_hw_state_dec, ctx->auth_state_dec_paddr);
+ ctx->auth_hw_state_dec = NULL;
+out_free_auth_enc:
+ dma_free_coherent(dev, sizeof(struct qat_auth_state),
+ ctx->auth_hw_state_enc, ctx->auth_state_enc_paddr);
+ ctx->auth_hw_state_enc = NULL;
+out_free_dec:
+ dma_free_coherent(dev, sizeof(struct qat_alg_cd),
+ ctx->dec_cd, ctx->dec_cd_paddr);
+ ctx->dec_cd = NULL;
+out_free_enc:
+ dma_free_coherent(dev, sizeof(struct qat_alg_cd),
+ ctx->enc_cd, ctx->enc_cd_paddr);
+ ctx->enc_cd = NULL;
+ return -ENOMEM;
+}
+
+static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ struct qat_crypto_request *qat_req)
+{
+ struct device *dev = &GET_DEV(inst->accel_dev);
+ struct qat_alg_buf_list *bl = qat_req->buf.bl;
+ struct qat_alg_buf_list *blout = qat_req->buf.blout;
+ dma_addr_t blp = qat_req->buf.blp;
+ dma_addr_t blpout = qat_req->buf.bloutp;
+ size_t sz = qat_req->buf.sz;
+ int i, bufs = bl->num_bufs;
+
+ for (i = 0; i < bl->num_bufs; i++)
+ dma_unmap_single(dev, bl->bufers[i].addr,
+ bl->bufers[i].len, DMA_BIDIRECTIONAL);
+
+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
+ kfree(bl);
+ if (blp != blpout) {
+ /* If out of place operation dma unmap only data */
+ int bufless = bufs - blout->num_mapped_bufs;
+
+ for (i = bufless; i < bufs; i++) {
+ dma_unmap_single(dev, blout->bufers[i].addr,
+ blout->bufers[i].len,
+ DMA_BIDIRECTIONAL);
+ }
+ dma_unmap_single(dev, blpout, sz, DMA_TO_DEVICE);
+ kfree(blout);
+ }
+}
+
+static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ struct scatterlist *assoc,
+ struct scatterlist *sgl,
+ struct scatterlist *sglout, uint8_t *iv,
+ uint8_t ivlen,
+ struct qat_crypto_request *qat_req)
+{
+ struct device *dev = &GET_DEV(inst->accel_dev);
+ int i, bufs = 0, n = sg_nents(sgl), assoc_n = sg_nents(assoc);
+ struct qat_alg_buf_list *bufl;
+ struct qat_alg_buf_list *buflout = NULL;
+ dma_addr_t blp;
+ dma_addr_t bloutp = 0;
+ struct scatterlist *sg;
+ size_t sz = sizeof(struct qat_alg_buf_list) +
+ ((1 + n + assoc_n) * sizeof(struct qat_alg_buf));
+
+ if (unlikely(!n))
+ return -EINVAL;
+
+ bufl = kmalloc_node(sz, GFP_ATOMIC, inst->accel_dev->numa_node);
+ if (unlikely(!bufl))
+ return -ENOMEM;
+
+ blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, blp)))
+ goto err;
+
+ for_each_sg(assoc, sg, assoc_n, i) {
+ bufl->bufers[bufs].addr = dma_map_single(dev,
+ sg_virt(sg),
+ sg->length,
+ DMA_BIDIRECTIONAL);
+ bufl->bufers[bufs].len = sg->length;
+ if (unlikely(dma_mapping_error(dev, bufl->bufers[bufs].addr)))
+ goto err;
+ bufs++;
+ }
+ bufl->bufers[bufs].addr = dma_map_single(dev, iv, ivlen,
+ DMA_BIDIRECTIONAL);
+ bufl->bufers[bufs].len = ivlen;
+ if (unlikely(dma_mapping_error(dev, bufl->bufers[bufs].addr)))
+ goto err;
+ bufs++;
+
+ for_each_sg(sgl, sg, n, i) {
+ int y = i + bufs;
+
+ bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ sg->length,
+ DMA_BIDIRECTIONAL);
+ bufl->bufers[y].len = sg->length;
+ if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr)))
+ goto err;
+ }
+ bufl->num_bufs = n + bufs;
+ qat_req->buf.bl = bufl;
+ qat_req->buf.blp = blp;
+ qat_req->buf.sz = sz;
+ /* Handle out of place operation */
+ if (sgl != sglout) {
+ struct qat_alg_buf *bufers;
+
+ buflout = kmalloc_node(sz, GFP_ATOMIC,
+ inst->accel_dev->numa_node);
+ if (unlikely(!buflout))
+ goto err;
+ bloutp = dma_map_single(dev, buflout, sz, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev, bloutp)))
+ goto err;
+ bufers = buflout->bufers;
+ /* For out of place operation dma map only data and
+ * reuse assoc mapping and iv */
+ for (i = 0; i < bufs; i++) {
+ bufers[i].len = bufl->bufers[i].len;
+ bufers[i].addr = bufl->bufers[i].addr;
+ }
+ for_each_sg(sglout, sg, n, i) {
+ int y = i + bufs;
+
+ bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ sg->length,
+ DMA_BIDIRECTIONAL);
+ buflout->bufers[y].len = sg->length;
+ if (unlikely(dma_mapping_error(dev, bufers[y].addr)))
+ goto err;
+ }
+ buflout->num_bufs = n + bufs;
+ buflout->num_mapped_bufs = n;
+ qat_req->buf.blout = buflout;
+ qat_req->buf.bloutp = bloutp;
+ } else {
+ /* Otherwise set the src and dst to the same address */
+ qat_req->buf.bloutp = qat_req->buf.blp;
+ }
+ return 0;
+err:
+ dev_err(dev, "Failed to map buf for dma\n");
+ for_each_sg(sgl, sg, n + bufs, i) {
+ if (!dma_mapping_error(dev, bufl->bufers[i].addr)) {
+ dma_unmap_single(dev, bufl->bufers[i].addr,
+ bufl->bufers[i].len,
+ DMA_BIDIRECTIONAL);
+ }
+ }
+ if (!dma_mapping_error(dev, blp))
+ dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
+ kfree(bufl);
+ if (sgl != sglout && buflout) {
+ for_each_sg(sglout, sg, n, i) {
+ int y = i + bufs;
+
+ if (!dma_mapping_error(dev, buflout->bufers[y].addr))
+ dma_unmap_single(dev, buflout->bufers[y].addr,
+ buflout->bufers[y].len,
+ DMA_BIDIRECTIONAL);
+ }
+ if (!dma_mapping_error(dev, bloutp))
+ dma_unmap_single(dev, bloutp, sz, DMA_TO_DEVICE);
+ kfree(buflout);
+ }
+ return -ENOMEM;
+}
+
+void qat_alg_callback(void *resp)
+{
+ struct icp_qat_fw_la_resp *qat_resp = resp;
+ struct qat_crypto_request *qat_req =
+ (void *)(__force long)qat_resp->opaque_data;
+ struct qat_alg_session_ctx *ctx = qat_req->ctx;
+ struct qat_crypto_instance *inst = ctx->inst;
+ struct aead_request *areq = qat_req->areq;
+ uint8_t stat_filed = qat_resp->comn_resp.comn_status;
+ int res = 0, qat_res = ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(stat_filed);
+
+ qat_alg_free_bufl(inst, qat_req);
+ if (unlikely(qat_res != ICP_QAT_FW_COMN_STATUS_FLAG_OK))
+ res = -EBADMSG;
+ areq->base.complete(&areq->base, res);
+}
+
+static int qat_alg_dec(struct aead_request *areq)
+{
+ struct crypto_aead *aead_tfm = crypto_aead_reqtfm(areq);
+ struct crypto_tfm *tfm = crypto_aead_tfm(aead_tfm);
+ struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct qat_crypto_request *qat_req = aead_request_ctx(areq);
+ struct icp_qat_fw_la_cipher_req_params *cipher_param;
+ struct icp_qat_fw_la_auth_req_params *auth_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+ int digst_size = crypto_aead_crt(aead_tfm)->authsize;
+ int ret, ctr = 0;
+
+ ret = qat_alg_sgl_to_bufl(ctx->inst, areq->assoc, areq->src, areq->dst,
+ areq->iv, AES_BLOCK_SIZE, qat_req);
+ if (unlikely(ret))
+ return ret;
+
+ msg = &qat_req->req;
+ *msg = ctx->dec_fw_req_tmpl;
+ qat_req->ctx = ctx;
+ qat_req->areq = areq;
+ qat_req->req.comn_mid.opaque_data = (uint64_t)(__force long)qat_req;
+ qat_req->req.comn_mid.src_data_addr = qat_req->buf.blp;
+ qat_req->req.comn_mid.dest_data_addr = qat_req->buf.bloutp;
+ cipher_param = (void *)&qat_req->req.serv_specif_rqpars;
+ cipher_param->cipher_length = areq->cryptlen - digst_size;
+ cipher_param->cipher_offset = areq->assoclen + AES_BLOCK_SIZE;
+ memcpy(cipher_param->u.cipher_IV_array, areq->iv, AES_BLOCK_SIZE);
+ auth_param = (void *)((uint8_t *)cipher_param + sizeof(*cipher_param));
+ auth_param->auth_off = 0;
+ auth_param->auth_len = areq->assoclen +
+ cipher_param->cipher_length + AES_BLOCK_SIZE;
+ do {
+ ret = adf_send_message(ctx->inst->sym_tx, (uint32_t *)msg);
+ } while (ret == -EAGAIN && ctr++ < 10);
+
+ if (ret == -EAGAIN) {
+ qat_alg_free_bufl(ctx->inst, qat_req);
+ return -EBUSY;
+ }
+ return -EINPROGRESS;
+}
+
+static int qat_alg_enc_internal(struct aead_request *areq, uint8_t *iv,
+ int enc_iv)
+{
+ struct crypto_aead *aead_tfm = crypto_aead_reqtfm(areq);
+ struct crypto_tfm *tfm = crypto_aead_tfm(aead_tfm);
+ struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct qat_crypto_request *qat_req = aead_request_ctx(areq);
+ struct icp_qat_fw_la_cipher_req_params *cipher_param;
+ struct icp_qat_fw_la_auth_req_params *auth_param;
+ struct icp_qat_fw_la_bulk_req *msg;
+ int ret, ctr = 0;
+
+ ret = qat_alg_sgl_to_bufl(ctx->inst, areq->assoc, areq->src, areq->dst,
+ iv, AES_BLOCK_SIZE, qat_req);
+ if (unlikely(ret))
+ return ret;
+
+ msg = &qat_req->req;
+ *msg = ctx->enc_fw_req_tmpl;
+ qat_req->ctx = ctx;
+ qat_req->areq = areq;
+ qat_req->req.comn_mid.opaque_data = (uint64_t)(__force long)qat_req;
+ qat_req->req.comn_mid.src_data_addr = qat_req->buf.blp;
+ qat_req->req.comn_mid.dest_data_addr = qat_req->buf.bloutp;
+ cipher_param = (void *)&qat_req->req.serv_specif_rqpars;
+ auth_param = (void *)((uint8_t *)cipher_param + sizeof(*cipher_param));
+
+ if (enc_iv) {
+ cipher_param->cipher_length = areq->cryptlen + AES_BLOCK_SIZE;
+ cipher_param->cipher_offset = areq->assoclen;
+ } else {
+ memcpy(cipher_param->u.cipher_IV_array, iv, AES_BLOCK_SIZE);
+ cipher_param->cipher_length = areq->cryptlen;
+ cipher_param->cipher_offset = areq->assoclen + AES_BLOCK_SIZE;
+ }
+ auth_param->auth_off = 0;
+ auth_param->auth_len = areq->assoclen + areq->cryptlen + AES_BLOCK_SIZE;
+
+ do {
+ ret = adf_send_message(ctx->inst->sym_tx, (uint32_t *)msg);
+ } while (ret == -EAGAIN && ctr++ < 10);
+
+ if (ret == -EAGAIN) {
+ qat_alg_free_bufl(ctx->inst, qat_req);
+ return -EBUSY;
+ }
+ return -EINPROGRESS;
+}
+
+static int qat_alg_enc(struct aead_request *areq)
+{
+ return qat_alg_enc_internal(areq, areq->iv, 0);
+}
+
+static int qat_alg_genivenc(struct aead_givcrypt_request *req)
+{
+ struct crypto_aead *aead_tfm = crypto_aead_reqtfm(&req->areq);
+ struct crypto_tfm *tfm = crypto_aead_tfm(aead_tfm);
+ struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm);
+ __be64 seq;
+
+ memcpy(req->giv, ctx->salt, AES_BLOCK_SIZE);
+ seq = cpu_to_be64(req->seq);
+ memcpy(req->giv + AES_BLOCK_SIZE - sizeof(uint64_t),
+ &seq, sizeof(uint64_t));
+ return qat_alg_enc_internal(&req->areq, req->giv, 1);
+}
+
+static int qat_alg_init(struct crypto_tfm *tfm,
+ enum icp_qat_hw_auth_algo hash, const char *hash_name)
+{
+ struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ memset(ctx, '\0', sizeof(*ctx));
+ ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0);
+ if (IS_ERR(ctx->hash_tfm))
+ return -EFAULT;
+ spin_lock_init(&ctx->lock);
+ ctx->qat_hash_alg = hash;
+ tfm->crt_aead.reqsize = sizeof(struct aead_request) +
+ sizeof(struct qat_crypto_request);
+ ctx->tfm = tfm;
+ return 0;
+}
+
+static int qat_alg_sha1_init(struct crypto_tfm *tfm)
+{
+ return qat_alg_init(tfm, ICP_QAT_HW_AUTH_ALGO_SHA1, "sha1");
+}
+
+static int qat_alg_sha256_init(struct crypto_tfm *tfm)
+{
+ return qat_alg_init(tfm, ICP_QAT_HW_AUTH_ALGO_SHA256, "sha256");
+}
+
+static int qat_alg_sha512_init(struct crypto_tfm *tfm)
+{
+ return qat_alg_init(tfm, ICP_QAT_HW_AUTH_ALGO_SHA512, "sha512");
+}
+
+static void qat_alg_exit(struct crypto_tfm *tfm)
+{
+ struct qat_alg_session_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct qat_crypto_instance *inst = ctx->inst;
+ struct device *dev;
+
+ if (!IS_ERR(ctx->hash_tfm))
+ crypto_free_shash(ctx->hash_tfm);
+
+ if (!inst)
+ return;
+
+ dev = &GET_DEV(inst->accel_dev);
+ if (ctx->enc_cd)
+ dma_free_coherent(dev, sizeof(struct qat_alg_cd),
+ ctx->enc_cd, ctx->enc_cd_paddr);
+ if (ctx->dec_cd)
+ dma_free_coherent(dev, sizeof(struct qat_alg_cd),
+ ctx->dec_cd, ctx->dec_cd_paddr);
+ if (ctx->auth_hw_state_enc)
+ dma_free_coherent(dev, sizeof(struct qat_auth_state),
+ ctx->auth_hw_state_enc,
+ ctx->auth_state_enc_paddr);
+
+ if (ctx->auth_hw_state_dec)
+ dma_free_coherent(dev, sizeof(struct qat_auth_state),
+ ctx->auth_hw_state_dec,
+ ctx->auth_state_dec_paddr);
+
+ qat_crypto_put_instance(inst);
+}
+
+static struct crypto_alg qat_algs[] = { {
+ .cra_name = "authenc(hmac(sha1),cbc(aes))",
+ .cra_driver_name = "qat_aes_cbc_hmac_sha1",
+ .cra_priority = 4001,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct qat_alg_session_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_aead_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = qat_alg_sha1_init,
+ .cra_exit = qat_alg_exit,
+ .cra_u = {
+ .aead = {
+ .setkey = qat_alg_setkey,
+ .decrypt = qat_alg_dec,
+ .encrypt = qat_alg_enc,
+ .givencrypt = qat_alg_genivenc,
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA1_DIGEST_SIZE,
+ },
+ },
+}, {
+ .cra_name = "authenc(hmac(sha256),cbc(aes))",
+ .cra_driver_name = "qat_aes_cbc_hmac_sha256",
+ .cra_priority = 4001,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct qat_alg_session_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_aead_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = qat_alg_sha256_init,
+ .cra_exit = qat_alg_exit,
+ .cra_u = {
+ .aead = {
+ .setkey = qat_alg_setkey,
+ .decrypt = qat_alg_dec,
+ .encrypt = qat_alg_enc,
+ .givencrypt = qat_alg_genivenc,
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA256_DIGEST_SIZE,
+ },
+ },
+}, {
+ .cra_name = "authenc(hmac(sha512),cbc(aes))",
+ .cra_driver_name = "qat_aes_cbc_hmac_sha512",
+ .cra_priority = 4001,
+ .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct qat_alg_session_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_aead_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = qat_alg_sha512_init,
+ .cra_exit = qat_alg_exit,
+ .cra_u = {
+ .aead = {
+ .setkey = qat_alg_setkey,
+ .decrypt = qat_alg_dec,
+ .encrypt = qat_alg_enc,
+ .givencrypt = qat_alg_genivenc,
+ .ivsize = AES_BLOCK_SIZE,
+ .maxauthsize = SHA512_DIGEST_SIZE,
+ },
+ },
+} };
+
+int qat_algs_register(void)
+{
+ if (atomic_add_return(1, &active_dev) == 1) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(qat_algs); i++)
+ qat_algs[i].cra_flags = CRYPTO_ALG_TYPE_AEAD |
+ CRYPTO_ALG_ASYNC;
+ return crypto_register_algs(qat_algs, ARRAY_SIZE(qat_algs));
+ }
+ return 0;
+}
+
+int qat_algs_unregister(void)
+{
+ if (atomic_sub_return(1, &active_dev) == 0)
+ return crypto_unregister_algs(qat_algs, ARRAY_SIZE(qat_algs));
+ return 0;
+}
+
+int qat_algs_init(void)
+{
+ atomic_set(&active_dev, 0);
+ crypto_get_default_rng();
+ return 0;
+}
+
+void qat_algs_exit(void)
+{
+ crypto_put_default_rng();
+}
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c
new file mode 100644
index 000000000000..0d59bcb50de1
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_crypto.c
@@ -0,0 +1,284 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/module.h>
+#include <linux/slab.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_transport.h"
+#include "adf_cfg.h"
+#include "adf_cfg_strings.h"
+#include "qat_crypto.h"
+#include "icp_qat_fw.h"
+
+#define SEC ADF_KERNEL_SEC
+
+static struct service_hndl qat_crypto;
+
+void qat_crypto_put_instance(struct qat_crypto_instance *inst)
+{
+ if (atomic_sub_return(1, &inst->refctr) == 0)
+ adf_dev_put(inst->accel_dev);
+}
+
+static int qat_crypto_free_instances(struct adf_accel_dev *accel_dev)
+{
+ struct qat_crypto_instance *inst;
+ struct list_head *list_ptr, *tmp;
+ int i;
+
+ list_for_each_safe(list_ptr, tmp, &accel_dev->crypto_list) {
+ inst = list_entry(list_ptr, struct qat_crypto_instance, list);
+
+ for (i = 0; i < atomic_read(&inst->refctr); i++)
+ qat_crypto_put_instance(inst);
+
+ if (inst->sym_tx)
+ adf_remove_ring(inst->sym_tx);
+
+ if (inst->sym_rx)
+ adf_remove_ring(inst->sym_rx);
+
+ if (inst->pke_tx)
+ adf_remove_ring(inst->pke_tx);
+
+ if (inst->pke_rx)
+ adf_remove_ring(inst->pke_rx);
+
+ if (inst->rnd_tx)
+ adf_remove_ring(inst->rnd_tx);
+
+ if (inst->rnd_rx)
+ adf_remove_ring(inst->rnd_rx);
+
+ list_del(list_ptr);
+ kfree(inst);
+ }
+ return 0;
+}
+
+struct qat_crypto_instance *qat_crypto_get_instance_node(int node)
+{
+ struct adf_accel_dev *accel_dev = NULL;
+ struct qat_crypto_instance *inst_best = NULL;
+ struct list_head *itr;
+ unsigned long best = ~0;
+
+ list_for_each(itr, adf_devmgr_get_head()) {
+ accel_dev = list_entry(itr, struct adf_accel_dev, list);
+ if (accel_dev->numa_node == node && adf_dev_started(accel_dev))
+ break;
+ accel_dev = NULL;
+ }
+ if (!accel_dev) {
+ pr_err("QAT: Could not find device on give node\n");
+ accel_dev = adf_devmgr_get_first();
+ }
+ if (!accel_dev || !adf_dev_started(accel_dev))
+ return NULL;
+
+ list_for_each(itr, &accel_dev->crypto_list) {
+ struct qat_crypto_instance *inst;
+ unsigned long cur;
+
+ inst = list_entry(itr, struct qat_crypto_instance, list);
+ cur = atomic_read(&inst->refctr);
+ if (best > cur) {
+ inst_best = inst;
+ best = cur;
+ }
+ }
+ if (inst_best) {
+ if (atomic_add_return(1, &inst_best->refctr) == 1) {
+ if (adf_dev_get(accel_dev)) {
+ atomic_dec(&inst_best->refctr);
+ pr_err("QAT: Could increment dev refctr\n");
+ return NULL;
+ }
+ }
+ }
+ return inst_best;
+}
+
+static int qat_crypto_create_instances(struct adf_accel_dev *accel_dev)
+{
+ int i;
+ unsigned long bank;
+ unsigned long num_inst, num_msg_sym, num_msg_asym;
+ int msg_size;
+ struct qat_crypto_instance *inst;
+ char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+
+ INIT_LIST_HEAD(&accel_dev->crypto_list);
+ strlcpy(key, ADF_NUM_CY, sizeof(key));
+
+ if (adf_cfg_get_param_value(accel_dev, SEC, key, val))
+ return -EFAULT;
+
+ if (kstrtoul(val, 0, &num_inst))
+ return -EFAULT;
+
+ for (i = 0; i < num_inst; i++) {
+ inst = kzalloc_node(sizeof(*inst), GFP_KERNEL,
+ accel_dev->numa_node);
+ if (!inst)
+ goto err;
+
+ list_add_tail(&inst->list, &accel_dev->crypto_list);
+ inst->id = i;
+ atomic_set(&inst->refctr, 0);
+ inst->accel_dev = accel_dev;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, i);
+ if (adf_cfg_get_param_value(accel_dev, SEC, key, val))
+ goto err;
+
+ if (kstrtoul(val, 10, &bank))
+ goto err;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, i);
+ if (adf_cfg_get_param_value(accel_dev, SEC, key, val))
+ goto err;
+
+ if (kstrtoul(val, 10, &num_msg_sym))
+ goto err;
+ num_msg_sym = num_msg_sym >> 1;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, i);
+ if (adf_cfg_get_param_value(accel_dev, SEC, key, val))
+ goto err;
+
+ if (kstrtoul(val, 10, &num_msg_asym))
+ goto err;
+ num_msg_asym = num_msg_asym >> 1;
+
+ msg_size = ICP_QAT_FW_REQ_DEFAULT_SZ;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_sym,
+ msg_size, key, NULL, 0, &inst->sym_tx))
+ goto err;
+
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_RND_TX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_asym,
+ msg_size, key, NULL, 0, &inst->rnd_tx))
+ goto err;
+
+ msg_size = msg_size >> 1;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_asym,
+ msg_size, key, NULL, 0, &inst->pke_tx))
+ goto err;
+
+ msg_size = ICP_QAT_FW_RESP_DEFAULT_SZ;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_sym,
+ msg_size, key, qat_alg_callback, 0,
+ &inst->sym_rx))
+ goto err;
+
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_RND_RX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_asym,
+ msg_size, key, qat_alg_callback, 0,
+ &inst->rnd_rx))
+ goto err;
+
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, i);
+ if (adf_create_ring(accel_dev, SEC, bank, num_msg_asym,
+ msg_size, key, qat_alg_callback, 0,
+ &inst->pke_rx))
+ goto err;
+ }
+ return 0;
+err:
+ qat_crypto_free_instances(accel_dev);
+ return -ENOMEM;
+}
+
+static int qat_crypto_init(struct adf_accel_dev *accel_dev)
+{
+ if (qat_crypto_create_instances(accel_dev))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int qat_crypto_shutdown(struct adf_accel_dev *accel_dev)
+{
+ return qat_crypto_free_instances(accel_dev);
+}
+
+static int qat_crypto_event_handler(struct adf_accel_dev *accel_dev,
+ enum adf_event event)
+{
+ int ret;
+
+ switch (event) {
+ case ADF_EVENT_INIT:
+ ret = qat_crypto_init(accel_dev);
+ break;
+ case ADF_EVENT_SHUTDOWN:
+ ret = qat_crypto_shutdown(accel_dev);
+ break;
+ case ADF_EVENT_RESTARTING:
+ case ADF_EVENT_RESTARTED:
+ case ADF_EVENT_START:
+ case ADF_EVENT_STOP:
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
+int qat_crypto_register(void)
+{
+ memset(&qat_crypto, 0, sizeof(qat_crypto));
+ qat_crypto.event_hld = qat_crypto_event_handler;
+ qat_crypto.name = "qat_crypto";
+ return adf_service_register(&qat_crypto);
+}
+
+int qat_crypto_unregister(void)
+{
+ return adf_service_unregister(&qat_crypto);
+}
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.h b/drivers/crypto/qat/qat_common/qat_crypto.h
new file mode 100644
index 000000000000..ab8468d11ddb
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_crypto.h
@@ -0,0 +1,83 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef _QAT_CRYPTO_INSTANCE_H_
+#define _QAT_CRYPTO_INSTANCE_H_
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include "adf_accel_devices.h"
+#include "icp_qat_fw_la.h"
+
+struct qat_crypto_instance {
+ struct adf_etr_ring_data *sym_tx;
+ struct adf_etr_ring_data *sym_rx;
+ struct adf_etr_ring_data *pke_tx;
+ struct adf_etr_ring_data *pke_rx;
+ struct adf_etr_ring_data *rnd_tx;
+ struct adf_etr_ring_data *rnd_rx;
+ struct adf_accel_dev *accel_dev;
+ struct list_head list;
+ unsigned long state;
+ int id;
+ atomic_t refctr;
+};
+
+struct qat_crypto_request_buffs {
+ struct qat_alg_buf_list *bl;
+ dma_addr_t blp;
+ struct qat_alg_buf_list *blout;
+ dma_addr_t bloutp;
+ size_t sz;
+};
+
+struct qat_crypto_request {
+ struct icp_qat_fw_la_bulk_req req;
+ struct qat_alg_session_ctx *ctx;
+ struct aead_request *areq;
+ struct qat_crypto_request_buffs buf;
+};
+#endif
diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c
new file mode 100644
index 000000000000..9b8a31521ff3
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_hal.c
@@ -0,0 +1,1393 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/slab.h>
+
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "icp_qat_hal.h"
+#include "icp_qat_uclo.h"
+
+#define BAD_REGADDR 0xffff
+#define MAX_RETRY_TIMES 10000
+#define INIT_CTX_ARB_VALUE 0x0
+#define INIT_CTX_ENABLE_VALUE 0x0
+#define INIT_PC_VALUE 0x0
+#define INIT_WAKEUP_EVENTS_VALUE 0x1
+#define INIT_SIG_EVENTS_VALUE 0x1
+#define INIT_CCENABLE_VALUE 0x2000
+#define RST_CSR_QAT_LSB 20
+#define RST_CSR_AE_LSB 0
+#define MC_TIMESTAMP_ENABLE (0x1 << 7)
+
+#define IGNORE_W1C_MASK ((~(1 << CE_BREAKPOINT_BITPOS)) & \
+ (~(1 << CE_CNTL_STORE_PARITY_ERROR_BITPOS)) & \
+ (~(1 << CE_REG_PAR_ERR_BITPOS)))
+#define INSERT_IMMED_GPRA_CONST(inst, const_val) \
+ (inst = ((inst & 0xFFFF00C03FFull) | \
+ ((((const_val) << 12) & 0x0FF00000ull) | \
+ (((const_val) << 10) & 0x0003FC00ull))))
+#define INSERT_IMMED_GPRB_CONST(inst, const_val) \
+ (inst = ((inst & 0xFFFF00FFF00ull) | \
+ ((((const_val) << 12) & 0x0FF00000ull) | \
+ (((const_val) << 0) & 0x000000FFull))))
+
+#define AE(handle, ae) handle->hal_handle->aes[ae]
+
+static const uint64_t inst_4b[] = {
+ 0x0F0400C0000ull, 0x0F4400C0000ull, 0x0F040000300ull, 0x0F440000300ull,
+ 0x0FC066C0000ull, 0x0F0000C0300ull, 0x0F0000C0300ull, 0x0F0000C0300ull,
+ 0x0A021000000ull
+};
+
+static const uint64_t inst[] = {
+ 0x0F0000C0000ull, 0x0F000000380ull, 0x0D805000011ull, 0x0FC082C0300ull,
+ 0x0F0000C0300ull, 0x0F0000C0300ull, 0x0F0000C0300ull, 0x0F0000C0300ull,
+ 0x0A0643C0000ull, 0x0BAC0000301ull, 0x0D802000101ull, 0x0F0000C0001ull,
+ 0x0FC066C0001ull, 0x0F0000C0300ull, 0x0F0000C0300ull, 0x0F0000C0300ull,
+ 0x0F000400300ull, 0x0A0610C0000ull, 0x0BAC0000301ull, 0x0D804400101ull,
+ 0x0A0580C0000ull, 0x0A0581C0000ull, 0x0A0582C0000ull, 0x0A0583C0000ull,
+ 0x0A0584C0000ull, 0x0A0585C0000ull, 0x0A0586C0000ull, 0x0A0587C0000ull,
+ 0x0A0588C0000ull, 0x0A0589C0000ull, 0x0A058AC0000ull, 0x0A058BC0000ull,
+ 0x0A058CC0000ull, 0x0A058DC0000ull, 0x0A058EC0000ull, 0x0A058FC0000ull,
+ 0x0A05C0C0000ull, 0x0A05C1C0000ull, 0x0A05C2C0000ull, 0x0A05C3C0000ull,
+ 0x0A05C4C0000ull, 0x0A05C5C0000ull, 0x0A05C6C0000ull, 0x0A05C7C0000ull,
+ 0x0A05C8C0000ull, 0x0A05C9C0000ull, 0x0A05CAC0000ull, 0x0A05CBC0000ull,
+ 0x0A05CCC0000ull, 0x0A05CDC0000ull, 0x0A05CEC0000ull, 0x0A05CFC0000ull,
+ 0x0A0400C0000ull, 0x0B0400C0000ull, 0x0A0401C0000ull, 0x0B0401C0000ull,
+ 0x0A0402C0000ull, 0x0B0402C0000ull, 0x0A0403C0000ull, 0x0B0403C0000ull,
+ 0x0A0404C0000ull, 0x0B0404C0000ull, 0x0A0405C0000ull, 0x0B0405C0000ull,
+ 0x0A0406C0000ull, 0x0B0406C0000ull, 0x0A0407C0000ull, 0x0B0407C0000ull,
+ 0x0A0408C0000ull, 0x0B0408C0000ull, 0x0A0409C0000ull, 0x0B0409C0000ull,
+ 0x0A040AC0000ull, 0x0B040AC0000ull, 0x0A040BC0000ull, 0x0B040BC0000ull,
+ 0x0A040CC0000ull, 0x0B040CC0000ull, 0x0A040DC0000ull, 0x0B040DC0000ull,
+ 0x0A040EC0000ull, 0x0B040EC0000ull, 0x0A040FC0000ull, 0x0B040FC0000ull,
+ 0x0D81581C010ull, 0x0E000010000ull, 0x0E000010000ull,
+};
+
+void qat_hal_set_live_ctx(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask)
+{
+ AE(handle, ae).live_ctx_mask = ctx_mask;
+}
+
+#define CSR_RETRY_TIMES 500
+static int qat_hal_rd_ae_csr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int csr,
+ unsigned int *value)
+{
+ unsigned int iterations = CSR_RETRY_TIMES;
+
+ do {
+ *value = GET_AE_CSR(handle, ae, csr);
+ if (!(GET_AE_CSR(handle, ae, LOCAL_CSR_STATUS) & LCS_STATUS))
+ return 0;
+ } while (iterations--);
+
+ pr_err("QAT: Read CSR timeout\n");
+ return -EFAULT;
+}
+
+static int qat_hal_wr_ae_csr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int csr,
+ unsigned int value)
+{
+ unsigned int iterations = CSR_RETRY_TIMES;
+
+ do {
+ SET_AE_CSR(handle, ae, csr, value);
+ if (!(GET_AE_CSR(handle, ae, LOCAL_CSR_STATUS) & LCS_STATUS))
+ return 0;
+ } while (iterations--);
+
+ pr_err("QAT: Write CSR Timeout\n");
+ return -EFAULT;
+}
+
+static void qat_hal_get_wakeup_event(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ unsigned int *events)
+{
+ unsigned int cur_ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CSR_CTX_POINTER, &cur_ctx);
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, ctx);
+ qat_hal_rd_ae_csr(handle, ae, CTX_WAKEUP_EVENTS_INDIRECT, events);
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, cur_ctx);
+}
+
+static int qat_hal_wait_cycles(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int cycles,
+ int chk_inactive)
+{
+ unsigned int base_cnt = 0, cur_cnt = 0;
+ unsigned int csr = (1 << ACS_ABO_BITPOS);
+ int times = MAX_RETRY_TIMES;
+ int elapsed_cycles = 0;
+
+ qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT, &base_cnt);
+ base_cnt &= 0xffff;
+ while ((int)cycles > elapsed_cycles && times--) {
+ if (chk_inactive)
+ qat_hal_rd_ae_csr(handle, ae, ACTIVE_CTX_STATUS, &csr);
+
+ qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT, &cur_cnt);
+ cur_cnt &= 0xffff;
+ elapsed_cycles = cur_cnt - base_cnt;
+
+ if (elapsed_cycles < 0)
+ elapsed_cycles += 0x10000;
+
+ /* ensure at least 8 time cycles elapsed in wait_cycles */
+ if (elapsed_cycles >= 8 && !(csr & (1 << ACS_ABO_BITPOS)))
+ return 0;
+ }
+ if (!times) {
+ pr_err("QAT: wait_num_cycles time out\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+#define CLR_BIT(wrd, bit) (wrd & ~(1 << bit))
+#define SET_BIT(wrd, bit) (wrd | 1 << bit)
+
+int qat_hal_set_ae_ctx_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char mode)
+{
+ unsigned int csr, new_csr;
+
+ if ((mode != 4) && (mode != 8)) {
+ pr_err("QAT: bad ctx mode=%d\n", mode);
+ return -EINVAL;
+ }
+
+ /* Sets the accelaration engine context mode to either four or eight */
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &csr);
+ csr = IGNORE_W1C_MASK & csr;
+ new_csr = (mode == 4) ?
+ SET_BIT(csr, CE_INUSE_CONTEXTS_BITPOS) :
+ CLR_BIT(csr, CE_INUSE_CONTEXTS_BITPOS);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, new_csr);
+ return 0;
+}
+
+int qat_hal_set_ae_nn_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char mode)
+{
+ unsigned int csr, new_csr;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &csr);
+ csr &= IGNORE_W1C_MASK;
+
+ new_csr = (mode) ?
+ SET_BIT(csr, CE_NN_MODE_BITPOS) :
+ CLR_BIT(csr, CE_NN_MODE_BITPOS);
+
+ if (new_csr != csr)
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, new_csr);
+
+ return 0;
+}
+
+int qat_hal_set_ae_lm_mode(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, enum icp_qat_uof_regtype lm_type,
+ unsigned char mode)
+{
+ unsigned int csr, new_csr;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &csr);
+ csr &= IGNORE_W1C_MASK;
+ switch (lm_type) {
+ case ICP_LMEM0:
+ new_csr = (mode) ?
+ SET_BIT(csr, CE_LMADDR_0_GLOBAL_BITPOS) :
+ CLR_BIT(csr, CE_LMADDR_0_GLOBAL_BITPOS);
+ break;
+ case ICP_LMEM1:
+ new_csr = (mode) ?
+ SET_BIT(csr, CE_LMADDR_1_GLOBAL_BITPOS) :
+ CLR_BIT(csr, CE_LMADDR_1_GLOBAL_BITPOS);
+ break;
+ default:
+ pr_err("QAT: lmType = 0x%x\n", lm_type);
+ return -EINVAL;
+ }
+
+ if (new_csr != csr)
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, new_csr);
+ return 0;
+}
+
+static unsigned short qat_hal_get_reg_addr(unsigned int type,
+ unsigned short reg_num)
+{
+ unsigned short reg_addr;
+
+ switch (type) {
+ case ICP_GPA_ABS:
+ case ICP_GPB_ABS:
+ reg_addr = 0x80 | (reg_num & 0x7f);
+ break;
+ case ICP_GPA_REL:
+ case ICP_GPB_REL:
+ reg_addr = reg_num & 0x1f;
+ break;
+ case ICP_SR_RD_REL:
+ case ICP_SR_WR_REL:
+ case ICP_SR_REL:
+ reg_addr = 0x180 | (reg_num & 0x1f);
+ break;
+ case ICP_SR_ABS:
+ reg_addr = 0x140 | ((reg_num & 0x3) << 1);
+ break;
+ case ICP_DR_RD_REL:
+ case ICP_DR_WR_REL:
+ case ICP_DR_REL:
+ reg_addr = 0x1c0 | (reg_num & 0x1f);
+ break;
+ case ICP_DR_ABS:
+ reg_addr = 0x100 | ((reg_num & 0x3) << 1);
+ break;
+ case ICP_NEIGH_REL:
+ reg_addr = 0x280 | (reg_num & 0x1f);
+ break;
+ case ICP_LMEM0:
+ reg_addr = 0x200;
+ break;
+ case ICP_LMEM1:
+ reg_addr = 0x220;
+ break;
+ case ICP_NO_DEST:
+ reg_addr = 0x300 | (reg_num & 0xff);
+ break;
+ default:
+ reg_addr = BAD_REGADDR;
+ break;
+ }
+ return reg_addr;
+}
+
+void qat_hal_reset(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned int ae_reset_csr;
+
+ ae_reset_csr = GET_GLB_CSR(handle, ICP_RESET);
+ ae_reset_csr |= handle->hal_handle->ae_mask << RST_CSR_AE_LSB;
+ ae_reset_csr |= handle->hal_handle->slice_mask << RST_CSR_QAT_LSB;
+ SET_GLB_CSR(handle, ICP_RESET, ae_reset_csr);
+}
+
+static void qat_hal_wr_indr_csr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask,
+ unsigned int ae_csr, unsigned int csr_val)
+{
+ unsigned int ctx, cur_ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CSR_CTX_POINTER, &cur_ctx);
+
+ for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++) {
+ if (!(ctx_mask & (1 << ctx)))
+ continue;
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, ctx);
+ qat_hal_wr_ae_csr(handle, ae, ae_csr, csr_val);
+ }
+
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, cur_ctx);
+}
+
+static void qat_hal_rd_indr_csr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ unsigned int ae_csr, unsigned int *csr_val)
+{
+ unsigned int cur_ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CSR_CTX_POINTER, &cur_ctx);
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, ctx);
+ qat_hal_rd_ae_csr(handle, ae, ae_csr, csr_val);
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, cur_ctx);
+}
+
+static void qat_hal_put_sig_event(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask,
+ unsigned int events)
+{
+ unsigned int ctx, cur_ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CSR_CTX_POINTER, &cur_ctx);
+ for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++) {
+ if (!(ctx_mask & (1 << ctx)))
+ continue;
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, ctx);
+ qat_hal_wr_ae_csr(handle, ae, CTX_SIG_EVENTS_INDIRECT, events);
+ }
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, cur_ctx);
+}
+
+static void qat_hal_put_wakeup_event(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask,
+ unsigned int events)
+{
+ unsigned int ctx, cur_ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CSR_CTX_POINTER, &cur_ctx);
+ for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++) {
+ if (!(ctx_mask & (1 << ctx)))
+ continue;
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, ctx);
+ qat_hal_wr_ae_csr(handle, ae, CTX_WAKEUP_EVENTS_INDIRECT,
+ events);
+ }
+ qat_hal_wr_ae_csr(handle, ae, CSR_CTX_POINTER, cur_ctx);
+}
+
+static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned int base_cnt, cur_cnt;
+ unsigned char ae;
+ unsigned int times = MAX_RETRY_TIMES;
+
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!(handle->hal_handle->ae_mask & (1 << ae)))
+ continue;
+
+ qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT,
+ (unsigned int *)&base_cnt);
+ base_cnt &= 0xffff;
+
+ do {
+ qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT,
+ (unsigned int *)&cur_cnt);
+ cur_cnt &= 0xffff;
+ } while (times-- && (cur_cnt == base_cnt));
+
+ if (!times) {
+ pr_err("QAT: AE%d is inactive!!\n", ae);
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static void qat_hal_reset_timestamp(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned int misc_ctl;
+ unsigned char ae;
+
+ /* stop the timestamp timers */
+ misc_ctl = GET_GLB_CSR(handle, MISC_CONTROL);
+ if (misc_ctl & MC_TIMESTAMP_ENABLE)
+ SET_GLB_CSR(handle, MISC_CONTROL, misc_ctl &
+ (~MC_TIMESTAMP_ENABLE));
+
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!(handle->hal_handle->ae_mask & (1 << ae)))
+ continue;
+ qat_hal_wr_ae_csr(handle, ae, TIMESTAMP_LOW, 0);
+ qat_hal_wr_ae_csr(handle, ae, TIMESTAMP_HIGH, 0);
+ }
+ /* start timestamp timers */
+ SET_GLB_CSR(handle, MISC_CONTROL, misc_ctl | MC_TIMESTAMP_ENABLE);
+}
+
+#define ESRAM_AUTO_TINIT (1<<2)
+#define ESRAM_AUTO_TINIT_DONE (1<<3)
+#define ESRAM_AUTO_INIT_USED_CYCLES (1640)
+#define ESRAM_AUTO_INIT_CSR_OFFSET 0xC1C
+static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
+{
+ void __iomem *csr_addr = handle->hal_ep_csr_addr_v +
+ ESRAM_AUTO_INIT_CSR_OFFSET;
+ unsigned int csr_val, times = 30;
+
+ csr_val = ADF_CSR_RD(csr_addr, 0);
+ if ((csr_val & ESRAM_AUTO_TINIT) && (csr_val & ESRAM_AUTO_TINIT_DONE))
+ return 0;
+
+ csr_val = ADF_CSR_RD(csr_addr, 0);
+ csr_val |= ESRAM_AUTO_TINIT;
+ ADF_CSR_WR(csr_addr, 0, csr_val);
+
+ do {
+ qat_hal_wait_cycles(handle, 0, ESRAM_AUTO_INIT_USED_CYCLES, 0);
+ csr_val = ADF_CSR_RD(csr_addr, 0);
+ } while (!(csr_val & ESRAM_AUTO_TINIT_DONE) && times--);
+ if ((!times)) {
+ pr_err("QAT: Fail to init eSram!\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+#define SHRAM_INIT_CYCLES 2060
+int qat_hal_clr_reset(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned int ae_reset_csr;
+ unsigned char ae;
+ unsigned int clk_csr;
+ unsigned int times = 100;
+ unsigned int csr;
+
+ /* write to the reset csr */
+ ae_reset_csr = GET_GLB_CSR(handle, ICP_RESET);
+ ae_reset_csr &= ~(handle->hal_handle->ae_mask << RST_CSR_AE_LSB);
+ ae_reset_csr &= ~(handle->hal_handle->slice_mask << RST_CSR_QAT_LSB);
+ do {
+ SET_GLB_CSR(handle, ICP_RESET, ae_reset_csr);
+ if (!(times--))
+ goto out_err;
+ csr = GET_GLB_CSR(handle, ICP_RESET);
+ } while ((handle->hal_handle->ae_mask |
+ (handle->hal_handle->slice_mask << RST_CSR_QAT_LSB)) & csr);
+ /* enable clock */
+ clk_csr = GET_GLB_CSR(handle, ICP_GLOBAL_CLK_ENABLE);
+ clk_csr |= handle->hal_handle->ae_mask << 0;
+ clk_csr |= handle->hal_handle->slice_mask << 20;
+ SET_GLB_CSR(handle, ICP_GLOBAL_CLK_ENABLE, clk_csr);
+ if (qat_hal_check_ae_alive(handle))
+ goto out_err;
+
+ /* Set undefined power-up/reset states to reasonable default values */
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!(handle->hal_handle->ae_mask & (1 << ae)))
+ continue;
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES,
+ INIT_CTX_ENABLE_VALUE);
+ qat_hal_wr_indr_csr(handle, ae, ICP_QAT_UCLO_AE_ALL_CTX,
+ CTX_STS_INDIRECT,
+ handle->hal_handle->upc_mask &
+ INIT_PC_VALUE);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ARB_CNTL, INIT_CTX_ARB_VALUE);
+ qat_hal_wr_ae_csr(handle, ae, CC_ENABLE, INIT_CCENABLE_VALUE);
+ qat_hal_put_wakeup_event(handle, ae,
+ ICP_QAT_UCLO_AE_ALL_CTX,
+ INIT_WAKEUP_EVENTS_VALUE);
+ qat_hal_put_sig_event(handle, ae,
+ ICP_QAT_UCLO_AE_ALL_CTX,
+ INIT_SIG_EVENTS_VALUE);
+ }
+ if (qat_hal_init_esram(handle))
+ goto out_err;
+ if (qat_hal_wait_cycles(handle, 0, SHRAM_INIT_CYCLES, 0))
+ goto out_err;
+ qat_hal_reset_timestamp(handle);
+
+ return 0;
+out_err:
+ pr_err("QAT: failed to get device out of reset\n");
+ return -EFAULT;
+}
+
+static void qat_hal_disable_ctx(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask)
+{
+ unsigned int ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx);
+ ctx &= IGNORE_W1C_MASK &
+ (~((ctx_mask & ICP_QAT_UCLO_AE_ALL_CTX) << CE_ENABLE_BITPOS));
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx);
+}
+
+static uint64_t qat_hal_parity_64bit(uint64_t word)
+{
+ word ^= word >> 1;
+ word ^= word >> 2;
+ word ^= word >> 4;
+ word ^= word >> 8;
+ word ^= word >> 16;
+ word ^= word >> 32;
+ return word & 1;
+}
+
+static uint64_t qat_hal_set_uword_ecc(uint64_t uword)
+{
+ uint64_t bit0_mask = 0xff800007fffULL, bit1_mask = 0x1f801ff801fULL,
+ bit2_mask = 0xe387e0781e1ULL, bit3_mask = 0x7cb8e388e22ULL,
+ bit4_mask = 0xaf5b2c93244ULL, bit5_mask = 0xf56d5525488ULL,
+ bit6_mask = 0xdaf69a46910ULL;
+
+ /* clear the ecc bits */
+ uword &= ~(0x7fULL << 0x2C);
+ uword |= qat_hal_parity_64bit(bit0_mask & uword) << 0x2C;
+ uword |= qat_hal_parity_64bit(bit1_mask & uword) << 0x2D;
+ uword |= qat_hal_parity_64bit(bit2_mask & uword) << 0x2E;
+ uword |= qat_hal_parity_64bit(bit3_mask & uword) << 0x2F;
+ uword |= qat_hal_parity_64bit(bit4_mask & uword) << 0x30;
+ uword |= qat_hal_parity_64bit(bit5_mask & uword) << 0x31;
+ uword |= qat_hal_parity_64bit(bit6_mask & uword) << 0x32;
+ return uword;
+}
+
+void qat_hal_wr_uwords(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int uaddr,
+ unsigned int words_num, uint64_t *uword)
+{
+ unsigned int ustore_addr;
+ unsigned int i;
+
+ qat_hal_rd_ae_csr(handle, ae, USTORE_ADDRESS, &ustore_addr);
+ uaddr |= UA_ECS;
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
+ for (i = 0; i < words_num; i++) {
+ unsigned int uwrd_lo, uwrd_hi;
+ uint64_t tmp;
+
+ tmp = qat_hal_set_uword_ecc(uword[i]);
+ uwrd_lo = (unsigned int)(tmp & 0xffffffff);
+ uwrd_hi = (unsigned int)(tmp >> 0x20);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_LOWER, uwrd_lo);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_UPPER, uwrd_hi);
+ }
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, ustore_addr);
+}
+
+static void qat_hal_enable_ctx(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask)
+{
+ unsigned int ctx;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx);
+ ctx &= IGNORE_W1C_MASK;
+ ctx_mask &= (ctx & CE_INUSE_CONTEXTS) ? 0x55 : 0xFF;
+ ctx |= (ctx_mask << CE_ENABLE_BITPOS);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx);
+}
+
+static int qat_hal_clear_gpr(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned char ae;
+ unsigned int ctx_mask = ICP_QAT_UCLO_AE_ALL_CTX;
+ int times = MAX_RETRY_TIMES;
+ unsigned int csr_val = 0;
+ unsigned short reg;
+ unsigned int savctx = 0;
+ int ret = 0;
+
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!(handle->hal_handle->ae_mask & (1 << ae)))
+ continue;
+ for (reg = 0; reg < ICP_QAT_UCLO_MAX_GPR_REG; reg++) {
+ qat_hal_init_rd_xfer(handle, ae, 0, ICP_SR_RD_ABS,
+ reg, 0);
+ qat_hal_init_rd_xfer(handle, ae, 0, ICP_DR_RD_ABS,
+ reg, 0);
+ }
+ qat_hal_rd_ae_csr(handle, ae, AE_MISC_CONTROL, &csr_val);
+ csr_val &= ~(1 << MMC_SHARE_CS_BITPOS);
+ qat_hal_wr_ae_csr(handle, ae, AE_MISC_CONTROL, csr_val);
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &csr_val);
+ csr_val &= IGNORE_W1C_MASK;
+ csr_val |= CE_NN_MODE;
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, csr_val);
+ qat_hal_wr_uwords(handle, ae, 0, ARRAY_SIZE(inst),
+ (uint64_t *)inst);
+ qat_hal_wr_indr_csr(handle, ae, ctx_mask, CTX_STS_INDIRECT,
+ handle->hal_handle->upc_mask &
+ INIT_PC_VALUE);
+ qat_hal_rd_ae_csr(handle, ae, ACTIVE_CTX_STATUS, &savctx);
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS, 0);
+ qat_hal_put_wakeup_event(handle, ae, ctx_mask, XCWE_VOLUNTARY);
+ qat_hal_wr_indr_csr(handle, ae, ctx_mask,
+ CTX_SIG_EVENTS_INDIRECT, 0);
+ qat_hal_wr_ae_csr(handle, ae, CTX_SIG_EVENTS_ACTIVE, 0);
+ qat_hal_enable_ctx(handle, ae, ctx_mask);
+ }
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!(handle->hal_handle->ae_mask & (1 << ae)))
+ continue;
+ /* wait for AE to finish */
+ do {
+ ret = qat_hal_wait_cycles(handle, ae, 20, 1);
+ } while (ret && times--);
+
+ if (!times) {
+ pr_err("QAT: clear GPR of AE %d failed", ae);
+ return -EINVAL;
+ }
+ qat_hal_disable_ctx(handle, ae, ctx_mask);
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS,
+ savctx & ACS_ACNO);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES,
+ INIT_CTX_ENABLE_VALUE);
+ qat_hal_wr_indr_csr(handle, ae, ctx_mask, CTX_STS_INDIRECT,
+ handle->hal_handle->upc_mask &
+ INIT_PC_VALUE);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ARB_CNTL, INIT_CTX_ARB_VALUE);
+ qat_hal_wr_ae_csr(handle, ae, CC_ENABLE, INIT_CCENABLE_VALUE);
+ qat_hal_put_wakeup_event(handle, ae, ctx_mask,
+ INIT_WAKEUP_EVENTS_VALUE);
+ qat_hal_put_sig_event(handle, ae, ctx_mask,
+ INIT_SIG_EVENTS_VALUE);
+ }
+ return 0;
+}
+
+#define ICP_DH895XCC_AE_OFFSET 0x20000
+#define ICP_DH895XCC_CAP_OFFSET (ICP_DH895XCC_AE_OFFSET + 0x10000)
+#define LOCAL_TO_XFER_REG_OFFSET 0x800
+#define ICP_DH895XCC_EP_OFFSET 0x3a000
+#define ICP_DH895XCC_PMISC_BAR 1
+int qat_hal_init(struct adf_accel_dev *accel_dev)
+{
+ unsigned char ae;
+ unsigned int max_en_ae_id = 0;
+ struct icp_qat_fw_loader_handle *handle;
+ struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct adf_bar *bar = &pci_info->pci_bars[ADF_DH895XCC_PMISC_BAR];
+
+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->hal_cap_g_ctl_csr_addr_v = bar->virt_addr +
+ ICP_DH895XCC_CAP_OFFSET;
+ handle->hal_cap_ae_xfer_csr_addr_v = bar->virt_addr +
+ ICP_DH895XCC_AE_OFFSET;
+ handle->hal_ep_csr_addr_v = bar->virt_addr + ICP_DH895XCC_EP_OFFSET;
+ handle->hal_cap_ae_local_csr_addr_v =
+ handle->hal_cap_ae_xfer_csr_addr_v + LOCAL_TO_XFER_REG_OFFSET;
+
+ handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL);
+ if (!handle->hal_handle)
+ goto out_hal_handle;
+ handle->hal_handle->revision_id = accel_dev->accel_pci_dev.revid;
+ handle->hal_handle->ae_mask = hw_data->ae_mask;
+ handle->hal_handle->slice_mask = hw_data->accel_mask;
+ /* create AE objects */
+ handle->hal_handle->upc_mask = 0x1ffff;
+ handle->hal_handle->max_ustore = 0x4000;
+ for (ae = 0; ae < ICP_QAT_UCLO_MAX_AE; ae++) {
+ if (!(hw_data->ae_mask & (1 << ae)))
+ continue;
+ handle->hal_handle->aes[ae].free_addr = 0;
+ handle->hal_handle->aes[ae].free_size =
+ handle->hal_handle->max_ustore;
+ handle->hal_handle->aes[ae].ustore_size =
+ handle->hal_handle->max_ustore;
+ handle->hal_handle->aes[ae].live_ctx_mask =
+ ICP_QAT_UCLO_AE_ALL_CTX;
+ max_en_ae_id = ae;
+ }
+ handle->hal_handle->ae_max_num = max_en_ae_id + 1;
+ /* take all AEs out of reset */
+ if (qat_hal_clr_reset(handle)) {
+ pr_err("QAT: qat_hal_clr_reset error\n");
+ goto out_err;
+ }
+ if (qat_hal_clear_gpr(handle))
+ goto out_err;
+ /* Set SIGNATURE_ENABLE[0] to 0x1 in order to enable ALU_OUT csr */
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ unsigned int csr_val = 0;
+
+ if (!(hw_data->ae_mask & (1 << ae)))
+ continue;
+ qat_hal_rd_ae_csr(handle, ae, SIGNATURE_ENABLE, &csr_val);
+ csr_val |= 0x1;
+ qat_hal_wr_ae_csr(handle, ae, SIGNATURE_ENABLE, csr_val);
+ }
+ accel_dev->fw_loader->fw_loader = handle;
+ return 0;
+
+out_err:
+ kfree(handle->hal_handle);
+out_hal_handle:
+ kfree(handle);
+ return -EFAULT;
+}
+
+void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle)
+{
+ if (!handle)
+ return;
+ kfree(handle->hal_handle);
+ kfree(handle);
+}
+
+void qat_hal_start(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
+ unsigned int ctx_mask)
+{
+ qat_hal_put_wakeup_event(handle, ae, (~ctx_mask) &
+ ICP_QAT_UCLO_AE_ALL_CTX, 0x10000);
+ qat_hal_enable_ctx(handle, ae, ctx_mask);
+}
+
+void qat_hal_stop(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
+ unsigned int ctx_mask)
+{
+ qat_hal_disable_ctx(handle, ae, ctx_mask);
+}
+
+void qat_hal_set_pc(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int ctx_mask, unsigned int upc)
+{
+ qat_hal_wr_indr_csr(handle, ae, ctx_mask, CTX_STS_INDIRECT,
+ handle->hal_handle->upc_mask & upc);
+}
+
+static void qat_hal_get_uwords(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int uaddr,
+ unsigned int words_num, uint64_t *uword)
+{
+ unsigned int i, uwrd_lo, uwrd_hi;
+ unsigned int ustore_addr, misc_control;
+
+ qat_hal_rd_ae_csr(handle, ae, AE_MISC_CONTROL, &misc_control);
+ qat_hal_wr_ae_csr(handle, ae, AE_MISC_CONTROL,
+ misc_control & 0xfffffffb);
+ qat_hal_rd_ae_csr(handle, ae, USTORE_ADDRESS, &ustore_addr);
+ uaddr |= UA_ECS;
+ for (i = 0; i < words_num; i++) {
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
+ uaddr++;
+ qat_hal_rd_ae_csr(handle, ae, USTORE_DATA_LOWER, &uwrd_lo);
+ qat_hal_rd_ae_csr(handle, ae, USTORE_DATA_UPPER, &uwrd_hi);
+ uword[i] = uwrd_hi;
+ uword[i] = (uword[i] << 0x20) | uwrd_lo;
+ }
+ qat_hal_wr_ae_csr(handle, ae, AE_MISC_CONTROL, misc_control);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, ustore_addr);
+}
+
+void qat_hal_wr_umem(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int uaddr,
+ unsigned int words_num, unsigned int *data)
+{
+ unsigned int i, ustore_addr;
+
+ qat_hal_rd_ae_csr(handle, ae, USTORE_ADDRESS, &ustore_addr);
+ uaddr |= UA_ECS;
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
+ for (i = 0; i < words_num; i++) {
+ unsigned int uwrd_lo, uwrd_hi, tmp;
+
+ uwrd_lo = ((data[i] & 0xfff0000) << 4) | (0x3 << 18) |
+ ((data[i] & 0xff00) << 2) |
+ (0x3 << 8) | (data[i] & 0xff);
+ uwrd_hi = (0xf << 4) | ((data[i] & 0xf0000000) >> 28);
+ uwrd_hi |= (hweight32(data[i] & 0xffff) & 0x1) << 8;
+ tmp = ((data[i] >> 0x10) & 0xffff);
+ uwrd_hi |= (hweight32(tmp) & 0x1) << 9;
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_LOWER, uwrd_lo);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_UPPER, uwrd_hi);
+ }
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, ustore_addr);
+}
+
+#define MAX_EXEC_INST 100
+static int qat_hal_exec_micro_inst(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ uint64_t *micro_inst, unsigned int inst_num,
+ int code_off, unsigned int max_cycle,
+ unsigned int *endpc)
+{
+ uint64_t savuwords[MAX_EXEC_INST];
+ unsigned int ind_lm_addr0, ind_lm_addr1;
+ unsigned int ind_lm_addr_byte0, ind_lm_addr_byte1;
+ unsigned int ind_cnt_sig;
+ unsigned int ind_sig, act_sig;
+ unsigned int csr_val = 0, newcsr_val;
+ unsigned int savctx;
+ unsigned int savcc, wakeup_events, savpc;
+ unsigned int ctxarb_ctl, ctx_enables;
+
+ if ((inst_num > handle->hal_handle->max_ustore) || !micro_inst) {
+ pr_err("QAT: invalid instruction num %d\n", inst_num);
+ return -EINVAL;
+ }
+ /* save current context */
+ qat_hal_rd_indr_csr(handle, ae, ctx, LM_ADDR_0_INDIRECT, &ind_lm_addr0);
+ qat_hal_rd_indr_csr(handle, ae, ctx, LM_ADDR_1_INDIRECT, &ind_lm_addr1);
+ qat_hal_rd_indr_csr(handle, ae, ctx, INDIRECT_LM_ADDR_0_BYTE_INDEX,
+ &ind_lm_addr_byte0);
+ qat_hal_rd_indr_csr(handle, ae, ctx, INDIRECT_LM_ADDR_1_BYTE_INDEX,
+ &ind_lm_addr_byte1);
+ if (inst_num <= MAX_EXEC_INST)
+ qat_hal_get_uwords(handle, ae, 0, inst_num, savuwords);
+ qat_hal_get_wakeup_event(handle, ae, ctx, &wakeup_events);
+ qat_hal_rd_indr_csr(handle, ae, ctx, CTX_STS_INDIRECT, &savpc);
+ savpc = (savpc & handle->hal_handle->upc_mask) >> 0;
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ ctx_enables &= IGNORE_W1C_MASK;
+ qat_hal_rd_ae_csr(handle, ae, CC_ENABLE, &savcc);
+ qat_hal_rd_ae_csr(handle, ae, ACTIVE_CTX_STATUS, &savctx);
+ qat_hal_rd_ae_csr(handle, ae, CTX_ARB_CNTL, &ctxarb_ctl);
+ qat_hal_rd_indr_csr(handle, ae, ctx, FUTURE_COUNT_SIGNAL_INDIRECT,
+ &ind_cnt_sig);
+ qat_hal_rd_indr_csr(handle, ae, ctx, CTX_SIG_EVENTS_INDIRECT, &ind_sig);
+ qat_hal_rd_ae_csr(handle, ae, CTX_SIG_EVENTS_ACTIVE, &act_sig);
+ /* execute micro codes */
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables);
+ qat_hal_wr_uwords(handle, ae, 0, inst_num, micro_inst);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx), CTX_STS_INDIRECT, 0);
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS, ctx & ACS_ACNO);
+ if (code_off)
+ qat_hal_wr_ae_csr(handle, ae, CC_ENABLE, savcc & 0xffffdfff);
+ qat_hal_put_wakeup_event(handle, ae, (1 << ctx), XCWE_VOLUNTARY);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx), CTX_SIG_EVENTS_INDIRECT, 0);
+ qat_hal_wr_ae_csr(handle, ae, CTX_SIG_EVENTS_ACTIVE, 0);
+ qat_hal_enable_ctx(handle, ae, (1 << ctx));
+ /* wait for micro codes to finish */
+ if (qat_hal_wait_cycles(handle, ae, max_cycle, 1) != 0)
+ return -EFAULT;
+ if (endpc) {
+ unsigned int ctx_status;
+
+ qat_hal_rd_indr_csr(handle, ae, ctx, CTX_STS_INDIRECT,
+ &ctx_status);
+ *endpc = ctx_status & handle->hal_handle->upc_mask;
+ }
+ /* retore to saved context */
+ qat_hal_disable_ctx(handle, ae, (1 << ctx));
+ if (inst_num <= MAX_EXEC_INST)
+ qat_hal_wr_uwords(handle, ae, 0, inst_num, savuwords);
+ qat_hal_put_wakeup_event(handle, ae, (1 << ctx), wakeup_events);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx), CTX_STS_INDIRECT,
+ handle->hal_handle->upc_mask & savpc);
+ qat_hal_rd_ae_csr(handle, ae, AE_MISC_CONTROL, &csr_val);
+ newcsr_val = CLR_BIT(csr_val, MMC_SHARE_CS_BITPOS);
+ qat_hal_wr_ae_csr(handle, ae, AE_MISC_CONTROL, newcsr_val);
+ qat_hal_wr_ae_csr(handle, ae, CC_ENABLE, savcc);
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS, savctx & ACS_ACNO);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ARB_CNTL, ctxarb_ctl);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ LM_ADDR_0_INDIRECT, ind_lm_addr0);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ LM_ADDR_1_INDIRECT, ind_lm_addr1);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ INDIRECT_LM_ADDR_0_BYTE_INDEX, ind_lm_addr_byte0);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ INDIRECT_LM_ADDR_1_BYTE_INDEX, ind_lm_addr_byte1);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ FUTURE_COUNT_SIGNAL_INDIRECT, ind_cnt_sig);
+ qat_hal_wr_indr_csr(handle, ae, (1 << ctx),
+ CTX_SIG_EVENTS_INDIRECT, ind_sig);
+ qat_hal_wr_ae_csr(handle, ae, CTX_SIG_EVENTS_ACTIVE, act_sig);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables);
+
+ return 0;
+}
+
+static int qat_hal_rd_rel_reg(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int *data)
+{
+ unsigned int savctx, uaddr, uwrd_lo, uwrd_hi;
+ unsigned int ctxarb_cntl, ustore_addr, ctx_enables;
+ unsigned short reg_addr;
+ int status = 0;
+ uint64_t insts, savuword;
+
+ reg_addr = qat_hal_get_reg_addr(reg_type, reg_num);
+ if (reg_addr == BAD_REGADDR) {
+ pr_err("QAT: bad regaddr=0x%x\n", reg_addr);
+ return -EINVAL;
+ }
+ switch (reg_type) {
+ case ICP_GPA_REL:
+ insts = 0xA070000000ull | (reg_addr & 0x3ff);
+ break;
+ default:
+ insts = (uint64_t)0xA030000000ull | ((reg_addr & 0x3ff) << 10);
+ break;
+ }
+ qat_hal_rd_ae_csr(handle, ae, ACTIVE_CTX_STATUS, &savctx);
+ qat_hal_rd_ae_csr(handle, ae, CTX_ARB_CNTL, &ctxarb_cntl);
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ ctx_enables &= IGNORE_W1C_MASK;
+ if (ctx != (savctx & ACS_ACNO))
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS,
+ ctx & ACS_ACNO);
+ qat_hal_get_uwords(handle, ae, 0, 1, &savuword);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables);
+ qat_hal_rd_ae_csr(handle, ae, USTORE_ADDRESS, &ustore_addr);
+ uaddr = UA_ECS;
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
+ insts = qat_hal_set_uword_ecc(insts);
+ uwrd_lo = (unsigned int)(insts & 0xffffffff);
+ uwrd_hi = (unsigned int)(insts >> 0x20);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_LOWER, uwrd_lo);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_UPPER, uwrd_hi);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
+ /* delay for at least 8 cycles */
+ qat_hal_wait_cycles(handle, ae, 0x8, 0);
+ /*
+ * read ALU output
+ * the instruction should have been executed
+ * prior to clearing the ECS in putUwords
+ */
+ qat_hal_rd_ae_csr(handle, ae, ALU_OUT, data);
+ qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, ustore_addr);
+ qat_hal_wr_uwords(handle, ae, 0, 1, &savuword);
+ if (ctx != (savctx & ACS_ACNO))
+ qat_hal_wr_ae_csr(handle, ae, ACTIVE_CTX_STATUS,
+ savctx & ACS_ACNO);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ARB_CNTL, ctxarb_cntl);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables);
+
+ return status;
+}
+
+static int qat_hal_wr_rel_reg(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int data)
+{
+ unsigned short src_hiaddr, src_lowaddr, dest_addr, data16hi, data16lo;
+ uint64_t insts[] = {
+ 0x0F440000000ull,
+ 0x0F040000000ull,
+ 0x0F0000C0300ull,
+ 0x0E000010000ull
+ };
+ const int num_inst = ARRAY_SIZE(insts), code_off = 1;
+ const int imm_w1 = 0, imm_w0 = 1;
+
+ dest_addr = qat_hal_get_reg_addr(reg_type, reg_num);
+ if (dest_addr == BAD_REGADDR) {
+ pr_err("QAT: bad destAddr=0x%x\n", dest_addr);
+ return -EINVAL;
+ }
+
+ data16lo = 0xffff & data;
+ data16hi = 0xffff & (data >> 0x10);
+ src_hiaddr = qat_hal_get_reg_addr(ICP_NO_DEST, (unsigned short)
+ (0xff & data16hi));
+ src_lowaddr = qat_hal_get_reg_addr(ICP_NO_DEST, (unsigned short)
+ (0xff & data16lo));
+ switch (reg_type) {
+ case ICP_GPA_REL:
+ insts[imm_w1] = insts[imm_w1] | ((data16hi >> 8) << 20) |
+ ((src_hiaddr & 0x3ff) << 10) | (dest_addr & 0x3ff);
+ insts[imm_w0] = insts[imm_w0] | ((data16lo >> 8) << 20) |
+ ((src_lowaddr & 0x3ff) << 10) | (dest_addr & 0x3ff);
+ break;
+ default:
+ insts[imm_w1] = insts[imm_w1] | ((data16hi >> 8) << 20) |
+ ((dest_addr & 0x3ff) << 10) | (src_hiaddr & 0x3ff);
+
+ insts[imm_w0] = insts[imm_w0] | ((data16lo >> 8) << 20) |
+ ((dest_addr & 0x3ff) << 10) | (src_lowaddr & 0x3ff);
+ break;
+ }
+
+ return qat_hal_exec_micro_inst(handle, ae, ctx, insts, num_inst,
+ code_off, num_inst * 0x5, NULL);
+}
+
+int qat_hal_get_ins_num(void)
+{
+ return ARRAY_SIZE(inst_4b);
+}
+
+static int qat_hal_concat_micro_code(uint64_t *micro_inst,
+ unsigned int inst_num, unsigned int size,
+ unsigned int addr, unsigned int *value)
+{
+ int i, val_indx;
+ unsigned int cur_value;
+ const uint64_t *inst_arr;
+ int fixup_offset;
+ int usize = 0;
+ int orig_num;
+
+ orig_num = inst_num;
+ val_indx = 0;
+ cur_value = value[val_indx++];
+ inst_arr = inst_4b;
+ usize = ARRAY_SIZE(inst_4b);
+ fixup_offset = inst_num;
+ for (i = 0; i < usize; i++)
+ micro_inst[inst_num++] = inst_arr[i];
+ INSERT_IMMED_GPRA_CONST(micro_inst[fixup_offset], (addr));
+ fixup_offset++;
+ INSERT_IMMED_GPRA_CONST(micro_inst[fixup_offset], 0);
+ fixup_offset++;
+ INSERT_IMMED_GPRB_CONST(micro_inst[fixup_offset], (cur_value >> 0));
+ fixup_offset++;
+ INSERT_IMMED_GPRB_CONST(micro_inst[fixup_offset], (cur_value >> 0x10));
+
+ return inst_num - orig_num;
+}
+
+static int qat_hal_exec_micro_init_lm(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ int *pfirst_exec, uint64_t *micro_inst,
+ unsigned int inst_num)
+{
+ int stat = 0;
+ unsigned int gpra0 = 0, gpra1 = 0, gpra2 = 0;
+ unsigned int gprb0 = 0, gprb1 = 0;
+
+ if (*pfirst_exec) {
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0, &gpra0);
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0x1, &gpra1);
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0x2, &gpra2);
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, 0, &gprb0);
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, 0x1, &gprb1);
+ *pfirst_exec = 0;
+ }
+ stat = qat_hal_exec_micro_inst(handle, ae, ctx, micro_inst, inst_num, 1,
+ inst_num * 0x5, NULL);
+ if (stat != 0)
+ return -EFAULT;
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0, gpra0);
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0x1, gpra1);
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPA_REL, 0x2, gpra2);
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPB_REL, 0, gprb0);
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPB_REL, 0x1, gprb1);
+
+ return 0;
+}
+
+int qat_hal_batch_wr_lm(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae,
+ struct icp_qat_uof_batch_init *lm_init_header)
+{
+ struct icp_qat_uof_batch_init *plm_init;
+ uint64_t *micro_inst_arry;
+ int micro_inst_num;
+ int alloc_inst_size;
+ int first_exec = 1;
+ int stat = 0;
+
+ plm_init = lm_init_header->next;
+ alloc_inst_size = lm_init_header->size;
+ if ((unsigned int)alloc_inst_size > handle->hal_handle->max_ustore)
+ alloc_inst_size = handle->hal_handle->max_ustore;
+ micro_inst_arry = kmalloc_array(alloc_inst_size, sizeof(uint64_t),
+ GFP_KERNEL);
+ if (!micro_inst_arry)
+ return -ENOMEM;
+ micro_inst_num = 0;
+ while (plm_init) {
+ unsigned int addr, *value, size;
+
+ ae = plm_init->ae;
+ addr = plm_init->addr;
+ value = plm_init->value;
+ size = plm_init->size;
+ micro_inst_num += qat_hal_concat_micro_code(micro_inst_arry,
+ micro_inst_num,
+ size, addr, value);
+ plm_init = plm_init->next;
+ }
+ /* exec micro codes */
+ if (micro_inst_arry && (micro_inst_num > 0)) {
+ micro_inst_arry[micro_inst_num++] = 0x0E000010000ull;
+ stat = qat_hal_exec_micro_init_lm(handle, ae, 0, &first_exec,
+ micro_inst_arry,
+ micro_inst_num);
+ }
+ kfree(micro_inst_arry);
+ return stat;
+}
+
+static int qat_hal_put_rel_rd_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int val)
+{
+ int status = 0;
+ unsigned int reg_addr;
+ unsigned int ctx_enables;
+ unsigned short mask;
+ unsigned short dr_offset = 0x10;
+
+ status = qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ if (CE_INUSE_CONTEXTS & ctx_enables) {
+ if (ctx & 0x1) {
+ pr_err("QAT: bad 4-ctx mode,ctx=0x%x\n", ctx);
+ return -EINVAL;
+ }
+ mask = 0x1f;
+ dr_offset = 0x20;
+ } else {
+ mask = 0x0f;
+ }
+ if (reg_num & ~mask)
+ return -EINVAL;
+ reg_addr = reg_num + (ctx << 0x5);
+ switch (reg_type) {
+ case ICP_SR_RD_REL:
+ case ICP_SR_REL:
+ SET_AE_XFER(handle, ae, reg_addr, val);
+ break;
+ case ICP_DR_RD_REL:
+ case ICP_DR_REL:
+ SET_AE_XFER(handle, ae, (reg_addr + dr_offset), val);
+ break;
+ default:
+ status = -EINVAL;
+ break;
+ }
+ return status;
+}
+
+static int qat_hal_put_rel_wr_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int data)
+{
+ unsigned int gprval, ctx_enables;
+ unsigned short src_hiaddr, src_lowaddr, gpr_addr, xfr_addr, data16hi,
+ data16low;
+ unsigned short reg_mask;
+ int status = 0;
+ uint64_t micro_inst[] = {
+ 0x0F440000000ull,
+ 0x0F040000000ull,
+ 0x0A000000000ull,
+ 0x0F0000C0300ull,
+ 0x0E000010000ull
+ };
+ const int num_inst = ARRAY_SIZE(micro_inst), code_off = 1;
+ const unsigned short gprnum = 0, dly = num_inst * 0x5;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ if (CE_INUSE_CONTEXTS & ctx_enables) {
+ if (ctx & 0x1) {
+ pr_err("QAT: 4-ctx mode,ctx=0x%x\n", ctx);
+ return -EINVAL;
+ }
+ reg_mask = (unsigned short)~0x1f;
+ } else {
+ reg_mask = (unsigned short)~0xf;
+ }
+ if (reg_num & reg_mask)
+ return -EINVAL;
+ xfr_addr = qat_hal_get_reg_addr(reg_type, reg_num);
+ if (xfr_addr == BAD_REGADDR) {
+ pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr);
+ return -EINVAL;
+ }
+ qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval);
+ gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum);
+ data16low = 0xffff & data;
+ data16hi = 0xffff & (data >> 0x10);
+ src_hiaddr = qat_hal_get_reg_addr(ICP_NO_DEST,
+ (unsigned short)(0xff & data16hi));
+ src_lowaddr = qat_hal_get_reg_addr(ICP_NO_DEST,
+ (unsigned short)(0xff & data16low));
+ micro_inst[0] = micro_inst[0x0] | ((data16hi >> 8) << 20) |
+ ((gpr_addr & 0x3ff) << 10) | (src_hiaddr & 0x3ff);
+ micro_inst[1] = micro_inst[0x1] | ((data16low >> 8) << 20) |
+ ((gpr_addr & 0x3ff) << 10) | (src_lowaddr & 0x3ff);
+ micro_inst[0x2] = micro_inst[0x2] |
+ ((xfr_addr & 0x3ff) << 20) | ((gpr_addr & 0x3ff) << 10);
+ status = qat_hal_exec_micro_inst(handle, ae, ctx, micro_inst, num_inst,
+ code_off, dly, NULL);
+ qat_hal_wr_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, gprval);
+ return status;
+}
+
+static int qat_hal_put_rel_nn(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx,
+ unsigned short nn, unsigned int val)
+{
+ unsigned int ctx_enables;
+ int stat = 0;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ ctx_enables &= IGNORE_W1C_MASK;
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables | CE_NN_MODE);
+
+ stat = qat_hal_put_rel_wr_xfer(handle, ae, ctx, ICP_NEIGH_REL, nn, val);
+ qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx_enables);
+ return stat;
+}
+
+static int qat_hal_convert_abs_to_rel(struct icp_qat_fw_loader_handle
+ *handle, unsigned char ae,
+ unsigned short absreg_num,
+ unsigned short *relreg,
+ unsigned char *ctx)
+{
+ unsigned int ctx_enables;
+
+ qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES, &ctx_enables);
+ if (ctx_enables & CE_INUSE_CONTEXTS) {
+ /* 4-ctx mode */
+ *relreg = absreg_num & 0x1F;
+ *ctx = (absreg_num >> 0x4) & 0x6;
+ } else {
+ /* 8-ctx mode */
+ *relreg = absreg_num & 0x0F;
+ *ctx = (absreg_num >> 0x4) & 0x7;
+ }
+ return 0;
+}
+
+int qat_hal_init_gpr(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata)
+{
+ int stat = 0;
+ unsigned short reg;
+ unsigned char ctx = 0;
+ enum icp_qat_uof_regtype type;
+
+ if (reg_num >= ICP_QAT_UCLO_MAX_GPR_REG)
+ return -EINVAL;
+
+ do {
+ if (ctx_mask == 0) {
+ qat_hal_convert_abs_to_rel(handle, ae, reg_num, &reg,
+ &ctx);
+ type = reg_type - 1;
+ } else {
+ reg = reg_num;
+ type = reg_type;
+ if (!test_bit(ctx, (unsigned long *)&ctx_mask))
+ continue;
+ }
+ stat = qat_hal_wr_rel_reg(handle, ae, ctx, type, reg, regdata);
+ if (stat) {
+ pr_err("QAT: write gpr fail\n");
+ return -EINVAL;
+ }
+ } while (ctx_mask && (ctx++ < ICP_QAT_UCLO_MAX_CTX));
+
+ return 0;
+}
+
+int qat_hal_init_wr_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata)
+{
+ int stat = 0;
+ unsigned short reg;
+ unsigned char ctx = 0;
+ enum icp_qat_uof_regtype type;
+
+ if (reg_num >= ICP_QAT_UCLO_MAX_XFER_REG)
+ return -EINVAL;
+
+ do {
+ if (ctx_mask == 0) {
+ qat_hal_convert_abs_to_rel(handle, ae, reg_num, &reg,
+ &ctx);
+ type = reg_type - 3;
+ } else {
+ reg = reg_num;
+ type = reg_type;
+ if (!test_bit(ctx, (unsigned long *)&ctx_mask))
+ continue;
+ }
+ stat = qat_hal_put_rel_wr_xfer(handle, ae, ctx, type, reg,
+ regdata);
+ if (stat) {
+ pr_err("QAT: write wr xfer fail\n");
+ return -EINVAL;
+ }
+ } while (ctx_mask && (ctx++ < ICP_QAT_UCLO_MAX_CTX));
+
+ return 0;
+}
+
+int qat_hal_init_rd_xfer(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_num, unsigned int regdata)
+{
+ int stat = 0;
+ unsigned short reg;
+ unsigned char ctx = 0;
+ enum icp_qat_uof_regtype type;
+
+ if (reg_num >= ICP_QAT_UCLO_MAX_XFER_REG)
+ return -EINVAL;
+
+ do {
+ if (ctx_mask == 0) {
+ qat_hal_convert_abs_to_rel(handle, ae, reg_num, &reg,
+ &ctx);
+ type = reg_type - 3;
+ } else {
+ reg = reg_num;
+ type = reg_type;
+ if (!test_bit(ctx, (unsigned long *)&ctx_mask))
+ continue;
+ }
+ stat = qat_hal_put_rel_rd_xfer(handle, ae, ctx, type, reg,
+ regdata);
+ if (stat) {
+ pr_err("QAT: write rd xfer fail\n");
+ return -EINVAL;
+ }
+ } while (ctx_mask && (ctx++ < ICP_QAT_UCLO_MAX_CTX));
+
+ return 0;
+}
+
+int qat_hal_init_nn(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ unsigned short reg_num, unsigned int regdata)
+{
+ int stat = 0;
+ unsigned char ctx;
+
+ if (ctx_mask == 0)
+ return -EINVAL;
+
+ for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++) {
+ if (!test_bit(ctx, (unsigned long *)&ctx_mask))
+ continue;
+ stat = qat_hal_put_rel_nn(handle, ae, ctx, reg_num, regdata);
+ if (stat) {
+ pr_err("QAT: write neigh error\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c
new file mode 100644
index 000000000000..1e27f9f7fddf
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/qat_uclo.c
@@ -0,0 +1,1181 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "icp_qat_uclo.h"
+#include "icp_qat_hal.h"
+#include "icp_qat_fw_loader_handle.h"
+
+#define UWORD_CPYBUF_SIZE 1024
+#define INVLD_UWORD 0xffffffffffull
+#define PID_MINOR_REV 0xf
+#define PID_MAJOR_REV (0xf << 4)
+
+static int qat_uclo_init_ae_data(struct icp_qat_uclo_objhandle *obj_handle,
+ unsigned int ae, unsigned int image_num)
+{
+ struct icp_qat_uclo_aedata *ae_data;
+ struct icp_qat_uclo_encapme *encap_image;
+ struct icp_qat_uclo_page *page = NULL;
+ struct icp_qat_uclo_aeslice *ae_slice = NULL;
+
+ ae_data = &obj_handle->ae_data[ae];
+ encap_image = &obj_handle->ae_uimage[image_num];
+ ae_slice = &ae_data->ae_slices[ae_data->slice_num];
+ ae_slice->encap_image = encap_image;
+
+ if (encap_image->img_ptr) {
+ ae_slice->ctx_mask_assigned =
+ encap_image->img_ptr->ctx_assigned;
+ ae_data->eff_ustore_size = obj_handle->ustore_phy_size;
+ } else {
+ ae_slice->ctx_mask_assigned = 0;
+ }
+ ae_slice->region = kzalloc(sizeof(*ae_slice->region), GFP_KERNEL);
+ if (!ae_slice->region)
+ return -ENOMEM;
+ ae_slice->page = kzalloc(sizeof(*ae_slice->page), GFP_KERNEL);
+ if (!ae_slice->page)
+ goto out_err;
+ page = ae_slice->page;
+ page->encap_page = encap_image->page;
+ ae_slice->page->region = ae_slice->region;
+ ae_data->slice_num++;
+ return 0;
+out_err:
+ kfree(ae_slice->region);
+ ae_slice->region = NULL;
+ return -ENOMEM;
+}
+
+static int qat_uclo_free_ae_data(struct icp_qat_uclo_aedata *ae_data)
+{
+ unsigned int i;
+
+ if (!ae_data) {
+ pr_err("QAT: bad argument, ae_data is NULL\n ");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ae_data->slice_num; i++) {
+ kfree(ae_data->ae_slices[i].region);
+ ae_data->ae_slices[i].region = NULL;
+ kfree(ae_data->ae_slices[i].page);
+ ae_data->ae_slices[i].page = NULL;
+ }
+ return 0;
+}
+
+static char *qat_uclo_get_string(struct icp_qat_uof_strtable *str_table,
+ unsigned int str_offset)
+{
+ if ((!str_table->table_len) || (str_offset > str_table->table_len))
+ return NULL;
+ return (char *)(((unsigned long)(str_table->strings)) + str_offset);
+}
+
+static int qat_uclo_check_format(struct icp_qat_uof_filehdr *hdr)
+{
+ int maj = hdr->maj_ver & 0xff;
+ int min = hdr->min_ver & 0xff;
+
+ if (hdr->file_id != ICP_QAT_UOF_FID) {
+ pr_err("QAT: Invalid header 0x%x\n", hdr->file_id);
+ return -EINVAL;
+ }
+ if (min != ICP_QAT_UOF_MINVER || maj != ICP_QAT_UOF_MAJVER) {
+ pr_err("QAT: bad UOF version, major 0x%x, minor 0x%x\n",
+ maj, min);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void qat_uclo_wr_sram_by_words(struct icp_qat_fw_loader_handle *handle,
+ unsigned int addr, unsigned int *val,
+ unsigned int num_in_bytes)
+{
+ unsigned int outval;
+ unsigned char *ptr = (unsigned char *)val;
+
+ while (num_in_bytes) {
+ memcpy(&outval, ptr, 4);
+ SRAM_WRITE(handle, addr, outval);
+ num_in_bytes -= 4;
+ ptr += 4;
+ addr += 4;
+ }
+}
+
+static void qat_uclo_wr_umem_by_words(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned int addr,
+ unsigned int *val,
+ unsigned int num_in_bytes)
+{
+ unsigned int outval;
+ unsigned char *ptr = (unsigned char *)val;
+
+ addr >>= 0x2; /* convert to uword address */
+
+ while (num_in_bytes) {
+ memcpy(&outval, ptr, 4);
+ qat_hal_wr_umem(handle, ae, addr++, 1, &outval);
+ num_in_bytes -= 4;
+ ptr += 4;
+ }
+}
+
+static void qat_uclo_batch_wr_umem(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae,
+ struct icp_qat_uof_batch_init
+ *umem_init_header)
+{
+ struct icp_qat_uof_batch_init *umem_init;
+
+ if (!umem_init_header)
+ return;
+ umem_init = umem_init_header->next;
+ while (umem_init) {
+ unsigned int addr, *value, size;
+
+ ae = umem_init->ae;
+ addr = umem_init->addr;
+ value = umem_init->value;
+ size = umem_init->size;
+ qat_uclo_wr_umem_by_words(handle, ae, addr, value, size);
+ umem_init = umem_init->next;
+ }
+}
+
+static void
+qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_batch_init **base)
+{
+ struct icp_qat_uof_batch_init *umem_init;
+
+ umem_init = *base;
+ while (umem_init) {
+ struct icp_qat_uof_batch_init *pre;
+
+ pre = umem_init;
+ umem_init = umem_init->next;
+ kfree(pre);
+ }
+ *base = NULL;
+}
+
+static int qat_uclo_parse_num(char *str, unsigned int *num)
+{
+ char buf[16] = {0};
+ unsigned long ae = 0;
+ int i;
+
+ strncpy(buf, str, 15);
+ for (i = 0; i < 16; i++) {
+ if (!isdigit(buf[i])) {
+ buf[i] = '\0';
+ break;
+ }
+ }
+ if ((kstrtoul(buf, 10, &ae)))
+ return -EFAULT;
+
+ *num = (unsigned int)ae;
+ return 0;
+}
+
+static int qat_uclo_fetch_initmem_ae(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_initmem *init_mem,
+ unsigned int size_range, unsigned int *ae)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ char *str;
+
+ if ((init_mem->addr + init_mem->num_in_bytes) > (size_range << 0x2)) {
+ pr_err("QAT: initmem is out of range");
+ return -EINVAL;
+ }
+ if (init_mem->scope != ICP_QAT_UOF_LOCAL_SCOPE) {
+ pr_err("QAT: Memory scope for init_mem error\n");
+ return -EINVAL;
+ }
+ str = qat_uclo_get_string(&obj_handle->str_table, init_mem->sym_name);
+ if (!str) {
+ pr_err("QAT: AE name assigned in UOF init table is NULL\n");
+ return -EINVAL;
+ }
+ if (qat_uclo_parse_num(str, ae)) {
+ pr_err("QAT: Parse num for AE number failed\n");
+ return -EINVAL;
+ }
+ if (*ae >= ICP_QAT_UCLO_MAX_AE) {
+ pr_err("QAT: ae %d out of range\n", *ae);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle
+ *handle, struct icp_qat_uof_initmem
+ *init_mem, unsigned int ae,
+ struct icp_qat_uof_batch_init
+ **init_tab_base)
+{
+ struct icp_qat_uof_batch_init *init_header, *tail;
+ struct icp_qat_uof_batch_init *mem_init, *tail_old;
+ struct icp_qat_uof_memvar_attr *mem_val_attr;
+ unsigned int i, flag = 0;
+
+ mem_val_attr =
+ (struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
+ sizeof(struct icp_qat_uof_initmem));
+
+ init_header = *init_tab_base;
+ if (!init_header) {
+ init_header = kzalloc(sizeof(*init_header), GFP_KERNEL);
+ if (!init_header)
+ return -ENOMEM;
+ init_header->size = 1;
+ *init_tab_base = init_header;
+ flag = 1;
+ }
+ tail_old = init_header;
+ while (tail_old->next)
+ tail_old = tail_old->next;
+ tail = tail_old;
+ for (i = 0; i < init_mem->val_attr_num; i++) {
+ mem_init = kzalloc(sizeof(*mem_init), GFP_KERNEL);
+ if (!mem_init)
+ goto out_err;
+ mem_init->ae = ae;
+ mem_init->addr = init_mem->addr + mem_val_attr->offset_in_byte;
+ mem_init->value = &mem_val_attr->value;
+ mem_init->size = 4;
+ mem_init->next = NULL;
+ tail->next = mem_init;
+ tail = mem_init;
+ init_header->size += qat_hal_get_ins_num();
+ mem_val_attr++;
+ }
+ return 0;
+out_err:
+ while (tail_old) {
+ mem_init = tail_old->next;
+ kfree(tail_old);
+ tail_old = mem_init;
+ }
+ if (flag)
+ kfree(*init_tab_base);
+ return -ENOMEM;
+}
+
+static int qat_uclo_init_lmem_seg(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_initmem *init_mem)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int ae;
+
+ if (qat_uclo_fetch_initmem_ae(handle, init_mem,
+ ICP_QAT_UCLO_MAX_LMEM_REG, &ae))
+ return -EINVAL;
+ if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
+ &obj_handle->lm_init_tab[ae]))
+ return -EINVAL;
+ return 0;
+}
+
+static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_initmem *init_mem)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int ae, ustore_size, uaddr, i;
+
+ ustore_size = obj_handle->ustore_phy_size;
+ if (qat_uclo_fetch_initmem_ae(handle, init_mem, ustore_size, &ae))
+ return -EINVAL;
+ if (qat_uclo_create_batch_init_list(handle, init_mem, ae,
+ &obj_handle->umem_init_tab[ae]))
+ return -EINVAL;
+ /* set the highest ustore address referenced */
+ uaddr = (init_mem->addr + init_mem->num_in_bytes) >> 0x2;
+ for (i = 0; i < obj_handle->ae_data[ae].slice_num; i++) {
+ if (obj_handle->ae_data[ae].ae_slices[i].
+ encap_image->uwords_num < uaddr)
+ obj_handle->ae_data[ae].ae_slices[i].
+ encap_image->uwords_num = uaddr;
+ }
+ return 0;
+}
+
+#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000
+static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_initmem *init_mem)
+{
+ unsigned int i;
+ struct icp_qat_uof_memvar_attr *mem_val_attr;
+
+ mem_val_attr =
+ (struct icp_qat_uof_memvar_attr *)((unsigned long)init_mem +
+ sizeof(struct icp_qat_uof_initmem));
+
+ switch (init_mem->region) {
+ case ICP_QAT_UOF_SRAM_REGION:
+ if ((init_mem->addr + init_mem->num_in_bytes) >
+ ICP_DH895XCC_PESRAM_BAR_SIZE) {
+ pr_err("QAT: initmem on SRAM is out of range");
+ return -EINVAL;
+ }
+ for (i = 0; i < init_mem->val_attr_num; i++) {
+ qat_uclo_wr_sram_by_words(handle,
+ init_mem->addr +
+ mem_val_attr->offset_in_byte,
+ &mem_val_attr->value, 4);
+ mem_val_attr++;
+ }
+ break;
+ case ICP_QAT_UOF_LMEM_REGION:
+ if (qat_uclo_init_lmem_seg(handle, init_mem))
+ return -EINVAL;
+ break;
+ case ICP_QAT_UOF_UMEM_REGION:
+ if (qat_uclo_init_umem_seg(handle, init_mem))
+ return -EINVAL;
+ break;
+ default:
+ pr_err("QAT: initmem region error. region type=0x%x\n",
+ init_mem->region);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int qat_uclo_init_ustore(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uclo_encapme *image)
+{
+ unsigned int i;
+ struct icp_qat_uclo_encap_page *page;
+ struct icp_qat_uof_image *uof_image;
+ unsigned char ae;
+ unsigned int ustore_size;
+ unsigned int patt_pos;
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ uint64_t *fill_data;
+
+ uof_image = image->img_ptr;
+ fill_data = kcalloc(ICP_QAT_UCLO_MAX_USTORE, sizeof(uint64_t),
+ GFP_KERNEL);
+ if (!fill_data)
+ return -ENOMEM;
+ for (i = 0; i < ICP_QAT_UCLO_MAX_USTORE; i++)
+ memcpy(&fill_data[i], &uof_image->fill_pattern,
+ sizeof(uint64_t));
+ page = image->page;
+
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!test_bit(ae, (unsigned long *)&uof_image->ae_assigned))
+ continue;
+ ustore_size = obj_handle->ae_data[ae].eff_ustore_size;
+ patt_pos = page->beg_addr_p + page->micro_words_num;
+
+ qat_hal_wr_uwords(handle, (unsigned char)ae, 0,
+ page->beg_addr_p, &fill_data[0]);
+ qat_hal_wr_uwords(handle, (unsigned char)ae, patt_pos,
+ ustore_size - patt_pos + 1,
+ &fill_data[page->beg_addr_p]);
+ }
+ kfree(fill_data);
+ return 0;
+}
+
+static int qat_uclo_init_memory(struct icp_qat_fw_loader_handle *handle)
+{
+ int i, ae;
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ struct icp_qat_uof_initmem *initmem = obj_handle->init_mem_tab.init_mem;
+
+ for (i = 0; i < obj_handle->init_mem_tab.entry_num; i++) {
+ if (initmem->num_in_bytes) {
+ if (qat_uclo_init_ae_memory(handle, initmem))
+ return -EINVAL;
+ }
+ initmem = (struct icp_qat_uof_initmem *)((unsigned long)(
+ (unsigned long)initmem +
+ sizeof(struct icp_qat_uof_initmem)) +
+ (sizeof(struct icp_qat_uof_memvar_attr) *
+ initmem->val_attr_num));
+ }
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (qat_hal_batch_wr_lm(handle, ae,
+ obj_handle->lm_init_tab[ae])) {
+ pr_err("QAT: fail to batch init lmem for AE %d\n", ae);
+ return -EINVAL;
+ }
+ qat_uclo_cleanup_batch_init_list(handle,
+ &obj_handle->lm_init_tab[ae]);
+ qat_uclo_batch_wr_umem(handle, ae,
+ obj_handle->umem_init_tab[ae]);
+ qat_uclo_cleanup_batch_init_list(handle,
+ &obj_handle->
+ umem_init_tab[ae]);
+ }
+ return 0;
+}
+
+static void *qat_uclo_find_chunk(struct icp_qat_uof_objhdr *obj_hdr,
+ char *chunk_id, void *cur)
+{
+ int i;
+ struct icp_qat_uof_chunkhdr *chunk_hdr =
+ (struct icp_qat_uof_chunkhdr *)
+ ((unsigned long)obj_hdr + sizeof(struct icp_qat_uof_objhdr));
+
+ for (i = 0; i < obj_hdr->num_chunks; i++) {
+ if ((cur < (void *)&chunk_hdr[i]) &&
+ !strncmp(chunk_hdr[i].chunk_id, chunk_id,
+ ICP_QAT_UOF_OBJID_LEN)) {
+ return &chunk_hdr[i];
+ }
+ }
+ return NULL;
+}
+
+static unsigned int qat_uclo_calc_checksum(unsigned int reg, int ch)
+{
+ int i;
+ unsigned int topbit = 1 << 0xF;
+ unsigned int inbyte = (unsigned int)((reg >> 0x18) ^ ch);
+
+ reg ^= inbyte << 0x8;
+ for (i = 0; i < 0x8; i++) {
+ if (reg & topbit)
+ reg = (reg << 1) ^ 0x1021;
+ else
+ reg <<= 1;
+ }
+ return reg & 0xFFFF;
+}
+
+static unsigned int qat_uclo_calc_str_checksum(char *ptr, int num)
+{
+ unsigned int chksum = 0;
+
+ if (ptr)
+ while (num--)
+ chksum = qat_uclo_calc_checksum(chksum, *ptr++);
+ return chksum;
+}
+
+static struct icp_qat_uclo_objhdr *
+qat_uclo_map_chunk(char *buf, struct icp_qat_uof_filehdr *file_hdr,
+ char *chunk_id)
+{
+ struct icp_qat_uof_filechunkhdr *file_chunk;
+ struct icp_qat_uclo_objhdr *obj_hdr;
+ char *chunk;
+ int i;
+
+ file_chunk = (struct icp_qat_uof_filechunkhdr *)
+ (buf + sizeof(struct icp_qat_uof_filehdr));
+ for (i = 0; i < file_hdr->num_chunks; i++) {
+ if (!strncmp(file_chunk->chunk_id, chunk_id,
+ ICP_QAT_UOF_OBJID_LEN)) {
+ chunk = buf + file_chunk->offset;
+ if (file_chunk->checksum != qat_uclo_calc_str_checksum(
+ chunk, file_chunk->size))
+ break;
+ obj_hdr = kzalloc(sizeof(*obj_hdr), GFP_KERNEL);
+ if (!obj_hdr)
+ break;
+ obj_hdr->file_buff = chunk;
+ obj_hdr->checksum = file_chunk->checksum;
+ obj_hdr->size = file_chunk->size;
+ return obj_hdr;
+ }
+ file_chunk++;
+ }
+ return NULL;
+}
+
+static unsigned int
+qat_uclo_check_image_compat(struct icp_qat_uof_encap_obj *encap_uof_obj,
+ struct icp_qat_uof_image *image)
+{
+ struct icp_qat_uof_objtable *uc_var_tab, *imp_var_tab, *imp_expr_tab;
+ struct icp_qat_uof_objtable *neigh_reg_tab;
+ struct icp_qat_uof_code_page *code_page;
+
+ code_page = (struct icp_qat_uof_code_page *)
+ ((char *)image + sizeof(struct icp_qat_uof_image));
+ uc_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
+ code_page->uc_var_tab_offset);
+ imp_var_tab = (struct icp_qat_uof_objtable *)(encap_uof_obj->beg_uof +
+ code_page->imp_var_tab_offset);
+ imp_expr_tab = (struct icp_qat_uof_objtable *)
+ (encap_uof_obj->beg_uof +
+ code_page->imp_expr_tab_offset);
+ if (uc_var_tab->entry_num || imp_var_tab->entry_num ||
+ imp_expr_tab->entry_num) {
+ pr_err("QAT: UOF can't contain imported variable to be parsed");
+ return -EINVAL;
+ }
+ neigh_reg_tab = (struct icp_qat_uof_objtable *)
+ (encap_uof_obj->beg_uof +
+ code_page->neigh_reg_tab_offset);
+ if (neigh_reg_tab->entry_num) {
+ pr_err("QAT: UOF can't contain shared control store feature");
+ return -EINVAL;
+ }
+ if (image->numpages > 1) {
+ pr_err("QAT: UOF can't contain multiple pages");
+ return -EINVAL;
+ }
+ if (ICP_QAT_SHARED_USTORE_MODE(image->ae_mode)) {
+ pr_err("QAT: UOF can't use shared control store feature");
+ return -EFAULT;
+ }
+ if (RELOADABLE_CTX_SHARED_MODE(image->ae_mode)) {
+ pr_err("QAT: UOF can't use reloadable feature");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void qat_uclo_map_image_page(struct icp_qat_uof_encap_obj
+ *encap_uof_obj,
+ struct icp_qat_uof_image *img,
+ struct icp_qat_uclo_encap_page *page)
+{
+ struct icp_qat_uof_code_page *code_page;
+ struct icp_qat_uof_code_area *code_area;
+ struct icp_qat_uof_objtable *uword_block_tab;
+ struct icp_qat_uof_uword_block *uwblock;
+ int i;
+
+ code_page = (struct icp_qat_uof_code_page *)
+ ((char *)img + sizeof(struct icp_qat_uof_image));
+ page->def_page = code_page->def_page;
+ page->page_region = code_page->page_region;
+ page->beg_addr_v = code_page->beg_addr_v;
+ page->beg_addr_p = code_page->beg_addr_p;
+ code_area = (struct icp_qat_uof_code_area *)(encap_uof_obj->beg_uof +
+ code_page->code_area_offset);
+ page->micro_words_num = code_area->micro_words_num;
+ uword_block_tab = (struct icp_qat_uof_objtable *)
+ (encap_uof_obj->beg_uof +
+ code_area->uword_block_tab);
+ page->uwblock_num = uword_block_tab->entry_num;
+ uwblock = (struct icp_qat_uof_uword_block *)((char *)uword_block_tab +
+ sizeof(struct icp_qat_uof_objtable));
+ page->uwblock = (struct icp_qat_uclo_encap_uwblock *)uwblock;
+ for (i = 0; i < uword_block_tab->entry_num; i++)
+ page->uwblock[i].micro_words =
+ (unsigned long)encap_uof_obj->beg_uof + uwblock[i].uword_offset;
+}
+
+static int qat_uclo_map_uimage(struct icp_qat_uclo_objhandle *obj_handle,
+ struct icp_qat_uclo_encapme *ae_uimage,
+ int max_image)
+{
+ int i, j;
+ struct icp_qat_uof_chunkhdr *chunk_hdr = NULL;
+ struct icp_qat_uof_image *image;
+ struct icp_qat_uof_objtable *ae_regtab;
+ struct icp_qat_uof_objtable *init_reg_sym_tab;
+ struct icp_qat_uof_objtable *sbreak_tab;
+ struct icp_qat_uof_encap_obj *encap_uof_obj =
+ &obj_handle->encap_uof_obj;
+
+ for (j = 0; j < max_image; j++) {
+ chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
+ ICP_QAT_UOF_IMAG, chunk_hdr);
+ if (!chunk_hdr)
+ break;
+ image = (struct icp_qat_uof_image *)(encap_uof_obj->beg_uof +
+ chunk_hdr->offset);
+ ae_regtab = (struct icp_qat_uof_objtable *)
+ (image->reg_tab_offset +
+ obj_handle->obj_hdr->file_buff);
+ ae_uimage[j].ae_reg_num = ae_regtab->entry_num;
+ ae_uimage[j].ae_reg = (struct icp_qat_uof_ae_reg *)
+ (((char *)ae_regtab) +
+ sizeof(struct icp_qat_uof_objtable));
+ init_reg_sym_tab = (struct icp_qat_uof_objtable *)
+ (image->init_reg_sym_tab +
+ obj_handle->obj_hdr->file_buff);
+ ae_uimage[j].init_regsym_num = init_reg_sym_tab->entry_num;
+ ae_uimage[j].init_regsym = (struct icp_qat_uof_init_regsym *)
+ (((char *)init_reg_sym_tab) +
+ sizeof(struct icp_qat_uof_objtable));
+ sbreak_tab = (struct icp_qat_uof_objtable *)
+ (image->sbreak_tab + obj_handle->obj_hdr->file_buff);
+ ae_uimage[j].sbreak_num = sbreak_tab->entry_num;
+ ae_uimage[j].sbreak = (struct icp_qat_uof_sbreak *)
+ (((char *)sbreak_tab) +
+ sizeof(struct icp_qat_uof_objtable));
+ ae_uimage[j].img_ptr = image;
+ if (qat_uclo_check_image_compat(encap_uof_obj, image))
+ goto out_err;
+ ae_uimage[j].page =
+ kzalloc(sizeof(struct icp_qat_uclo_encap_page),
+ GFP_KERNEL);
+ if (!ae_uimage[j].page)
+ goto out_err;
+ qat_uclo_map_image_page(encap_uof_obj, image,
+ ae_uimage[j].page);
+ }
+ return j;
+out_err:
+ for (i = 0; i < j; i++)
+ kfree(ae_uimage[i].page);
+ return 0;
+}
+
+static int qat_uclo_map_ae(struct icp_qat_fw_loader_handle *handle, int max_ae)
+{
+ int i, ae;
+ int mflag = 0;
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+
+ for (ae = 0; ae <= max_ae; ae++) {
+ if (!test_bit(ae,
+ (unsigned long *)&handle->hal_handle->ae_mask))
+ continue;
+ for (i = 0; i < obj_handle->uimage_num; i++) {
+ if (!test_bit(ae, (unsigned long *)
+ &obj_handle->ae_uimage[i].img_ptr->ae_assigned))
+ continue;
+ mflag = 1;
+ if (qat_uclo_init_ae_data(obj_handle, ae, i))
+ return -EINVAL;
+ }
+ }
+ if (!mflag) {
+ pr_err("QAT: uimage uses AE not set");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct icp_qat_uof_strtable *
+qat_uclo_map_str_table(struct icp_qat_uclo_objhdr *obj_hdr,
+ char *tab_name, struct icp_qat_uof_strtable *str_table)
+{
+ struct icp_qat_uof_chunkhdr *chunk_hdr;
+
+ chunk_hdr = qat_uclo_find_chunk((struct icp_qat_uof_objhdr *)
+ obj_hdr->file_buff, tab_name, NULL);
+ if (chunk_hdr) {
+ int hdr_size;
+
+ memcpy(&str_table->table_len, obj_hdr->file_buff +
+ chunk_hdr->offset, sizeof(str_table->table_len));
+ hdr_size = (char *)&str_table->strings - (char *)str_table;
+ str_table->strings = (unsigned long)obj_hdr->file_buff +
+ chunk_hdr->offset + hdr_size;
+ return str_table;
+ }
+ return NULL;
+}
+
+static void
+qat_uclo_map_initmem_table(struct icp_qat_uof_encap_obj *encap_uof_obj,
+ struct icp_qat_uclo_init_mem_table *init_mem_tab)
+{
+ struct icp_qat_uof_chunkhdr *chunk_hdr;
+
+ chunk_hdr = qat_uclo_find_chunk(encap_uof_obj->obj_hdr,
+ ICP_QAT_UOF_IMEM, NULL);
+ if (chunk_hdr) {
+ memmove(&init_mem_tab->entry_num, encap_uof_obj->beg_uof +
+ chunk_hdr->offset, sizeof(unsigned int));
+ init_mem_tab->init_mem = (struct icp_qat_uof_initmem *)
+ (encap_uof_obj->beg_uof + chunk_hdr->offset +
+ sizeof(unsigned int));
+ }
+}
+
+static int qat_uclo_check_uof_compat(struct icp_qat_uclo_objhandle *obj_handle)
+{
+ unsigned int maj_ver, prod_type = obj_handle->prod_type;
+
+ if (!(prod_type & obj_handle->encap_uof_obj.obj_hdr->cpu_type)) {
+ pr_err("QAT: UOF type 0x%x not match with cur platform 0x%x\n",
+ obj_handle->encap_uof_obj.obj_hdr->cpu_type, prod_type);
+ return -EINVAL;
+ }
+ maj_ver = obj_handle->prod_rev & 0xff;
+ if ((obj_handle->encap_uof_obj.obj_hdr->max_cpu_ver < maj_ver) ||
+ (obj_handle->encap_uof_obj.obj_hdr->min_cpu_ver > maj_ver)) {
+ pr_err("QAT: UOF majVer 0x%x out of range\n", maj_ver);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int qat_uclo_init_reg(struct icp_qat_fw_loader_handle *handle,
+ unsigned char ae, unsigned char ctx_mask,
+ enum icp_qat_uof_regtype reg_type,
+ unsigned short reg_addr, unsigned int value)
+{
+ switch (reg_type) {
+ case ICP_GPA_ABS:
+ case ICP_GPB_ABS:
+ ctx_mask = 0;
+ case ICP_GPA_REL:
+ case ICP_GPB_REL:
+ return qat_hal_init_gpr(handle, ae, ctx_mask, reg_type,
+ reg_addr, value);
+ case ICP_SR_ABS:
+ case ICP_DR_ABS:
+ case ICP_SR_RD_ABS:
+ case ICP_DR_RD_ABS:
+ ctx_mask = 0;
+ case ICP_SR_REL:
+ case ICP_DR_REL:
+ case ICP_SR_RD_REL:
+ case ICP_DR_RD_REL:
+ return qat_hal_init_rd_xfer(handle, ae, ctx_mask, reg_type,
+ reg_addr, value);
+ case ICP_SR_WR_ABS:
+ case ICP_DR_WR_ABS:
+ ctx_mask = 0;
+ case ICP_SR_WR_REL:
+ case ICP_DR_WR_REL:
+ return qat_hal_init_wr_xfer(handle, ae, ctx_mask, reg_type,
+ reg_addr, value);
+ case ICP_NEIGH_REL:
+ return qat_hal_init_nn(handle, ae, ctx_mask, reg_addr, value);
+ default:
+ pr_err("QAT: UOF uses not supported reg type 0x%x\n", reg_type);
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int qat_uclo_init_reg_sym(struct icp_qat_fw_loader_handle *handle,
+ unsigned int ae,
+ struct icp_qat_uclo_encapme *encap_ae)
+{
+ unsigned int i;
+ unsigned char ctx_mask;
+ struct icp_qat_uof_init_regsym *init_regsym;
+
+ if (ICP_QAT_CTX_MODE(encap_ae->img_ptr->ae_mode) ==
+ ICP_QAT_UCLO_MAX_CTX)
+ ctx_mask = 0xff;
+ else
+ ctx_mask = 0x55;
+
+ for (i = 0; i < encap_ae->init_regsym_num; i++) {
+ unsigned int exp_res;
+
+ init_regsym = &encap_ae->init_regsym[i];
+ exp_res = init_regsym->value;
+ switch (init_regsym->init_type) {
+ case ICP_QAT_UOF_INIT_REG:
+ qat_uclo_init_reg(handle, ae, ctx_mask,
+ (enum icp_qat_uof_regtype)
+ init_regsym->reg_type,
+ (unsigned short)init_regsym->reg_addr,
+ exp_res);
+ break;
+ case ICP_QAT_UOF_INIT_REG_CTX:
+ /* check if ctx is appropriate for the ctxMode */
+ if (!((1 << init_regsym->ctx) & ctx_mask)) {
+ pr_err("QAT: invalid ctx num = 0x%x\n",
+ init_regsym->ctx);
+ return -EINVAL;
+ }
+ qat_uclo_init_reg(handle, ae,
+ (unsigned char)
+ (1 << init_regsym->ctx),
+ (enum icp_qat_uof_regtype)
+ init_regsym->reg_type,
+ (unsigned short)init_regsym->reg_addr,
+ exp_res);
+ break;
+ case ICP_QAT_UOF_INIT_EXPR:
+ pr_err("QAT: INIT_EXPR feature not supported\n");
+ return -EINVAL;
+ case ICP_QAT_UOF_INIT_EXPR_ENDIAN_SWAP:
+ pr_err("QAT: INIT_EXPR_ENDIAN_SWAP feature not supported\n");
+ return -EINVAL;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+static int qat_uclo_init_globals(struct icp_qat_fw_loader_handle *handle)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int s, ae;
+
+ if (obj_handle->global_inited)
+ return 0;
+ if (obj_handle->init_mem_tab.entry_num) {
+ if (qat_uclo_init_memory(handle)) {
+ pr_err("QAT: initialize memory failed\n");
+ return -EINVAL;
+ }
+ }
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
+ if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
+ continue;
+ if (qat_uclo_init_reg_sym(handle, ae,
+ obj_handle->ae_data[ae].
+ ae_slices[s].encap_image))
+ return -EINVAL;
+ }
+ }
+ obj_handle->global_inited = 1;
+ return 0;
+}
+
+static int qat_uclo_set_ae_mode(struct icp_qat_fw_loader_handle *handle)
+{
+ unsigned char ae, nn_mode, s;
+ struct icp_qat_uof_image *uof_image;
+ struct icp_qat_uclo_aedata *ae_data;
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!test_bit(ae,
+ (unsigned long *)&handle->hal_handle->ae_mask))
+ continue;
+ ae_data = &obj_handle->ae_data[ae];
+ for (s = 0; s < min_t(unsigned int, ae_data->slice_num,
+ ICP_QAT_UCLO_MAX_CTX); s++) {
+ if (!obj_handle->ae_data[ae].ae_slices[s].encap_image)
+ continue;
+ uof_image = ae_data->ae_slices[s].encap_image->img_ptr;
+ if (qat_hal_set_ae_ctx_mode(handle, ae,
+ (char)ICP_QAT_CTX_MODE
+ (uof_image->ae_mode))) {
+ pr_err("QAT: qat_hal_set_ae_ctx_mode error\n");
+ return -EFAULT;
+ }
+ nn_mode = ICP_QAT_NN_MODE(uof_image->ae_mode);
+ if (qat_hal_set_ae_nn_mode(handle, ae, nn_mode)) {
+ pr_err("QAT: qat_hal_set_ae_nn_mode error\n");
+ return -EFAULT;
+ }
+ if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM0,
+ (char)ICP_QAT_LOC_MEM0_MODE
+ (uof_image->ae_mode))) {
+ pr_err("QAT: qat_hal_set_ae_lm_mode LMEM0 error\n");
+ return -EFAULT;
+ }
+ if (qat_hal_set_ae_lm_mode(handle, ae, ICP_LMEM1,
+ (char)ICP_QAT_LOC_MEM1_MODE
+ (uof_image->ae_mode))) {
+ pr_err("QAT: qat_hal_set_ae_lm_mode LMEM1 error\n");
+ return -EFAULT;
+ }
+ }
+ }
+ return 0;
+}
+
+static void qat_uclo_init_uword_num(struct icp_qat_fw_loader_handle *handle)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ struct icp_qat_uclo_encapme *image;
+ int a;
+
+ for (a = 0; a < obj_handle->uimage_num; a++) {
+ image = &obj_handle->ae_uimage[a];
+ image->uwords_num = image->page->beg_addr_p +
+ image->page->micro_words_num;
+ }
+}
+
+static int qat_uclo_parse_uof_obj(struct icp_qat_fw_loader_handle *handle)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int ae;
+
+ obj_handle->uword_buf = kcalloc(UWORD_CPYBUF_SIZE, sizeof(uint64_t),
+ GFP_KERNEL);
+ if (!obj_handle->uword_buf)
+ return -ENOMEM;
+ obj_handle->encap_uof_obj.beg_uof = obj_handle->obj_hdr->file_buff;
+ obj_handle->encap_uof_obj.obj_hdr = (struct icp_qat_uof_objhdr *)
+ obj_handle->obj_hdr->file_buff;
+ obj_handle->uword_in_bytes = 6;
+ obj_handle->prod_type = ICP_QAT_AC_C_CPU_TYPE;
+ obj_handle->prod_rev = PID_MAJOR_REV |
+ (PID_MINOR_REV & handle->hal_handle->revision_id);
+ if (qat_uclo_check_uof_compat(obj_handle)) {
+ pr_err("QAT: UOF incompatible\n");
+ return -EINVAL;
+ }
+ obj_handle->ustore_phy_size = ICP_QAT_UCLO_MAX_USTORE;
+ if (!obj_handle->obj_hdr->file_buff ||
+ !qat_uclo_map_str_table(obj_handle->obj_hdr, ICP_QAT_UOF_STRT,
+ &obj_handle->str_table)) {
+ pr_err("QAT: UOF doesn't have effective images\n");
+ goto out_err;
+ }
+ obj_handle->uimage_num =
+ qat_uclo_map_uimage(obj_handle, obj_handle->ae_uimage,
+ ICP_QAT_UCLO_MAX_AE * ICP_QAT_UCLO_MAX_CTX);
+ if (!obj_handle->uimage_num)
+ goto out_err;
+ if (qat_uclo_map_ae(handle, handle->hal_handle->ae_max_num)) {
+ pr_err("QAT: Bad object\n");
+ goto out_check_uof_aemask_err;
+ }
+ qat_uclo_init_uword_num(handle);
+ qat_uclo_map_initmem_table(&obj_handle->encap_uof_obj,
+ &obj_handle->init_mem_tab);
+ if (qat_uclo_set_ae_mode(handle))
+ goto out_check_uof_aemask_err;
+ return 0;
+out_check_uof_aemask_err:
+ for (ae = 0; ae < obj_handle->uimage_num; ae++)
+ kfree(obj_handle->ae_uimage[ae].page);
+out_err:
+ kfree(obj_handle->uword_buf);
+ return -EFAULT;
+}
+
+int qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle,
+ void *addr_ptr, int mem_size)
+{
+ struct icp_qat_uof_filehdr *filehdr;
+ struct icp_qat_uclo_objhandle *objhdl;
+
+ BUILD_BUG_ON(ICP_QAT_UCLO_MAX_AE >=
+ (sizeof(handle->hal_handle->ae_mask) * 8));
+
+ if (!handle || !addr_ptr || mem_size < 24)
+ return -EINVAL;
+ objhdl = kzalloc(sizeof(*objhdl), GFP_KERNEL);
+ if (!objhdl)
+ return -ENOMEM;
+ objhdl->obj_buf = kmemdup(addr_ptr, mem_size, GFP_KERNEL);
+ if (!objhdl->obj_buf)
+ goto out_objbuf_err;
+ filehdr = (struct icp_qat_uof_filehdr *)objhdl->obj_buf;
+ if (qat_uclo_check_format(filehdr))
+ goto out_objhdr_err;
+ objhdl->obj_hdr = qat_uclo_map_chunk((char *)objhdl->obj_buf, filehdr,
+ ICP_QAT_UOF_OBJS);
+ if (!objhdl->obj_hdr) {
+ pr_err("QAT: object file chunk is null\n");
+ goto out_objhdr_err;
+ }
+ handle->obj_handle = objhdl;
+ if (qat_uclo_parse_uof_obj(handle))
+ goto out_overlay_obj_err;
+ return 0;
+
+out_overlay_obj_err:
+ handle->obj_handle = NULL;
+ kfree(objhdl->obj_hdr);
+out_objhdr_err:
+ kfree(objhdl->obj_buf);
+out_objbuf_err:
+ kfree(objhdl);
+ return -ENOMEM;
+}
+
+void qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int a;
+
+ if (!obj_handle)
+ return;
+
+ kfree(obj_handle->uword_buf);
+ for (a = 0; a < obj_handle->uimage_num; a++)
+ kfree(obj_handle->ae_uimage[a].page);
+
+ for (a = 0; a < handle->hal_handle->ae_max_num; a++)
+ qat_uclo_free_ae_data(&obj_handle->ae_data[a]);
+
+ kfree(obj_handle->obj_hdr);
+ kfree(obj_handle->obj_buf);
+ kfree(obj_handle);
+ handle->obj_handle = NULL;
+}
+
+static void qat_uclo_fill_uwords(struct icp_qat_uclo_objhandle *obj_handle,
+ struct icp_qat_uclo_encap_page *encap_page,
+ uint64_t *uword, unsigned int addr_p,
+ unsigned int raddr, uint64_t fill)
+{
+ uint64_t uwrd = 0;
+ unsigned int i;
+
+ if (!encap_page) {
+ *uword = fill;
+ return;
+ }
+ for (i = 0; i < encap_page->uwblock_num; i++) {
+ if (raddr >= encap_page->uwblock[i].start_addr &&
+ raddr <= encap_page->uwblock[i].start_addr +
+ encap_page->uwblock[i].words_num - 1) {
+ raddr -= encap_page->uwblock[i].start_addr;
+ raddr *= obj_handle->uword_in_bytes;
+ memcpy(&uwrd, (void *)(((unsigned long)
+ encap_page->uwblock[i].micro_words) + raddr),
+ obj_handle->uword_in_bytes);
+ uwrd = uwrd & 0xbffffffffffull;
+ }
+ }
+ *uword = uwrd;
+ if (*uword == INVLD_UWORD)
+ *uword = fill;
+}
+
+static void qat_uclo_wr_uimage_raw_page(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uclo_encap_page
+ *encap_page, unsigned int ae)
+{
+ unsigned int uw_physical_addr, uw_relative_addr, i, words_num, cpylen;
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ uint64_t fill_pat;
+
+ /* load the page starting at appropriate ustore address */
+ /* get fill-pattern from an image -- they are all the same */
+ memcpy(&fill_pat, obj_handle->ae_uimage[0].img_ptr->fill_pattern,
+ sizeof(uint64_t));
+ uw_physical_addr = encap_page->beg_addr_p;
+ uw_relative_addr = 0;
+ words_num = encap_page->micro_words_num;
+ while (words_num) {
+ if (words_num < UWORD_CPYBUF_SIZE)
+ cpylen = words_num;
+ else
+ cpylen = UWORD_CPYBUF_SIZE;
+
+ /* load the buffer */
+ for (i = 0; i < cpylen; i++)
+ qat_uclo_fill_uwords(obj_handle, encap_page,
+ &obj_handle->uword_buf[i],
+ uw_physical_addr + i,
+ uw_relative_addr + i, fill_pat);
+
+ /* copy the buffer to ustore */
+ qat_hal_wr_uwords(handle, (unsigned char)ae,
+ uw_physical_addr, cpylen,
+ obj_handle->uword_buf);
+
+ uw_physical_addr += cpylen;
+ uw_relative_addr += cpylen;
+ words_num -= cpylen;
+ }
+}
+
+static void qat_uclo_wr_uimage_page(struct icp_qat_fw_loader_handle *handle,
+ struct icp_qat_uof_image *image)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int ctx_mask, s;
+ struct icp_qat_uclo_page *page;
+ unsigned char ae;
+ int ctx;
+
+ if (ICP_QAT_CTX_MODE(image->ae_mode) == ICP_QAT_UCLO_MAX_CTX)
+ ctx_mask = 0xff;
+ else
+ ctx_mask = 0x55;
+ /* load the default page and set assigned CTX PC
+ * to the entrypoint address */
+ for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
+ if (!test_bit(ae, (unsigned long *)&image->ae_assigned))
+ continue;
+ /* find the slice to which this image is assigned */
+ for (s = 0; s < obj_handle->ae_data[ae].slice_num; s++) {
+ if (image->ctx_assigned & obj_handle->ae_data[ae].
+ ae_slices[s].ctx_mask_assigned)
+ break;
+ }
+ if (s >= obj_handle->ae_data[ae].slice_num)
+ continue;
+ page = obj_handle->ae_data[ae].ae_slices[s].page;
+ if (!page->encap_page->def_page)
+ continue;
+ qat_uclo_wr_uimage_raw_page(handle, page->encap_page, ae);
+
+ page = obj_handle->ae_data[ae].ae_slices[s].page;
+ for (ctx = 0; ctx < ICP_QAT_UCLO_MAX_CTX; ctx++)
+ obj_handle->ae_data[ae].ae_slices[s].cur_page[ctx] =
+ (ctx_mask & (1 << ctx)) ? page : NULL;
+ qat_hal_set_live_ctx(handle, (unsigned char)ae,
+ image->ctx_assigned);
+ qat_hal_set_pc(handle, (unsigned char)ae, image->ctx_assigned,
+ image->entry_address);
+ }
+}
+
+int qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle)
+{
+ struct icp_qat_uclo_objhandle *obj_handle = handle->obj_handle;
+ unsigned int i;
+
+ if (qat_uclo_init_globals(handle))
+ return -EINVAL;
+ for (i = 0; i < obj_handle->uimage_num; i++) {
+ if (!obj_handle->ae_uimage[i].img_ptr)
+ return -EINVAL;
+ if (qat_uclo_init_ustore(handle, &obj_handle->ae_uimage[i]))
+ return -EINVAL;
+ qat_uclo_wr_uimage_page(handle,
+ obj_handle->ae_uimage[i].img_ptr);
+ }
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_dh895xcc/Makefile b/drivers/crypto/qat/qat_dh895xcc/Makefile
new file mode 100644
index 000000000000..25171c557043
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/Makefile
@@ -0,0 +1,8 @@
+ccflags-y := -I$(src)/../qat_common
+obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc.o
+qat_dh895xcc-objs := adf_drv.o \
+ adf_isr.o \
+ adf_dh895xcc_hw_data.o \
+ adf_hw_arbiter.o \
+ qat_admin.o \
+ adf_admin.o
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_admin.c b/drivers/crypto/qat/qat_dh895xcc/adf_admin.c
new file mode 100644
index 000000000000..978d6c56639d
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_admin.c
@@ -0,0 +1,144 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <adf_accel_devices.h>
+#include "adf_drv.h"
+#include "adf_dh895xcc_hw_data.h"
+
+#define ADF_ADMINMSG_LEN 32
+
+struct adf_admin_comms {
+ dma_addr_t phy_addr;
+ void *virt_addr;
+ void __iomem *mailbox_addr;
+ struct mutex lock; /* protects adf_admin_comms struct */
+};
+
+int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev,
+ uint32_t ae, void *in, void *out)
+{
+ struct adf_admin_comms *admin = accel_dev->admin;
+ int offset = ae * ADF_ADMINMSG_LEN * 2;
+ void __iomem *mailbox = admin->mailbox_addr;
+ int mb_offset = ae * ADF_DH895XCC_MAILBOX_STRIDE;
+ int times, received;
+
+ mutex_lock(&admin->lock);
+
+ if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
+ mutex_unlock(&admin->lock);
+ return -EAGAIN;
+ }
+
+ memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
+ ADF_CSR_WR(mailbox, mb_offset, 1);
+ received = 0;
+ for (times = 0; times < 50; times++) {
+ msleep(20);
+ if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
+ received = 1;
+ break;
+ }
+ }
+ if (received)
+ memcpy(out, admin->virt_addr + offset +
+ ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
+ else
+ pr_err("QAT: Failed to send admin msg to accelerator\n");
+
+ mutex_unlock(&admin->lock);
+ return received ? 0 : -EFAULT;
+}
+
+int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
+{
+ struct adf_admin_comms *admin;
+ struct adf_bar *pmisc = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR];
+ void __iomem *csr = pmisc->virt_addr;
+ void __iomem *mailbox = csr + ADF_DH895XCC_MAILBOX_BASE_OFFSET;
+ uint64_t reg_val;
+
+ admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
+ accel_dev->numa_node);
+ if (!admin)
+ return -ENOMEM;
+ admin->virt_addr = dma_zalloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
+ &admin->phy_addr, GFP_KERNEL);
+ if (!admin->virt_addr) {
+ dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
+ kfree(admin);
+ return -ENOMEM;
+ }
+ reg_val = (uint64_t)admin->phy_addr;
+ ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGUR_OFFSET, reg_val >> 32);
+ ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGLR_OFFSET, reg_val);
+ mutex_init(&admin->lock);
+ admin->mailbox_addr = mailbox;
+ accel_dev->admin = admin;
+ return 0;
+}
+
+void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
+{
+ struct adf_admin_comms *admin = accel_dev->admin;
+
+ if (!admin)
+ return;
+
+ if (admin->virt_addr)
+ dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
+ admin->virt_addr, admin->phy_addr);
+
+ mutex_destroy(&admin->lock);
+ kfree(admin);
+ accel_dev->admin = NULL;
+}
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
new file mode 100644
index 000000000000..ef05825cc651
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
@@ -0,0 +1,214 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <adf_accel_devices.h>
+#include "adf_dh895xcc_hw_data.h"
+#include "adf_drv.h"
+
+/* Worker thread to service arbiter mappings based on dev SKUs */
+static const uint32_t thrd_to_arb_map_sku4[] = {
+ 0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666,
+ 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static const uint32_t thrd_to_arb_map_sku6[] = {
+ 0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666,
+ 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222,
+ 0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222
+};
+
+static struct adf_hw_device_class dh895xcc_class = {
+ .name = ADF_DH895XCC_DEVICE_NAME,
+ .type = DEV_DH895XCC,
+ .instances = 0
+};
+
+static uint32_t get_accel_mask(uint32_t fuse)
+{
+ return (~fuse) >> ADF_DH895XCC_ACCELERATORS_REG_OFFSET &
+ ADF_DH895XCC_ACCELERATORS_MASK;
+}
+
+static uint32_t get_ae_mask(uint32_t fuse)
+{
+ return (~fuse) & ADF_DH895XCC_ACCELENGINES_MASK;
+}
+
+static uint32_t get_num_accels(struct adf_hw_device_data *self)
+{
+ uint32_t i, ctr = 0;
+
+ if (!self || !self->accel_mask)
+ return 0;
+
+ for (i = 0; i < ADF_DH895XCC_MAX_ACCELERATORS; i++) {
+ if (self->accel_mask & (1 << i))
+ ctr++;
+ }
+ return ctr;
+}
+
+static uint32_t get_num_aes(struct adf_hw_device_data *self)
+{
+ uint32_t i, ctr = 0;
+
+ if (!self || !self->ae_mask)
+ return 0;
+
+ for (i = 0; i < ADF_DH895XCC_MAX_ACCELENGINES; i++) {
+ if (self->ae_mask & (1 << i))
+ ctr++;
+ }
+ return ctr;
+}
+
+static uint32_t get_misc_bar_id(struct adf_hw_device_data *self)
+{
+ return ADF_DH895XCC_PMISC_BAR;
+}
+
+static uint32_t get_etr_bar_id(struct adf_hw_device_data *self)
+{
+ return ADF_DH895XCC_ETR_BAR;
+}
+
+static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
+{
+ int sku = (self->fuses & ADF_DH895XCC_FUSECTL_SKU_MASK)
+ >> ADF_DH895XCC_FUSECTL_SKU_SHIFT;
+
+ switch (sku) {
+ case ADF_DH895XCC_FUSECTL_SKU_1:
+ return DEV_SKU_1;
+ case ADF_DH895XCC_FUSECTL_SKU_2:
+ return DEV_SKU_2;
+ case ADF_DH895XCC_FUSECTL_SKU_3:
+ return DEV_SKU_3;
+ case ADF_DH895XCC_FUSECTL_SKU_4:
+ return DEV_SKU_4;
+ default:
+ return DEV_SKU_UNKNOWN;
+ }
+ return DEV_SKU_UNKNOWN;
+}
+
+void adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
+ uint32_t const **arb_map_config)
+{
+ switch (accel_dev->accel_pci_dev.sku) {
+ case DEV_SKU_1:
+ *arb_map_config = thrd_to_arb_map_sku4;
+ break;
+
+ case DEV_SKU_2:
+ case DEV_SKU_4:
+ *arb_map_config = thrd_to_arb_map_sku6;
+ break;
+ default:
+ pr_err("QAT: The configuration doesn't match any SKU");
+ *arb_map_config = NULL;
+ }
+}
+
+static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+ struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR];
+ void __iomem *csr = misc_bar->virt_addr;
+ unsigned int val, i;
+
+ /* Enable Accel Engine error detection & correction */
+ for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
+ val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_CTX_ENABLES(i));
+ val |= ADF_DH895XCC_ENABLE_AE_ECC_ERR;
+ ADF_CSR_WR(csr, ADF_DH895XCC_AE_CTX_ENABLES(i), val);
+ val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_MISC_CONTROL(i));
+ val |= ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR;
+ ADF_CSR_WR(csr, ADF_DH895XCC_AE_MISC_CONTROL(i), val);
+ }
+
+ /* Enable shared memory error detection & correction */
+ for (i = 0; i < hw_device->get_num_accels(hw_device); i++) {
+ val = ADF_CSR_RD(csr, ADF_DH895XCC_UERRSSMSH(i));
+ val |= ADF_DH895XCC_ERRSSMSH_EN;
+ ADF_CSR_WR(csr, ADF_DH895XCC_UERRSSMSH(i), val);
+ val = ADF_CSR_RD(csr, ADF_DH895XCC_CERRSSMSH(i));
+ val |= ADF_DH895XCC_ERRSSMSH_EN;
+ ADF_CSR_WR(csr, ADF_DH895XCC_CERRSSMSH(i), val);
+ }
+}
+
+void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
+{
+ hw_data->dev_class = &dh895xcc_class;
+ hw_data->instance_id = dh895xcc_class.instances++;
+ hw_data->num_banks = ADF_DH895XCC_ETR_MAX_BANKS;
+ hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS;
+ hw_data->pci_dev_id = ADF_DH895XCC_PCI_DEVICE_ID;
+ hw_data->num_logical_accel = 1;
+ hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES;
+ hw_data->tx_rx_gap = ADF_DH895XCC_RX_RINGS_OFFSET;
+ hw_data->tx_rings_mask = ADF_DH895XCC_TX_RINGS_MASK;
+ hw_data->alloc_irq = adf_isr_resource_alloc;
+ hw_data->free_irq = adf_isr_resource_free;
+ hw_data->enable_error_correction = adf_enable_error_correction;
+ hw_data->hw_arb_ring_enable = adf_update_ring_arb_enable;
+ hw_data->hw_arb_ring_disable = adf_update_ring_arb_enable;
+ hw_data->get_accel_mask = get_accel_mask;
+ hw_data->get_ae_mask = get_ae_mask;
+ hw_data->get_num_accels = get_num_accels;
+ hw_data->get_num_aes = get_num_aes;
+ hw_data->get_etr_bar_id = get_etr_bar_id;
+ hw_data->get_misc_bar_id = get_misc_bar_id;
+ hw_data->get_sku = get_sku;
+ hw_data->fw_name = ADF_DH895XCC_FW;
+}
+
+void adf_clean_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
+{
+ hw_data->dev_class->instances--;
+}
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h
new file mode 100644
index 000000000000..b707f292b377
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h
@@ -0,0 +1,86 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_DH895x_HW_DATA_H_
+#define ADF_DH895x_HW_DATA_H_
+
+/* PCIe configuration space */
+#define ADF_DH895XCC_RX_RINGS_OFFSET 8
+#define ADF_DH895XCC_TX_RINGS_MASK 0xFF
+#define ADF_DH895XCC_FUSECTL_OFFSET 0x40
+#define ADF_DH895XCC_FUSECTL_SKU_MASK 0x300000
+#define ADF_DH895XCC_FUSECTL_SKU_SHIFT 20
+#define ADF_DH895XCC_FUSECTL_SKU_1 0x0
+#define ADF_DH895XCC_FUSECTL_SKU_2 0x1
+#define ADF_DH895XCC_FUSECTL_SKU_3 0x2
+#define ADF_DH895XCC_FUSECTL_SKU_4 0x3
+#define ADF_DH895XCC_MAX_ACCELERATORS 6
+#define ADF_DH895XCC_MAX_ACCELENGINES 12
+#define ADF_DH895XCC_ACCELERATORS_REG_OFFSET 13
+#define ADF_DH895XCC_ACCELERATORS_MASK 0x3F
+#define ADF_DH895XCC_ACCELENGINES_MASK 0xFFF
+#define ADF_DH895XCC_LEGFUSE_OFFSET 0x4C
+#define ADF_DH895XCC_ETR_MAX_BANKS 32
+#define ADF_DH895XCC_SMIAPF0_MASK_OFFSET (0x3A000 + 0x28)
+#define ADF_DH895XCC_SMIAPF1_MASK_OFFSET (0x3A000 + 0x30)
+#define ADF_DH895XCC_SMIA0_MASK 0xFFFF
+#define ADF_DH895XCC_SMIA1_MASK 0x1
+/* Error detection and correction */
+#define ADF_DH895XCC_AE_CTX_ENABLES(i) (i * 0x1000 + 0x20818)
+#define ADF_DH895XCC_AE_MISC_CONTROL(i) (i * 0x1000 + 0x20960)
+#define ADF_DH895XCC_ENABLE_AE_ECC_ERR (1 << 28)
+#define ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR (1 << 24 | 1 << 12)
+#define ADF_DH895XCC_UERRSSMSH(i) (i * 0x4000 + 0x18)
+#define ADF_DH895XCC_CERRSSMSH(i) (i * 0x4000 + 0x10)
+#define ADF_DH895XCC_ERRSSMSH_EN (1 << 3)
+
+/* Admin Messages Registers */
+#define ADF_DH895XCC_ADMINMSGUR_OFFSET (0x3A000 + 0x574)
+#define ADF_DH895XCC_ADMINMSGLR_OFFSET (0x3A000 + 0x578)
+#define ADF_DH895XCC_MAILBOX_BASE_OFFSET 0x20970
+#define ADF_DH895XCC_MAILBOX_STRIDE 0x1000
+#define ADF_DH895XCC_FW "qat_895xcc.bin"
+#endif
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c
new file mode 100644
index 000000000000..0d0435a41be9
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c
@@ -0,0 +1,449 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <adf_accel_devices.h>
+#include <adf_common_drv.h>
+#include <adf_cfg.h>
+#include <adf_transport_access_macros.h>
+#include "adf_dh895xcc_hw_data.h"
+#include "adf_drv.h"
+
+static const char adf_driver_name[] = ADF_DH895XCC_DEVICE_NAME;
+
+#define ADF_SYSTEM_DEVICE(device_id) \
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
+
+static const struct pci_device_id adf_pci_tbl[] = {
+ ADF_SYSTEM_DEVICE(ADF_DH895XCC_PCI_DEVICE_ID),
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, adf_pci_tbl);
+
+static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent);
+static void adf_remove(struct pci_dev *dev);
+
+static struct pci_driver adf_driver = {
+ .id_table = adf_pci_tbl,
+ .name = adf_driver_name,
+ .probe = adf_probe,
+ .remove = adf_remove
+};
+
+static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
+{
+ struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
+ int i;
+
+ adf_exit_admin_comms(accel_dev);
+ adf_exit_arb(accel_dev);
+ adf_cleanup_etr_data(accel_dev);
+
+ for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
+ struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
+
+ if (bar->virt_addr)
+ pci_iounmap(accel_pci_dev->pci_dev, bar->virt_addr);
+ }
+
+ if (accel_dev->hw_device) {
+ switch (accel_dev->hw_device->pci_dev_id) {
+ case ADF_DH895XCC_PCI_DEVICE_ID:
+ adf_clean_hw_data_dh895xcc(accel_dev->hw_device);
+ break;
+ default:
+ break;
+ }
+ kfree(accel_dev->hw_device);
+ }
+ adf_cfg_dev_remove(accel_dev);
+ debugfs_remove(accel_dev->debugfs_dir);
+ adf_devmgr_rm_dev(accel_dev);
+ pci_release_regions(accel_pci_dev->pci_dev);
+ pci_disable_device(accel_pci_dev->pci_dev);
+ kfree(accel_dev);
+}
+
+static uint8_t adf_get_dev_node_id(struct pci_dev *pdev)
+{
+ unsigned int bus_per_cpu = 0;
+ struct cpuinfo_x86 *c = &cpu_data(num_online_cpus() - 1);
+
+ if (!c->phys_proc_id)
+ return 0;
+
+ bus_per_cpu = 256 / (c->phys_proc_id + 1);
+
+ if (bus_per_cpu != 0)
+ return pdev->bus->number / bus_per_cpu;
+ return 0;
+}
+
+static int qat_dev_start(struct adf_accel_dev *accel_dev)
+{
+ int cpus = num_online_cpus();
+ int banks = GET_MAX_BANKS(accel_dev);
+ int instances = min(cpus, banks);
+ char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
+ int i;
+ unsigned long val;
+
+ if (adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC))
+ goto err;
+ if (adf_cfg_section_add(accel_dev, "Accelerator0"))
+ goto err;
+ for (i = 0; i < instances; i++) {
+ val = i;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
+ i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, i);
+ val = 128;
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 512;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 0;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 2;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 4;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_RND_TX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 8;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 10;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = 12;
+ snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_RND_RX, i);
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ key, (void *)&val, ADF_DEC))
+ goto err;
+
+ val = ADF_COALESCING_DEF_TIME;
+ snprintf(key, sizeof(key), ADF_ETRMGR_COALESCE_TIMER_FORMAT, i);
+ if (adf_cfg_add_key_value_param(accel_dev, "Accelerator0",
+ key, (void *)&val, ADF_DEC))
+ goto err;
+ }
+
+ val = i;
+ if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
+ ADF_NUM_CY, (void *)&val, ADF_DEC))
+ goto err;
+
+ set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
+ return adf_dev_start(accel_dev);
+err:
+ dev_err(&GET_DEV(accel_dev), "Failed to start QAT accel dev\n");
+ return -EINVAL;
+}
+
+static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct adf_accel_dev *accel_dev;
+ struct adf_accel_pci *accel_pci_dev;
+ struct adf_hw_device_data *hw_data;
+ void __iomem *pmisc_bar_addr = NULL;
+ char name[ADF_DEVICE_NAME_LENGTH];
+ unsigned int i, bar_nr;
+ uint8_t node;
+ int ret;
+
+ switch (ent->device) {
+ case ADF_DH895XCC_PCI_DEVICE_ID:
+ break;
+ default:
+ dev_err(&pdev->dev, "Invalid device 0x%x.\n", ent->device);
+ return -ENODEV;
+ }
+
+ node = adf_get_dev_node_id(pdev);
+ accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL, node);
+ if (!accel_dev)
+ return -ENOMEM;
+
+ accel_dev->numa_node = node;
+ INIT_LIST_HEAD(&accel_dev->crypto_list);
+
+ /* Add accel device to accel table.
+ * This should be called before adf_cleanup_accel is called */
+ if (adf_devmgr_add_dev(accel_dev)) {
+ dev_err(&pdev->dev, "Failed to add new accelerator device.\n");
+ kfree(accel_dev);
+ return -EFAULT;
+ }
+
+ accel_dev->owner = THIS_MODULE;
+ /* Allocate and configure device configuration structure */
+ hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL, node);
+ if (!hw_data) {
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ accel_dev->hw_device = hw_data;
+ switch (ent->device) {
+ case ADF_DH895XCC_PCI_DEVICE_ID:
+ adf_init_hw_data_dh895xcc(accel_dev->hw_device);
+ break;
+ default:
+ return -ENODEV;
+ }
+ accel_pci_dev = &accel_dev->accel_pci_dev;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &accel_pci_dev->revid);
+ pci_read_config_dword(pdev, ADF_DH895XCC_FUSECTL_OFFSET,
+ &hw_data->fuses);
+
+ /* Get Accelerators and Accelerators Engines masks */
+ hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses);
+ hw_data->ae_mask = hw_data->get_ae_mask(hw_data->fuses);
+ accel_pci_dev->sku = hw_data->get_sku(hw_data);
+ accel_pci_dev->pci_dev = pdev;
+ /* If the device has no acceleration engines then ignore it. */
+ if (!hw_data->accel_mask || !hw_data->ae_mask ||
+ ((~hw_data->ae_mask) & 0x01)) {
+ dev_err(&pdev->dev, "No acceleration units found");
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ /* Create dev top level debugfs entry */
+ snprintf(name, sizeof(name), "%s%s_dev%d", ADF_DEVICE_NAME_PREFIX,
+ hw_data->dev_class->name, hw_data->instance_id);
+ accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
+ if (!accel_dev->debugfs_dir) {
+ dev_err(&pdev->dev, "Could not create debugfs dir\n");
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ /* Create device configuration table */
+ ret = adf_cfg_dev_add(accel_dev);
+ if (ret)
+ goto out_err;
+
+ /* enable PCI device */
+ if (pci_enable_device(pdev)) {
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ /* set dma identifier */
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
+ dev_err(&pdev->dev, "No usable DMA configuration\n");
+ ret = -EFAULT;
+ goto out_err;
+ } else {
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+ }
+
+ } else {
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+ }
+
+ if (pci_request_regions(pdev, adf_driver_name)) {
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ /* Read accelerator capabilities mask */
+ pci_read_config_dword(pdev, ADF_DH895XCC_LEGFUSE_OFFSET,
+ &hw_data->accel_capabilities_mask);
+
+ /* Find and map all the device's BARS */
+ for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
+ struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
+
+ bar_nr = i * 2;
+ bar->base_addr = pci_resource_start(pdev, bar_nr);
+ if (!bar->base_addr)
+ break;
+ bar->size = pci_resource_len(pdev, bar_nr);
+ bar->virt_addr = pci_iomap(accel_pci_dev->pci_dev, bar_nr, 0);
+ if (!bar->virt_addr) {
+ dev_err(&pdev->dev, "Failed to map BAR %d\n", i);
+ ret = -EFAULT;
+ goto out_err;
+ }
+ if (i == ADF_DH895XCC_PMISC_BAR)
+ pmisc_bar_addr = bar->virt_addr;
+ }
+ pci_set_master(pdev);
+
+ if (adf_enable_aer(accel_dev, &adf_driver)) {
+ dev_err(&pdev->dev, "Failed to enable aer\n");
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ if (adf_init_etr_data(accel_dev)) {
+ dev_err(&pdev->dev, "Failed initialize etr\n");
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ if (adf_init_admin_comms(accel_dev)) {
+ dev_err(&pdev->dev, "Failed initialize admin comms\n");
+ ret = -EFAULT;
+ goto out_err;
+ }
+
+ if (adf_init_arb(accel_dev)) {
+ dev_err(&pdev->dev, "Failed initialize hw arbiter\n");
+ ret = -EFAULT;
+ goto out_err;
+ }
+ if (pci_save_state(pdev)) {
+ dev_err(&pdev->dev, "Failed to save pci state\n");
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ /* Enable bundle and misc interrupts */
+ ADF_CSR_WR(pmisc_bar_addr, ADF_DH895XCC_SMIAPF0_MASK_OFFSET,
+ ADF_DH895XCC_SMIA0_MASK);
+ ADF_CSR_WR(pmisc_bar_addr, ADF_DH895XCC_SMIAPF1_MASK_OFFSET,
+ ADF_DH895XCC_SMIA1_MASK);
+
+ ret = qat_dev_start(accel_dev);
+ if (ret) {
+ adf_dev_stop(accel_dev);
+ goto out_err;
+ }
+
+ return 0;
+out_err:
+ adf_cleanup_accel(accel_dev);
+ return ret;
+}
+
+static void __exit adf_remove(struct pci_dev *pdev)
+{
+ struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+
+ if (!accel_dev) {
+ pr_err("QAT: Driver removal failed\n");
+ return;
+ }
+ if (adf_dev_stop(accel_dev))
+ dev_err(&GET_DEV(accel_dev), "Failed to stop QAT accel dev\n");
+ adf_disable_aer(accel_dev);
+ adf_cleanup_accel(accel_dev);
+}
+
+static int __init adfdrv_init(void)
+{
+ request_module("intel_qat");
+ if (qat_admin_register())
+ return -EFAULT;
+
+ if (pci_register_driver(&adf_driver)) {
+ pr_err("QAT: Driver initialization failed\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void __exit adfdrv_release(void)
+{
+ pci_unregister_driver(&adf_driver);
+ qat_admin_unregister();
+}
+
+module_init(adfdrv_init);
+module_exit(adfdrv_release);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel");
+MODULE_FIRMWARE("qat_895xcc.bin");
+MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_drv.h b/drivers/crypto/qat/qat_dh895xcc/adf_drv.h
new file mode 100644
index 000000000000..a2fbb6ce75cd
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_drv.h
@@ -0,0 +1,67 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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.
+*/
+#ifndef ADF_DH895x_DRV_H_
+#define ADF_DH895x_DRV_H_
+#include <adf_accel_devices.h>
+#include <adf_transport.h>
+
+void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data);
+void adf_clean_hw_data_dh895xcc(struct adf_hw_device_data *hw_data);
+int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev);
+void adf_isr_resource_free(struct adf_accel_dev *accel_dev);
+void adf_update_ring_arb_enable(struct adf_etr_ring_data *ring);
+void adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
+ uint32_t const **arb_map_config);
+int adf_init_admin_comms(struct adf_accel_dev *accel_dev);
+void adf_exit_admin_comms(struct adf_accel_dev *accel_dev);
+int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev,
+ uint32_t ae, void *in, void *out);
+int qat_admin_register(void);
+int qat_admin_unregister(void);
+int adf_init_arb(struct adf_accel_dev *accel_dev);
+void adf_exit_arb(struct adf_accel_dev *accel_dev);
+#endif
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c b/drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c
new file mode 100644
index 000000000000..1864bdb36f8f
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_hw_arbiter.c
@@ -0,0 +1,159 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <adf_accel_devices.h>
+#include <adf_transport_internal.h>
+#include "adf_drv.h"
+
+#define ADF_ARB_NUM 4
+#define ADF_ARB_REQ_RING_NUM 8
+#define ADF_ARB_REG_SIZE 0x4
+#define ADF_ARB_WTR_SIZE 0x20
+#define ADF_ARB_OFFSET 0x30000
+#define ADF_ARB_REG_SLOT 0x1000
+#define ADF_ARB_WTR_OFFSET 0x010
+#define ADF_ARB_RO_EN_OFFSET 0x090
+#define ADF_ARB_WQCFG_OFFSET 0x100
+#define ADF_ARB_WRK_2_SER_MAP_OFFSET 0x180
+#define ADF_ARB_WRK_2_SER_MAP 10
+#define ADF_ARB_RINGSRVARBEN_OFFSET 0x19C
+
+#define WRITE_CSR_ARB_RINGSRVARBEN(csr_addr, index, value) \
+ ADF_CSR_WR(csr_addr, ADF_ARB_RINGSRVARBEN_OFFSET + \
+ (ADF_ARB_REG_SLOT * index), value)
+
+#define WRITE_CSR_ARB_RESPORDERING(csr_addr, index, value) \
+ ADF_CSR_WR(csr_addr, (ADF_ARB_OFFSET + \
+ ADF_ARB_RO_EN_OFFSET) + (ADF_ARB_REG_SIZE * index), value)
+
+#define WRITE_CSR_ARB_WEIGHT(csr_addr, arb, index, value) \
+ ADF_CSR_WR(csr_addr, (ADF_ARB_OFFSET + \
+ ADF_ARB_WTR_OFFSET) + (ADF_ARB_WTR_SIZE * arb) + \
+ (ADF_ARB_REG_SIZE * index), value)
+
+#define WRITE_CSR_ARB_SARCONFIG(csr_addr, index, value) \
+ ADF_CSR_WR(csr_addr, ADF_ARB_OFFSET + \
+ (ADF_ARB_REG_SIZE * index), value)
+
+#define WRITE_CSR_ARB_WRK_2_SER_MAP(csr_addr, index, value) \
+ ADF_CSR_WR(csr_addr, (ADF_ARB_OFFSET + \
+ ADF_ARB_WRK_2_SER_MAP_OFFSET) + \
+ (ADF_ARB_REG_SIZE * index), value)
+
+#define WRITE_CSR_ARB_WQCFG(csr_addr, index, value) \
+ ADF_CSR_WR(csr_addr, (ADF_ARB_OFFSET + \
+ ADF_ARB_WQCFG_OFFSET) + (ADF_ARB_REG_SIZE * index), value)
+
+int adf_init_arb(struct adf_accel_dev *accel_dev)
+{
+ void __iomem *csr = accel_dev->transport->banks[0].csr_addr;
+ uint32_t arb_cfg = 0x1 << 31 | 0x4 << 4 | 0x1;
+ uint32_t arb, i;
+ const uint32_t *thd_2_arb_cfg;
+
+ /* Service arb configured for 32 bytes responses and
+ * ring flow control check enabled. */
+ for (arb = 0; arb < ADF_ARB_NUM; arb++)
+ WRITE_CSR_ARB_SARCONFIG(csr, arb, arb_cfg);
+
+ /* Setup service weighting */
+ for (arb = 0; arb < ADF_ARB_NUM; arb++)
+ for (i = 0; i < ADF_ARB_REQ_RING_NUM; i++)
+ WRITE_CSR_ARB_WEIGHT(csr, arb, i, 0xFFFFFFFF);
+
+ /* Setup ring response ordering */
+ for (i = 0; i < ADF_ARB_REQ_RING_NUM; i++)
+ WRITE_CSR_ARB_RESPORDERING(csr, i, 0xFFFFFFFF);
+
+ /* Setup worker queue registers */
+ for (i = 0; i < ADF_ARB_WRK_2_SER_MAP; i++)
+ WRITE_CSR_ARB_WQCFG(csr, i, i);
+
+ /* Map worker threads to service arbiters */
+ adf_get_arbiter_mapping(accel_dev, &thd_2_arb_cfg);
+
+ if (!thd_2_arb_cfg)
+ return -EFAULT;
+
+ for (i = 0; i < ADF_ARB_WRK_2_SER_MAP; i++)
+ WRITE_CSR_ARB_WRK_2_SER_MAP(csr, i, *(thd_2_arb_cfg + i));
+
+ return 0;
+}
+
+void adf_update_ring_arb_enable(struct adf_etr_ring_data *ring)
+{
+ WRITE_CSR_ARB_RINGSRVARBEN(ring->bank->csr_addr,
+ ring->bank->bank_number,
+ ring->bank->ring_mask & 0xFF);
+}
+
+void adf_exit_arb(struct adf_accel_dev *accel_dev)
+{
+ void __iomem *csr;
+ unsigned int i;
+
+ if (!accel_dev->transport)
+ return;
+
+ csr = accel_dev->transport->banks[0].csr_addr;
+
+ /* Reset arbiter configuration */
+ for (i = 0; i < ADF_ARB_NUM; i++)
+ WRITE_CSR_ARB_SARCONFIG(csr, i, 0);
+
+ /* Shutdown work queue */
+ for (i = 0; i < ADF_ARB_WRK_2_SER_MAP; i++)
+ WRITE_CSR_ARB_WQCFG(csr, i, 0);
+
+ /* Unmap worker threads to service arbiters */
+ for (i = 0; i < ADF_ARB_WRK_2_SER_MAP; i++)
+ WRITE_CSR_ARB_WRK_2_SER_MAP(csr, i, 0);
+
+ /* Disable arbitration on all rings */
+ for (i = 0; i < GET_MAX_BANKS(accel_dev); i++)
+ WRITE_CSR_ARB_RINGSRVARBEN(csr, i, 0);
+}
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_isr.c b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c
new file mode 100644
index 000000000000..d4172dedf775
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_isr.c
@@ -0,0 +1,266 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <adf_accel_devices.h>
+#include <adf_common_drv.h>
+#include <adf_cfg.h>
+#include <adf_cfg_strings.h>
+#include <adf_cfg_common.h>
+#include <adf_transport_access_macros.h>
+#include <adf_transport_internal.h>
+#include "adf_drv.h"
+
+static int adf_enable_msix(struct adf_accel_dev *accel_dev)
+{
+ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint32_t msix_num_entries = hw_data->num_banks + 1;
+ int i;
+
+ for (i = 0; i < msix_num_entries; i++)
+ pci_dev_info->msix_entries.entries[i].entry = i;
+
+ if (pci_enable_msix(pci_dev_info->pci_dev,
+ pci_dev_info->msix_entries.entries,
+ msix_num_entries)) {
+ pr_err("QAT: Failed to enable MSIX IRQ\n");
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void adf_disable_msix(struct adf_accel_pci *pci_dev_info)
+{
+ pci_disable_msix(pci_dev_info->pci_dev);
+}
+
+static irqreturn_t adf_msix_isr_bundle(int irq, void *bank_ptr)
+{
+ struct adf_etr_bank_data *bank = bank_ptr;
+
+ WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, bank->bank_number, 0);
+ tasklet_hi_schedule(&bank->resp_hanlder);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
+{
+ struct adf_accel_dev *accel_dev = dev_ptr;
+
+ pr_info("QAT: qat_dev%d spurious AE interrupt\n", accel_dev->accel_id);
+ return IRQ_HANDLED;
+}
+
+static int adf_request_irqs(struct adf_accel_dev *accel_dev)
+{
+ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct msix_entry *msixe = pci_dev_info->msix_entries.entries;
+ struct adf_etr_data *etr_data = accel_dev->transport;
+ int ret, i;
+ char *name;
+
+ /* Request msix irq for all banks */
+ for (i = 0; i < hw_data->num_banks; i++) {
+ struct adf_etr_bank_data *bank = &etr_data->banks[i];
+ unsigned int cpu, cpus = num_online_cpus();
+
+ name = *(pci_dev_info->msix_entries.names + i);
+ snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
+ "qat%d-bundle%d", accel_dev->accel_id, i);
+ ret = request_irq(msixe[i].vector,
+ adf_msix_isr_bundle, 0, name, bank);
+ if (ret) {
+ pr_err("QAT: failed to enable irq %d for %s\n",
+ msixe[i].vector, name);
+ return ret;
+ }
+
+ cpu = ((accel_dev->accel_id * hw_data->num_banks) + i) % cpus;
+ irq_set_affinity_hint(msixe[i].vector, get_cpu_mask(cpu));
+ }
+
+ /* Request msix irq for AE */
+ name = *(pci_dev_info->msix_entries.names + i);
+ snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
+ "qat%d-ae-cluster", accel_dev->accel_id);
+ ret = request_irq(msixe[i].vector, adf_msix_isr_ae, 0, name, accel_dev);
+ if (ret) {
+ pr_err("QAT: failed to enable irq %d, for %s\n",
+ msixe[i].vector, name);
+ return ret;
+ }
+ return ret;
+}
+
+static void adf_free_irqs(struct adf_accel_dev *accel_dev)
+{
+ struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct msix_entry *msixe = pci_dev_info->msix_entries.entries;
+ struct adf_etr_data *etr_data = accel_dev->transport;
+ int i;
+
+ for (i = 0; i < hw_data->num_banks; i++) {
+ irq_set_affinity_hint(msixe[i].vector, NULL);
+ free_irq(msixe[i].vector, &etr_data->banks[i]);
+ }
+ irq_set_affinity_hint(msixe[i].vector, NULL);
+ free_irq(msixe[i].vector, accel_dev);
+}
+
+static int adf_isr_alloc_msix_entry_table(struct adf_accel_dev *accel_dev)
+{
+ int i;
+ char **names;
+ struct msix_entry *entries;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint32_t msix_num_entries = hw_data->num_banks + 1;
+
+ entries = kzalloc_node(msix_num_entries * sizeof(*entries),
+ GFP_KERNEL, accel_dev->numa_node);
+ if (!entries)
+ return -ENOMEM;
+
+ names = kcalloc(msix_num_entries, sizeof(char *), GFP_KERNEL);
+ if (!names) {
+ kfree(entries);
+ return -ENOMEM;
+ }
+ for (i = 0; i < msix_num_entries; i++) {
+ *(names + i) = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL);
+ if (!(*(names + i)))
+ goto err;
+ }
+ accel_dev->accel_pci_dev.msix_entries.entries = entries;
+ accel_dev->accel_pci_dev.msix_entries.names = names;
+ return 0;
+err:
+ for (i = 0; i < msix_num_entries; i++) {
+ if (*(names + i))
+ kfree(*(names + i));
+ }
+ kfree(entries);
+ kfree(names);
+ return -ENOMEM;
+}
+
+static void adf_isr_free_msix_entry_table(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ uint32_t msix_num_entries = hw_data->num_banks + 1;
+ char **names = accel_dev->accel_pci_dev.msix_entries.names;
+ int i;
+
+ kfree(accel_dev->accel_pci_dev.msix_entries.entries);
+ for (i = 0; i < msix_num_entries; i++) {
+ if (*(names + i))
+ kfree(*(names + i));
+ }
+ kfree(names);
+}
+
+static int adf_setup_bh(struct adf_accel_dev *accel_dev)
+{
+ struct adf_etr_data *priv_data = accel_dev->transport;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ int i;
+
+ for (i = 0; i < hw_data->num_banks; i++)
+ tasklet_init(&priv_data->banks[i].resp_hanlder,
+ adf_response_handler,
+ (unsigned long)&priv_data->banks[i]);
+ return 0;
+}
+
+static void adf_cleanup_bh(struct adf_accel_dev *accel_dev)
+{
+ struct adf_etr_data *priv_data = accel_dev->transport;
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ int i;
+
+ for (i = 0; i < hw_data->num_banks; i++) {
+ tasklet_disable(&priv_data->banks[i].resp_hanlder);
+ tasklet_kill(&priv_data->banks[i].resp_hanlder);
+ }
+}
+
+void adf_isr_resource_free(struct adf_accel_dev *accel_dev)
+{
+ adf_free_irqs(accel_dev);
+ adf_cleanup_bh(accel_dev);
+ adf_disable_msix(&accel_dev->accel_pci_dev);
+ adf_isr_free_msix_entry_table(accel_dev);
+}
+
+int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev)
+{
+ int ret;
+
+ ret = adf_isr_alloc_msix_entry_table(accel_dev);
+ if (ret)
+ return ret;
+ if (adf_enable_msix(accel_dev))
+ goto err_out;
+
+ if (adf_setup_bh(accel_dev))
+ goto err_out;
+
+ if (adf_request_irqs(accel_dev))
+ goto err_out;
+
+ return 0;
+err_out:
+ adf_isr_resource_free(accel_dev);
+ return -EFAULT;
+}
diff --git a/drivers/crypto/qat/qat_dh895xcc/qat_admin.c b/drivers/crypto/qat/qat_dh895xcc/qat_admin.c
new file mode 100644
index 000000000000..55b7a8e48bad
--- /dev/null
+++ b/drivers/crypto/qat/qat_dh895xcc/qat_admin.c
@@ -0,0 +1,107 @@
+/*
+ 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
+ Copyright(c) 2014 Intel 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.
+
+ Contact Information:
+ qat-linux@intel.com
+
+ BSD LICENSE
+ Copyright(c) 2014 Intel Corporation.
+ 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 <icp_qat_fw_init_admin.h>
+#include <adf_accel_devices.h>
+#include <adf_common_drv.h>
+#include "adf_drv.h"
+
+static struct service_hndl qat_admin;
+
+static int qat_send_admin_cmd(struct adf_accel_dev *accel_dev, int cmd)
+{
+ struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+ struct icp_qat_fw_init_admin_req req;
+ struct icp_qat_fw_init_admin_resp resp;
+ int i;
+
+ memset(&req, 0, sizeof(struct icp_qat_fw_init_admin_req));
+ req.init_admin_cmd_id = cmd;
+ for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
+ memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
+ if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
+ resp.init_resp_hdr.status)
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static int qat_admin_start(struct adf_accel_dev *accel_dev)
+{
+ return qat_send_admin_cmd(accel_dev, ICP_QAT_FW_INIT_ME);
+}
+
+static int qat_admin_event_handler(struct adf_accel_dev *accel_dev,
+ enum adf_event event)
+{
+ int ret;
+
+ switch (event) {
+ case ADF_EVENT_START:
+ ret = qat_admin_start(accel_dev);
+ break;
+ case ADF_EVENT_STOP:
+ case ADF_EVENT_INIT:
+ case ADF_EVENT_SHUTDOWN:
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
+int qat_admin_register(void)
+{
+ memset(&qat_admin, 0, sizeof(struct service_hndl));
+ qat_admin.event_hld = qat_admin_event_handler;
+ qat_admin.name = "qat_admin";
+ qat_admin.admin = 1;
+ return adf_service_register(&qat_admin);
+}
+
+int qat_admin_unregister(void)
+{
+ return adf_service_unregister(&qat_admin);
+}
diff --git a/drivers/crypto/qce/Makefile b/drivers/crypto/qce/Makefile
new file mode 100644
index 000000000000..348dc3173afa
--- /dev/null
+++ b/drivers/crypto/qce/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_CRYPTO_DEV_QCE) += qcrypto.o
+qcrypto-objs := core.o \
+ common.o \
+ dma.o \
+ sha.o \
+ ablkcipher.o
diff --git a/drivers/crypto/qce/ablkcipher.c b/drivers/crypto/qce/ablkcipher.c
new file mode 100644
index 000000000000..ad592de475a4
--- /dev/null
+++ b/drivers/crypto/qce/ablkcipher.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/des.h>
+
+#include "cipher.h"
+
+static LIST_HEAD(ablkcipher_algs);
+
+static void qce_ablkcipher_done(void *data)
+{
+ struct crypto_async_request *async_req = data;
+ struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
+ struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ enum dma_data_direction dir_src, dir_dst;
+ u32 status;
+ int error;
+ bool diff_dst;
+
+ diff_dst = (req->src != req->dst) ? true : false;
+ dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
+ dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
+
+ error = qce_dma_terminate_all(&qce->dma);
+ if (error)
+ dev_dbg(qce->dev, "ablkcipher dma termination error (%d)\n",
+ error);
+
+ if (diff_dst)
+ qce_unmapsg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src,
+ rctx->dst_chained);
+ qce_unmapsg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst,
+ rctx->dst_chained);
+
+ sg_free_table(&rctx->dst_tbl);
+
+ error = qce_check_status(qce, &status);
+ if (error < 0)
+ dev_dbg(qce->dev, "ablkcipher operation error (%x)\n", status);
+
+ qce->async_req_done(tmpl->qce, error);
+}
+
+static int
+qce_ablkcipher_async_req_handle(struct crypto_async_request *async_req)
+{
+ struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
+ struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
+ struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ enum dma_data_direction dir_src, dir_dst;
+ struct scatterlist *sg;
+ bool diff_dst;
+ gfp_t gfp;
+ int ret;
+
+ rctx->iv = req->info;
+ rctx->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+ rctx->cryptlen = req->nbytes;
+
+ diff_dst = (req->src != req->dst) ? true : false;
+ dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
+ dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
+
+ rctx->src_nents = qce_countsg(req->src, req->nbytes,
+ &rctx->src_chained);
+ if (diff_dst) {
+ rctx->dst_nents = qce_countsg(req->dst, req->nbytes,
+ &rctx->dst_chained);
+ } else {
+ rctx->dst_nents = rctx->src_nents;
+ rctx->dst_chained = rctx->src_chained;
+ }
+
+ rctx->dst_nents += 1;
+
+ gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+ GFP_KERNEL : GFP_ATOMIC;
+
+ ret = sg_alloc_table(&rctx->dst_tbl, rctx->dst_nents, gfp);
+ if (ret)
+ return ret;
+
+ sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
+
+ sg = qce_sgtable_add(&rctx->dst_tbl, req->dst);
+ if (IS_ERR(sg)) {
+ ret = PTR_ERR(sg);
+ goto error_free;
+ }
+
+ sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->result_sg);
+ if (IS_ERR(sg)) {
+ ret = PTR_ERR(sg);
+ goto error_free;
+ }
+
+ sg_mark_end(sg);
+ rctx->dst_sg = rctx->dst_tbl.sgl;
+
+ ret = qce_mapsg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst,
+ rctx->dst_chained);
+ if (ret < 0)
+ goto error_free;
+
+ if (diff_dst) {
+ ret = qce_mapsg(qce->dev, req->src, rctx->src_nents, dir_src,
+ rctx->src_chained);
+ if (ret < 0)
+ goto error_unmap_dst;
+ rctx->src_sg = req->src;
+ } else {
+ rctx->src_sg = rctx->dst_sg;
+ }
+
+ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents,
+ rctx->dst_sg, rctx->dst_nents,
+ qce_ablkcipher_done, async_req);
+ if (ret)
+ goto error_unmap_src;
+
+ qce_dma_issue_pending(&qce->dma);
+
+ ret = qce_start(async_req, tmpl->crypto_alg_type, req->nbytes, 0);
+ if (ret)
+ goto error_terminate;
+
+ return 0;
+
+error_terminate:
+ qce_dma_terminate_all(&qce->dma);
+error_unmap_src:
+ if (diff_dst)
+ qce_unmapsg(qce->dev, req->src, rctx->src_nents, dir_src,
+ rctx->src_chained);
+error_unmap_dst:
+ qce_unmapsg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst,
+ rctx->dst_chained);
+error_free:
+ sg_free_table(&rctx->dst_tbl);
+ return ret;
+}
+
+static int qce_ablkcipher_setkey(struct crypto_ablkcipher *ablk, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk);
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
+ unsigned long flags = to_cipher_tmpl(tfm)->alg_flags;
+ int ret;
+
+ if (!key || !keylen)
+ return -EINVAL;
+
+ if (IS_AES(flags)) {
+ switch (keylen) {
+ case AES_KEYSIZE_128:
+ case AES_KEYSIZE_256:
+ break;
+ default:
+ goto fallback;
+ }
+ } else if (IS_DES(flags)) {
+ u32 tmp[DES_EXPKEY_WORDS];
+
+ ret = des_ekey(tmp, key);
+ if (!ret && crypto_ablkcipher_get_flags(ablk) &
+ CRYPTO_TFM_REQ_WEAK_KEY)
+ goto weakkey;
+ }
+
+ ctx->enc_keylen = keylen;
+ memcpy(ctx->enc_key, key, keylen);
+ return 0;
+fallback:
+ ret = crypto_ablkcipher_setkey(ctx->fallback, key, keylen);
+ if (!ret)
+ ctx->enc_keylen = keylen;
+ return ret;
+weakkey:
+ crypto_ablkcipher_set_flags(ablk, CRYPTO_TFM_RES_WEAK_KEY);
+ return -EINVAL;
+}
+
+static int qce_ablkcipher_crypt(struct ablkcipher_request *req, int encrypt)
+{
+ struct crypto_tfm *tfm =
+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct qce_alg_template *tmpl = to_cipher_tmpl(tfm);
+ int ret;
+
+ rctx->flags = tmpl->alg_flags;
+ rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
+
+ if (IS_AES(rctx->flags) && ctx->enc_keylen != AES_KEYSIZE_128 &&
+ ctx->enc_keylen != AES_KEYSIZE_256) {
+ ablkcipher_request_set_tfm(req, ctx->fallback);
+ ret = encrypt ? crypto_ablkcipher_encrypt(req) :
+ crypto_ablkcipher_decrypt(req);
+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+ return ret;
+ }
+
+ return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base);
+}
+
+static int qce_ablkcipher_encrypt(struct ablkcipher_request *req)
+{
+ return qce_ablkcipher_crypt(req, 1);
+}
+
+static int qce_ablkcipher_decrypt(struct ablkcipher_request *req)
+{
+ return qce_ablkcipher_crypt(req, 0);
+}
+
+static int qce_ablkcipher_init(struct crypto_tfm *tfm)
+{
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ memset(ctx, 0, sizeof(*ctx));
+ tfm->crt_ablkcipher.reqsize = sizeof(struct qce_cipher_reqctx);
+
+ ctx->fallback = crypto_alloc_ablkcipher(crypto_tfm_alg_name(tfm),
+ CRYPTO_ALG_TYPE_ABLKCIPHER,
+ CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->fallback))
+ return PTR_ERR(ctx->fallback);
+
+ return 0;
+}
+
+static void qce_ablkcipher_exit(struct crypto_tfm *tfm)
+{
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_ablkcipher(ctx->fallback);
+}
+
+struct qce_ablkcipher_def {
+ unsigned long flags;
+ const char *name;
+ const char *drv_name;
+ unsigned int blocksize;
+ unsigned int ivsize;
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+};
+
+static const struct qce_ablkcipher_def ablkcipher_def[] = {
+ {
+ .flags = QCE_ALG_AES | QCE_MODE_ECB,
+ .name = "ecb(aes)",
+ .drv_name = "ecb-aes-qce",
+ .blocksize = AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_AES | QCE_MODE_CBC,
+ .name = "cbc(aes)",
+ .drv_name = "cbc-aes-qce",
+ .blocksize = AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_AES | QCE_MODE_CTR,
+ .name = "ctr(aes)",
+ .drv_name = "ctr-aes-qce",
+ .blocksize = AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_AES | QCE_MODE_XTS,
+ .name = "xts(aes)",
+ .drv_name = "xts-aes-qce",
+ .blocksize = AES_BLOCK_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_DES | QCE_MODE_ECB,
+ .name = "ecb(des)",
+ .drv_name = "ecb-des-qce",
+ .blocksize = DES_BLOCK_SIZE,
+ .ivsize = 0,
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_DES | QCE_MODE_CBC,
+ .name = "cbc(des)",
+ .drv_name = "cbc-des-qce",
+ .blocksize = DES_BLOCK_SIZE,
+ .ivsize = DES_BLOCK_SIZE,
+ .min_keysize = DES_KEY_SIZE,
+ .max_keysize = DES_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_3DES | QCE_MODE_ECB,
+ .name = "ecb(des3_ede)",
+ .drv_name = "ecb-3des-qce",
+ .blocksize = DES3_EDE_BLOCK_SIZE,
+ .ivsize = 0,
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ },
+ {
+ .flags = QCE_ALG_3DES | QCE_MODE_CBC,
+ .name = "cbc(des3_ede)",
+ .drv_name = "cbc-3des-qce",
+ .blocksize = DES3_EDE_BLOCK_SIZE,
+ .ivsize = DES3_EDE_BLOCK_SIZE,
+ .min_keysize = DES3_EDE_KEY_SIZE,
+ .max_keysize = DES3_EDE_KEY_SIZE,
+ },
+};
+
+static int qce_ablkcipher_register_one(const struct qce_ablkcipher_def *def,
+ struct qce_device *qce)
+{
+ struct qce_alg_template *tmpl;
+ struct crypto_alg *alg;
+ int ret;
+
+ tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
+ if (!tmpl)
+ return -ENOMEM;
+
+ alg = &tmpl->alg.crypto;
+
+ snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
+ snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
+ def->drv_name);
+
+ alg->cra_blocksize = def->blocksize;
+ alg->cra_ablkcipher.ivsize = def->ivsize;
+ alg->cra_ablkcipher.min_keysize = def->min_keysize;
+ alg->cra_ablkcipher.max_keysize = def->max_keysize;
+ alg->cra_ablkcipher.setkey = qce_ablkcipher_setkey;
+ alg->cra_ablkcipher.encrypt = qce_ablkcipher_encrypt;
+ alg->cra_ablkcipher.decrypt = qce_ablkcipher_decrypt;
+
+ alg->cra_priority = 300;
+ alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_NEED_FALLBACK;
+ alg->cra_ctxsize = sizeof(struct qce_cipher_ctx);
+ alg->cra_alignmask = 0;
+ alg->cra_type = &crypto_ablkcipher_type;
+ alg->cra_module = THIS_MODULE;
+ alg->cra_init = qce_ablkcipher_init;
+ alg->cra_exit = qce_ablkcipher_exit;
+ INIT_LIST_HEAD(&alg->cra_list);
+
+ INIT_LIST_HEAD(&tmpl->entry);
+ tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_ABLKCIPHER;
+ tmpl->alg_flags = def->flags;
+ tmpl->qce = qce;
+
+ ret = crypto_register_alg(alg);
+ if (ret) {
+ kfree(tmpl);
+ dev_err(qce->dev, "%s registration failed\n", alg->cra_name);
+ return ret;
+ }
+
+ list_add_tail(&tmpl->entry, &ablkcipher_algs);
+ dev_dbg(qce->dev, "%s is registered\n", alg->cra_name);
+ return 0;
+}
+
+static void qce_ablkcipher_unregister(struct qce_device *qce)
+{
+ struct qce_alg_template *tmpl, *n;
+
+ list_for_each_entry_safe(tmpl, n, &ablkcipher_algs, entry) {
+ crypto_unregister_alg(&tmpl->alg.crypto);
+ list_del(&tmpl->entry);
+ kfree(tmpl);
+ }
+}
+
+static int qce_ablkcipher_register(struct qce_device *qce)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(ablkcipher_def); i++) {
+ ret = qce_ablkcipher_register_one(&ablkcipher_def[i], qce);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ qce_ablkcipher_unregister(qce);
+ return ret;
+}
+
+const struct qce_algo_ops ablkcipher_ops = {
+ .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+ .register_algs = qce_ablkcipher_register,
+ .unregister_algs = qce_ablkcipher_unregister,
+ .async_req_handle = qce_ablkcipher_async_req_handle,
+};
diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
new file mode 100644
index 000000000000..d5757cfcda2d
--- /dev/null
+++ b/drivers/crypto/qce/cipher.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CIPHER_H_
+#define _CIPHER_H_
+
+#include "common.h"
+#include "core.h"
+
+#define QCE_MAX_KEY_SIZE 64
+
+struct qce_cipher_ctx {
+ u8 enc_key[QCE_MAX_KEY_SIZE];
+ unsigned int enc_keylen;
+ struct crypto_ablkcipher *fallback;
+};
+
+/**
+ * struct qce_cipher_reqctx - holds private cipher objects per request
+ * @flags: operation flags
+ * @iv: pointer to the IV
+ * @ivsize: IV size
+ * @src_nents: source entries
+ * @dst_nents: destination entries
+ * @src_chained: is source chained
+ * @dst_chained: is destination chained
+ * @result_sg: scatterlist used for result buffer
+ * @dst_tbl: destination sg table
+ * @dst_sg: destination sg pointer table beginning
+ * @src_tbl: source sg table
+ * @src_sg: source sg pointer table beginning;
+ * @cryptlen: crypto length
+ */
+struct qce_cipher_reqctx {
+ unsigned long flags;
+ u8 *iv;
+ unsigned int ivsize;
+ int src_nents;
+ int dst_nents;
+ bool src_chained;
+ bool dst_chained;
+ struct scatterlist result_sg;
+ struct sg_table dst_tbl;
+ struct scatterlist *dst_sg;
+ struct sg_table src_tbl;
+ struct scatterlist *src_sg;
+ unsigned int cryptlen;
+};
+
+static inline struct qce_alg_template *to_cipher_tmpl(struct crypto_tfm *tfm)
+{
+ struct crypto_alg *alg = tfm->__crt_alg;
+ return container_of(alg, struct qce_alg_template, alg.crypto);
+}
+
+extern const struct qce_algo_ops ablkcipher_ops;
+
+#endif /* _CIPHER_H_ */
diff --git a/drivers/crypto/qce/common.c b/drivers/crypto/qce/common.c
new file mode 100644
index 000000000000..1fb5fde7fc03
--- /dev/null
+++ b/drivers/crypto/qce/common.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/sha.h>
+
+#include "cipher.h"
+#include "common.h"
+#include "core.h"
+#include "regs-v5.h"
+#include "sha.h"
+
+#define QCE_SECTOR_SIZE 512
+
+static inline u32 qce_read(struct qce_device *qce, u32 offset)
+{
+ return readl(qce->base + offset);
+}
+
+static inline void qce_write(struct qce_device *qce, u32 offset, u32 val)
+{
+ writel(val, qce->base + offset);
+}
+
+static inline void qce_write_array(struct qce_device *qce, u32 offset,
+ const u32 *val, unsigned int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ qce_write(qce, offset + i * sizeof(u32), val[i]);
+}
+
+static inline void
+qce_clear_array(struct qce_device *qce, u32 offset, unsigned int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ qce_write(qce, offset + i * sizeof(u32), 0);
+}
+
+static u32 qce_encr_cfg(unsigned long flags, u32 aes_key_size)
+{
+ u32 cfg = 0;
+
+ if (IS_AES(flags)) {
+ if (aes_key_size == AES_KEYSIZE_128)
+ cfg |= ENCR_KEY_SZ_AES128 << ENCR_KEY_SZ_SHIFT;
+ else if (aes_key_size == AES_KEYSIZE_256)
+ cfg |= ENCR_KEY_SZ_AES256 << ENCR_KEY_SZ_SHIFT;
+ }
+
+ if (IS_AES(flags))
+ cfg |= ENCR_ALG_AES << ENCR_ALG_SHIFT;
+ else if (IS_DES(flags) || IS_3DES(flags))
+ cfg |= ENCR_ALG_DES << ENCR_ALG_SHIFT;
+
+ if (IS_DES(flags))
+ cfg |= ENCR_KEY_SZ_DES << ENCR_KEY_SZ_SHIFT;
+
+ if (IS_3DES(flags))
+ cfg |= ENCR_KEY_SZ_3DES << ENCR_KEY_SZ_SHIFT;
+
+ switch (flags & QCE_MODE_MASK) {
+ case QCE_MODE_ECB:
+ cfg |= ENCR_MODE_ECB << ENCR_MODE_SHIFT;
+ break;
+ case QCE_MODE_CBC:
+ cfg |= ENCR_MODE_CBC << ENCR_MODE_SHIFT;
+ break;
+ case QCE_MODE_CTR:
+ cfg |= ENCR_MODE_CTR << ENCR_MODE_SHIFT;
+ break;
+ case QCE_MODE_XTS:
+ cfg |= ENCR_MODE_XTS << ENCR_MODE_SHIFT;
+ break;
+ case QCE_MODE_CCM:
+ cfg |= ENCR_MODE_CCM << ENCR_MODE_SHIFT;
+ cfg |= LAST_CCM_XFR << LAST_CCM_SHIFT;
+ break;
+ default:
+ return ~0;
+ }
+
+ return cfg;
+}
+
+static u32 qce_auth_cfg(unsigned long flags, u32 key_size)
+{
+ u32 cfg = 0;
+
+ if (IS_AES(flags) && (IS_CCM(flags) || IS_CMAC(flags)))
+ cfg |= AUTH_ALG_AES << AUTH_ALG_SHIFT;
+ else
+ cfg |= AUTH_ALG_SHA << AUTH_ALG_SHIFT;
+
+ if (IS_CCM(flags) || IS_CMAC(flags)) {
+ if (key_size == AES_KEYSIZE_128)
+ cfg |= AUTH_KEY_SZ_AES128 << AUTH_KEY_SIZE_SHIFT;
+ else if (key_size == AES_KEYSIZE_256)
+ cfg |= AUTH_KEY_SZ_AES256 << AUTH_KEY_SIZE_SHIFT;
+ }
+
+ if (IS_SHA1(flags) || IS_SHA1_HMAC(flags))
+ cfg |= AUTH_SIZE_SHA1 << AUTH_SIZE_SHIFT;
+ else if (IS_SHA256(flags) || IS_SHA256_HMAC(flags))
+ cfg |= AUTH_SIZE_SHA256 << AUTH_SIZE_SHIFT;
+ else if (IS_CMAC(flags))
+ cfg |= AUTH_SIZE_ENUM_16_BYTES << AUTH_SIZE_SHIFT;
+
+ if (IS_SHA1(flags) || IS_SHA256(flags))
+ cfg |= AUTH_MODE_HASH << AUTH_MODE_SHIFT;
+ else if (IS_SHA1_HMAC(flags) || IS_SHA256_HMAC(flags) ||
+ IS_CBC(flags) || IS_CTR(flags))
+ cfg |= AUTH_MODE_HMAC << AUTH_MODE_SHIFT;
+ else if (IS_AES(flags) && IS_CCM(flags))
+ cfg |= AUTH_MODE_CCM << AUTH_MODE_SHIFT;
+ else if (IS_AES(flags) && IS_CMAC(flags))
+ cfg |= AUTH_MODE_CMAC << AUTH_MODE_SHIFT;
+
+ if (IS_SHA(flags) || IS_SHA_HMAC(flags))
+ cfg |= AUTH_POS_BEFORE << AUTH_POS_SHIFT;
+
+ if (IS_CCM(flags))
+ cfg |= QCE_MAX_NONCE_WORDS << AUTH_NONCE_NUM_WORDS_SHIFT;
+
+ if (IS_CBC(flags) || IS_CTR(flags) || IS_CCM(flags) ||
+ IS_CMAC(flags))
+ cfg |= BIT(AUTH_LAST_SHIFT) | BIT(AUTH_FIRST_SHIFT);
+
+ return cfg;
+}
+
+static u32 qce_config_reg(struct qce_device *qce, int little)
+{
+ u32 beats = (qce->burst_size >> 3) - 1;
+ u32 pipe_pair = qce->pipe_pair_id;
+ u32 config;
+
+ config = (beats << REQ_SIZE_SHIFT) & REQ_SIZE_MASK;
+ config |= BIT(MASK_DOUT_INTR_SHIFT) | BIT(MASK_DIN_INTR_SHIFT) |
+ BIT(MASK_OP_DONE_INTR_SHIFT) | BIT(MASK_ERR_INTR_SHIFT);
+ config |= (pipe_pair << PIPE_SET_SELECT_SHIFT) & PIPE_SET_SELECT_MASK;
+ config &= ~HIGH_SPD_EN_N_SHIFT;
+
+ if (little)
+ config |= BIT(LITTLE_ENDIAN_MODE_SHIFT);
+
+ return config;
+}
+
+void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len)
+{
+ __be32 *d = dst;
+ const u8 *s = src;
+ unsigned int n;
+
+ n = len / sizeof(u32);
+ for (; n > 0; n--) {
+ *d = cpu_to_be32p((const __u32 *) s);
+ s += sizeof(__u32);
+ d++;
+ }
+}
+
+static void qce_xts_swapiv(__be32 *dst, const u8 *src, unsigned int ivsize)
+{
+ u8 swap[QCE_AES_IV_LENGTH];
+ u32 i, j;
+
+ if (ivsize > QCE_AES_IV_LENGTH)
+ return;
+
+ memset(swap, 0, QCE_AES_IV_LENGTH);
+
+ for (i = (QCE_AES_IV_LENGTH - ivsize), j = ivsize - 1;
+ i < QCE_AES_IV_LENGTH; i++, j--)
+ swap[i] = src[j];
+
+ qce_cpu_to_be32p_array(dst, swap, QCE_AES_IV_LENGTH);
+}
+
+static void qce_xtskey(struct qce_device *qce, const u8 *enckey,
+ unsigned int enckeylen, unsigned int cryptlen)
+{
+ u32 xtskey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(u32)] = {0};
+ unsigned int xtsklen = enckeylen / (2 * sizeof(u32));
+ unsigned int xtsdusize;
+
+ qce_cpu_to_be32p_array((__be32 *)xtskey, enckey + enckeylen / 2,
+ enckeylen / 2);
+ qce_write_array(qce, REG_ENCR_XTS_KEY0, xtskey, xtsklen);
+
+ /* xts du size 512B */
+ xtsdusize = min_t(u32, QCE_SECTOR_SIZE, cryptlen);
+ qce_write(qce, REG_ENCR_XTS_DU_SIZE, xtsdusize);
+}
+
+static void qce_setup_config(struct qce_device *qce)
+{
+ u32 config;
+
+ /* get big endianness */
+ config = qce_config_reg(qce, 0);
+
+ /* clear status */
+ qce_write(qce, REG_STATUS, 0);
+ qce_write(qce, REG_CONFIG, config);
+}
+
+static inline void qce_crypto_go(struct qce_device *qce)
+{
+ qce_write(qce, REG_GOPROC, BIT(GO_SHIFT) | BIT(RESULTS_DUMP_SHIFT));
+}
+
+static int qce_setup_regs_ahash(struct crypto_async_request *async_req,
+ u32 totallen, u32 offset)
+{
+ struct ahash_request *req = ahash_request_cast(async_req);
+ struct crypto_ahash *ahash = __crypto_ahash_cast(async_req->tfm);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ unsigned int digestsize = crypto_ahash_digestsize(ahash);
+ unsigned int blocksize = crypto_tfm_alg_blocksize(async_req->tfm);
+ __be32 auth[SHA256_DIGEST_SIZE / sizeof(__be32)] = {0};
+ __be32 mackey[QCE_SHA_HMAC_KEY_SIZE / sizeof(__be32)] = {0};
+ u32 auth_cfg = 0, config;
+ unsigned int iv_words;
+
+ /* if not the last, the size has to be on the block boundary */
+ if (!rctx->last_blk && req->nbytes % blocksize)
+ return -EINVAL;
+
+ qce_setup_config(qce);
+
+ if (IS_CMAC(rctx->flags)) {
+ qce_write(qce, REG_AUTH_SEG_CFG, 0);
+ qce_write(qce, REG_ENCR_SEG_CFG, 0);
+ qce_write(qce, REG_ENCR_SEG_SIZE, 0);
+ qce_clear_array(qce, REG_AUTH_IV0, 16);
+ qce_clear_array(qce, REG_AUTH_KEY0, 16);
+ qce_clear_array(qce, REG_AUTH_BYTECNT0, 4);
+
+ auth_cfg = qce_auth_cfg(rctx->flags, rctx->authklen);
+ }
+
+ if (IS_SHA_HMAC(rctx->flags) || IS_CMAC(rctx->flags)) {
+ u32 authkey_words = rctx->authklen / sizeof(u32);
+
+ qce_cpu_to_be32p_array(mackey, rctx->authkey, rctx->authklen);
+ qce_write_array(qce, REG_AUTH_KEY0, (u32 *)mackey,
+ authkey_words);
+ }
+
+ if (IS_CMAC(rctx->flags))
+ goto go_proc;
+
+ if (rctx->first_blk)
+ memcpy(auth, rctx->digest, digestsize);
+ else
+ qce_cpu_to_be32p_array(auth, rctx->digest, digestsize);
+
+ iv_words = (IS_SHA1(rctx->flags) || IS_SHA1_HMAC(rctx->flags)) ? 5 : 8;
+ qce_write_array(qce, REG_AUTH_IV0, (u32 *)auth, iv_words);
+
+ if (rctx->first_blk)
+ qce_clear_array(qce, REG_AUTH_BYTECNT0, 4);
+ else
+ qce_write_array(qce, REG_AUTH_BYTECNT0,
+ (u32 *)rctx->byte_count, 2);
+
+ auth_cfg = qce_auth_cfg(rctx->flags, 0);
+
+ if (rctx->last_blk)
+ auth_cfg |= BIT(AUTH_LAST_SHIFT);
+ else
+ auth_cfg &= ~BIT(AUTH_LAST_SHIFT);
+
+ if (rctx->first_blk)
+ auth_cfg |= BIT(AUTH_FIRST_SHIFT);
+ else
+ auth_cfg &= ~BIT(AUTH_FIRST_SHIFT);
+
+go_proc:
+ qce_write(qce, REG_AUTH_SEG_CFG, auth_cfg);
+ qce_write(qce, REG_AUTH_SEG_SIZE, req->nbytes);
+ qce_write(qce, REG_AUTH_SEG_START, 0);
+ qce_write(qce, REG_ENCR_SEG_CFG, 0);
+ qce_write(qce, REG_SEG_SIZE, req->nbytes);
+
+ /* get little endianness */
+ config = qce_config_reg(qce, 1);
+ qce_write(qce, REG_CONFIG, config);
+
+ qce_crypto_go(qce);
+
+ return 0;
+}
+
+static int qce_setup_regs_ablkcipher(struct crypto_async_request *async_req,
+ u32 totallen, u32 offset)
+{
+ struct ablkcipher_request *req = ablkcipher_request_cast(async_req);
+ struct qce_cipher_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct qce_cipher_ctx *ctx = crypto_tfm_ctx(async_req->tfm);
+ struct qce_alg_template *tmpl = to_cipher_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ __be32 enckey[QCE_MAX_CIPHER_KEY_SIZE / sizeof(__be32)] = {0};
+ __be32 enciv[QCE_MAX_IV_SIZE / sizeof(__be32)] = {0};
+ unsigned int enckey_words, enciv_words;
+ unsigned int keylen;
+ u32 encr_cfg = 0, auth_cfg = 0, config;
+ unsigned int ivsize = rctx->ivsize;
+ unsigned long flags = rctx->flags;
+
+ qce_setup_config(qce);
+
+ if (IS_XTS(flags))
+ keylen = ctx->enc_keylen / 2;
+ else
+ keylen = ctx->enc_keylen;
+
+ qce_cpu_to_be32p_array(enckey, ctx->enc_key, keylen);
+ enckey_words = keylen / sizeof(u32);
+
+ qce_write(qce, REG_AUTH_SEG_CFG, auth_cfg);
+
+ encr_cfg = qce_encr_cfg(flags, keylen);
+
+ if (IS_DES(flags)) {
+ enciv_words = 2;
+ enckey_words = 2;
+ } else if (IS_3DES(flags)) {
+ enciv_words = 2;
+ enckey_words = 6;
+ } else if (IS_AES(flags)) {
+ if (IS_XTS(flags))
+ qce_xtskey(qce, ctx->enc_key, ctx->enc_keylen,
+ rctx->cryptlen);
+ enciv_words = 4;
+ } else {
+ return -EINVAL;
+ }
+
+ qce_write_array(qce, REG_ENCR_KEY0, (u32 *)enckey, enckey_words);
+
+ if (!IS_ECB(flags)) {
+ if (IS_XTS(flags))
+ qce_xts_swapiv(enciv, rctx->iv, ivsize);
+ else
+ qce_cpu_to_be32p_array(enciv, rctx->iv, ivsize);
+
+ qce_write_array(qce, REG_CNTR0_IV0, (u32 *)enciv, enciv_words);
+ }
+
+ if (IS_ENCRYPT(flags))
+ encr_cfg |= BIT(ENCODE_SHIFT);
+
+ qce_write(qce, REG_ENCR_SEG_CFG, encr_cfg);
+ qce_write(qce, REG_ENCR_SEG_SIZE, rctx->cryptlen);
+ qce_write(qce, REG_ENCR_SEG_START, offset & 0xffff);
+
+ if (IS_CTR(flags)) {
+ qce_write(qce, REG_CNTR_MASK, ~0);
+ qce_write(qce, REG_CNTR_MASK0, ~0);
+ qce_write(qce, REG_CNTR_MASK1, ~0);
+ qce_write(qce, REG_CNTR_MASK2, ~0);
+ }
+
+ qce_write(qce, REG_SEG_SIZE, totallen);
+
+ /* get little endianness */
+ config = qce_config_reg(qce, 1);
+ qce_write(qce, REG_CONFIG, config);
+
+ qce_crypto_go(qce);
+
+ return 0;
+}
+
+int qce_start(struct crypto_async_request *async_req, u32 type, u32 totallen,
+ u32 offset)
+{
+ switch (type) {
+ case CRYPTO_ALG_TYPE_ABLKCIPHER:
+ return qce_setup_regs_ablkcipher(async_req, totallen, offset);
+ case CRYPTO_ALG_TYPE_AHASH:
+ return qce_setup_regs_ahash(async_req, totallen, offset);
+ default:
+ return -EINVAL;
+ }
+}
+
+#define STATUS_ERRORS \
+ (BIT(SW_ERR_SHIFT) | BIT(AXI_ERR_SHIFT) | BIT(HSD_ERR_SHIFT))
+
+int qce_check_status(struct qce_device *qce, u32 *status)
+{
+ int ret = 0;
+
+ *status = qce_read(qce, REG_STATUS);
+
+ /*
+ * Don't use result dump status. The operation may not be complete.
+ * Instead, use the status we just read from device. In case, we need to
+ * use result_status from result dump the result_status needs to be byte
+ * swapped, since we set the device to little endian.
+ */
+ if (*status & STATUS_ERRORS || !(*status & BIT(OPERATION_DONE_SHIFT)))
+ ret = -ENXIO;
+
+ return ret;
+}
+
+void qce_get_version(struct qce_device *qce, u32 *major, u32 *minor, u32 *step)
+{
+ u32 val;
+
+ val = qce_read(qce, REG_VERSION);
+ *major = (val & CORE_MAJOR_REV_MASK) >> CORE_MAJOR_REV_SHIFT;
+ *minor = (val & CORE_MINOR_REV_MASK) >> CORE_MINOR_REV_SHIFT;
+ *step = (val & CORE_STEP_REV_MASK) >> CORE_STEP_REV_SHIFT;
+}
diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
new file mode 100644
index 000000000000..a4addd4f7d6c
--- /dev/null
+++ b/drivers/crypto/qce/common.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <linux/crypto.h>
+#include <linux/types.h>
+#include <crypto/aes.h>
+#include <crypto/hash.h>
+
+/* key size in bytes */
+#define QCE_SHA_HMAC_KEY_SIZE 64
+#define QCE_MAX_CIPHER_KEY_SIZE AES_KEYSIZE_256
+
+/* IV length in bytes */
+#define QCE_AES_IV_LENGTH AES_BLOCK_SIZE
+/* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
+#define QCE_MAX_IV_SIZE AES_BLOCK_SIZE
+
+/* maximum nonce bytes */
+#define QCE_MAX_NONCE 16
+#define QCE_MAX_NONCE_WORDS (QCE_MAX_NONCE / sizeof(u32))
+
+/* burst size alignment requirement */
+#define QCE_MAX_ALIGN_SIZE 64
+
+/* cipher algorithms */
+#define QCE_ALG_DES BIT(0)
+#define QCE_ALG_3DES BIT(1)
+#define QCE_ALG_AES BIT(2)
+
+/* hash and hmac algorithms */
+#define QCE_HASH_SHA1 BIT(3)
+#define QCE_HASH_SHA256 BIT(4)
+#define QCE_HASH_SHA1_HMAC BIT(5)
+#define QCE_HASH_SHA256_HMAC BIT(6)
+#define QCE_HASH_AES_CMAC BIT(7)
+
+/* cipher modes */
+#define QCE_MODE_CBC BIT(8)
+#define QCE_MODE_ECB BIT(9)
+#define QCE_MODE_CTR BIT(10)
+#define QCE_MODE_XTS BIT(11)
+#define QCE_MODE_CCM BIT(12)
+#define QCE_MODE_MASK GENMASK(12, 8)
+
+/* cipher encryption/decryption operations */
+#define QCE_ENCRYPT BIT(13)
+#define QCE_DECRYPT BIT(14)
+
+#define IS_DES(flags) (flags & QCE_ALG_DES)
+#define IS_3DES(flags) (flags & QCE_ALG_3DES)
+#define IS_AES(flags) (flags & QCE_ALG_AES)
+
+#define IS_SHA1(flags) (flags & QCE_HASH_SHA1)
+#define IS_SHA256(flags) (flags & QCE_HASH_SHA256)
+#define IS_SHA1_HMAC(flags) (flags & QCE_HASH_SHA1_HMAC)
+#define IS_SHA256_HMAC(flags) (flags & QCE_HASH_SHA256_HMAC)
+#define IS_CMAC(flags) (flags & QCE_HASH_AES_CMAC)
+#define IS_SHA(flags) (IS_SHA1(flags) || IS_SHA256(flags))
+#define IS_SHA_HMAC(flags) \
+ (IS_SHA1_HMAC(flags) || IS_SHA256_HMAC(flags))
+
+#define IS_CBC(mode) (mode & QCE_MODE_CBC)
+#define IS_ECB(mode) (mode & QCE_MODE_ECB)
+#define IS_CTR(mode) (mode & QCE_MODE_CTR)
+#define IS_XTS(mode) (mode & QCE_MODE_XTS)
+#define IS_CCM(mode) (mode & QCE_MODE_CCM)
+
+#define IS_ENCRYPT(dir) (dir & QCE_ENCRYPT)
+#define IS_DECRYPT(dir) (dir & QCE_DECRYPT)
+
+struct qce_alg_template {
+ struct list_head entry;
+ u32 crypto_alg_type;
+ unsigned long alg_flags;
+ const u32 *std_iv;
+ union {
+ struct crypto_alg crypto;
+ struct ahash_alg ahash;
+ } alg;
+ struct qce_device *qce;
+};
+
+void qce_cpu_to_be32p_array(__be32 *dst, const u8 *src, unsigned int len);
+int qce_check_status(struct qce_device *qce, u32 *status);
+void qce_get_version(struct qce_device *qce, u32 *major, u32 *minor, u32 *step);
+int qce_start(struct crypto_async_request *async_req, u32 type, u32 totallen,
+ u32 offset);
+
+#endif /* _COMMON_H_ */
diff --git a/drivers/crypto/qce/core.c b/drivers/crypto/qce/core.c
new file mode 100644
index 000000000000..33ae3545dc48
--- /dev/null
+++ b/drivers/crypto/qce/core.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <crypto/algapi.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha.h>
+
+#include "core.h"
+#include "cipher.h"
+#include "sha.h"
+
+#define QCE_MAJOR_VERSION5 0x05
+#define QCE_QUEUE_LENGTH 1
+
+static const struct qce_algo_ops *qce_ops[] = {
+ &ablkcipher_ops,
+ &ahash_ops,
+};
+
+static void qce_unregister_algs(struct qce_device *qce)
+{
+ const struct qce_algo_ops *ops;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
+ ops = qce_ops[i];
+ ops->unregister_algs(qce);
+ }
+}
+
+static int qce_register_algs(struct qce_device *qce)
+{
+ const struct qce_algo_ops *ops;
+ int i, ret = -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
+ ops = qce_ops[i];
+ ret = ops->register_algs(qce);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int qce_handle_request(struct crypto_async_request *async_req)
+{
+ int ret = -EINVAL, i;
+ const struct qce_algo_ops *ops;
+ u32 type = crypto_tfm_alg_type(async_req->tfm);
+
+ for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
+ ops = qce_ops[i];
+ if (type != ops->type)
+ continue;
+ ret = ops->async_req_handle(async_req);
+ break;
+ }
+
+ return ret;
+}
+
+static int qce_handle_queue(struct qce_device *qce,
+ struct crypto_async_request *req)
+{
+ struct crypto_async_request *async_req, *backlog;
+ unsigned long flags;
+ int ret = 0, err;
+
+ spin_lock_irqsave(&qce->lock, flags);
+
+ if (req)
+ ret = crypto_enqueue_request(&qce->queue, req);
+
+ /* busy, do not dequeue request */
+ if (qce->req) {
+ spin_unlock_irqrestore(&qce->lock, flags);
+ return ret;
+ }
+
+ backlog = crypto_get_backlog(&qce->queue);
+ async_req = crypto_dequeue_request(&qce->queue);
+ if (async_req)
+ qce->req = async_req;
+
+ spin_unlock_irqrestore(&qce->lock, flags);
+
+ if (!async_req)
+ return ret;
+
+ if (backlog) {
+ spin_lock_bh(&qce->lock);
+ backlog->complete(backlog, -EINPROGRESS);
+ spin_unlock_bh(&qce->lock);
+ }
+
+ err = qce_handle_request(async_req);
+ if (err) {
+ qce->result = err;
+ tasklet_schedule(&qce->done_tasklet);
+ }
+
+ return ret;
+}
+
+static void qce_tasklet_req_done(unsigned long data)
+{
+ struct qce_device *qce = (struct qce_device *)data;
+ struct crypto_async_request *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qce->lock, flags);
+ req = qce->req;
+ qce->req = NULL;
+ spin_unlock_irqrestore(&qce->lock, flags);
+
+ if (req)
+ req->complete(req, qce->result);
+
+ qce_handle_queue(qce, NULL);
+}
+
+static int qce_async_request_enqueue(struct qce_device *qce,
+ struct crypto_async_request *req)
+{
+ return qce_handle_queue(qce, req);
+}
+
+static void qce_async_request_done(struct qce_device *qce, int ret)
+{
+ qce->result = ret;
+ tasklet_schedule(&qce->done_tasklet);
+}
+
+static int qce_check_version(struct qce_device *qce)
+{
+ u32 major, minor, step;
+
+ qce_get_version(qce, &major, &minor, &step);
+
+ /*
+ * the driver does not support v5 with minor 0 because it has special
+ * alignment requirements.
+ */
+ if (major != QCE_MAJOR_VERSION5 || minor == 0)
+ return -ENODEV;
+
+ qce->burst_size = QCE_BAM_BURST_SIZE;
+ qce->pipe_pair_id = 1;
+
+ dev_dbg(qce->dev, "Crypto device found, version %d.%d.%d\n",
+ major, minor, step);
+
+ return 0;
+}
+
+static int qce_crypto_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct qce_device *qce;
+ struct resource *res;
+ int ret;
+
+ qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL);
+ if (!qce)
+ return -ENOMEM;
+
+ qce->dev = dev;
+ platform_set_drvdata(pdev, qce);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ qce->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qce->base))
+ return PTR_ERR(qce->base);
+
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (ret < 0)
+ return ret;
+
+ qce->core = devm_clk_get(qce->dev, "core");
+ if (IS_ERR(qce->core))
+ return PTR_ERR(qce->core);
+
+ qce->iface = devm_clk_get(qce->dev, "iface");
+ if (IS_ERR(qce->iface))
+ return PTR_ERR(qce->iface);
+
+ qce->bus = devm_clk_get(qce->dev, "bus");
+ if (IS_ERR(qce->bus))
+ return PTR_ERR(qce->bus);
+
+ ret = clk_prepare_enable(qce->core);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(qce->iface);
+ if (ret)
+ goto err_clks_core;
+
+ ret = clk_prepare_enable(qce->bus);
+ if (ret)
+ goto err_clks_iface;
+
+ ret = qce_dma_request(qce->dev, &qce->dma);
+ if (ret)
+ goto err_clks;
+
+ ret = qce_check_version(qce);
+ if (ret)
+ goto err_clks;
+
+ spin_lock_init(&qce->lock);
+ tasklet_init(&qce->done_tasklet, qce_tasklet_req_done,
+ (unsigned long)qce);
+ crypto_init_queue(&qce->queue, QCE_QUEUE_LENGTH);
+
+ qce->async_req_enqueue = qce_async_request_enqueue;
+ qce->async_req_done = qce_async_request_done;
+
+ ret = qce_register_algs(qce);
+ if (ret)
+ goto err_dma;
+
+ return 0;
+
+err_dma:
+ qce_dma_release(&qce->dma);
+err_clks:
+ clk_disable_unprepare(qce->bus);
+err_clks_iface:
+ clk_disable_unprepare(qce->iface);
+err_clks_core:
+ clk_disable_unprepare(qce->core);
+ return ret;
+}
+
+static int qce_crypto_remove(struct platform_device *pdev)
+{
+ struct qce_device *qce = platform_get_drvdata(pdev);
+
+ tasklet_kill(&qce->done_tasklet);
+ qce_unregister_algs(qce);
+ qce_dma_release(&qce->dma);
+ clk_disable_unprepare(qce->bus);
+ clk_disable_unprepare(qce->iface);
+ clk_disable_unprepare(qce->core);
+ return 0;
+}
+
+static const struct of_device_id qce_crypto_of_match[] = {
+ { .compatible = "qcom,crypto-v5.1", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qce_crypto_of_match);
+
+static struct platform_driver qce_crypto_driver = {
+ .probe = qce_crypto_probe,
+ .remove = qce_crypto_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = KBUILD_MODNAME,
+ .of_match_table = qce_crypto_of_match,
+ },
+};
+module_platform_driver(qce_crypto_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm crypto engine driver");
+MODULE_ALIAS("platform:" KBUILD_MODNAME);
+MODULE_AUTHOR("The Linux Foundation");
diff --git a/drivers/crypto/qce/core.h b/drivers/crypto/qce/core.h
new file mode 100644
index 000000000000..549965d4d91f
--- /dev/null
+++ b/drivers/crypto/qce/core.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CORE_H_
+#define _CORE_H_
+
+#include "dma.h"
+
+/**
+ * struct qce_device - crypto engine device structure
+ * @queue: crypto request queue
+ * @lock: the lock protects queue and req
+ * @done_tasklet: done tasklet object
+ * @req: current active request
+ * @result: result of current transform
+ * @base: virtual IO base
+ * @dev: pointer to device structure
+ * @core: core device clock
+ * @iface: interface clock
+ * @bus: bus clock
+ * @dma: pointer to dma data
+ * @burst_size: the crypto burst size
+ * @pipe_pair_id: which pipe pair id the device using
+ * @async_req_enqueue: invoked by every algorithm to enqueue a request
+ * @async_req_done: invoked by every algorithm to finish its request
+ */
+struct qce_device {
+ struct crypto_queue queue;
+ spinlock_t lock;
+ struct tasklet_struct done_tasklet;
+ struct crypto_async_request *req;
+ int result;
+ void __iomem *base;
+ struct device *dev;
+ struct clk *core, *iface, *bus;
+ struct qce_dma_data dma;
+ int burst_size;
+ unsigned int pipe_pair_id;
+ int (*async_req_enqueue)(struct qce_device *qce,
+ struct crypto_async_request *req);
+ void (*async_req_done)(struct qce_device *qce, int ret);
+};
+
+/**
+ * struct qce_algo_ops - algorithm operations per crypto type
+ * @type: should be CRYPTO_ALG_TYPE_XXX
+ * @register_algs: invoked by core to register the algorithms
+ * @unregister_algs: invoked by core to unregister the algorithms
+ * @async_req_handle: invoked by core to handle enqueued request
+ */
+struct qce_algo_ops {
+ u32 type;
+ int (*register_algs)(struct qce_device *qce);
+ void (*unregister_algs)(struct qce_device *qce);
+ int (*async_req_handle)(struct crypto_async_request *async_req);
+};
+
+#endif /* _CORE_H_ */
diff --git a/drivers/crypto/qce/dma.c b/drivers/crypto/qce/dma.c
new file mode 100644
index 000000000000..0fb21e13f247
--- /dev/null
+++ b/drivers/crypto/qce/dma.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dmaengine.h>
+#include <crypto/scatterwalk.h>
+
+#include "dma.h"
+
+int qce_dma_request(struct device *dev, struct qce_dma_data *dma)
+{
+ int ret;
+
+ dma->txchan = dma_request_slave_channel_reason(dev, "tx");
+ if (IS_ERR(dma->txchan))
+ return PTR_ERR(dma->txchan);
+
+ dma->rxchan = dma_request_slave_channel_reason(dev, "rx");
+ if (IS_ERR(dma->rxchan)) {
+ ret = PTR_ERR(dma->rxchan);
+ goto error_rx;
+ }
+
+ dma->result_buf = kmalloc(QCE_RESULT_BUF_SZ + QCE_IGNORE_BUF_SZ,
+ GFP_KERNEL);
+ if (!dma->result_buf) {
+ ret = -ENOMEM;
+ goto error_nomem;
+ }
+
+ dma->ignore_buf = dma->result_buf + QCE_RESULT_BUF_SZ;
+
+ return 0;
+error_nomem:
+ dma_release_channel(dma->rxchan);
+error_rx:
+ dma_release_channel(dma->txchan);
+ return ret;
+}
+
+void qce_dma_release(struct qce_dma_data *dma)
+{
+ dma_release_channel(dma->txchan);
+ dma_release_channel(dma->rxchan);
+ kfree(dma->result_buf);
+}
+
+int qce_mapsg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, bool chained)
+{
+ int err;
+
+ if (chained) {
+ while (sg) {
+ err = dma_map_sg(dev, sg, 1, dir);
+ if (!err)
+ return -EFAULT;
+ sg = scatterwalk_sg_next(sg);
+ }
+ } else {
+ err = dma_map_sg(dev, sg, nents, dir);
+ if (!err)
+ return -EFAULT;
+ }
+
+ return nents;
+}
+
+void qce_unmapsg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, bool chained)
+{
+ if (chained)
+ while (sg) {
+ dma_unmap_sg(dev, sg, 1, dir);
+ sg = scatterwalk_sg_next(sg);
+ }
+ else
+ dma_unmap_sg(dev, sg, nents, dir);
+}
+
+int qce_countsg(struct scatterlist *sglist, int nbytes, bool *chained)
+{
+ struct scatterlist *sg = sglist;
+ int nents = 0;
+
+ if (chained)
+ *chained = false;
+
+ while (nbytes > 0 && sg) {
+ nents++;
+ nbytes -= sg->length;
+ if (!sg_is_last(sg) && (sg + 1)->length == 0 && chained)
+ *chained = true;
+ sg = scatterwalk_sg_next(sg);
+ }
+
+ return nents;
+}
+
+struct scatterlist *
+qce_sgtable_add(struct sg_table *sgt, struct scatterlist *new_sgl)
+{
+ struct scatterlist *sg = sgt->sgl, *sg_last = NULL;
+
+ while (sg) {
+ if (!sg_page(sg))
+ break;
+ sg = sg_next(sg);
+ }
+
+ if (!sg)
+ return ERR_PTR(-EINVAL);
+
+ while (new_sgl && sg) {
+ sg_set_page(sg, sg_page(new_sgl), new_sgl->length,
+ new_sgl->offset);
+ sg_last = sg;
+ sg = sg_next(sg);
+ new_sgl = sg_next(new_sgl);
+ }
+
+ return sg_last;
+}
+
+static int qce_dma_prep_sg(struct dma_chan *chan, struct scatterlist *sg,
+ int nents, unsigned long flags,
+ enum dma_transfer_direction dir,
+ dma_async_tx_callback cb, void *cb_param)
+{
+ struct dma_async_tx_descriptor *desc;
+ dma_cookie_t cookie;
+
+ if (!sg || !nents)
+ return -EINVAL;
+
+ desc = dmaengine_prep_slave_sg(chan, sg, nents, dir, flags);
+ if (!desc)
+ return -EINVAL;
+
+ desc->callback = cb;
+ desc->callback_param = cb_param;
+ cookie = dmaengine_submit(desc);
+
+ return dma_submit_error(cookie);
+}
+
+int qce_dma_prep_sgs(struct qce_dma_data *dma, struct scatterlist *rx_sg,
+ int rx_nents, struct scatterlist *tx_sg, int tx_nents,
+ dma_async_tx_callback cb, void *cb_param)
+{
+ struct dma_chan *rxchan = dma->rxchan;
+ struct dma_chan *txchan = dma->txchan;
+ unsigned long flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
+ int ret;
+
+ ret = qce_dma_prep_sg(rxchan, rx_sg, rx_nents, flags, DMA_MEM_TO_DEV,
+ NULL, NULL);
+ if (ret)
+ return ret;
+
+ return qce_dma_prep_sg(txchan, tx_sg, tx_nents, flags, DMA_DEV_TO_MEM,
+ cb, cb_param);
+}
+
+void qce_dma_issue_pending(struct qce_dma_data *dma)
+{
+ dma_async_issue_pending(dma->rxchan);
+ dma_async_issue_pending(dma->txchan);
+}
+
+int qce_dma_terminate_all(struct qce_dma_data *dma)
+{
+ int ret;
+
+ ret = dmaengine_terminate_all(dma->rxchan);
+ return ret ?: dmaengine_terminate_all(dma->txchan);
+}
diff --git a/drivers/crypto/qce/dma.h b/drivers/crypto/qce/dma.h
new file mode 100644
index 000000000000..805e378d59e9
--- /dev/null
+++ b/drivers/crypto/qce/dma.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DMA_H_
+#define _DMA_H_
+
+/* maximum data transfer block size between BAM and CE */
+#define QCE_BAM_BURST_SIZE 64
+
+#define QCE_AUTHIV_REGS_CNT 16
+#define QCE_AUTH_BYTECOUNT_REGS_CNT 4
+#define QCE_CNTRIV_REGS_CNT 4
+
+struct qce_result_dump {
+ u32 auth_iv[QCE_AUTHIV_REGS_CNT];
+ u32 auth_byte_count[QCE_AUTH_BYTECOUNT_REGS_CNT];
+ u32 encr_cntr_iv[QCE_CNTRIV_REGS_CNT];
+ u32 status;
+ u32 status2;
+};
+
+#define QCE_IGNORE_BUF_SZ (2 * QCE_BAM_BURST_SIZE)
+#define QCE_RESULT_BUF_SZ \
+ ALIGN(sizeof(struct qce_result_dump), QCE_BAM_BURST_SIZE)
+
+struct qce_dma_data {
+ struct dma_chan *txchan;
+ struct dma_chan *rxchan;
+ struct qce_result_dump *result_buf;
+ void *ignore_buf;
+};
+
+int qce_dma_request(struct device *dev, struct qce_dma_data *dma);
+void qce_dma_release(struct qce_dma_data *dma);
+int qce_dma_prep_sgs(struct qce_dma_data *dma, struct scatterlist *sg_in,
+ int in_ents, struct scatterlist *sg_out, int out_ents,
+ dma_async_tx_callback cb, void *cb_param);
+void qce_dma_issue_pending(struct qce_dma_data *dma);
+int qce_dma_terminate_all(struct qce_dma_data *dma);
+int qce_countsg(struct scatterlist *sg_list, int nbytes, bool *chained);
+void qce_unmapsg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, bool chained);
+int qce_mapsg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, bool chained);
+struct scatterlist *
+qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add);
+
+#endif /* _DMA_H_ */
diff --git a/drivers/crypto/qce/regs-v5.h b/drivers/crypto/qce/regs-v5.h
new file mode 100644
index 000000000000..f0e19e35664a
--- /dev/null
+++ b/drivers/crypto/qce/regs-v5.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _REGS_V5_H_
+#define _REGS_V5_H_
+
+#include <linux/bitops.h>
+
+#define REG_VERSION 0x000
+#define REG_STATUS 0x100
+#define REG_STATUS2 0x104
+#define REG_ENGINES_AVAIL 0x108
+#define REG_FIFO_SIZES 0x10c
+#define REG_SEG_SIZE 0x110
+#define REG_GOPROC 0x120
+#define REG_ENCR_SEG_CFG 0x200
+#define REG_ENCR_SEG_SIZE 0x204
+#define REG_ENCR_SEG_START 0x208
+#define REG_CNTR0_IV0 0x20c
+#define REG_CNTR1_IV1 0x210
+#define REG_CNTR2_IV2 0x214
+#define REG_CNTR3_IV3 0x218
+#define REG_CNTR_MASK 0x21C
+#define REG_ENCR_CCM_INT_CNTR0 0x220
+#define REG_ENCR_CCM_INT_CNTR1 0x224
+#define REG_ENCR_CCM_INT_CNTR2 0x228
+#define REG_ENCR_CCM_INT_CNTR3 0x22c
+#define REG_ENCR_XTS_DU_SIZE 0x230
+#define REG_CNTR_MASK2 0x234
+#define REG_CNTR_MASK1 0x238
+#define REG_CNTR_MASK0 0x23c
+#define REG_AUTH_SEG_CFG 0x300
+#define REG_AUTH_SEG_SIZE 0x304
+#define REG_AUTH_SEG_START 0x308
+#define REG_AUTH_IV0 0x310
+#define REG_AUTH_IV1 0x314
+#define REG_AUTH_IV2 0x318
+#define REG_AUTH_IV3 0x31c
+#define REG_AUTH_IV4 0x320
+#define REG_AUTH_IV5 0x324
+#define REG_AUTH_IV6 0x328
+#define REG_AUTH_IV7 0x32c
+#define REG_AUTH_IV8 0x330
+#define REG_AUTH_IV9 0x334
+#define REG_AUTH_IV10 0x338
+#define REG_AUTH_IV11 0x33c
+#define REG_AUTH_IV12 0x340
+#define REG_AUTH_IV13 0x344
+#define REG_AUTH_IV14 0x348
+#define REG_AUTH_IV15 0x34c
+#define REG_AUTH_INFO_NONCE0 0x350
+#define REG_AUTH_INFO_NONCE1 0x354
+#define REG_AUTH_INFO_NONCE2 0x358
+#define REG_AUTH_INFO_NONCE3 0x35c
+#define REG_AUTH_BYTECNT0 0x390
+#define REG_AUTH_BYTECNT1 0x394
+#define REG_AUTH_BYTECNT2 0x398
+#define REG_AUTH_BYTECNT3 0x39c
+#define REG_AUTH_EXP_MAC0 0x3a0
+#define REG_AUTH_EXP_MAC1 0x3a4
+#define REG_AUTH_EXP_MAC2 0x3a8
+#define REG_AUTH_EXP_MAC3 0x3ac
+#define REG_AUTH_EXP_MAC4 0x3b0
+#define REG_AUTH_EXP_MAC5 0x3b4
+#define REG_AUTH_EXP_MAC6 0x3b8
+#define REG_AUTH_EXP_MAC7 0x3bc
+#define REG_CONFIG 0x400
+#define REG_GOPROC_QC_KEY 0x1000
+#define REG_GOPROC_OEM_KEY 0x2000
+#define REG_ENCR_KEY0 0x3000
+#define REG_ENCR_KEY1 0x3004
+#define REG_ENCR_KEY2 0x3008
+#define REG_ENCR_KEY3 0x300c
+#define REG_ENCR_KEY4 0x3010
+#define REG_ENCR_KEY5 0x3014
+#define REG_ENCR_KEY6 0x3018
+#define REG_ENCR_KEY7 0x301c
+#define REG_ENCR_XTS_KEY0 0x3020
+#define REG_ENCR_XTS_KEY1 0x3024
+#define REG_ENCR_XTS_KEY2 0x3028
+#define REG_ENCR_XTS_KEY3 0x302c
+#define REG_ENCR_XTS_KEY4 0x3030
+#define REG_ENCR_XTS_KEY5 0x3034
+#define REG_ENCR_XTS_KEY6 0x3038
+#define REG_ENCR_XTS_KEY7 0x303c
+#define REG_AUTH_KEY0 0x3040
+#define REG_AUTH_KEY1 0x3044
+#define REG_AUTH_KEY2 0x3048
+#define REG_AUTH_KEY3 0x304c
+#define REG_AUTH_KEY4 0x3050
+#define REG_AUTH_KEY5 0x3054
+#define REG_AUTH_KEY6 0x3058
+#define REG_AUTH_KEY7 0x305c
+#define REG_AUTH_KEY8 0x3060
+#define REG_AUTH_KEY9 0x3064
+#define REG_AUTH_KEY10 0x3068
+#define REG_AUTH_KEY11 0x306c
+#define REG_AUTH_KEY12 0x3070
+#define REG_AUTH_KEY13 0x3074
+#define REG_AUTH_KEY14 0x3078
+#define REG_AUTH_KEY15 0x307c
+
+/* Register bits - REG_VERSION */
+#define CORE_STEP_REV_SHIFT 0
+#define CORE_STEP_REV_MASK GENMASK(15, 0)
+#define CORE_MINOR_REV_SHIFT 16
+#define CORE_MINOR_REV_MASK GENMASK(23, 16)
+#define CORE_MAJOR_REV_SHIFT 24
+#define CORE_MAJOR_REV_MASK GENMASK(31, 24)
+
+/* Register bits - REG_STATUS */
+#define MAC_FAILED_SHIFT 31
+#define DOUT_SIZE_AVAIL_SHIFT 26
+#define DOUT_SIZE_AVAIL_MASK GENMASK(30, 26)
+#define DIN_SIZE_AVAIL_SHIFT 21
+#define DIN_SIZE_AVAIL_MASK GENMASK(25, 21)
+#define HSD_ERR_SHIFT 20
+#define ACCESS_VIOL_SHIFT 19
+#define PIPE_ACTIVE_ERR_SHIFT 18
+#define CFG_CHNG_ERR_SHIFT 17
+#define DOUT_ERR_SHIFT 16
+#define DIN_ERR_SHIFT 15
+#define AXI_ERR_SHIFT 14
+#define CRYPTO_STATE_SHIFT 10
+#define CRYPTO_STATE_MASK GENMASK(13, 10)
+#define ENCR_BUSY_SHIFT 9
+#define AUTH_BUSY_SHIFT 8
+#define DOUT_INTR_SHIFT 7
+#define DIN_INTR_SHIFT 6
+#define OP_DONE_INTR_SHIFT 5
+#define ERR_INTR_SHIFT 4
+#define DOUT_RDY_SHIFT 3
+#define DIN_RDY_SHIFT 2
+#define OPERATION_DONE_SHIFT 1
+#define SW_ERR_SHIFT 0
+
+/* Register bits - REG_STATUS2 */
+#define AXI_EXTRA_SHIFT 1
+#define LOCKED_SHIFT 2
+
+/* Register bits - REG_CONFIG */
+#define REQ_SIZE_SHIFT 17
+#define REQ_SIZE_MASK GENMASK(20, 17)
+#define REQ_SIZE_ENUM_1_BEAT 0
+#define REQ_SIZE_ENUM_2_BEAT 1
+#define REQ_SIZE_ENUM_3_BEAT 2
+#define REQ_SIZE_ENUM_4_BEAT 3
+#define REQ_SIZE_ENUM_5_BEAT 4
+#define REQ_SIZE_ENUM_6_BEAT 5
+#define REQ_SIZE_ENUM_7_BEAT 6
+#define REQ_SIZE_ENUM_8_BEAT 7
+#define REQ_SIZE_ENUM_9_BEAT 8
+#define REQ_SIZE_ENUM_10_BEAT 9
+#define REQ_SIZE_ENUM_11_BEAT 10
+#define REQ_SIZE_ENUM_12_BEAT 11
+#define REQ_SIZE_ENUM_13_BEAT 12
+#define REQ_SIZE_ENUM_14_BEAT 13
+#define REQ_SIZE_ENUM_15_BEAT 14
+#define REQ_SIZE_ENUM_16_BEAT 15
+
+#define MAX_QUEUED_REQ_SHIFT 14
+#define MAX_QUEUED_REQ_MASK GENMASK(24, 16)
+#define ENUM_1_QUEUED_REQS 0
+#define ENUM_2_QUEUED_REQS 1
+#define ENUM_3_QUEUED_REQS 2
+
+#define IRQ_ENABLES_SHIFT 10
+#define IRQ_ENABLES_MASK GENMASK(13, 10)
+
+#define LITTLE_ENDIAN_MODE_SHIFT 9
+#define PIPE_SET_SELECT_SHIFT 5
+#define PIPE_SET_SELECT_MASK GENMASK(8, 5)
+
+#define HIGH_SPD_EN_N_SHIFT 4
+#define MASK_DOUT_INTR_SHIFT 3
+#define MASK_DIN_INTR_SHIFT 2
+#define MASK_OP_DONE_INTR_SHIFT 1
+#define MASK_ERR_INTR_SHIFT 0
+
+/* Register bits - REG_AUTH_SEG_CFG */
+#define COMP_EXP_MAC_SHIFT 24
+#define COMP_EXP_MAC_DISABLED 0
+#define COMP_EXP_MAC_ENABLED 1
+
+#define F9_DIRECTION_SHIFT 23
+#define F9_DIRECTION_UPLINK 0
+#define F9_DIRECTION_DOWNLINK 1
+
+#define AUTH_NONCE_NUM_WORDS_SHIFT 20
+#define AUTH_NONCE_NUM_WORDS_MASK GENMASK(22, 20)
+
+#define USE_PIPE_KEY_AUTH_SHIFT 19
+#define USE_HW_KEY_AUTH_SHIFT 18
+#define AUTH_FIRST_SHIFT 17
+#define AUTH_LAST_SHIFT 16
+
+#define AUTH_POS_SHIFT 14
+#define AUTH_POS_MASK GENMASK(15, 14)
+#define AUTH_POS_BEFORE 0
+#define AUTH_POS_AFTER 1
+
+#define AUTH_SIZE_SHIFT 9
+#define AUTH_SIZE_MASK GENMASK(13, 9)
+#define AUTH_SIZE_SHA1 0
+#define AUTH_SIZE_SHA256 1
+#define AUTH_SIZE_ENUM_1_BYTES 0
+#define AUTH_SIZE_ENUM_2_BYTES 1
+#define AUTH_SIZE_ENUM_3_BYTES 2
+#define AUTH_SIZE_ENUM_4_BYTES 3
+#define AUTH_SIZE_ENUM_5_BYTES 4
+#define AUTH_SIZE_ENUM_6_BYTES 5
+#define AUTH_SIZE_ENUM_7_BYTES 6
+#define AUTH_SIZE_ENUM_8_BYTES 7
+#define AUTH_SIZE_ENUM_9_BYTES 8
+#define AUTH_SIZE_ENUM_10_BYTES 9
+#define AUTH_SIZE_ENUM_11_BYTES 10
+#define AUTH_SIZE_ENUM_12_BYTES 11
+#define AUTH_SIZE_ENUM_13_BYTES 12
+#define AUTH_SIZE_ENUM_14_BYTES 13
+#define AUTH_SIZE_ENUM_15_BYTES 14
+#define AUTH_SIZE_ENUM_16_BYTES 15
+
+#define AUTH_MODE_SHIFT 6
+#define AUTH_MODE_MASK GENMASK(8, 6)
+#define AUTH_MODE_HASH 0
+#define AUTH_MODE_HMAC 1
+#define AUTH_MODE_CCM 0
+#define AUTH_MODE_CMAC 1
+
+#define AUTH_KEY_SIZE_SHIFT 3
+#define AUTH_KEY_SIZE_MASK GENMASK(5, 3)
+#define AUTH_KEY_SZ_AES128 0
+#define AUTH_KEY_SZ_AES256 2
+
+#define AUTH_ALG_SHIFT 0
+#define AUTH_ALG_MASK GENMASK(2, 0)
+#define AUTH_ALG_NONE 0
+#define AUTH_ALG_SHA 1
+#define AUTH_ALG_AES 2
+#define AUTH_ALG_KASUMI 3
+#define AUTH_ALG_SNOW3G 4
+#define AUTH_ALG_ZUC 5
+
+/* Register bits - REG_ENCR_XTS_DU_SIZE */
+#define ENCR_XTS_DU_SIZE_SHIFT 0
+#define ENCR_XTS_DU_SIZE_MASK GENMASK(19, 0)
+
+/* Register bits - REG_ENCR_SEG_CFG */
+#define F8_KEYSTREAM_ENABLE_SHIFT 17
+#define F8_KEYSTREAM_DISABLED 0
+#define F8_KEYSTREAM_ENABLED 1
+
+#define F8_DIRECTION_SHIFT 16
+#define F8_DIRECTION_UPLINK 0
+#define F8_DIRECTION_DOWNLINK 1
+
+#define USE_PIPE_KEY_ENCR_SHIFT 15
+#define USE_PIPE_KEY_ENCR_ENABLED 1
+#define USE_KEY_REGISTERS 0
+
+#define USE_HW_KEY_ENCR_SHIFT 14
+#define USE_KEY_REG 0
+#define USE_HW_KEY 1
+
+#define LAST_CCM_SHIFT 13
+#define LAST_CCM_XFR 1
+#define INTERM_CCM_XFR 0
+
+#define CNTR_ALG_SHIFT 11
+#define CNTR_ALG_MASK GENMASK(12, 11)
+#define CNTR_ALG_NIST 0
+
+#define ENCODE_SHIFT 10
+
+#define ENCR_MODE_SHIFT 6
+#define ENCR_MODE_MASK GENMASK(9, 6)
+#define ENCR_MODE_ECB 0
+#define ENCR_MODE_CBC 1
+#define ENCR_MODE_CTR 2
+#define ENCR_MODE_XTS 3
+#define ENCR_MODE_CCM 4
+
+#define ENCR_KEY_SZ_SHIFT 3
+#define ENCR_KEY_SZ_MASK GENMASK(5, 3)
+#define ENCR_KEY_SZ_DES 0
+#define ENCR_KEY_SZ_3DES 1
+#define ENCR_KEY_SZ_AES128 0
+#define ENCR_KEY_SZ_AES256 2
+
+#define ENCR_ALG_SHIFT 0
+#define ENCR_ALG_MASK GENMASK(2, 0)
+#define ENCR_ALG_NONE 0
+#define ENCR_ALG_DES 1
+#define ENCR_ALG_AES 2
+#define ENCR_ALG_KASUMI 4
+#define ENCR_ALG_SNOW_3G 5
+#define ENCR_ALG_ZUC 6
+
+/* Register bits - REG_GOPROC */
+#define GO_SHIFT 0
+#define CLR_CNTXT_SHIFT 1
+#define RESULTS_DUMP_SHIFT 2
+
+/* Register bits - REG_ENGINES_AVAIL */
+#define ENCR_AES_SEL_SHIFT 0
+#define DES_SEL_SHIFT 1
+#define ENCR_SNOW3G_SEL_SHIFT 2
+#define ENCR_KASUMI_SEL_SHIFT 3
+#define SHA_SEL_SHIFT 4
+#define SHA512_SEL_SHIFT 5
+#define AUTH_AES_SEL_SHIFT 6
+#define AUTH_SNOW3G_SEL_SHIFT 7
+#define AUTH_KASUMI_SEL_SHIFT 8
+#define BAM_PIPE_SETS_SHIFT 9
+#define BAM_PIPE_SETS_MASK GENMASK(12, 9)
+#define AXI_WR_BEATS_SHIFT 13
+#define AXI_WR_BEATS_MASK GENMASK(18, 13)
+#define AXI_RD_BEATS_SHIFT 19
+#define AXI_RD_BEATS_MASK GENMASK(24, 19)
+#define ENCR_ZUC_SEL_SHIFT 26
+#define AUTH_ZUC_SEL_SHIFT 27
+#define ZUC_ENABLE_SHIFT 28
+
+#endif /* _REGS_V5_H_ */
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
new file mode 100644
index 000000000000..f3385934eed2
--- /dev/null
+++ b/drivers/crypto/qce/sha.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <crypto/internal/hash.h>
+
+#include "common.h"
+#include "core.h"
+#include "sha.h"
+
+/* crypto hw padding constant for first operation */
+#define SHA_PADDING 64
+#define SHA_PADDING_MASK (SHA_PADDING - 1)
+
+static LIST_HEAD(ahash_algs);
+
+static const u32 std_iv_sha1[SHA256_DIGEST_SIZE / sizeof(u32)] = {
+ SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4, 0, 0, 0
+};
+
+static const u32 std_iv_sha256[SHA256_DIGEST_SIZE / sizeof(u32)] = {
+ SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3,
+ SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7
+};
+
+static void qce_ahash_done(void *data)
+{
+ struct crypto_async_request *async_req = data;
+ struct ahash_request *req = ahash_request_cast(async_req);
+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ struct qce_result_dump *result = qce->dma.result_buf;
+ unsigned int digestsize = crypto_ahash_digestsize(ahash);
+ int error;
+ u32 status;
+
+ error = qce_dma_terminate_all(&qce->dma);
+ if (error)
+ dev_dbg(qce->dev, "ahash dma termination error (%d)\n", error);
+
+ qce_unmapsg(qce->dev, req->src, rctx->src_nents, DMA_TO_DEVICE,
+ rctx->src_chained);
+ qce_unmapsg(qce->dev, &rctx->result_sg, 1, DMA_FROM_DEVICE, 0);
+
+ memcpy(rctx->digest, result->auth_iv, digestsize);
+ if (req->result)
+ memcpy(req->result, result->auth_iv, digestsize);
+
+ rctx->byte_count[0] = cpu_to_be32(result->auth_byte_count[0]);
+ rctx->byte_count[1] = cpu_to_be32(result->auth_byte_count[1]);
+
+ error = qce_check_status(qce, &status);
+ if (error < 0)
+ dev_dbg(qce->dev, "ahash operation error (%x)\n", status);
+
+ req->src = rctx->src_orig;
+ req->nbytes = rctx->nbytes_orig;
+ rctx->last_blk = false;
+ rctx->first_blk = false;
+
+ qce->async_req_done(tmpl->qce, error);
+}
+
+static int qce_ahash_async_req_handle(struct crypto_async_request *async_req)
+{
+ struct ahash_request *req = ahash_request_cast(async_req);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_sha_ctx *ctx = crypto_tfm_ctx(async_req->tfm);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(async_req->tfm);
+ struct qce_device *qce = tmpl->qce;
+ unsigned long flags = rctx->flags;
+ int ret;
+
+ if (IS_SHA_HMAC(flags)) {
+ rctx->authkey = ctx->authkey;
+ rctx->authklen = QCE_SHA_HMAC_KEY_SIZE;
+ } else if (IS_CMAC(flags)) {
+ rctx->authkey = ctx->authkey;
+ rctx->authklen = AES_KEYSIZE_128;
+ }
+
+ rctx->src_nents = qce_countsg(req->src, req->nbytes,
+ &rctx->src_chained);
+ ret = qce_mapsg(qce->dev, req->src, rctx->src_nents, DMA_TO_DEVICE,
+ rctx->src_chained);
+ if (ret < 0)
+ return ret;
+
+ sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
+
+ ret = qce_mapsg(qce->dev, &rctx->result_sg, 1, DMA_FROM_DEVICE, 0);
+ if (ret < 0)
+ goto error_unmap_src;
+
+ ret = qce_dma_prep_sgs(&qce->dma, req->src, rctx->src_nents,
+ &rctx->result_sg, 1, qce_ahash_done, async_req);
+ if (ret)
+ goto error_unmap_dst;
+
+ qce_dma_issue_pending(&qce->dma);
+
+ ret = qce_start(async_req, tmpl->crypto_alg_type, 0, 0);
+ if (ret)
+ goto error_terminate;
+
+ return 0;
+
+error_terminate:
+ qce_dma_terminate_all(&qce->dma);
+error_unmap_dst:
+ qce_unmapsg(qce->dev, &rctx->result_sg, 1, DMA_FROM_DEVICE, 0);
+error_unmap_src:
+ qce_unmapsg(qce->dev, req->src, rctx->src_nents, DMA_TO_DEVICE,
+ rctx->src_chained);
+ return ret;
+}
+
+static int qce_ahash_init(struct ahash_request *req)
+{
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
+ const u32 *std_iv = tmpl->std_iv;
+
+ memset(rctx, 0, sizeof(*rctx));
+ rctx->first_blk = true;
+ rctx->last_blk = false;
+ rctx->flags = tmpl->alg_flags;
+ memcpy(rctx->digest, std_iv, sizeof(rctx->digest));
+
+ return 0;
+}
+
+static int qce_ahash_export(struct ahash_request *req, void *out)
+{
+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ unsigned long flags = rctx->flags;
+ unsigned int digestsize = crypto_ahash_digestsize(ahash);
+ unsigned int blocksize =
+ crypto_tfm_alg_blocksize(crypto_ahash_tfm(ahash));
+
+ if (IS_SHA1(flags) || IS_SHA1_HMAC(flags)) {
+ struct sha1_state *out_state = out;
+
+ out_state->count = rctx->count;
+ qce_cpu_to_be32p_array((__be32 *)out_state->state,
+ rctx->digest, digestsize);
+ memcpy(out_state->buffer, rctx->buf, blocksize);
+ } else if (IS_SHA256(flags) || IS_SHA256_HMAC(flags)) {
+ struct sha256_state *out_state = out;
+
+ out_state->count = rctx->count;
+ qce_cpu_to_be32p_array((__be32 *)out_state->state,
+ rctx->digest, digestsize);
+ memcpy(out_state->buf, rctx->buf, blocksize);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int qce_import_common(struct ahash_request *req, u64 in_count,
+ const u32 *state, const u8 *buffer, bool hmac)
+{
+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ unsigned int digestsize = crypto_ahash_digestsize(ahash);
+ unsigned int blocksize;
+ u64 count = in_count;
+
+ blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(ahash));
+ rctx->count = in_count;
+ memcpy(rctx->buf, buffer, blocksize);
+
+ if (in_count <= blocksize) {
+ rctx->first_blk = 1;
+ } else {
+ rctx->first_blk = 0;
+ /*
+ * For HMAC, there is a hardware padding done when first block
+ * is set. Therefore the byte_count must be incremened by 64
+ * after the first block operation.
+ */
+ if (hmac)
+ count += SHA_PADDING;
+ }
+
+ rctx->byte_count[0] = (__force __be32)(count & ~SHA_PADDING_MASK);
+ rctx->byte_count[1] = (__force __be32)(count >> 32);
+ qce_cpu_to_be32p_array((__be32 *)rctx->digest, (const u8 *)state,
+ digestsize);
+ rctx->buflen = (unsigned int)(in_count & (blocksize - 1));
+
+ return 0;
+}
+
+static int qce_ahash_import(struct ahash_request *req, const void *in)
+{
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ unsigned long flags = rctx->flags;
+ bool hmac = IS_SHA_HMAC(flags);
+ int ret = -EINVAL;
+
+ if (IS_SHA1(flags) || IS_SHA1_HMAC(flags)) {
+ const struct sha1_state *state = in;
+
+ ret = qce_import_common(req, state->count, state->state,
+ state->buffer, hmac);
+ } else if (IS_SHA256(flags) || IS_SHA256_HMAC(flags)) {
+ const struct sha256_state *state = in;
+
+ ret = qce_import_common(req, state->count, state->state,
+ state->buf, hmac);
+ }
+
+ return ret;
+}
+
+static int qce_ahash_update(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
+ struct qce_device *qce = tmpl->qce;
+ struct scatterlist *sg_last, *sg;
+ unsigned int total, len;
+ unsigned int hash_later;
+ unsigned int nbytes;
+ unsigned int blocksize;
+
+ blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+ rctx->count += req->nbytes;
+
+ /* check for buffer from previous updates and append it */
+ total = req->nbytes + rctx->buflen;
+
+ if (total <= blocksize) {
+ scatterwalk_map_and_copy(rctx->buf + rctx->buflen, req->src,
+ 0, req->nbytes, 0);
+ rctx->buflen += req->nbytes;
+ return 0;
+ }
+
+ /* save the original req structure fields */
+ rctx->src_orig = req->src;
+ rctx->nbytes_orig = req->nbytes;
+
+ /*
+ * if we have data from previous update copy them on buffer. The old
+ * data will be combined with current request bytes.
+ */
+ if (rctx->buflen)
+ memcpy(rctx->tmpbuf, rctx->buf, rctx->buflen);
+
+ /* calculate how many bytes will be hashed later */
+ hash_later = total % blocksize;
+ if (hash_later) {
+ unsigned int src_offset = req->nbytes - hash_later;
+ scatterwalk_map_and_copy(rctx->buf, req->src, src_offset,
+ hash_later, 0);
+ }
+
+ /* here nbytes is multiple of blocksize */
+ nbytes = total - hash_later;
+
+ len = rctx->buflen;
+ sg = sg_last = req->src;
+
+ while (len < nbytes && sg) {
+ if (len + sg_dma_len(sg) > nbytes)
+ break;
+ len += sg_dma_len(sg);
+ sg_last = sg;
+ sg = scatterwalk_sg_next(sg);
+ }
+
+ if (!sg_last)
+ return -EINVAL;
+
+ sg_mark_end(sg_last);
+
+ if (rctx->buflen) {
+ sg_init_table(rctx->sg, 2);
+ sg_set_buf(rctx->sg, rctx->tmpbuf, rctx->buflen);
+ scatterwalk_sg_chain(rctx->sg, 2, req->src);
+ req->src = rctx->sg;
+ }
+
+ req->nbytes = nbytes;
+ rctx->buflen = hash_later;
+
+ return qce->async_req_enqueue(tmpl->qce, &req->base);
+}
+
+static int qce_ahash_final(struct ahash_request *req)
+{
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
+ struct qce_device *qce = tmpl->qce;
+
+ if (!rctx->buflen)
+ return 0;
+
+ rctx->last_blk = true;
+
+ rctx->src_orig = req->src;
+ rctx->nbytes_orig = req->nbytes;
+
+ memcpy(rctx->tmpbuf, rctx->buf, rctx->buflen);
+ sg_init_one(rctx->sg, rctx->tmpbuf, rctx->buflen);
+
+ req->src = rctx->sg;
+ req->nbytes = rctx->buflen;
+
+ return qce->async_req_enqueue(tmpl->qce, &req->base);
+}
+
+static int qce_ahash_digest(struct ahash_request *req)
+{
+ struct qce_sha_reqctx *rctx = ahash_request_ctx(req);
+ struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
+ struct qce_device *qce = tmpl->qce;
+ int ret;
+
+ ret = qce_ahash_init(req);
+ if (ret)
+ return ret;
+
+ rctx->src_orig = req->src;
+ rctx->nbytes_orig = req->nbytes;
+ rctx->first_blk = true;
+ rctx->last_blk = true;
+
+ return qce->async_req_enqueue(tmpl->qce, &req->base);
+}
+
+struct qce_ahash_result {
+ struct completion completion;
+ int error;
+};
+
+static void qce_digest_complete(struct crypto_async_request *req, int error)
+{
+ struct qce_ahash_result *result = req->data;
+
+ if (error == -EINPROGRESS)
+ return;
+
+ result->error = error;
+ complete(&result->completion);
+}
+
+static int qce_ahash_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ unsigned int digestsize = crypto_ahash_digestsize(tfm);
+ struct qce_sha_ctx *ctx = crypto_tfm_ctx(&tfm->base);
+ struct qce_ahash_result result;
+ struct ahash_request *req;
+ struct scatterlist sg;
+ unsigned int blocksize;
+ struct crypto_ahash *ahash_tfm;
+ u8 *buf;
+ int ret;
+ const char *alg_name;
+
+ blocksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+ memset(ctx->authkey, 0, sizeof(ctx->authkey));
+
+ if (keylen <= blocksize) {
+ memcpy(ctx->authkey, key, keylen);
+ return 0;
+ }
+
+ if (digestsize == SHA1_DIGEST_SIZE)
+ alg_name = "sha1-qce";
+ else if (digestsize == SHA256_DIGEST_SIZE)
+ alg_name = "sha256-qce";
+ else
+ return -EINVAL;
+
+ ahash_tfm = crypto_alloc_ahash(alg_name, CRYPTO_ALG_TYPE_AHASH,
+ CRYPTO_ALG_TYPE_AHASH_MASK);
+ if (IS_ERR(ahash_tfm))
+ return PTR_ERR(ahash_tfm);
+
+ req = ahash_request_alloc(ahash_tfm, GFP_KERNEL);
+ if (!req) {
+ ret = -ENOMEM;
+ goto err_free_ahash;
+ }
+
+ init_completion(&result.completion);
+ ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ qce_digest_complete, &result);
+ crypto_ahash_clear_flags(ahash_tfm, ~0);
+
+ buf = kzalloc(keylen + QCE_MAX_ALIGN_SIZE, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto err_free_req;
+ }
+
+ memcpy(buf, key, keylen);
+ sg_init_one(&sg, buf, keylen);
+ ahash_request_set_crypt(req, &sg, ctx->authkey, keylen);
+
+ ret = crypto_ahash_digest(req);
+ if (ret == -EINPROGRESS || ret == -EBUSY) {
+ ret = wait_for_completion_interruptible(&result.completion);
+ if (!ret)
+ ret = result.error;
+ }
+
+ if (ret)
+ crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+
+ kfree(buf);
+err_free_req:
+ ahash_request_free(req);
+err_free_ahash:
+ crypto_free_ahash(ahash_tfm);
+ return ret;
+}
+
+static int qce_ahash_cra_init(struct crypto_tfm *tfm)
+{
+ struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
+ struct qce_sha_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_ahash_set_reqsize(ahash, sizeof(struct qce_sha_reqctx));
+ memset(ctx, 0, sizeof(*ctx));
+ return 0;
+}
+
+struct qce_ahash_def {
+ unsigned long flags;
+ const char *name;
+ const char *drv_name;
+ unsigned int digestsize;
+ unsigned int blocksize;
+ unsigned int statesize;
+ const u32 *std_iv;
+};
+
+static const struct qce_ahash_def ahash_def[] = {
+ {
+ .flags = QCE_HASH_SHA1,
+ .name = "sha1",
+ .drv_name = "sha1-qce",
+ .digestsize = SHA1_DIGEST_SIZE,
+ .blocksize = SHA1_BLOCK_SIZE,
+ .statesize = sizeof(struct sha1_state),
+ .std_iv = std_iv_sha1,
+ },
+ {
+ .flags = QCE_HASH_SHA256,
+ .name = "sha256",
+ .drv_name = "sha256-qce",
+ .digestsize = SHA256_DIGEST_SIZE,
+ .blocksize = SHA256_BLOCK_SIZE,
+ .statesize = sizeof(struct sha256_state),
+ .std_iv = std_iv_sha256,
+ },
+ {
+ .flags = QCE_HASH_SHA1_HMAC,
+ .name = "hmac(sha1)",
+ .drv_name = "hmac-sha1-qce",
+ .digestsize = SHA1_DIGEST_SIZE,
+ .blocksize = SHA1_BLOCK_SIZE,
+ .statesize = sizeof(struct sha1_state),
+ .std_iv = std_iv_sha1,
+ },
+ {
+ .flags = QCE_HASH_SHA256_HMAC,
+ .name = "hmac(sha256)",
+ .drv_name = "hmac-sha256-qce",
+ .digestsize = SHA256_DIGEST_SIZE,
+ .blocksize = SHA256_BLOCK_SIZE,
+ .statesize = sizeof(struct sha256_state),
+ .std_iv = std_iv_sha256,
+ },
+};
+
+static int qce_ahash_register_one(const struct qce_ahash_def *def,
+ struct qce_device *qce)
+{
+ struct qce_alg_template *tmpl;
+ struct ahash_alg *alg;
+ struct crypto_alg *base;
+ int ret;
+
+ tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL);
+ if (!tmpl)
+ return -ENOMEM;
+
+ tmpl->std_iv = def->std_iv;
+
+ alg = &tmpl->alg.ahash;
+ alg->init = qce_ahash_init;
+ alg->update = qce_ahash_update;
+ alg->final = qce_ahash_final;
+ alg->digest = qce_ahash_digest;
+ alg->export = qce_ahash_export;
+ alg->import = qce_ahash_import;
+ if (IS_SHA_HMAC(def->flags))
+ alg->setkey = qce_ahash_hmac_setkey;
+ alg->halg.digestsize = def->digestsize;
+ alg->halg.statesize = def->statesize;
+
+ base = &alg->halg.base;
+ base->cra_blocksize = def->blocksize;
+ base->cra_priority = 300;
+ base->cra_flags = CRYPTO_ALG_ASYNC;
+ base->cra_ctxsize = sizeof(struct qce_sha_ctx);
+ base->cra_alignmask = 0;
+ base->cra_module = THIS_MODULE;
+ base->cra_init = qce_ahash_cra_init;
+ INIT_LIST_HEAD(&base->cra_list);
+
+ snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
+ snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
+ def->drv_name);
+
+ INIT_LIST_HEAD(&tmpl->entry);
+ tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_AHASH;
+ tmpl->alg_flags = def->flags;
+ tmpl->qce = qce;
+
+ ret = crypto_register_ahash(alg);
+ if (ret) {
+ kfree(tmpl);
+ dev_err(qce->dev, "%s registration failed\n", base->cra_name);
+ return ret;
+ }
+
+ list_add_tail(&tmpl->entry, &ahash_algs);
+ dev_dbg(qce->dev, "%s is registered\n", base->cra_name);
+ return 0;
+}
+
+static void qce_ahash_unregister(struct qce_device *qce)
+{
+ struct qce_alg_template *tmpl, *n;
+
+ list_for_each_entry_safe(tmpl, n, &ahash_algs, entry) {
+ crypto_unregister_ahash(&tmpl->alg.ahash);
+ list_del(&tmpl->entry);
+ kfree(tmpl);
+ }
+}
+
+static int qce_ahash_register(struct qce_device *qce)
+{
+ int ret, i;
+
+ for (i = 0; i < ARRAY_SIZE(ahash_def); i++) {
+ ret = qce_ahash_register_one(&ahash_def[i], qce);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ qce_ahash_unregister(qce);
+ return ret;
+}
+
+const struct qce_algo_ops ahash_ops = {
+ .type = CRYPTO_ALG_TYPE_AHASH,
+ .register_algs = qce_ahash_register,
+ .unregister_algs = qce_ahash_unregister,
+ .async_req_handle = qce_ahash_async_req_handle,
+};
diff --git a/drivers/crypto/qce/sha.h b/drivers/crypto/qce/sha.h
new file mode 100644
index 000000000000..286f0d5397f3
--- /dev/null
+++ b/drivers/crypto/qce/sha.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SHA_H_
+#define _SHA_H_
+
+#include <crypto/scatterwalk.h>
+#include <crypto/sha.h>
+
+#include "common.h"
+#include "core.h"
+
+#define QCE_SHA_MAX_BLOCKSIZE SHA256_BLOCK_SIZE
+#define QCE_SHA_MAX_DIGESTSIZE SHA256_DIGEST_SIZE
+
+struct qce_sha_ctx {
+ u8 authkey[QCE_SHA_MAX_BLOCKSIZE];
+};
+
+/**
+ * struct qce_sha_reqctx - holds private ahash objects per request
+ * @buf: used during update, import and export
+ * @tmpbuf: buffer for internal use
+ * @digest: calculated digest buffer
+ * @buflen: length of the buffer
+ * @flags: operation flags
+ * @src_orig: original request sg list
+ * @nbytes_orig: original request number of bytes
+ * @src_chained: is source scatterlist chained
+ * @src_nents: source number of entries
+ * @byte_count: byte count
+ * @count: save count in states during update, import and export
+ * @first_blk: is it the first block
+ * @last_blk: is it the last block
+ * @sg: used to chain sg lists
+ * @authkey: pointer to auth key in sha ctx
+ * @authklen: auth key length
+ * @result_sg: scatterlist used for result buffer
+ */
+struct qce_sha_reqctx {
+ u8 buf[QCE_SHA_MAX_BLOCKSIZE];
+ u8 tmpbuf[QCE_SHA_MAX_BLOCKSIZE];
+ u8 digest[QCE_SHA_MAX_DIGESTSIZE];
+ unsigned int buflen;
+ unsigned long flags;
+ struct scatterlist *src_orig;
+ unsigned int nbytes_orig;
+ bool src_chained;
+ int src_nents;
+ __be32 byte_count[2];
+ u64 count;
+ bool first_blk;
+ bool last_blk;
+ struct scatterlist sg[2];
+ u8 *authkey;
+ unsigned int authklen;
+ struct scatterlist result_sg;
+};
+
+static inline struct qce_alg_template *to_ahash_tmpl(struct crypto_tfm *tfm)
+{
+ struct crypto_ahash *ahash = __crypto_ahash_cast(tfm);
+ struct ahash_alg *alg = container_of(crypto_hash_alg_common(ahash),
+ struct ahash_alg, halg);
+
+ return container_of(alg, struct qce_alg_template, alg.ahash);
+}
+
+extern const struct qce_algo_ops ahash_ops;
+
+#endif /* _SHA_H_ */
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index a999f537228f..92105f3dc8e0 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -190,7 +190,7 @@ static void add_session_id(struct cryp_ctx *ctx)
static irqreturn_t cryp_interrupt_handler(int irq, void *param)
{
struct cryp_ctx *ctx;
- int i;
+ int count;
struct cryp_device_data *device_data;
if (param == NULL) {
@@ -215,12 +215,11 @@ static irqreturn_t cryp_interrupt_handler(int irq, void *param)
if (cryp_pending_irq_src(device_data,
CRYP_IRQ_SRC_OUTPUT_FIFO)) {
if (ctx->outlen / ctx->blocksize > 0) {
- for (i = 0; i < ctx->blocksize / 4; i++) {
- *(ctx->outdata) = readl_relaxed(
- &device_data->base->dout);
- ctx->outdata += 4;
- ctx->outlen -= 4;
- }
+ count = ctx->blocksize / 4;
+
+ readsl(&device_data->base->dout, ctx->outdata, count);
+ ctx->outdata += count;
+ ctx->outlen -= count;
if (ctx->outlen == 0) {
cryp_disable_irq_src(device_data,
@@ -230,12 +229,12 @@ static irqreturn_t cryp_interrupt_handler(int irq, void *param)
} else if (cryp_pending_irq_src(device_data,
CRYP_IRQ_SRC_INPUT_FIFO)) {
if (ctx->datalen / ctx->blocksize > 0) {
- for (i = 0 ; i < ctx->blocksize / 4; i++) {
- writel_relaxed(ctx->indata,
- &device_data->base->din);
- ctx->indata += 4;
- ctx->datalen -= 4;
- }
+ count = ctx->blocksize / 4;
+
+ writesl(&device_data->base->din, ctx->indata, count);
+
+ ctx->indata += count;
+ ctx->datalen -= count;
if (ctx->datalen == 0)
cryp_disable_irq_src(device_data,
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 49e74c1fc639..3dced0a9eae3 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers"
config ARM_EXYNOS4_BUS_DEVFREQ
bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
- select ARCH_HAS_OPP
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select PM_OPP
help
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
new file mode 100644
index 000000000000..57a675f90cd0
--- /dev/null
+++ b/drivers/dma-buf/Makefile
@@ -0,0 +1 @@
+obj-y := dma-buf.o fence.o reservation.o seqno-fence.o
diff --git a/drivers/base/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 840c7fa80983..f3014c448e1e 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -25,10 +25,13 @@
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/dma-buf.h>
+#include <linux/fence.h>
#include <linux/anon_inodes.h>
#include <linux/export.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/poll.h>
+#include <linux/reservation.h>
static inline int is_dma_buf_file(struct file *);
@@ -50,12 +53,25 @@ static int dma_buf_release(struct inode *inode, struct file *file)
BUG_ON(dmabuf->vmapping_counter);
+ /*
+ * Any fences that a dma-buf poll can wait on should be signaled
+ * before releasing dma-buf. This is the responsibility of each
+ * driver that uses the reservation objects.
+ *
+ * If you hit this BUG() it means someone dropped their ref to the
+ * dma-buf while still having pending operation to the buffer.
+ */
+ BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
+
dmabuf->ops->release(dmabuf);
mutex_lock(&db_list.lock);
list_del(&dmabuf->list_node);
mutex_unlock(&db_list.lock);
+ if (dmabuf->resv == (struct reservation_object *)&dmabuf[1])
+ reservation_object_fini(dmabuf->resv);
+
kfree(dmabuf);
return 0;
}
@@ -103,10 +119,141 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence)
return base + offset;
}
+static void dma_buf_poll_cb(struct fence *fence, struct fence_cb *cb)
+{
+ struct dma_buf_poll_cb_t *dcb = (struct dma_buf_poll_cb_t *)cb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dcb->poll->lock, flags);
+ wake_up_locked_poll(dcb->poll, dcb->active);
+ dcb->active = 0;
+ spin_unlock_irqrestore(&dcb->poll->lock, flags);
+}
+
+static unsigned int dma_buf_poll(struct file *file, poll_table *poll)
+{
+ struct dma_buf *dmabuf;
+ struct reservation_object *resv;
+ struct reservation_object_list *fobj;
+ struct fence *fence_excl;
+ unsigned long events;
+ unsigned shared_count, seq;
+
+ dmabuf = file->private_data;
+ if (!dmabuf || !dmabuf->resv)
+ return POLLERR;
+
+ resv = dmabuf->resv;
+
+ poll_wait(file, &dmabuf->poll, poll);
+
+ events = poll_requested_events(poll) & (POLLIN | POLLOUT);
+ if (!events)
+ return 0;
+
+retry:
+ seq = read_seqcount_begin(&resv->seq);
+ rcu_read_lock();
+
+ fobj = rcu_dereference(resv->fence);
+ if (fobj)
+ shared_count = fobj->shared_count;
+ else
+ shared_count = 0;
+ fence_excl = rcu_dereference(resv->fence_excl);
+ if (read_seqcount_retry(&resv->seq, seq)) {
+ rcu_read_unlock();
+ goto retry;
+ }
+
+ if (fence_excl && (!(events & POLLOUT) || shared_count == 0)) {
+ struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
+ unsigned long pevents = POLLIN;
+
+ if (shared_count == 0)
+ pevents |= POLLOUT;
+
+ spin_lock_irq(&dmabuf->poll.lock);
+ if (dcb->active) {
+ dcb->active |= pevents;
+ events &= ~pevents;
+ } else
+ dcb->active = pevents;
+ spin_unlock_irq(&dmabuf->poll.lock);
+
+ if (events & pevents) {
+ if (!fence_get_rcu(fence_excl)) {
+ /* force a recheck */
+ events &= ~pevents;
+ dma_buf_poll_cb(NULL, &dcb->cb);
+ } else if (!fence_add_callback(fence_excl, &dcb->cb,
+ dma_buf_poll_cb)) {
+ events &= ~pevents;
+ fence_put(fence_excl);
+ } else {
+ /*
+ * No callback queued, wake up any additional
+ * waiters.
+ */
+ fence_put(fence_excl);
+ dma_buf_poll_cb(NULL, &dcb->cb);
+ }
+ }
+ }
+
+ if ((events & POLLOUT) && shared_count > 0) {
+ struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_shared;
+ int i;
+
+ /* Only queue a new callback if no event has fired yet */
+ spin_lock_irq(&dmabuf->poll.lock);
+ if (dcb->active)
+ events &= ~POLLOUT;
+ else
+ dcb->active = POLLOUT;
+ spin_unlock_irq(&dmabuf->poll.lock);
+
+ if (!(events & POLLOUT))
+ goto out;
+
+ for (i = 0; i < shared_count; ++i) {
+ struct fence *fence = rcu_dereference(fobj->shared[i]);
+
+ if (!fence_get_rcu(fence)) {
+ /*
+ * fence refcount dropped to zero, this means
+ * that fobj has been freed
+ *
+ * call dma_buf_poll_cb and force a recheck!
+ */
+ events &= ~POLLOUT;
+ dma_buf_poll_cb(NULL, &dcb->cb);
+ break;
+ }
+ if (!fence_add_callback(fence, &dcb->cb,
+ dma_buf_poll_cb)) {
+ fence_put(fence);
+ events &= ~POLLOUT;
+ break;
+ }
+ fence_put(fence);
+ }
+
+ /* No callback queued, wake up any additional waiters. */
+ if (i == shared_count)
+ dma_buf_poll_cb(NULL, &dcb->cb);
+ }
+
+out:
+ rcu_read_unlock();
+ return events;
+}
+
static const struct file_operations dma_buf_fops = {
.release = dma_buf_release,
.mmap = dma_buf_mmap_internal,
.llseek = dma_buf_llseek,
+ .poll = dma_buf_poll,
};
/*
@@ -128,6 +275,7 @@ static inline int is_dma_buf_file(struct file *file)
* @size: [in] Size of the buffer
* @flags: [in] mode flags for the file.
* @exp_name: [in] name of the exporting module - useful for debugging.
+ * @resv: [in] reservation-object, NULL to allocate default one.
*
* Returns, on success, a newly created dma_buf object, which wraps the
* supplied private data and operations for dma_buf_ops. On either missing
@@ -135,10 +283,17 @@ static inline int is_dma_buf_file(struct file *file)
*
*/
struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
- size_t size, int flags, const char *exp_name)
+ size_t size, int flags, const char *exp_name,
+ struct reservation_object *resv)
{
struct dma_buf *dmabuf;
struct file *file;
+ size_t alloc_size = sizeof(struct dma_buf);
+ if (!resv)
+ alloc_size += sizeof(struct reservation_object);
+ else
+ /* prevent &dma_buf[1] == dma_buf->resv */
+ alloc_size += 1;
if (WARN_ON(!priv || !ops
|| !ops->map_dma_buf
@@ -150,7 +305,7 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
return ERR_PTR(-EINVAL);
}
- dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
+ dmabuf = kzalloc(alloc_size, GFP_KERNEL);
if (dmabuf == NULL)
return ERR_PTR(-ENOMEM);
@@ -158,6 +313,15 @@ struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops,
dmabuf->ops = ops;
dmabuf->size = size;
dmabuf->exp_name = exp_name;
+ init_waitqueue_head(&dmabuf->poll);
+ dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
+ dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
+
+ if (!resv) {
+ resv = (struct reservation_object *)&dmabuf[1];
+ reservation_object_init(resv);
+ }
+ dmabuf->resv = resv;
file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags);
if (IS_ERR(file)) {
diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
new file mode 100644
index 000000000000..4222cb2aa96a
--- /dev/null
+++ b/drivers/dma-buf/fence.c
@@ -0,0 +1,431 @@
+/*
+ * Fence mechanism for dma-buf and to allow for asynchronous dma access
+ *
+ * Copyright (C) 2012 Canonical Ltd
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * Authors:
+ * Rob Clark <robdclark@gmail.com>
+ * Maarten Lankhorst <maarten.lankhorst@canonical.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/slab.h>
+#include <linux/export.h>
+#include <linux/atomic.h>
+#include <linux/fence.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/fence.h>
+
+EXPORT_TRACEPOINT_SYMBOL(fence_annotate_wait_on);
+EXPORT_TRACEPOINT_SYMBOL(fence_emit);
+
+/**
+ * fence context counter: each execution context should have its own
+ * fence context, this allows checking if fences belong to the same
+ * context or not. One device can have multiple separate contexts,
+ * and they're used if some engine can run independently of another.
+ */
+static atomic_t fence_context_counter = ATOMIC_INIT(0);
+
+/**
+ * fence_context_alloc - allocate an array of fence contexts
+ * @num: [in] amount of contexts to allocate
+ *
+ * This function will return the first index of the number of fences allocated.
+ * The fence context is used for setting fence->context to a unique number.
+ */
+unsigned fence_context_alloc(unsigned num)
+{
+ BUG_ON(!num);
+ return atomic_add_return(num, &fence_context_counter) - num;
+}
+EXPORT_SYMBOL(fence_context_alloc);
+
+/**
+ * fence_signal_locked - signal completion of a fence
+ * @fence: the fence to signal
+ *
+ * Signal completion for software callbacks on a fence, this will unblock
+ * fence_wait() calls and run all the callbacks added with
+ * fence_add_callback(). Can be called multiple times, but since a fence
+ * can only go from unsignaled to signaled state, it will only be effective
+ * the first time.
+ *
+ * Unlike fence_signal, this function must be called with fence->lock held.
+ */
+int fence_signal_locked(struct fence *fence)
+{
+ struct fence_cb *cur, *tmp;
+ int ret = 0;
+
+ if (WARN_ON(!fence))
+ return -EINVAL;
+
+ if (!ktime_to_ns(fence->timestamp)) {
+ fence->timestamp = ktime_get();
+ smp_mb__before_atomic();
+ }
+
+ if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ ret = -EINVAL;
+
+ /*
+ * we might have raced with the unlocked fence_signal,
+ * still run through all callbacks
+ */
+ } else
+ trace_fence_signaled(fence);
+
+ list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
+ list_del_init(&cur->node);
+ cur->func(fence, cur);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(fence_signal_locked);
+
+/**
+ * fence_signal - signal completion of a fence
+ * @fence: the fence to signal
+ *
+ * Signal completion for software callbacks on a fence, this will unblock
+ * fence_wait() calls and run all the callbacks added with
+ * fence_add_callback(). Can be called multiple times, but since a fence
+ * can only go from unsignaled to signaled state, it will only be effective
+ * the first time.
+ */
+int fence_signal(struct fence *fence)
+{
+ unsigned long flags;
+
+ if (!fence)
+ return -EINVAL;
+
+ if (!ktime_to_ns(fence->timestamp)) {
+ fence->timestamp = ktime_get();
+ smp_mb__before_atomic();
+ }
+
+ if (test_and_set_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+ return -EINVAL;
+
+ trace_fence_signaled(fence);
+
+ if (test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
+ struct fence_cb *cur, *tmp;
+
+ spin_lock_irqsave(fence->lock, flags);
+ list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
+ list_del_init(&cur->node);
+ cur->func(fence, cur);
+ }
+ spin_unlock_irqrestore(fence->lock, flags);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(fence_signal);
+
+/**
+ * fence_wait_timeout - sleep until the fence gets signaled
+ * or until timeout elapses
+ * @fence: [in] the fence to wait on
+ * @intr: [in] if true, do an interruptible wait
+ * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
+ *
+ * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
+ * remaining timeout in jiffies on success. Other error values may be
+ * returned on custom implementations.
+ *
+ * Performs a synchronous wait on this fence. It is assumed the caller
+ * directly or indirectly (buf-mgr between reservation and committing)
+ * holds a reference to the fence, otherwise the fence might be
+ * freed before return, resulting in undefined behavior.
+ */
+signed long
+fence_wait_timeout(struct fence *fence, bool intr, signed long timeout)
+{
+ signed long ret;
+
+ if (WARN_ON(timeout < 0))
+ return -EINVAL;
+
+ trace_fence_wait_start(fence);
+ ret = fence->ops->wait(fence, intr, timeout);
+ trace_fence_wait_end(fence);
+ return ret;
+}
+EXPORT_SYMBOL(fence_wait_timeout);
+
+void fence_release(struct kref *kref)
+{
+ struct fence *fence =
+ container_of(kref, struct fence, refcount);
+
+ trace_fence_destroy(fence);
+
+ BUG_ON(!list_empty(&fence->cb_list));
+
+ if (fence->ops->release)
+ fence->ops->release(fence);
+ else
+ fence_free(fence);
+}
+EXPORT_SYMBOL(fence_release);
+
+void fence_free(struct fence *fence)
+{
+ kfree_rcu(fence, rcu);
+}
+EXPORT_SYMBOL(fence_free);
+
+/**
+ * fence_enable_sw_signaling - enable signaling on fence
+ * @fence: [in] the fence to enable
+ *
+ * this will request for sw signaling to be enabled, to make the fence
+ * complete as soon as possible
+ */
+void fence_enable_sw_signaling(struct fence *fence)
+{
+ unsigned long flags;
+
+ if (!test_and_set_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags) &&
+ !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ trace_fence_enable_signal(fence);
+
+ spin_lock_irqsave(fence->lock, flags);
+
+ if (!fence->ops->enable_signaling(fence))
+ fence_signal_locked(fence);
+
+ spin_unlock_irqrestore(fence->lock, flags);
+ }
+}
+EXPORT_SYMBOL(fence_enable_sw_signaling);
+
+/**
+ * fence_add_callback - add a callback to be called when the fence
+ * is signaled
+ * @fence: [in] the fence to wait on
+ * @cb: [in] the callback to register
+ * @func: [in] the function to call
+ *
+ * cb will be initialized by fence_add_callback, no initialization
+ * by the caller is required. Any number of callbacks can be registered
+ * to a fence, but a callback can only be registered to one fence at a time.
+ *
+ * Note that the callback can be called from an atomic context. If
+ * fence is already signaled, this function will return -ENOENT (and
+ * *not* call the callback)
+ *
+ * Add a software callback to the fence. Same restrictions apply to
+ * refcount as it does to fence_wait, however the caller doesn't need to
+ * keep a refcount to fence afterwards: when software access is enabled,
+ * the creator of the fence is required to keep the fence alive until
+ * after it signals with fence_signal. The callback itself can be called
+ * from irq context.
+ *
+ */
+int fence_add_callback(struct fence *fence, struct fence_cb *cb,
+ fence_func_t func)
+{
+ unsigned long flags;
+ int ret = 0;
+ bool was_set;
+
+ if (WARN_ON(!fence || !func))
+ return -EINVAL;
+
+ if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ INIT_LIST_HEAD(&cb->node);
+ return -ENOENT;
+ }
+
+ spin_lock_irqsave(fence->lock, flags);
+
+ was_set = test_and_set_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags);
+
+ if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+ ret = -ENOENT;
+ else if (!was_set) {
+ trace_fence_enable_signal(fence);
+
+ if (!fence->ops->enable_signaling(fence)) {
+ fence_signal_locked(fence);
+ ret = -ENOENT;
+ }
+ }
+
+ if (!ret) {
+ cb->func = func;
+ list_add_tail(&cb->node, &fence->cb_list);
+ } else
+ INIT_LIST_HEAD(&cb->node);
+ spin_unlock_irqrestore(fence->lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(fence_add_callback);
+
+/**
+ * fence_remove_callback - remove a callback from the signaling list
+ * @fence: [in] the fence to wait on
+ * @cb: [in] the callback to remove
+ *
+ * Remove a previously queued callback from the fence. This function returns
+ * true if the callback is succesfully removed, or false if the fence has
+ * already been signaled.
+ *
+ * *WARNING*:
+ * Cancelling a callback should only be done if you really know what you're
+ * doing, since deadlocks and race conditions could occur all too easily. For
+ * this reason, it should only ever be done on hardware lockup recovery,
+ * with a reference held to the fence.
+ */
+bool
+fence_remove_callback(struct fence *fence, struct fence_cb *cb)
+{
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(fence->lock, flags);
+
+ ret = !list_empty(&cb->node);
+ if (ret)
+ list_del_init(&cb->node);
+
+ spin_unlock_irqrestore(fence->lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(fence_remove_callback);
+
+struct default_wait_cb {
+ struct fence_cb base;
+ struct task_struct *task;
+};
+
+static void
+fence_default_wait_cb(struct fence *fence, struct fence_cb *cb)
+{
+ struct default_wait_cb *wait =
+ container_of(cb, struct default_wait_cb, base);
+
+ wake_up_state(wait->task, TASK_NORMAL);
+}
+
+/**
+ * fence_default_wait - default sleep until the fence gets signaled
+ * or until timeout elapses
+ * @fence: [in] the fence to wait on
+ * @intr: [in] if true, do an interruptible wait
+ * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
+ *
+ * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
+ * remaining timeout in jiffies on success.
+ */
+signed long
+fence_default_wait(struct fence *fence, bool intr, signed long timeout)
+{
+ struct default_wait_cb cb;
+ unsigned long flags;
+ signed long ret = timeout;
+ bool was_set;
+
+ if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+ return timeout;
+
+ spin_lock_irqsave(fence->lock, flags);
+
+ if (intr && signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+
+ was_set = test_and_set_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags);
+
+ if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
+ goto out;
+
+ if (!was_set) {
+ trace_fence_enable_signal(fence);
+
+ if (!fence->ops->enable_signaling(fence)) {
+ fence_signal_locked(fence);
+ goto out;
+ }
+ }
+
+ cb.base.func = fence_default_wait_cb;
+ cb.task = current;
+ list_add(&cb.base.node, &fence->cb_list);
+
+ while (!test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags) && ret > 0) {
+ if (intr)
+ __set_current_state(TASK_INTERRUPTIBLE);
+ else
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ spin_unlock_irqrestore(fence->lock, flags);
+
+ ret = schedule_timeout(ret);
+
+ spin_lock_irqsave(fence->lock, flags);
+ if (ret > 0 && intr && signal_pending(current))
+ ret = -ERESTARTSYS;
+ }
+
+ if (!list_empty(&cb.base.node))
+ list_del(&cb.base.node);
+ __set_current_state(TASK_RUNNING);
+
+out:
+ spin_unlock_irqrestore(fence->lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(fence_default_wait);
+
+/**
+ * fence_init - Initialize a custom fence.
+ * @fence: [in] the fence to initialize
+ * @ops: [in] the fence_ops for operations on this fence
+ * @lock: [in] the irqsafe spinlock to use for locking this fence
+ * @context: [in] the execution context this fence is run on
+ * @seqno: [in] a linear increasing sequence number for this context
+ *
+ * Initializes an allocated fence, the caller doesn't have to keep its
+ * refcount after committing with this fence, but it will need to hold a
+ * refcount again if fence_ops.enable_signaling gets called. This can
+ * be used for other implementing other types of fence.
+ *
+ * context and seqno are used for easy comparison between fences, allowing
+ * to check which fence is later by simply using fence_later.
+ */
+void
+fence_init(struct fence *fence, const struct fence_ops *ops,
+ spinlock_t *lock, unsigned context, unsigned seqno)
+{
+ BUG_ON(!lock);
+ BUG_ON(!ops || !ops->wait || !ops->enable_signaling ||
+ !ops->get_driver_name || !ops->get_timeline_name);
+
+ kref_init(&fence->refcount);
+ fence->ops = ops;
+ INIT_LIST_HEAD(&fence->cb_list);
+ fence->lock = lock;
+ fence->context = context;
+ fence->seqno = seqno;
+ fence->flags = 0UL;
+
+ trace_fence_init(fence);
+}
+EXPORT_SYMBOL(fence_init);
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
new file mode 100644
index 000000000000..3c97c8fa8d02
--- /dev/null
+++ b/drivers/dma-buf/reservation.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2012-2014 Canonical Ltd (Maarten Lankhorst)
+ *
+ * Based on bo.c which bears the following copyright notice,
+ * but is dual licensed:
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <linux/reservation.h>
+#include <linux/export.h>
+
+DEFINE_WW_CLASS(reservation_ww_class);
+EXPORT_SYMBOL(reservation_ww_class);
+
+struct lock_class_key reservation_seqcount_class;
+EXPORT_SYMBOL(reservation_seqcount_class);
+
+const char reservation_seqcount_string[] = "reservation_seqcount";
+EXPORT_SYMBOL(reservation_seqcount_string);
+/*
+ * Reserve space to add a shared fence to a reservation_object,
+ * must be called with obj->lock held.
+ */
+int reservation_object_reserve_shared(struct reservation_object *obj)
+{
+ struct reservation_object_list *fobj, *old;
+ u32 max;
+
+ old = reservation_object_get_list(obj);
+
+ if (old && old->shared_max) {
+ if (old->shared_count < old->shared_max) {
+ /* perform an in-place update */
+ kfree(obj->staged);
+ obj->staged = NULL;
+ return 0;
+ } else
+ max = old->shared_max * 2;
+ } else
+ max = 4;
+
+ /*
+ * resize obj->staged or allocate if it doesn't exist,
+ * noop if already correct size
+ */
+ fobj = krealloc(obj->staged, offsetof(typeof(*fobj), shared[max]),
+ GFP_KERNEL);
+ if (!fobj)
+ return -ENOMEM;
+
+ obj->staged = fobj;
+ fobj->shared_max = max;
+ return 0;
+}
+EXPORT_SYMBOL(reservation_object_reserve_shared);
+
+static void
+reservation_object_add_shared_inplace(struct reservation_object *obj,
+ struct reservation_object_list *fobj,
+ struct fence *fence)
+{
+ u32 i;
+
+ fence_get(fence);
+
+ preempt_disable();
+ write_seqcount_begin(&obj->seq);
+
+ for (i = 0; i < fobj->shared_count; ++i) {
+ struct fence *old_fence;
+
+ old_fence = rcu_dereference_protected(fobj->shared[i],
+ reservation_object_held(obj));
+
+ if (old_fence->context == fence->context) {
+ /* memory barrier is added by write_seqcount_begin */
+ RCU_INIT_POINTER(fobj->shared[i], fence);
+ write_seqcount_end(&obj->seq);
+ preempt_enable();
+
+ fence_put(old_fence);
+ return;
+ }
+ }
+
+ /*
+ * memory barrier is added by write_seqcount_begin,
+ * fobj->shared_count is protected by this lock too
+ */
+ RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
+ fobj->shared_count++;
+
+ write_seqcount_end(&obj->seq);
+ preempt_enable();
+}
+
+static void
+reservation_object_add_shared_replace(struct reservation_object *obj,
+ struct reservation_object_list *old,
+ struct reservation_object_list *fobj,
+ struct fence *fence)
+{
+ unsigned i;
+ struct fence *old_fence = NULL;
+
+ fence_get(fence);
+
+ if (!old) {
+ RCU_INIT_POINTER(fobj->shared[0], fence);
+ fobj->shared_count = 1;
+ goto done;
+ }
+
+ /*
+ * no need to bump fence refcounts, rcu_read access
+ * requires the use of kref_get_unless_zero, and the
+ * references from the old struct are carried over to
+ * the new.
+ */
+ fobj->shared_count = old->shared_count;
+
+ for (i = 0; i < old->shared_count; ++i) {
+ struct fence *check;
+
+ check = rcu_dereference_protected(old->shared[i],
+ reservation_object_held(obj));
+
+ if (!old_fence && check->context == fence->context) {
+ old_fence = check;
+ RCU_INIT_POINTER(fobj->shared[i], fence);
+ } else
+ RCU_INIT_POINTER(fobj->shared[i], check);
+ }
+ if (!old_fence) {
+ RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence);
+ fobj->shared_count++;
+ }
+
+done:
+ preempt_disable();
+ write_seqcount_begin(&obj->seq);
+ /*
+ * RCU_INIT_POINTER can be used here,
+ * seqcount provides the necessary barriers
+ */
+ RCU_INIT_POINTER(obj->fence, fobj);
+ write_seqcount_end(&obj->seq);
+ preempt_enable();
+
+ if (old)
+ kfree_rcu(old, rcu);
+
+ if (old_fence)
+ fence_put(old_fence);
+}
+
+/*
+ * Add a fence to a shared slot, obj->lock must be held, and
+ * reservation_object_reserve_shared_fence has been called.
+ */
+void reservation_object_add_shared_fence(struct reservation_object *obj,
+ struct fence *fence)
+{
+ struct reservation_object_list *old, *fobj = obj->staged;
+
+ old = reservation_object_get_list(obj);
+ obj->staged = NULL;
+
+ if (!fobj) {
+ BUG_ON(old->shared_count >= old->shared_max);
+ reservation_object_add_shared_inplace(obj, old, fence);
+ } else
+ reservation_object_add_shared_replace(obj, old, fobj, fence);
+}
+EXPORT_SYMBOL(reservation_object_add_shared_fence);
+
+void reservation_object_add_excl_fence(struct reservation_object *obj,
+ struct fence *fence)
+{
+ struct fence *old_fence = reservation_object_get_excl(obj);
+ struct reservation_object_list *old;
+ u32 i = 0;
+
+ old = reservation_object_get_list(obj);
+ if (old)
+ i = old->shared_count;
+
+ if (fence)
+ fence_get(fence);
+
+ preempt_disable();
+ write_seqcount_begin(&obj->seq);
+ /* write_seqcount_begin provides the necessary memory barrier */
+ RCU_INIT_POINTER(obj->fence_excl, fence);
+ if (old)
+ old->shared_count = 0;
+ write_seqcount_end(&obj->seq);
+ preempt_enable();
+
+ /* inplace update, no shared fences */
+ while (i--)
+ fence_put(rcu_dereference_protected(old->shared[i],
+ reservation_object_held(obj)));
+
+ if (old_fence)
+ fence_put(old_fence);
+}
+EXPORT_SYMBOL(reservation_object_add_excl_fence);
+
+int reservation_object_get_fences_rcu(struct reservation_object *obj,
+ struct fence **pfence_excl,
+ unsigned *pshared_count,
+ struct fence ***pshared)
+{
+ unsigned shared_count = 0;
+ unsigned retry = 1;
+ struct fence **shared = NULL, *fence_excl = NULL;
+ int ret = 0;
+
+ while (retry) {
+ struct reservation_object_list *fobj;
+ unsigned seq;
+
+ seq = read_seqcount_begin(&obj->seq);
+
+ rcu_read_lock();
+
+ fobj = rcu_dereference(obj->fence);
+ if (fobj) {
+ struct fence **nshared;
+ size_t sz = sizeof(*shared) * fobj->shared_max;
+
+ nshared = krealloc(shared, sz,
+ GFP_NOWAIT | __GFP_NOWARN);
+ if (!nshared) {
+ rcu_read_unlock();
+ nshared = krealloc(shared, sz, GFP_KERNEL);
+ if (nshared) {
+ shared = nshared;
+ continue;
+ }
+
+ ret = -ENOMEM;
+ shared_count = 0;
+ break;
+ }
+ shared = nshared;
+ memcpy(shared, fobj->shared, sz);
+ shared_count = fobj->shared_count;
+ } else
+ shared_count = 0;
+ fence_excl = rcu_dereference(obj->fence_excl);
+
+ retry = read_seqcount_retry(&obj->seq, seq);
+ if (retry)
+ goto unlock;
+
+ if (!fence_excl || fence_get_rcu(fence_excl)) {
+ unsigned i;
+
+ for (i = 0; i < shared_count; ++i) {
+ if (fence_get_rcu(shared[i]))
+ continue;
+
+ /* uh oh, refcount failed, abort and retry */
+ while (i--)
+ fence_put(shared[i]);
+
+ if (fence_excl) {
+ fence_put(fence_excl);
+ fence_excl = NULL;
+ }
+
+ retry = 1;
+ break;
+ }
+ } else
+ retry = 1;
+
+unlock:
+ rcu_read_unlock();
+ }
+ *pshared_count = shared_count;
+ if (shared_count)
+ *pshared = shared;
+ else {
+ *pshared = NULL;
+ kfree(shared);
+ }
+ *pfence_excl = fence_excl;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reservation_object_get_fences_rcu);
+
+long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
+ bool wait_all, bool intr,
+ unsigned long timeout)
+{
+ struct fence *fence;
+ unsigned seq, shared_count, i = 0;
+ long ret = timeout;
+
+retry:
+ fence = NULL;
+ shared_count = 0;
+ seq = read_seqcount_begin(&obj->seq);
+ rcu_read_lock();
+
+ if (wait_all) {
+ struct reservation_object_list *fobj = rcu_dereference(obj->fence);
+
+ if (fobj)
+ shared_count = fobj->shared_count;
+
+ if (read_seqcount_retry(&obj->seq, seq))
+ goto unlock_retry;
+
+ for (i = 0; i < shared_count; ++i) {
+ struct fence *lfence = rcu_dereference(fobj->shared[i]);
+
+ if (test_bit(FENCE_FLAG_SIGNALED_BIT, &lfence->flags))
+ continue;
+
+ if (!fence_get_rcu(lfence))
+ goto unlock_retry;
+
+ if (fence_is_signaled(lfence)) {
+ fence_put(lfence);
+ continue;
+ }
+
+ fence = lfence;
+ break;
+ }
+ }
+
+ if (!shared_count) {
+ struct fence *fence_excl = rcu_dereference(obj->fence_excl);
+
+ if (read_seqcount_retry(&obj->seq, seq))
+ goto unlock_retry;
+
+ if (fence_excl &&
+ !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) {
+ if (!fence_get_rcu(fence_excl))
+ goto unlock_retry;
+
+ if (fence_is_signaled(fence_excl))
+ fence_put(fence_excl);
+ else
+ fence = fence_excl;
+ }
+ }
+
+ rcu_read_unlock();
+ if (fence) {
+ ret = fence_wait_timeout(fence, intr, ret);
+ fence_put(fence);
+ if (ret > 0 && wait_all && (i + 1 < shared_count))
+ goto retry;
+ }
+ return ret;
+
+unlock_retry:
+ rcu_read_unlock();
+ goto retry;
+}
+EXPORT_SYMBOL_GPL(reservation_object_wait_timeout_rcu);
+
+
+static inline int
+reservation_object_test_signaled_single(struct fence *passed_fence)
+{
+ struct fence *fence, *lfence = passed_fence;
+ int ret = 1;
+
+ if (!test_bit(FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) {
+ int ret;
+
+ fence = fence_get_rcu(lfence);
+ if (!fence)
+ return -1;
+
+ ret = !!fence_is_signaled(fence);
+ fence_put(fence);
+ }
+ return ret;
+}
+
+bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
+ bool test_all)
+{
+ unsigned seq, shared_count;
+ int ret = true;
+
+retry:
+ shared_count = 0;
+ seq = read_seqcount_begin(&obj->seq);
+ rcu_read_lock();
+
+ if (test_all) {
+ unsigned i;
+
+ struct reservation_object_list *fobj = rcu_dereference(obj->fence);
+
+ if (fobj)
+ shared_count = fobj->shared_count;
+
+ if (read_seqcount_retry(&obj->seq, seq))
+ goto unlock_retry;
+
+ for (i = 0; i < shared_count; ++i) {
+ struct fence *fence = rcu_dereference(fobj->shared[i]);
+
+ ret = reservation_object_test_signaled_single(fence);
+ if (ret < 0)
+ goto unlock_retry;
+ else if (!ret)
+ break;
+ }
+
+ /*
+ * There could be a read_seqcount_retry here, but nothing cares
+ * about whether it's the old or newer fence pointers that are
+ * signaled. That race could still have happened after checking
+ * read_seqcount_retry. If you care, use ww_mutex_lock.
+ */
+ }
+
+ if (!shared_count) {
+ struct fence *fence_excl = rcu_dereference(obj->fence_excl);
+
+ if (read_seqcount_retry(&obj->seq, seq))
+ goto unlock_retry;
+
+ if (fence_excl) {
+ ret = reservation_object_test_signaled_single(fence_excl);
+ if (ret < 0)
+ goto unlock_retry;
+ }
+ }
+
+ rcu_read_unlock();
+ return ret;
+
+unlock_retry:
+ rcu_read_unlock();
+ goto retry;
+}
+EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu);
diff --git a/drivers/dma-buf/seqno-fence.c b/drivers/dma-buf/seqno-fence.c
new file mode 100644
index 000000000000..7d12a39a4b57
--- /dev/null
+++ b/drivers/dma-buf/seqno-fence.c
@@ -0,0 +1,73 @@
+/*
+ * seqno-fence, using a dma-buf to synchronize fencing
+ *
+ * Copyright (C) 2012 Texas Instruments
+ * Copyright (C) 2012-2014 Canonical Ltd
+ * Authors:
+ * Rob Clark <robdclark@gmail.com>
+ * Maarten Lankhorst <maarten.lankhorst@canonical.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/slab.h>
+#include <linux/export.h>
+#include <linux/seqno-fence.h>
+
+static const char *seqno_fence_get_driver_name(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->get_driver_name(fence);
+}
+
+static const char *seqno_fence_get_timeline_name(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->get_timeline_name(fence);
+}
+
+static bool seqno_enable_signaling(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->enable_signaling(fence);
+}
+
+static bool seqno_signaled(struct fence *fence)
+{
+ struct seqno_fence *seqno_fence = to_seqno_fence(fence);
+ return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence);
+}
+
+static void seqno_release(struct fence *fence)
+{
+ struct seqno_fence *f = to_seqno_fence(fence);
+
+ dma_buf_put(f->sync_buf);
+ if (f->ops->release)
+ f->ops->release(fence);
+ else
+ fence_free(&f->base);
+}
+
+static signed long seqno_wait(struct fence *fence, bool intr, signed long timeout)
+{
+ struct seqno_fence *f = to_seqno_fence(fence);
+ return f->ops->wait(fence, intr, timeout);
+}
+
+const struct fence_ops seqno_fence_ops = {
+ .get_driver_name = seqno_fence_get_driver_name,
+ .get_timeline_name = seqno_fence_get_timeline_name,
+ .enable_signaling = seqno_enable_signaling,
+ .signaled = seqno_signaled,
+ .wait = seqno_wait,
+ .release = seqno_release,
+};
+EXPORT_SYMBOL(seqno_fence_ops);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 1eca7b9760e6..8f6afbf9ba54 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -33,6 +33,24 @@ if DMADEVICES
comment "DMA Devices"
+config INTEL_MIC_X100_DMA
+ tristate "Intel MIC X100 DMA Driver"
+ depends on 64BIT && X86 && INTEL_MIC_BUS
+ select DMA_ENGINE
+ help
+ This enables DMA support for the Intel Many Integrated Core
+ (MIC) family of PCIe form factor coprocessor X100 devices that
+ run a 64 bit Linux OS. This driver will be used by both MIC
+ host and card drivers.
+
+ If you are building host kernel with a MIC device or a card
+ kernel for a MIC device, then say M (recommended) or Y, else
+ say N. If unsure say N.
+
+ More information about the Intel MIC family as well as the Linux
+ OS and tools for MIC to use with this driver are available from
+ <http://software.intel.com/en-us/mic-developer>.
+
config INTEL_MID_DMAC
tristate "Intel MID DMA support for Peripheral DMA controllers"
depends on PCI && X86
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index c779e1eb2db2..bd9e7fa928bd 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
obj-$(CONFIG_QCOM_BAM_DMA) += qcom_bam_dma.o
obj-y += xilinx/
+obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c
index d028f36ae655..8f8b0b608875 100644
--- a/drivers/dma/cppi41.c
+++ b/drivers/dma/cppi41.c
@@ -86,6 +86,9 @@
#define USBSS_IRQ_PD_COMP (1 << 2)
+/* Packet Descriptor */
+#define PD2_ZERO_LENGTH (1 << 19)
+
struct cppi41_channel {
struct dma_chan chan;
struct dma_async_tx_descriptor txd;
@@ -307,7 +310,7 @@ static irqreturn_t cppi41_irq(int irq, void *data)
__iormb();
while (val) {
- u32 desc;
+ u32 desc, len;
q_num = __fls(val);
val &= ~(1 << q_num);
@@ -319,9 +322,13 @@ static irqreturn_t cppi41_irq(int irq, void *data)
q_num, desc);
continue;
}
- c->residue = pd_trans_len(c->desc->pd6) -
- pd_trans_len(c->desc->pd0);
+ if (c->desc->pd2 & PD2_ZERO_LENGTH)
+ len = 0;
+ else
+ len = pd_trans_len(c->desc->pd0);
+
+ c->residue = pd_trans_len(c->desc->pd6) - len;
dma_cookie_complete(&c->txd);
c->txd.callback(c->txd.callback_param);
}
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index d08c4dedef35..b512caf46944 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -982,6 +982,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
#define EDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+ BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
static int edma_dma_device_slave_caps(struct dma_chan *dchan,
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 128714622bf5..14867e3ac8ff 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -255,6 +255,7 @@ struct sdma_channel {
enum dma_slave_buswidth word_size;
unsigned int buf_tail;
unsigned int num_bd;
+ unsigned int period_len;
struct sdma_buffer_descriptor *bd;
dma_addr_t bd_phys;
unsigned int pc_from_device, pc_to_device;
@@ -593,6 +594,12 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
{
+ if (sdmac->desc.callback)
+ sdmac->desc.callback(sdmac->desc.callback_param);
+}
+
+static void sdma_update_channel_loop(struct sdma_channel *sdmac)
+{
struct sdma_buffer_descriptor *bd;
/*
@@ -611,9 +618,6 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
bd->mode.status |= BD_DONE;
sdmac->buf_tail++;
sdmac->buf_tail %= sdmac->num_bd;
-
- if (sdmac->desc.callback)
- sdmac->desc.callback(sdmac->desc.callback_param);
}
}
@@ -669,6 +673,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
int channel = fls(stat) - 1;
struct sdma_channel *sdmac = &sdma->channel[channel];
+ if (sdmac->flags & IMX_DMA_SG_LOOP)
+ sdma_update_channel_loop(sdmac);
+
tasklet_schedule(&sdmac->tasklet);
__clear_bit(channel, &stat);
@@ -1129,6 +1136,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
sdmac->status = DMA_IN_PROGRESS;
sdmac->buf_tail = 0;
+ sdmac->period_len = period_len;
sdmac->flags |= IMX_DMA_SG_LOOP;
sdmac->direction = direction;
@@ -1225,9 +1233,15 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
struct dma_tx_state *txstate)
{
struct sdma_channel *sdmac = to_sdma_chan(chan);
+ u32 residue;
+
+ if (sdmac->flags & IMX_DMA_SG_LOOP)
+ residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
+ else
+ residue = sdmac->chn_count - sdmac->chn_real_count;
dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,
- sdmac->chn_count - sdmac->chn_real_count);
+ residue);
return sdmac->status;
}
diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c
new file mode 100644
index 000000000000..6de2e677be04
--- /dev/null
+++ b/drivers/dma/mic_x100_dma.c
@@ -0,0 +1,774 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2014 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC X100 DMA Driver.
+ *
+ * Adapted from IOAT dma driver.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/seq_file.h>
+
+#include "mic_x100_dma.h"
+
+#define MIC_DMA_MAX_XFER_SIZE_CARD (1 * 1024 * 1024 -\
+ MIC_DMA_ALIGN_BYTES)
+#define MIC_DMA_MAX_XFER_SIZE_HOST (1 * 1024 * 1024 >> 1)
+#define MIC_DMA_DESC_TYPE_SHIFT 60
+#define MIC_DMA_MEMCPY_LEN_SHIFT 46
+#define MIC_DMA_STAT_INTR_SHIFT 59
+
+/* high-water mark for pushing dma descriptors */
+static int mic_dma_pending_level = 4;
+
+/* Status descriptor is used to write a 64 bit value to a memory location */
+enum mic_dma_desc_format_type {
+ MIC_DMA_MEMCPY = 1,
+ MIC_DMA_STATUS,
+};
+
+static inline u32 mic_dma_hw_ring_inc(u32 val)
+{
+ return (val + 1) % MIC_DMA_DESC_RX_SIZE;
+}
+
+static inline u32 mic_dma_hw_ring_dec(u32 val)
+{
+ return val ? val - 1 : MIC_DMA_DESC_RX_SIZE - 1;
+}
+
+static inline void mic_dma_hw_ring_inc_head(struct mic_dma_chan *ch)
+{
+ ch->head = mic_dma_hw_ring_inc(ch->head);
+}
+
+/* Prepare a memcpy desc */
+static inline void mic_dma_memcpy_desc(struct mic_dma_desc *desc,
+ dma_addr_t src_phys, dma_addr_t dst_phys, u64 size)
+{
+ u64 qw0, qw1;
+
+ qw0 = src_phys;
+ qw0 |= (size >> MIC_DMA_ALIGN_SHIFT) << MIC_DMA_MEMCPY_LEN_SHIFT;
+ qw1 = MIC_DMA_MEMCPY;
+ qw1 <<= MIC_DMA_DESC_TYPE_SHIFT;
+ qw1 |= dst_phys;
+ desc->qw0 = qw0;
+ desc->qw1 = qw1;
+}
+
+/* Prepare a status desc. with @data to be written at @dst_phys */
+static inline void mic_dma_prep_status_desc(struct mic_dma_desc *desc, u64 data,
+ dma_addr_t dst_phys, bool generate_intr)
+{
+ u64 qw0, qw1;
+
+ qw0 = data;
+ qw1 = (u64) MIC_DMA_STATUS << MIC_DMA_DESC_TYPE_SHIFT | dst_phys;
+ if (generate_intr)
+ qw1 |= (1ULL << MIC_DMA_STAT_INTR_SHIFT);
+ desc->qw0 = qw0;
+ desc->qw1 = qw1;
+}
+
+static void mic_dma_cleanup(struct mic_dma_chan *ch)
+{
+ struct dma_async_tx_descriptor *tx;
+ u32 tail;
+ u32 last_tail;
+
+ spin_lock(&ch->cleanup_lock);
+ tail = mic_dma_read_cmp_cnt(ch);
+ /*
+ * This is the barrier pair for smp_wmb() in fn.
+ * mic_dma_tx_submit_unlock. It's required so that we read the
+ * updated cookie value from tx->cookie.
+ */
+ smp_rmb();
+ for (last_tail = ch->last_tail; tail != last_tail;) {
+ tx = &ch->tx_array[last_tail];
+ if (tx->cookie) {
+ dma_cookie_complete(tx);
+ if (tx->callback) {
+ tx->callback(tx->callback_param);
+ tx->callback = NULL;
+ }
+ }
+ last_tail = mic_dma_hw_ring_inc(last_tail);
+ }
+ /* finish all completion callbacks before incrementing tail */
+ smp_mb();
+ ch->last_tail = last_tail;
+ spin_unlock(&ch->cleanup_lock);
+}
+
+static u32 mic_dma_ring_count(u32 head, u32 tail)
+{
+ u32 count;
+
+ if (head >= tail)
+ count = (tail - 0) + (MIC_DMA_DESC_RX_SIZE - head);
+ else
+ count = tail - head;
+ return count - 1;
+}
+
+/* Returns the num. of free descriptors on success, -ENOMEM on failure */
+static int mic_dma_avail_desc_ring_space(struct mic_dma_chan *ch, int required)
+{
+ struct device *dev = mic_dma_ch_to_device(ch);
+ u32 count;
+
+ count = mic_dma_ring_count(ch->head, ch->last_tail);
+ if (count < required) {
+ mic_dma_cleanup(ch);
+ count = mic_dma_ring_count(ch->head, ch->last_tail);
+ }
+
+ if (count < required) {
+ dev_dbg(dev, "Not enough desc space");
+ dev_dbg(dev, "%s %d required=%u, avail=%u\n",
+ __func__, __LINE__, required, count);
+ return -ENOMEM;
+ } else {
+ return count;
+ }
+}
+
+/* Program memcpy descriptors into the descriptor ring and update s/w head ptr*/
+static int mic_dma_prog_memcpy_desc(struct mic_dma_chan *ch, dma_addr_t src,
+ dma_addr_t dst, size_t len)
+{
+ size_t current_transfer_len;
+ size_t max_xfer_size = to_mic_dma_dev(ch)->max_xfer_size;
+ /* 3 is added to make sure we have enough space for status desc */
+ int num_desc = len / max_xfer_size + 3;
+ int ret;
+
+ if (len % max_xfer_size)
+ num_desc++;
+
+ ret = mic_dma_avail_desc_ring_space(ch, num_desc);
+ if (ret < 0)
+ return ret;
+ do {
+ current_transfer_len = min(len, max_xfer_size);
+ mic_dma_memcpy_desc(&ch->desc_ring[ch->head],
+ src, dst, current_transfer_len);
+ mic_dma_hw_ring_inc_head(ch);
+ len -= current_transfer_len;
+ dst = dst + current_transfer_len;
+ src = src + current_transfer_len;
+ } while (len > 0);
+ return 0;
+}
+
+/* It's a h/w quirk and h/w needs 2 status descriptors for every status desc */
+static void mic_dma_prog_intr(struct mic_dma_chan *ch)
+{
+ mic_dma_prep_status_desc(&ch->desc_ring[ch->head], 0,
+ ch->status_dest_micpa, false);
+ mic_dma_hw_ring_inc_head(ch);
+ mic_dma_prep_status_desc(&ch->desc_ring[ch->head], 0,
+ ch->status_dest_micpa, true);
+ mic_dma_hw_ring_inc_head(ch);
+}
+
+/* Wrapper function to program memcpy descriptors/status descriptors */
+static int mic_dma_do_dma(struct mic_dma_chan *ch, int flags, dma_addr_t src,
+ dma_addr_t dst, size_t len)
+{
+ if (-ENOMEM == mic_dma_prog_memcpy_desc(ch, src, dst, len))
+ return -ENOMEM;
+ /* Above mic_dma_prog_memcpy_desc() makes sure we have enough space */
+ if (flags & DMA_PREP_FENCE) {
+ mic_dma_prep_status_desc(&ch->desc_ring[ch->head], 0,
+ ch->status_dest_micpa, false);
+ mic_dma_hw_ring_inc_head(ch);
+ }
+
+ if (flags & DMA_PREP_INTERRUPT)
+ mic_dma_prog_intr(ch);
+
+ return 0;
+}
+
+static inline void mic_dma_issue_pending(struct dma_chan *ch)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
+
+ spin_lock(&mic_ch->issue_lock);
+ /*
+ * Write to head triggers h/w to act on the descriptors.
+ * On MIC, writing the same head value twice causes
+ * a h/w error. On second write, h/w assumes we filled
+ * the entire ring & overwrote some of the descriptors.
+ */
+ if (mic_ch->issued == mic_ch->submitted)
+ goto out;
+ mic_ch->issued = mic_ch->submitted;
+ /*
+ * make descriptor updates visible before advancing head,
+ * this is purposefully not smp_wmb() since we are also
+ * publishing the descriptor updates to a dma device
+ */
+ wmb();
+ mic_dma_write_reg(mic_ch, MIC_DMA_REG_DHPR, mic_ch->issued);
+out:
+ spin_unlock(&mic_ch->issue_lock);
+}
+
+static inline void mic_dma_update_pending(struct mic_dma_chan *ch)
+{
+ if (mic_dma_ring_count(ch->issued, ch->submitted)
+ > mic_dma_pending_level)
+ mic_dma_issue_pending(&ch->api_ch);
+}
+
+static dma_cookie_t mic_dma_tx_submit_unlock(struct dma_async_tx_descriptor *tx)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(tx->chan);
+ dma_cookie_t cookie;
+
+ dma_cookie_assign(tx);
+ cookie = tx->cookie;
+ /*
+ * We need an smp write barrier here because another CPU might see
+ * an update to submitted and update h/w head even before we
+ * assigned a cookie to this tx.
+ */
+ smp_wmb();
+ mic_ch->submitted = mic_ch->head;
+ spin_unlock(&mic_ch->prep_lock);
+ mic_dma_update_pending(mic_ch);
+ return cookie;
+}
+
+static inline struct dma_async_tx_descriptor *
+allocate_tx(struct mic_dma_chan *ch)
+{
+ u32 idx = mic_dma_hw_ring_dec(ch->head);
+ struct dma_async_tx_descriptor *tx = &ch->tx_array[idx];
+
+ dma_async_tx_descriptor_init(tx, &ch->api_ch);
+ tx->tx_submit = mic_dma_tx_submit_unlock;
+ return tx;
+}
+
+/*
+ * Prepare a memcpy descriptor to be added to the ring.
+ * Note that the temporary descriptor adds an extra overhead of copying the
+ * descriptor to ring. So, we copy directly to the descriptor ring
+ */
+static struct dma_async_tx_descriptor *
+mic_dma_prep_memcpy_lock(struct dma_chan *ch, dma_addr_t dma_dest,
+ dma_addr_t dma_src, size_t len, unsigned long flags)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
+ struct device *dev = mic_dma_ch_to_device(mic_ch);
+ int result;
+
+ if (!len && !flags)
+ return NULL;
+
+ spin_lock(&mic_ch->prep_lock);
+ result = mic_dma_do_dma(mic_ch, flags, dma_src, dma_dest, len);
+ if (result >= 0)
+ return allocate_tx(mic_ch);
+ dev_err(dev, "Error enqueueing dma, error=%d\n", result);
+ spin_unlock(&mic_ch->prep_lock);
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+mic_dma_prep_interrupt_lock(struct dma_chan *ch, unsigned long flags)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
+ int ret;
+
+ spin_lock(&mic_ch->prep_lock);
+ ret = mic_dma_do_dma(mic_ch, flags, 0, 0, 0);
+ if (!ret)
+ return allocate_tx(mic_ch);
+ spin_unlock(&mic_ch->prep_lock);
+ return NULL;
+}
+
+/* Return the status of the transaction */
+static enum dma_status
+mic_dma_tx_status(struct dma_chan *ch, dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
+
+ if (DMA_COMPLETE != dma_cookie_status(ch, cookie, txstate))
+ mic_dma_cleanup(mic_ch);
+
+ return dma_cookie_status(ch, cookie, txstate);
+}
+
+static irqreturn_t mic_dma_thread_fn(int irq, void *data)
+{
+ mic_dma_cleanup((struct mic_dma_chan *)data);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t mic_dma_intr_handler(int irq, void *data)
+{
+ struct mic_dma_chan *ch = ((struct mic_dma_chan *)data);
+
+ mic_dma_ack_interrupt(ch);
+ return IRQ_WAKE_THREAD;
+}
+
+static int mic_dma_alloc_desc_ring(struct mic_dma_chan *ch)
+{
+ u64 desc_ring_size = MIC_DMA_DESC_RX_SIZE * sizeof(*ch->desc_ring);
+ struct device *dev = &to_mbus_device(ch)->dev;
+
+ desc_ring_size = ALIGN(desc_ring_size, MIC_DMA_ALIGN_BYTES);
+ ch->desc_ring = kzalloc(desc_ring_size, GFP_KERNEL);
+
+ if (!ch->desc_ring)
+ return -ENOMEM;
+
+ ch->desc_ring_micpa = dma_map_single(dev, ch->desc_ring,
+ desc_ring_size, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, ch->desc_ring_micpa))
+ goto map_error;
+
+ ch->tx_array = vzalloc(MIC_DMA_DESC_RX_SIZE * sizeof(*ch->tx_array));
+ if (!ch->tx_array)
+ goto tx_error;
+ return 0;
+tx_error:
+ dma_unmap_single(dev, ch->desc_ring_micpa, desc_ring_size,
+ DMA_BIDIRECTIONAL);
+map_error:
+ kfree(ch->desc_ring);
+ return -ENOMEM;
+}
+
+static void mic_dma_free_desc_ring(struct mic_dma_chan *ch)
+{
+ u64 desc_ring_size = MIC_DMA_DESC_RX_SIZE * sizeof(*ch->desc_ring);
+
+ vfree(ch->tx_array);
+ desc_ring_size = ALIGN(desc_ring_size, MIC_DMA_ALIGN_BYTES);
+ dma_unmap_single(&to_mbus_device(ch)->dev, ch->desc_ring_micpa,
+ desc_ring_size, DMA_BIDIRECTIONAL);
+ kfree(ch->desc_ring);
+ ch->desc_ring = NULL;
+}
+
+static void mic_dma_free_status_dest(struct mic_dma_chan *ch)
+{
+ dma_unmap_single(&to_mbus_device(ch)->dev, ch->status_dest_micpa,
+ L1_CACHE_BYTES, DMA_BIDIRECTIONAL);
+ kfree(ch->status_dest);
+}
+
+static int mic_dma_alloc_status_dest(struct mic_dma_chan *ch)
+{
+ struct device *dev = &to_mbus_device(ch)->dev;
+
+ ch->status_dest = kzalloc(L1_CACHE_BYTES, GFP_KERNEL);
+ if (!ch->status_dest)
+ return -ENOMEM;
+ ch->status_dest_micpa = dma_map_single(dev, ch->status_dest,
+ L1_CACHE_BYTES, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, ch->status_dest_micpa)) {
+ kfree(ch->status_dest);
+ ch->status_dest = NULL;
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int mic_dma_check_chan(struct mic_dma_chan *ch)
+{
+ if (mic_dma_read_reg(ch, MIC_DMA_REG_DCHERR) ||
+ mic_dma_read_reg(ch, MIC_DMA_REG_DSTAT) & MIC_DMA_CHAN_QUIESCE) {
+ mic_dma_disable_chan(ch);
+ mic_dma_chan_mask_intr(ch);
+ dev_err(mic_dma_ch_to_device(ch),
+ "%s %d error setting up mic dma chan %d\n",
+ __func__, __LINE__, ch->ch_num);
+ return -EBUSY;
+ }
+ return 0;
+}
+
+static int mic_dma_chan_setup(struct mic_dma_chan *ch)
+{
+ if (MIC_DMA_CHAN_MIC == ch->owner)
+ mic_dma_chan_set_owner(ch);
+ mic_dma_disable_chan(ch);
+ mic_dma_chan_mask_intr(ch);
+ mic_dma_write_reg(ch, MIC_DMA_REG_DCHERRMSK, 0);
+ mic_dma_chan_set_desc_ring(ch);
+ ch->last_tail = mic_dma_read_reg(ch, MIC_DMA_REG_DTPR);
+ ch->head = ch->last_tail;
+ ch->issued = 0;
+ mic_dma_chan_unmask_intr(ch);
+ mic_dma_enable_chan(ch);
+ return mic_dma_check_chan(ch);
+}
+
+static void mic_dma_chan_destroy(struct mic_dma_chan *ch)
+{
+ mic_dma_disable_chan(ch);
+ mic_dma_chan_mask_intr(ch);
+}
+
+static void mic_dma_unregister_dma_device(struct mic_dma_device *mic_dma_dev)
+{
+ dma_async_device_unregister(&mic_dma_dev->dma_dev);
+}
+
+static int mic_dma_setup_irq(struct mic_dma_chan *ch)
+{
+ ch->cookie =
+ to_mbus_hw_ops(ch)->request_threaded_irq(to_mbus_device(ch),
+ mic_dma_intr_handler, mic_dma_thread_fn,
+ "mic dma_channel", ch, ch->ch_num);
+ if (IS_ERR(ch->cookie))
+ return IS_ERR(ch->cookie);
+ return 0;
+}
+
+static inline void mic_dma_free_irq(struct mic_dma_chan *ch)
+{
+ to_mbus_hw_ops(ch)->free_irq(to_mbus_device(ch), ch->cookie, ch);
+}
+
+static int mic_dma_chan_init(struct mic_dma_chan *ch)
+{
+ int ret = mic_dma_alloc_desc_ring(ch);
+
+ if (ret)
+ goto ring_error;
+ ret = mic_dma_alloc_status_dest(ch);
+ if (ret)
+ goto status_error;
+ ret = mic_dma_chan_setup(ch);
+ if (ret)
+ goto chan_error;
+ return ret;
+chan_error:
+ mic_dma_free_status_dest(ch);
+status_error:
+ mic_dma_free_desc_ring(ch);
+ring_error:
+ return ret;
+}
+
+static int mic_dma_drain_chan(struct mic_dma_chan *ch)
+{
+ struct dma_async_tx_descriptor *tx;
+ int err = 0;
+ dma_cookie_t cookie;
+
+ tx = mic_dma_prep_memcpy_lock(&ch->api_ch, 0, 0, 0, DMA_PREP_FENCE);
+ if (!tx) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ cookie = tx->tx_submit(tx);
+ if (dma_submit_error(cookie))
+ err = -ENOMEM;
+ else
+ err = dma_sync_wait(&ch->api_ch, cookie);
+ if (err) {
+ dev_err(mic_dma_ch_to_device(ch), "%s %d TO chan 0x%x\n",
+ __func__, __LINE__, ch->ch_num);
+ err = -EIO;
+ }
+error:
+ mic_dma_cleanup(ch);
+ return err;
+}
+
+static inline void mic_dma_chan_uninit(struct mic_dma_chan *ch)
+{
+ mic_dma_chan_destroy(ch);
+ mic_dma_cleanup(ch);
+ mic_dma_free_status_dest(ch);
+ mic_dma_free_desc_ring(ch);
+}
+
+static int mic_dma_init(struct mic_dma_device *mic_dma_dev,
+ enum mic_dma_chan_owner owner)
+{
+ int i, first_chan = mic_dma_dev->start_ch;
+ struct mic_dma_chan *ch;
+ int ret;
+
+ for (i = first_chan; i < first_chan + MIC_DMA_NUM_CHAN; i++) {
+ unsigned long data;
+ ch = &mic_dma_dev->mic_ch[i];
+ data = (unsigned long)ch;
+ ch->ch_num = i;
+ ch->owner = owner;
+ spin_lock_init(&ch->cleanup_lock);
+ spin_lock_init(&ch->prep_lock);
+ spin_lock_init(&ch->issue_lock);
+ ret = mic_dma_setup_irq(ch);
+ if (ret)
+ goto error;
+ }
+ return 0;
+error:
+ for (i = i - 1; i >= first_chan; i--)
+ mic_dma_free_irq(ch);
+ return ret;
+}
+
+static void mic_dma_uninit(struct mic_dma_device *mic_dma_dev)
+{
+ int i, first_chan = mic_dma_dev->start_ch;
+ struct mic_dma_chan *ch;
+
+ for (i = first_chan; i < first_chan + MIC_DMA_NUM_CHAN; i++) {
+ ch = &mic_dma_dev->mic_ch[i];
+ mic_dma_free_irq(ch);
+ }
+}
+
+static int mic_dma_alloc_chan_resources(struct dma_chan *ch)
+{
+ int ret = mic_dma_chan_init(to_mic_dma_chan(ch));
+ if (ret)
+ return ret;
+ return MIC_DMA_DESC_RX_SIZE;
+}
+
+static void mic_dma_free_chan_resources(struct dma_chan *ch)
+{
+ struct mic_dma_chan *mic_ch = to_mic_dma_chan(ch);
+ mic_dma_drain_chan(mic_ch);
+ mic_dma_chan_uninit(mic_ch);
+}
+
+/* Set the fn. handlers and register the dma device with dma api */
+static int mic_dma_register_dma_device(struct mic_dma_device *mic_dma_dev,
+ enum mic_dma_chan_owner owner)
+{
+ int i, first_chan = mic_dma_dev->start_ch;
+
+ dma_cap_zero(mic_dma_dev->dma_dev.cap_mask);
+ /*
+ * This dma engine is not capable of host memory to host memory
+ * transfers
+ */
+ dma_cap_set(DMA_MEMCPY, mic_dma_dev->dma_dev.cap_mask);
+
+ if (MIC_DMA_CHAN_HOST == owner)
+ dma_cap_set(DMA_PRIVATE, mic_dma_dev->dma_dev.cap_mask);
+ mic_dma_dev->dma_dev.device_alloc_chan_resources =
+ mic_dma_alloc_chan_resources;
+ mic_dma_dev->dma_dev.device_free_chan_resources =
+ mic_dma_free_chan_resources;
+ mic_dma_dev->dma_dev.device_tx_status = mic_dma_tx_status;
+ mic_dma_dev->dma_dev.device_prep_dma_memcpy = mic_dma_prep_memcpy_lock;
+ mic_dma_dev->dma_dev.device_prep_dma_interrupt =
+ mic_dma_prep_interrupt_lock;
+ mic_dma_dev->dma_dev.device_issue_pending = mic_dma_issue_pending;
+ mic_dma_dev->dma_dev.copy_align = MIC_DMA_ALIGN_SHIFT;
+ INIT_LIST_HEAD(&mic_dma_dev->dma_dev.channels);
+ for (i = first_chan; i < first_chan + MIC_DMA_NUM_CHAN; i++) {
+ mic_dma_dev->mic_ch[i].api_ch.device = &mic_dma_dev->dma_dev;
+ dma_cookie_init(&mic_dma_dev->mic_ch[i].api_ch);
+ list_add_tail(&mic_dma_dev->mic_ch[i].api_ch.device_node,
+ &mic_dma_dev->dma_dev.channels);
+ }
+ return dma_async_device_register(&mic_dma_dev->dma_dev);
+}
+
+/*
+ * Initializes dma channels and registers the dma device with the
+ * dma engine api.
+ */
+static struct mic_dma_device *mic_dma_dev_reg(struct mbus_device *mbdev,
+ enum mic_dma_chan_owner owner)
+{
+ struct mic_dma_device *mic_dma_dev;
+ int ret;
+ struct device *dev = &mbdev->dev;
+
+ mic_dma_dev = kzalloc(sizeof(*mic_dma_dev), GFP_KERNEL);
+ if (!mic_dma_dev) {
+ ret = -ENOMEM;
+ goto alloc_error;
+ }
+ mic_dma_dev->mbdev = mbdev;
+ mic_dma_dev->dma_dev.dev = dev;
+ mic_dma_dev->mmio = mbdev->mmio_va;
+ if (MIC_DMA_CHAN_HOST == owner) {
+ mic_dma_dev->start_ch = 0;
+ mic_dma_dev->max_xfer_size = MIC_DMA_MAX_XFER_SIZE_HOST;
+ } else {
+ mic_dma_dev->start_ch = 4;
+ mic_dma_dev->max_xfer_size = MIC_DMA_MAX_XFER_SIZE_CARD;
+ }
+ ret = mic_dma_init(mic_dma_dev, owner);
+ if (ret)
+ goto init_error;
+ ret = mic_dma_register_dma_device(mic_dma_dev, owner);
+ if (ret)
+ goto reg_error;
+ return mic_dma_dev;
+reg_error:
+ mic_dma_uninit(mic_dma_dev);
+init_error:
+ kfree(mic_dma_dev);
+ mic_dma_dev = NULL;
+alloc_error:
+ dev_err(dev, "Error at %s %d ret=%d\n", __func__, __LINE__, ret);
+ return mic_dma_dev;
+}
+
+static void mic_dma_dev_unreg(struct mic_dma_device *mic_dma_dev)
+{
+ mic_dma_unregister_dma_device(mic_dma_dev);
+ mic_dma_uninit(mic_dma_dev);
+ kfree(mic_dma_dev);
+}
+
+/* DEBUGFS CODE */
+static int mic_dma_reg_seq_show(struct seq_file *s, void *pos)
+{
+ struct mic_dma_device *mic_dma_dev = s->private;
+ int i, chan_num, first_chan = mic_dma_dev->start_ch;
+ struct mic_dma_chan *ch;
+
+ seq_printf(s, "SBOX_DCR: %#x\n",
+ mic_dma_mmio_read(&mic_dma_dev->mic_ch[first_chan],
+ MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR));
+ seq_puts(s, "DMA Channel Registers\n");
+ seq_printf(s, "%-10s| %-10s %-10s %-10s %-10s %-10s",
+ "Channel", "DCAR", "DTPR", "DHPR", "DRAR_HI", "DRAR_LO");
+ seq_printf(s, " %-11s %-14s %-10s\n", "DCHERR", "DCHERRMSK", "DSTAT");
+ for (i = first_chan; i < first_chan + MIC_DMA_NUM_CHAN; i++) {
+ ch = &mic_dma_dev->mic_ch[i];
+ chan_num = ch->ch_num;
+ seq_printf(s, "%-10i| %-#10x %-#10x %-#10x %-#10x",
+ chan_num,
+ mic_dma_read_reg(ch, MIC_DMA_REG_DCAR),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DTPR),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DHPR),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DRAR_HI));
+ seq_printf(s, " %-#10x %-#10x %-#14x %-#10x\n",
+ mic_dma_read_reg(ch, MIC_DMA_REG_DRAR_LO),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DCHERR),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DCHERRMSK),
+ mic_dma_read_reg(ch, MIC_DMA_REG_DSTAT));
+ }
+ return 0;
+}
+
+static int mic_dma_reg_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mic_dma_reg_seq_show, inode->i_private);
+}
+
+static int mic_dma_reg_debug_release(struct inode *inode, struct file *file)
+{
+ return single_release(inode, file);
+}
+
+static const struct file_operations mic_dma_reg_ops = {
+ .owner = THIS_MODULE,
+ .open = mic_dma_reg_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = mic_dma_reg_debug_release
+};
+
+/* Debugfs parent dir */
+static struct dentry *mic_dma_dbg;
+
+static int mic_dma_driver_probe(struct mbus_device *mbdev)
+{
+ struct mic_dma_device *mic_dma_dev;
+ enum mic_dma_chan_owner owner;
+
+ if (MBUS_DEV_DMA_MIC == mbdev->id.device)
+ owner = MIC_DMA_CHAN_MIC;
+ else
+ owner = MIC_DMA_CHAN_HOST;
+
+ mic_dma_dev = mic_dma_dev_reg(mbdev, owner);
+ dev_set_drvdata(&mbdev->dev, mic_dma_dev);
+
+ if (mic_dma_dbg) {
+ mic_dma_dev->dbg_dir = debugfs_create_dir(dev_name(&mbdev->dev),
+ mic_dma_dbg);
+ if (mic_dma_dev->dbg_dir)
+ debugfs_create_file("mic_dma_reg", 0444,
+ mic_dma_dev->dbg_dir, mic_dma_dev,
+ &mic_dma_reg_ops);
+ }
+ return 0;
+}
+
+static void mic_dma_driver_remove(struct mbus_device *mbdev)
+{
+ struct mic_dma_device *mic_dma_dev;
+
+ mic_dma_dev = dev_get_drvdata(&mbdev->dev);
+ debugfs_remove_recursive(mic_dma_dev->dbg_dir);
+ mic_dma_dev_unreg(mic_dma_dev);
+}
+
+static struct mbus_device_id id_table[] = {
+ {MBUS_DEV_DMA_MIC, MBUS_DEV_ANY_ID},
+ {MBUS_DEV_DMA_HOST, MBUS_DEV_ANY_ID},
+ {0},
+};
+
+static struct mbus_driver mic_dma_driver = {
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = mic_dma_driver_probe,
+ .remove = mic_dma_driver_remove,
+};
+
+static int __init mic_x100_dma_init(void)
+{
+ int rc = mbus_register_driver(&mic_dma_driver);
+ if (rc)
+ return rc;
+ mic_dma_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ return 0;
+}
+
+static void __exit mic_x100_dma_exit(void)
+{
+ debugfs_remove_recursive(mic_dma_dbg);
+ mbus_unregister_driver(&mic_dma_driver);
+}
+
+module_init(mic_x100_dma_init);
+module_exit(mic_x100_dma_exit);
+
+MODULE_DEVICE_TABLE(mbus, id_table);
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) MIC X100 DMA Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/mic_x100_dma.h b/drivers/dma/mic_x100_dma.h
new file mode 100644
index 000000000000..f663b0bdd11d
--- /dev/null
+++ b/drivers/dma/mic_x100_dma.h
@@ -0,0 +1,286 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2014 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC X100 DMA Driver.
+ *
+ * Adapted from IOAT dma driver.
+ */
+#ifndef _MIC_X100_DMA_H_
+#define _MIC_X100_DMA_H_
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/mic_bus.h>
+
+#include "dmaengine.h"
+
+/*
+ * MIC has a total of 8 dma channels.
+ * Four channels are assigned for host SW use & the remaining for MIC SW.
+ * MIC DMA transfer size & addresses need to be 64 byte aligned.
+ */
+#define MIC_DMA_MAX_NUM_CHAN 8
+#define MIC_DMA_NUM_CHAN 4
+#define MIC_DMA_ALIGN_SHIFT 6
+#define MIC_DMA_ALIGN_BYTES (1 << MIC_DMA_ALIGN_SHIFT)
+#define MIC_DMA_DESC_RX_SIZE (128 * 1024 - 4)
+
+/*
+ * Register descriptions
+ * All the registers are 32 bit registers.
+ * DCR is a global register and all others are per-channel.
+ * DCR - bits 0, 2, 4, 6, 8, 10, 12, 14 - enable bits for channels 0 to 7
+ * bits 1, 3, 5, 7, 9, 11, 13, 15 - owner bits for channels 0 to 7
+ * DCAR - bit 24 & 25 interrupt masks for mic owned & host owned channels
+ * DHPR - head of the descriptor ring updated by s/w
+ * DTPR - tail of the descriptor ring updated by h/w
+ * DRAR_LO - lower 32 bits of descriptor ring's mic address
+ * DRAR_HI - 3:0 - remaining 4 bits of descriptor ring's mic address
+ * 20:4 descriptor ring size
+ * 25:21 mic smpt entry number
+ * DSTAT - 16:0 h/w completion count; 31:28 dma engine status
+ * DCHERR - this register is non-zero on error
+ * DCHERRMSK - interrupt mask register
+ */
+#define MIC_DMA_HW_CMP_CNT_MASK 0x1ffff
+#define MIC_DMA_CHAN_QUIESCE 0x20000000
+#define MIC_DMA_SBOX_BASE 0x00010000
+#define MIC_DMA_SBOX_DCR 0x0000A280
+#define MIC_DMA_SBOX_CH_BASE 0x0001A000
+#define MIC_DMA_SBOX_CHAN_OFF 0x40
+#define MIC_DMA_SBOX_DCAR_IM0 (0x1 << 24)
+#define MIC_DMA_SBOX_DCAR_IM1 (0x1 << 25)
+#define MIC_DMA_SBOX_DRARHI_SYS_MASK (0x1 << 26)
+#define MIC_DMA_REG_DCAR 0
+#define MIC_DMA_REG_DHPR 4
+#define MIC_DMA_REG_DTPR 8
+#define MIC_DMA_REG_DRAR_LO 20
+#define MIC_DMA_REG_DRAR_HI 24
+#define MIC_DMA_REG_DSTAT 32
+#define MIC_DMA_REG_DCHERR 44
+#define MIC_DMA_REG_DCHERRMSK 48
+
+/* HW dma desc */
+struct mic_dma_desc {
+ u64 qw0;
+ u64 qw1;
+};
+
+enum mic_dma_chan_owner {
+ MIC_DMA_CHAN_MIC = 0,
+ MIC_DMA_CHAN_HOST
+};
+
+/*
+ * mic_dma_chan - channel specific information
+ * @ch_num: channel number
+ * @owner: owner of this channel
+ * @last_tail: cached value of descriptor ring tail
+ * @head: index of next descriptor in desc_ring
+ * @issued: hardware notification point
+ * @submitted: index that will be used to submit descriptors to h/w
+ * @api_ch: dma engine api channel
+ * @desc_ring: dma descriptor ring
+ * @desc_ring_micpa: mic physical address of desc_ring
+ * @status_dest: destination for status (fence) descriptor
+ * @status_dest_micpa: mic address for status_dest,
+ * DMA controller uses this address
+ * @tx_array: array of async_tx
+ * @cleanup_lock: lock held when processing completed tx
+ * @prep_lock: lock held in prep_memcpy & released in tx_submit
+ * @issue_lock: lock used to synchronize writes to head
+ * @cookie: mic_irq cookie used with mic irq request
+ */
+struct mic_dma_chan {
+ int ch_num;
+ enum mic_dma_chan_owner owner;
+ u32 last_tail;
+ u32 head;
+ u32 issued;
+ u32 submitted;
+ struct dma_chan api_ch;
+ struct mic_dma_desc *desc_ring;
+ dma_addr_t desc_ring_micpa;
+ u64 *status_dest;
+ dma_addr_t status_dest_micpa;
+ struct dma_async_tx_descriptor *tx_array;
+ spinlock_t cleanup_lock;
+ spinlock_t prep_lock;
+ spinlock_t issue_lock;
+ struct mic_irq *cookie;
+};
+
+/*
+ * struct mic_dma_device - per mic device
+ * @mic_ch: dma channels
+ * @dma_dev: underlying dma device
+ * @mbdev: mic bus dma device
+ * @mmio: virtual address of the mmio space
+ * @dbg_dir: debugfs directory
+ * @start_ch: first channel number that can be used
+ * @max_xfer_size: maximum transfer size per dma descriptor
+ */
+struct mic_dma_device {
+ struct mic_dma_chan mic_ch[MIC_DMA_MAX_NUM_CHAN];
+ struct dma_device dma_dev;
+ struct mbus_device *mbdev;
+ void __iomem *mmio;
+ struct dentry *dbg_dir;
+ int start_ch;
+ size_t max_xfer_size;
+};
+
+static inline struct mic_dma_chan *to_mic_dma_chan(struct dma_chan *ch)
+{
+ return container_of(ch, struct mic_dma_chan, api_ch);
+}
+
+static inline struct mic_dma_device *to_mic_dma_dev(struct mic_dma_chan *ch)
+{
+ return
+ container_of((const typeof(((struct mic_dma_device *)0)->mic_ch)*)
+ (ch - ch->ch_num), struct mic_dma_device, mic_ch);
+}
+
+static inline struct mbus_device *to_mbus_device(struct mic_dma_chan *ch)
+{
+ return to_mic_dma_dev(ch)->mbdev;
+}
+
+static inline struct mbus_hw_ops *to_mbus_hw_ops(struct mic_dma_chan *ch)
+{
+ return to_mbus_device(ch)->hw_ops;
+}
+
+static inline struct device *mic_dma_ch_to_device(struct mic_dma_chan *ch)
+{
+ return to_mic_dma_dev(ch)->dma_dev.dev;
+}
+
+static inline void __iomem *mic_dma_chan_to_mmio(struct mic_dma_chan *ch)
+{
+ return to_mic_dma_dev(ch)->mmio;
+}
+
+static inline u32 mic_dma_read_reg(struct mic_dma_chan *ch, u32 reg)
+{
+ return ioread32(mic_dma_chan_to_mmio(ch) + MIC_DMA_SBOX_CH_BASE +
+ ch->ch_num * MIC_DMA_SBOX_CHAN_OFF + reg);
+}
+
+static inline void mic_dma_write_reg(struct mic_dma_chan *ch, u32 reg, u32 val)
+{
+ iowrite32(val, mic_dma_chan_to_mmio(ch) + MIC_DMA_SBOX_CH_BASE +
+ ch->ch_num * MIC_DMA_SBOX_CHAN_OFF + reg);
+}
+
+static inline u32 mic_dma_mmio_read(struct mic_dma_chan *ch, u32 offset)
+{
+ return ioread32(mic_dma_chan_to_mmio(ch) + offset);
+}
+
+static inline void mic_dma_mmio_write(struct mic_dma_chan *ch, u32 val,
+ u32 offset)
+{
+ iowrite32(val, mic_dma_chan_to_mmio(ch) + offset);
+}
+
+static inline u32 mic_dma_read_cmp_cnt(struct mic_dma_chan *ch)
+{
+ return mic_dma_read_reg(ch, MIC_DMA_REG_DSTAT) &
+ MIC_DMA_HW_CMP_CNT_MASK;
+}
+
+static inline void mic_dma_chan_set_owner(struct mic_dma_chan *ch)
+{
+ u32 dcr = mic_dma_mmio_read(ch, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+ u32 chan_num = ch->ch_num;
+
+ dcr = (dcr & ~(0x1 << (chan_num * 2))) | (ch->owner << (chan_num * 2));
+ mic_dma_mmio_write(ch, dcr, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+}
+
+static inline void mic_dma_enable_chan(struct mic_dma_chan *ch)
+{
+ u32 dcr = mic_dma_mmio_read(ch, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+
+ dcr |= 2 << (ch->ch_num << 1);
+ mic_dma_mmio_write(ch, dcr, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+}
+
+static inline void mic_dma_disable_chan(struct mic_dma_chan *ch)
+{
+ u32 dcr = mic_dma_mmio_read(ch, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+
+ dcr &= ~(2 << (ch->ch_num << 1));
+ mic_dma_mmio_write(ch, dcr, MIC_DMA_SBOX_BASE + MIC_DMA_SBOX_DCR);
+}
+
+static void mic_dma_chan_set_desc_ring(struct mic_dma_chan *ch)
+{
+ u32 drar_hi;
+ dma_addr_t desc_ring_micpa = ch->desc_ring_micpa;
+
+ drar_hi = (MIC_DMA_DESC_RX_SIZE & 0x1ffff) << 4;
+ if (MIC_DMA_CHAN_MIC == ch->owner) {
+ drar_hi |= (desc_ring_micpa >> 32) & 0xf;
+ } else {
+ drar_hi |= MIC_DMA_SBOX_DRARHI_SYS_MASK;
+ drar_hi |= ((desc_ring_micpa >> 34)
+ & 0x1f) << 21;
+ drar_hi |= (desc_ring_micpa >> 32) & 0x3;
+ }
+ mic_dma_write_reg(ch, MIC_DMA_REG_DRAR_LO, (u32) desc_ring_micpa);
+ mic_dma_write_reg(ch, MIC_DMA_REG_DRAR_HI, drar_hi);
+}
+
+static inline void mic_dma_chan_mask_intr(struct mic_dma_chan *ch)
+{
+ u32 dcar = mic_dma_read_reg(ch, MIC_DMA_REG_DCAR);
+
+ if (MIC_DMA_CHAN_MIC == ch->owner)
+ dcar |= MIC_DMA_SBOX_DCAR_IM0;
+ else
+ dcar |= MIC_DMA_SBOX_DCAR_IM1;
+ mic_dma_write_reg(ch, MIC_DMA_REG_DCAR, dcar);
+}
+
+static inline void mic_dma_chan_unmask_intr(struct mic_dma_chan *ch)
+{
+ u32 dcar = mic_dma_read_reg(ch, MIC_DMA_REG_DCAR);
+
+ if (MIC_DMA_CHAN_MIC == ch->owner)
+ dcar &= ~MIC_DMA_SBOX_DCAR_IM0;
+ else
+ dcar &= ~MIC_DMA_SBOX_DCAR_IM1;
+ mic_dma_write_reg(ch, MIC_DMA_REG_DCAR, dcar);
+}
+
+static void mic_dma_ack_interrupt(struct mic_dma_chan *ch)
+{
+ if (MIC_DMA_CHAN_MIC == ch->owner) {
+ /* HW errata */
+ mic_dma_chan_mask_intr(ch);
+ mic_dma_chan_unmask_intr(ch);
+ }
+ to_mbus_hw_ops(ch)->ack_interrupt(to_mbus_device(ch), ch->ch_num);
+}
+#endif
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 878f09005fad..f8665f9c3e03 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -72,6 +72,7 @@ config EDAC_MCE_INJ
config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
+ select RAS
help
Some systems are able to detect and correct errors in main
memory. EDAC can report statistics on memory error
@@ -186,6 +187,13 @@ config EDAC_I3200
Support for error detection and correction on the Intel
3200 and 3210 server chipsets.
+config EDAC_IE31200
+ tristate "Intel e312xx"
+ depends on EDAC_MM_EDAC && PCI && X86
+ help
+ Support for error detection and correction on the Intel
+ E3-1200 based DRAM controllers.
+
config EDAC_X38
tristate "Intel X38"
depends on EDAC_MM_EDAC && PCI && X86
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 4154ed6a02c6..c479a24d8f77 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_EDAC_I82875P) += i82875p_edac.o
obj-$(CONFIG_EDAC_I82975X) += i82975x_edac.o
obj-$(CONFIG_EDAC_I3000) += i3000_edac.o
obj-$(CONFIG_EDAC_I3200) += i3200_edac.o
+obj-$(CONFIG_EDAC_IE31200) += ie31200_edac.o
obj-$(CONFIG_EDAC_X38) += x38_edac.o
obj-$(CONFIG_EDAC_I82860) += i82860_edac.o
obj-$(CONFIG_EDAC_R82600) += r82600_edac.o
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 2c694b5297cc..9f134823fa75 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -33,9 +33,6 @@
#include <asm/edac.h>
#include "edac_core.h"
#include "edac_module.h"
-
-#define CREATE_TRACE_POINTS
-#define TRACE_INCLUDE_PATH ../../include/ras
#include <ras/ras_event.h>
/* lock to memory controller's control array */
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
index a66941fea5a4..e6d1691dfa45 100644
--- a/drivers/edac/edac_module.c
+++ b/drivers/edac/edac_module.c
@@ -28,7 +28,7 @@ static int edac_set_debug_level(const char *buf, struct kernel_param *kp)
if (ret)
return ret;
- if (val < 0 || val > 4)
+ if (val > 4)
return -EINVAL;
return param_set_int(buf, kp);
diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c
new file mode 100644
index 000000000000..a981dc6fd88e
--- /dev/null
+++ b/drivers/edac/ie31200_edac.c
@@ -0,0 +1,536 @@
+/*
+ * Intel E3-1200
+ * Copyright (C) 2014 Jason Baron <jbaron@akamai.com>
+ *
+ * Support for the E3-1200 processor family. Heavily based on previous
+ * Intel EDAC drivers.
+ *
+ * Since the DRAM controller is on the cpu chip, we can use its PCI device
+ * id to identify these processors.
+ *
+ * PCI DRAM controller device ids (Taken from The PCI ID Repository - http://pci-ids.ucw.cz/)
+ *
+ * 0108: Xeon E3-1200 Processor Family DRAM Controller
+ * 010c: Xeon E3-1200/2nd Generation Core Processor Family DRAM Controller
+ * 0150: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
+ * 0158: Xeon E3-1200 v2/Ivy Bridge DRAM Controller
+ * 015c: Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
+ * 0c04: Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller
+ * 0c08: Xeon E3-1200 v3 Processor DRAM Controller
+ *
+ * Based on Intel specification:
+ * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v3-vol-2-datasheet.pdf
+ * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e3-1200-family-vol-2-datasheet.html
+ *
+ * According to the above datasheet (p.16):
+ * "
+ * 6. Software must not access B0/D0/F0 32-bit memory-mapped registers with
+ * requests that cross a DW boundary.
+ * "
+ *
+ * Thus, we make use of the explicit: lo_hi_readq(), which breaks the readq into
+ * 2 readl() calls. This restriction may be lifted in subsequent chip releases,
+ * but lo_hi_readq() ensures that we are safe across all e3-1200 processors.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/edac.h>
+
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include "edac_core.h"
+
+#define IE31200_REVISION "1.0"
+#define EDAC_MOD_STR "ie31200_edac"
+
+#define ie31200_printk(level, fmt, arg...) \
+ edac_printk(level, "ie31200", fmt, ##arg)
+
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_1 0x0108
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_2 0x010c
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_3 0x0150
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_4 0x0158
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_5 0x015c
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_6 0x0c04
+#define PCI_DEVICE_ID_INTEL_IE31200_HB_7 0x0c08
+
+#define IE31200_DIMMS 4
+#define IE31200_RANKS 8
+#define IE31200_RANKS_PER_CHANNEL 4
+#define IE31200_DIMMS_PER_CHANNEL 2
+#define IE31200_CHANNELS 2
+
+/* Intel IE31200 register addresses - device 0 function 0 - DRAM Controller */
+#define IE31200_MCHBAR_LOW 0x48
+#define IE31200_MCHBAR_HIGH 0x4c
+#define IE31200_MCHBAR_MASK GENMASK_ULL(38, 15)
+#define IE31200_MMR_WINDOW_SIZE BIT(15)
+
+/*
+ * Error Status Register (16b)
+ *
+ * 15 reserved
+ * 14 Isochronous TBWRR Run Behind FIFO Full
+ * (ITCV)
+ * 13 Isochronous TBWRR Run Behind FIFO Put
+ * (ITSTV)
+ * 12 reserved
+ * 11 MCH Thermal Sensor Event
+ * for SMI/SCI/SERR (GTSE)
+ * 10 reserved
+ * 9 LOCK to non-DRAM Memory Flag (LCKF)
+ * 8 reserved
+ * 7 DRAM Throttle Flag (DTF)
+ * 6:2 reserved
+ * 1 Multi-bit DRAM ECC Error Flag (DMERR)
+ * 0 Single-bit DRAM ECC Error Flag (DSERR)
+ */
+#define IE31200_ERRSTS 0xc8
+#define IE31200_ERRSTS_UE BIT(1)
+#define IE31200_ERRSTS_CE BIT(0)
+#define IE31200_ERRSTS_BITS (IE31200_ERRSTS_UE | IE31200_ERRSTS_CE)
+
+/*
+ * Channel 0 ECC Error Log (64b)
+ *
+ * 63:48 Error Column Address (ERRCOL)
+ * 47:32 Error Row Address (ERRROW)
+ * 31:29 Error Bank Address (ERRBANK)
+ * 28:27 Error Rank Address (ERRRANK)
+ * 26:24 reserved
+ * 23:16 Error Syndrome (ERRSYND)
+ * 15: 2 reserved
+ * 1 Multiple Bit Error Status (MERRSTS)
+ * 0 Correctable Error Status (CERRSTS)
+ */
+#define IE31200_C0ECCERRLOG 0x40c8
+#define IE31200_C1ECCERRLOG 0x44c8
+#define IE31200_ECCERRLOG_CE BIT(0)
+#define IE31200_ECCERRLOG_UE BIT(1)
+#define IE31200_ECCERRLOG_RANK_BITS GENMASK_ULL(28, 27)
+#define IE31200_ECCERRLOG_RANK_SHIFT 27
+#define IE31200_ECCERRLOG_SYNDROME_BITS GENMASK_ULL(23, 16)
+#define IE31200_ECCERRLOG_SYNDROME_SHIFT 16
+
+#define IE31200_ECCERRLOG_SYNDROME(log) \
+ ((log & IE31200_ECCERRLOG_SYNDROME_BITS) >> \
+ IE31200_ECCERRLOG_SYNDROME_SHIFT)
+
+#define IE31200_CAPID0 0xe4
+#define IE31200_CAPID0_PDCD BIT(4)
+#define IE31200_CAPID0_DDPCD BIT(6)
+#define IE31200_CAPID0_ECC BIT(1)
+
+#define IE31200_MAD_DIMM_0_OFFSET 0x5004
+#define IE31200_MAD_DIMM_SIZE GENMASK_ULL(7, 0)
+#define IE31200_MAD_DIMM_A_RANK BIT(17)
+#define IE31200_MAD_DIMM_A_WIDTH BIT(19)
+
+#define IE31200_PAGES(n) (n << (28 - PAGE_SHIFT))
+
+static int nr_channels;
+
+struct ie31200_priv {
+ void __iomem *window;
+};
+
+enum ie31200_chips {
+ IE31200 = 0,
+};
+
+struct ie31200_dev_info {
+ const char *ctl_name;
+};
+
+struct ie31200_error_info {
+ u16 errsts;
+ u16 errsts2;
+ u64 eccerrlog[IE31200_CHANNELS];
+};
+
+static const struct ie31200_dev_info ie31200_devs[] = {
+ [IE31200] = {
+ .ctl_name = "IE31200"
+ },
+};
+
+struct dimm_data {
+ u8 size; /* in 256MB multiples */
+ u8 dual_rank : 1,
+ x16_width : 1; /* 0 means x8 width */
+};
+
+static int how_many_channels(struct pci_dev *pdev)
+{
+ int n_channels;
+ unsigned char capid0_2b; /* 2nd byte of CAPID0 */
+
+ pci_read_config_byte(pdev, IE31200_CAPID0 + 1, &capid0_2b);
+
+ /* check PDCD: Dual Channel Disable */
+ if (capid0_2b & IE31200_CAPID0_PDCD) {
+ edac_dbg(0, "In single channel mode\n");
+ n_channels = 1;
+ } else {
+ edac_dbg(0, "In dual channel mode\n");
+ n_channels = 2;
+ }
+
+ /* check DDPCD - check if both channels are filled */
+ if (capid0_2b & IE31200_CAPID0_DDPCD)
+ edac_dbg(0, "2 DIMMS per channel disabled\n");
+ else
+ edac_dbg(0, "2 DIMMS per channel enabled\n");
+
+ return n_channels;
+}
+
+static bool ecc_capable(struct pci_dev *pdev)
+{
+ unsigned char capid0_4b; /* 4th byte of CAPID0 */
+
+ pci_read_config_byte(pdev, IE31200_CAPID0 + 3, &capid0_4b);
+ if (capid0_4b & IE31200_CAPID0_ECC)
+ return false;
+ return true;
+}
+
+static int eccerrlog_row(int channel, u64 log)
+{
+ int rank = ((log & IE31200_ECCERRLOG_RANK_BITS) >>
+ IE31200_ECCERRLOG_RANK_SHIFT);
+ return rank | (channel * IE31200_RANKS_PER_CHANNEL);
+}
+
+static void ie31200_clear_error_info(struct mem_ctl_info *mci)
+{
+ /*
+ * Clear any error bits.
+ * (Yes, we really clear bits by writing 1 to them.)
+ */
+ pci_write_bits16(to_pci_dev(mci->pdev), IE31200_ERRSTS,
+ IE31200_ERRSTS_BITS, IE31200_ERRSTS_BITS);
+}
+
+static void ie31200_get_and_clear_error_info(struct mem_ctl_info *mci,
+ struct ie31200_error_info *info)
+{
+ struct pci_dev *pdev;
+ struct ie31200_priv *priv = mci->pvt_info;
+ void __iomem *window = priv->window;
+
+ pdev = to_pci_dev(mci->pdev);
+
+ /*
+ * This is a mess because there is no atomic way to read all the
+ * registers at once and the registers can transition from CE being
+ * overwritten by UE.
+ */
+ pci_read_config_word(pdev, IE31200_ERRSTS, &info->errsts);
+ if (!(info->errsts & IE31200_ERRSTS_BITS))
+ return;
+
+ info->eccerrlog[0] = lo_hi_readq(window + IE31200_C0ECCERRLOG);
+ if (nr_channels == 2)
+ info->eccerrlog[1] = lo_hi_readq(window + IE31200_C1ECCERRLOG);
+
+ pci_read_config_word(pdev, IE31200_ERRSTS, &info->errsts2);
+
+ /*
+ * If the error is the same for both reads then the first set
+ * of reads is valid. If there is a change then there is a CE
+ * with no info and the second set of reads is valid and
+ * should be UE info.
+ */
+ if ((info->errsts ^ info->errsts2) & IE31200_ERRSTS_BITS) {
+ info->eccerrlog[0] = lo_hi_readq(window + IE31200_C0ECCERRLOG);
+ if (nr_channels == 2)
+ info->eccerrlog[1] =
+ lo_hi_readq(window + IE31200_C1ECCERRLOG);
+ }
+
+ ie31200_clear_error_info(mci);
+}
+
+static void ie31200_process_error_info(struct mem_ctl_info *mci,
+ struct ie31200_error_info *info)
+{
+ int channel;
+ u64 log;
+
+ if (!(info->errsts & IE31200_ERRSTS_BITS))
+ return;
+
+ if ((info->errsts ^ info->errsts2) & IE31200_ERRSTS_BITS) {
+ edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
+ -1, -1, -1, "UE overwrote CE", "");
+ info->errsts = info->errsts2;
+ }
+
+ for (channel = 0; channel < nr_channels; channel++) {
+ log = info->eccerrlog[channel];
+ if (log & IE31200_ECCERRLOG_UE) {
+ edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
+ 0, 0, 0,
+ eccerrlog_row(channel, log),
+ channel, -1,
+ "ie31200 UE", "");
+ } else if (log & IE31200_ECCERRLOG_CE) {
+ edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
+ 0, 0,
+ IE31200_ECCERRLOG_SYNDROME(log),
+ eccerrlog_row(channel, log),
+ channel, -1,
+ "ie31200 CE", "");
+ }
+ }
+}
+
+static void ie31200_check(struct mem_ctl_info *mci)
+{
+ struct ie31200_error_info info;
+
+ edac_dbg(1, "MC%d\n", mci->mc_idx);
+ ie31200_get_and_clear_error_info(mci, &info);
+ ie31200_process_error_info(mci, &info);
+}
+
+static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev)
+{
+ union {
+ u64 mchbar;
+ struct {
+ u32 mchbar_low;
+ u32 mchbar_high;
+ };
+ } u;
+ void __iomem *window;
+
+ pci_read_config_dword(pdev, IE31200_MCHBAR_LOW, &u.mchbar_low);
+ pci_read_config_dword(pdev, IE31200_MCHBAR_HIGH, &u.mchbar_high);
+ u.mchbar &= IE31200_MCHBAR_MASK;
+
+ if (u.mchbar != (resource_size_t)u.mchbar) {
+ ie31200_printk(KERN_ERR, "mmio space beyond accessible range (0x%llx)\n",
+ (unsigned long long)u.mchbar);
+ return NULL;
+ }
+
+ window = ioremap_nocache(u.mchbar, IE31200_MMR_WINDOW_SIZE);
+ if (!window)
+ ie31200_printk(KERN_ERR, "Cannot map mmio space at 0x%llx\n",
+ (unsigned long long)u.mchbar);
+
+ return window;
+}
+
+static int ie31200_probe1(struct pci_dev *pdev, int dev_idx)
+{
+ int i, j, ret;
+ struct mem_ctl_info *mci = NULL;
+ struct edac_mc_layer layers[2];
+ struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL];
+ void __iomem *window;
+ struct ie31200_priv *priv;
+ u32 addr_decode;
+
+ edac_dbg(0, "MC:\n");
+
+ if (!ecc_capable(pdev)) {
+ ie31200_printk(KERN_INFO, "No ECC support\n");
+ return -ENODEV;
+ }
+
+ nr_channels = how_many_channels(pdev);
+ layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
+ layers[0].size = IE31200_DIMMS;
+ layers[0].is_virt_csrow = true;
+ layers[1].type = EDAC_MC_LAYER_CHANNEL;
+ layers[1].size = nr_channels;
+ layers[1].is_virt_csrow = false;
+ mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
+ sizeof(struct ie31200_priv));
+ if (!mci)
+ return -ENOMEM;
+
+ window = ie31200_map_mchbar(pdev);
+ if (!window) {
+ ret = -ENODEV;
+ goto fail_free;
+ }
+
+ edac_dbg(3, "MC: init mci\n");
+ mci->pdev = &pdev->dev;
+ mci->mtype_cap = MEM_FLAG_DDR3;
+ mci->edac_ctl_cap = EDAC_FLAG_SECDED;
+ mci->edac_cap = EDAC_FLAG_SECDED;
+ mci->mod_name = EDAC_MOD_STR;
+ mci->mod_ver = IE31200_REVISION;
+ mci->ctl_name = ie31200_devs[dev_idx].ctl_name;
+ mci->dev_name = pci_name(pdev);
+ mci->edac_check = ie31200_check;
+ mci->ctl_page_to_phys = NULL;
+ priv = mci->pvt_info;
+ priv->window = window;
+
+ /* populate DIMM info */
+ for (i = 0; i < IE31200_CHANNELS; i++) {
+ addr_decode = readl(window + IE31200_MAD_DIMM_0_OFFSET +
+ (i * 4));
+ edac_dbg(0, "addr_decode: 0x%x\n", addr_decode);
+ for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) {
+ dimm_info[i][j].size = (addr_decode >> (j * 8)) &
+ IE31200_MAD_DIMM_SIZE;
+ dimm_info[i][j].dual_rank = (addr_decode &
+ (IE31200_MAD_DIMM_A_RANK << j)) ? 1 : 0;
+ dimm_info[i][j].x16_width = (addr_decode &
+ (IE31200_MAD_DIMM_A_WIDTH << j)) ? 1 : 0;
+ edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
+ dimm_info[i][j].size,
+ dimm_info[i][j].dual_rank,
+ dimm_info[i][j].x16_width);
+ }
+ }
+
+ /*
+ * The dram rank boundary (DRB) reg values are boundary addresses
+ * for each DRAM rank with a granularity of 64MB. DRB regs are
+ * cumulative; the last one will contain the total memory
+ * contained in all ranks.
+ */
+ for (i = 0; i < IE31200_DIMMS_PER_CHANNEL; i++) {
+ for (j = 0; j < IE31200_CHANNELS; j++) {
+ struct dimm_info *dimm;
+ unsigned long nr_pages;
+
+ nr_pages = IE31200_PAGES(dimm_info[j][i].size);
+ if (nr_pages == 0)
+ continue;
+
+ if (dimm_info[j][i].dual_rank) {
+ nr_pages = nr_pages / 2;
+ dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
+ mci->n_layers, (i * 2) + 1,
+ j, 0);
+ dimm->nr_pages = nr_pages;
+ edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
+ dimm->grain = 8; /* just a guess */
+ dimm->mtype = MEM_DDR3;
+ dimm->dtype = DEV_UNKNOWN;
+ dimm->edac_mode = EDAC_UNKNOWN;
+ }
+ dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms,
+ mci->n_layers, i * 2, j, 0);
+ dimm->nr_pages = nr_pages;
+ edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
+ dimm->grain = 8; /* same guess */
+ dimm->mtype = MEM_DDR3;
+ dimm->dtype = DEV_UNKNOWN;
+ dimm->edac_mode = EDAC_UNKNOWN;
+ }
+ }
+
+ ie31200_clear_error_info(mci);
+
+ if (edac_mc_add_mc(mci)) {
+ edac_dbg(3, "MC: failed edac_mc_add_mc()\n");
+ ret = -ENODEV;
+ goto fail_unmap;
+ }
+
+ /* get this far and it's successful */
+ edac_dbg(3, "MC: success\n");
+ return 0;
+
+fail_unmap:
+ iounmap(window);
+
+fail_free:
+ edac_mc_free(mci);
+
+ return ret;
+}
+
+static int ie31200_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ edac_dbg(0, "MC:\n");
+
+ if (pci_enable_device(pdev) < 0)
+ return -EIO;
+
+ return ie31200_probe1(pdev, ent->driver_data);
+}
+
+static void ie31200_remove_one(struct pci_dev *pdev)
+{
+ struct mem_ctl_info *mci;
+ struct ie31200_priv *priv;
+
+ edac_dbg(0, "\n");
+ mci = edac_mc_del_mc(&pdev->dev);
+ if (!mci)
+ return;
+ priv = mci->pvt_info;
+ iounmap(priv->window);
+ edac_mc_free(mci);
+}
+
+static const struct pci_device_id ie31200_pci_tbl[] = {
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_4), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_5), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_6), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ PCI_VEND_DEV(INTEL, IE31200_HB_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ IE31200},
+ {
+ 0,
+ } /* 0 terminated list. */
+};
+MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);
+
+static struct pci_driver ie31200_driver = {
+ .name = EDAC_MOD_STR,
+ .probe = ie31200_init_one,
+ .remove = ie31200_remove_one,
+ .id_table = ie31200_pci_tbl,
+};
+
+static int __init ie31200_init(void)
+{
+ edac_dbg(3, "MC:\n");
+ /* Ensure that the OPSTATE is set correctly for POLL or NMI */
+ opstate_init();
+
+ return pci_register_driver(&ie31200_driver);
+}
+
+static void __exit ie31200_exit(void)
+{
+ edac_dbg(3, "MC:\n");
+ pci_unregister_driver(&ie31200_driver);
+}
+
+module_init(ie31200_init);
+module_exit(ie31200_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
+MODULE_DESCRIPTION("MC support for Intel Processor E31200 memory hub controllers");
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 5f43620d580a..f78c1c54dbd5 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -78,7 +78,8 @@ static const char * const f15h_mc1_mce_desc[] = {
"uop queue",
"insn buffer",
"predecode buffer",
- "fetch address FIFO"
+ "fetch address FIFO",
+ "dispatch uop queue"
};
static const char * const f15h_mc2_mce_desc[] = {
@@ -267,6 +268,12 @@ static bool f15h_mc0_mce(u16 ec, u8 xec)
pr_cont("System Read Data Error.\n");
else
pr_cont(" Internal error condition type %d.\n", xec);
+ } else if (INT_ERROR(ec)) {
+ if (xec <= 0x1f)
+ pr_cont("Hardware Assert.\n");
+ else
+ ret = false;
+
} else
ret = false;
@@ -373,7 +380,7 @@ static bool f15h_mc1_mce(u16 ec, u8 xec)
pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
break;
- case 0x11 ... 0x14:
+ case 0x11 ... 0x15:
pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
break;
@@ -397,10 +404,20 @@ static void decode_mc1_mce(struct mce *m)
bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
+ } else if (INT_ERROR(ec)) {
+ if (xec <= 0x3f)
+ pr_cont("Hardware Assert.\n");
+ else
+ goto wrong_mc1_mce;
} else if (fam_ops->mc1_mce(ec, xec))
;
else
- pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
+ goto wrong_mc1_mce;
+
+ return;
+
+wrong_mc1_mce:
+ pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
}
static bool k8_mc2_mce(u16 ec, u8 xec)
@@ -468,6 +485,11 @@ static bool f15h_mc2_mce(u16 ec, u8 xec)
default:
ret = false;
}
+ } else if (INT_ERROR(ec)) {
+ if (xec <= 0x3f)
+ pr_cont("Hardware Assert.\n");
+ else
+ ret = false;
}
return ret;
@@ -615,6 +637,7 @@ static void decode_mc4_mce(struct mce *m)
static void decode_mc5_mce(struct mce *m)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
+ u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
if (c->x86 == 0xf || c->x86 == 0x11)
@@ -622,6 +645,14 @@ static void decode_mc5_mce(struct mce *m)
pr_emerg(HW_ERR "MC5 Error: ");
+ if (INT_ERROR(ec)) {
+ if (xec <= 0x1f) {
+ pr_cont("Hardware Assert.\n");
+ return;
+ } else
+ goto wrong_mc5_mce;
+ }
+
if (xec == 0x0 || xec == 0xc)
pr_cont("%s.\n", mc5_mce_desc[xec]);
else if (xec <= 0xd)
@@ -642,6 +673,10 @@ static void decode_mc6_mce(struct mce *m)
pr_emerg(HW_ERR "MC6 Error: ");
switch (xec) {
+ case 0x0:
+ pr_cont("Hardware Assertion");
+ break;
+
case 0x1:
pr_cont("Free List");
break;
@@ -857,7 +892,8 @@ static int __init mce_amd_init(void)
break;
case 0x15:
- xec_mask = 0x1f;
+ xec_mask = c->x86_model == 0x60 ? 0x3f : 0x1f;
+
fam_ops->mc0_mce = f15h_mc0_mce;
fam_ops->mc1_mce = f15h_mc1_mce;
fam_ops->mc2_mce = f15h_mc2_mce;
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c
index 4891b450830b..e644b52c287c 100644
--- a/drivers/edac/x38_edac.c
+++ b/drivers/edac/x38_edac.c
@@ -14,6 +14,8 @@
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>
+
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
#include "edac_core.h"
#define X38_REVISION "1.1"
@@ -161,11 +163,6 @@ static void x38_clear_error_info(struct mem_ctl_info *mci)
X38_ERRSTS_BITS);
}
-static u64 x38_readq(const void __iomem *addr)
-{
- return readl(addr) | (((u64)readl(addr + 4)) << 32);
-}
-
static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
struct x38_error_info *info)
{
@@ -183,9 +180,9 @@ static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
if (!(info->errsts & X38_ERRSTS_BITS))
return;
- info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
+ info->eccerrlog[0] = lo_hi_readq(window + X38_C0ECCERRLOG);
if (x38_channel_num == 2)
- info->eccerrlog[1] = x38_readq(window + X38_C1ECCERRLOG);
+ info->eccerrlog[1] = lo_hi_readq(window + X38_C1ECCERRLOG);
pci_read_config_word(pdev, X38_ERRSTS, &info->errsts2);
@@ -196,10 +193,10 @@ static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
* should be UE info.
*/
if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) {
- info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
+ info->eccerrlog[0] = lo_hi_readq(window + X38_C0ECCERRLOG);
if (x38_channel_num == 2)
info->eccerrlog[1] =
- x38_readq(window + X38_C1ECCERRLOG);
+ lo_hi_readq(window + X38_C1ECCERRLOG);
}
x38_clear_error_info(mci);
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index aebde489c291..6f2f4727de2c 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -14,6 +14,20 @@ if EXTCON
comment "Extcon Device Drivers"
+config EXTCON_ADC_JACK
+ tristate "ADC Jack extcon support"
+ depends on IIO
+ help
+ Say Y here to enable extcon device driver based on ADC values.
+
+config EXTCON_ARIZONA
+ tristate "Wolfson Arizona EXTCON support"
+ depends on MFD_ARIZONA && INPUT && SND_SOC
+ help
+ Say Y here to enable support for external accessory detection
+ with Wolfson Arizona devices. These are audio CODECs with
+ advanced audio accessory detection support.
+
config EXTCON_GPIO
tristate "GPIO extcon support"
depends on GPIOLIB
@@ -21,12 +35,6 @@ config EXTCON_GPIO
Say Y here to enable GPIO based extcon support. Note that GPIO
extcon supports single state per extcon instance.
-config EXTCON_ADC_JACK
- tristate "ADC Jack extcon support"
- depends on IIO
- help
- Say Y here to enable extcon device driver based on ADC values.
-
config EXTCON_MAX14577
tristate "MAX14577/77836 EXTCON Support"
depends on MFD_MAX14577
@@ -55,14 +63,6 @@ config EXTCON_MAX8997
Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory
detector and switch.
-config EXTCON_ARIZONA
- tristate "Wolfson Arizona EXTCON support"
- depends on MFD_ARIZONA && INPUT && SND_SOC
- help
- Say Y here to enable support for external accessory detection
- with Wolfson Arizona devices. These are audio CODECs with
- advanced audio accessory detection support.
-
config EXTCON_PALMAS
tristate "Palmas USB EXTCON support"
depends on MFD_PALMAS
@@ -70,4 +70,14 @@ config EXTCON_PALMAS
Say Y here to enable support for USB peripheral and USB host
detection by palmas usb.
+config EXTCON_SM5502
+ tristate "SM5502 EXTCON support"
+ select IRQ_DOMAIN
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ If you say yes here you get support for the MUIC device of
+ Silicon Mitus SM5502. The SM5502 is a USB port accessory
+ detector and switch.
+
endif # MULTISTATE_SWITCH
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index bf7861ec0906..b38546eb522a 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -1,12 +1,13 @@
-#
+
# Makefile for external connector class (extcon) devices
#
obj-$(CONFIG_EXTCON) += extcon-class.o
-obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o
+obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
+obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o
obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o
-obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o
+obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index e18f95be3733..d860229e4de1 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -112,7 +112,6 @@ static int adc_jack_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate extcon device\n");
return -ENOMEM;
}
- data->edev->dev.parent = &pdev->dev;
data->edev->name = pdata->name;
/* Check the length of array and set num_cables */
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 6c84e3d12043..ba51588cc000 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -39,6 +39,11 @@
#define ARIZONA_ACCDET_MODE_HPL 1
#define ARIZONA_ACCDET_MODE_HPR 2
+#define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
+#define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
+#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
+#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
+
#define ARIZONA_HPDET_MAX 10000
#define HPDET_DEBOUNCE 500
@@ -324,14 +329,17 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
}
static struct {
+ unsigned int threshold;
unsigned int factor_a;
unsigned int factor_b;
} arizona_hpdet_b_ranges[] = {
- { 5528, 362464 },
- { 11084, 6186851 },
- { 11065, 65460395 },
+ { 100, 5528, 362464 },
+ { 169, 11084, 6186851 },
+ { 169, 11065, 65460395 },
};
+#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
+
static struct {
int min;
int max;
@@ -386,7 +394,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
>> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
- (val < 100 || val >= 0x3fb)) {
+ (val < arizona_hpdet_b_ranges[range].threshold ||
+ val >= ARIZONA_HPDET_B_RANGE_MAX)) {
range++;
dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
range);
@@ -399,7 +408,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
}
/* If we go out of range report top of range */
- if (val < 100 || val >= 0x3fb) {
+ if (val < arizona_hpdet_b_ranges[range].threshold ||
+ val >= ARIZONA_HPDET_B_RANGE_MAX) {
dev_dbg(arizona->dev, "Measurement out of range\n");
return ARIZONA_HPDET_MAX;
}
@@ -664,9 +674,8 @@ err:
ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
/* Just report headphone */
- ret = extcon_update_state(info->edev,
- 1 << ARIZONA_CABLE_HEADPHONE,
- 1 << ARIZONA_CABLE_HEADPHONE);
+ ret = extcon_set_cable_state_(info->edev,
+ ARIZONA_CABLE_HEADPHONE, true);
if (ret != 0)
dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
@@ -723,9 +732,8 @@ err:
ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
/* Just report headphone */
- ret = extcon_update_state(info->edev,
- 1 << ARIZONA_CABLE_HEADPHONE,
- 1 << ARIZONA_CABLE_HEADPHONE);
+ ret = extcon_set_cable_state_(info->edev,
+ ARIZONA_CABLE_HEADPHONE, true);
if (ret != 0)
dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
@@ -812,16 +820,15 @@ static void arizona_micd_detect(struct work_struct *work)
if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
arizona_identify_headphone(info);
- ret = extcon_update_state(info->edev,
- 1 << ARIZONA_CABLE_MICROPHONE,
- 1 << ARIZONA_CABLE_MICROPHONE);
+ ret = extcon_set_cable_state_(info->edev,
+ ARIZONA_CABLE_MICROPHONE, true);
if (ret != 0)
dev_err(arizona->dev, "Headset report failed: %d\n",
ret);
/* Don't need to regulate for button detection */
- ret = regulator_allow_bypass(info->micvdd, false);
+ ret = regulator_allow_bypass(info->micvdd, true);
if (ret != 0) {
dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
ret);
@@ -962,10 +969,16 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
if (arizona->pdata.jd_gpio5) {
mask = ARIZONA_MICD_CLAMP_STS;
- present = 0;
+ if (arizona->pdata.jd_invert)
+ present = ARIZONA_MICD_CLAMP_STS;
+ else
+ present = 0;
} else {
mask = ARIZONA_JD1_STS;
- present = ARIZONA_JD1_STS;
+ if (arizona->pdata.jd_invert)
+ present = 0;
+ else
+ present = ARIZONA_JD1_STS;
}
ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
@@ -1096,6 +1109,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_extcon_info *info;
unsigned int val;
+ unsigned int clamp_mode;
int jack_irq_fall, jack_irq_rise;
int ret, mode, i, j;
@@ -1103,12 +1117,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "Failed to allocate memory\n");
+ if (!info)
return -ENOMEM;
- }
- info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
+ info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
if (IS_ERR(info->micvdd)) {
ret = PTR_ERR(info->micvdd);
dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
@@ -1156,7 +1168,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
return -ENOMEM;
}
info->edev->name = "Headset Jack";
- info->edev->dev.parent = arizona->dev;
ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret < 0) {
@@ -1174,7 +1185,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
info->input->name = "Headset";
info->input->phys = "arizona/extcon";
- info->input->dev.parent = &pdev->dev;
if (pdata->num_micd_configs) {
info->micd_modes = pdata->micd_configs;
@@ -1305,16 +1315,22 @@ static int arizona_extcon_probe(struct platform_device *pdev)
regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
val);
- regmap_update_bits(arizona->regmap,
- ARIZONA_MICD_CLAMP_CONTROL,
- ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
+ if (arizona->pdata.jd_invert)
+ clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
+ else
+ clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
} else {
- regmap_update_bits(arizona->regmap,
- ARIZONA_MICD_CLAMP_CONTROL,
- ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
+ if (arizona->pdata.jd_invert)
+ clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
+ else
+ clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
}
regmap_update_bits(arizona->regmap,
+ ARIZONA_MICD_CLAMP_CONTROL,
+ ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
+
+ regmap_update_bits(arizona->regmap,
ARIZONA_JACK_DETECT_DEBOUNCE,
ARIZONA_MICD_CLAMP_DB,
ARIZONA_MICD_CLAMP_DB);
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 18d42c0e4581..4c2f2c543bb7 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -645,6 +645,8 @@ struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
return edev;
}
+ edev->dev.parent = dev;
+
*ptr = edev;
devres_add(dev, ptr);
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 645b28356819..5b7ec274cb63 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -105,7 +105,6 @@ static int gpio_extcon_probe(struct platform_device *pdev)
return -ENOMEM;
}
extcon_data->edev->name = pdata->name;
- extcon_data->edev->dev.parent = &pdev->dev;
extcon_data->gpio = pdata->gpio;
extcon_data->gpio_active_low = pdata->gpio_active_low;
diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c
index d49e891b5675..7309743d0da1 100644
--- a/drivers/extcon/extcon-max14577.c
+++ b/drivers/extcon/extcon-max14577.c
@@ -692,10 +692,9 @@ static int max14577_muic_probe(struct platform_device *pdev)
u8 id;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ if (!info)
return -ENOMEM;
- }
+
info->dev = &pdev->dev;
info->max14577 = max14577;
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index 2c7c3e191591..77460f2c1ca1 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -255,10 +255,10 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
case ADC_DEBOUNCE_TIME_10MS:
case ADC_DEBOUNCE_TIME_25MS:
case ADC_DEBOUNCE_TIME_38_62MS:
- ret = max77693_update_reg(info->max77693->regmap_muic,
+ ret = regmap_update_bits(info->max77693->regmap_muic,
MAX77693_MUIC_REG_CTRL3,
- time << CONTROL3_ADCDBSET_SHIFT,
- CONTROL3_ADCDBSET_MASK);
+ CONTROL3_ADCDBSET_MASK,
+ time << CONTROL3_ADCDBSET_SHIFT);
if (ret) {
dev_err(info->dev, "failed to set ADC debounce time\n");
return ret;
@@ -286,15 +286,15 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
u8 val, bool attached)
{
int ret = 0;
- u8 ctrl1, ctrl2 = 0;
+ unsigned int ctrl1, ctrl2 = 0;
if (attached)
ctrl1 = val;
else
ctrl1 = CONTROL1_SW_OPEN;
- ret = max77693_update_reg(info->max77693->regmap_muic,
- MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+ ret = regmap_update_bits(info->max77693->regmap_muic,
+ MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);
if (ret < 0) {
dev_err(info->dev, "failed to update MUIC register\n");
return ret;
@@ -305,9 +305,9 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
else
ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
- ret = max77693_update_reg(info->max77693->regmap_muic,
- MAX77693_MUIC_REG_CTRL2, ctrl2,
- CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
+ ret = regmap_update_bits(info->max77693->regmap_muic,
+ MAX77693_MUIC_REG_CTRL2,
+ CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2);
if (ret < 0) {
dev_err(info->dev, "failed to update MUIC register\n");
return ret;
@@ -969,8 +969,8 @@ static void max77693_muic_irq_work(struct work_struct *work)
if (info->irq == muic_irqs[i].virq)
irq_type = muic_irqs[i].irq;
- ret = max77693_bulk_read(info->max77693->regmap_muic,
- MAX77693_MUIC_REG_STATUS1, 2, info->status);
+ ret = regmap_bulk_read(info->max77693->regmap_muic,
+ MAX77693_MUIC_REG_STATUS1, info->status, 2);
if (ret) {
dev_err(info->dev, "failed to read MUIC register\n");
mutex_unlock(&info->mutex);
@@ -1042,8 +1042,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
mutex_lock(&info->mutex);
/* Read STATUSx register to detect accessory */
- ret = max77693_bulk_read(info->max77693->regmap_muic,
- MAX77693_MUIC_REG_STATUS1, 2, info->status);
+ ret = regmap_bulk_read(info->max77693->regmap_muic,
+ MAX77693_MUIC_REG_STATUS1, info->status, 2);
if (ret) {
dev_err(info->dev, "failed to read MUIC register\n");
mutex_unlock(&info->mutex);
@@ -1095,14 +1095,13 @@ static int max77693_muic_probe(struct platform_device *pdev)
int delay_jiffies;
int ret;
int i;
- u8 id;
+ unsigned int id;
info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),
GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ if (!info)
return -ENOMEM;
- }
+
info->dev = &pdev->dev;
info->max77693 = max77693;
if (info->max77693->regmap_muic) {
@@ -1154,7 +1153,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
struct max77693_muic_irq *muic_irq = &muic_irqs[i];
unsigned int virq = 0;
- virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
+ virq = regmap_irq_get_virq(max77693->irq_data_muic,
+ muic_irq->irq);
if (!virq) {
ret = -EINVAL;
goto err_irq;
@@ -1183,7 +1183,6 @@ static int max77693_muic_probe(struct platform_device *pdev)
goto err_irq;
}
info->edev->name = DEV_NAME;
- info->edev->dev.parent = &pdev->dev;
ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret) {
@@ -1204,7 +1203,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
enum max77693_irq_source irq_src
= MAX77693_IRQ_GROUP_NR;
- max77693_write_reg(info->max77693->regmap_muic,
+ regmap_write(info->max77693->regmap_muic,
init_data[i].addr,
init_data[i].data);
@@ -1262,7 +1261,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
max77693_muic_set_path(info, info->path_uart, true);
/* Check revision number of MUIC device*/
- ret = max77693_read_reg(info->max77693->regmap_muic,
+ ret = regmap_read(info->max77693->regmap_muic,
MAX77693_MUIC_REG_ID, &id);
if (ret < 0) {
dev_err(&pdev->dev, "failed to read revision number\n");
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index d9f7f1baaa03..75e501c98005 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -661,10 +661,8 @@ static int max8997_muic_probe(struct platform_device *pdev)
info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
+ if (!info)
return -ENOMEM;
- }
info->dev = &pdev->dev;
info->muic = max8997->muic;
@@ -706,7 +704,6 @@ static int max8997_muic_probe(struct platform_device *pdev)
goto err_irq;
}
info->edev->name = DEV_NAME;
- info->edev->dev.parent = &pdev->dev;
ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret) {
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index 7417ce84eb2d..230e1220ce48 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -194,7 +194,6 @@ static int palmas_usb_probe(struct platform_device *pdev)
return -ENOMEM;
}
palmas_usb->edev->name = kstrdup(node->name, GFP_KERNEL);
- palmas_usb->edev->dev.parent = palmas_usb->dev;
palmas_usb->edev->mutually_exclusive = mutually_exclusive;
status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev);
@@ -278,7 +277,7 @@ static int palmas_usb_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(palmas_pm_ops, palmas_usb_suspend, palmas_usb_resume);
-static struct of_device_id of_palmas_match_tbl[] = {
+static const struct of_device_id of_palmas_match_tbl[] = {
{ .compatible = "ti,palmas-usb", },
{ .compatible = "ti,palmas-usb-vid", },
{ .compatible = "ti,twl6035-usb", },
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
new file mode 100644
index 000000000000..560d7dccec7b
--- /dev/null
+++ b/drivers/extcon/extcon-sm5502.c
@@ -0,0 +1,724 @@
+/*
+ * extcon-sm5502.c - Silicon Mitus SM5502 extcon drvier to support USB switches
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ * Author: Chanwoo Choi <cw00.choi@samsung.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/input.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/extcon.h>
+#include <linux/extcon/sm5502.h>
+
+#define DELAY_MS_DEFAULT 17000 /* unit: millisecond */
+
+struct muic_irq {
+ unsigned int irq;
+ const char *name;
+ unsigned int virq;
+};
+
+struct reg_data {
+ u8 reg;
+ unsigned int val;
+ bool invert;
+};
+
+struct sm5502_muic_info {
+ struct device *dev;
+ struct extcon_dev *edev;
+
+ struct i2c_client *i2c;
+ struct regmap *regmap;
+
+ struct regmap_irq_chip_data *irq_data;
+ struct muic_irq *muic_irqs;
+ unsigned int num_muic_irqs;
+ int irq;
+ bool irq_attach;
+ bool irq_detach;
+ struct work_struct irq_work;
+
+ struct reg_data *reg_data;
+ unsigned int num_reg_data;
+
+ struct mutex mutex;
+
+ /*
+ * Use delayed workqueue to detect cable state and then
+ * notify cable state to notifiee/platform through uevent.
+ * After completing the booting of platform, the extcon provider
+ * driver should notify cable state to upper layer.
+ */
+ struct delayed_work wq_detcable;
+};
+
+/* Default value of SM5502 register to bring up MUIC device. */
+static struct reg_data sm5502_reg_data[] = {
+ {
+ .reg = SM5502_REG_CONTROL,
+ .val = SM5502_REG_CONTROL_MASK_INT_MASK,
+ .invert = false,
+ }, {
+ .reg = SM5502_REG_INTMASK1,
+ .val = SM5502_REG_INTM1_KP_MASK
+ | SM5502_REG_INTM1_LKP_MASK
+ | SM5502_REG_INTM1_LKR_MASK,
+ .invert = true,
+ }, {
+ .reg = SM5502_REG_INTMASK2,
+ .val = SM5502_REG_INTM2_VBUS_DET_MASK
+ | SM5502_REG_INTM2_REV_ACCE_MASK
+ | SM5502_REG_INTM2_ADC_CHG_MASK
+ | SM5502_REG_INTM2_STUCK_KEY_MASK
+ | SM5502_REG_INTM2_STUCK_KEY_RCV_MASK
+ | SM5502_REG_INTM2_MHL_MASK,
+ .invert = true,
+ },
+ { }
+};
+
+/* List of detectable cables */
+enum {
+ EXTCON_CABLE_USB = 0,
+ EXTCON_CABLE_USB_HOST,
+ EXTCON_CABLE_TA,
+
+ EXTCON_CABLE_END,
+};
+
+static const char *sm5502_extcon_cable[] = {
+ [EXTCON_CABLE_USB] = "USB",
+ [EXTCON_CABLE_USB_HOST] = "USB-Host",
+ [EXTCON_CABLE_TA] = "TA",
+ NULL,
+};
+
+/* Define supported accessory type */
+enum sm5502_muic_acc_type {
+ SM5502_MUIC_ADC_GROUND = 0x0,
+ SM5502_MUIC_ADC_SEND_END_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S1_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S2_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S3_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S4_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S5_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S6_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S7_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S8_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S9_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S10_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S11_BUTTON,
+ SM5502_MUIC_ADC_REMOTE_S12_BUTTON,
+ SM5502_MUIC_ADC_RESERVED_ACC_1,
+ SM5502_MUIC_ADC_RESERVED_ACC_2,
+ SM5502_MUIC_ADC_RESERVED_ACC_3,
+ SM5502_MUIC_ADC_RESERVED_ACC_4,
+ SM5502_MUIC_ADC_RESERVED_ACC_5,
+ SM5502_MUIC_ADC_AUDIO_TYPE2,
+ SM5502_MUIC_ADC_PHONE_POWERED_DEV,
+ SM5502_MUIC_ADC_TTY_CONVERTER,
+ SM5502_MUIC_ADC_UART_CABLE,
+ SM5502_MUIC_ADC_TYPE1_CHARGER,
+ SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB,
+ SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB,
+ SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE,
+ SM5502_MUIC_ADC_TYPE2_CHARGER,
+ SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART,
+ SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART,
+ SM5502_MUIC_ADC_AUDIO_TYPE1,
+ SM5502_MUIC_ADC_OPEN = 0x1f,
+
+ /* The below accessories have same ADC value (0x1f or 0x1e).
+ So, Device type1 is used to separate specific accessory. */
+ /* |---------|--ADC| */
+ /* | [7:5]|[4:0]| */
+ SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE = 0x3e, /* | 001|11110| */
+ SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END = 0x5e, /* | 010|11110| */
+ /* |Dev Type1|--ADC| */
+ SM5502_MUIC_ADC_OPEN_USB = 0x5f, /* | 010|11111| */
+ SM5502_MUIC_ADC_OPEN_TA = 0xdf, /* | 110|11111| */
+ SM5502_MUIC_ADC_OPEN_USB_OTG = 0xff, /* | 111|11111| */
+};
+
+/* List of supported interrupt for SM5502 */
+static struct muic_irq sm5502_muic_irqs[] = {
+ { SM5502_IRQ_INT1_ATTACH, "muic-attach" },
+ { SM5502_IRQ_INT1_DETACH, "muic-detach" },
+ { SM5502_IRQ_INT1_KP, "muic-kp" },
+ { SM5502_IRQ_INT1_LKP, "muic-lkp" },
+ { SM5502_IRQ_INT1_LKR, "muic-lkr" },
+ { SM5502_IRQ_INT1_OVP_EVENT, "muic-ovp-event" },
+ { SM5502_IRQ_INT1_OCP_EVENT, "muic-ocp-event" },
+ { SM5502_IRQ_INT1_OVP_OCP_DIS, "muic-ovp-ocp-dis" },
+ { SM5502_IRQ_INT2_VBUS_DET, "muic-vbus-det" },
+ { SM5502_IRQ_INT2_REV_ACCE, "muic-rev-acce" },
+ { SM5502_IRQ_INT2_ADC_CHG, "muic-adc-chg" },
+ { SM5502_IRQ_INT2_STUCK_KEY, "muic-stuck-key" },
+ { SM5502_IRQ_INT2_STUCK_KEY_RCV, "muic-stuck-key-rcv" },
+ { SM5502_IRQ_INT2_MHL, "muic-mhl" },
+};
+
+/* Define interrupt list of SM5502 to register regmap_irq */
+static const struct regmap_irq sm5502_irqs[] = {
+ /* INT1 interrupts */
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_ATTACH_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_DETACH_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_KP_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKP_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKR_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_EVENT_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OCP_EVENT_MASK, },
+ { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_OCP_DIS_MASK, },
+
+ /* INT2 interrupts */
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_VBUS_DET_MASK,},
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_REV_ACCE_MASK, },
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_ADC_CHG_MASK, },
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_MASK, },
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK, },
+ { .reg_offset = 1, .mask = SM5502_IRQ_INT2_MHL_MASK, },
+};
+
+static const struct regmap_irq_chip sm5502_muic_irq_chip = {
+ .name = "sm5502",
+ .status_base = SM5502_REG_INT1,
+ .mask_base = SM5502_REG_INTMASK1,
+ .mask_invert = false,
+ .num_regs = 2,
+ .irqs = sm5502_irqs,
+ .num_irqs = ARRAY_SIZE(sm5502_irqs),
+};
+
+/* Define regmap configuration of SM5502 for I2C communication */
+static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case SM5502_REG_INTMASK1:
+ case SM5502_REG_INTMASK2:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static const struct regmap_config sm5502_muic_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_reg = sm5502_muic_volatile_reg,
+ .max_register = SM5502_REG_END,
+};
+
+/* Change DM_CON/DP_CON/VBUSIN switch according to cable type */
+static int sm5502_muic_set_path(struct sm5502_muic_info *info,
+ unsigned int con_sw, unsigned int vbus_sw,
+ bool attached)
+{
+ int ret;
+
+ if (!attached) {
+ con_sw = DM_DP_SWITCH_OPEN;
+ vbus_sw = VBUSIN_SWITCH_OPEN;
+ }
+
+ switch (con_sw) {
+ case DM_DP_SWITCH_OPEN:
+ case DM_DP_SWITCH_USB:
+ case DM_DP_SWITCH_AUDIO:
+ case DM_DP_SWITCH_UART:
+ ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
+ SM5502_REG_MANUAL_SW1_DP_MASK |
+ SM5502_REG_MANUAL_SW1_DM_MASK,
+ con_sw);
+ if (ret < 0) {
+ dev_err(info->dev,
+ "cannot update DM_CON/DP_CON switch\n");
+ return ret;
+ }
+ break;
+ default:
+ dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n",
+ con_sw);
+ return -EINVAL;
+ };
+
+ switch (vbus_sw) {
+ case VBUSIN_SWITCH_OPEN:
+ case VBUSIN_SWITCH_VBUSOUT:
+ case VBUSIN_SWITCH_MIC:
+ case VBUSIN_SWITCH_VBUSOUT_WITH_USB:
+ ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
+ SM5502_REG_MANUAL_SW1_VBUSIN_MASK,
+ vbus_sw);
+ if (ret < 0) {
+ dev_err(info->dev,
+ "cannot update VBUSIN switch\n");
+ return ret;
+ }
+ break;
+ default:
+ dev_err(info->dev, "Unknown VBUS switch type (%d)\n", vbus_sw);
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+/* Return cable type of attached or detached accessories */
+static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
+{
+ unsigned int cable_type = -1, adc, dev_type1;
+ int ret;
+
+ /* Read ADC value according to external cable or button */
+ ret = regmap_read(info->regmap, SM5502_REG_ADC, &adc);
+ if (ret) {
+ dev_err(info->dev, "failed to read ADC register\n");
+ return ret;
+ }
+
+ /*
+ * If ADC is SM5502_MUIC_ADC_GROUND(0x0), external cable hasn't
+ * connected with to MUIC device.
+ */
+ cable_type &= SM5502_REG_ADC_MASK;
+ if (cable_type == SM5502_MUIC_ADC_GROUND)
+ return SM5502_MUIC_ADC_GROUND;
+
+ switch (cable_type) {
+ case SM5502_MUIC_ADC_GROUND:
+ case SM5502_MUIC_ADC_SEND_END_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S1_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S2_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S3_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S4_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S5_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S6_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S7_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S8_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S9_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S10_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S11_BUTTON:
+ case SM5502_MUIC_ADC_REMOTE_S12_BUTTON:
+ case SM5502_MUIC_ADC_RESERVED_ACC_1:
+ case SM5502_MUIC_ADC_RESERVED_ACC_2:
+ case SM5502_MUIC_ADC_RESERVED_ACC_3:
+ case SM5502_MUIC_ADC_RESERVED_ACC_4:
+ case SM5502_MUIC_ADC_RESERVED_ACC_5:
+ case SM5502_MUIC_ADC_AUDIO_TYPE2:
+ case SM5502_MUIC_ADC_PHONE_POWERED_DEV:
+ case SM5502_MUIC_ADC_TTY_CONVERTER:
+ case SM5502_MUIC_ADC_UART_CABLE:
+ case SM5502_MUIC_ADC_TYPE1_CHARGER:
+ case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
+ case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
+ case SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE:
+ case SM5502_MUIC_ADC_TYPE2_CHARGER:
+ case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
+ case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
+ break;
+ case SM5502_MUIC_ADC_AUDIO_TYPE1:
+ /*
+ * Check whether cable type is
+ * SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE
+ * or SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END
+ * by using Button event.
+ */
+ break;
+ case SM5502_MUIC_ADC_OPEN:
+ ret = regmap_read(info->regmap, SM5502_REG_DEV_TYPE1,
+ &dev_type1);
+ if (ret) {
+ dev_err(info->dev, "failed to read DEV_TYPE1 reg\n");
+ return ret;
+ }
+
+ switch (dev_type1) {
+ case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
+ cable_type = SM5502_MUIC_ADC_OPEN_USB;
+ break;
+ case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
+ cable_type = SM5502_MUIC_ADC_OPEN_TA;
+ break;
+ case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
+ cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
+ break;
+ default:
+ dev_dbg(info->dev,
+ "cannot identify the cable type: adc(0x%x) "
+ "dev_type1(0x%x)\n", adc, dev_type1);
+ return -EINVAL;
+ };
+ break;
+ default:
+ dev_err(info->dev,
+ "failed to identify the cable type: adc(0x%x)\n", adc);
+ return -EINVAL;
+ };
+
+ return cable_type;
+}
+
+static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
+ bool attached)
+{
+ static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND;
+ const char **cable_names = info->edev->supported_cable;
+ unsigned int cable_type = SM5502_MUIC_ADC_GROUND;
+ unsigned int con_sw = DM_DP_SWITCH_OPEN;
+ unsigned int vbus_sw = VBUSIN_SWITCH_OPEN;
+ unsigned int idx = 0;
+ int ret;
+
+ if (!cable_names)
+ return 0;
+
+ /* Get the type of attached or detached cable */
+ if (attached)
+ cable_type = sm5502_muic_get_cable_type(info);
+ else if (!attached)
+ cable_type = prev_cable_type;
+ prev_cable_type = cable_type;
+
+ switch (cable_type) {
+ case SM5502_MUIC_ADC_OPEN_USB:
+ idx = EXTCON_CABLE_USB;
+ con_sw = DM_DP_SWITCH_USB;
+ vbus_sw = VBUSIN_SWITCH_VBUSOUT_WITH_USB;
+ break;
+ case SM5502_MUIC_ADC_OPEN_TA:
+ idx = EXTCON_CABLE_TA;
+ con_sw = DM_DP_SWITCH_OPEN;
+ vbus_sw = VBUSIN_SWITCH_VBUSOUT;
+ break;
+ case SM5502_MUIC_ADC_OPEN_USB_OTG:
+ idx = EXTCON_CABLE_USB_HOST;
+ con_sw = DM_DP_SWITCH_USB;
+ vbus_sw = VBUSIN_SWITCH_OPEN;
+ break;
+ default:
+ dev_dbg(info->dev,
+ "cannot handle this cable_type (0x%x)\n", cable_type);
+ return 0;
+ };
+
+ /* Change internal hardware path(DM_CON/DP_CON, VBUSIN) */
+ ret = sm5502_muic_set_path(info, con_sw, vbus_sw, attached);
+ if (ret < 0)
+ return ret;
+
+ /* Change the state of external accessory */
+ extcon_set_cable_state(info->edev, cable_names[idx], attached);
+
+ return 0;
+}
+
+static void sm5502_muic_irq_work(struct work_struct *work)
+{
+ struct sm5502_muic_info *info = container_of(work,
+ struct sm5502_muic_info, irq_work);
+ int ret = 0;
+
+ if (!info->edev)
+ return;
+
+ mutex_lock(&info->mutex);
+
+ /* Detect attached or detached cables */
+ if (info->irq_attach) {
+ ret = sm5502_muic_cable_handler(info, true);
+ info->irq_attach = false;
+ }
+ if (info->irq_detach) {
+ ret = sm5502_muic_cable_handler(info, false);
+ info->irq_detach = false;
+ }
+
+ if (ret < 0)
+ dev_err(info->dev, "failed to handle MUIC interrupt\n");
+
+ mutex_unlock(&info->mutex);
+
+ return;
+}
+
+/*
+ * Sets irq_attach or irq_detach in sm5502_muic_info and returns 0.
+ * Returns -ESRCH if irq_type does not match registered IRQ for this dev type.
+ */
+static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
+{
+ switch (irq_type) {
+ case SM5502_IRQ_INT1_ATTACH:
+ info->irq_attach = true;
+ break;
+ case SM5502_IRQ_INT1_DETACH:
+ info->irq_detach = true;
+ break;
+ case SM5502_IRQ_INT1_KP:
+ case SM5502_IRQ_INT1_LKP:
+ case SM5502_IRQ_INT1_LKR:
+ case SM5502_IRQ_INT1_OVP_EVENT:
+ case SM5502_IRQ_INT1_OCP_EVENT:
+ case SM5502_IRQ_INT1_OVP_OCP_DIS:
+ case SM5502_IRQ_INT2_VBUS_DET:
+ case SM5502_IRQ_INT2_REV_ACCE:
+ case SM5502_IRQ_INT2_ADC_CHG:
+ case SM5502_IRQ_INT2_STUCK_KEY:
+ case SM5502_IRQ_INT2_STUCK_KEY_RCV:
+ case SM5502_IRQ_INT2_MHL:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
+{
+ struct sm5502_muic_info *info = data;
+ int i, irq_type = -1, ret;
+
+ for (i = 0; i < info->num_muic_irqs; i++)
+ if (irq == info->muic_irqs[i].virq)
+ irq_type = info->muic_irqs[i].irq;
+
+ ret = sm5502_parse_irq(info, irq_type);
+ if (ret < 0) {
+ dev_warn(info->dev, "cannot handle is interrupt:%d\n",
+ irq_type);
+ return IRQ_HANDLED;
+ }
+ schedule_work(&info->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static void sm5502_muic_detect_cable_wq(struct work_struct *work)
+{
+ struct sm5502_muic_info *info = container_of(to_delayed_work(work),
+ struct sm5502_muic_info, wq_detcable);
+ int ret;
+
+ /* Notify the state of connector cable or not */
+ ret = sm5502_muic_cable_handler(info, true);
+ if (ret < 0)
+ dev_warn(info->dev, "failed to detect cable state\n");
+}
+
+static void sm5502_init_dev_type(struct sm5502_muic_info *info)
+{
+ unsigned int reg_data, vendor_id, version_id;
+ int i, ret;
+
+ /* To test I2C, Print version_id and vendor_id of SM5502 */
+ ret = regmap_read(info->regmap, SM5502_REG_DEVICE_ID, &reg_data);
+ if (ret) {
+ dev_err(info->dev,
+ "failed to read DEVICE_ID register: %d\n", ret);
+ return;
+ }
+
+ vendor_id = ((reg_data & SM5502_REG_DEVICE_ID_VENDOR_MASK) >>
+ SM5502_REG_DEVICE_ID_VENDOR_SHIFT);
+ version_id = ((reg_data & SM5502_REG_DEVICE_ID_VERSION_MASK) >>
+ SM5502_REG_DEVICE_ID_VERSION_SHIFT);
+
+ dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
+ version_id, vendor_id);
+
+ /* Initiazle the register of SM5502 device to bring-up */
+ for (i = 0; i < info->num_reg_data; i++) {
+ unsigned int val = 0;
+
+ if (!info->reg_data[i].invert)
+ val |= ~info->reg_data[i].val;
+ else
+ val = info->reg_data[i].val;
+ regmap_write(info->regmap, info->reg_data[i].reg, val);
+ }
+}
+
+static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = i2c->dev.of_node;
+ struct sm5502_muic_info *info;
+ int i, ret, irq_flags;
+
+ if (!np)
+ return -EINVAL;
+
+ info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ i2c_set_clientdata(i2c, info);
+
+ info->dev = &i2c->dev;
+ info->i2c = i2c;
+ info->irq = i2c->irq;
+ info->muic_irqs = sm5502_muic_irqs;
+ info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
+ info->reg_data = sm5502_reg_data;
+ info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
+
+ mutex_init(&info->mutex);
+
+ INIT_WORK(&info->irq_work, sm5502_muic_irq_work);
+
+ info->regmap = devm_regmap_init_i2c(i2c, &sm5502_muic_regmap_config);
+ if (IS_ERR(info->regmap)) {
+ ret = PTR_ERR(info->regmap);
+ dev_err(info->dev, "failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* Support irq domain for SM5502 MUIC device */
+ irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
+ ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
+ &sm5502_muic_irq_chip, &info->irq_data);
+ if (ret != 0) {
+ dev_err(info->dev, "failed to request IRQ %d: %d\n",
+ info->irq, ret);
+ return ret;
+ }
+
+ for (i = 0; i < info->num_muic_irqs; i++) {
+ struct muic_irq *muic_irq = &info->muic_irqs[i];
+ unsigned int virq = 0;
+
+ virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
+ if (virq <= 0)
+ return -EINVAL;
+ muic_irq->virq = virq;
+
+ ret = devm_request_threaded_irq(info->dev, virq, NULL,
+ sm5502_muic_irq_handler,
+ IRQF_NO_SUSPEND,
+ muic_irq->name, info);
+ if (ret) {
+ dev_err(info->dev, "failed: irq request (IRQ: %d,"
+ " error :%d)\n", muic_irq->irq, ret);
+ return ret;
+ }
+ }
+
+ /* Allocate extcon device */
+ info->edev = devm_extcon_dev_allocate(info->dev, sm5502_extcon_cable);
+ if (IS_ERR(info->edev)) {
+ dev_err(info->dev, "failed to allocate memory for extcon\n");
+ return -ENOMEM;
+ }
+ info->edev->name = np->name;
+
+ /* Register extcon device */
+ ret = devm_extcon_dev_register(info->dev, info->edev);
+ if (ret) {
+ dev_err(info->dev, "failed to register extcon device\n");
+ return ret;
+ }
+
+ /*
+ * Detect accessory after completing the initialization of platform
+ *
+ * - Use delayed workqueue to detect cable state and then
+ * notify cable state to notifiee/platform through uevent.
+ * After completing the booting of platform, the extcon provider
+ * driver should notify cable state to upper layer.
+ */
+ INIT_DELAYED_WORK(&info->wq_detcable, sm5502_muic_detect_cable_wq);
+ queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
+ msecs_to_jiffies(DELAY_MS_DEFAULT));
+
+ /* Initialize SM5502 device and print vendor id and version id */
+ sm5502_init_dev_type(info);
+
+ return 0;
+}
+
+static int sm5502_muic_i2c_remove(struct i2c_client *i2c)
+{
+ struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
+
+ regmap_del_irq_chip(info->irq, info->irq_data);
+
+ return 0;
+}
+
+static struct of_device_id sm5502_dt_match[] = {
+ { .compatible = "siliconmitus,sm5502-muic" },
+ { },
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int sm5502_muic_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
+
+ enable_irq_wake(info->irq);
+
+ return 0;
+}
+
+static int sm5502_muic_resume(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
+
+ disable_irq_wake(info->irq);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
+ sm5502_muic_suspend, sm5502_muic_resume);
+
+static const struct i2c_device_id sm5502_i2c_id[] = {
+ { "sm5502", TYPE_SM5502 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
+
+static struct i2c_driver sm5502_muic_i2c_driver = {
+ .driver = {
+ .name = "sm5502",
+ .owner = THIS_MODULE,
+ .pm = &sm5502_muic_pm_ops,
+ .of_match_table = sm5502_dt_match,
+ },
+ .probe = sm5022_muic_i2c_probe,
+ .remove = sm5502_muic_i2c_remove,
+ .id_table = sm5502_i2c_id,
+};
+
+static int __init sm5502_muic_i2c_init(void)
+{
+ return i2c_add_driver(&sm5502_muic_i2c_driver);
+}
+subsys_initcall(sm5502_muic_i2c_init);
+
+MODULE_DESCRIPTION("Silicon Mitus SM5502 Extcon driver");
+MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index 4199849e3758..145974f9662b 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -1,4 +1,5 @@
menu "IEEE 1394 (FireWire) support"
+ depends on HAS_DMA
depends on PCI || COMPILE_TEST
# firewire-core does not depend on PCI but is
# not useful without PCI controller driver
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index d7d5c8af92b9..5d997a33907e 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1214,9 +1214,9 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME);
switch (a->clk_id) {
- case CLOCK_REALTIME: getnstimeofday(&ts); break;
- case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break;
- case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break;
+ case CLOCK_REALTIME: getnstimeofday(&ts); break;
+ case CLOCK_MONOTONIC: ktime_get_ts(&ts); break;
+ case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break;
default:
ret = -EINVAL;
}
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index c3986452194d..2c68da1ceeee 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -1460,7 +1460,8 @@ static int fwnet_probe(struct fw_unit *unit,
goto have_dev;
}
- net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev);
+ net = alloc_netdev(sizeof(*dev), "firewire%d", NET_NAME_UNKNOWN,
+ fwnet_init_dev);
if (net == NULL) {
mutex_unlock(&fwnet_device_mutex);
return -ENOMEM;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 57985410f12f..a66a3217f1d9 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -336,10 +336,10 @@ static const struct {
QUIRK_CYCLE_TIMER | QUIRK_IR_WAKE},
{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, 0,
- QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
+ QUIRK_CYCLE_TIMER /* FIXME: necessary? */ | QUIRK_NO_MSI},
{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT6315, PCI_ANY_ID,
- 0},
+ QUIRK_NO_MSI},
{PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index d420ae2d3413..f712d47f30d8 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -54,6 +54,12 @@ config EFI_PARAMS_FROM_FDT
the EFI runtime support gets system table address, memory
map address, and other parameters from the device tree.
+config EFI_RUNTIME_WRAPPERS
+ bool
+
+config EFI_ARMSTUB
+ bool
+
endmenu
config UEFI_CPER
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9553496b0f43..d8be608a9f3b 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -1,8 +1,10 @@
#
# Makefile for linux kernel
#
-obj-$(CONFIG_EFI) += efi.o vars.o
+obj-$(CONFIG_EFI) += efi.o vars.o reboot.o
obj-$(CONFIG_EFI_VARS) += efivars.o
obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
obj-$(CONFIG_UEFI_CPER) += cper.o
obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
+obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o
+obj-$(CONFIG_EFI_STUB) += libstub/
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 1491dd4f08f9..5b53d6183b6b 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -34,6 +34,9 @@
#include <linux/aer.h>
#define INDENT_SP " "
+
+static char rcd_decode_str[CPER_REC_LEN];
+
/*
* CPER record ID need to be unique even after reboot, because record
* ID is used as index for ERST storage, while CPER records from
@@ -50,18 +53,19 @@ u64 cper_next_record_id(void)
}
EXPORT_SYMBOL_GPL(cper_next_record_id);
-static const char *cper_severity_strs[] = {
+static const char * const severity_strs[] = {
"recoverable",
"fatal",
"corrected",
"info",
};
-static const char *cper_severity_str(unsigned int severity)
+const char *cper_severity_str(unsigned int severity)
{
- return severity < ARRAY_SIZE(cper_severity_strs) ?
- cper_severity_strs[severity] : "unknown";
+ return severity < ARRAY_SIZE(severity_strs) ?
+ severity_strs[severity] : "unknown";
}
+EXPORT_SYMBOL_GPL(cper_severity_str);
/*
* cper_print_bits - print strings for set bits
@@ -100,32 +104,32 @@ void cper_print_bits(const char *pfx, unsigned int bits,
printk("%s\n", buf);
}
-static const char * const cper_proc_type_strs[] = {
+static const char * const proc_type_strs[] = {
"IA32/X64",
"IA64",
};
-static const char * const cper_proc_isa_strs[] = {
+static const char * const proc_isa_strs[] = {
"IA32",
"IA64",
"X64",
};
-static const char * const cper_proc_error_type_strs[] = {
+static const char * const proc_error_type_strs[] = {
"cache error",
"TLB error",
"bus error",
"micro-architectural error",
};
-static const char * const cper_proc_op_strs[] = {
+static const char * const proc_op_strs[] = {
"unknown or generic",
"data read",
"data write",
"instruction execution",
};
-static const char * const cper_proc_flag_strs[] = {
+static const char * const proc_flag_strs[] = {
"restartable",
"precise IP",
"overflow",
@@ -137,26 +141,26 @@ static void cper_print_proc_generic(const char *pfx,
{
if (proc->validation_bits & CPER_PROC_VALID_TYPE)
printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
- proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
- cper_proc_type_strs[proc->proc_type] : "unknown");
+ proc->proc_type < ARRAY_SIZE(proc_type_strs) ?
+ proc_type_strs[proc->proc_type] : "unknown");
if (proc->validation_bits & CPER_PROC_VALID_ISA)
printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
- proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
- cper_proc_isa_strs[proc->proc_isa] : "unknown");
+ proc->proc_isa < ARRAY_SIZE(proc_isa_strs) ?
+ proc_isa_strs[proc->proc_isa] : "unknown");
if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
cper_print_bits(pfx, proc->proc_error_type,
- cper_proc_error_type_strs,
- ARRAY_SIZE(cper_proc_error_type_strs));
+ proc_error_type_strs,
+ ARRAY_SIZE(proc_error_type_strs));
}
if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
printk("%s""operation: %d, %s\n", pfx, proc->operation,
- proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
- cper_proc_op_strs[proc->operation] : "unknown");
+ proc->operation < ARRAY_SIZE(proc_op_strs) ?
+ proc_op_strs[proc->operation] : "unknown");
if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
printk("%s""flags: 0x%02x\n", pfx, proc->flags);
- cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
- ARRAY_SIZE(cper_proc_flag_strs));
+ cper_print_bits(pfx, proc->flags, proc_flag_strs,
+ ARRAY_SIZE(proc_flag_strs));
}
if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
printk("%s""level: %d\n", pfx, proc->level);
@@ -177,7 +181,7 @@ static void cper_print_proc_generic(const char *pfx,
printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
}
-static const char *cper_mem_err_type_strs[] = {
+static const char * const mem_err_type_strs[] = {
"unknown",
"no error",
"single-bit ECC",
@@ -196,58 +200,136 @@ static const char *cper_mem_err_type_strs[] = {
"physical memory map-out event",
};
-static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
+const char *cper_mem_err_type_str(unsigned int etype)
{
- if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
- printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
- if (mem->validation_bits & CPER_MEM_VALID_PA)
- printk("%s""physical_address: 0x%016llx\n",
- pfx, mem->physical_addr);
- if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
- printk("%s""physical_address_mask: 0x%016llx\n",
- pfx, mem->physical_addr_mask);
+ return etype < ARRAY_SIZE(mem_err_type_strs) ?
+ mem_err_type_strs[etype] : "unknown";
+}
+EXPORT_SYMBOL_GPL(cper_mem_err_type_str);
+
+static int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg)
+{
+ u32 len, n;
+
+ if (!msg)
+ return 0;
+
+ n = 0;
+ len = CPER_REC_LEN - 1;
if (mem->validation_bits & CPER_MEM_VALID_NODE)
- pr_debug("node: %d\n", mem->node);
+ n += scnprintf(msg + n, len - n, "node: %d ", mem->node);
if (mem->validation_bits & CPER_MEM_VALID_CARD)
- pr_debug("card: %d\n", mem->card);
+ n += scnprintf(msg + n, len - n, "card: %d ", mem->card);
if (mem->validation_bits & CPER_MEM_VALID_MODULE)
- pr_debug("module: %d\n", mem->module);
+ n += scnprintf(msg + n, len - n, "module: %d ", mem->module);
if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
- pr_debug("rank: %d\n", mem->rank);
+ n += scnprintf(msg + n, len - n, "rank: %d ", mem->rank);
if (mem->validation_bits & CPER_MEM_VALID_BANK)
- pr_debug("bank: %d\n", mem->bank);
+ n += scnprintf(msg + n, len - n, "bank: %d ", mem->bank);
if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
- pr_debug("device: %d\n", mem->device);
+ n += scnprintf(msg + n, len - n, "device: %d ", mem->device);
if (mem->validation_bits & CPER_MEM_VALID_ROW)
- pr_debug("row: %d\n", mem->row);
+ n += scnprintf(msg + n, len - n, "row: %d ", mem->row);
if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
- pr_debug("column: %d\n", mem->column);
+ n += scnprintf(msg + n, len - n, "column: %d ", mem->column);
if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
- pr_debug("bit_position: %d\n", mem->bit_pos);
+ n += scnprintf(msg + n, len - n, "bit_position: %d ",
+ mem->bit_pos);
if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
- pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
+ n += scnprintf(msg + n, len - n, "requestor_id: 0x%016llx ",
+ mem->requestor_id);
if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
- pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
+ n += scnprintf(msg + n, len - n, "responder_id: 0x%016llx ",
+ mem->responder_id);
if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
- pr_debug("target_id: 0x%016llx\n", mem->target_id);
+ scnprintf(msg + n, len - n, "target_id: 0x%016llx ",
+ mem->target_id);
+
+ msg[n] = '\0';
+ return n;
+}
+
+static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
+{
+ u32 len, n;
+ const char *bank = NULL, *device = NULL;
+
+ if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE))
+ return 0;
+
+ n = 0;
+ len = CPER_REC_LEN - 1;
+ dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
+ if (bank && device)
+ n = snprintf(msg, len, "DIMM location: %s %s ", bank, device);
+ else
+ n = snprintf(msg, len,
+ "DIMM location: not present. DMI handle: 0x%.4x ",
+ mem->mem_dev_handle);
+
+ msg[n] = '\0';
+ return n;
+}
+
+void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
+ struct cper_mem_err_compact *cmem)
+{
+ cmem->validation_bits = mem->validation_bits;
+ cmem->node = mem->node;
+ cmem->card = mem->card;
+ cmem->module = mem->module;
+ cmem->bank = mem->bank;
+ cmem->device = mem->device;
+ cmem->row = mem->row;
+ cmem->column = mem->column;
+ cmem->bit_pos = mem->bit_pos;
+ cmem->requestor_id = mem->requestor_id;
+ cmem->responder_id = mem->responder_id;
+ cmem->target_id = mem->target_id;
+ cmem->rank = mem->rank;
+ cmem->mem_array_handle = mem->mem_array_handle;
+ cmem->mem_dev_handle = mem->mem_dev_handle;
+}
+
+const char *cper_mem_err_unpack(struct trace_seq *p,
+ struct cper_mem_err_compact *cmem)
+{
+ const char *ret = p->buffer + p->len;
+
+ if (cper_mem_err_location(cmem, rcd_decode_str))
+ trace_seq_printf(p, "%s", rcd_decode_str);
+ if (cper_dimm_err_location(cmem, rcd_decode_str))
+ trace_seq_printf(p, "%s", rcd_decode_str);
+ trace_seq_putc(p, '\0');
+
+ return ret;
+}
+
+static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
+{
+ struct cper_mem_err_compact cmem;
+
+ if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
+ printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
+ if (mem->validation_bits & CPER_MEM_VALID_PA)
+ printk("%s""physical_address: 0x%016llx\n",
+ pfx, mem->physical_addr);
+ if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
+ printk("%s""physical_address_mask: 0x%016llx\n",
+ pfx, mem->physical_addr_mask);
+ cper_mem_err_pack(mem, &cmem);
+ if (cper_mem_err_location(&cmem, rcd_decode_str))
+ printk("%s%s\n", pfx, rcd_decode_str);
if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
u8 etype = mem->error_type;
printk("%s""error_type: %d, %s\n", pfx, etype,
- etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
- cper_mem_err_type_strs[etype] : "unknown");
- }
- if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
- const char *bank = NULL, *device = NULL;
- dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
- if (bank != NULL && device != NULL)
- printk("%s""DIMM location: %s %s", pfx, bank, device);
- else
- printk("%s""DIMM DMI handle: 0x%.4x",
- pfx, mem->mem_dev_handle);
+ cper_mem_err_type_str(etype));
}
+ if (cper_dimm_err_location(&cmem, rcd_decode_str))
+ printk("%s%s\n", pfx, rcd_decode_str);
}
-static const char *cper_pcie_port_type_strs[] = {
+static const char * const pcie_port_type_strs[] = {
"PCIe end point",
"legacy PCI end point",
"unknown",
@@ -262,12 +344,12 @@ static const char *cper_pcie_port_type_strs[] = {
};
static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
- const struct acpi_generic_data *gdata)
+ const struct acpi_hest_generic_data *gdata)
{
if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
- pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
- cper_pcie_port_type_strs[pcie->port_type] : "unknown");
+ pcie->port_type < ARRAY_SIZE(pcie_port_type_strs) ?
+ pcie_port_type_strs[pcie->port_type] : "unknown");
if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
printk("%s""version: %d.%d\n", pfx,
pcie->version.major, pcie->version.minor);
@@ -298,7 +380,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
}
static void cper_estatus_print_section(
- const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
+ const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
{
uuid_le *sec_type = (uuid_le *)gdata->section_type;
__u16 severity;
@@ -344,9 +426,9 @@ err_section_too_small:
}
void cper_estatus_print(const char *pfx,
- const struct acpi_generic_status *estatus)
+ const struct acpi_hest_generic_status *estatus)
{
- struct acpi_generic_data *gdata;
+ struct acpi_hest_generic_data *gdata;
unsigned int data_len, gedata_len;
int sec_no = 0;
char newpfx[64];
@@ -359,7 +441,7 @@ void cper_estatus_print(const char *pfx,
"and requires no further action");
printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
data_len = estatus->data_length;
- gdata = (struct acpi_generic_data *)(estatus + 1);
+ gdata = (struct acpi_hest_generic_data *)(estatus + 1);
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length;
@@ -371,10 +453,10 @@ void cper_estatus_print(const char *pfx,
}
EXPORT_SYMBOL_GPL(cper_estatus_print);
-int cper_estatus_check_header(const struct acpi_generic_status *estatus)
+int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
{
if (estatus->data_length &&
- estatus->data_length < sizeof(struct acpi_generic_data))
+ estatus->data_length < sizeof(struct acpi_hest_generic_data))
return -EINVAL;
if (estatus->raw_data_length &&
estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
@@ -384,9 +466,9 @@ int cper_estatus_check_header(const struct acpi_generic_status *estatus)
}
EXPORT_SYMBOL_GPL(cper_estatus_check_header);
-int cper_estatus_check(const struct acpi_generic_status *estatus)
+int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
{
- struct acpi_generic_data *gdata;
+ struct acpi_hest_generic_data *gdata;
unsigned int data_len, gedata_len;
int rc;
@@ -394,7 +476,7 @@ int cper_estatus_check(const struct acpi_generic_status *estatus)
if (rc)
return rc;
data_len = estatus->data_length;
- gdata = (struct acpi_generic_data *)(estatus + 1);
+ gdata = (struct acpi_hest_generic_data *)(estatus + 1);
while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length;
if (gedata_len > data_len - sizeof(*gdata))
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index eff1a2f22f09..64ecbb501c50 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -23,6 +23,7 @@
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/io.h>
+#include <linux/platform_device.h>
struct efi __read_mostly efi = {
.mps = EFI_INVALID_TABLE_ADDR,
@@ -104,16 +105,19 @@ static struct attribute *efi_subsys_attrs[] = {
static umode_t efi_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
- umode_t mode = attr->mode;
-
- if (attr == &efi_attr_fw_vendor.attr)
- return (efi.fw_vendor == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
- else if (attr == &efi_attr_runtime.attr)
- return (efi.runtime == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
- else if (attr == &efi_attr_config_table.attr)
- return (efi.config_table == EFI_INVALID_TABLE_ADDR) ? 0 : mode;
+ if (attr == &efi_attr_fw_vendor.attr) {
+ if (efi_enabled(EFI_PARAVIRT) ||
+ efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
+ return 0;
+ } else if (attr == &efi_attr_runtime.attr) {
+ if (efi.runtime == EFI_INVALID_TABLE_ADDR)
+ return 0;
+ } else if (attr == &efi_attr_config_table.attr) {
+ if (efi.config_table == EFI_INVALID_TABLE_ADDR)
+ return 0;
+ }
- return mode;
+ return attr->mode;
}
static struct attribute_group efi_subsys_attr_group = {
@@ -298,7 +302,7 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
if (table64 >> 32) {
pr_cont("\n");
pr_err("Table located above 4GB, disabling EFI.\n");
- early_iounmap(config_tables,
+ early_memunmap(config_tables,
efi.systab->nr_tables * sz);
return -EINVAL;
}
@@ -314,13 +318,27 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
tablep += sz;
}
pr_cont("\n");
- early_iounmap(config_tables, efi.systab->nr_tables * sz);
+ early_memunmap(config_tables, efi.systab->nr_tables * sz);
set_bit(EFI_CONFIG_TABLES, &efi.flags);
return 0;
}
+#ifdef CONFIG_EFI_VARS_MODULE
+static int __init efi_load_efivars(void)
+{
+ struct platform_device *pdev;
+
+ if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ return 0;
+
+ pdev = platform_device_register_simple("efivars", 0, NULL, 0);
+ return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
+}
+device_initcall(efi_load_efivars);
+#endif
+
#ifdef CONFIG_EFI_PARAMS_FROM_FDT
#define UEFI_PARAM(name, prop, field) \
@@ -346,6 +364,7 @@ static __initdata struct {
struct param_info {
int verbose;
+ int found;
void *params;
};
@@ -362,16 +381,12 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
(strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
return 0;
- pr_info("Getting parameters from FDT:\n");
-
for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
- if (!prop) {
- pr_err("Can't find %s in device tree!\n",
- dt_params[i].name);
+ if (!prop)
return 0;
- }
dest = info->params + dt_params[i].offset;
+ info->found++;
val = of_read_number(prop, len / sizeof(u32));
@@ -390,10 +405,21 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
{
struct param_info info;
+ int ret;
+
+ pr_info("Getting EFI parameters from FDT:\n");
info.verbose = verbose;
+ info.found = 0;
info.params = params;
- return of_scan_flat_dt(fdt_find_uefi_params, &info);
+ ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+ if (!info.found)
+ pr_info("UEFI not found.\n");
+ else if (!ret)
+ pr_err("Can't find '%s' in device tree!\n",
+ dt_params[info.found].name);
+
+ return ret;
}
#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 463c56545ae8..f256ecd8a176 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -78,6 +78,7 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
MODULE_DESCRIPTION("sysfs interface to EFI Variables");
MODULE_LICENSE("GPL");
MODULE_VERSION(EFIVARS_VERSION);
+MODULE_ALIAS("platform:efivars");
LIST_HEAD(efivar_sysfs_list);
EXPORT_SYMBOL_GPL(efivar_sysfs_list);
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
new file mode 100644
index 000000000000..b14bc2b9fb4d
--- /dev/null
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -0,0 +1,26 @@
+#
+# The stub may be linked into the kernel proper or into a separate boot binary,
+# but in either case, it executes before the kernel does (with MMU disabled) so
+# things like ftrace and stack-protector are likely to cause trouble if left
+# enabled, even if doing so doesn't break the build.
+#
+cflags-$(CONFIG_X86_32) := -march=i386
+cflags-$(CONFIG_X86_64) := -mcmodel=small
+cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+ -fPIC -fno-strict-aliasing -mno-red-zone \
+ -mno-mmx -mno-sse -DDISABLE_BRANCH_PROFILING
+
+cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS))
+cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \
+ -fno-builtin -fpic -mno-single-pic-base
+
+KBUILD_CFLAGS := $(cflags-y) \
+ $(call cc-option,-ffreestanding) \
+ $(call cc-option,-fno-stack-protector)
+
+GCOV_PROFILE := n
+
+lib-y := efi-stub-helper.o
+lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o
+
+CFLAGS_fdt.o += -I$(srctree)/scripts/dtc/libfdt/
diff --git a/drivers/firmware/efi/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 41114ce03b01..480339b6b110 100644
--- a/drivers/firmware/efi/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -12,6 +12,11 @@
*
*/
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
static int __init efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
{
static efi_guid_t const var_guid __initconst = EFI_GLOBAL_VARIABLE_GUID;
@@ -36,8 +41,8 @@ static int __init efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
}
}
-static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
- void *__image, void **__fh)
+efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
+ void *__image, void **__fh)
{
efi_file_io_interface_t *io;
efi_loaded_image_t *image = __image;
@@ -60,14 +65,15 @@ static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
*__fh = fh;
return status;
}
-static efi_status_t efi_file_close(void *handle)
+
+efi_status_t efi_file_close(void *handle)
{
efi_file_handle_t *fh = handle;
return fh->close(handle);
}
-static efi_status_t
+efi_status_t
efi_file_read(void *handle, unsigned long *size, void *addr)
{
efi_file_handle_t *fh = handle;
@@ -76,7 +82,7 @@ efi_file_read(void *handle, unsigned long *size, void *addr)
}
-static efi_status_t
+efi_status_t
efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
efi_char16_t *filename_16, void **handle, u64 *file_sz)
{
@@ -129,7 +135,7 @@ grow:
-static void efi_char16_printk(efi_system_table_t *sys_table_arg,
+void efi_char16_printk(efi_system_table_t *sys_table_arg,
efi_char16_t *str)
{
struct efi_simple_text_output_protocol *out;
@@ -145,13 +151,13 @@ static void efi_char16_printk(efi_system_table_t *sys_table_arg,
* must be reserved. On failure it is required to free all
* all allocations it has made.
*/
-static efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
- unsigned long *image_addr,
- unsigned long *image_size,
- unsigned long *reserve_addr,
- unsigned long *reserve_size,
- unsigned long dram_base,
- efi_loaded_image_t *image);
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
+ unsigned long *image_addr,
+ unsigned long *image_size,
+ unsigned long *reserve_addr,
+ unsigned long *reserve_size,
+ unsigned long dram_base,
+ efi_loaded_image_t *image);
/*
* EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
* that is described in the PE/COFF header. Most of the code is the same
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index eb6d4be9e722..32d5cca30f49 100644
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -9,18 +9,20 @@
* under the terms of the GNU General Public License version 2.
*
*/
-#define EFI_READ_CHUNK_SIZE (1024 * 1024)
-/* error code which can't be mistaken for valid address */
-#define EFI_ERROR (~0UL)
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+#define EFI_READ_CHUNK_SIZE (1024 * 1024)
struct file_info {
efi_file_handle_t *handle;
u64 size;
};
-static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
+void efi_printk(efi_system_table_t *sys_table_arg, char *str)
{
char *s8;
@@ -37,16 +39,12 @@ static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
}
}
-#define pr_efi(sys_table, msg) efi_printk(sys_table, "EFI stub: "msg)
-#define pr_efi_err(sys_table, msg) efi_printk(sys_table, "EFI stub: ERROR: "msg)
-
-
-static efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
- efi_memory_desc_t **map,
- unsigned long *map_size,
- unsigned long *desc_size,
- u32 *desc_ver,
- unsigned long *key_ptr)
+efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
+ efi_memory_desc_t **map,
+ unsigned long *map_size,
+ unsigned long *desc_size,
+ u32 *desc_ver,
+ unsigned long *key_ptr)
{
efi_memory_desc_t *m = NULL;
efi_status_t status;
@@ -88,7 +86,7 @@ fail:
}
-static unsigned long __init get_dram_base(efi_system_table_t *sys_table_arg)
+unsigned long __init get_dram_base(efi_system_table_t *sys_table_arg)
{
efi_status_t status;
unsigned long map_size;
@@ -116,9 +114,9 @@ static unsigned long __init get_dram_base(efi_system_table_t *sys_table_arg)
/*
* Allocate at the highest possible address that is not above 'max'.
*/
-static efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
- unsigned long size, unsigned long align,
- unsigned long *addr, unsigned long max)
+efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
+ unsigned long size, unsigned long align,
+ unsigned long *addr, unsigned long max)
{
unsigned long map_size, desc_size;
efi_memory_desc_t *map;
@@ -202,9 +200,9 @@ fail:
/*
* Allocate at the lowest possible address.
*/
-static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
- unsigned long size, unsigned long align,
- unsigned long *addr)
+efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
+ unsigned long size, unsigned long align,
+ unsigned long *addr)
{
unsigned long map_size, desc_size;
efi_memory_desc_t *map;
@@ -271,8 +269,8 @@ fail:
return status;
}
-static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
- unsigned long addr)
+void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
+ unsigned long addr)
{
unsigned long nr_pages;
@@ -290,12 +288,12 @@ static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
* We only support loading a file from the same filesystem as
* the kernel image.
*/
-static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
- efi_loaded_image_t *image,
- char *cmd_line, char *option_string,
- unsigned long max_addr,
- unsigned long *load_addr,
- unsigned long *load_size)
+efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
+ efi_loaded_image_t *image,
+ char *cmd_line, char *option_string,
+ unsigned long max_addr,
+ unsigned long *load_addr,
+ unsigned long *load_size)
{
struct file_info *files;
unsigned long file_addr;
@@ -477,12 +475,12 @@ fail:
* address is not available the lowest available address will
* be used.
*/
-static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
- unsigned long *image_addr,
- unsigned long image_size,
- unsigned long alloc_size,
- unsigned long preferred_addr,
- unsigned long alignment)
+efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
+ unsigned long *image_addr,
+ unsigned long image_size,
+ unsigned long alloc_size,
+ unsigned long preferred_addr,
+ unsigned long alignment)
{
unsigned long cur_image_addr;
unsigned long new_addr = 0;
@@ -589,9 +587,9 @@ static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
* Size of memory allocated return in *cmd_line_len.
* Returns NULL on error.
*/
-static char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
- efi_loaded_image_t *image,
- int *cmd_line_len)
+char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
+ efi_loaded_image_t *image,
+ int *cmd_line_len)
{
const u16 *s2;
u8 *s1 = NULL;
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
new file mode 100644
index 000000000000..304ab295ca1a
--- /dev/null
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -0,0 +1,42 @@
+
+#ifndef _DRIVERS_FIRMWARE_EFI_EFISTUB_H
+#define _DRIVERS_FIRMWARE_EFI_EFISTUB_H
+
+/* error code which can't be mistaken for valid address */
+#define EFI_ERROR (~0UL)
+
+void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
+
+efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
+ void **__fh);
+
+efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
+ efi_char16_t *filename_16, void **handle,
+ u64 *file_sz);
+
+efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr);
+
+efi_status_t efi_file_close(void *handle);
+
+unsigned long get_dram_base(efi_system_table_t *sys_table_arg);
+
+efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+ unsigned long orig_fdt_size,
+ void *fdt, int new_fdt_size, char *cmdline_ptr,
+ u64 initrd_addr, u64 initrd_size,
+ efi_memory_desc_t *memory_map,
+ unsigned long map_size, unsigned long desc_size,
+ u32 desc_ver);
+
+efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
+ void *handle,
+ unsigned long *new_fdt_addr,
+ unsigned long max_addr,
+ u64 initrd_addr, u64 initrd_size,
+ char *cmdline_ptr,
+ unsigned long fdt_addr,
+ unsigned long fdt_size);
+
+void *get_fdt(efi_system_table_t *sys_table);
+
+#endif
diff --git a/drivers/firmware/efi/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 82d774161cc9..a56bb3528755 100644
--- a/drivers/firmware/efi/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -10,29 +10,23 @@
*
*/
-static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
- unsigned long orig_fdt_size,
- void *fdt, int new_fdt_size, char *cmdline_ptr,
- u64 initrd_addr, u64 initrd_size,
- efi_memory_desc_t *memory_map,
- unsigned long map_size, unsigned long desc_size,
- u32 desc_ver)
+#include <linux/efi.h>
+#include <linux/libfdt.h>
+#include <asm/efi.h>
+
+efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+ unsigned long orig_fdt_size,
+ void *fdt, int new_fdt_size, char *cmdline_ptr,
+ u64 initrd_addr, u64 initrd_size,
+ efi_memory_desc_t *memory_map,
+ unsigned long map_size, unsigned long desc_size,
+ u32 desc_ver)
{
int node, prev;
int status;
u32 fdt_val32;
u64 fdt_val64;
- /*
- * Copy definition of linux_banner here. Since this code is
- * built as part of the decompressor for ARM v7, pulling
- * in version.c where linux_banner is defined for the
- * kernel brings other kernel dependencies with it.
- */
- const char linux_banner[] =
- "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
- LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
-
/* Do some checks on provided FDT, if it exists*/
if (orig_fdt) {
if (fdt_check_header(orig_fdt)) {
@@ -265,7 +259,7 @@ fail:
return EFI_LOAD_ERROR;
}
-static void *get_fdt(efi_system_table_t *sys_table)
+void *get_fdt(efi_system_table_t *sys_table)
{
efi_guid_t fdt_guid = DEVICE_TREE_GUID;
efi_config_table_t *tables;
diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
new file mode 100644
index 000000000000..9c59d1c795d1
--- /dev/null
+++ b/drivers/firmware/efi/reboot.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Intel Corporation; author Matt Fleming
+ * Copyright (c) 2014 Red Hat, Inc., Mark Salter <msalter@redhat.com>
+ */
+#include <linux/efi.h>
+#include <linux/reboot.h>
+
+int efi_reboot_quirk_mode = -1;
+
+void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
+{
+ int efi_mode;
+
+ if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ return;
+
+ switch (reboot_mode) {
+ case REBOOT_WARM:
+ case REBOOT_SOFT:
+ efi_mode = EFI_RESET_WARM;
+ break;
+ default:
+ efi_mode = EFI_RESET_COLD;
+ break;
+ }
+
+ /*
+ * If a quirk forced an EFI reset mode, always use that.
+ */
+ if (efi_reboot_quirk_mode != -1)
+ efi_mode = efi_reboot_quirk_mode;
+
+ efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL);
+}
+
+bool __weak efi_poweroff_required(void)
+{
+ return false;
+}
+
+static void efi_power_off(void)
+{
+ efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
+}
+
+static int __init efi_shutdown_init(void)
+{
+ if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ return -ENODEV;
+
+ if (efi_poweroff_required())
+ pm_power_off = efi_power_off;
+
+ return 0;
+}
+late_initcall(efi_shutdown_init);
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
new file mode 100644
index 000000000000..10daa4bbb258
--- /dev/null
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -0,0 +1,161 @@
+/*
+ * runtime-wrappers.c - Runtime Services function call wrappers
+ *
+ * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * Split off from arch/x86/platform/efi/efi.c
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 2005-2008 Intel Co.
+ * Copyright (C) 2013 SuSE Labs
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/efi.h>
+#include <linux/spinlock.h> /* spinlock_t */
+#include <asm/efi.h>
+
+/*
+ * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
+ * the EFI specification requires that callers of the time related runtime
+ * functions serialize with other CMOS accesses in the kernel, as the EFI time
+ * functions may choose to also use the legacy CMOS RTC.
+ */
+__weak DEFINE_SPINLOCK(rtc_lock);
+
+static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+{
+ unsigned long flags;
+ efi_status_t status;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ status = efi_call_virt(get_time, tm, tc);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return status;
+}
+
+static efi_status_t virt_efi_set_time(efi_time_t *tm)
+{
+ unsigned long flags;
+ efi_status_t status;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ status = efi_call_virt(set_time, tm);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return status;
+}
+
+static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
+ efi_bool_t *pending,
+ efi_time_t *tm)
+{
+ unsigned long flags;
+ efi_status_t status;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return status;
+}
+
+static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+{
+ unsigned long flags;
+ efi_status_t status;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ status = efi_call_virt(set_wakeup_time, enabled, tm);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return status;
+}
+
+static efi_status_t virt_efi_get_variable(efi_char16_t *name,
+ efi_guid_t *vendor,
+ u32 *attr,
+ unsigned long *data_size,
+ void *data)
+{
+ return efi_call_virt(get_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
+ efi_char16_t *name,
+ efi_guid_t *vendor)
+{
+ return efi_call_virt(get_next_variable, name_size, name, vendor);
+}
+
+static efi_status_t virt_efi_set_variable(efi_char16_t *name,
+ efi_guid_t *vendor,
+ u32 attr,
+ unsigned long data_size,
+ void *data)
+{
+ return efi_call_virt(set_variable, name, vendor, attr, data_size, data);
+}
+
+static efi_status_t virt_efi_query_variable_info(u32 attr,
+ u64 *storage_space,
+ u64 *remaining_space,
+ u64 *max_variable_size)
+{
+ if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+ return EFI_UNSUPPORTED;
+
+ return efi_call_virt(query_variable_info, attr, storage_space,
+ remaining_space, max_variable_size);
+}
+
+static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
+{
+ return efi_call_virt(get_next_high_mono_count, count);
+}
+
+static void virt_efi_reset_system(int reset_type,
+ efi_status_t status,
+ unsigned long data_size,
+ efi_char16_t *data)
+{
+ __efi_call_virt(reset_system, reset_type, status, data_size, data);
+}
+
+static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
+ unsigned long count,
+ unsigned long sg_list)
+{
+ if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+ return EFI_UNSUPPORTED;
+
+ return efi_call_virt(update_capsule, capsules, count, sg_list);
+}
+
+static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+ unsigned long count,
+ u64 *max_size,
+ int *reset_type)
+{
+ if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+ return EFI_UNSUPPORTED;
+
+ return efi_call_virt(query_capsule_caps, capsules, count, max_size,
+ reset_type);
+}
+
+void efi_native_runtime_setup(void)
+{
+ efi.get_time = virt_efi_get_time;
+ efi.set_time = virt_efi_set_time;
+ efi.get_wakeup_time = virt_efi_get_wakeup_time;
+ efi.set_wakeup_time = virt_efi_set_wakeup_time;
+ efi.get_variable = virt_efi_get_variable;
+ efi.get_next_variable = virt_efi_get_next_variable;
+ efi.set_variable = virt_efi_set_variable;
+ efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
+ efi.reset_system = virt_efi_reset_system;
+ efi.query_variable_info = virt_efi_query_variable_info;
+ efi.update_capsule = virt_efi_update_capsule;
+ efi.query_capsule_caps = virt_efi_query_capsule_caps;
+}
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 17cf96c45f2b..79f18e6d9c4f 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -286,7 +286,11 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
struct firmware_map_entry *entry;
- entry = firmware_map_find_entry_bootmem(start, end, type);
+ entry = firmware_map_find_entry(start, end - 1, type);
+ if (entry)
+ return 0;
+
+ entry = firmware_map_find_entry_bootmem(start, end - 1, type);
if (!entry) {
entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
if (!entry)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4a1b5113e527..4a065b45330f 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -450,6 +450,19 @@ config GPIO_ARIZONA
help
Support for GPIOs on Wolfson Arizona class devices.
+config GPIO_CRYSTAL_COVE
+ tristate "GPIO support for Crystal Cove PMIC"
+ depends on INTEL_SOC_PMIC
+ select GPIOLIB_IRQCHIP
+ help
+ Support for GPIO pins on Crystal Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Crystal Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-crystalcove.
+
config GPIO_LP3943
tristate "TI/National Semiconductor LP3943 GPIO expander"
depends on MFD_LP3943
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d10f6a9d875a..e18e9564b073 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o
+obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o
obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o
obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c
new file mode 100644
index 000000000000..934462f5bd22
--- /dev/null
+++ b/drivers/gpio/gpio-crystalcove.c
@@ -0,0 +1,380 @@
+/*
+ * gpio-crystalcove.c - Intel Crystal Cove GPIO Driver
+ *
+ * Copyright (C) 2012, 2014 Intel 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 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.
+ *
+ * Author: Yang, Bin <bin.yang@intel.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/seq_file.h>
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <linux/mfd/intel_soc_pmic.h>
+
+#define CRYSTALCOVE_GPIO_NUM 16
+
+#define UPDATE_IRQ_TYPE BIT(0)
+#define UPDATE_IRQ_MASK BIT(1)
+
+#define GPIO0IRQ 0x0b
+#define GPIO1IRQ 0x0c
+#define MGPIO0IRQS0 0x19
+#define MGPIO1IRQS0 0x1a
+#define MGPIO0IRQSX 0x1b
+#define MGPIO1IRQSX 0x1c
+#define GPIO0P0CTLO 0x2b
+#define GPIO0P0CTLI 0x33
+#define GPIO1P0CTLO 0x3b
+#define GPIO1P0CTLI 0x43
+
+#define CTLI_INTCNT_DIS (0)
+#define CTLI_INTCNT_NE (1 << 1)
+#define CTLI_INTCNT_PE (2 << 1)
+#define CTLI_INTCNT_BE (3 << 1)
+
+#define CTLO_DIR_IN (0)
+#define CTLO_DIR_OUT (1 << 5)
+
+#define CTLO_DRV_CMOS (0)
+#define CTLO_DRV_OD (1 << 4)
+
+#define CTLO_DRV_REN (1 << 3)
+
+#define CTLO_RVAL_2KDW (0)
+#define CTLO_RVAL_2KUP (1 << 1)
+#define CTLO_RVAL_50KDW (2 << 1)
+#define CTLO_RVAL_50KUP (3 << 1)
+
+#define CTLO_INPUT_SET (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
+#define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET)
+
+enum ctrl_register {
+ CTRL_IN,
+ CTRL_OUT,
+};
+
+/**
+ * struct crystalcove_gpio - Crystal Cove GPIO controller
+ * @buslock: for bus lock/sync and unlock.
+ * @chip: the abstract gpio_chip structure.
+ * @regmap: the regmap from the parent device.
+ * @update: pending IRQ setting update, to be written to the chip upon unlock.
+ * @intcnt_value: the Interrupt Detect value to be written.
+ * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
+ */
+struct crystalcove_gpio {
+ struct mutex buslock; /* irq_bus_lock */
+ struct gpio_chip chip;
+ struct regmap *regmap;
+ int update;
+ int intcnt_value;
+ bool set_irq_mask;
+};
+
+static inline struct crystalcove_gpio *to_cg(struct gpio_chip *gc)
+{
+ return container_of(gc, struct crystalcove_gpio, chip);
+}
+
+static inline int to_reg(int gpio, enum ctrl_register reg_type)
+{
+ int reg;
+
+ if (reg_type == CTRL_IN) {
+ if (gpio < 8)
+ reg = GPIO0P0CTLI;
+ else
+ reg = GPIO1P0CTLI;
+ } else {
+ if (gpio < 8)
+ reg = GPIO0P0CTLO;
+ else
+ reg = GPIO1P0CTLO;
+ }
+
+ return reg + gpio % 8;
+}
+
+static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg,
+ int gpio)
+{
+ u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0;
+ int mask = BIT(gpio % 8);
+
+ if (cg->set_irq_mask)
+ regmap_update_bits(cg->regmap, mirqs0, mask, mask);
+ else
+ regmap_update_bits(cg->regmap, mirqs0, mask, 0);
+}
+
+static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio)
+{
+ int reg = to_reg(gpio, CTRL_IN);
+
+ regmap_update_bits(cg->regmap, reg, CTLI_INTCNT_BE, cg->intcnt_value);
+}
+
+static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio)
+{
+ struct crystalcove_gpio *cg = to_cg(chip);
+
+ return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
+ CTLO_INPUT_SET);
+}
+
+static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio,
+ int value)
+{
+ struct crystalcove_gpio *cg = to_cg(chip);
+
+ return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT),
+ CTLO_OUTPUT_SET | value);
+}
+
+static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ struct crystalcove_gpio *cg = to_cg(chip);
+ int ret;
+ unsigned int val;
+
+ ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val);
+ if (ret)
+ return ret;
+
+ return val & 0x1;
+}
+
+static void crystalcove_gpio_set(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct crystalcove_gpio *cg = to_cg(chip);
+
+ if (value)
+ regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1);
+ else
+ regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 0);
+}
+
+static int crystalcove_irq_type(struct irq_data *data, unsigned type)
+{
+ struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data));
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ cg->intcnt_value = CTLI_INTCNT_DIS;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ cg->intcnt_value = CTLI_INTCNT_BE;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ cg->intcnt_value = CTLI_INTCNT_PE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ cg->intcnt_value = CTLI_INTCNT_NE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ cg->update |= UPDATE_IRQ_TYPE;
+
+ return 0;
+}
+
+static void crystalcove_bus_lock(struct irq_data *data)
+{
+ struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data));
+
+ mutex_lock(&cg->buslock);
+}
+
+static void crystalcove_bus_sync_unlock(struct irq_data *data)
+{
+ struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data));
+ int gpio = data->hwirq;
+
+ if (cg->update & UPDATE_IRQ_TYPE)
+ crystalcove_update_irq_ctrl(cg, gpio);
+ if (cg->update & UPDATE_IRQ_MASK)
+ crystalcove_update_irq_mask(cg, gpio);
+ cg->update = 0;
+
+ mutex_unlock(&cg->buslock);
+}
+
+static void crystalcove_irq_unmask(struct irq_data *data)
+{
+ struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data));
+
+ cg->set_irq_mask = false;
+ cg->update |= UPDATE_IRQ_MASK;
+}
+
+static void crystalcove_irq_mask(struct irq_data *data)
+{
+ struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data));
+
+ cg->set_irq_mask = true;
+ cg->update |= UPDATE_IRQ_MASK;
+}
+
+static struct irq_chip crystalcove_irqchip = {
+ .name = "Crystal Cove",
+ .irq_mask = crystalcove_irq_mask,
+ .irq_unmask = crystalcove_irq_unmask,
+ .irq_set_type = crystalcove_irq_type,
+ .irq_bus_lock = crystalcove_bus_lock,
+ .irq_bus_sync_unlock = crystalcove_bus_sync_unlock,
+};
+
+static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
+{
+ struct crystalcove_gpio *cg = data;
+ unsigned int p0, p1;
+ int pending;
+ int gpio;
+ unsigned int virq;
+
+ if (regmap_read(cg->regmap, GPIO0IRQ, &p0) ||
+ regmap_read(cg->regmap, GPIO1IRQ, &p1))
+ return IRQ_NONE;
+
+ regmap_write(cg->regmap, GPIO0IRQ, p0);
+ regmap_write(cg->regmap, GPIO1IRQ, p1);
+
+ pending = p0 | p1 << 8;
+
+ for (gpio = 0; gpio < cg->chip.ngpio; gpio++) {
+ if (pending & BIT(gpio)) {
+ virq = irq_find_mapping(cg->chip.irqdomain, gpio);
+ generic_handle_irq(virq);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void crystalcove_gpio_dbg_show(struct seq_file *s,
+ struct gpio_chip *chip)
+{
+ struct crystalcove_gpio *cg = to_cg(chip);
+ int gpio, offset;
+ unsigned int ctlo, ctli, mirqs0, mirqsx, irq;
+
+ for (gpio = 0; gpio < cg->chip.ngpio; gpio++) {
+ regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
+ regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli);
+ regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0,
+ &mirqs0);
+ regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQSX : MGPIO1IRQSX,
+ &mirqsx);
+ regmap_read(cg->regmap, gpio < 8 ? GPIO0IRQ : GPIO1IRQ,
+ &irq);
+
+ offset = gpio % 8;
+ seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s %s\n",
+ gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ",
+ ctli & 0x1 ? "hi" : "lo",
+ ctli & CTLI_INTCNT_NE ? "fall" : " ",
+ ctli & CTLI_INTCNT_PE ? "rise" : " ",
+ ctlo,
+ mirqs0 & BIT(offset) ? "s0 mask " : "s0 unmask",
+ mirqsx & BIT(offset) ? "sx mask " : "sx unmask",
+ irq & BIT(offset) ? "pending" : " ");
+ }
+}
+
+static int crystalcove_gpio_probe(struct platform_device *pdev)
+{
+ int irq = platform_get_irq(pdev, 0);
+ struct crystalcove_gpio *cg;
+ int retval;
+ struct device *dev = pdev->dev.parent;
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
+
+ if (irq < 0)
+ return irq;
+
+ cg = devm_kzalloc(&pdev->dev, sizeof(*cg), GFP_KERNEL);
+ if (!cg)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, cg);
+
+ mutex_init(&cg->buslock);
+ cg->chip.label = KBUILD_MODNAME;
+ cg->chip.direction_input = crystalcove_gpio_dir_in;
+ cg->chip.direction_output = crystalcove_gpio_dir_out;
+ cg->chip.get = crystalcove_gpio_get;
+ cg->chip.set = crystalcove_gpio_set;
+ cg->chip.base = -1;
+ cg->chip.ngpio = CRYSTALCOVE_GPIO_NUM;
+ cg->chip.can_sleep = true;
+ cg->chip.dev = dev;
+ cg->chip.dbg_show = crystalcove_gpio_dbg_show;
+ cg->regmap = pmic->regmap;
+
+ retval = gpiochip_add(&cg->chip);
+ if (retval) {
+ dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval);
+ return retval;
+ }
+
+ gpiochip_irqchip_add(&cg->chip, &crystalcove_irqchip, 0,
+ handle_simple_irq, IRQ_TYPE_NONE);
+
+ retval = request_threaded_irq(irq, NULL, crystalcove_gpio_irq_handler,
+ IRQF_ONESHOT, KBUILD_MODNAME, cg);
+
+ if (retval) {
+ dev_warn(&pdev->dev, "request irq failed: %d\n", retval);
+ goto out_remove_gpio;
+ }
+
+ return 0;
+
+out_remove_gpio:
+ WARN_ON(gpiochip_remove(&cg->chip));
+ return retval;
+}
+
+static int crystalcove_gpio_remove(struct platform_device *pdev)
+{
+ struct crystalcove_gpio *cg = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+ int err;
+
+ err = gpiochip_remove(&cg->chip);
+
+ if (irq >= 0)
+ free_irq(irq, cg);
+
+ return err;
+}
+
+static struct platform_driver crystalcove_gpio_driver = {
+ .probe = crystalcove_gpio_probe,
+ .remove = crystalcove_gpio_remove,
+ .driver = {
+ .name = "crystal_cove_gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(crystalcove_gpio_driver);
+
+MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>");
+MODULE_DESCRIPTION("Intel Crystal Cove GPIO Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c
index fe7c0e211f9a..57adbc90fdad 100644
--- a/drivers/gpio/gpio-mcp23s08.c
+++ b/drivers/gpio/gpio-mcp23s08.c
@@ -900,8 +900,6 @@ static int mcp23s08_probe(struct spi_device *spi)
if (spi_present_mask & (1 << addr))
chips++;
}
- if (!chips)
- return -ENODEV;
} else {
type = spi_get_device_id(spi)->driver_data;
pdata = dev_get_platdata(&spi->dev);
@@ -940,10 +938,6 @@ static int mcp23s08_probe(struct spi_device *spi)
if (!(spi_present_mask & (1 << addr)))
continue;
chips--;
- if (chips < 0) {
- dev_err(&spi->dev, "FATAL: invalid negative chip id\n");
- goto fail;
- }
data->mcp[addr] = &data->chip[chips];
status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
0x40 | (addr << 1), type, base,
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index 0c9f803fc1ac..b6ae89ea8811 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -284,6 +284,7 @@ static int gpio_rcar_irq_domain_map(struct irq_domain *h, unsigned int irq,
static struct irq_domain_ops gpio_rcar_irq_domain_ops = {
.map = gpio_rcar_irq_domain_map,
+ .xlate = irq_domain_xlate_twocell,
};
struct gpio_rcar_info {
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 07105ee5c9ae..3810da47043f 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -32,10 +32,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
-
-#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
#include <mach/gpio-samsung.h>
-#endif
#include <plat/cpu.h>
#include <plat/gpio-core.h>
@@ -358,47 +355,6 @@ static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
}
#endif
-#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
-static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
- unsigned int off, unsigned int cfg)
-{
- void __iomem *reg = chip->base;
- unsigned int shift;
- u32 con;
-
- switch (off) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- shift = (off & 7) * 4;
- reg -= 4;
- break;
- case 6:
- shift = ((off + 1) & 7) * 4;
- reg -= 4;
- break;
- default:
- shift = ((off + 1) & 7) * 4;
- break;
- }
-
- if (samsung_gpio_is_cfg_special(cfg)) {
- cfg &= 0xf;
- cfg <<= shift;
- }
-
- con = __raw_readl(reg);
- con &= ~(0xf << shift);
- con |= cfg;
- __raw_writel(con, reg);
-
- return 0;
-}
-#endif
-
static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
int nr_chips)
{
@@ -426,16 +382,6 @@ static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
};
#endif
-#if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
-static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
- .cfg_eint = 0x3,
- .set_config = s5p64x0_gpio_setcfg_rbank,
- .get_config = samsung_gpio_getcfg_4bit,
- .set_pull = samsung_gpio_setpull_updown,
- .get_pull = samsung_gpio_getpull_updown,
-};
-#endif
-
static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
[0] = {
.cfg_eint = 0x0,
@@ -708,91 +654,6 @@ static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
}
#endif
-/* The next set of routines are for the case of s5p64x0 bank r */
-
-static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
- unsigned int offset)
-{
- struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
- void __iomem *base = ourchip->base;
- void __iomem *regcon = base;
- unsigned long con;
- unsigned long flags;
-
- switch (offset) {
- case 6:
- offset += 1;
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- regcon -= 4;
- break;
- default:
- offset -= 7;
- break;
- }
-
- samsung_gpio_lock(ourchip, flags);
-
- con = __raw_readl(regcon);
- con &= ~(0xf << con_4bit_shift(offset));
- __raw_writel(con, regcon);
-
- samsung_gpio_unlock(ourchip, flags);
-
- return 0;
-}
-
-static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
- void __iomem *base = ourchip->base;
- void __iomem *regcon = base;
- unsigned long con;
- unsigned long dat;
- unsigned long flags;
- unsigned con_offset = offset;
-
- switch (con_offset) {
- case 6:
- con_offset += 1;
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- regcon -= 4;
- break;
- default:
- con_offset -= 7;
- break;
- }
-
- samsung_gpio_lock(ourchip, flags);
-
- con = __raw_readl(regcon);
- con &= ~(0xf << con_4bit_shift(con_offset));
- con |= 0x1 << con_4bit_shift(con_offset);
-
- dat = __raw_readl(base + GPIODAT_OFF);
- if (value)
- dat |= 1 << offset;
- else
- dat &= ~(1 << offset);
-
- __raw_writel(con, regcon);
- __raw_writel(dat, base + GPIODAT_OFF);
-
- samsung_gpio_unlock(ourchip, flags);
-
- return 0;
-}
-
static void samsung_gpiolib_set(struct gpio_chip *chip,
unsigned offset, int value)
{
@@ -999,20 +860,6 @@ static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chi
}
}
-static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
- int nr_chips)
-{
- for (; nr_chips > 0; nr_chips--, chip++) {
- chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
- chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
-
- if (!chip->pm)
- chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
-
- samsung_gpiolib_add(chip);
- }
-}
-
int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
@@ -1319,773 +1166,9 @@ static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
#endif
};
-/*
- * S5P6440 GPIO bank summary:
- *
- * Bank GPIOs Style SlpCon ExtInt Group
- * A 6 4Bit Yes 1
- * B 7 4Bit Yes 1
- * C 8 4Bit Yes 2
- * F 2 2Bit Yes 4 [1]
- * G 7 4Bit Yes 5
- * H 10 4Bit[2] Yes 6
- * I 16 2Bit Yes None
- * J 12 2Bit Yes None
- * N 16 2Bit No IRQ_EINT
- * P 8 2Bit Yes 8
- * R 15 4Bit[2] Yes 8
- */
-
-static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
-#ifdef CONFIG_CPU_S5P6440
- {
- .chip = {
- .base = S5P6440_GPA(0),
- .ngpio = S5P6440_GPIO_A_NR,
- .label = "GPA",
- },
- }, {
- .chip = {
- .base = S5P6440_GPB(0),
- .ngpio = S5P6440_GPIO_B_NR,
- .label = "GPB",
- },
- }, {
- .chip = {
- .base = S5P6440_GPC(0),
- .ngpio = S5P6440_GPIO_C_NR,
- .label = "GPC",
- },
- }, {
- .base = S5P64X0_GPG_BASE,
- .chip = {
- .base = S5P6440_GPG(0),
- .ngpio = S5P6440_GPIO_G_NR,
- .label = "GPG",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
-#ifdef CONFIG_CPU_S5P6440
- {
- .base = S5P64X0_GPH_BASE + 0x4,
- .chip = {
- .base = S5P6440_GPH(0),
- .ngpio = S5P6440_GPIO_H_NR,
- .label = "GPH",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
-#ifdef CONFIG_CPU_S5P6440
- {
- .base = S5P64X0_GPR_BASE + 0x4,
- .config = &s5p64x0_gpio_cfg_rbank,
- .chip = {
- .base = S5P6440_GPR(0),
- .ngpio = S5P6440_GPIO_R_NR,
- .label = "GPR",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
-#ifdef CONFIG_CPU_S5P6440
- {
- .base = S5P64X0_GPF_BASE,
- .config = &samsung_gpio_cfgs[6],
- .chip = {
- .base = S5P6440_GPF(0),
- .ngpio = S5P6440_GPIO_F_NR,
- .label = "GPF",
- },
- }, {
- .base = S5P64X0_GPI_BASE,
- .config = &samsung_gpio_cfgs[4],
- .chip = {
- .base = S5P6440_GPI(0),
- .ngpio = S5P6440_GPIO_I_NR,
- .label = "GPI",
- },
- }, {
- .base = S5P64X0_GPJ_BASE,
- .config = &samsung_gpio_cfgs[4],
- .chip = {
- .base = S5P6440_GPJ(0),
- .ngpio = S5P6440_GPIO_J_NR,
- .label = "GPJ",
- },
- }, {
- .base = S5P64X0_GPN_BASE,
- .config = &samsung_gpio_cfgs[5],
- .chip = {
- .base = S5P6440_GPN(0),
- .ngpio = S5P6440_GPIO_N_NR,
- .label = "GPN",
- },
- }, {
- .base = S5P64X0_GPP_BASE,
- .config = &samsung_gpio_cfgs[6],
- .chip = {
- .base = S5P6440_GPP(0),
- .ngpio = S5P6440_GPIO_P_NR,
- .label = "GPP",
- },
- },
-#endif
-};
-
-/*
- * S5P6450 GPIO bank summary:
- *
- * Bank GPIOs Style SlpCon ExtInt Group
- * A 6 4Bit Yes 1
- * B 7 4Bit Yes 1
- * C 8 4Bit Yes 2
- * D 8 4Bit Yes None
- * F 2 2Bit Yes None
- * G 14 4Bit[2] Yes 5
- * H 10 4Bit[2] Yes 6
- * I 16 2Bit Yes None
- * J 12 2Bit Yes None
- * K 5 4Bit Yes None
- * N 16 2Bit No IRQ_EINT
- * P 11 2Bit Yes 8
- * Q 14 2Bit Yes None
- * R 15 4Bit[2] Yes None
- * S 8 2Bit Yes None
- *
- * [1] BANKF pins 14,15 do not form part of the external interrupt sources
- * [2] BANK has two control registers, GPxCON0 and GPxCON1
- */
-
-static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
-#ifdef CONFIG_CPU_S5P6450
- {
- .chip = {
- .base = S5P6450_GPA(0),
- .ngpio = S5P6450_GPIO_A_NR,
- .label = "GPA",
- },
- }, {
- .chip = {
- .base = S5P6450_GPB(0),
- .ngpio = S5P6450_GPIO_B_NR,
- .label = "GPB",
- },
- }, {
- .chip = {
- .base = S5P6450_GPC(0),
- .ngpio = S5P6450_GPIO_C_NR,
- .label = "GPC",
- },
- }, {
- .chip = {
- .base = S5P6450_GPD(0),
- .ngpio = S5P6450_GPIO_D_NR,
- .label = "GPD",
- },
- }, {
- .base = S5P6450_GPK_BASE,
- .chip = {
- .base = S5P6450_GPK(0),
- .ngpio = S5P6450_GPIO_K_NR,
- .label = "GPK",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
-#ifdef CONFIG_CPU_S5P6450
- {
- .base = S5P64X0_GPG_BASE + 0x4,
- .chip = {
- .base = S5P6450_GPG(0),
- .ngpio = S5P6450_GPIO_G_NR,
- .label = "GPG",
- },
- }, {
- .base = S5P64X0_GPH_BASE + 0x4,
- .chip = {
- .base = S5P6450_GPH(0),
- .ngpio = S5P6450_GPIO_H_NR,
- .label = "GPH",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
-#ifdef CONFIG_CPU_S5P6450
- {
- .base = S5P64X0_GPR_BASE + 0x4,
- .config = &s5p64x0_gpio_cfg_rbank,
- .chip = {
- .base = S5P6450_GPR(0),
- .ngpio = S5P6450_GPIO_R_NR,
- .label = "GPR",
- },
- },
-#endif
-};
-
-static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
-#ifdef CONFIG_CPU_S5P6450
- {
- .base = S5P64X0_GPF_BASE,
- .config = &samsung_gpio_cfgs[6],
- .chip = {
- .base = S5P6450_GPF(0),
- .ngpio = S5P6450_GPIO_F_NR,
- .label = "GPF",
- },
- }, {
- .base = S5P64X0_GPI_BASE,
- .config = &samsung_gpio_cfgs[4],
- .chip = {
- .base = S5P6450_GPI(0),
- .ngpio = S5P6450_GPIO_I_NR,
- .label = "GPI",
- },
- }, {
- .base = S5P64X0_GPJ_BASE,
- .config = &samsung_gpio_cfgs[4],
- .chip = {
- .base = S5P6450_GPJ(0),
- .ngpio = S5P6450_GPIO_J_NR,
- .label = "GPJ",
- },
- }, {
- .base = S5P64X0_GPN_BASE,
- .config = &samsung_gpio_cfgs[5],
- .chip = {
- .base = S5P6450_GPN(0),
- .ngpio = S5P6450_GPIO_N_NR,
- .label = "GPN",
- },
- }, {
- .base = S5P64X0_GPP_BASE,
- .config = &samsung_gpio_cfgs[6],
- .chip = {
- .base = S5P6450_GPP(0),
- .ngpio = S5P6450_GPIO_P_NR,
- .label = "GPP",
- },
- }, {
- .base = S5P6450_GPQ_BASE,
- .config = &samsung_gpio_cfgs[5],
- .chip = {
- .base = S5P6450_GPQ(0),
- .ngpio = S5P6450_GPIO_Q_NR,
- .label = "GPQ",
- },
- }, {
- .base = S5P6450_GPS_BASE,
- .config = &samsung_gpio_cfgs[6],
- .chip = {
- .base = S5P6450_GPS(0),
- .ngpio = S5P6450_GPIO_S_NR,
- .label = "GPS",
- },
- },
-#endif
-};
-
-/*
- * S5PC100 GPIO bank summary:
- *
- * Bank GPIOs Style INT Type
- * A0 8 4Bit GPIO_INT0
- * A1 5 4Bit GPIO_INT1
- * B 8 4Bit GPIO_INT2
- * C 5 4Bit GPIO_INT3
- * D 7 4Bit GPIO_INT4
- * E0 8 4Bit GPIO_INT5
- * E1 6 4Bit GPIO_INT6
- * F0 8 4Bit GPIO_INT7
- * F1 8 4Bit GPIO_INT8
- * F2 8 4Bit GPIO_INT9
- * F3 4 4Bit GPIO_INT10
- * G0 8 4Bit GPIO_INT11
- * G1 3 4Bit GPIO_INT12
- * G2 7 4Bit GPIO_INT13
- * G3 7 4Bit GPIO_INT14
- * H0 8 4Bit WKUP_INT
- * H1 8 4Bit WKUP_INT
- * H2 8 4Bit WKUP_INT
- * H3 8 4Bit WKUP_INT
- * I 8 4Bit GPIO_INT15
- * J0 8 4Bit GPIO_INT16
- * J1 5 4Bit GPIO_INT17
- * J2 8 4Bit GPIO_INT18
- * J3 8 4Bit GPIO_INT19
- * J4 4 4Bit GPIO_INT20
- * K0 8 4Bit None
- * K1 6 4Bit None
- * K2 8 4Bit None
- * K3 8 4Bit None
- * L0 8 4Bit None
- * L1 8 4Bit None
- * L2 8 4Bit None
- * L3 8 4Bit None
- */
-
-static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
-#ifdef CONFIG_CPU_S5PC100
- {
- .chip = {
- .base = S5PC100_GPA0(0),
- .ngpio = S5PC100_GPIO_A0_NR,
- .label = "GPA0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPA1(0),
- .ngpio = S5PC100_GPIO_A1_NR,
- .label = "GPA1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPB(0),
- .ngpio = S5PC100_GPIO_B_NR,
- .label = "GPB",
- },
- }, {
- .chip = {
- .base = S5PC100_GPC(0),
- .ngpio = S5PC100_GPIO_C_NR,
- .label = "GPC",
- },
- }, {
- .chip = {
- .base = S5PC100_GPD(0),
- .ngpio = S5PC100_GPIO_D_NR,
- .label = "GPD",
- },
- }, {
- .chip = {
- .base = S5PC100_GPE0(0),
- .ngpio = S5PC100_GPIO_E0_NR,
- .label = "GPE0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPE1(0),
- .ngpio = S5PC100_GPIO_E1_NR,
- .label = "GPE1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPF0(0),
- .ngpio = S5PC100_GPIO_F0_NR,
- .label = "GPF0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPF1(0),
- .ngpio = S5PC100_GPIO_F1_NR,
- .label = "GPF1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPF2(0),
- .ngpio = S5PC100_GPIO_F2_NR,
- .label = "GPF2",
- },
- }, {
- .chip = {
- .base = S5PC100_GPF3(0),
- .ngpio = S5PC100_GPIO_F3_NR,
- .label = "GPF3",
- },
- }, {
- .chip = {
- .base = S5PC100_GPG0(0),
- .ngpio = S5PC100_GPIO_G0_NR,
- .label = "GPG0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPG1(0),
- .ngpio = S5PC100_GPIO_G1_NR,
- .label = "GPG1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPG2(0),
- .ngpio = S5PC100_GPIO_G2_NR,
- .label = "GPG2",
- },
- }, {
- .chip = {
- .base = S5PC100_GPG3(0),
- .ngpio = S5PC100_GPIO_G3_NR,
- .label = "GPG3",
- },
- }, {
- .chip = {
- .base = S5PC100_GPI(0),
- .ngpio = S5PC100_GPIO_I_NR,
- .label = "GPI",
- },
- }, {
- .chip = {
- .base = S5PC100_GPJ0(0),
- .ngpio = S5PC100_GPIO_J0_NR,
- .label = "GPJ0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPJ1(0),
- .ngpio = S5PC100_GPIO_J1_NR,
- .label = "GPJ1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPJ2(0),
- .ngpio = S5PC100_GPIO_J2_NR,
- .label = "GPJ2",
- },
- }, {
- .chip = {
- .base = S5PC100_GPJ3(0),
- .ngpio = S5PC100_GPIO_J3_NR,
- .label = "GPJ3",
- },
- }, {
- .chip = {
- .base = S5PC100_GPJ4(0),
- .ngpio = S5PC100_GPIO_J4_NR,
- .label = "GPJ4",
- },
- }, {
- .chip = {
- .base = S5PC100_GPK0(0),
- .ngpio = S5PC100_GPIO_K0_NR,
- .label = "GPK0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPK1(0),
- .ngpio = S5PC100_GPIO_K1_NR,
- .label = "GPK1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPK2(0),
- .ngpio = S5PC100_GPIO_K2_NR,
- .label = "GPK2",
- },
- }, {
- .chip = {
- .base = S5PC100_GPK3(0),
- .ngpio = S5PC100_GPIO_K3_NR,
- .label = "GPK3",
- },
- }, {
- .chip = {
- .base = S5PC100_GPL0(0),
- .ngpio = S5PC100_GPIO_L0_NR,
- .label = "GPL0",
- },
- }, {
- .chip = {
- .base = S5PC100_GPL1(0),
- .ngpio = S5PC100_GPIO_L1_NR,
- .label = "GPL1",
- },
- }, {
- .chip = {
- .base = S5PC100_GPL2(0),
- .ngpio = S5PC100_GPIO_L2_NR,
- .label = "GPL2",
- },
- }, {
- .chip = {
- .base = S5PC100_GPL3(0),
- .ngpio = S5PC100_GPIO_L3_NR,
- .label = "GPL3",
- },
- }, {
- .chip = {
- .base = S5PC100_GPL4(0),
- .ngpio = S5PC100_GPIO_L4_NR,
- .label = "GPL4",
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC00),
- .irq_base = IRQ_EINT(0),
- .chip = {
- .base = S5PC100_GPH0(0),
- .ngpio = S5PC100_GPIO_H0_NR,
- .label = "GPH0",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC20),
- .irq_base = IRQ_EINT(8),
- .chip = {
- .base = S5PC100_GPH1(0),
- .ngpio = S5PC100_GPIO_H1_NR,
- .label = "GPH1",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC40),
- .irq_base = IRQ_EINT(16),
- .chip = {
- .base = S5PC100_GPH2(0),
- .ngpio = S5PC100_GPIO_H2_NR,
- .label = "GPH2",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC60),
- .irq_base = IRQ_EINT(24),
- .chip = {
- .base = S5PC100_GPH3(0),
- .ngpio = S5PC100_GPIO_H3_NR,
- .label = "GPH3",
- .to_irq = samsung_gpiolib_to_irq,
- },
- },
-#endif
-};
-
-/*
- * Followings are the gpio banks in S5PV210/S5PC110
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure samsung_gpio_cfgs[3] in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of samsung_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-
-static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
-#ifdef CONFIG_CPU_S5PV210
- {
- .chip = {
- .base = S5PV210_GPA0(0),
- .ngpio = S5PV210_GPIO_A0_NR,
- .label = "GPA0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPA1(0),
- .ngpio = S5PV210_GPIO_A1_NR,
- .label = "GPA1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPB(0),
- .ngpio = S5PV210_GPIO_B_NR,
- .label = "GPB",
- },
- }, {
- .chip = {
- .base = S5PV210_GPC0(0),
- .ngpio = S5PV210_GPIO_C0_NR,
- .label = "GPC0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPC1(0),
- .ngpio = S5PV210_GPIO_C1_NR,
- .label = "GPC1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPD0(0),
- .ngpio = S5PV210_GPIO_D0_NR,
- .label = "GPD0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPD1(0),
- .ngpio = S5PV210_GPIO_D1_NR,
- .label = "GPD1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPE0(0),
- .ngpio = S5PV210_GPIO_E0_NR,
- .label = "GPE0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPE1(0),
- .ngpio = S5PV210_GPIO_E1_NR,
- .label = "GPE1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPF0(0),
- .ngpio = S5PV210_GPIO_F0_NR,
- .label = "GPF0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPF1(0),
- .ngpio = S5PV210_GPIO_F1_NR,
- .label = "GPF1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPF2(0),
- .ngpio = S5PV210_GPIO_F2_NR,
- .label = "GPF2",
- },
- }, {
- .chip = {
- .base = S5PV210_GPF3(0),
- .ngpio = S5PV210_GPIO_F3_NR,
- .label = "GPF3",
- },
- }, {
- .chip = {
- .base = S5PV210_GPG0(0),
- .ngpio = S5PV210_GPIO_G0_NR,
- .label = "GPG0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPG1(0),
- .ngpio = S5PV210_GPIO_G1_NR,
- .label = "GPG1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPG2(0),
- .ngpio = S5PV210_GPIO_G2_NR,
- .label = "GPG2",
- },
- }, {
- .chip = {
- .base = S5PV210_GPG3(0),
- .ngpio = S5PV210_GPIO_G3_NR,
- .label = "GPG3",
- },
- }, {
- .chip = {
- .base = S5PV210_GPI(0),
- .ngpio = S5PV210_GPIO_I_NR,
- .label = "GPI",
- },
- }, {
- .chip = {
- .base = S5PV210_GPJ0(0),
- .ngpio = S5PV210_GPIO_J0_NR,
- .label = "GPJ0",
- },
- }, {
- .chip = {
- .base = S5PV210_GPJ1(0),
- .ngpio = S5PV210_GPIO_J1_NR,
- .label = "GPJ1",
- },
- }, {
- .chip = {
- .base = S5PV210_GPJ2(0),
- .ngpio = S5PV210_GPIO_J2_NR,
- .label = "GPJ2",
- },
- }, {
- .chip = {
- .base = S5PV210_GPJ3(0),
- .ngpio = S5PV210_GPIO_J3_NR,
- .label = "GPJ3",
- },
- }, {
- .chip = {
- .base = S5PV210_GPJ4(0),
- .ngpio = S5PV210_GPIO_J4_NR,
- .label = "GPJ4",
- },
- }, {
- .chip = {
- .base = S5PV210_MP01(0),
- .ngpio = S5PV210_GPIO_MP01_NR,
- .label = "MP01",
- },
- }, {
- .chip = {
- .base = S5PV210_MP02(0),
- .ngpio = S5PV210_GPIO_MP02_NR,
- .label = "MP02",
- },
- }, {
- .chip = {
- .base = S5PV210_MP03(0),
- .ngpio = S5PV210_GPIO_MP03_NR,
- .label = "MP03",
- },
- }, {
- .chip = {
- .base = S5PV210_MP04(0),
- .ngpio = S5PV210_GPIO_MP04_NR,
- .label = "MP04",
- },
- }, {
- .chip = {
- .base = S5PV210_MP05(0),
- .ngpio = S5PV210_GPIO_MP05_NR,
- .label = "MP05",
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC00),
- .irq_base = IRQ_EINT(0),
- .chip = {
- .base = S5PV210_GPH0(0),
- .ngpio = S5PV210_GPIO_H0_NR,
- .label = "GPH0",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC20),
- .irq_base = IRQ_EINT(8),
- .chip = {
- .base = S5PV210_GPH1(0),
- .ngpio = S5PV210_GPIO_H1_NR,
- .label = "GPH1",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC40),
- .irq_base = IRQ_EINT(16),
- .chip = {
- .base = S5PV210_GPH2(0),
- .ngpio = S5PV210_GPIO_H2_NR,
- .label = "GPH2",
- .to_irq = samsung_gpiolib_to_irq,
- },
- }, {
- .base = (S5P_VA_GPIO + 0xC60),
- .irq_base = IRQ_EINT(24),
- .chip = {
- .base = S5PV210_GPH3(0),
- .ngpio = S5PV210_GPIO_H3_NR,
- .label = "GPH3",
- .to_irq = samsung_gpiolib_to_irq,
- },
- },
-#endif
-};
-
/* TODO: cleanup soc_is_* */
static __init int samsung_gpiolib_init(void)
{
- struct samsung_gpio_chip *chip;
- int i, nr_chips;
- int group = 0;
-
/*
* Currently there are two drivers that can provide GPIO support for
* Samsung SoCs. For device tree enabled platforms, the new
@@ -2109,54 +1192,6 @@ static __init int samsung_gpiolib_init(void)
S3C64XX_VA_GPIO);
samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
ARRAY_SIZE(s3c64xx_gpios_4bit2));
- } else if (soc_is_s5p6440()) {
- samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
- ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
- samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
- ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
- samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
- ARRAY_SIZE(s5p6440_gpios_4bit2));
- s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
- ARRAY_SIZE(s5p6440_gpios_rbank));
- } else if (soc_is_s5p6450()) {
- samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
- ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
- samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
- ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
- samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
- ARRAY_SIZE(s5p6450_gpios_4bit2));
- s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
- ARRAY_SIZE(s5p6450_gpios_rbank));
- } else if (soc_is_s5pc100()) {
- group = 0;
- chip = s5pc100_gpios_4bit;
- nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
-
- for (i = 0; i < nr_chips; i++, chip++) {
- if (!chip->config) {
- chip->config = &samsung_gpio_cfgs[3];
- chip->group = group++;
- }
- }
- samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
-#if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
- s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-#endif
- } else if (soc_is_s5pv210()) {
- group = 0;
- chip = s5pv210_gpios_4bit;
- nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
-
- for (i = 0; i < nr_chips; i++, chip++) {
- if (!chip->config) {
- chip->config = &samsung_gpio_cfgs[3];
- chip->group = group++;
- }
- }
- samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
-#if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
- s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-#endif
} else {
WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
return -ENODEV;
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f5120046ff80..b066bb3ca01a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -114,6 +114,7 @@ config DRM_RADEON
select POWER_SUPPLY
select HWMON
select BACKLIGHT_CLASS_DEVICE
+ select INTERVAL_TREE
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
@@ -201,3 +202,5 @@ source "drivers/gpu/drm/msm/Kconfig"
source "drivers/gpu/drm/tegra/Kconfig"
source "drivers/gpu/drm/panel/Kconfig"
+
+source "drivers/gpu/drm/sti/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index dd2ba4269740..4a55d59ccd22 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -6,8 +6,8 @@ ccflags-y := -Iinclude/drm
drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm_context.o drm_dma.o \
- drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
- drm_lock.o drm_memory.o drm_stub.o drm_vm.o \
+ drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
+ drm_lock.o drm_memory.o drm_drv.o drm_vm.o \
drm_agpsupport.o drm_scatter.o drm_pci.o \
drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
drm_crtc.o drm_modes.o drm_edid.o \
@@ -20,11 +20,12 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
drm-$(CONFIG_PCI) += ati_pcigart.o
drm-$(CONFIG_DRM_PANEL) += drm_panel.o
+drm-$(CONFIG_OF) += drm_of.o
drm-usb-y := drm_usb.o
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
- drm_plane_helper.o
+ drm_plane_helper.o drm_dp_mst_topology.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_DRM_QXL) += qxl/
obj-$(CONFIG_DRM_BOCHS) += bochs/
obj-$(CONFIG_DRM_MSM) += msm/
obj-$(CONFIG_DRM_TEGRA) += tegra/
+obj-$(CONFIG_DRM_STI) += sti/
obj-y += i2c/
obj-y += panel/
obj-y += bridge/
diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index 59948eff6095..ad3d2ebf95c9 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -15,20 +15,19 @@
#include "armada_drm.h"
#include "armada_hw.h"
-static int armada510_init(struct armada_private *priv, struct device *dev)
+static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
{
- priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1");
+ struct clk *clk;
- if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT)
- priv->extclk[0] = ERR_PTR(-EPROBE_DEFER);
+ clk = devm_clk_get(dev, "ext_ref_clk1");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER : PTR_ERR(clk);
- return PTR_RET(priv->extclk[0]);
-}
+ dcrtc->extclk[0] = clk;
-static int armada510_crtc_init(struct armada_crtc *dcrtc)
-{
/* Lower the watermark so to eliminate jitter at higher bandwidths */
armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
+
return 0;
}
@@ -45,8 +44,7 @@ static int armada510_crtc_init(struct armada_crtc *dcrtc)
static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
const struct drm_display_mode *mode, uint32_t *sclk)
{
- struct armada_private *priv = dcrtc->crtc.dev->dev_private;
- struct clk *clk = priv->extclk[0];
+ struct clk *clk = dcrtc->extclk[0];
int ret;
if (dcrtc->num == 1)
@@ -81,7 +79,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
const struct armada_variant armada510_ops = {
.has_spu_adv_reg = true,
.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
- .init = armada510_init,
- .crtc_init = armada510_crtc_init,
- .crtc_compute_clock = armada510_crtc_compute_clock,
+ .init = armada510_crtc_init,
+ .compute_clock = armada510_crtc_compute_clock,
};
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 81c34f949dfc..9a0cc09e6653 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -7,6 +7,9 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "armada_crtc.h"
@@ -332,24 +335,23 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode, struct drm_display_mode *adj)
{
- struct armada_private *priv = crtc->dev->dev_private;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
int ret;
/* We can't do interlaced modes if we don't have the SPU_ADV_REG */
- if (!priv->variant->has_spu_adv_reg &&
+ if (!dcrtc->variant->has_spu_adv_reg &&
adj->flags & DRM_MODE_FLAG_INTERLACE)
return false;
/* Check whether the display mode is possible */
- ret = priv->variant->crtc_compute_clock(dcrtc, adj, NULL);
+ ret = dcrtc->variant->compute_clock(dcrtc, adj, NULL);
if (ret)
return false;
return true;
}
-void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
+static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
{
struct armada_vbl_event *e, *n;
void __iomem *base = dcrtc->base;
@@ -410,6 +412,27 @@ void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
}
}
+static irqreturn_t armada_drm_irq(int irq, void *arg)
+{
+ struct armada_crtc *dcrtc = arg;
+ u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
+
+ /*
+ * This is rediculous - rather than writing bits to clear, we
+ * have to set the actual status register value. This is racy.
+ */
+ writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
+
+ /* Mask out those interrupts we haven't enabled */
+ v = stat & dcrtc->irq_ena;
+
+ if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
+ armada_drm_crtc_irq(dcrtc, stat);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
/* These are locked by dev->vbl_lock */
void armada_drm_crtc_disable_irq(struct armada_crtc *dcrtc, u32 mask)
{
@@ -470,7 +493,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode, struct drm_display_mode *adj,
int x, int y, struct drm_framebuffer *old_fb)
{
- struct armada_private *priv = crtc->dev->dev_private;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
struct armada_regs regs[17];
uint32_t lm, rm, tm, bm, val, sclk;
@@ -515,7 +537,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
}
/* Now compute the divider for real */
- priv->variant->crtc_compute_clock(dcrtc, adj, &sclk);
+ dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
/* Ensure graphic fifo is enabled */
armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
@@ -537,7 +559,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
dcrtc->v[1].spu_v_porch = tm << 16 | bm;
val = adj->crtc_hsync_start;
dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
- priv->variant->spu_adv_reg;
+ dcrtc->variant->spu_adv_reg;
if (interlaced) {
/* Odd interlaced frame */
@@ -546,7 +568,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
- priv->variant->spu_adv_reg;
+ dcrtc->variant->spu_adv_reg;
} else {
dcrtc->v[0] = dcrtc->v[1];
}
@@ -561,7 +583,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
LCD_SPUT_V_H_TOTAL);
- if (priv->variant->has_spu_adv_reg) {
+ if (dcrtc->variant->has_spu_adv_reg) {
armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
@@ -805,12 +827,11 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_private *priv = crtc->dev->dev_private;
struct armada_gem_object *obj = NULL;
int ret;
/* If no cursor support, replicate drm's return value */
- if (!priv->variant->has_spu_adv_reg)
+ if (!dcrtc->variant->has_spu_adv_reg)
return -ENXIO;
if (handle && w > 0 && h > 0) {
@@ -858,11 +879,10 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
struct drm_device *dev = crtc->dev;
struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
- struct armada_private *priv = crtc->dev->dev_private;
int ret;
/* If no cursor support, replicate drm's return value */
- if (!priv->variant->has_spu_adv_reg)
+ if (!dcrtc->variant->has_spu_adv_reg)
return -EFAULT;
mutex_lock(&dev->struct_mutex);
@@ -888,6 +908,10 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
if (!IS_ERR(dcrtc->clk))
clk_disable_unprepare(dcrtc->clk);
+ writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
+
+ of_node_put(dcrtc->crtc.port);
+
kfree(dcrtc);
}
@@ -1027,23 +1051,22 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
return 0;
}
-int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
- struct resource *res)
+int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
+ struct resource *res, int irq, const struct armada_variant *variant,
+ struct device_node *port)
{
- struct armada_private *priv = dev->dev_private;
+ struct armada_private *priv = drm->dev_private;
struct armada_crtc *dcrtc;
void __iomem *base;
int ret;
- ret = armada_drm_crtc_create_properties(dev);
+ ret = armada_drm_crtc_create_properties(drm);
if (ret)
return ret;
- base = devm_request_and_ioremap(dev->dev, res);
- if (!base) {
- DRM_ERROR("failed to ioremap register\n");
- return -ENOMEM;
- }
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
dcrtc = kzalloc(sizeof(*dcrtc), GFP_KERNEL);
if (!dcrtc) {
@@ -1051,8 +1074,12 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
return -ENOMEM;
}
+ if (dev != drm->dev)
+ dev_set_drvdata(dev, dcrtc);
+
+ dcrtc->variant = variant;
dcrtc->base = base;
- dcrtc->num = num;
+ dcrtc->num = drm->mode_config.num_crtc;
dcrtc->clk = ERR_PTR(-EINVAL);
dcrtc->csc_yuv_mode = CSC_AUTO;
dcrtc->csc_rgb_mode = CSC_AUTO;
@@ -1074,9 +1101,18 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN);
+ writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
+ writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
- if (priv->variant->crtc_init) {
- ret = priv->variant->crtc_init(dcrtc);
+ ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
+ dcrtc);
+ if (ret < 0) {
+ kfree(dcrtc);
+ return ret;
+ }
+
+ if (dcrtc->variant->init) {
+ ret = dcrtc->variant->init(dcrtc, dev);
if (ret) {
kfree(dcrtc);
return ret;
@@ -1088,7 +1124,8 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
priv->dcrtc[dcrtc->num] = dcrtc;
- drm_crtc_init(dev, &dcrtc->crtc, &armada_crtc_funcs);
+ dcrtc->crtc.port = port;
+ drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs);
drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
@@ -1096,5 +1133,107 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop,
dcrtc->csc_rgb_mode);
- return armada_overlay_plane_create(dev, 1 << dcrtc->num);
+ return armada_overlay_plane_create(drm, 1 << dcrtc->num);
+}
+
+static int
+armada_lcd_bind(struct device *dev, struct device *master, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct drm_device *drm = data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int irq = platform_get_irq(pdev, 0);
+ const struct armada_variant *variant;
+ struct device_node *port = NULL;
+
+ if (irq < 0)
+ return irq;
+
+ if (!dev->of_node) {
+ const struct platform_device_id *id;
+
+ id = platform_get_device_id(pdev);
+ if (!id)
+ return -ENXIO;
+
+ variant = (const struct armada_variant *)id->driver_data;
+ } else {
+ const struct of_device_id *match;
+ struct device_node *np, *parent = dev->of_node;
+
+ match = of_match_device(dev->driver->of_match_table, dev);
+ if (!match)
+ return -ENXIO;
+
+ np = of_get_child_by_name(parent, "ports");
+ if (np)
+ parent = np;
+ 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);
+ return -ENXIO;
+ }
+
+ variant = match->data;
+ }
+
+ return armada_drm_crtc_create(drm, dev, res, irq, variant, port);
+}
+
+static void
+armada_lcd_unbind(struct device *dev, struct device *master, void *data)
+{
+ struct armada_crtc *dcrtc = dev_get_drvdata(dev);
+
+ armada_drm_crtc_destroy(&dcrtc->crtc);
}
+
+static const struct component_ops armada_lcd_ops = {
+ .bind = armada_lcd_bind,
+ .unbind = armada_lcd_unbind,
+};
+
+static int armada_lcd_probe(struct platform_device *pdev)
+{
+ return component_add(&pdev->dev, &armada_lcd_ops);
+}
+
+static int armada_lcd_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &armada_lcd_ops);
+ return 0;
+}
+
+static struct of_device_id armada_lcd_of_match[] = {
+ {
+ .compatible = "marvell,dove-lcd",
+ .data = &armada510_ops,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
+
+static const struct platform_device_id armada_lcd_platform_ids[] = {
+ {
+ .name = "armada-lcd",
+ .driver_data = (unsigned long)&armada510_ops,
+ }, {
+ .name = "armada-510-lcd",
+ .driver_data = (unsigned long)&armada510_ops,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids);
+
+struct platform_driver armada_lcd_platform_driver = {
+ .probe = armada_lcd_probe,
+ .remove = armada_lcd_remove,
+ .driver = {
+ .name = "armada-lcd",
+ .owner = THIS_MODULE,
+ .of_match_table = armada_lcd_of_match,
+ },
+ .id_table = armada_lcd_platform_ids,
+};
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 9c10a07e7492..98102a5a9af5 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -32,12 +32,15 @@ struct armada_regs {
armada_reg_queue_mod(_r, _i, 0, 0, ~0)
struct armada_frame_work;
+struct armada_variant;
struct armada_crtc {
struct drm_crtc crtc;
+ const struct armada_variant *variant;
unsigned num;
void __iomem *base;
struct clk *clk;
+ struct clk *extclk[2];
struct {
uint32_t spu_v_h_total;
uint32_t spu_v_porch;
@@ -72,12 +75,16 @@ struct armada_crtc {
};
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
-int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *);
+struct device_node;
+int armada_drm_crtc_create(struct drm_device *, struct device *,
+ struct resource *, int, const struct armada_variant *,
+ struct device_node *);
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_irq(struct armada_crtc *, u32);
void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
+extern struct platform_driver armada_lcd_platform_driver;
+
#endif
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index a72cae03b99b..ea63c6c7c66f 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -59,26 +59,23 @@ void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *,
struct armada_private;
struct armada_variant {
- bool has_spu_adv_reg;
+ bool has_spu_adv_reg;
uint32_t spu_adv_reg;
- int (*init)(struct armada_private *, struct device *);
- int (*crtc_init)(struct armada_crtc *);
- int (*crtc_compute_clock)(struct armada_crtc *,
- const struct drm_display_mode *,
- uint32_t *);
+ int (*init)(struct armada_crtc *, struct device *);
+ int (*compute_clock)(struct armada_crtc *,
+ const struct drm_display_mode *,
+ uint32_t *);
};
/* Variant ops */
extern const struct armada_variant armada510_ops;
struct armada_private {
- const struct armada_variant *variant;
struct work_struct fb_unref_work;
DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
struct drm_fb_helper *fbdev;
struct armada_crtc *dcrtc[2];
struct drm_mm linear;
- struct clk *extclk[2];
struct drm_property *csc_yuv_prop;
struct drm_property *csc_rgb_prop;
struct drm_property *colorkey_prop;
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 8ab3cd1a8cdb..e2d5792b140f 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -6,7 +6,9 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
+#include <linux/component.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "armada_crtc.h"
@@ -52,6 +54,11 @@ static const struct armada_drm_slave_config tda19988_config = {
};
#endif
+static bool is_componentized(struct device *dev)
+{
+ return dev->of_node || dev->platform_data;
+}
+
static void armada_drm_unref_work(struct work_struct *work)
{
struct armada_private *priv =
@@ -85,6 +92,7 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
static int armada_drm_load(struct drm_device *dev, unsigned long flags)
{
const struct platform_device_id *id;
+ const struct armada_variant *variant;
struct armada_private *priv;
struct resource *res[ARRAY_SIZE(priv->dcrtc)];
struct resource *mem = NULL;
@@ -107,7 +115,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
return -EINVAL;
}
- if (!res[0] || !mem)
+ if (!mem)
return -ENXIO;
if (!devm_request_mem_region(dev->dev, mem->start,
@@ -128,11 +136,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (!id)
return -ENXIO;
- priv->variant = (struct armada_variant *)id->driver_data;
-
- ret = priv->variant->init(priv, dev->dev);
- if (ret)
- return ret;
+ variant = (const struct armada_variant *)id->driver_data;
INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
INIT_KFIFO(priv->fb_unref);
@@ -155,40 +159,50 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
/* Create all LCD controllers */
for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
+ int irq;
+
if (!res[n])
break;
- ret = armada_drm_crtc_create(dev, n, res[n]);
+ irq = platform_get_irq(dev->platformdev, n);
+ if (irq < 0)
+ goto err_kms;
+
+ ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
+ variant, NULL);
if (ret)
goto err_kms;
}
+ if (is_componentized(dev->dev)) {
+ ret = component_bind_all(dev->dev, dev);
+ if (ret)
+ goto err_kms;
+ } else {
#ifdef CONFIG_DRM_ARMADA_TDA1998X
- ret = armada_drm_connector_slave_create(dev, &tda19988_config);
- if (ret)
- goto err_kms;
+ ret = armada_drm_connector_slave_create(dev, &tda19988_config);
+ if (ret)
+ goto err_kms;
#endif
+ }
- ret = drm_vblank_init(dev, n);
- if (ret)
- goto err_kms;
-
- ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
+ ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
- goto err_kms;
+ goto err_comp;
dev->vblank_disable_allowed = 1;
ret = armada_fbdev_init(dev);
if (ret)
- goto err_irq;
+ goto err_comp;
drm_kms_helper_poll_init(dev);
return 0;
- err_irq:
- drm_irq_uninstall(dev);
+ err_comp:
+ if (is_componentized(dev->dev))
+ component_unbind_all(dev->dev, dev);
err_kms:
drm_mode_config_cleanup(dev);
drm_mm_takedown(&priv->linear);
@@ -203,7 +217,10 @@ static int armada_drm_unload(struct drm_device *dev)
drm_kms_helper_poll_fini(dev);
armada_fbdev_fini(dev);
- drm_irq_uninstall(dev);
+
+ if (is_componentized(dev->dev))
+ component_unbind_all(dev->dev, dev);
+
drm_mode_config_cleanup(dev);
drm_mm_takedown(&priv->linear);
flush_work(&priv->fb_unref_work);
@@ -259,52 +276,6 @@ static void armada_drm_disable_vblank(struct drm_device *dev, int crtc)
armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
}
-static irqreturn_t armada_drm_irq_handler(int irq, void *arg)
-{
- struct drm_device *dev = arg;
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
- uint32_t v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
- irqreturn_t handled = IRQ_NONE;
-
- /*
- * This is rediculous - rather than writing bits to clear, we
- * have to set the actual status register value. This is racy.
- */
- writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
-
- /* Mask out those interrupts we haven't enabled */
- v = stat & dcrtc->irq_ena;
-
- if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
- armada_drm_crtc_irq(dcrtc, stat);
- handled = IRQ_HANDLED;
- }
-
- return handled;
-}
-
-static int armada_drm_irq_postinstall(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
-
- spin_lock_irq(&dev->vbl_lock);
- writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
- writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
- spin_unlock_irq(&dev->vbl_lock);
-
- return 0;
-}
-
-static void armada_drm_irq_uninstall(struct drm_device *dev)
-{
- struct armada_private *priv = dev->dev_private;
- struct armada_crtc *dcrtc = priv->dcrtc[0];
-
- writel(0, dcrtc->base + LCD_SPU_IRQ_ENA);
-}
-
static struct drm_ioctl_desc armada_ioctls[] = {
DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,
DRM_UNLOCKED),
@@ -340,9 +311,6 @@ static struct drm_driver armada_drm_driver = {
.get_vblank_counter = drm_vblank_count,
.enable_vblank = armada_drm_enable_vblank,
.disable_vblank = armada_drm_disable_vblank,
- .irq_handler = armada_drm_irq_handler,
- .irq_postinstall = armada_drm_irq_postinstall,
- .irq_uninstall = armada_drm_irq_uninstall,
#ifdef CONFIG_DEBUG_FS
.debugfs_init = armada_drm_debugfs_init,
.debugfs_cleanup = armada_drm_debugfs_cleanup,
@@ -362,19 +330,140 @@ static struct drm_driver armada_drm_driver = {
.desc = "Armada SoC DRM",
.date = "20120730",
.driver_features = DRIVER_GEM | DRIVER_MODESET |
- DRIVER_HAVE_IRQ | DRIVER_PRIME,
+ DRIVER_PRIME,
.ioctls = armada_ioctls,
.fops = &armada_drm_fops,
};
+static int armada_drm_bind(struct device *dev)
+{
+ return drm_platform_init(&armada_drm_driver, to_platform_device(dev));
+}
+
+static void armada_drm_unbind(struct device *dev)
+{
+ drm_put_dev(dev_get_drvdata(dev));
+}
+
+static int compare_of(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+static int compare_dev_name(struct device *dev, void *data)
+{
+ const char *name = data;
+ return !strcmp(dev_name(dev), name);
+}
+
+static void armada_add_endpoints(struct device *dev,
+ struct component_match **match, struct device_node *port)
+{
+ struct device_node *ep, *remote;
+
+ for_each_child_of_node(port, ep) {
+ remote = of_graph_get_remote_port_parent(ep);
+ if (!remote || !of_device_is_available(remote)) {
+ 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);
+ of_node_put(remote);
+ continue;
+ }
+
+ component_match_add(dev, match, compare_of, remote);
+ of_node_put(remote);
+ }
+}
+
+static int armada_drm_find_components(struct device *dev,
+ struct component_match **match)
+{
+ struct device_node *port;
+ int i;
+
+ if (dev->of_node) {
+ struct device_node *np = dev->of_node;
+
+ for (i = 0; ; i++) {
+ port = of_parse_phandle(np, "ports", i);
+ if (!port)
+ break;
+
+ component_match_add(dev, match, compare_of, port);
+ of_node_put(port);
+ }
+
+ if (i == 0) {
+ dev_err(dev, "missing 'ports' property\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; ; i++) {
+ port = of_parse_phandle(np, "ports", i);
+ if (!port)
+ break;
+
+ armada_add_endpoints(dev, match, port);
+ of_node_put(port);
+ }
+ } else if (dev->platform_data) {
+ char **devices = dev->platform_data;
+ struct device *d;
+
+ for (i = 0; devices[i]; i++)
+ component_match_add(dev, match, compare_dev_name,
+ devices[i]);
+
+ if (i == 0) {
+ dev_err(dev, "missing 'ports' property\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; devices[i]; i++) {
+ d = bus_find_device_by_name(&platform_bus_type, NULL,
+ devices[i]);
+ if (d && d->of_node) {
+ for_each_child_of_node(d->of_node, port)
+ armada_add_endpoints(dev, match, port);
+ }
+ put_device(d);
+ }
+ }
+
+ return 0;
+}
+
+static const struct component_master_ops armada_master_ops = {
+ .bind = armada_drm_bind,
+ .unbind = armada_drm_unbind,
+};
+
static int armada_drm_probe(struct platform_device *pdev)
{
- return drm_platform_init(&armada_drm_driver, pdev);
+ if (is_componentized(&pdev->dev)) {
+ struct component_match *match = NULL;
+ int ret;
+
+ ret = armada_drm_find_components(&pdev->dev, &match);
+ if (ret < 0)
+ return ret;
+
+ return component_master_add_with_match(&pdev->dev,
+ &armada_master_ops, match);
+ } else {
+ return drm_platform_init(&armada_drm_driver, pdev);
+ }
}
static int armada_drm_remove(struct platform_device *pdev)
{
- drm_put_dev(platform_get_drvdata(pdev));
+ if (is_componentized(&pdev->dev))
+ component_master_del(&pdev->dev, &armada_master_ops);
+ else
+ drm_put_dev(platform_get_drvdata(pdev));
return 0;
}
@@ -402,14 +491,24 @@ static struct platform_driver armada_drm_platform_driver = {
static int __init armada_drm_init(void)
{
+ int ret;
+
armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls);
- return platform_driver_register(&armada_drm_platform_driver);
+
+ ret = platform_driver_register(&armada_lcd_platform_driver);
+ if (ret)
+ return ret;
+ ret = platform_driver_register(&armada_drm_platform_driver);
+ if (ret)
+ platform_driver_unregister(&armada_lcd_platform_driver);
+ return ret;
}
module_init(armada_drm_init);
static void __exit armada_drm_exit(void)
{
platform_driver_unregister(&armada_drm_platform_driver);
+ platform_driver_unregister(&armada_lcd_platform_driver);
}
module_exit(armada_drm_exit);
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index fd166f532ab9..7838e731b0de 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -131,7 +131,7 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
return ret;
}
-static struct drm_fb_helper_funcs armada_fb_helper_funcs = {
+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,
@@ -149,7 +149,7 @@ int armada_fbdev_init(struct drm_device *dev)
priv->fbdev = fbh;
- fbh->funcs = &armada_fb_helper_funcs;
+ drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs);
ret = drm_fb_helper_init(dev, fbh, 1, 1);
if (ret) {
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index bb9b642d8485..7496f55611a5 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -539,7 +539,7 @@ armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj,
int flags)
{
return dma_buf_export(obj, &armada_gem_prime_dmabuf_ops, obj->size,
- O_RDWR);
+ O_RDWR, NULL);
}
struct drm_gem_object *
diff --git a/drivers/gpu/drm/armada/armada_output.c b/drivers/gpu/drm/armada/armada_output.c
index d685a5421485..abbc309fe539 100644
--- a/drivers/gpu/drm/armada/armada_output.c
+++ b/drivers/gpu/drm/armada/armada_output.c
@@ -48,7 +48,7 @@ static void armada_drm_connector_destroy(struct drm_connector *conn)
{
struct armada_connector *dconn = drm_to_armada_conn(conn);
- drm_sysfs_connector_remove(conn);
+ drm_connector_unregister(conn);
drm_connector_cleanup(conn);
kfree(dconn);
}
@@ -141,7 +141,7 @@ int armada_output_create(struct drm_device *dev,
if (ret)
goto err_conn;
- ret = drm_sysfs_connector_add(&dconn->conn);
+ ret = drm_connector_register(&dconn->conn);
if (ret)
goto err_sysfs;
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 5d6a87573c33..957d4fabf1e1 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -362,7 +362,7 @@ static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
{
int ret;
- ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, NULL);
if (ret) {
if (ret != -ERESTARTSYS && ret != -EBUSY)
DRM_ERROR("reserve failed %p\n", bo);
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index a28640f47c27..cba45c774552 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -287,7 +287,7 @@ static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
*blue = ast_crtc->lut_b[regno] << 8;
}
-static struct drm_fb_helper_funcs ast_fb_helper_funcs = {
+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,
@@ -328,8 +328,10 @@ int ast_fbdev_init(struct drm_device *dev)
return -ENOMEM;
ast->fbdev = afbdev;
- afbdev->helper.funcs = &ast_fb_helper_funcs;
spin_lock_init(&afbdev->dirty_lock);
+
+ drm_fb_helper_prepare(dev, &afbdev->helper, &ast_fb_helper_funcs);
+
ret = drm_fb_helper_init(dev, &afbdev->helper,
1, 1);
if (ret) {
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 114aee941d46..5389350244f2 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -667,17 +667,9 @@ static void ast_encoder_destroy(struct drm_encoder *encoder)
static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
/* pick the encoder ids */
- if (enc_id) {
- obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
@@ -829,7 +821,7 @@ static void ast_connector_destroy(struct drm_connector *connector)
{
struct ast_connector *ast_connector = to_ast_connector(connector);
ast_i2c_destroy(ast_connector->i2c);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -871,7 +863,7 @@ static int ast_connector_init(struct drm_device *dev)
connector->interlace_allowed = 0;
connector->doublescan_allowed = 0;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 9c13df29fd20..f5e0ead974a6 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -97,6 +97,7 @@ static struct drm_driver bochs_driver = {
/* ---------------------------------------------------------------------- */
/* pm interface */
+#ifdef CONFIG_PM_SLEEP
static int bochs_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -131,6 +132,7 @@ static int bochs_pm_resume(struct device *dev)
drm_kms_helper_poll_enable(drm_dev);
return 0;
}
+#endif
static const struct dev_pm_ops bochs_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 561b84474122..fe95d31cd110 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -72,7 +72,7 @@ static int bochsfb_create(struct drm_fb_helper *helper,
bo = gem_to_bochs_bo(gobj);
- ret = ttm_bo_reserve(&bo->bo, true, false, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL);
if (ret)
return ret;
@@ -179,7 +179,7 @@ void bochs_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
*blue = regno;
}
-static struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs bochs_fb_helper_funcs = {
.gamma_set = bochs_fb_gamma_set,
.gamma_get = bochs_fb_gamma_get,
.fb_probe = bochsfb_create,
@@ -189,7 +189,8 @@ int bochs_fbdev_init(struct bochs_device *bochs)
{
int ret;
- bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
+ drm_fb_helper_prepare(bochs->dev, &bochs->fb.helper,
+ &bochs_fb_helper_funcs);
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
1, 1);
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index dcf2e55f4ae9..9d7346b92653 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -53,7 +53,7 @@ static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
if (old_fb) {
bochs_fb = to_bochs_framebuffer(old_fb);
bo = gem_to_bochs_bo(bochs_fb->obj);
- ret = ttm_bo_reserve(&bo->bo, true, false, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL);
if (ret) {
DRM_ERROR("failed to reserve old_fb bo\n");
} else {
@@ -67,7 +67,7 @@ static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
bochs_fb = to_bochs_framebuffer(crtc->primary->fb);
bo = gem_to_bochs_bo(bochs_fb->obj);
- ret = ttm_bo_reserve(&bo->bo, true, false, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL);
if (ret)
return ret;
@@ -216,18 +216,9 @@ static struct drm_encoder *
bochs_connector_best_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
/* pick the encoder ids */
- if (enc_id) {
- obj = drm_mode_object_find(connector->dev, enc_id,
- DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c
index b9a695d92792..1728a1b0b813 100644
--- a/drivers/gpu/drm/bochs/bochs_mm.c
+++ b/drivers/gpu/drm/bochs/bochs_mm.c
@@ -387,7 +387,7 @@ int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel,
*obj = NULL;
- size = ALIGN(size, PAGE_SIZE);
+ size = PAGE_ALIGN(size);
if (size == 0)
return -EINVAL;
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index 98fd17ae4916..d466696ed5e8 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -328,7 +328,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
}
drm_connector_helper_add(&ptn_bridge->connector,
&ptn3460_connector_helper_funcs);
- drm_sysfs_connector_add(&ptn_bridge->connector);
+ drm_connector_register(&ptn_bridge->connector);
drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder);
return 0;
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 08ce520f61a5..4516b052cc67 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -76,6 +76,7 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}
+#ifdef CONFIG_PM_SLEEP
static int cirrus_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -110,6 +111,7 @@ static int cirrus_pm_resume(struct device *dev)
drm_kms_helper_poll_enable(drm_dev);
return 0;
}
+#endif
static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 117d3eca5e37..401c890b6c6a 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -241,7 +241,7 @@ static inline int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
{
int ret;
- ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, NULL);
if (ret) {
if (ret != -ERESTARTSYS && ret != -EBUSY)
DRM_ERROR("reserve failed %p\n", bo);
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 32bbba0a787b..2a135f253e29 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -288,7 +288,7 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
return 0;
}
-static struct drm_fb_helper_funcs cirrus_fb_helper_funcs = {
+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,
@@ -306,9 +306,11 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
return -ENOMEM;
cdev->mode_info.gfbdev = gfbdev;
- gfbdev->helper.funcs = &cirrus_fb_helper_funcs;
spin_lock_init(&gfbdev->dirty_lock);
+ drm_fb_helper_prepare(cdev->dev, &gfbdev->helper,
+ &cirrus_fb_helper_funcs);
+
ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
cdev->num_crtc, CIRRUSFB_CONN_LIMIT);
if (ret) {
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 49332c5fe35b..e1c5c3222129 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -509,19 +509,9 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
*connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
/* pick the encoder ids */
- if (enc_id) {
- obj =
- drm_mode_object_find(connector->dev, enc_id,
- DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c
index 0406110f83ed..86a4a4a60afc 100644
--- a/drivers/gpu/drm/drm_buffer.c
+++ b/drivers/gpu/drm/drm_buffer.c
@@ -80,11 +80,7 @@ int drm_buffer_alloc(struct drm_buffer **buf, int size)
error_out:
- /* Only last element can be null pointer so check for it first. */
- if ((*buf)->data[idx])
- kfree((*buf)->data[idx]);
-
- for (--idx; idx >= 0; --idx)
+ for (; idx >= 0; --idx)
kfree((*buf)->data[idx]);
kfree(*buf);
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 68175b54504b..61acb8f6756d 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -1217,7 +1217,6 @@ int drm_infobufs(struct drm_device *dev, void *data,
struct drm_buf_desc __user *to =
&request->list[count];
struct drm_buf_entry *from = &dma->bufs[i];
- struct drm_freelist *list = &dma->bufs[i].freelist;
if (copy_to_user(&to->count,
&from->buf_count,
sizeof(from->buf_count)) ||
@@ -1225,19 +1224,19 @@ int drm_infobufs(struct drm_device *dev, void *data,
&from->buf_size,
sizeof(from->buf_size)) ||
copy_to_user(&to->low_mark,
- &list->low_mark,
- sizeof(list->low_mark)) ||
+ &from->low_mark,
+ sizeof(from->low_mark)) ||
copy_to_user(&to->high_mark,
- &list->high_mark,
- sizeof(list->high_mark)))
+ &from->high_mark,
+ sizeof(from->high_mark)))
return -EFAULT;
DRM_DEBUG("%d %d %d %d %d\n",
i,
dma->bufs[i].buf_count,
dma->bufs[i].buf_size,
- dma->bufs[i].freelist.low_mark,
- dma->bufs[i].freelist.high_mark);
+ dma->bufs[i].low_mark,
+ dma->bufs[i].high_mark);
++count;
}
}
@@ -1290,8 +1289,8 @@ int drm_markbufs(struct drm_device *dev, void *data,
if (request->high_mark < 0 || request->high_mark > entry->buf_count)
return -EINVAL;
- entry->freelist.low_mark = request->low_mark;
- entry->freelist.high_mark = request->high_mark;
+ entry->low_mark = request->low_mark;
+ entry->high_mark = request->high_mark;
return 0;
}
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index a4b017b6849e..9b23525c0ed0 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -1,18 +1,13 @@
-/**
- * \file drm_context.c
- * IOCTLs for generic contexts
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
/*
- * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
+ * Legacy: Generic DRM Contexts
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
+ * Author: Rickard E. (Rik) Faith <faith@valinux.com>
+ * Author: Gareth Hughes <gareth@valinux.com>
+ *
* 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
@@ -33,14 +28,14 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-/*
- * ChangeLog:
- * 2001-11-16 Torsten Duwe <duwe@caldera.de>
- * added context constructor/destructor hooks,
- * needed by SiS driver's memory management.
- */
-
#include <drm/drmP.h>
+#include "drm_legacy.h"
+
+struct drm_ctx_list {
+ struct list_head head;
+ drm_context_t handle;
+ struct drm_file *tag;
+};
/******************************************************************/
/** \name Context bitmap support */
@@ -56,7 +51,7 @@
* in drm_device::ctx_idr, while holding the drm_device::struct_mutex
* lock.
*/
-void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
+void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
{
mutex_lock(&dev->struct_mutex);
idr_remove(&dev->ctx_idr, ctx_handle);
@@ -72,7 +67,7 @@ void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
* Allocate a new idr from drm_device::ctx_idr while holding the
* drm_device::struct_mutex lock.
*/
-static int drm_ctxbitmap_next(struct drm_device * dev)
+static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
{
int ret;
@@ -90,7 +85,7 @@ static int drm_ctxbitmap_next(struct drm_device * dev)
*
* Initialise the drm_device::ctx_idr
*/
-int drm_ctxbitmap_init(struct drm_device * dev)
+int drm_legacy_ctxbitmap_init(struct drm_device * dev)
{
idr_init(&dev->ctx_idr);
return 0;
@@ -104,13 +99,43 @@ int drm_ctxbitmap_init(struct drm_device * dev)
* Free all idr members using drm_ctx_sarea_free helper function
* while holding the drm_device::struct_mutex lock.
*/
-void drm_ctxbitmap_cleanup(struct drm_device * dev)
+void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
{
mutex_lock(&dev->struct_mutex);
idr_destroy(&dev->ctx_idr);
mutex_unlock(&dev->struct_mutex);
}
+/**
+ * drm_ctxbitmap_flush() - Flush all contexts owned by a file
+ * @dev: DRM device to operate on
+ * @file: Open file to flush contexts for
+ *
+ * This iterates over all contexts on @dev and drops them if they're owned by
+ * @file. Note that after this call returns, new contexts might be added if
+ * the file is still alive.
+ */
+void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
+{
+ struct drm_ctx_list *pos, *tmp;
+
+ mutex_lock(&dev->ctxlist_mutex);
+
+ list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
+ if (pos->tag == file &&
+ pos->handle != DRM_KERNEL_CONTEXT) {
+ if (dev->driver->context_dtor)
+ dev->driver->context_dtor(dev, pos->handle);
+
+ drm_legacy_ctxbitmap_free(dev, pos->handle);
+ list_del(&pos->head);
+ kfree(pos);
+ }
+ }
+
+ mutex_unlock(&dev->ctxlist_mutex);
+}
+
/*@}*/
/******************************************************************/
@@ -129,8 +154,8 @@ void drm_ctxbitmap_cleanup(struct drm_device * dev)
* Gets the map from drm_device::ctx_idr with the handle specified and
* returns its handle.
*/
-int drm_getsareactx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_getsareactx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
struct drm_local_map *map;
@@ -173,8 +198,8 @@ int drm_getsareactx(struct drm_device *dev, void *data,
* Searches the mapping specified in \p arg and update the entry in
* drm_device::ctx_idr with it.
*/
-int drm_setsareactx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_setsareactx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
struct drm_local_map *map = NULL;
@@ -273,8 +298,8 @@ static int drm_context_switch_complete(struct drm_device *dev,
* \param arg user argument pointing to a drm_ctx_res structure.
* \return zero on success or a negative number on failure.
*/
-int drm_resctx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_resctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx_res *res = data;
struct drm_ctx ctx;
@@ -304,16 +329,16 @@ int drm_resctx(struct drm_device *dev, void *data,
*
* Get a new handle for the context and copy to userspace.
*/
-int drm_addctx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_addctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx_list *ctx_entry;
struct drm_ctx *ctx = data;
- ctx->handle = drm_ctxbitmap_next(dev);
+ ctx->handle = drm_legacy_ctxbitmap_next(dev);
if (ctx->handle == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
- ctx->handle = drm_ctxbitmap_next(dev);
+ ctx->handle = drm_legacy_ctxbitmap_next(dev);
}
DRM_DEBUG("%d\n", ctx->handle);
if (ctx->handle == -1) {
@@ -348,7 +373,8 @@ int drm_addctx(struct drm_device *dev, void *data,
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*/
-int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int drm_legacy_getctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
@@ -369,8 +395,8 @@ int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
*
* Calls context_switch().
*/
-int drm_switchctx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_switchctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
@@ -389,8 +415,8 @@ int drm_switchctx(struct drm_device *dev, void *data,
*
* Calls context_switch_complete().
*/
-int drm_newctx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_newctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
@@ -411,8 +437,8 @@ int drm_newctx(struct drm_device *dev, void *data,
*
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
*/
-int drm_rmctx(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_rmctx(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_ctx *ctx = data;
@@ -420,7 +446,7 @@ int drm_rmctx(struct drm_device *dev, void *data,
if (ctx->handle != DRM_KERNEL_CONTEXT) {
if (dev->driver->context_dtor)
dev->driver->context_dtor(dev, ctx->handle);
- drm_ctxbitmap_free(dev, ctx->handle);
+ drm_legacy_ctxbitmap_free(dev, ctx->handle);
}
mutex_lock(&dev->ctxlist_mutex);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index fe94cc10cd35..fa2be249999c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -41,6 +41,10 @@
#include "drm_crtc_internal.h"
+static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
+ struct drm_mode_fb_cmd2 *r,
+ struct drm_file *file_priv);
+
/**
* drm_modeset_lock_all - take all modeset locks
* @dev: drm device
@@ -178,6 +182,12 @@ static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
};
+static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
+ { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },
+ { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },
+ { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
+};
+
/*
* Non-global properties, but "required" for certain connectors.
*/
@@ -357,6 +367,32 @@ const char *drm_get_format_name(uint32_t format)
}
EXPORT_SYMBOL(drm_get_format_name);
+/*
+ * Internal function to assign a slot in the object idr and optionally
+ * register the object into the idr.
+ */
+static int drm_mode_object_get_reg(struct drm_device *dev,
+ struct drm_mode_object *obj,
+ uint32_t obj_type,
+ bool register_obj)
+{
+ int ret;
+
+ mutex_lock(&dev->mode_config.idr_mutex);
+ ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL);
+ if (ret >= 0) {
+ /*
+ * Set up the object linking under the protection of the idr
+ * lock so that other users can't see inconsistent state.
+ */
+ obj->id = ret;
+ obj->type = obj_type;
+ }
+ mutex_unlock(&dev->mode_config.idr_mutex);
+
+ return ret < 0 ? ret : 0;
+}
+
/**
* drm_mode_object_get - allocate a new modeset identifier
* @dev: DRM device
@@ -375,21 +411,15 @@ EXPORT_SYMBOL(drm_get_format_name);
int drm_mode_object_get(struct drm_device *dev,
struct drm_mode_object *obj, uint32_t obj_type)
{
- int ret;
+ return drm_mode_object_get_reg(dev, obj, obj_type, true);
+}
+static void drm_mode_object_register(struct drm_device *dev,
+ struct drm_mode_object *obj)
+{
mutex_lock(&dev->mode_config.idr_mutex);
- ret = idr_alloc(&dev->mode_config.crtc_idr, obj, 1, 0, GFP_KERNEL);
- if (ret >= 0) {
- /*
- * Set up the object linking under the protection of the idr
- * lock so that other users can't see inconsistent state.
- */
- obj->id = ret;
- obj->type = obj_type;
- }
+ idr_replace(&dev->mode_config.crtc_idr, obj, obj->id);
mutex_unlock(&dev->mode_config.idr_mutex);
-
- return ret < 0 ? ret : 0;
}
/**
@@ -416,8 +446,12 @@ static struct drm_mode_object *_object_find(struct drm_device *dev,
mutex_lock(&dev->mode_config.idr_mutex);
obj = idr_find(&dev->mode_config.crtc_idr, id);
- if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) ||
- (obj->id != id))
+ if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type)
+ obj = NULL;
+ if (obj && obj->id != id)
+ obj = NULL;
+ /* don't leak out unref'd fb's */
+ if (obj && (obj->type == DRM_MODE_OBJECT_FB))
obj = NULL;
mutex_unlock(&dev->mode_config.idr_mutex);
@@ -444,9 +478,6 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
* function.*/
WARN_ON(type == DRM_MODE_OBJECT_FB);
obj = _object_find(dev, id, type);
- /* don't leak out unref'd fb's */
- if (obj && (obj->type == DRM_MODE_OBJECT_FB))
- obj = NULL;
return obj;
}
EXPORT_SYMBOL(drm_mode_object_find);
@@ -723,7 +754,7 @@ DEFINE_WW_CLASS(crtc_ww_class);
*/
int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_plane *primary,
- void *cursor,
+ struct drm_plane *cursor,
const struct drm_crtc_funcs *funcs)
{
struct drm_mode_config *config = &dev->mode_config;
@@ -748,8 +779,11 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
config->num_crtc++;
crtc->primary = primary;
+ crtc->cursor = cursor;
if (primary)
primary->possible_crtcs = 1 << drm_crtc_index(crtc);
+ if (cursor)
+ cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
out:
drm_modeset_unlock_all(dev);
@@ -842,7 +876,7 @@ int drm_connector_init(struct drm_device *dev,
drm_modeset_lock_all(dev);
- ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
+ ret = drm_mode_object_get_reg(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false);
if (ret)
goto out_unlock;
@@ -881,6 +915,8 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(&connector->base,
dev->mode_config.dpms_property, 0);
+ connector->debugfs_entry = NULL;
+
out_put:
if (ret)
drm_mode_object_put(dev, &connector->base);
@@ -921,6 +957,49 @@ void drm_connector_cleanup(struct drm_connector *connector)
EXPORT_SYMBOL(drm_connector_cleanup);
/**
+ * drm_connector_register - register a connector
+ * @connector: the connector to register
+ *
+ * Register userspace interfaces for a connector
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_register(struct drm_connector *connector)
+{
+ int ret;
+
+ drm_mode_object_register(connector->dev, &connector->base);
+
+ ret = drm_sysfs_connector_add(connector);
+ if (ret)
+ return ret;
+
+ ret = drm_debugfs_connector_add(connector);
+ if (ret) {
+ drm_sysfs_connector_remove(connector);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_register);
+
+/**
+ * drm_connector_unregister - unregister a connector
+ * @connector: the connector to unregister
+ *
+ * Unregister userspace interfaces for a connector
+ */
+void drm_connector_unregister(struct drm_connector *connector)
+{
+ drm_sysfs_connector_remove(connector);
+ drm_debugfs_connector_remove(connector);
+}
+EXPORT_SYMBOL(drm_connector_unregister);
+
+
+/**
* drm_connector_unplug_all - unregister connector userspace interfaces
* @dev: drm device
*
@@ -934,7 +1013,7 @@ void drm_connector_unplug_all(struct drm_device *dev)
/* taking the mode config mutex ends up in a clash with sysfs */
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
}
EXPORT_SYMBOL(drm_connector_unplug_all);
@@ -1214,6 +1293,7 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
{
struct drm_property *edid;
struct drm_property *dpms;
+ struct drm_property *dev_path;
/*
* Standard properties (apply to all connectors)
@@ -1228,6 +1308,12 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
ARRAY_SIZE(drm_dpms_enum_list));
dev->mode_config.dpms_property = dpms;
+ dev_path = drm_property_create(dev,
+ DRM_MODE_PROP_BLOB |
+ DRM_MODE_PROP_IMMUTABLE,
+ "PATH", 0);
+ dev->mode_config.path_property = dev_path;
+
return 0;
}
@@ -1384,6 +1470,33 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev)
EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
/**
+ * drm_mode_create_aspect_ratio_property - create aspect ratio property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ *
+ * Returns:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
+{
+ if (dev->mode_config.aspect_ratio_property)
+ return 0;
+
+ dev->mode_config.aspect_ratio_property =
+ drm_property_create_enum(dev, 0, "aspect ratio",
+ drm_aspect_ratio_enum_list,
+ ARRAY_SIZE(drm_aspect_ratio_enum_list));
+
+ if (dev->mode_config.aspect_ratio_property == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
+
+/**
* drm_mode_create_dirty_property - create dirty property
* @dev: DRM device
*
@@ -1470,6 +1583,15 @@ int drm_mode_group_init_legacy_group(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_mode_group_init_legacy_group);
+void drm_reinit_primary_mode_group(struct drm_device *dev)
+{
+ drm_modeset_lock_all(dev);
+ drm_mode_group_destroy(&dev->primary->mode_group);
+ drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
+ drm_modeset_unlock_all(dev);
+}
+EXPORT_SYMBOL(drm_reinit_primary_mode_group);
+
/**
* drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
* @out: drm_mode_modeinfo struct to return to the user
@@ -2118,45 +2240,32 @@ out:
return ret;
}
-/**
- * drm_mode_setplane - configure a plane's configuration
- * @dev: DRM device
- * @data: ioctl data*
- * @file_priv: DRM file info
+/*
+ * setplane_internal - setplane handler for internal callers
*
- * Set plane configuration, including placement, fb, scaling, and other factors.
- * Or pass a NULL fb to disable.
+ * Note that we assume an extra reference has already been taken on fb. If the
+ * update fails, this reference will be dropped before return; if it succeeds,
+ * the previous framebuffer (if any) will be unreferenced instead.
*
- * Returns:
- * Zero on success, errno on failure.
+ * src_{x,y,w,h} are provided in 16.16 fixed point format
*/
-int drm_mode_setplane(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+static int setplane_internal(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int32_t crtc_x, int32_t crtc_y,
+ uint32_t crtc_w, uint32_t crtc_h,
+ /* src_{x,y,w,h} values are 16.16 fixed point */
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
{
- struct drm_mode_set_plane *plane_req = data;
- struct drm_plane *plane;
- struct drm_crtc *crtc;
- struct drm_framebuffer *fb = NULL, *old_fb = NULL;
+ struct drm_device *dev = plane->dev;
+ struct drm_framebuffer *old_fb = NULL;
int ret = 0;
unsigned int fb_width, fb_height;
int i;
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
- return -EINVAL;
-
- /*
- * First, find the plane, crtc, and fb objects. If not available,
- * we don't bother to call the driver.
- */
- plane = drm_plane_find(dev, plane_req->plane_id);
- if (!plane) {
- DRM_DEBUG_KMS("Unknown plane ID %d\n",
- plane_req->plane_id);
- return -ENOENT;
- }
-
/* No fb means shut it down */
- if (!plane_req->fb_id) {
+ if (!fb) {
drm_modeset_lock_all(dev);
old_fb = plane->fb;
ret = plane->funcs->disable_plane(plane);
@@ -2170,14 +2279,6 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
goto out;
}
- crtc = drm_crtc_find(dev, plane_req->crtc_id);
- if (!crtc) {
- DRM_DEBUG_KMS("Unknown crtc ID %d\n",
- plane_req->crtc_id);
- ret = -ENOENT;
- goto out;
- }
-
/* Check whether this plane is usable on this CRTC */
if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
DRM_DEBUG_KMS("Invalid crtc for plane\n");
@@ -2185,14 +2286,6 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
goto out;
}
- fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
- if (!fb) {
- DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
- plane_req->fb_id);
- ret = -ENOENT;
- goto out;
- }
-
/* Check whether this plane supports the fb pixel format. */
for (i = 0; i < plane->format_count; i++)
if (fb->pixel_format == plane->format_types[i])
@@ -2208,43 +2301,25 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
fb_height = fb->height << 16;
/* Make sure source coordinates are inside the fb. */
- if (plane_req->src_w > fb_width ||
- plane_req->src_x > fb_width - plane_req->src_w ||
- plane_req->src_h > fb_height ||
- plane_req->src_y > fb_height - plane_req->src_h) {
+ if (src_w > fb_width ||
+ src_x > fb_width - src_w ||
+ src_h > fb_height ||
+ src_y > fb_height - src_h) {
DRM_DEBUG_KMS("Invalid source coordinates "
"%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
- plane_req->src_w >> 16,
- ((plane_req->src_w & 0xffff) * 15625) >> 10,
- plane_req->src_h >> 16,
- ((plane_req->src_h & 0xffff) * 15625) >> 10,
- plane_req->src_x >> 16,
- ((plane_req->src_x & 0xffff) * 15625) >> 10,
- plane_req->src_y >> 16,
- ((plane_req->src_y & 0xffff) * 15625) >> 10);
+ src_w >> 16, ((src_w & 0xffff) * 15625) >> 10,
+ src_h >> 16, ((src_h & 0xffff) * 15625) >> 10,
+ src_x >> 16, ((src_x & 0xffff) * 15625) >> 10,
+ src_y >> 16, ((src_y & 0xffff) * 15625) >> 10);
ret = -ENOSPC;
goto out;
}
- /* Give drivers some help against integer overflows */
- if (plane_req->crtc_w > INT_MAX ||
- plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
- plane_req->crtc_h > INT_MAX ||
- plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
- DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
- plane_req->crtc_w, plane_req->crtc_h,
- plane_req->crtc_x, plane_req->crtc_y);
- ret = -ERANGE;
- goto out;
- }
-
drm_modeset_lock_all(dev);
old_fb = plane->fb;
ret = plane->funcs->update_plane(plane, crtc, fb,
- plane_req->crtc_x, plane_req->crtc_y,
- plane_req->crtc_w, plane_req->crtc_h,
- plane_req->src_x, plane_req->src_y,
- plane_req->src_w, plane_req->src_h);
+ crtc_x, crtc_y, crtc_w, crtc_h,
+ src_x, src_y, src_w, src_h);
if (!ret) {
plane->crtc = crtc;
plane->fb = fb;
@@ -2261,6 +2336,85 @@ out:
drm_framebuffer_unreference(old_fb);
return ret;
+
+}
+
+/**
+ * drm_mode_setplane - configure a plane's configuration
+ * @dev: DRM device
+ * @data: ioctl data*
+ * @file_priv: DRM file info
+ *
+ * Set plane configuration, including placement, fb, scaling, and other factors.
+ * Or pass a NULL fb to disable (planes may be disabled without providing a
+ * valid crtc).
+ *
+ * Returns:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_setplane(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_mode_set_plane *plane_req = data;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct drm_crtc *crtc = NULL;
+ struct drm_framebuffer *fb = NULL;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ /* Give drivers some help against integer overflows */
+ if (plane_req->crtc_w > INT_MAX ||
+ plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
+ plane_req->crtc_h > INT_MAX ||
+ plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
+ DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
+ plane_req->crtc_w, plane_req->crtc_h,
+ plane_req->crtc_x, plane_req->crtc_y);
+ return -ERANGE;
+ }
+
+ /*
+ * First, find the plane, crtc, and fb objects. If not available,
+ * we don't bother to call the driver.
+ */
+ obj = drm_mode_object_find(dev, plane_req->plane_id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ DRM_DEBUG_KMS("Unknown plane ID %d\n",
+ plane_req->plane_id);
+ return -ENOENT;
+ }
+ plane = obj_to_plane(obj);
+
+ if (plane_req->fb_id) {
+ fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
+ if (!fb) {
+ DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
+ plane_req->fb_id);
+ return -ENOENT;
+ }
+
+ obj = drm_mode_object_find(dev, plane_req->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!obj) {
+ DRM_DEBUG_KMS("Unknown crtc ID %d\n",
+ plane_req->crtc_id);
+ return -ENOENT;
+ }
+ crtc = obj_to_crtc(obj);
+ }
+
+ /*
+ * setplane_internal will take care of deref'ing either the old or new
+ * framebuffer depending on success.
+ */
+ return setplane_internal(plane, crtc, fb,
+ plane_req->crtc_x, plane_req->crtc_y,
+ plane_req->crtc_w, plane_req->crtc_h,
+ plane_req->src_x, plane_req->src_y,
+ plane_req->src_w, plane_req->src_h);
}
/**
@@ -2509,6 +2663,102 @@ out:
return ret;
}
+/**
+ * drm_mode_cursor_universal - translate legacy cursor ioctl call into a
+ * universal plane handler call
+ * @crtc: crtc to update cursor for
+ * @req: data pointer for the ioctl
+ * @file_priv: drm file for the ioctl call
+ *
+ * Legacy cursor ioctl's work directly with driver buffer handles. To
+ * translate legacy ioctl calls into universal plane handler calls, we need to
+ * wrap the native buffer handle in a drm_framebuffer.
+ *
+ * Note that we assume any handle passed to the legacy ioctls was a 32-bit ARGB
+ * buffer with a pitch of 4*width; the universal plane interface should be used
+ * directly in cases where the hardware can support other buffer settings and
+ * userspace wants to make use of these capabilities.
+ *
+ * Returns:
+ * Zero on success, errno on failure.
+ */
+static int drm_mode_cursor_universal(struct drm_crtc *crtc,
+ struct drm_mode_cursor2 *req,
+ struct drm_file *file_priv)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_framebuffer *fb = NULL;
+ struct drm_mode_fb_cmd2 fbreq = {
+ .width = req->width,
+ .height = req->height,
+ .pixel_format = DRM_FORMAT_ARGB8888,
+ .pitches = { req->width * 4 },
+ .handles = { req->handle },
+ };
+ int32_t crtc_x, crtc_y;
+ uint32_t crtc_w = 0, crtc_h = 0;
+ uint32_t src_w = 0, src_h = 0;
+ int ret = 0;
+
+ BUG_ON(!crtc->cursor);
+
+ /*
+ * Obtain fb we'll be using (either new or existing) and take an extra
+ * reference to it if fb != null. setplane will take care of dropping
+ * the reference if the plane update fails.
+ */
+ if (req->flags & DRM_MODE_CURSOR_BO) {
+ if (req->handle) {
+ fb = add_framebuffer_internal(dev, &fbreq, file_priv);
+ if (IS_ERR(fb)) {
+ DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n");
+ return PTR_ERR(fb);
+ }
+
+ drm_framebuffer_reference(fb);
+ } else {
+ fb = NULL;
+ }
+ } else {
+ mutex_lock(&dev->mode_config.mutex);
+ fb = crtc->cursor->fb;
+ if (fb)
+ drm_framebuffer_reference(fb);
+ mutex_unlock(&dev->mode_config.mutex);
+ }
+
+ if (req->flags & DRM_MODE_CURSOR_MOVE) {
+ crtc_x = req->x;
+ crtc_y = req->y;
+ } else {
+ crtc_x = crtc->cursor_x;
+ crtc_y = crtc->cursor_y;
+ }
+
+ if (fb) {
+ crtc_w = fb->width;
+ crtc_h = fb->height;
+ src_w = fb->width << 16;
+ src_h = fb->height << 16;
+ }
+
+ /*
+ * setplane_internal will take care of deref'ing either the old or new
+ * framebuffer depending on success.
+ */
+ ret = setplane_internal(crtc->cursor, crtc, fb,
+ crtc_x, crtc_y, crtc_w, crtc_h,
+ 0, 0, src_w, src_h);
+
+ /* Update successful; save new cursor position, if necessary */
+ if (ret == 0 && req->flags & DRM_MODE_CURSOR_MOVE) {
+ crtc->cursor_x = req->x;
+ crtc->cursor_y = req->y;
+ }
+
+ return ret;
+}
+
static int drm_mode_cursor_common(struct drm_device *dev,
struct drm_mode_cursor2 *req,
struct drm_file *file_priv)
@@ -2528,6 +2778,13 @@ static int drm_mode_cursor_common(struct drm_device *dev,
return -ENOENT;
}
+ /*
+ * If this crtc has a universal cursor plane, call that plane's update
+ * handler rather than using legacy cursor handlers.
+ */
+ if (crtc->cursor)
+ return drm_mode_cursor_universal(crtc, req, file_priv);
+
drm_modeset_lock(&crtc->mutex, NULL);
if (req->flags & DRM_MODE_CURSOR_BO) {
if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
@@ -2827,56 +3084,38 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
return 0;
}
-/**
- * drm_mode_addfb2 - add an FB to the graphics configuration
- * @dev: drm device for the ioctl
- * @data: data pointer for the ioctl
- * @file_priv: drm file for the ioctl call
- *
- * Add a new FB to the specified CRTC, given a user request with format. This is
- * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
- * and uses fourcc codes as pixel format specifiers.
- *
- * Called by the user via ioctl.
- *
- * Returns:
- * Zero on success, errno on failure.
- */
-int drm_mode_addfb2(struct drm_device *dev,
- void *data, struct drm_file *file_priv)
+static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
+ struct drm_mode_fb_cmd2 *r,
+ struct drm_file *file_priv)
{
- struct drm_mode_fb_cmd2 *r = data;
struct drm_mode_config *config = &dev->mode_config;
struct drm_framebuffer *fb;
int ret;
- if (!drm_core_check_feature(dev, DRIVER_MODESET))
- return -EINVAL;
-
if (r->flags & ~DRM_MODE_FB_INTERLACED) {
DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
if ((config->min_width > r->width) || (r->width > config->max_width)) {
DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",
r->width, config->min_width, config->max_width);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
if ((config->min_height > r->height) || (r->height > config->max_height)) {
DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",
r->height, config->min_height, config->max_height);
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
ret = framebuffer_check(r);
if (ret)
- return ret;
+ return ERR_PTR(ret);
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) {
DRM_DEBUG_KMS("could not create framebuffer\n");
- return PTR_ERR(fb);
+ return fb;
}
mutex_lock(&file_priv->fbs_lock);
@@ -2885,8 +3124,37 @@ int drm_mode_addfb2(struct drm_device *dev,
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
mutex_unlock(&file_priv->fbs_lock);
+ return fb;
+}
- return ret;
+/**
+ * drm_mode_addfb2 - add an FB to the graphics configuration
+ * @dev: drm device for the ioctl
+ * @data: data pointer for the ioctl
+ * @file_priv: drm file for the ioctl call
+ *
+ * Add a new FB to the specified CRTC, given a user request with format. This is
+ * the 2nd version of the addfb ioctl, which supports multi-planar framebuffers
+ * and uses fourcc codes as pixel format specifiers.
+ *
+ * Called by the user via ioctl.
+ *
+ * Returns:
+ * Zero on success, errno on failure.
+ */
+int drm_mode_addfb2(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_framebuffer *fb;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return -EINVAL;
+
+ fb = add_framebuffer_internal(dev, data, file_priv);
+ if (IS_ERR(fb))
+ return PTR_ERR(fb);
+
+ return 0;
}
/**
@@ -3176,7 +3444,7 @@ fail:
EXPORT_SYMBOL(drm_property_create);
/**
- * drm_property_create - create a new enumeration property type
+ * drm_property_create_enum - create a new enumeration property type
* @dev: drm device
* @flags: flags specifying the property type
* @name: name of the property
@@ -3222,7 +3490,7 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
EXPORT_SYMBOL(drm_property_create_enum);
/**
- * drm_property_create - create a new bitmask property type
+ * drm_property_create_bitmask - create a new bitmask property type
* @dev: drm device
* @flags: flags specifying the property type
* @name: name of the property
@@ -3242,19 +3510,28 @@ EXPORT_SYMBOL(drm_property_create_enum);
struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
int flags, const char *name,
const struct drm_prop_enum_list *props,
- int num_values)
+ int num_props,
+ uint64_t supported_bits)
{
struct drm_property *property;
- int i, ret;
+ int i, ret, index = 0;
+ int num_values = hweight64(supported_bits);
flags |= DRM_MODE_PROP_BITMASK;
property = drm_property_create(dev, flags, name, num_values);
if (!property)
return NULL;
+ for (i = 0; i < num_props; i++) {
+ if (!(supported_bits & (1ULL << props[i].type)))
+ continue;
- for (i = 0; i < num_values; i++) {
- ret = drm_property_add_enum(property, i,
+ if (WARN_ON(index >= num_values)) {
+ drm_property_destroy(dev, property);
+ return NULL;
+ }
+
+ ret = drm_property_add_enum(property, index++,
props[i].type,
props[i].name);
if (ret) {
@@ -3284,7 +3561,7 @@ static struct drm_property *property_create_range(struct drm_device *dev,
}
/**
- * drm_property_create - create a new ranged property type
+ * drm_property_create_range - create a new ranged property type
* @dev: drm device
* @flags: flags specifying the property type
* @name: name of the property
@@ -3703,6 +3980,25 @@ done:
return ret;
}
+int drm_mode_connector_set_path_property(struct drm_connector *connector,
+ char *path)
+{
+ struct drm_device *dev = connector->dev;
+ int ret, size;
+ size = strlen(path) + 1;
+
+ connector->path_blob_ptr = drm_property_create_blob(connector->dev,
+ size, path);
+ if (!connector->path_blob_ptr)
+ return -EINVAL;
+
+ ret = drm_object_property_set_value(&connector->base,
+ dev->mode_config.path_property,
+ connector->path_blob_ptr->base.id);
+ return ret;
+}
+EXPORT_SYMBOL(drm_mode_connector_set_path_property);
+
/**
* drm_mode_connector_update_edid_property - update the edid property of a connector
* @connector: drm connector
@@ -3720,6 +4016,10 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct drm_device *dev = connector->dev;
int ret, size;
+ /* ignore requests to set edid when overridden */
+ if (connector->override_edid)
+ return 0;
+
if (connector->edid_blob_ptr)
drm_property_destroy_blob(dev, connector->edid_blob_ptr);
@@ -4680,6 +4980,36 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
/**
+ * drm_rotation_simplify() - Try to simplify the rotation
+ * @rotation: Rotation to be simplified
+ * @supported_rotations: Supported rotations
+ *
+ * Attempt to simplify the rotation to a form that is supported.
+ * Eg. if the hardware supports everything except DRM_REFLECT_X
+ * one could call this function like this:
+ *
+ * drm_rotation_simplify(rotation, BIT(DRM_ROTATE_0) |
+ * BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_180) |
+ * BIT(DRM_ROTATE_270) | BIT(DRM_REFLECT_Y));
+ *
+ * to eliminate the DRM_ROTATE_X flag. Depending on what kind of
+ * transforms the hardware supports, this function may not
+ * be able to produce a supported transform, so the caller should
+ * check the result afterwards.
+ */
+unsigned int drm_rotation_simplify(unsigned int rotation,
+ unsigned int supported_rotations)
+{
+ if (rotation & ~supported_rotations) {
+ rotation ^= BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y);
+ rotation = (rotation & ~0xf) | BIT((ffs(rotation & 0xf) + 1) % 4);
+ }
+
+ return rotation;
+}
+EXPORT_SYMBOL(drm_rotation_simplify);
+
+/**
* drm_mode_config_init - initialize DRM mode_configuration structure
* @dev: DRM device
*
@@ -4797,3 +5127,21 @@ void drm_mode_config_cleanup(struct drm_device *dev)
drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
+
+struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
+ unsigned int supported_rotations)
+{
+ static const struct drm_prop_enum_list props[] = {
+ { DRM_ROTATE_0, "rotate-0" },
+ { DRM_ROTATE_90, "rotate-90" },
+ { DRM_ROTATE_180, "rotate-180" },
+ { DRM_ROTATE_270, "rotate-270" },
+ { DRM_REFLECT_X, "reflect-x" },
+ { DRM_REFLECT_Y, "reflect-y" },
+ };
+
+ return drm_property_create_bitmask(dev, 0, "rotation",
+ props, ARRAY_SIZE(props),
+ supported_rotations);
+}
+EXPORT_SYMBOL(drm_mode_create_rotation_property);
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 78b37f3febd3..6c65a0a28fbd 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -818,6 +818,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
&fb->bits_per_pixel);
fb->pixel_format = mode_cmd->pixel_format;
+ fb->flags = mode_cmd->flags;
}
EXPORT_SYMBOL(drm_helper_mode_fill_fb_struct);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index b4b51d46f339..13bd42923dd4 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <drm/drmP.h>
+#include <drm/drm_edid.h>
#if defined(CONFIG_DEBUG_FS)
@@ -237,5 +238,186 @@ int drm_debugfs_cleanup(struct drm_minor *minor)
return 0;
}
+static int connector_show(struct seq_file *m, void *data)
+{
+ struct drm_connector *connector = m->private;
+ const char *status;
+
+ switch (connector->force) {
+ case DRM_FORCE_ON:
+ status = "on\n";
+ break;
+
+ case DRM_FORCE_ON_DIGITAL:
+ status = "digital\n";
+ break;
+
+ case DRM_FORCE_OFF:
+ status = "off\n";
+ break;
+
+ case DRM_FORCE_UNSPECIFIED:
+ status = "unspecified\n";
+ break;
+
+ default:
+ return 0;
+ }
+
+ seq_puts(m, status);
+
+ return 0;
+}
+
+static int connector_open(struct inode *inode, struct file *file)
+{
+ struct drm_connector *dev = inode->i_private;
+
+ return single_open(file, connector_show, dev);
+}
+
+static ssize_t connector_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct drm_connector *connector = m->private;
+ char buf[12];
+
+ if (len > sizeof(buf) - 1)
+ return -EINVAL;
+
+ if (copy_from_user(buf, ubuf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+
+ if (!strcmp(buf, "on"))
+ connector->force = DRM_FORCE_ON;
+ else if (!strcmp(buf, "digital"))
+ connector->force = DRM_FORCE_ON_DIGITAL;
+ else if (!strcmp(buf, "off"))
+ connector->force = DRM_FORCE_OFF;
+ else if (!strcmp(buf, "unspecified"))
+ connector->force = DRM_FORCE_UNSPECIFIED;
+ else
+ return -EINVAL;
+
+ return len;
+}
+
+static int edid_show(struct seq_file *m, void *data)
+{
+ struct drm_connector *connector = m->private;
+ struct drm_property_blob *edid = connector->edid_blob_ptr;
+
+ if (connector->override_edid && edid)
+ seq_write(m, edid->data, edid->length);
+
+ return 0;
+}
+
+static int edid_open(struct inode *inode, struct file *file)
+{
+ struct drm_connector *dev = inode->i_private;
+
+ return single_open(file, edid_show, dev);
+}
+
+static ssize_t edid_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct seq_file *m = file->private_data;
+ struct drm_connector *connector = m->private;
+ char *buf;
+ struct edid *edid;
+ int ret;
+
+ buf = memdup_user(ubuf, len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ edid = (struct edid *) buf;
+
+ if (len == 5 && !strncmp(buf, "reset", 5)) {
+ connector->override_edid = false;
+ ret = drm_mode_connector_update_edid_property(connector, NULL);
+ } else if (len < EDID_LENGTH ||
+ EDID_LENGTH * (1 + edid->extensions) > len)
+ ret = -EINVAL;
+ else {
+ connector->override_edid = false;
+ ret = drm_mode_connector_update_edid_property(connector, edid);
+ if (!ret)
+ connector->override_edid = true;
+ }
+
+ kfree(buf);
+
+ return (ret) ? ret : len;
+}
+
+static const struct file_operations drm_edid_fops = {
+ .owner = THIS_MODULE,
+ .open = edid_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = edid_write
+};
+
+
+static const struct file_operations drm_connector_fops = {
+ .owner = THIS_MODULE,
+ .open = connector_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = connector_write
+};
+
+int drm_debugfs_connector_add(struct drm_connector *connector)
+{
+ struct drm_minor *minor = connector->dev->primary;
+ struct dentry *root, *ent;
+
+ if (!minor->debugfs_root)
+ return -1;
+
+ root = debugfs_create_dir(connector->name, minor->debugfs_root);
+ if (!root)
+ return -ENOMEM;
+
+ connector->debugfs_entry = root;
+
+ /* force */
+ ent = debugfs_create_file("force", S_IRUGO | S_IWUSR, root, connector,
+ &drm_connector_fops);
+ if (!ent)
+ goto error;
+
+ /* edid */
+ ent = debugfs_create_file("edid_override", S_IRUGO | S_IWUSR, root,
+ connector, &drm_edid_fops);
+ if (!ent)
+ goto error;
+
+ return 0;
+
+error:
+ debugfs_remove_recursive(connector->debugfs_entry);
+ connector->debugfs_entry = NULL;
+ return -ENOMEM;
+}
+
+void drm_debugfs_connector_remove(struct drm_connector *connector)
+{
+ if (!connector->debugfs_entry)
+ return;
+
+ debugfs_remove_recursive(connector->debugfs_entry);
+
+ connector->debugfs_entry = NULL;
+}
+
#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
new file mode 100644
index 000000000000..ac3c2738db94
--- /dev/null
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -0,0 +1,2715 @@
+/*
+ * Copyright © 2014 Red Hat
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/i2c.h>
+#include <drm/drm_dp_mst_helper.h>
+#include <drm/drmP.h>
+
+#include <drm/drm_fixed.h>
+
+/**
+ * DOC: dp mst helper
+ *
+ * These functions contain parts of the DisplayPort 1.2a MultiStream Transport
+ * protocol. The helpers contain a topology manager and bandwidth manager.
+ * The helpers encapsulate the sending and received of sideband msgs.
+ */
+static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
+ char *buf);
+static int test_calc_pbn_mode(void);
+
+static void drm_dp_put_port(struct drm_dp_mst_port *port);
+
+static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
+ int id,
+ struct drm_dp_payload *payload);
+
+static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int offset, int size, u8 *bytes);
+
+static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb);
+static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_port *port);
+static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
+ u8 *guid);
+
+static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
+static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
+static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
+/* sideband msg handling */
+static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t num_nibbles)
+{
+ u8 bitmask = 0x80;
+ u8 bitshift = 7;
+ u8 array_index = 0;
+ int number_of_bits = num_nibbles * 4;
+ u8 remainder = 0;
+
+ while (number_of_bits != 0) {
+ number_of_bits--;
+ remainder <<= 1;
+ remainder |= (data[array_index] & bitmask) >> bitshift;
+ bitmask >>= 1;
+ bitshift--;
+ if (bitmask == 0) {
+ bitmask = 0x80;
+ bitshift = 7;
+ array_index++;
+ }
+ if ((remainder & 0x10) == 0x10)
+ remainder ^= 0x13;
+ }
+
+ number_of_bits = 4;
+ while (number_of_bits != 0) {
+ number_of_bits--;
+ remainder <<= 1;
+ if ((remainder & 0x10) != 0)
+ remainder ^= 0x13;
+ }
+
+ return remainder;
+}
+
+static u8 drm_dp_msg_data_crc4(const uint8_t *data, u8 number_of_bytes)
+{
+ u8 bitmask = 0x80;
+ u8 bitshift = 7;
+ u8 array_index = 0;
+ int number_of_bits = number_of_bytes * 8;
+ u16 remainder = 0;
+
+ while (number_of_bits != 0) {
+ number_of_bits--;
+ remainder <<= 1;
+ remainder |= (data[array_index] & bitmask) >> bitshift;
+ bitmask >>= 1;
+ bitshift--;
+ if (bitmask == 0) {
+ bitmask = 0x80;
+ bitshift = 7;
+ array_index++;
+ }
+ if ((remainder & 0x100) == 0x100)
+ remainder ^= 0xd5;
+ }
+
+ number_of_bits = 8;
+ while (number_of_bits != 0) {
+ number_of_bits--;
+ remainder <<= 1;
+ if ((remainder & 0x100) != 0)
+ remainder ^= 0xd5;
+ }
+
+ return remainder & 0xff;
+}
+static inline u8 drm_dp_calc_sb_hdr_size(struct drm_dp_sideband_msg_hdr *hdr)
+{
+ u8 size = 3;
+ size += (hdr->lct / 2);
+ return size;
+}
+
+static void drm_dp_encode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
+ u8 *buf, int *len)
+{
+ int idx = 0;
+ int i;
+ u8 crc4;
+ buf[idx++] = ((hdr->lct & 0xf) << 4) | (hdr->lcr & 0xf);
+ for (i = 0; i < (hdr->lct / 2); i++)
+ buf[idx++] = hdr->rad[i];
+ buf[idx++] = (hdr->broadcast << 7) | (hdr->path_msg << 6) |
+ (hdr->msg_len & 0x3f);
+ buf[idx++] = (hdr->somt << 7) | (hdr->eomt << 6) | (hdr->seqno << 4);
+
+ crc4 = drm_dp_msg_header_crc4(buf, (idx * 2) - 1);
+ buf[idx - 1] |= (crc4 & 0xf);
+
+ *len = idx;
+}
+
+static bool drm_dp_decode_sideband_msg_hdr(struct drm_dp_sideband_msg_hdr *hdr,
+ u8 *buf, int buflen, u8 *hdrlen)
+{
+ u8 crc4;
+ u8 len;
+ int i;
+ u8 idx;
+ if (buf[0] == 0)
+ return false;
+ len = 3;
+ len += ((buf[0] & 0xf0) >> 4) / 2;
+ if (len > buflen)
+ return false;
+ crc4 = drm_dp_msg_header_crc4(buf, (len * 2) - 1);
+
+ if ((crc4 & 0xf) != (buf[len - 1] & 0xf)) {
+ DRM_DEBUG_KMS("crc4 mismatch 0x%x 0x%x\n", crc4, buf[len - 1]);
+ return false;
+ }
+
+ hdr->lct = (buf[0] & 0xf0) >> 4;
+ hdr->lcr = (buf[0] & 0xf);
+ idx = 1;
+ for (i = 0; i < (hdr->lct / 2); i++)
+ hdr->rad[i] = buf[idx++];
+ hdr->broadcast = (buf[idx] >> 7) & 0x1;
+ hdr->path_msg = (buf[idx] >> 6) & 0x1;
+ hdr->msg_len = buf[idx] & 0x3f;
+ idx++;
+ hdr->somt = (buf[idx] >> 7) & 0x1;
+ hdr->eomt = (buf[idx] >> 6) & 0x1;
+ hdr->seqno = (buf[idx] >> 4) & 0x1;
+ idx++;
+ *hdrlen = idx;
+ return true;
+}
+
+static void drm_dp_encode_sideband_req(struct drm_dp_sideband_msg_req_body *req,
+ struct drm_dp_sideband_msg_tx *raw)
+{
+ int idx = 0;
+ int i;
+ u8 *buf = raw->msg;
+ buf[idx++] = req->req_type & 0x7f;
+
+ switch (req->req_type) {
+ case DP_ENUM_PATH_RESOURCES:
+ buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
+ idx++;
+ break;
+ case DP_ALLOCATE_PAYLOAD:
+ buf[idx] = (req->u.allocate_payload.port_number & 0xf) << 4 |
+ (req->u.allocate_payload.number_sdp_streams & 0xf);
+ idx++;
+ buf[idx] = (req->u.allocate_payload.vcpi & 0x7f);
+ idx++;
+ buf[idx] = (req->u.allocate_payload.pbn >> 8);
+ idx++;
+ buf[idx] = (req->u.allocate_payload.pbn & 0xff);
+ idx++;
+ for (i = 0; i < req->u.allocate_payload.number_sdp_streams / 2; i++) {
+ buf[idx] = ((req->u.allocate_payload.sdp_stream_sink[i * 2] & 0xf) << 4) |
+ (req->u.allocate_payload.sdp_stream_sink[i * 2 + 1] & 0xf);
+ idx++;
+ }
+ if (req->u.allocate_payload.number_sdp_streams & 1) {
+ i = req->u.allocate_payload.number_sdp_streams - 1;
+ buf[idx] = (req->u.allocate_payload.sdp_stream_sink[i] & 0xf) << 4;
+ idx++;
+ }
+ break;
+ case DP_QUERY_PAYLOAD:
+ buf[idx] = (req->u.query_payload.port_number & 0xf) << 4;
+ idx++;
+ buf[idx] = (req->u.query_payload.vcpi & 0x7f);
+ idx++;
+ break;
+ case DP_REMOTE_DPCD_READ:
+ buf[idx] = (req->u.dpcd_read.port_number & 0xf) << 4;
+ buf[idx] |= ((req->u.dpcd_read.dpcd_address & 0xf0000) >> 16) & 0xf;
+ idx++;
+ buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff00) >> 8;
+ idx++;
+ buf[idx] = (req->u.dpcd_read.dpcd_address & 0xff);
+ idx++;
+ buf[idx] = (req->u.dpcd_read.num_bytes);
+ idx++;
+ break;
+
+ case DP_REMOTE_DPCD_WRITE:
+ buf[idx] = (req->u.dpcd_write.port_number & 0xf) << 4;
+ buf[idx] |= ((req->u.dpcd_write.dpcd_address & 0xf0000) >> 16) & 0xf;
+ idx++;
+ buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff00) >> 8;
+ idx++;
+ buf[idx] = (req->u.dpcd_write.dpcd_address & 0xff);
+ idx++;
+ buf[idx] = (req->u.dpcd_write.num_bytes);
+ idx++;
+ memcpy(&buf[idx], req->u.dpcd_write.bytes, req->u.dpcd_write.num_bytes);
+ idx += req->u.dpcd_write.num_bytes;
+ break;
+ case DP_REMOTE_I2C_READ:
+ buf[idx] = (req->u.i2c_read.port_number & 0xf) << 4;
+ buf[idx] |= (req->u.i2c_read.num_transactions & 0x3);
+ idx++;
+ for (i = 0; i < (req->u.i2c_read.num_transactions & 0x3); i++) {
+ buf[idx] = req->u.i2c_read.transactions[i].i2c_dev_id & 0x7f;
+ idx++;
+ buf[idx] = req->u.i2c_read.transactions[i].num_bytes;
+ idx++;
+ memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes);
+ idx += req->u.i2c_read.transactions[i].num_bytes;
+
+ buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 5;
+ buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf);
+ idx++;
+ }
+ buf[idx] = (req->u.i2c_read.read_i2c_device_id) & 0x7f;
+ idx++;
+ buf[idx] = (req->u.i2c_read.num_bytes_read);
+ idx++;
+ break;
+
+ case DP_REMOTE_I2C_WRITE:
+ buf[idx] = (req->u.i2c_write.port_number & 0xf) << 4;
+ idx++;
+ buf[idx] = (req->u.i2c_write.write_i2c_device_id) & 0x7f;
+ idx++;
+ buf[idx] = (req->u.i2c_write.num_bytes);
+ idx++;
+ memcpy(&buf[idx], req->u.i2c_write.bytes, req->u.i2c_write.num_bytes);
+ idx += req->u.i2c_write.num_bytes;
+ break;
+ }
+ raw->cur_len = idx;
+}
+
+static void drm_dp_crc_sideband_chunk_req(u8 *msg, u8 len)
+{
+ u8 crc4;
+ crc4 = drm_dp_msg_data_crc4(msg, len);
+ msg[len] = crc4;
+}
+
+static void drm_dp_encode_sideband_reply(struct drm_dp_sideband_msg_reply_body *rep,
+ struct drm_dp_sideband_msg_tx *raw)
+{
+ int idx = 0;
+ u8 *buf = raw->msg;
+
+ buf[idx++] = (rep->reply_type & 0x1) << 7 | (rep->req_type & 0x7f);
+
+ raw->cur_len = idx;
+}
+
+/* this adds a chunk of msg to the builder to get the final msg */
+static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
+ u8 *replybuf, u8 replybuflen, bool hdr)
+{
+ int ret;
+ u8 crc4;
+
+ if (hdr) {
+ u8 hdrlen;
+ struct drm_dp_sideband_msg_hdr recv_hdr;
+ ret = drm_dp_decode_sideband_msg_hdr(&recv_hdr, replybuf, replybuflen, &hdrlen);
+ if (ret == false) {
+ print_hex_dump(KERN_DEBUG, "failed hdr", DUMP_PREFIX_NONE, 16, 1, replybuf, replybuflen, false);
+ return false;
+ }
+
+ /* get length contained in this portion */
+ msg->curchunk_len = recv_hdr.msg_len;
+ msg->curchunk_hdrlen = hdrlen;
+
+ /* we have already gotten an somt - don't bother parsing */
+ if (recv_hdr.somt && msg->have_somt)
+ return false;
+
+ if (recv_hdr.somt) {
+ memcpy(&msg->initial_hdr, &recv_hdr, sizeof(struct drm_dp_sideband_msg_hdr));
+ msg->have_somt = true;
+ }
+ if (recv_hdr.eomt)
+ msg->have_eomt = true;
+
+ /* copy the bytes for the remainder of this header chunk */
+ msg->curchunk_idx = min(msg->curchunk_len, (u8)(replybuflen - hdrlen));
+ memcpy(&msg->chunk[0], replybuf + hdrlen, msg->curchunk_idx);
+ } else {
+ memcpy(&msg->chunk[msg->curchunk_idx], replybuf, replybuflen);
+ msg->curchunk_idx += replybuflen;
+ }
+
+ if (msg->curchunk_idx >= msg->curchunk_len) {
+ /* do CRC */
+ crc4 = drm_dp_msg_data_crc4(msg->chunk, msg->curchunk_len - 1);
+ /* copy chunk into bigger msg */
+ memcpy(&msg->msg[msg->curlen], msg->chunk, msg->curchunk_len - 1);
+ msg->curlen += msg->curchunk_len - 1;
+ }
+ return true;
+}
+
+static bool drm_dp_sideband_parse_link_address(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ int i;
+ memcpy(repmsg->u.link_addr.guid, &raw->msg[idx], 16);
+ idx += 16;
+ repmsg->u.link_addr.nports = raw->msg[idx] & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ for (i = 0; i < repmsg->u.link_addr.nports; i++) {
+ if (raw->msg[idx] & 0x80)
+ repmsg->u.link_addr.ports[i].input_port = 1;
+
+ repmsg->u.link_addr.ports[i].peer_device_type = (raw->msg[idx] >> 4) & 0x7;
+ repmsg->u.link_addr.ports[i].port_number = (raw->msg[idx] & 0xf);
+
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.link_addr.ports[i].mcs = (raw->msg[idx] >> 7) & 0x1;
+ repmsg->u.link_addr.ports[i].ddps = (raw->msg[idx] >> 6) & 0x1;
+ if (repmsg->u.link_addr.ports[i].input_port == 0)
+ repmsg->u.link_addr.ports[i].legacy_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ if (repmsg->u.link_addr.ports[i].input_port == 0) {
+ repmsg->u.link_addr.ports[i].dpcd_revision = (raw->msg[idx]);
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ memcpy(repmsg->u.link_addr.ports[i].peer_guid, &raw->msg[idx], 16);
+ idx += 16;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.link_addr.ports[i].num_sdp_streams = (raw->msg[idx] >> 4) & 0xf;
+ repmsg->u.link_addr.ports[i].num_sdp_stream_sinks = (raw->msg[idx] & 0xf);
+ idx++;
+
+ }
+ if (idx > raw->curlen)
+ goto fail_len;
+ }
+
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_remote_dpcd_read(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ repmsg->u.remote_dpcd_read_ack.port_number = raw->msg[idx] & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx];
+ if (idx > raw->curlen)
+ goto fail_len;
+
+ memcpy(repmsg->u.remote_dpcd_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_dpcd_read_ack.num_bytes);
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("link address reply parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_remote_dpcd_write(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ repmsg->u.remote_dpcd_write_ack.port_number = raw->msg[idx] & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_remote_i2c_read_ack(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+
+ repmsg->u.remote_i2c_read_ack.port_number = (raw->msg[idx] & 0xf);
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.remote_i2c_read_ack.num_bytes = raw->msg[idx];
+ idx++;
+ /* TODO check */
+ memcpy(repmsg->u.remote_i2c_read_ack.bytes, &raw->msg[idx], repmsg->u.remote_i2c_read_ack.num_bytes);
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("remote i2c reply parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_enum_path_resources_ack(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ repmsg->u.path_resources.port_number = (raw->msg[idx] >> 4) & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.path_resources.full_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
+ idx += 2;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.path_resources.avail_payload_bw_number = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
+ idx += 2;
+ if (idx > raw->curlen)
+ goto fail_len;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("enum resource parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_allocate_payload_ack(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ repmsg->u.allocate_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.allocate_payload.vcpi = raw->msg[idx];
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.allocate_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx+1]);
+ idx += 2;
+ if (idx > raw->curlen)
+ goto fail_len;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("allocate payload parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_query_payload_ack(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *repmsg)
+{
+ int idx = 1;
+ repmsg->u.query_payload.port_number = (raw->msg[idx] >> 4) & 0xf;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+ repmsg->u.query_payload.allocated_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
+ idx += 2;
+ if (idx > raw->curlen)
+ goto fail_len;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("query payload parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_reply_body *msg)
+{
+ memset(msg, 0, sizeof(*msg));
+ msg->reply_type = (raw->msg[0] & 0x80) >> 7;
+ msg->req_type = (raw->msg[0] & 0x7f);
+
+ if (msg->reply_type) {
+ memcpy(msg->u.nak.guid, &raw->msg[1], 16);
+ msg->u.nak.reason = raw->msg[17];
+ msg->u.nak.nak_data = raw->msg[18];
+ return false;
+ }
+
+ switch (msg->req_type) {
+ case DP_LINK_ADDRESS:
+ return drm_dp_sideband_parse_link_address(raw, msg);
+ case DP_QUERY_PAYLOAD:
+ return drm_dp_sideband_parse_query_payload_ack(raw, msg);
+ case DP_REMOTE_DPCD_READ:
+ return drm_dp_sideband_parse_remote_dpcd_read(raw, msg);
+ case DP_REMOTE_DPCD_WRITE:
+ return drm_dp_sideband_parse_remote_dpcd_write(raw, msg);
+ case DP_REMOTE_I2C_READ:
+ return drm_dp_sideband_parse_remote_i2c_read_ack(raw, msg);
+ case DP_ENUM_PATH_RESOURCES:
+ return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
+ case DP_ALLOCATE_PAYLOAD:
+ return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
+ default:
+ DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type);
+ return false;
+ }
+}
+
+static bool drm_dp_sideband_parse_connection_status_notify(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_req_body *msg)
+{
+ int idx = 1;
+
+ msg->u.conn_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+
+ memcpy(msg->u.conn_stat.guid, &raw->msg[idx], 16);
+ idx += 16;
+ if (idx > raw->curlen)
+ goto fail_len;
+
+ msg->u.conn_stat.legacy_device_plug_status = (raw->msg[idx] >> 6) & 0x1;
+ msg->u.conn_stat.displayport_device_plug_status = (raw->msg[idx] >> 5) & 0x1;
+ msg->u.conn_stat.message_capability_status = (raw->msg[idx] >> 4) & 0x1;
+ msg->u.conn_stat.input_port = (raw->msg[idx] >> 3) & 0x1;
+ msg->u.conn_stat.peer_device_type = (raw->msg[idx] & 0x7);
+ idx++;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("connection status reply parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_resource_status_notify(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_req_body *msg)
+{
+ int idx = 1;
+
+ msg->u.resource_stat.port_number = (raw->msg[idx] & 0xf0) >> 4;
+ idx++;
+ if (idx > raw->curlen)
+ goto fail_len;
+
+ memcpy(msg->u.resource_stat.guid, &raw->msg[idx], 16);
+ idx += 16;
+ if (idx > raw->curlen)
+ goto fail_len;
+
+ msg->u.resource_stat.available_pbn = (raw->msg[idx] << 8) | (raw->msg[idx + 1]);
+ idx++;
+ return true;
+fail_len:
+ DRM_DEBUG_KMS("resource status reply parse length fail %d %d\n", idx, raw->curlen);
+ return false;
+}
+
+static bool drm_dp_sideband_parse_req(struct drm_dp_sideband_msg_rx *raw,
+ struct drm_dp_sideband_msg_req_body *msg)
+{
+ memset(msg, 0, sizeof(*msg));
+ msg->req_type = (raw->msg[0] & 0x7f);
+
+ switch (msg->req_type) {
+ case DP_CONNECTION_STATUS_NOTIFY:
+ return drm_dp_sideband_parse_connection_status_notify(raw, msg);
+ case DP_RESOURCE_STATUS_NOTIFY:
+ return drm_dp_sideband_parse_resource_status_notify(raw, msg);
+ default:
+ DRM_ERROR("Got unknown request 0x%02x\n", msg->req_type);
+ return false;
+ }
+}
+
+static int build_dpcd_write(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes, u8 *bytes)
+{
+ struct drm_dp_sideband_msg_req_body req;
+
+ req.req_type = DP_REMOTE_DPCD_WRITE;
+ req.u.dpcd_write.port_number = port_num;
+ req.u.dpcd_write.dpcd_address = offset;
+ req.u.dpcd_write.num_bytes = num_bytes;
+ req.u.dpcd_write.bytes = bytes;
+ drm_dp_encode_sideband_req(&req, msg);
+
+ return 0;
+}
+
+static int build_link_address(struct drm_dp_sideband_msg_tx *msg)
+{
+ struct drm_dp_sideband_msg_req_body req;
+
+ req.req_type = DP_LINK_ADDRESS;
+ drm_dp_encode_sideband_req(&req, msg);
+ return 0;
+}
+
+static int build_enum_path_resources(struct drm_dp_sideband_msg_tx *msg, int port_num)
+{
+ struct drm_dp_sideband_msg_req_body req;
+
+ req.req_type = DP_ENUM_PATH_RESOURCES;
+ req.u.port_num.port_number = port_num;
+ drm_dp_encode_sideband_req(&req, msg);
+ msg->path_msg = true;
+ return 0;
+}
+
+static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_num,
+ u8 vcpi, uint16_t pbn)
+{
+ struct drm_dp_sideband_msg_req_body req;
+ memset(&req, 0, sizeof(req));
+ req.req_type = DP_ALLOCATE_PAYLOAD;
+ req.u.allocate_payload.port_number = port_num;
+ req.u.allocate_payload.vcpi = vcpi;
+ req.u.allocate_payload.pbn = pbn;
+ drm_dp_encode_sideband_req(&req, msg);
+ msg->path_msg = true;
+ return 0;
+}
+
+static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_vcpi *vcpi)
+{
+ int ret;
+
+ mutex_lock(&mgr->payload_lock);
+ ret = find_first_zero_bit(&mgr->payload_mask, mgr->max_payloads + 1);
+ if (ret > mgr->max_payloads) {
+ ret = -EINVAL;
+ DRM_DEBUG_KMS("out of payload ids %d\n", ret);
+ goto out_unlock;
+ }
+
+ set_bit(ret, &mgr->payload_mask);
+ vcpi->vcpi = ret;
+ mgr->proposed_vcpis[ret - 1] = vcpi;
+out_unlock:
+ mutex_unlock(&mgr->payload_lock);
+ return ret;
+}
+
+static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr,
+ int id)
+{
+ if (id == 0)
+ return;
+
+ mutex_lock(&mgr->payload_lock);
+ DRM_DEBUG_KMS("putting payload %d\n", id);
+ clear_bit(id, &mgr->payload_mask);
+ mgr->proposed_vcpis[id - 1] = NULL;
+ mutex_unlock(&mgr->payload_lock);
+}
+
+static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_sideband_msg_tx *txmsg)
+{
+ bool ret;
+ mutex_lock(&mgr->qlock);
+ ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX ||
+ txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT);
+ mutex_unlock(&mgr->qlock);
+ return ret;
+}
+
+static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_sideband_msg_tx *txmsg)
+{
+ struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
+ int ret;
+
+ ret = wait_event_timeout(mgr->tx_waitq,
+ check_txmsg_state(mgr, txmsg),
+ (4 * HZ));
+ mutex_lock(&mstb->mgr->qlock);
+ if (ret > 0) {
+ if (txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT) {
+ ret = -EIO;
+ goto out;
+ }
+ } else {
+ DRM_DEBUG_KMS("timedout msg send %p %d %d\n", txmsg, txmsg->state, txmsg->seqno);
+
+ /* dump some state */
+ ret = -EIO;
+
+ /* remove from q */
+ if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED ||
+ txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND) {
+ list_del(&txmsg->next);
+ }
+
+ if (txmsg->state == DRM_DP_SIDEBAND_TX_START_SEND ||
+ txmsg->state == DRM_DP_SIDEBAND_TX_SENT) {
+ mstb->tx_slots[txmsg->seqno] = NULL;
+ }
+ }
+out:
+ mutex_unlock(&mgr->qlock);
+
+ return ret;
+}
+
+static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad)
+{
+ struct drm_dp_mst_branch *mstb;
+
+ mstb = kzalloc(sizeof(*mstb), GFP_KERNEL);
+ if (!mstb)
+ return NULL;
+
+ mstb->lct = lct;
+ if (lct > 1)
+ memcpy(mstb->rad, rad, lct / 2);
+ INIT_LIST_HEAD(&mstb->ports);
+ kref_init(&mstb->kref);
+ return mstb;
+}
+
+static void drm_dp_destroy_mst_branch_device(struct kref *kref)
+{
+ struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref);
+ struct drm_dp_mst_port *port, *tmp;
+ bool wake_tx = false;
+
+ cancel_work_sync(&mstb->mgr->work);
+
+ /*
+ * destroy all ports - don't need lock
+ * as there are no more references to the mst branch
+ * device at this point.
+ */
+ list_for_each_entry_safe(port, tmp, &mstb->ports, next) {
+ list_del(&port->next);
+ drm_dp_put_port(port);
+ }
+
+ /* drop any tx slots msg */
+ mutex_lock(&mstb->mgr->qlock);
+ if (mstb->tx_slots[0]) {
+ mstb->tx_slots[0]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
+ mstb->tx_slots[0] = NULL;
+ wake_tx = true;
+ }
+ if (mstb->tx_slots[1]) {
+ mstb->tx_slots[1]->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
+ mstb->tx_slots[1] = NULL;
+ wake_tx = true;
+ }
+ mutex_unlock(&mstb->mgr->qlock);
+
+ if (wake_tx)
+ wake_up(&mstb->mgr->tx_waitq);
+ kfree(mstb);
+}
+
+static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb)
+{
+ kref_put(&mstb->kref, drm_dp_destroy_mst_branch_device);
+}
+
+
+static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
+{
+ switch (old_pdt) {
+ case DP_PEER_DEVICE_DP_LEGACY_CONV:
+ case DP_PEER_DEVICE_SST_SINK:
+ /* remove i2c over sideband */
+ drm_dp_mst_unregister_i2c_bus(&port->aux);
+ break;
+ case DP_PEER_DEVICE_MST_BRANCHING:
+ drm_dp_put_mst_branch_device(port->mstb);
+ port->mstb = NULL;
+ break;
+ }
+}
+
+static void drm_dp_destroy_port(struct kref *kref)
+{
+ struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref);
+ struct drm_dp_mst_topology_mgr *mgr = port->mgr;
+ if (!port->input) {
+ port->vcpi.num_slots = 0;
+ if (port->connector)
+ (*port->mgr->cbs->destroy_connector)(mgr, port->connector);
+ drm_dp_port_teardown_pdt(port, port->pdt);
+
+ if (!port->input && port->vcpi.vcpi > 0)
+ drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+ }
+ kfree(port);
+
+ (*mgr->cbs->hotplug)(mgr);
+}
+
+static void drm_dp_put_port(struct drm_dp_mst_port *port)
+{
+ kref_put(&port->kref, drm_dp_destroy_port);
+}
+
+static struct drm_dp_mst_branch *drm_dp_mst_get_validated_mstb_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_branch *to_find)
+{
+ struct drm_dp_mst_port *port;
+ struct drm_dp_mst_branch *rmstb;
+ if (to_find == mstb) {
+ kref_get(&mstb->kref);
+ return mstb;
+ }
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (port->mstb) {
+ rmstb = drm_dp_mst_get_validated_mstb_ref_locked(port->mstb, to_find);
+ if (rmstb)
+ return rmstb;
+ }
+ }
+ return NULL;
+}
+
+static struct drm_dp_mst_branch *drm_dp_get_validated_mstb_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb)
+{
+ struct drm_dp_mst_branch *rmstb = NULL;
+ mutex_lock(&mgr->lock);
+ if (mgr->mst_primary)
+ rmstb = drm_dp_mst_get_validated_mstb_ref_locked(mgr->mst_primary, mstb);
+ mutex_unlock(&mgr->lock);
+ return rmstb;
+}
+
+static struct drm_dp_mst_port *drm_dp_mst_get_port_ref_locked(struct drm_dp_mst_branch *mstb, struct drm_dp_mst_port *to_find)
+{
+ struct drm_dp_mst_port *port, *mport;
+
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (port == to_find) {
+ kref_get(&port->kref);
+ return port;
+ }
+ if (port->mstb) {
+ mport = drm_dp_mst_get_port_ref_locked(port->mstb, to_find);
+ if (mport)
+ return mport;
+ }
+ }
+ return NULL;
+}
+
+static struct drm_dp_mst_port *drm_dp_get_validated_port_ref(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+{
+ struct drm_dp_mst_port *rport = NULL;
+ mutex_lock(&mgr->lock);
+ if (mgr->mst_primary)
+ rport = drm_dp_mst_get_port_ref_locked(mgr->mst_primary, port);
+ mutex_unlock(&mgr->lock);
+ return rport;
+}
+
+static struct drm_dp_mst_port *drm_dp_get_port(struct drm_dp_mst_branch *mstb, u8 port_num)
+{
+ struct drm_dp_mst_port *port;
+
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (port->port_num == port_num) {
+ kref_get(&port->kref);
+ return port;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * calculate a new RAD for this MST branch device
+ * if parent has an LCT of 2 then it has 1 nibble of RAD,
+ * if parent has an LCT of 3 then it has 2 nibbles of RAD,
+ */
+static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port,
+ u8 *rad)
+{
+ int lct = port->parent->lct;
+ int shift = 4;
+ int idx = lct / 2;
+ if (lct > 1) {
+ memcpy(rad, port->parent->rad, idx);
+ shift = (lct % 2) ? 4 : 0;
+ } else
+ rad[0] = 0;
+
+ rad[idx] |= port->port_num << shift;
+ return lct + 1;
+}
+
+/*
+ * return sends link address for new mstb
+ */
+static bool drm_dp_port_setup_pdt(struct drm_dp_mst_port *port)
+{
+ int ret;
+ u8 rad[6], lct;
+ bool send_link = false;
+ switch (port->pdt) {
+ case DP_PEER_DEVICE_DP_LEGACY_CONV:
+ case DP_PEER_DEVICE_SST_SINK:
+ /* add i2c over sideband */
+ ret = drm_dp_mst_register_i2c_bus(&port->aux);
+ break;
+ case DP_PEER_DEVICE_MST_BRANCHING:
+ lct = drm_dp_calculate_rad(port, rad);
+
+ port->mstb = drm_dp_add_mst_branch_device(lct, rad);
+ port->mstb->mgr = port->mgr;
+ port->mstb->port_parent = port;
+
+ send_link = true;
+ break;
+ }
+ return send_link;
+}
+
+static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_port *port)
+{
+ int ret;
+ if (port->dpcd_rev >= 0x12) {
+ port->guid_valid = drm_dp_validate_guid(mstb->mgr, port->guid);
+ if (!port->guid_valid) {
+ ret = drm_dp_send_dpcd_write(mstb->mgr,
+ port,
+ DP_GUID,
+ 16, port->guid);
+ port->guid_valid = true;
+ }
+ }
+}
+
+static void build_mst_prop_path(struct drm_dp_mst_port *port,
+ struct drm_dp_mst_branch *mstb,
+ char *proppath)
+{
+ int i;
+ char temp[8];
+ snprintf(proppath, 255, "mst:%d", mstb->mgr->conn_base_id);
+ for (i = 0; i < (mstb->lct - 1); i++) {
+ int shift = (i % 2) ? 0 : 4;
+ int port_num = mstb->rad[i / 2] >> shift;
+ snprintf(temp, 8, "-%d", port_num);
+ strncat(proppath, temp, 255);
+ }
+ snprintf(temp, 8, "-%d", port->port_num);
+ strncat(proppath, temp, 255);
+}
+
+static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
+ struct device *dev,
+ struct drm_dp_link_addr_reply_port *port_msg)
+{
+ struct drm_dp_mst_port *port;
+ bool ret;
+ bool created = false;
+ int old_pdt = 0;
+ int old_ddps = 0;
+ port = drm_dp_get_port(mstb, port_msg->port_number);
+ if (!port) {
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return;
+ kref_init(&port->kref);
+ port->parent = mstb;
+ port->port_num = port_msg->port_number;
+ port->mgr = mstb->mgr;
+ port->aux.name = "DPMST";
+ port->aux.dev = dev;
+ created = true;
+ } else {
+ old_pdt = port->pdt;
+ old_ddps = port->ddps;
+ }
+
+ port->pdt = port_msg->peer_device_type;
+ port->input = port_msg->input_port;
+ port->mcs = port_msg->mcs;
+ port->ddps = port_msg->ddps;
+ port->ldps = port_msg->legacy_device_plug_status;
+ port->dpcd_rev = port_msg->dpcd_revision;
+ port->num_sdp_streams = port_msg->num_sdp_streams;
+ port->num_sdp_stream_sinks = port_msg->num_sdp_stream_sinks;
+ memcpy(port->guid, port_msg->peer_guid, 16);
+
+ /* manage mstb port lists with mgr lock - take a reference
+ for this list */
+ if (created) {
+ mutex_lock(&mstb->mgr->lock);
+ kref_get(&port->kref);
+ list_add(&port->next, &mstb->ports);
+ mutex_unlock(&mstb->mgr->lock);
+ }
+
+ if (old_ddps != port->ddps) {
+ if (port->ddps) {
+ drm_dp_check_port_guid(mstb, port);
+ if (!port->input)
+ drm_dp_send_enum_path_resources(mstb->mgr, mstb, port);
+ } else {
+ port->guid_valid = false;
+ port->available_pbn = 0;
+ }
+ }
+
+ if (old_pdt != port->pdt && !port->input) {
+ drm_dp_port_teardown_pdt(port, old_pdt);
+
+ ret = drm_dp_port_setup_pdt(port);
+ if (ret == true) {
+ drm_dp_send_link_address(mstb->mgr, port->mstb);
+ port->mstb->link_address_sent = true;
+ }
+ }
+
+ if (created && !port->input) {
+ char proppath[255];
+ build_mst_prop_path(port, mstb, proppath);
+ port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);
+ }
+
+ /* put reference to this port */
+ drm_dp_put_port(port);
+}
+
+static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
+ struct drm_dp_connection_status_notify *conn_stat)
+{
+ struct drm_dp_mst_port *port;
+ int old_pdt;
+ int old_ddps;
+ bool dowork = false;
+ port = drm_dp_get_port(mstb, conn_stat->port_number);
+ if (!port)
+ return;
+
+ old_ddps = port->ddps;
+ old_pdt = port->pdt;
+ port->pdt = conn_stat->peer_device_type;
+ port->mcs = conn_stat->message_capability_status;
+ port->ldps = conn_stat->legacy_device_plug_status;
+ port->ddps = conn_stat->displayport_device_plug_status;
+
+ if (old_ddps != port->ddps) {
+ if (port->ddps) {
+ drm_dp_check_port_guid(mstb, port);
+ dowork = true;
+ } else {
+ port->guid_valid = false;
+ port->available_pbn = 0;
+ }
+ }
+ if (old_pdt != port->pdt && !port->input) {
+ drm_dp_port_teardown_pdt(port, old_pdt);
+
+ if (drm_dp_port_setup_pdt(port))
+ dowork = true;
+ }
+
+ drm_dp_put_port(port);
+ if (dowork)
+ queue_work(system_long_wq, &mstb->mgr->work);
+
+}
+
+static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_topology_mgr *mgr,
+ u8 lct, u8 *rad)
+{
+ struct drm_dp_mst_branch *mstb;
+ struct drm_dp_mst_port *port;
+ int i;
+ /* find the port by iterating down */
+ mstb = mgr->mst_primary;
+
+ for (i = 0; i < lct - 1; i++) {
+ int shift = (i % 2) ? 0 : 4;
+ int port_num = rad[i / 2] >> shift;
+
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (port->port_num == port_num) {
+ if (!port->mstb) {
+ DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]);
+ return NULL;
+ }
+
+ mstb = port->mstb;
+ break;
+ }
+ }
+ }
+ kref_get(&mstb->kref);
+ return mstb;
+}
+
+static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb)
+{
+ struct drm_dp_mst_port *port;
+
+ if (!mstb->link_address_sent) {
+ drm_dp_send_link_address(mgr, mstb);
+ mstb->link_address_sent = true;
+ }
+ list_for_each_entry(port, &mstb->ports, next) {
+ if (port->input)
+ continue;
+
+ if (!port->ddps)
+ continue;
+
+ if (!port->available_pbn)
+ drm_dp_send_enum_path_resources(mgr, mstb, port);
+
+ if (port->mstb)
+ drm_dp_check_and_send_link_address(mgr, port->mstb);
+ }
+}
+
+static void drm_dp_mst_link_probe_work(struct work_struct *work)
+{
+ struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work);
+
+ drm_dp_check_and_send_link_address(mgr, mgr->mst_primary);
+
+}
+
+static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
+ u8 *guid)
+{
+ static u8 zero_guid[16];
+
+ 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 0
+static int build_dpcd_read(struct drm_dp_sideband_msg_tx *msg, u8 port_num, u32 offset, u8 num_bytes)
+{
+ struct drm_dp_sideband_msg_req_body req;
+
+ req.req_type = DP_REMOTE_DPCD_READ;
+ req.u.dpcd_read.port_number = port_num;
+ req.u.dpcd_read.dpcd_address = offset;
+ req.u.dpcd_read.num_bytes = num_bytes;
+ drm_dp_encode_sideband_req(&req, msg);
+
+ return 0;
+}
+#endif
+
+static int drm_dp_send_sideband_msg(struct drm_dp_mst_topology_mgr *mgr,
+ bool up, u8 *msg, int len)
+{
+ int ret;
+ int regbase = up ? DP_SIDEBAND_MSG_UP_REP_BASE : DP_SIDEBAND_MSG_DOWN_REQ_BASE;
+ int tosend, total, offset;
+ int retries = 0;
+
+retry:
+ total = len;
+ offset = 0;
+ do {
+ tosend = min3(mgr->max_dpcd_transaction_bytes, 16, total);
+
+ ret = drm_dp_dpcd_write(mgr->aux, regbase + offset,
+ &msg[offset],
+ tosend);
+ if (ret != tosend) {
+ if (ret == -EIO && retries < 5) {
+ retries++;
+ goto retry;
+ }
+ DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret);
+ WARN(1, "fail\n");
+
+ return -EIO;
+ }
+ offset += tosend;
+ total -= tosend;
+ } while (total > 0);
+ return 0;
+}
+
+static int set_hdr_from_dst_qlock(struct drm_dp_sideband_msg_hdr *hdr,
+ struct drm_dp_sideband_msg_tx *txmsg)
+{
+ struct drm_dp_mst_branch *mstb = txmsg->dst;
+
+ /* both msg slots are full */
+ if (txmsg->seqno == -1) {
+ if (mstb->tx_slots[0] && mstb->tx_slots[1]) {
+ DRM_DEBUG_KMS("%s: failed to find slot\n", __func__);
+ return -EAGAIN;
+ }
+ if (mstb->tx_slots[0] == NULL && mstb->tx_slots[1] == NULL) {
+ txmsg->seqno = mstb->last_seqno;
+ mstb->last_seqno ^= 1;
+ } else if (mstb->tx_slots[0] == NULL)
+ txmsg->seqno = 0;
+ else
+ txmsg->seqno = 1;
+ mstb->tx_slots[txmsg->seqno] = txmsg;
+ }
+ hdr->broadcast = 0;
+ hdr->path_msg = txmsg->path_msg;
+ hdr->lct = mstb->lct;
+ hdr->lcr = mstb->lct - 1;
+ if (mstb->lct > 1)
+ memcpy(hdr->rad, mstb->rad, mstb->lct / 2);
+ hdr->seqno = txmsg->seqno;
+ return 0;
+}
+/*
+ * process a single block of the next message in the sideband queue
+ */
+static int process_single_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_sideband_msg_tx *txmsg,
+ bool up)
+{
+ u8 chunk[48];
+ struct drm_dp_sideband_msg_hdr hdr;
+ int len, space, idx, tosend;
+ int ret;
+
+ memset(&hdr, 0, sizeof(struct drm_dp_sideband_msg_hdr));
+
+ if (txmsg->state == DRM_DP_SIDEBAND_TX_QUEUED) {
+ txmsg->seqno = -1;
+ txmsg->state = DRM_DP_SIDEBAND_TX_START_SEND;
+ }
+
+ /* make hdr from dst mst - for replies use seqno
+ otherwise assign one */
+ ret = set_hdr_from_dst_qlock(&hdr, txmsg);
+ if (ret < 0)
+ return ret;
+
+ /* amount left to send in this message */
+ len = txmsg->cur_len - txmsg->cur_offset;
+
+ /* 48 - sideband msg size - 1 byte for data CRC, x header bytes */
+ space = 48 - 1 - drm_dp_calc_sb_hdr_size(&hdr);
+
+ tosend = min(len, space);
+ if (len == txmsg->cur_len)
+ hdr.somt = 1;
+ if (space >= len)
+ hdr.eomt = 1;
+
+
+ hdr.msg_len = tosend + 1;
+ drm_dp_encode_sideband_msg_hdr(&hdr, chunk, &idx);
+ memcpy(&chunk[idx], &txmsg->msg[txmsg->cur_offset], tosend);
+ /* add crc at end */
+ drm_dp_crc_sideband_chunk_req(&chunk[idx], tosend);
+ idx += tosend + 1;
+
+ ret = drm_dp_send_sideband_msg(mgr, up, chunk, idx);
+ if (ret) {
+ DRM_DEBUG_KMS("sideband msg failed to send\n");
+ return ret;
+ }
+
+ txmsg->cur_offset += tosend;
+ if (txmsg->cur_offset == txmsg->cur_len) {
+ txmsg->state = DRM_DP_SIDEBAND_TX_SENT;
+ return 1;
+ }
+ return 0;
+}
+
+/* must be called holding qlock */
+static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
+{
+ struct drm_dp_sideband_msg_tx *txmsg;
+ int ret;
+
+ /* construct a chunk from the first msg in the tx_msg queue */
+ if (list_empty(&mgr->tx_msg_downq)) {
+ mgr->tx_down_in_progress = false;
+ return;
+ }
+ mgr->tx_down_in_progress = true;
+
+ txmsg = list_first_entry(&mgr->tx_msg_downq, struct drm_dp_sideband_msg_tx, next);
+ ret = process_single_tx_qlock(mgr, txmsg, false);
+ if (ret == 1) {
+ /* txmsg is sent it should be in the slots now */
+ list_del(&txmsg->next);
+ } else if (ret) {
+ DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
+ list_del(&txmsg->next);
+ if (txmsg->seqno != -1)
+ txmsg->dst->tx_slots[txmsg->seqno] = NULL;
+ txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
+ wake_up(&mgr->tx_waitq);
+ }
+ if (list_empty(&mgr->tx_msg_downq)) {
+ mgr->tx_down_in_progress = false;
+ return;
+ }
+}
+
+/* called holding qlock */
+static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
+{
+ struct drm_dp_sideband_msg_tx *txmsg;
+ int ret;
+
+ /* construct a chunk from the first msg in the tx_msg queue */
+ if (list_empty(&mgr->tx_msg_upq)) {
+ mgr->tx_up_in_progress = false;
+ return;
+ }
+
+ txmsg = list_first_entry(&mgr->tx_msg_upq, struct drm_dp_sideband_msg_tx, next);
+ ret = process_single_tx_qlock(mgr, txmsg, true);
+ if (ret == 1) {
+ /* up txmsgs aren't put in slots - so free after we send it */
+ list_del(&txmsg->next);
+ kfree(txmsg);
+ } else if (ret)
+ DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
+ mgr->tx_up_in_progress = true;
+}
+
+static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_sideband_msg_tx *txmsg)
+{
+ mutex_lock(&mgr->qlock);
+ list_add_tail(&txmsg->next, &mgr->tx_msg_downq);
+ if (!mgr->tx_down_in_progress)
+ process_single_down_tx_qlock(mgr);
+ mutex_unlock(&mgr->qlock);
+}
+
+static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb)
+{
+ int len;
+ struct drm_dp_sideband_msg_tx *txmsg;
+ int ret;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg)
+ return -ENOMEM;
+
+ txmsg->dst = mstb;
+ len = build_link_address(txmsg);
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
+ if (ret > 0) {
+ int i;
+
+ if (txmsg->reply.reply_type == 1)
+ DRM_DEBUG_KMS("link address nak received\n");
+ else {
+ DRM_DEBUG_KMS("link address reply: %d\n", txmsg->reply.u.link_addr.nports);
+ for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
+ DRM_DEBUG_KMS("port %d: input %d, pdt: %d, pn: %d, dpcd_rev: %02x, mcs: %d, ddps: %d, ldps %d, sdp %d/%d\n", i,
+ txmsg->reply.u.link_addr.ports[i].input_port,
+ txmsg->reply.u.link_addr.ports[i].peer_device_type,
+ txmsg->reply.u.link_addr.ports[i].port_number,
+ txmsg->reply.u.link_addr.ports[i].dpcd_revision,
+ txmsg->reply.u.link_addr.ports[i].mcs,
+ txmsg->reply.u.link_addr.ports[i].ddps,
+ txmsg->reply.u.link_addr.ports[i].legacy_device_plug_status,
+ txmsg->reply.u.link_addr.ports[i].num_sdp_streams,
+ txmsg->reply.u.link_addr.ports[i].num_sdp_stream_sinks);
+ }
+ for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) {
+ drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]);
+ }
+ (*mgr->cbs->hotplug)(mgr);
+ }
+ } else
+ DRM_DEBUG_KMS("link address failed %d\n", ret);
+
+ kfree(txmsg);
+ return 0;
+}
+
+static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb,
+ struct drm_dp_mst_port *port)
+{
+ int len;
+ struct drm_dp_sideband_msg_tx *txmsg;
+ int ret;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg)
+ return -ENOMEM;
+
+ txmsg->dst = mstb;
+ len = build_enum_path_resources(txmsg, port->port_num);
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
+ if (ret > 0) {
+ if (txmsg->reply.reply_type == 1)
+ DRM_DEBUG_KMS("enum path resources nak received\n");
+ else {
+ if (port->port_num != txmsg->reply.u.path_resources.port_number)
+ DRM_ERROR("got incorrect port in response\n");
+ DRM_DEBUG_KMS("enum path resources %d: %d %d\n", txmsg->reply.u.path_resources.port_number, txmsg->reply.u.path_resources.full_payload_bw_number,
+ txmsg->reply.u.path_resources.avail_payload_bw_number);
+ port->available_pbn = txmsg->reply.u.path_resources.avail_payload_bw_number;
+ }
+ }
+
+ kfree(txmsg);
+ return 0;
+}
+
+static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int id,
+ int pbn)
+{
+ struct drm_dp_sideband_msg_tx *txmsg;
+ struct drm_dp_mst_branch *mstb;
+ int len, ret;
+
+ mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
+ if (!mstb)
+ return -EINVAL;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg) {
+ ret = -ENOMEM;
+ goto fail_put;
+ }
+
+ txmsg->dst = mstb;
+ len = build_allocate_payload(txmsg, port->port_num,
+ id,
+ pbn);
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
+ if (ret > 0) {
+ if (txmsg->reply.reply_type == 1) {
+ ret = -EINVAL;
+ } else
+ ret = 0;
+ }
+ kfree(txmsg);
+fail_put:
+ drm_dp_put_mst_branch_device(mstb);
+ return ret;
+}
+
+static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
+ int id,
+ struct drm_dp_payload *payload)
+{
+ int ret;
+
+ ret = drm_dp_dpcd_write_payload(mgr, id, payload);
+ if (ret < 0) {
+ payload->payload_state = 0;
+ return ret;
+ }
+ payload->payload_state = DP_PAYLOAD_LOCAL;
+ return 0;
+}
+
+static int drm_dp_create_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int id,
+ struct drm_dp_payload *payload)
+{
+ int ret;
+ ret = drm_dp_payload_send_msg(mgr, port, id, port->vcpi.pbn);
+ if (ret < 0)
+ return ret;
+ payload->payload_state = DP_PAYLOAD_REMOTE;
+ return ret;
+}
+
+static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int id,
+ struct drm_dp_payload *payload)
+{
+ DRM_DEBUG_KMS("\n");
+ /* its okay for these to fail */
+ if (port) {
+ drm_dp_payload_send_msg(mgr, port, id, 0);
+ }
+
+ drm_dp_dpcd_write_payload(mgr, id, payload);
+ payload->payload_state = 0;
+ return 0;
+}
+
+static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr,
+ int id,
+ struct drm_dp_payload *payload)
+{
+ payload->payload_state = 0;
+ return 0;
+}
+
+/**
+ * drm_dp_update_payload_part1() - Execute payload update part 1
+ * @mgr: manager to use.
+ *
+ * This iterates over all proposed virtual channels, and tries to
+ * allocate space in the link for them. For 0->slots transitions,
+ * this step just writes the VCPI to the MST device. For slots->0
+ * transitions, this writes the updated VCPIs and removes the
+ * remote VC payloads.
+ *
+ * after calling this the driver should generate ACT and payload
+ * packets.
+ */
+int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
+{
+ int i;
+ int cur_slots = 1;
+ struct drm_dp_payload req_payload;
+ struct drm_dp_mst_port *port;
+
+ mutex_lock(&mgr->payload_lock);
+ for (i = 0; i < mgr->max_payloads; i++) {
+ /* solve the current payloads - compare to the hw ones
+ - update the hw view */
+ req_payload.start_slot = cur_slots;
+ if (mgr->proposed_vcpis[i]) {
+ port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+ req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots;
+ } else {
+ port = NULL;
+ req_payload.num_slots = 0;
+ }
+ /* work out what is required to happen with this payload */
+ if (mgr->payloads[i].start_slot != req_payload.start_slot ||
+ mgr->payloads[i].num_slots != req_payload.num_slots) {
+
+ /* need to push an update for this payload */
+ if (req_payload.num_slots) {
+ drm_dp_create_payload_step1(mgr, i + 1, &req_payload);
+ mgr->payloads[i].num_slots = req_payload.num_slots;
+ } else if (mgr->payloads[i].num_slots) {
+ mgr->payloads[i].num_slots = 0;
+ drm_dp_destroy_payload_step1(mgr, port, i + 1, &mgr->payloads[i]);
+ req_payload.payload_state = mgr->payloads[i].payload_state;
+ } else
+ req_payload.payload_state = 0;
+
+ mgr->payloads[i].start_slot = req_payload.start_slot;
+ mgr->payloads[i].payload_state = req_payload.payload_state;
+ }
+ cur_slots += req_payload.num_slots;
+ }
+ mutex_unlock(&mgr->payload_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_update_payload_part1);
+
+/**
+ * drm_dp_update_payload_part2() - Execute payload update part 2
+ * @mgr: manager to use.
+ *
+ * This iterates over all proposed virtual channels, and tries to
+ * allocate space in the link for them. For 0->slots transitions,
+ * this step writes the remote VC payload commands. For slots->0
+ * this just resets some internal state.
+ */
+int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
+{
+ struct drm_dp_mst_port *port;
+ int i;
+ int ret = 0;
+ mutex_lock(&mgr->payload_lock);
+ for (i = 0; i < mgr->max_payloads; i++) {
+
+ if (!mgr->proposed_vcpis[i])
+ continue;
+
+ port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+
+ DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state);
+ if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) {
+ ret = drm_dp_create_payload_step2(mgr, port, i + 1, &mgr->payloads[i]);
+ } else if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) {
+ ret = drm_dp_destroy_payload_step2(mgr, i + 1, &mgr->payloads[i]);
+ }
+ if (ret) {
+ mutex_unlock(&mgr->payload_lock);
+ return ret;
+ }
+ }
+ mutex_unlock(&mgr->payload_lock);
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_update_payload_part2);
+
+#if 0 /* unused as of yet */
+static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int offset, int size)
+{
+ int len;
+ struct drm_dp_sideband_msg_tx *txmsg;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg)
+ return -ENOMEM;
+
+ len = build_dpcd_read(txmsg, port->port_num, 0, 8);
+ txmsg->dst = port->parent;
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ return 0;
+}
+#endif
+
+static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port,
+ int offset, int size, u8 *bytes)
+{
+ int len;
+ int ret;
+ struct drm_dp_sideband_msg_tx *txmsg;
+ struct drm_dp_mst_branch *mstb;
+
+ mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
+ if (!mstb)
+ return -EINVAL;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg) {
+ ret = -ENOMEM;
+ goto fail_put;
+ }
+
+ len = build_dpcd_write(txmsg, port->port_num, offset, size, bytes);
+ txmsg->dst = mstb;
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
+ if (ret > 0) {
+ if (txmsg->reply.reply_type == 1) {
+ ret = -EINVAL;
+ } else
+ ret = 0;
+ }
+ kfree(txmsg);
+fail_put:
+ drm_dp_put_mst_branch_device(mstb);
+ return ret;
+}
+
+static int drm_dp_encode_up_ack_reply(struct drm_dp_sideband_msg_tx *msg, u8 req_type)
+{
+ struct drm_dp_sideband_msg_reply_body reply;
+
+ reply.reply_type = 1;
+ reply.req_type = req_type;
+ drm_dp_encode_sideband_reply(&reply, msg);
+ return 0;
+}
+
+static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb,
+ int req_type, int seqno, bool broadcast)
+{
+ struct drm_dp_sideband_msg_tx *txmsg;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg)
+ return -ENOMEM;
+
+ txmsg->dst = mstb;
+ txmsg->seqno = seqno;
+ drm_dp_encode_up_ack_reply(txmsg, req_type);
+
+ mutex_lock(&mgr->qlock);
+ list_add_tail(&txmsg->next, &mgr->tx_msg_upq);
+ if (!mgr->tx_up_in_progress) {
+ process_single_up_tx_qlock(mgr);
+ }
+ mutex_unlock(&mgr->qlock);
+ return 0;
+}
+
+static int drm_dp_get_vc_payload_bw(int dp_link_bw, int dp_link_count)
+{
+ switch (dp_link_bw) {
+ case DP_LINK_BW_1_62:
+ return 3 * dp_link_count;
+ case DP_LINK_BW_2_7:
+ return 5 * dp_link_count;
+ case DP_LINK_BW_5_4:
+ return 10 * dp_link_count;
+ }
+ return 0;
+}
+
+/**
+ * drm_dp_mst_topology_mgr_set_mst() - Set the MST state for a topology manager
+ * @mgr: manager to set state for
+ * @mst_state: true to enable MST on this connector - false to disable.
+ *
+ * This is called by the driver when it detects an MST capable device plugged
+ * into a DP MST capable port, or when a DP MST capable device is unplugged.
+ */
+int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)
+{
+ int ret = 0;
+ struct drm_dp_mst_branch *mstb = NULL;
+
+ mutex_lock(&mgr->lock);
+ if (mst_state == mgr->mst_state)
+ goto out_unlock;
+
+ mgr->mst_state = mst_state;
+ /* set the device into MST mode */
+ if (mst_state) {
+ WARN_ON(mgr->mst_primary);
+
+ /* get dpcd info */
+ ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
+ if (ret != DP_RECEIVER_CAP_SIZE) {
+ DRM_DEBUG_KMS("failed to read DPCD\n");
+ goto out_unlock;
+ }
+
+ mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1], mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
+ mgr->total_pbn = 2560;
+ mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
+ mgr->avail_slots = mgr->total_slots;
+
+ /* add initial branch device at LCT 1 */
+ mstb = drm_dp_add_mst_branch_device(1, NULL);
+ if (mstb == NULL) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+ mstb->mgr = mgr;
+
+ /* give this the main reference */
+ mgr->mst_primary = mstb;
+ kref_get(&mgr->mst_primary->kref);
+
+ {
+ struct drm_dp_payload reset_pay;
+ reset_pay.start_slot = 0;
+ reset_pay.num_slots = 0x3f;
+ drm_dp_dpcd_write_payload(mgr, 0, &reset_pay);
+ }
+
+ ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
+ DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
+ if (ret < 0) {
+ goto out_unlock;
+ }
+
+
+ /* sort out guid */
+ ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, mgr->guid, 16);
+ if (ret != 16) {
+ DRM_DEBUG_KMS("failed to read DP GUID %d\n", ret);
+ goto out_unlock;
+ }
+
+ mgr->guid_valid = drm_dp_validate_guid(mgr, mgr->guid);
+ if (!mgr->guid_valid) {
+ ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, mgr->guid, 16);
+ mgr->guid_valid = true;
+ }
+
+ queue_work(system_long_wq, &mgr->work);
+
+ ret = 0;
+ } else {
+ /* disable MST on the device */
+ mstb = mgr->mst_primary;
+ mgr->mst_primary = NULL;
+ /* this can fail if the device is gone */
+ drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
+ ret = 0;
+ memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload));
+ mgr->payload_mask = 0;
+ set_bit(0, &mgr->payload_mask);
+ }
+
+out_unlock:
+ mutex_unlock(&mgr->lock);
+ if (mstb)
+ drm_dp_put_mst_branch_device(mstb);
+ return ret;
+
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_mgr_set_mst);
+
+/**
+ * drm_dp_mst_topology_mgr_suspend() - suspend the MST manager
+ * @mgr: manager to suspend
+ *
+ * This function tells the MST device that we can't handle UP messages
+ * anymore. This should stop it from sending any since we are suspended.
+ */
+void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)
+{
+ mutex_lock(&mgr->lock);
+ drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
+ DP_MST_EN | DP_UPSTREAM_IS_SRC);
+ mutex_unlock(&mgr->lock);
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend);
+
+/**
+ * drm_dp_mst_topology_mgr_resume() - resume the MST manager
+ * @mgr: manager to resume
+ *
+ * This will fetch DPCD and see if the device is still there,
+ * if it is, it will rewrite the MSTM control bits, and return.
+ *
+ * if the device fails this returns -1, and the driver should do
+ * a full MST reprobe, in case we were undocked.
+ */
+int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr)
+{
+ int ret = 0;
+
+ mutex_lock(&mgr->lock);
+
+ if (mgr->mst_primary) {
+ int sret;
+ sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE);
+ if (sret != DP_RECEIVER_CAP_SIZE) {
+ DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n");
+ ret = -1;
+ goto out_unlock;
+ }
+
+ ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
+ DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("mst write failed - undocked during suspend?\n");
+ ret = -1;
+ goto out_unlock;
+ }
+ ret = 0;
+ } else
+ ret = -1;
+
+out_unlock:
+ mutex_unlock(&mgr->lock);
+ return ret;
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
+
+static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
+{
+ int len;
+ u8 replyblock[32];
+ int replylen, origlen, curreply;
+ int ret;
+ struct drm_dp_sideband_msg_rx *msg;
+ int basereg = up ? DP_SIDEBAND_MSG_UP_REQ_BASE : DP_SIDEBAND_MSG_DOWN_REP_BASE;
+ msg = up ? &mgr->up_req_recv : &mgr->down_rep_recv;
+
+ len = min(mgr->max_dpcd_transaction_bytes, 16);
+ ret = drm_dp_dpcd_read(mgr->aux, basereg,
+ replyblock, len);
+ if (ret != len) {
+ DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
+ return;
+ }
+ ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
+ if (!ret) {
+ DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
+ return;
+ }
+ replylen = msg->curchunk_len + msg->curchunk_hdrlen;
+
+ origlen = replylen;
+ replylen -= len;
+ curreply = len;
+ while (replylen > 0) {
+ len = min3(replylen, mgr->max_dpcd_transaction_bytes, 16);
+ ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
+ replyblock, len);
+ if (ret != len) {
+ DRM_DEBUG_KMS("failed to read a chunk\n");
+ }
+ ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
+ if (ret == false)
+ DRM_DEBUG_KMS("failed to build sideband msg\n");
+ curreply += len;
+ replylen -= len;
+ }
+}
+
+static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
+{
+ int ret = 0;
+
+ drm_dp_get_one_sb_msg(mgr, false);
+
+ if (mgr->down_rep_recv.have_eomt) {
+ struct drm_dp_sideband_msg_tx *txmsg;
+ struct drm_dp_mst_branch *mstb;
+ int slot = -1;
+ mstb = drm_dp_get_mst_branch_device(mgr,
+ mgr->down_rep_recv.initial_hdr.lct,
+ mgr->down_rep_recv.initial_hdr.rad);
+
+ if (!mstb) {
+ DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->down_rep_recv.initial_hdr.lct);
+ memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
+
+ /* find the message */
+ slot = mgr->down_rep_recv.initial_hdr.seqno;
+ mutex_lock(&mgr->qlock);
+ txmsg = mstb->tx_slots[slot];
+ /* remove from slots */
+ mutex_unlock(&mgr->qlock);
+
+ if (!txmsg) {
+ DRM_DEBUG_KMS("Got MST reply with no msg %p %d %d %02x %02x\n",
+ mstb,
+ mgr->down_rep_recv.initial_hdr.seqno,
+ mgr->down_rep_recv.initial_hdr.lct,
+ mgr->down_rep_recv.initial_hdr.rad[0],
+ mgr->down_rep_recv.msg[0]);
+ drm_dp_put_mst_branch_device(mstb);
+ memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
+
+ drm_dp_sideband_parse_reply(&mgr->down_rep_recv, &txmsg->reply);
+ if (txmsg->reply.reply_type == 1) {
+ DRM_DEBUG_KMS("Got NAK reply: req 0x%02x, reason 0x%02x, nak data 0x%02x\n", txmsg->reply.req_type, txmsg->reply.u.nak.reason, txmsg->reply.u.nak.nak_data);
+ }
+
+ memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ drm_dp_put_mst_branch_device(mstb);
+
+ mutex_lock(&mgr->qlock);
+ txmsg->state = DRM_DP_SIDEBAND_TX_RX;
+ mstb->tx_slots[slot] = NULL;
+ mutex_unlock(&mgr->qlock);
+
+ wake_up(&mgr->tx_waitq);
+ }
+ return ret;
+}
+
+static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
+{
+ int ret = 0;
+ drm_dp_get_one_sb_msg(mgr, true);
+
+ if (mgr->up_req_recv.have_eomt) {
+ struct drm_dp_sideband_msg_req_body msg;
+ struct drm_dp_mst_branch *mstb;
+ bool seqno;
+ mstb = drm_dp_get_mst_branch_device(mgr,
+ mgr->up_req_recv.initial_hdr.lct,
+ mgr->up_req_recv.initial_hdr.rad);
+ if (!mstb) {
+ DRM_DEBUG_KMS("Got MST reply from unknown device %d\n", mgr->up_req_recv.initial_hdr.lct);
+ memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
+
+ seqno = mgr->up_req_recv.initial_hdr.seqno;
+ drm_dp_sideband_parse_req(&mgr->up_req_recv, &msg);
+
+ if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
+ drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+ drm_dp_update_port(mstb, &msg.u.conn_stat);
+ DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type);
+ (*mgr->cbs->hotplug)(mgr);
+
+ } else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
+ drm_dp_send_up_ack_reply(mgr, mstb, msg.req_type, seqno, false);
+ DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
+ }
+
+ drm_dp_put_mst_branch_device(mstb);
+ memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
+ }
+ return ret;
+}
+
+/**
+ * drm_dp_mst_hpd_irq() - MST hotplug IRQ notify
+ * @mgr: manager to notify irq for.
+ * @esi: 4 bytes from SINK_COUNT_ESI
+ *
+ * This should be called from the driver when it detects a short IRQ,
+ * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The
+ * topology manager will process the sideband messages received as a result
+ * of this.
+ */
+int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handled)
+{
+ int ret = 0;
+ int sc;
+ *handled = false;
+ sc = esi[0] & 0x3f;
+
+ if (sc != mgr->sink_count) {
+ mgr->sink_count = sc;
+ *handled = true;
+ }
+
+ if (esi[1] & DP_DOWN_REP_MSG_RDY) {
+ ret = drm_dp_mst_handle_down_rep(mgr);
+ *handled = true;
+ }
+
+ if (esi[1] & DP_UP_REQ_MSG_RDY) {
+ ret |= drm_dp_mst_handle_up_req(mgr);
+ *handled = true;
+ }
+
+ drm_dp_mst_kick_tx(mgr);
+ return ret;
+}
+EXPORT_SYMBOL(drm_dp_mst_hpd_irq);
+
+/**
+ * drm_dp_mst_detect_port() - get connection status for an MST port
+ * @mgr: manager for this port
+ * @port: unverified pointer to a port
+ *
+ * This returns the current connection state for a port. It validates the
+ * port pointer still exists so the caller doesn't require a reference
+ */
+enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+{
+ enum drm_connector_status status = connector_status_disconnected;
+
+ /* we need to search for the port in the mgr in case its gone */
+ port = drm_dp_get_validated_port_ref(mgr, port);
+ if (!port)
+ return connector_status_disconnected;
+
+ if (!port->ddps)
+ goto out;
+
+ switch (port->pdt) {
+ case DP_PEER_DEVICE_NONE:
+ case DP_PEER_DEVICE_MST_BRANCHING:
+ break;
+
+ case DP_PEER_DEVICE_SST_SINK:
+ status = connector_status_connected;
+ break;
+ case DP_PEER_DEVICE_DP_LEGACY_CONV:
+ if (port->ldps)
+ status = connector_status_connected;
+ break;
+ }
+out:
+ drm_dp_put_port(port);
+ return status;
+}
+EXPORT_SYMBOL(drm_dp_mst_detect_port);
+
+/**
+ * drm_dp_mst_get_edid() - get EDID for an MST port
+ * @connector: toplevel connector to get EDID for
+ * @mgr: manager for this port
+ * @port: unverified pointer to a port.
+ *
+ * This returns an EDID for the port connected to a connector,
+ * It validates the pointer still exists so the caller doesn't require a
+ * reference.
+ */
+struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+{
+ struct edid *edid = NULL;
+
+ /* we need to search for the port in the mgr in case its gone */
+ port = drm_dp_get_validated_port_ref(mgr, port);
+ if (!port)
+ return NULL;
+
+ edid = drm_get_edid(connector, &port->aux.ddc);
+ drm_dp_put_port(port);
+ return edid;
+}
+EXPORT_SYMBOL(drm_dp_mst_get_edid);
+
+/**
+ * drm_dp_find_vcpi_slots() - find slots for this PBN value
+ * @mgr: manager to use
+ * @pbn: payload bandwidth to convert into slots.
+ */
+int drm_dp_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr,
+ int pbn)
+{
+ int num_slots;
+
+ num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
+
+ if (num_slots > mgr->avail_slots)
+ return -ENOSPC;
+ return num_slots;
+}
+EXPORT_SYMBOL(drm_dp_find_vcpi_slots);
+
+static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_vcpi *vcpi, int pbn)
+{
+ int num_slots;
+ int ret;
+
+ num_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
+
+ if (num_slots > mgr->avail_slots)
+ return -ENOSPC;
+
+ vcpi->pbn = pbn;
+ vcpi->aligned_pbn = num_slots * mgr->pbn_div;
+ vcpi->num_slots = num_slots;
+
+ ret = drm_dp_mst_assign_payload_id(mgr, vcpi);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+/**
+ * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
+ * @mgr: manager for this port
+ * @port: port to allocate a virtual channel for.
+ * @pbn: payload bandwidth number to request
+ * @slots: returned number of slots for this PBN.
+ */
+bool drm_dp_mst_allocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, int pbn, int *slots)
+{
+ int ret;
+
+ port = drm_dp_get_validated_port_ref(mgr, port);
+ if (!port)
+ return false;
+
+ if (port->vcpi.vcpi > 0) {
+ DRM_DEBUG_KMS("payload: vcpi %d already allocated for pbn %d - requested pbn %d\n", port->vcpi.vcpi, port->vcpi.pbn, pbn);
+ if (pbn == port->vcpi.pbn) {
+ *slots = port->vcpi.num_slots;
+ return true;
+ }
+ }
+
+ ret = drm_dp_init_vcpi(mgr, &port->vcpi, pbn);
+ if (ret) {
+ DRM_DEBUG_KMS("failed to init vcpi %d %d %d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), mgr->avail_slots, ret);
+ goto out;
+ }
+ DRM_DEBUG_KMS("initing vcpi for %d %d\n", pbn, port->vcpi.num_slots);
+ *slots = port->vcpi.num_slots;
+
+ drm_dp_put_port(port);
+ return true;
+out:
+ return false;
+}
+EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi);
+
+/**
+ * drm_dp_mst_reset_vcpi_slots() - Reset number of slots to 0 for VCPI
+ * @mgr: manager for this port
+ * @port: unverified pointer to a port.
+ *
+ * This just resets the number of slots for the ports VCPI for later programming.
+ */
+void drm_dp_mst_reset_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+{
+ port = drm_dp_get_validated_port_ref(mgr, port);
+ if (!port)
+ return;
+ port->vcpi.num_slots = 0;
+ drm_dp_put_port(port);
+}
+EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
+
+/**
+ * drm_dp_mst_deallocate_vcpi() - deallocate a VCPI
+ * @mgr: manager for this port
+ * @port: unverified port to deallocate vcpi for
+ */
+void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
+{
+ port = drm_dp_get_validated_port_ref(mgr, port);
+ if (!port)
+ return;
+
+ drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+ port->vcpi.num_slots = 0;
+ port->vcpi.pbn = 0;
+ port->vcpi.aligned_pbn = 0;
+ port->vcpi.vcpi = 0;
+ drm_dp_put_port(port);
+}
+EXPORT_SYMBOL(drm_dp_mst_deallocate_vcpi);
+
+static int drm_dp_dpcd_write_payload(struct drm_dp_mst_topology_mgr *mgr,
+ int id, struct drm_dp_payload *payload)
+{
+ u8 payload_alloc[3], status;
+ int ret;
+ int retries = 0;
+
+ drm_dp_dpcd_writeb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
+ DP_PAYLOAD_TABLE_UPDATED);
+
+ payload_alloc[0] = id;
+ payload_alloc[1] = payload->start_slot;
+ payload_alloc[2] = payload->num_slots;
+
+ ret = drm_dp_dpcd_write(mgr->aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
+ if (ret != 3) {
+ DRM_DEBUG_KMS("failed to write payload allocation %d\n", ret);
+ goto fail;
+ }
+
+retry:
+ ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
+ if (ret < 0) {
+ DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
+ goto fail;
+ }
+
+ if (!(status & DP_PAYLOAD_TABLE_UPDATED)) {
+ retries++;
+ if (retries < 20) {
+ usleep_range(10000, 20000);
+ goto retry;
+ }
+ DRM_DEBUG_KMS("status not set after read payload table status %d\n", status);
+ ret = -EINVAL;
+ goto fail;
+ }
+ ret = 0;
+fail:
+ return ret;
+}
+
+
+/**
+ * drm_dp_check_act_status() - Check ACT handled status.
+ * @mgr: manager to use
+ *
+ * Check the payload status bits in the DPCD for ACT handled completion.
+ */
+int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr)
+{
+ u8 status;
+ int ret;
+ int count = 0;
+
+ do {
+ ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
+
+ if (ret < 0) {
+ DRM_DEBUG_KMS("failed to read payload table status %d\n", ret);
+ goto fail;
+ }
+
+ if (status & DP_PAYLOAD_ACT_HANDLED)
+ break;
+ count++;
+ udelay(100);
+
+ } while (count < 30);
+
+ if (!(status & DP_PAYLOAD_ACT_HANDLED)) {
+ DRM_DEBUG_KMS("failed to get ACT bit %d after %d retries\n", status, count);
+ ret = -EINVAL;
+ goto fail;
+ }
+ return 0;
+fail:
+ return ret;
+}
+EXPORT_SYMBOL(drm_dp_check_act_status);
+
+/**
+ * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.
+ * @clock: dot clock for the mode
+ * @bpp: bpp for the mode.
+ *
+ * This uses the formula in the spec to calculate the PBN value for a mode.
+ */
+int drm_dp_calc_pbn_mode(int clock, int bpp)
+{
+ fixed20_12 pix_bw;
+ fixed20_12 fbpp;
+ fixed20_12 result;
+ fixed20_12 margin, tmp;
+ u32 res;
+
+ pix_bw.full = dfixed_const(clock);
+ fbpp.full = dfixed_const(bpp);
+ tmp.full = dfixed_const(8);
+ fbpp.full = dfixed_div(fbpp, tmp);
+
+ result.full = dfixed_mul(pix_bw, fbpp);
+ margin.full = dfixed_const(54);
+ tmp.full = dfixed_const(64);
+ margin.full = dfixed_div(margin, tmp);
+ result.full = dfixed_div(result, margin);
+
+ margin.full = dfixed_const(1006);
+ tmp.full = dfixed_const(1000);
+ margin.full = dfixed_div(margin, tmp);
+ result.full = dfixed_mul(result, margin);
+
+ result.full = dfixed_div(result, tmp);
+ result.full = dfixed_ceil(result);
+ res = dfixed_trunc(result);
+ return res;
+}
+EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
+
+static int test_calc_pbn_mode(void)
+{
+ int ret;
+ ret = drm_dp_calc_pbn_mode(154000, 30);
+ if (ret != 689)
+ return -EINVAL;
+ ret = drm_dp_calc_pbn_mode(234000, 30);
+ if (ret != 1047)
+ return -EINVAL;
+ return 0;
+}
+
+/* we want to kick the TX after we've ack the up/down IRQs. */
+static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr)
+{
+ queue_work(system_long_wq, &mgr->tx_work);
+}
+
+static void drm_dp_mst_dump_mstb(struct seq_file *m,
+ struct drm_dp_mst_branch *mstb)
+{
+ struct drm_dp_mst_port *port;
+ int tabs = mstb->lct;
+ char prefix[10];
+ int i;
+
+ for (i = 0; i < tabs; i++)
+ prefix[i] = '\t';
+ prefix[i] = '\0';
+
+ seq_printf(m, "%smst: %p, %d\n", prefix, mstb, mstb->num_ports);
+ list_for_each_entry(port, &mstb->ports, next) {
+ seq_printf(m, "%sport: %d: ddps: %d ldps: %d, %p, conn: %p\n", prefix, port->port_num, port->ddps, port->ldps, port, port->connector);
+ if (port->mstb)
+ drm_dp_mst_dump_mstb(m, port->mstb);
+ }
+}
+
+static bool dump_dp_payload_table(struct drm_dp_mst_topology_mgr *mgr,
+ char *buf)
+{
+ int ret;
+ int i;
+ for (i = 0; i < 4; i++) {
+ ret = drm_dp_dpcd_read(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS + (i * 16), &buf[i * 16], 16);
+ if (ret != 16)
+ break;
+ }
+ if (i == 4)
+ return true;
+ return false;
+}
+
+/**
+ * drm_dp_mst_dump_topology(): dump topology to seq file.
+ * @m: seq_file to dump output to
+ * @mgr: manager to dump current topology for.
+ *
+ * helper to dump MST topology to a seq file for debugfs.
+ */
+void drm_dp_mst_dump_topology(struct seq_file *m,
+ struct drm_dp_mst_topology_mgr *mgr)
+{
+ int i;
+ struct drm_dp_mst_port *port;
+ mutex_lock(&mgr->lock);
+ if (mgr->mst_primary)
+ drm_dp_mst_dump_mstb(m, mgr->mst_primary);
+
+ /* dump VCPIs */
+ mutex_unlock(&mgr->lock);
+
+ mutex_lock(&mgr->payload_lock);
+ seq_printf(m, "vcpi: %lx\n", mgr->payload_mask);
+
+ for (i = 0; i < mgr->max_payloads; i++) {
+ if (mgr->proposed_vcpis[i]) {
+ port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+ seq_printf(m, "vcpi %d: %d %d %d\n", i, port->port_num, port->vcpi.vcpi, port->vcpi.num_slots);
+ } else
+ seq_printf(m, "vcpi %d:unsed\n", i);
+ }
+ for (i = 0; i < mgr->max_payloads; i++) {
+ seq_printf(m, "payload %d: %d, %d, %d\n",
+ i,
+ mgr->payloads[i].payload_state,
+ mgr->payloads[i].start_slot,
+ mgr->payloads[i].num_slots);
+
+
+ }
+ mutex_unlock(&mgr->payload_lock);
+
+ mutex_lock(&mgr->lock);
+ if (mgr->mst_primary) {
+ u8 buf[64];
+ bool bret;
+ int ret;
+ ret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, buf, DP_RECEIVER_CAP_SIZE);
+ seq_printf(m, "dpcd: ");
+ for (i = 0; i < DP_RECEIVER_CAP_SIZE; i++)
+ seq_printf(m, "%02x ", buf[i]);
+ seq_printf(m, "\n");
+ ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);
+ seq_printf(m, "faux/mst: ");
+ for (i = 0; i < 2; i++)
+ seq_printf(m, "%02x ", buf[i]);
+ seq_printf(m, "\n");
+ ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);
+ seq_printf(m, "mst ctrl: ");
+ for (i = 0; i < 1; i++)
+ seq_printf(m, "%02x ", buf[i]);
+ seq_printf(m, "\n");
+
+ bret = dump_dp_payload_table(mgr, buf);
+ if (bret == true) {
+ seq_printf(m, "payload table: ");
+ for (i = 0; i < 63; i++)
+ seq_printf(m, "%02x ", buf[i]);
+ seq_printf(m, "\n");
+ }
+
+ }
+
+ mutex_unlock(&mgr->lock);
+
+}
+EXPORT_SYMBOL(drm_dp_mst_dump_topology);
+
+static void drm_dp_tx_work(struct work_struct *work)
+{
+ struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);
+
+ mutex_lock(&mgr->qlock);
+ if (mgr->tx_down_in_progress)
+ process_single_down_tx_qlock(mgr);
+ mutex_unlock(&mgr->qlock);
+}
+
+/**
+ * drm_dp_mst_topology_mgr_init - initialise a topology manager
+ * @mgr: manager struct to initialise
+ * @dev: device providing this structure - for i2c addition.
+ * @aux: DP helper aux channel to talk to this device
+ * @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
+ * @max_payloads: maximum number of payloads this GPU can source
+ * @conn_base_id: the connector object ID the MST device is connected to.
+ *
+ * Return 0 for success, or negative error code on failure
+ */
+int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
+ struct device *dev, struct drm_dp_aux *aux,
+ int max_dpcd_transaction_bytes,
+ int max_payloads, int conn_base_id)
+{
+ mutex_init(&mgr->lock);
+ mutex_init(&mgr->qlock);
+ mutex_init(&mgr->payload_lock);
+ INIT_LIST_HEAD(&mgr->tx_msg_upq);
+ INIT_LIST_HEAD(&mgr->tx_msg_downq);
+ INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
+ INIT_WORK(&mgr->tx_work, drm_dp_tx_work);
+ init_waitqueue_head(&mgr->tx_waitq);
+ mgr->dev = dev;
+ mgr->aux = aux;
+ mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
+ mgr->max_payloads = max_payloads;
+ mgr->conn_base_id = conn_base_id;
+ mgr->payloads = kcalloc(max_payloads, sizeof(struct drm_dp_payload), GFP_KERNEL);
+ if (!mgr->payloads)
+ return -ENOMEM;
+ mgr->proposed_vcpis = kcalloc(max_payloads, sizeof(struct drm_dp_vcpi *), GFP_KERNEL);
+ if (!mgr->proposed_vcpis)
+ return -ENOMEM;
+ set_bit(0, &mgr->payload_mask);
+ test_calc_pbn_mode();
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
+
+/**
+ * drm_dp_mst_topology_mgr_destroy() - destroy topology manager.
+ * @mgr: manager to destroy
+ */
+void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
+{
+ mutex_lock(&mgr->payload_lock);
+ kfree(mgr->payloads);
+ mgr->payloads = NULL;
+ kfree(mgr->proposed_vcpis);
+ mgr->proposed_vcpis = NULL;
+ mutex_unlock(&mgr->payload_lock);
+ mgr->dev = NULL;
+ mgr->aux = NULL;
+}
+EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
+
+/* I2C device */
+static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
+ int num)
+{
+ struct drm_dp_aux *aux = adapter->algo_data;
+ struct drm_dp_mst_port *port = container_of(aux, struct drm_dp_mst_port, aux);
+ struct drm_dp_mst_branch *mstb;
+ struct drm_dp_mst_topology_mgr *mgr = port->mgr;
+ unsigned int i;
+ bool reading = false;
+ struct drm_dp_sideband_msg_req_body msg;
+ struct drm_dp_sideband_msg_tx *txmsg = NULL;
+ int ret;
+
+ mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent);
+ if (!mstb)
+ return -EREMOTEIO;
+
+ /* construct i2c msg */
+ /* see if last msg is a read */
+ if (msgs[num - 1].flags & I2C_M_RD)
+ reading = true;
+
+ if (!reading) {
+ DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ msg.req_type = DP_REMOTE_I2C_READ;
+ msg.u.i2c_read.num_transactions = num - 1;
+ msg.u.i2c_read.port_number = port->port_num;
+ for (i = 0; i < num - 1; i++) {
+ msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr;
+ msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;
+ msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;
+ }
+ msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;
+ msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;
+
+ txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+ if (!txmsg) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ txmsg->dst = mstb;
+ drm_dp_encode_sideband_req(&msg, txmsg);
+
+ drm_dp_queue_down_tx(mgr, txmsg);
+
+ ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
+ if (ret > 0) {
+
+ if (txmsg->reply.reply_type == 1) { /* got a NAK back */
+ ret = -EREMOTEIO;
+ goto out;
+ }
+ if (txmsg->reply.u.remote_i2c_read_ack.num_bytes != msgs[num - 1].len) {
+ ret = -EIO;
+ goto out;
+ }
+ memcpy(msgs[num - 1].buf, txmsg->reply.u.remote_i2c_read_ack.bytes, msgs[num - 1].len);
+ ret = num;
+ }
+out:
+ kfree(txmsg);
+ drm_dp_put_mst_branch_device(mstb);
+ return ret;
+}
+
+static u32 drm_dp_mst_i2c_functionality(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+ I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+ I2C_FUNC_10BIT_ADDR;
+}
+
+static const struct i2c_algorithm drm_dp_mst_i2c_algo = {
+ .functionality = drm_dp_mst_i2c_functionality,
+ .master_xfer = drm_dp_mst_i2c_xfer,
+};
+
+/**
+ * drm_dp_mst_register_i2c_bus() - register an I2C adapter for I2C-over-AUX
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux)
+{
+ aux->ddc.algo = &drm_dp_mst_i2c_algo;
+ aux->ddc.algo_data = aux;
+ aux->ddc.retries = 3;
+
+ aux->ddc.class = I2C_CLASS_DDC;
+ aux->ddc.owner = THIS_MODULE;
+ aux->ddc.dev.parent = aux->dev;
+ aux->ddc.dev.of_node = aux->dev->of_node;
+
+ strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
+ sizeof(aux->ddc.name));
+
+ return i2c_add_adapter(&aux->ddc);
+}
+
+/**
+ * drm_dp_mst_unregister_i2c_bus() - unregister an I2C-over-AUX adapter
+ * @aux: DisplayPort AUX channel
+ */
+static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux)
+{
+ i2c_del_adapter(&aux->ddc);
+}
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8218078b6133..3242e208c0d0 100755..100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1,31 +1,11 @@
-/**
- * \file drm_drv.c
- * Generic driver template
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- *
- * To use this template, you must at least define the following (samples
- * given for the MGA driver):
- *
- * \code
- * #define DRIVER_AUTHOR "VA Linux Systems, Inc."
- *
- * #define DRIVER_NAME "mga"
- * #define DRIVER_DESC "Matrox G200/G400"
- * #define DRIVER_DATE "20001127"
- *
- * #define drm_x mga_##x
- * \endcode
- */
-
/*
- * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
*
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
+ * Author Rickard E. (Rik) Faith <faith@valinux.com>
+ *
* 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
@@ -40,432 +20,906 @@
* 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
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mount.h>
#include <linux/slab.h>
-#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_core.h>
+#include "drm_legacy.h"
+unsigned int drm_debug = 0; /* 1 to enable debug output */
+EXPORT_SYMBOL(drm_debug);
-static int drm_version(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-
-#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
- [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
-
-/** Ioctl table */
-static const struct drm_ioctl_desc drm_ioctls[] = {
- DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
-
- DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
-
- DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
-
- DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-
- DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH),
-
- DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-
-#if __OS_HAS_AGP
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-#endif
-
- DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_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_MODESET_CTL, drm_modeset_ctl, 0),
-
- DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-
- DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
-
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-
- DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
-
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-};
+unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
-#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
-/** File operations structure */
-static const struct file_operations drm_stub_fops = {
- .owner = THIS_MODULE,
- .open = drm_stub_open,
- .llseek = noop_llseek,
-};
+/*
+ * Default to use monotonic timestamps for wait-for-vblank and page-flip
+ * complete events.
+ */
+unsigned int drm_timestamp_monotonic = 1;
-static int __init drm_core_init(void)
+MODULE_AUTHOR(CORE_AUTHOR);
+MODULE_DESCRIPTION(CORE_DESC);
+MODULE_LICENSE("GPL and additional rights");
+MODULE_PARM_DESC(debug, "Enable debug output");
+MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]");
+MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
+MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
+
+module_param_named(debug, drm_debug, int, 0600);
+module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
+module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
+module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
+
+static DEFINE_SPINLOCK(drm_minor_lock);
+static struct idr drm_minors_idr;
+
+struct class *drm_class;
+static struct dentry *drm_debugfs_root;
+
+int drm_err(const char *func, const char *format, ...)
{
- int ret = -ENOMEM;
+ struct va_format vaf;
+ va_list args;
+ int r;
- drm_global_init();
- drm_connector_ida_init();
- idr_init(&drm_minors_idr);
+ va_start(args, format);
- if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
- goto err_p1;
+ vaf.fmt = format;
+ vaf.va = &args;
- drm_class = drm_sysfs_create(THIS_MODULE, "drm");
- if (IS_ERR(drm_class)) {
- printk(KERN_ERR "DRM: Error creating drm class.\n");
- ret = PTR_ERR(drm_class);
- goto err_p2;
+ r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf);
+
+ va_end(args);
+
+ return r;
+}
+EXPORT_SYMBOL(drm_err);
+
+void drm_ut_debug_printk(const char *function_name, const char *format, ...)
+{
+ struct va_format vaf;
+ va_list args;
+
+ va_start(args, format);
+ vaf.fmt = format;
+ vaf.va = &args;
+
+ printk(KERN_DEBUG "[" DRM_NAME ":%s] %pV", function_name, &vaf);
+
+ va_end(args);
+}
+EXPORT_SYMBOL(drm_ut_debug_printk);
+
+struct drm_master *drm_master_create(struct drm_minor *minor)
+{
+ struct drm_master *master;
+
+ master = kzalloc(sizeof(*master), GFP_KERNEL);
+ if (!master)
+ return NULL;
+
+ kref_init(&master->refcount);
+ spin_lock_init(&master->lock.spinlock);
+ init_waitqueue_head(&master->lock.lock_queue);
+ if (drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER)) {
+ kfree(master);
+ return NULL;
}
+ INIT_LIST_HEAD(&master->magicfree);
+ master->minor = minor;
- drm_debugfs_root = debugfs_create_dir("dri", NULL);
- if (!drm_debugfs_root) {
- DRM_ERROR("Cannot create /sys/kernel/debug/dri\n");
- ret = -1;
- goto err_p3;
+ return master;
+}
+
+struct drm_master *drm_master_get(struct drm_master *master)
+{
+ kref_get(&master->refcount);
+ return master;
+}
+EXPORT_SYMBOL(drm_master_get);
+
+static void drm_master_destroy(struct kref *kref)
+{
+ struct drm_master *master = container_of(kref, struct drm_master, refcount);
+ struct drm_magic_entry *pt, *next;
+ struct drm_device *dev = master->minor->dev;
+ struct drm_map_list *r_list, *list_temp;
+
+ mutex_lock(&dev->struct_mutex);
+ if (dev->driver->master_destroy)
+ dev->driver->master_destroy(dev, master);
+
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
+ if (r_list->master == master) {
+ drm_rmmap_locked(dev, r_list->map);
+ r_list = NULL;
+ }
}
- DRM_INFO("Initialized %s %d.%d.%d %s\n",
- CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
- return 0;
-err_p3:
- drm_sysfs_destroy();
-err_p2:
- unregister_chrdev(DRM_MAJOR, "drm");
+ if (master->unique) {
+ kfree(master->unique);
+ master->unique = NULL;
+ master->unique_len = 0;
+ }
- idr_destroy(&drm_minors_idr);
-err_p1:
- return ret;
+ list_for_each_entry_safe(pt, next, &master->magicfree, head) {
+ list_del(&pt->head);
+ drm_ht_remove_item(&master->magiclist, &pt->hash_item);
+ kfree(pt);
+ }
+
+ drm_ht_remove(&master->magiclist);
+
+ mutex_unlock(&dev->struct_mutex);
+ kfree(master);
}
-static void __exit drm_core_exit(void)
+void drm_master_put(struct drm_master **master)
{
- debugfs_remove(drm_debugfs_root);
- drm_sysfs_destroy();
+ kref_put(&(*master)->refcount, drm_master_destroy);
+ *master = NULL;
+}
+EXPORT_SYMBOL(drm_master_put);
- unregister_chrdev(DRM_MAJOR, "drm");
+int drm_setmaster_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ int ret = 0;
- drm_connector_ida_destroy();
- idr_destroy(&drm_minors_idr);
+ mutex_lock(&dev->master_mutex);
+ if (file_priv->is_master)
+ goto out_unlock;
+
+ if (file_priv->minor->master) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (!file_priv->master) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ file_priv->minor->master = drm_master_get(file_priv->master);
+ file_priv->is_master = 1;
+ if (dev->driver->master_set) {
+ ret = dev->driver->master_set(dev, file_priv, false);
+ if (unlikely(ret != 0)) {
+ file_priv->is_master = 0;
+ drm_master_put(&file_priv->minor->master);
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&dev->master_mutex);
+ return ret;
}
-module_init(drm_core_init);
-module_exit(drm_core_exit);
+int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ int ret = -EINVAL;
-/**
- * Copy and IOCTL return string to user space
+ mutex_lock(&dev->master_mutex);
+ if (!file_priv->is_master)
+ goto out_unlock;
+
+ if (!file_priv->minor->master)
+ goto out_unlock;
+
+ ret = 0;
+ if (dev->driver->master_drop)
+ dev->driver->master_drop(dev, file_priv, false);
+ drm_master_put(&file_priv->minor->master);
+ file_priv->is_master = 0;
+
+out_unlock:
+ mutex_unlock(&dev->master_mutex);
+ return ret;
+}
+
+/*
+ * DRM Minors
+ * A DRM device can provide several char-dev interfaces on the DRM-Major. Each
+ * of them is represented by a drm_minor object. Depending on the capabilities
+ * of the device-driver, different interfaces are registered.
+ *
+ * Minors can be accessed via dev->$minor_name. This pointer is either
+ * NULL or a valid drm_minor pointer and stays valid as long as the device is
+ * valid. This means, DRM minors have the same life-time as the underlying
+ * device. However, this doesn't mean that the minor is active. Minors are
+ * registered and unregistered dynamically according to device-state.
*/
-static int drm_copy_field(char *buf, size_t *buf_len, const char *value)
+
+static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
+ unsigned int type)
{
- int len;
+ switch (type) {
+ case DRM_MINOR_LEGACY:
+ return &dev->primary;
+ case DRM_MINOR_RENDER:
+ return &dev->render;
+ case DRM_MINOR_CONTROL:
+ return &dev->control;
+ default:
+ return NULL;
+ }
+}
- /* don't overflow userbuf */
- len = strlen(value);
- if (len > *buf_len)
- len = *buf_len;
+static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
+{
+ struct drm_minor *minor;
+ unsigned long flags;
+ int r;
+
+ minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+ if (!minor)
+ return -ENOMEM;
+
+ minor->type = type;
+ minor->dev = dev;
+
+ idr_preload(GFP_KERNEL);
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ r = idr_alloc(&drm_minors_idr,
+ NULL,
+ 64 * type,
+ 64 * (type + 1),
+ GFP_NOWAIT);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+ idr_preload_end();
+
+ if (r < 0)
+ goto err_free;
+
+ minor->index = r;
+
+ minor->kdev = drm_sysfs_minor_alloc(minor);
+ if (IS_ERR(minor->kdev)) {
+ r = PTR_ERR(minor->kdev);
+ goto err_index;
+ }
- /* let userspace know exact length of driver value (which could be
- * larger than the userspace-supplied buffer) */
- *buf_len = strlen(value);
+ *drm_minor_get_slot(dev, type) = minor;
+ return 0;
+
+err_index:
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ idr_remove(&drm_minors_idr, minor->index);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+err_free:
+ kfree(minor);
+ return r;
+}
+
+static void drm_minor_free(struct drm_device *dev, unsigned int type)
+{
+ struct drm_minor **slot, *minor;
+ unsigned long flags;
+
+ slot = drm_minor_get_slot(dev, type);
+ minor = *slot;
+ if (!minor)
+ return;
+
+ drm_mode_group_destroy(&minor->mode_group);
+ put_device(minor->kdev);
+
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ idr_remove(&drm_minors_idr, minor->index);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+
+ kfree(minor);
+ *slot = NULL;
+}
- /* finally, try filling in the userbuf */
- if (len && buf)
- if (copy_to_user(buf, value, len))
- return -EFAULT;
+static int drm_minor_register(struct drm_device *dev, unsigned int type)
+{
+ struct drm_minor *minor;
+ unsigned long flags;
+ int ret;
+
+ DRM_DEBUG("\n");
+
+ minor = *drm_minor_get_slot(dev, type);
+ if (!minor)
+ return 0;
+
+ ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root);
+ if (ret) {
+ DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
+ return ret;
+ }
+
+ ret = device_add(minor->kdev);
+ if (ret)
+ goto err_debugfs;
+
+ /* replace NULL with @minor so lookups will succeed from now on */
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ idr_replace(&drm_minors_idr, minor, minor->index);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+
+ DRM_DEBUG("new minor registered %d\n", minor->index);
return 0;
+
+err_debugfs:
+ drm_debugfs_cleanup(minor);
+ return ret;
+}
+
+static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
+{
+ struct drm_minor *minor;
+ unsigned long flags;
+
+ minor = *drm_minor_get_slot(dev, type);
+ if (!minor || !device_is_registered(minor->kdev))
+ return;
+
+ /* replace @minor with NULL so lookups will fail from now on */
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ idr_replace(&drm_minors_idr, NULL, minor->index);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+
+ device_del(minor->kdev);
+ dev_set_drvdata(minor->kdev, NULL); /* safety belt */
+ drm_debugfs_cleanup(minor);
}
/**
- * Get version information
+ * drm_minor_acquire - Acquire a DRM minor
+ * @minor_id: Minor ID of the DRM-minor
+ *
+ * Looks up the given minor-ID and returns the respective DRM-minor object. The
+ * refence-count of the underlying device is increased so you must release this
+ * object with drm_minor_release().
*
- * \param inode device inode.
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_version structure.
- * \return zero on success or negative number on failure.
+ * As long as you hold this minor, it is guaranteed that the object and the
+ * minor->dev pointer will stay valid! However, the device may get unplugged and
+ * unregistered while you hold the minor.
*
- * Fills in the version information in \p arg.
+ * Returns:
+ * Pointer to minor-object with increased device-refcount, or PTR_ERR on
+ * failure.
*/
-static int drm_version(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+struct drm_minor *drm_minor_acquire(unsigned int minor_id)
{
- struct drm_version *version = data;
- int err;
+ struct drm_minor *minor;
+ unsigned long flags;
+
+ spin_lock_irqsave(&drm_minor_lock, flags);
+ minor = idr_find(&drm_minors_idr, minor_id);
+ if (minor)
+ drm_dev_ref(minor->dev);
+ spin_unlock_irqrestore(&drm_minor_lock, flags);
+
+ if (!minor) {
+ return ERR_PTR(-ENODEV);
+ } else if (drm_device_is_unplugged(minor->dev)) {
+ drm_dev_unref(minor->dev);
+ return ERR_PTR(-ENODEV);
+ }
- version->version_major = dev->driver->major;
- version->version_minor = dev->driver->minor;
- version->version_patchlevel = dev->driver->patchlevel;
- err = drm_copy_field(version->name, &version->name_len,
- dev->driver->name);
- if (!err)
- err = drm_copy_field(version->date, &version->date_len,
- dev->driver->date);
- if (!err)
- err = drm_copy_field(version->desc, &version->desc_len,
- dev->driver->desc);
+ return minor;
+}
- return err;
+/**
+ * drm_minor_release - Release DRM minor
+ * @minor: Pointer to DRM minor object
+ *
+ * Release a minor that was previously acquired via drm_minor_acquire().
+ */
+void drm_minor_release(struct drm_minor *minor)
+{
+ drm_dev_unref(minor->dev);
}
/**
- * drm_ioctl_permit - Check ioctl permissions against caller
+ * drm_put_dev - Unregister and release a DRM device
+ * @dev: DRM device
+ *
+ * Called at module unload time or when a PCI device is unplugged.
*
- * @flags: ioctl permission flags.
- * @file_priv: Pointer to struct drm_file identifying the caller.
+ * Use of this function is discouraged. It will eventually go away completely.
+ * Please use drm_dev_unregister() and drm_dev_unref() explicitly instead.
*
- * Checks whether the caller is allowed to run an ioctl with the
- * indicated permissions. If so, returns zero. Otherwise returns an
- * error code suitable for ioctl return.
+ * Cleans up all DRM device, calling drm_lastclose().
*/
-static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
+void drm_put_dev(struct drm_device *dev)
{
- /* ROOT_ONLY is only for CAP_SYS_ADMIN */
- if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
- return -EACCES;
-
- /* AUTH is only for authenticated or render client */
- if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
- !file_priv->authenticated))
- return -EACCES;
-
- /* MASTER is only for master or control clients */
- if (unlikely((flags & DRM_MASTER) && !file_priv->is_master &&
- !drm_is_control_client(file_priv)))
- return -EACCES;
-
- /* Control clients must be explicitly allowed */
- if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
- drm_is_control_client(file_priv)))
- return -EACCES;
-
- /* Render clients must be explicitly allowed */
- if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
- drm_is_render_client(file_priv)))
- return -EACCES;
+ DRM_DEBUG("\n");
- return 0;
+ if (!dev) {
+ DRM_ERROR("cleanup called no dev\n");
+ return;
+ }
+
+ drm_dev_unregister(dev);
+ drm_dev_unref(dev);
+}
+EXPORT_SYMBOL(drm_put_dev);
+
+void drm_unplug_dev(struct drm_device *dev)
+{
+ /* for a USB device */
+ drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+ drm_minor_unregister(dev, DRM_MINOR_RENDER);
+ drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+
+ mutex_lock(&drm_global_mutex);
+
+ drm_device_set_unplugged(dev);
+
+ if (dev->open_count == 0) {
+ drm_put_dev(dev);
+ }
+ mutex_unlock(&drm_global_mutex);
+}
+EXPORT_SYMBOL(drm_unplug_dev);
+
+/*
+ * DRM internal mount
+ * We want to be able to allocate our own "struct address_space" to control
+ * memory-mappings in VRAM (or stolen RAM, ...). However, core MM does not allow
+ * stand-alone address_space objects, so we need an underlying inode. As there
+ * is no way to allocate an independent inode easily, we need a fake internal
+ * VFS mount-point.
+ *
+ * The drm_fs_inode_new() function allocates a new inode, drm_fs_inode_free()
+ * frees it again. You are allowed to use iget() and iput() to get references to
+ * the inode. But each drm_fs_inode_new() call must be paired with exactly one
+ * drm_fs_inode_free() call (which does not have to be the last iput()).
+ * We use drm_fs_inode_*() to manage our internal VFS mount-point and share it
+ * between multiple inode-users. You could, technically, call
+ * iget() + drm_fs_inode_free() directly after alloc and sometime later do an
+ * iput(), but this way you'd end up with a new vfsmount for each inode.
+ */
+
+static int drm_fs_cnt;
+static struct vfsmount *drm_fs_mnt;
+
+static const struct dentry_operations drm_fs_dops = {
+ .d_dname = simple_dname,
+};
+
+static const struct super_operations drm_fs_sops = {
+ .statfs = simple_statfs,
+};
+
+static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data)
+{
+ return mount_pseudo(fs_type,
+ "drm:",
+ &drm_fs_sops,
+ &drm_fs_dops,
+ 0x010203ff);
+}
+
+static struct file_system_type drm_fs_type = {
+ .name = "drm",
+ .owner = THIS_MODULE,
+ .mount = drm_fs_mount,
+ .kill_sb = kill_anon_super,
+};
+
+static struct inode *drm_fs_inode_new(void)
+{
+ struct inode *inode;
+ int r;
+
+ r = simple_pin_fs(&drm_fs_type, &drm_fs_mnt, &drm_fs_cnt);
+ if (r < 0) {
+ DRM_ERROR("Cannot mount pseudo fs: %d\n", r);
+ return ERR_PTR(r);
+ }
+
+ inode = alloc_anon_inode(drm_fs_mnt->mnt_sb);
+ if (IS_ERR(inode))
+ simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
+
+ return inode;
+}
+
+static void drm_fs_inode_free(struct inode *inode)
+{
+ if (inode) {
+ iput(inode);
+ simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
+ }
}
/**
- * Called whenever a process performs an ioctl on /dev/drm.
+ * drm_dev_alloc - Allocate new DRM device
+ * @driver: DRM driver to allocate device for
+ * @parent: Parent device object
*
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or negative number on failure.
+ * Allocate and initialize a new DRM device. No device registration is done.
+ * Call drm_dev_register() to advertice the device to user space and register it
+ * with other core subsystems.
*
- * Looks up the ioctl function in the ::ioctls table, checking for root
- * previleges if so required, and dispatches to the respective function.
+ * The initial ref-count of the object is 1. Use drm_dev_ref() and
+ * drm_dev_unref() to take and drop further ref-counts.
+ *
+ * RETURNS:
+ * Pointer to new DRM device, or NULL if out of memory.
*/
-long drm_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
+struct drm_device *drm_dev_alloc(struct drm_driver *driver,
+ struct device *parent)
{
- struct drm_file *file_priv = filp->private_data;
struct drm_device *dev;
- const struct drm_ioctl_desc *ioctl = NULL;
- drm_ioctl_t *func;
- unsigned int nr = DRM_IOCTL_NR(cmd);
- int retcode = -EINVAL;
- char stack_kdata[128];
- char *kdata = NULL;
- unsigned int usize, asize;
-
- dev = file_priv->minor->dev;
-
- if (drm_device_is_unplugged(dev))
- return -ENODEV;
-
- if ((nr >= DRM_CORE_IOCTL_COUNT) &&
- ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
- goto err_i1;
- if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
- (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
- u32 drv_size;
- ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
- drv_size = _IOC_SIZE(ioctl->cmd_drv);
- usize = asize = _IOC_SIZE(cmd);
- if (drv_size > asize)
- asize = drv_size;
- cmd = ioctl->cmd_drv;
+ int ret;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ kref_init(&dev->ref);
+ dev->dev = parent;
+ dev->driver = driver;
+
+ INIT_LIST_HEAD(&dev->filelist);
+ INIT_LIST_HEAD(&dev->ctxlist);
+ INIT_LIST_HEAD(&dev->vmalist);
+ INIT_LIST_HEAD(&dev->maplist);
+ INIT_LIST_HEAD(&dev->vblank_event_list);
+
+ spin_lock_init(&dev->buf_lock);
+ spin_lock_init(&dev->event_lock);
+ mutex_init(&dev->struct_mutex);
+ mutex_init(&dev->ctxlist_mutex);
+ mutex_init(&dev->master_mutex);
+
+ dev->anon_inode = drm_fs_inode_new();
+ if (IS_ERR(dev->anon_inode)) {
+ ret = PTR_ERR(dev->anon_inode);
+ DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
+ goto err_free;
}
- else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
- u32 drv_size;
-
- ioctl = &drm_ioctls[nr];
- drv_size = _IOC_SIZE(ioctl->cmd);
- usize = asize = _IOC_SIZE(cmd);
- if (drv_size > asize)
- asize = drv_size;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_minors;
+ }
- cmd = ioctl->cmd;
- } else
- goto err_i1;
+ if (drm_core_check_feature(dev, DRIVER_RENDER)) {
+ ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
+ if (ret)
+ goto err_minors;
+ }
- DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
- task_pid_nr(current),
- (long)old_encode_dev(file_priv->minor->kdev->devt),
- file_priv->authenticated, ioctl->name);
+ ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
+ if (ret)
+ goto err_minors;
- /* Do not trust userspace, use our own definition */
- func = ioctl->func;
+ if (drm_ht_create(&dev->map_hash, 12))
+ goto err_minors;
- if (unlikely(!func)) {
- DRM_DEBUG("no function\n");
- retcode = -EINVAL;
- goto err_i1;
+ ret = drm_legacy_ctxbitmap_init(dev);
+ if (ret) {
+ DRM_ERROR("Cannot allocate memory for context bitmap.\n");
+ goto err_ht;
}
- retcode = drm_ioctl_permit(ioctl->flags, file_priv);
- if (unlikely(retcode))
- goto err_i1;
-
- if (cmd & (IOC_IN | IOC_OUT)) {
- if (asize <= sizeof(stack_kdata)) {
- kdata = stack_kdata;
- } else {
- kdata = kmalloc(asize, GFP_KERNEL);
- if (!kdata) {
- retcode = -ENOMEM;
- goto err_i1;
- }
+ if (driver->driver_features & DRIVER_GEM) {
+ ret = drm_gem_init(dev);
+ if (ret) {
+ DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
+ goto err_ctxbitmap;
}
- if (asize > usize)
- memset(kdata + usize, 0, asize - usize);
}
- if (cmd & IOC_IN) {
- if (copy_from_user(kdata, (void __user *)arg,
- usize) != 0) {
- retcode = -EFAULT;
- goto err_i1;
- }
- } else if (cmd & IOC_OUT) {
- memset(kdata, 0, usize);
- }
+ return dev;
+
+err_ctxbitmap:
+ drm_legacy_ctxbitmap_cleanup(dev);
+err_ht:
+ drm_ht_remove(&dev->map_hash);
+err_minors:
+ drm_minor_free(dev, DRM_MINOR_LEGACY);
+ drm_minor_free(dev, DRM_MINOR_RENDER);
+ drm_minor_free(dev, DRM_MINOR_CONTROL);
+ drm_fs_inode_free(dev->anon_inode);
+err_free:
+ mutex_destroy(&dev->master_mutex);
+ kfree(dev);
+ return NULL;
+}
+EXPORT_SYMBOL(drm_dev_alloc);
+
+static void drm_dev_release(struct kref *ref)
+{
+ struct drm_device *dev = container_of(ref, struct drm_device, ref);
+
+ if (dev->driver->driver_features & DRIVER_GEM)
+ drm_gem_destroy(dev);
+
+ drm_legacy_ctxbitmap_cleanup(dev);
+ drm_ht_remove(&dev->map_hash);
+ drm_fs_inode_free(dev->anon_inode);
+
+ drm_minor_free(dev, DRM_MINOR_LEGACY);
+ drm_minor_free(dev, DRM_MINOR_RENDER);
+ drm_minor_free(dev, DRM_MINOR_CONTROL);
+
+ mutex_destroy(&dev->master_mutex);
+ kfree(dev->unique);
+ kfree(dev);
+}
- if (ioctl->flags & DRM_UNLOCKED)
- retcode = func(dev, kdata, file_priv);
- else {
- mutex_lock(&drm_global_mutex);
- retcode = func(dev, kdata, file_priv);
- mutex_unlock(&drm_global_mutex);
+/**
+ * drm_dev_ref - Take reference of a DRM device
+ * @dev: device to take reference of or NULL
+ *
+ * This increases the ref-count of @dev by one. You *must* already own a
+ * reference when calling this. Use drm_dev_unref() to drop this reference
+ * again.
+ *
+ * This function never fails. However, this function does not provide *any*
+ * guarantee whether the device is alive or running. It only provides a
+ * reference to the object and the memory associated with it.
+ */
+void drm_dev_ref(struct drm_device *dev)
+{
+ if (dev)
+ kref_get(&dev->ref);
+}
+EXPORT_SYMBOL(drm_dev_ref);
+
+/**
+ * drm_dev_unref - Drop reference of a DRM device
+ * @dev: device to drop reference of or NULL
+ *
+ * This decreases the ref-count of @dev by one. The device is destroyed if the
+ * ref-count drops to zero.
+ */
+void drm_dev_unref(struct drm_device *dev)
+{
+ if (dev)
+ kref_put(&dev->ref, drm_dev_release);
+}
+EXPORT_SYMBOL(drm_dev_unref);
+
+/**
+ * drm_dev_register - Register DRM device
+ * @dev: Device to register
+ * @flags: Flags passed to the driver's .load() function
+ *
+ * Register the DRM device @dev with the system, advertise device to user-space
+ * and start normal device operation. @dev must be allocated via drm_dev_alloc()
+ * previously.
+ *
+ * Never call this twice on any device!
+ *
+ * RETURNS:
+ * 0 on success, negative error code on failure.
+ */
+int drm_dev_register(struct drm_device *dev, unsigned long flags)
+{
+ int ret;
+
+ mutex_lock(&drm_global_mutex);
+
+ ret = drm_minor_register(dev, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_minors;
+
+ ret = drm_minor_register(dev, DRM_MINOR_RENDER);
+ if (ret)
+ goto err_minors;
+
+ ret = drm_minor_register(dev, DRM_MINOR_LEGACY);
+ if (ret)
+ goto err_minors;
+
+ if (dev->driver->load) {
+ ret = dev->driver->load(dev, flags);
+ if (ret)
+ goto err_minors;
}
- if (cmd & IOC_OUT) {
- if (copy_to_user((void __user *)arg, kdata,
- usize) != 0)
- retcode = -EFAULT;
+ /* setup grouping for legacy outputs */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_mode_group_init_legacy_group(dev,
+ &dev->primary->mode_group);
+ if (ret)
+ goto err_unload;
}
- err_i1:
- if (!ioctl)
- DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
- task_pid_nr(current),
- (long)old_encode_dev(file_priv->minor->kdev->devt),
- file_priv->authenticated, cmd, nr);
-
- if (kdata != stack_kdata)
- kfree(kdata);
- if (retcode)
- DRM_DEBUG("ret = %d\n", retcode);
- return retcode;
+ ret = 0;
+ goto out_unlock;
+
+err_unload:
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
+err_minors:
+ drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+ drm_minor_unregister(dev, DRM_MINOR_RENDER);
+ drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+out_unlock:
+ mutex_unlock(&drm_global_mutex);
+ return ret;
}
-EXPORT_SYMBOL(drm_ioctl);
+EXPORT_SYMBOL(drm_dev_register);
/**
- * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags
+ * drm_dev_unregister - Unregister DRM device
+ * @dev: Device to unregister
+ *
+ * Unregister the DRM device from the system. This does the reverse of
+ * drm_dev_register() but does not deallocate the device. The caller must call
+ * drm_dev_unref() to drop their final reference.
+ */
+void drm_dev_unregister(struct drm_device *dev)
+{
+ struct drm_map_list *r_list, *list_temp;
+
+ drm_lastclose(dev);
+
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
+
+ if (dev->agp)
+ drm_pci_agp_destroy(dev);
+
+ drm_vblank_cleanup(dev);
+
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+
+ drm_minor_unregister(dev, DRM_MINOR_LEGACY);
+ drm_minor_unregister(dev, DRM_MINOR_RENDER);
+ drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+}
+EXPORT_SYMBOL(drm_dev_unregister);
+
+/**
+ * drm_dev_set_unique - Set the unique name of a DRM device
+ * @dev: device of which to set the unique name
+ * @fmt: format string for unique name
+ *
+ * Sets the unique name of a DRM device using the specified format string and
+ * a variable list of arguments. Drivers can use this at driver probe time if
+ * the unique name of the devices they drive is static.
*
- * @nr: Ioctl number.
- * @flags: Where to return the ioctl permission flags
+ * Return: 0 on success or a negative error code on failure.
*/
-bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
+int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...)
{
- if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) ||
- (nr < DRM_COMMAND_BASE)) {
- *flags = drm_ioctls[nr].flags;
- return true;
+ va_list ap;
+
+ kfree(dev->unique);
+
+ va_start(ap, fmt);
+ dev->unique = kvasprintf(GFP_KERNEL, fmt, ap);
+ va_end(ap);
+
+ return dev->unique ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL(drm_dev_set_unique);
+
+/*
+ * DRM Core
+ * The DRM core module initializes all global DRM objects and makes them
+ * available to drivers. Once setup, drivers can probe their respective
+ * devices.
+ * Currently, core management includes:
+ * - The "DRM-Global" key/value database
+ * - Global ID management for connectors
+ * - DRM major number allocation
+ * - DRM minor management
+ * - DRM sysfs class
+ * - DRM debugfs root
+ *
+ * Furthermore, the DRM core provides dynamic char-dev lookups. For each
+ * interface registered on a DRM device, you can request minor numbers from DRM
+ * core. DRM core takes care of major-number management and char-dev
+ * registration. A stub ->open() callback forwards any open() requests to the
+ * registered minor.
+ */
+
+static int drm_stub_open(struct inode *inode, struct file *filp)
+{
+ const struct file_operations *new_fops;
+ struct drm_minor *minor;
+ int err;
+
+ DRM_DEBUG("\n");
+
+ mutex_lock(&drm_global_mutex);
+ minor = drm_minor_acquire(iminor(inode));
+ if (IS_ERR(minor)) {
+ err = PTR_ERR(minor);
+ goto out_unlock;
+ }
+
+ new_fops = fops_get(minor->dev->driver->fops);
+ if (!new_fops) {
+ err = -ENODEV;
+ goto out_release;
}
- return false;
+ replace_fops(filp, new_fops);
+ if (filp->f_op->open)
+ err = filp->f_op->open(inode, filp);
+ else
+ err = 0;
+
+out_release:
+ drm_minor_release(minor);
+out_unlock:
+ mutex_unlock(&drm_global_mutex);
+ return err;
}
-EXPORT_SYMBOL(drm_ioctl_flags);
+
+static const struct file_operations drm_stub_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_stub_open,
+ .llseek = noop_llseek,
+};
+
+static int __init drm_core_init(void)
+{
+ int ret = -ENOMEM;
+
+ drm_global_init();
+ drm_connector_ida_init();
+ idr_init(&drm_minors_idr);
+
+ if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
+ goto err_p1;
+
+ drm_class = drm_sysfs_create(THIS_MODULE, "drm");
+ if (IS_ERR(drm_class)) {
+ printk(KERN_ERR "DRM: Error creating drm class.\n");
+ ret = PTR_ERR(drm_class);
+ goto err_p2;
+ }
+
+ drm_debugfs_root = debugfs_create_dir("dri", NULL);
+ if (!drm_debugfs_root) {
+ DRM_ERROR("Cannot create /sys/kernel/debug/dri\n");
+ ret = -1;
+ goto err_p3;
+ }
+
+ DRM_INFO("Initialized %s %d.%d.%d %s\n",
+ CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
+ return 0;
+err_p3:
+ drm_sysfs_destroy();
+err_p2:
+ unregister_chrdev(DRM_MAJOR, "drm");
+
+ idr_destroy(&drm_minors_idr);
+err_p1:
+ return ret;
+}
+
+static void __exit drm_core_exit(void)
+{
+ debugfs_remove(drm_debugfs_root);
+ drm_sysfs_destroy();
+
+ unregister_chrdev(DRM_MAJOR, "drm");
+
+ drm_connector_ida_destroy();
+ idr_destroy(&drm_minors_idr);
+}
+
+module_init(drm_core_init);
+module_exit(drm_core_exit);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index dfa9769b26b5..1dbf3bc4c6a3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3305,6 +3305,7 @@ struct drm_connector *drm_select_eld(struct drm_encoder *encoder,
struct drm_device *dev = encoder->dev;
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
if (connector->encoder == encoder && connector->eld[0])
@@ -3775,8 +3776,14 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
- /* Populate picture aspect ratio from CEA mode list */
- if (frame->video_code > 0)
+ /*
+ * Populate picture aspect ratio from either
+ * user input (if specified) or from the CEA mode list.
+ */
+ if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 ||
+ mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9)
+ frame->picture_aspect = mode->picture_aspect_ratio;
+ else if (frame->video_code > 0)
frame->picture_aspect = drm_get_cea_aspect_ratio(
frame->video_code);
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index f27c883be391..cc0ae047ed3b 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -327,7 +327,7 @@ err_drm_gem_cma_free_object:
return ret;
}
-static struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {
+static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = {
.fb_probe = drm_fbdev_cma_create,
};
@@ -354,9 +354,10 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
return ERR_PTR(-ENOMEM);
}
- fbdev_cma->fb_helper.funcs = &drm_fb_cma_helper_funcs;
helper = &fbdev_cma->fb_helper;
+ drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs);
+
ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count);
if (ret < 0) {
dev_err(dev->dev, "Failed to initialize drm fb helper.\n");
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d5d8cea1a679..3144db9dc0f1 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -49,10 +49,11 @@ static LIST_HEAD(kernel_fb_helper_list);
* helper functions used by many drivers to implement the kernel mode setting
* interfaces.
*
- * Initialization is done as a three-step process with drm_fb_helper_init(),
- * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
- * Drivers with fancier requirements than the default behaviour can override the
- * second step with their own code. Teardown is done with drm_fb_helper_fini().
+ * Initialization is done as a four-step process with drm_fb_helper_prepare(),
+ * drm_fb_helper_init(), drm_fb_helper_single_add_all_connectors() and
+ * drm_fb_helper_initial_config(). Drivers with fancier requirements than the
+ * default behaviour can override the third step with their own code.
+ * Teardown is done with drm_fb_helper_fini().
*
* At runtime drivers should restore the fbdev console by calling
* drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
@@ -63,6 +64,19 @@ static LIST_HEAD(kernel_fb_helper_list);
*
* All other functions exported by the fb helper library can be used to
* implement the fbdev driver interface by the driver.
+ *
+ * It is possible, though perhaps somewhat tricky, to implement race-free
+ * hotplug detection using the fbdev helpers. The drm_fb_helper_prepare()
+ * helper must be called first to initialize the minimum required to make
+ * hotplug detection work. Drivers also need to make sure to properly set up
+ * the dev->mode_config.funcs member. After calling drm_kms_helper_poll_init()
+ * it is safe to enable interrupts and start processing hotplug events. At the
+ * same time, drivers should initialize all modeset objects such as CRTCs,
+ * encoders and connectors. To finish up the fbdev helper initialization, the
+ * drm_fb_helper_init() function is called. To probe for all attached displays
+ * and set up an initial configuration using the detected hardware, drivers
+ * should call drm_fb_helper_single_add_all_connectors() followed by
+ * drm_fb_helper_initial_config().
*/
/**
@@ -105,6 +119,58 @@ fail:
}
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
+int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_connector *connector)
+{
+ struct drm_fb_helper_connector **temp;
+ struct drm_fb_helper_connector *fb_helper_connector;
+
+ WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+ if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) {
+ temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector) * (fb_helper->connector_count + 1), GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
+
+ fb_helper->connector_info_alloc_count = fb_helper->connector_count + 1;
+ fb_helper->connector_info = temp;
+ }
+
+
+ fb_helper_connector = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
+ if (!fb_helper_connector)
+ return -ENOMEM;
+
+ fb_helper_connector->connector = connector;
+ fb_helper->connector_info[fb_helper->connector_count++] = fb_helper_connector;
+ return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
+
+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;
+
+ WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+
+ for (i = 0; i < fb_helper->connector_count; i++) {
+ if (fb_helper->connector_info[i]->connector == connector)
+ break;
+ }
+
+ if (i == fb_helper->connector_count)
+ return -EINVAL;
+ fb_helper_connector = fb_helper->connector_info[i];
+
+ for (j = i + 1; j < fb_helper->connector_count; j++) {
+ fb_helper->connector_info[j - 1] = fb_helper->connector_info[j];
+ }
+ fb_helper->connector_count--;
+ kfree(fb_helper_connector);
+ return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
+
static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
{
struct drm_fb_helper_connector *fb_helper_conn;
@@ -199,9 +265,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
struct drm_crtc_helper_funcs *funcs;
int i;
- if (list_empty(&kernel_fb_helper_list))
- return false;
-
list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
for (i = 0; i < helper->crtc_count; i++) {
struct drm_mode_set *mode_set =
@@ -531,6 +594,24 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
}
/**
+ * drm_fb_helper_prepare - setup a drm_fb_helper structure
+ * @dev: DRM device
+ * @helper: driver-allocated fbdev helper structure to set up
+ * @funcs: pointer to structure of functions associate with this helper
+ *
+ * Sets up the bare minimum to make the framebuffer helper usable. This is
+ * useful to implement race-free initialization of the polling helpers.
+ */
+void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
+ const struct drm_fb_helper_funcs *funcs)
+{
+ INIT_LIST_HEAD(&helper->kernel_fb_list);
+ helper->funcs = funcs;
+ helper->dev = dev;
+}
+EXPORT_SYMBOL(drm_fb_helper_prepare);
+
+/**
* drm_fb_helper_init - initialize a drm_fb_helper structure
* @dev: drm device
* @fb_helper: driver-allocated fbdev helper structure to initialize
@@ -542,8 +623,7 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
* nor register the fbdev. This is only done in drm_fb_helper_initial_config()
* to allow driver writes more control over the exact init sequence.
*
- * Drivers must set fb_helper->funcs before calling
- * drm_fb_helper_initial_config().
+ * Drivers must call drm_fb_helper_prepare() before calling this function.
*
* RETURNS:
* Zero if everything went ok, nonzero otherwise.
@@ -558,10 +638,6 @@ int drm_fb_helper_init(struct drm_device *dev,
if (!max_conn_count)
return -EINVAL;
- fb_helper->dev = dev;
-
- INIT_LIST_HEAD(&fb_helper->kernel_fb_list);
-
fb_helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
if (!fb_helper->crtc_info)
return -ENOMEM;
@@ -572,6 +648,7 @@ int drm_fb_helper_init(struct drm_device *dev,
kfree(fb_helper->crtc_info);
return -ENOMEM;
}
+ fb_helper->connector_info_alloc_count = dev->mode_config.num_connector;
fb_helper->connector_count = 0;
for (i = 0; i < crtc_count; i++) {
@@ -1056,7 +1133,6 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
info->fix.ypanstep = 1; /* doing it in hw */
info->fix.ywrapstep = 0;
info->fix.accel = FB_ACCEL_NONE;
- info->fix.type_aux = 0;
info->fix.line_length = pitch;
return;
@@ -1613,8 +1689,10 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config);
* either the output polling work or a work item launched from the driver's
* hotplug interrupt).
*
- * Note that the driver must ensure that this is only called _after_ the fb has
- * been fully set up, i.e. after the call to drm_fb_helper_initial_config.
+ * Note that drivers may call this even before calling
+ * drm_fb_helper_initial_config but only aftert drm_fb_helper_init. This allows
+ * for a race-free fbcon setup and will make sure that the fbdev emulation will
+ * not miss any hotplug events.
*
* RETURNS:
* 0 on success and a non-zero error code otherwise.
@@ -1624,11 +1702,8 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
struct drm_device *dev = fb_helper->dev;
u32 max_width, max_height;
- if (!fb_helper->fb)
- return 0;
-
mutex_lock(&fb_helper->dev->mode_config.mutex);
- if (!drm_fb_helper_is_bound(fb_helper)) {
+ if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true;
mutex_unlock(&fb_helper->dev->mode_config.mutex);
return 0;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 021fe5d11df5..79d5221c6e41 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -38,6 +38,7 @@
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include "drm_legacy.h"
/* from BKL pushdown */
DEFINE_MUTEX(drm_global_mutex);
@@ -112,55 +113,12 @@ err_undo:
EXPORT_SYMBOL(drm_open);
/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the dev->fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-int drm_stub_open(struct inode *inode, struct file *filp)
-{
- struct drm_device *dev;
- struct drm_minor *minor;
- int err = -ENODEV;
- const struct file_operations *new_fops;
-
- DRM_DEBUG("\n");
-
- mutex_lock(&drm_global_mutex);
- minor = drm_minor_acquire(iminor(inode));
- if (IS_ERR(minor))
- goto out_unlock;
-
- dev = minor->dev;
- new_fops = fops_get(dev->driver->fops);
- if (!new_fops)
- goto out_release;
-
- replace_fops(filp, new_fops);
- if (filp->f_op->open)
- err = filp->f_op->open(inode, filp);
-
-out_release:
- drm_minor_release(minor);
-out_unlock:
- mutex_unlock(&drm_global_mutex);
- return err;
-}
-
-/**
* Check whether DRI will run on this CPU.
*
* \return non-zero if the DRI will run on this CPU, or zero otherwise.
*/
static int drm_cpu_valid(void)
{
-#if defined(__i386__)
- if (boot_cpu_data.x86 == 3)
- return 0; /* No cmpxchg on a 386 */
-#endif
#if defined(__sparc__) && !defined(__sparc_v9__)
return 0; /* No cmpxchg before v9 sparc. */
#endif
@@ -203,8 +161,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
priv->minor = minor;
/* for compatibility root is always authenticated */
- priv->always_authenticated = capable(CAP_SYS_ADMIN);
- priv->authenticated = priv->always_authenticated;
+ priv->authenticated = capable(CAP_SYS_ADMIN);
priv->lock_count = 0;
INIT_LIST_HEAD(&priv->lhead);
@@ -429,6 +386,10 @@ int drm_release(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
+ mutex_lock(&dev->struct_mutex);
+ list_del(&file_priv->lhead);
+ mutex_unlock(&dev->struct_mutex);
+
if (dev->driver->preclose)
dev->driver->preclose(dev, file_priv);
@@ -461,44 +422,18 @@ int drm_release(struct inode *inode, struct file *filp)
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_release(dev, file_priv);
- mutex_lock(&dev->ctxlist_mutex);
- if (!list_empty(&dev->ctxlist)) {
- struct drm_ctx_list *pos, *n;
-
- list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
- if (pos->tag == file_priv &&
- pos->handle != DRM_KERNEL_CONTEXT) {
- if (dev->driver->context_dtor)
- dev->driver->context_dtor(dev,
- pos->handle);
-
- drm_ctxbitmap_free(dev, pos->handle);
-
- list_del(&pos->head);
- kfree(pos);
- }
- }
- }
- mutex_unlock(&dev->ctxlist_mutex);
+ drm_legacy_ctxbitmap_flush(dev, file_priv);
mutex_lock(&dev->master_mutex);
if (file_priv->is_master) {
struct drm_master *master = file_priv->master;
- struct drm_file *temp;
-
- mutex_lock(&dev->struct_mutex);
- list_for_each_entry(temp, &dev->filelist, lhead) {
- if ((temp->master == file_priv->master) &&
- (temp != file_priv))
- temp->authenticated = temp->always_authenticated;
- }
/**
* Since the master is disappearing, so is the
* possibility to lock.
*/
-
+ mutex_lock(&dev->struct_mutex);
if (master->lock.hw_lock) {
if (dev->sigdata.lock == master->lock.hw_lock)
dev->sigdata.lock = NULL;
@@ -522,10 +457,6 @@ int drm_release(struct inode *inode, struct file *filp)
file_priv->is_master = 0;
mutex_unlock(&dev->master_mutex);
- mutex_lock(&dev->struct_mutex);
- list_del(&file_priv->lhead);
- mutex_unlock(&dev->struct_mutex);
-
if (dev->driver->postclose)
dev->driver->postclose(dev, file_priv);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index f7d71190aad5..6adee4c2afc0 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -441,18 +441,31 @@ EXPORT_SYMBOL(drm_gem_create_mmap_offset);
* drm_gem_get_pages - helper to allocate backing pages for a GEM object
* from shmem
* @obj: obj in question
- * @gfpmask: gfp mask of requested pages
+ *
+ * This reads the page-array of the shmem-backing storage of the given gem
+ * object. An array of pages is returned. If a page is not allocated or
+ * swapped-out, this will allocate/swap-in the required pages. Note that the
+ * whole object is covered by the page-array and pinned in memory.
+ *
+ * Use drm_gem_put_pages() to release the array and unpin all pages.
+ *
+ * This uses the GFP-mask set on the shmem-mapping (see mapping_set_gfp_mask()).
+ * If you require other GFP-masks, you have to do those allocations yourself.
+ *
+ * Note that you are not allowed to change gfp-zones during runtime. That is,
+ * shmem_read_mapping_page_gfp() must be called with the same gfp_zone(gfp) as
+ * set during initialization. If you have special zone constraints, set them
+ * after drm_gem_init_object() via mapping_set_gfp_mask(). shmem-core takes care
+ * to keep pages in the required zone during swap-in.
*/
-struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
+struct page **drm_gem_get_pages(struct drm_gem_object *obj)
{
- struct inode *inode;
struct address_space *mapping;
struct page *p, **pages;
int i, npages;
/* This is the shared memory object that backs the GEM resource */
- inode = file_inode(obj->filp);
- mapping = inode->i_mapping;
+ mapping = file_inode(obj->filp)->i_mapping;
/* We already BUG_ON() for non-page-aligned sizes in
* drm_gem_object_init(), so we should never hit this unless
@@ -466,10 +479,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
if (pages == NULL)
return ERR_PTR(-ENOMEM);
- gfpmask |= mapping_gfp_mask(mapping);
-
for (i = 0; i < npages; i++) {
- p = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
+ p = shmem_read_mapping_page(mapping, i);
if (IS_ERR(p))
goto fail;
pages[i] = p;
@@ -479,7 +490,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
* __GFP_DMA32 to be set in mapping_gfp_mask(inode->i_mapping)
* so shmem can relocate pages during swapin if required.
*/
- BUG_ON((gfpmask & __GFP_DMA32) &&
+ BUG_ON((mapping_gfp_mask(mapping) & __GFP_DMA32) &&
(page_to_pfn(p) >= 0x00100000UL));
}
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index 05c97c5350a1..e467e67af6e7 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -327,7 +327,7 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, size_t size,
/* Create a CMA GEM buffer. */
cma_obj = __drm_gem_cma_create(dev, size);
if (IS_ERR(cma_obj))
- return ERR_PTR(PTR_ERR(cma_obj));
+ return ERR_CAST(cma_obj);
cma_obj->paddr = sg_dma_address(sgt->sgl);
cma_obj->sgt = sgt;
diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c
index 7e4bae760e27..c3b80fd65d62 100644
--- a/drivers/gpu/drm/drm_hashtab.c
+++ b/drivers/gpu/drm/drm_hashtab.c
@@ -125,7 +125,7 @@ int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item)
parent = &entry->head;
}
if (parent) {
- hlist_add_after_rcu(parent, &item->head);
+ hlist_add_behind_rcu(&item->head, parent);
} else {
hlist_add_head_rcu(&item->head, h_list);
}
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 86feedd5e6f6..ecaf0fa2eec8 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -132,7 +132,7 @@ int drm_bufs_info(struct seq_file *m, void *data)
i,
dma->bufs[i].buf_size,
dma->bufs[i].buf_count,
- atomic_read(&dma->bufs[i].freelist.count),
+ 0,
dma->bufs[i].seg_count,
seg_pages,
seg_pages * PAGE_SIZE / 1024);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 69c61f392e66..40be746b7e68 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -1,11 +1,3 @@
-/**
- * \file drm_ioctl.c
- * IOCTL processing for DRM
- *
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- * \author Gareth Hughes <gareth@valinux.com>
- */
-
/*
* Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
*
@@ -13,6 +5,9 @@
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
+ * Author Rickard E. (Rik) Faith <faith@valinux.com>
+ * Author Gareth Hughes <gareth@valinux.com>
+ *
* 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
@@ -35,6 +30,7 @@
#include <drm/drmP.h>
#include <drm/drm_core.h>
+#include "drm_legacy.h"
#include <linux/pci.h>
#include <linux/export.h>
@@ -42,6 +38,124 @@
#include <asm/mtrr.h>
#endif
+static int drm_version(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+#define DRM_IOCTL_DEF(ioctl, _func, _flags) \
+ [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
+
+/** Ioctl table */
+static const struct drm_ioctl_desc drm_ioctls[] = {
+ DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+#if __OS_HAS_AGP
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+#endif
+
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_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_MODESET_CTL, drm_modeset_ctl, 0),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+};
+
+#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+
/**
* Get the bus id.
*
@@ -342,8 +456,6 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
file_priv->stereo_allowed = req->value;
break;
case DRM_CLIENT_CAP_UNIVERSAL_PLANES:
- if (!drm_universal_planes)
- return -EINVAL;
if (req->value > 1)
return -EINVAL;
file_priv->universal_planes = req->value;
@@ -417,3 +529,243 @@ int drm_noop(struct drm_device *dev, void *data,
return 0;
}
EXPORT_SYMBOL(drm_noop);
+
+/**
+ * Copy and IOCTL return string to user space
+ */
+static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
+{
+ int len;
+
+ /* don't overflow userbuf */
+ len = strlen(value);
+ if (len > *buf_len)
+ len = *buf_len;
+
+ /* let userspace know exact length of driver value (which could be
+ * larger than the userspace-supplied buffer) */
+ *buf_len = strlen(value);
+
+ /* finally, try filling in the userbuf */
+ if (len && buf)
+ if (copy_to_user(buf, value, len))
+ return -EFAULT;
+ return 0;
+}
+
+/**
+ * Get version information
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument, pointing to a drm_version structure.
+ * \return zero on success or negative number on failure.
+ *
+ * Fills in the version information in \p arg.
+ */
+static int drm_version(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_version *version = data;
+ int err;
+
+ version->version_major = dev->driver->major;
+ version->version_minor = dev->driver->minor;
+ version->version_patchlevel = dev->driver->patchlevel;
+ err = drm_copy_field(version->name, &version->name_len,
+ dev->driver->name);
+ if (!err)
+ err = drm_copy_field(version->date, &version->date_len,
+ dev->driver->date);
+ if (!err)
+ err = drm_copy_field(version->desc, &version->desc_len,
+ dev->driver->desc);
+
+ return err;
+}
+
+/**
+ * drm_ioctl_permit - Check ioctl permissions against caller
+ *
+ * @flags: ioctl permission flags.
+ * @file_priv: Pointer to struct drm_file identifying the caller.
+ *
+ * Checks whether the caller is allowed to run an ioctl with the
+ * indicated permissions. If so, returns zero. Otherwise returns an
+ * error code suitable for ioctl return.
+ */
+static int drm_ioctl_permit(u32 flags, struct drm_file *file_priv)
+{
+ /* ROOT_ONLY is only for CAP_SYS_ADMIN */
+ if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)))
+ return -EACCES;
+
+ /* AUTH is only for authenticated or render client */
+ if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) &&
+ !file_priv->authenticated))
+ return -EACCES;
+
+ /* MASTER is only for master or control clients */
+ if (unlikely((flags & DRM_MASTER) && !file_priv->is_master &&
+ !drm_is_control_client(file_priv)))
+ return -EACCES;
+
+ /* Control clients must be explicitly allowed */
+ if (unlikely(!(flags & DRM_CONTROL_ALLOW) &&
+ drm_is_control_client(file_priv)))
+ return -EACCES;
+
+ /* Render clients must be explicitly allowed */
+ if (unlikely(!(flags & DRM_RENDER_ALLOW) &&
+ drm_is_render_client(file_priv)))
+ return -EACCES;
+
+ return 0;
+}
+
+/**
+ * Called whenever a process performs an ioctl on /dev/drm.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ *
+ * Looks up the ioctl function in the ::ioctls table, checking for root
+ * previleges if so required, and dispatches to the respective function.
+ */
+long drm_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct drm_file *file_priv = filp->private_data;
+ struct drm_device *dev;
+ const struct drm_ioctl_desc *ioctl = NULL;
+ drm_ioctl_t *func;
+ unsigned int nr = DRM_IOCTL_NR(cmd);
+ int retcode = -EINVAL;
+ char stack_kdata[128];
+ char *kdata = NULL;
+ unsigned int usize, asize;
+
+ dev = file_priv->minor->dev;
+
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
+ if ((nr >= DRM_CORE_IOCTL_COUNT) &&
+ ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
+ goto err_i1;
+ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
+ (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
+ u32 drv_size;
+ ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+ drv_size = _IOC_SIZE(ioctl->cmd_drv);
+ usize = asize = _IOC_SIZE(cmd);
+ if (drv_size > asize)
+ asize = drv_size;
+ cmd = ioctl->cmd_drv;
+ }
+ else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
+ u32 drv_size;
+
+ ioctl = &drm_ioctls[nr];
+
+ drv_size = _IOC_SIZE(ioctl->cmd);
+ usize = asize = _IOC_SIZE(cmd);
+ if (drv_size > asize)
+ asize = drv_size;
+
+ cmd = ioctl->cmd;
+ } else
+ goto err_i1;
+
+ DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
+ task_pid_nr(current),
+ (long)old_encode_dev(file_priv->minor->kdev->devt),
+ file_priv->authenticated, ioctl->name);
+
+ /* Do not trust userspace, use our own definition */
+ func = ioctl->func;
+
+ if (unlikely(!func)) {
+ DRM_DEBUG("no function\n");
+ retcode = -EINVAL;
+ goto err_i1;
+ }
+
+ retcode = drm_ioctl_permit(ioctl->flags, file_priv);
+ if (unlikely(retcode))
+ goto err_i1;
+
+ if (cmd & (IOC_IN | IOC_OUT)) {
+ if (asize <= sizeof(stack_kdata)) {
+ kdata = stack_kdata;
+ } else {
+ kdata = kmalloc(asize, GFP_KERNEL);
+ if (!kdata) {
+ retcode = -ENOMEM;
+ goto err_i1;
+ }
+ }
+ if (asize > usize)
+ memset(kdata + usize, 0, asize - usize);
+ }
+
+ if (cmd & IOC_IN) {
+ if (copy_from_user(kdata, (void __user *)arg,
+ usize) != 0) {
+ retcode = -EFAULT;
+ goto err_i1;
+ }
+ } else if (cmd & IOC_OUT) {
+ memset(kdata, 0, usize);
+ }
+
+ if (ioctl->flags & DRM_UNLOCKED)
+ retcode = func(dev, kdata, file_priv);
+ else {
+ mutex_lock(&drm_global_mutex);
+ retcode = func(dev, kdata, file_priv);
+ mutex_unlock(&drm_global_mutex);
+ }
+
+ if (cmd & IOC_OUT) {
+ if (copy_to_user((void __user *)arg, kdata,
+ usize) != 0)
+ retcode = -EFAULT;
+ }
+
+ err_i1:
+ if (!ioctl)
+ DRM_DEBUG("invalid ioctl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n",
+ task_pid_nr(current),
+ (long)old_encode_dev(file_priv->minor->kdev->devt),
+ file_priv->authenticated, cmd, nr);
+
+ if (kdata != stack_kdata)
+ kfree(kdata);
+ if (retcode)
+ DRM_DEBUG("ret = %d\n", retcode);
+ return retcode;
+}
+EXPORT_SYMBOL(drm_ioctl);
+
+/**
+ * drm_ioctl_flags - Check for core ioctl and return ioctl permission flags
+ *
+ * @nr: Ioctl number.
+ * @flags: Where to return the ioctl permission flags
+ */
+bool drm_ioctl_flags(unsigned int nr, unsigned int *flags)
+{
+ if ((nr >= DRM_COMMAND_END && nr < DRM_CORE_IOCTL_COUNT) ||
+ (nr < DRM_COMMAND_BASE)) {
+ *flags = drm_ioctls[nr].flags;
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL(drm_ioctl_flags);
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 0de123afdb34..08ba1209228e 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -542,8 +542,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
const struct drm_crtc *refcrtc,
const struct drm_display_mode *mode)
{
- ktime_t stime, etime, mono_time_offset;
struct timeval tv_etime;
+ ktime_t stime, etime;
int vbl_status;
int vpos, hpos, i;
int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
@@ -588,13 +588,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos,
&hpos, &stime, &etime);
- /*
- * Get correction for CLOCK_MONOTONIC -> CLOCK_REALTIME if
- * CLOCK_REALTIME is requested.
- */
- if (!drm_timestamp_monotonic)
- mono_time_offset = ktime_get_monotonic_offset();
-
/* Return as no-op if scanout query unsupported or failed. */
if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n",
@@ -633,7 +626,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
delta_ns = vpos * linedur_ns + hpos * pixeldur_ns;
if (!drm_timestamp_monotonic)
- etime = ktime_sub(etime, mono_time_offset);
+ etime = ktime_mono_to_real(etime);
/* save this only for debugging purposes */
tv_etime = ktime_to_timeval(etime);
@@ -664,10 +657,7 @@ static struct timeval get_drm_timestamp(void)
{
ktime_t now;
- now = ktime_get();
- if (!drm_timestamp_monotonic)
- now = ktime_sub(now, ktime_get_monotonic_offset());
-
+ now = drm_timestamp_monotonic ? ktime_get() : ktime_get_real();
return ktime_to_timeval(now);
}
diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h
new file mode 100644
index 000000000000..d34f20a79b7c
--- /dev/null
+++ b/drivers/gpu/drm/drm_legacy.h
@@ -0,0 +1,51 @@
+#ifndef __DRM_LEGACY_H__
+#define __DRM_LEGACY_H__
+
+/*
+ * Copyright (c) 2014 David Herrmann <dh.herrmann@gmail.com>
+ *
+ * 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.
+ */
+
+struct drm_device;
+struct drm_file;
+
+/*
+ * Generic DRM Contexts
+ */
+
+#define DRM_KERNEL_CONTEXT 0
+#define DRM_RESERVED_CONTEXTS 1
+
+int drm_legacy_ctxbitmap_init(struct drm_device *dev);
+void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev);
+void drm_legacy_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
+void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file);
+
+int drm_legacy_resctx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_addctx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_getctx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_switchctx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_newctx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_rmctx(struct drm_device *d, void *v, struct drm_file *f);
+
+int drm_legacy_setsareactx(struct drm_device *d, void *v, struct drm_file *f);
+int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f);
+
+#endif /* __DRM_LEGACY_H__ */
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index f6452682141b..e26b59e385ff 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -35,6 +35,7 @@
#include <linux/export.h>
#include <drm/drmP.h>
+#include "drm_legacy.h"
static int drm_notifier(void *priv);
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index e633df2f68d8..6aa6a9e95570 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -201,16 +201,15 @@ EXPORT_SYMBOL(mipi_dsi_detach);
/**
* mipi_dsi_dcs_write - send DCS write command
* @dsi: DSI device
- * @channel: virtual channel
* @data: pointer to the command followed by parameters
* @len: length of @data
*/
-int mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, unsigned int channel,
- const void *data, size_t len)
+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data,
+ size_t len)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
struct mipi_dsi_msg msg = {
- .channel = channel,
+ .channel = dsi->channel,
.tx_buf = data,
.tx_len = len
};
@@ -239,19 +238,18 @@ EXPORT_SYMBOL(mipi_dsi_dcs_write);
/**
* mipi_dsi_dcs_read - send DCS read request command
* @dsi: DSI device
- * @channel: virtual channel
* @cmd: DCS read command
* @data: pointer to read buffer
* @len: length of @data
*
* Function returns number of read bytes or error code.
*/
-ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, unsigned int channel,
- u8 cmd, void *data, size_t len)
+ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
+ size_t len)
{
const struct mipi_dsi_host_ops *ops = dsi->host->ops;
struct mipi_dsi_msg msg = {
- .channel = channel,
+ .channel = dsi->channel,
.type = MIPI_DSI_DCS_READ,
.tx_buf = &cmd,
.tx_len = 1,
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
new file mode 100644
index 000000000000..16150a00c237
--- /dev/null
+++ b/drivers/gpu/drm/drm_of.c
@@ -0,0 +1,67 @@
+#include <linux/export.h>
+#include <linux/list.h>
+#include <linux/of_graph.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_of.h>
+
+/**
+ * drm_crtc_port_mask - find the mask of a registered CRTC by port OF node
+ * @dev: DRM device
+ * @port: port OF node
+ *
+ * Given a port OF node, return the possible mask of the corresponding
+ * CRTC within a device's list of CRTCs. Returns zero if not found.
+ */
+static uint32_t drm_crtc_port_mask(struct drm_device *dev,
+ struct device_node *port)
+{
+ unsigned int index = 0;
+ struct drm_crtc *tmp;
+
+ list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
+ if (tmp->port == port)
+ return 1 << index;
+
+ index++;
+ }
+
+ return 0;
+}
+
+/**
+ * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port
+ * @dev: DRM device
+ * @port: encoder port to scan for endpoints
+ *
+ * Scan all endpoints attached to a port, locate their attached CRTCs,
+ * and generate the DRM mask of CRTCs which may be attached to this
+ * encoder.
+ *
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ */
+uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
+ struct device_node *port)
+{
+ struct device_node *remote_port, *ep = NULL;
+ uint32_t possible_crtcs = 0;
+
+ do {
+ ep = of_graph_get_next_endpoint(port, ep);
+ if (!ep)
+ break;
+
+ remote_port = of_graph_get_remote_port(ep);
+ if (!remote_port) {
+ of_node_put(ep);
+ return 0;
+ }
+
+ possible_crtcs |= drm_crtc_port_mask(dev, remote_port);
+
+ of_node_put(remote_port);
+ } while (1);
+
+ return possible_crtcs;
+}
+EXPORT_SYMBOL(drm_of_find_possible_crtcs);
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 6d133149cc74..827ec1a3040b 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -335,9 +335,10 @@ struct drm_plane *drm_primary_helper_create_plane(struct drm_device *dev,
}
/* possible_crtc's will be filled in later by crtc_init */
- ret = drm_plane_init(dev, primary, 0, &drm_primary_helper_funcs,
- formats, num_formats,
- DRM_PLANE_TYPE_PRIMARY);
+ ret = drm_universal_plane_init(dev, primary, 0,
+ &drm_primary_helper_funcs,
+ formats, num_formats,
+ DRM_PLANE_TYPE_PRIMARY);
if (ret) {
kfree(primary);
primary = NULL;
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 304ca8cacbc4..99d578bad17e 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -336,7 +336,13 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
- return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags);
+ struct reservation_object *robj = NULL;
+
+ if (dev->driver->gem_prime_res_obj)
+ robj = dev->driver->gem_prime_res_obj(obj);
+
+ return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size,
+ flags, robj);
}
EXPORT_SYMBOL(drm_gem_prime_export);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index d22676b89cbb..db7d250f7ac7 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -130,7 +130,14 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
count = drm_load_edid_firmware(connector);
if (count == 0)
#endif
- count = (*connector_funcs->get_modes)(connector);
+ {
+ if (connector->override_edid) {
+ struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
+
+ count = drm_add_edid_modes(connector, edid);
+ } else
+ count = (*connector_funcs->get_modes)(connector);
+ }
if (count == 0 && connector->status == connector_status_connected)
count = drm_add_modes_noedid(connector, 1024, 768);
diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c
index 7047ca025787..631f5afd451c 100644
--- a/drivers/gpu/drm/drm_rect.c
+++ b/drivers/gpu/drm/drm_rect.c
@@ -293,3 +293,143 @@ void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
}
EXPORT_SYMBOL(drm_rect_debug_print);
+
+/**
+ * drm_rect_rotate - Rotate the rectangle
+ * @r: rectangle to be rotated
+ * @width: Width of the coordinate space
+ * @height: Height of the coordinate space
+ * @rotation: Transformation to be applied
+ *
+ * Apply @rotation to the coordinates of rectangle @r.
+ *
+ * @width and @height combined with @rotation define
+ * the location of the new origin.
+ *
+ * @width correcsponds to the horizontal and @height
+ * to the vertical axis of the untransformed coordinate
+ * space.
+ */
+void drm_rect_rotate(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation)
+{
+ struct drm_rect tmp;
+
+ if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
+ tmp = *r;
+
+ if (rotation & BIT(DRM_REFLECT_X)) {
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ }
+
+ if (rotation & BIT(DRM_REFLECT_Y)) {
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ }
+ }
+
+ switch (rotation & 0xf) {
+ case BIT(DRM_ROTATE_0):
+ break;
+ case BIT(DRM_ROTATE_90):
+ tmp = *r;
+ r->x1 = tmp.y1;
+ r->x2 = tmp.y2;
+ r->y1 = width - tmp.x2;
+ r->y2 = width - tmp.x1;
+ break;
+ case BIT(DRM_ROTATE_180):
+ tmp = *r;
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ break;
+ case BIT(DRM_ROTATE_270):
+ tmp = *r;
+ r->x1 = height - tmp.y2;
+ r->x2 = height - tmp.y1;
+ r->y1 = tmp.x1;
+ r->y2 = tmp.x2;
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(drm_rect_rotate);
+
+/**
+ * drm_rect_rotate_inv - Inverse rotate the rectangle
+ * @r: rectangle to be rotated
+ * @width: Width of the coordinate space
+ * @height: Height of the coordinate space
+ * @rotation: Transformation whose inverse is to be applied
+ *
+ * Apply the inverse of @rotation to the coordinates
+ * of rectangle @r.
+ *
+ * @width and @height combined with @rotation define
+ * the location of the new origin.
+ *
+ * @width correcsponds to the horizontal and @height
+ * to the vertical axis of the original untransformed
+ * coordinate space, so that you never have to flip
+ * them when doing a rotatation and its inverse.
+ * That is, if you do:
+ *
+ * drm_rotate(&r, width, height, rotation);
+ * drm_rotate_inv(&r, width, height, rotation);
+ *
+ * you will always get back the original rectangle.
+ */
+void drm_rect_rotate_inv(struct drm_rect *r,
+ int width, int height,
+ unsigned int rotation)
+{
+ struct drm_rect tmp;
+
+ switch (rotation & 0xf) {
+ case BIT(DRM_ROTATE_0):
+ break;
+ case BIT(DRM_ROTATE_90):
+ tmp = *r;
+ r->x1 = width - tmp.y2;
+ r->x2 = width - tmp.y1;
+ r->y1 = tmp.x1;
+ r->y2 = tmp.x2;
+ break;
+ case BIT(DRM_ROTATE_180):
+ tmp = *r;
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ break;
+ case BIT(DRM_ROTATE_270):
+ tmp = *r;
+ r->x1 = tmp.y1;
+ r->x2 = tmp.y2;
+ r->y1 = height - tmp.x2;
+ r->y2 = height - tmp.x1;
+ break;
+ default:
+ break;
+ }
+
+ if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
+ tmp = *r;
+
+ if (rotation & BIT(DRM_REFLECT_X)) {
+ r->x1 = width - tmp.x2;
+ r->x2 = width - tmp.x1;
+ }
+
+ if (rotation & BIT(DRM_REFLECT_Y)) {
+ r->y1 = height - tmp.y2;
+ r->y2 = height - tmp.y1;
+ }
+ }
+}
+EXPORT_SYMBOL(drm_rect_rotate_inv);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
deleted file mode 100644
index 14d16464000a..000000000000
--- a/drivers/gpu/drm/drm_stub.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
- *
- * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Author Rickard E. (Rik) Faith <faith@valinux.com>
- *
- * 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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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/fs.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <drm/drmP.h>
-#include <drm/drm_core.h>
-
-unsigned int drm_debug = 0; /* 1 to enable debug output */
-EXPORT_SYMBOL(drm_debug);
-
-unsigned int drm_rnodes = 0; /* 1 to enable experimental render nodes API */
-EXPORT_SYMBOL(drm_rnodes);
-
-/* 1 to allow user space to request universal planes (experimental) */
-unsigned int drm_universal_planes = 0;
-EXPORT_SYMBOL(drm_universal_planes);
-
-unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
-EXPORT_SYMBOL(drm_vblank_offdelay);
-
-unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
-EXPORT_SYMBOL(drm_timestamp_precision);
-
-/*
- * Default to use monotonic timestamps for wait-for-vblank and page-flip
- * complete events.
- */
-unsigned int drm_timestamp_monotonic = 1;
-
-MODULE_AUTHOR(CORE_AUTHOR);
-MODULE_DESCRIPTION(CORE_DESC);
-MODULE_LICENSE("GPL and additional rights");
-MODULE_PARM_DESC(debug, "Enable debug output");
-MODULE_PARM_DESC(rnodes, "Enable experimental render nodes API");
-MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]");
-MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
-MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
-
-module_param_named(debug, drm_debug, int, 0600);
-module_param_named(rnodes, drm_rnodes, int, 0600);
-module_param_named(universal_planes, drm_universal_planes, int, 0600);
-module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
-module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
-module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
-
-static DEFINE_SPINLOCK(drm_minor_lock);
-struct idr drm_minors_idr;
-
-struct class *drm_class;
-struct dentry *drm_debugfs_root;
-
-int drm_err(const char *func, const char *format, ...)
-{
- struct va_format vaf;
- va_list args;
- int r;
-
- va_start(args, format);
-
- vaf.fmt = format;
- vaf.va = &args;
-
- r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf);
-
- va_end(args);
-
- return r;
-}
-EXPORT_SYMBOL(drm_err);
-
-void drm_ut_debug_printk(const char *function_name, const char *format, ...)
-{
- struct va_format vaf;
- va_list args;
-
- va_start(args, format);
- vaf.fmt = format;
- vaf.va = &args;
-
- printk(KERN_DEBUG "[" DRM_NAME ":%s] %pV", function_name, &vaf);
-
- va_end(args);
-}
-EXPORT_SYMBOL(drm_ut_debug_printk);
-
-struct drm_master *drm_master_create(struct drm_minor *minor)
-{
- struct drm_master *master;
-
- master = kzalloc(sizeof(*master), GFP_KERNEL);
- if (!master)
- return NULL;
-
- kref_init(&master->refcount);
- spin_lock_init(&master->lock.spinlock);
- init_waitqueue_head(&master->lock.lock_queue);
- if (drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER)) {
- kfree(master);
- return NULL;
- }
- INIT_LIST_HEAD(&master->magicfree);
- master->minor = minor;
-
- return master;
-}
-
-struct drm_master *drm_master_get(struct drm_master *master)
-{
- kref_get(&master->refcount);
- return master;
-}
-EXPORT_SYMBOL(drm_master_get);
-
-static void drm_master_destroy(struct kref *kref)
-{
- struct drm_master *master = container_of(kref, struct drm_master, refcount);
- struct drm_magic_entry *pt, *next;
- struct drm_device *dev = master->minor->dev;
- struct drm_map_list *r_list, *list_temp;
-
- mutex_lock(&dev->struct_mutex);
- if (dev->driver->master_destroy)
- dev->driver->master_destroy(dev, master);
-
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
- if (r_list->master == master) {
- drm_rmmap_locked(dev, r_list->map);
- r_list = NULL;
- }
- }
-
- if (master->unique) {
- kfree(master->unique);
- master->unique = NULL;
- master->unique_len = 0;
- }
-
- list_for_each_entry_safe(pt, next, &master->magicfree, head) {
- list_del(&pt->head);
- drm_ht_remove_item(&master->magiclist, &pt->hash_item);
- kfree(pt);
- }
-
- drm_ht_remove(&master->magiclist);
-
- mutex_unlock(&dev->struct_mutex);
- kfree(master);
-}
-
-void drm_master_put(struct drm_master **master)
-{
- kref_put(&(*master)->refcount, drm_master_destroy);
- *master = NULL;
-}
-EXPORT_SYMBOL(drm_master_put);
-
-int drm_setmaster_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- int ret = 0;
-
- mutex_lock(&dev->master_mutex);
- if (file_priv->is_master)
- goto out_unlock;
-
- if (file_priv->minor->master) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- if (!file_priv->master) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- file_priv->minor->master = drm_master_get(file_priv->master);
- file_priv->is_master = 1;
- if (dev->driver->master_set) {
- ret = dev->driver->master_set(dev, file_priv, false);
- if (unlikely(ret != 0)) {
- file_priv->is_master = 0;
- drm_master_put(&file_priv->minor->master);
- }
- }
-
-out_unlock:
- mutex_unlock(&dev->master_mutex);
- return ret;
-}
-
-int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- int ret = -EINVAL;
-
- mutex_lock(&dev->master_mutex);
- if (!file_priv->is_master)
- goto out_unlock;
-
- if (!file_priv->minor->master)
- goto out_unlock;
-
- ret = 0;
- if (dev->driver->master_drop)
- dev->driver->master_drop(dev, file_priv, false);
- drm_master_put(&file_priv->minor->master);
- file_priv->is_master = 0;
-
-out_unlock:
- mutex_unlock(&dev->master_mutex);
- return ret;
-}
-
-/*
- * DRM Minors
- * A DRM device can provide several char-dev interfaces on the DRM-Major. Each
- * of them is represented by a drm_minor object. Depending on the capabilities
- * of the device-driver, different interfaces are registered.
- *
- * Minors can be accessed via dev->$minor_name. This pointer is either
- * NULL or a valid drm_minor pointer and stays valid as long as the device is
- * valid. This means, DRM minors have the same life-time as the underlying
- * device. However, this doesn't mean that the minor is active. Minors are
- * registered and unregistered dynamically according to device-state.
- */
-
-static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
- unsigned int type)
-{
- switch (type) {
- case DRM_MINOR_LEGACY:
- return &dev->primary;
- case DRM_MINOR_RENDER:
- return &dev->render;
- case DRM_MINOR_CONTROL:
- return &dev->control;
- default:
- return NULL;
- }
-}
-
-static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
-{
- struct drm_minor *minor;
-
- minor = kzalloc(sizeof(*minor), GFP_KERNEL);
- if (!minor)
- return -ENOMEM;
-
- minor->type = type;
- minor->dev = dev;
-
- *drm_minor_get_slot(dev, type) = minor;
- return 0;
-}
-
-static void drm_minor_free(struct drm_device *dev, unsigned int type)
-{
- struct drm_minor **slot;
-
- slot = drm_minor_get_slot(dev, type);
- if (*slot) {
- drm_mode_group_destroy(&(*slot)->mode_group);
- kfree(*slot);
- *slot = NULL;
- }
-}
-
-static int drm_minor_register(struct drm_device *dev, unsigned int type)
-{
- struct drm_minor *new_minor;
- unsigned long flags;
- int ret;
- int minor_id;
-
- DRM_DEBUG("\n");
-
- new_minor = *drm_minor_get_slot(dev, type);
- if (!new_minor)
- return 0;
-
- idr_preload(GFP_KERNEL);
- spin_lock_irqsave(&drm_minor_lock, flags);
- minor_id = idr_alloc(&drm_minors_idr,
- NULL,
- 64 * type,
- 64 * (type + 1),
- GFP_NOWAIT);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
- idr_preload_end();
-
- if (minor_id < 0)
- return minor_id;
-
- new_minor->index = minor_id;
-
- ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root);
- if (ret) {
- DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
- goto err_id;
- }
-
- ret = drm_sysfs_device_add(new_minor);
- if (ret) {
- DRM_ERROR("DRM: Error sysfs_device_add.\n");
- goto err_debugfs;
- }
-
- /* replace NULL with @minor so lookups will succeed from now on */
- spin_lock_irqsave(&drm_minor_lock, flags);
- idr_replace(&drm_minors_idr, new_minor, new_minor->index);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
-
- DRM_DEBUG("new minor assigned %d\n", minor_id);
- return 0;
-
-err_debugfs:
- drm_debugfs_cleanup(new_minor);
-err_id:
- spin_lock_irqsave(&drm_minor_lock, flags);
- idr_remove(&drm_minors_idr, minor_id);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
- new_minor->index = 0;
- return ret;
-}
-
-static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
-{
- struct drm_minor *minor;
- unsigned long flags;
-
- minor = *drm_minor_get_slot(dev, type);
- if (!minor || !minor->kdev)
- return;
-
- spin_lock_irqsave(&drm_minor_lock, flags);
- idr_remove(&drm_minors_idr, minor->index);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
- minor->index = 0;
-
- drm_debugfs_cleanup(minor);
- drm_sysfs_device_remove(minor);
-}
-
-/**
- * drm_minor_acquire - Acquire a DRM minor
- * @minor_id: Minor ID of the DRM-minor
- *
- * Looks up the given minor-ID and returns the respective DRM-minor object. The
- * refence-count of the underlying device is increased so you must release this
- * object with drm_minor_release().
- *
- * As long as you hold this minor, it is guaranteed that the object and the
- * minor->dev pointer will stay valid! However, the device may get unplugged and
- * unregistered while you hold the minor.
- *
- * Returns:
- * Pointer to minor-object with increased device-refcount, or PTR_ERR on
- * failure.
- */
-struct drm_minor *drm_minor_acquire(unsigned int minor_id)
-{
- struct drm_minor *minor;
- unsigned long flags;
-
- spin_lock_irqsave(&drm_minor_lock, flags);
- minor = idr_find(&drm_minors_idr, minor_id);
- if (minor)
- drm_dev_ref(minor->dev);
- spin_unlock_irqrestore(&drm_minor_lock, flags);
-
- if (!minor) {
- return ERR_PTR(-ENODEV);
- } else if (drm_device_is_unplugged(minor->dev)) {
- drm_dev_unref(minor->dev);
- return ERR_PTR(-ENODEV);
- }
-
- return minor;
-}
-
-/**
- * drm_minor_release - Release DRM minor
- * @minor: Pointer to DRM minor object
- *
- * Release a minor that was previously acquired via drm_minor_acquire().
- */
-void drm_minor_release(struct drm_minor *minor)
-{
- drm_dev_unref(minor->dev);
-}
-
-/**
- * drm_put_dev - Unregister and release a DRM device
- * @dev: DRM device
- *
- * Called at module unload time or when a PCI device is unplugged.
- *
- * Use of this function is discouraged. It will eventually go away completely.
- * Please use drm_dev_unregister() and drm_dev_unref() explicitly instead.
- *
- * Cleans up all DRM device, calling drm_lastclose().
- */
-void drm_put_dev(struct drm_device *dev)
-{
- DRM_DEBUG("\n");
-
- if (!dev) {
- DRM_ERROR("cleanup called no dev\n");
- return;
- }
-
- drm_dev_unregister(dev);
- drm_dev_unref(dev);
-}
-EXPORT_SYMBOL(drm_put_dev);
-
-void drm_unplug_dev(struct drm_device *dev)
-{
- /* for a USB device */
- drm_minor_unregister(dev, DRM_MINOR_LEGACY);
- drm_minor_unregister(dev, DRM_MINOR_RENDER);
- drm_minor_unregister(dev, DRM_MINOR_CONTROL);
-
- mutex_lock(&drm_global_mutex);
-
- drm_device_set_unplugged(dev);
-
- if (dev->open_count == 0) {
- drm_put_dev(dev);
- }
- mutex_unlock(&drm_global_mutex);
-}
-EXPORT_SYMBOL(drm_unplug_dev);
-
-/*
- * DRM internal mount
- * We want to be able to allocate our own "struct address_space" to control
- * memory-mappings in VRAM (or stolen RAM, ...). However, core MM does not allow
- * stand-alone address_space objects, so we need an underlying inode. As there
- * is no way to allocate an independent inode easily, we need a fake internal
- * VFS mount-point.
- *
- * The drm_fs_inode_new() function allocates a new inode, drm_fs_inode_free()
- * frees it again. You are allowed to use iget() and iput() to get references to
- * the inode. But each drm_fs_inode_new() call must be paired with exactly one
- * drm_fs_inode_free() call (which does not have to be the last iput()).
- * We use drm_fs_inode_*() to manage our internal VFS mount-point and share it
- * between multiple inode-users. You could, technically, call
- * iget() + drm_fs_inode_free() directly after alloc and sometime later do an
- * iput(), but this way you'd end up with a new vfsmount for each inode.
- */
-
-static int drm_fs_cnt;
-static struct vfsmount *drm_fs_mnt;
-
-static const struct dentry_operations drm_fs_dops = {
- .d_dname = simple_dname,
-};
-
-static const struct super_operations drm_fs_sops = {
- .statfs = simple_statfs,
-};
-
-static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data)
-{
- return mount_pseudo(fs_type,
- "drm:",
- &drm_fs_sops,
- &drm_fs_dops,
- 0x010203ff);
-}
-
-static struct file_system_type drm_fs_type = {
- .name = "drm",
- .owner = THIS_MODULE,
- .mount = drm_fs_mount,
- .kill_sb = kill_anon_super,
-};
-
-static struct inode *drm_fs_inode_new(void)
-{
- struct inode *inode;
- int r;
-
- r = simple_pin_fs(&drm_fs_type, &drm_fs_mnt, &drm_fs_cnt);
- if (r < 0) {
- DRM_ERROR("Cannot mount pseudo fs: %d\n", r);
- return ERR_PTR(r);
- }
-
- inode = alloc_anon_inode(drm_fs_mnt->mnt_sb);
- if (IS_ERR(inode))
- simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
-
- return inode;
-}
-
-static void drm_fs_inode_free(struct inode *inode)
-{
- if (inode) {
- iput(inode);
- simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
- }
-}
-
-/**
- * drm_dev_alloc - Allocate new DRM device
- * @driver: DRM driver to allocate device for
- * @parent: Parent device object
- *
- * Allocate and initialize a new DRM device. No device registration is done.
- * Call drm_dev_register() to advertice the device to user space and register it
- * with other core subsystems.
- *
- * The initial ref-count of the object is 1. Use drm_dev_ref() and
- * drm_dev_unref() to take and drop further ref-counts.
- *
- * RETURNS:
- * Pointer to new DRM device, or NULL if out of memory.
- */
-struct drm_device *drm_dev_alloc(struct drm_driver *driver,
- struct device *parent)
-{
- struct drm_device *dev;
- int ret;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return NULL;
-
- kref_init(&dev->ref);
- dev->dev = parent;
- dev->driver = driver;
-
- INIT_LIST_HEAD(&dev->filelist);
- INIT_LIST_HEAD(&dev->ctxlist);
- INIT_LIST_HEAD(&dev->vmalist);
- INIT_LIST_HEAD(&dev->maplist);
- INIT_LIST_HEAD(&dev->vblank_event_list);
-
- spin_lock_init(&dev->buf_lock);
- spin_lock_init(&dev->event_lock);
- mutex_init(&dev->struct_mutex);
- mutex_init(&dev->ctxlist_mutex);
- mutex_init(&dev->master_mutex);
-
- dev->anon_inode = drm_fs_inode_new();
- if (IS_ERR(dev->anon_inode)) {
- ret = PTR_ERR(dev->anon_inode);
- DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
- goto err_free;
- }
-
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
- if (ret)
- goto err_minors;
- }
-
- if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
- ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
- if (ret)
- goto err_minors;
- }
-
- ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
- if (ret)
- goto err_minors;
-
- if (drm_ht_create(&dev->map_hash, 12))
- goto err_minors;
-
- ret = drm_ctxbitmap_init(dev);
- if (ret) {
- DRM_ERROR("Cannot allocate memory for context bitmap.\n");
- goto err_ht;
- }
-
- if (driver->driver_features & DRIVER_GEM) {
- ret = drm_gem_init(dev);
- if (ret) {
- DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
- goto err_ctxbitmap;
- }
- }
-
- return dev;
-
-err_ctxbitmap:
- drm_ctxbitmap_cleanup(dev);
-err_ht:
- drm_ht_remove(&dev->map_hash);
-err_minors:
- drm_minor_free(dev, DRM_MINOR_LEGACY);
- drm_minor_free(dev, DRM_MINOR_RENDER);
- drm_minor_free(dev, DRM_MINOR_CONTROL);
- drm_fs_inode_free(dev->anon_inode);
-err_free:
- mutex_destroy(&dev->master_mutex);
- kfree(dev);
- return NULL;
-}
-EXPORT_SYMBOL(drm_dev_alloc);
-
-static void drm_dev_release(struct kref *ref)
-{
- struct drm_device *dev = container_of(ref, struct drm_device, ref);
-
- if (dev->driver->driver_features & DRIVER_GEM)
- drm_gem_destroy(dev);
-
- drm_ctxbitmap_cleanup(dev);
- drm_ht_remove(&dev->map_hash);
- drm_fs_inode_free(dev->anon_inode);
-
- drm_minor_free(dev, DRM_MINOR_LEGACY);
- drm_minor_free(dev, DRM_MINOR_RENDER);
- drm_minor_free(dev, DRM_MINOR_CONTROL);
-
- mutex_destroy(&dev->master_mutex);
- kfree(dev->unique);
- kfree(dev);
-}
-
-/**
- * drm_dev_ref - Take reference of a DRM device
- * @dev: device to take reference of or NULL
- *
- * This increases the ref-count of @dev by one. You *must* already own a
- * reference when calling this. Use drm_dev_unref() to drop this reference
- * again.
- *
- * This function never fails. However, this function does not provide *any*
- * guarantee whether the device is alive or running. It only provides a
- * reference to the object and the memory associated with it.
- */
-void drm_dev_ref(struct drm_device *dev)
-{
- if (dev)
- kref_get(&dev->ref);
-}
-EXPORT_SYMBOL(drm_dev_ref);
-
-/**
- * drm_dev_unref - Drop reference of a DRM device
- * @dev: device to drop reference of or NULL
- *
- * This decreases the ref-count of @dev by one. The device is destroyed if the
- * ref-count drops to zero.
- */
-void drm_dev_unref(struct drm_device *dev)
-{
- if (dev)
- kref_put(&dev->ref, drm_dev_release);
-}
-EXPORT_SYMBOL(drm_dev_unref);
-
-/**
- * drm_dev_register - Register DRM device
- * @dev: Device to register
- * @flags: Flags passed to the driver's .load() function
- *
- * Register the DRM device @dev with the system, advertise device to user-space
- * and start normal device operation. @dev must be allocated via drm_dev_alloc()
- * previously.
- *
- * Never call this twice on any device!
- *
- * RETURNS:
- * 0 on success, negative error code on failure.
- */
-int drm_dev_register(struct drm_device *dev, unsigned long flags)
-{
- int ret;
-
- mutex_lock(&drm_global_mutex);
-
- ret = drm_minor_register(dev, DRM_MINOR_CONTROL);
- if (ret)
- goto err_minors;
-
- ret = drm_minor_register(dev, DRM_MINOR_RENDER);
- if (ret)
- goto err_minors;
-
- ret = drm_minor_register(dev, DRM_MINOR_LEGACY);
- if (ret)
- goto err_minors;
-
- if (dev->driver->load) {
- ret = dev->driver->load(dev, flags);
- if (ret)
- goto err_minors;
- }
-
- /* setup grouping for legacy outputs */
- if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- ret = drm_mode_group_init_legacy_group(dev,
- &dev->primary->mode_group);
- if (ret)
- goto err_unload;
- }
-
- ret = 0;
- goto out_unlock;
-
-err_unload:
- if (dev->driver->unload)
- dev->driver->unload(dev);
-err_minors:
- drm_minor_unregister(dev, DRM_MINOR_LEGACY);
- drm_minor_unregister(dev, DRM_MINOR_RENDER);
- drm_minor_unregister(dev, DRM_MINOR_CONTROL);
-out_unlock:
- mutex_unlock(&drm_global_mutex);
- return ret;
-}
-EXPORT_SYMBOL(drm_dev_register);
-
-/**
- * drm_dev_unregister - Unregister DRM device
- * @dev: Device to unregister
- *
- * Unregister the DRM device from the system. This does the reverse of
- * drm_dev_register() but does not deallocate the device. The caller must call
- * drm_dev_unref() to drop their final reference.
- */
-void drm_dev_unregister(struct drm_device *dev)
-{
- struct drm_map_list *r_list, *list_temp;
-
- drm_lastclose(dev);
-
- if (dev->driver->unload)
- dev->driver->unload(dev);
-
- if (dev->agp)
- drm_pci_agp_destroy(dev);
-
- drm_vblank_cleanup(dev);
-
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
- drm_rmmap(dev, r_list->map);
-
- drm_minor_unregister(dev, DRM_MINOR_LEGACY);
- drm_minor_unregister(dev, DRM_MINOR_RENDER);
- drm_minor_unregister(dev, DRM_MINOR_CONTROL);
-}
-EXPORT_SYMBOL(drm_dev_unregister);
-
-/**
- * drm_dev_set_unique - Set the unique name of a DRM device
- * @dev: device of which to set the unique name
- * @fmt: format string for unique name
- *
- * Sets the unique name of a DRM device using the specified format string and
- * a variable list of arguments. Drivers can use this at driver probe time if
- * the unique name of the devices they drive is static.
- *
- * Return: 0 on success or a negative error code on failure.
- */
-int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...)
-{
- va_list ap;
-
- kfree(dev->unique);
-
- va_start(ap, fmt);
- dev->unique = kvasprintf(GFP_KERNEL, fmt, ap);
- va_end(ap);
-
- return dev->unique ? 0 : -ENOMEM;
-}
-EXPORT_SYMBOL(drm_dev_set_unique);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 369b26278e76..ab1a5f6dde8a 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -438,7 +438,6 @@ err_out_files:
out:
return ret;
}
-EXPORT_SYMBOL(drm_sysfs_connector_add);
/**
* drm_sysfs_connector_remove - remove an connector device from sysfs
@@ -468,7 +467,6 @@ void drm_sysfs_connector_remove(struct drm_connector *connector)
device_unregister(connector->kdev);
connector->kdev = NULL;
}
-EXPORT_SYMBOL(drm_sysfs_connector_remove);
/**
* drm_sysfs_hotplug_event - generate a DRM uevent
@@ -495,71 +493,55 @@ static void drm_sysfs_release(struct device *dev)
}
/**
- * drm_sysfs_device_add - adds a class device to sysfs for a character driver
- * @dev: DRM device to be added
- * @head: DRM head in question
+ * drm_sysfs_minor_alloc() - Allocate sysfs device for given minor
+ * @minor: minor to allocate sysfs device for
*
- * Add a DRM device to the DRM's device model class. We use @dev's PCI device
- * as the parent for the Linux device, and make sure it has a file containing
- * the driver we're using (for userspace compatibility).
+ * This allocates a new sysfs device for @minor and returns it. The device is
+ * not registered nor linked. The caller has to use device_add() and
+ * device_del() to register and unregister it.
+ *
+ * Note that dev_get_drvdata() on the new device will return the minor.
+ * However, the device does not hold a ref-count to the minor nor to the
+ * underlying drm_device. This is unproblematic as long as you access the
+ * private data only in sysfs callbacks. device_del() disables those
+ * synchronously, so they cannot be called after you cleanup a minor.
*/
-int drm_sysfs_device_add(struct drm_minor *minor)
+struct device *drm_sysfs_minor_alloc(struct drm_minor *minor)
{
- char *minor_str;
+ const char *minor_str;
+ struct device *kdev;
int r;
if (minor->type == DRM_MINOR_CONTROL)
minor_str = "controlD%d";
- else if (minor->type == DRM_MINOR_RENDER)
- minor_str = "renderD%d";
- else
- minor_str = "card%d";
-
- minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL);
- if (!minor->kdev) {
- r = -ENOMEM;
- goto error;
- }
-
- device_initialize(minor->kdev);
- minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index);
- minor->kdev->class = drm_class;
- minor->kdev->type = &drm_sysfs_device_minor;
- minor->kdev->parent = minor->dev->dev;
- minor->kdev->release = drm_sysfs_release;
- dev_set_drvdata(minor->kdev, minor);
-
- r = dev_set_name(minor->kdev, minor_str, minor->index);
+ else if (minor->type == DRM_MINOR_RENDER)
+ minor_str = "renderD%d";
+ else
+ minor_str = "card%d";
+
+ kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
+ if (!kdev)
+ return ERR_PTR(-ENOMEM);
+
+ device_initialize(kdev);
+ kdev->devt = MKDEV(DRM_MAJOR, minor->index);
+ kdev->class = drm_class;
+ kdev->type = &drm_sysfs_device_minor;
+ kdev->parent = minor->dev->dev;
+ kdev->release = drm_sysfs_release;
+ dev_set_drvdata(kdev, minor);
+
+ r = dev_set_name(kdev, minor_str, minor->index);
if (r < 0)
- goto error;
-
- r = device_add(minor->kdev);
- if (r < 0)
- goto error;
-
- return 0;
+ goto err_free;
-error:
- DRM_ERROR("device create failed %d\n", r);
- put_device(minor->kdev);
- return r;
-}
+ return kdev;
-/**
- * drm_sysfs_device_remove - remove DRM device
- * @dev: DRM device to remove
- *
- * This call unregisters and cleans up a class device that was created with a
- * call to drm_sysfs_device_add()
- */
-void drm_sysfs_device_remove(struct drm_minor *minor)
-{
- if (minor->kdev)
- device_unregister(minor->kdev);
- minor->kdev = NULL;
+err_free:
+ put_device(kdev);
+ return ERR_PTR(r);
}
-
/**
* drm_class_device_register - Register a struct device in the drm class.
*
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 178d2a9672a8..7f9f6f9e9b7e 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -28,6 +28,7 @@ config DRM_EXYNOS_FIMD
bool "Exynos DRM FIMD"
depends on DRM_EXYNOS && !FB_S3C
select FB_MODE_HELPERS
+ select MFD_SYSCON
help
Choose this option if you want to use Exynos FIMD for DRM.
@@ -52,6 +53,7 @@ config DRM_EXYNOS_DP
bool "EXYNOS DRM DP driver support"
depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
default DRM_EXYNOS
+ select DRM_PANEL
help
This enables support for DP device.
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index a8ffc8c1477b..4f3c7eb2d37d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -16,7 +16,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/interrupt.h>
-#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
@@ -28,6 +27,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
#include <drm/bridge/ptn3460.h>
#include "exynos_drm_drv.h"
@@ -41,7 +41,7 @@ struct bridge_init {
struct device_node *node;
};
-static int exynos_dp_init_dp(struct exynos_dp_device *dp)
+static void exynos_dp_init_dp(struct exynos_dp_device *dp)
{
exynos_dp_reset(dp);
@@ -58,8 +58,6 @@ static int exynos_dp_init_dp(struct exynos_dp_device *dp)
exynos_dp_init_hpd(dp);
exynos_dp_init_aux(dp);
-
- return 0;
}
static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
@@ -875,10 +873,24 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
static void exynos_dp_hotplug(struct work_struct *work)
{
struct exynos_dp_device *dp;
- int ret;
dp = container_of(work, struct exynos_dp_device, hotplug_work);
+ if (dp->drm_dev)
+ drm_helper_hpd_irq_event(dp->drm_dev);
+}
+
+static void exynos_dp_commit(struct exynos_drm_display *display)
+{
+ struct exynos_dp_device *dp = display->ctx;
+ int ret;
+
+ /* Keep the panel disabled while we configure video */
+ if (dp->panel) {
+ if (drm_panel_disable(dp->panel))
+ DRM_ERROR("failed to disable the panel\n");
+ }
+
ret = exynos_dp_detect_hpd(dp);
if (ret) {
/* Cable has been disconnected, we're done */
@@ -909,6 +921,12 @@ static void exynos_dp_hotplug(struct work_struct *work)
ret = exynos_dp_config_video(dp);
if (ret)
dev_err(dp->dev, "unable to config video\n");
+
+ /* Safe to enable the panel now */
+ if (dp->panel) {
+ if (drm_panel_enable(dp->panel))
+ DRM_ERROR("failed to enable the panel\n");
+ }
}
static enum drm_connector_status exynos_dp_detect(
@@ -933,15 +951,18 @@ static int exynos_dp_get_modes(struct drm_connector *connector)
struct exynos_dp_device *dp = ctx_from_connector(connector);
struct drm_display_mode *mode;
+ if (dp->panel)
+ return drm_panel_get_modes(dp->panel);
+
mode = drm_mode_create(connector->dev);
if (!mode) {
DRM_ERROR("failed to create a new display mode.\n");
return 0;
}
- drm_display_mode_from_videomode(&dp->panel.vm, mode);
- mode->width_mm = dp->panel.width_mm;
- mode->height_mm = dp->panel.height_mm;
+ drm_display_mode_from_videomode(&dp->priv.vm, mode);
+ mode->width_mm = dp->priv.width_mm;
+ mode->height_mm = dp->priv.height_mm;
connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm;
@@ -1018,10 +1039,13 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
}
drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
- return 0;
+ if (dp->panel)
+ ret = drm_panel_attach(dp->panel, &dp->connector);
+
+ return ret;
}
static void exynos_dp_phy_init(struct exynos_dp_device *dp)
@@ -1050,26 +1074,50 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
}
}
-static void exynos_dp_poweron(struct exynos_dp_device *dp)
+static void exynos_dp_poweron(struct exynos_drm_display *display)
{
+ struct exynos_dp_device *dp = display->ctx;
+
if (dp->dpms_mode == DRM_MODE_DPMS_ON)
return;
+ if (dp->panel) {
+ if (drm_panel_prepare(dp->panel)) {
+ DRM_ERROR("failed to setup the panel\n");
+ return;
+ }
+ }
+
clk_prepare_enable(dp->clock);
exynos_dp_phy_init(dp);
exynos_dp_init_dp(dp);
enable_irq(dp->irq);
+ exynos_dp_commit(display);
}
-static void exynos_dp_poweroff(struct exynos_dp_device *dp)
+static void exynos_dp_poweroff(struct exynos_drm_display *display)
{
+ struct exynos_dp_device *dp = display->ctx;
+
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
return;
+ if (dp->panel) {
+ if (drm_panel_disable(dp->panel)) {
+ DRM_ERROR("failed to disable the panel\n");
+ return;
+ }
+ }
+
disable_irq(dp->irq);
flush_work(&dp->hotplug_work);
exynos_dp_phy_exit(dp);
clk_disable_unprepare(dp->clock);
+
+ if (dp->panel) {
+ if (drm_panel_unprepare(dp->panel))
+ DRM_ERROR("failed to turnoff the panel\n");
+ }
}
static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
@@ -1078,12 +1126,12 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
- exynos_dp_poweron(dp);
+ exynos_dp_poweron(display);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- exynos_dp_poweroff(dp);
+ exynos_dp_poweroff(display);
break;
default:
break;
@@ -1094,6 +1142,7 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
static struct exynos_drm_display_ops exynos_dp_display_ops = {
.create_connector = exynos_dp_create_connector,
.dpms = exynos_dp_dpms,
+ .commit = exynos_dp_commit,
};
static struct exynos_drm_display exynos_dp_display = {
@@ -1201,7 +1250,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
{
int ret;
- ret = of_get_videomode(dp->dev->of_node, &dp->panel.vm,
+ ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
OF_USE_NATIVE_MODE);
if (ret) {
DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
@@ -1215,16 +1264,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm_dev = data;
struct resource *res;
- struct exynos_dp_device *dp;
+ struct exynos_dp_device *dp = exynos_dp_display.ctx;
unsigned int irq_flags;
-
int ret = 0;
- dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
- GFP_KERNEL);
- if (!dp)
- return -ENOMEM;
-
dp->dev = &pdev->dev;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1236,9 +1279,11 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
if (ret)
return ret;
- ret = exynos_dp_dt_parse_panel(dp);
- if (ret)
- return ret;
+ if (!dp->panel) {
+ ret = exynos_dp_dt_parse_panel(dp);
+ if (ret)
+ return ret;
+ }
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
@@ -1298,7 +1343,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
disable_irq(dp->irq);
dp->drm_dev = drm_dev;
- exynos_dp_display.ctx = dp;
platform_set_drvdata(pdev, &exynos_dp_display);
@@ -1325,6 +1369,9 @@ static const struct component_ops exynos_dp_ops = {
static int exynos_dp_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct device_node *panel_node;
+ struct exynos_dp_device *dp;
int ret;
ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
@@ -1332,6 +1379,21 @@ static int exynos_dp_probe(struct platform_device *pdev)
if (ret)
return ret;
+ dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
+ GFP_KERNEL);
+ if (!dp)
+ return -ENOMEM;
+
+ panel_node = of_parse_phandle(dev->of_node, "panel", 0);
+ if (panel_node) {
+ dp->panel = of_drm_find_panel(panel_node);
+ of_node_put(panel_node);
+ if (!dp->panel)
+ return -EPROBE_DEFER;
+ }
+
+ exynos_dp_display.ctx = dp;
+
ret = component_add(&pdev->dev, &exynos_dp_ops);
if (ret)
exynos_drm_component_del(&pdev->dev,
@@ -1376,6 +1438,7 @@ static const struct of_device_id exynos_dp_match[] = {
{ .compatible = "samsung,exynos5-dp" },
{},
};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
struct platform_driver dp_driver = {
.probe = exynos_dp_probe,
@@ -1390,4 +1453,4 @@ struct platform_driver dp_driver = {
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
MODULE_DESCRIPTION("Samsung SoC DP Driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 02cc4f9ab903..a1aee6931bd7 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -149,6 +149,7 @@ struct exynos_dp_device {
struct drm_device *drm_dev;
struct drm_connector connector;
struct drm_encoder *encoder;
+ struct drm_panel *panel;
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
@@ -162,7 +163,7 @@ struct exynos_dp_device {
int dpms_mode;
int hpd_gpio;
- struct exynos_drm_panel_info panel;
+ struct exynos_drm_panel_info priv;
};
/* exynos_dp_reg.c */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 9a16dbe121d1..ba9b3d5ed672 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -117,20 +117,7 @@ static struct drm_encoder *exynos_drm_best_encoder(
struct drm_device *dev = connector->dev;
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
- obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
- DRM_MODE_OBJECT_ENCODER);
- if (!obj) {
- DRM_DEBUG_KMS("Unknown ENCODER ID %d\n",
- exynos_connector->encoder_id);
- return NULL;
- }
-
- encoder = obj_to_encoder(obj);
-
- return encoder;
+ return drm_encoder_find(dev, exynos_connector->encoder_id);
}
static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
@@ -185,7 +172,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(exynos_connector);
}
@@ -230,7 +217,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
drm_connector_init(dev, connector, &exynos_connector_funcs, type);
drm_connector_helper_add(connector, &exynos_connector_helper_funcs);
- err = drm_sysfs_connector_add(connector);
+ err = drm_connector_register(connector);
if (err)
goto err_connector;
@@ -250,7 +237,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
return connector;
err_sysfs:
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
err_connector:
drm_connector_cleanup(connector);
kfree(exynos_connector);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 95c9435d0266..b68e58f78cd1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -69,8 +69,10 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
if (mode > DRM_MODE_DPMS_ON) {
/* wait for the completion of page flip. */
- wait_event(exynos_crtc->pending_flip_queue,
- atomic_read(&exynos_crtc->pending_flip) == 0);
+ if (!wait_event_timeout(exynos_crtc->pending_flip_queue,
+ !atomic_read(&exynos_crtc->pending_flip),
+ HZ/20))
+ atomic_set(&exynos_crtc->pending_flip, 0);
drm_vblank_off(crtc->dev, exynos_crtc->pipe);
}
@@ -259,6 +261,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
spin_lock_irq(&dev->event_lock);
drm_vblank_put(dev, exynos_crtc->pipe);
list_del(&event->base.link);
+ atomic_set(&exynos_crtc->pending_flip, 0);
spin_unlock_irq(&dev->event_lock);
goto out;
@@ -508,3 +511,11 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
return -EPERM;
}
+
+void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
+{
+ struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
+
+ if (manager->ops->te_handler)
+ manager->ops->te_handler(manager);
+}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index 9f74b10a8a01..690dcddab725 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -36,4 +36,11 @@ void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
unsigned int out_type);
+/*
+ * This function calls the crtc device(manager)'s te_handler() callback
+ * to trigger to transfer video image at the tearing effect synchronization
+ * signal.
+ */
+void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
+
#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 2a3ad24276f8..60192ed544f0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -187,7 +187,7 @@ struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
return dma_buf_export(obj, &exynos_dmabuf_ops,
- exynos_gem_obj->base.size, flags);
+ exynos_gem_obj->base.size, flags, NULL);
}
struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 9e530f205ad2..fa08f05e3e34 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -48,7 +48,7 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
static void exynos_dpi_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -117,7 +117,7 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
}
drm_connector_helper_add(connector, &exynos_dpi_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
return 0;
@@ -125,14 +125,18 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
static void exynos_dpi_poweron(struct exynos_dpi *ctx)
{
- if (ctx->panel)
+ if (ctx->panel) {
+ drm_panel_prepare(ctx->panel);
drm_panel_enable(ctx->panel);
+ }
}
static void exynos_dpi_poweroff(struct exynos_dpi *ctx)
{
- if (ctx->panel)
+ if (ctx->panel) {
drm_panel_disable(ctx->panel);
+ drm_panel_unprepare(ctx->panel);
+ }
}
static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index ab7d182063c3..0d74e9b99c4e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -39,8 +39,6 @@
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
-#define VBLANK_OFF_DELAY 50000
-
static struct platform_device *exynos_drm_pdev;
static DEFINE_MUTEX(drm_component_lock);
@@ -103,8 +101,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
/* setup possible_clones. */
exynos_drm_encoder_setup(dev);
- drm_vblank_offdelay = VBLANK_OFF_DELAY;
-
platform_set_drvdata(dev->platformdev, dev);
/* Try to bind all sub drivers. */
@@ -362,7 +358,7 @@ static int exynos_drm_sys_suspend(struct device *dev)
struct drm_device *drm_dev = dev_get_drvdata(dev);
pm_message_t message;
- if (pm_runtime_suspended(dev))
+ if (pm_runtime_suspended(dev) || !drm_dev)
return 0;
message.event = PM_EVENT_SUSPEND;
@@ -373,7 +369,7 @@ static int exynos_drm_sys_resume(struct device *dev)
{
struct drm_device *drm_dev = dev_get_drvdata(dev);
- if (pm_runtime_suspended(dev))
+ if (pm_runtime_suspended(dev) || !drm_dev)
return 0;
return exynos_drm_resume(drm_dev);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 06cde4506278..69a6fa397d75 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -40,8 +40,6 @@ struct drm_device;
struct exynos_drm_overlay;
struct drm_connector;
-extern unsigned int drm_vblank_offdelay;
-
/* This enumerates device type. */
enum exynos_drm_device_type {
EXYNOS_DEVICE_TYPE_NONE,
@@ -188,6 +186,8 @@ struct exynos_drm_display {
* @win_commit: apply hardware specific overlay data to registers.
* @win_enable: enable hardware specific overlay.
* @win_disable: disable hardware specific overlay.
+ * @te_handler: trigger to transfer video image at the tearing effect
+ * synchronization signal if there is a page flip request.
*/
struct exynos_drm_manager;
struct exynos_drm_manager_ops {
@@ -206,6 +206,7 @@ struct exynos_drm_manager_ops {
void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
+ void (*te_handler)(struct exynos_drm_manager *mgr);
};
/*
@@ -236,14 +237,9 @@ struct exynos_drm_g2d_private {
struct list_head userptr_list;
};
-struct exynos_drm_ipp_private {
- struct device *dev;
- struct list_head event_list;
-};
-
struct drm_exynos_file_private {
struct exynos_drm_g2d_private *g2d_priv;
- struct exynos_drm_ipp_private *ipp_priv;
+ struct device *ipp_dev;
struct file *anon_filp;
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 6302aa64f6c1..442aa2d00132 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -16,7 +16,10 @@
#include <drm/drm_panel.h>
#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
#include <linux/irq.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/phy/phy.h>
#include <linux/regulator/consumer.h>
#include <linux/component.h>
@@ -24,6 +27,7 @@
#include <video/mipi_display.h>
#include <video/videomode.h>
+#include "exynos_drm_crtc.h"
#include "exynos_drm_drv.h"
/* returns true iff both arguments logically differs */
@@ -54,9 +58,12 @@
/* FIFO memory AC characteristic register */
#define DSIM_PLLCTRL_REG 0x4c /* PLL control register */
-#define DSIM_PLLTMR_REG 0x50 /* PLL timer register */
#define DSIM_PHYACCHR_REG 0x54 /* D-PHY AC characteristic register */
#define DSIM_PHYACCHR1_REG 0x58 /* D-PHY AC characteristic register1 */
+#define DSIM_PHYCTRL_REG 0x5c
+#define DSIM_PHYTIMING_REG 0x64
+#define DSIM_PHYTIMING1_REG 0x68
+#define DSIM_PHYTIMING2_REG 0x6c
/* DSIM_STATUS */
#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
@@ -200,6 +207,24 @@
#define DSIM_PLL_M(x) ((x) << 4)
#define DSIM_PLL_S(x) ((x) << 1)
+/* DSIM_PHYCTRL */
+#define DSIM_PHYCTRL_ULPS_EXIT(x) (((x) & 0x1ff) << 0)
+
+/* DSIM_PHYTIMING */
+#define DSIM_PHYTIMING_LPX(x) ((x) << 8)
+#define DSIM_PHYTIMING_HS_EXIT(x) ((x) << 0)
+
+/* DSIM_PHYTIMING1 */
+#define DSIM_PHYTIMING1_CLK_PREPARE(x) ((x) << 24)
+#define DSIM_PHYTIMING1_CLK_ZERO(x) ((x) << 16)
+#define DSIM_PHYTIMING1_CLK_POST(x) ((x) << 8)
+#define DSIM_PHYTIMING1_CLK_TRAIL(x) ((x) << 0)
+
+/* DSIM_PHYTIMING2 */
+#define DSIM_PHYTIMING2_HS_PREPARE(x) ((x) << 16)
+#define DSIM_PHYTIMING2_HS_ZERO(x) ((x) << 8)
+#define DSIM_PHYTIMING2_HS_TRAIL(x) ((x) << 0)
+
#define DSI_MAX_BUS_WIDTH 4
#define DSI_NUM_VIRTUAL_CHANNELS 4
#define DSI_TX_FIFO_SIZE 2048
@@ -233,6 +258,12 @@ struct exynos_dsi_transfer {
#define DSIM_STATE_INITIALIZED BIT(1)
#define DSIM_STATE_CMD_LPM BIT(2)
+struct exynos_dsi_driver_data {
+ unsigned int plltmr_reg;
+
+ unsigned int has_freqband:1;
+};
+
struct exynos_dsi {
struct mipi_dsi_host dsi_host;
struct drm_connector connector;
@@ -247,6 +278,7 @@ struct exynos_dsi {
struct clk *bus_clk;
struct regulator_bulk_data supplies[2];
int irq;
+ int te_gpio;
u32 pll_clk_rate;
u32 burst_clk_rate;
@@ -262,11 +294,39 @@ struct exynos_dsi {
spinlock_t transfer_lock; /* protects transfer_list */
struct list_head transfer_list;
+
+ struct exynos_dsi_driver_data *driver_data;
};
#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
+static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
+ .plltmr_reg = 0x50,
+ .has_freqband = 1,
+};
+
+static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
+ .plltmr_reg = 0x58,
+};
+
+static struct of_device_id exynos_dsi_of_match[] = {
+ { .compatible = "samsung,exynos4210-mipi-dsi",
+ .data = &exynos4_dsi_driver_data },
+ { .compatible = "samsung,exynos5410-mipi-dsi",
+ .data = &exynos5_dsi_driver_data },
+ { }
+};
+
+static inline struct exynos_dsi_driver_data *exynos_dsi_get_driver_data(
+ struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(exynos_dsi_of_match, &pdev->dev);
+
+ return (struct exynos_dsi_driver_data *)of_id->data;
+}
+
static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
{
if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))
@@ -340,14 +400,9 @@ static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
unsigned long freq)
{
- static const unsigned long freq_bands[] = {
- 100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
- 270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
- 510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
- 770 * MHZ, 870 * MHZ, 950 * MHZ,
- };
+ struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
unsigned long fin, fout;
- int timeout, band;
+ int timeout;
u8 p, s;
u16 m;
u32 reg;
@@ -368,18 +423,30 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
"failed to find PLL PMS for requested frequency\n");
return -EFAULT;
}
+ dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);
- for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
- if (fout < freq_bands[band])
- break;
+ writel(500, dsi->reg_base + driver_data->plltmr_reg);
+
+ reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
- dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d), band %d\n", fout,
- p, m, s, band);
+ if (driver_data->has_freqband) {
+ static const unsigned long freq_bands[] = {
+ 100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,
+ 270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,
+ 510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,
+ 770 * MHZ, 870 * MHZ, 950 * MHZ,
+ };
+ int band;
- writel(500, dsi->reg_base + DSIM_PLLTMR_REG);
+ for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)
+ if (fout < freq_bands[band])
+ break;
+
+ dev_dbg(dsi->dev, "band %d\n", band);
+
+ reg |= DSIM_FREQ_BAND(band);
+ }
- reg = DSIM_FREQ_BAND(band) | DSIM_PLL_EN
- | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
writel(reg, dsi->reg_base + DSIM_PLLCTRL_REG);
timeout = 1000;
@@ -433,6 +500,59 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
return 0;
}
+static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
+{
+ struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
+ u32 reg;
+
+ if (driver_data->has_freqband)
+ return;
+
+ /* B D-PHY: D-PHY Master & Slave Analog Block control */
+ reg = DSIM_PHYCTRL_ULPS_EXIT(0x0af);
+ writel(reg, dsi->reg_base + DSIM_PHYCTRL_REG);
+
+ /*
+ * T LPX: Transmitted length of any Low-Power state period
+ * T HS-EXIT: Time that the transmitter drives LP-11 following a HS
+ * burst
+ */
+ reg = DSIM_PHYTIMING_LPX(0x06) | DSIM_PHYTIMING_HS_EXIT(0x0b);
+ writel(reg, dsi->reg_base + DSIM_PHYTIMING_REG);
+
+ /*
+ * T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
+ * Line state immediately before the HS-0 Line state starting the
+ * HS transmission
+ * T CLK-ZERO: Time that the transmitter drives the HS-0 state prior to
+ * transmitting the Clock.
+ * T CLK_POST: Time that the transmitter continues to send HS clock
+ * after the last associated Data Lane has transitioned to LP Mode
+ * Interval is defined as the period from the end of T HS-TRAIL to
+ * the beginning of T CLK-TRAIL
+ * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after
+ * the last payload clock bit of a HS transmission burst
+ */
+ reg = DSIM_PHYTIMING1_CLK_PREPARE(0x07) |
+ DSIM_PHYTIMING1_CLK_ZERO(0x27) |
+ DSIM_PHYTIMING1_CLK_POST(0x0d) |
+ DSIM_PHYTIMING1_CLK_TRAIL(0x08);
+ writel(reg, dsi->reg_base + DSIM_PHYTIMING1_REG);
+
+ /*
+ * T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
+ * Line state immediately before the HS-0 Line state starting the
+ * HS transmission
+ * T HS-ZERO: Time that the transmitter drives the HS-0 state prior to
+ * transmitting the Sync sequence.
+ * T HS-TRAIL: Time that the transmitter drives the flipped differential
+ * state after last payload data bit of a HS transmission burst
+ */
+ reg = DSIM_PHYTIMING2_HS_PREPARE(0x09) | DSIM_PHYTIMING2_HS_ZERO(0x0d) |
+ DSIM_PHYTIMING2_HS_TRAIL(0x0b);
+ writel(reg, dsi->reg_base + DSIM_PHYTIMING2_REG);
+}
+
static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
{
u32 reg;
@@ -468,13 +588,20 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
/* DSI configuration */
reg = 0;
+ /*
+ * The first bit of mode_flags specifies display configuration.
+ * If this bit is set[= MIPI_DSI_MODE_VIDEO], dsi will support video
+ * mode, otherwise it will support command mode.
+ */
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
reg |= DSIM_VIDEO_MODE;
+ /*
+ * The user manual describes that following bits are ignored in
+ * command mode.
+ */
if (!(dsi->mode_flags & MIPI_DSI_MODE_VSYNC_FLUSH))
reg |= DSIM_MFLUSH_VS;
- if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
- reg |= DSIM_EOT_DISABLE;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
reg |= DSIM_SYNC_INFORM;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
@@ -491,6 +618,9 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
reg |= DSIM_HSA_MODE;
}
+ if (!(dsi->mode_flags & MIPI_DSI_MODE_EOT_PACKET))
+ reg |= DSIM_EOT_DISABLE;
+
switch (dsi->format) {
case MIPI_DSI_FMT_RGB888:
reg |= DSIM_MAIN_PIX_FORMAT_RGB888;
@@ -944,17 +1074,90 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
+{
+ struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
+ struct drm_encoder *encoder = dsi->encoder;
+
+ if (dsi->state & DSIM_STATE_ENABLED)
+ exynos_drm_crtc_te_handler(encoder->crtc);
+
+ return IRQ_HANDLED;
+}
+
+static void exynos_dsi_enable_irq(struct exynos_dsi *dsi)
+{
+ enable_irq(dsi->irq);
+
+ if (gpio_is_valid(dsi->te_gpio))
+ enable_irq(gpio_to_irq(dsi->te_gpio));
+}
+
+static void exynos_dsi_disable_irq(struct exynos_dsi *dsi)
+{
+ if (gpio_is_valid(dsi->te_gpio))
+ disable_irq(gpio_to_irq(dsi->te_gpio));
+
+ disable_irq(dsi->irq);
+}
+
static int exynos_dsi_init(struct exynos_dsi *dsi)
{
- exynos_dsi_enable_clock(dsi);
exynos_dsi_reset(dsi);
- enable_irq(dsi->irq);
+ exynos_dsi_enable_irq(dsi);
+ exynos_dsi_enable_clock(dsi);
exynos_dsi_wait_for_reset(dsi);
+ exynos_dsi_set_phy_ctrl(dsi);
exynos_dsi_init_link(dsi);
return 0;
}
+static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
+{
+ int ret;
+
+ dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
+ if (!gpio_is_valid(dsi->te_gpio)) {
+ dev_err(dsi->dev, "no te-gpios specified\n");
+ ret = dsi->te_gpio;
+ goto out;
+ }
+
+ ret = gpio_request_one(dsi->te_gpio, GPIOF_IN, "te_gpio");
+ if (ret) {
+ dev_err(dsi->dev, "gpio request failed with %d\n", ret);
+ goto out;
+ }
+
+ /*
+ * This TE GPIO IRQ should not be set to IRQ_NOAUTOEN, because panel
+ * calls drm_panel_init() first then calls mipi_dsi_attach() in probe().
+ * It means that te_gpio is invalid when exynos_dsi_enable_irq() is
+ * called by drm_panel_init() before panel is attached.
+ */
+ ret = request_threaded_irq(gpio_to_irq(dsi->te_gpio),
+ exynos_dsi_te_irq_handler, NULL,
+ IRQF_TRIGGER_RISING, "TE", dsi);
+ if (ret) {
+ dev_err(dsi->dev, "request interrupt failed with %d\n", ret);
+ gpio_free(dsi->te_gpio);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void exynos_dsi_unregister_te_irq(struct exynos_dsi *dsi)
+{
+ if (gpio_is_valid(dsi->te_gpio)) {
+ free_irq(gpio_to_irq(dsi->te_gpio), dsi);
+ gpio_free(dsi->te_gpio);
+ dsi->te_gpio = -ENOENT;
+ }
+}
+
static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
struct mipi_dsi_device *device)
{
@@ -968,6 +1171,19 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
if (dsi->connector.dev)
drm_helper_hpd_irq_event(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 (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) {
+ int ret = exynos_dsi_register_te_irq(dsi);
+
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -976,6 +1192,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
{
struct exynos_dsi *dsi = host_to_dsi(host);
+ exynos_dsi_unregister_te_irq(dsi);
+
dsi->panel_node = NULL;
if (dsi->connector.dev)
@@ -1089,7 +1307,7 @@ static void exynos_dsi_poweroff(struct exynos_dsi *dsi)
exynos_dsi_disable_clock(dsi);
- disable_irq(dsi->irq);
+ exynos_dsi_disable_irq(dsi);
}
dsi->state &= ~DSIM_STATE_CMD_LPM;
@@ -1115,7 +1333,7 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
if (ret < 0)
return ret;
- ret = drm_panel_enable(dsi->panel);
+ ret = drm_panel_prepare(dsi->panel);
if (ret < 0) {
exynos_dsi_poweroff(dsi);
return ret;
@@ -1124,6 +1342,14 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi)
exynos_dsi_set_display_mode(dsi);
exynos_dsi_set_display_enable(dsi, true);
+ ret = drm_panel_enable(dsi->panel);
+ if (ret < 0) {
+ exynos_dsi_set_display_enable(dsi, false);
+ drm_panel_unprepare(dsi->panel);
+ exynos_dsi_poweroff(dsi);
+ return ret;
+ }
+
dsi->state |= DSIM_STATE_ENABLED;
return 0;
@@ -1134,8 +1360,9 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi)
if (!(dsi->state & DSIM_STATE_ENABLED))
return;
- exynos_dsi_set_display_enable(dsi, false);
drm_panel_disable(dsi->panel);
+ exynos_dsi_set_display_enable(dsi, false);
+ drm_panel_unprepare(dsi->panel);
exynos_dsi_poweroff(dsi);
dsi->state &= ~DSIM_STATE_ENABLED;
@@ -1246,7 +1473,7 @@ static int exynos_dsi_create_connector(struct exynos_drm_display *display,
}
drm_connector_helper_add(connector, &exynos_dsi_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
return 0;
@@ -1278,6 +1505,7 @@ static struct exynos_drm_display exynos_dsi_display = {
.type = EXYNOS_DISPLAY_TYPE_LCD,
.ops = &exynos_dsi_display_ops,
};
+MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
/* of_* functions will be removed after merge of of_graph patches */
static struct device_node *
@@ -1435,6 +1663,9 @@ static int exynos_dsi_probe(struct platform_device *pdev)
goto err_del_component;
}
+ /* To be checked as invalid one */
+ dsi->te_gpio = -ENOENT;
+
init_completion(&dsi->completed);
spin_lock_init(&dsi->transfer_lock);
INIT_LIST_HEAD(&dsi->transfer_list);
@@ -1443,6 +1674,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
dsi->dsi_host.dev = &pdev->dev;
dsi->dev = &pdev->dev;
+ dsi->driver_data = exynos_dsi_get_driver_data(pdev);
ret = exynos_dsi_parse_dt(dsi);
if (ret)
@@ -1525,11 +1757,6 @@ static int exynos_dsi_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id exynos_dsi_of_match[] = {
- { .compatible = "samsung,exynos4210-mipi-dsi" },
- { }
-};
-
struct platform_driver dsi_driver = {
.probe = exynos_dsi_probe,
.remove = exynos_dsi_remove,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d771b467cf0c..32e63f60e1d1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -225,7 +225,7 @@ out:
return ret;
}
-static struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
.fb_probe = exynos_drm_fbdev_create,
};
@@ -266,7 +266,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
return -ENOMEM;
private->fb_helper = helper = &fbdev->drm_fb_helper;
- helper->funcs = &exynos_drm_fb_helper_funcs;
+
+ drm_fb_helper_prepare(dev, helper, &exynos_drm_fb_helper_funcs);
num_crtc = dev->mode_config.num_crtc;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 831dde9034c6..ec7cc9ea50df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -1887,6 +1887,7 @@ static const struct of_device_id fimc_of_match[] = {
{ .compatible = "samsung,exynos4212-fimc" },
{ },
};
+MODULE_DEVICE_TABLE(of, fimc_of_match);
struct platform_driver fimc_driver = {
.probe = fimc_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 33161ad38201..5d09e33fef87 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -20,6 +20,8 @@
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h>
@@ -61,6 +63,24 @@
/* color key value register for hardware window 1 ~ 4. */
#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8))
+/* I80 / RGB trigger control register */
+#define TRIGCON 0x1A4
+#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0)
+#define SWTRGCMD_I80_RGB_ENABLE (1 << 1)
+
+/* display mode change control register except exynos4 */
+#define VIDOUT_CON 0x000
+#define VIDOUT_CON_F_I80_LDI0 (0x2 << 8)
+
+/* I80 interface control for main LDI register */
+#define I80IFCONFAx(x) (0x1B0 + (x) * 4)
+#define I80IFCONFBx(x) (0x1B8 + (x) * 4)
+#define LCD_CS_SETUP(x) ((x) << 16)
+#define LCD_WR_SETUP(x) ((x) << 12)
+#define LCD_WR_ACTIVE(x) ((x) << 8)
+#define LCD_WR_HOLD(x) ((x) << 4)
+#define I80IFEN_ENABLE (1 << 0)
+
/* FIMD has totally five hardware windows. */
#define WINDOWS_NR 5
@@ -68,10 +88,14 @@
struct fimd_driver_data {
unsigned int timing_base;
+ unsigned int lcdblk_offset;
+ unsigned int lcdblk_vt_shift;
+ unsigned int lcdblk_bypass_shift;
unsigned int has_shadowcon:1;
unsigned int has_clksel:1;
unsigned int has_limited_fmt:1;
+ unsigned int has_vidoutcon:1;
};
static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -82,12 +106,19 @@ static struct fimd_driver_data s3c64xx_fimd_driver_data = {
static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
+ .lcdblk_offset = 0x210,
+ .lcdblk_vt_shift = 10,
+ .lcdblk_bypass_shift = 1,
.has_shadowcon = 1,
};
static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x20000,
+ .lcdblk_offset = 0x214,
+ .lcdblk_vt_shift = 24,
+ .lcdblk_bypass_shift = 15,
.has_shadowcon = 1,
+ .has_vidoutcon = 1,
};
struct fimd_win_data {
@@ -112,15 +143,22 @@ struct fimd_context {
struct clk *bus_clk;
struct clk *lcd_clk;
void __iomem *regs;
+ struct regmap *sysreg;
struct drm_display_mode mode;
struct fimd_win_data win_data[WINDOWS_NR];
unsigned int default_win;
unsigned long irq_flags;
+ u32 vidcon0;
u32 vidcon1;
+ u32 vidout_con;
+ u32 i80ifcon;
+ bool i80_if;
bool suspended;
int pipe;
wait_queue_head_t wait_vsync_queue;
atomic_t wait_vsync_event;
+ atomic_t win_updated;
+ atomic_t triggering;
struct exynos_drm_panel_info panel;
struct fimd_driver_data *driver_data;
@@ -136,6 +174,7 @@ static const struct of_device_id fimd_driver_dt_match[] = {
.data = &exynos5_fimd_driver_data },
{},
};
+MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
static inline struct fimd_driver_data *drm_fimd_get_driver_data(
struct platform_device *pdev)
@@ -243,6 +282,14 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
u32 clkdiv;
+ if (ctx->i80_if) {
+ /*
+ * The frame done interrupt should be occurred prior to the
+ * next TE signal.
+ */
+ ideal_clk *= 2;
+ }
+
/* Find the clock divider value that gets us closest to ideal_clk */
clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->lcd_clk), ideal_clk);
@@ -271,11 +318,10 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
{
struct fimd_context *ctx = mgr->ctx;
struct drm_display_mode *mode = &ctx->mode;
- struct fimd_driver_data *driver_data;
- u32 val, clkdiv, vidcon1;
- int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
+ struct fimd_driver_data *driver_data = ctx->driver_data;
+ void *timing_base = ctx->regs + driver_data->timing_base;
+ u32 val, clkdiv;
- driver_data = ctx->driver_data;
if (ctx->suspended)
return;
@@ -283,33 +329,65 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
if (mode->htotal == 0 || mode->vtotal == 0)
return;
- /* setup polarity values */
- vidcon1 = ctx->vidcon1;
- if (mode->flags & DRM_MODE_FLAG_NVSYNC)
- vidcon1 |= VIDCON1_INV_VSYNC;
- if (mode->flags & DRM_MODE_FLAG_NHSYNC)
- vidcon1 |= VIDCON1_INV_HSYNC;
- writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
-
- /* setup vertical timing values. */
- vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
- vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
- vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
-
- val = VIDTCON0_VBPD(vbpd - 1) |
- VIDTCON0_VFPD(vfpd - 1) |
- VIDTCON0_VSPW(vsync_len - 1);
- writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
-
- /* setup horizontal timing values. */
- hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
- hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
- hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
-
- val = VIDTCON1_HBPD(hbpd - 1) |
- VIDTCON1_HFPD(hfpd - 1) |
- VIDTCON1_HSPW(hsync_len - 1);
- writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
+ if (ctx->i80_if) {
+ val = ctx->i80ifcon | I80IFEN_ENABLE;
+ writel(val, timing_base + I80IFCONFAx(0));
+
+ /* disable auto frame rate */
+ writel(0, timing_base + I80IFCONFBx(0));
+
+ /* set video type selection to I80 interface */
+ if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
+ driver_data->lcdblk_offset,
+ 0x3 << driver_data->lcdblk_vt_shift,
+ 0x1 << driver_data->lcdblk_vt_shift)) {
+ DRM_ERROR("Failed to update sysreg for I80 i/f.\n");
+ return;
+ }
+ } else {
+ int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
+ u32 vidcon1;
+
+ /* setup polarity values */
+ vidcon1 = ctx->vidcon1;
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ vidcon1 |= VIDCON1_INV_VSYNC;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ vidcon1 |= VIDCON1_INV_HSYNC;
+ writel(vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
+
+ /* setup vertical timing values. */
+ vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
+ vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
+ vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
+
+ val = VIDTCON0_VBPD(vbpd - 1) |
+ VIDTCON0_VFPD(vfpd - 1) |
+ VIDTCON0_VSPW(vsync_len - 1);
+ writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
+
+ /* setup horizontal timing values. */
+ hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
+ hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
+ hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
+
+ val = VIDTCON1_HBPD(hbpd - 1) |
+ VIDTCON1_HFPD(hfpd - 1) |
+ VIDTCON1_HSPW(hsync_len - 1);
+ writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
+ }
+
+ if (driver_data->has_vidoutcon)
+ writel(ctx->vidout_con, timing_base + VIDOUT_CON);
+
+ /* set bypass selection */
+ if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
+ driver_data->lcdblk_offset,
+ 0x1 << driver_data->lcdblk_bypass_shift,
+ 0x1 << driver_data->lcdblk_bypass_shift)) {
+ DRM_ERROR("Failed to update sysreg for bypass setting.\n");
+ return;
+ }
/* setup horizontal and vertical display size. */
val = VIDTCON2_LINEVAL(mode->vdisplay - 1) |
@@ -322,7 +400,8 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
* fields of register with prefix '_F' would be updated
* at vsync(same as dma start)
*/
- val = VIDCON0_ENVID | VIDCON0_ENVID_F;
+ val = ctx->vidcon0;
+ val |= VIDCON0_ENVID | VIDCON0_ENVID_F;
if (ctx->driver_data->has_clksel)
val |= VIDCON0_CLKSEL_LCD;
@@ -660,6 +739,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
}
win_data->enabled = true;
+
+ if (ctx->i80_if)
+ atomic_set(&ctx->win_updated, 1);
}
static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
@@ -838,6 +920,58 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
}
}
+static void fimd_trigger(struct device *dev)
+{
+ struct exynos_drm_manager *mgr = get_fimd_manager(dev);
+ struct fimd_context *ctx = mgr->ctx;
+ struct fimd_driver_data *driver_data = ctx->driver_data;
+ void *timing_base = ctx->regs + driver_data->timing_base;
+ u32 reg;
+
+ atomic_set(&ctx->triggering, 1);
+
+ reg = readl(ctx->regs + VIDINTCON0);
+ reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |
+ VIDINTCON0_INT_SYSMAINCON);
+ writel(reg, ctx->regs + VIDINTCON0);
+
+ reg = readl(timing_base + TRIGCON);
+ reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
+ writel(reg, timing_base + TRIGCON);
+}
+
+static void fimd_te_handler(struct exynos_drm_manager *mgr)
+{
+ struct fimd_context *ctx = mgr->ctx;
+
+ /* Checks the crtc is detached already from encoder */
+ if (ctx->pipe < 0 || !ctx->drm_dev)
+ return;
+
+ /*
+ * Skips to trigger if in triggering state, because multiple triggering
+ * requests can cause panel reset.
+ */
+ if (atomic_read(&ctx->triggering))
+ return;
+
+ /*
+ * If there is a page flip request, triggers and handles the page flip
+ * event so that current fb can be updated into panel GRAM.
+ */
+ if (atomic_add_unless(&ctx->win_updated, -1, 0))
+ fimd_trigger(ctx->dev);
+
+ /* Wakes up vsync event queue */
+ if (atomic_read(&ctx->wait_vsync_event)) {
+ atomic_set(&ctx->wait_vsync_event, 0);
+ wake_up(&ctx->wait_vsync_queue);
+
+ if (!atomic_read(&ctx->triggering))
+ drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+ }
+}
+
static struct exynos_drm_manager_ops fimd_manager_ops = {
.dpms = fimd_dpms,
.mode_fixup = fimd_mode_fixup,
@@ -849,6 +983,7 @@ static struct exynos_drm_manager_ops fimd_manager_ops = {
.win_mode_set = fimd_win_mode_set,
.win_commit = fimd_win_commit,
.win_disable = fimd_win_disable,
+ .te_handler = fimd_te_handler,
};
static struct exynos_drm_manager fimd_manager = {
@@ -859,26 +994,40 @@ static struct exynos_drm_manager fimd_manager = {
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
{
struct fimd_context *ctx = (struct fimd_context *)dev_id;
- u32 val;
+ u32 val, clear_bit;
val = readl(ctx->regs + VIDINTCON1);
- if (val & VIDINTCON1_INT_FRAME)
- /* VSYNC interrupt */
- writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1);
+ clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
+ if (val & clear_bit)
+ writel(clear_bit, ctx->regs + VIDINTCON1);
/* check the crtc is detached already from encoder */
if (ctx->pipe < 0 || !ctx->drm_dev)
goto out;
- drm_handle_vblank(ctx->drm_dev, ctx->pipe);
- exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+ if (ctx->i80_if) {
+ /* unset I80 frame done interrupt */
+ val = readl(ctx->regs + VIDINTCON0);
+ val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
+ writel(val, ctx->regs + VIDINTCON0);
- /* set wait vsync event to zero and wake up queue. */
- if (atomic_read(&ctx->wait_vsync_event)) {
- atomic_set(&ctx->wait_vsync_event, 0);
- wake_up(&ctx->wait_vsync_queue);
+ /* exit triggering mode */
+ atomic_set(&ctx->triggering, 0);
+
+ drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+ exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+ } else {
+ drm_handle_vblank(ctx->drm_dev, ctx->pipe);
+ exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
+
+ /* set wait vsync event to zero and wake up queue. */
+ if (atomic_read(&ctx->wait_vsync_event)) {
+ atomic_set(&ctx->wait_vsync_event, 0);
+ wake_up(&ctx->wait_vsync_queue);
+ }
}
+
out:
return IRQ_HANDLED;
}
@@ -923,6 +1072,7 @@ static int fimd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct fimd_context *ctx;
+ struct device_node *i80_if_timings;
struct resource *res;
int ret = -EINVAL;
@@ -944,12 +1094,51 @@ static int fimd_probe(struct platform_device *pdev)
ctx->dev = dev;
ctx->suspended = true;
+ ctx->driver_data = drm_fimd_get_driver_data(pdev);
if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
ctx->vidcon1 |= VIDCON1_INV_VDEN;
if (of_property_read_bool(dev->of_node, "samsung,invert-vclk"))
ctx->vidcon1 |= VIDCON1_INV_VCLK;
+ i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings");
+ if (i80_if_timings) {
+ u32 val;
+
+ ctx->i80_if = true;
+
+ if (ctx->driver_data->has_vidoutcon)
+ ctx->vidout_con |= VIDOUT_CON_F_I80_LDI0;
+ else
+ ctx->vidcon0 |= VIDCON0_VIDOUT_I80_LDI0;
+ /*
+ * The user manual describes that this "DSI_EN" bit is required
+ * to enable I80 24-bit data interface.
+ */
+ ctx->vidcon0 |= VIDCON0_DSI_EN;
+
+ if (of_property_read_u32(i80_if_timings, "cs-setup", &val))
+ val = 0;
+ ctx->i80ifcon = LCD_CS_SETUP(val);
+ if (of_property_read_u32(i80_if_timings, "wr-setup", &val))
+ val = 0;
+ ctx->i80ifcon |= LCD_WR_SETUP(val);
+ if (of_property_read_u32(i80_if_timings, "wr-active", &val))
+ val = 1;
+ ctx->i80ifcon |= LCD_WR_ACTIVE(val);
+ if (of_property_read_u32(i80_if_timings, "wr-hold", &val))
+ val = 0;
+ ctx->i80ifcon |= LCD_WR_HOLD(val);
+ }
+ of_node_put(i80_if_timings);
+
+ ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "samsung,sysreg");
+ if (IS_ERR(ctx->sysreg)) {
+ dev_warn(dev, "failed to get system register.\n");
+ ctx->sysreg = NULL;
+ }
+
ctx->bus_clk = devm_clk_get(dev, "fimd");
if (IS_ERR(ctx->bus_clk)) {
dev_err(dev, "failed to get bus clock\n");
@@ -972,7 +1161,8 @@ static int fimd_probe(struct platform_device *pdev)
goto err_del_component;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+ ctx->i80_if ? "lcd_sys" : "vsync");
if (!res) {
dev_err(dev, "irq request failed.\n");
ret = -ENXIO;
@@ -986,7 +1176,6 @@ static int fimd_probe(struct platform_device *pdev)
goto err_del_component;
}
- ctx->driver_data = drm_fimd_get_driver_data(pdev);
init_waitqueue_head(&ctx->wait_vsync_queue);
atomic_set(&ctx->wait_vsync_event, 0);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index 800158714473..df7a77d3eff8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1042,8 +1042,23 @@ err:
int exynos_g2d_get_ver_ioctl(struct drm_device *drm_dev, void *data,
struct drm_file *file)
{
+ struct drm_exynos_file_private *file_priv = file->driver_priv;
+ struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
+ struct device *dev;
+ struct g2d_data *g2d;
struct drm_exynos_g2d_get_ver *ver = data;
+ if (!g2d_priv)
+ return -ENODEV;
+
+ dev = g2d_priv->dev;
+ if (!dev)
+ return -ENODEV;
+
+ g2d = dev_get_drvdata(dev);
+ if (!g2d)
+ return -EFAULT;
+
ver->major = G2D_HW_MAJOR_VER;
ver->minor = G2D_HW_MINOR_VER;
@@ -1056,7 +1071,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
- struct device *dev = g2d_priv->dev;
+ struct device *dev;
struct g2d_data *g2d;
struct drm_exynos_g2d_set_cmdlist *req = data;
struct drm_exynos_g2d_cmd *cmd;
@@ -1067,6 +1082,10 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
int size;
int ret;
+ if (!g2d_priv)
+ return -ENODEV;
+
+ dev = g2d_priv->dev;
if (!dev)
return -ENODEV;
@@ -1223,13 +1242,17 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
- struct device *dev = g2d_priv->dev;
+ struct device *dev;
struct g2d_data *g2d;
struct drm_exynos_g2d_exec *req = data;
struct g2d_runqueue_node *runqueue_node;
struct list_head *run_cmdlist;
struct list_head *event_list;
+ if (!g2d_priv)
+ return -ENODEV;
+
+ dev = g2d_priv->dev;
if (!dev)
return -ENODEV;
@@ -1544,8 +1567,10 @@ static const struct dev_pm_ops g2d_pm_ops = {
static const struct of_device_id exynos_g2d_match[] = {
{ .compatible = "samsung,exynos5250-g2d" },
+ { .compatible = "samsung,exynos4212-g2d" },
{},
};
+MODULE_DEVICE_TABLE(of, exynos_g2d_match);
struct platform_driver g2d_driver = {
.probe = g2d_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 163a054922cb..15db80138382 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -301,7 +301,6 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *filp)
{
- struct exynos_drm_gem_obj *exynos_gem_obj;
struct drm_gem_object *obj;
obj = drm_gem_object_lookup(dev, filp, gem_handle);
@@ -310,8 +309,6 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
return;
}
- exynos_gem_obj = to_exynos_gem_obj(obj);
-
drm_gem_object_unreference_unlocked(obj);
/*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index a1888e128f1d..c411399070d6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -129,9 +129,6 @@ void exynos_platform_device_ipp_unregister(void)
int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
{
- if (!ippdrv)
- return -EINVAL;
-
mutex_lock(&exynos_drm_ippdrv_lock);
list_add_tail(&ippdrv->drv_list, &exynos_drm_ippdrv_list);
mutex_unlock(&exynos_drm_ippdrv_lock);
@@ -141,9 +138,6 @@ int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
{
- if (!ippdrv)
- return -EINVAL;
-
mutex_lock(&exynos_drm_ippdrv_lock);
list_del(&ippdrv->drv_list);
mutex_unlock(&exynos_drm_ippdrv_lock);
@@ -151,20 +145,15 @@ int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
return 0;
}
-static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
- u32 *idp)
+static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj)
{
int ret;
- /* do the allocation under our mutexlock */
mutex_lock(lock);
ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
mutex_unlock(lock);
- if (ret < 0)
- return ret;
- *idp = ret;
- return 0;
+ return ret;
}
static void ipp_remove_id(struct idr *id_idr, struct mutex *lock, u32 id)
@@ -178,35 +167,25 @@ static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
{
void *obj;
- DRM_DEBUG_KMS("id[%d]\n", id);
-
mutex_lock(lock);
-
- /* find object using handle */
obj = idr_find(id_idr, id);
- if (!obj) {
- DRM_ERROR("failed to find object.\n");
- mutex_unlock(lock);
- return ERR_PTR(-ENODEV);
- }
-
mutex_unlock(lock);
return obj;
}
-static inline bool ipp_check_dedicated(struct exynos_drm_ippdrv *ippdrv,
- enum drm_exynos_ipp_cmd cmd)
+static int ipp_check_driver(struct exynos_drm_ippdrv *ippdrv,
+ struct drm_exynos_ipp_property *property)
{
- /*
- * check dedicated flag and WB, OUTPUT operation with
- * power on state.
- */
- if (ippdrv->dedicated || (!ipp_is_m2m_cmd(cmd) &&
- !pm_runtime_suspended(ippdrv->dev)))
- return true;
+ if (ippdrv->dedicated || (!ipp_is_m2m_cmd(property->cmd) &&
+ !pm_runtime_suspended(ippdrv->dev)))
+ return -EBUSY;
- return false;
+ if (ippdrv->check_property &&
+ ippdrv->check_property(ippdrv->dev, property))
+ return -EINVAL;
+
+ return 0;
}
static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
@@ -214,62 +193,30 @@ static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
{
struct exynos_drm_ippdrv *ippdrv;
u32 ipp_id = property->ipp_id;
-
- DRM_DEBUG_KMS("ipp_id[%d]\n", ipp_id);
+ int ret;
if (ipp_id) {
- /* find ipp driver using idr */
- ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
- ipp_id);
- if (IS_ERR(ippdrv)) {
- DRM_ERROR("not found ipp%d driver.\n", ipp_id);
- return ippdrv;
+ ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock, ipp_id);
+ if (!ippdrv) {
+ DRM_DEBUG("ipp%d driver not found\n", ipp_id);
+ return ERR_PTR(-ENODEV);
}
- /*
- * WB, OUTPUT opertion not supported multi-operation.
- * so, make dedicated state at set property ioctl.
- * when ipp driver finished operations, clear dedicated flags.
- */
- if (ipp_check_dedicated(ippdrv, property->cmd)) {
- DRM_ERROR("already used choose device.\n");
- return ERR_PTR(-EBUSY);
- }
-
- /*
- * This is necessary to find correct device in ipp drivers.
- * ipp drivers have different abilities,
- * so need to check property.
- */
- if (ippdrv->check_property &&
- ippdrv->check_property(ippdrv->dev, property)) {
- DRM_ERROR("not support property.\n");
- return ERR_PTR(-EINVAL);
+ ret = ipp_check_driver(ippdrv, property);
+ if (ret < 0) {
+ DRM_DEBUG("ipp%d driver check error %d\n", ipp_id, ret);
+ return ERR_PTR(ret);
}
return ippdrv;
} else {
- /*
- * This case is search all ipp driver for finding.
- * user application don't set ipp_id in this case,
- * so ipp subsystem search correct driver in driver list.
- */
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
- if (ipp_check_dedicated(ippdrv, property->cmd)) {
- DRM_DEBUG_KMS("used device.\n");
- continue;
- }
-
- if (ippdrv->check_property &&
- ippdrv->check_property(ippdrv->dev, property)) {
- DRM_DEBUG_KMS("not support property.\n");
- continue;
- }
-
- return ippdrv;
+ ret = ipp_check_driver(ippdrv, property);
+ if (ret == 0)
+ return ippdrv;
}
- DRM_ERROR("not support ipp driver operations.\n");
+ DRM_DEBUG("cannot find driver suitable for given property.\n");
}
return ERR_PTR(-ENODEV);
@@ -308,8 +255,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
- struct device *dev = priv->dev;
+ struct device *dev = file_priv->ipp_dev;
struct ipp_context *ctx = get_ipp_context(dev);
struct drm_exynos_ipp_prop_list *prop_list = data;
struct exynos_drm_ippdrv *ippdrv;
@@ -346,10 +292,10 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
*/
ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
prop_list->ipp_id);
- if (IS_ERR(ippdrv)) {
+ if (!ippdrv) {
DRM_ERROR("not found ipp%d driver.\n",
prop_list->ipp_id);
- return PTR_ERR(ippdrv);
+ return -ENODEV;
}
*prop_list = ippdrv->prop_list;
@@ -432,7 +378,7 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
if (!event_work)
return ERR_PTR(-ENOMEM);
- INIT_WORK((struct work_struct *)event_work, ipp_sched_event);
+ INIT_WORK(&event_work->work, ipp_sched_event);
return event_work;
}
@@ -441,8 +387,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
- struct device *dev = priv->dev;
+ struct device *dev = file_priv->ipp_dev;
struct ipp_context *ctx = get_ipp_context(dev);
struct drm_exynos_ipp_property *property = data;
struct exynos_drm_ippdrv *ippdrv;
@@ -489,19 +434,18 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
if (!c_node)
return -ENOMEM;
- /* create property id */
- ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node,
- &property->prop_id);
- if (ret) {
+ ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node);
+ if (ret < 0) {
DRM_ERROR("failed to create id.\n");
goto err_clear;
}
+ property->prop_id = ret;
DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
property->prop_id, property->cmd, (int)ippdrv);
/* stored property information and ippdrv in private data */
- c_node->priv = priv;
+ c_node->dev = dev;
c_node->property = *property;
c_node->state = IPP_STATE_IDLE;
@@ -534,7 +478,6 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
INIT_LIST_HEAD(&c_node->mem_list[i]);
INIT_LIST_HEAD(&c_node->event_list);
- list_splice_init(&priv->event_list, &c_node->event_list);
mutex_lock(&ippdrv->cmd_lock);
list_add_tail(&c_node->list, &ippdrv->cmd_list);
mutex_unlock(&ippdrv->cmd_lock);
@@ -577,42 +520,18 @@ static void ipp_clean_cmd_node(struct ipp_context *ctx,
kfree(c_node);
}
-static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
+static bool ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
{
- struct drm_exynos_ipp_property *property = &c_node->property;
- struct drm_exynos_ipp_mem_node *m_node;
- struct list_head *head;
- int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
-
- for_each_ipp_ops(i) {
- /* source/destination memory list */
- head = &c_node->mem_list[i];
-
- /* find memory node entry */
- list_for_each_entry(m_node, head, list) {
- DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n",
- i ? "dst" : "src", count[i], (int)m_node);
- count[i]++;
- }
+ switch (c_node->property.cmd) {
+ case IPP_CMD_WB:
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_DST]);
+ case IPP_CMD_OUTPUT:
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_SRC]);
+ case IPP_CMD_M2M:
+ default:
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_SRC]) &&
+ !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_DST]);
}
-
- DRM_DEBUG_KMS("min[%d]max[%d]\n",
- min(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]),
- max(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]));
-
- /*
- * M2M operations should be need paired memory address.
- * so, need to check minimum count about src, dst.
- * other case not use paired memory, so use maximum count
- */
- if (ipp_is_m2m_cmd(property->cmd))
- ret = min(count[EXYNOS_DRM_OPS_SRC],
- count[EXYNOS_DRM_OPS_DST]);
- else
- ret = max(count[EXYNOS_DRM_OPS_SRC],
- count[EXYNOS_DRM_OPS_DST]);
-
- return ret;
}
static struct drm_exynos_ipp_mem_node
@@ -683,16 +602,14 @@ static struct drm_exynos_ipp_mem_node
struct drm_exynos_ipp_queue_buf *qbuf)
{
struct drm_exynos_ipp_mem_node *m_node;
- struct drm_exynos_ipp_buf_info buf_info;
- void *addr;
+ struct drm_exynos_ipp_buf_info *buf_info;
int i;
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
if (!m_node)
return ERR_PTR(-ENOMEM);
- /* clear base address for error handling */
- memset(&buf_info, 0x0, sizeof(buf_info));
+ buf_info = &m_node->buf_info;
/* operations, buffer id */
m_node->ops_id = qbuf->ops_id;
@@ -707,6 +624,8 @@ static struct drm_exynos_ipp_mem_node
/* get dma address by handle */
if (qbuf->handle[i]) {
+ dma_addr_t *addr;
+
addr = exynos_drm_gem_get_dma_addr(drm_dev,
qbuf->handle[i], file);
if (IS_ERR(addr)) {
@@ -714,15 +633,14 @@ static struct drm_exynos_ipp_mem_node
goto err_clear;
}
- buf_info.handles[i] = qbuf->handle[i];
- buf_info.base[i] = *(dma_addr_t *) addr;
- DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%x]\n",
- i, buf_info.base[i], (int)buf_info.handles[i]);
+ buf_info->handles[i] = qbuf->handle[i];
+ buf_info->base[i] = *addr;
+ DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
+ buf_info->base[i], buf_info->handles[i]);
}
}
m_node->filp = file;
- m_node->buf_info = buf_info;
mutex_lock(&c_node->mem_lock);
list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
mutex_unlock(&c_node->mem_lock);
@@ -930,8 +848,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
- struct device *dev = priv->dev;
+ struct device *dev = file_priv->ipp_dev;
struct ipp_context *ctx = get_ipp_context(dev);
struct drm_exynos_ipp_queue_buf *qbuf = data;
struct drm_exynos_ipp_cmd_node *c_node;
@@ -955,9 +872,9 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
/* find command node */
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
qbuf->prop_id);
- if (IS_ERR(c_node)) {
+ if (!c_node) {
DRM_ERROR("failed to get command node.\n");
- return PTR_ERR(c_node);
+ return -ENODEV;
}
/* buffer control */
@@ -1062,9 +979,8 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
struct exynos_drm_ippdrv *ippdrv = NULL;
- struct device *dev = priv->dev;
+ struct device *dev = file_priv->ipp_dev;
struct ipp_context *ctx = get_ipp_context(dev);
struct drm_exynos_ipp_cmd_ctrl *cmd_ctrl = data;
struct drm_exynos_ipp_cmd_work *cmd_work;
@@ -1091,9 +1007,9 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
cmd_ctrl->prop_id);
- if (IS_ERR(c_node)) {
+ if (!c_node) {
DRM_ERROR("invalid command node list.\n");
- return PTR_ERR(c_node);
+ return -ENODEV;
}
if (!exynos_drm_ipp_check_valid(ippdrv->dev, cmd_ctrl->ctrl,
@@ -1198,7 +1114,6 @@ static int ipp_set_property(struct exynos_drm_ippdrv *ippdrv,
/* reset h/w block */
if (ippdrv->reset &&
ippdrv->reset(ippdrv->dev)) {
- DRM_ERROR("failed to reset.\n");
return -EINVAL;
}
@@ -1216,30 +1131,24 @@ static int ipp_set_property(struct exynos_drm_ippdrv *ippdrv,
/* set format */
if (ops->set_fmt) {
ret = ops->set_fmt(ippdrv->dev, config->fmt);
- if (ret) {
- DRM_ERROR("not support format.\n");
+ if (ret)
return ret;
- }
}
/* set transform for rotation, flip */
if (ops->set_transf) {
ret = ops->set_transf(ippdrv->dev, config->degree,
config->flip, &swap);
- if (ret) {
- DRM_ERROR("not support tranf.\n");
- return -EINVAL;
- }
+ if (ret)
+ return ret;
}
/* set size */
if (ops->set_size) {
ret = ops->set_size(ippdrv->dev, swap, &config->pos,
&config->sz);
- if (ret) {
- DRM_ERROR("not support size.\n");
+ if (ret)
return ret;
- }
}
}
@@ -1283,11 +1192,6 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
m_node = list_first_entry(head,
struct drm_exynos_ipp_mem_node, list);
- if (!m_node) {
- DRM_ERROR("failed to get node.\n");
- ret = -EFAULT;
- goto err_unlock;
- }
DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
@@ -1545,11 +1449,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
m_node = list_first_entry(head,
struct drm_exynos_ipp_mem_node, list);
- if (!m_node) {
- DRM_ERROR("empty memory node.\n");
- ret = -ENOMEM;
- goto err_mem_unlock;
- }
tbuf_id[i] = m_node->buf_id;
DRM_DEBUG_KMS("%s buf_id[%d]\n",
@@ -1586,11 +1485,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
m_node = list_first_entry(head,
struct drm_exynos_ipp_mem_node, list);
- if (!m_node) {
- DRM_ERROR("empty memory node.\n");
- ret = -ENOMEM;
- goto err_mem_unlock;
- }
tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id;
@@ -1704,21 +1598,17 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
/* get ipp driver entry */
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
- u32 ipp_id;
-
ippdrv->drm_dev = drm_dev;
- ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv,
- &ipp_id);
- if (ret || ipp_id == 0) {
+ ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv);
+ if (ret < 0) {
DRM_ERROR("failed to create id.\n");
goto err;
}
+ ippdrv->prop_list.ipp_id = ret;
DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
- count++, (int)ippdrv, ipp_id);
-
- ippdrv->prop_list.ipp_id = ipp_id;
+ count++, (int)ippdrv, ret);
/* store parent device for node */
ippdrv->parent_dev = dev;
@@ -1776,17 +1666,10 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- priv->dev = dev;
- file_priv->ipp_priv = priv;
- INIT_LIST_HEAD(&priv->event_list);
+ file_priv->ipp_dev = dev;
- DRM_DEBUG_KMS("done priv[0x%x]\n", (int)priv);
+ DRM_DEBUG_KMS("done priv[0x%x]\n", (int)dev);
return 0;
}
@@ -1795,13 +1678,12 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
struct drm_file *file)
{
struct drm_exynos_file_private *file_priv = file->driver_priv;
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
struct exynos_drm_ippdrv *ippdrv = NULL;
struct ipp_context *ctx = get_ipp_context(dev);
struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
int count = 0;
- DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv);
+ DRM_DEBUG_KMS("for priv[0x%x]\n", (int)file_priv->ipp_dev);
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
mutex_lock(&ippdrv->cmd_lock);
@@ -1810,7 +1692,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n",
count++, (int)ippdrv);
- if (c_node->priv == priv) {
+ if (c_node->dev == file_priv->ipp_dev) {
/*
* userland goto unnormal state. process killed.
* and close the file.
@@ -1832,7 +1714,6 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
mutex_unlock(&ippdrv->cmd_lock);
}
- kfree(priv);
return;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index 7aaeaae757c2..6f48d62aeb30 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -48,7 +48,7 @@ struct drm_exynos_ipp_cmd_work {
/*
* A structure of command node.
*
- * @priv: IPP private information.
+ * @dev: IPP device.
* @list: list head to command queue information.
* @event_list: list head of event.
* @mem_list: list head to source,destination memory queue information.
@@ -64,7 +64,7 @@ struct drm_exynos_ipp_cmd_work {
* @state: state of command node.
*/
struct drm_exynos_ipp_cmd_node {
- struct exynos_drm_ipp_private *priv;
+ struct device *dev;
struct list_head list;
struct list_head event_list;
struct list_head mem_list[EXYNOS_DRM_OPS_MAX];
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index f01fbb6dc1f0..55af6b41c1df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -691,6 +691,7 @@ static const struct of_device_id exynos_rotator_match[] = {
},
{},
};
+MODULE_DEVICE_TABLE(of, exynos_rotator_match);
static int rotator_probe(struct platform_device *pdev)
{
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 2fb8705d6461..9528d81d8004 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -562,7 +562,7 @@ static int vidi_create_connector(struct exynos_drm_display *display,
}
drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index aa259b0a873a..562966db2aa1 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -84,6 +84,7 @@ struct hdmi_resources {
struct clk *sclk_hdmiphy;
struct clk *mout_hdmi;
struct regulator_bulk_data *regul_bulk;
+ struct regulator *reg_hdmi_en;
int regul_count;
};
@@ -592,6 +593,13 @@ static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
.is_apb_phy = 0,
};
+static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
+ .type = HDMI_TYPE13,
+ .phy_confs = hdmiphy_v13_configs,
+ .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs),
+ .is_apb_phy = 0,
+};
+
static struct hdmi_driver_data exynos5_hdmi_driver_data = {
.type = HDMI_TYPE14,
.phy_confs = hdmiphy_v13_configs,
@@ -1129,7 +1137,7 @@ static int hdmi_create_connector(struct exynos_drm_display *display,
}
drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
return 0;
@@ -1241,14 +1249,13 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
static void hdmi_audio_init(struct hdmi_context *hdata)
{
- u32 sample_rate, bits_per_sample, frame_size_code;
+ u32 sample_rate, bits_per_sample;
u32 data_num, bit_ch, sample_frq;
u32 val;
u8 acr[7];
sample_rate = 44100;
bits_per_sample = 16;
- frame_size_code = 0;
switch (bits_per_sample) {
case 20:
@@ -2168,7 +2175,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
struct device *dev = hdata->dev;
struct hdmi_resources *res = &hdata->res;
static char *supply[] = {
- "hdmi-en",
"vdd",
"vdd_osc",
"vdd_pll",
@@ -2228,6 +2234,20 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
}
res->regul_count = ARRAY_SIZE(supply);
+ res->reg_hdmi_en = devm_regulator_get(dev, "hdmi-en");
+ if (IS_ERR(res->reg_hdmi_en) && PTR_ERR(res->reg_hdmi_en) != -ENOENT) {
+ DRM_ERROR("failed to get hdmi-en regulator\n");
+ return PTR_ERR(res->reg_hdmi_en);
+ }
+ if (!IS_ERR(res->reg_hdmi_en)) {
+ ret = regulator_enable(res->reg_hdmi_en);
+ if (ret) {
+ DRM_ERROR("failed to enable hdmi-en regulator\n");
+ return ret;
+ }
+ } else
+ res->reg_hdmi_en = NULL;
+
return ret;
fail:
DRM_ERROR("HDMI resource init - failed\n");
@@ -2263,6 +2283,9 @@ static struct of_device_id hdmi_match_types[] = {
.compatible = "samsung,exynos5-hdmi",
.data = &exynos5_hdmi_driver_data,
}, {
+ .compatible = "samsung,exynos4210-hdmi",
+ .data = &exynos4210_hdmi_driver_data,
+ }, {
.compatible = "samsung,exynos4212-hdmi",
.data = &exynos4212_hdmi_driver_data,
}, {
@@ -2272,6 +2295,7 @@ static struct of_device_id hdmi_match_types[] = {
/* end node */
}
};
+MODULE_DEVICE_TABLE (of, hdmi_match_types);
static int hdmi_bind(struct device *dev, struct device *master, void *data)
{
@@ -2494,7 +2518,11 @@ static int hdmi_remove(struct platform_device *pdev)
cancel_delayed_work_sync(&hdata->hotplug_work);
- put_device(&hdata->hdmiphy_port->dev);
+ if (hdata->res.reg_hdmi_en)
+ regulator_disable(hdata->res.reg_hdmi_en);
+
+ if (hdata->hdmiphy_port)
+ put_device(&hdata->hdmiphy_port->dev);
put_device(&hdata->ddc_adpt->dev);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 7529946d0a74..e8b4ec84b312 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -76,7 +76,7 @@ struct mixer_resources {
struct clk *vp;
struct clk *sclk_mixer;
struct clk *sclk_hdmi;
- struct clk *sclk_dac;
+ struct clk *mout_mixer;
};
enum mixer_version_id {
@@ -93,6 +93,7 @@ struct mixer_context {
bool interlace;
bool powered;
bool vp_enabled;
+ bool has_sclk;
u32 int_en;
struct mutex mixer_mutex;
@@ -106,6 +107,7 @@ struct mixer_context {
struct mixer_drv_data {
enum mixer_version_id version;
bool is_vp_enabled;
+ bool has_sclk;
};
static const u8 filter_y_horiz_tap8[] = {
@@ -363,6 +365,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
mixer_reg_writemask(res, MXR_CFG, val,
MXR_CFG_VP_ENABLE);
+
+ /* control blending of graphic layer 0 */
+ mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val,
+ MXR_GRP_CFG_BLEND_PRE_MUL |
+ MXR_GRP_CFG_PIXEL_BLEND_EN);
}
break;
}
@@ -809,19 +816,23 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
dev_err(dev, "failed to get clock 'vp'\n");
return -ENODEV;
}
- mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
- if (IS_ERR(mixer_res->sclk_mixer)) {
- dev_err(dev, "failed to get clock 'sclk_mixer'\n");
- return -ENODEV;
- }
- mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
- if (IS_ERR(mixer_res->sclk_dac)) {
- dev_err(dev, "failed to get clock 'sclk_dac'\n");
- return -ENODEV;
- }
- if (mixer_res->sclk_hdmi)
- clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
+ if (mixer_ctx->has_sclk) {
+ mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
+ if (IS_ERR(mixer_res->sclk_mixer)) {
+ dev_err(dev, "failed to get clock 'sclk_mixer'\n");
+ return -ENODEV;
+ }
+ mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
+ if (IS_ERR(mixer_res->mout_mixer)) {
+ dev_err(dev, "failed to get clock 'mout_mixer'\n");
+ return -ENODEV;
+ }
+
+ if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
+ clk_set_parent(mixer_res->mout_mixer,
+ mixer_res->sclk_hdmi);
+ }
res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
if (res == NULL) {
@@ -1082,7 +1093,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
clk_prepare_enable(res->mixer);
if (ctx->vp_enabled) {
clk_prepare_enable(res->vp);
- clk_prepare_enable(res->sclk_mixer);
+ if (ctx->has_sclk)
+ clk_prepare_enable(res->sclk_mixer);
}
mutex_lock(&ctx->mixer_mutex);
@@ -1121,7 +1133,8 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
clk_disable_unprepare(res->mixer);
if (ctx->vp_enabled) {
clk_disable_unprepare(res->vp);
- clk_disable_unprepare(res->sclk_mixer);
+ if (ctx->has_sclk)
+ clk_disable_unprepare(res->sclk_mixer);
}
pm_runtime_put_sync(ctx->dev);
@@ -1189,9 +1202,15 @@ static struct mixer_drv_data exynos5250_mxr_drv_data = {
.is_vp_enabled = 0,
};
+static struct mixer_drv_data exynos4212_mxr_drv_data = {
+ .version = MXR_VER_0_0_0_16,
+ .is_vp_enabled = 1,
+};
+
static struct mixer_drv_data exynos4210_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
+ .has_sclk = 1,
};
static struct platform_device_id mixer_driver_types[] = {
@@ -1208,6 +1227,12 @@ static struct platform_device_id mixer_driver_types[] = {
static struct of_device_id mixer_match_types[] = {
{
+ .compatible = "samsung,exynos4210-mixer",
+ .data = &exynos4210_mxr_drv_data,
+ }, {
+ .compatible = "samsung,exynos4212-mixer",
+ .data = &exynos4212_mxr_drv_data,
+ }, {
.compatible = "samsung,exynos5-mixer",
.data = &exynos5250_mxr_drv_data,
}, {
@@ -1220,6 +1245,7 @@ static struct of_device_id mixer_match_types[] = {
/* end node */
}
};
+MODULE_DEVICE_TABLE(of, mixer_match_types);
static int mixer_bind(struct device *dev, struct device *manager, void *data)
{
@@ -1251,6 +1277,7 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
ctx->pdev = pdev;
ctx->dev = dev;
ctx->vp_enabled = drv->is_vp_enabled;
+ ctx->has_sclk = drv->has_sclk;
ctx->mxr_ver = drv->version;
init_waitqueue_head(&ctx->wait_vsync_queue);
atomic_set(&ctx->wait_vsync_event, 0);
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index c18268cd516e..248c33a35ebf 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -192,7 +192,7 @@ static void cdv_intel_crt_destroy(struct drm_connector *connector)
struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
psb_intel_i2c_destroy(gma_encoder->ddc_bus);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -304,7 +304,7 @@ void cdv_intel_crt_init(struct drm_device *dev,
drm_connector_helper_add(connector,
&cdv_intel_crt_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
failed_ddc:
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
index 9ff30c2efadb..a4cc0e60a1be 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
@@ -1713,7 +1713,7 @@ cdv_intel_dp_destroy(struct drm_connector *connector)
}
}
i2c_del_adapter(&intel_dp->adapter);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -1847,7 +1847,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
/* Set up the DDC bus. */
switch (output_reg) {
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index b99084b3f706..4268bf210034 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -248,7 +248,7 @@ static void cdv_hdmi_destroy(struct drm_connector *connector)
if (gma_encoder->i2c_bus)
psb_intel_i2c_destroy(gma_encoder->i2c_bus);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -356,7 +356,7 @@ void cdv_hdmi_init(struct drm_device *dev,
hdmi_priv->hdmi_i2c_adapter = &(gma_encoder->i2c_bus->adapter);
hdmi_priv->dev = dev;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
failed_ddc:
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index 8ecc920fc26d..0b770396548c 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -446,7 +446,7 @@ static void cdv_intel_lvds_destroy(struct drm_connector *connector)
if (gma_encoder->i2c_bus)
psb_intel_i2c_destroy(gma_encoder->i2c_bus);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -774,7 +774,7 @@ void cdv_intel_lvds_init(struct drm_device *dev,
out:
mutex_unlock(&dev->mode_config.mutex);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
failed_find:
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index e7fcc148f333..d0dd3bea8aa5 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -561,7 +561,7 @@ static int psbfb_probe(struct drm_fb_helper *helper,
return psbfb_create(psb_fbdev, sizes);
}
-static struct drm_fb_helper_funcs psb_fb_helper_funcs = {
+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,
@@ -600,7 +600,8 @@ int psb_fbdev_init(struct drm_device *dev)
}
dev_priv->fbdev = fbdev;
- fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
+
+ drm_fb_helper_prepare(dev, &fbdev->psb_fb_helper, &psb_fb_helper_funcs);
drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
INTELFB_CONN_LIMIT);
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 592d205a0089..ce015db59dc6 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -206,7 +206,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
WARN_ON(gt->pages);
- pages = drm_gem_get_pages(&gt->gem, 0);
+ pages = drm_gem_get_pages(&gt->gem);
if (IS_ERR(pages))
return PTR_ERR(pages);
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index 6e91b20ce2e5..abf2248da61e 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -318,7 +318,7 @@ static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
if (!dsi_connector)
return;
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
sender = dsi_connector->pkg_sender;
mdfld_dsi_pkg_sender_destroy(sender);
@@ -597,7 +597,7 @@ void mdfld_dsi_output_init(struct drm_device *dev,
dsi_config->encoder = encoder;
encoder->base.type = (pipe == 0) ? INTEL_OUTPUT_MIPI :
INTEL_OUTPUT_MIPI2;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
/*TODO: add code to destroy outputs on error*/
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index a97e38e284fa..d75ecb3bdee7 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -39,7 +39,6 @@ static void mid_get_fuse_settings(struct drm_device *dev)
#define FB_REG06 0xD0810600
#define FB_MIPI_DISABLE (1 << 11)
#define FB_REG09 0xD0810900
-#define FB_REG09 0xD0810900
#define FB_SKU_MASK 0x7000
#define FB_SKU_SHIFT 12
#define FB_SKU_100 0
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index cf018ddcc5a6..e6f5c620a0a2 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -665,7 +665,7 @@ void oaktrail_hdmi_init(struct drm_device *dev,
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = false;
connector->doublescan_allowed = false;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
dev_info(dev->dev, "HDMI initialised.\n");
return;
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index 9b099468a5db..0d39da6e8b7a 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -404,7 +404,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
out:
mutex_unlock(&dev->mode_config.mutex);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
failed_find:
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index d7778d0472c1..88aad95bde09 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -563,7 +563,7 @@ void psb_intel_lvds_destroy(struct drm_connector *connector)
if (lvds_priv->ddc_bus)
psb_intel_i2c_destroy(lvds_priv->ddc_bus);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -829,7 +829,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
*/
out:
mutex_unlock(&dev->mode_config.mutex);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
failed_find:
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index deeb0829b129..0be96fdb5e28 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -1682,7 +1682,7 @@ static void psb_intel_sdvo_destroy(struct drm_connector *connector)
psb_intel_sdvo_connector->tv_format);
psb_intel_sdvo_destroy_enhance_property(connector);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -2071,7 +2071,7 @@ psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector,
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
gma_connector_attach_encoder(&connector->base, &encoder->base);
- drm_sysfs_connector_add(&connector->base.base);
+ drm_connector_register(&connector->base.base);
}
static void
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 240c331405b9..d4762799351d 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -15,8 +15,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-
+#include <linux/component.h>
#include <linux/hdmi.h>
#include <linux/module.h>
#include <linux/irq.h>
@@ -730,12 +729,9 @@ tda998x_configure_audio(struct tda998x_priv *priv,
/* DRM encoder functions */
-static void
-tda998x_encoder_set_config(struct drm_encoder *encoder, void *params)
+static void tda998x_encoder_set_config(struct tda998x_priv *priv,
+ const struct tda998x_encoder_params *p)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
- struct tda998x_encoder_params *p = params;
-
priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
(p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
VIP_CNTRL_0_SWAP_B(p->swap_b) |
@@ -752,11 +748,8 @@ tda998x_encoder_set_config(struct drm_encoder *encoder, void *params)
priv->params = *p;
}
-static void
-tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
-
/* we only care about on or off: */
if (mode != DRM_MODE_DPMS_ON)
mode = DRM_MODE_DPMS_OFF;
@@ -806,19 +799,23 @@ tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
return true;
}
-static int
-tda998x_encoder_mode_valid(struct drm_encoder *encoder,
- struct drm_display_mode *mode)
+static int tda998x_encoder_mode_valid(struct tda998x_priv *priv,
+ struct drm_display_mode *mode)
{
+ if (mode->clock > 150000)
+ return MODE_CLOCK_HIGH;
+ if (mode->htotal >= BIT(13))
+ return MODE_BAD_HVALUE;
+ if (mode->vtotal >= BIT(11))
+ return MODE_BAD_VVALUE;
return MODE_OK;
}
static void
-tda998x_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+tda998x_encoder_mode_set(struct tda998x_priv *priv,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
uint16_t ref_pix, ref_line, n_pix, n_line;
uint16_t hs_pix_s, hs_pix_e;
uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
@@ -1006,20 +1003,16 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
}
static enum drm_connector_status
-tda998x_encoder_detect(struct drm_encoder *encoder,
- struct drm_connector *connector)
+tda998x_encoder_detect(struct tda998x_priv *priv)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV);
return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected :
connector_status_disconnected;
}
-static int
-read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk)
+static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
uint8_t offset, segptr;
int ret, i;
@@ -1048,8 +1041,8 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk)
return i;
}
} else {
- for (i = 10; i > 0; i--) {
- msleep(10);
+ for (i = 100; i > 0; i--) {
+ msleep(1);
ret = reg_read(priv, REG_INT_FLAGS_2);
if (ret < 0)
return ret;
@@ -1073,10 +1066,8 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk)
return 0;
}
-static uint8_t *
-do_get_edid(struct drm_encoder *encoder)
+static uint8_t *do_get_edid(struct tda998x_priv *priv)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
int j, valid_extensions = 0;
uint8_t *block, *new;
bool print_bad_edid = drm_debug & DRM_UT_KMS;
@@ -1088,7 +1079,7 @@ do_get_edid(struct drm_encoder *encoder)
reg_clear(priv, REG_TX4, TX4_PD_RAM);
/* base block fetch */
- if (read_edid_block(encoder, block, 0))
+ if (read_edid_block(priv, block, 0))
goto fail;
if (!drm_edid_block_valid(block, 0, print_bad_edid))
@@ -1105,7 +1096,7 @@ do_get_edid(struct drm_encoder *encoder)
for (j = 1; j <= block[0x7e]; j++) {
uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH;
- if (read_edid_block(encoder, ext_block, j))
+ if (read_edid_block(priv, ext_block, j))
goto fail;
if (!drm_edid_block_valid(ext_block, j, print_bad_edid))
@@ -1138,11 +1129,10 @@ fail:
}
static int
-tda998x_encoder_get_modes(struct drm_encoder *encoder,
- struct drm_connector *connector)
+tda998x_encoder_get_modes(struct tda998x_priv *priv,
+ struct drm_connector *connector)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
- struct edid *edid = (struct edid *)do_get_edid(encoder);
+ struct edid *edid = (struct edid *)do_get_edid(priv);
int n = 0;
if (edid) {
@@ -1155,18 +1145,14 @@ tda998x_encoder_get_modes(struct drm_encoder *encoder,
return n;
}
-static int
-tda998x_encoder_create_resources(struct drm_encoder *encoder,
- struct drm_connector *connector)
+static void tda998x_encoder_set_polling(struct tda998x_priv *priv,
+ struct drm_connector *connector)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
-
if (priv->hdmi->irq)
connector->polled = DRM_CONNECTOR_POLL_HPD;
else
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
- return 0;
}
static int
@@ -1179,66 +1165,97 @@ tda998x_encoder_set_property(struct drm_encoder *encoder,
return 0;
}
-static void
-tda998x_encoder_destroy(struct drm_encoder *encoder)
+static void tda998x_destroy(struct tda998x_priv *priv)
{
- struct tda998x_priv *priv = to_tda998x_priv(encoder);
- drm_i2c_encoder_destroy(encoder);
-
/* disable all IRQs and free the IRQ handler */
cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
if (priv->hdmi->irq)
free_irq(priv->hdmi->irq, priv);
- if (priv->cec)
- i2c_unregister_device(priv->cec);
+ i2c_unregister_device(priv->cec);
+}
+
+/* Slave encoder support */
+
+static void
+tda998x_encoder_slave_set_config(struct drm_encoder *encoder, void *params)
+{
+ tda998x_encoder_set_config(to_tda998x_priv(encoder), params);
+}
+
+static void tda998x_encoder_slave_destroy(struct drm_encoder *encoder)
+{
+ struct tda998x_priv *priv = to_tda998x_priv(encoder);
+
+ tda998x_destroy(priv);
+ drm_i2c_encoder_destroy(encoder);
kfree(priv);
}
-static struct drm_encoder_slave_funcs tda998x_encoder_funcs = {
- .set_config = tda998x_encoder_set_config,
- .destroy = tda998x_encoder_destroy,
- .dpms = tda998x_encoder_dpms,
- .save = tda998x_encoder_save,
- .restore = tda998x_encoder_restore,
- .mode_fixup = tda998x_encoder_mode_fixup,
- .mode_valid = tda998x_encoder_mode_valid,
- .mode_set = tda998x_encoder_mode_set,
- .detect = tda998x_encoder_detect,
- .get_modes = tda998x_encoder_get_modes,
- .create_resources = tda998x_encoder_create_resources,
- .set_property = tda998x_encoder_set_property,
-};
+static void tda998x_encoder_slave_dpms(struct drm_encoder *encoder, int mode)
+{
+ tda998x_encoder_dpms(to_tda998x_priv(encoder), mode);
+}
-/* I2C driver functions */
+static int tda998x_encoder_slave_mode_valid(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+{
+ return tda998x_encoder_mode_valid(to_tda998x_priv(encoder), mode);
+}
-static int
-tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+static void
+tda998x_encoder_slave_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
- return 0;
+ tda998x_encoder_mode_set(to_tda998x_priv(encoder), mode, adjusted_mode);
+}
+
+static enum drm_connector_status
+tda998x_encoder_slave_detect(struct drm_encoder *encoder,
+ struct drm_connector *connector)
+{
+ return tda998x_encoder_detect(to_tda998x_priv(encoder));
+}
+
+static int tda998x_encoder_slave_get_modes(struct drm_encoder *encoder,
+ struct drm_connector *connector)
+{
+ return tda998x_encoder_get_modes(to_tda998x_priv(encoder), connector);
}
static int
-tda998x_remove(struct i2c_client *client)
+tda998x_encoder_slave_create_resources(struct drm_encoder *encoder,
+ struct drm_connector *connector)
{
+ tda998x_encoder_set_polling(to_tda998x_priv(encoder), connector);
return 0;
}
-static int
-tda998x_encoder_init(struct i2c_client *client,
- struct drm_device *dev,
- struct drm_encoder_slave *encoder_slave)
+static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = {
+ .set_config = tda998x_encoder_slave_set_config,
+ .destroy = tda998x_encoder_slave_destroy,
+ .dpms = tda998x_encoder_slave_dpms,
+ .save = tda998x_encoder_save,
+ .restore = tda998x_encoder_restore,
+ .mode_fixup = tda998x_encoder_mode_fixup,
+ .mode_valid = tda998x_encoder_slave_mode_valid,
+ .mode_set = tda998x_encoder_slave_mode_set,
+ .detect = tda998x_encoder_slave_detect,
+ .get_modes = tda998x_encoder_slave_get_modes,
+ .create_resources = tda998x_encoder_slave_create_resources,
+ .set_property = tda998x_encoder_set_property,
+};
+
+/* I2C driver functions */
+
+static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
{
- struct tda998x_priv *priv;
struct device_node *np = client->dev.of_node;
u32 video;
int rev_lo, rev_hi, ret;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3);
priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
@@ -1246,17 +1263,11 @@ tda998x_encoder_init(struct i2c_client *client,
priv->current_page = 0xff;
priv->hdmi = client;
priv->cec = i2c_new_dummy(client->adapter, 0x34);
- if (!priv->cec) {
- kfree(priv);
+ if (!priv->cec)
return -ENODEV;
- }
- priv->encoder = &encoder_slave->base;
priv->dpms = DRM_MODE_DPMS_OFF;
- encoder_slave->slave_priv = priv;
- encoder_slave->slave_funcs = &tda998x_encoder_funcs;
-
/* wake up the device: */
cec_write(priv, REG_CEC_ENAMODS,
CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI);
@@ -1359,12 +1370,231 @@ fail:
*/
if (priv->cec)
i2c_unregister_device(priv->cec);
- kfree(priv);
- encoder_slave->slave_priv = NULL;
- encoder_slave->slave_funcs = NULL;
return -ENXIO;
}
+static int tda998x_encoder_init(struct i2c_client *client,
+ struct drm_device *dev,
+ struct drm_encoder_slave *encoder_slave)
+{
+ struct tda998x_priv *priv;
+ int ret;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->encoder = &encoder_slave->base;
+
+ ret = tda998x_create(client, priv);
+ if (ret) {
+ kfree(priv);
+ return ret;
+ }
+
+ encoder_slave->slave_priv = priv;
+ encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs;
+
+ return 0;
+}
+
+struct tda998x_priv2 {
+ struct tda998x_priv base;
+ struct drm_encoder encoder;
+ struct drm_connector connector;
+};
+
+#define conn_to_tda998x_priv2(x) \
+ container_of(x, struct tda998x_priv2, connector);
+
+#define enc_to_tda998x_priv2(x) \
+ container_of(x, struct tda998x_priv2, encoder);
+
+static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+
+ tda998x_encoder_dpms(&priv->base, mode);
+}
+
+static void tda998x_encoder_prepare(struct drm_encoder *encoder)
+{
+ tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void tda998x_encoder_commit(struct drm_encoder *encoder)
+{
+ tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static void tda998x_encoder2_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+
+ tda998x_encoder_mode_set(&priv->base, mode, adjusted_mode);
+}
+
+static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
+ .dpms = tda998x_encoder2_dpms,
+ .save = tda998x_encoder_save,
+ .restore = tda998x_encoder_restore,
+ .mode_fixup = tda998x_encoder_mode_fixup,
+ .prepare = tda998x_encoder_prepare,
+ .commit = tda998x_encoder_commit,
+ .mode_set = tda998x_encoder2_mode_set,
+};
+
+static void tda998x_encoder_destroy(struct drm_encoder *encoder)
+{
+ struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder);
+
+ tda998x_destroy(&priv->base);
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs tda998x_encoder_funcs = {
+ .destroy = tda998x_encoder_destroy,
+};
+
+static int tda998x_connector_get_modes(struct drm_connector *connector)
+{
+ struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+
+ return tda998x_encoder_get_modes(&priv->base, connector);
+}
+
+static int tda998x_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+
+ return tda998x_encoder_mode_valid(&priv->base, mode);
+}
+
+static struct drm_encoder *
+tda998x_connector_best_encoder(struct drm_connector *connector)
+{
+ struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+
+ return &priv->encoder;
+}
+
+static
+const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = {
+ .get_modes = tda998x_connector_get_modes,
+ .mode_valid = tda998x_connector_mode_valid,
+ .best_encoder = tda998x_connector_best_encoder,
+};
+
+static enum drm_connector_status
+tda998x_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector);
+
+ return tda998x_encoder_detect(&priv->base);
+}
+
+static void tda998x_connector_destroy(struct drm_connector *connector)
+{
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+}
+
+static const struct drm_connector_funcs tda998x_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = tda998x_connector_detect,
+ .destroy = tda998x_connector_destroy,
+};
+
+static int tda998x_bind(struct device *dev, struct device *master, void *data)
+{
+ struct tda998x_encoder_params *params = dev->platform_data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct drm_device *drm = data;
+ struct tda998x_priv2 *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, priv);
+
+ priv->base.encoder = &priv->encoder;
+ priv->connector.interlace_allowed = 1;
+ priv->encoder.possible_crtcs = 1 << 0;
+
+ ret = tda998x_create(client, &priv->base);
+ if (ret)
+ return ret;
+
+ if (!dev->of_node && params)
+ tda998x_encoder_set_config(&priv->base, params);
+
+ tda998x_encoder_set_polling(&priv->base, &priv->connector);
+
+ drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs);
+ ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS);
+ if (ret)
+ goto err_encoder;
+
+ drm_connector_helper_add(&priv->connector,
+ &tda998x_connector_helper_funcs);
+ ret = drm_connector_init(drm, &priv->connector,
+ &tda998x_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA);
+ if (ret)
+ goto err_connector;
+
+ ret = drm_connector_register(&priv->connector);
+ if (ret)
+ goto err_sysfs;
+
+ priv->connector.encoder = &priv->encoder;
+ drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder);
+
+ return 0;
+
+err_sysfs:
+ drm_connector_cleanup(&priv->connector);
+err_connector:
+ drm_encoder_cleanup(&priv->encoder);
+err_encoder:
+ tda998x_destroy(&priv->base);
+ return ret;
+}
+
+static void tda998x_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct tda998x_priv2 *priv = dev_get_drvdata(dev);
+
+ drm_connector_cleanup(&priv->connector);
+ drm_encoder_cleanup(&priv->encoder);
+ tda998x_destroy(&priv->base);
+}
+
+static const struct component_ops tda998x_ops = {
+ .bind = tda998x_bind,
+ .unbind = tda998x_unbind,
+};
+
+static int
+tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ return component_add(&client->dev, &tda998x_ops);
+}
+
+static int tda998x_remove(struct i2c_client *client)
+{
+ component_del(&client->dev, &tda998x_ops);
+ return 0;
+}
+
#ifdef CONFIG_OF
static const struct of_device_id tda998x_dt_ids[] = {
{ .compatible = "nxp,tda998x", },
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 437e1824d0bf..4e39ab34eb1c 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -69,15 +69,3 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
option changes the default for that module option.
If in doubt, say "N".
-
-config DRM_I915_UMS
- bool "Enable userspace modesetting on Intel hardware (DEPRECATED)"
- depends on DRM_I915 && BROKEN
- default n
- help
- Choose this option if you still need userspace modesetting.
-
- Userspace modesetting is deprecated for quite some time now, so
- enable this only if you have ancient versions of the DDX drivers.
-
- If in doubt, say "N".
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cad1683d8bb5..91bd167e1cb7 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -59,6 +59,7 @@ i915-y += dvo_ch7017.o \
intel_crt.o \
intel_ddi.o \
intel_dp.o \
+ intel_dp_mst.o \
intel_dsi_cmd.o \
intel_dsi.o \
intel_dsi_pll.o \
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 9d7954366bd2..dea99d92fb4a 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -426,6 +426,9 @@ static const u32 gen7_render_regs[] = {
GEN7_SO_WRITE_OFFSET(1),
GEN7_SO_WRITE_OFFSET(2),
GEN7_SO_WRITE_OFFSET(3),
+ GEN7_L3SQCREG1,
+ GEN7_L3CNTLREG2,
+ GEN7_L3CNTLREG3,
};
static const u32 gen7_blt_regs[] = {
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b8c689202c40..9e737b771c40 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -170,11 +170,13 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
}
if (obj->ring != NULL)
seq_printf(m, " (%s)", obj->ring->name);
+ if (obj->frontbuffer_bits)
+ seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
}
static void describe_ctx(struct seq_file *m, struct intel_context *ctx)
{
- seq_putc(m, ctx->is_initialized ? 'I' : 'i');
+ seq_putc(m, ctx->legacy_hw_ctx.initialized ? 'I' : 'i');
seq_putc(m, ctx->remap_slice ? 'R' : 'r');
seq_putc(m, ' ');
}
@@ -515,6 +517,11 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
unsigned long flags;
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);
@@ -556,6 +563,8 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
spin_unlock_irqrestore(&dev->event_lock, flags);
}
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
@@ -985,29 +994,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
i915_next_seqno_get, i915_next_seqno_set,
"0x%llx\n");
-static int i915_rstdby_delays(struct seq_file *m, void *unused)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u16 crstanddelay;
- int ret;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
- intel_runtime_pm_get(dev_priv);
-
- crstanddelay = I915_READ16(CRSTANDVID);
-
- intel_runtime_pm_put(dev_priv);
- mutex_unlock(&dev->struct_mutex);
-
- seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f));
-
- return 0;
-}
-
static int i915_frequency_info(struct seq_file *m, void *unused)
{
struct drm_info_node *node = m->private;
@@ -1029,7 +1015,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
MEMSTAT_VID_SHIFT);
seq_printf(m, "Current P-state: %d\n",
(rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
- } else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) {
+ } else if (IS_GEN6(dev) || (IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) ||
+ IS_BROADWELL(dev)) {
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
@@ -1048,7 +1035,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
reqf = I915_READ(GEN6_RPNSWREQ);
reqf &= ~GEN6_TURBO_DISABLE;
- if (IS_HASWELL(dev))
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev))
reqf >>= 24;
else
reqf >>= 25;
@@ -1065,7 +1052,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI);
rpcurdown = I915_READ(GEN6_RP_CUR_DOWN);
rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
- if (IS_HASWELL(dev))
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev))
cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
else
cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
@@ -1121,20 +1108,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
seq_printf(m, "Max overclocked frequency: %dMHz\n",
dev_priv->rps.max_freq * GT_FREQUENCY_MULTIPLIER);
} else if (IS_VALLEYVIEW(dev)) {
- u32 freq_sts, val;
+ u32 freq_sts;
mutex_lock(&dev_priv->rps.hw_lock);
freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
- val = valleyview_rps_max_freq(dev_priv);
seq_printf(m, "max GPU freq: %d MHz\n",
- vlv_gpu_freq(dev_priv, val));
+ vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq));
- val = valleyview_rps_min_freq(dev_priv);
seq_printf(m, "min GPU freq: %d MHz\n",
- vlv_gpu_freq(dev_priv, val));
+ vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq));
+
+ seq_printf(m, "efficient (RPe) frequency: %d MHz\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq));
seq_printf(m, "current GPU freq: %d MHz\n",
vlv_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
@@ -1148,61 +1136,6 @@ out:
return ret;
}
-static int i915_delayfreq_table(struct seq_file *m, void *unused)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 delayfreq;
- int ret, i;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
- intel_runtime_pm_get(dev_priv);
-
- for (i = 0; i < 16; i++) {
- delayfreq = I915_READ(PXVFREQ_BASE + i * 4);
- seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq,
- (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT);
- }
-
- intel_runtime_pm_put(dev_priv);
-
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
-static inline int MAP_TO_MV(int map)
-{
- return 1250 - (map * 25);
-}
-
-static int i915_inttoext_table(struct seq_file *m, void *unused)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 inttoext;
- int ret, i;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
- intel_runtime_pm_get(dev_priv);
-
- for (i = 1; i <= 32; i++) {
- inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4);
- seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext);
- }
-
- intel_runtime_pm_put(dev_priv);
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
static int ironlake_drpc_info(struct seq_file *m)
{
struct drm_info_node *node = m->private;
@@ -1513,10 +1446,17 @@ static int i915_ips_status(struct seq_file *m, void *unused)
intel_runtime_pm_get(dev_priv);
- if (IS_BROADWELL(dev) || I915_READ(IPS_CTL) & IPS_ENABLE)
- seq_puts(m, "enabled\n");
- else
- seq_puts(m, "disabled\n");
+ seq_printf(m, "Enabled by kernel parameter: %s\n",
+ yesno(i915.enable_ips));
+
+ if (INTEL_INFO(dev)->gen >= 8) {
+ seq_puts(m, "Currently: unknown\n");
+ } else {
+ if (I915_READ(IPS_CTL) & IPS_ENABLE)
+ seq_puts(m, "Currently: enabled\n");
+ else
+ seq_puts(m, "Currently: disabled\n");
+ }
intel_runtime_pm_put(dev_priv);
@@ -1620,26 +1560,6 @@ out:
return ret;
}
-static int i915_gfxec(struct seq_file *m, void *unused)
-{
- struct drm_info_node *node = m->private;
- struct drm_device *dev = node->minor->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
- intel_runtime_pm_get(dev_priv);
-
- seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4));
- intel_runtime_pm_put(dev_priv);
-
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
static int i915_opregion(struct seq_file *m, void *unused)
{
struct drm_info_node *node = m->private;
@@ -1677,9 +1597,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
#ifdef CONFIG_DRM_I915_FBDEV
struct drm_i915_private *dev_priv = dev->dev_private;
- int ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (ret)
- return ret;
ifbdev = dev_priv->fbdev;
fb = to_intel_framebuffer(ifbdev->helper.fb);
@@ -1692,7 +1609,6 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
atomic_read(&fb->base.refcount.refcount));
describe_obj(m, fb->obj);
seq_putc(m, '\n');
- mutex_unlock(&dev->mode_config.mutex);
#endif
mutex_lock(&dev->mode_config.fb_lock);
@@ -1723,7 +1639,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
struct intel_context *ctx;
int ret, i;
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
@@ -1740,7 +1656,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
}
list_for_each_entry(ctx, &dev_priv->context_list, link) {
- if (ctx->obj == NULL)
+ if (ctx->legacy_hw_ctx.rcs_state == NULL)
continue;
seq_puts(m, "HW context ");
@@ -1749,11 +1665,11 @@ static int i915_context_status(struct seq_file *m, void *unused)
if (ring->default_context == ctx)
seq_printf(m, "(default context %s) ", ring->name);
- describe_obj(m, ctx->obj);
+ describe_obj(m, ctx->legacy_hw_ctx.rcs_state);
seq_putc(m, '\n');
}
- mutex_unlock(&dev->mode_config.mutex);
+ mutex_unlock(&dev->struct_mutex);
return 0;
}
@@ -1863,7 +1779,7 @@ static int per_file_ctx(int id, void *ptr, void *data)
if (i915_gem_context_is_default(ctx))
seq_puts(m, " default context:\n");
else
- seq_printf(m, " context %d:\n", ctx->id);
+ seq_printf(m, " context %d:\n", ctx->user_handle);
ppgtt->debug_dump(ppgtt, m);
return 0;
@@ -1976,17 +1892,25 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv);
+ mutex_lock(&dev_priv->psr.lock);
seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support));
seq_printf(m, "Source_OK: %s\n", yesno(dev_priv->psr.source_ok));
+ seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled));
+ seq_printf(m, "Active: %s\n", yesno(dev_priv->psr.active));
+ seq_printf(m, "Busy frontbuffer bits: 0x%03x\n",
+ dev_priv->psr.busy_frontbuffer_bits);
+ seq_printf(m, "Re-enable work scheduled: %s\n",
+ yesno(work_busy(&dev_priv->psr.work.work)));
enabled = HAS_PSR(dev) &&
I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
- seq_printf(m, "Enabled: %s\n", yesno(enabled));
+ seq_printf(m, "HW Enabled & Active bit: %s\n", yesno(enabled));
if (HAS_PSR(dev))
psrperf = I915_READ(EDP_PSR_PERF_CNT(dev)) &
EDP_PSR_PERF_CNT_MASK;
seq_printf(m, "Performance_Counter: %u\n", psrperf);
+ mutex_unlock(&dev_priv->psr.lock);
intel_runtime_pm_put(dev_priv);
return 0;
@@ -2072,7 +1996,7 @@ static int i915_pc8_status(struct seq_file *m, void *unused)
seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy));
seq_printf(m, "IRQs disabled: %s\n",
- yesno(dev_priv->pm.irqs_disabled));
+ yesno(!intel_irqs_enabled(dev_priv)));
return 0;
}
@@ -2126,6 +2050,8 @@ static const char *power_domain_str(enum intel_display_power_domain domain)
return "VGA";
case POWER_DOMAIN_AUDIO:
return "AUDIO";
+ case POWER_DOMAIN_PLLS:
+ return "PLLS";
case POWER_DOMAIN_INIT:
return "INIT";
default:
@@ -2223,9 +2149,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc)
struct drm_crtc *crtc = &intel_crtc->base;
struct intel_encoder *intel_encoder;
- seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
- crtc->primary->fb->base.id, crtc->x, crtc->y,
- crtc->primary->fb->width, crtc->primary->fb->height);
+ if (crtc->primary->fb)
+ seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
+ crtc->primary->fb->base.id, crtc->x, crtc->y,
+ crtc->primary->fb->width, crtc->primary->fb->height);
+ else
+ seq_puts(m, "\tprimary plane disabled\n");
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
intel_encoder_info(m, intel_crtc, intel_encoder);
}
@@ -2287,13 +2216,15 @@ static void intel_connector_info(struct seq_file *m,
seq_printf(m, "\tCEA rev: %d\n",
connector->display_info.cea_rev);
}
- if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
- intel_encoder->type == INTEL_OUTPUT_EDP)
- intel_dp_info(m, intel_connector);
- else if (intel_encoder->type == INTEL_OUTPUT_HDMI)
- intel_hdmi_info(m, intel_connector);
- else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
- intel_lvds_info(m, intel_connector);
+ if (intel_encoder) {
+ if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+ intel_encoder->type == INTEL_OUTPUT_EDP)
+ intel_dp_info(m, intel_connector);
+ else if (intel_encoder->type == INTEL_OUTPUT_HDMI)
+ intel_hdmi_info(m, intel_connector);
+ else if (intel_encoder->type == INTEL_OUTPUT_LVDS)
+ intel_lvds_info(m, intel_connector);
+ }
seq_printf(m, "\tmodes:\n");
list_for_each_entry(mode, &connector->modes, head)
@@ -2347,17 +2278,17 @@ static int i915_display_info(struct seq_file *m, void *unused)
bool active;
int x, y;
- seq_printf(m, "CRTC %d: pipe: %c, active: %s\n",
+ seq_printf(m, "CRTC %d: pipe: %c, active=%s (size=%dx%d)\n",
crtc->base.base.id, pipe_name(crtc->pipe),
- yesno(crtc->active));
+ yesno(crtc->active), crtc->config.pipe_src_w, crtc->config.pipe_src_h);
if (crtc->active) {
intel_crtc_info(m, crtc);
active = cursor_position(dev, crtc->pipe, &x, &y);
- seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n",
+ seq_printf(m, "\tcursor visible? %s, position (%d, %d), size %dx%d, addr 0x%08x, active? %s\n",
yesno(crtc->cursor_base),
- x, y, crtc->cursor_addr,
- yesno(active));
+ x, y, crtc->cursor_width, crtc->cursor_height,
+ crtc->cursor_addr, yesno(active));
}
seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
@@ -2377,12 +2308,132 @@ static int i915_display_info(struct seq_file *m, void *unused)
return 0;
}
+static int i915_semaphore_status(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 drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *ring;
+ int num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+ int i, j, ret;
+
+ if (!i915_semaphore_is_enabled(dev)) {
+ seq_puts(m, "Semaphores are disabled\n");
+ return 0;
+ }
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ return ret;
+ intel_runtime_pm_get(dev_priv);
+
+ if (IS_BROADWELL(dev)) {
+ struct page *page;
+ uint64_t *seqno;
+
+ page = i915_gem_object_get_page(dev_priv->semaphore_obj, 0);
+
+ seqno = (uint64_t *)kmap_atomic(page);
+ for_each_ring(ring, dev_priv, i) {
+ uint64_t offset;
+
+ seq_printf(m, "%s\n", ring->name);
+
+ seq_puts(m, " Last signal:");
+ for (j = 0; j < num_rings; j++) {
+ offset = i * I915_NUM_RINGS + j;
+ seq_printf(m, "0x%08llx (0x%02llx) ",
+ seqno[offset], offset * 8);
+ }
+ seq_putc(m, '\n');
+
+ seq_puts(m, " Last wait: ");
+ for (j = 0; j < num_rings; j++) {
+ offset = i + (j * I915_NUM_RINGS);
+ seq_printf(m, "0x%08llx (0x%02llx) ",
+ seqno[offset], offset * 8);
+ }
+ seq_putc(m, '\n');
+
+ }
+ kunmap_atomic(seqno);
+ } else {
+ seq_puts(m, " Last signal:");
+ for_each_ring(ring, dev_priv, i)
+ for (j = 0; j < num_rings; j++)
+ seq_printf(m, "0x%08x\n",
+ I915_READ(ring->semaphore.mbox.signal[j]));
+ seq_putc(m, '\n');
+ }
+
+ seq_puts(m, "\nSync seqno:\n");
+ for_each_ring(ring, dev_priv, i) {
+ for (j = 0; j < num_rings; j++) {
+ seq_printf(m, " 0x%08x ", ring->semaphore.sync_seqno[j]);
+ }
+ seq_putc(m, '\n');
+ }
+ seq_putc(m, '\n');
+
+ intel_runtime_pm_put(dev_priv);
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+static int i915_shared_dplls_info(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 drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ drm_modeset_lock_all(dev);
+ for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+ struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+ seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->name, pll->id);
+ seq_printf(m, " refcount: %i, active: %i, on: %s\n", pll->refcount,
+ pll->active, yesno(pll->on));
+ seq_printf(m, " tracked hardware state:\n");
+ seq_printf(m, " dpll: 0x%08x\n", pll->hw_state.dpll);
+ seq_printf(m, " dpll_md: 0x%08x\n", pll->hw_state.dpll_md);
+ seq_printf(m, " fp0: 0x%08x\n", pll->hw_state.fp0);
+ seq_printf(m, " fp1: 0x%08x\n", pll->hw_state.fp1);
+ seq_printf(m, " wrpll: 0x%08x\n", pll->hw_state.wrpll);
+ }
+ drm_modeset_unlock_all(dev);
+
+ return 0;
+}
+
struct pipe_crc_info {
const char *name;
struct drm_device *dev;
enum pipe pipe;
};
+static int i915_dp_mst_info(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 drm_encoder *encoder;
+ struct intel_encoder *intel_encoder;
+ struct intel_digital_port *intel_dig_port;
+ drm_modeset_lock_all(dev);
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ intel_encoder = to_intel_encoder(encoder);
+ if (intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT)
+ continue;
+ intel_dig_port = enc_to_dig_port(encoder);
+ if (!intel_dig_port->dp.can_mst)
+ continue;
+
+ drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
+ }
+ drm_modeset_unlock_all(dev);
+ return 0;
+}
+
static int i915_pipe_crc_open(struct inode *inode, struct file *filep)
{
struct pipe_crc_info *info = inode->i_private;
@@ -2849,7 +2900,60 @@ static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
return 0;
}
-static int ivb_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
+static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *crtc =
+ to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+
+ drm_modeset_lock_all(dev);
+ /*
+ * If we use the eDP transcoder we need to make sure that we don't
+ * bypass the pfit, since otherwise the pipe CRC source won't work. Only
+ * relevant on hsw with pipe A when using the always-on power well
+ * routing.
+ */
+ if (crtc->config.cpu_transcoder == TRANSCODER_EDP &&
+ !crtc->config.pch_pfit.enabled) {
+ crtc->config.pch_pfit.force_thru = true;
+
+ intel_display_power_get(dev_priv,
+ POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
+
+ dev_priv->display.crtc_disable(&crtc->base);
+ dev_priv->display.crtc_enable(&crtc->base);
+ }
+ drm_modeset_unlock_all(dev);
+}
+
+static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *crtc =
+ to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+
+ drm_modeset_lock_all(dev);
+ /*
+ * If we use the eDP transcoder we need to make sure that we don't
+ * bypass the pfit, since otherwise the pipe CRC source won't work. Only
+ * relevant on hsw with pipe A when using the always-on power well
+ * routing.
+ */
+ if (crtc->config.pch_pfit.force_thru) {
+ crtc->config.pch_pfit.force_thru = false;
+
+ dev_priv->display.crtc_disable(&crtc->base);
+ dev_priv->display.crtc_enable(&crtc->base);
+
+ intel_display_power_put(dev_priv,
+ POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
+ }
+ drm_modeset_unlock_all(dev);
+}
+
+static int ivb_pipe_crc_ctl_reg(struct drm_device *dev,
+ enum pipe pipe,
+ enum intel_pipe_crc_source *source,
uint32_t *val)
{
if (*source == INTEL_PIPE_CRC_SOURCE_AUTO)
@@ -2863,6 +2967,9 @@ static int ivb_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB;
break;
case INTEL_PIPE_CRC_SOURCE_PF:
+ if (IS_HASWELL(dev) && pipe == PIPE_A)
+ hsw_trans_edp_pipe_A_crc_wa(dev);
+
*val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB;
break;
case INTEL_PIPE_CRC_SOURCE_NONE:
@@ -2895,11 +3002,11 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
else if (INTEL_INFO(dev)->gen < 5)
ret = i9xx_pipe_crc_ctl_reg(dev, pipe, &source, &val);
else if (IS_VALLEYVIEW(dev))
- ret = vlv_pipe_crc_ctl_reg(dev,pipe, &source, &val);
+ ret = vlv_pipe_crc_ctl_reg(dev, pipe, &source, &val);
else if (IS_GEN5(dev) || IS_GEN6(dev))
ret = ilk_pipe_crc_ctl_reg(&source, &val);
else
- ret = ivb_pipe_crc_ctl_reg(&source, &val);
+ ret = ivb_pipe_crc_ctl_reg(dev, pipe, &source, &val);
if (ret != 0)
return ret;
@@ -2929,11 +3036,16 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
/* real source -> none transition */
if (source == INTEL_PIPE_CRC_SOURCE_NONE) {
struct intel_pipe_crc_entry *entries;
+ struct intel_crtc *crtc =
+ to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n",
pipe_name(pipe));
- intel_wait_for_vblank(dev, pipe);
+ drm_modeset_lock(&crtc->base.mutex, NULL);
+ if (crtc->active)
+ intel_wait_for_vblank(dev, pipe);
+ drm_modeset_unlock(&crtc->base.mutex);
spin_lock_irq(&pipe_crc->lock);
entries = pipe_crc->entries;
@@ -2946,6 +3058,8 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
g4x_undo_pipe_scramble_reset(dev, pipe);
else if (IS_VALLEYVIEW(dev))
vlv_undo_pipe_scramble_reset(dev, pipe);
+ else if (IS_HASWELL(dev) && pipe == PIPE_A)
+ hsw_undo_trans_edp_pipe_A_crc_wa(dev);
}
return 0;
@@ -3177,7 +3291,7 @@ static int pri_wm_latency_open(struct inode *inode, struct file *file)
{
struct drm_device *dev = inode->i_private;
- if (!HAS_PCH_SPLIT(dev))
+ if (HAS_GMCH_DISPLAY(dev))
return -ENODEV;
return single_open(file, pri_wm_latency_show, dev);
@@ -3187,7 +3301,7 @@ static int spr_wm_latency_open(struct inode *inode, struct file *file)
{
struct drm_device *dev = inode->i_private;
- if (!HAS_PCH_SPLIT(dev))
+ if (HAS_GMCH_DISPLAY(dev))
return -ENODEV;
return single_open(file, spr_wm_latency_show, dev);
@@ -3197,7 +3311,7 @@ static int cur_wm_latency_open(struct inode *inode, struct file *file)
{
struct drm_device *dev = inode->i_private;
- if (!HAS_PCH_SPLIT(dev))
+ if (HAS_GMCH_DISPLAY(dev))
return -ENODEV;
return single_open(file, cur_wm_latency_show, dev);
@@ -3506,7 +3620,7 @@ i915_max_freq_get(void *data, u64 *val)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ if (INTEL_INFO(dev)->gen < 6)
return -ENODEV;
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
@@ -3532,7 +3646,7 @@ i915_max_freq_set(void *data, u64 val)
u32 rp_state_cap, hw_max, hw_min;
int ret;
- if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ if (INTEL_INFO(dev)->gen < 6)
return -ENODEV;
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
@@ -3549,8 +3663,8 @@ i915_max_freq_set(void *data, u64 val)
if (IS_VALLEYVIEW(dev)) {
val = vlv_freq_opcode(dev_priv, val);
- hw_max = valleyview_rps_max_freq(dev_priv);
- hw_min = valleyview_rps_min_freq(dev_priv);
+ hw_max = dev_priv->rps.max_freq;
+ hw_min = dev_priv->rps.min_freq;
} else {
do_div(val, GT_FREQUENCY_MULTIPLIER);
@@ -3587,7 +3701,7 @@ i915_min_freq_get(void *data, u64 *val)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ if (INTEL_INFO(dev)->gen < 6)
return -ENODEV;
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
@@ -3613,7 +3727,7 @@ i915_min_freq_set(void *data, u64 val)
u32 rp_state_cap, hw_max, hw_min;
int ret;
- if (!(IS_GEN6(dev) || IS_GEN7(dev)))
+ if (INTEL_INFO(dev)->gen < 6)
return -ENODEV;
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
@@ -3630,8 +3744,8 @@ i915_min_freq_set(void *data, u64 val)
if (IS_VALLEYVIEW(dev)) {
val = vlv_freq_opcode(dev_priv, val);
- hw_max = valleyview_rps_max_freq(dev_priv);
- hw_min = valleyview_rps_min_freq(dev_priv);
+ hw_max = dev_priv->rps.max_freq;
+ hw_min = dev_priv->rps.min_freq;
} else {
do_div(val, GT_FREQUENCY_MULTIPLIER);
@@ -3799,14 +3913,10 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS},
{"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
{"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
- {"i915_rstdby_delays", i915_rstdby_delays, 0},
{"i915_frequency_info", i915_frequency_info, 0},
- {"i915_delayfreq_table", i915_delayfreq_table, 0},
- {"i915_inttoext_table", i915_inttoext_table, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
{"i915_ring_freq_table", i915_ring_freq_table, 0},
- {"i915_gfxec", i915_gfxec, 0},
{"i915_fbc_status", i915_fbc_status, 0},
{"i915_ips_status", i915_ips_status, 0},
{"i915_sr_status", i915_sr_status, 0},
@@ -3823,6 +3933,9 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_pc8_status", i915_pc8_status, 0},
{"i915_power_domain_info", i915_power_domain_info, 0},
{"i915_display_info", i915_display_info, 0},
+ {"i915_semaphore_status", i915_semaphore_status, 0},
+ {"i915_shared_dplls_info", i915_shared_dplls_info, 0},
+ {"i915_dp_mst_info", i915_dp_mst_info, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 6c656392d67d..2e7f03ad5ee2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -138,7 +138,7 @@ static void i915_free_hws(struct drm_device *dev)
I915_WRITE(HWS_PGA, 0x1ffff000);
}
-void i915_kernel_lost_context(struct drm_device * dev)
+void i915_kernel_lost_context(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv;
@@ -166,7 +166,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
-static int i915_dma_cleanup(struct drm_device * dev)
+static int i915_dma_cleanup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
@@ -190,7 +190,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
return 0;
}
-static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
+static int i915_initialize(struct drm_device *dev, drm_i915_init_t *init)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
@@ -235,7 +235,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
return 0;
}
-static int i915_dma_resume(struct drm_device * dev)
+static int i915_dma_resume(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring = LP_RING(dev_priv);
@@ -359,7 +359,7 @@ static int validate_cmd(int cmd)
return 0;
}
-static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
+static int i915_emit_cmds(struct drm_device *dev, int *buffer, int dwords)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i, ret;
@@ -369,6 +369,7 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
for (i = 0; i < dwords;) {
int sz = validate_cmd(buffer[i]);
+
if (sz == 0 || i + sz > dwords)
return -EINVAL;
i += sz;
@@ -453,7 +454,7 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
}
}
-static int i915_dispatch_cmdbuffer(struct drm_device * dev,
+static int i915_dispatch_cmdbuffer(struct drm_device *dev,
drm_i915_cmdbuffer_t *cmd,
struct drm_clip_rect *cliprects,
void *cmdbuf)
@@ -487,8 +488,8 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
return 0;
}
-static int i915_dispatch_batchbuffer(struct drm_device * dev,
- drm_i915_batchbuffer_t * batch,
+static int i915_dispatch_batchbuffer(struct drm_device *dev,
+ drm_i915_batchbuffer_t *batch,
struct drm_clip_rect *cliprects)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -549,7 +550,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
return 0;
}
-static int i915_dispatch_flip(struct drm_device * dev)
+static int i915_dispatch_flip(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv =
@@ -755,7 +756,7 @@ fail_batch_free:
return ret;
}
-static int i915_emit_irq(struct drm_device * dev)
+static int i915_emit_irq(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
@@ -781,7 +782,7 @@ static int i915_emit_irq(struct drm_device * dev)
return dev_priv->dri1.counter;
}
-static int i915_wait_irq(struct drm_device * dev, int irq_nr)
+static int i915_wait_irq(struct drm_device *dev, int irq_nr)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
@@ -1266,6 +1267,7 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
{
struct drm_device *dev = pci_get_drvdata(pdev);
pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
+
if (state == VGA_SWITCHEROO_ON) {
pr_info("switched on\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
@@ -1338,6 +1340,8 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto cleanup_gem_stolen;
+ dev_priv->pm._irqs_disabled = false;
+
/* Important: The output setup functions called by modeset_init need
* working irqs for e.g. gmbus and dp aux transfers. */
intel_modeset_init(dev);
@@ -1375,9 +1379,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
*/
intel_fbdev_initial_config(dev);
- /* Only enable hotplug handling once the fbdev is fully set up. */
- dev_priv->enable_hotplug_processing = true;
-
drm_kms_helper_poll_init(dev);
return 0;
@@ -1425,15 +1426,16 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
}
#if IS_ENABLED(CONFIG_FB)
-static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
+static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
{
struct apertures_struct *ap;
struct pci_dev *pdev = dev_priv->dev->pdev;
bool primary;
+ int ret;
ap = alloc_apertures(1);
if (!ap)
- return;
+ return -ENOMEM;
ap->ranges[0].base = dev_priv->gtt.mappable_base;
ap->ranges[0].size = dev_priv->gtt.mappable_end;
@@ -1441,13 +1443,16 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
primary =
pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
- remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
+ ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
kfree(ap);
+
+ return ret;
}
#else
-static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
+static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
{
+ return 0;
}
#endif
@@ -1464,12 +1469,13 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
#else
static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
{
- int ret;
+ int ret = 0;
DRM_INFO("Replacing VGA console driver\n");
console_lock();
- ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
+ if (con_is_bound(&vga_con))
+ ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
if (ret == 0) {
ret = do_unregister_con_driver(&vga_con);
@@ -1491,10 +1497,11 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
#define SEP_EMPTY
#define PRINT_FLAG(name) info->name ? #name "," : ""
#define SEP_COMMA ,
- DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x flags="
+ DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags="
DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY),
info->gen,
dev_priv->dev->pdev->device,
+ dev_priv->dev->pdev->revision,
DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA));
#undef PRINT_S
#undef SEP_EMPTY
@@ -1593,7 +1600,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (dev_priv == NULL)
return -ENOMEM;
- dev->dev_private = (void *)dev_priv;
+ dev->dev_private = dev_priv;
dev_priv->dev = dev;
/* copy initial configuration to dev_priv->info */
@@ -1605,6 +1612,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
spin_lock_init(&dev_priv->backlight_lock);
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->dpio_lock);
mutex_init(&dev_priv->modeset_restore_lock);
@@ -1663,7 +1671,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_gtt;
}
- i915_kick_out_firmware_fb(dev_priv);
+ ret = i915_kick_out_firmware_fb(dev_priv);
+ if (ret) {
+ DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
+ goto out_gtt;
+ }
}
pci_set_master(dev->pdev);
@@ -1716,6 +1728,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree;
}
+ dev_priv->dp_wq = alloc_ordered_workqueue("i915-dp", 0);
+ if (dev_priv->dp_wq == NULL) {
+ DRM_ERROR("Failed to create our dp workqueue.\n");
+ ret = -ENOMEM;
+ goto out_freewq;
+ }
+
intel_irq_init(dev);
intel_uncore_sanitize(dev);
@@ -1791,6 +1810,8 @@ out_gem_unload:
intel_teardown_gmbus(dev);
intel_teardown_mchbar(dev);
pm_qos_remove_request(&dev_priv->pm_qos);
+ destroy_workqueue(dev_priv->dp_wq);
+out_freewq:
destroy_workqueue(dev_priv->wq);
out_mtrrfree:
arch_phys_wc_del(dev_priv->gtt.mtrr);
@@ -1891,6 +1912,7 @@ int i915_driver_unload(struct drm_device *dev)
intel_teardown_gmbus(dev);
intel_teardown_mchbar(dev);
+ destroy_workqueue(dev_priv->dp_wq);
destroy_workqueue(dev_priv->wq);
pm_qos_remove_request(&dev_priv->pm_qos);
@@ -1932,7 +1954,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file)
* and DMA structures, since the kernel won't be using them, and clea
* up any GEM state.
*/
-void i915_driver_lastclose(struct drm_device * dev)
+void i915_driver_lastclose(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1953,11 +1975,11 @@ void i915_driver_lastclose(struct drm_device * dev)
i915_dma_cleanup(dev);
}
-void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
+void i915_driver_preclose(struct drm_device *dev, struct drm_file *file)
{
mutex_lock(&dev->struct_mutex);
- i915_gem_context_close(dev, file_priv);
- i915_gem_release(dev, file_priv);
+ i915_gem_context_close(dev, file);
+ i915_gem_release(dev, file);
mutex_unlock(&dev->struct_mutex);
}
@@ -2030,7 +2052,7 @@ int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
* manage the gtt, we need to claim that all intel devices are agp. For
* otherwise the drm core refuses to initialize the agp support code.
*/
-int i915_driver_device_is_agp(struct drm_device * dev)
+int i915_driver_device_is_agp(struct drm_device *dev)
{
return 1;
}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 651e65e051c0..ec96f9a9724c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -28,6 +28,7 @@
*/
#include <linux/device.h>
+#include <linux/acpi.h>
#include <drm/drmP.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
@@ -46,8 +47,6 @@ static struct drm_driver driver;
PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \
.trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \
TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \
- .dpll_offsets = { DPLL_A_OFFSET, DPLL_B_OFFSET }, \
- .dpll_md_offsets = { DPLL_A_MD_OFFSET, DPLL_B_MD_OFFSET }, \
.palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET }
#define GEN_CHV_PIPEOFFSETS \
@@ -55,10 +54,6 @@ static struct drm_driver driver;
CHV_PIPE_C_OFFSET }, \
.trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \
CHV_TRANSCODER_C_OFFSET, }, \
- .dpll_offsets = { DPLL_A_OFFSET, DPLL_B_OFFSET, \
- CHV_DPLL_C_OFFSET }, \
- .dpll_md_offsets = { DPLL_A_MD_OFFSET, DPLL_B_MD_OFFSET, \
- CHV_DPLL_C_MD_OFFSET }, \
.palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \
CHV_PALETTE_C_OFFSET }
@@ -308,6 +303,7 @@ static const struct intel_device_info intel_broadwell_d_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.has_llc = 1,
.has_ddi = 1,
+ .has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
@@ -319,6 +315,7 @@ static const struct intel_device_info intel_broadwell_m_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
.has_llc = 1,
.has_ddi = 1,
+ .has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
@@ -330,6 +327,7 @@ static const struct intel_device_info intel_broadwell_gt3d_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.has_llc = 1,
.has_ddi = 1,
+ .has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
@@ -341,6 +339,7 @@ static const struct intel_device_info intel_broadwell_gt3m_info = {
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
.has_llc = 1,
.has_ddi = 1,
+ .has_fpga_dbg = 1,
.has_fbc = 1,
GEN_DEFAULT_PIPEOFFSETS,
IVB_CURSOR_OFFSETS,
@@ -499,8 +498,7 @@ static int i915_drm_freeze(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
-
- intel_runtime_pm_get(dev_priv);
+ pci_power_t opregion_target_state;
/* ignore lid events during suspend */
mutex_lock(&dev_priv->modeset_restore_lock);
@@ -526,21 +524,23 @@ static int i915_drm_freeze(struct drm_device *dev)
return error;
}
- drm_irq_uninstall(dev);
- dev_priv->enable_hotplug_processing = false;
-
- intel_disable_gt_powersave(dev);
-
/*
* Disable CRTCs directly since we want to preserve sw state
- * for _thaw.
+ * for _thaw. Also, power gate the CRTC power wells.
*/
drm_modeset_lock_all(dev);
- for_each_crtc(dev, crtc) {
- dev_priv->display.crtc_disable(crtc);
- }
+ for_each_crtc(dev, crtc)
+ intel_crtc_control(crtc, false);
drm_modeset_unlock_all(dev);
+ intel_dp_mst_suspend(dev);
+
+ flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+ intel_runtime_pm_disable_interrupts(dev);
+
+ intel_suspend_gt_powersave(dev);
+
intel_modeset_suspend_hw(dev);
}
@@ -548,8 +548,15 @@ static int i915_drm_freeze(struct drm_device *dev)
i915_save_state(dev);
+ opregion_target_state = PCI_D3cold;
+#if IS_ENABLED(CONFIG_ACPI_SLEEP)
+ if (acpi_target_system_state() < ACPI_STATE_S3)
+ opregion_target_state = PCI_D1;
+#endif
+ intel_opregion_notify_adapter(dev, opregion_target_state);
+
+ intel_uncore_forcewake_reset(dev, false);
intel_opregion_fini(dev);
- intel_uncore_fini(dev);
console_lock();
intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED);
@@ -557,6 +564,8 @@ static int i915_drm_freeze(struct drm_device *dev)
dev_priv->suspend_count++;
+ intel_display_set_init_power(dev_priv, false);
+
return 0;
}
@@ -606,7 +615,10 @@ static int i915_drm_thaw_early(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- intel_uncore_early_sanitize(dev);
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ hsw_disable_pc8(dev_priv);
+
+ intel_uncore_early_sanitize(dev, true);
intel_uncore_sanitize(dev);
intel_power_domains_init_hw(dev_priv);
@@ -639,11 +651,19 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
}
mutex_unlock(&dev->struct_mutex);
- /* We need working interrupts for modeset enabling ... */
- drm_irq_install(dev, dev->pdev->irq);
+ intel_runtime_pm_restore_interrupts(dev);
intel_modeset_init_hw(dev);
+ {
+ unsigned long irqflags;
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ if (dev_priv->display.hpd_irq_setup)
+ dev_priv->display.hpd_irq_setup(dev);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+ }
+
+ intel_dp_mst_resume(dev);
drm_modeset_lock_all(dev);
intel_modeset_setup_hw_state(dev, true);
drm_modeset_unlock_all(dev);
@@ -655,7 +675,6 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
* notifications.
* */
intel_hpd_init(dev);
- dev_priv->enable_hotplug_processing = true;
/* Config may have changed between suspend and resume */
drm_helper_hpd_irq_event(dev);
}
@@ -678,7 +697,8 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
dev_priv->modeset_restore = MODESET_DONE;
mutex_unlock(&dev_priv->modeset_restore_lock);
- intel_runtime_pm_put(dev_priv);
+ intel_opregion_notify_adapter(dev, PCI_D0);
+
return 0;
}
@@ -887,6 +907,7 @@ static int i915_pm_suspend_late(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct drm_i915_private *dev_priv = drm_dev->dev_private;
/*
* We have a suspedn ordering issue with the snd-hda driver also
@@ -900,6 +921,9 @@ static int i915_pm_suspend_late(struct device *dev)
if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
+ if (IS_HASWELL(drm_dev) || IS_BROADWELL(drm_dev))
+ hsw_enable_pc8(dev_priv);
+
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a47fbf60b781..4412f6a4383b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -53,7 +53,7 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20080730"
+#define DRIVER_DATE "20140725"
enum pipe {
INVALID_PIPE = -1,
@@ -129,6 +129,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_PORT_OTHER,
POWER_DOMAIN_VGA,
POWER_DOMAIN_AUDIO,
+ POWER_DOMAIN_PLLS,
POWER_DOMAIN_INIT,
POWER_DOMAIN_NUM,
@@ -178,14 +179,20 @@ enum hpd_pin {
list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
if ((intel_connector)->base.encoder == (__encoder))
+#define for_each_power_domain(domain, mask) \
+ for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
+ if ((1 << (domain)) & (mask))
+
struct drm_i915_private;
struct i915_mmu_object;
enum intel_dpll_id {
DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
/* real shared dpll ids must be >= 0 */
- DPLL_ID_PCH_PLL_A,
- DPLL_ID_PCH_PLL_B,
+ DPLL_ID_PCH_PLL_A = 0,
+ DPLL_ID_PCH_PLL_B = 1,
+ DPLL_ID_WRPLL1 = 0,
+ DPLL_ID_WRPLL2 = 1,
};
#define I915_NUM_PLLS 2
@@ -194,6 +201,7 @@ struct intel_dpll_hw_state {
uint32_t dpll_md;
uint32_t fp0;
uint32_t fp1;
+ uint32_t wrpll;
};
struct intel_shared_dpll {
@@ -204,6 +212,8 @@ struct intel_shared_dpll {
/* should match the index in the dev_priv->shared_dplls array */
enum intel_dpll_id id;
struct intel_dpll_hw_state hw_state;
+ /* The mode_set hook is optional and should be used together with the
+ * intel_prepare_shared_dpll function. */
void (*mode_set)(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll);
void (*enable)(struct drm_i915_private *dev_priv,
@@ -228,12 +238,6 @@ void intel_link_compute_m_n(int bpp, int nlanes,
int pixel_clock, int link_clock,
struct intel_link_m_n *m_n);
-struct intel_ddi_plls {
- int spll_refcount;
- int wrpll1_refcount;
- int wrpll2_refcount;
-};
-
/* Interface history:
*
* 1.1: Original.
@@ -310,6 +314,7 @@ struct drm_i915_error_state {
u32 eir;
u32 pgtbl_er;
u32 ier;
+ u32 gtier[4];
u32 ccid;
u32 derrmr;
u32 forcewake;
@@ -324,6 +329,7 @@ struct drm_i915_error_state {
u64 fence[I915_MAX_NUM_FENCES];
struct intel_overlay_error_state *overlay;
struct intel_display_error_state *display;
+ struct drm_i915_error_object *semaphore_obj;
struct drm_i915_error_ring {
bool valid;
@@ -435,8 +441,8 @@ struct drm_i915_display_funcs {
void (*update_wm)(struct drm_crtc *crtc);
void (*update_sprite_wm)(struct drm_plane *plane,
struct drm_crtc *crtc,
- uint32_t sprite_width, int pixel_size,
- bool enable, bool scaled);
+ uint32_t sprite_width, uint32_t sprite_height,
+ int pixel_size, bool enable, bool scaled);
void (*modeset_global_resources)(struct drm_device *dev);
/* Returns the active state of the crtc, and if the crtc is active,
* fills out the pipe-config with the hw state. */
@@ -552,8 +558,6 @@ struct intel_device_info {
/* Register offsets for the various display pipes and transcoders */
int pipe_offsets[I915_MAX_TRANSCODERS];
int trans_offsets[I915_MAX_TRANSCODERS];
- int dpll_offsets[I915_MAX_PIPES];
- int dpll_md_offsets[I915_MAX_PIPES];
int palette_offsets[I915_MAX_PIPES];
int cursor_offsets[I915_MAX_PIPES];
};
@@ -586,28 +590,48 @@ struct i915_ctx_hang_stats {
};
/* This must match up with the value previously used for execbuf2.rsvd1. */
-#define DEFAULT_CONTEXT_ID 0
+#define DEFAULT_CONTEXT_HANDLE 0
+/**
+ * struct intel_context - as the name implies, represents a context.
+ * @ref: reference count.
+ * @user_handle: userspace tracking identity for this context.
+ * @remap_slice: l3 row remapping information.
+ * @file_priv: filp associated with this context (NULL for global default
+ * context).
+ * @hang_stats: information about the role of this context in possible GPU
+ * hangs.
+ * @vm: virtual memory space used by this context.
+ * @legacy_hw_ctx: render context backing object and whether it is correctly
+ * initialized (legacy ring submission mechanism only).
+ * @link: link in the global list of contexts.
+ *
+ * Contexts are memory images used by the hardware to store copies of their
+ * internal state.
+ */
struct intel_context {
struct kref ref;
- int id;
- bool is_initialized;
+ int user_handle;
uint8_t remap_slice;
struct drm_i915_file_private *file_priv;
- struct intel_engine_cs *last_ring;
- struct drm_i915_gem_object *obj;
struct i915_ctx_hang_stats hang_stats;
struct i915_address_space *vm;
+ struct {
+ struct drm_i915_gem_object *rcs_state;
+ bool initialized;
+ } legacy_hw_ctx;
+
struct list_head link;
};
struct i915_fbc {
unsigned long size;
+ unsigned threshold;
unsigned int fb_id;
enum plane plane;
int y;
- struct drm_mm_node *compressed_fb;
+ struct drm_mm_node compressed_fb;
struct drm_mm_node *compressed_llb;
struct intel_fbc_work {
@@ -635,9 +659,15 @@ struct i915_drrs {
struct intel_connector *connector;
};
+struct intel_dp;
struct i915_psr {
+ struct mutex lock;
bool sink_support;
bool source_ok;
+ struct intel_dp *enabled;
+ bool active;
+ struct delayed_work work;
+ unsigned busy_frontbuffer_bits;
};
enum intel_pch {
@@ -656,6 +686,7 @@ enum intel_sbi_destination {
#define QUIRK_PIPEA_FORCE (1<<0)
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
+#define QUIRK_BACKLIGHT_PRESENT (1<<3)
struct intel_fbdev;
struct intel_fbc_work;
@@ -879,6 +910,12 @@ struct vlv_s0ix_state {
u32 clock_gate_dis2;
};
+struct intel_rps_ei {
+ u32 cz_clock;
+ u32 render_c0;
+ u32 media_c0;
+};
+
struct intel_gen6_power_mgmt {
/* work and pm_iir are protected by dev_priv->irq_lock */
struct work_struct work;
@@ -902,6 +939,9 @@ struct intel_gen6_power_mgmt {
u8 efficient_freq; /* AKA RPe. Pre-determined balanced frequency */
u8 rp1_freq; /* "less than" RP0 power/freqency */
u8 rp0_freq; /* Non-overclocked max frequency. */
+ u32 cz_freq;
+
+ u32 ei_interrupt_count;
int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
@@ -909,6 +949,9 @@ struct intel_gen6_power_mgmt {
bool enabled;
struct delayed_work delayed_resume_work;
+ /* manual wa residency calculations */
+ struct intel_rps_ei up_ei, down_ei;
+
/*
* Protects RPS/RC6 register access and PCU communication.
* Must be taken after struct_mutex if nested.
@@ -930,7 +973,7 @@ struct intel_ilk_power_mgmt {
unsigned long last_time1;
unsigned long chipset_power;
u64 last_count2;
- struct timespec last_time2;
+ u64 last_time2;
unsigned long gfx_power;
u8 corr;
@@ -1229,6 +1272,7 @@ struct intel_vbt_data {
u16 pwm_freq_hz;
bool present;
bool active_low_pwm;
+ u8 min_brightness; /* min_brightness/255 of max */
} backlight;
/* MIPI DSI */
@@ -1298,7 +1342,7 @@ struct ilk_wm_values {
*/
struct i915_runtime_pm {
bool suspended;
- bool irqs_disabled;
+ bool _irqs_disabled;
};
enum intel_pipe_crc_source {
@@ -1331,6 +1375,17 @@ struct intel_pipe_crc {
wait_queue_head_t wq;
};
+struct i915_frontbuffer_tracking {
+ struct mutex lock;
+
+ /*
+ * Tracking bits for delayed frontbuffer flushing du to gpu activity or
+ * scheduled flips.
+ */
+ unsigned busy_bits;
+ unsigned flip_bits;
+};
+
struct drm_i915_private {
struct drm_device *dev;
struct kmem_cache *slab;
@@ -1362,6 +1417,7 @@ struct drm_i915_private {
struct pci_dev *bridge_dev;
struct intel_engine_cs ring[I915_NUM_RINGS];
+ struct drm_i915_gem_object *semaphore_obj;
uint32_t last_seqno, next_seqno;
drm_dma_handle_t *status_page_dmah;
@@ -1370,6 +1426,9 @@ 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. */
@@ -1389,7 +1448,6 @@ struct drm_i915_private {
u32 pipestat_irq_mask[I915_MAX_PIPES];
struct work_struct hotplug_work;
- bool enable_hotplug_processing;
struct {
unsigned long hpd_last_jiffies;
int hpd_cnt;
@@ -1466,7 +1524,6 @@ struct drm_i915_private {
int num_shared_dpll;
struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
- struct intel_ddi_plls ddi_plls;
int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
/* Reclocking support */
@@ -1474,6 +1531,9 @@ struct drm_i915_private {
bool lvds_downclock_avail;
/* indicates the reduced downclock for LVDS*/
int lvds_downclock;
+
+ struct i915_frontbuffer_tracking fb_tracking;
+
u16 orig_clock;
bool mchbar_need_disable;
@@ -1540,6 +1600,20 @@ struct drm_i915_private {
struct i915_runtime_pm pm;
+ struct intel_digital_port *hpd_irq_port[I915_MAX_PORTS];
+ u32 long_hpd_port_mask;
+ u32 short_hpd_port_mask;
+ struct work_struct dig_port_work;
+
+ /*
+ * if we get a HPD irq from DP and a HPD irq from non-DP
+ * the non-DP HPD could block the workqueue on a mode config
+ * mutex getting, that userspace may have taken. However
+ * userspace is waiting on the DP workqueue to run which is
+ * blocked behind the non-DP one.
+ */
+ struct workqueue_struct *dp_wq;
+
/* Old dri1 support infrastructure, beware the dragons ya fools entering
* here! */
struct i915_dri1_state dri1;
@@ -1591,6 +1665,28 @@ struct drm_i915_gem_object_ops {
void (*release)(struct drm_i915_gem_object *);
};
+/*
+ * Frontbuffer tracking bits. Set in obj->frontbuffer_bits while a gem bo is
+ * considered to be the frontbuffer for the given plane interface-vise. This
+ * doesn't mean that the hw necessarily already scans it out, but that any
+ * rendering (by the cpu or gpu) will land in the frontbuffer eventually.
+ *
+ * We have one bit per pipe and per scanout plane type.
+ */
+#define INTEL_FRONTBUFFER_BITS_PER_PIPE 4
+#define INTEL_FRONTBUFFER_BITS \
+ (INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES)
+#define INTEL_FRONTBUFFER_PRIMARY(pipe) \
+ (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+#define INTEL_FRONTBUFFER_CURSOR(pipe) \
+ (1 << (1 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_SPRITE(pipe) \
+ (1 << (2 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_OVERLAY(pipe) \
+ (1 << (3 +(INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))))
+#define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
+ (0xf << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+
struct drm_i915_gem_object {
struct drm_gem_object base;
@@ -1661,6 +1757,12 @@ struct drm_i915_gem_object {
unsigned int pin_display:1;
/*
+ * Is the object to be mapped as read-only to the GPU
+ * Only honoured if hardware has relevant pte bit
+ */
+ unsigned long gt_ro:1;
+
+ /*
* Is the GPU currently using a fence to access this buffer,
*/
unsigned int pending_fenced_gpu_access:1;
@@ -1672,6 +1774,8 @@ struct drm_i915_gem_object {
unsigned int has_global_gtt_mapping:1;
unsigned int has_dma_mapping:1;
+ unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS;
+
struct sg_table *pages;
int pages_pin_count;
@@ -1718,6 +1822,10 @@ struct drm_i915_gem_object {
};
#define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+void i915_gem_track_fb(struct drm_i915_gem_object *old,
+ struct drm_i915_gem_object *new,
+ unsigned frontbuffer_bits);
+
/**
* Request queue structure.
*
@@ -1939,10 +2047,8 @@ struct drm_i915_cmd_table {
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)
#define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6)
-#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >= 6 && \
- (!IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)))
-#define HAS_PPGTT(dev) (INTEL_INFO(dev)->gen >= 7 \
- && !IS_GEN8(dev))
+#define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >= 6)
+#define HAS_PPGTT(dev) (INTEL_INFO(dev)->gen >= 7 && !IS_GEN8(dev))
#define USES_PPGTT(dev) intel_enable_ppgtt(dev, false)
#define USES_FULL_PPGTT(dev) intel_enable_ppgtt(dev, true)
@@ -1997,6 +2103,8 @@ struct drm_i915_cmd_table {
#define HAS_PCH_NOP(dev) (INTEL_PCH_TYPE(dev) == PCH_NOP)
#define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE)
+#define HAS_GMCH_DISPLAY(dev) (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev))
+
/* DPF == dynamic parity feature */
#define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
#define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev))
@@ -2039,6 +2147,8 @@ struct i915_params {
bool reset;
bool disable_display;
bool disable_vtd_wa;
+ int use_mmio_flip;
+ bool mmio_debug;
};
extern struct i915_params i915 __read_mostly;
@@ -2047,12 +2157,12 @@ void i915_update_dri1_breadcrumb(struct drm_device *dev);
extern void i915_kernel_lost_context(struct drm_device * dev);
extern int i915_driver_load(struct drm_device *, unsigned long flags);
extern int i915_driver_unload(struct drm_device *);
-extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file);
extern void i915_driver_lastclose(struct drm_device * dev);
extern void i915_driver_preclose(struct drm_device *dev,
- struct drm_file *file_priv);
+ struct drm_file *file);
extern void i915_driver_postclose(struct drm_device *dev,
- struct drm_file *file_priv);
+ struct drm_file *file);
extern int i915_driver_device_is_agp(struct drm_device * dev);
#ifdef CONFIG_COMPAT
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
@@ -2083,10 +2193,12 @@ extern void intel_irq_init(struct drm_device *dev);
extern void intel_hpd_init(struct drm_device *dev);
extern void intel_uncore_sanitize(struct drm_device *dev);
-extern void intel_uncore_early_sanitize(struct drm_device *dev);
+extern void intel_uncore_early_sanitize(struct drm_device *dev,
+ bool restore_forcewake);
extern void intel_uncore_init(struct drm_device *dev);
extern void intel_uncore_check_errors(struct drm_device *dev);
extern void intel_uncore_fini(struct drm_device *dev);
+extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
void
i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
@@ -2234,6 +2346,8 @@ bool i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_requests_ring(struct intel_engine_cs *ring);
int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
bool interruptible);
+int __must_check i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno);
+
static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
{
return unlikely(atomic_read(&error->reset_counter)
@@ -2403,7 +2517,7 @@ static inline void i915_gem_context_unreference(struct intel_context *ctx)
static inline bool i915_gem_context_is_default(const struct intel_context *c)
{
- return c->id == DEFAULT_CONTEXT_ID;
+ return c->user_handle == DEFAULT_CONTEXT_HANDLE;
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
@@ -2434,7 +2548,7 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev)
/* i915_gem_stolen.c */
int i915_gem_init_stolen(struct drm_device *dev);
-int i915_gem_stolen_setup_compression(struct drm_device *dev, int size);
+int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp);
void i915_gem_stolen_cleanup_compression(struct drm_device *dev);
void i915_gem_cleanup_stolen(struct drm_device *dev);
struct drm_i915_gem_object *
@@ -2444,7 +2558,6 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
u32 stolen_offset,
u32 gtt_offset,
u32 size);
-void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj);
/* i915_gem_tiling.c */
static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
@@ -2592,8 +2705,8 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
extern void intel_init_pch_refclk(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void valleyview_set_rps(struct drm_device *dev, u8 val);
-extern int valleyview_rps_max_freq(struct drm_i915_private *dev_priv);
-extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv);
+extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
+ bool enable);
extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
extern int intel_enable_rc6(const struct drm_device *dev);
@@ -2604,6 +2717,8 @@ int i915_reg_read_ioctl(struct drm_device *dev, void *data,
int i915_get_reset_stats_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+void intel_notify_mmio_flip(struct intel_engine_cs *ring);
+
/* overlay */
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
@@ -2699,10 +2814,10 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
static inline uint32_t i915_vgacntrl_reg(struct drm_device *dev)
{
- if (HAS_PCH_SPLIT(dev))
- return CPU_VGACNTRL;
- else if (IS_VALLEYVIEW(dev))
+ if (IS_VALLEYVIEW(dev))
return VLV_VGACNTRL;
+ else if (INTEL_INFO(dev)->gen >= 5)
+ return CPU_VGACNTRL;
else
return VGACNTRL;
}
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f36126383d26..ba7f5c6bb50d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1095,7 +1095,7 @@ i915_gem_check_wedge(struct i915_gpu_error *error,
* Compare seqno against outstanding lazy request. Emit a request if they are
* equal.
*/
-static int
+int
i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno)
{
int ret;
@@ -1149,26 +1149,26 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno,
unsigned reset_counter,
bool interruptible,
- struct timespec *timeout,
+ s64 *timeout,
struct drm_i915_file_private *file_priv)
{
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
const bool irq_test_in_progress =
ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_ring_flag(ring);
- struct timespec before, now;
DEFINE_WAIT(wait);
unsigned long timeout_expire;
+ s64 before, now;
int ret;
- WARN(dev_priv->pm.irqs_disabled, "IRQs disabled\n");
+ WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
return 0;
- timeout_expire = timeout ? jiffies + timespec_to_jiffies_timeout(timeout) : 0;
+ timeout_expire = timeout ? jiffies + nsecs_to_jiffies((u64)*timeout) : 0;
- if (INTEL_INFO(dev)->gen >= 6 && can_wait_boost(file_priv)) {
+ if (INTEL_INFO(dev)->gen >= 6 && ring->id == RCS && can_wait_boost(file_priv)) {
gen6_rps_boost(dev_priv);
if (file_priv)
mod_delayed_work(dev_priv->wq,
@@ -1181,7 +1181,7 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno,
/* Record current time in case interrupted by signal, or wedged */
trace_i915_gem_request_wait_begin(ring, seqno);
- getrawmonotonic(&before);
+ before = ktime_get_raw_ns();
for (;;) {
struct timer_list timer;
@@ -1230,7 +1230,7 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno,
destroy_timer_on_stack(&timer);
}
}
- getrawmonotonic(&now);
+ now = ktime_get_raw_ns();
trace_i915_gem_request_wait_end(ring, seqno);
if (!irq_test_in_progress)
@@ -1239,10 +1239,9 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno,
finish_wait(&ring->irq_queue, &wait);
if (timeout) {
- struct timespec sleep_time = timespec_sub(now, before);
- *timeout = timespec_sub(*timeout, sleep_time);
- if (!timespec_valid(timeout)) /* i.e. negative time remains */
- set_normalized_timespec(timeout, 0, 0);
+ s64 tres = *timeout - (now - before);
+
+ *timeout = tres < 0 ? 0 : tres;
}
return ret;
@@ -1561,14 +1560,29 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (ret)
goto unpin;
- obj->fault_mappable = true;
-
+ /* Finally, remap it using the new GTT offset */
pfn = dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj);
pfn >>= PAGE_SHIFT;
- pfn += page_offset;
- /* Finally, remap it using the new GTT offset */
- ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
+ if (!obj->fault_mappable) {
+ unsigned long size = min_t(unsigned long,
+ vma->vm_end - vma->vm_start,
+ obj->base.size);
+ int i;
+
+ for (i = 0; i < size >> PAGE_SHIFT; i++) {
+ ret = vm_insert_pfn(vma,
+ (unsigned long)vma->vm_start + i * PAGE_SIZE,
+ pfn + i);
+ if (ret)
+ break;
+ }
+
+ obj->fault_mappable = true;
+ } else
+ ret = vm_insert_pfn(vma,
+ (unsigned long)vmf->virtual_address,
+ pfn + page_offset);
unpin:
i915_gem_object_ggtt_unpin(obj);
unlock:
@@ -1616,22 +1630,6 @@ out:
return ret;
}
-void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv)
-{
- struct i915_vma *vma;
-
- /*
- * Only the global gtt is relevant for gtt memory mappings, so restrict
- * list traversal to objects bound into the global address space. Note
- * that the active list should be empty, but better safe than sorry.
- */
- WARN_ON(!list_empty(&dev_priv->gtt.base.active_list));
- list_for_each_entry(vma, &dev_priv->gtt.base.active_list, mm_list)
- i915_gem_release_mmap(vma->obj);
- list_for_each_entry(vma, &dev_priv->gtt.base.inactive_list, mm_list)
- i915_gem_release_mmap(vma->obj);
-}
-
/**
* i915_gem_release_mmap - remove physical page mappings
* @obj: obj in question
@@ -1657,6 +1655,15 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
obj->fault_mappable = false;
}
+void
+i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv)
+{
+ struct drm_i915_gem_object *obj;
+
+ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
+ i915_gem_release_mmap(obj);
+}
+
uint32_t
i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
{
@@ -2059,16 +2066,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
* our own buffer, now let the real VM do its job and
* go down in flames if truly OOM.
*/
- gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD);
- gfp |= __GFP_IO | __GFP_WAIT;
-
i915_gem_shrink_all(dev_priv);
- page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+ page = shmem_read_mapping_page(mapping, i);
if (IS_ERR(page))
goto err_pages;
-
- gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
- gfp &= ~(__GFP_IO | __GFP_WAIT);
}
#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
@@ -2217,6 +2218,8 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
list_move_tail(&vma->mm_list, &vm->inactive_list);
}
+ intel_fb_obj_flush(obj, true);
+
list_del_init(&obj->ring_list);
obj->ring = NULL;
@@ -2326,7 +2329,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
u32 request_ring_position, request_start;
int ret;
- request_start = intel_ring_get_tail(ring);
+ request_start = intel_ring_get_tail(ring->buffer);
/*
* Emit any outstanding flushes - execbuf can fail to emit the flush
* after having emitted the batchbuffer command. Hence we need to fix
@@ -2347,7 +2350,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
* GPU processing the request, we never over-estimate the
* position of the head.
*/
- request_ring_position = intel_ring_get_tail(ring);
+ request_ring_position = intel_ring_get_tail(ring->buffer);
ret = ring->add_request(ring);
if (ret)
@@ -2753,16 +2756,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
struct drm_i915_gem_wait *args = data;
struct drm_i915_gem_object *obj;
struct intel_engine_cs *ring = NULL;
- struct timespec timeout_stack, *timeout = NULL;
unsigned reset_counter;
u32 seqno = 0;
int ret = 0;
- if (args->timeout_ns >= 0) {
- timeout_stack = ns_to_timespec(args->timeout_ns);
- timeout = &timeout_stack;
- }
-
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ret;
@@ -2787,9 +2784,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto out;
/* Do this after OLR check to make sure we make forward progress polling
- * on this IOCTL with a 0 timeout (like busy ioctl)
+ * on this IOCTL with a timeout <=0 (like busy ioctl)
*/
- if (!args->timeout_ns) {
+ if (args->timeout_ns <= 0) {
ret = -ETIME;
goto out;
}
@@ -2798,10 +2795,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
mutex_unlock(&dev->struct_mutex);
- ret = __wait_seqno(ring, seqno, reset_counter, true, timeout, file->driver_priv);
- if (timeout)
- args->timeout_ns = timespec_to_ns(timeout);
- return ret;
+ return __wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns,
+ file->driver_priv);
out:
drm_gem_object_unreference(&obj->base);
@@ -2838,6 +2833,8 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
idx = intel_ring_sync_index(from, to);
seqno = obj->last_read_seqno;
+ /* Optimization: Avoid semaphore sync when we are sure we already
+ * waited for an object with higher seqno */
if (seqno <= from->semaphore.sync_seqno[idx])
return 0;
@@ -2921,8 +2918,6 @@ int i915_vma_unbind(struct i915_vma *vma)
vma->unbind_vma(vma);
- i915_gem_gtt_finish_object(obj);
-
list_del_init(&vma->mm_list);
/* Avoid an unnecessary call to unbind on rebind. */
if (i915_is_ggtt(vma->vm))
@@ -2933,8 +2928,10 @@ int i915_vma_unbind(struct i915_vma *vma)
/* Since the unbound list is global, only move to that list if
* no more VMAs exist. */
- if (list_empty(&obj->vma_list))
+ if (list_empty(&obj->vma_list)) {
+ i915_gem_gtt_finish_object(obj);
list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
+ }
/* And finally now the object is completely decoupled from this vma,
* we can drop its hold on the backing storage and allow it to be
@@ -3546,6 +3543,8 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
old_write_domain = obj->base.write_domain;
obj->base.write_domain = 0;
+ intel_fb_obj_flush(obj, false);
+
trace_i915_gem_object_change_domain(obj,
obj->base.read_domains,
old_write_domain);
@@ -3567,6 +3566,8 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj,
old_write_domain = obj->base.write_domain;
obj->base.write_domain = 0;
+ intel_fb_obj_flush(obj, false);
+
trace_i915_gem_object_change_domain(obj,
obj->base.read_domains,
old_write_domain);
@@ -3620,6 +3621,9 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
obj->dirty = 1;
}
+ if (write)
+ intel_fb_obj_invalidate(obj, NULL);
+
trace_i915_gem_object_change_domain(obj,
old_read_domains,
old_write_domain);
@@ -3956,6 +3960,9 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
}
+ if (write)
+ intel_fb_obj_invalidate(obj, NULL);
+
trace_i915_gem_object_change_domain(obj,
old_read_domains,
old_write_domain);
@@ -4444,13 +4451,14 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
if (obj->stolen)
i915_gem_object_unpin_pages(obj);
+ WARN_ON(obj->frontbuffer_bits);
+
if (WARN_ON(obj->pages_pin_count))
obj->pages_pin_count = 0;
if (discard_backing_storage(obj))
obj->madv = I915_MADV_DONTNEED;
i915_gem_object_put_pages(obj);
i915_gem_object_free_mmap_offset(obj);
- i915_gem_object_release_stolen(obj);
BUG_ON(obj->pages);
@@ -4537,7 +4545,7 @@ i915_gem_suspend(struct drm_device *dev)
del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
cancel_delayed_work_sync(&dev_priv->mm.retire_work);
- cancel_delayed_work_sync(&dev_priv->mm.idle_work);
+ flush_delayed_work(&dev_priv->mm.idle_work);
return 0;
@@ -4928,6 +4936,8 @@ i915_gem_load(struct drm_device *dev)
dev_priv->mm.oom_notifier.notifier_call = i915_gem_shrinker_oom;
register_oom_notifier(&dev_priv->mm.oom_notifier);
+
+ mutex_init(&dev_priv->fb_tracking.lock);
}
void i915_gem_release(struct drm_device *dev, struct drm_file *file)
@@ -4989,6 +4999,23 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file)
return ret;
}
+void i915_gem_track_fb(struct drm_i915_gem_object *old,
+ struct drm_i915_gem_object *new,
+ unsigned frontbuffer_bits)
+{
+ if (old) {
+ WARN_ON(!mutex_is_locked(&old->base.dev->struct_mutex));
+ WARN_ON(!(old->frontbuffer_bits & frontbuffer_bits));
+ old->frontbuffer_bits &= ~frontbuffer_bits;
+ }
+
+ if (new) {
+ WARN_ON(!mutex_is_locked(&new->base.dev->struct_mutex));
+ WARN_ON(new->frontbuffer_bits & frontbuffer_bits);
+ new->frontbuffer_bits |= frontbuffer_bits;
+ }
+}
+
static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
{
if (!mutex_is_locked(mutex))
@@ -5071,12 +5098,13 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o,
vm == &dev_priv->mm.aliasing_ppgtt->base)
vm = &dev_priv->gtt.base;
- BUG_ON(list_empty(&o->vma_list));
list_for_each_entry(vma, &o->vma_list, vma_link) {
if (vma->vm == vm)
return vma->node.start;
}
+ WARN(1, "%s vma for this object not found.\n",
+ i915_is_ggtt(vm) ? "global" : "ppgtt");
return -1;
}
@@ -5157,8 +5185,11 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr)
bool was_interruptible;
bool unlock;
- while (!i915_gem_shrinker_lock(dev, &unlock) && --timeout)
+ while (!i915_gem_shrinker_lock(dev, &unlock) && --timeout) {
schedule_timeout_killable(1);
+ if (fatal_signal_pending(current))
+ return NOTIFY_DONE;
+ }
if (timeout == 0) {
pr_err("Unable to purge GPU memory due lock contention.\n");
return NOTIFY_DONE;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index a5ddf3bce9c3..3b99390e467a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -182,22 +182,50 @@ void i915_gem_context_free(struct kref *ctx_ref)
typeof(*ctx), ref);
struct i915_hw_ppgtt *ppgtt = NULL;
- if (ctx->obj) {
+ if (ctx->legacy_hw_ctx.rcs_state) {
/* We refcount even the aliasing PPGTT to keep the code symmetric */
- if (USES_PPGTT(ctx->obj->base.dev))
+ if (USES_PPGTT(ctx->legacy_hw_ctx.rcs_state->base.dev))
ppgtt = ctx_to_ppgtt(ctx);
-
- /* XXX: Free up the object before tearing down the address space, in
- * case we're bound in the PPGTT */
- drm_gem_object_unreference(&ctx->obj->base);
}
if (ppgtt)
kref_put(&ppgtt->ref, ppgtt_release);
+ if (ctx->legacy_hw_ctx.rcs_state)
+ drm_gem_object_unreference(&ctx->legacy_hw_ctx.rcs_state->base);
list_del(&ctx->link);
kfree(ctx);
}
+static struct drm_i915_gem_object *
+i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
+{
+ struct drm_i915_gem_object *obj;
+ int ret;
+
+ obj = i915_gem_alloc_object(dev, size);
+ if (obj == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * Try to make the context utilize L3 as well as LLC.
+ *
+ * On VLV we don't have L3 controls in the PTEs so we
+ * shouldn't touch the cache level, especially as that
+ * would make the object snooped which might have a
+ * negative performance impact.
+ */
+ if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev)) {
+ ret = i915_gem_object_set_cache_level(obj, I915_CACHE_L3_LLC);
+ /* Failure shouldn't ever happen this early */
+ if (WARN_ON(ret)) {
+ drm_gem_object_unreference(&obj->base);
+ return ERR_PTR(ret);
+ }
+ }
+
+ return obj;
+}
+
static struct i915_hw_ppgtt *
create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx)
{
@@ -234,40 +262,26 @@ __create_hw_context(struct drm_device *dev,
list_add_tail(&ctx->link, &dev_priv->context_list);
if (dev_priv->hw_context_size) {
- ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
- if (ctx->obj == NULL) {
- ret = -ENOMEM;
+ struct drm_i915_gem_object *obj =
+ i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size);
+ if (IS_ERR(obj)) {
+ ret = PTR_ERR(obj);
goto err_out;
}
-
- /*
- * Try to make the context utilize L3 as well as LLC.
- *
- * On VLV we don't have L3 controls in the PTEs so we
- * shouldn't touch the cache level, especially as that
- * would make the object snooped which might have a
- * negative performance impact.
- */
- if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev)) {
- ret = i915_gem_object_set_cache_level(ctx->obj,
- I915_CACHE_L3_LLC);
- /* Failure shouldn't ever happen this early */
- if (WARN_ON(ret))
- goto err_out;
- }
+ ctx->legacy_hw_ctx.rcs_state = obj;
}
/* Default context will never have a file_priv */
if (file_priv != NULL) {
ret = idr_alloc(&file_priv->context_idr, ctx,
- DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
+ DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL);
if (ret < 0)
goto err_out;
} else
- ret = DEFAULT_CONTEXT_ID;
+ ret = DEFAULT_CONTEXT_HANDLE;
ctx->file_priv = file_priv;
- ctx->id = ret;
+ ctx->user_handle = ret;
/* NB: Mark all slices as needing a remap so that when the context first
* loads it will restore whatever remap state already exists. If there
* is no remap info, it will be a NOP. */
@@ -301,7 +315,7 @@ i915_gem_create_context(struct drm_device *dev,
if (IS_ERR(ctx))
return ctx;
- if (is_global_default_ctx && ctx->obj) {
+ if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) {
/* We may need to do things with the shrinker which
* require us to immediately switch back to the default
* context. This can cause a problem as pinning the
@@ -309,7 +323,7 @@ i915_gem_create_context(struct drm_device *dev,
* be available. To avoid this we always pin the default
* context.
*/
- ret = i915_gem_obj_ggtt_pin(ctx->obj,
+ ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
get_context_alignment(dev), 0);
if (ret) {
DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
@@ -349,8 +363,8 @@ i915_gem_create_context(struct drm_device *dev,
return ctx;
err_unpin:
- if (is_global_default_ctx && ctx->obj)
- i915_gem_object_ggtt_unpin(ctx->obj);
+ if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
+ i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
err_destroy:
i915_gem_context_unreference(ctx);
return ERR_PTR(ret);
@@ -366,23 +380,27 @@ void i915_gem_context_reset(struct drm_device *dev)
for (i = 0; i < I915_NUM_RINGS; i++) {
struct intel_engine_cs *ring = &dev_priv->ring[i];
struct intel_context *dctx = ring->default_context;
+ struct intel_context *lctx = ring->last_context;
/* Do a fake switch to the default context */
- if (ring->last_context == dctx)
+ if (lctx == dctx)
continue;
- if (!ring->last_context)
+ if (!lctx)
continue;
- if (dctx->obj && i == RCS) {
- WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
+ if (dctx->legacy_hw_ctx.rcs_state && i == RCS) {
+ WARN_ON(i915_gem_obj_ggtt_pin(dctx->legacy_hw_ctx.rcs_state,
get_context_alignment(dev), 0));
/* Fake a finish/inactive */
- dctx->obj->base.write_domain = 0;
- dctx->obj->active = 0;
+ dctx->legacy_hw_ctx.rcs_state->base.write_domain = 0;
+ dctx->legacy_hw_ctx.rcs_state->active = 0;
}
- i915_gem_context_unreference(ring->last_context);
+ if (lctx->legacy_hw_ctx.rcs_state && i == RCS)
+ i915_gem_object_ggtt_unpin(lctx->legacy_hw_ctx.rcs_state);
+
+ i915_gem_context_unreference(lctx);
i915_gem_context_reference(dctx);
ring->last_context = dctx;
}
@@ -429,7 +447,7 @@ void i915_gem_context_fini(struct drm_device *dev)
struct intel_context *dctx = dev_priv->ring[RCS].default_context;
int i;
- if (dctx->obj) {
+ if (dctx->legacy_hw_ctx.rcs_state) {
/* The only known way to stop the gpu from accessing the hw context is
* to reset it. Do this as the very last operation to avoid confusing
* other code, leading to spurious errors. */
@@ -444,13 +462,13 @@ void i915_gem_context_fini(struct drm_device *dev)
WARN_ON(!dev_priv->ring[RCS].last_context);
if (dev_priv->ring[RCS].last_context == dctx) {
/* Fake switch to NULL context */
- WARN_ON(dctx->obj->active);
- i915_gem_object_ggtt_unpin(dctx->obj);
+ WARN_ON(dctx->legacy_hw_ctx.rcs_state->active);
+ i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state);
i915_gem_context_unreference(dctx);
dev_priv->ring[RCS].last_context = NULL;
}
- i915_gem_object_ggtt_unpin(dctx->obj);
+ i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state);
}
for (i = 0; i < I915_NUM_RINGS; i++) {
@@ -570,7 +588,7 @@ mi_set_context(struct intel_engine_cs *ring,
intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_SET_CONTEXT);
- intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->obj) |
+ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->legacy_hw_ctx.rcs_state) |
MI_MM_SPACE_GTT |
MI_SAVE_EXT_STATE_EN |
MI_RESTORE_EXT_STATE_EN |
@@ -602,16 +620,16 @@ static int do_switch(struct intel_engine_cs *ring,
int ret, i;
if (from != NULL && ring == &dev_priv->ring[RCS]) {
- BUG_ON(from->obj == NULL);
- BUG_ON(!i915_gem_obj_is_pinned(from->obj));
+ BUG_ON(from->legacy_hw_ctx.rcs_state == NULL);
+ BUG_ON(!i915_gem_obj_is_pinned(from->legacy_hw_ctx.rcs_state));
}
- if (from == to && from->last_ring == ring && !to->remap_slice)
+ if (from == to && !to->remap_slice)
return 0;
/* Trying to pin first makes error handling easier. */
if (ring == &dev_priv->ring[RCS]) {
- ret = i915_gem_obj_ggtt_pin(to->obj,
+ ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state,
get_context_alignment(ring->dev), 0);
if (ret)
return ret;
@@ -644,17 +662,17 @@ static int do_switch(struct intel_engine_cs *ring,
*
* XXX: We need a real interface to do this instead of trickery.
*/
- ret = i915_gem_object_set_to_gtt_domain(to->obj, false);
+ ret = i915_gem_object_set_to_gtt_domain(to->legacy_hw_ctx.rcs_state, false);
if (ret)
goto unpin_out;
- if (!to->obj->has_global_gtt_mapping) {
- struct i915_vma *vma = i915_gem_obj_to_vma(to->obj,
+ if (!to->legacy_hw_ctx.rcs_state->has_global_gtt_mapping) {
+ struct i915_vma *vma = i915_gem_obj_to_vma(to->legacy_hw_ctx.rcs_state,
&dev_priv->gtt.base);
- vma->bind_vma(vma, to->obj->cache_level, GLOBAL_BIND);
+ vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, GLOBAL_BIND);
}
- if (!to->is_initialized || i915_gem_context_is_default(to))
+ if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT;
ret = mi_set_context(ring, to, hw_flags);
@@ -680,8 +698,8 @@ static int do_switch(struct intel_engine_cs *ring,
* MI_SET_CONTEXT instead of when the next seqno has completed.
*/
if (from != NULL) {
- from->obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
- i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->obj), ring);
+ from->legacy_hw_ctx.rcs_state->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+ i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->legacy_hw_ctx.rcs_state), ring);
/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
* whole damn pipeline, we don't need to explicitly mark the
* object dirty. The only exception is that the context must be
@@ -689,21 +707,20 @@ static int do_switch(struct intel_engine_cs *ring,
* able to defer doing this until we know the object would be
* swapped, but there is no way to do that yet.
*/
- from->obj->dirty = 1;
- BUG_ON(from->obj->ring != ring);
+ from->legacy_hw_ctx.rcs_state->dirty = 1;
+ BUG_ON(from->legacy_hw_ctx.rcs_state->ring != ring);
/* obj is kept alive until the next request by its active ref */
- i915_gem_object_ggtt_unpin(from->obj);
+ i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);
i915_gem_context_unreference(from);
}
- uninitialized = !to->is_initialized && from == NULL;
- to->is_initialized = true;
+ uninitialized = !to->legacy_hw_ctx.initialized && from == NULL;
+ to->legacy_hw_ctx.initialized = true;
done:
i915_gem_context_reference(to);
ring->last_context = to;
- to->last_ring = ring;
if (uninitialized) {
ret = i915_gem_render_state_init(ring);
@@ -715,7 +732,7 @@ done:
unpin_out:
if (ring->id == RCS)
- i915_gem_object_ggtt_unpin(to->obj);
+ i915_gem_object_ggtt_unpin(to->legacy_hw_ctx.rcs_state);
return ret;
}
@@ -736,7 +753,7 @@ int i915_switch_context(struct intel_engine_cs *ring,
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
- if (to->obj == NULL) { /* We have the fake context */
+ if (to->legacy_hw_ctx.rcs_state == NULL) { /* We have the fake context */
if (to != ring->last_context) {
i915_gem_context_reference(to);
if (ring->last_context)
@@ -774,7 +791,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
if (IS_ERR(ctx))
return PTR_ERR(ctx);
- args->ctx_id = ctx->id;
+ args->ctx_id = ctx->user_handle;
DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id);
return 0;
@@ -788,7 +805,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
struct intel_context *ctx;
int ret;
- if (args->ctx_id == DEFAULT_CONTEXT_ID)
+ if (args->ctx_id == DEFAULT_CONTEXT_HANDLE)
return -ENOENT;
ret = i915_mutex_lock_interruptible(dev);
@@ -801,7 +818,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
return PTR_ERR(ctx);
}
- idr_remove(&ctx->file_priv->context_idr, ctx->id);
+ idr_remove(&ctx->file_priv->context_idr, ctx->user_handle);
i915_gem_context_unreference(ctx);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 580aa42443ed..82a1f4b57778 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -237,7 +237,8 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
return ERR_PTR(ret);
}
- return dma_buf_export(gem_obj, &i915_dmabuf_ops, gem_obj->size, flags);
+ return dma_buf_export(gem_obj, &i915_dmabuf_ops, gem_obj->size, flags,
+ NULL);
}
static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 3a30133f93e8..60998fc4e5b2 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -938,7 +938,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
struct intel_context *ctx = NULL;
struct i915_ctx_hang_stats *hs;
- if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_ID)
+ if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE)
return ERR_PTR(-EINVAL);
ctx = i915_gem_context_get(file->driver_priv, ctx_id);
@@ -975,10 +975,8 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
if (obj->base.write_domain) {
obj->dirty = 1;
obj->last_write_seqno = intel_ring_get_seqno(ring);
- /* check for potential scanout */
- if (i915_gem_obj_ggtt_bound(obj) &&
- i915_gem_obj_to_ggtt(obj)->pin_count)
- intel_mark_fb_busy(obj, ring);
+
+ intel_fb_obj_invalidate(obj, ring);
/* update for the implicit flush after a batch */
obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
@@ -1028,6 +1026,163 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev,
return 0;
}
+static int
+legacy_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
+ struct intel_engine_cs *ring,
+ struct intel_context *ctx,
+ struct drm_i915_gem_execbuffer2 *args,
+ struct list_head *vmas,
+ struct drm_i915_gem_object *batch_obj,
+ u64 exec_start, u32 flags)
+{
+ struct drm_clip_rect *cliprects = NULL;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u64 exec_len;
+ int instp_mode;
+ u32 instp_mask;
+ int i, ret = 0;
+
+ if (args->num_cliprects != 0) {
+ if (ring != &dev_priv->ring[RCS]) {
+ DRM_DEBUG("clip rectangles are only valid with the render ring\n");
+ return -EINVAL;
+ }
+
+ if (INTEL_INFO(dev)->gen >= 5) {
+ DRM_DEBUG("clip rectangles are only valid on pre-gen5\n");
+ return -EINVAL;
+ }
+
+ if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
+ DRM_DEBUG("execbuf with %u cliprects\n",
+ args->num_cliprects);
+ return -EINVAL;
+ }
+
+ cliprects = kcalloc(args->num_cliprects,
+ sizeof(*cliprects),
+ GFP_KERNEL);
+ if (cliprects == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ if (copy_from_user(cliprects,
+ to_user_ptr(args->cliprects_ptr),
+ sizeof(*cliprects)*args->num_cliprects)) {
+ ret = -EFAULT;
+ goto error;
+ }
+ } else {
+ if (args->DR4 == 0xffffffff) {
+ DRM_DEBUG("UXA submitting garbage DR4, fixing up\n");
+ args->DR4 = 0;
+ }
+
+ if (args->DR1 || args->DR4 || args->cliprects_ptr) {
+ DRM_DEBUG("0 cliprects but dirt in cliprects fields\n");
+ return -EINVAL;
+ }
+ }
+
+ ret = i915_gem_execbuffer_move_to_gpu(ring, vmas);
+ if (ret)
+ goto error;
+
+ ret = i915_switch_context(ring, ctx);
+ if (ret)
+ goto error;
+
+ instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+ instp_mask = I915_EXEC_CONSTANTS_MASK;
+ switch (instp_mode) {
+ case I915_EXEC_CONSTANTS_REL_GENERAL:
+ case I915_EXEC_CONSTANTS_ABSOLUTE:
+ case I915_EXEC_CONSTANTS_REL_SURFACE:
+ if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
+ DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (instp_mode != dev_priv->relative_constants_mode) {
+ if (INTEL_INFO(dev)->gen < 4) {
+ DRM_DEBUG("no rel constants on pre-gen4\n");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (INTEL_INFO(dev)->gen > 5 &&
+ instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
+ DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* The HW changed the meaning on this bit on gen6 */
+ if (INTEL_INFO(dev)->gen >= 6)
+ instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
+ }
+ break;
+ default:
+ DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (ring == &dev_priv->ring[RCS] &&
+ instp_mode != dev_priv->relative_constants_mode) {
+ ret = intel_ring_begin(ring, 4);
+ if (ret)
+ goto error;
+
+ intel_ring_emit(ring, MI_NOOP);
+ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
+ intel_ring_emit(ring, INSTPM);
+ intel_ring_emit(ring, instp_mask << 16 | instp_mode);
+ intel_ring_advance(ring);
+
+ dev_priv->relative_constants_mode = instp_mode;
+ }
+
+ if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
+ ret = i915_reset_gen7_sol_offsets(dev, ring);
+ if (ret)
+ goto error;
+ }
+
+ exec_len = args->batch_len;
+ if (cliprects) {
+ for (i = 0; i < args->num_cliprects; i++) {
+ ret = i915_emit_box(dev, &cliprects[i],
+ args->DR1, args->DR4);
+ if (ret)
+ goto error;
+
+ ret = ring->dispatch_execbuffer(ring,
+ exec_start, exec_len,
+ flags);
+ if (ret)
+ goto error;
+ }
+ } else {
+ ret = ring->dispatch_execbuffer(ring,
+ exec_start, exec_len,
+ flags);
+ if (ret)
+ return ret;
+ }
+
+ trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
+
+ i915_gem_execbuffer_move_to_active(vmas, ring);
+ i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
+
+error:
+ kfree(cliprects);
+ return ret;
+}
+
/**
* Find one BSD ring to dispatch the corresponding BSD command.
* The Ring ID is returned.
@@ -1087,14 +1242,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_private *dev_priv = dev->dev_private;
struct eb_vmas *eb;
struct drm_i915_gem_object *batch_obj;
- struct drm_clip_rect *cliprects = NULL;
struct intel_engine_cs *ring;
struct intel_context *ctx;
struct i915_address_space *vm;
const u32 ctx_id = i915_execbuffer2_get_context_id(*args);
- u64 exec_start = args->batch_start_offset, exec_len;
- u32 mask, flags;
- int ret, mode, i;
+ u64 exec_start = args->batch_start_offset;
+ u32 flags;
+ int ret;
bool need_relocs;
if (!i915_gem_check_execbuffer(args))
@@ -1138,87 +1292,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
- mode = args->flags & I915_EXEC_CONSTANTS_MASK;
- mask = I915_EXEC_CONSTANTS_MASK;
- switch (mode) {
- case I915_EXEC_CONSTANTS_REL_GENERAL:
- case I915_EXEC_CONSTANTS_ABSOLUTE:
- case I915_EXEC_CONSTANTS_REL_SURFACE:
- if (mode != 0 && ring != &dev_priv->ring[RCS]) {
- DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
- return -EINVAL;
- }
-
- if (mode != dev_priv->relative_constants_mode) {
- if (INTEL_INFO(dev)->gen < 4) {
- DRM_DEBUG("no rel constants on pre-gen4\n");
- return -EINVAL;
- }
-
- if (INTEL_INFO(dev)->gen > 5 &&
- mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
- DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
- return -EINVAL;
- }
-
- /* The HW changed the meaning on this bit on gen6 */
- if (INTEL_INFO(dev)->gen >= 6)
- mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
- }
- break;
- default:
- DRM_DEBUG("execbuf with unknown constants: %d\n", mode);
- return -EINVAL;
- }
-
if (args->buffer_count < 1) {
DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count);
return -EINVAL;
}
- if (args->num_cliprects != 0) {
- if (ring != &dev_priv->ring[RCS]) {
- DRM_DEBUG("clip rectangles are only valid with the render ring\n");
- return -EINVAL;
- }
-
- if (INTEL_INFO(dev)->gen >= 5) {
- DRM_DEBUG("clip rectangles are only valid on pre-gen5\n");
- return -EINVAL;
- }
-
- if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
- DRM_DEBUG("execbuf with %u cliprects\n",
- args->num_cliprects);
- return -EINVAL;
- }
-
- cliprects = kcalloc(args->num_cliprects,
- sizeof(*cliprects),
- GFP_KERNEL);
- if (cliprects == NULL) {
- ret = -ENOMEM;
- goto pre_mutex_err;
- }
-
- if (copy_from_user(cliprects,
- to_user_ptr(args->cliprects_ptr),
- sizeof(*cliprects)*args->num_cliprects)) {
- ret = -EFAULT;
- goto pre_mutex_err;
- }
- } else {
- if (args->DR4 == 0xffffffff) {
- DRM_DEBUG("UXA submitting garbage DR4, fixing up\n");
- args->DR4 = 0;
- }
-
- if (args->DR1 || args->DR4 || args->cliprects_ptr) {
- DRM_DEBUG("0 cliprects but dirt in cliprects fields\n");
- return -EINVAL;
- }
- }
-
intel_runtime_pm_get(dev_priv);
ret = i915_mutex_lock_interruptible(dev);
@@ -1322,63 +1400,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
else
exec_start += i915_gem_obj_offset(batch_obj, vm);
- ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas);
+ ret = legacy_ringbuffer_submission(dev, file, ring, ctx,
+ args, &eb->vmas, batch_obj, exec_start, flags);
if (ret)
goto err;
- ret = i915_switch_context(ring, ctx);
- if (ret)
- goto err;
-
- if (ring == &dev_priv->ring[RCS] &&
- mode != dev_priv->relative_constants_mode) {
- ret = intel_ring_begin(ring, 4);
- if (ret)
- goto err;
-
- intel_ring_emit(ring, MI_NOOP);
- intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
- intel_ring_emit(ring, INSTPM);
- intel_ring_emit(ring, mask << 16 | mode);
- intel_ring_advance(ring);
-
- dev_priv->relative_constants_mode = mode;
- }
-
- if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
- ret = i915_reset_gen7_sol_offsets(dev, ring);
- if (ret)
- goto err;
- }
-
-
- exec_len = args->batch_len;
- if (cliprects) {
- for (i = 0; i < args->num_cliprects; i++) {
- ret = i915_emit_box(dev, &cliprects[i],
- args->DR1, args->DR4);
- if (ret)
- goto err;
-
- ret = ring->dispatch_execbuffer(ring,
- exec_start, exec_len,
- flags);
- if (ret)
- goto err;
- }
- } else {
- ret = ring->dispatch_execbuffer(ring,
- exec_start, exec_len,
- flags);
- if (ret)
- goto err;
- }
-
- trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
-
- i915_gem_execbuffer_move_to_active(&eb->vmas, ring);
- i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
-
err:
/* the request owns the ref now */
i915_gem_context_unreference(ctx);
@@ -1387,8 +1413,6 @@ err:
mutex_unlock(&dev->struct_mutex);
pre_mutex_err:
- kfree(cliprects);
-
/* intel_gpu_busy should also get a ref, so it will free when the device
* is really idle. */
intel_runtime_pm_put(dev_priv);
@@ -1525,7 +1549,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list);
if (!ret) {
/* Copy the new buffer offsets back to the user's exec list. */
- struct drm_i915_gem_exec_object2 *user_exec_list =
+ struct drm_i915_gem_exec_object2 __user *user_exec_list =
to_user_ptr(args->buffers_ptr);
int i;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 8b3cde703364..1411613f2174 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -63,6 +63,13 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt)
}
#endif
+ /* Early VLV doesn't have this */
+ if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) &&
+ dev->pdev->revision < 0xb) {
+ DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n");
+ return 0;
+ }
+
return HAS_ALIASING_PPGTT(dev) ? 1 : 0;
}
@@ -110,7 +117,7 @@ static inline gen8_ppgtt_pde_t gen8_pde_encode(struct drm_device *dev,
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
- bool valid)
+ bool valid, u32 unused)
{
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -132,7 +139,7 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
- bool valid)
+ bool valid, u32 unused)
{
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -156,7 +163,7 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
- bool valid)
+ bool valid, u32 flags)
{
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -164,7 +171,8 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
/* Mark the page as writeable. Other platforms don't have a
* setting for read-only/writable, so this matches that behavior.
*/
- pte |= BYT_PTE_WRITEABLE;
+ if (!(flags & PTE_READ_ONLY))
+ pte |= BYT_PTE_WRITEABLE;
if (level != I915_CACHE_NONE)
pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
@@ -174,7 +182,7 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
- bool valid)
+ bool valid, u32 unused)
{
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= HSW_PTE_ADDR_ENCODE(addr);
@@ -187,7 +195,7 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
- bool valid)
+ bool valid, u32 unused)
{
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= HSW_PTE_ADDR_ENCODE(addr);
@@ -301,7 +309,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
struct sg_table *pages,
uint64_t start,
- enum i915_cache_level cache_level)
+ enum i915_cache_level cache_level, u32 unused)
{
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
@@ -639,7 +647,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
uint32_t pd_entry;
int pte, pde;
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
@@ -941,7 +949,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
unsigned last_pte, i;
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
while (num_entries) {
last_pte = first_pte + num_entries;
@@ -964,7 +972,7 @@ 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,
uint64_t start,
- enum i915_cache_level cache_level)
+ enum i915_cache_level cache_level, u32 flags)
{
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
@@ -981,7 +989,8 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
pt_vaddr[act_pte] =
vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
- cache_level, true);
+ cache_level, true, flags);
+
if (++act_pte == I915_PPGTT_PT_ENTRIES) {
kunmap_atomic(pt_vaddr);
pt_vaddr = NULL;
@@ -1218,8 +1227,12 @@ ppgtt_bind_vma(struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
{
+ /* Currently applicable only to VLV */
+ if (vma->obj->gt_ro)
+ flags |= PTE_READ_ONLY;
+
vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
- cache_level);
+ cache_level, flags);
}
static void ppgtt_unbind_vma(struct i915_vma *vma)
@@ -1394,7 +1407,7 @@ static inline void gen8_set_pte(void __iomem *addr, gen8_gtt_pte_t pte)
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
struct sg_table *st,
uint64_t start,
- enum i915_cache_level level)
+ enum i915_cache_level level, u32 unused)
{
struct drm_i915_private *dev_priv = vm->dev->dev_private;
unsigned first_entry = start >> PAGE_SHIFT;
@@ -1402,7 +1415,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
(gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
int i = 0;
struct sg_page_iter sg_iter;
- dma_addr_t addr = 0;
+ dma_addr_t addr = 0; /* shut up gcc */
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
addr = sg_dma_address(sg_iter.sg) +
@@ -1440,7 +1453,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
struct sg_table *st,
uint64_t start,
- enum i915_cache_level level)
+ enum i915_cache_level level, u32 flags)
{
struct drm_i915_private *dev_priv = vm->dev->dev_private;
unsigned first_entry = start >> PAGE_SHIFT;
@@ -1448,11 +1461,11 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
(gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
int i = 0;
struct sg_page_iter sg_iter;
- dma_addr_t addr;
+ dma_addr_t addr = 0;
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
addr = sg_page_iter_dma_address(&sg_iter);
- iowrite32(vm->pte_encode(addr, level, true), &gtt_entries[i]);
+ iowrite32(vm->pte_encode(addr, level, true, flags), &gtt_entries[i]);
i++;
}
@@ -1462,9 +1475,10 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
* of NUMA access patterns. Therefore, even with the way we assume
* hardware should work, we must keep this posting read for paranoia.
*/
- if (i != 0)
- WARN_ON(readl(&gtt_entries[i-1]) !=
- vm->pte_encode(addr, level, true));
+ if (i != 0) {
+ unsigned long gtt = readl(&gtt_entries[i-1]);
+ WARN_ON(gtt != vm->pte_encode(addr, level, true, flags));
+ }
/* This next bit makes the above posting read even more important. We
* want to flush the TLBs only after we're certain all the PTE updates
@@ -1518,7 +1532,7 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
first_entry, num_entries, max_entries))
num_entries = max_entries;
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch);
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch, 0);
for (i = 0; i < num_entries; i++)
iowrite32(scratch_pte, &gtt_base[i]);
@@ -1567,6 +1581,10 @@ static void ggtt_bind_vma(struct i915_vma *vma,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj = vma->obj;
+ /* Currently applicable only to VLV */
+ if (obj->gt_ro)
+ flags |= PTE_READ_ONLY;
+
/* If there is no aliasing PPGTT, or the caller needs a global mapping,
* or we have a global mapping already but the cacheability flags have
* changed, set the global PTEs.
@@ -1583,7 +1601,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
(cache_level != obj->cache_level)) {
vma->vm->insert_entries(vma->vm, obj->pages,
vma->node.start,
- cache_level);
+ cache_level, flags);
obj->has_global_gtt_mapping = 1;
}
}
@@ -1595,7 +1613,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
appgtt->base.insert_entries(&appgtt->base,
vma->obj->pages,
vma->node.start,
- cache_level);
+ cache_level, flags);
vma->obj->has_aliasing_ppgtt_mapping = 1;
}
}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 1b96a06be3cb..8d6f7c18c404 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -154,6 +154,7 @@ struct i915_vma {
void (*unbind_vma)(struct i915_vma *vma);
/* Map an object into an address space with the given cache flags. */
#define GLOBAL_BIND (1<<0)
+#define PTE_READ_ONLY (1<<1)
void (*bind_vma)(struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags);
@@ -197,7 +198,7 @@ struct i915_address_space {
/* FIXME: Need a more generic return type */
gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
enum i915_cache_level level,
- bool valid); /* Create a valid PTE */
+ bool valid, u32 flags); /* Create a valid PTE */
void (*clear_range)(struct i915_address_space *vm,
uint64_t start,
uint64_t length,
@@ -205,7 +206,7 @@ struct i915_address_space {
void (*insert_entries)(struct i915_address_space *vm,
struct sg_table *st,
uint64_t start,
- enum i915_cache_level cache_level);
+ enum i915_cache_level cache_level, u32 flags);
void (*cleanup)(struct i915_address_space *vm);
};
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 3521f998a178..e60be3f552a6 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -28,64 +28,13 @@
#include "i915_drv.h"
#include "intel_renderstate.h"
-struct i915_render_state {
+struct render_state {
+ const struct intel_renderstate_rodata *rodata;
struct drm_i915_gem_object *obj;
- unsigned long ggtt_offset;
- void *batch;
- u32 size;
- u32 len;
+ u64 ggtt_offset;
+ int gen;
};
-static struct i915_render_state *render_state_alloc(struct drm_device *dev)
-{
- struct i915_render_state *so;
- struct page *page;
- int ret;
-
- so = kzalloc(sizeof(*so), GFP_KERNEL);
- if (!so)
- return ERR_PTR(-ENOMEM);
-
- so->obj = i915_gem_alloc_object(dev, 4096);
- if (so->obj == NULL) {
- ret = -ENOMEM;
- goto free;
- }
- so->size = 4096;
-
- ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
- if (ret)
- goto free_gem;
-
- BUG_ON(so->obj->pages->nents != 1);
- page = sg_page(so->obj->pages->sgl);
-
- so->batch = kmap(page);
- if (!so->batch) {
- ret = -ENOMEM;
- goto unpin;
- }
-
- so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj);
-
- return so;
-unpin:
- i915_gem_object_ggtt_unpin(so->obj);
-free_gem:
- drm_gem_object_unreference(&so->obj->base);
-free:
- kfree(so);
- return ERR_PTR(ret);
-}
-
-static void render_state_free(struct i915_render_state *so)
-{
- kunmap(so->batch);
- i915_gem_object_ggtt_unpin(so->obj);
- drm_gem_object_unreference(&so->obj->base);
- kfree(so);
-}
-
static const struct intel_renderstate_rodata *
render_state_get_rodata(struct drm_device *dev, const int gen)
{
@@ -101,98 +50,120 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
return NULL;
}
-static int render_state_setup(const int gen,
- const struct intel_renderstate_rodata *rodata,
- struct i915_render_state *so)
+static int render_state_init(struct render_state *so, struct drm_device *dev)
{
- const u64 goffset = i915_gem_obj_ggtt_offset(so->obj);
- u32 reloc_index = 0;
- u32 * const d = so->batch;
- unsigned int i = 0;
int ret;
- if (!rodata || rodata->batch_items * 4 > so->size)
+ so->gen = INTEL_INFO(dev)->gen;
+ so->rodata = render_state_get_rodata(dev, so->gen);
+ if (so->rodata == NULL)
+ return 0;
+
+ if (so->rodata->batch_items * 4 > 4096)
return -EINVAL;
+ so->obj = i915_gem_alloc_object(dev, 4096);
+ if (so->obj == NULL)
+ return -ENOMEM;
+
+ ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
+ if (ret)
+ goto free_gem;
+
+ so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj);
+ return 0;
+
+free_gem:
+ drm_gem_object_unreference(&so->obj->base);
+ return ret;
+}
+
+static int render_state_setup(struct render_state *so)
+{
+ const struct intel_renderstate_rodata *rodata = so->rodata;
+ unsigned int i = 0, reloc_index = 0;
+ struct page *page;
+ u32 *d;
+ int ret;
+
ret = i915_gem_object_set_to_cpu_domain(so->obj, true);
if (ret)
return ret;
+ page = sg_page(so->obj->pages->sgl);
+ d = kmap(page);
+
while (i < rodata->batch_items) {
u32 s = rodata->batch[i];
- if (reloc_index < rodata->reloc_items &&
- i * 4 == rodata->reloc[reloc_index]) {
-
- s += goffset & 0xffffffff;
-
- /* We keep batch offsets max 32bit */
- if (gen >= 8) {
+ if (i * 4 == rodata->reloc[reloc_index]) {
+ u64 r = s + so->ggtt_offset;
+ s = lower_32_bits(r);
+ if (so->gen >= 8) {
if (i + 1 >= rodata->batch_items ||
rodata->batch[i + 1] != 0)
return -EINVAL;
- d[i] = s;
- i++;
- s = (goffset & 0xffffffff00000000ull) >> 32;
+ d[i++] = s;
+ s = upper_32_bits(r);
}
reloc_index++;
}
- d[i] = s;
- i++;
+ d[i++] = s;
}
+ kunmap(page);
ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
if (ret)
return ret;
- if (rodata->reloc_items != reloc_index) {
- DRM_ERROR("not all relocs resolved, %d out of %d\n",
- reloc_index, rodata->reloc_items);
+ if (rodata->reloc[reloc_index] != -1) {
+ DRM_ERROR("only %d relocs resolved\n", reloc_index);
return -EINVAL;
}
- so->len = rodata->batch_items * 4;
-
return 0;
}
+static void render_state_fini(struct render_state *so)
+{
+ i915_gem_object_ggtt_unpin(so->obj);
+ drm_gem_object_unreference(&so->obj->base);
+}
+
int i915_gem_render_state_init(struct intel_engine_cs *ring)
{
- const int gen = INTEL_INFO(ring->dev)->gen;
- struct i915_render_state *so;
- const struct intel_renderstate_rodata *rodata;
+ struct render_state so;
int ret;
if (WARN_ON(ring->id != RCS))
return -ENOENT;
- rodata = render_state_get_rodata(ring->dev, gen);
- if (rodata == NULL)
- return 0;
+ ret = render_state_init(&so, ring->dev);
+ if (ret)
+ return ret;
- so = render_state_alloc(ring->dev);
- if (IS_ERR(so))
- return PTR_ERR(so);
+ if (so.rodata == NULL)
+ return 0;
- ret = render_state_setup(gen, rodata, so);
+ ret = render_state_setup(&so);
if (ret)
goto out;
ret = ring->dispatch_execbuffer(ring,
- i915_gem_obj_ggtt_offset(so->obj),
- so->len,
+ so.ggtt_offset,
+ so.rodata->batch_items * 4,
I915_DISPATCH_SECURE);
if (ret)
goto out;
- i915_vma_move_to_active(i915_gem_obj_to_ggtt(so->obj), ring);
+ i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
- ret = __i915_add_request(ring, NULL, so->obj, NULL);
+ ret = __i915_add_request(ring, NULL, so.obj, NULL);
/* __i915_add_request moves object to inactive if it fails */
out:
- render_state_free(so);
+ render_state_fini(&so);
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 62ef55ba061c..21c025a209c0 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
if (base == 0)
return 0;
+ /* make sure we don't clobber the GTT if it's within stolen memory */
+ if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) {
+ struct {
+ u32 start, end;
+ } stolen[2] = {
+ { .start = base, .end = base + dev_priv->gtt.stolen_size, },
+ { .start = base, .end = base + dev_priv->gtt.stolen_size, },
+ };
+ u64 gtt_start, gtt_end;
+
+ gtt_start = I915_READ(PGTBL_CTL);
+ if (IS_GEN4(dev))
+ gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) |
+ (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
+ else
+ gtt_start &= PGTBL_ADDRESS_LO_MASK;
+ gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4;
+
+ if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end)
+ stolen[0].end = gtt_start;
+ if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end)
+ stolen[1].start = gtt_end;
+
+ /* pick the larger of the two chunks */
+ if (stolen[0].end - stolen[0].start >
+ stolen[1].end - stolen[1].start) {
+ base = stolen[0].start;
+ dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start;
+ } else {
+ base = stolen[1].start;
+ dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start;
+ }
+
+ if (stolen[0].start != stolen[1].start ||
+ stolen[0].end != stolen[1].end) {
+ DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
+ (unsigned long long) gtt_start,
+ (unsigned long long) gtt_end - 1);
+ DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n",
+ base, base + (u32) dev_priv->gtt.stolen_size - 1);
+ }
+ }
+
+
/* Verify that nothing else uses this physical address. Stolen
* memory should be reserved by the BIOS and hidden from the
* kernel. So if the region is already marked as busy, something
@@ -103,30 +147,68 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
return base;
}
-static int i915_setup_compression(struct drm_device *dev, int size)
+static int find_compression_threshold(struct drm_device *dev,
+ struct drm_mm_node *node,
+ int size,
+ int fb_cpp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
+ int compression_threshold = 1;
int ret;
- compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL);
- if (!compressed_fb)
- goto err_llb;
+ /* HACK: This code depends on what we will do in *_enable_fbc. If that
+ * code changes, this code needs to change as well.
+ *
+ * The enable_fbc code will attempt to use one of our 2 compression
+ * thresholds, therefore, in that case, we only have 1 resort.
+ */
- /* Try to over-allocate to reduce reallocations and fragmentation */
- ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
+ /* Try to over-allocate to reduce reallocations and fragmentation. */
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT);
- if (ret)
- ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
- size >>= 1, 4096,
- DRM_MM_SEARCH_DEFAULT);
- if (ret)
+ if (ret == 0)
+ return compression_threshold;
+
+again:
+ /* HW's ability to limit the CFB is 1:4 */
+ if (compression_threshold > 4 ||
+ (fb_cpp == 2 && compression_threshold == 2))
+ return 0;
+
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
+ size >>= 1, 4096,
+ DRM_MM_SEARCH_DEFAULT);
+ if (ret && INTEL_INFO(dev)->gen <= 4) {
+ return 0;
+ } else if (ret) {
+ compression_threshold <<= 1;
+ goto again;
+ } else {
+ return compression_threshold;
+ }
+}
+
+static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mm_node *uninitialized_var(compressed_llb);
+ int ret;
+
+ ret = find_compression_threshold(dev, &dev_priv->fbc.compressed_fb,
+ size, fb_cpp);
+ if (!ret)
goto err_llb;
+ else if (ret > 1) {
+ DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
+
+ }
+
+ dev_priv->fbc.threshold = ret;
if (HAS_PCH_SPLIT(dev))
- I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
+ I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
else if (IS_GM45(dev)) {
- I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
+ I915_WRITE(DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
} else {
compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL);
if (!compressed_llb)
@@ -140,13 +222,12 @@ static int i915_setup_compression(struct drm_device *dev, int size)
dev_priv->fbc.compressed_llb = compressed_llb;
I915_WRITE(FBC_CFB_BASE,
- dev_priv->mm.stolen_base + compressed_fb->start);
+ dev_priv->mm.stolen_base + dev_priv->fbc.compressed_fb.start);
I915_WRITE(FBC_LL_BASE,
dev_priv->mm.stolen_base + compressed_llb->start);
}
- dev_priv->fbc.compressed_fb = compressed_fb;
- dev_priv->fbc.size = size;
+ dev_priv->fbc.size = size / dev_priv->fbc.threshold;
DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",
size);
@@ -155,14 +236,13 @@ static int i915_setup_compression(struct drm_device *dev, int size)
err_fb:
kfree(compressed_llb);
- drm_mm_remove_node(compressed_fb);
+ drm_mm_remove_node(&dev_priv->fbc.compressed_fb);
err_llb:
- kfree(compressed_fb);
pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
return -ENOSPC;
}
-int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)
+int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -175,7 +255,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)
/* Release any current block */
i915_gem_stolen_cleanup_compression(dev);
- return i915_setup_compression(dev, size);
+ return i915_setup_compression(dev, size, fb_cpp);
}
void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
@@ -185,10 +265,7 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
if (dev_priv->fbc.size == 0)
return;
- if (dev_priv->fbc.compressed_fb) {
- drm_mm_remove_node(dev_priv->fbc.compressed_fb);
- kfree(dev_priv->fbc.compressed_fb);
- }
+ drm_mm_remove_node(&dev_priv->fbc.compressed_fb);
if (dev_priv->fbc.compressed_llb) {
drm_mm_remove_node(dev_priv->fbc.compressed_llb);
@@ -292,9 +369,20 @@ static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj)
kfree(obj->pages);
}
+
+static void
+i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
+{
+ if (obj->stolen) {
+ drm_mm_remove_node(obj->stolen);
+ kfree(obj->stolen);
+ obj->stolen = NULL;
+ }
+}
static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
.get_pages = i915_gem_object_get_pages_stolen,
.put_pages = i915_gem_object_put_pages_stolen,
+ .release = i915_gem_object_release_stolen,
};
static struct drm_i915_gem_object *
@@ -452,13 +540,3 @@ err_out:
drm_gem_object_unreference(&obj->base);
return NULL;
}
-
-void
-i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
-{
- if (obj->stolen) {
- drm_mm_remove_node(obj->stolen);
- kfree(obj->stolen);
- obj->stolen = NULL;
- }
-}
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 21ea92886a56..fe69fc837d9e 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -40,19 +40,87 @@ struct i915_mmu_notifier {
struct hlist_node node;
struct mmu_notifier mn;
struct rb_root objects;
+ struct list_head linear;
struct drm_device *dev;
struct mm_struct *mm;
struct work_struct work;
unsigned long count;
unsigned long serial;
+ bool has_linear;
};
struct i915_mmu_object {
struct i915_mmu_notifier *mmu;
struct interval_tree_node it;
+ struct list_head link;
struct drm_i915_gem_object *obj;
+ bool is_linear;
};
+static unsigned long cancel_userptr(struct drm_i915_gem_object *obj)
+{
+ struct drm_device *dev = obj->base.dev;
+ unsigned long end;
+
+ mutex_lock(&dev->struct_mutex);
+ /* Cancel any active worker and force us to re-evaluate gup */
+ obj->userptr.work = NULL;
+
+ if (obj->pages != NULL) {
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct i915_vma *vma, *tmp;
+ bool was_interruptible;
+
+ was_interruptible = dev_priv->mm.interruptible;
+ dev_priv->mm.interruptible = false;
+
+ list_for_each_entry_safe(vma, tmp, &obj->vma_list, vma_link) {
+ int ret = i915_vma_unbind(vma);
+ WARN_ON(ret && ret != -EIO);
+ }
+ WARN_ON(i915_gem_object_put_pages(obj));
+
+ dev_priv->mm.interruptible = was_interruptible;
+ }
+
+ end = obj->userptr.ptr + obj->base.size;
+
+ drm_gem_object_unreference(&obj->base);
+ mutex_unlock(&dev->struct_mutex);
+
+ return end;
+}
+
+static void *invalidate_range__linear(struct i915_mmu_notifier *mn,
+ struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{
+ struct i915_mmu_object *mmu;
+ unsigned long serial;
+
+restart:
+ serial = mn->serial;
+ list_for_each_entry(mmu, &mn->linear, link) {
+ struct drm_i915_gem_object *obj;
+
+ if (mmu->it.last < start || mmu->it.start > end)
+ continue;
+
+ obj = mmu->obj;
+ drm_gem_object_reference(&obj->base);
+ spin_unlock(&mn->lock);
+
+ cancel_userptr(obj);
+
+ spin_lock(&mn->lock);
+ if (serial != mn->serial)
+ goto restart;
+ }
+
+ return NULL;
+}
+
static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
struct mm_struct *mm,
unsigned long start,
@@ -60,16 +128,18 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
{
struct i915_mmu_notifier *mn = container_of(_mn, struct i915_mmu_notifier, mn);
struct interval_tree_node *it = NULL;
+ unsigned long next = start;
unsigned long serial = 0;
end--; /* interval ranges are inclusive, but invalidate range is exclusive */
- while (start < end) {
- struct drm_i915_gem_object *obj;
+ while (next < end) {
+ struct drm_i915_gem_object *obj = NULL;
- obj = NULL;
spin_lock(&mn->lock);
- if (serial == mn->serial)
- it = interval_tree_iter_next(it, start, end);
+ if (mn->has_linear)
+ it = invalidate_range__linear(mn, mm, start, end);
+ else if (serial == mn->serial)
+ it = interval_tree_iter_next(it, next, end);
else
it = interval_tree_iter_first(&mn->objects, start, end);
if (it != NULL) {
@@ -81,31 +151,7 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
if (obj == NULL)
return;
- mutex_lock(&mn->dev->struct_mutex);
- /* Cancel any active worker and force us to re-evaluate gup */
- obj->userptr.work = NULL;
-
- if (obj->pages != NULL) {
- struct drm_i915_private *dev_priv = to_i915(mn->dev);
- struct i915_vma *vma, *tmp;
- bool was_interruptible;
-
- was_interruptible = dev_priv->mm.interruptible;
- dev_priv->mm.interruptible = false;
-
- list_for_each_entry_safe(vma, tmp, &obj->vma_list, vma_link) {
- int ret = i915_vma_unbind(vma);
- WARN_ON(ret && ret != -EIO);
- }
- WARN_ON(i915_gem_object_put_pages(obj));
-
- dev_priv->mm.interruptible = was_interruptible;
- }
-
- start = obj->userptr.ptr + obj->base.size;
-
- drm_gem_object_unreference(&obj->base);
- mutex_unlock(&mn->dev->struct_mutex);
+ next = cancel_userptr(obj);
}
}
@@ -150,7 +196,9 @@ i915_mmu_notifier_get(struct drm_device *dev, struct mm_struct *mm)
mmu->mm = mm;
mmu->objects = RB_ROOT;
mmu->count = 0;
- mmu->serial = 0;
+ mmu->serial = 1;
+ INIT_LIST_HEAD(&mmu->linear);
+ mmu->has_linear = false;
/* Protected by mmap_sem (write-lock) */
ret = __mmu_notifier_register(&mmu->mn, mm);
@@ -197,6 +245,17 @@ static void __i915_mmu_notifier_update_serial(struct i915_mmu_notifier *mmu)
mmu->serial = 1;
}
+static bool i915_mmu_notifier_has_linear(struct i915_mmu_notifier *mmu)
+{
+ struct i915_mmu_object *mn;
+
+ list_for_each_entry(mn, &mmu->linear, link)
+ if (mn->is_linear)
+ return true;
+
+ return false;
+}
+
static void
i915_mmu_notifier_del(struct i915_mmu_notifier *mmu,
struct i915_mmu_object *mn)
@@ -204,7 +263,11 @@ i915_mmu_notifier_del(struct i915_mmu_notifier *mmu,
lockdep_assert_held(&mmu->dev->struct_mutex);
spin_lock(&mmu->lock);
- interval_tree_remove(&mn->it, &mmu->objects);
+ list_del(&mn->link);
+ if (mn->is_linear)
+ mmu->has_linear = i915_mmu_notifier_has_linear(mmu);
+ else
+ interval_tree_remove(&mn->it, &mmu->objects);
__i915_mmu_notifier_update_serial(mmu);
spin_unlock(&mmu->lock);
@@ -230,7 +293,6 @@ i915_mmu_notifier_add(struct i915_mmu_notifier *mmu,
*/
i915_gem_retire_requests(mmu->dev);
- /* Disallow overlapping userptr objects */
spin_lock(&mmu->lock);
it = interval_tree_iter_first(&mmu->objects,
mn->it.start, mn->it.last);
@@ -243,14 +305,22 @@ i915_mmu_notifier_add(struct i915_mmu_notifier *mmu,
* to flush their object references upon which the object will
* be removed from the interval-tree, or the the range is
* still in use by another client and the overlap is invalid.
+ *
+ * If we do have an overlap, we cannot use the interval tree
+ * for fast range invalidation.
*/
obj = container_of(it, struct i915_mmu_object, it)->obj;
- ret = obj->userptr.workers ? -EAGAIN : -EINVAL;
- } else {
+ if (!obj->userptr.workers)
+ mmu->has_linear = mn->is_linear = true;
+ else
+ ret = -EAGAIN;
+ } else
interval_tree_insert(&mn->it, &mmu->objects);
+
+ if (ret == 0) {
+ list_add(&mn->link, &mmu->linear);
__i915_mmu_notifier_update_serial(mmu);
- ret = 0;
}
spin_unlock(&mmu->lock);
mutex_unlock(&mmu->dev->struct_mutex);
@@ -611,12 +681,11 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
* We impose several restrictions upon the memory being mapped
* into the GPU.
* 1. It must be page aligned (both start/end addresses, i.e ptr and size).
- * 2. It cannot overlap any other userptr object in the same address space.
- * 3. It must be normal system memory, not a pointer into another map of IO
+ * 2. It must be normal system memory, not a pointer into another map of IO
* space (e.g. it must not be a GTT mmapping of another object).
- * 4. We only allow a bo as large as we could in theory map into the GTT,
+ * 3. We only allow a bo as large as we could in theory map into the GTT,
* that is we limit the size to the total size of the GTT.
- * 5. The bo is marked as being snoopable. The backing pages are left
+ * 4. The bo is marked as being snoopable. The backing pages are left
* accessible directly by the CPU, but reads and writes by the GPU may
* incur the cost of a snoop (unless you have an LLC architecture).
*
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 66cf41765bf9..eab41f9390f8 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -229,6 +229,8 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a)
return "wait";
case HANGCHECK_ACTIVE:
return "active";
+ case HANGCHECK_ACTIVE_LOOP:
+ return "active (loop)";
case HANGCHECK_KICK:
return "kick";
case HANGCHECK_HUNG:
@@ -327,6 +329,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
struct drm_device *dev = error_priv->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_error_state *error = error_priv->error;
+ struct drm_i915_error_object *obj;
int i, j, offset, elt;
int max_hangcheck_score;
@@ -358,6 +361,12 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device);
err_printf(m, "EIR: 0x%08x\n", error->eir);
err_printf(m, "IER: 0x%08x\n", error->ier);
+ if (INTEL_INFO(dev)->gen >= 8) {
+ for (i = 0; i < 4; i++)
+ err_printf(m, "GTIER gt %d: 0x%08x\n", i,
+ error->gtier[i]);
+ } else if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev))
+ err_printf(m, "GTIER: 0x%08x\n", error->gtier[0]);
err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
@@ -395,8 +404,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
error->pinned_bo_count[0]);
for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
- struct drm_i915_error_object *obj;
-
obj = error->ring[i].batchbuffer;
if (obj) {
err_puts(m, dev_priv->ring[i].name);
@@ -459,6 +466,18 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
}
}
+ if ((obj = error->semaphore_obj)) {
+ err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
+ for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
+ err_printf(m, "[%04x] %08x %08x %08x %08x\n",
+ elt * 4,
+ obj->pages[0][elt],
+ obj->pages[0][elt+1],
+ obj->pages[0][elt+2],
+ obj->pages[0][elt+3]);
+ }
+ }
+
if (error->overlay)
intel_overlay_print_error_state(m, error->overlay);
@@ -529,6 +548,7 @@ static void i915_error_state_free(struct kref *error_ref)
kfree(error->ring[i].requests);
}
+ i915_error_object_free(error->semaphore_obj);
kfree(error->active_bo);
kfree(error->overlay);
kfree(error->display);
@@ -746,7 +766,60 @@ static void i915_gem_record_fences(struct drm_device *dev,
}
}
+
+static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
+ struct drm_i915_error_state *error,
+ struct intel_engine_cs *ring,
+ struct drm_i915_error_ring *ering)
+{
+ struct intel_engine_cs *to;
+ int i;
+
+ if (!i915_semaphore_is_enabled(dev_priv->dev))
+ return;
+
+ if (!error->semaphore_obj)
+ error->semaphore_obj =
+ i915_error_object_create(dev_priv,
+ dev_priv->semaphore_obj,
+ &dev_priv->gtt.base);
+
+ for_each_ring(to, dev_priv, i) {
+ int idx;
+ u16 signal_offset;
+ u32 *tmp;
+
+ if (ring == to)
+ continue;
+
+ signal_offset = (GEN8_SIGNAL_OFFSET(ring, i) & (PAGE_SIZE - 1))
+ / 4;
+ tmp = error->semaphore_obj->pages[0];
+ idx = intel_ring_sync_index(ring, to);
+
+ ering->semaphore_mboxes[idx] = tmp[signal_offset];
+ ering->semaphore_seqno[idx] = ring->semaphore.sync_seqno[idx];
+ }
+}
+
+static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv,
+ struct intel_engine_cs *ring,
+ struct drm_i915_error_ring *ering)
+{
+ ering->semaphore_mboxes[0] = I915_READ(RING_SYNC_0(ring->mmio_base));
+ ering->semaphore_mboxes[1] = I915_READ(RING_SYNC_1(ring->mmio_base));
+ ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0];
+ ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1];
+
+ if (HAS_VEBOX(dev_priv->dev)) {
+ ering->semaphore_mboxes[2] =
+ I915_READ(RING_SYNC_2(ring->mmio_base));
+ ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2];
+ }
+}
+
static void i915_record_ring_state(struct drm_device *dev,
+ struct drm_i915_error_state *error,
struct intel_engine_cs *ring,
struct drm_i915_error_ring *ering)
{
@@ -755,18 +828,10 @@ static void i915_record_ring_state(struct drm_device *dev,
if (INTEL_INFO(dev)->gen >= 6) {
ering->rc_psmi = I915_READ(ring->mmio_base + 0x50);
ering->fault_reg = I915_READ(RING_FAULT_REG(ring));
- ering->semaphore_mboxes[0]
- = I915_READ(RING_SYNC_0(ring->mmio_base));
- ering->semaphore_mboxes[1]
- = I915_READ(RING_SYNC_1(ring->mmio_base));
- ering->semaphore_seqno[0] = ring->semaphore.sync_seqno[0];
- ering->semaphore_seqno[1] = ring->semaphore.sync_seqno[1];
- }
-
- if (HAS_VEBOX(dev)) {
- ering->semaphore_mboxes[2] =
- I915_READ(RING_SYNC_2(ring->mmio_base));
- ering->semaphore_seqno[2] = ring->semaphore.sync_seqno[2];
+ if (INTEL_INFO(dev)->gen >= 8)
+ gen8_record_semaphore_state(dev_priv, error, ring, ering);
+ else
+ gen6_record_semaphore_state(dev_priv, ring, ering);
}
if (INTEL_INFO(dev)->gen >= 4) {
@@ -871,6 +936,9 @@ static void i915_gem_record_active_context(struct intel_engine_cs *ring,
return;
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
+ if (!i915_gem_obj_ggtt_bound(obj))
+ continue;
+
if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) {
ering->ctx = i915_error_ggtt_object_create(dev_priv, obj);
break;
@@ -895,7 +963,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
error->ring[i].valid = true;
- i915_record_ring_state(dev, ring, &error->ring[i]);
+ i915_record_ring_state(dev, error, ring, &error->ring[i]);
request = i915_gem_find_active_request(ring);
if (request) {
@@ -1032,6 +1100,7 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
struct drm_i915_error_state *error)
{
struct drm_device *dev = dev_priv->dev;
+ int i;
/* General organization
* 1. Registers specific to a single generation
@@ -1043,7 +1112,8 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
/* 1: Registers specific to a single generation */
if (IS_VALLEYVIEW(dev)) {
- error->ier = I915_READ(GTIER) | I915_READ(VLV_IER);
+ error->gtier[0] = I915_READ(GTIER);
+ error->ier = I915_READ(VLV_IER);
error->forcewake = I915_READ(FORCEWAKE_VLV);
}
@@ -1076,16 +1146,18 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
if (HAS_HW_CONTEXTS(dev))
error->ccid = I915_READ(CCID);
- if (HAS_PCH_SPLIT(dev))
- error->ier = I915_READ(DEIER) | I915_READ(GTIER);
- else {
- if (IS_GEN2(dev))
- error->ier = I915_READ16(IER);
- else
- error->ier = I915_READ(IER);
+ if (INTEL_INFO(dev)->gen >= 8) {
+ error->ier = I915_READ(GEN8_DE_MISC_IER);
+ for (i = 0; i < 4; i++)
+ error->gtier[i] = I915_READ(GEN8_GT_IER(i));
+ } else if (HAS_PCH_SPLIT(dev)) {
+ error->ier = I915_READ(DEIER);
+ error->gtier[0] = I915_READ(GTIER);
+ } else if (IS_GEN2(dev)) {
+ error->ier = I915_READ16(IER);
+ } else if (!IS_VALLEYVIEW(dev)) {
+ error->ier = I915_READ(IER);
}
-
- /* 4: Everything else */
error->eir = I915_READ(EIR);
error->pgtbl_er = I915_READ(PGTBL_ER);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 267f069765ad..390ccc2a3096 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -136,7 +136,7 @@ ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
{
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
if ((dev_priv->irq_mask & mask) != 0) {
@@ -151,7 +151,7 @@ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
{
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (!intel_irqs_enabled(dev_priv))
return;
if ((dev_priv->irq_mask & mask) != mask) {
@@ -173,7 +173,7 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv,
{
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
dev_priv->gt_irq_mask &= ~interrupt_mask;
@@ -182,12 +182,12 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv,
POSTING_READ(GTIMR);
}
-void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
ilk_update_gt_irq(dev_priv, mask, mask);
}
-void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
ilk_update_gt_irq(dev_priv, mask, 0);
}
@@ -206,7 +206,7 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
new_val = dev_priv->pm_irq_mask;
@@ -220,12 +220,12 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
}
}
-void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
snb_update_pm_irq(dev_priv, mask, mask);
}
-void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
snb_update_pm_irq(dev_priv, mask, 0);
}
@@ -264,7 +264,7 @@ static void bdw_update_pm_irq(struct drm_i915_private *dev_priv,
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
new_val = dev_priv->pm_irq_mask;
@@ -278,12 +278,12 @@ static void bdw_update_pm_irq(struct drm_i915_private *dev_priv,
}
}
-void bdw_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
bdw_update_pm_irq(dev_priv, mask, mask);
}
-void bdw_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
+void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
bdw_update_pm_irq(dev_priv, mask, 0);
}
@@ -420,7 +420,7 @@ static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
assert_spin_locked(&dev_priv->irq_lock);
- if (WARN_ON(dev_priv->pm.irqs_disabled))
+ if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
I915_WRITE(SDEIMR, sdeimr);
@@ -1090,6 +1090,53 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
return true;
}
+static void i915_digport_work_func(struct work_struct *work)
+{
+ struct drm_i915_private *dev_priv =
+ container_of(work, struct drm_i915_private, dig_port_work);
+ unsigned long irqflags;
+ u32 long_port_mask, short_port_mask;
+ struct intel_digital_port *intel_dig_port;
+ int i, ret;
+ u32 old_bits = 0;
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ long_port_mask = dev_priv->long_hpd_port_mask;
+ dev_priv->long_hpd_port_mask = 0;
+ short_port_mask = dev_priv->short_hpd_port_mask;
+ dev_priv->short_hpd_port_mask = 0;
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+ for (i = 0; i < I915_MAX_PORTS; i++) {
+ bool valid = false;
+ bool long_hpd = false;
+ intel_dig_port = dev_priv->hpd_irq_port[i];
+ if (!intel_dig_port || !intel_dig_port->hpd_pulse)
+ continue;
+
+ if (long_port_mask & (1 << i)) {
+ valid = true;
+ long_hpd = true;
+ } else if (short_port_mask & (1 << i))
+ valid = true;
+
+ if (valid) {
+ ret = intel_dig_port->hpd_pulse(intel_dig_port, long_hpd);
+ if (ret == true) {
+ /* if we get true fallback to old school hpd */
+ old_bits |= (1 << intel_dig_port->base.hpd_pin);
+ }
+ }
+ }
+
+ if (old_bits) {
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ dev_priv->hpd_event_bits |= old_bits;
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+ schedule_work(&dev_priv->hotplug_work);
+ }
+}
+
/*
* Handle hotplug events outside the interrupt handler proper.
*/
@@ -1109,10 +1156,6 @@ static void i915_hotplug_work_func(struct work_struct *work)
bool changed = false;
u32 hpd_event_bits;
- /* HPD irq before everything is fully set up. */
- if (!dev_priv->enable_hotplug_processing)
- return;
-
mutex_lock(&mode_config->mutex);
DRM_DEBUG_KMS("running encoder hotplug functions\n");
@@ -1122,6 +1165,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
dev_priv->hpd_event_bits = 0;
list_for_each_entry(connector, &mode_config->connector_list, head) {
intel_connector = to_intel_connector(connector);
+ if (!intel_connector->encoder)
+ continue;
intel_encoder = intel_connector->encoder;
if (intel_encoder->hpd_pin > HPD_NONE &&
dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_MARK_DISABLED &&
@@ -1152,6 +1197,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
list_for_each_entry(connector, &mode_config->connector_list, head) {
intel_connector = to_intel_connector(connector);
+ if (!intel_connector->encoder)
+ continue;
intel_encoder = intel_connector->encoder;
if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
if (intel_encoder->hot_plug)
@@ -1218,10 +1265,138 @@ static void notify_ring(struct drm_device *dev,
trace_i915_gem_request_complete(ring);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ intel_notify_mmio_flip(ring);
+
wake_up_all(&ring->irq_queue);
i915_queue_hangcheck(dev);
}
+static u32 vlv_c0_residency(struct drm_i915_private *dev_priv,
+ struct intel_rps_ei *rps_ei)
+{
+ u32 cz_ts, cz_freq_khz;
+ u32 render_count, media_count;
+ u32 elapsed_render, elapsed_media, elapsed_time;
+ u32 residency = 0;
+
+ cz_ts = vlv_punit_read(dev_priv, PUNIT_REG_CZ_TIMESTAMP);
+ cz_freq_khz = DIV_ROUND_CLOSEST(dev_priv->mem_freq * 1000, 4);
+
+ render_count = I915_READ(VLV_RENDER_C0_COUNT_REG);
+ media_count = I915_READ(VLV_MEDIA_C0_COUNT_REG);
+
+ if (rps_ei->cz_clock == 0) {
+ rps_ei->cz_clock = cz_ts;
+ rps_ei->render_c0 = render_count;
+ rps_ei->media_c0 = media_count;
+
+ return dev_priv->rps.cur_freq;
+ }
+
+ elapsed_time = cz_ts - rps_ei->cz_clock;
+ rps_ei->cz_clock = cz_ts;
+
+ elapsed_render = render_count - rps_ei->render_c0;
+ rps_ei->render_c0 = render_count;
+
+ elapsed_media = media_count - rps_ei->media_c0;
+ rps_ei->media_c0 = media_count;
+
+ /* Convert all the counters into common unit of milli sec */
+ elapsed_time /= VLV_CZ_CLOCK_TO_MILLI_SEC;
+ elapsed_render /= cz_freq_khz;
+ elapsed_media /= cz_freq_khz;
+
+ /*
+ * Calculate overall C0 residency percentage
+ * only if elapsed time is non zero
+ */
+ if (elapsed_time) {
+ residency =
+ ((max(elapsed_render, elapsed_media) * 100)
+ / elapsed_time);
+ }
+
+ return residency;
+}
+
+/**
+ * vlv_calc_delay_from_C0_counters - Increase/Decrease freq based on GPU
+ * busy-ness calculated from C0 counters of render & media power wells
+ * @dev_priv: DRM device private
+ *
+ */
+static u32 vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv)
+{
+ u32 residency_C0_up = 0, residency_C0_down = 0;
+ u8 new_delay, adj;
+
+ dev_priv->rps.ei_interrupt_count++;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+
+ if (dev_priv->rps.up_ei.cz_clock == 0) {
+ vlv_c0_residency(dev_priv, &dev_priv->rps.up_ei);
+ vlv_c0_residency(dev_priv, &dev_priv->rps.down_ei);
+ return dev_priv->rps.cur_freq;
+ }
+
+
+ /*
+ * To down throttle, C0 residency should be less than down threshold
+ * for continous EI intervals. So calculate down EI counters
+ * once in VLV_INT_COUNT_FOR_DOWN_EI
+ */
+ if (dev_priv->rps.ei_interrupt_count == VLV_INT_COUNT_FOR_DOWN_EI) {
+
+ dev_priv->rps.ei_interrupt_count = 0;
+
+ residency_C0_down = vlv_c0_residency(dev_priv,
+ &dev_priv->rps.down_ei);
+ } else {
+ residency_C0_up = vlv_c0_residency(dev_priv,
+ &dev_priv->rps.up_ei);
+ }
+
+ new_delay = dev_priv->rps.cur_freq;
+
+ adj = dev_priv->rps.last_adj;
+ /* C0 residency is greater than UP threshold. Increase Frequency */
+ if (residency_C0_up >= VLV_RP_UP_EI_THRESHOLD) {
+ if (adj > 0)
+ adj *= 2;
+ else
+ adj = 1;
+
+ if (dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit)
+ new_delay = dev_priv->rps.cur_freq + adj;
+
+ /*
+ * For better performance, jump directly
+ * to RPe if we're below it.
+ */
+ if (new_delay < dev_priv->rps.efficient_freq)
+ new_delay = dev_priv->rps.efficient_freq;
+
+ } else if (!dev_priv->rps.ei_interrupt_count &&
+ (residency_C0_down < VLV_RP_DOWN_EI_THRESHOLD)) {
+ if (adj < 0)
+ adj *= 2;
+ else
+ adj = -1;
+ /*
+ * This means, C0 residency is less than down threshold over
+ * a period of VLV_INT_COUNT_FOR_DOWN_EI. So, reduce the freq
+ */
+ if (dev_priv->rps.cur_freq > dev_priv->rps.min_freq_softlimit)
+ new_delay = dev_priv->rps.cur_freq + adj;
+ }
+
+ return new_delay;
+}
+
static void gen6_pm_rps_work(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
@@ -1232,11 +1407,11 @@ static void gen6_pm_rps_work(struct work_struct *work)
spin_lock_irq(&dev_priv->irq_lock);
pm_iir = dev_priv->rps.pm_iir;
dev_priv->rps.pm_iir = 0;
- if (IS_BROADWELL(dev_priv->dev))
- bdw_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+ if (INTEL_INFO(dev_priv->dev)->gen >= 8)
+ gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
else {
/* Make sure not to corrupt PMIMR state used by ringbuffer */
- snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+ gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
}
spin_unlock_irq(&dev_priv->irq_lock);
@@ -1252,8 +1427,10 @@ static void gen6_pm_rps_work(struct work_struct *work)
if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
if (adj > 0)
adj *= 2;
- else
- adj = 1;
+ else {
+ /* CHV needs even encode values */
+ adj = IS_CHERRYVIEW(dev_priv->dev) ? 2 : 1;
+ }
new_delay = dev_priv->rps.cur_freq + adj;
/*
@@ -1268,11 +1445,15 @@ static void gen6_pm_rps_work(struct work_struct *work)
else
new_delay = dev_priv->rps.min_freq_softlimit;
adj = 0;
+ } else if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
+ new_delay = vlv_calc_delay_from_C0_counters(dev_priv);
} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
if (adj < 0)
adj *= 2;
- else
- adj = -1;
+ else {
+ /* CHV needs even encode values */
+ adj = IS_CHERRYVIEW(dev_priv->dev) ? -2 : -1;
+ }
new_delay = dev_priv->rps.cur_freq + adj;
} else { /* unknown event */
new_delay = dev_priv->rps.cur_freq;
@@ -1372,7 +1553,7 @@ static void ivybridge_parity_work(struct work_struct *work)
out:
WARN_ON(dev_priv->l3_parity.which_slice);
spin_lock_irqsave(&dev_priv->irq_lock, flags);
- ilk_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev));
+ gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev));
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
mutex_unlock(&dev_priv->dev->struct_mutex);
@@ -1386,7 +1567,7 @@ static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
return;
spin_lock(&dev_priv->irq_lock);
- ilk_disable_gt_irq(dev_priv, GT_PARITY_ERROR(dev));
+ gen5_disable_gt_irq(dev_priv, GT_PARITY_ERROR(dev));
spin_unlock(&dev_priv->irq_lock);
iir &= GT_PARITY_ERROR(dev);
@@ -1441,7 +1622,7 @@ static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
spin_lock(&dev_priv->irq_lock);
dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
- bdw_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
+ gen8_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
spin_unlock(&dev_priv->irq_lock);
queue_work(dev_priv->wq, &dev_priv->rps.work);
@@ -1458,6 +1639,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
tmp = I915_READ(GEN8_GT_IIR(0));
if (tmp) {
+ I915_WRITE(GEN8_GT_IIR(0), tmp);
ret = IRQ_HANDLED;
rcs = tmp >> GEN8_RCS_IRQ_SHIFT;
bcs = tmp >> GEN8_BCS_IRQ_SHIFT;
@@ -1465,7 +1647,6 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
notify_ring(dev, &dev_priv->ring[RCS]);
if (bcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, &dev_priv->ring[BCS]);
- I915_WRITE(GEN8_GT_IIR(0), tmp);
} else
DRM_ERROR("The master control interrupt lied (GT0)!\n");
}
@@ -1473,6 +1654,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
tmp = I915_READ(GEN8_GT_IIR(1));
if (tmp) {
+ I915_WRITE(GEN8_GT_IIR(1), tmp);
ret = IRQ_HANDLED;
vcs = tmp >> GEN8_VCS1_IRQ_SHIFT;
if (vcs & GT_RENDER_USER_INTERRUPT)
@@ -1480,7 +1662,6 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
vcs = tmp >> GEN8_VCS2_IRQ_SHIFT;
if (vcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, &dev_priv->ring[VCS2]);
- I915_WRITE(GEN8_GT_IIR(1), tmp);
} else
DRM_ERROR("The master control interrupt lied (GT1)!\n");
}
@@ -1488,10 +1669,10 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (master_ctl & GEN8_GT_PM_IRQ) {
tmp = I915_READ(GEN8_GT_IIR(2));
if (tmp & dev_priv->pm_rps_events) {
- ret = IRQ_HANDLED;
- gen8_rps_irq_handler(dev_priv, tmp);
I915_WRITE(GEN8_GT_IIR(2),
tmp & dev_priv->pm_rps_events);
+ ret = IRQ_HANDLED;
+ gen8_rps_irq_handler(dev_priv, tmp);
} else
DRM_ERROR("The master control interrupt lied (PM)!\n");
}
@@ -1499,11 +1680,11 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
if (master_ctl & GEN8_GT_VECS_IRQ) {
tmp = I915_READ(GEN8_GT_IIR(3));
if (tmp) {
+ I915_WRITE(GEN8_GT_IIR(3), tmp);
ret = IRQ_HANDLED;
vcs = tmp >> GEN8_VECS_IRQ_SHIFT;
if (vcs & GT_RENDER_USER_INTERRUPT)
notify_ring(dev, &dev_priv->ring[VECS]);
- I915_WRITE(GEN8_GT_IIR(3), tmp);
} else
DRM_ERROR("The master control interrupt lied (GT3)!\n");
}
@@ -1514,23 +1695,104 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
#define HPD_STORM_DETECT_PERIOD 1000
#define HPD_STORM_THRESHOLD 5
+static int ilk_port_to_hotplug_shift(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ case PORT_E:
+ default:
+ return -1;
+ case PORT_B:
+ return 0;
+ case PORT_C:
+ return 8;
+ case PORT_D:
+ return 16;
+ }
+}
+
+static int g4x_port_to_hotplug_shift(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ case PORT_E:
+ default:
+ return -1;
+ case PORT_B:
+ return 17;
+ case PORT_C:
+ return 19;
+ case PORT_D:
+ return 21;
+ }
+}
+
+static inline enum port get_port_from_pin(enum hpd_pin pin)
+{
+ switch (pin) {
+ case HPD_PORT_B:
+ return PORT_B;
+ case HPD_PORT_C:
+ return PORT_C;
+ case HPD_PORT_D:
+ return PORT_D;
+ default:
+ return PORT_A; /* no hpd */
+ }
+}
+
static inline void intel_hpd_irq_handler(struct drm_device *dev,
u32 hotplug_trigger,
+ u32 dig_hotplug_reg,
const u32 *hpd)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
+ enum port port;
bool storm_detected = false;
+ bool queue_dig = false, queue_hp = false;
+ u32 dig_shift;
+ u32 dig_port_mask = 0;
if (!hotplug_trigger)
return;
- DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
- hotplug_trigger);
+ DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x, dig 0x%08x\n",
+ hotplug_trigger, dig_hotplug_reg);
spin_lock(&dev_priv->irq_lock);
for (i = 1; i < HPD_NUM_PINS; i++) {
+ if (!(hpd[i] & hotplug_trigger))
+ continue;
+
+ port = get_port_from_pin(i);
+ if (port && dev_priv->hpd_irq_port[port]) {
+ bool long_hpd;
+
+ if (IS_G4X(dev)) {
+ dig_shift = g4x_port_to_hotplug_shift(port);
+ long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
+ } else {
+ dig_shift = ilk_port_to_hotplug_shift(port);
+ long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT;
+ }
+
+ DRM_DEBUG_DRIVER("digital hpd port %d %d\n", port, long_hpd);
+ /* for long HPD pulses we want to have the digital queue happen,
+ but we still want HPD storm detection to function. */
+ if (long_hpd) {
+ dev_priv->long_hpd_port_mask |= (1 << port);
+ dig_port_mask |= hpd[i];
+ } else {
+ /* for short HPD just trigger the digital queue */
+ dev_priv->short_hpd_port_mask |= (1 << port);
+ hotplug_trigger &= ~hpd[i];
+ }
+ queue_dig = true;
+ }
+ }
+ for (i = 1; i < HPD_NUM_PINS; i++) {
if (hpd[i] & hotplug_trigger &&
dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) {
/*
@@ -1550,7 +1812,11 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED)
continue;
- dev_priv->hpd_event_bits |= (1 << i);
+ if (!(dig_port_mask & hpd[i])) {
+ dev_priv->hpd_event_bits |= (1 << i);
+ queue_hp = true;
+ }
+
if (!time_in_range(jiffies, dev_priv->hpd_stats[i].hpd_last_jiffies,
dev_priv->hpd_stats[i].hpd_last_jiffies
+ msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) {
@@ -1579,7 +1845,10 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
* queue for otherwise the flush_work in the pageflip code will
* deadlock.
*/
- schedule_work(&dev_priv->hotplug_work);
+ if (queue_dig)
+ queue_work(dev_priv->dp_wq, &dev_priv->dig_port_work);
+ if (queue_hp)
+ schedule_work(&dev_priv->hotplug_work);
}
static void gmbus_irq_handler(struct drm_device *dev)
@@ -1700,7 +1969,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
if (pm_iir & dev_priv->pm_rps_events) {
spin_lock(&dev_priv->irq_lock);
dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
- snb_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
+ gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
spin_unlock(&dev_priv->irq_lock);
queue_work(dev_priv->wq, &dev_priv->rps.work);
@@ -1809,26 +2078,28 @@ static void i9xx_hpd_irq_handler(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
- if (IS_G4X(dev)) {
- u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
+ if (hotplug_status) {
+ I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+ /*
+ * Make sure hotplug status is cleared before we clear IIR, or else we
+ * may miss hotplug events.
+ */
+ POSTING_READ(PORT_HOTPLUG_STAT);
- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_g4x);
- } else {
- u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;
+ if (IS_G4X(dev)) {
+ u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915);
- }
+ intel_hpd_irq_handler(dev, hotplug_trigger, 0, hpd_status_g4x);
+ } else {
+ u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915;
- if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) &&
- hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
- dp_aux_irq_handler(dev);
+ intel_hpd_irq_handler(dev, hotplug_trigger, 0, hpd_status_i915);
+ }
- I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
- /*
- * Make sure hotplug status is cleared before we clear IIR, or else we
- * may miss hotplug events.
- */
- POSTING_READ(PORT_HOTPLUG_STAT);
+ if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) &&
+ hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)
+ dp_aux_irq_handler(dev);
+ }
}
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
@@ -1839,29 +2110,36 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
irqreturn_t ret = IRQ_NONE;
while (true) {
- iir = I915_READ(VLV_IIR);
+ /* Find, clear, then process each source of interrupt */
+
gt_iir = I915_READ(GTIIR);
+ if (gt_iir)
+ I915_WRITE(GTIIR, gt_iir);
+
pm_iir = I915_READ(GEN6_PMIIR);
+ if (pm_iir)
+ I915_WRITE(GEN6_PMIIR, pm_iir);
+
+ iir = I915_READ(VLV_IIR);
+ if (iir) {
+ /* Consume port before clearing IIR or we'll miss events */
+ if (iir & I915_DISPLAY_PORT_INTERRUPT)
+ i9xx_hpd_irq_handler(dev);
+ I915_WRITE(VLV_IIR, iir);
+ }
if (gt_iir == 0 && pm_iir == 0 && iir == 0)
goto out;
ret = IRQ_HANDLED;
- snb_gt_irq_handler(dev, dev_priv, gt_iir);
-
- valleyview_pipestat_irq_handler(dev, iir);
-
- /* Consume port. Then clear IIR or we'll miss events */
- if (iir & I915_DISPLAY_PORT_INTERRUPT)
- i9xx_hpd_irq_handler(dev);
-
+ if (gt_iir)
+ snb_gt_irq_handler(dev, dev_priv, gt_iir);
if (pm_iir)
gen6_rps_irq_handler(dev_priv, pm_iir);
-
- I915_WRITE(GTIIR, gt_iir);
- I915_WRITE(GEN6_PMIIR, pm_iir);
- I915_WRITE(VLV_IIR, iir);
+ /* Call regardless, as some status bits might not be
+ * signalled in iir */
+ valleyview_pipestat_irq_handler(dev, iir);
}
out:
@@ -1882,21 +2160,27 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
if (master_ctl == 0 && iir == 0)
break;
+ ret = IRQ_HANDLED;
+
I915_WRITE(GEN8_MASTER_IRQ, 0);
- gen8_gt_irq_handler(dev, dev_priv, master_ctl);
+ /* Find, clear, then process each source of interrupt */
- valleyview_pipestat_irq_handler(dev, iir);
+ if (iir) {
+ /* Consume port before clearing IIR or we'll miss events */
+ if (iir & I915_DISPLAY_PORT_INTERRUPT)
+ i9xx_hpd_irq_handler(dev);
+ I915_WRITE(VLV_IIR, iir);
+ }
- /* Consume port. Then clear IIR or we'll miss events */
- i9xx_hpd_irq_handler(dev);
+ gen8_gt_irq_handler(dev, dev_priv, master_ctl);
- I915_WRITE(VLV_IIR, iir);
+ /* Call regardless, as some status bits might not be
+ * signalled in iir */
+ valleyview_pipestat_irq_handler(dev, iir);
I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
POSTING_READ(GEN8_MASTER_IRQ);
-
- ret = IRQ_HANDLED;
}
return ret;
@@ -1907,8 +2191,12 @@ static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
+ u32 dig_hotplug_reg;
+
+ dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+ I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx);
+ intel_hpd_irq_handler(dev, hotplug_trigger, dig_hotplug_reg, hpd_ibx);
if (pch_iir & SDE_AUDIO_POWER_MASK) {
int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >>
@@ -2014,8 +2302,12 @@ static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe;
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
+ u32 dig_hotplug_reg;
- intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt);
+ dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+ I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg);
+
+ intel_hpd_irq_handler(dev, hotplug_trigger, dig_hotplug_reg, hpd_cpt);
if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) {
int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
@@ -2132,6 +2424,14 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
}
}
+/*
+ * To handle irqs with the minimum potential races with fresh interrupts, we:
+ * 1 - Disable Master Interrupt Control.
+ * 2 - Find the source(s) of the interrupt.
+ * 3 - Clear the Interrupt Identity bits (IIR).
+ * 4 - Process the interrupt(s) that had bits set in the IIRs.
+ * 5 - Re-enable Master Interrupt Control.
+ */
static irqreturn_t ironlake_irq_handler(int irq, void *arg)
{
struct drm_device *dev = arg;
@@ -2159,32 +2459,34 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
POSTING_READ(SDEIER);
}
+ /* Find, clear, then process each source of interrupt */
+
gt_iir = I915_READ(GTIIR);
if (gt_iir) {
+ I915_WRITE(GTIIR, gt_iir);
+ ret = IRQ_HANDLED;
if (INTEL_INFO(dev)->gen >= 6)
snb_gt_irq_handler(dev, dev_priv, gt_iir);
else
ilk_gt_irq_handler(dev, dev_priv, gt_iir);
- I915_WRITE(GTIIR, gt_iir);
- ret = IRQ_HANDLED;
}
de_iir = I915_READ(DEIIR);
if (de_iir) {
+ I915_WRITE(DEIIR, de_iir);
+ ret = IRQ_HANDLED;
if (INTEL_INFO(dev)->gen >= 7)
ivb_display_irq_handler(dev, de_iir);
else
ilk_display_irq_handler(dev, de_iir);
- I915_WRITE(DEIIR, de_iir);
- ret = IRQ_HANDLED;
}
if (INTEL_INFO(dev)->gen >= 6) {
u32 pm_iir = I915_READ(GEN6_PMIIR);
if (pm_iir) {
- gen6_rps_irq_handler(dev_priv, pm_iir);
I915_WRITE(GEN6_PMIIR, pm_iir);
ret = IRQ_HANDLED;
+ gen6_rps_irq_handler(dev_priv, pm_iir);
}
}
@@ -2215,36 +2517,36 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
I915_WRITE(GEN8_MASTER_IRQ, 0);
POSTING_READ(GEN8_MASTER_IRQ);
+ /* Find, clear, then process each source of interrupt */
+
ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl);
if (master_ctl & GEN8_DE_MISC_IRQ) {
tmp = I915_READ(GEN8_DE_MISC_IIR);
- if (tmp & GEN8_DE_MISC_GSE)
- intel_opregion_asle_intr(dev);
- else if (tmp)
- DRM_ERROR("Unexpected DE Misc interrupt\n");
- else
- DRM_ERROR("The master control interrupt lied (DE MISC)!\n");
-
if (tmp) {
I915_WRITE(GEN8_DE_MISC_IIR, tmp);
ret = IRQ_HANDLED;
+ if (tmp & GEN8_DE_MISC_GSE)
+ intel_opregion_asle_intr(dev);
+ else
+ DRM_ERROR("Unexpected DE Misc interrupt\n");
}
+ else
+ DRM_ERROR("The master control interrupt lied (DE MISC)!\n");
}
if (master_ctl & GEN8_DE_PORT_IRQ) {
tmp = I915_READ(GEN8_DE_PORT_IIR);
- if (tmp & GEN8_AUX_CHANNEL_A)
- dp_aux_irq_handler(dev);
- else if (tmp)
- DRM_ERROR("Unexpected DE Port interrupt\n");
- else
- DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
-
if (tmp) {
I915_WRITE(GEN8_DE_PORT_IIR, tmp);
ret = IRQ_HANDLED;
+ if (tmp & GEN8_AUX_CHANNEL_A)
+ dp_aux_irq_handler(dev);
+ else
+ DRM_ERROR("Unexpected DE Port interrupt\n");
}
+ else
+ DRM_ERROR("The master control interrupt lied (DE PORT)!\n");
}
for_each_pipe(pipe) {
@@ -2254,33 +2556,32 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
continue;
pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe));
- if (pipe_iir & GEN8_PIPE_VBLANK)
- intel_pipe_handle_vblank(dev, pipe);
-
- if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
- intel_prepare_page_flip(dev, pipe);
- intel_finish_page_flip_plane(dev, pipe);
- }
+ if (pipe_iir) {
+ ret = IRQ_HANDLED;
+ I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
+ if (pipe_iir & GEN8_PIPE_VBLANK)
+ intel_pipe_handle_vblank(dev, pipe);
- if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE)
- hsw_pipe_crc_irq_handler(dev, pipe);
+ if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) {
+ intel_prepare_page_flip(dev, pipe);
+ intel_finish_page_flip_plane(dev, pipe);
+ }
- if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) {
- if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
- false))
- DRM_ERROR("Pipe %c FIFO underrun\n",
- pipe_name(pipe));
- }
+ if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE)
+ hsw_pipe_crc_irq_handler(dev, pipe);
- if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
- DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
- pipe_name(pipe),
- pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
- }
+ if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) {
+ if (intel_set_cpu_fifo_underrun_reporting(dev, pipe,
+ false))
+ DRM_ERROR("Pipe %c FIFO underrun\n",
+ pipe_name(pipe));
+ }
- if (pipe_iir) {
- ret = IRQ_HANDLED;
- I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir);
+ if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) {
+ DRM_ERROR("Fault errors on pipe %c\n: 0x%08x",
+ pipe_name(pipe),
+ pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS);
+ }
} else
DRM_ERROR("The master control interrupt lied (DE PIPE)!\n");
}
@@ -2292,13 +2593,13 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
* on older pch-split platforms. But this needs testing.
*/
u32 pch_iir = I915_READ(SDEIIR);
-
- cpt_irq_handler(dev, pch_iir);
-
if (pch_iir) {
I915_WRITE(SDEIIR, pch_iir);
ret = IRQ_HANDLED;
- }
+ cpt_irq_handler(dev, pch_iir);
+ } else
+ DRM_ERROR("The master control interrupt lied (SDE)!\n");
+
}
I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
@@ -2753,12 +3054,7 @@ static bool
ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
{
if (INTEL_INFO(dev)->gen >= 8) {
- /*
- * FIXME: gen8 semaphore support - currently we don't emit
- * semaphores on bdw anyway, but this needs to be addressed when
- * we merge that code.
- */
- return false;
+ return (ipehr >> 23) == 0x1c;
} else {
ipehr &= ~MI_SEMAPHORE_SYNC_MASK;
return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE |
@@ -2767,19 +3063,20 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
}
static struct intel_engine_cs *
-semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr)
+semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr, u64 offset)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
struct intel_engine_cs *signaller;
int i;
if (INTEL_INFO(dev_priv->dev)->gen >= 8) {
- /*
- * FIXME: gen8 semaphore support - currently we don't emit
- * semaphores on bdw anyway, but this needs to be addressed when
- * we merge that code.
- */
- return NULL;
+ for_each_ring(signaller, dev_priv, i) {
+ if (ring == signaller)
+ continue;
+
+ if (offset == signaller->semaphore.signal_ggtt[ring->id])
+ return signaller;
+ }
} else {
u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK;
@@ -2792,8 +3089,8 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr)
}
}
- DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x\n",
- ring->id, ipehr);
+ DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n",
+ ring->id, ipehr, offset);
return NULL;
}
@@ -2803,7 +3100,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
u32 cmd, ipehr, head;
- int i;
+ u64 offset = 0;
+ int i, backwards;
ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
if (!ipehr_is_semaphore_wait(ring->dev, ipehr))
@@ -2812,13 +3110,15 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
/*
* HEAD is likely pointing to the dword after the actual command,
* so scan backwards until we find the MBOX. But limit it to just 3
- * dwords. Note that we don't care about ACTHD here since that might
+ * or 4 dwords depending on the semaphore wait command size.
+ * Note that we don't care about ACTHD here since that might
* point at at batch, and semaphores are always emitted into the
* ringbuffer itself.
*/
head = I915_READ_HEAD(ring) & HEAD_ADDR;
+ backwards = (INTEL_INFO(ring->dev)->gen >= 8) ? 5 : 4;
- for (i = 4; i; --i) {
+ for (i = backwards; i; --i) {
/*
* Be paranoid and presume the hw has gone off into the wild -
* our ring is smaller than what the hardware (and hence
@@ -2838,14 +3138,19 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
return NULL;
*seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1;
- return semaphore_wait_to_signaller_ring(ring, ipehr);
+ if (INTEL_INFO(ring->dev)->gen >= 8) {
+ offset = ioread32(ring->buffer->virtual_start + head + 12);
+ offset <<= 32;
+ offset = ioread32(ring->buffer->virtual_start + head + 8);
+ }
+ return semaphore_wait_to_signaller_ring(ring, ipehr, offset);
}
static int semaphore_passed(struct intel_engine_cs *ring)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
struct intel_engine_cs *signaller;
- u32 seqno, ctl;
+ u32 seqno;
ring->hangcheck.deadlock++;
@@ -2857,15 +3162,12 @@ static int semaphore_passed(struct intel_engine_cs *ring)
if (signaller->hangcheck.deadlock >= I915_NUM_RINGS)
return -1;
- /* cursory check for an unkickable deadlock */
- ctl = I915_READ_CTL(signaller);
- if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0)
- return -1;
-
if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno))
return 1;
- if (signaller->hangcheck.deadlock)
+ /* cursory check for an unkickable deadlock */
+ if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE &&
+ semaphore_passed(signaller) < 0)
return -1;
return 0;
@@ -2887,8 +3189,14 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;
- if (ring->hangcheck.acthd != acthd)
- return HANGCHECK_ACTIVE;
+ if (acthd != ring->hangcheck.acthd) {
+ if (acthd > ring->hangcheck.max_acthd) {
+ ring->hangcheck.max_acthd = acthd;
+ return HANGCHECK_ACTIVE;
+ }
+
+ return HANGCHECK_ACTIVE_LOOP;
+ }
if (IS_GEN2(dev))
return HANGCHECK_HUNG;
@@ -2999,8 +3307,9 @@ static void i915_hangcheck_elapsed(unsigned long data)
switch (ring->hangcheck.action) {
case HANGCHECK_IDLE:
case HANGCHECK_WAIT:
- break;
case HANGCHECK_ACTIVE:
+ break;
+ case HANGCHECK_ACTIVE_LOOP:
ring->hangcheck.score += BUSY;
break;
case HANGCHECK_KICK:
@@ -3020,6 +3329,8 @@ static void i915_hangcheck_elapsed(unsigned long data)
*/
if (ring->hangcheck.score > 0)
ring->hangcheck.score--;
+
+ ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0;
}
ring->hangcheck.seqno = seqno;
@@ -3162,7 +3473,9 @@ static void gen8_irq_reset(struct drm_device *dev)
gen8_gt_irq_reset(dev_priv);
for_each_pipe(pipe)
- GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
+ if (intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(pipe)))
+ GEN8_IRQ_RESET_NDX(DE_PIPE, pipe);
GEN5_IRQ_RESET(GEN8_DE_PORT_);
GEN5_IRQ_RESET(GEN8_DE_MISC_);
@@ -3171,6 +3484,18 @@ static void gen8_irq_reset(struct drm_device *dev)
ibx_irq_reset(dev);
}
+void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv)
+{
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+ GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B],
+ ~dev_priv->de_irq_mask[PIPE_B]);
+ GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C],
+ ~dev_priv->de_irq_mask[PIPE_C]);
+ spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
static void cherryview_irq_preinstall(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3495,8 +3820,11 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked;
for_each_pipe(pipe)
- GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, dev_priv->de_irq_mask[pipe],
- de_pipe_enables);
+ if (intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(pipe)))
+ GEN8_IRQ_INIT_NDX(DE_PIPE, pipe,
+ dev_priv->de_irq_mask[pipe],
+ de_pipe_enables);
GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A);
}
@@ -4327,12 +4655,17 @@ void intel_irq_init(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
+ INIT_WORK(&dev_priv->dig_port_work, i915_digport_work_func);
INIT_WORK(&dev_priv->gpu_error.work, i915_error_work_func);
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
/* Let's track the enabled rps events */
- dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
+ if (IS_VALLEYVIEW(dev))
+ /* WaGsvRC0ResidenncyMethod:VLV */
+ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
+ else
+ dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
setup_timer(&dev_priv->gpu_error.hangcheck_timer,
i915_hangcheck_elapsed,
@@ -4342,6 +4675,9 @@ void intel_irq_init(struct drm_device *dev)
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
+ /* Haven't installed the IRQ handler yet */
+ dev_priv->pm._irqs_disabled = true;
+
if (IS_GEN2(dev)) {
dev->max_vblank_count = 0;
dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
@@ -4429,7 +4765,9 @@ void intel_hpd_init(struct drm_device *dev)
list_for_each_entry(connector, &mode_config->connector_list, head) {
struct intel_connector *intel_connector = to_intel_connector(connector);
connector->polled = intel_connector->polled;
- if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE)
+ if (connector->encoder && !connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE)
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+ if (intel_connector->mst_port)
connector->polled = DRM_CONNECTOR_POLL_HPD;
}
@@ -4447,7 +4785,7 @@ void intel_runtime_pm_disable_interrupts(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
dev->driver->irq_uninstall(dev);
- dev_priv->pm.irqs_disabled = true;
+ dev_priv->pm._irqs_disabled = true;
}
/* Restore interrupts so we can recover from runtime PM. */
@@ -4455,7 +4793,7 @@ void intel_runtime_pm_restore_interrupts(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- dev_priv->pm.irqs_disabled = false;
+ dev_priv->pm._irqs_disabled = false;
dev->driver->irq_preinstall(dev);
dev->driver->irq_postinstall(dev);
}
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index d05a2afa17dc..62ee8308d682 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -37,7 +37,7 @@ struct i915_params i915 __read_mostly = {
.enable_fbc = -1,
.enable_hangcheck = true,
.enable_ppgtt = -1,
- .enable_psr = 0,
+ .enable_psr = 1,
.preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT),
.disable_power_well = 1,
.enable_ips = 1,
@@ -48,6 +48,8 @@ struct i915_params i915 __read_mostly = {
.disable_display = 0,
.enable_cmd_parser = 1,
.disable_vtd_wa = 0,
+ .use_mmio_flip = 0,
+ .mmio_debug = 0,
};
module_param_named(modeset, i915.modeset, int, 0400);
@@ -117,7 +119,7 @@ MODULE_PARM_DESC(enable_ppgtt,
"(-1=auto [default], 0=disabled, 1=aliasing, 2=full)");
module_param_named(enable_psr, i915.enable_psr, int, 0600);
-MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)");
+MODULE_PARM_DESC(enable_psr, "Enable PSR (default: true)");
module_param_named(preliminary_hw_support, i915.preliminary_hw_support, int, 0600);
MODULE_PARM_DESC(preliminary_hw_support,
@@ -156,3 +158,12 @@ MODULE_PARM_DESC(disable_vtd_wa, "Disable all VT-d workarounds (default: false)"
module_param_named(enable_cmd_parser, i915.enable_cmd_parser, int, 0600);
MODULE_PARM_DESC(enable_cmd_parser,
"Enable command parsing (1=enabled [default], 0=disabled)");
+
+module_param_named(use_mmio_flip, i915.use_mmio_flip, int, 0600);
+MODULE_PARM_DESC(use_mmio_flip,
+ "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)");
+
+module_param_named(mmio_debug, i915.mmio_debug, bool, 0600);
+MODULE_PARM_DESC(mmio_debug,
+ "Enable the MMIO debug code (default: false). This may negatively "
+ "affect performance.");
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e691b30b2817..e4d7607da2c4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -29,8 +29,8 @@
#define _TRANSCODER(tran, a, b) ((a) + (tran)*((b)-(a)))
#define _PORT(port, a, b) ((a) + (port)*((b)-(a)))
-#define _PIPE3(pipe, a, b, c) (pipe < 2 ? _PIPE(pipe, a, b) : c)
-#define _PORT3(port, a, b, c) (port < 2 ? _PORT(port, a, b) : c)
+#define _PIPE3(pipe, a, b, c) ((pipe) == PIPE_A ? (a) : \
+ (pipe) == PIPE_B ? (b) : (c))
#define _MASKED_BIT_ENABLE(a) (((a) << 16) | (a))
#define _MASKED_BIT_DISABLE(a) ((a) << 16)
@@ -240,7 +240,7 @@
#define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19)
#define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19)
#define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19)
-#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */
+#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */
#define MI_SEMAPHORE_GLOBAL_GTT (1<<22)
#define MI_SEMAPHORE_UPDATE (1<<21)
#define MI_SEMAPHORE_COMPARE (1<<20)
@@ -266,6 +266,11 @@
#define MI_RESTORE_EXT_STATE_EN (1<<2)
#define MI_FORCE_RESTORE (1<<1)
#define MI_RESTORE_INHIBIT (1<<0)
+#define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */
+#define MI_SEMAPHORE_TARGET(engine) ((engine)<<15)
+#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */
+#define MI_SEMAPHORE_POLL (1<<15)
+#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
@@ -360,6 +365,7 @@
#define PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE (1<<10) /* GM45+ only */
#define PIPE_CONTROL_INDIRECT_STATE_DISABLE (1<<9)
#define PIPE_CONTROL_NOTIFY (1<<8)
+#define PIPE_CONTROL_FLUSH_ENABLE (1<<7) /* gen7+ */
#define PIPE_CONTROL_VF_CACHE_INVALIDATE (1<<4)
#define PIPE_CONTROL_CONST_CACHE_INVALIDATE (1<<3)
#define PIPE_CONTROL_STATE_CACHE_INVALIDATE (1<<2)
@@ -525,10 +531,21 @@ enum punit_power_well {
#define PUNIT_REG_GPU_FREQ_STS 0xd8
#define GENFREQSTATUS (1<<0)
#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc
+#define PUNIT_REG_CZ_TIMESTAMP 0xce
#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */
#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */
+#define PUNIT_GPU_STATUS_REG 0xdb
+#define PUNIT_GPU_STATUS_MAX_FREQ_SHIFT 16
+#define PUNIT_GPU_STATUS_MAX_FREQ_MASK 0xff
+#define PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT 8
+#define PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK 0xff
+
+#define PUNIT_GPU_DUTYCYCLE_REG 0xdf
+#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT 8
+#define PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK 0xff
+
#define IOSF_NC_FB_GFX_FREQ_FUSE 0x1c
#define FB_GFX_MAX_FREQ_FUSE_SHIFT 3
#define FB_GFX_MAX_FREQ_FUSE_MASK 0x000007f8
@@ -540,6 +557,11 @@ enum punit_power_well {
#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27
#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000
+#define VLV_CZ_CLOCK_TO_MILLI_SEC 100000
+#define VLV_RP_UP_EI_THRESHOLD 90
+#define VLV_RP_DOWN_EI_THRESHOLD 70
+#define VLV_INT_COUNT_FOR_DOWN_EI 5
+
/* vlv2 north clock has */
#define CCK_FUSE_REG 0x8
#define CCK_FUSE_HPLL_FREQ_MASK 0x3
@@ -574,6 +596,11 @@ enum punit_power_well {
#define DSI_PLL_M1_DIV_SHIFT 0
#define DSI_PLL_M1_DIV_MASK (0x1ff << 0)
#define CCK_DISPLAY_CLOCK_CONTROL 0x6b
+#define DISPLAY_TRUNK_FORCE_ON (1 << 17)
+#define DISPLAY_TRUNK_FORCE_OFF (1 << 16)
+#define DISPLAY_FREQUENCY_STATUS (0x1f << 8)
+#define DISPLAY_FREQUENCY_STATUS_SHIFT 8
+#define DISPLAY_FREQUENCY_VALUES (0x1f << 0)
/**
* DOC: DPIO
@@ -761,6 +788,8 @@ enum punit_power_well {
#define _VLV_PCS_DW8_CH0 0x8220
#define _VLV_PCS_DW8_CH1 0x8420
+#define CHV_PCS_USEDCLKCHANNEL_OVRRIDE (1 << 20)
+#define CHV_PCS_USEDCLKCHANNEL (1 << 21)
#define VLV_PCS_DW8(ch) _PORT(ch, _VLV_PCS_DW8_CH0, _VLV_PCS_DW8_CH1)
#define _VLV_PCS01_DW8_CH0 0x0220
@@ -869,6 +898,16 @@ enum punit_power_well {
#define DPIO_CHV_PROP_COEFF_SHIFT 0
#define CHV_PLL_DW6(ch) _PIPE(ch, _CHV_PLL_DW6_CH0, _CHV_PLL_DW6_CH1)
+#define _CHV_CMN_DW5_CH0 0x8114
+#define CHV_BUFRIGHTENA1_DISABLE (0 << 20)
+#define CHV_BUFRIGHTENA1_NORMAL (1 << 20)
+#define CHV_BUFRIGHTENA1_FORCE (3 << 20)
+#define CHV_BUFRIGHTENA1_MASK (3 << 20)
+#define CHV_BUFLEFTENA1_DISABLE (0 << 22)
+#define CHV_BUFLEFTENA1_NORMAL (1 << 22)
+#define CHV_BUFLEFTENA1_FORCE (3 << 22)
+#define CHV_BUFLEFTENA1_MASK (3 << 22)
+
#define _CHV_CMN_DW13_CH0 0x8134
#define _CHV_CMN_DW0_CH1 0x8080
#define DPIO_CHV_S1_DIV_SHIFT 21
@@ -883,8 +922,21 @@ enum punit_power_well {
#define _CHV_CMN_DW1_CH1 0x8084
#define DPIO_AFC_RECAL (1 << 14)
#define DPIO_DCLKP_EN (1 << 13)
+#define CHV_BUFLEFTENA2_DISABLE (0 << 17) /* CL2 DW1 only */
+#define CHV_BUFLEFTENA2_NORMAL (1 << 17) /* CL2 DW1 only */
+#define CHV_BUFLEFTENA2_FORCE (3 << 17) /* CL2 DW1 only */
+#define CHV_BUFLEFTENA2_MASK (3 << 17) /* CL2 DW1 only */
+#define CHV_BUFRIGHTENA2_DISABLE (0 << 19) /* CL2 DW1 only */
+#define CHV_BUFRIGHTENA2_NORMAL (1 << 19) /* CL2 DW1 only */
+#define CHV_BUFRIGHTENA2_FORCE (3 << 19) /* CL2 DW1 only */
+#define CHV_BUFRIGHTENA2_MASK (3 << 19) /* CL2 DW1 only */
#define CHV_CMN_DW14(ch) _PIPE(ch, _CHV_CMN_DW14_CH0, _CHV_CMN_DW1_CH1)
+#define _CHV_CMN_DW19_CH0 0x814c
+#define _CHV_CMN_DW6_CH1 0x8098
+#define CHV_CMN_USEDCLKCHANNEL (1 << 13)
+#define CHV_CMN_DW19(ch) _PIPE(ch, _CHV_CMN_DW19_CH0, _CHV_CMN_DW6_CH1)
+
#define CHV_CMN_DW30 0x8178
#define DPIO_LRC_BYPASS (1 << 3)
@@ -933,6 +985,7 @@ enum punit_power_well {
#define SANDYBRIDGE_FENCE_PITCH_SHIFT 32
#define GEN7_FENCE_MAX_PITCH_VAL 0x0800
+
/* control register for cpu gtt access */
#define TILECTL 0x101000
#define TILECTL_SWZCTL (1 << 0)
@@ -942,6 +995,9 @@ enum punit_power_well {
/*
* Instruction and interrupt control regs
*/
+#define PGTBL_CTL 0x02020
+#define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */
+#define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */
#define PGTBL_ER 0x02024
#define RENDER_RING_BASE 0x02000
#define BSD_RING_BASE 0x04000
@@ -1167,6 +1223,8 @@ enum punit_power_well {
#define VLV_IMR (VLV_DISPLAY_BASE + 0x20a8)
#define VLV_ISR (VLV_DISPLAY_BASE + 0x20ac)
#define VLV_PCBR (VLV_DISPLAY_BASE + 0x2120)
+#define VLV_PCBR_ADDR_SHIFT 12
+
#define DISPLAY_PLANE_FLIP_PENDING(plane) (1<<(11-(plane))) /* A and B only */
#define EIR 0x020b0
#define EMR 0x020b4
@@ -1567,11 +1625,10 @@ enum punit_power_well {
/*
* Clock control & power management
*/
-#define DPLL_A_OFFSET 0x6014
-#define DPLL_B_OFFSET 0x6018
-#define CHV_DPLL_C_OFFSET 0x6030
-#define DPLL(pipe) (dev_priv->info.dpll_offsets[pipe] + \
- dev_priv->info.display_mmio_offset)
+#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014)
+#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018)
+#define _CHV_DPLL_C (dev_priv->info.display_mmio_offset + 0x6030)
+#define DPLL(pipe) _PIPE3((pipe), _DPLL_A, _DPLL_B, _CHV_DPLL_C)
#define VGA0 0x6000
#define VGA1 0x6004
@@ -1659,11 +1716,10 @@ enum punit_power_well {
#define SDVO_MULTIPLIER_SHIFT_HIRES 4
#define SDVO_MULTIPLIER_SHIFT_VGA 0
-#define DPLL_A_MD_OFFSET 0x601c /* 965+ only */
-#define DPLL_B_MD_OFFSET 0x6020 /* 965+ only */
-#define CHV_DPLL_C_MD_OFFSET 0x603c
-#define DPLL_MD(pipe) (dev_priv->info.dpll_md_offsets[pipe] + \
- dev_priv->info.display_mmio_offset)
+#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c)
+#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020)
+#define _CHV_DPLL_C_MD (dev_priv->info.display_mmio_offset + 0x603c)
+#define DPLL_MD(pipe) _PIPE3((pipe), _DPLL_A_MD, _DPLL_B_MD, _CHV_DPLL_C_MD)
/*
* UDI pixel divider, controlling how many pixels are stuffed into a packet.
@@ -2228,7 +2284,7 @@ enum punit_power_well {
/* Same as Haswell, but 72064 bytes now. */
#define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE)
-
+#define CHV_CLK_CTL1 0x101100
#define VLV_CLK_CTL2 0x101104
#define CLK_CTL2_CZCOUNT_30NS_SHIFT 28
@@ -2373,6 +2429,7 @@ enum punit_power_well {
#define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800)
#define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0)
#define EDP_PSR_ENABLE (1<<31)
+#define BDW_PSR_SINGLE_FRAME (1<<30)
#define EDP_PSR_LINK_DISABLE (0<<27)
#define EDP_PSR_LINK_STANDBY (1<<27)
#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25)
@@ -2530,8 +2587,14 @@ enum punit_power_well {
#define PORTC_HOTPLUG_LIVE_STATUS_VLV (1 << 28)
#define PORTB_HOTPLUG_LIVE_STATUS_VLV (1 << 29)
#define PORTD_HOTPLUG_INT_STATUS (3 << 21)
+#define PORTD_HOTPLUG_INT_LONG_PULSE (2 << 21)
+#define PORTD_HOTPLUG_INT_SHORT_PULSE (1 << 21)
#define PORTC_HOTPLUG_INT_STATUS (3 << 19)
+#define PORTC_HOTPLUG_INT_LONG_PULSE (2 << 19)
+#define PORTC_HOTPLUG_INT_SHORT_PULSE (1 << 19)
#define PORTB_HOTPLUG_INT_STATUS (3 << 17)
+#define PORTB_HOTPLUG_INT_LONG_PULSE (2 << 17)
+#define PORTB_HOTPLUG_INT_SHORT_PLUSE (1 << 17)
/* CRT/TV common between gen3+ */
#define CRT_HOTPLUG_INT_STATUS (1 << 11)
#define TV_HOTPLUG_INT_STATUS (1 << 10)
@@ -2585,7 +2648,7 @@ enum punit_power_well {
#define PORT_DFT_I9XX 0x61150
#define DC_BALANCE_RESET (1 << 25)
-#define PORT_DFT2_G4X 0x61154
+#define PORT_DFT2_G4X (dev_priv->info.display_mmio_offset + 0x61154)
#define DC_BALANCE_RESET_VLV (1 << 31)
#define PIPE_SCRAMBLE_RESET_MASK (0x3 << 0)
#define PIPE_B_SCRAMBLE_RESET (1 << 1)
@@ -3800,47 +3863,47 @@ enum punit_power_well {
/* drain latency register values*/
#define DRAIN_LATENCY_PRECISION_32 32
-#define DRAIN_LATENCY_PRECISION_16 16
+#define DRAIN_LATENCY_PRECISION_64 64
#define VLV_DDL1 (VLV_DISPLAY_BASE + 0x70050)
-#define DDL_CURSORA_PRECISION_32 (1<<31)
-#define DDL_CURSORA_PRECISION_16 (0<<31)
+#define DDL_CURSORA_PRECISION_64 (1<<31)
+#define DDL_CURSORA_PRECISION_32 (0<<31)
#define DDL_CURSORA_SHIFT 24
-#define DDL_SPRITEB_PRECISION_32 (1<<23)
-#define DDL_SPRITEB_PRECISION_16 (0<<23)
+#define DDL_SPRITEB_PRECISION_64 (1<<23)
+#define DDL_SPRITEB_PRECISION_32 (0<<23)
#define DDL_SPRITEB_SHIFT 16
-#define DDL_SPRITEA_PRECISION_32 (1<<15)
-#define DDL_SPRITEA_PRECISION_16 (0<<15)
+#define DDL_SPRITEA_PRECISION_64 (1<<15)
+#define DDL_SPRITEA_PRECISION_32 (0<<15)
#define DDL_SPRITEA_SHIFT 8
-#define DDL_PLANEA_PRECISION_32 (1<<7)
-#define DDL_PLANEA_PRECISION_16 (0<<7)
+#define DDL_PLANEA_PRECISION_64 (1<<7)
+#define DDL_PLANEA_PRECISION_32 (0<<7)
#define DDL_PLANEA_SHIFT 0
#define VLV_DDL2 (VLV_DISPLAY_BASE + 0x70054)
-#define DDL_CURSORB_PRECISION_32 (1<<31)
-#define DDL_CURSORB_PRECISION_16 (0<<31)
+#define DDL_CURSORB_PRECISION_64 (1<<31)
+#define DDL_CURSORB_PRECISION_32 (0<<31)
#define DDL_CURSORB_SHIFT 24
-#define DDL_SPRITED_PRECISION_32 (1<<23)
-#define DDL_SPRITED_PRECISION_16 (0<<23)
+#define DDL_SPRITED_PRECISION_64 (1<<23)
+#define DDL_SPRITED_PRECISION_32 (0<<23)
#define DDL_SPRITED_SHIFT 16
-#define DDL_SPRITEC_PRECISION_32 (1<<15)
-#define DDL_SPRITEC_PRECISION_16 (0<<15)
+#define DDL_SPRITEC_PRECISION_64 (1<<15)
+#define DDL_SPRITEC_PRECISION_32 (0<<15)
#define DDL_SPRITEC_SHIFT 8
-#define DDL_PLANEB_PRECISION_32 (1<<7)
-#define DDL_PLANEB_PRECISION_16 (0<<7)
+#define DDL_PLANEB_PRECISION_64 (1<<7)
+#define DDL_PLANEB_PRECISION_32 (0<<7)
#define DDL_PLANEB_SHIFT 0
#define VLV_DDL3 (VLV_DISPLAY_BASE + 0x70058)
-#define DDL_CURSORC_PRECISION_32 (1<<31)
-#define DDL_CURSORC_PRECISION_16 (0<<31)
+#define DDL_CURSORC_PRECISION_64 (1<<31)
+#define DDL_CURSORC_PRECISION_32 (0<<31)
#define DDL_CURSORC_SHIFT 24
-#define DDL_SPRITEF_PRECISION_32 (1<<23)
-#define DDL_SPRITEF_PRECISION_16 (0<<23)
+#define DDL_SPRITEF_PRECISION_64 (1<<23)
+#define DDL_SPRITEF_PRECISION_32 (0<<23)
#define DDL_SPRITEF_SHIFT 16
-#define DDL_SPRITEE_PRECISION_32 (1<<15)
-#define DDL_SPRITEE_PRECISION_16 (0<<15)
+#define DDL_SPRITEE_PRECISION_64 (1<<15)
+#define DDL_SPRITEE_PRECISION_32 (0<<15)
#define DDL_SPRITEE_SHIFT 8
-#define DDL_PLANEC_PRECISION_32 (1<<7)
-#define DDL_PLANEC_PRECISION_16 (0<<7)
+#define DDL_PLANEC_PRECISION_64 (1<<7)
+#define DDL_PLANEC_PRECISION_32 (0<<7)
#define DDL_PLANEC_SHIFT 0
/* FIFO watermark sizes etc */
@@ -4627,6 +4690,8 @@ enum punit_power_well {
#define GEN7_L3CNTLREG1 0xB01C
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C
#define GEN7_L3AGDIS (1<<19)
+#define GEN7_L3CNTLREG2 0xB020
+#define GEN7_L3CNTLREG3 0xB024
#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030
#define GEN7_WA_L3_CHICKEN_MODE 0x20000000
@@ -4873,8 +4938,7 @@ enum punit_power_well {
#define _PCH_TRANSA_LINK_M2 0xe0048
#define _PCH_TRANSA_LINK_N2 0xe004c
-/* Per-transcoder DIP controls */
-
+/* Per-transcoder DIP controls (PCH) */
#define _VIDEO_DIP_CTL_A 0xe0200
#define _VIDEO_DIP_DATA_A 0xe0208
#define _VIDEO_DIP_GCP_A 0xe0210
@@ -4887,6 +4951,7 @@ enum punit_power_well {
#define TVIDEO_DIP_DATA(pipe) _PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
#define TVIDEO_DIP_GCP(pipe) _PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
+/* Per-transcoder DIP controls (VLV) */
#define VLV_VIDEO_DIP_CTL_A (VLV_DISPLAY_BASE + 0x60200)
#define VLV_VIDEO_DIP_DATA_A (VLV_DISPLAY_BASE + 0x60208)
#define VLV_VIDEO_DIP_GDCP_PAYLOAD_A (VLV_DISPLAY_BASE + 0x60210)
@@ -4895,12 +4960,19 @@ enum punit_power_well {
#define VLV_VIDEO_DIP_DATA_B (VLV_DISPLAY_BASE + 0x61174)
#define VLV_VIDEO_DIP_GDCP_PAYLOAD_B (VLV_DISPLAY_BASE + 0x61178)
+#define CHV_VIDEO_DIP_CTL_C (VLV_DISPLAY_BASE + 0x611f0)
+#define CHV_VIDEO_DIP_DATA_C (VLV_DISPLAY_BASE + 0x611f4)
+#define CHV_VIDEO_DIP_GDCP_PAYLOAD_C (VLV_DISPLAY_BASE + 0x611f8)
+
#define VLV_TVIDEO_DIP_CTL(pipe) \
- _PIPE(pipe, VLV_VIDEO_DIP_CTL_A, VLV_VIDEO_DIP_CTL_B)
+ _PIPE3((pipe), VLV_VIDEO_DIP_CTL_A, \
+ VLV_VIDEO_DIP_CTL_B, CHV_VIDEO_DIP_CTL_C)
#define VLV_TVIDEO_DIP_DATA(pipe) \
- _PIPE(pipe, VLV_VIDEO_DIP_DATA_A, VLV_VIDEO_DIP_DATA_B)
+ _PIPE3((pipe), VLV_VIDEO_DIP_DATA_A, \
+ VLV_VIDEO_DIP_DATA_B, CHV_VIDEO_DIP_DATA_C)
#define VLV_TVIDEO_DIP_GCP(pipe) \
- _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B)
+ _PIPE3((pipe), VLV_VIDEO_DIP_GDCP_PAYLOAD_A, \
+ VLV_VIDEO_DIP_GDCP_PAYLOAD_B, CHV_VIDEO_DIP_GDCP_PAYLOAD_C)
/* Haswell DIP controls */
#define HSW_VIDEO_DIP_CTL_A 0x60200
@@ -5331,6 +5403,7 @@ enum punit_power_well {
#define VLV_GTLC_ALLOWWAKEERR (1 << 1)
#define VLV_GTLC_PW_MEDIA_STATUS_MASK (1 << 5)
#define VLV_GTLC_PW_RENDER_STATUS_MASK (1 << 7)
+#define VLV_GTLC_SURVIVABILITY_REG 0x130098
#define FORCEWAKE_MT 0xa188 /* multi-threaded */
#define FORCEWAKE_KERNEL 0x1
#define FORCEWAKE_USER 0x2
@@ -5468,6 +5541,12 @@ enum punit_power_well {
GEN6_PM_RP_DOWN_THRESHOLD | \
GEN6_PM_RP_DOWN_TIMEOUT)
+#define CHV_CZ_CLOCK_FREQ_MODE_200 200
+#define CHV_CZ_CLOCK_FREQ_MODE_267 267
+#define CHV_CZ_CLOCK_FREQ_MODE_320 320
+#define CHV_CZ_CLOCK_FREQ_MODE_333 333
+#define CHV_CZ_CLOCK_FREQ_MODE_400 400
+
#define GEN7_GT_SCRATCH_BASE 0x4F100
#define GEN7_GT_SCRATCH_REG_NUM 8
@@ -5478,6 +5557,8 @@ enum punit_power_well {
#define GEN6_GT_GFX_RC6_LOCKED 0x138104
#define VLV_COUNTER_CONTROL 0x138104
#define VLV_COUNT_RANGE_HIGH (1<<15)
+#define VLV_MEDIA_RC0_COUNT_EN (1<<5)
+#define VLV_RENDER_RC0_COUNT_EN (1<<4)
#define VLV_MEDIA_RC6_COUNT_EN (1<<1)
#define VLV_RENDER_RC6_COUNT_EN (1<<0)
#define GEN6_GT_GFX_RC6 0x138108
@@ -5486,6 +5567,8 @@ enum punit_power_well {
#define GEN6_GT_GFX_RC6p 0x13810C
#define GEN6_GT_GFX_RC6pp 0x138110
+#define VLV_RENDER_C0_COUNT_REG 0x138118
+#define VLV_MEDIA_C0_COUNT_REG 0x13811C
#define GEN6_PCODE_MAILBOX 0x138124
#define GEN6_PCODE_READY (1<<31)
@@ -5720,6 +5803,7 @@ enum punit_power_well {
#define TRANS_DDI_FUNC_ENABLE (1<<31)
/* Those bits are ignored by pipe EDP since it can only connect to DDI A */
#define TRANS_DDI_PORT_MASK (7<<28)
+#define TRANS_DDI_PORT_SHIFT 28
#define TRANS_DDI_SELECT_PORT(x) ((x)<<28)
#define TRANS_DDI_PORT_NONE (0<<28)
#define TRANS_DDI_MODE_SELECT_MASK (7<<24)
@@ -5740,6 +5824,7 @@ enum punit_power_well {
#define TRANS_DDI_EDP_INPUT_A_ONOFF (4<<12)
#define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12)
#define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12)
+#define TRANS_DDI_DP_VC_PAYLOAD_ALLOC (1<<8)
#define TRANS_DDI_BFI_ENABLE (1<<4)
/* DisplayPort Transport Control */
@@ -5749,6 +5834,7 @@ enum punit_power_well {
#define DP_TP_CTL_ENABLE (1<<31)
#define DP_TP_CTL_MODE_SST (0<<27)
#define DP_TP_CTL_MODE_MST (1<<27)
+#define DP_TP_CTL_FORCE_ACT (1<<25)
#define DP_TP_CTL_ENHANCED_FRAME_ENABLE (1<<18)
#define DP_TP_CTL_FDI_AUTOTRAIN (1<<15)
#define DP_TP_CTL_LINK_TRAIN_MASK (7<<8)
@@ -5763,15 +5849,19 @@ enum punit_power_well {
#define DP_TP_STATUS_A 0x64044
#define DP_TP_STATUS_B 0x64144
#define DP_TP_STATUS(port) _PORT(port, DP_TP_STATUS_A, DP_TP_STATUS_B)
-#define DP_TP_STATUS_IDLE_DONE (1<<25)
-#define DP_TP_STATUS_AUTOTRAIN_DONE (1<<12)
+#define DP_TP_STATUS_IDLE_DONE (1<<25)
+#define DP_TP_STATUS_ACT_SENT (1<<24)
+#define DP_TP_STATUS_MODE_STATUS_MST (1<<23)
+#define DP_TP_STATUS_AUTOTRAIN_DONE (1<<12)
+#define DP_TP_STATUS_PAYLOAD_MAPPING_VC2 (3 << 8)
+#define DP_TP_STATUS_PAYLOAD_MAPPING_VC1 (3 << 4)
+#define DP_TP_STATUS_PAYLOAD_MAPPING_VC0 (3 << 0)
/* DDI Buffer Control */
#define DDI_BUF_CTL_A 0x64000
#define DDI_BUF_CTL_B 0x64100
#define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B)
#define DDI_BUF_CTL_ENABLE (1<<31)
-/* Haswell */
#define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */
#define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */
#define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */
@@ -5781,16 +5871,6 @@ enum punit_power_well {
#define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */
#define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */
#define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */
-/* Broadwell */
-#define DDI_BUF_EMP_400MV_0DB_BDW (0<<24) /* Sel0 */
-#define DDI_BUF_EMP_400MV_3_5DB_BDW (1<<24) /* Sel1 */
-#define DDI_BUF_EMP_400MV_6DB_BDW (2<<24) /* Sel2 */
-#define DDI_BUF_EMP_600MV_0DB_BDW (3<<24) /* Sel3 */
-#define DDI_BUF_EMP_600MV_3_5DB_BDW (4<<24) /* Sel4 */
-#define DDI_BUF_EMP_600MV_6DB_BDW (5<<24) /* Sel5 */
-#define DDI_BUF_EMP_800MV_0DB_BDW (6<<24) /* Sel6 */
-#define DDI_BUF_EMP_800MV_3_5DB_BDW (7<<24) /* Sel7 */
-#define DDI_BUF_EMP_1200MV_0DB_BDW (8<<24) /* Sel8 */
#define DDI_BUF_EMP_MASK (0xf<<24)
#define DDI_BUF_PORT_REVERSAL (1<<16)
#define DDI_BUF_IS_IDLE (1<<7)
@@ -5858,10 +5938,12 @@ enum punit_power_well {
/* WRPLL */
#define WRPLL_CTL1 0x46040
#define WRPLL_CTL2 0x46060
+#define WRPLL_CTL(pll) (pll == 0 ? WRPLL_CTL1 : WRPLL_CTL2)
#define WRPLL_PLL_ENABLE (1<<31)
-#define WRPLL_PLL_SELECT_SSC (0x01<<28)
-#define WRPLL_PLL_SELECT_NON_SSC (0x02<<28)
-#define WRPLL_PLL_SELECT_LCPLL_2700 (0x03<<28)
+#define WRPLL_PLL_SSC (1<<28)
+#define WRPLL_PLL_NON_SSC (2<<28)
+#define WRPLL_PLL_LCPLL (3<<28)
+#define WRPLL_PLL_REF_MASK (3<<28)
/* WRPLL divider programming */
#define WRPLL_DIVIDER_REFERENCE(x) ((x)<<0)
#define WRPLL_DIVIDER_REF_MASK (0xff)
@@ -5880,6 +5962,7 @@ enum punit_power_well {
#define PORT_CLK_SEL_LCPLL_1350 (1<<29)
#define PORT_CLK_SEL_LCPLL_810 (2<<29)
#define PORT_CLK_SEL_SPLL (3<<29)
+#define PORT_CLK_SEL_WRPLL(pll) (((pll)+4)<<29)
#define PORT_CLK_SEL_WRPLL1 (4<<29)
#define PORT_CLK_SEL_WRPLL2 (5<<29)
#define PORT_CLK_SEL_NONE (7<<29)
@@ -5921,7 +6004,10 @@ enum punit_power_well {
#define LCPLL_CD_SOURCE_FCLK (1<<21)
#define LCPLL_CD_SOURCE_FCLK_DONE (1<<19)
-#define D_COMP (MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
+/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
+ * since on HSW we can't write to it using I915_WRITE. */
+#define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
+#define D_COMP_BDW 0x138144
#define D_COMP_RCOMP_IN_PROGRESS (1<<9)
#define D_COMP_COMP_FORCE (1<<8)
#define D_COMP_COMP_DISABLE (1<<0)
@@ -6002,7 +6088,8 @@ enum punit_power_well {
#define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190)
#define _MIPIB_PORT_CTRL (VLV_DISPLAY_BASE + 0x61700)
-#define MIPI_PORT_CTRL(pipe) _PIPE(pipe, _MIPIA_PORT_CTRL, _MIPIB_PORT_CTRL)
+#define MIPI_PORT_CTRL(tc) _TRANSCODER(tc, _MIPIA_PORT_CTRL, \
+ _MIPIB_PORT_CTRL)
#define DPI_ENABLE (1 << 31) /* A + B */
#define MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
#define MIPIA_MIPI4DPHY_DELAY_COUNT_MASK (0xf << 27)
@@ -6044,18 +6131,20 @@ enum punit_power_well {
#define _MIPIA_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61194)
#define _MIPIB_TEARING_CTRL (VLV_DISPLAY_BASE + 0x61704)
-#define MIPI_TEARING_CTRL(pipe) _PIPE(pipe, _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL)
+#define MIPI_TEARING_CTRL(tc) _TRANSCODER(tc, \
+ _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL)
#define TEARING_EFFECT_DELAY_SHIFT 0
#define TEARING_EFFECT_DELAY_MASK (0xffff << 0)
/* XXX: all bits reserved */
-#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0)
+#define _MIPIA_AUTOPWG (VLV_DISPLAY_BASE + 0x611a0)
/* MIPI DSI Controller and D-PHY registers */
-#define _MIPIA_DEVICE_READY (VLV_DISPLAY_BASE + 0xb000)
-#define _MIPIB_DEVICE_READY (VLV_DISPLAY_BASE + 0xb800)
-#define MIPI_DEVICE_READY(pipe) _PIPE(pipe, _MIPIA_DEVICE_READY, _MIPIB_DEVICE_READY)
+#define _MIPIA_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb000)
+#define _MIPIB_DEVICE_READY (dev_priv->mipi_mmio_base + 0xb800)
+#define MIPI_DEVICE_READY(tc) _TRANSCODER(tc, _MIPIA_DEVICE_READY, \
+ _MIPIB_DEVICE_READY)
#define BUS_POSSESSION (1 << 3) /* set to give bus to receiver */
#define ULPS_STATE_MASK (3 << 1)
#define ULPS_STATE_ENTER (2 << 1)
@@ -6063,12 +6152,14 @@ enum punit_power_well {
#define ULPS_STATE_NORMAL_OPERATION (0 << 1)
#define DEVICE_READY (1 << 0)
-#define _MIPIA_INTR_STAT (VLV_DISPLAY_BASE + 0xb004)
-#define _MIPIB_INTR_STAT (VLV_DISPLAY_BASE + 0xb804)
-#define MIPI_INTR_STAT(pipe) _PIPE(pipe, _MIPIA_INTR_STAT, _MIPIB_INTR_STAT)
-#define _MIPIA_INTR_EN (VLV_DISPLAY_BASE + 0xb008)
-#define _MIPIB_INTR_EN (VLV_DISPLAY_BASE + 0xb808)
-#define MIPI_INTR_EN(pipe) _PIPE(pipe, _MIPIA_INTR_EN, _MIPIB_INTR_EN)
+#define _MIPIA_INTR_STAT (dev_priv->mipi_mmio_base + 0xb004)
+#define _MIPIB_INTR_STAT (dev_priv->mipi_mmio_base + 0xb804)
+#define MIPI_INTR_STAT(tc) _TRANSCODER(tc, _MIPIA_INTR_STAT, \
+ _MIPIB_INTR_STAT)
+#define _MIPIA_INTR_EN (dev_priv->mipi_mmio_base + 0xb008)
+#define _MIPIB_INTR_EN (dev_priv->mipi_mmio_base + 0xb808)
+#define MIPI_INTR_EN(tc) _TRANSCODER(tc, _MIPIA_INTR_EN, \
+ _MIPIB_INTR_EN)
#define TEARING_EFFECT (1 << 31)
#define SPL_PKT_SENT_INTERRUPT (1 << 30)
#define GEN_READ_DATA_AVAIL (1 << 29)
@@ -6102,9 +6193,10 @@ enum punit_power_well {
#define RXSOT_SYNC_ERROR (1 << 1)
#define RXSOT_ERROR (1 << 0)
-#define _MIPIA_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb00c)
-#define _MIPIB_DSI_FUNC_PRG (VLV_DISPLAY_BASE + 0xb80c)
-#define MIPI_DSI_FUNC_PRG(pipe) _PIPE(pipe, _MIPIA_DSI_FUNC_PRG, _MIPIB_DSI_FUNC_PRG)
+#define _MIPIA_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb00c)
+#define _MIPIB_DSI_FUNC_PRG (dev_priv->mipi_mmio_base + 0xb80c)
+#define MIPI_DSI_FUNC_PRG(tc) _TRANSCODER(tc, _MIPIA_DSI_FUNC_PRG, \
+ _MIPIB_DSI_FUNC_PRG)
#define CMD_MODE_DATA_WIDTH_MASK (7 << 13)
#define CMD_MODE_NOT_SUPPORTED (0 << 13)
#define CMD_MODE_DATA_WIDTH_16_BIT (1 << 13)
@@ -6125,78 +6217,94 @@ enum punit_power_well {
#define DATA_LANES_PRG_REG_SHIFT 0
#define DATA_LANES_PRG_REG_MASK (7 << 0)
-#define _MIPIA_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb010)
-#define _MIPIB_HS_TX_TIMEOUT (VLV_DISPLAY_BASE + 0xb810)
-#define MIPI_HS_TX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_HS_TX_TIMEOUT, _MIPIB_HS_TX_TIMEOUT)
+#define _MIPIA_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb010)
+#define _MIPIB_HS_TX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb810)
+#define MIPI_HS_TX_TIMEOUT(tc) _TRANSCODER(tc, _MIPIA_HS_TX_TIMEOUT, \
+ _MIPIB_HS_TX_TIMEOUT)
#define HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK 0xffffff
-#define _MIPIA_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb014)
-#define _MIPIB_LP_RX_TIMEOUT (VLV_DISPLAY_BASE + 0xb814)
-#define MIPI_LP_RX_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_LP_RX_TIMEOUT, _MIPIB_LP_RX_TIMEOUT)
+#define _MIPIA_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb014)
+#define _MIPIB_LP_RX_TIMEOUT (dev_priv->mipi_mmio_base + 0xb814)
+#define MIPI_LP_RX_TIMEOUT(tc) _TRANSCODER(tc, _MIPIA_LP_RX_TIMEOUT, \
+ _MIPIB_LP_RX_TIMEOUT)
#define LOW_POWER_RX_TIMEOUT_COUNTER_MASK 0xffffff
-#define _MIPIA_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb018)
-#define _MIPIB_TURN_AROUND_TIMEOUT (VLV_DISPLAY_BASE + 0xb818)
-#define MIPI_TURN_AROUND_TIMEOUT(pipe) _PIPE(pipe, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT)
+#define _MIPIA_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb018)
+#define _MIPIB_TURN_AROUND_TIMEOUT (dev_priv->mipi_mmio_base + 0xb818)
+#define MIPI_TURN_AROUND_TIMEOUT(tc) _TRANSCODER(tc, \
+ _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT)
#define TURN_AROUND_TIMEOUT_MASK 0x3f
-#define _MIPIA_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb01c)
-#define _MIPIB_DEVICE_RESET_TIMER (VLV_DISPLAY_BASE + 0xb81c)
-#define MIPI_DEVICE_RESET_TIMER(pipe) _PIPE(pipe, _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER)
+#define _MIPIA_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb01c)
+#define _MIPIB_DEVICE_RESET_TIMER (dev_priv->mipi_mmio_base + 0xb81c)
+#define MIPI_DEVICE_RESET_TIMER(tc) _TRANSCODER(tc, \
+ _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER)
#define DEVICE_RESET_TIMER_MASK 0xffff
-#define _MIPIA_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb020)
-#define _MIPIB_DPI_RESOLUTION (VLV_DISPLAY_BASE + 0xb820)
-#define MIPI_DPI_RESOLUTION(pipe) _PIPE(pipe, _MIPIA_DPI_RESOLUTION, _MIPIB_DPI_RESOLUTION)
+#define _MIPIA_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb020)
+#define _MIPIB_DPI_RESOLUTION (dev_priv->mipi_mmio_base + 0xb820)
+#define MIPI_DPI_RESOLUTION(tc) _TRANSCODER(tc, _MIPIA_DPI_RESOLUTION, \
+ _MIPIB_DPI_RESOLUTION)
#define VERTICAL_ADDRESS_SHIFT 16
#define VERTICAL_ADDRESS_MASK (0xffff << 16)
#define HORIZONTAL_ADDRESS_SHIFT 0
#define HORIZONTAL_ADDRESS_MASK 0xffff
-#define _MIPIA_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb024)
-#define _MIPIB_DBI_FIFO_THROTTLE (VLV_DISPLAY_BASE + 0xb824)
-#define MIPI_DBI_FIFO_THROTTLE(pipe) _PIPE(pipe, _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE)
+#define _MIPIA_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb024)
+#define _MIPIB_DBI_FIFO_THROTTLE (dev_priv->mipi_mmio_base + 0xb824)
+#define MIPI_DBI_FIFO_THROTTLE(tc) _TRANSCODER(tc, \
+ _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE)
#define DBI_FIFO_EMPTY_HALF (0 << 0)
#define DBI_FIFO_EMPTY_QUARTER (1 << 0)
#define DBI_FIFO_EMPTY_7_LOCATIONS (2 << 0)
/* regs below are bits 15:0 */
-#define _MIPIA_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb028)
-#define _MIPIB_HSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb828)
-#define MIPI_HSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT)
-
-#define _MIPIA_HBP_COUNT (VLV_DISPLAY_BASE + 0xb02c)
-#define _MIPIB_HBP_COUNT (VLV_DISPLAY_BASE + 0xb82c)
-#define MIPI_HBP_COUNT(pipe) _PIPE(pipe, _MIPIA_HBP_COUNT, _MIPIB_HBP_COUNT)
-
-#define _MIPIA_HFP_COUNT (VLV_DISPLAY_BASE + 0xb030)
-#define _MIPIB_HFP_COUNT (VLV_DISPLAY_BASE + 0xb830)
-#define MIPI_HFP_COUNT(pipe) _PIPE(pipe, _MIPIA_HFP_COUNT, _MIPIB_HFP_COUNT)
-
-#define _MIPIA_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb034)
-#define _MIPIB_HACTIVE_AREA_COUNT (VLV_DISPLAY_BASE + 0xb834)
-#define MIPI_HACTIVE_AREA_COUNT(pipe) _PIPE(pipe, _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT)
-
-#define _MIPIA_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb038)
-#define _MIPIB_VSYNC_PADDING_COUNT (VLV_DISPLAY_BASE + 0xb838)
-#define MIPI_VSYNC_PADDING_COUNT(pipe) _PIPE(pipe, _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT)
+#define _MIPIA_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb028)
+#define _MIPIB_HSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb828)
+#define MIPI_HSYNC_PADDING_COUNT(tc) _TRANSCODER(tc, \
+ _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT)
+
+#define _MIPIA_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb02c)
+#define _MIPIB_HBP_COUNT (dev_priv->mipi_mmio_base + 0xb82c)
+#define MIPI_HBP_COUNT(tc) _TRANSCODER(tc, _MIPIA_HBP_COUNT, \
+ _MIPIB_HBP_COUNT)
+
+#define _MIPIA_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb030)
+#define _MIPIB_HFP_COUNT (dev_priv->mipi_mmio_base + 0xb830)
+#define MIPI_HFP_COUNT(tc) _TRANSCODER(tc, _MIPIA_HFP_COUNT, \
+ _MIPIB_HFP_COUNT)
+
+#define _MIPIA_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb034)
+#define _MIPIB_HACTIVE_AREA_COUNT (dev_priv->mipi_mmio_base + 0xb834)
+#define MIPI_HACTIVE_AREA_COUNT(tc) _TRANSCODER(tc, \
+ _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT)
+
+#define _MIPIA_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb038)
+#define _MIPIB_VSYNC_PADDING_COUNT (dev_priv->mipi_mmio_base + 0xb838)
+#define MIPI_VSYNC_PADDING_COUNT(tc) _TRANSCODER(tc, \
+ _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT)
+
+#define _MIPIA_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb03c)
+#define _MIPIB_VBP_COUNT (dev_priv->mipi_mmio_base + 0xb83c)
+#define MIPI_VBP_COUNT(tc) _TRANSCODER(tc, _MIPIA_VBP_COUNT, \
+ _MIPIB_VBP_COUNT)
+
+#define _MIPIA_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb040)
+#define _MIPIB_VFP_COUNT (dev_priv->mipi_mmio_base + 0xb840)
+#define MIPI_VFP_COUNT(tc) _TRANSCODER(tc, _MIPIA_VFP_COUNT, \
+ _MIPIB_VFP_COUNT)
+
+#define _MIPIA_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb044)
+#define _MIPIB_HIGH_LOW_SWITCH_COUNT (dev_priv->mipi_mmio_base + 0xb844)
+#define MIPI_HIGH_LOW_SWITCH_COUNT(tc) _TRANSCODER(tc, \
+ _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT)
-#define _MIPIA_VBP_COUNT (VLV_DISPLAY_BASE + 0xb03c)
-#define _MIPIB_VBP_COUNT (VLV_DISPLAY_BASE + 0xb83c)
-#define MIPI_VBP_COUNT(pipe) _PIPE(pipe, _MIPIA_VBP_COUNT, _MIPIB_VBP_COUNT)
-
-#define _MIPIA_VFP_COUNT (VLV_DISPLAY_BASE + 0xb040)
-#define _MIPIB_VFP_COUNT (VLV_DISPLAY_BASE + 0xb840)
-#define MIPI_VFP_COUNT(pipe) _PIPE(pipe, _MIPIA_VFP_COUNT, _MIPIB_VFP_COUNT)
-
-#define _MIPIA_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb044)
-#define _MIPIB_HIGH_LOW_SWITCH_COUNT (VLV_DISPLAY_BASE + 0xb844)
-#define MIPI_HIGH_LOW_SWITCH_COUNT(pipe) _PIPE(pipe, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT)
/* regs above are bits 15:0 */
-#define _MIPIA_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb048)
-#define _MIPIB_DPI_CONTROL (VLV_DISPLAY_BASE + 0xb848)
-#define MIPI_DPI_CONTROL(pipe) _PIPE(pipe, _MIPIA_DPI_CONTROL, _MIPIB_DPI_CONTROL)
+#define _MIPIA_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb048)
+#define _MIPIB_DPI_CONTROL (dev_priv->mipi_mmio_base + 0xb848)
+#define MIPI_DPI_CONTROL(tc) _TRANSCODER(tc, _MIPIA_DPI_CONTROL, \
+ _MIPIB_DPI_CONTROL)
#define DPI_LP_MODE (1 << 6)
#define BACKLIGHT_OFF (1 << 5)
#define BACKLIGHT_ON (1 << 4)
@@ -6205,27 +6313,31 @@ enum punit_power_well {
#define TURN_ON (1 << 1)
#define SHUTDOWN (1 << 0)
-#define _MIPIA_DPI_DATA (VLV_DISPLAY_BASE + 0xb04c)
-#define _MIPIB_DPI_DATA (VLV_DISPLAY_BASE + 0xb84c)
-#define MIPI_DPI_DATA(pipe) _PIPE(pipe, _MIPIA_DPI_DATA, _MIPIB_DPI_DATA)
+#define _MIPIA_DPI_DATA (dev_priv->mipi_mmio_base + 0xb04c)
+#define _MIPIB_DPI_DATA (dev_priv->mipi_mmio_base + 0xb84c)
+#define MIPI_DPI_DATA(tc) _TRANSCODER(tc, _MIPIA_DPI_DATA, \
+ _MIPIB_DPI_DATA)
#define COMMAND_BYTE_SHIFT 0
#define COMMAND_BYTE_MASK (0x3f << 0)
-#define _MIPIA_INIT_COUNT (VLV_DISPLAY_BASE + 0xb050)
-#define _MIPIB_INIT_COUNT (VLV_DISPLAY_BASE + 0xb850)
-#define MIPI_INIT_COUNT(pipe) _PIPE(pipe, _MIPIA_INIT_COUNT, _MIPIB_INIT_COUNT)
+#define _MIPIA_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb050)
+#define _MIPIB_INIT_COUNT (dev_priv->mipi_mmio_base + 0xb850)
+#define MIPI_INIT_COUNT(tc) _TRANSCODER(tc, _MIPIA_INIT_COUNT, \
+ _MIPIB_INIT_COUNT)
#define MASTER_INIT_TIMER_SHIFT 0
#define MASTER_INIT_TIMER_MASK (0xffff << 0)
-#define _MIPIA_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb054)
-#define _MIPIB_MAX_RETURN_PKT_SIZE (VLV_DISPLAY_BASE + 0xb854)
-#define MIPI_MAX_RETURN_PKT_SIZE(pipe) _PIPE(pipe, _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE)
+#define _MIPIA_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb054)
+#define _MIPIB_MAX_RETURN_PKT_SIZE (dev_priv->mipi_mmio_base + 0xb854)
+#define MIPI_MAX_RETURN_PKT_SIZE(tc) _TRANSCODER(tc, \
+ _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE)
#define MAX_RETURN_PKT_SIZE_SHIFT 0
#define MAX_RETURN_PKT_SIZE_MASK (0x3ff << 0)
-#define _MIPIA_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb058)
-#define _MIPIB_VIDEO_MODE_FORMAT (VLV_DISPLAY_BASE + 0xb858)
-#define MIPI_VIDEO_MODE_FORMAT(pipe) _PIPE(pipe, _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT)
+#define _MIPIA_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb058)
+#define _MIPIB_VIDEO_MODE_FORMAT (dev_priv->mipi_mmio_base + 0xb858)
+#define MIPI_VIDEO_MODE_FORMAT(tc) _TRANSCODER(tc, \
+ _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT)
#define RANDOM_DPI_DISPLAY_RESOLUTION (1 << 4)
#define DISABLE_VIDEO_BTA (1 << 3)
#define IP_TG_CONFIG (1 << 2)
@@ -6233,9 +6345,10 @@ enum punit_power_well {
#define VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS (2 << 0)
#define VIDEO_MODE_BURST (3 << 0)
-#define _MIPIA_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb05c)
-#define _MIPIB_EOT_DISABLE (VLV_DISPLAY_BASE + 0xb85c)
-#define MIPI_EOT_DISABLE(pipe) _PIPE(pipe, _MIPIA_EOT_DISABLE, _MIPIB_EOT_DISABLE)
+#define _MIPIA_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb05c)
+#define _MIPIB_EOT_DISABLE (dev_priv->mipi_mmio_base + 0xb85c)
+#define MIPI_EOT_DISABLE(tc) _TRANSCODER(tc, _MIPIA_EOT_DISABLE, \
+ _MIPIB_EOT_DISABLE)
#define LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 7)
#define HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE (1 << 6)
#define LOW_CONTENTION_RECOVERY_DISABLE (1 << 5)
@@ -6245,28 +6358,33 @@ enum punit_power_well {
#define CLOCKSTOP (1 << 1)
#define EOT_DISABLE (1 << 0)
-#define _MIPIA_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb060)
-#define _MIPIB_LP_BYTECLK (VLV_DISPLAY_BASE + 0xb860)
-#define MIPI_LP_BYTECLK(pipe) _PIPE(pipe, _MIPIA_LP_BYTECLK, _MIPIB_LP_BYTECLK)
+#define _MIPIA_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb060)
+#define _MIPIB_LP_BYTECLK (dev_priv->mipi_mmio_base + 0xb860)
+#define MIPI_LP_BYTECLK(tc) _TRANSCODER(tc, _MIPIA_LP_BYTECLK, \
+ _MIPIB_LP_BYTECLK)
#define LP_BYTECLK_SHIFT 0
#define LP_BYTECLK_MASK (0xffff << 0)
/* bits 31:0 */
-#define _MIPIA_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb064)
-#define _MIPIB_LP_GEN_DATA (VLV_DISPLAY_BASE + 0xb864)
-#define MIPI_LP_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_LP_GEN_DATA, _MIPIB_LP_GEN_DATA)
+#define _MIPIA_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb064)
+#define _MIPIB_LP_GEN_DATA (dev_priv->mipi_mmio_base + 0xb864)
+#define MIPI_LP_GEN_DATA(tc) _TRANSCODER(tc, _MIPIA_LP_GEN_DATA, \
+ _MIPIB_LP_GEN_DATA)
/* bits 31:0 */
-#define _MIPIA_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb068)
-#define _MIPIB_HS_GEN_DATA (VLV_DISPLAY_BASE + 0xb868)
-#define MIPI_HS_GEN_DATA(pipe) _PIPE(pipe, _MIPIA_HS_GEN_DATA, _MIPIB_HS_GEN_DATA)
-
-#define _MIPIA_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb06c)
-#define _MIPIB_LP_GEN_CTRL (VLV_DISPLAY_BASE + 0xb86c)
-#define MIPI_LP_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_LP_GEN_CTRL, _MIPIB_LP_GEN_CTRL)
-#define _MIPIA_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb070)
-#define _MIPIB_HS_GEN_CTRL (VLV_DISPLAY_BASE + 0xb870)
-#define MIPI_HS_GEN_CTRL(pipe) _PIPE(pipe, _MIPIA_HS_GEN_CTRL, _MIPIB_HS_GEN_CTRL)
+#define _MIPIA_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb068)
+#define _MIPIB_HS_GEN_DATA (dev_priv->mipi_mmio_base + 0xb868)
+#define MIPI_HS_GEN_DATA(tc) _TRANSCODER(tc, _MIPIA_HS_GEN_DATA, \
+ _MIPIB_HS_GEN_DATA)
+
+#define _MIPIA_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb06c)
+#define _MIPIB_LP_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb86c)
+#define MIPI_LP_GEN_CTRL(tc) _TRANSCODER(tc, _MIPIA_LP_GEN_CTRL, \
+ _MIPIB_LP_GEN_CTRL)
+#define _MIPIA_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb070)
+#define _MIPIB_HS_GEN_CTRL (dev_priv->mipi_mmio_base + 0xb870)
+#define MIPI_HS_GEN_CTRL(tc) _TRANSCODER(tc, _MIPIA_HS_GEN_CTRL, \
+ _MIPIB_HS_GEN_CTRL)
#define LONG_PACKET_WORD_COUNT_SHIFT 8
#define LONG_PACKET_WORD_COUNT_MASK (0xffff << 8)
#define SHORT_PACKET_PARAM_SHIFT 8
@@ -6277,9 +6395,10 @@ enum punit_power_well {
#define DATA_TYPE_MASK (3f << 0)
/* data type values, see include/video/mipi_display.h */
-#define _MIPIA_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb074)
-#define _MIPIB_GEN_FIFO_STAT (VLV_DISPLAY_BASE + 0xb874)
-#define MIPI_GEN_FIFO_STAT(pipe) _PIPE(pipe, _MIPIA_GEN_FIFO_STAT, _MIPIB_GEN_FIFO_STAT)
+#define _MIPIA_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb074)
+#define _MIPIB_GEN_FIFO_STAT (dev_priv->mipi_mmio_base + 0xb874)
+#define MIPI_GEN_FIFO_STAT(tc) _TRANSCODER(tc, _MIPIA_GEN_FIFO_STAT, \
+ _MIPIB_GEN_FIFO_STAT)
#define DPI_FIFO_EMPTY (1 << 28)
#define DBI_FIFO_EMPTY (1 << 27)
#define LP_CTRL_FIFO_EMPTY (1 << 26)
@@ -6295,16 +6414,18 @@ enum punit_power_well {
#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
#define HS_DATA_FIFO_FULL (1 << 0)
-#define _MIPIA_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb078)
-#define _MIPIB_HS_LS_DBI_ENABLE (VLV_DISPLAY_BASE + 0xb878)
-#define MIPI_HS_LP_DBI_ENABLE(pipe) _PIPE(pipe, _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE)
+#define _MIPIA_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb078)
+#define _MIPIB_HS_LS_DBI_ENABLE (dev_priv->mipi_mmio_base + 0xb878)
+#define MIPI_HS_LP_DBI_ENABLE(tc) _TRANSCODER(tc, \
+ _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE)
#define DBI_HS_LP_MODE_MASK (1 << 0)
#define DBI_LP_MODE (1 << 0)
#define DBI_HS_MODE (0 << 0)
-#define _MIPIA_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb080)
-#define _MIPIB_DPHY_PARAM (VLV_DISPLAY_BASE + 0xb880)
-#define MIPI_DPHY_PARAM(pipe) _PIPE(pipe, _MIPIA_DPHY_PARAM, _MIPIB_DPHY_PARAM)
+#define _MIPIA_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb080)
+#define _MIPIB_DPHY_PARAM (dev_priv->mipi_mmio_base + 0xb880)
+#define MIPI_DPHY_PARAM(tc) _TRANSCODER(tc, _MIPIA_DPHY_PARAM, \
+ _MIPIB_DPHY_PARAM)
#define EXIT_ZERO_COUNT_SHIFT 24
#define EXIT_ZERO_COUNT_MASK (0x3f << 24)
#define TRAIL_COUNT_SHIFT 16
@@ -6315,34 +6436,41 @@ enum punit_power_well {
#define PREPARE_COUNT_MASK (0x3f << 0)
/* bits 31:0 */
-#define _MIPIA_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb084)
-#define _MIPIB_DBI_BW_CTRL (VLV_DISPLAY_BASE + 0xb884)
-#define MIPI_DBI_BW_CTRL(pipe) _PIPE(pipe, _MIPIA_DBI_BW_CTRL, _MIPIB_DBI_BW_CTRL)
-
-#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb088)
-#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (VLV_DISPLAY_BASE + 0xb888)
-#define MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe) _PIPE(pipe, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT)
+#define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084)
+#define _MIPIB_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884)
+#define MIPI_DBI_BW_CTRL(tc) _TRANSCODER(tc, _MIPIA_DBI_BW_CTRL, \
+ _MIPIB_DBI_BW_CTRL)
+
+#define _MIPIA_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base \
+ + 0xb088)
+#define _MIPIB_CLK_LANE_SWITCH_TIME_CNT (dev_priv->mipi_mmio_base \
+ + 0xb888)
+#define MIPI_CLK_LANE_SWITCH_TIME_CNT(tc) _TRANSCODER(tc, \
+ _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT)
#define LP_HS_SSW_CNT_SHIFT 16
#define LP_HS_SSW_CNT_MASK (0xffff << 16)
#define HS_LP_PWR_SW_CNT_SHIFT 0
#define HS_LP_PWR_SW_CNT_MASK (0xffff << 0)
-#define _MIPIA_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb08c)
-#define _MIPIB_STOP_STATE_STALL (VLV_DISPLAY_BASE + 0xb88c)
-#define MIPI_STOP_STATE_STALL(pipe) _PIPE(pipe, _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL)
+#define _MIPIA_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb08c)
+#define _MIPIB_STOP_STATE_STALL (dev_priv->mipi_mmio_base + 0xb88c)
+#define MIPI_STOP_STATE_STALL(tc) _TRANSCODER(tc, \
+ _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL)
#define STOP_STATE_STALL_COUNTER_SHIFT 0
#define STOP_STATE_STALL_COUNTER_MASK (0xff << 0)
-#define _MIPIA_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb090)
-#define _MIPIB_INTR_STAT_REG_1 (VLV_DISPLAY_BASE + 0xb890)
-#define MIPI_INTR_STAT_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1)
-#define _MIPIA_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb094)
-#define _MIPIB_INTR_EN_REG_1 (VLV_DISPLAY_BASE + 0xb894)
-#define MIPI_INTR_EN_REG_1(pipe) _PIPE(pipe, _MIPIA_INTR_EN_REG_1, _MIPIB_INTR_EN_REG_1)
+#define _MIPIA_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb090)
+#define _MIPIB_INTR_STAT_REG_1 (dev_priv->mipi_mmio_base + 0xb890)
+#define MIPI_INTR_STAT_REG_1(tc) _TRANSCODER(tc, \
+ _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1)
+#define _MIPIA_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb094)
+#define _MIPIB_INTR_EN_REG_1 (dev_priv->mipi_mmio_base + 0xb894)
+#define MIPI_INTR_EN_REG_1(tc) _TRANSCODER(tc, _MIPIA_INTR_EN_REG_1, \
+ _MIPIB_INTR_EN_REG_1)
#define RX_CONTENTION_DETECTED (1 << 0)
/* XXX: only pipe A ?!? */
-#define MIPIA_DBI_TYPEC_CTRL (VLV_DISPLAY_BASE + 0xb100)
+#define MIPIA_DBI_TYPEC_CTRL (dev_priv->mipi_mmio_base + 0xb100)
#define DBI_TYPEC_ENABLE (1 << 31)
#define DBI_TYPEC_WIP (1 << 30)
#define DBI_TYPEC_OPTION_SHIFT 28
@@ -6356,9 +6484,10 @@ enum punit_power_well {
/* MIPI adapter registers */
-#define _MIPIA_CTRL (VLV_DISPLAY_BASE + 0xb104)
-#define _MIPIB_CTRL (VLV_DISPLAY_BASE + 0xb904)
-#define MIPI_CTRL(pipe) _PIPE(pipe, _MIPIA_CTRL, _MIPIB_CTRL)
+#define _MIPIA_CTRL (dev_priv->mipi_mmio_base + 0xb104)
+#define _MIPIB_CTRL (dev_priv->mipi_mmio_base + 0xb904)
+#define MIPI_CTRL(tc) _TRANSCODER(tc, _MIPIA_CTRL, \
+ _MIPIB_CTRL)
#define ESCAPE_CLOCK_DIVIDER_SHIFT 5 /* A only */
#define ESCAPE_CLOCK_DIVIDER_MASK (3 << 5)
#define ESCAPE_CLOCK_DIVIDER_1 (0 << 5)
@@ -6370,50 +6499,52 @@ enum punit_power_well {
#define READ_REQUEST_PRIORITY_HIGH (3 << 3)
#define RGB_FLIP_TO_BGR (1 << 2)
-#define _MIPIA_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb108)
-#define _MIPIB_DATA_ADDRESS (VLV_DISPLAY_BASE + 0xb908)
-#define MIPI_DATA_ADDRESS(pipe) _PIPE(pipe, _MIPIA_DATA_ADDRESS, _MIPIB_DATA_ADDRESS)
+#define _MIPIA_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb108)
+#define _MIPIB_DATA_ADDRESS (dev_priv->mipi_mmio_base + 0xb908)
+#define MIPI_DATA_ADDRESS(tc) _TRANSCODER(tc, _MIPIA_DATA_ADDRESS, \
+ _MIPIB_DATA_ADDRESS)
#define DATA_MEM_ADDRESS_SHIFT 5
#define DATA_MEM_ADDRESS_MASK (0x7ffffff << 5)
#define DATA_VALID (1 << 0)
-#define _MIPIA_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb10c)
-#define _MIPIB_DATA_LENGTH (VLV_DISPLAY_BASE + 0xb90c)
-#define MIPI_DATA_LENGTH(pipe) _PIPE(pipe, _MIPIA_DATA_LENGTH, _MIPIB_DATA_LENGTH)
+#define _MIPIA_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb10c)
+#define _MIPIB_DATA_LENGTH (dev_priv->mipi_mmio_base + 0xb90c)
+#define MIPI_DATA_LENGTH(tc) _TRANSCODER(tc, _MIPIA_DATA_LENGTH, \
+ _MIPIB_DATA_LENGTH)
#define DATA_LENGTH_SHIFT 0
#define DATA_LENGTH_MASK (0xfffff << 0)
-#define _MIPIA_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb110)
-#define _MIPIB_COMMAND_ADDRESS (VLV_DISPLAY_BASE + 0xb910)
-#define MIPI_COMMAND_ADDRESS(pipe) _PIPE(pipe, _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS)
+#define _MIPIA_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb110)
+#define _MIPIB_COMMAND_ADDRESS (dev_priv->mipi_mmio_base + 0xb910)
+#define MIPI_COMMAND_ADDRESS(tc) _TRANSCODER(tc, \
+ _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS)
#define COMMAND_MEM_ADDRESS_SHIFT 5
#define COMMAND_MEM_ADDRESS_MASK (0x7ffffff << 5)
#define AUTO_PWG_ENABLE (1 << 2)
#define MEMORY_WRITE_DATA_FROM_PIPE_RENDERING (1 << 1)
#define COMMAND_VALID (1 << 0)
-#define _MIPIA_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb114)
-#define _MIPIB_COMMAND_LENGTH (VLV_DISPLAY_BASE + 0xb914)
-#define MIPI_COMMAND_LENGTH(pipe) _PIPE(pipe, _MIPIA_COMMAND_LENGTH, _MIPIB_COMMAND_LENGTH)
+#define _MIPIA_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb114)
+#define _MIPIB_COMMAND_LENGTH (dev_priv->mipi_mmio_base + 0xb914)
+#define MIPI_COMMAND_LENGTH(tc) _TRANSCODER(tc, _MIPIA_COMMAND_LENGTH, \
+ _MIPIB_COMMAND_LENGTH)
#define COMMAND_LENGTH_SHIFT(n) (8 * (n)) /* n: 0...3 */
#define COMMAND_LENGTH_MASK(n) (0xff << (8 * (n)))
-#define _MIPIA_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb118)
-#define _MIPIB_READ_DATA_RETURN0 (VLV_DISPLAY_BASE + 0xb918)
-#define MIPI_READ_DATA_RETURN(pipe, n) \
- (_PIPE(pipe, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
+#define _MIPIA_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb118)
+#define _MIPIB_READ_DATA_RETURN0 (dev_priv->mipi_mmio_base + 0xb918)
+#define MIPI_READ_DATA_RETURN(tc, n) \
+ (_TRANSCODER(tc, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) \
+ + 4 * (n)) /* n: 0...7 */
-#define _MIPIA_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb138)
-#define _MIPIB_READ_DATA_VALID (VLV_DISPLAY_BASE + 0xb938)
-#define MIPI_READ_DATA_VALID(pipe) _PIPE(pipe, _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID)
+#define _MIPIA_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb138)
+#define _MIPIB_READ_DATA_VALID (dev_priv->mipi_mmio_base + 0xb938)
+#define MIPI_READ_DATA_VALID(tc) _TRANSCODER(tc, \
+ _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID)
#define READ_DATA_VALID(n) (1 << (n))
/* For UMS only (deprecated): */
#define _PALETTE_A (dev_priv->info.display_mmio_offset + 0xa000)
#define _PALETTE_B (dev_priv->info.display_mmio_offset + 0xa800)
-#define _DPLL_A (dev_priv->info.display_mmio_offset + 0x6014)
-#define _DPLL_B (dev_priv->info.display_mmio_offset + 0x6018)
-#define _DPLL_A_MD (dev_priv->info.display_mmio_offset + 0x601c)
-#define _DPLL_B_MD (dev_priv->info.display_mmio_offset + 0x6020)
#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 86ce39aad0ff..ae7fd8fc27f0 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -47,22 +47,45 @@ static u32 calc_residency(struct drm_device *dev, const u32 reg)
intel_runtime_pm_get(dev_priv);
- /* On VLV, residency time is in CZ units rather than 1.28us */
+ /* On VLV and CHV, residency time is in CZ units rather than 1.28us */
if (IS_VALLEYVIEW(dev)) {
- u32 clkctl2;
+ u32 reg, czcount_30ns;
- clkctl2 = I915_READ(VLV_CLK_CTL2) >>
- CLK_CTL2_CZCOUNT_30NS_SHIFT;
- if (!clkctl2) {
- WARN(!clkctl2, "bogus CZ count value");
+ if (IS_CHERRYVIEW(dev))
+ reg = CHV_CLK_CTL1;
+ else
+ reg = VLV_CLK_CTL2;
+
+ czcount_30ns = I915_READ(reg) >> CLK_CTL2_CZCOUNT_30NS_SHIFT;
+
+ if (!czcount_30ns) {
+ WARN(!czcount_30ns, "bogus CZ count value");
ret = 0;
goto out;
}
- units = DIV_ROUND_UP_ULL(30ULL * bias, (u64)clkctl2);
+
+ units = 0;
+ div = 1000000ULL;
+
+ if (IS_CHERRYVIEW(dev)) {
+ /* Special case for 320Mhz */
+ if (czcount_30ns == 1) {
+ div = 10000000ULL;
+ units = 3125ULL;
+ } else {
+ /* chv counts are one less */
+ czcount_30ns += 1;
+ }
+ }
+
+ if (units == 0)
+ units = DIV_ROUND_UP_ULL(30ULL * bias,
+ (u64)czcount_30ns);
+
if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
units <<= 8;
- div = 1000000ULL * bias;
+ div = div * bias;
}
raw_time = I915_READ(reg) * units;
@@ -461,11 +484,20 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
mutex_unlock(&dev->struct_mutex);
if (attr == &dev_attr_gt_RP0_freq_mhz) {
- val = ((rp_state_cap & 0x0000ff) >> 0) * GT_FREQUENCY_MULTIPLIER;
+ if (IS_VALLEYVIEW(dev))
+ val = vlv_gpu_freq(dev_priv, dev_priv->rps.rp0_freq);
+ else
+ val = ((rp_state_cap & 0x0000ff) >> 0) * GT_FREQUENCY_MULTIPLIER;
} else if (attr == &dev_attr_gt_RP1_freq_mhz) {
- val = ((rp_state_cap & 0x00ff00) >> 8) * GT_FREQUENCY_MULTIPLIER;
+ if (IS_VALLEYVIEW(dev))
+ val = vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq);
+ else
+ val = ((rp_state_cap & 0x00ff00) >> 8) * GT_FREQUENCY_MULTIPLIER;
} else if (attr == &dev_attr_gt_RPn_freq_mhz) {
- val = ((rp_state_cap & 0xff0000) >> 16) * GT_FREQUENCY_MULTIPLIER;
+ if (IS_VALLEYVIEW(dev))
+ val = vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq);
+ else
+ val = ((rp_state_cap & 0xff0000) >> 16) * GT_FREQUENCY_MULTIPLIER;
} else {
BUG();
}
@@ -486,6 +518,9 @@ static const struct attribute *vlv_attrs[] = {
&dev_attr_gt_cur_freq_mhz.attr,
&dev_attr_gt_max_freq_mhz.attr,
&dev_attr_gt_min_freq_mhz.attr,
+ &dev_attr_gt_RP0_freq_mhz.attr,
+ &dev_attr_gt_RP1_freq_mhz.attr,
+ &dev_attr_gt_RPn_freq_mhz.attr,
&dev_attr_vlv_rpe_freq_mhz.attr,
NULL,
};
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 827498e081df..a66955037e4e 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -336,11 +336,12 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
+ dev_priv->vbt.backlight.min_brightness = entry->min_brightness;
DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
"active %s, min brightness %u, level %u\n",
dev_priv->vbt.backlight.pwm_freq_hz,
dev_priv->vbt.backlight.active_low_pwm ? "low" : "high",
- entry->min_brightness,
+ dev_priv->vbt.backlight.min_brightness,
backlight_data->level[panel_type]);
}
@@ -877,7 +878,7 @@ err:
/* error during parsing so set all pointers to null
* because of partial parsing */
- memset(dev_priv->vbt.dsi.sequence, 0, MIPI_SEQ_MAX);
+ memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence));
}
static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 5a045d3bd77e..2efaf8e8d9c4 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -137,6 +137,18 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);
}
+static void hsw_crt_pre_enable(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL already enabled\n");
+ I915_WRITE(SPLL_CTL,
+ SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC);
+ POSTING_READ(SPLL_CTL);
+ udelay(20);
+}
+
/* Note: The caller is required to filter out dpms modes not supported by the
* platform. */
static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
@@ -194,6 +206,20 @@ static void intel_disable_crt(struct intel_encoder *encoder)
intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
}
+
+static void hsw_crt_post_disable(struct intel_encoder *encoder)
+{
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t val;
+
+ DRM_DEBUG_KMS("Disabling SPLL\n");
+ val = I915_READ(SPLL_CTL);
+ WARN_ON(!(val & SPLL_PLL_ENABLE));
+ I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
+ POSTING_READ(SPLL_CTL);
+}
+
static void intel_enable_crt(struct intel_encoder *encoder)
{
struct intel_crt *crt = intel_encoder_to_crt(encoder);
@@ -289,8 +315,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
pipe_config->pipe_bpp = 24;
/* FDI must always be 2.7 GHz */
- if (HAS_DDI(dev))
+ if (HAS_DDI(dev)) {
+ pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL;
pipe_config->port_clock = 135000 * 2;
+ }
return true;
}
@@ -632,8 +660,6 @@ intel_crt_detect(struct drm_connector *connector, bool force)
struct intel_load_detect_pipe tmp;
struct drm_modeset_acquire_ctx ctx;
- intel_runtime_pm_get(dev_priv);
-
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
connector->base.id, connector->name,
force);
@@ -685,8 +711,6 @@ intel_crt_detect(struct drm_connector *connector, bool force)
out:
intel_display_power_put(dev_priv, power_domain);
- intel_runtime_pm_put(dev_priv);
-
return status;
}
@@ -860,6 +884,8 @@ void intel_crt_init(struct drm_device *dev)
if (HAS_DDI(dev)) {
crt->base.get_config = hsw_crt_get_config;
crt->base.get_hw_state = intel_ddi_get_hw_state;
+ crt->base.pre_enable = hsw_crt_pre_enable;
+ crt->base.post_disable = hsw_crt_post_disable;
} else {
crt->base.get_config = intel_crt_get_config;
crt->base.get_hw_state = intel_crt_get_hw_state;
@@ -869,7 +895,7 @@ void intel_crt_init(struct drm_device *dev)
drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
if (!I915_HAS_HOTPLUG(dev))
intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index b17b9c7c769f..5db0b5552e39 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -76,12 +76,12 @@ static const u32 bdw_ddi_translations_edp[] = {
0x00FFFFFF, 0x00000012, /* eDP parameters */
0x00EBAFFF, 0x00020011,
0x00C71FFF, 0x0006000F,
+ 0x00AAAFFF, 0x000E000A,
0x00FFFFFF, 0x00020011,
0x00DB6FFF, 0x0005000F,
0x00BEEFFF, 0x000A000C,
0x00FFFFFF, 0x0005000F,
0x00DB6FFF, 0x000A000C,
- 0x00FFFFFF, 0x000A000C,
0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
};
@@ -89,12 +89,12 @@ static const u32 bdw_ddi_translations_dp[] = {
0x00FFFFFF, 0x0007000E, /* DP parameters */
0x00D75FFF, 0x000E000A,
0x00BEFFFF, 0x00140006,
+ 0x80B2CFFF, 0x001B0002,
0x00FFFFFF, 0x000E000A,
0x00D75FFF, 0x00180004,
0x80CB2FFF, 0x001B0002,
0x00F7DFFF, 0x00180004,
0x80D75FFF, 0x001B0002,
- 0x80FFFFFF, 0x001B0002,
0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
};
@@ -116,7 +116,10 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
struct drm_encoder *encoder = &intel_encoder->base;
int type = intel_encoder->type;
- if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
+ if (type == INTEL_OUTPUT_DP_MST) {
+ struct intel_digital_port *intel_dig_port = enc_to_mst(encoder)->primary;
+ return intel_dig_port->port;
+ } else if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP ||
type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_UNKNOWN) {
struct intel_digital_port *intel_dig_port =
enc_to_dig_port(encoder);
@@ -277,7 +280,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
/* Configure Port Clock Select */
- I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->ddi_pll_sel);
+ I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config.ddi_pll_sel);
+ WARN_ON(intel_crtc->config.ddi_pll_sel != PORT_CLK_SEL_SPLL);
/* Start the training iterating through available voltages and emphasis,
* testing each value twice. */
@@ -364,6 +368,18 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
DRM_ERROR("FDI link training failed!\n");
}
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+ struct intel_digital_port *intel_dig_port =
+ enc_to_dig_port(&encoder->base);
+
+ intel_dp->DP = intel_dig_port->saved_port_bits |
+ DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
+ intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+
+}
+
static struct intel_encoder *
intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
{
@@ -385,53 +401,6 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
return ret;
}
-void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
-{
- struct drm_i915_private *dev_priv = crtc->dev->dev_private;
- struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- uint32_t val;
-
- switch (intel_crtc->ddi_pll_sel) {
- case PORT_CLK_SEL_SPLL:
- plls->spll_refcount--;
- if (plls->spll_refcount == 0) {
- DRM_DEBUG_KMS("Disabling SPLL\n");
- val = I915_READ(SPLL_CTL);
- WARN_ON(!(val & SPLL_PLL_ENABLE));
- I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
- POSTING_READ(SPLL_CTL);
- }
- break;
- case PORT_CLK_SEL_WRPLL1:
- plls->wrpll1_refcount--;
- if (plls->wrpll1_refcount == 0) {
- DRM_DEBUG_KMS("Disabling WRPLL 1\n");
- val = I915_READ(WRPLL_CTL1);
- WARN_ON(!(val & WRPLL_PLL_ENABLE));
- I915_WRITE(WRPLL_CTL1, val & ~WRPLL_PLL_ENABLE);
- POSTING_READ(WRPLL_CTL1);
- }
- break;
- case PORT_CLK_SEL_WRPLL2:
- plls->wrpll2_refcount--;
- if (plls->wrpll2_refcount == 0) {
- DRM_DEBUG_KMS("Disabling WRPLL 2\n");
- val = I915_READ(WRPLL_CTL2);
- WARN_ON(!(val & WRPLL_PLL_ENABLE));
- I915_WRITE(WRPLL_CTL2, val & ~WRPLL_PLL_ENABLE);
- POSTING_READ(WRPLL_CTL2);
- }
- break;
- }
-
- WARN(plls->spll_refcount < 0, "Invalid SPLL refcount\n");
- WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n");
- WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
-
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
-}
-
#define LC_FREQ 2700
#define LC_FREQ_2K (LC_FREQ * 2000)
@@ -592,9 +561,9 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
u32 wrpll;
wrpll = I915_READ(reg);
- switch (wrpll & SPLL_PLL_REF_MASK) {
- case SPLL_PLL_SSC:
- case SPLL_PLL_NON_SSC:
+ switch (wrpll & WRPLL_PLL_REF_MASK) {
+ case WRPLL_PLL_SSC:
+ case WRPLL_PLL_NON_SSC:
/*
* We could calculate spread here, but our checking
* code only cares about 5% accuracy, and spread is a max of
@@ -602,7 +571,7 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
*/
refclk = 135;
break;
- case SPLL_PLL_LCPLL:
+ case WRPLL_PLL_LCPLL:
refclk = LC_FREQ;
break;
default:
@@ -618,15 +587,14 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
return (refclk * n * 100) / (p * r);
}
-static void intel_ddi_clock_get(struct intel_encoder *encoder,
- struct intel_crtc_config *pipe_config)
+void intel_ddi_clock_get(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config)
{
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
- enum port port = intel_ddi_get_encoder_port(encoder);
int link_clock = 0;
u32 val, pll;
- val = I915_READ(PORT_CLK_SEL(port));
+ val = pipe_config->ddi_pll_sel;
switch (val & PORT_CLK_SEL_MASK) {
case PORT_CLK_SEL_LCPLL_810:
link_clock = 81000;
@@ -750,173 +718,37 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
{
struct drm_crtc *crtc = &intel_crtc->base;
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
- struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_i915_private *dev_priv = crtc->dev->dev_private;
- struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
int type = intel_encoder->type;
- enum pipe pipe = intel_crtc->pipe;
int clock = intel_crtc->config.port_clock;
- intel_ddi_put_crtc_pll(crtc);
-
- if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ intel_put_shared_dpll(intel_crtc);
- switch (intel_dp->link_bw) {
- case DP_LINK_BW_1_62:
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
- break;
- case DP_LINK_BW_2_7:
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
- break;
- case DP_LINK_BW_5_4:
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
- break;
- default:
- DRM_ERROR("Link bandwidth %d unsupported\n",
- intel_dp->link_bw);
- return false;
- }
-
- } else if (type == INTEL_OUTPUT_HDMI) {
- uint32_t reg, val;
+ if (type == INTEL_OUTPUT_HDMI) {
+ struct intel_shared_dpll *pll;
+ uint32_t val;
unsigned p, n2, r2;
intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
- val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
+ val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
WRPLL_DIVIDER_POST(p);
- if (val == I915_READ(WRPLL_CTL1)) {
- DRM_DEBUG_KMS("Reusing WRPLL 1 on pipe %c\n",
- pipe_name(pipe));
- reg = WRPLL_CTL1;
- } else if (val == I915_READ(WRPLL_CTL2)) {
- DRM_DEBUG_KMS("Reusing WRPLL 2 on pipe %c\n",
- pipe_name(pipe));
- reg = WRPLL_CTL2;
- } else if (plls->wrpll1_refcount == 0) {
- DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
- pipe_name(pipe));
- reg = WRPLL_CTL1;
- } else if (plls->wrpll2_refcount == 0) {
- DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
- pipe_name(pipe));
- reg = WRPLL_CTL2;
- } else {
- DRM_ERROR("No WRPLLs available!\n");
- return false;
- }
-
- DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
- clock, p, n2, r2);
-
- if (reg == WRPLL_CTL1) {
- plls->wrpll1_refcount++;
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
- } else {
- plls->wrpll2_refcount++;
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
- }
+ intel_crtc->config.dpll_hw_state.wrpll = val;
- } else if (type == INTEL_OUTPUT_ANALOG) {
- if (plls->spll_refcount == 0) {
- DRM_DEBUG_KMS("Using SPLL on pipe %c\n",
- pipe_name(pipe));
- plls->spll_refcount++;
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL;
- } else {
- DRM_ERROR("SPLL already in use\n");
+ pll = intel_get_shared_dpll(intel_crtc);
+ if (pll == NULL) {
+ DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+ pipe_name(intel_crtc->pipe));
return false;
}
- } else {
- WARN(1, "Invalid DDI encoder type %d\n", type);
- return false;
+ intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
}
return true;
}
-/*
- * To be called after intel_ddi_pll_select(). That one selects the PLL to be
- * used, this one actually enables the PLL.
- */
-void intel_ddi_pll_enable(struct intel_crtc *crtc)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
- int clock = crtc->config.port_clock;
- uint32_t reg, cur_val, new_val;
- int refcount;
- const char *pll_name;
- uint32_t enable_bit = (1 << 31);
- unsigned int p, n2, r2;
-
- BUILD_BUG_ON(enable_bit != SPLL_PLL_ENABLE);
- BUILD_BUG_ON(enable_bit != WRPLL_PLL_ENABLE);
-
- switch (crtc->ddi_pll_sel) {
- case PORT_CLK_SEL_LCPLL_2700:
- case PORT_CLK_SEL_LCPLL_1350:
- case PORT_CLK_SEL_LCPLL_810:
- /*
- * LCPLL should always be enabled at this point of the mode set
- * sequence, so nothing to do.
- */
- return;
-
- case PORT_CLK_SEL_SPLL:
- pll_name = "SPLL";
- reg = SPLL_CTL;
- refcount = plls->spll_refcount;
- new_val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz |
- SPLL_PLL_SSC;
- break;
-
- case PORT_CLK_SEL_WRPLL1:
- case PORT_CLK_SEL_WRPLL2:
- if (crtc->ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
- pll_name = "WRPLL1";
- reg = WRPLL_CTL1;
- refcount = plls->wrpll1_refcount;
- } else {
- pll_name = "WRPLL2";
- reg = WRPLL_CTL2;
- refcount = plls->wrpll2_refcount;
- }
-
- intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-
- new_val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
- WRPLL_DIVIDER_REFERENCE(r2) |
- WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p);
-
- break;
-
- case PORT_CLK_SEL_NONE:
- WARN(1, "Bad selected pll: PORT_CLK_SEL_NONE\n");
- return;
- default:
- WARN(1, "Bad selected pll: 0x%08x\n", crtc->ddi_pll_sel);
- return;
- }
-
- cur_val = I915_READ(reg);
-
- WARN(refcount < 1, "Bad %s refcount: %d\n", pll_name, refcount);
- if (refcount == 1) {
- WARN(cur_val & enable_bit, "%s already enabled\n", pll_name);
- I915_WRITE(reg, new_val);
- POSTING_READ(reg);
- udelay(20);
- } else {
- WARN((cur_val & enable_bit) == 0, "%s disabled\n", pll_name);
- }
-}
-
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -926,8 +758,7 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
int type = intel_encoder->type;
uint32_t temp;
- if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
-
+ if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
temp = TRANS_MSA_SYNC_CLK;
switch (intel_crtc->config.pipe_bpp) {
case 18:
@@ -949,6 +780,21 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
}
}
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+ uint32_t temp;
+ temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ if (state == true)
+ temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+ else
+ temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
+ I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
+}
+
void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -995,7 +841,9 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
* eDP when not using the panel fitter, and when not
* using motion blur mitigation (which we don't
* support). */
- if (IS_HASWELL(dev) && intel_crtc->config.pch_pfit.enabled)
+ if (IS_HASWELL(dev) &&
+ (intel_crtc->config.pch_pfit.enabled ||
+ intel_crtc->config.pch_pfit.force_thru))
temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
else
temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1026,7 +874,19 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- temp |= TRANS_DDI_MODE_SELECT_DP_SST;
+ if (intel_dp->is_mst) {
+ temp |= TRANS_DDI_MODE_SELECT_DP_MST;
+ } else
+ temp |= TRANS_DDI_MODE_SELECT_DP_SST;
+
+ temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
+ } else if (type == INTEL_OUTPUT_DP_MST) {
+ struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
+
+ if (intel_dp->is_mst) {
+ temp |= TRANS_DDI_MODE_SELECT_DP_MST;
+ } else
+ temp |= TRANS_DDI_MODE_SELECT_DP_SST;
temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
} else {
@@ -1043,7 +903,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
uint32_t val = I915_READ(reg);
- val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK);
+ val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
val |= TRANS_DDI_PORT_NONE;
I915_WRITE(reg, val);
}
@@ -1082,8 +942,11 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
case TRANS_DDI_MODE_SELECT_DP_SST:
if (type == DRM_MODE_CONNECTOR_eDP)
return true;
- case TRANS_DDI_MODE_SELECT_DP_MST:
return (type == DRM_MODE_CONNECTOR_DisplayPort);
+ case TRANS_DDI_MODE_SELECT_DP_MST:
+ /* if the transcoder is in MST state then
+ * connector isn't connected */
+ return false;
case TRANS_DDI_MODE_SELECT_FDI:
return (type == DRM_MODE_CONNECTOR_VGA);
@@ -1135,6 +998,9 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
if ((tmp & TRANS_DDI_PORT_MASK)
== TRANS_DDI_SELECT_PORT(port)) {
+ if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
+ return false;
+
*pipe = i;
return true;
}
@@ -1146,76 +1012,6 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
return false;
}
-static uint32_t intel_ddi_get_crtc_pll(struct drm_i915_private *dev_priv,
- enum pipe pipe)
-{
- uint32_t temp, ret;
- enum port port = I915_MAX_PORTS;
- enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
- pipe);
- int i;
-
- if (cpu_transcoder == TRANSCODER_EDP) {
- port = PORT_A;
- } else {
- temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
- temp &= TRANS_DDI_PORT_MASK;
-
- for (i = PORT_B; i <= PORT_E; i++)
- if (temp == TRANS_DDI_SELECT_PORT(i))
- port = i;
- }
-
- if (port == I915_MAX_PORTS) {
- WARN(1, "Pipe %c enabled on an unknown port\n",
- pipe_name(pipe));
- ret = PORT_CLK_SEL_NONE;
- } else {
- ret = I915_READ(PORT_CLK_SEL(port));
- DRM_DEBUG_KMS("Pipe %c connected to port %c using clock "
- "0x%08x\n", pipe_name(pipe), port_name(port),
- ret);
- }
-
- return ret;
-}
-
-void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- enum pipe pipe;
- struct intel_crtc *intel_crtc;
-
- dev_priv->ddi_plls.spll_refcount = 0;
- dev_priv->ddi_plls.wrpll1_refcount = 0;
- dev_priv->ddi_plls.wrpll2_refcount = 0;
-
- for_each_pipe(pipe) {
- intel_crtc =
- to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-
- if (!intel_crtc->active) {
- intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
- continue;
- }
-
- intel_crtc->ddi_pll_sel = intel_ddi_get_crtc_pll(dev_priv,
- pipe);
-
- switch (intel_crtc->ddi_pll_sel) {
- case PORT_CLK_SEL_SPLL:
- dev_priv->ddi_plls.spll_refcount++;
- break;
- case PORT_CLK_SEL_WRPLL1:
- dev_priv->ddi_plls.wrpll1_refcount++;
- break;
- case PORT_CLK_SEL_WRPLL2:
- dev_priv->ddi_plls.wrpll2_refcount++;
- break;
- }
- }
-}
-
void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
{
struct drm_crtc *crtc = &intel_crtc->base;
@@ -1261,17 +1057,13 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
intel_edp_panel_on(intel_dp);
}
- WARN_ON(crtc->ddi_pll_sel == PORT_CLK_SEL_NONE);
- I915_WRITE(PORT_CLK_SEL(port), crtc->ddi_pll_sel);
+ WARN_ON(crtc->config.ddi_pll_sel == PORT_CLK_SEL_NONE);
+ I915_WRITE(PORT_CLK_SEL(port), crtc->config.ddi_pll_sel);
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
- struct intel_digital_port *intel_dig_port =
- enc_to_dig_port(encoder);
- intel_dp->DP = intel_dig_port->saved_port_bits |
- DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
- intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+ intel_ddi_init_dp_buf_reg(intel_encoder);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_start_link_train(intel_dp);
@@ -1418,10 +1210,60 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
}
}
+static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll)
+{
+ I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll);
+ POSTING_READ(WRPLL_CTL(pll->id));
+ udelay(20);
+}
+
+static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll)
+{
+ uint32_t val;
+
+ val = I915_READ(WRPLL_CTL(pll->id));
+ I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
+ POSTING_READ(WRPLL_CTL(pll->id));
+}
+
+static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+ struct intel_shared_dpll *pll,
+ struct intel_dpll_hw_state *hw_state)
+{
+ uint32_t val;
+
+ if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
+ return false;
+
+ val = I915_READ(WRPLL_CTL(pll->id));
+ hw_state->wrpll = val;
+
+ return val & WRPLL_PLL_ENABLE;
+}
+
+static const char * const hsw_ddi_pll_names[] = {
+ "WRPLL 1",
+ "WRPLL 2",
+};
+
void intel_ddi_pll_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t val = I915_READ(LCPLL_CTL);
+ int i;
+
+ dev_priv->num_shared_dpll = 2;
+
+ for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+ dev_priv->shared_dplls[i].id = i;
+ dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
+ dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
+ dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
+ dev_priv->shared_dplls[i].get_hw_state =
+ hsw_ddi_pll_get_hw_state;
+ }
/* The LCPLL register should be turned on by the BIOS. For now let's
* just check its state and print errors in case something is wrong.
@@ -1465,10 +1307,15 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
intel_wait_ddi_buf_idle(dev_priv, port);
}
- val = DP_TP_CTL_ENABLE | DP_TP_CTL_MODE_SST |
+ val = DP_TP_CTL_ENABLE |
DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
- val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
+ if (intel_dp->is_mst)
+ val |= DP_TP_CTL_MODE_MST;
+ else {
+ val |= DP_TP_CTL_MODE_SST;
+ if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+ val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
+ }
I915_WRITE(DP_TP_CTL(port), val);
POSTING_READ(DP_TP_CTL(port));
@@ -1507,11 +1354,16 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc)
static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
- int type = intel_encoder->type;
+ struct intel_digital_port *intel_dig_port = enc_to_dig_port(&intel_encoder->base);
+ int type = intel_dig_port->base.type;
+
+ if (type != INTEL_OUTPUT_DISPLAYPORT &&
+ type != INTEL_OUTPUT_EDP &&
+ type != INTEL_OUTPUT_UNKNOWN) {
+ return;
+ }
- if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP)
- intel_dp_check_link_status(intel_dp);
+ intel_dp_hot_plug(intel_encoder);
}
void intel_ddi_get_config(struct intel_encoder *encoder,
@@ -1663,15 +1515,13 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
- struct intel_connector *hdmi_connector = NULL;
- struct intel_connector *dp_connector = NULL;
bool init_hdmi, init_dp;
init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
dev_priv->vbt.ddi_port_info[port].supports_hdmi);
init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
if (!init_dp && !init_hdmi) {
- DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible\n",
+ DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
port_name(port));
init_hdmi = true;
init_dp = true;
@@ -1701,20 +1551,28 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
DDI_A_4_LANES);
intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
- intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
+ intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
intel_encoder->cloneable = 0;
intel_encoder->hot_plug = intel_ddi_hot_plug;
- if (init_dp)
- dp_connector = intel_ddi_init_dp_connector(intel_dig_port);
+ if (init_dp) {
+ if (!intel_ddi_init_dp_connector(intel_dig_port))
+ goto err;
+
+ intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+ dev_priv->hpd_irq_port[port] = intel_dig_port;
+ }
/* In theory we don't need the encoder->type check, but leave it just in
* case we have some really bad VBTs... */
- if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi)
- hdmi_connector = intel_ddi_init_hdmi_connector(intel_dig_port);
-
- if (!dp_connector && !hdmi_connector) {
- drm_encoder_cleanup(encoder);
- kfree(intel_dig_port);
+ if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
+ if (!intel_ddi_init_hdmi_connector(intel_dig_port))
+ goto err;
}
+
+ return;
+
+err:
+ drm_encoder_cleanup(encoder);
+ kfree(intel_dig_port);
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5f285fba4e41..018fb7222f60 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -39,12 +39,45 @@
#include "i915_trace.h"
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_rect.h>
#include <linux/dma_remapping.h>
+/* Primary plane formats supported by all gen */
+#define COMMON_PRIMARY_FORMATS \
+ DRM_FORMAT_C8, \
+ DRM_FORMAT_RGB565, \
+ DRM_FORMAT_XRGB8888, \
+ DRM_FORMAT_ARGB8888
+
+/* Primary plane formats for gen <= 3 */
+static const uint32_t intel_primary_formats_gen2[] = {
+ COMMON_PRIMARY_FORMATS,
+ DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB1555,
+};
+
+/* Primary plane formats for gen >= 4 */
+static const uint32_t intel_primary_formats_gen4[] = {
+ COMMON_PRIMARY_FORMATS, \
+ DRM_FORMAT_XBGR8888,
+ DRM_FORMAT_ABGR8888,
+ DRM_FORMAT_XRGB2101010,
+ DRM_FORMAT_ARGB2101010,
+ DRM_FORMAT_XBGR2101010,
+ DRM_FORMAT_ABGR2101010,
+};
+
+/* Cursor formats */
+static const uint32_t intel_cursor_formats[] = {
+ DRM_FORMAT_ARGB8888,
+};
+
#define DIV_ROUND_CLOSEST_ULL(ll, d) \
- ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
+({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
-static void intel_increase_pllclock(struct drm_crtc *crtc);
+static void intel_increase_pllclock(struct drm_device *dev,
+ enum pipe pipe);
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
@@ -68,6 +101,14 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc);
static void intel_set_pipe_csc(struct drm_crtc *crtc);
static void vlv_prepare_pll(struct intel_crtc *crtc);
+static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
+{
+ if (!connector->mst_port)
+ return connector->encoder;
+ else
+ return &connector->mst_port->mst_encoders[pipe]->base;
+}
+
typedef struct {
int min, max;
} intel_range_t;
@@ -1061,11 +1102,6 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
bool cur_state;
struct intel_dpll_hw_state hw_state;
- if (HAS_PCH_LPT(dev_priv->dev)) {
- DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n");
- return;
- }
-
if (WARN (!pll,
"asserting DPLL %s with no DPLL\n", state_string(state)))
return;
@@ -1481,9 +1517,6 @@ static void intel_reset_dpio(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!IS_VALLEYVIEW(dev))
- return;
-
if (IS_CHERRYVIEW(dev)) {
enum dpio_phy phy;
u32 val;
@@ -1505,26 +1538,6 @@ static void intel_reset_dpio(struct drm_device *dev)
I915_WRITE(DISPLAY_PHY_CONTROL,
PHY_COM_LANE_RESET_DEASSERT(phy, val));
}
-
- } else {
- /*
- * If DPIO has already been reset, e.g. by BIOS, just skip all
- * this.
- */
- if (I915_READ(DPIO_CTL) & DPIO_CMNRST)
- return;
-
- /*
- * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
- * Need to assert and de-assert PHY SB reset by gating the
- * common lane power, then un-gating it.
- * Simply ungating isn't enough to reset the PHY enough to get
- * ports and lanes running.
- */
- __vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
- false);
- __vlv_set_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC,
- true);
}
}
@@ -1712,6 +1725,17 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
val &= ~DPIO_DCLKP_EN;
vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
+ /* disable left/right clock distribution */
+ if (pipe != PIPE_B) {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+ val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+ } else {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+ val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+ }
+
mutex_unlock(&dev_priv->dpio_lock);
}
@@ -1749,6 +1773,9 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+ if (WARN_ON(pll == NULL))
+ return;
+
WARN_ON(!pll->refcount);
if (pll->active == 0) {
DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
@@ -1790,12 +1817,14 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
}
WARN_ON(pll->on);
+ intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+
DRM_DEBUG_KMS("enabling %s\n", pll->name);
pll->enable(dev_priv, pll);
pll->on = true;
}
-static void intel_disable_shared_dpll(struct intel_crtc *crtc)
+void intel_disable_shared_dpll(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1826,6 +1855,8 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc)
DRM_DEBUG_KMS("disabling %s\n", pll->name);
pll->disable(dev_priv, pll);
pll->on = false;
+
+ intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
}
static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
@@ -2087,6 +2118,7 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv,
enum plane plane, enum pipe pipe)
{
+ struct drm_device *dev = dev_priv->dev;
struct intel_crtc *intel_crtc =
to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
int reg;
@@ -2106,6 +2138,14 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv,
I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
intel_flush_primary_plane(dev_priv, plane);
+
+ /*
+ * BDW signals flip done immediately if the plane
+ * is disabled, even if the plane enable is already
+ * armed to occur at the next vblank :(
+ */
+ if (IS_BROADWELL(dev))
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
}
/**
@@ -2163,6 +2203,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
u32 alignment;
int ret;
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
switch (obj->tiling_mode) {
case I915_TILING_NONE:
if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
@@ -2219,6 +2261,8 @@ err_interruptible:
void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
{
+ WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
+
i915_gem_object_unpin_fence(obj);
i915_gem_object_unpin_from_display_plane(obj);
}
@@ -2305,6 +2349,7 @@ static bool intel_alloc_plane_obj(struct intel_crtc *crtc,
goto out_unref_obj;
}
+ obj->frontbuffer_bits = INTEL_FRONTBUFFER_PRIMARY(crtc->pipe);
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG_KMS("plane fb obj %p\n", obj);
@@ -2322,7 +2367,7 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
struct drm_device *dev = intel_crtc->base.dev;
struct drm_crtc *c;
struct intel_crtc *i;
- struct intel_framebuffer *fb;
+ struct drm_i915_gem_object *obj;
if (!intel_crtc->base.primary->fb)
return;
@@ -2343,13 +2388,17 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
if (c == &intel_crtc->base)
continue;
- if (!i->active || !c->primary->fb)
+ if (!i->active)
continue;
- fb = to_intel_framebuffer(c->primary->fb);
- if (i915_gem_obj_ggtt_offset(fb->obj) == plane_config->base) {
+ obj = intel_fb_obj(c->primary->fb);
+ if (obj == NULL)
+ continue;
+
+ if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) {
drm_framebuffer_reference(c->primary->fb);
intel_crtc->base.primary->fb = c->primary->fb;
+ obj->frontbuffer_bits |= INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
break;
}
}
@@ -2362,16 +2411,12 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_framebuffer *intel_fb;
- struct drm_i915_gem_object *obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int plane = intel_crtc->plane;
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
- intel_fb = to_intel_framebuffer(fb);
- obj = intel_fb->obj;
-
reg = DSPCNTR(plane);
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
@@ -2452,16 +2497,12 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_framebuffer *intel_fb;
- struct drm_i915_gem_object *obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
int plane = intel_crtc->plane;
unsigned long linear_offset;
u32 dspcntr;
u32 reg;
- intel_fb = to_intel_framebuffer(fb);
- obj = intel_fb->obj;
-
reg = DSPCNTR(plane);
dspcntr = I915_READ(reg);
/* Mask out pixel format bits in case we change it */
@@ -2537,7 +2578,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
if (dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
- intel_increase_pllclock(crtc);
+ intel_increase_pllclock(dev, to_intel_crtc(crtc)->pipe);
dev_priv->display.update_primary_plane(crtc, fb, x, y);
@@ -2592,7 +2633,7 @@ void intel_display_handle_reset(struct drm_device *dev)
static int
intel_finish_fb(struct drm_framebuffer *old_fb)
{
- struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(old_fb);
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
bool was_interruptible = dev_priv->mm.interruptible;
int ret;
@@ -2638,7 +2679,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_framebuffer *old_fb;
+ enum pipe pipe = intel_crtc->pipe;
+ struct drm_framebuffer *old_fb = crtc->primary->fb;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
int ret;
if (intel_crtc_has_pending_flip(crtc)) {
@@ -2660,9 +2704,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
}
mutex_lock(&dev->struct_mutex);
- ret = intel_pin_and_fence_fb_obj(dev,
- to_intel_framebuffer(fb)->obj,
- NULL);
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret == 0)
+ i915_gem_track_fb(old_obj, obj,
+ INTEL_FRONTBUFFER_PRIMARY(pipe));
mutex_unlock(&dev->struct_mutex);
if (ret != 0) {
DRM_ERROR("pin & fence failed\n");
@@ -2702,7 +2747,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
dev_priv->display.update_primary_plane(crtc, fb, x, y);
- old_fb = crtc->primary->fb;
+ if (intel_crtc->active)
+ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
+
crtc->primary->fb = fb;
crtc->x = x;
crtc->y = y;
@@ -2711,13 +2758,12 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
if (intel_crtc->active && old_fb != fb)
intel_wait_for_vblank(dev, intel_crtc->pipe);
mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
+ intel_unpin_fb_obj(old_obj);
mutex_unlock(&dev->struct_mutex);
}
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
- intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
return 0;
@@ -3578,7 +3624,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
}
-static void intel_put_shared_dpll(struct intel_crtc *crtc)
+void intel_put_shared_dpll(struct intel_crtc *crtc)
{
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
@@ -3598,7 +3644,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc)
crtc->config.shared_dpll = DPLL_ID_PRIVATE;
}
-static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
@@ -3809,7 +3855,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
}
/* use legacy palette for Ironlake */
- if (HAS_PCH_SPLIT(dev))
+ if (!HAS_GMCH_DISPLAY(dev))
palreg = LGC_PALETTE(pipe);
/* Workaround : Do not read or write the pipe palette/gamma data while
@@ -3851,30 +3897,6 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
*/
}
-/**
- * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
- * cursor plane briefly if not already running after enabling the display
- * plane.
- * This workaround avoids occasional blank screens when self refresh is
- * enabled.
- */
-static void
-g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
-{
- u32 cntl = I915_READ(CURCNTR(pipe));
-
- if ((cntl & CURSOR_MODE) == 0) {
- u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
-
- I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
- I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
- intel_wait_for_vblank(dev_priv->dev, pipe);
- I915_WRITE(CURCNTR(pipe), cntl);
- I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
- I915_WRITE(FW_BLC_SELF, fw_bcl_self);
- }
-}
-
static void intel_crtc_enable_planes(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -3883,11 +3905,10 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
+ drm_vblank_on(dev, pipe);
+
intel_enable_primary_hw_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
- /* The fixup needs to happen before cursor is enabled */
- if (IS_G4X(dev))
- g4x_fixup_plane(dev_priv, pipe);
intel_crtc_update_cursor(crtc, true);
intel_crtc_dpms_overlay(intel_crtc, true);
@@ -3895,8 +3916,14 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
- intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
+
+ /*
+ * FIXME: Once we grow proper nuclear flip support out of this we need
+ * to compute the mask of flip planes precisely. For the time being
+ * consider this a flip from a NULL plane.
+ */
+ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
}
static void intel_crtc_disable_planes(struct drm_crtc *crtc)
@@ -3908,7 +3935,6 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
int plane = intel_crtc->plane;
intel_crtc_wait_for_pending_flips(crtc);
- drm_crtc_vblank_off(crtc);
if (dev_priv->fbc.plane == plane)
intel_disable_fbc(dev);
@@ -3919,6 +3945,15 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc);
intel_disable_primary_hw_plane(dev_priv, plane, pipe);
+
+ /*
+ * FIXME: Once we grow proper nuclear flip support out of this we need
+ * to compute the mask of flip planes precisely. For the time being
+ * consider this a flip to a NULL plane.
+ */
+ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
+
+ drm_vblank_off(dev, pipe);
}
static void ironlake_crtc_enable(struct drm_crtc *crtc)
@@ -3997,8 +4032,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
cpt_verify_modeset(dev, intel_crtc->pipe);
intel_crtc_enable_planes(crtc);
-
- drm_crtc_vblank_on(crtc);
}
/* IPS only exists on ULT machines and is tied to pipe A. */
@@ -4050,6 +4083,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc->active)
return;
+ if (intel_crtc_to_shared_dpll(intel_crtc))
+ intel_enable_shared_dpll(intel_crtc);
+
if (intel_crtc->config.has_dp_encoder)
intel_dp_set_m_n(intel_crtc);
@@ -4074,16 +4110,15 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_crtc->active = true;
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
- if (intel_crtc->config.has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
-
- if (intel_crtc->config.has_pch_encoder)
- dev_priv->display.fdi_link_train(crtc);
-
for_each_encoder_on_crtc(dev, crtc, encoder)
if (encoder->pre_enable)
encoder->pre_enable(encoder);
+ if (intel_crtc->config.has_pch_encoder) {
+ intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
+ dev_priv->display.fdi_link_train(crtc);
+ }
+
intel_ddi_enable_pipe_clock(intel_crtc);
ironlake_pfit_enable(intel_crtc);
@@ -4103,6 +4138,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
if (intel_crtc->config.has_pch_encoder)
lpt_pch_enable(crtc);
+ if (intel_crtc->config.dp_encoder_is_mst)
+ intel_ddi_set_vc_payload_alloc(crtc, true);
+
for_each_encoder_on_crtc(dev, crtc, encoder) {
encoder->enable(encoder);
intel_opregion_notify_encoder(encoder, true);
@@ -4112,8 +4150,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
* to change the workaround. */
haswell_mode_set_planes_workaround(intel_crtc);
intel_crtc_enable_planes(crtc);
-
- drm_crtc_vblank_on(crtc);
}
static void ironlake_pfit_disable(struct intel_crtc *crtc)
@@ -4153,6 +4189,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_disable_pipe(dev_priv, pipe);
+ if (intel_crtc->config.dp_encoder_is_mst)
+ intel_ddi_set_vc_payload_alloc(crtc, false);
+
ironlake_pfit_disable(intel_crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -4191,7 +4230,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
- intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -4224,23 +4262,25 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_ddi_disable_pipe_clock(intel_crtc);
- for_each_encoder_on_crtc(dev, crtc, encoder)
- if (encoder->post_disable)
- encoder->post_disable(encoder);
-
if (intel_crtc->config.has_pch_encoder) {
lpt_disable_pch_transcoder(dev_priv);
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
intel_ddi_fdi_disable(crtc);
}
+ for_each_encoder_on_crtc(dev, crtc, encoder)
+ if (encoder->post_disable)
+ encoder->post_disable(encoder);
+
intel_crtc->active = false;
intel_update_watermarks(crtc);
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
- intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
+
+ if (intel_crtc_to_shared_dpll(intel_crtc))
+ intel_disable_shared_dpll(intel_crtc);
}
static void ironlake_crtc_off(struct drm_crtc *crtc)
@@ -4249,10 +4289,6 @@ static void ironlake_crtc_off(struct drm_crtc *crtc)
intel_put_shared_dpll(intel_crtc);
}
-static void haswell_crtc_off(struct drm_crtc *crtc)
-{
- intel_ddi_put_crtc_pll(crtc);
-}
static void i9xx_pfit_enable(struct intel_crtc *crtc)
{
@@ -4278,6 +4314,23 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
I915_WRITE(BCLRPAT(crtc->pipe), 0);
}
+static enum intel_display_power_domain port_to_power_domain(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ return POWER_DOMAIN_PORT_DDI_A_4_LANES;
+ case PORT_B:
+ return POWER_DOMAIN_PORT_DDI_B_4_LANES;
+ case PORT_C:
+ return POWER_DOMAIN_PORT_DDI_C_4_LANES;
+ case PORT_D:
+ return POWER_DOMAIN_PORT_DDI_D_4_LANES;
+ default:
+ WARN_ON_ONCE(1);
+ return POWER_DOMAIN_PORT_OTHER;
+ }
+}
+
#define for_each_power_domain(domain, mask) \
for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++) \
if ((1 << (domain)) & (mask))
@@ -4296,19 +4349,10 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder)
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
intel_dig_port = enc_to_dig_port(&intel_encoder->base);
- switch (intel_dig_port->port) {
- case PORT_A:
- return POWER_DOMAIN_PORT_DDI_A_4_LANES;
- case PORT_B:
- return POWER_DOMAIN_PORT_DDI_B_4_LANES;
- case PORT_C:
- return POWER_DOMAIN_PORT_DDI_C_4_LANES;
- case PORT_D:
- return POWER_DOMAIN_PORT_DDI_D_4_LANES;
- default:
- WARN_ON_ONCE(1);
- return POWER_DOMAIN_PORT_OTHER;
- }
+ return port_to_power_domain(intel_dig_port->port);
+ case INTEL_OUTPUT_DP_MST:
+ intel_dig_port = enc_to_mst(&intel_encoder->base)->primary;
+ return port_to_power_domain(intel_dig_port->port);
case INTEL_OUTPUT_ANALOG:
return POWER_DOMAIN_PORT_CRT;
case INTEL_OUTPUT_DSI:
@@ -4324,7 +4368,6 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
struct intel_encoder *intel_encoder;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
- bool pfit_enabled = intel_crtc->config.pch_pfit.enabled;
unsigned long mask;
enum transcoder transcoder;
@@ -4332,7 +4375,8 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
mask = BIT(POWER_DOMAIN_PIPE(pipe));
mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
- if (pfit_enabled)
+ if (intel_crtc->config.pch_pfit.enabled ||
+ intel_crtc->config.pch_pfit.force_thru)
mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
@@ -4389,7 +4433,8 @@ static void modeset_update_crtc_power_domains(struct drm_device *dev)
intel_display_set_init_power(dev_priv, false);
}
-int valleyview_get_vco(struct drm_i915_private *dev_priv)
+/* returns HPLL frequency in kHz */
+static int valleyview_get_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
@@ -4399,7 +4444,23 @@ int valleyview_get_vco(struct drm_i915_private *dev_priv)
CCK_FUSE_HPLL_FREQ_MASK;
mutex_unlock(&dev_priv->dpio_lock);
- return vco_freq[hpll_freq];
+ return vco_freq[hpll_freq] * 1000;
+}
+
+static void vlv_update_cdclk(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ dev_priv->vlv_cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
+ DRM_DEBUG_DRIVER("Current CD clock rate: %d kHz",
+ dev_priv->vlv_cdclk_freq);
+
+ /*
+ * Program the gmbus_freq based on the cdclk frequency.
+ * BSpec erroneously claims we should aim for 4MHz, but
+ * in fact 1MHz is the correct frequency.
+ */
+ I915_WRITE(GMBUSFREQ_VLV, dev_priv->vlv_cdclk_freq);
}
/* Adjust CDclk dividers to allow high res or save power if possible */
@@ -4408,12 +4469,11 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 val, cmd;
- WARN_ON(valleyview_cur_cdclk(dev_priv) != dev_priv->vlv_cdclk_freq);
- dev_priv->vlv_cdclk_freq = cdclk;
+ WARN_ON(dev_priv->display.get_display_clock_speed(dev) != dev_priv->vlv_cdclk_freq);
- if (cdclk >= 320) /* jump to highest voltage for 400MHz too */
+ if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
cmd = 2;
- else if (cdclk == 266)
+ else if (cdclk == 266667)
cmd = 1;
else
cmd = 0;
@@ -4430,18 +4490,23 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
}
mutex_unlock(&dev_priv->rps.hw_lock);
- if (cdclk == 400) {
+ if (cdclk == 400000) {
u32 divider, vco;
vco = valleyview_get_vco(dev_priv);
- divider = ((vco << 1) / cdclk) - 1;
+ divider = DIV_ROUND_CLOSEST(vco << 1, cdclk) - 1;
mutex_lock(&dev_priv->dpio_lock);
/* adjust cdclk divider */
val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
- val &= ~0xf;
+ val &= ~DISPLAY_FREQUENCY_VALUES;
val |= divider;
vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
+
+ if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
+ DISPLAY_FREQUENCY_STATUS) == (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
+ 50))
+ DRM_ERROR("timed out waiting for CDclk change\n");
mutex_unlock(&dev_priv->dpio_lock);
}
@@ -4454,54 +4519,43 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk)
* For high bandwidth configs, we set a higher latency in the bunit
* so that the core display fetch happens in time to avoid underruns.
*/
- if (cdclk == 400)
+ if (cdclk == 400000)
val |= 4500 / 250; /* 4.5 usec */
else
val |= 3000 / 250; /* 3.0 usec */
vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
mutex_unlock(&dev_priv->dpio_lock);
- /* Since we changed the CDclk, we need to update the GMBUSFREQ too */
- intel_i2c_reset(dev);
-}
-
-int valleyview_cur_cdclk(struct drm_i915_private *dev_priv)
-{
- int cur_cdclk, vco;
- int divider;
-
- vco = valleyview_get_vco(dev_priv);
-
- mutex_lock(&dev_priv->dpio_lock);
- divider = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
- mutex_unlock(&dev_priv->dpio_lock);
-
- divider &= 0xf;
-
- cur_cdclk = (vco << 1) / (divider + 1);
-
- return cur_cdclk;
+ vlv_update_cdclk(dev);
}
static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
int max_pixclk)
{
+ int vco = valleyview_get_vco(dev_priv);
+ int freq_320 = (vco << 1) % 320000 != 0 ? 333333 : 320000;
+
/*
* Really only a few cases to deal with, as only 4 CDclks are supported:
* 200MHz
* 267MHz
- * 320MHz
+ * 320/333MHz (depends on HPLL freq)
* 400MHz
* So we check to see whether we're above 90% of the lower bin and
* adjust if needed.
+ *
+ * We seem to get an unstable or solid color picture at 200MHz.
+ * Not sure what's wrong. For now use 200MHz only when all pipes
+ * are off.
*/
- if (max_pixclk > 288000) {
- return 400;
- } else if (max_pixclk > 240000) {
- return 320;
- } else
- return 266;
- /* Looks like the 200MHz CDclk freq doesn't work on some configs */
+ if (max_pixclk > freq_320*9/10)
+ return 400000;
+ else if (max_pixclk > 266667*9/10)
+ return freq_320;
+ else if (max_pixclk > 0)
+ return 266667;
+ else
+ return 200000;
}
/* compute the max pixel clock for new configuration */
@@ -4624,8 +4678,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
intel_crtc_enable_planes(crtc);
- drm_crtc_vblank_on(crtc);
-
/* Underruns don't raise interrupts, so check manually. */
i9xx_check_fifo_underruns(dev);
}
@@ -4718,8 +4770,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
if (IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
- drm_crtc_vblank_on(crtc);
-
/* Underruns don't raise interrupts, so check manually. */
i9xx_check_fifo_underruns(dev);
}
@@ -4759,6 +4809,16 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
if (IS_GEN2(dev))
intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
+ /*
+ * Vblank time updates from the shadow to live plane control register
+ * are blocked if the memory self-refresh mode is active at that
+ * moment. So to make sure the plane gets truly disabled, disable
+ * first the self-refresh mode. The self-refresh enable bit in turn
+ * will be checked/applied by the HW only at the next frame start
+ * event which is after the vblank start event, so we need to have a
+ * wait-for-vblank between disabling the plane and the pipe.
+ */
+ intel_set_memory_cxsr(dev_priv, false);
intel_crtc_disable_planes(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -4767,9 +4827,10 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
/*
* On gen2 planes are double buffered but the pipe isn't, so we must
* wait for planes to fully turn off before disabling the pipe.
+ * We also need to wait on all gmch platforms because of the
+ * self-refresh mode constraint explained above.
*/
- if (IS_GEN2(dev))
- intel_wait_for_vblank(dev, pipe);
+ intel_wait_for_vblank(dev, pipe);
intel_disable_pipe(dev_priv, pipe);
@@ -4796,7 +4857,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
mutex_lock(&dev->struct_mutex);
intel_update_fbc(dev);
- intel_edp_psr_update(dev);
mutex_unlock(&dev->struct_mutex);
}
@@ -4834,23 +4894,49 @@ static void intel_crtc_update_sarea(struct drm_crtc *crtc,
}
}
+/* Master function to enable/disable CRTC and corresponding power wells */
+void intel_crtc_control(struct drm_crtc *crtc, bool enable)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum intel_display_power_domain domain;
+ unsigned long domains;
+
+ if (enable) {
+ if (!intel_crtc->active) {
+ domains = get_crtc_power_domains(crtc);
+ for_each_power_domain(domain, domains)
+ intel_display_power_get(dev_priv, domain);
+ intel_crtc->enabled_power_domains = domains;
+
+ dev_priv->display.crtc_enable(crtc);
+ }
+ } else {
+ if (intel_crtc->active) {
+ dev_priv->display.crtc_disable(crtc);
+
+ domains = intel_crtc->enabled_power_domains;
+ for_each_power_domain(domain, domains)
+ intel_display_power_put(dev_priv, domain);
+ intel_crtc->enabled_power_domains = 0;
+ }
+ }
+}
+
/**
* Sets the power management mode of the pipe and plane.
*/
void intel_crtc_update_dpms(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder;
bool enable = false;
for_each_encoder_on_crtc(dev, crtc, intel_encoder)
enable |= intel_encoder->connectors_active;
- if (enable)
- dev_priv->display.crtc_enable(crtc);
- else
- dev_priv->display.crtc_disable(crtc);
+ intel_crtc_control(crtc, enable);
intel_crtc_update_sarea(crtc, enable);
}
@@ -4860,6 +4946,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_connector *connector;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *old_obj = intel_fb_obj(crtc->primary->fb);
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
/* crtc should still be enabled when we disable it. */
WARN_ON(!crtc->enabled);
@@ -4868,13 +4956,11 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
intel_crtc_update_sarea(crtc, false);
dev_priv->display.off(crtc);
- assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
- assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe);
- assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
-
if (crtc->primary->fb) {
mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_obj(to_intel_framebuffer(crtc->primary->fb)->obj);
+ intel_unpin_fb_obj(old_obj);
+ i915_gem_track_fb(old_obj, NULL,
+ INTEL_FRONTBUFFER_PRIMARY(pipe));
mutex_unlock(&dev->struct_mutex);
crtc->primary->fb = NULL;
}
@@ -4930,24 +5016,31 @@ static void intel_connector_check_state(struct intel_connector *connector)
connector->base.base.id,
connector->base.name);
+ /* there is no real hw state for MST connectors */
+ if (connector->mst_port)
+ return;
+
WARN(connector->base.dpms == DRM_MODE_DPMS_OFF,
"wrong connector dpms state\n");
WARN(connector->base.encoder != &encoder->base,
"active connector not linked to encoder\n");
- WARN(!encoder->connectors_active,
- "encoder->connectors_active not set\n");
- encoder_enabled = encoder->get_hw_state(encoder, &pipe);
- WARN(!encoder_enabled, "encoder not enabled\n");
- if (WARN_ON(!encoder->base.crtc))
- return;
+ if (encoder) {
+ WARN(!encoder->connectors_active,
+ "encoder->connectors_active not set\n");
+
+ encoder_enabled = encoder->get_hw_state(encoder, &pipe);
+ WARN(!encoder_enabled, "encoder not enabled\n");
+ if (WARN_ON(!encoder->base.crtc))
+ return;
- crtc = encoder->base.crtc;
+ crtc = encoder->base.crtc;
- WARN(!crtc->enabled, "crtc not enabled\n");
- WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
- WARN(pipe != to_intel_crtc(crtc)->pipe,
- "encoder active on the wrong pipe\n");
+ WARN(!crtc->enabled, "crtc not enabled\n");
+ WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
+ WARN(pipe != to_intel_crtc(crtc)->pipe,
+ "encoder active on the wrong pipe\n");
+ }
}
}
@@ -5152,9 +5245,11 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
if (HAS_IPS(dev))
hsw_compute_ips_config(crtc, pipe_config);
- /* XXX: PCH clock sharing is done in ->mode_set, so make sure the old
- * clock survives for now. */
- if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+ /*
+ * XXX: PCH/WRPLL clock sharing is done in ->mode_set, so make sure the
+ * old clock survives for now.
+ */
+ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev) || HAS_DDI(dev))
pipe_config->shared_dpll = crtc->config.shared_dpll;
if (pipe_config->has_pch_encoder)
@@ -5165,7 +5260,22 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
static int valleyview_get_display_clock_speed(struct drm_device *dev)
{
- return 400000; /* FIXME */
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int vco = valleyview_get_vco(dev_priv);
+ u32 val;
+ int divider;
+
+ mutex_lock(&dev_priv->dpio_lock);
+ val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
+ mutex_unlock(&dev_priv->dpio_lock);
+
+ divider = val & DISPLAY_FREQUENCY_VALUES;
+
+ WARN((val & DISPLAY_FREQUENCY_STATUS) !=
+ (divider << DISPLAY_FREQUENCY_STATUS_SHIFT),
+ "cdclk change in progress\n");
+
+ return DIV_ROUND_CLOSEST(vco << 1, divider + 1);
}
static int i945_get_display_clock_speed(struct drm_device *dev)
@@ -6051,6 +6161,10 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
u32 mdiv;
int refclk = 100000;
+ /* In case of MIPI DPLL will not even be used */
+ if (!(pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE))
+ return;
+
mutex_lock(&dev_priv->dpio_lock);
mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
mutex_unlock(&dev_priv->dpio_lock);
@@ -6116,8 +6230,8 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled);
- plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
- aligned_height, PAGE_SIZE);
+ plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
+ aligned_height);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe, plane, crtc->base.primary->fb->width,
@@ -7136,8 +7250,8 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc,
aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled);
- plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
- aligned_height, PAGE_SIZE);
+ plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
+ aligned_height);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe, plane, crtc->base.primary->fb->width,
@@ -7154,6 +7268,10 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t tmp;
+ if (!intel_display_power_enabled(dev_priv,
+ POWER_DOMAIN_PIPE(crtc->pipe)))
+ return false;
+
pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
@@ -7228,7 +7346,6 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
- struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
struct intel_crtc *crtc;
for_each_intel_crtc(dev, crtc)
@@ -7236,14 +7353,15 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
pipe_name(crtc->pipe));
WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
- WARN(plls->spll_refcount, "SPLL enabled\n");
- WARN(plls->wrpll1_refcount, "WRPLL1 enabled\n");
- WARN(plls->wrpll2_refcount, "WRPLL2 enabled\n");
+ WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
+ WARN(I915_READ(WRPLL_CTL1) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
+ WARN(I915_READ(WRPLL_CTL2) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
WARN(I915_READ(PCH_PP_STATUS) & PP_ON, "Panel power on\n");
WARN(I915_READ(BLC_PWM_CPU_CTL2) & BLM_PWM_ENABLE,
"CPU PWM1 enabled\n");
- WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
- "CPU PWM2 enabled\n");
+ if (IS_HASWELL(dev))
+ WARN(I915_READ(HSW_BLC_PWM2_CTL) & BLM_PWM_ENABLE,
+ "CPU PWM2 enabled\n");
WARN(I915_READ(BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE,
"PCH PWM1 enabled\n");
WARN(I915_READ(UTIL_PIN_CTL) & UTIL_PIN_ENABLE,
@@ -7256,7 +7374,17 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
* gen-specific and since we only disable LCPLL after we fully disable
* the interrupts, the check below should be enough.
*/
- WARN(!dev_priv->pm.irqs_disabled, "IRQs enabled\n");
+ WARN(intel_irqs_enabled(dev_priv), "IRQs enabled\n");
+}
+
+static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+
+ if (IS_HASWELL(dev))
+ return I915_READ(D_COMP_HSW);
+ else
+ return I915_READ(D_COMP_BDW);
}
static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
@@ -7267,12 +7395,12 @@ static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
mutex_lock(&dev_priv->rps.hw_lock);
if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
val))
- DRM_ERROR("Failed to disable D_COMP\n");
+ DRM_ERROR("Failed to write to D_COMP\n");
mutex_unlock(&dev_priv->rps.hw_lock);
} else {
- I915_WRITE(D_COMP, val);
+ I915_WRITE(D_COMP_BDW, val);
+ POSTING_READ(D_COMP_BDW);
}
- POSTING_READ(D_COMP);
}
/*
@@ -7310,12 +7438,13 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
if (wait_for((I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK) == 0, 1))
DRM_ERROR("LCPLL still locked\n");
- val = I915_READ(D_COMP);
+ val = hsw_read_dcomp(dev_priv);
val |= D_COMP_COMP_DISABLE;
hsw_write_dcomp(dev_priv, val);
ndelay(100);
- if (wait_for((I915_READ(D_COMP) & D_COMP_RCOMP_IN_PROGRESS) == 0, 1))
+ if (wait_for((hsw_read_dcomp(dev_priv) & D_COMP_RCOMP_IN_PROGRESS) == 0,
+ 1))
DRM_ERROR("D_COMP RCOMP still in progress\n");
if (allow_power_down) {
@@ -7364,7 +7493,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
POSTING_READ(LCPLL_CTL);
}
- val = I915_READ(D_COMP);
+ val = hsw_read_dcomp(dev_priv);
val |= D_COMP_COMP_FORCE;
val &= ~D_COMP_COMP_DISABLE;
hsw_write_dcomp(dev_priv, val);
@@ -7470,13 +7599,59 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
if (!intel_ddi_pll_select(intel_crtc))
return -EINVAL;
- intel_ddi_pll_enable(intel_crtc);
intel_crtc->lowfreq_avail = false;
return 0;
}
+static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
+ struct intel_crtc_config *pipe_config)
+{
+ struct drm_device *dev = crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_shared_dpll *pll;
+ enum port port;
+ uint32_t tmp;
+
+ tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
+
+ port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT;
+
+ pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
+
+ switch (pipe_config->ddi_pll_sel) {
+ case PORT_CLK_SEL_WRPLL1:
+ pipe_config->shared_dpll = DPLL_ID_WRPLL1;
+ break;
+ case PORT_CLK_SEL_WRPLL2:
+ pipe_config->shared_dpll = DPLL_ID_WRPLL2;
+ break;
+ }
+
+ if (pipe_config->shared_dpll >= 0) {
+ pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
+
+ WARN_ON(!pll->get_hw_state(dev_priv, pll,
+ &pipe_config->dpll_hw_state));
+ }
+
+ /*
+ * Haswell has only FDI/PCH transcoder A. It is which is connected to
+ * DDI E. So just check whether this pipe is wired to DDI E and whether
+ * the PCH transcoder is on.
+ */
+ if ((port == PORT_E) && I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
+ pipe_config->has_pch_encoder = true;
+
+ tmp = I915_READ(FDI_RX_CTL(PIPE_A));
+ pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
+ FDI_DP_PORT_WIDTH_SHIFT) + 1;
+
+ ironlake_get_fdi_m_n_config(crtc, pipe_config);
+ }
+}
+
static bool haswell_get_pipe_config(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config)
{
@@ -7522,22 +7697,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
if (!(tmp & PIPECONF_ENABLE))
return false;
- /*
- * Haswell has only FDI/PCH transcoder A. It is which is connected to
- * DDI E. So just check whether this pipe is wired to DDI E and whether
- * the PCH transcoder is on.
- */
- tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
- if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) &&
- I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
- pipe_config->has_pch_encoder = true;
-
- tmp = I915_READ(FDI_RX_CTL(PIPE_A));
- pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
- FDI_DP_PORT_WIDTH_SHIFT) + 1;
-
- ironlake_get_fdi_m_n_config(crtc, pipe_config);
- }
+ haswell_get_ddi_port_state(crtc, pipe_config);
intel_get_pipe_timings(crtc, pipe_config);
@@ -7982,8 +8142,8 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int pipe = intel_crtc->pipe;
- int x = intel_crtc->cursor_x;
- int y = intel_crtc->cursor_y;
+ int x = crtc->cursor_x;
+ int y = crtc->cursor_y;
u32 base = 0, pos = 0;
if (on)
@@ -8027,21 +8187,27 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
intel_crtc->cursor_base = base;
}
-static int intel_crtc_cursor_set(struct drm_crtc *crtc,
- struct drm_file *file,
- uint32_t handle,
- uint32_t width, uint32_t height)
+/*
+ * intel_crtc_cursor_set_obj - Set cursor to specified GEM object
+ *
+ * Note that the object's reference will be consumed if the update fails. If
+ * the update succeeds, the reference of the old object (if any) will be
+ * consumed.
+ */
+static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
+ struct drm_i915_gem_object *obj,
+ uint32_t width, uint32_t height)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_i915_gem_object *obj;
+ enum pipe pipe = intel_crtc->pipe;
unsigned old_width;
uint32_t addr;
int ret;
/* if we want to turn off the cursor ignore width and height */
- if (!handle) {
+ if (!obj) {
DRM_DEBUG_KMS("cursor off\n");
addr = 0;
obj = NULL;
@@ -8057,12 +8223,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
return -EINVAL;
}
- obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
- if (&obj->base == NULL)
- return -ENOENT;
-
if (obj->base.size < width * height * 4) {
- DRM_DEBUG_KMS("buffer is to small\n");
+ DRM_DEBUG_KMS("buffer is too small\n");
ret = -ENOMEM;
goto fail;
}
@@ -8117,9 +8279,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
if (intel_crtc->cursor_bo) {
if (!INTEL_INFO(dev)->cursor_needs_physical)
i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo);
- drm_gem_object_unreference(&intel_crtc->cursor_bo->base);
}
+ i915_gem_track_fb(intel_crtc->cursor_bo, obj,
+ INTEL_FRONTBUFFER_CURSOR(pipe));
mutex_unlock(&dev->struct_mutex);
old_width = intel_crtc->cursor_width;
@@ -8135,6 +8298,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
}
+ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe));
+
return 0;
fail_unpin:
i915_gem_object_unpin_from_display_plane(obj);
@@ -8145,19 +8310,6 @@ fail:
return ret;
}
-static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- intel_crtc->cursor_x = clamp_t(int, x, SHRT_MIN, SHRT_MAX);
- intel_crtc->cursor_y = clamp_t(int, y, SHRT_MIN, SHRT_MAX);
-
- if (intel_crtc->active)
- intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
-
- return 0;
-}
-
static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t start, uint32_t size)
{
@@ -8233,7 +8385,7 @@ static u32
intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp)
{
u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp);
- return ALIGN(pitch * mode->vdisplay, PAGE_SIZE);
+ return PAGE_ALIGN(pitch * mode->vdisplay);
}
static struct drm_framebuffer *
@@ -8658,16 +8810,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
return mode;
}
-static void intel_increase_pllclock(struct drm_crtc *crtc)
+static void intel_increase_pllclock(struct drm_device *dev,
+ enum pipe pipe)
{
- struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- int pipe = intel_crtc->pipe;
int dpll_reg = DPLL(pipe);
int dpll;
- if (HAS_PCH_SPLIT(dev))
+ if (!HAS_GMCH_DISPLAY(dev))
return;
if (!dev_priv->lvds_downclock_avail)
@@ -8695,7 +8845,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- if (HAS_PCH_SPLIT(dev))
+ if (!HAS_GMCH_DISPLAY(dev))
return;
if (!dev_priv->lvds_downclock_avail)
@@ -8764,28 +8914,179 @@ out:
intel_runtime_pm_put(dev_priv);
}
-void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring)
+
+/**
+ * intel_mark_fb_busy - mark given planes as busy
+ * @dev: DRM device
+ * @frontbuffer_bits: bits for the affected planes
+ * @ring: optional ring for asynchronous commands
+ *
+ * This function gets called every time the screen contents change. It can be
+ * used to keep e.g. the update rate at the nominal refresh rate with DRRS.
+ */
+static void intel_mark_fb_busy(struct drm_device *dev,
+ unsigned frontbuffer_bits,
+ struct intel_engine_cs *ring)
{
- struct drm_device *dev = obj->base.dev;
- struct drm_crtc *crtc;
+ enum pipe pipe;
if (!i915.powersave)
return;
- for_each_crtc(dev, crtc) {
- if (!crtc->primary->fb)
- continue;
-
- if (to_intel_framebuffer(crtc->primary->fb)->obj != obj)
+ for_each_pipe(pipe) {
+ if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe)))
continue;
- intel_increase_pllclock(crtc);
+ intel_increase_pllclock(dev, pipe);
if (ring && intel_fbc_enabled(dev))
ring->fbc_dirty = true;
}
}
+/**
+ * intel_fb_obj_invalidate - invalidate frontbuffer object
+ * @obj: GEM object to invalidate
+ * @ring: set for asynchronous rendering
+ *
+ * This function gets called every time rendering on the given object starts and
+ * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must
+ * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed
+ * until the rendering completes or a flip on this frontbuffer plane is
+ * scheduled.
+ */
+void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
+ struct intel_engine_cs *ring)
+{
+ struct drm_device *dev = obj->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ if (!obj->frontbuffer_bits)
+ return;
+
+ if (ring) {
+ mutex_lock(&dev_priv->fb_tracking.lock);
+ dev_priv->fb_tracking.busy_bits
+ |= obj->frontbuffer_bits;
+ dev_priv->fb_tracking.flip_bits
+ &= ~obj->frontbuffer_bits;
+ mutex_unlock(&dev_priv->fb_tracking.lock);
+ }
+
+ intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring);
+
+ intel_edp_psr_invalidate(dev, obj->frontbuffer_bits);
+}
+
+/**
+ * intel_frontbuffer_flush - flush frontbuffer
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called every time rendering on the given planes has
+ * completed and frontbuffer caching can be started again. Flushes will get
+ * delayed if they're blocked by some oustanding asynchronous rendering.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flush(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ /* Delay flushing when rings are still busy.*/
+ mutex_lock(&dev_priv->fb_tracking.lock);
+ frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits;
+ mutex_unlock(&dev_priv->fb_tracking.lock);
+
+ intel_mark_fb_busy(dev, frontbuffer_bits, NULL);
+
+ intel_edp_psr_flush(dev, frontbuffer_bits);
+}
+
+/**
+ * intel_fb_obj_flush - flush frontbuffer object
+ * @obj: GEM object to flush
+ * @retire: set when retiring asynchronous rendering
+ *
+ * This function gets called every time rendering on the given object has
+ * completed and frontbuffer caching can be started again. If @retire is true
+ * then any delayed flushes will be unblocked.
+ */
+void intel_fb_obj_flush(struct drm_i915_gem_object *obj,
+ bool retire)
+{
+ struct drm_device *dev = obj->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned frontbuffer_bits;
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ if (!obj->frontbuffer_bits)
+ return;
+
+ frontbuffer_bits = obj->frontbuffer_bits;
+
+ if (retire) {
+ mutex_lock(&dev_priv->fb_tracking.lock);
+ /* Filter out new bits since rendering started. */
+ frontbuffer_bits &= dev_priv->fb_tracking.busy_bits;
+
+ dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits;
+ mutex_unlock(&dev_priv->fb_tracking.lock);
+ }
+
+ intel_frontbuffer_flush(dev, frontbuffer_bits);
+}
+
+/**
+ * intel_frontbuffer_flip_prepare - prepare asnychronous frontbuffer flip
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after scheduling a flip on @obj. The actual
+ * frontbuffer flushing will be delayed until completion is signalled with
+ * intel_frontbuffer_flip_complete. If an invalidate happens in between this
+ * flush will be cancelled.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flip_prepare(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->fb_tracking.lock);
+ dev_priv->fb_tracking.flip_bits
+ |= frontbuffer_bits;
+ mutex_unlock(&dev_priv->fb_tracking.lock);
+}
+
+/**
+ * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flush
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after the flip has been latched and will complete
+ * on the next vblank. It will execute the fush if it hasn't been cancalled yet.
+ *
+ * Can be called without any locks held.
+ */
+void intel_frontbuffer_flip_complete(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->fb_tracking.lock);
+ /* Mask any cancelled flips. */
+ frontbuffer_bits &= dev_priv->fb_tracking.flip_bits;
+ dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits;
+ mutex_unlock(&dev_priv->fb_tracking.lock);
+
+ intel_frontbuffer_flush(dev, frontbuffer_bits);
+}
+
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -8803,8 +9104,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
kfree(work);
}
- intel_crtc_cursor_set(crtc, NULL, 0, 0, 0);
-
drm_crtc_cleanup(crtc);
kfree(intel_crtc);
@@ -8815,6 +9114,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
struct intel_unpin_work *work =
container_of(__work, struct intel_unpin_work, work);
struct drm_device *dev = work->crtc->dev;
+ enum pipe pipe = to_intel_crtc(work->crtc)->pipe;
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(work->old_fb_obj);
@@ -8824,6 +9124,8 @@ static void intel_unpin_work_fn(struct work_struct *__work)
intel_update_fbc(dev);
mutex_unlock(&dev->struct_mutex);
+ intel_frontbuffer_flip_complete(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
+
BUG_ON(atomic_read(&to_intel_crtc(work->crtc)->unpin_work_count) == 0);
atomic_dec(&to_intel_crtc(work->crtc)->unpin_work_count);
@@ -9193,6 +9495,150 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
return 0;
}
+static bool use_mmio_flip(struct intel_engine_cs *ring,
+ 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 (ring == NULL)
+ return true;
+
+ if (INTEL_INFO(ring->dev)->gen < 5)
+ return false;
+
+ if (i915.use_mmio_flip < 0)
+ return false;
+ else if (i915.use_mmio_flip > 0)
+ return true;
+ else
+ return ring != obj->ring;
+}
+
+static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_framebuffer *intel_fb =
+ to_intel_framebuffer(intel_crtc->base.primary->fb);
+ struct drm_i915_gem_object *obj = intel_fb->obj;
+ u32 dspcntr;
+ u32 reg;
+
+ intel_mark_page_flip_active(intel_crtc);
+
+ reg = DSPCNTR(intel_crtc->plane);
+ dspcntr = I915_READ(reg);
+
+ if (INTEL_INFO(dev)->gen >= 4) {
+ if (obj->tiling_mode != I915_TILING_NONE)
+ dspcntr |= DISPPLANE_TILED;
+ else
+ dspcntr &= ~DISPPLANE_TILED;
+ }
+ I915_WRITE(reg, dspcntr);
+
+ I915_WRITE(DSPSURF(intel_crtc->plane),
+ intel_crtc->unpin_work->gtt_offset);
+ POSTING_READ(DSPSURF(intel_crtc->plane));
+}
+
+static int intel_postpone_flip(struct drm_i915_gem_object *obj)
+{
+ struct intel_engine_cs *ring;
+ int ret;
+
+ lockdep_assert_held(&obj->base.dev->struct_mutex);
+
+ if (!obj->last_write_seqno)
+ return 0;
+
+ ring = obj->ring;
+
+ if (i915_seqno_passed(ring->get_seqno(ring, true),
+ obj->last_write_seqno))
+ return 0;
+
+ ret = i915_gem_check_olr(ring, obj->last_write_seqno);
+ if (ret)
+ return ret;
+
+ if (WARN_ON(!ring->irq_get(ring)))
+ return 0;
+
+ return 1;
+}
+
+void intel_notify_mmio_flip(struct intel_engine_cs *ring)
+{
+ struct drm_i915_private *dev_priv = to_i915(ring->dev);
+ struct intel_crtc *intel_crtc;
+ unsigned long irq_flags;
+ u32 seqno;
+
+ seqno = ring->get_seqno(ring, false);
+
+ spin_lock_irqsave(&dev_priv->mmio_flip_lock, irq_flags);
+ for_each_intel_crtc(ring->dev, intel_crtc) {
+ struct intel_mmio_flip *mmio_flip;
+
+ mmio_flip = &intel_crtc->mmio_flip;
+ if (mmio_flip->seqno == 0)
+ continue;
+
+ if (ring->id != mmio_flip->ring_id)
+ continue;
+
+ if (i915_seqno_passed(seqno, mmio_flip->seqno)) {
+ intel_do_mmio_flip(intel_crtc);
+ mmio_flip->seqno = 0;
+ ring->irq_put(ring);
+ }
+ }
+ spin_unlock_irqrestore(&dev_priv->mmio_flip_lock, irq_flags);
+}
+
+static int intel_queue_mmio_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj,
+ struct intel_engine_cs *ring,
+ uint32_t flags)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ unsigned long irq_flags;
+ int ret;
+
+ if (WARN_ON(intel_crtc->mmio_flip.seqno))
+ return -EBUSY;
+
+ ret = intel_postpone_flip(obj);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ intel_do_mmio_flip(intel_crtc);
+ return 0;
+ }
+
+ spin_lock_irqsave(&dev_priv->mmio_flip_lock, irq_flags);
+ intel_crtc->mmio_flip.seqno = obj->last_write_seqno;
+ intel_crtc->mmio_flip.ring_id = obj->ring->id;
+ spin_unlock_irqrestore(&dev_priv->mmio_flip_lock, irq_flags);
+
+ /*
+ * Double check to catch cases where irq fired before
+ * mmio flip data was ready
+ */
+ intel_notify_mmio_flip(obj->ring);
+ return 0;
+}
+
static int intel_default_queue_flip(struct drm_device *dev,
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
@@ -9211,13 +9657,22 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum pipe pipe = intel_crtc->pipe;
struct intel_unpin_work *work;
struct intel_engine_cs *ring;
unsigned long flags;
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->pixel_format != crtc->primary->fb->pixel_format)
return -EINVAL;
@@ -9240,7 +9695,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->event = event;
work->crtc = crtc;
- work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
+ work->old_fb_obj = intel_fb_obj(old_fb);
INIT_WORK(&work->work, intel_unpin_work_fn);
ret = drm_crtc_vblank_get(crtc);
@@ -9281,10 +9736,15 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_crtc->reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
- work->flip_count = I915_READ(PIPE_FLIPCOUNT_GM45(intel_crtc->pipe)) + 1;
+ work->flip_count = I915_READ(PIPE_FLIPCOUNT_GM45(pipe)) + 1;
if (IS_VALLEYVIEW(dev)) {
ring = &dev_priv->ring[BCS];
+ if (obj->tiling_mode != work->old_fb_obj->tiling_mode)
+ /* vlv: DISPLAY_FLIP fails to change tiling */
+ ring = NULL;
+ } else if (IS_IVYBRIDGE(dev)) {
+ ring = &dev_priv->ring[BCS];
} else if (INTEL_INFO(dev)->gen >= 7) {
ring = obj->ring;
if (ring == NULL || ring->id != RCS)
@@ -9300,12 +9760,20 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->gtt_offset =
i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset;
- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring, page_flip_flags);
+ if (use_mmio_flip(ring, obj))
+ ret = intel_queue_mmio_flip(dev, crtc, fb, obj, ring,
+ page_flip_flags);
+ else
+ ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
+ page_flip_flags);
if (ret)
goto cleanup_unpin;
+ i915_gem_track_fb(work->old_fb_obj, obj,
+ INTEL_FRONTBUFFER_PRIMARY(pipe));
+
intel_disable_fbc(dev);
- intel_mark_fb_busy(obj, NULL);
+ intel_frontbuffer_flip_prepare(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
mutex_unlock(&dev->struct_mutex);
trace_i915_flip_request(intel_crtc->plane, obj);
@@ -9335,7 +9803,7 @@ out_hang:
intel_crtc_wait_for_pending_flips(crtc);
ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb);
if (ret == 0 && event)
- drm_send_vblank_event(dev, intel_crtc->pipe, event);
+ drm_send_vblank_event(dev, pipe, event);
}
return ret;
}
@@ -10008,11 +10476,14 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I(double_wide);
+ PIPE_CONF_CHECK_X(ddi_pll_sel);
+
PIPE_CONF_CHECK_I(shared_dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
+ PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
PIPE_CONF_CHECK_I(pipe_bpp);
@@ -10074,6 +10545,14 @@ check_encoder_state(struct drm_device *dev)
if (connector->base.dpms != DRM_MODE_DPMS_OFF)
active = true;
}
+ /*
+ * for MST connectors if we unplug the connector is gone
+ * away but the encoder is still connected to a crtc
+ * until a modeset happens in response to the hotplug.
+ */
+ if (!enabled && encoder->base.encoder_type == DRM_MODE_ENCODER_DPMST)
+ continue;
+
WARN(!!encoder->base.crtc != enabled,
"encoder's enabled state mismatch "
"(expected %i, found %i)\n",
@@ -10369,20 +10848,23 @@ static int __intel_set_mode(struct drm_crtc *crtc,
* on the DPLL.
*/
for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
- struct drm_framebuffer *old_fb;
+ struct drm_framebuffer *old_fb = crtc->primary->fb;
+ struct drm_i915_gem_object *old_obj = intel_fb_obj(old_fb);
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev,
- to_intel_framebuffer(fb)->obj,
+ obj,
NULL);
if (ret != 0) {
DRM_ERROR("pin & fence failed\n");
mutex_unlock(&dev->struct_mutex);
goto done;
}
- old_fb = crtc->primary->fb;
if (old_fb)
- intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
+ intel_unpin_fb_obj(old_obj);
+ i915_gem_track_fb(old_obj, obj,
+ INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
mutex_unlock(&dev->struct_mutex);
crtc->primary->fb = fb;
@@ -10554,12 +11036,17 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
if (is_crtc_connector_off(set)) {
config->mode_changed = true;
} else if (set->crtc->primary->fb != set->fb) {
- /* If we have no fb then treat it as a full mode set */
+ /*
+ * If we have no fb, we can only flip as long as the crtc is
+ * active, otherwise we need a full mode set. The crtc may
+ * be active if we've only disabled the primary plane, or
+ * in fastboot situations.
+ */
if (set->crtc->primary->fb == NULL) {
struct intel_crtc *intel_crtc =
to_intel_crtc(set->crtc);
- if (intel_crtc->active && i915.fastboot) {
+ if (intel_crtc->active) {
DRM_DEBUG_KMS("crtc has no fb, will flip\n");
config->fb_changed = true;
} else {
@@ -10611,7 +11098,7 @@ intel_modeset_stage_output_state(struct drm_device *dev,
* for them. */
for (ro = 0; ro < set->num_connectors; ro++) {
if (set->connectors[ro] == &connector->base) {
- connector->new_encoder = connector->encoder;
+ connector->new_encoder = intel_find_encoder(connector, to_intel_crtc(set->crtc)->pipe);
break;
}
}
@@ -10657,7 +11144,7 @@ intel_modeset_stage_output_state(struct drm_device *dev,
new_crtc)) {
return -EINVAL;
}
- connector->encoder->new_crtc = to_intel_crtc(new_crtc);
+ connector->new_encoder->new_crtc = to_intel_crtc(new_crtc);
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
connector->base.base.id,
@@ -10691,7 +11178,12 @@ intel_modeset_stage_output_state(struct drm_device *dev,
}
}
/* Now we've also updated encoder->new_crtc for all encoders. */
-
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ base.head) {
+ if (connector->new_encoder)
+ if (connector->new_encoder != connector->encoder)
+ connector->encoder = connector->new_encoder;
+ }
for_each_intel_crtc(dev, crtc) {
crtc->new_enabled = false;
@@ -10797,10 +11289,24 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
ret = intel_set_mode(set->crtc, set->mode,
set->x, set->y, set->fb);
} else if (config->fb_changed) {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
+
intel_crtc_wait_for_pending_flips(set->crtc);
ret = intel_pipe_set_base(set->crtc,
set->x, set->y, set->fb);
+
+ /*
+ * We need to make sure the primary plane is re-enabled if it
+ * has previously been turned off.
+ */
+ if (!intel_crtc->primary_enabled && ret == 0) {
+ WARN_ON(!intel_crtc->active);
+ intel_enable_primary_hw_plane(dev_priv, intel_crtc->plane,
+ intel_crtc->pipe);
+ }
+
/*
* In the fastboot case this may be our only check of the
* state after boot. It would be better to only do it on
@@ -10841,26 +11347,21 @@ out_config:
}
static const struct drm_crtc_funcs intel_crtc_funcs = {
- .cursor_set = intel_crtc_cursor_set,
- .cursor_move = intel_crtc_cursor_move,
.gamma_set = intel_crtc_gamma_set,
.set_config = intel_crtc_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
};
-static void intel_cpu_pll_init(struct drm_device *dev)
-{
- if (HAS_DDI(dev))
- intel_ddi_pll_init(dev);
-}
-
static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
struct intel_dpll_hw_state *hw_state)
{
uint32_t val;
+ if (!intel_display_power_enabled(dev_priv, POWER_DOMAIN_PLLS))
+ return false;
+
val = I915_READ(PCH_DPLL(pll->id));
hw_state->dpll = val;
hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
@@ -10942,7 +11443,9 @@ static void intel_shared_dpll_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+ if (HAS_DDI(dev))
+ intel_ddi_pll_init(dev);
+ else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
ibx_pch_dpll_init(dev);
else
dev_priv->num_shared_dpll = 0;
@@ -10950,17 +11453,328 @@ static void intel_shared_dpll_init(struct drm_device *dev)
BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
}
+static int
+intel_primary_plane_disable(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_crtc *intel_crtc;
+
+ if (!plane->fb)
+ return 0;
+
+ BUG_ON(!plane->crtc);
+
+ intel_crtc = to_intel_crtc(plane->crtc);
+
+ /*
+ * Even though we checked plane->fb above, it's still possible that
+ * the primary plane has been implicitly disabled because the crtc
+ * coordinates given weren't visible, or because we detected
+ * that it was 100% covered by a sprite plane. Or, the CRTC may be
+ * off and we've set a fb, but haven't actually turned on the CRTC yet.
+ * In either case, we need to unpin the FB and let the fb pointer get
+ * updated, but otherwise we don't need to touch the hardware.
+ */
+ if (!intel_crtc->primary_enabled)
+ goto disable_unpin;
+
+ intel_crtc_wait_for_pending_flips(plane->crtc);
+ intel_disable_primary_hw_plane(dev_priv, intel_plane->plane,
+ intel_plane->pipe);
+disable_unpin:
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
+ INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
+ intel_unpin_fb_obj(intel_fb_obj(plane->fb));
+ mutex_unlock(&dev->struct_mutex);
+ plane->fb = NULL;
+
+ return 0;
+}
+
+static int
+intel_primary_plane_setplane(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,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+ struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
+ struct drm_rect dest = {
+ /* integer pixels */
+ .x1 = crtc_x,
+ .y1 = crtc_y,
+ .x2 = crtc_x + crtc_w,
+ .y2 = crtc_y + crtc_h,
+ };
+ struct drm_rect src = {
+ /* 16.16 fixed point */
+ .x1 = src_x,
+ .y1 = src_y,
+ .x2 = src_x + src_w,
+ .y2 = src_y + src_h,
+ };
+ const struct drm_rect clip = {
+ /* integer pixels */
+ .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
+ .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
+ };
+ bool visible;
+ int ret;
+
+ ret = drm_plane_helper_check_update(plane, crtc, fb,
+ &src, &dest, &clip,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, true, &visible);
+
+ if (ret)
+ return ret;
+
+ /*
+ * If the CRTC isn't enabled, we're just pinning the framebuffer,
+ * updating the fb pointer, and returning without touching the
+ * hardware. This allows us to later do a drmModeSetCrtc with fb=-1 to
+ * turn on the display with all planes setup as desired.
+ */
+ if (!crtc->enabled) {
+ mutex_lock(&dev->struct_mutex);
+
+ /*
+ * If we already called setplane while the crtc was disabled,
+ * we may have an fb pinned; unpin it.
+ */
+ if (plane->fb)
+ intel_unpin_fb_obj(old_obj);
+
+ i915_gem_track_fb(old_obj, obj,
+ INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
+
+ /* Pin and return without programming hardware */
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+ }
+
+ intel_crtc_wait_for_pending_flips(crtc);
+
+ /*
+ * If clipping results in a non-visible primary plane, we'll disable
+ * the primary plane. Note that this is a bit different than what
+ * happens if userspace explicitly disables the plane by passing fb=0
+ * because plane->fb still gets set and pinned.
+ */
+ if (!visible) {
+ mutex_lock(&dev->struct_mutex);
+
+ /*
+ * Try to pin the new fb first so that we can bail out if we
+ * fail.
+ */
+ if (plane->fb != fb) {
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+ }
+
+ i915_gem_track_fb(old_obj, obj,
+ INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe));
+
+ if (intel_crtc->primary_enabled)
+ intel_disable_primary_hw_plane(dev_priv,
+ intel_plane->plane,
+ intel_plane->pipe);
+
+
+ if (plane->fb != fb)
+ if (plane->fb)
+ intel_unpin_fb_obj(old_obj);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+ }
+
+ ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
+ if (ret)
+ return ret;
+
+ if (!intel_crtc->primary_enabled)
+ intel_enable_primary_hw_plane(dev_priv, intel_crtc->plane,
+ intel_crtc->pipe);
+
+ return 0;
+}
+
+/* Common destruction function for both primary and cursor planes */
+static void intel_plane_destroy(struct drm_plane *plane)
+{
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ drm_plane_cleanup(plane);
+ kfree(intel_plane);
+}
+
+static const struct drm_plane_funcs intel_primary_plane_funcs = {
+ .update_plane = intel_primary_plane_setplane,
+ .disable_plane = intel_primary_plane_disable,
+ .destroy = intel_plane_destroy,
+};
+
+static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
+ int pipe)
+{
+ struct intel_plane *primary;
+ const uint32_t *intel_primary_formats;
+ int num_formats;
+
+ primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+ if (primary == NULL)
+ return NULL;
+
+ primary->can_scale = false;
+ primary->max_downscale = 1;
+ primary->pipe = pipe;
+ primary->plane = pipe;
+ if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
+ primary->plane = !pipe;
+
+ if (INTEL_INFO(dev)->gen <= 3) {
+ intel_primary_formats = intel_primary_formats_gen2;
+ num_formats = ARRAY_SIZE(intel_primary_formats_gen2);
+ } else {
+ intel_primary_formats = intel_primary_formats_gen4;
+ num_formats = ARRAY_SIZE(intel_primary_formats_gen4);
+ }
+
+ drm_universal_plane_init(dev, &primary->base, 0,
+ &intel_primary_plane_funcs,
+ intel_primary_formats, num_formats,
+ DRM_PLANE_TYPE_PRIMARY);
+ return &primary->base;
+}
+
+static int
+intel_cursor_plane_disable(struct drm_plane *plane)
+{
+ if (!plane->fb)
+ return 0;
+
+ BUG_ON(!plane->crtc);
+
+ return intel_crtc_cursor_set_obj(plane->crtc, NULL, 0, 0);
+}
+
+static int
+intel_cursor_plane_update(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,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+ struct drm_i915_gem_object *obj = intel_fb->obj;
+ struct drm_rect dest = {
+ /* integer pixels */
+ .x1 = crtc_x,
+ .y1 = crtc_y,
+ .x2 = crtc_x + crtc_w,
+ .y2 = crtc_y + crtc_h,
+ };
+ struct drm_rect src = {
+ /* 16.16 fixed point */
+ .x1 = src_x,
+ .y1 = src_y,
+ .x2 = src_x + src_w,
+ .y2 = src_y + src_h,
+ };
+ const struct drm_rect clip = {
+ /* integer pixels */
+ .x2 = intel_crtc->config.pipe_src_w,
+ .y2 = intel_crtc->config.pipe_src_h,
+ };
+ bool visible;
+ int ret;
+
+ ret = drm_plane_helper_check_update(plane, crtc, fb,
+ &src, &dest, &clip,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ true, true, &visible);
+ if (ret)
+ return ret;
+
+ crtc->cursor_x = crtc_x;
+ crtc->cursor_y = crtc_y;
+ if (fb != crtc->cursor->fb) {
+ return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h);
+ } else {
+ intel_crtc_update_cursor(crtc, visible);
+ return 0;
+ }
+}
+static const struct drm_plane_funcs intel_cursor_plane_funcs = {
+ .update_plane = intel_cursor_plane_update,
+ .disable_plane = intel_cursor_plane_disable,
+ .destroy = intel_plane_destroy,
+};
+
+static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
+ int pipe)
+{
+ struct intel_plane *cursor;
+
+ cursor = kzalloc(sizeof(*cursor), GFP_KERNEL);
+ if (cursor == NULL)
+ return NULL;
+
+ cursor->can_scale = false;
+ cursor->max_downscale = 1;
+ cursor->pipe = pipe;
+ cursor->plane = pipe;
+
+ drm_universal_plane_init(dev, &cursor->base, 0,
+ &intel_cursor_plane_funcs,
+ intel_cursor_formats,
+ ARRAY_SIZE(intel_cursor_formats),
+ DRM_PLANE_TYPE_CURSOR);
+ return &cursor->base;
+}
+
static void intel_crtc_init(struct drm_device *dev, int pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc;
- int i;
+ struct drm_plane *primary = NULL;
+ struct drm_plane *cursor = NULL;
+ int i, ret;
intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
if (intel_crtc == NULL)
return;
- drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
+ primary = intel_primary_plane_create(dev, pipe);
+ if (!primary)
+ goto fail;
+
+ cursor = intel_cursor_plane_create(dev, pipe);
+ if (!cursor)
+ goto fail;
+
+ ret = drm_crtc_init_with_planes(dev, &intel_crtc->base, primary,
+ cursor, &intel_crtc_funcs);
+ if (ret)
+ goto fail;
drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
for (i = 0; i < 256; i++) {
@@ -10971,7 +11785,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
/*
* On gen2/3 only plane A can do fbc, but the panel fitter and lvds port
- * is hooked to plane B. Hence we want plane A feeding pipe B.
+ * is hooked to pipe B. Hence we want plane A feeding pipe B.
*/
intel_crtc->pipe = pipe;
intel_crtc->plane = pipe;
@@ -10993,6 +11807,14 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
+ return;
+
+fail:
+ if (primary)
+ drm_plane_cleanup(primary);
+ if (cursor)
+ drm_plane_cleanup(cursor);
+ kfree(intel_crtc);
}
enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
@@ -11012,21 +11834,20 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file)
{
struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
- struct drm_mode_object *drmmode_obj;
+ struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
- drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
- DRM_MODE_OBJECT_CRTC);
+ drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
- if (!drmmode_obj) {
+ if (!drmmode_crtc) {
DRM_ERROR("no such CRTC id\n");
return -ENOENT;
}
- crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
+ crtc = to_intel_crtc(drmmode_crtc);
pipe_from_crtc_id->pipe = crtc->pipe;
return 0;
@@ -11088,6 +11909,22 @@ const char *intel_output_name(int output)
return names[output];
}
+static bool intel_crt_present(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (IS_ULT(dev))
+ return false;
+
+ if (IS_CHERRYVIEW(dev))
+ return false;
+
+ if (IS_VALLEYVIEW(dev) && !dev_priv->vbt.int_crt_support)
+ return false;
+
+ return true;
+}
+
static void intel_setup_outputs(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -11096,7 +11933,7 @@ static void intel_setup_outputs(struct drm_device *dev)
intel_lvds_init(dev);
- if (!IS_ULT(dev) && !IS_CHERRYVIEW(dev) && dev_priv->vbt.int_crt_support)
+ if (intel_crt_present(dev))
intel_crt_init(dev);
if (HAS_DDI(dev)) {
@@ -11211,6 +12048,8 @@ static void intel_setup_outputs(struct drm_device *dev)
if (SUPPORTS_TV(dev))
intel_tv_init(dev);
+ intel_edp_psr_init(dev);
+
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
encoder->base.possible_crtcs = encoder->crtc_mask;
encoder->base.possible_clones =
@@ -11224,11 +12063,14 @@ static void intel_setup_outputs(struct drm_device *dev)
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
+ struct drm_device *dev = fb->dev;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
drm_framebuffer_cleanup(fb);
+ mutex_lock(&dev->struct_mutex);
WARN_ON(!intel_fb->obj->framebuffer_references--);
- drm_gem_object_unreference_unlocked(&intel_fb->obj->base);
+ drm_gem_object_unreference(&intel_fb->obj->base);
+ mutex_unlock(&dev->struct_mutex);
kfree(intel_fb);
}
@@ -11413,7 +12255,7 @@ static void intel_init_display(struct drm_device *dev)
dev_priv->display.crtc_mode_set = haswell_crtc_mode_set;
dev_priv->display.crtc_enable = haswell_crtc_enable;
dev_priv->display.crtc_disable = haswell_crtc_disable;
- dev_priv->display.off = haswell_crtc_off;
+ dev_priv->display.off = ironlake_crtc_off;
dev_priv->display.update_primary_plane =
ironlake_update_primary_plane;
} else if (HAS_PCH_SPLIT(dev)) {
@@ -11566,6 +12408,14 @@ static void quirk_invert_brightness(struct drm_device *dev)
DRM_INFO("applying inverted panel brightness quirk\n");
}
+/* Some VBT's incorrectly indicate no backlight is present */
+static void quirk_backlight_present(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT;
+ DRM_INFO("applying backlight present quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -11634,6 +12484,15 @@ static struct intel_quirk intel_quirks[] = {
/* Acer Aspire 5336 */
{ 0x2a42, 0x1025, 0x048a, quirk_invert_brightness },
+
+ /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
+ { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
+
+ /* Toshiba CB35 Chromebook (Celeron 2955U) */
+ { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
+
+ /* HP Chromebook 14 (Celeron 2955U) */
+ { 0x0a06, 0x103c, 0x21ed, quirk_backlight_present },
};
static void intel_init_quirks(struct drm_device *dev)
@@ -11680,6 +12539,9 @@ void intel_modeset_init_hw(struct drm_device *dev)
{
intel_prepare_ddi(dev);
+ if (IS_VALLEYVIEW(dev))
+ vlv_update_cdclk(dev);
+
intel_init_clock_gating(dev);
intel_reset_dpio(dev);
@@ -11756,7 +12618,6 @@ void intel_modeset_init(struct drm_device *dev)
intel_init_dpio(dev);
intel_reset_dpio(dev);
- intel_cpu_pll_init(dev);
intel_shared_dpll_init(dev);
/* Just disable it once at startup */
@@ -11872,6 +12733,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
* ... */
plane = crtc->plane;
crtc->plane = !plane;
+ crtc->primary_enabled = true;
dev_priv->display.crtc_disable(&crtc->base);
crtc->plane = plane;
@@ -11981,6 +12843,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
encoder->base.base.id,
encoder->base.name);
encoder->disable(encoder);
+ if (encoder->post_disable)
+ encoder->post_disable(encoder);
}
encoder->base.crtc = NULL;
encoder->connectors_active = false;
@@ -12065,10 +12929,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
crtc->active ? "enabled" : "disabled");
}
- /* FIXME: Smash this into the new shared dpll infrastructure. */
- if (HAS_DDI(dev))
- intel_ddi_setup_hw_pll_state(dev);
-
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
@@ -12082,6 +12942,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n",
pll->name, pll->refcount, pll->on);
+
+ if (pll->refcount)
+ intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
@@ -12199,7 +13062,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
void intel_modeset_gem_init(struct drm_device *dev)
{
struct drm_crtc *c;
- struct intel_framebuffer *fb;
+ struct drm_i915_gem_object *obj;
mutex_lock(&dev->struct_mutex);
intel_init_gt_powersave(dev);
@@ -12216,11 +13079,11 @@ void intel_modeset_gem_init(struct drm_device *dev)
*/
mutex_lock(&dev->struct_mutex);
for_each_crtc(dev, c) {
- if (!c->primary->fb)
+ obj = intel_fb_obj(c->primary->fb);
+ if (obj == NULL)
continue;
- fb = to_intel_framebuffer(c->primary->fb);
- if (intel_pin_and_fence_fb_obj(dev, fb->obj, NULL)) {
+ if (intel_pin_and_fence_fb_obj(dev, obj, NULL)) {
DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe);
drm_framebuffer_unreference(c->primary->fb);
@@ -12235,13 +13098,12 @@ void intel_connector_unregister(struct intel_connector *intel_connector)
struct drm_connector *connector = &intel_connector->base;
intel_panel_destroy_backlight(connector);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
}
void intel_modeset_cleanup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc;
struct drm_connector *connector;
/*
@@ -12251,6 +13113,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
*/
drm_irq_uninstall(dev);
cancel_work_sync(&dev_priv->hotplug_work);
+ dev_priv->pm._irqs_disabled = true;
+
/*
* Due to the hpd irq storm handling the hotplug work can re-arm the
* poll handlers. Hence disable polling after hpd handling is shut down.
@@ -12261,14 +13125,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
intel_unregister_dsm_handler();
- for_each_crtc(dev, crtc) {
- /* Skip inactive CRTCs */
- if (!crtc->primary->fb)
- continue;
-
- intel_increase_pllclock(crtc);
- }
-
intel_disable_fbc(dev);
intel_disable_gt_powersave(dev);
@@ -12436,7 +13292,7 @@ intel_display_capture_error_state(struct drm_device *dev)
error->pipe[i].source = I915_READ(PIPESRC(i));
- if (!HAS_PCH_SPLIT(dev))
+ if (HAS_GMCH_DISPLAY(dev))
error->pipe[i].stat = I915_READ(PIPESTAT(i));
}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 52fda950fd2a..ee3942f0b068 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -28,6 +28,8 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/export.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
@@ -112,7 +114,7 @@ static void intel_dp_link_down(struct intel_dp *intel_dp);
static bool _edp_panel_vdd_on(struct intel_dp *intel_dp);
static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
-static int
+int
intel_dp_max_link_bw(struct intel_dp *intel_dp)
{
int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE];
@@ -336,6 +338,37 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp)
return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
}
+/* Reboot notifier handler to shutdown panel power to guarantee T12 timing
+ This function only applicable when panel PM state is not to be tracked */
+static int edp_notify_handler(struct notifier_block *this, unsigned long code,
+ void *unused)
+{
+ struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp),
+ edp_notifier);
+ struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 pp_div;
+ u32 pp_ctrl_reg, pp_div_reg;
+ enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+
+ if (!is_edp(intel_dp) || code != SYS_RESTART)
+ return 0;
+
+ if (IS_VALLEYVIEW(dev)) {
+ pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
+ pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
+ pp_div = I915_READ(pp_div_reg);
+ pp_div &= PP_REFERENCE_DIVIDER_MASK;
+
+ /* 0x1F write to PP_DIV_REG sets max cycle delay */
+ I915_WRITE(pp_div_reg, pp_div | 0x1F);
+ I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF);
+ msleep(intel_dp->panel_power_cycle_delay);
+ }
+
+ return 0;
+}
+
static bool edp_have_panel_power(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
@@ -740,12 +773,29 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
{
struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
- sysfs_remove_link(&intel_connector->base.kdev->kobj,
- intel_dp->aux.ddc.dev.kobj.name);
+ if (!intel_connector->mst_port)
+ sysfs_remove_link(&intel_connector->base.kdev->kobj,
+ intel_dp->aux.ddc.dev.kobj.name);
intel_connector_unregister(intel_connector);
}
static void
+hsw_dp_set_ddi_pll_sel(struct intel_crtc_config *pipe_config, int link_bw)
+{
+ switch (link_bw) {
+ case DP_LINK_BW_1_62:
+ pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
+ break;
+ case DP_LINK_BW_2_7:
+ pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
+ break;
+ case DP_LINK_BW_5_4:
+ pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
+ break;
+ }
+}
+
+static void
intel_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config, int link_bw)
{
@@ -756,8 +806,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
if (IS_G4X(dev)) {
divisor = gen4_dpll;
count = ARRAY_SIZE(gen4_dpll);
- } else if (IS_HASWELL(dev)) {
- /* Haswell has special-purpose DP DDI clocks. */
} else if (HAS_PCH_SPLIT(dev)) {
divisor = pch_dpll;
count = ARRAY_SIZE(pch_dpll);
@@ -873,8 +921,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
bpp);
- for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) {
- for (clock = min_clock; clock <= max_clock; clock++) {
+ for (clock = min_clock; clock <= max_clock; clock++) {
+ for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) {
link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
link_avail = intel_dp_max_data_rate(link_clock,
lane_count);
@@ -928,7 +976,10 @@ found:
&pipe_config->dp_m2_n2);
}
- intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
+ if (HAS_DDI(dev))
+ hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
+ else
+ intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
return true;
}
@@ -1234,6 +1285,19 @@ static void edp_panel_vdd_work(struct work_struct *__work)
drm_modeset_unlock(&dev->mode_config.connection_mutex);
}
+static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
+{
+ unsigned long delay;
+
+ /*
+ * Queue the timer to fire a long time from now (relative to the power
+ * down delay) to keep the panel power up across a sequence of
+ * operations.
+ */
+ delay = msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5);
+ schedule_delayed_work(&intel_dp->panel_vdd_work, delay);
+}
+
static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
{
if (!is_edp(intel_dp))
@@ -1243,17 +1307,10 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
intel_dp->want_panel_vdd = false;
- if (sync) {
+ if (sync)
edp_panel_vdd_off_sync(intel_dp);
- } else {
- /*
- * Queue the timer to fire a long
- * time from now (relative to the power down delay)
- * to keep the panel power up across a sequence of operations
- */
- schedule_delayed_work(&intel_dp->panel_vdd_work,
- msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
- }
+ else
+ edp_panel_vdd_schedule_off(intel_dp);
}
void intel_edp_panel_on(struct intel_dp *intel_dp)
@@ -1316,8 +1373,6 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
DRM_DEBUG_KMS("Turn eDP power off\n");
- edp_wait_backlight_off(intel_dp);
-
WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
pp = ironlake_get_pp_control(intel_dp);
@@ -1353,6 +1408,9 @@ void intel_edp_backlight_on(struct intel_dp *intel_dp)
return;
DRM_DEBUG_KMS("\n");
+
+ intel_panel_enable_backlight(intel_dp->attached_connector);
+
/*
* If we enable the backlight right away following a panel power
* on, we may see slight flicker as the panel syncs with the eDP
@@ -1367,8 +1425,6 @@ void intel_edp_backlight_on(struct intel_dp *intel_dp)
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
-
- intel_panel_enable_backlight(intel_dp->attached_connector);
}
void intel_edp_backlight_off(struct intel_dp *intel_dp)
@@ -1381,8 +1437,6 @@ void intel_edp_backlight_off(struct intel_dp *intel_dp)
if (!is_edp(intel_dp))
return;
- intel_panel_disable_backlight(intel_dp->attached_connector);
-
DRM_DEBUG_KMS("\n");
pp = ironlake_get_pp_control(intel_dp);
pp &= ~EDP_BLC_ENABLE;
@@ -1392,6 +1446,10 @@ void intel_edp_backlight_off(struct intel_dp *intel_dp)
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
intel_dp->last_backlight_off = jiffies;
+
+ edp_wait_backlight_off(intel_dp);
+
+ intel_panel_disable_backlight(intel_dp->attached_connector);
}
static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
@@ -1613,11 +1671,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
}
}
-static bool is_edp_psr(struct drm_device *dev)
+static bool is_edp_psr(struct intel_dp *intel_dp)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- return dev_priv->psr.sink_support;
+ return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
}
static bool intel_edp_is_psr_enabled(struct drm_device *dev)
@@ -1665,9 +1721,6 @@ static void intel_edp_psr_setup(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
struct edp_vsc_psr psr_vsc;
- if (intel_dp->psr_setup_done)
- return;
-
/* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */
memset(&psr_vsc, 0, sizeof(psr_vsc));
psr_vsc.sdp_header.HB0 = 0;
@@ -1679,22 +1732,25 @@ static void intel_edp_psr_setup(struct intel_dp *intel_dp)
/* Avoid continuous PSR exit by masking memup and hpd */
I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
-
- intel_dp->psr_setup_done = true;
}
static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp)
{
- struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t aux_clock_divider;
int precharge = 0x3;
int msg_size = 5; /* Header(4) + Message(1) */
+ bool only_standby = false;
aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0);
+ if (IS_BROADWELL(dev) && dig_port->port != PORT_A)
+ only_standby = true;
+
/* Enable PSR in sink */
- if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT)
+ if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby)
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
DP_PSR_ENABLE & ~DP_PSR_MAIN_LINK_ACTIVE);
else
@@ -1713,18 +1769,24 @@ static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp)
static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
{
- struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t max_sleep_time = 0x1f;
uint32_t idle_frames = 1;
uint32_t val = 0x0;
const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
+ bool only_standby = false;
- if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) {
+ if (IS_BROADWELL(dev) && dig_port->port != PORT_A)
+ only_standby = true;
+
+ if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT || only_standby) {
val |= EDP_PSR_LINK_STANDBY;
val |= EDP_PSR_TP2_TP3_TIME_0us;
val |= EDP_PSR_TP1_TIME_0us;
val |= EDP_PSR_SKIP_AUX_EXIT;
+ val |= IS_BROADWELL(dev) ? BDW_PSR_SINGLE_FRAME : 0;
} else
val |= EDP_PSR_LINK_DISABLE;
@@ -1742,18 +1804,14 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dig_port->base.base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->primary->fb)->obj;
- struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
- dev_priv->psr.source_ok = false;
+ lockdep_assert_held(&dev_priv->psr.lock);
+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+ WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
- if (!HAS_PSR(dev)) {
- DRM_DEBUG_KMS("PSR not supported on this platform\n");
- return false;
- }
+ dev_priv->psr.source_ok = false;
- if ((intel_encoder->type != INTEL_OUTPUT_EDP) ||
- (dig_port->port != PORT_A)) {
+ if (IS_HASWELL(dev) && dig_port->port != PORT_A) {
DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n");
return false;
}
@@ -1763,29 +1821,9 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
return false;
}
- crtc = dig_port->base.base.crtc;
- if (crtc == NULL) {
- DRM_DEBUG_KMS("crtc not active for PSR\n");
- return false;
- }
-
- intel_crtc = to_intel_crtc(crtc);
- if (!intel_crtc_active(crtc)) {
- DRM_DEBUG_KMS("crtc not active for PSR\n");
- return false;
- }
-
- obj = to_intel_framebuffer(crtc->primary->fb)->obj;
- if (obj->tiling_mode != I915_TILING_X ||
- obj->fence_reg == I915_FENCE_REG_NONE) {
- DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
- return false;
- }
-
- if (I915_READ(SPRCTL(intel_crtc->pipe)) & SPRITE_ENABLE) {
- DRM_DEBUG_KMS("PSR condition failed: Sprite is Enabled\n");
- return false;
- }
+ /* Below limitations aren't valid for Broadwell */
+ if (IS_BROADWELL(dev))
+ goto out;
if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) &
S3D_ENABLE) {
@@ -1798,35 +1836,60 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
return false;
}
+ out:
dev_priv->psr.source_ok = true;
return true;
}
static void intel_edp_psr_do_enable(struct intel_dp *intel_dp)
{
- struct drm_device *dev = intel_dp_to_dev(intel_dp);
-
- if (!intel_edp_psr_match_conditions(intel_dp) ||
- intel_edp_is_psr_enabled(dev))
- return;
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
- /* Setup PSR once */
- intel_edp_psr_setup(intel_dp);
+ WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
+ WARN_ON(dev_priv->psr.active);
+ lockdep_assert_held(&dev_priv->psr.lock);
/* Enable PSR on the panel */
intel_edp_psr_enable_sink(intel_dp);
/* Enable PSR on the host */
intel_edp_psr_enable_source(intel_dp);
+
+ dev_priv->psr.active = true;
}
void intel_edp_psr_enable(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (!HAS_PSR(dev)) {
+ DRM_DEBUG_KMS("PSR not supported on this platform\n");
+ return;
+ }
+
+ if (!is_edp_psr(intel_dp)) {
+ DRM_DEBUG_KMS("PSR not supported by this panel\n");
+ return;
+ }
- if (intel_edp_psr_match_conditions(intel_dp) &&
- !intel_edp_is_psr_enabled(dev))
- intel_edp_psr_do_enable(intel_dp);
+ mutex_lock(&dev_priv->psr.lock);
+ if (dev_priv->psr.enabled) {
+ DRM_DEBUG_KMS("PSR already in use\n");
+ mutex_unlock(&dev_priv->psr.lock);
+ return;
+ }
+
+ dev_priv->psr.busy_frontbuffer_bits = 0;
+
+ /* Setup PSR once */
+ intel_edp_psr_setup(intel_dp);
+
+ if (intel_edp_psr_match_conditions(intel_dp))
+ dev_priv->psr.enabled = intel_dp;
+ mutex_unlock(&dev_priv->psr.lock);
}
void intel_edp_psr_disable(struct intel_dp *intel_dp)
@@ -1834,36 +1897,136 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!intel_edp_is_psr_enabled(dev))
+ mutex_lock(&dev_priv->psr.lock);
+ if (!dev_priv->psr.enabled) {
+ mutex_unlock(&dev_priv->psr.lock);
return;
+ }
+
+ if (dev_priv->psr.active) {
+ I915_WRITE(EDP_PSR_CTL(dev),
+ I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE);
+
+ /* Wait till PSR is idle */
+ if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) &
+ EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
+ DRM_ERROR("Timed out waiting for PSR Idle State\n");
+
+ dev_priv->psr.active = false;
+ } else {
+ WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
+ }
- I915_WRITE(EDP_PSR_CTL(dev),
- I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE);
+ dev_priv->psr.enabled = NULL;
+ mutex_unlock(&dev_priv->psr.lock);
- /* Wait till PSR is idle */
- if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) &
- EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
- DRM_ERROR("Timed out waiting for PSR Idle State\n");
+ cancel_delayed_work_sync(&dev_priv->psr.work);
}
-void intel_edp_psr_update(struct drm_device *dev)
+static void intel_edp_psr_work(struct work_struct *work)
{
- struct intel_encoder *encoder;
- struct intel_dp *intel_dp = NULL;
+ struct drm_i915_private *dev_priv =
+ container_of(work, typeof(*dev_priv), psr.work.work);
+ struct intel_dp *intel_dp = dev_priv->psr.enabled;
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head)
- if (encoder->type == INTEL_OUTPUT_EDP) {
- intel_dp = enc_to_intel_dp(&encoder->base);
+ mutex_lock(&dev_priv->psr.lock);
+ intel_dp = dev_priv->psr.enabled;
- if (!is_edp_psr(dev))
- return;
+ if (!intel_dp)
+ goto unlock;
- if (!intel_edp_psr_match_conditions(intel_dp))
- intel_edp_psr_disable(intel_dp);
- else
- if (!intel_edp_is_psr_enabled(dev))
- intel_edp_psr_do_enable(intel_dp);
- }
+ /*
+ * The delayed work can race with an invalidate hence we need to
+ * recheck. Since psr_flush first clears this and then reschedules we
+ * won't ever miss a flush when bailing out here.
+ */
+ if (dev_priv->psr.busy_frontbuffer_bits)
+ goto unlock;
+
+ intel_edp_psr_do_enable(intel_dp);
+unlock:
+ mutex_unlock(&dev_priv->psr.lock);
+}
+
+static void intel_edp_psr_do_exit(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->psr.active) {
+ u32 val = I915_READ(EDP_PSR_CTL(dev));
+
+ WARN_ON(!(val & EDP_PSR_ENABLE));
+
+ I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE);
+
+ dev_priv->psr.active = false;
+ }
+
+}
+
+void intel_edp_psr_invalidate(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc;
+ enum pipe pipe;
+
+ mutex_lock(&dev_priv->psr.lock);
+ if (!dev_priv->psr.enabled) {
+ mutex_unlock(&dev_priv->psr.lock);
+ return;
+ }
+
+ crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+ pipe = to_intel_crtc(crtc)->pipe;
+
+ intel_edp_psr_do_exit(dev);
+
+ frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(pipe);
+
+ dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits;
+ mutex_unlock(&dev_priv->psr.lock);
+}
+
+void intel_edp_psr_flush(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc;
+ enum pipe pipe;
+
+ mutex_lock(&dev_priv->psr.lock);
+ if (!dev_priv->psr.enabled) {
+ mutex_unlock(&dev_priv->psr.lock);
+ return;
+ }
+
+ crtc = dp_to_dig_port(dev_priv->psr.enabled)->base.base.crtc;
+ pipe = to_intel_crtc(crtc)->pipe;
+ dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits;
+
+ /*
+ * On Haswell sprite plane updates don't result in a psr invalidating
+ * signal in the hardware. Which means we need to manually fake this in
+ * software for all flushes, not just when we've seen a preceding
+ * invalidation through frontbuffer rendering.
+ */
+ if (IS_HASWELL(dev) &&
+ (frontbuffer_bits & INTEL_FRONTBUFFER_SPRITE(pipe)))
+ intel_edp_psr_do_exit(dev);
+
+ if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits)
+ schedule_delayed_work(&dev_priv->psr.work,
+ msecs_to_jiffies(100));
+ mutex_unlock(&dev_priv->psr.lock);
+}
+
+void intel_edp_psr_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ INIT_DELAYED_WORK(&dev_priv->psr.work, intel_edp_psr_work);
+ mutex_init(&dev_priv->psr.lock);
}
static void intel_disable_dp(struct intel_encoder *encoder)
@@ -2119,6 +2282,70 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
vlv_wait_port_ready(dev_priv, dport);
}
+static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
+{
+ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc =
+ to_intel_crtc(encoder->base.crtc);
+ enum dpio_channel ch = vlv_dport_to_channel(dport);
+ enum pipe pipe = intel_crtc->pipe;
+ u32 val;
+
+ mutex_lock(&dev_priv->dpio_lock);
+
+ /* program left/right clock distribution */
+ if (pipe != PIPE_B) {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+ val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+ if (ch == DPIO_CH0)
+ val |= CHV_BUFLEFTENA1_FORCE;
+ if (ch == DPIO_CH1)
+ val |= CHV_BUFRIGHTENA1_FORCE;
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+ } else {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+ val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+ if (ch == DPIO_CH0)
+ val |= CHV_BUFLEFTENA2_FORCE;
+ if (ch == DPIO_CH1)
+ val |= CHV_BUFRIGHTENA2_FORCE;
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+ }
+
+ /* program clock channel usage */
+ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
+ val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+ if (pipe != PIPE_B)
+ val &= ~CHV_PCS_USEDCLKCHANNEL;
+ else
+ val |= CHV_PCS_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
+
+ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
+ val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+ if (pipe != PIPE_B)
+ val &= ~CHV_PCS_USEDCLKCHANNEL;
+ else
+ val |= CHV_PCS_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
+
+ /*
+ * This a a bit weird since generally CL
+ * matches the pipe, but here we need to
+ * pick the CL based on the port.
+ */
+ val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
+ if (pipe != PIPE_B)
+ val &= ~CHV_CMN_USEDCLKCHANNEL;
+ else
+ val |= CHV_CMN_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
+
+ mutex_unlock(&dev_priv->dpio_lock);
+}
+
/*
* Native read with retry for link status and receiver capability reads for
* cases where the sink may still be asleep.
@@ -2156,18 +2383,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
}
-/*
- * These are source-specific values; current Intel hardware supports
- * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
- */
-
+/* These are source-specific values. */
static uint8_t
intel_dp_voltage_max(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
enum port port = dp_to_dig_port(intel_dp)->port;
- if (IS_VALLEYVIEW(dev) || IS_BROADWELL(dev))
+ if (IS_VALLEYVIEW(dev))
return DP_TRAIN_VOLTAGE_SWING_1200;
else if (IS_GEN7(dev) && port == PORT_A)
return DP_TRAIN_VOLTAGE_SWING_800;
@@ -2183,18 +2406,7 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
enum port port = dp_to_dig_port(intel_dp)->port;
- if (IS_BROADWELL(dev)) {
- switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
- case DP_TRAIN_VOLTAGE_SWING_400:
- case DP_TRAIN_VOLTAGE_SWING_600:
- return DP_TRAIN_PRE_EMPHASIS_6;
- case DP_TRAIN_VOLTAGE_SWING_800:
- return DP_TRAIN_PRE_EMPHASIS_3_5;
- case DP_TRAIN_VOLTAGE_SWING_1200:
- default:
- return DP_TRAIN_PRE_EMPHASIS_0;
- }
- } else if (IS_HASWELL(dev)) {
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
case DP_TRAIN_VOLTAGE_SWING_400:
return DP_TRAIN_PRE_EMPHASIS_9_5;
@@ -2666,41 +2878,6 @@ intel_hsw_signal_levels(uint8_t train_set)
}
}
-static uint32_t
-intel_bdw_signal_levels(uint8_t train_set)
-{
- int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
- DP_TRAIN_PRE_EMPHASIS_MASK);
- switch (signal_levels) {
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_400MV_3_5DB_BDW; /* Sel1 */
- case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
- return DDI_BUF_EMP_400MV_6DB_BDW; /* Sel2 */
-
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_600MV_0DB_BDW; /* Sel3 */
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_600MV_3_5DB_BDW; /* Sel4 */
- case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
- return DDI_BUF_EMP_600MV_6DB_BDW; /* Sel5 */
-
- case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_800MV_0DB_BDW; /* Sel6 */
- case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
- return DDI_BUF_EMP_800MV_3_5DB_BDW; /* Sel7 */
-
- case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
- return DDI_BUF_EMP_1200MV_0DB_BDW; /* Sel8 */
-
- default:
- DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
- "0x%x\n", signal_levels);
- return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */
- }
-}
-
/* Properly updates "DP" with the correct signal levels. */
static void
intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
@@ -2711,10 +2888,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
uint32_t signal_levels, mask;
uint8_t train_set = intel_dp->train_set[0];
- if (IS_BROADWELL(dev)) {
- signal_levels = intel_bdw_signal_levels(train_set);
- mask = DDI_BUF_EMP_MASK;
- } else if (IS_HASWELL(dev)) {
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
signal_levels = intel_hsw_signal_levels(train_set);
mask = DDI_BUF_EMP_MASK;
} else if (IS_CHERRYVIEW(dev)) {
@@ -3213,6 +3387,33 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
edp_panel_vdd_off(intel_dp, false);
}
+static bool
+intel_dp_probe_mst(struct intel_dp *intel_dp)
+{
+ u8 buf[1];
+
+ if (!intel_dp->can_mst)
+ return false;
+
+ if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
+ return false;
+
+ _edp_panel_vdd_on(intel_dp);
+ if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) {
+ if (buf[0] & DP_MST_CAP) {
+ DRM_DEBUG_KMS("Sink is MST capable\n");
+ intel_dp->is_mst = true;
+ } else {
+ DRM_DEBUG_KMS("Sink is not MST capable\n");
+ intel_dp->is_mst = false;
+ }
+ }
+ edp_panel_vdd_off(intel_dp, false);
+
+ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+ return intel_dp->is_mst;
+}
+
int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -3250,6 +3451,20 @@ intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
sink_irq_vector, 1) == 1;
}
+static bool
+intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
+{
+ int ret;
+
+ ret = intel_dp_dpcd_read_wake(&intel_dp->aux,
+ DP_SINK_COUNT_ESI,
+ sink_irq_vector, 14);
+ if (ret != 14)
+ return false;
+
+ return true;
+}
+
static void
intel_dp_handle_test_request(struct intel_dp *intel_dp)
{
@@ -3257,6 +3472,63 @@ intel_dp_handle_test_request(struct intel_dp *intel_dp)
drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_RESPONSE, DP_TEST_NAK);
}
+static int
+intel_dp_check_mst_status(struct intel_dp *intel_dp)
+{
+ bool bret;
+
+ if (intel_dp->is_mst) {
+ u8 esi[16] = { 0 };
+ int ret = 0;
+ int retry;
+ bool handled;
+ bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
+go_again:
+ if (bret == true) {
+
+ /* check link status - esi[10] = 0x200c */
+ if (intel_dp->active_mst_links && !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
+ DRM_DEBUG_KMS("channel EQ not ok, retraining\n");
+ intel_dp_start_link_train(intel_dp);
+ intel_dp_complete_link_train(intel_dp);
+ intel_dp_stop_link_train(intel_dp);
+ }
+
+ DRM_DEBUG_KMS("got esi %02x %02x %02x\n", esi[0], esi[1], esi[2]);
+ ret = drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled);
+
+ if (handled) {
+ for (retry = 0; retry < 3; retry++) {
+ int wret;
+ wret = drm_dp_dpcd_write(&intel_dp->aux,
+ DP_SINK_COUNT_ESI+1,
+ &esi[1], 3);
+ if (wret == 3) {
+ break;
+ }
+ }
+
+ bret = intel_dp_get_sink_irq_esi(intel_dp, esi);
+ if (bret == true) {
+ DRM_DEBUG_KMS("got esi2 %02x %02x %02x\n", esi[0], esi[1], esi[2]);
+ goto go_again;
+ }
+ } else
+ ret = 0;
+
+ return ret;
+ } else {
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ DRM_DEBUG_KMS("failed to get ESI - device may have failed\n");
+ intel_dp->is_mst = false;
+ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+ /* send a hotplug event */
+ drm_kms_helper_hotplug_event(intel_dig_port->base.base.dev);
+ }
+ }
+ return -EINVAL;
+}
+
/*
* According to DP spec
* 5.1.2:
@@ -3265,15 +3537,16 @@ intel_dp_handle_test_request(struct intel_dp *intel_dp)
* 3. Use Link Training from 2.5.3.3 and 3.5.1.3
* 4. Check link status on receipt of hot-plug interrupt
*/
-
void
intel_dp_check_link_status(struct intel_dp *intel_dp)
{
+ struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
u8 sink_irq_vector;
u8 link_status[DP_LINK_STATUS_SIZE];
- /* FIXME: This access isn't protected by any locks. */
+ WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
if (!intel_encoder->connectors_active)
return;
@@ -3485,8 +3758,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
enum drm_connector_status status;
enum intel_display_power_domain power_domain;
struct edid *edid = NULL;
-
- intel_runtime_pm_get(dev_priv);
+ bool ret;
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
@@ -3494,6 +3766,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
+ if (intel_dp->is_mst) {
+ /* MST devices are disconnected from a monitor POV */
+ if (intel_encoder->type != INTEL_OUTPUT_EDP)
+ intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+ status = connector_status_disconnected;
+ goto out;
+ }
+
intel_dp->has_audio = false;
if (HAS_PCH_SPLIT(dev))
@@ -3506,6 +3786,16 @@ intel_dp_detect(struct drm_connector *connector, bool force)
intel_dp_probe_oui(intel_dp);
+ ret = intel_dp_probe_mst(intel_dp);
+ if (ret) {
+ /* if we are in MST mode then this connector
+ won't appear connected or have anything with EDID on it */
+ if (intel_encoder->type != INTEL_OUTPUT_EDP)
+ intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
+ status = connector_status_disconnected;
+ goto out;
+ }
+
if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
} else {
@@ -3522,9 +3812,6 @@ intel_dp_detect(struct drm_connector *connector, bool force)
out:
intel_display_power_put(dev_priv, power_domain);
-
- intel_runtime_pm_put(dev_priv);
-
return status;
}
@@ -3701,16 +3988,26 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
struct drm_device *dev = intel_dp_to_dev(intel_dp);
drm_dp_aux_unregister(&intel_dp->aux);
+ intel_dp_mst_encoder_cleanup(intel_dig_port);
drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
edp_panel_vdd_off_sync(intel_dp);
drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ if (intel_dp->edp_notifier.notifier_call) {
+ unregister_reboot_notifier(&intel_dp->edp_notifier);
+ intel_dp->edp_notifier.notifier_call = NULL;
+ }
}
kfree(intel_dig_port);
}
+static void intel_dp_encoder_reset(struct drm_encoder *encoder)
+{
+ intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
+}
+
static const struct drm_connector_funcs intel_dp_connector_funcs = {
.dpms = intel_connector_dpms,
.detect = intel_dp_detect,
@@ -3726,15 +4023,68 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
};
static const struct drm_encoder_funcs intel_dp_enc_funcs = {
+ .reset = intel_dp_encoder_reset,
.destroy = intel_dp_encoder_destroy,
};
-static void
+void
intel_dp_hot_plug(struct intel_encoder *intel_encoder)
{
- struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
+ return;
+}
+
+bool
+intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
+{
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+ if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
+ intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
+
+ DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port,
+ long_hpd ? "long" : "short");
+
+ if (long_hpd) {
+ if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
+ goto mst_fail;
+
+ if (!intel_dp_get_dpcd(intel_dp)) {
+ goto mst_fail;
+ }
+
+ intel_dp_probe_oui(intel_dp);
- intel_dp_check_link_status(intel_dp);
+ if (!intel_dp_probe_mst(intel_dp))
+ goto mst_fail;
+
+ } else {
+ if (intel_dp->is_mst) {
+ ret = intel_dp_check_mst_status(intel_dp);
+ if (ret == -EINVAL)
+ goto mst_fail;
+ }
+
+ if (!intel_dp->is_mst) {
+ /*
+ * we'll check the link status via the normal hot plug path later -
+ * but for short hpds we should check it now
+ */
+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+ intel_dp_check_link_status(intel_dp);
+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
+ }
+ }
+ return false;
+mst_fail:
+ /* if we were in MST mode, and device is not there get out of MST mode */
+ if (intel_dp->is_mst) {
+ DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n", intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+ intel_dp->is_mst = false;
+ drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+ }
+ return true;
}
/* Return which DP Port should be selected for Transcoder DP control */
@@ -3785,7 +4135,7 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port)
return false;
}
-static void
+void
intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
@@ -3998,6 +4348,11 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
return;
}
+ /*
+ * FIXME: This needs proper synchronization with psr state. But really
+ * hard to tell without seeing the user of this function of this code.
+ * Check locking and ordering once that lands.
+ */
if (INTEL_INFO(dev)->gen < 8 && intel_edp_is_psr_enabled(dev)) {
DRM_DEBUG_KMS("DRRS is disabled as PSR is enabled\n");
return;
@@ -4101,6 +4456,32 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
return downclock_mode;
}
+void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
+{
+ struct drm_device *dev = intel_encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_dp *intel_dp;
+ enum intel_display_power_domain power_domain;
+
+ if (intel_encoder->type != INTEL_OUTPUT_EDP)
+ return;
+
+ intel_dp = enc_to_intel_dp(&intel_encoder->base);
+ if (!edp_have_panel_vdd(intel_dp))
+ return;
+ /*
+ * The VDD bit needs a power domain reference, so if the bit is
+ * already enabled when we boot or resume, grab this reference and
+ * schedule a vdd off, so we don't hold on to the reference
+ * indefinitely.
+ */
+ DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
+ power_domain = intel_display_port_power_domain(intel_encoder);
+ intel_display_power_get(dev_priv, power_domain);
+
+ edp_panel_vdd_schedule_off(intel_dp);
+}
+
static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct intel_connector *intel_connector,
struct edp_power_seq *power_seq)
@@ -4121,13 +4502,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
if (!is_edp(intel_dp))
return true;
- /* The VDD bit needs a power domain reference, so if the bit is already
- * enabled when we boot, grab this reference. */
- if (edp_have_panel_vdd(intel_dp)) {
- enum intel_display_power_domain power_domain;
- power_domain = intel_display_port_power_domain(intel_encoder);
- intel_display_power_get(dev_priv, power_domain);
- }
+ intel_edp_panel_vdd_sanitize(intel_encoder);
/* Cache DPCD and EDID for edp. */
intel_edp_panel_vdd_on(intel_dp);
@@ -4184,6 +4559,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
}
mutex_unlock(&dev->mode_config.mutex);
+ if (IS_VALLEYVIEW(dev)) {
+ intel_dp->edp_notifier.notifier_call = edp_notify_handler;
+ register_reboot_notifier(&intel_dp->edp_notifier);
+ }
+
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
intel_panel_setup_backlight(connector);
@@ -4246,7 +4626,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
edp_panel_vdd_work);
intel_connector_attach_encoder(intel_connector, intel_encoder);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
if (HAS_DDI(dev))
intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
@@ -4279,7 +4659,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
intel_dp_aux_init(intel_dp, intel_connector);
- intel_dp->psr_setup_done = false;
+ /* init MST on ports that can support it */
+ if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ if (port == PORT_B || port == PORT_C || port == PORT_D) {
+ intel_dp_mst_encoder_init(intel_dig_port, intel_connector->base.base.id);
+ }
+ }
if (!intel_edp_init_connector(intel_dp, intel_connector, &power_seq)) {
drm_dp_aux_unregister(&intel_dp->aux);
@@ -4289,7 +4674,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
edp_panel_vdd_off_sync(intel_dp);
drm_modeset_unlock(&dev->mode_config.connection_mutex);
}
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
return false;
}
@@ -4311,6 +4696,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
void
intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
{
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port;
struct intel_encoder *intel_encoder;
struct drm_encoder *encoder;
@@ -4337,6 +4723,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
intel_encoder->get_hw_state = intel_dp_get_hw_state;
intel_encoder->get_config = intel_dp_get_config;
if (IS_CHERRYVIEW(dev)) {
+ intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
intel_encoder->pre_enable = chv_pre_enable_dp;
intel_encoder->enable = vlv_enable_dp;
intel_encoder->post_disable = chv_post_disable_dp;
@@ -4366,9 +4753,55 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
intel_encoder->cloneable = 0;
intel_encoder->hot_plug = intel_dp_hot_plug;
+ intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
+ dev_priv->hpd_irq_port[port] = intel_dig_port;
+
if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
drm_encoder_cleanup(encoder);
kfree(intel_dig_port);
kfree(intel_connector);
}
}
+
+void intel_dp_mst_suspend(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ /* disable MST */
+ for (i = 0; i < I915_MAX_PORTS; i++) {
+ struct intel_digital_port *intel_dig_port = dev_priv->hpd_irq_port[i];
+ if (!intel_dig_port)
+ continue;
+
+ if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+ if (!intel_dig_port->dp.can_mst)
+ continue;
+ if (intel_dig_port->dp.is_mst)
+ drm_dp_mst_topology_mgr_suspend(&intel_dig_port->dp.mst_mgr);
+ }
+ }
+}
+
+void intel_dp_mst_resume(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ for (i = 0; i < I915_MAX_PORTS; i++) {
+ struct intel_digital_port *intel_dig_port = dev_priv->hpd_irq_port[i];
+ if (!intel_dig_port)
+ continue;
+ if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) {
+ int ret;
+
+ if (!intel_dig_port->dp.can_mst)
+ continue;
+
+ ret = drm_dp_mst_topology_mgr_resume(&intel_dig_port->dp.mst_mgr);
+ if (ret != 0) {
+ intel_dp_check_mst_status(&intel_dig_port->dp);
+ }
+ }
+ }
+}
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
new file mode 100644
index 000000000000..d9a7a7865f66
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ * 2014 Red Hat 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 (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 <drm/drmP.h>
+#include "i915_drv.h"
+#include "intel_drv.h"
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+
+static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = encoder->base.dev;
+ int bpp;
+ int lane_count, slots;
+ struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+ struct intel_connector *found = NULL, *intel_connector;
+ int mst_pbn;
+
+ pipe_config->dp_encoder_is_mst = true;
+ pipe_config->has_pch_encoder = false;
+ pipe_config->has_dp_encoder = true;
+ bpp = 24;
+ /*
+ * for MST we always configure max link bw - the spec doesn't
+ * seem to suggest we should do otherwise.
+ */
+ lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
+ intel_dp->link_bw = intel_dp_max_link_bw(intel_dp);
+ intel_dp->lane_count = lane_count;
+
+ pipe_config->pipe_bpp = 24;
+ pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
+
+ list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+ if (intel_connector->new_encoder == encoder) {
+ found = intel_connector;
+ break;
+ }
+ }
+
+ if (!found) {
+ DRM_ERROR("can't find connector\n");
+ return false;
+ }
+
+ mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp);
+
+ pipe_config->pbn = mst_pbn;
+ slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn);
+
+ intel_link_compute_m_n(bpp, lane_count,
+ adjusted_mode->crtc_clock,
+ pipe_config->port_clock,
+ &pipe_config->dp_m_n);
+
+ pipe_config->dp_m_n.tu = slots;
+ return true;
+
+}
+
+static void intel_mst_disable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ int ret;
+
+ DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+ drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, intel_mst->port);
+
+ ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+ if (ret) {
+ DRM_ERROR("failed to update payload %d\n", ret);
+ }
+}
+
+static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+ DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+ /* this can fail */
+ drm_dp_check_act_status(&intel_dp->mst_mgr);
+ /* and this can also fail */
+ drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+
+ drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->port);
+
+ intel_dp->active_mst_links--;
+ intel_mst->port = NULL;
+ if (intel_dp->active_mst_links == 0) {
+ intel_dig_port->base.post_disable(&intel_dig_port->base);
+ intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+ }
+}
+
+static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum port port = intel_dig_port->port;
+ int ret;
+ uint32_t temp;
+ struct intel_connector *found = NULL, *intel_connector;
+ int slots;
+ struct drm_crtc *crtc = encoder->base.crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+ list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+ if (intel_connector->new_encoder == encoder) {
+ found = intel_connector;
+ break;
+ }
+ }
+
+ if (!found) {
+ DRM_ERROR("can't find connector\n");
+ return;
+ }
+
+ DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+ intel_mst->port = found->port;
+
+ if (intel_dp->active_mst_links == 0) {
+ enum port port = intel_ddi_get_encoder_port(encoder);
+
+ I915_WRITE(PORT_CLK_SEL(port), intel_crtc->config.ddi_pll_sel);
+
+ intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
+
+ intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+
+
+ intel_dp_start_link_train(intel_dp);
+ intel_dp_complete_link_train(intel_dp);
+ intel_dp_stop_link_train(intel_dp);
+ }
+
+ ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
+ intel_mst->port, intel_crtc->config.pbn, &slots);
+ if (ret == false) {
+ DRM_ERROR("failed to allocate vcpi\n");
+ return;
+ }
+
+
+ intel_dp->active_mst_links++;
+ temp = I915_READ(DP_TP_STATUS(port));
+ I915_WRITE(DP_TP_STATUS(port), temp);
+
+ ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+}
+
+static void intel_mst_enable_dp(struct intel_encoder *encoder)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum port port = intel_dig_port->port;
+ int ret;
+
+ DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
+
+ if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_ACT_SENT),
+ 1))
+ DRM_ERROR("Timed out waiting for ACT sent\n");
+
+ ret = drm_dp_check_act_status(&intel_dp->mst_mgr);
+
+ ret = drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+}
+
+static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
+ enum pipe *pipe)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ *pipe = intel_mst->pipe;
+ if (intel_mst->port)
+ return true;
+ return false;
+}
+
+static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
+ struct intel_digital_port *intel_dig_port = intel_mst->primary;
+ struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+ u32 temp, flags = 0;
+
+ pipe_config->has_dp_encoder = true;
+
+ temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+ if (temp & TRANS_DDI_PHSYNC)
+ flags |= DRM_MODE_FLAG_PHSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NHSYNC;
+ if (temp & TRANS_DDI_PVSYNC)
+ flags |= DRM_MODE_FLAG_PVSYNC;
+ else
+ flags |= DRM_MODE_FLAG_NVSYNC;
+
+ switch (temp & TRANS_DDI_BPC_MASK) {
+ case TRANS_DDI_BPC_6:
+ pipe_config->pipe_bpp = 18;
+ break;
+ case TRANS_DDI_BPC_8:
+ pipe_config->pipe_bpp = 24;
+ break;
+ case TRANS_DDI_BPC_10:
+ pipe_config->pipe_bpp = 30;
+ break;
+ case TRANS_DDI_BPC_12:
+ pipe_config->pipe_bpp = 36;
+ break;
+ default:
+ break;
+ }
+ pipe_config->adjusted_mode.flags |= flags;
+ intel_dp_get_m_n(crtc, pipe_config);
+
+ intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
+}
+
+static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
+{
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_dp *intel_dp = intel_connector->mst_port;
+ struct edid *edid;
+ int ret;
+
+ edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
+ if (!edid)
+ return 0;
+
+ ret = intel_connector_update_modes(connector, edid);
+ kfree(edid);
+
+ return ret;
+}
+
+static enum drm_connector_status
+intel_mst_port_dp_detect(struct drm_connector *connector)
+{
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_dp *intel_dp = intel_connector->mst_port;
+
+ return drm_dp_mst_detect_port(&intel_dp->mst_mgr, intel_connector->port);
+}
+
+static enum drm_connector_status
+intel_dp_mst_detect(struct drm_connector *connector, bool force)
+{
+ enum drm_connector_status status;
+ status = intel_mst_port_dp_detect(connector);
+ return status;
+}
+
+static int
+intel_dp_mst_set_property(struct drm_connector *connector,
+ struct drm_property *property,
+ uint64_t val)
+{
+ return 0;
+}
+
+static void
+intel_dp_mst_connector_destroy(struct drm_connector *connector)
+{
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+
+ if (!IS_ERR_OR_NULL(intel_connector->edid))
+ kfree(intel_connector->edid);
+
+ drm_connector_cleanup(connector);
+ kfree(connector);
+}
+
+static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
+ .dpms = intel_connector_dpms,
+ .detect = intel_dp_mst_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = intel_dp_mst_set_property,
+ .destroy = intel_dp_mst_connector_destroy,
+};
+
+static int intel_dp_mst_get_modes(struct drm_connector *connector)
+{
+ return intel_dp_mst_get_ddc_modes(connector);
+}
+
+static enum drm_mode_status
+intel_dp_mst_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ /* TODO - validate mode against available PBN for link */
+ if (mode->clock < 10000)
+ return MODE_CLOCK_LOW;
+
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+ return MODE_H_ILLEGAL;
+
+ return MODE_OK;
+}
+
+static struct drm_encoder *intel_mst_best_encoder(struct drm_connector *connector)
+{
+ struct intel_connector *intel_connector = to_intel_connector(connector);
+ struct intel_dp *intel_dp = intel_connector->mst_port;
+ return &intel_dp->mst_encoders[0]->base.base;
+}
+
+static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = {
+ .get_modes = intel_dp_mst_get_modes,
+ .mode_valid = intel_dp_mst_mode_valid,
+ .best_encoder = intel_mst_best_encoder,
+};
+
+static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
+{
+ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
+
+ drm_encoder_cleanup(encoder);
+ kfree(intel_mst);
+}
+
+static const struct drm_encoder_funcs intel_dp_mst_enc_funcs = {
+ .destroy = intel_dp_mst_encoder_destroy,
+};
+
+static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
+{
+ if (connector->encoder) {
+ enum pipe pipe;
+ if (!connector->encoder->get_hw_state(connector->encoder, &pipe))
+ return false;
+ return true;
+ }
+ return false;
+}
+
+static void intel_connector_add_to_fbdev(struct intel_connector *connector)
+{
+#ifdef CONFIG_DRM_I915_FBDEV
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ 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_I915_FBDEV
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ 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, char *pathprop)
+{
+ struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ struct intel_connector *intel_connector;
+ struct drm_connector *connector;
+ int i;
+
+ intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
+ if (!intel_connector)
+ return NULL;
+
+ connector = &intel_connector->base;
+ drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort);
+ drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
+
+ intel_connector->unregister = intel_connector_unregister;
+ intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
+ intel_connector->mst_port = intel_dp;
+ intel_connector->port = port;
+
+ for (i = PIPE_A; i <= PIPE_C; i++) {
+ drm_mode_connector_attach_encoder(&intel_connector->base,
+ &intel_dp->mst_encoders[i]->base.base);
+ }
+ intel_dp_add_properties(intel_dp, connector);
+
+ drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
+ drm_mode_connector_set_path_property(connector, pathprop);
+ drm_reinit_primary_mode_group(dev);
+ mutex_lock(&dev->mode_config.mutex);
+ intel_connector_add_to_fbdev(intel_connector);
+ mutex_unlock(&dev->mode_config.mutex);
+ drm_connector_register(&intel_connector->base);
+ return 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;
+ /* need to nuke the connector */
+ mutex_lock(&dev->mode_config.mutex);
+ intel_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+ mutex_unlock(&dev->mode_config.mutex);
+
+ intel_connector->unregister(intel_connector);
+
+ mutex_lock(&dev->mode_config.mutex);
+ intel_connector_remove_from_fbdev(intel_connector);
+ drm_connector_cleanup(connector);
+ mutex_unlock(&dev->mode_config.mutex);
+
+ drm_reinit_primary_mode_group(dev);
+
+ kfree(intel_connector);
+ DRM_DEBUG_KMS("\n");
+}
+
+static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
+{
+ struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+ struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+
+ drm_kms_helper_hotplug_event(dev);
+}
+
+static struct drm_dp_mst_topology_cbs mst_cbs = {
+ .add_connector = intel_dp_add_mst_connector,
+ .destroy_connector = intel_dp_destroy_mst_connector,
+ .hotplug = intel_dp_mst_hotplug,
+};
+
+static struct intel_dp_mst_encoder *
+intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum pipe pipe)
+{
+ struct intel_dp_mst_encoder *intel_mst;
+ struct intel_encoder *intel_encoder;
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+
+ intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL);
+
+ if (!intel_mst)
+ return NULL;
+
+ intel_mst->pipe = pipe;
+ intel_encoder = &intel_mst->base;
+ intel_mst->primary = intel_dig_port;
+
+ drm_encoder_init(dev, &intel_encoder->base, &intel_dp_mst_enc_funcs,
+ DRM_MODE_ENCODER_DPMST);
+
+ intel_encoder->type = INTEL_OUTPUT_DP_MST;
+ intel_encoder->crtc_mask = 0x7;
+ intel_encoder->cloneable = 0;
+
+ intel_encoder->compute_config = intel_dp_mst_compute_config;
+ intel_encoder->disable = intel_mst_disable_dp;
+ intel_encoder->post_disable = intel_mst_post_disable_dp;
+ intel_encoder->pre_enable = intel_mst_pre_enable_dp;
+ intel_encoder->enable = intel_mst_enable_dp;
+ intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state;
+ intel_encoder->get_config = intel_dp_mst_enc_get_config;
+
+ return intel_mst;
+
+}
+
+static bool
+intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port)
+{
+ int i;
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+ for (i = PIPE_A; i <= PIPE_C; i++)
+ intel_dp->mst_encoders[i] = intel_dp_create_fake_mst_encoder(intel_dig_port, i);
+ return true;
+}
+
+int
+intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_base_id)
+{
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+ struct drm_device *dev = intel_dig_port->base.base.dev;
+ int ret;
+
+ intel_dp->can_mst = true;
+ intel_dp->mst_mgr.cbs = &mst_cbs;
+
+ /* create encoders */
+ intel_dp_create_fake_mst_encoders(intel_dig_port);
+ ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, dev->dev, &intel_dp->aux, 16, 3, conn_base_id);
+ if (ret) {
+ intel_dp->can_mst = false;
+ return ret;
+ }
+ return 0;
+}
+
+void
+intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
+{
+ struct intel_dp *intel_dp = &intel_dig_port->dp;
+
+ if (!intel_dp->can_mst)
+ return;
+
+ drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
+ /* encoders will get killed by normal cleanup */
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eaa27ee9e367..4b2664bd5b81 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -32,7 +32,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_mst_helper.h>
/**
* _wait_for - magic (register) wait macro
@@ -100,6 +100,7 @@
#define INTEL_OUTPUT_EDP 8
#define INTEL_OUTPUT_DSI 9
#define INTEL_OUTPUT_UNKNOWN 10
+#define INTEL_OUTPUT_DP_MST 11
#define INTEL_DVO_CHIP_NONE 0
#define INTEL_DVO_CHIP_LVDS 1
@@ -165,6 +166,7 @@ struct intel_panel {
struct {
bool present;
u32 level;
+ u32 min;
u32 max;
bool enabled;
bool combination_mode; /* gen 2/4 only */
@@ -207,6 +209,10 @@ struct intel_connector {
/* since POLL and HPD connectors may use the same HPD line keep the native
state of connector->polled in case hotplug storm detection changes it */
u8 polled;
+
+ void *port; /* store this opaque as its illegal to dereference it */
+
+ struct intel_dp *mst_port;
};
typedef struct dpll {
@@ -307,6 +313,9 @@ struct intel_crtc_config {
/* Selected dpll when shared or DPLL_ID_PRIVATE. */
enum intel_dpll_id shared_dpll;
+ /* PORT_CLK_SEL for DDI ports. */
+ uint32_t ddi_pll_sel;
+
/* Actual register state of the dpll, for shared dpll cross-checking. */
struct intel_dpll_hw_state dpll_hw_state;
@@ -338,6 +347,7 @@ struct intel_crtc_config {
u32 pos;
u32 size;
bool enabled;
+ bool force_thru;
} pch_pfit;
/* FDI configuration, only valid if has_pch_encoder is set. */
@@ -347,6 +357,9 @@ struct intel_crtc_config {
bool ips_enabled;
bool double_wide;
+
+ bool dp_encoder_is_mst;
+ int pbn;
};
struct intel_pipe_wm {
@@ -358,6 +371,11 @@ struct intel_pipe_wm {
bool sprites_scaled;
};
+struct intel_mmio_flip {
+ u32 seqno;
+ u32 ring_id;
+};
+
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
@@ -384,7 +402,6 @@ struct intel_crtc {
struct drm_i915_gem_object *cursor_bo;
uint32_t cursor_addr;
- int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height;
uint32_t cursor_cntl;
uint32_t cursor_base;
@@ -394,8 +411,6 @@ struct intel_crtc {
struct intel_crtc_config *new_config;
bool new_enabled;
- uint32_t ddi_pll_sel;
-
/* reset counter value when the last flip was submitted */
unsigned int reset_counter;
@@ -412,10 +427,12 @@ struct intel_crtc {
wait_queue_head_t vbl_wait;
int scanline_offset;
+ struct intel_mmio_flip mmio_flip;
};
struct intel_plane_wm_parameters {
uint32_t horiz_pixels;
+ uint32_t vert_pixels;
uint8_t bytes_per_pixel;
bool enabled;
bool scaled;
@@ -428,7 +445,6 @@ struct intel_plane {
struct drm_i915_gem_object *obj;
bool can_scale;
int max_downscale;
- u32 lut_r[1024], lut_g[1024], lut_b[1024];
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
uint32_t src_x, src_y;
@@ -481,6 +497,7 @@ struct cxsr_latency {
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
#define to_intel_plane(x) container_of(x, struct intel_plane, base)
+#define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL)
struct intel_hdmi {
u32 hdmi_reg;
@@ -491,6 +508,7 @@ struct intel_hdmi {
bool has_audio;
enum hdmi_force_audio force_audio;
bool rgb_quant_range_selectable;
+ enum hdmi_picture_aspect aspect_ratio;
void (*write_infoframe)(struct drm_encoder *encoder,
enum hdmi_infoframe_type type,
const void *frame, ssize_t len);
@@ -499,6 +517,7 @@ struct intel_hdmi {
struct drm_display_mode *adjusted_mode);
};
+struct intel_dp_mst_encoder;
#define DP_MAX_DOWNSTREAM_PORTS 0x10
/**
@@ -537,10 +556,20 @@ struct intel_dp {
unsigned long last_power_cycle;
unsigned long last_power_on;
unsigned long last_backlight_off;
- bool psr_setup_done;
+
+ struct notifier_block edp_notifier;
+
bool use_tps3;
+ bool can_mst; /* this port supports mst */
+ bool is_mst;
+ int active_mst_links;
+ /* connector directly attached - won't be use for modeset in mst world */
struct intel_connector *attached_connector;
+ /* mst connector list */
+ struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
+ struct drm_dp_mst_topology_mgr mst_mgr;
+
uint32_t (*get_aux_clock_divider)(struct intel_dp *dp, int index);
/*
* This function returns the value we have to program the AUX_CTL
@@ -564,6 +593,14 @@ struct intel_digital_port {
u32 saved_port_bits;
struct intel_dp dp;
struct intel_hdmi hdmi;
+ bool (*hpd_pulse)(struct intel_digital_port *, bool);
+};
+
+struct intel_dp_mst_encoder {
+ struct intel_encoder base;
+ enum pipe pipe;
+ struct intel_digital_port *primary;
+ void *port; /* store this opaque as its illegal to dereference it */
};
static inline int
@@ -650,6 +687,12 @@ enc_to_dig_port(struct drm_encoder *encoder)
return container_of(encoder, struct intel_digital_port, base.base);
}
+static inline struct intel_dp_mst_encoder *
+enc_to_mst(struct drm_encoder *encoder)
+{
+ return container_of(encoder, struct intel_dp_mst_encoder, base.base);
+}
+
static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
{
return &enc_to_dig_port(encoder)->dp;
@@ -674,17 +717,26 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
enum transcoder pch_transcoder,
bool enable);
-void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void bdw_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
-void bdw_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
+void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void intel_runtime_pm_disable_interrupts(struct drm_device *dev);
void intel_runtime_pm_restore_interrupts(struct drm_device *dev);
+static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
+{
+ /*
+ * We only use drm_irq_uninstall() at unload and VT switch, so
+ * this is the only thing we need to check.
+ */
+ return !dev_priv->pm._irqs_disabled;
+}
+
int intel_get_crtc_scanline(struct intel_crtc *crtc);
void i9xx_check_fifo_underruns(struct drm_device *dev);
-
+void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv);
/* intel_crt.c */
void intel_crt_init(struct drm_device *dev);
@@ -703,10 +755,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder);
void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
-void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
bool intel_ddi_pll_select(struct intel_crtc *crtc);
-void intel_ddi_pll_enable(struct intel_crtc *crtc);
-void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
@@ -714,17 +763,46 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc);
void intel_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config);
+void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
+void intel_ddi_clock_get(struct intel_encoder *encoder,
+ struct intel_crtc_config *pipe_config);
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
/* intel_display.c */
const char *intel_output_name(int output);
bool intel_has_pending_fb_unpin(struct drm_device *dev);
int intel_pch_rawclk(struct drm_device *dev);
-int valleyview_cur_cdclk(struct drm_i915_private *dev_priv);
void intel_mark_busy(struct drm_device *dev);
-void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
- struct intel_engine_cs *ring);
+void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
+ struct intel_engine_cs *ring);
+void intel_frontbuffer_flip_prepare(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+void intel_frontbuffer_flip_complete(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+void intel_frontbuffer_flush(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+/**
+ * intel_frontbuffer_flip - prepare frontbuffer flip
+ * @dev: DRM device
+ * @frontbuffer_bits: frontbuffer plane tracking bits
+ *
+ * This function gets called after scheduling a flip on @obj. This is for
+ * synchronous plane updates which will happen on the next vblank and which will
+ * not get delayed by pending gpu rendering.
+ *
+ * Can be called without any locks held.
+ */
+static inline
+void intel_frontbuffer_flip(struct drm_device *dev,
+ unsigned frontbuffer_bits)
+{
+ intel_frontbuffer_flush(dev, frontbuffer_bits);
+}
+
+void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);
void intel_mark_idle(struct drm_device *dev);
void intel_crtc_restore_mode(struct drm_crtc *crtc);
+void intel_crtc_control(struct drm_crtc *crtc, bool enable);
void intel_crtc_update_dpms(struct drm_crtc *crtc);
void intel_encoder_destroy(struct drm_encoder *encoder);
void intel_connector_dpms(struct drm_connector *, int mode);
@@ -765,12 +843,18 @@ __intel_framebuffer_create(struct drm_device *dev,
void intel_prepare_page_flip(struct drm_device *dev, int plane);
void intel_finish_page_flip(struct drm_device *dev, int pipe);
void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
+
+/* shared dpll functions */
struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll,
bool state);
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc);
+void intel_put_shared_dpll(struct intel_crtc *crtc);
+
+/* modesetting asserts */
void assert_pll(struct drm_i915_private *dev_priv,
enum pipe pipe, bool state);
#define assert_pll_enabled(d, p) assert_pll(d, p, true)
@@ -803,7 +887,6 @@ void hsw_disable_ips(struct intel_crtc *crtc);
void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
enum intel_display_power_domain
intel_display_port_power_domain(struct intel_encoder *intel_encoder);
-int valleyview_get_vco(struct drm_i915_private *dev_priv);
void intel_mode_from_pipe_config(struct drm_display_mode *mode,
struct intel_crtc_config *pipe_config);
int intel_format_to_fourcc(int format);
@@ -824,18 +907,34 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc);
bool intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config);
bool intel_dp_is_edp(struct drm_device *dev, enum port port);
+bool intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port,
+ bool long_hpd);
void intel_edp_backlight_on(struct intel_dp *intel_dp);
void intel_edp_backlight_off(struct intel_dp *intel_dp);
void intel_edp_panel_vdd_on(struct intel_dp *intel_dp);
+void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder);
void intel_edp_panel_on(struct intel_dp *intel_dp);
void intel_edp_panel_off(struct intel_dp *intel_dp);
void intel_edp_psr_enable(struct intel_dp *intel_dp);
void intel_edp_psr_disable(struct intel_dp *intel_dp);
-void intel_edp_psr_update(struct drm_device *dev);
void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
-
+void intel_edp_psr_invalidate(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+void intel_edp_psr_flush(struct drm_device *dev,
+ unsigned frontbuffer_bits);
+void intel_edp_psr_init(struct drm_device *dev);
+
+int intel_dp_handle_hpd_irq(struct intel_digital_port *digport, bool long_hpd);
+void intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector);
+void intel_dp_mst_suspend(struct drm_device *dev);
+void intel_dp_mst_resume(struct drm_device *dev);
+int intel_dp_max_link_bw(struct intel_dp *intel_dp);
+void intel_dp_hot_plug(struct intel_encoder *intel_encoder);
+/* intel_dp_mst.c */
+int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
+void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
/* intel_dsi.c */
-bool intel_dsi_init(struct drm_device *dev);
+void intel_dsi_init(struct drm_device *dev);
/* intel_dvo.c */
@@ -918,8 +1017,8 @@ void intel_pch_panel_fitting(struct intel_crtc *crtc,
void intel_gmch_panel_fitting(struct intel_crtc *crtc,
struct intel_crtc_config *pipe_config,
int fitting_mode);
-void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
- u32 max);
+void intel_panel_set_backlight_acpi(struct intel_connector *connector,
+ u32 level, u32 max);
int intel_panel_setup_backlight(struct drm_connector *connector);
void intel_panel_enable_backlight(struct intel_connector *connector);
void intel_panel_disable_backlight(struct intel_connector *connector);
@@ -938,7 +1037,9 @@ int ilk_wm_max_level(const struct drm_device *dev);
void intel_update_watermarks(struct drm_crtc *crtc);
void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
- uint32_t sprite_width, int pixel_size,
+ uint32_t sprite_width,
+ uint32_t sprite_height,
+ int pixel_size,
bool enabled, bool scaled);
void intel_init_pm(struct drm_device *dev);
void intel_pm_setup(struct drm_device *dev);
@@ -961,6 +1062,7 @@ void intel_init_gt_powersave(struct drm_device *dev);
void intel_cleanup_gt_powersave(struct drm_device *dev);
void intel_enable_gt_powersave(struct drm_device *dev);
void intel_disable_gt_powersave(struct drm_device *dev);
+void intel_suspend_gt_powersave(struct drm_device *dev);
void intel_reset_gt_powersave(struct drm_device *dev);
void ironlake_teardown_rc6(struct drm_device *dev);
void gen6_update_ring_freq(struct drm_device *dev);
@@ -974,8 +1076,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
void ilk_wm_get_hw_state(struct drm_device *dev);
-void __vlv_set_power_well(struct drm_i915_private *dev_priv,
- enum punit_power_well power_well_id, bool enable);
+
/* intel_sdvo.c */
bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 02f99d768d49..670c29a7b5dd 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -92,6 +92,9 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
if (fixed_mode)
intel_fixed_panel_mode(fixed_mode, adjusted_mode);
+ /* DSI uses short packets for sync events, so clear mode flags for DSI */
+ adjusted_mode->flags = 0;
+
if (intel_dsi->dev.dev_ops->mode_fixup)
return intel_dsi->dev.dev_ops->mode_fixup(&intel_dsi->dev,
mode, adjusted_mode);
@@ -117,17 +120,18 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
/* bandgap reset is needed after everytime we do power gate */
band_gap_reset(dev_priv);
+ I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
+ usleep_range(2500, 3000);
+
val = I915_READ(MIPI_PORT_CTRL(pipe));
I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD);
usleep_range(1000, 1500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
- usleep_range(2000, 2500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
- usleep_range(2000, 2500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
- usleep_range(2000, 2500);
+
+ I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
+ usleep_range(2500, 3000);
+
I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY);
- usleep_range(2000, 2500);
+ usleep_range(2500, 3000);
}
static void intel_dsi_enable(struct intel_encoder *encoder)
@@ -151,6 +155,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
if (intel_dsi->dev.dev_ops->enable)
intel_dsi->dev.dev_ops->enable(&intel_dsi->dev);
+ wait_for_dsi_fifo_empty(intel_dsi);
+
/* assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe)) & ~LANE_CONFIGURATION_MASK;
temp = temp | intel_dsi->port_bits;
@@ -176,6 +182,10 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
tmp |= DPLL_REFA_CLK_ENABLE_VLV;
I915_WRITE(DPLL(pipe), tmp);
+ /* update the hw state for DPLL */
+ intel_crtc->config.dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
+ DPLL_REFA_CLK_ENABLE_VLV;
+
tmp = I915_READ(DSPCLK_GATE_D);
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, tmp);
@@ -191,6 +201,8 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
if (intel_dsi->dev.dev_ops->send_otp_cmds)
intel_dsi->dev.dev_ops->send_otp_cmds(&intel_dsi->dev);
+ wait_for_dsi_fifo_empty(intel_dsi);
+
/* Enable port in pre-enable phase itself because as per hw team
* recommendation, port should be enabled befor plane & pipe */
intel_dsi_enable(encoder);
@@ -231,6 +243,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n");
if (is_vid_mode(intel_dsi)) {
+ wait_for_dsi_fifo_empty(intel_dsi);
+
/* de-assert ip_tg_enable signal */
temp = I915_READ(MIPI_PORT_CTRL(pipe));
I915_WRITE(MIPI_PORT_CTRL(pipe), temp & ~DPI_ENABLE);
@@ -260,6 +274,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder)
* some next enable sequence send turn on packet error is observed */
if (intel_dsi->dev.dev_ops->disable)
intel_dsi->dev.dev_ops->disable(&intel_dsi->dev);
+
+ wait_for_dsi_fifo_empty(intel_dsi);
}
static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
@@ -271,23 +287,23 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n");
- I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
+ I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
usleep_range(2000, 2500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT);
+ I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT);
usleep_range(2000, 2500);
- I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER);
+ I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER);
usleep_range(2000, 2500);
- val = I915_READ(MIPI_PORT_CTRL(pipe));
- I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
- usleep_range(1000, 1500);
-
if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT)
== 0x00000), 30))
DRM_ERROR("DSI LP not going Low\n");
+ val = I915_READ(MIPI_PORT_CTRL(pipe));
+ I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD);
+ usleep_range(1000, 1500);
+
I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00);
usleep_range(2000, 2500);
@@ -350,9 +366,21 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
static void intel_dsi_get_config(struct intel_encoder *encoder,
struct intel_crtc_config *pipe_config)
{
+ u32 pclk;
DRM_DEBUG_KMS("\n");
- /* XXX: read flags, set to adjusted_mode */
+ /*
+ * DPLL_MD is not used in case of DSI, reading will get some default value
+ * set dpll_md = 0
+ */
+ pipe_config->dpll_hw_state.dpll_md = 0;
+
+ pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp);
+ if (!pclk)
+ return;
+
+ pipe_config->adjusted_mode.crtc_clock = pclk;
+ pipe_config->port_clock = pclk;
}
static enum drm_mode_status
@@ -657,7 +685,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
};
-bool intel_dsi_init(struct drm_device *dev)
+void intel_dsi_init(struct drm_device *dev)
{
struct intel_dsi *intel_dsi;
struct intel_encoder *intel_encoder;
@@ -673,29 +701,29 @@ bool intel_dsi_init(struct drm_device *dev)
/* There is no detection method for MIPI so rely on VBT */
if (!dev_priv->vbt.has_mipi)
- return false;
+ return;
+
+ if (IS_VALLEYVIEW(dev)) {
+ dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
+ } else {
+ DRM_ERROR("Unsupported Mipi device to reg base");
+ return;
+ }
intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
if (!intel_dsi)
- return false;
+ return;
intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_dsi);
- return false;
+ return;
}
intel_encoder = &intel_dsi->base;
encoder = &intel_encoder->base;
intel_dsi->attached_connector = intel_connector;
- if (IS_VALLEYVIEW(dev)) {
- dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
- } else {
- DRM_ERROR("Unsupported Mipi device to reg base");
- return false;
- }
-
connector = &intel_connector->base;
drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI);
@@ -742,7 +770,7 @@ bool intel_dsi_init(struct drm_device *dev)
intel_connector_attach_encoder(intel_connector, intel_encoder);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
fixed_mode = dsi->dev_ops->get_modes(&intel_dsi->dev);
if (!fixed_mode) {
@@ -753,12 +781,10 @@ bool intel_dsi_init(struct drm_device *dev)
fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
- return true;
+ return;
err:
drm_encoder_cleanup(&intel_encoder->base);
kfree(intel_dsi);
kfree(intel_connector);
-
- return false;
}
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 31db33d3e5cc..fd51867fd0d3 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -132,6 +132,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
+extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
extern struct intel_dsi_dev_ops vbt_generic_dsi_display_ops;
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c
index 3eeb21b9fddf..7f1430ac8543 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.c
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c
@@ -404,12 +404,6 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
else
cmd |= DPI_LP_MODE;
- /* DPI virtual channel?! */
-
- mask = DPI_FIFO_EMPTY;
- if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50))
- DRM_ERROR("Timeout waiting for DPI FIFO empty.\n");
-
/* clear bit */
I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT);
@@ -425,3 +419,19 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs)
return 0;
}
+
+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi)
+{
+ struct drm_encoder *encoder = &intel_dsi->base.base;
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ enum pipe pipe = intel_crtc->pipe;
+ u32 mask;
+
+ mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY |
+ LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY;
+
+ if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 100))
+ DRM_ERROR("DPI FIFOs are not empty\n");
+}
diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.h b/drivers/gpu/drm/i915/intel_dsi_cmd.h
index 9a18cbfa5460..46aa1acc00eb 100644
--- a/drivers/gpu/drm/i915/intel_dsi_cmd.h
+++ b/drivers/gpu/drm/i915/intel_dsi_cmd.h
@@ -51,6 +51,7 @@ int dsi_vc_generic_read(struct intel_dsi *intel_dsi, int channel,
u8 *reqdata, int reqlen, u8 *buf, int buflen);
int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs);
+void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi);
/* XXX: questionable write helpers */
static inline int dsi_vc_dcs_write_0(struct intel_dsi *intel_dsi,
diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
index 21a0d348cedc..47c7584a4aa0 100644
--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
@@ -143,7 +143,7 @@ static u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, u8 *data)
case MIPI_DSI_DCS_LONG_WRITE:
dsi_vc_dcs_write(intel_dsi, vc, data, len);
break;
- };
+ }
data += len;
@@ -294,7 +294,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
intel_dsi->rst_timer_val = mipi_config->device_reset_timer;
intel_dsi->init_count = mipi_config->master_init_timer;
intel_dsi->bw_timer = mipi_config->dbi_bw_timer;
- intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
+ intel_dsi->video_frmt_cfg_bits =
+ mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
switch (intel_dsi->escape_clk_div) {
case 0:
@@ -351,7 +352,8 @@ static bool generic_init(struct intel_dsi_device *dsi)
*
* prepare count
*/
- ths_prepare_ns = max(mipi_config->ths_prepare, mipi_config->tclk_prepare);
+ ths_prepare_ns = max(mipi_config->ths_prepare,
+ mipi_config->tclk_prepare);
prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * 2);
/* exit zero count */
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index ba79ec19da3b..d8bb1ea2f0da 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -298,3 +298,84 @@ void vlv_disable_dsi_pll(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
}
+
+static void assert_bpp_mismatch(int pixel_format, int pipe_bpp)
+{
+ int bpp;
+
+ switch (pixel_format) {
+ default:
+ case VID_MODE_FORMAT_RGB888:
+ case VID_MODE_FORMAT_RGB666_LOOSE:
+ bpp = 24;
+ break;
+ case VID_MODE_FORMAT_RGB666:
+ bpp = 18;
+ break;
+ case VID_MODE_FORMAT_RGB565:
+ bpp = 16;
+ break;
+ }
+
+ WARN(bpp != pipe_bpp,
+ "bpp match assertion failure (expected %d, current %d)\n",
+ bpp, pipe_bpp);
+}
+
+u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
+{
+ struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+ struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+ u32 dsi_clock, pclk;
+ u32 pll_ctl, pll_div;
+ u32 m = 0, p = 0;
+ int refclk = 25000;
+ int i;
+
+ DRM_DEBUG_KMS("\n");
+
+ mutex_lock(&dev_priv->dpio_lock);
+ pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
+ pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
+ mutex_unlock(&dev_priv->dpio_lock);
+
+ /* mask out other bits and extract the P1 divisor */
+ pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
+ pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
+
+ /* mask out the other bits and extract the M1 divisor */
+ pll_div &= DSI_PLL_M1_DIV_MASK;
+ pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
+
+ while (pll_ctl) {
+ pll_ctl = pll_ctl >> 1;
+ p++;
+ }
+ p--;
+
+ if (!p) {
+ DRM_ERROR("wrong P1 divisor\n");
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
+ if (lfsr_converts[i] == pll_div)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(lfsr_converts)) {
+ DRM_ERROR("wrong m_seed programmed\n");
+ return 0;
+ }
+
+ m = i + 62;
+
+ dsi_clock = (m * refclk) / p;
+
+ /* pixel_format and pipe_bpp should agree */
+ assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
+
+ pclk = DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, pipe_bpp);
+
+ return pclk;
+}
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index a3631c0a5c28..56b47d2ffaf7 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -112,7 +112,15 @@ static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector)
static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector)
{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base);
+ u32 tmp;
+
+ tmp = I915_READ(intel_dvo->dev.dvo_reg);
+
+ if (!(tmp & DVO_ENABLE))
+ return false;
return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev);
}
@@ -558,7 +566,7 @@ void intel_dvo_init(struct drm_device *dev)
intel_dvo->panel_wants_dither = true;
}
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return;
}
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 088fe9378a4c..f475414671d8 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -43,10 +43,36 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
+static int intel_fbdev_set_par(struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct intel_fbdev *ifbdev =
+ container_of(fb_helper, struct intel_fbdev, helper);
+ int ret;
+
+ ret = drm_fb_helper_set_par(info);
+
+ if (ret == 0) {
+ /*
+ * FIXME: fbdev presumes that all callbacks also work from
+ * atomic contexts and relies on that for emergency oops
+ * printing. KMS totally doesn't do that and the locking here is
+ * by far not the only place this goes wrong. Ignore this for
+ * now until we solve this for real.
+ */
+ mutex_lock(&fb_helper->dev->struct_mutex);
+ ret = i915_gem_object_set_to_gtt_domain(ifbdev->fb->obj,
+ true);
+ mutex_unlock(&fb_helper->dev->struct_mutex);
+ }
+
+ return ret;
+}
+
static struct fb_ops intelfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
- .fb_set_par = drm_fb_helper_set_par,
+ .fb_set_par = intel_fbdev_set_par,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
@@ -81,7 +107,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
sizes->surface_depth);
size = mode_cmd.pitches[0] * mode_cmd.height;
- size = ALIGN(size, PAGE_SIZE);
+ size = PAGE_ALIGN(size);
obj = i915_gem_object_create_stolen(dev, size);
if (obj == NULL)
obj = i915_gem_alloc_object(dev, size);
@@ -417,7 +443,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
}
crtcs[i] = new_crtc;
- DRM_DEBUG_KMS("connector %s on pipe %d [CRTC:%d]: %dx%d%s\n",
+ DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
connector->name,
pipe_name(to_intel_crtc(encoder->crtc)->pipe),
encoder->crtc->base.id,
@@ -452,7 +478,7 @@ out:
return true;
}
-static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
+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,
@@ -623,7 +649,8 @@ int intel_fbdev_init(struct drm_device *dev)
if (ifbdev == NULL)
return -ENOMEM;
- ifbdev->helper.funcs = &intel_fb_helper_funcs;
+ drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
+
if (!intel_fbdev_init_bios(dev, ifbdev))
ifbdev->preferred_bpp = 32;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index eee2bbec2958..f9151f6641d9 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -367,6 +367,9 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
union hdmi_infoframe frame;
int ret;
+ /* Set user selected PAR to incoming mode's member */
+ adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio;
+
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
adjusted_mode);
if (ret < 0) {
@@ -879,7 +882,7 @@ static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
struct intel_encoder *encoder;
int count = 0, count_hdmi = 0;
- if (!HAS_PCH_SPLIT(dev))
+ if (HAS_GMCH_DISPLAY(dev))
return false;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) {
@@ -1124,6 +1127,23 @@ intel_hdmi_set_property(struct drm_connector *connector,
goto done;
}
+ if (property == connector->dev->mode_config.aspect_ratio_property) {
+ switch (val) {
+ case DRM_MODE_PICTURE_ASPECT_NONE:
+ intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+ break;
+ case DRM_MODE_PICTURE_ASPECT_4_3:
+ intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
+ break;
+ case DRM_MODE_PICTURE_ASPECT_16_9:
+ intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
+ break;
+ default:
+ return -EINVAL;
+ }
+ goto done;
+ }
+
return -EINVAL;
done:
@@ -1229,6 +1249,70 @@ static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock);
}
+static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
+{
+ struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+ struct drm_device *dev = encoder->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc =
+ to_intel_crtc(encoder->base.crtc);
+ enum dpio_channel ch = vlv_dport_to_channel(dport);
+ enum pipe pipe = intel_crtc->pipe;
+ u32 val;
+
+ mutex_lock(&dev_priv->dpio_lock);
+
+ /* program left/right clock distribution */
+ if (pipe != PIPE_B) {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0);
+ val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
+ if (ch == DPIO_CH0)
+ val |= CHV_BUFLEFTENA1_FORCE;
+ if (ch == DPIO_CH1)
+ val |= CHV_BUFRIGHTENA1_FORCE;
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val);
+ } else {
+ val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1);
+ val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
+ if (ch == DPIO_CH0)
+ val |= CHV_BUFLEFTENA2_FORCE;
+ if (ch == DPIO_CH1)
+ val |= CHV_BUFRIGHTENA2_FORCE;
+ vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
+ }
+
+ /* program clock channel usage */
+ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(ch));
+ val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+ if (pipe != PIPE_B)
+ val &= ~CHV_PCS_USEDCLKCHANNEL;
+ else
+ val |= CHV_PCS_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val);
+
+ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch));
+ val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
+ if (pipe != PIPE_B)
+ val &= ~CHV_PCS_USEDCLKCHANNEL;
+ else
+ val |= CHV_PCS_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val);
+
+ /*
+ * This a a bit weird since generally CL
+ * matches the pipe, but here we need to
+ * pick the CL based on the port.
+ */
+ val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW19(ch));
+ if (pipe != PIPE_B)
+ val &= ~CHV_CMN_USEDCLKCHANNEL;
+ else
+ val |= CHV_CMN_USEDCLKCHANNEL;
+ vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
+
+ mutex_unlock(&dev_priv->dpio_lock);
+}
+
static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
{
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
@@ -1416,11 +1500,22 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
};
static void
+intel_attach_aspect_ratio_property(struct drm_connector *connector)
+{
+ if (!drm_mode_create_aspect_ratio_property(connector->dev))
+ drm_object_attach_property(&connector->base,
+ connector->dev->mode_config.aspect_ratio_property,
+ DRM_MODE_PICTURE_ASPECT_NONE);
+}
+
+static void
intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
{
intel_attach_force_audio_property(connector);
intel_attach_broadcast_rgb_property(connector);
intel_hdmi->color_range_auto = true;
+ intel_attach_aspect_ratio_property(connector);
+ intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
}
void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
@@ -1467,7 +1562,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
if (IS_VALLEYVIEW(dev)) {
intel_hdmi->write_infoframe = vlv_write_infoframe;
intel_hdmi->set_infoframes = vlv_set_infoframes;
- } else if (!HAS_PCH_SPLIT(dev)) {
+ } else if (IS_G4X(dev)) {
intel_hdmi->write_infoframe = g4x_write_infoframe;
intel_hdmi->set_infoframes = g4x_set_infoframes;
} else if (HAS_DDI(dev)) {
@@ -1490,7 +1585,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
intel_hdmi_add_properties(intel_hdmi, connector);
intel_connector_attach_encoder(intel_connector, intel_encoder);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
* 0xd. Failure to do so will result in spurious interrupts being
@@ -1528,6 +1623,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
intel_encoder->get_config = intel_hdmi_get_config;
if (IS_CHERRYVIEW(dev)) {
+ intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
intel_encoder->pre_enable = chv_hdmi_pre_enable;
intel_encoder->enable = vlv_enable_hdmi;
intel_encoder->post_disable = chv_hdmi_post_disable;
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index d33b61d0dd33..b31088a551f2 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -34,11 +34,6 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
-enum disp_clk {
- CDCLK,
- CZCLK
-};
-
struct gmbus_port {
const char *name;
int reg;
@@ -63,60 +58,11 @@ to_intel_gmbus(struct i2c_adapter *i2c)
return container_of(i2c, struct intel_gmbus, adapter);
}
-static int get_disp_clk_div(struct drm_i915_private *dev_priv,
- enum disp_clk clk)
-{
- u32 reg_val;
- int clk_ratio;
-
- reg_val = I915_READ(CZCLK_CDCLK_FREQ_RATIO);
-
- if (clk == CDCLK)
- clk_ratio =
- ((reg_val & CDCLK_FREQ_MASK) >> CDCLK_FREQ_SHIFT) + 1;
- else
- clk_ratio = (reg_val & CZCLK_FREQ_MASK) + 1;
-
- return clk_ratio;
-}
-
-static void gmbus_set_freq(struct drm_i915_private *dev_priv)
-{
- int vco, gmbus_freq = 0, cdclk_div;
-
- BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
-
- vco = valleyview_get_vco(dev_priv);
-
- /* Get the CDCLK divide ratio */
- cdclk_div = get_disp_clk_div(dev_priv, CDCLK);
-
- /*
- * Program the gmbus_freq based on the cdclk frequency.
- * BSpec erroneously claims we should aim for 4MHz, but
- * in fact 1MHz is the correct frequency.
- */
- if (cdclk_div)
- gmbus_freq = (vco << 1) / cdclk_div;
-
- if (WARN_ON(gmbus_freq == 0))
- return;
-
- I915_WRITE(GMBUSFREQ_VLV, gmbus_freq);
-}
-
void
intel_i2c_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- /*
- * In BIOS-less system, program the correct gmbus frequency
- * before reading edid.
- */
- if (IS_VALLEYVIEW(dev))
- gmbus_set_freq(dev_priv);
-
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0);
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0);
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 23126023aeba..881361c0f27e 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -51,6 +51,7 @@ struct intel_lvds_encoder {
bool is_dual_link;
u32 reg;
+ u32 a3_power;
struct intel_lvds_connector *attached_connector;
};
@@ -71,8 +72,13 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+ enum intel_display_power_domain power_domain;
u32 tmp;
+ power_domain = intel_display_port_power_domain(encoder);
+ if (!intel_display_power_enabled(dev_priv, power_domain))
+ return false;
+
tmp = I915_READ(lvds_encoder->reg);
if (!(tmp & LVDS_PORT_EN))
@@ -111,6 +117,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
pipe_config->adjusted_mode.flags |= flags;
+ /* gen2/3 store dither state in pfit control, needs to match */
+ if (INTEL_INFO(dev)->gen < 4) {
+ tmp = I915_READ(PFIT_CONTROL);
+
+ pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
+ }
+
dotclock = pipe_config->port_clock;
if (HAS_PCH_SPLIT(dev_priv->dev))
@@ -165,8 +178,11 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
* appropriately here, but we need to look more thoroughly into how
- * panels behave in the two modes.
+ * panels behave in the two modes. For now, let's just maintain the
+ * value we got from the BIOS.
*/
+ temp &= ~LVDS_A3_POWER_MASK;
+ temp |= lvds_encoder->a3_power;
/* Set the dithering flag on LVDS as needed, note that there is no
* special lvds dither control bit on pch-split platforms, dithering is
@@ -264,7 +280,6 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
struct intel_crtc_config *pipe_config)
{
struct drm_device *dev = intel_encoder->base.dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_lvds_encoder *lvds_encoder =
to_lvds_encoder(&intel_encoder->base);
struct intel_connector *intel_connector =
@@ -279,8 +294,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
return false;
}
- if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) ==
- LVDS_A3_POWER_UP)
+ if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
lvds_bpp = 8*3;
else
lvds_bpp = 6*3;
@@ -1081,6 +1095,9 @@ out:
DRM_DEBUG_KMS("detected %s-link lvds configuration\n",
lvds_encoder->is_dual_link ? "dual" : "single");
+ lvds_encoder->a3_power = I915_READ(lvds_encoder->reg) &
+ LVDS_A3_POWER_MASK;
+
/*
* Unlock registers and just
* leave them unlocked
@@ -1097,7 +1114,7 @@ out:
DRM_DEBUG_KMS("lid notifier registration failed\n");
lvds_connector->lid_notifier.notifier_call = NULL;
}
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
intel_panel_setup_backlight(connector);
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 2e2c71fcc9ed..ca52ad2ae7d1 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -352,6 +352,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
case INTEL_OUTPUT_UNKNOWN:
case INTEL_OUTPUT_DISPLAYPORT:
case INTEL_OUTPUT_HDMI:
+ case INTEL_OUTPUT_DP_MST:
type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
break;
case INTEL_OUTPUT_EDP:
@@ -403,6 +404,15 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
+ /*
+ * If the acpi_video interface is not supposed to be used, don't
+ * bother processing backlight level change requests from firmware.
+ */
+ if (!acpi_video_verify_backlight_support()) {
+ DRM_DEBUG_KMS("opregion backlight request ignored\n");
+ return 0;
+ }
+
if (!(bclp & ASLE_BCLP_VALID))
return ASLC_BACKLIGHT_FAILED;
@@ -418,7 +428,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
*/
DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
- intel_panel_set_backlight(intel_connector, bclp, 255);
+ intel_panel_set_backlight_acpi(intel_connector, bclp, 255);
iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
drm_modeset_unlock(&dev->mode_config.connection_mutex);
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index daa118978eec..dc2f4f26c961 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -415,6 +415,10 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
}
intel_overlay_release_old_vid_tail(overlay);
+
+
+ i915_gem_track_fb(overlay->old_vid_bo, NULL,
+ INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
return 0;
}
@@ -686,6 +690,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
bool scale_changed = false;
struct drm_device *dev = overlay->dev;
u32 swidth, swidthsw, sheight, ostride;
+ enum pipe pipe = overlay->crtc->pipe;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
BUG_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
@@ -713,7 +718,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
oconfig = OCONF_CC_OUT_8BIT;
if (IS_GEN4(overlay->dev))
oconfig |= OCONF_CSC_MODE_BT709;
- oconfig |= overlay->crtc->pipe == 0 ?
+ oconfig |= pipe == 0 ?
OCONF_PIPE_A : OCONF_PIPE_B;
iowrite32(oconfig, &regs->OCONFIG);
intel_overlay_unmap_regs(overlay, regs);
@@ -776,9 +781,15 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret)
goto out_unpin;
+ i915_gem_track_fb(overlay->vid_bo, new_bo,
+ INTEL_FRONTBUFFER_OVERLAY(pipe));
+
overlay->old_vid_bo = overlay->vid_bo;
overlay->vid_bo = new_bo;
+ intel_frontbuffer_flip(dev,
+ INTEL_FRONTBUFFER_OVERLAY(pipe));
+
return 0;
out_unpin:
@@ -1028,7 +1039,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_intel_overlay_put_image *put_image_rec = data;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_overlay *overlay;
- struct drm_mode_object *drmmode_obj;
+ struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
struct drm_i915_gem_object *new_bo;
struct put_image_params *params;
@@ -1057,13 +1068,12 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
if (!params)
return -ENOMEM;
- drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
- DRM_MODE_OBJECT_CRTC);
- if (!drmmode_obj) {
+ drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+ if (!drmmode_crtc) {
ret = -ENOENT;
goto out_free;
}
- crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
+ crtc = to_intel_crtc(drmmode_crtc);
new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv,
put_image_rec->bo_handle));
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 38a98570d10c..59b028f0b1e8 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -361,16 +361,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
PFIT_FILTER_FUZZY);
- /* Make sure pre-965 set dither correctly for 18bpp panels. */
- if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
- pfit_control |= PANEL_8TO6_DITHER_ENABLE;
-
out:
if ((pfit_control & PFIT_ENABLE) == 0) {
pfit_control = 0;
pfit_pgm_ratios = 0;
}
+ /* Make sure pre-965 set dither correctly for 18bpp panels. */
+ if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
+ pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
pipe_config->gmch_pfit.control = pfit_control;
pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
pipe_config->gmch_pfit.lvds_border_bits = border;
@@ -398,6 +398,69 @@ intel_panel_detect(struct drm_device *dev)
}
}
+/**
+ * scale - scale values from one range to another
+ *
+ * @source_val: value in range [@source_min..@source_max]
+ *
+ * Return @source_val in range [@source_min..@source_max] scaled to range
+ * [@target_min..@target_max].
+ */
+static uint32_t scale(uint32_t source_val,
+ uint32_t source_min, uint32_t source_max,
+ uint32_t target_min, uint32_t target_max)
+{
+ uint64_t target_val;
+
+ WARN_ON(source_min > source_max);
+ WARN_ON(target_min > target_max);
+
+ /* defensive */
+ source_val = clamp(source_val, source_min, source_max);
+
+ /* avoid overflows */
+ target_val = (uint64_t)(source_val - source_min) *
+ (target_max - target_min);
+ do_div(target_val, source_max - source_min);
+ target_val += target_min;
+
+ return target_val;
+}
+
+/* Scale user_level in range [0..user_max] to [hw_min..hw_max]. */
+static inline u32 scale_user_to_hw(struct intel_connector *connector,
+ u32 user_level, u32 user_max)
+{
+ struct intel_panel *panel = &connector->panel;
+
+ return scale(user_level, 0, user_max,
+ panel->backlight.min, panel->backlight.max);
+}
+
+/* Scale user_level in range [0..user_max] to [0..hw_max], clamping the result
+ * to [hw_min..hw_max]. */
+static inline u32 clamp_user_to_hw(struct intel_connector *connector,
+ u32 user_level, u32 user_max)
+{
+ struct intel_panel *panel = &connector->panel;
+ u32 hw_level;
+
+ hw_level = scale(user_level, 0, user_max, 0, panel->backlight.max);
+ hw_level = clamp(hw_level, panel->backlight.min, panel->backlight.max);
+
+ return hw_level;
+}
+
+/* Scale hw_level in range [hw_min..hw_max] to [0..user_max]. */
+static inline u32 scale_hw_to_user(struct intel_connector *connector,
+ u32 hw_level, u32 user_max)
+{
+ struct intel_panel *panel = &connector->panel;
+
+ return scale(hw_level, panel->backlight.min, panel->backlight.max,
+ 0, user_max);
+}
+
static u32 intel_panel_compute_brightness(struct intel_connector *connector,
u32 val)
{
@@ -557,17 +620,16 @@ intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
dev_priv->display.set_backlight(connector, level);
}
-/* set backlight brightness to level in range [0..max] */
-void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
- u32 max)
+/* set backlight brightness to level in range [0..max], scaling wrt hw min */
+static void intel_panel_set_backlight(struct intel_connector *connector,
+ u32 user_level, u32 user_max)
{
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_panel *panel = &connector->panel;
enum pipe pipe = intel_get_pipe_from_connector(connector);
- u32 freq;
+ u32 hw_level;
unsigned long flags;
- u64 n;
if (!panel->backlight.present || pipe == INVALID_PIPE)
return;
@@ -576,18 +638,46 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
WARN_ON(panel->backlight.max == 0);
- /* scale to hardware max, but be careful to not overflow */
- freq = panel->backlight.max;
- n = (u64)level * freq;
- do_div(n, max);
- level = n;
+ hw_level = scale_user_to_hw(connector, user_level, user_max);
+ panel->backlight.level = hw_level;
+
+ if (panel->backlight.enabled)
+ intel_panel_actually_set_backlight(connector, hw_level);
+
+ spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+}
+
+/* set backlight brightness to level in range [0..max], assuming hw min is
+ * respected.
+ */
+void intel_panel_set_backlight_acpi(struct intel_connector *connector,
+ u32 user_level, u32 user_max)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_panel *panel = &connector->panel;
+ enum pipe pipe = intel_get_pipe_from_connector(connector);
+ u32 hw_level;
+ unsigned long flags;
+
+ if (!panel->backlight.present || pipe == INVALID_PIPE)
+ return;
+
+ spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+
+ WARN_ON(panel->backlight.max == 0);
+
+ hw_level = clamp_user_to_hw(connector, user_level, user_max);
+ panel->backlight.level = hw_level;
- panel->backlight.level = level;
if (panel->backlight.device)
- panel->backlight.device->props.brightness = level;
+ panel->backlight.device->props.brightness =
+ scale_hw_to_user(connector,
+ panel->backlight.level,
+ panel->backlight.device->props.max_brightness);
if (panel->backlight.enabled)
- intel_panel_actually_set_backlight(connector, level);
+ intel_panel_actually_set_backlight(connector, hw_level);
spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
}
@@ -860,7 +950,9 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
panel->backlight.level = panel->backlight.max;
if (panel->backlight.device)
panel->backlight.device->props.brightness =
- panel->backlight.level;
+ scale_hw_to_user(connector,
+ panel->backlight.level,
+ panel->backlight.device->props.max_brightness);
}
dev_priv->display.enable_backlight(connector);
@@ -889,11 +981,15 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd)
struct intel_connector *connector = bl_get_data(bd);
struct drm_device *dev = connector->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 hw_level;
int ret;
intel_runtime_pm_get(dev_priv);
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
- ret = intel_panel_get_backlight(connector);
+
+ hw_level = intel_panel_get_backlight(connector);
+ ret = scale_hw_to_user(connector, hw_level, bd->props.max_brightness);
+
drm_modeset_unlock(&dev->mode_config.connection_mutex);
intel_runtime_pm_put(dev_priv);
@@ -913,12 +1009,19 @@ static int intel_backlight_device_register(struct intel_connector *connector)
if (WARN_ON(panel->backlight.device))
return -ENODEV;
- BUG_ON(panel->backlight.max == 0);
+ WARN_ON(panel->backlight.max == 0);
memset(&props, 0, sizeof(props));
props.type = BACKLIGHT_RAW;
- props.brightness = panel->backlight.level;
+
+ /*
+ * Note: Everything should work even if the backlight device max
+ * presented to the userspace is arbitrarily chosen.
+ */
props.max_brightness = panel->backlight.max;
+ props.brightness = scale_hw_to_user(connector,
+ panel->backlight.level,
+ props.max_brightness);
/*
* Note: using the same name independent of the connector prevents
@@ -964,6 +1067,19 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
* XXX: Query mode clock or hardware clock and program PWM modulation frequency
* appropriately when it's 0. Use VBT and/or sane defaults.
*/
+static u32 get_backlight_min_vbt(struct intel_connector *connector)
+{
+ struct drm_device *dev = connector->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_panel *panel = &connector->panel;
+
+ WARN_ON(panel->backlight.max == 0);
+
+ /* vbt value is a coefficient in range [0..255] */
+ return scale(dev_priv->vbt.backlight.min_brightness, 0, 255,
+ 0, panel->backlight.max);
+}
+
static int bdw_setup_backlight(struct intel_connector *connector)
{
struct drm_device *dev = connector->base.dev;
@@ -979,6 +1095,8 @@ static int bdw_setup_backlight(struct intel_connector *connector)
if (!panel->backlight.max)
return -ENODEV;
+ panel->backlight.min = get_backlight_min_vbt(connector);
+
val = bdw_get_backlight(connector);
panel->backlight.level = intel_panel_compute_brightness(connector, val);
@@ -1003,6 +1121,8 @@ static int pch_setup_backlight(struct intel_connector *connector)
if (!panel->backlight.max)
return -ENODEV;
+ panel->backlight.min = get_backlight_min_vbt(connector);
+
val = pch_get_backlight(connector);
panel->backlight.level = intel_panel_compute_brightness(connector, val);
@@ -1035,6 +1155,8 @@ static int i9xx_setup_backlight(struct intel_connector *connector)
if (!panel->backlight.max)
return -ENODEV;
+ panel->backlight.min = get_backlight_min_vbt(connector);
+
val = i9xx_get_backlight(connector);
panel->backlight.level = intel_panel_compute_brightness(connector, val);
@@ -1062,6 +1184,8 @@ static int i965_setup_backlight(struct intel_connector *connector)
if (!panel->backlight.max)
return -ENODEV;
+ panel->backlight.min = get_backlight_min_vbt(connector);
+
val = i9xx_get_backlight(connector);
panel->backlight.level = intel_panel_compute_brightness(connector, val);
@@ -1099,6 +1223,8 @@ static int vlv_setup_backlight(struct intel_connector *connector)
if (!panel->backlight.max)
return -ENODEV;
+ panel->backlight.min = get_backlight_min_vbt(connector);
+
val = _vlv_get_backlight(dev, PIPE_A);
panel->backlight.level = intel_panel_compute_brightness(connector, val);
@@ -1118,8 +1244,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
int ret;
if (!dev_priv->vbt.backlight.present) {
- DRM_DEBUG_KMS("native backlight control not available per VBT\n");
- return 0;
+ if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
+ DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n");
+ } else {
+ DRM_DEBUG_KMS("no backlight present per VBT\n");
+ return 0;
+ }
}
/* set level and max in panel struct */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9ad0c6afc487..40c12295c0bd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -93,8 +93,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int cfb_pitch;
int i;
@@ -150,8 +149,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 dpfc_ctl;
@@ -222,16 +220,26 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 dpfc_ctl;
dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+ dev_priv->fbc.threshold++;
+
+ switch (dev_priv->fbc.threshold) {
+ case 4:
+ case 3:
+ dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+ break;
+ case 2:
dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- else
+ break;
+ case 1:
dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+ break;
+ }
dpfc_ctl |= DPFC_CTL_FENCE_EN;
if (IS_GEN5(dev))
dpfc_ctl |= obj->fence_reg;
@@ -278,16 +286,27 @@ static void gen7_enable_fbc(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
- struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
+ struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
u32 dpfc_ctl;
dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
+ dev_priv->fbc.threshold++;
+
+ switch (dev_priv->fbc.threshold) {
+ case 4:
+ case 3:
+ dpfc_ctl |= DPFC_CTL_LIMIT_4X;
+ break;
+ case 2:
dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- else
+ break;
+ case 1:
dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+ break;
+ }
+
dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
@@ -462,7 +481,6 @@ void intel_update_fbc(struct drm_device *dev)
struct drm_crtc *crtc = NULL, *tmp_crtc;
struct intel_crtc *intel_crtc;
struct drm_framebuffer *fb;
- struct intel_framebuffer *intel_fb;
struct drm_i915_gem_object *obj;
const struct drm_display_mode *adjusted_mode;
unsigned int max_width, max_height;
@@ -507,8 +525,7 @@ void intel_update_fbc(struct drm_device *dev)
intel_crtc = to_intel_crtc(crtc);
fb = crtc->primary->fb;
- intel_fb = to_intel_framebuffer(fb);
- obj = intel_fb->obj;
+ obj = intel_fb_obj(fb);
adjusted_mode = &intel_crtc->config.adjusted_mode;
if (i915.enable_fbc < 0) {
@@ -529,7 +546,10 @@ void intel_update_fbc(struct drm_device *dev)
goto out_disable;
}
- if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+ if (INTEL_INFO(dev)->gen >= 8 || IS_HASWELL(dev)) {
+ max_width = 4096;
+ max_height = 4096;
+ } else if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
max_width = 4096;
max_height = 2048;
} else {
@@ -563,7 +583,8 @@ void intel_update_fbc(struct drm_device *dev)
if (in_dbg_master())
goto out_disable;
- if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) {
+ if (i915_gem_stolen_setup_compression(dev, obj->base.size,
+ drm_format_plane_cpp(fb->pixel_format, 0))) {
if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL))
DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
goto out_disable;
@@ -789,12 +810,33 @@ static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop,
return NULL;
}
-static void pineview_disable_cxsr(struct drm_device *dev)
+void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_device *dev = dev_priv->dev;
+ u32 val;
+
+ if (IS_VALLEYVIEW(dev)) {
+ I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0);
+ } else if (IS_G4X(dev) || IS_CRESTLINE(dev)) {
+ I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
+ } else if (IS_PINEVIEW(dev)) {
+ val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN;
+ val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0;
+ I915_WRITE(DSPFW3, val);
+ } else if (IS_I945G(dev) || IS_I945GM(dev)) {
+ val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
+ _MASKED_BIT_DISABLE(FW_BLC_SELF_EN);
+ I915_WRITE(FW_BLC_SELF, val);
+ } else if (IS_I915GM(dev)) {
+ val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) :
+ _MASKED_BIT_DISABLE(INSTPM_SELF_EN);
+ I915_WRITE(INSTPM, val);
+ } else {
+ return;
+ }
- /* deactivate cxsr */
- I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN);
+ DRM_DEBUG_KMS("memory self-refresh is %s\n",
+ enable ? "enabled" : "disabled");
}
/*
@@ -864,95 +906,95 @@ static int i845_get_fifo_size(struct drm_device *dev, int plane)
/* Pineview has different values for various configs */
static const struct intel_watermark_params pineview_display_wm = {
- PINEVIEW_DISPLAY_FIFO,
- PINEVIEW_MAX_WM,
- PINEVIEW_DFT_WM,
- PINEVIEW_GUARD_WM,
- PINEVIEW_FIFO_LINE_SIZE
+ .fifo_size = PINEVIEW_DISPLAY_FIFO,
+ .max_wm = PINEVIEW_MAX_WM,
+ .default_wm = PINEVIEW_DFT_WM,
+ .guard_size = PINEVIEW_GUARD_WM,
+ .cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params pineview_display_hplloff_wm = {
- PINEVIEW_DISPLAY_FIFO,
- PINEVIEW_MAX_WM,
- PINEVIEW_DFT_HPLLOFF_WM,
- PINEVIEW_GUARD_WM,
- PINEVIEW_FIFO_LINE_SIZE
+ .fifo_size = PINEVIEW_DISPLAY_FIFO,
+ .max_wm = PINEVIEW_MAX_WM,
+ .default_wm = PINEVIEW_DFT_HPLLOFF_WM,
+ .guard_size = PINEVIEW_GUARD_WM,
+ .cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params pineview_cursor_wm = {
- PINEVIEW_CURSOR_FIFO,
- PINEVIEW_CURSOR_MAX_WM,
- PINEVIEW_CURSOR_DFT_WM,
- PINEVIEW_CURSOR_GUARD_WM,
- PINEVIEW_FIFO_LINE_SIZE,
+ .fifo_size = PINEVIEW_CURSOR_FIFO,
+ .max_wm = PINEVIEW_CURSOR_MAX_WM,
+ .default_wm = PINEVIEW_CURSOR_DFT_WM,
+ .guard_size = PINEVIEW_CURSOR_GUARD_WM,
+ .cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params pineview_cursor_hplloff_wm = {
- PINEVIEW_CURSOR_FIFO,
- PINEVIEW_CURSOR_MAX_WM,
- PINEVIEW_CURSOR_DFT_WM,
- PINEVIEW_CURSOR_GUARD_WM,
- PINEVIEW_FIFO_LINE_SIZE
+ .fifo_size = PINEVIEW_CURSOR_FIFO,
+ .max_wm = PINEVIEW_CURSOR_MAX_WM,
+ .default_wm = PINEVIEW_CURSOR_DFT_WM,
+ .guard_size = PINEVIEW_CURSOR_GUARD_WM,
+ .cacheline_size = PINEVIEW_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params g4x_wm_info = {
- G4X_FIFO_SIZE,
- G4X_MAX_WM,
- G4X_MAX_WM,
- 2,
- G4X_FIFO_LINE_SIZE,
+ .fifo_size = G4X_FIFO_SIZE,
+ .max_wm = G4X_MAX_WM,
+ .default_wm = G4X_MAX_WM,
+ .guard_size = 2,
+ .cacheline_size = G4X_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params g4x_cursor_wm_info = {
- I965_CURSOR_FIFO,
- I965_CURSOR_MAX_WM,
- I965_CURSOR_DFT_WM,
- 2,
- G4X_FIFO_LINE_SIZE,
+ .fifo_size = I965_CURSOR_FIFO,
+ .max_wm = I965_CURSOR_MAX_WM,
+ .default_wm = I965_CURSOR_DFT_WM,
+ .guard_size = 2,
+ .cacheline_size = G4X_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params valleyview_wm_info = {
- VALLEYVIEW_FIFO_SIZE,
- VALLEYVIEW_MAX_WM,
- VALLEYVIEW_MAX_WM,
- 2,
- G4X_FIFO_LINE_SIZE,
+ .fifo_size = VALLEYVIEW_FIFO_SIZE,
+ .max_wm = VALLEYVIEW_MAX_WM,
+ .default_wm = VALLEYVIEW_MAX_WM,
+ .guard_size = 2,
+ .cacheline_size = G4X_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params valleyview_cursor_wm_info = {
- I965_CURSOR_FIFO,
- VALLEYVIEW_CURSOR_MAX_WM,
- I965_CURSOR_DFT_WM,
- 2,
- G4X_FIFO_LINE_SIZE,
+ .fifo_size = I965_CURSOR_FIFO,
+ .max_wm = VALLEYVIEW_CURSOR_MAX_WM,
+ .default_wm = I965_CURSOR_DFT_WM,
+ .guard_size = 2,
+ .cacheline_size = G4X_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params i965_cursor_wm_info = {
- I965_CURSOR_FIFO,
- I965_CURSOR_MAX_WM,
- I965_CURSOR_DFT_WM,
- 2,
- I915_FIFO_LINE_SIZE,
+ .fifo_size = I965_CURSOR_FIFO,
+ .max_wm = I965_CURSOR_MAX_WM,
+ .default_wm = I965_CURSOR_DFT_WM,
+ .guard_size = 2,
+ .cacheline_size = I915_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params i945_wm_info = {
- I945_FIFO_SIZE,
- I915_MAX_WM,
- 1,
- 2,
- I915_FIFO_LINE_SIZE
+ .fifo_size = I945_FIFO_SIZE,
+ .max_wm = I915_MAX_WM,
+ .default_wm = 1,
+ .guard_size = 2,
+ .cacheline_size = I915_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params i915_wm_info = {
- I915_FIFO_SIZE,
- I915_MAX_WM,
- 1,
- 2,
- I915_FIFO_LINE_SIZE
+ .fifo_size = I915_FIFO_SIZE,
+ .max_wm = I915_MAX_WM,
+ .default_wm = 1,
+ .guard_size = 2,
+ .cacheline_size = I915_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params i830_wm_info = {
- I855GM_FIFO_SIZE,
- I915_MAX_WM,
- 1,
- 2,
- I830_FIFO_LINE_SIZE
+ .fifo_size = I855GM_FIFO_SIZE,
+ .max_wm = I915_MAX_WM,
+ .default_wm = 1,
+ .guard_size = 2,
+ .cacheline_size = I830_FIFO_LINE_SIZE,
};
static const struct intel_watermark_params i845_wm_info = {
- I830_FIFO_SIZE,
- I915_MAX_WM,
- 1,
- 2,
- I830_FIFO_LINE_SIZE
+ .fifo_size = I830_FIFO_SIZE,
+ .max_wm = I915_MAX_WM,
+ .default_wm = 1,
+ .guard_size = 2,
+ .cacheline_size = I830_FIFO_LINE_SIZE,
};
/**
@@ -1033,7 +1075,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
dev_priv->fsb_freq, dev_priv->mem_freq);
if (!latency) {
DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
- pineview_disable_cxsr(dev);
+ intel_set_memory_cxsr(dev_priv, false);
return;
}
@@ -1084,13 +1126,9 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
I915_WRITE(DSPFW3, reg);
DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg);
- /* activate cxsr */
- I915_WRITE(DSPFW3,
- I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN);
- DRM_DEBUG_KMS("Self-refresh is enabled\n");
+ intel_set_memory_cxsr(dev_priv, true);
} else {
- pineview_disable_cxsr(dev);
- DRM_DEBUG_KMS("Self-refresh is disabled\n");
+ intel_set_memory_cxsr(dev_priv, false);
}
}
@@ -1249,15 +1287,14 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */
entries = (clock / 1000) * pixel_size;
- *plane_prec_mult = (entries > 256) ?
- DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16;
- *plane_dl = (64 * (*plane_prec_mult) * 4) / ((clock / 1000) *
- pixel_size);
+ *plane_prec_mult = (entries > 128) ?
+ DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32;
+ *plane_dl = (64 * (*plane_prec_mult) * 4) / entries;
entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */
- *cursor_prec_mult = (entries > 256) ?
- DRAIN_LATENCY_PRECISION_32 : DRAIN_LATENCY_PRECISION_16;
- *cursor_dl = (64 * (*cursor_prec_mult) * 4) / ((clock / 1000) * 4);
+ *cursor_prec_mult = (entries > 128) ?
+ DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32;
+ *cursor_dl = (64 * (*cursor_prec_mult) * 4) / entries;
return true;
}
@@ -1282,9 +1319,9 @@ static void vlv_update_drain_latency(struct drm_device *dev)
if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl,
&cursor_prec_mult, &cursora_dl)) {
cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ?
- DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_16;
+ DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_64;
planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ?
- DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_16;
+ DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_64;
I915_WRITE(VLV_DDL1, cursora_prec |
(cursora_dl << DDL_CURSORA_SHIFT) |
@@ -1295,9 +1332,9 @@ static void vlv_update_drain_latency(struct drm_device *dev)
if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl,
&cursor_prec_mult, &cursorb_dl)) {
cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ?
- DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_16;
+ DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_64;
planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ?
- DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_16;
+ DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_64;
I915_WRITE(VLV_DDL2, cursorb_prec |
(cursorb_dl << DDL_CURSORB_SHIFT) |
@@ -1316,6 +1353,7 @@ static void valleyview_update_wm(struct drm_crtc *crtc)
int plane_sr, cursor_sr;
int ignore_plane_sr, ignore_cursor_sr;
unsigned int enabled = 0;
+ bool cxsr_enabled;
vlv_update_drain_latency(dev);
@@ -1342,10 +1380,10 @@ static void valleyview_update_wm(struct drm_crtc *crtc)
&valleyview_wm_info,
&valleyview_cursor_wm_info,
&ignore_plane_sr, &cursor_sr)) {
- I915_WRITE(FW_BLC_SELF_VLV, FW_CSPWRDWNEN);
+ cxsr_enabled = true;
} else {
- I915_WRITE(FW_BLC_SELF_VLV,
- I915_READ(FW_BLC_SELF_VLV) & ~FW_CSPWRDWNEN);
+ cxsr_enabled = false;
+ intel_set_memory_cxsr(dev_priv, false);
plane_sr = cursor_sr = 0;
}
@@ -1365,6 +1403,9 @@ static void valleyview_update_wm(struct drm_crtc *crtc)
I915_WRITE(DSPFW3,
(I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) |
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
+
+ if (cxsr_enabled)
+ intel_set_memory_cxsr(dev_priv, true);
}
static void g4x_update_wm(struct drm_crtc *crtc)
@@ -1375,6 +1416,7 @@ static void g4x_update_wm(struct drm_crtc *crtc)
int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
int plane_sr, cursor_sr;
unsigned int enabled = 0;
+ bool cxsr_enabled;
if (g4x_compute_wm0(dev, PIPE_A,
&g4x_wm_info, latency_ns,
@@ -1394,10 +1436,10 @@ static void g4x_update_wm(struct drm_crtc *crtc)
&g4x_wm_info,
&g4x_cursor_wm_info,
&plane_sr, &cursor_sr)) {
- I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+ cxsr_enabled = true;
} else {
- I915_WRITE(FW_BLC_SELF,
- I915_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN);
+ cxsr_enabled = false;
+ intel_set_memory_cxsr(dev_priv, false);
plane_sr = cursor_sr = 0;
}
@@ -1418,6 +1460,9 @@ static void g4x_update_wm(struct drm_crtc *crtc)
I915_WRITE(DSPFW3,
(I915_READ(DSPFW3) & ~(DSPFW_HPLL_SR_EN | DSPFW_CURSOR_SR_MASK)) |
(cursor_sr << DSPFW_CURSOR_SR_SHIFT));
+
+ if (cxsr_enabled)
+ intel_set_memory_cxsr(dev_priv, true);
}
static void i965_update_wm(struct drm_crtc *unused_crtc)
@@ -1427,6 +1472,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
struct drm_crtc *crtc;
int srwm = 1;
int cursor_sr = 16;
+ bool cxsr_enabled;
/* Calc sr entries for one plane configs */
crtc = single_enabled_crtc(dev);
@@ -1468,13 +1514,11 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
DRM_DEBUG_KMS("self-refresh watermark: display plane %d "
"cursor %d\n", srwm, cursor_sr);
- if (IS_CRESTLINE(dev))
- I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+ cxsr_enabled = true;
} else {
+ cxsr_enabled = false;
/* Turn off self refresh if both pipes are enabled */
- if (IS_CRESTLINE(dev))
- I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
- & ~FW_BLC_SELF_EN);
+ intel_set_memory_cxsr(dev_priv, false);
}
DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
@@ -1486,6 +1530,9 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
I915_WRITE(DSPFW2, (8 << 8) | (8 << 0));
/* update cursor SR watermark */
I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
+
+ if (cxsr_enabled)
+ intel_set_memory_cxsr(dev_priv, true);
}
static void i9xx_update_wm(struct drm_crtc *unused_crtc)
@@ -1545,12 +1592,12 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
if (IS_I915GM(dev) && enabled) {
- struct intel_framebuffer *fb;
+ struct drm_i915_gem_object *obj;
- fb = to_intel_framebuffer(enabled->primary->fb);
+ obj = intel_fb_obj(enabled->primary->fb);
/* self-refresh seems busted with untiled */
- if (fb->obj->tiling_mode == I915_TILING_NONE)
+ if (obj->tiling_mode == I915_TILING_NONE)
enabled = NULL;
}
@@ -1560,10 +1607,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
cwm = 2;
/* Play safe and disable self-refresh before adjusting watermarks. */
- if (IS_I945G(dev) || IS_I945GM(dev))
- I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | 0);
- else if (IS_I915GM(dev))
- I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_SELF_EN));
+ intel_set_memory_cxsr(dev_priv, false);
/* Calc sr entries for one plane configs */
if (HAS_FW_BLC(dev) && enabled) {
@@ -1609,17 +1653,8 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
I915_WRITE(FW_BLC, fwater_lo);
I915_WRITE(FW_BLC2, fwater_hi);
- if (HAS_FW_BLC(dev)) {
- if (enabled) {
- if (IS_I945G(dev) || IS_I945GM(dev))
- I915_WRITE(FW_BLC_SELF,
- FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
- else if (IS_I915GM(dev))
- I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_SELF_EN));
- DRM_DEBUG_KMS("memory self refresh enabled\n");
- } else
- DRM_DEBUG_KMS("memory self refresh disabled\n");
- }
+ if (enabled)
+ intel_set_memory_cxsr(dev_priv, true);
}
static void i845_update_wm(struct drm_crtc *unused_crtc)
@@ -2707,10 +2742,11 @@ static void ilk_update_wm(struct drm_crtc *crtc)
ilk_write_wm_values(dev_priv, &results);
}
-static void ilk_update_sprite_wm(struct drm_plane *plane,
- struct drm_crtc *crtc,
- uint32_t sprite_width, int pixel_size,
- bool enabled, bool scaled)
+static void
+ilk_update_sprite_wm(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ uint32_t sprite_width, uint32_t sprite_height,
+ int pixel_size, bool enabled, bool scaled)
{
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -2718,6 +2754,7 @@ static void ilk_update_sprite_wm(struct drm_plane *plane,
intel_plane->wm.enabled = enabled;
intel_plane->wm.scaled = scaled;
intel_plane->wm.horiz_pixels = sprite_width;
+ intel_plane->wm.vert_pixels = sprite_width;
intel_plane->wm.bytes_per_pixel = pixel_size;
/*
@@ -2852,13 +2889,16 @@ void intel_update_watermarks(struct drm_crtc *crtc)
void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
- uint32_t sprite_width, int pixel_size,
+ uint32_t sprite_width,
+ uint32_t sprite_height,
+ int pixel_size,
bool enabled, bool scaled)
{
struct drm_i915_private *dev_priv = plane->dev->dev_private;
if (dev_priv->display.update_sprite_wm)
- dev_priv->display.update_sprite_wm(plane, crtc, sprite_width,
+ dev_priv->display.update_sprite_wm(plane, crtc,
+ sprite_width, sprite_height,
pixel_size, enabled, scaled);
}
@@ -2993,7 +3033,7 @@ static void ironlake_enable_drps(struct drm_device *dev)
I915_READ(0x112e0);
dev_priv->ips.last_time1 = jiffies_to_msecs(jiffies);
dev_priv->ips.last_count2 = I915_READ(0x112f4);
- getrawmonotonic(&dev_priv->ips.last_time2);
+ dev_priv->ips.last_time2 = ktime_get_raw_ns();
spin_unlock_irq(&mchdev_lock);
}
@@ -3147,6 +3187,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
if (val < dev_priv->rps.max_freq_softlimit)
mask |= GEN6_PM_RP_UP_THRESHOLD;
+ mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED);
+ mask &= dev_priv->pm_rps_events;
+
/* IVB and SNB hard hangs on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*/
@@ -3209,6 +3252,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
*/
static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
+
+ /* Latest VLV doesn't need to force the gfx clock */
+ if (dev->pdev->revision >= 0xd) {
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
+ return;
+ }
+
/*
* When we are idle. Drop to min voltage state.
*/
@@ -3242,7 +3293,9 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
mutex_lock(&dev_priv->rps.hw_lock);
if (dev_priv->rps.enabled) {
- if (IS_VALLEYVIEW(dev))
+ if (IS_CHERRYVIEW(dev))
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
+ else if (IS_VALLEYVIEW(dev))
vlv_set_rps_idle(dev_priv);
else
gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
@@ -3340,6 +3393,15 @@ static void gen6_disable_rps(struct drm_device *dev)
gen6_disable_rps_interrupts(dev);
}
+static void cherryview_disable_rps(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE(GEN6_RC_CONTROL, 0);
+
+ gen8_disable_rps_interrupts(dev);
+}
+
static void valleyview_disable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3357,10 +3419,10 @@ static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
else
mode = 0;
}
- DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
- (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
- (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
- (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
+ DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
+ (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
+ (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
+ (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
}
static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6)
@@ -3384,8 +3446,8 @@ static int sanitize_rc6_option(const struct drm_device *dev, int enable_rc6)
mask = INTEL_RC6_ENABLE;
if ((enable_rc6 & mask) != enable_rc6)
- DRM_INFO("Adjusting RC6 mask to %d (requested %d, valid %d)\n",
- enable_rc6 & mask, enable_rc6, mask);
+ DRM_DEBUG_KMS("Adjusting RC6 mask to %d (requested %d, valid %d)\n",
+ enable_rc6 & mask, enable_rc6, mask);
return enable_rc6 & mask;
}
@@ -3411,7 +3473,7 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev)
spin_lock_irq(&dev_priv->irq_lock);
WARN_ON(dev_priv->rps.pm_iir);
- bdw_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+ gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock);
}
@@ -3422,7 +3484,7 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev)
spin_lock_irq(&dev_priv->irq_lock);
WARN_ON(dev_priv->rps.pm_iir);
- snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
+ gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock);
}
@@ -3475,15 +3537,23 @@ static void gen8_enable_rps(struct drm_device *dev)
for_each_ring(ring, dev_priv, unused)
I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
I915_WRITE(GEN6_RC_SLEEP, 0);
- I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
+ if (IS_BROADWELL(dev))
+ I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
+ else
+ I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
/* 3: Enable RC6 */
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
intel_print_rc6_info(dev, rc6_mask);
- I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
- GEN6_RC_CTL_EI_MODE(1) |
- rc6_mask);
+ if (IS_BROADWELL(dev))
+ I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+ GEN7_RC_CTL_TO_MODE |
+ rc6_mask);
+ else
+ I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
+ GEN6_RC_CTL_EI_MODE(1) |
+ rc6_mask);
/* 4 Program defaults and thresholds for RPS*/
I915_WRITE(GEN6_RPNSWREQ,
@@ -3719,7 +3789,57 @@ void gen6_update_ring_freq(struct drm_device *dev)
mutex_unlock(&dev_priv->rps.hw_lock);
}
-int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
+static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
+{
+ u32 val, rp0;
+
+ val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
+ rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK;
+
+ return rp0;
+}
+
+static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
+{
+ u32 val, rpe;
+
+ val = vlv_punit_read(dev_priv, PUNIT_GPU_DUTYCYCLE_REG);
+ rpe = (val >> PUNIT_GPU_DUTYCYCLE_RPE_FREQ_SHIFT) & PUNIT_GPU_DUTYCYCLE_RPE_FREQ_MASK;
+
+ return rpe;
+}
+
+static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
+{
+ u32 val, rp1;
+
+ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+ rp1 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK;
+
+ return rp1;
+}
+
+static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
+{
+ u32 val, rpn;
+
+ val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
+ rpn = (val >> PUNIT_GPU_STATIS_GFX_MIN_FREQ_SHIFT) & PUNIT_GPU_STATUS_GFX_MIN_FREQ_MASK;
+ return rpn;
+}
+
+static int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv)
+{
+ u32 val, rp1;
+
+ val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
+
+ rp1 = (val & FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) >> FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT;
+
+ return rp1;
+}
+
+static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
{
u32 val, rp0;
@@ -3744,7 +3864,7 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv)
return rpe;
}
-int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
+static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
{
return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
}
@@ -3758,6 +3878,35 @@ static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
dev_priv->vlv_pctx->stolen->start);
}
+
+/* Check that the pcbr address is not empty. */
+static void cherryview_check_pctx(struct drm_i915_private *dev_priv)
+{
+ unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
+
+ WARN_ON((pctx_addr >> VLV_PCBR_ADDR_SHIFT) == 0);
+}
+
+static void cherryview_setup_pctx(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long pctx_paddr, paddr;
+ struct i915_gtt *gtt = &dev_priv->gtt;
+ u32 pcbr;
+ int pctx_size = 32*1024;
+
+ WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ pcbr = I915_READ(VLV_PCBR);
+ if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
+ paddr = (dev_priv->mm.stolen_base +
+ (gtt->stolen_size - pctx_size));
+
+ pctx_paddr = (paddr & (~4095));
+ I915_WRITE(VLV_PCBR, pctx_paddr);
+ }
+}
+
static void valleyview_setup_pctx(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3832,6 +3981,11 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
dev_priv->rps.efficient_freq);
+ dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv);
+ DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+ dev_priv->rps.rp1_freq);
+
dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv);
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
@@ -3847,11 +4001,142 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
mutex_unlock(&dev_priv->rps.hw_lock);
}
+static void cherryview_init_gt_powersave(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ cherryview_setup_pctx(dev);
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+
+ dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv);
+ dev_priv->rps.rp0_freq = dev_priv->rps.max_freq;
+ DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.max_freq),
+ dev_priv->rps.max_freq);
+
+ dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv);
+ DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ dev_priv->rps.efficient_freq);
+
+ dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv);
+ DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
+ dev_priv->rps.rp1_freq);
+
+ dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv);
+ DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
+ dev_priv->rps.min_freq);
+
+ /* Preserve min/max settings in case of re-init */
+ if (dev_priv->rps.max_freq_softlimit == 0)
+ dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq;
+
+ if (dev_priv->rps.min_freq_softlimit == 0)
+ dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq;
+
+ mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
static void valleyview_cleanup_gt_powersave(struct drm_device *dev)
{
valleyview_cleanup_pctx(dev);
}
+static void cherryview_enable_rps(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *ring;
+ u32 gtfifodbg, val, rc6_mode = 0, pcbr;
+ int i;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+ gtfifodbg = I915_READ(GTFIFODBG);
+ if (gtfifodbg) {
+ DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
+ gtfifodbg);
+ I915_WRITE(GTFIFODBG, gtfifodbg);
+ }
+
+ cherryview_check_pctx(dev_priv);
+
+ /* 1a & 1b: Get forcewake during program sequence. Although the driver
+ * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
+ gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+ /* 2a: Program RC6 thresholds.*/
+ I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
+ I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */
+ I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */
+
+ for_each_ring(ring, dev_priv, i)
+ I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+ I915_WRITE(GEN6_RC_SLEEP, 0);
+
+ I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
+
+ /* allows RC6 residency counter to work */
+ I915_WRITE(VLV_COUNTER_CONTROL,
+ _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+ VLV_MEDIA_RC6_COUNT_EN |
+ VLV_RENDER_RC6_COUNT_EN));
+
+ /* For now we assume BIOS is allocating and populating the PCBR */
+ pcbr = I915_READ(VLV_PCBR);
+
+ DRM_DEBUG_DRIVER("PCBR offset : 0x%x\n", pcbr);
+
+ /* 3: Enable RC6 */
+ if ((intel_enable_rc6(dev) & INTEL_RC6_ENABLE) &&
+ (pcbr >> VLV_PCBR_ADDR_SHIFT))
+ rc6_mode = GEN6_RC_CTL_EI_MODE(1);
+
+ I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
+
+ /* 4 Program defaults and thresholds for RPS*/
+ I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+ I915_WRITE(GEN6_RP_UP_EI, 66000);
+ I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
+ I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+ /* WaDisablePwrmtrEvent:chv (pre-production hw) */
+ I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff);
+ I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00);
+
+ /* 5: Enable RPS */
+ I915_WRITE(GEN6_RP_CONTROL,
+ GEN6_RP_MEDIA_HW_NORMAL_MODE |
+ GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */
+ GEN6_RP_ENABLE |
+ GEN6_RP_UP_BUSY_AVG |
+ GEN6_RP_DOWN_IDLE_AVG);
+
+ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+
+ DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no");
+ DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+
+ dev_priv->rps.cur_freq = (val >> 8) & 0xff;
+ DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq),
+ dev_priv->rps.cur_freq);
+
+ DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
+ vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
+ dev_priv->rps.efficient_freq);
+
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
+
+ gen8_enable_rps_interrupts(dev);
+
+ gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+}
+
static void valleyview_enable_rps(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3878,6 +4163,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RP_DOWN_EI, 350000);
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 0xf4240);
I915_WRITE(GEN6_RP_CONTROL,
GEN6_RP_MEDIA_TURBO |
@@ -3898,9 +4184,11 @@ static void valleyview_enable_rps(struct drm_device *dev)
/* allows RC6 residency counter to work */
I915_WRITE(VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+ _MASKED_BIT_ENABLE(VLV_MEDIA_RC0_COUNT_EN |
+ VLV_RENDER_RC0_COUNT_EN |
VLV_MEDIA_RC6_COUNT_EN |
VLV_RENDER_RC6_COUNT_EN));
+
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
@@ -4306,18 +4594,16 @@ static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
{
- struct timespec now, diff1;
- u64 diff;
- unsigned long diffms;
+ u64 now, diff, diffms;
u32 count;
assert_spin_locked(&mchdev_lock);
- getrawmonotonic(&now);
- diff1 = timespec_sub(now, dev_priv->ips.last_time2);
+ now = ktime_get_raw_ns();
+ diffms = now - dev_priv->ips.last_time2;
+ do_div(diffms, NSEC_PER_MSEC);
/* Don't divide by 0 */
- diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000;
if (!diffms)
return;
@@ -4660,33 +4946,60 @@ void intel_init_gt_powersave(struct drm_device *dev)
{
i915.enable_rc6 = sanitize_rc6_option(dev, i915.enable_rc6);
- if (IS_VALLEYVIEW(dev))
+ if (IS_CHERRYVIEW(dev))
+ cherryview_init_gt_powersave(dev);
+ else if (IS_VALLEYVIEW(dev))
valleyview_init_gt_powersave(dev);
}
void intel_cleanup_gt_powersave(struct drm_device *dev)
{
- if (IS_VALLEYVIEW(dev))
+ if (IS_CHERRYVIEW(dev))
+ return;
+ else if (IS_VALLEYVIEW(dev))
valleyview_cleanup_gt_powersave(dev);
}
+/**
+ * intel_suspend_gt_powersave - suspend PM work and helper threads
+ * @dev: drm device
+ *
+ * We don't want to disable RC6 or other features here, we just want
+ * to make sure any work we've queued has finished and won't bother
+ * us while we're suspended.
+ */
+void intel_suspend_gt_powersave(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ /* Interrupts should be disabled already to avoid re-arming. */
+ WARN_ON(intel_irqs_enabled(dev_priv));
+
+ flush_delayed_work(&dev_priv->rps.delayed_resume_work);
+
+ cancel_work_sync(&dev_priv->rps.work);
+
+ /* Force GPU to min freq during suspend */
+ gen6_rps_idle(dev_priv);
+}
+
void intel_disable_gt_powersave(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
/* Interrupts should be disabled already to avoid re-arming. */
- WARN_ON(dev->irq_enabled);
+ WARN_ON(intel_irqs_enabled(dev_priv));
if (IS_IRONLAKE_M(dev)) {
ironlake_disable_drps(dev);
ironlake_disable_rc6(dev);
- } else if (IS_GEN6(dev) || IS_GEN7(dev) || IS_BROADWELL(dev)) {
- if (cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work))
- intel_runtime_pm_put(dev_priv);
+ } else if (INTEL_INFO(dev)->gen >= 6) {
+ intel_suspend_gt_powersave(dev);
- cancel_work_sync(&dev_priv->rps.work);
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev))
+ if (IS_CHERRYVIEW(dev))
+ cherryview_disable_rps(dev);
+ else if (IS_VALLEYVIEW(dev))
valleyview_disable_rps(dev);
else
gen6_disable_rps(dev);
@@ -4704,7 +5017,9 @@ static void intel_gen6_powersave_work(struct work_struct *work)
mutex_lock(&dev_priv->rps.hw_lock);
- if (IS_VALLEYVIEW(dev)) {
+ if (IS_CHERRYVIEW(dev)) {
+ cherryview_enable_rps(dev);
+ } else if (IS_VALLEYVIEW(dev)) {
valleyview_enable_rps(dev);
} else if (IS_BROADWELL(dev)) {
gen8_enable_rps(dev);
@@ -4729,7 +5044,7 @@ void intel_enable_gt_powersave(struct drm_device *dev)
ironlake_enable_rc6(dev);
intel_init_emon(dev);
mutex_unlock(&dev->struct_mutex);
- } else if (IS_GEN6(dev) || IS_GEN7(dev) || IS_BROADWELL(dev)) {
+ } else if (INTEL_INFO(dev)->gen >= 6) {
/*
* PCU communication is slow and this doesn't need to be
* done at any specific time, so do this out of our fast path
@@ -4912,11 +5227,9 @@ static void gen6_check_mch_setup(struct drm_device *dev)
uint32_t tmp;
tmp = I915_READ(MCH_SSKPD);
- if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL) {
- DRM_INFO("Wrong MCH_SSKPD value: 0x%08x\n", tmp);
- DRM_INFO("This can cause pipe underruns and display issues.\n");
- DRM_INFO("Please upgrade your BIOS to fix this.\n");
- }
+ if ((tmp & MCH_SSKPD_WM0_MASK) != MCH_SSKPD_WM0_VAL)
+ DRM_DEBUG_KMS("Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n",
+ tmp);
}
static void gen6_init_clock_gating(struct drm_device *dev)
@@ -5102,7 +5415,7 @@ static void gen8_init_clock_gating(struct drm_device *dev)
I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE));
I915_WRITE(_3D_CHICKEN3,
- _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2));
+ _MASKED_BIT_ENABLE(_3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2)));
I915_WRITE(COMMON_SLICE_CHICKEN2,
_MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE));
@@ -5337,10 +5650,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
}
DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
- dev_priv->vlv_cdclk_freq = valleyview_cur_cdclk(dev_priv);
- DRM_DEBUG_DRIVER("Current CD clock rate: %d MHz",
- dev_priv->vlv_cdclk_freq);
-
I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
/* WaDisableEarlyCull:vlv */
@@ -5415,6 +5724,35 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
static void cherryview_init_clock_gating(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 val;
+
+ mutex_lock(&dev_priv->rps.hw_lock);
+ val = vlv_punit_read(dev_priv, CCK_FUSE_REG);
+ mutex_unlock(&dev_priv->rps.hw_lock);
+ switch ((val >> 2) & 0x7) {
+ case 0:
+ case 1:
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_200;
+ dev_priv->mem_freq = 1600;
+ break;
+ case 2:
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_267;
+ dev_priv->mem_freq = 1600;
+ break;
+ case 3:
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_333;
+ dev_priv->mem_freq = 2000;
+ break;
+ case 4:
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_320;
+ dev_priv->mem_freq = 1600;
+ break;
+ case 5:
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_400;
+ dev_priv->mem_freq = 1600;
+ break;
+ }
+ DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
@@ -5655,7 +5993,6 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
- unsigned long irqflags;
/*
* After we re-enable the power well, if we touch VGA register 0x3d5
@@ -5671,21 +6008,8 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
- if (IS_BROADWELL(dev)) {
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
- I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B),
- dev_priv->de_irq_mask[PIPE_B]);
- I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B),
- ~dev_priv->de_irq_mask[PIPE_B] |
- GEN8_PIPE_VBLANK);
- I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C),
- dev_priv->de_irq_mask[PIPE_C]);
- I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C),
- ~dev_priv->de_irq_mask[PIPE_C] |
- GEN8_PIPE_VBLANK);
- POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C));
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
- }
+ if (IS_BROADWELL(dev))
+ gen8_irq_power_well_post_enable(dev_priv);
}
static void hsw_set_power_well(struct drm_i915_private *dev_priv,
@@ -5756,34 +6080,13 @@ static bool i9xx_always_on_power_well_enabled(struct drm_i915_private *dev_priv,
return true;
}
-void __vlv_set_power_well(struct drm_i915_private *dev_priv,
- enum punit_power_well power_well_id, bool enable)
+static void vlv_set_power_well(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well, bool enable)
{
- struct drm_device *dev = dev_priv->dev;
+ enum punit_power_well power_well_id = power_well->data;
u32 mask;
u32 state;
u32 ctrl;
- enum pipe pipe;
-
- if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC) {
- if (enable) {
- /*
- * Enable the CRI clock source so we can get at the
- * display and the reference clock for VGA
- * hotplug / manual detection.
- */
- I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
- DPLL_REFA_CLK_ENABLE_VLV |
- DPLL_INTEGRATED_CRI_CLK_VLV);
- udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
- } else {
- for_each_pipe(pipe)
- assert_pll_disabled(dev_priv, pipe);
- /* Assert common reset */
- I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) &
- ~DPIO_CMNRST);
- }
- }
mask = PUNIT_PWRGT_MASK(power_well_id);
state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
@@ -5811,28 +6114,6 @@ void __vlv_set_power_well(struct drm_i915_private *dev_priv,
out:
mutex_unlock(&dev_priv->rps.hw_lock);
-
- /*
- * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
- * 6. De-assert cmn_reset/side_reset. Same as VLV X0.
- * a. GUnit 0x2110 bit[0] set to 1 (def 0)
- * b. The other bits such as sfr settings / modesel may all
- * be set to 0.
- *
- * This should only be done on init and resume from S3 with
- * both PLLs disabled, or we risk losing DPIO and PLL
- * synchronization.
- */
- if (power_well_id == PUNIT_POWER_WELL_DPIO_CMN_BC && enable)
- I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
-}
-
-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->data;
-
- __vlv_set_power_well(dev_priv, power_well_id, enable);
}
static void vlv_power_well_sync_hw(struct drm_i915_private *dev_priv,
@@ -5924,6 +6205,53 @@ static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
vlv_set_power_well(dev_priv, power_well, false);
}
+static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC);
+
+ /*
+ * Enable the CRI clock source so we can get at the
+ * display and the reference clock for VGA
+ * hotplug / manual detection.
+ */
+ I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
+ DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
+ udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
+
+ vlv_set_power_well(dev_priv, power_well, true);
+
+ /*
+ * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
+ * 6. De-assert cmn_reset/side_reset. Same as VLV X0.
+ * a. GUnit 0x2110 bit[0] set to 1 (def 0)
+ * b. The other bits such as sfr settings / modesel may all
+ * be set to 0.
+ *
+ * This should only be done on init and resume from S3 with
+ * both PLLs disabled, or we risk losing DPIO and PLL
+ * synchronization.
+ */
+ I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
+}
+
+static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ struct drm_device *dev = dev_priv->dev;
+ enum pipe pipe;
+
+ WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC);
+
+ for_each_pipe(pipe)
+ assert_pll_disabled(dev_priv, pipe);
+
+ /* Assert common reset */
+ I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST);
+
+ vlv_set_power_well(dev_priv, power_well, false);
+}
+
static void check_power_well_state(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
@@ -6038,6 +6366,27 @@ int i915_release_power_well(void)
}
EXPORT_SYMBOL_GPL(i915_release_power_well);
+/*
+ * Private interface for the audio driver to get CDCLK in kHz.
+ *
+ * Caller must request power well using i915_request_power_well() prior to
+ * making the call.
+ */
+int i915_get_cdclk_freq(void)
+{
+ struct drm_i915_private *dev_priv;
+
+ if (!hsw_pwr)
+ return -ENODEV;
+
+ dev_priv = container_of(hsw_pwr, struct drm_i915_private,
+ power_domains);
+
+ return intel_ddi_get_cdclk_freq(dev_priv);
+}
+EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
+
+
#define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
#define HSW_ALWAYS_ON_POWER_DOMAINS ( \
@@ -6052,6 +6401,7 @@ EXPORT_SYMBOL_GPL(i915_release_power_well);
BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) | \
BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) | \
BIT(POWER_DOMAIN_PORT_CRT) | \
+ BIT(POWER_DOMAIN_PLLS) | \
BIT(POWER_DOMAIN_INIT))
#define HSW_DISPLAY_POWER_DOMAINS ( \
(POWER_DOMAIN_MASK & ~HSW_ALWAYS_ON_POWER_DOMAINS) | \
@@ -6151,6 +6501,13 @@ static const struct i915_power_well_ops vlv_display_power_well_ops = {
.is_enabled = vlv_power_well_enabled,
};
+static const struct i915_power_well_ops vlv_dpio_cmn_power_well_ops = {
+ .sync_hw = vlv_power_well_sync_hw,
+ .enable = vlv_dpio_cmn_power_well_enable,
+ .disable = vlv_dpio_cmn_power_well_disable,
+ .is_enabled = vlv_power_well_enabled,
+};
+
static const struct i915_power_well_ops vlv_dpio_power_well_ops = {
.sync_hw = vlv_power_well_sync_hw,
.enable = vlv_power_well_enable,
@@ -6211,10 +6568,25 @@ static struct i915_power_well vlv_power_wells[] = {
.name = "dpio-common",
.domains = VLV_DPIO_CMN_BC_POWER_DOMAINS,
.data = PUNIT_POWER_WELL_DPIO_CMN_BC,
- .ops = &vlv_dpio_power_well_ops,
+ .ops = &vlv_dpio_cmn_power_well_ops,
},
};
+static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
+ enum punit_power_well power_well_id)
+{
+ struct i915_power_domains *power_domains = &dev_priv->power_domains;
+ struct i915_power_well *power_well;
+ int i;
+
+ for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
+ if (power_well->data == power_well_id)
+ return power_well;
+ }
+
+ return NULL;
+}
+
#define set_power_wells(power_domains, __power_wells) ({ \
(power_domains)->power_wells = (__power_wells); \
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
@@ -6265,11 +6637,50 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
mutex_unlock(&power_domains->lock);
}
+static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
+{
+ struct i915_power_well *cmn =
+ lookup_power_well(dev_priv, PUNIT_POWER_WELL_DPIO_CMN_BC);
+ struct i915_power_well *disp2d =
+ lookup_power_well(dev_priv, PUNIT_POWER_WELL_DISP2D);
+
+ /* nothing to do if common lane is already off */
+ if (!cmn->ops->is_enabled(dev_priv, cmn))
+ return;
+
+ /* If the display might be already active skip this */
+ if (disp2d->ops->is_enabled(dev_priv, disp2d) &&
+ I915_READ(DPIO_CTL) & DPIO_CMNRST)
+ return;
+
+ DRM_DEBUG_KMS("toggling display PHY side reset\n");
+
+ /* cmnlane needs DPLL registers */
+ disp2d->ops->enable(dev_priv, disp2d);
+
+ /*
+ * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
+ * Need to assert and de-assert PHY SB reset by gating the
+ * common lane power, then un-gating it.
+ * Simply ungating isn't enough to reset the PHY enough to get
+ * ports and lanes running.
+ */
+ cmn->ops->disable(dev_priv, cmn);
+}
+
void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
{
+ struct drm_device *dev = dev_priv->dev;
struct i915_power_domains *power_domains = &dev_priv->power_domains;
power_domains->initializing = true;
+
+ if (IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev)) {
+ mutex_lock(&power_domains->lock);
+ vlv_cmnlane_wa(dev_priv);
+ mutex_unlock(&power_domains->lock);
+ }
+
/* For now, we need the power well to be always enabled. */
intel_display_set_init_power(dev_priv, true);
intel_power_domains_resume(dev_priv);
@@ -6442,7 +6853,7 @@ void intel_init_pm(struct drm_device *dev)
(dev_priv->is_ddr3 == 1) ? "3" : "2",
dev_priv->fsb_freq, dev_priv->mem_freq);
/* Disable CxSR and never update its watermark again */
- pineview_disable_cxsr(dev);
+ intel_set_memory_cxsr(dev_priv, false);
dev_priv->display.update_wm = NULL;
} else
dev_priv->display.update_wm = pineview_update_wm;
@@ -6525,7 +6936,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
return 0;
}
-int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
+static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
int div;
@@ -6547,7 +6958,7 @@ int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div);
}
-int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
+static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
int mul;
@@ -6569,6 +6980,80 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6;
}
+static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+ int div, freq;
+
+ switch (dev_priv->rps.cz_freq) {
+ case 200:
+ div = 5;
+ break;
+ case 267:
+ div = 6;
+ break;
+ case 320:
+ case 333:
+ case 400:
+ div = 8;
+ break;
+ default:
+ return -1;
+ }
+
+ freq = (DIV_ROUND_CLOSEST((dev_priv->rps.cz_freq * val), 2 * div) / 2);
+
+ return freq;
+}
+
+static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
+{
+ int mul, opcode;
+
+ switch (dev_priv->rps.cz_freq) {
+ case 200:
+ mul = 5;
+ break;
+ case 267:
+ mul = 6;
+ break;
+ case 320:
+ case 333:
+ case 400:
+ mul = 8;
+ break;
+ default:
+ return -1;
+ }
+
+ opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2);
+
+ return opcode;
+}
+
+int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
+{
+ int ret = -1;
+
+ if (IS_CHERRYVIEW(dev_priv->dev))
+ ret = chv_gpu_freq(dev_priv, val);
+ else if (IS_VALLEYVIEW(dev_priv->dev))
+ ret = byt_gpu_freq(dev_priv, val);
+
+ return ret;
+}
+
+int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
+{
+ int ret = -1;
+
+ if (IS_CHERRYVIEW(dev_priv->dev))
+ ret = chv_freq_opcode(dev_priv, val);
+ else if (IS_VALLEYVIEW(dev_priv->dev))
+ ret = byt_freq_opcode(dev_priv, val);
+
+ return ret;
+}
+
void intel_pm_setup(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6579,5 +7064,5 @@ void intel_pm_setup(struct drm_device *dev)
intel_gen6_powersave_work);
dev_priv->pm.suspended = false;
- dev_priv->pm.irqs_disabled = false;
+ dev_priv->pm._irqs_disabled = false;
}
diff --git a/drivers/gpu/drm/i915/intel_renderstate.h b/drivers/gpu/drm/i915/intel_renderstate.h
index a5e783a9928a..fd4f66231d30 100644
--- a/drivers/gpu/drm/i915/intel_renderstate.h
+++ b/drivers/gpu/drm/i915/intel_renderstate.h
@@ -28,7 +28,6 @@
struct intel_renderstate_rodata {
const u32 *reloc;
- const u32 reloc_items;
const u32 *batch;
const u32 batch_items;
};
@@ -40,7 +39,6 @@ extern const struct intel_renderstate_rodata gen8_null_state;
#define RO_RENDERSTATE(_g) \
const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
.reloc = gen ## _g ## _null_state_relocs, \
- .reloc_items = sizeof(gen ## _g ## _null_state_relocs)/4, \
.batch = gen ## _g ## _null_state_batch, \
.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
}
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.c b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
index 740538ad0977..56c1429d8a60 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
@@ -6,6 +6,7 @@ static const u32 gen6_null_state_relocs[] = {
0x0000002c,
0x000001e0,
0x000001e4,
+ -1,
};
static const u32 gen6_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
index 6fa7ff2a1298..419e35a7b0ff 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
@@ -5,6 +5,7 @@ static const u32 gen7_null_state_relocs[] = {
0x00000010,
0x00000018,
0x000001ec,
+ -1,
};
static const u32 gen7_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
index 5c875615d42a..75ef1b5de45c 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
@@ -5,6 +5,7 @@ static const u32 gen8_null_state_relocs[] = {
0x00000050,
0x00000060,
0x000003ec,
+ -1,
};
static const u32 gen8_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 279488addf3f..16371a444426 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -48,9 +48,8 @@ static inline int __ring_space(int head, int tail, int size)
return space;
}
-static inline int ring_space(struct intel_engine_cs *ring)
+static inline int ring_space(struct intel_ringbuffer *ringbuf)
{
- struct intel_ringbuffer *ringbuf = ring->buffer;
return __ring_space(ringbuf->head & HEAD_ADDR, ringbuf->tail, ringbuf->size);
}
@@ -381,6 +380,27 @@ gen7_render_ring_flush(struct intel_engine_cs *ring,
}
static int
+gen8_emit_pipe_control(struct intel_engine_cs *ring,
+ u32 flags, u32 scratch_addr)
+{
+ int ret;
+
+ ret = intel_ring_begin(ring, 6);
+ if (ret)
+ return ret;
+
+ intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
+ intel_ring_emit(ring, flags);
+ intel_ring_emit(ring, scratch_addr);
+ intel_ring_emit(ring, 0);
+ intel_ring_emit(ring, 0);
+ intel_ring_emit(ring, 0);
+ intel_ring_advance(ring);
+
+ return 0;
+}
+
+static int
gen8_render_ring_flush(struct intel_engine_cs *ring,
u32 invalidate_domains, u32 flush_domains)
{
@@ -403,22 +423,17 @@ gen8_render_ring_flush(struct intel_engine_cs *ring,
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_QW_WRITE;
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
- }
-
- ret = intel_ring_begin(ring, 6);
- if (ret)
- return ret;
- intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6));
- intel_ring_emit(ring, flags);
- intel_ring_emit(ring, scratch_addr);
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, 0);
- intel_ring_emit(ring, 0);
- intel_ring_advance(ring);
-
- return 0;
+ /* WaCsStallBeforeStateCacheInvalidate:bdw,chv */
+ ret = gen8_emit_pipe_control(ring,
+ PIPE_CONTROL_CS_STALL |
+ PIPE_CONTROL_STALL_AT_SCOREBOARD,
+ 0);
+ if (ret)
+ return ret;
+ }
+ return gen8_emit_pipe_control(ring, flags, scratch_addr);
}
static void ring_write_tail(struct intel_engine_cs *ring,
@@ -517,6 +532,9 @@ static int init_ring_common(struct intel_engine_cs *ring)
else
ring_setup_phys_status_page(ring);
+ /* Enforce ordering by reading HEAD register back */
+ I915_READ_HEAD(ring);
+
/* Initialize the ring. This must happen _after_ we've cleared the ring
* registers with the above sequence (the readback of the HEAD registers
* also enforces ordering), otherwise the hw might lose the new ring
@@ -545,7 +563,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
else {
ringbuf->head = I915_READ_HEAD(ring);
ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
- ringbuf->space = ring_space(ring);
+ ringbuf->space = ring_space(ringbuf);
ringbuf->last_retired_head = -1;
}
@@ -604,6 +622,8 @@ static int init_render_ring(struct intel_engine_cs *ring)
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = init_ring_common(ring);
+ if (ret)
+ return ret;
/* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
if (INTEL_INFO(dev)->gen >= 4 && INTEL_INFO(dev)->gen < 7)
@@ -658,6 +678,13 @@ static int init_render_ring(struct intel_engine_cs *ring)
static void render_ring_cleanup(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->semaphore_obj) {
+ i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj);
+ drm_gem_object_unreference(&dev_priv->semaphore_obj->base);
+ dev_priv->semaphore_obj = NULL;
+ }
if (ring->scratch.obj == NULL)
return;
@@ -671,29 +698,96 @@ static void render_ring_cleanup(struct intel_engine_cs *ring)
ring->scratch.obj = NULL;
}
+static int gen8_rcs_signal(struct intel_engine_cs *signaller,
+ unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 8
+ struct drm_device *dev = signaller->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *waiter;
+ int i, ret, num_rings;
+
+ num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+ num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+ ret = intel_ring_begin(signaller, num_dwords);
+ if (ret)
+ return ret;
+
+ for_each_ring(waiter, dev_priv, i) {
+ u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
+ if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+ continue;
+
+ intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
+ intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
+ PIPE_CONTROL_QW_WRITE |
+ PIPE_CONTROL_FLUSH_ENABLE);
+ intel_ring_emit(signaller, lower_32_bits(gtt_offset));
+ intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, 0);
+ intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+ MI_SEMAPHORE_TARGET(waiter->id));
+ intel_ring_emit(signaller, 0);
+ }
+
+ return 0;
+}
+
+static int gen8_xcs_signal(struct intel_engine_cs *signaller,
+ unsigned int num_dwords)
+{
+#define MBOX_UPDATE_DWORDS 6
+ struct drm_device *dev = signaller->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_engine_cs *waiter;
+ int i, ret, num_rings;
+
+ num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+ num_dwords += (num_rings-1) * MBOX_UPDATE_DWORDS;
+#undef MBOX_UPDATE_DWORDS
+
+ ret = intel_ring_begin(signaller, num_dwords);
+ if (ret)
+ return ret;
+
+ for_each_ring(waiter, dev_priv, i) {
+ u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
+ if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
+ continue;
+
+ intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
+ MI_FLUSH_DW_OP_STOREDW);
+ intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
+ MI_FLUSH_DW_USE_GTT);
+ intel_ring_emit(signaller, upper_32_bits(gtt_offset));
+ intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+ intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
+ MI_SEMAPHORE_TARGET(waiter->id));
+ intel_ring_emit(signaller, 0);
+ }
+
+ return 0;
+}
+
static int gen6_signal(struct intel_engine_cs *signaller,
unsigned int num_dwords)
{
struct drm_device *dev = signaller->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *useless;
- int i, ret;
+ int i, ret, num_rings;
- /* NB: In order to be able to do semaphore MBOX updates for varying
- * number of rings, it's easiest if we round up each individual update
- * to a multiple of 2 (since ring updates must always be a multiple of
- * 2) even though the actual update only requires 3 dwords.
- */
-#define MBOX_UPDATE_DWORDS 4
- if (i915_semaphore_is_enabled(dev))
- num_dwords += ((I915_NUM_RINGS-1) * MBOX_UPDATE_DWORDS);
- else
- return intel_ring_begin(signaller, num_dwords);
+#define MBOX_UPDATE_DWORDS 3
+ num_rings = hweight32(INTEL_INFO(dev)->ring_mask);
+ num_dwords += round_up((num_rings-1) * MBOX_UPDATE_DWORDS, 2);
+#undef MBOX_UPDATE_DWORDS
ret = intel_ring_begin(signaller, num_dwords);
if (ret)
return ret;
-#undef MBOX_UPDATE_DWORDS
for_each_ring(useless, dev_priv, i) {
u32 mbox_reg = signaller->semaphore.mbox.signal[i];
@@ -701,15 +795,13 @@ static int gen6_signal(struct intel_engine_cs *signaller,
intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(signaller, mbox_reg);
intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
- intel_ring_emit(signaller, MI_NOOP);
- } else {
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
- intel_ring_emit(signaller, MI_NOOP);
}
}
+ /* If num_dwords was rounded, make sure the tail pointer is correct */
+ if (num_rings % 2 == 0)
+ intel_ring_emit(signaller, MI_NOOP);
+
return 0;
}
@@ -727,7 +819,11 @@ gen6_add_request(struct intel_engine_cs *ring)
{
int ret;
- ret = ring->semaphore.signal(ring, 4);
+ if (ring->semaphore.signal)
+ ret = ring->semaphore.signal(ring, 4);
+ else
+ ret = intel_ring_begin(ring, 4);
+
if (ret)
return ret;
@@ -754,6 +850,32 @@ static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev,
* @signaller - ring which has, or will signal
* @seqno - seqno which the waiter will block on
*/
+
+static int
+gen8_ring_sync(struct intel_engine_cs *waiter,
+ struct intel_engine_cs *signaller,
+ u32 seqno)
+{
+ struct drm_i915_private *dev_priv = waiter->dev->dev_private;
+ int ret;
+
+ ret = intel_ring_begin(waiter, 4);
+ if (ret)
+ return ret;
+
+ intel_ring_emit(waiter, MI_SEMAPHORE_WAIT |
+ MI_SEMAPHORE_GLOBAL_GTT |
+ MI_SEMAPHORE_POLL |
+ MI_SEMAPHORE_SAD_GTE_SDD);
+ intel_ring_emit(waiter, seqno);
+ intel_ring_emit(waiter,
+ lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+ intel_ring_emit(waiter,
+ upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id)));
+ intel_ring_advance(waiter);
+ return 0;
+}
+
static int
gen6_ring_sync(struct intel_engine_cs *waiter,
struct intel_engine_cs *signaller,
@@ -901,7 +1023,7 @@ gen5_ring_get_irq(struct intel_engine_cs *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (ring->irq_refcount++ == 0)
- ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask);
+ gen5_enable_gt_irq(dev_priv, ring->irq_enable_mask);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
return true;
@@ -916,7 +1038,7 @@ gen5_ring_put_irq(struct intel_engine_cs *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (--ring->irq_refcount == 0)
- ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask);
+ gen5_disable_gt_irq(dev_priv, ring->irq_enable_mask);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
}
@@ -1109,7 +1231,7 @@ gen6_ring_get_irq(struct intel_engine_cs *ring)
GT_PARITY_ERROR(dev)));
else
I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
- ilk_enable_gt_irq(dev_priv, ring->irq_enable_mask);
+ gen5_enable_gt_irq(dev_priv, ring->irq_enable_mask);
}
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
@@ -1129,7 +1251,7 @@ gen6_ring_put_irq(struct intel_engine_cs *ring)
I915_WRITE_IMR(ring, ~GT_PARITY_ERROR(dev));
else
I915_WRITE_IMR(ring, ~0);
- ilk_disable_gt_irq(dev_priv, ring->irq_enable_mask);
+ gen5_disable_gt_irq(dev_priv, ring->irq_enable_mask);
}
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
}
@@ -1147,7 +1269,7 @@ hsw_vebox_get_irq(struct intel_engine_cs *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (ring->irq_refcount++ == 0) {
I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
- snb_enable_pm_irq(dev_priv, ring->irq_enable_mask);
+ gen6_enable_pm_irq(dev_priv, ring->irq_enable_mask);
}
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
@@ -1167,7 +1289,7 @@ hsw_vebox_put_irq(struct intel_engine_cs *ring)
spin_lock_irqsave(&dev_priv->irq_lock, flags);
if (--ring->irq_refcount == 0) {
I915_WRITE_IMR(ring, ~0);
- snb_disable_pm_irq(dev_priv, ring->irq_enable_mask);
+ gen6_disable_pm_irq(dev_priv, ring->irq_enable_mask);
}
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
}
@@ -1329,6 +1451,7 @@ static int init_status_page(struct intel_engine_cs *ring)
struct drm_i915_gem_object *obj;
if ((obj = ring->status_page.obj) == NULL) {
+ unsigned flags;
int ret;
obj = i915_gem_alloc_object(ring->dev, 4096);
@@ -1341,7 +1464,20 @@ static int init_status_page(struct intel_engine_cs *ring)
if (ret)
goto err_unref;
- ret = i915_gem_obj_ggtt_pin(obj, 4096, 0);
+ flags = 0;
+ if (!HAS_LLC(ring->dev))
+ /* On g33, we cannot place HWS above 256MiB, so
+ * restrict its pinning to the low mappable arena.
+ * Though this restriction is not documented for
+ * gen4, gen5, or byt, they also behave similarly
+ * and hang if the HWS is placed at the top of the
+ * GTT. To generalise, it appears that all !llc
+ * platforms have issues with us placing the HWS
+ * above the mappable region (even though we never
+ * actualy map it).
+ */
+ flags |= PIN_MAPPABLE;
+ ret = i915_gem_obj_ggtt_pin(obj, 4096, flags);
if (ret) {
err_unref:
drm_gem_object_unreference(&obj->base);
@@ -1378,15 +1514,25 @@ static int init_phys_status_page(struct intel_engine_cs *ring)
return 0;
}
-static int allocate_ring_buffer(struct intel_engine_cs *ring)
+static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf)
+{
+ if (!ringbuf->obj)
+ return;
+
+ iounmap(ringbuf->virtual_start);
+ i915_gem_object_ggtt_unpin(ringbuf->obj);
+ drm_gem_object_unreference(&ringbuf->obj->base);
+ ringbuf->obj = NULL;
+}
+
+static int intel_alloc_ringbuffer_obj(struct drm_device *dev,
+ struct intel_ringbuffer *ringbuf)
{
- struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_ringbuffer *ringbuf = ring->buffer;
struct drm_i915_gem_object *obj;
int ret;
- if (intel_ring_initialized(ring))
+ if (ringbuf->obj)
return 0;
obj = NULL;
@@ -1397,6 +1543,9 @@ static int allocate_ring_buffer(struct intel_engine_cs *ring)
if (obj == NULL)
return -ENOMEM;
+ /* mark ring buffers as read-only from GPU side by default */
+ obj->gt_ro = 1;
+
ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE);
if (ret)
goto err_unref;
@@ -1455,7 +1604,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
goto error;
}
- ret = allocate_ring_buffer(ring);
+ ret = intel_alloc_ringbuffer_obj(dev, ringbuf);
if (ret) {
DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", ring->name, ret);
goto error;
@@ -1496,11 +1645,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
intel_stop_ring_buffer(ring);
WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0);
- iounmap(ringbuf->virtual_start);
-
- i915_gem_object_ggtt_unpin(ringbuf->obj);
- drm_gem_object_unreference(&ringbuf->obj->base);
- ringbuf->obj = NULL;
+ intel_destroy_ringbuffer_obj(ringbuf);
ring->preallocated_lazy_request = NULL;
ring->outstanding_lazy_seqno = 0;
@@ -1526,7 +1671,7 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
ringbuf->head = ringbuf->last_retired_head;
ringbuf->last_retired_head = -1;
- ringbuf->space = ring_space(ring);
+ ringbuf->space = ring_space(ringbuf);
if (ringbuf->space >= n)
return 0;
}
@@ -1549,7 +1694,7 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
ringbuf->head = ringbuf->last_retired_head;
ringbuf->last_retired_head = -1;
- ringbuf->space = ring_space(ring);
+ ringbuf->space = ring_space(ringbuf);
return 0;
}
@@ -1578,7 +1723,7 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n)
trace_i915_ring_wait_begin(ring);
do {
ringbuf->head = I915_READ_HEAD(ring);
- ringbuf->space = ring_space(ring);
+ ringbuf->space = ring_space(ringbuf);
if (ringbuf->space >= n) {
ret = 0;
break;
@@ -1630,7 +1775,7 @@ static int intel_wrap_ring_buffer(struct intel_engine_cs *ring)
iowrite32(MI_NOOP, virt++);
ringbuf->tail = 0;
- ringbuf->space = ring_space(ring);
+ ringbuf->space = ring_space(ringbuf);
return 0;
}
@@ -1746,14 +1891,15 @@ int intel_ring_cacheline_align(struct intel_engine_cs *ring)
void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno)
{
- struct drm_i915_private *dev_priv = ring->dev->dev_private;
+ struct drm_device *dev = ring->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
BUG_ON(ring->outstanding_lazy_seqno);
- if (INTEL_INFO(ring->dev)->gen >= 6) {
+ if (INTEL_INFO(dev)->gen == 6 || INTEL_INFO(dev)->gen == 7) {
I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
I915_WRITE(RING_SYNC_1(ring->mmio_base), 0);
- if (HAS_VEBOX(ring->dev))
+ if (HAS_VEBOX(dev))
I915_WRITE(RING_SYNC_2(ring->mmio_base), 0);
}
@@ -1941,45 +2087,74 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+ struct drm_i915_gem_object *obj;
+ int ret;
ring->name = "render ring";
ring->id = RCS;
ring->mmio_base = RENDER_RING_BASE;
- if (INTEL_INFO(dev)->gen >= 6) {
+ if (INTEL_INFO(dev)->gen >= 8) {
+ if (i915_semaphore_is_enabled(dev)) {
+ obj = i915_gem_alloc_object(dev, 4096);
+ if (obj == NULL) {
+ DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n");
+ i915.semaphores = 0;
+ } else {
+ i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
+ ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_NONBLOCK);
+ if (ret != 0) {
+ drm_gem_object_unreference(&obj->base);
+ DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n");
+ i915.semaphores = 0;
+ } else
+ dev_priv->semaphore_obj = obj;
+ }
+ }
+ ring->add_request = gen6_add_request;
+ ring->flush = gen8_render_ring_flush;
+ ring->irq_get = gen8_ring_get_irq;
+ ring->irq_put = gen8_ring_put_irq;
+ ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
+ ring->get_seqno = gen6_ring_get_seqno;
+ ring->set_seqno = ring_set_seqno;
+ if (i915_semaphore_is_enabled(dev)) {
+ WARN_ON(!dev_priv->semaphore_obj);
+ ring->semaphore.sync_to = gen8_ring_sync;
+ ring->semaphore.signal = gen8_rcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
+ }
+ } else if (INTEL_INFO(dev)->gen >= 6) {
ring->add_request = gen6_add_request;
ring->flush = gen7_render_ring_flush;
if (INTEL_INFO(dev)->gen == 6)
ring->flush = gen6_render_ring_flush;
- if (INTEL_INFO(dev)->gen >= 8) {
- ring->flush = gen8_render_ring_flush;
- ring->irq_get = gen8_ring_get_irq;
- ring->irq_put = gen8_ring_put_irq;
- } else {
- ring->irq_get = gen6_ring_get_irq;
- ring->irq_put = gen6_ring_put_irq;
- }
+ ring->irq_get = gen6_ring_get_irq;
+ ring->irq_put = gen6_ring_put_irq;
ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
ring->get_seqno = gen6_ring_get_seqno;
ring->set_seqno = ring_set_seqno;
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- /*
- * The current semaphore is only applied on pre-gen8 platform.
- * And there is no VCS2 ring on the pre-gen8 platform. So the
- * semaphore between RCS and VCS2 is initialized as INVALID.
- * Gen8 will initialize the sema between VCS2 and RCS later.
- */
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
- ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
- ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ /*
+ * The current semaphore is only applied on pre-gen8
+ * platform. And there is no VCS2 ring on the pre-gen8
+ * platform. So the semaphore between RCS and VCS2 is
+ * initialized as INVALID. Gen8 will initialize the
+ * sema between VCS2 and RCS later.
+ */
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE;
+ ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VRSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BRSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VERSYNC;
+ ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+ }
} else if (IS_GEN5(dev)) {
ring->add_request = pc_render_add_request;
ring->flush = gen4_render_ring_flush;
@@ -2007,6 +2182,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->irq_enable_mask = I915_USER_INTERRUPT;
}
ring->write_tail = ring_write_tail;
+
if (IS_HASWELL(dev))
ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer;
else if (IS_GEN8(dev))
@@ -2024,9 +2200,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
/* Workaround batchbuffer to combat CS tlb bug. */
if (HAS_BROKEN_CS_TLB(dev)) {
- struct drm_i915_gem_object *obj;
- int ret;
-
obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT);
if (obj == NULL) {
DRM_ERROR("Failed to allocate batch bo\n");
@@ -2157,31 +2330,32 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer =
gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen8_ring_sync;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
+ }
} else {
ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
ring->irq_get = gen6_ring_get_irq;
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer =
gen6_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
+ ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
+ ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+ }
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- /*
- * The current semaphore is only applied on pre-gen8 platform.
- * And there is no VCS2 ring on the pre-gen8 platform. So the
- * semaphore between VCS and VCS2 is initialized as INVALID.
- * Gen8 will initialize the sema between VCS2 and VCS later.
- */
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE;
- ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC;
- ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
} else {
ring->mmio_base = BSD_RING_BASE;
ring->flush = bsd_ring_flush;
@@ -2218,7 +2392,7 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev)
return -EINVAL;
}
- ring->name = "bds2_ring";
+ ring->name = "bsd2 ring";
ring->id = VCS2;
ring->write_tail = ring_write_tail;
@@ -2233,25 +2407,11 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev)
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer =
gen8_ring_dispatch_execbuffer;
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- /*
- * The current semaphore is only applied on the pre-gen8. And there
- * is no bsd2 ring on the pre-gen8. So now the semaphore_register
- * between VCS2 and other ring is initialized as invalid.
- * Gen8 will initialize the sema between VCS2 and other ring later.
- */
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
-
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen8_ring_sync;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
+ }
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
@@ -2277,30 +2437,38 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
ring->irq_get = gen8_ring_get_irq;
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen8_ring_sync;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
+ }
} else {
ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
ring->irq_get = gen6_ring_get_irq;
ring->irq_put = gen6_ring_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.sync_to = gen6_ring_sync;
+ /*
+ * The current semaphore is only applied on pre-gen8
+ * platform. And there is no VCS2 ring on the pre-gen8
+ * platform. So the semaphore between BCS and VCS2 is
+ * initialized as INVALID. Gen8 will initialize the
+ * sema between BCS and VCS2 later.
+ */
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
+ ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
+ ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+ }
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- /*
- * The current semaphore is only applied on pre-gen8 platform. And
- * there is no VCS2 ring on the pre-gen8 platform. So the semaphore
- * between BCS and VCS2 is initialized as INVALID.
- * Gen8 will initialize the sema between BCS and VCS2 later.
- */
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE;
- ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_RBSYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VBSYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC;
- ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
@@ -2327,24 +2495,31 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev)
ring->irq_get = gen8_ring_get_irq;
ring->irq_put = gen8_ring_put_irq;
ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen8_ring_sync;
+ ring->semaphore.signal = gen8_xcs_signal;
+ GEN8_RING_SEMAPHORE_INIT;
+ }
} else {
ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
ring->irq_get = hsw_vebox_get_irq;
ring->irq_put = hsw_vebox_put_irq;
ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+ if (i915_semaphore_is_enabled(dev)) {
+ ring->semaphore.sync_to = gen6_ring_sync;
+ ring->semaphore.signal = gen6_signal;
+ ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
+ ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
+ ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
+ ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
+ ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
+ ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
+ ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
+ ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
+ ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
+ }
}
- ring->semaphore.sync_to = gen6_ring_sync;
- ring->semaphore.signal = gen6_signal;
- ring->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER;
- ring->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV;
- ring->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB;
- ring->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID;
- ring->semaphore.mbox.signal[RCS] = GEN6_RVESYNC;
- ring->semaphore.mbox.signal[VCS] = GEN6_VVESYNC;
- ring->semaphore.mbox.signal[BCS] = GEN6_BVESYNC;
- ring->semaphore.mbox.signal[VECS] = GEN6_NOSYNC;
- ring->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC;
ring->init = init_ring_common;
return intel_init_ring_buffer(dev, ring);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index e72017bdcd7f..70525d0c2c74 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -40,10 +40,37 @@ struct intel_hw_status_page {
#define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
+/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
+ * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
+ */
+#define i915_semaphore_seqno_size sizeof(uint64_t)
+#define GEN8_SIGNAL_OFFSET(__ring, to) \
+ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+ ((__ring)->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
+ (i915_semaphore_seqno_size * (to)))
+
+#define GEN8_WAIT_OFFSET(__ring, from) \
+ (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \
+ ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \
+ (i915_semaphore_seqno_size * (__ring)->id))
+
+#define GEN8_RING_SEMAPHORE_INIT do { \
+ if (!dev_priv->semaphore_obj) { \
+ break; \
+ } \
+ ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(ring, RCS); \
+ ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(ring, VCS); \
+ ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(ring, BCS); \
+ ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(ring, VECS); \
+ ring->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET(ring, VCS2); \
+ ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \
+ } while(0)
+
enum intel_ring_hangcheck_action {
HANGCHECK_IDLE = 0,
HANGCHECK_WAIT,
HANGCHECK_ACTIVE,
+ HANGCHECK_ACTIVE_LOOP,
HANGCHECK_KICK,
HANGCHECK_HUNG,
};
@@ -52,6 +79,7 @@ enum intel_ring_hangcheck_action {
struct intel_ring_hangcheck {
u64 acthd;
+ u64 max_acthd;
u32 seqno;
int score;
enum intel_ring_hangcheck_action action;
@@ -127,15 +155,55 @@ struct intel_engine_cs {
#define I915_DISPATCH_PINNED 0x2
void (*cleanup)(struct intel_engine_cs *ring);
+ /* GEN8 signal/wait table - never trust comments!
+ * signal to signal to signal to signal to signal to
+ * RCS VCS BCS VECS VCS2
+ * --------------------------------------------------------------------
+ * RCS | NOP (0x00) | VCS (0x08) | BCS (0x10) | VECS (0x18) | VCS2 (0x20) |
+ * |-------------------------------------------------------------------
+ * VCS | RCS (0x28) | NOP (0x30) | BCS (0x38) | VECS (0x40) | VCS2 (0x48) |
+ * |-------------------------------------------------------------------
+ * BCS | RCS (0x50) | VCS (0x58) | NOP (0x60) | VECS (0x68) | VCS2 (0x70) |
+ * |-------------------------------------------------------------------
+ * VECS | RCS (0x78) | VCS (0x80) | BCS (0x88) | NOP (0x90) | VCS2 (0x98) |
+ * |-------------------------------------------------------------------
+ * VCS2 | RCS (0xa0) | VCS (0xa8) | BCS (0xb0) | VECS (0xb8) | NOP (0xc0) |
+ * |-------------------------------------------------------------------
+ *
+ * Generalization:
+ * f(x, y) := (x->id * NUM_RINGS * seqno_size) + (seqno_size * y->id)
+ * ie. transpose of g(x, y)
+ *
+ * sync from sync from sync from sync from sync from
+ * RCS VCS BCS VECS VCS2
+ * --------------------------------------------------------------------
+ * RCS | NOP (0x00) | VCS (0x28) | BCS (0x50) | VECS (0x78) | VCS2 (0xa0) |
+ * |-------------------------------------------------------------------
+ * VCS | RCS (0x08) | NOP (0x30) | BCS (0x58) | VECS (0x80) | VCS2 (0xa8) |
+ * |-------------------------------------------------------------------
+ * BCS | RCS (0x10) | VCS (0x38) | NOP (0x60) | VECS (0x88) | VCS2 (0xb0) |
+ * |-------------------------------------------------------------------
+ * VECS | RCS (0x18) | VCS (0x40) | BCS (0x68) | NOP (0x90) | VCS2 (0xb8) |
+ * |-------------------------------------------------------------------
+ * VCS2 | RCS (0x20) | VCS (0x48) | BCS (0x70) | VECS (0x98) | NOP (0xc0) |
+ * |-------------------------------------------------------------------
+ *
+ * Generalization:
+ * g(x, y) := (y->id * NUM_RINGS * seqno_size) + (seqno_size * x->id)
+ * ie. transpose of f(x, y)
+ */
struct {
u32 sync_seqno[I915_NUM_RINGS-1];
- struct {
- /* our mbox written by others */
- u32 wait[I915_NUM_RINGS];
- /* mboxes this ring signals to */
- u32 signal[I915_NUM_RINGS];
- } mbox;
+ union {
+ struct {
+ /* our mbox written by others */
+ u32 wait[I915_NUM_RINGS];
+ /* mboxes this ring signals to */
+ u32 signal[I915_NUM_RINGS];
+ } mbox;
+ u64 signal_ggtt[I915_NUM_RINGS];
+ };
/* AKA wait() */
int (*sync_to)(struct intel_engine_cs *ring,
@@ -238,9 +306,11 @@ intel_ring_sync_index(struct intel_engine_cs *ring,
int idx;
/*
- * cs -> 0 = vcs, 1 = bcs
- * vcs -> 0 = bcs, 1 = cs,
- * bcs -> 0 = cs, 1 = vcs.
+ * rcs -> 0 = vcs, 1 = bcs, 2 = vecs, 3 = vcs2;
+ * vcs -> 0 = bcs, 1 = vecs, 2 = vcs2, 3 = rcs;
+ * bcs -> 0 = vecs, 1 = vcs2. 2 = rcs, 3 = vcs;
+ * vecs -> 0 = vcs2, 1 = rcs, 2 = vcs, 3 = bcs;
+ * vcs2 -> 0 = rcs, 1 = vcs, 2 = bcs, 3 = vecs;
*/
idx = (other - ring) - 1;
@@ -318,9 +388,9 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev);
u64 intel_ring_get_active_head(struct intel_engine_cs *ring);
void intel_ring_setup_status_page(struct intel_engine_cs *ring);
-static inline u32 intel_ring_get_tail(struct intel_engine_cs *ring)
+static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
{
- return ring->buffer->tail;
+ return ringbuf->tail;
}
static inline u32 intel_ring_get_seqno(struct intel_engine_cs *ring)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 20375cc7f82d..9350edd6728d 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2433,7 +2433,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
connector->base.unregister = intel_sdvo_connector_unregister;
intel_connector_attach_encoder(&connector->base, &encoder->base);
- ret = drm_sysfs_connector_add(drm_connector);
+ ret = drm_connector_register(drm_connector);
if (ret < 0)
goto err1;
@@ -2446,7 +2446,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
return 0;
err2:
- drm_sysfs_connector_remove(drm_connector);
+ drm_connector_unregister(drm_connector);
err1:
drm_connector_cleanup(drm_connector);
@@ -2559,7 +2559,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
return true;
err:
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
intel_sdvo_destroy(connector);
return false;
}
@@ -2638,7 +2638,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
return true;
err:
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
intel_sdvo_destroy(connector);
return false;
}
@@ -2711,7 +2711,7 @@ static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
list_for_each_entry_safe(connector, tmp,
&dev->mode_config.connector_list, head) {
if (intel_attached_encoder(connector) == &intel_sdvo->base) {
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
intel_sdvo_destroy(connector);
}
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 1b66ddcdfb33..168c6652cda1 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -218,7 +218,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
sprctl |= SP_ENABLE;
- intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true,
+ intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
+ pixel_size, true,
src_w != crtc_w || src_h != crtc_h);
/* Sizes are 0 based */
@@ -283,7 +284,7 @@ vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
if (atomic_update)
intel_pipe_update_end(intel_crtc, start_vbl_count);
- intel_update_sprite_watermarks(dplane, crtc, 0, 0, false, false);
+ intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
}
static int
@@ -406,7 +407,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
sprctl |= SPRITE_PIPE_CSC_ENABLE;
- intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true,
+ intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
+ true,
src_w != crtc_w || src_h != crtc_h);
/* Sizes are 0 based */
@@ -486,7 +488,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
*/
intel_wait_for_vblank(dev, pipe);
- intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
+ intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
}
static int
@@ -606,7 +608,8 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
dvscntr |= DVS_ENABLE;
- intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true,
+ intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
+ pixel_size, true,
src_w != crtc_w || src_h != crtc_h);
/* Sizes are 0 based */
@@ -681,7 +684,7 @@ ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
*/
intel_wait_for_vblank(dev, pipe);
- intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
+ intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
}
static void
@@ -691,6 +694,14 @@ intel_post_enable_primary(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
/*
+ * BDW signals flip done immediately if the plane
+ * is disabled, even if the plane enable is already
+ * armed to occur at the next vblank :(
+ */
+ if (IS_BROADWELL(dev))
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
+
+ /*
* FIXME IPS should be fine as long as one plane is
* enabled, but in practice it seems to have problems
* when going from primary only to sprite only and vice
@@ -811,6 +822,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_device *dev = plane->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane = to_intel_plane(plane);
+ enum pipe pipe = intel_crtc->pipe;
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb->obj;
struct drm_i915_gem_object *old_obj = intel_plane->obj;
@@ -998,6 +1010,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
*/
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ i915_gem_track_fb(old_obj, obj,
+ INTEL_FRONTBUFFER_SPRITE(pipe));
mutex_unlock(&dev->struct_mutex);
if (ret)
@@ -1031,6 +1045,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
else
intel_plane->disable_plane(plane, crtc);
+ intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
+
if (!primary_was_enabled && primary_enabled)
intel_post_enable_primary(crtc);
}
@@ -1060,6 +1076,7 @@ intel_disable_plane(struct drm_plane *plane)
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_crtc *intel_crtc;
+ enum pipe pipe;
if (!plane->fb)
return 0;
@@ -1068,6 +1085,7 @@ intel_disable_plane(struct drm_plane *plane)
return -EINVAL;
intel_crtc = to_intel_crtc(plane->crtc);
+ pipe = intel_crtc->pipe;
if (intel_crtc->active) {
bool primary_was_enabled = intel_crtc->primary_enabled;
@@ -1086,6 +1104,8 @@ intel_disable_plane(struct drm_plane *plane)
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(intel_plane->obj);
+ i915_gem_track_fb(intel_plane->obj, NULL,
+ INTEL_FRONTBUFFER_SPRITE(pipe));
mutex_unlock(&dev->struct_mutex);
intel_plane->obj = NULL;
@@ -1106,7 +1126,6 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_intel_sprite_colorkey *set = data;
- struct drm_mode_object *obj;
struct drm_plane *plane;
struct intel_plane *intel_plane;
int ret = 0;
@@ -1120,13 +1139,12 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
- if (!obj) {
+ plane = drm_plane_find(dev, set->plane_id);
+ if (!plane) {
ret = -ENOENT;
goto out_unlock;
}
- plane = obj_to_plane(obj);
intel_plane = to_intel_plane(plane);
ret = intel_plane->update_colorkey(plane, set);
@@ -1139,7 +1157,6 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_intel_sprite_colorkey *get = data;
- struct drm_mode_object *obj;
struct drm_plane *plane;
struct intel_plane *intel_plane;
int ret = 0;
@@ -1149,13 +1166,12 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
- if (!obj) {
+ plane = drm_plane_find(dev, get->plane_id);
+ if (!plane) {
ret = -ENOENT;
goto out_unlock;
}
- plane = obj_to_plane(obj);
intel_plane = to_intel_plane(plane);
intel_plane->get_colorkey(plane, get);
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 67c6c9a2eb1c..e211eef4b7e4 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1680,5 +1680,5 @@ intel_tv_init(struct drm_device *dev)
drm_object_attach_property(&connector->base,
dev->mode_config.tv_bottom_margin_property,
intel_tv->margin[TV_MARGIN_BOTTOM]);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
}
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 4f6fef7ac069..e81bc3bdc533 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -231,8 +231,8 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
}
/* WaRsForcewakeWaitTC0:vlv */
- __gen6_gt_wait_for_thread_c0(dev_priv);
-
+ if (!IS_CHERRYVIEW(dev_priv->dev))
+ __gen6_gt_wait_for_thread_c0(dev_priv);
}
static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
@@ -250,9 +250,10 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
- /* The below doubles as a POSTING_READ */
- gen6_gt_check_fifodbg(dev_priv);
-
+ /* something from same cacheline, but !FORCEWAKE_VLV */
+ __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
+ if (!IS_CHERRYVIEW(dev_priv->dev))
+ gen6_gt_check_fifodbg(dev_priv);
}
static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
@@ -315,7 +316,7 @@ static void gen6_force_wake_timer(unsigned long arg)
intel_runtime_pm_put(dev_priv);
}
-static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
+void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
{
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
@@ -357,16 +358,12 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
dev_priv->uncore.fifo_count =
__raw_i915_read32(dev_priv, GTFIFOCTL) &
GT_FIFO_FREE_ENTRIES_MASK;
- } else {
- dev_priv->uncore.forcewake_count = 0;
- dev_priv->uncore.fw_rendercount = 0;
- dev_priv->uncore.fw_mediacount = 0;
}
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-void intel_uncore_early_sanitize(struct drm_device *dev)
+void intel_uncore_early_sanitize(struct drm_device *dev, bool restore_forcewake)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -389,7 +386,7 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
__raw_i915_write32(dev_priv, GTFIFODBG,
__raw_i915_read32(dev_priv, GTFIFODBG));
- intel_uncore_forcewake_reset(dev, false);
+ intel_uncore_forcewake_reset(dev, restore_forcewake);
}
void intel_uncore_sanitize(struct drm_device *dev)
@@ -469,16 +466,43 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
((reg) < 0x40000 && (reg) != FORCEWAKE)
-#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
- (((reg) >= 0x2000 && (reg) < 0x4000) ||\
- ((reg) >= 0x5000 && (reg) < 0x8000) ||\
- ((reg) >= 0xB000 && (reg) < 0x12000) ||\
- ((reg) >= 0x2E000 && (reg) < 0x30000))
+#define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end))
-#define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)\
- (((reg) >= 0x12000 && (reg) < 0x14000) ||\
- ((reg) >= 0x22000 && (reg) < 0x24000) ||\
- ((reg) >= 0x30000 && (reg) < 0x40000))
+#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
+ (REG_RANGE((reg), 0x2000, 0x4000) || \
+ REG_RANGE((reg), 0x5000, 0x8000) || \
+ REG_RANGE((reg), 0xB000, 0x12000) || \
+ REG_RANGE((reg), 0x2E000, 0x30000))
+
+#define FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg) \
+ (REG_RANGE((reg), 0x12000, 0x14000) || \
+ REG_RANGE((reg), 0x22000, 0x24000) || \
+ REG_RANGE((reg), 0x30000, 0x40000))
+
+#define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \
+ (REG_RANGE((reg), 0x2000, 0x4000) || \
+ REG_RANGE((reg), 0x5000, 0x8000) || \
+ REG_RANGE((reg), 0x8300, 0x8500) || \
+ REG_RANGE((reg), 0xB000, 0xC000) || \
+ REG_RANGE((reg), 0xE000, 0xE800))
+
+#define FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg) \
+ (REG_RANGE((reg), 0x8800, 0x8900) || \
+ REG_RANGE((reg), 0xD000, 0xD800) || \
+ REG_RANGE((reg), 0x12000, 0x14000) || \
+ REG_RANGE((reg), 0x1A000, 0x1C000) || \
+ REG_RANGE((reg), 0x1E800, 0x1EA00) || \
+ REG_RANGE((reg), 0x30000, 0x40000))
+
+#define FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg) \
+ (REG_RANGE((reg), 0x4000, 0x5000) || \
+ REG_RANGE((reg), 0x8000, 0x8300) || \
+ REG_RANGE((reg), 0x8500, 0x8600) || \
+ REG_RANGE((reg), 0x9000, 0xB000) || \
+ REG_RANGE((reg), 0xC000, 0xC800) || \
+ REG_RANGE((reg), 0xF000, 0x10000) || \
+ REG_RANGE((reg), 0x14000, 0x14400) || \
+ REG_RANGE((reg), 0x22000, 0x24000))
static void
ilk_dummy_write(struct drm_i915_private *dev_priv)
@@ -490,20 +514,30 @@ ilk_dummy_write(struct drm_i915_private *dev_priv)
}
static void
-hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg)
+hsw_unclaimed_reg_debug(struct drm_i915_private *dev_priv, u32 reg, bool read,
+ bool before)
{
+ const char *op = read ? "reading" : "writing to";
+ const char *when = before ? "before" : "after";
+
+ if (!i915.mmio_debug)
+ return;
+
if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) {
- DRM_ERROR("Unknown unclaimed register before writing to %x\n",
- reg);
+ WARN(1, "Unclaimed register detected %s %s register 0x%x\n",
+ when, op, reg);
__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
}
}
static void
-hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg)
+hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
{
+ if (i915.mmio_debug)
+ return;
+
if (__raw_i915_read32(dev_priv, FPGA_DBG) & FPGA_DBG_RM_NOCLAIM) {
- DRM_ERROR("Unclaimed write to %x\n", reg);
+ DRM_ERROR("Unclaimed register detected. Please use the i915.mmio_debug=1 to debug this problem.");
__raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
}
}
@@ -540,6 +574,7 @@ gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
static u##x \
gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
REG_READ_HEADER(x); \
+ hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
if (dev_priv->uncore.forcewake_count == 0 && \
NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
dev_priv->uncore.funcs.force_wake_get(dev_priv, \
@@ -550,6 +585,7 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
} else { \
val = __raw_i915_read##x(dev_priv, reg); \
} \
+ hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
REG_READ_FOOTER; \
}
@@ -573,7 +609,35 @@ vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
REG_READ_FOOTER; \
}
+#define __chv_read(x) \
+static u##x \
+chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+ unsigned fwengine = 0; \
+ REG_READ_HEADER(x); \
+ if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_rendercount == 0) \
+ fwengine = FORCEWAKE_RENDER; \
+ } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_mediacount == 0) \
+ fwengine = FORCEWAKE_MEDIA; \
+ } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_rendercount == 0) \
+ fwengine |= FORCEWAKE_RENDER; \
+ if (dev_priv->uncore.fw_mediacount == 0) \
+ fwengine |= FORCEWAKE_MEDIA; \
+ } \
+ if (fwengine) \
+ dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+ val = __raw_i915_read##x(dev_priv, reg); \
+ if (fwengine) \
+ dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
+ REG_READ_FOOTER; \
+}
+__chv_read(8)
+__chv_read(16)
+__chv_read(32)
+__chv_read(64)
__vlv_read(8)
__vlv_read(16)
__vlv_read(32)
@@ -591,6 +655,7 @@ __gen4_read(16)
__gen4_read(32)
__gen4_read(64)
+#undef __chv_read
#undef __vlv_read
#undef __gen6_read
#undef __gen5_read
@@ -647,12 +712,13 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \
- hsw_unclaimed_reg_clear(dev_priv, reg); \
+ hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
__raw_i915_write##x(dev_priv, reg, val); \
if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \
} \
- hsw_unclaimed_reg_check(dev_priv, reg); \
+ hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
+ hsw_unclaimed_reg_detect(dev_priv); \
REG_WRITE_FOOTER; \
}
@@ -681,6 +747,7 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg)
static void \
gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
REG_WRITE_HEADER; \
+ hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
if (dev_priv->uncore.forcewake_count == 0) \
dev_priv->uncore.funcs.force_wake_get(dev_priv, \
@@ -692,9 +759,43 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
} else { \
__raw_i915_write##x(dev_priv, reg, val); \
} \
+ hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
+ hsw_unclaimed_reg_detect(dev_priv); \
REG_WRITE_FOOTER; \
}
+#define __chv_write(x) \
+static void \
+chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
+ unsigned fwengine = 0; \
+ bool shadowed = is_gen8_shadowed(dev_priv, reg); \
+ REG_WRITE_HEADER; \
+ if (!shadowed) { \
+ if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_rendercount == 0) \
+ fwengine = FORCEWAKE_RENDER; \
+ } else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_mediacount == 0) \
+ fwengine = FORCEWAKE_MEDIA; \
+ } else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
+ if (dev_priv->uncore.fw_rendercount == 0) \
+ fwengine |= FORCEWAKE_RENDER; \
+ if (dev_priv->uncore.fw_mediacount == 0) \
+ fwengine |= FORCEWAKE_MEDIA; \
+ } \
+ } \
+ if (fwengine) \
+ dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+ __raw_i915_write##x(dev_priv, reg, val); \
+ if (fwengine) \
+ dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
+ REG_WRITE_FOOTER; \
+}
+
+__chv_write(8)
+__chv_write(16)
+__chv_write(32)
+__chv_write(64)
__gen8_write(8)
__gen8_write(16)
__gen8_write(32)
@@ -716,6 +817,7 @@ __gen4_write(16)
__gen4_write(32)
__gen4_write(64)
+#undef __chv_write
#undef __gen8_write
#undef __hsw_write
#undef __gen6_write
@@ -731,7 +833,7 @@ void intel_uncore_init(struct drm_device *dev)
setup_timer(&dev_priv->uncore.force_wake_timer,
gen6_force_wake_timer, (unsigned long)dev_priv);
- intel_uncore_early_sanitize(dev);
+ intel_uncore_early_sanitize(dev, false);
if (IS_VALLEYVIEW(dev)) {
dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
@@ -779,14 +881,26 @@ void intel_uncore_init(struct drm_device *dev)
switch (INTEL_INFO(dev)->gen) {
default:
- dev_priv->uncore.funcs.mmio_writeb = gen8_write8;
- dev_priv->uncore.funcs.mmio_writew = gen8_write16;
- dev_priv->uncore.funcs.mmio_writel = gen8_write32;
- dev_priv->uncore.funcs.mmio_writeq = gen8_write64;
- dev_priv->uncore.funcs.mmio_readb = gen6_read8;
- dev_priv->uncore.funcs.mmio_readw = gen6_read16;
- dev_priv->uncore.funcs.mmio_readl = gen6_read32;
- dev_priv->uncore.funcs.mmio_readq = gen6_read64;
+ if (IS_CHERRYVIEW(dev)) {
+ dev_priv->uncore.funcs.mmio_writeb = chv_write8;
+ dev_priv->uncore.funcs.mmio_writew = chv_write16;
+ dev_priv->uncore.funcs.mmio_writel = chv_write32;
+ dev_priv->uncore.funcs.mmio_writeq = chv_write64;
+ dev_priv->uncore.funcs.mmio_readb = chv_read8;
+ dev_priv->uncore.funcs.mmio_readw = chv_read16;
+ dev_priv->uncore.funcs.mmio_readl = chv_read32;
+ dev_priv->uncore.funcs.mmio_readq = chv_read64;
+
+ } else {
+ dev_priv->uncore.funcs.mmio_writeb = gen8_write8;
+ dev_priv->uncore.funcs.mmio_writew = gen8_write16;
+ dev_priv->uncore.funcs.mmio_writel = gen8_write32;
+ dev_priv->uncore.funcs.mmio_writeq = gen8_write64;
+ dev_priv->uncore.funcs.mmio_readb = gen6_read8;
+ dev_priv->uncore.funcs.mmio_readw = gen6_read16;
+ dev_priv->uncore.funcs.mmio_readl = gen6_read32;
+ dev_priv->uncore.funcs.mmio_readq = gen6_read64;
+ }
break;
case 7:
case 6:
@@ -912,7 +1026,7 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev,
if (args->flags || args->pad)
return -EINVAL;
- if (args->ctx_id == DEFAULT_CONTEXT_ID && !capable(CAP_SYS_ADMIN))
+ if (args->ctx_id == DEFAULT_CONTEXT_HANDLE && !capable(CAP_SYS_ADMIN))
return -EPERM;
ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -1053,18 +1167,16 @@ static int gen6_do_reset(struct drm_device *dev)
int intel_gpu_reset(struct drm_device *dev)
{
- switch (INTEL_INFO(dev)->gen) {
- case 8:
- case 7:
- case 6: return gen6_do_reset(dev);
- case 5: return ironlake_do_reset(dev);
- case 4:
- if (IS_G4X(dev))
- return g4x_do_reset(dev);
- else
- return i965_do_reset(dev);
- default: return -ENODEV;
- }
+ if (INTEL_INFO(dev)->gen >= 6)
+ return gen6_do_reset(dev);
+ else if (IS_GEN5(dev))
+ return ironlake_do_reset(dev);
+ else if (IS_G4X(dev))
+ return g4x_do_reset(dev);
+ else if (IS_GEN4(dev))
+ return i965_do_reset(dev);
+ else
+ return -ENODEV;
}
void intel_uncore_check_errors(struct drm_device *dev)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index cf11ee68a6d9..80de23d9b9c9 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -280,7 +280,7 @@ static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
{
int ret;
- ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+ ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, NULL);
if (ret) {
if (ret != -ERESTARTSYS && ret != -EBUSY)
DRM_ERROR("reserve failed %p\n", bo);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 13b7dd83faa9..5451dc58eff1 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -272,7 +272,7 @@ static int mga_fbdev_destroy(struct drm_device *dev,
return 0;
}
-static struct drm_fb_helper_funcs mga_fb_helper_funcs = {
+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,
@@ -293,9 +293,10 @@ int mgag200_fbdev_init(struct mga_device *mdev)
return -ENOMEM;
mdev->mfbdev = mfbdev;
- mfbdev->helper.funcs = &mga_fb_helper_funcs;
spin_lock_init(&mfbdev->dirty_lock);
+ drm_fb_helper_prepare(mdev->dev, &mfbdev->helper, &mga_fb_helper_funcs);
+
ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper,
mdev->num_crtc, MGAG200FB_CONN_LIMIT);
if (ret)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index a034ed408252..45f04dea0ac2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1562,19 +1562,9 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
*connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
/* pick the encoder ids */
- if (enc_id) {
- obj =
- drm_mode_object_find(connector->dev, enc_id,
- DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
@@ -1621,7 +1611,7 @@ static struct drm_connector *mga_vga_init(struct drm_device *dev)
drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
mga_connector->i2c = mgag200_i2c_create(dev);
if (!mga_connector->i2c)
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index f12388967856..c99c50de3226 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -2,7 +2,6 @@
config DRM_MSM
tristate "MSM DRM"
depends on DRM
- depends on MSM_IOMMU
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
select DRM_KMS_HELPER
select SHMEM
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
index 85d615e7d62f..a8a144b38eaa 100644
--- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
@@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32814 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 8900 bytes, from 2013-10-22 23:57:49)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 10574 bytes, from 2013-11-13 05:44:45)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 53644 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 8344 bytes, from 2013-11-30 14:49:47)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-05-16 11:51:57)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-06-25 12:57:16)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 26602 bytes, from 2014-06-25 12:57:16)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -203,6 +203,15 @@ enum a2xx_rb_copy_sample_select {
SAMPLE_0123 = 6,
};
+enum a2xx_rb_blend_opcode {
+ BLEND_DST_PLUS_SRC = 0,
+ BLEND_SRC_MINUS_DST = 1,
+ BLEND_MIN_DST_SRC = 2,
+ BLEND_MAX_DST_SRC = 3,
+ BLEND_DST_MINUS_SRC = 4,
+ BLEND_DST_PLUS_SRC_BIAS = 5,
+};
+
enum adreno_mmu_clnt_beh {
BEH_NEVR = 0,
BEH_TRAN_RNG = 1,
@@ -890,6 +899,39 @@ static inline uint32_t A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(uint32_t val)
#define REG_A2XX_VGT_EVENT_INITIATOR 0x000021f9
#define REG_A2XX_VGT_DRAW_INITIATOR 0x000021fc
+#define A2XX_VGT_DRAW_INITIATOR_PRIM_TYPE__MASK 0x0000003f
+#define A2XX_VGT_DRAW_INITIATOR_PRIM_TYPE__SHIFT 0
+static inline uint32_t A2XX_VGT_DRAW_INITIATOR_PRIM_TYPE(enum pc_di_primtype val)
+{
+ return ((val) << A2XX_VGT_DRAW_INITIATOR_PRIM_TYPE__SHIFT) & A2XX_VGT_DRAW_INITIATOR_PRIM_TYPE__MASK;
+}
+#define A2XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__MASK 0x000000c0
+#define A2XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__SHIFT 6
+static inline uint32_t A2XX_VGT_DRAW_INITIATOR_SOURCE_SELECT(enum pc_di_src_sel val)
+{
+ return ((val) << A2XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__SHIFT) & A2XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__MASK;
+}
+#define A2XX_VGT_DRAW_INITIATOR_VIS_CULL__MASK 0x00000600
+#define A2XX_VGT_DRAW_INITIATOR_VIS_CULL__SHIFT 9
+static inline uint32_t A2XX_VGT_DRAW_INITIATOR_VIS_CULL(enum pc_di_vis_cull_mode val)
+{
+ return ((val) << A2XX_VGT_DRAW_INITIATOR_VIS_CULL__SHIFT) & A2XX_VGT_DRAW_INITIATOR_VIS_CULL__MASK;
+}
+#define A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE__MASK 0x00000800
+#define A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE__SHIFT 11
+static inline uint32_t A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE(enum pc_di_index_size val)
+{
+ return ((val) << A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE__SHIFT) & A2XX_VGT_DRAW_INITIATOR_INDEX_SIZE__MASK;
+}
+#define A2XX_VGT_DRAW_INITIATOR_NOT_EOP 0x00001000
+#define A2XX_VGT_DRAW_INITIATOR_SMALL_INDEX 0x00002000
+#define A2XX_VGT_DRAW_INITIATOR_PRE_DRAW_INITIATOR_ENABLE 0x00004000
+#define A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK 0xffff0000
+#define A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT 16
+static inline uint32_t A2XX_VGT_DRAW_INITIATOR_NUM_INDICES(uint32_t val)
+{
+ return ((val) << A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT) & A2XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK;
+}
#define REG_A2XX_VGT_IMMED_DATA 0x000021fd
@@ -963,7 +1005,7 @@ static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(enum adreno_rb_blend
}
#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK 0x000000e0
#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT 5
-static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(enum adreno_rb_blend_opcode val)
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(enum a2xx_rb_blend_opcode val)
{
return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK;
}
@@ -981,7 +1023,7 @@ static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(enum adreno_rb_blend
}
#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK 0x00e00000
#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT 21
-static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(enum adreno_rb_blend_opcode val)
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(enum a2xx_rb_blend_opcode val)
{
return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK;
}
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
index a7be56163d23..303e8a9e91a5 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
@@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32814 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 8900 bytes, from 2013-10-22 23:57:49)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 10574 bytes, from 2013-11-13 05:44:45)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 53644 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 8344 bytes, from 2013-11-30 14:49:47)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-05-16 11:51:57)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-06-25 12:57:16)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 26602 bytes, from 2014-06-25 12:57:16)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -41,31 +41,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-enum a3xx_render_mode {
- RB_RENDERING_PASS = 0,
- RB_TILING_PASS = 1,
- RB_RESOLVE_PASS = 2,
-};
-
enum a3xx_tile_mode {
LINEAR = 0,
TILE_32X32 = 2,
};
-enum a3xx_threadmode {
- MULTI = 0,
- SINGLE = 1,
-};
-
-enum a3xx_instrbuffermode {
- BUFFER = 1,
-};
-
-enum a3xx_threadsize {
- TWO_QUADS = 0,
- FOUR_QUADS = 1,
-};
-
enum a3xx_state_block_id {
HLSQ_BLOCK_ID_TP_TEX = 2,
HLSQ_BLOCK_ID_TP_MIPMAP = 3,
@@ -169,6 +149,8 @@ enum a3xx_color_fmt {
RB_R8G8B8A8_UNORM = 8,
RB_Z16_UNORM = 12,
RB_A8_UNORM = 20,
+ RB_R16G16B16A16_FLOAT = 27,
+ RB_R32G32B32A32_FLOAT = 51,
};
enum a3xx_color_swap {
@@ -178,12 +160,6 @@ enum a3xx_color_swap {
XYZW = 3,
};
-enum a3xx_msaa_samples {
- MSAA_ONE = 0,
- MSAA_TWO = 1,
- MSAA_FOUR = 2,
-};
-
enum a3xx_sp_perfcounter_select {
SP_FS_CFLOW_INSTRUCTIONS = 12,
SP_FS_FULL_ALU_INSTRUCTIONS = 14,
@@ -191,21 +167,45 @@ enum a3xx_sp_perfcounter_select {
SP_ALU_ACTIVE_CYCLES = 29,
};
-enum adreno_rb_copy_control_mode {
- RB_COPY_RESOLVE = 1,
- RB_COPY_DEPTH_STENCIL = 5,
+enum a3xx_rop_code {
+ ROP_CLEAR = 0,
+ ROP_NOR = 1,
+ ROP_AND_INVERTED = 2,
+ ROP_COPY_INVERTED = 3,
+ ROP_AND_REVERSE = 4,
+ ROP_INVERT = 5,
+ ROP_XOR = 6,
+ ROP_NAND = 7,
+ ROP_AND = 8,
+ ROP_EQUIV = 9,
+ ROP_NOOP = 10,
+ ROP_OR_INVERTED = 11,
+ ROP_COPY = 12,
+ ROP_OR_REVERSE = 13,
+ ROP_OR = 14,
+ ROP_SET = 15,
+};
+
+enum a3xx_rb_blend_opcode {
+ BLEND_DST_PLUS_SRC = 0,
+ BLEND_SRC_MINUS_DST = 1,
+ BLEND_DST_MINUS_SRC = 2,
+ BLEND_MIN_DST_SRC = 3,
+ BLEND_MAX_DST_SRC = 4,
};
enum a3xx_tex_filter {
A3XX_TEX_NEAREST = 0,
A3XX_TEX_LINEAR = 1,
+ A3XX_TEX_ANISO = 2,
};
enum a3xx_tex_clamp {
A3XX_TEX_REPEAT = 0,
A3XX_TEX_CLAMP_TO_EDGE = 1,
A3XX_TEX_MIRROR_REPEAT = 2,
- A3XX_TEX_CLAMP_NONE = 3,
+ A3XX_TEX_CLAMP_TO_BORDER = 3,
+ A3XX_TEX_MIRROR_CLAMP = 4,
};
enum a3xx_tex_swiz {
@@ -316,6 +316,7 @@ enum a3xx_tex_type {
#define REG_A3XX_RBBM_INT_0_STATUS 0x00000064
#define REG_A3XX_RBBM_PERFCTR_CTL 0x00000080
+#define A3XX_RBBM_PERFCTR_CTL_ENABLE 0x00000001
#define REG_A3XX_RBBM_PERFCTR_LOAD_CMD0 0x00000081
@@ -549,6 +550,10 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460
#define REG_A3XX_CP_AHB_FAULT 0x0000054d
+#define REG_A3XX_SP_GLOBAL_MEM_SIZE 0x00000e22
+
+#define REG_A3XX_SP_GLOBAL_MEM_ADDR 0x00000e23
+
#define REG_A3XX_GRAS_CL_CLIP_CNTL 0x00002040
#define A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER 0x00001000
#define A3XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE 0x00010000
@@ -556,6 +561,9 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460
#define A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE 0x00080000
#define A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE 0x00100000
#define A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE 0x00200000
+#define A3XX_GRAS_CL_CLIP_CNTL_ZCOORD 0x00800000
+#define A3XX_GRAS_CL_CLIP_CNTL_WCOORD 0x01000000
+#define A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE 0x02000000
#define REG_A3XX_GRAS_CL_GB_CLIP_ADJ 0x00002044
#define A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK 0x000003ff
@@ -620,8 +628,26 @@ static inline uint32_t A3XX_GRAS_CL_VPORT_ZSCALE(float val)
}
#define REG_A3XX_GRAS_SU_POINT_MINMAX 0x00002068
+#define A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK 0x0000ffff
+#define A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT 0
+static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MIN(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK;
+}
+#define A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK 0xffff0000
+#define A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT 16
+static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MAX(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK;
+}
#define REG_A3XX_GRAS_SU_POINT_SIZE 0x00002069
+#define A3XX_GRAS_SU_POINT_SIZE__MASK 0xffffffff
+#define A3XX_GRAS_SU_POINT_SIZE__SHIFT 0
+static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val)
+{
+ return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_SIZE__SHIFT) & A3XX_GRAS_SU_POINT_SIZE__MASK;
+}
#define REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE 0x0000206c
#define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK 0x00ffffff
@@ -743,6 +769,7 @@ static inline uint32_t A3XX_RB_MODE_CONTROL_RENDER_MODE(enum a3xx_render_mode va
#define A3XX_RB_MODE_CONTROL_PACKER_TIMER_ENABLE 0x00010000
#define REG_A3XX_RB_RENDER_CONTROL 0x000020c1
+#define A3XX_RB_RENDER_CONTROL_FACENESS 0x00000008
#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__MASK 0x00000ff0
#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__SHIFT 4
static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val)
@@ -751,6 +778,10 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val)
}
#define A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE 0x00001000
#define A3XX_RB_RENDER_CONTROL_ENABLE_GMEM 0x00002000
+#define A3XX_RB_RENDER_CONTROL_XCOORD 0x00004000
+#define A3XX_RB_RENDER_CONTROL_YCOORD 0x00008000
+#define A3XX_RB_RENDER_CONTROL_ZCOORD 0x00010000
+#define A3XX_RB_RENDER_CONTROL_WCOORD 0x00020000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST 0x00400000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK 0x07000000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT 24
@@ -796,7 +827,7 @@ static inline uint32_t REG_A3XX_RB_MRT_CONTROL(uint32_t i0) { return 0x000020c4
#define A3XX_RB_MRT_CONTROL_BLEND2 0x00000020
#define A3XX_RB_MRT_CONTROL_ROP_CODE__MASK 0x00000f00
#define A3XX_RB_MRT_CONTROL_ROP_CODE__SHIFT 8
-static inline uint32_t A3XX_RB_MRT_CONTROL_ROP_CODE(uint32_t val)
+static inline uint32_t A3XX_RB_MRT_CONTROL_ROP_CODE(enum a3xx_rop_code val)
{
return ((val) << A3XX_RB_MRT_CONTROL_ROP_CODE__SHIFT) & A3XX_RB_MRT_CONTROL_ROP_CODE__MASK;
}
@@ -856,7 +887,7 @@ static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(enum adreno_rb_b
}
#define A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK 0x000000e0
#define A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT 5
-static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(enum adreno_rb_blend_opcode val)
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(enum a3xx_rb_blend_opcode val)
{
return ((val) << A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK;
}
@@ -874,7 +905,7 @@ static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(enum adreno_rb
}
#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK 0x00e00000
#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT 21
-static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(enum adreno_rb_blend_opcode val)
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(enum a3xx_rb_blend_opcode val)
{
return ((val) << A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK;
}
@@ -957,17 +988,24 @@ static inline uint32_t A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(enum a3xx_msaa_samples
{
return ((val) << A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__SHIFT) & A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__MASK;
}
+#define A3XX_RB_COPY_CONTROL_DEPTHCLEAR 0x00000008
#define A3XX_RB_COPY_CONTROL_MODE__MASK 0x00000070
#define A3XX_RB_COPY_CONTROL_MODE__SHIFT 4
static inline uint32_t A3XX_RB_COPY_CONTROL_MODE(enum adreno_rb_copy_control_mode val)
{
return ((val) << A3XX_RB_COPY_CONTROL_MODE__SHIFT) & A3XX_RB_COPY_CONTROL_MODE__MASK;
}
-#define A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK 0xfffffc00
-#define A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT 10
+#define A3XX_RB_COPY_CONTROL_FASTCLEAR__MASK 0x00000f00
+#define A3XX_RB_COPY_CONTROL_FASTCLEAR__SHIFT 8
+static inline uint32_t A3XX_RB_COPY_CONTROL_FASTCLEAR(uint32_t val)
+{
+ return ((val) << A3XX_RB_COPY_CONTROL_FASTCLEAR__SHIFT) & A3XX_RB_COPY_CONTROL_FASTCLEAR__MASK;
+}
+#define A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK 0xffffc000
+#define A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT 14
static inline uint32_t A3XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val)
{
- return ((val >> 10) << A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT) & A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK;
+ return ((val >> 14) << A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT) & A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK;
}
#define REG_A3XX_RB_COPY_DEST_BASE 0x000020ed
@@ -1005,6 +1043,12 @@ static inline uint32_t A3XX_RB_COPY_DEST_INFO_SWAP(enum a3xx_color_swap val)
{
return ((val) << A3XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A3XX_RB_COPY_DEST_INFO_SWAP__MASK;
}
+#define A3XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK 0x00000c00
+#define A3XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT 10
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+ return ((val) << A3XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT) & A3XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK;
+}
#define A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__MASK 0x0003c000
#define A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__SHIFT 14
static inline uint32_t A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(uint32_t val)
@@ -1019,6 +1063,7 @@ static inline uint32_t A3XX_RB_COPY_DEST_INFO_ENDIAN(enum adreno_rb_surface_endi
}
#define REG_A3XX_RB_DEPTH_CONTROL 0x00002100
+#define A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z 0x00000001
#define A3XX_RB_DEPTH_CONTROL_Z_ENABLE 0x00000002
#define A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE 0x00000004
#define A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE 0x00000008
@@ -1044,7 +1089,7 @@ static inline uint32_t A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_form
#define A3XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT 11
static inline uint32_t A3XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
{
- return ((val >> 10) << A3XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A3XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
+ return ((val >> 12) << A3XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A3XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
}
#define REG_A3XX_RB_DEPTH_PITCH 0x00002103
@@ -1172,6 +1217,8 @@ static inline uint32_t A3XX_RB_WINDOW_OFFSET_Y(uint32_t val)
}
#define REG_A3XX_RB_SAMPLE_COUNT_CONTROL 0x00002110
+#define A3XX_RB_SAMPLE_COUNT_CONTROL_RESET 0x00000001
+#define A3XX_RB_SAMPLE_COUNT_CONTROL_COPY 0x00000002
#define REG_A3XX_RB_SAMPLE_COUNT_ADDR 0x00002111
@@ -1179,7 +1226,23 @@ static inline uint32_t A3XX_RB_WINDOW_OFFSET_Y(uint32_t val)
#define REG_A3XX_RB_Z_CLAMP_MAX 0x00002115
+#define REG_A3XX_VGT_BIN_BASE 0x000021e1
+
+#define REG_A3XX_VGT_BIN_SIZE 0x000021e2
+
#define REG_A3XX_PC_VSTREAM_CONTROL 0x000021e4
+#define A3XX_PC_VSTREAM_CONTROL_SIZE__MASK 0x003f0000
+#define A3XX_PC_VSTREAM_CONTROL_SIZE__SHIFT 16
+static inline uint32_t A3XX_PC_VSTREAM_CONTROL_SIZE(uint32_t val)
+{
+ return ((val) << A3XX_PC_VSTREAM_CONTROL_SIZE__SHIFT) & A3XX_PC_VSTREAM_CONTROL_SIZE__MASK;
+}
+#define A3XX_PC_VSTREAM_CONTROL_N__MASK 0x07c00000
+#define A3XX_PC_VSTREAM_CONTROL_N__SHIFT 22
+static inline uint32_t A3XX_PC_VSTREAM_CONTROL_N(uint32_t val)
+{
+ return ((val) << A3XX_PC_VSTREAM_CONTROL_N__SHIFT) & A3XX_PC_VSTREAM_CONTROL_N__MASK;
+}
#define REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL 0x000021ea
@@ -1203,6 +1266,7 @@ static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(enum adreno_pa_
return ((val) << A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__MASK;
}
#define A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST 0x02000000
+#define A3XX_PC_PRIM_VTX_CNTL_PSIZE 0x04000000
#define REG_A3XX_PC_RESTART_INDEX 0x000021ed
@@ -1232,6 +1296,7 @@ static inline uint32_t A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(enum a3xx_threadsize
}
#define A3XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE 0x00000100
#define A3XX_HLSQ_CONTROL_1_REG_RESERVED1 0x00000200
+#define A3XX_HLSQ_CONTROL_1_REG_ZWCOORD 0x02000000
#define REG_A3XX_HLSQ_CONTROL_2_REG 0x00002202
#define A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK 0xfc000000
@@ -1242,6 +1307,12 @@ static inline uint32_t A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(uint32_t val)
}
#define REG_A3XX_HLSQ_CONTROL_3_REG 0x00002203
+#define A3XX_HLSQ_CONTROL_3_REG_REGID__MASK 0x000000ff
+#define A3XX_HLSQ_CONTROL_3_REG_REGID__SHIFT 0
+static inline uint32_t A3XX_HLSQ_CONTROL_3_REG_REGID(uint32_t val)
+{
+ return ((val) << A3XX_HLSQ_CONTROL_3_REG_REGID__SHIFT) & A3XX_HLSQ_CONTROL_3_REG_REGID__MASK;
+}
#define REG_A3XX_HLSQ_VS_CONTROL_REG 0x00002204
#define A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__MASK 0x00000fff
@@ -1312,10 +1383,36 @@ static inline uint32_t A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(uint32_t val)
}
#define REG_A3XX_HLSQ_CL_NDRANGE_0_REG 0x0000220a
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_WORKDIM__MASK 0x00000003
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_WORKDIM__SHIFT 0
+static inline uint32_t A3XX_HLSQ_CL_NDRANGE_0_REG_WORKDIM(uint32_t val)
+{
+ return ((val) << A3XX_HLSQ_CL_NDRANGE_0_REG_WORKDIM__SHIFT) & A3XX_HLSQ_CL_NDRANGE_0_REG_WORKDIM__MASK;
+}
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE0__MASK 0x00000ffc
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE0__SHIFT 2
+static inline uint32_t A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE0(uint32_t val)
+{
+ return ((val) << A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE0__SHIFT) & A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE0__MASK;
+}
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE1__MASK 0x003ff000
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE1__SHIFT 12
+static inline uint32_t A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE1(uint32_t val)
+{
+ return ((val) << A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE1__SHIFT) & A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE1__MASK;
+}
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE2__MASK 0xffc00000
+#define A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE2__SHIFT 22
+static inline uint32_t A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE2(uint32_t val)
+{
+ return ((val) << A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE2__SHIFT) & A3XX_HLSQ_CL_NDRANGE_0_REG_LOCALSIZE2__MASK;
+}
+
+static inline uint32_t REG_A3XX_HLSQ_CL_GLOBAL_WORK(uint32_t i0) { return 0x0000220b + 0x2*i0; }
-#define REG_A3XX_HLSQ_CL_NDRANGE_1_REG 0x0000220b
+static inline uint32_t REG_A3XX_HLSQ_CL_GLOBAL_WORK_SIZE(uint32_t i0) { return 0x0000220b + 0x2*i0; }
-#define REG_A3XX_HLSQ_CL_NDRANGE_2_REG 0x0000220c
+static inline uint32_t REG_A3XX_HLSQ_CL_GLOBAL_WORK_OFFSET(uint32_t i0) { return 0x0000220c + 0x2*i0; }
#define REG_A3XX_HLSQ_CL_CONTROL_0_REG 0x00002211
@@ -1323,7 +1420,9 @@ static inline uint32_t A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(uint32_t val)
#define REG_A3XX_HLSQ_CL_KERNEL_CONST_REG 0x00002214
-#define REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG 0x00002215
+static inline uint32_t REG_A3XX_HLSQ_CL_KERNEL_GROUP(uint32_t i0) { return 0x00002215 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_HLSQ_CL_KERNEL_GROUP_RATIO(uint32_t i0) { return 0x00002215 + 0x1*i0; }
#define REG_A3XX_HLSQ_CL_KERNEL_GROUP_Y_REG 0x00002216
@@ -1438,6 +1537,12 @@ static inline uint32_t A3XX_VFD_DECODE_INSTR_REGID(uint32_t val)
{
return ((val) << A3XX_VFD_DECODE_INSTR_REGID__SHIFT) & A3XX_VFD_DECODE_INSTR_REGID__MASK;
}
+#define A3XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000
+#define A3XX_VFD_DECODE_INSTR_SWAP__SHIFT 22
+static inline uint32_t A3XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val)
+{
+ return ((val) << A3XX_VFD_DECODE_INSTR_SWAP__SHIFT) & A3XX_VFD_DECODE_INSTR_SWAP__MASK;
+}
#define A3XX_VFD_DECODE_INSTR_SHIFTCNT__MASK 0x1f000000
#define A3XX_VFD_DECODE_INSTR_SHIFTCNT__SHIFT 24
static inline uint32_t A3XX_VFD_DECODE_INSTR_SHIFTCNT(uint32_t val)
@@ -1462,12 +1567,13 @@ static inline uint32_t A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT(uint32_t val
}
#define REG_A3XX_VPC_ATTR 0x00002280
-#define A3XX_VPC_ATTR_TOTALATTR__MASK 0x00000fff
+#define A3XX_VPC_ATTR_TOTALATTR__MASK 0x000001ff
#define A3XX_VPC_ATTR_TOTALATTR__SHIFT 0
static inline uint32_t A3XX_VPC_ATTR_TOTALATTR(uint32_t val)
{
return ((val) << A3XX_VPC_ATTR_TOTALATTR__SHIFT) & A3XX_VPC_ATTR_TOTALATTR__MASK;
}
+#define A3XX_VPC_ATTR_PSIZE 0x00000200
#define A3XX_VPC_ATTR_THRDASSIGN__MASK 0x0ffff000
#define A3XX_VPC_ATTR_THRDASSIGN__SHIFT 12
static inline uint32_t A3XX_VPC_ATTR_THRDASSIGN(uint32_t val)
@@ -1522,11 +1628,11 @@ static inline uint32_t A3XX_SP_SP_CTRL_REG_SLEEPMODE(uint32_t val)
{
return ((val) << A3XX_SP_SP_CTRL_REG_SLEEPMODE__SHIFT) & A3XX_SP_SP_CTRL_REG_SLEEPMODE__MASK;
}
-#define A3XX_SP_SP_CTRL_REG_LOMODE__MASK 0x00c00000
-#define A3XX_SP_SP_CTRL_REG_LOMODE__SHIFT 22
-static inline uint32_t A3XX_SP_SP_CTRL_REG_LOMODE(uint32_t val)
+#define A3XX_SP_SP_CTRL_REG_L0MODE__MASK 0x00c00000
+#define A3XX_SP_SP_CTRL_REG_L0MODE__SHIFT 22
+static inline uint32_t A3XX_SP_SP_CTRL_REG_L0MODE(uint32_t val)
{
- return ((val) << A3XX_SP_SP_CTRL_REG_LOMODE__SHIFT) & A3XX_SP_SP_CTRL_REG_LOMODE__MASK;
+ return ((val) << A3XX_SP_SP_CTRL_REG_L0MODE__SHIFT) & A3XX_SP_SP_CTRL_REG_L0MODE__MASK;
}
#define REG_A3XX_SP_VS_CTRL_REG0 0x000022c4
@@ -1569,6 +1675,7 @@ static inline uint32_t A3XX_SP_VS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val)
}
#define A3XX_SP_VS_CTRL_REG0_SUPERTHREADMODE 0x00200000
#define A3XX_SP_VS_CTRL_REG0_PIXLODENABLE 0x00400000
+#define A3XX_SP_VS_CTRL_REG0_COMPUTEMODE 0x00800000
#define A3XX_SP_VS_CTRL_REG0_LENGTH__MASK 0xff000000
#define A3XX_SP_VS_CTRL_REG0_LENGTH__SHIFT 24
static inline uint32_t A3XX_SP_VS_CTRL_REG0_LENGTH(uint32_t val)
@@ -1742,6 +1849,7 @@ static inline uint32_t A3XX_SP_FS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val)
}
#define A3XX_SP_FS_CTRL_REG0_SUPERTHREADMODE 0x00200000
#define A3XX_SP_FS_CTRL_REG0_PIXLODENABLE 0x00400000
+#define A3XX_SP_FS_CTRL_REG0_COMPUTEMODE 0x00800000
#define A3XX_SP_FS_CTRL_REG0_LENGTH__MASK 0xff000000
#define A3XX_SP_FS_CTRL_REG0_LENGTH__SHIFT 24
static inline uint32_t A3XX_SP_FS_CTRL_REG0_LENGTH(uint32_t val)
@@ -1802,6 +1910,13 @@ static inline uint32_t A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val)
#define REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_1 0x000022e9
#define REG_A3XX_SP_FS_OUTPUT_REG 0x000022ec
+#define A3XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE 0x00000080
+#define A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID__MASK 0x0000ff00
+#define A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID__SHIFT 8
+static inline uint32_t A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID(uint32_t val)
+{
+ return ((val) << A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID__SHIFT) & A3XX_SP_FS_OUTPUT_REG_DEPTH_REGID__MASK;
+}
static inline uint32_t REG_A3XX_SP_FS_MRT(uint32_t i0) { return 0x000022f0 + 0x1*i0; }
@@ -1914,6 +2029,42 @@ static inline uint32_t A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR(uint32_t val)
#define REG_A3XX_VBIF_OUT_AXI_AOOO 0x0000305f
+#define REG_A3XX_VBIF_PERF_CNT_EN 0x00003070
+#define A3XX_VBIF_PERF_CNT_EN_CNT0 0x00000001
+#define A3XX_VBIF_PERF_CNT_EN_CNT1 0x00000002
+#define A3XX_VBIF_PERF_CNT_EN_PWRCNT0 0x00000004
+#define A3XX_VBIF_PERF_CNT_EN_PWRCNT1 0x00000008
+#define A3XX_VBIF_PERF_CNT_EN_PWRCNT2 0x00000010
+
+#define REG_A3XX_VBIF_PERF_CNT_CLR 0x00003071
+#define A3XX_VBIF_PERF_CNT_CLR_CNT0 0x00000001
+#define A3XX_VBIF_PERF_CNT_CLR_CNT1 0x00000002
+#define A3XX_VBIF_PERF_CNT_CLR_PWRCNT0 0x00000004
+#define A3XX_VBIF_PERF_CNT_CLR_PWRCNT1 0x00000008
+#define A3XX_VBIF_PERF_CNT_CLR_PWRCNT2 0x00000010
+
+#define REG_A3XX_VBIF_PERF_CNT_SEL 0x00003072
+
+#define REG_A3XX_VBIF_PERF_CNT0_LO 0x00003073
+
+#define REG_A3XX_VBIF_PERF_CNT0_HI 0x00003074
+
+#define REG_A3XX_VBIF_PERF_CNT1_LO 0x00003075
+
+#define REG_A3XX_VBIF_PERF_CNT1_HI 0x00003076
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT0_LO 0x00003077
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT0_HI 0x00003078
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT1_LO 0x00003079
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT1_HI 0x0000307a
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT2_LO 0x0000307b
+
+#define REG_A3XX_VBIF_PERF_PWR_CNT2_HI 0x0000307c
+
#define REG_A3XX_VSC_BIN_SIZE 0x00000c01
#define A3XX_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f
#define A3XX_VSC_BIN_SIZE_WIDTH__SHIFT 0
@@ -2080,6 +2231,8 @@ static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_op
}
#define A3XX_UCHE_CACHE_INVALIDATE1_REG_ENTIRE_CACHE 0x80000000
+#define REG_A3XX_UNKNOWN_0EA6 0x00000ea6
+
#define REG_A3XX_SP_PERFCOUNTER0_SELECT 0x00000ec4
#define REG_A3XX_SP_PERFCOUNTER1_SELECT 0x00000ec5
@@ -2117,6 +2270,39 @@ static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_op
#define REG_A3XX_VGT_EVENT_INITIATOR 0x000021f9
#define REG_A3XX_VGT_DRAW_INITIATOR 0x000021fc
+#define A3XX_VGT_DRAW_INITIATOR_PRIM_TYPE__MASK 0x0000003f
+#define A3XX_VGT_DRAW_INITIATOR_PRIM_TYPE__SHIFT 0
+static inline uint32_t A3XX_VGT_DRAW_INITIATOR_PRIM_TYPE(enum pc_di_primtype val)
+{
+ return ((val) << A3XX_VGT_DRAW_INITIATOR_PRIM_TYPE__SHIFT) & A3XX_VGT_DRAW_INITIATOR_PRIM_TYPE__MASK;
+}
+#define A3XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__MASK 0x000000c0
+#define A3XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__SHIFT 6
+static inline uint32_t A3XX_VGT_DRAW_INITIATOR_SOURCE_SELECT(enum pc_di_src_sel val)
+{
+ return ((val) << A3XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__SHIFT) & A3XX_VGT_DRAW_INITIATOR_SOURCE_SELECT__MASK;
+}
+#define A3XX_VGT_DRAW_INITIATOR_VIS_CULL__MASK 0x00000600
+#define A3XX_VGT_DRAW_INITIATOR_VIS_CULL__SHIFT 9
+static inline uint32_t A3XX_VGT_DRAW_INITIATOR_VIS_CULL(enum pc_di_vis_cull_mode val)
+{
+ return ((val) << A3XX_VGT_DRAW_INITIATOR_VIS_CULL__SHIFT) & A3XX_VGT_DRAW_INITIATOR_VIS_CULL__MASK;
+}
+#define A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE__MASK 0x00000800
+#define A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE__SHIFT 11
+static inline uint32_t A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE(enum pc_di_index_size val)
+{
+ return ((val) << A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE__SHIFT) & A3XX_VGT_DRAW_INITIATOR_INDEX_SIZE__MASK;
+}
+#define A3XX_VGT_DRAW_INITIATOR_NOT_EOP 0x00001000
+#define A3XX_VGT_DRAW_INITIATOR_SMALL_INDEX 0x00002000
+#define A3XX_VGT_DRAW_INITIATOR_PRE_DRAW_INITIATOR_ENABLE 0x00004000
+#define A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK 0xffff0000
+#define A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT 16
+static inline uint32_t A3XX_VGT_DRAW_INITIATOR_NUM_INDICES(uint32_t val)
+{
+ return ((val) << A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__SHIFT) & A3XX_VGT_DRAW_INITIATOR_NUM_INDICES__MASK;
+}
#define REG_A3XX_VGT_IMMED_DATA 0x000021fd
@@ -2152,6 +2338,12 @@ static inline uint32_t A3XX_TEX_SAMP_0_WRAP_R(enum a3xx_tex_clamp val)
{
return ((val) << A3XX_TEX_SAMP_0_WRAP_R__SHIFT) & A3XX_TEX_SAMP_0_WRAP_R__MASK;
}
+#define A3XX_TEX_SAMP_0_COMPARE_FUNC__MASK 0x00700000
+#define A3XX_TEX_SAMP_0_COMPARE_FUNC__SHIFT 20
+static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val)
+{
+ return ((val) << A3XX_TEX_SAMP_0_COMPARE_FUNC__SHIFT) & A3XX_TEX_SAMP_0_COMPARE_FUNC__MASK;
+}
#define A3XX_TEX_SAMP_0_UNNORM_COORDS 0x80000000
#define REG_A3XX_TEX_SAMP_1 0x00000001
@@ -2170,6 +2362,7 @@ static inline uint32_t A3XX_TEX_SAMP_1_MIN_LOD(float val)
#define REG_A3XX_TEX_CONST_0 0x00000000
#define A3XX_TEX_CONST_0_TILED 0x00000001
+#define A3XX_TEX_CONST_0_SRGB 0x00000004
#define A3XX_TEX_CONST_0_SWIZ_X__MASK 0x00000070
#define A3XX_TEX_CONST_0_SWIZ_X__SHIFT 4
static inline uint32_t A3XX_TEX_CONST_0_SWIZ_X(enum a3xx_tex_swiz val)
@@ -2206,6 +2399,7 @@ static inline uint32_t A3XX_TEX_CONST_0_FMT(enum a3xx_tex_fmt val)
{
return ((val) << A3XX_TEX_CONST_0_FMT__SHIFT) & A3XX_TEX_CONST_0_FMT__MASK;
}
+#define A3XX_TEX_CONST_0_NOCONVERT 0x20000000
#define A3XX_TEX_CONST_0_TYPE__MASK 0xc0000000
#define A3XX_TEX_CONST_0_TYPE__SHIFT 30
static inline uint32_t A3XX_TEX_CONST_0_TYPE(enum a3xx_tex_type val)
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 942e09d898a8..2773600c9488 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -392,13 +392,10 @@ static const unsigned int a3xx_registers[] = {
#ifdef CONFIG_DEBUG_FS
static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m)
{
- struct drm_device *dev = gpu->dev;
int i;
adreno_show(gpu, m);
- mutex_lock(&dev->struct_mutex);
-
gpu->funcs->pm_resume(gpu);
seq_printf(m, "status: %08x\n",
@@ -418,8 +415,6 @@ static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m)
}
gpu->funcs->pm_suspend(gpu);
-
- mutex_unlock(&dev->struct_mutex);
}
#endif
@@ -685,6 +680,8 @@ static int a3xx_remove(struct platform_device *pdev)
}
static const struct of_device_id dt_match[] = {
+ { .compatible = "qcom,adreno-3xx" },
+ /* for backwards compat w/ downstream kgsl DT files: */
{ .compatible = "qcom,kgsl-3d0" },
{}
};
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
index bb9a8ca0507b..85ff66cbddd6 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
@@ -19,6 +19,11 @@
#define __A3XX_GPU_H__
#include "adreno_gpu.h"
+
+/* arrg, somehow fb.h is getting pulled in: */
+#undef ROP_COPY
+#undef ROP_XOR
+
#include "a3xx.xml.h"
struct a3xx_gpu {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
index d6e6ce2d1abd..9de19ac2e86c 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
@@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32814 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 8900 bytes, from 2013-10-22 23:57:49)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 10574 bytes, from 2013-11-13 05:44:45)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 53644 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 8344 bytes, from 2013-11-30 14:49:47)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-05-16 11:51:57)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-06-25 12:57:16)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 26602 bytes, from 2014-06-25 12:57:16)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -87,15 +87,6 @@ enum adreno_rb_blend_factor {
FACTOR_SRC_ALPHA_SATURATE = 16,
};
-enum adreno_rb_blend_opcode {
- BLEND_DST_PLUS_SRC = 0,
- BLEND_SRC_MINUS_DST = 1,
- BLEND_MIN_DST_SRC = 2,
- BLEND_MAX_DST_SRC = 3,
- BLEND_DST_MINUS_SRC = 4,
- BLEND_DST_PLUS_SRC_BIAS = 5,
-};
-
enum adreno_rb_surface_endian {
ENDIAN_NONE = 0,
ENDIAN_8IN16 = 1,
@@ -116,6 +107,39 @@ enum adreno_rb_depth_format {
DEPTHX_24_8 = 1,
};
+enum adreno_rb_copy_control_mode {
+ RB_COPY_RESOLVE = 1,
+ RB_COPY_CLEAR = 2,
+ RB_COPY_DEPTH_STENCIL = 5,
+};
+
+enum a3xx_render_mode {
+ RB_RENDERING_PASS = 0,
+ RB_TILING_PASS = 1,
+ RB_RESOLVE_PASS = 2,
+ RB_COMPUTE_PASS = 3,
+};
+
+enum a3xx_msaa_samples {
+ MSAA_ONE = 0,
+ MSAA_TWO = 1,
+ MSAA_FOUR = 2,
+};
+
+enum a3xx_threadmode {
+ MULTI = 0,
+ SINGLE = 1,
+};
+
+enum a3xx_instrbuffermode {
+ BUFFER = 1,
+};
+
+enum a3xx_threadsize {
+ TWO_QUADS = 0,
+ FOUR_QUADS = 1,
+};
+
#define REG_AXXX_CP_RB_BASE 0x000001c0
#define REG_AXXX_CP_RB_CNTL 0x000001c1
@@ -264,6 +288,8 @@ static inline uint32_t AXXX_SCRATCH_UMSK_SWAP(uint32_t val)
#define REG_AXXX_CP_INT_ACK 0x000001f4
#define REG_AXXX_CP_ME_CNTL 0x000001f6
+#define AXXX_CP_ME_CNTL_BUSY 0x20000000
+#define AXXX_CP_ME_CNTL_HALT 0x10000000
#define REG_AXXX_CP_ME_STATUS 0x000001f7
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 28ca8cd8b09e..655ce5b14ad0 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -91,9 +91,17 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
int adreno_hw_init(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ int ret;
DBG("%s", gpu->name);
+ ret = msm_gem_get_iova(gpu->rb->bo, gpu->id, &gpu->rb_iova);
+ if (ret) {
+ gpu->rb_iova = 0;
+ dev_err(gpu->dev->dev, "could not map ringbuffer: %d\n", ret);
+ return ret;
+ }
+
/* Setup REG_CP_RB_CNTL: */
gpu_write(gpu, REG_AXXX_CP_RB_CNTL,
/* size is log2(quad-words): */
@@ -362,8 +370,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return ret;
}
+ mutex_lock(&drm->struct_mutex);
gpu->memptrs_bo = msm_gem_new(drm, sizeof(*gpu->memptrs),
MSM_BO_UNCACHED);
+ mutex_unlock(&drm->struct_mutex);
if (IS_ERR(gpu->memptrs_bo)) {
ret = PTR_ERR(gpu->memptrs_bo);
gpu->memptrs_bo = NULL;
@@ -371,13 +381,13 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return ret;
}
- gpu->memptrs = msm_gem_vaddr_locked(gpu->memptrs_bo);
+ gpu->memptrs = msm_gem_vaddr(gpu->memptrs_bo);
if (!gpu->memptrs) {
dev_err(drm->dev, "could not vmap memptrs\n");
return -ENOMEM;
}
- ret = msm_gem_get_iova_locked(gpu->memptrs_bo, gpu->base.id,
+ ret = msm_gem_get_iova(gpu->memptrs_bo, gpu->base.id,
&gpu->memptrs_iova);
if (ret) {
dev_err(drm->dev, "could not map memptrs: %d\n", ret);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
index ae992c71703f..4eee0ec8f069 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
@@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32814 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 8900 bytes, from 2013-10-22 23:57:49)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 10574 bytes, from 2013-11-13 05:44:45)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 53644 bytes, from 2013-11-30 15:07:33)
-- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 8344 bytes, from 2013-11-30 14:49:47)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-05-16 11:51:57)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-06-25 12:57:16)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 26602 bytes, from 2014-06-25 12:57:16)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -105,6 +105,7 @@ enum pc_di_index_size {
enum pc_di_vis_cull_mode {
IGNORE_VISIBILITY = 0,
+ USE_VISIBILITY = 1,
};
enum adreno_pm4_packet_type {
@@ -163,6 +164,11 @@ enum adreno_pm4_type3_packets {
CP_SET_BIN = 76,
CP_TEST_TWO_MEMS = 113,
CP_WAIT_FOR_ME = 19,
+ CP_SET_DRAW_STATE = 67,
+ CP_DRAW_INDX_OFFSET = 56,
+ CP_DRAW_INDIRECT = 40,
+ CP_DRAW_INDX_INDIRECT = 41,
+ CP_DRAW_AUTO = 36,
IN_IB_PREFETCH_END = 23,
IN_SUBBLK_PREFETCH = 31,
IN_INSTR_PREFETCH = 32,
@@ -232,6 +238,211 @@ static inline uint32_t CP_LOAD_STATE_1_EXT_SRC_ADDR(uint32_t val)
return ((val >> 2) << CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT) & CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK;
}
+#define REG_CP_DRAW_INDX_0 0x00000000
+#define CP_DRAW_INDX_0_VIZ_QUERY__MASK 0xffffffff
+#define CP_DRAW_INDX_0_VIZ_QUERY__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_0_VIZ_QUERY(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_0_VIZ_QUERY__SHIFT) & CP_DRAW_INDX_0_VIZ_QUERY__MASK;
+}
+
+#define REG_CP_DRAW_INDX_1 0x00000001
+#define CP_DRAW_INDX_1_PRIM_TYPE__MASK 0x0000003f
+#define CP_DRAW_INDX_1_PRIM_TYPE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_1_PRIM_TYPE(enum pc_di_primtype val)
+{
+ return ((val) << CP_DRAW_INDX_1_PRIM_TYPE__SHIFT) & CP_DRAW_INDX_1_PRIM_TYPE__MASK;
+}
+#define CP_DRAW_INDX_1_SOURCE_SELECT__MASK 0x000000c0
+#define CP_DRAW_INDX_1_SOURCE_SELECT__SHIFT 6
+static inline uint32_t CP_DRAW_INDX_1_SOURCE_SELECT(enum pc_di_src_sel val)
+{
+ return ((val) << CP_DRAW_INDX_1_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_1_SOURCE_SELECT__MASK;
+}
+#define CP_DRAW_INDX_1_VIS_CULL__MASK 0x00000600
+#define CP_DRAW_INDX_1_VIS_CULL__SHIFT 9
+static inline uint32_t CP_DRAW_INDX_1_VIS_CULL(enum pc_di_vis_cull_mode val)
+{
+ return ((val) << CP_DRAW_INDX_1_VIS_CULL__SHIFT) & CP_DRAW_INDX_1_VIS_CULL__MASK;
+}
+#define CP_DRAW_INDX_1_INDEX_SIZE__MASK 0x00000800
+#define CP_DRAW_INDX_1_INDEX_SIZE__SHIFT 11
+static inline uint32_t CP_DRAW_INDX_1_INDEX_SIZE(enum pc_di_index_size val)
+{
+ return ((val) << CP_DRAW_INDX_1_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_1_INDEX_SIZE__MASK;
+}
+#define CP_DRAW_INDX_1_NOT_EOP 0x00001000
+#define CP_DRAW_INDX_1_SMALL_INDEX 0x00002000
+#define CP_DRAW_INDX_1_PRE_DRAW_INITIATOR_ENABLE 0x00004000
+#define CP_DRAW_INDX_1_NUM_INDICES__MASK 0xffff0000
+#define CP_DRAW_INDX_1_NUM_INDICES__SHIFT 16
+static inline uint32_t CP_DRAW_INDX_1_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_1_NUM_INDICES__SHIFT) & CP_DRAW_INDX_1_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2 0x00000002
+#define CP_DRAW_INDX_2_NUM_INDICES__MASK 0xffffffff
+#define CP_DRAW_INDX_2_NUM_INDICES__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_NUM_INDICES__SHIFT) & CP_DRAW_INDX_2_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2 0x00000002
+#define CP_DRAW_INDX_2_INDX_BASE__MASK 0xffffffff
+#define CP_DRAW_INDX_2_INDX_BASE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_INDX_BASE(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_INDX_BASE__SHIFT) & CP_DRAW_INDX_2_INDX_BASE__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2 0x00000002
+#define CP_DRAW_INDX_2_INDX_SIZE__MASK 0xffffffff
+#define CP_DRAW_INDX_2_INDX_SIZE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_INDX_SIZE(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_INDX_SIZE__SHIFT) & CP_DRAW_INDX_2_INDX_SIZE__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2_0 0x00000000
+#define CP_DRAW_INDX_2_0_VIZ_QUERY__MASK 0xffffffff
+#define CP_DRAW_INDX_2_0_VIZ_QUERY__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_0_VIZ_QUERY(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_0_VIZ_QUERY__SHIFT) & CP_DRAW_INDX_2_0_VIZ_QUERY__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2_1 0x00000001
+#define CP_DRAW_INDX_2_1_PRIM_TYPE__MASK 0x0000003f
+#define CP_DRAW_INDX_2_1_PRIM_TYPE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_1_PRIM_TYPE(enum pc_di_primtype val)
+{
+ return ((val) << CP_DRAW_INDX_2_1_PRIM_TYPE__SHIFT) & CP_DRAW_INDX_2_1_PRIM_TYPE__MASK;
+}
+#define CP_DRAW_INDX_2_1_SOURCE_SELECT__MASK 0x000000c0
+#define CP_DRAW_INDX_2_1_SOURCE_SELECT__SHIFT 6
+static inline uint32_t CP_DRAW_INDX_2_1_SOURCE_SELECT(enum pc_di_src_sel val)
+{
+ return ((val) << CP_DRAW_INDX_2_1_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_2_1_SOURCE_SELECT__MASK;
+}
+#define CP_DRAW_INDX_2_1_VIS_CULL__MASK 0x00000600
+#define CP_DRAW_INDX_2_1_VIS_CULL__SHIFT 9
+static inline uint32_t CP_DRAW_INDX_2_1_VIS_CULL(enum pc_di_vis_cull_mode val)
+{
+ return ((val) << CP_DRAW_INDX_2_1_VIS_CULL__SHIFT) & CP_DRAW_INDX_2_1_VIS_CULL__MASK;
+}
+#define CP_DRAW_INDX_2_1_INDEX_SIZE__MASK 0x00000800
+#define CP_DRAW_INDX_2_1_INDEX_SIZE__SHIFT 11
+static inline uint32_t CP_DRAW_INDX_2_1_INDEX_SIZE(enum pc_di_index_size val)
+{
+ return ((val) << CP_DRAW_INDX_2_1_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_2_1_INDEX_SIZE__MASK;
+}
+#define CP_DRAW_INDX_2_1_NOT_EOP 0x00001000
+#define CP_DRAW_INDX_2_1_SMALL_INDEX 0x00002000
+#define CP_DRAW_INDX_2_1_PRE_DRAW_INITIATOR_ENABLE 0x00004000
+#define CP_DRAW_INDX_2_1_NUM_INDICES__MASK 0xffff0000
+#define CP_DRAW_INDX_2_1_NUM_INDICES__SHIFT 16
+static inline uint32_t CP_DRAW_INDX_2_1_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_1_NUM_INDICES__SHIFT) & CP_DRAW_INDX_2_1_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_2_2 0x00000002
+#define CP_DRAW_INDX_2_2_NUM_INDICES__MASK 0xffffffff
+#define CP_DRAW_INDX_2_2_NUM_INDICES__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_2_2_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_2_2_NUM_INDICES__SHIFT) & CP_DRAW_INDX_2_2_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_OFFSET_0 0x00000000
+#define CP_DRAW_INDX_OFFSET_0_PRIM_TYPE__MASK 0x0000003f
+#define CP_DRAW_INDX_OFFSET_0_PRIM_TYPE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(enum pc_di_primtype val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_0_PRIM_TYPE__SHIFT) & CP_DRAW_INDX_OFFSET_0_PRIM_TYPE__MASK;
+}
+#define CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__MASK 0x000000c0
+#define CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__SHIFT 6
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(enum pc_di_src_sel val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__MASK;
+}
+#define CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK 0x00000700
+#define CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT 8
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_VIS_CULL(enum pc_di_vis_cull_mode val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT) & CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK;
+}
+#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK 0x00000800
+#define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT 11
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum pc_di_index_size val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK;
+}
+#define CP_DRAW_INDX_OFFSET_0_NOT_EOP 0x00001000
+#define CP_DRAW_INDX_OFFSET_0_SMALL_INDEX 0x00002000
+#define CP_DRAW_INDX_OFFSET_0_PRE_DRAW_INITIATOR_ENABLE 0x00004000
+#define CP_DRAW_INDX_OFFSET_0_NUM_INDICES__MASK 0xffff0000
+#define CP_DRAW_INDX_OFFSET_0_NUM_INDICES__SHIFT 16
+static inline uint32_t CP_DRAW_INDX_OFFSET_0_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_0_NUM_INDICES__SHIFT) & CP_DRAW_INDX_OFFSET_0_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_OFFSET_1 0x00000001
+
+#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002
+#define CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK 0xffffffff
+#define CP_DRAW_INDX_OFFSET_2_NUM_INDICES__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_OFFSET_2_NUM_INDICES(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_2_NUM_INDICES__SHIFT) & CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK;
+}
+
+#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002
+#define CP_DRAW_INDX_OFFSET_2_INDX_BASE__MASK 0xffffffff
+#define CP_DRAW_INDX_OFFSET_2_INDX_BASE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_OFFSET_2_INDX_BASE(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_2_INDX_BASE__SHIFT) & CP_DRAW_INDX_OFFSET_2_INDX_BASE__MASK;
+}
+
+#define REG_CP_DRAW_INDX_OFFSET_2 0x00000002
+#define CP_DRAW_INDX_OFFSET_2_INDX_SIZE__MASK 0xffffffff
+#define CP_DRAW_INDX_OFFSET_2_INDX_SIZE__SHIFT 0
+static inline uint32_t CP_DRAW_INDX_OFFSET_2_INDX_SIZE(uint32_t val)
+{
+ return ((val) << CP_DRAW_INDX_OFFSET_2_INDX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_2_INDX_SIZE__MASK;
+}
+
+#define REG_CP_SET_DRAW_STATE_0 0x00000000
+#define CP_SET_DRAW_STATE_0_COUNT__MASK 0x0000ffff
+#define CP_SET_DRAW_STATE_0_COUNT__SHIFT 0
+static inline uint32_t CP_SET_DRAW_STATE_0_COUNT(uint32_t val)
+{
+ return ((val) << CP_SET_DRAW_STATE_0_COUNT__SHIFT) & CP_SET_DRAW_STATE_0_COUNT__MASK;
+}
+#define CP_SET_DRAW_STATE_0_DIRTY 0x00010000
+#define CP_SET_DRAW_STATE_0_DISABLE 0x00020000
+#define CP_SET_DRAW_STATE_0_DISABLE_ALL_GROUPS 0x00040000
+#define CP_SET_DRAW_STATE_0_LOAD_IMMED 0x00080000
+#define CP_SET_DRAW_STATE_0_GROUP_ID__MASK 0x1f000000
+#define CP_SET_DRAW_STATE_0_GROUP_ID__SHIFT 24
+static inline uint32_t CP_SET_DRAW_STATE_0_GROUP_ID(uint32_t val)
+{
+ return ((val) << CP_SET_DRAW_STATE_0_GROUP_ID__SHIFT) & CP_SET_DRAW_STATE_0_GROUP_ID__MASK;
+}
+
+#define REG_CP_SET_DRAW_STATE_1 0x00000001
+#define CP_SET_DRAW_STATE_1_ADDR__MASK 0xffffffff
+#define CP_SET_DRAW_STATE_1_ADDR__SHIFT 0
+static inline uint32_t CP_SET_DRAW_STATE_1_ADDR(uint32_t val)
+{
+ return ((val) << CP_SET_DRAW_STATE_1_ADDR__SHIFT) & CP_SET_DRAW_STATE_1_ADDR__MASK;
+}
+
#define REG_CP_SET_BIN_0 0x00000000
#define REG_CP_SET_BIN_1 0x00000001
@@ -262,5 +473,21 @@ static inline uint32_t CP_SET_BIN_2_Y2(uint32_t val)
return ((val) << CP_SET_BIN_2_Y2__SHIFT) & CP_SET_BIN_2_Y2__MASK;
}
+#define REG_CP_SET_BIN_DATA_0 0x00000000
+#define CP_SET_BIN_DATA_0_BIN_DATA_ADDR__MASK 0xffffffff
+#define CP_SET_BIN_DATA_0_BIN_DATA_ADDR__SHIFT 0
+static inline uint32_t CP_SET_BIN_DATA_0_BIN_DATA_ADDR(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_DATA_0_BIN_DATA_ADDR__SHIFT) & CP_SET_BIN_DATA_0_BIN_DATA_ADDR__MASK;
+}
+
+#define REG_CP_SET_BIN_DATA_1 0x00000001
+#define CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__MASK 0xffffffff
+#define CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__SHIFT 0
+static inline uint32_t CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS(uint32_t val)
+{
+ return ((val) << CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__SHIFT) & CP_SET_BIN_DATA_1_BIN_SIZE_ADDRESS__MASK;
+}
+
#endif /* ADRENO_PM4_XML */
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 87be647e3825..0f1f5b9459a5 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
index 747a6ef4211f..d468f86f637c 100644
--- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
+++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
index 48e03acf19bf..da8740054cdf 100644
--- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h
+++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 7f7aadef8a82..a125a7e32742 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -123,7 +123,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
for (i = 0; i < config->hpd_reg_cnt; i++) {
struct regulator *reg;
- reg = devm_regulator_get(&pdev->dev, config->hpd_reg_names[i]);
+ reg = devm_regulator_get_exclusive(&pdev->dev,
+ config->hpd_reg_names[i]);
if (IS_ERR(reg)) {
ret = PTR_ERR(reg);
dev_err(dev->dev, "failed to get hpd regulator: %s (%d)\n",
@@ -138,7 +139,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder)
for (i = 0; i < config->pwr_reg_cnt; i++) {
struct regulator *reg;
- reg = devm_regulator_get(&pdev->dev, config->pwr_reg_names[i]);
+ reg = devm_regulator_get_exclusive(&pdev->dev,
+ config->pwr_reg_names[i]);
if (IS_ERR(reg)) {
ret = PTR_ERR(reg);
dev_err(dev->dev, "failed to get pwr regulator: %s (%d)\n",
@@ -266,37 +268,56 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
{
int gpio = of_get_named_gpio(of_node, name, 0);
if (gpio < 0) {
- dev_err(dev, "failed to get gpio: %s (%d)\n",
- name, gpio);
- gpio = -1;
+ char name2[32];
+ snprintf(name2, sizeof(name2), "%s-gpio", name);
+ gpio = of_get_named_gpio(of_node, name2, 0);
+ if (gpio < 0) {
+ dev_err(dev, "failed to get gpio: %s (%d)\n",
+ name, gpio);
+ gpio = -1;
+ }
}
return gpio;
}
- /* TODO actually use DT.. */
- static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"};
- static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"};
- static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"};
- static unsigned long hpd_clk_freq[] = {0, 19200000, 0};
- static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"};
+ if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) {
+ static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"};
+ static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"};
+ static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"};
+ static unsigned long hpd_clk_freq[] = {0, 19200000, 0};
+ static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"};
+ config.phy_init = hdmi_phy_8x74_init;
+ config.hpd_reg_names = hpd_reg_names;
+ config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names);
+ config.pwr_reg_names = pwr_reg_names;
+ config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names);
+ config.hpd_clk_names = hpd_clk_names;
+ config.hpd_freq = hpd_clk_freq;
+ config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names);
+ config.pwr_clk_names = pwr_clk_names;
+ config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names);
+ config.shared_irq = true;
+ } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) {
+ static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"};
+ static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"};
+ config.phy_init = hdmi_phy_8960_init;
+ config.hpd_reg_names = hpd_reg_names;
+ config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names);
+ config.hpd_clk_names = hpd_clk_names;
+ config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names);
+ } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8660")) {
+ config.phy_init = hdmi_phy_8x60_init;
+ } else {
+ dev_err(dev, "unknown phy: %s\n", of_node->name);
+ }
- config.phy_init = hdmi_phy_8x74_init;
config.mmio_name = "core_physical";
- config.hpd_reg_names = hpd_reg_names;
- config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names);
- config.pwr_reg_names = pwr_reg_names;
- config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names);
- config.hpd_clk_names = hpd_clk_names;
- config.hpd_freq = hpd_clk_freq;
- config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names);
- config.pwr_clk_names = pwr_clk_names;
- config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names);
config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk");
config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data");
config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd");
config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en");
config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel");
- config.shared_irq = true;
+ config.mux_lpm_gpio = get_gpio("qcom,hdmi-tx-mux-lpm");
#else
static const char *hpd_clk_names[] = {
@@ -373,7 +394,9 @@ static int hdmi_dev_remove(struct platform_device *pdev)
}
static const struct of_device_id dt_match[] = {
- { .compatible = "qcom,hdmi-tx" },
+ { .compatible = "qcom,hdmi-tx-8074" },
+ { .compatible = "qcom,hdmi-tx-8960" },
+ { .compatible = "qcom,hdmi-tx-8660" },
{}
};
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 9d7723c6528a..b981995410b5 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -96,6 +96,7 @@ struct hdmi_platform_config {
/* gpio's: */
int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, mux_en_gpio, mux_sel_gpio;
+ int mux_lpm_gpio;
/* older devices had their own irq, mdp5+ it is shared w/ mdp: */
bool shared_irq;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
index e2636582cfd7..e89fe053d375 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
@@ -12,14 +12,14 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -148,9 +148,9 @@ static inline uint32_t REG_HDMI_GENERIC0(uint32_t i0) { return 0x00000088 + 0x4*
static inline uint32_t REG_HDMI_GENERIC1(uint32_t i0) { return 0x000000a8 + 0x4*i0; }
-static inline uint32_t REG_HDMI_ACR(uint32_t i0) { return 0x000000c4 + 0x8*i0; }
+static inline uint32_t REG_HDMI_ACR(enum hdmi_acr_cts i0) { return 0x000000c4 + 0x8*i0; }
-static inline uint32_t REG_HDMI_ACR_0(uint32_t i0) { return 0x000000c4 + 0x8*i0; }
+static inline uint32_t REG_HDMI_ACR_0(enum hdmi_acr_cts i0) { return 0x000000c4 + 0x8*i0; }
#define HDMI_ACR_0_CTS__MASK 0xfffff000
#define HDMI_ACR_0_CTS__SHIFT 12
static inline uint32_t HDMI_ACR_0_CTS(uint32_t val)
@@ -158,7 +158,7 @@ static inline uint32_t HDMI_ACR_0_CTS(uint32_t val)
return ((val) << HDMI_ACR_0_CTS__SHIFT) & HDMI_ACR_0_CTS__MASK;
}
-static inline uint32_t REG_HDMI_ACR_1(uint32_t i0) { return 0x000000c8 + 0x8*i0; }
+static inline uint32_t REG_HDMI_ACR_1(enum hdmi_acr_cts i0) { return 0x000000c8 + 0x8*i0; }
#define HDMI_ACR_1_N__MASK 0xffffffff
#define HDMI_ACR_1_N__SHIFT 0
static inline uint32_t HDMI_ACR_1_N(uint32_t val)
@@ -552,6 +552,103 @@ static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val)
#define REG_HDMI_8960_PHY_REG11 0x0000042c
#define REG_HDMI_8960_PHY_REG12 0x00000430
+#define HDMI_8960_PHY_REG12_SW_RESET 0x00000020
+#define HDMI_8960_PHY_REG12_PWRDN_B 0x00000080
+
+#define REG_HDMI_8960_PHY_REG_BIST_CFG 0x00000434
+
+#define REG_HDMI_8960_PHY_DEBUG_BUS_SEL 0x00000438
+
+#define REG_HDMI_8960_PHY_REG_MISC0 0x0000043c
+
+#define REG_HDMI_8960_PHY_REG13 0x00000440
+
+#define REG_HDMI_8960_PHY_REG14 0x00000444
+
+#define REG_HDMI_8960_PHY_REG15 0x00000448
+
+#define REG_HDMI_8960_PHY_PLL_REFCLK_CFG 0x00000500
+
+#define REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG 0x00000504
+
+#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 0x00000508
+
+#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 0x0000050c
+
+#define REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG 0x00000510
+
+#define REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG 0x00000514
+
+#define REG_HDMI_8960_PHY_PLL_PWRDN_B 0x00000518
+#define HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL 0x00000002
+#define HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B 0x00000008
+
+#define REG_HDMI_8960_PHY_PLL_SDM_CFG0 0x0000051c
+
+#define REG_HDMI_8960_PHY_PLL_SDM_CFG1 0x00000520
+
+#define REG_HDMI_8960_PHY_PLL_SDM_CFG2 0x00000524
+
+#define REG_HDMI_8960_PHY_PLL_SDM_CFG3 0x00000528
+
+#define REG_HDMI_8960_PHY_PLL_SDM_CFG4 0x0000052c
+
+#define REG_HDMI_8960_PHY_PLL_SSC_CFG0 0x00000530
+
+#define REG_HDMI_8960_PHY_PLL_SSC_CFG1 0x00000534
+
+#define REG_HDMI_8960_PHY_PLL_SSC_CFG2 0x00000538
+
+#define REG_HDMI_8960_PHY_PLL_SSC_CFG3 0x0000053c
+
+#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 0x00000540
+
+#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 0x00000544
+
+#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 0x00000548
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 0x0000054c
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 0x00000550
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 0x00000554
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 0x00000558
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 0x0000055c
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 0x00000560
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 0x00000564
+
+#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 0x00000568
+
+#define REG_HDMI_8960_PHY_PLL_DEBUG_SEL 0x0000056c
+
+#define REG_HDMI_8960_PHY_PLL_MISC0 0x00000570
+
+#define REG_HDMI_8960_PHY_PLL_MISC1 0x00000574
+
+#define REG_HDMI_8960_PHY_PLL_MISC2 0x00000578
+
+#define REG_HDMI_8960_PHY_PLL_MISC3 0x0000057c
+
+#define REG_HDMI_8960_PHY_PLL_MISC4 0x00000580
+
+#define REG_HDMI_8960_PHY_PLL_MISC5 0x00000584
+
+#define REG_HDMI_8960_PHY_PLL_MISC6 0x00000588
+
+#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS0 0x0000058c
+
+#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS1 0x00000590
+
+#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS2 0x00000594
+
+#define REG_HDMI_8960_PHY_PLL_STATUS0 0x00000598
+#define HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK 0x00000001
+
+#define REG_HDMI_8960_PHY_PLL_STATUS1 0x0000059c
#define REG_HDMI_8x74_ANA_CFG0 0x00000000
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index 28f7e3ec6c28..4aca2a3c667c 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -63,7 +63,7 @@ static int gpio_config(struct hdmi *hdmi, bool on)
ret = gpio_request(config->mux_en_gpio, "HDMI_MUX_EN");
if (ret) {
dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
- "HDMI_MUX_SEL", config->mux_en_gpio, ret);
+ "HDMI_MUX_EN", config->mux_en_gpio, ret);
goto error4;
}
gpio_set_value_cansleep(config->mux_en_gpio, 1);
@@ -78,6 +78,19 @@ static int gpio_config(struct hdmi *hdmi, bool on)
}
gpio_set_value_cansleep(config->mux_sel_gpio, 0);
}
+
+ if (config->mux_lpm_gpio != -1) {
+ ret = gpio_request(config->mux_lpm_gpio,
+ "HDMI_MUX_LPM");
+ if (ret) {
+ dev_err(dev->dev,
+ "'%s'(%d) gpio_request failed: %d\n",
+ "HDMI_MUX_LPM",
+ config->mux_lpm_gpio, ret);
+ goto error6;
+ }
+ gpio_set_value_cansleep(config->mux_lpm_gpio, 1);
+ }
DBG("gpio on");
} else {
gpio_free(config->ddc_clk_gpio);
@@ -93,11 +106,19 @@ static int gpio_config(struct hdmi *hdmi, bool on)
gpio_set_value_cansleep(config->mux_sel_gpio, 1);
gpio_free(config->mux_sel_gpio);
}
+
+ if (config->mux_lpm_gpio != -1) {
+ gpio_set_value_cansleep(config->mux_lpm_gpio, 0);
+ gpio_free(config->mux_lpm_gpio);
+ }
DBG("gpio off");
}
return 0;
+error6:
+ if (config->mux_sel_gpio != -1)
+ gpio_free(config->mux_sel_gpio);
error5:
if (config->mux_en_gpio != -1)
gpio_free(config->mux_en_gpio);
@@ -306,7 +327,7 @@ static void hdmi_connector_destroy(struct drm_connector *connector)
hdp_disable(hdmi_connector);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
hdmi_unreference(hdmi_connector->hdmi);
@@ -416,7 +437,7 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi)
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
ret = hpd_enable(hdmi_connector);
if (ret) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
index e5b7ed5b8f01..902d7685d441 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
@@ -15,13 +15,370 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
#include "hdmi.h"
struct hdmi_phy_8960 {
struct hdmi_phy base;
struct hdmi *hdmi;
+ struct clk_hw pll_hw;
+ struct clk *pll;
+ unsigned long pixclk;
};
#define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base)
+#define clk_to_phy(x) container_of(x, struct hdmi_phy_8960, pll_hw)
+
+/*
+ * HDMI PLL:
+ *
+ * To get the parent clock setup properly, we need to plug in hdmi pll
+ * configuration into common-clock-framework.
+ */
+
+struct pll_rate {
+ unsigned long rate;
+ struct {
+ uint32_t val;
+ uint32_t reg;
+ } conf[32];
+};
+
+/* NOTE: keep sorted highest freq to lowest: */
+static const struct pll_rate freqtbl[] = {
+ /* 1080p60/1080p50 case */
+ { 148500000, {
+ { 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+ { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
+ { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+ { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
+ { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
+ { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
+ { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
+ { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
+ { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
+ { 0, 0 } }
+ },
+ { 108000000, {
+ { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0, 0 } }
+ },
+ /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */
+ { 74250000, {
+ { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
+ { 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0, 0 } }
+ },
+ { 65000000, {
+ { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0, 0 } }
+ },
+ /* 480p60/480i60 */
+ { 27030000, {
+ { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
+ { 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+ { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
+ { 0, 0 } }
+ },
+ /* 576p50/576i50 */
+ { 27000000, {
+ { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+ { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
+ { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+ { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
+ { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
+ { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
+ { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
+ { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
+ { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
+ { 0, 0 } }
+ },
+ /* 640x480p60 */
+ { 25200000, {
+ { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
+ { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+ { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+ { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
+ { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+ { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
+ { 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
+ { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
+ { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
+ { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
+ { 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
+ { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
+ { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
+ { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
+ { 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
+ { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
+ { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
+ { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
+ { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
+ { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
+ { 0, 0 } }
+ },
+};
+
+static int hdmi_pll_enable(struct clk_hw *hw)
+{
+ struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw);
+ struct hdmi *hdmi = phy_8960->hdmi;
+ int timeout_count, pll_lock_retry = 10;
+ unsigned int val;
+
+ DBG("");
+
+ /* Assert PLL S/W reset */
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10);
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a);
+
+ /* Wait for a short time before de-asserting
+ * to allow the hardware to complete its job.
+ * This much of delay should be fine for hardware
+ * to assert and de-assert.
+ */
+ udelay(10);
+
+ /* De-assert PLL S/W reset */
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);
+
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12);
+ val |= HDMI_8960_PHY_REG12_SW_RESET;
+ /* Assert PHY S/W reset */
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
+ val &= ~HDMI_8960_PHY_REG12_SW_RESET;
+ /* Wait for a short time before de-asserting
+ to allow the hardware to complete its job.
+ This much of delay should be fine for hardware
+ to assert and de-assert. */
+ udelay(10);
+ /* De-assert PHY S/W reset */
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x3f);
+
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12);
+ val |= HDMI_8960_PHY_REG12_PWRDN_B;
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
+ /* Wait 10 us for enabling global power for PHY */
+ mb();
+ udelay(10);
+
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B);
+ val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B;
+ val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL;
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B, val);
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x80);
+
+ timeout_count = 1000;
+ while (--pll_lock_retry > 0) {
+
+ /* are we there yet? */
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_STATUS0);
+ if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK)
+ break;
+
+ udelay(1);
+
+ if (--timeout_count > 0)
+ continue;
+
+ /*
+ * PLL has still not locked.
+ * Do a software reset and try again
+ * Assert PLL S/W reset first
+ */
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
+ udelay(10);
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);
+
+ /*
+ * Wait for a short duration for the PLL calibration
+ * before checking if the PLL gets locked
+ */
+ udelay(350);
+
+ timeout_count = 1000;
+ }
+
+ return 0;
+}
+
+static void hdmi_pll_disable(struct clk_hw *hw)
+{
+ struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw);
+ struct hdmi *hdmi = phy_8960->hdmi;
+ unsigned int val;
+
+ DBG("");
+
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_REG12);
+ val &= ~HDMI_8960_PHY_REG12_PWRDN_B;
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG12, val);
+
+ val = hdmi_read(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B);
+ val |= HDMI_8960_PHY_REG12_SW_RESET;
+ val &= ~HDMI_8960_PHY_REG12_PWRDN_B;
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_PLL_PWRDN_B, val);
+ /* Make sure HDMI PHY/PLL are powered down */
+ mb();
+}
+
+static const struct pll_rate *find_rate(unsigned long rate)
+{
+ int i;
+ for (i = 1; i < ARRAY_SIZE(freqtbl); i++)
+ if (rate > freqtbl[i].rate)
+ return &freqtbl[i-1];
+ return &freqtbl[i-1];
+}
+
+static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw);
+ return phy_8960->pixclk;
+}
+
+static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ const struct pll_rate *pll_rate = find_rate(rate);
+ return pll_rate->rate;
+}
+
+static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct hdmi_phy_8960 *phy_8960 = clk_to_phy(hw);
+ struct hdmi *hdmi = phy_8960->hdmi;
+ const struct pll_rate *pll_rate = find_rate(rate);
+ int i;
+
+ DBG("rate=%lu", rate);
+
+ for (i = 0; pll_rate->conf[i].reg; i++)
+ hdmi_write(hdmi, pll_rate->conf[i].reg, pll_rate->conf[i].val);
+
+ phy_8960->pixclk = rate;
+
+ return 0;
+}
+
+
+static const struct clk_ops hdmi_pll_ops = {
+ .enable = hdmi_pll_enable,
+ .disable = hdmi_pll_disable,
+ .recalc_rate = hdmi_pll_recalc_rate,
+ .round_rate = hdmi_pll_round_rate,
+ .set_rate = hdmi_pll_set_rate,
+};
+
+static const char *hdmi_pll_parents[] = {
+ "pxo",
+};
+
+static struct clk_init_data pll_init = {
+ .name = "hdmi_pll",
+ .ops = &hdmi_pll_ops,
+ .parent_names = hdmi_pll_parents,
+ .num_parents = ARRAY_SIZE(hdmi_pll_parents),
+};
+
+
+/*
+ * HDMI Phy:
+ */
static void hdmi_phy_8960_destroy(struct hdmi_phy *phy)
{
@@ -86,6 +443,9 @@ static void hdmi_phy_8960_powerup(struct hdmi_phy *phy,
struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
struct hdmi *hdmi = phy_8960->hdmi;
+ DBG("pixclock: %lu", pixclock);
+
+ hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x00);
hdmi_write(hdmi, REG_HDMI_8960_PHY_REG0, 0x1b);
hdmi_write(hdmi, REG_HDMI_8960_PHY_REG1, 0xf2);
hdmi_write(hdmi, REG_HDMI_8960_PHY_REG4, 0x00);
@@ -104,6 +464,8 @@ static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy)
struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
struct hdmi *hdmi = phy_8960->hdmi;
+ DBG("");
+
hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x7f);
}
@@ -118,7 +480,12 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi)
{
struct hdmi_phy_8960 *phy_8960;
struct hdmi_phy *phy = NULL;
- int ret;
+ int ret, i;
+
+ /* sanity check: */
+ for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++)
+ if (WARN_ON(freqtbl[i].rate < freqtbl[i+1].rate))
+ return ERR_PTR(-EINVAL);
phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL);
if (!phy_8960) {
@@ -132,6 +499,14 @@ struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi)
phy_8960->hdmi = hdmi;
+ phy_8960->pll_hw.init = &pll_init;
+ phy_8960->pll = devm_clk_register(hdmi->dev->dev, &phy_8960->pll_hw);
+ if (IS_ERR(phy_8960->pll)) {
+ ret = PTR_ERR(phy_8960->pll);
+ phy_8960->pll = NULL;
+ goto fail;
+ }
+
return phy;
fail:
diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
index d591567173c4..bd81db6a7829 100644
--- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
+++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
index 416a26e1e58d..122208e8a2ee 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 0bb4faa17523..733646c0d3f8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -147,7 +147,7 @@ static void mdp4_destroy(struct msm_kms *kms)
if (mdp4_kms->blank_cursor_iova)
msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
if (mdp4_kms->blank_cursor_bo)
- drm_gem_object_unreference(mdp4_kms->blank_cursor_bo);
+ drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
kfree(mdp4_kms);
}
@@ -176,6 +176,8 @@ int mdp4_disable(struct mdp4_kms *mdp4_kms)
if (mdp4_kms->pclk)
clk_disable_unprepare(mdp4_kms->pclk);
clk_disable_unprepare(mdp4_kms->lut_clk);
+ if (mdp4_kms->axi_clk)
+ clk_disable_unprepare(mdp4_kms->axi_clk);
return 0;
}
@@ -188,6 +190,8 @@ int mdp4_enable(struct mdp4_kms *mdp4_kms)
if (mdp4_kms->pclk)
clk_prepare_enable(mdp4_kms->pclk);
clk_prepare_enable(mdp4_kms->lut_clk);
+ if (mdp4_kms->axi_clk)
+ clk_prepare_enable(mdp4_kms->axi_clk);
return 0;
}
@@ -294,15 +298,17 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
goto fail;
}
- mdp4_kms->dsi_pll_vdda = devm_regulator_get(&pdev->dev, "dsi_pll_vdda");
+ mdp4_kms->dsi_pll_vdda =
+ devm_regulator_get_optional(&pdev->dev, "dsi_pll_vdda");
if (IS_ERR(mdp4_kms->dsi_pll_vdda))
mdp4_kms->dsi_pll_vdda = NULL;
- mdp4_kms->dsi_pll_vddio = devm_regulator_get(&pdev->dev, "dsi_pll_vddio");
+ mdp4_kms->dsi_pll_vddio =
+ devm_regulator_get_optional(&pdev->dev, "dsi_pll_vddio");
if (IS_ERR(mdp4_kms->dsi_pll_vddio))
mdp4_kms->dsi_pll_vddio = NULL;
- mdp4_kms->vdd = devm_regulator_get(&pdev->dev, "vdd");
+ mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd");
if (IS_ERR(mdp4_kms->vdd))
mdp4_kms->vdd = NULL;
@@ -333,6 +339,13 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
goto fail;
}
+ mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "mdp_axi_clk");
+ if (IS_ERR(mdp4_kms->axi_clk)) {
+ dev_err(dev->dev, "failed to get axi_clk\n");
+ ret = PTR_ERR(mdp4_kms->axi_clk);
+ goto fail;
+ }
+
clk_set_rate(mdp4_kms->clk, config->max_clk);
clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
@@ -348,7 +361,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
mdelay(16);
if (config->iommu) {
- mmu = msm_iommu_new(dev, config->iommu);
+ mmu = msm_iommu_new(&pdev->dev, config->iommu);
if (IS_ERR(mmu)) {
ret = PTR_ERR(mmu);
goto fail;
@@ -406,6 +419,8 @@ static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev)
static struct mdp4_platform_config config = {};
#ifdef CONFIG_OF
/* TODO */
+ config.max_clk = 266667000;
+ config.iommu = iommu_domain_alloc(&platform_bus_type);
#else
if (cpu_is_apq8064())
config.max_clk = 266667000;
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
index 715520c54cde..3225da804c61 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
@@ -42,6 +42,7 @@ struct mdp4_kms {
struct clk *clk;
struct clk *pclk;
struct clk *lut_clk;
+ struct clk *axi_clk;
struct mdp_irq error_handler;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
index 0aa51517f826..67f4f896ba8c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h
@@ -12,14 +12,14 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
-Copyright (C) 2013 by the following authors:
+Copyright (C) 2013-2014 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
Permission is hereby granted, free of charge, to any person obtaining
@@ -68,6 +68,8 @@ enum mdp5_pipe {
SSPP_RGB2 = 5,
SSPP_DMA0 = 6,
SSPP_DMA1 = 7,
+ SSPP_VIG3 = 8,
+ SSPP_RGB3 = 9,
};
enum mdp5_ctl_mode {
@@ -126,7 +128,11 @@ enum mdp5_client_id {
CID_RGB0 = 16,
CID_RGB1 = 17,
CID_RGB2 = 18,
- CID_MAX = 19,
+ CID_VIG3_Y = 19,
+ CID_VIG3_CR = 20,
+ CID_VIG3_CB = 21,
+ CID_RGB3 = 22,
+ CID_MAX = 23,
};
enum mdp5_igc_type {
@@ -299,11 +305,34 @@ static inline uint32_t MDP5_IGC_LUT_REG_VAL(uint32_t val)
#define MDP5_IGC_LUT_REG_DISABLE_PIPE_1 0x20000000
#define MDP5_IGC_LUT_REG_DISABLE_PIPE_2 0x40000000
-static inline uint32_t REG_MDP5_CTL(uint32_t i0) { return 0x00000600 + 0x100*i0; }
+static inline uint32_t __offset_CTL(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return (mdp5_cfg->ctl.base[0]);
+ case 1: return (mdp5_cfg->ctl.base[1]);
+ case 2: return (mdp5_cfg->ctl.base[2]);
+ case 3: return (mdp5_cfg->ctl.base[3]);
+ case 4: return (mdp5_cfg->ctl.base[4]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_CTL(uint32_t i0) { return 0x00000000 + __offset_CTL(i0); }
-static inline uint32_t REG_MDP5_CTL_LAYER(uint32_t i0, uint32_t i1) { return 0x00000600 + 0x100*i0 + 0x4*i1; }
+static inline uint32_t __offset_LAYER(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return 0x00000000;
+ case 1: return 0x00000004;
+ case 2: return 0x00000008;
+ case 3: return 0x0000000c;
+ case 4: return 0x00000010;
+ case 5: return 0x00000024;
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_CTL_LAYER(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_CTL(i0) + __offset_LAYER(i1); }
-static inline uint32_t REG_MDP5_CTL_LAYER_REG(uint32_t i0, uint32_t i1) { return 0x00000600 + 0x100*i0 + 0x4*i1; }
+static inline uint32_t REG_MDP5_CTL_LAYER_REG(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_CTL(i0) + __offset_LAYER(i1); }
#define MDP5_CTL_LAYER_REG_VIG0__MASK 0x00000007
#define MDP5_CTL_LAYER_REG_VIG0__SHIFT 0
static inline uint32_t MDP5_CTL_LAYER_REG_VIG0(enum mdp_mixer_stage_id val)
@@ -354,8 +383,20 @@ static inline uint32_t MDP5_CTL_LAYER_REG_DMA1(enum mdp_mixer_stage_id val)
}
#define MDP5_CTL_LAYER_REG_BORDER_COLOR 0x01000000
#define MDP5_CTL_LAYER_REG_CURSOR_OUT 0x02000000
+#define MDP5_CTL_LAYER_REG_VIG3__MASK 0x1c000000
+#define MDP5_CTL_LAYER_REG_VIG3__SHIFT 26
+static inline uint32_t MDP5_CTL_LAYER_REG_VIG3(enum mdp_mixer_stage_id val)
+{
+ return ((val) << MDP5_CTL_LAYER_REG_VIG3__SHIFT) & MDP5_CTL_LAYER_REG_VIG3__MASK;
+}
+#define MDP5_CTL_LAYER_REG_RGB3__MASK 0xe0000000
+#define MDP5_CTL_LAYER_REG_RGB3__SHIFT 29
+static inline uint32_t MDP5_CTL_LAYER_REG_RGB3(enum mdp_mixer_stage_id val)
+{
+ return ((val) << MDP5_CTL_LAYER_REG_RGB3__SHIFT) & MDP5_CTL_LAYER_REG_RGB3__MASK;
+}
-static inline uint32_t REG_MDP5_CTL_OP(uint32_t i0) { return 0x00000614 + 0x100*i0; }
+static inline uint32_t REG_MDP5_CTL_OP(uint32_t i0) { return 0x00000014 + __offset_CTL(i0); }
#define MDP5_CTL_OP_MODE__MASK 0x0000000f
#define MDP5_CTL_OP_MODE__SHIFT 0
static inline uint32_t MDP5_CTL_OP_MODE(enum mdp5_ctl_mode val)
@@ -377,7 +418,7 @@ static inline uint32_t MDP5_CTL_OP_PACK_3D(enum mdp5_pack_3d val)
return ((val) << MDP5_CTL_OP_PACK_3D__SHIFT) & MDP5_CTL_OP_PACK_3D__MASK;
}
-static inline uint32_t REG_MDP5_CTL_FLUSH(uint32_t i0) { return 0x00000618 + 0x100*i0; }
+static inline uint32_t REG_MDP5_CTL_FLUSH(uint32_t i0) { return 0x00000018 + __offset_CTL(i0); }
#define MDP5_CTL_FLUSH_VIG0 0x00000001
#define MDP5_CTL_FLUSH_VIG1 0x00000002
#define MDP5_CTL_FLUSH_VIG2 0x00000004
@@ -387,26 +428,48 @@ static inline uint32_t REG_MDP5_CTL_FLUSH(uint32_t i0) { return 0x00000618 + 0x1
#define MDP5_CTL_FLUSH_LM0 0x00000040
#define MDP5_CTL_FLUSH_LM1 0x00000080
#define MDP5_CTL_FLUSH_LM2 0x00000100
+#define MDP5_CTL_FLUSH_LM3 0x00000200
+#define MDP5_CTL_FLUSH_LM4 0x00000400
#define MDP5_CTL_FLUSH_DMA0 0x00000800
#define MDP5_CTL_FLUSH_DMA1 0x00001000
#define MDP5_CTL_FLUSH_DSPP0 0x00002000
#define MDP5_CTL_FLUSH_DSPP1 0x00004000
#define MDP5_CTL_FLUSH_DSPP2 0x00008000
#define MDP5_CTL_FLUSH_CTL 0x00020000
+#define MDP5_CTL_FLUSH_VIG3 0x00040000
+#define MDP5_CTL_FLUSH_RGB3 0x00080000
+#define MDP5_CTL_FLUSH_LM5 0x00100000
+#define MDP5_CTL_FLUSH_DSPP3 0x00200000
-static inline uint32_t REG_MDP5_CTL_START(uint32_t i0) { return 0x0000061c + 0x100*i0; }
+static inline uint32_t REG_MDP5_CTL_START(uint32_t i0) { return 0x0000001c + __offset_CTL(i0); }
-static inline uint32_t REG_MDP5_CTL_PACK_3D(uint32_t i0) { return 0x00000620 + 0x100*i0; }
+static inline uint32_t REG_MDP5_CTL_PACK_3D(uint32_t i0) { return 0x00000020 + __offset_CTL(i0); }
-static inline uint32_t REG_MDP5_PIPE(enum mdp5_pipe i0) { return 0x00001200 + 0x400*i0; }
+static inline uint32_t __offset_PIPE(enum mdp5_pipe idx)
+{
+ switch (idx) {
+ case SSPP_VIG0: return (mdp5_cfg->pipe_vig.base[0]);
+ case SSPP_VIG1: return (mdp5_cfg->pipe_vig.base[1]);
+ case SSPP_VIG2: return (mdp5_cfg->pipe_vig.base[2]);
+ case SSPP_RGB0: return (mdp5_cfg->pipe_rgb.base[0]);
+ case SSPP_RGB1: return (mdp5_cfg->pipe_rgb.base[1]);
+ case SSPP_RGB2: return (mdp5_cfg->pipe_rgb.base[2]);
+ case SSPP_DMA0: return (mdp5_cfg->pipe_dma.base[0]);
+ case SSPP_DMA1: return (mdp5_cfg->pipe_dma.base[1]);
+ case SSPP_VIG3: return (mdp5_cfg->pipe_vig.base[3]);
+ case SSPP_RGB3: return (mdp5_cfg->pipe_rgb.base[3]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_PIPE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_HIST_CTL_BASE(enum mdp5_pipe i0) { return 0x000014c4 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_HIST_CTL_BASE(enum mdp5_pipe i0) { return 0x000002c4 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_HIST_LUT_BASE(enum mdp5_pipe i0) { return 0x000014f0 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_HIST_LUT_BASE(enum mdp5_pipe i0) { return 0x000002f0 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_HIST_LUT_SWAP(enum mdp5_pipe i0) { return 0x00001500 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_HIST_LUT_SWAP(enum mdp5_pipe i0) { return 0x00000300 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC_SIZE(enum mdp5_pipe i0) { return 0x00001200 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_SIZE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_SIZE_HEIGHT__MASK 0xffff0000
#define MDP5_PIPE_SRC_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP5_PIPE_SRC_SIZE_HEIGHT(uint32_t val)
@@ -420,7 +483,7 @@ static inline uint32_t MDP5_PIPE_SRC_SIZE_WIDTH(uint32_t val)
return ((val) << MDP5_PIPE_SRC_SIZE_WIDTH__SHIFT) & MDP5_PIPE_SRC_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC_IMG_SIZE(enum mdp5_pipe i0) { return 0x00001204 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_IMG_SIZE(enum mdp5_pipe i0) { return 0x00000004 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_IMG_SIZE_HEIGHT__MASK 0xffff0000
#define MDP5_PIPE_SRC_IMG_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP5_PIPE_SRC_IMG_SIZE_HEIGHT(uint32_t val)
@@ -434,7 +497,7 @@ static inline uint32_t MDP5_PIPE_SRC_IMG_SIZE_WIDTH(uint32_t val)
return ((val) << MDP5_PIPE_SRC_IMG_SIZE_WIDTH__SHIFT) & MDP5_PIPE_SRC_IMG_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC_XY(enum mdp5_pipe i0) { return 0x00001208 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_XY(enum mdp5_pipe i0) { return 0x00000008 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_XY_Y__MASK 0xffff0000
#define MDP5_PIPE_SRC_XY_Y__SHIFT 16
static inline uint32_t MDP5_PIPE_SRC_XY_Y(uint32_t val)
@@ -448,7 +511,7 @@ static inline uint32_t MDP5_PIPE_SRC_XY_X(uint32_t val)
return ((val) << MDP5_PIPE_SRC_XY_X__SHIFT) & MDP5_PIPE_SRC_XY_X__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_OUT_SIZE(enum mdp5_pipe i0) { return 0x0000120c + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_OUT_SIZE(enum mdp5_pipe i0) { return 0x0000000c + __offset_PIPE(i0); }
#define MDP5_PIPE_OUT_SIZE_HEIGHT__MASK 0xffff0000
#define MDP5_PIPE_OUT_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP5_PIPE_OUT_SIZE_HEIGHT(uint32_t val)
@@ -462,7 +525,7 @@ static inline uint32_t MDP5_PIPE_OUT_SIZE_WIDTH(uint32_t val)
return ((val) << MDP5_PIPE_OUT_SIZE_WIDTH__SHIFT) & MDP5_PIPE_OUT_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_OUT_XY(enum mdp5_pipe i0) { return 0x00001210 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_OUT_XY(enum mdp5_pipe i0) { return 0x00000010 + __offset_PIPE(i0); }
#define MDP5_PIPE_OUT_XY_Y__MASK 0xffff0000
#define MDP5_PIPE_OUT_XY_Y__SHIFT 16
static inline uint32_t MDP5_PIPE_OUT_XY_Y(uint32_t val)
@@ -476,15 +539,15 @@ static inline uint32_t MDP5_PIPE_OUT_XY_X(uint32_t val)
return ((val) << MDP5_PIPE_OUT_XY_X__SHIFT) & MDP5_PIPE_OUT_XY_X__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC0_ADDR(enum mdp5_pipe i0) { return 0x00001214 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC0_ADDR(enum mdp5_pipe i0) { return 0x00000014 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC1_ADDR(enum mdp5_pipe i0) { return 0x00001218 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC1_ADDR(enum mdp5_pipe i0) { return 0x00000018 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC2_ADDR(enum mdp5_pipe i0) { return 0x0000121c + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC2_ADDR(enum mdp5_pipe i0) { return 0x0000001c + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC3_ADDR(enum mdp5_pipe i0) { return 0x00001220 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC3_ADDR(enum mdp5_pipe i0) { return 0x00000020 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC_STRIDE_A(enum mdp5_pipe i0) { return 0x00001224 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_STRIDE_A(enum mdp5_pipe i0) { return 0x00000024 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff
#define MDP5_PIPE_SRC_STRIDE_A_P0__SHIFT 0
static inline uint32_t MDP5_PIPE_SRC_STRIDE_A_P0(uint32_t val)
@@ -498,7 +561,7 @@ static inline uint32_t MDP5_PIPE_SRC_STRIDE_A_P1(uint32_t val)
return ((val) << MDP5_PIPE_SRC_STRIDE_A_P1__SHIFT) & MDP5_PIPE_SRC_STRIDE_A_P1__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC_STRIDE_B(enum mdp5_pipe i0) { return 0x00001228 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_STRIDE_B(enum mdp5_pipe i0) { return 0x00000028 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_STRIDE_B_P2__MASK 0x0000ffff
#define MDP5_PIPE_SRC_STRIDE_B_P2__SHIFT 0
static inline uint32_t MDP5_PIPE_SRC_STRIDE_B_P2(uint32_t val)
@@ -512,9 +575,9 @@ static inline uint32_t MDP5_PIPE_SRC_STRIDE_B_P3(uint32_t val)
return ((val) << MDP5_PIPE_SRC_STRIDE_B_P3__SHIFT) & MDP5_PIPE_SRC_STRIDE_B_P3__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_STILE_FRAME_SIZE(enum mdp5_pipe i0) { return 0x0000122c + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_STILE_FRAME_SIZE(enum mdp5_pipe i0) { return 0x0000002c + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC_FORMAT(enum mdp5_pipe i0) { return 0x00001230 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_FORMAT(enum mdp5_pipe i0) { return 0x00000030 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_FORMAT_G_BPC__MASK 0x00000003
#define MDP5_PIPE_SRC_FORMAT_G_BPC__SHIFT 0
static inline uint32_t MDP5_PIPE_SRC_FORMAT_G_BPC(enum mdp_bpc val)
@@ -568,7 +631,7 @@ static inline uint32_t MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp5_chroma_samp_ty
return ((val) << MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC_UNPACK(enum mdp5_pipe i0) { return 0x00001234 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_UNPACK(enum mdp5_pipe i0) { return 0x00000034 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff
#define MDP5_PIPE_SRC_UNPACK_ELEM0__SHIFT 0
static inline uint32_t MDP5_PIPE_SRC_UNPACK_ELEM0(uint32_t val)
@@ -594,7 +657,7 @@ static inline uint32_t MDP5_PIPE_SRC_UNPACK_ELEM3(uint32_t val)
return ((val) << MDP5_PIPE_SRC_UNPACK_ELEM3__SHIFT) & MDP5_PIPE_SRC_UNPACK_ELEM3__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SRC_OP_MODE(enum mdp5_pipe i0) { return 0x00001238 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_OP_MODE(enum mdp5_pipe i0) { return 0x00000038 + __offset_PIPE(i0); }
#define MDP5_PIPE_SRC_OP_MODE_BWC_EN 0x00000001
#define MDP5_PIPE_SRC_OP_MODE_BWC__MASK 0x00000006
#define MDP5_PIPE_SRC_OP_MODE_BWC__SHIFT 1
@@ -610,29 +673,29 @@ static inline uint32_t MDP5_PIPE_SRC_OP_MODE_BWC(enum mdp5_pipe_bwc val)
#define MDP5_PIPE_SRC_OP_MODE_DEINTERLACE 0x00400000
#define MDP5_PIPE_SRC_OP_MODE_DEINTERLACE_ODD 0x00800000
-static inline uint32_t REG_MDP5_PIPE_SRC_CONSTANT_COLOR(enum mdp5_pipe i0) { return 0x0000123c + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_CONSTANT_COLOR(enum mdp5_pipe i0) { return 0x0000003c + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_FETCH_CONFIG(enum mdp5_pipe i0) { return 0x00001248 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_FETCH_CONFIG(enum mdp5_pipe i0) { return 0x00000048 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_VC1_RANGE(enum mdp5_pipe i0) { return 0x0000124c + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_VC1_RANGE(enum mdp5_pipe i0) { return 0x0000004c + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(enum mdp5_pipe i0) { return 0x00001250 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(enum mdp5_pipe i0) { return 0x00000050 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(enum mdp5_pipe i0) { return 0x00001254 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(enum mdp5_pipe i0) { return 0x00000054 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(enum mdp5_pipe i0) { return 0x00001258 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(enum mdp5_pipe i0) { return 0x00000058 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(enum mdp5_pipe i0) { return 0x00001270 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(enum mdp5_pipe i0) { return 0x00000070 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC0_ADDR(enum mdp5_pipe i0) { return 0x000012a4 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC0_ADDR(enum mdp5_pipe i0) { return 0x000000a4 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC1_ADDR(enum mdp5_pipe i0) { return 0x000012a8 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC1_ADDR(enum mdp5_pipe i0) { return 0x000000a8 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC2_ADDR(enum mdp5_pipe i0) { return 0x000012ac + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC2_ADDR(enum mdp5_pipe i0) { return 0x000000ac + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC3_ADDR(enum mdp5_pipe i0) { return 0x000012b0 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_CURRENT_SRC3_ADDR(enum mdp5_pipe i0) { return 0x000000b0 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_DECIMATION(enum mdp5_pipe i0) { return 0x000012b4 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_DECIMATION(enum mdp5_pipe i0) { return 0x000000b4 + __offset_PIPE(i0); }
#define MDP5_PIPE_DECIMATION_VERT__MASK 0x000000ff
#define MDP5_PIPE_DECIMATION_VERT__SHIFT 0
static inline uint32_t MDP5_PIPE_DECIMATION_VERT(uint32_t val)
@@ -646,7 +709,7 @@ static inline uint32_t MDP5_PIPE_DECIMATION_HORZ(uint32_t val)
return ((val) << MDP5_PIPE_DECIMATION_HORZ__SHIFT) & MDP5_PIPE_DECIMATION_HORZ__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SCALE_CONFIG(enum mdp5_pipe i0) { return 0x00001404 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SCALE_CONFIG(enum mdp5_pipe i0) { return 0x00000204 + __offset_PIPE(i0); }
#define MDP5_PIPE_SCALE_CONFIG_SCALEX_EN 0x00000001
#define MDP5_PIPE_SCALE_CONFIG_SCALEY_EN 0x00000002
#define MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER__MASK 0x00000300
@@ -686,23 +749,34 @@ static inline uint32_t MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(enum mdp5_scale_
return ((val) << MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER__SHIFT) & MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER__MASK;
}
-static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_X(enum mdp5_pipe i0) { return 0x00001410 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_X(enum mdp5_pipe i0) { return 0x00000210 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x00001414 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x00000214 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_X(enum mdp5_pipe i0) { return 0x00001420 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_X(enum mdp5_pipe i0) { return 0x00000220 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_Y(enum mdp5_pipe i0) { return 0x00001424 + 0x400*i0; }
+static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_Y(enum mdp5_pipe i0) { return 0x00000224 + __offset_PIPE(i0); }
-static inline uint32_t REG_MDP5_LM(uint32_t i0) { return 0x00003200 + 0x400*i0; }
+static inline uint32_t __offset_LM(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return (mdp5_cfg->lm.base[0]);
+ case 1: return (mdp5_cfg->lm.base[1]);
+ case 2: return (mdp5_cfg->lm.base[2]);
+ case 3: return (mdp5_cfg->lm.base[3]);
+ case 4: return (mdp5_cfg->lm.base[4]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_LM(uint32_t i0) { return 0x00000000 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_BLEND_COLOR_OUT(uint32_t i0) { return 0x00003200 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_BLEND_COLOR_OUT(uint32_t i0) { return 0x00000000 + __offset_LM(i0); }
#define MDP5_LM_BLEND_COLOR_OUT_STAGE0_FG_ALPHA 0x00000002
#define MDP5_LM_BLEND_COLOR_OUT_STAGE1_FG_ALPHA 0x00000004
#define MDP5_LM_BLEND_COLOR_OUT_STAGE2_FG_ALPHA 0x00000008
#define MDP5_LM_BLEND_COLOR_OUT_STAGE3_FG_ALPHA 0x00000010
-static inline uint32_t REG_MDP5_LM_OUT_SIZE(uint32_t i0) { return 0x00003204 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_OUT_SIZE(uint32_t i0) { return 0x00000004 + __offset_LM(i0); }
#define MDP5_LM_OUT_SIZE_HEIGHT__MASK 0xffff0000
#define MDP5_LM_OUT_SIZE_HEIGHT__SHIFT 16
static inline uint32_t MDP5_LM_OUT_SIZE_HEIGHT(uint32_t val)
@@ -716,13 +790,13 @@ static inline uint32_t MDP5_LM_OUT_SIZE_WIDTH(uint32_t val)
return ((val) << MDP5_LM_OUT_SIZE_WIDTH__SHIFT) & MDP5_LM_OUT_SIZE_WIDTH__MASK;
}
-static inline uint32_t REG_MDP5_LM_BORDER_COLOR_0(uint32_t i0) { return 0x00003208 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_BORDER_COLOR_0(uint32_t i0) { return 0x00000008 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_BORDER_COLOR_1(uint32_t i0) { return 0x00003210 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_BORDER_COLOR_1(uint32_t i0) { return 0x00000010 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_BLEND(uint32_t i0, uint32_t i1) { return 0x00003220 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND(uint32_t i0, uint32_t i1) { return 0x00000020 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_OP_MODE(uint32_t i0, uint32_t i1) { return 0x00003220 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_OP_MODE(uint32_t i0, uint32_t i1) { return 0x00000020 + __offset_LM(i0) + 0x30*i1; }
#define MDP5_LM_BLEND_OP_MODE_FG_ALPHA__MASK 0x00000003
#define MDP5_LM_BLEND_OP_MODE_FG_ALPHA__SHIFT 0
static inline uint32_t MDP5_LM_BLEND_OP_MODE_FG_ALPHA(enum mdp_alpha_type val)
@@ -744,57 +818,67 @@ static inline uint32_t MDP5_LM_BLEND_OP_MODE_BG_ALPHA(enum mdp_alpha_type val)
#define MDP5_LM_BLEND_OP_MODE_BG_INV_MOD_ALPHA 0x00001000
#define MDP5_LM_BLEND_OP_MODE_BG_TRANSP_EN 0x00002000
-static inline uint32_t REG_MDP5_LM_BLEND_FG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00003224 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_FG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00000024 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_BG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00003228 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_BG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00000028 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_LOW0(uint32_t i0, uint32_t i1) { return 0x0000322c + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_LOW0(uint32_t i0, uint32_t i1) { return 0x0000002c + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_LOW1(uint32_t i0, uint32_t i1) { return 0x00003230 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_LOW1(uint32_t i0, uint32_t i1) { return 0x00000030 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_HIGH0(uint32_t i0, uint32_t i1) { return 0x00003234 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_HIGH0(uint32_t i0, uint32_t i1) { return 0x00000034 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00003238 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_FG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000038 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_LOW0(uint32_t i0, uint32_t i1) { return 0x0000323c + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_LOW0(uint32_t i0, uint32_t i1) { return 0x0000003c + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_LOW1(uint32_t i0, uint32_t i1) { return 0x00003240 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_LOW1(uint32_t i0, uint32_t i1) { return 0x00000040 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH0(uint32_t i0, uint32_t i1) { return 0x00003244 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH0(uint32_t i0, uint32_t i1) { return 0x00000044 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00003248 + 0x400*i0 + 0x30*i1; }
+static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000048 + __offset_LM(i0) + 0x30*i1; }
-static inline uint32_t REG_MDP5_LM_CURSOR_IMG_SIZE(uint32_t i0) { return 0x000032e0 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_IMG_SIZE(uint32_t i0) { return 0x000000e0 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_SIZE(uint32_t i0) { return 0x000032e4 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_SIZE(uint32_t i0) { return 0x000000e4 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_XY(uint32_t i0) { return 0x000032e8 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_XY(uint32_t i0) { return 0x000000e8 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_STRIDE(uint32_t i0) { return 0x000032dc + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_STRIDE(uint32_t i0) { return 0x000000dc + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_FORMAT(uint32_t i0) { return 0x000032ec + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_FORMAT(uint32_t i0) { return 0x000000ec + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BASE_ADDR(uint32_t i0) { return 0x000032f0 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BASE_ADDR(uint32_t i0) { return 0x000000f0 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_START_XY(uint32_t i0) { return 0x000032f4 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_START_XY(uint32_t i0) { return 0x000000f4 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_CONFIG(uint32_t i0) { return 0x000032f8 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_CONFIG(uint32_t i0) { return 0x000000f8 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_PARAM(uint32_t i0) { return 0x000032fc + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_PARAM(uint32_t i0) { return 0x000000fc + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_LOW0(uint32_t i0) { return 0x00003300 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_LOW0(uint32_t i0) { return 0x00000100 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_LOW1(uint32_t i0) { return 0x00003304 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_LOW1(uint32_t i0) { return 0x00000104 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_HIGH0(uint32_t i0) { return 0x00003308 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_HIGH0(uint32_t i0) { return 0x00000108 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_HIGH1(uint32_t i0) { return 0x0000330c + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_TRANSP_HIGH1(uint32_t i0) { return 0x0000010c + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_LM_GC_LUT_BASE(uint32_t i0) { return 0x00003310 + 0x400*i0; }
+static inline uint32_t REG_MDP5_LM_GC_LUT_BASE(uint32_t i0) { return 0x00000110 + __offset_LM(i0); }
-static inline uint32_t REG_MDP5_DSPP(uint32_t i0) { return 0x00004600 + 0x400*i0; }
+static inline uint32_t __offset_DSPP(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return (mdp5_cfg->dspp.base[0]);
+ case 1: return (mdp5_cfg->dspp.base[1]);
+ case 2: return (mdp5_cfg->dspp.base[2]);
+ case 3: return (mdp5_cfg->dspp.base[3]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_DSPP(uint32_t i0) { return 0x00000000 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_OP_MODE(uint32_t i0) { return 0x00004600 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_OP_MODE(uint32_t i0) { return 0x00000000 + __offset_DSPP(i0); }
#define MDP5_DSPP_OP_MODE_IGC_LUT_EN 0x00000001
#define MDP5_DSPP_OP_MODE_IGC_TBL_IDX__MASK 0x0000000e
#define MDP5_DSPP_OP_MODE_IGC_TBL_IDX__SHIFT 1
@@ -811,29 +895,40 @@ static inline uint32_t MDP5_DSPP_OP_MODE_IGC_TBL_IDX(uint32_t val)
#define MDP5_DSPP_OP_MODE_GAMUT_EN 0x00800000
#define MDP5_DSPP_OP_MODE_GAMUT_ORDER 0x01000000
-static inline uint32_t REG_MDP5_DSPP_PCC_BASE(uint32_t i0) { return 0x00004630 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_PCC_BASE(uint32_t i0) { return 0x00000030 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_DITHER_DEPTH(uint32_t i0) { return 0x00004750 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_DITHER_DEPTH(uint32_t i0) { return 0x00000150 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_HIST_CTL_BASE(uint32_t i0) { return 0x00004810 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_HIST_CTL_BASE(uint32_t i0) { return 0x00000210 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_HIST_LUT_BASE(uint32_t i0) { return 0x00004830 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_HIST_LUT_BASE(uint32_t i0) { return 0x00000230 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_HIST_LUT_SWAP(uint32_t i0) { return 0x00004834 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_HIST_LUT_SWAP(uint32_t i0) { return 0x00000234 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_PA_BASE(uint32_t i0) { return 0x00004838 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_PA_BASE(uint32_t i0) { return 0x00000238 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_GAMUT_BASE(uint32_t i0) { return 0x000048dc + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_GAMUT_BASE(uint32_t i0) { return 0x000002dc + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_DSPP_GC_BASE(uint32_t i0) { return 0x000048b0 + 0x400*i0; }
+static inline uint32_t REG_MDP5_DSPP_GC_BASE(uint32_t i0) { return 0x000002b0 + __offset_DSPP(i0); }
-static inline uint32_t REG_MDP5_INTF(uint32_t i0) { return 0x00012500 + 0x200*i0; }
+static inline uint32_t __offset_INTF(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return (mdp5_cfg->intf.base[0]);
+ case 1: return (mdp5_cfg->intf.base[1]);
+ case 2: return (mdp5_cfg->intf.base[2]);
+ case 3: return (mdp5_cfg->intf.base[3]);
+ case 4: return (mdp5_cfg->intf.base[4]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_INTF(uint32_t i0) { return 0x00000000 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TIMING_ENGINE_EN(uint32_t i0) { return 0x00012500 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TIMING_ENGINE_EN(uint32_t i0) { return 0x00000000 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_CONFIG(uint32_t i0) { return 0x00012504 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_CONFIG(uint32_t i0) { return 0x00000004 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_HSYNC_CTL(uint32_t i0) { return 0x00012508 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_HSYNC_CTL(uint32_t i0) { return 0x00000008 + __offset_INTF(i0); }
#define MDP5_INTF_HSYNC_CTL_PULSEW__MASK 0x0000ffff
#define MDP5_INTF_HSYNC_CTL_PULSEW__SHIFT 0
static inline uint32_t MDP5_INTF_HSYNC_CTL_PULSEW(uint32_t val)
@@ -847,23 +942,23 @@ static inline uint32_t MDP5_INTF_HSYNC_CTL_PERIOD(uint32_t val)
return ((val) << MDP5_INTF_HSYNC_CTL_PERIOD__SHIFT) & MDP5_INTF_HSYNC_CTL_PERIOD__MASK;
}
-static inline uint32_t REG_MDP5_INTF_VSYNC_PERIOD_F0(uint32_t i0) { return 0x0001250c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_VSYNC_PERIOD_F0(uint32_t i0) { return 0x0000000c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_VSYNC_PERIOD_F1(uint32_t i0) { return 0x00012510 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_VSYNC_PERIOD_F1(uint32_t i0) { return 0x00000010 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_VSYNC_LEN_F0(uint32_t i0) { return 0x00012514 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_VSYNC_LEN_F0(uint32_t i0) { return 0x00000014 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_VSYNC_LEN_F1(uint32_t i0) { return 0x00012518 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_VSYNC_LEN_F1(uint32_t i0) { return 0x00000018 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DISPLAY_VSTART_F0(uint32_t i0) { return 0x0001251c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DISPLAY_VSTART_F0(uint32_t i0) { return 0x0000001c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DISPLAY_VSTART_F1(uint32_t i0) { return 0x00012520 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DISPLAY_VSTART_F1(uint32_t i0) { return 0x00000020 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DISPLAY_VEND_F0(uint32_t i0) { return 0x00012524 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DISPLAY_VEND_F0(uint32_t i0) { return 0x00000024 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DISPLAY_VEND_F1(uint32_t i0) { return 0x00012528 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DISPLAY_VEND_F1(uint32_t i0) { return 0x00000028 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_ACTIVE_VSTART_F0(uint32_t i0) { return 0x0001252c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_ACTIVE_VSTART_F0(uint32_t i0) { return 0x0000002c + __offset_INTF(i0); }
#define MDP5_INTF_ACTIVE_VSTART_F0_VAL__MASK 0x7fffffff
#define MDP5_INTF_ACTIVE_VSTART_F0_VAL__SHIFT 0
static inline uint32_t MDP5_INTF_ACTIVE_VSTART_F0_VAL(uint32_t val)
@@ -872,7 +967,7 @@ static inline uint32_t MDP5_INTF_ACTIVE_VSTART_F0_VAL(uint32_t val)
}
#define MDP5_INTF_ACTIVE_VSTART_F0_ACTIVE_V_ENABLE 0x80000000
-static inline uint32_t REG_MDP5_INTF_ACTIVE_VSTART_F1(uint32_t i0) { return 0x00012530 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_ACTIVE_VSTART_F1(uint32_t i0) { return 0x00000030 + __offset_INTF(i0); }
#define MDP5_INTF_ACTIVE_VSTART_F1_VAL__MASK 0x7fffffff
#define MDP5_INTF_ACTIVE_VSTART_F1_VAL__SHIFT 0
static inline uint32_t MDP5_INTF_ACTIVE_VSTART_F1_VAL(uint32_t val)
@@ -880,11 +975,11 @@ static inline uint32_t MDP5_INTF_ACTIVE_VSTART_F1_VAL(uint32_t val)
return ((val) << MDP5_INTF_ACTIVE_VSTART_F1_VAL__SHIFT) & MDP5_INTF_ACTIVE_VSTART_F1_VAL__MASK;
}
-static inline uint32_t REG_MDP5_INTF_ACTIVE_VEND_F0(uint32_t i0) { return 0x00012534 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_ACTIVE_VEND_F0(uint32_t i0) { return 0x00000034 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_ACTIVE_VEND_F1(uint32_t i0) { return 0x00012538 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_ACTIVE_VEND_F1(uint32_t i0) { return 0x00000038 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DISPLAY_HCTL(uint32_t i0) { return 0x0001253c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DISPLAY_HCTL(uint32_t i0) { return 0x0000003c + __offset_INTF(i0); }
#define MDP5_INTF_DISPLAY_HCTL_START__MASK 0x0000ffff
#define MDP5_INTF_DISPLAY_HCTL_START__SHIFT 0
static inline uint32_t MDP5_INTF_DISPLAY_HCTL_START(uint32_t val)
@@ -898,7 +993,7 @@ static inline uint32_t MDP5_INTF_DISPLAY_HCTL_END(uint32_t val)
return ((val) << MDP5_INTF_DISPLAY_HCTL_END__SHIFT) & MDP5_INTF_DISPLAY_HCTL_END__MASK;
}
-static inline uint32_t REG_MDP5_INTF_ACTIVE_HCTL(uint32_t i0) { return 0x00012540 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_ACTIVE_HCTL(uint32_t i0) { return 0x00000040 + __offset_INTF(i0); }
#define MDP5_INTF_ACTIVE_HCTL_START__MASK 0x00007fff
#define MDP5_INTF_ACTIVE_HCTL_START__SHIFT 0
static inline uint32_t MDP5_INTF_ACTIVE_HCTL_START(uint32_t val)
@@ -913,124 +1008,132 @@ static inline uint32_t MDP5_INTF_ACTIVE_HCTL_END(uint32_t val)
}
#define MDP5_INTF_ACTIVE_HCTL_ACTIVE_H_ENABLE 0x80000000
-static inline uint32_t REG_MDP5_INTF_BORDER_COLOR(uint32_t i0) { return 0x00012544 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_BORDER_COLOR(uint32_t i0) { return 0x00000044 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_UNDERFLOW_COLOR(uint32_t i0) { return 0x00012548 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_UNDERFLOW_COLOR(uint32_t i0) { return 0x00000048 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_HSYNC_SKEW(uint32_t i0) { return 0x0001254c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_HSYNC_SKEW(uint32_t i0) { return 0x0000004c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_POLARITY_CTL(uint32_t i0) { return 0x00012550 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_POLARITY_CTL(uint32_t i0) { return 0x00000050 + __offset_INTF(i0); }
#define MDP5_INTF_POLARITY_CTL_HSYNC_LOW 0x00000001
#define MDP5_INTF_POLARITY_CTL_VSYNC_LOW 0x00000002
#define MDP5_INTF_POLARITY_CTL_DATA_EN_LOW 0x00000004
-static inline uint32_t REG_MDP5_INTF_TEST_CTL(uint32_t i0) { return 0x00012554 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TEST_CTL(uint32_t i0) { return 0x00000054 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TP_COLOR0(uint32_t i0) { return 0x00012558 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TP_COLOR0(uint32_t i0) { return 0x00000058 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TP_COLOR1(uint32_t i0) { return 0x0001255c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TP_COLOR1(uint32_t i0) { return 0x0000005c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DSI_CMD_MODE_TRIGGER_EN(uint32_t i0) { return 0x00012584 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DSI_CMD_MODE_TRIGGER_EN(uint32_t i0) { return 0x00000084 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_PANEL_FORMAT(uint32_t i0) { return 0x00012590 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_PANEL_FORMAT(uint32_t i0) { return 0x00000090 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_FRAME_LINE_COUNT_EN(uint32_t i0) { return 0x000125a8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_FRAME_LINE_COUNT_EN(uint32_t i0) { return 0x000000a8 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_FRAME_COUNT(uint32_t i0) { return 0x000125ac + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_FRAME_COUNT(uint32_t i0) { return 0x000000ac + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_LINE_COUNT(uint32_t i0) { return 0x000125b0 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_LINE_COUNT(uint32_t i0) { return 0x000000b0 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DEFLICKER_CONFIG(uint32_t i0) { return 0x000125f0 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DEFLICKER_CONFIG(uint32_t i0) { return 0x000000f0 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DEFLICKER_STRNG_COEFF(uint32_t i0) { return 0x000125f4 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DEFLICKER_STRNG_COEFF(uint32_t i0) { return 0x000000f4 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_DEFLICKER_WEAK_COEFF(uint32_t i0) { return 0x000125f8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_DEFLICKER_WEAK_COEFF(uint32_t i0) { return 0x000000f8 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_ENABLE(uint32_t i0) { return 0x00012600 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_ENABLE(uint32_t i0) { return 0x00000100 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_MAIN_CONTROL(uint32_t i0) { return 0x00012604 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_MAIN_CONTROL(uint32_t i0) { return 0x00000104 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_VIDEO_CONFIG(uint32_t i0) { return 0x00012608 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_VIDEO_CONFIG(uint32_t i0) { return 0x00000108 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_COMPONENT_LIMITS(uint32_t i0) { return 0x0001260c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_COMPONENT_LIMITS(uint32_t i0) { return 0x0000010c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_RECTANGLE(uint32_t i0) { return 0x00012610 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_RECTANGLE(uint32_t i0) { return 0x00000110 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_INITIAL_VALUE(uint32_t i0) { return 0x00012614 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_INITIAL_VALUE(uint32_t i0) { return 0x00000114 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_BLK_WHITE_PATTERN_FRAME(uint32_t i0) { return 0x00012618 + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_BLK_WHITE_PATTERN_FRAME(uint32_t i0) { return 0x00000118 + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_INTF_TPG_RGB_MAPPING(uint32_t i0) { return 0x0001261c + 0x200*i0; }
+static inline uint32_t REG_MDP5_INTF_TPG_RGB_MAPPING(uint32_t i0) { return 0x0000011c + __offset_INTF(i0); }
-static inline uint32_t REG_MDP5_AD(uint32_t i0) { return 0x00013100 + 0x200*i0; }
+static inline uint32_t __offset_AD(uint32_t idx)
+{
+ switch (idx) {
+ case 0: return (mdp5_cfg->ad.base[0]);
+ case 1: return (mdp5_cfg->ad.base[1]);
+ default: return INVALID_IDX(idx);
+ }
+}
+static inline uint32_t REG_MDP5_AD(uint32_t i0) { return 0x00000000 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BYPASS(uint32_t i0) { return 0x00013100 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BYPASS(uint32_t i0) { return 0x00000000 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CTRL_0(uint32_t i0) { return 0x00013104 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CTRL_0(uint32_t i0) { return 0x00000004 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CTRL_1(uint32_t i0) { return 0x00013108 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CTRL_1(uint32_t i0) { return 0x00000008 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_FRAME_SIZE(uint32_t i0) { return 0x0001310c + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_FRAME_SIZE(uint32_t i0) { return 0x0000000c + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CON_CTRL_0(uint32_t i0) { return 0x00013110 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CON_CTRL_0(uint32_t i0) { return 0x00000010 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CON_CTRL_1(uint32_t i0) { return 0x00013114 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CON_CTRL_1(uint32_t i0) { return 0x00000014 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_STR_MAN(uint32_t i0) { return 0x00013118 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_STR_MAN(uint32_t i0) { return 0x00000018 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_VAR(uint32_t i0) { return 0x0001311c + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_VAR(uint32_t i0) { return 0x0000001c + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_DITH(uint32_t i0) { return 0x00013120 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_DITH(uint32_t i0) { return 0x00000020 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_DITH_CTRL(uint32_t i0) { return 0x00013124 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_DITH_CTRL(uint32_t i0) { return 0x00000024 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_AMP_LIM(uint32_t i0) { return 0x00013128 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_AMP_LIM(uint32_t i0) { return 0x00000028 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_SLOPE(uint32_t i0) { return 0x0001312c + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_SLOPE(uint32_t i0) { return 0x0000002c + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BW_LVL(uint32_t i0) { return 0x00013130 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BW_LVL(uint32_t i0) { return 0x00000030 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_LOGO_POS(uint32_t i0) { return 0x00013134 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_LOGO_POS(uint32_t i0) { return 0x00000034 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_LUT_FI(uint32_t i0) { return 0x00013138 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_LUT_FI(uint32_t i0) { return 0x00000038 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_LUT_CC(uint32_t i0) { return 0x0001317c + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_LUT_CC(uint32_t i0) { return 0x0000007c + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_STR_LIM(uint32_t i0) { return 0x000131c8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_STR_LIM(uint32_t i0) { return 0x000000c8 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CALIB_AB(uint32_t i0) { return 0x000131cc + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CALIB_AB(uint32_t i0) { return 0x000000cc + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CALIB_CD(uint32_t i0) { return 0x000131d0 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CALIB_CD(uint32_t i0) { return 0x000000d0 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_MODE_SEL(uint32_t i0) { return 0x000131d4 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_MODE_SEL(uint32_t i0) { return 0x000000d4 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_TFILT_CTRL(uint32_t i0) { return 0x000131d8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_TFILT_CTRL(uint32_t i0) { return 0x000000d8 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BL_MINMAX(uint32_t i0) { return 0x000131dc + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BL_MINMAX(uint32_t i0) { return 0x000000dc + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BL(uint32_t i0) { return 0x000131e0 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BL(uint32_t i0) { return 0x000000e0 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BL_MAX(uint32_t i0) { return 0x000131e8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BL_MAX(uint32_t i0) { return 0x000000e8 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_AL(uint32_t i0) { return 0x000131ec + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_AL(uint32_t i0) { return 0x000000ec + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_AL_MIN(uint32_t i0) { return 0x000131f0 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_AL_MIN(uint32_t i0) { return 0x000000f0 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_AL_FILT(uint32_t i0) { return 0x000131f4 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_AL_FILT(uint32_t i0) { return 0x000000f4 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CFG_BUF(uint32_t i0) { return 0x000131f8 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CFG_BUF(uint32_t i0) { return 0x000000f8 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_LUT_AL(uint32_t i0) { return 0x00013200 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_LUT_AL(uint32_t i0) { return 0x00000100 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_TARG_STR(uint32_t i0) { return 0x00013244 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_TARG_STR(uint32_t i0) { return 0x00000144 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_START_CALC(uint32_t i0) { return 0x00013248 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_START_CALC(uint32_t i0) { return 0x00000148 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_STR_OUT(uint32_t i0) { return 0x0001324c + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_STR_OUT(uint32_t i0) { return 0x0000014c + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_BL_OUT(uint32_t i0) { return 0x00013254 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_BL_OUT(uint32_t i0) { return 0x00000154 + __offset_AD(i0); }
-static inline uint32_t REG_MDP5_AD_CALC_DONE(uint32_t i0) { return 0x00013258 + 0x200*i0; }
+static inline uint32_t REG_MDP5_AD_CALC_DONE(uint32_t i0) { return 0x00000158 + __offset_AD(i0); }
#endif /* MDP5_XML */
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 71510ee26e96..31a2c6331a1d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -26,14 +26,98 @@ static const char *iommu_ports[] = {
static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev);
-static int mdp5_hw_init(struct msm_kms *kms)
+const struct mdp5_config *mdp5_cfg;
+
+static const struct mdp5_config msm8x74_config = {
+ .name = "msm8x74",
+ .ctl = {
+ .count = 5,
+ .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+ },
+ .pipe_vig = {
+ .count = 3,
+ .base = { 0x01200, 0x01600, 0x01a00 },
+ },
+ .pipe_rgb = {
+ .count = 3,
+ .base = { 0x01e00, 0x02200, 0x02600 },
+ },
+ .pipe_dma = {
+ .count = 2,
+ .base = { 0x02a00, 0x02e00 },
+ },
+ .lm = {
+ .count = 5,
+ .base = { 0x03200, 0x03600, 0x03a00, 0x03e00, 0x04200 },
+ },
+ .dspp = {
+ .count = 3,
+ .base = { 0x04600, 0x04a00, 0x04e00 },
+ },
+ .ad = {
+ .count = 2,
+ .base = { 0x13100, 0x13300 }, /* NOTE: no ad in v1.0 */
+ },
+ .intf = {
+ .count = 4,
+ .base = { 0x12500, 0x12700, 0x12900, 0x12b00 },
+ },
+};
+
+static const struct mdp5_config apq8084_config = {
+ .name = "apq8084",
+ .ctl = {
+ .count = 5,
+ .base = { 0x00600, 0x00700, 0x00800, 0x00900, 0x00a00 },
+ },
+ .pipe_vig = {
+ .count = 4,
+ .base = { 0x01200, 0x01600, 0x01a00, 0x01e00 },
+ },
+ .pipe_rgb = {
+ .count = 4,
+ .base = { 0x02200, 0x02600, 0x02a00, 0x02e00 },
+ },
+ .pipe_dma = {
+ .count = 2,
+ .base = { 0x03200, 0x03600 },
+ },
+ .lm = {
+ .count = 6,
+ .base = { 0x03a00, 0x03e00, 0x04200, 0x04600, 0x04a00, 0x04e00 },
+ },
+ .dspp = {
+ .count = 4,
+ .base = { 0x05200, 0x05600, 0x05a00, 0x05e00 },
+
+ },
+ .ad = {
+ .count = 3,
+ .base = { 0x13500, 0x13700, 0x13900 },
+ },
+ .intf = {
+ .count = 5,
+ .base = { 0x12500, 0x12700, 0x12900, 0x12b00, 0x12d00 },
+ },
+};
+
+struct mdp5_config_entry {
+ int revision;
+ const struct mdp5_config *config;
+};
+
+static const struct mdp5_config_entry mdp5_configs[] = {
+ { .revision = 0, .config = &msm8x74_config },
+ { .revision = 2, .config = &msm8x74_config },
+ { .revision = 3, .config = &apq8084_config },
+};
+
+static int mdp5_select_hw_cfg(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
struct drm_device *dev = mdp5_kms->dev;
uint32_t version, major, minor;
- int ret = 0;
-
- pm_runtime_get_sync(dev->dev);
+ int i, ret = 0;
mdp5_enable(mdp5_kms);
version = mdp5_read(mdp5_kms, REG_MDP5_MDP_VERSION);
@@ -44,8 +128,8 @@ static int mdp5_hw_init(struct msm_kms *kms)
DBG("found MDP5 version v%d.%d", major, minor);
- if ((major != 1) || ((minor != 0) && (minor != 2))) {
- dev_err(dev->dev, "unexpected MDP version: v%d.%d\n",
+ if (major != 1) {
+ dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n",
major, minor);
ret = -ENXIO;
goto out;
@@ -53,6 +137,35 @@ static int mdp5_hw_init(struct msm_kms *kms)
mdp5_kms->rev = minor;
+ /* only after mdp5_cfg global pointer's init can we access the hw */
+ for (i = 0; i < ARRAY_SIZE(mdp5_configs); i++) {
+ if (mdp5_configs[i].revision != minor)
+ continue;
+ mdp5_kms->hw_cfg = mdp5_cfg = mdp5_configs[i].config;
+ break;
+ }
+ if (unlikely(!mdp5_kms->hw_cfg)) {
+ dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
+ major, minor);
+ ret = -ENXIO;
+ goto out;
+ }
+
+ DBG("MDP5: %s config selected", mdp5_kms->hw_cfg->name);
+
+ return 0;
+out:
+ return ret;
+}
+
+static int mdp5_hw_init(struct msm_kms *kms)
+{
+ struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct drm_device *dev = mdp5_kms->dev;
+ int i;
+
+ pm_runtime_get_sync(dev->dev);
+
/* Magic unknown register writes:
*
* W VBIF:0x004 00000001 (mdss_mdp.c:839)
@@ -78,15 +191,13 @@ static int mdp5_hw_init(struct msm_kms *kms)
*/
mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0);
- mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(0), 0);
- mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(1), 0);
- mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(2), 0);
- mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(3), 0);
-out:
+ for (i = 0; i < mdp5_kms->hw_cfg->ctl.count; i++)
+ mdp5_write(mdp5_kms, REG_MDP5_CTL_OP(i), 0);
+
pm_runtime_put_sync(dev->dev);
- return ret;
+ return 0;
}
static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
@@ -161,7 +272,7 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
static int modeset_init(struct mdp5_kms *mdp5_kms)
{
static const enum mdp5_pipe crtcs[] = {
- SSPP_RGB0, SSPP_RGB1, SSPP_RGB2,
+ SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
};
struct drm_device *dev = mdp5_kms->dev;
struct msm_drm_private *priv = dev->dev_private;
@@ -169,7 +280,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms)
int i, ret;
/* construct CRTCs: */
- for (i = 0; i < ARRAY_SIZE(crtcs); i++) {
+ for (i = 0; i < mdp5_kms->hw_cfg->pipe_rgb.count; i++) {
struct drm_plane *plane;
struct drm_crtc *crtc;
@@ -246,7 +357,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
struct mdp5_kms *mdp5_kms;
struct msm_kms *kms = NULL;
struct msm_mmu *mmu;
- int ret;
+ int i, ret;
mdp5_kms = kzalloc(sizeof(*mdp5_kms), GFP_KERNEL);
if (!mdp5_kms) {
@@ -307,20 +418,22 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
ret = clk_set_rate(mdp5_kms->src_clk, config->max_clk);
+ ret = mdp5_select_hw_cfg(kms);
+ if (ret)
+ goto fail;
+
/* make sure things are off before attaching iommu (bootloader could
* have left things on, in which case we'll start getting faults if
* we don't disable):
*/
mdp5_enable(mdp5_kms);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(0), 0);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(1), 0);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(2), 0);
- mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(3), 0);
+ for (i = 0; i < mdp5_kms->hw_cfg->intf.count; i++)
+ mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
mdp5_disable(mdp5_kms);
mdelay(16);
if (config->iommu) {
- mmu = msm_iommu_new(dev, config->iommu);
+ mmu = msm_iommu_new(&pdev->dev, config->iommu);
if (IS_ERR(mmu)) {
ret = PTR_ERR(mmu);
dev_err(dev->dev, "failed to init iommu: %d\n", ret);
@@ -368,5 +481,11 @@ static struct mdp5_platform_config *mdp5_get_config(struct platform_device *dev)
#ifdef CONFIG_OF
/* TODO */
#endif
+ config.iommu = iommu_domain_alloc(&platform_bus_type);
+ /* TODO hard-coded in downstream mdss, but should it be? */
+ config.max_clk = 200000000;
+ /* TODO get from DT: */
+ config.smp_blk_cnt = 22;
+
return &config;
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 6e981b692d1d..5bf340dd0f00 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -21,6 +21,24 @@
#include "msm_drv.h"
#include "msm_kms.h"
#include "mdp/mdp_kms.h"
+/* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */
+#define MDP5_MAX_BASES 8
+struct mdp5_sub_block {
+ int count;
+ uint32_t base[MDP5_MAX_BASES];
+};
+struct mdp5_config {
+ char *name;
+ struct mdp5_sub_block ctl;
+ struct mdp5_sub_block pipe_vig;
+ struct mdp5_sub_block pipe_rgb;
+ struct mdp5_sub_block pipe_dma;
+ struct mdp5_sub_block lm;
+ struct mdp5_sub_block dspp;
+ struct mdp5_sub_block ad;
+ struct mdp5_sub_block intf;
+};
+extern const struct mdp5_config *mdp5_cfg;
#include "mdp5.xml.h"
#include "mdp5_smp.h"
@@ -30,6 +48,7 @@ struct mdp5_kms {
struct drm_device *dev;
int rev;
+ const struct mdp5_config *hw_cfg;
/* mapper-id used to request GEM buffer mapped for scanout: */
int id;
@@ -82,6 +101,7 @@ static inline const char *pipe2name(enum mdp5_pipe pipe)
NAME(VIG0), NAME(VIG1), NAME(VIG2),
NAME(RGB0), NAME(RGB1), NAME(RGB2),
NAME(DMA0), NAME(DMA1),
+ NAME(VIG3), NAME(RGB3),
#undef NAME
};
return names[pipe];
@@ -98,6 +118,8 @@ static inline uint32_t pipe2flush(enum mdp5_pipe pipe)
case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2;
case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0;
case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
+ case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
+ case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
default: return 0;
}
}
@@ -108,6 +130,7 @@ static inline int pipe2nclients(enum mdp5_pipe pipe)
case SSPP_RGB0:
case SSPP_RGB1:
case SSPP_RGB2:
+ case SSPP_RGB3:
return 1;
default:
return 3;
@@ -126,6 +149,8 @@ static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane)
case SSPP_RGB2: return CID_RGB2;
case SSPP_DMA0: return CID_DMA0_Y + plane;
case SSPP_DMA1: return CID_DMA1_Y + plane;
+ case SSPP_VIG3: return CID_VIG3_Y + plane;
+ case SSPP_RGB3: return CID_RGB3;
default: return CID_UNUSED;
}
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
index a9629b85b983..64c1afd6030a 100644
--- a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
+++ b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h
@@ -12,12 +12,12 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31)
- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52)
-- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2013-12-03 20:59:13)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32)
- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05)
- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12)
-- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 20932 bytes, from 2013-12-01 15:13:04)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44)
Copyright (C) 2013 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9a5d87db5c23..b447c01ad89c 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -181,7 +181,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
struct msm_kms *kms;
int ret;
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(dev->dev, "failed to allocate private data\n");
@@ -314,13 +313,15 @@ fail:
static void load_gpu(struct drm_device *dev)
{
+ static DEFINE_MUTEX(init_lock);
struct msm_drm_private *priv = dev->dev_private;
struct msm_gpu *gpu;
+ mutex_lock(&init_lock);
+
if (priv->gpu)
- return;
+ goto out;
- mutex_lock(&dev->struct_mutex);
gpu = a3xx_gpu_init(dev);
if (IS_ERR(gpu)) {
dev_warn(dev->dev, "failed to load a3xx gpu\n");
@@ -330,7 +331,9 @@ static void load_gpu(struct drm_device *dev)
if (gpu) {
int ret;
+ mutex_lock(&dev->struct_mutex);
gpu->funcs->pm_resume(gpu);
+ mutex_unlock(&dev->struct_mutex);
ret = gpu->funcs->hw_init(gpu);
if (ret) {
dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
@@ -340,12 +343,12 @@ static void load_gpu(struct drm_device *dev)
/* give inactive pm a chance to kick in: */
msm_gpu_retire(gpu);
}
-
}
priv->gpu = gpu;
- mutex_unlock(&dev->struct_mutex);
+out:
+ mutex_unlock(&init_lock);
}
static int msm_open(struct drm_device *dev, struct drm_file *file)
@@ -906,25 +909,22 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == data;
}
-static int msm_drm_add_components(struct device *master, struct master *m)
+static int add_components(struct device *dev, struct component_match **matchptr,
+ const char *name)
{
- struct device_node *np = master->of_node;
+ struct device_node *np = dev->of_node;
unsigned i;
- int ret;
for (i = 0; ; i++) {
struct device_node *node;
- node = of_parse_phandle(np, "connectors", i);
+ node = of_parse_phandle(np, name, i);
if (!node)
break;
- ret = component_master_add_child(m, compare_of, node);
- of_node_put(node);
-
- if (ret)
- return ret;
+ component_match_add(dev, matchptr, compare_of, node);
}
+
return 0;
}
#else
@@ -932,9 +932,34 @@ static int compare_dev(struct device *dev, void *data)
{
return dev == data;
}
+#endif
+
+static int msm_drm_bind(struct device *dev)
+{
+ return drm_platform_init(&msm_driver, to_platform_device(dev));
+}
+
+static void msm_drm_unbind(struct device *dev)
+{
+ drm_put_dev(platform_get_drvdata(to_platform_device(dev)));
+}
+
+static const struct component_master_ops msm_drm_ops = {
+ .bind = msm_drm_bind,
+ .unbind = msm_drm_unbind,
+};
+
+/*
+ * Platform driver:
+ */
-static int msm_drm_add_components(struct device *master, struct master *m)
+static int msm_pdev_probe(struct platform_device *pdev)
{
+ struct component_match *match = NULL;
+#ifdef CONFIG_OF
+ add_components(&pdev->dev, &match, "connectors");
+ add_components(&pdev->dev, &match, "gpus");
+#else
/* For non-DT case, it kinda sucks. We don't actually have a way
* to know whether or not we are waiting for certain devices (or if
* they are simply not present). But for non-DT we only need to
@@ -958,41 +983,12 @@ static int msm_drm_add_components(struct device *master, struct master *m)
return -EPROBE_DEFER;
}
- ret = component_master_add_child(m, compare_dev, dev);
- if (ret) {
- DBG("could not add child: %d", ret);
- return ret;
- }
+ component_match_add(&pdev->dev, &match, compare_dev, dev);
}
-
- return 0;
-}
#endif
-static int msm_drm_bind(struct device *dev)
-{
- return drm_platform_init(&msm_driver, to_platform_device(dev));
-}
-
-static void msm_drm_unbind(struct device *dev)
-{
- drm_put_dev(platform_get_drvdata(to_platform_device(dev)));
-}
-
-static const struct component_master_ops msm_drm_ops = {
- .add_components = msm_drm_add_components,
- .bind = msm_drm_bind,
- .unbind = msm_drm_unbind,
-};
-
-/*
- * Platform driver:
- */
-
-static int msm_pdev_probe(struct platform_device *pdev)
-{
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- return component_master_add(&pdev->dev, &msm_drm_ops);
+ return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);
}
static int msm_pdev_remove(struct platform_device *pdev)
@@ -1008,7 +1004,8 @@ static const struct platform_device_id msm_id[] = {
};
static const struct of_device_id dt_match[] = {
- { .compatible = "qcom,mdss_mdp" },
+ { .compatible = "qcom,mdp" }, /* mdp4 */
+ { .compatible = "qcom,mdss_mdp" }, /* mdp5 */
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 5107fc4826bc..9c5221ce391a 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -19,6 +19,11 @@
#include "drm_crtc.h"
#include "drm_fb_helper.h"
+#include "msm_gem.h"
+
+extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
+ struct vm_area_struct *vma);
+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);
/*
* fbdev funcs, to implement legacy fbdev interface on top of drm driver
@@ -43,6 +48,7 @@ static struct fb_ops msm_fb_ops = {
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
+ .fb_mmap = msm_fbdev_mmap,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
@@ -51,6 +57,31 @@ static struct fb_ops msm_fb_ops = {
.fb_setcmap = drm_fb_helper_setcmap,
};
+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_device *dev = helper->dev;
+ int ret = 0;
+
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ret) {
+ pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
+ return ret;
+ }
+
+ return msm_gem_mmap_obj(drm_obj, vma);
+}
+
static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
@@ -104,8 +135,16 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- /* TODO implement our own fb_mmap so we don't need this: */
- msm_gem_get_iova_locked(fbdev->bo, 0, &paddr);
+ /*
+ * NOTE: if we can be guaranteed to be able to map buffer
+ * in panic (ie. lock-safe, etc) we could avoid pinning the
+ * buffer now:
+ */
+ ret = msm_gem_get_iova_locked(fbdev->bo, 0, &paddr);
+ if (ret) {
+ dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
+ goto fail;
+ }
fbi = framebuffer_alloc(0, dev->dev);
if (!fbi) {
@@ -177,7 +216,7 @@ static void msm_crtc_fb_gamma_get(struct drm_crtc *crtc,
DBG("fbdev: get gamma");
}
-static struct drm_fb_helper_funcs msm_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs msm_fb_helper_funcs = {
.gamma_set = msm_crtc_fb_gamma_set,
.gamma_get = msm_crtc_fb_gamma_get,
.fb_probe = msm_fbdev_create,
@@ -189,7 +228,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
struct msm_drm_private *priv = dev->dev_private;
struct msm_fbdev *fbdev = NULL;
struct drm_fb_helper *helper;
- int ret = 0;
+ int ret;
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev)
@@ -197,7 +236,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
helper = &fbdev->base;
- helper->funcs = &msm_fb_helper_funcs;
+ drm_fb_helper_prepare(dev, helper, &msm_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper,
priv->num_crtcs, priv->num_connectors);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 690d7e7b6d1e..4b1b82adabde 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -73,7 +73,7 @@ static struct page **get_pages(struct drm_gem_object *obj)
int npages = obj->size >> PAGE_SHIFT;
if (iommu_present(&platform_bus_type))
- p = drm_gem_get_pages(obj, 0);
+ p = drm_gem_get_pages(obj);
else
p = get_pages_vram(obj, npages);
@@ -278,24 +278,23 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
uint32_t *iova)
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
- struct drm_device *dev = obj->dev;
int ret = 0;
if (!msm_obj->domain[id].iova) {
struct msm_drm_private *priv = obj->dev->dev_private;
- struct msm_mmu *mmu = priv->mmus[id];
struct page **pages = get_pages(obj);
- if (!mmu) {
- dev_err(dev->dev, "null MMU pointer\n");
- return -EINVAL;
- }
-
if (IS_ERR(pages))
return PTR_ERR(pages);
if (iommu_present(&platform_bus_type)) {
- uint32_t offset = (uint32_t)mmap_offset(obj);
+ struct msm_mmu *mmu = priv->mmus[id];
+ uint32_t offset;
+
+ if (WARN_ON(!mmu))
+ return -EINVAL;
+
+ offset = (uint32_t)mmap_offset(obj);
ret = mmu->funcs->map(mmu, offset, msm_obj->sgt,
obj->size, IOMMU_READ | IOMMU_WRITE);
msm_obj->domain[id].iova = offset;
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index c6322197db8c..4a0dce587745 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -606,14 +606,17 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
iommu = iommu_domain_alloc(&platform_bus_type);
if (iommu) {
dev_info(drm->dev, "%s: using IOMMU\n", name);
- gpu->mmu = msm_iommu_new(drm, iommu);
+ gpu->mmu = msm_iommu_new(&pdev->dev, iommu);
} else {
dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
}
gpu->id = msm_register_mmu(drm, gpu->mmu);
+
/* Create ringbuffer: */
+ mutex_lock(&drm->struct_mutex);
gpu->rb = msm_ringbuffer_new(gpu, ringsz);
+ mutex_unlock(&drm->struct_mutex);
if (IS_ERR(gpu->rb)) {
ret = PTR_ERR(gpu->rb);
gpu->rb = NULL;
@@ -621,13 +624,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
goto fail;
}
- ret = msm_gem_get_iova_locked(gpu->rb->bo, gpu->id, &gpu->rb_iova);
- if (ret) {
- gpu->rb_iova = 0;
- dev_err(drm->dev, "could not map ringbuffer: %d\n", ret);
- goto fail;
- }
-
bs_init(gpu);
return 0;
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 4b2ad9181edf..099af483fdf0 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -33,39 +33,14 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev,
static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
{
- struct drm_device *dev = mmu->dev;
struct msm_iommu *iommu = to_msm_iommu(mmu);
- int i, ret;
-
- for (i = 0; i < cnt; i++) {
- struct device *msm_iommu_get_ctx(const char *ctx_name);
- struct device *ctx = msm_iommu_get_ctx(names[i]);
- if (IS_ERR_OR_NULL(ctx)) {
- dev_warn(dev->dev, "couldn't get %s context", names[i]);
- continue;
- }
- ret = iommu_attach_device(iommu->domain, ctx);
- if (ret) {
- dev_warn(dev->dev, "could not attach iommu to %s", names[i]);
- return ret;
- }
- }
-
- return 0;
+ return iommu_attach_device(iommu->domain, mmu->dev);
}
static void msm_iommu_detach(struct msm_mmu *mmu, const char **names, int cnt)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
- int i;
-
- for (i = 0; i < cnt; i++) {
- struct device *msm_iommu_get_ctx(const char *ctx_name);
- struct device *ctx = msm_iommu_get_ctx(names[i]);
- if (IS_ERR_OR_NULL(ctx))
- continue;
- iommu_detach_device(iommu->domain, ctx);
- }
+ iommu_detach_device(iommu->domain, mmu->dev);
}
static int msm_iommu_map(struct msm_mmu *mmu, uint32_t iova,
@@ -149,7 +124,7 @@ static const struct msm_mmu_funcs funcs = {
.destroy = msm_iommu_destroy,
};
-struct msm_mmu *msm_iommu_new(struct drm_device *dev, struct iommu_domain *domain)
+struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
{
struct msm_iommu *iommu;
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 21da6d154f71..7cd88d9dc155 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -32,17 +32,17 @@ struct msm_mmu_funcs {
struct msm_mmu {
const struct msm_mmu_funcs *funcs;
- struct drm_device *dev;
+ struct device *dev;
};
-static inline void msm_mmu_init(struct msm_mmu *mmu, struct drm_device *dev,
+static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
const struct msm_mmu_funcs *funcs)
{
mmu->dev = dev;
mmu->funcs = funcs;
}
-struct msm_mmu *msm_iommu_new(struct drm_device *dev, struct iommu_domain *domain);
-struct msm_mmu *msm_gpummu_new(struct drm_device *dev, struct msm_gpu *gpu);
+struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain);
+struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu);
#endif /* __MSM_MMU_H__ */
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 26e962b7e702..2283c442a10d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -1516,11 +1516,11 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head)
}
switch ((ctrl & 0x000f0000) >> 16) {
- case 6: datarate = pclk * 30 / 8; break;
- case 5: datarate = pclk * 24 / 8; break;
+ case 6: datarate = pclk * 30; break;
+ case 5: datarate = pclk * 24; break;
case 2:
default:
- datarate = pclk * 18 / 8;
+ datarate = pclk * 18;
break;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 48aa38a87e3f..fa30d8196f35 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -1159,11 +1159,11 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
if (outp->info.type == DCB_OUTPUT_DP) {
u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300));
switch ((sync & 0x000003c0) >> 6) {
- case 6: pclk = pclk * 30 / 8; break;
- case 5: pclk = pclk * 24 / 8; break;
+ case 6: pclk = pclk * 30; break;
+ case 5: pclk = pclk * 24; break;
case 2:
default:
- pclk = pclk * 18 / 8;
+ pclk = pclk * 18;
break;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c
index 52c299c3d300..eb2d7789555d 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c
@@ -34,7 +34,7 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
struct nvkm_output_dp *outp = (void *)base;
bool retrain = true;
u8 link[2], stat[3];
- u32 rate;
+ u32 linkrate;
int ret, i;
/* check that the link is trained at a high enough rate */
@@ -44,8 +44,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
goto done;
}
- rate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
- if (rate < ((datarate / 8) * 10)) {
+ linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET);
+ linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */
+ datarate = (datarate + 9) / 10; /* -> decakilobits */
+ if (linkrate < datarate) {
DBG("link not trained at sufficient rate\n");
goto done;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
index e1832778e8b6..7a1ebdfa9e1b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
@@ -87,6 +87,7 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
struct nvkm_output_dp *outpdp = (void *)outp;
switch (data) {
case NV94_DISP_SOR_DP_PWR_STATE_OFF:
+ nouveau_event_put(outpdp->irq);
((struct nvkm_output_dp_impl *)nv_oclass(outp))
->lnk_pwr(outpdp, 0);
atomic_set(&outpdp->lt.done, 0);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
index 0f57fcfe0bbf..2af9cfd2c60f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
@@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2)
};
}
-static inline struct ramfuc_reg
+static noinline struct ramfuc_reg
ramfuc_reg(u32 addr)
{
return ramfuc_reg2(addr, addr);
@@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec)
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
-#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
+#define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000)
#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r)
#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d))
#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
index 1ad3ea503133..c5b46e302319 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
@@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc)
/* (re)program mempll, if required */
if (ram->mode == 2) {
ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000);
+ ram_mask(fuc, 0x132000, 0x80000000, 0x80000000);
ram_mask(fuc, 0x132000, 0x00000001, 0x00000000);
ram_mask(fuc, 0x132004, 0x103fffff, mcoef);
ram_mask(fuc, 0x132000, 0x00000001, 0x00000001);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
index cfde9eb44ad0..6212537b90c5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -192,11 +192,11 @@ alarm_timer_callback(struct nouveau_alarm *alarm)
nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_shutdown,
NOUVEAU_THERM_THRS_SHUTDOWN);
+ spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
+
/* schedule the next poll in one second */
if (therm->temp_get(therm) >= 0 && list_empty(&alarm->head))
- ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm);
-
- spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
+ ptimer->alarm(ptimer, 1000000000ULL, alarm);
}
void
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index b6dc85c614be..ba29a701ca1d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -309,7 +309,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
struct ttm_buffer_object *bo = &nvbo->bo;
int ret;
- ret = ttm_bo_reserve(bo, false, false, false, 0);
+ ret = ttm_bo_reserve(bo, false, false, false, NULL);
if (ret)
goto out;
@@ -350,7 +350,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
struct ttm_buffer_object *bo = &nvbo->bo;
int ret, ref;
- ret = ttm_bo_reserve(bo, false, false, false, 0);
+ ret = ttm_bo_reserve(bo, false, false, false, NULL);
if (ret)
return ret;
@@ -385,7 +385,7 @@ nouveau_bo_map(struct nouveau_bo *nvbo)
{
int ret;
- ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+ ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 1fa222e8f007..dbdc9ad59546 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -63,7 +63,7 @@ find_encoder(struct drm_connector *connector, int type)
{
struct drm_device *dev = connector->dev;
struct nouveau_encoder *nv_encoder;
- struct drm_mode_object *obj;
+ struct drm_encoder *enc;
int i, id;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
@@ -71,10 +71,10 @@ find_encoder(struct drm_connector *connector, int type)
if (!id)
break;
- obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ enc = drm_encoder_find(dev, id);
+ if (!enc)
continue;
- nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+ nv_encoder = nouveau_encoder(enc);
if (type == DCB_OUTPUT_ANY ||
(nv_encoder->dcb && nv_encoder->dcb->type == type))
@@ -104,7 +104,7 @@ nouveau_connector_destroy(struct drm_connector *connector)
struct nouveau_connector *nv_connector = nouveau_connector(connector);
nouveau_event_ref(NULL, &nv_connector->hpd);
kfree(nv_connector->edid);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
if (nv_connector->aux.transfer)
drm_dp_aux_unregister(&nv_connector->aux);
@@ -119,7 +119,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
struct nouveau_encoder *nv_encoder;
- struct drm_mode_object *obj;
+ struct drm_encoder *encoder;
int i, panel = -ENODEV;
/* eDP panels need powering on by us (if the VBIOS doesn't default it
@@ -139,10 +139,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
if (id == 0)
break;
- obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(dev, id);
+ if (!encoder)
continue;
- nv_encoder = nouveau_encoder(obj_to_encoder(obj));
+ nv_encoder = nouveau_encoder(encoder);
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
int ret = nouveau_dp_detect(nv_encoder);
@@ -1236,6 +1236,6 @@ nouveau_connector_create(struct drm_device *dev, int index)
INIT_WORK(&nv_connector->work, nouveau_connector_hotplug_work);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return connector;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ddd83756b9a2..c9428c943afb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev)
ret = nouveau_do_resume(drm_dev);
if (ret)
return ret;
- if (drm_dev->mode_config.num_crtc)
- nouveau_fbcon_set_suspend(drm_dev, 0);
- nouveau_fbcon_zfill_all(drm_dev);
- if (drm_dev->mode_config.num_crtc)
+ if (drm_dev->mode_config.num_crtc) {
nouveau_display_resume(drm_dev);
+ nouveau_fbcon_set_suspend(drm_dev, 0);
+ }
+
return 0;
}
@@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev)
ret = nouveau_do_resume(drm_dev);
if (ret)
return ret;
- if (drm_dev->mode_config.num_crtc)
- nouveau_fbcon_set_suspend(drm_dev, 0);
- nouveau_fbcon_zfill_all(drm_dev);
- if (drm_dev->mode_config.num_crtc)
+
+ if (drm_dev->mode_config.num_crtc) {
nouveau_display_resume(drm_dev);
+ nouveau_fbcon_set_suspend(drm_dev, 0);
+ }
+
return 0;
}
@@ -844,6 +845,7 @@ driver = {
.gem_prime_export = drm_gem_prime_export,
.gem_prime_import = drm_gem_prime_import,
.gem_prime_pin = nouveau_gem_prime_pin,
+ .gem_prime_res_obj = nouveau_gem_prime_res_obj,
.gem_prime_unpin = nouveau_gem_prime_unpin,
.gem_prime_get_sg_table = nouveau_gem_prime_get_sg_table,
.gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table,
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 64a42cfd3717..758c11cb9a9a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -438,7 +438,7 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info)
info->flags |= FBINFO_HWACCEL_DISABLED;
}
-static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
+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,
@@ -464,7 +464,8 @@ nouveau_fbcon_init(struct drm_device *dev)
fbcon->dev = dev;
drm->fbcon = fbcon;
- fbcon->helper.funcs = &nouveau_fbcon_helper_funcs;
+
+ drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs);
ret = drm_fb_helper_init(dev, &fbcon->helper,
dev->mode_config.num_crtc, 4);
@@ -531,17 +532,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
if (state == 1)
nouveau_fbcon_save_disable_accel(dev);
fb_set_suspend(drm->fbcon->helper.fbdev, state);
- if (state == 0)
+ if (state == 0) {
nouveau_fbcon_restore_accel(dev);
+ nouveau_fbcon_zfill(dev, drm->fbcon);
+ }
console_unlock();
}
}
-
-void
-nouveau_fbcon_zfill_all(struct drm_device *dev)
-{
- struct nouveau_drm *drm = nouveau_drm(dev);
- if (drm->fbcon) {
- nouveau_fbcon_zfill(dev, drm->fbcon);
- }
-}
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
index fdfc0c94fbcc..fcff797d2084 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h
@@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info);
int nouveau_fbcon_init(struct drm_device *dev);
void nouveau_fbcon_fini(struct drm_device *dev);
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
-void nouveau_fbcon_zfill_all(struct drm_device *dev);
void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
void nouveau_fbcon_restore_accel(struct drm_device *dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index c90c0dc0afe8..df9d451afdcd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -61,7 +61,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
if (!cli->base.vm)
return 0;
- ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+ ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL);
if (ret)
return ret;
@@ -132,7 +132,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
if (!cli->base.vm)
return;
- ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
+ ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL);
if (ret)
return;
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h
index 7caca057bc38..ddab762d81fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.h
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.h
@@ -35,6 +35,7 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_prime_pin(struct drm_gem_object *);
+struct reservation_object *nouveau_gem_prime_res_obj(struct drm_gem_object *);
extern void nouveau_gem_prime_unpin(struct drm_gem_object *);
extern struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *);
extern struct drm_gem_object *nouveau_gem_prime_import_sg_table(
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index 51a2cb102b44..1f51008e4d26 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -102,3 +102,10 @@ void nouveau_gem_prime_unpin(struct drm_gem_object *obj)
nouveau_bo_unpin(nvbo);
}
+
+struct reservation_object *nouveau_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+ struct nouveau_bo *nvbo = nouveau_gem_object(obj);
+
+ return nvbo->bo.resv;
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index ab0228f640a5..7e185c122750 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -76,6 +76,7 @@ static int
nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *bo,
struct ttm_placement *placement,
+ uint32_t flags,
struct ttm_mem_reg *mem)
{
struct nouveau_drm *drm = nouveau_bdev(man->bdev);
@@ -162,6 +163,7 @@ static int
nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *bo,
struct ttm_placement *placement,
+ uint32_t flags,
struct ttm_mem_reg *mem)
{
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
@@ -242,6 +244,7 @@ static int
nv04_gart_manager_new(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *bo,
struct ttm_placement *placement,
+ uint32_t flags,
struct ttm_mem_reg *mem)
{
struct nouveau_mem *node;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index afdf607df3e6..4c534b7b04da 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1741,7 +1741,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
}
}
- mthd = (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
+ mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3;
+ mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
mthd |= nv_encoder->or;
if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index 86f4ead0441d..36bc5cc80816 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -130,7 +130,7 @@ static void omap_connector_destroy(struct drm_connector *connector)
struct omap_dss_device *dssdev = omap_connector->dssdev;
DBG("%s", omap_connector->dssdev->name);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(omap_connector);
@@ -307,7 +307,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
connector->interlace_allowed = 1;
connector->doublescan_allowed = 0;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return connector;
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index f926b4caf449..56c60552abba 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -199,7 +199,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm)
static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
struct page **pages, uint32_t npages, uint32_t roll)
{
- dma_addr_t pat_pa = 0;
+ dma_addr_t pat_pa = 0, data_pa = 0;
uint32_t *data;
struct pat *pat;
struct refill_engine *engine = txn->engine_handle;
@@ -223,7 +223,9 @@ static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area,
.lut_id = engine->tcm->lut_id,
};
- data = alloc_dma(txn, 4*i, &pat->data_pa);
+ data = alloc_dma(txn, 4*i, &data_pa);
+ /* FIXME: what if data_pa is more than 32-bit ? */
+ pat->data_pa = data_pa;
while (i--) {
int n = i + roll;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 284b80fc3c54..b08a450d1b5d 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -119,13 +119,6 @@ struct omap_drm_private {
struct omap_drm_irq error_handler;
};
-/* this should probably be in drm-core to standardize amongst drivers */
-#define DRM_ROTATE_0 0
-#define DRM_ROTATE_90 1
-#define DRM_ROTATE_180 2
-#define DRM_ROTATE_270 3
-#define DRM_REFLECT_X 4
-#define DRM_REFLECT_Y 5
#ifdef CONFIG_DEBUG_FS
int omap_debugfs_init(struct drm_minor *minor);
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 1388ca7f87e8..8436c6857cda 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -281,7 +281,7 @@ fail:
return ret;
}
-static struct drm_fb_helper_funcs omap_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs omap_fb_helper_funcs = {
.fb_probe = omap_fbdev_create,
};
@@ -325,7 +325,7 @@ struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
helper = &fbdev->base;
- helper->funcs = &omap_fb_helper_funcs;
+ drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs);
ret = drm_fb_helper_init(dev, helper,
priv->num_crtcs, priv->num_connectors);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 95dbce286a41..e4849413ee80 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -233,11 +233,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj)
WARN_ON(omap_obj->pages);
- /* TODO: __GFP_DMA32 .. but somehow GFP_HIGHMEM is coming from the
- * mapping_gfp_mask(mapping) which conflicts w/ GFP_DMA32.. probably
- * we actually want CMA memory for it all anyways..
- */
- pages = drm_gem_get_pages(obj, GFP_KERNEL);
+ pages = drm_gem_get_pages(obj);
if (IS_ERR(pages)) {
dev_err(obj->dev->dev, "could not get pages: %ld\n", PTR_ERR(pages));
return PTR_ERR(pages);
@@ -791,7 +787,7 @@ int omap_gem_get_paddr(struct drm_gem_object *obj,
omap_obj->paddr = tiler_ssptr(block);
omap_obj->block = block;
- DBG("got paddr: %08x", omap_obj->paddr);
+ DBG("got paddr: %pad", &omap_obj->paddr);
}
omap_obj->paddr_cnt++;
@@ -985,9 +981,9 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
off = drm_vma_node_start(&obj->vma_node);
- seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
+ seq_printf(m, "%08x: %2d (%2d) %08llx %pad (%2d) %p %4d",
omap_obj->flags, obj->name, obj->refcount.refcount.counter,
- off, omap_obj->paddr, omap_obj->paddr_cnt,
+ off, &omap_obj->paddr, omap_obj->paddr_cnt,
omap_obj->vaddr, omap_obj->roll);
if (omap_obj->flags & OMAP_BO_TILED) {
@@ -1183,9 +1179,7 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op)
}
}
spin_unlock(&sync_lock);
-
- if (waiter)
- kfree(waiter);
+ kfree(waiter);
}
return ret;
}
@@ -1347,6 +1341,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
struct omap_drm_private *priv = dev->dev_private;
struct omap_gem_object *omap_obj;
struct drm_gem_object *obj = NULL;
+ struct address_space *mapping;
size_t size;
int ret;
@@ -1404,14 +1399,16 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
omap_obj->height = gsize.tiled.height;
}
- ret = 0;
- if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM))
+ if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) {
drm_gem_private_object_init(dev, obj, size);
- else
+ } else {
ret = drm_gem_object_init(dev, obj, size);
+ if (ret)
+ goto fail;
- if (ret)
- goto fail;
+ mapping = file_inode(obj->filp)->i_mapping;
+ mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32);
+ }
return obj;
@@ -1467,8 +1464,8 @@ void omap_gem_init(struct drm_device *dev)
entry->paddr = tiler_ssptr(block);
entry->block = block;
- DBG("%d:%d: %dx%d: paddr=%08x stride=%d", i, j, w, h,
- entry->paddr,
+ DBG("%d:%d: %dx%d: paddr=%pad stride=%d", i, j, w, h,
+ &entry->paddr,
usergart[i].stride_pfn << PAGE_SHIFT);
}
}
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 4fcca8d42796..a2dbfb1737b4 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -171,7 +171,7 @@ static struct dma_buf_ops omap_dmabuf_ops = {
struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
- return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags);
+ return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags, NULL);
}
struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 3cf31ee59aac..891a4dc608af 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -142,8 +142,8 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
DBG("%dx%d -> %dx%d (%d)", info->width, info->height,
info->out_width, info->out_height,
info->screen_width);
- DBG("%d,%d %08x %08x", info->pos_x, info->pos_y,
- info->paddr, info->p_uv_addr);
+ DBG("%d,%d %pad %pad", info->pos_x, info->pos_y,
+ &info->paddr, &info->p_uv_addr);
/* TODO: */
ilace = false;
@@ -308,16 +308,13 @@ void omap_plane_install_properties(struct drm_plane *plane,
if (priv->has_dmm) {
prop = priv->rotation_prop;
if (!prop) {
- const struct drm_prop_enum_list props[] = {
- { DRM_ROTATE_0, "rotate-0" },
- { DRM_ROTATE_90, "rotate-90" },
- { DRM_ROTATE_180, "rotate-180" },
- { DRM_ROTATE_270, "rotate-270" },
- { DRM_REFLECT_X, "reflect-x" },
- { DRM_REFLECT_Y, "reflect-y" },
- };
- prop = drm_property_create_bitmask(dev, 0, "rotation",
- props, ARRAY_SIZE(props));
+ prop = drm_mode_create_rotation_property(dev,
+ BIT(DRM_ROTATE_0) |
+ BIT(DRM_ROTATE_90) |
+ BIT(DRM_ROTATE_180) |
+ BIT(DRM_ROTATE_270) |
+ BIT(DRM_REFLECT_X) |
+ BIT(DRM_REFLECT_Y));
if (prop == NULL)
return;
priv->rotation_prop = prop;
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4ec874da5668..bee9f72b3a93 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -5,7 +5,7 @@ config DRM_PANEL
Panel registration and lookup framework.
menu "Display Panels"
- depends on DRM_PANEL
+ depends on DRM && DRM_PANEL
config DRM_PANEL_SIMPLE
tristate "support for simple panels"
@@ -18,14 +18,11 @@ config DRM_PANEL_SIMPLE
config DRM_PANEL_LD9040
tristate "LD9040 RGB/SPI panel"
- depends on DRM && DRM_PANEL
- depends on OF
- select SPI
+ depends on OF && SPI
select VIDEOMODE_HELPERS
config DRM_PANEL_S6E8AA0
tristate "S6E8AA0 DSI video mode panel"
- depends on DRM && DRM_PANEL
depends on OF
select DRM_MIPI_DSI
select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/panel/panel-ld9040.c b/drivers/gpu/drm/panel/panel-ld9040.c
index db1601fdbe29..42ac67b21e9f 100644
--- a/drivers/gpu/drm/panel/panel-ld9040.c
+++ b/drivers/gpu/drm/panel/panel-ld9040.c
@@ -110,7 +110,10 @@ struct ld9040 {
int error;
};
-#define panel_to_ld9040(p) container_of(p, struct ld9040, panel)
+static inline struct ld9040 *panel_to_ld9040(struct drm_panel *panel)
+{
+ return container_of(panel, struct ld9040, panel);
+}
static int ld9040_clear_error(struct ld9040 *ctx)
{
@@ -216,6 +219,11 @@ static int ld9040_power_off(struct ld9040 *ctx)
static int ld9040_disable(struct drm_panel *panel)
{
+ return 0;
+}
+
+static int ld9040_unprepare(struct drm_panel *panel)
+{
struct ld9040 *ctx = panel_to_ld9040(panel);
msleep(120);
@@ -228,7 +236,7 @@ static int ld9040_disable(struct drm_panel *panel)
return ld9040_power_off(ctx);
}
-static int ld9040_enable(struct drm_panel *panel)
+static int ld9040_prepare(struct drm_panel *panel)
{
struct ld9040 *ctx = panel_to_ld9040(panel);
int ret;
@@ -242,11 +250,16 @@ static int ld9040_enable(struct drm_panel *panel)
ret = ld9040_clear_error(ctx);
if (ret < 0)
- ld9040_disable(panel);
+ ld9040_unprepare(panel);
return ret;
}
+static int ld9040_enable(struct drm_panel *panel)
+{
+ return 0;
+}
+
static int ld9040_get_modes(struct drm_panel *panel)
{
struct drm_connector *connector = panel->connector;
@@ -273,6 +286,8 @@ static int ld9040_get_modes(struct drm_panel *panel)
static const struct drm_panel_funcs ld9040_drm_funcs = {
.disable = ld9040_disable,
+ .unprepare = ld9040_unprepare,
+ .prepare = ld9040_prepare,
.enable = ld9040_enable,
.get_modes = ld9040_get_modes,
};
diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-s6e8aa0.c
index 06e57a26db7a..b5217fe37f02 100644
--- a/drivers/gpu/drm/panel/panel-s6e8aa0.c
+++ b/drivers/gpu/drm/panel/panel-s6e8aa0.c
@@ -120,7 +120,10 @@ struct s6e8aa0 {
int error;
};
-#define panel_to_s6e8aa0(p) container_of(p, struct s6e8aa0, panel)
+static inline struct s6e8aa0 *panel_to_s6e8aa0(struct drm_panel *panel)
+{
+ return container_of(panel, struct s6e8aa0, panel);
+}
static int s6e8aa0_clear_error(struct s6e8aa0 *ctx)
{
@@ -133,14 +136,14 @@ static int s6e8aa0_clear_error(struct s6e8aa0 *ctx)
static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len)
{
struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
- int ret;
+ ssize_t ret;
if (ctx->error < 0)
return;
- ret = mipi_dsi_dcs_write(dsi, dsi->channel, data, len);
+ ret = mipi_dsi_dcs_write(dsi, data, len);
if (ret < 0) {
- dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, len,
+ dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, len,
data);
ctx->error = ret;
}
@@ -154,7 +157,7 @@ static int s6e8aa0_dcs_read(struct s6e8aa0 *ctx, u8 cmd, void *data, size_t len)
if (ctx->error < 0)
return ctx->error;
- ret = mipi_dsi_dcs_read(dsi, dsi->channel, cmd, data, len);
+ ret = mipi_dsi_dcs_read(dsi, cmd, data, len);
if (ret < 0) {
dev_err(ctx->dev, "error %d reading dcs seq(%#x)\n", ret, cmd);
ctx->error = ret;
@@ -889,6 +892,11 @@ static int s6e8aa0_power_off(struct s6e8aa0 *ctx)
static int s6e8aa0_disable(struct drm_panel *panel)
{
+ return 0;
+}
+
+static int s6e8aa0_unprepare(struct drm_panel *panel)
+{
struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
@@ -900,7 +908,7 @@ static int s6e8aa0_disable(struct drm_panel *panel)
return s6e8aa0_power_off(ctx);
}
-static int s6e8aa0_enable(struct drm_panel *panel)
+static int s6e8aa0_prepare(struct drm_panel *panel)
{
struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
int ret;
@@ -913,11 +921,16 @@ static int s6e8aa0_enable(struct drm_panel *panel)
ret = ctx->error;
if (ret < 0)
- s6e8aa0_disable(panel);
+ s6e8aa0_unprepare(panel);
return ret;
}
+static int s6e8aa0_enable(struct drm_panel *panel)
+{
+ return 0;
+}
+
static int s6e8aa0_get_modes(struct drm_panel *panel)
{
struct drm_connector *connector = panel->connector;
@@ -944,6 +957,8 @@ static int s6e8aa0_get_modes(struct drm_panel *panel)
static const struct drm_panel_funcs s6e8aa0_drm_funcs = {
.disable = s6e8aa0_disable,
+ .unprepare = s6e8aa0_unprepare,
+ .prepare = s6e8aa0_prepare,
.enable = s6e8aa0_enable,
.get_modes = s6e8aa0_get_modes,
};
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index a25136132c31..4ce1db0a68ff 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -37,14 +37,35 @@ struct panel_desc {
const struct drm_display_mode *modes;
unsigned int num_modes;
+ unsigned int bpc;
+
struct {
unsigned int width;
unsigned int height;
} size;
+
+ /**
+ * @prepare: the time (in milliseconds) that it takes for the panel to
+ * become ready and start receiving video data
+ * @enable: the time (in milliseconds) that it takes for the panel to
+ * display the first valid frame after starting to receive
+ * video data
+ * @disable: the time (in milliseconds) that it takes for the panel to
+ * turn the display off (no content is visible)
+ * @unprepare: the time (in milliseconds) that it takes for the panel
+ * to power itself down completely
+ */
+ struct {
+ unsigned int prepare;
+ unsigned int enable;
+ unsigned int disable;
+ unsigned int unprepare;
+ } delay;
};
struct panel_simple {
struct drm_panel base;
+ bool prepared;
bool enabled;
const struct panel_desc *desc;
@@ -87,6 +108,7 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel)
num++;
}
+ connector->display_info.bpc = panel->desc->bpc;
connector->display_info.width_mm = panel->desc->size.width;
connector->display_info.height_mm = panel->desc->size.height;
@@ -105,21 +127,40 @@ static int panel_simple_disable(struct drm_panel *panel)
backlight_update_status(p->backlight);
}
+ if (p->desc->delay.disable)
+ msleep(p->desc->delay.disable);
+
+ p->enabled = false;
+
+ return 0;
+}
+
+static int panel_simple_unprepare(struct drm_panel *panel)
+{
+ struct panel_simple *p = to_panel_simple(panel);
+
+ if (!p->prepared)
+ return 0;
+
if (p->enable_gpio)
gpiod_set_value_cansleep(p->enable_gpio, 0);
regulator_disable(p->supply);
- p->enabled = false;
+
+ if (p->desc->delay.unprepare)
+ msleep(p->desc->delay.unprepare);
+
+ p->prepared = false;
return 0;
}
-static int panel_simple_enable(struct drm_panel *panel)
+static int panel_simple_prepare(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);
int err;
- if (p->enabled)
+ if (p->prepared)
return 0;
err = regulator_enable(p->supply);
@@ -131,6 +172,24 @@ static int panel_simple_enable(struct drm_panel *panel)
if (p->enable_gpio)
gpiod_set_value_cansleep(p->enable_gpio, 1);
+ if (p->desc->delay.prepare)
+ msleep(p->desc->delay.prepare);
+
+ p->prepared = true;
+
+ return 0;
+}
+
+static int panel_simple_enable(struct drm_panel *panel)
+{
+ struct panel_simple *p = to_panel_simple(panel);
+
+ if (p->enabled)
+ return 0;
+
+ if (p->desc->delay.enable)
+ msleep(p->desc->delay.enable);
+
if (p->backlight) {
p->backlight->props.power = FB_BLANK_UNBLANK;
backlight_update_status(p->backlight);
@@ -164,6 +223,8 @@ static int panel_simple_get_modes(struct drm_panel *panel)
static const struct drm_panel_funcs panel_simple_funcs = {
.disable = panel_simple_disable,
+ .unprepare = panel_simple_unprepare,
+ .prepare = panel_simple_prepare,
.enable = panel_simple_enable,
.get_modes = panel_simple_get_modes,
};
@@ -179,22 +240,21 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
return -ENOMEM;
panel->enabled = false;
+ panel->prepared = false;
panel->desc = desc;
panel->supply = devm_regulator_get(dev, "power");
if (IS_ERR(panel->supply))
return PTR_ERR(panel->supply);
- panel->enable_gpio = devm_gpiod_get(dev, "enable");
+ panel->enable_gpio = devm_gpiod_get_optional(dev, "enable");
if (IS_ERR(panel->enable_gpio)) {
err = PTR_ERR(panel->enable_gpio);
- if (err != -ENOENT) {
- dev_err(dev, "failed to request GPIO: %d\n", err);
- return err;
- }
+ dev_err(dev, "failed to request GPIO: %d\n", err);
+ return err;
+ }
- panel->enable_gpio = NULL;
- } else {
+ if (panel->enable_gpio) {
err = gpiod_direction_output(panel->enable_gpio, 0);
if (err < 0) {
dev_err(dev, "failed to setup GPIO: %d\n", err);
@@ -285,6 +345,7 @@ static const struct drm_display_mode auo_b101aw03_mode = {
static const struct panel_desc auo_b101aw03 = {
.modes = &auo_b101aw03_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 223,
.height = 125,
@@ -307,12 +368,40 @@ static const struct drm_display_mode auo_b133xtn01_mode = {
static const struct panel_desc auo_b133xtn01 = {
.modes = &auo_b133xtn01_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 293,
.height = 165,
},
};
+static const struct drm_display_mode auo_b133htn01_mode = {
+ .clock = 150660,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 172,
+ .hsync_end = 1920 + 172 + 80,
+ .htotal = 1920 + 172 + 80 + 60,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 25,
+ .vsync_end = 1080 + 25 + 10,
+ .vtotal = 1080 + 25 + 10 + 10,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc auo_b133htn01 = {
+ .modes = &auo_b133htn01_mode,
+ .num_modes = 1,
+ .size = {
+ .width = 293,
+ .height = 165,
+ },
+ .delay = {
+ .prepare = 105,
+ .enable = 20,
+ .unprepare = 50,
+ },
+};
+
static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
.clock = 72070,
.hdisplay = 1366,
@@ -329,6 +418,7 @@ static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
static const struct panel_desc chunghwa_claa101wa01a = {
.modes = &chunghwa_claa101wa01a_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 220,
.height = 120,
@@ -351,6 +441,7 @@ static const struct drm_display_mode chunghwa_claa101wb01_mode = {
static const struct panel_desc chunghwa_claa101wb01 = {
.modes = &chunghwa_claa101wb01_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 223,
.height = 125,
@@ -374,6 +465,7 @@ static const struct drm_display_mode edt_et057090dhu_mode = {
static const struct panel_desc edt_et057090dhu = {
.modes = &edt_et057090dhu_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 115,
.height = 86,
@@ -397,12 +489,82 @@ static const struct drm_display_mode edt_etm0700g0dh6_mode = {
static const struct panel_desc edt_etm0700g0dh6 = {
.modes = &edt_etm0700g0dh6_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 152,
.height = 91,
},
};
+static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
+ .clock = 32260,
+ .hdisplay = 800,
+ .hsync_start = 800 + 168,
+ .hsync_end = 800 + 168 + 64,
+ .htotal = 800 + 168 + 64 + 88,
+ .vdisplay = 480,
+ .vsync_start = 480 + 37,
+ .vsync_end = 480 + 37 + 2,
+ .vtotal = 480 + 37 + 2 + 8,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc foxlink_fl500wvr00_a0t = {
+ .modes = &foxlink_fl500wvr00_a0t_mode,
+ .num_modes = 1,
+ .size = {
+ .width = 108,
+ .height = 65,
+ },
+};
+
+static const struct drm_display_mode innolux_n116bge_mode = {
+ .clock = 71000,
+ .hdisplay = 1366,
+ .hsync_start = 1366 + 64,
+ .hsync_end = 1366 + 64 + 6,
+ .htotal = 1366 + 64 + 6 + 64,
+ .vdisplay = 768,
+ .vsync_start = 768 + 8,
+ .vsync_end = 768 + 8 + 4,
+ .vtotal = 768 + 8 + 4 + 8,
+ .vrefresh = 60,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static const struct panel_desc innolux_n116bge = {
+ .modes = &innolux_n116bge_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 256,
+ .height = 144,
+ },
+};
+
+static const struct drm_display_mode innolux_n156bge_l21_mode = {
+ .clock = 69300,
+ .hdisplay = 1366,
+ .hsync_start = 1366 + 16,
+ .hsync_end = 1366 + 16 + 34,
+ .htotal = 1366 + 16 + 34 + 50,
+ .vdisplay = 768,
+ .vsync_start = 768 + 2,
+ .vsync_end = 768 + 2 + 6,
+ .vtotal = 768 + 2 + 6 + 12,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc innolux_n156bge_l21 = {
+ .modes = &innolux_n156bge_l21_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 344,
+ .height = 193,
+ },
+};
+
static const struct drm_display_mode lg_lp129qe_mode = {
.clock = 285250,
.hdisplay = 2560,
@@ -419,6 +581,7 @@ static const struct drm_display_mode lg_lp129qe_mode = {
static const struct panel_desc lg_lp129qe = {
.modes = &lg_lp129qe_mode,
.num_modes = 1,
+ .bpc = 8,
.size = {
.width = 272,
.height = 181,
@@ -441,6 +604,7 @@ static const struct drm_display_mode samsung_ltn101nt05_mode = {
static const struct panel_desc samsung_ltn101nt05 = {
.modes = &samsung_ltn101nt05_mode,
.num_modes = 1,
+ .bpc = 6,
.size = {
.width = 1024,
.height = 600,
@@ -452,6 +616,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "auo,b101aw03",
.data = &auo_b101aw03,
}, {
+ .compatible = "auo,b133htn01",
+ .data = &auo_b133htn01,
+ }, {
.compatible = "auo,b133xtn01",
.data = &auo_b133xtn01,
}, {
@@ -470,14 +637,21 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "edt,etm0700g0dh6",
.data = &edt_etm0700g0dh6,
}, {
+ .compatible = "foxlink,fl500wvr00-a0t",
+ .data = &foxlink_fl500wvr00_a0t,
+ }, {
+ .compatible = "innolux,n116bge",
+ .data = &innolux_n116bge,
+ }, {
+ .compatible = "innolux,n156bge-l21",
+ .data = &innolux_n156bge_l21,
+ }, {
.compatible = "lg,lp129qe",
.data = &lg_lp129qe,
}, {
.compatible = "samsung,ltn101nt05",
.data = &samsung_ltn101nt05,
}, {
- .compatible = "simple-panel",
- }, {
/* sentinel */
}
};
@@ -545,7 +719,7 @@ static const struct panel_desc_dsi lg_ld070wx3_sl01 = {
.height = 151,
},
},
- .flags = MIPI_DSI_MODE_VIDEO,
+ .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
.format = MIPI_DSI_FMT_RGB888,
.lanes = 4,
};
@@ -599,7 +773,8 @@ static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
.height = 136,
},
},
- .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
+ .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS,
.format = MIPI_DSI_FMT_RGB888,
.lanes = 4,
};
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 5d7ea2461852..b8ced08b6291 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -835,7 +835,7 @@ static void qxl_conn_destroy(struct drm_connector *connector)
struct qxl_output *qxl_output =
drm_connector_to_qxl_output(connector);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(qxl_output);
}
@@ -902,7 +902,7 @@ static int qdev_output_init(struct drm_device *dev, int num_output)
drm_object_attach_property(&connector->base,
qdev->hotplug_mode_update_property, 0);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return 0;
}
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index f437b30ce689..df567888bb1e 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -660,7 +660,7 @@ static int qxl_fbdev_destroy(struct drm_device *dev, struct qxl_fbdev *qfbdev)
return 0;
}
-static struct drm_fb_helper_funcs qxl_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs qxl_fb_helper_funcs = {
.fb_probe = qxl_fb_find_or_create_single,
};
@@ -676,9 +676,12 @@ int qxl_fbdev_init(struct qxl_device *qdev)
qfbdev->qdev = qdev;
qdev->mode_info.qfbdev = qfbdev;
- qfbdev->helper.funcs = &qxl_fb_helper_funcs;
spin_lock_init(&qfbdev->delayed_ops_lock);
INIT_LIST_HEAD(&qfbdev->delayed_ops);
+
+ drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper,
+ &qxl_fb_helper_funcs);
+
ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
qxl_num_crtc /* num_crtc - QXL supports just 1 */,
QXLFB_CONN_LIMIT);
diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c
index 34d6a85e9023..0bf1e20c6e44 100644
--- a/drivers/gpu/drm/qxl/qxl_irq.c
+++ b/drivers/gpu/drm/qxl/qxl_irq.c
@@ -33,6 +33,9 @@ irqreturn_t qxl_irq_handler(int irq, void *arg)
pending = xchg(&qdev->ram_header->int_pending, 0);
+ if (!pending)
+ return IRQ_NONE;
+
atomic_inc(&qdev->irq_received);
if (pending & QXL_INTERRUPT_DISPLAY) {
diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h
index d458a140c024..83a423293afd 100644
--- a/drivers/gpu/drm/qxl/qxl_object.h
+++ b/drivers/gpu/drm/qxl/qxl_object.h
@@ -31,7 +31,7 @@ static inline int qxl_bo_reserve(struct qxl_bo *bo, bool no_wait)
{
int r;
- r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+ r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, NULL);
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS) {
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
@@ -67,7 +67,7 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type,
{
int r;
- r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
+ r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, NULL);
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS) {
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index dbcbfe80aac0..0013ad0db9ef 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -80,7 +80,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
trinity_smc.o ni_dpm.o si_smc.o si_dpm.o kv_smc.o kv_dpm.o ci_smc.o \
- ci_dpm.o dce6_afmt.o radeon_vm.o
+ ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o
# add async DMA block
radeon-y += \
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index a03c73411a56..30d242b25078 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1414,8 +1414,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN;
WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
- /* set pageflip to happen anywhere in vblank interval */
- WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
+ /* set pageflip to happen only at start of vblank interval (front porch) */
+ WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
if (!atomic && fb && fb != crtc->primary->fb) {
radeon_fb = to_radeon_framebuffer(fb);
@@ -1614,8 +1614,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN;
WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp);
- /* set pageflip to happen anywhere in vblank interval */
- WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
+ /* set pageflip to happen only at start of vblank interval (front porch) */
+ WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
if (!atomic && fb && fb != crtc->primary->fb) {
radeon_fb = to_radeon_framebuffer(fb);
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index c5b1f2da3954..b1e11f8434e2 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -127,7 +127,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
/* flags not zero */
if (args.v1.ucReplyStatus == 2) {
DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
- r = -EBUSY;
+ r = -EIO;
goto done;
}
@@ -403,16 +403,18 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
{
struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
u8 msg[DP_DPCD_SIZE];
- int ret, i;
+ int ret;
+
+ char dpcd_hex_dump[DP_DPCD_SIZE * 3];
ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg,
DP_DPCD_SIZE);
if (ret > 0) {
memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
- DRM_DEBUG_KMS("DPCD: ");
- for (i = 0; i < DP_DPCD_SIZE; i++)
- DRM_DEBUG_KMS("%02x ", msg[i]);
- DRM_DEBUG_KMS("\n");
+
+ hex_dump_to_buffer(dig_connector->dpcd, sizeof(dig_connector->dpcd),
+ 32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false);
+ DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump);
radeon_dp_probe_oui(radeon_connector);
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 2b2908440644..a7f2ddf09a9d 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -183,7 +183,6 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
struct backlight_properties props;
struct radeon_backlight_privdata *pdata;
struct radeon_encoder_atom_dig *dig;
- u8 backlight_level;
char bl_name[16];
/* Mac laptops with multiple GPUs use the gmux driver for backlight
@@ -222,12 +221,17 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
pdata->encoder = radeon_encoder;
- backlight_level = radeon_atom_get_backlight_level_from_reg(rdev);
-
dig = radeon_encoder->enc_priv;
dig->bl_dev = bd;
bd->props.brightness = radeon_atom_backlight_get_brightness(bd);
+ /* Set a reasonable default here if the level is 0 otherwise
+ * fbdev will attempt to turn the backlight on after console
+ * unblanking and it will try and restore 0 which turns the backlight
+ * off again.
+ */
+ if (bd->props.brightness == 0)
+ bd->props.brightness = RADEON_MAX_BL_LEVEL;
bd->props.power = FB_BLANK_UNBLANK;
backlight_update_status(bd);
@@ -327,12 +331,10 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
- /* get the native mode for LVDS */
- if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+ /* get the native mode for scaling */
+ if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
radeon_panel_mode_fixup(encoder, adjusted_mode);
-
- /* get the native mode for TV */
- if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+ } else if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
if (tv_dac) {
if (tv_dac->tv_std == TV_STD_NTSC ||
@@ -342,6 +344,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
else
radeon_atom_get_tv_timings(rdev, 1, adjusted_mode);
}
+ } else if (radeon_encoder->rmx_type != RMX_OFF) {
+ radeon_panel_mode_fixup(encoder, adjusted_mode);
}
if (ASIC_IS_DCE3(rdev) &&
@@ -712,7 +716,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_connector->use_digital &&
(radeon_connector->audio == RADEON_AUDIO_ENABLE))
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
+ else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
@@ -731,7 +735,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
+ else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
@@ -751,7 +755,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
} else if (radeon_audio != 0) {
if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
return ATOM_ENCODER_MODE_HDMI;
- else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
+ else if (drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
(radeon_connector->audio == RADEON_AUDIO_AUTO))
return ATOM_ENCODER_MODE_HDMI;
else
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index 10dae4106c08..022561e28707 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -940,7 +940,18 @@ static void ci_get_leakage_voltages(struct radeon_device *rdev)
pi->vddc_leakage.count = 0;
pi->vddci_leakage.count = 0;
- if (radeon_atom_get_leakage_id_from_vbios(rdev, &leakage_id) == 0) {
+ if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
+ for (i = 0; i < CISLANDS_MAX_LEAKAGE_COUNT; i++) {
+ virtual_voltage_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
+ if (radeon_atom_get_voltage_evv(rdev, virtual_voltage_id, &vddc) != 0)
+ continue;
+ if (vddc != 0 && vddc != virtual_voltage_id) {
+ pi->vddc_leakage.actual_voltage[pi->vddc_leakage.count] = vddc;
+ pi->vddc_leakage.leakage_id[pi->vddc_leakage.count] = virtual_voltage_id;
+ pi->vddc_leakage.count++;
+ }
+ }
+ } else if (radeon_atom_get_leakage_id_from_vbios(rdev, &leakage_id) == 0) {
for (i = 0; i < CISLANDS_MAX_LEAKAGE_COUNT; i++) {
virtual_voltage_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
if (radeon_atom_get_leakage_vddc_based_on_leakage_params(rdev, &vddc, &vddci,
@@ -1179,7 +1190,7 @@ static int ci_stop_dpm(struct radeon_device *rdev)
tmp &= ~GLOBAL_PWRMGT_EN;
WREG32_SMC(GENERAL_PWRMGT, tmp);
- tmp = RREG32(SCLK_PWRMGT_CNTL);
+ tmp = RREG32_SMC(SCLK_PWRMGT_CNTL);
tmp &= ~DYNAMIC_PM_EN;
WREG32_SMC(SCLK_PWRMGT_CNTL, tmp);
diff --git a/drivers/gpu/drm/radeon/ci_smc.c b/drivers/gpu/drm/radeon/ci_smc.c
index 8debc9d47362..b630edc2fd0c 100644
--- a/drivers/gpu/drm/radeon/ci_smc.c
+++ b/drivers/gpu/drm/radeon/ci_smc.c
@@ -213,24 +213,37 @@ int ci_load_smc_ucode(struct radeon_device *rdev, u32 limit)
if (!rdev->smc_fw)
return -EINVAL;
- switch (rdev->family) {
- case CHIP_BONAIRE:
- ucode_start_address = BONAIRE_SMC_UCODE_START;
- ucode_size = BONAIRE_SMC_UCODE_SIZE;
- break;
- case CHIP_HAWAII:
- ucode_start_address = HAWAII_SMC_UCODE_START;
- ucode_size = HAWAII_SMC_UCODE_SIZE;
- break;
- default:
- DRM_ERROR("unknown asic in smc ucode loader\n");
- BUG();
+ if (rdev->new_fw) {
+ const struct smc_firmware_header_v1_0 *hdr =
+ (const struct smc_firmware_header_v1_0 *)rdev->smc_fw->data;
+
+ radeon_ucode_print_smc_hdr(&hdr->header);
+
+ ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
+ ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
+ src = (const u8 *)
+ (rdev->smc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ } else {
+ switch (rdev->family) {
+ case CHIP_BONAIRE:
+ ucode_start_address = BONAIRE_SMC_UCODE_START;
+ ucode_size = BONAIRE_SMC_UCODE_SIZE;
+ break;
+ case CHIP_HAWAII:
+ ucode_start_address = HAWAII_SMC_UCODE_START;
+ ucode_size = HAWAII_SMC_UCODE_SIZE;
+ break;
+ default:
+ DRM_ERROR("unknown asic in smc ucode loader\n");
+ BUG();
+ }
+
+ src = (const u8 *)rdev->smc_fw->data;
}
if (ucode_size & 3)
return -EINVAL;
- src = (const u8 *)rdev->smc_fw->data;
spin_lock_irqsave(&rdev->smc_idx_lock, flags);
WREG32(SMC_IND_INDEX_0, ucode_start_address);
WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index dcd4518a9b08..b625646bf3e2 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -42,6 +42,16 @@ MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin");
MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
+
+MODULE_FIRMWARE("radeon/bonaire_pfp.bin");
+MODULE_FIRMWARE("radeon/bonaire_me.bin");
+MODULE_FIRMWARE("radeon/bonaire_ce.bin");
+MODULE_FIRMWARE("radeon/bonaire_mec.bin");
+MODULE_FIRMWARE("radeon/bonaire_mc.bin");
+MODULE_FIRMWARE("radeon/bonaire_rlc.bin");
+MODULE_FIRMWARE("radeon/bonaire_sdma.bin");
+MODULE_FIRMWARE("radeon/bonaire_smc.bin");
+
MODULE_FIRMWARE("radeon/HAWAII_pfp.bin");
MODULE_FIRMWARE("radeon/HAWAII_me.bin");
MODULE_FIRMWARE("radeon/HAWAII_ce.bin");
@@ -51,18 +61,45 @@ MODULE_FIRMWARE("radeon/HAWAII_mc2.bin");
MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
+
+MODULE_FIRMWARE("radeon/hawaii_pfp.bin");
+MODULE_FIRMWARE("radeon/hawaii_me.bin");
+MODULE_FIRMWARE("radeon/hawaii_ce.bin");
+MODULE_FIRMWARE("radeon/hawaii_mec.bin");
+MODULE_FIRMWARE("radeon/hawaii_mc.bin");
+MODULE_FIRMWARE("radeon/hawaii_rlc.bin");
+MODULE_FIRMWARE("radeon/hawaii_sdma.bin");
+MODULE_FIRMWARE("radeon/hawaii_smc.bin");
+
MODULE_FIRMWARE("radeon/KAVERI_pfp.bin");
MODULE_FIRMWARE("radeon/KAVERI_me.bin");
MODULE_FIRMWARE("radeon/KAVERI_ce.bin");
MODULE_FIRMWARE("radeon/KAVERI_mec.bin");
MODULE_FIRMWARE("radeon/KAVERI_rlc.bin");
MODULE_FIRMWARE("radeon/KAVERI_sdma.bin");
+
+MODULE_FIRMWARE("radeon/kaveri_pfp.bin");
+MODULE_FIRMWARE("radeon/kaveri_me.bin");
+MODULE_FIRMWARE("radeon/kaveri_ce.bin");
+MODULE_FIRMWARE("radeon/kaveri_mec.bin");
+MODULE_FIRMWARE("radeon/kaveri_mec2.bin");
+MODULE_FIRMWARE("radeon/kaveri_rlc.bin");
+MODULE_FIRMWARE("radeon/kaveri_sdma.bin");
+
MODULE_FIRMWARE("radeon/KABINI_pfp.bin");
MODULE_FIRMWARE("radeon/KABINI_me.bin");
MODULE_FIRMWARE("radeon/KABINI_ce.bin");
MODULE_FIRMWARE("radeon/KABINI_mec.bin");
MODULE_FIRMWARE("radeon/KABINI_rlc.bin");
MODULE_FIRMWARE("radeon/KABINI_sdma.bin");
+
+MODULE_FIRMWARE("radeon/kabini_pfp.bin");
+MODULE_FIRMWARE("radeon/kabini_me.bin");
+MODULE_FIRMWARE("radeon/kabini_ce.bin");
+MODULE_FIRMWARE("radeon/kabini_mec.bin");
+MODULE_FIRMWARE("radeon/kabini_rlc.bin");
+MODULE_FIRMWARE("radeon/kabini_sdma.bin");
+
MODULE_FIRMWARE("radeon/MULLINS_pfp.bin");
MODULE_FIRMWARE("radeon/MULLINS_me.bin");
MODULE_FIRMWARE("radeon/MULLINS_ce.bin");
@@ -70,6 +107,13 @@ MODULE_FIRMWARE("radeon/MULLINS_mec.bin");
MODULE_FIRMWARE("radeon/MULLINS_rlc.bin");
MODULE_FIRMWARE("radeon/MULLINS_sdma.bin");
+MODULE_FIRMWARE("radeon/mullins_pfp.bin");
+MODULE_FIRMWARE("radeon/mullins_me.bin");
+MODULE_FIRMWARE("radeon/mullins_ce.bin");
+MODULE_FIRMWARE("radeon/mullins_mec.bin");
+MODULE_FIRMWARE("radeon/mullins_rlc.bin");
+MODULE_FIRMWARE("radeon/mullins_sdma.bin");
+
extern int r600_ih_ring_alloc(struct radeon_device *rdev);
extern void r600_ih_ring_fini(struct radeon_device *rdev);
extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
@@ -1760,27 +1804,44 @@ static void cik_srbm_select(struct radeon_device *rdev,
*/
int ci_mc_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
+ const __be32 *fw_data = NULL;
+ const __le32 *new_fw_data = NULL;
u32 running, blackout = 0;
- u32 *io_mc_regs;
+ u32 *io_mc_regs = NULL;
+ const __le32 *new_io_mc_regs = NULL;
int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
- ucode_size = rdev->mc_fw->size / 4;
+ if (rdev->new_fw) {
+ const struct mc_firmware_header_v1_0 *hdr =
+ (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
- switch (rdev->family) {
- case CHIP_BONAIRE:
- io_mc_regs = (u32 *)&bonaire_io_mc_regs;
- regs_size = BONAIRE_IO_MC_REGS_SIZE;
- break;
- case CHIP_HAWAII:
- io_mc_regs = (u32 *)&hawaii_io_mc_regs;
- regs_size = HAWAII_IO_MC_REGS_SIZE;
- break;
- default:
- return -EINVAL;
+ radeon_ucode_print_mc_hdr(&hdr->header);
+
+ regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
+ new_io_mc_regs = (const __le32 *)
+ (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
+ ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ new_fw_data = (const __le32 *)
+ (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ } else {
+ ucode_size = rdev->mc_fw->size / 4;
+
+ switch (rdev->family) {
+ case CHIP_BONAIRE:
+ io_mc_regs = (u32 *)&bonaire_io_mc_regs;
+ regs_size = BONAIRE_IO_MC_REGS_SIZE;
+ break;
+ case CHIP_HAWAII:
+ io_mc_regs = (u32 *)&hawaii_io_mc_regs;
+ regs_size = HAWAII_IO_MC_REGS_SIZE;
+ break;
+ default:
+ return -EINVAL;
+ }
+ fw_data = (const __be32 *)rdev->mc_fw->data;
}
running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
@@ -1797,13 +1858,21 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
/* load mc io regs */
for (i = 0; i < regs_size; i++) {
- WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
- WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+ if (rdev->new_fw) {
+ WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
+ WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
+ } else {
+ WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+ WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+ }
}
/* load the MC ucode */
- fw_data = (const __be32 *)rdev->mc_fw->data;
- for (i = 0; i < ucode_size; i++)
- WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+ for (i = 0; i < ucode_size; i++) {
+ if (rdev->new_fw)
+ WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
+ else
+ WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+ }
/* put the engine back into the active state */
WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
@@ -1841,17 +1910,21 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
static int cik_init_microcode(struct radeon_device *rdev)
{
const char *chip_name;
+ const char *new_chip_name;
size_t pfp_req_size, me_req_size, ce_req_size,
mec_req_size, rlc_req_size, mc_req_size = 0,
sdma_req_size, smc_req_size = 0, mc2_req_size = 0;
char fw_name[30];
+ int new_fw = 0;
int err;
+ int num_fw;
DRM_DEBUG("\n");
switch (rdev->family) {
case CHIP_BONAIRE:
chip_name = "BONAIRE";
+ new_chip_name = "bonaire";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
me_req_size = CIK_ME_UCODE_SIZE * 4;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
@@ -1861,9 +1934,11 @@ static int cik_init_microcode(struct radeon_device *rdev)
mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4);
+ num_fw = 8;
break;
case CHIP_HAWAII:
chip_name = "HAWAII";
+ new_chip_name = "hawaii";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
me_req_size = CIK_ME_UCODE_SIZE * 4;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
@@ -1873,142 +1948,285 @@ static int cik_init_microcode(struct radeon_device *rdev)
mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4);
+ num_fw = 8;
break;
case CHIP_KAVERI:
chip_name = "KAVERI";
+ new_chip_name = "kaveri";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
me_req_size = CIK_ME_UCODE_SIZE * 4;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = KV_RLC_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+ num_fw = 7;
break;
case CHIP_KABINI:
chip_name = "KABINI";
+ new_chip_name = "kabini";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
me_req_size = CIK_ME_UCODE_SIZE * 4;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = KB_RLC_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+ num_fw = 6;
break;
case CHIP_MULLINS:
chip_name = "MULLINS";
+ new_chip_name = "mullins";
pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
me_req_size = CIK_ME_UCODE_SIZE * 4;
ce_req_size = CIK_CE_UCODE_SIZE * 4;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = ML_RLC_UCODE_SIZE * 4;
sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+ num_fw = 6;
break;
default: BUG();
}
- DRM_INFO("Loading %s Microcode\n", chip_name);
+ DRM_INFO("Loading %s Microcode\n", new_chip_name);
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->pfp_fw->size != pfp_req_size) {
- printk(KERN_ERR
- "cik_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->pfp_fw->size, fw_name);
- err = -EINVAL;
- goto out;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+ err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->pfp_fw->size != pfp_req_size) {
+ printk(KERN_ERR
+ "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->pfp_fw->size, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->pfp_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->me_fw->size != me_req_size) {
- printk(KERN_ERR
- "cik_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->me_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+ err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->me_fw->size != me_req_size) {
+ printk(KERN_ERR
+ "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->me_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->ce_fw->size != ce_req_size) {
- printk(KERN_ERR
- "cik_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->ce_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+ err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->ce_fw->size != ce_req_size) {
+ printk(KERN_ERR
+ "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->ce_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->ce_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", new_chip_name);
err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->mec_fw->size != mec_req_size) {
- printk(KERN_ERR
- "cik_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->mec_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name);
+ err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->mec_fw->size != mec_req_size) {
+ printk(KERN_ERR
+ "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->mec_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->mec_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
+ if (rdev->family == CHIP_KAVERI) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec2.bin", new_chip_name);
+ err = request_firmware(&rdev->mec2_fw, fw_name, rdev->dev);
+ if (err) {
+ goto out;
+ } else {
+ err = radeon_ucode_validate(rdev->mec2_fw);
+ if (err) {
+ goto out;
+ } else {
+ new_fw++;
+ }
+ }
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->rlc_fw->size != rlc_req_size) {
- printk(KERN_ERR
- "cik_rlc: Bogus length %zu in firmware \"%s\"\n",
- rdev->rlc_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
+ err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->rlc_fw->size != rlc_req_size) {
+ printk(KERN_ERR
+ "cik_rlc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->rlc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->rlc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", new_chip_name);
err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->sdma_fw->size != sdma_req_size) {
- printk(KERN_ERR
- "cik_sdma: Bogus length %zu in firmware \"%s\"\n",
- rdev->sdma_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name);
+ err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->sdma_fw->size != sdma_req_size) {
+ printk(KERN_ERR
+ "cik_sdma: Bogus length %zu in firmware \"%s\"\n",
+ rdev->sdma_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->sdma_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
/* No SMC, MC ucode on APUs */
if (!(rdev->flags & RADEON_IS_IGP)) {
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
if (err) {
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
- if (err)
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ }
+ if ((rdev->mc_fw->size != mc_req_size) &&
+ (rdev->mc_fw->size != mc2_req_size)){
+ printk(KERN_ERR
+ "cik_mc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->mc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
+ } else {
+ err = radeon_ucode_validate(rdev->mc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
goto out;
+ } else {
+ new_fw++;
+ }
}
- if ((rdev->mc_fw->size != mc_req_size) &&
- (rdev->mc_fw->size != mc2_req_size)){
- printk(KERN_ERR
- "cik_mc: Bogus length %zu in firmware \"%s\"\n",
- rdev->mc_fw->size, fw_name);
- err = -EINVAL;
- }
- DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
if (err) {
- printk(KERN_ERR
- "smc: error loading firmware \"%s\"\n",
- fw_name);
- release_firmware(rdev->smc_fw);
- rdev->smc_fw = NULL;
- err = 0;
- } else if (rdev->smc_fw->size != smc_req_size) {
- printk(KERN_ERR
- "cik_smc: Bogus length %zu in firmware \"%s\"\n",
- rdev->smc_fw->size, fw_name);
- err = -EINVAL;
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+ err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+ if (err) {
+ printk(KERN_ERR
+ "smc: error loading firmware \"%s\"\n",
+ fw_name);
+ release_firmware(rdev->smc_fw);
+ rdev->smc_fw = NULL;
+ err = 0;
+ } else if (rdev->smc_fw->size != smc_req_size) {
+ printk(KERN_ERR
+ "cik_smc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->smc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->smc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "cik_fw: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
}
+ if (new_fw == 0) {
+ rdev->new_fw = false;
+ } else if (new_fw < num_fw) {
+ printk(KERN_ERR "ci_fw: mixing new and old firmware!\n");
+ err = -EINVAL;
+ } else {
+ rdev->new_fw = true;
+ }
+
out:
if (err) {
if (err != -EINVAL)
@@ -2021,8 +2239,14 @@ out:
rdev->me_fw = NULL;
release_firmware(rdev->ce_fw);
rdev->ce_fw = NULL;
+ release_firmware(rdev->mec_fw);
+ rdev->mec_fw = NULL;
+ release_firmware(rdev->mec2_fw);
+ rdev->mec2_fw = NULL;
release_firmware(rdev->rlc_fw);
rdev->rlc_fw = NULL;
+ release_firmware(rdev->sdma_fw);
+ rdev->sdma_fw = NULL;
release_firmware(rdev->mc_fw);
rdev->mc_fw = NULL;
release_firmware(rdev->smc_fw);
@@ -2291,6 +2515,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev)
gb_tile_moden = 0;
break;
}
+ rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden;
WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
}
} else if (num_pipe_configs == 8) {
@@ -3665,8 +3890,6 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2));
radeon_ring_write(ring, fence->seq);
radeon_ring_write(ring, 0);
- /* HDP flush */
- cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
}
/**
@@ -3695,8 +3918,6 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev,
radeon_ring_write(ring, upper_32_bits(addr));
radeon_ring_write(ring, fence->seq);
radeon_ring_write(ring, 0);
- /* HDP flush */
- cik_hdp_flush_cp_ring_emit(rdev, fence->ring);
}
bool cik_semaphore_ring_emit(struct radeon_device *rdev,
@@ -3968,7 +4189,6 @@ static void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable)
*/
static int cik_cp_gfx_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
int i;
if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
@@ -3976,26 +4196,70 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev)
cik_cp_gfx_enable(rdev, false);
- /* PFP */
- fw_data = (const __be32 *)rdev->pfp_fw->data;
- WREG32(CP_PFP_UCODE_ADDR, 0);
- for (i = 0; i < CIK_PFP_UCODE_SIZE; i++)
- WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_PFP_UCODE_ADDR, 0);
-
- /* CE */
- fw_data = (const __be32 *)rdev->ce_fw->data;
- WREG32(CP_CE_UCODE_ADDR, 0);
- for (i = 0; i < CIK_CE_UCODE_SIZE; i++)
- WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_CE_UCODE_ADDR, 0);
-
- /* ME */
- fw_data = (const __be32 *)rdev->me_fw->data;
- WREG32(CP_ME_RAM_WADDR, 0);
- for (i = 0; i < CIK_ME_UCODE_SIZE; i++)
- WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_ME_RAM_WADDR, 0);
+ if (rdev->new_fw) {
+ const struct gfx_firmware_header_v1_0 *pfp_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
+ const struct gfx_firmware_header_v1_0 *ce_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
+ const struct gfx_firmware_header_v1_0 *me_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
+ const __le32 *fw_data;
+ u32 fw_size;
+
+ radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
+ radeon_ucode_print_gfx_hdr(&ce_hdr->header);
+ radeon_ucode_print_gfx_hdr(&me_hdr->header);
+
+ /* PFP */
+ fw_data = (const __le32 *)
+ (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+
+ /* CE */
+ fw_data = (const __le32 *)
+ (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_CE_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_CE_UCODE_ADDR, 0);
+
+ /* ME */
+ fw_data = (const __be32 *)
+ (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_ME_RAM_WADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_ME_RAM_WADDR, 0);
+ } else {
+ const __be32 *fw_data;
+
+ /* PFP */
+ fw_data = (const __be32 *)rdev->pfp_fw->data;
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+ for (i = 0; i < CIK_PFP_UCODE_SIZE; i++)
+ WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+
+ /* CE */
+ fw_data = (const __be32 *)rdev->ce_fw->data;
+ WREG32(CP_CE_UCODE_ADDR, 0);
+ for (i = 0; i < CIK_CE_UCODE_SIZE; i++)
+ WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_CE_UCODE_ADDR, 0);
+
+ /* ME */
+ fw_data = (const __be32 *)rdev->me_fw->data;
+ WREG32(CP_ME_RAM_WADDR, 0);
+ for (i = 0; i < CIK_ME_UCODE_SIZE; i++)
+ WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_ME_RAM_WADDR, 0);
+ }
WREG32(CP_PFP_UCODE_ADDR, 0);
WREG32(CP_CE_UCODE_ADDR, 0);
@@ -4260,7 +4524,6 @@ static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable)
*/
static int cik_cp_compute_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
int i;
if (!rdev->mec_fw)
@@ -4268,20 +4531,55 @@ static int cik_cp_compute_load_microcode(struct radeon_device *rdev)
cik_cp_compute_enable(rdev, false);
- /* MEC1 */
- fw_data = (const __be32 *)rdev->mec_fw->data;
- WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
- for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
- WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
+ if (rdev->new_fw) {
+ const struct gfx_firmware_header_v1_0 *mec_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data;
+ const __le32 *fw_data;
+ u32 fw_size;
+
+ radeon_ucode_print_gfx_hdr(&mec_hdr->header);
+
+ /* MEC1 */
+ fw_data = (const __le32 *)
+ (rdev->mec_fw->data + le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
- if (rdev->family == CHIP_KAVERI) {
/* MEC2 */
+ if (rdev->family == CHIP_KAVERI) {
+ const struct gfx_firmware_header_v1_0 *mec2_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data;
+
+ fw_data = (const __le32 *)
+ (rdev->mec2_fw->data +
+ le32_to_cpu(mec2_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(mec2_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ }
+ } else {
+ const __be32 *fw_data;
+
+ /* MEC1 */
fw_data = (const __be32 *)rdev->mec_fw->data;
- WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
- WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
+
+ if (rdev->family == CHIP_KAVERI) {
+ /* MEC2 */
+ fw_data = (const __be32 *)rdev->mec_fw->data;
+ WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
+ WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+ }
}
return 0;
@@ -4374,7 +4672,7 @@ static int cik_mec_init(struct radeon_device *rdev)
r = radeon_bo_create(rdev,
rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2,
PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_GTT, NULL,
+ RADEON_GEM_DOMAIN_GTT, 0, NULL,
&rdev->mec.hpd_eop_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r);
@@ -4544,7 +4842,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
r = radeon_bo_create(rdev,
sizeof(struct bonaire_mqd),
PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_GTT, NULL,
+ RADEON_GEM_DOMAIN_GTT, 0, NULL,
&rdev->ring[idx].mqd_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r);
@@ -5401,7 +5699,6 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup TLB control */
WREG32(MC_VM_MX_L1_TLB_CNTL,
(0xA << 7) |
@@ -5641,12 +5938,13 @@ static void cik_vm_decode_fault(struct radeon_device *rdev,
void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
{
struct radeon_ring *ring = &rdev->ring[ridx];
+ int usepfp = (ridx == RADEON_RING_TYPE_GFX_INDEX);
if (vm == NULL)
return;
radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
WRITE_DATA_DST_SEL(0)));
if (vm->id < 8) {
radeon_ring_write(ring,
@@ -5696,7 +5994,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
radeon_ring_write(ring, 1 << vm->id);
/* compute doesn't have PFP */
- if (ridx == RADEON_RING_TYPE_GFX_INDEX) {
+ if (usepfp) {
/* sync PFP to ME, otherwise we might get invalid PFP reads */
radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
radeon_ring_write(ring, 0x0);
@@ -5864,28 +6162,10 @@ static void cik_rlc_start(struct radeon_device *rdev)
static int cik_rlc_resume(struct radeon_device *rdev)
{
u32 i, size, tmp;
- const __be32 *fw_data;
if (!rdev->rlc_fw)
return -EINVAL;
- switch (rdev->family) {
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- default:
- size = BONAIRE_RLC_UCODE_SIZE;
- break;
- case CHIP_KAVERI:
- size = KV_RLC_UCODE_SIZE;
- break;
- case CHIP_KABINI:
- size = KB_RLC_UCODE_SIZE;
- break;
- case CHIP_MULLINS:
- size = ML_RLC_UCODE_SIZE;
- break;
- }
-
cik_rlc_stop(rdev);
/* disable CG */
@@ -5909,11 +6189,45 @@ static int cik_rlc_resume(struct radeon_device *rdev)
WREG32(RLC_MC_CNTL, 0);
WREG32(RLC_UCODE_CNTL, 0);
- fw_data = (const __be32 *)rdev->rlc_fw->data;
+ if (rdev->new_fw) {
+ const struct rlc_firmware_header_v1_0 *hdr =
+ (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
+ const __le32 *fw_data = (const __le32 *)
+ (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+
+ radeon_ucode_print_rlc_hdr(&hdr->header);
+
+ size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ WREG32(RLC_GPM_UCODE_ADDR, 0);
+ for (i = 0; i < size; i++)
+ WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++));
WREG32(RLC_GPM_UCODE_ADDR, 0);
- for (i = 0; i < size; i++)
- WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(RLC_GPM_UCODE_ADDR, 0);
+ } else {
+ const __be32 *fw_data;
+
+ switch (rdev->family) {
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ default:
+ size = BONAIRE_RLC_UCODE_SIZE;
+ break;
+ case CHIP_KAVERI:
+ size = KV_RLC_UCODE_SIZE;
+ break;
+ case CHIP_KABINI:
+ size = KB_RLC_UCODE_SIZE;
+ break;
+ case CHIP_MULLINS:
+ size = ML_RLC_UCODE_SIZE;
+ break;
+ }
+
+ fw_data = (const __be32 *)rdev->rlc_fw->data;
+ WREG32(RLC_GPM_UCODE_ADDR, 0);
+ for (i = 0; i < size; i++)
+ WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(RLC_GPM_UCODE_ADDR, 0);
+ }
/* XXX - find out what chips support lbpw */
cik_enable_lbpw(rdev, false);
@@ -6347,11 +6661,10 @@ static void cik_enable_gds_pg(struct radeon_device *rdev, bool enable)
void cik_init_cp_pg_table(struct radeon_device *rdev)
{
- const __be32 *fw_data;
volatile u32 *dst_ptr;
int me, i, max_me = 4;
u32 bo_offset = 0;
- u32 table_offset;
+ u32 table_offset, table_size;
if (rdev->family == CHIP_KAVERI)
max_me = 5;
@@ -6362,24 +6675,71 @@ void cik_init_cp_pg_table(struct radeon_device *rdev)
/* write the cp table buffer */
dst_ptr = rdev->rlc.cp_table_ptr;
for (me = 0; me < max_me; me++) {
- if (me == 0) {
- fw_data = (const __be32 *)rdev->ce_fw->data;
- table_offset = CP_ME_TABLE_OFFSET;
- } else if (me == 1) {
- fw_data = (const __be32 *)rdev->pfp_fw->data;
- table_offset = CP_ME_TABLE_OFFSET;
- } else if (me == 2) {
- fw_data = (const __be32 *)rdev->me_fw->data;
- table_offset = CP_ME_TABLE_OFFSET;
+ if (rdev->new_fw) {
+ const __le32 *fw_data;
+ const struct gfx_firmware_header_v1_0 *hdr;
+
+ if (me == 0) {
+ hdr = (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
+ fw_data = (const __le32 *)
+ (rdev->ce_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ table_offset = le32_to_cpu(hdr->jt_offset);
+ table_size = le32_to_cpu(hdr->jt_size);
+ } else if (me == 1) {
+ hdr = (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
+ fw_data = (const __le32 *)
+ (rdev->pfp_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ table_offset = le32_to_cpu(hdr->jt_offset);
+ table_size = le32_to_cpu(hdr->jt_size);
+ } else if (me == 2) {
+ hdr = (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
+ fw_data = (const __le32 *)
+ (rdev->me_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ table_offset = le32_to_cpu(hdr->jt_offset);
+ table_size = le32_to_cpu(hdr->jt_size);
+ } else if (me == 3) {
+ hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data;
+ fw_data = (const __le32 *)
+ (rdev->mec_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ table_offset = le32_to_cpu(hdr->jt_offset);
+ table_size = le32_to_cpu(hdr->jt_size);
+ } else {
+ hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data;
+ fw_data = (const __le32 *)
+ (rdev->mec2_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ table_offset = le32_to_cpu(hdr->jt_offset);
+ table_size = le32_to_cpu(hdr->jt_size);
+ }
+
+ for (i = 0; i < table_size; i ++) {
+ dst_ptr[bo_offset + i] =
+ cpu_to_le32(le32_to_cpu(fw_data[table_offset + i]));
+ }
+ bo_offset += table_size;
} else {
- fw_data = (const __be32 *)rdev->mec_fw->data;
- table_offset = CP_MEC_TABLE_OFFSET;
- }
+ const __be32 *fw_data;
+ table_size = CP_ME_TABLE_SIZE;
+
+ if (me == 0) {
+ fw_data = (const __be32 *)rdev->ce_fw->data;
+ table_offset = CP_ME_TABLE_OFFSET;
+ } else if (me == 1) {
+ fw_data = (const __be32 *)rdev->pfp_fw->data;
+ table_offset = CP_ME_TABLE_OFFSET;
+ } else if (me == 2) {
+ fw_data = (const __be32 *)rdev->me_fw->data;
+ table_offset = CP_ME_TABLE_OFFSET;
+ } else {
+ fw_data = (const __be32 *)rdev->mec_fw->data;
+ table_offset = CP_MEC_TABLE_OFFSET;
+ }
- for (i = 0; i < CP_ME_TABLE_SIZE; i ++) {
- dst_ptr[bo_offset + i] = cpu_to_le32(be32_to_cpu(fw_data[table_offset + i]));
+ for (i = 0; i < table_size; i ++) {
+ dst_ptr[bo_offset + i] =
+ cpu_to_le32(be32_to_cpu(fw_data[table_offset + i]));
+ }
+ bo_offset += table_size;
}
- bo_offset += CP_ME_TABLE_SIZE;
}
}
@@ -7376,6 +7736,7 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)
tmp = RREG32(IH_RB_CNTL);
tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp);
+ wptr &= ~RB_OVERFLOW;
}
return (wptr & rdev->ih.ptr_mask);
}
@@ -7616,7 +7977,8 @@ restart_ih:
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
- radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
+ if (radeon_use_pflipirq > 0)
+ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */
switch (src_data) {
@@ -7676,14 +8038,16 @@ restart_ih:
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
+ /* reset addr and status */
+ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+ if (addr == 0x0 && status == 0x0)
+ break;
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
addr);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
status);
cik_vm_decode_fault(rdev, status, addr, mc_client);
- /* reset addr and status */
- WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
break;
case 167: /* VCE */
DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data);
@@ -7896,6 +8260,7 @@ restart_ih:
static int cik_startup(struct radeon_device *rdev)
{
struct radeon_ring *ring;
+ u32 nop;
int r;
/* enable pcie gen2/3 link */
@@ -8029,9 +8394,18 @@ static int cik_startup(struct radeon_device *rdev)
}
cik_irq_set(rdev);
+ if (rdev->family == CHIP_HAWAII) {
+ if (rdev->new_fw)
+ nop = PACKET3(PACKET3_NOP, 0x3FFF);
+ else
+ nop = RADEON_CP_PACKET2;
+ } else {
+ nop = PACKET3(PACKET3_NOP, 0x3FFF);
+ }
+
ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
- PACKET3(PACKET3_NOP, 0x3FFF));
+ nop);
if (r)
return r;
@@ -8039,7 +8413,7 @@ static int cik_startup(struct radeon_device *rdev)
/* type-2 packets are deprecated on MEC, use type-3 instead */
ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
- PACKET3(PACKET3_NOP, 0x3FFF));
+ nop);
if (r)
return r;
ring->me = 1; /* first MEC */
@@ -8050,7 +8424,7 @@ static int cik_startup(struct radeon_device *rdev)
/* type-2 packets are deprecated on MEC, use type-3 instead */
ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
- PACKET3(PACKET3_NOP, 0x3FFF));
+ nop);
if (r)
return r;
/* dGPU only have 1 MEC */
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c
index 8e9d0f1d858e..bcf480510ac2 100644
--- a/drivers/gpu/drm/radeon/cik_sdma.c
+++ b/drivers/gpu/drm/radeon/cik_sdma.c
@@ -24,6 +24,7 @@
#include <linux/firmware.h>
#include <drm/drmP.h>
#include "radeon.h"
+#include "radeon_ucode.h"
#include "radeon_asic.h"
#include "radeon_trace.h"
#include "cikd.h"
@@ -118,6 +119,7 @@ void cik_sdma_set_wptr(struct radeon_device *rdev,
reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+ (void)RREG32(reg);
}
/**
@@ -419,7 +421,6 @@ static int cik_sdma_rlc_resume(struct radeon_device *rdev)
*/
static int cik_sdma_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
int i;
if (!rdev->sdma_fw)
@@ -428,19 +429,48 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev)
/* halt the MEs */
cik_sdma_enable(rdev, false);
- /* sdma0 */
- fw_data = (const __be32 *)rdev->sdma_fw->data;
- WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
- for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
- WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, be32_to_cpup(fw_data++));
- WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
-
- /* sdma1 */
- fw_data = (const __be32 *)rdev->sdma_fw->data;
- WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
- for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
- WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, be32_to_cpup(fw_data++));
- WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+ if (rdev->new_fw) {
+ const struct sdma_firmware_header_v1_0 *hdr =
+ (const struct sdma_firmware_header_v1_0 *)rdev->sdma_fw->data;
+ const __le32 *fw_data;
+ u32 fw_size;
+
+ radeon_ucode_print_sdma_hdr(&hdr->header);
+
+ /* sdma0 */
+ fw_data = (const __le32 *)
+ (rdev->sdma_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, le32_to_cpup(fw_data++));
+ WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+
+ /* sdma1 */
+ fw_data = (const __le32 *)
+ (rdev->sdma_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, le32_to_cpup(fw_data++));
+ WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+ } else {
+ const __be32 *fw_data;
+
+ /* sdma0 */
+ fw_data = (const __be32 *)rdev->sdma_fw->data;
+ WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
+ for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
+ WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, be32_to_cpup(fw_data++));
+ WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+
+ /* sdma1 */
+ fw_data = (const __be32 *)rdev->sdma_fw->data;
+ WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
+ for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
+ WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, be32_to_cpup(fw_data++));
+ WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+ }
WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
@@ -719,7 +749,43 @@ bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
}
/**
- * cik_sdma_vm_set_page - update the page tables using sDMA
+ * cik_sdma_vm_copy_pages - update PTEs by copying them from the GART
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @src: src addr to copy from
+ * @count: number of page entries to update
+ *
+ * Update PTEs by copying them from the GART using sDMA (CIK).
+ */
+void cik_sdma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count)
+{
+ while (count) {
+ unsigned bytes = count * 8;
+ if (bytes > 0x1FFFF8)
+ bytes = 0x1FFFF8;
+
+ ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY,
+ SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+ ib->ptr[ib->length_dw++] = bytes;
+ ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
+ ib->ptr[ib->length_dw++] = lower_32_bits(src);
+ ib->ptr[ib->length_dw++] = upper_32_bits(src);
+ ib->ptr[ib->length_dw++] = lower_32_bits(pe);
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+
+ pe += bytes;
+ src += bytes;
+ count -= bytes / 8;
+ }
+}
+
+/**
+ * cik_sdma_vm_write_pages - update PTEs by writing them manually
*
* @rdev: radeon_device pointer
* @ib: indirect buffer to fill with commands
@@ -729,84 +795,103 @@ bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
* @incr: increase next addr by incr bytes
* @flags: access flags
*
- * Update the page tables using sDMA (CIK).
+ * Update PTEs by writing them manually using sDMA (CIK).
*/
-void cik_sdma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags)
+void cik_sdma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
{
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if (flags == R600_PTE_GART) {
- uint64_t src = rdev->gart.table_addr + (addr >> 12) * 8;
- while (count) {
- unsigned bytes = count * 8;
- if (bytes > 0x1FFFF8)
- bytes = 0x1FFFF8;
-
- ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- ib->ptr[ib->length_dw++] = bytes;
- ib->ptr[ib->length_dw++] = 0; /* src/dst endian swap */
- ib->ptr[ib->length_dw++] = lower_32_bits(src);
- ib->ptr[ib->length_dw++] = upper_32_bits(src);
- ib->ptr[ib->length_dw++] = lower_32_bits(pe);
- ib->ptr[ib->length_dw++] = upper_32_bits(pe);
-
- pe += bytes;
- src += bytes;
- count -= bytes / 8;
- }
- } else if (flags & R600_PTE_SYSTEM) {
- while (count) {
- ndw = count * 2;
- if (ndw > 0xFFFFE)
- ndw = 0xFFFFE;
-
- /* for non-physically contiguous pages (system) */
- ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
- ib->ptr[ib->length_dw++] = pe;
- ib->ptr[ib->length_dw++] = upper_32_bits(pe);
- ib->ptr[ib->length_dw++] = ndw;
- for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ /* for non-physically contiguous pages (system) */
+ ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE,
+ SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+ ib->ptr[ib->length_dw++] = ndw;
+ for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ if (flags & R600_PTE_SYSTEM) {
value = radeon_vm_map_gart(rdev, addr);
value &= 0xFFFFFFFFFFFFF000ULL;
- addr += incr;
- value |= flags;
- ib->ptr[ib->length_dw++] = value;
- ib->ptr[ib->length_dw++] = upper_32_bits(value);
- }
- }
- } else {
- while (count) {
- ndw = count;
- if (ndw > 0x7FFFF)
- ndw = 0x7FFFF;
-
- if (flags & R600_PTE_VALID)
+ } else if (flags & R600_PTE_VALID) {
value = addr;
- else
+ } else {
value = 0;
- /* for physically contiguous pages (vram) */
- ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
- ib->ptr[ib->length_dw++] = pe; /* dst addr */
- ib->ptr[ib->length_dw++] = upper_32_bits(pe);
- ib->ptr[ib->length_dw++] = flags; /* mask */
- ib->ptr[ib->length_dw++] = 0;
- ib->ptr[ib->length_dw++] = value; /* value */
+ }
+ addr += incr;
+ value |= flags;
+ ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
- ib->ptr[ib->length_dw++] = incr; /* increment size */
- ib->ptr[ib->length_dw++] = 0;
- ib->ptr[ib->length_dw++] = ndw; /* number of entries */
- pe += ndw * 8;
- addr += ndw * incr;
- count -= ndw;
}
}
+}
+
+/**
+ * cik_sdma_vm_set_pages - update the page tables using sDMA
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using sDMA (CIK).
+ */
+void cik_sdma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint64_t value;
+ unsigned ndw;
+
+ while (count) {
+ ndw = count;
+ if (ndw > 0x7FFFF)
+ ndw = 0x7FFFF;
+
+ if (flags & R600_PTE_VALID)
+ value = addr;
+ else
+ value = 0;
+
+ /* for physically contiguous pages (vram) */
+ ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
+ ib->ptr[ib->length_dw++] = pe; /* dst addr */
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+ ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = 0;
+ ib->ptr[ib->length_dw++] = value; /* value */
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ ib->ptr[ib->length_dw++] = incr; /* increment size */
+ ib->ptr[ib->length_dw++] = 0;
+ ib->ptr[ib->length_dw++] = ndw; /* number of entries */
+
+ pe += ndw * 8;
+ addr += ndw * incr;
+ count -= ndw;
+ }
+}
+
+/**
+ * cik_sdma_vm_pad_ib - pad the IB to the required number of dw
+ *
+ * @ib: indirect buffer to fill with padding
+ *
+ */
+void cik_sdma_vm_pad_ib(struct radeon_ib *ib)
+{
while (ib->length_dw & 0x7)
ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0);
}
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index ae88660f34ea..0c6e1b55d968 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -1752,12 +1752,12 @@
#define EOP_TC_WB_ACTION_EN (1 << 15) /* L2 */
#define EOP_TCL1_ACTION_EN (1 << 16)
#define EOP_TC_ACTION_EN (1 << 17) /* L2 */
+#define EOP_TCL2_VOLATILE (1 << 24)
#define EOP_CACHE_POLICY(x) ((x) << 25)
/* 0 - LRU
* 1 - Stream
* 2 - Bypass
*/
-#define EOP_TCL2_VOLATILE (1 << 27)
#define DATA_SEL(x) ((x) << 29)
/* 0 - discard
* 1 - send low 32bit data
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
index 5a9a5f4d7888..47d31e915758 100644
--- a/drivers/gpu/drm/radeon/cypress_dpm.c
+++ b/drivers/gpu/drm/radeon/cypress_dpm.c
@@ -1551,7 +1551,7 @@ int cypress_populate_smc_voltage_tables(struct radeon_device *rdev,
table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDCI] = 0;
table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDCI] =
- cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+ cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
}
return 0;
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
index 0a65dc7e93e7..ab29f953a767 100644
--- a/drivers/gpu/drm/radeon/dce6_afmt.c
+++ b/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -136,13 +136,13 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
AUDIO_LIPSYNC(connector->audio_latency[1]);
else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
+ tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
} else {
if (connector->latency_present[0])
tmp = VIDEO_LIPSYNC(connector->video_latency[0]) |
AUDIO_LIPSYNC(connector->audio_latency[0]);
else
- tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255);
+ tmp = VIDEO_LIPSYNC(0) | AUDIO_LIPSYNC(0);
}
WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp);
}
@@ -164,8 +164,10 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
offset = dig->afmt->pin->offset;
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder)
+ if (connector->encoder == encoder) {
radeon_connector = to_radeon_connector(connector);
+ break;
+ }
}
if (!radeon_connector) {
@@ -173,7 +175,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
+ sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
if (sad_count <= 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
return;
@@ -225,8 +227,10 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
offset = dig->afmt->pin->offset;
list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) {
- if (connector->encoder == encoder)
+ if (connector->encoder == encoder) {
radeon_connector = to_radeon_connector(connector);
+ break;
+ }
}
if (!radeon_connector) {
@@ -234,7 +238,7 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
+ sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
if (sad_count <= 0) {
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
return;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index e2f605224e8c..4fedd14e670a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -189,7 +189,7 @@ static const u32 evergreen_golden_registers[] =
0x8c1c, 0xffffffff, 0x00001010,
0x28350, 0xffffffff, 0x00000000,
0xa008, 0xffffffff, 0x00010000,
- 0x5cc, 0xffffffff, 0x00000001,
+ 0x5c4, 0xffffffff, 0x00000001,
0x9508, 0xffffffff, 0x00000002,
0x913c, 0x0000000f, 0x0000000a
};
@@ -476,7 +476,7 @@ static const u32 cedar_golden_registers[] =
0x8c1c, 0xffffffff, 0x00001010,
0x28350, 0xffffffff, 0x00000000,
0xa008, 0xffffffff, 0x00010000,
- 0x5cc, 0xffffffff, 0x00000001,
+ 0x5c4, 0xffffffff, 0x00000001,
0x9508, 0xffffffff, 0x00000002
};
@@ -635,7 +635,7 @@ static const u32 juniper_mgcg_init[] =
static const u32 supersumo_golden_registers[] =
{
0x5eb4, 0xffffffff, 0x00000002,
- 0x5cc, 0xffffffff, 0x00000001,
+ 0x5c4, 0xffffffff, 0x00000001,
0x7030, 0xffffffff, 0x00000011,
0x7c30, 0xffffffff, 0x00000011,
0x6104, 0x01000300, 0x00000000,
@@ -719,7 +719,7 @@ static const u32 sumo_golden_registers[] =
static const u32 wrestler_golden_registers[] =
{
0x5eb4, 0xffffffff, 0x00000002,
- 0x5cc, 0xffffffff, 0x00000001,
+ 0x5c4, 0xffffffff, 0x00000001,
0x7030, 0xffffffff, 0x00000011,
0x7c30, 0xffffffff, 0x00000011,
0x6104, 0x01000300, 0x00000000,
@@ -2424,7 +2424,6 @@ static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup L2 cache */
WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
@@ -2642,8 +2641,9 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
for (i = 0; i < rdev->num_crtc; i++) {
if (save->crtc_enabled[i]) {
tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x3) != 0) {
- tmp &= ~0x3;
+ if ((tmp & 0x7) != 3) {
+ tmp &= ~0x7;
+ tmp |= 0x3;
WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
}
tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
@@ -2676,7 +2676,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
if (save->crtc_enabled[i]) {
if (ASIC_IS_DCE6(rdev)) {
tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ tmp &= ~EVERGREEN_CRTC_BLANK_DATA_EN;
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
@@ -4022,7 +4022,8 @@ int sumo_rlc_init(struct radeon_device *rdev)
/* save restore block */
if (rdev->rlc.save_restore_obj == NULL) {
r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.save_restore_obj);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL,
+ &rdev->rlc.save_restore_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
return r;
@@ -4100,7 +4101,8 @@ int sumo_rlc_init(struct radeon_device *rdev)
if (rdev->rlc.clear_state_obj == NULL) {
r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL,
+ &rdev->rlc.clear_state_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
sumo_rlc_fini(rdev);
@@ -4174,8 +4176,10 @@ int sumo_rlc_init(struct radeon_device *rdev)
if (rdev->rlc.cp_table_size) {
if (rdev->rlc.cp_table_obj == NULL) {
- r = radeon_bo_create(rdev, rdev->rlc.cp_table_size, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.cp_table_obj);
+ r = radeon_bo_create(rdev, rdev->rlc.cp_table_size,
+ PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL,
+ &rdev->rlc.cp_table_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r);
sumo_rlc_fini(rdev);
@@ -4755,6 +4759,7 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
tmp = RREG32(IH_RB_CNTL);
tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp);
+ wptr &= ~RB_OVERFLOW;
}
return (wptr & rdev->ih.ptr_mask);
}
@@ -4959,7 +4964,8 @@ restart_ih:
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
- radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
+ if (radeon_use_pflipirq > 0)
+ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */
switch (src_data) {
@@ -5066,14 +5072,16 @@ restart_ih:
case 147:
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
+ /* reset addr and status */
+ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+ if (addr == 0x0 && status == 0x0)
+ break;
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
addr);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
status);
cayman_vm_decode_fault(rdev, status, addr);
- /* reset addr and status */
- WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
break;
case 176: /* CP_INT in ring buffer */
case 177: /* CP_INT in IB1 */
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index 1ec0e6e83f9f..278c7a139d74 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -117,7 +117,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb);
+ sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb);
if (sad_count <= 0) {
DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count);
return;
@@ -172,7 +172,7 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder)
return;
}
- sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
+ sad_count = drm_edid_to_sad(radeon_connector_edid(connector), &sads);
if (sad_count <= 0) {
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
return;
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 333d143fca2c..23bff590fb6e 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -239,7 +239,6 @@
# define EVERGREEN_CRTC_V_BLANK (1 << 0)
#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90
#define EVERGREEN_CRTC_STATUS_HV_COUNT 0x6ea0
-#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4
#define EVERGREEN_MASTER_UPDATE_LOCK 0x6ef4
#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c
index 3f6e817d97ee..9ef8c38f2d66 100644
--- a/drivers/gpu/drm/radeon/kv_dpm.c
+++ b/drivers/gpu/drm/radeon/kv_dpm.c
@@ -2726,7 +2726,7 @@ int kv_dpm_init(struct radeon_device *rdev)
pi->caps_sclk_ds = true;
pi->enable_auto_thermal_throttling = true;
pi->disable_nb_ps3_in_battery = false;
- pi->bapm_enable = false;
+ pi->bapm_enable = true;
pi->voltage_drop_t = 0;
pi->caps_sclk_throttle_low_notification = false;
pi->caps_fps = false; /* true? */
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 5a33ca681867..327b85f7fd0d 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1229,7 +1229,6 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup TLB control */
WREG32(MC_VM_MX_L1_TLB_CNTL,
(0xA << 7) |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c
index 6378e0276691..8a3e6221cece 100644
--- a/drivers/gpu/drm/radeon/ni_dma.c
+++ b/drivers/gpu/drm/radeon/ni_dma.c
@@ -307,7 +307,43 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
}
/**
- * cayman_dma_vm_set_page - update the page tables using the DMA
+ * cayman_dma_vm_copy_pages - update PTEs by copying them from the GART
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @src: src addr where to copy from
+ * @count: number of page entries to update
+ *
+ * Update PTEs by copying them from the GART using the DMA (cayman/TN).
+ */
+void cayman_dma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count)
+{
+ unsigned ndw;
+
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
+ 0, 0, ndw);
+ ib->ptr[ib->length_dw++] = lower_32_bits(pe);
+ ib->ptr[ib->length_dw++] = lower_32_bits(src);
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ ib->ptr[ib->length_dw++] = upper_32_bits(src) & 0xff;
+
+ pe += ndw * 4;
+ src += ndw * 4;
+ count -= ndw / 2;
+ }
+}
+
+/**
+ * cayman_dma_vm_write_pages - update PTEs by writing them manually
*
* @rdev: radeon_device pointer
* @ib: indirect buffer to fill with commands
@@ -315,71 +351,103 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
* @addr: dst addr to write into pe
* @count: number of page entries to update
* @incr: increase next addr by incr bytes
- * @flags: hw access flags
+ * @flags: hw access flags
*
- * Update the page tables using the DMA (cayman/TN).
+ * Update PTEs by writing them manually using the DMA (cayman/TN).
*/
-void cayman_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags)
+void cayman_dma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
{
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if ((flags & R600_PTE_SYSTEM) || (count == 1)) {
- while (count) {
- ndw = count * 2;
- if (ndw > 0xFFFFE)
- ndw = 0xFFFFE;
-
- /* for non-physically contiguous pages (system) */
- ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
- ib->ptr[ib->length_dw++] = pe;
- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- for (; ndw > 0; ndw -= 2, --count, pe += 8) {
- if (flags & R600_PTE_SYSTEM) {
- value = radeon_vm_map_gart(rdev, addr);
- value &= 0xFFFFFFFFFFFFF000ULL;
- } else if (flags & R600_PTE_VALID) {
- value = addr;
- } else {
- value = 0;
- }
- addr += incr;
- value |= flags;
- ib->ptr[ib->length_dw++] = value;
- ib->ptr[ib->length_dw++] = upper_32_bits(value);
- }
- }
- } else {
- while (count) {
- ndw = count * 2;
- if (ndw > 0xFFFFE)
- ndw = 0xFFFFE;
-
- if (flags & R600_PTE_VALID)
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ /* for non-physically contiguous pages (system) */
+ ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE,
+ 0, 0, ndw);
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ if (flags & R600_PTE_SYSTEM) {
+ value = radeon_vm_map_gart(rdev, addr);
+ value &= 0xFFFFFFFFFFFFF000ULL;
+ } else if (flags & R600_PTE_VALID) {
value = addr;
- else
+ } else {
value = 0;
- /* for physically contiguous pages (vram) */
- ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
- ib->ptr[ib->length_dw++] = pe; /* dst addr */
- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- ib->ptr[ib->length_dw++] = flags; /* mask */
- ib->ptr[ib->length_dw++] = 0;
- ib->ptr[ib->length_dw++] = value; /* value */
+ }
+ addr += incr;
+ value |= flags;
+ ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
- ib->ptr[ib->length_dw++] = incr; /* increment size */
- ib->ptr[ib->length_dw++] = 0;
- pe += ndw * 4;
- addr += (ndw / 2) * incr;
- count -= ndw / 2;
}
}
+}
+
+/**
+ * cayman_dma_vm_set_pages - update the page tables using the DMA
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: hw access flags
+ *
+ * Update the page tables using the DMA (cayman/TN).
+ */
+void cayman_dma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint64_t value;
+ unsigned ndw;
+
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ if (flags & R600_PTE_VALID)
+ value = addr;
+ else
+ value = 0;
+
+ /* for physically contiguous pages (vram) */
+ ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
+ ib->ptr[ib->length_dw++] = pe; /* dst addr */
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = 0;
+ ib->ptr[ib->length_dw++] = value; /* value */
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ ib->ptr[ib->length_dw++] = incr; /* increment size */
+ ib->ptr[ib->length_dw++] = 0;
+
+ pe += ndw * 4;
+ addr += (ndw / 2) * incr;
+ count -= ndw / 2;
+ }
+}
+
+/**
+ * cayman_dma_vm_pad_ib - pad the IB to the required number of dw
+ *
+ * @ib: indirect buffer to fill with padding
+ *
+ */
+void cayman_dma_vm_pad_ib(struct radeon_ib *ib)
+{
while (ib->length_dw & 0x7)
ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
}
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
index 004c931606c4..01fc4888e6fe 100644
--- a/drivers/gpu/drm/radeon/ni_dpm.c
+++ b/drivers/gpu/drm/radeon/ni_dpm.c
@@ -1315,7 +1315,7 @@ static void ni_populate_smc_voltage_tables(struct radeon_device *rdev,
table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = 0;
table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] =
- cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+ cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
}
}
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 1544efcf1c3a..04b5940b8923 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -652,7 +652,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev)
{
uint32_t tmp;
- radeon_gart_restore(rdev);
/* discard memory request outside of configured range */
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
WREG32(RADEON_AIC_CNTL, tmp);
@@ -683,7 +682,7 @@ void r100_pci_gart_disable(struct radeon_device *rdev)
}
void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr)
+ uint64_t addr, uint32_t flags)
{
u32 *gtt = rdev->gart.ptr;
gtt[i] = cpu_to_le32(lower_32_bits(addr));
@@ -838,11 +837,7 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
/* Wait until IDLE & CLEAN */
radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0));
radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
- radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
- radeon_ring_write(ring, rdev->config.r100.hdp_cntl |
- RADEON_HDP_READ_BUFFER_INVALIDATE);
- radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
- radeon_ring_write(ring, rdev->config.r100.hdp_cntl);
+ r100_ring_hdp_flush(rdev, ring);
/* Emit fence sequence & fire IRQ */
radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0));
radeon_ring_write(ring, fence->seq);
@@ -1061,6 +1056,20 @@ void r100_gfx_set_wptr(struct radeon_device *rdev,
(void)RREG32(RADEON_CP_RB_WPTR);
}
+/**
+ * r100_ring_hdp_flush - flush Host Data Path via the ring buffer
+ * rdev: radeon device structure
+ * ring: ring buffer struct for emitting packets
+ */
+void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+ radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+ radeon_ring_write(ring, rdev->config.r100.hdp_cntl |
+ RADEON_HDP_READ_BUFFER_INVALIDATE);
+ radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0));
+ radeon_ring_write(ring, rdev->config.r100.hdp_cntl);
+}
+
static void r100_cp_load_microcode(struct radeon_device *rdev)
{
const __be32 *fw_data;
@@ -1401,7 +1410,6 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p,
*/
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
{
- struct drm_mode_object *obj;
struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
struct radeon_cs_packet p3reloc, waitreloc;
@@ -1441,12 +1449,11 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 5);
reg = R100_CP_PACKET0_GET_REG(header);
- obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
- if (!obj) {
+ crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
}
- crtc = obj_to_crtc(obj);
radeon_crtc = to_radeon_crtc(crtc);
crtc_id = radeon_crtc->crtc_id;
@@ -4067,39 +4074,6 @@ int r100_init(struct radeon_device *rdev)
return 0;
}
-uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg,
- bool always_indirect)
-{
- if (reg < rdev->rmmio_size && !always_indirect)
- return readl(((void __iomem *)rdev->rmmio) + reg);
- else {
- unsigned long flags;
- uint32_t ret;
-
- spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
- writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
- ret = readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
- spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
-
- return ret;
- }
-}
-
-void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
- bool always_indirect)
-{
- if (reg < rdev->rmmio_size && !always_indirect)
- writel(v, ((void __iomem *)rdev->rmmio) + reg);
- else {
- unsigned long flags;
-
- spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
- writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
- writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
- spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
- }
-}
-
u32 r100_io_rreg(struct radeon_device *rdev, u32 reg)
{
if (reg < rdev->rio_mem_size)
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 3c21d77a483d..75b30338c226 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -69,17 +69,23 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
mb();
}
+#define R300_PTE_UNSNOOPED (1 << 0)
#define R300_PTE_WRITEABLE (1 << 2)
#define R300_PTE_READABLE (1 << 3)
void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr)
+ uint64_t addr, uint32_t flags)
{
void __iomem *ptr = rdev->gart.ptr;
addr = (lower_32_bits(addr) >> 8) |
- ((upper_32_bits(addr) & 0xff) << 24) |
- R300_PTE_WRITEABLE | R300_PTE_READABLE;
+ ((upper_32_bits(addr) & 0xff) << 24);
+ if (flags & RADEON_GART_PAGE_READ)
+ addr |= R300_PTE_READABLE;
+ if (flags & RADEON_GART_PAGE_WRITE)
+ addr |= R300_PTE_WRITEABLE;
+ if (!(flags & RADEON_GART_PAGE_SNOOP))
+ addr |= R300_PTE_UNSNOOPED;
/* on x86 we want this to be CPU endian, on powerpc
* on powerpc without HW swappers, it'll get swapped on way
* into VRAM - so no need for cpu_to_le32 on VRAM tables */
@@ -120,7 +126,6 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* discard memory request outside of configured range */
tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c66952d4b00c..c70a504d96af 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -968,7 +968,6 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup L2 cache */
WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
@@ -1339,7 +1338,7 @@ int r600_vram_scratch_init(struct radeon_device *rdev)
if (rdev->vram_scratch.robj == NULL) {
r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
- NULL, &rdev->vram_scratch.robj);
+ 0, NULL, &rdev->vram_scratch.robj);
if (r) {
return r;
}
@@ -3227,7 +3226,7 @@ int r600_ih_ring_alloc(struct radeon_device *rdev)
if (rdev->ih.ring_obj == NULL) {
r = radeon_bo_create(rdev, rdev->ih.ring_size,
PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_GTT,
+ RADEON_GEM_DOMAIN_GTT, 0,
NULL, &rdev->ih.ring_obj);
if (r) {
DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
@@ -3795,6 +3794,7 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev)
tmp = RREG32(IH_RB_CNTL);
tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp);
+ wptr &= ~RB_OVERFLOW;
}
return (wptr & rdev->ih.ptr_mask);
}
@@ -3923,11 +3923,13 @@ restart_ih:
break;
case 9: /* D1 pflip */
DRM_DEBUG("IH: D1 flip\n");
- radeon_crtc_handle_flip(rdev, 0);
+ if (radeon_use_pflipirq > 0)
+ radeon_crtc_handle_flip(rdev, 0);
break;
case 11: /* D2 pflip */
DRM_DEBUG("IH: D2 flip\n");
- radeon_crtc_handle_flip(rdev, 1);
+ if (radeon_use_pflipirq > 0)
+ radeon_crtc_handle_flip(rdev, 1);
break;
case 19: /* HPD/DAC hotplug */
switch (src_data) {
@@ -4088,16 +4090,15 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
}
/**
- * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl
+ * r600_mmio_hdp_flush - flush Host Data Path cache via MMIO
* rdev: radeon device structure
- * bo: buffer object struct which userspace is waiting for idle
*
- * Some R6XX/R7XX doesn't seems to take into account HDP flush performed
- * through ring buffer, this leads to corruption in rendering, see
- * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we
- * directly perform HDP flush by writing register through MMIO.
+ * Some R6XX/R7XX don't seem to take into account HDP flushes performed
+ * through the ring buffer. This leads to corruption in rendering, see
+ * http://bugzilla.kernel.org/show_bug.cgi?id=15186 . To avoid this, we
+ * directly perform the HDP flush by writing the register through MMIO.
*/
-void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
+void r600_mmio_hdp_flush(struct radeon_device *rdev)
{
/* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
* rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 12511bb5fd6f..c47537a1ddba 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -825,7 +825,6 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
uint32_t *vline_start_end,
uint32_t *vline_status)
{
- struct drm_mode_object *obj;
struct drm_crtc *crtc;
struct radeon_crtc *radeon_crtc;
struct radeon_cs_packet p3reloc, wait_reg_mem;
@@ -887,12 +886,11 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
reg = R600_CP_PACKET0_GET_REG(header);
- obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
- if (!obj) {
+ crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
}
- crtc = obj_to_crtc(obj);
radeon_crtc = to_radeon_crtc(crtc);
crtc_id = radeon_crtc->crtc_id;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4b0bbf88d5c0..9e1732eb402c 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -64,6 +64,7 @@
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/kref.h>
+#include <linux/interval_tree.h>
#include <ttm/ttm_bo_api.h>
#include <ttm/ttm_bo_driver.h>
@@ -102,6 +103,8 @@ extern int radeon_runtime_pm;
extern int radeon_hard_reset;
extern int radeon_vm_size;
extern int radeon_vm_block_size;
+extern int radeon_deep_color;
+extern int radeon_use_pflipirq;
/*
* Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -303,6 +306,9 @@ int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *r
u16 *vddc, u16 *vddci,
u16 virtual_voltage_id,
u16 vbios_voltage_id);
+int radeon_atom_get_voltage_evv(struct radeon_device *rdev,
+ u16 virtual_voltage_id,
+ u16 *voltage);
int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
u8 voltage_type,
u16 nominal_voltage,
@@ -316,6 +322,9 @@ int radeon_atom_get_voltage_table(struct radeon_device *rdev,
struct atom_voltage_table *voltage_table);
bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
u8 voltage_type, u8 voltage_mode);
+int radeon_atom_get_svi2_info(struct radeon_device *rdev,
+ u8 voltage_type,
+ u8 *svd_gpio_id, u8 *svc_gpio_id);
void radeon_atom_update_memory_dll(struct radeon_device *rdev,
u32 mem_clock);
void radeon_atom_set_ac_timing(struct radeon_device *rdev,
@@ -440,14 +449,13 @@ struct radeon_mman {
struct radeon_bo_va {
/* protected by bo being reserved */
struct list_head bo_list;
- uint64_t soffset;
- uint64_t eoffset;
uint32_t flags;
- bool valid;
+ uint64_t addr;
unsigned ref_count;
/* protected by vm mutex */
- struct list_head vm_list;
+ struct interval_tree_node it;
+ struct list_head vm_status;
/* constant after initialization */
struct radeon_vm *vm;
@@ -463,6 +471,7 @@ struct radeon_bo {
struct ttm_placement placement;
struct ttm_buffer_object tbo;
struct ttm_bo_kmap_obj kmap;
+ u32 flags;
unsigned pin_count;
void *kptr;
u32 tiling_flags;
@@ -541,9 +550,9 @@ struct radeon_gem {
int radeon_gem_init(struct radeon_device *rdev);
void radeon_gem_fini(struct radeon_device *rdev);
-int radeon_gem_object_create(struct radeon_device *rdev, int size,
+int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size,
int alignment, int initial_domain,
- bool discardable, bool kernel,
+ u32 flags, bool kernel,
struct drm_gem_object **obj);
int radeon_mode_dumb_create(struct drm_file *file_priv,
@@ -588,6 +597,12 @@ struct radeon_mc;
#define RADEON_GPU_PAGE_SHIFT 12
#define RADEON_GPU_PAGE_ALIGN(a) (((a) + RADEON_GPU_PAGE_MASK) & ~RADEON_GPU_PAGE_MASK)
+#define RADEON_GART_PAGE_DUMMY 0
+#define RADEON_GART_PAGE_VALID (1 << 0)
+#define RADEON_GART_PAGE_READ (1 << 1)
+#define RADEON_GART_PAGE_WRITE (1 << 2)
+#define RADEON_GART_PAGE_SNOOP (1 << 3)
+
struct radeon_gart {
dma_addr_t table_addr;
struct radeon_bo *robj;
@@ -612,8 +627,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
int pages);
int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
int pages, struct page **pagelist,
- dma_addr_t *dma_addr);
-void radeon_gart_restore(struct radeon_device *rdev);
+ dma_addr_t *dma_addr, uint32_t flags);
/*
@@ -683,10 +697,9 @@ struct radeon_flip_work {
struct work_struct unpin_work;
struct radeon_device *rdev;
int crtc_id;
- struct drm_framebuffer *fb;
+ uint64_t base;
struct drm_pending_vblank_event *event;
struct radeon_bo *old_rbo;
- struct radeon_bo *new_rbo;
struct radeon_fence *fence;
};
@@ -749,10 +762,6 @@ union radeon_irq_stat_regs {
struct cik_irq_stat_regs cik;
};
-#define RADEON_MAX_HPD_PINS 7
-#define RADEON_MAX_CRTCS 6
-#define RADEON_MAX_AFMT_BLOCKS 7
-
struct radeon_irq {
bool installed;
spinlock_t lock;
@@ -858,9 +867,9 @@ struct radeon_mec {
#define R600_PTE_FRAG_64KB (4 << 7)
#define R600_PTE_FRAG_256KB (6 << 7)
-/* flags used for GART page table entries on R600+ */
-#define R600_PTE_GART ( R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED \
- | R600_PTE_READABLE | R600_PTE_WRITEABLE)
+/* flags needed to be set so we can copy directly from the GART table */
+#define R600_PTE_GART_MASK ( R600_PTE_READABLE | R600_PTE_WRITEABLE | \
+ R600_PTE_SYSTEM | R600_PTE_VALID )
struct radeon_vm_pt {
struct radeon_bo *bo;
@@ -868,9 +877,15 @@ struct radeon_vm_pt {
};
struct radeon_vm {
- struct list_head va;
+ struct rb_root va;
unsigned id;
+ /* BOs moved, but not yet updated in the PT */
+ struct list_head invalidated;
+
+ /* BOs freed, but not yet updated in the PT */
+ struct list_head freed;
+
/* contains the page directory */
struct radeon_bo *page_directory;
uint64_t pd_gpu_addr;
@@ -879,6 +894,8 @@ struct radeon_vm {
/* array of page tables, one for each page directory entry */
struct radeon_vm_pt *page_tables;
+ struct radeon_bo_va *ib_bo_va;
+
struct mutex mutex;
/* last fence for cs using this vm */
struct radeon_fence *fence;
@@ -1738,6 +1755,7 @@ struct radeon_asic_ring {
/* command emmit functions */
void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence);
+ void (*hdp_flush)(struct radeon_device *rdev, struct radeon_ring *ring);
bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp,
struct radeon_semaphore *semaphore, bool emit_wait);
void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
@@ -1761,13 +1779,8 @@ struct radeon_asic {
int (*suspend)(struct radeon_device *rdev);
void (*vga_set_state)(struct radeon_device *rdev, bool state);
int (*asic_reset)(struct radeon_device *rdev);
- /* ioctl hw specific callback. Some hw might want to perform special
- * operation on specific ioctl. For instance on wait idle some hw
- * might want to perform and HDP flush through MMIO as it seems that
- * some R6XX/R7XX hw doesn't take HDP flush into account if programmed
- * through ring.
- */
- void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo);
+ /* Flush the HDP cache via MMIO */
+ void (*mmio_hdp_flush)(struct radeon_device *rdev);
/* check if 3D engine is idle */
bool (*gui_idle)(struct radeon_device *rdev);
/* wait for mc_idle */
@@ -1780,16 +1793,26 @@ struct radeon_asic {
struct {
void (*tlb_flush)(struct radeon_device *rdev);
void (*set_page)(struct radeon_device *rdev, unsigned i,
- uint64_t addr);
+ uint64_t addr, uint32_t flags);
} gart;
struct {
int (*init)(struct radeon_device *rdev);
void (*fini)(struct radeon_device *rdev);
- void (*set_page)(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
+ void (*copy_pages)(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count);
+ void (*write_pages)(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+ void (*set_pages)(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+ void (*pad_ib)(struct radeon_ib *ib);
} vm;
/* ring specific callbacks */
struct radeon_asic_ring *ring[RADEON_NUM_RINGS];
@@ -2297,10 +2320,12 @@ struct radeon_device {
const struct firmware *mc_fw; /* NI MC firmware */
const struct firmware *ce_fw; /* SI CE firmware */
const struct firmware *mec_fw; /* CIK MEC firmware */
+ const struct firmware *mec2_fw; /* KV MEC2 firmware */
const struct firmware *sdma_fw; /* CIK SDMA firmware */
const struct firmware *smc_fw; /* SMC firmware */
const struct firmware *uvd_fw; /* UVD firmware */
const struct firmware *vce_fw; /* VCE firmware */
+ bool new_fw;
struct r600_vram_scratch vram_scratch;
int msi_enabled; /* msi enabled */
struct r600_ih ih; /* r6/700 interrupt ring */
@@ -2340,6 +2365,11 @@ struct radeon_device {
struct dev_pm_domain vga_pm_domain;
bool have_disp_power_ref;
+ u32 px_quirk_flags;
+
+ /* tracking pinned memory */
+ u64 vram_pin_size;
+ u64 gart_pin_size;
};
bool radeon_is_px(struct drm_device *dev);
@@ -2350,10 +2380,42 @@ int radeon_device_init(struct radeon_device *rdev,
void radeon_device_fini(struct radeon_device *rdev);
int radeon_gpu_wait_for_idle(struct radeon_device *rdev);
-uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg,
- bool always_indirect);
-void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
- bool always_indirect);
+#define RADEON_MIN_MMIO_SIZE 0x10000
+
+static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg,
+ bool always_indirect)
+{
+ /* The mmio size is 64kb at minimum. Allows the if to be optimized out. */
+ if ((reg < rdev->rmmio_size || reg < RADEON_MIN_MMIO_SIZE) && !always_indirect)
+ return readl(((void __iomem *)rdev->rmmio) + reg);
+ else {
+ unsigned long flags;
+ uint32_t ret;
+
+ spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
+ writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
+ ret = readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
+ spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
+
+ return ret;
+ }
+}
+
+static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v,
+ bool always_indirect)
+{
+ if ((reg < rdev->rmmio_size || reg < RADEON_MIN_MMIO_SIZE) && !always_indirect)
+ writel(v, ((void __iomem *)rdev->rmmio) + reg);
+ else {
+ unsigned long flags;
+
+ spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
+ writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX);
+ writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA);
+ spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
+ }
+}
+
u32 r100_io_rreg(struct radeon_device *rdev, u32 reg);
void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v);
@@ -2707,10 +2769,13 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
-#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p))
+#define radeon_gart_set_page(rdev, i, p, f) (rdev)->asic->gart.set_page((rdev), (i), (p), (f))
#define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
#define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
-#define radeon_asic_vm_set_page(rdev, ib, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (ib), (pe), (addr), (count), (incr), (flags)))
+#define radeon_asic_vm_copy_pages(rdev, ib, pe, src, count) ((rdev)->asic->vm.copy_pages((rdev), (ib), (pe), (src), (count)))
+#define radeon_asic_vm_write_pages(rdev, ib, pe, addr, count, incr, flags) ((rdev)->asic->vm.write_pages((rdev), (ib), (pe), (addr), (count), (incr), (flags)))
+#define radeon_asic_vm_set_pages(rdev, ib, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_pages((rdev), (ib), (pe), (addr), (count), (incr), (flags)))
+#define radeon_asic_vm_pad_ib(rdev, ib) ((rdev)->asic->vm.pad_ib((ib)))
#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)]->ring_start((rdev), (cp))
#define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)]->ring_test((rdev), (cp))
#define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)]->ib_test((rdev), (cp))
@@ -2836,9 +2901,12 @@ void radeon_vm_fence(struct radeon_device *rdev,
uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
int radeon_vm_update_page_directory(struct radeon_device *rdev,
struct radeon_vm *vm);
+int radeon_vm_clear_freed(struct radeon_device *rdev,
+ struct radeon_vm *vm);
+int radeon_vm_clear_invalids(struct radeon_device *rdev,
+ struct radeon_vm *vm);
int radeon_vm_bo_update(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
+ struct radeon_bo_va *bo_va,
struct ttm_mem_reg *mem);
void radeon_vm_bo_invalidate(struct radeon_device *rdev,
struct radeon_bo *bo);
@@ -2851,8 +2919,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
struct radeon_bo_va *bo_va,
uint64_t offset,
uint32_t flags);
-int radeon_vm_bo_rmv(struct radeon_device *rdev,
- struct radeon_bo_va *bo_va);
+void radeon_vm_bo_rmv(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va);
/* audio */
void r600_audio_update_hdmi(struct work_struct *work);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 34b9aa9e3c06..eeeeabe09758 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -185,6 +185,7 @@ static struct radeon_asic_ring r100_gfx_ring = {
.get_rptr = &r100_gfx_get_rptr,
.get_wptr = &r100_gfx_get_wptr,
.set_wptr = &r100_gfx_set_wptr,
+ .hdp_flush = &r100_ring_hdp_flush,
};
static struct radeon_asic r100_asic = {
@@ -194,7 +195,7 @@ static struct radeon_asic r100_asic = {
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r100_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r100_mc_wait_for_idle,
.gart = {
@@ -260,7 +261,7 @@ static struct radeon_asic r200_asic = {
.resume = &r100_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r100_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r100_mc_wait_for_idle,
.gart = {
@@ -331,6 +332,7 @@ static struct radeon_asic_ring r300_gfx_ring = {
.get_rptr = &r100_gfx_get_rptr,
.get_wptr = &r100_gfx_get_wptr,
.set_wptr = &r100_gfx_set_wptr,
+ .hdp_flush = &r100_ring_hdp_flush,
};
static struct radeon_asic r300_asic = {
@@ -340,7 +342,7 @@ static struct radeon_asic r300_asic = {
.resume = &r300_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r300_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r300_mc_wait_for_idle,
.gart = {
@@ -406,7 +408,7 @@ static struct radeon_asic r300_asic_pcie = {
.resume = &r300_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r300_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r300_mc_wait_for_idle,
.gart = {
@@ -472,7 +474,7 @@ static struct radeon_asic r420_asic = {
.resume = &r420_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r300_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r300_mc_wait_for_idle,
.gart = {
@@ -538,7 +540,7 @@ static struct radeon_asic rs400_asic = {
.resume = &rs400_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &r300_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &rs400_mc_wait_for_idle,
.gart = {
@@ -604,7 +606,7 @@ static struct radeon_asic rs600_asic = {
.resume = &rs600_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &rs600_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &rs600_mc_wait_for_idle,
.gart = {
@@ -672,7 +674,7 @@ static struct radeon_asic rs690_asic = {
.resume = &rs690_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &rs600_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &rs690_mc_wait_for_idle,
.gart = {
@@ -740,7 +742,7 @@ static struct radeon_asic rv515_asic = {
.resume = &rv515_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &rs600_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &rv515_mc_wait_for_idle,
.gart = {
@@ -806,7 +808,7 @@ static struct radeon_asic r520_asic = {
.resume = &r520_resume,
.vga_set_state = &r100_vga_set_state,
.asic_reset = &rs600_asic_reset,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = NULL,
.gui_idle = &r100_gui_idle,
.mc_wait_for_idle = &r520_mc_wait_for_idle,
.gart = {
@@ -898,7 +900,7 @@ static struct radeon_asic r600_asic = {
.resume = &r600_resume,
.vga_set_state = &r600_vga_set_state,
.asic_reset = &r600_asic_reset,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
@@ -970,7 +972,7 @@ static struct radeon_asic rv6xx_asic = {
.resume = &r600_resume,
.vga_set_state = &r600_vga_set_state,
.asic_reset = &r600_asic_reset,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
@@ -1060,7 +1062,7 @@ static struct radeon_asic rs780_asic = {
.resume = &r600_resume,
.vga_set_state = &r600_vga_set_state,
.asic_reset = &r600_asic_reset,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
@@ -1163,7 +1165,7 @@ static struct radeon_asic rv770_asic = {
.resume = &rv770_resume,
.asic_reset = &r600_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &r600_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
@@ -1281,7 +1283,7 @@ static struct radeon_asic evergreen_asic = {
.resume = &evergreen_resume,
.asic_reset = &evergreen_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
@@ -1373,7 +1375,7 @@ static struct radeon_asic sumo_asic = {
.resume = &evergreen_resume,
.asic_reset = &evergreen_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
@@ -1464,7 +1466,7 @@ static struct radeon_asic btc_asic = {
.resume = &evergreen_resume,
.asic_reset = &evergreen_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
@@ -1599,7 +1601,7 @@ static struct radeon_asic cayman_asic = {
.resume = &cayman_resume,
.asic_reset = &cayman_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &rv770_get_xclk,
@@ -1611,7 +1613,10 @@ static struct radeon_asic cayman_asic = {
.vm = {
.init = &cayman_vm_init,
.fini = &cayman_vm_fini,
- .set_page = &cayman_dma_vm_set_page,
+ .copy_pages = &cayman_dma_vm_copy_pages,
+ .write_pages = &cayman_dma_vm_write_pages,
+ .set_pages = &cayman_dma_vm_set_pages,
+ .pad_ib = &cayman_dma_vm_pad_ib,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring,
@@ -1699,7 +1704,7 @@ static struct radeon_asic trinity_asic = {
.resume = &cayman_resume,
.asic_reset = &cayman_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &r600_get_xclk,
@@ -1711,7 +1716,10 @@ static struct radeon_asic trinity_asic = {
.vm = {
.init = &cayman_vm_init,
.fini = &cayman_vm_fini,
- .set_page = &cayman_dma_vm_set_page,
+ .copy_pages = &cayman_dma_vm_copy_pages,
+ .write_pages = &cayman_dma_vm_write_pages,
+ .set_pages = &cayman_dma_vm_set_pages,
+ .pad_ib = &cayman_dma_vm_pad_ib,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring,
@@ -1829,7 +1837,7 @@ static struct radeon_asic si_asic = {
.resume = &si_resume,
.asic_reset = &si_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = r600_ioctl_wait_idle,
+ .mmio_hdp_flush = r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &si_get_xclk,
@@ -1841,7 +1849,10 @@ static struct radeon_asic si_asic = {
.vm = {
.init = &si_vm_init,
.fini = &si_vm_fini,
- .set_page = &si_dma_vm_set_page,
+ .copy_pages = &si_dma_vm_copy_pages,
+ .write_pages = &si_dma_vm_write_pages,
+ .set_pages = &si_dma_vm_set_pages,
+ .pad_ib = &cayman_dma_vm_pad_ib,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &si_gfx_ring,
@@ -1987,7 +1998,7 @@ static struct radeon_asic ci_asic = {
.resume = &cik_resume,
.asic_reset = &cik_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = &r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &cik_get_xclk,
@@ -1999,7 +2010,10 @@ static struct radeon_asic ci_asic = {
.vm = {
.init = &cik_vm_init,
.fini = &cik_vm_fini,
- .set_page = &cik_sdma_vm_set_page,
+ .copy_pages = &cik_sdma_vm_copy_pages,
+ .write_pages = &cik_sdma_vm_write_pages,
+ .set_pages = &cik_sdma_vm_set_pages,
+ .pad_ib = &cik_sdma_vm_pad_ib,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring,
@@ -2091,7 +2105,7 @@ static struct radeon_asic kv_asic = {
.resume = &cik_resume,
.asic_reset = &cik_asic_reset,
.vga_set_state = &r600_vga_set_state,
- .ioctl_wait_idle = NULL,
+ .mmio_hdp_flush = &r600_mmio_hdp_flush,
.gui_idle = &r600_gui_idle,
.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
.get_xclk = &cik_get_xclk,
@@ -2103,7 +2117,10 @@ static struct radeon_asic kv_asic = {
.vm = {
.init = &cik_vm_init,
.fini = &cik_vm_fini,
- .set_page = &cik_sdma_vm_set_page,
+ .copy_pages = &cik_sdma_vm_copy_pages,
+ .write_pages = &cik_sdma_vm_write_pages,
+ .set_pages = &cik_sdma_vm_set_pages,
+ .pad_ib = &cik_sdma_vm_pad_ib,
},
.ring = {
[RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring,
@@ -2457,7 +2474,7 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->cg_flags =
RADEON_CG_SUPPORT_GFX_MGCG |
RADEON_CG_SUPPORT_GFX_MGLS |
- RADEON_CG_SUPPORT_GFX_CGCG |
+ /*RADEON_CG_SUPPORT_GFX_CGCG |*/
RADEON_CG_SUPPORT_GFX_CGLS |
RADEON_CG_SUPPORT_GFX_CGTS |
RADEON_CG_SUPPORT_GFX_CGTS_LS |
@@ -2476,7 +2493,7 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->cg_flags =
RADEON_CG_SUPPORT_GFX_MGCG |
RADEON_CG_SUPPORT_GFX_MGLS |
- RADEON_CG_SUPPORT_GFX_CGCG |
+ /*RADEON_CG_SUPPORT_GFX_CGCG |*/
RADEON_CG_SUPPORT_GFX_CGLS |
RADEON_CG_SUPPORT_GFX_CGTS |
RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2502,7 +2519,7 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->cg_flags =
RADEON_CG_SUPPORT_GFX_MGCG |
RADEON_CG_SUPPORT_GFX_MGLS |
- RADEON_CG_SUPPORT_GFX_CGCG |
+ /*RADEON_CG_SUPPORT_GFX_CGCG |*/
RADEON_CG_SUPPORT_GFX_CGLS |
RADEON_CG_SUPPORT_GFX_CGTS |
RADEON_CG_SUPPORT_GFX_CGTS_LS |
@@ -2530,7 +2547,7 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->cg_flags =
RADEON_CG_SUPPORT_GFX_MGCG |
RADEON_CG_SUPPORT_GFX_MGLS |
- RADEON_CG_SUPPORT_GFX_CGCG |
+ /*RADEON_CG_SUPPORT_GFX_CGCG |*/
RADEON_CG_SUPPORT_GFX_CGLS |
RADEON_CG_SUPPORT_GFX_CGTS |
RADEON_CG_SUPPORT_GFX_CGTS_LS |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 01e7c0ad8f01..275a5dc01780 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -68,7 +68,7 @@ int r100_asic_reset(struct radeon_device *rdev);
u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr);
+ uint64_t addr, uint32_t flags);
void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring);
int r100_irq_set(struct radeon_device *rdev);
int r100_irq_process(struct radeon_device *rdev);
@@ -148,7 +148,8 @@ u32 r100_gfx_get_wptr(struct radeon_device *rdev,
struct radeon_ring *ring);
void r100_gfx_set_wptr(struct radeon_device *rdev,
struct radeon_ring *ring);
-
+void r100_ring_hdp_flush(struct radeon_device *rdev,
+ struct radeon_ring *ring);
/*
* r200,rv250,rs300,rv280
*/
@@ -173,7 +174,7 @@ extern void r300_fence_ring_emit(struct radeon_device *rdev,
extern int r300_cs_parse(struct radeon_cs_parser *p);
extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr);
+ uint64_t addr, uint32_t flags);
extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
extern void r300_set_reg_safe(struct radeon_device *rdev);
@@ -209,7 +210,7 @@ extern int rs400_suspend(struct radeon_device *rdev);
extern int rs400_resume(struct radeon_device *rdev);
void rs400_gart_tlb_flush(struct radeon_device *rdev);
void rs400_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr);
+ uint64_t addr, uint32_t flags);
uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
int rs400_gart_init(struct radeon_device *rdev);
@@ -233,7 +234,7 @@ void rs600_irq_disable(struct radeon_device *rdev);
u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
void rs600_gart_tlb_flush(struct radeon_device *rdev);
void rs600_gart_set_page(struct radeon_device *rdev, unsigned i,
- uint64_t addr);
+ uint64_t addr, uint32_t flags);
uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
void rs600_bandwidth_update(struct radeon_device *rdev);
@@ -351,7 +352,7 @@ void r600_hpd_fini(struct radeon_device *rdev);
bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
void r600_hpd_set_polarity(struct radeon_device *rdev,
enum radeon_hpd_id hpd);
-extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo);
+extern void r600_mmio_hdp_flush(struct radeon_device *rdev);
extern bool r600_gui_idle(struct radeon_device *rdev);
extern void r600_pm_misc(struct radeon_device *rdev);
extern void r600_pm_init_profile(struct radeon_device *rdev);
@@ -606,11 +607,22 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
struct radeon_ib *ib);
bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
-void cayman_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
+
+void cayman_dma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count);
+void cayman_dma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void cayman_dma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void cayman_dma_vm_pad_ib(struct radeon_ib *ib);
void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
@@ -693,11 +705,22 @@ int si_copy_dma(struct radeon_device *rdev,
uint64_t src_offset, uint64_t dst_offset,
unsigned num_gpu_pages,
struct radeon_fence **fence);
-void si_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
+
+void si_dma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count);
+void si_dma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void si_dma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+
void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
u32 si_get_xclk(struct radeon_device *rdev);
uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
@@ -771,11 +794,23 @@ int cik_irq_process(struct radeon_device *rdev);
int cik_vm_init(struct radeon_device *rdev);
void cik_vm_fini(struct radeon_device *rdev);
void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
-void cik_sdma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags);
+
+void cik_sdma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count);
+void cik_sdma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void cik_sdma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags);
+void cik_sdma_vm_pad_ib(struct radeon_ib *ib);
+
void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
u32 cik_gfx_get_rptr(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 30844814c25a..92b2d8dd4735 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1227,11 +1227,19 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
rdev->clock.default_dispclk =
le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
if (rdev->clock.default_dispclk == 0) {
- if (ASIC_IS_DCE5(rdev))
+ if (ASIC_IS_DCE6(rdev))
+ rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+ else if (ASIC_IS_DCE5(rdev))
rdev->clock.default_dispclk = 54000; /* 540 Mhz */
else
rdev->clock.default_dispclk = 60000; /* 600 Mhz */
}
+ /* set a reasonable default for DP */
+ if (ASIC_IS_DCE6(rdev) && (rdev->clock.default_dispclk < 53900)) {
+ DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",
+ rdev->clock.default_dispclk / 100);
+ rdev->clock.default_dispclk = 60000;
+ }
rdev->clock.dp_extclk =
le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
rdev->clock.current_dispclk = rdev->clock.default_dispclk;
@@ -1955,7 +1963,7 @@ static const char *thermal_controller_names[] = {
"adm1032",
"adm1030",
"max6649",
- "lm64",
+ "lm63", /* lm64 */
"f75375",
"asc7xxx",
};
@@ -1966,7 +1974,7 @@ static const char *pp_lib_thermal_controller_names[] = {
"adm1032",
"adm1030",
"max6649",
- "lm64",
+ "lm63", /* lm64 */
"f75375",
"RV6xx",
"RV770",
@@ -3228,6 +3236,41 @@ int radeon_atom_get_leakage_vddc_based_on_leakage_params(struct radeon_device *r
return 0;
}
+union get_voltage_info {
+ struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_2 in;
+ struct _GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 evv_out;
+};
+
+int radeon_atom_get_voltage_evv(struct radeon_device *rdev,
+ u16 virtual_voltage_id,
+ u16 *voltage)
+{
+ int index = GetIndexIntoMasterTable(COMMAND, GetVoltageInfo);
+ u32 entry_id;
+ u32 count = rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count;
+ union get_voltage_info args;
+
+ for (entry_id = 0; entry_id < count; entry_id++) {
+ if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].v ==
+ virtual_voltage_id)
+ break;
+ }
+
+ if (entry_id >= count)
+ return -EINVAL;
+
+ args.in.ucVoltageType = VOLTAGE_TYPE_VDDC;
+ args.in.ucVoltageMode = ATOM_GET_VOLTAGE_EVV_VOLTAGE;
+ args.in.ulSCLKFreq =
+ cpu_to_le32(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[entry_id].clk);
+
+ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+ *voltage = le16_to_cpu(args.evv_out.usVoltageLevel);
+
+ return 0;
+}
+
int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
u16 voltage_level, u8 voltage_type,
u32 *gpio_value, u32 *gpio_mask)
@@ -3389,6 +3432,50 @@ radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
return false;
}
+int radeon_atom_get_svi2_info(struct radeon_device *rdev,
+ u8 voltage_type,
+ u8 *svd_gpio_id, u8 *svc_gpio_id)
+{
+ int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+ u8 frev, crev;
+ u16 data_offset, size;
+ union voltage_object_info *voltage_info;
+ union voltage_object *voltage_object = NULL;
+
+ if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+ &frev, &crev, &data_offset)) {
+ voltage_info = (union voltage_object_info *)
+ (rdev->mode_info.atom_context->bios + data_offset);
+
+ switch (frev) {
+ case 3:
+ switch (crev) {
+ case 1:
+ voltage_object = (union voltage_object *)
+ atom_lookup_voltage_object_v3(&voltage_info->v3,
+ voltage_type,
+ VOLTAGE_OBJ_SVID2);
+ if (voltage_object) {
+ *svd_gpio_id = voltage_object->v3.asSVID2Obj.ucSVDGpioId;
+ *svc_gpio_id = voltage_object->v3.asSVID2Obj.ucSVCGpioId;
+ } else {
+ return -EINVAL;
+ }
+ break;
+ default:
+ DRM_ERROR("unknown voltage object table\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ DRM_ERROR("unknown voltage object table\n");
+ return -EINVAL;
+ }
+
+ }
+ return 0;
+}
+
int radeon_atom_get_max_voltage(struct radeon_device *rdev,
u8 voltage_type, u16 *max_voltage)
{
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 6e05a2e75a46..69f5695bdab9 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -97,7 +97,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
int time;
n = RADEON_BENCHMARK_ITERATIONS;
- r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, NULL, &sobj);
+ r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, 0, NULL, &sobj);
if (r) {
goto out_cleanup;
}
@@ -109,7 +109,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
if (r) {
goto out_cleanup;
}
- r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, NULL, &dobj);
+ r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, 0, NULL, &dobj);
if (r) {
goto out_cleanup;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 1b9177ed181f..300c4b3d4669 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -107,7 +107,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) {
- if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -115,7 +115,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break;
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
- if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -124,7 +124,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
dig_connector = radeon_connector->con_priv;
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
- drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
if (connector->display_info.bpc)
bpc = connector->display_info.bpc;
}
@@ -148,7 +148,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
break;
}
- if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
/* hdmi deep color only implemented on DCE4+ */
if ((bpc > 8) && !ASIC_IS_DCE4(rdev)) {
DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 8 bpc.\n",
@@ -197,6 +197,18 @@ int radeon_get_monitor_bpc(struct drm_connector *connector)
connector->name, bpc);
}
}
+ else if (bpc > 8) {
+ /* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
+ DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
+ connector->name);
+ bpc = 8;
+ }
+ }
+
+ if ((radeon_deep_color == 0) && (bpc > 8)) {
+ DRM_DEBUG("%s: Deep color disabled. Set radeon module param deep_color=1 to enable.\n",
+ connector->name);
+ bpc = 8;
}
DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n",
@@ -213,7 +225,6 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
struct drm_encoder *best_encoder = NULL;
struct drm_encoder *encoder = NULL;
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
- struct drm_mode_object *obj;
bool connected;
int i;
@@ -223,14 +234,11 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev,
- connector->encoder_ids[i],
- DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev,
+ connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
-
if ((encoder == best_encoder) && (status == connector_status_connected))
connected = true;
else
@@ -246,7 +254,6 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
{
- struct drm_mode_object *obj;
struct drm_encoder *encoder;
int i;
@@ -254,34 +261,134 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
if (encoder->encoder_type == encoder_type)
return encoder;
}
return NULL;
}
+struct edid *radeon_connector_edid(struct drm_connector *connector)
+{
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ struct drm_property_blob *edid_blob = connector->edid_blob_ptr;
+
+ if (radeon_connector->edid) {
+ return radeon_connector->edid;
+ } else if (edid_blob) {
+ struct edid *edid = kmemdup(edid_blob->data, edid_blob->length, GFP_KERNEL);
+ if (edid)
+ radeon_connector->edid = edid;
+ }
+ return radeon_connector->edid;
+}
+
+static void radeon_connector_get_edid(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+ if (radeon_connector->edid)
+ return;
+
+ /* on hw with routers, select right port */
+ if (radeon_connector->router.ddc_valid)
+ radeon_router_select_ddc_port(radeon_connector);
+
+ if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+ ENCODER_OBJECT_ID_NONE) &&
+ radeon_connector->ddc_bus->has_aux) {
+ radeon_connector->edid = drm_get_edid(connector,
+ &radeon_connector->ddc_bus->aux.ddc);
+ } else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+ (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+
+ if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
+ dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
+ radeon_connector->ddc_bus->has_aux)
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->aux.ddc);
+ else if (radeon_connector->ddc_bus)
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->adapter);
+ } else if (radeon_connector->ddc_bus) {
+ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+ &radeon_connector->ddc_bus->adapter);
+ }
+
+ if (!radeon_connector->edid) {
+ if (rdev->is_atom_bios) {
+ /* some laptops provide a hardcoded edid in rom for LCDs */
+ if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
+ (connector->connector_type == DRM_MODE_CONNECTOR_eDP)))
+ radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
+ } else {
+ /* some servers provide a hardcoded edid in rom for KVMs */
+ radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
+ }
+ }
+}
+
+static void radeon_connector_free_edid(struct drm_connector *connector)
+{
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+ if (radeon_connector->edid) {
+ kfree(radeon_connector->edid);
+ radeon_connector->edid = NULL;
+ }
+}
+
+static int radeon_ddc_get_modes(struct drm_connector *connector)
+{
+ struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+ int ret;
+
+ if (radeon_connector->edid) {
+ drm_mode_connector_update_edid_property(connector, radeon_connector->edid);
+ ret = drm_add_edid_modes(connector, radeon_connector->edid);
+ drm_edid_to_eld(connector, radeon_connector->edid);
+ return ret;
+ }
+ drm_mode_connector_update_edid_property(connector, NULL);
+ return 0;
+}
+
static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
/* pick the encoder ids */
- if (enc_id) {
- obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
+static void radeon_get_native_mode(struct drm_connector *connector)
+{
+ struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+ struct radeon_encoder *radeon_encoder;
+
+ if (encoder == NULL)
+ return;
+
+ radeon_encoder = to_radeon_encoder(encoder);
+
+ if (!list_empty(&connector->probed_modes)) {
+ struct drm_display_mode *preferred_mode =
+ list_first_entry(&connector->probed_modes,
+ struct drm_display_mode, head);
+
+ radeon_encoder->native_mode = *preferred_mode;
+ } else {
+ radeon_encoder->native_mode.clock = 0;
+ }
+}
+
/*
* radeon_connector_analog_encoder_conflict_solve
* - search for other connectors sharing this encoder
@@ -582,6 +689,35 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
radeon_property_change_mode(&radeon_encoder->base);
}
+ if (property == dev->mode_config.scaling_mode_property) {
+ enum radeon_rmx_type rmx_type;
+
+ if (connector->encoder)
+ radeon_encoder = to_radeon_encoder(connector->encoder);
+ else {
+ struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
+ radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
+ }
+
+ switch (val) {
+ default:
+ case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
+ case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
+ case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
+ case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
+ }
+ if (radeon_encoder->rmx_type == rmx_type)
+ return 0;
+
+ if ((rmx_type != DRM_MODE_SCALE_NONE) &&
+ (radeon_encoder->native_mode.clock == 0))
+ return 0;
+
+ radeon_encoder->rmx_type = rmx_type;
+
+ radeon_property_change_mode(&radeon_encoder->base);
+ }
+
return 0;
}
@@ -622,22 +758,20 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
static int radeon_lvds_get_modes(struct drm_connector *connector)
{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder;
int ret = 0;
struct drm_display_mode *mode;
- if (radeon_connector->ddc_bus) {
- ret = radeon_ddc_get_modes(radeon_connector);
- if (ret > 0) {
- encoder = radeon_best_single_encoder(connector);
- if (encoder) {
- radeon_fixup_lvds_native_mode(encoder, connector);
- /* add scaled modes */
- radeon_add_common_modes(encoder, connector);
- }
- return ret;
+ radeon_connector_get_edid(connector);
+ ret = radeon_ddc_get_modes(connector);
+ if (ret > 0) {
+ encoder = radeon_best_single_encoder(connector);
+ if (encoder) {
+ radeon_fixup_lvds_native_mode(encoder, connector);
+ /* add scaled modes */
+ radeon_add_common_modes(encoder, connector);
}
+ return ret;
}
encoder = radeon_best_single_encoder(connector);
@@ -712,16 +846,9 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
}
/* check for edid as well */
+ radeon_connector_get_edid(connector);
if (radeon_connector->edid)
ret = connector_status_connected;
- else {
- if (radeon_connector->ddc_bus) {
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &radeon_connector->ddc_bus->adapter);
- if (radeon_connector->edid)
- ret = connector_status_connected;
- }
- }
/* check acpi lid status ??? */
radeon_connector_update_scratch_regs(connector, ret);
@@ -734,10 +861,9 @@ static void radeon_connector_destroy(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- if (radeon_connector->edid)
- kfree(radeon_connector->edid);
+ radeon_connector_free_edid(connector);
kfree(radeon_connector->con_priv);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -794,10 +920,12 @@ static const struct drm_connector_funcs radeon_lvds_connector_funcs = {
static int radeon_vga_get_modes(struct drm_connector *connector)
{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
int ret;
- ret = radeon_ddc_get_modes(radeon_connector);
+ radeon_connector_get_edid(connector);
+ ret = radeon_ddc_get_modes(connector);
+
+ radeon_get_native_mode(connector);
return ret;
}
@@ -840,28 +968,26 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
dret = radeon_ddc_probe(radeon_connector, false);
if (dret) {
radeon_connector->detected_by_load = false;
- if (radeon_connector->edid) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
- }
- radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+ radeon_connector_free_edid(connector);
+ radeon_connector_get_edid(connector);
if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
connector->name);
ret = connector_status_connected;
} else {
- radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+ radeon_connector->use_digital =
+ !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
/* some oems have boards with separate digital and analog connectors
* with a shared ddc line (often vga + hdmi)
*/
if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
+ radeon_connector_free_edid(connector);
ret = connector_status_disconnected;
- } else
+ } else {
ret = connector_status_connected;
+ }
}
} else {
@@ -996,15 +1122,6 @@ static const struct drm_connector_funcs radeon_tv_connector_funcs = {
.set_property = radeon_connector_set_property,
};
-static int radeon_dvi_get_modes(struct drm_connector *connector)
-{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- int ret;
-
- ret = radeon_ddc_get_modes(radeon_connector);
- return ret;
-}
-
static bool radeon_check_hpd_status_unchanged(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -1045,7 +1162,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder = NULL;
struct drm_encoder_helper_funcs *encoder_funcs;
- struct drm_mode_object *obj;
int i, r;
enum drm_connector_status ret = connector_status_disconnected;
bool dret = false, broken_edid = false;
@@ -1063,18 +1179,16 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
dret = radeon_ddc_probe(radeon_connector, false);
if (dret) {
radeon_connector->detected_by_load = false;
- if (radeon_connector->edid) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
- }
- radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+ radeon_connector_free_edid(connector);
+ radeon_connector_get_edid(connector);
if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
connector->name);
/* rs690 seems to have a problem with connectors not existing and always
* return a block of 0's. If we see this just stop polling on this output */
- if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
+ if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) &&
+ radeon_connector->base.null_edid_counter) {
ret = connector_status_disconnected;
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n",
connector->name);
@@ -1084,18 +1198,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
broken_edid = true; /* defer use_digital to later */
}
} else {
- radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+ radeon_connector->use_digital =
+ !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
/* some oems have boards with separate digital and analog connectors
* with a shared ddc line (often vga + hdmi)
*/
if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
+ radeon_connector_free_edid(connector);
ret = connector_status_disconnected;
- } else
+ } else {
ret = connector_status_connected;
-
+ }
/* This gets complicated. We have boards with VGA + HDMI with a
* shared DDC line and we have boards with DVI-D + HDMI with a shared
* DDC line. The latter is more complex because with DVI<->HDMI adapters
@@ -1115,8 +1229,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {
/* hpd is our only option in this case */
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
+ radeon_connector_free_edid(connector);
ret = connector_status_disconnected;
}
}
@@ -1150,14 +1263,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev,
- connector->encoder_ids[i],
- DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev,
+ connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
-
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
continue;
@@ -1222,19 +1332,16 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct drm_mode_object *obj;
struct drm_encoder *encoder;
int i;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
-
if (radeon_connector->use_digital == true) {
if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
return encoder;
@@ -1249,13 +1356,8 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
- if (enc_id) {
- obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
- }
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
return NULL;
}
@@ -1288,7 +1390,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
return MODE_OK;
- else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
/* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000)
return MODE_CLOCK_HIGH;
@@ -1307,7 +1409,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
- .get_modes = radeon_dvi_get_modes,
+ .get_modes = radeon_vga_get_modes,
.mode_valid = radeon_dvi_mode_valid,
.best_encoder = radeon_dvi_encoder,
};
@@ -1336,7 +1438,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
if (!radeon_dig_connector->edp_on)
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_ON);
- ret = radeon_ddc_get_modes(radeon_connector);
+ radeon_connector_get_edid(connector);
+ ret = radeon_ddc_get_modes(connector);
if (!radeon_dig_connector->edp_on)
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF);
@@ -1347,7 +1450,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
- ret = radeon_ddc_get_modes(radeon_connector);
+ radeon_connector_get_edid(connector);
+ ret = radeon_ddc_get_modes(connector);
}
if (ret > 0) {
@@ -1380,7 +1484,10 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
- ret = radeon_ddc_get_modes(radeon_connector);
+ radeon_connector_get_edid(connector);
+ ret = radeon_ddc_get_modes(connector);
+
+ radeon_get_native_mode(connector);
}
return ret;
@@ -1388,7 +1495,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)
{
- struct drm_mode_object *obj;
struct drm_encoder *encoder;
struct radeon_encoder *radeon_encoder;
int i;
@@ -1397,11 +1503,10 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
radeon_encoder = to_radeon_encoder(encoder);
switch (radeon_encoder->encoder_id) {
@@ -1416,9 +1521,8 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
return ENCODER_OBJECT_ID_NONE;
}
-bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
+static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
{
- struct drm_mode_object *obj;
struct drm_encoder *encoder;
struct radeon_encoder *radeon_encoder;
int i;
@@ -1428,11 +1532,10 @@ bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
- if (!obj)
+ encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ if (!encoder)
continue;
- encoder = obj_to_encoder(obj);
radeon_encoder = to_radeon_encoder(encoder);
if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)
found = true;
@@ -1475,10 +1578,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
goto out;
}
- if (radeon_connector->edid) {
- kfree(radeon_connector->edid);
- radeon_connector->edid = NULL;
- }
+ radeon_connector_free_edid(connector);
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
@@ -1584,7 +1684,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
(radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
return radeon_dp_mode_valid_helper(connector, mode);
} else {
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
/* HDMI 1.3+ supports max clock of 340 Mhz */
if (mode->clock > 340000)
return MODE_CLOCK_HIGH;
@@ -1744,6 +1844,9 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.load_detect_property,
1);
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
break;
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID:
@@ -1765,6 +1868,10 @@ radeon_add_atom_connector(struct drm_device *dev,
0);
drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
+
+ drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.dither_property,
RADEON_FMT_DITHER_DISABLE);
@@ -1814,6 +1921,10 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.load_detect_property,
1);
+ if (ASIC_IS_AVIVO(rdev))
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
@@ -1832,6 +1943,10 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.load_detect_property,
1);
+ if (ASIC_IS_AVIVO(rdev))
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
connector->interlace_allowed = true;
@@ -1865,17 +1980,18 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property,
0);
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
}
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
}
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
- }
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
drm_object_attach_property(&radeon_connector->base.base,
@@ -1915,17 +2031,18 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property,
0);
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
}
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
}
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
- }
subpixel_order = SubPixelHorizontalRGB;
connector->interlace_allowed = true;
if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
@@ -1962,18 +2079,18 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.underscan_vborder_property,
0);
+ drm_object_attach_property(&radeon_connector->base.base,
+ rdev->mode_info.dither_property,
+ RADEON_FMT_DITHER_DISABLE);
+ drm_object_attach_property(&radeon_connector->base.base,
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_NONE);
}
if (ASIC_IS_DCE2(rdev) && (radeon_audio != 0)) {
drm_object_attach_property(&radeon_connector->base.base,
rdev->mode_info.audio_property,
RADEON_AUDIO_AUTO);
}
- if (ASIC_IS_AVIVO(rdev)) {
- drm_object_attach_property(&radeon_connector->base.base,
- rdev->mode_info.dither_property,
- RADEON_FMT_DITHER_DISABLE);
-
- }
connector->interlace_allowed = true;
/* in theory with a DP to VGA converter... */
connector->doublescan_allowed = false;
@@ -2047,7 +2164,7 @@ radeon_add_atom_connector(struct drm_device *dev,
connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->display_info.subpixel_order = subpixel_order;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
if (has_aux)
radeon_dp_aux_init(radeon_connector);
@@ -2208,5 +2325,5 @@ radeon_add_legacy_connector(struct drm_device *dev,
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;
connector->display_info.subpixel_order = subpixel_order;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
}
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 71a143461478..ee712c199b25 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -461,13 +461,23 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
struct radeon_vm *vm)
{
struct radeon_device *rdev = p->rdev;
+ struct radeon_bo_va *bo_va;
int i, r;
r = radeon_vm_update_page_directory(rdev, vm);
if (r)
return r;
- r = radeon_vm_bo_update(rdev, vm, rdev->ring_tmp_bo.bo,
+ r = radeon_vm_clear_freed(rdev, vm);
+ if (r)
+ return r;
+
+ if (vm->ib_bo_va == NULL) {
+ DRM_ERROR("Tmp BO not in VM!\n");
+ return -EINVAL;
+ }
+
+ r = radeon_vm_bo_update(rdev, vm->ib_bo_va,
&rdev->ring_tmp_bo.bo->tbo.mem);
if (r)
return r;
@@ -480,11 +490,18 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
continue;
bo = p->relocs[i].robj;
- r = radeon_vm_bo_update(rdev, vm, bo, &bo->tbo.mem);
+ bo_va = radeon_vm_bo_find(vm, bo);
+ if (bo_va == NULL) {
+ dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
+ return -EINVAL;
+ }
+
+ r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem);
if (r)
return r;
}
- return 0;
+
+ return radeon_vm_clear_invalids(rdev, vm);
}
static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 03686fab842d..c8ea050c8fa4 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -103,6 +103,31 @@ static const char radeon_family_name[][16] = {
"LAST",
};
+#define RADEON_PX_QUIRK_DISABLE_PX (1 << 0)
+#define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1)
+
+struct radeon_px_quirk {
+ u32 chip_vendor;
+ u32 chip_device;
+ u32 subsys_vendor;
+ u32 subsys_device;
+ u32 px_quirk_flags;
+};
+
+static struct radeon_px_quirk radeon_px_quirk_list[] = {
+ /* Acer aspire 5560g (CPU: AMD A4-3305M; GPU: AMD Radeon HD 6480g + 7470m)
+ * https://bugzilla.kernel.org/show_bug.cgi?id=74551
+ */
+ { PCI_VENDOR_ID_ATI, 0x6760, 0x1025, 0x0672, RADEON_PX_QUIRK_DISABLE_PX },
+ /* Asus K73TA laptop with AMD A6-3400M APU and Radeon 6550 GPU
+ * https://bugzilla.kernel.org/show_bug.cgi?id=51381
+ */
+ { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX },
+ /* macbook pro 8.2 */
+ { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP },
+ { 0, 0, 0, 0, 0 },
+};
+
bool radeon_is_px(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
@@ -112,6 +137,26 @@ bool radeon_is_px(struct drm_device *dev)
return false;
}
+static void radeon_device_handle_px_quirks(struct radeon_device *rdev)
+{
+ struct radeon_px_quirk *p = radeon_px_quirk_list;
+
+ /* Apply PX quirks */
+ while (p && p->chip_device != 0) {
+ if (rdev->pdev->vendor == p->chip_vendor &&
+ rdev->pdev->device == p->chip_device &&
+ rdev->pdev->subsystem_vendor == p->subsys_vendor &&
+ rdev->pdev->subsystem_device == p->subsys_device) {
+ rdev->px_quirk_flags = p->px_quirk_flags;
+ break;
+ }
+ ++p;
+ }
+
+ if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX)
+ rdev->flags &= ~RADEON_IS_PX;
+}
+
/**
* radeon_program_register_sequence - program an array of registers.
*
@@ -385,7 +430,8 @@ int radeon_wb_init(struct radeon_device *rdev)
if (rdev->wb.wb_obj == NULL) {
r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_GTT, NULL, &rdev->wb.wb_obj);
+ RADEON_GEM_DOMAIN_GTT, 0, NULL,
+ &rdev->wb.wb_obj);
if (r) {
dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
return r;
@@ -1056,61 +1102,54 @@ static void radeon_check_arguments(struct radeon_device *rdev)
if (!radeon_check_pot_argument(radeon_vm_size)) {
dev_warn(rdev->dev, "VM size (%d) must be a power of 2\n",
radeon_vm_size);
- radeon_vm_size = 4096;
+ radeon_vm_size = 4;
}
- if (radeon_vm_size < 4) {
- dev_warn(rdev->dev, "VM size (%d) to small, min is 4MB\n",
+ if (radeon_vm_size < 1) {
+ dev_warn(rdev->dev, "VM size (%d) to small, min is 1GB\n",
radeon_vm_size);
- radeon_vm_size = 4096;
+ radeon_vm_size = 4;
}
/*
* Max GPUVM size for Cayman, SI and CI are 40 bits.
*/
- if (radeon_vm_size > 1024*1024) {
- dev_warn(rdev->dev, "VM size (%d) to large, max is 1TB\n",
+ if (radeon_vm_size > 1024) {
+ dev_warn(rdev->dev, "VM size (%d) too large, max is 1TB\n",
radeon_vm_size);
- radeon_vm_size = 4096;
+ radeon_vm_size = 4;
}
/* defines number of bits in page table versus page directory,
* a page is 4KB so we have 12 bits offset, minimum 9 bits in the
* page table and the remaining bits are in the page directory */
- if (radeon_vm_block_size < 9) {
- dev_warn(rdev->dev, "VM page table size (%d) to small\n",
+ if (radeon_vm_block_size == -1) {
+
+ /* Total bits covered by PD + PTs */
+ unsigned bits = ilog2(radeon_vm_size) + 17;
+
+ /* Make sure the PD is 4K in size up to 8GB address space.
+ Above that split equal between PD and PTs */
+ if (radeon_vm_size <= 8)
+ radeon_vm_block_size = bits - 9;
+ else
+ radeon_vm_block_size = (bits + 3) / 2;
+
+ } else if (radeon_vm_block_size < 9) {
+ dev_warn(rdev->dev, "VM page table size (%d) too small\n",
radeon_vm_block_size);
radeon_vm_block_size = 9;
}
if (radeon_vm_block_size > 24 ||
- radeon_vm_size < (1ull << radeon_vm_block_size)) {
- dev_warn(rdev->dev, "VM page table size (%d) to large\n",
+ (radeon_vm_size * 1024) < (1ull << radeon_vm_block_size)) {
+ dev_warn(rdev->dev, "VM page table size (%d) too large\n",
radeon_vm_block_size);
radeon_vm_block_size = 9;
}
}
/**
- * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is
- * needed for waking up.
- *
- * @pdev: pci dev pointer
- */
-static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
-{
-
- /* 6600m in a macbook pro */
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
- pdev->subsystem_device == 0x00e2) {
- printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n");
- return true;
- }
-
- return false;
-}
-
-/**
* radeon_switcheroo_set_state - set switcheroo state
*
* @pdev: pci dev pointer
@@ -1122,6 +1161,7 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
{
struct drm_device *dev = pci_get_drvdata(pdev);
+ struct radeon_device *rdev = dev->dev_private;
if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
return;
@@ -1133,7 +1173,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
/* don't suspend or resume card normally */
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
- if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev))
+ if (d3_delay < 20 && (rdev->px_quirk_flags & RADEON_PX_QUIRK_LONG_WAKEUP))
dev->pdev->d3_delay = 20;
radeon_resume_kms(dev, true, true);
@@ -1238,7 +1278,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* Adjust VM size here.
* Max GPUVM size for cayman+ is 40 bits.
*/
- rdev->vm_manager.max_pfn = radeon_vm_size << 8;
+ rdev->vm_manager.max_pfn = radeon_vm_size << 18;
/* Set asic functions */
r = radeon_asic_init(rdev);
@@ -1337,6 +1377,9 @@ int radeon_device_init(struct radeon_device *rdev,
if (rdev->rio_mem == NULL)
DRM_ERROR("Unable to find PCI I/O BAR\n");
+ if (rdev->flags & RADEON_IS_PX)
+ radeon_device_handle_px_quirks(rdev);
+
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
/* this will fail for cards that aren't VGA class devices, just
* ignore it */
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 8fc362aa6a1a..3fdf87318069 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -285,7 +285,6 @@ static void radeon_unpin_work_func(struct work_struct *__work)
void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
{
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
- struct radeon_flip_work *work;
unsigned long flags;
u32 update_pending;
int vpos, hpos;
@@ -294,9 +293,24 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id)
if (radeon_crtc == NULL)
return;
+ /* Skip the pageflip completion check below (based on polling) on
+ * asics which reliably support hw pageflip completion irqs. pflip
+ * irqs are a reliable and race-free method of handling pageflip
+ * completion detection. A use_pflipirq module parameter < 2 allows
+ * to override this in case of asics with faulty pflip irqs.
+ * A module parameter of 0 would only use this polling based path,
+ * a parameter of 1 would use pflip irq only as a backup to this
+ * path, as in Linux 3.16.
+ */
+ if ((radeon_use_pflipirq == 2) && ASIC_IS_DCE4(rdev))
+ return;
+
spin_lock_irqsave(&rdev->ddev->event_lock, flags);
- work = radeon_crtc->flip_work;
- if (work == NULL) {
+ if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
+ DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
+ "RADEON_FLIP_SUBMITTED(%d)\n",
+ radeon_crtc->flip_status,
+ RADEON_FLIP_SUBMITTED);
spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
return;
}
@@ -344,12 +358,17 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
spin_lock_irqsave(&rdev->ddev->event_lock, flags);
work = radeon_crtc->flip_work;
- if (work == NULL) {
+ if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
+ DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
+ "RADEON_FLIP_SUBMITTED(%d)\n",
+ radeon_crtc->flip_status,
+ RADEON_FLIP_SUBMITTED);
spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
return;
}
/* Pageflip completed. Clean up. */
+ radeon_crtc->flip_status = RADEON_FLIP_NONE;
radeon_crtc->flip_work = NULL;
/* wakeup userspace */
@@ -359,7 +378,6 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
- radeon_fence_unref(&work->fence);
radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
queue_work(radeon_crtc->flip_queue, &work->unpin_work);
}
@@ -379,51 +397,108 @@ static void radeon_flip_work_func(struct work_struct *__work)
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
struct drm_crtc *crtc = &radeon_crtc->base;
- struct drm_framebuffer *fb = work->fb;
-
- uint32_t tiling_flags, pitch_pixels;
- uint64_t base;
-
unsigned long flags;
int r;
down_read(&rdev->exclusive_lock);
- while (work->fence) {
+ if (work->fence) {
r = radeon_fence_wait(work->fence, false);
if (r == -EDEADLK) {
up_read(&rdev->exclusive_lock);
r = radeon_gpu_reset(rdev);
down_read(&rdev->exclusive_lock);
}
+ if (r)
+ DRM_ERROR("failed to wait on page flip fence (%d)!\n", r);
- if (r) {
- DRM_ERROR("failed to wait on page flip fence (%d)!\n",
- r);
- goto cleanup;
- } else
- radeon_fence_unref(&work->fence);
+ /* We continue with the page flip even if we failed to wait on
+ * the fence, otherwise the DRM core and userspace will be
+ * confused about which BO the CRTC is scanning out
+ */
+
+ radeon_fence_unref(&work->fence);
}
+ /* We borrow the event spin lock for protecting flip_status */
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+
+ /* set the proper interrupt */
+ radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
+
+ /* do the flip (mmio) */
+ radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
+
+ radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ up_read(&rdev->exclusive_lock);
+}
+
+static int radeon_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 radeon_device *rdev = dev->dev_private;
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct radeon_framebuffer *old_radeon_fb;
+ struct radeon_framebuffer *new_radeon_fb;
+ struct drm_gem_object *obj;
+ struct radeon_flip_work *work;
+ struct radeon_bo *new_rbo;
+ uint32_t tiling_flags, pitch_pixels;
+ uint64_t base;
+ unsigned long flags;
+ int r;
+
+ work = kzalloc(sizeof *work, GFP_KERNEL);
+ if (work == NULL)
+ return -ENOMEM;
+
+ INIT_WORK(&work->flip_work, radeon_flip_work_func);
+ INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
+
+ work->rdev = rdev;
+ work->crtc_id = radeon_crtc->crtc_id;
+ work->event = event;
+
+ /* schedule unpin of the old buffer */
+ old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
+ obj = old_radeon_fb->obj;
+
+ /* take a reference to the old object */
+ drm_gem_object_reference(obj);
+ work->old_rbo = gem_to_radeon_bo(obj);
+
+ new_radeon_fb = to_radeon_framebuffer(fb);
+ obj = new_radeon_fb->obj;
+ new_rbo = gem_to_radeon_bo(obj);
+
+ spin_lock(&new_rbo->tbo.bdev->fence_lock);
+ if (new_rbo->tbo.sync_obj)
+ work->fence = radeon_fence_ref(new_rbo->tbo.sync_obj);
+ spin_unlock(&new_rbo->tbo.bdev->fence_lock);
+
/* pin the new buffer */
- DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n",
- work->old_rbo, work->new_rbo);
+ DRM_DEBUG_DRIVER("flip-ioctl() cur_rbo = %p, new_rbo = %p\n",
+ work->old_rbo, new_rbo);
- r = radeon_bo_reserve(work->new_rbo, false);
+ r = radeon_bo_reserve(new_rbo, false);
if (unlikely(r != 0)) {
DRM_ERROR("failed to reserve new rbo buffer before flip\n");
goto cleanup;
}
/* Only 27 bit offset for legacy CRTC */
- r = radeon_bo_pin_restricted(work->new_rbo, RADEON_GEM_DOMAIN_VRAM,
+ r = radeon_bo_pin_restricted(new_rbo, RADEON_GEM_DOMAIN_VRAM,
ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base);
if (unlikely(r != 0)) {
- radeon_bo_unreserve(work->new_rbo);
+ radeon_bo_unreserve(new_rbo);
r = -EINVAL;
DRM_ERROR("failed to pin new rbo buffer before flip\n");
goto cleanup;
}
- radeon_bo_get_tiling_flags(work->new_rbo, &tiling_flags, NULL);
- radeon_bo_unreserve(work->new_rbo);
+ radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
+ radeon_bo_unreserve(new_rbo);
if (!ASIC_IS_AVIVO(rdev)) {
/* crtc offset is from display base addr not FB location */
@@ -460,6 +535,7 @@ static void radeon_flip_work_func(struct work_struct *__work)
}
base &= ~7;
}
+ work->base = base;
r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
if (r) {
@@ -470,98 +546,42 @@ static void radeon_flip_work_func(struct work_struct *__work)
/* We borrow the event spin lock for protecting flip_work */
spin_lock_irqsave(&crtc->dev->event_lock, flags);
- /* set the proper interrupt */
- radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
+ if (radeon_crtc->flip_status != RADEON_FLIP_NONE) {
+ DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ r = -EBUSY;
+ goto vblank_cleanup;
+ }
+ radeon_crtc->flip_status = RADEON_FLIP_PENDING;
+ radeon_crtc->flip_work = work;
- /* do the flip (mmio) */
- radeon_page_flip(rdev, radeon_crtc->crtc_id, base);
+ /* update crtc fb */
+ crtc->primary->fb = fb;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- up_read(&rdev->exclusive_lock);
- return;
+ queue_work(radeon_crtc->flip_queue, &work->flip_work);
+ return 0;
+
+vblank_cleanup:
+ drm_vblank_put(crtc->dev, radeon_crtc->crtc_id);
pflip_cleanup:
- if (unlikely(radeon_bo_reserve(work->new_rbo, false) != 0)) {
+ if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
DRM_ERROR("failed to reserve new rbo in error path\n");
goto cleanup;
}
- if (unlikely(radeon_bo_unpin(work->new_rbo) != 0)) {
+ if (unlikely(radeon_bo_unpin(new_rbo) != 0)) {
DRM_ERROR("failed to unpin new rbo in error path\n");
}
- radeon_bo_unreserve(work->new_rbo);
+ radeon_bo_unreserve(new_rbo);
cleanup:
drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
radeon_fence_unref(&work->fence);
kfree(work);
- up_read(&rdev->exclusive_lock);
-}
-
-static int radeon_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 radeon_device *rdev = dev->dev_private;
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- struct radeon_framebuffer *old_radeon_fb;
- struct radeon_framebuffer *new_radeon_fb;
- struct drm_gem_object *obj;
- struct radeon_flip_work *work;
- unsigned long flags;
-
- work = kzalloc(sizeof *work, GFP_KERNEL);
- if (work == NULL)
- return -ENOMEM;
-
- INIT_WORK(&work->flip_work, radeon_flip_work_func);
- INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
-
- work->rdev = rdev;
- work->crtc_id = radeon_crtc->crtc_id;
- work->fb = fb;
- work->event = event;
-
- /* schedule unpin of the old buffer */
- old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
- obj = old_radeon_fb->obj;
-
- /* take a reference to the old object */
- drm_gem_object_reference(obj);
- work->old_rbo = gem_to_radeon_bo(obj);
-
- new_radeon_fb = to_radeon_framebuffer(fb);
- obj = new_radeon_fb->obj;
- work->new_rbo = gem_to_radeon_bo(obj);
-
- spin_lock(&work->new_rbo->tbo.bdev->fence_lock);
- if (work->new_rbo->tbo.sync_obj)
- work->fence = radeon_fence_ref(work->new_rbo->tbo.sync_obj);
- spin_unlock(&work->new_rbo->tbo.bdev->fence_lock);
-
- /* We borrow the event spin lock for protecting flip_work */
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
-
- if (radeon_crtc->flip_work) {
- DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
- radeon_fence_unref(&work->fence);
- kfree(work);
- return -EBUSY;
- }
- radeon_crtc->flip_work = work;
-
- /* update crtc fb */
- crtc->primary->fb = fb;
-
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-
- queue_work(radeon_crtc->flip_queue, &work->flip_work);
- return 0;
+ return r;
}
static int
@@ -815,59 +835,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
return ret;
}
-int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
-{
- struct drm_device *dev = radeon_connector->base.dev;
- struct radeon_device *rdev = dev->dev_private;
- int ret = 0;
-
- /* on hw with routers, select right port */
- if (radeon_connector->router.ddc_valid)
- radeon_router_select_ddc_port(radeon_connector);
-
- if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
- ENCODER_OBJECT_ID_NONE) {
- if (radeon_connector->ddc_bus->has_aux)
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &radeon_connector->ddc_bus->aux.ddc);
- } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
- (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
- if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
- dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
- radeon_connector->ddc_bus->has_aux)
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &radeon_connector->ddc_bus->aux.ddc);
- else if (radeon_connector->ddc_bus && !radeon_connector->edid)
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &radeon_connector->ddc_bus->adapter);
- } else {
- if (radeon_connector->ddc_bus && !radeon_connector->edid)
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &radeon_connector->ddc_bus->adapter);
- }
-
- if (!radeon_connector->edid) {
- if (rdev->is_atom_bios) {
- /* some laptops provide a hardcoded edid in rom for LCDs */
- if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) ||
- (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)))
- radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
- } else
- /* some servers provide a hardcoded edid in rom for KVMs */
- radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
- }
- if (radeon_connector->edid) {
- drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
- ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
- drm_edid_to_eld(&radeon_connector->base, radeon_connector->edid);
- return ret;
- }
- drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
- return 0;
-}
-
/* avivo */
/**
@@ -1736,7 +1703,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
- drm_detect_hdmi_monitor(radeon_connector->edid) &&
+ drm_detect_hdmi_monitor(radeon_connector_edid(connector)) &&
is_hdtv_mode(mode)))) {
if (radeon_encoder->underscan_hborder != 0)
radeon_crtc->h_border = radeon_encoder->underscan_hborder;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 6e3017413386..092d067f93e1 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -82,9 +82,11 @@
* 2.38.0 - RADEON_GEM_OP (GET_INITIAL_DOMAIN, SET_INITIAL_DOMAIN),
* CIK: 1D and linear tiling modes contain valid PIPE_CONFIG
* 2.39.0 - Add INFO query for number of active CUs
+ * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting
+ * CS to GPU
*/
#define KMS_DRIVER_MAJOR 2
-#define KMS_DRIVER_MINOR 39
+#define KMS_DRIVER_MINOR 40
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);
@@ -132,6 +134,7 @@ struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev,
struct sg_table *sg);
int radeon_gem_prime_pin(struct drm_gem_object *obj);
void radeon_gem_prime_unpin(struct drm_gem_object *obj);
+struct reservation_object *radeon_gem_prime_res_obj(struct drm_gem_object *);
void *radeon_gem_prime_vmap(struct drm_gem_object *obj);
void radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd,
@@ -173,8 +176,10 @@ int radeon_dpm = -1;
int radeon_aspm = -1;
int radeon_runtime_pm = -1;
int radeon_hard_reset = 0;
-int radeon_vm_size = 4096;
-int radeon_vm_block_size = 9;
+int radeon_vm_size = 8;
+int radeon_vm_block_size = -1;
+int radeon_deep_color = 0;
+int radeon_use_pflipirq = 2;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -242,12 +247,18 @@ module_param_named(runpm, radeon_runtime_pm, int, 0444);
MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))");
module_param_named(hard_reset, radeon_hard_reset, int, 0444);
-MODULE_PARM_DESC(vm_size, "VM address space size in megabytes (default 4GB)");
+MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 4GB)");
module_param_named(vm_size, radeon_vm_size, int, 0444);
-MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default 9)");
+MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)");
module_param_named(vm_block_size, radeon_vm_block_size, int, 0444);
+MODULE_PARM_DESC(deep_color, "Deep Color support (1 = enable, 0 = disable (default))");
+module_param_named(deep_color, radeon_deep_color, int, 0444);
+
+MODULE_PARM_DESC(use_pflipirq, "Pflip irqs for pageflip completion (0 = disable, 1 = as fallback, 2 = exclusive (default))");
+module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444);
+
static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
};
@@ -562,6 +573,7 @@ static struct drm_driver kms_driver = {
.gem_prime_import = drm_gem_prime_import,
.gem_prime_pin = radeon_gem_prime_pin,
.gem_prime_unpin = radeon_gem_prime_unpin,
+ .gem_prime_res_obj = radeon_gem_prime_res_obj,
.gem_prime_get_sg_table = radeon_gem_prime_get_sg_table,
.gem_prime_import_sg_table = radeon_gem_prime_import_sg_table,
.gem_prime_vmap = radeon_gem_prime_vmap,
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index bd4959ca23aa..3c2094c25b53 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -343,7 +343,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
case DRM_MODE_CONNECTOR_HDMIB:
if (radeon_connector->use_digital) {
/* HDMI 1.3 supports up to 340 Mhz over single link */
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
if (pixel_clock > 340000)
return true;
else
@@ -365,7 +365,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
return false;
else {
/* HDMI 1.3 supports up to 340 Mhz over single link */
- if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector_edid(connector))) {
if (pixel_clock > 340000)
return true;
else
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 665ced3b7313..94b0f2aa3d7c 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -127,8 +127,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
aligned_size = ALIGN(size, PAGE_SIZE);
ret = radeon_gem_object_create(rdev, aligned_size, 0,
RADEON_GEM_DOMAIN_VRAM,
- false, true,
- &gobj);
+ 0, true, &gobj);
if (ret) {
printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
aligned_size);
@@ -331,7 +330,7 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
return 0;
}
-static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
+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,
@@ -353,7 +352,9 @@ int radeon_fbdev_init(struct radeon_device *rdev)
rfbdev->rdev = rdev;
rdev->mode_info.rfbdev = rfbdev;
- rfbdev->helper.funcs = &radeon_fb_helper_funcs;
+
+ drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper,
+ &radeon_fb_helper_funcs);
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
rdev->num_crtc,
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 2e723651069b..a053a0779aac 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -128,7 +128,7 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
if (rdev->gart.robj == NULL) {
r = radeon_bo_create(rdev, rdev->gart.table_size,
PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
- NULL, &rdev->gart.robj);
+ 0, NULL, &rdev->gart.robj);
if (r) {
return r;
}
@@ -243,7 +243,8 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
page_base = rdev->gart.pages_addr[p];
for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
if (rdev->gart.ptr) {
- radeon_gart_set_page(rdev, t, page_base);
+ radeon_gart_set_page(rdev, t, page_base,
+ RADEON_GART_PAGE_DUMMY);
}
page_base += RADEON_GPU_PAGE_SIZE;
}
@@ -261,13 +262,15 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
* @pages: number of pages to bind
* @pagelist: pages to bind
* @dma_addr: DMA addresses of pages
+ * @flags: RADEON_GART_PAGE_* flags
*
* Binds the requested pages to the gart page table
* (all asics).
* Returns 0 for success, -EINVAL for failure.
*/
int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
- int pages, struct page **pagelist, dma_addr_t *dma_addr)
+ int pages, struct page **pagelist, dma_addr_t *dma_addr,
+ uint32_t flags)
{
unsigned t;
unsigned p;
@@ -287,7 +290,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
if (rdev->gart.ptr) {
page_base = rdev->gart.pages_addr[p];
for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
- radeon_gart_set_page(rdev, t, page_base);
+ radeon_gart_set_page(rdev, t, page_base, flags);
page_base += RADEON_GPU_PAGE_SIZE;
}
}
@@ -298,33 +301,6 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
}
/**
- * radeon_gart_restore - bind all pages in the gart page table
- *
- * @rdev: radeon_device pointer
- *
- * Binds all pages in the gart page table (all asics).
- * Used to rebuild the gart table on device startup or resume.
- */
-void radeon_gart_restore(struct radeon_device *rdev)
-{
- int i, j, t;
- u64 page_base;
-
- if (!rdev->gart.ptr) {
- return;
- }
- for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) {
- page_base = rdev->gart.pages_addr[i];
- for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) {
- radeon_gart_set_page(rdev, t, page_base);
- page_base += RADEON_GPU_PAGE_SIZE;
- }
- }
- mb();
- radeon_gart_tlb_flush(rdev);
-}
-
-/**
* radeon_gart_init - init the driver info for managing the gart
*
* @rdev: radeon_device pointer
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index d09650c1d720..bfd7e1b0ff3f 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -40,9 +40,9 @@ void radeon_gem_object_free(struct drm_gem_object *gobj)
}
}
-int radeon_gem_object_create(struct radeon_device *rdev, int size,
+int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size,
int alignment, int initial_domain,
- bool discardable, bool kernel,
+ u32 flags, bool kernel,
struct drm_gem_object **obj)
{
struct radeon_bo *robj;
@@ -55,23 +55,26 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
alignment = PAGE_SIZE;
}
- /* maximun bo size is the minimun btw visible vram and gtt size */
- max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
+ /* Maximum bo size is the unpinned gtt size since we use the gtt to
+ * handle vram to system pool migrations.
+ */
+ max_size = rdev->mc.gtt_size - rdev->gart_pin_size;
if (size > max_size) {
- printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n",
- __func__, __LINE__, size >> 20, max_size >> 20);
+ DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n",
+ size >> 20, max_size >> 20);
return -ENOMEM;
}
retry:
- r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj);
+ r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain,
+ flags, NULL, &robj);
if (r) {
if (r != -ERESTARTSYS) {
if (initial_domain == RADEON_GEM_DOMAIN_VRAM) {
initial_domain |= RADEON_GEM_DOMAIN_GTT;
goto retry;
}
- DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
+ DRM_ERROR("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
size, initial_domain, alignment, r);
}
return r;
@@ -208,18 +211,15 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
struct radeon_device *rdev = dev->dev_private;
struct drm_radeon_gem_info *args = data;
struct ttm_mem_type_manager *man;
- unsigned i;
man = &rdev->mman.bdev.man[TTM_PL_VRAM];
args->vram_size = rdev->mc.real_vram_size;
args->vram_visible = (u64)man->size << PAGE_SHIFT;
- if (rdev->stollen_vga_memory)
- args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory);
- args->vram_visible -= radeon_fbdev_total_size(rdev);
- args->gart_size = rdev->mc.gtt_size - 4096 - RADEON_IB_POOL_SIZE*64*1024;
- for(i = 0; i < RADEON_NUM_RINGS; ++i)
- args->gart_size -= rdev->ring[i].ring_size;
+ args->vram_visible -= rdev->vram_pin_size;
+ args->gart_size = rdev->mc.gtt_size;
+ args->gart_size -= rdev->gart_pin_size;
+
return 0;
}
@@ -252,8 +252,8 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
/* create a gem object to contain this object in */
args->size = roundup(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, args->alignment,
- args->initial_domain, false,
- false, &gobj);
+ args->initial_domain, args->flags,
+ false, &gobj);
if (r) {
up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
@@ -358,16 +358,18 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
struct drm_gem_object *gobj;
struct radeon_bo *robj;
int r;
+ uint32_t cur_placement = 0;
gobj = drm_gem_object_lookup(dev, filp, args->handle);
if (gobj == NULL) {
return -ENOENT;
}
robj = gem_to_radeon_bo(gobj);
- r = radeon_bo_wait(robj, NULL, false);
- /* callback hw specific functions if any */
- if (rdev->asic->ioctl_wait_idle)
- robj->rdev->asic->ioctl_wait_idle(rdev, robj);
+ r = radeon_bo_wait(robj, &cur_placement, false);
+ /* Flush HDP cache via MMIO if necessary */
+ 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);
r = radeon_gem_handle_lockup(rdev, r);
return r;
@@ -461,11 +463,6 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
args->operation = RADEON_VA_RESULT_ERROR;
return -EINVAL;
}
- if (!(args->flags & RADEON_VM_PAGE_SNOOPED)) {
- dev_err(&dev->pdev->dev, "only supported snooped mapping for now\n");
- args->operation = RADEON_VA_RESULT_ERROR;
- return -EINVAL;
- }
switch (args->operation) {
case RADEON_VA_MAP:
@@ -499,9 +496,9 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
switch (args->operation) {
case RADEON_VA_MAP:
- if (bo_va->soffset) {
+ if (bo_va->it.start) {
args->operation = RADEON_VA_RESULT_VA_EXIST;
- args->offset = bo_va->soffset;
+ args->offset = bo_va->it.start * RADEON_GPU_PAGE_SIZE;
goto out;
}
r = radeon_vm_bo_set_addr(rdev, bo_va, args->offset, args->flags);
@@ -572,9 +569,8 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
args->size = ALIGN(args->size, PAGE_SIZE);
r = radeon_gem_object_create(rdev, args->size, 0,
- RADEON_GEM_DOMAIN_VRAM,
- false, ttm_bo_type_device,
- &gobj);
+ RADEON_GEM_DOMAIN_VRAM, 0,
+ false, &gobj);
if (r)
return -ENOMEM;
diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c
new file mode 100644
index 000000000000..65b0c213488d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_ib.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * 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: Dave Airlie
+ * Alex Deucher
+ * Jerome Glisse
+ * Christian König
+ */
+#include <drm/drmP.h>
+#include "radeon.h"
+
+/*
+ * IB
+ * IBs (Indirect Buffers) and areas of GPU accessible memory where
+ * commands are stored. You can put a pointer to the IB in the
+ * command ring and the hw will fetch the commands from the IB
+ * and execute them. Generally userspace acceleration drivers
+ * produce command buffers which are send to the kernel and
+ * put in IBs for execution by the requested ring.
+ */
+static int radeon_debugfs_sa_init(struct radeon_device *rdev);
+
+/**
+ * radeon_ib_get - request an IB (Indirect Buffer)
+ *
+ * @rdev: radeon_device pointer
+ * @ring: ring index the IB is associated with
+ * @ib: IB object returned
+ * @size: requested IB size
+ *
+ * Request an IB (all asics). IBs are allocated using the
+ * suballocator.
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ib_get(struct radeon_device *rdev, int ring,
+ struct radeon_ib *ib, struct radeon_vm *vm,
+ unsigned size)
+{
+ int r;
+
+ r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
+ if (r) {
+ dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
+ return r;
+ }
+
+ r = radeon_semaphore_create(rdev, &ib->semaphore);
+ if (r) {
+ return r;
+ }
+
+ ib->ring = ring;
+ ib->fence = NULL;
+ ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo);
+ ib->vm = vm;
+ if (vm) {
+ /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
+ * space and soffset is the offset inside the pool bo
+ */
+ ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
+ } else {
+ ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
+ }
+ ib->is_const_ib = false;
+
+ return 0;
+}
+
+/**
+ * radeon_ib_free - free an IB (Indirect Buffer)
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to free
+ *
+ * Free an IB (all asics).
+ */
+void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+ radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
+ radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
+ radeon_fence_unref(&ib->fence);
+}
+
+/**
+ * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ * @const_ib: Const IB to schedule (SI only)
+ *
+ * Schedule an IB on the associated ring (all asics).
+ * Returns 0 on success, error on failure.
+ *
+ * On SI, there are two parallel engines fed from the primary ring,
+ * the CE (Constant Engine) and the DE (Drawing Engine). Since
+ * resource descriptors have moved to memory, the CE allows you to
+ * prime the caches while the DE is updating register state so that
+ * the resource descriptors will be already in cache when the draw is
+ * processed. To accomplish this, the userspace driver submits two
+ * IBs, one for the CE and one for the DE. If there is a CE IB (called
+ * a CONST_IB), it will be put on the ring prior to the DE IB. Prior
+ * to SI there was just a DE IB.
+ */
+int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
+ struct radeon_ib *const_ib)
+{
+ struct radeon_ring *ring = &rdev->ring[ib->ring];
+ int r = 0;
+
+ if (!ib->length_dw || !ring->ready) {
+ /* TODO: Nothings in the ib we should report. */
+ dev_err(rdev->dev, "couldn't schedule ib\n");
+ return -EINVAL;
+ }
+
+ /* 64 dwords should be enough for fence too */
+ r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8);
+ if (r) {
+ dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
+ return r;
+ }
+
+ /* grab a vm id if necessary */
+ if (ib->vm) {
+ struct radeon_fence *vm_id_fence;
+ vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
+ radeon_semaphore_sync_to(ib->semaphore, vm_id_fence);
+ }
+
+ /* sync with other rings */
+ r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
+ if (r) {
+ dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+
+ if (ib->vm)
+ radeon_vm_flush(rdev, ib->vm, ib->ring);
+
+ if (const_ib) {
+ radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
+ radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
+ }
+ radeon_ring_ib_execute(rdev, ib->ring, ib);
+ r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
+ if (r) {
+ dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r);
+ radeon_ring_unlock_undo(rdev, ring);
+ return r;
+ }
+ if (const_ib) {
+ const_ib->fence = radeon_fence_ref(ib->fence);
+ }
+
+ if (ib->vm)
+ radeon_vm_fence(rdev, ib->vm, ib->fence);
+
+ radeon_ring_unlock_commit(rdev, ring);
+ return 0;
+}
+
+/**
+ * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the suballocator to manage a pool of memory
+ * for use as IBs (all asics).
+ * Returns 0 on success, error on failure.
+ */
+int radeon_ib_pool_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->ib_pool_ready) {
+ return 0;
+ }
+
+ if (rdev->family >= CHIP_BONAIRE) {
+ r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
+ RADEON_IB_POOL_SIZE*64*1024,
+ RADEON_GPU_PAGE_SIZE,
+ RADEON_GEM_DOMAIN_GTT,
+ RADEON_GEM_GTT_WC);
+ } else {
+ /* Before CIK, it's better to stick to cacheable GTT due
+ * to the command stream checking
+ */
+ r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
+ RADEON_IB_POOL_SIZE*64*1024,
+ RADEON_GPU_PAGE_SIZE,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+ if (r) {
+ return r;
+ }
+
+ r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo);
+ if (r) {
+ return r;
+ }
+
+ rdev->ib_pool_ready = true;
+ if (radeon_debugfs_sa_init(rdev)) {
+ dev_err(rdev->dev, "failed to register debugfs file for SA\n");
+ }
+ return 0;
+}
+
+/**
+ * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the suballocator managing the pool of memory
+ * for use as IBs (all asics).
+ */
+void radeon_ib_pool_fini(struct radeon_device *rdev)
+{
+ if (rdev->ib_pool_ready) {
+ radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo);
+ radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo);
+ rdev->ib_pool_ready = false;
+ }
+}
+
+/**
+ * radeon_ib_ring_tests - test IBs on the rings
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Test an IB (Indirect Buffer) on each ring.
+ * If the test fails, disable the ring.
+ * Returns 0 on success, error if the primary GFX ring
+ * IB test fails.
+ */
+int radeon_ib_ring_tests(struct radeon_device *rdev)
+{
+ unsigned i;
+ int r;
+
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ struct radeon_ring *ring = &rdev->ring[i];
+
+ if (!ring->ready)
+ continue;
+
+ r = radeon_ib_test(rdev, i, ring);
+ if (r) {
+ ring->ready = false;
+ rdev->needs_reset = false;
+
+ if (i == RADEON_RING_TYPE_GFX_INDEX) {
+ /* oh, oh, that's really bad */
+ DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r);
+ rdev->accel_working = false;
+ return r;
+
+ } else {
+ /* still not good, but we can live with it */
+ DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r);
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Debugfs info
+ */
+#if defined(CONFIG_DEBUG_FS)
+
+static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m);
+
+ return 0;
+
+}
+
+static struct drm_info_list radeon_debugfs_sa_list[] = {
+ {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
+};
+
+#endif
+
+static int radeon_debugfs_sa_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+ return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
+#else
+ return 0;
+#endif
+}
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 35d931881b4b..eb7164d07985 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -254,7 +254,18 @@ static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file
}
break;
case RADEON_INFO_ACCEL_WORKING2:
- *value = rdev->accel_working;
+ if (rdev->family == CHIP_HAWAII) {
+ if (rdev->accel_working) {
+ if (rdev->new_fw)
+ *value = 3;
+ else
+ *value = 2;
+ } else {
+ *value = 0;
+ }
+ } else {
+ *value = rdev->accel_working;
+ }
break;
case RADEON_INFO_TILING_CONFIG:
if (rdev->family >= CHIP_BONAIRE)
@@ -579,7 +590,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
/* new gpu have virtual address space support */
if (rdev->family >= CHIP_CAYMAN) {
struct radeon_fpriv *fpriv;
- struct radeon_bo_va *bo_va;
+ struct radeon_vm *vm;
int r;
fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
@@ -587,7 +598,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
return -ENOMEM;
}
- r = radeon_vm_init(rdev, &fpriv->vm);
+ vm = &fpriv->vm;
+ r = radeon_vm_init(rdev, vm);
if (r) {
kfree(fpriv);
return r;
@@ -596,22 +608,23 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (r) {
- radeon_vm_fini(rdev, &fpriv->vm);
+ radeon_vm_fini(rdev, vm);
kfree(fpriv);
return r;
}
/* map the ib pool buffer read only into
* virtual address space */
- bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
- rdev->ring_tmp_bo.bo);
- r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
+ vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
+ rdev->ring_tmp_bo.bo);
+ r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
+ RADEON_VA_IB_OFFSET,
RADEON_VM_PAGE_READABLE |
RADEON_VM_PAGE_SNOOPED);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
if (r) {
- radeon_vm_fini(rdev, &fpriv->vm);
+ radeon_vm_fini(rdev, vm);
kfree(fpriv);
return r;
}
@@ -640,21 +653,19 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
/* new gpu have virtual address space support */
if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
struct radeon_fpriv *fpriv = file_priv->driver_priv;
- struct radeon_bo_va *bo_va;
+ struct radeon_vm *vm = &fpriv->vm;
int r;
if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (!r) {
- bo_va = radeon_vm_bo_find(&fpriv->vm,
- rdev->ring_tmp_bo.bo);
- if (bo_va)
- radeon_vm_bo_rmv(rdev, bo_va);
+ if (vm->ib_bo_va)
+ radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
}
}
- radeon_vm_fini(rdev, &fpriv->vm);
+ radeon_vm_fini(rdev, vm);
kfree(fpriv);
file_priv->driver_priv = NULL;
}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index ad0e4b8cc7e3..e27608c29c11 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -46,6 +46,10 @@ struct radeon_device;
#define to_radeon_encoder(x) container_of(x, struct radeon_encoder, base)
#define to_radeon_framebuffer(x) container_of(x, struct radeon_framebuffer, base)
+#define RADEON_MAX_HPD_PINS 7
+#define RADEON_MAX_CRTCS 6
+#define RADEON_MAX_AFMT_BLOCKS 7
+
enum radeon_rmx_type {
RMX_OFF,
RMX_FULL,
@@ -233,8 +237,8 @@ struct radeon_mode_info {
struct card_info *atom_card_info;
enum radeon_connector_table connector_table;
bool mode_config_initialized;
- struct radeon_crtc *crtcs[6];
- struct radeon_afmt *afmt[7];
+ struct radeon_crtc *crtcs[RADEON_MAX_CRTCS];
+ struct radeon_afmt *afmt[RADEON_MAX_AFMT_BLOCKS];
/* DVI-I properties */
struct drm_property *coherent_mode_property;
/* DAC enable load detect */
@@ -302,6 +306,12 @@ struct radeon_atom_ss {
uint16_t amount;
};
+enum radeon_flip_status {
+ RADEON_FLIP_NONE,
+ RADEON_FLIP_PENDING,
+ RADEON_FLIP_SUBMITTED
+};
+
struct radeon_crtc {
struct drm_crtc base;
int crtc_id;
@@ -327,6 +337,7 @@ struct radeon_crtc {
/* page flipping */
struct workqueue_struct *flip_queue;
struct radeon_flip_work *flip_work;
+ enum radeon_flip_status flip_status;
/* pll sharing */
struct radeon_atom_ss ss;
bool ss_enabled;
@@ -674,10 +685,11 @@ extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder);
extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
-extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
extern int radeon_get_monitor_bpc(struct drm_connector *connector);
+extern struct edid *radeon_connector_edid(struct drm_connector *connector);
+
extern void radeon_connector_hotplug(struct drm_connector *connector);
extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,
struct drm_display_mode *mode);
@@ -727,7 +739,6 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux);
-extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 6c717b257d6d..480c87d8edc5 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -46,16 +46,6 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
* function are calling it.
*/
-static void radeon_bo_clear_va(struct radeon_bo *bo)
-{
- struct radeon_bo_va *bo_va, *tmp;
-
- list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) {
- /* remove from all vm address space */
- radeon_vm_bo_rmv(bo->rdev, bo_va);
- }
-}
-
static void radeon_update_memory_usage(struct radeon_bo *bo,
unsigned mem_type, int sign)
{
@@ -90,7 +80,7 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
list_del_init(&bo->list);
mutex_unlock(&bo->rdev->gem.mutex);
radeon_bo_clear_surface_reg(bo);
- radeon_bo_clear_va(bo);
+ WARN_ON(!list_empty(&bo->va));
drm_gem_object_release(&bo->gem_base);
kfree(bo);
}
@@ -114,15 +104,23 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
TTM_PL_FLAG_VRAM;
if (domain & RADEON_GEM_DOMAIN_GTT) {
- if (rbo->rdev->flags & RADEON_IS_AGP) {
- rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT;
+ if (rbo->flags & RADEON_GEM_GTT_UC) {
+ rbo->placements[c++] = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_TT;
+ } else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
+ (rbo->rdev->flags & RADEON_IS_AGP)) {
+ rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
+ TTM_PL_FLAG_TT;
} else {
rbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT;
}
}
if (domain & RADEON_GEM_DOMAIN_CPU) {
- if (rbo->rdev->flags & RADEON_IS_AGP) {
- rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_SYSTEM;
+ if (rbo->flags & RADEON_GEM_GTT_UC) {
+ rbo->placements[c++] = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_SYSTEM;
+ } else if ((rbo->flags & RADEON_GEM_GTT_WC) ||
+ rbo->rdev->flags & RADEON_IS_AGP) {
+ rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
+ TTM_PL_FLAG_SYSTEM;
} else {
rbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM;
}
@@ -146,7 +144,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
int radeon_bo_create(struct radeon_device *rdev,
unsigned long size, int byte_align, bool kernel, u32 domain,
- struct sg_table *sg, struct radeon_bo **bo_ptr)
+ u32 flags, struct sg_table *sg, struct radeon_bo **bo_ptr)
{
struct radeon_bo *bo;
enum ttm_bo_type type;
@@ -183,6 +181,12 @@ int radeon_bo_create(struct radeon_device *rdev,
bo->initial_domain = domain & (RADEON_GEM_DOMAIN_VRAM |
RADEON_GEM_DOMAIN_GTT |
RADEON_GEM_DOMAIN_CPU);
+
+ bo->flags = flags;
+ /* PCI GART is always snooped */
+ if (!(rdev->flags & RADEON_IS_PCIE))
+ bo->flags &= ~(RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC);
+
radeon_ttm_placement_from_domain(bo, domain);
/* Kernel allocation are uninterruptible */
down_read(&rdev->pm.mclk_lock);
@@ -232,6 +236,15 @@ void radeon_bo_kunmap(struct radeon_bo *bo)
ttm_bo_kunmap(&bo->kmap);
}
+struct radeon_bo *radeon_bo_ref(struct radeon_bo *bo)
+{
+ if (bo == NULL)
+ return NULL;
+
+ ttm_bo_reference(&bo->tbo);
+ return bo;
+}
+
void radeon_bo_unref(struct radeon_bo **bo)
{
struct ttm_buffer_object *tbo;
@@ -241,9 +254,7 @@ void radeon_bo_unref(struct radeon_bo **bo)
return;
rdev = (*bo)->rdev;
tbo = &((*bo)->tbo);
- down_read(&rdev->pm.mclk_lock);
ttm_bo_unref(&tbo);
- up_read(&rdev->pm.mclk_lock);
if (tbo == NULL)
*bo = NULL;
}
@@ -292,9 +303,13 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
bo->pin_count = 1;
if (gpu_addr != NULL)
*gpu_addr = radeon_bo_gpu_offset(bo);
- }
- if (unlikely(r != 0))
+ if (domain == RADEON_GEM_DOMAIN_VRAM)
+ bo->rdev->vram_pin_size += radeon_bo_size(bo);
+ else
+ bo->rdev->gart_pin_size += radeon_bo_size(bo);
+ } else {
dev_err(bo->rdev->dev, "%p pin failed\n", bo);
+ }
return r;
}
@@ -317,8 +332,14 @@ int radeon_bo_unpin(struct radeon_bo *bo)
for (i = 0; i < bo->placement.num_placement; i++)
bo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
- if (unlikely(r != 0))
+ if (likely(r == 0)) {
+ if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
+ bo->rdev->vram_pin_size -= radeon_bo_size(bo);
+ else
+ bo->rdev->gart_pin_size -= radeon_bo_size(bo);
+ } else {
dev_err(bo->rdev->dev, "%p validate failed for unpin\n", bo);
+ }
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 5a873f31a171..98a47fdf3625 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -124,11 +124,12 @@ extern int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
extern int radeon_bo_create(struct radeon_device *rdev,
unsigned long size, int byte_align,
- bool kernel, u32 domain,
+ bool kernel, u32 domain, u32 flags,
struct sg_table *sg,
struct radeon_bo **bo_ptr);
extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
extern void radeon_bo_kunmap(struct radeon_bo *bo);
+extern struct radeon_bo *radeon_bo_ref(struct radeon_bo *bo);
extern void radeon_bo_unref(struct radeon_bo **bo);
extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr);
extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain,
@@ -170,7 +171,8 @@ static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo)
extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
struct radeon_sa_manager *sa_manager,
- unsigned size, u32 align, u32 domain);
+ unsigned size, u32 align, u32 domain,
+ u32 flags);
extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
struct radeon_sa_manager *sa_manager);
extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 12c663e86ca1..23314be49480 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -73,8 +73,10 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev)
rdev->pm.dpm.ac_power = true;
else
rdev->pm.dpm.ac_power = false;
- if (rdev->asic->dpm.enable_bapm)
- radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power);
+ if (rdev->family == CHIP_ARUBA) {
+ if (rdev->asic->dpm.enable_bapm)
+ radeon_dpm_enable_bapm(rdev, rdev->pm.dpm.ac_power);
+ }
mutex_unlock(&rdev->pm.mutex);
} else if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
if (rdev->pm.profile == PM_PROFILE_AUTO) {
@@ -1301,10 +1303,6 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_RS780:
case CHIP_RS880:
case CHIP_RV770:
- case CHIP_BARTS:
- case CHIP_TURKS:
- case CHIP_CAICOS:
- case CHIP_CAYMAN:
/* DPM requires the RLC, RV770+ dGPU requires SMC */
if (!rdev->rlc_fw)
rdev->pm.pm_method = PM_METHOD_PROFILE;
@@ -1328,6 +1326,10 @@ int radeon_pm_init(struct radeon_device *rdev)
case CHIP_PALM:
case CHIP_SUMO:
case CHIP_SUMO2:
+ case CHIP_BARTS:
+ case CHIP_TURKS:
+ case CHIP_CAICOS:
+ case CHIP_CAYMAN:
case CHIP_ARUBA:
case CHIP_TAHITI:
case CHIP_PITCAIRN:
@@ -1398,9 +1400,7 @@ static void radeon_pm_fini_old(struct radeon_device *rdev)
}
radeon_hwmon_fini(rdev);
-
- if (rdev->pm.power_state)
- kfree(rdev->pm.power_state);
+ kfree(rdev->pm.power_state);
}
static void radeon_pm_fini_dpm(struct radeon_device *rdev)
@@ -1419,9 +1419,7 @@ static void radeon_pm_fini_dpm(struct radeon_device *rdev)
radeon_dpm_fini(rdev);
radeon_hwmon_fini(rdev);
-
- if (rdev->pm.power_state)
- kfree(rdev->pm.power_state);
+ kfree(rdev->pm.power_state);
}
void radeon_pm_fini(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c
index 20074560fc25..0b16f2cbcf17 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -65,7 +65,7 @@ struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev,
int ret;
ret = radeon_bo_create(rdev, size, PAGE_SIZE, false,
- RADEON_GEM_DOMAIN_GTT, sg, &bo);
+ RADEON_GEM_DOMAIN_GTT, 0, sg, &bo);
if (ret)
return ERR_PTR(ret);
@@ -103,3 +103,11 @@ void radeon_gem_prime_unpin(struct drm_gem_object *obj)
radeon_bo_unpin(bo);
radeon_bo_unreserve(bo);
}
+
+
+struct reservation_object *radeon_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+ struct radeon_bo *bo = gem_to_radeon_bo(obj);
+
+ return bo->tbo.resv;
+}
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index f8050f5429e2..5b4e0cf231a0 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -26,258 +26,8 @@
* Jerome Glisse
* Christian König
*/
-#include <linux/seq_file.h>
-#include <linux/slab.h>
#include <drm/drmP.h>
-#include <drm/radeon_drm.h>
-#include "radeon_reg.h"
#include "radeon.h"
-#include "atom.h"
-
-/*
- * IB
- * IBs (Indirect Buffers) and areas of GPU accessible memory where
- * commands are stored. You can put a pointer to the IB in the
- * command ring and the hw will fetch the commands from the IB
- * and execute them. Generally userspace acceleration drivers
- * produce command buffers which are send to the kernel and
- * put in IBs for execution by the requested ring.
- */
-static int radeon_debugfs_sa_init(struct radeon_device *rdev);
-
-/**
- * radeon_ib_get - request an IB (Indirect Buffer)
- *
- * @rdev: radeon_device pointer
- * @ring: ring index the IB is associated with
- * @ib: IB object returned
- * @size: requested IB size
- *
- * Request an IB (all asics). IBs are allocated using the
- * suballocator.
- * Returns 0 on success, error on failure.
- */
-int radeon_ib_get(struct radeon_device *rdev, int ring,
- struct radeon_ib *ib, struct radeon_vm *vm,
- unsigned size)
-{
- int r;
-
- r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256);
- if (r) {
- dev_err(rdev->dev, "failed to get a new IB (%d)\n", r);
- return r;
- }
-
- r = radeon_semaphore_create(rdev, &ib->semaphore);
- if (r) {
- return r;
- }
-
- ib->ring = ring;
- ib->fence = NULL;
- ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo);
- ib->vm = vm;
- if (vm) {
- /* ib pool is bound at RADEON_VA_IB_OFFSET in virtual address
- * space and soffset is the offset inside the pool bo
- */
- ib->gpu_addr = ib->sa_bo->soffset + RADEON_VA_IB_OFFSET;
- } else {
- ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo);
- }
- ib->is_const_ib = false;
-
- return 0;
-}
-
-/**
- * radeon_ib_free - free an IB (Indirect Buffer)
- *
- * @rdev: radeon_device pointer
- * @ib: IB object to free
- *
- * Free an IB (all asics).
- */
-void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib)
-{
- radeon_semaphore_free(rdev, &ib->semaphore, ib->fence);
- radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence);
- radeon_fence_unref(&ib->fence);
-}
-
-/**
- * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring
- *
- * @rdev: radeon_device pointer
- * @ib: IB object to schedule
- * @const_ib: Const IB to schedule (SI only)
- *
- * Schedule an IB on the associated ring (all asics).
- * Returns 0 on success, error on failure.
- *
- * On SI, there are two parallel engines fed from the primary ring,
- * the CE (Constant Engine) and the DE (Drawing Engine). Since
- * resource descriptors have moved to memory, the CE allows you to
- * prime the caches while the DE is updating register state so that
- * the resource descriptors will be already in cache when the draw is
- * processed. To accomplish this, the userspace driver submits two
- * IBs, one for the CE and one for the DE. If there is a CE IB (called
- * a CONST_IB), it will be put on the ring prior to the DE IB. Prior
- * to SI there was just a DE IB.
- */
-int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib,
- struct radeon_ib *const_ib)
-{
- struct radeon_ring *ring = &rdev->ring[ib->ring];
- int r = 0;
-
- if (!ib->length_dw || !ring->ready) {
- /* TODO: Nothings in the ib we should report. */
- dev_err(rdev->dev, "couldn't schedule ib\n");
- return -EINVAL;
- }
-
- /* 64 dwords should be enough for fence too */
- r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8);
- if (r) {
- dev_err(rdev->dev, "scheduling IB failed (%d).\n", r);
- return r;
- }
-
- /* grab a vm id if necessary */
- if (ib->vm) {
- struct radeon_fence *vm_id_fence;
- vm_id_fence = radeon_vm_grab_id(rdev, ib->vm, ib->ring);
- radeon_semaphore_sync_to(ib->semaphore, vm_id_fence);
- }
-
- /* sync with other rings */
- r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring);
- if (r) {
- dev_err(rdev->dev, "failed to sync rings (%d)\n", r);
- radeon_ring_unlock_undo(rdev, ring);
- return r;
- }
-
- if (ib->vm)
- radeon_vm_flush(rdev, ib->vm, ib->ring);
-
- if (const_ib) {
- radeon_ring_ib_execute(rdev, const_ib->ring, const_ib);
- radeon_semaphore_free(rdev, &const_ib->semaphore, NULL);
- }
- radeon_ring_ib_execute(rdev, ib->ring, ib);
- r = radeon_fence_emit(rdev, &ib->fence, ib->ring);
- if (r) {
- dev_err(rdev->dev, "failed to emit fence for new IB (%d)\n", r);
- radeon_ring_unlock_undo(rdev, ring);
- return r;
- }
- if (const_ib) {
- const_ib->fence = radeon_fence_ref(ib->fence);
- }
-
- if (ib->vm)
- radeon_vm_fence(rdev, ib->vm, ib->fence);
-
- radeon_ring_unlock_commit(rdev, ring);
- return 0;
-}
-
-/**
- * radeon_ib_pool_init - Init the IB (Indirect Buffer) pool
- *
- * @rdev: radeon_device pointer
- *
- * Initialize the suballocator to manage a pool of memory
- * for use as IBs (all asics).
- * Returns 0 on success, error on failure.
- */
-int radeon_ib_pool_init(struct radeon_device *rdev)
-{
- int r;
-
- if (rdev->ib_pool_ready) {
- return 0;
- }
- r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
- RADEON_IB_POOL_SIZE*64*1024,
- RADEON_GPU_PAGE_SIZE,
- RADEON_GEM_DOMAIN_GTT);
- if (r) {
- return r;
- }
-
- r = radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo);
- if (r) {
- return r;
- }
-
- rdev->ib_pool_ready = true;
- if (radeon_debugfs_sa_init(rdev)) {
- dev_err(rdev->dev, "failed to register debugfs file for SA\n");
- }
- return 0;
-}
-
-/**
- * radeon_ib_pool_fini - Free the IB (Indirect Buffer) pool
- *
- * @rdev: radeon_device pointer
- *
- * Tear down the suballocator managing the pool of memory
- * for use as IBs (all asics).
- */
-void radeon_ib_pool_fini(struct radeon_device *rdev)
-{
- if (rdev->ib_pool_ready) {
- radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo);
- radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo);
- rdev->ib_pool_ready = false;
- }
-}
-
-/**
- * radeon_ib_ring_tests - test IBs on the rings
- *
- * @rdev: radeon_device pointer
- *
- * Test an IB (Indirect Buffer) on each ring.
- * If the test fails, disable the ring.
- * Returns 0 on success, error if the primary GFX ring
- * IB test fails.
- */
-int radeon_ib_ring_tests(struct radeon_device *rdev)
-{
- unsigned i;
- int r;
-
- for (i = 0; i < RADEON_NUM_RINGS; ++i) {
- struct radeon_ring *ring = &rdev->ring[i];
-
- if (!ring->ready)
- continue;
-
- r = radeon_ib_test(rdev, i, ring);
- if (r) {
- ring->ready = false;
- rdev->needs_reset = false;
-
- if (i == RADEON_RING_TYPE_GFX_INDEX) {
- /* oh, oh, that's really bad */
- DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r);
- rdev->accel_working = false;
- return r;
-
- } else {
- /* still not good, but we can live with it */
- DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r);
- }
- }
- }
- return 0;
-}
/*
* Rings
@@ -433,11 +183,21 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig
*/
void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring)
{
+ /* If we are emitting the HDP flush via the ring buffer, we need to
+ * do it before padding.
+ */
+ if (rdev->asic->ring[ring->idx]->hdp_flush)
+ rdev->asic->ring[ring->idx]->hdp_flush(rdev, ring);
/* We pad to match fetch size */
while (ring->wptr & ring->align_mask) {
radeon_ring_write(ring, ring->nop);
}
mb();
+ /* If we are emitting the HDP flush via MMIO, we need to do it after
+ * all CPU writes to VRAM finished.
+ */
+ if (rdev->asic->mmio_hdp_flush)
+ rdev->asic->mmio_hdp_flush(rdev);
radeon_ring_set_wptr(rdev, ring);
}
@@ -641,6 +401,8 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig
if (ring->ring_obj == NULL) {
r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT,
+ (rdev->flags & RADEON_IS_PCIE) ?
+ RADEON_GEM_GTT_WC : 0,
NULL, &ring->ring_obj);
if (r) {
dev_err(rdev->dev, "(%d) ring create failed\n", r);
@@ -791,22 +553,6 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = {
{"radeon_ring_vce2", radeon_debugfs_ring_info, 0, &si_vce2_index},
};
-static int radeon_debugfs_sa_info(struct seq_file *m, void *data)
-{
- struct drm_info_node *node = (struct drm_info_node *) m->private;
- struct drm_device *dev = node->minor->dev;
- struct radeon_device *rdev = dev->dev_private;
-
- radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m);
-
- return 0;
-
-}
-
-static struct drm_info_list radeon_debugfs_sa_list[] = {
- {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL},
-};
-
#endif
static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring)
@@ -828,12 +574,3 @@ static int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ri
#endif
return 0;
}
-
-static int radeon_debugfs_sa_init(struct radeon_device *rdev)
-{
-#if defined(CONFIG_DEBUG_FS)
- return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1);
-#else
- return 0;
-#endif
-}
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c
index adcf3e2f07da..b84f97c8718c 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -49,7 +49,7 @@ static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager);
int radeon_sa_bo_manager_init(struct radeon_device *rdev,
struct radeon_sa_manager *sa_manager,
- unsigned size, u32 align, u32 domain)
+ unsigned size, u32 align, u32 domain, u32 flags)
{
int i, r;
@@ -65,7 +65,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev,
}
r = radeon_bo_create(rdev, size, align, true,
- domain, NULL, &sa_manager->bo);
+ domain, flags, NULL, &sa_manager->bo);
if (r) {
dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r);
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c
index 3a13e0d1055c..5adf4207453d 100644
--- a/drivers/gpu/drm/radeon/radeon_test.c
+++ b/drivers/gpu/drm/radeon/radeon_test.c
@@ -56,13 +56,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
/* Number of tests =
* (Total GTT - IB pool - writeback page - ring buffers) / test size
*/
- n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024;
- for (i = 0; i < RADEON_NUM_RINGS; ++i)
- n -= rdev->ring[i].ring_size;
- if (rdev->wb.wb_obj)
- n -= RADEON_GPU_PAGE_SIZE;
- if (rdev->ih.ring_obj)
- n -= rdev->ih.ring_size;
+ n = rdev->mc.gtt_size - rdev->gart_pin_size;
n /= size;
gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);
@@ -73,7 +67,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
}
r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
- NULL, &vram_obj);
+ 0, NULL, &vram_obj);
if (r) {
DRM_ERROR("Failed to create VRAM object\n");
goto out_cleanup;
@@ -93,7 +87,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
struct radeon_fence *fence = NULL;
r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_GTT, NULL, gtt_obj + i);
+ RADEON_GEM_DOMAIN_GTT, 0, NULL, gtt_obj + i);
if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i);
goto out_lclean;
diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h
index f749f2c3bbdb..9db74a96ef61 100644
--- a/drivers/gpu/drm/radeon/radeon_trace.h
+++ b/drivers/gpu/drm/radeon/radeon_trace.h
@@ -72,8 +72,8 @@ TRACE_EVENT(radeon_vm_bo_update,
),
TP_fast_assign(
- __entry->soffset = bo_va->soffset;
- __entry->eoffset = bo_va->eoffset;
+ __entry->soffset = bo_va->it.start;
+ __entry->eoffset = bo_va->it.last + 1;
__entry->flags = bo_va->flags;
),
TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x",
@@ -104,6 +104,24 @@ TRACE_EVENT(radeon_vm_set_page,
__entry->flags, __entry->count)
);
+TRACE_EVENT(radeon_vm_flush,
+ TP_PROTO(uint64_t pd_addr, unsigned ring, unsigned id),
+ TP_ARGS(pd_addr, ring, id),
+ TP_STRUCT__entry(
+ __field(u64, pd_addr)
+ __field(u32, ring)
+ __field(u32, id)
+ ),
+
+ TP_fast_assign(
+ __entry->pd_addr = pd_addr;
+ __entry->ring = ring;
+ __entry->id = id;
+ ),
+ TP_printk("pd_addr=%010Lx, ring=%u, id=%u",
+ __entry->pd_addr, __entry->ring, __entry->id)
+);
+
DECLARE_EVENT_CLASS(radeon_fence_request,
TP_PROTO(struct drm_device *dev, int ring, u32 seqno),
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index c8a8a5144ec1..72afe82a95c9 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -521,6 +521,8 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
struct ttm_mem_reg *bo_mem)
{
struct radeon_ttm_tt *gtt = (void*)ttm;
+ uint32_t flags = RADEON_GART_PAGE_VALID | RADEON_GART_PAGE_READ |
+ RADEON_GART_PAGE_WRITE;
int r;
gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT);
@@ -528,8 +530,10 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
ttm->num_pages, bo_mem, ttm);
}
- r = radeon_gart_bind(gtt->rdev, gtt->offset,
- ttm->num_pages, ttm->pages, gtt->ttm.dma_address);
+ if (ttm->caching_state == tt_cached)
+ flags |= RADEON_GART_PAGE_SNOOP;
+ r = radeon_gart_bind(gtt->rdev, gtt->offset, ttm->num_pages,
+ ttm->pages, gtt->ttm.dma_address, flags);
if (r) {
DRM_ERROR("failed to bind %lu pages at 0x%08X\n",
ttm->num_pages, (unsigned)gtt->offset);
@@ -726,7 +730,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM,
+ RADEON_GEM_DOMAIN_VRAM, 0,
NULL, &rdev->stollen_vga_memory);
if (r) {
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.c b/drivers/gpu/drm/radeon/radeon_ucode.c
new file mode 100644
index 000000000000..6beec680390c
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_ucode.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2014 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 <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include "radeon.h"
+#include "radeon_ucode.h"
+
+static void radeon_ucode_print_common_hdr(const struct common_firmware_header *hdr)
+{
+ DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes));
+ DRM_DEBUG("header_size_bytes: %u\n", le32_to_cpu(hdr->header_size_bytes));
+ DRM_DEBUG("header_version_major: %u\n", le16_to_cpu(hdr->header_version_major));
+ DRM_DEBUG("header_version_minor: %u\n", le16_to_cpu(hdr->header_version_minor));
+ DRM_DEBUG("ip_version_major: %u\n", le16_to_cpu(hdr->ip_version_major));
+ DRM_DEBUG("ip_version_minor: %u\n", le16_to_cpu(hdr->ip_version_minor));
+ DRM_DEBUG("ucode_version: 0x%08x\n", le32_to_cpu(hdr->ucode_version));
+ DRM_DEBUG("ucode_size_bytes: %u\n", le32_to_cpu(hdr->ucode_size_bytes));
+ DRM_DEBUG("ucode_array_offset_bytes: %u\n",
+ le32_to_cpu(hdr->ucode_array_offset_bytes));
+ DRM_DEBUG("crc32: 0x%08x\n", le32_to_cpu(hdr->crc32));
+}
+
+void radeon_ucode_print_mc_hdr(const struct common_firmware_header *hdr)
+{
+ uint16_t version_major = le16_to_cpu(hdr->header_version_major);
+ uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
+
+ DRM_DEBUG("MC\n");
+ radeon_ucode_print_common_hdr(hdr);
+
+ if (version_major == 1) {
+ const struct mc_firmware_header_v1_0 *mc_hdr =
+ container_of(hdr, struct mc_firmware_header_v1_0, header);
+
+ DRM_DEBUG("io_debug_size_bytes: %u\n",
+ le32_to_cpu(mc_hdr->io_debug_size_bytes));
+ DRM_DEBUG("io_debug_array_offset_bytes: %u\n",
+ le32_to_cpu(mc_hdr->io_debug_array_offset_bytes));
+ } else {
+ DRM_ERROR("Unknown MC ucode version: %u.%u\n", version_major, version_minor);
+ }
+}
+
+void radeon_ucode_print_smc_hdr(const struct common_firmware_header *hdr)
+{
+ uint16_t version_major = le16_to_cpu(hdr->header_version_major);
+ uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
+
+ DRM_DEBUG("SMC\n");
+ radeon_ucode_print_common_hdr(hdr);
+
+ if (version_major == 1) {
+ const struct smc_firmware_header_v1_0 *smc_hdr =
+ container_of(hdr, struct smc_firmware_header_v1_0, header);
+
+ DRM_DEBUG("ucode_start_addr: %u\n", le32_to_cpu(smc_hdr->ucode_start_addr));
+ } else {
+ DRM_ERROR("Unknown SMC ucode version: %u.%u\n", version_major, version_minor);
+ }
+}
+
+void radeon_ucode_print_gfx_hdr(const struct common_firmware_header *hdr)
+{
+ uint16_t version_major = le16_to_cpu(hdr->header_version_major);
+ uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
+
+ DRM_DEBUG("GFX\n");
+ radeon_ucode_print_common_hdr(hdr);
+
+ if (version_major == 1) {
+ const struct gfx_firmware_header_v1_0 *gfx_hdr =
+ container_of(hdr, struct gfx_firmware_header_v1_0, header);
+
+ DRM_DEBUG("ucode_feature_version: %u\n",
+ le32_to_cpu(gfx_hdr->ucode_feature_version));
+ DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(gfx_hdr->jt_offset));
+ DRM_DEBUG("jt_size: %u\n", le32_to_cpu(gfx_hdr->jt_size));
+ } else {
+ DRM_ERROR("Unknown GFX ucode version: %u.%u\n", version_major, version_minor);
+ }
+}
+
+void radeon_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
+{
+ uint16_t version_major = le16_to_cpu(hdr->header_version_major);
+ uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
+
+ DRM_DEBUG("RLC\n");
+ radeon_ucode_print_common_hdr(hdr);
+
+ if (version_major == 1) {
+ const struct rlc_firmware_header_v1_0 *rlc_hdr =
+ container_of(hdr, struct rlc_firmware_header_v1_0, header);
+
+ DRM_DEBUG("ucode_feature_version: %u\n",
+ le32_to_cpu(rlc_hdr->ucode_feature_version));
+ DRM_DEBUG("save_and_restore_offset: %u\n",
+ le32_to_cpu(rlc_hdr->save_and_restore_offset));
+ DRM_DEBUG("clear_state_descriptor_offset: %u\n",
+ le32_to_cpu(rlc_hdr->clear_state_descriptor_offset));
+ DRM_DEBUG("avail_scratch_ram_locations: %u\n",
+ le32_to_cpu(rlc_hdr->avail_scratch_ram_locations));
+ DRM_DEBUG("master_pkt_description_offset: %u\n",
+ le32_to_cpu(rlc_hdr->master_pkt_description_offset));
+ } else {
+ DRM_ERROR("Unknown RLC ucode version: %u.%u\n", version_major, version_minor);
+ }
+}
+
+void radeon_ucode_print_sdma_hdr(const struct common_firmware_header *hdr)
+{
+ uint16_t version_major = le16_to_cpu(hdr->header_version_major);
+ uint16_t version_minor = le16_to_cpu(hdr->header_version_minor);
+
+ DRM_DEBUG("SDMA\n");
+ radeon_ucode_print_common_hdr(hdr);
+
+ if (version_major == 1) {
+ const struct sdma_firmware_header_v1_0 *sdma_hdr =
+ container_of(hdr, struct sdma_firmware_header_v1_0, header);
+
+ DRM_DEBUG("ucode_feature_version: %u\n",
+ le32_to_cpu(sdma_hdr->ucode_feature_version));
+ DRM_DEBUG("ucode_change_version: %u\n",
+ le32_to_cpu(sdma_hdr->ucode_change_version));
+ DRM_DEBUG("jt_offset: %u\n", le32_to_cpu(sdma_hdr->jt_offset));
+ DRM_DEBUG("jt_size: %u\n", le32_to_cpu(sdma_hdr->jt_size));
+ } else {
+ DRM_ERROR("Unknown SDMA ucode version: %u.%u\n",
+ version_major, version_minor);
+ }
+}
+
+int radeon_ucode_validate(const struct firmware *fw)
+{
+ const struct common_firmware_header *hdr =
+ (const struct common_firmware_header *)fw->data;
+
+ if (fw->size == le32_to_cpu(hdr->size_bytes))
+ return 0;
+
+ return -EINVAL;
+}
+
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
index 4e7c3269b183..dc4576e4d8ad 100644
--- a/drivers/gpu/drm/radeon/radeon_ucode.h
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -153,4 +153,75 @@
#define HAWAII_SMC_UCODE_START 0x20000
#define HAWAII_SMC_UCODE_SIZE 0x1FDEC
+struct common_firmware_header {
+ uint32_t size_bytes; /* size of the entire header+image(s) in bytes */
+ uint32_t header_size_bytes; /* size of just the header in bytes */
+ uint16_t header_version_major; /* header version */
+ uint16_t header_version_minor; /* header version */
+ uint16_t ip_version_major; /* IP version */
+ uint16_t ip_version_minor; /* IP version */
+ uint32_t ucode_version;
+ uint32_t ucode_size_bytes; /* size of ucode in bytes */
+ uint32_t ucode_array_offset_bytes; /* payload offset from the start of the header */
+ uint32_t crc32; /* crc32 checksum of the payload */
+};
+
+/* version_major=1, version_minor=0 */
+struct mc_firmware_header_v1_0 {
+ struct common_firmware_header header;
+ uint32_t io_debug_size_bytes; /* size of debug array in dwords */
+ uint32_t io_debug_array_offset_bytes; /* payload offset from the start of the header */
+};
+
+/* version_major=1, version_minor=0 */
+struct smc_firmware_header_v1_0 {
+ struct common_firmware_header header;
+ uint32_t ucode_start_addr;
+};
+
+/* version_major=1, version_minor=0 */
+struct gfx_firmware_header_v1_0 {
+ struct common_firmware_header header;
+ uint32_t ucode_feature_version;
+ uint32_t jt_offset; /* jt location */
+ uint32_t jt_size; /* size of jt */
+};
+
+/* version_major=1, version_minor=0 */
+struct rlc_firmware_header_v1_0 {
+ struct common_firmware_header header;
+ uint32_t ucode_feature_version;
+ uint32_t save_and_restore_offset;
+ uint32_t clear_state_descriptor_offset;
+ uint32_t avail_scratch_ram_locations;
+ uint32_t master_pkt_description_offset;
+};
+
+/* version_major=1, version_minor=0 */
+struct sdma_firmware_header_v1_0 {
+ struct common_firmware_header header;
+ uint32_t ucode_feature_version;
+ uint32_t ucode_change_version;
+ uint32_t jt_offset; /* jt location */
+ uint32_t jt_size; /* size of jt */
+};
+
+/* header is fixed size */
+union radeon_firmware_header {
+ struct common_firmware_header common;
+ struct mc_firmware_header_v1_0 mc;
+ struct smc_firmware_header_v1_0 smc;
+ struct gfx_firmware_header_v1_0 gfx;
+ struct rlc_firmware_header_v1_0 rlc;
+ struct sdma_firmware_header_v1_0 sdma;
+ uint8_t raw[0x100];
+};
+
+void radeon_ucode_print_mc_hdr(const struct common_firmware_header *hdr);
+void radeon_ucode_print_smc_hdr(const struct common_firmware_header *hdr);
+void radeon_ucode_print_gfx_hdr(const struct common_firmware_header *hdr);
+void radeon_ucode_print_rlc_hdr(const struct common_firmware_header *hdr);
+void radeon_ucode_print_sdma_hdr(const struct common_firmware_header *hdr);
+int radeon_ucode_validate(const struct firmware *fw);
+
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c
index a4ad270e8261..6bf55ec85b62 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -117,7 +117,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->uvd.vcpu_bo);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL, &rdev->uvd.vcpu_bo);
if (r) {
dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r);
return r;
@@ -674,7 +674,7 @@ int radeon_uvd_get_create_msg(struct radeon_device *rdev, int ring,
int r, i;
r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &bo);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL, &bo);
if (r)
return r;
@@ -720,7 +720,7 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
int r, i;
r = radeon_bo_create(rdev, 1024, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &bo);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL, &bo);
if (r)
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
index aa21c31a846c..f9b70a43aa52 100644
--- a/drivers/gpu/drm/radeon/radeon_vce.c
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -126,7 +126,7 @@ int radeon_vce_init(struct radeon_device *rdev)
size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) +
RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE;
r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
- RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo);
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL, &rdev->vce.vcpu_bo);
if (r) {
dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r);
return r;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 899d9126cad6..ccae4d9dc3de 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -238,8 +238,8 @@ void radeon_vm_flush(struct radeon_device *rdev,
uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
/* if we can't remember our last VM flush then flush now! */
- /* XXX figure out why we have to flush all the time */
- if (!vm->last_flush || true || pd_addr != vm->pd_gpu_addr) {
+ if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) {
+ trace_radeon_vm_flush(pd_addr, ring, vm->id);
vm->pd_gpu_addr = pd_addr;
radeon_ring_vm_flush(rdev, ring, vm);
}
@@ -325,16 +325,15 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
}
bo_va->vm = vm;
bo_va->bo = bo;
- bo_va->soffset = 0;
- bo_va->eoffset = 0;
+ bo_va->it.start = 0;
+ bo_va->it.last = 0;
bo_va->flags = 0;
- bo_va->valid = false;
+ bo_va->addr = 0;
bo_va->ref_count = 1;
INIT_LIST_HEAD(&bo_va->bo_list);
- INIT_LIST_HEAD(&bo_va->vm_list);
+ INIT_LIST_HEAD(&bo_va->vm_status);
mutex_lock(&vm->mutex);
- list_add(&bo_va->vm_list, &vm->va);
list_add_tail(&bo_va->bo_list, &bo->va);
mutex_unlock(&vm->mutex);
@@ -342,6 +341,42 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev,
}
/**
+ * radeon_vm_set_pages - helper to call the right asic function
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: hw access flags
+ *
+ * Traces the parameters and calls the right asic functions
+ * to setup the page table using the DMA.
+ */
+static void radeon_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ trace_radeon_vm_set_page(pe, addr, count, incr, flags);
+
+ if ((flags & R600_PTE_GART_MASK) == R600_PTE_GART_MASK) {
+ uint64_t src = rdev->gart.table_addr + (addr >> 12) * 8;
+ radeon_asic_vm_copy_pages(rdev, ib, pe, src, count);
+
+ } else if ((flags & R600_PTE_SYSTEM) || (count < 3)) {
+ radeon_asic_vm_write_pages(rdev, ib, pe, addr,
+ count, incr, flags);
+
+ } else {
+ radeon_asic_vm_set_pages(rdev, ib, pe, addr,
+ count, incr, flags);
+ }
+}
+
+/**
* radeon_vm_clear_bo - initially clear the page dir/table
*
* @rdev: radeon_device pointer
@@ -375,14 +410,15 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev,
addr = radeon_bo_gpu_offset(bo);
entries = radeon_bo_size(bo) / 8;
- r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib,
- NULL, entries * 2 + 64);
+ r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256);
if (r)
goto error;
ib.length_dw = 0;
- radeon_asic_vm_set_page(rdev, &ib, addr, 0, entries, 0, 0);
+ radeon_vm_set_pages(rdev, &ib, addr, 0, entries, 0, 0);
+ radeon_asic_vm_pad_ib(rdev, &ib);
+ WARN_ON(ib.length_dw > 64);
r = radeon_ib_schedule(rdev, &ib, NULL);
if (r)
@@ -418,11 +454,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
uint32_t flags)
{
uint64_t size = radeon_bo_size(bo_va->bo);
- uint64_t eoffset, last_offset = 0;
struct radeon_vm *vm = bo_va->vm;
- struct radeon_bo_va *tmp;
- struct list_head *head;
unsigned last_pfn, pt_idx;
+ uint64_t eoffset;
int r;
if (soffset) {
@@ -444,38 +478,49 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
}
mutex_lock(&vm->mutex);
- head = &vm->va;
- last_offset = 0;
- list_for_each_entry(tmp, &vm->va, vm_list) {
- if (bo_va == tmp) {
- /* skip over currently modified bo */
- continue;
+ if (bo_va->it.start || bo_va->it.last) {
+ if (bo_va->addr) {
+ /* add a clone of the bo_va to clear the old address */
+ struct radeon_bo_va *tmp;
+ tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL);
+ tmp->it.start = bo_va->it.start;
+ tmp->it.last = bo_va->it.last;
+ tmp->vm = vm;
+ tmp->addr = bo_va->addr;
+ tmp->bo = radeon_bo_ref(bo_va->bo);
+ list_add(&tmp->vm_status, &vm->freed);
}
- if (soffset >= last_offset && eoffset <= tmp->soffset) {
- /* bo can be added before this one */
- break;
- }
- if (eoffset > tmp->soffset && soffset < tmp->eoffset) {
+ interval_tree_remove(&bo_va->it, &vm->va);
+ bo_va->it.start = 0;
+ bo_va->it.last = 0;
+ }
+
+ soffset /= RADEON_GPU_PAGE_SIZE;
+ eoffset /= RADEON_GPU_PAGE_SIZE;
+ if (soffset || eoffset) {
+ struct interval_tree_node *it;
+ it = interval_tree_iter_first(&vm->va, soffset, eoffset - 1);
+ if (it) {
+ struct radeon_bo_va *tmp;
+ tmp = container_of(it, struct radeon_bo_va, it);
/* bo and tmp overlap, invalid offset */
- dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n",
- bo_va->bo, (unsigned)bo_va->soffset, tmp->bo,
- (unsigned)tmp->soffset, (unsigned)tmp->eoffset);
+ dev_err(rdev->dev, "bo %p va 0x%010Lx conflict with "
+ "(bo %p 0x%010lx 0x%010lx)\n", bo_va->bo,
+ soffset, tmp->bo, tmp->it.start, tmp->it.last);
mutex_unlock(&vm->mutex);
return -EINVAL;
}
- last_offset = tmp->eoffset;
- head = &tmp->vm_list;
+ bo_va->it.start = soffset;
+ bo_va->it.last = eoffset - 1;
+ interval_tree_insert(&bo_va->it, &vm->va);
}
- bo_va->soffset = soffset;
- bo_va->eoffset = eoffset;
bo_va->flags = flags;
- bo_va->valid = false;
- list_move(&bo_va->vm_list, head);
+ bo_va->addr = 0;
- soffset = (soffset / RADEON_GPU_PAGE_SIZE) >> radeon_vm_block_size;
- eoffset = (eoffset / RADEON_GPU_PAGE_SIZE) >> radeon_vm_block_size;
+ soffset >>= radeon_vm_block_size;
+ eoffset >>= radeon_vm_block_size;
BUG_ON(eoffset >= radeon_vm_num_pdes(rdev));
@@ -495,8 +540,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
mutex_unlock(&vm->mutex);
r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8,
- RADEON_GPU_PAGE_SIZE, false,
- RADEON_GEM_DOMAIN_VRAM, NULL, &pt);
+ RADEON_GPU_PAGE_SIZE, true,
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL, &pt);
if (r)
return r;
@@ -597,7 +642,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
ndw = 64;
/* assume the worst case */
- ndw += vm->max_pde_used * 16;
+ ndw += vm->max_pde_used * 6;
/* update too big for an IB */
if (ndw > 0xfffff)
@@ -626,9 +671,9 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
((last_pt + incr * count) != pt)) {
if (count) {
- radeon_asic_vm_set_page(rdev, &ib, last_pde,
- last_pt, count, incr,
- R600_PTE_VALID);
+ radeon_vm_set_pages(rdev, &ib, last_pde,
+ last_pt, count, incr,
+ R600_PTE_VALID);
}
count = 1;
@@ -640,12 +685,14 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
}
if (count)
- radeon_asic_vm_set_page(rdev, &ib, last_pde, last_pt, count,
- incr, R600_PTE_VALID);
+ radeon_vm_set_pages(rdev, &ib, last_pde, last_pt, count,
+ incr, R600_PTE_VALID);
if (ib.length_dw != 0) {
+ radeon_asic_vm_pad_ib(rdev, &ib);
radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj);
radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use);
+ WARN_ON(ib.length_dw > ndw);
r = radeon_ib_schedule(rdev, &ib, NULL);
if (r) {
radeon_ib_free(rdev, &ib);
@@ -711,30 +758,30 @@ static void radeon_vm_frag_ptes(struct radeon_device *rdev,
(frag_start >= frag_end)) {
count = (pe_end - pe_start) / 8;
- radeon_asic_vm_set_page(rdev, ib, pe_start, addr, count,
- RADEON_GPU_PAGE_SIZE, flags);
+ radeon_vm_set_pages(rdev, ib, pe_start, addr, count,
+ RADEON_GPU_PAGE_SIZE, flags);
return;
}
/* handle the 4K area at the beginning */
if (pe_start != frag_start) {
count = (frag_start - pe_start) / 8;
- radeon_asic_vm_set_page(rdev, ib, pe_start, addr, count,
- RADEON_GPU_PAGE_SIZE, flags);
+ radeon_vm_set_pages(rdev, ib, pe_start, addr, count,
+ RADEON_GPU_PAGE_SIZE, flags);
addr += RADEON_GPU_PAGE_SIZE * count;
}
/* handle the area in the middle */
count = (frag_end - frag_start) / 8;
- radeon_asic_vm_set_page(rdev, ib, frag_start, addr, count,
- RADEON_GPU_PAGE_SIZE, flags | frag_flags);
+ radeon_vm_set_pages(rdev, ib, frag_start, addr, count,
+ RADEON_GPU_PAGE_SIZE, flags | frag_flags);
/* handle the 4K area at the end */
if (frag_end != pe_end) {
addr += RADEON_GPU_PAGE_SIZE * count;
count = (pe_end - frag_end) / 8;
- radeon_asic_vm_set_page(rdev, ib, frag_end, addr, count,
- RADEON_GPU_PAGE_SIZE, flags);
+ radeon_vm_set_pages(rdev, ib, frag_end, addr, count,
+ RADEON_GPU_PAGE_SIZE, flags);
}
}
@@ -763,9 +810,6 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
unsigned count = 0;
uint64_t addr;
- start = start / RADEON_GPU_PAGE_SIZE;
- end = end / RADEON_GPU_PAGE_SIZE;
-
/* walk over the address space and update the page tables */
for (addr = start; addr < end; ) {
uint64_t pt_idx = addr >> radeon_vm_block_size;
@@ -823,66 +867,78 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
* Object have to be reserved and mutex must be locked!
*/
int radeon_vm_bo_update(struct radeon_device *rdev,
- struct radeon_vm *vm,
- struct radeon_bo *bo,
+ struct radeon_bo_va *bo_va,
struct ttm_mem_reg *mem)
{
+ struct radeon_vm *vm = bo_va->vm;
struct radeon_ib ib;
- struct radeon_bo_va *bo_va;
- unsigned nptes, ndw;
+ unsigned nptes, ncmds, ndw;
uint64_t addr;
+ uint32_t flags;
int r;
- bo_va = radeon_vm_bo_find(vm, bo);
- if (bo_va == NULL) {
- dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm);
- return -EINVAL;
- }
-
- if (!bo_va->soffset) {
+ if (!bo_va->it.start) {
dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n",
- bo, vm);
+ bo_va->bo, vm);
return -EINVAL;
}
- if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL))
- return 0;
+ list_del_init(&bo_va->vm_status);
bo_va->flags &= ~RADEON_VM_PAGE_VALID;
bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
+ bo_va->flags &= ~RADEON_VM_PAGE_SNOOPED;
if (mem) {
addr = mem->start << PAGE_SHIFT;
if (mem->mem_type != TTM_PL_SYSTEM) {
bo_va->flags |= RADEON_VM_PAGE_VALID;
- bo_va->valid = true;
}
if (mem->mem_type == TTM_PL_TT) {
bo_va->flags |= RADEON_VM_PAGE_SYSTEM;
+ if (!(bo_va->bo->flags & (RADEON_GEM_GTT_WC | RADEON_GEM_GTT_UC)))
+ bo_va->flags |= RADEON_VM_PAGE_SNOOPED;
+
} else {
addr += rdev->vm_manager.vram_base_offset;
}
} else {
addr = 0;
- bo_va->valid = false;
}
+ if (addr == bo_va->addr)
+ return 0;
+ bo_va->addr = addr;
+
trace_radeon_vm_bo_update(bo_va);
- nptes = radeon_bo_ngpu_pages(bo);
+ nptes = bo_va->it.last - bo_va->it.start + 1;
+
+ /* reserve space for one command every (1 << BLOCK_SIZE) entries
+ or 2k dwords (whatever is smaller) */
+ ncmds = (nptes >> min(radeon_vm_block_size, 11)) + 1;
/* padding, etc. */
ndw = 64;
- if (radeon_vm_block_size > 11)
- /* reserve space for one header for every 2k dwords */
- ndw += (nptes >> 11) * 4;
- else
- /* reserve space for one header for
- every (1 << BLOCK_SIZE) entries */
- ndw += (nptes >> radeon_vm_block_size) * 4;
+ flags = radeon_vm_page_flags(bo_va->flags);
+ if ((flags & R600_PTE_GART_MASK) == R600_PTE_GART_MASK) {
+ /* only copy commands needed */
+ ndw += ncmds * 7;
+
+ } else if (flags & R600_PTE_SYSTEM) {
+ /* header for write data commands */
+ ndw += ncmds * 4;
- /* reserve space for pte addresses */
- ndw += nptes * 2;
+ /* body of write data command */
+ ndw += nptes * 2;
+
+ } else {
+ /* set page commands needed */
+ ndw += ncmds * 10;
+
+ /* two extra commands for begin/end of fragment */
+ ndw += 2 * 10;
+ }
/* update too big for an IB */
if (ndw > 0xfffff)
@@ -893,8 +949,12 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
return r;
ib.length_dw = 0;
- radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset,
- addr, radeon_vm_page_flags(bo_va->flags));
+ radeon_vm_update_ptes(rdev, vm, &ib, bo_va->it.start,
+ bo_va->it.last + 1, addr,
+ radeon_vm_page_flags(bo_va->flags));
+
+ radeon_asic_vm_pad_ib(rdev, &ib);
+ WARN_ON(ib.length_dw > ndw);
radeon_semaphore_sync_to(ib.semaphore, vm->fence);
r = radeon_ib_schedule(rdev, &ib, NULL);
@@ -911,33 +971,87 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
}
/**
+ * radeon_vm_clear_freed - clear freed BOs in the PT
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ *
+ * Make sure all freed BOs are cleared in the PT.
+ * Returns 0 for success.
+ *
+ * PTs have to be reserved and mutex must be locked!
+ */
+int radeon_vm_clear_freed(struct radeon_device *rdev,
+ struct radeon_vm *vm)
+{
+ struct radeon_bo_va *bo_va, *tmp;
+ int r;
+
+ list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
+ r = radeon_vm_bo_update(rdev, bo_va, NULL);
+ radeon_bo_unref(&bo_va->bo);
+ kfree(bo_va);
+ if (r)
+ return r;
+ }
+ return 0;
+
+}
+
+/**
+ * radeon_vm_clear_invalids - clear invalidated BOs in the PT
+ *
+ * @rdev: radeon_device pointer
+ * @vm: requested vm
+ *
+ * Make sure all invalidated BOs are cleared in the PT.
+ * Returns 0 for success.
+ *
+ * PTs have to be reserved and mutex must be locked!
+ */
+int radeon_vm_clear_invalids(struct radeon_device *rdev,
+ struct radeon_vm *vm)
+{
+ struct radeon_bo_va *bo_va, *tmp;
+ int r;
+
+ list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) {
+ r = radeon_vm_bo_update(rdev, bo_va, NULL);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+/**
* radeon_vm_bo_rmv - remove a bo to a specific vm
*
* @rdev: radeon_device pointer
* @bo_va: requested bo_va
*
* Remove @bo_va->bo from the requested vm (cayman+).
- * Remove @bo_va->bo from the list of bos associated with the bo_va->vm and
- * remove the ptes for @bo_va in the page table.
- * Returns 0 for success.
*
* Object have to be reserved!
*/
-int radeon_vm_bo_rmv(struct radeon_device *rdev,
- struct radeon_bo_va *bo_va)
+void radeon_vm_bo_rmv(struct radeon_device *rdev,
+ struct radeon_bo_va *bo_va)
{
- int r = 0;
-
- mutex_lock(&bo_va->vm->mutex);
- if (bo_va->soffset)
- r = radeon_vm_bo_update(rdev, bo_va->vm, bo_va->bo, NULL);
+ struct radeon_vm *vm = bo_va->vm;
- list_del(&bo_va->vm_list);
- mutex_unlock(&bo_va->vm->mutex);
list_del(&bo_va->bo_list);
- kfree(bo_va);
- return r;
+ mutex_lock(&vm->mutex);
+ interval_tree_remove(&bo_va->it, &vm->va);
+ list_del(&bo_va->vm_status);
+
+ if (bo_va->addr) {
+ bo_va->bo = radeon_bo_ref(bo_va->bo);
+ list_add(&bo_va->vm_status, &vm->freed);
+ } else {
+ kfree(bo_va);
+ }
+
+ mutex_unlock(&vm->mutex);
}
/**
@@ -955,7 +1069,12 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
struct radeon_bo_va *bo_va;
list_for_each_entry(bo_va, &bo->va, bo_list) {
- bo_va->valid = false;
+ if (bo_va->addr) {
+ mutex_lock(&bo_va->vm->mutex);
+ list_del(&bo_va->vm_status);
+ list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
+ mutex_unlock(&bo_va->vm->mutex);
+ }
}
}
@@ -975,11 +1094,14 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
int r;
vm->id = 0;
+ vm->ib_bo_va = NULL;
vm->fence = NULL;
vm->last_flush = NULL;
vm->last_id_use = NULL;
mutex_init(&vm->mutex);
- INIT_LIST_HEAD(&vm->va);
+ vm->va = RB_ROOT;
+ INIT_LIST_HEAD(&vm->invalidated);
+ INIT_LIST_HEAD(&vm->freed);
pd_size = radeon_vm_directory_size(rdev);
pd_entries = radeon_vm_num_pdes(rdev);
@@ -992,8 +1114,8 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
return -ENOMEM;
}
- r = radeon_bo_create(rdev, pd_size, align, false,
- RADEON_GEM_DOMAIN_VRAM, NULL,
+ r = radeon_bo_create(rdev, pd_size, align, true,
+ RADEON_GEM_DOMAIN_VRAM, 0, NULL,
&vm->page_directory);
if (r)
return r;
@@ -1022,11 +1144,11 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
struct radeon_bo_va *bo_va, *tmp;
int i, r;
- if (!list_empty(&vm->va)) {
+ if (!RB_EMPTY_ROOT(&vm->va)) {
dev_err(rdev->dev, "still active bo inside vm\n");
}
- list_for_each_entry_safe(bo_va, tmp, &vm->va, vm_list) {
- list_del_init(&bo_va->vm_list);
+ rbtree_postorder_for_each_entry_safe(bo_va, tmp, &vm->va, it.rb) {
+ interval_tree_remove(&bo_va->it, &vm->va);
r = radeon_bo_reserve(bo_va->bo, false);
if (!r) {
list_del_init(&bo_va->bo_list);
@@ -1034,7 +1156,10 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
kfree(bo_va);
}
}
-
+ list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
+ radeon_bo_unref(&bo_va->bo);
+ kfree(bo_va);
+ }
for (i = 0; i < radeon_vm_num_pdes(rdev); i++)
radeon_bo_unref(&vm->page_tables[i].bo);
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a0f96decece3..6c1fc339d228 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -109,7 +109,6 @@ int rs400_gart_enable(struct radeon_device *rdev)
uint32_t size_reg;
uint32_t tmp;
- radeon_gart_restore(rdev);
tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
WREG32_MC(RS690_AIC_CTRL_SCRATCH, tmp);
@@ -209,17 +208,24 @@ void rs400_gart_fini(struct radeon_device *rdev)
radeon_gart_table_ram_free(rdev);
}
+#define RS400_PTE_UNSNOOPED (1 << 0)
#define RS400_PTE_WRITEABLE (1 << 2)
#define RS400_PTE_READABLE (1 << 3)
-void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, uint64_t addr)
+void rs400_gart_set_page(struct radeon_device *rdev, unsigned i,
+ uint64_t addr, uint32_t flags)
{
uint32_t entry;
u32 *gtt = rdev->gart.ptr;
entry = (lower_32_bits(addr) & PAGE_MASK) |
- ((upper_32_bits(addr) & 0xff) << 4) |
- RS400_PTE_WRITEABLE | RS400_PTE_READABLE;
+ ((upper_32_bits(addr) & 0xff) << 4);
+ if (flags & RADEON_GART_PAGE_READ)
+ addr |= RS400_PTE_READABLE;
+ if (flags & RADEON_GART_PAGE_WRITE)
+ addr |= RS400_PTE_WRITEABLE;
+ if (!(flags & RADEON_GART_PAGE_SNOOP))
+ entry |= RS400_PTE_UNSNOOPED;
entry = cpu_to_le32(entry);
gtt[i] = entry;
}
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index d1a35cb1c91d..5f6db4629aaa 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -555,7 +555,6 @@ static int rs600_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Enable bus master */
tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
WREG32(RADEON_BUS_CNTL, tmp);
@@ -626,15 +625,21 @@ static void rs600_gart_fini(struct radeon_device *rdev)
radeon_gart_table_vram_free(rdev);
}
-void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, uint64_t addr)
+void rs600_gart_set_page(struct radeon_device *rdev, unsigned i,
+ uint64_t addr, uint32_t flags)
{
void __iomem *ptr = (void *)rdev->gart.ptr;
addr = addr & 0xFFFFFFFFFFFFF000ULL;
- if (addr == rdev->dummy_page.addr)
- addr |= R600_PTE_SYSTEM | R600_PTE_SNOOPED;
- else
- addr |= R600_PTE_GART;
+ addr |= R600_PTE_SYSTEM;
+ if (flags & RADEON_GART_PAGE_VALID)
+ addr |= R600_PTE_VALID;
+ if (flags & RADEON_GART_PAGE_READ)
+ addr |= R600_PTE_READABLE;
+ if (flags & RADEON_GART_PAGE_WRITE)
+ addr |= R600_PTE_WRITEABLE;
+ if (flags & RADEON_GART_PAGE_SNOOP)
+ addr |= R600_PTE_SNOOPED;
writeq(addr, ptr + (i * 8));
}
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 237dd29d9f1c..3e21e869015f 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -406,8 +406,9 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
for (i = 0; i < rdev->num_crtc; i++) {
if (save->crtc_enabled[i]) {
tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x3) != 0) {
- tmp &= ~0x3;
+ if ((tmp & 0x7) != 3) {
+ tmp &= ~0x7;
+ tmp |= 0x3;
WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
}
tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index da8703d8d455..2983f17ea1b3 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -900,7 +900,6 @@ static int rv770_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup L2 cache */
WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index da041a43d82e..3c76e1dcdf04 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -2329,12 +2329,6 @@ void rv770_get_engine_memory_ss(struct radeon_device *rdev)
pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
ASIC_INTERNAL_MEMORY_SS, 0);
- /* disable ss, causes hangs on some cayman boards */
- if (rdev->family == CHIP_CAYMAN) {
- pi->sclk_ss = false;
- pi->mclk_ss = false;
- }
-
if (pi->sclk_ss || pi->mclk_ss)
pi->dynamic_ss = true;
else
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 730cee2c34cf..011779bd2b3d 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -42,6 +42,14 @@ MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
+
+MODULE_FIRMWARE("radeon/tahiti_pfp.bin");
+MODULE_FIRMWARE("radeon/tahiti_me.bin");
+MODULE_FIRMWARE("radeon/tahiti_ce.bin");
+MODULE_FIRMWARE("radeon/tahiti_mc.bin");
+MODULE_FIRMWARE("radeon/tahiti_rlc.bin");
+MODULE_FIRMWARE("radeon/tahiti_smc.bin");
+
MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
@@ -49,6 +57,14 @@ MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
+
+MODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
+MODULE_FIRMWARE("radeon/pitcairn_me.bin");
+MODULE_FIRMWARE("radeon/pitcairn_ce.bin");
+MODULE_FIRMWARE("radeon/pitcairn_mc.bin");
+MODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
+MODULE_FIRMWARE("radeon/pitcairn_smc.bin");
+
MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
MODULE_FIRMWARE("radeon/VERDE_me.bin");
MODULE_FIRMWARE("radeon/VERDE_ce.bin");
@@ -56,6 +72,14 @@ MODULE_FIRMWARE("radeon/VERDE_mc.bin");
MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
MODULE_FIRMWARE("radeon/VERDE_smc.bin");
+
+MODULE_FIRMWARE("radeon/verde_pfp.bin");
+MODULE_FIRMWARE("radeon/verde_me.bin");
+MODULE_FIRMWARE("radeon/verde_ce.bin");
+MODULE_FIRMWARE("radeon/verde_mc.bin");
+MODULE_FIRMWARE("radeon/verde_rlc.bin");
+MODULE_FIRMWARE("radeon/verde_smc.bin");
+
MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
MODULE_FIRMWARE("radeon/OLAND_me.bin");
MODULE_FIRMWARE("radeon/OLAND_ce.bin");
@@ -63,6 +87,14 @@ MODULE_FIRMWARE("radeon/OLAND_mc.bin");
MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
MODULE_FIRMWARE("radeon/OLAND_smc.bin");
+
+MODULE_FIRMWARE("radeon/oland_pfp.bin");
+MODULE_FIRMWARE("radeon/oland_me.bin");
+MODULE_FIRMWARE("radeon/oland_ce.bin");
+MODULE_FIRMWARE("radeon/oland_mc.bin");
+MODULE_FIRMWARE("radeon/oland_rlc.bin");
+MODULE_FIRMWARE("radeon/oland_smc.bin");
+
MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
MODULE_FIRMWARE("radeon/HAINAN_me.bin");
MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
@@ -71,6 +103,13 @@ MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
+MODULE_FIRMWARE("radeon/hainan_pfp.bin");
+MODULE_FIRMWARE("radeon/hainan_me.bin");
+MODULE_FIRMWARE("radeon/hainan_ce.bin");
+MODULE_FIRMWARE("radeon/hainan_mc.bin");
+MODULE_FIRMWARE("radeon/hainan_rlc.bin");
+MODULE_FIRMWARE("radeon/hainan_smc.bin");
+
static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
static void si_pcie_gen3_enable(struct radeon_device *rdev);
static void si_program_aspm(struct radeon_device *rdev);
@@ -1470,38 +1509,54 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
/* ucode loading */
int si_mc_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
+ const __be32 *fw_data = NULL;
+ const __le32 *new_fw_data = NULL;
u32 running, blackout = 0;
- u32 *io_mc_regs;
+ u32 *io_mc_regs = NULL;
+ const __le32 *new_io_mc_regs = NULL;
int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
- ucode_size = rdev->mc_fw->size / 4;
+ if (rdev->new_fw) {
+ const struct mc_firmware_header_v1_0 *hdr =
+ (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
+
+ radeon_ucode_print_mc_hdr(&hdr->header);
+ regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
+ new_io_mc_regs = (const __le32 *)
+ (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
+ ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ new_fw_data = (const __le32 *)
+ (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ } else {
+ ucode_size = rdev->mc_fw->size / 4;
- switch (rdev->family) {
- case CHIP_TAHITI:
- io_mc_regs = (u32 *)&tahiti_io_mc_regs;
- regs_size = TAHITI_IO_MC_REGS_SIZE;
- break;
- case CHIP_PITCAIRN:
- io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
- regs_size = TAHITI_IO_MC_REGS_SIZE;
- break;
- case CHIP_VERDE:
- default:
- io_mc_regs = (u32 *)&verde_io_mc_regs;
- regs_size = TAHITI_IO_MC_REGS_SIZE;
- break;
- case CHIP_OLAND:
- io_mc_regs = (u32 *)&oland_io_mc_regs;
- regs_size = TAHITI_IO_MC_REGS_SIZE;
- break;
- case CHIP_HAINAN:
- io_mc_regs = (u32 *)&hainan_io_mc_regs;
- regs_size = TAHITI_IO_MC_REGS_SIZE;
- break;
+ switch (rdev->family) {
+ case CHIP_TAHITI:
+ io_mc_regs = (u32 *)&tahiti_io_mc_regs;
+ regs_size = TAHITI_IO_MC_REGS_SIZE;
+ break;
+ case CHIP_PITCAIRN:
+ io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
+ regs_size = TAHITI_IO_MC_REGS_SIZE;
+ break;
+ case CHIP_VERDE:
+ default:
+ io_mc_regs = (u32 *)&verde_io_mc_regs;
+ regs_size = TAHITI_IO_MC_REGS_SIZE;
+ break;
+ case CHIP_OLAND:
+ io_mc_regs = (u32 *)&oland_io_mc_regs;
+ regs_size = TAHITI_IO_MC_REGS_SIZE;
+ break;
+ case CHIP_HAINAN:
+ io_mc_regs = (u32 *)&hainan_io_mc_regs;
+ regs_size = TAHITI_IO_MC_REGS_SIZE;
+ break;
+ }
+ fw_data = (const __be32 *)rdev->mc_fw->data;
}
running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
@@ -1518,13 +1573,21 @@ int si_mc_load_microcode(struct radeon_device *rdev)
/* load mc io regs */
for (i = 0; i < regs_size; i++) {
- WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
- WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+ if (rdev->new_fw) {
+ WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
+ WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
+ } else {
+ WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+ WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+ }
}
/* load the MC ucode */
- fw_data = (const __be32 *)rdev->mc_fw->data;
- for (i = 0; i < ucode_size; i++)
- WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+ for (i = 0; i < ucode_size; i++) {
+ if (rdev->new_fw)
+ WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
+ else
+ WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+ }
/* put the engine back into the active state */
WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
@@ -1553,18 +1616,19 @@ int si_mc_load_microcode(struct radeon_device *rdev)
static int si_init_microcode(struct radeon_device *rdev)
{
const char *chip_name;
- const char *rlc_chip_name;
+ const char *new_chip_name;
size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
size_t smc_req_size, mc2_req_size;
char fw_name[30];
int err;
+ int new_fw = 0;
DRM_DEBUG("\n");
switch (rdev->family) {
case CHIP_TAHITI:
chip_name = "TAHITI";
- rlc_chip_name = "TAHITI";
+ new_chip_name = "tahiti";
pfp_req_size = SI_PFP_UCODE_SIZE * 4;
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1575,7 +1639,7 @@ static int si_init_microcode(struct radeon_device *rdev)
break;
case CHIP_PITCAIRN:
chip_name = "PITCAIRN";
- rlc_chip_name = "PITCAIRN";
+ new_chip_name = "pitcairn";
pfp_req_size = SI_PFP_UCODE_SIZE * 4;
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1586,7 +1650,7 @@ static int si_init_microcode(struct radeon_device *rdev)
break;
case CHIP_VERDE:
chip_name = "VERDE";
- rlc_chip_name = "VERDE";
+ new_chip_name = "verde";
pfp_req_size = SI_PFP_UCODE_SIZE * 4;
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1597,7 +1661,7 @@ static int si_init_microcode(struct radeon_device *rdev)
break;
case CHIP_OLAND:
chip_name = "OLAND";
- rlc_chip_name = "OLAND";
+ new_chip_name = "oland";
pfp_req_size = SI_PFP_UCODE_SIZE * 4;
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1607,7 +1671,7 @@ static int si_init_microcode(struct radeon_device *rdev)
break;
case CHIP_HAINAN:
chip_name = "HAINAN";
- rlc_chip_name = "HAINAN";
+ new_chip_name = "hainan";
pfp_req_size = SI_PFP_UCODE_SIZE * 4;
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
@@ -1618,86 +1682,178 @@ static int si_init_microcode(struct radeon_device *rdev)
default: BUG();
}
- DRM_INFO("Loading %s Microcode\n", chip_name);
+ DRM_INFO("Loading %s Microcode\n", new_chip_name);
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->pfp_fw->size != pfp_req_size) {
- printk(KERN_ERR
- "si_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->pfp_fw->size, fw_name);
- err = -EINVAL;
- goto out;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+ err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->pfp_fw->size != pfp_req_size) {
+ printk(KERN_ERR
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->pfp_fw->size, fw_name);
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->pfp_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->me_fw->size != me_req_size) {
- printk(KERN_ERR
- "si_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->me_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+ err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->me_fw->size != me_req_size) {
+ printk(KERN_ERR
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->me_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->ce_fw->size != ce_req_size) {
- printk(KERN_ERR
- "si_cp: Bogus length %zu in firmware \"%s\"\n",
- rdev->ce_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
+ err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->ce_fw->size != ce_req_size) {
+ printk(KERN_ERR
+ "si_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->ce_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->ce_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
- if (err)
- goto out;
- if (rdev->rlc_fw->size != rlc_req_size) {
- printk(KERN_ERR
- "si_rlc: Bogus length %zu in firmware \"%s\"\n",
- rdev->rlc_fw->size, fw_name);
- err = -EINVAL;
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
+ err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ if (rdev->rlc_fw->size != rlc_req_size) {
+ printk(KERN_ERR
+ "si_rlc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->rlc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->rlc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
if (err) {
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
- if (err)
+ if (err) {
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
+ err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+ if (err)
+ goto out;
+ }
+ if ((rdev->mc_fw->size != mc_req_size) &&
+ (rdev->mc_fw->size != mc2_req_size)) {
+ printk(KERN_ERR
+ "si_mc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->mc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
+ } else {
+ err = radeon_ucode_validate(rdev->mc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
goto out;
+ } else {
+ new_fw++;
+ }
}
- if ((rdev->mc_fw->size != mc_req_size) &&
- (rdev->mc_fw->size != mc2_req_size)) {
- printk(KERN_ERR
- "si_mc: Bogus length %zu in firmware \"%s\"\n",
- rdev->mc_fw->size, fw_name);
- err = -EINVAL;
- }
- DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
- snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
if (err) {
- printk(KERN_ERR
- "smc: error loading firmware \"%s\"\n",
- fw_name);
- release_firmware(rdev->smc_fw);
- rdev->smc_fw = NULL;
- err = 0;
- } else if (rdev->smc_fw->size != smc_req_size) {
- printk(KERN_ERR
- "si_smc: Bogus length %zu in firmware \"%s\"\n",
- rdev->smc_fw->size, fw_name);
- err = -EINVAL;
+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
+ err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+ if (err) {
+ printk(KERN_ERR
+ "smc: error loading firmware \"%s\"\n",
+ fw_name);
+ release_firmware(rdev->smc_fw);
+ rdev->smc_fw = NULL;
+ err = 0;
+ } else if (rdev->smc_fw->size != smc_req_size) {
+ printk(KERN_ERR
+ "si_smc: Bogus length %zu in firmware \"%s\"\n",
+ rdev->smc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ } else {
+ err = radeon_ucode_validate(rdev->smc_fw);
+ if (err) {
+ printk(KERN_ERR
+ "si_cp: validation failed for firmware \"%s\"\n",
+ fw_name);
+ goto out;
+ } else {
+ new_fw++;
+ }
}
+ if (new_fw == 0) {
+ rdev->new_fw = false;
+ } else if (new_fw < 6) {
+ printk(KERN_ERR "si_fw: mixing new and old firmware!\n");
+ err = -EINVAL;
+ } else {
+ rdev->new_fw = true;
+ }
out:
if (err) {
if (err != -EINVAL)
@@ -3282,34 +3438,77 @@ static void si_cp_enable(struct radeon_device *rdev, bool enable)
static int si_cp_load_microcode(struct radeon_device *rdev)
{
- const __be32 *fw_data;
int i;
- if (!rdev->me_fw || !rdev->pfp_fw)
+ if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
return -EINVAL;
si_cp_enable(rdev, false);
- /* PFP */
- fw_data = (const __be32 *)rdev->pfp_fw->data;
- WREG32(CP_PFP_UCODE_ADDR, 0);
- for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
- WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_PFP_UCODE_ADDR, 0);
-
- /* CE */
- fw_data = (const __be32 *)rdev->ce_fw->data;
- WREG32(CP_CE_UCODE_ADDR, 0);
- for (i = 0; i < SI_CE_UCODE_SIZE; i++)
- WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_CE_UCODE_ADDR, 0);
-
- /* ME */
- fw_data = (const __be32 *)rdev->me_fw->data;
- WREG32(CP_ME_RAM_WADDR, 0);
- for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
- WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
- WREG32(CP_ME_RAM_WADDR, 0);
+ if (rdev->new_fw) {
+ const struct gfx_firmware_header_v1_0 *pfp_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
+ const struct gfx_firmware_header_v1_0 *ce_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
+ const struct gfx_firmware_header_v1_0 *me_hdr =
+ (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
+ const __le32 *fw_data;
+ u32 fw_size;
+
+ radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
+ radeon_ucode_print_gfx_hdr(&ce_hdr->header);
+ radeon_ucode_print_gfx_hdr(&me_hdr->header);
+
+ /* PFP */
+ fw_data = (const __le32 *)
+ (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+
+ /* CE */
+ fw_data = (const __le32 *)
+ (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_CE_UCODE_ADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_CE_UCODE_ADDR, 0);
+
+ /* ME */
+ fw_data = (const __be32 *)
+ (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
+ fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
+ WREG32(CP_ME_RAM_WADDR, 0);
+ for (i = 0; i < fw_size; i++)
+ WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
+ WREG32(CP_ME_RAM_WADDR, 0);
+ } else {
+ const __be32 *fw_data;
+
+ /* PFP */
+ fw_data = (const __be32 *)rdev->pfp_fw->data;
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+ for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
+ WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_PFP_UCODE_ADDR, 0);
+
+ /* CE */
+ fw_data = (const __be32 *)rdev->ce_fw->data;
+ WREG32(CP_CE_UCODE_ADDR, 0);
+ for (i = 0; i < SI_CE_UCODE_SIZE; i++)
+ WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_CE_UCODE_ADDR, 0);
+
+ /* ME */
+ fw_data = (const __be32 *)rdev->me_fw->data;
+ WREG32(CP_ME_RAM_WADDR, 0);
+ for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
+ WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+ WREG32(CP_ME_RAM_WADDR, 0);
+ }
WREG32(CP_PFP_UCODE_ADDR, 0);
WREG32(CP_CE_UCODE_ADDR, 0);
@@ -4048,7 +4247,6 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
- radeon_gart_restore(rdev);
/* Setup TLB control */
WREG32(MC_VM_MX_L1_TLB_CNTL,
(0xA << 7) |
@@ -4815,7 +5013,7 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
/* write new base address */
radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
WRITE_DATA_DST_SEL(0)));
if (vm->id < 8) {
@@ -5592,7 +5790,6 @@ static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
static int si_rlc_resume(struct radeon_device *rdev)
{
u32 i;
- const __be32 *fw_data;
if (!rdev->rlc_fw)
return -EINVAL;
@@ -5615,10 +5812,26 @@ static int si_rlc_resume(struct radeon_device *rdev)
WREG32(RLC_MC_CNTL, 0);
WREG32(RLC_UCODE_CNTL, 0);
- fw_data = (const __be32 *)rdev->rlc_fw->data;
- for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
- WREG32(RLC_UCODE_ADDR, i);
- WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+ if (rdev->new_fw) {
+ const struct rlc_firmware_header_v1_0 *hdr =
+ (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
+ u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
+ const __le32 *fw_data = (const __le32 *)
+ (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+
+ radeon_ucode_print_rlc_hdr(&hdr->header);
+
+ for (i = 0; i < fw_size; i++) {
+ WREG32(RLC_UCODE_ADDR, i);
+ WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
+ }
+ } else {
+ const __be32 *fw_data =
+ (const __be32 *)rdev->rlc_fw->data;
+ for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
+ WREG32(RLC_UCODE_ADDR, i);
+ WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+ }
}
WREG32(RLC_UCODE_ADDR, 0);
@@ -6103,6 +6316,7 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
tmp = RREG32(IH_RB_CNTL);
tmp |= IH_WPTR_OVERFLOW_CLEAR;
WREG32(IH_RB_CNTL, tmp);
+ wptr &= ~RB_OVERFLOW;
}
return (wptr & rdev->ih.ptr_mask);
}
@@ -6317,7 +6531,8 @@ restart_ih:
case 16: /* D5 page flip */
case 18: /* D6 page flip */
DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
- radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
+ if (radeon_use_pflipirq > 0)
+ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
break;
case 42: /* HPD hotplug */
switch (src_data) {
@@ -6376,14 +6591,16 @@ restart_ih:
case 147:
addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
+ /* reset addr and status */
+ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+ if (addr == 0x0 && status == 0x0)
+ break;
dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
addr);
dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
status);
si_vm_decode_fault(rdev, status, addr);
- /* reset addr and status */
- WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
break;
case 176: /* RINGID0 CP_INT */
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index e24c94b6d14d..716505129450 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -56,7 +56,41 @@ bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
}
/**
- * si_dma_vm_set_page - update the page tables using the DMA
+ * si_dma_vm_copy_pages - update PTEs by copying them from the GART
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @src: src addr where to copy from
+ * @count: number of page entries to update
+ *
+ * Update PTEs by copying them from the GART using the DMA (SI).
+ */
+void si_dma_vm_copy_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe, uint64_t src,
+ unsigned count)
+{
+ while (count) {
+ unsigned bytes = count * 8;
+ if (bytes > 0xFFFF8)
+ bytes = 0xFFFF8;
+
+ ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
+ 1, 0, 0, bytes);
+ ib->ptr[ib->length_dw++] = lower_32_bits(pe);
+ ib->ptr[ib->length_dw++] = lower_32_bits(src);
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ ib->ptr[ib->length_dw++] = upper_32_bits(src) & 0xff;
+
+ pe += bytes;
+ src += bytes;
+ count -= bytes / 8;
+ }
+}
+
+/**
+ * si_dma_vm_write_pages - update PTEs by writing them manually
*
* @rdev: radeon_device pointer
* @ib: indirect buffer to fill with commands
@@ -66,83 +100,89 @@ bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
* @incr: increase next addr by incr bytes
* @flags: access flags
*
- * Update the page tables using the DMA (SI).
+ * Update PTEs by writing them manually using the DMA (SI).
*/
-void si_dma_vm_set_page(struct radeon_device *rdev,
- struct radeon_ib *ib,
- uint64_t pe,
- uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags)
+void si_dma_vm_write_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
{
uint64_t value;
unsigned ndw;
- trace_radeon_vm_set_page(pe, addr, count, incr, flags);
-
- if (flags == R600_PTE_GART) {
- uint64_t src = rdev->gart.table_addr + (addr >> 12) * 8;
- while (count) {
- unsigned bytes = count * 8;
- if (bytes > 0xFFFF8)
- bytes = 0xFFFF8;
-
- ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
- 1, 0, 0, bytes);
- ib->ptr[ib->length_dw++] = lower_32_bits(pe);
- ib->ptr[ib->length_dw++] = lower_32_bits(src);
- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- ib->ptr[ib->length_dw++] = upper_32_bits(src) & 0xff;
-
- pe += bytes;
- src += bytes;
- count -= bytes / 8;
- }
- } else if (flags & R600_PTE_SYSTEM) {
- while (count) {
- ndw = count * 2;
- if (ndw > 0xFFFFE)
- ndw = 0xFFFFE;
-
- /* for non-physically contiguous pages (system) */
- ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, ndw);
- ib->ptr[ib->length_dw++] = pe;
- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ /* for non-physically contiguous pages (system) */
+ ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, ndw);
+ ib->ptr[ib->length_dw++] = pe;
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+ if (flags & R600_PTE_SYSTEM) {
value = radeon_vm_map_gart(rdev, addr);
value &= 0xFFFFFFFFFFFFF000ULL;
- addr += incr;
- value |= flags;
- ib->ptr[ib->length_dw++] = value;
- ib->ptr[ib->length_dw++] = upper_32_bits(value);
- }
- }
- } else {
- while (count) {
- ndw = count * 2;
- if (ndw > 0xFFFFE)
- ndw = 0xFFFFE;
-
- if (flags & R600_PTE_VALID)
+ } else if (flags & R600_PTE_VALID) {
value = addr;
- else
+ } else {
value = 0;
- /* for physically contiguous pages (vram) */
- ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
- ib->ptr[ib->length_dw++] = pe; /* dst addr */
- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
- ib->ptr[ib->length_dw++] = flags; /* mask */
- ib->ptr[ib->length_dw++] = 0;
- ib->ptr[ib->length_dw++] = value; /* value */
+ }
+ addr += incr;
+ value |= flags;
+ ib->ptr[ib->length_dw++] = value;
ib->ptr[ib->length_dw++] = upper_32_bits(value);
- ib->ptr[ib->length_dw++] = incr; /* increment size */
- ib->ptr[ib->length_dw++] = 0;
- pe += ndw * 4;
- addr += (ndw / 2) * incr;
- count -= ndw / 2;
}
}
- while (ib->length_dw & 0x7)
- ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0);
+}
+
+/**
+ * si_dma_vm_set_pages - update the page tables using the DMA
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using the DMA (SI).
+ */
+void si_dma_vm_set_pages(struct radeon_device *rdev,
+ struct radeon_ib *ib,
+ uint64_t pe,
+ uint64_t addr, unsigned count,
+ uint32_t incr, uint32_t flags)
+{
+ uint64_t value;
+ unsigned ndw;
+
+ while (count) {
+ ndw = count * 2;
+ if (ndw > 0xFFFFE)
+ ndw = 0xFFFFE;
+
+ if (flags & R600_PTE_VALID)
+ value = addr;
+ else
+ value = 0;
+
+ /* for physically contiguous pages (vram) */
+ ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
+ ib->ptr[ib->length_dw++] = pe; /* dst addr */
+ ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
+ ib->ptr[ib->length_dw++] = flags; /* mask */
+ ib->ptr[ib->length_dw++] = 0;
+ ib->ptr[ib->length_dw++] = value; /* value */
+ ib->ptr[ib->length_dw++] = upper_32_bits(value);
+ ib->ptr[ib->length_dw++] = incr; /* increment size */
+ ib->ptr[ib->length_dw++] = 0;
+ pe += ndw * 4;
+ addr += (ndw / 2) * incr;
+ count -= ndw / 2;
+ }
}
void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 58918868f894..70e61ffeace2 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -3812,6 +3812,27 @@ void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
voltage_table->count = max_voltage_steps;
}
+static int si_get_svi2_voltage_table(struct radeon_device *rdev,
+ struct radeon_clock_voltage_dependency_table *voltage_dependency_table,
+ struct atom_voltage_table *voltage_table)
+{
+ u32 i;
+
+ if (voltage_dependency_table == NULL)
+ return -EINVAL;
+
+ voltage_table->mask_low = 0;
+ voltage_table->phase_delay = 0;
+
+ voltage_table->count = voltage_dependency_table->count;
+ for (i = 0; i < voltage_table->count; i++) {
+ voltage_table->entries[i].value = voltage_dependency_table->entries[i].v;
+ voltage_table->entries[i].smio_low = 0;
+ }
+
+ return 0;
+}
+
static int si_construct_voltage_tables(struct radeon_device *rdev)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
@@ -3819,15 +3840,25 @@ static int si_construct_voltage_tables(struct radeon_device *rdev)
struct si_power_info *si_pi = si_get_pi(rdev);
int ret;
- ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
- VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);
- if (ret)
- return ret;
+ if (pi->voltage_control) {
+ ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
+ VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);
+ if (ret)
+ return ret;
- if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
- si_trim_voltage_table_to_fit_state_table(rdev,
- SISLANDS_MAX_NO_VREG_STEPS,
- &eg_pi->vddc_voltage_table);
+ if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
+ si_trim_voltage_table_to_fit_state_table(rdev,
+ SISLANDS_MAX_NO_VREG_STEPS,
+ &eg_pi->vddc_voltage_table);
+ } else if (si_pi->voltage_control_svi2) {
+ ret = si_get_svi2_voltage_table(rdev,
+ &rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+ &eg_pi->vddc_voltage_table);
+ if (ret)
+ return ret;
+ } else {
+ return -EINVAL;
+ }
if (eg_pi->vddci_control) {
ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI,
@@ -3840,6 +3871,13 @@ static int si_construct_voltage_tables(struct radeon_device *rdev)
SISLANDS_MAX_NO_VREG_STEPS,
&eg_pi->vddci_voltage_table);
}
+ if (si_pi->vddci_control_svi2) {
+ ret = si_get_svi2_voltage_table(rdev,
+ &rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+ &eg_pi->vddci_voltage_table);
+ if (ret)
+ return ret;
+ }
if (pi->mvdd_control) {
ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_MVDDC,
@@ -3893,46 +3931,55 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev,
struct si_power_info *si_pi = si_get_pi(rdev);
u8 i;
- if (eg_pi->vddc_voltage_table.count) {
- si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
- table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
- cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
-
- for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
- if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
- table->maxVDDCIndexInPPTable = i;
- break;
+ if (si_pi->voltage_control_svi2) {
+ si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc,
+ si_pi->svc_gpio_id);
+ si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd,
+ si_pi->svd_gpio_id);
+ si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type,
+ 2);
+ } else {
+ if (eg_pi->vddc_voltage_table.count) {
+ si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
+ table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+ cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+
+ for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
+ if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
+ table->maxVDDCIndexInPPTable = i;
+ break;
+ }
}
}
- }
- if (eg_pi->vddci_voltage_table.count) {
- si_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
+ if (eg_pi->vddci_voltage_table.count) {
+ si_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
- table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =
- cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
- }
+ table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =
+ cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
+ }
- if (si_pi->mvdd_voltage_table.count) {
- si_populate_smc_voltage_table(rdev, &si_pi->mvdd_voltage_table, table);
+ if (si_pi->mvdd_voltage_table.count) {
+ si_populate_smc_voltage_table(rdev, &si_pi->mvdd_voltage_table, table);
- table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =
- cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);
- }
+ table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =
+ cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);
+ }
- if (si_pi->vddc_phase_shed_control) {
- if (si_validate_phase_shedding_tables(rdev, &si_pi->vddc_phase_shed_table,
- &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
- si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
+ if (si_pi->vddc_phase_shed_control) {
+ if (si_validate_phase_shedding_tables(rdev, &si_pi->vddc_phase_shed_table,
+ &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
+ si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
- table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
- cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
+ table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+ cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
- si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
- (u32)si_pi->vddc_phase_shed_table.phase_delay);
- } else {
- si_pi->vddc_phase_shed_control = false;
+ si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
+ (u32)si_pi->vddc_phase_shed_table.phase_delay);
+ } else {
+ si_pi->vddc_phase_shed_control = false;
+ }
}
}
@@ -5798,16 +5845,17 @@ int si_dpm_enable(struct radeon_device *rdev)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+ struct si_power_info *si_pi = si_get_pi(rdev);
struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
int ret;
if (si_is_smc_running(rdev))
return -EINVAL;
- if (pi->voltage_control)
+ if (pi->voltage_control || si_pi->voltage_control_svi2)
si_enable_voltage_control(rdev, true);
if (pi->mvdd_control)
si_get_mvdd_configuration(rdev);
- if (pi->voltage_control) {
+ if (pi->voltage_control || si_pi->voltage_control_svi2) {
ret = si_construct_voltage_tables(rdev);
if (ret) {
DRM_ERROR("si_construct_voltage_tables failed\n");
@@ -6406,16 +6454,32 @@ int si_dpm_init(struct radeon_device *rdev)
ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
pi->voltage_control =
- radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT);
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+ VOLTAGE_OBJ_GPIO_LUT);
+ if (!pi->voltage_control) {
+ si_pi->voltage_control_svi2 =
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+ VOLTAGE_OBJ_SVID2);
+ if (si_pi->voltage_control_svi2)
+ radeon_atom_get_svi2_info(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+ &si_pi->svd_gpio_id, &si_pi->svc_gpio_id);
+ }
pi->mvdd_control =
- radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT);
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC,
+ VOLTAGE_OBJ_GPIO_LUT);
eg_pi->vddci_control =
- radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT);
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
+ VOLTAGE_OBJ_GPIO_LUT);
+ if (!eg_pi->vddci_control)
+ si_pi->vddci_control_svi2 =
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
+ VOLTAGE_OBJ_SVID2);
si_pi->vddc_phase_shed_control =
- radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
+ radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+ VOLTAGE_OBJ_PHASE_LUT);
rv770_get_engine_memory_ss(rdev);
diff --git a/drivers/gpu/drm/radeon/si_dpm.h b/drivers/gpu/drm/radeon/si_dpm.h
index 4ce5032cdf49..8b5c06a0832d 100644
--- a/drivers/gpu/drm/radeon/si_dpm.h
+++ b/drivers/gpu/drm/radeon/si_dpm.h
@@ -170,6 +170,8 @@ struct si_power_info {
bool vddc_phase_shed_control;
bool pspp_notify_required;
bool sclk_deep_sleep_above_low;
+ bool voltage_control_svi2;
+ bool vddci_control_svi2;
/* smc offsets */
u32 sram_end;
u32 state_table_start;
@@ -192,6 +194,9 @@ struct si_power_info {
SMC_SIslands_MCRegisters smc_mc_reg_table;
SISLANDS_SMC_STATETABLE smc_statetable;
PP_SIslands_PAPMParameters papm_parm;
+ /* SVI2 */
+ u8 svd_gpio_id;
+ u8 svc_gpio_id;
};
#define SISLANDS_INITIAL_STATE_ARB_INDEX 0
diff --git a/drivers/gpu/drm/radeon/si_smc.c b/drivers/gpu/drm/radeon/si_smc.c
index e80efcf0c230..73dbc79c959d 100644
--- a/drivers/gpu/drm/radeon/si_smc.c
+++ b/drivers/gpu/drm/radeon/si_smc.c
@@ -219,36 +219,48 @@ int si_load_smc_ucode(struct radeon_device *rdev, u32 limit)
if (!rdev->smc_fw)
return -EINVAL;
- switch (rdev->family) {
- case CHIP_TAHITI:
- ucode_start_address = TAHITI_SMC_UCODE_START;
- ucode_size = TAHITI_SMC_UCODE_SIZE;
- break;
- case CHIP_PITCAIRN:
- ucode_start_address = PITCAIRN_SMC_UCODE_START;
- ucode_size = PITCAIRN_SMC_UCODE_SIZE;
- break;
- case CHIP_VERDE:
- ucode_start_address = VERDE_SMC_UCODE_START;
- ucode_size = VERDE_SMC_UCODE_SIZE;
- break;
- case CHIP_OLAND:
- ucode_start_address = OLAND_SMC_UCODE_START;
- ucode_size = OLAND_SMC_UCODE_SIZE;
- break;
- case CHIP_HAINAN:
- ucode_start_address = HAINAN_SMC_UCODE_START;
- ucode_size = HAINAN_SMC_UCODE_SIZE;
- break;
- default:
- DRM_ERROR("unknown asic in smc ucode loader\n");
- BUG();
+ if (rdev->new_fw) {
+ const struct smc_firmware_header_v1_0 *hdr =
+ (const struct smc_firmware_header_v1_0 *)rdev->smc_fw->data;
+
+ radeon_ucode_print_smc_hdr(&hdr->header);
+
+ ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
+ ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
+ src = (const u8 *)
+ (rdev->smc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
+ } else {
+ switch (rdev->family) {
+ case CHIP_TAHITI:
+ ucode_start_address = TAHITI_SMC_UCODE_START;
+ ucode_size = TAHITI_SMC_UCODE_SIZE;
+ break;
+ case CHIP_PITCAIRN:
+ ucode_start_address = PITCAIRN_SMC_UCODE_START;
+ ucode_size = PITCAIRN_SMC_UCODE_SIZE;
+ break;
+ case CHIP_VERDE:
+ ucode_start_address = VERDE_SMC_UCODE_START;
+ ucode_size = VERDE_SMC_UCODE_SIZE;
+ break;
+ case CHIP_OLAND:
+ ucode_start_address = OLAND_SMC_UCODE_START;
+ ucode_size = OLAND_SMC_UCODE_SIZE;
+ break;
+ case CHIP_HAINAN:
+ ucode_start_address = HAINAN_SMC_UCODE_START;
+ ucode_size = HAINAN_SMC_UCODE_SIZE;
+ break;
+ default:
+ DRM_ERROR("unknown asic in smc ucode loader\n");
+ BUG();
+ }
+ src = (const u8 *)rdev->smc_fw->data;
}
if (ucode_size & 3)
return -EINVAL;
- src = (const u8 *)rdev->smc_fw->data;
spin_lock_irqsave(&rdev->smc_idx_lock, flags);
WREG32(SMC_IND_INDEX_0, ucode_start_address);
WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h
index 10e945a49479..623a0b1e2d9d 100644
--- a/drivers/gpu/drm/radeon/sislands_smc.h
+++ b/drivers/gpu/drm/radeon/sislands_smc.h
@@ -241,6 +241,9 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE;
#define SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width 0xF4
#define SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen 0xFC
#define SI_SMC_SOFT_REGISTER_vr_hot_gpio 0x100
+#define SI_SMC_SOFT_REGISTER_svi_rework_plat_type 0x118
+#define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c
+#define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120
#define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
#define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c
index 2a2822c03329..32e50be9c4ac 100644
--- a/drivers/gpu/drm/radeon/trinity_dpm.c
+++ b/drivers/gpu/drm/radeon/trinity_dpm.c
@@ -1874,7 +1874,16 @@ int trinity_dpm_init(struct radeon_device *rdev)
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
pi->at[i] = TRINITY_AT_DFLT;
- pi->enable_bapm = false;
+ /* There are stability issues reported on with
+ * bapm enabled when switching between AC and battery
+ * power. At the same time, some MSI boards hang
+ * if it's not enabled and dpm is enabled. Just enable
+ * it for MSI boards right now.
+ */
+ if (rdev->pdev->subsystem_vendor == 0x1462)
+ pi->enable_bapm = true;
+ else
+ pi->enable_bapm = false;
pi->enable_nbps_policy = true;
pi->enable_sclk_ds = true;
pi->enable_gfx_power_gating = true;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 792fd1d20e86..fda64b7b73e8 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -187,7 +187,7 @@ static struct drm_driver rcar_du_driver = {
* Power management
*/
-#if CONFIG_PM_SLEEP
+#ifdef CONFIG_PM_SLEEP
static int rcar_du_pm_suspend(struct device *dev)
{
struct rcar_du_device *rcdu = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index a87edfac111f..76026104d000 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -135,7 +135,9 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
{
struct rcar_du_device *rcdu = dev->dev_private;
const struct rcar_du_format_info *format;
+ unsigned int max_pitch;
unsigned int align;
+ unsigned int bpp;
format = rcar_du_format_info(mode_cmd->pixel_format);
if (format == NULL) {
@@ -144,13 +146,20 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
return ERR_PTR(-EINVAL);
}
+ /*
+ * The pitch and alignment constraints are expressed in pixels on the
+ * hardware side and in bytes in the DRM API.
+ */
+ bpp = format->planes == 2 ? 1 : format->bpp / 8;
+ max_pitch = 4096 * bpp;
+
if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
align = 128;
else
- align = 16 * format->bpp / 8;
+ align = 16 * bpp;
if (mode_cmd->pitches[0] & (align - 1) ||
- mode_cmd->pitches[0] >= 8192) {
+ mode_cmd->pitches[0] >= max_pitch) {
dev_dbg(dev->dev, "invalid pitch value %u\n",
mode_cmd->pitches[0]);
return ERR_PTR(-EINVAL);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
index 289048d1c7b2..21426bd234eb 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
@@ -64,7 +64,7 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
static void rcar_du_lvds_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -105,7 +105,7 @@ int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
return ret;
drm_connector_helper_add(connector, &connector_helper_funcs);
- ret = drm_sysfs_connector_add(connector);
+ ret = drm_connector_register(connector);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
index ccfe64c7188f..8af3944d31b9 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c
@@ -32,7 +32,7 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
static void rcar_du_vga_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -70,7 +70,7 @@ int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
return ret;
drm_connector_helper_add(connector, &connector_helper_funcs);
- ret = drm_sysfs_connector_add(connector);
+ ret = drm_connector_register(connector);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index faf176b2daf9..47875de89010 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -692,7 +692,7 @@ static void shmob_drm_connector_destroy(struct drm_connector *connector)
struct shmob_drm_connector *scon = to_shmob_connector(connector);
shmob_drm_backlight_exit(scon);
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -726,7 +726,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
return ret;
drm_connector_helper_add(connector, &connector_helper_funcs);
- ret = drm_sysfs_connector_add(connector);
+ ret = drm_connector_register(connector);
if (ret < 0)
goto err_cleanup;
@@ -749,7 +749,7 @@ int shmob_drm_connector_create(struct shmob_drm_device *sdev,
err_backlight:
shmob_drm_backlight_exit(&sdev->connector);
err_sysfs:
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
err_cleanup:
drm_connector_cleanup(connector);
return ret;
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index 82c84c7fd4f6..ff4ba483b602 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -297,7 +297,7 @@ static struct drm_driver shmob_drm_driver = {
* Power management
*/
-#if CONFIG_PM_SLEEP
+#ifdef CONFIG_PM_SLEEP
static int shmob_drm_pm_suspend(struct device *dev)
{
struct shmob_drm_device *sdev = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
new file mode 100644
index 000000000000..2d9d4252d598
--- /dev/null
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -0,0 +1,14 @@
+config DRM_STI
+ tristate "DRM Support for STMicroelectronics SoC stiH41x Series"
+ depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
+ select DRM_KMS_HELPER
+ select DRM_GEM_CMA_HELPER
+ select DRM_KMS_CMA_HELPER
+ help
+ Choose this option to enable DRM on STM stiH41x chipset
+
+config DRM_STI_FBDEV
+ bool "DRM frame buffer device for STMicroelectronics SoC stiH41x Serie"
+ depends on DRM_STI
+ help
+ Choose this option to enable FBDEV on top of DRM for STM stiH41x chipset
diff --git a/drivers/gpu/drm/sti/Makefile b/drivers/gpu/drm/sti/Makefile
new file mode 100644
index 000000000000..04ac2ceef27f
--- /dev/null
+++ b/drivers/gpu/drm/sti/Makefile
@@ -0,0 +1,21 @@
+sticompositor-y := \
+ sti_layer.o \
+ sti_mixer.o \
+ sti_gdp.o \
+ sti_vid.o \
+ sti_compositor.o \
+ sti_drm_crtc.o \
+ sti_drm_plane.o
+
+stihdmi-y := sti_hdmi.o \
+ sti_hdmi_tx3g0c55phy.o \
+ sti_hdmi_tx3g4c28phy.o \
+
+obj-$(CONFIG_DRM_STI) = \
+ sti_vtg.o \
+ sti_vtac.o \
+ stihdmi.o \
+ sti_hda.o \
+ sti_tvout.o \
+ sticompositor.o \
+ sti_drm_drv.o \ No newline at end of file
diff --git a/drivers/gpu/drm/sti/NOTES b/drivers/gpu/drm/sti/NOTES
new file mode 100644
index 000000000000..57e257969198
--- /dev/null
+++ b/drivers/gpu/drm/sti/NOTES
@@ -0,0 +1,58 @@
+1. stiH display hardware IP
+---------------------------
+The STMicroelectronics stiH SoCs use a common chain of HW display IP blocks:
+- The High Quality Video Display Processor (HQVDP) gets video frames from a
+ video decoder and does high quality video processing, including scaling.
+
+- The Compositor is a multiplane, dual-mixer (Main & Aux) digital processor. It
+ has several inputs:
+ - The graphics planes are internally processed by the Generic Display
+ Pipeline (GDP).
+ - The video plug (VID) connects to the HQVDP output.
+ - The cursor handles ... a cursor.
+- The TV OUT pre-formats (convert, clip, round) the compositor output data
+- The HDMI / DVO / HD Analog / SD analog IP builds the video signals
+ - DVO (Digital Video Output) handles a 24bits parallel signal
+ - The HD analog signal is typically driven by a YCbCr cable, supporting up to
+ 1080i mode.
+ - The SD analog signal is typically used for legacy TV
+- The VTG (Video Timing Generators) build Vsync signals used by the other HW IP
+Note that some stiH drivers support only a subset of thee HW IP.
+
+ .-------------. .-----------. .-----------.
+GPU >-------------+GDP Main | | +---+ HDMI +--> HDMI
+GPU >-------------+GDP mixer+---+ | :===========:
+GPU >-------------+Cursor | | +---+ DVO +--> 24b//
+ ------- | COMPOSITOR | | TV OUT | :===========:
+ | | | | | +---+ HD analog +--> YCbCr
+Vid >--+ HQVDP +--+VID Aux +---+ | :===========:
+dec | | | mixer| | +---+ SD analog +--> CVBS
+ '-------' '-------------' '-----------' '-----------'
+ .-----------.
+ | main+--> Vsync
+ | VTG |
+ | aux+--> Vsync
+ '-----------'
+
+2. DRM / HW mapping
+-------------------
+These IP are mapped to the DRM objects as following:
+- The CRTCs are mapped to the Compositor Main and Aux Mixers
+- The Framebuffers and planes are mapped to the Compositor GDP (non video
+ buffers) and to HQVDP+VID (video buffers)
+- The Cursor is mapped to the Compositor Cursor
+- The Encoders are mapped to the TVOut
+- The Bridges/Connectors are mapped to the HDMI / DVO / HD Analog / SD analog
+
+FB & planes Cursor CRTC Encoders Bridges/Connectors
+ | | | | |
+ | | | | |
+ | .-------------. | .-----------. .-----------. |
+ +------------> |GDP | Main | | | +-> | | HDMI | <-+
+ +------------> |GDP v mixer|<+ | | | :===========: |
+ | |Cursor | | | +-> | | DVO | <-+
+ | ------- | COMPOSITOR | | |TV OUT | | :===========: |
+ | | | | | | | +-> | | HD analog | <-+
+ +-> | HQVDP | |VID Aux |<+ | | | :===========: |
+ | | | mixer| | +-> | | SD analog | <-+
+ '-------' '-------------' '-----------' '-----------'
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c
new file mode 100644
index 000000000000..390d93e9a06c
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_compositor.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <drm/drmP.h>
+
+#include "sti_compositor.h"
+#include "sti_drm_crtc.h"
+#include "sti_drm_drv.h"
+#include "sti_drm_plane.h"
+#include "sti_gdp.h"
+#include "sti_vtg.h"
+
+/*
+ * stiH407 compositor properties
+ */
+struct sti_compositor_data stih407_compositor_data = {
+ .nb_subdev = 6,
+ .subdev_desc = {
+ {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
+ {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
+ {STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300},
+ {STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400},
+ {STI_VID_SUBDEV, (int)STI_VID_0, 0x700},
+ {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
+ },
+};
+
+/*
+ * stiH416 compositor properties
+ * Note:
+ * on stih416 MIXER_AUX has a different base address from MIXER_MAIN
+ * Moreover, GDPx is different for Main and Aux Mixer. So this subdev map does
+ * not fit for stiH416 if we want to enable the MIXER_AUX.
+ */
+struct sti_compositor_data stih416_compositor_data = {
+ .nb_subdev = 3,
+ .subdev_desc = {
+ {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100},
+ {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200},
+ {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}
+ },
+};
+
+static int sti_compositor_init_subdev(struct sti_compositor *compo,
+ struct sti_compositor_subdev_descriptor *desc,
+ unsigned int array_size)
+{
+ unsigned int i, mixer_id = 0, layer_id = 0;
+
+ for (i = 0; i < array_size; i++) {
+ switch (desc[i].type) {
+ case STI_MIXER_MAIN_SUBDEV:
+ case STI_MIXER_AUX_SUBDEV:
+ compo->mixer[mixer_id++] =
+ sti_mixer_create(compo->dev, desc[i].id,
+ compo->regs + desc[i].offset);
+ break;
+ case STI_GPD_SUBDEV:
+ case STI_VID_SUBDEV:
+ compo->layer[layer_id++] =
+ sti_layer_create(compo->dev, desc[i].id,
+ compo->regs + desc[i].offset);
+ break;
+ /* case STI_CURSOR_SUBDEV : TODO */
+ default:
+ DRM_ERROR("Unknow subdev compoment type\n");
+ return 1;
+ }
+
+ }
+ compo->nb_mixers = mixer_id;
+ compo->nb_layers = layer_id;
+
+ return 0;
+}
+
+static int sti_compositor_bind(struct device *dev, struct device *master,
+ void *data)
+{
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ unsigned int i, crtc = 0, plane = 0;
+ struct sti_drm_private *dev_priv = drm_dev->dev_private;
+ struct drm_plane *cursor = NULL;
+ struct drm_plane *primary = NULL;
+
+ dev_priv->compo = compo;
+
+ for (i = 0; i < compo->nb_layers; i++) {
+ if (compo->layer[i]) {
+ enum sti_layer_desc desc = compo->layer[i]->desc;
+ enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK;
+ enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY;
+
+ if (compo->mixer[crtc])
+ plane_type = DRM_PLANE_TYPE_PRIMARY;
+
+ switch (type) {
+ case STI_CUR:
+ cursor = sti_drm_plane_init(drm_dev,
+ compo->layer[i],
+ (1 << crtc) - 1,
+ DRM_PLANE_TYPE_CURSOR);
+ break;
+ case STI_GDP:
+ case STI_VID:
+ primary = sti_drm_plane_init(drm_dev,
+ compo->layer[i],
+ (1 << crtc) - 1, plane_type);
+ plane++;
+ break;
+ case STI_BCK:
+ break;
+ }
+
+ /* The first planes are reserved for primary planes*/
+ if (compo->mixer[crtc]) {
+ sti_drm_crtc_init(drm_dev, compo->mixer[crtc],
+ primary, cursor);
+ crtc++;
+ cursor = NULL;
+ }
+ }
+ }
+
+ drm_vblank_init(drm_dev, crtc);
+ /* Allow usage of vblank without having to call drm_irq_install */
+ drm_dev->irq_enabled = 1;
+
+ DRM_DEBUG_DRIVER("Initialized %d DRM CRTC(s) and %d DRM plane(s)\n",
+ crtc, plane);
+ DRM_DEBUG_DRIVER("DRM plane(s) for VID/VDP not created yet\n");
+
+ return 0;
+}
+
+static void sti_compositor_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ /* do nothing */
+}
+
+static const struct component_ops sti_compositor_ops = {
+ .bind = sti_compositor_bind,
+ .unbind = sti_compositor_unbind,
+};
+
+static const struct of_device_id compositor_of_match[] = {
+ {
+ .compatible = "st,stih416-compositor",
+ .data = &stih416_compositor_data,
+ }, {
+ .compatible = "st,stih407-compositor",
+ .data = &stih407_compositor_data,
+ }, {
+ /* end node */
+ }
+};
+MODULE_DEVICE_TABLE(of, compositor_of_match);
+
+static int sti_compositor_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *vtg_np;
+ struct sti_compositor *compo;
+ struct resource *res;
+ int err;
+
+ compo = devm_kzalloc(dev, sizeof(*compo), GFP_KERNEL);
+ if (!compo) {
+ DRM_ERROR("Failed to allocate compositor context\n");
+ return -ENOMEM;
+ }
+ compo->dev = dev;
+ compo->vtg_vblank_nb.notifier_call = sti_drm_crtc_vblank_cb;
+
+ /* populate data structure depending on compatibility */
+ BUG_ON(!of_match_node(compositor_of_match, np)->data);
+
+ memcpy(&compo->data, of_match_node(compositor_of_match, np)->data,
+ sizeof(struct sti_compositor_data));
+
+ /* Get Memory ressources */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ DRM_ERROR("Get memory resource failed\n");
+ return -ENXIO;
+ }
+ compo->regs = devm_ioremap(dev, res->start, resource_size(res));
+ if (compo->regs == NULL) {
+ DRM_ERROR("Register mapping failed\n");
+ return -ENXIO;
+ }
+
+ /* Get clock resources */
+ compo->clk_compo_main = devm_clk_get(dev, "compo_main");
+ if (IS_ERR(compo->clk_compo_main)) {
+ DRM_ERROR("Cannot get compo_main clock\n");
+ return PTR_ERR(compo->clk_compo_main);
+ }
+
+ compo->clk_compo_aux = devm_clk_get(dev, "compo_aux");
+ if (IS_ERR(compo->clk_compo_aux)) {
+ DRM_ERROR("Cannot get compo_aux clock\n");
+ return PTR_ERR(compo->clk_compo_aux);
+ }
+
+ compo->clk_pix_main = devm_clk_get(dev, "pix_main");
+ if (IS_ERR(compo->clk_pix_main)) {
+ DRM_ERROR("Cannot get pix_main clock\n");
+ return PTR_ERR(compo->clk_pix_main);
+ }
+
+ compo->clk_pix_aux = devm_clk_get(dev, "pix_aux");
+ if (IS_ERR(compo->clk_pix_aux)) {
+ DRM_ERROR("Cannot get pix_aux clock\n");
+ return PTR_ERR(compo->clk_pix_aux);
+ }
+
+ /* Get reset resources */
+ compo->rst_main = devm_reset_control_get(dev, "compo-main");
+ /* Take compo main out of reset */
+ if (!IS_ERR(compo->rst_main))
+ reset_control_deassert(compo->rst_main);
+
+ compo->rst_aux = devm_reset_control_get(dev, "compo-aux");
+ /* Take compo aux out of reset */
+ if (!IS_ERR(compo->rst_aux))
+ reset_control_deassert(compo->rst_aux);
+
+ vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 0);
+ if (vtg_np)
+ compo->vtg_main = of_vtg_find(vtg_np);
+
+ vtg_np = of_parse_phandle(pdev->dev.of_node, "st,vtg", 1);
+ if (vtg_np)
+ compo->vtg_aux = of_vtg_find(vtg_np);
+
+ /* Initialize compositor subdevices */
+ err = sti_compositor_init_subdev(compo, compo->data.subdev_desc,
+ compo->data.nb_subdev);
+ if (err)
+ return err;
+
+ platform_set_drvdata(pdev, compo);
+
+ return component_add(&pdev->dev, &sti_compositor_ops);
+}
+
+static int sti_compositor_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &sti_compositor_ops);
+ return 0;
+}
+
+static struct platform_driver sti_compositor_driver = {
+ .driver = {
+ .name = "sti-compositor",
+ .owner = THIS_MODULE,
+ .of_match_table = compositor_of_match,
+ },
+ .probe = sti_compositor_probe,
+ .remove = sti_compositor_remove,
+};
+
+module_platform_driver(sti_compositor_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_compositor.h b/drivers/gpu/drm/sti/sti_compositor.h
new file mode 100644
index 000000000000..3ea19db72e0f
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_compositor.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_COMPOSITOR_H_
+#define _STI_COMPOSITOR_H_
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+
+#include "sti_layer.h"
+#include "sti_mixer.h"
+
+#define WAIT_NEXT_VSYNC_MS 50 /*ms*/
+
+#define STI_MAX_LAYER 8
+#define STI_MAX_MIXER 2
+
+enum sti_compositor_subdev_type {
+ STI_MIXER_MAIN_SUBDEV,
+ STI_MIXER_AUX_SUBDEV,
+ STI_GPD_SUBDEV,
+ STI_VID_SUBDEV,
+ STI_CURSOR_SUBDEV,
+};
+
+struct sti_compositor_subdev_descriptor {
+ enum sti_compositor_subdev_type type;
+ int id;
+ unsigned int offset;
+};
+
+/**
+ * STI Compositor data structure
+ *
+ * @nb_subdev: number of subdevices supported by the compositor
+ * @subdev_desc: subdev list description
+ */
+#define MAX_SUBDEV 9
+struct sti_compositor_data {
+ unsigned int nb_subdev;
+ struct sti_compositor_subdev_descriptor subdev_desc[MAX_SUBDEV];
+};
+
+/**
+ * STI Compositor structure
+ *
+ * @dev: driver device
+ * @regs: registers (main)
+ * @data: device data
+ * @clk_compo_main: clock for main compo
+ * @clk_compo_aux: clock for aux compo
+ * @clk_pix_main: pixel clock for main path
+ * @clk_pix_aux: pixel clock for aux path
+ * @rst_main: reset control of the main path
+ * @rst_aux: reset control of the aux path
+ * @mixer: array of mixers
+ * @vtg_main: vtg for main data path
+ * @vtg_aux: vtg for auxillary data path
+ * @layer: array of layers
+ * @nb_mixers: number of mixers for this compositor
+ * @nb_layers: number of layers (GDP,VID,...) for this compositor
+ * @enable: true if compositor is enable else false
+ * @vtg_vblank_nb: callback for VTG VSYNC notification
+ */
+struct sti_compositor {
+ struct device *dev;
+ void __iomem *regs;
+ struct sti_compositor_data data;
+ struct clk *clk_compo_main;
+ struct clk *clk_compo_aux;
+ struct clk *clk_pix_main;
+ struct clk *clk_pix_aux;
+ struct reset_control *rst_main;
+ struct reset_control *rst_aux;
+ struct sti_mixer *mixer[STI_MAX_MIXER];
+ struct sti_vtg *vtg_main;
+ struct sti_vtg *vtg_aux;
+ struct sti_layer *layer[STI_MAX_LAYER];
+ int nb_mixers;
+ int nb_layers;
+ bool enable;
+ struct notifier_block vtg_vblank_nb;
+};
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c
new file mode 100644
index 000000000000..d2ae0c0e13be
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "sti_compositor.h"
+#include "sti_drm_drv.h"
+#include "sti_drm_crtc.h"
+#include "sti_vtg.h"
+
+static void sti_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+ DRM_DEBUG_KMS("\n");
+}
+
+static void sti_drm_crtc_prepare(struct drm_crtc *crtc)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ struct device *dev = mixer->dev;
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+
+ compo->enable = true;
+
+ /* Prepare and enable the compo IP clock */
+ if (mixer->id == STI_MIXER_MAIN) {
+ if (clk_prepare_enable(compo->clk_compo_main))
+ DRM_INFO("Failed to prepare/enable compo_main clk\n");
+ } else {
+ if (clk_prepare_enable(compo->clk_compo_aux))
+ DRM_INFO("Failed to prepare/enable compo_aux clk\n");
+ }
+}
+
+static void sti_drm_crtc_commit(struct drm_crtc *crtc)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ struct device *dev = mixer->dev;
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+ struct sti_layer *layer;
+
+ if ((!mixer || !compo)) {
+ DRM_ERROR("Can not find mixer or compositor)\n");
+ return;
+ }
+
+ /* get GDP which is reserved to the CRTC FB */
+ layer = to_sti_layer(crtc->primary);
+ if (layer)
+ sti_layer_commit(layer);
+ else
+ DRM_ERROR("Can not find CRTC dedicated plane (GDP0)\n");
+
+ /* Enable layer on mixer */
+ if (sti_mixer_set_layer_status(mixer, layer, true))
+ DRM_ERROR("Can not enable layer at mixer\n");
+}
+
+static bool sti_drm_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ /* accept the provided drm_display_mode, do not fix it up */
+ return true;
+}
+
+static int
+sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ struct device *dev = mixer->dev;
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+ struct sti_layer *layer;
+ struct clk *clk;
+ int rate = mode->clock * 1000;
+ int res;
+ unsigned int w, h;
+
+ DRM_DEBUG_KMS("CRTC:%d (%s) fb:%d mode:%d (%s)\n",
+ crtc->base.id, sti_mixer_to_str(mixer),
+ crtc->primary->fb->base.id, mode->base.id, mode->name);
+
+ DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
+ mode->vrefresh, mode->clock,
+ mode->hdisplay,
+ mode->hsync_start, mode->hsync_end,
+ mode->htotal,
+ mode->vdisplay,
+ mode->vsync_start, mode->vsync_end,
+ mode->vtotal, mode->type, mode->flags);
+
+ /* Set rate and prepare/enable pixel clock */
+ if (mixer->id == STI_MIXER_MAIN)
+ clk = compo->clk_pix_main;
+ else
+ clk = compo->clk_pix_aux;
+
+ res = clk_set_rate(clk, rate);
+ if (res < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for pix clk\n", rate);
+ return -EINVAL;
+ }
+ if (clk_prepare_enable(clk)) {
+ DRM_ERROR("Failed to prepare/enable pix clk\n");
+ return -EINVAL;
+ }
+
+ sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux, &crtc->mode);
+
+ /* a GDP is reserved to the CRTC FB */
+ layer = to_sti_layer(crtc->primary);
+ if (!layer) {
+ DRM_ERROR("Can not find GDP0)\n");
+ return -EINVAL;
+ }
+
+ /* copy the mode data adjusted by mode_fixup() into crtc->mode
+ * so that hardware can be set to proper mode
+ */
+ memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
+
+ res = sti_mixer_set_layer_depth(mixer, layer);
+ if (res) {
+ DRM_ERROR("Can not set layer depth\n");
+ return -EINVAL;
+ }
+ res = sti_mixer_active_video_area(mixer, &crtc->mode);
+ if (res) {
+ DRM_ERROR("Can not set active video area\n");
+ return -EINVAL;
+ }
+
+ w = crtc->primary->fb->width - x;
+ h = crtc->primary->fb->height - y;
+
+ return sti_layer_prepare(layer, crtc->primary->fb, &crtc->mode,
+ mixer->id, 0, 0, w, h, x, y, w, h);
+}
+
+static int sti_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ struct sti_layer *layer;
+ unsigned int w, h;
+ int ret;
+
+ DRM_DEBUG_KMS("CRTC:%d (%s) fb:%d (%d,%d)\n",
+ crtc->base.id, sti_mixer_to_str(mixer),
+ crtc->primary->fb->base.id, x, y);
+
+ /* GDP is reserved to the CRTC FB */
+ layer = to_sti_layer(crtc->primary);
+ if (!layer) {
+ DRM_ERROR("Can not find GDP0)\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ w = crtc->primary->fb->width - crtc->x;
+ h = crtc->primary->fb->height - crtc->y;
+
+ ret = sti_layer_prepare(layer, crtc->primary->fb, &crtc->mode,
+ mixer->id, 0, 0, w, h,
+ crtc->x, crtc->y, w, h);
+ if (ret) {
+ DRM_ERROR("Can not prepare layer\n");
+ goto out;
+ }
+
+ sti_drm_crtc_commit(crtc);
+out:
+ return ret;
+}
+
+static void sti_drm_crtc_load_lut(struct drm_crtc *crtc)
+{
+ /* do nothing */
+}
+
+static void sti_drm_crtc_disable(struct drm_crtc *crtc)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ struct device *dev = mixer->dev;
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+ struct sti_layer *layer;
+
+ if (!compo->enable)
+ return;
+
+ DRM_DEBUG_KMS("CRTC:%d (%s)\n", crtc->base.id, sti_mixer_to_str(mixer));
+
+ /* Disable Background */
+ sti_mixer_set_background_status(mixer, false);
+
+ /* Disable GDP */
+ layer = to_sti_layer(crtc->primary);
+ if (!layer) {
+ DRM_ERROR("Cannot find GDP0\n");
+ return;
+ }
+
+ /* Disable layer at mixer level */
+ if (sti_mixer_set_layer_status(mixer, layer, false))
+ DRM_ERROR("Can not disable %s layer at mixer\n",
+ sti_layer_to_str(layer));
+
+ /* Wait a while to be sure that a Vsync event is received */
+ msleep(WAIT_NEXT_VSYNC_MS);
+
+ /* Then disable layer itself */
+ sti_layer_disable(layer);
+
+ drm_vblank_off(crtc->dev, mixer->id);
+
+ /* Disable pixel clock and compo IP clocks */
+ if (mixer->id == STI_MIXER_MAIN) {
+ clk_disable_unprepare(compo->clk_pix_main);
+ clk_disable_unprepare(compo->clk_compo_main);
+ } else {
+ clk_disable_unprepare(compo->clk_pix_aux);
+ clk_disable_unprepare(compo->clk_compo_aux);
+ }
+
+ compo->enable = false;
+}
+
+static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
+ .dpms = sti_drm_crtc_dpms,
+ .prepare = sti_drm_crtc_prepare,
+ .commit = sti_drm_crtc_commit,
+ .mode_fixup = sti_drm_crtc_mode_fixup,
+ .mode_set = sti_drm_crtc_mode_set,
+ .mode_set_base = sti_drm_crtc_mode_set_base,
+ .load_lut = sti_drm_crtc_load_lut,
+ .disable = sti_drm_crtc_disable,
+};
+
+static int sti_drm_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 *drm_dev = crtc->dev;
+ struct drm_framebuffer *old_fb;
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ unsigned long flags;
+ int ret;
+
+ DRM_DEBUG_KMS("fb %d --> fb %d\n",
+ crtc->primary->fb->base.id, fb->base.id);
+
+ mutex_lock(&drm_dev->struct_mutex);
+
+ old_fb = crtc->primary->fb;
+ crtc->primary->fb = fb;
+ ret = sti_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb);
+ if (ret) {
+ DRM_ERROR("failed\n");
+ crtc->primary->fb = old_fb;
+ goto out;
+ }
+
+ if (event) {
+ event->pipe = mixer->id;
+
+ ret = drm_vblank_get(drm_dev, event->pipe);
+ if (ret) {
+ DRM_ERROR("Cannot get vblank\n");
+ goto out;
+ }
+
+ spin_lock_irqsave(&drm_dev->event_lock, flags);
+ if (mixer->pending_event) {
+ drm_vblank_put(drm_dev, event->pipe);
+ ret = -EBUSY;
+ } else {
+ mixer->pending_event = event;
+ }
+ spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+ }
+out:
+ mutex_unlock(&drm_dev->struct_mutex);
+ return ret;
+}
+
+static void sti_drm_crtc_destroy(struct drm_crtc *crtc)
+{
+ DRM_DEBUG_KMS("\n");
+ drm_crtc_cleanup(crtc);
+}
+
+static int sti_drm_crtc_set_property(struct drm_crtc *crtc,
+ struct drm_property *property,
+ uint64_t val)
+{
+ DRM_DEBUG_KMS("\n");
+ return 0;
+}
+
+int sti_drm_crtc_vblank_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct drm_device *drm_dev;
+ struct sti_compositor *compo =
+ container_of(nb, struct sti_compositor, vtg_vblank_nb);
+ int *crtc = data;
+ unsigned long flags;
+ struct sti_drm_private *priv;
+
+ drm_dev = compo->mixer[*crtc]->drm_crtc.dev;
+ priv = drm_dev->dev_private;
+
+ if ((event != VTG_TOP_FIELD_EVENT) &&
+ (event != VTG_BOTTOM_FIELD_EVENT)) {
+ DRM_ERROR("unknown event: %lu\n", event);
+ return -EINVAL;
+ }
+
+ drm_handle_vblank(drm_dev, *crtc);
+
+ spin_lock_irqsave(&drm_dev->event_lock, flags);
+ if (compo->mixer[*crtc]->pending_event) {
+ drm_send_vblank_event(drm_dev, -1,
+ compo->mixer[*crtc]->pending_event);
+ drm_vblank_put(drm_dev, *crtc);
+ compo->mixer[*crtc]->pending_event = NULL;
+ }
+ spin_unlock_irqrestore(&drm_dev->event_lock, flags);
+
+ return 0;
+}
+
+int sti_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
+{
+ struct sti_drm_private *dev_priv = dev->dev_private;
+ struct sti_compositor *compo = dev_priv->compo;
+ struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+
+ if (sti_vtg_register_client(crtc == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux,
+ vtg_vblank_nb, crtc)) {
+ DRM_ERROR("Cannot register VTG notifier\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sti_drm_crtc_enable_vblank);
+
+void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
+{
+ struct sti_drm_private *priv = dev->dev_private;
+ struct sti_compositor *compo = priv->compo;
+ struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb;
+ unsigned long flags;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (sti_vtg_unregister_client(crtc == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux, vtg_vblank_nb))
+ DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n");
+
+ /* free the resources of the pending requests */
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (compo->mixer[crtc]->pending_event) {
+ drm_vblank_put(dev, crtc);
+ compo->mixer[crtc]->pending_event = NULL;
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+}
+EXPORT_SYMBOL(sti_drm_crtc_disable_vblank);
+
+static struct drm_crtc_funcs sti_crtc_funcs = {
+ .set_config = drm_crtc_helper_set_config,
+ .page_flip = sti_drm_crtc_page_flip,
+ .destroy = sti_drm_crtc_destroy,
+ .set_property = sti_drm_crtc_set_property,
+};
+
+bool sti_drm_crtc_is_main(struct drm_crtc *crtc)
+{
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+
+ if (mixer->id == STI_MIXER_MAIN)
+ return true;
+
+ return false;
+}
+
+int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
+ struct drm_plane *primary, struct drm_plane *cursor)
+{
+ struct drm_crtc *crtc = &mixer->drm_crtc;
+ int res;
+
+ res = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
+ &sti_crtc_funcs);
+ if (res) {
+ DRM_ERROR("Can not initialze CRTC\n");
+ return -EINVAL;
+ }
+
+ drm_crtc_helper_add(crtc, &sti_crtc_helper_funcs);
+
+ DRM_DEBUG_DRIVER("drm CRTC:%d mapped to %s\n",
+ crtc->base.id, sti_mixer_to_str(mixer));
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.h b/drivers/gpu/drm/sti/sti_drm_crtc.h
new file mode 100644
index 000000000000..caca8b14f017
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_DRM_CRTC_H_
+#define _STI_DRM_CRTC_H_
+
+#include <drm/drmP.h>
+
+struct sti_mixer;
+
+int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer,
+ struct drm_plane *primary, struct drm_plane *cursor);
+int sti_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
+void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
+int sti_drm_crtc_vblank_cb(struct notifier_block *nb,
+ unsigned long event, void *data);
+bool sti_drm_crtc_is_main(struct drm_crtc *drm_crtc);
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.c b/drivers/gpu/drm/sti/sti_drm_drv.c
new file mode 100644
index 000000000000..a7cc24917a96
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_drv.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <drm/drmP.h>
+
+#include <linux/component.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "sti_drm_drv.h"
+#include "sti_drm_crtc.h"
+
+#define DRIVER_NAME "sti"
+#define DRIVER_DESC "STMicroelectronics SoC DRM"
+#define DRIVER_DATE "20140601"
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+
+#define STI_MAX_FB_HEIGHT 4096
+#define STI_MAX_FB_WIDTH 4096
+
+static struct drm_mode_config_funcs sti_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+};
+
+static void sti_drm_mode_config_init(struct drm_device *dev)
+{
+ dev->mode_config.min_width = 0;
+ dev->mode_config.min_height = 0;
+
+ /*
+ * set max width and height as default value.
+ * this value would be used to check framebuffer size limitation
+ * at drm_mode_addfb().
+ */
+ dev->mode_config.max_width = STI_MAX_FB_HEIGHT;
+ dev->mode_config.max_height = STI_MAX_FB_WIDTH;
+
+ dev->mode_config.funcs = &sti_drm_mode_config_funcs;
+}
+
+static int sti_drm_load(struct drm_device *dev, unsigned long flags)
+{
+ struct sti_drm_private *private;
+ int ret;
+
+ private = kzalloc(sizeof(struct sti_drm_private), GFP_KERNEL);
+ if (!private) {
+ DRM_ERROR("Failed to allocate private\n");
+ return -ENOMEM;
+ }
+ dev->dev_private = (void *)private;
+ private->drm_dev = dev;
+
+ drm_mode_config_init(dev);
+ drm_kms_helper_poll_init(dev);
+
+ sti_drm_mode_config_init(dev);
+
+ ret = component_bind_all(dev->dev, dev);
+ if (ret)
+ return ret;
+
+ drm_helper_disable_unused_functions(dev);
+
+#ifdef CONFIG_DRM_STI_FBDEV
+ drm_fbdev_cma_init(dev, 32,
+ dev->mode_config.num_crtc,
+ dev->mode_config.num_connector);
+#endif
+ return 0;
+}
+
+static const struct file_operations sti_drm_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .mmap = drm_gem_cma_mmap,
+ .poll = drm_poll,
+ .read = drm_read,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .release = drm_release,
+};
+
+static struct dma_buf *sti_drm_gem_prime_export(struct drm_device *dev,
+ struct drm_gem_object *obj,
+ int flags)
+{
+ /* we want to be able to write in mmapped buffer */
+ flags |= O_RDWR;
+ return drm_gem_prime_export(dev, obj, flags);
+}
+
+static struct drm_driver sti_drm_driver = {
+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET |
+ DRIVER_GEM | DRIVER_PRIME,
+ .load = sti_drm_load,
+ .gem_free_object = 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_drm_driver_fops,
+
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = sti_drm_crtc_enable_vblank,
+ .disable_vblank = sti_drm_crtc_disable_vblank,
+
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = sti_drm_gem_prime_export,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+ .gem_prime_vmap = drm_gem_cma_prime_vmap,
+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+ .gem_prime_mmap = drm_gem_cma_prime_mmap,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+static int sti_drm_bind(struct device *dev)
+{
+ return drm_platform_init(&sti_drm_driver, to_platform_device(dev));
+}
+
+static void sti_drm_unbind(struct device *dev)
+{
+ drm_put_dev(dev_get_drvdata(dev));
+}
+
+static const struct component_master_ops sti_drm_ops = {
+ .bind = sti_drm_bind,
+ .unbind = sti_drm_unbind,
+};
+
+static int sti_drm_master_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->parent->of_node;
+ struct device_node *child_np;
+ struct component_match *match = NULL;
+
+ dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+
+ child_np = of_get_next_available_child(node, NULL);
+
+ while (child_np) {
+ component_match_add(dev, &match, compare_of, child_np);
+ of_node_put(child_np);
+ child_np = of_get_next_available_child(node, child_np);
+ }
+
+ return component_master_add_with_match(dev, &sti_drm_ops, match);
+}
+
+static int sti_drm_master_remove(struct platform_device *pdev)
+{
+ component_master_del(&pdev->dev, &sti_drm_ops);
+ return 0;
+}
+
+static struct platform_driver sti_drm_master_driver = {
+ .probe = sti_drm_master_probe,
+ .remove = sti_drm_master_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME "__master",
+ },
+};
+
+static int sti_drm_platform_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct platform_device *master;
+
+ of_platform_populate(node, NULL, NULL, dev);
+
+ platform_driver_register(&sti_drm_master_driver);
+ master = platform_device_register_resndata(dev,
+ DRIVER_NAME "__master", -1,
+ NULL, 0, NULL, 0);
+ if (!master)
+ return -EINVAL;
+
+ platform_set_drvdata(pdev, master);
+ return 0;
+}
+
+static int sti_drm_platform_remove(struct platform_device *pdev)
+{
+ struct platform_device *master = platform_get_drvdata(pdev);
+
+ of_platform_depopulate(&pdev->dev);
+ platform_device_unregister(master);
+ platform_driver_unregister(&sti_drm_master_driver);
+ return 0;
+}
+
+static const struct of_device_id sti_drm_dt_ids[] = {
+ { .compatible = "st,sti-display-subsystem", },
+ { /* end node */ },
+};
+MODULE_DEVICE_TABLE(of, sti_drm_dt_ids);
+
+static struct platform_driver sti_drm_platform_driver = {
+ .probe = sti_drm_platform_probe,
+ .remove = sti_drm_platform_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .of_match_table = sti_drm_dt_ids,
+ },
+};
+
+module_platform_driver(sti_drm_platform_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.h b/drivers/gpu/drm/sti/sti_drm_drv.h
new file mode 100644
index 000000000000..ec5e2eb8dff9
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_drv.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_DRM_DRV_H_
+#define _STI_DRM_DRV_H_
+
+#include <drm/drmP.h>
+
+struct sti_compositor;
+struct sti_tvout;
+
+/**
+ * STI drm private structure
+ * This structure is stored as private in the drm_device
+ *
+ * @compo: compositor
+ * @plane_zorder_property: z-order property for CRTC planes
+ * @drm_dev: drm device
+ */
+struct sti_drm_private {
+ struct sti_compositor *compo;
+ struct drm_property *plane_zorder_property;
+ struct drm_device *drm_dev;
+};
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_drm_plane.c b/drivers/gpu/drm/sti/sti_drm_plane.c
new file mode 100644
index 000000000000..f4118d4cac22
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_plane.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include "sti_compositor.h"
+#include "sti_drm_drv.h"
+#include "sti_drm_plane.h"
+#include "sti_vtg.h"
+
+enum sti_layer_desc sti_layer_default_zorder[] = {
+ STI_GDP_0,
+ STI_VID_0,
+ STI_GDP_1,
+ STI_VID_1,
+ STI_GDP_2,
+ STI_GDP_3,
+};
+
+/* (Background) < GDP0 < VID0 < GDP1 < VID1 < GDP2 < GDP3 < (ForeGround) */
+
+static int
+sti_drm_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,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct sti_layer *layer = to_sti_layer(plane);
+ struct sti_mixer *mixer = to_sti_mixer(crtc);
+ int res;
+
+ DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s) drm fb:%d\n",
+ crtc->base.id, sti_mixer_to_str(mixer),
+ plane->base.id, sti_layer_to_str(layer), fb->base.id);
+ DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", crtc_w, crtc_h, crtc_x, crtc_y);
+
+ res = sti_mixer_set_layer_depth(mixer, layer);
+ if (res) {
+ DRM_ERROR("Can not set layer depth\n");
+ return res;
+ }
+
+ /* src_x are in 16.16 format. */
+ res = sti_layer_prepare(layer, fb, &crtc->mode, mixer->id,
+ crtc_x, crtc_y, crtc_w, crtc_h,
+ src_x >> 16, src_y >> 16,
+ src_w >> 16, src_h >> 16);
+ if (res) {
+ DRM_ERROR("Layer prepare failed\n");
+ return res;
+ }
+
+ res = sti_layer_commit(layer);
+ if (res) {
+ DRM_ERROR("Layer commit failed\n");
+ return res;
+ }
+
+ res = sti_mixer_set_layer_status(mixer, layer, true);
+ if (res) {
+ DRM_ERROR("Can not enable layer at mixer\n");
+ return res;
+ }
+
+ return 0;
+}
+
+static int sti_drm_disable_plane(struct drm_plane *plane)
+{
+ struct sti_layer *layer;
+ struct sti_mixer *mixer;
+ int lay_res, mix_res;
+
+ if (!plane->crtc) {
+ DRM_DEBUG_DRIVER("drm plane:%d not enabled\n", plane->base.id);
+ return 0;
+ }
+ layer = to_sti_layer(plane);
+ mixer = to_sti_mixer(plane->crtc);
+
+ DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
+ plane->crtc->base.id, sti_mixer_to_str(mixer),
+ plane->base.id, sti_layer_to_str(layer));
+
+ /* Disable layer at mixer level */
+ mix_res = sti_mixer_set_layer_status(mixer, layer, false);
+ if (mix_res)
+ DRM_ERROR("Can not disable layer at mixer\n");
+
+ /* Wait a while to be sure that a Vsync event is received */
+ msleep(WAIT_NEXT_VSYNC_MS);
+
+ /* Then disable layer itself */
+ lay_res = sti_layer_disable(layer);
+ if (lay_res)
+ DRM_ERROR("Layer disable failed\n");
+
+ if (lay_res || mix_res)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void sti_drm_plane_destroy(struct drm_plane *plane)
+{
+ DRM_DEBUG_DRIVER("\n");
+
+ sti_drm_disable_plane(plane);
+ drm_plane_cleanup(plane);
+}
+
+static int sti_drm_plane_set_property(struct drm_plane *plane,
+ struct drm_property *property,
+ uint64_t val)
+{
+ struct drm_device *dev = plane->dev;
+ struct sti_drm_private *private = dev->dev_private;
+ struct sti_layer *layer = to_sti_layer(plane);
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (property == private->plane_zorder_property) {
+ layer->zorder = val;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static struct drm_plane_funcs sti_drm_plane_funcs = {
+ .update_plane = sti_drm_update_plane,
+ .disable_plane = sti_drm_disable_plane,
+ .destroy = sti_drm_plane_destroy,
+ .set_property = sti_drm_plane_set_property,
+};
+
+static void sti_drm_plane_attach_zorder_property(struct drm_plane *plane,
+ uint64_t default_val)
+{
+ struct drm_device *dev = plane->dev;
+ struct sti_drm_private *private = dev->dev_private;
+ struct drm_property *prop;
+ struct sti_layer *layer = to_sti_layer(plane);
+
+ prop = private->plane_zorder_property;
+ if (!prop) {
+ prop = drm_property_create_range(dev, 0, "zpos", 0,
+ GAM_MIXER_NB_DEPTH_LEVEL - 1);
+ if (!prop)
+ return;
+
+ private->plane_zorder_property = prop;
+ }
+
+ drm_object_attach_property(&plane->base, prop, default_val);
+ layer->zorder = default_val;
+}
+
+struct drm_plane *sti_drm_plane_init(struct drm_device *dev,
+ struct sti_layer *layer,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type)
+{
+ int err, i;
+ uint64_t default_zorder = 0;
+
+ err = drm_universal_plane_init(dev, &layer->plane, possible_crtcs,
+ &sti_drm_plane_funcs,
+ sti_layer_get_formats(layer),
+ sti_layer_get_nb_formats(layer), type);
+ if (err) {
+ DRM_ERROR("Failed to initialize plane\n");
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sti_layer_default_zorder); i++)
+ if (sti_layer_default_zorder[i] == layer->desc)
+ break;
+
+ default_zorder = i;
+
+ if (type == DRM_PLANE_TYPE_OVERLAY)
+ sti_drm_plane_attach_zorder_property(&layer->plane,
+ default_zorder);
+
+ DRM_DEBUG_DRIVER("drm plane:%d mapped to %s with zorder:%llu\n",
+ layer->plane.base.id,
+ sti_layer_to_str(layer), default_zorder);
+
+ return &layer->plane;
+}
diff --git a/drivers/gpu/drm/sti/sti_drm_plane.h b/drivers/gpu/drm/sti/sti_drm_plane.h
new file mode 100644
index 000000000000..4f191839f2a7
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_drm_plane.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_DRM_PLANE_H_
+#define _STI_DRM_PLANE_H_
+
+#include <drm/drmP.h>
+
+struct sti_layer;
+
+struct drm_plane *sti_drm_plane_init(struct drm_device *dev,
+ struct sti_layer *layer,
+ unsigned int possible_crtcs,
+ enum drm_plane_type type);
+#endif
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
new file mode 100644
index 000000000000..4e30b74559f5
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
+#include "sti_compositor.h"
+#include "sti_gdp.h"
+#include "sti_layer.h"
+#include "sti_vtg.h"
+
+#define ENA_COLOR_FILL BIT(8)
+#define WAIT_NEXT_VSYNC BIT(31)
+
+/* GDP color formats */
+#define GDP_RGB565 0x00
+#define GDP_RGB888 0x01
+#define GDP_RGB888_32 0x02
+#define GDP_ARGB8565 0x04
+#define GDP_ARGB8888 0x05
+#define GDP_ARGB1555 0x06
+#define GDP_ARGB4444 0x07
+#define GDP_CLUT8 0x0B
+#define GDP_YCBR888 0x10
+#define GDP_YCBR422R 0x12
+#define GDP_AYCBR8888 0x15
+
+#define GAM_GDP_CTL_OFFSET 0x00
+#define GAM_GDP_AGC_OFFSET 0x04
+#define GAM_GDP_VPO_OFFSET 0x0C
+#define GAM_GDP_VPS_OFFSET 0x10
+#define GAM_GDP_PML_OFFSET 0x14
+#define GAM_GDP_PMP_OFFSET 0x18
+#define GAM_GDP_SIZE_OFFSET 0x1C
+#define GAM_GDP_NVN_OFFSET 0x24
+#define GAM_GDP_KEY1_OFFSET 0x28
+#define GAM_GDP_KEY2_OFFSET 0x2C
+#define GAM_GDP_PPT_OFFSET 0x34
+#define GAM_GDP_CML_OFFSET 0x3C
+#define GAM_GDP_MST_OFFSET 0x68
+
+#define GAM_GDP_ALPHARANGE_255 BIT(5)
+#define GAM_GDP_AGC_FULL_RANGE 0x00808080
+#define GAM_GDP_PPT_IGNORE (BIT(1) | BIT(0))
+#define GAM_GDP_SIZE_MAX 0x7FF
+
+#define GDP_NODE_NB_BANK 2
+#define GDP_NODE_PER_FIELD 2
+
+struct sti_gdp_node {
+ u32 gam_gdp_ctl;
+ u32 gam_gdp_agc;
+ u32 reserved1;
+ u32 gam_gdp_vpo;
+ u32 gam_gdp_vps;
+ u32 gam_gdp_pml;
+ u32 gam_gdp_pmp;
+ u32 gam_gdp_size;
+ u32 reserved2;
+ u32 gam_gdp_nvn;
+ u32 gam_gdp_key1;
+ u32 gam_gdp_key2;
+ u32 reserved3;
+ u32 gam_gdp_ppt;
+ u32 reserved4;
+ u32 gam_gdp_cml;
+};
+
+struct sti_gdp_node_list {
+ struct sti_gdp_node *top_field;
+ struct sti_gdp_node *btm_field;
+};
+
+/**
+ * STI GDP structure
+ *
+ * @layer: layer structure
+ * @clk_pix: pixel clock for the current gdp
+ * @vtg_field_nb: callback for VTG FIELD (top or bottom) notification
+ * @is_curr_top: true if the current node processed is the top field
+ * @node_list: array of node list
+ */
+struct sti_gdp {
+ struct sti_layer layer;
+ struct clk *clk_pix;
+ struct notifier_block vtg_field_nb;
+ bool is_curr_top;
+ struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK];
+};
+
+#define to_sti_gdp(x) container_of(x, struct sti_gdp, layer)
+
+static const uint32_t gdp_supported_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_AYUV,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_VYUY,
+ DRM_FORMAT_C8,
+};
+
+static const uint32_t *sti_gdp_get_formats(struct sti_layer *layer)
+{
+ return gdp_supported_formats;
+}
+
+static unsigned int sti_gdp_get_nb_formats(struct sti_layer *layer)
+{
+ return ARRAY_SIZE(gdp_supported_formats);
+}
+
+static int sti_gdp_fourcc2format(int fourcc)
+{
+ switch (fourcc) {
+ case DRM_FORMAT_XRGB8888:
+ return GDP_RGB888_32;
+ case DRM_FORMAT_ARGB8888:
+ return GDP_ARGB8888;
+ case DRM_FORMAT_ARGB4444:
+ return GDP_ARGB4444;
+ case DRM_FORMAT_ARGB1555:
+ return GDP_ARGB1555;
+ case DRM_FORMAT_RGB565:
+ return GDP_RGB565;
+ case DRM_FORMAT_RGB888:
+ return GDP_RGB888;
+ case DRM_FORMAT_AYUV:
+ return GDP_AYCBR8888;
+ case DRM_FORMAT_YUV444:
+ return GDP_YCBR888;
+ case DRM_FORMAT_VYUY:
+ return GDP_YCBR422R;
+ case DRM_FORMAT_C8:
+ return GDP_CLUT8;
+ }
+ return -1;
+}
+
+static int sti_gdp_get_alpharange(int format)
+{
+ switch (format) {
+ case GDP_ARGB8565:
+ case GDP_ARGB8888:
+ case GDP_AYCBR8888:
+ return GAM_GDP_ALPHARANGE_255;
+ }
+ return 0;
+}
+
+/**
+ * sti_gdp_get_free_nodes
+ * @layer: gdp layer
+ *
+ * Look for a GDP node list that is not currently read by the HW.
+ *
+ * RETURNS:
+ * Pointer to the free GDP node list
+ */
+static struct sti_gdp_node_list *sti_gdp_get_free_nodes(struct sti_layer *layer)
+{
+ int hw_nvn;
+ void *virt_nvn;
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ unsigned int i;
+
+ hw_nvn = readl(layer->regs + GAM_GDP_NVN_OFFSET);
+ if (!hw_nvn)
+ goto end;
+
+ virt_nvn = dma_to_virt(layer->dev, (dma_addr_t) hw_nvn);
+
+ for (i = 0; i < GDP_NODE_NB_BANK; i++)
+ if ((virt_nvn != gdp->node_list[i].btm_field) &&
+ (virt_nvn != gdp->node_list[i].top_field))
+ return &gdp->node_list[i];
+
+ /* in hazardious cases restart with the first node */
+ DRM_ERROR("inconsistent NVN for %s: 0x%08X\n",
+ sti_layer_to_str(layer), hw_nvn);
+
+end:
+ return &gdp->node_list[0];
+}
+
+/**
+ * sti_gdp_get_current_nodes
+ * @layer: GDP layer
+ *
+ * Look for GDP nodes that are currently read by the HW.
+ *
+ * RETURNS:
+ * Pointer to the current GDP node list
+ */
+static
+struct sti_gdp_node_list *sti_gdp_get_current_nodes(struct sti_layer *layer)
+{
+ int hw_nvn;
+ void *virt_nvn;
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ unsigned int i;
+
+ hw_nvn = readl(layer->regs + GAM_GDP_NVN_OFFSET);
+ if (!hw_nvn)
+ goto end;
+
+ virt_nvn = dma_to_virt(layer->dev, (dma_addr_t) hw_nvn);
+
+ for (i = 0; i < GDP_NODE_NB_BANK; i++)
+ if ((virt_nvn == gdp->node_list[i].btm_field) ||
+ (virt_nvn == gdp->node_list[i].top_field))
+ return &gdp->node_list[i];
+
+end:
+ DRM_DEBUG_DRIVER("Warning, NVN 0x%08X for %s does not match any node\n",
+ hw_nvn, sti_layer_to_str(layer));
+
+ return NULL;
+}
+
+/**
+ * sti_gdp_prepare_layer
+ * @lay: gdp layer
+ * @first_prepare: true if it is the first time this function is called
+ *
+ * Update the free GDP node list according to the layer properties.
+ *
+ * RETURNS:
+ * 0 on success.
+ */
+static int sti_gdp_prepare_layer(struct sti_layer *layer, bool first_prepare)
+{
+ struct sti_gdp_node_list *list;
+ struct sti_gdp_node *top_field, *btm_field;
+ struct drm_display_mode *mode = layer->mode;
+ struct device *dev = layer->dev;
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ struct sti_compositor *compo = dev_get_drvdata(dev);
+ int format;
+ unsigned int depth, bpp;
+ int rate = mode->clock * 1000;
+ int res;
+ u32 ydo, xdo, yds, xds;
+
+ list = sti_gdp_get_free_nodes(layer);
+ top_field = list->top_field;
+ btm_field = list->btm_field;
+
+ dev_dbg(dev, "%s %s top_node:0x%p btm_node:0x%p\n", __func__,
+ sti_layer_to_str(layer), top_field, btm_field);
+
+ /* Build the top field from layer params */
+ top_field->gam_gdp_agc = GAM_GDP_AGC_FULL_RANGE;
+ top_field->gam_gdp_ctl = WAIT_NEXT_VSYNC;
+ format = sti_gdp_fourcc2format(layer->format);
+ if (format == -1) {
+ DRM_ERROR("Format not supported by GDP %.4s\n",
+ (char *)&layer->format);
+ return 1;
+ }
+ top_field->gam_gdp_ctl |= format;
+ top_field->gam_gdp_ctl |= sti_gdp_get_alpharange(format);
+ top_field->gam_gdp_ppt &= ~GAM_GDP_PPT_IGNORE;
+
+ /* pixel memory location */
+ drm_fb_get_bpp_depth(layer->format, &depth, &bpp);
+ top_field->gam_gdp_pml = (u32) layer->paddr + layer->offsets[0];
+ top_field->gam_gdp_pml += layer->src_x * (bpp >> 3);
+ top_field->gam_gdp_pml += layer->src_y * layer->pitches[0];
+
+ /* input parameters */
+ top_field->gam_gdp_pmp = layer->pitches[0];
+ top_field->gam_gdp_size =
+ clamp_val(layer->src_h, 0, GAM_GDP_SIZE_MAX) << 16 |
+ clamp_val(layer->src_w, 0, GAM_GDP_SIZE_MAX);
+
+ /* output parameters */
+ ydo = sti_vtg_get_line_number(*mode, layer->dst_y);
+ yds = sti_vtg_get_line_number(*mode, layer->dst_y + layer->dst_h - 1);
+ xdo = sti_vtg_get_pixel_number(*mode, layer->dst_x);
+ xds = sti_vtg_get_pixel_number(*mode, layer->dst_x + layer->dst_w - 1);
+ top_field->gam_gdp_vpo = (ydo << 16) | xdo;
+ top_field->gam_gdp_vps = (yds << 16) | xds;
+
+ /* Same content and chained together */
+ memcpy(btm_field, top_field, sizeof(*btm_field));
+ top_field->gam_gdp_nvn = virt_to_dma(dev, btm_field);
+ btm_field->gam_gdp_nvn = virt_to_dma(dev, top_field);
+
+ /* Interlaced mode */
+ if (layer->mode->flags & DRM_MODE_FLAG_INTERLACE)
+ btm_field->gam_gdp_pml = top_field->gam_gdp_pml +
+ layer->pitches[0];
+
+ if (first_prepare) {
+ /* Register gdp callback */
+ if (sti_vtg_register_client(layer->mixer_id == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux,
+ &gdp->vtg_field_nb, layer->mixer_id)) {
+ DRM_ERROR("Cannot register VTG notifier\n");
+ return 1;
+ }
+
+ /* Set and enable gdp clock */
+ if (gdp->clk_pix) {
+ res = clk_set_rate(gdp->clk_pix, rate);
+ if (res < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for gdp\n",
+ rate);
+ return 1;
+ }
+
+ if (clk_prepare_enable(gdp->clk_pix)) {
+ DRM_ERROR("Failed to prepare/enable gdp\n");
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * sti_gdp_commit_layer
+ * @lay: gdp layer
+ *
+ * Update the NVN field of the 'right' field of the current GDP node (being
+ * used by the HW) with the address of the updated ('free') top field GDP node.
+ * - In interlaced mode the 'right' field is the bottom field as we update
+ * frames starting from their top field
+ * - In progressive mode, we update both bottom and top fields which are
+ * equal nodes.
+ * At the next VSYNC, the updated node list will be used by the HW.
+ *
+ * RETURNS:
+ * 0 on success.
+ */
+static int sti_gdp_commit_layer(struct sti_layer *layer)
+{
+ struct sti_gdp_node_list *updated_list = sti_gdp_get_free_nodes(layer);
+ struct sti_gdp_node *updated_top_node = updated_list->top_field;
+ struct sti_gdp_node *updated_btm_node = updated_list->btm_field;
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ u32 dma_updated_top = virt_to_dma(layer->dev, updated_top_node);
+ u32 dma_updated_btm = virt_to_dma(layer->dev, updated_btm_node);
+ struct sti_gdp_node_list *curr_list = sti_gdp_get_current_nodes(layer);
+
+ dev_dbg(layer->dev, "%s %s top/btm_node:0x%p/0x%p\n", __func__,
+ sti_layer_to_str(layer),
+ updated_top_node, updated_btm_node);
+ dev_dbg(layer->dev, "Current NVN:0x%X\n",
+ readl(layer->regs + GAM_GDP_NVN_OFFSET));
+ dev_dbg(layer->dev, "Posted buff: %lx current buff: %x\n",
+ (unsigned long)layer->paddr,
+ readl(layer->regs + GAM_GDP_PML_OFFSET));
+
+ if (curr_list == NULL) {
+ /* First update or invalid node should directly write in the
+ * hw register */
+ DRM_DEBUG_DRIVER("%s first update (or invalid node)",
+ sti_layer_to_str(layer));
+
+ writel(gdp->is_curr_top == true ?
+ dma_updated_btm : dma_updated_top,
+ layer->regs + GAM_GDP_NVN_OFFSET);
+ return 0;
+ }
+
+ if (layer->mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ if (gdp->is_curr_top == true) {
+ /* Do not update in the middle of the frame, but
+ * postpone the update after the bottom field has
+ * been displayed */
+ curr_list->btm_field->gam_gdp_nvn = dma_updated_top;
+ } else {
+ /* Direct update to avoid one frame delay */
+ writel(dma_updated_top,
+ layer->regs + GAM_GDP_NVN_OFFSET);
+ }
+ } else {
+ /* Direct update for progressive to avoid one frame delay */
+ writel(dma_updated_top, layer->regs + GAM_GDP_NVN_OFFSET);
+ }
+
+ return 0;
+}
+
+/**
+ * sti_gdp_disable_layer
+ * @lay: gdp layer
+ *
+ * Disable a GDP.
+ *
+ * RETURNS:
+ * 0 on success.
+ */
+static int sti_gdp_disable_layer(struct sti_layer *layer)
+{
+ unsigned int i;
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ struct sti_compositor *compo = dev_get_drvdata(layer->dev);
+
+ DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer));
+
+ /* Set the nodes as 'to be ignored on mixer' */
+ for (i = 0; i < GDP_NODE_NB_BANK; i++) {
+ gdp->node_list[i].top_field->gam_gdp_ppt |= GAM_GDP_PPT_IGNORE;
+ gdp->node_list[i].btm_field->gam_gdp_ppt |= GAM_GDP_PPT_IGNORE;
+ }
+
+ if (sti_vtg_unregister_client(layer->mixer_id == STI_MIXER_MAIN ?
+ compo->vtg_main : compo->vtg_aux, &gdp->vtg_field_nb))
+ DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n");
+
+ if (gdp->clk_pix)
+ clk_disable_unprepare(gdp->clk_pix);
+
+ return 0;
+}
+
+/**
+ * sti_gdp_field_cb
+ * @nb: notifier block
+ * @event: event message
+ * @data: private data
+ *
+ * Handle VTG top field and bottom field event.
+ *
+ * RETURNS:
+ * 0 on success.
+ */
+int sti_gdp_field_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct sti_gdp *gdp = container_of(nb, struct sti_gdp, vtg_field_nb);
+
+ switch (event) {
+ case VTG_TOP_FIELD_EVENT:
+ gdp->is_curr_top = true;
+ break;
+ case VTG_BOTTOM_FIELD_EVENT:
+ gdp->is_curr_top = false;
+ break;
+ default:
+ DRM_ERROR("unsupported event: %lu\n", event);
+ break;
+ }
+
+ return 0;
+}
+
+static void sti_gdp_init(struct sti_layer *layer)
+{
+ struct sti_gdp *gdp = to_sti_gdp(layer);
+ struct device_node *np = layer->dev->of_node;
+ dma_addr_t dma;
+ void *base;
+ unsigned int i, size;
+
+ /* Allocate all the nodes within a single memory page */
+ size = sizeof(struct sti_gdp_node) *
+ GDP_NODE_PER_FIELD * GDP_NODE_NB_BANK;
+
+ base = dma_alloc_writecombine(layer->dev,
+ size, &dma, GFP_KERNEL | GFP_DMA);
+ if (!base) {
+ DRM_ERROR("Failed to allocate memory for GDP node\n");
+ return;
+ }
+ memset(base, 0, size);
+
+ for (i = 0; i < GDP_NODE_NB_BANK; i++) {
+ if (virt_to_dma(layer->dev, base) & 0xF) {
+ DRM_ERROR("Mem alignment failed\n");
+ return;
+ }
+ gdp->node_list[i].top_field = base;
+ DRM_DEBUG_DRIVER("node[%d].top_field=%p\n", i, base);
+ base += sizeof(struct sti_gdp_node);
+
+ if (virt_to_dma(layer->dev, base) & 0xF) {
+ DRM_ERROR("Mem alignment failed\n");
+ return;
+ }
+ gdp->node_list[i].btm_field = base;
+ DRM_DEBUG_DRIVER("node[%d].btm_field=%p\n", i, base);
+ base += sizeof(struct sti_gdp_node);
+ }
+
+ if (of_device_is_compatible(np, "st,stih407-compositor")) {
+ /* GDP of STiH407 chip have its own pixel clock */
+ char *clk_name;
+
+ switch (layer->desc) {
+ case STI_GDP_0:
+ clk_name = "pix_gdp1";
+ break;
+ case STI_GDP_1:
+ clk_name = "pix_gdp2";
+ break;
+ case STI_GDP_2:
+ clk_name = "pix_gdp3";
+ break;
+ case STI_GDP_3:
+ clk_name = "pix_gdp4";
+ break;
+ default:
+ DRM_ERROR("GDP id not recognized\n");
+ return;
+ }
+
+ gdp->clk_pix = devm_clk_get(layer->dev, clk_name);
+ if (IS_ERR(gdp->clk_pix))
+ DRM_ERROR("Cannot get %s clock\n", clk_name);
+ }
+}
+
+static const struct sti_layer_funcs gdp_ops = {
+ .get_formats = sti_gdp_get_formats,
+ .get_nb_formats = sti_gdp_get_nb_formats,
+ .init = sti_gdp_init,
+ .prepare = sti_gdp_prepare_layer,
+ .commit = sti_gdp_commit_layer,
+ .disable = sti_gdp_disable_layer,
+};
+
+struct sti_layer *sti_gdp_create(struct device *dev, int id)
+{
+ struct sti_gdp *gdp;
+
+ gdp = devm_kzalloc(dev, sizeof(*gdp), GFP_KERNEL);
+ if (!gdp) {
+ DRM_ERROR("Failed to allocate memory for GDP\n");
+ return NULL;
+ }
+
+ gdp->layer.ops = &gdp_ops;
+ gdp->vtg_field_nb.notifier_call = sti_gdp_field_cb;
+
+ return (struct sti_layer *)gdp;
+}
diff --git a/drivers/gpu/drm/sti/sti_gdp.h b/drivers/gpu/drm/sti/sti_gdp.h
new file mode 100644
index 000000000000..1dab68274ad3
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_gdp.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_GDP_H_
+#define _STI_GDP_H_
+
+#include <linux/types.h>
+
+struct sti_layer *sti_gdp_create(struct device *dev, int id);
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
new file mode 100644
index 000000000000..72d957f81c05
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+/* HDformatter registers */
+#define HDA_ANA_CFG 0x0000
+#define HDA_ANA_SCALE_CTRL_Y 0x0004
+#define HDA_ANA_SCALE_CTRL_CB 0x0008
+#define HDA_ANA_SCALE_CTRL_CR 0x000C
+#define HDA_ANA_ANC_CTRL 0x0010
+#define HDA_ANA_SRC_Y_CFG 0x0014
+#define HDA_COEFF_Y_PH1_TAP123 0x0018
+#define HDA_COEFF_Y_PH1_TAP456 0x001C
+#define HDA_COEFF_Y_PH2_TAP123 0x0020
+#define HDA_COEFF_Y_PH2_TAP456 0x0024
+#define HDA_COEFF_Y_PH3_TAP123 0x0028
+#define HDA_COEFF_Y_PH3_TAP456 0x002C
+#define HDA_COEFF_Y_PH4_TAP123 0x0030
+#define HDA_COEFF_Y_PH4_TAP456 0x0034
+#define HDA_ANA_SRC_C_CFG 0x0040
+#define HDA_COEFF_C_PH1_TAP123 0x0044
+#define HDA_COEFF_C_PH1_TAP456 0x0048
+#define HDA_COEFF_C_PH2_TAP123 0x004C
+#define HDA_COEFF_C_PH2_TAP456 0x0050
+#define HDA_COEFF_C_PH3_TAP123 0x0054
+#define HDA_COEFF_C_PH3_TAP456 0x0058
+#define HDA_COEFF_C_PH4_TAP123 0x005C
+#define HDA_COEFF_C_PH4_TAP456 0x0060
+#define HDA_SYNC_AWGI 0x0300
+
+/* HDA_ANA_CFG */
+#define CFG_AWG_ASYNC_EN BIT(0)
+#define CFG_AWG_ASYNC_HSYNC_MTD BIT(1)
+#define CFG_AWG_ASYNC_VSYNC_MTD BIT(2)
+#define CFG_AWG_SYNC_DEL BIT(3)
+#define CFG_AWG_FLTR_MODE_SHIFT 4
+#define CFG_AWG_FLTR_MODE_MASK (0xF << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_SD (0 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_ED (1 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_AWG_FLTR_MODE_HD (2 << CFG_AWG_FLTR_MODE_SHIFT)
+#define CFG_SYNC_ON_PBPR_MASK BIT(8)
+#define CFG_PREFILTER_EN_MASK BIT(9)
+#define CFG_PBPR_SYNC_OFF_SHIFT 16
+#define CFG_PBPR_SYNC_OFF_MASK (0x7FF << CFG_PBPR_SYNC_OFF_SHIFT)
+#define CFG_PBPR_SYNC_OFF_VAL 0x117 /* Voltage dependent. stiH416 */
+
+/* Default scaling values */
+#define SCALE_CTRL_Y_DFLT 0x00C50256
+#define SCALE_CTRL_CB_DFLT 0x00DB0249
+#define SCALE_CTRL_CR_DFLT 0x00DB0249
+
+/* Video DACs control */
+#define VIDEO_DACS_CONTROL_MASK 0x0FFF
+#define VIDEO_DACS_CONTROL_SYSCFG2535 0x085C /* for stih416 */
+#define DAC_CFG_HD_OFF_SHIFT 5
+#define DAC_CFG_HD_OFF_MASK (0x7 << DAC_CFG_HD_OFF_SHIFT)
+#define VIDEO_DACS_CONTROL_SYSCFG5072 0x0120 /* for stih407 */
+#define DAC_CFG_HD_HZUVW_OFF_MASK BIT(1)
+
+
+/* Upsampler values for the alternative 2X Filter */
+#define SAMPLER_COEF_NB 8
+#define HDA_ANA_SRC_Y_CFG_ALT_2X 0x01130000
+static u32 coef_y_alt_2x[] = {
+ 0x00FE83FB, 0x1F900401, 0x00000000, 0x00000000,
+ 0x00F408F9, 0x055F7C25, 0x00000000, 0x00000000
+};
+
+#define HDA_ANA_SRC_C_CFG_ALT_2X 0x01750004
+static u32 coef_c_alt_2x[] = {
+ 0x001305F7, 0x05274BD0, 0x00000000, 0x00000000,
+ 0x0004907C, 0x09C80B9D, 0x00000000, 0x00000000
+};
+
+/* Upsampler values for the 4X Filter */
+#define HDA_ANA_SRC_Y_CFG_4X 0x01ED0005
+#define HDA_ANA_SRC_C_CFG_4X 0x01ED0004
+static u32 coef_yc_4x[] = {
+ 0x00FC827F, 0x008FE20B, 0x00F684FC, 0x050F7C24,
+ 0x00F4857C, 0x0A1F402E, 0x00FA027F, 0x0E076E1D
+};
+
+/* AWG instructions for some video modes */
+#define AWG_MAX_INST 64
+
+/* 720p@50 */
+static u32 AWGi_720p_50[] = {
+ 0x00000971, 0x00000C26, 0x0000013B, 0x00000CDA,
+ 0x00000104, 0x00000E7E, 0x00000E7F, 0x0000013B,
+ 0x00000D8E, 0x00000104, 0x00001804, 0x00000971,
+ 0x00000C26, 0x0000003B, 0x00000FB4, 0x00000FB5,
+ 0x00000104, 0x00001AE8
+};
+
+#define NN_720p_50 ARRAY_SIZE(AWGi_720p_50)
+
+/* 720p@60 */
+static u32 AWGi_720p_60[] = {
+ 0x00000971, 0x00000C26, 0x0000013B, 0x00000CDA,
+ 0x00000104, 0x00000E7E, 0x00000E7F, 0x0000013B,
+ 0x00000C44, 0x00000104, 0x00001804, 0x00000971,
+ 0x00000C26, 0x0000003B, 0x00000F0F, 0x00000F10,
+ 0x00000104, 0x00001AE8
+};
+
+#define NN_720p_60 ARRAY_SIZE(AWGi_720p_60)
+
+/* 1080p@30 */
+static u32 AWGi_1080p_30[] = {
+ 0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
+ 0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
+ 0x00000C2A, 0x00000104, 0x00001804, 0x00000971,
+ 0x00000C2A, 0x0000003B, 0x00000EBE, 0x00000EBF,
+ 0x00000EBF, 0x00000104, 0x00001A2F, 0x00001C4B,
+ 0x00001C52
+};
+
+#define NN_1080p_30 ARRAY_SIZE(AWGi_1080p_30)
+
+/* 1080p@25 */
+static u32 AWGi_1080p_25[] = {
+ 0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
+ 0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
+ 0x00000DE2, 0x00000104, 0x00001804, 0x00000971,
+ 0x00000C2A, 0x0000003B, 0x00000F51, 0x00000F51,
+ 0x00000F52, 0x00000104, 0x00001A2F, 0x00001C4B,
+ 0x00001C52
+};
+
+#define NN_1080p_25 ARRAY_SIZE(AWGi_1080p_25)
+
+/* 1080p@24 */
+static u32 AWGi_1080p_24[] = {
+ 0x00000971, 0x00000C2A, 0x0000013B, 0x00000C56,
+ 0x00000104, 0x00000FDC, 0x00000FDD, 0x0000013B,
+ 0x00000E50, 0x00000104, 0x00001804, 0x00000971,
+ 0x00000C2A, 0x0000003B, 0x00000F76, 0x00000F76,
+ 0x00000F76, 0x00000104, 0x00001A2F, 0x00001C4B,
+ 0x00001C52
+};
+
+#define NN_1080p_24 ARRAY_SIZE(AWGi_1080p_24)
+
+/* 720x480p@60 */
+static u32 AWGi_720x480p_60[] = {
+ 0x00000904, 0x00000F18, 0x0000013B, 0x00001805,
+ 0x00000904, 0x00000C3D, 0x0000003B, 0x00001A06
+};
+
+#define NN_720x480p_60 ARRAY_SIZE(AWGi_720x480p_60)
+
+/* Video mode category */
+enum sti_hda_vid_cat {
+ VID_SD,
+ VID_ED,
+ VID_HD_74M,
+ VID_HD_148M
+};
+
+struct sti_hda_video_config {
+ struct drm_display_mode mode;
+ u32 *awg_instr;
+ int nb_instr;
+ enum sti_hda_vid_cat vid_cat;
+};
+
+/* HD analog supported modes
+ * Interlaced modes may be added when supported by the whole display chain
+ */
+static const struct sti_hda_video_config hda_supported_modes[] = {
+ /* 1080p30 74.250Mhz */
+ {{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)},
+ AWGi_1080p_30, NN_1080p_30, VID_HD_74M},
+ /* 1080p30 74.176Mhz */
+ {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74176, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
+ AWGi_1080p_30, NN_1080p_30, VID_HD_74M},
+ /* 1080p24 74.250Mhz */
+ {{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)},
+ AWGi_1080p_24, NN_1080p_24, VID_HD_74M},
+ /* 1080p24 74.176Mhz */
+ {{DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74176, 1920, 2558,
+ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
+ AWGi_1080p_24, NN_1080p_24, VID_HD_74M},
+ /* 1080p25 74.250Mhz */
+ {{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)},
+ AWGi_1080p_25, NN_1080p_25, VID_HD_74M},
+ /* 720p60 74.250Mhz */
+ {{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)},
+ AWGi_720p_60, NN_720p_60, VID_HD_74M},
+ /* 720p60 74.176Mhz */
+ {{DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74176, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)},
+ AWGi_720p_60, NN_720p_60, VID_HD_74M},
+ /* 720p50 74.250Mhz */
+ {{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)},
+ AWGi_720p_50, NN_720p_50, VID_HD_74M},
+ /* 720x480p60 27.027Mhz */
+ {{DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27027, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
+ AWGi_720x480p_60, NN_720x480p_60, VID_ED},
+ /* 720x480p60 27.000Mhz */
+ {{DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
+ 798, 858, 0, 480, 489, 495, 525, 0,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)},
+ AWGi_720x480p_60, NN_720x480p_60, VID_ED}
+};
+
+/**
+ * STI hd analog structure
+ *
+ * @dev: driver device
+ * @drm_dev: pointer to drm device
+ * @mode: current display mode selected
+ * @regs: HD analog register
+ * @video_dacs_ctrl: video DACS control register
+ * @enabled: true if HD analog is enabled else false
+ */
+struct sti_hda {
+ struct device dev;
+ struct drm_device *drm_dev;
+ struct drm_display_mode mode;
+ void __iomem *regs;
+ void __iomem *video_dacs_ctrl;
+ struct clk *clk_pix;
+ struct clk *clk_hddac;
+ bool enabled;
+};
+
+struct sti_hda_connector {
+ struct drm_connector drm_connector;
+ struct drm_encoder *encoder;
+ struct sti_hda *hda;
+};
+
+#define to_sti_hda_connector(x) \
+ container_of(x, struct sti_hda_connector, drm_connector)
+
+static u32 hda_read(struct sti_hda *hda, int offset)
+{
+ return readl(hda->regs + offset);
+}
+
+static void hda_write(struct sti_hda *hda, u32 val, int offset)
+{
+ writel(val, hda->regs + offset);
+}
+
+/**
+ * Search for a video mode in the supported modes table
+ *
+ * @mode: mode being searched
+ * @idx: index of the found mode
+ *
+ * Return true if mode is found
+ */
+static bool hda_get_mode_idx(struct drm_display_mode mode, int *idx)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(hda_supported_modes); i++)
+ if (drm_mode_equal(&hda_supported_modes[i].mode, &mode)) {
+ *idx = i;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Enable the HD DACS
+ *
+ * @hda: pointer to HD analog structure
+ * @enable: true if HD DACS need to be enabled, else false
+ */
+static void hda_enable_hd_dacs(struct sti_hda *hda, bool enable)
+{
+ u32 mask;
+
+ if (hda->video_dacs_ctrl) {
+ u32 val;
+
+ switch ((u32)hda->video_dacs_ctrl & VIDEO_DACS_CONTROL_MASK) {
+ case VIDEO_DACS_CONTROL_SYSCFG2535:
+ mask = DAC_CFG_HD_OFF_MASK;
+ break;
+ case VIDEO_DACS_CONTROL_SYSCFG5072:
+ mask = DAC_CFG_HD_HZUVW_OFF_MASK;
+ break;
+ default:
+ DRM_INFO("Video DACS control register not supported!");
+ return;
+ }
+
+ val = readl(hda->video_dacs_ctrl);
+ if (enable)
+ val &= ~mask;
+ else
+ val |= mask;
+
+ writel(val, hda->video_dacs_ctrl);
+ }
+}
+
+/**
+ * Configure AWG, writing instructions
+ *
+ * @hda: pointer to HD analog structure
+ * @awg_instr: pointer to AWG instructions table
+ * @nb: nb of AWG instructions
+ */
+static void sti_hda_configure_awg(struct sti_hda *hda, u32 *awg_instr, int nb)
+{
+ unsigned int i;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ for (i = 0; i < nb; i++)
+ hda_write(hda, awg_instr[i], HDA_SYNC_AWGI + i * 4);
+ for (i = nb; i < AWG_MAX_INST; i++)
+ hda_write(hda, 0, HDA_SYNC_AWGI + i * 4);
+}
+
+static void sti_hda_disable(struct drm_bridge *bridge)
+{
+ struct sti_hda *hda = bridge->driver_private;
+ u32 val;
+
+ if (!hda->enabled)
+ return;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Disable HD DAC and AWG */
+ val = hda_read(hda, HDA_ANA_CFG);
+ val &= ~CFG_AWG_ASYNC_EN;
+ hda_write(hda, val, HDA_ANA_CFG);
+ hda_write(hda, 0, HDA_ANA_ANC_CTRL);
+
+ hda_enable_hd_dacs(hda, false);
+
+ /* Disable/unprepare hda clock */
+ clk_disable_unprepare(hda->clk_hddac);
+ clk_disable_unprepare(hda->clk_pix);
+
+ hda->enabled = false;
+}
+
+static void sti_hda_pre_enable(struct drm_bridge *bridge)
+{
+ struct sti_hda *hda = bridge->driver_private;
+ u32 val, i, mode_idx;
+ u32 src_filter_y, src_filter_c;
+ u32 *coef_y, *coef_c;
+ u32 filter_mode;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (hda->enabled)
+ return;
+
+ /* Prepare/enable clocks */
+ if (clk_prepare_enable(hda->clk_pix))
+ DRM_ERROR("Failed to prepare/enable hda_pix clk\n");
+ if (clk_prepare_enable(hda->clk_hddac))
+ DRM_ERROR("Failed to prepare/enable hda_hddac clk\n");
+
+ if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
+ DRM_ERROR("Undefined mode\n");
+ return;
+ }
+
+ switch (hda_supported_modes[mode_idx].vid_cat) {
+ case VID_HD_148M:
+ DRM_ERROR("Beyond HD analog capabilities\n");
+ return;
+ case VID_HD_74M:
+ /* HD use alternate 2x filter */
+ filter_mode = CFG_AWG_FLTR_MODE_HD;
+ src_filter_y = HDA_ANA_SRC_Y_CFG_ALT_2X;
+ src_filter_c = HDA_ANA_SRC_C_CFG_ALT_2X;
+ coef_y = coef_y_alt_2x;
+ coef_c = coef_c_alt_2x;
+ break;
+ case VID_ED:
+ /* ED uses 4x filter */
+ filter_mode = CFG_AWG_FLTR_MODE_ED;
+ src_filter_y = HDA_ANA_SRC_Y_CFG_4X;
+ src_filter_c = HDA_ANA_SRC_C_CFG_4X;
+ coef_y = coef_yc_4x;
+ coef_c = coef_yc_4x;
+ break;
+ case VID_SD:
+ DRM_ERROR("Not supported\n");
+ return;
+ default:
+ DRM_ERROR("Undefined resolution\n");
+ return;
+ }
+ DRM_DEBUG_DRIVER("Using HDA mode #%d\n", mode_idx);
+
+ /* Enable HD Video DACs */
+ hda_enable_hd_dacs(hda, true);
+
+ /* Configure scaler */
+ hda_write(hda, SCALE_CTRL_Y_DFLT, HDA_ANA_SCALE_CTRL_Y);
+ hda_write(hda, SCALE_CTRL_CB_DFLT, HDA_ANA_SCALE_CTRL_CB);
+ hda_write(hda, SCALE_CTRL_CR_DFLT, HDA_ANA_SCALE_CTRL_CR);
+
+ /* Configure sampler */
+ hda_write(hda , src_filter_y, HDA_ANA_SRC_Y_CFG);
+ hda_write(hda, src_filter_c, HDA_ANA_SRC_C_CFG);
+ for (i = 0; i < SAMPLER_COEF_NB; i++) {
+ hda_write(hda, coef_y[i], HDA_COEFF_Y_PH1_TAP123 + i * 4);
+ hda_write(hda, coef_c[i], HDA_COEFF_C_PH1_TAP123 + i * 4);
+ }
+
+ /* Configure main HDFormatter */
+ val = 0;
+ val |= (hda->mode.flags & DRM_MODE_FLAG_INTERLACE) ?
+ 0 : CFG_AWG_ASYNC_VSYNC_MTD;
+ val |= (CFG_PBPR_SYNC_OFF_VAL << CFG_PBPR_SYNC_OFF_SHIFT);
+ val |= filter_mode;
+ hda_write(hda, val, HDA_ANA_CFG);
+
+ /* Configure AWG */
+ sti_hda_configure_awg(hda, hda_supported_modes[mode_idx].awg_instr,
+ hda_supported_modes[mode_idx].nb_instr);
+
+ /* Enable AWG */
+ val = hda_read(hda, HDA_ANA_CFG);
+ val |= CFG_AWG_ASYNC_EN;
+ hda_write(hda, val, HDA_ANA_CFG);
+
+ hda->enabled = true;
+}
+
+static void sti_hda_set_mode(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct sti_hda *hda = bridge->driver_private;
+ u32 mode_idx;
+ int hddac_rate;
+ int ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
+
+ if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
+ DRM_ERROR("Undefined mode\n");
+ return;
+ }
+
+ switch (hda_supported_modes[mode_idx].vid_cat) {
+ case VID_HD_74M:
+ /* HD use alternate 2x filter */
+ hddac_rate = mode->clock * 1000 * 2;
+ break;
+ case VID_ED:
+ /* ED uses 4x filter */
+ hddac_rate = mode->clock * 1000 * 4;
+ break;
+ default:
+ DRM_ERROR("Undefined mode\n");
+ return;
+ }
+
+ /* HD DAC = 148.5Mhz or 108 Mhz */
+ ret = clk_set_rate(hda->clk_hddac, hddac_rate);
+ if (ret < 0)
+ DRM_ERROR("Cannot set rate (%dHz) for hda_hddac clk\n",
+ hddac_rate);
+
+ /* HDformatter clock = compositor clock */
+ ret = clk_set_rate(hda->clk_pix, mode->clock * 1000);
+ if (ret < 0)
+ DRM_ERROR("Cannot set rate (%dHz) for hda_pix clk\n",
+ mode->clock * 1000);
+}
+
+static void sti_hda_bridge_nope(struct drm_bridge *bridge)
+{
+ /* do nothing */
+}
+
+static void sti_hda_brigde_destroy(struct drm_bridge *bridge)
+{
+ drm_bridge_cleanup(bridge);
+ kfree(bridge);
+}
+
+static const struct drm_bridge_funcs sti_hda_bridge_funcs = {
+ .pre_enable = sti_hda_pre_enable,
+ .enable = sti_hda_bridge_nope,
+ .disable = sti_hda_disable,
+ .post_disable = sti_hda_bridge_nope,
+ .mode_set = sti_hda_set_mode,
+ .destroy = sti_hda_brigde_destroy,
+};
+
+static int sti_hda_connector_get_modes(struct drm_connector *connector)
+{
+ unsigned int i;
+ int count = 0;
+ struct sti_hda_connector *hda_connector
+ = to_sti_hda_connector(connector);
+ struct sti_hda *hda = hda_connector->hda;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ for (i = 0; i < ARRAY_SIZE(hda_supported_modes); i++) {
+ struct drm_display_mode *mode =
+ drm_mode_duplicate(hda->drm_dev,
+ &hda_supported_modes[i].mode);
+ if (!mode)
+ continue;
+ mode->vrefresh = drm_mode_vrefresh(mode);
+
+ /* the first mode is the preferred mode */
+ if (i == 0)
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(connector, mode);
+ count++;
+ }
+
+ drm_mode_sort(&connector->modes);
+
+ return count;
+}
+
+#define CLK_TOLERANCE_HZ 50
+
+static int sti_hda_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+ int target_max = target + CLK_TOLERANCE_HZ;
+ int result;
+ int idx;
+ struct sti_hda_connector *hda_connector
+ = to_sti_hda_connector(connector);
+ struct sti_hda *hda = hda_connector->hda;
+
+ if (!hda_get_mode_idx(*mode, &idx)) {
+ return MODE_BAD;
+ } else {
+ result = clk_round_rate(hda->clk_pix, target);
+
+ DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
+ target, result);
+
+ if ((result < target_min) || (result > target_max)) {
+ DRM_DEBUG_DRIVER("hda pixclk=%d not supported\n",
+ target);
+ return MODE_BAD;
+ }
+ }
+
+ return MODE_OK;
+}
+
+struct drm_encoder *sti_hda_best_encoder(struct drm_connector *connector)
+{
+ struct sti_hda_connector *hda_connector
+ = to_sti_hda_connector(connector);
+
+ /* Best encoder is the one associated during connector creation */
+ return hda_connector->encoder;
+}
+
+static struct drm_connector_helper_funcs sti_hda_connector_helper_funcs = {
+ .get_modes = sti_hda_connector_get_modes,
+ .mode_valid = sti_hda_connector_mode_valid,
+ .best_encoder = sti_hda_best_encoder,
+};
+
+static enum drm_connector_status
+sti_hda_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static void sti_hda_connector_destroy(struct drm_connector *connector)
+{
+ struct sti_hda_connector *hda_connector
+ = to_sti_hda_connector(connector);
+
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+ kfree(hda_connector);
+}
+
+static struct drm_connector_funcs sti_hda_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = sti_hda_connector_detect,
+ .destroy = sti_hda_connector_destroy,
+};
+
+static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev)
+{
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->encoder_type == DRM_MODE_ENCODER_DAC)
+ return encoder;
+ }
+
+ return NULL;
+}
+
+static int sti_hda_bind(struct device *dev, struct device *master, void *data)
+{
+ struct sti_hda *hda = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ struct drm_encoder *encoder;
+ struct sti_hda_connector *connector;
+ struct drm_connector *drm_connector;
+ struct drm_bridge *bridge;
+ int err;
+
+ /* Set the drm device handle */
+ hda->drm_dev = drm_dev;
+
+ encoder = sti_hda_find_encoder(drm_dev);
+ if (!encoder)
+ return -ENOMEM;
+
+ connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
+ if (!connector)
+ return -ENOMEM;
+
+ connector->hda = hda;
+
+ bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge)
+ return -ENOMEM;
+
+ bridge->driver_private = hda;
+ drm_bridge_init(drm_dev, bridge, &sti_hda_bridge_funcs);
+
+ encoder->bridge = bridge;
+ connector->encoder = encoder;
+
+ drm_connector = (struct drm_connector *)connector;
+
+ drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+ drm_connector_init(drm_dev, drm_connector,
+ &sti_hda_connector_funcs, DRM_MODE_CONNECTOR_Component);
+ drm_connector_helper_add(drm_connector,
+ &sti_hda_connector_helper_funcs);
+
+ err = drm_connector_register(drm_connector);
+ if (err)
+ goto err_connector;
+
+ err = drm_mode_connector_attach_encoder(drm_connector, encoder);
+ if (err) {
+ DRM_ERROR("Failed to attach a connector to a encoder\n");
+ goto err_sysfs;
+ }
+
+ return 0;
+
+err_sysfs:
+ drm_connector_unregister(drm_connector);
+err_connector:
+ drm_bridge_cleanup(bridge);
+ drm_connector_cleanup(drm_connector);
+ return -EINVAL;
+}
+
+static void sti_hda_unbind(struct device *dev,
+ struct device *master, void *data)
+{
+ /* do nothing */
+}
+
+static const struct component_ops sti_hda_ops = {
+ .bind = sti_hda_bind,
+ .unbind = sti_hda_unbind,
+};
+
+static int sti_hda_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sti_hda *hda;
+ struct resource *res;
+
+ DRM_INFO("%s\n", __func__);
+
+ hda = devm_kzalloc(dev, sizeof(*hda), GFP_KERNEL);
+ if (!hda)
+ return -ENOMEM;
+
+ hda->dev = pdev->dev;
+
+ /* Get resources */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hda-reg");
+ if (!res) {
+ DRM_ERROR("Invalid hda resource\n");
+ return -ENOMEM;
+ }
+ hda->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+ if (IS_ERR(hda->regs))
+ return PTR_ERR(hda->regs);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "video-dacs-ctrl");
+ if (res) {
+ hda->video_dacs_ctrl = devm_ioremap_nocache(dev, res->start,
+ resource_size(res));
+ if (IS_ERR(hda->video_dacs_ctrl))
+ return PTR_ERR(hda->video_dacs_ctrl);
+ } else {
+ /* If no existing video-dacs-ctrl resource continue the probe */
+ DRM_DEBUG_DRIVER("No video-dacs-ctrl resource\n");
+ hda->video_dacs_ctrl = NULL;
+ }
+
+ /* Get clock resources */
+ hda->clk_pix = devm_clk_get(dev, "pix");
+ if (IS_ERR(hda->clk_pix)) {
+ DRM_ERROR("Cannot get hda_pix clock\n");
+ return PTR_ERR(hda->clk_pix);
+ }
+
+ hda->clk_hddac = devm_clk_get(dev, "hddac");
+ if (IS_ERR(hda->clk_hddac)) {
+ DRM_ERROR("Cannot get hda_hddac clock\n");
+ return PTR_ERR(hda->clk_hddac);
+ }
+
+ platform_set_drvdata(pdev, hda);
+
+ return component_add(&pdev->dev, &sti_hda_ops);
+}
+
+static int sti_hda_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &sti_hda_ops);
+ return 0;
+}
+
+static struct of_device_id hda_of_match[] = {
+ { .compatible = "st,stih416-hda", },
+ { .compatible = "st,stih407-hda", },
+ { /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, hda_of_match);
+
+struct platform_driver sti_hda_driver = {
+ .driver = {
+ .name = "sti-hda",
+ .owner = THIS_MODULE,
+ .of_match_table = hda_of_match,
+ },
+ .probe = sti_hda_probe,
+ .remove = sti_hda_remove,
+};
+
+module_platform_driver(sti_hda_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
new file mode 100644
index 000000000000..284e541d970d
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/hdmi.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+
+#include "sti_hdmi.h"
+#include "sti_hdmi_tx3g4c28phy.h"
+#include "sti_hdmi_tx3g0c55phy.h"
+#include "sti_vtg.h"
+
+#define HDMI_CFG 0x0000
+#define HDMI_INT_EN 0x0004
+#define HDMI_INT_STA 0x0008
+#define HDMI_INT_CLR 0x000C
+#define HDMI_STA 0x0010
+#define HDMI_ACTIVE_VID_XMIN 0x0100
+#define HDMI_ACTIVE_VID_XMAX 0x0104
+#define HDMI_ACTIVE_VID_YMIN 0x0108
+#define HDMI_ACTIVE_VID_YMAX 0x010C
+#define HDMI_DFLT_CHL0_DAT 0x0110
+#define HDMI_DFLT_CHL1_DAT 0x0114
+#define HDMI_DFLT_CHL2_DAT 0x0118
+#define HDMI_SW_DI_1_HEAD_WORD 0x0210
+#define HDMI_SW_DI_1_PKT_WORD0 0x0214
+#define HDMI_SW_DI_1_PKT_WORD1 0x0218
+#define HDMI_SW_DI_1_PKT_WORD2 0x021C
+#define HDMI_SW_DI_1_PKT_WORD3 0x0220
+#define HDMI_SW_DI_1_PKT_WORD4 0x0224
+#define HDMI_SW_DI_1_PKT_WORD5 0x0228
+#define HDMI_SW_DI_1_PKT_WORD6 0x022C
+#define HDMI_SW_DI_CFG 0x0230
+
+#define HDMI_IFRAME_SLOT_AVI 1
+
+#define XCAT(prefix, x, suffix) prefix ## x ## suffix
+#define HDMI_SW_DI_N_HEAD_WORD(x) XCAT(HDMI_SW_DI_, x, _HEAD_WORD)
+#define HDMI_SW_DI_N_PKT_WORD0(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD0)
+#define HDMI_SW_DI_N_PKT_WORD1(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD1)
+#define HDMI_SW_DI_N_PKT_WORD2(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD2)
+#define HDMI_SW_DI_N_PKT_WORD3(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD3)
+#define HDMI_SW_DI_N_PKT_WORD4(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD4)
+#define HDMI_SW_DI_N_PKT_WORD5(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD5)
+#define HDMI_SW_DI_N_PKT_WORD6(x) XCAT(HDMI_SW_DI_, x, _PKT_WORD6)
+
+#define HDMI_IFRAME_DISABLED 0x0
+#define HDMI_IFRAME_SINGLE_SHOT 0x1
+#define HDMI_IFRAME_FIELD 0x2
+#define HDMI_IFRAME_FRAME 0x3
+#define HDMI_IFRAME_MASK 0x3
+#define HDMI_IFRAME_CFG_DI_N(x, n) ((x) << ((n-1)*4)) /* n from 1 to 6 */
+
+#define HDMI_CFG_DEVICE_EN BIT(0)
+#define HDMI_CFG_HDMI_NOT_DVI BIT(1)
+#define HDMI_CFG_HDCP_EN BIT(2)
+#define HDMI_CFG_ESS_NOT_OESS BIT(3)
+#define HDMI_CFG_H_SYNC_POL_NEG BIT(4)
+#define HDMI_CFG_SINK_TERM_DET_EN BIT(5)
+#define HDMI_CFG_V_SYNC_POL_NEG BIT(6)
+#define HDMI_CFG_422_EN BIT(8)
+#define HDMI_CFG_FIFO_OVERRUN_CLR BIT(12)
+#define HDMI_CFG_FIFO_UNDERRUN_CLR BIT(13)
+#define HDMI_CFG_SW_RST_EN BIT(31)
+
+#define HDMI_INT_GLOBAL BIT(0)
+#define HDMI_INT_SW_RST BIT(1)
+#define HDMI_INT_PIX_CAP BIT(3)
+#define HDMI_INT_HOT_PLUG BIT(4)
+#define HDMI_INT_DLL_LCK BIT(5)
+#define HDMI_INT_NEW_FRAME BIT(6)
+#define HDMI_INT_GENCTRL_PKT BIT(7)
+#define HDMI_INT_SINK_TERM_PRESENT BIT(11)
+
+#define HDMI_DEFAULT_INT (HDMI_INT_SINK_TERM_PRESENT \
+ | HDMI_INT_DLL_LCK \
+ | HDMI_INT_HOT_PLUG \
+ | HDMI_INT_GLOBAL)
+
+#define HDMI_WORKING_INT (HDMI_INT_SINK_TERM_PRESENT \
+ | HDMI_INT_GENCTRL_PKT \
+ | HDMI_INT_NEW_FRAME \
+ | HDMI_INT_DLL_LCK \
+ | HDMI_INT_HOT_PLUG \
+ | HDMI_INT_PIX_CAP \
+ | HDMI_INT_SW_RST \
+ | HDMI_INT_GLOBAL)
+
+#define HDMI_STA_SW_RST BIT(1)
+
+struct sti_hdmi_connector {
+ struct drm_connector drm_connector;
+ struct drm_encoder *encoder;
+ struct sti_hdmi *hdmi;
+};
+
+#define to_sti_hdmi_connector(x) \
+ container_of(x, struct sti_hdmi_connector, drm_connector)
+
+u32 hdmi_read(struct sti_hdmi *hdmi, int offset)
+{
+ return readl(hdmi->regs + offset);
+}
+
+void hdmi_write(struct sti_hdmi *hdmi, u32 val, int offset)
+{
+ writel(val, hdmi->regs + offset);
+}
+
+/**
+ * HDMI interrupt handler threaded
+ *
+ * @irq: irq number
+ * @arg: connector structure
+ */
+static irqreturn_t hdmi_irq_thread(int irq, void *arg)
+{
+ struct sti_hdmi *hdmi = arg;
+
+ /* Hot plug/unplug IRQ */
+ if (hdmi->irq_status & HDMI_INT_HOT_PLUG) {
+ /* read gpio to get the status */
+ hdmi->hpd = gpio_get_value(hdmi->hpd_gpio);
+ if (hdmi->drm_dev)
+ drm_helper_hpd_irq_event(hdmi->drm_dev);
+ }
+
+ /* Sw reset and PLL lock are exclusive so we can use the same
+ * event to signal them
+ */
+ if (hdmi->irq_status & (HDMI_INT_SW_RST | HDMI_INT_DLL_LCK)) {
+ hdmi->event_received = true;
+ wake_up_interruptible(&hdmi->wait_event);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * HDMI interrupt handler
+ *
+ * @irq: irq number
+ * @arg: connector structure
+ */
+static irqreturn_t hdmi_irq(int irq, void *arg)
+{
+ struct sti_hdmi *hdmi = arg;
+
+ /* read interrupt status */
+ hdmi->irq_status = hdmi_read(hdmi, HDMI_INT_STA);
+
+ /* clear interrupt status */
+ hdmi_write(hdmi, hdmi->irq_status, HDMI_INT_CLR);
+
+ /* force sync bus write */
+ hdmi_read(hdmi, HDMI_INT_STA);
+
+ return IRQ_WAKE_THREAD;
+}
+
+/**
+ * Set hdmi active area depending on the drm display mode selected
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ */
+static void hdmi_active_area(struct sti_hdmi *hdmi)
+{
+ u32 xmin, xmax;
+ u32 ymin, ymax;
+
+ xmin = sti_vtg_get_pixel_number(hdmi->mode, 0);
+ xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay - 1);
+ ymin = sti_vtg_get_line_number(hdmi->mode, 0);
+ ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1);
+
+ hdmi_write(hdmi, xmin, HDMI_ACTIVE_VID_XMIN);
+ hdmi_write(hdmi, xmax, HDMI_ACTIVE_VID_XMAX);
+ hdmi_write(hdmi, ymin, HDMI_ACTIVE_VID_YMIN);
+ hdmi_write(hdmi, ymax, HDMI_ACTIVE_VID_YMAX);
+}
+
+/**
+ * Overall hdmi configuration
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ */
+static void hdmi_config(struct sti_hdmi *hdmi)
+{
+ u32 conf;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Clear overrun and underrun fifo */
+ conf = HDMI_CFG_FIFO_OVERRUN_CLR | HDMI_CFG_FIFO_UNDERRUN_CLR;
+
+ /* Enable HDMI mode not DVI */
+ conf |= HDMI_CFG_HDMI_NOT_DVI | HDMI_CFG_ESS_NOT_OESS;
+
+ /* Enable sink term detection */
+ conf |= HDMI_CFG_SINK_TERM_DET_EN;
+
+ /* Set Hsync polarity */
+ if (hdmi->mode.flags & DRM_MODE_FLAG_NHSYNC) {
+ DRM_DEBUG_DRIVER("H Sync Negative\n");
+ conf |= HDMI_CFG_H_SYNC_POL_NEG;
+ }
+
+ /* Set Vsync polarity */
+ if (hdmi->mode.flags & DRM_MODE_FLAG_NVSYNC) {
+ DRM_DEBUG_DRIVER("V Sync Negative\n");
+ conf |= HDMI_CFG_V_SYNC_POL_NEG;
+ }
+
+ /* Enable HDMI */
+ conf |= HDMI_CFG_DEVICE_EN;
+
+ hdmi_write(hdmi, conf, HDMI_CFG);
+}
+
+/**
+ * Prepare and configure the AVI infoframe
+ *
+ * AVI infoframe are transmitted at least once per two video field and
+ * contains information about HDMI transmission mode such as color space,
+ * colorimetry, ...
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * Return negative value if error occurs
+ */
+static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
+{
+ struct drm_display_mode *mode = &hdmi->mode;
+ struct hdmi_avi_infoframe infoframe;
+ u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
+ u8 *frame = buffer + HDMI_INFOFRAME_HEADER_SIZE;
+ u32 val;
+ int ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode);
+ if (ret < 0) {
+ DRM_ERROR("failed to setup AVI infoframe: %d\n", ret);
+ return ret;
+ }
+
+ /* fixed infoframe configuration not linked to the mode */
+ infoframe.colorspace = HDMI_COLORSPACE_RGB;
+ infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+ infoframe.colorimetry = HDMI_COLORIMETRY_NONE;
+
+ ret = hdmi_avi_infoframe_pack(&infoframe, buffer, sizeof(buffer));
+ if (ret < 0) {
+ DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
+ return ret;
+ }
+
+ /* Disable transmission slot for AVI infoframe */
+ val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
+ val &= ~HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, HDMI_IFRAME_SLOT_AVI);
+ hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+
+ /* Infoframe header */
+ val = buffer[0x0];
+ val |= buffer[0x1] << 8;
+ val |= buffer[0x2] << 16;
+ hdmi_write(hdmi, val, HDMI_SW_DI_N_HEAD_WORD(HDMI_IFRAME_SLOT_AVI));
+
+ /* Infoframe packet bytes */
+ val = frame[0x0];
+ val |= frame[0x1] << 8;
+ val |= frame[0x2] << 16;
+ val |= frame[0x3] << 24;
+ hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD0(HDMI_IFRAME_SLOT_AVI));
+
+ val = frame[0x4];
+ val |= frame[0x5] << 8;
+ val |= frame[0x6] << 16;
+ val |= frame[0x7] << 24;
+ hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD1(HDMI_IFRAME_SLOT_AVI));
+
+ val = frame[0x8];
+ val |= frame[0x9] << 8;
+ val |= frame[0xA] << 16;
+ val |= frame[0xB] << 24;
+ hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD2(HDMI_IFRAME_SLOT_AVI));
+
+ val = frame[0xC];
+ val |= frame[0xD] << 8;
+ hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD3(HDMI_IFRAME_SLOT_AVI));
+
+ /* Enable transmission slot for AVI infoframe
+ * According to the hdmi specification, AVI infoframe should be
+ * transmitted at least once per two video fields
+ */
+ val = hdmi_read(hdmi, HDMI_SW_DI_CFG);
+ val |= HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_FIELD, HDMI_IFRAME_SLOT_AVI);
+ hdmi_write(hdmi, val, HDMI_SW_DI_CFG);
+
+ return 0;
+}
+
+/**
+ * Software reset of the hdmi subsystem
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ */
+#define HDMI_TIMEOUT_SWRESET 100 /*milliseconds */
+static void hdmi_swreset(struct sti_hdmi *hdmi)
+{
+ u32 val;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Enable hdmi_audio clock only during hdmi reset */
+ if (clk_prepare_enable(hdmi->clk_audio))
+ DRM_INFO("Failed to prepare/enable hdmi_audio clk\n");
+
+ /* Sw reset */
+ hdmi->event_received = false;
+
+ val = hdmi_read(hdmi, HDMI_CFG);
+ val |= HDMI_CFG_SW_RST_EN;
+ hdmi_write(hdmi, val, HDMI_CFG);
+
+ /* Wait reset completed */
+ wait_event_interruptible_timeout(hdmi->wait_event,
+ hdmi->event_received == true,
+ msecs_to_jiffies
+ (HDMI_TIMEOUT_SWRESET));
+
+ /*
+ * HDMI_STA_SW_RST bit is set to '1' when SW_RST bit in HDMI_CFG is
+ * set to '1' and clk_audio is running.
+ */
+ if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_SW_RST) == 0)
+ DRM_DEBUG_DRIVER("Warning: HDMI sw reset timeout occurs\n");
+
+ val = hdmi_read(hdmi, HDMI_CFG);
+ val &= ~HDMI_CFG_SW_RST_EN;
+ hdmi_write(hdmi, val, HDMI_CFG);
+
+ /* Disable hdmi_audio clock. Not used anymore for drm purpose */
+ clk_disable_unprepare(hdmi->clk_audio);
+}
+
+static void sti_hdmi_disable(struct drm_bridge *bridge)
+{
+ struct sti_hdmi *hdmi = bridge->driver_private;
+
+ u32 val = hdmi_read(hdmi, HDMI_CFG);
+
+ if (!hdmi->enabled)
+ return;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Disable HDMI */
+ val &= ~HDMI_CFG_DEVICE_EN;
+ hdmi_write(hdmi, val, HDMI_CFG);
+
+ hdmi_write(hdmi, 0xffffffff, HDMI_INT_CLR);
+
+ /* Stop the phy */
+ hdmi->phy_ops->stop(hdmi);
+
+ /* Set the default channel data to be a dark red */
+ hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL0_DAT);
+ hdmi_write(hdmi, 0x0000, HDMI_DFLT_CHL1_DAT);
+ hdmi_write(hdmi, 0x0060, HDMI_DFLT_CHL2_DAT);
+
+ /* Disable/unprepare hdmi clock */
+ clk_disable_unprepare(hdmi->clk_phy);
+ clk_disable_unprepare(hdmi->clk_tmds);
+ clk_disable_unprepare(hdmi->clk_pix);
+
+ hdmi->enabled = false;
+}
+
+static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
+{
+ struct sti_hdmi *hdmi = bridge->driver_private;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (hdmi->enabled)
+ return;
+
+ /* Prepare/enable clocks */
+ if (clk_prepare_enable(hdmi->clk_pix))
+ DRM_ERROR("Failed to prepare/enable hdmi_pix clk\n");
+ if (clk_prepare_enable(hdmi->clk_tmds))
+ DRM_ERROR("Failed to prepare/enable hdmi_tmds clk\n");
+ if (clk_prepare_enable(hdmi->clk_phy))
+ DRM_ERROR("Failed to prepare/enable hdmi_rejec_pll clk\n");
+
+ hdmi->enabled = true;
+
+ /* Program hdmi serializer and start phy */
+ if (!hdmi->phy_ops->start(hdmi)) {
+ DRM_ERROR("Unable to start hdmi phy\n");
+ return;
+ }
+
+ /* Program hdmi active area */
+ hdmi_active_area(hdmi);
+
+ /* Enable working interrupts */
+ hdmi_write(hdmi, HDMI_WORKING_INT, HDMI_INT_EN);
+
+ /* Program hdmi config */
+ hdmi_config(hdmi);
+
+ /* Program AVI infoframe */
+ if (hdmi_avi_infoframe_config(hdmi))
+ DRM_ERROR("Unable to configure AVI infoframe\n");
+
+ /* Sw reset */
+ hdmi_swreset(hdmi);
+}
+
+static void sti_hdmi_set_mode(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct sti_hdmi *hdmi = bridge->driver_private;
+ int ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Copy the drm display mode in the connector local structure */
+ memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
+
+ /* Update clock framerate according to the selected mode */
+ ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
+ if (ret < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for hdmi_pix clk\n",
+ mode->clock * 1000);
+ return;
+ }
+ ret = clk_set_rate(hdmi->clk_phy, mode->clock * 1000);
+ if (ret < 0) {
+ DRM_ERROR("Cannot set rate (%dHz) for hdmi_rejection_pll clk\n",
+ mode->clock * 1000);
+ return;
+ }
+}
+
+static void sti_hdmi_bridge_nope(struct drm_bridge *bridge)
+{
+ /* do nothing */
+}
+
+static void sti_hdmi_brigde_destroy(struct drm_bridge *bridge)
+{
+ drm_bridge_cleanup(bridge);
+ kfree(bridge);
+}
+
+static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
+ .pre_enable = sti_hdmi_pre_enable,
+ .enable = sti_hdmi_bridge_nope,
+ .disable = sti_hdmi_disable,
+ .post_disable = sti_hdmi_bridge_nope,
+ .mode_set = sti_hdmi_set_mode,
+ .destroy = sti_hdmi_brigde_destroy,
+};
+
+static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+ struct i2c_adapter *i2c_adap;
+ struct edid *edid;
+ int count;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ i2c_adap = i2c_get_adapter(1);
+ if (!i2c_adap)
+ goto fail;
+
+ edid = drm_get_edid(connector, i2c_adap);
+ if (!edid)
+ goto fail;
+
+ count = drm_add_edid_modes(connector, edid);
+ drm_mode_connector_update_edid_property(connector, edid);
+
+ kfree(edid);
+ return count;
+
+fail:
+ DRM_ERROR("Can not read HDMI EDID\n");
+ return 0;
+}
+
+#define CLK_TOLERANCE_HZ 50
+
+static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ int target = mode->clock * 1000;
+ int target_min = target - CLK_TOLERANCE_HZ;
+ int target_max = target + CLK_TOLERANCE_HZ;
+ int result;
+ struct sti_hdmi_connector *hdmi_connector
+ = to_sti_hdmi_connector(connector);
+ struct sti_hdmi *hdmi = hdmi_connector->hdmi;
+
+
+ result = clk_round_rate(hdmi->clk_pix, target);
+
+ DRM_DEBUG_DRIVER("target rate = %d => available rate = %d\n",
+ target, result);
+
+ if ((result < target_min) || (result > target_max)) {
+ DRM_DEBUG_DRIVER("hdmi pixclk=%d not supported\n", target);
+ return MODE_BAD;
+ }
+
+ return MODE_OK;
+}
+
+struct drm_encoder *sti_hdmi_best_encoder(struct drm_connector *connector)
+{
+ struct sti_hdmi_connector *hdmi_connector
+ = to_sti_hdmi_connector(connector);
+
+ /* Best encoder is the one associated during connector creation */
+ return hdmi_connector->encoder;
+}
+
+static struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
+ .get_modes = sti_hdmi_connector_get_modes,
+ .mode_valid = sti_hdmi_connector_mode_valid,
+ .best_encoder = sti_hdmi_best_encoder,
+};
+
+/* get detection status of display device */
+static enum drm_connector_status
+sti_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct sti_hdmi_connector *hdmi_connector
+ = to_sti_hdmi_connector(connector);
+ struct sti_hdmi *hdmi = hdmi_connector->hdmi;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (hdmi->hpd) {
+ DRM_DEBUG_DRIVER("hdmi cable connected\n");
+ return connector_status_connected;
+ }
+
+ DRM_DEBUG_DRIVER("hdmi cable disconnected\n");
+ return connector_status_disconnected;
+}
+
+static void sti_hdmi_connector_destroy(struct drm_connector *connector)
+{
+ struct sti_hdmi_connector *hdmi_connector
+ = to_sti_hdmi_connector(connector);
+
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+ kfree(hdmi_connector);
+}
+
+static struct drm_connector_funcs sti_hdmi_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = sti_hdmi_connector_detect,
+ .destroy = sti_hdmi_connector_destroy,
+};
+
+static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)
+{
+ struct drm_encoder *encoder;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
+ return encoder;
+ }
+
+ return NULL;
+}
+
+static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
+{
+ struct sti_hdmi *hdmi = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ struct drm_encoder *encoder;
+ struct sti_hdmi_connector *connector;
+ struct drm_connector *drm_connector;
+ struct drm_bridge *bridge;
+ struct i2c_adapter *i2c_adap;
+ int err;
+
+ i2c_adap = i2c_get_adapter(1);
+ if (!i2c_adap)
+ return -EPROBE_DEFER;
+
+ /* Set the drm device handle */
+ hdmi->drm_dev = drm_dev;
+
+ encoder = sti_hdmi_find_encoder(drm_dev);
+ if (!encoder)
+ return -ENOMEM;
+
+ connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
+ if (!connector)
+ return -ENOMEM;
+
+ connector->hdmi = hdmi;
+
+ bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
+ if (!bridge)
+ return -ENOMEM;
+
+ bridge->driver_private = hdmi;
+ drm_bridge_init(drm_dev, bridge, &sti_hdmi_bridge_funcs);
+
+ encoder->bridge = bridge;
+ connector->encoder = encoder;
+
+ drm_connector = (struct drm_connector *)connector;
+
+ drm_connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+ drm_connector_init(drm_dev, drm_connector,
+ &sti_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA);
+ drm_connector_helper_add(drm_connector,
+ &sti_hdmi_connector_helper_funcs);
+
+ err = drm_connector_register(drm_connector);
+ if (err)
+ goto err_connector;
+
+ err = drm_mode_connector_attach_encoder(drm_connector, encoder);
+ if (err) {
+ DRM_ERROR("Failed to attach a connector to a encoder\n");
+ goto err_sysfs;
+ }
+
+ /* Enable default interrupts */
+ hdmi_write(hdmi, HDMI_DEFAULT_INT, HDMI_INT_EN);
+
+ return 0;
+
+err_sysfs:
+ drm_connector_unregister(drm_connector);
+err_connector:
+ drm_bridge_cleanup(bridge);
+ drm_connector_cleanup(drm_connector);
+ return -EINVAL;
+}
+
+static void sti_hdmi_unbind(struct device *dev,
+ struct device *master, void *data)
+{
+ /* do nothing */
+}
+
+static const struct component_ops sti_hdmi_ops = {
+ .bind = sti_hdmi_bind,
+ .unbind = sti_hdmi_unbind,
+};
+
+static struct of_device_id hdmi_of_match[] = {
+ {
+ .compatible = "st,stih416-hdmi",
+ .data = &tx3g0c55phy_ops,
+ }, {
+ .compatible = "st,stih407-hdmi",
+ .data = &tx3g4c28phy_ops,
+ }, {
+ /* end node */
+ }
+};
+MODULE_DEVICE_TABLE(of, hdmi_of_match);
+
+static int sti_hdmi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct sti_hdmi *hdmi;
+ struct device_node *np = dev->of_node;
+ struct resource *res;
+ int ret;
+
+ DRM_INFO("%s\n", __func__);
+
+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+ if (!hdmi)
+ return -ENOMEM;
+
+ hdmi->dev = pdev->dev;
+
+ /* Get resources */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi-reg");
+ if (!res) {
+ DRM_ERROR("Invalid hdmi resource\n");
+ return -ENOMEM;
+ }
+ hdmi->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+ if (IS_ERR(hdmi->regs))
+ return PTR_ERR(hdmi->regs);
+
+ if (of_device_is_compatible(np, "st,stih416-hdmi")) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "syscfg");
+ if (!res) {
+ DRM_ERROR("Invalid syscfg resource\n");
+ return -ENOMEM;
+ }
+ hdmi->syscfg = devm_ioremap_nocache(dev, res->start,
+ resource_size(res));
+ if (IS_ERR(hdmi->syscfg))
+ return PTR_ERR(hdmi->syscfg);
+
+ }
+
+ hdmi->phy_ops = (struct hdmi_phy_ops *)
+ of_match_node(hdmi_of_match, np)->data;
+
+ /* Get clock resources */
+ hdmi->clk_pix = devm_clk_get(dev, "pix");
+ if (IS_ERR(hdmi->clk_pix)) {
+ DRM_ERROR("Cannot get hdmi_pix clock\n");
+ return PTR_ERR(hdmi->clk_pix);
+ }
+
+ hdmi->clk_tmds = devm_clk_get(dev, "tmds");
+ if (IS_ERR(hdmi->clk_tmds)) {
+ DRM_ERROR("Cannot get hdmi_tmds clock\n");
+ return PTR_ERR(hdmi->clk_tmds);
+ }
+
+ hdmi->clk_phy = devm_clk_get(dev, "phy");
+ if (IS_ERR(hdmi->clk_phy)) {
+ DRM_ERROR("Cannot get hdmi_phy clock\n");
+ return PTR_ERR(hdmi->clk_phy);
+ }
+
+ hdmi->clk_audio = devm_clk_get(dev, "audio");
+ if (IS_ERR(hdmi->clk_audio)) {
+ DRM_ERROR("Cannot get hdmi_audio clock\n");
+ return PTR_ERR(hdmi->clk_audio);
+ }
+
+ hdmi->hpd_gpio = of_get_named_gpio(np, "hdmi,hpd-gpio", 0);
+ if (hdmi->hpd_gpio < 0) {
+ DRM_ERROR("Failed to get hdmi hpd-gpio\n");
+ return -EIO;
+ }
+
+ hdmi->hpd = gpio_get_value(hdmi->hpd_gpio);
+
+ init_waitqueue_head(&hdmi->wait_event);
+
+ hdmi->irq = platform_get_irq_byname(pdev, "irq");
+
+ ret = devm_request_threaded_irq(dev, hdmi->irq, hdmi_irq,
+ hdmi_irq_thread, IRQF_ONESHOT, dev_name(dev), hdmi);
+ if (ret) {
+ DRM_ERROR("Failed to register HDMI interrupt\n");
+ return ret;
+ }
+
+ hdmi->reset = devm_reset_control_get(dev, "hdmi");
+ /* Take hdmi out of reset */
+ if (!IS_ERR(hdmi->reset))
+ reset_control_deassert(hdmi->reset);
+
+ platform_set_drvdata(pdev, hdmi);
+
+ return component_add(&pdev->dev, &sti_hdmi_ops);
+}
+
+static int sti_hdmi_remove(struct platform_device *pdev)
+{
+ component_del(&pdev->dev, &sti_hdmi_ops);
+ return 0;
+}
+
+struct platform_driver sti_hdmi_driver = {
+ .driver = {
+ .name = "sti-hdmi",
+ .owner = THIS_MODULE,
+ .of_match_table = hdmi_of_match,
+ },
+ .probe = sti_hdmi_probe,
+ .remove = sti_hdmi_remove,
+};
+
+module_platform_driver(sti_hdmi_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h
new file mode 100644
index 000000000000..61bec6557ceb
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_HDMI_H_
+#define _STI_HDMI_H_
+
+#include <linux/platform_device.h>
+
+#include <drm/drmP.h>
+
+#define HDMI_STA 0x0010
+#define HDMI_STA_DLL_LCK BIT(5)
+
+struct sti_hdmi;
+
+struct hdmi_phy_ops {
+ bool (*start)(struct sti_hdmi *hdmi);
+ void (*stop)(struct sti_hdmi *hdmi);
+};
+
+/**
+ * STI hdmi structure
+ *
+ * @dev: driver device
+ * @drm_dev: pointer to drm device
+ * @mode: current display mode selected
+ * @regs: hdmi register
+ * @syscfg: syscfg register for pll rejection configuration
+ * @clk_pix: hdmi pixel clock
+ * @clk_tmds: hdmi tmds clock
+ * @clk_phy: hdmi phy clock
+ * @clk_audio: hdmi audio clock
+ * @irq: hdmi interrupt number
+ * @irq_status: interrupt status register
+ * @phy_ops: phy start/stop operations
+ * @enabled: true if hdmi is enabled else false
+ * @hpd_gpio: hdmi hot plug detect gpio number
+ * @hpd: hot plug detect status
+ * @wait_event: wait event
+ * @event_received: wait event status
+ * @reset: reset control of the hdmi phy
+ */
+struct sti_hdmi {
+ struct device dev;
+ struct drm_device *drm_dev;
+ struct drm_display_mode mode;
+ void __iomem *regs;
+ void __iomem *syscfg;
+ struct clk *clk_pix;
+ struct clk *clk_tmds;
+ struct clk *clk_phy;
+ struct clk *clk_audio;
+ int irq;
+ u32 irq_status;
+ struct hdmi_phy_ops *phy_ops;
+ bool enabled;
+ int hpd_gpio;
+ bool hpd;
+ wait_queue_head_t wait_event;
+ bool event_received;
+ struct reset_control *reset;
+};
+
+u32 hdmi_read(struct sti_hdmi *hdmi, int offset);
+void hdmi_write(struct sti_hdmi *hdmi, u32 val, int offset);
+
+/**
+ * hdmi phy config structure
+ *
+ * A pointer to an array of these structures is passed to a TMDS (HDMI) output
+ * via the control interface to provide board and SoC specific
+ * configurations of the HDMI PHY. Each entry in the array specifies a hardware
+ * specific configuration for a given TMDS clock frequency range.
+ *
+ * @min_tmds_freq: Lower bound of TMDS clock frequency this entry applies to
+ * @max_tmds_freq: Upper bound of TMDS clock frequency this entry applies to
+ * @config: SoC specific register configuration
+ */
+struct hdmi_phy_config {
+ u32 min_tmds_freq;
+ u32 max_tmds_freq;
+ u32 config[4];
+};
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c b/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c
new file mode 100644
index 000000000000..49ae8e44b285
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include "sti_hdmi_tx3g0c55phy.h"
+
+#define HDMI_SRZ_PLL_CFG 0x0504
+#define HDMI_SRZ_TAP_1 0x0508
+#define HDMI_SRZ_TAP_2 0x050C
+#define HDMI_SRZ_TAP_3 0x0510
+#define HDMI_SRZ_CTRL 0x0514
+
+#define HDMI_SRZ_PLL_CFG_POWER_DOWN BIT(0)
+#define HDMI_SRZ_PLL_CFG_VCOR_SHIFT 1
+#define HDMI_SRZ_PLL_CFG_VCOR_425MHZ 0
+#define HDMI_SRZ_PLL_CFG_VCOR_850MHZ 1
+#define HDMI_SRZ_PLL_CFG_VCOR_1700MHZ 2
+#define HDMI_SRZ_PLL_CFG_VCOR_3000MHZ 3
+#define HDMI_SRZ_PLL_CFG_VCOR_MASK 3
+#define HDMI_SRZ_PLL_CFG_VCOR(x) (x << HDMI_SRZ_PLL_CFG_VCOR_SHIFT)
+#define HDMI_SRZ_PLL_CFG_NDIV_SHIFT 8
+#define HDMI_SRZ_PLL_CFG_NDIV_MASK (0x1F << HDMI_SRZ_PLL_CFG_NDIV_SHIFT)
+#define HDMI_SRZ_PLL_CFG_MODE_SHIFT 16
+#define HDMI_SRZ_PLL_CFG_MODE_13_5_MHZ 0x1
+#define HDMI_SRZ_PLL_CFG_MODE_25_2_MHZ 0x4
+#define HDMI_SRZ_PLL_CFG_MODE_27_MHZ 0x5
+#define HDMI_SRZ_PLL_CFG_MODE_33_75_MHZ 0x6
+#define HDMI_SRZ_PLL_CFG_MODE_40_5_MHZ 0x7
+#define HDMI_SRZ_PLL_CFG_MODE_54_MHZ 0x8
+#define HDMI_SRZ_PLL_CFG_MODE_67_5_MHZ 0x9
+#define HDMI_SRZ_PLL_CFG_MODE_74_25_MHZ 0xA
+#define HDMI_SRZ_PLL_CFG_MODE_81_MHZ 0xB
+#define HDMI_SRZ_PLL_CFG_MODE_82_5_MHZ 0xC
+#define HDMI_SRZ_PLL_CFG_MODE_108_MHZ 0xD
+#define HDMI_SRZ_PLL_CFG_MODE_148_5_MHZ 0xE
+#define HDMI_SRZ_PLL_CFG_MODE_165_MHZ 0xF
+#define HDMI_SRZ_PLL_CFG_MODE_MASK 0xF
+#define HDMI_SRZ_PLL_CFG_MODE(x) (x << HDMI_SRZ_PLL_CFG_MODE_SHIFT)
+
+#define HDMI_SRZ_CTRL_POWER_DOWN (1 << 0)
+#define HDMI_SRZ_CTRL_EXTERNAL_DATA_EN (1 << 1)
+
+/* sysconf registers */
+#define HDMI_REJECTION_PLL_CONFIGURATION 0x0858 /* SYSTEM_CONFIG2534 */
+#define HDMI_REJECTION_PLL_STATUS 0x0948 /* SYSTEM_CONFIG2594 */
+
+#define REJECTION_PLL_HDMI_ENABLE_SHIFT 0
+#define REJECTION_PLL_HDMI_ENABLE_MASK (0x1 << REJECTION_PLL_HDMI_ENABLE_SHIFT)
+#define REJECTION_PLL_HDMI_PDIV_SHIFT 24
+#define REJECTION_PLL_HDMI_PDIV_MASK (0x7 << REJECTION_PLL_HDMI_PDIV_SHIFT)
+#define REJECTION_PLL_HDMI_NDIV_SHIFT 16
+#define REJECTION_PLL_HDMI_NDIV_MASK (0xFF << REJECTION_PLL_HDMI_NDIV_SHIFT)
+#define REJECTION_PLL_HDMI_MDIV_SHIFT 8
+#define REJECTION_PLL_HDMI_MDIV_MASK (0xFF << REJECTION_PLL_HDMI_MDIV_SHIFT)
+
+#define REJECTION_PLL_HDMI_REJ_PLL_LOCK BIT(0)
+
+#define HDMI_TIMEOUT_PLL_LOCK 50 /*milliseconds */
+
+/**
+ * pll mode structure
+ *
+ * A pointer to an array of these structures is passed to a TMDS (HDMI) output
+ * via the control interface to provide board and SoC specific
+ * configurations of the HDMI PHY. Each entry in the array specifies a hardware
+ * specific configuration for a given TMDS clock frequency range. The array
+ * should be terminated with an entry that has all fields set to zero.
+ *
+ * @min: Lower bound of TMDS clock frequency this entry applies to
+ * @max: Upper bound of TMDS clock frequency this entry applies to
+ * @mode: SoC specific register configuration
+ */
+struct pllmode {
+ u32 min;
+ u32 max;
+ u32 mode;
+};
+
+#define NB_PLL_MODE 7
+static struct pllmode pllmodes[NB_PLL_MODE] = {
+ {13500000, 13513500, HDMI_SRZ_PLL_CFG_MODE_13_5_MHZ},
+ {25174800, 25200000, HDMI_SRZ_PLL_CFG_MODE_25_2_MHZ},
+ {27000000, 27027000, HDMI_SRZ_PLL_CFG_MODE_27_MHZ},
+ {54000000, 54054000, HDMI_SRZ_PLL_CFG_MODE_54_MHZ},
+ {72000000, 74250000, HDMI_SRZ_PLL_CFG_MODE_74_25_MHZ},
+ {108000000, 108108000, HDMI_SRZ_PLL_CFG_MODE_108_MHZ},
+ {148351648, 297000000, HDMI_SRZ_PLL_CFG_MODE_148_5_MHZ}
+};
+
+#define NB_HDMI_PHY_CONFIG 5
+static struct hdmi_phy_config hdmiphy_config[NB_HDMI_PHY_CONFIG] = {
+ {0, 40000000, {0x00101010, 0x00101010, 0x00101010, 0x02} },
+ {40000000, 140000000, {0x00111111, 0x00111111, 0x00111111, 0x02} },
+ {140000000, 160000000, {0x00131313, 0x00101010, 0x00101010, 0x02} },
+ {160000000, 250000000, {0x00131313, 0x00111111, 0x00111111, 0x03FE} },
+ {250000000, 300000000, {0x00151515, 0x00101010, 0x00101010, 0x03FE} },
+};
+
+#define PLL_CHANGE_DELAY 1 /* ms */
+
+/**
+ * Disable the pll rejection
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * return true if the pll has been disabled
+ */
+static bool disable_pll_rejection(struct sti_hdmi *hdmi)
+{
+ u32 val;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
+ val &= ~REJECTION_PLL_HDMI_ENABLE_MASK;
+ writel(val, hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
+
+ msleep(PLL_CHANGE_DELAY);
+ val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_STATUS);
+
+ return !(val & REJECTION_PLL_HDMI_REJ_PLL_LOCK);
+}
+
+/**
+ * Enable the old BCH/rejection PLL is now reused to provide the CLKPXPLL
+ * clock input to the new PHY PLL that generates the serializer clock
+ * (TMDS*10) and the TMDS clock which is now fed back into the HDMI
+ * formatter instead of the TMDS clock line from ClockGenB.
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * return true if pll has been correctly set
+ */
+static bool enable_pll_rejection(struct sti_hdmi *hdmi)
+{
+ unsigned int inputclock;
+ u32 mdiv, ndiv, pdiv, val;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ if (!disable_pll_rejection(hdmi))
+ return false;
+
+ inputclock = hdmi->mode.clock * 1000;
+
+ DRM_DEBUG_DRIVER("hdmi rejection pll input clock = %dHz\n", inputclock);
+
+
+ /* Power up the HDMI rejection PLL
+ * Note: On this SoC (stiH416) we are forced to have the input clock
+ * be equal to the HDMI pixel clock.
+ *
+ * The values here have been suggested by validation however they are
+ * still provisional and subject to change.
+ *
+ * PLLout = (Fin*Mdiv) / ((2 * Ndiv) / 2^Pdiv)
+ */
+ if (inputclock < 50000000) {
+ /*
+ * For slower clocks we need to multiply more to keep the
+ * internal VCO frequency within the physical specification
+ * of the PLL.
+ */
+ pdiv = 4;
+ ndiv = 240;
+ mdiv = 30;
+ } else {
+ pdiv = 2;
+ ndiv = 60;
+ mdiv = 30;
+ }
+
+ val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
+
+ val &= ~(REJECTION_PLL_HDMI_PDIV_MASK |
+ REJECTION_PLL_HDMI_NDIV_MASK |
+ REJECTION_PLL_HDMI_MDIV_MASK |
+ REJECTION_PLL_HDMI_ENABLE_MASK);
+
+ val |= (pdiv << REJECTION_PLL_HDMI_PDIV_SHIFT) |
+ (ndiv << REJECTION_PLL_HDMI_NDIV_SHIFT) |
+ (mdiv << REJECTION_PLL_HDMI_MDIV_SHIFT) |
+ (0x1 << REJECTION_PLL_HDMI_ENABLE_SHIFT);
+
+ writel(val, hdmi->syscfg + HDMI_REJECTION_PLL_CONFIGURATION);
+
+ msleep(PLL_CHANGE_DELAY);
+ val = readl(hdmi->syscfg + HDMI_REJECTION_PLL_STATUS);
+
+ return (val & REJECTION_PLL_HDMI_REJ_PLL_LOCK);
+}
+
+/**
+ * Start hdmi phy macro cell tx3g0c55
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * Return false if an error occur
+ */
+static bool sti_hdmi_tx3g0c55phy_start(struct sti_hdmi *hdmi)
+{
+ u32 ckpxpll = hdmi->mode.clock * 1000;
+ u32 val, tmdsck, freqvco, pllctrl = 0;
+ unsigned int i;
+
+ if (!enable_pll_rejection(hdmi))
+ return false;
+
+ DRM_DEBUG_DRIVER("ckpxpll = %dHz\n", ckpxpll);
+
+ /* Assuming no pixel repetition and 24bits color */
+ tmdsck = ckpxpll;
+ pllctrl = 2 << HDMI_SRZ_PLL_CFG_NDIV_SHIFT;
+
+ /*
+ * Setup the PLL mode parameter based on the ckpxpll. If we haven't got
+ * a clock frequency supported by one of the specific PLL modes then we
+ * will end up using the generic mode (0) which only supports a 10x
+ * multiplier, hence only 24bit color.
+ */
+ for (i = 0; i < NB_PLL_MODE; i++) {
+ if (ckpxpll >= pllmodes[i].min && ckpxpll <= pllmodes[i].max)
+ pllctrl |= HDMI_SRZ_PLL_CFG_MODE(pllmodes[i].mode);
+ }
+
+ freqvco = tmdsck * 10;
+ if (freqvco <= 425000000UL)
+ pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_425MHZ);
+ else if (freqvco <= 850000000UL)
+ pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_850MHZ);
+ else if (freqvco <= 1700000000UL)
+ pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_1700MHZ);
+ else if (freqvco <= 2970000000UL)
+ pllctrl |= HDMI_SRZ_PLL_CFG_VCOR(HDMI_SRZ_PLL_CFG_VCOR_3000MHZ);
+ else {
+ DRM_ERROR("PHY serializer clock out of range\n");
+ goto err;
+ }
+
+ /*
+ * Configure and power up the PHY PLL
+ */
+ hdmi->event_received = false;
+ DRM_DEBUG_DRIVER("pllctrl = 0x%x\n", pllctrl);
+ hdmi_write(hdmi, pllctrl, HDMI_SRZ_PLL_CFG);
+
+ /* wait PLL interrupt */
+ wait_event_interruptible_timeout(hdmi->wait_event,
+ hdmi->event_received == true,
+ msecs_to_jiffies
+ (HDMI_TIMEOUT_PLL_LOCK));
+
+ if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK) == 0) {
+ DRM_ERROR("hdmi phy pll not locked\n");
+ goto err;
+ }
+
+ DRM_DEBUG_DRIVER("got PHY PLL Lock\n");
+
+ /*
+ * To configure the source termination and pre-emphasis appropriately
+ * for different high speed TMDS clock frequencies a phy configuration
+ * table must be provided, tailored to the SoC and board combination.
+ */
+ for (i = 0; i < NB_HDMI_PHY_CONFIG; i++) {
+ if ((hdmiphy_config[i].min_tmds_freq <= tmdsck) &&
+ (hdmiphy_config[i].max_tmds_freq >= tmdsck)) {
+ val = hdmiphy_config[i].config[0];
+ hdmi_write(hdmi, val, HDMI_SRZ_TAP_1);
+ val = hdmiphy_config[i].config[1];
+ hdmi_write(hdmi, val, HDMI_SRZ_TAP_2);
+ val = hdmiphy_config[i].config[2];
+ hdmi_write(hdmi, val, HDMI_SRZ_TAP_3);
+ val = hdmiphy_config[i].config[3];
+ val |= HDMI_SRZ_CTRL_EXTERNAL_DATA_EN;
+ val &= ~HDMI_SRZ_CTRL_POWER_DOWN;
+ hdmi_write(hdmi, val, HDMI_SRZ_CTRL);
+
+ DRM_DEBUG_DRIVER("serializer cfg 0x%x 0x%x 0x%x 0x%x\n",
+ hdmiphy_config[i].config[0],
+ hdmiphy_config[i].config[1],
+ hdmiphy_config[i].config[2],
+ hdmiphy_config[i].config[3]);
+ return true;
+ }
+ }
+
+ /*
+ * Default, power up the serializer with no pre-emphasis or source
+ * termination.
+ */
+ hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_1);
+ hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_2);
+ hdmi_write(hdmi, 0x0, HDMI_SRZ_TAP_3);
+ hdmi_write(hdmi, HDMI_SRZ_CTRL_EXTERNAL_DATA_EN, HDMI_SRZ_CTRL);
+
+ return true;
+
+err:
+ disable_pll_rejection(hdmi);
+
+ return false;
+}
+
+/**
+ * Stop hdmi phy macro cell tx3g0c55
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ */
+static void sti_hdmi_tx3g0c55phy_stop(struct sti_hdmi *hdmi)
+{
+ DRM_DEBUG_DRIVER("\n");
+
+ hdmi->event_received = false;
+
+ hdmi_write(hdmi, HDMI_SRZ_CTRL_POWER_DOWN, HDMI_SRZ_CTRL);
+ hdmi_write(hdmi, HDMI_SRZ_PLL_CFG_POWER_DOWN, HDMI_SRZ_PLL_CFG);
+
+ /* wait PLL interrupt */
+ wait_event_interruptible_timeout(hdmi->wait_event,
+ hdmi->event_received == true,
+ msecs_to_jiffies
+ (HDMI_TIMEOUT_PLL_LOCK));
+
+ if (hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK)
+ DRM_ERROR("hdmi phy pll not well disabled\n");
+
+ disable_pll_rejection(hdmi);
+}
+
+struct hdmi_phy_ops tx3g0c55phy_ops = {
+ .start = sti_hdmi_tx3g0c55phy_start,
+ .stop = sti_hdmi_tx3g0c55phy_stop,
+};
diff --git a/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h b/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h
new file mode 100644
index 000000000000..068237b3a303
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi_tx3g0c55phy.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_HDMI_TX3G0C55PHY_H_
+#define _STI_HDMI_TX3G0C55PHY_H_
+
+#include "sti_hdmi.h"
+
+extern struct hdmi_phy_ops tx3g0c55phy_ops;
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c b/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c
new file mode 100644
index 000000000000..8e0ceb0ced33
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include "sti_hdmi_tx3g4c28phy.h"
+
+#define HDMI_SRZ_CFG 0x504
+#define HDMI_SRZ_PLL_CFG 0x510
+#define HDMI_SRZ_ICNTL 0x518
+#define HDMI_SRZ_CALCODE_EXT 0x520
+
+#define HDMI_SRZ_CFG_EN BIT(0)
+#define HDMI_SRZ_CFG_DISABLE_BYPASS_SINK_CURRENT BIT(1)
+#define HDMI_SRZ_CFG_EXTERNAL_DATA BIT(16)
+#define HDMI_SRZ_CFG_RBIAS_EXT BIT(17)
+#define HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION BIT(18)
+#define HDMI_SRZ_CFG_EN_BIASRES_DETECTION BIT(19)
+#define HDMI_SRZ_CFG_EN_SRC_TERMINATION BIT(24)
+
+#define HDMI_SRZ_CFG_INTERNAL_MASK (HDMI_SRZ_CFG_EN | \
+ HDMI_SRZ_CFG_DISABLE_BYPASS_SINK_CURRENT | \
+ HDMI_SRZ_CFG_EXTERNAL_DATA | \
+ HDMI_SRZ_CFG_RBIAS_EXT | \
+ HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION | \
+ HDMI_SRZ_CFG_EN_BIASRES_DETECTION | \
+ HDMI_SRZ_CFG_EN_SRC_TERMINATION)
+
+#define PLL_CFG_EN BIT(0)
+#define PLL_CFG_NDIV_SHIFT (8)
+#define PLL_CFG_IDF_SHIFT (16)
+#define PLL_CFG_ODF_SHIFT (24)
+
+#define ODF_DIV_1 (0)
+#define ODF_DIV_2 (1)
+#define ODF_DIV_4 (2)
+#define ODF_DIV_8 (3)
+
+#define HDMI_TIMEOUT_PLL_LOCK 50 /*milliseconds */
+
+struct plldividers_s {
+ uint32_t min;
+ uint32_t max;
+ uint32_t idf;
+ uint32_t odf;
+};
+
+/*
+ * Functional specification recommended values
+ */
+#define NB_PLL_MODE 5
+static struct plldividers_s plldividers[NB_PLL_MODE] = {
+ {0, 20000000, 1, ODF_DIV_8},
+ {20000000, 42500000, 2, ODF_DIV_8},
+ {42500000, 85000000, 4, ODF_DIV_4},
+ {85000000, 170000000, 8, ODF_DIV_2},
+ {170000000, 340000000, 16, ODF_DIV_1}
+};
+
+#define NB_HDMI_PHY_CONFIG 2
+static struct hdmi_phy_config hdmiphy_config[NB_HDMI_PHY_CONFIG] = {
+ {0, 250000000, {0x0, 0x0, 0x0, 0x0} },
+ {250000000, 300000000, {0x1110, 0x0, 0x0, 0x0} },
+};
+
+/**
+ * Start hdmi phy macro cell tx3g4c28
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ *
+ * Return false if an error occur
+ */
+static bool sti_hdmi_tx3g4c28phy_start(struct sti_hdmi *hdmi)
+{
+ u32 ckpxpll = hdmi->mode.clock * 1000;
+ u32 val, tmdsck, idf, odf, pllctrl = 0;
+ bool foundplldivides = false;
+ int i;
+
+ DRM_DEBUG_DRIVER("ckpxpll = %dHz\n", ckpxpll);
+
+ for (i = 0; i < NB_PLL_MODE; i++) {
+ if (ckpxpll >= plldividers[i].min &&
+ ckpxpll < plldividers[i].max) {
+ idf = plldividers[i].idf;
+ odf = plldividers[i].odf;
+ foundplldivides = true;
+ break;
+ }
+ }
+
+ if (!foundplldivides) {
+ DRM_ERROR("input TMDS clock speed (%d) not supported\n",
+ ckpxpll);
+ goto err;
+ }
+
+ /* Assuming no pixel repetition and 24bits color */
+ tmdsck = ckpxpll;
+ pllctrl |= 40 << PLL_CFG_NDIV_SHIFT;
+
+ if (tmdsck > 340000000) {
+ DRM_ERROR("output TMDS clock (%d) out of range\n", tmdsck);
+ goto err;
+ }
+
+ pllctrl |= idf << PLL_CFG_IDF_SHIFT;
+ pllctrl |= odf << PLL_CFG_ODF_SHIFT;
+
+ /*
+ * Configure and power up the PHY PLL
+ */
+ hdmi->event_received = false;
+ DRM_DEBUG_DRIVER("pllctrl = 0x%x\n", pllctrl);
+ hdmi_write(hdmi, (pllctrl | PLL_CFG_EN), HDMI_SRZ_PLL_CFG);
+
+ /* wait PLL interrupt */
+ wait_event_interruptible_timeout(hdmi->wait_event,
+ hdmi->event_received == true,
+ msecs_to_jiffies
+ (HDMI_TIMEOUT_PLL_LOCK));
+
+ if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK) == 0) {
+ DRM_ERROR("hdmi phy pll not locked\n");
+ goto err;
+ }
+
+ DRM_DEBUG_DRIVER("got PHY PLL Lock\n");
+
+ val = (HDMI_SRZ_CFG_EN |
+ HDMI_SRZ_CFG_EXTERNAL_DATA |
+ HDMI_SRZ_CFG_EN_BIASRES_DETECTION |
+ HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION);
+
+ if (tmdsck > 165000000)
+ val |= HDMI_SRZ_CFG_EN_SRC_TERMINATION;
+
+ /*
+ * To configure the source termination and pre-emphasis appropriately
+ * for different high speed TMDS clock frequencies a phy configuration
+ * table must be provided, tailored to the SoC and board combination.
+ */
+ for (i = 0; i < NB_HDMI_PHY_CONFIG; i++) {
+ if ((hdmiphy_config[i].min_tmds_freq <= tmdsck) &&
+ (hdmiphy_config[i].max_tmds_freq >= tmdsck)) {
+ val |= (hdmiphy_config[i].config[0]
+ & ~HDMI_SRZ_CFG_INTERNAL_MASK);
+ hdmi_write(hdmi, val, HDMI_SRZ_CFG);
+
+ val = hdmiphy_config[i].config[1];
+ hdmi_write(hdmi, val, HDMI_SRZ_ICNTL);
+
+ val = hdmiphy_config[i].config[2];
+ hdmi_write(hdmi, val, HDMI_SRZ_CALCODE_EXT);
+
+ DRM_DEBUG_DRIVER("serializer cfg 0x%x 0x%x 0x%x\n",
+ hdmiphy_config[i].config[0],
+ hdmiphy_config[i].config[1],
+ hdmiphy_config[i].config[2]);
+ return true;
+ }
+ }
+
+ /*
+ * Default, power up the serializer with no pre-emphasis or
+ * output swing correction
+ */
+ hdmi_write(hdmi, val, HDMI_SRZ_CFG);
+ hdmi_write(hdmi, 0x0, HDMI_SRZ_ICNTL);
+ hdmi_write(hdmi, 0x0, HDMI_SRZ_CALCODE_EXT);
+
+ return true;
+
+err:
+ return false;
+}
+
+/**
+ * Stop hdmi phy macro cell tx3g4c28
+ *
+ * @hdmi: pointer on the hdmi internal structure
+ */
+static void sti_hdmi_tx3g4c28phy_stop(struct sti_hdmi *hdmi)
+{
+ int val = 0;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ hdmi->event_received = false;
+
+ val = HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION;
+ val |= HDMI_SRZ_CFG_EN_BIASRES_DETECTION;
+
+ hdmi_write(hdmi, val, HDMI_SRZ_CFG);
+ hdmi_write(hdmi, 0, HDMI_SRZ_PLL_CFG);
+
+ /* wait PLL interrupt */
+ wait_event_interruptible_timeout(hdmi->wait_event,
+ hdmi->event_received == true,
+ msecs_to_jiffies
+ (HDMI_TIMEOUT_PLL_LOCK));
+
+ if (hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK)
+ DRM_ERROR("hdmi phy pll not well disabled\n");
+}
+
+struct hdmi_phy_ops tx3g4c28phy_ops = {
+ .start = sti_hdmi_tx3g4c28phy_start,
+ .stop = sti_hdmi_tx3g4c28phy_stop,
+};
diff --git a/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h b/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h
new file mode 100644
index 000000000000..f99a7ff281ef
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_hdmi_tx3g4c28phy.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_HDMI_TX3G4C28PHY_H_
+#define _STI_HDMI_TX3G4C28PHY_H_
+
+#include "sti_hdmi.h"
+
+extern struct hdmi_phy_ops tx3g4c28phy_ops;
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_layer.c b/drivers/gpu/drm/sti/sti_layer.c
new file mode 100644
index 000000000000..06a587c4f1bb
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_layer.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "sti_compositor.h"
+#include "sti_gdp.h"
+#include "sti_layer.h"
+#include "sti_vid.h"
+
+const char *sti_layer_to_str(struct sti_layer *layer)
+{
+ switch (layer->desc) {
+ case STI_GDP_0:
+ return "GDP0";
+ case STI_GDP_1:
+ return "GDP1";
+ case STI_GDP_2:
+ return "GDP2";
+ case STI_GDP_3:
+ return "GDP3";
+ case STI_VID_0:
+ return "VID0";
+ case STI_VID_1:
+ return "VID1";
+ case STI_CURSOR:
+ return "CURSOR";
+ default:
+ return "<UNKNOWN LAYER>";
+ }
+}
+
+struct sti_layer *sti_layer_create(struct device *dev, int desc,
+ void __iomem *baseaddr)
+{
+
+ struct sti_layer *layer = NULL;
+
+ switch (desc & STI_LAYER_TYPE_MASK) {
+ case STI_GDP:
+ layer = sti_gdp_create(dev, desc);
+ break;
+ case STI_VID:
+ layer = sti_vid_create(dev);
+ break;
+ }
+
+ if (!layer) {
+ DRM_ERROR("Failed to create layer\n");
+ return NULL;
+ }
+
+ layer->desc = desc;
+ layer->dev = dev;
+ layer->regs = baseaddr;
+
+ layer->ops->init(layer);
+
+ DRM_DEBUG_DRIVER("%s created\n", sti_layer_to_str(layer));
+
+ return layer;
+}
+
+int sti_layer_prepare(struct sti_layer *layer, struct drm_framebuffer *fb,
+ struct drm_display_mode *mode, int mixer_id,
+ int dest_x, int dest_y, int dest_w, int dest_h,
+ int src_x, int src_y, int src_w, int src_h)
+{
+ int ret;
+ unsigned int i;
+ struct drm_gem_cma_object *cma_obj;
+
+ if (!layer || !fb || !mode) {
+ DRM_ERROR("Null fb, layer or mode\n");
+ return 1;
+ }
+
+ cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ if (!cma_obj) {
+ DRM_ERROR("Can't get CMA GEM object for fb\n");
+ return 1;
+ }
+
+ layer->fb = fb;
+ layer->mode = mode;
+ layer->mixer_id = mixer_id;
+ layer->dst_x = dest_x;
+ layer->dst_y = dest_y;
+ layer->dst_w = clamp_val(dest_w, 0, mode->crtc_hdisplay - dest_x);
+ layer->dst_h = clamp_val(dest_h, 0, mode->crtc_vdisplay - dest_y);
+ layer->src_x = src_x;
+ layer->src_y = src_y;
+ layer->src_w = src_w;
+ layer->src_h = src_h;
+ layer->format = fb->pixel_format;
+ layer->paddr = cma_obj->paddr;
+ for (i = 0; i < 4; i++) {
+ layer->pitches[i] = fb->pitches[i];
+ layer->offsets[i] = fb->offsets[i];
+ }
+
+ DRM_DEBUG_DRIVER("%s is associated with mixer_id %d\n",
+ sti_layer_to_str(layer),
+ layer->mixer_id);
+ DRM_DEBUG_DRIVER("%s dst=(%dx%d)@(%d,%d) - src=(%dx%d)@(%d,%d)\n",
+ sti_layer_to_str(layer),
+ layer->dst_w, layer->dst_h, layer->dst_x, layer->dst_y,
+ layer->src_w, layer->src_h, layer->src_x,
+ layer->src_y);
+
+ DRM_DEBUG_DRIVER("drm FB:%d format:%.4s phys@:0x%lx\n", fb->base.id,
+ (char *)&layer->format, (unsigned long)layer->paddr);
+
+ if (!layer->ops->prepare)
+ goto err_no_prepare;
+
+ ret = layer->ops->prepare(layer, !layer->enabled);
+ if (!ret)
+ layer->enabled = true;
+
+ return ret;
+
+err_no_prepare:
+ DRM_ERROR("Cannot prepare\n");
+ return 1;
+}
+
+int sti_layer_commit(struct sti_layer *layer)
+{
+ if (!layer)
+ return 1;
+
+ if (!layer->ops->commit)
+ goto err_no_commit;
+
+ return layer->ops->commit(layer);
+
+err_no_commit:
+ DRM_ERROR("Cannot commit\n");
+ return 1;
+}
+
+int sti_layer_disable(struct sti_layer *layer)
+{
+ int ret;
+
+ DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer));
+ if (!layer)
+ return 1;
+
+ if (!layer->enabled)
+ return 0;
+
+ if (!layer->ops->disable)
+ goto err_no_disable;
+
+ ret = layer->ops->disable(layer);
+ if (!ret)
+ layer->enabled = false;
+ else
+ DRM_ERROR("Disable failed\n");
+
+ return ret;
+
+err_no_disable:
+ DRM_ERROR("Cannot disable\n");
+ return 1;
+}
+
+const uint32_t *sti_layer_get_formats(struct sti_layer *layer)
+{
+ if (!layer)
+ return NULL;
+
+ if (!layer->ops->get_formats)
+ return NULL;
+
+ return layer->ops->get_formats(layer);
+}
+
+unsigned int sti_layer_get_nb_formats(struct sti_layer *layer)
+{
+ if (!layer)
+ return 0;
+
+ if (!layer->ops->get_nb_formats)
+ return 0;
+
+ return layer->ops->get_nb_formats(layer);
+}
diff --git a/drivers/gpu/drm/sti/sti_layer.h b/drivers/gpu/drm/sti/sti_layer.h
new file mode 100644
index 000000000000..198c3774cc12
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_layer.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_LAYER_H_
+#define _STI_LAYER_H_
+
+#include <drm/drmP.h>
+
+#define to_sti_layer(x) container_of(x, struct sti_layer, plane)
+
+#define STI_LAYER_TYPE_SHIFT 8
+#define STI_LAYER_TYPE_MASK (~((1<<STI_LAYER_TYPE_SHIFT)-1))
+
+struct sti_layer;
+
+enum sti_layer_type {
+ STI_GDP = 1 << STI_LAYER_TYPE_SHIFT,
+ STI_VID = 2 << STI_LAYER_TYPE_SHIFT,
+ STI_CUR = 3 << STI_LAYER_TYPE_SHIFT,
+ STI_BCK = 4 << STI_LAYER_TYPE_SHIFT
+};
+
+enum sti_layer_id_of_type {
+ STI_ID_0 = 0,
+ STI_ID_1 = 1,
+ STI_ID_2 = 2,
+ STI_ID_3 = 3
+};
+
+enum sti_layer_desc {
+ STI_GDP_0 = STI_GDP | STI_ID_0,
+ STI_GDP_1 = STI_GDP | STI_ID_1,
+ STI_GDP_2 = STI_GDP | STI_ID_2,
+ STI_GDP_3 = STI_GDP | STI_ID_3,
+ STI_VID_0 = STI_VID | STI_ID_0,
+ STI_VID_1 = STI_VID | STI_ID_1,
+ STI_CURSOR = STI_CUR,
+ STI_BACK = STI_BCK
+};
+
+/**
+ * STI layer functions structure
+ *
+ * @get_formats: get layer supported formats
+ * @get_nb_formats: get number of format supported
+ * @init: initialize the layer
+ * @prepare: prepare layer before rendering
+ * @commit: set layer for rendering
+ * @disable: disable layer
+ */
+struct sti_layer_funcs {
+ const uint32_t* (*get_formats)(struct sti_layer *layer);
+ unsigned int (*get_nb_formats)(struct sti_layer *layer);
+ void (*init)(struct sti_layer *layer);
+ int (*prepare)(struct sti_layer *layer, bool first_prepare);
+ int (*commit)(struct sti_layer *layer);
+ int (*disable)(struct sti_layer *layer);
+};
+
+/**
+ * STI layer structure
+ *
+ * @plane: drm plane it is bound to (if any)
+ * @fb: drm fb it is bound to
+ * @mode: display mode
+ * @desc: layer type & id
+ * @device: driver device
+ * @regs: layer registers
+ * @ops: layer functions
+ * @zorder: layer z-order
+ * @mixer_id: id of the mixer used to display the layer
+ * @enabled: to know if the layer is active or not
+ * @src_x src_y: coordinates of the input (fb) area
+ * @src_w src_h: size of the input (fb) area
+ * @dst_x dst_y: coordinates of the output (crtc) area
+ * @dst_w dst_h: size of the output (crtc) area
+ * @format: format
+ * @pitches: pitch of 'planes' (eg: Y, U, V)
+ * @offsets: offset of 'planes'
+ * @paddr: physical address of the input buffer
+ */
+struct sti_layer {
+ struct drm_plane plane;
+ struct drm_framebuffer *fb;
+ struct drm_display_mode *mode;
+ enum sti_layer_desc desc;
+ struct device *dev;
+ void __iomem *regs;
+ const struct sti_layer_funcs *ops;
+ int zorder;
+ int mixer_id;
+ bool enabled;
+ int src_x, src_y;
+ int src_w, src_h;
+ int dst_x, dst_y;
+ int dst_w, dst_h;
+ uint32_t format;
+ unsigned int pitches[4];
+ unsigned int offsets[4];
+ dma_addr_t paddr;
+};
+
+struct sti_layer *sti_layer_create(struct device *dev, int desc,
+ void __iomem *baseaddr);
+int sti_layer_prepare(struct sti_layer *layer, struct drm_framebuffer *fb,
+ struct drm_display_mode *mode,
+ int mixer_id,
+ int dest_x, int dest_y,
+ int dest_w, int dest_h,
+ int src_x, int src_y,
+ int src_w, int src_h);
+int sti_layer_commit(struct sti_layer *layer);
+int sti_layer_disable(struct sti_layer *layer);
+const uint32_t *sti_layer_get_formats(struct sti_layer *layer);
+unsigned int sti_layer_get_nb_formats(struct sti_layer *layer);
+const char *sti_layer_to_str(struct sti_layer *layer);
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
new file mode 100644
index 000000000000..79f369db9fb6
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_mixer.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include "sti_compositor.h"
+#include "sti_mixer.h"
+#include "sti_vtg.h"
+
+/* Identity: G=Y , B=Cb , R=Cr */
+static const u32 mixerColorSpaceMatIdentity[] = {
+ 0x10000000, 0x00000000, 0x10000000, 0x00001000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+/* regs offset */
+#define GAM_MIXER_CTL 0x00
+#define GAM_MIXER_BKC 0x04
+#define GAM_MIXER_BCO 0x0C
+#define GAM_MIXER_BCS 0x10
+#define GAM_MIXER_AVO 0x28
+#define GAM_MIXER_AVS 0x2C
+#define GAM_MIXER_CRB 0x34
+#define GAM_MIXER_ACT 0x38
+#define GAM_MIXER_MBP 0x3C
+#define GAM_MIXER_MX0 0x80
+
+/* id for depth of CRB reg */
+#define GAM_DEPTH_VID0_ID 1
+#define GAM_DEPTH_VID1_ID 2
+#define GAM_DEPTH_GDP0_ID 3
+#define GAM_DEPTH_GDP1_ID 4
+#define GAM_DEPTH_GDP2_ID 5
+#define GAM_DEPTH_GDP3_ID 6
+#define GAM_DEPTH_MASK_ID 7
+
+/* mask in CTL reg */
+#define GAM_CTL_BACK_MASK BIT(0)
+#define GAM_CTL_VID0_MASK BIT(1)
+#define GAM_CTL_VID1_MASK BIT(2)
+#define GAM_CTL_GDP0_MASK BIT(3)
+#define GAM_CTL_GDP1_MASK BIT(4)
+#define GAM_CTL_GDP2_MASK BIT(5)
+#define GAM_CTL_GDP3_MASK BIT(6)
+
+const char *sti_mixer_to_str(struct sti_mixer *mixer)
+{
+ switch (mixer->id) {
+ case STI_MIXER_MAIN:
+ return "MAIN_MIXER";
+ case STI_MIXER_AUX:
+ return "AUX_MIXER";
+ default:
+ return "<UNKNOWN MIXER>";
+ }
+}
+
+static inline u32 sti_mixer_reg_read(struct sti_mixer *mixer, u32 reg_id)
+{
+ return readl(mixer->regs + reg_id);
+}
+
+static inline void sti_mixer_reg_write(struct sti_mixer *mixer,
+ u32 reg_id, u32 val)
+{
+ writel(val, mixer->regs + reg_id);
+}
+
+void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable)
+{
+ u32 val = sti_mixer_reg_read(mixer, GAM_MIXER_CTL);
+
+ val &= ~GAM_CTL_BACK_MASK;
+ val |= enable;
+ sti_mixer_reg_write(mixer, GAM_MIXER_CTL, val);
+}
+
+static void sti_mixer_set_background_color(struct sti_mixer *mixer,
+ u8 red, u8 green, u8 blue)
+{
+ u32 val = (red << 16) | (green << 8) | blue;
+
+ sti_mixer_reg_write(mixer, GAM_MIXER_BKC, val);
+}
+
+static void sti_mixer_set_background_area(struct sti_mixer *mixer,
+ struct drm_display_mode *mode)
+{
+ u32 ydo, xdo, yds, xds;
+
+ ydo = sti_vtg_get_line_number(*mode, 0);
+ yds = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);
+ xdo = sti_vtg_get_pixel_number(*mode, 0);
+ xds = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
+
+ sti_mixer_reg_write(mixer, GAM_MIXER_BCO, ydo << 16 | xdo);
+ sti_mixer_reg_write(mixer, GAM_MIXER_BCS, yds << 16 | xds);
+}
+
+int sti_mixer_set_layer_depth(struct sti_mixer *mixer, struct sti_layer *layer)
+{
+ int layer_id = 0, depth = layer->zorder;
+ u32 mask, val;
+
+ if (depth >= GAM_MIXER_NB_DEPTH_LEVEL)
+ return 1;
+
+ switch (layer->desc) {
+ case STI_GDP_0:
+ layer_id = GAM_DEPTH_GDP0_ID;
+ break;
+ case STI_GDP_1:
+ layer_id = GAM_DEPTH_GDP1_ID;
+ break;
+ case STI_GDP_2:
+ layer_id = GAM_DEPTH_GDP2_ID;
+ break;
+ case STI_GDP_3:
+ layer_id = GAM_DEPTH_GDP3_ID;
+ break;
+ case STI_VID_0:
+ layer_id = GAM_DEPTH_VID0_ID;
+ break;
+ case STI_VID_1:
+ layer_id = GAM_DEPTH_VID1_ID;
+ break;
+ default:
+ DRM_ERROR("Unknown layer %d\n", layer->desc);
+ return 1;
+ }
+ mask = GAM_DEPTH_MASK_ID << (3 * depth);
+ layer_id = layer_id << (3 * depth);
+
+ DRM_DEBUG_DRIVER("%s %s depth=%d\n", sti_mixer_to_str(mixer),
+ sti_layer_to_str(layer), depth);
+ dev_dbg(mixer->dev, "GAM_MIXER_CRB val 0x%x mask 0x%x\n",
+ layer_id, mask);
+
+ val = sti_mixer_reg_read(mixer, GAM_MIXER_CRB);
+ val &= ~mask;
+ val |= layer_id;
+ sti_mixer_reg_write(mixer, GAM_MIXER_CRB, val);
+
+ dev_dbg(mixer->dev, "Read GAM_MIXER_CRB 0x%x\n",
+ sti_mixer_reg_read(mixer, GAM_MIXER_CRB));
+ return 0;
+}
+
+int sti_mixer_active_video_area(struct sti_mixer *mixer,
+ struct drm_display_mode *mode)
+{
+ u32 ydo, xdo, yds, xds;
+
+ ydo = sti_vtg_get_line_number(*mode, 0);
+ yds = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);
+ xdo = sti_vtg_get_pixel_number(*mode, 0);
+ xds = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
+
+ DRM_DEBUG_DRIVER("%s active video area xdo:%d ydo:%d xds:%d yds:%d\n",
+ sti_mixer_to_str(mixer), xdo, ydo, xds, yds);
+ sti_mixer_reg_write(mixer, GAM_MIXER_AVO, ydo << 16 | xdo);
+ sti_mixer_reg_write(mixer, GAM_MIXER_AVS, yds << 16 | xds);
+
+ sti_mixer_set_background_color(mixer, 0xFF, 0, 0);
+
+ sti_mixer_set_background_area(mixer, mode);
+ sti_mixer_set_background_status(mixer, true);
+ return 0;
+}
+
+static u32 sti_mixer_get_layer_mask(struct sti_layer *layer)
+{
+ switch (layer->desc) {
+ case STI_BACK:
+ return GAM_CTL_BACK_MASK;
+ case STI_GDP_0:
+ return GAM_CTL_GDP0_MASK;
+ case STI_GDP_1:
+ return GAM_CTL_GDP1_MASK;
+ case STI_GDP_2:
+ return GAM_CTL_GDP2_MASK;
+ case STI_GDP_3:
+ return GAM_CTL_GDP3_MASK;
+ case STI_VID_0:
+ return GAM_CTL_VID0_MASK;
+ case STI_VID_1:
+ return GAM_CTL_VID1_MASK;
+ default:
+ return 0;
+ }
+}
+
+int sti_mixer_set_layer_status(struct sti_mixer *mixer,
+ struct sti_layer *layer, bool status)
+{
+ u32 mask, val;
+
+ DRM_DEBUG_DRIVER("%s %s %s\n", status ? "enable" : "disable",
+ sti_mixer_to_str(mixer), sti_layer_to_str(layer));
+
+ mask = sti_mixer_get_layer_mask(layer);
+ if (!mask) {
+ DRM_ERROR("Can not find layer mask\n");
+ return -EINVAL;
+ }
+
+ val = sti_mixer_reg_read(mixer, GAM_MIXER_CTL);
+ val &= ~mask;
+ val |= status ? mask : 0;
+ sti_mixer_reg_write(mixer, GAM_MIXER_CTL, val);
+
+ return 0;
+}
+
+void sti_mixer_set_matrix(struct sti_mixer *mixer)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(mixerColorSpaceMatIdentity); i++)
+ sti_mixer_reg_write(mixer, GAM_MIXER_MX0 + (i * 4),
+ mixerColorSpaceMatIdentity[i]);
+}
+
+struct sti_mixer *sti_mixer_create(struct device *dev, int id,
+ void __iomem *baseaddr)
+{
+ struct sti_mixer *mixer = devm_kzalloc(dev, sizeof(*mixer), GFP_KERNEL);
+ struct device_node *np = dev->of_node;
+
+ dev_dbg(dev, "%s\n", __func__);
+ if (!mixer) {
+ DRM_ERROR("Failed to allocated memory for mixer\n");
+ return NULL;
+ }
+ mixer->regs = baseaddr;
+ mixer->dev = dev;
+ mixer->id = id;
+
+ if (of_device_is_compatible(np, "st,stih416-compositor"))
+ sti_mixer_set_matrix(mixer);
+
+ DRM_DEBUG_DRIVER("%s created. Regs=%p\n",
+ sti_mixer_to_str(mixer), mixer->regs);
+
+ return mixer;
+}
diff --git a/drivers/gpu/drm/sti/sti_mixer.h b/drivers/gpu/drm/sti/sti_mixer.h
new file mode 100644
index 000000000000..874372102e52
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_mixer.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_MIXER_H_
+#define _STI_MIXER_H_
+
+#include <drm/drmP.h>
+
+#include "sti_layer.h"
+
+#define to_sti_mixer(x) container_of(x, struct sti_mixer, drm_crtc)
+
+/**
+ * STI Mixer subdevice structure
+ *
+ * @dev: driver device
+ * @regs: mixer registers
+ * @id: id of the mixer
+ * @drm_crtc: crtc object link to the mixer
+ * @pending_event: set if a flip event is pending on crtc
+ */
+struct sti_mixer {
+ struct device *dev;
+ void __iomem *regs;
+ int id;
+ struct drm_crtc drm_crtc;
+ struct drm_pending_vblank_event *pending_event;
+};
+
+const char *sti_mixer_to_str(struct sti_mixer *mixer);
+
+struct sti_mixer *sti_mixer_create(struct device *dev, int id,
+ void __iomem *baseaddr);
+
+int sti_mixer_set_layer_status(struct sti_mixer *mixer,
+ struct sti_layer *layer, bool status);
+int sti_mixer_set_layer_depth(struct sti_mixer *mixer, struct sti_layer *layer);
+int sti_mixer_active_video_area(struct sti_mixer *mixer,
+ struct drm_display_mode *mode);
+
+void sti_mixer_set_background_status(struct sti_mixer *mixer, bool enable);
+
+/* depth in Cross-bar control = z order */
+#define GAM_MIXER_NB_DEPTH_LEVEL 7
+
+#define STI_MIXER_MAIN 0
+#define STI_MIXER_AUX 1
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
new file mode 100644
index 000000000000..b69e26fee76e
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Vincent Abriou <vincent.abriou@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+/* glue registers */
+#define TVO_CSC_MAIN_M0 0x000
+#define TVO_CSC_MAIN_M1 0x004
+#define TVO_CSC_MAIN_M2 0x008
+#define TVO_CSC_MAIN_M3 0x00c
+#define TVO_CSC_MAIN_M4 0x010
+#define TVO_CSC_MAIN_M5 0x014
+#define TVO_CSC_MAIN_M6 0x018
+#define TVO_CSC_MAIN_M7 0x01c
+#define TVO_MAIN_IN_VID_FORMAT 0x030
+#define TVO_CSC_AUX_M0 0x100
+#define TVO_CSC_AUX_M1 0x104
+#define TVO_CSC_AUX_M2 0x108
+#define TVO_CSC_AUX_M3 0x10c
+#define TVO_CSC_AUX_M4 0x110
+#define TVO_CSC_AUX_M5 0x114
+#define TVO_CSC_AUX_M6 0x118
+#define TVO_CSC_AUX_M7 0x11c
+#define TVO_AUX_IN_VID_FORMAT 0x130
+#define TVO_VIP_HDF 0x400
+#define TVO_HD_SYNC_SEL 0x418
+#define TVO_HD_DAC_CFG_OFF 0x420
+#define TVO_VIP_HDMI 0x500
+#define TVO_HDMI_FORCE_COLOR_0 0x504
+#define TVO_HDMI_FORCE_COLOR_1 0x508
+#define TVO_HDMI_CLIP_VALUE_B_CB 0x50c
+#define TVO_HDMI_CLIP_VALUE_Y_G 0x510
+#define TVO_HDMI_CLIP_VALUE_R_CR 0x514
+#define TVO_HDMI_SYNC_SEL 0x518
+#define TVO_HDMI_DFV_OBS 0x540
+
+#define TVO_IN_FMT_SIGNED BIT(0)
+#define TVO_SYNC_EXT BIT(4)
+
+#define TVO_VIP_REORDER_R_SHIFT 24
+#define TVO_VIP_REORDER_G_SHIFT 20
+#define TVO_VIP_REORDER_B_SHIFT 16
+#define TVO_VIP_REORDER_MASK 0x3
+#define TVO_VIP_REORDER_Y_G_SEL 0
+#define TVO_VIP_REORDER_CB_B_SEL 1
+#define TVO_VIP_REORDER_CR_R_SEL 2
+
+#define TVO_VIP_CLIP_SHIFT 8
+#define TVO_VIP_CLIP_MASK 0x7
+#define TVO_VIP_CLIP_DISABLED 0
+#define TVO_VIP_CLIP_EAV_SAV 1
+#define TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y 2
+#define TVO_VIP_CLIP_LIMITED_RANGE_CB_CR 3
+#define TVO_VIP_CLIP_PROG_RANGE 4
+
+#define TVO_VIP_RND_SHIFT 4
+#define TVO_VIP_RND_MASK 0x3
+#define TVO_VIP_RND_8BIT_ROUNDED 0
+#define TVO_VIP_RND_10BIT_ROUNDED 1
+#define TVO_VIP_RND_12BIT_ROUNDED 2
+
+#define TVO_VIP_SEL_INPUT_MASK 0xf
+#define TVO_VIP_SEL_INPUT_MAIN 0x0
+#define TVO_VIP_SEL_INPUT_AUX 0x8
+#define TVO_VIP_SEL_INPUT_FORCE_COLOR 0xf
+#define TVO_VIP_SEL_INPUT_BYPASS_MASK 0x1
+#define TVO_VIP_SEL_INPUT_BYPASSED 1
+
+#define TVO_SYNC_MAIN_VTG_SET_REF 0x00
+#define TVO_SYNC_MAIN_VTG_SET_1 0x01
+#define TVO_SYNC_MAIN_VTG_SET_2 0x02
+#define TVO_SYNC_MAIN_VTG_SET_3 0x03
+#define TVO_SYNC_MAIN_VTG_SET_4 0x04
+#define TVO_SYNC_MAIN_VTG_SET_5 0x05
+#define TVO_SYNC_MAIN_VTG_SET_6 0x06
+#define TVO_SYNC_AUX_VTG_SET_REF 0x10
+#define TVO_SYNC_AUX_VTG_SET_1 0x11
+#define TVO_SYNC_AUX_VTG_SET_2 0x12
+#define TVO_SYNC_AUX_VTG_SET_3 0x13
+#define TVO_SYNC_AUX_VTG_SET_4 0x14
+#define TVO_SYNC_AUX_VTG_SET_5 0x15
+#define TVO_SYNC_AUX_VTG_SET_6 0x16
+
+#define TVO_SYNC_HD_DCS_SHIFT 8
+
+#define ENCODER_MAIN_CRTC_MASK BIT(0)
+
+/* enum listing the supported output data format */
+enum sti_tvout_video_out_type {
+ STI_TVOUT_VIDEO_OUT_RGB,
+ STI_TVOUT_VIDEO_OUT_YUV,
+};
+
+struct sti_tvout {
+ struct device *dev;
+ struct drm_device *drm_dev;
+ void __iomem *regs;
+ struct reset_control *reset;
+ struct drm_encoder *hdmi;
+ struct drm_encoder *hda;
+};
+
+struct sti_tvout_encoder {
+ struct drm_encoder encoder;
+ struct sti_tvout *tvout;
+};
+
+#define to_sti_tvout_encoder(x) \
+ container_of(x, struct sti_tvout_encoder, encoder)
+
+#define to_sti_tvout(x) to_sti_tvout_encoder(x)->tvout
+
+/* preformatter conversion matrix */
+static const u32 rgb_to_ycbcr_601[8] = {
+ 0xF927082E, 0x04C9FEAB, 0x01D30964, 0xFA95FD3D,
+ 0x0000082E, 0x00002000, 0x00002000, 0x00000000
+};
+
+/* 709 RGB to YCbCr */
+static const u32 rgb_to_ycbcr_709[8] = {
+ 0xF891082F, 0x0367FF40, 0x01280B71, 0xF9B1FE20,
+ 0x0000082F, 0x00002000, 0x00002000, 0x00000000
+};
+
+static u32 tvout_read(struct sti_tvout *tvout, int offset)
+{
+ return readl(tvout->regs + offset);
+}
+
+static void tvout_write(struct sti_tvout *tvout, u32 val, int offset)
+{
+ writel(val, tvout->regs + offset);
+}
+
+/**
+ * Set the clipping mode of a VIP
+ *
+ * @tvout: tvout structure
+ * @cr_r:
+ * @y_g:
+ * @cb_b:
+ */
+static void tvout_vip_set_color_order(struct sti_tvout *tvout,
+ u32 cr_r, u32 y_g, u32 cb_b)
+{
+ u32 val = tvout_read(tvout, TVO_VIP_HDMI);
+
+ val &= ~(TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_R_SHIFT);
+ val &= ~(TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_G_SHIFT);
+ val &= ~(TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_B_SHIFT);
+ val |= cr_r << TVO_VIP_REORDER_R_SHIFT;
+ val |= y_g << TVO_VIP_REORDER_G_SHIFT;
+ val |= cb_b << TVO_VIP_REORDER_B_SHIFT;
+
+ tvout_write(tvout, val, TVO_VIP_HDMI);
+}
+
+/**
+ * Set the clipping mode of a VIP
+ *
+ * @tvout: tvout structure
+ * @range: clipping range
+ */
+static void tvout_vip_set_clip_mode(struct sti_tvout *tvout, u32 range)
+{
+ u32 val = tvout_read(tvout, TVO_VIP_HDMI);
+
+ val &= ~(TVO_VIP_CLIP_MASK << TVO_VIP_CLIP_SHIFT);
+ val |= range << TVO_VIP_CLIP_SHIFT;
+ tvout_write(tvout, val, TVO_VIP_HDMI);
+}
+
+/**
+ * Set the rounded value of a VIP
+ *
+ * @tvout: tvout structure
+ * @rnd: rounded val per component
+ */
+static void tvout_vip_set_rnd(struct sti_tvout *tvout, u32 rnd)
+{
+ u32 val = tvout_read(tvout, TVO_VIP_HDMI);
+
+ val &= ~(TVO_VIP_RND_MASK << TVO_VIP_RND_SHIFT);
+ val |= rnd << TVO_VIP_RND_SHIFT;
+ tvout_write(tvout, val, TVO_VIP_HDMI);
+}
+
+/**
+ * Select the VIP input
+ *
+ * @tvout: tvout structure
+ * @sel_input: selected_input (main/aux + conv)
+ */
+static void tvout_vip_set_sel_input(struct sti_tvout *tvout,
+ bool main_path,
+ bool sel_input_logic_inverted,
+ enum sti_tvout_video_out_type video_out)
+{
+ u32 sel_input;
+ u32 val = tvout_read(tvout, TVO_VIP_HDMI);
+
+ if (main_path)
+ sel_input = TVO_VIP_SEL_INPUT_MAIN;
+ else
+ sel_input = TVO_VIP_SEL_INPUT_AUX;
+
+ switch (video_out) {
+ case STI_TVOUT_VIDEO_OUT_RGB:
+ sel_input |= TVO_VIP_SEL_INPUT_BYPASSED;
+ break;
+ case STI_TVOUT_VIDEO_OUT_YUV:
+ sel_input &= ~TVO_VIP_SEL_INPUT_BYPASSED;
+ break;
+ }
+
+ /* on stih407 chip the sel_input bypass mode logic is inverted */
+ if (sel_input_logic_inverted)
+ sel_input = sel_input ^ TVO_VIP_SEL_INPUT_BYPASS_MASK;
+
+ val &= ~TVO_VIP_SEL_INPUT_MASK;
+ val |= sel_input;
+ tvout_write(tvout, val, TVO_VIP_HDMI);
+}
+
+/**
+ * Select the input video signed or unsigned
+ *
+ * @tvout: tvout structure
+ * @in_vid_signed: used video input format
+ */
+static void tvout_vip_set_in_vid_fmt(struct sti_tvout *tvout, u32 in_vid_fmt)
+{
+ u32 val = tvout_read(tvout, TVO_VIP_HDMI);
+
+ val &= ~TVO_IN_FMT_SIGNED;
+ val |= in_vid_fmt;
+ tvout_write(tvout, val, TVO_MAIN_IN_VID_FORMAT);
+}
+
+/**
+ * Start VIP block for HDMI output
+ *
+ * @tvout: pointer on tvout structure
+ * @main_path: true if main path has to be used in the vip configuration
+ * else aux path is used.
+ */
+static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
+{
+ struct device_node *node = tvout->dev->of_node;
+ bool sel_input_logic_inverted = false;
+
+ dev_dbg(tvout->dev, "%s\n", __func__);
+
+ if (main_path) {
+ DRM_DEBUG_DRIVER("main vip for hdmi\n");
+ /* select the input sync for hdmi = VTG set 1 */
+ tvout_write(tvout, TVO_SYNC_MAIN_VTG_SET_1, TVO_HDMI_SYNC_SEL);
+ } else {
+ DRM_DEBUG_DRIVER("aux vip for hdmi\n");
+ /* select the input sync for hdmi = VTG set 1 */
+ tvout_write(tvout, TVO_SYNC_AUX_VTG_SET_1, TVO_HDMI_SYNC_SEL);
+ }
+
+ /* set color channel order */
+ tvout_vip_set_color_order(tvout,
+ TVO_VIP_REORDER_CR_R_SEL,
+ TVO_VIP_REORDER_Y_G_SEL,
+ TVO_VIP_REORDER_CB_B_SEL);
+
+ /* set clipping mode (Limited range RGB/Y) */
+ tvout_vip_set_clip_mode(tvout, TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y);
+
+ /* set round mode (rounded to 8-bit per component) */
+ tvout_vip_set_rnd(tvout, TVO_VIP_RND_8BIT_ROUNDED);
+
+ if (of_device_is_compatible(node, "st,stih407-tvout")) {
+ /* set input video format */
+ tvout_vip_set_in_vid_fmt(tvout->regs + TVO_MAIN_IN_VID_FORMAT,
+ TVO_IN_FMT_SIGNED);
+ sel_input_logic_inverted = true;
+ }
+
+ /* input selection */
+ tvout_vip_set_sel_input(tvout, main_path,
+ sel_input_logic_inverted, STI_TVOUT_VIDEO_OUT_RGB);
+}
+
+/**
+ * Start HDF VIP and HD DAC
+ *
+ * @tvout: pointer on tvout structure
+ * @main_path: true if main path has to be used in the vip configuration
+ * else aux path is used.
+ */
+static void tvout_hda_start(struct sti_tvout *tvout, bool main_path)
+{
+ struct device_node *node = tvout->dev->of_node;
+ bool sel_input_logic_inverted = false;
+
+ dev_dbg(tvout->dev, "%s\n", __func__);
+
+ if (!main_path) {
+ DRM_ERROR("HD Analog on aux not implemented\n");
+ return;
+ }
+
+ DRM_DEBUG_DRIVER("main vip for HDF\n");
+
+ /* set color channel order */
+ tvout_vip_set_color_order(tvout->regs + TVO_VIP_HDF,
+ TVO_VIP_REORDER_CR_R_SEL,
+ TVO_VIP_REORDER_Y_G_SEL,
+ TVO_VIP_REORDER_CB_B_SEL);
+
+ /* set clipping mode (Limited range RGB/Y) */
+ tvout_vip_set_clip_mode(tvout->regs + TVO_VIP_HDF,
+ TVO_VIP_CLIP_LIMITED_RANGE_CB_CR);
+
+ /* set round mode (rounded to 10-bit per component) */
+ tvout_vip_set_rnd(tvout->regs + TVO_VIP_HDF, TVO_VIP_RND_10BIT_ROUNDED);
+
+ if (of_device_is_compatible(node, "st,stih407-tvout")) {
+ /* set input video format */
+ tvout_vip_set_in_vid_fmt(tvout, TVO_IN_FMT_SIGNED);
+ sel_input_logic_inverted = true;
+ }
+
+ /* Input selection */
+ tvout_vip_set_sel_input(tvout->regs + TVO_VIP_HDF,
+ main_path,
+ sel_input_logic_inverted,
+ STI_TVOUT_VIDEO_OUT_YUV);
+
+ /* select the input sync for HD analog = VTG set 3
+ * and HD DCS = VTG set 2 */
+ tvout_write(tvout,
+ (TVO_SYNC_MAIN_VTG_SET_2 << TVO_SYNC_HD_DCS_SHIFT)
+ | TVO_SYNC_MAIN_VTG_SET_3,
+ TVO_HD_SYNC_SEL);
+
+ /* power up HD DAC */
+ tvout_write(tvout, 0, TVO_HD_DAC_CFG_OFF);
+}
+
+static void sti_tvout_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool sti_tvout_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void sti_tvout_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void sti_tvout_encoder_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void sti_tvout_encoder_destroy(struct drm_encoder *encoder)
+{
+ struct sti_tvout_encoder *sti_encoder = to_sti_tvout_encoder(encoder);
+
+ drm_encoder_cleanup(encoder);
+ kfree(sti_encoder);
+}
+
+static const struct drm_encoder_funcs sti_tvout_encoder_funcs = {
+ .destroy = sti_tvout_encoder_destroy,
+};
+
+static void sti_hda_encoder_commit(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ tvout_hda_start(tvout, true);
+}
+
+static void sti_hda_encoder_disable(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ /* reset VIP register */
+ tvout_write(tvout, 0x0, TVO_VIP_HDF);
+
+ /* power down HD DAC */
+ tvout_write(tvout, 1, TVO_HD_DAC_CFG_OFF);
+}
+
+static const struct drm_encoder_helper_funcs sti_hda_encoder_helper_funcs = {
+ .dpms = sti_tvout_encoder_dpms,
+ .mode_fixup = sti_tvout_encoder_mode_fixup,
+ .mode_set = sti_tvout_encoder_mode_set,
+ .prepare = sti_tvout_encoder_prepare,
+ .commit = sti_hda_encoder_commit,
+ .disable = sti_hda_encoder_disable,
+};
+
+static struct drm_encoder *sti_tvout_create_hda_encoder(struct drm_device *dev,
+ struct sti_tvout *tvout)
+{
+ struct sti_tvout_encoder *encoder;
+ struct drm_encoder *drm_encoder;
+
+ encoder = devm_kzalloc(tvout->dev, sizeof(*encoder), GFP_KERNEL);
+ if (!encoder)
+ return NULL;
+
+ encoder->tvout = tvout;
+
+ drm_encoder = (struct drm_encoder *) encoder;
+
+ drm_encoder->possible_crtcs = ENCODER_MAIN_CRTC_MASK;
+ drm_encoder->possible_clones = 1 << 0;
+
+ drm_encoder_init(dev, drm_encoder,
+ &sti_tvout_encoder_funcs, DRM_MODE_ENCODER_DAC);
+
+ drm_encoder_helper_add(drm_encoder, &sti_hda_encoder_helper_funcs);
+
+ return drm_encoder;
+}
+
+static void sti_hdmi_encoder_commit(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ tvout_hdmi_start(tvout, true);
+}
+
+static void sti_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+ struct sti_tvout *tvout = to_sti_tvout(encoder);
+
+ /* reset VIP register */
+ tvout_write(tvout, 0x0, TVO_VIP_HDMI);
+}
+
+static const struct drm_encoder_helper_funcs sti_hdmi_encoder_helper_funcs = {
+ .dpms = sti_tvout_encoder_dpms,
+ .mode_fixup = sti_tvout_encoder_mode_fixup,
+ .mode_set = sti_tvout_encoder_mode_set,
+ .prepare = sti_tvout_encoder_prepare,
+ .commit = sti_hdmi_encoder_commit,
+ .disable = sti_hdmi_encoder_disable,
+};
+
+static struct drm_encoder *sti_tvout_create_hdmi_encoder(struct drm_device *dev,
+ struct sti_tvout *tvout)
+{
+ struct sti_tvout_encoder *encoder;
+ struct drm_encoder *drm_encoder;
+
+ encoder = devm_kzalloc(tvout->dev, sizeof(*encoder), GFP_KERNEL);
+ if (!encoder)
+ return NULL;
+
+ encoder->tvout = tvout;
+
+ drm_encoder = (struct drm_encoder *) encoder;
+
+ drm_encoder->possible_crtcs = ENCODER_MAIN_CRTC_MASK;
+ drm_encoder->possible_clones = 1 << 1;
+
+ drm_encoder_init(dev, drm_encoder,
+ &sti_tvout_encoder_funcs, DRM_MODE_ENCODER_TMDS);
+
+ drm_encoder_helper_add(drm_encoder, &sti_hdmi_encoder_helper_funcs);
+
+ return drm_encoder;
+}
+
+static void sti_tvout_create_encoders(struct drm_device *dev,
+ struct sti_tvout *tvout)
+{
+ tvout->hdmi = sti_tvout_create_hdmi_encoder(dev, tvout);
+ tvout->hda = sti_tvout_create_hda_encoder(dev, tvout);
+}
+
+static void sti_tvout_destroy_encoders(struct sti_tvout *tvout)
+{
+ if (tvout->hdmi)
+ drm_encoder_cleanup(tvout->hdmi);
+ tvout->hdmi = NULL;
+
+ if (tvout->hda)
+ drm_encoder_cleanup(tvout->hda);
+ tvout->hda = NULL;
+}
+
+static int sti_tvout_bind(struct device *dev, struct device *master, void *data)
+{
+ struct sti_tvout *tvout = dev_get_drvdata(dev);
+ struct drm_device *drm_dev = data;
+ unsigned int i;
+ int ret;
+
+ tvout->drm_dev = drm_dev;
+
+ /* set preformatter matrix */
+ for (i = 0; i < 8; i++) {
+ tvout_write(tvout, rgb_to_ycbcr_601[i],
+ TVO_CSC_MAIN_M0 + (i * 4));
+ tvout_write(tvout, rgb_to_ycbcr_601[i],
+ TVO_CSC_AUX_M0 + (i * 4));
+ }
+
+ sti_tvout_create_encoders(drm_dev, tvout);
+
+ ret = component_bind_all(dev, drm_dev);
+ if (ret)
+ sti_tvout_destroy_encoders(tvout);
+
+ return ret;
+}
+
+static void sti_tvout_unbind(struct device *dev, struct device *master,
+ void *data)
+{
+ /* do nothing */
+}
+
+static const struct component_ops sti_tvout_ops = {
+ .bind = sti_tvout_bind,
+ .unbind = sti_tvout_unbind,
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+static int sti_tvout_master_bind(struct device *dev)
+{
+ return 0;
+}
+
+static void sti_tvout_master_unbind(struct device *dev)
+{
+ /* do nothing */
+}
+
+static const struct component_master_ops sti_tvout_master_ops = {
+ .bind = sti_tvout_master_bind,
+ .unbind = sti_tvout_master_unbind,
+};
+
+static int sti_tvout_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct sti_tvout *tvout;
+ struct resource *res;
+ struct device_node *child_np;
+ struct component_match *match = NULL;
+
+ DRM_INFO("%s\n", __func__);
+
+ if (!node)
+ return -ENODEV;
+
+ tvout = devm_kzalloc(dev, sizeof(*tvout), GFP_KERNEL);
+ if (!tvout)
+ return -ENOMEM;
+
+ tvout->dev = dev;
+
+ /* get Memory ressources */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tvout-reg");
+ if (!res) {
+ DRM_ERROR("Invalid glue resource\n");
+ return -ENOMEM;
+ }
+ tvout->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+ if (IS_ERR(tvout->regs))
+ return PTR_ERR(tvout->regs);
+
+ /* get reset resources */
+ tvout->reset = devm_reset_control_get(dev, "tvout");
+ /* take tvout out of reset */
+ if (!IS_ERR(tvout->reset))
+ reset_control_deassert(tvout->reset);
+
+ platform_set_drvdata(pdev, tvout);
+
+ of_platform_populate(node, NULL, NULL, dev);
+
+ child_np = of_get_next_available_child(node, NULL);
+
+ while (child_np) {
+ component_match_add(dev, &match, compare_of, child_np);
+ of_node_put(child_np);
+ child_np = of_get_next_available_child(node, child_np);
+ }
+
+ component_master_add_with_match(dev, &sti_tvout_master_ops, match);
+
+ return component_add(dev, &sti_tvout_ops);
+}
+
+static int sti_tvout_remove(struct platform_device *pdev)
+{
+ component_master_del(&pdev->dev, &sti_tvout_master_ops);
+ component_del(&pdev->dev, &sti_tvout_ops);
+ return 0;
+}
+
+static struct of_device_id tvout_of_match[] = {
+ { .compatible = "st,stih416-tvout", },
+ { .compatible = "st,stih407-tvout", },
+ { /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, tvout_of_match);
+
+struct platform_driver sti_tvout_driver = {
+ .driver = {
+ .name = "sti-tvout",
+ .owner = THIS_MODULE,
+ .of_match_table = tvout_of_match,
+ },
+ .probe = sti_tvout_probe,
+ .remove = sti_tvout_remove,
+};
+
+module_platform_driver(sti_tvout_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c
new file mode 100644
index 000000000000..10ced6a479f4
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vid.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <drm/drmP.h>
+
+#include "sti_layer.h"
+#include "sti_vid.h"
+#include "sti_vtg.h"
+
+/* Registers */
+#define VID_CTL 0x00
+#define VID_ALP 0x04
+#define VID_CLF 0x08
+#define VID_VPO 0x0C
+#define VID_VPS 0x10
+#define VID_KEY1 0x28
+#define VID_KEY2 0x2C
+#define VID_MPR0 0x30
+#define VID_MPR1 0x34
+#define VID_MPR2 0x38
+#define VID_MPR3 0x3C
+#define VID_MST 0x68
+#define VID_BC 0x70
+#define VID_TINT 0x74
+#define VID_CSAT 0x78
+
+/* Registers values */
+#define VID_CTL_IGNORE (BIT(31) | BIT(30))
+#define VID_CTL_PSI_ENABLE (BIT(2) | BIT(1) | BIT(0))
+#define VID_ALP_OPAQUE 0x00000080
+#define VID_BC_DFLT 0x00008000
+#define VID_TINT_DFLT 0x00000000
+#define VID_CSAT_DFLT 0x00000080
+/* YCbCr to RGB BT709:
+ * R = Y+1.5391Cr
+ * G = Y-0.4590Cr-0.1826Cb
+ * B = Y+1.8125Cb */
+#define VID_MPR0_BT709 0x0A800000
+#define VID_MPR1_BT709 0x0AC50000
+#define VID_MPR2_BT709 0x07150545
+#define VID_MPR3_BT709 0x00000AE8
+
+static int sti_vid_prepare_layer(struct sti_layer *vid, bool first_prepare)
+{
+ u32 val;
+
+ /* Unmask */
+ val = readl(vid->regs + VID_CTL);
+ val &= ~VID_CTL_IGNORE;
+ writel(val, vid->regs + VID_CTL);
+
+ return 0;
+}
+
+static int sti_vid_commit_layer(struct sti_layer *vid)
+{
+ struct drm_display_mode *mode = vid->mode;
+ u32 ydo, xdo, yds, xds;
+
+ ydo = sti_vtg_get_line_number(*mode, vid->dst_y);
+ yds = sti_vtg_get_line_number(*mode, vid->dst_y + vid->dst_h - 1);
+ xdo = sti_vtg_get_pixel_number(*mode, vid->dst_x);
+ xds = sti_vtg_get_pixel_number(*mode, vid->dst_x + vid->dst_w - 1);
+
+ writel((ydo << 16) | xdo, vid->regs + VID_VPO);
+ writel((yds << 16) | xds, vid->regs + VID_VPS);
+
+ return 0;
+}
+
+static int sti_vid_disable_layer(struct sti_layer *vid)
+{
+ u32 val;
+
+ /* Mask */
+ val = readl(vid->regs + VID_CTL);
+ val |= VID_CTL_IGNORE;
+ writel(val, vid->regs + VID_CTL);
+
+ return 0;
+}
+
+static const uint32_t *sti_vid_get_formats(struct sti_layer *layer)
+{
+ return NULL;
+}
+
+static unsigned int sti_vid_get_nb_formats(struct sti_layer *layer)
+{
+ return 0;
+}
+
+static void sti_vid_init(struct sti_layer *vid)
+{
+ /* Enable PSI, Mask layer */
+ writel(VID_CTL_PSI_ENABLE | VID_CTL_IGNORE, vid->regs + VID_CTL);
+
+ /* Opaque */
+ writel(VID_ALP_OPAQUE, vid->regs + VID_ALP);
+
+ /* Color conversion parameters */
+ writel(VID_MPR0_BT709, vid->regs + VID_MPR0);
+ writel(VID_MPR1_BT709, vid->regs + VID_MPR1);
+ writel(VID_MPR2_BT709, vid->regs + VID_MPR2);
+ writel(VID_MPR3_BT709, vid->regs + VID_MPR3);
+
+ /* Brightness, contrast, tint, saturation */
+ writel(VID_BC_DFLT, vid->regs + VID_BC);
+ writel(VID_TINT_DFLT, vid->regs + VID_TINT);
+ writel(VID_CSAT_DFLT, vid->regs + VID_CSAT);
+}
+
+static const struct sti_layer_funcs vid_ops = {
+ .get_formats = sti_vid_get_formats,
+ .get_nb_formats = sti_vid_get_nb_formats,
+ .init = sti_vid_init,
+ .prepare = sti_vid_prepare_layer,
+ .commit = sti_vid_commit_layer,
+ .disable = sti_vid_disable_layer,
+};
+
+struct sti_layer *sti_vid_create(struct device *dev)
+{
+ struct sti_layer *vid;
+
+ vid = devm_kzalloc(dev, sizeof(*vid), GFP_KERNEL);
+ if (!vid) {
+ DRM_ERROR("Failed to allocate memory for VID\n");
+ return NULL;
+ }
+
+ vid->ops = &vid_ops;
+
+ return vid;
+}
diff --git a/drivers/gpu/drm/sti/sti_vid.h b/drivers/gpu/drm/sti/sti_vid.h
new file mode 100644
index 000000000000..2c0aecd63294
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vid.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_VID_H_
+#define _STI_VID_H_
+
+struct sti_layer *sti_vid_create(struct device *dev);
+
+#endif
diff --git a/drivers/gpu/drm/sti/sti_vtac.c b/drivers/gpu/drm/sti/sti_vtac.c
new file mode 100644
index 000000000000..82a51d488434
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vtac.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <drm/drmP.h>
+
+/* registers offset */
+#define VTAC_CONFIG 0x00
+#define VTAC_RX_FIFO_CONFIG 0x04
+#define VTAC_FIFO_CONFIG_VAL 0x04
+
+#define VTAC_SYS_CFG8521 0x824
+#define VTAC_SYS_CFG8522 0x828
+
+/* Number of phyts per pixel */
+#define VTAC_2_5_PPP 0x0005
+#define VTAC_3_PPP 0x0006
+#define VTAC_4_PPP 0x0008
+#define VTAC_5_PPP 0x000A
+#define VTAC_6_PPP 0x000C
+#define VTAC_13_PPP 0x001A
+#define VTAC_14_PPP 0x001C
+#define VTAC_15_PPP 0x001E
+#define VTAC_16_PPP 0x0020
+#define VTAC_17_PPP 0x0022
+#define VTAC_18_PPP 0x0024
+
+/* enable bits */
+#define VTAC_ENABLE 0x3003
+
+#define VTAC_TX_PHY_ENABLE_CLK_PHY BIT(0)
+#define VTAC_TX_PHY_ENABLE_CLK_DLL BIT(1)
+#define VTAC_TX_PHY_PLL_NOT_OSC_MODE BIT(3)
+#define VTAC_TX_PHY_RST_N_DLL_SWITCH BIT(4)
+#define VTAC_TX_PHY_PROG_N3 BIT(9)
+
+
+/**
+ * VTAC mode structure
+ *
+ * @vid_in_width: Video Data Resolution
+ * @phyts_width: Width of phyt buses(phyt low and phyt high).
+ * @phyts_per_pixel: Number of phyts sent per pixel
+ */
+struct sti_vtac_mode {
+ u32 vid_in_width;
+ u32 phyts_width;
+ u32 phyts_per_pixel;
+};
+
+static const struct sti_vtac_mode vtac_mode_main = {0x2, 0x2, VTAC_5_PPP};
+static const struct sti_vtac_mode vtac_mode_aux = {0x1, 0x0, VTAC_17_PPP};
+
+/**
+ * VTAC structure
+ *
+ * @dev: pointer to device structure
+ * @regs: ioremapped registers for RX and TX devices
+ * @phy_regs: phy registers for TX device
+ * @clk: clock
+ * @mode: main or auxillary configuration mode
+ */
+struct sti_vtac {
+ struct device *dev;
+ void __iomem *regs;
+ void __iomem *phy_regs;
+ struct clk *clk;
+ const struct sti_vtac_mode *mode;
+};
+
+static void sti_vtac_rx_set_config(struct sti_vtac *vtac)
+{
+ u32 config;
+
+ /* Enable VTAC clock */
+ if (clk_prepare_enable(vtac->clk))
+ DRM_ERROR("Failed to prepare/enable vtac_rx clock.\n");
+
+ writel(VTAC_FIFO_CONFIG_VAL, vtac->regs + VTAC_RX_FIFO_CONFIG);
+
+ config = VTAC_ENABLE;
+ config |= vtac->mode->vid_in_width << 4;
+ config |= vtac->mode->phyts_width << 16;
+ config |= vtac->mode->phyts_per_pixel << 23;
+ writel(config, vtac->regs + VTAC_CONFIG);
+}
+
+static void sti_vtac_tx_set_config(struct sti_vtac *vtac)
+{
+ u32 phy_config;
+ u32 config;
+
+ /* Enable VTAC clock */
+ if (clk_prepare_enable(vtac->clk))
+ DRM_ERROR("Failed to prepare/enable vtac_tx clock.\n");
+
+ /* Configure vtac phy */
+ phy_config = 0x00000000;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8522);
+ phy_config = VTAC_TX_PHY_ENABLE_CLK_PHY;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config |= VTAC_TX_PHY_PROG_N3;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config |= VTAC_TX_PHY_ENABLE_CLK_DLL;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config |= VTAC_TX_PHY_RST_N_DLL_SWITCH;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config = readl(vtac->phy_regs + VTAC_SYS_CFG8521);
+ phy_config |= VTAC_TX_PHY_PLL_NOT_OSC_MODE;
+ writel(phy_config, vtac->phy_regs + VTAC_SYS_CFG8521);
+
+ /* Configure vtac tx */
+ config = VTAC_ENABLE;
+ config |= vtac->mode->vid_in_width << 4;
+ config |= vtac->mode->phyts_width << 16;
+ config |= vtac->mode->phyts_per_pixel << 23;
+ writel(config, vtac->regs + VTAC_CONFIG);
+}
+
+static const struct of_device_id vtac_of_match[] = {
+ {
+ .compatible = "st,vtac-main",
+ .data = &vtac_mode_main,
+ }, {
+ .compatible = "st,vtac-aux",
+ .data = &vtac_mode_aux,
+ }, {
+ /* end node */
+ }
+};
+MODULE_DEVICE_TABLE(of, vtac_of_match);
+
+static int sti_vtac_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ const struct of_device_id *id;
+ struct sti_vtac *vtac;
+ struct resource *res;
+
+ vtac = devm_kzalloc(dev, sizeof(*vtac), GFP_KERNEL);
+ if (!vtac)
+ return -ENOMEM;
+
+ vtac->dev = dev;
+
+ id = of_match_node(vtac_of_match, np);
+ if (!id)
+ return -ENOMEM;
+
+ vtac->mode = id->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ DRM_ERROR("Invalid resource\n");
+ return -ENOMEM;
+ }
+ vtac->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(vtac->regs))
+ return PTR_ERR(vtac->regs);
+
+
+ vtac->clk = devm_clk_get(dev, "vtac");
+ if (IS_ERR(vtac->clk)) {
+ DRM_ERROR("Cannot get vtac clock\n");
+ return PTR_ERR(vtac->clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res) {
+ vtac->phy_regs = devm_ioremap_nocache(dev, res->start,
+ resource_size(res));
+ sti_vtac_tx_set_config(vtac);
+ } else {
+
+ sti_vtac_rx_set_config(vtac);
+ }
+
+ platform_set_drvdata(pdev, vtac);
+ DRM_INFO("%s %s\n", __func__, dev_name(vtac->dev));
+
+ return 0;
+}
+
+static int sti_vtac_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+struct platform_driver sti_vtac_driver = {
+ .driver = {
+ .name = "sti-vtac",
+ .owner = THIS_MODULE,
+ .of_match_table = vtac_of_match,
+ },
+ .probe = sti_vtac_probe,
+ .remove = sti_vtac_remove,
+};
+
+module_platform_driver(sti_vtac_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c
new file mode 100644
index 000000000000..740d6e347a62
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vtg.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
+ * Fabien Dessenne <fabien.dessenne@st.com>
+ * Vincent Abriou <vincent.abriou@st.com>
+ * for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+
+#include <drm/drmP.h>
+
+#include "sti_vtg.h"
+
+#define VTG_TYPE_MASTER 0
+#define VTG_TYPE_SLAVE_BY_EXT0 1
+
+/* registers offset */
+#define VTG_MODE 0x0000
+#define VTG_CLKLN 0x0008
+#define VTG_HLFLN 0x000C
+#define VTG_DRST_AUTOC 0x0010
+#define VTG_VID_TFO 0x0040
+#define VTG_VID_TFS 0x0044
+#define VTG_VID_BFO 0x0048
+#define VTG_VID_BFS 0x004C
+
+#define VTG_HOST_ITS 0x0078
+#define VTG_HOST_ITS_BCLR 0x007C
+#define VTG_HOST_ITM_BCLR 0x0088
+#define VTG_HOST_ITM_BSET 0x008C
+
+#define VTG_H_HD_1 0x00C0
+#define VTG_TOP_V_VD_1 0x00C4
+#define VTG_BOT_V_VD_1 0x00C8
+#define VTG_TOP_V_HD_1 0x00CC
+#define VTG_BOT_V_HD_1 0x00D0
+
+#define VTG_H_HD_2 0x00E0
+#define VTG_TOP_V_VD_2 0x00E4
+#define VTG_BOT_V_VD_2 0x00E8
+#define VTG_TOP_V_HD_2 0x00EC
+#define VTG_BOT_V_HD_2 0x00F0
+
+#define VTG_H_HD_3 0x0100
+#define VTG_TOP_V_VD_3 0x0104
+#define VTG_BOT_V_VD_3 0x0108
+#define VTG_TOP_V_HD_3 0x010C
+#define VTG_BOT_V_HD_3 0x0110
+
+#define VTG_IRQ_BOTTOM BIT(0)
+#define VTG_IRQ_TOP BIT(1)
+#define VTG_IRQ_MASK (VTG_IRQ_TOP | VTG_IRQ_BOTTOM)
+
+/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */
+#define AWG_DELAY_HD (-9)
+#define AWG_DELAY_ED (-8)
+#define AWG_DELAY_SD (-7)
+
+LIST_HEAD(vtg_lookup);
+
+/**
+ * STI VTG structure
+ *
+ * @dev: pointer to device driver
+ * @data: data associated to the device
+ * @irq: VTG irq
+ * @type: VTG type (main or aux)
+ * @notifier_list: notifier callback
+ * @crtc_id: the crtc id for vblank event
+ * @slave: slave vtg
+ * @link: List node to link the structure in lookup list
+ */
+struct sti_vtg {
+ struct device *dev;
+ struct device_node *np;
+ void __iomem *regs;
+ int irq;
+ u32 irq_status;
+ struct raw_notifier_head notifier_list;
+ int crtc_id;
+ struct sti_vtg *slave;
+ struct list_head link;
+};
+
+static void vtg_register(struct sti_vtg *vtg)
+{
+ list_add_tail(&vtg->link, &vtg_lookup);
+}
+
+struct sti_vtg *of_vtg_find(struct device_node *np)
+{
+ struct sti_vtg *vtg;
+
+ list_for_each_entry(vtg, &vtg_lookup, link) {
+ if (vtg->np == np)
+ return vtg;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_vtg_find);
+
+static void vtg_reset(struct sti_vtg *vtg)
+{
+ /* reset slave and then master */
+ if (vtg->slave)
+ vtg_reset(vtg->slave);
+
+ writel(1, vtg->regs + VTG_DRST_AUTOC);
+}
+
+static void vtg_set_mode(struct sti_vtg *vtg,
+ int type, const struct drm_display_mode *mode)
+{
+ u32 tmp;
+
+ if (vtg->slave)
+ vtg_set_mode(vtg->slave, VTG_TYPE_SLAVE_BY_EXT0, mode);
+
+ writel(mode->htotal, vtg->regs + VTG_CLKLN);
+ writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN);
+
+ tmp = (mode->vtotal - mode->vsync_start + 1) << 16;
+ tmp |= mode->htotal - mode->hsync_start;
+ writel(tmp, vtg->regs + VTG_VID_TFO);
+ writel(tmp, vtg->regs + VTG_VID_BFO);
+
+ tmp = (mode->vdisplay + mode->vtotal - mode->vsync_start + 1) << 16;
+ tmp |= mode->hdisplay + mode->htotal - mode->hsync_start;
+ writel(tmp, vtg->regs + VTG_VID_TFS);
+ writel(tmp, vtg->regs + VTG_VID_BFS);
+
+ /* prepare VTG set 1 and 2 for HDMI and VTG set 3 for HD DAC */
+ tmp = (mode->hsync_end - mode->hsync_start) << 16;
+ writel(tmp, vtg->regs + VTG_H_HD_1);
+ writel(tmp, vtg->regs + VTG_H_HD_2);
+
+ tmp = (mode->vsync_end - mode->vsync_start + 1) << 16;
+ tmp |= 1;
+ writel(tmp, vtg->regs + VTG_TOP_V_VD_1);
+ writel(tmp, vtg->regs + VTG_BOT_V_VD_1);
+ writel(0, vtg->regs + VTG_TOP_V_HD_1);
+ writel(0, vtg->regs + VTG_BOT_V_HD_1);
+
+ /* prepare VTG set 2 for for HD DCS */
+ writel(tmp, vtg->regs + VTG_TOP_V_VD_2);
+ writel(tmp, vtg->regs + VTG_BOT_V_VD_2);
+ writel(0, vtg->regs + VTG_TOP_V_HD_2);
+ writel(0, vtg->regs + VTG_BOT_V_HD_2);
+
+ /* prepare VTG set 3 for HD Analog in HD mode */
+ tmp = (mode->hsync_end - mode->hsync_start + AWG_DELAY_HD) << 16;
+ tmp |= mode->htotal + AWG_DELAY_HD;
+ writel(tmp, vtg->regs + VTG_H_HD_3);
+
+ tmp = (mode->vsync_end - mode->vsync_start) << 16;
+ tmp |= mode->vtotal;
+ writel(tmp, vtg->regs + VTG_TOP_V_VD_3);
+ writel(tmp, vtg->regs + VTG_BOT_V_VD_3);
+
+ tmp = (mode->htotal + AWG_DELAY_HD) << 16;
+ tmp |= mode->htotal + AWG_DELAY_HD;
+ writel(tmp, vtg->regs + VTG_TOP_V_HD_3);
+ writel(tmp, vtg->regs + VTG_BOT_V_HD_3);
+
+ /* mode */
+ writel(type, vtg->regs + VTG_MODE);
+}
+
+static void vtg_enable_irq(struct sti_vtg *vtg)
+{
+ /* clear interrupt status and mask */
+ writel(0xFFFF, vtg->regs + VTG_HOST_ITS_BCLR);
+ writel(0xFFFF, vtg->regs + VTG_HOST_ITM_BCLR);
+ writel(VTG_IRQ_MASK, vtg->regs + VTG_HOST_ITM_BSET);
+}
+
+void sti_vtg_set_config(struct sti_vtg *vtg,
+ const struct drm_display_mode *mode)
+{
+ /* write configuration */
+ vtg_set_mode(vtg, VTG_TYPE_MASTER, mode);
+
+ vtg_reset(vtg);
+
+ /* enable irq for the vtg vblank synchro */
+ if (vtg->slave)
+ vtg_enable_irq(vtg->slave);
+ else
+ vtg_enable_irq(vtg);
+}
+EXPORT_SYMBOL(sti_vtg_set_config);
+
+/**
+ * sti_vtg_get_line_number
+ *
+ * @mode: display mode to be used
+ * @y: line
+ *
+ * Return the line number according to the display mode taking
+ * into account the Sync and Back Porch information.
+ * Video frame line numbers start at 1, y starts at 0.
+ * In interlaced modes the start line is the field line number of the odd
+ * field, but y is still defined as a progressive frame.
+ */
+u32 sti_vtg_get_line_number(struct drm_display_mode mode, int y)
+{
+ u32 start_line = mode.vtotal - mode.vsync_start + 1;
+
+ if (mode.flags & DRM_MODE_FLAG_INTERLACE)
+ start_line *= 2;
+
+ return start_line + y;
+}
+EXPORT_SYMBOL(sti_vtg_get_line_number);
+
+/**
+ * sti_vtg_get_pixel_number
+ *
+ * @mode: display mode to be used
+ * @x: row
+ *
+ * Return the pixel number according to the display mode taking
+ * into account the Sync and Back Porch information.
+ * Pixels are counted from 0.
+ */
+u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x)
+{
+ return mode.htotal - mode.hsync_start + x;
+}
+EXPORT_SYMBOL(sti_vtg_get_pixel_number);
+
+int sti_vtg_register_client(struct sti_vtg *vtg,
+ struct notifier_block *nb, int crtc_id)
+{
+ if (vtg->slave)
+ return sti_vtg_register_client(vtg->slave, nb, crtc_id);
+
+ vtg->crtc_id = crtc_id;
+ return raw_notifier_chain_register(&vtg->notifier_list, nb);
+}
+EXPORT_SYMBOL(sti_vtg_register_client);
+
+int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
+{
+ if (vtg->slave)
+ return sti_vtg_unregister_client(vtg->slave, nb);
+
+ return raw_notifier_chain_unregister(&vtg->notifier_list, nb);
+}
+EXPORT_SYMBOL(sti_vtg_unregister_client);
+
+static irqreturn_t vtg_irq_thread(int irq, void *arg)
+{
+ struct sti_vtg *vtg = arg;
+ u32 event;
+
+ event = (vtg->irq_status & VTG_IRQ_TOP) ?
+ VTG_TOP_FIELD_EVENT : VTG_BOTTOM_FIELD_EVENT;
+
+ raw_notifier_call_chain(&vtg->notifier_list, event, &vtg->crtc_id);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t vtg_irq(int irq, void *arg)
+{
+ struct sti_vtg *vtg = arg;
+
+ vtg->irq_status = readl(vtg->regs + VTG_HOST_ITS);
+
+ writel(vtg->irq_status, vtg->regs + VTG_HOST_ITS_BCLR);
+
+ /* force sync bus write */
+ readl(vtg->regs + VTG_HOST_ITS);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static int vtg_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np;
+ struct sti_vtg *vtg;
+ struct resource *res;
+ char irq_name[32];
+ int ret;
+
+ vtg = devm_kzalloc(dev, sizeof(*vtg), GFP_KERNEL);
+ if (!vtg)
+ return -ENOMEM;
+
+ vtg->dev = dev;
+ vtg->np = pdev->dev.of_node;
+
+ /* Get Memory ressources */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ DRM_ERROR("Get memory resource failed\n");
+ return -ENOMEM;
+ }
+ vtg->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+
+ np = of_parse_phandle(pdev->dev.of_node, "st,slave", 0);
+ if (np) {
+ vtg->slave = of_vtg_find(np);
+
+ if (!vtg->slave)
+ return -EPROBE_DEFER;
+ } else {
+ vtg->irq = platform_get_irq(pdev, 0);
+ if (IS_ERR_VALUE(vtg->irq)) {
+ DRM_ERROR("Failed to get VTG interrupt\n");
+ return vtg->irq;
+ }
+
+ snprintf(irq_name, sizeof(irq_name), "vsync-%s",
+ dev_name(vtg->dev));
+
+ RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list);
+
+ ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq,
+ vtg_irq_thread, IRQF_ONESHOT, irq_name, vtg);
+ if (IS_ERR_VALUE(ret)) {
+ DRM_ERROR("Failed to register VTG interrupt\n");
+ return ret;
+ }
+ }
+
+ vtg_register(vtg);
+ platform_set_drvdata(pdev, vtg);
+
+ DRM_INFO("%s %s\n", __func__, dev_name(vtg->dev));
+
+ return 0;
+}
+
+static int vtg_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id vtg_of_match[] = {
+ { .compatible = "st,vtg", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vtg_of_match);
+
+struct platform_driver sti_vtg_driver = {
+ .driver = {
+ .name = "sti-vtg",
+ .owner = THIS_MODULE,
+ .of_match_table = vtg_of_match,
+ },
+ .probe = vtg_probe,
+ .remove = vtg_remove,
+};
+
+module_platform_driver(sti_vtg_driver);
+
+MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/sti/sti_vtg.h b/drivers/gpu/drm/sti/sti_vtg.h
new file mode 100644
index 000000000000..e84d23f1f57f
--- /dev/null
+++ b/drivers/gpu/drm/sti/sti_vtg.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2014
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _STI_VTG_H_
+#define _STI_VTG_H_
+
+#define VTG_TOP_FIELD_EVENT 1
+#define VTG_BOTTOM_FIELD_EVENT 2
+
+struct sti_vtg;
+struct drm_display_mode;
+struct notifier_block;
+
+struct sti_vtg *of_vtg_find(struct device_node *np);
+void sti_vtg_set_config(struct sti_vtg *vtg,
+ const struct drm_display_mode *mode);
+int sti_vtg_register_client(struct sti_vtg *vtg,
+ struct notifier_block *nb, int crtc_id);
+int sti_vtg_unregister_client(struct sti_vtg *vtg,
+ struct notifier_block *nb);
+
+u32 sti_vtg_get_line_number(struct drm_display_mode mode, int y);
+u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x);
+
+#endif
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ef40381f3909..6553fd238685 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -18,6 +18,8 @@
struct tegra_dc_soc_info {
bool supports_interlacing;
bool supports_cursor;
+ bool supports_block_linear;
+ unsigned int pitch_align;
};
struct tegra_plane {
@@ -212,15 +214,44 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
- if (window->tiled) {
- value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
- DC_WIN_BUFFER_ADDR_MODE_TILE;
+ if (dc->soc->supports_block_linear) {
+ unsigned long height = window->tiling.value;
+
+ switch (window->tiling.mode) {
+ case TEGRA_BO_TILING_MODE_PITCH:
+ value = DC_WINBUF_SURFACE_KIND_PITCH;
+ break;
+
+ case TEGRA_BO_TILING_MODE_TILED:
+ value = DC_WINBUF_SURFACE_KIND_TILED;
+ break;
+
+ case TEGRA_BO_TILING_MODE_BLOCK:
+ value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) |
+ DC_WINBUF_SURFACE_KIND_BLOCK;
+ break;
+ }
+
+ tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND);
} else {
- value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
- DC_WIN_BUFFER_ADDR_MODE_LINEAR;
- }
+ switch (window->tiling.mode) {
+ case TEGRA_BO_TILING_MODE_PITCH:
+ value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
+ DC_WIN_BUFFER_ADDR_MODE_LINEAR;
+ break;
- tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
+ case TEGRA_BO_TILING_MODE_TILED:
+ value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
+ DC_WIN_BUFFER_ADDR_MODE_TILE;
+ break;
+
+ case TEGRA_BO_TILING_MODE_BLOCK:
+ DRM_ERROR("hardware doesn't support block linear mode\n");
+ return -EINVAL;
+ }
+
+ tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
+ }
value = WIN_ENABLE;
@@ -288,6 +319,7 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
struct tegra_dc *dc = to_tegra_dc(crtc);
struct tegra_dc_window window;
unsigned int i;
+ int err;
memset(&window, 0, sizeof(window));
window.src.x = src_x >> 16;
@@ -301,7 +333,10 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
window.format = tegra_dc_format(fb->pixel_format, &window.swap);
window.bits_per_pixel = fb->bits_per_pixel;
window.bottom_up = tegra_fb_is_bottom_up(fb);
- window.tiled = tegra_fb_is_tiled(fb);
+
+ err = tegra_fb_get_tiling(fb, &window.tiling);
+ if (err < 0)
+ return err;
for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
@@ -402,8 +437,14 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
{
struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned int h_offset = 0, v_offset = 0;
+ struct tegra_bo_tiling tiling;
unsigned int format, swap;
unsigned long value;
+ int err;
+
+ err = tegra_fb_get_tiling(fb, &tiling);
+ if (err < 0)
+ return err;
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -417,15 +458,44 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
tegra_dc_writel(dc, swap, DC_WIN_BYTE_SWAP);
- if (tegra_fb_is_tiled(fb)) {
- value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
- DC_WIN_BUFFER_ADDR_MODE_TILE;
+ if (dc->soc->supports_block_linear) {
+ unsigned long height = tiling.value;
+
+ switch (tiling.mode) {
+ case TEGRA_BO_TILING_MODE_PITCH:
+ value = DC_WINBUF_SURFACE_KIND_PITCH;
+ break;
+
+ case TEGRA_BO_TILING_MODE_TILED:
+ value = DC_WINBUF_SURFACE_KIND_TILED;
+ break;
+
+ case TEGRA_BO_TILING_MODE_BLOCK:
+ value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) |
+ DC_WINBUF_SURFACE_KIND_BLOCK;
+ break;
+ }
+
+ tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND);
} else {
- value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
- DC_WIN_BUFFER_ADDR_MODE_LINEAR;
- }
+ switch (tiling.mode) {
+ case TEGRA_BO_TILING_MODE_PITCH:
+ value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
+ DC_WIN_BUFFER_ADDR_MODE_LINEAR;
+ break;
+
+ case TEGRA_BO_TILING_MODE_TILED:
+ value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
+ DC_WIN_BUFFER_ADDR_MODE_TILE;
+ break;
+
+ case TEGRA_BO_TILING_MODE_BLOCK:
+ DRM_ERROR("hardware doesn't support block linear mode\n");
+ return -EINVAL;
+ }
- tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
+ tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
+ }
/* make sure bottom-up buffers are properly displayed */
if (tegra_fb_is_bottom_up(fb)) {
@@ -1214,12 +1284,20 @@ static int tegra_dc_init(struct host1x_client *client)
{
struct drm_device *drm = dev_get_drvdata(client->parent);
struct tegra_dc *dc = host1x_client_to_dc(client);
+ struct tegra_drm *tegra = drm->dev_private;
int err;
drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs);
drm_mode_crtc_set_gamma_size(&dc->base, 256);
drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
+ /*
+ * Keep track of the minimum pitch alignment across all display
+ * controllers.
+ */
+ if (dc->soc->pitch_align > tegra->pitch_align)
+ tegra->pitch_align = dc->soc->pitch_align;
+
err = tegra_dc_rgb_init(drm, dc);
if (err < 0 && err != -ENODEV) {
dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
@@ -1277,16 +1355,29 @@ static const struct host1x_client_ops dc_client_ops = {
static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
.supports_interlacing = false,
.supports_cursor = false,
+ .supports_block_linear = false,
+ .pitch_align = 8,
};
static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
.supports_interlacing = false,
.supports_cursor = false,
+ .supports_block_linear = false,
+ .pitch_align = 8,
+};
+
+static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
+ .supports_interlacing = false,
+ .supports_cursor = false,
+ .supports_block_linear = false,
+ .pitch_align = 64,
};
static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
.supports_interlacing = true,
.supports_cursor = true,
+ .supports_block_linear = true,
+ .pitch_align = 64,
};
static const struct of_device_id tegra_dc_of_match[] = {
@@ -1303,6 +1394,7 @@ static const struct of_device_id tegra_dc_of_match[] = {
/* sentinel */
}
};
+MODULE_DEVICE_TABLE(of, tegra_dc_of_match);
static int tegra_dc_parse_dt(struct tegra_dc *dc)
{
@@ -1430,6 +1522,7 @@ static int tegra_dc_remove(struct platform_device *pdev)
return err;
}
+ reset_control_assert(dc->rst);
clk_disable_unprepare(dc->clk);
return 0;
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 78c5feff95d2..705c93b00794 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -428,6 +428,11 @@
#define DC_WINBUF_ADDR_V_OFFSET_NS 0x809
#define DC_WINBUF_UFLOW_STATUS 0x80a
+#define DC_WINBUF_SURFACE_KIND 0x80b
+#define DC_WINBUF_SURFACE_KIND_PITCH (0 << 0)
+#define DC_WINBUF_SURFACE_KIND_TILED (1 << 0)
+#define DC_WINBUF_SURFACE_KIND_BLOCK (2 << 0)
+#define DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
#define DC_WINBUF_AD_UFLOW_STATUS 0xbca
#define DC_WINBUF_BD_UFLOW_STATUS 0xdca
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 3f132e356e9c..708f783ead47 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -382,6 +382,7 @@ static const struct of_device_id tegra_dpaux_of_match[] = {
{ .compatible = "nvidia,tegra124-dpaux", },
{ },
};
+MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);
struct platform_driver tegra_dpaux_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 3396f9f6a9f7..59736bb810cd 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -40,6 +40,12 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
drm_mode_config_init(drm);
+ err = tegra_drm_fb_prepare(drm);
+ if (err < 0)
+ return err;
+
+ drm_kms_helper_poll_init(drm);
+
err = host1x_device_init(device);
if (err < 0)
return err;
@@ -59,8 +65,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
if (err < 0)
return err;
- drm_kms_helper_poll_init(drm);
-
return 0;
}
@@ -128,6 +132,45 @@ host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
return &bo->base;
}
+static int host1x_reloc_copy_from_user(struct host1x_reloc *dest,
+ struct drm_tegra_reloc __user *src,
+ struct drm_device *drm,
+ struct drm_file *file)
+{
+ u32 cmdbuf, target;
+ int err;
+
+ err = get_user(cmdbuf, &src->cmdbuf.handle);
+ if (err < 0)
+ return err;
+
+ err = get_user(dest->cmdbuf.offset, &src->cmdbuf.offset);
+ if (err < 0)
+ return err;
+
+ err = get_user(target, &src->target.handle);
+ if (err < 0)
+ return err;
+
+ err = get_user(dest->target.offset, &src->cmdbuf.offset);
+ if (err < 0)
+ return err;
+
+ err = get_user(dest->shift, &src->shift);
+ if (err < 0)
+ return err;
+
+ dest->cmdbuf.bo = host1x_bo_lookup(drm, file, cmdbuf);
+ if (!dest->cmdbuf.bo)
+ return -ENOENT;
+
+ dest->target.bo = host1x_bo_lookup(drm, file, target);
+ if (!dest->target.bo)
+ return -ENOENT;
+
+ return 0;
+}
+
int tegra_drm_submit(struct tegra_drm_context *context,
struct drm_tegra_submit *args, struct drm_device *drm,
struct drm_file *file)
@@ -180,26 +223,13 @@ int tegra_drm_submit(struct tegra_drm_context *context,
cmdbufs++;
}
- if (copy_from_user(job->relocarray, relocs,
- sizeof(*relocs) * num_relocs)) {
- err = -EFAULT;
- goto fail;
- }
-
+ /* copy and resolve relocations from submit */
while (num_relocs--) {
- struct host1x_reloc *reloc = &job->relocarray[num_relocs];
- struct host1x_bo *cmdbuf, *target;
-
- cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf);
- target = host1x_bo_lookup(drm, file, (u32)reloc->target);
-
- reloc->cmdbuf = cmdbuf;
- reloc->target = target;
-
- if (!reloc->target || !reloc->cmdbuf) {
- err = -ENOENT;
+ err = host1x_reloc_copy_from_user(&job->relocarray[num_relocs],
+ &relocs[num_relocs], drm,
+ file);
+ if (err < 0)
goto fail;
- }
}
if (copy_from_user(job->waitchk, waitchks,
@@ -451,11 +481,151 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data,
return 0;
}
+
+static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_set_tiling *args = data;
+ enum tegra_bo_tiling_mode mode;
+ struct drm_gem_object *gem;
+ unsigned long value = 0;
+ struct tegra_bo *bo;
+
+ switch (args->mode) {
+ case DRM_TEGRA_GEM_TILING_MODE_PITCH:
+ mode = TEGRA_BO_TILING_MODE_PITCH;
+
+ if (args->value != 0)
+ return -EINVAL;
+
+ break;
+
+ case DRM_TEGRA_GEM_TILING_MODE_TILED:
+ mode = TEGRA_BO_TILING_MODE_TILED;
+
+ if (args->value != 0)
+ return -EINVAL;
+
+ break;
+
+ case DRM_TEGRA_GEM_TILING_MODE_BLOCK:
+ mode = TEGRA_BO_TILING_MODE_BLOCK;
+
+ if (args->value > 5)
+ return -EINVAL;
+
+ value = args->value;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ gem = drm_gem_object_lookup(drm, file, args->handle);
+ if (!gem)
+ return -ENOENT;
+
+ bo = to_tegra_bo(gem);
+
+ bo->tiling.mode = mode;
+ bo->tiling.value = value;
+
+ drm_gem_object_unreference(gem);
+
+ return 0;
+}
+
+static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_get_tiling *args = data;
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo;
+ int err = 0;
+
+ gem = drm_gem_object_lookup(drm, file, args->handle);
+ if (!gem)
+ return -ENOENT;
+
+ bo = to_tegra_bo(gem);
+
+ switch (bo->tiling.mode) {
+ case TEGRA_BO_TILING_MODE_PITCH:
+ args->mode = DRM_TEGRA_GEM_TILING_MODE_PITCH;
+ args->value = 0;
+ break;
+
+ case TEGRA_BO_TILING_MODE_TILED:
+ args->mode = DRM_TEGRA_GEM_TILING_MODE_TILED;
+ args->value = 0;
+ break;
+
+ case TEGRA_BO_TILING_MODE_BLOCK:
+ args->mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK;
+ args->value = bo->tiling.value;
+ break;
+
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ drm_gem_object_unreference(gem);
+
+ return err;
+}
+
+static int tegra_gem_set_flags(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_set_flags *args = data;
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo;
+
+ if (args->flags & ~DRM_TEGRA_GEM_FLAGS)
+ return -EINVAL;
+
+ gem = drm_gem_object_lookup(drm, file, args->handle);
+ if (!gem)
+ return -ENOENT;
+
+ bo = to_tegra_bo(gem);
+ bo->flags = 0;
+
+ if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
+ bo->flags |= TEGRA_BO_BOTTOM_UP;
+
+ drm_gem_object_unreference(gem);
+
+ return 0;
+}
+
+static int tegra_gem_get_flags(struct drm_device *drm, void *data,
+ struct drm_file *file)
+{
+ struct drm_tegra_gem_get_flags *args = data;
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo;
+
+ gem = drm_gem_object_lookup(drm, file, args->handle);
+ if (!gem)
+ return -ENOENT;
+
+ bo = to_tegra_bo(gem);
+ args->flags = 0;
+
+ if (bo->flags & TEGRA_BO_BOTTOM_UP)
+ args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
+
+ drm_gem_object_unreference(gem);
+
+ return 0;
+}
#endif
static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
#ifdef CONFIG_DRM_TEGRA_STAGING
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED | DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, DRM_UNLOCKED),
@@ -465,6 +635,10 @@ static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, DRM_UNLOCKED),
#endif
};
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 6b8fe9d86ed4..e89c70fa82d5 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -19,6 +19,8 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_fixed.h>
+#include "gem.h"
+
struct reset_control;
struct tegra_fb {
@@ -43,6 +45,8 @@ struct tegra_drm {
#ifdef CONFIG_DRM_TEGRA_FBDEV
struct tegra_fbdev *fbdev;
#endif
+
+ unsigned int pitch_align;
};
struct tegra_drm_client;
@@ -160,7 +164,8 @@ struct tegra_dc_window {
unsigned int stride[2];
unsigned long base[3];
bool bottom_up;
- bool tiled;
+
+ struct tegra_bo_tiling tiling;
};
/* from dc.c */
@@ -279,7 +284,9 @@ int tegra_dpaux_train(struct tegra_dpaux *dpaux, struct drm_dp_link *link,
struct tegra_bo *tegra_fb_get_plane(struct drm_framebuffer *framebuffer,
unsigned int index);
bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer);
-bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer);
+int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
+ struct tegra_bo_tiling *tiling);
+int tegra_drm_fb_prepare(struct drm_device *drm);
int tegra_drm_fb_init(struct drm_device *drm);
void tegra_drm_fb_exit(struct drm_device *drm);
#ifdef CONFIG_DRM_TEGRA_FBDEV
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index bd56f2affa78..f7874458926a 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -474,7 +474,8 @@ static int tegra_output_dsi_enable(struct tegra_output *output)
tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
value = tegra_dsi_readl(dsi, DSI_CONTROL);
- value |= DSI_CONTROL_HS_CLK_CTRL;
+ if (dsi->flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+ value |= DSI_CONTROL_HS_CLK_CTRL;
value &= ~DSI_CONTROL_TX_TRIG(3);
value &= ~DSI_CONTROL_DCS_ENABLE;
value |= DSI_CONTROL_VIDEO_ENABLE;
@@ -982,6 +983,7 @@ static const struct of_device_id tegra_dsi_of_match[] = {
{ .compatible = "nvidia,tegra114-dsi", },
{ },
};
+MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);
struct platform_driver tegra_dsi_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 9798a7080322..3513d12d5aa1 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -46,14 +46,15 @@ bool tegra_fb_is_bottom_up(struct drm_framebuffer *framebuffer)
return false;
}
-bool tegra_fb_is_tiled(struct drm_framebuffer *framebuffer)
+int tegra_fb_get_tiling(struct drm_framebuffer *framebuffer,
+ struct tegra_bo_tiling *tiling)
{
struct tegra_fb *fb = to_tegra_fb(framebuffer);
- if (fb->planes[0]->flags & TEGRA_BO_TILED)
- return true;
+ /* TODO: handle YUV formats? */
+ *tiling = fb->planes[0]->tiling;
- return false;
+ return 0;
}
static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
@@ -193,6 +194,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct tegra_fbdev *fbdev = to_tegra_fbdev(helper);
+ struct tegra_drm *tegra = helper->dev->dev_private;
struct drm_device *drm = helper->dev;
struct drm_mode_fb_cmd2 cmd = { 0 };
unsigned int bytes_per_pixel;
@@ -207,7 +209,8 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
cmd.width = sizes->surface_width;
cmd.height = sizes->surface_height;
- cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;
+ cmd.pitches[0] = round_up(sizes->surface_width * bytes_per_pixel,
+ tegra->pitch_align);
cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);
@@ -267,18 +270,13 @@ release:
return err;
}
-static struct drm_fb_helper_funcs tegra_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs tegra_fb_helper_funcs = {
.fb_probe = tegra_fbdev_probe,
};
-static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm,
- unsigned int preferred_bpp,
- unsigned int num_crtc,
- unsigned int max_connectors)
+static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm)
{
- struct drm_fb_helper *helper;
struct tegra_fbdev *fbdev;
- int err;
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev) {
@@ -286,13 +284,23 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm,
return ERR_PTR(-ENOMEM);
}
- fbdev->base.funcs = &tegra_fb_helper_funcs;
- helper = &fbdev->base;
+ drm_fb_helper_prepare(drm, &fbdev->base, &tegra_fb_helper_funcs);
+
+ return fbdev;
+}
+
+static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
+ unsigned int preferred_bpp,
+ unsigned int num_crtc,
+ unsigned int max_connectors)
+{
+ struct drm_device *drm = fbdev->base.dev;
+ int err;
err = drm_fb_helper_init(drm, &fbdev->base, num_crtc, max_connectors);
if (err < 0) {
dev_err(drm->dev, "failed to initialize DRM FB helper\n");
- goto free;
+ return err;
}
err = drm_fb_helper_single_add_all_connectors(&fbdev->base);
@@ -301,21 +309,17 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm,
goto fini;
}
- drm_helper_disable_unused_functions(drm);
-
err = drm_fb_helper_initial_config(&fbdev->base, preferred_bpp);
if (err < 0) {
dev_err(drm->dev, "failed to set initial configuration\n");
goto fini;
}
- return fbdev;
+ return 0;
fini:
drm_fb_helper_fini(&fbdev->base);
-free:
- kfree(fbdev);
- return ERR_PTR(err);
+ return err;
}
static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
@@ -366,7 +370,7 @@ static const struct drm_mode_config_funcs tegra_drm_mode_funcs = {
#endif
};
-int tegra_drm_fb_init(struct drm_device *drm)
+int tegra_drm_fb_prepare(struct drm_device *drm)
{
#ifdef CONFIG_DRM_TEGRA_FBDEV
struct tegra_drm *tegra = drm->dev_private;
@@ -381,8 +385,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
drm->mode_config.funcs = &tegra_drm_mode_funcs;
#ifdef CONFIG_DRM_TEGRA_FBDEV
- tegra->fbdev = tegra_fbdev_create(drm, 32, drm->mode_config.num_crtc,
- drm->mode_config.num_connector);
+ tegra->fbdev = tegra_fbdev_create(drm);
if (IS_ERR(tegra->fbdev))
return PTR_ERR(tegra->fbdev);
#endif
@@ -390,6 +393,21 @@ int tegra_drm_fb_init(struct drm_device *drm)
return 0;
}
+int tegra_drm_fb_init(struct drm_device *drm)
+{
+#ifdef CONFIG_DRM_TEGRA_FBDEV
+ struct tegra_drm *tegra = drm->dev_private;
+ int err;
+
+ err = tegra_fbdev_init(tegra->fbdev, 32, drm->mode_config.num_crtc,
+ drm->mode_config.num_connector);
+ if (err < 0)
+ return err;
+#endif
+
+ return 0;
+}
+
void tegra_drm_fb_exit(struct drm_device *drm)
{
#ifdef CONFIG_DRM_TEGRA_FBDEV
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index aa85b7b26f10..ce023fa3e8ae 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -16,6 +16,7 @@
#include <linux/dma-buf.h>
#include <drm/tegra_drm.h>
+#include "drm.h"
#include "gem.h"
static inline struct tegra_bo *host1x_to_tegra_bo(struct host1x_bo *bo)
@@ -126,7 +127,7 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size,
goto err_mmap;
if (flags & DRM_TEGRA_GEM_CREATE_TILED)
- bo->flags |= TEGRA_BO_TILED;
+ bo->tiling.mode = TEGRA_BO_TILING_MODE_TILED;
if (flags & DRM_TEGRA_GEM_CREATE_BOTTOM_UP)
bo->flags |= TEGRA_BO_BOTTOM_UP;
@@ -259,8 +260,10 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
struct drm_mode_create_dumb *args)
{
int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+ struct tegra_drm *tegra = drm->dev_private;
struct tegra_bo *bo;
+ min_pitch = round_up(min_pitch, tegra->pitch_align);
if (args->pitch < min_pitch)
args->pitch = min_pitch;
@@ -420,7 +423,7 @@ struct dma_buf *tegra_gem_prime_export(struct drm_device *drm,
int flags)
{
return dma_buf_export(gem, &tegra_gem_prime_dmabuf_ops, gem->size,
- flags);
+ flags, NULL);
}
struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h
index 2f3fe96c5154..43a25c853357 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/drm/tegra/gem.h
@@ -16,8 +16,18 @@
#include <drm/drm.h>
#include <drm/drmP.h>
-#define TEGRA_BO_TILED (1 << 0)
-#define TEGRA_BO_BOTTOM_UP (1 << 1)
+#define TEGRA_BO_BOTTOM_UP (1 << 0)
+
+enum tegra_bo_tiling_mode {
+ TEGRA_BO_TILING_MODE_PITCH,
+ TEGRA_BO_TILING_MODE_TILED,
+ TEGRA_BO_TILING_MODE_BLOCK,
+};
+
+struct tegra_bo_tiling {
+ enum tegra_bo_tiling_mode mode;
+ unsigned long value;
+};
struct tegra_bo {
struct drm_gem_object gem;
@@ -26,6 +36,8 @@ struct tegra_bo {
struct sg_table *sgt;
dma_addr_t paddr;
void *vaddr;
+
+ struct tegra_bo_tiling tiling;
};
static inline struct tegra_bo *to_tegra_bo(struct drm_gem_object *gem)
diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index 7c53941f2a9e..02cd3e37a6ec 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -121,6 +121,7 @@ static const struct of_device_id gr2d_match[] = {
{ .compatible = "nvidia,tegra20-gr2d" },
{ },
};
+MODULE_DEVICE_TABLE(of, gr2d_match);
static const u32 gr2d_addr_regs[] = {
GR2D_UA_BASE_ADDR,
diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index 30f5ba9bd6d0..0b3f2b977ba0 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -12,7 +12,8 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
-#include <linux/tegra-powergate.h>
+
+#include <soc/tegra/pmc.h>
#include "drm.h"
#include "gem.h"
@@ -130,6 +131,7 @@ static const struct of_device_id tegra_gr3d_match[] = {
{ .compatible = "nvidia,tegra20-gr3d" },
{ }
};
+MODULE_DEVICE_TABLE(of, tegra_gr3d_match);
static const u32 gr3d_addr_regs[] = {
GR3D_IDX_ATTRIBUTE( 0),
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index ba067bb767e3..ffe26547328d 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -1450,6 +1450,7 @@ static const struct of_device_id tegra_hdmi_of_match[] = {
{ .compatible = "nvidia,tegra20-hdmi", .data = &tegra20_hdmi_config },
{ },
};
+MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match);
static int tegra_hdmi_probe(struct platform_device *pdev)
{
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index a3e4f1eca6f7..0c67d7eebc94 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -105,7 +105,7 @@ static void drm_connector_clear(struct drm_connector *connector)
static void tegra_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
drm_connector_clear(connector);
}
@@ -140,7 +140,9 @@ static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
if (mode != DRM_MODE_DPMS_ON) {
drm_panel_disable(panel);
tegra_output_disable(output);
+ drm_panel_unprepare(panel);
} else {
+ drm_panel_prepare(panel);
tegra_output_enable(output);
drm_panel_enable(panel);
}
@@ -318,7 +320,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
drm_mode_connector_attach_encoder(&output->connector, &output->encoder);
- drm_sysfs_connector_add(&output->connector);
+ drm_connector_register(&output->connector);
output->encoder.possible_crtcs = 0x3;
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 27c979b50111..7829e81f065d 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -11,7 +11,8 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
-#include <linux/tegra-powergate.h>
+
+#include <soc/tegra/pmc.h>
#include <drm/drm_dp_helper.h>
@@ -516,7 +517,7 @@ static int tegra_output_sor_enable(struct tegra_output *output)
if (err < 0) {
dev_err(sor->dev, "failed to probe eDP link: %d\n",
err);
- return err;
+ goto unlock;
}
}
@@ -525,7 +526,7 @@ static int tegra_output_sor_enable(struct tegra_output *output)
dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
memset(&config, 0, sizeof(config));
- config.bits_per_pixel = 24; /* XXX: don't hardcode? */
+ config.bits_per_pixel = output->connector.display_info.bpc * 3;
err = tegra_sor_calc_config(sor, mode, &config, &link);
if (err < 0)
@@ -815,12 +816,22 @@ static int tegra_output_sor_enable(struct tegra_output *output)
* configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete
* raster, associate with display controller)
*/
- value = SOR_STATE_ASY_VSYNCPOL |
- SOR_STATE_ASY_HSYNCPOL |
- SOR_STATE_ASY_PROTOCOL_DP_A |
+ value = SOR_STATE_ASY_PROTOCOL_DP_A |
SOR_STATE_ASY_CRC_MODE_COMPLETE |
SOR_STATE_ASY_OWNER(dc->pipe + 1);
+ if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+ value &= ~SOR_STATE_ASY_HSYNCPOL;
+
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ value |= SOR_STATE_ASY_HSYNCPOL;
+
+ if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+ value &= ~SOR_STATE_ASY_VSYNCPOL;
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ value |= SOR_STATE_ASY_VSYNCPOL;
+
switch (config.bits_per_pixel) {
case 24:
value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
@@ -1455,6 +1466,7 @@ static const struct of_device_id tegra_sor_of_match[] = {
{ .compatible = "nvidia,tegra124-sor", },
{ },
};
+MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
struct platform_driver tegra_sor_driver = {
.driver = {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index b20b69488dc9..6be623b4a86f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -120,8 +120,8 @@ static int cpufreq_transition(struct notifier_block *nb,
static int tilcdc_unload(struct drm_device *dev)
{
struct tilcdc_drm_private *priv = dev->dev_private;
- struct tilcdc_module *mod, *cur;
+ drm_fbdev_cma_fini(priv->fbdev);
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
drm_vblank_cleanup(dev);
@@ -148,11 +148,6 @@ static int tilcdc_unload(struct drm_device *dev)
pm_runtime_disable(dev->dev);
- list_for_each_entry_safe(mod, cur, &module_list, list) {
- DBG("destroying module: %s", mod->name);
- mod->funcs->destroy(mod);
- }
-
kfree(priv);
return 0;
@@ -628,13 +623,13 @@ static int __init tilcdc_drm_init(void)
static void __exit tilcdc_drm_fini(void)
{
DBG("fini");
- tilcdc_tfp410_fini();
- tilcdc_slave_fini();
- tilcdc_panel_fini();
platform_driver_unregister(&tilcdc_platform_driver);
+ tilcdc_panel_fini();
+ tilcdc_slave_fini();
+ tilcdc_tfp410_fini();
}
-late_initcall(tilcdc_drm_init);
+module_init(tilcdc_drm_init);
module_exit(tilcdc_drm_fini);
MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index 093803683b25..7596c144a9fb 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -98,7 +98,6 @@ struct tilcdc_module;
struct tilcdc_module_ops {
/* create appropriate encoders/connectors: */
int (*modeset_init)(struct tilcdc_module *mod, struct drm_device *dev);
- void (*destroy)(struct tilcdc_module *mod);
#ifdef CONFIG_DEBUG_FS
/* create debugfs nodes (can be NULL): */
int (*debugfs_init)(struct tilcdc_module *mod, struct drm_minor *minor);
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 86c67329b605..4c7aa1d8134f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -151,6 +151,7 @@ struct panel_connector {
static void panel_connector_destroy(struct drm_connector *connector)
{
struct panel_connector *panel_connector = to_panel_connector(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(panel_connector);
}
@@ -247,7 +248,7 @@ static struct drm_connector *panel_connector_create(struct drm_device *dev,
if (ret)
goto fail;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return connector;
@@ -281,23 +282,8 @@ static int panel_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
return 0;
}
-static void panel_destroy(struct tilcdc_module *mod)
-{
- struct panel_module *panel_mod = to_panel_module(mod);
-
- if (panel_mod->timings) {
- display_timings_release(panel_mod->timings);
- kfree(panel_mod->timings);
- }
-
- tilcdc_module_cleanup(mod);
- kfree(panel_mod->info);
- kfree(panel_mod);
-}
-
static const struct tilcdc_module_ops panel_module_ops = {
.modeset_init = panel_modeset_init,
- .destroy = panel_destroy,
};
/*
@@ -373,6 +359,7 @@ static int panel_probe(struct platform_device *pdev)
return -ENOMEM;
mod = &panel_mod->base;
+ pdev->dev.platform_data = mod;
tilcdc_module_init(mod, "panel", &panel_module_ops);
@@ -380,17 +367,16 @@ static int panel_probe(struct platform_device *pdev)
if (IS_ERR(pinctrl))
dev_warn(&pdev->dev, "pins are not configured\n");
-
panel_mod->timings = of_get_display_timings(node);
if (!panel_mod->timings) {
dev_err(&pdev->dev, "could not get panel timings\n");
- goto fail;
+ goto fail_free;
}
panel_mod->info = of_get_panel_info(node);
if (!panel_mod->info) {
dev_err(&pdev->dev, "could not get panel info\n");
- goto fail;
+ goto fail_timings;
}
mod->preferred_bpp = panel_mod->info->bpp;
@@ -401,13 +387,26 @@ static int panel_probe(struct platform_device *pdev)
return 0;
-fail:
- panel_destroy(mod);
+fail_timings:
+ display_timings_release(panel_mod->timings);
+
+fail_free:
+ kfree(panel_mod);
+ tilcdc_module_cleanup(mod);
return ret;
}
static int panel_remove(struct platform_device *pdev)
{
+ struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+ struct panel_module *panel_mod = to_panel_module(mod);
+
+ display_timings_release(panel_mod->timings);
+
+ tilcdc_module_cleanup(mod);
+ kfree(panel_mod->info);
+ kfree(panel_mod);
+
return 0;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
index 595068ba2d5e..3775fd49dac4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
@@ -166,6 +166,7 @@ struct slave_connector {
static void slave_connector_destroy(struct drm_connector *connector)
{
struct slave_connector *slave_connector = to_slave_connector(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(slave_connector);
}
@@ -261,7 +262,7 @@ static struct drm_connector *slave_connector_create(struct drm_device *dev,
if (ret)
goto fail;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return connector;
@@ -295,17 +296,8 @@ static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
return 0;
}
-static void slave_destroy(struct tilcdc_module *mod)
-{
- struct slave_module *slave_mod = to_slave_module(mod);
-
- tilcdc_module_cleanup(mod);
- kfree(slave_mod);
-}
-
static const struct tilcdc_module_ops slave_module_ops = {
.modeset_init = slave_modeset_init,
- .destroy = slave_destroy,
};
/*
@@ -355,10 +347,13 @@ static int slave_probe(struct platform_device *pdev)
}
slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL);
- if (!slave_mod)
- return -ENOMEM;
+ if (!slave_mod) {
+ ret = -ENOMEM;
+ goto fail_adapter;
+ }
mod = &slave_mod->base;
+ pdev->dev.platform_data = mod;
mod->preferred_bpp = slave_info.bpp;
@@ -373,10 +368,20 @@ static int slave_probe(struct platform_device *pdev)
tilcdc_slave_probedefer(false);
return 0;
+
+fail_adapter:
+ i2c_put_adapter(slavei2c);
+ return ret;
}
static int slave_remove(struct platform_device *pdev)
{
+ struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+ struct slave_module *slave_mod = to_slave_module(mod);
+
+ tilcdc_module_cleanup(mod);
+ kfree(slave_mod);
+
return 0;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index c38b56b268ac..354c47ca6374 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -167,6 +167,7 @@ struct tfp410_connector {
static void tfp410_connector_destroy(struct drm_connector *connector)
{
struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(tfp410_connector);
}
@@ -261,7 +262,7 @@ static struct drm_connector *tfp410_connector_create(struct drm_device *dev,
if (ret)
goto fail;
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
return connector;
@@ -295,23 +296,8 @@ static int tfp410_modeset_init(struct tilcdc_module *mod, struct drm_device *dev
return 0;
}
-static void tfp410_destroy(struct tilcdc_module *mod)
-{
- struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
-
- if (tfp410_mod->i2c)
- i2c_put_adapter(tfp410_mod->i2c);
-
- if (!IS_ERR_VALUE(tfp410_mod->gpio))
- gpio_free(tfp410_mod->gpio);
-
- tilcdc_module_cleanup(mod);
- kfree(tfp410_mod);
-}
-
static const struct tilcdc_module_ops tfp410_module_ops = {
.modeset_init = tfp410_modeset_init,
- .destroy = tfp410_destroy,
};
/*
@@ -341,6 +327,7 @@ static int tfp410_probe(struct platform_device *pdev)
return -ENOMEM;
mod = &tfp410_mod->base;
+ pdev->dev.platform_data = mod;
tilcdc_module_init(mod, "tfp410", &tfp410_module_ops);
@@ -364,6 +351,7 @@ static int tfp410_probe(struct platform_device *pdev)
tfp410_mod->i2c = of_find_i2c_adapter_by_node(i2c_node);
if (!tfp410_mod->i2c) {
dev_err(&pdev->dev, "could not get i2c\n");
+ of_node_put(i2c_node);
goto fail;
}
@@ -377,19 +365,32 @@ static int tfp410_probe(struct platform_device *pdev)
ret = gpio_request(tfp410_mod->gpio, "DVI_PDn");
if (ret) {
dev_err(&pdev->dev, "could not get DVI_PDn gpio\n");
- goto fail;
+ goto fail_adapter;
}
}
return 0;
+fail_adapter:
+ i2c_put_adapter(tfp410_mod->i2c);
+
fail:
- tfp410_destroy(mod);
+ kfree(tfp410_mod);
+ tilcdc_module_cleanup(mod);
return ret;
}
static int tfp410_remove(struct platform_device *pdev)
{
+ struct tilcdc_module *mod = dev_get_platdata(&pdev->dev);
+ struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
+
+ i2c_put_adapter(tfp410_mod->i2c);
+ gpio_free(tfp410_mod->gpio);
+
+ tilcdc_module_cleanup(mod);
+ kfree(tfp410_mod);
+
return 0;
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 4ab9f7171c4f..3da89d5dab60 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -412,7 +412,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
int ret;
spin_lock(&glob->lru_lock);
- ret = __ttm_bo_reserve(bo, false, true, false, 0);
+ ret = __ttm_bo_reserve(bo, false, true, false, NULL);
spin_lock(&bdev->fence_lock);
(void) ttm_bo_wait(bo, false, false, true);
@@ -514,7 +514,7 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
return ret;
spin_lock(&glob->lru_lock);
- ret = __ttm_bo_reserve(bo, false, true, false, 0);
+ ret = __ttm_bo_reserve(bo, false, true, false, NULL);
/*
* We raced, and lost, someone else holds the reservation now,
@@ -577,11 +577,11 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
kref_get(&nentry->list_kref);
}
- ret = __ttm_bo_reserve(entry, false, true, false, 0);
+ ret = __ttm_bo_reserve(entry, false, true, false, NULL);
if (remove_all && ret) {
spin_unlock(&glob->lru_lock);
ret = __ttm_bo_reserve(entry, false, false,
- false, 0);
+ false, NULL);
spin_lock(&glob->lru_lock);
}
@@ -726,7 +726,7 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
spin_lock(&glob->lru_lock);
list_for_each_entry(bo, &man->lru, lru) {
- ret = __ttm_bo_reserve(bo, false, true, false, 0);
+ ret = __ttm_bo_reserve(bo, false, true, false, NULL);
if (!ret)
break;
}
@@ -784,7 +784,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
int ret;
do {
- ret = (*man->func->get_node)(man, bo, placement, mem);
+ ret = (*man->func->get_node)(man, bo, placement, 0, mem);
if (unlikely(ret != 0))
return ret;
if (mem->mm_node)
@@ -897,7 +897,8 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
if (man->has_type && man->use_type) {
type_found = true;
- ret = (*man->func->get_node)(man, bo, placement, mem);
+ ret = (*man->func->get_node)(man, bo, placement,
+ cur_flags, mem);
if (unlikely(ret))
return ret;
}
@@ -937,7 +938,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
ttm_flag_masked(&cur_flags, placement->busy_placement[i],
~TTM_PL_MASK_MEMTYPE);
-
if (mem_type == TTM_PL_SYSTEM) {
mem->mem_type = mem_type;
mem->placement = cur_flags;
@@ -1595,7 +1595,7 @@ int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
* Using ttm_bo_reserve makes sure the lru lists are updated.
*/
- ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
+ ret = ttm_bo_reserve(bo, true, no_wait, false, NULL);
if (unlikely(ret != 0))
return ret;
spin_lock(&bdev->fence_lock);
@@ -1630,7 +1630,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
spin_lock(&glob->lru_lock);
list_for_each_entry(bo, &glob->swap_lru, swap) {
- ret = __ttm_bo_reserve(bo, false, true, false, 0);
+ ret = __ttm_bo_reserve(bo, false, true, false, NULL);
if (!ret)
break;
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index bd850c9f4bca..9e103a4875c8 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -50,6 +50,7 @@ struct ttm_range_manager {
static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *bo,
struct ttm_placement *placement,
+ uint32_t flags,
struct ttm_mem_reg *mem)
{
struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
@@ -67,7 +68,7 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
if (!node)
return -ENOMEM;
- if (bo->mem.placement & TTM_PL_FLAG_TOPDOWN)
+ if (flags & TTM_PL_FLAG_TOPDOWN)
aflags = DRM_MM_CREATE_TOP;
spin_lock(&rman->lock);
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 1df856f78568..30e5d90cb7bc 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -500,7 +500,7 @@ pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
pgprot_val(tmp) |= _PAGE_GUARDED;
}
#endif
-#if defined(__ia64__)
+#if defined(__ia64__) || defined(__arm__)
if (caching_flags & TTM_PL_FLAG_WC)
tmp = pgprot_writecombine(tmp);
else
diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c
index d7f92fe9d904..66fc6395eb54 100644
--- a/drivers/gpu/drm/ttm/ttm_module.c
+++ b/drivers/gpu/drm/ttm/ttm_module.c
@@ -35,7 +35,7 @@
#include <drm/drm_sysfs.h>
static DECLARE_WAIT_QUEUE_HEAD(exit_q);
-atomic_t device_released;
+static atomic_t device_released;
static struct device_type ttm_drm_class_type = {
.name = "ttm",
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c
index d2a053352789..12c87110db3a 100644
--- a/drivers/gpu/drm/ttm/ttm_object.c
+++ b/drivers/gpu/drm/ttm/ttm_object.c
@@ -695,7 +695,7 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
}
dma_buf = dma_buf_export(prime, &tdev->ops,
- prime->size, flags);
+ prime->size, flags, NULL);
if (IS_ERR(dma_buf)) {
ret = PTR_ERR(dma_buf);
ttm_mem_global_free(tdev->mem_glob,
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 863bef9f9234..09874d695188 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -297,8 +297,10 @@ static void ttm_pool_update_free_locked(struct ttm_page_pool *pool,
*
* @pool: to free the pages from
* @free_all: If set to true will free all pages in pool
+ * @gfp: GFP flags.
**/
-static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
+static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free,
+ gfp_t gfp)
{
unsigned long irq_flags;
struct page *p;
@@ -309,8 +311,7 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free)
if (NUM_PAGES_TO_ALLOC < nr_free)
npages_to_free = NUM_PAGES_TO_ALLOC;
- pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
- GFP_KERNEL);
+ pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
if (!pages_to_free) {
pr_err("Failed to allocate memory for pool free operation\n");
return 0;
@@ -382,32 +383,35 @@ out:
*
* XXX: (dchinner) Deadlock warning!
*
- * ttm_page_pool_free() does memory allocation using GFP_KERNEL. that means
- * this can deadlock when called a sc->gfp_mask that is not equal to
- * GFP_KERNEL.
+ * We need to pass sc->gfp_mask to ttm_page_pool_free().
*
* This code is crying out for a shrinker per pool....
*/
static unsigned long
ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
{
- static atomic_t start_pool = ATOMIC_INIT(0);
+ static DEFINE_MUTEX(lock);
+ static unsigned start_pool;
unsigned i;
- unsigned pool_offset = atomic_add_return(1, &start_pool);
+ unsigned pool_offset;
struct ttm_page_pool *pool;
int shrink_pages = sc->nr_to_scan;
unsigned long freed = 0;
- pool_offset = pool_offset % NUM_POOLS;
+ if (!mutex_trylock(&lock))
+ return SHRINK_STOP;
+ pool_offset = ++start_pool % NUM_POOLS;
/* select start pool in round robin fashion */
for (i = 0; i < NUM_POOLS; ++i) {
unsigned nr_free = shrink_pages;
if (shrink_pages == 0)
break;
pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
- shrink_pages = ttm_page_pool_free(pool, nr_free);
+ shrink_pages = ttm_page_pool_free(pool, nr_free,
+ sc->gfp_mask);
freed += nr_free - shrink_pages;
}
+ mutex_unlock(&lock);
return freed;
}
@@ -706,7 +710,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
}
spin_unlock_irqrestore(&pool->lock, irq_flags);
if (npages)
- ttm_page_pool_free(pool, npages);
+ ttm_page_pool_free(pool, npages, GFP_KERNEL);
}
/*
@@ -790,7 +794,7 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags,
return 0;
}
-static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, int flags,
+static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, gfp_t flags,
char *name)
{
spin_lock_init(&pool->lock);
@@ -846,7 +850,8 @@ void ttm_page_alloc_fini(void)
ttm_pool_mm_shrink_fini(_manager);
for (i = 0; i < NUM_POOLS; ++i)
- ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES);
+ ttm_page_pool_free(&_manager->pools[i], FREE_ALL_PAGES,
+ GFP_KERNEL);
kobject_put(&_manager->kobj);
_manager = NULL;
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index fb8259f69839..ca65df144765 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -411,8 +411,10 @@ static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
*
* @pool: to free the pages from
* @nr_free: If set to true will free all pages in pool
+ * @gfp: GFP flags.
**/
-static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
+static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free,
+ gfp_t gfp)
{
unsigned long irq_flags;
struct dma_page *dma_p, *tmp;
@@ -430,8 +432,7 @@ static unsigned ttm_dma_page_pool_free(struct dma_pool *pool, unsigned nr_free)
npages_to_free, nr_free);
}
#endif
- pages_to_free = kmalloc(npages_to_free * sizeof(struct page *),
- GFP_KERNEL);
+ pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), gfp);
if (!pages_to_free) {
pr_err("%s: Failed to allocate memory for pool free operation\n",
@@ -530,7 +531,7 @@ static void ttm_dma_free_pool(struct device *dev, enum pool_type type)
if (pool->type != type)
continue;
/* Takes a spinlock.. */
- ttm_dma_page_pool_free(pool, FREE_ALL_PAGES);
+ ttm_dma_page_pool_free(pool, FREE_ALL_PAGES, GFP_KERNEL);
WARN_ON(((pool->npages_in_use + pool->npages_free) != 0));
/* This code path is called after _all_ references to the
* struct device has been dropped - so nobody should be
@@ -983,7 +984,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
/* shrink pool if necessary (only on !is_cached pools)*/
if (npages)
- ttm_dma_page_pool_free(pool, npages);
+ ttm_dma_page_pool_free(pool, npages, GFP_KERNEL);
ttm->state = tt_unpopulated;
}
EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
@@ -993,10 +994,7 @@ EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
*
* XXX: (dchinner) Deadlock warning!
*
- * ttm_dma_page_pool_free() does GFP_KERNEL memory allocation, and so attention
- * needs to be paid to sc->gfp_mask to determine if this can be done or not.
- * GFP_KERNEL memory allocation in a GFP_ATOMIC reclaim context woul dbe really
- * bad.
+ * We need to pass sc->gfp_mask to ttm_dma_page_pool_free().
*
* I'm getting sadder as I hear more pathetical whimpers about needing per-pool
* shrinkers
@@ -1004,9 +1002,9 @@ EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);
static unsigned long
ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
{
- static atomic_t start_pool = ATOMIC_INIT(0);
+ static unsigned start_pool;
unsigned idx = 0;
- unsigned pool_offset = atomic_add_return(1, &start_pool);
+ unsigned pool_offset;
unsigned shrink_pages = sc->nr_to_scan;
struct device_pools *p;
unsigned long freed = 0;
@@ -1014,8 +1012,11 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
if (list_empty(&_manager->pools))
return SHRINK_STOP;
- mutex_lock(&_manager->lock);
- pool_offset = pool_offset % _manager->npools;
+ if (!mutex_trylock(&_manager->lock))
+ return SHRINK_STOP;
+ if (!_manager->npools)
+ goto out;
+ pool_offset = ++start_pool % _manager->npools;
list_for_each_entry(p, &_manager->pools, pools) {
unsigned nr_free;
@@ -1027,13 +1028,15 @@ ttm_dma_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
if (++idx < pool_offset)
continue;
nr_free = shrink_pages;
- shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free);
+ shrink_pages = ttm_dma_page_pool_free(p->pool, nr_free,
+ sc->gfp_mask);
freed += nr_free - shrink_pages;
pr_debug("%s: (%s:%d) Asked to shrink %d, have %d more to go\n",
p->pool->dev_name, p->pool->name, current->pid,
nr_free, shrink_pages);
}
+out:
mutex_unlock(&_manager->lock);
return freed;
}
@@ -1044,7 +1047,8 @@ ttm_dma_pool_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
struct device_pools *p;
unsigned long count = 0;
- mutex_lock(&_manager->lock);
+ if (!mutex_trylock(&_manager->lock))
+ return 0;
list_for_each_entry(p, &_manager->pools, pools)
count += p->pool->npages_free;
mutex_unlock(&_manager->lock);
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index b44d548c56f8..e026a9e2942a 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -105,14 +105,7 @@ static struct drm_encoder*
udl_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- struct drm_mode_object *obj;
- struct drm_encoder *encoder;
-
- obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
- if (!obj)
- return NULL;
- encoder = obj_to_encoder(obj);
- return encoder;
+ return drm_encoder_find(connector->dev, enc_id);
}
static int udl_connector_set_property(struct drm_connector *connector,
@@ -124,7 +117,7 @@ static int udl_connector_set_property(struct drm_connector *connector,
static void udl_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(connector);
}
@@ -154,7 +147,7 @@ int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)
drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_DVII);
drm_connector_helper_add(connector, &udl_connector_helper_funcs);
- drm_sysfs_connector_add(connector);
+ drm_connector_register(connector);
drm_mode_connector_attach_encoder(connector, encoder);
drm_object_attach_property(&connector->base,
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 377176372da8..d1da339843ca 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -550,7 +550,7 @@ out:
return ret;
}
-static struct drm_fb_helper_funcs udl_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs udl_fb_helper_funcs = {
.fb_probe = udlfb_create,
};
@@ -583,7 +583,8 @@ int udl_fbdev_init(struct drm_device *dev)
return -ENOMEM;
udl->fbdev = ufbdev;
- ufbdev->helper.funcs = &udl_fb_helper_funcs;
+
+ drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs);
ret = drm_fb_helper_init(dev, &ufbdev->helper,
1, 1);
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index c041cd73f399..8044f5fb7c49 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -107,14 +107,14 @@ int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
}
-static int udl_gem_get_pages(struct udl_gem_object *obj, gfp_t gfpmask)
+static int udl_gem_get_pages(struct udl_gem_object *obj)
{
struct page **pages;
if (obj->pages)
return 0;
- pages = drm_gem_get_pages(&obj->base, gfpmask);
+ pages = drm_gem_get_pages(&obj->base);
if (IS_ERR(pages))
return PTR_ERR(pages);
@@ -147,7 +147,7 @@ int udl_gem_vmap(struct udl_gem_object *obj)
return 0;
}
- ret = udl_gem_get_pages(obj, GFP_KERNEL);
+ ret = udl_gem_get_pages(obj);
if (ret)
return ret;
@@ -205,7 +205,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev,
}
gobj = to_udl_bo(obj);
- ret = udl_gem_get_pages(gobj, GFP_KERNEL);
+ ret = udl_gem_get_pages(gobj);
if (ret)
goto out;
ret = drm_gem_create_mmap_offset(obj);
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 7094b92d1ec7..42795674bc07 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -306,10 +306,23 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags)
DRM_DEBUG("\n");
ret = udl_modeset_init(dev);
+ if (ret)
+ goto err;
ret = udl_fbdev_init(dev);
+ if (ret)
+ goto err;
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret)
+ goto err_fb;
+
return 0;
+err_fb:
+ udl_fbdev_cleanup(dev);
err:
+ if (udl->urbs.count)
+ udl_free_urb_list(dev);
kfree(udl);
DRM_ERROR("%d\n", ret);
return ret;
@@ -325,6 +338,8 @@ int 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/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index cddc4fcf35cf..dc145d320b25 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -363,6 +363,26 @@ static void udl_crtc_destroy(struct drm_crtc *crtc)
kfree(crtc);
}
+static int udl_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t page_flip_flags)
+{
+ struct udl_framebuffer *ufb = to_udl_fb(fb);
+ struct drm_device *dev = crtc->dev;
+ unsigned long flags;
+
+ udl_handle_damage(ufb, 0, 0, fb->width, fb->height);
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ if (event)
+ drm_send_vblank_event(dev, 0, event);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ crtc->primary->fb = fb;
+
+ return 0;
+}
+
static void udl_crtc_prepare(struct drm_crtc *crtc)
{
}
@@ -384,6 +404,7 @@ static struct drm_crtc_helper_funcs udl_helper_funcs = {
static const struct drm_crtc_funcs udl_crtc_funcs = {
.set_config = drm_crtc_helper_set_config,
.destroy = udl_crtc_destroy,
+ .page_flip = udl_crtc_page_flip,
};
static int udl_crtc_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 458cdf6d81e8..ce0ab951f507 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -6,6 +6,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \
vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \
vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \
- vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o
+ vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
+ vmwgfx_cmdbuf_res.o \
obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
new file mode 100644
index 000000000000..bfeb4b1f2acf
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
@@ -0,0 +1,341 @@
+/**************************************************************************
+ *
+ * Copyright © 2014 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 "vmwgfx_drv.h"
+
+#define VMW_CMDBUF_RES_MAN_HT_ORDER 12
+
+enum vmw_cmdbuf_res_state {
+ VMW_CMDBUF_RES_COMMITED,
+ VMW_CMDBUF_RES_ADD,
+ VMW_CMDBUF_RES_DEL
+};
+
+/**
+ * struct vmw_cmdbuf_res - Command buffer managed resource entry.
+ *
+ * @res: Refcounted pointer to a struct vmw_resource.
+ * @hash: Hash entry for the manager hash table.
+ * @head: List head used either by the staging list or the manager list
+ * of commited resources.
+ * @state: Staging state of this resource entry.
+ * @man: Pointer to a resource manager for this entry.
+ */
+struct vmw_cmdbuf_res {
+ struct vmw_resource *res;
+ struct drm_hash_item hash;
+ struct list_head head;
+ enum vmw_cmdbuf_res_state state;
+ struct vmw_cmdbuf_res_manager *man;
+};
+
+/**
+ * struct vmw_cmdbuf_res_manager - Command buffer resource manager.
+ *
+ * @resources: Hash table containing staged and commited command buffer
+ * resources
+ * @list: List of commited command buffer resources.
+ * @dev_priv: Pointer to a device private structure.
+ *
+ * @resources and @list are protected by the cmdbuf mutex for now.
+ */
+struct vmw_cmdbuf_res_manager {
+ struct drm_open_hash resources;
+ struct list_head list;
+ struct vmw_private *dev_priv;
+};
+
+
+/**
+ * vmw_cmdbuf_res_lookup - Look up a command buffer resource
+ *
+ * @man: Pointer to the command buffer resource manager
+ * @resource_type: The resource type, that combined with the user key
+ * identifies the resource.
+ * @user_key: The user key.
+ *
+ * Returns a valid refcounted struct vmw_resource pointer on success,
+ * an error pointer on failure.
+ */
+struct vmw_resource *
+vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key)
+{
+ struct drm_hash_item *hash;
+ int ret;
+ unsigned long key = user_key | (res_type << 24);
+
+ ret = drm_ht_find_item(&man->resources, key, &hash);
+ if (unlikely(ret != 0))
+ return ERR_PTR(ret);
+
+ return vmw_resource_reference
+ (drm_hash_entry(hash, struct vmw_cmdbuf_res, hash)->res);
+}
+
+/**
+ * vmw_cmdbuf_res_free - Free a command buffer resource.
+ *
+ * @man: Pointer to the command buffer resource manager
+ * @entry: Pointer to a struct vmw_cmdbuf_res.
+ *
+ * Frees a struct vmw_cmdbuf_res entry and drops its reference to the
+ * struct vmw_resource.
+ */
+static void vmw_cmdbuf_res_free(struct vmw_cmdbuf_res_manager *man,
+ struct vmw_cmdbuf_res *entry)
+{
+ list_del(&entry->head);
+ WARN_ON(drm_ht_remove_item(&man->resources, &entry->hash));
+ vmw_resource_unreference(&entry->res);
+ kfree(entry);
+}
+
+/**
+ * vmw_cmdbuf_res_commit - Commit a list of command buffer resource actions
+ *
+ * @list: Caller's list of command buffer resource actions.
+ *
+ * This function commits a list of command buffer resource
+ * additions or removals.
+ * It is typically called when the execbuf ioctl call triggering these
+ * actions has commited the fifo contents to the device.
+ */
+void vmw_cmdbuf_res_commit(struct list_head *list)
+{
+ struct vmw_cmdbuf_res *entry, *next;
+
+ list_for_each_entry_safe(entry, next, list, head) {
+ list_del(&entry->head);
+ switch (entry->state) {
+ case VMW_CMDBUF_RES_ADD:
+ entry->state = VMW_CMDBUF_RES_COMMITED;
+ list_add_tail(&entry->head, &entry->man->list);
+ break;
+ case VMW_CMDBUF_RES_DEL:
+ vmw_resource_unreference(&entry->res);
+ kfree(entry);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ }
+}
+
+/**
+ * vmw_cmdbuf_res_revert - Revert a list of command buffer resource actions
+ *
+ * @man: Pointer to the command buffer resource manager
+ * @list: Caller's list of command buffer resource action
+ *
+ * This function reverts a list of command buffer resource
+ * additions or removals.
+ * It is typically called when the execbuf ioctl call triggering these
+ * actions failed for some reason, and the command stream was never
+ * submitted.
+ */
+void vmw_cmdbuf_res_revert(struct list_head *list)
+{
+ struct vmw_cmdbuf_res *entry, *next;
+ int ret;
+
+ list_for_each_entry_safe(entry, next, list, head) {
+ switch (entry->state) {
+ case VMW_CMDBUF_RES_ADD:
+ vmw_cmdbuf_res_free(entry->man, entry);
+ break;
+ case VMW_CMDBUF_RES_DEL:
+ ret = drm_ht_insert_item(&entry->man->resources,
+ &entry->hash);
+ list_del(&entry->head);
+ list_add_tail(&entry->head, &entry->man->list);
+ entry->state = VMW_CMDBUF_RES_COMMITED;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ }
+}
+
+/**
+ * vmw_cmdbuf_res_add - Stage a command buffer managed resource for addition.
+ *
+ * @man: Pointer to the command buffer resource manager.
+ * @res_type: The resource type.
+ * @user_key: The user-space id of the resource.
+ * @res: Valid (refcount != 0) pointer to a struct vmw_resource.
+ * @list: The staging list.
+ *
+ * This function allocates a struct vmw_cmdbuf_res entry and adds the
+ * resource to the hash table of the manager identified by @man. The
+ * entry is then put on the staging list identified by @list.
+ */
+int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key,
+ struct vmw_resource *res,
+ struct list_head *list)
+{
+ struct vmw_cmdbuf_res *cres;
+ int ret;
+
+ cres = kzalloc(sizeof(*cres), GFP_KERNEL);
+ if (unlikely(cres == NULL))
+ return -ENOMEM;
+
+ cres->hash.key = user_key | (res_type << 24);
+ ret = drm_ht_insert_item(&man->resources, &cres->hash);
+ if (unlikely(ret != 0))
+ goto out_invalid_key;
+
+ cres->state = VMW_CMDBUF_RES_ADD;
+ cres->res = vmw_resource_reference(res);
+ cres->man = man;
+ list_add_tail(&cres->head, list);
+
+out_invalid_key:
+ return ret;
+}
+
+/**
+ * vmw_cmdbuf_res_remove - Stage a command buffer managed resource for removal.
+ *
+ * @man: Pointer to the command buffer resource manager.
+ * @res_type: The resource type.
+ * @user_key: The user-space id of the resource.
+ * @list: The staging list.
+ *
+ * This function looks up the struct vmw_cmdbuf_res entry from the manager
+ * hash table and, if it exists, removes it. Depending on its current staging
+ * state it then either removes the entry from the staging list or adds it
+ * to it with a staging state of removal.
+ */
+int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key,
+ struct list_head *list)
+{
+ struct vmw_cmdbuf_res *entry;
+ struct drm_hash_item *hash;
+ int ret;
+
+ ret = drm_ht_find_item(&man->resources, user_key, &hash);
+ if (likely(ret != 0))
+ return -EINVAL;
+
+ entry = drm_hash_entry(hash, struct vmw_cmdbuf_res, hash);
+
+ switch (entry->state) {
+ case VMW_CMDBUF_RES_ADD:
+ vmw_cmdbuf_res_free(man, entry);
+ break;
+ case VMW_CMDBUF_RES_COMMITED:
+ (void) drm_ht_remove_item(&man->resources, &entry->hash);
+ list_del(&entry->head);
+ entry->state = VMW_CMDBUF_RES_DEL;
+ list_add_tail(&entry->head, list);
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * vmw_cmdbuf_res_man_create - Allocate a command buffer managed resource
+ * manager.
+ *
+ * @dev_priv: Pointer to a struct vmw_private
+ *
+ * Allocates and initializes a command buffer managed resource manager. Returns
+ * an error pointer on failure.
+ */
+struct vmw_cmdbuf_res_manager *
+vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv)
+{
+ struct vmw_cmdbuf_res_manager *man;
+ int ret;
+
+ man = kzalloc(sizeof(*man), GFP_KERNEL);
+ if (man == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ man->dev_priv = dev_priv;
+ INIT_LIST_HEAD(&man->list);
+ ret = drm_ht_create(&man->resources, VMW_CMDBUF_RES_MAN_HT_ORDER);
+ if (ret == 0)
+ return man;
+
+ kfree(man);
+ return ERR_PTR(ret);
+}
+
+/**
+ * vmw_cmdbuf_res_man_destroy - Destroy a command buffer managed resource
+ * manager.
+ *
+ * @man: Pointer to the manager to destroy.
+ *
+ * This function destroys a command buffer managed resource manager and
+ * unreferences / frees all command buffer managed resources and -entries
+ * associated with it.
+ */
+void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man)
+{
+ struct vmw_cmdbuf_res *entry, *next;
+
+ list_for_each_entry_safe(entry, next, &man->list, head)
+ vmw_cmdbuf_res_free(man, entry);
+
+ kfree(man);
+}
+
+/**
+ *
+ * vmw_cmdbuf_res_man_size - Return the size of a command buffer managed
+ * resource manager
+ *
+ * Returns the approximate allocation size of a command buffer managed
+ * resource manager.
+ */
+size_t vmw_cmdbuf_res_man_size(void)
+{
+ static size_t res_man_size;
+
+ if (unlikely(res_man_size == 0))
+ res_man_size =
+ ttm_round_pot(sizeof(struct vmw_cmdbuf_res_manager)) +
+ ttm_round_pot(sizeof(struct hlist_head) <<
+ VMW_CMDBUF_RES_MAN_HT_ORDER);
+
+ return res_man_size;
+}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
index 8bb26dcd9eae..5ac92874404d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
@@ -33,6 +33,7 @@ struct vmw_user_context {
struct ttm_base_object base;
struct vmw_resource res;
struct vmw_ctx_binding_state cbs;
+ struct vmw_cmdbuf_res_manager *man;
};
@@ -103,7 +104,8 @@ static const vmw_scrub_func vmw_scrub_funcs[vmw_ctx_binding_max] = {
static void vmw_hw_context_destroy(struct vmw_resource *res)
{
-
+ struct vmw_user_context *uctx =
+ container_of(res, struct vmw_user_context, res);
struct vmw_private *dev_priv = res->dev_priv;
struct {
SVGA3dCmdHeader header;
@@ -113,9 +115,9 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
if (res->func->destroy == vmw_gb_context_destroy) {
mutex_lock(&dev_priv->cmdbuf_mutex);
+ vmw_cmdbuf_res_man_destroy(uctx->man);
mutex_lock(&dev_priv->binding_mutex);
- (void) vmw_context_binding_state_kill
- (&container_of(res, struct vmw_user_context, res)->cbs);
+ (void) vmw_context_binding_state_kill(&uctx->cbs);
(void) vmw_gb_context_destroy(res);
mutex_unlock(&dev_priv->binding_mutex);
if (dev_priv->pinned_bo != NULL &&
@@ -152,13 +154,16 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
ret = vmw_resource_init(dev_priv, res, true,
res_free, &vmw_gb_context_func);
res->backup_size = SVGA3D_CONTEXT_DATA_SIZE;
+ if (unlikely(ret != 0))
+ goto out_err;
- if (unlikely(ret != 0)) {
- if (res_free)
- res_free(res);
- else
- kfree(res);
- return ret;
+ if (dev_priv->has_mob) {
+ uctx->man = vmw_cmdbuf_res_man_create(dev_priv);
+ if (unlikely(IS_ERR(uctx->man))) {
+ ret = PTR_ERR(uctx->man);
+ uctx->man = NULL;
+ goto out_err;
+ }
}
memset(&uctx->cbs, 0, sizeof(uctx->cbs));
@@ -166,6 +171,13 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
vmw_resource_activate(res, vmw_hw_context_destroy);
return 0;
+
+out_err:
+ if (res_free)
+ res_free(res);
+ else
+ kfree(res);
+ return ret;
}
static int vmw_context_init(struct vmw_private *dev_priv,
@@ -471,7 +483,8 @@ int vmw_context_define_ioctl(struct drm_device *dev, void *data,
*/
if (unlikely(vmw_user_context_size == 0))
- vmw_user_context_size = ttm_round_pot(sizeof(*ctx)) + 128;
+ vmw_user_context_size = ttm_round_pot(sizeof(*ctx)) + 128 +
+ ((dev_priv->has_mob) ? vmw_cmdbuf_res_man_size() : 0);
ret = ttm_read_lock(&dev_priv->reservation_sem, true);
if (unlikely(ret != 0))
@@ -901,3 +914,8 @@ struct list_head *vmw_context_binding_list(struct vmw_resource *ctx)
{
return &(container_of(ctx, struct vmw_user_context, res)->cbs.list);
}
+
+struct vmw_cmdbuf_res_manager *vmw_context_res_man(struct vmw_resource *ctx)
+{
+ return container_of(ctx, struct vmw_user_context, res)->man;
+}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
index 70ddce8358b0..ed1d51006ab1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -61,7 +61,7 @@ int vmw_dmabuf_to_placement(struct vmw_private *dev_priv,
vmw_execbuf_release_pinned_bo(dev_priv);
- ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
+ ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
if (unlikely(ret != 0))
goto err;
@@ -105,7 +105,7 @@ int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv,
if (pin)
vmw_execbuf_release_pinned_bo(dev_priv);
- ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
+ ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
if (unlikely(ret != 0))
goto err;
@@ -212,7 +212,7 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv,
if (pin)
vmw_execbuf_release_pinned_bo(dev_priv);
- ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
+ ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
if (unlikely(ret != 0))
goto err_unlock;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 246a62bab378..18b54acacfbb 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -316,7 +316,7 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
if (unlikely(ret != 0))
return ret;
- ret = ttm_bo_reserve(bo, false, true, false, 0);
+ ret = ttm_bo_reserve(bo, false, true, false, NULL);
BUG_ON(ret != 0);
ret = ttm_bo_kmap(bo, 0, 1, &map);
@@ -946,7 +946,6 @@ static void vmw_postclose(struct drm_device *dev,
drm_master_put(&vmw_fp->locked_master);
}
- vmw_compat_shader_man_destroy(vmw_fp->shman);
ttm_object_file_release(&vmw_fp->tfile);
kfree(vmw_fp);
}
@@ -966,16 +965,10 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
if (unlikely(vmw_fp->tfile == NULL))
goto out_no_tfile;
- vmw_fp->shman = vmw_compat_shader_man_create(dev_priv);
- if (IS_ERR(vmw_fp->shman))
- goto out_no_shman;
-
file_priv->driver_priv = vmw_fp;
return 0;
-out_no_shman:
- ttm_object_file_release(&vmw_fp->tfile);
out_no_tfile:
kfree(vmw_fp);
return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 6b252a887ae2..99f731757c4b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -40,10 +40,10 @@
#include <drm/ttm/ttm_module.h>
#include "vmwgfx_fence.h"
-#define VMWGFX_DRIVER_DATE "20140325"
+#define VMWGFX_DRIVER_DATE "20140704"
#define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 6
-#define VMWGFX_DRIVER_PATCHLEVEL 0
+#define VMWGFX_DRIVER_PATCHLEVEL 1
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
#define VMWGFX_MAX_RELOCATIONS 2048
@@ -75,14 +75,11 @@
#define VMW_RES_FENCE ttm_driver_type3
#define VMW_RES_SHADER ttm_driver_type4
-struct vmw_compat_shader_manager;
-
struct vmw_fpriv {
struct drm_master *locked_master;
struct ttm_object_file *tfile;
struct list_head fence_events;
bool gb_aware;
- struct vmw_compat_shader_manager *shman;
};
struct vmw_dma_buffer {
@@ -124,6 +121,10 @@ struct vmw_resource {
void (*hw_destroy) (struct vmw_resource *res);
};
+
+/*
+ * Resources that are managed using ioctls.
+ */
enum vmw_res_type {
vmw_res_context,
vmw_res_surface,
@@ -132,6 +133,15 @@ enum vmw_res_type {
vmw_res_max
};
+/*
+ * Resources that are managed using command streams.
+ */
+enum vmw_cmdbuf_res_type {
+ vmw_cmdbuf_res_compat_shader
+};
+
+struct vmw_cmdbuf_res_manager;
+
struct vmw_cursor_snooper {
struct drm_crtc *crtc;
size_t age;
@@ -159,8 +169,8 @@ struct vmw_surface {
struct vmw_marker_queue {
struct list_head head;
- struct timespec lag;
- struct timespec lag_time;
+ u64 lag;
+ u64 lag_time;
spinlock_t lock;
};
@@ -341,7 +351,7 @@ struct vmw_sw_context{
bool needs_post_query_barrier;
struct vmw_resource *error_resource;
struct vmw_ctx_binding_state staged_bindings;
- struct list_head staged_shaders;
+ struct list_head staged_cmd_res;
};
struct vmw_legacy_display;
@@ -974,7 +984,8 @@ extern void vmw_context_binding_res_list_kill(struct list_head *head);
extern void vmw_context_binding_res_list_scrub(struct list_head *head);
extern int vmw_context_rebind_all(struct vmw_resource *ctx);
extern struct list_head *vmw_context_binding_list(struct vmw_resource *ctx);
-
+extern struct vmw_cmdbuf_res_manager *
+vmw_context_res_man(struct vmw_resource *ctx);
/*
* Surface management - vmwgfx_surface.c
*/
@@ -1008,27 +1019,42 @@ extern int vmw_shader_define_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man,
- SVGA3dShaderType shader_type,
- u32 *user_key);
-extern void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man,
- struct list_head *list);
-extern void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man,
- struct list_head *list);
-extern int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man,
- u32 user_key,
- SVGA3dShaderType shader_type,
- struct list_head *list);
-extern int vmw_compat_shader_add(struct vmw_compat_shader_manager *man,
+extern int vmw_compat_shader_add(struct vmw_private *dev_priv,
+ struct vmw_cmdbuf_res_manager *man,
u32 user_key, const void *bytecode,
SVGA3dShaderType shader_type,
size_t size,
- struct ttm_object_file *tfile,
struct list_head *list);
-extern struct vmw_compat_shader_manager *
-vmw_compat_shader_man_create(struct vmw_private *dev_priv);
-extern void
-vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man);
+extern int vmw_compat_shader_remove(struct vmw_cmdbuf_res_manager *man,
+ u32 user_key, SVGA3dShaderType shader_type,
+ struct list_head *list);
+extern struct vmw_resource *
+vmw_compat_shader_lookup(struct vmw_cmdbuf_res_manager *man,
+ u32 user_key, SVGA3dShaderType shader_type);
+
+/*
+ * Command buffer managed resources - vmwgfx_cmdbuf_res.c
+ */
+
+extern struct vmw_cmdbuf_res_manager *
+vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv);
+extern void vmw_cmdbuf_res_man_destroy(struct vmw_cmdbuf_res_manager *man);
+extern size_t vmw_cmdbuf_res_man_size(void);
+extern struct vmw_resource *
+vmw_cmdbuf_res_lookup(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key);
+extern void vmw_cmdbuf_res_revert(struct list_head *list);
+extern void vmw_cmdbuf_res_commit(struct list_head *list);
+extern int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key,
+ struct vmw_resource *res,
+ struct list_head *list);
+extern int vmw_cmdbuf_res_remove(struct vmw_cmdbuf_res_manager *man,
+ enum vmw_cmdbuf_res_type res_type,
+ u32 user_key,
+ struct list_head *list);
/**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 87df0b3674fd..7bfdaa163a33 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -422,28 +422,91 @@ static int vmw_resources_validate(struct vmw_sw_context *sw_context)
return 0;
}
+
+/**
+ * vmw_cmd_res_reloc_add - Add a resource to a software context's
+ * relocation- and validation lists.
+ *
+ * @dev_priv: Pointer to a struct vmw_private identifying the device.
+ * @sw_context: Pointer to the software context.
+ * @res_type: Resource type.
+ * @id_loc: Pointer to where the id that needs translation is located.
+ * @res: Valid pointer to a struct vmw_resource.
+ * @p_val: If non null, a pointer to the struct vmw_resource_validate_node
+ * used for this resource is returned here.
+ */
+static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
+ struct vmw_sw_context *sw_context,
+ enum vmw_res_type res_type,
+ uint32_t *id_loc,
+ struct vmw_resource *res,
+ struct vmw_resource_val_node **p_val)
+{
+ int ret;
+ struct vmw_resource_val_node *node;
+
+ *p_val = NULL;
+ ret = vmw_resource_relocation_add(&sw_context->res_relocations,
+ res,
+ id_loc - sw_context->buf_start);
+ if (unlikely(ret != 0))
+ goto out_err;
+
+ ret = vmw_resource_val_add(sw_context, res, &node);
+ if (unlikely(ret != 0))
+ goto out_err;
+
+ if (res_type == vmw_res_context && dev_priv->has_mob &&
+ node->first_usage) {
+
+ /*
+ * Put contexts first on the list to be able to exit
+ * list traversal for contexts early.
+ */
+ list_del(&node->head);
+ list_add(&node->head, &sw_context->resource_list);
+
+ ret = vmw_resource_context_res_add(dev_priv, sw_context, res);
+ if (unlikely(ret != 0))
+ goto out_err;
+ node->staged_bindings =
+ kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL);
+ if (node->staged_bindings == NULL) {
+ DRM_ERROR("Failed to allocate context binding "
+ "information.\n");
+ goto out_err;
+ }
+ INIT_LIST_HEAD(&node->staged_bindings->list);
+ }
+
+ if (p_val)
+ *p_val = node;
+
+out_err:
+ return ret;
+}
+
+
/**
- * vmw_cmd_compat_res_check - Check that a resource is present and if so, put it
+ * vmw_cmd_res_check - Check that a resource is present and if so, put it
* on the resource validate list unless it's already there.
*
* @dev_priv: Pointer to a device private structure.
* @sw_context: Pointer to the software context.
* @res_type: Resource type.
* @converter: User-space visisble type specific information.
- * @id: user-space resource id handle.
* @id_loc: Pointer to the location in the command buffer currently being
* parsed from where the user-space resource id handle is located.
* @p_val: Pointer to pointer to resource validalidation node. Populated
* on exit.
*/
static int
-vmw_cmd_compat_res_check(struct vmw_private *dev_priv,
- struct vmw_sw_context *sw_context,
- enum vmw_res_type res_type,
- const struct vmw_user_resource_conv *converter,
- uint32_t id,
- uint32_t *id_loc,
- struct vmw_resource_val_node **p_val)
+vmw_cmd_res_check(struct vmw_private *dev_priv,
+ struct vmw_sw_context *sw_context,
+ enum vmw_res_type res_type,
+ const struct vmw_user_resource_conv *converter,
+ uint32_t *id_loc,
+ struct vmw_resource_val_node **p_val)
{
struct vmw_res_cache_entry *rcache =
&sw_context->res_cache[res_type];
@@ -451,7 +514,7 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv,
struct vmw_resource_val_node *node;
int ret;
- if (id == SVGA3D_INVALID_ID) {
+ if (*id_loc == SVGA3D_INVALID_ID) {
if (p_val)
*p_val = NULL;
if (res_type == vmw_res_context) {
@@ -466,7 +529,7 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv,
* resource
*/
- if (likely(rcache->valid && id == rcache->handle)) {
+ if (likely(rcache->valid && *id_loc == rcache->handle)) {
const struct vmw_resource *res = rcache->res;
rcache->node->first_usage = false;
@@ -480,49 +543,28 @@ vmw_cmd_compat_res_check(struct vmw_private *dev_priv,
ret = vmw_user_resource_lookup_handle(dev_priv,
sw_context->fp->tfile,
- id,
+ *id_loc,
converter,
&res);
if (unlikely(ret != 0)) {
DRM_ERROR("Could not find or use resource 0x%08x.\n",
- (unsigned) id);
+ (unsigned) *id_loc);
dump_stack();
return ret;
}
rcache->valid = true;
rcache->res = res;
- rcache->handle = id;
-
- ret = vmw_resource_relocation_add(&sw_context->res_relocations,
- res,
- id_loc - sw_context->buf_start);
- if (unlikely(ret != 0))
- goto out_no_reloc;
+ rcache->handle = *id_loc;
- ret = vmw_resource_val_add(sw_context, res, &node);
+ ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, res_type, id_loc,
+ res, &node);
if (unlikely(ret != 0))
goto out_no_reloc;
rcache->node = node;
if (p_val)
*p_val = node;
-
- if (dev_priv->has_mob && node->first_usage &&
- res_type == vmw_res_context) {
- ret = vmw_resource_context_res_add(dev_priv, sw_context, res);
- if (unlikely(ret != 0))
- goto out_no_reloc;
- node->staged_bindings =
- kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL);
- if (node->staged_bindings == NULL) {
- DRM_ERROR("Failed to allocate context binding "
- "information.\n");
- goto out_no_reloc;
- }
- INIT_LIST_HEAD(&node->staged_bindings->list);
- }
-
vmw_resource_unreference(&res);
return 0;
@@ -534,31 +576,6 @@ out_no_reloc:
}
/**
- * vmw_cmd_res_check - Check that a resource is present and if so, put it
- * on the resource validate list unless it's already there.
- *
- * @dev_priv: Pointer to a device private structure.
- * @sw_context: Pointer to the software context.
- * @res_type: Resource type.
- * @converter: User-space visisble type specific information.
- * @id_loc: Pointer to the location in the command buffer currently being
- * parsed from where the user-space resource id handle is located.
- * @p_val: Pointer to pointer to resource validalidation node. Populated
- * on exit.
- */
-static int
-vmw_cmd_res_check(struct vmw_private *dev_priv,
- struct vmw_sw_context *sw_context,
- enum vmw_res_type res_type,
- const struct vmw_user_resource_conv *converter,
- uint32_t *id_loc,
- struct vmw_resource_val_node **p_val)
-{
- return vmw_cmd_compat_res_check(dev_priv, sw_context, res_type,
- converter, *id_loc, id_loc, p_val);
-}
-
-/**
* vmw_rebind_contexts - Rebind all resources previously bound to
* referenced contexts.
*
@@ -572,8 +589,8 @@ static int vmw_rebind_contexts(struct vmw_sw_context *sw_context)
int ret;
list_for_each_entry(val, &sw_context->resource_list, head) {
- if (likely(!val->staged_bindings))
- continue;
+ if (unlikely(!val->staged_bindings))
+ break;
ret = vmw_context_rebind_all(val->res);
if (unlikely(ret != 0)) {
@@ -1626,13 +1643,14 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
} *cmd;
int ret;
size_t size;
+ struct vmw_resource_val_node *val;
cmd = container_of(header, struct vmw_shader_define_cmd,
header);
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
user_context_converter, &cmd->body.cid,
- NULL);
+ &val);
if (unlikely(ret != 0))
return ret;
@@ -1640,11 +1658,11 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
return 0;
size = cmd->header.size - sizeof(cmd->body);
- ret = vmw_compat_shader_add(sw_context->fp->shman,
+ ret = vmw_compat_shader_add(dev_priv,
+ vmw_context_res_man(val->res),
cmd->body.shid, cmd + 1,
cmd->body.type, size,
- sw_context->fp->tfile,
- &sw_context->staged_shaders);
+ &sw_context->staged_cmd_res);
if (unlikely(ret != 0))
return ret;
@@ -1672,23 +1690,24 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv,
SVGA3dCmdDestroyShader body;
} *cmd;
int ret;
+ struct vmw_resource_val_node *val;
cmd = container_of(header, struct vmw_shader_destroy_cmd,
header);
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
user_context_converter, &cmd->body.cid,
- NULL);
+ &val);
if (unlikely(ret != 0))
return ret;
if (unlikely(!dev_priv->has_mob))
return 0;
- ret = vmw_compat_shader_remove(sw_context->fp->shman,
+ ret = vmw_compat_shader_remove(vmw_context_res_man(val->res),
cmd->body.shid,
cmd->body.type,
- &sw_context->staged_shaders);
+ &sw_context->staged_cmd_res);
if (unlikely(ret != 0))
return ret;
@@ -1715,7 +1734,9 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
SVGA3dCmdHeader header;
SVGA3dCmdSetShader body;
} *cmd;
- struct vmw_resource_val_node *ctx_node;
+ struct vmw_resource_val_node *ctx_node, *res_node = NULL;
+ struct vmw_ctx_bindinfo bi;
+ struct vmw_resource *res = NULL;
int ret;
cmd = container_of(header, struct vmw_set_shader_cmd,
@@ -1727,32 +1748,40 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
if (unlikely(ret != 0))
return ret;
- if (dev_priv->has_mob) {
- struct vmw_ctx_bindinfo bi;
- struct vmw_resource_val_node *res_node;
- u32 shid = cmd->body.shid;
-
- if (shid != SVGA3D_INVALID_ID)
- (void) vmw_compat_shader_lookup(sw_context->fp->shman,
- cmd->body.type,
- &shid);
-
- ret = vmw_cmd_compat_res_check(dev_priv, sw_context,
- vmw_res_shader,
- user_shader_converter,
- shid,
- &cmd->body.shid, &res_node);
+ if (!dev_priv->has_mob)
+ return 0;
+
+ if (cmd->body.shid != SVGA3D_INVALID_ID) {
+ res = vmw_compat_shader_lookup
+ (vmw_context_res_man(ctx_node->res),
+ cmd->body.shid,
+ cmd->body.type);
+
+ if (!IS_ERR(res)) {
+ ret = vmw_cmd_res_reloc_add(dev_priv, sw_context,
+ vmw_res_shader,
+ &cmd->body.shid, res,
+ &res_node);
+ vmw_resource_unreference(&res);
+ if (unlikely(ret != 0))
+ return ret;
+ }
+ }
+
+ if (!res_node) {
+ ret = vmw_cmd_res_check(dev_priv, sw_context,
+ vmw_res_shader,
+ user_shader_converter,
+ &cmd->body.shid, &res_node);
if (unlikely(ret != 0))
return ret;
-
- bi.ctx = ctx_node->res;
- bi.res = res_node ? res_node->res : NULL;
- bi.bt = vmw_ctx_binding_shader;
- bi.i1.shader_type = cmd->body.type;
- return vmw_context_binding_add(ctx_node->staged_bindings, &bi);
}
- return 0;
+ bi.ctx = ctx_node->res;
+ bi.res = res_node ? res_node->res : NULL;
+ bi.bt = vmw_ctx_binding_shader;
+ bi.i1.shader_type = cmd->body.type;
+ return vmw_context_binding_add(ctx_node->staged_bindings, &bi);
}
/**
@@ -2394,6 +2423,8 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
}
}
+
+
int vmw_execbuf_process(struct drm_file *file_priv,
struct vmw_private *dev_priv,
void __user *user_commands,
@@ -2453,7 +2484,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
goto out_unlock;
sw_context->res_ht_initialized = true;
}
- INIT_LIST_HEAD(&sw_context->staged_shaders);
+ INIT_LIST_HEAD(&sw_context->staged_cmd_res);
INIT_LIST_HEAD(&resource_list);
ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
@@ -2548,8 +2579,7 @@ int vmw_execbuf_process(struct drm_file *file_priv,
}
list_splice_init(&sw_context->resource_list, &resource_list);
- vmw_compat_shaders_commit(sw_context->fp->shman,
- &sw_context->staged_shaders);
+ vmw_cmdbuf_res_commit(&sw_context->staged_cmd_res);
mutex_unlock(&dev_priv->cmdbuf_mutex);
/*
@@ -2576,8 +2606,7 @@ out_unlock:
list_splice_init(&sw_context->resource_list, &resource_list);
error_resource = sw_context->error_resource;
sw_context->error_resource = NULL;
- vmw_compat_shaders_revert(sw_context->fp->shman,
- &sw_context->staged_shaders);
+ vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res);
mutex_unlock(&dev_priv->cmdbuf_mutex);
/*
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index a89ad938eacf..b031b48dbb3c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -179,7 +179,6 @@ static int vmw_fb_set_par(struct fb_info *info)
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, info->var.yoffset);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
- vmw_write(vmw_priv, SVGA_REG_BYTES_PER_LINE, info->fix.line_length);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index b1273e8e9a69..26f8bdde3529 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -47,6 +47,7 @@ struct vmwgfx_gmrid_man {
static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *bo,
struct ttm_placement *placement,
+ uint32_t flags,
struct ttm_mem_reg *mem)
{
struct vmwgfx_gmrid_man *gman =
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 8f3edc4710f2..d2bc2b03d4c6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -75,7 +75,7 @@ void vmw_display_unit_cleanup(struct vmw_display_unit *du)
vmw_surface_unreference(&du->cursor_surface);
if (du->cursor_dmabuf)
vmw_dmabuf_unreference(&du->cursor_dmabuf);
- drm_sysfs_connector_remove(&du->connector);
+ drm_connector_unregister(&du->connector);
drm_crtc_cleanup(&du->crtc);
drm_encoder_cleanup(&du->encoder);
drm_connector_cleanup(&du->connector);
@@ -136,7 +136,7 @@ int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv,
kmap_offset = 0;
kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT;
- ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0);
+ ret = ttm_bo_reserve(&dmabuf->base, true, false, false, NULL);
if (unlikely(ret != 0)) {
DRM_ERROR("reserve failed\n");
return -EINVAL;
@@ -343,7 +343,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
kmap_num = (64*64*4) >> PAGE_SHIFT;
- ret = ttm_bo_reserve(bo, true, false, false, 0);
+ ret = ttm_bo_reserve(bo, true, false, false, NULL);
if (unlikely(ret != 0)) {
DRM_ERROR("reserve failed\n");
return;
@@ -1501,7 +1501,6 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
{
struct drm_vmw_cursor_bypass_arg *arg = data;
struct vmw_display_unit *du;
- struct drm_mode_object *obj;
struct drm_crtc *crtc;
int ret = 0;
@@ -1519,13 +1518,12 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
return 0;
}
- obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
- if (!obj) {
+ crtc = drm_crtc_find(dev, arg->crtc_id);
+ if (!crtc) {
ret = -ENOENT;
goto out;
}
- crtc = obj_to_crtc(obj);
du = vmw_crtc_to_du(crtc);
du->hotspot_x = arg->xhot;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index b2b9bd23aeee..15e185ae4c99 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -371,7 +371,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
encoder->possible_crtcs = (1 << unit);
encoder->possible_clones = 0;
- (void) drm_sysfs_connector_add(connector);
+ (void) drm_connector_register(connector);
drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_marker.c b/drivers/gpu/drm/vmwgfx/vmwgfx_marker.c
index 8a8725c2716c..efd1ffd68185 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_marker.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_marker.c
@@ -31,14 +31,14 @@
struct vmw_marker {
struct list_head head;
uint32_t seqno;
- struct timespec submitted;
+ u64 submitted;
};
void vmw_marker_queue_init(struct vmw_marker_queue *queue)
{
INIT_LIST_HEAD(&queue->head);
- queue->lag = ns_to_timespec(0);
- getrawmonotonic(&queue->lag_time);
+ queue->lag = 0;
+ queue->lag_time = ktime_get_raw_ns();
spin_lock_init(&queue->lock);
}
@@ -62,7 +62,7 @@ int vmw_marker_push(struct vmw_marker_queue *queue,
return -ENOMEM;
marker->seqno = seqno;
- getrawmonotonic(&marker->submitted);
+ marker->submitted = ktime_get_raw_ns();
spin_lock(&queue->lock);
list_add_tail(&marker->head, &queue->head);
spin_unlock(&queue->lock);
@@ -74,14 +74,14 @@ int vmw_marker_pull(struct vmw_marker_queue *queue,
uint32_t signaled_seqno)
{
struct vmw_marker *marker, *next;
- struct timespec now;
bool updated = false;
+ u64 now;
spin_lock(&queue->lock);
- getrawmonotonic(&now);
+ now = ktime_get_raw_ns();
if (list_empty(&queue->head)) {
- queue->lag = ns_to_timespec(0);
+ queue->lag = 0;
queue->lag_time = now;
updated = true;
goto out_unlock;
@@ -91,7 +91,7 @@ int vmw_marker_pull(struct vmw_marker_queue *queue,
if (signaled_seqno - marker->seqno > (1 << 30))
continue;
- queue->lag = timespec_sub(now, marker->submitted);
+ queue->lag = now - marker->submitted;
queue->lag_time = now;
updated = true;
list_del(&marker->head);
@@ -104,27 +104,13 @@ out_unlock:
return (updated) ? 0 : -EBUSY;
}
-static struct timespec vmw_timespec_add(struct timespec t1,
- struct timespec t2)
+static u64 vmw_fifo_lag(struct vmw_marker_queue *queue)
{
- t1.tv_sec += t2.tv_sec;
- t1.tv_nsec += t2.tv_nsec;
- if (t1.tv_nsec >= 1000000000L) {
- t1.tv_sec += 1;
- t1.tv_nsec -= 1000000000L;
- }
-
- return t1;
-}
-
-static struct timespec vmw_fifo_lag(struct vmw_marker_queue *queue)
-{
- struct timespec now;
+ u64 now;
spin_lock(&queue->lock);
- getrawmonotonic(&now);
- queue->lag = vmw_timespec_add(queue->lag,
- timespec_sub(now, queue->lag_time));
+ now = ktime_get_raw_ns();
+ queue->lag += now - queue->lag_time;
queue->lag_time = now;
spin_unlock(&queue->lock);
return queue->lag;
@@ -134,11 +120,9 @@ static struct timespec vmw_fifo_lag(struct vmw_marker_queue *queue)
static bool vmw_lag_lt(struct vmw_marker_queue *queue,
uint32_t us)
{
- struct timespec lag, cond;
+ u64 cond = (u64) us * NSEC_PER_USEC;
- cond = ns_to_timespec((s64) us * 1000);
- lag = vmw_fifo_lag(queue);
- return (timespec_compare(&lag, &cond) < 1);
+ return vmw_fifo_lag(queue) <= cond;
}
int vmw_wait_lag(struct vmw_private *dev_priv,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 01d68f0a69dc..a432c0db257c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -127,7 +127,7 @@ static void vmw_resource_release(struct kref *kref)
if (res->backup) {
struct ttm_buffer_object *bo = &res->backup->base;
- ttm_bo_reserve(bo, false, false, false, 0);
+ ttm_bo_reserve(bo, false, false, false, NULL);
if (!list_empty(&res->mob_head) &&
res->func->unbind != NULL) {
struct ttm_validate_buffer val_buf;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index a95d3a0cabe4..b295463a60b3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -467,7 +467,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
encoder->possible_crtcs = (1 << unit);
encoder->possible_clones = 0;
- (void) drm_sysfs_connector_add(connector);
+ (void) drm_connector_register(connector);
drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
index c1559eeaffe9..8719fb3cccc9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
@@ -29,8 +29,6 @@
#include "vmwgfx_resource_priv.h"
#include "ttm/ttm_placement.h"
-#define VMW_COMPAT_SHADER_HT_ORDER 12
-
struct vmw_shader {
struct vmw_resource res;
SVGA3dShaderType type;
@@ -42,49 +40,8 @@ struct vmw_user_shader {
struct vmw_shader shader;
};
-/**
- * enum vmw_compat_shader_state - Staging state for compat shaders
- */
-enum vmw_compat_shader_state {
- VMW_COMPAT_COMMITED,
- VMW_COMPAT_ADD,
- VMW_COMPAT_DEL
-};
-
-/**
- * struct vmw_compat_shader - Metadata for compat shaders.
- *
- * @handle: The TTM handle of the guest backed shader.
- * @tfile: The struct ttm_object_file the guest backed shader is registered
- * with.
- * @hash: Hash item for lookup.
- * @head: List head for staging lists or the compat shader manager list.
- * @state: Staging state.
- *
- * The structure is protected by the cmdbuf lock.
- */
-struct vmw_compat_shader {
- u32 handle;
- struct ttm_object_file *tfile;
- struct drm_hash_item hash;
- struct list_head head;
- enum vmw_compat_shader_state state;
-};
-
-/**
- * struct vmw_compat_shader_manager - Compat shader manager.
- *
- * @shaders: Hash table containing staged and commited compat shaders
- * @list: List of commited shaders.
- * @dev_priv: Pointer to a device private structure.
- *
- * @shaders and @list are protected by the cmdbuf mutex for now.
- */
-struct vmw_compat_shader_manager {
- struct drm_open_hash shaders;
- struct list_head list;
- struct vmw_private *dev_priv;
-};
+static uint64_t vmw_user_shader_size;
+static uint64_t vmw_shader_size;
static void vmw_user_shader_free(struct vmw_resource *res);
static struct vmw_resource *
@@ -98,8 +55,6 @@ static int vmw_gb_shader_unbind(struct vmw_resource *res,
struct ttm_validate_buffer *val_buf);
static int vmw_gb_shader_destroy(struct vmw_resource *res);
-static uint64_t vmw_user_shader_size;
-
static const struct vmw_user_resource_conv user_shader_conv = {
.object_type = VMW_RES_SHADER,
.base_obj_to_res = vmw_user_shader_base_to_res,
@@ -347,6 +302,16 @@ static void vmw_user_shader_free(struct vmw_resource *res)
vmw_user_shader_size);
}
+static void vmw_shader_free(struct vmw_resource *res)
+{
+ struct vmw_shader *shader = vmw_res_to_shader(res);
+ struct vmw_private *dev_priv = res->dev_priv;
+
+ kfree(shader);
+ ttm_mem_global_free(vmw_mem_glob(dev_priv),
+ vmw_shader_size);
+}
+
/**
* This function is called when user space has no more references on the
* base object. It releases the base-object's reference on the resource object.
@@ -371,13 +336,13 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data,
TTM_REF_USAGE);
}
-static int vmw_shader_alloc(struct vmw_private *dev_priv,
- struct vmw_dma_buffer *buffer,
- size_t shader_size,
- size_t offset,
- SVGA3dShaderType shader_type,
- struct ttm_object_file *tfile,
- u32 *handle)
+static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
+ struct vmw_dma_buffer *buffer,
+ size_t shader_size,
+ size_t offset,
+ SVGA3dShaderType shader_type,
+ struct ttm_object_file *tfile,
+ u32 *handle)
{
struct vmw_user_shader *ushader;
struct vmw_resource *res, *tmp;
@@ -442,6 +407,56 @@ out:
}
+struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
+ struct vmw_dma_buffer *buffer,
+ size_t shader_size,
+ size_t offset,
+ SVGA3dShaderType shader_type)
+{
+ struct vmw_shader *shader;
+ struct vmw_resource *res;
+ int ret;
+
+ /*
+ * Approximate idr memory usage with 128 bytes. It will be limited
+ * by maximum number_of shaders anyway.
+ */
+ if (unlikely(vmw_shader_size == 0))
+ vmw_shader_size =
+ ttm_round_pot(sizeof(struct vmw_shader)) + 128;
+
+ ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
+ vmw_shader_size,
+ false, true);
+ if (unlikely(ret != 0)) {
+ if (ret != -ERESTARTSYS)
+ DRM_ERROR("Out of graphics memory for shader "
+ "creation.\n");
+ goto out_err;
+ }
+
+ shader = kzalloc(sizeof(*shader), GFP_KERNEL);
+ if (unlikely(shader == NULL)) {
+ ttm_mem_global_free(vmw_mem_glob(dev_priv),
+ vmw_shader_size);
+ ret = -ENOMEM;
+ goto out_err;
+ }
+
+ res = &shader->res;
+
+ /*
+ * From here on, the destructor takes over resource freeing.
+ */
+ ret = vmw_gb_shader_init(dev_priv, res, shader_size,
+ offset, shader_type, buffer,
+ vmw_shader_free);
+
+out_err:
+ return ret ? ERR_PTR(ret) : res;
+}
+
+
int vmw_shader_define_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -490,8 +505,8 @@ int vmw_shader_define_ioctl(struct drm_device *dev, void *data,
if (unlikely(ret != 0))
goto out_bad_arg;
- ret = vmw_shader_alloc(dev_priv, buffer, arg->size, arg->offset,
- shader_type, tfile, &arg->shader_handle);
+ ret = vmw_user_shader_alloc(dev_priv, buffer, arg->size, arg->offset,
+ shader_type, tfile, &arg->shader_handle);
ttm_read_unlock(&dev_priv->reservation_sem);
out_bad_arg:
@@ -500,202 +515,83 @@ out_bad_arg:
}
/**
- * vmw_compat_shader_lookup - Look up a compat shader
- *
- * @man: Pointer to the compat shader manager.
- * @shader_type: The shader type, that combined with the user_key identifies
- * the shader.
- * @user_key: On entry, this should be a pointer to the user_key.
- * On successful exit, it will contain the guest-backed shader's TTM handle.
+ * vmw_compat_shader_id_ok - Check whether a compat shader user key and
+ * shader type are within valid bounds.
*
- * Returns 0 on success. Non-zero on failure, in which case the value pointed
- * to by @user_key is unmodified.
- */
-int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man,
- SVGA3dShaderType shader_type,
- u32 *user_key)
-{
- struct drm_hash_item *hash;
- int ret;
- unsigned long key = *user_key | (shader_type << 24);
-
- ret = drm_ht_find_item(&man->shaders, key, &hash);
- if (unlikely(ret != 0))
- return ret;
-
- *user_key = drm_hash_entry(hash, struct vmw_compat_shader,
- hash)->handle;
-
- return 0;
-}
-
-/**
- * vmw_compat_shader_free - Free a compat shader.
- *
- * @man: Pointer to the compat shader manager.
- * @entry: Pointer to a struct vmw_compat_shader.
- *
- * Frees a struct vmw_compat_shder entry and drops its reference to the
- * guest backed shader.
- */
-static void vmw_compat_shader_free(struct vmw_compat_shader_manager *man,
- struct vmw_compat_shader *entry)
-{
- list_del(&entry->head);
- WARN_ON(drm_ht_remove_item(&man->shaders, &entry->hash));
- WARN_ON(ttm_ref_object_base_unref(entry->tfile, entry->handle,
- TTM_REF_USAGE));
- kfree(entry);
-}
-
-/**
- * vmw_compat_shaders_commit - Commit a list of compat shader actions.
- *
- * @man: Pointer to the compat shader manager.
- * @list: Caller's list of compat shader actions.
+ * @user_key: User space id of the shader.
+ * @shader_type: Shader type.
*
- * This function commits a list of compat shader additions or removals.
- * It is typically called when the execbuf ioctl call triggering these
- * actions has commited the fifo contents to the device.
+ * Returns true if valid false if not.
*/
-void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man,
- struct list_head *list)
+static bool vmw_compat_shader_id_ok(u32 user_key, SVGA3dShaderType shader_type)
{
- struct vmw_compat_shader *entry, *next;
-
- list_for_each_entry_safe(entry, next, list, head) {
- list_del(&entry->head);
- switch (entry->state) {
- case VMW_COMPAT_ADD:
- entry->state = VMW_COMPAT_COMMITED;
- list_add_tail(&entry->head, &man->list);
- break;
- case VMW_COMPAT_DEL:
- ttm_ref_object_base_unref(entry->tfile, entry->handle,
- TTM_REF_USAGE);
- kfree(entry);
- break;
- default:
- BUG();
- break;
- }
- }
+ return user_key <= ((1 << 20) - 1) && (unsigned) shader_type < 16;
}
/**
- * vmw_compat_shaders_revert - Revert a list of compat shader actions
+ * vmw_compat_shader_key - Compute a hash key suitable for a compat shader.
*
- * @man: Pointer to the compat shader manager.
- * @list: Caller's list of compat shader actions.
+ * @user_key: User space id of the shader.
+ * @shader_type: Shader type.
*
- * This function reverts a list of compat shader additions or removals.
- * It is typically called when the execbuf ioctl call triggering these
- * actions failed for some reason, and the command stream was never
- * submitted.
+ * Returns a hash key suitable for a command buffer managed resource
+ * manager hash table.
*/
-void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man,
- struct list_head *list)
+static u32 vmw_compat_shader_key(u32 user_key, SVGA3dShaderType shader_type)
{
- struct vmw_compat_shader *entry, *next;
- int ret;
-
- list_for_each_entry_safe(entry, next, list, head) {
- switch (entry->state) {
- case VMW_COMPAT_ADD:
- vmw_compat_shader_free(man, entry);
- break;
- case VMW_COMPAT_DEL:
- ret = drm_ht_insert_item(&man->shaders, &entry->hash);
- list_del(&entry->head);
- list_add_tail(&entry->head, &man->list);
- entry->state = VMW_COMPAT_COMMITED;
- break;
- default:
- BUG();
- break;
- }
- }
+ return user_key | (shader_type << 20);
}
/**
* vmw_compat_shader_remove - Stage a compat shader for removal.
*
- * @man: Pointer to the compat shader manager
+ * @man: Pointer to the compat shader manager identifying the shader namespace.
* @user_key: The key that is used to identify the shader. The key is
* unique to the shader type.
* @shader_type: Shader type.
- * @list: Caller's list of staged shader actions.
- *
- * This function stages a compat shader for removal and removes the key from
- * the shader manager's hash table. If the shader was previously only staged
- * for addition it is completely removed (But the execbuf code may keep a
- * reference if it was bound to a context between addition and removal). If
- * it was previously commited to the manager, it is staged for removal.
+ * @list: Caller's list of staged command buffer resource actions.
*/
-int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man,
+int vmw_compat_shader_remove(struct vmw_cmdbuf_res_manager *man,
u32 user_key, SVGA3dShaderType shader_type,
struct list_head *list)
{
- struct vmw_compat_shader *entry;
- struct drm_hash_item *hash;
- int ret;
-
- ret = drm_ht_find_item(&man->shaders, user_key | (shader_type << 24),
- &hash);
- if (likely(ret != 0))
+ if (!vmw_compat_shader_id_ok(user_key, shader_type))
return -EINVAL;
- entry = drm_hash_entry(hash, struct vmw_compat_shader, hash);
-
- switch (entry->state) {
- case VMW_COMPAT_ADD:
- vmw_compat_shader_free(man, entry);
- break;
- case VMW_COMPAT_COMMITED:
- (void) drm_ht_remove_item(&man->shaders, &entry->hash);
- list_del(&entry->head);
- entry->state = VMW_COMPAT_DEL;
- list_add_tail(&entry->head, list);
- break;
- default:
- BUG();
- break;
- }
-
- return 0;
+ return vmw_cmdbuf_res_remove(man, vmw_cmdbuf_res_compat_shader,
+ vmw_compat_shader_key(user_key,
+ shader_type),
+ list);
}
/**
- * vmw_compat_shader_add - Create a compat shader and add the
- * key to the manager
+ * vmw_compat_shader_add - Create a compat shader and stage it for addition
+ * as a command buffer managed resource.
*
- * @man: Pointer to the compat shader manager
+ * @man: Pointer to the compat shader manager identifying the shader namespace.
* @user_key: The key that is used to identify the shader. The key is
* unique to the shader type.
* @bytecode: Pointer to the bytecode of the shader.
* @shader_type: Shader type.
* @tfile: Pointer to a struct ttm_object_file that the guest-backed shader is
* to be created with.
- * @list: Caller's list of staged shader actions.
+ * @list: Caller's list of staged command buffer resource actions.
*
- * Note that only the key is added to the shader manager's hash table.
- * The shader is not yet added to the shader manager's list of shaders.
*/
-int vmw_compat_shader_add(struct vmw_compat_shader_manager *man,
+int vmw_compat_shader_add(struct vmw_private *dev_priv,
+ struct vmw_cmdbuf_res_manager *man,
u32 user_key, const void *bytecode,
SVGA3dShaderType shader_type,
size_t size,
- struct ttm_object_file *tfile,
struct list_head *list)
{
struct vmw_dma_buffer *buf;
struct ttm_bo_kmap_obj map;
bool is_iomem;
- struct vmw_compat_shader *compat;
- u32 handle;
int ret;
+ struct vmw_resource *res;
- if (user_key > ((1 << 24) - 1) || (unsigned) shader_type > 16)
+ if (!vmw_compat_shader_id_ok(user_key, shader_type))
return -EINVAL;
/* Allocate and pin a DMA buffer */
@@ -703,7 +599,7 @@ int vmw_compat_shader_add(struct vmw_compat_shader_manager *man,
if (unlikely(buf == NULL))
return -ENOMEM;
- ret = vmw_dmabuf_init(man->dev_priv, buf, size, &vmw_sys_ne_placement,
+ ret = vmw_dmabuf_init(dev_priv, buf, size, &vmw_sys_ne_placement,
true, vmw_dmabuf_bo_free);
if (unlikely(ret != 0))
goto out;
@@ -728,84 +624,40 @@ int vmw_compat_shader_add(struct vmw_compat_shader_manager *man,
WARN_ON(ret != 0);
ttm_bo_unreserve(&buf->base);
- /* Create a guest-backed shader container backed by the dma buffer */
- ret = vmw_shader_alloc(man->dev_priv, buf, size, 0, shader_type,
- tfile, &handle);
- vmw_dmabuf_unreference(&buf);
+ res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type);
if (unlikely(ret != 0))
goto no_reserve;
- /*
- * Create a compat shader structure and stage it for insertion
- * in the manager
- */
- compat = kzalloc(sizeof(*compat), GFP_KERNEL);
- if (compat == NULL)
- goto no_compat;
-
- compat->hash.key = user_key | (shader_type << 24);
- ret = drm_ht_insert_item(&man->shaders, &compat->hash);
- if (unlikely(ret != 0))
- goto out_invalid_key;
-
- compat->state = VMW_COMPAT_ADD;
- compat->handle = handle;
- compat->tfile = tfile;
- list_add_tail(&compat->head, list);
-
- return 0;
-out_invalid_key:
- kfree(compat);
-no_compat:
- ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE);
+ ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_compat_shader,
+ vmw_compat_shader_key(user_key, shader_type),
+ res, list);
+ vmw_resource_unreference(&res);
no_reserve:
+ vmw_dmabuf_unreference(&buf);
out:
return ret;
}
/**
- * vmw_compat_shader_man_create - Create a compat shader manager
- *
- * @dev_priv: Pointer to a device private structure.
- *
- * Typically done at file open time. If successful returns a pointer to a
- * compat shader manager. Otherwise returns an error pointer.
- */
-struct vmw_compat_shader_manager *
-vmw_compat_shader_man_create(struct vmw_private *dev_priv)
-{
- struct vmw_compat_shader_manager *man;
- int ret;
-
- man = kzalloc(sizeof(*man), GFP_KERNEL);
- if (man == NULL)
- return ERR_PTR(-ENOMEM);
-
- man->dev_priv = dev_priv;
- INIT_LIST_HEAD(&man->list);
- ret = drm_ht_create(&man->shaders, VMW_COMPAT_SHADER_HT_ORDER);
- if (ret == 0)
- return man;
-
- kfree(man);
- return ERR_PTR(ret);
-}
-
-/**
- * vmw_compat_shader_man_destroy - Destroy a compat shader manager
+ * vmw_compat_shader_lookup - Look up a compat shader
*
- * @man: Pointer to the shader manager to destroy.
+ * @man: Pointer to the command buffer managed resource manager identifying
+ * the shader namespace.
+ * @user_key: The user space id of the shader.
+ * @shader_type: The shader type.
*
- * Typically done at file close time.
+ * Returns a refcounted pointer to a struct vmw_resource if the shader was
+ * found. An error pointer otherwise.
*/
-void vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man)
+struct vmw_resource *
+vmw_compat_shader_lookup(struct vmw_cmdbuf_res_manager *man,
+ u32 user_key,
+ SVGA3dShaderType shader_type)
{
- struct vmw_compat_shader *entry, *next;
-
- mutex_lock(&man->dev_priv->cmdbuf_mutex);
- list_for_each_entry_safe(entry, next, &man->list, head)
- vmw_compat_shader_free(man, entry);
+ if (!vmw_compat_shader_id_ok(user_key, shader_type))
+ return ERR_PTR(-EINVAL);
- mutex_unlock(&man->dev_priv->cmdbuf_mutex);
- kfree(man);
+ return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_compat_shader,
+ vmw_compat_shader_key(user_key,
+ shader_type));
}
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index 112f27e51bc7..63bd63f3c7df 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -185,16 +185,16 @@ static unsigned int pin_job(struct host1x_job *job)
struct sg_table *sgt;
dma_addr_t phys_addr;
- reloc->target = host1x_bo_get(reloc->target);
- if (!reloc->target)
+ reloc->target.bo = host1x_bo_get(reloc->target.bo);
+ if (!reloc->target.bo)
goto unpin;
- phys_addr = host1x_bo_pin(reloc->target, &sgt);
+ phys_addr = host1x_bo_pin(reloc->target.bo, &sgt);
if (!phys_addr)
goto unpin;
job->addr_phys[job->num_unpins] = phys_addr;
- job->unpins[job->num_unpins].bo = reloc->target;
+ job->unpins[job->num_unpins].bo = reloc->target.bo;
job->unpins[job->num_unpins].sgt = sgt;
job->num_unpins++;
}
@@ -235,21 +235,21 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf)
for (i = 0; i < job->num_relocs; i++) {
struct host1x_reloc *reloc = &job->relocarray[i];
u32 reloc_addr = (job->reloc_addr_phys[i] +
- reloc->target_offset) >> reloc->shift;
+ reloc->target.offset) >> reloc->shift;
u32 *target;
/* skip all other gathers */
- if (cmdbuf != reloc->cmdbuf)
+ if (cmdbuf != reloc->cmdbuf.bo)
continue;
- if (last_page != reloc->cmdbuf_offset >> PAGE_SHIFT) {
+ if (last_page != reloc->cmdbuf.offset >> PAGE_SHIFT) {
if (cmdbuf_page_addr)
host1x_bo_kunmap(cmdbuf, last_page,
cmdbuf_page_addr);
cmdbuf_page_addr = host1x_bo_kmap(cmdbuf,
- reloc->cmdbuf_offset >> PAGE_SHIFT);
- last_page = reloc->cmdbuf_offset >> PAGE_SHIFT;
+ reloc->cmdbuf.offset >> PAGE_SHIFT);
+ last_page = reloc->cmdbuf.offset >> PAGE_SHIFT;
if (unlikely(!cmdbuf_page_addr)) {
pr_err("Could not map cmdbuf for relocation\n");
@@ -257,7 +257,7 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf)
}
}
- target = cmdbuf_page_addr + (reloc->cmdbuf_offset & ~PAGE_MASK);
+ target = cmdbuf_page_addr + (reloc->cmdbuf.offset & ~PAGE_MASK);
*target = reloc_addr;
}
@@ -272,7 +272,7 @@ static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
{
offset *= sizeof(u32);
- if (reloc->cmdbuf != cmdbuf || reloc->cmdbuf_offset != offset)
+ if (reloc->cmdbuf.bo != cmdbuf || reloc->cmdbuf.offset != offset)
return false;
return true;
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index af0259708358..d2077f040f3e 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -237,12 +237,10 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
if (conflict->locks & lwants)
return conflict;
- /* Ok, now check if he owns the resource we want. We don't need
- * to check "decodes" since it should be impossible to own
- * own legacy resources you don't decode unless I have a bug
- * in this code...
+ /* Ok, now check if it owns the resource we want. We can
+ * lock resources that are not decoded, therefore a device
+ * can own resources it doesn't decode.
*/
- WARN_ON(conflict->owns & ~conflict->decodes);
match = lwants & conflict->owns;
if (!match)
continue;
@@ -254,13 +252,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
flags = 0;
pci_bits = 0;
+ /* If we can't control legacy resources via the bridge, we
+ * also need to disable normal decoding.
+ */
if (!conflict->bridge_has_one_vga) {
- vga_irq_set_state(conflict, false);
- flags |= PCI_VGA_STATE_CHANGE_DECODES;
- if (match & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+ if ((match & conflict->decodes) & VGA_RSRC_LEGACY_MEM)
pci_bits |= PCI_COMMAND_MEMORY;
- if (match & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+ if ((match & conflict->decodes) & VGA_RSRC_LEGACY_IO)
pci_bits |= PCI_COMMAND_IO;
+
+ if (pci_bits) {
+ vga_irq_set_state(conflict, false);
+ flags |= PCI_VGA_STATE_CHANGE_DECODES;
+ }
}
if (change_bridge)
@@ -268,18 +272,19 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev,
pci_set_vga_state(conflict->pdev, false, pci_bits, flags);
conflict->owns &= ~match;
- /* If he also owned non-legacy, that is no longer the case */
- if (match & VGA_RSRC_LEGACY_MEM)
+
+ /* If we disabled normal decoding, reflect it in owns */
+ if (pci_bits & PCI_COMMAND_MEMORY)
conflict->owns &= ~VGA_RSRC_NORMAL_MEM;
- if (match & VGA_RSRC_LEGACY_IO)
+ if (pci_bits & PCI_COMMAND_IO)
conflict->owns &= ~VGA_RSRC_NORMAL_IO;
}
enable_them:
/* ok dude, we got it, everybody conflicting has been disabled, let's
- * enable us. Make sure we don't mark a bit in "owns" that we don't
- * also have in "decodes". We can lock resources we don't decode but
- * not own them.
+ * enable us. Mark any bits in "owns" regardless of whether we
+ * decoded them. We can lock resources we don't decode, therefore
+ * we must track them via "owns".
*/
flags = 0;
pci_bits = 0;
@@ -291,7 +296,7 @@ enable_them:
if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
pci_bits |= PCI_COMMAND_IO;
}
- if (!!(wants & VGA_RSRC_LEGACY_MASK))
+ if (wants & VGA_RSRC_LEGACY_MASK)
flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
pci_set_vga_state(vgadev->pdev, true, pci_bits, flags);
@@ -299,7 +304,7 @@ enable_them:
if (!vgadev->bridge_has_one_vga) {
vga_irq_set_state(vgadev, true);
}
- vgadev->owns |= (wants & vgadev->decodes);
+ vgadev->owns |= wants;
lock_them:
vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
if (rsrc & VGA_RSRC_LEGACY_IO)
@@ -649,7 +654,6 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev,
old_decodes = vgadev->decodes;
decodes_removed = ~new_decodes & old_decodes;
decodes_unlocked = vgadev->locks & decodes_removed;
- vgadev->owns &= ~decodes_removed;
vgadev->decodes = new_decodes;
pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n",
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 800c8b60f7a2..ec48c823b157 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -261,6 +261,20 @@ config HOLTEK_FF
Say Y here if you have a Holtek On Line Grip based game controller
and want to have force feedback support for it.
+config HID_GT683R
+ tristate "MSI GT68xR LED support"
+ depends on LEDS_CLASS && USB_HID
+ ---help---
+ Say Y here if you want to enable support for the three MSI GT68xR LEDs
+
+ This driver support following modes:
+ - Normal: LEDs are fully on when enabled
+ - Audio: LEDs brightness depends on sound level
+ - Breathing: LEDs brightness varies at human breathing rate
+
+ Currently the following devices are know to be supported:
+ - MSI GT683R
+
config HID_HUION
tristate "Huion tablets"
depends on USB_HID
@@ -331,18 +345,20 @@ config HID_LCPOWER
---help---
Support for LC-Power RC1000MCE RF remote control.
-config HID_LENOVO_TPKBD
- tristate "Lenovo ThinkPad USB Keyboard with TrackPoint"
+config HID_LENOVO
+ tristate "Lenovo / Thinkpad devices"
depends on HID
select NEW_LEDS
select LEDS_CLASS
---help---
- Support for the Lenovo ThinkPad USB Keyboard with TrackPoint.
+ Support for Lenovo devices that are not fully compliant with HID standard.
- Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint
- and would like to use device-specific features like changing the
- sensitivity of the trackpoint, using the microphone mute button or
- controlling the mute and microphone mute LEDs.
+ Say Y if you want support for the non-compliant features of the Lenovo
+ Thinkpad standalone keyboards, e.g:
+ - ThinkPad USB Keyboard with TrackPoint (supports extra LEDs and trackpoint
+ configuration)
+ - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys)
+ - ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys)
config HID_LOGITECH
tristate "Logitech devices" if EXPERT
@@ -785,7 +801,7 @@ config HID_XINMO
depends on HID
---help---
Support for Xin-Mo devices that are not fully compliant with the HID
- standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
+ standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
if you have a Xin-Mo Dual Arcade controller.
config HID_ZEROPLUS
@@ -810,7 +826,7 @@ config HID_ZYDACRON
config HID_SENSOR_HUB
tristate "HID Sensors framework support"
- depends on HID
+ depends on HID && HAS_IOMEM
select MFD_CORE
default n
---help---
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a6fa6baf368e..a69f0adb5c76 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_ELO) += hid-elo.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
+obj-$(CONFIG_HID_GT683R) += hid-gt683r.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o
@@ -59,7 +60,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
-obj-$(CONFIG_HID_LENOVO_TPKBD) += hid-lenovo-tpkbd.o
+obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8ed66fd1ea87..b52baa120ffa 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -783,7 +783,9 @@ static int hid_scan_report(struct hid_device *hid)
* Vendor specific handlings
*/
if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) &&
- (hid->group == HID_GROUP_GENERIC))
+ (hid->group == HID_GROUP_GENERIC) &&
+ /* only bind to the mouse interface of composite USB devices */
+ (hid->bus != BUS_USB || hid->type == HID_TYPE_USBMOUSE))
/* hid-rmi should take care of them, not hid-generic */
hid->group = HID_GROUP_RMI;
@@ -1782,7 +1784,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
@@ -1796,8 +1798,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
-#if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD)
+#if IS_ENABLED(CONFIG_HID_LENOVO)
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
#endif
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1845,6 +1849,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2) },
@@ -2266,6 +2271,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_GN9350E) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
index 56be85a9a77c..a822db5a8338 100644
--- a/drivers/hid/hid-cp2112.c
+++ b/drivers/hid/hid-cp2112.c
@@ -240,8 +240,6 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
u8 buf[5];
int ret;
- cp2112_gpio_set(chip, offset, value);
-
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
sizeof(buf), HID_FEATURE_REPORT,
HID_REQ_GET_REPORT);
@@ -260,6 +258,12 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
return ret;
}
+ /*
+ * Set gpio value when output direction is already set,
+ * as specified in AN495, Rev. 0.2, cpt. 4.4
+ */
+ cp2112_gpio_set(chip, offset, value);
+
return 0;
}
@@ -425,6 +429,105 @@ static int cp2112_write_req(void *buf, u8 slave_address, u8 command, u8 *data,
return data_length + 4;
}
+static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data,
+ u8 data_length)
+{
+ struct cp2112_write_req_report *report = buf;
+
+ if (data_length > sizeof(report->data))
+ return -EINVAL;
+
+ report->report = CP2112_DATA_WRITE_REQUEST;
+ report->slave_address = slave_address << 1;
+ report->length = data_length;
+ memcpy(report->data, data, data_length);
+ return data_length + 3;
+}
+
+static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
+ struct hid_device *hdev = dev->hdev;
+ u8 buf[64];
+ ssize_t count;
+ unsigned int retries;
+ int ret;
+
+ hid_dbg(hdev, "I2C %d messages\n", num);
+
+ if (num != 1) {
+ hid_err(hdev,
+ "Multi-message I2C transactions not supported\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (msgs->flags & I2C_M_RD)
+ count = cp2112_read_req(buf, msgs->addr, msgs->len);
+ else
+ count = cp2112_i2c_write_req(buf, msgs->addr, msgs->buf,
+ msgs->len);
+
+ if (count < 0)
+ return count;
+
+ ret = hid_hw_power(hdev, PM_HINT_FULLON);
+ if (ret < 0) {
+ hid_err(hdev, "power management error: %d\n", ret);
+ return ret;
+ }
+
+ ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
+ if (ret < 0) {
+ hid_warn(hdev, "Error starting transaction: %d\n", ret);
+ goto power_normal;
+ }
+
+ for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
+ ret = cp2112_xfer_status(dev);
+ if (-EBUSY == ret)
+ continue;
+ if (ret < 0)
+ goto power_normal;
+ break;
+ }
+
+ if (XFER_STATUS_RETRIES <= retries) {
+ hid_warn(hdev, "Transfer timed out, cancelling.\n");
+ buf[0] = CP2112_CANCEL_TRANSFER;
+ buf[1] = 0x01;
+
+ ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
+ if (ret < 0)
+ hid_warn(hdev, "Error cancelling transaction: %d\n",
+ ret);
+
+ ret = -ETIMEDOUT;
+ goto power_normal;
+ }
+
+ if (!(msgs->flags & I2C_M_RD))
+ goto finish;
+
+ ret = cp2112_read(dev, msgs->buf, msgs->len);
+ if (ret < 0)
+ goto power_normal;
+ if (ret != msgs->len) {
+ hid_warn(hdev, "short read: %d < %d\n", ret, msgs->len);
+ ret = -EIO;
+ goto power_normal;
+ }
+
+finish:
+ /* return the number of transferred messages */
+ ret = 1;
+
+power_normal:
+ hid_hw_power(hdev, PM_HINT_NORMAL);
+ hid_dbg(hdev, "I2C transfer finished: %d\n", ret);
+ return ret;
+}
+
static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data)
@@ -591,7 +694,8 @@ power_normal:
static u32 cp2112_functionality(struct i2c_adapter *adap)
{
- return I2C_FUNC_SMBUS_BYTE |
+ return I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA |
@@ -601,6 +705,7 @@ static u32 cp2112_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm smbus_algorithm = {
+ .master_xfer = cp2112_i2c_xfer,
.smbus_xfer = cp2112_xfer,
.functionality = cp2112_functionality,
};
diff --git a/drivers/hid/hid-gt683r.c b/drivers/hid/hid-gt683r.c
new file mode 100644
index 000000000000..0d6f135e266c
--- /dev/null
+++ b/drivers/hid/hid-gt683r.c
@@ -0,0 +1,321 @@
+/*
+ * MSI GT683R led driver
+ *
+ * Copyright (c) 2014 Janne Kanniainen <janne.kanniainen@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.
+ *
+ * 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/device.h>
+#include <linux/hid.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define GT683R_BUFFER_SIZE 8
+
+/*
+ * GT683R_LED_OFF: all LEDs are off
+ * GT683R_LED_AUDIO: LEDs brightness depends on sound level
+ * GT683R_LED_BREATHING: LEDs brightness varies at human breathing rate
+ * GT683R_LED_NORMAL: LEDs are fully on when enabled
+ */
+enum gt683r_led_mode {
+ GT683R_LED_OFF = 0,
+ GT683R_LED_AUDIO = 2,
+ GT683R_LED_BREATHING = 3,
+ GT683R_LED_NORMAL = 5
+};
+
+enum gt683r_panels {
+ GT683R_LED_BACK = 0,
+ GT683R_LED_SIDE = 1,
+ GT683R_LED_FRONT = 2,
+ GT683R_LED_COUNT,
+};
+
+static const char * const gt683r_panel_names[] = {
+ "back",
+ "side",
+ "front",
+};
+
+struct gt683r_led {
+ struct hid_device *hdev;
+ struct led_classdev led_devs[GT683R_LED_COUNT];
+ struct mutex lock;
+ struct work_struct work;
+ enum led_brightness brightnesses[GT683R_LED_COUNT];
+ enum gt683r_led_mode mode;
+};
+
+static const struct hid_device_id gt683r_led_id[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
+ { }
+};
+
+static void gt683r_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ int i;
+ struct device *dev = led_cdev->dev->parent;
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct gt683r_led *led = hid_get_drvdata(hdev);
+
+ for (i = 0; i < GT683R_LED_COUNT; i++) {
+ if (led_cdev == &led->led_devs[i])
+ break;
+ }
+
+ if (i < GT683R_LED_COUNT) {
+ led->brightnesses[i] = brightness;
+ schedule_work(&led->work);
+ }
+}
+
+static ssize_t mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 sysfs_mode;
+ struct hid_device *hdev = container_of(dev->parent,
+ struct hid_device, dev);
+ struct gt683r_led *led = hid_get_drvdata(hdev);
+
+ if (led->mode == GT683R_LED_NORMAL)
+ sysfs_mode = 0;
+ else if (led->mode == GT683R_LED_AUDIO)
+ sysfs_mode = 1;
+ else
+ sysfs_mode = 2;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", sysfs_mode);
+}
+
+static ssize_t mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u8 sysfs_mode;
+ struct hid_device *hdev = container_of(dev->parent,
+ struct hid_device, dev);
+ struct gt683r_led *led = hid_get_drvdata(hdev);
+
+
+ if (kstrtou8(buf, 10, &sysfs_mode) || sysfs_mode > 2)
+ return -EINVAL;
+
+ mutex_lock(&led->lock);
+
+ if (sysfs_mode == 0)
+ led->mode = GT683R_LED_NORMAL;
+ else if (sysfs_mode == 1)
+ led->mode = GT683R_LED_AUDIO;
+ else
+ led->mode = GT683R_LED_BREATHING;
+
+ mutex_unlock(&led->lock);
+ schedule_work(&led->work);
+
+ return count;
+}
+
+static int gt683r_led_snd_msg(struct gt683r_led *led, u8 *msg)
+{
+ int ret;
+
+ ret = hid_hw_raw_request(led->hdev, msg[0], msg, GT683R_BUFFER_SIZE,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+ if (ret != GT683R_BUFFER_SIZE) {
+ hid_err(led->hdev,
+ "failed to send set report request: %i\n", ret);
+ if (ret < 0)
+ return ret;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int gt683r_leds_set(struct gt683r_led *led, u8 leds)
+{
+ int ret;
+ u8 *buffer;
+
+ buffer = kzalloc(GT683R_BUFFER_SIZE, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ buffer[0] = 0x01;
+ buffer[1] = 0x02;
+ buffer[2] = 0x30;
+ buffer[3] = leds;
+ ret = gt683r_led_snd_msg(led, buffer);
+
+ kfree(buffer);
+ return ret;
+}
+
+static int gt683r_mode_set(struct gt683r_led *led, u8 mode)
+{
+ int ret;
+ u8 *buffer;
+
+ buffer = kzalloc(GT683R_BUFFER_SIZE, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ buffer[0] = 0x01;
+ buffer[1] = 0x02;
+ buffer[2] = 0x20;
+ buffer[3] = mode;
+ buffer[4] = 0x01;
+ ret = gt683r_led_snd_msg(led, buffer);
+
+ kfree(buffer);
+ return ret;
+}
+
+static void gt683r_led_work(struct work_struct *work)
+{
+ int i;
+ u8 leds = 0;
+ u8 mode;
+ struct gt683r_led *led = container_of(work, struct gt683r_led, work);
+
+ mutex_lock(&led->lock);
+
+ for (i = 0; i < GT683R_LED_COUNT; i++) {
+ if (led->brightnesses[i])
+ leds |= BIT(i);
+ }
+
+ if (gt683r_leds_set(led, leds))
+ goto fail;
+
+ if (leds)
+ mode = led->mode;
+ else
+ mode = GT683R_LED_OFF;
+
+ gt683r_mode_set(led, mode);
+fail:
+ mutex_unlock(&led->lock);
+}
+
+static DEVICE_ATTR_RW(mode);
+
+static struct attribute *gt683r_led_attrs[] = {
+ &dev_attr_mode.attr,
+ NULL
+};
+
+static const struct attribute_group gt683r_led_group = {
+ .name = "gt683r",
+ .attrs = gt683r_led_attrs,
+};
+
+static const struct attribute_group *gt683r_led_groups[] = {
+ &gt683r_led_group,
+ NULL
+};
+
+static int gt683r_led_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ int i;
+ int ret;
+ int name_sz;
+ char *name;
+ struct gt683r_led *led;
+
+ led = devm_kzalloc(&hdev->dev, sizeof(*led), GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ mutex_init(&led->lock);
+ INIT_WORK(&led->work, gt683r_led_work);
+
+ led->mode = GT683R_LED_NORMAL;
+ led->hdev = hdev;
+ hid_set_drvdata(hdev, led);
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "hid parsing failed\n");
+ return ret;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < GT683R_LED_COUNT; i++) {
+ name_sz = strlen(dev_name(&hdev->dev)) +
+ strlen(gt683r_panel_names[i]) + 3;
+
+ name = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
+ if (!name) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ snprintf(name, name_sz, "%s::%s",
+ dev_name(&hdev->dev), gt683r_panel_names[i]);
+ led->led_devs[i].name = name;
+ led->led_devs[i].max_brightness = 1;
+ led->led_devs[i].brightness_set = gt683r_brightness_set;
+ led->led_devs[i].groups = gt683r_led_groups;
+
+ ret = led_classdev_register(&hdev->dev, &led->led_devs[i]);
+ if (ret) {
+ hid_err(hdev, "could not register led device\n");
+ goto fail;
+ }
+ }
+
+ return 0;
+
+fail:
+ for (i = i - 1; i >= 0; i--)
+ led_classdev_unregister(&led->led_devs[i]);
+ hid_hw_stop(hdev);
+ return ret;
+}
+
+static void gt683r_led_remove(struct hid_device *hdev)
+{
+ int i;
+ struct gt683r_led *led = hid_get_drvdata(hdev);
+
+ for (i = 0; i < GT683R_LED_COUNT; i++)
+ led_classdev_unregister(&led->led_devs[i]);
+ flush_work(&led->work);
+ hid_hw_stop(hdev);
+}
+
+static struct hid_driver gt683r_led_driver = {
+ .probe = gt683r_led_probe,
+ .remove = gt683r_led_remove,
+ .name = "gt683r_led",
+ .id_table = gt683r_led_id,
+};
+
+module_hid_driver(gt683r_led_driver);
+
+MODULE_AUTHOR("Janne Kanniainen");
+MODULE_DESCRIPTION("MSI GT683R led driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c
index cbf4da4689ba..60f44cd1b0ed 100644
--- a/drivers/hid/hid-huion.c
+++ b/drivers/hid/hid-huion.c
@@ -2,6 +2,7 @@
* HID driver for Huion devices not fully compliant with HID standard
*
* Copyright (c) 2013 Martin Rusko
+ * Copyright (c) 2014 Nikolai Kondrashov
*/
/*
@@ -15,67 +16,89 @@
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/usb.h>
+#include <asm/unaligned.h>
#include "usbhid/usbhid.h"
#include "hid-ids.h"
-/* Original Huion 580 report descriptor size */
-#define HUION_580_RDESC_ORIG_SIZE 177
-
-/* Fixed Huion 580 report descriptor */
-static __u8 huion_580_rdesc_fixed[] = {
- 0x05, 0x0D, /* Usage Page (Digitizer), */
- 0x09, 0x02, /* Usage (Pen), */
- 0xA1, 0x01, /* Collection (Application), */
- 0x85, 0x07, /* Report ID (7), */
- 0x09, 0x20, /* Usage (Stylus), */
- 0xA0, /* Collection (Physical), */
- 0x14, /* Logical Minimum (0), */
- 0x25, 0x01, /* Logical Maximum (1), */
- 0x75, 0x01, /* Report Size (1), */
- 0x09, 0x42, /* Usage (Tip Switch), */
- 0x09, 0x44, /* Usage (Barrel Switch), */
- 0x09, 0x46, /* Usage (Tablet Pick), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x03, /* Report Count (3), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x09, 0x32, /* Usage (In Range), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x02, /* Input (Variable), */
- 0x95, 0x01, /* Report Count (1), */
- 0x81, 0x03, /* Input (Constant, Variable), */
- 0x75, 0x10, /* Report Size (16), */
- 0x95, 0x01, /* Report Count (1), */
- 0xA4, /* Push, */
- 0x05, 0x01, /* Usage Page (Desktop), */
- 0x65, 0x13, /* Unit (Inch), */
- 0x55, 0xFD, /* Unit Exponent (-3), */
- 0x34, /* Physical Minimum (0), */
- 0x09, 0x30, /* Usage (X), */
- 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
- 0x26, 0x00, 0x7D, /* Logical Maximum (32000), */
- 0x81, 0x02, /* Input (Variable), */
- 0x09, 0x31, /* Usage (Y), */
- 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
- 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
- 0x81, 0x02, /* Input (Variable), */
- 0xB4, /* Pop, */
- 0x09, 0x30, /* Usage (Tip Pressure), */
- 0x26, 0xFF, 0x07, /* Logical Maximum (2047), */
- 0x81, 0x02, /* Input (Variable), */
- 0xC0, /* End Collection, */
- 0xC0 /* End Collection */
+/* Report descriptor template placeholder head */
+#define HUION_PH_HEAD 0xFE, 0xED, 0x1D
+
+/* Report descriptor template placeholder IDs */
+enum huion_ph_id {
+ HUION_PH_ID_X_LM,
+ HUION_PH_ID_X_PM,
+ HUION_PH_ID_Y_LM,
+ HUION_PH_ID_Y_PM,
+ HUION_PH_ID_PRESSURE_LM,
+ HUION_PH_ID_NUM
+};
+
+/* Report descriptor template placeholder */
+#define HUION_PH(_ID) HUION_PH_HEAD, HUION_PH_ID_##_ID
+
+/* Fixed report descriptor template */
+static const __u8 huion_tablet_rdesc_template[] = {
+ 0x05, 0x0D, /* Usage Page (Digitizer), */
+ 0x09, 0x02, /* Usage (Pen), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0x85, 0x07, /* Report ID (7), */
+ 0x09, 0x20, /* Usage (Stylus), */
+ 0xA0, /* Collection (Physical), */
+ 0x14, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x09, 0x42, /* Usage (Tip Switch), */
+ 0x09, 0x44, /* Usage (Barrel Switch), */
+ 0x09, 0x46, /* Usage (Tablet Pick), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x03, /* Report Count (3), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x09, 0x32, /* Usage (In Range), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0xA4, /* Push, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x65, 0x13, /* Unit (Inch), */
+ 0x55, 0xFD, /* Unit Exponent (-3), */
+ 0x34, /* Physical Minimum (0), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x27, HUION_PH(X_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x47, HUION_PH(X_PM), /* Physical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x27, HUION_PH(Y_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x47, HUION_PH(Y_PM), /* Physical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xB4, /* Pop, */
+ 0x09, 0x30, /* Usage (Tip Pressure), */
+ 0x27,
+ HUION_PH(PRESSURE_LM), /* Logical Maximum (PLACEHOLDER), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
+};
+
+/* Driver data */
+struct huion_drvdata {
+ __u8 *rdesc;
+ unsigned int rsize;
};
static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
+ struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
switch (hdev->product) {
- case USB_DEVICE_ID_HUION_580:
- if (*rsize == HUION_580_RDESC_ORIG_SIZE) {
- rdesc = huion_580_rdesc_fixed;
- *rsize = sizeof(huion_580_rdesc_fixed);
+ case USB_DEVICE_ID_HUION_TABLET:
+ if (drvdata->rdesc != NULL) {
+ rdesc = drvdata->rdesc;
+ *rsize = drvdata->rsize;
}
break;
}
@@ -83,82 +106,144 @@ static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
}
/**
- * Enable fully-functional tablet mode by reading special string
- * descriptor.
+ * Enable fully-functional tablet mode and determine device parameters.
*
* @hdev: HID device
- *
- * The specific string descriptor and data were discovered by sniffing
- * the Windows driver traffic.
*/
static int huion_tablet_enable(struct hid_device *hdev)
{
int rc;
- char buf[22];
+ struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+ struct huion_drvdata *drvdata = hid_get_drvdata(hdev);
+ __le16 buf[6];
- rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf));
- if (rc < 0)
- return rc;
+ /*
+ * Read string descriptor containing tablet parameters. The specific
+ * string descriptor and data were discovered by sniffing the Windows
+ * driver traffic.
+ * NOTE: This enables fully-functional tablet mode.
+ */
+ rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (USB_DT_STRING << 8) + 0x64,
+ 0x0409, buf, sizeof(buf),
+ USB_CTRL_GET_TIMEOUT);
+ if (rc == -EPIPE)
+ hid_warn(hdev, "device parameters not found\n");
+ else if (rc < 0)
+ hid_warn(hdev, "failed to get device parameters: %d\n", rc);
+ else if (rc != sizeof(buf))
+ hid_warn(hdev, "invalid device parameters\n");
+ else {
+ s32 params[HUION_PH_ID_NUM];
+ s32 resolution;
+ __u8 *p;
+ s32 v;
+
+ /* Extract device parameters */
+ params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]);
+ params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]);
+ params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]);
+ resolution = le16_to_cpu(buf[5]);
+ if (resolution == 0) {
+ params[HUION_PH_ID_X_PM] = 0;
+ params[HUION_PH_ID_Y_PM] = 0;
+ } else {
+ params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] *
+ 1000 / resolution;
+ params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] *
+ 1000 / resolution;
+ }
+
+ /* Allocate fixed report descriptor */
+ drvdata->rdesc = devm_kmalloc(&hdev->dev,
+ sizeof(huion_tablet_rdesc_template),
+ GFP_KERNEL);
+ if (drvdata->rdesc == NULL) {
+ hid_err(hdev, "failed to allocate fixed rdesc\n");
+ return -ENOMEM;
+ }
+ drvdata->rsize = sizeof(huion_tablet_rdesc_template);
+
+ /* Format fixed report descriptor */
+ memcpy(drvdata->rdesc, huion_tablet_rdesc_template,
+ drvdata->rsize);
+ for (p = drvdata->rdesc;
+ p <= drvdata->rdesc + drvdata->rsize - 4;) {
+ if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D &&
+ p[3] < sizeof(params)) {
+ v = params[p[3]];
+ put_unaligned(cpu_to_le32(v), (s32 *)p);
+ p += 4;
+ } else {
+ p++;
+ }
+ }
+ }
return 0;
}
static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
- int ret;
+ int rc;
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+ struct huion_drvdata *drvdata;
+
+ /* Allocate and assign driver data */
+ drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (drvdata == NULL) {
+ hid_err(hdev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+ hid_set_drvdata(hdev, drvdata);
- /* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet,
- * as they are not used
- */
switch (id->product) {
- case USB_DEVICE_ID_HUION_580:
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00)
- return -ENODEV;
+ case USB_DEVICE_ID_HUION_TABLET:
+ /* If this is the pen interface */
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+ rc = huion_tablet_enable(hdev);
+ if (rc) {
+ hid_err(hdev, "tablet enabling failed\n");
+ return rc;
+ }
+ }
break;
}
- ret = hid_parse(hdev);
- if (ret) {
+ rc = hid_parse(hdev);
+ if (rc) {
hid_err(hdev, "parse failed\n");
- goto err;
+ return rc;
}
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
+ rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (rc) {
hid_err(hdev, "hw start failed\n");
- goto err;
- }
-
- switch (id->product) {
- case USB_DEVICE_ID_HUION_580:
- ret = huion_tablet_enable(hdev);
- if (ret) {
- hid_err(hdev, "tablet enabling failed\n");
- goto enabling_err;
- }
- break;
+ return rc;
}
return 0;
-enabling_err:
- hid_hw_stop(hdev);
-err:
- return ret;
}
static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
u8 *data, int size)
{
- /* If this is a pen input report then invert the in-range bit */
- if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2)
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
+ /* If this is a pen input report */
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 0 &&
+ report->type == HID_INPUT_REPORT &&
+ report->id == 0x07 && size >= 2)
+ /* Invert the in-range bit */
data[1] ^= 0x40;
return 0;
}
static const struct hid_device_id huion_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_TABLET) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_HUION_TABLET) },
{ }
};
MODULE_DEVICE_TABLE(hid, huion_devices);
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index f52dbcb7133b..31fad641b744 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -308,6 +308,9 @@ static void mousevsc_on_receive(struct hv_device *device,
memcpy(input_dev->input_buf, input_report->buffer, len);
hid_input_report(input_dev->hid_device, HID_INPUT_REPORT,
input_dev->input_buf, len, 1);
+
+ pm_wakeup_event(&input_dev->device->device, 0);
+
break;
default:
pr_err("unsupported hid msg type - type %d len %d",
@@ -549,6 +552,8 @@ static int mousevsc_probe(struct hv_device *device,
goto probe_err2;
}
+ device_init_wakeup(&device->device, true);
+
input_dev->connected = true;
input_dev->init_complete = true;
@@ -571,6 +576,7 @@ static int mousevsc_remove(struct hv_device *dev)
{
struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
+ device_init_wakeup(&dev->device, false);
vmbus_close(dev->channel);
hid_hw_stop(input_dev->hid_device);
hid_destroy_device(input_dev->hid_device);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 6d00bb9366fa..25cd674d6064 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -323,6 +323,7 @@
#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
+#define USB_DEVICE_ID_ETURBOTOUCH_2968 0x2968
#define USB_VENDOR_ID_EZKEY 0x0518
#define USB_DEVICE_ID_BTC_8193 0x0002
@@ -447,7 +448,7 @@
#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
#define USB_VENDOR_ID_HUION 0x256c
-#define USB_DEVICE_ID_HUION_580 0x006e
+#define USB_DEVICE_ID_HUION_TABLET 0x006e
#define USB_VENDOR_ID_IDEACOM 0x1cb6
#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
@@ -478,6 +479,7 @@
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A070 0xa070
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
+#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096
#define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_DISC_STAKKA 0xd000
@@ -488,6 +490,7 @@
#define USB_VENDOR_ID_JABRA 0x0b0e
#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412
#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420
+#define USB_DEVICE_ID_JABRA_GN9350E 0x9350
#define USB_VENDOR_ID_JESS 0x0c45
#define USB_DEVICE_ID_JESS_YUREX 0x1010
@@ -560,6 +563,8 @@
#define USB_VENDOR_ID_LENOVO 0x17ef
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
+#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
+#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
#define USB_VENDOR_ID_LG 0x1fd2
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
@@ -645,7 +650,7 @@
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
#define USB_VENDOR_ID_MSI 0x1770
-#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00
+#define USB_DEVICE_ID_MSI_GT683R_LED_PANEL 0xff00
#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
#define USB_DEVICE_ID_N_S_HARMONY 0xc359
@@ -715,6 +720,8 @@
#define USB_VENDOR_ID_PENMOUNT 0x14e1
#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500
+#define USB_DEVICE_ID_PENMOUNT_1610 0x1610
+#define USB_DEVICE_ID_PENMOUNT_1640 0x1640
#define USB_VENDOR_ID_PETALYNX 0x18b1
#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c
deleted file mode 100644
index 2d25b6cbbc05..000000000000
--- a/drivers/hid/hid-lenovo-tpkbd.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * HID driver for Lenovo ThinkPad USB Keyboard with TrackPoint
- *
- * Copyright (c) 2012 Bernhard Seibold
- */
-
-/*
- * 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/module.h>
-#include <linux/sysfs.h>
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/input.h>
-#include <linux/leds.h>
-
-#include "hid-ids.h"
-
-/* This is only used for the trackpoint part of the driver, hence _tp */
-struct tpkbd_data_pointer {
- int led_state;
- struct led_classdev led_mute;
- struct led_classdev led_micmute;
- int press_to_select;
- int dragging;
- int release_to_select;
- int select_right;
- int sensitivity;
- int press_speed;
-};
-
-#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
-
-static int tpkbd_input_mapping(struct hid_device *hdev,
- struct hid_input *hi, struct hid_field *field,
- struct hid_usage *usage, unsigned long **bit, int *max)
-{
- if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
- /* mark the device as pointer */
- hid_set_drvdata(hdev, (void *)1);
- map_key_clear(KEY_MICMUTE);
- return 1;
- }
- return 0;
-}
-
-#undef map_key_clear
-
-static int tpkbd_features_set(struct hid_device *hdev)
-{
- struct hid_report *report;
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
-
- report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
- report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
- report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
- report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
- report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
- report->field[2]->value[0] = data_pointer->sensitivity;
- report->field[3]->value[0] = data_pointer->press_speed;
-
- hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
- return 0;
-}
-
-static ssize_t pointer_press_to_select_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
-}
-
-static ssize_t pointer_press_to_select_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value))
- return -EINVAL;
- if (value < 0 || value > 1)
- return -EINVAL;
-
- data_pointer->press_to_select = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static ssize_t pointer_dragging_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
-}
-
-static ssize_t pointer_dragging_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value))
- return -EINVAL;
- if (value < 0 || value > 1)
- return -EINVAL;
-
- data_pointer->dragging = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static ssize_t pointer_release_to_select_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
-}
-
-static ssize_t pointer_release_to_select_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value))
- return -EINVAL;
- if (value < 0 || value > 1)
- return -EINVAL;
-
- data_pointer->release_to_select = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static ssize_t pointer_select_right_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
-}
-
-static ssize_t pointer_select_right_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value))
- return -EINVAL;
- if (value < 0 || value > 1)
- return -EINVAL;
-
- data_pointer->select_right = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static ssize_t pointer_sensitivity_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- data_pointer->sensitivity);
-}
-
-static ssize_t pointer_sensitivity_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
- return -EINVAL;
-
- data_pointer->sensitivity = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static ssize_t pointer_press_speed_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n",
- data_pointer->press_speed);
-}
-
-static ssize_t pointer_press_speed_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int value;
-
- if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
- return -EINVAL;
-
- data_pointer->press_speed = value;
- tpkbd_features_set(hdev);
-
- return count;
-}
-
-static struct device_attribute dev_attr_pointer_press_to_select =
- __ATTR(press_to_select, S_IWUSR | S_IRUGO,
- pointer_press_to_select_show,
- pointer_press_to_select_store);
-
-static struct device_attribute dev_attr_pointer_dragging =
- __ATTR(dragging, S_IWUSR | S_IRUGO,
- pointer_dragging_show,
- pointer_dragging_store);
-
-static struct device_attribute dev_attr_pointer_release_to_select =
- __ATTR(release_to_select, S_IWUSR | S_IRUGO,
- pointer_release_to_select_show,
- pointer_release_to_select_store);
-
-static struct device_attribute dev_attr_pointer_select_right =
- __ATTR(select_right, S_IWUSR | S_IRUGO,
- pointer_select_right_show,
- pointer_select_right_store);
-
-static struct device_attribute dev_attr_pointer_sensitivity =
- __ATTR(sensitivity, S_IWUSR | S_IRUGO,
- pointer_sensitivity_show,
- pointer_sensitivity_store);
-
-static struct device_attribute dev_attr_pointer_press_speed =
- __ATTR(press_speed, S_IWUSR | S_IRUGO,
- pointer_press_speed_show,
- pointer_press_speed_store);
-
-static struct attribute *tpkbd_attributes_pointer[] = {
- &dev_attr_pointer_press_to_select.attr,
- &dev_attr_pointer_dragging.attr,
- &dev_attr_pointer_release_to_select.attr,
- &dev_attr_pointer_select_right.attr,
- &dev_attr_pointer_sensitivity.attr,
- &dev_attr_pointer_press_speed.attr,
- NULL
-};
-
-static const struct attribute_group tpkbd_attr_group_pointer = {
- .attrs = tpkbd_attributes_pointer,
-};
-
-static enum led_brightness tpkbd_led_brightness_get(
- struct led_classdev *led_cdev)
-{
- struct device *dev = led_cdev->dev->parent;
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- int led_nr = 0;
-
- if (led_cdev == &data_pointer->led_micmute)
- led_nr = 1;
-
- return data_pointer->led_state & (1 << led_nr)
- ? LED_FULL
- : LED_OFF;
-}
-
-static void tpkbd_led_brightness_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct device *dev = led_cdev->dev->parent;
- struct hid_device *hdev = container_of(dev, struct hid_device, dev);
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
- struct hid_report *report;
- int led_nr = 0;
-
- if (led_cdev == &data_pointer->led_micmute)
- led_nr = 1;
-
- if (value == LED_OFF)
- data_pointer->led_state &= ~(1 << led_nr);
- else
- data_pointer->led_state |= 1 << led_nr;
-
- report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
- report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
- report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
- hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
-}
-
-static int tpkbd_probe_tp(struct hid_device *hdev)
-{
- struct device *dev = &hdev->dev;
- struct tpkbd_data_pointer *data_pointer;
- size_t name_sz = strlen(dev_name(dev)) + 16;
- char *name_mute, *name_micmute;
- int i;
-
- /* Validate required reports. */
- for (i = 0; i < 4; i++) {
- if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
- return -ENODEV;
- }
- if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
- return -ENODEV;
-
- if (sysfs_create_group(&hdev->dev.kobj,
- &tpkbd_attr_group_pointer)) {
- hid_warn(hdev, "Could not create sysfs group\n");
- }
-
- data_pointer = devm_kzalloc(&hdev->dev,
- sizeof(struct tpkbd_data_pointer),
- GFP_KERNEL);
- if (data_pointer == NULL) {
- hid_err(hdev, "Could not allocate memory for driver data\n");
- return -ENOMEM;
- }
-
- // set same default values as windows driver
- data_pointer->sensitivity = 0xa0;
- data_pointer->press_speed = 0x38;
-
- name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
- name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
- if (name_mute == NULL || name_micmute == NULL) {
- hid_err(hdev, "Could not allocate memory for led data\n");
- return -ENOMEM;
- }
- snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
- snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
-
- hid_set_drvdata(hdev, data_pointer);
-
- data_pointer->led_mute.name = name_mute;
- data_pointer->led_mute.brightness_get = tpkbd_led_brightness_get;
- data_pointer->led_mute.brightness_set = tpkbd_led_brightness_set;
- data_pointer->led_mute.dev = dev;
- led_classdev_register(dev, &data_pointer->led_mute);
-
- data_pointer->led_micmute.name = name_micmute;
- data_pointer->led_micmute.brightness_get = tpkbd_led_brightness_get;
- data_pointer->led_micmute.brightness_set = tpkbd_led_brightness_set;
- data_pointer->led_micmute.dev = dev;
- led_classdev_register(dev, &data_pointer->led_micmute);
-
- tpkbd_features_set(hdev);
-
- return 0;
-}
-
-static int tpkbd_probe(struct hid_device *hdev,
- const struct hid_device_id *id)
-{
- int ret;
-
- ret = hid_parse(hdev);
- if (ret) {
- hid_err(hdev, "hid_parse failed\n");
- goto err;
- }
-
- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret) {
- hid_err(hdev, "hid_hw_start failed\n");
- goto err;
- }
-
- if (hid_get_drvdata(hdev)) {
- hid_set_drvdata(hdev, NULL);
- ret = tpkbd_probe_tp(hdev);
- if (ret)
- goto err_hid;
- }
-
- return 0;
-err_hid:
- hid_hw_stop(hdev);
-err:
- return ret;
-}
-
-static void tpkbd_remove_tp(struct hid_device *hdev)
-{
- struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev);
-
- sysfs_remove_group(&hdev->dev.kobj,
- &tpkbd_attr_group_pointer);
-
- led_classdev_unregister(&data_pointer->led_micmute);
- led_classdev_unregister(&data_pointer->led_mute);
-
- hid_set_drvdata(hdev, NULL);
-}
-
-static void tpkbd_remove(struct hid_device *hdev)
-{
- if (hid_get_drvdata(hdev))
- tpkbd_remove_tp(hdev);
-
- hid_hw_stop(hdev);
-}
-
-static const struct hid_device_id tpkbd_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
- { }
-};
-
-MODULE_DEVICE_TABLE(hid, tpkbd_devices);
-
-static struct hid_driver tpkbd_driver = {
- .name = "lenovo_tpkbd",
- .id_table = tpkbd_devices,
- .input_mapping = tpkbd_input_mapping,
- .probe = tpkbd_probe,
- .remove = tpkbd_remove,
-};
-module_hid_driver(tpkbd_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
new file mode 100644
index 000000000000..bf227f7679af
--- /dev/null
+++ b/drivers/hid/hid-lenovo.c
@@ -0,0 +1,708 @@
+/*
+ * HID driver for Lenovo:
+ * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
+ * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
+ * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
+ *
+ * Copyright (c) 2012 Bernhard Seibold
+ * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
+ */
+
+/*
+ * 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/module.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include "hid-ids.h"
+
+struct lenovo_drvdata_tpkbd {
+ int led_state;
+ struct led_classdev led_mute;
+ struct led_classdev led_micmute;
+ int press_to_select;
+ int dragging;
+ int release_to_select;
+ int select_right;
+ int sensitivity;
+ int press_speed;
+};
+
+struct lenovo_drvdata_cptkbd {
+ bool fn_lock;
+};
+
+#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
+
+static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
+ struct hid_input *hi, struct hid_field *field,
+ struct hid_usage *usage, unsigned long **bit, int *max)
+{
+ if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
+ /* This sub-device contains trackpoint, mark it */
+ hid_set_drvdata(hdev, (void *)1);
+ map_key_clear(KEY_MICMUTE);
+ return 1;
+ }
+ return 0;
+}
+
+static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
+ struct hid_input *hi, struct hid_field *field,
+ struct hid_usage *usage, unsigned long **bit, int *max)
+{
+ /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */
+ if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR ||
+ (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) {
+ set_bit(EV_REP, hi->input->evbit);
+ switch (usage->hid & HID_USAGE) {
+ case 0x00f1: /* Fn-F4: Mic mute */
+ map_key_clear(KEY_MICMUTE);
+ return 1;
+ case 0x00f2: /* Fn-F5: Brightness down */
+ map_key_clear(KEY_BRIGHTNESSDOWN);
+ return 1;
+ case 0x00f3: /* Fn-F6: Brightness up */
+ map_key_clear(KEY_BRIGHTNESSUP);
+ return 1;
+ case 0x00f4: /* Fn-F7: External display (projector) */
+ map_key_clear(KEY_SWITCHVIDEOMODE);
+ return 1;
+ case 0x00f5: /* Fn-F8: Wireless */
+ map_key_clear(KEY_WLAN);
+ return 1;
+ case 0x00f6: /* Fn-F9: Control panel */
+ map_key_clear(KEY_CONFIG);
+ return 1;
+ case 0x00f8: /* Fn-F11: View open applications (3 boxes) */
+ map_key_clear(KEY_SCALE);
+ return 1;
+ case 0x00fa: /* Fn-Esc: Fn-lock toggle */
+ map_key_clear(KEY_FN_ESC);
+ return 1;
+ case 0x00fb: /* Fn-F12: Open My computer (6 boxes) USB-only */
+ /* NB: This mapping is invented in raw_event below */
+ map_key_clear(KEY_FILE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int lenovo_input_mapping(struct hid_device *hdev,
+ struct hid_input *hi, struct hid_field *field,
+ struct hid_usage *usage, unsigned long **bit, int *max)
+{
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LENOVO_TPKBD:
+ return lenovo_input_mapping_tpkbd(hdev, hi, field,
+ usage, bit, max);
+ case USB_DEVICE_ID_LENOVO_CUSBKBD:
+ case USB_DEVICE_ID_LENOVO_CBTKBD:
+ return lenovo_input_mapping_cptkbd(hdev, hi, field,
+ usage, bit, max);
+ default:
+ return 0;
+ }
+}
+
+#undef map_key_clear
+
+/* Send a config command to the keyboard */
+static int lenovo_send_cmd_cptkbd(struct hid_device *hdev,
+ unsigned char byte2, unsigned char byte3)
+{
+ int ret;
+ unsigned char buf[] = {0x18, byte2, byte3};
+
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LENOVO_CUSBKBD:
+ ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+ break;
+ case USB_DEVICE_ID_LENOVO_CBTKBD:
+ ret = hid_hw_output_report(hdev, buf, sizeof(buf));
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */
+}
+
+static void lenovo_features_set_cptkbd(struct hid_device *hdev)
+{
+ int ret;
+ struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
+
+ ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
+ if (ret)
+ hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
+}
+
+static ssize_t attr_fn_lock_show_cptkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock);
+}
+
+static ssize_t attr_fn_lock_store_cptkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value))
+ return -EINVAL;
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ cptkbd_data->fn_lock = !!value;
+ lenovo_features_set_cptkbd(hdev);
+
+ return count;
+}
+
+static struct device_attribute dev_attr_fn_lock_cptkbd =
+ __ATTR(fn_lock, S_IWUSR | S_IRUGO,
+ attr_fn_lock_show_cptkbd,
+ attr_fn_lock_store_cptkbd);
+
+static struct attribute *lenovo_attributes_cptkbd[] = {
+ &dev_attr_fn_lock_cptkbd.attr,
+ NULL
+};
+
+static const struct attribute_group lenovo_attr_group_cptkbd = {
+ .attrs = lenovo_attributes_cptkbd,
+};
+
+static int lenovo_raw_event(struct hid_device *hdev,
+ struct hid_report *report, u8 *data, int size)
+{
+ /*
+ * Compact USB keyboard's Fn-F12 report holds down many other keys, and
+ * its own key is outside the usage page range. Remove extra
+ * keypresses and remap to inside usage page.
+ */
+ if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
+ && size == 3
+ && data[0] == 0x15
+ && data[1] == 0x94
+ && data[2] == 0x01)) {
+ data[1] = 0x0;
+ data[2] = 0x4;
+ }
+
+ return 0;
+}
+
+static int lenovo_features_set_tpkbd(struct hid_device *hdev)
+{
+ struct hid_report *report;
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
+
+ report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
+ report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
+ report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
+ report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
+ report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
+ report->field[2]->value[0] = data_pointer->sensitivity;
+ report->field[3]->value[0] = data_pointer->press_speed;
+
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+ return 0;
+}
+
+static ssize_t attr_press_to_select_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
+}
+
+static ssize_t attr_press_to_select_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value))
+ return -EINVAL;
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ data_pointer->press_to_select = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static ssize_t attr_dragging_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
+}
+
+static ssize_t attr_dragging_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value))
+ return -EINVAL;
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ data_pointer->dragging = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static ssize_t attr_release_to_select_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
+}
+
+static ssize_t attr_release_to_select_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value))
+ return -EINVAL;
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ data_pointer->release_to_select = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static ssize_t attr_select_right_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
+}
+
+static ssize_t attr_select_right_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value))
+ return -EINVAL;
+ if (value < 0 || value > 1)
+ return -EINVAL;
+
+ data_pointer->select_right = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static ssize_t attr_sensitivity_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data_pointer->sensitivity);
+}
+
+static ssize_t attr_sensitivity_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
+ return -EINVAL;
+
+ data_pointer->sensitivity = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static ssize_t attr_press_speed_show_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data_pointer->press_speed);
+}
+
+static ssize_t attr_press_speed_store_tpkbd(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int value;
+
+ if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
+ return -EINVAL;
+
+ data_pointer->press_speed = value;
+ lenovo_features_set_tpkbd(hdev);
+
+ return count;
+}
+
+static struct device_attribute dev_attr_press_to_select_tpkbd =
+ __ATTR(press_to_select, S_IWUSR | S_IRUGO,
+ attr_press_to_select_show_tpkbd,
+ attr_press_to_select_store_tpkbd);
+
+static struct device_attribute dev_attr_dragging_tpkbd =
+ __ATTR(dragging, S_IWUSR | S_IRUGO,
+ attr_dragging_show_tpkbd,
+ attr_dragging_store_tpkbd);
+
+static struct device_attribute dev_attr_release_to_select_tpkbd =
+ __ATTR(release_to_select, S_IWUSR | S_IRUGO,
+ attr_release_to_select_show_tpkbd,
+ attr_release_to_select_store_tpkbd);
+
+static struct device_attribute dev_attr_select_right_tpkbd =
+ __ATTR(select_right, S_IWUSR | S_IRUGO,
+ attr_select_right_show_tpkbd,
+ attr_select_right_store_tpkbd);
+
+static struct device_attribute dev_attr_sensitivity_tpkbd =
+ __ATTR(sensitivity, S_IWUSR | S_IRUGO,
+ attr_sensitivity_show_tpkbd,
+ attr_sensitivity_store_tpkbd);
+
+static struct device_attribute dev_attr_press_speed_tpkbd =
+ __ATTR(press_speed, S_IWUSR | S_IRUGO,
+ attr_press_speed_show_tpkbd,
+ attr_press_speed_store_tpkbd);
+
+static struct attribute *lenovo_attributes_tpkbd[] = {
+ &dev_attr_press_to_select_tpkbd.attr,
+ &dev_attr_dragging_tpkbd.attr,
+ &dev_attr_release_to_select_tpkbd.attr,
+ &dev_attr_select_right_tpkbd.attr,
+ &dev_attr_sensitivity_tpkbd.attr,
+ &dev_attr_press_speed_tpkbd.attr,
+ NULL
+};
+
+static const struct attribute_group lenovo_attr_group_tpkbd = {
+ .attrs = lenovo_attributes_tpkbd,
+};
+
+static enum led_brightness lenovo_led_brightness_get_tpkbd(
+ struct led_classdev *led_cdev)
+{
+ struct device *dev = led_cdev->dev->parent;
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ int led_nr = 0;
+
+ if (led_cdev == &data_pointer->led_micmute)
+ led_nr = 1;
+
+ return data_pointer->led_state & (1 << led_nr)
+ ? LED_FULL
+ : LED_OFF;
+}
+
+static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct device *dev = led_cdev->dev->parent;
+ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+ struct hid_report *report;
+ int led_nr = 0;
+
+ if (led_cdev == &data_pointer->led_micmute)
+ led_nr = 1;
+
+ if (value == LED_OFF)
+ data_pointer->led_state &= ~(1 << led_nr);
+ else
+ data_pointer->led_state |= 1 << led_nr;
+
+ report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
+ report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
+ report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+}
+
+static int lenovo_probe_tpkbd(struct hid_device *hdev)
+{
+ struct device *dev = &hdev->dev;
+ struct lenovo_drvdata_tpkbd *data_pointer;
+ size_t name_sz = strlen(dev_name(dev)) + 16;
+ char *name_mute, *name_micmute;
+ int i;
+ int ret;
+
+ /*
+ * Only register extra settings against subdevice where input_mapping
+ * set drvdata to 1, i.e. the trackpoint.
+ */
+ if (!hid_get_drvdata(hdev))
+ return 0;
+
+ hid_set_drvdata(hdev, NULL);
+
+ /* Validate required reports. */
+ for (i = 0; i < 4; i++) {
+ if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
+ return -ENODEV;
+ }
+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
+ return -ENODEV;
+
+ ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd);
+ if (ret)
+ hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
+
+ data_pointer = devm_kzalloc(&hdev->dev,
+ sizeof(struct lenovo_drvdata_tpkbd),
+ GFP_KERNEL);
+ if (data_pointer == NULL) {
+ hid_err(hdev, "Could not allocate memory for driver data\n");
+ return -ENOMEM;
+ }
+
+ // set same default values as windows driver
+ data_pointer->sensitivity = 0xa0;
+ data_pointer->press_speed = 0x38;
+
+ name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
+ name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
+ if (name_mute == NULL || name_micmute == NULL) {
+ hid_err(hdev, "Could not allocate memory for led data\n");
+ return -ENOMEM;
+ }
+ snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
+ snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
+
+ hid_set_drvdata(hdev, data_pointer);
+
+ data_pointer->led_mute.name = name_mute;
+ data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
+ data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
+ data_pointer->led_mute.dev = dev;
+ led_classdev_register(dev, &data_pointer->led_mute);
+
+ data_pointer->led_micmute.name = name_micmute;
+ data_pointer->led_micmute.brightness_get =
+ lenovo_led_brightness_get_tpkbd;
+ data_pointer->led_micmute.brightness_set =
+ lenovo_led_brightness_set_tpkbd;
+ data_pointer->led_micmute.dev = dev;
+ led_classdev_register(dev, &data_pointer->led_micmute);
+
+ lenovo_features_set_tpkbd(hdev);
+
+ return 0;
+}
+
+static int lenovo_probe_cptkbd(struct hid_device *hdev)
+{
+ int ret;
+ struct lenovo_drvdata_cptkbd *cptkbd_data;
+
+ /* All the custom action happens on the USBMOUSE device for USB */
+ if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
+ && hdev->type != HID_TYPE_USBMOUSE) {
+ hid_dbg(hdev, "Ignoring keyboard half of device\n");
+ return 0;
+ }
+
+ cptkbd_data = devm_kzalloc(&hdev->dev,
+ sizeof(*cptkbd_data),
+ GFP_KERNEL);
+ if (cptkbd_data == NULL) {
+ hid_err(hdev, "can't alloc keyboard descriptor\n");
+ return -ENOMEM;
+ }
+ hid_set_drvdata(hdev, cptkbd_data);
+
+ /*
+ * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
+ * regular keys
+ */
+ ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
+ if (ret)
+ hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
+
+ /* Turn Fn-Lock on by default */
+ cptkbd_data->fn_lock = true;
+ lenovo_features_set_cptkbd(hdev);
+
+ ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
+ if (ret)
+ hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
+
+ return 0;
+}
+
+static int lenovo_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ int ret;
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "hid_parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ hid_err(hdev, "hid_hw_start failed\n");
+ goto err;
+ }
+
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LENOVO_TPKBD:
+ ret = lenovo_probe_tpkbd(hdev);
+ break;
+ case USB_DEVICE_ID_LENOVO_CUSBKBD:
+ case USB_DEVICE_ID_LENOVO_CBTKBD:
+ ret = lenovo_probe_cptkbd(hdev);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ if (ret)
+ goto err_hid;
+
+ return 0;
+err_hid:
+ hid_hw_stop(hdev);
+err:
+ return ret;
+}
+
+static void lenovo_remove_tpkbd(struct hid_device *hdev)
+{
+ struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
+
+ /*
+ * Only the trackpoint half of the keyboard has drvdata and stuff that
+ * needs unregistering.
+ */
+ if (data_pointer == NULL)
+ return;
+
+ sysfs_remove_group(&hdev->dev.kobj,
+ &lenovo_attr_group_tpkbd);
+
+ led_classdev_unregister(&data_pointer->led_micmute);
+ led_classdev_unregister(&data_pointer->led_mute);
+
+ hid_set_drvdata(hdev, NULL);
+}
+
+static void lenovo_remove_cptkbd(struct hid_device *hdev)
+{
+ sysfs_remove_group(&hdev->dev.kobj,
+ &lenovo_attr_group_cptkbd);
+}
+
+static void lenovo_remove(struct hid_device *hdev)
+{
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LENOVO_TPKBD:
+ lenovo_remove_tpkbd(hdev);
+ break;
+ case USB_DEVICE_ID_LENOVO_CUSBKBD:
+ case USB_DEVICE_ID_LENOVO_CBTKBD:
+ lenovo_remove_cptkbd(hdev);
+ break;
+ }
+
+ hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id lenovo_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(hid, lenovo_devices);
+
+static struct hid_driver lenovo_driver = {
+ .name = "lenovo",
+ .id_table = lenovo_devices,
+ .input_mapping = lenovo_input_mapping,
+ .probe = lenovo_probe,
+ .remove = lenovo_remove,
+ .raw_event = lenovo_raw_event,
+};
+module_hid_driver(lenovo_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c
index cf1a9f1c1217..045f8ebf16b5 100644
--- a/drivers/hid/hid-picolcd_cir.c
+++ b/drivers/hid/hid-picolcd_cir.c
@@ -114,7 +114,7 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
rdev->priv = data;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = picolcd_cir_open;
rdev->close = picolcd_cir_close;
rdev->input_name = data->hdev->name;
diff --git a/drivers/hid/hid-picolcd_debugfs.c b/drivers/hid/hid-picolcd_debugfs.c
index 024cdf3c2297..3c13af684410 100644
--- a/drivers/hid/hid-picolcd_debugfs.c
+++ b/drivers/hid/hid-picolcd_debugfs.c
@@ -883,16 +883,13 @@ void picolcd_exit_devfs(struct picolcd_data *data)
dent = data->debug_reset;
data->debug_reset = NULL;
- if (dent)
- debugfs_remove(dent);
+ debugfs_remove(dent);
dent = data->debug_eeprom;
data->debug_eeprom = NULL;
- if (dent)
- debugfs_remove(dent);
+ debugfs_remove(dent);
dent = data->debug_flash;
data->debug_flash = NULL;
- if (dent)
- debugfs_remove(dent);
+ debugfs_remove(dent);
mutex_destroy(&data->mutex_flash);
}
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 2451c7e5febd..0dc25142f451 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -377,7 +377,7 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
irq_mask |= hdata->f30.irq_mask;
if (data[1] & ~irq_mask)
- hid_warn(hdev, "unknown intr source:%02lx %s:%d\n",
+ hid_dbg(hdev, "unknown intr source:%02lx %s:%d\n",
data[1] & ~irq_mask, __FILE__, __LINE__);
if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) {
@@ -400,7 +400,7 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
struct rmi_data *hdata = hid_get_drvdata(hdev);
if (!test_bit(RMI_READ_REQUEST_PENDING, &hdata->flags)) {
- hid_err(hdev, "no read request pending\n");
+ hid_dbg(hdev, "no read request pending\n");
return 0;
}
@@ -428,6 +428,7 @@ static int rmi_raw_event(struct hid_device *hdev,
return 0;
}
+#ifdef CONFIG_PM
static int rmi_post_reset(struct hid_device *hdev)
{
return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS);
@@ -437,6 +438,7 @@ static int rmi_post_resume(struct hid_device *hdev)
{
return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS);
}
+#endif /* CONFIG_PM */
#define RMI4_MAX_PAGE 0xff
#define RMI4_PAGE_SIZE 0x0100
@@ -547,10 +549,12 @@ static int rmi_populate_f11(struct hid_device *hdev)
u8 buf[20];
int ret;
bool has_query9;
- bool has_query10;
+ bool has_query10 = false;
bool has_query11;
bool has_query12;
bool has_physical_props;
+ bool has_gestures;
+ bool has_rel;
unsigned x_size, y_size;
u16 query12_offset;
@@ -587,19 +591,32 @@ static int rmi_populate_f11(struct hid_device *hdev)
return -ENODEV;
}
- /* query 8 to find out if query 10 exists */
- ret = rmi_read(hdev, data->f11.query_base_addr + 8, buf);
- if (ret) {
- hid_err(hdev, "can not read gesture information: %d.\n", ret);
- return ret;
+ has_rel = !!(buf[0] & BIT(3));
+ has_gestures = !!(buf[0] & BIT(5));
+
+ if (has_gestures) {
+ /* query 8 to find out if query 10 exists */
+ ret = rmi_read(hdev, data->f11.query_base_addr + 8, buf);
+ if (ret) {
+ hid_err(hdev, "can not read gesture information: %d.\n",
+ ret);
+ return ret;
+ }
+ has_query10 = !!(buf[0] & BIT(2));
}
- has_query10 = !!(buf[0] & BIT(2));
/*
- * At least 8 queries are guaranteed to be present in F11
- * +1 for query12.
+ * At least 4 queries are guaranteed to be present in F11
+ * +1 for query 5 which is present since absolute events are
+ * reported and +1 for query 12.
*/
- query12_offset = 9;
+ query12_offset = 6;
+
+ if (has_rel)
+ ++query12_offset; /* query 6 is present */
+
+ if (has_gestures)
+ query12_offset += 2; /* query 7 and 8 are present */
if (has_query9)
++query12_offset;
@@ -831,6 +848,8 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
struct rmi_data *data = NULL;
int ret;
size_t alloc_size;
+ struct hid_report *input_report;
+ struct hid_report *output_report;
data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
if (!data)
@@ -849,12 +868,26 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
return ret;
}
- data->input_report_size = (hdev->report_enum[HID_INPUT_REPORT]
- .report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3)
- + 1 /* report id */;
- data->output_report_size = (hdev->report_enum[HID_OUTPUT_REPORT]
- .report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3)
- + 1 /* report id */;
+ input_report = hdev->report_enum[HID_INPUT_REPORT]
+ .report_id_hash[RMI_ATTN_REPORT_ID];
+ if (!input_report) {
+ hid_err(hdev, "device does not have expected input report\n");
+ ret = -ENODEV;
+ return ret;
+ }
+
+ data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
+
+ output_report = hdev->report_enum[HID_OUTPUT_REPORT]
+ .report_id_hash[RMI_WRITE_REPORT_ID];
+ if (!output_report) {
+ hid_err(hdev, "device does not have expected output report\n");
+ ret = -ENODEV;
+ return ret;
+ }
+
+ data->output_report_size = (output_report->size >> 3)
+ + 1 /* report id */;
alloc_size = data->output_report_size + data->input_report_size;
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c
index 6adc0fa08d96..65e2e76bf2fe 100644
--- a/drivers/hid/hid-roccat-lua.c
+++ b/drivers/hid/hid-roccat-lua.c
@@ -61,7 +61,7 @@ static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj,
return -EINVAL;
mutex_lock(&lua->lua_lock);
- retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size);
+ retval = roccat_common2_send(usb_dev, command, buf, real_size);
mutex_unlock(&lua->lua_lock);
return retval ? retval : real_size;
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index a8d5c8faf8cf..e244e449cbba 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -159,17 +159,18 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
{
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
+ unsigned long flags;
- spin_lock(&pdata->dyn_callback_lock);
+ spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return -EINVAL;
}
callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
if (!callback) {
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return -ENOMEM;
}
callback->hsdev = hsdev;
@@ -177,7 +178,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
callback->usage_id = usage_id;
callback->priv = NULL;
list_add_tail(&callback->list, &pdata->dyn_callback_list);
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
@@ -188,8 +189,9 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
{
struct hid_sensor_hub_callbacks_list *callback;
struct sensor_hub_data *pdata = hid_get_drvdata(hsdev->hdev);
+ unsigned long flags;
- spin_lock(&pdata->dyn_callback_lock);
+ spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list)
if (callback->usage_id == usage_id &&
callback->hsdev == hsdev) {
@@ -197,7 +199,7 @@ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
kfree(callback);
break;
}
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
@@ -378,15 +380,16 @@ static int sensor_hub_suspend(struct hid_device *hdev, pm_message_t message)
{
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
struct hid_sensor_hub_callbacks_list *callback;
+ unsigned long flags;
hid_dbg(hdev, " sensor_hub_suspend\n");
- spin_lock(&pdata->dyn_callback_lock);
+ spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
if (callback->usage_callback->suspend)
callback->usage_callback->suspend(
callback->hsdev, callback->priv);
}
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
@@ -395,15 +398,16 @@ static int sensor_hub_resume(struct hid_device *hdev)
{
struct sensor_hub_data *pdata = hid_get_drvdata(hdev);
struct hid_sensor_hub_callbacks_list *callback;
+ unsigned long flags;
hid_dbg(hdev, " sensor_hub_resume\n");
- spin_lock(&pdata->dyn_callback_lock);
+ spin_lock_irqsave(&pdata->dyn_callback_lock, flags);
list_for_each_entry(callback, &pdata->dyn_callback_list, list) {
if (callback->usage_callback->resume)
callback->usage_callback->resume(
callback->hsdev, callback->priv);
}
- spin_unlock(&pdata->dyn_callback_lock);
+ spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags);
return 0;
}
@@ -632,6 +636,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
if (name == NULL) {
hid_err(hdev, "Failed MFD device name\n");
ret = -ENOMEM;
+ kfree(hsdev);
goto err_no_mem;
}
sd->hid_sensor_hub_client_devs[
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 2259eaa8b988..c372368e438c 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -56,32 +56,81 @@
#define MAX_LEDS 4
-static const u8 sixaxis_rdesc_fixup[] = {
- 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
- 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
- 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
-};
-
-static const u8 sixaxis_rdesc_fixup2[] = {
- 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
- 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
- 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
- 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
- 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
- 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
- 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
- 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
- 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
- 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
- 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
- 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
- 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
- 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
- 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
- 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
- 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
- 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
- 0xb1, 0x02, 0xc0, 0xc0,
+static __u8 sixaxis_rdesc[] = {
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x04, /* Usage (Joystik), */
+ 0xA1, 0x01, /* Collection (Application), */
+ 0xA1, 0x02, /* Collection (Logical), */
+ 0x85, 0x01, /* Report ID (1), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x01, /* Report Count (1), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x13, /* Report Count (19), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x25, 0x01, /* Logical Maximum (1), */
+ 0x35, 0x00, /* Physical Minimum (0), */
+ 0x45, 0x01, /* Physical Maximum (1), */
+ 0x05, 0x09, /* Usage Page (Button), */
+ 0x19, 0x01, /* Usage Minimum (01h), */
+ 0x29, 0x13, /* Usage Maximum (13h), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x75, 0x01, /* Report Size (1), */
+ 0x95, 0x0D, /* Report Count (13), */
+ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+ 0x81, 0x03, /* Input (Constant, Variable), */
+ 0x15, 0x00, /* Logical Minimum (0), */
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xA1, 0x00, /* Collection (Physical), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x04, /* Report Count (4), */
+ 0x35, 0x00, /* Physical Minimum (0), */
+ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */
+ 0x09, 0x30, /* Usage (X), */
+ 0x09, 0x31, /* Usage (Y), */
+ 0x09, 0x32, /* Usage (Z), */
+ 0x09, 0x35, /* Usage (Rz), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0x05, 0x01, /* Usage Page (Desktop), */
+ 0x95, 0x13, /* Report Count (19), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0x95, 0x0C, /* Report Count (12), */
+ 0x81, 0x01, /* Input (Constant), */
+ 0x75, 0x10, /* Report Size (16), */
+ 0x95, 0x04, /* Report Count (4), */
+ 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
+ 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0x81, 0x02, /* Input (Variable), */
+ 0xC0, /* End Collection, */
+ 0xA1, 0x02, /* Collection (Logical), */
+ 0x85, 0x02, /* Report ID (2), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x30, /* Report Count (48), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0xC0, /* End Collection, */
+ 0xA1, 0x02, /* Collection (Logical), */
+ 0x85, 0xEE, /* Report ID (238), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x30, /* Report Count (48), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0xC0, /* End Collection, */
+ 0xA1, 0x02, /* Collection (Logical), */
+ 0x85, 0xEF, /* Report ID (239), */
+ 0x75, 0x08, /* Report Size (8), */
+ 0x95, 0x30, /* Report Count (48), */
+ 0x09, 0x01, /* Usage (Pointer), */
+ 0xB1, 0x02, /* Feature (Variable), */
+ 0xC0, /* End Collection, */
+ 0xC0 /* End Collection */
};
/*
@@ -778,6 +827,13 @@ struct sony_sc {
__u8 led_count;
};
+static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ *rsize = sizeof(sixaxis_rdesc);
+ return sixaxis_rdesc;
+}
+
static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
@@ -819,8 +875,6 @@ static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
return 1;
}
-
-/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
@@ -857,20 +911,8 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
*rsize = sizeof(dualshock4_bt_rdesc);
}
- /* The HID descriptor exposed over BT has a trailing zero byte */
- if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
- ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
- rdesc[83] == 0x75) {
- hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
- memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
- sizeof(sixaxis_rdesc_fixup));
- } else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
- *rsize > sizeof(sixaxis_rdesc_fixup2)) {
- hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
- *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
- *rsize = sizeof(sixaxis_rdesc_fixup2);
- memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
- }
+ if (sc->quirks & SIXAXIS_CONTROLLER)
+ return sixaxis_fixup(hdev, rdesc, rsize);
if (sc->quirks & PS3REMOTE)
return ps3remote_fixup(hdev, rdesc, rsize);
@@ -1307,7 +1349,7 @@ static int sony_leds_init(struct sony_sc *sc)
static const char * const ds4_name_str[] = { "red", "green", "blue",
"global" };
__u8 initial_values[MAX_LEDS] = { 0 };
- __u8 max_brightness[MAX_LEDS] = { 1 };
+ __u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
__u8 use_hw_blink[MAX_LEDS] = { 0 };
BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
@@ -1830,9 +1872,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (sc->quirks & VAIO_RDESC_CONSTANT)
connect_mask |= HID_CONNECT_HIDDEV_FORCE;
- else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
- connect_mask |= HID_CONNECT_HIDDEV_FORCE;
- else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
+ else if (sc->quirks & SIXAXIS_CONTROLLER)
connect_mask |= HID_CONNECT_HIDDEV_FORCE;
ret = hid_hw_start(hdev, connect_mask);
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 21aafc8f48c8..747d54421e73 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -1054,21 +1054,29 @@ static int i2c_hid_remove(struct i2c_client *client)
static int i2c_hid_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_hid *ihid = i2c_get_clientdata(client);
+ struct hid_device *hid = ihid->hid;
+ int ret = 0;
disable_irq(client->irq);
if (device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
+ if (hid->driver && hid->driver->suspend)
+ ret = hid->driver->suspend(hid, PMSG_SUSPEND);
+
/* Save some power */
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
- return 0;
+ return ret;
}
static int i2c_hid_resume(struct device *dev)
{
int ret;
struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_hid *ihid = i2c_get_clientdata(client);
+ struct hid_device *hid = ihid->hid;
enable_irq(client->irq);
ret = i2c_hid_hwreset(client);
@@ -1078,6 +1086,11 @@ static int i2c_hid_resume(struct device *dev)
if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
+ if (hid->driver && hid->driver->reset_resume) {
+ ret = hid->driver->reset_resume(hid);
+ return ret;
+ }
+
return 0;
}
#endif
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 7b88f4cb9902..79cf503e37bf 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -58,7 +58,7 @@ module_param_named(ignoreled, ignoreled, uint, 0644);
MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
/* Quirks specified at module load time */
-static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
+static char *quirks_param[MAX_USBHID_BOOT_QUIRKS];
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
" quirks=vendorID:productID:quirks"
@@ -536,7 +536,8 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
int head;
struct usbhid_device *usbhid = hid->driver_data;
- if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
+ if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
+ test_bit(HID_DISCONNECTED, &usbhid->iofl))
return;
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
@@ -1366,6 +1367,9 @@ static void usbhid_disconnect(struct usb_interface *intf)
return;
usbhid = hid->driver_data;
+ spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
+ set_bit(HID_DISCONNECTED, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
hid_destroy_device(hid);
kfree(usbhid);
}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 59badc10a08c..15225f3eaed1 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -49,6 +49,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH_2968, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
{ USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
@@ -73,9 +74,11 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
@@ -121,6 +124,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS },
+ { USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096, HID_QUIRK_NO_INIT_INPUT_REPORTS },
{ 0, 0 }
};
diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
index ce4be3738d46..e5c7a969f28b 100644
--- a/drivers/hsi/clients/ssi_protocol.c
+++ b/drivers/hsi/clients/ssi_protocol.c
@@ -901,7 +901,7 @@ out:
ssip_free_data(msg);
}
-void ssip_port_event(struct hsi_client *cl, unsigned long event)
+static void ssip_port_event(struct hsi_client *cl, unsigned long event)
{
switch (event) {
case HSI_EVENT_START_RX:
@@ -1115,7 +1115,7 @@ static int ssi_protocol_probe(struct device *dev)
goto out;
}
- ssi->netdev = alloc_netdev(0, ifname, ssip_pn_setup);
+ ssi->netdev = alloc_netdev(0, ifname, NET_NAME_UNKNOWN, ssip_pn_setup);
if (!ssi->netdev) {
dev_err(dev, "No memory for netdev\n");
err = -ENOMEM;
diff --git a/drivers/hsi/controllers/omap_ssi.c b/drivers/hsi/controllers/omap_ssi.c
index 0fc7a7fd0140..bf0eace4cb67 100644
--- a/drivers/hsi/controllers/omap_ssi.c
+++ b/drivers/hsi/controllers/omap_ssi.c
@@ -148,14 +148,14 @@ static int __init ssi_debug_add_ctrl(struct hsi_controller *ssi)
/* SSI controller */
omap_ssi->dir = debugfs_create_dir(dev_name(&ssi->device), NULL);
- if (IS_ERR(omap_ssi->dir))
- return PTR_ERR(omap_ssi->dir);
+ if (!omap_ssi->dir)
+ return -ENOMEM;
debugfs_create_file("regs", S_IRUGO, omap_ssi->dir, ssi,
&ssi_regs_fops);
/* SSI GDD (DMA) */
dir = debugfs_create_dir("gdd", omap_ssi->dir);
- if (IS_ERR(dir))
+ if (!dir)
goto rback;
debugfs_create_file("regs", S_IRUGO, dir, ssi, &ssi_gdd_regs_fops);
@@ -163,7 +163,7 @@ static int __init ssi_debug_add_ctrl(struct hsi_controller *ssi)
rback:
debugfs_remove_recursive(omap_ssi->dir);
- return PTR_ERR(dir);
+ return -ENOMEM;
}
static void ssi_debug_remove_ctrl(struct hsi_controller *ssi)
@@ -353,12 +353,12 @@ static int __init ssi_add_controller(struct hsi_controller *ssi,
err = ssi_get_iomem(pd, "gdd", &omap_ssi->gdd, NULL);
if (err < 0)
goto out_err;
- omap_ssi->gdd_irq = platform_get_irq_byname(pd, "gdd_mpu");
- if (omap_ssi->gdd_irq < 0) {
+ err = platform_get_irq_byname(pd, "gdd_mpu");
+ if (err < 0) {
dev_err(&pd->dev, "GDD IRQ resource missing\n");
- err = omap_ssi->gdd_irq;
goto out_err;
}
+ omap_ssi->gdd_irq = err;
tasklet_init(&omap_ssi->gdd_tasklet, ssi_gdd_tasklet,
(unsigned long)ssi);
err = devm_request_irq(&ssi->device, omap_ssi->gdd_irq, ssi_gdd_isr,
diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c
index 29aea0b93360..4c0b5820581e 100644
--- a/drivers/hsi/controllers/omap_ssi_port.c
+++ b/drivers/hsi/controllers/omap_ssi_port.c
@@ -177,13 +177,13 @@ static int __init ssi_debug_add_port(struct omap_ssi_port *omap_port,
struct hsi_port *port = to_hsi_port(omap_port->dev);
dir = debugfs_create_dir(dev_name(omap_port->dev), dir);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
+ if (!dir)
+ return -ENOMEM;
omap_port->dir = dir;
debugfs_create_file("regs", S_IRUGO, dir, port, &ssi_port_regs_fops);
dir = debugfs_create_dir("sst", dir);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
+ if (!dir)
+ return -ENOMEM;
debugfs_create_file("divisor", S_IRUGO | S_IWUSR, dir, port,
&ssi_sst_div_fops);
@@ -1013,11 +1013,12 @@ static int __init ssi_port_irq(struct hsi_port *port,
struct omap_ssi_port *omap_port = hsi_port_drvdata(port);
int err;
- omap_port->irq = platform_get_irq(pd, 0);
- if (omap_port->irq < 0) {
+ err = platform_get_irq(pd, 0);
+ if (err < 0) {
dev_err(&port->device, "Port IRQ resource missing\n");
- return omap_port->irq;
+ return err;
}
+ omap_port->irq = err;
tasklet_init(&omap_port->pio_tasklet, ssi_pio_tasklet,
(unsigned long)port);
err = devm_request_irq(&port->device, omap_port->irq, ssi_pio_isr,
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 284cf66489f4..531a593912ec 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -808,12 +808,8 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
*buffer_actual_len = packetlen;
- if (packetlen > bufferlen) {
- pr_err("Buffer too small - needed %d bytes but "
- "got space for only %d bytes\n",
- packetlen, bufferlen);
+ if (packetlen > bufferlen)
return -ENOBUFS;
- }
*requestid = desc.trans_id;
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index e84f4526eb36..ae22e3c1fc4c 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -339,9 +339,13 @@ static void process_chn_event(u32 relid)
*/
do {
- hv_begin_read(&channel->inbound);
+ if (read_state)
+ hv_begin_read(&channel->inbound);
channel->onchannel_callback(arg);
- bytes_to_read = hv_end_read(&channel->inbound);
+ if (read_state)
+ bytes_to_read = hv_end_read(&channel->inbound);
+ else
+ bytes_to_read = 0;
} while (read_state && (bytes_to_read != 0));
} else {
pr_err("no channel callback for relid - %u\n", relid);
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
index eaaa3d843b80..23b2ce294c4c 100644
--- a/drivers/hv/hv_fcopy.c
+++ b/drivers/hv/hv_fcopy.c
@@ -246,8 +246,8 @@ void hv_fcopy_onchannelcallback(void *context)
/*
* Send the information to the user-level daemon.
*/
- fcopy_send_data();
schedule_delayed_work(&fcopy_work, 5*HZ);
+ fcopy_send_data();
return;
}
icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index ea852537307e..521c14625b3a 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -127,6 +127,17 @@ kvp_work_func(struct work_struct *dummy)
kvp_respond_to_host(NULL, HV_E_FAIL);
}
+static void poll_channel(struct vmbus_channel *channel)
+{
+ if (channel->target_cpu != smp_processor_id())
+ smp_call_function_single(channel->target_cpu,
+ hv_kvp_onchannelcallback,
+ channel, true);
+ else
+ hv_kvp_onchannelcallback(channel);
+}
+
+
static int kvp_handle_handshake(struct hv_kvp_msg *msg)
{
int ret = 1;
@@ -155,7 +166,7 @@ static int kvp_handle_handshake(struct hv_kvp_msg *msg)
kvp_register(dm_reg_value);
kvp_transaction.active = false;
if (kvp_transaction.kvp_context)
- hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
+ poll_channel(kvp_transaction.kvp_context);
}
return ret;
}
@@ -568,7 +579,7 @@ response_done:
vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
VM_PKT_DATA_INBAND, 0);
-
+ poll_channel(channel);
}
/*
@@ -603,7 +614,7 @@ void hv_kvp_onchannelcallback(void *context)
return;
}
- vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
+ vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 4, &recvlen,
&requestid);
if (recvlen > 0) {
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index dd761806f0e8..3b9c9ef0deb8 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -319,7 +319,7 @@ static int util_probe(struct hv_device *dev,
(struct hv_util_service *)dev_id->driver_data;
int ret;
- srv->recv_buffer = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
+ srv->recv_buffer = kmalloc(PAGE_SIZE * 4, GFP_KERNEL);
if (!srv->recv_buffer)
return -ENOMEM;
if (srv->util_init) {
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 02d3d85829f3..f00d048aa583 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -554,6 +554,17 @@ config SENSORS_IBMPEX
This driver can also be built as a module. If so, the module
will be called ibmpex.
+config SENSORS_IBMPOWERNV
+ tristate "IBM POWERNV platform sensors"
+ depends on PPC_POWERNV
+ default y
+ help
+ If you say yes here you get support for the temperature/fan/power
+ sensors on your PowerNV platform.
+
+ This driver can also be built as a module. If so, the module
+ will be called ibmpowernv.
+
config SENSORS_IIO_HWMON
tristate "Hwmon driver that uses channels specified via iio maps"
depends on IIO
@@ -608,6 +619,18 @@ config SENSORS_JC42
This driver can also be built as a module. If so, the module
will be called jc42.
+config SENSORS_POWR1220
+ tristate "Lattice POWR1220 Power Monitoring"
+ depends on I2C
+ default n
+ help
+ If you say yes here you get access to the hardware monitoring
+ functions of the Lattice POWR1220 isp Power Supply Monitoring,
+ Sequencing and Margining Controller.
+
+ This driver can also be built as a module. If so, the module
+ will be called powr1220.
+
config SENSORS_LINEAGE
tristate "Lineage Compact Power Line Power Entry Module"
depends on I2C
@@ -882,8 +905,8 @@ config SENSORS_LM75
- NXP's LM75A
- ST Microelectronics STDS75
- TelCom (now Microchip) TCN75
- - Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175,
- TMP275
+ - Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75,
+ TMP175, TMP275
This driver supports driver model based binding through board
specific I2C device tables.
@@ -1061,7 +1084,7 @@ config SENSORS_NTC_THERMISTOR
Currently, this driver supports
NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
- from Murata.
+ from Murata and B57330V2103 from EPCOS.
This driver can also be built as a module. If so, the module
will be called ntc-thermistor.
@@ -1082,8 +1105,8 @@ config SENSORS_NCT6775
select HWMON_VID
help
If you say yes here you get support for the hardware monitoring
- functionality of the Nuvoton NCT6775F, NCT6776F, NCT6779D
- and compatible Super-I/O chips. This driver replaces the
+ functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D,
+ NCT6791D and compatible Super-I/O chips. This driver replaces the
w83627ehf driver for NCT6775F and NCT6776F.
This driver can also be built as a module. If so, the module
@@ -1105,6 +1128,17 @@ config SENSORS_PCF8591
source drivers/hwmon/pmbus/Kconfig
+config SENSORS_PWM_FAN
+ tristate "PWM fan"
+ depends on (PWM && OF) || COMPILE_TEST
+ help
+ If you say yes here you get support for fans connected to PWM lines.
+ The driver uses the generic PWM interface, thus it will work on a
+ variety of SoCs.
+
+ This driver can also be built as a module. If so, the module
+ will be called pwm-fan.
+
config SENSORS_SHT15
tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
depends on GPIOLIB
@@ -1393,6 +1427,17 @@ config SENSORS_TMP102
This driver can also be built as a module. If so, the module
will be called tmp102.
+config SENSORS_TMP103
+ tristate "Texas Instruments TMP103"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for Texas Instruments TMP103
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called tmp103.
+
config SENSORS_TMP401
tristate "Texas Instruments TMP401 and compatibles"
depends on I2C
@@ -1408,7 +1453,7 @@ config SENSORS_TMP421
depends on I2C
help
If you say yes here you get support for Texas Instruments TMP421,
- TMP422 and TMP423 temperature sensor chips.
+ TMP422, TMP423, TMP441, and TMP442 temperature sensor chips.
This driver can also be built as a module. If so, the module
will be called tmp421.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 3dc0f02f71d2..be28152c9848 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
+obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
obj-$(CONFIG_SENSORS_INA209) += ina209.o
obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
@@ -120,6 +121,8 @@ obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
+obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o
+obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o
obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
@@ -135,6 +138,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
+obj-$(CONFIG_SENSORS_TMP103) += tmp103.o
obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index 5d501adc3e54..763490acc0df 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -39,7 +39,7 @@
static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
struct ad7414_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex lock; /* atomic read data updates */
char valid; /* !=0 if following fields are valid */
unsigned long next_update; /* In jiffies */
@@ -72,8 +72,8 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
static struct ad7414_data *ad7414_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ad7414_data *data = i2c_get_clientdata(client);
+ struct ad7414_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->lock);
@@ -127,8 +127,8 @@ static ssize_t set_max_min(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ad7414_data *data = i2c_get_clientdata(client);
+ struct ad7414_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int index = to_sensor_dev_attr(attr)->index;
u8 reg = AD7414_REG_LIMIT[index];
long temp;
@@ -164,7 +164,7 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
-static struct attribute *ad7414_attributes[] = {
+static struct attribute *ad7414_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -173,27 +173,25 @@ static struct attribute *ad7414_attributes[] = {
NULL
};
-static const struct attribute_group ad7414_group = {
- .attrs = ad7414_attributes,
-};
+ATTRIBUTE_GROUPS(ad7414);
static int ad7414_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
+ struct device *dev = &client->dev;
struct ad7414_data *data;
+ struct device *hwmon_dev;
int conf;
- int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EOPNOTSUPP;
- data = devm_kzalloc(&client->dev, sizeof(struct ad7414_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct ad7414_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "chip found\n");
@@ -201,38 +199,16 @@ static int ad7414_probe(struct i2c_client *client,
/* Make sure the chip is powered up. */
conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
if (conf < 0)
- dev_warn(&client->dev,
- "ad7414_probe unable to read config register.\n");
+ dev_warn(dev, "ad7414_probe unable to read config register.\n");
else {
conf &= ~(1 << 7);
i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
}
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &ad7414_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &ad7414_group);
- return err;
-}
-
-static int ad7414_remove(struct i2c_client *client)
-{
- struct ad7414_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &ad7414_group);
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+ client->name,
+ data, ad7414_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ad7414_id[] = {
@@ -246,7 +222,6 @@ static struct i2c_driver ad7414_driver = {
.name = "ad7414",
},
.probe = ad7414_probe,
- .remove = ad7414_remove,
.id_table = ad7414_id,
};
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index 57d4a6295675..a01b731ba5d7 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -44,8 +44,7 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
AD7418_REG_TEMP_OS };
struct ad7418_data {
- struct device *hwmon_dev;
- struct attribute_group attrs;
+ struct i2c_client *client;
enum chips type;
struct mutex lock;
int adc_max; /* number of ADC channels */
@@ -55,48 +54,10 @@ struct ad7418_data {
u16 in[4];
};
-static int ad7418_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ad7418_remove(struct i2c_client *client);
-
-static const struct i2c_device_id ad7418_id[] = {
- { "ad7416", ad7416 },
- { "ad7417", ad7417 },
- { "ad7418", ad7418 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ad7418_id);
-
-static struct i2c_driver ad7418_driver = {
- .driver = {
- .name = "ad7418",
- },
- .probe = ad7418_probe,
- .remove = ad7418_remove,
- .id_table = ad7418_id,
-};
-
-static void ad7418_init_client(struct i2c_client *client)
-{
- struct ad7418_data *data = i2c_get_clientdata(client);
-
- int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
- if (reg < 0) {
- dev_err(&client->dev, "cannot read configuration register\n");
- } else {
- dev_info(&client->dev, "configuring for mode 1\n");
- i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
-
- if (data->type == ad7417 || data->type == ad7418)
- i2c_smbus_write_byte_data(client,
- AD7418_REG_CONF2, 0x00);
- }
-}
-
static struct ad7418_data *ad7418_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ad7418_data *data = i2c_get_clientdata(client);
+ struct ad7418_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->lock);
@@ -165,8 +126,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct ad7418_data *data = i2c_get_clientdata(client);
+ struct ad7418_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
int ret = kstrtol(buf, 10, &temp);
@@ -193,14 +154,15 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
-static struct attribute *ad7416_attributes[] = {
+static struct attribute *ad7416_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
NULL
};
+ATTRIBUTE_GROUPS(ad7416);
-static struct attribute *ad7417_attributes[] = {
+static struct attribute *ad7417_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -210,83 +172,100 @@ static struct attribute *ad7417_attributes[] = {
&sensor_dev_attr_in4_input.dev_attr.attr,
NULL
};
+ATTRIBUTE_GROUPS(ad7417);
-static struct attribute *ad7418_attributes[] = {
+static struct attribute *ad7418_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
NULL
};
+ATTRIBUTE_GROUPS(ad7418);
+
+static void ad7418_init_client(struct i2c_client *client)
+{
+ struct ad7418_data *data = i2c_get_clientdata(client);
+
+ int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
+ if (reg < 0) {
+ dev_err(&client->dev, "cannot read configuration register\n");
+ } else {
+ dev_info(&client->dev, "configuring for mode 1\n");
+ i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
+
+ if (data->type == ad7417 || data->type == ad7418)
+ i2c_smbus_write_byte_data(client,
+ AD7418_REG_CONF2, 0x00);
+ }
+}
static int ad7418_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct i2c_adapter *adapter = client->adapter;
struct ad7418_data *data;
- int err;
+ struct device *hwmon_dev;
+ const struct attribute_group **attr_groups = NULL;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
return -EOPNOTSUPP;
- data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct ad7418_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
+ data->client = client;
data->type = id->driver_data;
switch (data->type) {
case ad7416:
data->adc_max = 0;
- data->attrs.attrs = ad7416_attributes;
+ attr_groups = ad7416_groups;
break;
case ad7417:
data->adc_max = 4;
- data->attrs.attrs = ad7417_attributes;
+ attr_groups = ad7417_groups;
break;
case ad7418:
data->adc_max = 1;
- data->attrs.attrs = ad7418_attributes;
+ attr_groups = ad7418_groups;
break;
}
- dev_info(&client->dev, "%s chip found\n", client->name);
+ dev_info(dev, "%s chip found\n", client->name);
/* Initialize the AD7418 chip */
ad7418_init_client(client);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &data->attrs);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- return err;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+ client->name,
+ data, attr_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static int ad7418_remove(struct i2c_client *client)
-{
- struct ad7418_data *data = i2c_get_clientdata(client);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- return 0;
-}
+static const struct i2c_device_id ad7418_id[] = {
+ { "ad7416", ad7416 },
+ { "ad7417", ad7417 },
+ { "ad7418", ad7418 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ad7418_id);
+
+static struct i2c_driver ad7418_driver = {
+ .driver = {
+ .name = "ad7418",
+ },
+ .probe = ad7418_probe,
+ .id_table = ad7418_id,
+};
module_i2c_driver(ad7418_driver);
diff --git a/drivers/hwmon/adc128d818.c b/drivers/hwmon/adc128d818.c
index 5ffd81f19d01..0625e50d7a6e 100644
--- a/drivers/hwmon/adc128d818.c
+++ b/drivers/hwmon/adc128d818.c
@@ -239,50 +239,50 @@ static ssize_t adc128_show_alarm(struct device *dev,
return sprintf(buf, "%u\n", !!(alarms & mask));
}
-static SENSOR_DEVICE_ATTR_2(in0_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO,
+ adc128_show_in, NULL, 0, 0);
static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 0, 1);
static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 0, 2);
-static SENSOR_DEVICE_ATTR_2(in1_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 1, 0);
+static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO,
+ adc128_show_in, NULL, 1, 0);
static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 1, 1);
static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 1, 2);
-static SENSOR_DEVICE_ATTR_2(in2_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 2, 0);
+static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO,
+ adc128_show_in, NULL, 2, 0);
static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 2, 1);
static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 2, 2);
-static SENSOR_DEVICE_ATTR_2(in3_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 3, 0);
+static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO,
+ adc128_show_in, NULL, 3, 0);
static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 3, 1);
static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 3, 2);
-static SENSOR_DEVICE_ATTR_2(in4_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 4, 0);
+static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO,
+ adc128_show_in, NULL, 4, 0);
static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 4, 1);
static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 4, 2);
-static SENSOR_DEVICE_ATTR_2(in5_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 5, 0);
+static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO,
+ adc128_show_in, NULL, 5, 0);
static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 5, 1);
static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 5, 2);
-static SENSOR_DEVICE_ATTR_2(in6_input, S_IWUSR | S_IRUGO,
- adc128_show_in, adc128_set_in, 6, 0);
+static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO,
+ adc128_show_in, NULL, 6, 0);
static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO,
adc128_show_in, adc128_set_in, 6, 1);
static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO,
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index 3eb4281689b5..1fdcc3e703b9 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -98,41 +98,63 @@ struct adm1021_data {
u8 remote_temp_offset_prec;
};
-static int adm1021_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm1021_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static void adm1021_init_client(struct i2c_client *client);
-static struct adm1021_data *adm1021_update_device(struct device *dev);
-
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
static bool read_only;
+static struct adm1021_data *adm1021_update_device(struct device *dev)
+{
+ struct adm1021_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
-static const struct i2c_device_id adm1021_id[] = {
- { "adm1021", adm1021 },
- { "adm1023", adm1023 },
- { "max1617", max1617 },
- { "max1617a", max1617a },
- { "thmc10", thmc10 },
- { "lm84", lm84 },
- { "gl523sm", gl523sm },
- { "mc1066", mc1066 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm1021_id);
+ mutex_lock(&data->update_lock);
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1021_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm1021",
- },
- .probe = adm1021_probe,
- .id_table = adm1021_id,
- .detect = adm1021_detect,
- .address_list = normal_i2c,
-};
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+
+ dev_dbg(dev, "Starting adm1021 update\n");
+
+ for (i = 0; i < 2; i++) {
+ data->temp[i] = 1000 *
+ (s8) i2c_smbus_read_byte_data(
+ client, ADM1021_REG_TEMP(i));
+ data->temp_max[i] = 1000 *
+ (s8) i2c_smbus_read_byte_data(
+ client, ADM1021_REG_TOS_R(i));
+ if (data->type != lm84) {
+ data->temp_min[i] = 1000 *
+ (s8) i2c_smbus_read_byte_data(client,
+ ADM1021_REG_THYST_R(i));
+ }
+ }
+ data->alarms = i2c_smbus_read_byte_data(client,
+ ADM1021_REG_STATUS) & 0x7c;
+ if (data->type == adm1023) {
+ /*
+ * The ADM1023 provides 3 extra bits of precision for
+ * the remote sensor in extra registers.
+ */
+ data->temp[1] += 125 * (i2c_smbus_read_byte_data(
+ client, ADM1023_REG_REM_TEMP_PREC) >> 5);
+ data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
+ client, ADM1023_REG_REM_TOS_PREC) >> 5);
+ data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
+ client, ADM1023_REG_REM_THYST_PREC) >> 5);
+ data->remote_temp_offset =
+ i2c_smbus_read_byte_data(client,
+ ADM1023_REG_REM_OFFSET);
+ data->remote_temp_offset_prec =
+ i2c_smbus_read_byte_data(client,
+ ADM1023_REG_REM_OFFSET_PREC);
+ }
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
static ssize_t show_temp(struct device *dev,
struct device_attribute *devattr, char *buf)
@@ -185,7 +207,7 @@ static ssize_t set_temp_max(struct device *dev,
struct adm1021_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
- int err;
+ int reg_val, err;
err = kstrtol(buf, 10, &temp);
if (err)
@@ -193,10 +215,11 @@ static ssize_t set_temp_max(struct device *dev,
temp /= 1000;
mutex_lock(&data->update_lock);
- data->temp_max[index] = clamp_val(temp, -128, 127);
+ reg_val = clamp_val(temp, -128, 127);
+ data->temp_max[index] = reg_val * 1000;
if (!read_only)
i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
- data->temp_max[index]);
+ reg_val);
mutex_unlock(&data->update_lock);
return count;
@@ -210,7 +233,7 @@ static ssize_t set_temp_min(struct device *dev,
struct adm1021_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
- int err;
+ int reg_val, err;
err = kstrtol(buf, 10, &temp);
if (err)
@@ -218,10 +241,11 @@ static ssize_t set_temp_min(struct device *dev,
temp /= 1000;
mutex_lock(&data->update_lock);
- data->temp_min[index] = clamp_val(temp, -128, 127);
+ reg_val = clamp_val(temp, -128, 127);
+ data->temp_min[index] = reg_val * 1000;
if (!read_only)
i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
- data->temp_min[index]);
+ reg_val);
mutex_unlock(&data->update_lock);
return count;
@@ -409,6 +433,15 @@ static int adm1021_detect(struct i2c_client *client,
return 0;
}
+static void adm1021_init_client(struct i2c_client *client)
+{
+ /* Enable ADC and disable suspend mode */
+ i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
+ i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
+ /* Set Conversion rate to 1/sec (this can be tinkered with) */
+ i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
+}
+
static int adm1021_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -438,69 +471,29 @@ static int adm1021_probe(struct i2c_client *client,
return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static void adm1021_init_client(struct i2c_client *client)
-{
- /* Enable ADC and disable suspend mode */
- i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
- i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
- /* Set Conversion rate to 1/sec (this can be tinkered with) */
- i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
-}
-
-static struct adm1021_data *adm1021_update_device(struct device *dev)
-{
- struct adm1021_data *data = dev_get_drvdata(dev);
- struct i2c_client *client = data->client;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- int i;
-
- dev_dbg(dev, "Starting adm1021 update\n");
-
- for (i = 0; i < 2; i++) {
- data->temp[i] = 1000 *
- (s8) i2c_smbus_read_byte_data(
- client, ADM1021_REG_TEMP(i));
- data->temp_max[i] = 1000 *
- (s8) i2c_smbus_read_byte_data(
- client, ADM1021_REG_TOS_R(i));
- if (data->type != lm84) {
- data->temp_min[i] = 1000 *
- (s8) i2c_smbus_read_byte_data(client,
- ADM1021_REG_THYST_R(i));
- }
- }
- data->alarms = i2c_smbus_read_byte_data(client,
- ADM1021_REG_STATUS) & 0x7c;
- if (data->type == adm1023) {
- /*
- * The ADM1023 provides 3 extra bits of precision for
- * the remote sensor in extra registers.
- */
- data->temp[1] += 125 * (i2c_smbus_read_byte_data(
- client, ADM1023_REG_REM_TEMP_PREC) >> 5);
- data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
- client, ADM1023_REG_REM_TOS_PREC) >> 5);
- data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
- client, ADM1023_REG_REM_THYST_PREC) >> 5);
- data->remote_temp_offset =
- i2c_smbus_read_byte_data(client,
- ADM1023_REG_REM_OFFSET);
- data->remote_temp_offset_prec =
- i2c_smbus_read_byte_data(client,
- ADM1023_REG_REM_OFFSET_PREC);
- }
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1021_id[] = {
+ { "adm1021", adm1021 },
+ { "adm1023", adm1023 },
+ { "max1617", max1617 },
+ { "max1617a", max1617a },
+ { "thmc10", thmc10 },
+ { "lm84", lm84 },
+ { "gl523sm", gl523sm },
+ { "mc1066", mc1066 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm1021_id);
- return data;
-}
+static struct i2c_driver adm1021_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm1021",
+ },
+ .probe = adm1021_probe,
+ .id_table = adm1021_id,
+ .detect = adm1021_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm1021_driver);
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index 9ffc4c8ca8b5..d3d0e8cf27b4 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -103,46 +103,12 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
(val) + 500) / 1000))
/*
- * Functions declaration
- */
-
-static int adm1025_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm1025_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static void adm1025_init_client(struct i2c_client *client);
-static int adm1025_remove(struct i2c_client *client);
-static struct adm1025_data *adm1025_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id adm1025_id[] = {
- { "adm1025", adm1025 },
- { "ne1619", ne1619 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm1025_id);
-
-static struct i2c_driver adm1025_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm1025",
- },
- .probe = adm1025_probe,
- .remove = adm1025_remove,
- .id_table = adm1025_id,
- .detect = adm1025_detect,
- .address_list = normal_i2c,
-};
-
-/*
* Client data (each client gets its own)
*/
struct adm1025_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -158,6 +124,51 @@ struct adm1025_data {
u8 vrm;
};
+static struct adm1025_data *adm1025_update_device(struct device *dev)
+{
+ struct adm1025_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Updating data.\n");
+ for (i = 0; i < 6; i++) {
+ data->in[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_IN(i));
+ data->in_min[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_IN_MIN(i));
+ data->in_max[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_IN_MAX(i));
+ }
+ for (i = 0; i < 2; i++) {
+ data->temp[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_TEMP(i));
+ data->temp_min[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_TEMP_LOW(i));
+ data->temp_max[i] = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_TEMP_HIGH(i));
+ }
+ data->alarms = i2c_smbus_read_byte_data(client,
+ ADM1025_REG_STATUS1)
+ | (i2c_smbus_read_byte_data(client,
+ ADM1025_REG_STATUS2) << 8);
+ data->vid = (i2c_smbus_read_byte_data(client,
+ ADM1025_REG_VID) & 0x0f)
+ | ((i2c_smbus_read_byte_data(client,
+ ADM1025_REG_VID4) & 0x01) << 4);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
/*
* Sysfs stuff
*/
@@ -217,8 +228,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1025_data *data = i2c_get_clientdata(client);
+ struct adm1025_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -238,8 +249,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1025_data *data = i2c_get_clientdata(client);
+ struct adm1025_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -273,8 +284,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1025_data *data = i2c_get_clientdata(client);
+ struct adm1025_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -294,8 +305,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1025_data *data = i2c_get_clientdata(client);
+ struct adm1025_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -470,51 +481,6 @@ static int adm1025_detect(struct i2c_client *client,
return 0;
}
-static int adm1025_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adm1025_data *data;
- int err;
- u8 config;
-
- data = devm_kzalloc(&client->dev, sizeof(struct adm1025_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- /* Initialize the ADM1025 chip */
- adm1025_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &adm1025_group);
- if (err)
- return err;
-
- /* Pin 11 is either in4 (+12V) or VID4 */
- config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
- if (!(config & 0x20)) {
- err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4);
- if (err)
- goto exit_remove;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &adm1025_group);
- sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
- return err;
-}
-
static void adm1025_init_client(struct i2c_client *client)
{
u8 reg;
@@ -557,61 +523,54 @@ static void adm1025_init_client(struct i2c_client *client)
(reg&0x7E)|0x01);
}
-static int adm1025_remove(struct i2c_client *client)
+static int adm1025_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct adm1025_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adm1025_group);
- sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
-
- return 0;
-}
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct adm1025_data *data;
+ u8 config;
-static struct adm1025_data *adm1025_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1025_data *data = i2c_get_clientdata(client);
+ data = devm_kzalloc(dev, sizeof(struct adm1025_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- mutex_lock(&data->update_lock);
+ i2c_set_clientdata(client, data);
+ data->client = client;
+ mutex_init(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
- int i;
+ /* Initialize the ADM1025 chip */
+ adm1025_init_client(client);
- dev_dbg(&client->dev, "Updating data.\n");
- for (i = 0; i < 6; i++) {
- data->in[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_IN(i));
- data->in_min[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_IN_MIN(i));
- data->in_max[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_IN_MAX(i));
- }
- for (i = 0; i < 2; i++) {
- data->temp[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_TEMP(i));
- data->temp_min[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_TEMP_LOW(i));
- data->temp_max[i] = i2c_smbus_read_byte_data(client,
- ADM1025_REG_TEMP_HIGH(i));
- }
- data->alarms = i2c_smbus_read_byte_data(client,
- ADM1025_REG_STATUS1)
- | (i2c_smbus_read_byte_data(client,
- ADM1025_REG_STATUS2) << 8);
- data->vid = (i2c_smbus_read_byte_data(client,
- ADM1025_REG_VID) & 0x0f)
- | ((i2c_smbus_read_byte_data(client,
- ADM1025_REG_VID4) & 0x01) << 4);
+ /* sysfs hooks */
+ data->groups[0] = &adm1025_group;
+ /* Pin 11 is either in4 (+12V) or VID4 */
+ config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
+ if (!(config & 0x20))
+ data->groups[1] = &adm1025_group_in4;
- data->last_updated = jiffies;
- data->valid = 1;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1025_id[] = {
+ { "adm1025", adm1025 },
+ { "ne1619", ne1619 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm1025_id);
- return data;
-}
+static struct i2c_driver adm1025_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm1025",
+ },
+ .probe = adm1025_probe,
+ .id_table = adm1025_id,
+ .detect = adm1025_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm1025_driver);
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index b3498acb9ab4..ca8430f92564 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -266,7 +266,8 @@ struct pwm_data {
};
struct adm1026_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
int valid; /* !=0 if following fields are valid */
@@ -298,37 +299,6 @@ struct adm1026_data {
u8 config3; /* Register value */
};
-static int adm1026_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm1026_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int adm1026_remove(struct i2c_client *client);
-static int adm1026_read_value(struct i2c_client *client, u8 reg);
-static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
-static void adm1026_print_gpio(struct i2c_client *client);
-static void adm1026_fixup_gpio(struct i2c_client *client);
-static struct adm1026_data *adm1026_update_device(struct device *dev);
-static void adm1026_init_client(struct i2c_client *client);
-
-
-static const struct i2c_device_id adm1026_id[] = {
- { "adm1026", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm1026_id);
-
-static struct i2c_driver adm1026_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm1026",
- },
- .probe = adm1026_probe,
- .remove = adm1026_remove,
- .id_table = adm1026_id,
- .detect = adm1026_detect,
- .address_list = normal_i2c,
-};
-
static int adm1026_read_value(struct i2c_client *client, u8 reg)
{
int res;
@@ -357,212 +327,10 @@ static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
return res;
}
-static void adm1026_init_client(struct i2c_client *client)
-{
- int value, i;
- struct adm1026_data *data = i2c_get_clientdata(client);
-
- dev_dbg(&client->dev, "Initializing device\n");
- /* Read chip config */
- data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
- data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
- data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
-
- /* Inform user of chip config */
- dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
- data->config1);
- if ((data->config1 & CFG1_MONITOR) == 0) {
- dev_dbg(&client->dev,
- "Monitoring not currently enabled.\n");
- }
- if (data->config1 & CFG1_INT_ENABLE) {
- dev_dbg(&client->dev,
- "SMBALERT interrupts are enabled.\n");
- }
- if (data->config1 & CFG1_AIN8_9) {
- dev_dbg(&client->dev,
- "in8 and in9 enabled. temp3 disabled.\n");
- } else {
- dev_dbg(&client->dev,
- "temp3 enabled. in8 and in9 disabled.\n");
- }
- if (data->config1 & CFG1_THERM_HOT) {
- dev_dbg(&client->dev,
- "Automatic THERM, PWM, and temp limits enabled.\n");
- }
-
- if (data->config3 & CFG3_GPIO16_ENABLE) {
- dev_dbg(&client->dev,
- "GPIO16 enabled. THERM pin disabled.\n");
- } else {
- dev_dbg(&client->dev,
- "THERM pin enabled. GPIO16 disabled.\n");
- }
- if (data->config3 & CFG3_VREF_250)
- dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
- else
- dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
- /* Read and pick apart the existing GPIO configuration */
- value = 0;
- for (i = 0; i <= 15; ++i) {
- if ((i & 0x03) == 0) {
- value = adm1026_read_value(client,
- ADM1026_REG_GPIO_CFG_0_3 + i / 4);
- }
- data->gpio_config[i] = value & 0x03;
- value >>= 2;
- }
- data->gpio_config[16] = (data->config3 >> 6) & 0x03;
-
- /* ... and then print it */
- adm1026_print_gpio(client);
-
- /*
- * If the user asks us to reprogram the GPIO config, then
- * do it now.
- */
- if (gpio_input[0] != -1 || gpio_output[0] != -1
- || gpio_inverted[0] != -1 || gpio_normal[0] != -1
- || gpio_fan[0] != -1) {
- adm1026_fixup_gpio(client);
- }
-
- /*
- * WE INTENTIONALLY make no changes to the limits,
- * offsets, pwms, fans and zones. If they were
- * configured, we don't want to mess with them.
- * If they weren't, the default is 100% PWM, no
- * control and will suffice until 'sensors -s'
- * can be run by the user. We DO set the default
- * value for pwm1.auto_pwm_min to its maximum
- * so that enabling automatic pwm fan control
- * without first setting a value for pwm1.auto_pwm_min
- * will not result in potentially dangerous fan speed decrease.
- */
- data->pwm1.auto_pwm_min = 255;
- /* Start monitoring */
- value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
- /* Set MONITOR, clear interrupt acknowledge and s/w reset */
- value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
- dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
- data->config1 = value;
- adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
-
- /* initialize fan_div[] to hardware defaults */
- value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
- (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
- for (i = 0; i <= 7; ++i) {
- data->fan_div[i] = DIV_FROM_REG(value & 0x03);
- value >>= 2;
- }
-}
-
-static void adm1026_print_gpio(struct i2c_client *client)
-{
- struct adm1026_data *data = i2c_get_clientdata(client);
- int i;
-
- dev_dbg(&client->dev, "GPIO config is:\n");
- for (i = 0; i <= 7; ++i) {
- if (data->config2 & (1 << i)) {
- dev_dbg(&client->dev, "\t%sGP%s%d\n",
- data->gpio_config[i] & 0x02 ? "" : "!",
- data->gpio_config[i] & 0x01 ? "OUT" : "IN",
- i);
- } else {
- dev_dbg(&client->dev, "\tFAN%d\n", i);
- }
- }
- for (i = 8; i <= 15; ++i) {
- dev_dbg(&client->dev, "\t%sGP%s%d\n",
- data->gpio_config[i] & 0x02 ? "" : "!",
- data->gpio_config[i] & 0x01 ? "OUT" : "IN",
- i);
- }
- if (data->config3 & CFG3_GPIO16_ENABLE) {
- dev_dbg(&client->dev, "\t%sGP%s16\n",
- data->gpio_config[16] & 0x02 ? "" : "!",
- data->gpio_config[16] & 0x01 ? "OUT" : "IN");
- } else {
- /* GPIO16 is THERM */
- dev_dbg(&client->dev, "\tTHERM\n");
- }
-}
-
-static void adm1026_fixup_gpio(struct i2c_client *client)
-{
- struct adm1026_data *data = i2c_get_clientdata(client);
- int i;
- int value;
-
- /* Make the changes requested. */
- /*
- * We may need to unlock/stop monitoring or soft-reset the
- * chip before we can make changes. This hasn't been
- * tested much. FIXME
- */
-
- /* Make outputs */
- for (i = 0; i <= 16; ++i) {
- if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
- data->gpio_config[gpio_output[i]] |= 0x01;
- /* if GPIO0-7 is output, it isn't a FAN tach */
- if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
- data->config2 |= 1 << gpio_output[i];
- }
-
- /* Input overrides output */
- for (i = 0; i <= 16; ++i) {
- if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
- data->gpio_config[gpio_input[i]] &= ~0x01;
- /* if GPIO0-7 is input, it isn't a FAN tach */
- if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
- data->config2 |= 1 << gpio_input[i];
- }
-
- /* Inverted */
- for (i = 0; i <= 16; ++i) {
- if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
- data->gpio_config[gpio_inverted[i]] &= ~0x02;
- }
-
- /* Normal overrides inverted */
- for (i = 0; i <= 16; ++i) {
- if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
- data->gpio_config[gpio_normal[i]] |= 0x02;
- }
-
- /* Fan overrides input and output */
- for (i = 0; i <= 7; ++i) {
- if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
- data->config2 &= ~(1 << gpio_fan[i]);
- }
-
- /* Write new configs to registers */
- adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
- data->config3 = (data->config3 & 0x3f)
- | ((data->gpio_config[16] & 0x03) << 6);
- adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
- for (i = 15, value = 0; i >= 0; --i) {
- value <<= 2;
- value |= data->gpio_config[i] & 0x03;
- if ((i & 0x03) == 0) {
- adm1026_write_value(client,
- ADM1026_REG_GPIO_CFG_0_3 + i/4,
- value);
- value = 0;
- }
- }
-
- /* Print the new config */
- adm1026_print_gpio(client);
-}
-
-
static struct adm1026_data *adm1026_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int i;
long value, alarms, gpio;
@@ -728,8 +496,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -756,8 +524,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -815,8 +583,8 @@ static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -840,8 +608,8 @@ static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr,
static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -888,8 +656,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -923,8 +691,8 @@ fan_offset(8);
/* Adjust fan_min to account for new fan divisor */
static void fixup_fan_min(struct device *dev, int fan, int old_div)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int new_min;
int new_div = data->fan_div[fan];
@@ -952,8 +720,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int orig_div, new_div;
int err;
@@ -1024,8 +792,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1053,8 +821,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1097,8 +865,8 @@ static ssize_t set_temp_offset(struct device *dev,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1153,8 +921,8 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1192,8 +960,8 @@ static ssize_t show_temp_crit_enable(struct device *dev,
static ssize_t set_temp_crit_enable(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1233,8 +1001,8 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1268,8 +1036,8 @@ static ssize_t set_analog_out_reg(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1378,8 +1146,8 @@ static ssize_t show_alarm_mask(struct device *dev,
static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long mask;
long val;
int err;
@@ -1420,8 +1188,8 @@ static ssize_t show_gpio(struct device *dev, struct device_attribute *attr,
static ssize_t set_gpio(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long gpio;
long val;
int err;
@@ -1453,8 +1221,8 @@ static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr,
static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long mask;
long val;
int err;
@@ -1487,8 +1255,8 @@ static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr,
static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
if (data->pwm1.enable == 1) {
long val;
@@ -1517,8 +1285,8 @@ static ssize_t set_auto_pwm_min(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1553,8 +1321,8 @@ static ssize_t show_pwm_enable(struct device *dev,
static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1026_data *data = i2c_get_clientdata(client);
+ struct adm1026_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int old_enable;
unsigned long val;
int err;
@@ -1829,18 +1597,220 @@ static int adm1026_detect(struct i2c_client *client,
return 0;
}
+static void adm1026_print_gpio(struct i2c_client *client)
+{
+ struct adm1026_data *data = i2c_get_clientdata(client);
+ int i;
+
+ dev_dbg(&client->dev, "GPIO config is:\n");
+ for (i = 0; i <= 7; ++i) {
+ if (data->config2 & (1 << i)) {
+ dev_dbg(&client->dev, "\t%sGP%s%d\n",
+ data->gpio_config[i] & 0x02 ? "" : "!",
+ data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+ i);
+ } else {
+ dev_dbg(&client->dev, "\tFAN%d\n", i);
+ }
+ }
+ for (i = 8; i <= 15; ++i) {
+ dev_dbg(&client->dev, "\t%sGP%s%d\n",
+ data->gpio_config[i] & 0x02 ? "" : "!",
+ data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+ i);
+ }
+ if (data->config3 & CFG3_GPIO16_ENABLE) {
+ dev_dbg(&client->dev, "\t%sGP%s16\n",
+ data->gpio_config[16] & 0x02 ? "" : "!",
+ data->gpio_config[16] & 0x01 ? "OUT" : "IN");
+ } else {
+ /* GPIO16 is THERM */
+ dev_dbg(&client->dev, "\tTHERM\n");
+ }
+}
+
+static void adm1026_fixup_gpio(struct i2c_client *client)
+{
+ struct adm1026_data *data = i2c_get_clientdata(client);
+ int i;
+ int value;
+
+ /* Make the changes requested. */
+ /*
+ * We may need to unlock/stop monitoring or soft-reset the
+ * chip before we can make changes. This hasn't been
+ * tested much. FIXME
+ */
+
+ /* Make outputs */
+ for (i = 0; i <= 16; ++i) {
+ if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
+ data->gpio_config[gpio_output[i]] |= 0x01;
+ /* if GPIO0-7 is output, it isn't a FAN tach */
+ if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
+ data->config2 |= 1 << gpio_output[i];
+ }
+
+ /* Input overrides output */
+ for (i = 0; i <= 16; ++i) {
+ if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
+ data->gpio_config[gpio_input[i]] &= ~0x01;
+ /* if GPIO0-7 is input, it isn't a FAN tach */
+ if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
+ data->config2 |= 1 << gpio_input[i];
+ }
+
+ /* Inverted */
+ for (i = 0; i <= 16; ++i) {
+ if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
+ data->gpio_config[gpio_inverted[i]] &= ~0x02;
+ }
+
+ /* Normal overrides inverted */
+ for (i = 0; i <= 16; ++i) {
+ if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
+ data->gpio_config[gpio_normal[i]] |= 0x02;
+ }
+
+ /* Fan overrides input and output */
+ for (i = 0; i <= 7; ++i) {
+ if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
+ data->config2 &= ~(1 << gpio_fan[i]);
+ }
+
+ /* Write new configs to registers */
+ adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
+ data->config3 = (data->config3 & 0x3f)
+ | ((data->gpio_config[16] & 0x03) << 6);
+ adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
+ for (i = 15, value = 0; i >= 0; --i) {
+ value <<= 2;
+ value |= data->gpio_config[i] & 0x03;
+ if ((i & 0x03) == 0) {
+ adm1026_write_value(client,
+ ADM1026_REG_GPIO_CFG_0_3 + i/4,
+ value);
+ value = 0;
+ }
+ }
+
+ /* Print the new config */
+ adm1026_print_gpio(client);
+}
+
+static void adm1026_init_client(struct i2c_client *client)
+{
+ int value, i;
+ struct adm1026_data *data = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "Initializing device\n");
+ /* Read chip config */
+ data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+ data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
+ data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
+
+ /* Inform user of chip config */
+ dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
+ data->config1);
+ if ((data->config1 & CFG1_MONITOR) == 0) {
+ dev_dbg(&client->dev,
+ "Monitoring not currently enabled.\n");
+ }
+ if (data->config1 & CFG1_INT_ENABLE) {
+ dev_dbg(&client->dev,
+ "SMBALERT interrupts are enabled.\n");
+ }
+ if (data->config1 & CFG1_AIN8_9) {
+ dev_dbg(&client->dev,
+ "in8 and in9 enabled. temp3 disabled.\n");
+ } else {
+ dev_dbg(&client->dev,
+ "temp3 enabled. in8 and in9 disabled.\n");
+ }
+ if (data->config1 & CFG1_THERM_HOT) {
+ dev_dbg(&client->dev,
+ "Automatic THERM, PWM, and temp limits enabled.\n");
+ }
+
+ if (data->config3 & CFG3_GPIO16_ENABLE) {
+ dev_dbg(&client->dev,
+ "GPIO16 enabled. THERM pin disabled.\n");
+ } else {
+ dev_dbg(&client->dev,
+ "THERM pin enabled. GPIO16 disabled.\n");
+ }
+ if (data->config3 & CFG3_VREF_250)
+ dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
+ else
+ dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
+ /* Read and pick apart the existing GPIO configuration */
+ value = 0;
+ for (i = 0; i <= 15; ++i) {
+ if ((i & 0x03) == 0) {
+ value = adm1026_read_value(client,
+ ADM1026_REG_GPIO_CFG_0_3 + i / 4);
+ }
+ data->gpio_config[i] = value & 0x03;
+ value >>= 2;
+ }
+ data->gpio_config[16] = (data->config3 >> 6) & 0x03;
+
+ /* ... and then print it */
+ adm1026_print_gpio(client);
+
+ /*
+ * If the user asks us to reprogram the GPIO config, then
+ * do it now.
+ */
+ if (gpio_input[0] != -1 || gpio_output[0] != -1
+ || gpio_inverted[0] != -1 || gpio_normal[0] != -1
+ || gpio_fan[0] != -1) {
+ adm1026_fixup_gpio(client);
+ }
+
+ /*
+ * WE INTENTIONALLY make no changes to the limits,
+ * offsets, pwms, fans and zones. If they were
+ * configured, we don't want to mess with them.
+ * If they weren't, the default is 100% PWM, no
+ * control and will suffice until 'sensors -s'
+ * can be run by the user. We DO set the default
+ * value for pwm1.auto_pwm_min to its maximum
+ * so that enabling automatic pwm fan control
+ * without first setting a value for pwm1.auto_pwm_min
+ * will not result in potentially dangerous fan speed decrease.
+ */
+ data->pwm1.auto_pwm_min = 255;
+ /* Start monitoring */
+ value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+ /* Set MONITOR, clear interrupt acknowledge and s/w reset */
+ value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
+ dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
+ data->config1 = value;
+ adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
+
+ /* initialize fan_div[] to hardware defaults */
+ value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
+ (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
+ for (i = 0; i <= 7; ++i) {
+ data->fan_div[i] = DIV_FROM_REG(value & 0x03);
+ value >>= 2;
+ }
+}
+
static int adm1026_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct adm1026_data *data;
- int err;
- data = devm_kzalloc(&client->dev, sizeof(struct adm1026_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct adm1026_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
/* Set the VRM version */
@@ -1849,48 +1819,34 @@ static int adm1026_probe(struct i2c_client *client,
/* Initialize the ADM1026 chip */
adm1026_init_client(client);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &adm1026_group);
- if (err)
- return err;
+ /* sysfs hooks */
+ data->groups[0] = &adm1026_group;
if (data->config1 & CFG1_AIN8_9)
- err = sysfs_create_group(&client->dev.kobj,
- &adm1026_group_in8_9);
+ data->groups[1] = &adm1026_group_in8_9;
else
- err = sysfs_create_group(&client->dev.kobj,
- &adm1026_group_temp3);
- if (err)
- goto exitremove;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exitremove;
- }
-
- return 0;
+ data->groups[1] = &adm1026_group_temp3;
- /* Error out and cleanup code */
-exitremove:
- sysfs_remove_group(&client->dev.kobj, &adm1026_group);
- if (data->config1 & CFG1_AIN8_9)
- sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
- else
- sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
- return err;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static int adm1026_remove(struct i2c_client *client)
-{
- struct adm1026_data *data = i2c_get_clientdata(client);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adm1026_group);
- if (data->config1 & CFG1_AIN8_9)
- sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
- else
- sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
- return 0;
-}
+static const struct i2c_device_id adm1026_id[] = {
+ { "adm1026", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm1026_id);
+
+static struct i2c_driver adm1026_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm1026",
+ },
+ .probe = adm1026_probe,
+ .id_table = adm1026_id,
+ .detect = adm1026_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm1026_driver);
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index 78339e880bd6..8c5cdb560258 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -106,45 +106,11 @@ static const u8 ADM1029_REG_FAN_DIV[] = {
};
/*
- * Functions declaration
- */
-
-static int adm1029_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm1029_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int adm1029_remove(struct i2c_client *client);
-static struct adm1029_data *adm1029_update_device(struct device *dev);
-static int adm1029_init_client(struct i2c_client *client);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id adm1029_id[] = {
- { "adm1029", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm1029_id);
-
-static struct i2c_driver adm1029_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm1029",
- },
- .probe = adm1029_probe,
- .remove = adm1029_remove,
- .id_table = adm1029_id,
- .detect = adm1029_detect,
- .address_list = normal_i2c,
-};
-
-/*
* Client data (each client gets its own)
*/
struct adm1029_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -156,6 +122,50 @@ struct adm1029_data {
};
/*
+ * function that update the status of the chips (temperature for example)
+ */
+static struct adm1029_data *adm1029_update_device(struct device *dev)
+{
+ struct adm1029_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+
+ mutex_lock(&data->update_lock);
+ /*
+ * Use the "cache" Luke, don't recheck values
+ * if there are already checked not a long time later
+ */
+ if (time_after(jiffies, data->last_updated + HZ * 2)
+ || !data->valid) {
+ int nr;
+
+ dev_dbg(&client->dev, "Updating adm1029 data\n");
+
+ for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
+ data->temp[nr] =
+ i2c_smbus_read_byte_data(client,
+ ADM1029_REG_TEMP[nr]);
+ }
+ for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
+ data->fan[nr] =
+ i2c_smbus_read_byte_data(client,
+ ADM1029_REG_FAN[nr]);
+ }
+ for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
+ data->fan_div[nr] =
+ i2c_smbus_read_byte_data(client,
+ ADM1029_REG_FAN_DIV[nr]);
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+/*
* Sysfs stuff
*/
@@ -197,8 +207,8 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
static ssize_t set_fan_div(struct device *dev,
struct device_attribute *devattr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1029_data *data = i2c_get_clientdata(client);
+ struct adm1029_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
u8 reg;
long val;
@@ -232,6 +242,9 @@ static ssize_t set_fan_div(struct device *dev,
/* Update the value */
reg = (reg & 0x3F) | (val << 6);
+ /* Update the cache */
+ data->fan_div[attr->index] = reg;
+
/* Write value */
i2c_smbus_write_byte_data(client,
ADM1029_REG_FAN_DIV[attr->index], reg);
@@ -267,7 +280,7 @@ static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
show_fan_div, set_fan_div, 1);
-static struct attribute *adm1029_attributes[] = {
+static struct attribute *adm1029_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -286,9 +299,7 @@ static struct attribute *adm1029_attributes[] = {
NULL
};
-static const struct attribute_group adm1029_group = {
- .attrs = adm1029_attributes,
-};
+ATTRIBUTE_GROUPS(adm1029);
/*
* Real code
@@ -337,48 +348,10 @@ static int adm1029_detect(struct i2c_client *client,
return 0;
}
-static int adm1029_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adm1029_data *data;
- int err;
-
- data = devm_kzalloc(&client->dev, sizeof(struct adm1029_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- /*
- * Initialize the ADM1029 chip
- * Check config register
- */
- if (adm1029_init_client(client) == 0)
- return -ENODEV;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &adm1029_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
-
- exit_remove_files:
- sysfs_remove_group(&client->dev.kobj, &adm1029_group);
- return err;
-}
-
static int adm1029_init_client(struct i2c_client *client)
{
u8 config;
+
config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
if ((config & 0x10) == 0) {
i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
@@ -393,59 +366,49 @@ static int adm1029_init_client(struct i2c_client *client)
return 1;
}
-static int adm1029_remove(struct i2c_client *client)
+static int adm1029_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct adm1029_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adm1029_group);
+ struct device *dev = &client->dev;
+ struct adm1029_data *data;
+ struct device *hwmon_dev;
- return 0;
-}
+ data = devm_kzalloc(dev, sizeof(struct adm1029_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
-/*
- * function that update the status of the chips (temperature for example)
- */
-static struct adm1029_data *adm1029_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1029_data *data = i2c_get_clientdata(client);
+ data->client = client;
+ mutex_init(&data->update_lock);
- mutex_lock(&data->update_lock);
/*
- * Use the "cache" Luke, don't recheck values
- * if there are already checked not a long time later
+ * Initialize the ADM1029 chip
+ * Check config register
*/
- if (time_after(jiffies, data->last_updated + HZ * 2)
- || !data->valid) {
- int nr;
-
- dev_dbg(&client->dev, "Updating adm1029 data\n");
-
- for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
- data->temp[nr] =
- i2c_smbus_read_byte_data(client,
- ADM1029_REG_TEMP[nr]);
- }
- for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
- data->fan[nr] =
- i2c_smbus_read_byte_data(client,
- ADM1029_REG_FAN[nr]);
- }
- for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
- data->fan_div[nr] =
- i2c_smbus_read_byte_data(client,
- ADM1029_REG_FAN_DIV[nr]);
- }
+ if (adm1029_init_client(client) == 0)
+ return -ENODEV;
- data->last_updated = jiffies;
- data->valid = 1;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ adm1029_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1029_id[] = {
+ { "adm1029", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm1029_id);
- return data;
-}
+static struct i2c_driver adm1029_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm1029",
+ },
+ .probe = adm1029_probe,
+ .id_table = adm1029_id,
+ .detect = adm1029_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm1029_driver);
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index a8a540ca8c34..a5818980dad7 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -74,7 +74,8 @@ typedef u8 auto_chan_table_t[8][2];
/* Each client has this additional data */
struct adm1031_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
int chip_type;
char valid; /* !=0 if following fields are valid */
@@ -105,34 +106,6 @@ struct adm1031_data {
s8 temp_crit[3];
};
-static int adm1031_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm1031_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static void adm1031_init_client(struct i2c_client *client);
-static int adm1031_remove(struct i2c_client *client);
-static struct adm1031_data *adm1031_update_device(struct device *dev);
-
-static const struct i2c_device_id adm1031_id[] = {
- { "adm1030", adm1030 },
- { "adm1031", adm1031 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm1031_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1031_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm1031",
- },
- .probe = adm1031_probe,
- .remove = adm1031_remove,
- .id_table = adm1031_id,
- .detect = adm1031_detect,
- .address_list = normal_i2c,
-};
-
static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
@@ -144,6 +117,96 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
return i2c_smbus_write_byte_data(client, reg, value);
}
+static struct adm1031_data *adm1031_update_device(struct device *dev)
+{
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ unsigned long next_update;
+ int chan;
+
+ mutex_lock(&data->update_lock);
+
+ next_update = data->last_updated
+ + msecs_to_jiffies(data->update_interval);
+ if (time_after(jiffies, next_update) || !data->valid) {
+
+ dev_dbg(&client->dev, "Starting adm1031 update\n");
+ for (chan = 0;
+ chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
+ u8 oldh, newh;
+
+ oldh =
+ adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+ data->ext_temp[chan] =
+ adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
+ newh =
+ adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+ if (newh != oldh) {
+ data->ext_temp[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_EXT_TEMP);
+#ifdef DEBUG
+ oldh =
+ adm1031_read_value(client,
+ ADM1031_REG_TEMP(chan));
+
+ /* oldh is actually newer */
+ if (newh != oldh)
+ dev_warn(&client->dev,
+ "Remote temperature may be wrong.\n");
+#endif
+ }
+ data->temp[chan] = newh;
+
+ data->temp_offset[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_TEMP_OFFSET(chan));
+ data->temp_min[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_TEMP_MIN(chan));
+ data->temp_max[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_TEMP_MAX(chan));
+ data->temp_crit[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_TEMP_CRIT(chan));
+ data->auto_temp[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_AUTO_TEMP(chan));
+
+ }
+
+ data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
+ data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
+
+ data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
+ | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
+ if (data->chip_type == adm1030)
+ data->alarm &= 0xc0ff;
+
+ for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
+ chan++) {
+ data->fan_div[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_FAN_DIV(chan));
+ data->fan_min[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_FAN_MIN(chan));
+ data->fan[chan] =
+ adm1031_read_value(client,
+ ADM1031_REG_FAN_SPEED(chan));
+ data->pwm[chan] =
+ (adm1031_read_value(client,
+ ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
+ }
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
#define TEMP_TO_REG(val) (((val) < 0 ? ((val - 500) / 1000) : \
((val + 500) / 1000)))
@@ -280,8 +343,8 @@ static ssize_t
set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
u8 reg;
@@ -355,8 +418,8 @@ static ssize_t
set_auto_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -365,6 +428,7 @@ set_auto_temp_min(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
+ val = clamp_val(val, 0, 127000);
mutex_lock(&data->update_lock);
data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
@@ -384,8 +448,8 @@ static ssize_t
set_auto_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -394,6 +458,7 @@ set_auto_temp_max(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
+ val = clamp_val(val, 0, 127000);
mutex_lock(&data->update_lock);
data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr],
data->pwm[nr]);
@@ -426,8 +491,8 @@ static ssize_t show_pwm(struct device *dev,
static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret, reg;
@@ -539,8 +604,8 @@ static ssize_t show_fan_min(struct device *dev,
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -563,8 +628,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
u8 tmp;
@@ -665,8 +730,8 @@ static ssize_t set_temp_offset(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -686,8 +751,8 @@ static ssize_t set_temp_offset(struct device *dev,
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -696,7 +761,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
- val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
+ val = clamp_val(val, -55000, 127000);
mutex_lock(&data->update_lock);
data->temp_min[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
@@ -707,8 +772,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -717,7 +782,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
- val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
+ val = clamp_val(val, -55000, 127000);
mutex_lock(&data->update_lock);
data->temp_max[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
@@ -728,8 +793,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
@@ -738,7 +803,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
- val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
+ val = clamp_val(val, -55000, 127000);
mutex_lock(&data->update_lock);
data->temp_crit[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
@@ -805,8 +870,7 @@ static const unsigned int update_intervals[] = {
static ssize_t show_update_interval(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", data->update_interval);
}
@@ -815,8 +879,8 @@ static ssize_t set_update_interval(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
+ struct adm1031_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int i, err;
u8 reg;
@@ -948,64 +1012,6 @@ static int adm1031_detect(struct i2c_client *client,
return 0;
}
-static int adm1031_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct adm1031_data *data;
- int err;
-
- data = devm_kzalloc(&client->dev, sizeof(struct adm1031_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- data->chip_type = id->driver_data;
- mutex_init(&data->update_lock);
-
- if (data->chip_type == adm1030)
- data->chan_select_table = &auto_channel_select_table_adm1030;
- else
- data->chan_select_table = &auto_channel_select_table_adm1031;
-
- /* Initialize the ADM1031 chip */
- adm1031_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &adm1031_group);
- if (err)
- return err;
-
- if (data->chip_type == adm1031) {
- err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt);
- if (err)
- goto exit_remove;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &adm1031_group);
- sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
- return err;
-}
-
-static int adm1031_remove(struct i2c_client *client)
-{
- struct adm1031_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adm1031_group);
- sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
- return 0;
-}
-
static void adm1031_init_client(struct i2c_client *client)
{
unsigned int read_val;
@@ -1037,96 +1043,57 @@ static void adm1031_init_client(struct i2c_client *client)
data->update_interval = update_intervals[i];
}
-static struct adm1031_data *adm1031_update_device(struct device *dev)
+static int adm1031_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm1031_data *data = i2c_get_clientdata(client);
- unsigned long next_update;
- int chan;
-
- mutex_lock(&data->update_lock);
-
- next_update = data->last_updated
- + msecs_to_jiffies(data->update_interval);
- if (time_after(jiffies, next_update) || !data->valid) {
-
- dev_dbg(&client->dev, "Starting adm1031 update\n");
- for (chan = 0;
- chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
- u8 oldh, newh;
-
- oldh =
- adm1031_read_value(client, ADM1031_REG_TEMP(chan));
- data->ext_temp[chan] =
- adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
- newh =
- adm1031_read_value(client, ADM1031_REG_TEMP(chan));
- if (newh != oldh) {
- data->ext_temp[chan] =
- adm1031_read_value(client,
- ADM1031_REG_EXT_TEMP);
-#ifdef DEBUG
- oldh =
- adm1031_read_value(client,
- ADM1031_REG_TEMP(chan));
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct adm1031_data *data;
- /* oldh is actually newer */
- if (newh != oldh)
- dev_warn(&client->dev,
- "Remote temperature may be wrong.\n");
-#endif
- }
- data->temp[chan] = newh;
+ data = devm_kzalloc(dev, sizeof(struct adm1031_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- data->temp_offset[chan] =
- adm1031_read_value(client,
- ADM1031_REG_TEMP_OFFSET(chan));
- data->temp_min[chan] =
- adm1031_read_value(client,
- ADM1031_REG_TEMP_MIN(chan));
- data->temp_max[chan] =
- adm1031_read_value(client,
- ADM1031_REG_TEMP_MAX(chan));
- data->temp_crit[chan] =
- adm1031_read_value(client,
- ADM1031_REG_TEMP_CRIT(chan));
- data->auto_temp[chan] =
- adm1031_read_value(client,
- ADM1031_REG_AUTO_TEMP(chan));
+ i2c_set_clientdata(client, data);
+ data->client = client;
+ data->chip_type = id->driver_data;
+ mutex_init(&data->update_lock);
- }
+ if (data->chip_type == adm1030)
+ data->chan_select_table = &auto_channel_select_table_adm1030;
+ else
+ data->chan_select_table = &auto_channel_select_table_adm1031;
- data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
- data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
+ /* Initialize the ADM1031 chip */
+ adm1031_init_client(client);
- data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
- | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
- if (data->chip_type == adm1030)
- data->alarm &= 0xc0ff;
+ /* sysfs hooks */
+ data->groups[0] = &adm1031_group;
+ if (data->chip_type == adm1031)
+ data->groups[1] = &adm1031_group_opt;
- for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
- chan++) {
- data->fan_div[chan] =
- adm1031_read_value(client,
- ADM1031_REG_FAN_DIV(chan));
- data->fan_min[chan] =
- adm1031_read_value(client,
- ADM1031_REG_FAN_MIN(chan));
- data->fan[chan] =
- adm1031_read_value(client,
- ADM1031_REG_FAN_SPEED(chan));
- data->pwm[chan] =
- (adm1031_read_value(client,
- ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
- }
- data->last_updated = jiffies;
- data->valid = 1;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1031_id[] = {
+ { "adm1030", adm1030 },
+ { "adm1031", adm1031 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm1031_id);
- return data;
-}
+static struct i2c_driver adm1031_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm1031",
+ },
+ .probe = adm1031_probe,
+ .id_table = adm1031_id,
+ .detect = adm1031_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm1031_driver);
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 086d02a9ecdc..98114cef1e43 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -130,38 +130,9 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
return SCALE(reg, 1250, 255);
}
-static int adm9240_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adm9240_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static void adm9240_init_client(struct i2c_client *client);
-static int adm9240_remove(struct i2c_client *client);
-static struct adm9240_data *adm9240_update_device(struct device *dev);
-
-/* driver data */
-static const struct i2c_device_id adm9240_id[] = {
- { "adm9240", adm9240 },
- { "ds1780", ds1780 },
- { "lm81", lm81 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adm9240_id);
-
-static struct i2c_driver adm9240_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adm9240",
- },
- .probe = adm9240_probe,
- .remove = adm9240_remove,
- .id_table = adm9240_id,
- .detect = adm9240_detect,
- .address_list = normal_i2c,
-};
-
/* per client data */
struct adm9240_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid;
unsigned long last_updated_measure;
@@ -181,6 +152,110 @@ struct adm9240_data {
u8 vrm; /* -- vrm set on startup, no accessor */
};
+/* write new fan div, callers must hold data->update_lock */
+static void adm9240_write_fan_div(struct i2c_client *client, int nr,
+ u8 fan_div)
+{
+ u8 reg, old, shift = (nr + 2) * 2;
+
+ reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+ old = (reg >> shift) & 3;
+ reg &= ~(3 << shift);
+ reg |= (fan_div << shift);
+ i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
+ dev_dbg(&client->dev,
+ "fan%d clock divider changed from %u to %u\n",
+ nr + 1, 1 << old, 1 << fan_div);
+}
+
+static struct adm9240_data *adm9240_update_device(struct device *dev)
+{
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ /* minimum measurement cycle: 1.75 seconds */
+ if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
+ || !data->valid) {
+
+ for (i = 0; i < 6; i++) { /* read voltages */
+ data->in[i] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_IN(i));
+ }
+ data->alarms = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_INT(0)) |
+ i2c_smbus_read_byte_data(client,
+ ADM9240_REG_INT(1)) << 8;
+
+ /*
+ * read temperature: assume temperature changes less than
+ * 0.5'C per two measurement cycles thus ignore possible
+ * but unlikely aliasing error on lsb reading. --Grant
+ */
+ data->temp = ((i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP) << 8) |
+ i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP_CONF)) / 128;
+
+ for (i = 0; i < 2; i++) { /* read fans */
+ data->fan[i] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_FAN(i));
+
+ /* adjust fan clock divider on overflow */
+ if (data->valid && data->fan[i] == 255 &&
+ data->fan_div[i] < 3) {
+
+ adm9240_write_fan_div(client, i,
+ ++data->fan_div[i]);
+
+ /* adjust fan_min if active, but not to 0 */
+ if (data->fan_min[i] < 255 &&
+ data->fan_min[i] >= 2)
+ data->fan_min[i] /= 2;
+ }
+ }
+ data->last_updated_measure = jiffies;
+ }
+
+ /* minimum config reading cycle: 300 seconds */
+ if (time_after(jiffies, data->last_updated_config + (HZ * 300))
+ || !data->valid) {
+
+ for (i = 0; i < 6; i++) {
+ data->in_min[i] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_IN_MIN(i));
+ data->in_max[i] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_IN_MAX(i));
+ }
+ for (i = 0; i < 2; i++) {
+ data->fan_min[i] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_FAN_MIN(i));
+ }
+ data->temp_max[0] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP_MAX(0));
+ data->temp_max[1] = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_TEMP_MAX(1));
+
+ /* read fan divs and 5-bit VID */
+ i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+ data->fan_div[0] = (i >> 4) & 3;
+ data->fan_div[1] = (i >> 6) & 3;
+ data->vid = i & 0x0f;
+ data->vid |= (i2c_smbus_read_byte_data(client,
+ ADM9240_REG_VID4) & 1) << 4;
+ /* read analog out */
+ data->aout = i2c_smbus_read_byte_data(client,
+ ADM9240_REG_ANALOG_OUT);
+
+ data->last_updated_config = jiffies;
+ data->valid = 1;
+ }
+ mutex_unlock(&data->update_lock);
+ return data;
+}
+
/*** sysfs accessors ***/
/* temperature */
@@ -203,8 +278,8 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -259,8 +334,8 @@ static ssize_t set_in_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -281,8 +356,8 @@ static ssize_t set_in_max(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
}
-/* write new fan div, callers must hold data->update_lock */
-static void adm9240_write_fan_div(struct i2c_client *client, int nr,
- u8 fan_div)
-{
- u8 reg, old, shift = (nr + 2) * 2;
-
- reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
- old = (reg >> shift) & 3;
- reg &= ~(3 << shift);
- reg |= (fan_div << shift);
- i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
- dev_dbg(&client->dev,
- "fan%d clock divider changed from %u to %u\n",
- nr + 1, 1 << old, 1 << fan_div);
-}
-
/*
* set fan speed low limit:
*
@@ -372,8 +431,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = attr->index;
u8 new_div;
unsigned long val;
@@ -485,8 +544,8 @@ static ssize_t set_aout(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -506,8 +565,8 @@ static ssize_t chassis_clear(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
+ struct adm9240_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
if (kstrtoul(buf, 10, &val) || val != 0)
@@ -524,7 +583,7 @@ static ssize_t chassis_clear(struct device *dev,
static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm,
chassis_clear, 12);
-static struct attribute *adm9240_attributes[] = {
+static struct attribute *adm9240_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -568,9 +627,7 @@ static struct attribute *adm9240_attributes[] = {
NULL
};
-static const struct attribute_group adm9240_group = {
- .attrs = adm9240_attributes,
-};
+ATTRIBUTE_GROUPS(adm9240);
/*** sensor chip detect and driver install ***/
@@ -620,49 +677,6 @@ static int adm9240_detect(struct i2c_client *new_client,
return 0;
}
-static int adm9240_probe(struct i2c_client *new_client,
- const struct i2c_device_id *id)
-{
- struct adm9240_data *data;
- int err;
-
- data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(new_client, data);
- mutex_init(&data->update_lock);
-
- adm9240_init_client(new_client);
-
- /* populate sysfs filesystem */
- err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&new_client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
- return err;
-}
-
-static int adm9240_remove(struct i2c_client *client)
-{
- struct adm9240_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adm9240_group);
-
- return 0;
-}
-
static void adm9240_init_client(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
@@ -705,93 +719,48 @@ static void adm9240_init_client(struct i2c_client *client)
}
}
-static struct adm9240_data *adm9240_update_device(struct device *dev)
+static int adm9240_probe(struct i2c_client *new_client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adm9240_data *data = i2c_get_clientdata(client);
- int i;
-
- mutex_lock(&data->update_lock);
-
- /* minimum measurement cycle: 1.75 seconds */
- if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
- || !data->valid) {
-
- for (i = 0; i < 6; i++) { /* read voltages */
- data->in[i] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_IN(i));
- }
- data->alarms = i2c_smbus_read_byte_data(client,
- ADM9240_REG_INT(0)) |
- i2c_smbus_read_byte_data(client,
- ADM9240_REG_INT(1)) << 8;
-
- /*
- * read temperature: assume temperature changes less than
- * 0.5'C per two measurement cycles thus ignore possible
- * but unlikely aliasing error on lsb reading. --Grant
- */
- data->temp = ((i2c_smbus_read_byte_data(client,
- ADM9240_REG_TEMP) << 8) |
- i2c_smbus_read_byte_data(client,
- ADM9240_REG_TEMP_CONF)) / 128;
-
- for (i = 0; i < 2; i++) { /* read fans */
- data->fan[i] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_FAN(i));
-
- /* adjust fan clock divider on overflow */
- if (data->valid && data->fan[i] == 255 &&
- data->fan_div[i] < 3) {
+ struct device *dev = &new_client->dev;
+ struct device *hwmon_dev;
+ struct adm9240_data *data;
- adm9240_write_fan_div(client, i,
- ++data->fan_div[i]);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- /* adjust fan_min if active, but not to 0 */
- if (data->fan_min[i] < 255 &&
- data->fan_min[i] >= 2)
- data->fan_min[i] /= 2;
- }
- }
- data->last_updated_measure = jiffies;
- }
+ i2c_set_clientdata(new_client, data);
+ data->client = new_client;
+ mutex_init(&data->update_lock);
- /* minimum config reading cycle: 300 seconds */
- if (time_after(jiffies, data->last_updated_config + (HZ * 300))
- || !data->valid) {
+ adm9240_init_client(new_client);
- for (i = 0; i < 6; i++) {
- data->in_min[i] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_IN_MIN(i));
- data->in_max[i] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_IN_MAX(i));
- }
- for (i = 0; i < 2; i++) {
- data->fan_min[i] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_FAN_MIN(i));
- }
- data->temp_max[0] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_TEMP_MAX(0));
- data->temp_max[1] = i2c_smbus_read_byte_data(client,
- ADM9240_REG_TEMP_MAX(1));
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+ new_client->name,
+ data,
+ adm9240_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- /* read fan divs and 5-bit VID */
- i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
- data->fan_div[0] = (i >> 4) & 3;
- data->fan_div[1] = (i >> 6) & 3;
- data->vid = i & 0x0f;
- data->vid |= (i2c_smbus_read_byte_data(client,
- ADM9240_REG_VID4) & 1) << 4;
- /* read analog out */
- data->aout = i2c_smbus_read_byte_data(client,
- ADM9240_REG_ANALOG_OUT);
+static const struct i2c_device_id adm9240_id[] = {
+ { "adm9240", adm9240 },
+ { "ds1780", ds1780 },
+ { "lm81", lm81 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adm9240_id);
- data->last_updated_config = jiffies;
- data->valid = 1;
- }
- mutex_unlock(&data->update_lock);
- return data;
-}
+static struct i2c_driver adm9240_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adm9240",
+ },
+ .probe = adm9240_probe,
+ .id_table = adm9240_id,
+ .detect = adm9240_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adm9240_driver);
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index 7f9dc2f86b63..22e0c926989d 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -198,7 +198,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
}
channel = be32_to_cpup(property);
- if (channel > ADS1015_CHANNELS) {
+ if (channel >= ADS1015_CHANNELS) {
dev_err(&client->dev,
"invalid channel index %d on %s\n",
channel, node->full_name);
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index 7092c78f814f..a622d40eec17 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -50,7 +50,7 @@ enum ads7828_chips { ads7828, ads7830 };
/* Client specific data */
struct ads7828_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock; /* Mutex protecting updates */
unsigned long last_updated; /* Last updated time (in jiffies) */
u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH samples */
@@ -72,8 +72,8 @@ static inline u8 ads7828_cmd_byte(u8 cmd, int ch)
/* Update data for the device (all 8 channels) */
static struct ads7828_data *ads7828_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ads7828_data *data = i2c_get_clientdata(client);
+ struct ads7828_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
@@ -116,7 +116,7 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6);
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7);
-static struct attribute *ads7828_attributes[] = {
+static struct attribute *ads7828_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -128,29 +128,17 @@ static struct attribute *ads7828_attributes[] = {
NULL
};
-static const struct attribute_group ads7828_group = {
- .attrs = ads7828_attributes,
-};
-
-static int ads7828_remove(struct i2c_client *client)
-{
- struct ads7828_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &ads7828_group);
-
- return 0;
-}
+ATTRIBUTE_GROUPS(ads7828);
static int ads7828_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct ads7828_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct device *dev = &client->dev;
+ struct ads7828_platform_data *pdata = dev_get_platdata(dev);
struct ads7828_data *data;
- int err;
+ struct device *hwmon_dev;
- data = devm_kzalloc(&client->dev, sizeof(struct ads7828_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -182,24 +170,13 @@ static int ads7828_probe(struct i2c_client *client,
if (!data->diff_input)
data->cmd_byte |= ADS7828_CMD_SD_SE;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
- err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto error;
- }
-
- return 0;
-
-error:
- sysfs_remove_group(&client->dev.kobj, &ads7828_group);
- return err;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ ads7828_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ads7828_device_ids[] = {
@@ -216,7 +193,6 @@ static struct i2c_driver ads7828_driver = {
.id_table = ads7828_device_ids,
.probe = ads7828_probe,
- .remove = ads7828_remove,
};
module_i2c_driver(ads7828_driver);
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index d9299dee37d1..827c03703128 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -51,7 +51,7 @@ struct adt7411_data {
struct mutex update_lock;
unsigned long next_update;
int vref_cached;
- struct device *hwmon_dev;
+ struct i2c_client *client;
};
/*
@@ -111,7 +111,8 @@ static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
static ssize_t adt7411_show_vdd(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct adt7411_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
ADT7411_REG_VDD_MSB, 2);
@@ -121,7 +122,8 @@ static ssize_t adt7411_show_vdd(struct device *dev,
static ssize_t adt7411_show_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
+ struct adt7411_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
ADT7411_REG_INT_TEMP_MSB, 0);
@@ -137,8 +139,8 @@ static ssize_t adt7411_show_input(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7411_data *data = i2c_get_clientdata(client);
+ struct adt7411_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int val;
u8 lsb_reg, lsb_shift;
@@ -180,7 +182,8 @@ static ssize_t adt7411_show_bit(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
+ struct adt7411_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ret = i2c_smbus_read_byte_data(client, attr2->index);
return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
@@ -191,8 +194,8 @@ static ssize_t adt7411_set_bit(struct device *dev,
size_t count)
{
struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7411_data *data = i2c_get_clientdata(client);
+ struct adt7411_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ret;
unsigned long flag;
@@ -245,9 +248,7 @@ static struct attribute *adt7411_attrs[] = {
NULL
};
-static const struct attribute_group adt7411_attr_grp = {
- .attrs = adt7411_attrs,
-};
+ATTRIBUTE_GROUPS(adt7411);
static int adt7411_detect(struct i2c_client *client,
struct i2c_board_info *info)
@@ -281,14 +282,17 @@ static int adt7411_detect(struct i2c_client *client,
static int adt7411_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct adt7411_data *data;
+ struct device *hwmon_dev;
int ret;
- data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->device_lock);
mutex_init(&data->update_lock);
@@ -300,32 +304,10 @@ static int adt7411_probe(struct i2c_client *client,
/* force update on first occasion */
data->next_update = jiffies;
- ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
- if (ret)
- return ret;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- ret = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- dev_info(&client->dev, "successfully registered\n");
-
- return 0;
-
- exit_remove:
- sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
- return ret;
-}
-
-static int adt7411_remove(struct i2c_client *client)
-{
- struct adt7411_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ adt7411_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id adt7411_id[] = {
@@ -339,7 +321,6 @@ static struct i2c_driver adt7411_driver = {
.name = "adt7411",
},
.probe = adt7411_probe,
- .remove = adt7411_remove,
.id_table = adt7411_id,
.detect = adt7411_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index 562cc3881d33..5929e126da63 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -202,8 +202,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
(((value) & prefix##_MASK) >> prefix##_SHIFT)
struct adt7462_data {
- struct device *hwmon_dev;
- struct attribute_group attrs;
+ struct i2c_client *client;
struct mutex lock;
char sensors_valid;
char limits_valid;
@@ -232,30 +231,6 @@ struct adt7462_data {
u8 alarms[ADT7462_ALARM_REG_COUNT];
};
-static int adt7462_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adt7462_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int adt7462_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7462_id[] = {
- { "adt7462", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adt7462_id);
-
-static struct i2c_driver adt7462_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adt7462",
- },
- .probe = adt7462_probe,
- .remove = adt7462_remove,
- .id_table = adt7462_id,
- .detect = adt7462_detect,
- .address_list = normal_i2c,
-};
-
/*
* 16-bit registers on the ADT7462 are low-byte first. The data sheet says
* that the low byte must be read before the high byte.
@@ -705,8 +680,8 @@ static int find_trange_value(int trange)
static struct adt7462_data *adt7462_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long local_jiffies = jiffies;
int i;
@@ -828,8 +803,8 @@ static ssize_t set_temp_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
@@ -866,8 +841,8 @@ static ssize_t set_temp_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
@@ -929,8 +904,8 @@ static ssize_t set_volt_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int x = voltage_multiplier(data, attr->index);
long temp;
@@ -971,8 +946,8 @@ static ssize_t set_volt_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int x = voltage_multiplier(data, attr->index);
long temp;
@@ -1061,8 +1036,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp ||
@@ -1109,8 +1084,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
u8 reg;
@@ -1142,8 +1117,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1172,8 +1147,8 @@ static ssize_t set_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1204,8 +1179,8 @@ static ssize_t set_pwm_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1238,8 +1213,8 @@ static ssize_t set_pwm_hyst(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1283,8 +1258,8 @@ static ssize_t set_pwm_tmax(struct device *dev,
{
int temp;
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int tmin, trange_value;
long trange;
@@ -1324,8 +1299,8 @@ static ssize_t set_pwm_tmin(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1381,8 +1356,8 @@ static ssize_t set_pwm_auto(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1440,8 +1415,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7462_data *data = i2c_get_clientdata(client);
+ struct adt7462_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -1725,7 +1700,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
show_pwm_auto_temp, set_pwm_auto_temp, 3);
-static struct attribute *adt7462_attr[] = {
+static struct attribute *adt7462_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
@@ -1896,6 +1871,8 @@ static struct attribute *adt7462_attr[] = {
NULL
};
+ATTRIBUTE_GROUPS(adt7462);
+
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7462_detect(struct i2c_client *client,
struct i2c_board_info *info)
@@ -1926,46 +1903,41 @@ static int adt7462_detect(struct i2c_client *client,
static int adt7462_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct adt7462_data *data;
- int err;
+ struct device *hwmon_dev;
- data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct adt7462_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
- /* Register sysfs hooks */
- data->attrs.attrs = adt7462_attr;
- err = sysfs_create_group(&client->dev.kobj, &data->attrs);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- return err;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ adt7462_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static int adt7462_remove(struct i2c_client *client)
-{
- struct adt7462_data *data = i2c_get_clientdata(client);
+static const struct i2c_device_id adt7462_id[] = {
+ { "adt7462", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adt7462_id);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- return 0;
-}
+static struct i2c_driver adt7462_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adt7462",
+ },
+ .probe = adt7462_probe,
+ .id_table = adt7462_id,
+ .detect = adt7462_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(adt7462_driver);
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 0f4dea5ccf17..f5da39a68929 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -143,8 +143,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
struct adt7470_data {
- struct device *hwmon_dev;
- struct attribute_group attrs;
+ struct i2c_client *client;
struct mutex lock;
char sensors_valid;
char limits_valid;
@@ -175,30 +174,6 @@ struct adt7470_data {
unsigned int auto_update_interval;
};
-static int adt7470_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int adt7470_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int adt7470_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7470_id[] = {
- { "adt7470", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, adt7470_id);
-
-static struct i2c_driver adt7470_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "adt7470",
- },
- .probe = adt7470_probe,
- .remove = adt7470_remove,
- .id_table = adt7470_id,
- .detect = adt7470_detect,
- .address_list = normal_i2c,
-};
-
/*
* 16-bit registers on the ADT7470 are low-byte first. The data sheet says
* that the low byte must be read before the high byte.
@@ -218,18 +193,6 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg,
|| i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
}
-static void adt7470_init_client(struct i2c_client *client)
-{
- int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
-
- if (reg < 0) {
- dev_err(&client->dev, "cannot read configuration register\n");
- } else {
- /* start monitoring (and do a self-test) */
- i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
- }
-}
-
/* Probe for temperature sensors. Assumes lock is held */
static int adt7470_read_temperatures(struct i2c_client *client,
struct adt7470_data *data)
@@ -314,8 +277,8 @@ static int adt7470_update_thread(void *p)
static struct adt7470_data *adt7470_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long local_jiffies = jiffies;
u8 cfg;
int i;
@@ -445,8 +408,7 @@ static ssize_t set_auto_update_interval(struct device *dev,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
long temp;
if (kstrtol(buf, 10, &temp))
@@ -474,8 +436,7 @@ static ssize_t set_num_temp_sensors(struct device *dev,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
long temp;
if (kstrtol(buf, 10, &temp))
@@ -507,15 +468,15 @@ static ssize_t set_temp_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = clamp_val(temp, 0, 255);
+ temp = clamp_val(temp, -128, 127);
mutex_lock(&data->lock);
data->temp_min[attr->index] = temp;
@@ -541,15 +502,15 @@ static ssize_t set_temp_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = clamp_val(temp, 0, 255);
+ temp = clamp_val(temp, -128, 127);
mutex_lock(&data->lock);
data->temp_max[attr->index] = temp;
@@ -596,8 +557,8 @@ static ssize_t set_fan_max(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp)
@@ -633,8 +594,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp)
@@ -677,8 +638,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
u8 reg;
@@ -710,8 +671,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -742,8 +703,8 @@ static ssize_t set_pwm_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -775,8 +736,8 @@ static ssize_t set_pwm_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
@@ -818,15 +779,15 @@ static ssize_t set_pwm_tmin(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
return -EINVAL;
temp = DIV_ROUND_CLOSEST(temp, 1000);
- temp = clamp_val(temp, 0, 255);
+ temp = clamp_val(temp, -128, 127);
mutex_lock(&data->lock);
data->pwm_tmin[attr->index] = temp;
@@ -852,8 +813,8 @@ static ssize_t set_pwm_auto(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index);
int pwm_auto_reg_mask;
long temp;
@@ -913,8 +874,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
- struct i2c_client *client = to_i2c_client(dev);
- struct adt7470_data *data = i2c_get_clientdata(client);
+ struct adt7470_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index);
long temp;
u8 reg;
@@ -1131,7 +1092,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
show_pwm_auto_temp, set_pwm_auto_temp, 3);
-static struct attribute *adt7470_attr[] = {
+static struct attribute *adt7470_attrs[] = {
&dev_attr_alarm_mask.attr,
&dev_attr_num_temp_sensors.attr,
&dev_attr_auto_update_interval.attr,
@@ -1223,6 +1184,8 @@ static struct attribute *adt7470_attr[] = {
NULL
};
+ATTRIBUTE_GROUPS(adt7470);
+
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7470_detect(struct i2c_client *client,
struct i2c_board_info *info)
@@ -1250,14 +1213,26 @@ static int adt7470_detect(struct i2c_client *client,
return 0;
}
+static void adt7470_init_client(struct i2c_client *client)
+{
+ int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
+
+ if (reg < 0) {
+ dev_err(&client->dev, "cannot read configuration register\n");
+ } else {
+ /* start monitoring (and do a self-test) */
+ i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
+ }
+}
+
static int adt7470_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct adt7470_data *data;
- int err;
+ struct device *hwmon_dev;
- data = devm_kzalloc(&client->dev, sizeof(struct adt7470_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct adt7470_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -1265,6 +1240,7 @@ static int adt7470_probe(struct i2c_client *client,
data->auto_update_interval = AUTO_UPDATE_INTERVAL;
i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
@@ -1273,32 +1249,21 @@ static int adt7470_probe(struct i2c_client *client,
adt7470_init_client(client);
/* Register sysfs hooks */
- data->attrs.attrs = adt7470_attr;
- err = sysfs_create_group(&client->dev.kobj, &data->attrs);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ adt7470_groups);
+
+ if (IS_ERR(hwmon_dev))
+ return PTR_ERR(hwmon_dev);
init_completion(&data->auto_update_stop);
data->auto_update = kthread_run(adt7470_update_thread, client, "%s",
- dev_name(data->hwmon_dev));
+ dev_name(hwmon_dev));
if (IS_ERR(data->auto_update)) {
- err = PTR_ERR(data->auto_update);
- goto exit_unregister;
+ return PTR_ERR(data->auto_update);
}
return 0;
-
-exit_unregister:
- hwmon_device_unregister(data->hwmon_dev);
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- return err;
}
static int adt7470_remove(struct i2c_client *client)
@@ -1307,11 +1272,27 @@ static int adt7470_remove(struct i2c_client *client)
kthread_stop(data->auto_update);
wait_for_completion(&data->auto_update_stop);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
return 0;
}
+static const struct i2c_device_id adt7470_id[] = {
+ { "adt7470", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adt7470_id);
+
+static struct i2c_driver adt7470_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adt7470",
+ },
+ .probe = adt7470_probe,
+ .remove = adt7470_remove,
+ .id_table = adt7470_id,
+ .detect = adt7470_detect,
+ .address_list = normal_i2c,
+};
+
module_i2c_driver(adt7470_driver);
MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
index eea817296513..12e851a5af48 100644
--- a/drivers/hwmon/amc6821.c
+++ b/drivers/hwmon/amc6821.c
@@ -21,7 +21,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/module.h>
#include <linux/init.h>
@@ -33,7 +32,6 @@
#include <linux/err.h>
#include <linux/mutex.h>
-
/*
* Addresses to scan.
*/
@@ -41,8 +39,6 @@
static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
-
-
/*
* Insmod parameters
*/
@@ -53,7 +49,6 @@ module_param(pwminv, int, S_IRUGO);
static int init = 1; /*Power-on initialization.*/
module_param(init, int, S_IRUGO);
-
enum chips { amc6821 };
#define AMC6821_REG_DEV_ID 0x3D
@@ -152,46 +147,12 @@ static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
AMC6821_REG_TACH_LLIMITH,
AMC6821_REG_TACH_HLIMITH, };
-static int amc6821_probe(
- struct i2c_client *client,
- const struct i2c_device_id *id);
-static int amc6821_detect(
- struct i2c_client *client,
- struct i2c_board_info *info);
-static int amc6821_init_client(struct i2c_client *client);
-static int amc6821_remove(struct i2c_client *client);
-static struct amc6821_data *amc6821_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id amc6821_id[] = {
- { "amc6821", amc6821 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, amc6821_id);
-
-static struct i2c_driver amc6821_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "amc6821",
- },
- .probe = amc6821_probe,
- .remove = amc6821_remove,
- .id_table = amc6821_id,
- .detect = amc6821_detect,
- .address_list = normal_i2c,
-};
-
-
/*
* Client data (each client gets its own)
*/
struct amc6821_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -213,6 +174,108 @@ struct amc6821_data {
u8 stat2;
};
+static struct amc6821_data *amc6821_update_device(struct device *dev)
+{
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int timeout = HZ;
+ u8 reg;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + timeout) ||
+ !data->valid) {
+
+ for (i = 0; i < TEMP_IDX_LEN; i++)
+ data->temp[i] = i2c_smbus_read_byte_data(client,
+ temp_reg[i]);
+
+ data->stat1 = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_STAT1);
+ data->stat2 = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_STAT2);
+
+ data->pwm1 = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_DCY);
+ for (i = 0; i < FAN1_IDX_LEN; i++) {
+ data->fan[i] = i2c_smbus_read_byte_data(
+ client,
+ fan_reg_low[i]);
+ data->fan[i] += i2c_smbus_read_byte_data(
+ client,
+ fan_reg_hi[i]) << 8;
+ }
+ data->fan1_div = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_CONF4);
+ data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
+
+ data->pwm1_auto_point_pwm[0] = 0;
+ data->pwm1_auto_point_pwm[2] = 255;
+ data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_DCY_LOW_TEMP);
+
+ data->temp1_auto_point_temp[0] =
+ i2c_smbus_read_byte_data(client,
+ AMC6821_REG_PSV_TEMP);
+ data->temp2_auto_point_temp[0] =
+ data->temp1_auto_point_temp[0];
+ reg = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_LTEMP_FAN_CTRL);
+ data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
+ reg &= 0x07;
+ reg = 0x20 >> reg;
+ if (reg > 0)
+ data->temp1_auto_point_temp[2] =
+ data->temp1_auto_point_temp[1] +
+ (data->pwm1_auto_point_pwm[2] -
+ data->pwm1_auto_point_pwm[1]) / reg;
+ else
+ data->temp1_auto_point_temp[2] = 255;
+
+ reg = i2c_smbus_read_byte_data(client,
+ AMC6821_REG_RTEMP_FAN_CTRL);
+ data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
+ reg &= 0x07;
+ reg = 0x20 >> reg;
+ if (reg > 0)
+ data->temp2_auto_point_temp[2] =
+ data->temp2_auto_point_temp[1] +
+ (data->pwm1_auto_point_pwm[2] -
+ data->pwm1_auto_point_pwm[1]) / reg;
+ else
+ data->temp2_auto_point_temp[2] = 255;
+
+ reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
+ reg = (reg >> 5) & 0x3;
+ switch (reg) {
+ case 0: /*open loop: software sets pwm1*/
+ data->pwm1_auto_channels_temp = 0;
+ data->pwm1_enable = 1;
+ break;
+ case 2: /*closed loop: remote T (temp2)*/
+ data->pwm1_auto_channels_temp = 2;
+ data->pwm1_enable = 2;
+ break;
+ case 3: /*closed loop: local and remote T (temp2)*/
+ data->pwm1_auto_channels_temp = 3;
+ data->pwm1_enable = 3;
+ break;
+ case 1: /*
+ * semi-open loop: software sets rpm, chip controls
+ * pwm1, currently not implemented
+ */
+ data->pwm1_auto_channels_temp = 0;
+ data->pwm1_enable = 0;
+ break;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+ mutex_unlock(&data->update_lock);
+ return data;
+}
static ssize_t get_temp(
struct device *dev,
@@ -225,16 +288,14 @@ static ssize_t get_temp(
return sprintf(buf, "%d\n", data->temp[ix] * 1000);
}
-
-
static ssize_t set_temp(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ix = to_sensor_dev_attr(attr)->index;
long val;
@@ -253,9 +314,6 @@ static ssize_t set_temp(
return count;
}
-
-
-
static ssize_t get_temp_alarm(
struct device *dev,
struct device_attribute *devattr,
@@ -294,9 +352,6 @@ static ssize_t get_temp_alarm(
return sprintf(buf, "0");
}
-
-
-
static ssize_t get_temp2_fault(
struct device *dev,
struct device_attribute *devattr,
@@ -324,8 +379,8 @@ static ssize_t set_pwm1(
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int ret = kstrtol(buf, 10, &val);
if (ret)
@@ -353,18 +408,20 @@ static ssize_t set_pwm1_enable(
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int config = kstrtol(buf, 10, &val);
if (config)
return config;
+ mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
if (config < 0) {
dev_err(&client->dev,
"Error reading configuration register, aborting.\n");
- return config;
+ count = config;
+ goto unlock;
}
switch (val) {
@@ -381,19 +438,19 @@ static ssize_t set_pwm1_enable(
config |= AMC6821_CONF1_FDRC1;
break;
default:
- return -EINVAL;
+ count = -EINVAL;
+ goto unlock;
}
- mutex_lock(&data->update_lock);
if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
dev_err(&client->dev,
"Configuration register write error, aborting.\n");
count = -EIO;
}
+unlock:
mutex_unlock(&data->update_lock);
return count;
}
-
static ssize_t get_pwm1_auto_channels_temp(
struct device *dev,
struct device_attribute *devattr,
@@ -403,7 +460,6 @@ static ssize_t get_pwm1_auto_channels_temp(
return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
}
-
static ssize_t get_temp_auto_point_temp(
struct device *dev,
struct device_attribute *devattr,
@@ -425,7 +481,6 @@ static ssize_t get_temp_auto_point_temp(
}
}
-
static ssize_t get_pwm1_auto_point_pwm(
struct device *dev,
struct device_attribute *devattr,
@@ -436,7 +491,6 @@ static ssize_t get_pwm1_auto_point_pwm(
return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
}
-
static inline ssize_t set_slope_register(struct i2c_client *client,
u8 reg,
u8 dpwm,
@@ -459,16 +513,14 @@ static inline ssize_t set_slope_register(struct i2c_client *client,
return 0;
}
-
-
static ssize_t set_temp_auto_point_temp(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = amc6821_update_device(dev);
+ struct i2c_client *client = data->client;
int ix = to_sensor_dev_attr_2(attr)->index;
int nr = to_sensor_dev_attr_2(attr)->nr;
u8 *ptemp;
@@ -493,8 +545,9 @@ static ssize_t set_temp_auto_point_temp(
return -EINVAL;
}
- data->valid = 0;
mutex_lock(&data->update_lock);
+ data->valid = 0;
+
switch (ix) {
case 0:
ptemp[0] = clamp_val(val / 1000, 0,
@@ -533,16 +586,14 @@ EXIT:
return count;
}
-
-
static ssize_t set_pwm1_auto_point_pwm(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int dpwm;
long val;
int ret = kstrtol(buf, 10, &val);
@@ -587,8 +638,6 @@ static ssize_t get_fan(
return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
}
-
-
static ssize_t get_fan1_fault(
struct device *dev,
struct device_attribute *devattr,
@@ -601,15 +650,13 @@ static ssize_t get_fan1_fault(
return sprintf(buf, "0");
}
-
-
static ssize_t set_fan(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int ix = to_sensor_dev_attr(attr)->index;
int ret = kstrtol(buf, 10, &val);
@@ -635,8 +682,6 @@ EXIT:
return count;
}
-
-
static ssize_t get_fan1_div(
struct device *dev,
struct device_attribute *devattr,
@@ -651,20 +696,21 @@ static ssize_t set_fan1_div(
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
+ struct amc6821_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int config = kstrtol(buf, 10, &val);
if (config)
return config;
+ mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
if (config < 0) {
dev_err(&client->dev,
"Error reading configuration register, aborting.\n");
- return config;
+ count = config;
+ goto EXIT;
}
- mutex_lock(&data->update_lock);
switch (val) {
case 2:
config &= ~AMC6821_CONF4_PSPR;
@@ -688,8 +734,6 @@ EXIT:
return count;
}
-
-
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
get_temp, NULL, IDX_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
@@ -704,7 +748,7 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
get_temp_alarm, NULL, IDX_TEMP1_MAX);
static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
get_temp_alarm, NULL, IDX_TEMP1_CRIT);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
get_temp, NULL, IDX_TEMP2_INPUT);
static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp,
set_temp, IDX_TEMP2_MIN);
@@ -754,8 +798,6 @@ static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);
-
-
static struct attribute *amc6821_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -792,11 +834,7 @@ static struct attribute *amc6821_attrs[] = {
NULL
};
-static struct attribute_group amc6821_attr_grp = {
- .attrs = amc6821_attrs,
-};
-
-
+ATTRIBUTE_GROUPS(amc6821);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int amc6821_detect(
@@ -844,53 +882,6 @@ static int amc6821_detect(
return 0;
}
-static int amc6821_probe(
- struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct amc6821_data *data;
- int err;
-
- data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- /*
- * Initialize the amc6821 chip
- */
- err = amc6821_init_client(client);
- if (err)
- return err;
-
- err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (!IS_ERR(data->hwmon_dev))
- return 0;
-
- err = PTR_ERR(data->hwmon_dev);
- dev_err(&client->dev, "error registering hwmon device.\n");
- sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
- return err;
-}
-
-static int amc6821_remove(struct i2c_client *client)
-{
- struct amc6821_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
-
- return 0;
-}
-
-
static int amc6821_init_client(struct i2c_client *client)
{
int config;
@@ -977,109 +968,51 @@ static int amc6821_init_client(struct i2c_client *client)
return 0;
}
-
-static struct amc6821_data *amc6821_update_device(struct device *dev)
+static int amc6821_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct amc6821_data *data = i2c_get_clientdata(client);
- int timeout = HZ;
- u8 reg;
- int i;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + timeout) ||
- !data->valid) {
-
- for (i = 0; i < TEMP_IDX_LEN; i++)
- data->temp[i] = i2c_smbus_read_byte_data(client,
- temp_reg[i]);
+ struct device *dev = &client->dev;
+ struct amc6821_data *data;
+ struct device *hwmon_dev;
+ int err;
- data->stat1 = i2c_smbus_read_byte_data(client,
- AMC6821_REG_STAT1);
- data->stat2 = i2c_smbus_read_byte_data(client,
- AMC6821_REG_STAT2);
+ data = devm_kzalloc(dev, sizeof(struct amc6821_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- data->pwm1 = i2c_smbus_read_byte_data(client,
- AMC6821_REG_DCY);
- for (i = 0; i < FAN1_IDX_LEN; i++) {
- data->fan[i] = i2c_smbus_read_byte_data(
- client,
- fan_reg_low[i]);
- data->fan[i] += i2c_smbus_read_byte_data(
- client,
- fan_reg_hi[i]) << 8;
- }
- data->fan1_div = i2c_smbus_read_byte_data(client,
- AMC6821_REG_CONF4);
- data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
+ data->client = client;
+ mutex_init(&data->update_lock);
- data->pwm1_auto_point_pwm[0] = 0;
- data->pwm1_auto_point_pwm[2] = 255;
- data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
- AMC6821_REG_DCY_LOW_TEMP);
+ /*
+ * Initialize the amc6821 chip
+ */
+ err = amc6821_init_client(client);
+ if (err)
+ return err;
- data->temp1_auto_point_temp[0] =
- i2c_smbus_read_byte_data(client,
- AMC6821_REG_PSV_TEMP);
- data->temp2_auto_point_temp[0] =
- data->temp1_auto_point_temp[0];
- reg = i2c_smbus_read_byte_data(client,
- AMC6821_REG_LTEMP_FAN_CTRL);
- data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
- reg &= 0x07;
- reg = 0x20 >> reg;
- if (reg > 0)
- data->temp1_auto_point_temp[2] =
- data->temp1_auto_point_temp[1] +
- (data->pwm1_auto_point_pwm[2] -
- data->pwm1_auto_point_pwm[1]) / reg;
- else
- data->temp1_auto_point_temp[2] = 255;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ amc6821_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- reg = i2c_smbus_read_byte_data(client,
- AMC6821_REG_RTEMP_FAN_CTRL);
- data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
- reg &= 0x07;
- reg = 0x20 >> reg;
- if (reg > 0)
- data->temp2_auto_point_temp[2] =
- data->temp2_auto_point_temp[1] +
- (data->pwm1_auto_point_pwm[2] -
- data->pwm1_auto_point_pwm[1]) / reg;
- else
- data->temp2_auto_point_temp[2] = 255;
+static const struct i2c_device_id amc6821_id[] = {
+ { "amc6821", amc6821 },
+ { }
+};
- reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
- reg = (reg >> 5) & 0x3;
- switch (reg) {
- case 0: /*open loop: software sets pwm1*/
- data->pwm1_auto_channels_temp = 0;
- data->pwm1_enable = 1;
- break;
- case 2: /*closed loop: remote T (temp2)*/
- data->pwm1_auto_channels_temp = 2;
- data->pwm1_enable = 2;
- break;
- case 3: /*closed loop: local and remote T (temp2)*/
- data->pwm1_auto_channels_temp = 3;
- data->pwm1_enable = 3;
- break;
- case 1: /*
- * semi-open loop: software sets rpm, chip controls
- * pwm1, currently not implemented
- */
- data->pwm1_auto_channels_temp = 0;
- data->pwm1_enable = 0;
- break;
- }
+MODULE_DEVICE_TABLE(i2c, amc6821_id);
- data->last_updated = jiffies;
- data->valid = 1;
- }
- mutex_unlock(&data->update_lock);
- return data;
-}
+static struct i2c_driver amc6821_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "amc6821",
+ },
+ .probe = amc6821_probe,
+ .id_table = amc6821_id,
+ .detect = amc6821_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(amc6821_driver);
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index 71463689d163..c77644d45a02 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -300,7 +300,7 @@ static ssize_t store_fan16(struct device *dev,
* respectively. That doesn't mean that's what the motherboard provides. :)
*/
-static int asc7621_in_scaling[] = {
+static const int asc7621_in_scaling[] = {
2500, 2250, 3300, 5000, 12000
};
@@ -451,7 +451,7 @@ static ssize_t store_temp62(struct device *dev,
* hwmon specs, we synthesize the auto_point_2 from them.
*/
-static u32 asc7621_range_map[] = {
+static const u32 asc7621_range_map[] = {
2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
};
@@ -512,7 +512,7 @@ static ssize_t show_pwm_ac(struct device *dev,
{
SETUP_SHOW_DATA_PARAM(dev, attr);
u8 config, altbit, regval;
- u8 map[] = {
+ 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;
- u16 map[] = {
+ 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,
@@ -651,7 +651,7 @@ static ssize_t store_pwm_enable(struct device *dev,
return count;
}
-static u32 asc7621_pwm_freq_map[] = {
+static const u32 asc7621_pwm_freq_map[] = {
10, 15, 23, 30, 38, 47, 62, 94,
23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
};
@@ -700,7 +700,7 @@ static ssize_t store_pwm_freq(struct device *dev,
return count;
}
-static u32 asc7621_pwm_auto_spinup_map[] = {
+static const u32 asc7621_pwm_auto_spinup_map[] = {
0, 100, 250, 400, 700, 1000, 2000, 4000
};
@@ -749,7 +749,7 @@ static ssize_t store_pwm_ast(struct device *dev,
return count;
}
-static u32 asc7621_temp_smoothing_time_map[] = {
+static const u32 asc7621_temp_smoothing_time_map[] = {
35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
};
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index ae208f612198..cccef87963e0 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -688,7 +688,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(atk_debugfs_gitm,
atk_debugfs_gitm_get,
NULL,
- "0x%08llx\n")
+ "0x%08llx\n");
static int atk_acpi_print(char *buf, size_t sz, union acpi_object *obj)
{
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index 2ae8a304b5ef..4c829bb2f9db 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -46,7 +46,7 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
struct atxp1_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
unsigned long last_updated;
u8 valid;
@@ -61,11 +61,8 @@ struct atxp1_data {
static struct atxp1_data *atxp1_update_device(struct device *dev)
{
- struct i2c_client *client;
- struct atxp1_data *data;
-
- client = to_i2c_client(dev);
- data = i2c_get_clientdata(client);
+ struct atxp1_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
@@ -105,15 +102,12 @@ static ssize_t atxp1_storevcore(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct atxp1_data *data;
- struct i2c_client *client;
+ struct atxp1_data *data = atxp1_update_device(dev);
+ struct i2c_client *client = data->client;
int vid, cvid;
unsigned long vcore;
int err;
- client = to_i2c_client(dev);
- data = atxp1_update_device(dev);
-
err = kstrtoul(buf, 10, &vcore);
if (err)
return err;
@@ -184,14 +178,11 @@ static ssize_t atxp1_storegpio1(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
- struct atxp1_data *data;
- struct i2c_client *client;
+ struct atxp1_data *data = atxp1_update_device(dev);
+ struct i2c_client *client = data->client;
unsigned long value;
int err;
- client = to_i2c_client(dev);
- data = atxp1_update_device(dev);
-
err = kstrtoul(buf, 16, &value);
if (err)
return err;
@@ -234,7 +225,7 @@ static ssize_t atxp1_storegpio2(struct device *dev,
const char *buf, size_t count)
{
struct atxp1_data *data = atxp1_update_device(dev);
- struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_client *client = data->client;
unsigned long value;
int err;
@@ -260,17 +251,13 @@ static ssize_t atxp1_storegpio2(struct device *dev,
*/
static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
-static struct attribute *atxp1_attributes[] = {
+static struct attribute *atxp1_attrs[] = {
&dev_attr_gpio1.attr,
&dev_attr_gpio2.attr,
&dev_attr_cpu0_vid.attr,
NULL
};
-
-static const struct attribute_group atxp1_group = {
- .attrs = atxp1_attributes,
-};
-
+ATTRIBUTE_GROUPS(atxp1);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int atxp1_detect(struct i2c_client *new_client,
@@ -314,50 +301,30 @@ static int atxp1_detect(struct i2c_client *new_client,
return 0;
}
-static int atxp1_probe(struct i2c_client *new_client,
+static int atxp1_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct atxp1_data *data;
- int err;
+ struct device *hwmon_dev;
- data = devm_kzalloc(&new_client->dev, sizeof(struct atxp1_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct atxp1_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/* Get VRM */
data->vrm = vid_which_vrm();
- i2c_set_clientdata(new_client, data);
+ data->client = client;
mutex_init(&data->update_lock);
- /* Register sysfs hooks */
- err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&new_client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- dev_info(&new_client->dev, "Using VRM: %d.%d\n",
- data->vrm / 10, data->vrm % 10);
-
- return 0;
-
-exit_remove_files:
- sysfs_remove_group(&new_client->dev.kobj, &atxp1_group);
- return err;
-};
-
-static int atxp1_remove(struct i2c_client *client)
-{
- struct atxp1_data *data = i2c_get_clientdata(client);
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ atxp1_groups);
+ if (IS_ERR(hwmon_dev))
+ return PTR_ERR(hwmon_dev);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &atxp1_group);
+ dev_info(dev, "Using VRM: %d.%d\n", data->vrm / 10, data->vrm % 10);
return 0;
};
@@ -374,7 +341,6 @@ static struct i2c_driver atxp1_driver = {
.name = "atxp1",
},
.probe = atxp1_probe,
- .remove = atxp1_remove,
.id_table = atxp1_id,
.detect = atxp1_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index afd31042b452..d14ab3c45daa 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -194,7 +194,7 @@ static ssize_t da9052_hwmon_show_name(struct device *dev,
struct device_attribute *devattr,
char *buf)
{
- return sprintf(buf, "da9052-hwmon\n");
+ return sprintf(buf, "da9052\n");
}
static ssize_t show_label(struct device *dev,
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c
index 73b3865f1207..35eb7738d711 100644
--- a/drivers/hwmon/da9055-hwmon.c
+++ b/drivers/hwmon/da9055-hwmon.c
@@ -204,7 +204,7 @@ static ssize_t da9055_hwmon_show_name(struct device *dev,
struct device_attribute *devattr,
char *buf)
{
- return sprintf(buf, "da9055-hwmon\n");
+ return sprintf(buf, "da9055\n");
}
static ssize_t show_label(struct device *dev,
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
index 0918b9136588..edf550fc4eef 100644
--- a/drivers/hwmon/ds620.c
+++ b/drivers/hwmon/ds620.c
@@ -67,7 +67,7 @@ static const u8 DS620_REG_TEMP[3] = {
/* Each client has this additional data */
struct ds620_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -106,8 +106,8 @@ static void ds620_init_client(struct i2c_client *client)
static struct ds620_data *ds620_update_client(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ds620_data *data = i2c_get_clientdata(client);
+ struct ds620_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
struct ds620_data *ret = data;
mutex_lock(&data->update_lock);
@@ -158,8 +158,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
long val;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
- struct i2c_client *client = to_i2c_client(dev);
- struct ds620_data *data = i2c_get_clientdata(client);
+ struct ds620_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
res = kstrtol(buf, 10, &val);
@@ -181,13 +181,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ds620_data *data = ds620_update_client(dev);
- struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_client *client;
u16 conf, new_conf;
int res;
if (IS_ERR(data))
return PTR_ERR(data);
+ client = data->client;
+
/* reset alarms if necessary */
res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
if (res < 0)
@@ -213,7 +215,7 @@ static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL,
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
DS620_REG_CONFIG_THF);
-static struct attribute *ds620_attributes[] = {
+static struct attribute *ds620_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -222,55 +224,28 @@ static struct attribute *ds620_attributes[] = {
NULL
};
-static const struct attribute_group ds620_group = {
- .attrs = ds620_attributes,
-};
+ATTRIBUTE_GROUPS(ds620);
static int ds620_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct ds620_data *data;
- int err;
- data = devm_kzalloc(&client->dev, sizeof(struct ds620_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct ds620_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
/* Initialize the DS620 chip */
ds620_init_client(client);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &ds620_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- dev_info(&client->dev, "temperature sensor found\n");
-
- return 0;
-
-exit_remove_files:
- sysfs_remove_group(&client->dev.kobj, &ds620_group);
- return err;
-}
-
-static int ds620_remove(struct i2c_client *client)
-{
- struct ds620_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &ds620_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, ds620_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ds620_id[] = {
@@ -287,7 +262,6 @@ static struct i2c_driver ds620_driver = {
.name = "ds620",
},
.probe = ds620_probe,
- .remove = ds620_remove,
.id_table = ds620_id,
};
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index a37b2204a418..1ea7ca510f84 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -416,7 +416,7 @@ static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)
}
}
-static struct regmap_config emc1403_regmap_config = {
+static const struct regmap_config emc1403_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
index fd892dd48e4c..952fe692d764 100644
--- a/drivers/hwmon/emc2103.c
+++ b/drivers/hwmon/emc2103.c
@@ -66,7 +66,8 @@ struct temperature {
};
struct emc2103_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[4];
struct mutex update_lock;
bool valid; /* registers are valid */
bool fan_rpm_control;
@@ -146,8 +147,8 @@ static void read_fan_config_from_i2c(struct i2c_client *client)
static struct emc2103_data *emc2103_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc2103_data *data = i2c_get_clientdata(client);
+ struct emc2103_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
@@ -242,17 +243,15 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(da)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct emc2103_data *data = i2c_get_clientdata(client);
+ struct emc2103_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int result = kstrtol(buf, 10, &val);
if (result < 0)
return result;
- val = DIV_ROUND_CLOSEST(val, 1000);
- if ((val < -63) || (val > 127))
- return -EINVAL;
+ val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127);
mutex_lock(&data->update_lock);
data->temp_min[nr] = val;
@@ -266,17 +265,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(da)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct emc2103_data *data = i2c_get_clientdata(client);
+ struct emc2103_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int result = kstrtol(buf, 10, &val);
if (result < 0)
return result;
- val = DIV_ROUND_CLOSEST(val, 1000);
- if ((val < -63) || (val > 127))
- return -EINVAL;
+ val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127);
mutex_lock(&data->update_lock);
data->temp_max[nr] = val;
@@ -314,7 +311,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct emc2103_data *data = emc2103_update_device(dev);
- struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_client *client = data->client;
int new_range_bits, old_div = 8 / data->fan_multiplier;
long new_div;
@@ -389,16 +386,15 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct emc2103_data *data = emc2103_update_device(dev);
- struct i2c_client *client = to_i2c_client(dev);
- long rpm_target;
+ struct i2c_client *client = data->client;
+ unsigned long rpm_target;
- int result = kstrtol(buf, 10, &rpm_target);
+ int result = kstrtoul(buf, 10, &rpm_target);
if (result < 0)
return result;
/* Datasheet states 16384 as maximum RPM target (table 3.2) */
- if ((rpm_target < 0) || (rpm_target > 16384))
- return -EINVAL;
+ rpm_target = clamp_val(rpm_target, 0, 16384);
mutex_lock(&data->update_lock);
@@ -433,8 +429,8 @@ show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf)
static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc2103_data *data = i2c_get_clientdata(client);
+ struct emc2103_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long new_value;
u8 conf_reg;
@@ -585,7 +581,8 @@ static int
emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct emc2103_data *data;
- int status;
+ struct device *hwmon_dev;
+ int status, idx = 0;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
@@ -596,6 +593,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -ENOMEM;
i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
/* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */
@@ -629,60 +627,21 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
- /* Register sysfs hooks */
- status = sysfs_create_group(&client->dev.kobj, &emc2103_group);
- if (status)
- return status;
-
- if (data->temp_count >= 3) {
- status = sysfs_create_group(&client->dev.kobj,
- &emc2103_temp3_group);
- if (status)
- goto exit_remove;
- }
-
- if (data->temp_count == 4) {
- status = sysfs_create_group(&client->dev.kobj,
- &emc2103_temp4_group);
- if (status)
- goto exit_remove_temp3;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- status = PTR_ERR(data->hwmon_dev);
- goto exit_remove_temp4;
- }
-
- dev_info(&client->dev, "%s: sensor '%s'\n",
- dev_name(data->hwmon_dev), client->name);
-
- return 0;
-
-exit_remove_temp4:
- if (data->temp_count == 4)
- sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
-exit_remove_temp3:
+ /* sysfs hooks */
+ data->groups[idx++] = &emc2103_group;
if (data->temp_count >= 3)
- sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &emc2103_group);
- return status;
-}
-
-static int emc2103_remove(struct i2c_client *client)
-{
- struct emc2103_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
-
+ data->groups[idx++] = &emc2103_temp3_group;
if (data->temp_count == 4)
- sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
+ data->groups[idx++] = &emc2103_temp4_group;
- if (data->temp_count >= 3)
- sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
+ hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+ client->name, data,
+ data->groups);
+ if (IS_ERR(hwmon_dev))
+ return PTR_ERR(hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &emc2103_group);
+ dev_info(&client->dev, "%s: sensor '%s'\n",
+ dev_name(hwmon_dev), client->name);
return 0;
}
@@ -722,7 +681,6 @@ static struct i2c_driver emc2103_driver = {
.name = "emc2103",
},
.probe = emc2103_probe,
- .remove = emc2103_remove,
.id_table = emc2103_ids,
.detect = emc2103_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index f76a74cb6dc4..e87da902f3ae 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -56,7 +56,7 @@ enum subfeature { input, min, max };
*/
struct emc6w201_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -134,8 +134,8 @@ static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
static struct emc6w201_data *emc6w201_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc6w201_data *data = i2c_get_clientdata(client);
+ struct emc6w201_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr;
mutex_lock(&data->update_lock);
@@ -203,8 +203,8 @@ static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc6w201_data *data = i2c_get_clientdata(client);
+ struct emc6w201_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int sf = to_sensor_dev_attr_2(devattr)->index;
int nr = to_sensor_dev_attr_2(devattr)->nr;
int err;
@@ -240,8 +240,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc6w201_data *data = i2c_get_clientdata(client);
+ struct emc6w201_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int sf = to_sensor_dev_attr_2(devattr)->index;
int nr = to_sensor_dev_attr_2(devattr)->nr;
int err;
@@ -283,8 +283,8 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct emc6w201_data *data = i2c_get_clientdata(client);
+ struct emc6w201_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int sf = to_sensor_dev_attr_2(devattr)->index;
int nr = to_sensor_dev_attr_2(devattr)->nr;
int err;
@@ -388,7 +388,7 @@ static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input);
static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
4, min);
-static struct attribute *emc6w201_attributes[] = {
+static struct attribute *emc6w201_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -440,9 +440,7 @@ static struct attribute *emc6w201_attributes[] = {
NULL
};
-static const struct attribute_group emc6w201_group = {
- .attrs = emc6w201_attributes,
-};
+ATTRIBUTE_GROUPS(emc6w201);
/*
* Driver interface
@@ -488,44 +486,21 @@ static int emc6w201_detect(struct i2c_client *client,
static int emc6w201_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct emc6w201_data *data;
- int err;
+ struct device *hwmon_dev;
- data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct emc6w201_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
- /* Create sysfs attribute */
- err = sysfs_create_group(&client->dev.kobj, &emc6w201_group);
- if (err)
- return err;
-
- /* Expose as a hwmon device */
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
- exit_remove:
- sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
- return err;
-}
-
-static int emc6w201_remove(struct i2c_client *client)
-{
- struct emc6w201_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ emc6w201_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id emc6w201_id[] = {
@@ -540,7 +515,6 @@ static struct i2c_driver emc6w201_driver = {
.name = "emc6w201",
},
.probe = emc6w201_probe,
- .remove = emc6w201_remove,
.id_table = emc6w201_id,
.detect = emc6w201_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index 6040121a405a..4a7cbfad1d74 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -31,9 +31,6 @@ MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
MODULE_LICENSE("GPL");
-/* Family 16h Northbridge's function 4 PCI ID */
-#define PCI_DEVICE_ID_AMD_16H_NB_F4 0x1534
-
/* D18F3 */
#define REG_NORTHBRIDGE_CAP 0xe8
@@ -45,7 +42,7 @@ MODULE_LICENSE("GPL");
#define REG_TDP_LIMIT3 0xe8
struct fam15h_power_data {
- struct device *hwmon_dev;
+ struct pci_dev *pdev;
unsigned int tdp_to_watts;
unsigned int base_tdp;
unsigned int processor_pwr_watts;
@@ -57,8 +54,8 @@ static ssize_t show_power(struct device *dev,
u32 val, tdp_limit, running_avg_range;
s32 running_avg_capture;
u64 curr_pwr_watts;
- struct pci_dev *f4 = to_pci_dev(dev);
struct fam15h_power_data *data = dev_get_drvdata(dev);
+ struct pci_dev *f4 = data->pdev;
pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
REG_TDP_RUNNING_AVERAGE, &val);
@@ -96,23 +93,13 @@ static ssize_t show_power_crit(struct device *dev,
}
static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL);
-static ssize_t show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "fam15h_power\n");
-}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
static struct attribute *fam15h_power_attrs[] = {
&dev_attr_power1_input.attr,
&dev_attr_power1_crit.attr,
- &dev_attr_name.attr,
NULL
};
-static const struct attribute_group fam15h_power_attr_group = {
- .attrs = fam15h_power_attrs,
-};
+ATTRIBUTE_GROUPS(fam15h_power);
static bool fam15h_power_is_internal_node0(struct pci_dev *f4)
{
@@ -202,7 +189,7 @@ static int fam15h_power_probe(struct pci_dev *pdev,
{
struct fam15h_power_data *data;
struct device *dev = &pdev->dev;
- int err;
+ struct device *hwmon_dev;
/*
* though we ignore every other northbridge, we still have to
@@ -219,34 +206,12 @@ static int fam15h_power_probe(struct pci_dev *pdev,
return -ENOMEM;
fam15h_power_init_data(pdev, data);
+ data->pdev = pdev;
- dev_set_drvdata(dev, data);
- err = sysfs_create_group(&dev->kobj, &fam15h_power_attr_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_group;
- }
-
- return 0;
-
-exit_remove_group:
- sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
- return err;
-}
-
-static void fam15h_power_remove(struct pci_dev *pdev)
-{
- struct device *dev;
- struct fam15h_power_data *data;
-
- dev = &pdev->dev;
- data = dev_get_drvdata(dev);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, "fam15h_power",
+ data,
+ fam15h_power_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct pci_device_id fam15h_power_id_table[] = {
@@ -260,7 +225,6 @@ static struct pci_driver fam15h_power_driver = {
.name = "fam15h_power",
.id_table = fam15h_power_id_table,
.probe = fam15h_power_probe,
- .remove = fam15h_power_remove,
.resume = fam15h_power_resume,
};
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index ea6480b80e7f..ec6a77da411a 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -24,12 +24,6 @@
#include <linux/mutex.h>
#include <linux/sysfs.h>
-static const struct i2c_device_id g760a_id[] = {
- { "g760a", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, g760a_id);
-
enum g760a_regs {
G760A_REG_SET_CNT = 0x00,
G760A_REG_ACT_CNT = 0x01,
@@ -44,7 +38,6 @@ enum g760a_regs {
struct g760a_data {
struct i2c_client *client;
- struct device *hwmon_dev;
struct mutex update_lock;
/* board specific parameters */
@@ -74,20 +67,6 @@ static inline unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
}
-/* new-style driver model */
-static int g760a_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int g760a_remove(struct i2c_client *client);
-
-static struct i2c_driver g760a_driver = {
- .driver = {
- .name = "g760a",
- },
- .probe = g760a_probe,
- .remove = g760a_remove,
- .id_table = g760a_id,
-};
-
/* read/write wrappers */
static int g760a_read_value(struct i2c_client *client, enum g760a_regs reg)
{
@@ -106,8 +85,8 @@ static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
static struct g760a_data *g760a_update_client(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct g760a_data *data = i2c_get_clientdata(client);
+ struct g760a_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
@@ -163,8 +142,8 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g760a_data *data = g760a_update_client(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
if (kstrtoul(buf, 10, &val))
@@ -182,16 +161,14 @@ static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
-static struct attribute *g760a_attributes[] = {
+static struct attribute *g760a_attrs[] = {
&dev_attr_pwm1.attr,
&dev_attr_fan1_input.attr,
&dev_attr_fan1_alarm.attr,
NULL
};
-static const struct attribute_group g760a_group = {
- .attrs = g760a_attributes,
-};
+ATTRIBUTE_GROUPS(g760a);
/*
* new-style driver model code
@@ -200,20 +177,17 @@ static const struct attribute_group g760a_group = {
static int g760a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct g760a_data *data;
- int err;
+ struct device *hwmon_dev;
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA))
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- data = devm_kzalloc(&client->dev, sizeof(struct g760a_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct g760a_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
-
data->client = client;
mutex_init(&data->update_lock);
@@ -221,31 +195,25 @@ static int g760a_probe(struct i2c_client *client,
data->fan_div = G760A_DEFAULT_FAN_DIV;
data->clk = G760A_DEFAULT_CLK;
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &g760a_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto error_hwmon_device_register;
- }
-
- return 0;
-
-error_hwmon_device_register:
- sysfs_remove_group(&client->dev.kobj, &g760a_group);
- return err;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ g760a_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static int g760a_remove(struct i2c_client *client)
-{
- struct g760a_data *data = i2c_get_clientdata(client);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &g760a_group);
- return 0;
-}
+static const struct i2c_device_id g760a_id[] = {
+ { "g760a", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, g760a_id);
+
+static struct i2c_driver g760a_driver = {
+ .driver = {
+ .name = "g760a",
+ },
+ .probe = g760a_probe,
+ .id_table = g760a_id,
+};
module_i2c_driver(g760a_driver);
diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c
index 98a8618d8fbf..6aac695b1688 100644
--- a/drivers/hwmon/g762.c
+++ b/drivers/hwmon/g762.c
@@ -128,8 +128,8 @@ enum g762_regs {
G762_REG_FAN_CMD2_GEAR_MODE_1)) >> 2))
struct g762_data {
- struct i2c_client *client;
struct device *hwmon_dev;
+ struct i2c_client *client;
struct clk *clk;
/* update mutex */
@@ -206,8 +206,8 @@ static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p,
/* helper to grab and cache data, at most one time per second */
static struct g762_data *g762_update_client(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct g762_data *data = i2c_get_clientdata(client);
+ struct g762_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ret = 0;
mutex_lock(&data->update_lock);
@@ -266,8 +266,7 @@ static struct g762_data *g762_update_client(struct device *dev)
*/
static int do_set_clk_freq(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct g762_data *data = i2c_get_clientdata(client);
+ struct g762_data *data = dev_get_drvdata(dev);
if (val > 0xffffff)
return -EINVAL;
@@ -282,7 +281,6 @@ static int do_set_clk_freq(struct device *dev, unsigned long val)
/* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */
static int do_set_pwm_mode(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -301,7 +299,7 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
data->valid = false;
out:
@@ -313,7 +311,6 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val)
/* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
static int do_set_fan_div(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -342,7 +339,7 @@ static int do_set_fan_div(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
data->valid = false;
out:
@@ -354,7 +351,6 @@ static int do_set_fan_div(struct device *dev, unsigned long val)
/* Set fan gear mode. Accepts either 0, 1 or 2. */
static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -379,7 +375,7 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2,
data->fan_cmd2);
data->valid = false;
out:
@@ -391,7 +387,6 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
/* Set number of fan pulses per revolution. Accepts either 2 or 4. */
static int do_set_fan_pulses(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -410,7 +405,7 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
data->valid = false;
out:
@@ -422,7 +417,6 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val)
/* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
static int do_set_pwm_enable(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -444,15 +438,15 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val)
* value of 254 if it is 255 when switching to open-loop.
*/
if (data->set_cnt == 0xff)
- i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
- 254);
+ i2c_smbus_write_byte_data(data->client,
+ G762_REG_SET_CNT, 254);
break;
default:
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
data->valid = false;
out:
@@ -464,7 +458,6 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val)
/* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */
static int do_set_pwm_polarity(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -483,7 +476,7 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
data->valid = false;
out:
@@ -498,8 +491,8 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val)
*/
static int do_set_pwm(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct g762_data *data = i2c_get_clientdata(client);
+ struct g762_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int ret;
if (val > 255)
@@ -519,7 +512,6 @@ static int do_set_pwm(struct device *dev, unsigned long val)
*/
static int do_set_fan_target(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -531,7 +523,7 @@ static int do_set_fan_target(struct device *dev, unsigned long val)
G762_PULSE_FROM_REG(data->fan_cmd1),
G762_CLKDIV_FROM_REG(data->fan_cmd1),
G762_GEARMULT_FROM_REG(data->fan_cmd2));
- ret = i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT,
data->set_cnt);
data->valid = false;
mutex_unlock(&data->update_lock);
@@ -542,7 +534,6 @@ static int do_set_fan_target(struct device *dev, unsigned long val)
/* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
static int do_set_fan_startv(struct device *dev, unsigned long val)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
int ret;
@@ -571,7 +562,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val)
ret = -EINVAL;
goto out;
}
- ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+ ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2,
data->fan_cmd2);
data->valid = false;
out:
@@ -658,15 +649,12 @@ static int g762_of_prop_import_one(struct i2c_client *client,
int (*psetter)(struct device *dev,
unsigned long val))
{
- const __be32 *prop;
- int len, ret;
+ int ret;
u32 pval;
- prop = of_get_property(client->dev.of_node, pname, &len);
- if (!prop || len != sizeof(u32))
+ if (of_property_read_u32(client->dev.of_node, pname, &pval))
return 0;
- pval = be32_to_cpu(prop[0]);
dev_dbg(&client->dev, "found %s (%d)\n", pname, pval);
ret = (*psetter)(&client->dev, pval);
if (ret)
@@ -1026,7 +1014,7 @@ static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO,
get_fan_pulses, set_fan_pulses);
/* Driver data */
-static struct attribute *g762_attributes[] = {
+static struct attribute *g762_attrs[] = {
&dev_attr_fan1_input.attr,
&dev_attr_fan1_alarm.attr,
&dev_attr_fan1_fault.attr,
@@ -1039,9 +1027,7 @@ static struct attribute *g762_attributes[] = {
NULL
};
-static const struct attribute_group g762_group = {
- .attrs = g762_attributes,
-};
+ATTRIBUTE_GROUPS(g762);
/*
* Enable both fan failure detection and fan out of control protection. The
@@ -1050,7 +1036,6 @@ static const struct attribute_group g762_group = {
*/
static inline int g762_fan_init(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
struct g762_data *data = g762_update_client(dev);
if (IS_ERR(data))
@@ -1060,12 +1045,13 @@ static inline int g762_fan_init(struct device *dev)
data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
data->valid = false;
- return i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+ return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
data->fan_cmd1);
}
static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct g762_data *data;
int ret;
@@ -1073,7 +1059,7 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- data = devm_kzalloc(&client->dev, sizeof(struct g762_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct g762_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -1082,7 +1068,7 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
mutex_init(&data->update_lock);
/* Enable fan failure detection and fan out of control protection */
- ret = g762_fan_init(&client->dev);
+ ret = g762_fan_init(dev);
if (ret)
return ret;
@@ -1098,22 +1084,17 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (ret)
goto clock_dis;
- /* Register sysfs hooks */
- ret = sysfs_create_group(&client->dev.kobj, &g762_group);
- if (ret)
- goto clock_dis;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
+ data->hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+ client->name,
+ data,
+ g762_groups);
if (IS_ERR(data->hwmon_dev)) {
ret = PTR_ERR(data->hwmon_dev);
- goto sysfs_rem;
+ goto clock_dis;
}
return 0;
- sysfs_rem:
- sysfs_remove_group(&client->dev.kobj, &g762_group);
-
clock_dis:
g762_of_clock_disable(client);
@@ -1125,7 +1106,6 @@ static int g762_remove(struct i2c_client *client)
struct g762_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &g762_group);
g762_of_clock_disable(client);
return 0;
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 1e9830513045..0212c8317bca 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -114,7 +114,8 @@ static inline u8 FAN_TO_REG(long rpm, int div)
/* Each client has this additional data */
struct gl518_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
enum chips type;
struct mutex update_lock;
@@ -137,33 +138,98 @@ struct gl518_data {
u8 beep_enable; /* Boolean */
};
-static int gl518_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info);
-static void gl518_init_client(struct i2c_client *client);
-static int gl518_remove(struct i2c_client *client);
-static int gl518_read_value(struct i2c_client *client, u8 reg);
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl518_data *gl518_update_device(struct device *dev);
+/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL518 uses a high-byte first convention, which is exactly opposite to
+ * the SMBus standard.
+ */
+static int gl518_read_value(struct i2c_client *client, u8 reg)
+{
+ if ((reg >= 0x07) && (reg <= 0x0c))
+ return i2c_smbus_read_word_swapped(client, reg);
+ else
+ return i2c_smbus_read_byte_data(client, reg);
+}
-static const struct i2c_device_id gl518_id[] = {
- { "gl518sm", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, gl518_id);
+static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+ if ((reg >= 0x07) && (reg <= 0x0c))
+ return i2c_smbus_write_word_swapped(client, reg, value);
+ else
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
-/* This is the driver that will be inserted */
-static struct i2c_driver gl518_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "gl518sm",
- },
- .probe = gl518_probe,
- .remove = gl518_remove,
- .id_table = gl518_id,
- .detect = gl518_detect,
- .address_list = normal_i2c,
-};
+static struct gl518_data *gl518_update_device(struct device *dev)
+{
+ struct gl518_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int val;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ dev_dbg(&client->dev, "Starting gl518 update\n");
+
+ data->alarms = gl518_read_value(client, GL518_REG_INT);
+ data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
+
+ val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
+ data->voltage_min[0] = val & 0xff;
+ data->voltage_max[0] = (val >> 8) & 0xff;
+ val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
+ data->voltage_min[1] = val & 0xff;
+ data->voltage_max[1] = (val >> 8) & 0xff;
+ val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
+ data->voltage_min[2] = val & 0xff;
+ data->voltage_max[2] = (val >> 8) & 0xff;
+ val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
+ data->voltage_min[3] = val & 0xff;
+ data->voltage_max[3] = (val >> 8) & 0xff;
+
+ val = gl518_read_value(client, GL518_REG_FAN_COUNT);
+ data->fan_in[0] = (val >> 8) & 0xff;
+ data->fan_in[1] = val & 0xff;
+
+ val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+ data->fan_min[0] = (val >> 8) & 0xff;
+ data->fan_min[1] = val & 0xff;
+
+ data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
+ data->temp_max =
+ gl518_read_value(client, GL518_REG_TEMP_MAX);
+ data->temp_hyst =
+ gl518_read_value(client, GL518_REG_TEMP_HYST);
+
+ val = gl518_read_value(client, GL518_REG_MISC);
+ data->fan_div[0] = (val >> 6) & 0x03;
+ data->fan_div[1] = (val >> 4) & 0x03;
+ data->fan_auto1 = (val >> 3) & 0x01;
+
+ data->alarms &= data->alarm_mask;
+
+ val = gl518_read_value(client, GL518_REG_CONF);
+ data->beep_enable = (val >> 2) & 1;
+
+ if (data->type != gl518sm_r00) {
+ data->voltage_in[0] =
+ gl518_read_value(client, GL518_REG_VDD);
+ data->voltage_in[1] =
+ gl518_read_value(client, GL518_REG_VIN1);
+ data->voltage_in[2] =
+ gl518_read_value(client, GL518_REG_VIN2);
+ }
+ data->voltage_in[3] =
+ gl518_read_value(client, GL518_REG_VIN3);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
/*
* Sysfs stuff
@@ -228,8 +294,8 @@ static ssize_t set_##suffix(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct gl518_data *data = i2c_get_clientdata(client); \
+ struct gl518_data *data = dev_get_drvdata(dev); \
+ struct i2c_client *client = data->client; \
long val; \
int err = kstrtol(buf, 10, &val); \
if (err) \
@@ -247,8 +313,8 @@ static ssize_t set_##suffix(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct gl518_data *data = i2c_get_clientdata(client); \
+ struct gl518_data *data = dev_get_drvdata(dev); \
+ struct i2c_client *client = data->client; \
int regvalue; \
unsigned long val; \
int err = kstrtoul(buf, 10, &val); \
@@ -286,8 +352,8 @@ set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl518_data *data = i2c_get_clientdata(client);
+ struct gl518_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
int regvalue;
unsigned long val;
@@ -319,8 +385,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl518_data *data = i2c_get_clientdata(client);
+ struct gl518_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
int regvalue;
unsigned long val;
@@ -420,8 +486,8 @@ static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl518_data *data = i2c_get_clientdata(client);
+ struct gl518_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int bitnr = to_sensor_dev_attr(attr)->index;
unsigned long bit;
int err;
@@ -539,52 +605,6 @@ static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info)
return 0;
}
-static int gl518_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct gl518_data *data;
- int err, revision;
-
- data = devm_kzalloc(&client->dev, sizeof(struct gl518_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- revision = gl518_read_value(client, GL518_REG_REVISION);
- data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00;
- mutex_init(&data->update_lock);
-
- /* Initialize the GL518SM chip */
- data->alarm_mask = 0xff;
- gl518_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &gl518_group);
- if (err)
- return err;
- if (data->type == gl518sm_r80) {
- err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80);
- if (err)
- goto exit_remove_files;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
-
-exit_remove_files:
- sysfs_remove_group(&client->dev.kobj, &gl518_group);
- if (data->type == gl518sm_r80)
- sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
- return err;
-}
-
-
/*
* Called when we have found a new GL518SM.
* Note that we preserve D4:NoFan2 and D2:beep_enable.
@@ -605,110 +625,53 @@ static void gl518_init_client(struct i2c_client *client)
gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
}
-static int gl518_remove(struct i2c_client *client)
-{
- struct gl518_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &gl518_group);
- if (data->type == gl518sm_r80)
- sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
-
- return 0;
-}
-
-/*
- * Registers 0x07 to 0x0c are word-sized, others are byte-sized
- * GL518 uses a high-byte first convention, which is exactly opposite to
- * the SMBus standard.
- */
-static int gl518_read_value(struct i2c_client *client, u8 reg)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return i2c_smbus_read_word_swapped(client, reg);
- else
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return i2c_smbus_write_word_swapped(client, reg, value);
- else
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static struct gl518_data *gl518_update_device(struct device *dev)
+static int gl518_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl518_data *data = i2c_get_clientdata(client);
- int val;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- dev_dbg(&client->dev, "Starting gl518 update\n");
-
- data->alarms = gl518_read_value(client, GL518_REG_INT);
- data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
-
- val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
- data->voltage_min[0] = val & 0xff;
- data->voltage_max[0] = (val >> 8) & 0xff;
- val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
- data->voltage_min[1] = val & 0xff;
- data->voltage_max[1] = (val >> 8) & 0xff;
- val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
- data->voltage_min[2] = val & 0xff;
- data->voltage_max[2] = (val >> 8) & 0xff;
- val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
- data->voltage_min[3] = val & 0xff;
- data->voltage_max[3] = (val >> 8) & 0xff;
-
- val = gl518_read_value(client, GL518_REG_FAN_COUNT);
- data->fan_in[0] = (val >> 8) & 0xff;
- data->fan_in[1] = val & 0xff;
-
- val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
- data->fan_min[0] = (val >> 8) & 0xff;
- data->fan_min[1] = val & 0xff;
-
- data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
- data->temp_max =
- gl518_read_value(client, GL518_REG_TEMP_MAX);
- data->temp_hyst =
- gl518_read_value(client, GL518_REG_TEMP_HYST);
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct gl518_data *data;
+ int revision;
- val = gl518_read_value(client, GL518_REG_MISC);
- data->fan_div[0] = (val >> 6) & 0x03;
- data->fan_div[1] = (val >> 4) & 0x03;
- data->fan_auto1 = (val >> 3) & 0x01;
+ data = devm_kzalloc(dev, sizeof(struct gl518_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- data->alarms &= data->alarm_mask;
+ data->client = client;
+ revision = gl518_read_value(client, GL518_REG_REVISION);
+ data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00;
+ mutex_init(&data->update_lock);
- val = gl518_read_value(client, GL518_REG_CONF);
- data->beep_enable = (val >> 2) & 1;
+ /* Initialize the GL518SM chip */
+ data->alarm_mask = 0xff;
+ gl518_init_client(client);
- if (data->type != gl518sm_r00) {
- data->voltage_in[0] =
- gl518_read_value(client, GL518_REG_VDD);
- data->voltage_in[1] =
- gl518_read_value(client, GL518_REG_VIN1);
- data->voltage_in[2] =
- gl518_read_value(client, GL518_REG_VIN2);
- }
- data->voltage_in[3] =
- gl518_read_value(client, GL518_REG_VIN3);
+ /* sysfs hooks */
+ data->groups[0] = &gl518_group;
+ if (data->type == gl518sm_r80)
+ data->groups[1] = &gl518_group_r80;
- data->last_updated = jiffies;
- data->valid = 1;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id gl518_id[] = {
+ { "gl518sm", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, gl518_id);
- return data;
-}
+static struct i2c_driver gl518_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "gl518sm",
+ },
+ .probe = gl518_probe,
+ .id_table = gl518_id,
+ .detect = gl518_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(gl518_driver);
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index ed56e09c3dd7..dee93ec87d02 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -73,41 +73,10 @@ static const u8 GL520_REG_TEMP_MAX_HYST[] = { 0x06, 0x18 };
#define GL520_REG_BEEP_MASK 0x10
#define GL520_REG_BEEP_ENABLE GL520_REG_CONF
-/*
- * Function declarations
- */
-
-static int gl520_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info);
-static void gl520_init_client(struct i2c_client *client);
-static int gl520_remove(struct i2c_client *client);
-static int gl520_read_value(struct i2c_client *client, u8 reg);
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl520_data *gl520_update_device(struct device *dev);
-
-/* Driver data */
-static const struct i2c_device_id gl520_id[] = {
- { "gl520sm", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, gl520_id);
-
-static struct i2c_driver gl520_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "gl520sm",
- },
- .probe = gl520_probe,
- .remove = gl520_remove,
- .id_table = gl520_id,
- .detect = gl520_detect,
- .address_list = normal_i2c,
-};
-
/* Client data */
struct gl520_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
char valid; /* zero until the following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -132,6 +101,102 @@ struct gl520_data {
};
/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL520 uses a high-byte first convention
+ */
+static int gl520_read_value(struct i2c_client *client, u8 reg)
+{
+ if ((reg >= 0x07) && (reg <= 0x0c))
+ return i2c_smbus_read_word_swapped(client, reg);
+ else
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+ if ((reg >= 0x07) && (reg <= 0x0c))
+ return i2c_smbus_write_word_swapped(client, reg, value);
+ else
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static struct gl520_data *gl520_update_device(struct device *dev)
+{
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int val, i;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+
+ dev_dbg(&client->dev, "Starting gl520sm update\n");
+
+ data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
+ data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
+ data->vid = gl520_read_value(client,
+ GL520_REG_VID_INPUT) & 0x1f;
+
+ for (i = 0; i < 4; i++) {
+ data->in_input[i] = gl520_read_value(client,
+ GL520_REG_IN_INPUT[i]);
+ val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
+ data->in_min[i] = val & 0xff;
+ data->in_max[i] = (val >> 8) & 0xff;
+ }
+
+ val = gl520_read_value(client, GL520_REG_FAN_INPUT);
+ data->fan_input[0] = (val >> 8) & 0xff;
+ data->fan_input[1] = val & 0xff;
+
+ val = gl520_read_value(client, GL520_REG_FAN_MIN);
+ data->fan_min[0] = (val >> 8) & 0xff;
+ data->fan_min[1] = val & 0xff;
+
+ data->temp_input[0] = gl520_read_value(client,
+ GL520_REG_TEMP_INPUT[0]);
+ data->temp_max[0] = gl520_read_value(client,
+ GL520_REG_TEMP_MAX[0]);
+ data->temp_max_hyst[0] = gl520_read_value(client,
+ GL520_REG_TEMP_MAX_HYST[0]);
+
+ val = gl520_read_value(client, GL520_REG_FAN_DIV);
+ data->fan_div[0] = (val >> 6) & 0x03;
+ data->fan_div[1] = (val >> 4) & 0x03;
+ data->fan_off = (val >> 2) & 0x01;
+
+ data->alarms &= data->alarm_mask;
+
+ val = gl520_read_value(client, GL520_REG_CONF);
+ data->beep_enable = !((val >> 2) & 1);
+
+ /* Temp1 and Vin4 are the same input */
+ if (data->two_temps) {
+ data->temp_input[1] = gl520_read_value(client,
+ GL520_REG_TEMP_INPUT[1]);
+ data->temp_max[1] = gl520_read_value(client,
+ GL520_REG_TEMP_MAX[1]);
+ data->temp_max_hyst[1] = gl520_read_value(client,
+ GL520_REG_TEMP_MAX_HYST[1]);
+ } else {
+ data->in_input[4] = gl520_read_value(client,
+ GL520_REG_IN_INPUT[4]);
+ data->in_min[4] = gl520_read_value(client,
+ GL520_REG_IN_MIN[4]);
+ data->in_max[4] = gl520_read_value(client,
+ GL520_REG_IN_MAX[4]);
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+/*
* Sysfs stuff
*/
@@ -191,8 +256,8 @@ static ssize_t get_in_max(struct device *dev, struct device_attribute *attr,
static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
u8 r;
long v;
@@ -225,8 +290,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
u8 r;
long v;
@@ -326,8 +391,8 @@ static ssize_t get_fan_off(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
u8 r;
unsigned long v;
@@ -365,8 +430,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
u8 r;
unsigned long v;
@@ -414,8 +479,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 r;
unsigned long v;
int err;
@@ -482,8 +547,8 @@ static ssize_t get_temp_max_hyst(struct device *dev,
static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
long v;
int err;
@@ -502,8 +567,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
*attr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int n = to_sensor_dev_attr(attr)->index;
long v;
int err;
@@ -555,8 +620,8 @@ static ssize_t get_beep_mask(struct device *dev, struct device_attribute *attr,
static ssize_t set_beep_enable(struct device *dev, struct device_attribute
*attr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 r;
unsigned long v;
int err;
@@ -579,8 +644,8 @@ static ssize_t set_beep_enable(struct device *dev, struct device_attribute
static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long r;
int err;
@@ -633,8 +698,8 @@ static ssize_t get_beep(struct device *dev, struct device_attribute *attr,
static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct gl520_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int bitnr = to_sensor_dev_attr(attr)->index;
unsigned long bit;
@@ -772,52 +837,6 @@ static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info)
return 0;
}
-static int gl520_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct gl520_data *data;
- int err;
-
- data = devm_kzalloc(&client->dev, sizeof(struct gl520_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- /* Initialize the GL520SM chip */
- gl520_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &gl520_group);
- if (err)
- return err;
-
- if (data->two_temps)
- err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2);
- else
- err = sysfs_create_group(&client->dev.kobj, &gl520_group_in4);
-
- if (err)
- goto exit_remove_files;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
-
-exit_remove_files:
- sysfs_remove_group(&client->dev.kobj, &gl520_group);
- sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
- sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
- return err;
-}
-
-
/* Called when we have found a new GL520SM. */
static void gl520_init_client(struct i2c_client *client)
{
@@ -856,115 +875,53 @@ static void gl520_init_client(struct i2c_client *client)
gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
}
-static int gl520_remove(struct i2c_client *client)
+static int gl520_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct gl520_data *data = i2c_get_clientdata(client);
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct gl520_data *data;
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &gl520_group);
- sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
- sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
+ data = devm_kzalloc(dev, sizeof(struct gl520_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- return 0;
-}
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+ data->client = client;
+ /* Initialize the GL520SM chip */
+ gl520_init_client(client);
-/*
- * Registers 0x07 to 0x0c are word-sized, others are byte-sized
- * GL520 uses a high-byte first convention
- */
-static int gl520_read_value(struct i2c_client *client, u8 reg)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return i2c_smbus_read_word_swapped(client, reg);
- else
- return i2c_smbus_read_byte_data(client, reg);
-}
+ /* sysfs hooks */
+ data->groups[0] = &gl520_group;
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return i2c_smbus_write_word_swapped(client, reg, value);
+ if (data->two_temps)
+ data->groups[1] = &gl520_group_temp2;
else
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-
-static struct gl520_data *gl520_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct gl520_data *data = i2c_get_clientdata(client);
- int val, i;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
-
- dev_dbg(&client->dev, "Starting gl520sm update\n");
-
- data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
- data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
- data->vid = gl520_read_value(client,
- GL520_REG_VID_INPUT) & 0x1f;
-
- for (i = 0; i < 4; i++) {
- data->in_input[i] = gl520_read_value(client,
- GL520_REG_IN_INPUT[i]);
- val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
- data->in_min[i] = val & 0xff;
- data->in_max[i] = (val >> 8) & 0xff;
- }
-
- val = gl520_read_value(client, GL520_REG_FAN_INPUT);
- data->fan_input[0] = (val >> 8) & 0xff;
- data->fan_input[1] = val & 0xff;
+ data->groups[1] = &gl520_group_in4;
- val = gl520_read_value(client, GL520_REG_FAN_MIN);
- data->fan_min[0] = (val >> 8) & 0xff;
- data->fan_min[1] = val & 0xff;
-
- data->temp_input[0] = gl520_read_value(client,
- GL520_REG_TEMP_INPUT[0]);
- data->temp_max[0] = gl520_read_value(client,
- GL520_REG_TEMP_MAX[0]);
- data->temp_max_hyst[0] = gl520_read_value(client,
- GL520_REG_TEMP_MAX_HYST[0]);
-
- val = gl520_read_value(client, GL520_REG_FAN_DIV);
- data->fan_div[0] = (val >> 6) & 0x03;
- data->fan_div[1] = (val >> 4) & 0x03;
- data->fan_off = (val >> 2) & 0x01;
-
- data->alarms &= data->alarm_mask;
-
- val = gl520_read_value(client, GL520_REG_CONF);
- data->beep_enable = !((val >> 2) & 1);
-
- /* Temp1 and Vin4 are the same input */
- if (data->two_temps) {
- data->temp_input[1] = gl520_read_value(client,
- GL520_REG_TEMP_INPUT[1]);
- data->temp_max[1] = gl520_read_value(client,
- GL520_REG_TEMP_MAX[1]);
- data->temp_max_hyst[1] = gl520_read_value(client,
- GL520_REG_TEMP_MAX_HYST[1]);
- } else {
- data->in_input[4] = gl520_read_value(client,
- GL520_REG_IN_INPUT[4]);
- data->in_min[4] = gl520_read_value(client,
- GL520_REG_IN_MIN[4]);
- data->in_max[4] = gl520_read_value(client,
- GL520_REG_IN_MAX[4]);
- }
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id gl520_id[] = {
+ { "gl520sm", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, gl520_id);
- return data;
-}
+static struct i2c_driver gl520_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "gl520sm",
+ },
+ .probe = gl520_probe,
+ .id_table = gl520_id,
+ .detect = gl520_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(gl520_driver);
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 2566c43dd1e9..4efa1734bdad 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -173,7 +173,7 @@ static int get_fan_speed_index(struct gpio_fan_data *fan_data)
return -ENODEV;
}
-static int rpm_to_speed_index(struct gpio_fan_data *fan_data, int rpm)
+static int rpm_to_speed_index(struct gpio_fan_data *fan_data, unsigned long rpm)
{
struct gpio_fan_speed *speed = fan_data->speed;
int i;
@@ -537,9 +537,10 @@ static int gpio_fan_probe(struct platform_device *pdev)
}
/* Make this driver part of hwmon class. */
- fan_data->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev,
- "gpio_fan", fan_data,
- gpio_fan_groups);
+ fan_data->hwmon_dev =
+ devm_hwmon_device_register_with_groups(&pdev->dev,
+ "gpio_fan", fan_data,
+ gpio_fan_groups);
if (IS_ERR(fan_data->hwmon_dev))
return PTR_ERR(fan_data->hwmon_dev);
@@ -548,15 +549,6 @@ static int gpio_fan_probe(struct platform_device *pdev)
return 0;
}
-static int gpio_fan_remove(struct platform_device *pdev)
-{
- struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
-
- hwmon_device_unregister(fan_data->hwmon_dev);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int gpio_fan_suspend(struct device *dev)
{
@@ -588,7 +580,6 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
static struct platform_driver gpio_fan_driver = {
.probe = gpio_fan_probe,
- .remove = gpio_fan_remove,
.driver = {
.name = "gpio-fan",
.pm = GPIO_FAN_PM,
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c
index 7d68a08baaa8..0e01c4e13e33 100644
--- a/drivers/hwmon/hih6130.c
+++ b/drivers/hwmon/hih6130.c
@@ -46,7 +46,7 @@
* @write_length: length for I2C measurement request
*/
struct hih6130 {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex lock;
bool valid;
unsigned long last_update;
@@ -62,7 +62,6 @@ struct hih6130 {
*/
static inline int hih6130_temp_ticks_to_millicelsius(int ticks)
{
-
ticks = ticks >> 2;
/*
* from data sheet section 5.0
@@ -78,7 +77,6 @@ static inline int hih6130_temp_ticks_to_millicelsius(int ticks)
*/
static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks)
{
-
ticks &= ~0xC000; /* clear status bits */
/*
* from data sheet section 4.0
@@ -89,15 +87,16 @@ static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks)
/**
* hih6130_update_measurements() - get updated measurements from device
- * @client: I2C client device
+ * @dev: device
*
* Returns 0 on success, else negative errno.
*/
-static int hih6130_update_measurements(struct i2c_client *client)
+static int hih6130_update_measurements(struct device *dev)
{
+ struct hih6130 *hih6130 = dev_get_drvdata(dev);
+ struct i2c_client *client = hih6130->client;
int ret = 0;
int t;
- struct hih6130 *hih6130 = i2c_get_clientdata(client);
unsigned char tmp[4];
struct i2c_msg msgs[1] = {
{
@@ -176,9 +175,10 @@ static ssize_t hih6130_show_temperature(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct hih6130 *hih6130 = i2c_get_clientdata(client);
- int ret = hih6130_update_measurements(client);
+ struct hih6130 *hih6130 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = hih6130_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", hih6130->temperature);
@@ -196,9 +196,10 @@ static ssize_t hih6130_show_temperature(struct device *dev,
static ssize_t hih6130_show_humidity(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct hih6130 *hih6130 = i2c_get_clientdata(client);
- int ret = hih6130_update_measurements(client);
+ struct hih6130 *hih6130 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = hih6130_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", hih6130->humidity);
@@ -210,79 +211,37 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, hih6130_show_temperature,
static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, hih6130_show_humidity,
NULL, 0);
-static struct attribute *hih6130_attributes[] = {
+static struct attribute *hih6130_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_humidity1_input.dev_attr.attr,
NULL
};
-static const struct attribute_group hih6130_attr_group = {
- .attrs = hih6130_attributes,
-};
+ATTRIBUTE_GROUPS(hih6130);
-/**
- * hih6130_probe() - probe device
- * @client: I2C client device
- * @id: device ID
- *
- * Called by the I2C core when an entry in the ID table matches a
- * device's name.
- * Returns 0 on success.
- */
static int hih6130_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct hih6130 *hih6130;
- int err;
+ struct device *hwmon_dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->dev, "adapter does not support true I2C\n");
return -ENODEV;
}
- hih6130 = devm_kzalloc(&client->dev, sizeof(*hih6130), GFP_KERNEL);
+ hih6130 = devm_kzalloc(dev, sizeof(*hih6130), GFP_KERNEL);
if (!hih6130)
return -ENOMEM;
- i2c_set_clientdata(client, hih6130);
-
+ hih6130->client = client;
mutex_init(&hih6130->lock);
- err = sysfs_create_group(&client->dev.kobj, &hih6130_attr_group);
- if (err) {
- dev_dbg(&client->dev, "could not create sysfs files\n");
- return err;
- }
-
- hih6130->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(hih6130->hwmon_dev)) {
- dev_dbg(&client->dev, "unable to register hwmon device\n");
- err = PTR_ERR(hih6130->hwmon_dev);
- goto fail_remove_sysfs;
- }
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_QUICK))
- hih6130->write_length = 1;
-
- return 0;
-
-fail_remove_sysfs:
- sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group);
- return err;
-}
-
-/**
- * hih6130_remove() - remove device
- * @client: I2C client device
- */
-static int hih6130_remove(struct i2c_client *client)
-{
- struct hih6130 *hih6130 = i2c_get_clientdata(client);
-
- hwmon_device_unregister(hih6130->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ hih6130,
+ hih6130_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
/* Device ID table */
@@ -295,7 +254,6 @@ MODULE_DEVICE_TABLE(i2c, hih6130_id);
static struct i2c_driver hih6130_driver = {
.driver.name = "hih6130",
.probe = hih6130_probe,
- .remove = hih6130_remove,
.id_table = hih6130_id,
};
diff --git a/drivers/hwmon/htu21.c b/drivers/hwmon/htu21.c
index 839086e0e951..4c3bbb72f82a 100644
--- a/drivers/hwmon/htu21.c
+++ b/drivers/hwmon/htu21.c
@@ -31,7 +31,7 @@
#define HTU21_RH_MEASUREMENT_HM 0xE5
struct htu21 {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex lock;
bool valid;
unsigned long last_update;
@@ -59,10 +59,11 @@ static inline int htu21_rh_ticks_to_per_cent_mille(int ticks)
return ((15625 * ticks) >> 13) - 6000;
}
-static int htu21_update_measurements(struct i2c_client *client)
+static int htu21_update_measurements(struct device *dev)
{
+ struct htu21 *htu21 = dev_get_drvdata(dev);
+ struct i2c_client *client = htu21->client;
int ret = 0;
- struct htu21 *htu21 = i2c_get_clientdata(client);
mutex_lock(&htu21->lock);
@@ -90,9 +91,10 @@ out:
static ssize_t htu21_show_temperature(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct htu21 *htu21 = i2c_get_clientdata(client);
- int ret = htu21_update_measurements(client);
+ struct htu21 *htu21 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = htu21_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", htu21->temperature);
@@ -101,9 +103,10 @@ static ssize_t htu21_show_temperature(struct device *dev,
static ssize_t htu21_show_humidity(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct htu21 *htu21 = i2c_get_clientdata(client);
- int ret = htu21_update_measurements(client);
+ struct htu21 *htu21 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = htu21_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", htu21->humidity);
@@ -114,21 +117,20 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO,
htu21_show_humidity, NULL, 0);
-static struct attribute *htu21_attributes[] = {
+static struct attribute *htu21_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_humidity1_input.dev_attr.attr,
NULL
};
-static const struct attribute_group htu21_group = {
- .attrs = htu21_attributes,
-};
+ATTRIBUTE_GROUPS(htu21);
static int htu21_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct htu21 *htu21;
- int err;
+ struct device *hwmon_dev;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_WORD_DATA)) {
@@ -137,43 +139,17 @@ static int htu21_probe(struct i2c_client *client,
return -ENODEV;
}
- htu21 = devm_kzalloc(&client->dev, sizeof(*htu21), GFP_KERNEL);
+ htu21 = devm_kzalloc(dev, sizeof(*htu21), GFP_KERNEL);
if (!htu21)
return -ENOMEM;
- i2c_set_clientdata(client, htu21);
-
+ htu21->client = client;
mutex_init(&htu21->lock);
- err = sysfs_create_group(&client->dev.kobj, &htu21_group);
- if (err) {
- dev_dbg(&client->dev, "could not create sysfs files\n");
- return err;
- }
- htu21->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(htu21->hwmon_dev)) {
- dev_dbg(&client->dev, "unable to register hwmon device\n");
- err = PTR_ERR(htu21->hwmon_dev);
- goto error;
- }
-
- dev_info(&client->dev, "initialized\n");
-
- return 0;
-
-error:
- sysfs_remove_group(&client->dev.kobj, &htu21_group);
- return err;
-}
-
-static int htu21_remove(struct i2c_client *client)
-{
- struct htu21 *htu21 = i2c_get_clientdata(client);
-
- hwmon_device_unregister(htu21->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &htu21_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ htu21,
+ htu21_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id htu21_id[] = {
@@ -188,7 +164,6 @@ static struct i2c_driver htu21_driver = {
.name = "htu21",
},
.probe = htu21_probe,
- .remove = htu21_remove,
.id_table = htu21_id,
};
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 632f1dc0fe1f..7a8a6fbf11ff 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -842,11 +842,10 @@ static ssize_t aem_show_power(struct device *dev,
struct aem_data *data = dev_get_drvdata(dev);
u64 before, after, delta, time;
signed long leftover;
- struct timespec b, a;
mutex_lock(&data->lock);
update_aem_energy_one(data, attr->index);
- getnstimeofday(&b);
+ time = ktime_get_ns();
before = data->energy[attr->index];
leftover = schedule_timeout_interruptible(
@@ -858,11 +857,10 @@ static ssize_t aem_show_power(struct device *dev,
}
update_aem_energy_one(data, attr->index);
- getnstimeofday(&a);
+ time = ktime_get_ns() - time;
after = data->energy[attr->index];
mutex_unlock(&data->lock);
- time = timespec_to_ns(&a) - timespec_to_ns(&b);
delta = (after - before) * UJ_PER_MJ;
return sprintf(buf, "%llu\n",
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
new file mode 100644
index 000000000000..d2bf2c97ae70
--- /dev/null
+++ b/drivers/hwmon/ibmpowernv.c
@@ -0,0 +1,363 @@
+/*
+ * IBM PowerNV platform sensors for temperature/fan/voltage/power
+ * Copyright (C) 2014 IBM
+ *
+ * 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.
+ */
+
+#define DRVNAME "ibmpowernv"
+#define pr_fmt(fmt) DRVNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <asm/opal.h>
+#include <linux/err.h>
+
+#define MAX_ATTR_LEN 32
+
+/* Sensor suffix name from DT */
+#define DT_FAULT_ATTR_SUFFIX "faulted"
+#define DT_DATA_ATTR_SUFFIX "data"
+#define DT_THRESHOLD_ATTR_SUFFIX "thrs"
+
+/*
+ * Enumerates all the types of sensors in the POWERNV platform and does index
+ * into 'struct sensor_group'
+ */
+enum sensors {
+ FAN,
+ AMBIENT_TEMP,
+ POWER_SUPPLY,
+ POWER_INPUT,
+ MAX_SENSOR_TYPE,
+};
+
+static struct sensor_group {
+ const char *name;
+ const char *compatible;
+ struct attribute_group group;
+ u32 attr_count;
+} sensor_groups[] = {
+ {"fan", "ibm,opal-sensor-cooling-fan"},
+ {"temp", "ibm,opal-sensor-amb-temp"},
+ {"in", "ibm,opal-sensor-power-supply"},
+ {"power", "ibm,opal-sensor-power"}
+};
+
+struct sensor_data {
+ u32 id; /* An opaque id of the firmware for each sensor */
+ enum sensors type;
+ char name[MAX_ATTR_LEN];
+ struct device_attribute dev_attr;
+};
+
+struct platform_data {
+ const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
+ u32 sensors_count; /* Total count of sensors from each group */
+};
+
+/* Platform device representing all the ibmpowernv sensors */
+static struct platform_device *pdevice;
+
+static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_data *sdata = container_of(devattr, struct sensor_data,
+ dev_attr);
+ ssize_t ret;
+ u32 x;
+
+ ret = opal_get_sensor_data(sdata->id, &x);
+ if (ret)
+ return ret;
+
+ /* Convert temperature to milli-degrees */
+ if (sdata->type == AMBIENT_TEMP)
+ x *= 1000;
+ /* Convert power to micro-watts */
+ else if (sdata->type == POWER_INPUT)
+ x *= 1000000;
+
+ return sprintf(buf, "%u\n", x);
+}
+
+static int __init get_sensor_index_attr(const char *name, u32 *index,
+ char *attr)
+{
+ char *hash_pos = strchr(name, '#');
+ char buf[8] = { 0 };
+ char *dash_pos;
+ u32 copy_len;
+ int err;
+
+ if (!hash_pos)
+ return -EINVAL;
+
+ dash_pos = strchr(hash_pos, '-');
+ if (!dash_pos)
+ return -EINVAL;
+
+ copy_len = dash_pos - hash_pos - 1;
+ if (copy_len >= sizeof(buf))
+ return -EINVAL;
+
+ strncpy(buf, hash_pos + 1, copy_len);
+
+ err = kstrtou32(buf, 10, index);
+ if (err)
+ return err;
+
+ strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
+
+ return 0;
+}
+
+/*
+ * This function translates the DT node name into the 'hwmon' attribute name.
+ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
+ * which need to be mapped as fan2_input, temp1_max respectively before
+ * populating them inside hwmon device class.
+ */
+static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,
+ const char *node_name,
+ char *hwmon_attr_name)
+{
+ char attr_suffix[MAX_ATTR_LEN];
+ char *attr_name;
+ u32 index;
+ int err;
+
+ err = get_sensor_index_attr(node_name, &index, attr_suffix);
+ if (err) {
+ dev_err(dev, "Sensor device node name '%s' is invalid\n",
+ node_name);
+ return err;
+ }
+
+ if (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {
+ attr_name = "fault";
+ } else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {
+ attr_name = "input";
+ } else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {
+ if (type == AMBIENT_TEMP)
+ attr_name = "max";
+ else if (type == FAN)
+ attr_name = "min";
+ else
+ return -ENOENT;
+ } else {
+ return -ENOENT;
+ }
+
+ snprintf(hwmon_attr_name, MAX_ATTR_LEN, "%s%d_%s",
+ sensor_groups[type].name, index, attr_name);
+ return 0;
+}
+
+static int __init populate_attr_groups(struct platform_device *pdev)
+{
+ struct platform_data *pdata = platform_get_drvdata(pdev);
+ const struct attribute_group **pgroups = pdata->attr_groups;
+ struct device_node *opal, *np;
+ enum sensors type;
+
+ opal = of_find_node_by_path("/ibm,opal/sensors");
+ if (!opal) {
+ dev_err(&pdev->dev, "Opal node 'sensors' not found\n");
+ return -ENODEV;
+ }
+
+ for_each_child_of_node(opal, np) {
+ if (np->name == NULL)
+ continue;
+
+ for (type = 0; type < MAX_SENSOR_TYPE; type++)
+ if (of_device_is_compatible(np,
+ sensor_groups[type].compatible)) {
+ sensor_groups[type].attr_count++;
+ break;
+ }
+ }
+
+ of_node_put(opal);
+
+ for (type = 0; type < MAX_SENSOR_TYPE; type++) {
+ sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,
+ sizeof(struct attribute *) *
+ (sensor_groups[type].attr_count + 1),
+ GFP_KERNEL);
+ if (!sensor_groups[type].group.attrs)
+ return -ENOMEM;
+
+ pgroups[type] = &sensor_groups[type].group;
+ pdata->sensors_count += sensor_groups[type].attr_count;
+ sensor_groups[type].attr_count = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Iterate through the device tree for each child of 'sensors' node, create
+ * a sysfs attribute file, the file is named by translating the DT node name
+ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
+ * etc..
+ */
+static int __init create_device_attrs(struct platform_device *pdev)
+{
+ struct platform_data *pdata = platform_get_drvdata(pdev);
+ const struct attribute_group **pgroups = pdata->attr_groups;
+ struct device_node *opal, *np;
+ struct sensor_data *sdata;
+ u32 sensor_id;
+ enum sensors type;
+ u32 count = 0;
+ int err = 0;
+
+ opal = of_find_node_by_path("/ibm,opal/sensors");
+ sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),
+ GFP_KERNEL);
+ if (!sdata) {
+ err = -ENOMEM;
+ goto exit_put_node;
+ }
+
+ for_each_child_of_node(opal, np) {
+ if (np->name == NULL)
+ continue;
+
+ for (type = 0; type < MAX_SENSOR_TYPE; type++)
+ if (of_device_is_compatible(np,
+ sensor_groups[type].compatible))
+ break;
+
+ if (type == MAX_SENSOR_TYPE)
+ continue;
+
+ if (of_property_read_u32(np, "sensor-id", &sensor_id)) {
+ dev_info(&pdev->dev,
+ "'sensor-id' missing in the node '%s'\n",
+ np->name);
+ continue;
+ }
+
+ sdata[count].id = sensor_id;
+ sdata[count].type = type;
+ err = create_hwmon_attr_name(&pdev->dev, type, np->name,
+ sdata[count].name);
+ if (err)
+ goto exit_put_node;
+
+ sysfs_attr_init(&sdata[count].dev_attr.attr);
+ sdata[count].dev_attr.attr.name = sdata[count].name;
+ sdata[count].dev_attr.attr.mode = S_IRUGO;
+ sdata[count].dev_attr.show = show_sensor;
+
+ pgroups[type]->attrs[sensor_groups[type].attr_count++] =
+ &sdata[count++].dev_attr.attr;
+ }
+
+exit_put_node:
+ of_node_put(opal);
+ return err;
+}
+
+static int __init ibmpowernv_probe(struct platform_device *pdev)
+{
+ struct platform_data *pdata;
+ struct device *hwmon_dev;
+ int err;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pdata);
+ pdata->sensors_count = 0;
+ err = populate_attr_groups(pdev);
+ if (err)
+ return err;
+
+ /* Create sysfs attribute data for each sensor found in the DT */
+ err = create_device_attrs(pdev);
+ if (err)
+ return err;
+
+ /* Finally, register with hwmon */
+ hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
+ pdata,
+ pdata->attr_groups);
+
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static struct platform_driver ibmpowernv_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRVNAME,
+ },
+};
+
+static int __init ibmpowernv_init(void)
+{
+ int err;
+
+ pdevice = platform_device_alloc(DRVNAME, 0);
+ if (!pdevice) {
+ pr_err("Device allocation failed\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ err = platform_device_add(pdevice);
+ if (err) {
+ pr_err("Device addition failed (%d)\n", err);
+ goto exit_device_put;
+ }
+
+ err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
+ if (err) {
+ pr_err("Platfrom driver probe failed\n");
+ goto exit_device_del;
+ }
+
+ return 0;
+
+exit_device_del:
+ platform_device_del(pdevice);
+exit_device_put:
+ platform_device_put(pdevice);
+exit:
+ return err;
+}
+
+static void __exit ibmpowernv_exit(void)
+{
+ platform_driver_unregister(&ibmpowernv_driver);
+ platform_device_unregister(pdevice);
+}
+
+MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("IBM POWERNV platform sensors");
+MODULE_LICENSE("GPL");
+
+module_init(ibmpowernv_init);
+module_exit(ibmpowernv_exit);
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index ebbb9f4f27a3..84d791bdb62d 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -125,7 +125,8 @@
#define FAN_SPEED_LEN 5
struct pem_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[4];
struct mutex update_lock;
bool valid;
@@ -160,8 +161,8 @@ abort:
static struct pem_data *pem_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct pem_data *data = i2c_get_clientdata(client);
+ struct pem_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
struct pem_data *ret = data;
mutex_lock(&data->update_lock);
@@ -444,18 +445,20 @@ static int pem_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct pem_data *data;
- int ret;
+ int ret, idx = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_DATA
| I2C_FUNC_SMBUS_WRITE_BYTE))
return -ENODEV;
- data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
/*
@@ -471,14 +474,12 @@ static int pem_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- dev_info(&client->dev, "Firmware revision %d.%d.%d\n",
+ dev_info(dev, "Firmware revision %d.%d.%d\n",
data->firmware_rev[0], data->firmware_rev[1],
data->firmware_rev[2]);
- /* Register sysfs hooks */
- ret = sysfs_create_group(&client->dev.kobj, &pem_group);
- if (ret)
- return ret;
+ /* sysfs hooks */
+ data->groups[idx++] = &pem_group;
/*
* Check if input readings are supported.
@@ -501,12 +502,9 @@ static int pem_probe(struct i2c_client *client,
data->input_string[2] || data->input_string[3]))
data->input_length = sizeof(data->input_string);
}
- ret = 0;
- if (data->input_length) {
- ret = sysfs_create_group(&client->dev.kobj, &pem_input_group);
- if (ret)
- goto out_remove_groups;
- }
+
+ if (data->input_length)
+ data->groups[idx++] = &pem_input_group;
/*
* Check if fan speed readings are supported.
@@ -520,37 +518,12 @@ static int pem_probe(struct i2c_client *client,
if (!ret && (data->fan_speed[0] || data->fan_speed[1] ||
data->fan_speed[2] || data->fan_speed[3])) {
data->fans_supported = true;
- ret = sysfs_create_group(&client->dev.kobj, &pem_fan_group);
- if (ret)
- goto out_remove_groups;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- ret = PTR_ERR(data->hwmon_dev);
- goto out_remove_groups;
+ data->groups[idx++] = &pem_fan_group;
}
- return 0;
-
-out_remove_groups:
- sysfs_remove_group(&client->dev.kobj, &pem_input_group);
- sysfs_remove_group(&client->dev.kobj, &pem_fan_group);
- sysfs_remove_group(&client->dev.kobj, &pem_group);
- return ret;
-}
-
-static int pem_remove(struct i2c_client *client)
-{
- struct pem_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
-
- sysfs_remove_group(&client->dev.kobj, &pem_input_group);
- sysfs_remove_group(&client->dev.kobj, &pem_fan_group);
- sysfs_remove_group(&client->dev.kobj, &pem_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id pem_id[] = {
@@ -564,7 +537,6 @@ static struct i2c_driver pem_driver = {
.name = "lineage_pem",
},
.probe = pem_probe,
- .remove = pem_remove,
.id_table = pem_id,
};
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 848b9611151f..33bfdb444138 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -126,24 +126,17 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
#define FAN_TO_REG(val) ((val) <= 82 ? 0xFFFC : \
(5400000 / (val)) & 0xFFFC)
#define TEMP8_FROM_REG(reg) ((reg) * 1000)
-#define TEMP8_TO_REG(val) ((val) <= -128000 ? -128 : \
- (val) >= 127000 ? 127 : \
- (val) < 0 ? ((val) - 500) / 1000 : \
- ((val) + 500) / 1000)
-#define TEMP8U_TO_REG(val) ((val) <= 0 ? 0 : \
- (val) >= 255000 ? 255 : \
- ((val) + 500) / 1000)
+#define TEMP8_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+ 127000), 1000)
+#define TEMP8U_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, \
+ 255000), 1000)
#define TEMP11_FROM_REG(reg) ((reg) / 32 * 125)
-#define TEMP11_TO_REG(val) ((val) <= -128000 ? 0x8000 : \
- (val) >= 127875 ? 0x7FE0 : \
- (val) < 0 ? ((val) - 62) / 125 * 32 : \
- ((val) + 62) / 125 * 32)
-#define TEMP11U_TO_REG(val) ((val) <= 0 ? 0 : \
- (val) >= 255875 ? 0xFFE0 : \
- ((val) + 62) / 125 * 32)
-#define HYST_TO_REG(val) ((val) <= 0 ? 0 : \
- (val) >= 127000 ? 127 : \
- ((val) + 500) / 1000)
+#define TEMP11_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+ 127875), 125) * 32)
+#define TEMP11U_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), 0, \
+ 255875), 125) * 32)
+#define HYST_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \
+ 1000)
#define UPDATE_INTERVAL(max, rate) \
((1000 << (LM63_MAX_CONVRATE - (rate))) / (max))
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 479ffbeed3f8..d16dbb33a531 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -52,6 +52,7 @@ enum lm75_type { /* keep sorted in alphabetical order */
tmp100,
tmp101,
tmp105,
+ tmp112,
tmp175,
tmp275,
tmp75,
@@ -255,6 +256,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
data->sample_time = HZ;
clr_mask |= 1 << 7; /* not one-shot mode */
break;
+ case tmp112:
+ set_mask |= 3 << 5; /* 12-bit mode */
+ clr_mask |= 1 << 7; /* not one-shot mode */
+ data->resolution = 12;
+ data->sample_time = HZ / 4;
+ break;
case tmp105:
case tmp175:
case tmp275:
@@ -323,6 +330,7 @@ static const struct i2c_device_id lm75_ids[] = {
{ "tmp100", tmp100, },
{ "tmp101", tmp101, },
{ "tmp105", tmp105, },
+ { "tmp112", tmp112, },
{ "tmp175", tmp175, },
{ "tmp275", tmp275, },
{ "tmp75", tmp75, },
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 5ceb443b938d..69b05cc2f60e 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -80,8 +80,7 @@ struct lm77_data {
*/
static inline s16 LM77_TEMP_TO_REG(int temp)
{
- int ntemp = clamp_val(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
- return (ntemp / 500) * 8;
+ return (temp / 500) * 8;
}
static inline int LM77_TEMP_FROM_REG(s16 reg)
@@ -175,6 +174,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
if (err)
return err;
+ val = clamp_val(val, LM77_TEMP_MIN, LM77_TEMP_MAX);
mutex_lock(&data->update_lock);
data->temp[nr] = val;
lm77_write_value(client, temp_regs[nr], LM77_TEMP_TO_REG(val));
@@ -192,15 +192,16 @@ static ssize_t set_temp_hyst(struct device *dev,
{
struct lm77_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
- unsigned long val;
+ long val;
int err;
- err = kstrtoul(buf, 10, &val);
+ err = kstrtol(buf, 10, &val);
if (err)
return err;
mutex_lock(&data->update_lock);
- data->temp[t_hyst] = data->temp[t_crit] - val;
+ val = clamp_val(data->temp[t_crit] - val, LM77_TEMP_MIN, LM77_TEMP_MAX);
+ data->temp[t_hyst] = val;
lm77_write_value(client, LM77_REG_TEMP_HYST,
LM77_TEMP_TO_REG(data->temp[t_hyst]));
mutex_unlock(&data->update_lock);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 9efadfc851bc..759661c7d480 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -108,7 +108,7 @@ static inline int FAN_FROM_REG(u8 val, int div)
* TEMP: mC (-128C to +127C)
* REG: 1C/bit, two's complement
*/
-static inline s8 TEMP_TO_REG(int val)
+static inline s8 TEMP_TO_REG(long val)
{
int nval = clamp_val(val, -128000, 127000) ;
return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
@@ -123,7 +123,6 @@ static inline int TEMP_FROM_REG(s8 val)
struct lm78_data {
struct i2c_client *client;
- struct device *hwmon_dev;
struct mutex lock;
enum chips type;
@@ -468,7 +467,7 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
-static struct attribute *lm78_attributes[] = {
+static struct attribute *lm78_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -519,9 +518,7 @@ static struct attribute *lm78_attributes[] = {
NULL
};
-static const struct attribute_group lm78_group = {
- .attrs = lm78_attributes,
-};
+ATTRIBUTE_GROUPS(lm78);
/*
* ISA related code
@@ -533,19 +530,6 @@ static struct platform_device *pdev;
static unsigned short isa_address = 0x290;
-/*
- * I2C devices get this name attribute automatically, but for ISA devices
- * we must create it by ourselves.
- */
-static ssize_t show_name(struct device *dev, struct device_attribute
- *devattr, char *buf)
-{
- struct lm78_data *data = dev_get_drvdata(dev);
-
- return sprintf(buf, "%s\n", data->name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
static struct lm78_data *lm78_data_if_isa(void)
{
return pdev ? platform_get_drvdata(pdev) : NULL;
@@ -661,46 +645,23 @@ static int lm78_i2c_detect(struct i2c_client *client,
static int lm78_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct lm78_data *data;
- int err;
- data = devm_kzalloc(&client->dev, sizeof(struct lm78_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
data->client = client;
data->type = id->driver_data;
/* Initialize the LM78 chip */
lm78_init_device(data);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &lm78_group);
- if (err)
- return err;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto error;
- }
-
- return 0;
-
-error:
- sysfs_remove_group(&client->dev.kobj, &lm78_group);
- return err;
-}
-
-static int lm78_i2c_remove(struct i2c_client *client)
-{
- struct lm78_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &lm78_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, lm78_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id lm78_i2c_id[] = {
@@ -716,7 +677,6 @@ static struct i2c_driver lm78_driver = {
.name = "lm78",
},
.probe = lm78_i2c_probe,
- .remove = lm78_i2c_remove,
.id_table = lm78_i2c_id,
.detect = lm78_i2c_detect,
.address_list = normal_i2c,
@@ -839,17 +799,18 @@ static struct lm78_data *lm78_update_device(struct device *dev)
#ifdef CONFIG_ISA
static int lm78_isa_probe(struct platform_device *pdev)
{
- int err;
+ struct device *dev = &pdev->dev;
+ struct device *hwmon_dev;
struct lm78_data *data;
struct resource *res;
/* Reserve the ISA region */
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!devm_request_region(&pdev->dev, res->start + LM78_ADDR_REG_OFFSET,
+ if (!devm_request_region(dev, res->start + LM78_ADDR_REG_OFFSET,
2, "lm78"))
return -EBUSY;
- data = devm_kzalloc(&pdev->dev, sizeof(struct lm78_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -868,37 +829,9 @@ static int lm78_isa_probe(struct platform_device *pdev)
/* Initialize the LM78 chip */
lm78_init_device(data);
- /* Register sysfs hooks */
- err = sysfs_create_group(&pdev->dev.kobj, &lm78_group);
- if (err)
- goto exit_remove_files;
- err = device_create_file(&pdev->dev, &dev_attr_name);
- if (err)
- goto exit_remove_files;
-
- data->hwmon_dev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
-
- exit_remove_files:
- sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
- device_remove_file(&pdev->dev, &dev_attr_name);
- return err;
-}
-
-static int lm78_isa_remove(struct platform_device *pdev)
-{
- struct lm78_data *data = platform_get_drvdata(pdev);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
- device_remove_file(&pdev->dev, &dev_attr_name);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
+ data, lm78_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static struct platform_driver lm78_isa_driver = {
@@ -907,7 +840,6 @@ static struct platform_driver lm78_isa_driver = {
.name = "lm78",
},
.probe = lm78_isa_probe,
- .remove = lm78_isa_remove,
};
/* return 1 if a supported chip is found, 0 otherwise */
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index b0129a54e1a6..2b4b419273fe 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -121,7 +121,6 @@ enum chips {
#define EMC6D102_REG_EXTEND_ADC3 0x87
#define EMC6D102_REG_EXTEND_ADC4 0x88
-
/*
* Conversions. Rounding and limit checking is only done on the TO_REG
* variants. Note that you should be a bit careful with which arguments
@@ -155,7 +154,7 @@ static inline u16 FAN_TO_REG(unsigned long val)
/* Temperature is reported in .001 degC increments */
#define TEMP_TO_REG(val) \
- clamp_val(SCALE(val, 1000, 1), -127, 127)
+ DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000)
#define TEMPEXT_FROM_REG(val, ext) \
SCALE(((val) << 4) + (ext), 16, 1000)
#define TEMP_FROM_REG(val) ((val) * 1000)
@@ -189,7 +188,7 @@ static const int lm85_range_map[] = {
13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
};
-static int RANGE_TO_REG(int range)
+static int RANGE_TO_REG(long range)
{
int i;
@@ -211,7 +210,7 @@ static const int adm1027_freq_map[8] = { /* 1 Hz */
11, 15, 22, 29, 35, 44, 59, 88
};
-static int FREQ_TO_REG(const int *map, int freq)
+static int FREQ_TO_REG(const int *map, unsigned long freq)
{
int i;
@@ -303,7 +302,8 @@ struct lm85_autofan {
* The structure is dynamically allocated.
*/
struct lm85_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[6];
const int *freq_map;
enum chips type;
@@ -334,44 +334,235 @@ struct lm85_data {
struct lm85_zone zone[3];
};
-static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info);
-static int lm85_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int lm85_remove(struct i2c_client *client);
+static int lm85_read_value(struct i2c_client *client, u8 reg)
+{
+ int res;
-static int lm85_read_value(struct i2c_client *client, u8 reg);
-static void lm85_write_value(struct i2c_client *client, u8 reg, int value);
-static struct lm85_data *lm85_update_device(struct device *dev);
+ /* What size location is it? */
+ switch (reg) {
+ case LM85_REG_FAN(0): /* Read WORD data */
+ case LM85_REG_FAN(1):
+ case LM85_REG_FAN(2):
+ case LM85_REG_FAN(3):
+ case LM85_REG_FAN_MIN(0):
+ case LM85_REG_FAN_MIN(1):
+ case LM85_REG_FAN_MIN(2):
+ case LM85_REG_FAN_MIN(3):
+ case LM85_REG_ALARM1: /* Read both bytes at once */
+ res = i2c_smbus_read_byte_data(client, reg) & 0xff;
+ res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
+ break;
+ default: /* Read BYTE data */
+ res = i2c_smbus_read_byte_data(client, reg);
+ break;
+ }
+ return res;
+}
-static const struct i2c_device_id lm85_id[] = {
- { "adm1027", adm1027 },
- { "adt7463", adt7463 },
- { "adt7468", adt7468 },
- { "lm85", lm85 },
- { "lm85b", lm85 },
- { "lm85c", lm85 },
- { "emc6d100", emc6d100 },
- { "emc6d101", emc6d100 },
- { "emc6d102", emc6d102 },
- { "emc6d103", emc6d103 },
- { "emc6d103s", emc6d103s },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, lm85_id);
+static void lm85_write_value(struct i2c_client *client, u8 reg, int value)
+{
+ switch (reg) {
+ case LM85_REG_FAN(0): /* Write WORD data */
+ case LM85_REG_FAN(1):
+ case LM85_REG_FAN(2):
+ case LM85_REG_FAN(3):
+ case LM85_REG_FAN_MIN(0):
+ case LM85_REG_FAN_MIN(1):
+ case LM85_REG_FAN_MIN(2):
+ case LM85_REG_FAN_MIN(3):
+ /* NOTE: ALARM is read only, so not included here */
+ i2c_smbus_write_byte_data(client, reg, value & 0xff);
+ i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
+ break;
+ default: /* Write BYTE data */
+ i2c_smbus_write_byte_data(client, reg, value);
+ break;
+ }
+}
-static struct i2c_driver lm85_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "lm85",
- },
- .probe = lm85_probe,
- .remove = lm85_remove,
- .id_table = lm85_id,
- .detect = lm85_detect,
- .address_list = normal_i2c,
-};
+static struct lm85_data *lm85_update_device(struct device *dev)
+{
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ if (!data->valid ||
+ time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
+ /* Things that change quickly */
+ dev_dbg(&client->dev, "Reading sensor values\n");
+
+ /*
+ * Have to read extended bits first to "freeze" the
+ * more significant bits that are read later.
+ * There are 2 additional resolution bits per channel and we
+ * have room for 4, so we shift them to the left.
+ */
+ if (data->type == adm1027 || data->type == adt7463 ||
+ data->type == adt7468) {
+ int ext1 = lm85_read_value(client,
+ ADM1027_REG_EXTEND_ADC1);
+ int ext2 = lm85_read_value(client,
+ ADM1027_REG_EXTEND_ADC2);
+ int val = (ext1 << 8) + ext2;
+
+ for (i = 0; i <= 4; i++)
+ data->in_ext[i] =
+ ((val >> (i * 2)) & 0x03) << 2;
+
+ for (i = 0; i <= 2; i++)
+ data->temp_ext[i] =
+ (val >> ((i + 4) * 2)) & 0x0c;
+ }
+
+ data->vid = lm85_read_value(client, LM85_REG_VID);
+
+ for (i = 0; i <= 3; ++i) {
+ data->in[i] =
+ lm85_read_value(client, LM85_REG_IN(i));
+ data->fan[i] =
+ lm85_read_value(client, LM85_REG_FAN(i));
+ }
+
+ if (!data->has_vid5)
+ data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
+
+ if (data->type == adt7468)
+ data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
+ for (i = 0; i <= 2; ++i) {
+ data->temp[i] =
+ lm85_read_value(client, LM85_REG_TEMP(i));
+ data->pwm[i] =
+ lm85_read_value(client, LM85_REG_PWM(i));
+
+ if (IS_ADT7468_OFF64(data))
+ data->temp[i] -= 64;
+ }
+
+ data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
+
+ if (data->type == emc6d100) {
+ /* Three more voltage sensors */
+ for (i = 5; i <= 7; ++i) {
+ data->in[i] = lm85_read_value(client,
+ EMC6D100_REG_IN(i));
+ }
+ /* More alarm bits */
+ data->alarms |= lm85_read_value(client,
+ EMC6D100_REG_ALARM3) << 16;
+ } else if (data->type == emc6d102 || data->type == emc6d103 ||
+ data->type == emc6d103s) {
+ /*
+ * Have to read LSB bits after the MSB ones because
+ * the reading of the MSB bits has frozen the
+ * LSBs (backward from the ADM1027).
+ */
+ int ext1 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC1);
+ int ext2 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC2);
+ int ext3 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC3);
+ int ext4 = lm85_read_value(client,
+ EMC6D102_REG_EXTEND_ADC4);
+ data->in_ext[0] = ext3 & 0x0f;
+ data->in_ext[1] = ext4 & 0x0f;
+ data->in_ext[2] = ext4 >> 4;
+ data->in_ext[3] = ext3 >> 4;
+ data->in_ext[4] = ext2 >> 4;
+
+ data->temp_ext[0] = ext1 & 0x0f;
+ data->temp_ext[1] = ext2 & 0x0f;
+ data->temp_ext[2] = ext1 >> 4;
+ }
+
+ data->last_reading = jiffies;
+ } /* last_reading */
+
+ if (!data->valid ||
+ time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
+ /* Things that don't change often */
+ dev_dbg(&client->dev, "Reading config values\n");
+
+ for (i = 0; i <= 3; ++i) {
+ data->in_min[i] =
+ lm85_read_value(client, LM85_REG_IN_MIN(i));
+ data->in_max[i] =
+ lm85_read_value(client, LM85_REG_IN_MAX(i));
+ data->fan_min[i] =
+ lm85_read_value(client, LM85_REG_FAN_MIN(i));
+ }
+
+ if (!data->has_vid5) {
+ data->in_min[4] = lm85_read_value(client,
+ LM85_REG_IN_MIN(4));
+ data->in_max[4] = lm85_read_value(client,
+ LM85_REG_IN_MAX(4));
+ }
+
+ if (data->type == emc6d100) {
+ for (i = 5; i <= 7; ++i) {
+ data->in_min[i] = lm85_read_value(client,
+ EMC6D100_REG_IN_MIN(i));
+ data->in_max[i] = lm85_read_value(client,
+ EMC6D100_REG_IN_MAX(i));
+ }
+ }
+
+ for (i = 0; i <= 2; ++i) {
+ int val;
+
+ data->temp_min[i] =
+ lm85_read_value(client, LM85_REG_TEMP_MIN(i));
+ data->temp_max[i] =
+ lm85_read_value(client, LM85_REG_TEMP_MAX(i));
+
+ data->autofan[i].config =
+ lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
+ val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
+ data->pwm_freq[i] = val & 0x07;
+ data->zone[i].range = val >> 4;
+ data->autofan[i].min_pwm =
+ lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
+ data->zone[i].limit =
+ lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
+ data->zone[i].critical =
+ lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
+
+ if (IS_ADT7468_OFF64(data)) {
+ data->temp_min[i] -= 64;
+ data->temp_max[i] -= 64;
+ data->zone[i].limit -= 64;
+ data->zone[i].critical -= 64;
+ }
+ }
+
+ if (data->type != emc6d103s) {
+ i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
+ data->autofan[0].min_off = (i & 0x20) != 0;
+ data->autofan[1].min_off = (i & 0x40) != 0;
+ data->autofan[2].min_off = (i & 0x80) != 0;
+
+ i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
+ data->zone[0].hyst = i >> 4;
+ data->zone[1].hyst = i & 0x0f;
+
+ i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
+ data->zone[2].hyst = i >> 4;
+ }
+
+ data->last_config = jiffies;
+ } /* last_config */
+
+ data->valid = 1;
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
/* 4 Fans */
static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
@@ -394,8 +585,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -460,6 +651,9 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
if (err)
return err;
+ if (val > 255)
+ return -EINVAL;
+
data->vrm = val;
return count;
}
@@ -515,8 +709,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -557,8 +751,8 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
*attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 config;
unsigned long val;
int err;
@@ -615,8 +809,8 @@ static ssize_t set_pwm_freq(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -682,8 +876,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -710,8 +904,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -766,8 +960,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -797,8 +991,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -843,8 +1037,8 @@ static ssize_t set_pwm_auto_channels(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -873,8 +1067,8 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -902,8 +1096,8 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 tmp;
long val;
int err;
@@ -953,8 +1147,8 @@ static ssize_t set_temp_auto_temp_off(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int min;
long val;
int err;
@@ -990,8 +1184,8 @@ static ssize_t set_temp_auto_temp_min(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1029,8 +1223,8 @@ static ssize_t set_temp_auto_temp_max(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int min;
long val;
int err;
@@ -1063,8 +1257,8 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
+ struct lm85_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1355,30 +1549,18 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
return 0;
}
-static void lm85_remove_files(struct i2c_client *client, struct lm85_data *data)
-{
- sysfs_remove_group(&client->dev.kobj, &lm85_group);
- if (data->type != emc6d103s) {
- sysfs_remove_group(&client->dev.kobj, &lm85_group_minctl);
- sysfs_remove_group(&client->dev.kobj, &lm85_group_temp_off);
- }
- if (!data->has_vid5)
- sysfs_remove_group(&client->dev.kobj, &lm85_group_in4);
- if (data->type == emc6d100)
- sysfs_remove_group(&client->dev.kobj, &lm85_group_in567);
-}
-
-static int lm85_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct lm85_data *data;
- int err;
+ int idx = 0;
- data = devm_kzalloc(&client->dev, sizeof(struct lm85_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
data->type = id->driver_data;
mutex_init(&data->update_lock);
@@ -1403,20 +1585,13 @@ static int lm85_probe(struct i2c_client *client,
/* Initialize the LM85 chip */
lm85_init_client(client);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &lm85_group);
- if (err)
- return err;
+ /* sysfs hooks */
+ data->groups[idx++] = &lm85_group;
/* minctl and temp_off exist on all chips except emc6d103s */
if (data->type != emc6d103s) {
- err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl);
- if (err)
- goto err_remove_files;
- err = sysfs_create_group(&client->dev.kobj,
- &lm85_group_temp_off);
- if (err)
- goto err_remove_files;
+ data->groups[idx++] = &lm85_group_minctl;
+ data->groups[idx++] = &lm85_group_temp_off;
}
/*
@@ -1429,271 +1604,44 @@ static int lm85_probe(struct i2c_client *client,
data->has_vid5 = true;
}
- if (!data->has_vid5) {
- err = sysfs_create_group(&client->dev.kobj, &lm85_group_in4);
- if (err)
- goto err_remove_files;
- }
+ if (!data->has_vid5)
+ data->groups[idx++] = &lm85_group_in4;
/* The EMC6D100 has 3 additional voltage inputs */
- if (data->type == emc6d100) {
- err = sysfs_create_group(&client->dev.kobj, &lm85_group_in567);
- if (err)
- goto err_remove_files;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto err_remove_files;
- }
-
- return 0;
-
- /* Error out and cleanup code */
- err_remove_files:
- lm85_remove_files(client, data);
- return err;
-}
-
-static int lm85_remove(struct i2c_client *client)
-{
- struct lm85_data *data = i2c_get_clientdata(client);
- hwmon_device_unregister(data->hwmon_dev);
- lm85_remove_files(client, data);
- return 0;
-}
-
-
-static int lm85_read_value(struct i2c_client *client, u8 reg)
-{
- int res;
-
- /* What size location is it? */
- switch (reg) {
- case LM85_REG_FAN(0): /* Read WORD data */
- case LM85_REG_FAN(1):
- case LM85_REG_FAN(2):
- case LM85_REG_FAN(3):
- case LM85_REG_FAN_MIN(0):
- case LM85_REG_FAN_MIN(1):
- case LM85_REG_FAN_MIN(2):
- case LM85_REG_FAN_MIN(3):
- case LM85_REG_ALARM1: /* Read both bytes at once */
- res = i2c_smbus_read_byte_data(client, reg) & 0xff;
- res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
- break;
- default: /* Read BYTE data */
- res = i2c_smbus_read_byte_data(client, reg);
- break;
- }
-
- return res;
-}
+ if (data->type == emc6d100)
+ data->groups[idx++] = &lm85_group_in567;
-static void lm85_write_value(struct i2c_client *client, u8 reg, int value)
-{
- switch (reg) {
- case LM85_REG_FAN(0): /* Write WORD data */
- case LM85_REG_FAN(1):
- case LM85_REG_FAN(2):
- case LM85_REG_FAN(3):
- case LM85_REG_FAN_MIN(0):
- case LM85_REG_FAN_MIN(1):
- case LM85_REG_FAN_MIN(2):
- case LM85_REG_FAN_MIN(3):
- /* NOTE: ALARM is read only, so not included here */
- i2c_smbus_write_byte_data(client, reg, value & 0xff);
- i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
- break;
- default: /* Write BYTE data */
- i2c_smbus_write_byte_data(client, reg, value);
- break;
- }
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static struct lm85_data *lm85_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
- int i;
-
- mutex_lock(&data->update_lock);
-
- if (!data->valid ||
- time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
- /* Things that change quickly */
- dev_dbg(&client->dev, "Reading sensor values\n");
-
- /*
- * Have to read extended bits first to "freeze" the
- * more significant bits that are read later.
- * There are 2 additional resolution bits per channel and we
- * have room for 4, so we shift them to the left.
- */
- if (data->type == adm1027 || data->type == adt7463 ||
- data->type == adt7468) {
- int ext1 = lm85_read_value(client,
- ADM1027_REG_EXTEND_ADC1);
- int ext2 = lm85_read_value(client,
- ADM1027_REG_EXTEND_ADC2);
- int val = (ext1 << 8) + ext2;
-
- for (i = 0; i <= 4; i++)
- data->in_ext[i] =
- ((val >> (i * 2)) & 0x03) << 2;
-
- for (i = 0; i <= 2; i++)
- data->temp_ext[i] =
- (val >> ((i + 4) * 2)) & 0x0c;
- }
-
- data->vid = lm85_read_value(client, LM85_REG_VID);
-
- for (i = 0; i <= 3; ++i) {
- data->in[i] =
- lm85_read_value(client, LM85_REG_IN(i));
- data->fan[i] =
- lm85_read_value(client, LM85_REG_FAN(i));
- }
-
- if (!data->has_vid5)
- data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
-
- if (data->type == adt7468)
- data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
-
- for (i = 0; i <= 2; ++i) {
- data->temp[i] =
- lm85_read_value(client, LM85_REG_TEMP(i));
- data->pwm[i] =
- lm85_read_value(client, LM85_REG_PWM(i));
-
- if (IS_ADT7468_OFF64(data))
- data->temp[i] -= 64;
- }
-
- data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
- if (data->type == emc6d100) {
- /* Three more voltage sensors */
- for (i = 5; i <= 7; ++i) {
- data->in[i] = lm85_read_value(client,
- EMC6D100_REG_IN(i));
- }
- /* More alarm bits */
- data->alarms |= lm85_read_value(client,
- EMC6D100_REG_ALARM3) << 16;
- } else if (data->type == emc6d102 || data->type == emc6d103 ||
- data->type == emc6d103s) {
- /*
- * Have to read LSB bits after the MSB ones because
- * the reading of the MSB bits has frozen the
- * LSBs (backward from the ADM1027).
- */
- int ext1 = lm85_read_value(client,
- EMC6D102_REG_EXTEND_ADC1);
- int ext2 = lm85_read_value(client,
- EMC6D102_REG_EXTEND_ADC2);
- int ext3 = lm85_read_value(client,
- EMC6D102_REG_EXTEND_ADC3);
- int ext4 = lm85_read_value(client,
- EMC6D102_REG_EXTEND_ADC4);
- data->in_ext[0] = ext3 & 0x0f;
- data->in_ext[1] = ext4 & 0x0f;
- data->in_ext[2] = ext4 >> 4;
- data->in_ext[3] = ext3 >> 4;
- data->in_ext[4] = ext2 >> 4;
-
- data->temp_ext[0] = ext1 & 0x0f;
- data->temp_ext[1] = ext2 & 0x0f;
- data->temp_ext[2] = ext1 >> 4;
- }
-
- data->last_reading = jiffies;
- } /* last_reading */
-
- if (!data->valid ||
- time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
- /* Things that don't change often */
- dev_dbg(&client->dev, "Reading config values\n");
-
- for (i = 0; i <= 3; ++i) {
- data->in_min[i] =
- lm85_read_value(client, LM85_REG_IN_MIN(i));
- data->in_max[i] =
- lm85_read_value(client, LM85_REG_IN_MAX(i));
- data->fan_min[i] =
- lm85_read_value(client, LM85_REG_FAN_MIN(i));
- }
-
- if (!data->has_vid5) {
- data->in_min[4] = lm85_read_value(client,
- LM85_REG_IN_MIN(4));
- data->in_max[4] = lm85_read_value(client,
- LM85_REG_IN_MAX(4));
- }
-
- if (data->type == emc6d100) {
- for (i = 5; i <= 7; ++i) {
- data->in_min[i] = lm85_read_value(client,
- EMC6D100_REG_IN_MIN(i));
- data->in_max[i] = lm85_read_value(client,
- EMC6D100_REG_IN_MAX(i));
- }
- }
-
- for (i = 0; i <= 2; ++i) {
- int val;
-
- data->temp_min[i] =
- lm85_read_value(client, LM85_REG_TEMP_MIN(i));
- data->temp_max[i] =
- lm85_read_value(client, LM85_REG_TEMP_MAX(i));
-
- data->autofan[i].config =
- lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
- val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
- data->pwm_freq[i] = val & 0x07;
- data->zone[i].range = val >> 4;
- data->autofan[i].min_pwm =
- lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
- data->zone[i].limit =
- lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
- data->zone[i].critical =
- lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
-
- if (IS_ADT7468_OFF64(data)) {
- data->temp_min[i] -= 64;
- data->temp_max[i] -= 64;
- data->zone[i].limit -= 64;
- data->zone[i].critical -= 64;
- }
- }
-
- if (data->type != emc6d103s) {
- i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
- data->autofan[0].min_off = (i & 0x20) != 0;
- data->autofan[1].min_off = (i & 0x40) != 0;
- data->autofan[2].min_off = (i & 0x80) != 0;
-
- i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
- data->zone[0].hyst = i >> 4;
- data->zone[1].hyst = i & 0x0f;
-
- i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
- data->zone[2].hyst = i >> 4;
- }
-
- data->last_config = jiffies;
- } /* last_config */
-
- data->valid = 1;
-
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id lm85_id[] = {
+ { "adm1027", adm1027 },
+ { "adt7463", adt7463 },
+ { "adt7468", adt7468 },
+ { "lm85", lm85 },
+ { "lm85b", lm85 },
+ { "lm85c", lm85 },
+ { "emc6d100", emc6d100 },
+ { "emc6d101", emc6d100 },
+ { "emc6d102", emc6d102 },
+ { "emc6d103", emc6d103 },
+ { "emc6d103s", emc6d103s },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lm85_id);
- return data;
-}
+static struct i2c_driver lm85_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "lm85",
+ },
+ .probe = lm85_probe,
+ .id_table = lm85_id,
+ .detect = lm85_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(lm85_driver);
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index 6c2df576f253..90bb04858117 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -207,7 +207,7 @@ struct block1_t {
* Client-specific data
*/
struct lm93_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
unsigned long last_updated; /* In jiffies */
@@ -919,8 +919,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values)
static struct lm93_data *lm93_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
const unsigned long interval = HZ + (HZ / 2);
mutex_lock(&data->update_lock);
@@ -1158,8 +1158,8 @@ static ssize_t store_in_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int vccp = nr - 6;
long vid;
unsigned long val;
@@ -1239,8 +1239,8 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int vccp = nr - 6;
long vid;
unsigned long val;
@@ -1323,8 +1323,8 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1358,8 +1358,8 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1394,8 +1394,8 @@ static ssize_t store_temp_auto_base(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1430,8 +1430,8 @@ static ssize_t store_temp_auto_boost(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -1469,8 +1469,8 @@ static ssize_t store_temp_auto_boost_hyst(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1520,8 +1520,8 @@ static ssize_t store_temp_auto_offset(struct device *dev,
struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
int nr = s_attr->index;
int ofs = s_attr->nr;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1632,8 +1632,8 @@ static ssize_t store_temp_auto_pwm_min(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 reg, ctl4;
unsigned long val;
int err;
@@ -1680,8 +1680,8 @@ static ssize_t store_temp_auto_offset_hyst(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 reg;
unsigned long val;
int err;
@@ -1741,8 +1741,8 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1824,8 +1824,8 @@ static ssize_t store_fan_smart_tach(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -1880,8 +1880,8 @@ static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ctl2, ctl4;
unsigned long val;
int err;
@@ -1928,8 +1928,8 @@ static ssize_t store_pwm_enable(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ctl2;
unsigned long val;
int err;
@@ -2006,8 +2006,8 @@ static ssize_t store_pwm_freq(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ctl4;
unsigned long val;
int err;
@@ -2046,8 +2046,8 @@ static ssize_t store_pwm_auto_channels(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -2087,8 +2087,8 @@ static ssize_t store_pwm_auto_spinup_min(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ctl3, ctl4;
unsigned long val;
int err;
@@ -2130,8 +2130,8 @@ static ssize_t store_pwm_auto_spinup_time(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ctl3;
unsigned long val;
int err;
@@ -2168,8 +2168,8 @@ static ssize_t store_pwm_auto_prochot_ramp(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ramp;
unsigned long val;
int err;
@@ -2202,8 +2202,8 @@ static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 ramp;
unsigned long val;
int err;
@@ -2270,8 +2270,8 @@ static ssize_t store_prochot_max(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -2308,8 +2308,8 @@ static ssize_t store_prochot_override(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -2351,8 +2351,8 @@ static ssize_t store_prochot_interval(struct device *dev,
const char *buf, size_t count)
{
int nr = (to_sensor_dev_attr(attr))->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 tmp;
unsigned long val;
int err;
@@ -2390,8 +2390,8 @@ static ssize_t store_prochot_override_duty_cycle(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -2423,8 +2423,8 @@ static ssize_t store_prochot_short(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm93_data *data = i2c_get_clientdata(client);
+ struct lm93_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -2631,9 +2631,7 @@ static struct attribute *lm93_attrs[] = {
NULL
};
-static struct attribute_group lm93_attr_grp = {
- .attrs = lm93_attrs,
-};
+ATTRIBUTE_GROUPS(lm93);
static void lm93_init_client(struct i2c_client *client)
{
@@ -2726,61 +2724,42 @@ static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info)
static int lm93_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct lm93_data *data;
- int err, func;
+ struct device *hwmon_dev;
+ int func;
void (*update)(struct lm93_data *, struct i2c_client *);
/* choose update routine based on bus capabilities */
func = i2c_get_functionality(client->adapter);
if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) &&
(!disable_block)) {
- dev_dbg(&client->dev, "using SMBus block data transactions\n");
+ dev_dbg(dev, "using SMBus block data transactions\n");
update = lm93_update_client_full;
} else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) {
- dev_dbg(&client->dev,
- "disabled SMBus block data transactions\n");
+ dev_dbg(dev, "disabled SMBus block data transactions\n");
update = lm93_update_client_min;
} else {
- dev_dbg(&client->dev,
- "detect failed, smbus byte and/or word data not supported!\n");
+ dev_dbg(dev, "detect failed, smbus byte and/or word data not supported!\n");
return -ENODEV;
}
- data = devm_kzalloc(&client->dev, sizeof(struct lm93_data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct lm93_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
/* housekeeping */
+ data->client = client;
data->update = update;
mutex_init(&data->update_lock);
/* initialize the chip */
lm93_init_client(client);
- err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp);
- if (err)
- return err;
-
- /* Register hwmon driver class */
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (!IS_ERR(data->hwmon_dev))
- return 0;
-
- err = PTR_ERR(data->hwmon_dev);
- dev_err(&client->dev, "error registering hwmon device.\n");
- sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
- return err;
-}
-
-static int lm93_remove(struct i2c_client *client)
-{
- struct lm93_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ lm93_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id lm93_id[] = {
@@ -2796,7 +2775,6 @@ static struct i2c_driver lm93_driver = {
.name = "lm93",
},
.probe = lm93_probe,
- .remove = lm93_remove,
.id_table = lm93_id,
.detect = lm93_detect,
.address_list = normal_i2c,
diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c
index 3701b329b6ae..1b92e4f6e234 100644
--- a/drivers/hwmon/ltc2945.c
+++ b/drivers/hwmon/ltc2945.c
@@ -469,7 +469,7 @@ static struct attribute *ltc2945_attrs[] = {
};
ATTRIBUTE_GROUPS(ltc2945);
-static struct regmap_config ltc2945_regmap_config = {
+static const struct regmap_config ltc2945_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = LTC2945_MIN_ADIN_THRES_L,
diff --git a/drivers/hwmon/ltc4222.c b/drivers/hwmon/ltc4222.c
index 07c25653659f..88f747292816 100644
--- a/drivers/hwmon/ltc4222.c
+++ b/drivers/hwmon/ltc4222.c
@@ -186,7 +186,7 @@ static struct attribute *ltc4222_attrs[] = {
};
ATTRIBUTE_GROUPS(ltc4222);
-static struct regmap_config ltc4222_regmap_config = {
+static const struct regmap_config ltc4222_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = LTC4222_ADC_CONTROL,
diff --git a/drivers/hwmon/ltc4260.c b/drivers/hwmon/ltc4260.c
index 453a250d9df5..afb09574b12c 100644
--- a/drivers/hwmon/ltc4260.c
+++ b/drivers/hwmon/ltc4260.c
@@ -150,7 +150,7 @@ static struct attribute *ltc4260_attrs[] = {
};
ATTRIBUTE_GROUPS(ltc4260);
-static struct regmap_config ltc4260_regmap_config = {
+static const struct regmap_config ltc4260_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = LTC4260_ADIN,
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index d4efc79d7b93..162401aaef71 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -642,10 +642,7 @@ static int max16065_probe(struct i2c_client *client,
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, data->groups);
- if (unlikely(IS_ERR(hwmon_dev)))
- return PTR_ERR(hwmon_dev);
-
- return 0;
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id max16065_id[] = {
diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c
index e3ed0a5b6d94..7ca889910262 100644
--- a/drivers/hwmon/max1668.c
+++ b/drivers/hwmon/max1668.c
@@ -30,7 +30,7 @@
#include <linux/mutex.h>
/* Addresses to scan */
-static unsigned short max1668_addr_list[] = {
+static const unsigned short max1668_addr_list[] = {
0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
/* max1668 registers */
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index 70650de2cbd1..dac6d85f2fd9 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -35,7 +35,7 @@
#include <linux/i2c/max6639.h>
/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
/* The MAX6639 registers, valid channel numbers: 0, 1 */
#define MAX6639_REG_TEMP(ch) (0x00 + (ch))
diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c
index 7fd3eaf817f4..f03a71722849 100644
--- a/drivers/hwmon/max6697.c
+++ b/drivers/hwmon/max6697.c
@@ -495,15 +495,13 @@ static void max6697_get_config_of(struct device_node *node,
int len;
const __be32 *prop;
- prop = of_get_property(node, "smbus-timeout-disable", &len);
- if (prop)
- pdata->smbus_timeout_disable = true;
- prop = of_get_property(node, "extended-range-enable", &len);
- if (prop)
- pdata->extended_range_enable = true;
- prop = of_get_property(node, "beta-compensation-enable", &len);
- if (prop)
- pdata->beta_compensation = true;
+ pdata->smbus_timeout_disable =
+ of_property_read_bool(node, "smbus-timeout-disable");
+ pdata->extended_range_enable =
+ of_property_read_bool(node, "extended-range-enable");
+ pdata->beta_compensation =
+ of_property_read_bool(node, "beta-compensation-enable");
+
prop = of_get_property(node, "alert-mask", &len);
if (prop && len == sizeof(u32))
pdata->alert_mask = be32_to_cpu(prop[0]);
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 59d9a3fc96b7..504cbddbdd90 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -735,7 +735,6 @@ struct nct6775_data {
enum kinds kind;
const char *name;
- int num_attr_groups;
const struct attribute_group *groups[6];
u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
@@ -3276,6 +3275,7 @@ static int nct6775_probe(struct platform_device *pdev)
u8 cr2a;
struct attribute_group *group;
struct device *hwmon_dev;
+ int num_attr_groups = 0;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
@@ -3907,29 +3907,29 @@ static int nct6775_probe(struct platform_device *pdev)
if (IS_ERR(group))
return PTR_ERR(group);
- data->groups[data->num_attr_groups++] = group;
+ data->groups[num_attr_groups++] = group;
group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
fls(data->have_in));
if (IS_ERR(group))
return PTR_ERR(group);
- data->groups[data->num_attr_groups++] = group;
+ data->groups[num_attr_groups++] = group;
group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
fls(data->has_fan));
if (IS_ERR(group))
return PTR_ERR(group);
- data->groups[data->num_attr_groups++] = group;
+ data->groups[num_attr_groups++] = group;
group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
fls(data->have_temp));
if (IS_ERR(group))
return PTR_ERR(group);
- data->groups[data->num_attr_groups++] = group;
- data->groups[data->num_attr_groups++] = &nct6775_group_other;
+ data->groups[num_attr_groups++] = group;
+ data->groups[num_attr_groups++] = &nct6775_group_other;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
data, data->groups);
@@ -4221,7 +4221,7 @@ static void __exit sensors_nct6775_exit(void)
}
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
-MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
+MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D driver");
MODULE_LICENSE("GPL");
module_init(sensors_nct6775_init);
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index bdfbe9114889..bd410722cd4b 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -51,6 +51,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
{ "ncp21wb473", TYPE_NCPXXWB473 },
{ "ncp03wb473", TYPE_NCPXXWB473 },
{ "ncp15wl333", TYPE_NCPXXWL333 },
+ { "b57330v2103", TYPE_B57330V2103},
{ },
};
@@ -133,6 +134,47 @@ static const struct ntc_compensation ncpXXwl333[] = {
{ .temp_c = 125, .ohm = 707 },
};
+/*
+ * The following compensation table is from the specification of EPCOS NTC
+ * Thermistors Datasheet
+ */
+static const struct ntc_compensation b57330v2103[] = {
+ { .temp_c = -40, .ohm = 190030 },
+ { .temp_c = -35, .ohm = 145360 },
+ { .temp_c = -30, .ohm = 112060 },
+ { .temp_c = -25, .ohm = 87041 },
+ { .temp_c = -20, .ohm = 68104 },
+ { .temp_c = -15, .ohm = 53665 },
+ { .temp_c = -10, .ohm = 42576 },
+ { .temp_c = -5, .ohm = 34001 },
+ { .temp_c = 0, .ohm = 27326 },
+ { .temp_c = 5, .ohm = 22096 },
+ { .temp_c = 10, .ohm = 17973 },
+ { .temp_c = 15, .ohm = 14703 },
+ { .temp_c = 20, .ohm = 12090 },
+ { .temp_c = 25, .ohm = 10000 },
+ { .temp_c = 30, .ohm = 8311 },
+ { .temp_c = 35, .ohm = 6941 },
+ { .temp_c = 40, .ohm = 5825 },
+ { .temp_c = 45, .ohm = 4911 },
+ { .temp_c = 50, .ohm = 4158 },
+ { .temp_c = 55, .ohm = 3536 },
+ { .temp_c = 60, .ohm = 3019 },
+ { .temp_c = 65, .ohm = 2588 },
+ { .temp_c = 70, .ohm = 2227 },
+ { .temp_c = 75, .ohm = 1924 },
+ { .temp_c = 80, .ohm = 1668 },
+ { .temp_c = 85, .ohm = 1451 },
+ { .temp_c = 90, .ohm = 1266 },
+ { .temp_c = 95, .ohm = 1108 },
+ { .temp_c = 100, .ohm = 973 },
+ { .temp_c = 105, .ohm = 857 },
+ { .temp_c = 110, .ohm = 757 },
+ { .temp_c = 115, .ohm = 671 },
+ { .temp_c = 120, .ohm = 596 },
+ { .temp_c = 125, .ohm = 531 },
+};
+
struct ntc_data {
struct device *hwmon_dev;
struct ntc_thermistor_platform_data *pdata;
@@ -173,6 +215,8 @@ static const struct of_device_id ntc_match[] = {
.data = &ntc_thermistor_id[3] },
{ .compatible = "murata,ncp15wl333",
.data = &ntc_thermistor_id[4] },
+ { .compatible = "epcos,b57330v2103",
+ .data = &ntc_thermistor_id[5]},
/* Usage of vendor name "ntc" is deprecated */
{ .compatible = "ntc,ncp15wb473",
@@ -490,6 +534,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
data->comp = ncpXXwl333;
data->n_comp = ARRAY_SIZE(ncpXXwl333);
break;
+ case TYPE_B57330V2103:
+ data->comp = b57330v2103;
+ data->n_comp = ARRAY_SIZE(b57330v2103);
+ break;
default:
dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n",
pdev_id->driver_data, pdev_id->name);
@@ -512,7 +560,7 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
}
dev_info(&pdev->dev, "Thermistor type: %s successfully probed.\n",
- pdev->name);
+ pdev_id->name);
return 0;
err_after_sysfs:
@@ -546,7 +594,7 @@ static struct platform_driver ntc_thermistor_driver = {
module_platform_driver(ntc_thermistor_driver);
-MODULE_DESCRIPTION("NTC Thermistor Driver from Murata");
+MODULE_DESCRIPTION("NTC Thermistor Driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ntc-thermistor");
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index 39cc63edfbb0..6e1e4935fc62 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -20,8 +20,7 @@ config SENSORS_PMBUS
help
If you say yes here you get hardware monitoring support for generic
PMBus devices, including but not limited to ADP4000, BMR453, BMR454,
- MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, TPS40400,
- and TPS40422.
+ MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, and TPS40400.
This driver can also be built as a module. If so, the module will
be called pmbus.
@@ -87,6 +86,16 @@ config SENSORS_MAX8688
This driver can also be built as a module. If so, the module will
be called max8688.
+config SENSORS_TPS40422
+ tristate "TI TPS40422"
+ default n
+ help
+ If you say yes here you get hardware monitoring support for TI
+ TPS40422.
+
+ This driver can also be built as a module. If so, the module will
+ be called tps40422.
+
config SENSORS_UCD9000
tristate "TI UCD90120, UCD90124, UCD9090, UCD90910"
default n
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 789376c85dbb..1454293e985c 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
obj-$(CONFIG_SENSORS_MAX16064) += max16064.o
obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
obj-$(CONFIG_SENSORS_MAX8688) += max8688.o
+obj-$(CONFIG_SENSORS_TPS40422) += tps40422.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/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
index 7e91700131a7..554d0249dcde 100644
--- a/drivers/hwmon/pmbus/pmbus.c
+++ b/drivers/hwmon/pmbus/pmbus.c
@@ -193,7 +193,6 @@ static const struct i2c_device_id pmbus_id[] = {
{"pdt012", 1},
{"pmbus", 0},
{"tps40400", 1},
- {"tps40422", 2},
{"udt020", 1},
{}
};
diff --git a/drivers/hwmon/pmbus/tps40422.c b/drivers/hwmon/pmbus/tps40422.c
new file mode 100644
index 000000000000..32803825d47e
--- /dev/null
+++ b/drivers/hwmon/pmbus/tps40422.c
@@ -0,0 +1,64 @@
+/*
+ * Hardware monitoring driver for TI TPS40422
+ *
+ * Copyright (c) 2014 Nokia Solutions and Networks.
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include "pmbus.h"
+
+static struct pmbus_driver_info tps40422_info = {
+ .pages = 2,
+ .format[PSC_VOLTAGE_IN] = linear,
+ .format[PSC_VOLTAGE_OUT] = linear,
+ .format[PSC_TEMPERATURE] = linear,
+ .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2
+ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP
+ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
+ .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2
+ | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP
+ | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
+};
+
+static int tps40422_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return pmbus_do_probe(client, id, &tps40422_info);
+}
+
+static const struct i2c_device_id tps40422_id[] = {
+ {"tps40422", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, tps40422_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver tps40422_driver = {
+ .driver = {
+ .name = "tps40422",
+ },
+ .probe = tps40422_probe,
+ .remove = pmbus_do_remove,
+ .id_table = tps40422_id,
+};
+
+module_i2c_driver(tps40422_driver);
+
+MODULE_AUTHOR("Zhu Laiwen <richard.zhu@nsn.com>");
+MODULE_DESCRIPTION("PMBus driver for TI TPS40422");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/powr1220.c b/drivers/hwmon/powr1220.c
new file mode 100644
index 000000000000..3014e4ac741e
--- /dev/null
+++ b/drivers/hwmon/powr1220.c
@@ -0,0 +1,391 @@
+/*
+ * powr1220.c - Driver for the Lattice POWR1220 programmable power supply
+ * and monitor. Users can read all ADC inputs along with their labels
+ * using the sysfs nodes.
+ *
+ * Copyright (c) 2014 Echo360 http://www.echo360.com
+ * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ADC_STEP_MV 2
+#define ADC_MAX_LOW_MEASUREMENT_MV 2000
+
+enum powr1220_regs {
+ VMON_STATUS0,
+ VMON_STATUS1,
+ VMON_STATUS2,
+ OUTPUT_STATUS0,
+ OUTPUT_STATUS1,
+ OUTPUT_STATUS2,
+ INPUT_STATUS,
+ ADC_VALUE_LOW,
+ ADC_VALUE_HIGH,
+ ADC_MUX,
+ UES_BYTE0,
+ UES_BYTE1,
+ UES_BYTE2,
+ UES_BYTE3,
+ GP_OUTPUT1,
+ GP_OUTPUT2,
+ GP_OUTPUT3,
+ INPUT_VALUE,
+ RESET,
+ TRIM1_TRIM,
+ TRIM2_TRIM,
+ TRIM3_TRIM,
+ TRIM4_TRIM,
+ TRIM5_TRIM,
+ TRIM6_TRIM,
+ TRIM7_TRIM,
+ TRIM8_TRIM,
+ MAX_POWR1220_REGS
+};
+
+enum powr1220_adc_values {
+ VMON1,
+ VMON2,
+ VMON3,
+ VMON4,
+ VMON5,
+ VMON6,
+ VMON7,
+ VMON8,
+ VMON9,
+ VMON10,
+ VMON11,
+ VMON12,
+ VCCA,
+ VCCINP,
+ MAX_POWR1220_ADC_VALUES
+};
+
+struct powr1220_data {
+ struct i2c_client *client;
+ struct mutex update_lock;
+ bool adc_valid[MAX_POWR1220_ADC_VALUES];
+ /* the next value is in jiffies */
+ unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
+
+ /* values */
+ int adc_maxes[MAX_POWR1220_ADC_VALUES];
+ int adc_values[MAX_POWR1220_ADC_VALUES];
+};
+
+static const char * const input_names[] = {
+ [VMON1] = "vmon1",
+ [VMON2] = "vmon2",
+ [VMON3] = "vmon3",
+ [VMON4] = "vmon4",
+ [VMON5] = "vmon5",
+ [VMON6] = "vmon6",
+ [VMON7] = "vmon7",
+ [VMON8] = "vmon8",
+ [VMON9] = "vmon9",
+ [VMON10] = "vmon10",
+ [VMON11] = "vmon11",
+ [VMON12] = "vmon12",
+ [VCCA] = "vcca",
+ [VCCINP] = "vccinp",
+};
+
+/* Reads the specified ADC channel */
+static int powr1220_read_adc(struct device *dev, int ch_num)
+{
+ struct powr1220_data *data = dev_get_drvdata(dev);
+ int reading;
+ int result;
+ int adc_range = 0;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
+ !data->adc_valid[ch_num]) {
+ /*
+ * figure out if we need to use the attenuator for
+ * high inputs or inputs that we don't yet have a measurement
+ * for. We dynamically set the attenuator depending on the
+ * max reading.
+ */
+ if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV ||
+ data->adc_maxes[ch_num] == 0)
+ adc_range = 1 << 4;
+
+ /* set the attenuator and mux */
+ result = i2c_smbus_write_byte_data(data->client, ADC_MUX,
+ adc_range | ch_num);
+ if (result)
+ goto exit;
+
+ /*
+ * wait at least Tconvert time (200 us) for the
+ * conversion to complete
+ */
+ udelay(200);
+
+ /* get the ADC reading */
+ result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW);
+ if (result < 0)
+ goto exit;
+
+ reading = result >> 4;
+
+ /* get the upper half of the reading */
+ result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH);
+ if (result < 0)
+ goto exit;
+
+ reading |= result << 4;
+
+ /* now convert the reading to a voltage */
+ reading *= ADC_STEP_MV;
+ data->adc_values[ch_num] = reading;
+ data->adc_valid[ch_num] = true;
+ data->adc_last_updated[ch_num] = jiffies;
+ result = reading;
+
+ if (reading > data->adc_maxes[ch_num])
+ data->adc_maxes[ch_num] = reading;
+ } else {
+ result = data->adc_values[ch_num];
+ }
+
+exit:
+ mutex_unlock(&data->update_lock);
+
+ return result;
+}
+
+/* Shows the voltage associated with the specified ADC channel */
+static ssize_t powr1220_show_voltage(struct device *dev,
+ struct device_attribute *dev_attr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+ int adc_val = powr1220_read_adc(dev, attr->index);
+
+ if (adc_val < 0)
+ return adc_val;
+
+ return sprintf(buf, "%d\n", adc_val);
+}
+
+/* Shows the maximum setting associated with the specified ADC channel */
+static ssize_t powr1220_show_max(struct device *dev,
+ struct device_attribute *dev_attr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+ struct powr1220_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", data->adc_maxes[attr->index]);
+}
+
+/* Shows the label associated with the specified ADC channel */
+static ssize_t powr1220_show_label(struct device *dev,
+ struct device_attribute *dev_attr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+
+ return sprintf(buf, "%s\n", input_names[attr->index]);
+}
+
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON1);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON2);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON3);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON4);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON5);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON6);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON7);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON8);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON9);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON10);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON11);
+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VMON12);
+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VCCA);
+static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, powr1220_show_voltage, NULL,
+ VCCINP);
+
+static SENSOR_DEVICE_ATTR(in0_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON1);
+static SENSOR_DEVICE_ATTR(in1_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON2);
+static SENSOR_DEVICE_ATTR(in2_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON3);
+static SENSOR_DEVICE_ATTR(in3_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON4);
+static SENSOR_DEVICE_ATTR(in4_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON5);
+static SENSOR_DEVICE_ATTR(in5_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON6);
+static SENSOR_DEVICE_ATTR(in6_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON7);
+static SENSOR_DEVICE_ATTR(in7_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON8);
+static SENSOR_DEVICE_ATTR(in8_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON9);
+static SENSOR_DEVICE_ATTR(in9_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON10);
+static SENSOR_DEVICE_ATTR(in10_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON11);
+static SENSOR_DEVICE_ATTR(in11_highest, S_IRUGO, powr1220_show_max, NULL,
+ VMON12);
+static SENSOR_DEVICE_ATTR(in12_highest, S_IRUGO, powr1220_show_max, NULL,
+ VCCA);
+static SENSOR_DEVICE_ATTR(in13_highest, S_IRUGO, powr1220_show_max, NULL,
+ VCCINP);
+
+static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON1);
+static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON2);
+static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON3);
+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON4);
+static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON5);
+static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON6);
+static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON7);
+static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON8);
+static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON9);
+static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON10);
+static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON11);
+static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, powr1220_show_label, NULL,
+ VMON12);
+static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, powr1220_show_label, NULL,
+ VCCA);
+static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, powr1220_show_label, NULL,
+ VCCINP);
+
+static struct attribute *powr1220_attrs[] = {
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in3_input.dev_attr.attr,
+ &sensor_dev_attr_in4_input.dev_attr.attr,
+ &sensor_dev_attr_in5_input.dev_attr.attr,
+ &sensor_dev_attr_in6_input.dev_attr.attr,
+ &sensor_dev_attr_in7_input.dev_attr.attr,
+ &sensor_dev_attr_in8_input.dev_attr.attr,
+ &sensor_dev_attr_in9_input.dev_attr.attr,
+ &sensor_dev_attr_in10_input.dev_attr.attr,
+ &sensor_dev_attr_in11_input.dev_attr.attr,
+ &sensor_dev_attr_in12_input.dev_attr.attr,
+ &sensor_dev_attr_in13_input.dev_attr.attr,
+
+ &sensor_dev_attr_in0_highest.dev_attr.attr,
+ &sensor_dev_attr_in1_highest.dev_attr.attr,
+ &sensor_dev_attr_in2_highest.dev_attr.attr,
+ &sensor_dev_attr_in3_highest.dev_attr.attr,
+ &sensor_dev_attr_in4_highest.dev_attr.attr,
+ &sensor_dev_attr_in5_highest.dev_attr.attr,
+ &sensor_dev_attr_in6_highest.dev_attr.attr,
+ &sensor_dev_attr_in7_highest.dev_attr.attr,
+ &sensor_dev_attr_in8_highest.dev_attr.attr,
+ &sensor_dev_attr_in9_highest.dev_attr.attr,
+ &sensor_dev_attr_in10_highest.dev_attr.attr,
+ &sensor_dev_attr_in11_highest.dev_attr.attr,
+ &sensor_dev_attr_in12_highest.dev_attr.attr,
+ &sensor_dev_attr_in13_highest.dev_attr.attr,
+
+ &sensor_dev_attr_in0_label.dev_attr.attr,
+ &sensor_dev_attr_in1_label.dev_attr.attr,
+ &sensor_dev_attr_in2_label.dev_attr.attr,
+ &sensor_dev_attr_in3_label.dev_attr.attr,
+ &sensor_dev_attr_in4_label.dev_attr.attr,
+ &sensor_dev_attr_in5_label.dev_attr.attr,
+ &sensor_dev_attr_in6_label.dev_attr.attr,
+ &sensor_dev_attr_in7_label.dev_attr.attr,
+ &sensor_dev_attr_in8_label.dev_attr.attr,
+ &sensor_dev_attr_in9_label.dev_attr.attr,
+ &sensor_dev_attr_in10_label.dev_attr.attr,
+ &sensor_dev_attr_in11_label.dev_attr.attr,
+ &sensor_dev_attr_in12_label.dev_attr.attr,
+ &sensor_dev_attr_in13_label.dev_attr.attr,
+
+ NULL
+};
+
+ATTRIBUTE_GROUPS(powr1220);
+
+static int powr1220_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct powr1220_data *data;
+ struct device *hwmon_dev;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ mutex_init(&data->update_lock);
+ data->client = client;
+
+ hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+ client->name, data, powr1220_groups);
+
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id powr1220_ids[] = {
+ { "powr1220", 0, },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, powr1220_ids);
+
+static struct i2c_driver powr1220_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "powr1220",
+ },
+ .probe = powr1220_probe,
+ .id_table = powr1220_ids,
+};
+
+module_i2c_driver(powr1220_driver);
+
+MODULE_AUTHOR("Scott Kanowitz");
+MODULE_DESCRIPTION("POWR1220 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c
new file mode 100644
index 000000000000..823c877a1ec0
--- /dev/null
+++ b/drivers/hwmon/pwm-fan.c
@@ -0,0 +1,193 @@
+/*
+ * pwm-fan.c - Hwmon driver for fans connected to PWM lines.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Author: Kamil Debski <k.debski@samsung.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/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/sysfs.h>
+
+#define MAX_PWM 255
+
+struct pwm_fan_ctx {
+ struct mutex lock;
+ struct pwm_device *pwm;
+ unsigned char pwm_value;
+};
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+ unsigned long pwm, duty;
+ ssize_t ret;
+
+ if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM)
+ return -EINVAL;
+
+ mutex_lock(&ctx->lock);
+
+ if (ctx->pwm_value == pwm)
+ goto exit_set_pwm_no_change;
+
+ if (pwm == 0) {
+ pwm_disable(ctx->pwm);
+ goto exit_set_pwm;
+ }
+
+ duty = DIV_ROUND_UP(pwm * (ctx->pwm->period - 1), MAX_PWM);
+ ret = pwm_config(ctx->pwm, duty, ctx->pwm->period);
+ if (ret)
+ goto exit_set_pwm_err;
+
+ if (ctx->pwm_value == 0) {
+ ret = pwm_enable(ctx->pwm);
+ if (ret)
+ goto exit_set_pwm_err;
+ }
+
+exit_set_pwm:
+ ctx->pwm_value = pwm;
+exit_set_pwm_no_change:
+ ret = count;
+exit_set_pwm_err:
+ mutex_unlock(&ctx->lock);
+ return ret;
+}
+
+static ssize_t show_pwm(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", ctx->pwm_value);
+}
+
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
+
+static struct attribute *pwm_fan_attrs[] = {
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(pwm_fan);
+
+static int pwm_fan_probe(struct platform_device *pdev)
+{
+ struct device *hwmon;
+ struct pwm_fan_ctx *ctx;
+ int duty_cycle;
+ int ret;
+
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ mutex_init(&ctx->lock);
+
+ ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL);
+ if (IS_ERR(ctx->pwm)) {
+ dev_err(&pdev->dev, "Could not get PWM\n");
+ return PTR_ERR(ctx->pwm);
+ }
+
+ platform_set_drvdata(pdev, ctx);
+
+ /* Set duty cycle to maximum allowed */
+ duty_cycle = ctx->pwm->period - 1;
+ ctx->pwm_value = MAX_PWM;
+
+ ret = pwm_config(ctx->pwm, duty_cycle, ctx->pwm->period);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to configure PWM\n");
+ return ret;
+ }
+
+ /* Enbale PWM output */
+ ret = pwm_enable(ctx->pwm);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable PWM\n");
+ return ret;
+ }
+
+ hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan",
+ ctx, pwm_fan_groups);
+ if (IS_ERR(hwmon)) {
+ dev_err(&pdev->dev, "Failed to register hwmon device\n");
+ pwm_disable(ctx->pwm);
+ return PTR_ERR(hwmon);
+ }
+ return 0;
+}
+
+static int pwm_fan_remove(struct platform_device *pdev)
+{
+ struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
+
+ if (ctx->pwm_value)
+ pwm_disable(ctx->pwm);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_fan_suspend(struct device *dev)
+{
+ struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+ if (ctx->pwm_value)
+ pwm_disable(ctx->pwm);
+ return 0;
+}
+
+static int pwm_fan_resume(struct device *dev)
+{
+ struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+ if (ctx->pwm_value)
+ return pwm_enable(ctx->pwm);
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pwm_fan_pm, pwm_fan_suspend, pwm_fan_resume);
+
+static struct of_device_id of_pwm_fan_match[] = {
+ { .compatible = "pwm-fan", },
+ {},
+};
+
+static struct platform_driver pwm_fan_driver = {
+ .probe = pwm_fan_probe,
+ .remove = pwm_fan_remove,
+ .driver = {
+ .name = "pwm-fan",
+ .pm = &pwm_fan_pm,
+ .of_match_table = of_pwm_fan_match,
+ },
+};
+
+module_platform_driver(pwm_fan_driver);
+
+MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
+MODULE_ALIAS("platform:pwm-fan");
+MODULE_DESCRIPTION("PWM FAN driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 2e9f9570b6f8..84cdb1cf0fb4 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -45,7 +45,7 @@
* @humidity: cached humidity measurement value
*/
struct sht21 {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex lock;
char valid;
unsigned long last_update;
@@ -85,14 +85,15 @@ static inline int sht21_rh_ticks_to_per_cent_mille(int ticks)
/**
* sht21_update_measurements() - get updated measurements from device
- * @client: I2C client device
+ * @dev: device
*
* Returns 0 on success, else negative errno.
*/
-static int sht21_update_measurements(struct i2c_client *client)
+static int sht21_update_measurements(struct device *dev)
{
int ret = 0;
- struct sht21 *sht21 = i2c_get_clientdata(client);
+ struct sht21 *sht21 = dev_get_drvdata(dev);
+ struct i2c_client *client = sht21->client;
mutex_lock(&sht21->lock);
/*
@@ -133,9 +134,10 @@ static ssize_t sht21_show_temperature(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct sht21 *sht21 = i2c_get_clientdata(client);
- int ret = sht21_update_measurements(client);
+ struct sht21 *sht21 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = sht21_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", sht21->temperature);
@@ -154,9 +156,10 @@ static ssize_t sht21_show_humidity(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct sht21 *sht21 = i2c_get_clientdata(client);
- int ret = sht21_update_measurements(client);
+ struct sht21 *sht21 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = sht21_update_measurements(dev);
if (ret < 0)
return ret;
return sprintf(buf, "%d\n", sht21->humidity);
@@ -168,30 +171,20 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature,
static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity,
NULL, 0);
-static struct attribute *sht21_attributes[] = {
+static struct attribute *sht21_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_humidity1_input.dev_attr.attr,
NULL
};
-static const struct attribute_group sht21_attr_group = {
- .attrs = sht21_attributes,
-};
+ATTRIBUTE_GROUPS(sht21);
-/**
- * sht21_probe() - probe device
- * @client: I2C client device
- * @id: device ID
- *
- * Called by the I2C core when an entry in the ID table matches a
- * device's name.
- * Returns 0 on success.
- */
static int sht21_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct sht21 *sht21;
- int err;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -200,47 +193,17 @@ static int sht21_probe(struct i2c_client *client,
return -ENODEV;
}
- sht21 = devm_kzalloc(&client->dev, sizeof(*sht21), GFP_KERNEL);
+ sht21 = devm_kzalloc(dev, sizeof(*sht21), GFP_KERNEL);
if (!sht21)
return -ENOMEM;
- i2c_set_clientdata(client, sht21);
+ sht21->client = client;
mutex_init(&sht21->lock);
- err = sysfs_create_group(&client->dev.kobj, &sht21_attr_group);
- if (err) {
- dev_dbg(&client->dev, "could not create sysfs files\n");
- return err;
- }
- sht21->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(sht21->hwmon_dev)) {
- dev_dbg(&client->dev, "unable to register hwmon device\n");
- err = PTR_ERR(sht21->hwmon_dev);
- goto fail_remove_sysfs;
- }
-
- dev_info(&client->dev, "initialized\n");
-
- return 0;
-
-fail_remove_sysfs:
- sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
- return err;
-}
-
-/**
- * sht21_remove() - remove device
- * @client: I2C client device
- */
-static int sht21_remove(struct i2c_client *client)
-{
- struct sht21 *sht21 = i2c_get_clientdata(client);
-
- hwmon_device_unregister(sht21->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ sht21, sht21_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
/* Device ID table */
@@ -253,7 +216,6 @@ MODULE_DEVICE_TABLE(i2c, sht21_id);
static struct i2c_driver sht21_driver = {
.driver.name = "sht21",
.probe = sht21_probe,
- .remove = sht21_remove,
.id_table = sht21_id,
};
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 3532026e25da..bf1d7893d51c 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -159,7 +159,7 @@ static inline int TEMP_FROM_REG(s8 val)
{
return val * 830 + 52120;
}
-static inline s8 TEMP_TO_REG(int val)
+static inline s8 TEMP_TO_REG(long val)
{
int nval = clamp_val(val, -54120, 157530) ;
return nval < 0 ? (nval - 5212 - 415) / 830 : (nval - 5212 + 415) / 830;
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c
index 4ef5802df6d8..627c9c3a8255 100644
--- a/drivers/hwmon/smm665.c
+++ b/drivers/hwmon/smm665.c
@@ -140,7 +140,7 @@ enum chips { smm465, smm665, smm665c, smm764, smm766 };
struct smm665_data {
enum chips type;
int conversion_time; /* ADC conversion time */
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
bool valid;
unsigned long last_updated; /* in jiffies */
@@ -239,8 +239,8 @@ static int smm665_read_adc(struct smm665_data *data, int adc)
static struct smm665_data *smm665_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smm665_data *data = i2c_get_clientdata(client);
+ struct smm665_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
struct smm665_data *ret = data;
mutex_lock(&data->update_lock);
@@ -315,32 +315,28 @@ static int smm665_convert(u16 adcval, int index)
static int smm665_get_min(struct device *dev, int index)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smm665_data *data = i2c_get_clientdata(client);
+ struct smm665_data *data = dev_get_drvdata(dev);
return data->alarm_min_limit[index];
}
static int smm665_get_max(struct device *dev, int index)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smm665_data *data = i2c_get_clientdata(client);
+ struct smm665_data *data = dev_get_drvdata(dev);
return data->alarm_max_limit[index];
}
static int smm665_get_lcrit(struct device *dev, int index)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smm665_data *data = i2c_get_clientdata(client);
+ struct smm665_data *data = dev_get_drvdata(dev);
return data->critical_min_limit[index];
}
static int smm665_get_crit(struct device *dev, int index)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smm665_data *data = i2c_get_clientdata(client);
+ struct smm665_data *data = dev_get_drvdata(dev);
return data->critical_max_limit[index];
}
@@ -486,7 +482,7 @@ SMM665_ATTR(temp1, crit_alarm, SMM665_FAULT_TEMP);
* Finally, construct an array of pointers to members of the above objects,
* as required for sysfs_create_group()
*/
-static struct attribute *smm665_attributes[] = {
+static struct attribute *smm665_attrs[] = {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
&sensor_dev_attr_in1_max.dev_attr.attr,
@@ -567,15 +563,14 @@ static struct attribute *smm665_attributes[] = {
NULL,
};
-static const struct attribute_group smm665_group = {
- .attrs = smm665_attributes,
-};
+ATTRIBUTE_GROUPS(smm665);
static int smm665_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct smm665_data *data;
+ struct device *hwmon_dev;
int i, ret;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
@@ -592,6 +587,7 @@ static int smm665_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
+ data->client = client;
data->type = id->driver_data;
data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK)
| SMM665_CMDREG_BASE);
@@ -662,21 +658,16 @@ static int smm665_probe(struct i2c_client *client,
data->alarm_max_limit[i] = smm665_convert(val, i);
}
- /* Register sysfs hooks */
- ret = sysfs_create_group(&client->dev.kobj, &smm665_group);
- if (ret)
+ hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+ client->name, data,
+ smm665_groups);
+ if (IS_ERR(hwmon_dev)) {
+ ret = PTR_ERR(hwmon_dev);
goto out_unregister;
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- ret = PTR_ERR(data->hwmon_dev);
- goto out_remove_group;
}
return 0;
-out_remove_group:
- sysfs_remove_group(&client->dev.kobj, &smm665_group);
out_unregister:
i2c_unregister_device(data->cmdreg);
return ret;
@@ -687,9 +678,6 @@ static int smm665_remove(struct i2c_client *client)
struct smm665_data *data = i2c_get_clientdata(client);
i2c_unregister_device(data->cmdreg);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &smm665_group);
-
return 0;
}
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 23a22c4eee51..d7485659acc5 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -142,11 +142,6 @@ struct smsc47m1_sio_data {
u8 activate; /* Remember initial device state */
};
-
-static int __exit smsc47m1_remove(struct platform_device *pdev);
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
- int init);
-
static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
{
return inb_p(data->addr + reg);
@@ -158,13 +153,54 @@ static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
outb_p(value, data->addr + reg);
}
-static struct platform_driver smsc47m1_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = DRVNAME,
- },
- .remove = __exit_p(smsc47m1_remove),
-};
+static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
+ int init)
+{
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
+ int i, fan_nr;
+ fan_nr = data->type == smsc47m2 ? 3 : 2;
+
+ for (i = 0; i < fan_nr; i++) {
+ data->fan[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_FAN[i]);
+ data->fan_preload[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_FAN_PRELOAD[i]);
+ data->pwm[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_PWM[i]);
+ }
+
+ i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
+ data->fan_div[0] = (i >> 4) & 0x03;
+ data->fan_div[1] = i >> 6;
+
+ data->alarms = smsc47m1_read_value(data,
+ SMSC47M1_REG_ALARM) >> 6;
+ /* Clear alarms if needed */
+ if (data->alarms)
+ smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
+
+ if (fan_nr >= 3) {
+ data->fan_div[2] = (smsc47m1_read_value(data,
+ SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
+ data->alarms |= (smsc47m1_read_value(data,
+ SMSC47M2_REG_ALARM6) & 0x40) >> 4;
+ /* Clear alarm if needed */
+ if (data->alarms & 0x04)
+ smsc47m1_write_value(data,
+ SMSC47M2_REG_ALARM6,
+ 0x40);
+ }
+
+ data->last_updated = jiffies;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return data;
+}
static ssize_t get_fan(struct device *dev, struct device_attribute
*devattr, char *buf)
@@ -811,54 +847,13 @@ static int __exit smsc47m1_remove(struct platform_device *pdev)
return 0;
}
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
- int init)
-{
- struct smsc47m1_data *data = dev_get_drvdata(dev);
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
- int i, fan_nr;
- fan_nr = data->type == smsc47m2 ? 3 : 2;
-
- for (i = 0; i < fan_nr; i++) {
- data->fan[i] = smsc47m1_read_value(data,
- SMSC47M1_REG_FAN[i]);
- data->fan_preload[i] = smsc47m1_read_value(data,
- SMSC47M1_REG_FAN_PRELOAD[i]);
- data->pwm[i] = smsc47m1_read_value(data,
- SMSC47M1_REG_PWM[i]);
- }
-
- i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = i >> 6;
-
- data->alarms = smsc47m1_read_value(data,
- SMSC47M1_REG_ALARM) >> 6;
- /* Clear alarms if needed */
- if (data->alarms)
- smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
-
- if (fan_nr >= 3) {
- data->fan_div[2] = (smsc47m1_read_value(data,
- SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
- data->alarms |= (smsc47m1_read_value(data,
- SMSC47M2_REG_ALARM6) & 0x40) >> 4;
- /* Clear alarm if needed */
- if (data->alarms & 0x04)
- smsc47m1_write_value(data,
- SMSC47M2_REG_ALARM6,
- 0x40);
- }
-
- data->last_updated = jiffies;
- }
-
- mutex_unlock(&data->update_lock);
- return data;
-}
+static struct platform_driver smsc47m1_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRVNAME,
+ },
+ .remove = __exit_p(smsc47m1_remove),
+};
static int __init smsc47m1_device_add(unsigned short address,
const struct smsc47m1_sio_data *sio_data)
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index efee4c59239f..6ac7cda72d4c 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -86,7 +86,7 @@ static inline u8 IN_TO_REG(unsigned long val, int n)
*/
static inline s8 TEMP_TO_REG(int val)
{
- return clamp_val(SCALE(val, 1, 1000), -128000, 127000);
+ return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
}
static inline int TEMP_FROM_REG(s8 val)
@@ -95,7 +95,8 @@ static inline int TEMP_FROM_REG(s8 val)
}
struct smsc47m192_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -112,30 +113,69 @@ struct smsc47m192_data {
u8 vrm;
};
-static int smsc47m192_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int smsc47m192_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int smsc47m192_remove(struct i2c_client *client);
-static struct smsc47m192_data *smsc47m192_update_device(struct device *dev);
+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
+{
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int i, config;
-static const struct i2c_device_id smsc47m192_id[] = {
- { "smsc47m192", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
+ mutex_lock(&data->update_lock);
-static struct i2c_driver smsc47m192_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "smsc47m192",
- },
- .probe = smsc47m192_probe,
- .remove = smsc47m192_remove,
- .id_table = smsc47m192_id,
- .detect = smsc47m192_detect,
- .address_list = normal_i2c,
-};
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
+
+ dev_dbg(&client->dev, "Starting smsc47m192 update\n");
+
+ for (i = 0; i <= 7; i++) {
+ data->in[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_IN(i));
+ data->in_min[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_IN_MIN(i));
+ data->in_max[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_IN_MAX(i));
+ }
+ for (i = 0; i < 3; i++) {
+ data->temp[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_TEMP[i]);
+ data->temp_max[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_TEMP_MAX[i]);
+ data->temp_min[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_TEMP_MIN[i]);
+ }
+ for (i = 1; i < 3; i++)
+ data->temp_offset[i] = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_TEMP_OFFSET(i));
+ /*
+ * first offset is temp_offset[0] if SFR bit 4 is set,
+ * temp_offset[1] otherwise
+ */
+ if (sfr & 0x10) {
+ data->temp_offset[0] = data->temp_offset[1];
+ data->temp_offset[1] = 0;
+ } else
+ data->temp_offset[0] = 0;
+
+ data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
+ & 0x0f;
+ config = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_CONFIG);
+ if (config & 0x20)
+ data->vid |= (i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_VID4) & 0x01) << 4;
+ data->alarms = i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_ALARM1) |
+ (i2c_smbus_read_byte_data(client,
+ SMSC47M192_REG_ALARM2) << 8);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
/* Voltages */
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
@@ -170,8 +210,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -192,8 +232,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -259,8 +299,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -281,8 +321,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -312,8 +352,8 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute
{
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
+ struct smsc47m192_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
long val;
int err;
@@ -384,6 +424,8 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
err = kstrtoul(buf, 10, &val);
if (err)
return err;
+ if (val > 255)
+ return -EINVAL;
data->vrm = val;
return count;
@@ -550,124 +592,50 @@ static int smsc47m192_detect(struct i2c_client *client,
static int smsc47m192_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
struct smsc47m192_data *data;
int config;
- int err;
- data = devm_kzalloc(&client->dev, sizeof(struct smsc47m192_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct smsc47m192_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
data->vrm = vid_which_vrm();
mutex_init(&data->update_lock);
/* Initialize the SMSC47M192 chip */
smsc47m192_init_client(client);
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group);
- if (err)
- return err;
-
+ /* sysfs hooks */
+ data->groups[0] = &smsc47m192_group;
/* Pin 110 is either in4 (+12V) or VID4 */
config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
- if (!(config & 0x20)) {
- err = sysfs_create_group(&client->dev.kobj,
- &smsc47m192_group_in4);
- if (err)
- goto exit_remove_files;
- }
-
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
-
-exit_remove_files:
- sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
- sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
- return err;
-}
-
-static int smsc47m192_remove(struct i2c_client *client)
-{
- struct smsc47m192_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
- sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
+ if (!(config & 0x20))
+ data->groups[1] = &smsc47m192_group_in4;
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m192_data *data = i2c_get_clientdata(client);
- int i, config;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
-
- dev_dbg(&client->dev, "Starting smsc47m192 update\n");
-
- for (i = 0; i <= 7; i++) {
- data->in[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_IN(i));
- data->in_min[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_IN_MIN(i));
- data->in_max[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_IN_MAX(i));
- }
- for (i = 0; i < 3; i++) {
- data->temp[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_TEMP[i]);
- data->temp_max[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_TEMP_MAX[i]);
- data->temp_min[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_TEMP_MIN[i]);
- }
- for (i = 1; i < 3; i++)
- data->temp_offset[i] = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_TEMP_OFFSET(i));
- /*
- * first offset is temp_offset[0] if SFR bit 4 is set,
- * temp_offset[1] otherwise
- */
- if (sfr & 0x10) {
- data->temp_offset[0] = data->temp_offset[1];
- data->temp_offset[1] = 0;
- } else
- data->temp_offset[0] = 0;
-
- data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
- & 0x0f;
- config = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_CONFIG);
- if (config & 0x20)
- data->vid |= (i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_VID4) & 0x01) << 4;
- data->alarms = i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_ALARM1) |
- (i2c_smbus_read_byte_data(client,
- SMSC47M192_REG_ALARM2) << 8);
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id smsc47m192_id[] = {
+ { "smsc47m192", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
- return data;
-}
+static struct i2c_driver smsc47m192_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "smsc47m192",
+ },
+ .probe = smsc47m192_probe,
+ .id_table = smsc47m192_id,
+ .detect = smsc47m192_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(smsc47m192_driver);
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index db288db7d3e9..6a0ee903127e 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -68,7 +68,8 @@ static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 };
/* Each client has this additional data */
struct thmc50_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
+ const struct attribute_group *groups[3];
struct mutex update_lock;
enum chips type;
@@ -85,32 +86,47 @@ struct thmc50_data {
u8 alarms;
};
-static int thmc50_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int thmc50_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int thmc50_remove(struct i2c_client *client);
-static void thmc50_init_client(struct i2c_client *client);
-static struct thmc50_data *thmc50_update_device(struct device *dev);
+static struct thmc50_data *thmc50_update_device(struct device *dev)
+{
+ struct thmc50_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
-static const struct i2c_device_id thmc50_id[] = {
- { "adm1022", adm1022 },
- { "thmc50", thmc50 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, thmc50_id);
+ mutex_lock(&data->update_lock);
-static struct i2c_driver thmc50_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "thmc50",
- },
- .probe = thmc50_probe,
- .remove = thmc50_remove,
- .id_table = thmc50_id,
- .detect = thmc50_detect,
- .address_list = normal_i2c,
-};
+ if (time_after(jiffies, data->last_updated + timeout)
+ || !data->valid) {
+
+ int temps = data->has_temp3 ? 3 : 2;
+ int i;
+ int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+
+ prog &= THMC50_REG_CONF_PROGRAMMED;
+
+ for (i = 0; i < temps; i++) {
+ data->temp_input[i] = i2c_smbus_read_byte_data(client,
+ THMC50_REG_TEMP[i]);
+ data->temp_max[i] = i2c_smbus_read_byte_data(client,
+ THMC50_REG_TEMP_MAX[i]);
+ data->temp_min[i] = i2c_smbus_read_byte_data(client,
+ THMC50_REG_TEMP_MIN[i]);
+ data->temp_critical[i] =
+ i2c_smbus_read_byte_data(client,
+ prog ? THMC50_REG_TEMP_CRITICAL[i]
+ : THMC50_REG_TEMP_DEFAULT[i]);
+ }
+ data->analog_out =
+ i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
+ data->alarms =
+ i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
static ssize_t show_analog_out(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -123,8 +139,8 @@ static ssize_t set_analog_out(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct thmc50_data *data = i2c_get_clientdata(client);
+ struct thmc50_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
int config;
unsigned long tmp;
int err;
@@ -177,8 +193,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct thmc50_data *data = i2c_get_clientdata(client);
+ struct thmc50_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -206,8 +222,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct thmc50_data *data = i2c_get_clientdata(client);
+ struct thmc50_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -355,67 +371,9 @@ static int thmc50_detect(struct i2c_client *client,
return 0;
}
-static int thmc50_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct thmc50_data *data;
- int err;
-
- data = devm_kzalloc(&client->dev, sizeof(struct thmc50_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- i2c_set_clientdata(client, data);
- data->type = id->driver_data;
- mutex_init(&data->update_lock);
-
- thmc50_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &thmc50_group);
- if (err)
- return err;
-
- /* Register ADM1022 sysfs hooks */
- if (data->has_temp3) {
- err = sysfs_create_group(&client->dev.kobj, &temp3_group);
- if (err)
- goto exit_remove_sysfs_thmc50;
- }
-
- /* Register a new directory entry with module sensors */
- data->hwmon_dev = hwmon_device_register(&client->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_sysfs;
- }
-
- return 0;
-
-exit_remove_sysfs:
- if (data->has_temp3)
- sysfs_remove_group(&client->dev.kobj, &temp3_group);
-exit_remove_sysfs_thmc50:
- sysfs_remove_group(&client->dev.kobj, &thmc50_group);
- return err;
-}
-
-static int thmc50_remove(struct i2c_client *client)
+static void thmc50_init_client(struct thmc50_data *data)
{
- struct thmc50_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &thmc50_group);
- if (data->has_temp3)
- sysfs_remove_group(&client->dev.kobj, &temp3_group);
-
- return 0;
-}
-
-static void thmc50_init_client(struct i2c_client *client)
-{
- struct thmc50_data *data = i2c_get_clientdata(client);
+ struct i2c_client *client = data->client;
int config;
data->analog_out = i2c_smbus_read_byte_data(client,
@@ -433,48 +391,54 @@ static void thmc50_init_client(struct i2c_client *client)
i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
}
-static struct thmc50_data *thmc50_update_device(struct device *dev)
+static int thmc50_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct thmc50_data *data = i2c_get_clientdata(client);
- int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
+ struct device *dev = &client->dev;
+ struct thmc50_data *data;
+ struct device *hwmon_dev;
+ int idx = 0;
- mutex_lock(&data->update_lock);
+ data = devm_kzalloc(dev, sizeof(struct thmc50_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- if (time_after(jiffies, data->last_updated + timeout)
- || !data->valid) {
+ data->client = client;
+ data->type = id->driver_data;
+ mutex_init(&data->update_lock);
- int temps = data->has_temp3 ? 3 : 2;
- int i;
- int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+ thmc50_init_client(data);
- prog &= THMC50_REG_CONF_PROGRAMMED;
+ /* sysfs hooks */
+ data->groups[idx++] = &thmc50_group;
- for (i = 0; i < temps; i++) {
- data->temp_input[i] = i2c_smbus_read_byte_data(client,
- THMC50_REG_TEMP[i]);
- data->temp_max[i] = i2c_smbus_read_byte_data(client,
- THMC50_REG_TEMP_MAX[i]);
- data->temp_min[i] = i2c_smbus_read_byte_data(client,
- THMC50_REG_TEMP_MIN[i]);
- data->temp_critical[i] =
- i2c_smbus_read_byte_data(client,
- prog ? THMC50_REG_TEMP_CRITICAL[i]
- : THMC50_REG_TEMP_DEFAULT[i]);
- }
- data->analog_out =
- i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
- data->alarms =
- i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
+ /* Register additional ADM1022 sysfs hooks */
+ if (data->has_temp3)
+ data->groups[idx++] = &temp3_group;
- return data;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data, data->groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
+static const struct i2c_device_id thmc50_id[] = {
+ { "adm1022", adm1022 },
+ { "thmc50", thmc50 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, thmc50_id);
+
+static struct i2c_driver thmc50_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "thmc50",
+ },
+ .probe = thmc50_probe,
+ .id_table = thmc50_id,
+ .detect = thmc50_detect,
+ .address_list = normal_i2c,
+};
+
module_i2c_driver(thmc50_driver);
MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
diff --git a/drivers/hwmon/tmp103.c b/drivers/hwmon/tmp103.c
new file mode 100644
index 000000000000..c74d2da389d9
--- /dev/null
+++ b/drivers/hwmon/tmp103.c
@@ -0,0 +1,206 @@
+/*
+ * Texas Instruments TMP103 SMBus temperature sensor driver
+ * Copyright (C) 2014 Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * Texas Instruments TMP102 SMBus temperature sensor driver
+ *
+ * Copyright (C) 2010 Steven King <sfking@fdwdc.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/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/regmap.h>
+
+#define TMP103_TEMP_REG 0x00
+#define TMP103_CONF_REG 0x01
+#define TMP103_TLOW_REG 0x02
+#define TMP103_THIGH_REG 0x03
+
+#define TMP103_CONF_M0 0x01
+#define TMP103_CONF_M1 0x02
+#define TMP103_CONF_LC 0x04
+#define TMP103_CONF_FL 0x08
+#define TMP103_CONF_FH 0x10
+#define TMP103_CONF_CR0 0x20
+#define TMP103_CONF_CR1 0x40
+#define TMP103_CONF_ID 0x80
+#define TMP103_CONF_SD (TMP103_CONF_M1)
+#define TMP103_CONF_SD_MASK (TMP103_CONF_M0 | TMP103_CONF_M1)
+
+#define TMP103_CONFIG (TMP103_CONF_CR1 | TMP103_CONF_M1)
+#define TMP103_CONFIG_MASK (TMP103_CONF_CR0 | TMP103_CONF_CR1 | \
+ TMP103_CONF_M0 | TMP103_CONF_M1)
+
+static inline int tmp103_reg_to_mc(s8 val)
+{
+ return val * 1000;
+}
+
+static inline u8 tmp103_mc_to_reg(int val)
+{
+ return DIV_ROUND_CLOSEST(val, 1000);
+}
+
+static ssize_t tmp103_show_temp(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+ struct regmap *regmap = dev_get_drvdata(dev);
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_read(regmap, sda->index, &regval);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%d\n", tmp103_reg_to_mc(regval));
+}
+
+static ssize_t tmp103_set_temp(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+ struct regmap *regmap = dev_get_drvdata(dev);
+ long val;
+ int ret;
+
+ if (kstrtol(buf, 10, &val) < 0)
+ return -EINVAL;
+
+ val = clamp_val(val, -55000, 127000);
+ ret = regmap_write(regmap, sda->index, tmp103_mc_to_reg(val));
+ return ret ? ret : count;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp103_show_temp, NULL ,
+ TMP103_TEMP_REG);
+
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, tmp103_show_temp,
+ tmp103_set_temp, TMP103_TLOW_REG);
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp103_show_temp,
+ tmp103_set_temp, TMP103_THIGH_REG);
+
+static struct attribute *tmp103_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_min.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(tmp103);
+
+static bool tmp103_regmap_is_volatile(struct device *dev, unsigned int reg)
+{
+ return reg == TMP103_TEMP_REG;
+}
+
+static const struct regmap_config tmp103_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = TMP103_THIGH_REG,
+ .volatile_reg = tmp103_regmap_is_volatile,
+};
+
+static int tmp103_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct device *hwmon_dev;
+ struct regmap *regmap;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(&client->dev,
+ "adapter doesn't support SMBus byte transactions\n");
+ return -ENODEV;
+ }
+
+ regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "failed to allocate register map\n");
+ return PTR_ERR(regmap);
+ }
+
+ ret = regmap_update_bits(regmap, TMP103_CONF_REG, TMP103_CONFIG_MASK,
+ TMP103_CONFIG);
+ if (ret < 0) {
+ dev_err(&client->dev, "error writing config register\n");
+ return ret;
+ }
+
+ i2c_set_clientdata(client, regmap);
+ hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
+ regmap, tmp103_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+#ifdef CONFIG_PM
+static int tmp103_suspend(struct device *dev)
+{
+ struct regmap *regmap = dev_get_drvdata(dev);
+
+ return regmap_update_bits(regmap, TMP103_CONF_REG,
+ TMP103_CONF_SD_MASK, 0);
+}
+
+static int tmp103_resume(struct device *dev)
+{
+ struct regmap *regmap = dev_get_drvdata(dev);
+
+ return regmap_update_bits(regmap, TMP103_CONF_REG,
+ TMP103_CONF_SD_MASK, TMP103_CONF_SD);
+}
+
+static const struct dev_pm_ops tmp103_dev_pm_ops = {
+ .suspend = tmp103_suspend,
+ .resume = tmp103_resume,
+};
+
+#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
+#else
+#define TMP103_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tmp103_id[] = {
+ { "tmp103", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tmp103_id);
+
+static struct i2c_driver tmp103_driver = {
+ .driver = {
+ .name = "tmp103",
+ .pm = TMP103_DEV_PM_OPS,
+ },
+ .probe = tmp103_probe,
+ .id_table = tmp103_id,
+};
+
+module_i2c_driver(tmp103_driver);
+
+MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 7bab7a9bedc6..85d48d80822a 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -13,15 +13,11 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
- * Supported models: TMP421, TMP422, TMP423
+ * Supported models: TMP421, TMP422, TMP423, TMP441, TMP442
*/
#include <linux/module.h>
@@ -39,9 +35,10 @@
static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
I2C_CLIENT_END };
-enum chips { tmp421, tmp422, tmp423 };
+enum chips { tmp421, tmp422, tmp423, tmp441, tmp442 };
/* The TMP421 registers */
+#define TMP421_STATUS_REG 0x08
#define TMP421_CONFIG_REG_1 0x09
#define TMP421_CONVERSION_RATE_REG 0x0B
#define TMP421_MANUFACTURER_ID_REG 0xFE
@@ -59,11 +56,15 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
#define TMP421_DEVICE_ID 0x21
#define TMP422_DEVICE_ID 0x22
#define TMP423_DEVICE_ID 0x23
+#define TMP441_DEVICE_ID 0x41
+#define TMP442_DEVICE_ID 0x42
static const struct i2c_device_id tmp421_id[] = {
{ "tmp421", 2 },
{ "tmp422", 3 },
{ "tmp423", 4 },
+ { "tmp441", 2 },
+ { "tmp442", 3 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -234,7 +235,9 @@ static int tmp421_detect(struct i2c_client *client,
{
enum chips kind;
struct i2c_adapter *adapter = client->adapter;
- const char *names[] = { "TMP421", "TMP422", "TMP423" };
+ const char * const names[] = { "TMP421", "TMP422", "TMP423",
+ "TMP441", "TMP442" };
+ int addr = client->addr;
u8 reg;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -244,17 +247,37 @@ static int tmp421_detect(struct i2c_client *client,
if (reg != TMP421_MANUFACTURER_ID)
return -ENODEV;
+ reg = i2c_smbus_read_byte_data(client, TMP421_CONVERSION_RATE_REG);
+ if (reg & 0xf8)
+ return -ENODEV;
+
+ reg = i2c_smbus_read_byte_data(client, TMP421_STATUS_REG);
+ if (reg & 0x7f)
+ return -ENODEV;
+
reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
switch (reg) {
case TMP421_DEVICE_ID:
kind = tmp421;
break;
case TMP422_DEVICE_ID:
+ if (addr == 0x2a)
+ return -ENODEV;
kind = tmp422;
break;
case TMP423_DEVICE_ID:
+ if (addr != 0x4c && addr != 0x4d)
+ return -ENODEV;
kind = tmp423;
break;
+ case TMP441_DEVICE_ID:
+ kind = tmp441;
+ break;
+ case TMP442_DEVICE_ID:
+ if (addr != 0x4c && addr != 0x4d)
+ return -ENODEV;
+ kind = tmp442;
+ break;
default:
return -ENODEV;
}
@@ -305,5 +328,5 @@ static struct i2c_driver tmp421_driver = {
module_i2c_driver(tmp421_driver);
MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
-MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor driver");
+MODULE_DESCRIPTION("Texas Instruments TMP421/422/423/441/442 temperature sensor driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c
index 6c6d440bb2dd..9a0e2b8e8b94 100644
--- a/drivers/hwmon/twl4030-madc-hwmon.c
+++ b/drivers/hwmon/twl4030-madc-hwmon.c
@@ -74,7 +74,7 @@ static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11);
static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
-static struct attribute *twl4030_madc_attributes[] = {
+static struct attribute *twl4030_madc_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -91,46 +91,20 @@ static struct attribute *twl4030_madc_attributes[] = {
&sensor_dev_attr_in15_input.dev_attr.attr,
NULL
};
-
-static const struct attribute_group twl4030_madc_group = {
- .attrs = twl4030_madc_attributes,
-};
+ATTRIBUTE_GROUPS(twl4030_madc);
static int twl4030_madc_hwmon_probe(struct platform_device *pdev)
{
- int ret;
struct device *hwmon;
- ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group);
- if (ret)
- goto err_sysfs;
- hwmon = hwmon_device_register(&pdev->dev);
- if (IS_ERR(hwmon)) {
- dev_err(&pdev->dev, "hwmon_device_register failed.\n");
- ret = PTR_ERR(hwmon);
- goto err_reg;
- }
-
- return 0;
-
-err_reg:
- sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
-err_sysfs:
-
- return ret;
-}
-
-static int twl4030_madc_hwmon_remove(struct platform_device *pdev)
-{
- hwmon_device_unregister(&pdev->dev);
- sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
-
- return 0;
+ hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+ "twl4030_madc", NULL,
+ twl4030_madc_groups);
+ return PTR_ERR_OR_ZERO(hwmon);
}
static struct platform_driver twl4030_madc_hwmon_driver = {
.probe = twl4030_madc_hwmon_probe,
- .remove = twl4030_madc_hwmon_remove,
.driver = {
.name = "twl4030_madc_hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index bdcf2dce5ec4..cb3765fec98c 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -249,19 +249,16 @@ static u8 fan_to_reg(long rpm, int div)
* the bottom 7 bits will always be zero
*/
#define TEMP23_FROM_REG(val) ((val) / 128 * 500)
-#define TEMP23_TO_REG(val) ((val) <= -128000 ? 0x8000 : \
- (val) >= 127500 ? 0x7F80 : \
- (val) < 0 ? ((val) - 250) / 500 * 128 : \
- ((val) + 250) / 500 * 128)
+#define TEMP23_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+ 127500), 500) * 128)
/* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
-#define TARGET_TEMP_TO_REG(val) ((val) < 0 ? 0 : \
- (val) >= 127000 ? 127 : \
- ((val) + 500) / 1000)
+#define TARGET_TEMP_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \
+ 1000)
/* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
-#define TOL_TEMP_TO_REG(val) ((val) >= 15000 ? 15 : \
- ((val) + 500) / 1000)
+#define TOL_TEMP_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 15000), \
+ 1000)
#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff)
#define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff)
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index 32487c19cbfc..330299613d38 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -124,7 +124,7 @@ DIV_TO_REG(long val)
}
struct w83l786ng_data {
- struct device *hwmon_dev;
+ struct i2c_client *client;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -148,32 +148,6 @@ struct w83l786ng_data {
u8 tolerance[2];
};
-static int w83l786ng_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int w83l786ng_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int w83l786ng_remove(struct i2c_client *client);
-static void w83l786ng_init_client(struct i2c_client *client);
-static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
-
-static const struct i2c_device_id w83l786ng_id[] = {
- { "w83l786ng", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
-
-static struct i2c_driver w83l786ng_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "w83l786ng",
- },
- .probe = w83l786ng_probe,
- .remove = w83l786ng_remove,
- .id_table = w83l786ng_id,
- .detect = w83l786ng_detect,
- .address_list = normal_i2c,
-};
-
static u8
w83l786ng_read_value(struct i2c_client *client, u8 reg)
{
@@ -186,6 +160,77 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value)
return i2c_smbus_write_byte_data(client, reg, value);
}
+static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
+{
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
+ int i, j;
+ u8 reg_tmp, pwmcfg;
+
+ mutex_lock(&data->update_lock);
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ dev_dbg(&client->dev, "Updating w83l786ng data.\n");
+
+ /* Update the voltages measured value and limits */
+ for (i = 0; i < 3; i++) {
+ data->in[i] = w83l786ng_read_value(client,
+ W83L786NG_REG_IN(i));
+ data->in_min[i] = w83l786ng_read_value(client,
+ W83L786NG_REG_IN_MIN(i));
+ data->in_max[i] = w83l786ng_read_value(client,
+ W83L786NG_REG_IN_MAX(i));
+ }
+
+ /* Update the fan counts and limits */
+ for (i = 0; i < 2; i++) {
+ data->fan[i] = w83l786ng_read_value(client,
+ W83L786NG_REG_FAN(i));
+ data->fan_min[i] = w83l786ng_read_value(client,
+ W83L786NG_REG_FAN_MIN(i));
+ }
+
+ /* Update the fan divisor */
+ reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
+ data->fan_div[0] = reg_tmp & 0x07;
+ data->fan_div[1] = (reg_tmp >> 4) & 0x07;
+
+ pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
+ for (i = 0; i < 2; i++) {
+ data->pwm_mode[i] =
+ ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
+ ? 0 : 1;
+ data->pwm_enable[i] =
+ ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1;
+ data->pwm[i] =
+ (w83l786ng_read_value(client, W83L786NG_REG_PWM[i])
+ & 0x0f) * 0x11;
+ }
+
+
+ /* Update the temperature sensors */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 3; j++) {
+ data->temp[i][j] = w83l786ng_read_value(client,
+ W83L786NG_REG_TEMP[i][j]);
+ }
+ }
+
+ /* Update Smart Fan I/II tolerance */
+ reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE);
+ data->tolerance[0] = reg_tmp & 0x0f;
+ data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
/* following are the sysfs callback functions */
#define show_in_reg(reg) \
static ssize_t \
@@ -207,8 +252,8 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
int nr = to_sensor_dev_attr(attr)->index; \
- struct i2c_client *client = to_i2c_client(dev); \
- struct w83l786ng_data *data = i2c_get_clientdata(client); \
+ struct w83l786ng_data *data = dev_get_drvdata(dev); \
+ struct i2c_client *client = data->client; \
unsigned long val; \
int err = kstrtoul(buf, 10, &val); \
if (err) \
@@ -260,8 +305,8 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -298,8 +343,8 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long min;
u8 tmp_fan_div;
@@ -389,8 +434,8 @@ store_temp(struct device *dev, struct device_attribute *attr,
to_sensor_dev_attr_2(attr);
int nr = sensor_attr->nr;
int index = sensor_attr->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
long val;
int err;
@@ -444,8 +489,8 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 reg;
unsigned long val;
int err;
@@ -472,8 +517,8 @@ store_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
unsigned long val;
int err;
@@ -496,8 +541,8 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 reg;
unsigned long val;
int err;
@@ -552,8 +597,8 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
+ struct w83l786ng_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = data->client;
u8 tol_tmp, tol_mask;
unsigned long val;
int err;
@@ -608,7 +653,7 @@ static struct sensor_device_attribute sda_tolerance[] = {
#define TOLERANCE_UNIT_ATTRS(X) \
&sda_tolerance[X].dev_attr.attr
-static struct attribute *w83l786ng_attributes[] = {
+static struct attribute *w83l786ng_attrs[] = {
IN_UNIT_ATTRS(0),
IN_UNIT_ATTRS(1),
IN_UNIT_ATTRS(2),
@@ -623,9 +668,7 @@ static struct attribute *w83l786ng_attributes[] = {
NULL
};
-static const struct attribute_group w83l786ng_group = {
- .attrs = w83l786ng_attributes,
-};
+ATTRIBUTE_GROUPS(w83l786ng);
static int
w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
@@ -662,20 +705,33 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
return 0;
}
+static void w83l786ng_init_client(struct i2c_client *client)
+{
+ u8 tmp;
+
+ if (reset)
+ w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80);
+
+ /* Start monitoring */
+ tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG);
+ if (!(tmp & 0x01))
+ w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01);
+}
+
static int
w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct w83l786ng_data *data;
- int i, err = 0;
+ struct device *hwmon_dev;
+ int i;
u8 reg_tmp;
- data = devm_kzalloc(&client->dev, sizeof(struct w83l786ng_data),
- GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct w83l786ng_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- i2c_set_clientdata(client, data);
+ data->client = client;
mutex_init(&data->update_lock);
/* Initialize the chip */
@@ -692,121 +748,28 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
data->fan_div[0] = reg_tmp & 0x07;
data->fan_div[1] = (reg_tmp >> 4) & 0x07;
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group);
- if (err)
- goto exit_remove;
-
- data->hwmon_dev = hwmon_device_register(dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove;
- }
-
- return 0;
-
- /* Unregister sysfs hooks */
-
-exit_remove:
- sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
- return err;
-}
-
-static int
-w83l786ng_remove(struct i2c_client *client)
-{
- struct w83l786ng_data *data = i2c_get_clientdata(client);
-
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
-
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ data,
+ w83l786ng_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
-static void
-w83l786ng_init_client(struct i2c_client *client)
-{
- u8 tmp;
-
- if (reset)
- w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80);
-
- /* Start monitoring */
- tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG);
- if (!(tmp & 0x01))
- w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01);
-}
-
-static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83l786ng_data *data = i2c_get_clientdata(client);
- int i, j;
- u8 reg_tmp, pwmcfg;
-
- mutex_lock(&data->update_lock);
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- dev_dbg(&client->dev, "Updating w83l786ng data.\n");
-
- /* Update the voltages measured value and limits */
- for (i = 0; i < 3; i++) {
- data->in[i] = w83l786ng_read_value(client,
- W83L786NG_REG_IN(i));
- data->in_min[i] = w83l786ng_read_value(client,
- W83L786NG_REG_IN_MIN(i));
- data->in_max[i] = w83l786ng_read_value(client,
- W83L786NG_REG_IN_MAX(i));
- }
-
- /* Update the fan counts and limits */
- for (i = 0; i < 2; i++) {
- data->fan[i] = w83l786ng_read_value(client,
- W83L786NG_REG_FAN(i));
- data->fan_min[i] = w83l786ng_read_value(client,
- W83L786NG_REG_FAN_MIN(i));
- }
-
- /* Update the fan divisor */
- reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
- data->fan_div[0] = reg_tmp & 0x07;
- data->fan_div[1] = (reg_tmp >> 4) & 0x07;
-
- pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
- for (i = 0; i < 2; i++) {
- data->pwm_mode[i] =
- ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
- ? 0 : 1;
- data->pwm_enable[i] =
- ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1;
- data->pwm[i] =
- (w83l786ng_read_value(client, W83L786NG_REG_PWM[i])
- & 0x0f) * 0x11;
- }
-
-
- /* Update the temperature sensors */
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 3; j++) {
- data->temp[i][j] = w83l786ng_read_value(client,
- W83L786NG_REG_TEMP[i][j]);
- }
- }
-
- /* Update Smart Fan I/II tolerance */
- reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE);
- data->tolerance[0] = reg_tmp & 0x0f;
- data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
-
- data->last_updated = jiffies;
- data->valid = 1;
-
- }
-
- mutex_unlock(&data->update_lock);
+static const struct i2c_device_id w83l786ng_id[] = {
+ { "w83l786ng", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
- return data;
-}
+static struct i2c_driver w83l786ng_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "w83l786ng",
+ },
+ .probe = w83l786ng_probe,
+ .id_table = w83l786ng_id,
+ .detect = w83l786ng_detect,
+ .address_list = normal_i2c,
+};
module_i2c_driver(w83l786ng_driver);
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c
index df6ceaf8d58a..3e6a3195cd11 100644
--- a/drivers/hwmon/wm831x-hwmon.c
+++ b/drivers/hwmon/wm831x-hwmon.c
@@ -29,17 +29,6 @@
#include <linux/mfd/wm831x/core.h>
#include <linux/mfd/wm831x/auxadc.h>
-struct wm831x_hwmon {
- struct wm831x *wm831x;
- struct device *classdev;
-};
-
-static ssize_t show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "wm831x\n");
-}
-
static const char * const input_names[] = {
[WM831X_AUX_SYSVDD] = "SYSVDD",
[WM831X_AUX_USB] = "USB",
@@ -50,15 +39,14 @@ static const char * const input_names[] = {
[WM831X_AUX_BATT_TEMP] = "Battery",
};
-
static ssize_t show_voltage(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+ struct wm831x *wm831x = dev_get_drvdata(dev);
int channel = to_sensor_dev_attr(attr)->index;
int ret;
- ret = wm831x_auxadc_read_uv(hwmon->wm831x, channel);
+ ret = wm831x_auxadc_read_uv(wm831x, channel);
if (ret < 0)
return ret;
@@ -68,11 +56,11 @@ static ssize_t show_voltage(struct device *dev,
static ssize_t show_chip_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+ struct wm831x *wm831x = dev_get_drvdata(dev);
int channel = to_sensor_dev_attr(attr)->index;
int ret;
- ret = wm831x_auxadc_read(hwmon->wm831x, channel);
+ ret = wm831x_auxadc_read(wm831x, channel);
if (ret < 0)
return ret;
@@ -100,8 +88,6 @@ static ssize_t show_label(struct device *dev,
static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \
NULL, name)
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
WM831X_VOLTAGE(0, WM831X_AUX_AUX1);
WM831X_VOLTAGE(1, WM831X_AUX_AUX2);
WM831X_VOLTAGE(2, WM831X_AUX_AUX3);
@@ -126,9 +112,7 @@ static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL,
static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
WM831X_AUX_BATT_TEMP);
-static struct attribute *wm831x_attributes[] = {
- &dev_attr_name.attr,
-
+static struct attribute *wm831x_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -153,55 +137,21 @@ static struct attribute *wm831x_attributes[] = {
NULL
};
-static const struct attribute_group wm831x_attr_group = {
- .attrs = wm831x_attributes,
-};
+ATTRIBUTE_GROUPS(wm831x);
static int wm831x_hwmon_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
- struct wm831x_hwmon *hwmon;
- int ret;
-
- hwmon = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_hwmon),
- GFP_KERNEL);
- if (!hwmon)
- return -ENOMEM;
-
- hwmon->wm831x = wm831x;
-
- ret = sysfs_create_group(&pdev->dev.kobj, &wm831x_attr_group);
- if (ret)
- return ret;
-
- hwmon->classdev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(hwmon->classdev)) {
- ret = PTR_ERR(hwmon->classdev);
- goto err_sysfs;
- }
-
- platform_set_drvdata(pdev, hwmon);
-
- return 0;
-
-err_sysfs:
- sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
- return ret;
-}
-
-static int wm831x_hwmon_remove(struct platform_device *pdev)
-{
- struct wm831x_hwmon *hwmon = platform_get_drvdata(pdev);
-
- hwmon_device_unregister(hwmon->classdev);
- sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
+ struct device *hwmon_dev;
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm831x",
+ wm831x,
+ wm831x_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static struct platform_driver wm831x_hwmon_driver = {
.probe = wm831x_hwmon_probe,
- .remove = wm831x_hwmon_remove,
.driver = {
.name = "wm831x-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
index 64bf75c9442b..90e3d918e597 100644
--- a/drivers/hwmon/wm8350-hwmon.c
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -28,19 +28,12 @@
#include <linux/mfd/wm8350/core.h>
#include <linux/mfd/wm8350/comparator.h>
-static ssize_t show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "wm8350\n");
-}
-
static const char * const input_names[] = {
[WM8350_AUXADC_USB] = "USB",
[WM8350_AUXADC_LINE] = "Line",
[WM8350_AUXADC_BATT] = "Battery",
};
-
static ssize_t show_voltage(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -68,15 +61,11 @@ static ssize_t show_label(struct device *dev,
static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \
NULL, name)
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
-static struct attribute *wm8350_attributes[] = {
- &dev_attr_name.attr,
-
+static struct attribute *wm8350_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_label.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
@@ -87,46 +76,21 @@ static struct attribute *wm8350_attributes[] = {
NULL,
};
-static const struct attribute_group wm8350_attr_group = {
- .attrs = wm8350_attributes,
-};
+ATTRIBUTE_GROUPS(wm8350);
static int wm8350_hwmon_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- int ret;
-
- ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group);
- if (ret)
- goto err;
-
- wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(wm8350->hwmon.classdev)) {
- ret = PTR_ERR(wm8350->hwmon.classdev);
- goto err_group;
- }
-
- return 0;
-
-err_group:
- sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
-err:
- return ret;
-}
-
-static int wm8350_hwmon_remove(struct platform_device *pdev)
-{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-
- hwmon_device_unregister(wm8350->hwmon.classdev);
- sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
+ struct device *hwmon_dev;
- return 0;
+ hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm8350",
+ wm8350,
+ wm8350_groups);
+ return PTR_ERR_OR_ZERO(hwmon_dev);
}
static struct platform_driver wm8350_hwmon_driver = {
.probe = wm8350_hwmon_probe,
- .remove = wm8350_hwmon_remove,
.driver = {
.name = "wm8350-hwmon",
.owner = THIS_MODULE,
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
index 8e7a71487bb1..05e033c98115 100644
--- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
@@ -183,6 +183,7 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
u8 *request = NULL;
u8 *response = NULL;
int result;
+ struct cros_ec_command msg;
request_len = ec_i2c_count_message(i2c_msgs, num);
if (request_len < 0) {
@@ -218,10 +219,16 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
}
ec_i2c_construct_message(request, i2c_msgs, num, bus_num);
- result = bus->ec->command_sendrecv(bus->ec, EC_CMD_I2C_PASSTHRU,
- request, request_len,
- response, response_len);
- if (result)
+
+ msg.version = 0;
+ msg.command = EC_CMD_I2C_PASSTHRU;
+ msg.outdata = request;
+ msg.outsize = request_len;
+ msg.indata = response;
+ msg.insize = response_len;
+
+ result = bus->ec->cmd_xfer(bus->ec, &msg);
+ if (result < 0)
goto exit;
result = ec_i2c_parse_response(response, i2c_msgs, &num);
@@ -258,7 +265,7 @@ static int ec_i2c_probe(struct platform_device *pdev)
u32 remote_bus;
int err;
- if (!ec->command_sendrecv) {
+ if (!ec->cmd_xfer) {
dev_err(dev, "Missing sendrecv\n");
return -EINVAL;
}
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index 09de4fd12d57..4d75d4759709 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -22,7 +22,6 @@
*
*/
#include <linux/clk.h>
-#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/interrupt.h>
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 7c7f4b856bad..66aa83b99383 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -42,6 +42,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/clk/clk-conf.h>
#include <linux/completion.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
@@ -274,6 +275,10 @@ static int i2c_device_probe(struct device *dev)
client->flags & I2C_CLIENT_WAKE);
dev_dbg(dev, "probe\n");
+ status = of_clk_set_defaults(dev->of_node, false);
+ if (status < 0)
+ return status;
+
acpi_dev_pm_attach(&client->dev, true);
status = driver->probe(client, i2c_match_id(driver->id_table, client));
if (status)
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index f7f9865b8b89..f6d313e528de 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -40,6 +40,7 @@ config I2C_MUX_PCA9541
config I2C_MUX_PCA954x
tristate "Philips PCA954x I2C Mux/switches"
+ depends on GPIOLIB
help
If you say yes here you get support for the Philips PCA954x
I2C mux/switch devices.
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8fb46aab2d87..a04c49f2a011 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -416,6 +416,7 @@ config BLK_DEV_CY82C693
config BLK_DEV_CS5520
tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
Include support for PIO tuning and virtual DMA on the Cyrix MediaGX
@@ -426,6 +427,7 @@ config BLK_DEV_CS5520
config BLK_DEV_CS5530
tristate "Cyrix/National Semiconductor CS5530 MediaGX chipset support"
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
@@ -435,7 +437,7 @@ config BLK_DEV_CS5530
config BLK_DEV_CS5535
tristate "AMD CS5535 chipset support"
- depends on X86 && !X86_64
+ depends on X86_32
select BLK_DEV_IDEDMA_PCI
help
Include support for UDMA on the NSC/AMD CS5535 companion chipset.
@@ -486,6 +488,7 @@ config BLK_DEV_JMICRON
config BLK_DEV_SC1200
tristate "National SCx200 chipset support"
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
This driver adds support for the on-board IDE controller on the
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 259786ca8b75..07ea58084068 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -592,18 +592,7 @@ static struct platform_driver au1200_ide_driver = {
.remove = au_ide_remove,
};
-static int __init au_ide_init(void)
-{
- return platform_driver_register(&au1200_ide_driver);
-}
-
-static void __exit au_ide_exit(void)
-{
- platform_driver_unregister(&au1200_ide_driver);
-}
+module_platform_driver(au1200_ide_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AU1200 IDE driver");
-
-module_init(au_ide_init);
-module_exit(au_ide_exit);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 2a744a91370e..a3d3b1733c49 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -853,8 +853,9 @@ static int init_irq (ide_hwif_t *hwif)
if (irq_handler == NULL)
irq_handler = ide_intr;
- if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
- goto out_up;
+ if (!host->get_lock)
+ if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
+ goto out_up;
#if !defined(__mc68000__)
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
@@ -1533,7 +1534,8 @@ static void ide_unregister(ide_hwif_t *hwif)
ide_proc_unregister_port(hwif);
- free_irq(hwif->irq, hwif);
+ if (!hwif->host->get_lock)
+ free_irq(hwif->irq, hwif);
device_unregister(hwif->portdev);
device_unregister(&hwif->gendev);
diff --git a/drivers/ide/ide_platform.c b/drivers/ide/ide_platform.c
index a8b4b6af80e7..d48de6de503e 100644
--- a/drivers/ide/ide_platform.c
+++ b/drivers/ide/ide_platform.c
@@ -131,19 +131,8 @@ static struct platform_driver platform_ide_driver = {
.remove = plat_ide_remove,
};
-static int __init platform_ide_init(void)
-{
- return platform_driver_register(&platform_ide_driver);
-}
-
-static void __exit platform_ide_exit(void)
-{
- platform_driver_unregister(&platform_ide_driver);
-}
+module_platform_driver(platform_ide_driver);
MODULE_DESCRIPTION("Platform IDE driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pata_platform");
-
-module_init(platform_ide_init);
-module_exit(platform_ide_exit);
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 1e120fa1e156..12addf272a61 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -77,4 +77,16 @@ config MMA8452
To compile this driver as a module, choose M here: the module
will be called mma8452.
+config KXCJK1013
+ tristate "Kionix 3-Axis Accelerometer Driver"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build a driver for the Kionix KXCJK-1013
+ triaxial acceleration sensor.
+
+ To compile this driver as a module, choose M here: the module will
+ be called kxcjk-1013.
+
endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index dc0e379c2592..6578ca1a8e09 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -5,6 +5,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_BMA180) += bma180.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
+obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o
obj-$(CONFIG_MMA8452) += mma8452.o
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index a7e68c81f89d..a077cc86421b 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -68,13 +68,13 @@
/* Defaults values */
#define BMA180_DEF_PMODE 0
#define BMA180_DEF_BW 20
-#define BMA180_DEF_SCALE 250
+#define BMA180_DEF_SCALE 2452
/* Available values for sysfs */
#define BMA180_FLP_FREQ_AVAILABLE \
"10 20 40 75 150 300"
#define BMA180_SCALE_AVAILABLE \
- "0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
+ "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"
struct bma180_data {
struct i2c_client *client;
@@ -94,7 +94,7 @@ enum bma180_axis {
};
static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
-static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
+static int scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
{
@@ -376,6 +376,8 @@ static int bma180_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->mutex);
return ret;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ if (val2)
+ return -EINVAL;
mutex_lock(&data->mutex);
ret = bma180_set_bw(data, val);
mutex_unlock(&data->mutex);
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 69abf9163df7..54e464e4bb72 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -110,7 +110,6 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
struct accel_3d_state *accel_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -151,14 +150,12 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&accel_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&accel_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
new file mode 100644
index 000000000000..7941cf2d31ee
--- /dev/null
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -0,0 +1,764 @@
+/*
+ * KXCJK-1013 3-axis accelerometer driver
+ * Copyright (c) 2014, Intel 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.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/iio/accel/kxcjk_1013.h>
+
+#define KXCJK1013_DRV_NAME "kxcjk1013"
+#define KXCJK1013_IRQ_NAME "kxcjk1013_event"
+
+#define KXCJK1013_REG_XOUT_L 0x06
+/*
+ * From low byte X axis register, all the other addresses of Y and Z can be
+ * obtained by just applying axis offset. The following axis defines are just
+ * provide clarity, but not used.
+ */
+#define KXCJK1013_REG_XOUT_H 0x07
+#define KXCJK1013_REG_YOUT_L 0x08
+#define KXCJK1013_REG_YOUT_H 0x09
+#define KXCJK1013_REG_ZOUT_L 0x0A
+#define KXCJK1013_REG_ZOUT_H 0x0B
+
+#define KXCJK1013_REG_DCST_RESP 0x0C
+#define KXCJK1013_REG_WHO_AM_I 0x0F
+#define KXCJK1013_REG_INT_SRC1 0x16
+#define KXCJK1013_REG_INT_SRC2 0x17
+#define KXCJK1013_REG_STATUS_REG 0x18
+#define KXCJK1013_REG_INT_REL 0x1A
+#define KXCJK1013_REG_CTRL1 0x1B
+#define KXCJK1013_REG_CTRL2 0x1D
+#define KXCJK1013_REG_INT_CTRL1 0x1E
+#define KXCJK1013_REG_INT_CTRL2 0x1F
+#define KXCJK1013_REG_DATA_CTRL 0x21
+#define KXCJK1013_REG_WAKE_TIMER 0x29
+#define KXCJK1013_REG_SELF_TEST 0x3A
+#define KXCJK1013_REG_WAKE_THRES 0x6A
+
+#define KXCJK1013_REG_CTRL1_BIT_PC1 BIT(7)
+#define KXCJK1013_REG_CTRL1_BIT_RES BIT(6)
+#define KXCJK1013_REG_CTRL1_BIT_DRDY BIT(5)
+#define KXCJK1013_REG_CTRL1_BIT_GSEL1 BIT(4)
+#define KXCJK1013_REG_CTRL1_BIT_GSEL0 BIT(3)
+#define KXCJK1013_REG_CTRL1_BIT_WUFE BIT(1)
+#define KXCJK1013_REG_INT_REG1_BIT_IEA BIT(4)
+#define KXCJK1013_REG_INT_REG1_BIT_IEN BIT(5)
+
+#define KXCJK1013_DATA_MASK_12_BIT 0x0FFF
+#define KXCJK1013_MAX_STARTUP_TIME_US 100000
+
+struct kxcjk1013_data {
+ struct i2c_client *client;
+ struct iio_trigger *trig;
+ bool trig_mode;
+ struct mutex mutex;
+ s16 buffer[8];
+ int power_state;
+ u8 odr_bits;
+ bool active_high_intr;
+};
+
+enum kxcjk1013_axis {
+ AXIS_X,
+ AXIS_Y,
+ AXIS_Z,
+};
+
+enum kxcjk1013_mode {
+ STANDBY,
+ OPERATION,
+};
+
+static const struct {
+ int val;
+ int val2;
+ int odr_bits;
+} samp_freq_table[] = { {0, 781000, 0x08}, {1, 563000, 0x09},
+ {3, 125000, 0x0A}, {6, 250000, 0x0B}, {12, 500000, 0},
+ {25, 0, 0x01}, {50, 0, 0x02}, {100, 0, 0x03},
+ {200, 0, 0x04}, {400, 0, 0x05}, {800, 0, 0x06},
+ {1600, 0, 0x07} };
+
+/* Refer to section 4 of the specification */
+static const struct {
+ int odr_bits;
+ int usec;
+} odr_start_up_times[] = { {0x08, 100000}, {0x09, 100000}, {0x0A, 100000},
+ {0x0B, 100000}, { 0, 80000}, {0x01, 41000},
+ {0x02, 21000}, {0x03, 11000}, {0x04, 6400},
+ {0x05, 3900}, {0x06, 2700}, {0x07, 2100} };
+
+static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
+ enum kxcjk1013_mode mode)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (mode == STANDBY)
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_PC1;
+ else
+ ret |= KXCJK1013_REG_CTRL1_BIT_PC1;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1, ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading who_am_i\n");
+ return ret;
+ }
+
+ dev_dbg(&data->client->dev, "KXCJK1013 Chip Id %x\n", ret);
+
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ /* Setting range to 4G */
+ ret |= KXCJK1013_REG_CTRL1_BIT_GSEL0;
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_GSEL1;
+
+ /* Set 12 bit mode */
+ ret |= KXCJK1013_REG_CTRL1_BIT_RES;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_data_ctrl\n");
+ return ret;
+ }
+
+ data->odr_bits = ret;
+
+ /* Set up INT polarity */
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+ return ret;
+ }
+
+ if (data->active_high_intr)
+ ret |= KXCJK1013_REG_INT_REG1_BIT_IEA;
+ else
+ ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEA;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data,
+ bool status)
+{
+ int ret;
+
+ /* This is requirement by spec to change state to STANDBY */
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
+ else
+ ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+ ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+ return ret;
+ }
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+ return ret;
+ }
+
+ if (status)
+ ret |= KXCJK1013_REG_CTRL1_BIT_DRDY;
+ else
+ ret &= ~KXCJK1013_REG_CTRL1_BIT_DRDY;
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ KXCJK1013_REG_CTRL1, ret);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int kxcjk1013_convert_freq_to_bit(int val, int val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) {
+ if (samp_freq_table[i].val == val &&
+ samp_freq_table[i].val2 == val2) {
+ return samp_freq_table[i].odr_bits;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
+{
+ int ret;
+ int odr_bits;
+
+ odr_bits = kxcjk1013_convert_freq_to_bit(val, val2);
+ if (odr_bits < 0)
+ return odr_bits;
+
+ /* To change ODR, the chip must be set to STANDBY as per spec */
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_DATA_CTRL,
+ odr_bits);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing data_ctrl\n");
+ return ret;
+ }
+
+ data->odr_bits = odr_bits;
+
+ /* Check, if the ODR is changed after data enable */
+ if (data->power_state) {
+ /* Set the state back to operation */
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_get_odr(struct kxcjk1013_data *data, int *val, int *val2)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(samp_freq_table); ++i) {
+ if (samp_freq_table[i].odr_bits == data->odr_bits) {
+ *val = samp_freq_table[i].val;
+ *val2 = samp_freq_table[i].val2;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis)
+{
+ u8 reg = KXCJK1013_REG_XOUT_L + axis * 2;
+ int ret;
+
+ ret = i2c_smbus_read_word_data(data->client, reg);
+ if (ret < 0) {
+ dev_err(&data->client->dev,
+ "failed to read accel_%c registers\n", 'x' + axis);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(odr_start_up_times); ++i) {
+ if (odr_start_up_times[i].odr_bits == data->odr_bits)
+ return odr_start_up_times[i].usec;
+ }
+
+ return KXCJK1013_MAX_STARTUP_TIME_US;
+}
+
+static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&data->mutex);
+ if (iio_buffer_enabled(indio_dev))
+ ret = -EBUSY;
+ else {
+ int sleep_val;
+
+ ret = kxcjk1013_set_mode(data, OPERATION);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ return ret;
+ }
+ ++data->power_state;
+ sleep_val = kxcjk1013_get_startup_times(data);
+ if (sleep_val < 20000)
+ usleep_range(sleep_val, 20000);
+ else
+ msleep_interruptible(sleep_val/1000);
+ ret = kxcjk1013_get_acc_reg(data, chan->scan_index);
+ if (--data->power_state == 0)
+ kxcjk1013_set_mode(data, STANDBY);
+ }
+ mutex_unlock(&data->mutex);
+
+ if (ret < 0)
+ return ret;
+
+ *val = sign_extend32(ret >> 4, 11);
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = 19163; /* range +-4g (4/2047*9.806650) */
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_get_odr(data, val, val2);
+ mutex_unlock(&data->mutex);
+ return ret;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int kxcjk1013_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int val,
+ int val2, long mask)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&data->mutex);
+ ret = kxcjk1013_set_odr(data, val, val2);
+ mutex_unlock(&data->mutex);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev,
+ struct iio_trigger *trig)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ if (data->trig != trig)
+ return -EINVAL;
+
+ return 0;
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
+ "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600");
+
+static struct attribute *kxcjk1013_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group kxcjk1013_attrs_group = {
+ .attrs = kxcjk1013_attributes,
+};
+
+#define KXCJK1013_CHANNEL(_axis) { \
+ .type = IIO_ACCEL, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##_axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = AXIS_##_axis, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_CPU, \
+ }, \
+}
+
+static const struct iio_chan_spec kxcjk1013_channels[] = {
+ KXCJK1013_CHANNEL(X),
+ KXCJK1013_CHANNEL(Y),
+ KXCJK1013_CHANNEL(Z),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_info kxcjk1013_info = {
+ .attrs = &kxcjk1013_attrs_group,
+ .read_raw = kxcjk1013_read_raw,
+ .write_raw = kxcjk1013_write_raw,
+ .validate_trigger = kxcjk1013_validate_trigger,
+ .driver_module = THIS_MODULE,
+};
+
+static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int bit, ret, i = 0;
+
+ mutex_lock(&data->mutex);
+
+ for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+ indio_dev->masklength) {
+ ret = kxcjk1013_get_acc_reg(data, bit);
+ if (ret < 0) {
+ mutex_unlock(&data->mutex);
+ goto err;
+ }
+ data->buffer[i++] = ret;
+ }
+ mutex_unlock(&data->mutex);
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ pf->timestamp);
+err:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int kxcjk1013_trig_try_reen(struct iio_trigger *trig)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error reading reg_int_rel\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
+ bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+ if (state) {
+ kxcjk1013_chip_setup_interrupt(data, true);
+ kxcjk1013_set_mode(data, OPERATION);
+ ++data->power_state;
+ } else {
+ if (--data->power_state) {
+ mutex_unlock(&data->mutex);
+ return 0;
+ }
+ kxcjk1013_chip_setup_interrupt(data, false);
+ kxcjk1013_set_mode(data, STANDBY);
+ }
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static const struct iio_trigger_ops kxcjk1013_trigger_ops = {
+ .set_trigger_state = kxcjk1013_data_rdy_trigger_set_state,
+ .try_reenable = kxcjk1013_trig_try_reen,
+ .owner = THIS_MODULE,
+};
+
+static int kxcjk1013_acpi_gpio_probe(struct i2c_client *client,
+ struct kxcjk1013_data *data)
+{
+ const struct acpi_device_id *id;
+ struct device *dev;
+ struct gpio_desc *gpio;
+ int ret;
+
+ if (!client)
+ return -EINVAL;
+
+ dev = &client->dev;
+ if (!ACPI_HANDLE(dev))
+ return -ENODEV;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id)
+ return -ENODEV;
+
+ /* data ready gpio interrupt pin */
+ gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0);
+ if (IS_ERR(gpio)) {
+ dev_err(dev, "acpi gpio get index failed\n");
+ return PTR_ERR(gpio);
+ }
+
+ ret = gpiod_direction_input(gpio);
+ if (ret)
+ return ret;
+
+ ret = gpiod_to_irq(gpio);
+
+ dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+ return ret;
+}
+
+static int kxcjk1013_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct kxcjk1013_data *data;
+ struct iio_dev *indio_dev;
+ struct iio_trigger *trig = NULL;
+ struct kxcjk_1013_platform_data *pdata;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ pdata = dev_get_platdata(&client->dev);
+ if (pdata)
+ data->active_high_intr = pdata->active_high_intr;
+ else
+ data->active_high_intr = true; /* default polarity */
+
+ ret = kxcjk1013_chip_init(data);
+ if (ret < 0)
+ return ret;
+
+ mutex_init(&data->mutex);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = kxcjk1013_channels;
+ indio_dev->num_channels = ARRAY_SIZE(kxcjk1013_channels);
+ indio_dev->name = KXCJK1013_DRV_NAME;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &kxcjk1013_info;
+
+ if (client->irq < 0)
+ client->irq = kxcjk1013_acpi_gpio_probe(client, data);
+
+ if (client->irq >= 0) {
+ trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+ indio_dev->id);
+ if (!trig)
+ return -ENOMEM;
+
+ data->trig_mode = true;
+
+ ret = devm_request_irq(&client->dev, client->irq,
+ iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_RISING,
+ KXCJK1013_IRQ_NAME,
+ trig);
+ if (ret) {
+ dev_err(&client->dev, "unable to request IRQ\n");
+ goto err_trigger_free;
+ }
+
+ trig->dev.parent = &client->dev;
+ trig->ops = &kxcjk1013_trigger_ops;
+ iio_trigger_set_drvdata(trig, indio_dev);
+ data->trig = trig;
+ indio_dev->trig = trig;
+ iio_trigger_get(indio_dev->trig);
+
+ ret = iio_trigger_register(trig);
+ if (ret)
+ goto err_trigger_free;
+
+ ret = iio_triggered_buffer_setup(indio_dev,
+ &iio_pollfunc_store_time,
+ kxcjk1013_trigger_handler,
+ NULL);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "iio triggered buffer setup failed\n");
+ goto err_trigger_unregister;
+ }
+ }
+
+ ret = devm_iio_device_register(&client->dev, indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "unable to register iio device\n");
+ goto err_buffer_cleanup;
+ }
+
+ return 0;
+
+err_buffer_cleanup:
+ if (data->trig_mode)
+ iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+ if (data->trig_mode)
+ iio_trigger_unregister(trig);
+err_trigger_free:
+ if (data->trig_mode)
+ iio_trigger_free(trig);
+
+ return ret;
+}
+
+static int kxcjk1013_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ if (data->trig_mode) {
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_trigger_unregister(data->trig);
+ iio_trigger_free(data->trig);
+ }
+
+ mutex_lock(&data->mutex);
+ kxcjk1013_set_mode(data, STANDBY);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int kxcjk1013_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+ kxcjk1013_set_mode(data, STANDBY);
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static int kxcjk1013_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ mutex_lock(&data->mutex);
+
+ if (data->power_state)
+ kxcjk1013_set_mode(data, OPERATION);
+
+ mutex_unlock(&data->mutex);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(kxcjk1013_pm_ops, kxcjk1013_suspend, kxcjk1013_resume);
+#define KXCJK1013_PM_OPS (&kxcjk1013_pm_ops)
+#else
+#define KXCJK1013_PM_OPS NULL
+#endif
+
+static const struct acpi_device_id kx_acpi_match[] = {
+ {"KXCJ1013", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
+
+static const struct i2c_device_id kxcjk1013_id[] = {
+ {"kxcjk1013", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, kxcjk1013_id);
+
+static struct i2c_driver kxcjk1013_driver = {
+ .driver = {
+ .name = KXCJK1013_DRV_NAME,
+ .acpi_match_table = ACPI_PTR(kx_acpi_match),
+ .pm = KXCJK1013_PM_OPS,
+ },
+ .probe = kxcjk1013_probe,
+ .remove = kxcjk1013_remove,
+ .id_table = kxcjk1013_id,
+};
+module_i2c_driver(kxcjk1013_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("KXCJK1013 accelerometer driver");
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index 17aeea170566..3c12d4966376 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -111,8 +111,14 @@ static const int mma8452_samp_freq[8][2] = {
{6, 250000}, {1, 560000}
};
+/*
+ * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
+ * The userspace interface uses m/s^2 and we declare micro units
+ * So scale factor is given by:
+ * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
+ */
static const int mma8452_scales[3][2] = {
- {0, 977}, {0, 1953}, {0, 3906}
+ {0, 9577}, {0, 19154}, {0, 38307}
};
static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
@@ -423,9 +429,15 @@ static const struct i2c_device_id mma8452_id[] = {
};
MODULE_DEVICE_TABLE(i2c, mma8452_id);
+static const struct of_device_id mma8452_dt_ids[] = {
+ { .compatible = "fsl,mma8452" },
+ { }
+};
+
static struct i2c_driver mma8452_driver = {
.driver = {
.name = "mma8452",
+ .of_match_table = of_match_ptr(mma8452_dt_ids),
.pm = MMA8452_PM_OPS,
},
.probe = mma8452_probe,
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index a2abf7c2ce3b..087864854c61 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -393,6 +393,9 @@ static int st_accel_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = adata->current_fullscale->gain;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = adata->odr;
+ return IIO_VAL_INT;
default:
return -EINVAL;
}
@@ -410,6 +413,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ err = st_sensors_set_odr(indio_dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return err;
default:
return -EINVAL;
}
@@ -417,14 +427,12 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
return err;
}
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
static struct attribute *st_accel_attributes[] = {
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL,
};
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index d7bedbdfc81d..7164aeff3ab1 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -18,6 +18,55 @@
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_accel.h"
+#ifdef CONFIG_OF
+static const struct of_device_id st_accel_of_match[] = {
+ {
+ .compatible = "st,lsm303dlh-accel",
+ .data = LSM303DLH_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm303dlhc-accel",
+ .data = LSM303DLHC_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,lsm303dl-accel",
+ .data = LSM303DL_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm303dlm-accel",
+ .data = LSM303DLM_ACCEL_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330-accel",
+ .data = LSM330_ACCEL_DEV_NAME,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_accel_of_match);
+#else
+#define st_accel_of_match NULL
+#endif
+
static int st_accel_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -31,6 +80,7 @@ static int st_accel_i2c_probe(struct i2c_client *client,
adata = iio_priv(indio_dev);
adata->dev = &client->dev;
+ st_sensors_of_i2c_probe(client, st_accel_of_match);
st_sensors_i2c_configure(indio_dev, client, adata);
@@ -67,6 +117,7 @@ static struct i2c_driver st_accel_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-accel-i2c",
+ .of_match_table = of_match_ptr(st_accel_of_match),
},
.probe = st_accel_i2c_probe,
.remove = st_accel_i2c_remove,
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a80d23628f14..11b048a59fde 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -20,6 +20,16 @@ config AD7266
Say yes here to build support for Analog Devices AD7265 and AD7266
ADCs.
+config AD7291
+ tristate "Analog Devices AD7291 ADC driver"
+ depends on I2C
+ help
+ Say yes here to build support for Analog Devices AD7291
+ 8 Channel ADC with temperature sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ad7291.
+
config AD7298
tristate "Analog Devices AD7298 ADC driver"
depends on SPI
@@ -131,6 +141,15 @@ config LP8788_ADC
help
Say yes here to build support for TI LP8788 ADC.
+config MAX1027
+ tristate "Maxim max1027 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Maxim SPI ADC models
+ max1027, max1029 and max1031.
+
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9d60f2deaaaf..ad81b512aa3d 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -5,6 +5,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o
+obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7298) += ad7298.o
obj-$(CONFIG_AD7923) += ad7923.o
obj-$(CONFIG_AD7476) += ad7476.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_AD799X) += ad799x.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
+obj-$(CONFIG_MAX1027) += max1027.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/iio/adc/ad7291.c
index 357cef2a6f4c..c0eabf156702 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/iio/adc/ad7291.c
@@ -6,22 +6,22 @@
* Licensed under the GPL-2 or later.
*/
-#include <linux/interrupt.h>
#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
+#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>
-#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
-#include "ad7291.h"
+#include <linux/platform_data/ad7291.h>
/*
* Simplified handling
@@ -31,7 +31,6 @@
* is in the read mask.
*
* The noise-delayed bit as per datasheet suggestion is always enabled.
- *
*/
/*
@@ -47,33 +46,38 @@
#define AD7291_VOLTAGE_ALERT_STATUS 0x1F
#define AD7291_T_ALERT_STATUS 0x20
+#define AD7291_BITS 12
#define AD7291_VOLTAGE_LIMIT_COUNT 8
/*
* AD7291 command
*/
-#define AD7291_AUTOCYCLE (1 << 0)
-#define AD7291_RESET (1 << 1)
-#define AD7291_ALERT_CLEAR (1 << 2)
-#define AD7291_ALERT_POLARITY (1 << 3)
-#define AD7291_EXT_REF (1 << 4)
-#define AD7291_NOISE_DELAY (1 << 5)
-#define AD7291_T_SENSE_MASK (1 << 7)
-#define AD7291_VOLTAGE_MASK 0xFF00
-#define AD7291_VOLTAGE_OFFSET 0x8
+#define AD7291_AUTOCYCLE BIT(0)
+#define AD7291_RESET BIT(1)
+#define AD7291_ALERT_CLEAR BIT(2)
+#define AD7291_ALERT_POLARITY BIT(3)
+#define AD7291_EXT_REF BIT(4)
+#define AD7291_NOISE_DELAY BIT(5)
+#define AD7291_T_SENSE_MASK BIT(7)
+#define AD7291_VOLTAGE_MASK GENMASK(15, 8)
+#define AD7291_VOLTAGE_OFFSET 8
/*
* AD7291 value masks
*/
-#define AD7291_CHANNEL_MASK 0xF000
-#define AD7291_BITS 12
-#define AD7291_VALUE_MASK 0xFFF
-#define AD7291_T_VALUE_SIGN 0x400
-#define AD7291_T_VALUE_FLOAT_OFFSET 2
-#define AD7291_T_VALUE_FLOAT_MASK 0x2
+#define AD7291_VALUE_MASK GENMASK(11, 0)
+
+/*
+ * AD7291 alert register bits
+ */
+#define AD7291_T_LOW BIT(0)
+#define AD7291_T_HIGH BIT(1)
+#define AD7291_T_AVG_LOW BIT(2)
+#define AD7291_T_AVG_HIGH BIT(3)
+#define AD7291_V_LOW(x) BIT((x) * 2)
+#define AD7291_V_HIGH(x) BIT((x) * 2 + 1)
-#define AD7291_BITS 12
struct ad7291_chip_info {
struct i2c_client *client;
@@ -129,14 +133,14 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
ad7291_i2c_write(chip, AD7291_COMMAND, command);
/* For now treat t_sense and t_sense_average the same */
- if ((t_status & (1 << 0)) || (t_status & (1 << 2)))
+ if ((t_status & AD7291_T_LOW) || (t_status & AD7291_T_AVG_LOW))
iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_TEMP,
0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_FALLING),
timestamp);
- if ((t_status & (1 << 1)) || (t_status & (1 << 3)))
+ if ((t_status & AD7291_T_HIGH) || (t_status & AD7291_T_AVG_HIGH))
iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_TEMP,
0,
@@ -144,18 +148,18 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
IIO_EV_DIR_RISING),
timestamp);
- for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
- if (v_status & (1 << i))
+ for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
+ if (v_status & AD7291_V_LOW(i))
iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- i/2,
+ i,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_FALLING),
timestamp);
- if (v_status & (1 << (i + 1)))
+ if (v_status & AD7291_V_HIGH(i))
iio_push_event(indio_dev,
IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
- i/2,
+ i,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_RISING),
timestamp);
@@ -165,7 +169,8 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
}
static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
- enum iio_event_direction dir, enum iio_event_info info)
+ enum iio_event_direction dir,
+ enum iio_event_info info)
{
unsigned int offset;
@@ -174,7 +179,7 @@ static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
offset = chan->channel;
break;
case IIO_TEMP:
- offset = 8;
+ offset = AD7291_VOLTAGE_OFFSET;
break;
default:
return 0;
@@ -182,14 +187,14 @@ static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
switch (info) {
case IIO_EV_INFO_VALUE:
- if (dir == IIO_EV_DIR_FALLING)
- return AD7291_DATA_HIGH(offset);
- else
- return AD7291_DATA_LOW(offset);
+ if (dir == IIO_EV_DIR_FALLING)
+ return AD7291_DATA_HIGH(offset);
+ else
+ return AD7291_DATA_LOW(offset);
case IIO_EV_INFO_HYSTERESIS:
- return AD7291_HYST(offset);
+ return AD7291_HYST(offset);
default:
- break;
+ break;
}
return 0;
}
@@ -206,7 +211,7 @@ static int ad7291_read_event_value(struct iio_dev *indio_dev,
u16 uval;
ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
- &uval);
+ &uval);
if (ret < 0)
return ret;
@@ -237,7 +242,7 @@ static int ad7291_write_event_value(struct iio_dev *indio_dev,
}
return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
- val);
+ val);
}
static int ad7291_read_event_config(struct iio_dev *indio_dev,
@@ -246,15 +251,14 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
enum iio_event_direction dir)
{
struct ad7291_chip_info *chip = iio_priv(indio_dev);
- /* To be enabled the channel must simply be on. If any are enabled
- we are in continuous sampling mode */
+ /*
+ * To be enabled the channel must simply be on. If any are enabled
+ * we are in continuous sampling mode
+ */
switch (chan->type) {
case IIO_VOLTAGE:
- if (chip->c_mask & (1 << (15 - chan->channel)))
- return 1;
- else
- return 0;
+ return !!(chip->c_mask & BIT(15 - chan->channel));
case IIO_TEMP:
/* always on */
return 1;
@@ -336,7 +340,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
}
/* Enable this channel alone */
regval = chip->command & (~AD7291_VOLTAGE_MASK);
- regval |= 1 << (15 - chan->channel);
+ regval |= BIT(15 - chan->channel);
ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
if (ret < 0) {
mutex_unlock(&chip->state_lock);
@@ -344,7 +348,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
}
/* Read voltage */
ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_VOLTAGE);
+ AD7291_VOLTAGE);
if (ret < 0) {
mutex_unlock(&chip->state_lock);
return ret;
@@ -355,7 +359,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
case IIO_TEMP:
/* Assumes tsense bit of command register always set */
ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_T_SENSE);
+ AD7291_T_SENSE);
if (ret < 0)
return ret;
*val = sign_extend32(ret, 11);
@@ -365,7 +369,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
}
case IIO_CHAN_INFO_AVERAGE_RAW:
ret = i2c_smbus_read_word_swapped(chip->client,
- AD7291_T_AVERAGE);
+ AD7291_T_AVERAGE);
if (ret < 0)
return ret;
*val = sign_extend32(ret, 11);
@@ -375,6 +379,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
case IIO_VOLTAGE:
if (chip->reg) {
int vref;
+
vref = regulator_get_voltage(chip->reg);
if (vref < 0)
return vref;
@@ -460,12 +465,12 @@ static const struct iio_info ad7291_info = {
};
static int ad7291_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct ad7291_platform_data *pdata = client->dev.platform_data;
struct ad7291_chip_info *chip;
struct iio_dev *indio_dev;
- int ret = 0;
+ int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
if (!indio_dev)
@@ -475,7 +480,7 @@ static int ad7291_probe(struct i2c_client *client,
if (pdata && pdata->use_external_ref) {
chip->reg = devm_regulator_get(&client->dev, "vref");
if (IS_ERR(chip->reg))
- return ret;
+ return PTR_ERR(chip->reg);
ret = regulator_enable(chip->reg);
if (ret)
diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c
index 2a3b65c74af9..4a8c0a2f49b6 100644
--- a/drivers/iio/adc/ad7298.c
+++ b/drivers/iio/adc/ad7298.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -25,23 +26,19 @@
#include <linux/platform_data/ad7298.h>
-#define AD7298_WRITE (1 << 15) /* write to the control register */
-#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */
-#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */
-#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */
-#define AD7298_EXTREF (1 << 2) /* external reference enable */
-#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */
-#define AD7298_PDD (1 << 0) /* partial power down enable */
+#define AD7298_WRITE BIT(15) /* write to the control register */
+#define AD7298_REPEAT BIT(14) /* repeated conversion enable */
+#define AD7298_CH(x) BIT(13 - (x)) /* channel select */
+#define AD7298_TSENSE BIT(5) /* temperature conversion enable */
+#define AD7298_EXTREF BIT(2) /* external reference enable */
+#define AD7298_TAVG BIT(1) /* temperature sensor averaging enable */
+#define AD7298_PDD BIT(0) /* partial power down enable */
#define AD7298_MAX_CHAN 8
-#define AD7298_BITS 12
-#define AD7298_STORAGE_BITS 16
#define AD7298_INTREF_mV 2500
#define AD7298_CH_TEMP 9
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
struct ad7298_state {
struct spi_device *spi;
struct regulator *reg;
@@ -257,7 +254,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev,
return ret;
if (chan->address != AD7298_CH_TEMP)
- *val = ret & RES_MASK(AD7298_BITS);
+ *val = ret & GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c
index d141d452c3d1..ce400ec176f1 100644
--- a/drivers/iio/adc/ad7476.c
+++ b/drivers/iio/adc/ad7476.c
@@ -14,6 +14,7 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -21,8 +22,6 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
struct ad7476_state;
struct ad7476_chip_info {
@@ -117,7 +116,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
- RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+ GENMASK(st->chip_info->channel[0].scan_type.realbits - 1, 0);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (!st->chip_info->int_vref_uv) {
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index 749a6cadab8b..2fd012ee99f5 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -25,14 +26,14 @@
#include <linux/platform_data/ad7887.h>
-#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
-#define AD7887_DUAL (1 << 4) /* dual-channel mode */
-#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
-#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
-#define AD7887_PM_MODE1 (0) /* CS based shutdown */
-#define AD7887_PM_MODE2 (1) /* full on */
-#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
-#define AD7887_PM_MODE4 (3) /* standby mode */
+#define AD7887_REF_DIS BIT(5) /* on-chip reference disable */
+#define AD7887_DUAL BIT(4) /* dual-channel mode */
+#define AD7887_CH_AIN1 BIT(3) /* convert on channel 1, DUAL=1 */
+#define AD7887_CH_AIN0 0 /* convert on channel 0, DUAL=0,1 */
+#define AD7887_PM_MODE1 0 /* CS based shutdown */
+#define AD7887_PM_MODE2 1 /* full on */
+#define AD7887_PM_MODE3 2 /* auto shutdown after conversion */
+#define AD7887_PM_MODE4 3 /* standby mode */
enum ad7887_channels {
AD7887_CH0,
@@ -40,8 +41,6 @@ enum ad7887_channels {
AD7887_CH1,
};
-#define RES_MASK(bits) ((1 << (bits)) - 1)
-
/**
* struct ad7887_chip_info - chip specifc information
* @int_vref_mv: the internal reference voltage
@@ -167,7 +166,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
*val = ret >> chan->scan_type.shift;
- *val &= RES_MASK(chan->scan_type.realbits);
+ *val &= GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (st->reg) {
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
index 39b4cb48d738..e37412da15f5 100644
--- a/drivers/iio/adc/ad799x.c
+++ b/drivers/iio/adc/ad799x.c
@@ -32,6 +32,7 @@
#include <linux/types.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@@ -41,7 +42,7 @@
#include <linux/iio/triggered_buffer.h>
#define AD799X_CHANNEL_SHIFT 4
-#define AD799X_STORAGEBITS 16
+
/*
* AD7991, AD7995 and AD7999 defines
*/
@@ -55,10 +56,10 @@
* AD7992, AD7993, AD7994, AD7997 and AD7998 defines
*/
-#define AD7998_FLTR 0x08
-#define AD7998_ALERT_EN 0x04
-#define AD7998_BUSY_ALERT 0x02
-#define AD7998_BUSY_ALERT_POL 0x01
+#define AD7998_FLTR BIT(3)
+#define AD7998_ALERT_EN BIT(2)
+#define AD7998_BUSY_ALERT BIT(1)
+#define AD7998_BUSY_ALERT_POL BIT(0)
#define AD7998_CONV_RES_REG 0x0
#define AD7998_ALERT_STAT_REG 0x1
@@ -69,7 +70,7 @@
#define AD7998_DATAHIGH_REG(x) ((x) * 3 + 0x5)
#define AD7998_HYST_REG(x) ((x) * 3 + 0x6)
-#define AD7998_CYC_MASK 0x7
+#define AD7998_CYC_MASK GENMASK(2, 0)
#define AD7998_CYC_DIS 0x0
#define AD7998_CYC_TCONF_32 0x1
#define AD7998_CYC_TCONF_64 0x2
@@ -85,10 +86,8 @@
* AD7997 and AD7997 defines
*/
-#define AD7997_8_READ_SINGLE 0x80
-#define AD7997_8_READ_SEQUENCE 0x70
-/* TODO: move this into a common header */
-#define RES_MASK(bits) ((1 << (bits)) - 1)
+#define AD7997_8_READ_SINGLE BIT(7)
+#define AD7997_8_READ_SEQUENCE (BIT(6) | BIT(5) | BIT(4))
enum {
ad7991,
@@ -102,23 +101,32 @@ enum {
};
/**
- * struct ad799x_chip_info - chip specific information
+ * struct ad799x_chip_config - chip specific information
* @channel: channel specification
- * @num_channels: number of channels
- * @monitor_mode: whether the chip supports monitor interrupts
* @default_config: device default configuration
- * @event_attrs: pointer to the monitor event attribute group
+ * @info: pointer to iio_info struct
*/
-struct ad799x_chip_info {
- struct iio_chan_spec channel[9];
- int num_channels;
+struct ad799x_chip_config {
+ const struct iio_chan_spec channel[9];
u16 default_config;
const struct iio_info *info;
};
+/**
+ * struct ad799x_chip_info - chip specific information
+ * @num_channels: number of channels
+ * @noirq_config: device configuration w/o IRQ
+ * @irq_config: device configuration w/IRQ
+ */
+struct ad799x_chip_info {
+ int num_channels;
+ const struct ad799x_chip_config noirq_config;
+ const struct ad799x_chip_config irq_config;
+};
+
struct ad799x_state {
struct i2c_client *client;
- const struct ad799x_chip_info *chip_info;
+ const struct ad799x_chip_config *chip_config;
struct regulator *reg;
struct regulator *vref;
unsigned id;
@@ -128,6 +136,30 @@ struct ad799x_state {
unsigned int transfer_size;
};
+static int ad799x_write_config(struct ad799x_state *st, u16 val)
+{
+ switch (st->id) {
+ case ad7997:
+ case ad7998:
+ return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG,
+ val);
+ default:
+ return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG,
+ val);
+ }
+}
+
+static int ad799x_read_config(struct ad799x_state *st)
+{
+ switch (st->id) {
+ case ad7997:
+ case ad7998:
+ return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG);
+ default:
+ return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG);
+ }
+}
+
/**
* ad799x_trigger_handler() bh of trigger launched polling to ring buffer
*
@@ -176,66 +208,7 @@ out:
return IRQ_HANDLED;
}
-/*
- * ad799x register access by I2C
- */
-static int ad799x_i2c_read16(struct ad799x_state *st, u8 reg, u16 *data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_read_word_swapped(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = (u16)ret;
-
- return 0;
-}
-
-static int ad799x_i2c_read8(struct ad799x_state *st, u8 reg, u8 *data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0) {
- dev_err(&client->dev, "I2C read error\n");
- return ret;
- }
-
- *data = (u8)ret;
-
- return 0;
-}
-
-static int ad799x_i2c_write16(struct ad799x_state *st, u8 reg, u16 data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_write_word_swapped(client, reg, data);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
-}
-
-static int ad799x_i2c_write8(struct ad799x_state *st, u8 reg, u8 data)
-{
- struct i2c_client *client = st->client;
- int ret = 0;
-
- ret = i2c_smbus_write_byte_data(client, reg, data);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
-}
-
-static int ad7997_8_update_scan_mode(struct iio_dev *indio_dev,
+static int ad799x_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct ad799x_state *st = iio_priv(indio_dev);
@@ -248,33 +221,33 @@ static int ad7997_8_update_scan_mode(struct iio_dev *indio_dev,
st->transfer_size = bitmap_weight(scan_mask, indio_dev->masklength) * 2;
switch (st->id) {
+ case ad7992:
+ case ad7993:
+ case ad7994:
case ad7997:
case ad7998:
- return ad799x_i2c_write16(st, AD7998_CONF_REG,
- st->config | (*scan_mask << AD799X_CHANNEL_SHIFT));
+ st->config &= ~(GENMASK(7, 0) << AD799X_CHANNEL_SHIFT);
+ st->config |= (*scan_mask << AD799X_CHANNEL_SHIFT);
+ return ad799x_write_config(st, st->config);
default:
- break;
+ return 0;
}
-
- return 0;
}
static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch)
{
- u16 rxbuf;
u8 cmd;
- int ret;
switch (st->id) {
case ad7991:
case ad7995:
case ad7999:
- cmd = st->config | ((1 << ch) << AD799X_CHANNEL_SHIFT);
+ cmd = st->config | (BIT(ch) << AD799X_CHANNEL_SHIFT);
break;
case ad7992:
case ad7993:
case ad7994:
- cmd = (1 << ch) << AD799X_CHANNEL_SHIFT;
+ cmd = BIT(ch) << AD799X_CHANNEL_SHIFT;
break;
case ad7997:
case ad7998:
@@ -284,11 +257,7 @@ static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch)
return -EINVAL;
}
- ret = ad799x_i2c_read16(st, cmd, &rxbuf);
- if (ret < 0)
- return ret;
-
- return rxbuf;
+ return i2c_smbus_read_word_swapped(st->client, cmd);
}
static int ad799x_read_raw(struct iio_dev *indio_dev,
@@ -312,7 +281,7 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
*val = (ret >> chan->scan_type.shift) &
- RES_MASK(chan->scan_type.realbits);
+ GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = regulator_get_voltage(st->vref);
@@ -333,6 +302,7 @@ static const unsigned int ad7998_frequencies[] = {
[AD7998_CYC_TCONF_1024] = 488,
[AD7998_CYC_TCONF_2048] = 244,
};
+
static ssize_t ad799x_read_frequency(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -340,15 +310,11 @@ static ssize_t ad799x_read_frequency(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad799x_state *st = iio_priv(indio_dev);
- int ret;
- u8 val;
- ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &val);
- if (ret)
+ int ret = i2c_smbus_read_byte_data(st->client, AD7998_CYCLE_TMR_REG);
+ if (ret < 0)
return ret;
- val &= AD7998_CYC_MASK;
-
- return sprintf(buf, "%u\n", ad7998_frequencies[val]);
+ return sprintf(buf, "%u\n", ad7998_frequencies[ret & AD7998_CYC_MASK]);
}
static ssize_t ad799x_write_frequency(struct device *dev,
@@ -361,18 +327,17 @@ static ssize_t ad799x_write_frequency(struct device *dev,
long val;
int ret, i;
- u8 t;
ret = kstrtol(buf, 10, &val);
if (ret)
return ret;
mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_read8(st, AD7998_CYCLE_TMR_REG, &t);
- if (ret)
+ ret = i2c_smbus_read_byte_data(st->client, AD7998_CYCLE_TMR_REG);
+ if (ret < 0)
goto error_ret_mutex;
/* Wipe the bits clean */
- t &= ~AD7998_CYC_MASK;
+ ret &= ~AD7998_CYC_MASK;
for (i = 0; i < ARRAY_SIZE(ad7998_frequencies); i++)
if (val == ad7998_frequencies[i])
@@ -381,13 +346,17 @@ static ssize_t ad799x_write_frequency(struct device *dev,
ret = -EINVAL;
goto error_ret_mutex;
}
- t |= i;
- ret = ad799x_i2c_write8(st, AD7998_CYCLE_TMR_REG, t);
+
+ ret = i2c_smbus_write_byte_data(st->client, AD7998_CYCLE_TMR_REG,
+ ret | i);
+ if (ret < 0)
+ goto error_ret_mutex;
+ ret = len;
error_ret_mutex:
mutex_unlock(&indio_dev->mlock);
- return ret ? ret : len;
+ return ret;
}
static int ad799x_read_event_config(struct iio_dev *indio_dev,
@@ -395,7 +364,48 @@ static int ad799x_read_event_config(struct iio_dev *indio_dev,
enum iio_event_type type,
enum iio_event_direction dir)
{
- return 1;
+ struct ad799x_state *st = iio_priv(indio_dev);
+
+ if (!(st->config & AD7998_ALERT_EN))
+ return 0;
+
+ if ((st->config >> AD799X_CHANNEL_SHIFT) & BIT(chan->scan_index))
+ return 1;
+
+ return 0;
+}
+
+static int ad799x_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 ad799x_state *st = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&indio_dev->mlock);
+ if (iio_buffer_enabled(indio_dev)) {
+ ret = -EBUSY;
+ goto done;
+ }
+
+ if (state)
+ st->config |= BIT(chan->scan_index) << AD799X_CHANNEL_SHIFT;
+ else
+ st->config &= ~(BIT(chan->scan_index) << AD799X_CHANNEL_SHIFT);
+
+ if (st->config >> AD799X_CHANNEL_SHIFT)
+ st->config |= AD7998_ALERT_EN;
+ else
+ st->config &= ~AD7998_ALERT_EN;
+
+ ret = ad799x_write_config(st, st->config);
+
+done:
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret;
}
static unsigned int ad799x_threshold_reg(const struct iio_chan_spec *chan,
@@ -427,9 +437,13 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev,
int ret;
struct ad799x_state *st = iio_priv(indio_dev);
+ if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
+ return -EINVAL;
+
mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_write16(st, ad799x_threshold_reg(chan, dir, info),
- val);
+ ret = i2c_smbus_write_word_swapped(st->client,
+ ad799x_threshold_reg(chan, dir, info),
+ val << chan->scan_type.shift);
mutex_unlock(&indio_dev->mlock);
return ret;
@@ -444,15 +458,15 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev,
{
int ret;
struct ad799x_state *st = iio_priv(indio_dev);
- u16 valin;
mutex_lock(&indio_dev->mlock);
- ret = ad799x_i2c_read16(st, ad799x_threshold_reg(chan, dir, info),
- &valin);
+ ret = i2c_smbus_read_word_swapped(st->client,
+ ad799x_threshold_reg(chan, dir, info));
mutex_unlock(&indio_dev->mlock);
if (ret < 0)
return ret;
- *val = valin;
+ *val = (ret >> chan->scan_type.shift) &
+ GENMASK(chan->scan_type.realbits - 1 , 0);
return IIO_VAL_INT;
}
@@ -461,20 +475,18 @@ static irqreturn_t ad799x_event_handler(int irq, void *private)
{
struct iio_dev *indio_dev = private;
struct ad799x_state *st = iio_priv(private);
- u8 status;
int i, ret;
- ret = ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status);
- if (ret)
+ ret = i2c_smbus_read_byte_data(st->client, AD7998_ALERT_STAT_REG);
+ if (ret <= 0)
goto done;
- if (!status)
+ if (i2c_smbus_write_byte_data(st->client, AD7998_ALERT_STAT_REG,
+ AD7998_ALERT_STAT_CLEAR) < 0)
goto done;
- ad799x_i2c_write8(st, AD7998_ALERT_STAT_REG, AD7998_ALERT_STAT_CLEAR);
-
for (i = 0; i < 8; i++) {
- if (status & (1 << i))
+ if (ret & BIT(i))
iio_push_event(indio_dev,
i & 0x1 ?
IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
@@ -513,14 +525,21 @@ static const struct iio_info ad7991_info = {
.driver_module = THIS_MODULE,
};
-static const struct iio_info ad7993_4_7_8_info = {
+static const struct iio_info ad7993_4_7_8_noirq_info = {
+ .read_raw = &ad799x_read_raw,
+ .driver_module = THIS_MODULE,
+ .update_scan_mode = ad799x_update_scan_mode,
+};
+
+static const struct iio_info ad7993_4_7_8_irq_info = {
.read_raw = &ad799x_read_raw,
.event_attrs = &ad799x_event_attrs_group,
.read_event_config = &ad799x_read_event_config,
+ .write_event_config = &ad799x_write_event_config,
.read_event_value = &ad799x_read_event_value,
.write_event_value = &ad799x_write_event_value,
.driver_module = THIS_MODULE,
- .update_scan_mode = ad7997_8_update_scan_mode,
+ .update_scan_mode = ad799x_update_scan_mode,
};
static const struct iio_event_spec ad799x_events[] = {
@@ -568,103 +587,175 @@ static const struct iio_event_spec ad799x_events[] = {
static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
[ad7991] = {
- .channel = {
- AD799X_CHANNEL(0, 12),
- AD799X_CHANNEL(1, 12),
- AD799X_CHANNEL(2, 12),
- AD799X_CHANNEL(3, 12),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
.num_channels = 5,
- .info = &ad7991_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 12),
+ AD799X_CHANNEL(1, 12),
+ AD799X_CHANNEL(2, 12),
+ AD799X_CHANNEL(3, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .info = &ad7991_info,
+ },
},
[ad7995] = {
- .channel = {
- AD799X_CHANNEL(0, 10),
- AD799X_CHANNEL(1, 10),
- AD799X_CHANNEL(2, 10),
- AD799X_CHANNEL(3, 10),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
.num_channels = 5,
- .info = &ad7991_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 10),
+ AD799X_CHANNEL(1, 10),
+ AD799X_CHANNEL(2, 10),
+ AD799X_CHANNEL(3, 10),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .info = &ad7991_info,
+ },
},
[ad7999] = {
- .channel = {
- AD799X_CHANNEL(0, 8),
- AD799X_CHANNEL(1, 8),
- AD799X_CHANNEL(2, 8),
- AD799X_CHANNEL(3, 8),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
.num_channels = 5,
- .info = &ad7991_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 8),
+ AD799X_CHANNEL(1, 8),
+ AD799X_CHANNEL(2, 8),
+ AD799X_CHANNEL(3, 8),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .info = &ad7991_info,
+ },
},
[ad7992] = {
- .channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
- IIO_CHAN_SOFT_TIMESTAMP(3),
- },
.num_channels = 3,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 12),
+ AD799X_CHANNEL(1, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+ },
+ .info = &ad7993_4_7_8_noirq_info,
+ },
+ .irq_config = {
+ .channel = {
+ AD799X_CHANNEL_WITH_EVENTS(0, 12),
+ AD799X_CHANNEL_WITH_EVENTS(1, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+ },
+ .default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT,
+ .info = &ad7993_4_7_8_irq_info,
+ },
},
[ad7993] = {
- .channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 10),
- AD799X_CHANNEL_WITH_EVENTS(1, 10),
- AD799X_CHANNEL_WITH_EVENTS(2, 10),
- AD799X_CHANNEL_WITH_EVENTS(3, 10),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
.num_channels = 5,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 10),
+ AD799X_CHANNEL(1, 10),
+ AD799X_CHANNEL(2, 10),
+ AD799X_CHANNEL(3, 10),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .info = &ad7993_4_7_8_noirq_info,
+ },
+ .irq_config = {
+ .channel = {
+ AD799X_CHANNEL_WITH_EVENTS(0, 10),
+ AD799X_CHANNEL_WITH_EVENTS(1, 10),
+ AD799X_CHANNEL_WITH_EVENTS(2, 10),
+ AD799X_CHANNEL_WITH_EVENTS(3, 10),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT,
+ .info = &ad7993_4_7_8_irq_info,
+ },
},
[ad7994] = {
- .channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
- AD799X_CHANNEL_WITH_EVENTS(2, 12),
- AD799X_CHANNEL_WITH_EVENTS(3, 12),
- IIO_CHAN_SOFT_TIMESTAMP(4),
- },
.num_channels = 5,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 12),
+ AD799X_CHANNEL(1, 12),
+ AD799X_CHANNEL(2, 12),
+ AD799X_CHANNEL(3, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .info = &ad7993_4_7_8_noirq_info,
+ },
+ .irq_config = {
+ .channel = {
+ AD799X_CHANNEL_WITH_EVENTS(0, 12),
+ AD799X_CHANNEL_WITH_EVENTS(1, 12),
+ AD799X_CHANNEL_WITH_EVENTS(2, 12),
+ AD799X_CHANNEL_WITH_EVENTS(3, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+ },
+ .default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT,
+ .info = &ad7993_4_7_8_irq_info,
+ },
},
[ad7997] = {
- .channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 10),
- AD799X_CHANNEL_WITH_EVENTS(1, 10),
- AD799X_CHANNEL_WITH_EVENTS(2, 10),
- AD799X_CHANNEL_WITH_EVENTS(3, 10),
- AD799X_CHANNEL(4, 10),
- AD799X_CHANNEL(5, 10),
- AD799X_CHANNEL(6, 10),
- AD799X_CHANNEL(7, 10),
- IIO_CHAN_SOFT_TIMESTAMP(8),
- },
.num_channels = 9,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 10),
+ AD799X_CHANNEL(1, 10),
+ AD799X_CHANNEL(2, 10),
+ AD799X_CHANNEL(3, 10),
+ AD799X_CHANNEL(4, 10),
+ AD799X_CHANNEL(5, 10),
+ AD799X_CHANNEL(6, 10),
+ AD799X_CHANNEL(7, 10),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ },
+ .info = &ad7993_4_7_8_noirq_info,
+ },
+ .irq_config = {
+ .channel = {
+ AD799X_CHANNEL_WITH_EVENTS(0, 10),
+ AD799X_CHANNEL_WITH_EVENTS(1, 10),
+ AD799X_CHANNEL_WITH_EVENTS(2, 10),
+ AD799X_CHANNEL_WITH_EVENTS(3, 10),
+ AD799X_CHANNEL(4, 10),
+ AD799X_CHANNEL(5, 10),
+ AD799X_CHANNEL(6, 10),
+ AD799X_CHANNEL(7, 10),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ },
+ .default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT,
+ .info = &ad7993_4_7_8_irq_info,
+ },
},
[ad7998] = {
- .channel = {
- AD799X_CHANNEL_WITH_EVENTS(0, 12),
- AD799X_CHANNEL_WITH_EVENTS(1, 12),
- AD799X_CHANNEL_WITH_EVENTS(2, 12),
- AD799X_CHANNEL_WITH_EVENTS(3, 12),
- AD799X_CHANNEL(4, 12),
- AD799X_CHANNEL(5, 12),
- AD799X_CHANNEL(6, 12),
- AD799X_CHANNEL(7, 12),
- IIO_CHAN_SOFT_TIMESTAMP(8),
- },
.num_channels = 9,
- .default_config = AD7998_ALERT_EN,
- .info = &ad7993_4_7_8_info,
+ .noirq_config = {
+ .channel = {
+ AD799X_CHANNEL(0, 12),
+ AD799X_CHANNEL(1, 12),
+ AD799X_CHANNEL(2, 12),
+ AD799X_CHANNEL(3, 12),
+ AD799X_CHANNEL(4, 12),
+ AD799X_CHANNEL(5, 12),
+ AD799X_CHANNEL(6, 12),
+ AD799X_CHANNEL(7, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ },
+ .info = &ad7993_4_7_8_noirq_info,
+ },
+ .irq_config = {
+ .channel = {
+ AD799X_CHANNEL_WITH_EVENTS(0, 12),
+ AD799X_CHANNEL_WITH_EVENTS(1, 12),
+ AD799X_CHANNEL_WITH_EVENTS(2, 12),
+ AD799X_CHANNEL_WITH_EVENTS(3, 12),
+ AD799X_CHANNEL(4, 12),
+ AD799X_CHANNEL(5, 12),
+ AD799X_CHANNEL(6, 12),
+ AD799X_CHANNEL(7, 12),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+ },
+ .default_config = AD7998_ALERT_EN | AD7998_BUSY_ALERT,
+ .info = &ad7993_4_7_8_irq_info,
+ },
},
};
@@ -674,6 +765,8 @@ static int ad799x_probe(struct i2c_client *client,
int ret;
struct ad799x_state *st;
struct iio_dev *indio_dev;
+ const struct ad799x_chip_info *chip_info =
+ &ad799x_chip_info_tbl[id->driver_data];
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL)
@@ -684,8 +777,10 @@ static int ad799x_probe(struct i2c_client *client,
i2c_set_clientdata(client, indio_dev);
st->id = id->driver_data;
- st->chip_info = &ad799x_chip_info_tbl[st->id];
- st->config = st->chip_info->default_config;
+ if (client->irq > 0 && chip_info->irq_config.info)
+ st->chip_config = &chip_info->irq_config;
+ else
+ st->chip_config = &chip_info->noirq_config;
/* TODO: Add pdata options for filtering and bit delay */
@@ -708,11 +803,19 @@ static int ad799x_probe(struct i2c_client *client,
indio_dev->dev.parent = &client->dev;
indio_dev->name = id->name;
- indio_dev->info = st->chip_info->info;
+ indio_dev->info = st->chip_config->info;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = st->chip_info->channel;
- indio_dev->num_channels = st->chip_info->num_channels;
+ indio_dev->channels = st->chip_config->channel;
+ indio_dev->num_channels = chip_info->num_channels;
+
+ ret = ad799x_write_config(st, st->chip_config->default_config);
+ if (ret < 0)
+ goto error_disable_reg;
+ ret = ad799x_read_config(st);
+ if (ret < 0)
+ goto error_disable_reg;
+ st->config = ret;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&ad799x_trigger_handler, NULL);
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index 9a4e0e32a771..c55b81f7f970 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -410,7 +410,7 @@ static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
complete(&sigma_delta->completion);
disable_irq_nosync(irq);
sigma_delta->irq_dis = true;
- iio_trigger_poll(sigma_delta->trig, iio_get_time_ns());
+ iio_trigger_poll(sigma_delta->trig);
return IRQ_HANDLED;
}
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 2b6a9ce9927c..772e869c280e 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -272,7 +272,7 @@ void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
if (iio_buffer_enabled(idev)) {
disable_irq_nosync(irq);
- iio_trigger_poll(idev->trig, iio_get_time_ns());
+ iio_trigger_poll(idev->trig);
} else {
st->last_value = at91_adc_readl(st, AT91_ADC_LCDR);
st->done = true;
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 010578f1d762..fc9dfc23ecb7 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/io.h>
@@ -39,11 +40,6 @@
#include <linux/iio/machine.h>
#include <linux/iio/driver.h>
-enum adc_version {
- ADC_V1,
- ADC_V2
-};
-
/* EXYNOS4412/5250 ADC_V1 registers definitions */
#define ADC_V1_CON(x) ((x) + 0x00)
#define ADC_V1_DLY(x) ((x) + 0x08)
@@ -75,8 +71,9 @@ enum adc_version {
#define ADC_V2_CON2_ACH_SEL(x) (((x) & 0xF) << 0)
#define ADC_V2_CON2_ACH_MASK 0xF
-#define MAX_ADC_V2_CHANNELS 10
-#define MAX_ADC_V1_CHANNELS 8
+#define MAX_ADC_V2_CHANNELS 10
+#define MAX_ADC_V1_CHANNELS 8
+#define MAX_EXYNOS3250_ADC_CHANNELS 2
/* Bit definitions common for ADC_V1 and ADC_V2 */
#define ADC_CON_EN_START (1u << 0)
@@ -85,9 +82,12 @@ enum adc_version {
#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100))
struct exynos_adc {
+ struct exynos_adc_data *data;
+ struct device *dev;
void __iomem *regs;
void __iomem *enable_reg;
struct clk *clk;
+ struct clk *sclk;
unsigned int irq;
struct regulator *vdd;
@@ -97,43 +97,213 @@ struct exynos_adc {
unsigned int version;
};
-static const struct of_device_id exynos_adc_match[] = {
- { .compatible = "samsung,exynos-adc-v1", .data = (void *)ADC_V1 },
- { .compatible = "samsung,exynos-adc-v2", .data = (void *)ADC_V2 },
- {},
+struct exynos_adc_data {
+ int num_channels;
+ bool needs_sclk;
+
+ void (*init_hw)(struct exynos_adc *info);
+ void (*exit_hw)(struct exynos_adc *info);
+ void (*clear_irq)(struct exynos_adc *info);
+ void (*start_conv)(struct exynos_adc *info, unsigned long addr);
};
-MODULE_DEVICE_TABLE(of, exynos_adc_match);
-static inline unsigned int exynos_adc_get_version(struct platform_device *pdev)
+static void exynos_adc_unprepare_clk(struct exynos_adc *info)
{
- const struct of_device_id *match;
+ if (info->data->needs_sclk)
+ clk_unprepare(info->sclk);
+ clk_unprepare(info->clk);
+}
- match = of_match_node(exynos_adc_match, pdev->dev.of_node);
- return (unsigned int)match->data;
+static int exynos_adc_prepare_clk(struct exynos_adc *info)
+{
+ int ret;
+
+ ret = clk_prepare(info->clk);
+ if (ret) {
+ dev_err(info->dev, "failed preparing adc clock: %d\n", ret);
+ return ret;
+ }
+
+ if (info->data->needs_sclk) {
+ ret = clk_prepare(info->sclk);
+ if (ret) {
+ clk_unprepare(info->clk);
+ dev_err(info->dev,
+ "failed preparing sclk_adc clock: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void exynos_adc_disable_clk(struct exynos_adc *info)
+{
+ if (info->data->needs_sclk)
+ clk_disable(info->sclk);
+ clk_disable(info->clk);
+}
+
+static int exynos_adc_enable_clk(struct exynos_adc *info)
+{
+ int ret;
+
+ ret = clk_enable(info->clk);
+ if (ret) {
+ dev_err(info->dev, "failed enabling adc clock: %d\n", ret);
+ return ret;
+ }
+
+ if (info->data->needs_sclk) {
+ ret = clk_enable(info->sclk);
+ if (ret) {
+ clk_disable(info->clk);
+ dev_err(info->dev,
+ "failed enabling sclk_adc clock: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void exynos_adc_v1_init_hw(struct exynos_adc *info)
+{
+ u32 con1;
+
+ writel(1, info->enable_reg);
+
+ /* set default prescaler values and Enable prescaler */
+ con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+
+ /* Enable 12-bit ADC resolution */
+ con1 |= ADC_V1_CON_RES;
+ writel(con1, ADC_V1_CON(info->regs));
+}
+
+static void exynos_adc_v1_exit_hw(struct exynos_adc *info)
+{
+ u32 con;
+
+ writel(0, info->enable_reg);
+
+ con = readl(ADC_V1_CON(info->regs));
+ con |= ADC_V1_CON_STANDBY;
+ writel(con, ADC_V1_CON(info->regs));
+}
+
+static void exynos_adc_v1_clear_irq(struct exynos_adc *info)
+{
+ writel(1, ADC_V1_INTCLR(info->regs));
+}
+
+static void exynos_adc_v1_start_conv(struct exynos_adc *info,
+ unsigned long addr)
+{
+ u32 con1;
+
+ writel(addr, ADC_V1_MUX(info->regs));
+
+ con1 = readl(ADC_V1_CON(info->regs));
+ writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs));
+}
+
+static const struct exynos_adc_data exynos_adc_v1_data = {
+ .num_channels = MAX_ADC_V1_CHANNELS,
+
+ .init_hw = exynos_adc_v1_init_hw,
+ .exit_hw = exynos_adc_v1_exit_hw,
+ .clear_irq = exynos_adc_v1_clear_irq,
+ .start_conv = exynos_adc_v1_start_conv,
+};
+
+static void exynos_adc_v2_init_hw(struct exynos_adc *info)
+{
+ u32 con1, con2;
+
+ writel(1, info->enable_reg);
+
+ con1 = ADC_V2_CON1_SOFT_RESET;
+ writel(con1, ADC_V2_CON1(info->regs));
+
+ con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
+ ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ /* Enable interrupts */
+ writel(1, ADC_V2_INT_EN(info->regs));
+}
+
+static void exynos_adc_v2_exit_hw(struct exynos_adc *info)
+{
+ u32 con;
+
+ writel(0, info->enable_reg);
+
+ con = readl(ADC_V2_CON1(info->regs));
+ con &= ~ADC_CON_EN_START;
+ writel(con, ADC_V2_CON1(info->regs));
}
-static void exynos_adc_hw_init(struct exynos_adc *info)
+static void exynos_adc_v2_clear_irq(struct exynos_adc *info)
+{
+ writel(1, ADC_V2_INT_ST(info->regs));
+}
+
+static void exynos_adc_v2_start_conv(struct exynos_adc *info,
+ unsigned long addr)
{
u32 con1, con2;
- if (info->version == ADC_V2) {
- con1 = ADC_V2_CON1_SOFT_RESET;
- writel(con1, ADC_V2_CON1(info->regs));
+ con2 = readl(ADC_V2_CON2(info->regs));
+ con2 &= ~ADC_V2_CON2_ACH_MASK;
+ con2 |= ADC_V2_CON2_ACH_SEL(addr);
+ writel(con2, ADC_V2_CON2(info->regs));
- con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
- ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
- writel(con2, ADC_V2_CON2(info->regs));
+ con1 = readl(ADC_V2_CON1(info->regs));
+ writel(con1 | ADC_CON_EN_START, ADC_V2_CON1(info->regs));
+}
- /* Enable interrupts */
- writel(1, ADC_V2_INT_EN(info->regs));
- } else {
- /* set default prescaler values and Enable prescaler */
- con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+static const struct exynos_adc_data exynos_adc_v2_data = {
+ .num_channels = MAX_ADC_V2_CHANNELS,
- /* Enable 12-bit ADC resolution */
- con1 |= ADC_V1_CON_RES;
- writel(con1, ADC_V1_CON(info->regs));
- }
+ .init_hw = exynos_adc_v2_init_hw,
+ .exit_hw = exynos_adc_v2_exit_hw,
+ .clear_irq = exynos_adc_v2_clear_irq,
+ .start_conv = exynos_adc_v2_start_conv,
+};
+
+static const struct exynos_adc_data exynos3250_adc_data = {
+ .num_channels = MAX_EXYNOS3250_ADC_CHANNELS,
+ .needs_sclk = true,
+
+ .init_hw = exynos_adc_v2_init_hw,
+ .exit_hw = exynos_adc_v2_exit_hw,
+ .clear_irq = exynos_adc_v2_clear_irq,
+ .start_conv = exynos_adc_v2_start_conv,
+};
+
+static const struct of_device_id exynos_adc_match[] = {
+ {
+ .compatible = "samsung,exynos-adc-v1",
+ .data = &exynos_adc_v1_data,
+ }, {
+ .compatible = "samsung,exynos-adc-v2",
+ .data = &exynos_adc_v2_data,
+ }, {
+ .compatible = "samsung,exynos3250-adc",
+ .data = &exynos3250_adc_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_adc_match);
+
+static struct exynos_adc_data *exynos_adc_get_data(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+
+ match = of_match_node(exynos_adc_match, pdev->dev.of_node);
+ return (struct exynos_adc_data *)match->data;
}
static int exynos_read_raw(struct iio_dev *indio_dev,
@@ -144,7 +314,6 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
{
struct exynos_adc *info = iio_priv(indio_dev);
unsigned long timeout;
- u32 con1, con2;
int ret;
if (mask != IIO_CHAN_INFO_RAW)
@@ -154,28 +323,15 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
reinit_completion(&info->completion);
/* Select the channel to be used and Trigger conversion */
- if (info->version == ADC_V2) {
- con2 = readl(ADC_V2_CON2(info->regs));
- con2 &= ~ADC_V2_CON2_ACH_MASK;
- con2 |= ADC_V2_CON2_ACH_SEL(chan->address);
- writel(con2, ADC_V2_CON2(info->regs));
-
- con1 = readl(ADC_V2_CON1(info->regs));
- writel(con1 | ADC_CON_EN_START,
- ADC_V2_CON1(info->regs));
- } else {
- writel(chan->address, ADC_V1_MUX(info->regs));
-
- con1 = readl(ADC_V1_CON(info->regs));
- writel(con1 | ADC_CON_EN_START,
- ADC_V1_CON(info->regs));
- }
+ if (info->data->start_conv)
+ info->data->start_conv(info, chan->address);
timeout = wait_for_completion_timeout
(&info->completion, EXYNOS_ADC_TIMEOUT);
if (timeout == 0) {
dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");
- exynos_adc_hw_init(info);
+ if (info->data->init_hw)
+ info->data->init_hw(info);
ret = -ETIMEDOUT;
} else {
*val = info->value;
@@ -193,13 +349,11 @@ static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
struct exynos_adc *info = (struct exynos_adc *)dev_id;
/* Read value */
- info->value = readl(ADC_V1_DATX(info->regs)) &
- ADC_DATX_MASK;
+ info->value = readl(ADC_V1_DATX(info->regs)) & ADC_DATX_MASK;
+
/* clear irq */
- if (info->version == ADC_V2)
- writel(1, ADC_V2_INT_ST(info->regs));
- else
- writel(1, ADC_V1_INTCLR(info->regs));
+ if (info->data->clear_irq)
+ info->data->clear_irq(info);
complete(&info->completion);
@@ -277,6 +431,12 @@ static int exynos_adc_probe(struct platform_device *pdev)
info = iio_priv(indio_dev);
+ info->data = exynos_adc_get_data(pdev);
+ if (!info->data) {
+ dev_err(&pdev->dev, "failed getting exynos_adc_data\n");
+ return -EINVAL;
+ }
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(info->regs))
@@ -294,6 +454,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
}
info->irq = irq;
+ info->dev = &pdev->dev;
init_completion(&info->completion);
@@ -304,6 +465,16 @@ static int exynos_adc_probe(struct platform_device *pdev)
return PTR_ERR(info->clk);
}
+ if (info->data->needs_sclk) {
+ info->sclk = devm_clk_get(&pdev->dev, "sclk");
+ if (IS_ERR(info->sclk)) {
+ dev_err(&pdev->dev,
+ "failed getting sclk clock, err = %ld\n",
+ PTR_ERR(info->sclk));
+ return PTR_ERR(info->sclk);
+ }
+ }
+
info->vdd = devm_regulator_get(&pdev->dev, "vdd");
if (IS_ERR(info->vdd)) {
dev_err(&pdev->dev, "failed getting regulator, err = %ld\n",
@@ -315,13 +486,13 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = clk_prepare_enable(info->clk);
+ ret = exynos_adc_prepare_clk(info);
if (ret)
goto err_disable_reg;
- writel(1, info->enable_reg);
-
- info->version = exynos_adc_get_version(pdev);
+ ret = exynos_adc_enable_clk(info);
+ if (ret)
+ goto err_unprepare_clk;
platform_set_drvdata(pdev, indio_dev);
@@ -331,11 +502,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
indio_dev->info = &exynos_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = exynos_adc_iio_channels;
-
- if (info->version == ADC_V1)
- indio_dev->num_channels = MAX_ADC_V1_CHANNELS;
- else
- indio_dev->num_channels = MAX_ADC_V2_CHANNELS;
+ indio_dev->num_channels = info->data->num_channels;
ret = request_irq(info->irq, exynos_adc_isr,
0, dev_name(&pdev->dev), info);
@@ -349,7 +516,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
if (ret)
goto err_irq;
- exynos_adc_hw_init(info);
+ if (info->data->init_hw)
+ info->data->init_hw(info);
ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev);
if (ret < 0) {
@@ -366,8 +534,11 @@ err_of_populate:
err_irq:
free_irq(info->irq, info);
err_disable_clk:
- writel(0, info->enable_reg);
- clk_disable_unprepare(info->clk);
+ if (info->data->exit_hw)
+ info->data->exit_hw(info);
+ exynos_adc_disable_clk(info);
+err_unprepare_clk:
+ exynos_adc_unprepare_clk(info);
err_disable_reg:
regulator_disable(info->vdd);
return ret;
@@ -382,8 +553,10 @@ static int exynos_adc_remove(struct platform_device *pdev)
exynos_adc_remove_devices);
iio_device_unregister(indio_dev);
free_irq(info->irq, info);
- writel(0, info->enable_reg);
- clk_disable_unprepare(info->clk);
+ if (info->data->exit_hw)
+ info->data->exit_hw(info);
+ exynos_adc_disable_clk(info);
+ exynos_adc_unprepare_clk(info);
regulator_disable(info->vdd);
return 0;
@@ -394,20 +567,10 @@ static int exynos_adc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct exynos_adc *info = iio_priv(indio_dev);
- u32 con;
- if (info->version == ADC_V2) {
- con = readl(ADC_V2_CON1(info->regs));
- con &= ~ADC_CON_EN_START;
- writel(con, ADC_V2_CON1(info->regs));
- } else {
- con = readl(ADC_V1_CON(info->regs));
- con |= ADC_V1_CON_STANDBY;
- writel(con, ADC_V1_CON(info->regs));
- }
-
- writel(0, info->enable_reg);
- clk_disable_unprepare(info->clk);
+ if (info->data->exit_hw)
+ info->data->exit_hw(info);
+ exynos_adc_disable_clk(info);
regulator_disable(info->vdd);
return 0;
@@ -423,12 +586,12 @@ static int exynos_adc_resume(struct device *dev)
if (ret)
return ret;
- ret = clk_prepare_enable(info->clk);
+ ret = exynos_adc_enable_clk(info);
if (ret)
return ret;
- writel(1, info->enable_reg);
- exynos_adc_hw_init(info);
+ if (info->data->init_hw)
+ info->data->init_hw(info);
return 0;
}
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c
new file mode 100644
index 000000000000..87ee1c7d0b54
--- /dev/null
+++ b/drivers/iio/adc/max1027.c
@@ -0,0 +1,521 @@
+ /*
+ * iio/adc/max1027.c
+ * Copyright (C) 2014 Philippe Reynes
+ *
+ * based on linux/drivers/iio/ad7923.c
+ * Copyright 2011 Analog Devices Inc (from AD7923 Driver)
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * 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.
+ *
+ * max1027.c
+ *
+ * Partial support for max1027 and similar chips.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.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>
+
+#define MAX1027_CONV_REG BIT(7)
+#define MAX1027_SETUP_REG BIT(6)
+#define MAX1027_AVG_REG BIT(5)
+#define MAX1027_RST_REG BIT(4)
+
+/* conversion register */
+#define MAX1027_TEMP BIT(0)
+#define MAX1027_SCAN_0_N (0x00 << 1)
+#define MAX1027_SCAN_N_M (0x01 << 1)
+#define MAX1027_SCAN_N (0x02 << 1)
+#define MAX1027_NOSCAN (0x03 << 1)
+#define MAX1027_CHAN(n) ((n) << 3)
+
+/* setup register */
+#define MAX1027_UNIPOLAR 0x02
+#define MAX1027_BIPOLAR 0x03
+#define MAX1027_REF_MODE0 (0x00 << 2)
+#define MAX1027_REF_MODE1 (0x01 << 2)
+#define MAX1027_REF_MODE2 (0x02 << 2)
+#define MAX1027_REF_MODE3 (0x03 << 2)
+#define MAX1027_CKS_MODE0 (0x00 << 4)
+#define MAX1027_CKS_MODE1 (0x01 << 4)
+#define MAX1027_CKS_MODE2 (0x02 << 4)
+#define MAX1027_CKS_MODE3 (0x03 << 4)
+
+/* averaging register */
+#define MAX1027_NSCAN_4 0x00
+#define MAX1027_NSCAN_8 0x01
+#define MAX1027_NSCAN_12 0x02
+#define MAX1027_NSCAN_16 0x03
+#define MAX1027_NAVG_4 (0x00 << 2)
+#define MAX1027_NAVG_8 (0x01 << 2)
+#define MAX1027_NAVG_16 (0x02 << 2)
+#define MAX1027_NAVG_32 (0x03 << 2)
+#define MAX1027_AVG_EN BIT(4)
+
+enum max1027_id {
+ max1027,
+ max1029,
+ max1031,
+};
+
+static const struct spi_device_id max1027_id[] = {
+ {"max1027", max1027},
+ {"max1029", max1029},
+ {"max1031", max1031},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, max1027_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id max1027_adc_dt_ids[] = {
+ { .compatible = "maxim,max1027" },
+ { .compatible = "maxim,max1029" },
+ { .compatible = "maxim,max1031" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
+#endif
+
+#define MAX1027_V_CHAN(index) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = index + 1, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 10, \
+ .storagebits = 16, \
+ .shift = 2, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define MAX1027_T_CHAN \
+ { \
+ .type = IIO_TEMP, \
+ .channel = 0, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = 0, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+static const struct iio_chan_spec max1027_channels[] = {
+ MAX1027_T_CHAN,
+ MAX1027_V_CHAN(0),
+ MAX1027_V_CHAN(1),
+ MAX1027_V_CHAN(2),
+ MAX1027_V_CHAN(3),
+ MAX1027_V_CHAN(4),
+ MAX1027_V_CHAN(5),
+ MAX1027_V_CHAN(6),
+ MAX1027_V_CHAN(7)
+};
+
+static const struct iio_chan_spec max1029_channels[] = {
+ MAX1027_T_CHAN,
+ MAX1027_V_CHAN(0),
+ MAX1027_V_CHAN(1),
+ MAX1027_V_CHAN(2),
+ MAX1027_V_CHAN(3),
+ MAX1027_V_CHAN(4),
+ MAX1027_V_CHAN(5),
+ MAX1027_V_CHAN(6),
+ MAX1027_V_CHAN(7),
+ MAX1027_V_CHAN(8),
+ MAX1027_V_CHAN(9),
+ MAX1027_V_CHAN(10),
+ MAX1027_V_CHAN(11)
+};
+
+static const struct iio_chan_spec max1031_channels[] = {
+ MAX1027_T_CHAN,
+ MAX1027_V_CHAN(0),
+ MAX1027_V_CHAN(1),
+ MAX1027_V_CHAN(2),
+ MAX1027_V_CHAN(3),
+ MAX1027_V_CHAN(4),
+ MAX1027_V_CHAN(5),
+ MAX1027_V_CHAN(6),
+ MAX1027_V_CHAN(7),
+ MAX1027_V_CHAN(8),
+ MAX1027_V_CHAN(9),
+ MAX1027_V_CHAN(10),
+ MAX1027_V_CHAN(11),
+ MAX1027_V_CHAN(12),
+ MAX1027_V_CHAN(13),
+ MAX1027_V_CHAN(14),
+ MAX1027_V_CHAN(15)
+};
+
+static const unsigned long max1027_available_scan_masks[] = {
+ 0x000001ff,
+ 0x00000000,
+};
+
+static const unsigned long max1029_available_scan_masks[] = {
+ 0x00001fff,
+ 0x00000000,
+};
+
+static const unsigned long max1031_available_scan_masks[] = {
+ 0x0001ffff,
+ 0x00000000,
+};
+
+struct max1027_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+ const unsigned long *available_scan_masks;
+};
+
+static const struct max1027_chip_info max1027_chip_info_tbl[] = {
+ [max1027] = {
+ .channels = max1027_channels,
+ .num_channels = ARRAY_SIZE(max1027_channels),
+ .available_scan_masks = max1027_available_scan_masks,
+ },
+ [max1029] = {
+ .channels = max1029_channels,
+ .num_channels = ARRAY_SIZE(max1029_channels),
+ .available_scan_masks = max1029_available_scan_masks,
+ },
+ [max1031] = {
+ .channels = max1031_channels,
+ .num_channels = ARRAY_SIZE(max1031_channels),
+ .available_scan_masks = max1031_available_scan_masks,
+ },
+};
+
+struct max1027_state {
+ const struct max1027_chip_info *info;
+ struct spi_device *spi;
+ struct iio_trigger *trig;
+ __be16 *buffer;
+ struct mutex lock;
+
+ u8 reg ____cacheline_aligned;
+};
+
+static int max1027_read_single_value(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ int ret;
+ struct max1027_state *st = iio_priv(indio_dev);
+
+ if (iio_buffer_enabled(indio_dev)) {
+ dev_warn(&indio_dev->dev, "trigger mode already enabled");
+ return -EBUSY;
+ }
+
+ /* Start acquisition on conversion register write */
+ st->reg = MAX1027_SETUP_REG | MAX1027_REF_MODE2 | MAX1027_CKS_MODE2;
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev,
+ "Failed to configure setup register\n");
+ return ret;
+ }
+
+ /* Configure conversion register with the requested chan */
+ st->reg = MAX1027_CONV_REG | MAX1027_CHAN(chan->channel) |
+ MAX1027_NOSCAN | !!(chan->type == IIO_TEMP);
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev,
+ "Failed to configure conversion register\n");
+ return ret;
+ }
+
+ /*
+ * For an unknown reason, when we use the mode "10" (write
+ * conversion register), the interrupt doesn't occur every time.
+ * So we just wait 1 ms.
+ */
+ mdelay(1);
+
+ /* Read result */
+ ret = spi_read(st->spi, st->buffer, (chan->type == IIO_TEMP) ? 4 : 2);
+ if (ret < 0)
+ return ret;
+
+ *val = be16_to_cpu(st->buffer[0]);
+
+ return IIO_VAL_INT;
+}
+
+static int max1027_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ int ret = 0;
+ struct max1027_state *st = iio_priv(indio_dev);
+
+ mutex_lock(&st->lock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = max1027_read_single_value(indio_dev, chan, val);
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = 1;
+ *val2 = 8;
+ ret = IIO_VAL_FRACTIONAL;
+ break;
+ case IIO_VOLTAGE:
+ *val = 2500;
+ *val2 = 10;
+ ret = IIO_VAL_FRACTIONAL_LOG2;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&st->lock);
+
+ return ret;
+}
+
+static int max1027_debugfs_reg_access(struct iio_dev *indio_dev,
+ unsigned reg, unsigned writeval,
+ unsigned *readval)
+{
+ struct max1027_state *st = iio_priv(indio_dev);
+ u8 *val = (u8 *)st->buffer;
+
+ if (readval != NULL)
+ return -EINVAL;
+
+ *val = (u8)writeval;
+ return spi_write(st->spi, val, 1);
+}
+
+static int max1027_validate_trigger(struct iio_dev *indio_dev,
+ struct iio_trigger *trig)
+{
+ struct max1027_state *st = iio_priv(indio_dev);
+
+ if (st->trig != trig)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int max1027_set_trigger_state(struct iio_trigger *trig, bool state)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct max1027_state *st = iio_priv(indio_dev);
+ int ret;
+
+ if (state) {
+ /* Start acquisition on cnvst */
+ st->reg = MAX1027_SETUP_REG | MAX1027_CKS_MODE0 |
+ MAX1027_REF_MODE2;
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0)
+ return ret;
+
+ /* Scan from 0 to max */
+ st->reg = MAX1027_CONV_REG | MAX1027_CHAN(0) |
+ MAX1027_SCAN_N_M | MAX1027_TEMP;
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0)
+ return ret;
+ } else {
+ /* Start acquisition on conversion register write */
+ st->reg = MAX1027_SETUP_REG | MAX1027_CKS_MODE2 |
+ MAX1027_REF_MODE2;
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int max1027_validate_device(struct iio_trigger *trig,
+ struct iio_dev *indio_dev)
+{
+ struct iio_dev *indio = iio_trigger_get_drvdata(trig);
+
+ if (indio != indio_dev)
+ return -EINVAL;
+
+ return 0;
+}
+
+static irqreturn_t max1027_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = (struct iio_poll_func *)private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct max1027_state *st = iio_priv(indio_dev);
+
+ pr_debug("%s(irq=%d, private=0x%p)\n", __func__, irq, private);
+
+ /* fill buffer with all channel */
+ spi_read(st->spi, st->buffer, indio_dev->masklength * 2);
+
+ iio_push_to_buffers(indio_dev, st->buffer);
+
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_trigger_ops max1027_trigger_ops = {
+ .owner = THIS_MODULE,
+ .validate_device = &max1027_validate_device,
+ .set_trigger_state = &max1027_set_trigger_state,
+};
+
+static const struct iio_info max1027_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = &max1027_read_raw,
+ .validate_trigger = &max1027_validate_trigger,
+ .debugfs_reg_access = &max1027_debugfs_reg_access,
+};
+
+static int max1027_probe(struct spi_device *spi)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct max1027_state *st;
+
+ pr_debug("%s: probe(spi = 0x%p)\n", __func__, spi);
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (indio_dev == NULL) {
+ pr_err("Can't allocate iio device\n");
+ return -ENOMEM;
+ }
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st = iio_priv(indio_dev);
+ st->spi = spi;
+ st->info = &max1027_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+ mutex_init(&st->lock);
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->info = &max1027_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = st->info->channels;
+ indio_dev->num_channels = st->info->num_channels;
+ indio_dev->available_scan_masks = st->info->available_scan_masks;
+
+ st->buffer = devm_kmalloc(&indio_dev->dev,
+ indio_dev->num_channels * 2,
+ GFP_KERNEL);
+ if (st->buffer == NULL) {
+ dev_err(&indio_dev->dev, "Can't allocate bufffer\n");
+ return -ENOMEM;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+ &max1027_trigger_handler, NULL);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Failed to setup buffer\n");
+ return ret;
+ }
+
+ st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-trigger",
+ indio_dev->name);
+ if (st->trig == NULL) {
+ ret = -ENOMEM;
+ dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n");
+ goto fail_trigger_alloc;
+ }
+
+ st->trig->ops = &max1027_trigger_ops;
+ st->trig->dev.parent = &spi->dev;
+ iio_trigger_set_drvdata(st->trig, indio_dev);
+ iio_trigger_register(st->trig);
+
+ ret = devm_request_threaded_irq(&spi->dev, spi->irq,
+ iio_trigger_generic_data_rdy_poll,
+ NULL,
+ IRQF_TRIGGER_FALLING,
+ spi->dev.driver->name, st->trig);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
+ goto fail_dev_register;
+ }
+
+ /* Disable averaging */
+ st->reg = MAX1027_AVG_REG;
+ ret = spi_write(st->spi, &st->reg, 1);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Failed to configure averaging register\n");
+ goto fail_dev_register;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&indio_dev->dev, "Failed to register iio device\n");
+ goto fail_dev_register;
+ }
+
+ return 0;
+
+fail_dev_register:
+fail_trigger_alloc:
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return ret;
+}
+
+static int max1027_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+
+ pr_debug("%s: remove(spi = 0x%p)\n", __func__, spi);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return 0;
+}
+
+static struct spi_driver max1027_driver = {
+ .driver = {
+ .name = "max1027",
+ .owner = THIS_MODULE,
+ },
+ .probe = max1027_probe,
+ .remove = max1027_remove,
+ .id_table = max1027_id,
+};
+module_spi_driver(max1027_driver);
+
+MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>");
+MODULE_DESCRIPTION("MAX1027/MAX1029/MAX1031 ADC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index a4db3026bec6..d5dc4c6ce86c 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -374,7 +374,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
return -EAGAIN;
}
}
- map_val = chan->channel + TOTAL_CHANNELS;
+ map_val = adc_dev->channel_step[chan->scan_index];
/*
* We check the complete FIFO. We programmed just one entry but in case
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c
index ab52be29141b..fd2745c62943 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -486,7 +486,7 @@ static irqreturn_t xadc_axi_interrupt_handler(int irq, void *devid)
return IRQ_NONE;
if ((status & XADC_AXI_INT_EOS) && xadc->trigger)
- iio_trigger_poll(xadc->trigger, 0);
+ iio_trigger_poll(xadc->trigger);
if (status & XADC_AXI_INT_ALARM_MASK) {
/*
diff --git a/drivers/iio/adc/xilinx-xadc-events.c b/drivers/iio/adc/xilinx-xadc-events.c
index 3e7f0d7a80c3..edcf3aabd70d 100644
--- a/drivers/iio/adc/xilinx-xadc-events.c
+++ b/drivers/iio/adc/xilinx-xadc-events.c
@@ -31,17 +31,11 @@ static const struct iio_chan_spec *xadc_event_to_channel(
static void xadc_handle_event(struct iio_dev *indio_dev, unsigned int event)
{
const struct iio_chan_spec *chan;
- unsigned int offset;
/* Temperature threshold error, we don't handle this yet */
if (event == 0)
return;
- if (event < 4)
- offset = event;
- else
- offset = event + 4;
-
chan = xadc_event_to_channel(indio_dev, event);
if (chan->type == IIO_TEMP) {
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index 403dd3d8986e..25b01e156d82 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -26,12 +26,12 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-struct {
+static struct {
u32 usage_id;
int unit; /* 0 for default others from HID sensor spec */
int scale_val0; /* scale, whole number */
int scale_val1; /* scale, fraction in micros */
-} static unit_conversion[] = {
+} unit_conversion[] = {
{HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650},
{HID_USAGE_SENSOR_ACCEL_3D,
HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0},
@@ -343,6 +343,7 @@ int hid_sensor_format_scale(u32 usage_id,
}
EXPORT_SYMBOL(hid_sensor_format_scale);
+static
int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
struct hid_sensor_common *st)
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index e8b932fed70e..8a4ec00a91a0 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -14,8 +14,8 @@
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
+#include <linux/of.h>
#include <asm/unaligned.h>
-
#include <linux/iio/common/st_sensors.h>
@@ -265,14 +265,47 @@ static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
return 0;
}
+#ifdef CONFIG_OF
+static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
+ struct st_sensors_platform_data *defdata)
+{
+ struct st_sensors_platform_data *pdata;
+ struct device_node *np = dev->of_node;
+ u32 val;
+
+ if (!np)
+ return NULL;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
+ pdata->drdy_int_pin = (u8) val;
+ else
+ pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 1;
+
+ return pdata;
+}
+#else
+static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
+ struct st_sensors_platform_data *defdata)
+{
+ return NULL;
+}
+#endif
+
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata)
{
struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct st_sensors_platform_data *of_pdata;
int err = 0;
mutex_init(&sdata->tb.buf_lock);
+ /* If OF/DT pdata exists, it will take precedence of anything else */
+ of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
+ if (of_pdata)
+ pdata = of_pdata;
+
if (pdata)
err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
@@ -463,35 +496,6 @@ read_wai_error:
}
EXPORT_SYMBOL(st_sensors_check_device_support);
-ssize_t st_sensors_sysfs_get_sampling_frequency(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct st_sensor_data *adata = iio_priv(dev_get_drvdata(dev));
-
- return sprintf(buf, "%d\n", adata->odr);
-}
-EXPORT_SYMBOL(st_sensors_sysfs_get_sampling_frequency);
-
-ssize_t st_sensors_sysfs_set_sampling_frequency(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
-{
- int err;
- unsigned int odr;
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
-
- err = kstrtoint(buf, 10, &odr);
- if (err < 0)
- goto conversion_error;
-
- mutex_lock(&indio_dev->mlock);
- err = st_sensors_set_odr(indio_dev, odr);
- mutex_unlock(&indio_dev->mlock);
-
-conversion_error:
- return err < 0 ? err : size;
-}
-EXPORT_SYMBOL(st_sensors_sysfs_set_sampling_frequency);
-
ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
struct device_attribute *attr, char *buf)
{
diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
index 38af9440c103..bb6f3085f57b 100644
--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/iio/iio.h>
+#include <linux/of_device.h>
#include <linux/iio/common/st_sensors_i2c.h>
@@ -76,6 +77,35 @@ 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
+
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index f378ca8033db..f278eff42a4c 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -163,4 +163,14 @@ config MCP4725
To compile this driver as a module, choose M here: the module
will be called mcp4725.
+config MCP4922
+ tristate "MCP4902, MCP4912, MCP4922 DAC driver"
+ depends on SPI
+ help
+ Say yes here to build the driver for the Microchip MCP4902
+ MCP4912, and MCP4922 DAC devices.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mcp4922.
+
endmenu
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index bb84ad64463f..10107640bb46 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_AD5686) += ad5686.o
obj-$(CONFIG_AD7303) += ad7303.o
obj-$(CONFIG_MAX517) += max517.o
obj-$(CONFIG_MCP4725) += mcp4725.o
+obj-$(CONFIG_MCP4922) += mcp4922.o
diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c
index 1e6449346b50..581ec141de3d 100644
--- a/drivers/iio/dac/ad5504.c
+++ b/drivers/iio/dac/ad5504.c
@@ -15,17 +15,16 @@
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/dac/ad5504.h>
-#define AD5505_BITS 12
-#define AD5504_RES_MASK ((1 << (AD5505_BITS)) - 1)
-
-#define AD5504_CMD_READ (1 << 15)
-#define AD5504_CMD_WRITE (0 << 15)
+#define AD5504_RES_MASK GENMASK(11, 0)
+#define AD5504_CMD_READ BIT(15)
+#define AD5504_CMD_WRITE 0
#define AD5504_ADDR(addr) ((addr) << 12)
/* Registers */
@@ -42,7 +41,7 @@
/**
* struct ad5446_state - driver instance specific data
- * @us: spi_device
+ * @spi: spi_device
* @reg: supply regulator
* @vref_mv: actual reference voltage used
* @pwr_down_mask power down mask
@@ -126,7 +125,6 @@ static int ad5504_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct ad5504_state *st = iio_priv(indio_dev);
- int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -135,10 +133,8 @@ static int ad5504_write_raw(struct iio_dev *indio_dev,
return ad5504_spi_write(st, chan->address, val);
default:
- ret = -EINVAL;
+ return -EINVAL;
}
-
- return -EINVAL;
}
static const char * const ad5504_powerdown_modes[] = {
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c
index e8199cce2aea..61bb9d4239ea 100644
--- a/drivers/iio/dac/ad5624r_spi.c
+++ b/drivers/iio/dac/ad5624r_spi.c
@@ -67,7 +67,6 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct ad5624r_state *st = iio_priv(indio_dev);
- int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -79,10 +78,8 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev,
chan->address, val,
chan->scan_type.shift);
default:
- ret = -EINVAL;
+ return -EINVAL;
}
-
- return -EINVAL;
}
static const char * const ad5624r_powerdown_modes[] = {
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 17aca4d9bd06..f57562aa396f 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -313,7 +313,7 @@ static int ad5686_probe(struct spi_device *spi)
{
struct ad5686_state *st;
struct iio_dev *indio_dev;
- int ret, regdone = 0, voltage_uv = 0;
+ int ret, voltage_uv = 0;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
@@ -355,7 +355,6 @@ static int ad5686_probe(struct spi_device *spi)
indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = AD5686_DAC_CHANNELS;
- regdone = 1;
ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0,
!!voltage_uv, 0);
if (ret)
diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c
index ae49afe2b380..5ba785f18589 100644
--- a/drivers/iio/dac/ad5791.c
+++ b/drivers/iio/dac/ad5791.c
@@ -16,17 +16,16 @@
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/dac/ad5791.h>
-#define AD5791_RES_MASK(x) ((1 << (x)) - 1)
-#define AD5791_DAC_MASK AD5791_RES_MASK(20)
-#define AD5791_DAC_MSB (1 << 19)
+#define AD5791_DAC_MASK GENMASK(19, 0)
-#define AD5791_CMD_READ (1 << 23)
-#define AD5791_CMD_WRITE (0 << 23)
+#define AD5791_CMD_READ BIT(23)
+#define AD5791_CMD_WRITE 0
#define AD5791_ADDR(addr) ((addr) << 20)
/* Registers */
@@ -37,11 +36,11 @@
#define AD5791_ADDR_SW_CTRL 4
/* Control Register */
-#define AD5791_CTRL_RBUF (1 << 1)
-#define AD5791_CTRL_OPGND (1 << 2)
-#define AD5791_CTRL_DACTRI (1 << 3)
-#define AD5791_CTRL_BIN2SC (1 << 4)
-#define AD5791_CTRL_SDODIS (1 << 5)
+#define AD5791_CTRL_RBUF BIT(1)
+#define AD5791_CTRL_OPGND BIT(2)
+#define AD5791_CTRL_DACTRI BIT(3)
+#define AD5791_CTRL_BIN2SC BIT(4)
+#define AD5791_CTRL_SDODIS BIT(5)
#define AD5761_CTRL_LINCOMP(x) ((x) << 6)
#define AD5791_LINCOMP_0_10 0
@@ -54,9 +53,9 @@
#define AD5780_LINCOMP_10_20 12
/* Software Control Register */
-#define AD5791_SWCTRL_LDAC (1 << 0)
-#define AD5791_SWCTRL_CLR (1 << 1)
-#define AD5791_SWCTRL_RESET (1 << 2)
+#define AD5791_SWCTRL_LDAC BIT(0)
+#define AD5791_SWCTRL_CLR BIT(1)
+#define AD5791_SWCTRL_RESET BIT(2)
#define AD5791_DAC_PWRDN_6K 0
#define AD5791_DAC_PWRDN_3STATE 1
@@ -72,7 +71,7 @@ struct ad5791_chip_info {
/**
* struct ad5791_state - driver instance specific data
- * @us: spi_device
+ * @spi: spi_device
* @reg_vdd: positive supply regulator
* @reg_vss: negative supply regulator
* @chip_info: chip model specific constants
@@ -328,7 +327,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- val &= AD5791_RES_MASK(chan->scan_type.realbits);
+ val &= GENMASK(chan->scan_type.realbits - 1, 0);
val <<= chan->scan_type.shift;
return ad5791_spi_write(st, chan->address, val);
diff --git a/drivers/iio/dac/mcp4922.c b/drivers/iio/dac/mcp4922.c
new file mode 100644
index 000000000000..92cf4ca6981d
--- /dev/null
+++ b/drivers/iio/dac/mcp4922.c
@@ -0,0 +1,216 @@
+/*
+ * mcp4922.c
+ *
+ * Driver for Microchip Digital to Analog Converters.
+ * Supports MCP4902, MCP4912, and MCP4922.
+ *
+ * Copyright (c) 2014 EMAC Inc.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/bitops.h>
+
+#define MCP4922_NUM_CHANNELS 2
+
+enum mcp4922_supported_device_ids {
+ ID_MCP4902,
+ ID_MCP4912,
+ ID_MCP4922,
+};
+
+struct mcp4922_state {
+ struct spi_device *spi;
+ unsigned int value[MCP4922_NUM_CHANNELS];
+ unsigned int vref_mv;
+ struct regulator *vref_reg;
+ u8 mosi[2] ____cacheline_aligned;
+};
+
+#define MCP4922_CHAN(chan, bits) { \
+ .type = IIO_VOLTAGE, \
+ .output = 1, \
+ .indexed = 1, \
+ .channel = chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .shift = 12 - (bits), \
+ }, \
+}
+
+static int mcp4922_spi_write(struct mcp4922_state *state, u8 addr, u32 val)
+{
+ state->mosi[1] = val & 0xff;
+ state->mosi[0] = (addr == 0) ? 0x00 : 0x80;
+ state->mosi[0] |= 0x30 | ((val >> 8) & 0x0f);
+
+ return spi_write(state->spi, state->mosi, 2);
+}
+
+static int mcp4922_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long mask)
+{
+ struct mcp4922_state *state = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ *val = state->value[chan->channel];
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = state->vref_mv;
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mcp4922_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct mcp4922_state *state = iio_priv(indio_dev);
+
+ if (val2 != 0)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (val > GENMASK(chan->scan_type.realbits-1, 0))
+ return -EINVAL;
+ val <<= chan->scan_type.shift;
+ state->value[chan->channel] = val;
+ return mcp4922_spi_write(state, chan->channel, val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_chan_spec mcp4922_channels[3][MCP4922_NUM_CHANNELS] = {
+ [ID_MCP4902] = { MCP4922_CHAN(0, 8), MCP4922_CHAN(1, 8) },
+ [ID_MCP4912] = { MCP4922_CHAN(0, 10), MCP4922_CHAN(1, 10) },
+ [ID_MCP4922] = { MCP4922_CHAN(0, 12), MCP4922_CHAN(1, 12) },
+};
+
+static const struct iio_info mcp4922_info = {
+ .read_raw = &mcp4922_read_raw,
+ .write_raw = &mcp4922_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int mcp4922_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct mcp4922_state *state;
+ const struct spi_device_id *id;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ state = iio_priv(indio_dev);
+ state->spi = spi;
+ state->vref_reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(state->vref_reg)) {
+ dev_err(&spi->dev, "Vref regulator not specified\n");
+ return PTR_ERR(state->vref_reg);
+ }
+
+ ret = regulator_enable(state->vref_reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable vref regulator: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = regulator_get_voltage(state->vref_reg);
+ if (ret < 0) {
+ dev_err(&spi->dev, "Failed to read vref regulator: %d\n",
+ ret);
+ goto error_disable_reg;
+ }
+ state->vref_mv = ret / 1000;
+
+ spi_set_drvdata(spi, indio_dev);
+ id = spi_get_device_id(spi);
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->info = &mcp4922_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = mcp4922_channels[id->driver_data];
+ indio_dev->num_channels = MCP4922_NUM_CHANNELS;
+ indio_dev->name = id->name;
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to register iio device: %d\n",
+ ret);
+ goto error_disable_reg;
+ }
+
+ return 0;
+
+error_disable_reg:
+ regulator_disable(state->vref_reg);
+
+ return ret;
+}
+
+static int mcp4922_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct mcp4922_state *state;
+
+ iio_device_unregister(indio_dev);
+ state = iio_priv(indio_dev);
+ regulator_disable(state->vref_reg);
+
+ return 0;
+}
+
+static const struct spi_device_id mcp4922_id[] = {
+ {"mcp4902", ID_MCP4902},
+ {"mcp4912", ID_MCP4912},
+ {"mcp4922", ID_MCP4922},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, mcp4922_id);
+
+static struct spi_driver mcp4922_driver = {
+ .driver = {
+ .name = "mcp4922",
+ .owner = THIS_MODULE,
+ },
+ .probe = mcp4922_probe,
+ .remove = mcp4922_remove,
+ .id_table = mcp4922_id,
+};
+module_spi_driver(mcp4922_driver);
+
+MODULE_AUTHOR("Michael Welling <mwelling@ieee.org>");
+MODULE_DESCRIPTION("Microchip MCP4902, MCP4912, MCP4922 DAC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c
index 22b6fb80fa1a..75fe0edd3d0f 100644
--- a/drivers/iio/gyro/adis16260.c
+++ b/drivers/iio/gyro/adis16260.c
@@ -101,65 +101,6 @@
#define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4
-static ssize_t adis16260_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis *adis = iio_priv(indio_dev);
- int ret, len = 0;
- u16 t;
- int sps;
- ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &t);
- if (ret)
- return ret;
-
- if (spi_get_device_id(adis->spi)->driver_data) /* If an adis16251 */
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
- else
- sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
- sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
- len = sprintf(buf, "%d\n", sps);
- return len;
-}
-
-static ssize_t adis16260_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis *adis = iio_priv(indio_dev);
- unsigned int val;
- int ret;
- u8 t;
-
- ret = kstrtouint(buf, 10, &val);
- if (ret)
- return ret;
-
- mutex_lock(&indio_dev->mlock);
- if (spi_get_device_id(adis->spi)->driver_data)
- t = 256 / val;
- else
- t = 2048 / val;
-
- if (t > ADIS16260_SMPL_PRD_DIV_MASK)
- t = ADIS16260_SMPL_PRD_DIV_MASK;
- else if (t > 0)
- t--;
-
- if (t >= 0x0A)
- adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
- else
- adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
- ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
-
- mutex_unlock(&indio_dev->mlock);
-
- return ret ? ret : len;
-}
-
/* Power down the device */
static int adis16260_stop_device(struct iio_dev *indio_dev)
{
@@ -174,18 +115,19 @@ static int adis16260_stop_device(struct iio_dev *indio_dev)
return ret;
}
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- adis16260_read_frequency,
- adis16260_write_frequency);
-
static const struct iio_chan_spec adis16260_channels[] = {
ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
BIT(IIO_CHAN_INFO_CALIBBIAS) |
- BIT(IIO_CHAN_INFO_CALIBSCALE), 14),
- ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14),
- ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12),
- ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12),
- ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12),
+ BIT(IIO_CHAN_INFO_CALIBSCALE),
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), 14),
+ ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0,
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), 14),
+ ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP,
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
+ ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY,
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
+ ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC,
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
@@ -258,6 +200,20 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
*val = val16;
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &val16);
+ if (ret)
+ return ret;
+
+ if (spi_get_device_id(adis->spi)->driver_data)
+ /* If an adis16251 */
+ *val = (val16 & ADIS16260_SMPL_PRD_TIME_BASE) ?
+ 8 : 256;
+ else
+ *val = (val16 & ADIS16260_SMPL_PRD_TIME_BASE) ?
+ 66 : 2048;
+ *val /= (val16 & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
+ return IIO_VAL_INT;
}
return -EINVAL;
}
@@ -269,7 +225,9 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct adis *adis = iio_priv(indio_dev);
+ int ret;
u8 addr;
+ u8 t;
switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS:
@@ -284,21 +242,31 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
addr = adis16260_addresses[chan->scan_index][1];
return adis_write_reg_16(adis, addr, val);
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ mutex_lock(&indio_dev->mlock);
+ if (spi_get_device_id(adis->spi)->driver_data)
+ t = 256 / val;
+ else
+ t = 2048 / val;
+
+ if (t > ADIS16260_SMPL_PRD_DIV_MASK)
+ t = ADIS16260_SMPL_PRD_DIV_MASK;
+ else if (t > 0)
+ t--;
+
+ if (t >= 0x0A)
+ adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
+ else
+ adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
+ ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
+
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
}
return -EINVAL;
}
-static struct attribute *adis16260_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group adis16260_attribute_group = {
- .attrs = adis16260_attributes,
-};
-
static const struct iio_info adis16260_info = {
- .attrs = &adis16260_attribute_group,
.read_raw = &adis16260_read_raw,
.write_raw = &adis16260_write_raw,
.update_scan_mode = adis_update_scan_mode,
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index 40f4e4935d0d..fa034a3dad78 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -110,7 +110,6 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
struct gyro_3d_state *gyro_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -151,14 +150,12 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&gyro_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&gyro_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c
index 8295e318399f..6a8020d48140 100644
--- a/drivers/iio/gyro/itg3200_core.c
+++ b/drivers/iio/gyro/itg3200_core.c
@@ -90,6 +90,7 @@ static int itg3200_read_raw(struct iio_dev *indio_dev,
{
int ret = 0;
u8 reg;
+ u8 regval;
switch (info) {
case IIO_CHAN_INFO_RAW:
@@ -107,65 +108,60 @@ static int itg3200_read_raw(struct iio_dev *indio_dev,
/* Only the temperature channel has an offset */
*val = 23000;
return IIO_VAL_INT;
- default:
- return -EINVAL;
- }
-}
-
-static ssize_t itg3200_read_frequency(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- int ret, sps;
- u8 val;
-
- ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val);
- if (ret)
- return ret;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &regval);
+ if (ret)
+ return ret;
- sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000;
+ *val = (regval & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000;
- ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val);
- if (ret)
- return ret;
+ ret = itg3200_read_reg_8(indio_dev,
+ ITG3200_REG_SAMPLE_RATE_DIV,
+ &regval);
+ if (ret)
+ return ret;
- sps /= val + 1;
+ *val /= regval + 1;
+ return IIO_VAL_INT;
- return sprintf(buf, "%d\n", sps);
+ default:
+ return -EINVAL;
+ }
}
-static ssize_t itg3200_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+static int itg3200_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- unsigned val;
int ret;
u8 t;
- ret = kstrtouint(buf, 10, &val);
- if (ret)
- return ret;
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val == 0 || val2 != 0)
+ return -EINVAL;
- mutex_lock(&indio_dev->mlock);
+ mutex_lock(&indio_dev->mlock);
- ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t);
- if (ret)
- goto err_ret;
+ ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t);
+ if (ret) {
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
+ }
+ t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1;
- if (val == 0) {
- ret = -EINVAL;
- goto err_ret;
- }
- t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1;
+ ret = itg3200_write_reg_8(indio_dev,
+ ITG3200_REG_SAMPLE_RATE_DIV,
+ t);
- ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t);
-
-err_ret:
- mutex_unlock(&indio_dev->mlock);
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
- return ret ? ret : len;
+ default:
+ return -EINVAL;
+ }
}
/*
@@ -255,6 +251,7 @@ err_ret:
.channel2 = IIO_MOD_ ## _mod, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \
.scan_index = ITG3200_SCAN_GYRO_ ## _mod, \
.scan_type = ITG3200_ST, \
@@ -267,6 +264,7 @@ static const struct iio_chan_spec itg3200_channels[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = ITG3200_REG_TEMP_OUT_H,
.scan_index = ITG3200_SCAN_TEMP,
.scan_type = ITG3200_ST,
@@ -277,22 +275,9 @@ static const struct iio_chan_spec itg3200_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS),
};
-/* IIO device attributes */
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency,
- itg3200_write_frequency);
-
-static struct attribute *itg3200_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group itg3200_attribute_group = {
- .attrs = itg3200_attributes,
-};
-
static const struct iio_info itg3200_info = {
- .attrs = &itg3200_attribute_group,
.read_raw = &itg3200_read_raw,
+ .write_raw = &itg3200_write_raw,
.driver_module = THIS_MODULE,
};
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c
index ed74a9069989..f156fc6c5c6c 100644
--- a/drivers/iio/gyro/st_gyro_core.c
+++ b/drivers/iio/gyro/st_gyro_core.c
@@ -245,6 +245,9 @@ static int st_gyro_read_raw(struct iio_dev *indio_dev,
*val = 0;
*val2 = gdata->current_fullscale->gain;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = gdata->odr;
+ return IIO_VAL_INT;
default:
return -EINVAL;
}
@@ -262,6 +265,13 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ err = st_sensors_set_odr(indio_dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return err;
default:
err = -EINVAL;
}
@@ -269,14 +279,12 @@ static int st_gyro_write_raw(struct iio_dev *indio_dev,
return err;
}
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
static struct attribute *st_gyro_attributes[] = {
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL,
};
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c
index 23c12f361b05..8fa0ad2ef4ef 100644
--- a/drivers/iio/gyro/st_gyro_i2c.c
+++ b/drivers/iio/gyro/st_gyro_i2c.c
@@ -18,6 +18,43 @@
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_gyro.h"
+#ifdef CONFIG_OF
+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,l3g4is-gyro",
+ .data = L3G4IS_GYRO_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm330-gyro",
+ .data = LSM330_GYRO_DEV_NAME,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_gyro_of_match);
+#else
+#define st_gyro_of_match NULL
+#endif
+
static int st_gyro_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -31,6 +68,7 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
gdata = iio_priv(indio_dev);
gdata->dev = &client->dev;
+ st_sensors_of_i2c_probe(client, st_gyro_of_match);
st_sensors_i2c_configure(indio_dev, client, gdata);
@@ -65,6 +103,7 @@ static struct i2c_driver st_gyro_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-gyro-i2c",
+ .of_match_table = of_match_ptr(st_gyro_of_match),
},
.probe = st_gyro_i2c_probe,
.remove = st_gyro_i2c_remove,
diff --git a/drivers/iio/imu/adis16400_buffer.c b/drivers/iio/imu/adis16400_buffer.c
index f2cf829e5df1..6e727ffe5262 100644
--- a/drivers/iio/imu/adis16400_buffer.c
+++ b/drivers/iio/imu/adis16400_buffer.c
@@ -18,7 +18,7 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev,
{
struct adis16400_state *st = iio_priv(indio_dev);
struct adis *adis = &st->adis;
- uint16_t *tx, *rx;
+ uint16_t *tx;
if (st->variant->flags & ADIS16400_NO_BURST)
return adis_update_scan_mode(indio_dev, scan_mask);
@@ -35,7 +35,6 @@ int adis16400_update_scan_mode(struct iio_dev *indio_dev,
if (!adis->buffer)
return -ENOMEM;
- rx = adis->buffer;
tx = adis->buffer + indio_dev->scan_bytes;
tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index 433583b6f800..b70873de04ea 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -214,21 +214,6 @@ static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, val);
}
-static ssize_t adis16400_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16400_state *st = iio_priv(indio_dev);
- int ret;
-
- ret = st->variant->get_freq(st);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d.%.3d\n", ret / 1000, ret % 1000);
-}
-
static const unsigned adis16400_3db_divisors[] = {
[0] = 2, /* Special case */
[1] = 6,
@@ -260,30 +245,6 @@ static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
return ret;
}
-static ssize_t adis16400_write_frequency(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16400_state *st = iio_priv(indio_dev);
- int i, f, val;
- int ret;
-
- ret = iio_str_to_fixpoint(buf, 100, &i, &f);
- if (ret)
- return ret;
-
- val = i * 1000 + f;
-
- if (val <= 0)
- return -EINVAL;
-
- mutex_lock(&indio_dev->mlock);
- st->variant->set_freq(st, val);
- mutex_unlock(&indio_dev->mlock);
-
- return len;
-}
-
/* Power down the device */
static int adis16400_stop_device(struct iio_dev *indio_dev)
{
@@ -350,10 +311,6 @@ err_ret:
return ret;
}
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- adis16400_read_frequency,
- adis16400_write_frequency);
-
static const uint8_t adis16400_addresses[] = {
[ADIS16400_SCAN_GYRO_X] = ADIS16400_XGYRO_OFF,
[ADIS16400_SCAN_GYRO_Y] = ADIS16400_YGYRO_OFF,
@@ -394,6 +351,16 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
val * 1000 + val2 / 1000);
mutex_unlock(&indio_dev->mlock);
return ret;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ sps = val * 1000 + val2 / 1000;
+
+ if (sps <= 0)
+ return -EINVAL;
+
+ mutex_lock(&indio_dev->mlock);
+ ret = st->variant->set_freq(st, sps);
+ mutex_unlock(&indio_dev->mlock);
+ return ret;
default:
return -EINVAL;
}
@@ -474,6 +441,13 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = st->variant->get_freq(st);
+ if (ret < 0)
+ return ret;
+ *val = ret / 1000;
+ *val2 = (ret % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
@@ -486,6 +460,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.extend_name = name, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = (si), \
.scan_type = { \
@@ -511,6 +486,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
BIT(IIO_CHAN_INFO_CALIBBIAS), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = addr, \
.scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
.scan_type = { \
@@ -530,6 +506,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
BIT(IIO_CHAN_INFO_CALIBBIAS), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = ADIS16400_SCAN_ACC_ ## mod, \
.scan_type = { \
@@ -548,6 +525,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
.scan_type = { \
@@ -573,6 +551,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_type = \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
.scan_type = { \
@@ -591,6 +570,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_OFFSET) | \
BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = ADIS16350_SCAN_TEMP_X, \
.scan_type = { \
@@ -608,6 +588,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
.channel2 = IIO_MOD_ ## mod, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (addr), \
.scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
.scan_type = { \
@@ -649,6 +630,7 @@ static const struct iio_chan_spec adis16448_channels[] = {
.type = IIO_PRESSURE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
.address = ADIS16448_BARO_OUT,
.scan_index = ADIS16400_SCAN_BARO,
.scan_type = {
@@ -704,15 +686,6 @@ static const struct iio_chan_spec adis16334_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
};
-static struct attribute *adis16400_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group adis16400_attribute_group = {
- .attrs = adis16400_attributes,
-};
-
static struct adis16400_chip_info adis16400_chips[] = {
[ADIS16300] = {
.channels = adis16300_channels,
@@ -813,7 +786,6 @@ static const struct iio_info adis16400_info = {
.driver_module = THIS_MODULE,
.read_raw = &adis16400_read_raw,
.write_raw = &adis16400_write_raw,
- .attrs = &adis16400_attribute_group,
.update_scan_mode = adis16400_update_scan_mode,
.debugfs_reg_access = adis_debugfs_reg_access,
};
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
index dd4206cac62d..989605dd6f78 100644
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -257,11 +257,16 @@ static int adis16480_debugfs_init(struct iio_dev *indio_dev)
#endif
-static int adis16480_set_freq(struct adis16480 *st, unsigned int freq)
+static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)
{
+ struct adis16480 *st = iio_priv(indio_dev);
unsigned int t;
- t = 2460000 / freq;
+ t = val * 1000 + val2 / 1000;
+ if (t <= 0)
+ return -EINVAL;
+
+ t = 2460000 / t;
if (t > 2048)
t = 2048;
@@ -271,65 +276,24 @@ static int adis16480_set_freq(struct adis16480 *st, unsigned int freq)
return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t);
}
-static int adis16480_get_freq(struct adis16480 *st, unsigned int *freq)
+static int adis16480_get_freq(struct iio_dev *indio_dev, int *val, int *val2)
{
+ struct adis16480 *st = iio_priv(indio_dev);
uint16_t t;
int ret;
+ unsigned freq;
ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t);
if (ret < 0)
return ret;
- *freq = 2460000 / (t + 1);
+ freq = 2460000 / (t + 1);
+ *val = freq / 1000;
+ *val2 = (freq % 1000) * 1000;
- return 0;
+ return IIO_VAL_INT_PLUS_MICRO;
}
-static ssize_t adis16480_read_frequency(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16480 *st = iio_priv(indio_dev);
- unsigned int freq;
- int ret;
-
- ret = adis16480_get_freq(st, &freq);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d.%.3d\n", freq / 1000, freq % 1000);
-}
-
-static ssize_t adis16480_write_frequency(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adis16480 *st = iio_priv(indio_dev);
- int freq_int, freq_fract;
- long val;
- int ret;
-
- ret = iio_str_to_fixpoint(buf, 100, &freq_int, &freq_fract);
- if (ret)
- return ret;
-
- val = freq_int * 1000 + freq_fract;
-
- if (val <= 0)
- return -EINVAL;
-
- ret = adis16480_set_freq(st, val);
-
- return ret ? ret : len;
-}
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
- adis16480_read_frequency,
- adis16480_write_frequency);
-
enum {
ADIS16480_SCAN_GYRO_X,
ADIS16480_SCAN_GYRO_Y,
@@ -571,6 +535,8 @@ static int adis16480_read_raw(struct iio_dev *indio_dev,
return adis16480_get_calibscale(indio_dev, chan, val);
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16480_get_filter_freq(indio_dev, chan, val);
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return adis16480_get_freq(indio_dev, val, val2);
default:
return -EINVAL;
}
@@ -586,6 +552,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
return adis16480_set_calibscale(indio_dev, chan, val);
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
return adis16480_set_filter_freq(indio_dev, chan, val);
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return adis16480_set_freq(indio_dev, val, val2);
+
default:
return -EINVAL;
}
@@ -600,6 +569,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
_info_sep, \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = (_address), \
.scan_index = (_si), \
.scan_type = { \
@@ -638,6 +608,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = ADIS16480_REG_BAROM_OUT, \
.scan_index = ADIS16480_SCAN_BARO, \
.scan_type = { \
@@ -655,6 +626,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_OFFSET), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.address = ADIS16480_REG_TEMP_OUT, \
.scan_index = ADIS16480_SCAN_TEMP, \
.scan_type = { \
@@ -717,17 +689,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
},
};
-static struct attribute *adis16480_attributes[] = {
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
- NULL
-};
-
-static const struct attribute_group adis16480_attribute_group = {
- .attrs = adis16480_attributes,
-};
-
static const struct iio_info adis16480_info = {
- .attrs = &adis16480_attribute_group,
.read_raw = &adis16480_read_raw,
.write_raw = &adis16480_write_raw,
.update_scan_mode = adis_update_scan_mode,
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 36b1ae92e239..0472ee268271 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -39,10 +39,7 @@ static bool iio_buffer_is_active(struct iio_buffer *buf)
static bool iio_buffer_data_available(struct iio_buffer *buf)
{
- if (buf->access->data_available)
- return buf->access->data_available(buf);
-
- return buf->stufftoread;
+ return buf->access->data_available(buf);
}
/**
@@ -966,7 +963,7 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,
/* Now we have the two masks, work from least sig and build up sizes */
for_each_set_bit(out_ind,
- indio_dev->active_scan_mask,
+ buffer->scan_mask,
indio_dev->masklength) {
in_ind = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength,
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 4b1f375c5659..af3e76d652ba 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -87,6 +87,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_QUATERNION] = "quaternion",
[IIO_MOD_TEMP_AMBIENT] = "ambient",
[IIO_MOD_TEMP_OBJECT] = "object",
+ [IIO_MOD_NORTH_MAGN] = "from_north_magnetic",
+ [IIO_MOD_NORTH_TRUE] = "from_north_true",
+ [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
+ [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
};
/* relies on pairs of these shared then separate */
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 258a973a1fb8..0c1e37e3120a 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -209,6 +209,7 @@ static const char * const iio_ev_info_text[] = {
[IIO_EV_INFO_ENABLE] = "en",
[IIO_EV_INFO_VALUE] = "value",
[IIO_EV_INFO_HYSTERESIS] = "hysteresis",
+ [IIO_EV_INFO_PERIOD] = "period",
};
static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)
@@ -345,6 +346,9 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
&indio_dev->event_interface->dev_attr_list);
kfree(postfix);
+ if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
+ continue;
+
if (ret)
return ret;
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 3383b025f62e..d31098e0c43f 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -114,7 +114,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
return trig;
}
-void iio_trigger_poll(struct iio_trigger *trig, s64 time)
+void iio_trigger_poll(struct iio_trigger *trig)
{
int i;
@@ -133,12 +133,12 @@ EXPORT_SYMBOL(iio_trigger_poll);
irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private)
{
- iio_trigger_poll(private, iio_get_time_ns());
+ iio_trigger_poll(private);
return IRQ_HANDLED;
}
EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
-void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
+void iio_trigger_poll_chained(struct iio_trigger *trig)
{
int i;
@@ -161,7 +161,7 @@ void iio_trigger_notify_done(struct iio_trigger *trig)
trig->ops->try_reenable)
if (trig->ops->try_reenable(trig))
/* Missed an interrupt so launch new poll now */
- iio_trigger_poll(trig, 0);
+ iio_trigger_poll(trig);
}
EXPORT_SYMBOL(iio_trigger_notify_done);
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index d833d55052ea..c7497009d60a 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -183,7 +183,7 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np,
else if (name && index >= 0) {
pr_err("ERROR: could not get IIO channel %s:%s(%i)\n",
np->full_name, name ? name : "", index);
- return chan;
+ return NULL;
}
/*
@@ -193,8 +193,9 @@ static struct iio_channel *of_iio_channel_get_by_name(struct device_node *np,
*/
np = np->parent;
if (np && !of_get_property(np, "io-channel-ranges", NULL))
- break;
+ return NULL;
}
+
return chan;
}
@@ -317,6 +318,7 @@ struct iio_channel *iio_channel_get(struct device *dev,
if (channel != NULL)
return channel;
}
+
return iio_channel_get_sys(name, channel_name);
}
EXPORT_SYMBOL_GPL(iio_channel_get);
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index c89740d4748f..bf05ca5b0a57 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -62,6 +62,18 @@ config GP2AP020A00F
To compile this driver as a module, choose M here: the
module will be called gp2ap020a00f.
+config ISL29125
+ tristate "Intersil ISL29125 digital color light sensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say Y here if you want to build a driver for the Intersil ISL29125
+ RGB light sensor for I2C.
+
+ To compile this driver as a module, choose M here: the module will be
+ called isl29125.
+
config HID_SENSOR_ALS
depends on HID_SENSOR_HUB
select IIO_BUFFER
@@ -116,6 +128,18 @@ config LTR501
This driver can also be built as a module. If so, the module
will be called ltr501.
+config TCS3414
+ tristate "TAOS TCS3414 digital color sensor"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for the TAOS TCS3414
+ family of digital color sensors.
+
+ This driver can also be built as a module. If so, the module
+ will be called tcs3414.
+
config TCS3472
tristate "TAOS TCS3472 color light-to-digital converter"
depends on I2C
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 3eb36e5151fa..8b8c09f9c1f8 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -10,9 +10,11 @@ obj-$(CONFIG_CM36651) += cm36651.o
obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o
+obj-$(CONFIG_ISL29125) += isl29125.o
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
obj-$(CONFIG_LTR501) += ltr501.o
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
+obj-$(CONFIG_TCS3414) += tcs3414.o
obj-$(CONFIG_TCS3472) += tcs3472.o
obj-$(CONFIG_TSL4531) += tsl4531.o
obj-$(CONFIG_VCNL4000) += vcnl4000.o
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index d976e6ce60db..ad36b294e4d5 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -331,7 +331,7 @@ static int cm32181_probe(struct i2c_client *client,
return ret;
}
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&client->dev, indio_dev);
if (ret) {
dev_err(&client->dev,
"%s: regist device failed\n",
@@ -342,14 +342,6 @@ static int cm32181_probe(struct i2c_client *client,
return 0;
}
-static int cm32181_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
- iio_device_unregister(indio_dev);
- return 0;
-}
-
static const struct i2c_device_id cm32181_id[] = {
{ "cm32181", 0 },
{ }
@@ -370,7 +362,6 @@ static struct i2c_driver cm32181_driver = {
},
.id_table = cm32181_id,
.probe = cm32181_probe,
- .remove = cm32181_remove,
};
module_i2c_driver(cm32181_driver);
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
index 04bdb85d2d9f..221ed16de1f7 100644
--- a/drivers/iio/light/gp2ap020a00f.c
+++ b/drivers/iio/light/gp2ap020a00f.c
@@ -827,7 +827,7 @@ static void gp2ap020a00f_iio_trigger_work(struct irq_work *work)
struct gp2ap020a00f_data *data =
container_of(work, struct gp2ap020a00f_data, work);
- iio_trigger_poll(data->trig, 0);
+ iio_trigger_poll(data->trig);
}
static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data)
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index f34c94380b41..96e71e103ea7 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -79,7 +79,6 @@ static int als_read_raw(struct iio_dev *indio_dev,
struct als_state *als_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -129,14 +128,12 @@ static int als_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&als_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&als_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index d203ef4d892f..412bae86d6ae 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -74,7 +74,6 @@ static int prox_read_raw(struct iio_dev *indio_dev,
struct prox_state *prox_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -125,14 +124,12 @@ static int prox_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&prox_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&prox_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c
new file mode 100644
index 000000000000..c82f4a6f8464
--- /dev/null
+++ b/drivers/iio/light/isl29125.c
@@ -0,0 +1,347 @@
+/*
+ * isl29125.c - Support for Intersil ISL29125 RGB light sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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
+ * directory of this archive for more details.
+ *
+ * RGB light sensor with 16-bit channels for red, green, blue);
+ * 7-bit I2C slave address 0x44
+ *
+ * TODO: interrupt support, IR compensation, thresholds, 12bit
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define ISL29125_DRV_NAME "isl29125"
+
+#define ISL29125_DEVICE_ID 0x00
+#define ISL29125_CONF1 0x01
+#define ISL29125_CONF2 0x02
+#define ISL29125_CONF3 0x03
+#define ISL29125_STATUS 0x08
+#define ISL29125_GREEN_DATA 0x09
+#define ISL29125_RED_DATA 0x0b
+#define ISL29125_BLUE_DATA 0x0d
+
+#define ISL29125_ID 0x7d
+
+#define ISL29125_MODE_MASK GENMASK(2, 0)
+#define ISL29125_MODE_PD 0x0
+#define ISL29125_MODE_G 0x1
+#define ISL29125_MODE_R 0x2
+#define ISL29125_MODE_B 0x3
+#define ISL29125_MODE_RGB 0x5
+
+#define ISL29125_MODE_RANGE BIT(3)
+
+#define ISL29125_STATUS_CONV BIT(1)
+
+struct isl29125_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 conf1;
+ u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */
+};
+
+#define ISL29125_CHANNEL(_color, _si) { \
+ .type = IIO_INTENSITY, \
+ .modified = 1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .channel2 = IIO_MOD_LIGHT_##_color, \
+ .scan_index = _si, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU, \
+ }, \
+}
+
+static const struct iio_chan_spec isl29125_channels[] = {
+ ISL29125_CHANNEL(GREEN, 0),
+ ISL29125_CHANNEL(RED, 1),
+ ISL29125_CHANNEL(BLUE, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct {
+ u8 mode, data;
+} isl29125_regs[] = {
+ {ISL29125_MODE_G, ISL29125_GREEN_DATA},
+ {ISL29125_MODE_R, ISL29125_RED_DATA},
+ {ISL29125_MODE_B, ISL29125_BLUE_DATA},
+};
+
+static int isl29125_read_data(struct isl29125_data *data, int si)
+{
+ int tries = 5;
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1 | isl29125_regs[si].mode);
+ if (ret < 0)
+ return ret;
+
+ msleep(101);
+
+ while (tries--) {
+ ret = i2c_smbus_read_byte_data(data->client, ISL29125_STATUS);
+ if (ret < 0)
+ goto fail;
+ if (ret & ISL29125_STATUS_CONV)
+ break;
+ msleep(20);
+ }
+
+ if (tries < 0) {
+ dev_err(&data->client->dev, "data not ready\n");
+ ret = -EIO;
+ goto fail;
+ }
+
+ ret = i2c_smbus_read_word_data(data->client, isl29125_regs[si].data);
+
+fail:
+ i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, data->conf1);
+ return ret;
+}
+
+static int isl29125_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct isl29125_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+ mutex_lock(&data->lock);
+ ret = isl29125_read_data(data, chan->scan_index);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ if (data->conf1 & ISL29125_MODE_RANGE)
+ *val2 = 152590; /* 10k lux full range */
+ else
+ *val2 = 5722; /* 375 lux full range */
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ return -EINVAL;
+}
+
+static int isl29125_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct isl29125_data *data = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ if (val != 0)
+ return -EINVAL;
+ if (val2 == 152590)
+ data->conf1 |= ISL29125_MODE_RANGE;
+ else if (val2 == 5722)
+ data->conf1 &= ~ISL29125_MODE_RANGE;
+ else
+ return -EINVAL;
+ return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1);
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t isl29125_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct isl29125_data *data = iio_priv(indio_dev);
+ int i, j = 0;
+
+ for_each_set_bit(i, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ int ret = i2c_smbus_read_word_data(data->client,
+ isl29125_regs[i].data);
+ if (ret < 0)
+ goto done;
+
+ data->buffer[j++] = ret;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ iio_get_time_ns());
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_info isl29125_info = {
+ .read_raw = isl29125_read_raw,
+ .write_raw = isl29125_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int isl29125_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct isl29125_data *data = iio_priv(indio_dev);
+
+ data->conf1 |= ISL29125_MODE_RGB;
+ return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1);
+}
+
+static int isl29125_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct isl29125_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = iio_triggered_buffer_predisable(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ data->conf1 &= ~ISL29125_MODE_MASK;
+ data->conf1 |= ISL29125_MODE_PD;
+ return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1);
+}
+
+static const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = {
+ .preenable = isl29125_buffer_preenable,
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = isl29125_buffer_predisable,
+};
+
+static int isl29125_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct isl29125_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ 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->info = &isl29125_info;
+ indio_dev->name = ISL29125_DRV_NAME;
+ indio_dev->channels = isl29125_channels;
+ indio_dev->num_channels = ARRAY_SIZE(isl29125_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = i2c_smbus_read_byte_data(data->client, ISL29125_DEVICE_ID);
+ if (ret < 0)
+ return ret;
+ if (ret != ISL29125_ID)
+ return -ENODEV;
+
+ data->conf1 = ISL29125_MODE_PD | ISL29125_MODE_RANGE;
+ ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, ISL29125_STATUS, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ isl29125_trigger_handler, &isl29125_buffer_setup_ops);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto buffer_cleanup;
+
+ return 0;
+
+buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+
+static int isl29125_powerdown(struct isl29125_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ (data->conf1 & ~ISL29125_MODE_MASK) | ISL29125_MODE_PD);
+}
+
+static int isl29125_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);
+ isl29125_powerdown(iio_priv(indio_dev));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int isl29125_suspend(struct device *dev)
+{
+ struct isl29125_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+ return isl29125_powerdown(data);
+}
+
+static int isl29125_resume(struct device *dev)
+{
+ struct isl29125_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+ return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
+ data->conf1);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(isl29125_pm_ops, isl29125_suspend, isl29125_resume);
+
+static const struct i2c_device_id isl29125_id[] = {
+ { "isl29125", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, isl29125_id);
+
+static struct i2c_driver isl29125_driver = {
+ .driver = {
+ .name = ISL29125_DRV_NAME,
+ .pm = &isl29125_pm_ops,
+ .owner = THIS_MODULE,
+ },
+ .probe = isl29125_probe,
+ .remove = isl29125_remove,
+ .id_table = isl29125_id,
+};
+module_i2c_driver(isl29125_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("ISL29125 RGB light sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c
new file mode 100644
index 000000000000..a9e449b0be0c
--- /dev/null
+++ b/drivers/iio/light/tcs3414.c
@@ -0,0 +1,405 @@
+/*
+ * tcs3414.c - Support for TAOS TCS3414 digital color sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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
+ * directory of this archive for more details.
+ *
+ * Digital color sensor with 16-bit channels for red, green, blue, clear);
+ * 7-bit I2C slave address 0x39 (TCS3414) or 0x29, 0x49, 0x59 (TCS3413,
+ * TCS3415, TCS3416, resp.)
+ *
+ * TODO: sync, interrupt support, thresholds, prescaler
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define TCS3414_DRV_NAME "tcs3414"
+
+#define TCS3414_COMMAND BIT(7)
+#define TCS3414_COMMAND_WORD (TCS3414_COMMAND | BIT(5))
+
+#define TCS3414_CONTROL (TCS3414_COMMAND | 0x00)
+#define TCS3414_TIMING (TCS3414_COMMAND | 0x01)
+#define TCS3414_ID (TCS3414_COMMAND | 0x04)
+#define TCS3414_GAIN (TCS3414_COMMAND | 0x07)
+#define TCS3414_DATA_GREEN (TCS3414_COMMAND_WORD | 0x10)
+#define TCS3414_DATA_RED (TCS3414_COMMAND_WORD | 0x12)
+#define TCS3414_DATA_BLUE (TCS3414_COMMAND_WORD | 0x14)
+#define TCS3414_DATA_CLEAR (TCS3414_COMMAND_WORD | 0x16)
+
+#define TCS3414_CONTROL_ADC_VALID BIT(4)
+#define TCS3414_CONTROL_ADC_EN BIT(1)
+#define TCS3414_CONTROL_POWER BIT(0)
+
+#define TCS3414_INTEG_MASK GENMASK(1, 0)
+#define TCS3414_INTEG_12MS 0x0
+#define TCS3414_INTEG_100MS 0x1
+#define TCS3414_INTEG_400MS 0x2
+
+#define TCS3414_GAIN_MASK GENMASK(5, 4)
+#define TCS3414_GAIN_SHIFT 4
+
+struct tcs3414_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 control;
+ u8 gain;
+ u8 timing;
+ u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */
+};
+
+#define TCS3414_CHANNEL(_color, _si, _addr) { \
+ .type = IIO_INTENSITY, \
+ .modified = 1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_INT_TIME), \
+ .channel2 = IIO_MOD_LIGHT_##_color, \
+ .address = _addr, \
+ .scan_index = _si, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU, \
+ }, \
+}
+
+/* scale factors: 1/gain */
+static const int tcs3414_scales[][2] = {
+ {1, 0}, {0, 250000}, {0, 62500}, {0, 15625}
+};
+
+/* integration time in ms */
+static const int tcs3414_times[] = { 12, 100, 400 };
+
+static const struct iio_chan_spec tcs3414_channels[] = {
+ TCS3414_CHANNEL(GREEN, 0, TCS3414_DATA_GREEN),
+ TCS3414_CHANNEL(RED, 1, TCS3414_DATA_RED),
+ TCS3414_CHANNEL(BLUE, 2, TCS3414_DATA_BLUE),
+ TCS3414_CHANNEL(CLEAR, 3, TCS3414_DATA_CLEAR),
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static int tcs3414_req_data(struct tcs3414_data *data)
+{
+ int tries = 25;
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control | TCS3414_CONTROL_ADC_EN);
+ if (ret < 0)
+ return ret;
+
+ while (tries--) {
+ ret = i2c_smbus_read_byte_data(data->client, TCS3414_CONTROL);
+ if (ret < 0)
+ return ret;
+ if (ret & TCS3414_CONTROL_ADC_VALID)
+ break;
+ msleep(20);
+ }
+
+ ret = i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control);
+ if (ret < 0)
+ return ret;
+
+ if (tries < 0) {
+ dev_err(&data->client->dev, "data not ready\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int tcs3414_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct tcs3414_data *data = iio_priv(indio_dev);
+ int i, ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+ mutex_lock(&data->lock);
+ ret = tcs3414_req_data(data);
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+ ret = i2c_smbus_read_word_data(data->client, chan->address);
+ mutex_unlock(&data->lock);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ i = (data->gain & TCS3414_GAIN_MASK) >> TCS3414_GAIN_SHIFT;
+ *val = tcs3414_scales[i][0];
+ *val2 = tcs3414_scales[i][1];
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_INT_TIME:
+ *val = 0;
+ *val2 = tcs3414_times[data->timing & TCS3414_INTEG_MASK] * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+ return -EINVAL;
+}
+
+static int tcs3414_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct tcs3414_data *data = iio_priv(indio_dev);
+ int i;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ for (i = 0; i < ARRAY_SIZE(tcs3414_scales); i++) {
+ if (val == tcs3414_scales[i][0] &&
+ val2 == tcs3414_scales[i][1]) {
+ data->gain &= ~TCS3414_GAIN_MASK;
+ data->gain |= i << TCS3414_GAIN_SHIFT;
+ return i2c_smbus_write_byte_data(
+ data->client, TCS3414_GAIN,
+ data->gain);
+ }
+ }
+ return -EINVAL;
+ case IIO_CHAN_INFO_INT_TIME:
+ if (val != 0)
+ return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(tcs3414_times); i++) {
+ if (val == tcs3414_times[i] * 1000) {
+ data->timing &= ~TCS3414_INTEG_MASK;
+ data->timing |= i;
+ return i2c_smbus_write_byte_data(
+ data->client, TCS3414_TIMING,
+ data->timing);
+ }
+ }
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t tcs3414_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct tcs3414_data *data = iio_priv(indio_dev);
+ int i, j = 0;
+
+ for_each_set_bit(i, indio_dev->active_scan_mask,
+ indio_dev->masklength) {
+ int ret = i2c_smbus_read_word_data(data->client,
+ TCS3414_DATA_GREEN + 2*i);
+ if (ret < 0)
+ goto done;
+
+ data->buffer[j++] = ret;
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+ iio_get_time_ns());
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static IIO_CONST_ATTR(scale_available, "1 0.25 0.0625 0.015625");
+static IIO_CONST_ATTR_INT_TIME_AVAIL("0.012 0.1 0.4");
+
+static struct attribute *tcs3414_attributes[] = {
+ &iio_const_attr_scale_available.dev_attr.attr,
+ &iio_const_attr_integration_time_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group tcs3414_attribute_group = {
+ .attrs = tcs3414_attributes,
+};
+
+static const struct iio_info tcs3414_info = {
+ .read_raw = tcs3414_read_raw,
+ .write_raw = tcs3414_write_raw,
+ .attrs = &tcs3414_attribute_group,
+ .driver_module = THIS_MODULE,
+};
+
+static int tcs3414_buffer_preenable(struct iio_dev *indio_dev)
+{
+ struct tcs3414_data *data = iio_priv(indio_dev);
+
+ data->control |= TCS3414_CONTROL_ADC_EN;
+ return i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control);
+}
+
+static int tcs3414_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct tcs3414_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = iio_triggered_buffer_predisable(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ data->control &= ~TCS3414_CONTROL_ADC_EN;
+ return i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control);
+}
+
+static const struct iio_buffer_setup_ops tcs3414_buffer_setup_ops = {
+ .preenable = tcs3414_buffer_preenable,
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = tcs3414_buffer_predisable,
+};
+
+static int tcs3414_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct tcs3414_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ 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->info = &tcs3414_info;
+ indio_dev->name = TCS3414_DRV_NAME;
+ indio_dev->channels = tcs3414_channels;
+ indio_dev->num_channels = ARRAY_SIZE(tcs3414_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = i2c_smbus_read_byte_data(data->client, TCS3414_ID);
+ if (ret < 0)
+ return ret;
+
+ switch (ret & 0xf0) {
+ case 0x00:
+ dev_info(&client->dev, "TCS3404 found\n");
+ break;
+ case 0x10:
+ dev_info(&client->dev, "TCS3413/14/15/16 found\n");
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ data->control = TCS3414_CONTROL_POWER;
+ ret = i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control);
+ if (ret < 0)
+ return ret;
+
+ data->timing = TCS3414_INTEG_12MS; /* free running */
+ ret = i2c_smbus_write_byte_data(data->client, TCS3414_TIMING,
+ data->timing);
+ if (ret < 0)
+ return ret;
+
+ ret = i2c_smbus_read_byte_data(data->client, TCS3414_GAIN);
+ if (ret < 0)
+ return ret;
+ data->gain = ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ tcs3414_trigger_handler, &tcs3414_buffer_setup_ops);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0)
+ goto buffer_cleanup;
+
+ return 0;
+
+buffer_cleanup:
+ iio_triggered_buffer_cleanup(indio_dev);
+ return ret;
+}
+
+static int tcs3414_powerdown(struct tcs3414_data *data)
+{
+ return i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control & ~(TCS3414_CONTROL_POWER |
+ TCS3414_CONTROL_ADC_EN));
+}
+
+static int tcs3414_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);
+ tcs3414_powerdown(iio_priv(indio_dev));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tcs3414_suspend(struct device *dev)
+{
+ struct tcs3414_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+ return tcs3414_powerdown(data);
+}
+
+static int tcs3414_resume(struct device *dev)
+{
+ struct tcs3414_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+ return i2c_smbus_write_byte_data(data->client, TCS3414_CONTROL,
+ data->control);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tcs3414_pm_ops, tcs3414_suspend, tcs3414_resume);
+
+static const struct i2c_device_id tcs3414_id[] = {
+ { "tcs3414", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tcs3414_id);
+
+static struct i2c_driver tcs3414_driver = {
+ .driver = {
+ .name = TCS3414_DRV_NAME,
+ .pm = &tcs3414_pm_ops,
+ .owner = THIS_MODULE,
+ },
+ .probe = tcs3414_probe,
+ .remove = tcs3414_remove,
+ .id_table = tcs3414_id,
+};
+module_i2c_driver(tcs3414_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("TCS3414 digital color sensors driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
index fe063a0a21cd..752569985d1d 100644
--- a/drivers/iio/light/tcs3472.c
+++ b/drivers/iio/light/tcs3472.c
@@ -52,6 +52,7 @@
struct tcs3472_data {
struct i2c_client *client;
+ struct mutex lock;
u8 enable;
u8 control;
u8 atime;
@@ -116,10 +117,17 @@ static int tcs3472_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ mutex_lock(&data->lock);
ret = tcs3472_req_data(data);
- if (ret < 0)
+ if (ret < 0) {
+ mutex_unlock(&data->lock);
return ret;
+ }
ret = i2c_smbus_read_word_data(data->client, chan->address);
+ mutex_unlock(&data->lock);
if (ret < 0)
return ret;
*val = ret;
@@ -255,6 +263,7 @@ static int tcs3472_probe(struct i2c_client *client,
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->info = &tcs3472_info;
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index 05a364c543f8..b2dba9e506ab 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -17,6 +17,16 @@ config AK8975
To compile this driver as a module, choose M here: the module
will be called ak8975.
+config AK09911
+ tristate "Asahi Kasei AK09911 3-axis Compass"
+ depends on I2C
+ help
+ Say yes here to build support for Asahi Kasei AK09911 3-Axis
+ Magnetometer.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ak09911.
+
config MAG3110
tristate "Freescale MAG3110 3-Axis Magnetometer"
depends on I2C
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 0f5d3c985799..b91315e0b826 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -3,6 +3,7 @@
#
# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_AK09911) += ak09911.o
obj-$(CONFIG_AK8975) += ak8975.o
obj-$(CONFIG_MAG3110) += mag3110.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
diff --git a/drivers/iio/magnetometer/ak09911.c b/drivers/iio/magnetometer/ak09911.c
new file mode 100644
index 000000000000..b2bc942ff6b8
--- /dev/null
+++ b/drivers/iio/magnetometer/ak09911.c
@@ -0,0 +1,326 @@
+/*
+ * AK09911 3-axis compass driver
+ * Copyright (c) 2014, Intel 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/iio/iio.h>
+
+#define AK09911_REG_WIA1 0x00
+#define AK09911_REG_WIA2 0x01
+#define AK09911_WIA1_VALUE 0x48
+#define AK09911_WIA2_VALUE 0x05
+
+#define AK09911_REG_ST1 0x10
+#define AK09911_REG_HXL 0x11
+#define AK09911_REG_HXH 0x12
+#define AK09911_REG_HYL 0x13
+#define AK09911_REG_HYH 0x14
+#define AK09911_REG_HZL 0x15
+#define AK09911_REG_HZH 0x16
+
+#define AK09911_REG_ASAX 0x60
+#define AK09911_REG_ASAY 0x61
+#define AK09911_REG_ASAZ 0x62
+
+#define AK09911_REG_CNTL1 0x30
+#define AK09911_REG_CNTL2 0x31
+#define AK09911_REG_CNTL3 0x32
+
+#define AK09911_MODE_SNG_MEASURE 0x01
+#define AK09911_MODE_SELF_TEST 0x10
+#define AK09911_MODE_FUSE_ACCESS 0x1F
+#define AK09911_MODE_POWERDOWN 0x00
+#define AK09911_RESET_DATA 0x01
+
+#define AK09911_REG_CNTL1 0x30
+#define AK09911_REG_CNTL2 0x31
+#define AK09911_REG_CNTL3 0x32
+
+#define AK09911_RAW_TO_GAUSS(asa) ((((asa) + 128) * 6000) / 256)
+
+#define AK09911_MAX_CONVERSION_TIMEOUT_MS 500
+#define AK09911_CONVERSION_DONE_POLL_TIME_MS 10
+
+struct ak09911_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 asa[3];
+ long raw_to_gauss[3];
+};
+
+static const int ak09911_index_to_reg[] = {
+ AK09911_REG_HXL, AK09911_REG_HYL, AK09911_REG_HZL,
+};
+
+static int ak09911_set_mode(struct i2c_client *client, u8 mode)
+{
+ int ret;
+
+ switch (mode) {
+ case AK09911_MODE_SNG_MEASURE:
+ case AK09911_MODE_SELF_TEST:
+ case AK09911_MODE_FUSE_ACCESS:
+ case AK09911_MODE_POWERDOWN:
+ ret = i2c_smbus_write_byte_data(client,
+ AK09911_REG_CNTL2, mode);
+ if (ret < 0) {
+ dev_err(&client->dev, "set_mode error\n");
+ return ret;
+ }
+ /* After mode change wait atleast 100us */
+ usleep_range(100, 500);
+ break;
+ default:
+ dev_err(&client->dev,
+ "%s: Unknown mode(%d).", __func__, mode);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Get Sensitivity Adjustment value */
+static int ak09911_get_asa(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct ak09911_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = ak09911_set_mode(client, AK09911_MODE_FUSE_ACCESS);
+ if (ret < 0)
+ return ret;
+
+ /* Get asa data and store in the device data. */
+ ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_ASAX,
+ 3, data->asa);
+ if (ret < 0) {
+ dev_err(&client->dev, "Not able to read asa data\n");
+ return ret;
+ }
+
+ ret = ak09911_set_mode(client, AK09911_MODE_POWERDOWN);
+ if (ret < 0)
+ return ret;
+
+ data->raw_to_gauss[0] = AK09911_RAW_TO_GAUSS(data->asa[0]);
+ data->raw_to_gauss[1] = AK09911_RAW_TO_GAUSS(data->asa[1]);
+ data->raw_to_gauss[2] = AK09911_RAW_TO_GAUSS(data->asa[2]);
+
+ return 0;
+}
+
+static int ak09911_verify_chip_id(struct i2c_client *client)
+{
+ u8 wia_val[2];
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_WIA1,
+ 2, wia_val);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error reading WIA\n");
+ return ret;
+ }
+
+ dev_dbg(&client->dev, "WIA %02x %02x\n", wia_val[0], wia_val[1]);
+
+ if (wia_val[0] != AK09911_WIA1_VALUE ||
+ wia_val[1] != AK09911_WIA2_VALUE) {
+ dev_err(&client->dev, "Device ak09911 not found\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int wait_conversion_complete_polled(struct ak09911_data *data)
+{
+ struct i2c_client *client = data->client;
+ u8 read_status;
+ u32 timeout_ms = AK09911_MAX_CONVERSION_TIMEOUT_MS;
+ int ret;
+
+ /* Wait for the conversion to complete. */
+ while (timeout_ms) {
+ msleep_interruptible(AK09911_CONVERSION_DONE_POLL_TIME_MS);
+ ret = i2c_smbus_read_byte_data(client, AK09911_REG_ST1);
+ if (ret < 0) {
+ dev_err(&client->dev, "Error in reading ST1\n");
+ return ret;
+ }
+ read_status = ret & 0x01;
+ if (read_status)
+ break;
+ timeout_ms -= AK09911_CONVERSION_DONE_POLL_TIME_MS;
+ }
+ if (!timeout_ms) {
+ dev_err(&client->dev, "Conversion timeout happened\n");
+ return -EIO;
+ }
+
+ return read_status;
+}
+
+static int ak09911_read_axis(struct iio_dev *indio_dev, int index, int *val)
+{
+ struct ak09911_data *data = iio_priv(indio_dev);
+ struct i2c_client *client = data->client;
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ ret = ak09911_set_mode(client, AK09911_MODE_SNG_MEASURE);
+ if (ret < 0)
+ goto fn_exit;
+
+ ret = wait_conversion_complete_polled(data);
+ if (ret < 0)
+ goto fn_exit;
+
+ /* Read data */
+ ret = i2c_smbus_read_word_data(client, ak09911_index_to_reg[index]);
+ if (ret < 0) {
+ dev_err(&client->dev, "Read axis data fails\n");
+ goto fn_exit;
+ }
+
+ mutex_unlock(&data->lock);
+
+ /* Clamp to valid range. */
+ *val = sign_extend32(clamp_t(s16, ret, -8192, 8191), 13);
+
+ return IIO_VAL_INT;
+
+fn_exit:
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static int ak09911_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2,
+ long mask)
+{
+ struct ak09911_data *data = iio_priv(indio_dev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ return ak09911_read_axis(indio_dev, chan->address, val);
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = data->raw_to_gauss[chan->address];
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+
+ return -EINVAL;
+}
+
+#define AK09911_CHANNEL(axis, index) \
+ { \
+ .type = IIO_MAGN, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ }
+
+static const struct iio_chan_spec ak09911_channels[] = {
+ AK09911_CHANNEL(X, 0), AK09911_CHANNEL(Y, 1), AK09911_CHANNEL(Z, 2),
+};
+
+static const struct iio_info ak09911_info = {
+ .read_raw = &ak09911_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static const struct acpi_device_id ak_acpi_match[] = {
+ {"AK009911", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
+
+static int ak09911_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct ak09911_data *data;
+ const char *name;
+ int ret;
+
+ ret = ak09911_verify_chip_id(client);
+ if (ret) {
+ dev_err(&client->dev, "AK00911 not detected\n");
+ return -ENODEV;
+ }
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+
+ data->client = client;
+ mutex_init(&data->lock);
+
+ ret = ak09911_get_asa(client);
+ if (ret)
+ return ret;
+
+ if (id)
+ name = id->name;
+ else if (ACPI_HANDLE(&client->dev))
+ name = dev_name(&client->dev);
+ else
+ return -ENODEV;
+
+ dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->channels = ak09911_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ak09911_channels);
+ indio_dev->info = &ak09911_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->name = name;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id ak09911_id[] = {
+ {"ak09911", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ak09911_id);
+
+static struct i2c_driver ak09911_driver = {
+ .driver = {
+ .name = "ak09911",
+ .acpi_match_table = ACPI_PTR(ak_acpi_match),
+ },
+ .probe = ak09911_probe,
+ .id_table = ak09911_id,
+};
+module_i2c_driver(ak09911_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("AK09911 Compass driver");
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index ea08313af0d2..a2357921d761 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -165,7 +165,7 @@ static int ak8975_setup_irq(struct ak8975_data *data)
else
irq = gpio_to_irq(data->eoc_gpio);
- rc = request_irq(irq, ak8975_irq_handler,
+ rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
dev_name(&client->dev), data);
if (rc < 0) {
@@ -513,21 +513,21 @@ static int ak8975_probe(struct i2c_client *client,
/* We may not have a GPIO based IRQ to scan, that is fine, we will
poll if so */
if (gpio_is_valid(eoc_gpio)) {
- err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975");
+ err = devm_gpio_request_one(&client->dev, eoc_gpio,
+ GPIOF_IN, "ak_8975");
if (err < 0) {
dev_err(&client->dev,
"failed to request GPIO %d, error %d\n",
eoc_gpio, err);
- goto exit;
+ return err;
}
}
/* Register with IIO */
- indio_dev = iio_device_alloc(sizeof(*data));
- if (indio_dev == NULL) {
- err = -ENOMEM;
- goto exit_gpio;
- }
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
@@ -542,17 +542,16 @@ static int ak8975_probe(struct i2c_client *client,
name = (char *) id->name;
} else if (ACPI_HANDLE(&client->dev))
name = ak8975_match_acpi_device(&client->dev, &data->chipset);
- else {
- err = -ENOSYS;
- goto exit_free_iio;
- }
+ else
+ return -ENOSYS;
+
dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
/* Perform some basic start-of-day setup of the device. */
err = ak8975_setup(client);
if (err < 0) {
dev_err(&client->dev, "AK8975 initialization fails\n");
- goto exit_free_iio;
+ return err;
}
data->client = client;
@@ -564,37 +563,9 @@ static int ak8975_probe(struct i2c_client *client,
indio_dev->info = &ak8975_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = name;
- err = iio_device_register(indio_dev);
+ err = devm_iio_device_register(&client->dev, indio_dev);
if (err < 0)
- goto exit_free_iio;
-
- return 0;
-
-exit_free_iio:
- iio_device_free(indio_dev);
- if (data->eoc_irq)
- free_irq(data->eoc_irq, data);
-exit_gpio:
- if (gpio_is_valid(eoc_gpio))
- gpio_free(eoc_gpio);
-exit:
- return err;
-}
-
-static int ak8975_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ak8975_data *data = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
-
- if (data->eoc_irq)
- free_irq(data->eoc_irq, data);
-
- if (gpio_is_valid(data->eoc_gpio))
- gpio_free(data->eoc_gpio);
-
- iio_device_free(indio_dev);
+ return err;
return 0;
}
@@ -621,7 +592,6 @@ static struct i2c_driver ak8975_driver = {
.acpi_match_table = ACPI_PTR(ak_acpi_match),
},
.probe = ak8975_probe,
- .remove = ak8975_remove,
.id_table = ak8975_id,
};
module_i2c_driver(ak8975_driver);
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 41cf29e2a371..3ec777a8f64e 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -35,6 +35,10 @@ enum magn_3d_channel {
CHANNEL_SCAN_INDEX_X,
CHANNEL_SCAN_INDEX_Y,
CHANNEL_SCAN_INDEX_Z,
+ CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP,
+ CHANNEL_SCAN_INDEX_NORTH_TRUE_TILT_COMP,
+ CHANNEL_SCAN_INDEX_NORTH_MAGN,
+ CHANNEL_SCAN_INDEX_NORTH_TRUE,
MAGN_3D_CHANNEL_MAX,
};
@@ -42,7 +46,12 @@ struct magn_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info magn[MAGN_3D_CHANNEL_MAX];
- u32 magn_val[MAGN_3D_CHANNEL_MAX];
+
+ /* dynamically sized array to hold sensor values */
+ u32 *iio_vals;
+ /* array of pointers to sensor value */
+ u32 *magn_val_addr[MAGN_3D_CHANNEL_MAX];
+
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -52,7 +61,11 @@ struct magn_3d_state {
static const u32 magn_3d_addresses[MAGN_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS,
HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS,
- HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS
+ HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS,
+ HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH,
+ HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH,
+ HID_USAGE_SENSOR_ORIENT_MAGN_NORTH,
+ HID_USAGE_SENSOR_ORIENT_TRUE_NORTH,
};
/* Channel definitions */
@@ -66,7 +79,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
- .scan_index = CHANNEL_SCAN_INDEX_X,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -76,7 +88,6 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
- .scan_index = CHANNEL_SCAN_INDEX_Y,
}, {
.type = IIO_MAGN,
.modified = 1,
@@ -86,7 +97,42 @@ static const struct iio_chan_spec magn_3d_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
- .scan_index = CHANNEL_SCAN_INDEX_Z,
+ }, {
+ .type = IIO_ROT,
+ .modified = 1,
+ .channel2 = IIO_MOD_NORTH_MAGN_TILT_COMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ }, {
+ .type = IIO_ROT,
+ .modified = 1,
+ .channel2 = IIO_MOD_NORTH_TRUE_TILT_COMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ }, {
+ .type = IIO_ROT,
+ .modified = 1,
+ .channel2 = IIO_MOD_NORTH_MAGN,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ }, {
+ .type = IIO_ROT,
+ .modified = 1,
+ .channel2 = IIO_MOD_NORTH_TRUE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
}
};
@@ -110,7 +156,6 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -127,8 +172,8 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
msleep_interruptible(poll_value * 2);
report_id =
- magn_state->magn[chan->scan_index].report_id;
- address = magn_3d_addresses[chan->scan_index];
+ magn_state->magn[chan->address].report_id;
+ address = magn_3d_addresses[chan->address];
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
magn_state->common_attributes.hsdev,
@@ -153,14 +198,12 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&magn_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&magn_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
@@ -221,8 +264,8 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
dev_dbg(&indio_dev->dev, "magn_3d_proc_event\n");
if (atomic_read(&magn_state->common_attributes.data_ready))
hid_sensor_push_data(indio_dev,
- magn_state->magn_val,
- sizeof(magn_state->magn_val));
+ magn_state->iio_vals,
+ sizeof(magn_state->iio_vals));
return 0;
}
@@ -236,52 +279,126 @@ static int magn_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct magn_3d_state *magn_state = iio_priv(indio_dev);
int offset;
- int ret = -EINVAL;
+ int ret = 0;
+ u32 *iio_val = NULL;
switch (usage_id) {
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Y_AXIS:
case HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_Z_AXIS:
- offset = usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS;
- magn_state->magn_val[CHANNEL_SCAN_INDEX_X + offset] =
- *(u32 *)raw_data;
- ret = 0;
+ offset = (usage_id - HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS)
+ + CHANNEL_SCAN_INDEX_X;
+ break;
+ case HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH:
+ case HID_USAGE_SENSOR_ORIENT_COMP_TRUE_NORTH:
+ case HID_USAGE_SENSOR_ORIENT_MAGN_NORTH:
+ case HID_USAGE_SENSOR_ORIENT_TRUE_NORTH:
+ offset = (usage_id - HID_USAGE_SENSOR_ORIENT_COMP_MAGN_NORTH)
+ + CHANNEL_SCAN_INDEX_NORTH_MAGN_TILT_COMP;
break;
default:
- break;
+ return -EINVAL;
}
+ iio_val = magn_state->magn_val_addr[offset];
+
+ if (iio_val != NULL)
+ *iio_val = *((u32 *)raw_data);
+ else
+ ret = -EINVAL;
+
return ret;
}
/* Parse report which is specific to an usage id*/
static int magn_3d_parse_report(struct platform_device *pdev,
struct hid_sensor_hub_device *hsdev,
- struct iio_chan_spec *channels,
+ struct iio_chan_spec **channels,
+ int *chan_count,
unsigned usage_id,
struct magn_3d_state *st)
{
- int ret;
int i;
+ int attr_count = 0;
+ struct iio_chan_spec *_channels;
+
+ /* Scan for each usage attribute supported */
+ for (i = 0; i < MAGN_3D_CHANNEL_MAX; i++) {
+ int status;
+ u32 address = magn_3d_addresses[i];
+
+ /* Check if usage attribute exists in the sensor hub device */
+ status = sensor_hub_input_get_attribute_info(hsdev,
+ HID_INPUT_REPORT,
+ usage_id,
+ address,
+ &(st->magn[i]));
+ if (!status)
+ attr_count++;
+ }
- for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
- ret = sensor_hub_input_get_attribute_info(hsdev,
- HID_INPUT_REPORT,
- usage_id,
- HID_USAGE_SENSOR_ORIENT_MAGN_FLUX_X_AXIS + i,
- &st->magn[CHANNEL_SCAN_INDEX_X + i]);
- if (ret < 0)
- break;
- magn_3d_adjust_channel_bit_mask(channels,
- CHANNEL_SCAN_INDEX_X + i,
- st->magn[CHANNEL_SCAN_INDEX_X + i].size);
+ if (attr_count <= 0) {
+ dev_err(&pdev->dev,
+ "failed to find any supported usage attributes in report\n");
+ return -EINVAL;
}
- dev_dbg(&pdev->dev, "magn_3d %x:%x, %x:%x, %x:%x\n",
+
+ dev_dbg(&pdev->dev, "magn_3d Found %d usage attributes\n",
+ attr_count);
+ dev_dbg(&pdev->dev, "magn_3d X: %x:%x Y: %x:%x Z: %x:%x\n",
st->magn[0].index,
st->magn[0].report_id,
st->magn[1].index, st->magn[1].report_id,
st->magn[2].index, st->magn[2].report_id);
+ /* Setup IIO channel array */
+ _channels = devm_kcalloc(&pdev->dev, attr_count,
+ sizeof(struct iio_chan_spec),
+ GFP_KERNEL);
+ if (!_channels) {
+ dev_err(&pdev->dev,
+ "failed to allocate space for iio channels\n");
+ return -ENOMEM;
+ }
+
+ st->iio_vals = devm_kcalloc(&pdev->dev, attr_count,
+ sizeof(u32),
+ GFP_KERNEL);
+ if (!st->iio_vals) {
+ dev_err(&pdev->dev,
+ "failed to allocate space for iio values array\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0, *chan_count = 0;
+ i < MAGN_3D_CHANNEL_MAX && *chan_count < attr_count;
+ i++){
+ if (st->magn[i].index >= 0) {
+ /* Setup IIO channel struct */
+ (_channels[*chan_count]) = magn_3d_channels[i];
+ (_channels[*chan_count]).scan_index = *chan_count;
+ (_channels[*chan_count]).address = i;
+
+ /* Set magn_val_addr to iio value address */
+ st->magn_val_addr[i] = &(st->iio_vals[*chan_count]);
+ magn_3d_adjust_channel_bit_mask(_channels,
+ *chan_count,
+ st->magn[i].size);
+ (*chan_count)++;
+ }
+ }
+
+ if (*chan_count <= 0) {
+ dev_err(&pdev->dev,
+ "failed to find any magnetic channels setup\n");
+ return -EINVAL;
+ }
+
+ *channels = _channels;
+
+ dev_dbg(&pdev->dev, "magn_3d Setup %d IIO channels\n",
+ *chan_count);
+
st->scale_precision = hid_sensor_format_scale(
HID_USAGE_SENSOR_COMPASS_3D,
&st->magn[CHANNEL_SCAN_INDEX_X],
@@ -299,7 +416,7 @@ static int magn_3d_parse_report(struct platform_device *pdev,
st->common_attributes.sensitivity.report_id);
}
- return ret;
+ return 0;
}
/* Function to initialize the processing for usage id */
@@ -311,6 +428,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
struct magn_3d_state *magn_state;
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
+ int chan_count = 0;
indio_dev = devm_iio_device_alloc(&pdev->dev,
sizeof(struct magn_3d_state));
@@ -331,22 +449,16 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
return ret;
}
- channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
- GFP_KERNEL);
- if (!channels) {
- dev_err(&pdev->dev, "failed to duplicate channels\n");
- return -ENOMEM;
- }
-
- ret = magn_3d_parse_report(pdev, hsdev, channels,
+ ret = magn_3d_parse_report(pdev, hsdev,
+ &channels, &chan_count,
HID_USAGE_SENSOR_COMPASS_3D, magn_state);
if (ret) {
- dev_err(&pdev->dev, "failed to setup attributes\n");
- goto error_free_dev_mem;
+ dev_err(&pdev->dev, "failed to parse report\n");
+ return ret;
}
indio_dev->channels = channels;
- indio_dev->num_channels = ARRAY_SIZE(magn_3d_channels);
+ indio_dev->num_channels = chan_count;
indio_dev->dev.parent = &pdev->dev;
indio_dev->info = &magn_3d_info;
indio_dev->name = name;
@@ -356,7 +468,7 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
NULL, NULL);
if (ret) {
dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
- goto error_free_dev_mem;
+ return ret;
}
atomic_set(&magn_state->common_attributes.data_ready, 0);
ret = hid_sensor_setup_trigger(indio_dev, name,
@@ -390,8 +502,6 @@ error_remove_trigger:
hid_sensor_remove_trigger(&magn_state->common_attributes);
error_unreg_buffer_funcs:
iio_triggered_buffer_cleanup(indio_dev);
-error_free_dev_mem:
- kfree(indio_dev->channels);
return ret;
}
@@ -406,7 +516,6 @@ static int hid_magn_3d_remove(struct platform_device *pdev)
iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(&magn_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
- kfree(indio_dev->channels);
return 0;
}
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c
index 240a21dd0c61..a4b64130ac2f 100644
--- a/drivers/iio/magnetometer/st_magn_core.c
+++ b/drivers/iio/magnetometer/st_magn_core.c
@@ -299,6 +299,9 @@ static int st_magn_read_raw(struct iio_dev *indio_dev,
else
*val2 = mdata->current_fullscale->gain;
return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = mdata->odr;
+ return IIO_VAL_INT;
default:
return -EINVAL;
}
@@ -316,6 +319,13 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ err = st_sensors_set_odr(indio_dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return err;
default:
err = -EINVAL;
}
@@ -323,14 +333,12 @@ static int st_magn_write_raw(struct iio_dev *indio_dev,
return err;
}
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
static struct attribute *st_magn_attributes[] = {
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_magn_scale_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL,
};
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index 892e0feeb5c1..689250058442 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -18,6 +18,27 @@
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_magn.h"
+#ifdef CONFIG_OF
+static const struct of_device_id st_magn_of_match[] = {
+ {
+ .compatible = "st,lsm303dlhc-magn",
+ .data = LSM303DLHC_MAGN_DEV_NAME,
+ },
+ {
+ .compatible = "st,lsm303dlm-magn",
+ .data = LSM303DLM_MAGN_DEV_NAME,
+ },
+ {
+ .compatible = "st,lis3mdl-magn",
+ .data = LIS3MDL_MAGN_DEV_NAME,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_magn_of_match);
+#else
+#define st_magn_of_match NULL
+#endif
+
static int st_magn_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -31,6 +52,7 @@ static int st_magn_i2c_probe(struct i2c_client *client,
mdata = iio_priv(indio_dev);
mdata->dev = &client->dev;
+ st_sensors_of_i2c_probe(client, st_magn_of_match);
st_sensors_i2c_configure(indio_dev, client, mdata);
@@ -61,6 +83,7 @@ static struct i2c_driver st_magn_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-magn-i2c",
+ .of_match_table = of_match_ptr(st_magn_of_match),
},
.probe = st_magn_i2c_probe,
.remove = st_magn_i2c_remove,
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index ffac8ac1efca..15afbc919521 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -70,4 +70,14 @@ config IIO_ST_PRESS_SPI
depends on IIO_ST_PRESS
depends on IIO_ST_SENSORS_SPI
+config T5403
+ tristate "EPCOS T5403 digital barometric pressure sensor driver"
+ depends on I2C
+ help
+ Say yes here to build support for the EPCOS T5403 pressure sensor
+ connected via I2C.
+
+ To compile this driver as a module, choose M here: the module
+ will be called t5403.
+
endmenu
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index c53d2500737a..90a37e85cf21 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_MPL3115) += mpl3115.o
obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
st_pressure-y := st_pressure_core.o
st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
+obj-$(CONFIG_T5403) += t5403.o
obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 1cd190c73788..2c0d2a4fed8c 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -78,7 +78,6 @@ static int press_read_raw(struct iio_dev *indio_dev,
struct press_state *press_state = iio_priv(indio_dev);
int report_id = -1;
u32 address;
- int ret;
int ret_type;
s32 poll_value;
@@ -128,14 +127,12 @@ static int press_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = hid_sensor_read_samp_freq_value(
+ ret_type = hid_sensor_read_samp_freq_value(
&press_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
case IIO_CHAN_INFO_HYSTERESIS:
- ret = hid_sensor_read_raw_hyst_value(
+ ret_type = hid_sensor_read_raw_hyst_value(
&press_state->common_attributes, val, val2);
- ret_type = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret_type = -EINVAL;
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index cd7e01f3a93b..473d914ef470 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -307,6 +307,27 @@ static const struct st_sensors st_press_sensors[] = {
},
};
+static int st_press_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *ch,
+ int val,
+ int val2,
+ long mask)
+{
+ int err;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val2)
+ return -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ err = st_sensors_set_odr(indio_dev, val);
+ mutex_unlock(&indio_dev->mlock);
+ return err;
+ default:
+ return -EINVAL;
+ }
+}
+
static int st_press_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *ch, int *val,
int *val2, long mask)
@@ -349,6 +370,9 @@ static int st_press_read_raw(struct iio_dev *indio_dev,
}
return IIO_VAL_FRACTIONAL;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = pdata->odr;
+ return IIO_VAL_INT;
default:
return -EINVAL;
}
@@ -357,12 +381,10 @@ read_error:
return err;
}
-static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
static struct attribute *st_press_attributes[] = {
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_sampling_frequency.dev_attr.attr,
NULL,
};
@@ -374,6 +396,7 @@ static const struct iio_info press_info = {
.driver_module = THIS_MODULE,
.attrs = &st_press_attribute_group,
.read_raw = &st_press_read_raw,
+ .write_raw = &st_press_write_raw,
};
#ifdef CONFIG_IIO_TRIGGER
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index 3cd73e39b840..acaf165260bb 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -18,6 +18,27 @@
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_pressure.h"
+#ifdef CONFIG_OF
+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,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_press_of_match);
+#else
+#define st_press_of_match NULL
+#endif
+
static int st_press_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -31,6 +52,7 @@ static int st_press_i2c_probe(struct i2c_client *client,
pdata = iio_priv(indio_dev);
pdata->dev = &client->dev;
+ st_sensors_of_i2c_probe(client, st_press_of_match);
st_sensors_i2c_configure(indio_dev, client, pdata);
@@ -60,6 +82,7 @@ static struct i2c_driver st_press_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "st-press-i2c",
+ .of_match_table = of_match_ptr(st_press_of_match),
},
.probe = st_press_i2c_probe,
.remove = st_press_i2c_remove,
diff --git a/drivers/iio/pressure/t5403.c b/drivers/iio/pressure/t5403.c
new file mode 100644
index 000000000000..e11cd3938d67
--- /dev/null
+++ b/drivers/iio/pressure/t5403.c
@@ -0,0 +1,275 @@
+/*
+ * t5403.c - Support for EPCOS T5403 pressure/temperature sensor
+ *
+ * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * 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
+ * directory of this archive for more details.
+ *
+ * (7-bit I2C slave address 0x77)
+ *
+ * TODO: end-of-conversion irq
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/delay.h>
+
+#define T5403_DATA 0xf5 /* data, LSB first, 16 bit */
+#define T5403_CALIB_DATA 0x8e /* 10 calibration coeff., LSB first, 16 bit */
+#define T5403_SLAVE_ADDR 0x88 /* I2C slave address, 0x77 */
+#define T5403_COMMAND 0xf1
+
+/* command bits */
+#define T5403_MODE_SHIFT 3 /* conversion time: 2, 8, 16, 66 ms */
+#define T5403_PT BIT(1) /* 0 .. pressure, 1 .. temperature measurement */
+#define T5403_SCO BIT(0) /* start conversion */
+
+#define T5403_MODE_LOW 0
+#define T5403_MODE_STANDARD 1
+#define T5403_MODE_HIGH 2
+#define T5403_MODE_ULTRA_HIGH 3
+
+#define T5403_I2C_MASK (~BIT(7))
+#define T5403_I2C_ADDR 0x77
+
+static const int t5403_pressure_conv_ms[] = {2, 8, 16, 66};
+
+struct t5403_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ int mode;
+ __le16 c[10];
+};
+
+#define T5403_C_U16(i) le16_to_cpu(data->c[(i) - 1])
+#define T5403_C(i) sign_extend32(T5403_C_U16(i), 15)
+
+static int t5403_read(struct t5403_data *data, bool pressure)
+{
+ int wait_time = 3; /* wakeup time in ms */
+
+ int ret = i2c_smbus_write_byte_data(data->client, T5403_COMMAND,
+ (pressure ? (data->mode << T5403_MODE_SHIFT) : T5403_PT) |
+ T5403_SCO);
+ if (ret < 0)
+ return ret;
+
+ wait_time += pressure ? t5403_pressure_conv_ms[data->mode] : 2;
+
+ msleep(wait_time);
+
+ return i2c_smbus_read_word_data(data->client, T5403_DATA);
+}
+
+static int t5403_comp_pressure(struct t5403_data *data, int *val, int *val2)
+{
+ int ret;
+ s16 t_r;
+ u16 p_r;
+ s32 S, O, X;
+
+ mutex_lock(&data->lock);
+
+ ret = t5403_read(data, false);
+ if (ret < 0)
+ goto done;
+ t_r = ret;
+
+ ret = t5403_read(data, true);
+ if (ret < 0)
+ goto done;
+ p_r = ret;
+
+ /* see EPCOS application note */
+ S = T5403_C_U16(3) + (s32) T5403_C_U16(4) * t_r / 0x20000 +
+ T5403_C(5) * t_r / 0x8000 * t_r / 0x80000 +
+ T5403_C(9) * t_r / 0x8000 * t_r / 0x8000 * t_r / 0x10000;
+
+ O = T5403_C(6) * 0x4000 + T5403_C(7) * t_r / 8 +
+ T5403_C(8) * t_r / 0x8000 * t_r / 16 +
+ T5403_C(9) * t_r / 0x8000 * t_r / 0x10000 * t_r;
+
+ X = (S * p_r + O) / 0x4000;
+
+ X += ((X - 75000) * (X - 75000) / 0x10000 - 9537) *
+ T5403_C(10) / 0x10000;
+
+ *val = X / 1000;
+ *val2 = (X % 1000) * 1000;
+
+done:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int t5403_comp_temp(struct t5403_data *data, int *val)
+{
+ int ret;
+ s16 t_r;
+
+ mutex_lock(&data->lock);
+ ret = t5403_read(data, false);
+ if (ret < 0)
+ goto done;
+ t_r = ret;
+
+ /* see EPCOS application note */
+ *val = ((s32) T5403_C_U16(1) * t_r / 0x100 +
+ (s32) T5403_C_U16(2) * 0x40) * 1000 / 0x10000;
+
+done:
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+static int t5403_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct t5403_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ switch (chan->type) {
+ case IIO_PRESSURE:
+ ret = t5403_comp_pressure(data, val, val2);
+ if (ret < 0)
+ return ret;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_TEMP:
+ ret = t5403_comp_temp(data, val);
+ if (ret < 0)
+ return ret;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_INT_TIME:
+ *val = 0;
+ *val2 = t5403_pressure_conv_ms[data->mode] * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int t5403_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct t5403_data *data = iio_priv(indio_dev);
+ int i;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_INT_TIME:
+ if (val != 0)
+ return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(t5403_pressure_conv_ms); i++)
+ if (val2 == t5403_pressure_conv_ms[i] * 1000) {
+ mutex_lock(&data->lock);
+ data->mode = i;
+ mutex_unlock(&data->lock);
+ return 0;
+ }
+ return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_chan_spec t5403_channels[] = {
+ {
+ .type = IIO_PRESSURE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+ BIT(IIO_CHAN_INFO_INT_TIME),
+ },
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+};
+
+static IIO_CONST_ATTR_INT_TIME_AVAIL("0.002 0.008 0.016 0.066");
+
+static struct attribute *t5403_attributes[] = {
+ &iio_const_attr_integration_time_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group t5403_attribute_group = {
+ .attrs = t5403_attributes,
+};
+
+static const struct iio_info t5403_info = {
+ .read_raw = &t5403_read_raw,
+ .write_raw = &t5403_write_raw,
+ .attrs = &t5403_attribute_group,
+ .driver_module = THIS_MODULE,
+};
+
+static int t5403_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct t5403_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENODEV;
+
+ ret = i2c_smbus_read_byte_data(client, T5403_SLAVE_ADDR);
+ if (ret < 0)
+ return ret;
+ if ((ret & T5403_I2C_MASK) != T5403_I2C_ADDR)
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ mutex_init(&data->lock);
+
+ i2c_set_clientdata(client, indio_dev);
+ indio_dev->info = &t5403_info;
+ indio_dev->name = id->name;
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = t5403_channels;
+ indio_dev->num_channels = ARRAY_SIZE(t5403_channels);
+
+ data->mode = T5403_MODE_STANDARD;
+
+ ret = i2c_smbus_read_i2c_block_data(data->client, T5403_CALIB_DATA,
+ sizeof(data->c), (u8 *) data->c);
+ if (ret < 0)
+ return ret;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id t5403_id[] = {
+ { "t5403", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, t5403_id);
+
+static struct i2c_driver t5403_driver = {
+ .driver = {
+ .name = "t5403",
+ },
+ .probe = t5403_probe,
+ .id_table = t5403_id,
+};
+module_i2c_driver(t5403_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("EPCOS T5403 pressure/temperature sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
index bf677bfe8eb2..5e780ef206f3 100644
--- a/drivers/iio/proximity/as3935.c
+++ b/drivers/iio/proximity/as3935.c
@@ -232,7 +232,7 @@ static void as3935_event_work(struct work_struct *work)
switch (val) {
case AS3935_EVENT_INT:
- iio_trigger_poll(st->trig, iio_get_time_ns());
+ iio_trigger_poll(st->trig);
break;
case AS3935_NOISE_INT:
dev_warn(&st->spi->dev, "noise level is too high");
diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c
index 02577ec54c6b..7a149a7822bc 100644
--- a/drivers/iio/trigger/iio-trig-interrupt.c
+++ b/drivers/iio/trigger/iio-trig-interrupt.c
@@ -24,8 +24,7 @@ struct iio_interrupt_trigger_info {
static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private)
{
- /* Timestamp not currently provided */
- iio_trigger_poll(private, 0);
+ iio_trigger_poll(private);
return IRQ_HANDLED;
}
diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
index 15e3b850f513..254c7e906127 100644
--- a/drivers/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/iio/trigger/iio-trig-sysfs.c
@@ -96,7 +96,7 @@ static void iio_sysfs_trigger_work(struct irq_work *work)
struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
work);
- iio_trigger_poll(trig->trig, 0);
+ iio_trigger_poll(trig->trig);
}
static ssize_t iio_sysfs_trigger_poll(struct device *dev,
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 8af33cf1fc4e..2d5cbf4363e4 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -734,7 +734,7 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
/* change ethxxx to iwxxx */
strcpy(name, "iw");
strcat(name, &c2dev->netdev->name[3]);
- netdev = alloc_netdev(0, name, setup);
+ netdev = alloc_netdev(0, name, NET_NAME_UNKNOWN, setup);
if (!netdev) {
printk(KERN_ERR PFX "%s - etherdev alloc failed",
__func__);
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 5e153f6d4b48..c2fb71c182a8 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -79,9 +79,10 @@ static int dack_mode = 1;
module_param(dack_mode, int, 0644);
MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");
-int c4iw_max_read_depth = 8;
+uint c4iw_max_read_depth = 32;
module_param(c4iw_max_read_depth, int, 0644);
-MODULE_PARM_DESC(c4iw_max_read_depth, "Per-connection max ORD/IRD (default=8)");
+MODULE_PARM_DESC(c4iw_max_read_depth,
+ "Per-connection max ORD/IRD (default=32)");
static int enable_tcp_timestamps;
module_param(enable_tcp_timestamps, int, 0644);
@@ -432,8 +433,17 @@ static void arp_failure_discard(void *handle, struct sk_buff *skb)
*/
static void act_open_req_arp_failure(void *handle, struct sk_buff *skb)
{
+ struct c4iw_ep *ep = handle;
+
printk(KERN_ERR MOD "ARP failure duing connect\n");
kfree_skb(skb);
+ connect_reply_upcall(ep, -EHOSTUNREACH);
+ state_set(&ep->com, DEAD);
+ remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
+ cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
+ dst_release(ep->dst);
+ cxgb4_l2t_release(ep->l2t);
+ c4iw_put_ep(&ep->com);
}
/*
@@ -465,7 +475,8 @@ static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
16)) | FW_WR_FLOWID(ep->hwtid));
flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
- flowc->mnemval[0].val = cpu_to_be32(PCI_FUNC(ep->com.dev->rdev.lldi.pdev->devfn) << 8);
+ flowc->mnemval[0].val = cpu_to_be32(FW_PFVF_CMD_PFN
+ (ep->com.dev->rdev.lldi.pf));
flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan);
flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
@@ -658,7 +669,7 @@ static int send_connect(struct c4iw_ep *ep)
opt2 |= T5_OPT_2_VALID;
opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
}
- t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure);
+ t4_set_arp_err_handler(skb, ep, act_open_req_arp_failure);
if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) {
if (ep->com.remote_addr.ss_family == AF_INET) {
@@ -812,6 +823,8 @@ static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
if (mpa_rev_to_use == 2) {
mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
sizeof (struct mpa_v2_conn_params));
+ PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird,
+ ep->ord);
mpa_v2_params.ird = htons((u16)ep->ird);
mpa_v2_params.ord = htons((u16)ep->ord);
@@ -1181,8 +1194,8 @@ static int connect_request_upcall(struct c4iw_ep *ep)
sizeof(struct mpa_v2_conn_params);
} else {
/* this means MPA_v1 is used. Send max supported */
- event.ord = c4iw_max_read_depth;
- event.ird = c4iw_max_read_depth;
+ event.ord = cur_max_read_depth(ep->com.dev);
+ event.ird = cur_max_read_depth(ep->com.dev);
event.private_data_len = ep->plen;
event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
}
@@ -1246,6 +1259,8 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
return credits;
}
+#define RELAXED_IRD_NEGOTIATION 1
+
static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
{
struct mpa_message *mpa;
@@ -1357,17 +1372,33 @@ static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
MPA_V2_IRD_ORD_MASK;
resp_ord = ntohs(mpa_v2_params->ord) &
MPA_V2_IRD_ORD_MASK;
+ PDBG("%s responder ird %u ord %u ep ird %u ord %u\n",
+ __func__, resp_ird, resp_ord, ep->ird, ep->ord);
/*
* This is a double-check. Ideally, below checks are
* not required since ird/ord stuff has been taken
* care of in c4iw_accept_cr
*/
- if ((ep->ird < resp_ord) || (ep->ord > resp_ird)) {
+ if (ep->ird < resp_ord) {
+ if (RELAXED_IRD_NEGOTIATION && resp_ord <=
+ ep->com.dev->rdev.lldi.max_ordird_qp)
+ ep->ird = resp_ord;
+ else
+ insuff_ird = 1;
+ } else if (ep->ird > resp_ord) {
+ ep->ird = resp_ord;
+ }
+ if (ep->ord > resp_ird) {
+ if (RELAXED_IRD_NEGOTIATION)
+ ep->ord = resp_ird;
+ else
+ insuff_ird = 1;
+ }
+ if (insuff_ird) {
err = -ENOMEM;
ep->ird = resp_ord;
ep->ord = resp_ird;
- insuff_ird = 1;
}
if (ntohs(mpa_v2_params->ird) &
@@ -1570,6 +1601,8 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
MPA_V2_IRD_ORD_MASK;
ep->ord = ntohs(mpa_v2_params->ord) &
MPA_V2_IRD_ORD_MASK;
+ PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird,
+ ep->ord);
if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL)
if (peer2peer) {
if (ntohs(mpa_v2_params->ord) &
@@ -1789,6 +1822,20 @@ static int is_neg_adv(unsigned int status)
status == CPL_ERR_KEEPALV_NEG_ADVICE;
}
+static char *neg_adv_str(unsigned int status)
+{
+ switch (status) {
+ case CPL_ERR_RTX_NEG_ADVICE:
+ return "Retransmit timeout";
+ case CPL_ERR_PERSIST_NEG_ADVICE:
+ return "Persist timeout";
+ case CPL_ERR_KEEPALV_NEG_ADVICE:
+ return "Keepalive timeout";
+ default:
+ return "Unknown";
+ }
+}
+
static void set_tcp_window(struct c4iw_ep *ep, struct port_info *pi)
{
ep->snd_win = snd_win;
@@ -1987,8 +2034,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
status, status2errno(status));
if (is_neg_adv(status)) {
- printk(KERN_WARNING MOD "Connection problems for atid %u\n",
- atid);
+ dev_warn(&dev->rdev.lldi.pdev->dev,
+ "Connection problems for atid %u status %u (%s)\n",
+ atid, status, neg_adv_str(status));
return 0;
}
@@ -2180,7 +2228,6 @@ static void reject_cr(struct c4iw_dev *dev, u32 hwtid, struct sk_buff *skb)
PDBG("%s c4iw_dev %p tid %u\n", __func__, dev, hwtid);
BUG_ON(skb_cloned(skb));
skb_trim(skb, sizeof(struct cpl_tid_release));
- skb_get(skb);
release_tid(&dev->rdev, hwtid, skb);
return;
}
@@ -2464,8 +2511,9 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
ep = lookup_tid(t, tid);
if (is_neg_adv(req->status)) {
- PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
- ep->hwtid);
+ dev_warn(&dev->rdev.lldi.pdev->dev,
+ "Negative advice on abort - tid %u status %d (%s)\n",
+ ep->hwtid, req->status, neg_adv_str(req->status));
return 0;
}
PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
@@ -2723,8 +2771,8 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
BUG_ON(!qp);
set_bit(ULP_ACCEPT, &ep->com.history);
- if ((conn_param->ord > c4iw_max_read_depth) ||
- (conn_param->ird > c4iw_max_read_depth)) {
+ if ((conn_param->ord > cur_max_read_depth(ep->com.dev)) ||
+ (conn_param->ird > cur_max_read_depth(ep->com.dev))) {
abort_connection(ep, NULL, GFP_KERNEL);
err = -EINVAL;
goto err;
@@ -2732,31 +2780,41 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
if (conn_param->ord > ep->ird) {
- ep->ird = conn_param->ird;
- ep->ord = conn_param->ord;
- send_mpa_reject(ep, conn_param->private_data,
- conn_param->private_data_len);
- abort_connection(ep, NULL, GFP_KERNEL);
- err = -ENOMEM;
- goto err;
+ if (RELAXED_IRD_NEGOTIATION) {
+ ep->ord = ep->ird;
+ } else {
+ ep->ird = conn_param->ird;
+ ep->ord = conn_param->ord;
+ send_mpa_reject(ep, conn_param->private_data,
+ conn_param->private_data_len);
+ abort_connection(ep, NULL, GFP_KERNEL);
+ err = -ENOMEM;
+ goto err;
+ }
}
- if (conn_param->ird > ep->ord) {
- if (!ep->ord)
- conn_param->ird = 1;
- else {
+ if (conn_param->ird < ep->ord) {
+ if (RELAXED_IRD_NEGOTIATION &&
+ ep->ord <= h->rdev.lldi.max_ordird_qp) {
+ conn_param->ird = ep->ord;
+ } else {
abort_connection(ep, NULL, GFP_KERNEL);
err = -ENOMEM;
goto err;
}
}
-
}
ep->ird = conn_param->ird;
ep->ord = conn_param->ord;
- if (ep->mpa_attr.version != 2)
+ if (ep->mpa_attr.version == 1) {
if (peer2peer && ep->ird == 0)
ep->ird = 1;
+ } else {
+ if (peer2peer &&
+ (ep->mpa_attr.p2p_type != FW_RI_INIT_P2PTYPE_DISABLED) &&
+ (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ) && ep->ord == 0)
+ ep->ird = 1;
+ }
PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);
@@ -2795,6 +2853,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
return 0;
err1:
ep->com.cm_id = NULL;
+ abort_connection(ep, NULL, GFP_KERNEL);
cm_id->rem_ref(cm_id);
err:
mutex_unlock(&ep->com.mutex);
@@ -2878,8 +2937,8 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
int iptype;
int iwpm_err = 0;
- if ((conn_param->ord > c4iw_max_read_depth) ||
- (conn_param->ird > c4iw_max_read_depth)) {
+ if ((conn_param->ord > cur_max_read_depth(dev)) ||
+ (conn_param->ird > cur_max_read_depth(dev))) {
err = -EINVAL;
goto out;
}
@@ -3859,8 +3918,9 @@ static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
return 0;
}
if (is_neg_adv(req->status)) {
- PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
- ep->hwtid);
+ dev_warn(&dev->rdev.lldi.pdev->dev,
+ "Negative advice on abort - tid %u status %d (%s)\n",
+ ep->hwtid, req->status, neg_adv_str(req->status));
kfree_skb(skb);
return 0;
}
@@ -3917,7 +3977,7 @@ int __init c4iw_cm_init(void)
return 0;
}
-void __exit c4iw_cm_term(void)
+void c4iw_cm_term(void)
{
WARN_ON(!list_empty(&timeout_list));
flush_workqueue(workq);
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index c04292c950f1..0f773e78e080 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -633,11 +633,15 @@ proc_cqe:
wq->sq.cidx = (uint16_t)idx;
PDBG("%s completing sq idx %u\n", __func__, wq->sq.cidx);
*cookie = wq->sq.sw_sq[wq->sq.cidx].wr_id;
+ if (c4iw_wr_log)
+ c4iw_log_wr_stats(wq, hw_cqe);
t4_sq_consume(wq);
} else {
PDBG("%s completing rq idx %u\n", __func__, wq->rq.cidx);
*cookie = wq->rq.sw_rq[wq->rq.cidx].wr_id;
BUG_ON(t4_rq_empty(wq));
+ if (c4iw_wr_log)
+ c4iw_log_wr_stats(wq, hw_cqe);
t4_rq_consume(wq);
goto skip_cqe;
}
@@ -895,7 +899,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
/*
* Make actual HW queue 2x to avoid cdix_inc overflows.
*/
- hwentries = min(entries * 2, T4_MAX_IQ_SIZE);
+ hwentries = min(entries * 2, rhp->rdev.hw_queue.t4_max_iq_size);
/*
* Make HW queue at least 64 entries so GTS updates aren't too
@@ -909,14 +913,8 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
/*
* memsize must be a multiple of the page size if its a user cq.
*/
- if (ucontext) {
+ if (ucontext)
memsize = roundup(memsize, PAGE_SIZE);
- hwentries = memsize / sizeof *chp->cq.queue;
- while (hwentries > T4_MAX_IQ_SIZE) {
- memsize -= PAGE_SIZE;
- hwentries = memsize / sizeof *chp->cq.queue;
- }
- }
chp->cq.size = hwentries;
chp->cq.memsize = memsize;
chp->cq.vector = vector;
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index dd93aadc996e..f25df5276c22 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -33,6 +33,7 @@
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/vmalloc.h>
+#include <linux/math64.h>
#include <rdma/ib_verbs.h>
@@ -55,6 +56,15 @@ module_param(allow_db_coalescing_on_t5, int, 0644);
MODULE_PARM_DESC(allow_db_coalescing_on_t5,
"Allow DB Coalescing on T5 (default = 0)");
+int c4iw_wr_log = 0;
+module_param(c4iw_wr_log, int, 0444);
+MODULE_PARM_DESC(c4iw_wr_log, "Enables logging of work request timing data.");
+
+int c4iw_wr_log_size_order = 12;
+module_param(c4iw_wr_log_size_order, int, 0444);
+MODULE_PARM_DESC(c4iw_wr_log_size_order,
+ "Number of entries (log2) in the work request timing log.");
+
struct uld_ctx {
struct list_head entry;
struct cxgb4_lld_info lldi;
@@ -103,6 +113,117 @@ static ssize_t debugfs_read(struct file *file, char __user *buf, size_t count,
return simple_read_from_buffer(buf, count, ppos, d->buf, d->pos);
}
+void c4iw_log_wr_stats(struct t4_wq *wq, struct t4_cqe *cqe)
+{
+ struct wr_log_entry le;
+ int idx;
+
+ if (!wq->rdev->wr_log)
+ return;
+
+ idx = (atomic_inc_return(&wq->rdev->wr_log_idx) - 1) &
+ (wq->rdev->wr_log_size - 1);
+ le.poll_sge_ts = cxgb4_read_sge_timestamp(wq->rdev->lldi.ports[0]);
+ getnstimeofday(&le.poll_host_ts);
+ le.valid = 1;
+ le.cqe_sge_ts = CQE_TS(cqe);
+ if (SQ_TYPE(cqe)) {
+ le.qid = wq->sq.qid;
+ le.opcode = CQE_OPCODE(cqe);
+ le.post_host_ts = wq->sq.sw_sq[wq->sq.cidx].host_ts;
+ le.post_sge_ts = wq->sq.sw_sq[wq->sq.cidx].sge_ts;
+ le.wr_id = CQE_WRID_SQ_IDX(cqe);
+ } else {
+ le.qid = wq->rq.qid;
+ le.opcode = FW_RI_RECEIVE;
+ le.post_host_ts = wq->rq.sw_rq[wq->rq.cidx].host_ts;
+ le.post_sge_ts = wq->rq.sw_rq[wq->rq.cidx].sge_ts;
+ le.wr_id = CQE_WRID_MSN(cqe);
+ }
+ wq->rdev->wr_log[idx] = le;
+}
+
+static int wr_log_show(struct seq_file *seq, void *v)
+{
+ struct c4iw_dev *dev = seq->private;
+ struct timespec prev_ts = {0, 0};
+ struct wr_log_entry *lep;
+ int prev_ts_set = 0;
+ int idx, end;
+
+#define ts2ns(ts) div64_ul((ts) * dev->rdev.lldi.cclk_ps, 1000)
+
+ idx = atomic_read(&dev->rdev.wr_log_idx) &
+ (dev->rdev.wr_log_size - 1);
+ end = idx - 1;
+ if (end < 0)
+ end = dev->rdev.wr_log_size - 1;
+ lep = &dev->rdev.wr_log[idx];
+ while (idx != end) {
+ if (lep->valid) {
+ if (!prev_ts_set) {
+ prev_ts_set = 1;
+ prev_ts = lep->poll_host_ts;
+ }
+ seq_printf(seq, "%04u: sec %lu nsec %lu qid %u opcode "
+ "%u %s 0x%x host_wr_delta sec %lu nsec %lu "
+ "post_sge_ts 0x%llx cqe_sge_ts 0x%llx "
+ "poll_sge_ts 0x%llx post_poll_delta_ns %llu "
+ "cqe_poll_delta_ns %llu\n",
+ idx,
+ timespec_sub(lep->poll_host_ts,
+ prev_ts).tv_sec,
+ timespec_sub(lep->poll_host_ts,
+ prev_ts).tv_nsec,
+ lep->qid, lep->opcode,
+ lep->opcode == FW_RI_RECEIVE ?
+ "msn" : "wrid",
+ lep->wr_id,
+ timespec_sub(lep->poll_host_ts,
+ lep->post_host_ts).tv_sec,
+ timespec_sub(lep->poll_host_ts,
+ lep->post_host_ts).tv_nsec,
+ lep->post_sge_ts, lep->cqe_sge_ts,
+ lep->poll_sge_ts,
+ ts2ns(lep->poll_sge_ts - lep->post_sge_ts),
+ ts2ns(lep->poll_sge_ts - lep->cqe_sge_ts));
+ prev_ts = lep->poll_host_ts;
+ }
+ idx++;
+ if (idx > (dev->rdev.wr_log_size - 1))
+ idx = 0;
+ lep = &dev->rdev.wr_log[idx];
+ }
+#undef ts2ns
+ return 0;
+}
+
+static int wr_log_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wr_log_show, inode->i_private);
+}
+
+static ssize_t wr_log_clear(struct file *file, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct c4iw_dev *dev = ((struct seq_file *)file->private_data)->private;
+ int i;
+
+ if (dev->rdev.wr_log)
+ for (i = 0; i < dev->rdev.wr_log_size; i++)
+ dev->rdev.wr_log[i].valid = 0;
+ return count;
+}
+
+static const struct file_operations wr_log_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = wr_log_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = wr_log_clear,
+};
+
static int dump_qp(int id, void *p, void *data)
{
struct c4iw_qp *qp = p;
@@ -241,12 +362,32 @@ static int dump_stag(int id, void *p, void *data)
struct c4iw_debugfs_data *stagd = data;
int space;
int cc;
+ struct fw_ri_tpte tpte;
+ int ret;
space = stagd->bufsize - stagd->pos - 1;
if (space == 0)
return 1;
- cc = snprintf(stagd->buf + stagd->pos, space, "0x%x\n", id<<8);
+ ret = cxgb4_read_tpte(stagd->devp->rdev.lldi.ports[0], (u32)id<<8,
+ (__be32 *)&tpte);
+ if (ret) {
+ dev_err(&stagd->devp->rdev.lldi.pdev->dev,
+ "%s cxgb4_read_tpte err %d\n", __func__, ret);
+ return ret;
+ }
+ cc = snprintf(stagd->buf + stagd->pos, space,
+ "stag: idx 0x%x valid %d key 0x%x state %d pdid %d "
+ "perm 0x%x ps %d len 0x%llx va 0x%llx\n",
+ (u32)id<<8,
+ G_FW_RI_TPTE_VALID(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_STAGKEY(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_STAGSTATE(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_PDID(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_PERM(ntohl(tpte.locread_to_qpid)),
+ G_FW_RI_TPTE_PS(ntohl(tpte.locread_to_qpid)),
+ ((u64)ntohl(tpte.len_hi) << 32) | ntohl(tpte.len_lo),
+ ((u64)ntohl(tpte.va_hi) << 32) | ntohl(tpte.va_lo_fbo));
if (cc < space)
stagd->pos += cc;
return 0;
@@ -259,7 +400,7 @@ static int stag_release(struct inode *inode, struct file *file)
printk(KERN_INFO "%s null stagd?\n", __func__);
return 0;
}
- kfree(stagd->buf);
+ vfree(stagd->buf);
kfree(stagd);
return 0;
}
@@ -282,8 +423,8 @@ static int stag_open(struct inode *inode, struct file *file)
idr_for_each(&stagd->devp->mmidr, count_idrs, &count);
spin_unlock_irq(&stagd->devp->lock);
- stagd->bufsize = count * sizeof("0x12345678\n");
- stagd->buf = kmalloc(stagd->bufsize, GFP_KERNEL);
+ stagd->bufsize = count * 256;
+ stagd->buf = vmalloc(stagd->bufsize);
if (!stagd->buf) {
ret = -ENOMEM;
goto err1;
@@ -348,6 +489,7 @@ static int stats_show(struct seq_file *seq, void *v)
dev->rdev.stats.act_ofld_conn_fails);
seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n",
dev->rdev.stats.pas_ofld_conn_fails);
+ seq_printf(seq, "AVAILABLE IRD: %10u\n", dev->avail_ird);
return 0;
}
@@ -583,6 +725,12 @@ static int setup_debugfs(struct c4iw_dev *devp)
if (de && de->d_inode)
de->d_inode->i_size = 4096;
+ if (c4iw_wr_log) {
+ de = debugfs_create_file("wr_log", S_IWUSR, devp->debugfs_root,
+ (void *)devp, &wr_log_debugfs_fops);
+ if (de && de->d_inode)
+ de->d_inode->i_size = 4096;
+ }
return 0;
}
@@ -696,6 +844,20 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
pr_err(MOD "error allocating status page\n");
goto err4;
}
+
+ if (c4iw_wr_log) {
+ rdev->wr_log = kzalloc((1 << c4iw_wr_log_size_order) *
+ sizeof(*rdev->wr_log), GFP_KERNEL);
+ if (rdev->wr_log) {
+ rdev->wr_log_size = 1 << c4iw_wr_log_size_order;
+ atomic_set(&rdev->wr_log_idx, 0);
+ } else {
+ pr_err(MOD "error allocating wr_log. Logging disabled\n");
+ }
+ }
+
+ rdev->status_page->db_off = 0;
+
return 0;
err4:
c4iw_rqtpool_destroy(rdev);
@@ -709,6 +871,7 @@ err1:
static void c4iw_rdev_close(struct c4iw_rdev *rdev)
{
+ kfree(rdev->wr_log);
free_page((unsigned long)rdev->status_page);
c4iw_pblpool_destroy(rdev);
c4iw_rqtpool_destroy(rdev);
@@ -729,7 +892,6 @@ static void c4iw_dealloc(struct uld_ctx *ctx)
if (ctx->dev->rdev.oc_mw_kva)
iounmap(ctx->dev->rdev.oc_mw_kva);
ib_dealloc_device(&ctx->dev->ibdev);
- iwpm_exit(RDMA_NL_C4IW);
ctx->dev = NULL;
}
@@ -768,6 +930,27 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
}
devp->rdev.lldi = *infop;
+ /* init various hw-queue params based on lld info */
+ PDBG("%s: Ing. padding boundary is %d, egrsstatuspagesize = %d\n",
+ __func__, devp->rdev.lldi.sge_ingpadboundary,
+ devp->rdev.lldi.sge_egrstatuspagesize);
+
+ devp->rdev.hw_queue.t4_eq_status_entries =
+ devp->rdev.lldi.sge_ingpadboundary > 64 ? 2 : 1;
+ devp->rdev.hw_queue.t4_max_eq_size = 65520;
+ devp->rdev.hw_queue.t4_max_iq_size = 65520;
+ devp->rdev.hw_queue.t4_max_rq_size = 8192 -
+ devp->rdev.hw_queue.t4_eq_status_entries - 1;
+ devp->rdev.hw_queue.t4_max_sq_size =
+ devp->rdev.hw_queue.t4_max_eq_size -
+ devp->rdev.hw_queue.t4_eq_status_entries - 1;
+ devp->rdev.hw_queue.t4_max_qp_depth =
+ devp->rdev.hw_queue.t4_max_rq_size;
+ devp->rdev.hw_queue.t4_max_cq_depth =
+ devp->rdev.hw_queue.t4_max_iq_size - 2;
+ devp->rdev.hw_queue.t4_stat_len =
+ devp->rdev.lldi.sge_egrstatuspagesize;
+
/*
* For T5 devices, we map all of BAR2 with WC.
* For T4 devices with onchip qp mem, we map only that part
@@ -818,6 +1001,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
mutex_init(&devp->rdev.stats.lock);
mutex_init(&devp->db_mutex);
INIT_LIST_HEAD(&devp->db_fc_list);
+ devp->avail_ird = devp->rdev.lldi.max_ird_adapter;
if (c4iw_debugfs_root) {
devp->debugfs_root = debugfs_create_dir(
@@ -826,12 +1010,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
setup_debugfs(devp);
}
- ret = iwpm_init(RDMA_NL_C4IW);
- if (ret) {
- pr_err("port mapper initialization failed with %d\n", ret);
- ib_dealloc_device(&devp->ibdev);
- return ERR_PTR(ret);
- }
return devp;
}
@@ -1332,6 +1510,15 @@ static int __init c4iw_init_module(void)
pr_err("%s[%u]: Failed to add netlink callback\n"
, __func__, __LINE__);
+ err = iwpm_init(RDMA_NL_C4IW);
+ if (err) {
+ pr_err("port mapper initialization failed with %d\n", err);
+ ibnl_remove_client(RDMA_NL_C4IW);
+ c4iw_cm_term();
+ debugfs_remove_recursive(c4iw_debugfs_root);
+ return err;
+ }
+
cxgb4_register_uld(CXGB4_ULD_RDMA, &c4iw_uld_info);
return 0;
@@ -1349,6 +1536,7 @@ static void __exit c4iw_exit_module(void)
}
mutex_unlock(&dev_mutex);
cxgb4_unregister_uld(CXGB4_ULD_RDMA);
+ iwpm_exit(RDMA_NL_C4IW);
ibnl_remove_client(RDMA_NL_C4IW);
c4iw_cm_term();
debugfs_remove_recursive(c4iw_debugfs_root);
diff --git a/drivers/infiniband/hw/cxgb4/ev.c b/drivers/infiniband/hw/cxgb4/ev.c
index d61d0a18f784..fbe6051af254 100644
--- a/drivers/infiniband/hw/cxgb4/ev.c
+++ b/drivers/infiniband/hw/cxgb4/ev.c
@@ -35,6 +35,55 @@
#include "iw_cxgb4.h"
+static void print_tpte(struct c4iw_dev *dev, u32 stag)
+{
+ int ret;
+ struct fw_ri_tpte tpte;
+
+ ret = cxgb4_read_tpte(dev->rdev.lldi.ports[0], stag,
+ (__be32 *)&tpte);
+ if (ret) {
+ dev_err(&dev->rdev.lldi.pdev->dev,
+ "%s cxgb4_read_tpte err %d\n", __func__, ret);
+ return;
+ }
+ PDBG("stag idx 0x%x valid %d key 0x%x state %d pdid %d "
+ "perm 0x%x ps %d len 0x%llx va 0x%llx\n",
+ stag & 0xffffff00,
+ G_FW_RI_TPTE_VALID(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_STAGKEY(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_STAGSTATE(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_PDID(ntohl(tpte.valid_to_pdid)),
+ G_FW_RI_TPTE_PERM(ntohl(tpte.locread_to_qpid)),
+ G_FW_RI_TPTE_PS(ntohl(tpte.locread_to_qpid)),
+ ((u64)ntohl(tpte.len_hi) << 32) | ntohl(tpte.len_lo),
+ ((u64)ntohl(tpte.va_hi) << 32) | ntohl(tpte.va_lo_fbo));
+}
+
+static void dump_err_cqe(struct c4iw_dev *dev, struct t4_cqe *err_cqe)
+{
+ __be64 *p = (void *)err_cqe;
+
+ dev_err(&dev->rdev.lldi.pdev->dev,
+ "AE qpid %d opcode %d status 0x%x "
+ "type %d len 0x%x wrid.hi 0x%x wrid.lo 0x%x\n",
+ CQE_QPID(err_cqe), CQE_OPCODE(err_cqe),
+ CQE_STATUS(err_cqe), CQE_TYPE(err_cqe), ntohl(err_cqe->len),
+ CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe));
+
+ PDBG("%016llx %016llx %016llx %016llx\n",
+ be64_to_cpu(p[0]), be64_to_cpu(p[1]), be64_to_cpu(p[2]),
+ be64_to_cpu(p[3]));
+
+ /*
+ * Ingress WRITE and READ_RESP errors provide
+ * the offending stag, so parse and log it.
+ */
+ if (RQ_TYPE(err_cqe) && (CQE_OPCODE(err_cqe) == FW_RI_RDMA_WRITE ||
+ CQE_OPCODE(err_cqe) == FW_RI_READ_RESP))
+ print_tpte(dev, CQE_WRID_STAG(err_cqe));
+}
+
static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp,
struct c4iw_qp *qhp,
struct t4_cqe *err_cqe,
@@ -44,11 +93,7 @@ static void post_qp_event(struct c4iw_dev *dev, struct c4iw_cq *chp,
struct c4iw_qp_attributes attrs;
unsigned long flag;
- printk(KERN_ERR MOD "AE qpid 0x%x opcode %d status 0x%x "
- "type %d wrid.hi 0x%x wrid.lo 0x%x\n",
- CQE_QPID(err_cqe), CQE_OPCODE(err_cqe),
- CQE_STATUS(err_cqe), CQE_TYPE(err_cqe),
- CQE_WRID_HI(err_cqe), CQE_WRID_LOW(err_cqe));
+ dump_err_cqe(dev, err_cqe);
if (qhp->attr.state == C4IW_QP_STATE_RTS) {
attrs.next_state = C4IW_QP_STATE_TERMINATE;
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index 125bc5d1e175..b5678ac97393 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -139,6 +139,29 @@ struct c4iw_stats {
u64 pas_ofld_conn_fails;
};
+struct c4iw_hw_queue {
+ int t4_eq_status_entries;
+ int t4_max_eq_size;
+ int t4_max_iq_size;
+ int t4_max_rq_size;
+ int t4_max_sq_size;
+ int t4_max_qp_depth;
+ int t4_max_cq_depth;
+ int t4_stat_len;
+};
+
+struct wr_log_entry {
+ struct timespec post_host_ts;
+ struct timespec poll_host_ts;
+ u64 post_sge_ts;
+ u64 cqe_sge_ts;
+ u64 poll_sge_ts;
+ u16 qid;
+ u16 wr_id;
+ u8 opcode;
+ u8 valid;
+};
+
struct c4iw_rdev {
struct c4iw_resource resource;
unsigned long qpshift;
@@ -156,7 +179,11 @@ struct c4iw_rdev {
unsigned long oc_mw_pa;
void __iomem *oc_mw_kva;
struct c4iw_stats stats;
+ struct c4iw_hw_queue hw_queue;
struct t4_dev_status_page *status_page;
+ atomic_t wr_log_idx;
+ struct wr_log_entry *wr_log;
+ int wr_log_size;
};
static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
@@ -166,7 +193,7 @@ static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
static inline int c4iw_num_stags(struct c4iw_rdev *rdev)
{
- return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5));
+ return (int)(rdev->lldi.vr->stag.size >> 5);
}
#define C4IW_WR_TO (30*HZ)
@@ -237,6 +264,7 @@ struct c4iw_dev {
struct idr atid_idr;
struct idr stid_idr;
struct list_head db_fc_list;
+ u32 avail_ird;
};
static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
@@ -318,6 +346,13 @@ static inline void remove_handle_nolock(struct c4iw_dev *rhp,
_remove_handle(rhp, idr, id, 0);
}
+extern uint c4iw_max_read_depth;
+
+static inline int cur_max_read_depth(struct c4iw_dev *dev)
+{
+ return min(dev->rdev.lldi.max_ordird_qp, c4iw_max_read_depth);
+}
+
struct c4iw_pd {
struct ib_pd ibpd;
u32 pdid;
@@ -908,7 +943,7 @@ int c4iw_destroy_ctrl_qp(struct c4iw_rdev *rdev);
int c4iw_register_device(struct c4iw_dev *dev);
void c4iw_unregister_device(struct c4iw_dev *dev);
int __init c4iw_cm_init(void);
-void __exit c4iw_cm_term(void);
+void c4iw_cm_term(void);
void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
struct c4iw_dev_ucontext *uctx);
void c4iw_init_dev_ucontext(struct c4iw_rdev *rdev,
@@ -991,7 +1026,8 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe);
extern struct cxgb4_client t4c_client;
extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
-extern int c4iw_max_read_depth;
+extern void c4iw_log_wr_stats(struct t4_wq *wq, struct t4_cqe *cqe);
+extern int c4iw_wr_log;
extern int db_fc_threshold;
extern int db_coalescing_threshold;
extern int use_dsgl;
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index b1d305338de6..72e3b69d1b76 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -318,14 +318,16 @@ static int c4iw_query_device(struct ib_device *ibdev,
props->vendor_id = (u32)dev->rdev.lldi.pdev->vendor;
props->vendor_part_id = (u32)dev->rdev.lldi.pdev->device;
props->max_mr_size = T4_MAX_MR_SIZE;
- props->max_qp = T4_MAX_NUM_QP;
- props->max_qp_wr = T4_MAX_QP_DEPTH;
+ props->max_qp = dev->rdev.lldi.vr->qp.size / 2;
+ props->max_qp_wr = dev->rdev.hw_queue.t4_max_qp_depth;
props->max_sge = T4_MAX_RECV_SGE;
props->max_sge_rd = 1;
- props->max_qp_rd_atom = c4iw_max_read_depth;
- props->max_qp_init_rd_atom = c4iw_max_read_depth;
- props->max_cq = T4_MAX_NUM_CQ;
- props->max_cqe = T4_MAX_CQ_DEPTH;
+ props->max_res_rd_atom = dev->rdev.lldi.max_ird_adapter;
+ props->max_qp_rd_atom = min(dev->rdev.lldi.max_ordird_qp,
+ c4iw_max_read_depth);
+ props->max_qp_init_rd_atom = props->max_qp_rd_atom;
+ props->max_cq = dev->rdev.lldi.vr->qp.size;
+ props->max_cqe = dev->rdev.hw_queue.t4_max_cq_depth;
props->max_mr = c4iw_num_stags(&dev->rdev);
props->max_pd = T4_MAX_NUM_PD;
props->local_ca_ack_delay = 0;
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index 086f62f5dc9e..c158fcc02bca 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -58,6 +58,31 @@ static int max_fr_immd = T4_MAX_FR_IMMD;
module_param(max_fr_immd, int, 0644);
MODULE_PARM_DESC(max_fr_immd, "fastreg threshold for using DSGL instead of immedate");
+static int alloc_ird(struct c4iw_dev *dev, u32 ird)
+{
+ int ret = 0;
+
+ spin_lock_irq(&dev->lock);
+ if (ird <= dev->avail_ird)
+ dev->avail_ird -= ird;
+ else
+ ret = -ENOMEM;
+ spin_unlock_irq(&dev->lock);
+
+ if (ret)
+ dev_warn(&dev->rdev.lldi.pdev->dev,
+ "device IRD resources exhausted\n");
+
+ return ret;
+}
+
+static void free_ird(struct c4iw_dev *dev, int ird)
+{
+ spin_lock_irq(&dev->lock);
+ dev->avail_ird += ird;
+ spin_unlock_irq(&dev->lock);
+}
+
static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state)
{
unsigned long flag;
@@ -180,9 +205,9 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
}
/*
- * RQT must be a power of 2.
+ * RQT must be a power of 2 and at least 16 deep.
*/
- wq->rq.rqt_size = roundup_pow_of_two(wq->rq.size);
+ wq->rq.rqt_size = roundup_pow_of_two(max_t(u16, wq->rq.size, 16));
wq->rq.rqt_hwaddr = c4iw_rqtpool_alloc(rdev, wq->rq.rqt_size);
if (!wq->rq.rqt_hwaddr) {
ret = -ENOMEM;
@@ -258,7 +283,8 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
/*
* eqsize is the number of 64B entries plus the status page size.
*/
- eqsize = wq->sq.size * T4_SQ_NUM_SLOTS + T4_EQ_STATUS_ENTRIES;
+ eqsize = wq->sq.size * T4_SQ_NUM_SLOTS +
+ rdev->hw_queue.t4_eq_status_entries;
res->u.sqrq.fetchszm_to_iqid = cpu_to_be32(
V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */
@@ -283,7 +309,8 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
/*
* eqsize is the number of 64B entries plus the status page size.
*/
- eqsize = wq->rq.size * T4_RQ_NUM_SLOTS + T4_EQ_STATUS_ENTRIES;
+ eqsize = wq->rq.size * T4_RQ_NUM_SLOTS +
+ rdev->hw_queue.t4_eq_status_entries;
res->u.sqrq.fetchszm_to_iqid = cpu_to_be32(
V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */
V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */
@@ -796,6 +823,11 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
qhp->sq_sig_all;
swsqe->flushed = 0;
swsqe->wr_id = wr->wr_id;
+ if (c4iw_wr_log) {
+ swsqe->sge_ts = cxgb4_read_sge_timestamp(
+ qhp->rhp->rdev.lldi.ports[0]);
+ getnstimeofday(&swsqe->host_ts);
+ }
init_wr_hdr(wqe, qhp->wq.sq.pidx, fw_opcode, fw_flags, len16);
@@ -859,6 +891,13 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
}
qhp->wq.rq.sw_rq[qhp->wq.rq.pidx].wr_id = wr->wr_id;
+ if (c4iw_wr_log) {
+ qhp->wq.rq.sw_rq[qhp->wq.rq.pidx].sge_ts =
+ cxgb4_read_sge_timestamp(
+ qhp->rhp->rdev.lldi.ports[0]);
+ getnstimeofday(
+ &qhp->wq.rq.sw_rq[qhp->wq.rq.pidx].host_ts);
+ }
wqe->recv.opcode = FW_RI_RECV_WR;
wqe->recv.r1 = 0;
@@ -1202,12 +1241,20 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
int ret;
struct sk_buff *skb;
- PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid,
- qhp->ep->hwtid);
+ PDBG("%s qhp %p qid 0x%x tid %u ird %u ord %u\n", __func__, qhp,
+ qhp->wq.sq.qid, qhp->ep->hwtid, qhp->ep->ird, qhp->ep->ord);
skb = alloc_skb(sizeof *wqe, GFP_KERNEL);
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ ret = alloc_ird(rhp, qhp->attr.max_ird);
+ if (ret) {
+ qhp->attr.max_ird = 0;
+ kfree_skb(skb);
+ goto out;
+ }
set_wr_txq(skb, CPL_PRIORITY_DATA, qhp->ep->txq_idx);
wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe));
@@ -1258,10 +1305,14 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
ret = c4iw_ofld_send(&rhp->rdev, skb);
if (ret)
- goto out;
+ goto err1;
ret = c4iw_wait_for_reply(&rhp->rdev, &qhp->ep->com.wr_wait,
qhp->ep->hwtid, qhp->wq.sq.qid, __func__);
+ if (!ret)
+ goto out;
+err1:
+ free_ird(rhp, qhp->attr.max_ird);
out:
PDBG("%s ret %d\n", __func__, ret);
return ret;
@@ -1306,7 +1357,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
newattr.max_ord = attrs->max_ord;
}
if (mask & C4IW_QP_ATTR_MAX_IRD) {
- if (attrs->max_ird > c4iw_max_read_depth) {
+ if (attrs->max_ird > cur_max_read_depth(rhp)) {
ret = -EINVAL;
goto out;
}
@@ -1529,6 +1580,7 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
if (!list_empty(&qhp->db_fc_entry))
list_del_init(&qhp->db_fc_entry);
spin_unlock_irq(&rhp->lock);
+ free_ird(rhp, qhp->attr.max_ird);
ucontext = ib_qp->uobject ?
to_c4iw_ucontext(ib_qp->uobject->context) : NULL;
@@ -1569,13 +1621,17 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
if (attrs->cap.max_inline_data > T4_MAX_SEND_INLINE)
return ERR_PTR(-EINVAL);
- rqsize = roundup(attrs->cap.max_recv_wr + 1, 16);
- if (rqsize > T4_MAX_RQ_SIZE)
+ if (attrs->cap.max_recv_wr > rhp->rdev.hw_queue.t4_max_rq_size)
return ERR_PTR(-E2BIG);
+ rqsize = attrs->cap.max_recv_wr + 1;
+ if (rqsize < 8)
+ rqsize = 8;
- sqsize = roundup(attrs->cap.max_send_wr + 1, 16);
- if (sqsize > T4_MAX_SQ_SIZE)
+ if (attrs->cap.max_send_wr > rhp->rdev.hw_queue.t4_max_sq_size)
return ERR_PTR(-E2BIG);
+ sqsize = attrs->cap.max_send_wr + 1;
+ if (sqsize < 8)
+ sqsize = 8;
ucontext = pd->uobject ? to_c4iw_ucontext(pd->uobject->context) : NULL;
@@ -1583,19 +1639,20 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
if (!qhp)
return ERR_PTR(-ENOMEM);
qhp->wq.sq.size = sqsize;
- qhp->wq.sq.memsize = (sqsize + 1) * sizeof *qhp->wq.sq.queue;
+ qhp->wq.sq.memsize =
+ (sqsize + rhp->rdev.hw_queue.t4_eq_status_entries) *
+ sizeof(*qhp->wq.sq.queue) + 16 * sizeof(__be64);
qhp->wq.sq.flush_cidx = -1;
qhp->wq.rq.size = rqsize;
- qhp->wq.rq.memsize = (rqsize + 1) * sizeof *qhp->wq.rq.queue;
+ qhp->wq.rq.memsize =
+ (rqsize + rhp->rdev.hw_queue.t4_eq_status_entries) *
+ sizeof(*qhp->wq.rq.queue);
if (ucontext) {
qhp->wq.sq.memsize = roundup(qhp->wq.sq.memsize, PAGE_SIZE);
qhp->wq.rq.memsize = roundup(qhp->wq.rq.memsize, PAGE_SIZE);
}
- PDBG("%s sqsize %u sqmemsize %zu rqsize %u rqmemsize %zu\n",
- __func__, sqsize, qhp->wq.sq.memsize, rqsize, qhp->wq.rq.memsize);
-
ret = create_qp(&rhp->rdev, &qhp->wq, &schp->cq, &rchp->cq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
if (ret)
@@ -1619,8 +1676,8 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
qhp->attr.enable_rdma_read = 1;
qhp->attr.enable_rdma_write = 1;
qhp->attr.enable_bind = 1;
- qhp->attr.max_ord = 1;
- qhp->attr.max_ird = 1;
+ qhp->attr.max_ord = 0;
+ qhp->attr.max_ird = 0;
qhp->sq_sig_all = attrs->sq_sig_type == IB_SIGNAL_ALL_WR;
spin_lock_init(&qhp->lock);
mutex_init(&qhp->mutex);
@@ -1714,9 +1771,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
qhp->ibqp.qp_num = qhp->wq.sq.qid;
init_timer(&(qhp->timer));
INIT_LIST_HEAD(&qhp->db_fc_entry);
- PDBG("%s qhp %p sq_num_entries %d, rq_num_entries %d qpid 0x%0x\n",
- __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries,
- qhp->wq.sq.qid);
+ PDBG("%s sq id %u size %u memsize %zu num_entries %u "
+ "rq id %u size %u memsize %zu num_entries %u\n", __func__,
+ qhp->wq.sq.qid, qhp->wq.sq.size, qhp->wq.sq.memsize,
+ attrs->cap.max_send_wr, qhp->wq.rq.qid, qhp->wq.rq.size,
+ qhp->wq.rq.memsize, attrs->cap.max_recv_wr);
return &qhp->ibqp;
err8:
kfree(mm5);
@@ -1804,5 +1863,11 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
memset(attr, 0, sizeof *attr);
memset(init_attr, 0, sizeof *init_attr);
attr->qp_state = to_ib_qp_state(qhp->attr.state);
+ init_attr->cap.max_send_wr = qhp->attr.sq_num_entries;
+ init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries;
+ init_attr->cap.max_send_sge = qhp->attr.sq_max_sges;
+ init_attr->cap.max_recv_sge = qhp->attr.sq_max_sges;
+ init_attr->cap.max_inline_data = T4_MAX_SEND_INLINE;
+ init_attr->sq_sig_type = qhp->sq_sig_all ? IB_SIGNAL_ALL_WR : 0;
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h
index 68b0a6bf4eb0..df5edfa31a8f 100644
--- a/drivers/infiniband/hw/cxgb4/t4.h
+++ b/drivers/infiniband/hw/cxgb4/t4.h
@@ -36,22 +36,11 @@
#include "t4_msg.h"
#include "t4fw_ri_api.h"
-#define T4_MAX_NUM_QP 65536
-#define T4_MAX_NUM_CQ 65536
#define T4_MAX_NUM_PD 65536
-#define T4_EQ_STATUS_ENTRIES (L1_CACHE_BYTES > 64 ? 2 : 1)
-#define T4_MAX_EQ_SIZE (65520 - T4_EQ_STATUS_ENTRIES)
-#define T4_MAX_IQ_SIZE (65520 - 1)
-#define T4_MAX_RQ_SIZE (8192 - T4_EQ_STATUS_ENTRIES)
-#define T4_MAX_SQ_SIZE (T4_MAX_EQ_SIZE - 1)
-#define T4_MAX_QP_DEPTH (T4_MAX_RQ_SIZE - 1)
-#define T4_MAX_CQ_DEPTH (T4_MAX_IQ_SIZE - 1)
-#define T4_MAX_NUM_STAG (1<<15)
#define T4_MAX_MR_SIZE (~0ULL)
#define T4_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */
#define T4_STAG_UNSET 0xffffffff
#define T4_FW_MAJ 0
-#define T4_EQ_STATUS_ENTRIES (L1_CACHE_BYTES > 64 ? 2 : 1)
#define A_PCIE_MA_SYNC 0x30b4
struct t4_status_page {
@@ -244,8 +233,8 @@ struct t4_cqe {
#define CQE_WRID_SQ_IDX(x) ((x)->u.scqe.cidx)
/* generic accessor macros */
-#define CQE_WRID_HI(x) ((x)->u.gen.wrid_hi)
-#define CQE_WRID_LOW(x) ((x)->u.gen.wrid_low)
+#define CQE_WRID_HI(x) (be32_to_cpu((x)->u.gen.wrid_hi))
+#define CQE_WRID_LOW(x) (be32_to_cpu((x)->u.gen.wrid_low))
/* macros for flit 3 of the cqe */
#define S_CQE_GENBIT 63
@@ -277,6 +266,8 @@ struct t4_swsqe {
int signaled;
u16 idx;
int flushed;
+ struct timespec host_ts;
+ u64 sge_ts;
};
static inline pgprot_t t4_pgprot_wc(pgprot_t prot)
@@ -314,6 +305,8 @@ struct t4_sq {
struct t4_swrqe {
u64 wr_id;
+ struct timespec host_ts;
+ u64 sge_ts;
};
struct t4_rq {
diff --git a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
index 91289a051af9..5709e77faf7c 100644
--- a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
+++ b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
@@ -849,6 +849,5 @@ enum { /* TCP congestion control algorithms */
#define G_CONG_CNTRL(x) (((x) >> S_CONG_CNTRL) & M_CONG_CNTRL)
#define CONG_CNTRL_VALID (1 << 18)
-#define T5_OPT_2_VALID (1 << 31)
#endif /* _T4FW_RI_API_H_ */
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 8ae4f896cb41..e4056279166d 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -180,7 +180,7 @@ static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
struct mlx5_core_srq *msrq = NULL;
if (qp->ibqp.xrcd) {
- msrq = mlx5_core_get_srq(&dev->mdev,
+ msrq = mlx5_core_get_srq(dev->mdev,
be32_to_cpu(cqe->srqn));
srq = to_mibsrq(msrq);
} else {
@@ -348,7 +348,7 @@ static void handle_atomic(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
u16 tail, u16 head)
{
- int idx;
+ u16 idx;
do {
idx = tail & (qp->sq.wqe_cnt - 1);
@@ -364,7 +364,7 @@ static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
{
- mlx5_buf_free(&dev->mdev, &buf->buf);
+ mlx5_buf_free(dev->mdev, &buf->buf);
}
static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe,
@@ -450,7 +450,7 @@ repoll:
* because CQs will be locked while QPs are removed
* from the table.
*/
- mqp = __mlx5_qp_lookup(&dev->mdev, qpn);
+ mqp = __mlx5_qp_lookup(dev->mdev, qpn);
if (unlikely(!mqp)) {
mlx5_ib_warn(dev, "CQE@CQ %06x for unknown QPN %6x\n",
cq->mcq.cqn, qpn);
@@ -514,11 +514,11 @@ repoll:
case MLX5_CQE_SIG_ERR:
sig_err_cqe = (struct mlx5_sig_err_cqe *)cqe64;
- read_lock(&dev->mdev.priv.mr_table.lock);
- mmr = __mlx5_mr_lookup(&dev->mdev,
+ read_lock(&dev->mdev->priv.mr_table.lock);
+ mmr = __mlx5_mr_lookup(dev->mdev,
mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
if (unlikely(!mmr)) {
- read_unlock(&dev->mdev.priv.mr_table.lock);
+ read_unlock(&dev->mdev->priv.mr_table.lock);
mlx5_ib_warn(dev, "CQE@CQ %06x for unknown MR %6x\n",
cq->mcq.cqn, be32_to_cpu(sig_err_cqe->mkey));
return -EINVAL;
@@ -536,7 +536,7 @@ repoll:
mr->sig->err_item.expected,
mr->sig->err_item.actual);
- read_unlock(&dev->mdev.priv.mr_table.lock);
+ read_unlock(&dev->mdev->priv.mr_table.lock);
goto repoll;
}
@@ -575,8 +575,8 @@ int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
mlx5_cq_arm(&to_mcq(ibcq)->mcq,
(flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
MLX5_CQ_DB_REQ_NOT_SOL : MLX5_CQ_DB_REQ_NOT,
- to_mdev(ibcq->device)->mdev.priv.uuari.uars[0].map,
- MLX5_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->mdev.priv.cq_uar_lock));
+ to_mdev(ibcq->device)->mdev->priv.uuari.uars[0].map,
+ MLX5_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->mdev->priv.cq_uar_lock));
return 0;
}
@@ -586,7 +586,7 @@ static int alloc_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf,
{
int err;
- err = mlx5_buf_alloc(&dev->mdev, nent * cqe_size,
+ err = mlx5_buf_alloc(dev->mdev, nent * cqe_size,
PAGE_SIZE * 2, &buf->buf);
if (err)
return err;
@@ -691,7 +691,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
{
int err;
- err = mlx5_db_alloc(&dev->mdev, &cq->db);
+ err = mlx5_db_alloc(dev->mdev, &cq->db);
if (err)
return err;
@@ -716,7 +716,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
mlx5_fill_page_array(&cq->buf.buf, (*cqb)->pas);
(*cqb)->ctx.log_pg_sz = cq->buf.buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT;
- *index = dev->mdev.priv.uuari.uars[0].index;
+ *index = dev->mdev->priv.uuari.uars[0].index;
return 0;
@@ -724,14 +724,14 @@ err_buf:
free_cq_buf(dev, &cq->buf);
err_db:
- mlx5_db_free(&dev->mdev, &cq->db);
+ mlx5_db_free(dev->mdev, &cq->db);
return err;
}
static void destroy_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq)
{
free_cq_buf(dev, &cq->buf);
- mlx5_db_free(&dev->mdev, &cq->db);
+ mlx5_db_free(dev->mdev, &cq->db);
}
struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
@@ -752,7 +752,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
return ERR_PTR(-EINVAL);
entries = roundup_pow_of_two(entries + 1);
- if (entries > dev->mdev.caps.max_cqes)
+ if (entries > dev->mdev->caps.max_cqes)
return ERR_PTR(-EINVAL);
cq = kzalloc(sizeof(*cq), GFP_KERNEL);
@@ -789,7 +789,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
cqb->ctx.c_eqn = cpu_to_be16(eqn);
cqb->ctx.db_record_addr = cpu_to_be64(cq->db.dma);
- err = mlx5_core_create_cq(&dev->mdev, &cq->mcq, cqb, inlen);
+ err = mlx5_core_create_cq(dev->mdev, &cq->mcq, cqb, inlen);
if (err)
goto err_cqb;
@@ -809,7 +809,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
return &cq->ibcq;
err_cmd:
- mlx5_core_destroy_cq(&dev->mdev, &cq->mcq);
+ mlx5_core_destroy_cq(dev->mdev, &cq->mcq);
err_cqb:
mlx5_vfree(cqb);
@@ -834,7 +834,7 @@ int mlx5_ib_destroy_cq(struct ib_cq *cq)
if (cq->uobject)
context = cq->uobject->context;
- mlx5_core_destroy_cq(&dev->mdev, &mcq->mcq);
+ mlx5_core_destroy_cq(dev->mdev, &mcq->mcq);
if (context)
destroy_cq_user(mcq, context);
else
@@ -919,7 +919,7 @@ int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
int err;
u32 fsel;
- if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_CQ_MODER))
+ if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_CQ_MODER))
return -ENOSYS;
in = kzalloc(sizeof(*in), GFP_KERNEL);
@@ -931,7 +931,7 @@ int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
in->ctx.cq_period = cpu_to_be16(cq_period);
in->ctx.cq_max_count = cpu_to_be16(cq_count);
in->field_select = cpu_to_be32(fsel);
- err = mlx5_core_modify_cq(&dev->mdev, &mcq->mcq, in, sizeof(*in));
+ err = mlx5_core_modify_cq(dev->mdev, &mcq->mcq, in, sizeof(*in));
kfree(in);
if (err)
@@ -1074,7 +1074,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
int uninitialized_var(cqe_size);
unsigned long flags;
- if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_RESIZE_CQ)) {
+ if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_RESIZE_CQ)) {
pr_info("Firmware does not support resize CQ\n");
return -ENOSYS;
}
@@ -1083,7 +1083,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
return -EINVAL;
entries = roundup_pow_of_two(entries + 1);
- if (entries > dev->mdev.caps.max_cqes + 1)
+ if (entries > dev->mdev->caps.max_cqes + 1)
return -EINVAL;
if (entries == ibcq->cqe + 1)
@@ -1128,7 +1128,7 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
in->hdr.opmod = cpu_to_be16(MLX5_CQ_OPMOD_RESIZE);
in->cqn = cpu_to_be32(cq->mcq.cqn);
- err = mlx5_core_modify_cq(&dev->mdev, &cq->mcq, in, inlen);
+ err = mlx5_core_modify_cq(dev->mdev, &cq->mcq, in, inlen);
if (err)
goto ex_alloc;
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c
index 5c8938be0e08..b514bbb5610f 100644
--- a/drivers/infiniband/hw/mlx5/mad.c
+++ b/drivers/infiniband/hw/mlx5/mad.c
@@ -41,7 +41,7 @@ enum {
};
int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
- int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
+ u8 port, struct ib_wc *in_wc, struct ib_grh *in_grh,
void *in_mad, void *response_mad)
{
u8 op_modifier = 0;
@@ -54,7 +54,7 @@ int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
if (ignore_bkey || !in_wc)
op_modifier |= 0x2;
- return mlx5_core_mad_ifc(&dev->mdev, in_mad, response_mad, op_modifier, port);
+ return mlx5_core_mad_ifc(dev->mdev, in_mad, response_mad, op_modifier, port);
}
int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
@@ -129,7 +129,7 @@ int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port)
packet_error = be16_to_cpu(out_mad->status);
- dev->mdev.caps.ext_port_cap[port - 1] = (!err && !packet_error) ?
+ dev->mdev->caps.ext_port_cap[port - 1] = (!err && !packet_error) ?
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO : 0;
out:
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 364d4b6937f5..d8907b20522a 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -54,96 +54,17 @@ MODULE_DESCRIPTION("Mellanox Connect-IB HCA IB driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRIVER_VERSION);
-static int prof_sel = 2;
-module_param_named(prof_sel, prof_sel, int, 0444);
-MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
+static int deprecated_prof_sel = 2;
+module_param_named(prof_sel, deprecated_prof_sel, int, 0444);
+MODULE_PARM_DESC(prof_sel, "profile selector. Deprecated here. Moved to module mlx5_core");
static char mlx5_version[] =
DRIVER_NAME ": Mellanox Connect-IB Infiniband driver v"
DRIVER_VERSION " (" DRIVER_RELDATE ")\n";
-static struct mlx5_profile profile[] = {
- [0] = {
- .mask = 0,
- },
- [1] = {
- .mask = MLX5_PROF_MASK_QP_SIZE,
- .log_max_qp = 12,
- },
- [2] = {
- .mask = MLX5_PROF_MASK_QP_SIZE |
- MLX5_PROF_MASK_MR_CACHE,
- .log_max_qp = 17,
- .mr_cache[0] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[1] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[2] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[3] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[4] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[5] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[6] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[7] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[8] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[9] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[10] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[11] = {
- .size = 500,
- .limit = 250
- },
- .mr_cache[12] = {
- .size = 64,
- .limit = 32
- },
- .mr_cache[13] = {
- .size = 32,
- .limit = 16
- },
- .mr_cache[14] = {
- .size = 16,
- .limit = 8
- },
- .mr_cache[15] = {
- .size = 8,
- .limit = 4
- },
- },
-};
-
int mlx5_vector2eqn(struct mlx5_ib_dev *dev, int vector, int *eqn, int *irqn)
{
- struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+ struct mlx5_eq_table *table = &dev->mdev->priv.eq_table;
struct mlx5_eq *eq, *n;
int err = -ENOENT;
@@ -163,7 +84,7 @@ int mlx5_vector2eqn(struct mlx5_ib_dev *dev, int vector, int *eqn, int *irqn)
static int alloc_comp_eqs(struct mlx5_ib_dev *dev)
{
- struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+ struct mlx5_eq_table *table = &dev->mdev->priv.eq_table;
char name[MLX5_MAX_EQ_NAME];
struct mlx5_eq *eq, *n;
int ncomp_vec;
@@ -182,9 +103,9 @@ static int alloc_comp_eqs(struct mlx5_ib_dev *dev)
}
snprintf(name, MLX5_MAX_EQ_NAME, "mlx5_comp%d", i);
- err = mlx5_create_map_eq(&dev->mdev, eq,
+ err = mlx5_create_map_eq(dev->mdev, eq,
i + MLX5_EQ_VEC_COMP_BASE, nent, 0,
- name, &dev->mdev.priv.uuari.uars[0]);
+ name, &dev->mdev->priv.uuari.uars[0]);
if (err) {
kfree(eq);
goto clean;
@@ -204,7 +125,7 @@ clean:
list_for_each_entry_safe(eq, n, &dev->eqs_list, list) {
list_del(&eq->list);
spin_unlock(&table->lock);
- if (mlx5_destroy_unmap_eq(&dev->mdev, eq))
+ if (mlx5_destroy_unmap_eq(dev->mdev, eq))
mlx5_ib_warn(dev, "failed to destroy EQ 0x%x\n", eq->eqn);
kfree(eq);
spin_lock(&table->lock);
@@ -215,14 +136,14 @@ clean:
static void free_comp_eqs(struct mlx5_ib_dev *dev)
{
- struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+ struct mlx5_eq_table *table = &dev->mdev->priv.eq_table;
struct mlx5_eq *eq, *n;
spin_lock(&table->lock);
list_for_each_entry_safe(eq, n, &dev->eqs_list, list) {
list_del(&eq->list);
spin_unlock(&table->lock);
- if (mlx5_destroy_unmap_eq(&dev->mdev, eq))
+ if (mlx5_destroy_unmap_eq(dev->mdev, eq))
mlx5_ib_warn(dev, "failed to destroy EQ 0x%x\n", eq->eqn);
kfree(eq);
spin_lock(&table->lock);
@@ -255,14 +176,14 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
memset(props, 0, sizeof(*props));
- props->fw_ver = ((u64)fw_rev_maj(&dev->mdev) << 32) |
- (fw_rev_min(&dev->mdev) << 16) |
- fw_rev_sub(&dev->mdev);
+ props->fw_ver = ((u64)fw_rev_maj(dev->mdev) << 32) |
+ (fw_rev_min(dev->mdev) << 16) |
+ fw_rev_sub(dev->mdev);
props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT |
IB_DEVICE_PORT_ACTIVE_EVENT |
IB_DEVICE_SYS_IMAGE_GUID |
IB_DEVICE_RC_RNR_NAK_GEN;
- flags = dev->mdev.caps.flags;
+ flags = dev->mdev->caps.flags;
if (flags & MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR)
props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
if (flags & MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR)
@@ -292,30 +213,30 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
props->max_mr_size = ~0ull;
- props->page_size_cap = dev->mdev.caps.min_page_sz;
- props->max_qp = 1 << dev->mdev.caps.log_max_qp;
- props->max_qp_wr = dev->mdev.caps.max_wqes;
- max_rq_sg = dev->mdev.caps.max_rq_desc_sz / sizeof(struct mlx5_wqe_data_seg);
- max_sq_sg = (dev->mdev.caps.max_sq_desc_sz - sizeof(struct mlx5_wqe_ctrl_seg)) /
+ props->page_size_cap = dev->mdev->caps.min_page_sz;
+ props->max_qp = 1 << dev->mdev->caps.log_max_qp;
+ props->max_qp_wr = dev->mdev->caps.max_wqes;
+ max_rq_sg = dev->mdev->caps.max_rq_desc_sz / sizeof(struct mlx5_wqe_data_seg);
+ max_sq_sg = (dev->mdev->caps.max_sq_desc_sz - sizeof(struct mlx5_wqe_ctrl_seg)) /
sizeof(struct mlx5_wqe_data_seg);
props->max_sge = min(max_rq_sg, max_sq_sg);
- props->max_cq = 1 << dev->mdev.caps.log_max_cq;
- props->max_cqe = dev->mdev.caps.max_cqes - 1;
- props->max_mr = 1 << dev->mdev.caps.log_max_mkey;
- props->max_pd = 1 << dev->mdev.caps.log_max_pd;
- props->max_qp_rd_atom = dev->mdev.caps.max_ra_req_qp;
- props->max_qp_init_rd_atom = dev->mdev.caps.max_ra_res_qp;
+ props->max_cq = 1 << dev->mdev->caps.log_max_cq;
+ props->max_cqe = dev->mdev->caps.max_cqes - 1;
+ props->max_mr = 1 << dev->mdev->caps.log_max_mkey;
+ props->max_pd = 1 << dev->mdev->caps.log_max_pd;
+ props->max_qp_rd_atom = dev->mdev->caps.max_ra_req_qp;
+ props->max_qp_init_rd_atom = dev->mdev->caps.max_ra_res_qp;
props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
- props->max_srq = 1 << dev->mdev.caps.log_max_srq;
- props->max_srq_wr = dev->mdev.caps.max_srq_wqes - 1;
+ props->max_srq = 1 << dev->mdev->caps.log_max_srq;
+ props->max_srq_wr = dev->mdev->caps.max_srq_wqes - 1;
props->max_srq_sge = max_rq_sg - 1;
props->max_fast_reg_page_list_len = (unsigned int)-1;
- props->local_ca_ack_delay = dev->mdev.caps.local_ca_ack_delay;
+ props->local_ca_ack_delay = dev->mdev->caps.local_ca_ack_delay;
props->atomic_cap = IB_ATOMIC_NONE;
props->masked_atomic_cap = IB_ATOMIC_NONE;
props->max_pkeys = be16_to_cpup((__be16 *)(out_mad->data + 28));
- props->max_mcast_grp = 1 << dev->mdev.caps.log_max_mcg;
- props->max_mcast_qp_attach = dev->mdev.caps.max_qp_mcg;
+ props->max_mcast_grp = 1 << dev->mdev->caps.log_max_mcg;
+ props->max_mcast_qp_attach = dev->mdev->caps.max_qp_mcg;
props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
props->max_mcast_grp;
props->max_map_per_fmr = INT_MAX; /* no limit in ConnectIB */
@@ -336,7 +257,7 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
int ext_active_speed;
int err = -ENOMEM;
- if (port < 1 || port > dev->mdev.caps.num_ports) {
+ if (port < 1 || port > dev->mdev->caps.num_ports) {
mlx5_ib_warn(dev, "invalid port number %d\n", port);
return -EINVAL;
}
@@ -367,8 +288,8 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
props->phys_state = out_mad->data[33] >> 4;
props->port_cap_flags = be32_to_cpup((__be32 *)(out_mad->data + 20));
props->gid_tbl_len = out_mad->data[50];
- props->max_msg_sz = 1 << to_mdev(ibdev)->mdev.caps.log_max_msg;
- props->pkey_tbl_len = to_mdev(ibdev)->mdev.caps.port[port - 1].pkey_table_len;
+ props->max_msg_sz = 1 << to_mdev(ibdev)->mdev->caps.log_max_msg;
+ props->pkey_tbl_len = to_mdev(ibdev)->mdev->caps.port[port - 1].pkey_table_len;
props->bad_pkey_cntr = be16_to_cpup((__be16 *)(out_mad->data + 46));
props->qkey_viol_cntr = be16_to_cpup((__be16 *)(out_mad->data + 48));
props->active_width = out_mad->data[31] & 0xf;
@@ -395,7 +316,7 @@ int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
/* If reported active speed is QDR, check if is FDR-10 */
if (props->active_speed == 4) {
- if (dev->mdev.caps.ext_port_cap[port - 1] &
+ if (dev->mdev->caps.ext_port_cap[port - 1] &
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO) {
init_query_mad(in_mad);
in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
@@ -508,7 +429,7 @@ static int mlx5_ib_modify_device(struct ib_device *ibdev, int mask,
* a 144 trap. If cmd fails, just ignore.
*/
memcpy(&in, props->node_desc, 64);
- err = mlx5_core_access_reg(&dev->mdev, &in, sizeof(in), &out,
+ err = mlx5_core_access_reg(dev->mdev, &in, sizeof(in), &out,
sizeof(out), MLX5_REG_NODE_DESC, 0, 1);
if (err)
return err;
@@ -535,7 +456,7 @@ static int mlx5_ib_modify_port(struct ib_device *ibdev, u8 port, int mask,
tmp = (attr.port_cap_flags | props->set_port_cap_mask) &
~props->clr_port_cap_mask;
- err = mlx5_set_port_caps(&dev->mdev, port, tmp);
+ err = mlx5_set_port_caps(dev->mdev, port, tmp);
out:
mutex_unlock(&dev->cap_mask_mutex);
@@ -557,7 +478,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
int uuarn;
int err;
int i;
- int reqlen;
+ size_t reqlen;
if (!dev->ib_active)
return ERR_PTR(-EAGAIN);
@@ -591,14 +512,14 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
num_uars = req.total_num_uuars / MLX5_NON_FP_BF_REGS_PER_PAGE;
gross_uuars = num_uars * MLX5_BF_REGS_PER_PAGE;
- resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp;
- resp.bf_reg_size = dev->mdev.caps.bf_reg_size;
+ resp.qp_tab_size = 1 << dev->mdev->caps.log_max_qp;
+ resp.bf_reg_size = dev->mdev->caps.bf_reg_size;
resp.cache_line_size = L1_CACHE_BYTES;
- resp.max_sq_desc_sz = dev->mdev.caps.max_sq_desc_sz;
- resp.max_rq_desc_sz = dev->mdev.caps.max_rq_desc_sz;
- resp.max_send_wqebb = dev->mdev.caps.max_wqes;
- resp.max_recv_wr = dev->mdev.caps.max_wqes;
- resp.max_srq_recv_wr = dev->mdev.caps.max_srq_wqes;
+ resp.max_sq_desc_sz = dev->mdev->caps.max_sq_desc_sz;
+ resp.max_rq_desc_sz = dev->mdev->caps.max_rq_desc_sz;
+ resp.max_send_wqebb = dev->mdev->caps.max_wqes;
+ resp.max_recv_wr = dev->mdev->caps.max_wqes;
+ resp.max_srq_recv_wr = dev->mdev->caps.max_srq_wqes;
context = kzalloc(sizeof(*context), GFP_KERNEL);
if (!context)
@@ -635,7 +556,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
}
for (i = 0; i < num_uars; i++) {
- err = mlx5_cmd_alloc_uar(&dev->mdev, &uars[i].index);
+ err = mlx5_cmd_alloc_uar(dev->mdev, &uars[i].index);
if (err)
goto out_count;
}
@@ -644,7 +565,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
mutex_init(&context->db_page_mutex);
resp.tot_uuars = req.total_num_uuars;
- resp.num_ports = dev->mdev.caps.num_ports;
+ resp.num_ports = dev->mdev->caps.num_ports;
err = ib_copy_to_udata(udata, &resp,
sizeof(resp) - sizeof(resp.reserved));
if (err)
@@ -658,7 +579,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
out_uars:
for (i--; i >= 0; i--)
- mlx5_cmd_free_uar(&dev->mdev, uars[i].index);
+ mlx5_cmd_free_uar(dev->mdev, uars[i].index);
out_count:
kfree(uuari->count);
@@ -681,7 +602,7 @@ static int mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
int i;
for (i = 0; i < uuari->num_uars; i++) {
- if (mlx5_cmd_free_uar(&dev->mdev, uuari->uars[i].index))
+ if (mlx5_cmd_free_uar(dev->mdev, uuari->uars[i].index))
mlx5_ib_warn(dev, "failed to free UAR 0x%x\n", uuari->uars[i].index);
}
@@ -695,7 +616,7 @@ static int mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
static phys_addr_t uar_index2pfn(struct mlx5_ib_dev *dev, int index)
{
- return (pci_resource_start(dev->mdev.pdev, 0) >> PAGE_SHIFT) + index;
+ return (pci_resource_start(dev->mdev->pdev, 0) >> PAGE_SHIFT) + index;
}
static int get_command(unsigned long offset)
@@ -773,7 +694,7 @@ static int alloc_pa_mkey(struct mlx5_ib_dev *dev, u32 *key, u32 pdn)
seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
seg->start_addr = 0;
- err = mlx5_core_create_mkey(&dev->mdev, &mr, in, sizeof(*in),
+ err = mlx5_core_create_mkey(dev->mdev, &mr, in, sizeof(*in),
NULL, NULL, NULL);
if (err) {
mlx5_ib_warn(dev, "failed to create mkey, %d\n", err);
@@ -798,7 +719,7 @@ static void free_pa_mkey(struct mlx5_ib_dev *dev, u32 key)
memset(&mr, 0, sizeof(mr));
mr.key = key;
- err = mlx5_core_destroy_mkey(&dev->mdev, &mr);
+ err = mlx5_core_destroy_mkey(dev->mdev, &mr);
if (err)
mlx5_ib_warn(dev, "failed to destroy mkey 0x%x\n", key);
}
@@ -815,7 +736,7 @@ static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
if (!pd)
return ERR_PTR(-ENOMEM);
- err = mlx5_core_alloc_pd(&to_mdev(ibdev)->mdev, &pd->pdn);
+ err = mlx5_core_alloc_pd(to_mdev(ibdev)->mdev, &pd->pdn);
if (err) {
kfree(pd);
return ERR_PTR(err);
@@ -824,14 +745,14 @@ static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
if (context) {
resp.pdn = pd->pdn;
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
- mlx5_core_dealloc_pd(&to_mdev(ibdev)->mdev, pd->pdn);
+ mlx5_core_dealloc_pd(to_mdev(ibdev)->mdev, pd->pdn);
kfree(pd);
return ERR_PTR(-EFAULT);
}
} else {
err = alloc_pa_mkey(to_mdev(ibdev), &pd->pa_lkey, pd->pdn);
if (err) {
- mlx5_core_dealloc_pd(&to_mdev(ibdev)->mdev, pd->pdn);
+ mlx5_core_dealloc_pd(to_mdev(ibdev)->mdev, pd->pdn);
kfree(pd);
return ERR_PTR(err);
}
@@ -848,7 +769,7 @@ static int mlx5_ib_dealloc_pd(struct ib_pd *pd)
if (!pd->uobject)
free_pa_mkey(mdev, mpd->pa_lkey);
- mlx5_core_dealloc_pd(&mdev->mdev, mpd->pdn);
+ mlx5_core_dealloc_pd(mdev->mdev, mpd->pdn);
kfree(mpd);
return 0;
@@ -859,7 +780,7 @@ 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);
int err;
- err = mlx5_core_attach_mcg(&dev->mdev, gid, ibqp->qp_num);
+ 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",
ibqp->qp_num, gid->raw);
@@ -872,7 +793,7 @@ static int mlx5_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
int err;
- err = mlx5_core_detach_mcg(&dev->mdev, gid, ibqp->qp_num);
+ err = mlx5_core_detach_mcg(dev->mdev, gid, ibqp->qp_num);
if (err)
mlx5_ib_warn(dev, "failed detaching QPN 0x%x, MGID %pI6\n",
ibqp->qp_num, gid->raw);
@@ -906,7 +827,7 @@ static int init_node_data(struct mlx5_ib_dev *dev)
if (err)
goto out;
- dev->mdev.rev_id = be32_to_cpup((__be32 *)(out_mad->data + 32));
+ dev->mdev->rev_id = be32_to_cpup((__be32 *)(out_mad->data + 32));
memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
out:
@@ -921,7 +842,7 @@ static ssize_t show_fw_pages(struct device *device, struct device_attribute *att
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
- return sprintf(buf, "%d\n", dev->mdev.priv.fw_pages);
+ return sprintf(buf, "%d\n", dev->mdev->priv.fw_pages);
}
static ssize_t show_reg_pages(struct device *device,
@@ -930,7 +851,7 @@ static ssize_t show_reg_pages(struct device *device,
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
- return sprintf(buf, "%d\n", dev->mdev.priv.reg_pages);
+ return sprintf(buf, "%d\n", dev->mdev->priv.reg_pages);
}
static ssize_t show_hca(struct device *device, struct device_attribute *attr,
@@ -938,7 +859,7 @@ static ssize_t show_hca(struct device *device, struct device_attribute *attr,
{
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
- return sprintf(buf, "MT%d\n", dev->mdev.pdev->device);
+ return sprintf(buf, "MT%d\n", dev->mdev->pdev->device);
}
static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
@@ -946,8 +867,8 @@ static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
{
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
- return sprintf(buf, "%d.%d.%d\n", fw_rev_maj(&dev->mdev),
- fw_rev_min(&dev->mdev), fw_rev_sub(&dev->mdev));
+ return sprintf(buf, "%d.%d.%d\n", fw_rev_maj(dev->mdev),
+ fw_rev_min(dev->mdev), fw_rev_sub(dev->mdev));
}
static ssize_t show_rev(struct device *device, struct device_attribute *attr,
@@ -955,7 +876,7 @@ static ssize_t show_rev(struct device *device, struct device_attribute *attr,
{
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
- return sprintf(buf, "%x\n", dev->mdev.rev_id);
+ return sprintf(buf, "%x\n", dev->mdev->rev_id);
}
static ssize_t show_board(struct device *device, struct device_attribute *attr,
@@ -964,7 +885,7 @@ static ssize_t show_board(struct device *device, struct device_attribute *attr,
struct mlx5_ib_dev *dev =
container_of(device, struct mlx5_ib_dev, ib_dev.dev);
return sprintf(buf, "%.*s\n", MLX5_BOARD_ID_LEN,
- dev->mdev.board_id);
+ dev->mdev->board_id);
}
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
@@ -983,11 +904,12 @@ static struct device_attribute *mlx5_class_attributes[] = {
&dev_attr_reg_pages,
};
-static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
- void *data)
+static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
+ enum mlx5_dev_event event, unsigned long param)
{
- struct mlx5_ib_dev *ibdev = container_of(dev, struct mlx5_ib_dev, mdev);
+ struct mlx5_ib_dev *ibdev = (struct mlx5_ib_dev *)context;
struct ib_event ibev;
+
u8 port = 0;
switch (event) {
@@ -998,12 +920,12 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
case MLX5_DEV_EVENT_PORT_UP:
ibev.event = IB_EVENT_PORT_ACTIVE;
- port = *(u8 *)data;
+ port = (u8)param;
break;
case MLX5_DEV_EVENT_PORT_DOWN:
ibev.event = IB_EVENT_PORT_ERR;
- port = *(u8 *)data;
+ port = (u8)param;
break;
case MLX5_DEV_EVENT_PORT_INITIALIZED:
@@ -1012,22 +934,22 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
case MLX5_DEV_EVENT_LID_CHANGE:
ibev.event = IB_EVENT_LID_CHANGE;
- port = *(u8 *)data;
+ port = (u8)param;
break;
case MLX5_DEV_EVENT_PKEY_CHANGE:
ibev.event = IB_EVENT_PKEY_CHANGE;
- port = *(u8 *)data;
+ port = (u8)param;
break;
case MLX5_DEV_EVENT_GUID_CHANGE:
ibev.event = IB_EVENT_GID_CHANGE;
- port = *(u8 *)data;
+ port = (u8)param;
break;
case MLX5_DEV_EVENT_CLIENT_REREG:
ibev.event = IB_EVENT_CLIENT_REREGISTER;
- port = *(u8 *)data;
+ port = (u8)param;
break;
}
@@ -1047,7 +969,7 @@ static void get_ext_port_caps(struct mlx5_ib_dev *dev)
{
int port;
- for (port = 1; port <= dev->mdev.caps.num_ports; port++)
+ for (port = 1; port <= dev->mdev->caps.num_ports; port++)
mlx5_query_ext_port_caps(dev, port);
}
@@ -1072,14 +994,14 @@ static int get_port_caps(struct mlx5_ib_dev *dev)
goto out;
}
- for (port = 1; port <= dev->mdev.caps.num_ports; port++) {
+ for (port = 1; port <= dev->mdev->caps.num_ports; port++) {
err = mlx5_ib_query_port(&dev->ib_dev, port, pprops);
if (err) {
mlx5_ib_warn(dev, "query_port %d failed %d\n", port, err);
break;
}
- dev->mdev.caps.port[port - 1].pkey_table_len = dprops->max_pkeys;
- dev->mdev.caps.port[port - 1].gid_table_len = pprops->gid_tbl_len;
+ dev->mdev->caps.port[port - 1].pkey_table_len = dprops->max_pkeys;
+ dev->mdev->caps.port[port - 1].gid_table_len = pprops->gid_tbl_len;
mlx5_ib_dbg(dev, "pkey_table_len %d, gid_table_len %d\n",
dprops->max_pkeys, pprops->gid_tbl_len);
}
@@ -1328,10 +1250,8 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
mlx5_ib_dealloc_pd(devr->p0);
}
-static int init_one(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
{
- struct mlx5_core_dev *mdev;
struct mlx5_ib_dev *dev;
int err;
int i;
@@ -1340,28 +1260,19 @@ static int init_one(struct pci_dev *pdev,
dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
if (!dev)
- return -ENOMEM;
+ return NULL;
- mdev = &dev->mdev;
- mdev->event = mlx5_ib_event;
- if (prof_sel >= ARRAY_SIZE(profile)) {
- pr_warn("selected pofile out of range, selceting default\n");
- prof_sel = 0;
- }
- mdev->profile = &profile[prof_sel];
- err = mlx5_dev_init(mdev, pdev);
- if (err)
- goto err_free;
+ dev->mdev = mdev;
err = get_port_caps(dev);
if (err)
- goto err_cleanup;
+ goto err_dealloc;
get_ext_port_caps(dev);
err = alloc_comp_eqs(dev);
if (err)
- goto err_cleanup;
+ goto err_dealloc;
MLX5_INIT_DOORBELL_LOCK(&dev->uar_lock);
@@ -1480,7 +1391,7 @@ static int init_one(struct pci_dev *pdev,
dev->ib_active = true;
- return 0;
+ return dev;
err_umrc:
destroy_umrc_res(dev);
@@ -1494,49 +1405,39 @@ err_rsrc:
err_eqs:
free_comp_eqs(dev);
-err_cleanup:
- mlx5_dev_cleanup(mdev);
-
-err_free:
+err_dealloc:
ib_dealloc_device((struct ib_device *)dev);
- return err;
+ return NULL;
}
-static void remove_one(struct pci_dev *pdev)
+static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
{
- struct mlx5_ib_dev *dev = mlx5_pci2ibdev(pdev);
-
+ struct mlx5_ib_dev *dev = context;
destroy_umrc_res(dev);
ib_unregister_device(&dev->ib_dev);
destroy_dev_resources(&dev->devr);
free_comp_eqs(dev);
- mlx5_dev_cleanup(&dev->mdev);
ib_dealloc_device(&dev->ib_dev);
}
-static DEFINE_PCI_DEVICE_TABLE(mlx5_ib_pci_table) = {
- { PCI_VDEVICE(MELLANOX, 4113) }, /* MT4113 Connect-IB */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, mlx5_ib_pci_table);
-
-static struct pci_driver mlx5_ib_driver = {
- .name = DRIVER_NAME,
- .id_table = mlx5_ib_pci_table,
- .probe = init_one,
- .remove = remove_one
+static struct mlx5_interface mlx5_ib_interface = {
+ .add = mlx5_ib_add,
+ .remove = mlx5_ib_remove,
+ .event = mlx5_ib_event,
};
static int __init mlx5_ib_init(void)
{
- return pci_register_driver(&mlx5_ib_driver);
+ if (deprecated_prof_sel != 2)
+ pr_warn("prof_sel is deprecated for mlx5_ib, set it for mlx5_core\n");
+
+ return mlx5_register_interface(&mlx5_ib_interface);
}
static void __exit mlx5_ib_cleanup(void)
{
- pci_unregister_driver(&mlx5_ib_driver);
+ mlx5_unregister_interface(&mlx5_ib_interface);
}
module_init(mlx5_ib_init);
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c
index 8499aec94db6..a3e81444c825 100644
--- a/drivers/infiniband/hw/mlx5/mem.c
+++ b/drivers/infiniband/hw/mlx5/mem.c
@@ -148,7 +148,7 @@ int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset)
u64 off_mask;
u64 buf_off;
- page_size = 1 << page_shift;
+ page_size = (u64)1 << page_shift;
page_mask = page_size - 1;
buf_off = addr & page_mask;
off_size = page_size >> 6;
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index f2ccf1a5a291..386780f0d1e1 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -360,7 +360,7 @@ struct mlx5_ib_resources {
struct mlx5_ib_dev {
struct ib_device ib_dev;
- struct mlx5_core_dev mdev;
+ struct mlx5_core_dev *mdev;
MLX5_DECLARE_DOORBELL_LOCK(uar_lock);
struct list_head eqs_list;
int num_ports;
@@ -454,16 +454,6 @@ static inline struct mlx5_ib_ah *to_mah(struct ib_ah *ibah)
return container_of(ibah, struct mlx5_ib_ah, ibah);
}
-static inline struct mlx5_ib_dev *mlx5_core2ibdev(struct mlx5_core_dev *dev)
-{
- return container_of(dev, struct mlx5_ib_dev, mdev);
-}
-
-static inline struct mlx5_ib_dev *mlx5_pci2ibdev(struct pci_dev *pdev)
-{
- return mlx5_core2ibdev(pci2mlx5_core_dev(pdev));
-}
-
int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
struct mlx5_db *db);
void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
@@ -471,7 +461,7 @@ void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq)
void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
- int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
+ u8 port, struct ib_wc *in_wc, struct ib_grh *in_grh,
void *in_mad, void *response_mad);
struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
struct mlx5_ib_ah *ah);
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index afa873bd028e..80b3c63eab5d 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -73,7 +73,7 @@ static void reg_mr_callback(int status, void *context)
struct mlx5_cache_ent *ent = &cache->ent[c];
u8 key;
unsigned long flags;
- struct mlx5_mr_table *table = &dev->mdev.priv.mr_table;
+ struct mlx5_mr_table *table = &dev->mdev->priv.mr_table;
int err;
spin_lock_irqsave(&ent->lock, flags);
@@ -97,9 +97,9 @@ static void reg_mr_callback(int status, void *context)
return;
}
- spin_lock_irqsave(&dev->mdev.priv.mkey_lock, flags);
- key = dev->mdev.priv.mkey_key++;
- spin_unlock_irqrestore(&dev->mdev.priv.mkey_lock, flags);
+ spin_lock_irqsave(&dev->mdev->priv.mkey_lock, flags);
+ key = dev->mdev->priv.mkey_key++;
+ spin_unlock_irqrestore(&dev->mdev->priv.mkey_lock, flags);
mr->mmr.key = mlx5_idx_to_mkey(be32_to_cpu(mr->out.mkey) & 0xffffff) | key;
cache->last_add = jiffies;
@@ -155,7 +155,7 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
spin_lock_irq(&ent->lock);
ent->pending++;
spin_unlock_irq(&ent->lock);
- err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in,
+ err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in,
sizeof(*in), reg_mr_callback,
mr, &mr->out);
if (err) {
@@ -188,7 +188,7 @@ static void remove_keys(struct mlx5_ib_dev *dev, int c, int num)
ent->cur--;
ent->size--;
spin_unlock_irq(&ent->lock);
- err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+ err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
if (err)
mlx5_ib_warn(dev, "failed destroy mkey\n");
else
@@ -479,7 +479,7 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
ent->cur--;
ent->size--;
spin_unlock_irq(&ent->lock);
- err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+ err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
if (err)
mlx5_ib_warn(dev, "failed destroy mkey\n");
else
@@ -496,7 +496,7 @@ static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
if (!mlx5_debugfs_root)
return 0;
- cache->root = debugfs_create_dir("mr_cache", dev->mdev.priv.dbg_root);
+ cache->root = debugfs_create_dir("mr_cache", dev->mdev->priv.dbg_root);
if (!cache->root)
return -ENOMEM;
@@ -571,8 +571,8 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
ent->order = i + 2;
ent->dev = dev;
- if (dev->mdev.profile->mask & MLX5_PROF_MASK_MR_CACHE)
- limit = dev->mdev.profile->mr_cache[i].limit;
+ if (dev->mdev->profile->mask & MLX5_PROF_MASK_MR_CACHE)
+ limit = dev->mdev->profile->mr_cache[i].limit;
else
limit = 0;
@@ -610,7 +610,7 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc)
{
struct mlx5_ib_dev *dev = to_mdev(pd->device);
- struct mlx5_core_dev *mdev = &dev->mdev;
+ struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_create_mkey_mbox_in *in;
struct mlx5_mkey_seg *seg;
struct mlx5_ib_mr *mr;
@@ -846,7 +846,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,
in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
in->xlat_oct_act_size = cpu_to_be32(get_octo_len(virt_addr, length,
1 << page_shift));
- err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, inlen, NULL,
+ err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, inlen, NULL,
NULL, NULL);
if (err) {
mlx5_ib_warn(dev, "create mkey failed\n");
@@ -923,7 +923,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mr->umem = umem;
mr->npages = npages;
spin_lock(&dev->mr_lock);
- dev->mdev.priv.reg_pages += npages;
+ dev->mdev->priv.reg_pages += npages;
spin_unlock(&dev->mr_lock);
mr->ibmr.lkey = mr->mmr.key;
mr->ibmr.rkey = mr->mmr.key;
@@ -978,7 +978,7 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
int err;
if (!umred) {
- err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+ err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
if (err) {
mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
mr->mmr.key, err);
@@ -996,7 +996,7 @@ int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
if (umem) {
ib_umem_release(umem);
spin_lock(&dev->mr_lock);
- dev->mdev.priv.reg_pages -= npages;
+ dev->mdev->priv.reg_pages -= npages;
spin_unlock(&dev->mr_lock);
}
@@ -1044,7 +1044,7 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
}
/* create mem & wire PSVs */
- err = mlx5_core_create_psv(&dev->mdev, to_mpd(pd)->pdn,
+ err = mlx5_core_create_psv(dev->mdev, to_mpd(pd)->pdn,
2, psv_index);
if (err)
goto err_free_sig;
@@ -1060,7 +1060,7 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
}
in->seg.flags = MLX5_PERM_UMR_EN | access_mode;
- err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in),
+ err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, sizeof(*in),
NULL, NULL, NULL);
if (err)
goto err_destroy_psv;
@@ -1074,11 +1074,11 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
err_destroy_psv:
if (mr->sig) {
- if (mlx5_core_destroy_psv(&dev->mdev,
+ if (mlx5_core_destroy_psv(dev->mdev,
mr->sig->psv_memory.psv_idx))
mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
mr->sig->psv_memory.psv_idx);
- if (mlx5_core_destroy_psv(&dev->mdev,
+ if (mlx5_core_destroy_psv(dev->mdev,
mr->sig->psv_wire.psv_idx))
mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
mr->sig->psv_wire.psv_idx);
@@ -1099,18 +1099,18 @@ int mlx5_ib_destroy_mr(struct ib_mr *ibmr)
int err;
if (mr->sig) {
- if (mlx5_core_destroy_psv(&dev->mdev,
+ if (mlx5_core_destroy_psv(dev->mdev,
mr->sig->psv_memory.psv_idx))
mlx5_ib_warn(dev, "failed to destroy mem psv %d\n",
mr->sig->psv_memory.psv_idx);
- if (mlx5_core_destroy_psv(&dev->mdev,
+ if (mlx5_core_destroy_psv(dev->mdev,
mr->sig->psv_wire.psv_idx))
mlx5_ib_warn(dev, "failed to destroy wire psv %d\n",
mr->sig->psv_wire.psv_idx);
kfree(mr->sig);
}
- err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+ err = mlx5_core_destroy_mkey(dev->mdev, &mr->mmr);
if (err) {
mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
mr->mmr.key, err);
@@ -1149,7 +1149,7 @@ struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
* TBD not needed - issue 197292 */
in->seg.log2_page_size = PAGE_SHIFT;
- err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in), NULL,
+ err = mlx5_core_create_mkey(dev->mdev, &mr->mmr, in, sizeof(*in), NULL,
NULL, NULL);
kfree(in);
if (err)
@@ -1202,7 +1202,7 @@ void mlx5_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
struct mlx5_ib_dev *dev = to_mdev(page_list->device);
int size = page_list->max_page_list_len * sizeof(u64);
- dma_free_coherent(&dev->mdev.pdev->dev, size, mfrpl->mapped_page_list,
+ dma_free_coherent(&dev->mdev->pdev->dev, size, mfrpl->mapped_page_list,
mfrpl->map);
kfree(mfrpl->ibfrpl.page_list);
kfree(mfrpl);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index d13ddf1c0033..7efe6e3f3542 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -162,7 +162,7 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,
int wq_size;
/* Sanity check RQ size before proceeding */
- if (cap->max_recv_wr > dev->mdev.caps.max_wqes)
+ if (cap->max_recv_wr > dev->mdev->caps.max_wqes)
return -EINVAL;
if (!has_rq) {
@@ -182,10 +182,10 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,
wq_size = roundup_pow_of_two(cap->max_recv_wr) * wqe_size;
wq_size = max_t(int, wq_size, MLX5_SEND_WQE_BB);
qp->rq.wqe_cnt = wq_size / wqe_size;
- if (wqe_size > dev->mdev.caps.max_rq_desc_sz) {
+ if (wqe_size > dev->mdev->caps.max_rq_desc_sz) {
mlx5_ib_dbg(dev, "wqe_size %d, max %d\n",
wqe_size,
- dev->mdev.caps.max_rq_desc_sz);
+ dev->mdev->caps.max_rq_desc_sz);
return -EINVAL;
}
qp->rq.wqe_shift = ilog2(wqe_size);
@@ -277,9 +277,9 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
if (wqe_size < 0)
return wqe_size;
- if (wqe_size > dev->mdev.caps.max_sq_desc_sz) {
+ if (wqe_size > dev->mdev->caps.max_sq_desc_sz) {
mlx5_ib_dbg(dev, "wqe_size(%d) > max_sq_desc_sz(%d)\n",
- wqe_size, dev->mdev.caps.max_sq_desc_sz);
+ wqe_size, dev->mdev->caps.max_sq_desc_sz);
return -EINVAL;
}
@@ -292,9 +292,9 @@ static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
wq_size = roundup_pow_of_two(attr->cap.max_send_wr * wqe_size);
qp->sq.wqe_cnt = wq_size / MLX5_SEND_WQE_BB;
- if (qp->sq.wqe_cnt > dev->mdev.caps.max_wqes) {
+ if (qp->sq.wqe_cnt > dev->mdev->caps.max_wqes) {
mlx5_ib_dbg(dev, "wqe count(%d) exceeds limits(%d)\n",
- qp->sq.wqe_cnt, dev->mdev.caps.max_wqes);
+ qp->sq.wqe_cnt, dev->mdev->caps.max_wqes);
return -ENOMEM;
}
qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
@@ -311,9 +311,9 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
{
int desc_sz = 1 << qp->sq.wqe_shift;
- if (desc_sz > dev->mdev.caps.max_sq_desc_sz) {
+ if (desc_sz > dev->mdev->caps.max_sq_desc_sz) {
mlx5_ib_warn(dev, "desc_sz %d, max_sq_desc_sz %d\n",
- desc_sz, dev->mdev.caps.max_sq_desc_sz);
+ desc_sz, dev->mdev->caps.max_sq_desc_sz);
return -EINVAL;
}
@@ -325,9 +325,9 @@ static int set_user_buf_size(struct mlx5_ib_dev *dev,
qp->sq.wqe_cnt = ucmd->sq_wqe_count;
- if (qp->sq.wqe_cnt > dev->mdev.caps.max_wqes) {
+ if (qp->sq.wqe_cnt > dev->mdev->caps.max_wqes) {
mlx5_ib_warn(dev, "wqe_cnt %d, max_wqes %d\n",
- qp->sq.wqe_cnt, dev->mdev.caps.max_wqes);
+ qp->sq.wqe_cnt, dev->mdev->caps.max_wqes);
return -EINVAL;
}
@@ -674,8 +674,8 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
int uuarn;
int err;
- uuari = &dev->mdev.priv.uuari;
- if (init_attr->create_flags & ~IB_QP_CREATE_SIGNATURE_EN)
+ uuari = &dev->mdev->priv.uuari;
+ if (init_attr->create_flags & ~(IB_QP_CREATE_SIGNATURE_EN | IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK))
return -EINVAL;
if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)
@@ -700,7 +700,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
qp->buf_size = err + (qp->rq.wqe_cnt << qp->rq.wqe_shift);
- err = mlx5_buf_alloc(&dev->mdev, qp->buf_size, PAGE_SIZE * 2, &qp->buf);
+ err = mlx5_buf_alloc(dev->mdev, qp->buf_size, PAGE_SIZE * 2, &qp->buf);
if (err) {
mlx5_ib_dbg(dev, "err %d\n", err);
goto err_uuar;
@@ -722,7 +722,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
mlx5_fill_page_array(&qp->buf, (*in)->pas);
- err = mlx5_db_alloc(&dev->mdev, &qp->db);
+ err = mlx5_db_alloc(dev->mdev, &qp->db);
if (err) {
mlx5_ib_dbg(dev, "err %d\n", err);
goto err_free;
@@ -747,7 +747,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
return 0;
err_wrid:
- mlx5_db_free(&dev->mdev, &qp->db);
+ mlx5_db_free(dev->mdev, &qp->db);
kfree(qp->sq.wqe_head);
kfree(qp->sq.w_list);
kfree(qp->sq.wrid);
@@ -758,23 +758,23 @@ err_free:
mlx5_vfree(*in);
err_buf:
- mlx5_buf_free(&dev->mdev, &qp->buf);
+ mlx5_buf_free(dev->mdev, &qp->buf);
err_uuar:
- free_uuar(&dev->mdev.priv.uuari, uuarn);
+ free_uuar(&dev->mdev->priv.uuari, uuarn);
return err;
}
static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
{
- mlx5_db_free(&dev->mdev, &qp->db);
+ mlx5_db_free(dev->mdev, &qp->db);
kfree(qp->sq.wqe_head);
kfree(qp->sq.w_list);
kfree(qp->sq.wrid);
kfree(qp->sq.wr_data);
kfree(qp->rq.wrid);
- mlx5_buf_free(&dev->mdev, &qp->buf);
- free_uuar(&dev->mdev.priv.uuari, qp->bf->uuarn);
+ mlx5_buf_free(dev->mdev, &qp->buf);
+ free_uuar(&dev->mdev->priv.uuari, qp->bf->uuarn);
}
static __be32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
@@ -812,7 +812,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
spin_lock_init(&qp->rq.lock);
if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
- if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
+ if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) {
mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n");
return -EINVAL;
} else {
@@ -851,9 +851,9 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
mlx5_ib_dbg(dev, "invalid rq params\n");
return -EINVAL;
}
- if (ucmd.sq_wqe_count > dev->mdev.caps.max_wqes) {
+ if (ucmd.sq_wqe_count > dev->mdev->caps.max_wqes) {
mlx5_ib_dbg(dev, "requested sq_wqe_count (%d) > max allowed (%d)\n",
- ucmd.sq_wqe_count, dev->mdev.caps.max_wqes);
+ ucmd.sq_wqe_count, dev->mdev->caps.max_wqes);
return -EINVAL;
}
err = create_user_qp(dev, pd, qp, udata, &in, &resp, &inlen);
@@ -957,7 +957,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
in->ctx.db_rec_addr = cpu_to_be64(qp->db.dma);
- err = mlx5_core_create_qp(&dev->mdev, &qp->mqp, in, inlen);
+ err = mlx5_core_create_qp(dev->mdev, &qp->mqp, in, inlen);
if (err) {
mlx5_ib_dbg(dev, "create qp failed\n");
goto err_create;
@@ -1081,7 +1081,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
if (!in)
return;
if (qp->state != IB_QPS_RESET)
- if (mlx5_core_qp_modify(&dev->mdev, to_mlx5_state(qp->state),
+ if (mlx5_core_qp_modify(dev->mdev, to_mlx5_state(qp->state),
MLX5_QP_STATE_RST, in, sizeof(*in), &qp->mqp))
mlx5_ib_warn(dev, "mlx5_ib: modify QP %06x to RESET failed\n",
qp->mqp.qpn);
@@ -1097,7 +1097,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
mlx5_ib_unlock_cqs(send_cq, recv_cq);
}
- err = mlx5_core_destroy_qp(&dev->mdev, &qp->mqp);
+ err = mlx5_core_destroy_qp(dev->mdev, &qp->mqp);
if (err)
mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n", qp->mqp.qpn);
kfree(in);
@@ -1165,7 +1165,7 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
switch (init_attr->qp_type) {
case IB_QPT_XRC_TGT:
case IB_QPT_XRC_INI:
- if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_XRC)) {
+ if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC)) {
mlx5_ib_dbg(dev, "XRC not supported\n");
return ERR_PTR(-ENOSYS);
}
@@ -1279,7 +1279,7 @@ static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
} else {
while (rate != IB_RATE_2_5_GBPS &&
!(1 << (rate + MLX5_STAT_RATE_OFFSET) &
- dev->mdev.caps.stat_rate_support))
+ dev->mdev->caps.stat_rate_support))
--rate;
}
@@ -1318,9 +1318,9 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
path->port = port;
if (ah->ah_flags & IB_AH_GRH) {
- if (ah->grh.sgid_index >= dev->mdev.caps.port[port - 1].gid_table_len) {
+ if (ah->grh.sgid_index >= dev->mdev->caps.port[port - 1].gid_table_len) {
pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n",
- ah->grh.sgid_index, dev->mdev.caps.port[port - 1].gid_table_len);
+ ah->grh.sgid_index, dev->mdev->caps.port[port - 1].gid_table_len);
return -EINVAL;
}
@@ -1539,7 +1539,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
err = -EINVAL;
goto out;
}
- context->mtu_msgmax = (attr->path_mtu << 5) | dev->mdev.caps.log_max_msg;
+ context->mtu_msgmax = (attr->path_mtu << 5) | dev->mdev->caps.log_max_msg;
}
if (attr_mask & IB_QP_DEST_QPN)
@@ -1637,7 +1637,7 @@ 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];
in->optparam = cpu_to_be32(optpar);
- err = mlx5_core_qp_modify(&dev->mdev, to_mlx5_state(cur_state),
+ err = mlx5_core_qp_modify(dev->mdev, to_mlx5_state(cur_state),
to_mlx5_state(new_state), in, sqd_event,
&qp->mqp);
if (err)
@@ -1699,21 +1699,21 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
if ((attr_mask & IB_QP_PORT) &&
- (attr->port_num == 0 || attr->port_num > dev->mdev.caps.num_ports))
+ (attr->port_num == 0 || attr->port_num > dev->mdev->caps.num_ports))
goto out;
if (attr_mask & IB_QP_PKEY_INDEX) {
port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
- if (attr->pkey_index >= dev->mdev.caps.port[port - 1].pkey_table_len)
+ if (attr->pkey_index >= dev->mdev->caps.port[port - 1].pkey_table_len)
goto out;
}
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
- attr->max_rd_atomic > dev->mdev.caps.max_ra_res_qp)
+ attr->max_rd_atomic > dev->mdev->caps.max_ra_res_qp)
goto out;
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
- attr->max_dest_rd_atomic > dev->mdev.caps.max_ra_req_qp)
+ attr->max_dest_rd_atomic > dev->mdev->caps.max_ra_req_qp)
goto out;
if (cur_state == new_state && cur_state == IB_QPS_RESET) {
@@ -2479,7 +2479,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
{
struct mlx5_wqe_ctrl_seg *ctrl = NULL; /* compiler warning */
struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
- struct mlx5_core_dev *mdev = &dev->mdev;
+ struct mlx5_core_dev *mdev = dev->mdev;
struct mlx5_ib_qp *qp = to_mqp(ibqp);
struct mlx5_ib_mr *mr;
struct mlx5_wqe_data_seg *dpseg;
@@ -2539,7 +2539,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
case IB_WR_RDMA_WRITE_WITH_IMM:
set_raddr_seg(seg, wr->wr.rdma.remote_addr,
wr->wr.rdma.rkey);
- seg += sizeof(struct mlx5_wqe_raddr_seg);
+ seg += sizeof(struct mlx5_wqe_raddr_seg);
size += sizeof(struct mlx5_wqe_raddr_seg) / 16;
break;
@@ -2668,7 +2668,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
case IB_QPT_SMI:
case IB_QPT_GSI:
set_datagram_seg(seg, wr);
- seg += sizeof(struct mlx5_wqe_datagram_seg);
+ seg += sizeof(struct mlx5_wqe_datagram_seg);
size += sizeof(struct mlx5_wqe_datagram_seg) / 16;
if (unlikely((seg == qend)))
seg = mlx5_get_send_wqe(qp, 0);
@@ -2888,7 +2888,7 @@ static int to_ib_qp_access_flags(int mlx5_flags)
static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_attr,
struct mlx5_qp_path *path)
{
- struct mlx5_core_dev *dev = &ibdev->mdev;
+ struct mlx5_core_dev *dev = ibdev->mdev;
memset(ib_ah_attr, 0, sizeof(*ib_ah_attr));
ib_ah_attr->port_num = path->port;
@@ -2931,7 +2931,7 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
goto out;
}
context = &outb->ctx;
- err = mlx5_core_qp_query(&dev->mdev, &qp->mqp, outb, sizeof(*outb));
+ err = mlx5_core_qp_query(dev->mdev, &qp->mqp, outb, sizeof(*outb));
if (err)
goto out_free;
@@ -3014,14 +3014,14 @@ struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
struct mlx5_ib_xrcd *xrcd;
int err;
- if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_XRC))
+ if (!(dev->mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC))
return ERR_PTR(-ENOSYS);
xrcd = kmalloc(sizeof(*xrcd), GFP_KERNEL);
if (!xrcd)
return ERR_PTR(-ENOMEM);
- err = mlx5_core_xrcd_alloc(&dev->mdev, &xrcd->xrcdn);
+ err = mlx5_core_xrcd_alloc(dev->mdev, &xrcd->xrcdn);
if (err) {
kfree(xrcd);
return ERR_PTR(-ENOMEM);
@@ -3036,7 +3036,7 @@ int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd)
u32 xrcdn = to_mxrcd(xrcd)->xrcdn;
int err;
- err = mlx5_core_xrcd_dealloc(&dev->mdev, xrcdn);
+ err = mlx5_core_xrcd_dealloc(dev->mdev, xrcdn);
if (err) {
mlx5_ib_warn(dev, "failed to dealloc xrcdn 0x%x\n", xrcdn);
return err;
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 384af6dec5eb..70bd131ba646 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -159,7 +159,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
int page_shift;
int npages;
- err = mlx5_db_alloc(&dev->mdev, &srq->db);
+ err = mlx5_db_alloc(dev->mdev, &srq->db);
if (err) {
mlx5_ib_warn(dev, "alloc dbell rec failed\n");
return err;
@@ -167,7 +167,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
*srq->db.db = 0;
- if (mlx5_buf_alloc(&dev->mdev, buf_size, PAGE_SIZE * 2, &srq->buf)) {
+ if (mlx5_buf_alloc(dev->mdev, buf_size, PAGE_SIZE * 2, &srq->buf)) {
mlx5_ib_dbg(dev, "buf alloc failed\n");
err = -ENOMEM;
goto err_db;
@@ -212,10 +212,10 @@ err_in:
mlx5_vfree(*in);
err_buf:
- mlx5_buf_free(&dev->mdev, &srq->buf);
+ mlx5_buf_free(dev->mdev, &srq->buf);
err_db:
- mlx5_db_free(&dev->mdev, &srq->db);
+ mlx5_db_free(dev->mdev, &srq->db);
return err;
}
@@ -229,8 +229,8 @@ 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);
- mlx5_buf_free(&dev->mdev, &srq->buf);
- mlx5_db_free(&dev->mdev, &srq->db);
+ mlx5_buf_free(dev->mdev, &srq->buf);
+ mlx5_db_free(dev->mdev, &srq->db);
}
struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
@@ -248,10 +248,10 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
u32 flgs, xrcdn;
/* Sanity check SRQ size before proceeding */
- if (init_attr->attr.max_wr >= dev->mdev.caps.max_srq_wqes) {
+ if (init_attr->attr.max_wr >= dev->mdev->caps.max_srq_wqes) {
mlx5_ib_dbg(dev, "max_wr %d, cap %d\n",
init_attr->attr.max_wr,
- dev->mdev.caps.max_srq_wqes);
+ dev->mdev->caps.max_srq_wqes);
return ERR_PTR(-EINVAL);
}
@@ -303,7 +303,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn);
in->ctx.db_record = cpu_to_be64(srq->db.dma);
- err = mlx5_core_create_srq(&dev->mdev, &srq->msrq, in, inlen);
+ err = mlx5_core_create_srq(dev->mdev, &srq->msrq, in, inlen);
mlx5_vfree(in);
if (err) {
mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err);
@@ -327,7 +327,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
return &srq->ibsrq;
err_core:
- mlx5_core_destroy_srq(&dev->mdev, &srq->msrq);
+ mlx5_core_destroy_srq(dev->mdev, &srq->msrq);
err_usr_kern_srq:
if (pd->uobject)
@@ -357,7 +357,7 @@ int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
return -EINVAL;
mutex_lock(&srq->mutex);
- ret = mlx5_core_arm_srq(&dev->mdev, &srq->msrq, attr->srq_limit, 1);
+ ret = mlx5_core_arm_srq(dev->mdev, &srq->msrq, attr->srq_limit, 1);
mutex_unlock(&srq->mutex);
if (ret)
@@ -378,7 +378,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
if (!out)
return -ENOMEM;
- ret = mlx5_core_query_srq(&dev->mdev, &srq->msrq, out);
+ ret = mlx5_core_query_srq(dev->mdev, &srq->msrq, out);
if (ret)
goto out_box;
@@ -396,7 +396,7 @@ int mlx5_ib_destroy_srq(struct ib_srq *srq)
struct mlx5_ib_dev *dev = to_mdev(srq->device);
struct mlx5_ib_srq *msrq = to_msrq(srq);
- mlx5_core_destroy_srq(&dev->mdev, &msrq->msrq);
+ mlx5_core_destroy_srq(dev->mdev, &msrq->msrq);
if (srq->uobject) {
mlx5_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 5786a78ff8bc..4e675f4fecc9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1394,8 +1394,8 @@ struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
{
struct net_device *dev;
- dev = alloc_netdev((int) sizeof (struct ipoib_dev_priv), name,
- ipoib_setup);
+ dev = alloc_netdev((int)sizeof(struct ipoib_dev_priv), name,
+ NET_NAME_UNKNOWN, ipoib_setup);
if (!dev)
return NULL;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index fd325ec9f064..de055451d1af 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -108,9 +108,8 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
struct input_event ev;
ktime_t time;
- time = ktime_get();
- if (client->clkid != CLOCK_MONOTONIC)
- time = ktime_sub(time, ktime_get_monotonic_offset());
+ time = (client->clkid == CLOCK_MONOTONIC) ?
+ ktime_get() : ktime_get_real();
ev.time = ktime_to_timeval(time);
ev.type = EV_SYN;
@@ -202,7 +201,7 @@ static void evdev_events(struct input_handle *handle,
ktime_t time_mono, time_real;
time_mono = ktime_get();
- time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
+ time_real = ktime_mono_to_real(time_mono);
rcu_read_lock();
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1c4c0db05550..29ca0bb4f561 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -257,9 +257,10 @@ static int input_handle_abs_event(struct input_dev *dev,
}
static int input_get_disposition(struct input_dev *dev,
- unsigned int type, unsigned int code, int value)
+ unsigned int type, unsigned int code, int *pval)
{
int disposition = INPUT_IGNORE_EVENT;
+ int value = *pval;
switch (type) {
@@ -357,6 +358,7 @@ static int input_get_disposition(struct input_dev *dev,
break;
}
+ *pval = value;
return disposition;
}
@@ -365,7 +367,7 @@ static void input_handle_event(struct input_dev *dev,
{
int disposition;
- disposition = input_get_disposition(dev, type, code, value);
+ disposition = input_get_disposition(dev, type, code, &value);
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value);
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 408379669d3c..791781ade4e7 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -24,8 +24,8 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
-#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/input/matrix_keypad.h>
@@ -42,7 +42,6 @@
* @dev: Device pointer
* @idev: Input device
* @ec: Top level ChromeOS device to use to talk to EC
- * @event_notifier: interrupt event notifier for transport devices
*/
struct cros_ec_keyb {
unsigned int rows;
@@ -55,7 +54,6 @@ struct cros_ec_keyb {
struct device *dev;
struct input_dev *idev;
struct cros_ec_device *ec;
- struct notifier_block notifier;
};
@@ -173,41 +171,55 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
input_sync(ckdev->idev);
}
-static int cros_ec_keyb_open(struct input_dev *dev)
-{
- struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
-
- return blocking_notifier_chain_register(&ckdev->ec->event_notifier,
- &ckdev->notifier);
-}
-
-static void cros_ec_keyb_close(struct input_dev *dev)
-{
- struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
-
- blocking_notifier_chain_unregister(&ckdev->ec->event_notifier,
- &ckdev->notifier);
-}
-
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
- return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE,
- kb_state, ckdev->cols);
+ struct cros_ec_command msg = {
+ .version = 0,
+ .command = EC_CMD_MKBP_STATE,
+ .outdata = NULL,
+ .outsize = 0,
+ .indata = kb_state,
+ .insize = ckdev->cols,
+ };
+
+ return ckdev->ec->cmd_xfer(ckdev->ec, &msg);
}
-static int cros_ec_keyb_work(struct notifier_block *nb,
- unsigned long state, void *_notify)
+static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
+ struct cros_ec_keyb *ckdev = data;
+ struct cros_ec_device *ec = ckdev->ec;
int ret;
- struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
- notifier);
uint8_t kb_state[ckdev->cols];
+ if (device_may_wakeup(ec->dev))
+ pm_wakeup_event(ec->dev, 0);
+
ret = cros_ec_keyb_get_state(ckdev, kb_state);
if (ret >= 0)
cros_ec_keyb_process(ckdev, kb_state, ret);
+ else
+ dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);
- return NOTIFY_DONE;
+ return IRQ_HANDLED;
+}
+
+static int cros_ec_keyb_open(struct input_dev *dev)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
+ struct cros_ec_device *ec = ckdev->ec;
+
+ return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "cros_ec_keyb", ckdev);
+}
+
+static void cros_ec_keyb_close(struct input_dev *dev)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
+ struct cros_ec_device *ec = ckdev->ec;
+
+ free_irq(ec->irq, ckdev);
}
static int cros_ec_keyb_probe(struct platform_device *pdev)
@@ -238,8 +250,12 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
if (!idev)
return -ENOMEM;
+ if (!ec->irq) {
+ dev_err(dev, "no EC IRQ specified\n");
+ return -EINVAL;
+ }
+
ckdev->ec = ec;
- ckdev->notifier.notifier_call = cros_ec_keyb_work;
ckdev->dev = dev;
dev_set_drvdata(&pdev->dev, ckdev);
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 0b42118cbf8f..cb32e2b506b7 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -558,6 +558,12 @@ static ssize_t lm8323_pwm_store_time(struct device *dev,
}
static DEVICE_ATTR(time, 0644, lm8323_pwm_show_time, lm8323_pwm_store_time);
+static struct attribute *lm8323_pwm_attrs[] = {
+ &dev_attr_time.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(lm8323_pwm);
+
static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
const char *name)
{
@@ -580,16 +586,11 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
if (name) {
pwm->cdev.name = name;
pwm->cdev.brightness_set = lm8323_pwm_set_brightness;
+ pwm->cdev.groups = lm8323_pwm_groups;
if (led_classdev_register(dev, &pwm->cdev) < 0) {
dev_err(dev, "couldn't register PWM %d\n", id);
return -1;
}
- if (device_create_file(pwm->cdev.dev,
- &dev_attr_time) < 0) {
- dev_err(dev, "couldn't register time attribute\n");
- led_classdev_unregister(&pwm->cdev);
- return -1;
- }
pwm->enabled = true;
}
@@ -753,11 +754,8 @@ fail3:
device_remove_file(&client->dev, &dev_attr_disable_kp);
fail2:
while (--pwm >= 0)
- if (lm->pwm[pwm].enabled) {
- device_remove_file(lm->pwm[pwm].cdev.dev,
- &dev_attr_time);
+ if (lm->pwm[pwm].enabled)
led_classdev_unregister(&lm->pwm[pwm].cdev);
- }
fail1:
input_free_device(idev);
kfree(lm);
@@ -777,10 +775,8 @@ static int lm8323_remove(struct i2c_client *client)
device_remove_file(&lm->client->dev, &dev_attr_disable_kp);
for (i = 0; i < 3; i++)
- if (lm->pwm[i].enabled) {
- device_remove_file(lm->pwm[i].cdev.dev, &dev_attr_time);
+ if (lm->pwm[i].enabled)
led_classdev_unregister(&lm->pwm[i].cdev);
- }
kfree(lm);
diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c
index 758b48731415..de7be4f03d91 100644
--- a/drivers/input/keyboard/st-keyscan.c
+++ b/drivers/input/keyboard/st-keyscan.c
@@ -215,6 +215,7 @@ static int keyscan_probe(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
static int keyscan_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -249,6 +250,7 @@ static int keyscan_resume(struct device *dev)
mutex_unlock(&input->mutex);
return retval;
}
+#endif
static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops, keyscan_suspend, keyscan_resume);
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c
index e4104f9b2e6d..fed5102e1802 100644
--- a/drivers/input/misc/sirfsoc-onkey.c
+++ b/drivers/input/misc/sirfsoc-onkey.c
@@ -213,7 +213,7 @@ static struct platform_driver sirfsoc_pwrc_driver = {
module_platform_driver(sirfsoc_pwrc_driver);
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>");
MODULE_DESCRIPTION("CSR Prima2 PWRC Driver");
MODULE_ALIAS("platform:sirfsoc-pwrc");
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 65fd3150919b..179ff1cd6f6b 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -86,13 +86,13 @@ static int bbc_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
spin_lock_irqsave(&state->lock, flags);
if (count) {
- outb(0x01, info->regs + 0);
- outb(0x00, info->regs + 2);
- outb((count >> 16) & 0xff, info->regs + 3);
- outb((count >> 8) & 0xff, info->regs + 4);
- outb(0x00, info->regs + 5);
+ sbus_writeb(0x01, info->regs + 0);
+ sbus_writeb(0x00, info->regs + 2);
+ sbus_writeb((count >> 16) & 0xff, info->regs + 3);
+ sbus_writeb((count >> 8) & 0xff, info->regs + 4);
+ sbus_writeb(0x00, info->regs + 5);
} else {
- outb(0x00, info->regs + 0);
+ sbus_writeb(0x00, info->regs + 0);
}
spin_unlock_irqrestore(&state->lock, flags);
@@ -123,15 +123,15 @@ static int grover_spkr_event(struct input_dev *dev, unsigned int type, unsigned
if (count) {
/* enable counter 2 */
- outb(inb(info->enable_reg) | 3, info->enable_reg);
+ sbus_writeb(sbus_readb(info->enable_reg) | 3, info->enable_reg);
/* set command for counter 2, 2 byte write */
- outb(0xB6, info->freq_regs + 1);
+ sbus_writeb(0xB6, info->freq_regs + 1);
/* select desired HZ */
- outb(count & 0xff, info->freq_regs + 0);
- outb((count >> 8) & 0xff, info->freq_regs + 0);
+ sbus_writeb(count & 0xff, info->freq_regs + 0);
+ sbus_writeb((count >> 8) & 0xff, info->freq_regs + 0);
} else {
/* disable counter 2 */
- outb(inb_p(info->enable_reg) & 0xFC, info->enable_reg);
+ sbus_writeb(sbus_readb(info->enable_reg) & 0xFC, info->enable_reg);
}
spin_unlock_irqrestore(&state->lock, flags);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index ec772d962f06..ef9e0b8a9aa7 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -132,7 +132,8 @@ static const struct min_max_quirk min_max_pnpid_table[] = {
1232, 5710, 1156, 4696
},
{
- (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL},
+ (const char * const []){"LEN0034", "LEN0036", "LEN2002",
+ "LEN2004", NULL},
1024, 5112, 2024, 4832
},
{
@@ -168,7 +169,7 @@ static const char * const topbuttonpad_pnp_ids[] = {
"LEN0049",
"LEN2000",
"LEN2001", /* Edge E431 */
- "LEN2002",
+ "LEN2002", /* Edge E531 */
"LEN2003",
"LEN2004", /* L440 */
"LEN2005",
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 381b20d4c561..136b7b204f56 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -402,6 +402,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
},
},
{
+ /* Acer Aspire 5710 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
+ },
+ },
+ {
/* Gericom Bellagio */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 977d05cd9e2e..e73cf2c71f35 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1217,9 +1217,9 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
* a=(pi*r^2)/C.
*/
int a = data[5];
- int x_res = input_abs_get_res(input, ABS_X);
- int y_res = input_abs_get_res(input, ABS_Y);
- width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
+ int x_res = input_abs_get_res(input, ABS_MT_POSITION_X);
+ int y_res = input_abs_get_res(input, ABS_MT_POSITION_Y);
+ width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
height = width * y_res / x_res;
}
@@ -1587,7 +1587,7 @@ static void wacom_abs_set_axis(struct input_dev *input_dev,
input_abs_set_res(input_dev, ABS_X, features->x_resolution);
input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
} else {
- if (features->touch_max <= 2) {
+ if (features->touch_max == 1) {
input_set_abs_params(input_dev, ABS_X, 0,
features->x_max, features->x_fuzz, 0);
input_set_abs_params(input_dev, ABS_Y, 0,
@@ -1815,14 +1815,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
case MTTPC:
case MTTPC_B:
case TABLETPC2FG:
- if (features->device_type == BTN_TOOL_FINGER) {
- unsigned int flags = INPUT_MT_DIRECT;
-
- if (wacom_wac->features.type == TABLETPC2FG)
- flags = 0;
-
- input_mt_init_slots(input_dev, features->touch_max, flags);
- }
+ if (features->device_type == BTN_TOOL_FINGER && features->touch_max > 1)
+ input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT);
/* fall through */
case TABLETPC:
@@ -1883,10 +1877,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
__set_bit(BTN_RIGHT, input_dev->keybit);
if (features->touch_max) {
- /* touch interface */
- unsigned int flags = INPUT_MT_POINTER;
-
- __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
input_set_abs_params(input_dev,
ABS_MT_TOUCH_MAJOR,
@@ -1894,12 +1884,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev,
ABS_MT_TOUCH_MINOR,
0, features->y_max, 0, 0);
- } else {
- __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
- __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
- flags = 0;
}
- input_mt_init_slots(input_dev, features->touch_max, flags);
+ input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
} else {
/* buttons/keys only interface */
__clear_bit(ABS_X, input_dev->absbit);
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 4e793a17361f..2ce649520fe0 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -359,9 +359,12 @@ static int titsc_parse_dt(struct platform_device *pdev,
*/
err = of_property_read_u32(node, "ti,coordinate-readouts",
&ts_dev->coordinate_readouts);
- if (err < 0)
+ if (err < 0) {
+ dev_warn(&pdev->dev, "please use 'ti,coordinate-readouts' instead\n");
err = of_property_read_u32(node, "ti,coordiante-readouts",
&ts_dev->coordinate_readouts);
+ }
+
if (err < 0)
return err;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d260605e6d5f..dd5112265cc9 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -76,7 +76,7 @@ config AMD_IOMMU_STATS
config AMD_IOMMU_V2
tristate "AMD IOMMU Version 2 driver"
- depends on AMD_IOMMU && PROFILING
+ depends on AMD_IOMMU
select MMU_NOTIFIER
---help---
This option enables support for the AMD IOMMUv2 features of the IOMMU
@@ -143,16 +143,12 @@ config OMAP_IOMMU
depends on ARCH_OMAP2PLUS
select IOMMU_API
-config OMAP_IOVMM
- tristate "OMAP IO Virtual Memory Manager Support"
- depends on OMAP_IOMMU
-
config OMAP_IOMMU_DEBUG
- tristate "Export OMAP IOMMU/IOVMM internals in DebugFS"
- depends on OMAP_IOVMM && DEBUG_FS
+ tristate "Export OMAP IOMMU internals in DebugFS"
+ depends on OMAP_IOMMU && DEBUG_FS
help
Select this to see extensive information about
- the internal state of OMAP IOMMU/IOVMM in debugfs.
+ the internal state of OMAP IOMMU in debugfs.
Say N unless you know you need this.
@@ -180,6 +176,7 @@ config EXYNOS_IOMMU
bool "Exynos IOMMU Support"
depends on ARCH_EXYNOS
select IOMMU_API
+ select ARM_DMA_USE_IOMMU
help
Support for the IOMMU (System MMU) of Samsung Exynos application
processor family. This enables H/W multimedia accelerators to see
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 8893bad048e0..16edef74b8ee 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_IOMMU_API) += iommu.o
obj-$(CONFIG_IOMMU_API) += iommu-traces.o
+obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
obj-$(CONFIG_OF_IOMMU) += of_iommu.o
obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
@@ -11,7 +12,6 @@ obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
-obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 4aec6a29e316..18405314168b 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -46,7 +46,6 @@
#include "amd_iommu_proto.h"
#include "amd_iommu_types.h"
#include "irq_remapping.h"
-#include "pci.h"
#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
@@ -81,7 +80,7 @@ LIST_HEAD(hpet_map);
*/
static struct protection_domain *pt_domain;
-static struct iommu_ops amd_iommu_ops;
+static const struct iommu_ops amd_iommu_ops;
static ATOMIC_NOTIFIER_HEAD(ppr_notifier);
int amd_iommu_max_glx_val = -1;
@@ -133,9 +132,6 @@ static void free_dev_data(struct iommu_dev_data *dev_data)
list_del(&dev_data->dev_data_list);
spin_unlock_irqrestore(&dev_data_list_lock, flags);
- if (dev_data->group)
- iommu_group_put(dev_data->group);
-
kfree(dev_data);
}
@@ -264,167 +260,79 @@ static bool check_device(struct device *dev)
return true;
}
-static struct pci_bus *find_hosted_bus(struct pci_bus *bus)
-{
- while (!bus->self) {
- if (!pci_is_root_bus(bus))
- bus = bus->parent;
- else
- return ERR_PTR(-ENODEV);
- }
-
- return bus;
-}
-
-#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
-
-static struct pci_dev *get_isolation_root(struct pci_dev *pdev)
-{
- struct pci_dev *dma_pdev = pdev;
-
- /* Account for quirked devices */
- swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
-
- /*
- * If it's a multifunction device that does not support our
- * required ACS flags, add to the same group as lowest numbered
- * function that also does not suport the required ACS flags.
- */
- if (dma_pdev->multifunction &&
- !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
- u8 i, slot = PCI_SLOT(dma_pdev->devfn);
-
- for (i = 0; i < 8; i++) {
- struct pci_dev *tmp;
-
- tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
- if (!tmp)
- continue;
-
- if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
- swap_pci_ref(&dma_pdev, tmp);
- break;
- }
- pci_dev_put(tmp);
- }
- }
-
- /*
- * Devices on the root bus go through the iommu. If that's not us,
- * find the next upstream device and test ACS up to the root bus.
- * Finding the next device may require skipping virtual buses.
- */
- while (!pci_is_root_bus(dma_pdev->bus)) {
- struct pci_bus *bus = find_hosted_bus(dma_pdev->bus);
- if (IS_ERR(bus))
- break;
-
- if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
- break;
-
- swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
- }
-
- return dma_pdev;
-}
-
-static int use_pdev_iommu_group(struct pci_dev *pdev, struct device *dev)
+static int init_iommu_group(struct device *dev)
{
- struct iommu_group *group = iommu_group_get(&pdev->dev);
- int ret;
+ struct iommu_group *group;
- if (!group) {
- group = iommu_group_alloc();
- if (IS_ERR(group))
- return PTR_ERR(group);
+ group = iommu_group_get_for_dev(dev);
- WARN_ON(&pdev->dev != dev);
- }
+ if (IS_ERR(group))
+ return PTR_ERR(group);
- ret = iommu_group_add_device(group, dev);
iommu_group_put(group);
- return ret;
+ return 0;
}
-static int use_dev_data_iommu_group(struct iommu_dev_data *dev_data,
- struct device *dev)
+static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
{
- if (!dev_data->group) {
- struct iommu_group *group = iommu_group_alloc();
- if (IS_ERR(group))
- return PTR_ERR(group);
-
- dev_data->group = group;
- }
-
- return iommu_group_add_device(dev_data->group, dev);
+ *(u16 *)data = alias;
+ return 0;
}
-static int init_iommu_group(struct device *dev)
+static u16 get_alias(struct device *dev)
{
- struct iommu_dev_data *dev_data;
- struct iommu_group *group;
- struct pci_dev *dma_pdev;
- int ret;
-
- group = iommu_group_get(dev);
- if (group) {
- iommu_group_put(group);
- return 0;
- }
-
- dev_data = find_dev_data(get_device_id(dev));
- if (!dev_data)
- return -ENOMEM;
+ struct pci_dev *pdev = to_pci_dev(dev);
+ u16 devid, ivrs_alias, pci_alias;
- if (dev_data->alias_data) {
- u16 alias;
- struct pci_bus *bus;
+ devid = get_device_id(dev);
+ ivrs_alias = amd_iommu_alias_table[devid];
+ pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
- if (dev_data->alias_data->group)
- goto use_group;
+ if (ivrs_alias == pci_alias)
+ return ivrs_alias;
- /*
- * If the alias device exists, it's effectively just a first
- * level quirk for finding the DMA source.
- */
- alias = amd_iommu_alias_table[dev_data->devid];
- dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
- if (dma_pdev) {
- dma_pdev = get_isolation_root(dma_pdev);
- goto use_pdev;
+ /*
+ * DMA alias showdown
+ *
+ * The IVRS is fairly reliable in telling us about aliases, but it
+ * can't know about every screwy device. If we don't have an IVRS
+ * reported alias, use the PCI reported alias. In that case we may
+ * still need to initialize the rlookup and dev_table entries if the
+ * alias is to a non-existent device.
+ */
+ if (ivrs_alias == devid) {
+ if (!amd_iommu_rlookup_table[pci_alias]) {
+ amd_iommu_rlookup_table[pci_alias] =
+ amd_iommu_rlookup_table[devid];
+ memcpy(amd_iommu_dev_table[pci_alias].data,
+ amd_iommu_dev_table[devid].data,
+ sizeof(amd_iommu_dev_table[pci_alias].data));
}
- /*
- * If the alias is virtual, try to find a parent device
- * and test whether the IOMMU group is actualy rooted above
- * the alias. Be careful to also test the parent device if
- * we think the alias is the root of the group.
- */
- bus = pci_find_bus(0, alias >> 8);
- if (!bus)
- goto use_group;
-
- bus = find_hosted_bus(bus);
- if (IS_ERR(bus) || !bus->self)
- goto use_group;
+ return pci_alias;
+ }
- dma_pdev = get_isolation_root(pci_dev_get(bus->self));
- if (dma_pdev != bus->self || (dma_pdev->multifunction &&
- !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)))
- goto use_pdev;
+ pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "
+ "for device %s[%04x:%04x], kernel reported alias "
+ "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),
+ PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,
+ PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),
+ PCI_FUNC(pci_alias));
- pci_dev_put(dma_pdev);
- goto use_group;
+ /*
+ * If we don't have a PCI DMA alias and the IVRS alias is on the same
+ * bus, then the IVRS table may know about a quirk that we don't.
+ */
+ if (pci_alias == devid &&
+ PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {
+ pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;
+ pdev->dma_alias_devfn = ivrs_alias & 0xff;
+ pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",
+ PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),
+ dev_name(dev));
}
- dma_pdev = get_isolation_root(pci_dev_get(to_pci_dev(dev)));
-use_pdev:
- ret = use_pdev_iommu_group(dma_pdev, dev);
- pci_dev_put(dma_pdev);
- return ret;
-use_group:
- return use_dev_data_iommu_group(dev_data->alias_data, dev);
+ return ivrs_alias;
}
static int iommu_init_device(struct device *dev)
@@ -441,7 +349,8 @@ static int iommu_init_device(struct device *dev)
if (!dev_data)
return -ENOMEM;
- alias = amd_iommu_alias_table[dev_data->devid];
+ alias = get_alias(dev);
+
if (alias != dev_data->devid) {
struct iommu_dev_data *alias_data;
@@ -470,6 +379,9 @@ static int iommu_init_device(struct device *dev)
dev->archdata.iommu = dev_data;
+ iommu_device_link(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
+ dev);
+
return 0;
}
@@ -489,12 +401,22 @@ static void iommu_ignore_device(struct device *dev)
static void iommu_uninit_device(struct device *dev)
{
+ struct iommu_dev_data *dev_data = search_dev_data(get_device_id(dev));
+
+ if (!dev_data)
+ return;
+
+ iommu_device_unlink(amd_iommu_rlookup_table[dev_data->devid]->iommu_dev,
+ dev);
+
iommu_group_remove_device(dev);
+ /* Unlink from alias, it may change if another device is re-plugged */
+ dev_data->alias_data = NULL;
+
/*
- * Nothing to do here - we keep dev_data around for unplugged devices
- * and reuse it when the device is re-plugged - not doing so would
- * introduce a ton of races.
+ * We keep dev_data around for unplugged devices and reuse it when the
+ * device is re-plugged - not doing so would introduce a ton of races.
*/
}
@@ -3473,7 +3395,7 @@ static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
return 0;
}
-static struct iommu_ops amd_iommu_ops = {
+static const struct iommu_ops amd_iommu_ops = {
.domain_init = amd_iommu_domain_init,
.domain_destroy = amd_iommu_domain_destroy,
.attach_dev = amd_iommu_attach_device,
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 0e08545d7298..3783e0b44df6 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -26,6 +26,7 @@
#include <linux/msi.h>
#include <linux/amd-iommu.h>
#include <linux/export.h>
+#include <linux/iommu.h>
#include <asm/pci-direct.h>
#include <asm/iommu.h>
#include <asm/gart.h>
@@ -1197,6 +1198,39 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
iommu->max_counters = (u8) ((val >> 7) & 0xf);
}
+static ssize_t amd_iommu_show_cap(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct amd_iommu *iommu = dev_get_drvdata(dev);
+ return sprintf(buf, "%x\n", iommu->cap);
+}
+static DEVICE_ATTR(cap, S_IRUGO, amd_iommu_show_cap, NULL);
+
+static ssize_t amd_iommu_show_features(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct amd_iommu *iommu = dev_get_drvdata(dev);
+ return sprintf(buf, "%llx\n", iommu->features);
+}
+static DEVICE_ATTR(features, S_IRUGO, amd_iommu_show_features, NULL);
+
+static struct attribute *amd_iommu_attrs[] = {
+ &dev_attr_cap.attr,
+ &dev_attr_features.attr,
+ NULL,
+};
+
+static struct attribute_group amd_iommu_group = {
+ .name = "amd-iommu",
+ .attrs = amd_iommu_attrs,
+};
+
+static const struct attribute_group *amd_iommu_groups[] = {
+ &amd_iommu_group,
+ NULL,
+};
static int iommu_init_pci(struct amd_iommu *iommu)
{
@@ -1297,6 +1331,10 @@ static int iommu_init_pci(struct amd_iommu *iommu)
amd_iommu_erratum_746_workaround(iommu);
+ iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
+ amd_iommu_groups, "ivhd%d",
+ iommu->index);
+
return pci_enable_device(iommu->dev);
}
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f1a5abf11acf..8e43b7cba133 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -390,12 +390,6 @@ struct amd_iommu_fault {
};
-#define PPR_FAULT_EXEC (1 << 1)
-#define PPR_FAULT_READ (1 << 2)
-#define PPR_FAULT_WRITE (1 << 5)
-#define PPR_FAULT_USER (1 << 6)
-#define PPR_FAULT_RSVD (1 << 7)
-#define PPR_FAULT_GN (1 << 8)
struct iommu_domain;
@@ -432,7 +426,6 @@ struct iommu_dev_data {
struct iommu_dev_data *alias_data;/* The alias dev_data */
struct protection_domain *domain; /* Domain the device is bound to */
atomic_t bind; /* Domain attach reference count */
- struct iommu_group *group; /* IOMMU group for virtual aliases */
u16 devid; /* PCI Device ID */
bool iommu_v2; /* Device can make use of IOMMUv2 */
bool passthrough; /* Default for device is pt_domain */
@@ -578,6 +571,9 @@ struct amd_iommu {
/* default dma_ops domain for that IOMMU */
struct dma_ops_domain *default_dom;
+ /* IOMMU sysfs device */
+ struct device *iommu_dev;
+
/*
* We can't rely on the BIOS to restore all values on reinit, so we
* need to stash them
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index 499b4366a98d..5f578e850fc5 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -47,12 +47,13 @@ struct pasid_state {
atomic_t count; /* Reference count */
unsigned mmu_notifier_count; /* Counting nested mmu_notifier
calls */
- struct task_struct *task; /* Task bound to this PASID */
struct mm_struct *mm; /* mm_struct for the faults */
- struct mmu_notifier mn; /* mmu_otifier handle */
+ struct mmu_notifier mn; /* mmu_notifier handle */
struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */
struct device_state *device_state; /* Link to our device_state */
int pasid; /* PASID index */
+ bool invalid; /* Used during setup and
+ teardown of the pasid */
spinlock_t lock; /* Protect pri_queues and
mmu_notifer_count */
wait_queue_head_t wq; /* To wait for count == 0 */
@@ -99,7 +100,6 @@ static struct workqueue_struct *iommu_wq;
static u64 *empty_page_table;
static void free_pasid_states(struct device_state *dev_state);
-static void unbind_pasid(struct device_state *dev_state, int pasid);
static u16 device_id(struct pci_dev *pdev)
{
@@ -297,37 +297,29 @@ static void put_pasid_state_wait(struct pasid_state *pasid_state)
schedule();
finish_wait(&pasid_state->wq, &wait);
- mmput(pasid_state->mm);
free_pasid_state(pasid_state);
}
-static void __unbind_pasid(struct pasid_state *pasid_state)
+static void unbind_pasid(struct pasid_state *pasid_state)
{
struct iommu_domain *domain;
domain = pasid_state->device_state->domain;
+ /*
+ * Mark pasid_state as invalid, no more faults will we added to the
+ * work queue after this is visible everywhere.
+ */
+ pasid_state->invalid = true;
+
+ /* Make sure this is visible */
+ smp_wmb();
+
+ /* After this the device/pasid can't access the mm anymore */
amd_iommu_domain_clear_gcr3(domain, pasid_state->pasid);
- clear_pasid_state(pasid_state->device_state, pasid_state->pasid);
/* Make sure no more pending faults are in the queue */
flush_workqueue(iommu_wq);
-
- mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);
-
- put_pasid_state(pasid_state); /* Reference taken in bind() function */
-}
-
-static void unbind_pasid(struct device_state *dev_state, int pasid)
-{
- struct pasid_state *pasid_state;
-
- pasid_state = get_pasid_state(dev_state, pasid);
- if (pasid_state == NULL)
- return;
-
- __unbind_pasid(pasid_state);
- put_pasid_state_wait(pasid_state); /* Reference taken in this function */
}
static void free_pasid_states_level1(struct pasid_state **tbl)
@@ -373,6 +365,12 @@ static void free_pasid_states(struct device_state *dev_state)
* unbind the PASID
*/
mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);
+
+ put_pasid_state_wait(pasid_state); /* Reference taken in
+ amd_iommu_bind_pasid */
+
+ /* Drop reference taken in amd_iommu_bind_pasid */
+ put_device_state(dev_state);
}
if (dev_state->pasid_levels == 2)
@@ -411,14 +409,6 @@ static int mn_clear_flush_young(struct mmu_notifier *mn,
return 0;
}
-static void mn_change_pte(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long address,
- pte_t pte)
-{
- __mn_flush_page(mn, address);
-}
-
static void mn_invalidate_page(struct mmu_notifier *mn,
struct mm_struct *mm,
unsigned long address)
@@ -472,22 +462,23 @@ static void mn_release(struct mmu_notifier *mn, struct mm_struct *mm)
{
struct pasid_state *pasid_state;
struct device_state *dev_state;
+ bool run_inv_ctx_cb;
might_sleep();
- pasid_state = mn_to_state(mn);
- dev_state = pasid_state->device_state;
+ pasid_state = mn_to_state(mn);
+ dev_state = pasid_state->device_state;
+ run_inv_ctx_cb = !pasid_state->invalid;
- if (pasid_state->device_state->inv_ctx_cb)
+ if (run_inv_ctx_cb && pasid_state->device_state->inv_ctx_cb)
dev_state->inv_ctx_cb(dev_state->pdev, pasid_state->pasid);
- unbind_pasid(dev_state, pasid_state->pasid);
+ unbind_pasid(pasid_state);
}
static struct mmu_notifier_ops iommu_mn = {
.release = mn_release,
.clear_flush_young = mn_clear_flush_young,
- .change_pte = mn_change_pte,
.invalidate_page = mn_invalidate_page,
.invalidate_range_start = mn_invalidate_range_start,
.invalidate_range_end = mn_invalidate_range_end,
@@ -529,7 +520,7 @@ static void do_fault(struct work_struct *work)
write = !!(fault->flags & PPR_FAULT_WRITE);
down_read(&fault->state->mm->mmap_sem);
- npages = get_user_pages(fault->state->task, fault->state->mm,
+ npages = get_user_pages(NULL, fault->state->mm,
fault->address, 1, write, 0, &page, NULL);
up_read(&fault->state->mm->mmap_sem);
@@ -587,7 +578,7 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
goto out;
pasid_state = get_pasid_state(dev_state, iommu_fault->pasid);
- if (pasid_state == NULL) {
+ if (pasid_state == NULL || pasid_state->invalid) {
/* We know the device but not the PASID -> send INVALID */
amd_iommu_complete_ppr(dev_state->pdev, iommu_fault->pasid,
PPR_INVALID, tag);
@@ -612,6 +603,7 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
fault->state = pasid_state;
fault->tag = tag;
fault->finish = finish;
+ fault->pasid = iommu_fault->pasid;
fault->flags = iommu_fault->flags;
INIT_WORK(&fault->work, do_fault);
@@ -620,6 +612,10 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
ret = NOTIFY_OK;
out_drop_state:
+
+ if (ret != NOTIFY_OK && pasid_state)
+ put_pasid_state(pasid_state);
+
put_device_state(dev_state);
out:
@@ -635,6 +631,7 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,
{
struct pasid_state *pasid_state;
struct device_state *dev_state;
+ struct mm_struct *mm;
u16 devid;
int ret;
@@ -658,20 +655,23 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,
if (pasid_state == NULL)
goto out;
+
atomic_set(&pasid_state->count, 1);
init_waitqueue_head(&pasid_state->wq);
spin_lock_init(&pasid_state->lock);
- pasid_state->task = task;
- pasid_state->mm = get_task_mm(task);
+ mm = get_task_mm(task);
+ pasid_state->mm = mm;
pasid_state->device_state = dev_state;
pasid_state->pasid = pasid;
+ pasid_state->invalid = true; /* Mark as valid only if we are
+ done with setting up the pasid */
pasid_state->mn.ops = &iommu_mn;
if (pasid_state->mm == NULL)
goto out_free;
- mmu_notifier_register(&pasid_state->mn, pasid_state->mm);
+ mmu_notifier_register(&pasid_state->mn, mm);
ret = set_pasid_state(dev_state, pasid_state, pasid);
if (ret)
@@ -682,15 +682,26 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,
if (ret)
goto out_clear_state;
+ /* Now we are ready to handle faults */
+ pasid_state->invalid = false;
+
+ /*
+ * Drop the reference to the mm_struct here. We rely on the
+ * mmu_notifier release call-back to inform us when the mm
+ * is going away.
+ */
+ mmput(mm);
+
return 0;
out_clear_state:
clear_pasid_state(dev_state, pasid);
out_unregister:
- mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);
+ mmu_notifier_unregister(&pasid_state->mn, mm);
out_free:
+ mmput(mm);
free_pasid_state(pasid_state);
out:
@@ -728,10 +739,22 @@ void amd_iommu_unbind_pasid(struct pci_dev *pdev, int pasid)
*/
put_pasid_state(pasid_state);
- /* This will call the mn_release function and unbind the PASID */
+ /* Clear the pasid state so that the pasid can be re-used */
+ clear_pasid_state(dev_state, pasid_state->pasid);
+
+ /*
+ * Call mmu_notifier_unregister to drop our reference
+ * to pasid_state->mm
+ */
mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);
+ put_pasid_state_wait(pasid_state); /* Reference taken in
+ amd_iommu_bind_pasid */
out:
+ /* Drop reference taken in this function */
+ put_device_state(dev_state);
+
+ /* Drop reference taken in amd_iommu_bind_pasid */
put_device_state(dev_state);
}
EXPORT_SYMBOL(amd_iommu_unbind_pasid);
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1599354e974d..ca18d6d42a9b 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -39,6 +39,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -316,9 +317,9 @@
#define FSR_AFF (1 << 2)
#define FSR_TF (1 << 1)
-#define FSR_IGN (FSR_AFF | FSR_ASF | FSR_TLBMCF | \
- FSR_TLBLKF)
-#define FSR_FAULT (FSR_MULTI | FSR_SS | FSR_UUT | \
+#define FSR_IGN (FSR_AFF | FSR_ASF | \
+ FSR_TLBMCF | FSR_TLBLKF)
+#define FSR_FAULT (FSR_MULTI | FSR_SS | FSR_UUT | \
FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
#define FSYNR0_WNR (1 << 4)
@@ -329,27 +330,20 @@ struct arm_smmu_smr {
u16 id;
};
-struct arm_smmu_master {
- struct device_node *of_node;
-
- /*
- * The following is specific to the master's position in the
- * SMMU chain.
- */
- struct rb_node node;
+struct arm_smmu_master_cfg {
int num_streamids;
u16 streamids[MAX_MASTER_STREAMIDS];
-
- /*
- * We only need to allocate these on the root SMMU, as we
- * configure unmatched streams to bypass translation.
- */
struct arm_smmu_smr *smrs;
};
+struct arm_smmu_master {
+ struct device_node *of_node;
+ struct rb_node node;
+ struct arm_smmu_master_cfg cfg;
+};
+
struct arm_smmu_device {
struct device *dev;
- struct device_node *parent_of_node;
void __iomem *base;
unsigned long size;
@@ -387,7 +381,6 @@ struct arm_smmu_device {
};
struct arm_smmu_cfg {
- struct arm_smmu_device *smmu;
u8 cbndx;
u8 irptndx;
u32 cbar;
@@ -399,15 +392,8 @@ struct arm_smmu_cfg {
#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1)
struct arm_smmu_domain {
- /*
- * A domain can span across multiple, chained SMMUs and requires
- * all devices within the domain to follow the same translation
- * path.
- */
- struct arm_smmu_device *leaf_smmu;
- struct arm_smmu_cfg root_cfg;
- phys_addr_t output_mask;
-
+ struct arm_smmu_device *smmu;
+ struct arm_smmu_cfg cfg;
spinlock_t lock;
};
@@ -419,7 +405,7 @@ struct arm_smmu_option_prop {
const char *prop;
};
-static struct arm_smmu_option_prop arm_smmu_options [] = {
+static struct arm_smmu_option_prop arm_smmu_options[] = {
{ ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" },
{ 0, NULL},
};
@@ -427,6 +413,7 @@ static struct arm_smmu_option_prop arm_smmu_options [] = {
static void parse_driver_options(struct arm_smmu_device *smmu)
{
int i = 0;
+
do {
if (of_property_read_bool(smmu->dev->of_node,
arm_smmu_options[i].prop)) {
@@ -437,6 +424,19 @@ static void parse_driver_options(struct arm_smmu_device *smmu)
} while (arm_smmu_options[++i].opt);
}
+static struct device *dev_get_master_dev(struct device *dev)
+{
+ if (dev_is_pci(dev)) {
+ struct pci_bus *bus = to_pci_dev(dev)->bus;
+
+ while (!pci_is_root_bus(bus))
+ bus = bus->parent;
+ return bus->bridge->parent;
+ }
+
+ return dev;
+}
+
static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
struct device_node *dev_node)
{
@@ -444,6 +444,7 @@ static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
while (node) {
struct arm_smmu_master *master;
+
master = container_of(node, struct arm_smmu_master, node);
if (dev_node < master->of_node)
@@ -457,6 +458,18 @@ static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
return NULL;
}
+static struct arm_smmu_master_cfg *
+find_smmu_master_cfg(struct arm_smmu_device *smmu, struct device *dev)
+{
+ struct arm_smmu_master *master;
+
+ if (dev_is_pci(dev))
+ return dev->archdata.iommu;
+
+ master = find_smmu_master(smmu, dev->of_node);
+ return master ? &master->cfg : NULL;
+}
+
static int insert_smmu_master(struct arm_smmu_device *smmu,
struct arm_smmu_master *master)
{
@@ -465,8 +478,8 @@ static int insert_smmu_master(struct arm_smmu_device *smmu,
new = &smmu->masters.rb_node;
parent = NULL;
while (*new) {
- struct arm_smmu_master *this;
- this = container_of(*new, struct arm_smmu_master, node);
+ struct arm_smmu_master *this
+ = container_of(*new, struct arm_smmu_master, node);
parent = *new;
if (master->of_node < this->of_node)
@@ -508,33 +521,30 @@ static int register_smmu_master(struct arm_smmu_device *smmu,
if (!master)
return -ENOMEM;
- master->of_node = masterspec->np;
- master->num_streamids = masterspec->args_count;
+ master->of_node = masterspec->np;
+ master->cfg.num_streamids = masterspec->args_count;
- for (i = 0; i < master->num_streamids; ++i)
- master->streamids[i] = masterspec->args[i];
+ for (i = 0; i < master->cfg.num_streamids; ++i)
+ master->cfg.streamids[i] = masterspec->args[i];
return insert_smmu_master(smmu, master);
}
-static struct arm_smmu_device *find_parent_smmu(struct arm_smmu_device *smmu)
+static struct arm_smmu_device *find_smmu_for_device(struct device *dev)
{
- struct arm_smmu_device *parent;
-
- if (!smmu->parent_of_node)
- return NULL;
+ struct arm_smmu_device *smmu;
+ struct arm_smmu_master *master = NULL;
+ struct device_node *dev_node = dev_get_master_dev(dev)->of_node;
spin_lock(&arm_smmu_devices_lock);
- list_for_each_entry(parent, &arm_smmu_devices, list)
- if (parent->dev->of_node == smmu->parent_of_node)
- goto out_unlock;
-
- parent = NULL;
- dev_warn(smmu->dev,
- "Failed to find SMMU parent despite parent in DT\n");
-out_unlock:
+ list_for_each_entry(smmu, &arm_smmu_devices, list) {
+ master = find_smmu_master(smmu, dev_node);
+ if (master)
+ break;
+ }
spin_unlock(&arm_smmu_devices_lock);
- return parent;
+
+ return master ? smmu : NULL;
}
static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end)
@@ -574,9 +584,10 @@ static void arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
}
}
-static void arm_smmu_tlb_inv_context(struct arm_smmu_cfg *cfg)
+static void arm_smmu_tlb_inv_context(struct arm_smmu_domain *smmu_domain)
{
- struct arm_smmu_device *smmu = cfg->smmu;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
void __iomem *base = ARM_SMMU_GR0(smmu);
bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
@@ -600,11 +611,11 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
unsigned long iova;
struct iommu_domain *domain = dev;
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- struct arm_smmu_device *smmu = root_cfg->smmu;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
void __iomem *cb_base;
- cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx);
+ cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
if (!(fsr & FSR_FAULT))
@@ -631,7 +642,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
} else {
dev_err_ratelimited(smmu->dev,
"Unhandled context fault: iova=0x%08lx, fsynr=0x%x, cb=%d\n",
- iova, fsynr, root_cfg->cbndx);
+ iova, fsynr, cfg->cbndx);
ret = IRQ_NONE;
resume = RESUME_TERMINATE;
}
@@ -696,19 +707,19 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
{
u32 reg;
bool stage1;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- struct arm_smmu_device *smmu = root_cfg->smmu;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
void __iomem *cb_base, *gr0_base, *gr1_base;
gr0_base = ARM_SMMU_GR0(smmu);
gr1_base = ARM_SMMU_GR1(smmu);
- stage1 = root_cfg->cbar != CBAR_TYPE_S2_TRANS;
- cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx);
+ stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
+ cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
/* CBAR */
- reg = root_cfg->cbar;
+ reg = cfg->cbar;
if (smmu->version == 1)
- reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+ reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT;
/*
* Use the weakest shareability/memory types, so they are
@@ -718,9 +729,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
(CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
} else {
- reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT;
+ reg |= ARM_SMMU_CB_VMID(cfg) << CBAR_VMID_SHIFT;
}
- writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx));
+ writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx));
if (smmu->version > 1) {
/* CBA2R */
@@ -730,7 +741,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
reg = CBA2R_RW64_32BIT;
#endif
writel_relaxed(reg,
- gr1_base + ARM_SMMU_GR1_CBA2R(root_cfg->cbndx));
+ gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx));
/* TTBCR2 */
switch (smmu->input_size) {
@@ -780,13 +791,13 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
}
/* TTBR0 */
- arm_smmu_flush_pgtable(smmu, root_cfg->pgd,
+ arm_smmu_flush_pgtable(smmu, cfg->pgd,
PTRS_PER_PGD * sizeof(pgd_t));
- reg = __pa(root_cfg->pgd);
+ reg = __pa(cfg->pgd);
writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
- reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32;
+ reg = (phys_addr_t)__pa(cfg->pgd) >> 32;
if (stage1)
- reg |= ARM_SMMU_CB_ASID(root_cfg) << TTBRn_HI_ASID_SHIFT;
+ reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
/*
@@ -800,6 +811,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
reg = TTBCR_TG0_64K;
if (!stage1) {
+ reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT;
+
switch (smmu->s2_output_size) {
case 32:
reg |= (TTBCR2_ADDR_32 << TTBCR_PASIZE_SHIFT);
@@ -821,7 +834,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
break;
}
} else {
- reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT;
+ reg |= (64 - smmu->input_size) << TTBCR_T0SZ_SHIFT;
}
} else {
reg = 0;
@@ -853,44 +866,25 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
}
static int arm_smmu_init_domain_context(struct iommu_domain *domain,
- struct device *dev)
+ struct arm_smmu_device *smmu)
{
int irq, ret, start;
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- struct arm_smmu_device *smmu, *parent;
-
- /*
- * Walk the SMMU chain to find the root device for this chain.
- * We assume that no masters have translations which terminate
- * early, and therefore check that the root SMMU does indeed have
- * a StreamID for the master in question.
- */
- parent = dev->archdata.iommu;
- smmu_domain->output_mask = -1;
- do {
- smmu = parent;
- smmu_domain->output_mask &= (1ULL << smmu->s2_output_size) - 1;
- } while ((parent = find_parent_smmu(smmu)));
-
- if (!find_smmu_master(smmu, dev->of_node)) {
- dev_err(dev, "unable to find root SMMU for device\n");
- return -ENODEV;
- }
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) {
/*
* We will likely want to change this if/when KVM gets
* involved.
*/
- root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
+ cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
start = smmu->num_s2_context_banks;
- } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S2) {
- root_cfg->cbar = CBAR_TYPE_S2_TRANS;
- start = 0;
- } else {
- root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
+ } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) {
+ cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
start = smmu->num_s2_context_banks;
+ } else {
+ cfg->cbar = CBAR_TYPE_S2_TRANS;
+ start = 0;
}
ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
@@ -898,38 +892,38 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
if (IS_ERR_VALUE(ret))
return ret;
- root_cfg->cbndx = ret;
+ cfg->cbndx = ret;
if (smmu->version == 1) {
- root_cfg->irptndx = atomic_inc_return(&smmu->irptndx);
- root_cfg->irptndx %= smmu->num_context_irqs;
+ cfg->irptndx = atomic_inc_return(&smmu->irptndx);
+ cfg->irptndx %= smmu->num_context_irqs;
} else {
- root_cfg->irptndx = root_cfg->cbndx;
+ cfg->irptndx = cfg->cbndx;
}
- irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx];
+ irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED,
"arm-smmu-context-fault", domain);
if (IS_ERR_VALUE(ret)) {
dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
- root_cfg->irptndx, irq);
- root_cfg->irptndx = INVALID_IRPTNDX;
+ cfg->irptndx, irq);
+ cfg->irptndx = INVALID_IRPTNDX;
goto out_free_context;
}
- root_cfg->smmu = smmu;
+ smmu_domain->smmu = smmu;
arm_smmu_init_context_bank(smmu_domain);
- return ret;
+ return 0;
out_free_context:
- __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx);
+ __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
return ret;
}
static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
{
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- struct arm_smmu_device *smmu = root_cfg->smmu;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
void __iomem *cb_base;
int irq;
@@ -937,16 +931,16 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
return;
/* Disable the context bank and nuke the TLB before freeing it. */
- cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx);
+ cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);
writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR);
- arm_smmu_tlb_inv_context(root_cfg);
+ arm_smmu_tlb_inv_context(smmu_domain);
- if (root_cfg->irptndx != INVALID_IRPTNDX) {
- irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx];
+ if (cfg->irptndx != INVALID_IRPTNDX) {
+ irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
free_irq(irq, domain);
}
- __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx);
+ __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
}
static int arm_smmu_domain_init(struct iommu_domain *domain)
@@ -963,10 +957,10 @@ static int arm_smmu_domain_init(struct iommu_domain *domain)
if (!smmu_domain)
return -ENOMEM;
- pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
+ pgd = kcalloc(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL);
if (!pgd)
goto out_free_domain;
- smmu_domain->root_cfg.pgd = pgd;
+ smmu_domain->cfg.pgd = pgd;
spin_lock_init(&smmu_domain->lock);
domain->priv = smmu_domain;
@@ -980,6 +974,7 @@ out_free_domain:
static void arm_smmu_free_ptes(pmd_t *pmd)
{
pgtable_t table = pmd_pgtable(*pmd);
+
pgtable_page_dtor(table);
__free_page(table);
}
@@ -1021,8 +1016,8 @@ static void arm_smmu_free_puds(pgd_t *pgd)
static void arm_smmu_free_pgtables(struct arm_smmu_domain *smmu_domain)
{
int i;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- pgd_t *pgd, *pgd_base = root_cfg->pgd;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ pgd_t *pgd, *pgd_base = cfg->pgd;
/*
* Recursively free the page tables for this domain. We don't
@@ -1054,7 +1049,7 @@ static void arm_smmu_domain_destroy(struct iommu_domain *domain)
}
static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu,
- struct arm_smmu_master *master)
+ struct arm_smmu_master_cfg *cfg)
{
int i;
struct arm_smmu_smr *smrs;
@@ -1063,18 +1058,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu,
if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH))
return 0;
- if (master->smrs)
+ if (cfg->smrs)
return -EEXIST;
- smrs = kmalloc(sizeof(*smrs) * master->num_streamids, GFP_KERNEL);
+ smrs = kmalloc_array(cfg->num_streamids, sizeof(*smrs), GFP_KERNEL);
if (!smrs) {
- dev_err(smmu->dev, "failed to allocate %d SMRs for master %s\n",
- master->num_streamids, master->of_node->name);
+ dev_err(smmu->dev, "failed to allocate %d SMRs\n",
+ cfg->num_streamids);
return -ENOMEM;
}
- /* Allocate the SMRs on the root SMMU */
- for (i = 0; i < master->num_streamids; ++i) {
+ /* Allocate the SMRs on the SMMU */
+ for (i = 0; i < cfg->num_streamids; ++i) {
int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0,
smmu->num_mapping_groups);
if (IS_ERR_VALUE(idx)) {
@@ -1085,18 +1080,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu,
smrs[i] = (struct arm_smmu_smr) {
.idx = idx,
.mask = 0, /* We don't currently share SMRs */
- .id = master->streamids[i],
+ .id = cfg->streamids[i],
};
}
/* It worked! Now, poke the actual hardware */
- for (i = 0; i < master->num_streamids; ++i) {
+ for (i = 0; i < cfg->num_streamids; ++i) {
u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT |
smrs[i].mask << SMR_MASK_SHIFT;
writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx));
}
- master->smrs = smrs;
+ cfg->smrs = smrs;
return 0;
err_free_smrs:
@@ -1107,68 +1102,55 @@ err_free_smrs:
}
static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu,
- struct arm_smmu_master *master)
+ struct arm_smmu_master_cfg *cfg)
{
int i;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
- struct arm_smmu_smr *smrs = master->smrs;
+ struct arm_smmu_smr *smrs = cfg->smrs;
/* Invalidate the SMRs before freeing back to the allocator */
- for (i = 0; i < master->num_streamids; ++i) {
+ for (i = 0; i < cfg->num_streamids; ++i) {
u8 idx = smrs[i].idx;
+
writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx));
__arm_smmu_free_bitmap(smmu->smr_map, idx);
}
- master->smrs = NULL;
+ cfg->smrs = NULL;
kfree(smrs);
}
static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu,
- struct arm_smmu_master *master)
+ struct arm_smmu_master_cfg *cfg)
{
int i;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
- for (i = 0; i < master->num_streamids; ++i) {
- u16 sid = master->streamids[i];
+ for (i = 0; i < cfg->num_streamids; ++i) {
+ u16 sid = cfg->streamids[i];
+
writel_relaxed(S2CR_TYPE_BYPASS,
gr0_base + ARM_SMMU_GR0_S2CR(sid));
}
}
static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_master *master)
+ struct arm_smmu_master_cfg *cfg)
{
int i, ret;
- struct arm_smmu_device *parent, *smmu = smmu_domain->root_cfg.smmu;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
- ret = arm_smmu_master_configure_smrs(smmu, master);
+ ret = arm_smmu_master_configure_smrs(smmu, cfg);
if (ret)
return ret;
- /* Bypass the leaves */
- smmu = smmu_domain->leaf_smmu;
- while ((parent = find_parent_smmu(smmu))) {
- /*
- * We won't have a StreamID match for anything but the root
- * smmu, so we only need to worry about StreamID indexing,
- * where we must install bypass entries in the S2CRs.
- */
- if (smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)
- continue;
-
- arm_smmu_bypass_stream_mapping(smmu, master);
- smmu = parent;
- }
-
- /* Now we're at the root, time to point at our context bank */
- for (i = 0; i < master->num_streamids; ++i) {
+ for (i = 0; i < cfg->num_streamids; ++i) {
u32 idx, s2cr;
- idx = master->smrs ? master->smrs[i].idx : master->streamids[i];
+
+ idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i];
s2cr = S2CR_TYPE_TRANS |
- (smmu_domain->root_cfg.cbndx << S2CR_CBNDX_SHIFT);
+ (smmu_domain->cfg.cbndx << S2CR_CBNDX_SHIFT);
writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx));
}
@@ -1176,58 +1158,57 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
}
static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
- struct arm_smmu_master *master)
+ struct arm_smmu_master_cfg *cfg)
{
- struct arm_smmu_device *smmu = smmu_domain->root_cfg.smmu;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
/*
* We *must* clear the S2CR first, because freeing the SMR means
* that it can be re-allocated immediately.
*/
- arm_smmu_bypass_stream_mapping(smmu, master);
- arm_smmu_master_free_smrs(smmu, master);
+ arm_smmu_bypass_stream_mapping(smmu, cfg);
+ arm_smmu_master_free_smrs(smmu, cfg);
}
static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
int ret = -EINVAL;
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_device *device_smmu = dev->archdata.iommu;
- struct arm_smmu_master *master;
+ struct arm_smmu_device *smmu;
+ struct arm_smmu_master_cfg *cfg;
unsigned long flags;
- if (!device_smmu) {
+ smmu = dev_get_master_dev(dev)->archdata.iommu;
+ if (!smmu) {
dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
return -ENXIO;
}
/*
- * Sanity check the domain. We don't currently support domains
- * that cross between different SMMU chains.
+ * Sanity check the domain. We don't support domains across
+ * different SMMUs.
*/
spin_lock_irqsave(&smmu_domain->lock, flags);
- if (!smmu_domain->leaf_smmu) {
+ if (!smmu_domain->smmu) {
/* Now that we have a master, we can finalise the domain */
- ret = arm_smmu_init_domain_context(domain, dev);
+ ret = arm_smmu_init_domain_context(domain, smmu);
if (IS_ERR_VALUE(ret))
goto err_unlock;
-
- smmu_domain->leaf_smmu = device_smmu;
- } else if (smmu_domain->leaf_smmu != device_smmu) {
+ } else if (smmu_domain->smmu != smmu) {
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n",
- dev_name(smmu_domain->leaf_smmu->dev),
- dev_name(device_smmu->dev));
+ dev_name(smmu_domain->smmu->dev),
+ dev_name(smmu->dev));
goto err_unlock;
}
spin_unlock_irqrestore(&smmu_domain->lock, flags);
/* Looks ok, so add the device to the domain */
- master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
- if (!master)
+ cfg = find_smmu_master_cfg(smmu_domain->smmu, dev);
+ if (!cfg)
return -ENODEV;
- return arm_smmu_domain_add_master(smmu_domain, master);
+ return arm_smmu_domain_add_master(smmu_domain, cfg);
err_unlock:
spin_unlock_irqrestore(&smmu_domain->lock, flags);
@@ -1237,11 +1218,11 @@ err_unlock:
static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
{
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_master *master;
+ struct arm_smmu_master_cfg *cfg;
- master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
- if (master)
- arm_smmu_domain_remove_master(smmu_domain, master);
+ cfg = find_smmu_master_cfg(smmu_domain->smmu, dev);
+ if (cfg)
+ arm_smmu_domain_remove_master(smmu_domain, cfg);
}
static bool arm_smmu_pte_is_contiguous_range(unsigned long addr,
@@ -1261,6 +1242,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
if (pmd_none(*pmd)) {
/* Allocate a new set of tables */
pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO);
+
if (!table)
return -ENOMEM;
@@ -1326,6 +1308,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
*/
do {
int i = 1;
+
pteval &= ~ARM_SMMU_PTE_CONT;
if (arm_smmu_pte_is_contiguous_range(addr, end)) {
@@ -1340,7 +1323,8 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
idx &= ~(ARM_SMMU_PTE_CONT_ENTRIES - 1);
cont_start = pmd_page_vaddr(*pmd) + idx;
for (j = 0; j < ARM_SMMU_PTE_CONT_ENTRIES; ++j)
- pte_val(*(cont_start + j)) &= ~ARM_SMMU_PTE_CONT;
+ pte_val(*(cont_start + j)) &=
+ ~ARM_SMMU_PTE_CONT;
arm_smmu_flush_pgtable(smmu, cont_start,
sizeof(*pte) *
@@ -1429,12 +1413,12 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
int ret, stage;
unsigned long end;
phys_addr_t input_mask, output_mask;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
- pgd_t *pgd = root_cfg->pgd;
- struct arm_smmu_device *smmu = root_cfg->smmu;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
+ pgd_t *pgd = cfg->pgd;
unsigned long flags;
- if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) {
+ if (cfg->cbar == CBAR_TYPE_S2_TRANS) {
stage = 2;
output_mask = (1ULL << smmu->s2_output_size) - 1;
} else {
@@ -1484,10 +1468,6 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
if (!smmu_domain)
return -ENODEV;
- /* Check for silent address truncation up the SMMU chain. */
- if ((phys_addr_t)iova & ~smmu_domain->output_mask)
- return -ERANGE;
-
return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot);
}
@@ -1498,7 +1478,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
struct arm_smmu_domain *smmu_domain = domain->priv;
ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0);
- arm_smmu_tlb_inv_context(&smmu_domain->root_cfg);
+ arm_smmu_tlb_inv_context(smmu_domain);
return ret ? 0 : size;
}
@@ -1510,9 +1490,9 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
pmd_t pmd;
pte_t pte;
struct arm_smmu_domain *smmu_domain = domain->priv;
- struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+ struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
- pgdp = root_cfg->pgd;
+ pgdp = cfg->pgd;
if (!pgdp)
return 0;
@@ -1538,19 +1518,29 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
unsigned long cap)
{
- unsigned long caps = 0;
struct arm_smmu_domain *smmu_domain = domain->priv;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ u32 features = smmu ? smmu->features : 0;
+
+ switch (cap) {
+ case IOMMU_CAP_CACHE_COHERENCY:
+ return features & ARM_SMMU_FEAT_COHERENT_WALK;
+ case IOMMU_CAP_INTR_REMAP:
+ return 1; /* MSIs are just memory writes */
+ default:
+ return 0;
+ }
+}
- if (smmu_domain->root_cfg.smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
- caps |= IOMMU_CAP_CACHE_COHERENCY;
-
- return !!(cap & caps);
+static int __arm_smmu_get_pci_sid(struct pci_dev *pdev, u16 alias, void *data)
+{
+ *((u16 *)data) = alias;
+ return 0; /* Continue walking */
}
static int arm_smmu_add_device(struct device *dev)
{
- struct arm_smmu_device *child, *parent, *smmu;
- struct arm_smmu_master *master = NULL;
+ struct arm_smmu_device *smmu;
struct iommu_group *group;
int ret;
@@ -1559,35 +1549,8 @@ static int arm_smmu_add_device(struct device *dev)
return -EINVAL;
}
- spin_lock(&arm_smmu_devices_lock);
- list_for_each_entry(parent, &arm_smmu_devices, list) {
- smmu = parent;
-
- /* Try to find a child of the current SMMU. */
- list_for_each_entry(child, &arm_smmu_devices, list) {
- if (child->parent_of_node == parent->dev->of_node) {
- /* Does the child sit above our master? */
- master = find_smmu_master(child, dev->of_node);
- if (master) {
- smmu = NULL;
- break;
- }
- }
- }
-
- /* We found some children, so keep searching. */
- if (!smmu) {
- master = NULL;
- continue;
- }
-
- master = find_smmu_master(smmu, dev->of_node);
- if (master)
- break;
- }
- spin_unlock(&arm_smmu_devices_lock);
-
- if (!master)
+ smmu = find_smmu_for_device(dev);
+ if (!smmu)
return -ENODEV;
group = iommu_group_alloc();
@@ -1596,20 +1559,45 @@ static int arm_smmu_add_device(struct device *dev)
return PTR_ERR(group);
}
+ if (dev_is_pci(dev)) {
+ struct arm_smmu_master_cfg *cfg;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+ if (!cfg) {
+ ret = -ENOMEM;
+ goto out_put_group;
+ }
+
+ cfg->num_streamids = 1;
+ /*
+ * Assume Stream ID == Requester ID for now.
+ * We need a way to describe the ID mappings in FDT.
+ */
+ pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid,
+ &cfg->streamids[0]);
+ dev->archdata.iommu = cfg;
+ } else {
+ dev->archdata.iommu = smmu;
+ }
+
ret = iommu_group_add_device(group, dev);
- iommu_group_put(group);
- dev->archdata.iommu = smmu;
+out_put_group:
+ iommu_group_put(group);
return ret;
}
static void arm_smmu_remove_device(struct device *dev)
{
+ if (dev_is_pci(dev))
+ kfree(dev->archdata.iommu);
+
dev->archdata.iommu = NULL;
iommu_group_remove_device(dev);
}
-static struct iommu_ops arm_smmu_ops = {
+static const struct iommu_ops arm_smmu_ops = {
.domain_init = arm_smmu_domain_init,
.domain_destroy = arm_smmu_domain_destroy,
.attach_dev = arm_smmu_attach_dev,
@@ -1639,7 +1627,8 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
/* Mark all SMRn as invalid and all S2CRn as bypass */
for (i = 0; i < smmu->num_mapping_groups; ++i) {
writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i));
- writel_relaxed(S2CR_TYPE_BYPASS, gr0_base + ARM_SMMU_GR0_S2CR(i));
+ writel_relaxed(S2CR_TYPE_BYPASS,
+ gr0_base + ARM_SMMU_GR0_S2CR(i));
}
/* Make sure all context banks are disabled and clear CB_FSR */
@@ -1779,11 +1768,13 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
smmu->pagesize = (id & ID1_PAGESIZE) ? SZ_64K : SZ_4K;
/* Check for size mismatch of SMMU address space from mapped region */
- size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
+ size = 1 <<
+ (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
size *= (smmu->pagesize << 1);
if (smmu->size != size)
- dev_warn(smmu->dev, "SMMU address space size (0x%lx) differs "
- "from mapped region size (0x%lx)!\n", size, smmu->size);
+ dev_warn(smmu->dev,
+ "SMMU address space size (0x%lx) differs from mapped region size (0x%lx)!\n",
+ size, smmu->size);
smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) &
ID1_NUMS2CB_MASK;
@@ -1804,14 +1795,14 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
* allocation (PTRS_PER_PGD).
*/
#ifdef CONFIG_64BIT
- smmu->s1_output_size = min((unsigned long)VA_BITS, size);
+ smmu->s1_output_size = min_t(unsigned long, VA_BITS, size);
#else
smmu->s1_output_size = min(32UL, size);
#endif
/* The stage-2 output mask is also applied for bypass */
size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
- smmu->s2_output_size = min((unsigned long)PHYS_MASK_SHIFT, size);
+ smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size);
if (smmu->version == 1) {
smmu->input_size = 32;
@@ -1835,7 +1826,8 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
dev_notice(smmu->dev,
"\t%lu-bit VA, %lu-bit IPA, %lu-bit PA\n",
- smmu->input_size, smmu->s1_output_size, smmu->s2_output_size);
+ smmu->input_size, smmu->s1_output_size,
+ smmu->s2_output_size);
return 0;
}
@@ -1843,7 +1835,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
{
struct resource *res;
struct arm_smmu_device *smmu;
- struct device_node *dev_node;
struct device *dev = &pdev->dev;
struct rb_node *node;
struct of_phandle_args masterspec;
@@ -1890,6 +1881,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
for (i = 0; i < num_irqs; ++i) {
int irq = platform_get_irq(pdev, i);
+
if (irq < 0) {
dev_err(dev, "failed to get irq index %d\n", i);
return -ENODEV;
@@ -1913,12 +1905,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
}
dev_notice(dev, "registered %d master devices\n", i);
- if ((dev_node = of_parse_phandle(dev->of_node, "smmu-parent", 0)))
- smmu->parent_of_node = dev_node;
-
err = arm_smmu_device_cfg_probe(smmu);
if (err)
- goto out_put_parent;
+ goto out_put_masters;
parse_driver_options(smmu);
@@ -1928,7 +1917,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev)
"found only %d context interrupt(s) but %d required\n",
smmu->num_context_irqs, smmu->num_context_banks);
err = -ENODEV;
- goto out_put_parent;
+ goto out_put_masters;
}
for (i = 0; i < smmu->num_global_irqs; ++i) {
@@ -1956,14 +1945,10 @@ out_free_irqs:
while (i--)
free_irq(smmu->irqs[i], smmu);
-out_put_parent:
- if (smmu->parent_of_node)
- of_node_put(smmu->parent_of_node);
-
out_put_masters:
for (node = rb_first(&smmu->masters); node; node = rb_next(node)) {
- struct arm_smmu_master *master;
- master = container_of(node, struct arm_smmu_master, node);
+ struct arm_smmu_master *master
+ = container_of(node, struct arm_smmu_master, node);
of_node_put(master->of_node);
}
@@ -1990,12 +1975,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
if (!smmu)
return -ENODEV;
- if (smmu->parent_of_node)
- of_node_put(smmu->parent_of_node);
-
for (node = rb_first(&smmu->masters); node; node = rb_next(node)) {
- struct arm_smmu_master *master;
- master = container_of(node, struct arm_smmu_master, node);
+ struct arm_smmu_master *master
+ = container_of(node, struct arm_smmu_master, node);
of_node_put(master->of_node);
}
@@ -2006,7 +1988,7 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
free_irq(smmu->irqs[i], smmu);
/* Turn the thing off */
- writel(sCR0_CLIENTPD,ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
return 0;
}
@@ -2048,6 +2030,11 @@ static int __init arm_smmu_init(void)
bus_set_iommu(&amba_bustype, &arm_smmu_ops);
#endif
+#ifdef CONFIG_PCI
+ if (!iommu_present(&pci_bus_type))
+ bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+#endif
+
return 0;
}
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 9a4f05e5b23f..60ab474bfff3 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -38,6 +38,7 @@
#include <linux/tboot.h>
#include <linux/dmi.h>
#include <linux/slab.h>
+#include <linux/iommu.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
@@ -84,7 +85,7 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt)
*cnt = 0;
while (start < end) {
scope = start;
- if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ACPI ||
+ if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_NAMESPACE ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++;
@@ -380,7 +381,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
struct acpi_dmar_andd *andd = (void *)header;
/* Check for NUL termination within the designated length */
- if (strnlen(andd->object_name, header->length - 8) == header->length - 8) {
+ if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
"Your BIOS is broken; ANDD object name is not NUL-terminated\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
@@ -390,7 +391,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
return -EINVAL;
}
pr_info("ANDD device: %x name: %s\n", andd->device_number,
- andd->object_name);
+ andd->device_name);
return 0;
}
@@ -448,17 +449,17 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
(unsigned long long)rmrr->base_address,
(unsigned long long)rmrr->end_address);
break;
- case ACPI_DMAR_TYPE_ATSR:
+ case ACPI_DMAR_TYPE_ROOT_ATS:
atsr = container_of(header, struct acpi_dmar_atsr, header);
pr_info("ATSR flags: %#x\n", atsr->flags);
break;
- case ACPI_DMAR_HARDWARE_AFFINITY:
+ case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
rhsa = container_of(header, struct acpi_dmar_rhsa, header);
pr_info("RHSA base: %#016Lx proximity domain: %#x\n",
(unsigned long long)rhsa->base_address,
rhsa->proximity_domain);
break;
- case ACPI_DMAR_TYPE_ANDD:
+ case ACPI_DMAR_TYPE_NAMESPACE:
/* We don't print this here because we need to sanity-check
it first. So print it in dmar_parse_one_andd() instead. */
break;
@@ -539,15 +540,15 @@ parse_dmar_table(void)
case ACPI_DMAR_TYPE_RESERVED_MEMORY:
ret = dmar_parse_one_rmrr(entry_header);
break;
- case ACPI_DMAR_TYPE_ATSR:
+ case ACPI_DMAR_TYPE_ROOT_ATS:
ret = dmar_parse_one_atsr(entry_header);
break;
- case ACPI_DMAR_HARDWARE_AFFINITY:
+ case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
#ifdef CONFIG_ACPI_NUMA
ret = dmar_parse_one_rhsa(entry_header);
#endif
break;
- case ACPI_DMAR_TYPE_ANDD:
+ case ACPI_DMAR_TYPE_NAMESPACE:
ret = dmar_parse_one_andd(entry_header);
break;
default:
@@ -631,7 +632,7 @@ static void __init dmar_acpi_insert_dev_scope(u8 device_number,
for (scope = (void *)(drhd + 1);
(unsigned long)scope < ((unsigned long)drhd) + drhd->header.length;
scope = ((void *)scope) + scope->length) {
- if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ACPI)
+ if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE)
continue;
if (scope->enumeration_id != device_number)
continue;
@@ -666,21 +667,21 @@ static int __init dmar_acpi_dev_scope_init(void)
for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length;
andd = ((void *)andd) + andd->header.length) {
- if (andd->header.type == ACPI_DMAR_TYPE_ANDD) {
+ if (andd->header.type == ACPI_DMAR_TYPE_NAMESPACE) {
acpi_handle h;
struct acpi_device *adev;
if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
- andd->object_name,
+ andd->device_name,
&h))) {
pr_err("Failed to find handle for ACPI object %s\n",
- andd->object_name);
+ andd->device_name);
continue;
}
acpi_bus_get_device(h, &adev);
if (!adev) {
pr_err("Failed to get device for ACPI object %s\n",
- andd->object_name);
+ andd->device_name);
continue;
}
dmar_acpi_insert_dev_scope(andd->device_number, adev);
@@ -980,6 +981,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
raw_spin_lock_init(&iommu->register_lock);
drhd->iommu = iommu;
+
+ if (intel_iommu_enabled)
+ iommu->iommu_dev = iommu_device_create(NULL, iommu,
+ intel_iommu_groups,
+ iommu->name);
+
return 0;
err_unmap:
@@ -991,6 +998,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
static void free_iommu(struct intel_iommu *iommu)
{
+ iommu_device_destroy(iommu->iommu_dev);
+
if (iommu->irq) {
free_irq(iommu->irq, iommu);
irq_set_handler_data(iommu->irq, NULL);
@@ -1339,9 +1348,6 @@ int dmar_enable_qi(struct intel_iommu *iommu)
return -ENOMEM;
}
- qi->free_head = qi->free_tail = 0;
- qi->free_cnt = QI_LENGTH;
-
raw_spin_lock_init(&qi->q_lock);
__dmar_enable_qi(iommu);
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 99054d2c040d..d037e87a1fe5 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1170,7 +1170,7 @@ static void exynos_iommu_remove_device(struct device *dev)
iommu_group_remove_device(dev);
}
-static struct iommu_ops exynos_iommu_ops = {
+static const struct iommu_ops exynos_iommu_ops = {
.domain_init = exynos_iommu_domain_init,
.domain_destroy = exynos_iommu_domain_destroy,
.attach_dev = exynos_iommu_attach_device,
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index b99dd88e31b9..2b6ce9387af1 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -92,7 +92,7 @@ struct gen_pool *spaace_pool;
* subwindow count per liodn.
*
*/
-u32 pamu_get_max_subwin_cnt()
+u32 pamu_get_max_subwin_cnt(void)
{
return max_subwindow_count;
}
@@ -170,10 +170,10 @@ int pamu_disable_liodn(int liodn)
static unsigned int map_addrspace_size_to_wse(phys_addr_t addrspace_size)
{
/* Bug if not a power of 2 */
- BUG_ON(!is_power_of_2(addrspace_size));
+ BUG_ON((addrspace_size & (addrspace_size - 1)));
/* window size is 2^(WSE+1) bytes */
- return __ffs(addrspace_size) - 1;
+ return fls64(addrspace_size) - 2;
}
/* Derive the PAACE window count encoding for the subwindow count */
@@ -351,7 +351,7 @@ int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,
struct paace *ppaace;
unsigned long fspi;
- if (!is_power_of_2(win_size) || win_size < PAMU_PAGE_SIZE) {
+ if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {
pr_debug("window size too small or not a power of two %llx\n", win_size);
return -EINVAL;
}
@@ -464,7 +464,7 @@ int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin,
return -ENOENT;
}
- if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) {
+ if ((subwin_size & (subwin_size - 1)) || subwin_size < PAMU_PAGE_SIZE) {
pr_debug("subwindow size out of range, or not a power of 2\n");
return -EINVAL;
}
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 93072ba44b1d..61d1dafa242d 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -38,7 +38,6 @@
#include <sysdev/fsl_pci.h>
#include "fsl_pamu_domain.h"
-#include "pci.h"
/*
* Global spinlock that needs to be held while
@@ -301,7 +300,7 @@ static int check_size(u64 size, dma_addr_t iova)
* Size must be a power of two and at least be equal
* to PAMU page size.
*/
- if (!is_power_of_2(size) || size < PAMU_PAGE_SIZE) {
+ if ((size & (size - 1)) || size < PAMU_PAGE_SIZE) {
pr_debug("%s: size too small or not a power of two\n", __func__);
return -EINVAL;
}
@@ -335,11 +334,6 @@ static struct fsl_dma_domain *iommu_alloc_dma_domain(void)
return domain;
}
-static inline struct device_domain_info *find_domain(struct device *dev)
-{
- return dev->archdata.iommu_domain;
-}
-
static void remove_device_ref(struct device_domain_info *info, u32 win_cnt)
{
unsigned long flags;
@@ -380,7 +374,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* Check here if the device is already attached to domain or not.
* If the device is already attached to a domain detach it.
*/
- old_domain_info = find_domain(dev);
+ old_domain_info = dev->archdata.iommu_domain;
if (old_domain_info && old_domain_info->domain != dma_domain) {
spin_unlock_irqrestore(&device_domain_lock, flags);
detach_device(dev, old_domain_info->domain);
@@ -399,7 +393,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* the info for the first LIODN as all
* LIODNs share the same domain
*/
- if (!old_domain_info)
+ if (!dev->archdata.iommu_domain)
dev->archdata.iommu_domain = info;
spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -892,8 +886,6 @@ static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
return ret;
}
-#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
-
static struct iommu_group *get_device_iommu_group(struct device *dev)
{
struct iommu_group *group;
@@ -950,75 +942,14 @@ static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
struct pci_controller *pci_ctl;
bool pci_endpt_partioning;
struct iommu_group *group = NULL;
- struct pci_dev *bridge, *dma_pdev = NULL;
pci_ctl = pci_bus_to_host(pdev->bus);
pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl);
/* We can partition PCIe devices so assign device group to the device */
if (pci_endpt_partioning) {
- bridge = pci_find_upstream_pcie_bridge(pdev);
- if (bridge) {
- if (pci_is_pcie(bridge))
- dma_pdev = pci_get_domain_bus_and_slot(
- pci_domain_nr(pdev->bus),
- bridge->subordinate->number, 0);
- if (!dma_pdev)
- dma_pdev = pci_dev_get(bridge);
- } else
- dma_pdev = pci_dev_get(pdev);
-
- /* Account for quirked devices */
- swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
-
- /*
- * If it's a multifunction device that does not support our
- * required ACS flags, add to the same group as lowest numbered
- * function that also does not suport the required ACS flags.
- */
- if (dma_pdev->multifunction &&
- !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
- u8 i, slot = PCI_SLOT(dma_pdev->devfn);
-
- for (i = 0; i < 8; i++) {
- struct pci_dev *tmp;
-
- tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
- if (!tmp)
- continue;
-
- if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
- swap_pci_ref(&dma_pdev, tmp);
- break;
- }
- pci_dev_put(tmp);
- }
- }
+ group = iommu_group_get_for_dev(&pdev->dev);
/*
- * Devices on the root bus go through the iommu. If that's not us,
- * find the next upstream device and test ACS up to the root bus.
- * Finding the next device may require skipping virtual buses.
- */
- while (!pci_is_root_bus(dma_pdev->bus)) {
- struct pci_bus *bus = dma_pdev->bus;
-
- while (!bus->self) {
- if (!pci_is_root_bus(bus))
- bus = bus->parent;
- else
- goto root_bus;
- }
-
- if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
- break;
-
- swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
- }
-
-root_bus:
- group = get_device_iommu_group(&dma_pdev->dev);
- pci_dev_put(dma_pdev);
- /*
* PCIe controller is not a paritionable entity
* free the controller device iommu_group.
*/
@@ -1042,12 +973,15 @@ root_bus:
group = get_shared_pci_device_group(pdev);
}
+ if (!group)
+ group = ERR_PTR(-ENODEV);
+
return group;
}
static int fsl_pamu_add_device(struct device *dev)
{
- struct iommu_group *group = NULL;
+ struct iommu_group *group = ERR_PTR(-ENODEV);
struct pci_dev *pdev;
const u32 *prop;
int ret, len;
@@ -1070,7 +1004,7 @@ static int fsl_pamu_add_device(struct device *dev)
group = get_device_iommu_group(dev);
}
- if (!group || IS_ERR(group))
+ if (IS_ERR(group))
return PTR_ERR(group);
ret = iommu_group_add_device(group, dev);
@@ -1118,8 +1052,7 @@ static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
ret = pamu_set_domain_geometry(dma_domain, &domain->geometry,
((w_count > 1) ? w_count : 0));
if (!ret) {
- if (dma_domain->win_arr)
- kfree(dma_domain->win_arr);
+ kfree(dma_domain->win_arr);
dma_domain->win_arr = kzalloc(sizeof(struct dma_window) *
w_count, GFP_ATOMIC);
if (!dma_domain->win_arr) {
@@ -1140,7 +1073,7 @@ static u32 fsl_pamu_get_windows(struct iommu_domain *domain)
return dma_domain->win_cnt;
}
-static struct iommu_ops fsl_pamu_ops = {
+static const struct iommu_ops fsl_pamu_ops = {
.domain_init = fsl_pamu_domain_init,
.domain_destroy = fsl_pamu_domain_destroy,
.attach_dev = fsl_pamu_attach_device,
@@ -1157,7 +1090,7 @@ static struct iommu_ops fsl_pamu_ops = {
.remove_device = fsl_pamu_remove_device,
};
-int pamu_domain_init()
+int pamu_domain_init(void)
{
int ret = 0;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 51b6b77dc3e5..d1f5caad04f9 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -45,7 +45,6 @@
#include <asm/iommu.h>
#include "irq_remapping.h"
-#include "pci.h"
#define ROOT_SIZE VTD_PAGE_SIZE
#define CONTEXT_SIZE VTD_PAGE_SIZE
@@ -304,7 +303,7 @@ static inline bool dma_pte_present(struct dma_pte *pte)
static inline bool dma_pte_superpage(struct dma_pte *pte)
{
- return (pte->val & (1 << 7));
+ return (pte->val & DMA_PTE_LARGE_PAGE);
}
static inline int first_pte_in_page(struct dma_pte *pte)
@@ -321,16 +320,13 @@ static inline int first_pte_in_page(struct dma_pte *pte)
static struct dmar_domain *si_domain;
static int hw_pass_through = 1;
-/* devices under the same p2p bridge are owned in one domain */
-#define DOMAIN_FLAG_P2P_MULTIPLE_DEVICES (1 << 0)
-
/* domain represents a virtual machine, more than one devices
* across iommus may be owned in one domain, e.g. kvm guest.
*/
-#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 1)
+#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
/* si_domain contains mulitple devices */
-#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2)
+#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
/* define the limit of IOMMUs supported in each domain */
#ifdef CONFIG_X86
@@ -429,6 +425,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
struct device *dev);
static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
struct device *dev);
+static int domain_detach_iommu(struct dmar_domain *domain,
+ struct intel_iommu *iommu);
#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
int dmar_disabled = 0;
@@ -451,7 +449,7 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
static DEFINE_SPINLOCK(device_domain_lock);
static LIST_HEAD(device_domain_list);
-static struct iommu_ops intel_iommu_ops;
+static const struct iommu_ops intel_iommu_ops;
static int __init intel_iommu_setup(char *str)
{
@@ -540,6 +538,24 @@ void free_iova_mem(struct iova *iova)
kmem_cache_free(iommu_iova_cache, iova);
}
+static inline int domain_type_is_vm(struct dmar_domain *domain)
+{
+ return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
+}
+
+static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
+{
+ return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
+ DOMAIN_FLAG_STATIC_IDENTITY);
+}
+
+static inline int domain_pfn_supported(struct dmar_domain *domain,
+ unsigned long pfn)
+{
+ int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+
+ return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
+}
static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
{
@@ -580,9 +596,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
int iommu_id;
/* si_domain and vm domain should not get here. */
- BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE);
- BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
-
+ BUG_ON(domain_type_is_vm_or_si(domain));
iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
return NULL;
@@ -619,50 +633,56 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
rcu_read_unlock();
}
-static void domain_update_iommu_snooping(struct dmar_domain *domain)
+static int domain_update_iommu_snooping(struct intel_iommu *skip)
{
- int i;
-
- domain->iommu_snooping = 1;
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu;
+ int ret = 1;
- for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
- if (!ecap_sc_support(g_iommus[i]->ecap)) {
- domain->iommu_snooping = 0;
- break;
+ rcu_read_lock();
+ for_each_active_iommu(iommu, drhd) {
+ if (iommu != skip) {
+ if (!ecap_sc_support(iommu->ecap)) {
+ ret = 0;
+ break;
+ }
}
}
+ rcu_read_unlock();
+
+ return ret;
}
-static void domain_update_iommu_superpage(struct dmar_domain *domain)
+static int domain_update_iommu_superpage(struct intel_iommu *skip)
{
struct dmar_drhd_unit *drhd;
- struct intel_iommu *iommu = NULL;
+ struct intel_iommu *iommu;
int mask = 0xf;
if (!intel_iommu_superpage) {
- domain->iommu_superpage = 0;
- return;
+ return 0;
}
/* set iommu_superpage to the smallest common denominator */
rcu_read_lock();
for_each_active_iommu(iommu, drhd) {
- mask &= cap_super_page_val(iommu->cap);
- if (!mask) {
- break;
+ if (iommu != skip) {
+ mask &= cap_super_page_val(iommu->cap);
+ if (!mask)
+ break;
}
}
rcu_read_unlock();
- domain->iommu_superpage = fls(mask);
+ return fls(mask);
}
/* Some capabilities may be different across iommus */
static void domain_update_iommu_cap(struct dmar_domain *domain)
{
domain_update_iommu_coherency(domain);
- domain_update_iommu_snooping(domain);
- domain_update_iommu_superpage(domain);
+ domain->iommu_snooping = domain_update_iommu_snooping(NULL);
+ domain->iommu_superpage = domain_update_iommu_superpage(NULL);
}
static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
@@ -671,7 +691,7 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
struct intel_iommu *iommu;
struct device *tmp;
struct pci_dev *ptmp, *pdev = NULL;
- u16 segment;
+ u16 segment = 0;
int i;
if (dev_is_pci(dev)) {
@@ -816,14 +836,13 @@ out:
static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
unsigned long pfn, int *target_level)
{
- int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
struct dma_pte *parent, *pte = NULL;
int level = agaw_to_level(domain->agaw);
int offset;
BUG_ON(!domain->pgd);
- if (addr_width < BITS_PER_LONG && pfn >> addr_width)
+ if (!domain_pfn_supported(domain, pfn))
/* Address beyond IOMMU's addressing capabilities. */
return NULL;
@@ -849,13 +868,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
- if (cmpxchg64(&pte->val, 0ULL, pteval)) {
+ if (cmpxchg64(&pte->val, 0ULL, pteval))
/* Someone else set it while we were thinking; use theirs. */
free_pgtable_page(tmp_page);
- } else {
- dma_pte_addr(pte);
+ else
domain_flush_cache(domain, pte, sizeof(*pte));
- }
}
if (level == 1)
break;
@@ -892,7 +909,7 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
break;
}
- if (pte->val & DMA_PTE_LARGE_PAGE) {
+ if (dma_pte_superpage(pte)) {
*large_page = total;
return pte;
}
@@ -908,12 +925,11 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
unsigned long start_pfn,
unsigned long last_pfn)
{
- int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
unsigned int large_page = 1;
struct dma_pte *first_pte, *pte;
- BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
- BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+ BUG_ON(!domain_pfn_supported(domain, start_pfn));
+ BUG_ON(!domain_pfn_supported(domain, last_pfn));
BUG_ON(start_pfn > last_pfn);
/* we don't need lock here; nobody else touches the iova range */
@@ -974,12 +990,12 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain,
unsigned long start_pfn,
unsigned long last_pfn)
{
- int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
-
- BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
- BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+ BUG_ON(!domain_pfn_supported(domain, start_pfn));
+ BUG_ON(!domain_pfn_supported(domain, last_pfn));
BUG_ON(start_pfn > last_pfn);
+ dma_pte_clear_range(domain, start_pfn, last_pfn);
+
/* We don't need lock here; nobody else touches the iova range */
dma_pte_free_level(domain, agaw_to_level(domain->agaw),
domain->pgd, 0, start_pfn, last_pfn);
@@ -1077,11 +1093,10 @@ struct page *domain_unmap(struct dmar_domain *domain,
unsigned long start_pfn,
unsigned long last_pfn)
{
- int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
struct page *freelist = NULL;
- BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
- BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
+ BUG_ON(!domain_pfn_supported(domain, start_pfn));
+ BUG_ON(!domain_pfn_supported(domain, last_pfn));
BUG_ON(start_pfn > last_pfn);
/* we don't need lock here; nobody else touches the iova range */
@@ -1275,7 +1290,8 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(info, &domain->devices, link)
- if (info->bus == bus && info->devfn == devfn) {
+ if (info->iommu == iommu && info->bus == bus &&
+ info->devfn == devfn) {
found = 1;
break;
}
@@ -1384,7 +1400,7 @@ static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
}
-static int iommu_enable_translation(struct intel_iommu *iommu)
+static void iommu_enable_translation(struct intel_iommu *iommu)
{
u32 sts;
unsigned long flags;
@@ -1398,10 +1414,9 @@ static int iommu_enable_translation(struct intel_iommu *iommu)
readl, (sts & DMA_GSTS_TES), sts);
raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
- return 0;
}
-static int iommu_disable_translation(struct intel_iommu *iommu)
+static void iommu_disable_translation(struct intel_iommu *iommu)
{
u32 sts;
unsigned long flag;
@@ -1415,7 +1430,6 @@ static int iommu_disable_translation(struct intel_iommu *iommu)
readl, (!(sts & DMA_GSTS_TES)), sts);
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
- return 0;
}
@@ -1462,8 +1476,7 @@ static int iommu_init_domains(struct intel_iommu *iommu)
static void free_dmar_iommu(struct intel_iommu *iommu)
{
struct dmar_domain *domain;
- int i, count;
- unsigned long flags;
+ int i;
if ((iommu->domains) && (iommu->domain_ids)) {
for_each_set_bit(i, iommu->domain_ids, cap_ndoms(iommu->cap)) {
@@ -1476,11 +1489,8 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
domain = iommu->domains[i];
clear_bit(i, iommu->domain_ids);
-
- spin_lock_irqsave(&domain->iommu_lock, flags);
- count = --domain->iommu_count;
- spin_unlock_irqrestore(&domain->iommu_lock, flags);
- if (count == 0)
+ if (domain_detach_iommu(domain, iommu) == 0 &&
+ !domain_type_is_vm(domain))
domain_exit(domain);
}
}
@@ -1499,7 +1509,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
free_context_table(iommu);
}
-static struct dmar_domain *alloc_domain(bool vm)
+static struct dmar_domain *alloc_domain(int flags)
{
/* domain id for virtual machine, it won't be set in context */
static atomic_t vm_domid = ATOMIC_INIT(0);
@@ -1509,46 +1519,62 @@ static struct dmar_domain *alloc_domain(bool vm)
if (!domain)
return NULL;
+ memset(domain, 0, sizeof(*domain));
domain->nid = -1;
- domain->iommu_count = 0;
- memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
- domain->flags = 0;
+ domain->flags = flags;
spin_lock_init(&domain->iommu_lock);
INIT_LIST_HEAD(&domain->devices);
- if (vm) {
+ if (flags & DOMAIN_FLAG_VIRTUAL_MACHINE)
domain->id = atomic_inc_return(&vm_domid);
- domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
- }
return domain;
}
-static int iommu_attach_domain(struct dmar_domain *domain,
- struct intel_iommu *iommu)
+static int __iommu_attach_domain(struct dmar_domain *domain,
+ struct intel_iommu *iommu)
{
int num;
unsigned long ndomains;
- unsigned long flags;
ndomains = cap_ndoms(iommu->cap);
-
- spin_lock_irqsave(&iommu->lock, flags);
-
num = find_first_zero_bit(iommu->domain_ids, ndomains);
- if (num >= ndomains) {
- spin_unlock_irqrestore(&iommu->lock, flags);
- printk(KERN_ERR "IOMMU: no free domain ids\n");
- return -ENOMEM;
+ if (num < ndomains) {
+ set_bit(num, iommu->domain_ids);
+ iommu->domains[num] = domain;
+ } else {
+ num = -ENOSPC;
}
- domain->id = num;
- domain->iommu_count++;
- set_bit(num, iommu->domain_ids);
- set_bit(iommu->seq_id, domain->iommu_bmp);
- iommu->domains[num] = domain;
+ return num;
+}
+
+static int iommu_attach_domain(struct dmar_domain *domain,
+ struct intel_iommu *iommu)
+{
+ int num;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ num = __iommu_attach_domain(domain, iommu);
spin_unlock_irqrestore(&iommu->lock, flags);
+ if (num < 0)
+ pr_err("IOMMU: no free domain ids\n");
- return 0;
+ return num;
+}
+
+static int iommu_attach_vm_domain(struct dmar_domain *domain,
+ struct intel_iommu *iommu)
+{
+ int num;
+ unsigned long ndomains;
+
+ ndomains = cap_ndoms(iommu->cap);
+ for_each_set_bit(num, iommu->domain_ids, ndomains)
+ if (iommu->domains[num] == domain)
+ return num;
+
+ return __iommu_attach_domain(domain, iommu);
}
static void iommu_detach_domain(struct dmar_domain *domain,
@@ -1558,17 +1584,53 @@ static void iommu_detach_domain(struct dmar_domain *domain,
int num, ndomains;
spin_lock_irqsave(&iommu->lock, flags);
- ndomains = cap_ndoms(iommu->cap);
- for_each_set_bit(num, iommu->domain_ids, ndomains) {
- if (iommu->domains[num] == domain) {
- clear_bit(num, iommu->domain_ids);
- iommu->domains[num] = NULL;
- break;
+ if (domain_type_is_vm_or_si(domain)) {
+ ndomains = cap_ndoms(iommu->cap);
+ for_each_set_bit(num, iommu->domain_ids, ndomains) {
+ if (iommu->domains[num] == domain) {
+ clear_bit(num, iommu->domain_ids);
+ iommu->domains[num] = NULL;
+ break;
+ }
}
+ } else {
+ clear_bit(domain->id, iommu->domain_ids);
+ iommu->domains[domain->id] = NULL;
}
spin_unlock_irqrestore(&iommu->lock, flags);
}
+static void domain_attach_iommu(struct dmar_domain *domain,
+ struct intel_iommu *iommu)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&domain->iommu_lock, flags);
+ if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
+ domain->iommu_count++;
+ if (domain->iommu_count == 1)
+ domain->nid = iommu->node;
+ domain_update_iommu_cap(domain);
+ }
+ spin_unlock_irqrestore(&domain->iommu_lock, flags);
+}
+
+static int domain_detach_iommu(struct dmar_domain *domain,
+ struct intel_iommu *iommu)
+{
+ unsigned long flags;
+ int count = INT_MAX;
+
+ spin_lock_irqsave(&domain->iommu_lock, flags);
+ if (test_and_clear_bit(iommu->seq_id, domain->iommu_bmp)) {
+ count = --domain->iommu_count;
+ domain_update_iommu_cap(domain);
+ }
+ spin_unlock_irqrestore(&domain->iommu_lock, flags);
+
+ return count;
+}
+
static struct iova_domain reserved_iova_list;
static struct lock_class_key reserved_rbtree_key;
@@ -1706,9 +1768,7 @@ static void domain_exit(struct dmar_domain *domain)
/* clear attached or cached domains */
rcu_read_lock();
for_each_active_iommu(iommu, drhd)
- if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
- test_bit(iommu->seq_id, domain->iommu_bmp))
- iommu_detach_domain(domain, iommu);
+ iommu_detach_domain(domain, iommu);
rcu_read_unlock();
dma_free_pagelist(freelist);
@@ -1723,8 +1783,6 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
struct context_entry *context;
unsigned long flags;
struct dma_pte *pgd;
- unsigned long num;
- unsigned long ndomains;
int id;
int agaw;
struct device_domain_info *info = NULL;
@@ -1748,31 +1806,14 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
id = domain->id;
pgd = domain->pgd;
- if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
- domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) {
- int found = 0;
-
- /* find an available domain id for this device in iommu */
- ndomains = cap_ndoms(iommu->cap);
- for_each_set_bit(num, iommu->domain_ids, ndomains) {
- if (iommu->domains[num] == domain) {
- id = num;
- found = 1;
- break;
- }
- }
-
- if (found == 0) {
- num = find_first_zero_bit(iommu->domain_ids, ndomains);
- if (num >= ndomains) {
+ if (domain_type_is_vm_or_si(domain)) {
+ if (domain_type_is_vm(domain)) {
+ id = iommu_attach_vm_domain(domain, iommu);
+ if (id < 0) {
spin_unlock_irqrestore(&iommu->lock, flags);
- printk(KERN_ERR "IOMMU: no free domain ids\n");
+ pr_err("IOMMU: no free domain ids\n");
return -EFAULT;
}
-
- set_bit(num, iommu->domain_ids);
- iommu->domains[num] = domain;
- id = num;
}
/* Skip top levels of page tables for
@@ -1824,72 +1865,68 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
(((u16)bus) << 8) | devfn,
DMA_CCMD_MASK_NOBIT,
DMA_CCMD_DEVICE_INVL);
- iommu->flush.flush_iotlb(iommu, domain->id, 0, 0, DMA_TLB_DSI_FLUSH);
+ iommu->flush.flush_iotlb(iommu, id, 0, 0, DMA_TLB_DSI_FLUSH);
} else {
iommu_flush_write_buffer(iommu);
}
iommu_enable_dev_iotlb(info);
spin_unlock_irqrestore(&iommu->lock, flags);
- spin_lock_irqsave(&domain->iommu_lock, flags);
- if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
- domain->iommu_count++;
- if (domain->iommu_count == 1)
- domain->nid = iommu->node;
- domain_update_iommu_cap(domain);
- }
- spin_unlock_irqrestore(&domain->iommu_lock, flags);
+ domain_attach_iommu(domain, iommu);
+
return 0;
}
+struct domain_context_mapping_data {
+ struct dmar_domain *domain;
+ struct intel_iommu *iommu;
+ int translation;
+};
+
+static int domain_context_mapping_cb(struct pci_dev *pdev,
+ u16 alias, void *opaque)
+{
+ struct domain_context_mapping_data *data = opaque;
+
+ return domain_context_mapping_one(data->domain, data->iommu,
+ PCI_BUS_NUM(alias), alias & 0xff,
+ data->translation);
+}
+
static int
domain_context_mapping(struct dmar_domain *domain, struct device *dev,
int translation)
{
- int ret;
- struct pci_dev *pdev, *tmp, *parent;
struct intel_iommu *iommu;
u8 bus, devfn;
+ struct domain_context_mapping_data data;
iommu = device_to_iommu(dev, &bus, &devfn);
if (!iommu)
return -ENODEV;
- ret = domain_context_mapping_one(domain, iommu, bus, devfn,
- translation);
- if (ret || !dev_is_pci(dev))
- return ret;
-
- /* dependent device mapping */
- pdev = to_pci_dev(dev);
- tmp = pci_find_upstream_pcie_bridge(pdev);
- if (!tmp)
- return 0;
- /* Secondary interface's bus number and devfn 0 */
- parent = pdev->bus->self;
- while (parent != tmp) {
- ret = domain_context_mapping_one(domain, iommu,
- parent->bus->number,
- parent->devfn, translation);
- if (ret)
- return ret;
- parent = parent->bus->self;
- }
- if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
- return domain_context_mapping_one(domain, iommu,
- tmp->subordinate->number, 0,
- translation);
- else /* this is a legacy PCI bridge */
- return domain_context_mapping_one(domain, iommu,
- tmp->bus->number,
- tmp->devfn,
+ if (!dev_is_pci(dev))
+ return domain_context_mapping_one(domain, iommu, bus, devfn,
translation);
+
+ data.domain = domain;
+ data.iommu = iommu;
+ data.translation = translation;
+
+ return pci_for_each_dma_alias(to_pci_dev(dev),
+ &domain_context_mapping_cb, &data);
+}
+
+static int domain_context_mapped_cb(struct pci_dev *pdev,
+ u16 alias, void *opaque)
+{
+ struct intel_iommu *iommu = opaque;
+
+ return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
}
static int domain_context_mapped(struct device *dev)
{
- int ret;
- struct pci_dev *pdev, *tmp, *parent;
struct intel_iommu *iommu;
u8 bus, devfn;
@@ -1897,30 +1934,11 @@ static int domain_context_mapped(struct device *dev)
if (!iommu)
return -ENODEV;
- ret = device_context_mapped(iommu, bus, devfn);
- if (!ret || !dev_is_pci(dev))
- return ret;
+ if (!dev_is_pci(dev))
+ return device_context_mapped(iommu, bus, devfn);
- /* dependent device mapping */
- pdev = to_pci_dev(dev);
- tmp = pci_find_upstream_pcie_bridge(pdev);
- if (!tmp)
- return ret;
- /* Secondary interface's bus number and devfn 0 */
- parent = pdev->bus->self;
- while (parent != tmp) {
- ret = device_context_mapped(iommu, parent->bus->number,
- parent->devfn);
- if (!ret)
- return ret;
- parent = parent->bus->self;
- }
- if (pci_is_pcie(tmp))
- return device_context_mapped(iommu, tmp->subordinate->number,
- 0);
- else
- return device_context_mapped(iommu, tmp->bus->number,
- tmp->devfn);
+ return !pci_for_each_dma_alias(to_pci_dev(dev),
+ domain_context_mapped_cb, iommu);
}
/* Returns a number of VTD pages, but aligned to MM page size */
@@ -1965,12 +1983,11 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
{
struct dma_pte *first_pte = NULL, *pte = NULL;
phys_addr_t uninitialized_var(pteval);
- int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
unsigned long sg_res;
unsigned int largepage_lvl = 0;
unsigned long lvl_pages = 0;
- BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width);
+ BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
return -EINVAL;
@@ -2004,12 +2021,14 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
/* It is large page*/
if (largepage_lvl > 1) {
pteval |= DMA_PTE_LARGE_PAGE;
- /* Ensure that old small page tables are removed to make room
- for superpage, if they exist. */
- dma_pte_clear_range(domain, iov_pfn,
- iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
+ lvl_pages = lvl_to_nr_pages(largepage_lvl);
+ /*
+ * Ensure that old small page tables are
+ * removed to make room for superpage,
+ * if they exist.
+ */
dma_pte_free_pagetable(domain, iov_pfn,
- iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
+ iov_pfn + lvl_pages - 1);
} else {
pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
}
@@ -2102,31 +2121,20 @@ static inline void unlink_domain_info(struct device_domain_info *info)
static void domain_remove_dev_info(struct dmar_domain *domain)
{
- struct device_domain_info *info;
- unsigned long flags, flags2;
+ struct device_domain_info *info, *tmp;
+ unsigned long flags;
spin_lock_irqsave(&device_domain_lock, flags);
- while (!list_empty(&domain->devices)) {
- info = list_entry(domain->devices.next,
- struct device_domain_info, link);
+ list_for_each_entry_safe(info, tmp, &domain->devices, link) {
unlink_domain_info(info);
spin_unlock_irqrestore(&device_domain_lock, flags);
iommu_disable_dev_iotlb(info);
iommu_detach_dev(info->iommu, info->bus, info->devfn);
- if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) {
+ if (domain_type_is_vm(domain)) {
iommu_detach_dependent_devices(info->iommu, info->dev);
- /* clear this iommu in iommu_bmp, update iommu count
- * and capabilities
- */
- spin_lock_irqsave(&domain->iommu_lock, flags2);
- if (test_and_clear_bit(info->iommu->seq_id,
- domain->iommu_bmp)) {
- domain->iommu_count--;
- domain_update_iommu_cap(domain);
- }
- spin_unlock_irqrestore(&domain->iommu_lock, flags2);
+ domain_detach_iommu(domain, info->iommu);
}
free_devinfo_mem(info);
@@ -2181,8 +2189,6 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
info->dev = dev;
info->domain = domain;
info->iommu = iommu;
- if (!dev)
- domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
spin_lock_irqsave(&device_domain_lock, flags);
if (dev)
@@ -2209,79 +2215,86 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
return domain;
}
+static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+ *(u16 *)opaque = alias;
+ return 0;
+}
+
/* domain is initialized */
static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
{
- struct dmar_domain *domain, *free = NULL;
- struct intel_iommu *iommu = NULL;
+ struct dmar_domain *domain, *tmp;
+ struct intel_iommu *iommu;
struct device_domain_info *info;
- struct pci_dev *dev_tmp = NULL;
+ u16 dma_alias;
unsigned long flags;
- u8 bus, devfn, bridge_bus, bridge_devfn;
+ u8 bus, devfn;
domain = find_domain(dev);
if (domain)
return domain;
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu)
+ return NULL;
+
if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);
- u16 segment;
- segment = pci_domain_nr(pdev->bus);
- dev_tmp = pci_find_upstream_pcie_bridge(pdev);
- if (dev_tmp) {
- if (pci_is_pcie(dev_tmp)) {
- bridge_bus = dev_tmp->subordinate->number;
- bridge_devfn = 0;
- } else {
- bridge_bus = dev_tmp->bus->number;
- bridge_devfn = dev_tmp->devfn;
- }
- spin_lock_irqsave(&device_domain_lock, flags);
- info = dmar_search_domain_by_dev_info(segment,
- bridge_bus,
- bridge_devfn);
- if (info) {
- iommu = info->iommu;
- domain = info->domain;
- }
- spin_unlock_irqrestore(&device_domain_lock, flags);
- /* pcie-pci bridge already has a domain, uses it */
- if (info)
- goto found_domain;
+ pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
+
+ spin_lock_irqsave(&device_domain_lock, flags);
+ info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
+ PCI_BUS_NUM(dma_alias),
+ dma_alias & 0xff);
+ if (info) {
+ iommu = info->iommu;
+ domain = info->domain;
}
- }
+ spin_unlock_irqrestore(&device_domain_lock, flags);
- iommu = device_to_iommu(dev, &bus, &devfn);
- if (!iommu)
- goto error;
+ /* DMA alias already has a domain, uses it */
+ if (info)
+ goto found_domain;
+ }
/* Allocate and initialize new domain for the device */
- domain = alloc_domain(false);
+ domain = alloc_domain(0);
if (!domain)
- goto error;
- if (iommu_attach_domain(domain, iommu)) {
+ return NULL;
+ domain->id = iommu_attach_domain(domain, iommu);
+ if (domain->id < 0) {
free_domain_mem(domain);
- domain = NULL;
- goto error;
+ return NULL;
}
- free = domain;
- if (domain_init(domain, gaw))
- goto error;
+ domain_attach_iommu(domain, iommu);
+ if (domain_init(domain, gaw)) {
+ domain_exit(domain);
+ return NULL;
+ }
+
+ /* register PCI DMA alias device */
+ if (dev_is_pci(dev)) {
+ tmp = dmar_insert_dev_info(iommu, PCI_BUS_NUM(dma_alias),
+ dma_alias & 0xff, NULL, domain);
+
+ if (!tmp || tmp != domain) {
+ domain_exit(domain);
+ domain = tmp;
+ }
- /* register pcie-to-pci device */
- if (dev_tmp) {
- domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
- NULL, domain);
if (!domain)
- goto error;
+ return NULL;
}
found_domain:
- domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
-error:
- if (free != domain)
- domain_exit(free);
+ tmp = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
+
+ if (!tmp || tmp != domain) {
+ domain_exit(domain);
+ domain = tmp;
+ }
return domain;
}
@@ -2405,6 +2418,7 @@ static inline void iommu_prepare_isa(void)
printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
"floppy might not work\n");
+ pci_dev_put(pdev);
}
#else
static inline void iommu_prepare_isa(void)
@@ -2420,19 +2434,25 @@ static int __init si_domain_init(int hw)
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
int nid, ret = 0;
+ bool first = true;
- si_domain = alloc_domain(false);
+ si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
if (!si_domain)
return -EFAULT;
- si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;
-
for_each_active_iommu(iommu, drhd) {
ret = iommu_attach_domain(si_domain, iommu);
- if (ret) {
+ if (ret < 0) {
+ domain_exit(si_domain);
+ return -EFAULT;
+ } else if (first) {
+ si_domain->id = ret;
+ first = false;
+ } else if (si_domain->id != ret) {
domain_exit(si_domain);
return -EFAULT;
}
+ domain_attach_iommu(si_domain, iommu);
}
if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
@@ -2523,22 +2543,46 @@ static bool device_has_rmrr(struct device *dev)
return false;
}
+/*
+ * There are a couple cases where we need to restrict the functionality of
+ * devices associated with RMRRs. The first is when evaluating a device for
+ * identity mapping because problems exist when devices are moved in and out
+ * of domains and their respective RMRR information is lost. This means that
+ * a device with associated RMRRs will never be in a "passthrough" domain.
+ * The second is use of the device through the IOMMU API. This interface
+ * expects to have full control of the IOVA space for the device. We cannot
+ * satisfy both the requirement that RMRR access is maintained and have an
+ * unencumbered IOVA space. We also have no ability to quiesce the device's
+ * use of the RMRR space or even inform the IOMMU API user of the restriction.
+ * We therefore prevent devices associated with an RMRR from participating in
+ * the IOMMU API, which eliminates them from device assignment.
+ *
+ * In both cases we assume that PCI USB devices with RMRRs have them largely
+ * for historical reasons and that the RMRR space is not actively used post
+ * boot. This exclusion may change if vendors begin to abuse it.
+ */
+static bool device_is_rmrr_locked(struct device *dev)
+{
+ if (!device_has_rmrr(dev))
+ return false;
+
+ if (dev_is_pci(dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
+ return false;
+ }
+
+ return true;
+}
+
static int iommu_should_identity_map(struct device *dev, int startup)
{
if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);
- /*
- * We want to prevent any device associated with an RMRR from
- * getting placed into the SI Domain. This is done because
- * problems exist when devices are moved in and out of domains
- * and their respective RMRR info is lost. We exempt USB devices
- * from this process due to their usage of RMRRs that are known
- * to not be needed after BIOS hand-off to OS.
- */
- if (device_has_rmrr(dev) &&
- (pdev->class >> 8) != PCI_CLASS_SERIAL_USB)
+ if (device_is_rmrr_locked(dev))
return 0;
if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
@@ -2850,11 +2894,7 @@ static int __init init_dmars(void)
iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
-
- ret = iommu_enable_translation(iommu);
- if (ret)
- goto free_iommu;
-
+ iommu_enable_translation(iommu);
iommu_disable_protect_mem_regions(iommu);
}
@@ -3091,10 +3131,10 @@ static void flush_unmaps(void)
/* On real hardware multiple invalidations are expensive */
if (cap_caching_mode(iommu->cap))
iommu_flush_iotlb_psi(iommu, domain->id,
- iova->pfn_lo, iova->pfn_hi - iova->pfn_lo + 1,
+ iova->pfn_lo, iova_size(iova),
!deferred_flush[i].freelist[j], 0);
else {
- mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1));
+ mask = ilog2(mm_to_dma_pfn(iova_size(iova)));
iommu_flush_dev_iotlb(deferred_flush[i].domain[j],
(uint64_t)iova->pfn_lo << PAGE_SHIFT, mask);
}
@@ -3144,9 +3184,7 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova, struct page *f
spin_unlock_irqrestore(&async_umap_flush_lock, flags);
}
-static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
- size_t size, enum dma_data_direction dir,
- struct dma_attrs *attrs)
+static void intel_unmap(struct device *dev, dma_addr_t dev_addr)
{
struct dmar_domain *domain;
unsigned long start_pfn, last_pfn;
@@ -3190,6 +3228,13 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
}
}
+static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ intel_unmap(dev, dev_addr);
+}
+
static void *intel_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags,
struct dma_attrs *attrs)
@@ -3246,7 +3291,7 @@ static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
size = PAGE_ALIGN(size);
order = get_order(size);
- intel_unmap_page(dev, dma_handle, size, DMA_BIDIRECTIONAL, NULL);
+ intel_unmap(dev, dma_handle);
if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
__free_pages(page, order);
}
@@ -3255,43 +3300,7 @@ static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
int nelems, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- struct dmar_domain *domain;
- unsigned long start_pfn, last_pfn;
- struct iova *iova;
- struct intel_iommu *iommu;
- struct page *freelist;
-
- if (iommu_no_mapping(dev))
- return;
-
- domain = find_domain(dev);
- BUG_ON(!domain);
-
- iommu = domain_get_iommu(domain);
-
- iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address));
- if (WARN_ONCE(!iova, "Driver unmaps unmatched sglist at PFN %llx\n",
- (unsigned long long)sglist[0].dma_address))
- return;
-
- start_pfn = mm_to_dma_pfn(iova->pfn_lo);
- last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1;
-
- freelist = domain_unmap(domain, start_pfn, last_pfn);
-
- if (intel_iommu_strict) {
- iommu_flush_iotlb_psi(iommu, domain->id, start_pfn,
- last_pfn - start_pfn + 1, !freelist, 0);
- /* free iova */
- __free_iova(&domain->iovad, iova);
- dma_free_pagelist(freelist);
- } else {
- add_unmap(domain, iova, freelist);
- /*
- * queue up the release of the unmap to save the 1/6th of the
- * cpu used up by the iotlb flush operation...
- */
- }
+ intel_unmap(dev, sglist[0].dma_address);
}
static int intel_nontranslate_map_sg(struct device *hddev,
@@ -3355,13 +3364,8 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
if (unlikely(ret)) {
- /* clear the page */
- dma_pte_clear_range(domain, start_vpfn,
- start_vpfn + size - 1);
- /* free page tables */
dma_pte_free_pagetable(domain, start_vpfn,
start_vpfn + size - 1);
- /* free iova */
__free_iova(&domain->iovad, iova);
return 0;
}
@@ -3568,10 +3572,8 @@ static int init_iommu_hw(void)
iommu->flush.flush_context(iommu, 0, 0, 0,
DMA_CCMD_GLOBAL_INVL);
- iommu->flush.flush_iotlb(iommu, 0, 0, 0,
- DMA_TLB_GLOBAL_FLUSH);
- if (iommu_enable_translation(iommu))
- return 1;
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
+ iommu_enable_translation(iommu);
iommu_disable_protect_mem_regions(iommu);
}
@@ -3873,9 +3875,7 @@ static int device_notifier(struct notifier_block *nb,
down_read(&dmar_global_lock);
domain_remove_one_dev_info(domain, dev);
- if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
- !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) &&
- list_empty(&domain->devices))
+ if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
domain_exit(domain);
up_read(&dmar_global_lock);
@@ -3935,8 +3935,7 @@ static int intel_iommu_memory_notifier(struct notifier_block *nb,
rcu_read_lock();
for_each_active_iommu(iommu, drhd)
iommu_flush_iotlb_psi(iommu, si_domain->id,
- iova->pfn_lo,
- iova->pfn_hi - iova->pfn_lo + 1,
+ iova->pfn_lo, iova_size(iova),
!freelist, 0);
rcu_read_unlock();
dma_free_pagelist(freelist);
@@ -3955,6 +3954,63 @@ static struct notifier_block intel_iommu_memory_nb = {
.priority = 0
};
+
+static ssize_t intel_iommu_show_version(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct intel_iommu *iommu = dev_get_drvdata(dev);
+ u32 ver = readl(iommu->reg + DMAR_VER_REG);
+ return sprintf(buf, "%d:%d\n",
+ DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
+}
+static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
+
+static ssize_t intel_iommu_show_address(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct intel_iommu *iommu = dev_get_drvdata(dev);
+ return sprintf(buf, "%llx\n", iommu->reg_phys);
+}
+static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
+
+static ssize_t intel_iommu_show_cap(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct intel_iommu *iommu = dev_get_drvdata(dev);
+ return sprintf(buf, "%llx\n", iommu->cap);
+}
+static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
+
+static ssize_t intel_iommu_show_ecap(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct intel_iommu *iommu = dev_get_drvdata(dev);
+ return sprintf(buf, "%llx\n", iommu->ecap);
+}
+static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
+
+static struct attribute *intel_iommu_attrs[] = {
+ &dev_attr_version.attr,
+ &dev_attr_address.attr,
+ &dev_attr_cap.attr,
+ &dev_attr_ecap.attr,
+ NULL,
+};
+
+static struct attribute_group intel_iommu_group = {
+ .name = "intel-iommu",
+ .attrs = intel_iommu_attrs,
+};
+
+const struct attribute_group *intel_iommu_groups[] = {
+ &intel_iommu_group,
+ NULL,
+};
+
int __init intel_iommu_init(void)
{
int ret = -ENODEV;
@@ -4026,6 +4082,11 @@ int __init intel_iommu_init(void)
init_iommu_pm_ops();
+ for_each_active_iommu(iommu, drhd)
+ iommu->iommu_dev = iommu_device_create(NULL, iommu,
+ intel_iommu_groups,
+ iommu->name);
+
bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
bus_register_notifier(&pci_bus_type, &device_nb);
if (si_domain && !hw_pass_through)
@@ -4044,33 +4105,27 @@ out_free_dmar:
return ret;
}
+static int iommu_detach_dev_cb(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+ struct intel_iommu *iommu = opaque;
+
+ iommu_detach_dev(iommu, PCI_BUS_NUM(alias), alias & 0xff);
+ return 0;
+}
+
+/*
+ * NB - intel-iommu lacks any sort of reference counting for the users of
+ * dependent devices. If multiple endpoints have intersecting dependent
+ * devices, unbinding the driver from any one of them will possibly leave
+ * the others unable to operate.
+ */
static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
struct device *dev)
{
- struct pci_dev *tmp, *parent, *pdev;
-
if (!iommu || !dev || !dev_is_pci(dev))
return;
- pdev = to_pci_dev(dev);
-
- /* dependent device detach */
- tmp = pci_find_upstream_pcie_bridge(pdev);
- /* Secondary interface's bus number and devfn 0 */
- if (tmp) {
- parent = pdev->bus->self;
- while (parent != tmp) {
- iommu_detach_dev(iommu, parent->bus->number,
- parent->devfn);
- parent = parent->bus->self;
- }
- if (pci_is_pcie(tmp)) /* this is a PCIe-to-PCI bridge */
- iommu_detach_dev(iommu,
- tmp->subordinate->number, 0);
- else /* this is a legacy PCI bridge */
- iommu_detach_dev(iommu, tmp->bus->number,
- tmp->devfn);
- }
+ pci_for_each_dma_alias(to_pci_dev(dev), &iommu_detach_dev_cb, iommu);
}
static void domain_remove_one_dev_info(struct dmar_domain *domain,
@@ -4117,20 +4172,9 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
spin_unlock_irqrestore(&device_domain_lock, flags);
if (found == 0) {
- unsigned long tmp_flags;
- spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
- clear_bit(iommu->seq_id, domain->iommu_bmp);
- domain->iommu_count--;
- domain_update_iommu_cap(domain);
- spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
-
- if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
- !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) {
- spin_lock_irqsave(&iommu->lock, tmp_flags);
- clear_bit(domain->id, iommu->domain_ids);
- iommu->domains[domain->id] = NULL;
- spin_unlock_irqrestore(&iommu->lock, tmp_flags);
- }
+ domain_detach_iommu(domain, iommu);
+ if (!domain_type_is_vm_or_si(domain))
+ iommu_detach_domain(domain, iommu);
}
}
@@ -4150,7 +4194,6 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
domain->iommu_snooping = 0;
domain->iommu_superpage = 0;
domain->max_addr = 0;
- domain->nid = -1;
/* always allocate the top pgd */
domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
@@ -4164,7 +4207,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
{
struct dmar_domain *dmar_domain;
- dmar_domain = alloc_domain(true);
+ dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
if (!dmar_domain) {
printk(KERN_ERR
"intel_iommu_domain_init: dmar_domain == NULL\n");
@@ -4202,14 +4245,18 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
int addr_width;
u8 bus, devfn;
+ if (device_is_rmrr_locked(dev)) {
+ dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
+ return -EPERM;
+ }
+
/* normally dev is not mapped */
if (unlikely(domain_context_mapped(dev))) {
struct dmar_domain *old_domain;
old_domain = find_domain(dev);
if (old_domain) {
- if (dmar_domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE ||
- dmar_domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)
+ if (domain_type_is_vm_or_si(dmar_domain))
domain_remove_one_dev_info(old_domain, dev);
else
domain_remove_dev_info(old_domain);
@@ -4373,99 +4420,42 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
return 0;
}
-#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
-
static int intel_iommu_add_device(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct pci_dev *bridge, *dma_pdev = NULL;
+ struct intel_iommu *iommu;
struct iommu_group *group;
- int ret;
u8 bus, devfn;
- if (!device_to_iommu(dev, &bus, &devfn))
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu)
return -ENODEV;
- bridge = pci_find_upstream_pcie_bridge(pdev);
- if (bridge) {
- if (pci_is_pcie(bridge))
- dma_pdev = pci_get_domain_bus_and_slot(
- pci_domain_nr(pdev->bus),
- bridge->subordinate->number, 0);
- if (!dma_pdev)
- dma_pdev = pci_dev_get(bridge);
- } else
- dma_pdev = pci_dev_get(pdev);
-
- /* Account for quirked devices */
- swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev));
+ iommu_device_link(iommu->iommu_dev, dev);
- /*
- * If it's a multifunction device that does not support our
- * required ACS flags, add to the same group as lowest numbered
- * function that also does not suport the required ACS flags.
- */
- if (dma_pdev->multifunction &&
- !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
- u8 i, slot = PCI_SLOT(dma_pdev->devfn);
-
- for (i = 0; i < 8; i++) {
- struct pci_dev *tmp;
+ group = iommu_group_get_for_dev(dev);
- tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
- if (!tmp)
- continue;
-
- if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
- swap_pci_ref(&dma_pdev, tmp);
- break;
- }
- pci_dev_put(tmp);
- }
- }
-
- /*
- * Devices on the root bus go through the iommu. If that's not us,
- * find the next upstream device and test ACS up to the root bus.
- * Finding the next device may require skipping virtual buses.
- */
- while (!pci_is_root_bus(dma_pdev->bus)) {
- struct pci_bus *bus = dma_pdev->bus;
-
- while (!bus->self) {
- if (!pci_is_root_bus(bus))
- bus = bus->parent;
- else
- goto root_bus;
- }
-
- if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
- break;
-
- swap_pci_ref(&dma_pdev, pci_dev_get(bus->self));
- }
-
-root_bus:
- group = iommu_group_get(&dma_pdev->dev);
- pci_dev_put(dma_pdev);
- if (!group) {
- group = iommu_group_alloc();
- if (IS_ERR(group))
- return PTR_ERR(group);
- }
-
- ret = iommu_group_add_device(group, dev);
+ if (IS_ERR(group))
+ return PTR_ERR(group);
iommu_group_put(group);
- return ret;
+ return 0;
}
static void intel_iommu_remove_device(struct device *dev)
{
+ struct intel_iommu *iommu;
+ u8 bus, devfn;
+
+ iommu = device_to_iommu(dev, &bus, &devfn);
+ if (!iommu)
+ return;
+
iommu_group_remove_device(dev);
+
+ iommu_device_unlink(iommu->iommu_dev, dev);
}
-static struct iommu_ops intel_iommu_ops = {
+static const struct iommu_ops intel_iommu_ops = {
.domain_init = intel_iommu_domain_init,
.domain_destroy = intel_iommu_domain_destroy,
.attach_dev = intel_iommu_attach_device,
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index 9b174893f0f5..0df41f6264f5 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -70,6 +70,11 @@ static int get_irte(int irq, struct irte *entry)
raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
+ if (unlikely(!irq_iommu->iommu)) {
+ raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
+ return -1;
+ }
+
index = irq_iommu->irte_index + irq_iommu->sub_handle;
*entry = *(irq_iommu->iommu->ir_table->base + index);
@@ -369,29 +374,52 @@ static int set_hpet_sid(struct irte *irte, u8 id)
return 0;
}
+struct set_msi_sid_data {
+ struct pci_dev *pdev;
+ u16 alias;
+};
+
+static int set_msi_sid_cb(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+ struct set_msi_sid_data *data = opaque;
+
+ data->pdev = pdev;
+ data->alias = alias;
+
+ return 0;
+}
+
static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
{
- struct pci_dev *bridge;
+ struct set_msi_sid_data data;
if (!irte || !dev)
return -1;
- /* PCIe device or Root Complex integrated PCI device */
- if (pci_is_pcie(dev) || !dev->bus->parent) {
- set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
- (dev->bus->number << 8) | dev->devfn);
- return 0;
- }
+ pci_for_each_dma_alias(dev, set_msi_sid_cb, &data);
- bridge = pci_find_upstream_pcie_bridge(dev);
- if (bridge) {
- if (pci_is_pcie(bridge))/* this is a PCIe-to-PCI/PCIX bridge */
- set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
- (bridge->bus->number << 8) | dev->bus->number);
- else /* this is a legacy PCI bridge */
- set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
- (bridge->bus->number << 8) | bridge->devfn);
- }
+ /*
+ * DMA alias provides us with a PCI device and alias. The only case
+ * where the it will return an alias on a different bus than the
+ * device is the case of a PCIe-to-PCI bridge, where the alias is for
+ * the subordinate bus. In this case we can only verify the bus.
+ *
+ * If the alias device is on a different bus than our source device
+ * then we have a topology based alias, use it.
+ *
+ * Otherwise, the alias is for a device DMA quirk and we cannot
+ * assume that MSI uses the same requester ID. Therefore use the
+ * original device.
+ */
+ if (PCI_BUS_NUM(data.alias) != data.pdev->bus->number)
+ set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16,
+ PCI_DEVID(PCI_BUS_NUM(data.alias),
+ dev->bus->number));
+ else if (data.pdev->bus->number != dev->bus->number)
+ set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, data.alias);
+ else
+ set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16,
+ PCI_DEVID(dev->bus->number, dev->devfn));
return 0;
}
diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c
new file mode 100644
index 000000000000..39b2d9127dbf
--- /dev/null
+++ b/drivers/iommu/iommu-sysfs.c
@@ -0,0 +1,134 @@
+/*
+ * IOMMU sysfs class support
+ *
+ * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+ * Author: Alex Williamson <alex.williamson@redhat.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.
+ */
+
+#include <linux/device.h>
+#include <linux/iommu.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/*
+ * We provide a common class "devices" group which initially has no attributes.
+ * As devices are added to the IOMMU, we'll add links to the group.
+ */
+static struct attribute *devices_attr[] = {
+ NULL,
+};
+
+static const struct attribute_group iommu_devices_attr_group = {
+ .name = "devices",
+ .attrs = devices_attr,
+};
+
+static const struct attribute_group *iommu_dev_groups[] = {
+ &iommu_devices_attr_group,
+ NULL,
+};
+
+static void iommu_release_device(struct device *dev)
+{
+ kfree(dev);
+}
+
+static struct class iommu_class = {
+ .name = "iommu",
+ .dev_release = iommu_release_device,
+ .dev_groups = iommu_dev_groups,
+};
+
+static int __init iommu_dev_init(void)
+{
+ return class_register(&iommu_class);
+}
+postcore_initcall(iommu_dev_init);
+
+/*
+ * Create an IOMMU device and return a pointer to it. IOMMU specific
+ * attributes can be provided as an attribute group, allowing a unique
+ * namespace per IOMMU type.
+ */
+struct device *iommu_device_create(struct device *parent, void *drvdata,
+ const struct attribute_group **groups,
+ const char *fmt, ...)
+{
+ struct device *dev;
+ va_list vargs;
+ int ret;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ device_initialize(dev);
+
+ dev->class = &iommu_class;
+ dev->parent = parent;
+ dev->groups = groups;
+ dev_set_drvdata(dev, drvdata);
+
+ va_start(vargs, fmt);
+ ret = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
+ va_end(vargs);
+ if (ret)
+ goto error;
+
+ ret = device_add(dev);
+ if (ret)
+ goto error;
+
+ return dev;
+
+error:
+ put_device(dev);
+ return ERR_PTR(ret);
+}
+
+void iommu_device_destroy(struct device *dev)
+{
+ if (!dev || IS_ERR(dev))
+ return;
+
+ device_unregister(dev);
+}
+
+/*
+ * IOMMU drivers can indicate a device is managed by a given IOMMU using
+ * this interface. A link to the device will be created in the "devices"
+ * directory of the IOMMU device in sysfs and an "iommu" link will be
+ * created under the linked device, pointing back at the IOMMU device.
+ */
+int iommu_device_link(struct device *dev, struct device *link)
+{
+ int ret;
+
+ if (!dev || IS_ERR(dev))
+ return -ENODEV;
+
+ ret = sysfs_add_link_to_group(&dev->kobj, "devices",
+ &link->kobj, dev_name(link));
+ if (ret)
+ return ret;
+
+ ret = sysfs_create_link_nowarn(&link->kobj, &dev->kobj, "iommu");
+ if (ret)
+ sysfs_remove_link_from_group(&dev->kobj, "devices",
+ dev_name(link));
+
+ return ret;
+}
+
+void iommu_device_unlink(struct device *dev, struct device *link)
+{
+ if (!dev || IS_ERR(dev))
+ return;
+
+ sysfs_remove_link(&link->kobj, "iommu");
+ sysfs_remove_link_from_group(&dev->kobj, "devices", dev_name(link));
+}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index e5555fcfe703..169836020208 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -29,12 +29,17 @@
#include <linux/idr.h>
#include <linux/notifier.h>
#include <linux/err.h>
+#include <linux/pci.h>
#include <trace/events/iommu.h>
static struct kset *iommu_group_kset;
static struct ida iommu_group_ida;
static struct mutex iommu_group_mutex;
+struct iommu_callback_data {
+ const struct iommu_ops *ops;
+};
+
struct iommu_group {
struct kobject kobj;
struct kobject *devices_kobj;
@@ -514,9 +519,191 @@ int iommu_group_id(struct iommu_group *group)
}
EXPORT_SYMBOL_GPL(iommu_group_id);
+/*
+ * To consider a PCI device isolated, we require ACS to support Source
+ * Validation, Request Redirection, Completer Redirection, and Upstream
+ * Forwarding. This effectively means that devices cannot spoof their
+ * requester ID, requests and completions cannot be redirected, and all
+ * transactions are forwarded upstream, even as it passes through a
+ * bridge where the target device is downstream.
+ */
+#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
+
+struct group_for_pci_data {
+ struct pci_dev *pdev;
+ struct iommu_group *group;
+};
+
+/*
+ * DMA alias iterator callback, return the last seen device. Stop and return
+ * the IOMMU group if we find one along the way.
+ */
+static int get_pci_alias_or_group(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+ struct group_for_pci_data *data = opaque;
+
+ data->pdev = pdev;
+ data->group = iommu_group_get(&pdev->dev);
+
+ return data->group != NULL;
+}
+
+/*
+ * Use standard PCI bus topology, isolation features, and DMA alias quirks
+ * to find or create an IOMMU group for a device.
+ */
+static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)
+{
+ struct group_for_pci_data data;
+ struct pci_bus *bus;
+ struct iommu_group *group = NULL;
+ struct pci_dev *tmp;
+
+ /*
+ * Find the upstream DMA alias for the device. A device must not
+ * be aliased due to topology in order to have its own IOMMU group.
+ * If we find an alias along the way that already belongs to a
+ * group, use it.
+ */
+ if (pci_for_each_dma_alias(pdev, get_pci_alias_or_group, &data))
+ return data.group;
+
+ pdev = data.pdev;
+
+ /*
+ * Continue upstream from the point of minimum IOMMU granularity
+ * due to aliases to the point where devices are protected from
+ * peer-to-peer DMA by PCI ACS. Again, if we find an existing
+ * group, use it.
+ */
+ for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
+ if (!bus->self)
+ continue;
+
+ if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
+ break;
+
+ pdev = bus->self;
+
+ group = iommu_group_get(&pdev->dev);
+ if (group)
+ return group;
+ }
+
+ /*
+ * Next we need to consider DMA alias quirks. If one device aliases
+ * to another, they should be grouped together. It's theoretically
+ * possible that aliases could create chains of devices where each
+ * device aliases another device. If we then factor in multifunction
+ * ACS grouping requirements, each alias could incorporate a new slot
+ * with multiple functions, each with aliases. This is all extremely
+ * unlikely as DMA alias quirks are typically only used for PCIe
+ * devices where we usually have a single slot per bus. Furthermore,
+ * the alias quirk is usually to another function within the slot
+ * (and ACS multifunction is not supported) or to a different slot
+ * that doesn't physically exist. The likely scenario is therefore
+ * that everything on the bus gets grouped together. To reduce the
+ * problem space, share the IOMMU group for all devices on the bus
+ * if a DMA alias quirk is present on the bus.
+ */
+ tmp = NULL;
+ for_each_pci_dev(tmp) {
+ if (tmp->bus != pdev->bus ||
+ !(tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN))
+ continue;
+
+ pci_dev_put(tmp);
+ tmp = NULL;
+
+ /* We have an alias quirk, search for an existing group */
+ for_each_pci_dev(tmp) {
+ struct iommu_group *group_tmp;
+
+ if (tmp->bus != pdev->bus)
+ continue;
+
+ group_tmp = iommu_group_get(&tmp->dev);
+ if (!group) {
+ group = group_tmp;
+ continue;
+ }
+
+ if (group_tmp) {
+ WARN_ON(group != group_tmp);
+ iommu_group_put(group_tmp);
+ }
+ }
+
+ return group ? group : iommu_group_alloc();
+ }
+
+ /*
+ * Non-multifunction devices or multifunction devices supporting
+ * ACS get their own group.
+ */
+ if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS))
+ return iommu_group_alloc();
+
+ /*
+ * Multifunction devices not supporting ACS share a group with other
+ * similar devices in the same slot.
+ */
+ tmp = NULL;
+ for_each_pci_dev(tmp) {
+ if (tmp == pdev || tmp->bus != pdev->bus ||
+ PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) ||
+ pci_acs_enabled(tmp, REQ_ACS_FLAGS))
+ continue;
+
+ group = iommu_group_get(&tmp->dev);
+ if (group) {
+ pci_dev_put(tmp);
+ return group;
+ }
+ }
+
+ /* No shared group found, allocate new */
+ return iommu_group_alloc();
+}
+
+/**
+ * iommu_group_get_for_dev - Find or create the IOMMU group for a device
+ * @dev: target device
+ *
+ * This function is intended to be called by IOMMU drivers and extended to
+ * support common, bus-defined algorithms when determining or creating the
+ * IOMMU group for a device. On success, the caller will hold a reference
+ * to the returned IOMMU group, which will already include the provided
+ * device. The reference should be released with iommu_group_put().
+ */
+struct iommu_group *iommu_group_get_for_dev(struct device *dev)
+{
+ struct iommu_group *group = ERR_PTR(-EIO);
+ int ret;
+
+ group = iommu_group_get(dev);
+ if (group)
+ return group;
+
+ if (dev_is_pci(dev))
+ group = iommu_group_get_for_pci_dev(to_pci_dev(dev));
+
+ if (IS_ERR(group))
+ return group;
+
+ ret = iommu_group_add_device(group, dev);
+ if (ret) {
+ iommu_group_put(group);
+ return ERR_PTR(ret);
+ }
+
+ return group;
+}
+
static int add_iommu_group(struct device *dev, void *data)
{
- struct iommu_ops *ops = data;
+ struct iommu_callback_data *cb = data;
+ const struct iommu_ops *ops = cb->ops;
if (!ops->add_device)
return -ENODEV;
@@ -532,7 +719,7 @@ static int iommu_bus_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
- struct iommu_ops *ops = dev->bus->iommu_ops;
+ const struct iommu_ops *ops = dev->bus->iommu_ops;
struct iommu_group *group;
unsigned long group_action = 0;
@@ -585,10 +772,14 @@ static struct notifier_block iommu_bus_nb = {
.notifier_call = iommu_bus_notifier,
};
-static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops)
+static void iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
{
+ struct iommu_callback_data cb = {
+ .ops = ops,
+ };
+
bus_register_notifier(bus, &iommu_bus_nb);
- bus_for_each_dev(bus, NULL, ops, add_iommu_group);
+ bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
}
/**
@@ -604,7 +795,7 @@ static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops)
* is set up. With this function the iommu-driver can set the iommu-ops
* afterwards.
*/
-int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops)
+int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops)
{
if (bus->iommu_ops != NULL)
return -EBUSY;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 53cde086e83b..7dab5cbcc775 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -1120,7 +1120,7 @@ static void ipmmu_remove_device(struct device *dev)
dev->archdata.iommu = NULL;
}
-static struct iommu_ops ipmmu_ops = {
+static const struct iommu_ops ipmmu_ops = {
.domain_init = ipmmu_domain_init,
.domain_destroy = ipmmu_domain_destroy,
.attach_dev = ipmmu_attach_device,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index f5ff657f49fa..49f41d6e02f1 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -674,7 +674,7 @@ fail:
return 0;
}
-static struct iommu_ops msm_iommu_ops = {
+static const struct iommu_ops msm_iommu_ops = {
.domain_init = msm_iommu_domain_init,
.domain_destroy = msm_iommu_domain_destroy,
.attach_dev = msm_iommu_attach_dev,
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 80fffba7f12d..531658d17333 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -213,116 +213,6 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
return bytes;
}
-static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = file->private_data;
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- char *p, *buf;
- struct iovm_struct *tmp;
- int uninitialized_var(i);
- ssize_t bytes;
-
- buf = (char *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- p = buf;
-
- p += sprintf(p, "%-3s %-8s %-8s %6s %8s\n",
- "No", "start", "end", "size", "flags");
- p += sprintf(p, "-------------------------------------------------\n");
-
- mutex_lock(&iommu_debug_lock);
-
- list_for_each_entry(tmp, &obj->mmap, list) {
- size_t len;
- const char *str = "%3d %08x-%08x %6x %8x\n";
- const int maxcol = 39;
-
- len = tmp->da_end - tmp->da_start;
- p += snprintf(p, maxcol, str,
- i, tmp->da_start, tmp->da_end, len, tmp->flags);
-
- if (PAGE_SIZE - (p - buf) < maxcol)
- break;
- i++;
- }
-
- bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-
- mutex_unlock(&iommu_debug_lock);
- free_page((unsigned long)buf);
-
- return bytes;
-}
-
-static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = file->private_data;
- char *p, *buf;
- struct iovm_struct *area;
- ssize_t bytes;
-
- count = min_t(ssize_t, count, PAGE_SIZE);
-
- buf = (char *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- p = buf;
-
- mutex_lock(&iommu_debug_lock);
-
- area = omap_find_iovm_area(dev, (u32)ppos);
- if (!area) {
- bytes = -EINVAL;
- goto err_out;
- }
- memcpy(p, area->va, count);
- p += count;
-
- bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
-err_out:
- mutex_unlock(&iommu_debug_lock);
- free_page((unsigned long)buf);
-
- return bytes;
-}
-
-static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = file->private_data;
- struct iovm_struct *area;
- char *p, *buf;
-
- count = min_t(size_t, count, PAGE_SIZE);
-
- buf = (char *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- p = buf;
-
- mutex_lock(&iommu_debug_lock);
-
- if (copy_from_user(p, userbuf, count)) {
- count = -EFAULT;
- goto err_out;
- }
-
- area = omap_find_iovm_area(dev, (u32)ppos);
- if (!area) {
- count = -EINVAL;
- goto err_out;
- }
- memcpy(area->va, p, count);
-err_out:
- mutex_unlock(&iommu_debug_lock);
- free_page((unsigned long)buf);
-
- return count;
-}
-
#define DEBUG_FOPS(name) \
static const struct file_operations debug_##name##_fops = { \
.open = simple_open, \
@@ -342,8 +232,6 @@ DEBUG_FOPS_RO(ver);
DEBUG_FOPS_RO(regs);
DEBUG_FOPS_RO(tlb);
DEBUG_FOPS(pagetable);
-DEBUG_FOPS_RO(mmap);
-DEBUG_FOPS(mem);
#define __DEBUG_ADD_FILE(attr, mode) \
{ \
@@ -389,8 +277,6 @@ static int iommu_debug_register(struct device *dev, void *data)
DEBUG_ADD_FILE_RO(regs);
DEBUG_ADD_FILE_RO(tlb);
DEBUG_ADD_FILE(pagetable);
- DEBUG_ADD_FILE_RO(mmap);
- DEBUG_ADD_FILE(mem);
return 0;
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 895af06a667f..e202b0c24120 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -959,31 +959,18 @@ static int omap_iommu_probe(struct platform_device *pdev)
return err;
if (obj->nr_tlb_entries != 32 && obj->nr_tlb_entries != 8)
return -EINVAL;
- /*
- * da_start and da_end are needed for omap-iovmm, so hardcode
- * these values as used by OMAP3 ISP - the only user for
- * omap-iovmm
- */
- obj->da_start = 0;
- obj->da_end = 0xfffff000;
if (of_find_property(of, "ti,iommu-bus-err-back", NULL))
obj->has_bus_err_back = MMU_GP_REG_BUS_ERR_BACK_EN;
} else {
obj->nr_tlb_entries = pdata->nr_tlb_entries;
obj->name = pdata->name;
- obj->da_start = pdata->da_start;
- obj->da_end = pdata->da_end;
}
- if (obj->da_end <= obj->da_start)
- return -EINVAL;
obj->dev = &pdev->dev;
obj->ctx = (void *)obj + sizeof(*obj);
spin_lock_init(&obj->iommu_lock);
- mutex_init(&obj->mmap_lock);
spin_lock_init(&obj->page_table_lock);
- INIT_LIST_HEAD(&obj->mmap);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
obj->regbase = devm_ioremap_resource(obj->dev, res);
@@ -1291,7 +1278,7 @@ static void omap_iommu_remove_device(struct device *dev)
kfree(arch_data);
}
-static struct iommu_ops omap_iommu_ops = {
+static const struct iommu_ops omap_iommu_ops = {
.domain_init = omap_iommu_domain_init,
.domain_destroy = omap_iommu_domain_destroy,
.attach_dev = omap_iommu_attach_dev,
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h
index ea920c3e94ff..1275a822934b 100644
--- a/drivers/iommu/omap-iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -46,12 +46,7 @@ struct omap_iommu {
int nr_tlb_entries;
- struct list_head mmap;
- struct mutex mmap_lock; /* protect mmap */
-
void *ctx; /* iommu context: registres saved area */
- u32 da_start;
- u32 da_end;
int has_bus_err_back;
};
@@ -154,9 +149,12 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
#define MMU_RAM_PADDR_MASK \
((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
+#define MMU_RAM_ENDIAN_SHIFT 9
#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ELSZ_SHIFT 7
#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c
deleted file mode 100644
index d14725984153..000000000000
--- a/drivers/iommu/omap-iovmm.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * omap iommu: simple virtual address space management
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.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.
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/scatterlist.h>
-#include <linux/iommu.h>
-#include <linux/omap-iommu.h>
-#include <linux/platform_data/iommu-omap.h>
-
-#include <asm/cacheflush.h>
-#include <asm/mach/map.h>
-
-#include "omap-iopgtable.h"
-#include "omap-iommu.h"
-
-/*
- * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
- *
- * lower 16 bit is used for h/w and upper 16 bit is for s/w.
- */
-#define IOVMF_SW_SHIFT 16
-
-/*
- * iovma: h/w flags derived from cam and ram attribute
- */
-#define IOVMF_CAM_MASK (~((1 << 10) - 1))
-#define IOVMF_RAM_MASK (~IOVMF_CAM_MASK)
-
-#define IOVMF_PGSZ_MASK (3 << 0)
-#define IOVMF_PGSZ_1M MMU_CAM_PGSZ_1M
-#define IOVMF_PGSZ_64K MMU_CAM_PGSZ_64K
-#define IOVMF_PGSZ_4K MMU_CAM_PGSZ_4K
-#define IOVMF_PGSZ_16M MMU_CAM_PGSZ_16M
-
-#define IOVMF_ENDIAN_MASK (1 << 9)
-#define IOVMF_ENDIAN_BIG MMU_RAM_ENDIAN_BIG
-
-#define IOVMF_ELSZ_MASK (3 << 7)
-#define IOVMF_ELSZ_16 MMU_RAM_ELSZ_16
-#define IOVMF_ELSZ_32 MMU_RAM_ELSZ_32
-#define IOVMF_ELSZ_NONE MMU_RAM_ELSZ_NONE
-
-#define IOVMF_MIXED_MASK (1 << 6)
-#define IOVMF_MIXED MMU_RAM_MIXED
-
-/*
- * iovma: s/w flags, used for mapping and umapping internally.
- */
-#define IOVMF_MMIO (1 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC (2 << IOVMF_SW_SHIFT)
-#define IOVMF_ALLOC_MASK (3 << IOVMF_SW_SHIFT)
-
-/* "superpages" is supported just with physically linear pages */
-#define IOVMF_DISCONT (1 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR (2 << (2 + IOVMF_SW_SHIFT))
-#define IOVMF_LINEAR_MASK (3 << (2 + IOVMF_SW_SHIFT))
-
-#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
-
-static struct kmem_cache *iovm_area_cachep;
-
-/* return the offset of the first scatterlist entry in a sg table */
-static unsigned int sgtable_offset(const struct sg_table *sgt)
-{
- if (!sgt || !sgt->nents)
- return 0;
-
- return sgt->sgl->offset;
-}
-
-/* return total bytes of sg buffers */
-static size_t sgtable_len(const struct sg_table *sgt)
-{
- unsigned int i, total = 0;
- struct scatterlist *sg;
-
- if (!sgt)
- return 0;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes;
-
- bytes = sg->length + sg->offset;
-
- if (!iopgsz_ok(bytes)) {
- pr_err("%s: sg[%d] not iommu pagesize(%u %u)\n",
- __func__, i, bytes, sg->offset);
- return 0;
- }
-
- if (i && sg->offset) {
- pr_err("%s: sg[%d] offset not allowed in internal entries\n",
- __func__, i);
- return 0;
- }
-
- total += bytes;
- }
-
- return total;
-}
-#define sgtable_ok(x) (!!sgtable_len(x))
-
-static unsigned max_alignment(u32 addr)
-{
- int i;
- unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
- for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++)
- ;
- return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0;
-}
-
-/*
- * calculate the optimal number sg elements from total bytes based on
- * iommu superpages
- */
-static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa)
-{
- unsigned nr_entries = 0, ent_sz;
-
- if (!IS_ALIGNED(bytes, PAGE_SIZE)) {
- pr_err("%s: wrong size %08x\n", __func__, bytes);
- return 0;
- }
-
- while (bytes) {
- ent_sz = max_alignment(da | pa);
- ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes));
- nr_entries++;
- da += ent_sz;
- pa += ent_sz;
- bytes -= ent_sz;
- }
-
- return nr_entries;
-}
-
-/* allocate and initialize sg_table header(a kind of 'superblock') */
-static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags,
- u32 da, u32 pa)
-{
- unsigned int nr_entries;
- int err;
- struct sg_table *sgt;
-
- if (!bytes)
- return ERR_PTR(-EINVAL);
-
- if (!IS_ALIGNED(bytes, PAGE_SIZE))
- return ERR_PTR(-EINVAL);
-
- if (flags & IOVMF_LINEAR) {
- nr_entries = sgtable_nents(bytes, da, pa);
- if (!nr_entries)
- return ERR_PTR(-EINVAL);
- } else
- nr_entries = bytes / PAGE_SIZE;
-
- sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
- if (!sgt)
- return ERR_PTR(-ENOMEM);
-
- err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
- if (err) {
- kfree(sgt);
- return ERR_PTR(err);
- }
-
- pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries);
-
- return sgt;
-}
-
-/* free sg_table header(a kind of superblock) */
-static void sgtable_free(struct sg_table *sgt)
-{
- if (!sgt)
- return;
-
- sg_free_table(sgt);
- kfree(sgt);
-
- pr_debug("%s: sgt:%p\n", __func__, sgt);
-}
-
-/* map 'sglist' to a contiguous mpu virtual area and return 'va' */
-static void *vmap_sg(const struct sg_table *sgt)
-{
- u32 va;
- size_t total;
- unsigned int i;
- struct scatterlist *sg;
- struct vm_struct *new;
- const struct mem_type *mtype;
-
- mtype = get_mem_type(MT_DEVICE);
- if (!mtype)
- return ERR_PTR(-EINVAL);
-
- total = sgtable_len(sgt);
- if (!total)
- return ERR_PTR(-EINVAL);
-
- new = __get_vm_area(total, VM_IOREMAP, VMALLOC_START, VMALLOC_END);
- if (!new)
- return ERR_PTR(-ENOMEM);
- va = (u32)new->addr;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes;
- u32 pa;
- int err;
-
- pa = sg_phys(sg) - sg->offset;
- bytes = sg->length + sg->offset;
-
- BUG_ON(bytes != PAGE_SIZE);
-
- err = ioremap_page(va, pa, mtype);
- if (err)
- goto err_out;
-
- va += bytes;
- }
-
- flush_cache_vmap((unsigned long)new->addr,
- (unsigned long)(new->addr + total));
- return new->addr;
-
-err_out:
- WARN_ON(1); /* FIXME: cleanup some mpu mappings */
- vunmap(new->addr);
- return ERR_PTR(-EAGAIN);
-}
-
-static inline void vunmap_sg(const void *va)
-{
- vunmap(va);
-}
-
-static struct iovm_struct *__find_iovm_area(struct omap_iommu *obj,
- const u32 da)
-{
- struct iovm_struct *tmp;
-
- list_for_each_entry(tmp, &obj->mmap, list) {
- if ((da >= tmp->da_start) && (da < tmp->da_end)) {
- size_t len;
-
- len = tmp->da_end - tmp->da_start;
-
- dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n",
- __func__, tmp->da_start, da, tmp->da_end, len,
- tmp->flags);
-
- return tmp;
- }
- }
-
- return NULL;
-}
-
-/**
- * omap_find_iovm_area - find iovma which includes @da
- * @dev: client device
- * @da: iommu device virtual address
- *
- * Find the existing iovma starting at @da
- */
-struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- struct iovm_struct *area;
-
- mutex_lock(&obj->mmap_lock);
- area = __find_iovm_area(obj, da);
- mutex_unlock(&obj->mmap_lock);
-
- return area;
-}
-EXPORT_SYMBOL_GPL(omap_find_iovm_area);
-
-/*
- * This finds the hole(area) which fits the requested address and len
- * in iovmas mmap, and returns the new allocated iovma.
- */
-static struct iovm_struct *alloc_iovm_area(struct omap_iommu *obj, u32 da,
- size_t bytes, u32 flags)
-{
- struct iovm_struct *new, *tmp;
- u32 start, prev_end, alignment;
-
- if (!obj || !bytes)
- return ERR_PTR(-EINVAL);
-
- start = da;
- alignment = PAGE_SIZE;
-
- if (~flags & IOVMF_DA_FIXED) {
- /* Don't map address 0 */
- start = obj->da_start ? obj->da_start : alignment;
-
- if (flags & IOVMF_LINEAR)
- alignment = iopgsz_max(bytes);
- start = roundup(start, alignment);
- } else if (start < obj->da_start || start > obj->da_end ||
- obj->da_end - start < bytes) {
- return ERR_PTR(-EINVAL);
- }
-
- tmp = NULL;
- if (list_empty(&obj->mmap))
- goto found;
-
- prev_end = 0;
- list_for_each_entry(tmp, &obj->mmap, list) {
-
- if (prev_end > start)
- break;
-
- if (tmp->da_start > start && (tmp->da_start - start) >= bytes)
- goto found;
-
- if (tmp->da_end >= start && ~flags & IOVMF_DA_FIXED)
- start = roundup(tmp->da_end + 1, alignment);
-
- prev_end = tmp->da_end;
- }
-
- if ((start >= prev_end) && (obj->da_end - start >= bytes))
- goto found;
-
- dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n",
- __func__, da, bytes, flags);
-
- return ERR_PTR(-EINVAL);
-
-found:
- new = kmem_cache_zalloc(iovm_area_cachep, GFP_KERNEL);
- if (!new)
- return ERR_PTR(-ENOMEM);
-
- new->iommu = obj;
- new->da_start = start;
- new->da_end = start + bytes;
- new->flags = flags;
-
- /*
- * keep ascending order of iovmas
- */
- if (tmp)
- list_add_tail(&new->list, &tmp->list);
- else
- list_add(&new->list, &obj->mmap);
-
- dev_dbg(obj->dev, "%s: found %08x-%08x-%08x(%x) %08x\n",
- __func__, new->da_start, start, new->da_end, bytes, flags);
-
- return new;
-}
-
-static void free_iovm_area(struct omap_iommu *obj, struct iovm_struct *area)
-{
- size_t bytes;
-
- BUG_ON(!obj || !area);
-
- bytes = area->da_end - area->da_start;
-
- dev_dbg(obj->dev, "%s: %08x-%08x(%x) %08x\n",
- __func__, area->da_start, area->da_end, bytes, area->flags);
-
- list_del(&area->list);
- kmem_cache_free(iovm_area_cachep, area);
-}
-
-/**
- * omap_da_to_va - convert (d) to (v)
- * @dev: client device
- * @da: iommu device virtual address
- * @va: mpu virtual address
- *
- * Returns mpu virtual addr which corresponds to a given device virtual addr
- */
-void *omap_da_to_va(struct device *dev, u32 da)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- void *va = NULL;
- struct iovm_struct *area;
-
- mutex_lock(&obj->mmap_lock);
-
- area = __find_iovm_area(obj, da);
- if (!area) {
- dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
- goto out;
- }
- va = area->va;
-out:
- mutex_unlock(&obj->mmap_lock);
-
- return va;
-}
-EXPORT_SYMBOL_GPL(omap_da_to_va);
-
-static void sgtable_fill_vmalloc(struct sg_table *sgt, void *_va)
-{
- unsigned int i;
- struct scatterlist *sg;
- void *va = _va;
- void *va_end;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- struct page *pg;
- const size_t bytes = PAGE_SIZE;
-
- /*
- * iommu 'superpage' isn't supported with 'omap_iommu_vmalloc()'
- */
- pg = vmalloc_to_page(va);
- BUG_ON(!pg);
- sg_set_page(sg, pg, bytes, 0);
-
- va += bytes;
- }
-
- va_end = _va + PAGE_SIZE * i;
-}
-
-static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
-{
- /*
- * Actually this is not necessary at all, just exists for
- * consistency of the code readability.
- */
- BUG_ON(!sgt);
-}
-
-/* create 'da' <-> 'pa' mapping from 'sgt' */
-static int map_iovm_area(struct iommu_domain *domain, struct iovm_struct *new,
- const struct sg_table *sgt, u32 flags)
-{
- int err;
- unsigned int i, j;
- struct scatterlist *sg;
- u32 da = new->da_start;
-
- if (!domain || !sgt)
- return -EINVAL;
-
- BUG_ON(!sgtable_ok(sgt));
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- u32 pa;
- size_t bytes;
-
- pa = sg_phys(sg) - sg->offset;
- bytes = sg->length + sg->offset;
-
- flags &= ~IOVMF_PGSZ_MASK;
-
- if (bytes_to_iopgsz(bytes) < 0)
- goto err_out;
-
- pr_debug("%s: [%d] %08x %08x(%x)\n", __func__,
- i, da, pa, bytes);
-
- err = iommu_map(domain, da, pa, bytes, flags);
- if (err)
- goto err_out;
-
- da += bytes;
- }
- return 0;
-
-err_out:
- da = new->da_start;
-
- for_each_sg(sgt->sgl, sg, i, j) {
- size_t bytes;
-
- bytes = sg->length + sg->offset;
-
- /* ignore failures.. we're already handling one */
- iommu_unmap(domain, da, bytes);
-
- da += bytes;
- }
- return err;
-}
-
-/* release 'da' <-> 'pa' mapping */
-static void unmap_iovm_area(struct iommu_domain *domain, struct omap_iommu *obj,
- struct iovm_struct *area)
-{
- u32 start;
- size_t total = area->da_end - area->da_start;
- const struct sg_table *sgt = area->sgt;
- struct scatterlist *sg;
- int i;
- size_t unmapped;
-
- BUG_ON(!sgtable_ok(sgt));
- BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE));
-
- start = area->da_start;
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes;
-
- bytes = sg->length + sg->offset;
-
- unmapped = iommu_unmap(domain, start, bytes);
- if (unmapped < bytes)
- break;
-
- dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n",
- __func__, start, bytes, area->flags);
-
- BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE));
-
- total -= bytes;
- start += bytes;
- }
- BUG_ON(total);
-}
-
-/* template function for all unmapping */
-static struct sg_table *unmap_vm_area(struct iommu_domain *domain,
- struct omap_iommu *obj, const u32 da,
- void (*fn)(const void *), u32 flags)
-{
- struct sg_table *sgt = NULL;
- struct iovm_struct *area;
-
- if (!IS_ALIGNED(da, PAGE_SIZE)) {
- dev_err(obj->dev, "%s: alignment err(%08x)\n", __func__, da);
- return NULL;
- }
-
- mutex_lock(&obj->mmap_lock);
-
- area = __find_iovm_area(obj, da);
- if (!area) {
- dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
- goto out;
- }
-
- if ((area->flags & flags) != flags) {
- dev_err(obj->dev, "%s: wrong flags(%08x)\n", __func__,
- area->flags);
- goto out;
- }
- sgt = (struct sg_table *)area->sgt;
-
- unmap_iovm_area(domain, obj, area);
-
- fn(area->va);
-
- dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n", __func__,
- area->da_start, da, area->da_end,
- area->da_end - area->da_start, area->flags);
-
- free_iovm_area(obj, area);
-out:
- mutex_unlock(&obj->mmap_lock);
-
- return sgt;
-}
-
-static u32 map_iommu_region(struct iommu_domain *domain, struct omap_iommu *obj,
- u32 da, const struct sg_table *sgt, void *va,
- size_t bytes, u32 flags)
-{
- int err = -ENOMEM;
- struct iovm_struct *new;
-
- mutex_lock(&obj->mmap_lock);
-
- new = alloc_iovm_area(obj, da, bytes, flags);
- if (IS_ERR(new)) {
- err = PTR_ERR(new);
- goto err_alloc_iovma;
- }
- new->va = va;
- new->sgt = sgt;
-
- if (map_iovm_area(domain, new, sgt, new->flags))
- goto err_map;
-
- mutex_unlock(&obj->mmap_lock);
-
- dev_dbg(obj->dev, "%s: da:%08x(%x) flags:%08x va:%p\n",
- __func__, new->da_start, bytes, new->flags, va);
-
- return new->da_start;
-
-err_map:
- free_iovm_area(obj, new);
-err_alloc_iovma:
- mutex_unlock(&obj->mmap_lock);
- return err;
-}
-
-static inline u32
-__iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj,
- u32 da, const struct sg_table *sgt,
- void *va, size_t bytes, u32 flags)
-{
- return map_iommu_region(domain, obj, da, sgt, va, bytes, flags);
-}
-
-/**
- * omap_iommu_vmap - (d)-(p)-(v) address mapper
- * @domain: iommu domain
- * @dev: client device
- * @sgt: address of scatter gather table
- * @flags: iovma and page property
- *
- * Creates 1-n-1 mapping with given @sgt and returns @da.
- * All @sgt element must be io page size aligned.
- */
-u32 omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
- const struct sg_table *sgt, u32 flags)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- size_t bytes;
- void *va = NULL;
-
- if (!obj || !obj->dev || !sgt)
- return -EINVAL;
-
- bytes = sgtable_len(sgt);
- if (!bytes)
- return -EINVAL;
- bytes = PAGE_ALIGN(bytes);
-
- if (flags & IOVMF_MMIO) {
- va = vmap_sg(sgt);
- if (IS_ERR(va))
- return PTR_ERR(va);
- }
-
- flags |= IOVMF_DISCONT;
- flags |= IOVMF_MMIO;
-
- da = __iommu_vmap(domain, obj, da, sgt, va, bytes, flags);
- if (IS_ERR_VALUE(da))
- vunmap_sg(va);
-
- return da + sgtable_offset(sgt);
-}
-EXPORT_SYMBOL_GPL(omap_iommu_vmap);
-
-/**
- * omap_iommu_vunmap - release virtual mapping obtained by 'omap_iommu_vmap()'
- * @domain: iommu domain
- * @dev: client device
- * @da: iommu device virtual address
- *
- * Free the iommu virtually contiguous memory area starting at
- * @da, which was returned by 'omap_iommu_vmap()'.
- */
-struct sg_table *
-omap_iommu_vunmap(struct iommu_domain *domain, struct device *dev, u32 da)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- struct sg_table *sgt;
- /*
- * 'sgt' is allocated before 'omap_iommu_vmalloc()' is called.
- * Just returns 'sgt' to the caller to free
- */
- da &= PAGE_MASK;
- sgt = unmap_vm_area(domain, obj, da, vunmap_sg,
- IOVMF_DISCONT | IOVMF_MMIO);
- if (!sgt)
- dev_dbg(obj->dev, "%s: No sgt\n", __func__);
- return sgt;
-}
-EXPORT_SYMBOL_GPL(omap_iommu_vunmap);
-
-/**
- * omap_iommu_vmalloc - (d)-(p)-(v) address allocator and mapper
- * @dev: client device
- * @da: contiguous iommu virtual memory
- * @bytes: allocation size
- * @flags: iovma and page property
- *
- * Allocate @bytes linearly and creates 1-n-1 mapping and returns
- * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set.
- */
-u32
-omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, u32 da,
- size_t bytes, u32 flags)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- void *va;
- struct sg_table *sgt;
-
- if (!obj || !obj->dev || !bytes)
- return -EINVAL;
-
- bytes = PAGE_ALIGN(bytes);
-
- va = vmalloc(bytes);
- if (!va)
- return -ENOMEM;
-
- flags |= IOVMF_DISCONT;
- flags |= IOVMF_ALLOC;
-
- sgt = sgtable_alloc(bytes, flags, da, 0);
- if (IS_ERR(sgt)) {
- da = PTR_ERR(sgt);
- goto err_sgt_alloc;
- }
- sgtable_fill_vmalloc(sgt, va);
-
- da = __iommu_vmap(domain, obj, da, sgt, va, bytes, flags);
- if (IS_ERR_VALUE(da))
- goto err_iommu_vmap;
-
- return da;
-
-err_iommu_vmap:
- sgtable_drain_vmalloc(sgt);
- sgtable_free(sgt);
-err_sgt_alloc:
- vfree(va);
- return da;
-}
-EXPORT_SYMBOL_GPL(omap_iommu_vmalloc);
-
-/**
- * omap_iommu_vfree - release memory allocated by 'omap_iommu_vmalloc()'
- * @dev: client device
- * @da: iommu device virtual address
- *
- * Frees the iommu virtually continuous memory area starting at
- * @da, as obtained from 'omap_iommu_vmalloc()'.
- */
-void omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
- const u32 da)
-{
- struct omap_iommu *obj = dev_to_omap_iommu(dev);
- struct sg_table *sgt;
-
- sgt = unmap_vm_area(domain, obj, da, vfree,
- IOVMF_DISCONT | IOVMF_ALLOC);
- if (!sgt)
- dev_dbg(obj->dev, "%s: No sgt\n", __func__);
- sgtable_free(sgt);
-}
-EXPORT_SYMBOL_GPL(omap_iommu_vfree);
-
-static int __init iovmm_init(void)
-{
- const unsigned long flags = SLAB_HWCACHE_ALIGN;
- struct kmem_cache *p;
-
- p = kmem_cache_create("iovm_area_cache", sizeof(struct iovm_struct), 0,
- flags, NULL);
- if (!p)
- return -ENOMEM;
- iovm_area_cachep = p;
-
- return 0;
-}
-module_init(iovmm_init);
-
-static void __exit iovmm_exit(void)
-{
- kmem_cache_destroy(iovm_area_cachep);
-}
-module_exit(iovmm_exit);
-
-MODULE_DESCRIPTION("omap iommu: simple virtual address space management");
-MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/pci.h b/drivers/iommu/pci.h
deleted file mode 100644
index 352d80ae7443..000000000000
--- a/drivers/iommu/pci.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Copyright (C) 2013 Red Hat, Inc.
- * Copyright (C) 2013 Freescale Semiconductor, Inc.
- *
- */
-#ifndef __IOMMU_PCI_H
-#define __IOMMU_PCI_H
-
-/* Helper function for swapping pci device reference */
-static inline void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
-{
- pci_dev_put(*from);
- *from = to;
-}
-
-#endif /* __IOMMU_PCI_H */
diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index 464acda0bbc4..1333e6fb3405 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -354,7 +354,7 @@ static int shmobile_iommu_add_device(struct device *dev)
return 0;
}
-static struct iommu_ops shmobile_iommu_ops = {
+static const struct iommu_ops shmobile_iommu_ops = {
.domain_init = shmobile_iommu_domain_init,
.domain_destroy = shmobile_iommu_domain_destroy,
.attach_dev = shmobile_iommu_attach_device,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index dba1a9fd5070..b10a8ecede8e 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -309,7 +309,7 @@ static int gart_iommu_domain_has_cap(struct iommu_domain *domain,
return 0;
}
-static struct iommu_ops gart_iommu_ops = {
+static const struct iommu_ops gart_iommu_ops = {
.domain_init = gart_iommu_domain_init,
.domain_destroy = gart_iommu_domain_destroy,
.attach_dev = gart_iommu_attach_dev,
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 605b5b46a903..3ded3894623c 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -35,7 +35,8 @@
#include <linux/of_iommu.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
-#include <linux/tegra-ahb.h>
+
+#include <soc/tegra/ahb.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
@@ -947,7 +948,7 @@ static void smmu_iommu_domain_destroy(struct iommu_domain *domain)
dev_dbg(smmu->dev, "smmu_as@%p\n", as);
}
-static struct iommu_ops smmu_iommu_ops = {
+static const struct iommu_ops smmu_iommu_ops = {
.domain_init = smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
.attach_dev = smmu_iommu_attach_dev,
diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c
index c276fde318e5..de5e32151a1e 100644
--- a/drivers/ipack/carriers/tpci200.c
+++ b/drivers/ipack/carriers/tpci200.c
@@ -618,7 +618,7 @@ static void tpci200_pci_remove(struct pci_dev *dev)
__tpci200_pci_remove(tpci200);
}
-static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = {
+static const struct pci_device_id tpci200_idtable[] = {
{ TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
TPCI200_SUBDEVICE_ID },
{ 0, },
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index 141094e7c06e..e41bef048c23 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -177,19 +177,20 @@ static void ipoctal_irq_tx(struct ipoctal_channel *channel)
if (channel->nb_bytes == 0)
return;
+ spin_lock(&channel->lock);
value = channel->tty_port.xmit_buf[*pointer_write];
iowrite8(value, &channel->regs->w.thr);
channel->stats.tx++;
(*pointer_write)++;
*pointer_write = *pointer_write % PAGE_SIZE;
channel->nb_bytes--;
+ spin_unlock(&channel->lock);
}
static void ipoctal_irq_channel(struct ipoctal_channel *channel)
{
u8 isr, sr;
- spin_lock(&channel->lock);
/* The HW is organized in pair of channels. See which register we need
* to read from */
isr = ioread8(&channel->block_regs->r.isr);
@@ -213,8 +214,6 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel)
/* TX of each character */
if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
ipoctal_irq_tx(channel);
-
- spin_unlock(&channel->lock);
}
static irqreturn_t ipoctal_irq_handler(void *arg)
@@ -324,13 +323,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
&block_regs[i].w.imr);
}
- /*
- * IP-OCTAL has different addresses to copy its IRQ vector.
- * Depending of the carrier these addresses are accesible or not.
- * More info in the datasheet.
- */
- ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
- ipoctal_irq_handler, ipoctal);
/* Dummy write */
iowrite8(1, ipoctal->mem8_space + 1);
@@ -391,6 +383,14 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
dev_set_drvdata(tty_dev, channel);
}
+ /*
+ * IP-OCTAL has different addresses to copy its IRQ vector.
+ * Depending of the carrier these addresses are accesible or not.
+ * More info in the datasheet.
+ */
+ ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
+ ipoctal_irq_handler, ipoctal);
+
return 0;
}
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index bbb746e35500..b8632bf9a7f3 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -10,6 +10,11 @@ config ARM_GIC
config GIC_NON_BANKED
bool
+config ARM_GIC_V3
+ bool
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+
config ARM_NVIC
bool
select IRQ_DOMAIN
@@ -23,13 +28,26 @@ config ARM_VIC
config ARM_VIC_NR
int
default 4 if ARCH_S5PV210
- default 3 if ARCH_S5PC100
default 2
depends on ARM_VIC
help
The maximum number of VICs available in the system, for
power management.
+config ATMEL_AIC_IRQ
+ bool
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
+
+config ATMEL_AIC5_IRQ
+ bool
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
+
config BRCMSTB_L2_IRQ
bool
depends on ARM
@@ -53,6 +71,10 @@ config CLPS711X_IRQCHIP
select SPARSE_IRQ
default y
+config OR1K_PIC
+ bool
+ select IRQ_DOMAIN
+
config ORION_IRQCHIP
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 62a13e5ef98f..73052ba9ca62 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -11,13 +11,17 @@ obj-$(CONFIG_METAG) += irq-metag-ext.o
obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o
obj-$(CONFIG_CLPS711X_IRQCHIP) += irq-clps711x.o
+obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic.o
obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o
obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
-obj-$(CONFIG_ARM_GIC) += irq-gic.o
+obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o
+obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
obj-$(CONFIG_ARM_VIC) += irq-vic.o
+obj-$(CONFIG_ATMEL_AIC_IRQ) += irq-atmel-aic-common.o irq-atmel-aic.o
+obj-$(CONFIG_ATMEL_AIC5_IRQ) += irq-atmel-aic-common.o irq-atmel-aic5.o
obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o
obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o
obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index c887e6eebc41..574aba0eba4e 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -334,6 +334,15 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask,
static void armada_xp_mpic_smp_cpu_init(void)
{
+ u32 control;
+ int nr_irqs, i;
+
+ control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
+ nr_irqs = (control >> 2) & 0x3ff;
+
+ for (i = 0; i < nr_irqs; i++)
+ writel(i, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS);
+
/* Clear pending IPIs */
writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
@@ -474,7 +483,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
struct device_node *parent)
{
struct resource main_int_res, per_cpu_int_res;
- int parent_irq;
+ int parent_irq, nr_irqs, i;
u32 control;
BUG_ON(of_address_to_resource(node, 0, &main_int_res));
@@ -496,9 +505,13 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
BUG_ON(!per_cpu_int_base);
control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
+ nr_irqs = (control >> 2) & 0x3ff;
+
+ for (i = 0; i < nr_irqs; i++)
+ writel(i, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS);
armada_370_xp_mpic_domain =
- irq_domain_add_linear(node, (control >> 2) & 0x3ff,
+ irq_domain_add_linear(node, nr_irqs,
&armada_370_xp_mpic_irq_ops, NULL);
BUG_ON(!armada_370_xp_mpic_domain);
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
new file mode 100644
index 000000000000..6ae3cdee0681
--- /dev/null
+++ b/drivers/irqchip/irq-atmel-aic-common.c
@@ -0,0 +1,254 @@
+/*
+ * Atmel AT91 common AIC (Advanced Interrupt Controller) code shared by
+ * irq-atmel-aic and irq-atmel-aic5 drivers
+ *
+ * Copyright (C) 2004 SAN People
+ * Copyright (C) 2004 ATMEL
+ * Copyright (C) Rick Bronson
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "irq-atmel-aic-common.h"
+
+#define AT91_AIC_PRIOR GENMASK(2, 0)
+#define AT91_AIC_IRQ_MIN_PRIORITY 0
+#define AT91_AIC_IRQ_MAX_PRIORITY 7
+
+#define AT91_AIC_SRCTYPE GENMASK(7, 6)
+#define AT91_AIC_SRCTYPE_LOW (0 << 5)
+#define AT91_AIC_SRCTYPE_FALLING (1 << 5)
+#define AT91_AIC_SRCTYPE_HIGH (2 << 5)
+#define AT91_AIC_SRCTYPE_RISING (3 << 5)
+
+struct aic_chip_data {
+ u32 ext_irqs;
+};
+
+static void aic_common_shutdown(struct irq_data *d)
+{
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+
+ ct->chip.irq_mask(d);
+}
+
+int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct aic_chip_data *aic = gc->private;
+ unsigned aic_type;
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ aic_type = AT91_AIC_SRCTYPE_HIGH;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ aic_type = AT91_AIC_SRCTYPE_RISING;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ if (!(d->mask & aic->ext_irqs))
+ return -EINVAL;
+
+ aic_type = AT91_AIC_SRCTYPE_LOW;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ if (!(d->mask & aic->ext_irqs))
+ return -EINVAL;
+
+ aic_type = AT91_AIC_SRCTYPE_FALLING;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *val &= AT91_AIC_SRCTYPE;
+ *val |= aic_type;
+
+ return 0;
+}
+
+int aic_common_set_priority(int priority, unsigned *val)
+{
+ if (priority < AT91_AIC_IRQ_MIN_PRIORITY ||
+ priority > AT91_AIC_IRQ_MAX_PRIORITY)
+ return -EINVAL;
+
+ *val &= AT91_AIC_PRIOR;
+ *val |= priority;
+
+ return 0;
+}
+
+int aic_common_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec,
+ unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type)
+{
+ if (WARN_ON(intsize < 3))
+ return -EINVAL;
+
+ if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY) ||
+ (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
+ return -EINVAL;
+
+ *out_hwirq = intspec[0];
+ *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+
+ return 0;
+}
+
+static void __init aic_common_ext_irq_of_init(struct irq_domain *domain)
+{
+ struct device_node *node = domain->of_node;
+ struct irq_chip_generic *gc;
+ struct aic_chip_data *aic;
+ struct property *prop;
+ const __be32 *p;
+ u32 hwirq;
+
+ gc = irq_get_domain_generic_chip(domain, 0);
+
+ aic = gc->private;
+ aic->ext_irqs |= 1;
+
+ of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) {
+ gc = irq_get_domain_generic_chip(domain, hwirq);
+ if (!gc) {
+ pr_warn("AIC: external irq %d >= %d skip it\n",
+ hwirq, domain->revmap_size);
+ continue;
+ }
+
+ aic = gc->private;
+ aic->ext_irqs |= (1 << (hwirq % 32));
+ }
+}
+
+#define AT91_RTC_IDR 0x24
+#define AT91_RTC_IMR 0x28
+#define AT91_RTC_IRQ_MASK 0x1f
+
+void __init aic_common_rtc_irq_fixup(struct device_node *root)
+{
+ struct device_node *np;
+ void __iomem *regs;
+
+ np = of_find_compatible_node(root, NULL, "atmel,at91rm9200-rtc");
+ if (!np)
+ np = of_find_compatible_node(root, NULL,
+ "atmel,at91sam9x5-rtc");
+
+ if (!np)
+ return;
+
+ regs = of_iomap(np, 0);
+ of_node_put(np);
+
+ if (!regs)
+ return;
+
+ writel(AT91_RTC_IRQ_MASK, regs + AT91_RTC_IDR);
+
+ iounmap(regs);
+}
+
+void __init aic_common_irq_fixup(const struct of_device_id *matches)
+{
+ struct device_node *root = of_find_node_by_path("/");
+ const struct of_device_id *match;
+
+ if (!root)
+ return;
+
+ match = of_match_node(matches, root);
+ of_node_put(root);
+
+ if (match) {
+ void (*fixup)(struct device_node *) = match->data;
+ fixup(root);
+ }
+
+ of_node_put(root);
+}
+
+struct irq_domain *__init aic_common_of_init(struct device_node *node,
+ const struct irq_domain_ops *ops,
+ const char *name, int nirqs)
+{
+ struct irq_chip_generic *gc;
+ struct irq_domain *domain;
+ struct aic_chip_data *aic;
+ void __iomem *reg_base;
+ int nchips;
+ int ret;
+ int i;
+
+ nchips = DIV_ROUND_UP(nirqs, 32);
+
+ reg_base = of_iomap(node, 0);
+ if (!reg_base)
+ return ERR_PTR(-ENOMEM);
+
+ aic = kcalloc(nchips, sizeof(*aic), GFP_KERNEL);
+ if (!aic) {
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+
+ domain = irq_domain_add_linear(node, nchips * 32, ops, aic);
+ if (!domain) {
+ ret = -ENOMEM;
+ goto err_free_aic;
+ }
+
+ ret = irq_alloc_domain_generic_chips(domain, 32, 1, name,
+ handle_level_irq, 0, 0,
+ IRQCHIP_SKIP_SET_WAKE);
+ if (ret)
+ goto err_domain_remove;
+
+ for (i = 0; i < nchips; i++) {
+ gc = irq_get_domain_generic_chip(domain, i * 32);
+
+ gc->reg_base = reg_base;
+
+ gc->unused = 0;
+ gc->wake_enabled = ~0;
+ gc->chip_types[0].type = IRQ_TYPE_SENSE_MASK;
+ gc->chip_types[0].handler = handle_fasteoi_irq;
+ gc->chip_types[0].chip.irq_eoi = irq_gc_eoi;
+ gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
+ gc->chip_types[0].chip.irq_shutdown = aic_common_shutdown;
+ gc->private = &aic[i];
+ }
+
+ aic_common_ext_irq_of_init(domain);
+
+ return domain;
+
+err_domain_remove:
+ irq_domain_remove(domain);
+
+err_free_aic:
+ kfree(aic);
+
+err_iounmap:
+ iounmap(reg_base);
+
+ return ERR_PTR(ret);
+}
diff --git a/drivers/irqchip/irq-atmel-aic-common.h b/drivers/irqchip/irq-atmel-aic-common.h
new file mode 100644
index 000000000000..90aa00e918d6
--- /dev/null
+++ b/drivers/irqchip/irq-atmel-aic-common.h
@@ -0,0 +1,39 @@
+/*
+ * Atmel AT91 common AIC (Advanced Interrupt Controller) header file
+ *
+ * Copyright (C) 2004 SAN People
+ * Copyright (C) 2004 ATMEL
+ * Copyright (C) Rick Bronson
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __IRQ_ATMEL_AIC_COMMON_H
+#define __IRQ_ATMEL_AIC_COMMON_H
+
+
+int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val);
+
+int aic_common_set_priority(int priority, unsigned *val);
+
+int aic_common_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec,
+ unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type);
+
+struct irq_domain *__init aic_common_of_init(struct device_node *node,
+ const struct irq_domain_ops *ops,
+ const char *name, int nirqs);
+
+void __init aic_common_rtc_irq_fixup(struct device_node *root);
+
+void __init aic_common_irq_fixup(const struct of_device_id *matches);
+
+#endif /* __IRQ_ATMEL_AIC_COMMON_H */
diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c
new file mode 100644
index 000000000000..a82869e9fb26
--- /dev/null
+++ b/drivers/irqchip/irq-atmel-aic.c
@@ -0,0 +1,262 @@
+/*
+ * Atmel AT91 AIC (Advanced Interrupt Controller) driver
+ *
+ * Copyright (C) 2004 SAN People
+ * Copyright (C) 2004 ATMEL
+ * Copyright (C) Rick Bronson
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/bitmap.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irq-atmel-aic-common.h"
+#include "irqchip.h"
+
+/* Number of irq lines managed by AIC */
+#define NR_AIC_IRQS 32
+
+#define AT91_AIC_SMR(n) ((n) * 4)
+
+#define AT91_AIC_SVR(n) (0x80 + ((n) * 4))
+#define AT91_AIC_IVR 0x100
+#define AT91_AIC_FVR 0x104
+#define AT91_AIC_ISR 0x108
+
+#define AT91_AIC_IPR 0x10c
+#define AT91_AIC_IMR 0x110
+#define AT91_AIC_CISR 0x114
+
+#define AT91_AIC_IECR 0x120
+#define AT91_AIC_IDCR 0x124
+#define AT91_AIC_ICCR 0x128
+#define AT91_AIC_ISCR 0x12c
+#define AT91_AIC_EOICR 0x130
+#define AT91_AIC_SPU 0x134
+#define AT91_AIC_DCR 0x138
+
+static struct irq_domain *aic_domain;
+
+static asmlinkage void __exception_irq_entry
+aic_handle(struct pt_regs *regs)
+{
+ struct irq_domain_chip_generic *dgc = aic_domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+ u32 irqnr;
+ u32 irqstat;
+
+ irqnr = irq_reg_readl(gc->reg_base + AT91_AIC_IVR);
+ irqstat = irq_reg_readl(gc->reg_base + AT91_AIC_ISR);
+
+ irqnr = irq_find_mapping(aic_domain, irqnr);
+
+ if (!irqstat)
+ irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR);
+ else
+ handle_IRQ(irqnr, regs);
+}
+
+static int aic_retrigger(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+
+ /* Enable interrupt on AIC5 */
+ irq_gc_lock(gc);
+ irq_reg_writel(d->mask, gc->reg_base + AT91_AIC_ISCR);
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int aic_set_type(struct irq_data *d, unsigned type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ unsigned int smr;
+ int ret;
+
+ smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(d->hwirq));
+ ret = aic_common_set_type(d, type, &smr);
+ if (ret)
+ return ret;
+
+ irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(d->hwirq));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static void aic_suspend(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+
+ irq_gc_lock(gc);
+ irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IDCR);
+ irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IECR);
+ irq_gc_unlock(gc);
+}
+
+static void aic_resume(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+
+ irq_gc_lock(gc);
+ irq_reg_writel(gc->wake_active, gc->reg_base + AT91_AIC_IDCR);
+ irq_reg_writel(gc->mask_cache, gc->reg_base + AT91_AIC_IECR);
+ irq_gc_unlock(gc);
+}
+
+static void aic_pm_shutdown(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+
+ irq_gc_lock(gc);
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR);
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR);
+ irq_gc_unlock(gc);
+}
+#else
+#define aic_suspend NULL
+#define aic_resume NULL
+#define aic_pm_shutdown NULL
+#endif /* CONFIG_PM */
+
+static void __init aic_hw_init(struct irq_domain *domain)
+{
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
+ int i;
+
+ /*
+ * Perform 8 End Of Interrupt Command to make sure AIC
+ * will not Lock out nIRQ
+ */
+ for (i = 0; i < 8; i++)
+ irq_reg_writel(0, gc->reg_base + AT91_AIC_EOICR);
+
+ /*
+ * Spurious Interrupt ID in Spurious Vector Register.
+ * When there is no current interrupt, the IRQ Vector Register
+ * reads the value stored in AIC_SPU
+ */
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_SPU);
+
+ /* No debugging in AIC: Debug (Protect) Control Register */
+ irq_reg_writel(0, gc->reg_base + AT91_AIC_DCR);
+
+ /* Disable and clear all interrupts initially */
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_IDCR);
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC_ICCR);
+
+ for (i = 0; i < 32; i++)
+ irq_reg_writel(i, gc->reg_base + AT91_AIC_SVR(i));
+}
+
+static int aic_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type)
+{
+ struct irq_domain_chip_generic *dgc = d->gc;
+ struct irq_chip_generic *gc;
+ unsigned smr;
+ int idx;
+ int ret;
+
+ if (!dgc)
+ return -EINVAL;
+
+ ret = aic_common_irq_domain_xlate(d, ctrlr, intspec, intsize,
+ out_hwirq, out_type);
+ if (ret)
+ return ret;
+
+ idx = intspec[0] / dgc->irqs_per_chip;
+ if (idx >= dgc->num_chips)
+ return -EINVAL;
+
+ gc = dgc->gc[idx];
+
+ irq_gc_lock(gc);
+ smr = irq_reg_readl(gc->reg_base + AT91_AIC_SMR(*out_hwirq));
+ ret = aic_common_set_priority(intspec[2], &smr);
+ if (!ret)
+ irq_reg_writel(smr, gc->reg_base + AT91_AIC_SMR(*out_hwirq));
+ irq_gc_unlock(gc);
+
+ return ret;
+}
+
+static const struct irq_domain_ops aic_irq_ops = {
+ .map = irq_map_generic_chip,
+ .xlate = aic_irq_domain_xlate,
+};
+
+static void __init at91sam9_aic_irq_fixup(struct device_node *root)
+{
+ aic_common_rtc_irq_fixup(root);
+}
+
+static const struct of_device_id __initdata aic_irq_fixups[] = {
+ { .compatible = "atmel,at91sam9g45", .data = at91sam9_aic_irq_fixup },
+ { .compatible = "atmel,at91sam9n12", .data = at91sam9_aic_irq_fixup },
+ { .compatible = "atmel,at91sam9rl", .data = at91sam9_aic_irq_fixup },
+ { .compatible = "atmel,at91sam9x5", .data = at91sam9_aic_irq_fixup },
+ { /* sentinel */ },
+};
+
+static int __init aic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct irq_chip_generic *gc;
+ struct irq_domain *domain;
+
+ if (aic_domain)
+ return -EEXIST;
+
+ domain = aic_common_of_init(node, &aic_irq_ops, "atmel-aic",
+ NR_AIC_IRQS);
+ if (IS_ERR(domain))
+ return PTR_ERR(domain);
+
+ aic_common_irq_fixup(aic_irq_fixups);
+
+ aic_domain = domain;
+ gc = irq_get_domain_generic_chip(domain, 0);
+
+ gc->chip_types[0].regs.eoi = AT91_AIC_EOICR;
+ gc->chip_types[0].regs.enable = AT91_AIC_IECR;
+ gc->chip_types[0].regs.disable = AT91_AIC_IDCR;
+ gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
+ gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
+ gc->chip_types[0].chip.irq_retrigger = aic_retrigger;
+ gc->chip_types[0].chip.irq_set_type = aic_set_type;
+ gc->chip_types[0].chip.irq_suspend = aic_suspend;
+ gc->chip_types[0].chip.irq_resume = aic_resume;
+ gc->chip_types[0].chip.irq_pm_shutdown = aic_pm_shutdown;
+
+ aic_hw_init(domain);
+ set_handle_irq(aic_handle);
+
+ return 0;
+}
+IRQCHIP_DECLARE(at91rm9200_aic, "atmel,at91rm9200-aic", aic_of_init);
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
new file mode 100644
index 000000000000..edb227081524
--- /dev/null
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -0,0 +1,353 @@
+/*
+ * Atmel AT91 AIC5 (Advanced Interrupt Controller) driver
+ *
+ * Copyright (C) 2004 SAN People
+ * Copyright (C) 2004 ATMEL
+ * Copyright (C) Rick Bronson
+ * Copyright (C) 2014 Free Electrons
+ *
+ * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/bitmap.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irq-atmel-aic-common.h"
+#include "irqchip.h"
+
+/* Number of irq lines managed by AIC */
+#define NR_AIC5_IRQS 128
+
+#define AT91_AIC5_SSR 0x0
+#define AT91_AIC5_INTSEL_MSK (0x7f << 0)
+
+#define AT91_AIC5_SMR 0x4
+
+#define AT91_AIC5_SVR 0x8
+#define AT91_AIC5_IVR 0x10
+#define AT91_AIC5_FVR 0x14
+#define AT91_AIC5_ISR 0x18
+
+#define AT91_AIC5_IPR0 0x20
+#define AT91_AIC5_IPR1 0x24
+#define AT91_AIC5_IPR2 0x28
+#define AT91_AIC5_IPR3 0x2c
+#define AT91_AIC5_IMR 0x30
+#define AT91_AIC5_CISR 0x34
+
+#define AT91_AIC5_IECR 0x40
+#define AT91_AIC5_IDCR 0x44
+#define AT91_AIC5_ICCR 0x48
+#define AT91_AIC5_ISCR 0x4c
+#define AT91_AIC5_EOICR 0x38
+#define AT91_AIC5_SPU 0x3c
+#define AT91_AIC5_DCR 0x6c
+
+#define AT91_AIC5_FFER 0x50
+#define AT91_AIC5_FFDR 0x54
+#define AT91_AIC5_FFSR 0x58
+
+static struct irq_domain *aic5_domain;
+
+static asmlinkage void __exception_irq_entry
+aic5_handle(struct pt_regs *regs)
+{
+ struct irq_domain_chip_generic *dgc = aic5_domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+ u32 irqnr;
+ u32 irqstat;
+
+ irqnr = irq_reg_readl(gc->reg_base + AT91_AIC5_IVR);
+ irqstat = irq_reg_readl(gc->reg_base + AT91_AIC5_ISR);
+
+ irqnr = irq_find_mapping(aic5_domain, irqnr);
+
+ if (!irqstat)
+ irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR);
+ else
+ handle_IRQ(irqnr, regs);
+}
+
+static void aic5_mask(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+
+ /* Disable interrupt on AIC5 */
+ irq_gc_lock(gc);
+ irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
+ irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR);
+ gc->mask_cache &= ~d->mask;
+ irq_gc_unlock(gc);
+}
+
+static void aic5_unmask(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+
+ /* Enable interrupt on AIC5 */
+ irq_gc_lock(gc);
+ irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
+ irq_reg_writel(1, gc->reg_base + AT91_AIC5_IECR);
+ gc->mask_cache |= d->mask;
+ irq_gc_unlock(gc);
+}
+
+static int aic5_retrigger(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+
+ /* Enable interrupt on AIC5 */
+ irq_gc_lock(gc);
+ irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
+ irq_reg_writel(1, gc->reg_base + AT91_AIC5_ISCR);
+ irq_gc_unlock(gc);
+
+ return 0;
+}
+
+static int aic5_set_type(struct irq_data *d, unsigned type)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *gc = dgc->gc[0];
+ unsigned int smr;
+ int ret;
+
+ irq_gc_lock(gc);
+ irq_reg_writel(d->hwirq, gc->reg_base + AT91_AIC5_SSR);
+ smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR);
+ ret = aic_common_set_type(d, type, &smr);
+ if (!ret)
+ irq_reg_writel(smr, gc->reg_base + AT91_AIC5_SMR);
+ irq_gc_unlock(gc);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static void aic5_suspend(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *bgc = dgc->gc[0];
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ int i;
+ u32 mask;
+
+ irq_gc_lock(bgc);
+ for (i = 0; i < dgc->irqs_per_chip; i++) {
+ mask = 1 << i;
+ if ((mask & gc->mask_cache) == (mask & gc->wake_active))
+ continue;
+
+ irq_reg_writel(i + gc->irq_base,
+ bgc->reg_base + AT91_AIC5_SSR);
+ if (mask & gc->wake_active)
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR);
+ else
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
+ }
+ irq_gc_unlock(bgc);
+}
+
+static void aic5_resume(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *bgc = dgc->gc[0];
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ int i;
+ u32 mask;
+
+ irq_gc_lock(bgc);
+ for (i = 0; i < dgc->irqs_per_chip; i++) {
+ mask = 1 << i;
+ if ((mask & gc->mask_cache) == (mask & gc->wake_active))
+ continue;
+
+ irq_reg_writel(i + gc->irq_base,
+ bgc->reg_base + AT91_AIC5_SSR);
+ if (mask & gc->mask_cache)
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IECR);
+ else
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
+ }
+ irq_gc_unlock(bgc);
+}
+
+static void aic5_pm_shutdown(struct irq_data *d)
+{
+ struct irq_domain *domain = d->domain;
+ struct irq_domain_chip_generic *dgc = domain->gc;
+ struct irq_chip_generic *bgc = dgc->gc[0];
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ int i;
+
+ irq_gc_lock(bgc);
+ for (i = 0; i < dgc->irqs_per_chip; i++) {
+ irq_reg_writel(i + gc->irq_base,
+ bgc->reg_base + AT91_AIC5_SSR);
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_IDCR);
+ irq_reg_writel(1, bgc->reg_base + AT91_AIC5_ICCR);
+ }
+ irq_gc_unlock(bgc);
+}
+#else
+#define aic5_suspend NULL
+#define aic5_resume NULL
+#define aic5_pm_shutdown NULL
+#endif /* CONFIG_PM */
+
+static void __init aic5_hw_init(struct irq_domain *domain)
+{
+ struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
+ int i;
+
+ /*
+ * Perform 8 End Of Interrupt Command to make sure AIC
+ * will not Lock out nIRQ
+ */
+ for (i = 0; i < 8; i++)
+ irq_reg_writel(0, gc->reg_base + AT91_AIC5_EOICR);
+
+ /*
+ * Spurious Interrupt ID in Spurious Vector Register.
+ * When there is no current interrupt, the IRQ Vector Register
+ * reads the value stored in AIC_SPU
+ */
+ irq_reg_writel(0xffffffff, gc->reg_base + AT91_AIC5_SPU);
+
+ /* No debugging in AIC: Debug (Protect) Control Register */
+ irq_reg_writel(0, gc->reg_base + AT91_AIC5_DCR);
+
+ /* Disable and clear all interrupts initially */
+ for (i = 0; i < domain->revmap_size; i++) {
+ irq_reg_writel(i, gc->reg_base + AT91_AIC5_SSR);
+ irq_reg_writel(i, gc->reg_base + AT91_AIC5_SVR);
+ irq_reg_writel(1, gc->reg_base + AT91_AIC5_IDCR);
+ irq_reg_writel(1, gc->reg_base + AT91_AIC5_ICCR);
+ }
+}
+
+static int aic5_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_type)
+{
+ struct irq_domain_chip_generic *dgc = d->gc;
+ struct irq_chip_generic *gc;
+ unsigned smr;
+ int ret;
+
+ if (!dgc)
+ return -EINVAL;
+
+ ret = aic_common_irq_domain_xlate(d, ctrlr, intspec, intsize,
+ out_hwirq, out_type);
+ if (ret)
+ return ret;
+
+ gc = dgc->gc[0];
+
+ irq_gc_lock(gc);
+ irq_reg_writel(*out_hwirq, gc->reg_base + AT91_AIC5_SSR);
+ smr = irq_reg_readl(gc->reg_base + AT91_AIC5_SMR);
+ ret = aic_common_set_priority(intspec[2], &smr);
+ if (!ret)
+ irq_reg_writel(intspec[2] | smr, gc->reg_base + AT91_AIC5_SMR);
+ irq_gc_unlock(gc);
+
+ return ret;
+}
+
+static const struct irq_domain_ops aic5_irq_ops = {
+ .map = irq_map_generic_chip,
+ .xlate = aic5_irq_domain_xlate,
+};
+
+static void __init sama5d3_aic_irq_fixup(struct device_node *root)
+{
+ aic_common_rtc_irq_fixup(root);
+}
+
+static const struct of_device_id __initdata aic5_irq_fixups[] = {
+ { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup },
+ { /* sentinel */ },
+};
+
+static int __init aic5_of_init(struct device_node *node,
+ struct device_node *parent,
+ int nirqs)
+{
+ struct irq_chip_generic *gc;
+ struct irq_domain *domain;
+ int nchips;
+ int i;
+
+ if (nirqs > NR_AIC5_IRQS)
+ return -EINVAL;
+
+ if (aic5_domain)
+ return -EEXIST;
+
+ domain = aic_common_of_init(node, &aic5_irq_ops, "atmel-aic5",
+ nirqs);
+ if (IS_ERR(domain))
+ return PTR_ERR(domain);
+
+ aic_common_irq_fixup(aic5_irq_fixups);
+
+ aic5_domain = domain;
+ nchips = aic5_domain->revmap_size / 32;
+ for (i = 0; i < nchips; i++) {
+ gc = irq_get_domain_generic_chip(domain, i * 32);
+
+ gc->chip_types[0].regs.eoi = AT91_AIC5_EOICR;
+ gc->chip_types[0].chip.irq_mask = aic5_mask;
+ gc->chip_types[0].chip.irq_unmask = aic5_unmask;
+ gc->chip_types[0].chip.irq_retrigger = aic5_retrigger;
+ gc->chip_types[0].chip.irq_set_type = aic5_set_type;
+ gc->chip_types[0].chip.irq_suspend = aic5_suspend;
+ gc->chip_types[0].chip.irq_resume = aic5_resume;
+ gc->chip_types[0].chip.irq_pm_shutdown = aic5_pm_shutdown;
+ }
+
+ aic5_hw_init(domain);
+ set_handle_irq(aic5_handle);
+
+ return 0;
+}
+
+#define NR_SAMA5D3_IRQS 50
+
+static int __init sama5d3_aic5_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return aic5_of_init(node, parent, NR_SAMA5D3_IRQS);
+}
+IRQCHIP_DECLARE(sama5d3_aic5, "atmel,sama5d3-aic", sama5d3_aic5_of_init);
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index 8ee2a36d5840..c15c840987d2 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -150,7 +150,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
/* Allocate a single Generic IRQ chip for this node */
ret = irq_alloc_domain_generic_chips(data->domain, 32, 1,
- np->full_name, handle_level_irq, clr, 0, 0);
+ np->full_name, handle_edge_irq, clr, 0, 0);
if (ret) {
pr_err("failed to allocate generic irq chip\n");
goto out_free_domain;
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 3d15d16a7088..85c2985d8bcb 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -15,22 +15,31 @@
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/irqchip/arm-gic.h>
+#include <linux/irqchip/irq-crossbar.h>
#define IRQ_FREE -1
+#define IRQ_RESERVED -2
+#define IRQ_SKIP -3
#define GIC_IRQ_START 32
-/*
+/**
+ * struct crossbar_device - crossbar device description
* @int_max: maximum number of supported interrupts
+ * @safe_map: safe default value to initialize the crossbar
+ * @max_crossbar_sources: Maximum number of crossbar sources
* @irq_map: array of interrupts to crossbar number mapping
* @crossbar_base: crossbar base address
* @register_offsets: offsets for each irq number
+ * @write: register write function pointer
*/
struct crossbar_device {
uint int_max;
+ uint safe_map;
+ uint max_crossbar_sources;
uint *irq_map;
void __iomem *crossbar_base;
int *register_offsets;
- void (*write) (int, int);
+ void (*write)(int, int);
};
static struct crossbar_device *cb;
@@ -50,11 +59,22 @@ static inline void crossbar_writeb(int irq_no, int cb_no)
writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
}
+static inline int get_prev_map_irq(int cb_no)
+{
+ int i;
+
+ for (i = cb->int_max - 1; i >= 0; i--)
+ if (cb->irq_map[i] == cb_no)
+ return i;
+
+ return -ENODEV;
+}
+
static inline int allocate_free_irq(int cb_no)
{
int i;
- for (i = 0; i < cb->int_max; i++) {
+ for (i = cb->int_max - 1; i >= 0; i--) {
if (cb->irq_map[i] == IRQ_FREE) {
cb->irq_map[i] = cb_no;
return i;
@@ -64,19 +84,47 @@ static inline int allocate_free_irq(int cb_no)
return -ENODEV;
}
+static inline bool needs_crossbar_write(irq_hw_number_t hw)
+{
+ int cb_no;
+
+ if (hw > GIC_IRQ_START) {
+ cb_no = cb->irq_map[hw - GIC_IRQ_START];
+ if (cb_no != IRQ_RESERVED && cb_no != IRQ_SKIP)
+ return true;
+ }
+
+ return false;
+}
+
static int crossbar_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
- cb->write(hw - GIC_IRQ_START, cb->irq_map[hw - GIC_IRQ_START]);
+ if (needs_crossbar_write(hw))
+ cb->write(hw - GIC_IRQ_START, cb->irq_map[hw - GIC_IRQ_START]);
+
return 0;
}
+/**
+ * crossbar_domain_unmap - unmap a crossbar<->irq connection
+ * @d: domain of irq to unmap
+ * @irq: virq number
+ *
+ * We do not maintain a use count of total number of map/unmap
+ * calls for a particular irq to find out if a irq can be really
+ * unmapped. This is because unmap is called during irq_dispose_mapping(irq),
+ * after which irq is anyways unusable. So an explicit map has to be called
+ * after that.
+ */
static void crossbar_domain_unmap(struct irq_domain *d, unsigned int irq)
{
irq_hw_number_t hw = irq_get_irq_data(irq)->hwirq;
- if (hw > GIC_IRQ_START)
+ if (needs_crossbar_write(hw)) {
cb->irq_map[hw - GIC_IRQ_START] = IRQ_FREE;
+ cb->write(hw - GIC_IRQ_START, cb->safe_map);
+ }
}
static int crossbar_domain_xlate(struct irq_domain *d,
@@ -85,18 +133,41 @@ static int crossbar_domain_xlate(struct irq_domain *d,
unsigned long *out_hwirq,
unsigned int *out_type)
{
- unsigned long ret;
+ int ret;
+ int req_num = intspec[1];
+ int direct_map_num;
+
+ if (req_num >= cb->max_crossbar_sources) {
+ direct_map_num = req_num - cb->max_crossbar_sources;
+ if (direct_map_num < cb->int_max) {
+ ret = cb->irq_map[direct_map_num];
+ if (ret == IRQ_RESERVED || ret == IRQ_SKIP) {
+ /* We use the interrupt num as h/w irq num */
+ ret = direct_map_num;
+ goto found;
+ }
+ }
+
+ pr_err("%s: requested crossbar number %d > max %d\n",
+ __func__, req_num, cb->max_crossbar_sources);
+ return -EINVAL;
+ }
- ret = allocate_free_irq(intspec[1]);
+ ret = get_prev_map_irq(req_num);
+ if (ret >= 0)
+ goto found;
- if (IS_ERR_VALUE(ret))
+ ret = allocate_free_irq(req_num);
+
+ if (ret < 0)
return ret;
+found:
*out_hwirq = ret + GIC_IRQ_START;
return 0;
}
-const struct irq_domain_ops routable_irq_domain_ops = {
+static const struct irq_domain_ops routable_irq_domain_ops = {
.map = crossbar_domain_map,
.unmap = crossbar_domain_unmap,
.xlate = crossbar_domain_xlate
@@ -104,22 +175,36 @@ const struct irq_domain_ops routable_irq_domain_ops = {
static int __init crossbar_of_init(struct device_node *node)
{
- int i, size, max, reserved = 0, entry;
+ int i, size, max = 0, reserved = 0, entry;
const __be32 *irqsr;
+ int ret = -ENOMEM;
cb = kzalloc(sizeof(*cb), GFP_KERNEL);
if (!cb)
- return -ENOMEM;
+ return ret;
cb->crossbar_base = of_iomap(node, 0);
if (!cb->crossbar_base)
- goto err1;
+ goto err_cb;
+
+ of_property_read_u32(node, "ti,max-crossbar-sources",
+ &cb->max_crossbar_sources);
+ if (!cb->max_crossbar_sources) {
+ pr_err("missing 'ti,max-crossbar-sources' property\n");
+ ret = -EINVAL;
+ goto err_base;
+ }
of_property_read_u32(node, "ti,max-irqs", &max);
- cb->irq_map = kzalloc(max * sizeof(int), GFP_KERNEL);
+ if (!max) {
+ pr_err("missing 'ti,max-irqs' property\n");
+ ret = -EINVAL;
+ goto err_base;
+ }
+ cb->irq_map = kcalloc(max, sizeof(int), GFP_KERNEL);
if (!cb->irq_map)
- goto err2;
+ goto err_base;
cb->int_max = max;
@@ -137,15 +222,35 @@ static int __init crossbar_of_init(struct device_node *node)
i, &entry);
if (entry > max) {
pr_err("Invalid reserved entry\n");
- goto err3;
+ ret = -EINVAL;
+ goto err_irq_map;
+ }
+ cb->irq_map[entry] = IRQ_RESERVED;
+ }
+ }
+
+ /* Skip irqs hardwired to bypass the crossbar */
+ irqsr = of_get_property(node, "ti,irqs-skip", &size);
+ if (irqsr) {
+ size /= sizeof(__be32);
+
+ for (i = 0; i < size; i++) {
+ of_property_read_u32_index(node,
+ "ti,irqs-skip",
+ i, &entry);
+ if (entry > max) {
+ pr_err("Invalid skip entry\n");
+ ret = -EINVAL;
+ goto err_irq_map;
}
- cb->irq_map[entry] = 0;
+ cb->irq_map[entry] = IRQ_SKIP;
}
}
- cb->register_offsets = kzalloc(max * sizeof(int), GFP_KERNEL);
+
+ cb->register_offsets = kcalloc(max, sizeof(int), GFP_KERNEL);
if (!cb->register_offsets)
- goto err3;
+ goto err_irq_map;
of_property_read_u32(node, "ti,reg-size", &size);
@@ -161,7 +266,8 @@ static int __init crossbar_of_init(struct device_node *node)
break;
default:
pr_err("Invalid reg-size property\n");
- goto err4;
+ ret = -EINVAL;
+ goto err_reg_offset;
break;
}
@@ -170,25 +276,37 @@ static int __init crossbar_of_init(struct device_node *node)
* reserved irqs. so find and store the offsets once.
*/
for (i = 0; i < max; i++) {
- if (!cb->irq_map[i])
+ if (cb->irq_map[i] == IRQ_RESERVED)
continue;
cb->register_offsets[i] = reserved;
reserved += size;
}
+ of_property_read_u32(node, "ti,irqs-safe-map", &cb->safe_map);
+ /* Initialize the crossbar with safe map to start with */
+ for (i = 0; i < max; i++) {
+ if (cb->irq_map[i] == IRQ_RESERVED ||
+ cb->irq_map[i] == IRQ_SKIP)
+ continue;
+
+ cb->write(i, cb->safe_map);
+ }
+
register_routable_domain_ops(&routable_irq_domain_ops);
return 0;
-err4:
+err_reg_offset:
kfree(cb->register_offsets);
-err3:
+err_irq_map:
kfree(cb->irq_map);
-err2:
+err_base:
iounmap(cb->crossbar_base);
-err1:
+err_cb:
kfree(cb);
- return -ENOMEM;
+
+ cb = NULL;
+ return ret;
}
static const struct of_device_id crossbar_match[] __initconst = {
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
new file mode 100644
index 000000000000..60ac704d2090
--- /dev/null
+++ b/drivers/irqchip/irq-gic-common.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip/arm-gic.h>
+
+#include "irq-gic-common.h"
+
+void gic_configure_irq(unsigned int irq, unsigned int type,
+ void __iomem *base, void (*sync_access)(void))
+{
+ u32 enablemask = 1 << (irq % 32);
+ u32 enableoff = (irq / 32) * 4;
+ u32 confmask = 0x2 << ((irq % 16) * 2);
+ u32 confoff = (irq / 16) * 4;
+ bool enabled = false;
+ u32 val;
+
+ /*
+ * Read current configuration register, and insert the config
+ * for "irq", depending on "type".
+ */
+ val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+ if (type == IRQ_TYPE_LEVEL_HIGH)
+ val &= ~confmask;
+ else if (type == IRQ_TYPE_EDGE_RISING)
+ val |= confmask;
+
+ /*
+ * As recommended by the spec, disable the interrupt before changing
+ * the configuration
+ */
+ if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+ if (sync_access)
+ sync_access();
+ enabled = true;
+ }
+
+ /*
+ * Write back the new configuration, and possibly re-enable
+ * the interrupt.
+ */
+ writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
+
+ if (enabled)
+ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+
+ if (sync_access)
+ sync_access();
+}
+
+void __init gic_dist_config(void __iomem *base, int gic_irqs,
+ void (*sync_access)(void))
+{
+ unsigned int i;
+
+ /*
+ * Set all global interrupts to be level triggered, active low.
+ */
+ for (i = 32; i < gic_irqs; i += 16)
+ writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4);
+
+ /*
+ * Set priority on all global interrupts.
+ */
+ for (i = 32; i < gic_irqs; i += 4)
+ writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i);
+
+ /*
+ * Disable all interrupts. Leave the PPI and SGIs alone
+ * as they are enabled by redistributor registers.
+ */
+ for (i = 32; i < gic_irqs; i += 32)
+ writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8);
+
+ if (sync_access)
+ sync_access();
+}
+
+void gic_cpu_config(void __iomem *base, void (*sync_access)(void))
+{
+ int i;
+
+ /*
+ * Deal with the banked PPI and SGI interrupts - disable all
+ * PPI interrupts, ensure all SGI interrupts are enabled.
+ */
+ writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR);
+ writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET);
+
+ /*
+ * Set priority on PPI and SGI interrupts
+ */
+ for (i = 0; i < 32; i += 4)
+ writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
+
+ if (sync_access)
+ sync_access();
+}
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
new file mode 100644
index 000000000000..b41f02481c3a
--- /dev/null
+++ b/drivers/irqchip/irq-gic-common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 _IRQ_GIC_COMMON_H
+#define _IRQ_GIC_COMMON_H
+
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+
+void gic_configure_irq(unsigned int irq, unsigned int type,
+ void __iomem *base, void (*sync_access)(void));
+void gic_dist_config(void __iomem *base, int gic_irqs,
+ void (*sync_access)(void));
+void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+
+#endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
new file mode 100644
index 000000000000..57eaa5a0b1e3
--- /dev/null
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 2013, 2014 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/cpu.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+
+#include <linux/irqchip/arm-gic-v3.h>
+
+#include <asm/cputype.h>
+#include <asm/exception.h>
+#include <asm/smp_plat.h>
+
+#include "irq-gic-common.h"
+#include "irqchip.h"
+
+struct gic_chip_data {
+ void __iomem *dist_base;
+ void __iomem **redist_base;
+ void __percpu __iomem **rdist;
+ struct irq_domain *domain;
+ u64 redist_stride;
+ u32 redist_regions;
+ unsigned int irq_nr;
+};
+
+static struct gic_chip_data gic_data __read_mostly;
+
+#define gic_data_rdist() (this_cpu_ptr(gic_data.rdist))
+#define gic_data_rdist_rd_base() (*gic_data_rdist())
+#define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K)
+
+/* Our default, arbitrary priority value. Linux only uses one anyway. */
+#define DEFAULT_PMR_VALUE 0xf0
+
+static inline unsigned int gic_irq(struct irq_data *d)
+{
+ return d->hwirq;
+}
+
+static inline int gic_irq_in_rdist(struct irq_data *d)
+{
+ return gic_irq(d) < 32;
+}
+
+static inline void __iomem *gic_dist_base(struct irq_data *d)
+{
+ if (gic_irq_in_rdist(d)) /* SGI+PPI -> SGI_base for this CPU */
+ return gic_data_rdist_sgi_base();
+
+ if (d->hwirq <= 1023) /* SPI -> dist_base */
+ return gic_data.dist_base;
+
+ if (d->hwirq >= 8192)
+ BUG(); /* LPI Detected!!! */
+
+ return NULL;
+}
+
+static void gic_do_wait_for_rwp(void __iomem *base)
+{
+ u32 count = 1000000; /* 1s! */
+
+ while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) {
+ count--;
+ if (!count) {
+ pr_err_ratelimited("RWP timeout, gone fishing\n");
+ return;
+ }
+ cpu_relax();
+ udelay(1);
+ };
+}
+
+/* Wait for completion of a distributor change */
+static void gic_dist_wait_for_rwp(void)
+{
+ gic_do_wait_for_rwp(gic_data.dist_base);
+}
+
+/* Wait for completion of a redistributor change */
+static void gic_redist_wait_for_rwp(void)
+{
+ gic_do_wait_for_rwp(gic_data_rdist_rd_base());
+}
+
+/* Low level accessors */
+static u64 gic_read_iar(void)
+{
+ u64 irqstat;
+
+ asm volatile("mrs_s %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat));
+ return irqstat;
+}
+
+static void gic_write_pmr(u64 val)
+{
+ asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
+}
+
+static void gic_write_ctlr(u64 val)
+{
+ asm volatile("msr_s " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val));
+ isb();
+}
+
+static void gic_write_grpen1(u64 val)
+{
+ asm volatile("msr_s " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val));
+ isb();
+}
+
+static void gic_write_sgi1r(u64 val)
+{
+ asm volatile("msr_s " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val));
+}
+
+static void gic_enable_sre(void)
+{
+ u64 val;
+
+ asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
+ val |= ICC_SRE_EL1_SRE;
+ asm volatile("msr_s " __stringify(ICC_SRE_EL1) ", %0" : : "r" (val));
+ isb();
+
+ /*
+ * Need to check that the SRE bit has actually been set. If
+ * not, it means that SRE is disabled at EL2. We're going to
+ * die painfully, and there is nothing we can do about it.
+ *
+ * Kindly inform the luser.
+ */
+ asm volatile("mrs_s %0, " __stringify(ICC_SRE_EL1) : "=r" (val));
+ if (!(val & ICC_SRE_EL1_SRE))
+ pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
+}
+
+static void gic_enable_redist(void)
+{
+ void __iomem *rbase;
+ u32 count = 1000000; /* 1s! */
+ u32 val;
+
+ rbase = gic_data_rdist_rd_base();
+
+ /* Wake up this CPU redistributor */
+ val = readl_relaxed(rbase + GICR_WAKER);
+ val &= ~GICR_WAKER_ProcessorSleep;
+ writel_relaxed(val, rbase + GICR_WAKER);
+
+ while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) {
+ count--;
+ if (!count) {
+ pr_err_ratelimited("redist didn't wake up...\n");
+ return;
+ }
+ cpu_relax();
+ udelay(1);
+ };
+}
+
+/*
+ * Routines to disable, enable, EOI and route interrupts
+ */
+static void gic_poke_irq(struct irq_data *d, u32 offset)
+{
+ u32 mask = 1 << (gic_irq(d) % 32);
+ void (*rwp_wait)(void);
+ void __iomem *base;
+
+ if (gic_irq_in_rdist(d)) {
+ base = gic_data_rdist_sgi_base();
+ rwp_wait = gic_redist_wait_for_rwp;
+ } else {
+ base = gic_data.dist_base;
+ rwp_wait = gic_dist_wait_for_rwp;
+ }
+
+ writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4);
+ rwp_wait();
+}
+
+static int gic_peek_irq(struct irq_data *d, u32 offset)
+{
+ u32 mask = 1 << (gic_irq(d) % 32);
+ void __iomem *base;
+
+ if (gic_irq_in_rdist(d))
+ base = gic_data_rdist_sgi_base();
+ else
+ base = gic_data.dist_base;
+
+ return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask);
+}
+
+static void gic_mask_irq(struct irq_data *d)
+{
+ gic_poke_irq(d, GICD_ICENABLER);
+}
+
+static void gic_unmask_irq(struct irq_data *d)
+{
+ gic_poke_irq(d, GICD_ISENABLER);
+}
+
+static void gic_eoi_irq(struct irq_data *d)
+{
+ gic_write_eoir(gic_irq(d));
+}
+
+static int gic_set_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int irq = gic_irq(d);
+ void (*rwp_wait)(void);
+ void __iomem *base;
+
+ /* Interrupt configuration for SGIs can't be changed */
+ if (irq < 16)
+ return -EINVAL;
+
+ if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ return -EINVAL;
+
+ if (gic_irq_in_rdist(d)) {
+ base = gic_data_rdist_sgi_base();
+ rwp_wait = gic_redist_wait_for_rwp;
+ } else {
+ base = gic_data.dist_base;
+ rwp_wait = gic_dist_wait_for_rwp;
+ }
+
+ gic_configure_irq(irq, type, base, rwp_wait);
+
+ return 0;
+}
+
+static u64 gic_mpidr_to_affinity(u64 mpidr)
+{
+ u64 aff;
+
+ aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 0));
+
+ return aff;
+}
+
+static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
+{
+ u64 irqnr;
+
+ do {
+ irqnr = gic_read_iar();
+
+ if (likely(irqnr > 15 && irqnr < 1020)) {
+ u64 irq = irq_find_mapping(gic_data.domain, irqnr);
+ if (likely(irq)) {
+ handle_IRQ(irq, regs);
+ continue;
+ }
+
+ WARN_ONCE(true, "Unexpected SPI received!\n");
+ gic_write_eoir(irqnr);
+ }
+ if (irqnr < 16) {
+ gic_write_eoir(irqnr);
+#ifdef CONFIG_SMP
+ handle_IPI(irqnr, regs);
+#else
+ WARN_ONCE(true, "Unexpected SGI received!\n");
+#endif
+ continue;
+ }
+ } while (irqnr != ICC_IAR1_EL1_SPURIOUS);
+}
+
+static void __init gic_dist_init(void)
+{
+ unsigned int i;
+ u64 affinity;
+ void __iomem *base = gic_data.dist_base;
+
+ /* Disable the distributor */
+ writel_relaxed(0, base + GICD_CTLR);
+ gic_dist_wait_for_rwp();
+
+ gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
+
+ /* Enable distributor with ARE, Group1 */
+ writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
+ base + GICD_CTLR);
+
+ /*
+ * Set all global interrupts to the boot CPU only. ARE must be
+ * enabled.
+ */
+ affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id()));
+ for (i = 32; i < gic_data.irq_nr; i++)
+ writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
+}
+
+static int gic_populate_rdist(void)
+{
+ u64 mpidr = cpu_logical_map(smp_processor_id());
+ u64 typer;
+ u32 aff;
+ 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.redist_regions; i++) {
+ void __iomem *ptr = gic_data.redist_base[i];
+ u32 reg;
+
+ reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
+ if (reg != GIC_PIDR2_ARCH_GICv3 &&
+ reg != GIC_PIDR2_ARCH_GICv4) { /* We're in trouble... */
+ pr_warn("No redistributor present @%p\n", ptr);
+ break;
+ }
+
+ do {
+ typer = readq_relaxed(ptr + GICR_TYPER);
+ if ((typer >> 32) == aff) {
+ gic_data_rdist_rd_base() = ptr;
+ pr_info("CPU%d: found redistributor %llx @%p\n",
+ smp_processor_id(),
+ (unsigned long long)mpidr, ptr);
+ return 0;
+ }
+
+ if (gic_data.redist_stride) {
+ ptr += gic_data.redist_stride;
+ } else {
+ ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */
+ if (typer & GICR_TYPER_VLPIS)
+ ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */
+ }
+ } while (!(typer & GICR_TYPER_LAST));
+ }
+
+ /* We couldn't even deal with ourselves... */
+ WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n",
+ smp_processor_id(), (unsigned long long)mpidr);
+ return -ENODEV;
+}
+
+static void gic_cpu_init(void)
+{
+ void __iomem *rbase;
+
+ /* Register ourselves with the rest of the world */
+ if (gic_populate_rdist())
+ return;
+
+ gic_enable_redist();
+
+ rbase = gic_data_rdist_sgi_base();
+
+ gic_cpu_config(rbase, gic_redist_wait_for_rwp);
+
+ /* Enable system registers */
+ gic_enable_sre();
+
+ /* Set priority mask register */
+ gic_write_pmr(DEFAULT_PMR_VALUE);
+
+ /* EOI deactivates interrupt too (mode 0) */
+ gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+
+ /* ... and let's hit the road... */
+ gic_write_grpen1(1);
+}
+
+#ifdef CONFIG_SMP
+static int gic_secondary_init(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+ gic_cpu_init();
+ return NOTIFY_OK;
+}
+
+/*
+ * Notifier for enabling the GIC CPU interface. Set an arbitrarily high
+ * priority because the GIC needs to be up before the ARM generic timers.
+ */
+static struct notifier_block gic_cpu_notifier = {
+ .notifier_call = gic_secondary_init,
+ .priority = 100,
+};
+
+static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask,
+ u64 cluster_id)
+{
+ int cpu = *base_cpu;
+ u64 mpidr = cpu_logical_map(cpu);
+ u16 tlist = 0;
+
+ while (cpu < nr_cpu_ids) {
+ /*
+ * If we ever get a cluster of more than 16 CPUs, just
+ * scream and skip that CPU.
+ */
+ if (WARN_ON((mpidr & 0xff) >= 16))
+ goto out;
+
+ tlist |= 1 << (mpidr & 0xf);
+
+ cpu = cpumask_next(cpu, mask);
+ if (cpu == nr_cpu_ids)
+ goto out;
+
+ mpidr = cpu_logical_map(cpu);
+
+ if (cluster_id != (mpidr & ~0xffUL)) {
+ cpu--;
+ goto out;
+ }
+ }
+out:
+ *base_cpu = cpu;
+ return tlist;
+}
+
+static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq)
+{
+ u64 val;
+
+ val = (MPIDR_AFFINITY_LEVEL(cluster_id, 3) << 48 |
+ MPIDR_AFFINITY_LEVEL(cluster_id, 2) << 32 |
+ irq << 24 |
+ MPIDR_AFFINITY_LEVEL(cluster_id, 1) << 16 |
+ tlist);
+
+ pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val);
+ gic_write_sgi1r(val);
+}
+
+static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+{
+ int cpu;
+
+ if (WARN_ON(irq >= 16))
+ return;
+
+ /*
+ * Ensure that stores to Normal memory are visible to the
+ * other CPUs before issuing the IPI.
+ */
+ smp_wmb();
+
+ for_each_cpu_mask(cpu, *mask) {
+ u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL;
+ u16 tlist;
+
+ tlist = gic_compute_target_list(&cpu, mask, cluster_id);
+ gic_send_sgi(cluster_id, tlist, irq);
+ }
+
+ /* Force the above writes to ICC_SGI1R_EL1 to be executed */
+ isb();
+}
+
+static void gic_smp_init(void)
+{
+ set_smp_cross_call(gic_raise_softirq);
+ register_cpu_notifier(&gic_cpu_notifier);
+}
+
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ bool force)
+{
+ unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ void __iomem *reg;
+ int enabled;
+ u64 val;
+
+ if (gic_irq_in_rdist(d))
+ return -EINVAL;
+
+ /* If interrupt was enabled, disable it first */
+ enabled = gic_peek_irq(d, GICD_ISENABLER);
+ if (enabled)
+ gic_mask_irq(d);
+
+ reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8);
+ val = gic_mpidr_to_affinity(cpu_logical_map(cpu));
+
+ writeq_relaxed(val, reg);
+
+ /*
+ * If the interrupt was enabled, enabled it again. Otherwise,
+ * just wait for the distributor to have digested our changes.
+ */
+ if (enabled)
+ gic_unmask_irq(d);
+ else
+ gic_dist_wait_for_rwp();
+
+ return IRQ_SET_MASK_OK;
+}
+#else
+#define gic_set_affinity NULL
+#define gic_smp_init() do { } while(0)
+#endif
+
+static struct irq_chip gic_chip = {
+ .name = "GICv3",
+ .irq_mask = gic_mask_irq,
+ .irq_unmask = gic_unmask_irq,
+ .irq_eoi = gic_eoi_irq,
+ .irq_set_type = gic_set_type,
+ .irq_set_affinity = gic_set_affinity,
+};
+
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ /* SGIs are private to the core kernel */
+ if (hw < 16)
+ return -EPERM;
+ /* PPIs */
+ if (hw < 32) {
+ irq_set_percpu_devid(irq);
+ irq_set_chip_and_handler(irq, &gic_chip,
+ handle_percpu_devid_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+ }
+ /* SPIs */
+ if (hw >= 32 && hw < gic_data.irq_nr) {
+ irq_set_chip_and_handler(irq, &gic_chip,
+ handle_fasteoi_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ irq_set_chip_data(irq, d->host_data);
+ return 0;
+}
+
+static int gic_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *controller,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (d->of_node != controller)
+ return -EINVAL;
+ if (intsize < 3)
+ return -EINVAL;
+
+ switch(intspec[0]) {
+ case 0: /* SPI */
+ *out_hwirq = intspec[1] + 32;
+ break;
+ case 1: /* PPI */
+ *out_hwirq = intspec[1] + 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+ return 0;
+}
+
+static const struct irq_domain_ops gic_irq_domain_ops = {
+ .map = gic_irq_domain_map,
+ .xlate = gic_irq_domain_xlate,
+};
+
+static int __init gic_of_init(struct device_node *node, struct device_node *parent)
+{
+ void __iomem *dist_base;
+ void __iomem **redist_base;
+ u64 redist_stride;
+ u32 redist_regions;
+ u32 reg;
+ int gic_irqs;
+ int err;
+ int i;
+
+ dist_base = of_iomap(node, 0);
+ if (!dist_base) {
+ pr_err("%s: unable to map gic dist registers\n",
+ node->full_name);
+ return -ENXIO;
+ }
+
+ reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+ if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
+ pr_err("%s: no distributor detected, giving up\n",
+ node->full_name);
+ err = -ENODEV;
+ goto out_unmap_dist;
+ }
+
+ if (of_property_read_u32(node, "#redistributor-regions", &redist_regions))
+ redist_regions = 1;
+
+ redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL);
+ if (!redist_base) {
+ err = -ENOMEM;
+ goto out_unmap_dist;
+ }
+
+ for (i = 0; i < redist_regions; i++) {
+ redist_base[i] = of_iomap(node, 1 + i);
+ if (!redist_base[i]) {
+ pr_err("%s: couldn't map region %d\n",
+ node->full_name, i);
+ err = -ENODEV;
+ goto out_unmap_rdist;
+ }
+ }
+
+ if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
+ redist_stride = 0;
+
+ gic_data.dist_base = dist_base;
+ gic_data.redist_base = redist_base;
+ gic_data.redist_regions = redist_regions;
+ gic_data.redist_stride = redist_stride;
+
+ /*
+ * Find out how many interrupts are supported.
+ * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
+ */
+ gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+ gic_data.irq_nr = gic_irqs;
+
+ gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops,
+ &gic_data);
+ gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist));
+
+ if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ set_handle_irq(gic_handle_irq);
+
+ gic_smp_init();
+ gic_dist_init();
+ gic_cpu_init();
+
+ return 0;
+
+out_free:
+ if (gic_data.domain)
+ irq_domain_remove(gic_data.domain);
+ free_percpu(gic_data.rdist);
+out_unmap_rdist:
+ for (i = 0; i < redist_regions; i++)
+ if (redist_base[i])
+ iounmap(redist_base[i]);
+ kfree(redist_base);
+out_unmap_dist:
+ iounmap(dist_base);
+ return err;
+}
+
+IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 7e11c9d6ae8c..4b959e606fe8 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1,6 +1,4 @@
/*
- * linux/arch/arm/common/gic.c
- *
* Copyright (C) 2002 ARM Limited, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -42,10 +40,12 @@
#include <linux/irqchip/chained_irq.h>
#include <linux/irqchip/arm-gic.h>
+#include <asm/cputype.h>
#include <asm/irq.h>
#include <asm/exception.h>
#include <asm/smp_plat.h>
+#include "irq-gic-common.h"
#include "irqchip.h"
union gic_base {
@@ -188,12 +188,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
{
void __iomem *base = gic_dist_base(d);
unsigned int gicirq = gic_irq(d);
- u32 enablemask = 1 << (gicirq % 32);
- u32 enableoff = (gicirq / 32) * 4;
- u32 confmask = 0x2 << ((gicirq % 16) * 2);
- u32 confoff = (gicirq / 16) * 4;
- bool enabled = false;
- u32 val;
/* Interrupt configuration for SGIs can't be changed */
if (gicirq < 16)
@@ -207,25 +201,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
if (gic_arch_extn.irq_set_type)
gic_arch_extn.irq_set_type(d, type);
- val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
- if (type == IRQ_TYPE_LEVEL_HIGH)
- val &= ~confmask;
- else if (type == IRQ_TYPE_EDGE_RISING)
- val |= confmask;
-
- /*
- * As recommended by the spec, disable the interrupt before changing
- * the configuration
- */
- if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
- enabled = true;
- }
-
- writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
-
- if (enabled)
- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+ gic_configure_irq(gicirq, type, base, NULL);
raw_spin_unlock(&irq_controller_lock);
@@ -387,12 +363,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
writel_relaxed(0, base + GIC_DIST_CTRL);
/*
- * Set all global interrupts to be level triggered, active low.
- */
- for (i = 32; i < gic_irqs; i += 16)
- writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
-
- /*
* Set all global interrupts to this CPU only.
*/
cpumask = gic_get_cpumask(gic);
@@ -401,18 +371,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
- /*
- * Set priority on all global interrupts.
- */
- for (i = 32; i < gic_irqs; i += 4)
- writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
-
- /*
- * Disable all interrupts. Leave the PPI and SGIs alone
- * as these enables are banked registers.
- */
- for (i = 32; i < gic_irqs; i += 32)
- writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
+ gic_dist_config(base, gic_irqs, NULL);
writel_relaxed(1, base + GIC_DIST_CTRL);
}
@@ -439,18 +398,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)
if (i != cpu)
gic_cpu_map[i] &= ~cpu_mask;
- /*
- * Deal with the banked PPI and SGI interrupts - disable all
- * PPI interrupts, ensure all SGI interrupts are enabled.
- */
- writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
- writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
-
- /*
- * Set priority on PPI and SGI interrupts
- */
- for (i = 0; i < 32; i += 4)
- writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+ gic_cpu_config(dist_base, NULL);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
writel_relaxed(1, base + GIC_CPU_CTRL);
@@ -954,7 +902,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
}
for_each_possible_cpu(cpu) {
- unsigned long offset = percpu_offset * cpu_logical_map(cpu);
+ u32 mpidr = cpu_logical_map(cpu);
+ u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ unsigned long offset = percpu_offset * core_id;
*per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset;
*per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset;
}
@@ -1071,8 +1021,10 @@ gic_of_init(struct device_node *node, struct device_node *parent)
gic_cnt++;
return 0;
}
+IRQCHIP_DECLARE(gic_400, "arm,gic-400", gic_of_init);
IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init);
IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init);
+IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index 70bdf6edb7bb..4ff0805fca01 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -49,14 +49,6 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
handle_IRQ(irq, regs);
}
-static void nvic_eoi(struct irq_data *d)
-{
- /*
- * This is a no-op as end of interrupt is signaled by the exception
- * return sequence.
- */
-}
-
static int __init nvic_of_init(struct device_node *node,
struct device_node *parent)
{
@@ -102,7 +94,10 @@ static int __init nvic_of_init(struct device_node *node,
gc->chip_types[0].regs.disable = NVIC_ICER;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
- gc->chip_types[0].chip.irq_eoi = nvic_eoi;
+ /* This is a no-op as end of interrupt is signaled by the
+ * exception return sequence.
+ */
+ gc->chip_types[0].chip.irq_eoi = irq_gc_noop;
/* disable interrupts */
writel_relaxed(~0, gc->reg_base + NVIC_ICER);
diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c
new file mode 100644
index 000000000000..17ff033d9925
--- /dev/null
+++ b/drivers/irqchip/irq-or1k-pic.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * Copyright (C) 2014 Stefan Kristansson <stefan.kristiansson@saunalahti.fi>
+ *
+ * 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/irq.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include "irqchip.h"
+
+/* OR1K PIC implementation */
+
+struct or1k_pic_dev {
+ struct irq_chip chip;
+ irq_flow_handler_t handle;
+ unsigned long flags;
+};
+
+/*
+ * We're a couple of cycles faster than the generic implementations with
+ * these 'fast' versions.
+ */
+
+static void or1k_pic_mask(struct irq_data *data)
+{
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
+}
+
+static void or1k_pic_unmask(struct irq_data *data)
+{
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->hwirq));
+}
+
+static void or1k_pic_ack(struct irq_data *data)
+{
+ mtspr(SPR_PICSR, (1UL << data->hwirq));
+}
+
+static void or1k_pic_mask_ack(struct irq_data *data)
+{
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
+ mtspr(SPR_PICSR, (1UL << data->hwirq));
+}
+
+/*
+ * There are two oddities with the OR1200 PIC implementation:
+ * i) LEVEL-triggered interrupts are latched and need to be cleared
+ * ii) the interrupt latch is cleared by writing a 0 to the bit,
+ * as opposed to a 1 as mandated by the spec
+ */
+static void or1k_pic_or1200_ack(struct irq_data *data)
+{
+ mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
+}
+
+static void or1k_pic_or1200_mask_ack(struct irq_data *data)
+{
+ mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq));
+ mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq));
+}
+
+static struct or1k_pic_dev or1k_pic_level = {
+ .chip = {
+ .name = "or1k-PIC-level",
+ .irq_unmask = or1k_pic_unmask,
+ .irq_mask = or1k_pic_mask,
+ .irq_mask_ack = or1k_pic_mask,
+ },
+ .handle = handle_level_irq,
+ .flags = IRQ_LEVEL | IRQ_NOPROBE,
+};
+
+static struct or1k_pic_dev or1k_pic_edge = {
+ .chip = {
+ .name = "or1k-PIC-edge",
+ .irq_unmask = or1k_pic_unmask,
+ .irq_mask = or1k_pic_mask,
+ .irq_ack = or1k_pic_ack,
+ .irq_mask_ack = or1k_pic_mask_ack,
+ },
+ .handle = handle_edge_irq,
+ .flags = IRQ_LEVEL | IRQ_NOPROBE,
+};
+
+static struct or1k_pic_dev or1k_pic_or1200 = {
+ .chip = {
+ .name = "or1200-PIC",
+ .irq_unmask = or1k_pic_unmask,
+ .irq_mask = or1k_pic_mask,
+ .irq_ack = or1k_pic_or1200_ack,
+ .irq_mask_ack = or1k_pic_or1200_mask_ack,
+ },
+ .handle = handle_level_irq,
+ .flags = IRQ_LEVEL | IRQ_NOPROBE,
+};
+
+static struct irq_domain *root_domain;
+
+static inline int pic_get_irq(int first)
+{
+ int hwirq;
+
+ hwirq = ffs(mfspr(SPR_PICSR) >> first);
+ if (!hwirq)
+ return NO_IRQ;
+ else
+ hwirq = hwirq + first - 1;
+
+ return irq_find_mapping(root_domain, hwirq);
+}
+
+static void or1k_pic_handle_irq(struct pt_regs *regs)
+{
+ int irq = -1;
+
+ while ((irq = pic_get_irq(irq + 1)) != NO_IRQ)
+ handle_IRQ(irq, regs);
+}
+
+static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ struct or1k_pic_dev *pic = d->host_data;
+
+ irq_set_chip_and_handler(irq, &pic->chip, pic->handle);
+ irq_set_status_flags(irq, pic->flags);
+
+ return 0;
+}
+
+static const struct irq_domain_ops or1k_irq_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = or1k_map,
+};
+
+/*
+ * This sets up the IRQ domain for the PIC built in to the OpenRISC
+ * 1000 CPU. This is the "root" domain as these are the interrupts
+ * that directly trigger an exception in the CPU.
+ */
+static int __init or1k_pic_init(struct device_node *node,
+ struct or1k_pic_dev *pic)
+{
+ /* Disable all interrupts until explicitly requested */
+ mtspr(SPR_PICMR, (0UL));
+
+ root_domain = irq_domain_add_linear(node, 32, &or1k_irq_domain_ops,
+ pic);
+
+ set_handle_irq(or1k_pic_handle_irq);
+
+ return 0;
+}
+
+static int __init or1k_pic_or1200_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return or1k_pic_init(node, &or1k_pic_or1200);
+}
+IRQCHIP_DECLARE(or1k_pic_or1200, "opencores,or1200-pic", or1k_pic_or1200_init);
+IRQCHIP_DECLARE(or1k_pic, "opencores,or1k-pic", or1k_pic_or1200_init);
+
+static int __init or1k_pic_level_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return or1k_pic_init(node, &or1k_pic_level);
+}
+IRQCHIP_DECLARE(or1k_pic_level, "opencores,or1k-pic-level",
+ or1k_pic_level_init);
+
+static int __init or1k_pic_edge_init(struct device_node *node,
+ struct device_node *parent)
+{
+ return or1k_pic_init(node, &or1k_pic_edge);
+}
+IRQCHIP_DECLARE(or1k_pic_edge, "opencores,or1k-pic-edge", or1k_pic_edge_init);
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 3ae2bb8d9cf2..ccf58548b161 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -14,6 +14,8 @@
#include <asm/exception.h>
#include <asm/mach/irq.h>
+#include "irqchip.h"
+
#define IRQ_STATUS 0x00
#define IRQ_RAW_STATUS 0x04
#define IRQ_ENABLE_SET 0x08
@@ -26,6 +28,8 @@
#define FIQ_ENABLE_SET 0x28
#define FIQ_ENABLE_CLEAR 0x2C
+#define PIC_ENABLES 0x20 /* set interrupt pass through bits */
+
/**
* struct fpga_irq_data - irq data container for the FPGA IRQ controller
* @base: memory offset in virtual memory
@@ -201,14 +205,26 @@ int __init fpga_irq_of_init(struct device_node *node,
/* Some chips are cascaded from a parent IRQ */
parent_irq = irq_of_parse_and_map(node, 0);
- if (!parent_irq)
+ if (!parent_irq) {
+ set_handle_irq(fpga_handle_irq);
parent_irq = -1;
+ }
fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
writel(clear_mask, base + IRQ_ENABLE_CLEAR);
writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+ /*
+ * On Versatile AB/PB, some secondary interrupts have a direct
+ * pass-thru to the primary controller for IRQs 20 and 22-31 which need
+ * to be enabled. See section 3.10 of the Versatile AB user guide.
+ */
+ if (of_device_is_compatible(node, "arm,versatile-sic"))
+ writel(0xffd00000, base + PIC_ENABLES);
+
return 0;
}
+IRQCHIP_DECLARE(arm_fpga, "arm,versatile-fpga-irq", fpga_irq_of_init);
+IRQCHIP_DECLARE(arm_fpga_sic, "arm,versatile-sic", fpga_irq_of_init);
#endif
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 3fdda3a40269..9c145a7cb056 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -19,7 +19,6 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
-#include <linux/irqchip/spear-shirq.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
@@ -27,20 +26,73 @@
#include "irqchip.h"
-static DEFINE_SPINLOCK(lock);
+/*
+ * struct spear_shirq: shared irq structure
+ *
+ * base: Base register address
+ * status_reg: Status register offset for chained interrupt handler
+ * mask_reg: Mask register offset for irq chip
+ * mask: Mask to apply to the status register
+ * virq_base: Base virtual interrupt number
+ * nr_irqs: Number of interrupts handled by this block
+ * offset: Bit offset of the first interrupt
+ * irq_chip: Interrupt controller chip used for this instance,
+ * if NULL group is disabled, but accounted
+ */
+struct spear_shirq {
+ void __iomem *base;
+ u32 status_reg;
+ u32 mask_reg;
+ u32 mask;
+ u32 virq_base;
+ u32 nr_irqs;
+ u32 offset;
+ struct irq_chip *irq_chip;
+};
/* spear300 shared irq registers offsets and masks */
#define SPEAR300_INT_ENB_MASK_REG 0x54
#define SPEAR300_INT_STS_MASK_REG 0x58
+static DEFINE_RAW_SPINLOCK(shirq_lock);
+
+static void shirq_irq_mask(struct irq_data *d)
+{
+ struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
+ u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
+ u32 __iomem *reg = shirq->base + shirq->mask_reg;
+
+ raw_spin_lock(&shirq_lock);
+ val = readl(reg) & ~(0x1 << shift);
+ writel(val, reg);
+ raw_spin_unlock(&shirq_lock);
+}
+
+static void shirq_irq_unmask(struct irq_data *d)
+{
+ struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
+ u32 val, shift = d->irq - shirq->virq_base + shirq->offset;
+ u32 __iomem *reg = shirq->base + shirq->mask_reg;
+
+ raw_spin_lock(&shirq_lock);
+ val = readl(reg) | (0x1 << shift);
+ writel(val, reg);
+ raw_spin_unlock(&shirq_lock);
+}
+
+static struct irq_chip shirq_chip = {
+ .name = "spear-shirq",
+ .irq_mask = shirq_irq_mask,
+ .irq_unmask = shirq_irq_unmask,
+};
+
static struct spear_shirq spear300_shirq_ras1 = {
- .irq_nr = 9,
- .irq_bit_off = 0,
- .regs = {
- .enb_reg = SPEAR300_INT_ENB_MASK_REG,
- .status_reg = SPEAR300_INT_STS_MASK_REG,
- .clear_reg = -1,
- },
+ .offset = 0,
+ .nr_irqs = 9,
+ .mask = ((0x1 << 9) - 1) << 0,
+ .irq_chip = &shirq_chip,
+ .status_reg = SPEAR300_INT_STS_MASK_REG,
+ .mask_reg = SPEAR300_INT_ENB_MASK_REG,
};
static struct spear_shirq *spear300_shirq_blocks[] = {
@@ -51,43 +103,35 @@ static struct spear_shirq *spear300_shirq_blocks[] = {
#define SPEAR310_INT_STS_MASK_REG 0x04
static struct spear_shirq spear310_shirq_ras1 = {
- .irq_nr = 8,
- .irq_bit_off = 0,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR310_INT_STS_MASK_REG,
- .clear_reg = -1,
- },
+ .offset = 0,
+ .nr_irqs = 8,
+ .mask = ((0x1 << 8) - 1) << 0,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
};
static struct spear_shirq spear310_shirq_ras2 = {
- .irq_nr = 5,
- .irq_bit_off = 8,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR310_INT_STS_MASK_REG,
- .clear_reg = -1,
- },
+ .offset = 8,
+ .nr_irqs = 5,
+ .mask = ((0x1 << 5) - 1) << 8,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
};
static struct spear_shirq spear310_shirq_ras3 = {
- .irq_nr = 1,
- .irq_bit_off = 13,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR310_INT_STS_MASK_REG,
- .clear_reg = -1,
- },
+ .offset = 13,
+ .nr_irqs = 1,
+ .mask = ((0x1 << 1) - 1) << 13,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
};
static struct spear_shirq spear310_shirq_intrcomm_ras = {
- .irq_nr = 3,
- .irq_bit_off = 14,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR310_INT_STS_MASK_REG,
- .clear_reg = -1,
- },
+ .offset = 14,
+ .nr_irqs = 3,
+ .mask = ((0x1 << 3) - 1) << 14,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
};
static struct spear_shirq *spear310_shirq_blocks[] = {
@@ -102,50 +146,34 @@ static struct spear_shirq *spear310_shirq_blocks[] = {
#define SPEAR320_INT_CLR_MASK_REG 0x04
#define SPEAR320_INT_ENB_MASK_REG 0x08
-static struct spear_shirq spear320_shirq_ras1 = {
- .irq_nr = 3,
- .irq_bit_off = 7,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR320_INT_STS_MASK_REG,
- .clear_reg = SPEAR320_INT_CLR_MASK_REG,
- .reset_to_clear = 1,
- },
+static struct spear_shirq spear320_shirq_ras3 = {
+ .offset = 0,
+ .nr_irqs = 7,
+ .mask = ((0x1 << 7) - 1) << 0,
};
-static struct spear_shirq spear320_shirq_ras2 = {
- .irq_nr = 1,
- .irq_bit_off = 10,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR320_INT_STS_MASK_REG,
- .clear_reg = SPEAR320_INT_CLR_MASK_REG,
- .reset_to_clear = 1,
- },
+static struct spear_shirq spear320_shirq_ras1 = {
+ .offset = 7,
+ .nr_irqs = 3,
+ .mask = ((0x1 << 3) - 1) << 7,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
};
-static struct spear_shirq spear320_shirq_ras3 = {
- .irq_nr = 3,
- .irq_bit_off = 0,
- .invalid_irq = 1,
- .regs = {
- .enb_reg = SPEAR320_INT_ENB_MASK_REG,
- .reset_to_enb = 1,
- .status_reg = SPEAR320_INT_STS_MASK_REG,
- .clear_reg = SPEAR320_INT_CLR_MASK_REG,
- .reset_to_clear = 1,
- },
+static struct spear_shirq spear320_shirq_ras2 = {
+ .offset = 10,
+ .nr_irqs = 1,
+ .mask = ((0x1 << 1) - 1) << 10,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
};
static struct spear_shirq spear320_shirq_intrcomm_ras = {
- .irq_nr = 11,
- .irq_bit_off = 11,
- .regs = {
- .enb_reg = -1,
- .status_reg = SPEAR320_INT_STS_MASK_REG,
- .clear_reg = SPEAR320_INT_CLR_MASK_REG,
- .reset_to_clear = 1,
- },
+ .offset = 11,
+ .nr_irqs = 11,
+ .mask = ((0x1 << 11) - 1) << 11,
+ .irq_chip = &dummy_irq_chip,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
};
static struct spear_shirq *spear320_shirq_blocks[] = {
@@ -155,104 +183,46 @@ static struct spear_shirq *spear320_shirq_blocks[] = {
&spear320_shirq_intrcomm_ras,
};
-static void shirq_irq_mask_unmask(struct irq_data *d, bool mask)
-{
- struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
- u32 val, offset = d->irq - shirq->irq_base;
- unsigned long flags;
-
- if (shirq->regs.enb_reg == -1)
- return;
-
- spin_lock_irqsave(&lock, flags);
- val = readl(shirq->base + shirq->regs.enb_reg);
-
- if (mask ^ shirq->regs.reset_to_enb)
- val &= ~(0x1 << shirq->irq_bit_off << offset);
- else
- val |= 0x1 << shirq->irq_bit_off << offset;
-
- writel(val, shirq->base + shirq->regs.enb_reg);
- spin_unlock_irqrestore(&lock, flags);
-
-}
-
-static void shirq_irq_mask(struct irq_data *d)
-{
- shirq_irq_mask_unmask(d, 1);
-}
-
-static void shirq_irq_unmask(struct irq_data *d)
-{
- shirq_irq_mask_unmask(d, 0);
-}
-
-static struct irq_chip shirq_chip = {
- .name = "spear-shirq",
- .irq_ack = shirq_irq_mask,
- .irq_mask = shirq_irq_mask,
- .irq_unmask = shirq_irq_unmask,
-};
-
static void shirq_handler(unsigned irq, struct irq_desc *desc)
{
- u32 i, j, val, mask, tmp;
- struct irq_chip *chip;
struct spear_shirq *shirq = irq_get_handler_data(irq);
+ u32 pend;
- chip = irq_get_chip(irq);
- chip->irq_ack(&desc->irq_data);
-
- mask = ((0x1 << shirq->irq_nr) - 1) << shirq->irq_bit_off;
- while ((val = readl(shirq->base + shirq->regs.status_reg) &
- mask)) {
-
- val >>= shirq->irq_bit_off;
- for (i = 0, j = 1; i < shirq->irq_nr; i++, j <<= 1) {
-
- if (!(j & val))
- continue;
+ pend = readl(shirq->base + shirq->status_reg) & shirq->mask;
+ pend >>= shirq->offset;
- generic_handle_irq(shirq->irq_base + i);
+ while (pend) {
+ int irq = __ffs(pend);
- /* clear interrupt */
- if (shirq->regs.clear_reg == -1)
- continue;
-
- tmp = readl(shirq->base + shirq->regs.clear_reg);
- if (shirq->regs.reset_to_clear)
- tmp &= ~(j << shirq->irq_bit_off);
- else
- tmp |= (j << shirq->irq_bit_off);
- writel(tmp, shirq->base + shirq->regs.clear_reg);
- }
+ pend &= ~(0x1 << irq);
+ generic_handle_irq(shirq->virq_base + irq);
}
- chip->irq_unmask(&desc->irq_data);
}
-static void __init spear_shirq_register(struct spear_shirq *shirq)
+static void __init spear_shirq_register(struct spear_shirq *shirq,
+ int parent_irq)
{
int i;
- if (shirq->invalid_irq)
+ if (!shirq->irq_chip)
return;
- irq_set_chained_handler(shirq->irq, shirq_handler);
- for (i = 0; i < shirq->irq_nr; i++) {
- irq_set_chip_and_handler(shirq->irq_base + i,
- &shirq_chip, handle_simple_irq);
- set_irq_flags(shirq->irq_base + i, IRQF_VALID);
- irq_set_chip_data(shirq->irq_base + i, shirq);
- }
+ irq_set_chained_handler(parent_irq, shirq_handler);
+ irq_set_handler_data(parent_irq, shirq);
- irq_set_handler_data(shirq->irq, shirq);
+ for (i = 0; i < shirq->nr_irqs; i++) {
+ irq_set_chip_and_handler(shirq->virq_base + i,
+ shirq->irq_chip, handle_simple_irq);
+ set_irq_flags(shirq->virq_base + i, IRQF_VALID);
+ irq_set_chip_data(shirq->virq_base + i, shirq);
+ }
}
static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
struct device_node *np)
{
- int i, irq_base, hwirq = 0, irq_nr = 0;
- static struct irq_domain *shirq_domain;
+ int i, parent_irq, virq_base, hwirq = 0, nr_irqs = 0;
+ struct irq_domain *shirq_domain;
void __iomem *base;
base = of_iomap(np, 0);
@@ -262,15 +232,15 @@ static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
}
for (i = 0; i < block_nr; i++)
- irq_nr += shirq_blocks[i]->irq_nr;
+ nr_irqs += shirq_blocks[i]->nr_irqs;
- irq_base = irq_alloc_descs(-1, 0, irq_nr, 0);
- if (IS_ERR_VALUE(irq_base)) {
+ virq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
+ if (IS_ERR_VALUE(virq_base)) {
pr_err("%s: irq desc alloc failed\n", __func__);
goto err_unmap;
}
- shirq_domain = irq_domain_add_legacy(np, irq_nr, irq_base, 0,
+ shirq_domain = irq_domain_add_legacy(np, nr_irqs, virq_base, 0,
&irq_domain_simple_ops, NULL);
if (WARN_ON(!shirq_domain)) {
pr_warn("%s: irq domain init failed\n", __func__);
@@ -279,41 +249,41 @@ static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
for (i = 0; i < block_nr; i++) {
shirq_blocks[i]->base = base;
- shirq_blocks[i]->irq_base = irq_find_mapping(shirq_domain,
+ shirq_blocks[i]->virq_base = irq_find_mapping(shirq_domain,
hwirq);
- shirq_blocks[i]->irq = irq_of_parse_and_map(np, i);
- spear_shirq_register(shirq_blocks[i]);
- hwirq += shirq_blocks[i]->irq_nr;
+ parent_irq = irq_of_parse_and_map(np, i);
+ spear_shirq_register(shirq_blocks[i], parent_irq);
+ hwirq += shirq_blocks[i]->nr_irqs;
}
return 0;
err_free_desc:
- irq_free_descs(irq_base, irq_nr);
+ irq_free_descs(virq_base, nr_irqs);
err_unmap:
iounmap(base);
return -ENXIO;
}
-int __init spear300_shirq_of_init(struct device_node *np,
- struct device_node *parent)
+static int __init spear300_shirq_of_init(struct device_node *np,
+ struct device_node *parent)
{
return shirq_init(spear300_shirq_blocks,
ARRAY_SIZE(spear300_shirq_blocks), np);
}
IRQCHIP_DECLARE(spear300_shirq, "st,spear300-shirq", spear300_shirq_of_init);
-int __init spear310_shirq_of_init(struct device_node *np,
- struct device_node *parent)
+static int __init spear310_shirq_of_init(struct device_node *np,
+ struct device_node *parent)
{
return shirq_init(spear310_shirq_blocks,
ARRAY_SIZE(spear310_shirq_blocks), np);
}
IRQCHIP_DECLARE(spear310_shirq, "st,spear310-shirq", spear310_shirq_of_init);
-int __init spear320_shirq_of_init(struct device_node *np,
- struct device_node *parent)
+static int __init spear320_shirq_of_init(struct device_node *np,
+ struct device_node *parent)
{
return shirq_init(spear320_shirq_blocks,
ARRAY_SIZE(spear320_shirq_blocks), np);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index f9a87ed2392b..6a2df3297e77 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1260,7 +1260,7 @@ static int __init capinc_tty_init(void)
if (capi_ttyminors <= 0)
capi_ttyminors = CAPINC_NR_PORTS;
- capiminors = kzalloc(sizeof(struct capi_minor *) * capi_ttyminors,
+ capiminors = kzalloc(sizeof(struct capiminor *) * capi_ttyminors,
GFP_KERNEL);
if (!capiminors)
return -ENOMEM;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index c44950d3eb7b..b7ae0a0dd5b6 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -2400,6 +2400,7 @@ allocerr:
error:
freeurbs(cs);
usb_set_intfdata(interface, NULL);
+ usb_put_dev(udev);
gigaset_freecs(cs);
return rc;
}
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 0df6691d045c..8dc791bfaa6f 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -2059,13 +2059,17 @@ static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic)
memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */
l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */
- if (ic->parm.ni1_io.timeout > 0)
- if (!(pc = ni1_new_l3_process(st, -1)))
- { free_invoke_id(st, id);
+ if (ic->parm.ni1_io.timeout > 0) {
+ pc = ni1_new_l3_process(st, -1);
+ if (!pc) {
+ free_invoke_id(st, id);
return (-2);
}
- pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */
- pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */
+ /* remember id */
+ pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id;
+ /* and procedure */
+ pc->prot.ni1.proc = ic->parm.ni1_io.proc;
+ }
if (!(skb = l3_alloc_skb(l)))
{ free_invoke_id(st, id);
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index d9aebbc510cc..94affa5e6f28 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2588,7 +2588,8 @@ isdn_net_new(char *name, struct net_device *master)
printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
return NULL;
}
- netdev->dev = alloc_netdev(sizeof(isdn_net_local), name, _isdn_setup);
+ netdev->dev = alloc_netdev(sizeof(isdn_net_local), name,
+ NET_NAME_UNKNOWN, _isdn_setup);
if (!netdev->dev) {
printk(KERN_WARNING "isdn_net: Could not allocate network device\n");
kfree(netdev);
@@ -2917,8 +2918,8 @@ isdn_net_getcfg(isdn_net_ioctl_cfg *cfg)
cfg->callback = 2;
cfg->cbhup = (lp->flags & ISDN_NET_CBHUP) ? 1 : 0;
cfg->dialmode = lp->flags & ISDN_NET_DIALMODE_MASK;
- cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
- cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
+ cfg->chargehup = (lp->hupflags & ISDN_CHARGEHUP) ? 1 : 0;
+ cfg->ihup = (lp->hupflags & ISDN_INHUP) ? 1 : 0;
cfg->cbdelay = lp->cbdelay;
cfg->dialmax = lp->dialmax;
cfg->triggercps = lp->triggercps;
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 61ac63237446..c4198fa490bf 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -379,12 +379,12 @@ isdn_ppp_release(int min, struct file *file)
#endif
#ifdef CONFIG_IPPP_FILTER
if (is->pass_filter) {
- sk_unattached_filter_destroy(is->pass_filter);
+ bpf_prog_destroy(is->pass_filter);
is->pass_filter = NULL;
}
if (is->active_filter) {
- sk_unattached_filter_destroy(is->active_filter);
+ bpf_prog_destroy(is->active_filter);
is->active_filter = NULL;
}
#endif
@@ -442,7 +442,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
{
struct sock_fprog uprog;
struct sock_filter *code = NULL;
- int len, err;
+ int len;
if (copy_from_user(&uprog, arg, sizeof(uprog)))
return -EFAULT;
@@ -458,12 +458,6 @@ static int get_filter(void __user *arg, struct sock_filter **p)
if (IS_ERR(code))
return PTR_ERR(code);
- err = sk_chk_filter(code, uprog.len);
- if (err) {
- kfree(code);
- return err;
- }
-
*p = code;
return uprog.len;
}
@@ -644,9 +638,14 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
fprog.len = len;
fprog.filter = code;
- if (is->pass_filter)
- sk_unattached_filter_destroy(is->pass_filter);
- err = sk_unattached_filter_create(&is->pass_filter, &fprog);
+ if (is->pass_filter) {
+ bpf_prog_destroy(is->pass_filter);
+ is->pass_filter = NULL;
+ }
+ if (fprog.filter != NULL)
+ err = bpf_prog_create(&is->pass_filter, &fprog);
+ else
+ err = 0;
kfree(code);
return err;
@@ -663,9 +662,14 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
fprog.len = len;
fprog.filter = code;
- if (is->active_filter)
- sk_unattached_filter_destroy(is->active_filter);
- err = sk_unattached_filter_create(&is->active_filter, &fprog);
+ if (is->active_filter) {
+ bpf_prog_destroy(is->active_filter);
+ is->active_filter = NULL;
+ }
+ if (fprog.filter != NULL)
+ err = bpf_prog_create(&is->active_filter, &fprog);
+ else
+ err = 0;
kfree(code);
return err;
@@ -1168,14 +1172,14 @@ isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *
}
if (is->pass_filter
- && SK_RUN_FILTER(is->pass_filter, skb) == 0) {
+ && BPF_PROG_RUN(is->pass_filter, skb) == 0) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: inbound frame filtered.\n");
kfree_skb(skb);
return;
}
if (!(is->active_filter
- && SK_RUN_FILTER(is->active_filter, skb) == 0)) {
+ && BPF_PROG_RUN(is->active_filter, skb) == 0)) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
lp->huptimer = 0;
@@ -1314,14 +1318,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
}
if (ipt->pass_filter
- && SK_RUN_FILTER(ipt->pass_filter, skb) == 0) {
+ && BPF_PROG_RUN(ipt->pass_filter, skb) == 0) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: outbound frame filtered.\n");
kfree_skb(skb);
goto unlock;
}
if (!(ipt->active_filter
- && SK_RUN_FILTER(ipt->active_filter, skb) == 0)) {
+ && BPF_PROG_RUN(ipt->active_filter, skb) == 0)) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
lp->huptimer = 0;
@@ -1511,9 +1515,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
}
drop |= is->pass_filter
- && SK_RUN_FILTER(is->pass_filter, skb) == 0;
+ && BPF_PROG_RUN(is->pass_filter, skb) == 0;
drop |= is->active_filter
- && SK_RUN_FILTER(is->active_filter, skb) == 0;
+ && BPF_PROG_RUN(is->active_filter, skb) == 0;
skb_push(skb, IPPP_MAX_HEADER - 4);
return drop;
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index f02cc506fbfa..4172e22ae7ed 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -1035,14 +1035,14 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
}
ptr->next = NULL;
- ptr->msn = kmalloc(len, GFP_ATOMIC);
+ ptr->msn = kmalloc(len + 1, GFP_ATOMIC);
if (!ptr->msn) {
printk(KERN_WARNING "kmalloc failed\n");
kfree(ptr);
return;
}
- memcpy(ptr->msn, sp, len - 1);
+ memcpy(ptr->msn, sp, len);
ptr->msn[len] = 0;
#ifdef DEBUG
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 8736f69262f9..8c96e2ddf43b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -135,6 +135,13 @@ config LEDS_SUNFIRE
This option enables support for the Left, Middle, and Right
LEDs on the I/O and CPU boards of SunFire UltraSPARC servers.
+config LEDS_IPAQ_MICRO
+ tristate "LED Support for the Compaq iPAQ h3xxx"
+ depends on MFD_IPAQ_MICRO
+ help
+ Choose this option if you want to use the notification LED on
+ Compaq/HP iPAQ h3100 and h3600.
+
config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3c036663f17b..d8cc5f2777de 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o
obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
+obj-$(CONFIG_LEDS_IPAQ_MICRO) += leds-ipaq-micro.o
obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index f37d63cf726b..129729d35478 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -15,10 +15,10 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
-#include <linux/timer.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/leds.h>
+#include <linux/workqueue.h>
#include "leds.h"
static struct class *leds_class;
@@ -97,9 +97,10 @@ static const struct attribute_group *led_groups[] = {
NULL,
};
-static void led_timer_function(unsigned long data)
+static void led_work_function(struct work_struct *ws)
{
- struct led_classdev *led_cdev = (void *)data;
+ struct led_classdev *led_cdev =
+ container_of(ws, struct led_classdev, blink_work.work);
unsigned long brightness;
unsigned long delay;
@@ -143,7 +144,8 @@ static void led_timer_function(unsigned long data)
}
}
- mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
+ queue_delayed_work(system_wq, &led_cdev->blink_work,
+ msecs_to_jiffies(delay));
}
static void set_brightness_delayed(struct work_struct *ws)
@@ -210,8 +212,9 @@ static const struct dev_pm_ops leds_class_dev_pm_ops = {
*/
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
- led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
- "%s", led_cdev->name);
+ led_cdev->dev = device_create_with_groups(leds_class, parent, 0,
+ led_cdev, led_cdev->groups,
+ "%s", led_cdev->name);
if (IS_ERR(led_cdev->dev))
return PTR_ERR(led_cdev->dev);
@@ -230,9 +233,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
- init_timer(&led_cdev->blink_timer);
- led_cdev->blink_timer.function = led_timer_function;
- led_cdev->blink_timer.data = (unsigned long)led_cdev;
+ INIT_DELAYED_WORK(&led_cdev->blink_work, led_work_function);
#ifdef CONFIG_LEDS_TRIGGERS
led_trigger_set_default(led_cdev);
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 71b40d3bf776..4bb116867b88 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/leds.h>
+#include <linux/workqueue.h>
#include "leds.h"
DECLARE_RWSEM(leds_list_lock);
@@ -51,7 +52,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
return;
}
- mod_timer(&led_cdev->blink_timer, jiffies + 1);
+ queue_delayed_work(system_wq, &led_cdev->blink_work, 1);
}
@@ -75,7 +76,7 @@ void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
- del_timer_sync(&led_cdev->blink_timer);
+ cancel_delayed_work_sync(&led_cdev->blink_work);
led_cdev->flags &= ~LED_BLINK_ONESHOT;
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
@@ -90,7 +91,7 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev,
int invert)
{
if ((led_cdev->flags & LED_BLINK_ONESHOT) &&
- timer_pending(&led_cdev->blink_timer))
+ delayed_work_pending(&led_cdev->blink_work))
return;
led_cdev->flags |= LED_BLINK_ONESHOT;
@@ -107,7 +108,7 @@ EXPORT_SYMBOL(led_blink_set_oneshot);
void led_stop_software_blink(struct led_classdev *led_cdev)
{
- del_timer_sync(&led_cdev->blink_timer);
+ cancel_delayed_work_sync(&led_cdev->blink_work);
led_cdev->blink_delay_on = 0;
led_cdev->blink_delay_off = 0;
}
@@ -116,7 +117,7 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink);
void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- /* delay brightness setting if need to stop soft-blink timer */
+ /* delay brightness setting if need to stop soft-blink work */
if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
led_cdev->delayed_set_value = brightness;
schedule_work(&led_cdev->set_brightness_work);
diff --git a/drivers/leds/leds-ipaq-micro.c b/drivers/leds/leds-ipaq-micro.c
new file mode 100644
index 000000000000..3776f516cd88
--- /dev/null
+++ b/drivers/leds/leds-ipaq-micro.c
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ *
+ * h3xxx atmel micro companion support, notification LED subdevice
+ *
+ * Author : Linus Walleij <linus.walleij@linaro.org>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ipaq-micro.h>
+#include <linux/leds.h>
+
+#define LED_YELLOW 0x00
+#define LED_GREEN 0x01
+
+#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
+#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
+#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
+
+static void micro_leds_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
+ /*
+ * In this message:
+ * Byte 0 = LED color: 0 = yellow, 1 = green
+ * yellow LED is always ~30 blinks per minute
+ * Byte 1 = duration (flags?) appears to be ignored
+ * Byte 2 = green ontime in 1/10 sec (deciseconds)
+ * 1 = 1/10 second
+ * 0 = 256/10 second
+ * Byte 3 = green offtime in 1/10 sec (deciseconds)
+ * 1 = 1/10 second
+ * 0 = 256/10 seconds
+ */
+ struct ipaq_micro_msg msg = {
+ .id = MSG_NOTIFY_LED,
+ .tx_len = 4,
+ };
+
+ msg.tx_data[0] = LED_GREEN;
+ msg.tx_data[1] = 0;
+ if (value) {
+ msg.tx_data[2] = 0; /* Duty cycle 256 */
+ msg.tx_data[3] = 1;
+ } else {
+ msg.tx_data[2] = 1;
+ msg.tx_data[3] = 0; /* Duty cycle 256 */
+ }
+ ipaq_micro_tx_msg_sync(micro, &msg);
+}
+
+/* Maximum duty cycle in ms 256/10 sec = 25600 ms */
+#define IPAQ_LED_MAX_DUTY 25600
+
+static int micro_leds_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
+ /*
+ * In this message:
+ * Byte 0 = LED color: 0 = yellow, 1 = green
+ * yellow LED is always ~30 blinks per minute
+ * Byte 1 = duration (flags?) appears to be ignored
+ * Byte 2 = green ontime in 1/10 sec (deciseconds)
+ * 1 = 1/10 second
+ * 0 = 256/10 second
+ * Byte 3 = green offtime in 1/10 sec (deciseconds)
+ * 1 = 1/10 second
+ * 0 = 256/10 seconds
+ */
+ struct ipaq_micro_msg msg = {
+ .id = MSG_NOTIFY_LED,
+ .tx_len = 4,
+ };
+
+ msg.tx_data[0] = LED_GREEN;
+ if (*delay_on > IPAQ_LED_MAX_DUTY ||
+ *delay_off > IPAQ_LED_MAX_DUTY)
+ return -EINVAL;
+
+ if (*delay_on == 0 && *delay_off == 0) {
+ *delay_on = 100;
+ *delay_off = 100;
+ }
+
+ msg.tx_data[1] = 0;
+ if (*delay_on >= IPAQ_LED_MAX_DUTY)
+ msg.tx_data[2] = 0;
+ else
+ msg.tx_data[2] = (u8) DIV_ROUND_CLOSEST(*delay_on, 100);
+ if (*delay_off >= IPAQ_LED_MAX_DUTY)
+ msg.tx_data[3] = 0;
+ else
+ msg.tx_data[3] = (u8) DIV_ROUND_CLOSEST(*delay_off, 100);
+ return ipaq_micro_tx_msg_sync(micro, &msg);
+}
+
+static struct led_classdev micro_led = {
+ .name = "led-ipaq-micro",
+ .brightness_set = micro_leds_brightness_set,
+ .blink_set = micro_leds_blink_set,
+ .flags = LED_CORE_SUSPENDRESUME,
+};
+
+static int micro_leds_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = led_classdev_register(&pdev->dev, &micro_led);
+ if (ret) {
+ dev_err(&pdev->dev, "registering led failed: %d\n", ret);
+ return ret;
+ }
+ dev_info(&pdev->dev, "iPAQ micro notification LED driver\n");
+
+ return 0;
+}
+
+static int micro_leds_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&micro_led);
+ return 0;
+}
+
+static struct platform_driver micro_leds_device_driver = {
+ .driver = {
+ .name = "ipaq-micro-leds",
+ },
+ .probe = micro_leds_probe,
+ .remove = micro_leds_remove,
+};
+module_platform_driver(micro_leds_device_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("driver for iPAQ Atmel micro leds");
+MODULE_ALIAS("platform:ipaq-micro-leds");
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 652368c2ea9a..91325de3cd33 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -400,6 +400,12 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
}
static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
+static struct attribute *lm3530_attrs[] = {
+ &dev_attr_mode.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(lm3530);
+
static int lm3530_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -436,6 +442,7 @@ static int lm3530_probe(struct i2c_client *client,
drvdata->led_dev.name = LM3530_LED_DEV;
drvdata->led_dev.brightness_set = lm3530_brightness_set;
drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
+ drvdata->led_dev.groups = lm3530_groups;
i2c_set_clientdata(client, drvdata);
@@ -461,26 +468,13 @@ static int lm3530_probe(struct i2c_client *client,
return err;
}
- err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
- if (err < 0) {
- dev_err(&client->dev, "File device creation failed: %d\n", err);
- err = -ENODEV;
- goto err_create_file;
- }
-
return 0;
-
-err_create_file:
- led_classdev_unregister(&drvdata->led_dev);
- return err;
}
static int lm3530_remove(struct i2c_client *client)
{
struct lm3530_data *drvdata = i2c_get_clientdata(client);
- device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
-
lm3530_led_disable(drvdata);
led_classdev_unregister(&drvdata->led_dev);
return 0;
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index e2c642c1169b..cbf61a40137d 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -645,6 +645,11 @@ static struct attribute_group lm3533_led_attribute_group = {
.attrs = lm3533_led_attributes
};
+static const struct attribute_group *lm3533_led_attribute_groups[] = {
+ &lm3533_led_attribute_group,
+ NULL
+};
+
static int lm3533_led_setup(struct lm3533_led *led,
struct lm3533_led_platform_data *pdata)
{
@@ -692,6 +697,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
led->cdev.brightness_get = lm3533_led_get;
led->cdev.blink_set = lm3533_led_blink_set;
led->cdev.brightness = LED_OFF;
+ led->cdev.groups = lm3533_led_attribute_groups,
led->id = pdev->id;
mutex_init(&led->mutex);
@@ -715,25 +721,16 @@ static int lm3533_led_probe(struct platform_device *pdev)
led->cb.dev = led->cdev.dev;
- ret = sysfs_create_group(&led->cdev.dev->kobj,
- &lm3533_led_attribute_group);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create sysfs attributes\n");
- goto err_unregister;
- }
-
ret = lm3533_led_setup(led, pdata);
if (ret)
- goto err_sysfs_remove;
+ goto err_unregister;
ret = lm3533_ctrlbank_enable(&led->cb);
if (ret)
- goto err_sysfs_remove;
+ goto err_unregister;
return 0;
-err_sysfs_remove:
- sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
err_unregister:
led_classdev_unregister(&led->cdev);
flush_work(&led->work);
@@ -748,7 +745,6 @@ static int lm3533_led_remove(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s\n", __func__);
lm3533_ctrlbank_disable(&led->cb);
- sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
led_classdev_unregister(&led->cdev);
flush_work(&led->work);
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
index 591eb5e58ae3..f5112cb2d991 100644
--- a/drivers/leds/leds-lm355x.c
+++ b/drivers/leds/leds-lm355x.c
@@ -413,6 +413,12 @@ out:
static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);
+static struct attribute *lm355x_indicator_attrs[] = {
+ &dev_attr_pattern.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(lm355x_indicator);
+
static const struct regmap_config lm355x_regmap = {
.reg_bits = 8,
.val_bits = 8,
@@ -501,25 +507,18 @@ static int lm355x_probe(struct i2c_client *client,
else
chip->cdev_indicator.max_brightness = 8;
chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
+ /* indicator pattern control only for LM3556 */
+ if (id->driver_data == CHIP_LM3556)
+ chip->cdev_indicator.groups = lm355x_indicator_groups;
err = led_classdev_register((struct device *)
&client->dev, &chip->cdev_indicator);
if (err < 0)
goto err_create_indicator_file;
- /* indicator pattern control only for LM3554 */
- if (id->driver_data == CHIP_LM3556) {
- err =
- device_create_file(chip->cdev_indicator.dev,
- &dev_attr_pattern);
- if (err < 0)
- goto err_create_pattern_file;
- }
dev_info(&client->dev, "%s is initialized\n",
lm355x_name[id->driver_data]);
return 0;
-err_create_pattern_file:
- led_classdev_unregister(&chip->cdev_indicator);
err_create_indicator_file:
led_classdev_unregister(&chip->cdev_torch);
err_create_torch_file:
@@ -534,8 +533,6 @@ static int lm355x_remove(struct i2c_client *client)
struct lm355x_reg_data *preg = chip->regs;
regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
- if (chip->type == CHIP_LM3556)
- device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
led_classdev_unregister(&chip->cdev_indicator);
flush_work(&chip->work_indicator);
led_classdev_unregister(&chip->cdev_torch);
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
index ceb6b3cde6fe..d3dec0132769 100644
--- a/drivers/leds/leds-lm3642.c
+++ b/drivers/leds/leds-lm3642.c
@@ -313,6 +313,18 @@ static const struct regmap_config lm3642_regmap = {
.max_register = REG_MAX,
};
+static struct attribute *lm3642_flash_attrs[] = {
+ &dev_attr_strobe_pin.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(lm3642_flash);
+
+static struct attribute *lm3642_torch_attrs[] = {
+ &dev_attr_torch_pin.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(lm3642_torch);
+
static int lm3642_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -364,17 +376,13 @@ static int lm3642_probe(struct i2c_client *client,
chip->cdev_flash.max_brightness = 16;
chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
chip->cdev_flash.default_trigger = "flash";
+ chip->cdev_flash.groups = lm3642_flash_groups,
err = led_classdev_register((struct device *)
&client->dev, &chip->cdev_flash);
if (err < 0) {
dev_err(chip->dev, "failed to register flash\n");
goto err_out;
}
- err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
- if (err < 0) {
- dev_err(chip->dev, "failed to create strobe-pin file\n");
- goto err_create_flash_pin_file;
- }
/* torch */
INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
@@ -382,17 +390,13 @@ static int lm3642_probe(struct i2c_client *client,
chip->cdev_torch.max_brightness = 8;
chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
chip->cdev_torch.default_trigger = "torch";
+ chip->cdev_torch.groups = lm3642_torch_groups,
err = led_classdev_register((struct device *)
&client->dev, &chip->cdev_torch);
if (err < 0) {
dev_err(chip->dev, "failed to register torch\n");
goto err_create_torch_file;
}
- err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
- if (err < 0) {
- dev_err(chip->dev, "failed to create torch-pin file\n");
- goto err_create_torch_pin_file;
- }
/* indicator */
INIT_WORK(&chip->work_indicator,
@@ -411,12 +415,8 @@ static int lm3642_probe(struct i2c_client *client,
return 0;
err_create_indicator_file:
- device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
-err_create_torch_pin_file:
led_classdev_unregister(&chip->cdev_torch);
err_create_torch_file:
- device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
-err_create_flash_pin_file:
led_classdev_unregister(&chip->cdev_flash);
err_out:
return err;
@@ -428,10 +428,8 @@ static int lm3642_remove(struct i2c_client *client)
led_classdev_unregister(&chip->cdev_indicator);
flush_work(&chip->work_indicator);
- device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
led_classdev_unregister(&chip->cdev_torch);
flush_work(&chip->work_torch);
- device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
led_classdev_unregister(&chip->cdev_flash);
flush_work(&chip->work_flash);
regmap_write(chip->regmap, REG_ENABLE, 0);
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 88317b4f7bf3..77c26bc32eed 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -127,15 +127,12 @@ static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current,
lp55xx_store_current);
static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL);
-static struct attribute *lp55xx_led_attributes[] = {
+static struct attribute *lp55xx_led_attrs[] = {
&dev_attr_led_current.attr,
&dev_attr_max_current.attr,
NULL,
};
-
-static struct attribute_group lp55xx_led_attr_group = {
- .attrs = lp55xx_led_attributes
-};
+ATTRIBUTE_GROUPS(lp55xx_led);
static void lp55xx_set_brightness(struct led_classdev *cdev,
enum led_brightness brightness)
@@ -176,6 +173,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
}
led->cdev.brightness_set = lp55xx_set_brightness;
+ led->cdev.groups = lp55xx_led_groups;
if (pdata->led_config[chan].name) {
led->cdev.name = pdata->led_config[chan].name;
@@ -185,24 +183,12 @@ static int lp55xx_init_led(struct lp55xx_led *led,
led->cdev.name = name;
}
- /*
- * register led class device for each channel and
- * add device attributes
- */
-
ret = led_classdev_register(dev, &led->cdev);
if (ret) {
dev_err(dev, "led register err: %d\n", ret);
return ret;
}
- ret = sysfs_create_group(&led->cdev.dev->kobj, &lp55xx_led_attr_group);
- if (ret) {
- dev_err(dev, "led sysfs err: %d\n", ret);
- led_classdev_unregister(&led->cdev);
- return ret;
- }
-
return 0;
}
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
index f449a8bdddc7..607bc2755aba 100644
--- a/drivers/leds/leds-max8997.c
+++ b/drivers/leds/leds-max8997.c
@@ -229,6 +229,12 @@ static ssize_t max8997_led_store_mode(struct device *dev,
static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode);
+static struct attribute *max8997_attrs[] = {
+ &dev_attr_mode.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(max8997);
+
static int max8997_led_probe(struct platform_device *pdev)
{
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
@@ -253,6 +259,7 @@ static int max8997_led_probe(struct platform_device *pdev)
led->cdev.brightness_set = max8997_led_brightness_set;
led->cdev.flags |= LED_CORE_SUSPENDRESUME;
led->cdev.brightness = 0;
+ led->cdev.groups = max8997_groups;
led->iodev = iodev;
/* initialize mode and brightness according to platform_data */
@@ -281,14 +288,6 @@ static int max8997_led_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- ret = device_create_file(led->cdev.dev, &dev_attr_mode);
- if (ret != 0) {
- dev_err(&pdev->dev,
- "failed to create file: %d\n", ret);
- led_classdev_unregister(&led->cdev);
- return ret;
- }
-
return 0;
}
@@ -296,7 +295,6 @@ static int max8997_led_remove(struct platform_device *pdev)
{
struct max8997_led *led = platform_get_drvdata(pdev);
- device_remove_file(led->cdev.dev, &dev_attr_mode);
led_classdev_unregister(&led->cdev);
return 0;
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index e97f443a6e07..64fde485dcaa 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -293,10 +293,14 @@ static ssize_t netxbig_led_sata_show(struct device *dev,
static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
+static struct attribute *netxbig_led_attrs[] = {
+ &dev_attr_sata.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(netxbig_led);
+
static void delete_netxbig_led(struct netxbig_led_data *led_dat)
{
- if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
- device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
led_classdev_unregister(&led_dat->cdev);
}
@@ -306,7 +310,6 @@ create_netxbig_led(struct platform_device *pdev,
const struct netxbig_led *template)
{
struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
- int ret;
spin_lock_init(&led_dat->lock);
led_dat->gpio_ext = pdata->gpio_ext;
@@ -327,6 +330,12 @@ create_netxbig_led(struct platform_device *pdev,
led_dat->sata = 0;
led_dat->cdev.brightness = LED_OFF;
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ /*
+ * If available, expose the SATA activity blink capability through
+ * a "sata" sysfs attribute.
+ */
+ if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
+ led_dat->cdev.groups = netxbig_led_groups;
led_dat->mode_addr = template->mode_addr;
led_dat->mode_val = template->mode_val;
led_dat->bright_addr = template->bright_addr;
@@ -334,21 +343,7 @@ create_netxbig_led(struct platform_device *pdev,
led_dat->timer = pdata->timer;
led_dat->num_timer = pdata->num_timer;
- ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
- if (ret < 0)
- return ret;
-
- /*
- * If available, expose the SATA activity blink capability through
- * a "sata" sysfs attribute.
- */
- if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
- ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
- if (ret)
- led_classdev_unregister(&led_dat->cdev);
- }
-
- return ret;
+ return led_classdev_register(&pdev->dev, &led_dat->cdev);
}
static int netxbig_led_probe(struct platform_device *pdev)
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index efa625883c83..231993d1fe21 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -185,6 +185,12 @@ static ssize_t ns2_led_sata_show(struct device *dev,
static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
+static struct attribute *ns2_led_attrs[] = {
+ &dev_attr_sata.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(ns2_led);
+
static int
create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
const struct ns2_led *template)
@@ -219,6 +225,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
led_dat->cdev.blink_set = NULL;
led_dat->cdev.brightness_set = ns2_led_set;
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ led_dat->cdev.groups = ns2_led_groups;
led_dat->cmd = template->cmd;
led_dat->slow = template->slow;
@@ -235,20 +242,11 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
if (ret < 0)
return ret;
- ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
- if (ret < 0)
- goto err_free_cdev;
-
return 0;
-
-err_free_cdev:
- led_classdev_unregister(&led_dat->cdev);
- return ret;
}
static void delete_ns2_led(struct ns2_led_data *led_dat)
{
- device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
led_classdev_unregister(&led_dat->cdev);
}
diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index 82589c0a5689..f110b4c456ba 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -12,7 +12,7 @@
* directory of this archive for more details.
*
* LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
- * LED driver for the PCA9634 I2C LED driver (7-bit slave address set by hw.)
+ * LED driver for the PCA9634/5 I2C LED driver (7-bit slave address set by hw.)
*
* Note that hardware blinking violates the leds infrastructure driver
* interface since the hardware only supports blinking all LEDs with the
@@ -52,6 +52,7 @@
enum pca963x_type {
pca9633,
pca9634,
+ pca9635,
};
struct pca963x_chipdef {
@@ -74,6 +75,12 @@ static struct pca963x_chipdef pca963x_chipdefs[] = {
.ledout_base = 0xc,
.n_leds = 8,
},
+ [pca9635] = {
+ .grppwm = 0x12,
+ .grpfreq = 0x13,
+ .ledout_base = 0x14,
+ .n_leds = 16,
+ },
};
/* Total blink period in milliseconds */
@@ -84,6 +91,7 @@ static const struct i2c_device_id pca963x_id[] = {
{ "pca9632", pca9633 },
{ "pca9633", pca9633 },
{ "pca9634", pca9634 },
+ { "pca9635", pca9635 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pca963x_id);
@@ -107,7 +115,7 @@ struct pca963x_led {
struct work_struct work;
enum led_brightness brightness;
struct led_classdev led_cdev;
- int led_num; /* 0 .. 7 potentially */
+ int led_num; /* 0 .. 15 potentially */
enum pca963x_cmd cmd;
char name[32];
u8 gdc;
@@ -321,6 +329,7 @@ static const struct of_device_id of_pca963x_match[] = {
{ .compatible = "nxp,pca9632", },
{ .compatible = "nxp,pca9633", },
{ .compatible = "nxp,pca9634", },
+ { .compatible = "nxp,pca9635", },
{},
};
#else
@@ -375,9 +384,8 @@ static int pca963x_probe(struct i2c_client *client,
pca963x_chip->leds = pca963x;
/* Turn off LEDs by default*/
- i2c_smbus_write_byte_data(client, chip->ledout_base, 0x00);
- if (chip->n_leds > 4)
- i2c_smbus_write_byte_data(client, chip->ledout_base + 1, 0x00);
+ for (i = 0; i < chip->n_leds / 4; i++)
+ i2c_smbus_write_byte_data(client, chip->ledout_base + i, 0x00);
for (i = 0; i < chip->n_leds; i++) {
pca963x[i].led_num = i;
@@ -415,9 +423,13 @@ static int pca963x_probe(struct i2c_client *client,
/* Disable LED all-call address and set normal mode */
i2c_smbus_write_byte_data(client, PCA963X_MODE1, 0x00);
- /* Configure output: open-drain or totem pole (push-pull) */
- if (pdata && pdata->outdrv == PCA963X_OPEN_DRAIN)
- i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01);
+ if (pdata) {
+ /* Configure output: open-drain or totem pole (push-pull) */
+ if (pdata->outdrv == PCA963X_OPEN_DRAIN)
+ i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01);
+ else
+ i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x05);
+ }
return 0;
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 2eb3ef62962b..046cb7008745 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -469,6 +469,12 @@ static ssize_t nas_led_blink_store(struct device *dev,
static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store);
+static struct attribute *nasgpio_led_attrs[] = {
+ &dev_attr_blink.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(nasgpio_led);
+
static int register_nasgpio_led(int led_nr)
{
int ret;
@@ -481,20 +487,18 @@ static int register_nasgpio_led(int led_nr)
led->brightness = LED_FULL;
led->brightness_set = nasgpio_led_set_brightness;
led->blink_set = nasgpio_led_set_blink;
+ led->groups = nasgpio_led_groups;
ret = led_classdev_register(&nas_gpio_pci_dev->dev, led);
if (ret)
return ret;
- ret = device_create_file(led->dev, &dev_attr_blink);
- if (ret)
- led_classdev_unregister(led);
- return ret;
+
+ return 0;
}
static void unregister_nasgpio_led(int led_nr)
{
struct led_classdev *led = get_classdev_for_led_nr(led_nr);
led_classdev_unregister(led);
- device_remove_file(led->dev, &dev_attr_blink);
}
/*
* module load/initialization
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index e72c974142d0..1b71e0701002 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -219,6 +219,12 @@ static ssize_t wm831x_status_src_store(struct device *dev,
static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store);
+static struct attribute *wm831x_status_attrs[] = {
+ &dev_attr_src.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(wm831x_status);
+
static int wm831x_status_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -232,8 +238,7 @@ static int wm831x_status_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) {
dev_err(&pdev->dev, "No register resource\n");
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status),
@@ -284,31 +289,21 @@ static int wm831x_status_probe(struct platform_device *pdev)
drvdata->cdev.default_trigger = pdata.default_trigger;
drvdata->cdev.brightness_set = wm831x_status_set;
drvdata->cdev.blink_set = wm831x_status_blink_set;
+ drvdata->cdev.groups = wm831x_status_groups;
ret = led_classdev_register(wm831x->dev, &drvdata->cdev);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
- goto err_led;
+ return ret;
}
- ret = device_create_file(drvdata->cdev.dev, &dev_attr_src);
- if (ret != 0)
- dev_err(&pdev->dev,
- "No source control for LED: %d\n", ret);
-
return 0;
-
-err_led:
- led_classdev_unregister(&drvdata->cdev);
-err:
- return ret;
}
static int wm831x_status_remove(struct platform_device *pdev)
{
struct wm831x_status *drvdata = platform_get_drvdata(pdev);
- device_remove_file(drvdata->cdev.dev, &dev_attr_src);
led_classdev_unregister(&drvdata->cdev);
return 0;
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 0bf1e4edf04d..6590558d1d31 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -42,7 +42,6 @@ DEFINE_MUTEX(lguest_lock);
static __init int map_switcher(void)
{
int i, err;
- struct page **pagep;
/*
* Map the Switcher in to high memory.
@@ -110,11 +109,9 @@ static __init int map_switcher(void)
* 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 pages), and a pointer to our
- * array of struct pages. It increments that pointer, but we don't
- * care.
+ * array of struct pages.
*/
- pagep = lg_switcher_pages;
- err = map_vm_area(switcher_vma, PAGE_KERNEL_EXEC, &pagep);
+ err = map_vm_area(switcher_vma, PAGE_KERNEL_EXEC, lg_switcher_pages);
if (err) {
printk("lguest: map_vm_area failed: %i\n", err);
goto free_vma;
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index b1d91170ded0..6f68537c93ce 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -110,13 +110,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
}
-static int pmu_backlight_get_brightness(struct backlight_device *bd)
-{
- return bd->props.brightness;
-}
-
static const struct backlight_ops pmu_backlight_data = {
- .get_brightness = pmu_backlight_get_brightness,
.update_status = pmu_backlight_update_status,
};
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 4e84095833db..ab472c557d18 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -615,16 +615,6 @@ static void write_endio(struct bio *bio, int error)
}
/*
- * This function is called when wait_on_bit is actually waiting.
- */
-static int do_io_schedule(void *word)
-{
- io_schedule();
-
- return 0;
-}
-
-/*
* Initiate a write on a dirty buffer, but don't wait for it.
*
* - If the buffer is not dirty, exit.
@@ -640,8 +630,7 @@ static void __write_dirty_buffer(struct dm_buffer *b,
return;
clear_bit(B_DIRTY, &b->state);
- wait_on_bit_lock(&b->state, B_WRITING,
- do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_lock_io(&b->state, B_WRITING, TASK_UNINTERRUPTIBLE);
if (!write_list)
submit_io(b, WRITE, b->block, write_endio);
@@ -675,9 +664,9 @@ static void __make_buffer_clean(struct dm_buffer *b)
if (!b->state) /* fast case */
return;
- wait_on_bit(&b->state, B_READING, do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE);
__write_dirty_buffer(b, NULL);
- wait_on_bit(&b->state, B_WRITING, do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_WRITING, TASK_UNINTERRUPTIBLE);
}
/*
@@ -1030,7 +1019,7 @@ static void *new_read(struct dm_bufio_client *c, sector_t block,
if (need_submit)
submit_io(b, READ, b->block, read_endio);
- wait_on_bit(&b->state, B_READING, do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE);
if (b->read_error) {
int error = b->read_error;
@@ -1209,15 +1198,13 @@ again:
dropped_lock = 1;
b->hold_count++;
dm_bufio_unlock(c);
- wait_on_bit(&b->state, B_WRITING,
- do_io_schedule,
- TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_WRITING,
+ TASK_UNINTERRUPTIBLE);
dm_bufio_lock(c);
b->hold_count--;
} else
- wait_on_bit(&b->state, B_WRITING,
- do_io_schedule,
- TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_WRITING,
+ TASK_UNINTERRUPTIBLE);
}
if (!test_bit(B_DIRTY, &b->state) &&
@@ -1321,15 +1308,15 @@ retry:
__write_dirty_buffer(b, NULL);
if (b->hold_count == 1) {
- wait_on_bit(&b->state, B_WRITING,
- do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_WRITING,
+ TASK_UNINTERRUPTIBLE);
set_bit(B_DIRTY, &b->state);
__unlink_buffer(b);
__link_buffer(b, new_block, LIST_DIRTY);
} else {
sector_t old_block;
- wait_on_bit_lock(&b->state, B_WRITING,
- do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_lock_io(&b->state, B_WRITING,
+ TASK_UNINTERRUPTIBLE);
/*
* Relink buffer to "new_block" so that write_callback
* sees "new_block" as a block number.
@@ -1341,8 +1328,8 @@ retry:
__unlink_buffer(b);
__link_buffer(b, new_block, b->list_mode);
submit_io(b, WRITE, new_block, write_endio);
- wait_on_bit(&b->state, B_WRITING,
- do_io_schedule, TASK_UNINTERRUPTIBLE);
+ wait_on_bit_io(&b->state, B_WRITING,
+ TASK_UNINTERRUPTIBLE);
__unlink_buffer(b);
__link_buffer(b, old_block, b->list_mode);
}
@@ -1541,7 +1528,7 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign
BUG_ON(block_size < 1 << SECTOR_SHIFT ||
(block_size & (block_size - 1)));
- c = kmalloc(sizeof(*c), GFP_KERNEL);
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
r = -ENOMEM;
goto bad_client;
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index 4ead4ba60656..d2899e7eb3aa 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -425,6 +425,15 @@ static int __open_metadata(struct dm_cache_metadata *cmd)
disk_super = dm_block_data(sblock);
+ /* Verify the data block size hasn't changed */
+ if (le32_to_cpu(disk_super->data_block_size) != cmd->data_block_size) {
+ DMERR("changing the data block size (from %u to %llu) is not supported",
+ le32_to_cpu(disk_super->data_block_size),
+ (unsigned long long)cmd->data_block_size);
+ r = -EINVAL;
+ goto bad;
+ }
+
r = __check_incompat_features(disk_super, cmd);
if (r < 0)
goto bad;
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 5f054c44b485..2c63326638b6 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -231,7 +231,7 @@ struct cache {
/*
* cache_size entries, dirty if set
*/
- dm_cblock_t nr_dirty;
+ atomic_t nr_dirty;
unsigned long *dirty_bitset;
/*
@@ -492,7 +492,7 @@ static bool is_dirty(struct cache *cache, dm_cblock_t b)
static void set_dirty(struct cache *cache, dm_oblock_t oblock, dm_cblock_t cblock)
{
if (!test_and_set_bit(from_cblock(cblock), cache->dirty_bitset)) {
- cache->nr_dirty = to_cblock(from_cblock(cache->nr_dirty) + 1);
+ atomic_inc(&cache->nr_dirty);
policy_set_dirty(cache->policy, oblock);
}
}
@@ -501,8 +501,7 @@ static void clear_dirty(struct cache *cache, dm_oblock_t oblock, dm_cblock_t cbl
{
if (test_and_clear_bit(from_cblock(cblock), cache->dirty_bitset)) {
policy_clear_dirty(cache->policy, oblock);
- cache->nr_dirty = to_cblock(from_cblock(cache->nr_dirty) - 1);
- if (!from_cblock(cache->nr_dirty))
+ if (atomic_dec_return(&cache->nr_dirty) == 0)
dm_table_event(cache->ti->table);
}
}
@@ -2269,7 +2268,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
atomic_set(&cache->quiescing_ack, 0);
r = -ENOMEM;
- cache->nr_dirty = 0;
+ atomic_set(&cache->nr_dirty, 0);
cache->dirty_bitset = alloc_bitset(from_cblock(cache->cache_size));
if (!cache->dirty_bitset) {
*error = "could not allocate dirty bitset";
@@ -2808,7 +2807,7 @@ static void cache_status(struct dm_target *ti, status_type_t type,
residency = policy_residency(cache->policy);
- DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %llu ",
+ DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %lu ",
(unsigned)(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT),
(unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
(unsigned long long)nr_blocks_metadata,
@@ -2821,7 +2820,7 @@ static void cache_status(struct dm_target *ti, status_type_t type,
(unsigned) atomic_read(&cache->stats.write_miss),
(unsigned) atomic_read(&cache->stats.demotion),
(unsigned) atomic_read(&cache->stats.promotion),
- (unsigned long long) from_cblock(cache->nr_dirty));
+ (unsigned long) atomic_read(&cache->nr_dirty));
if (writethrough_mode(&cache->features))
DMEMIT("1 writethrough ");
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 53b213226c01..4cba2d808afb 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
+ * Copyright (C) 2003 Jana Saout <jana@saout.de>
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013 Milan Broz <gmazyland@gmail.com>
@@ -1996,6 +1996,6 @@ static void __exit dm_crypt_exit(void)
module_init(dm_crypt_init);
module_exit(dm_crypt_exit);
-MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
+MODULE_AUTHOR("Jana Saout <jana@saout.de>");
MODULE_DESCRIPTION(DM_NAME " target for transparent encryption / decryption");
MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 3842ac738f98..db404a0f7e2c 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -10,6 +10,7 @@
#include <linux/device-mapper.h>
#include <linux/bio.h>
+#include <linux/completion.h>
#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/sched.h>
@@ -32,7 +33,7 @@ struct dm_io_client {
struct io {
unsigned long error_bits;
atomic_t count;
- struct task_struct *sleeper;
+ struct completion *wait;
struct dm_io_client *client;
io_notify_fn callback;
void *context;
@@ -121,8 +122,8 @@ static void dec_count(struct io *io, unsigned int region, int error)
invalidate_kernel_vmap_range(io->vma_invalidate_address,
io->vma_invalidate_size);
- if (io->sleeper)
- wake_up_process(io->sleeper);
+ if (io->wait)
+ complete(io->wait);
else {
unsigned long r = io->error_bits;
@@ -387,6 +388,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
*/
volatile char io_[sizeof(struct io) + __alignof__(struct io) - 1];
struct io *io = (struct io *)PTR_ALIGN(&io_, __alignof__(struct io));
+ DECLARE_COMPLETION_ONSTACK(wait);
if (num_regions > 1 && (rw & RW_MASK) != WRITE) {
WARN_ON(1);
@@ -395,7 +397,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
io->error_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
- io->sleeper = current;
+ io->wait = &wait;
io->client = client;
io->vma_invalidate_address = dp->vma_invalidate_address;
@@ -403,15 +405,7 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
dispatch_io(rw, num_regions, where, dp, io, 1);
- while (1) {
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- if (!atomic_read(&io->count))
- break;
-
- io_schedule();
- }
- set_current_state(TASK_RUNNING);
+ wait_for_completion_io(&wait);
if (error_bits)
*error_bits = io->error_bits;
@@ -434,7 +428,7 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,
io = mempool_alloc(client->pool, GFP_NOIO);
io->error_bits = 0;
atomic_set(&io->count, 1); /* see dispatch_io() */
- io->sleeper = NULL;
+ io->wait = NULL;
io->client = client;
io->callback = fn;
io->context = context;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 3f6fd9d33ba3..f4167b013d99 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1611,8 +1611,9 @@ static int multipath_busy(struct dm_target *ti)
spin_lock_irqsave(&m->lock, flags);
- /* pg_init in progress, requeue until done */
- if (!pg_ready(m)) {
+ /* pg_init in progress or no paths available */
+ if (m->pg_init_in_progress ||
+ (!m->nr_valid_paths && m->queue_if_no_path)) {
busy = 1;
goto out;
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 5bd2290cfb1e..864b03f47727 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1032,21 +1032,13 @@ static void start_merge(struct dm_snapshot *s)
snapshot_merge_next_chunks(s);
}
-static int wait_schedule(void *ptr)
-{
- schedule();
-
- return 0;
-}
-
/*
* Stop the merging process and wait until it finishes.
*/
static void stop_merge(struct dm_snapshot *s)
{
set_bit(SHUTDOWN_MERGE, &s->state_bits);
- wait_on_bit(&s->state_bits, RUNNING_MERGE, wait_schedule,
- TASK_UNINTERRUPTIBLE);
+ wait_on_bit(&s->state_bits, RUNNING_MERGE, TASK_UNINTERRUPTIBLE);
clear_bit(SHUTDOWN_MERGE, &s->state_bits);
}
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index b086a945edcb..e9d33ad59df5 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -613,6 +613,15 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
disk_super = dm_block_data(sblock);
+ /* Verify the data block size hasn't changed */
+ if (le32_to_cpu(disk_super->data_block_size) != pmd->data_block_size) {
+ DMERR("changing the data block size (from %u to %llu) is not supported",
+ le32_to_cpu(disk_super->data_block_size),
+ (unsigned long long)pmd->data_block_size);
+ r = -EINVAL;
+ goto bad_unlock_sblock;
+ }
+
r = __check_incompat_features(disk_super, pmd);
if (r < 0)
goto bad_unlock_sblock;
diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c
index c99003e0d47a..b9a64bbce304 100644
--- a/drivers/md/dm-zero.c
+++ b/drivers/md/dm-zero.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
+ * Copyright (C) 2003 Jana Saout <jana@saout.de>
*
* This file is released under the GPL.
*/
@@ -79,6 +79,6 @@ static void __exit dm_zero_exit(void)
module_init(dm_zero_init)
module_exit(dm_zero_exit)
-MODULE_AUTHOR("Christophe Saout <christophe@saout.de>");
+MODULE_AUTHOR("Jana Saout <jana@saout.de>");
MODULE_DESCRIPTION(DM_NAME " dummy target returning zeros");
MODULE_LICENSE("GPL");
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 437d99045ef2..32b958dbc499 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -54,6 +54,8 @@ static void do_deferred_remove(struct work_struct *w);
static DECLARE_WORK(deferred_remove_work, do_deferred_remove);
+static struct workqueue_struct *deferred_remove_workqueue;
+
/*
* For bio-based dm.
* One of these is allocated per bio.
@@ -276,16 +278,24 @@ static int __init local_init(void)
if (r)
goto out_free_rq_tio_cache;
+ deferred_remove_workqueue = alloc_workqueue("kdmremove", WQ_UNBOUND, 1);
+ if (!deferred_remove_workqueue) {
+ r = -ENOMEM;
+ goto out_uevent_exit;
+ }
+
_major = major;
r = register_blkdev(_major, _name);
if (r < 0)
- goto out_uevent_exit;
+ goto out_free_workqueue;
if (!_major)
_major = r;
return 0;
+out_free_workqueue:
+ destroy_workqueue(deferred_remove_workqueue);
out_uevent_exit:
dm_uevent_exit();
out_free_rq_tio_cache:
@@ -299,6 +309,7 @@ out_free_io_cache:
static void local_exit(void)
{
flush_scheduled_work();
+ destroy_workqueue(deferred_remove_workqueue);
kmem_cache_destroy(_rq_tio_cache);
kmem_cache_destroy(_io_cache);
@@ -407,7 +418,7 @@ static void dm_blk_close(struct gendisk *disk, fmode_t mode)
if (atomic_dec_and_test(&md->open_count) &&
(test_bit(DMF_DEFERRED_REMOVE, &md->flags)))
- schedule_work(&deferred_remove_work);
+ queue_work(deferred_remove_workqueue, &deferred_remove_work);
dm_put(md);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 34846856dbc6..32fc19c540d4 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5599,7 +5599,7 @@ static int get_array_info(struct mddev * mddev, void __user * arg)
if (mddev->in_sync)
info.state = (1<<MD_SB_CLEAN);
if (mddev->bitmap && mddev->bitmap_info.offset)
- info.state = (1<<MD_SB_BITMAP_PRESENT);
+ info.state |= (1<<MD_SB_BITMAP_PRESENT);
info.active_disks = insync;
info.working_disks = working;
info.failed_disks = failed;
@@ -7501,6 +7501,19 @@ void md_do_sync(struct md_thread *thread)
rdev->recovery_offset < j)
j = rdev->recovery_offset;
rcu_read_unlock();
+
+ /* If there is a bitmap, we need to make sure all
+ * writes that started before we added a spare
+ * complete before we start doing a recovery.
+ * Otherwise the write might complete and (via
+ * bitmap_endwrite) set a bit in the bitmap after the
+ * recovery has checked that bit and skipped that
+ * region.
+ */
+ if (mddev->bitmap) {
+ mddev->pers->quiesce(mddev, 1);
+ mddev->pers->quiesce(mddev, 0);
+ }
}
printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 1d0758aeb8e4..f60bad491eb6 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -59,6 +59,13 @@ config MEDIA_RADIO_SUPPORT
support radio reception. Disabling this option will
disable support for them.
+config MEDIA_SDR_SUPPORT
+ bool "Software defined radio support"
+ ---help---
+ Enable software defined radio support.
+
+ Say Y when you have a software defined radio device.
+
config MEDIA_RC_SUPPORT
bool "Remote Controller support"
depends on INPUT
@@ -95,7 +102,7 @@ config MEDIA_CONTROLLER
config VIDEO_DEV
tristate
depends on MEDIA_SUPPORT
- depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT
+ depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
default y
config VIDEO_V4L2_SUBDEV_API
@@ -171,10 +178,11 @@ comment "Media ancillary drivers (tuners, sensors, i2c, frontends)"
config MEDIA_SUBDRV_AUTOSELECT
bool "Autoselect ancillary drivers (tuners, sensors, i2c, frontends)"
- depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT
+ depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_CAMERA_SUPPORT || MEDIA_SDR_SUPPORT
depends on HAS_IOMEM
select I2C
select I2C_MUX
+ select SPI
default y
help
By default, a media driver auto-selects all possible ancillary
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index eda01bc68ab2..d9e1d6395ed9 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -533,13 +533,12 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
saa7146_vbi_uops.init(dev,vv);
- fmt = &vv->ov_fb.fmt;
- fmt->width = vv->standard->h_max_out;
- fmt->height = vv->standard->v_max_out;
- fmt->pixelformat = V4L2_PIX_FMT_RGB565;
- fmt->bytesperline = 2 * fmt->width;
- fmt->sizeimage = fmt->bytesperline * fmt->height;
- fmt->colorspace = V4L2_COLORSPACE_SRGB;
+ vv->ov_fb.fmt.width = vv->standard->h_max_out;
+ vv->ov_fb.fmt.height = vv->standard->v_max_out;
+ vv->ov_fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
+ vv->ov_fb.fmt.bytesperline = 2 * vv->ov_fb.fmt.width;
+ vv->ov_fb.fmt.sizeimage = vv->ov_fb.fmt.bytesperline * vv->ov_fb.fmt.height;
+ vv->ov_fb.fmt.colorspace = V4L2_COLORSPACE_SRGB;
fmt = &vv->video_fmt;
fmt->width = 384;
@@ -613,7 +612,6 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
vfd->lock = &dev->v4l2_lock;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->tvnorms = 0;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
strlcpy(vfd->name, name, sizeof(vfd->name));
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
index f953d33ee151..4bfbd5f463d1 100644
--- a/drivers/media/common/siano/Kconfig
+++ b/drivers/media/common/siano/Kconfig
@@ -22,8 +22,7 @@ config SMS_SIANO_DEBUGFS
bool "Enable debugfs for smsdvb"
depends on SMS_SIANO_MDTV
depends on DEBUG_FS
- depends on SMS_USB_DRV
- depends on CONFIG_SMS_USB_DRV = CONFIG_SMS_SDIO_DRV
+ depends on SMS_USB_DRV = SMS_SDIO_DRV
---help---
Choose Y to enable visualizing a dump of the frontend
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
index 6d7c0c858bd0..273043ea8f47 100644
--- a/drivers/media/common/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
dev->priv = coredev;
dev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(dev, RC_BIT_ALL);
+ dev->allowed_protocols = RC_BIT_ALL;
dev->map_name = sms_get_board(board_id)->rc_codes;
dev->driver_name = MODULE_NAME;
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 11d2bea23b02..5135a096bfa6 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -244,6 +244,7 @@
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009
#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
+#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400 0x3014
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
@@ -363,6 +364,7 @@
#define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d
#define USB_PID_SVEON_STV20_RTL2832U 0xd39d
+#define USB_PID_SVEON_STV21 0xd3b0
#define USB_PID_SVEON_STV22 0xe401
#define USB_PID_SVEON_STV22_IT9137 0xe411
#define USB_PID_AZUREWAVE_AZ6027 0x3275
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 6ce435ac866f..c2a6a0a85813 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -96,10 +96,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
* FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again.
*/
-#define DVB_FE_NO_EXIT 0
-#define DVB_FE_NORMAL_EXIT 1
-#define DVB_FE_DEVICE_REMOVED 2
-
static DEFINE_MUTEX(frontend_mutex);
struct dvb_frontend_private {
@@ -113,7 +109,6 @@ struct dvb_frontend_private {
wait_queue_head_t wait_queue;
struct task_struct *thread;
unsigned long release_jiffies;
- unsigned int exit;
unsigned int wakeup;
fe_status_t status;
unsigned long tune_mode_flags;
@@ -565,7 +560,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- if (fepriv->exit != DVB_FE_NO_EXIT)
+ if (fe->exit != DVB_FE_NO_EXIT)
return 1;
if (fepriv->dvbdev->writers == 1)
@@ -629,7 +624,7 @@ restart:
/* got signal or quitting */
if (!down_interruptible(&fepriv->sem))
semheld = true;
- fepriv->exit = DVB_FE_NORMAL_EXIT;
+ fe->exit = DVB_FE_NORMAL_EXIT;
break;
}
@@ -739,9 +734,9 @@ restart:
fepriv->thread = NULL;
if (kthread_should_stop())
- fepriv->exit = DVB_FE_DEVICE_REMOVED;
+ fe->exit = DVB_FE_DEVICE_REMOVED;
else
- fepriv->exit = DVB_FE_NO_EXIT;
+ fe->exit = DVB_FE_NO_EXIT;
mb();
if (semheld)
@@ -756,7 +751,8 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__);
- fepriv->exit = DVB_FE_NORMAL_EXIT;
+ if (fe->exit != DVB_FE_DEVICE_REMOVED)
+ fe->exit = DVB_FE_NORMAL_EXIT;
mb();
if (!fepriv->thread)
@@ -826,7 +822,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s:\n", __func__);
if (fepriv->thread) {
- if (fepriv->exit == DVB_FE_NO_EXIT)
+ if (fe->exit == DVB_FE_NO_EXIT)
return 0;
else
dvb_frontend_stop (fe);
@@ -838,7 +834,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return -EINTR;
fepriv->state = FESTATE_IDLE;
- fepriv->exit = DVB_FE_NO_EXIT;
+ fe->exit = DVB_FE_NO_EXIT;
fepriv->thread = NULL;
mb();
@@ -1906,7 +1902,7 @@ static int dvb_frontend_ioctl(struct file *file,
if (down_interruptible(&fepriv->sem))
return -ERESTARTSYS;
- if (fepriv->exit != DVB_FE_NO_EXIT) {
+ if (fe->exit != DVB_FE_NO_EXIT) {
up(&fepriv->sem);
return -ENODEV;
}
@@ -2424,7 +2420,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
int ret;
dev_dbg(fe->dvb->device, "%s:\n", __func__);
- if (fepriv->exit == DVB_FE_DEVICE_REMOVED)
+ if (fe->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV;
if (adapter->mfe_shared) {
@@ -2529,7 +2525,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (dvbdev->users == -1) {
wake_up(&fepriv->wait_queue);
- if (fepriv->exit != DVB_FE_NO_EXIT)
+ if (fe->exit != DVB_FE_NO_EXIT)
wake_up(&dvbdev->wait_queue);
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
@@ -2572,12 +2568,14 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num,
fe->id);
+ fe->exit = DVB_FE_DEVICE_RESUME;
if (fe->ops.init)
ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe);
+ fe->exit = DVB_FE_NO_EXIT;
fepriv->state = FESTATE_RETUNE;
dvb_frontend_wakeup(fe);
@@ -2666,20 +2664,20 @@ void dvb_frontend_detach(struct dvb_frontend* fe)
if (fe->ops.release_sec) {
fe->ops.release_sec(fe);
- symbol_put_addr(fe->ops.release_sec);
+ dvb_detach(fe->ops.release_sec);
}
if (fe->ops.tuner_ops.release) {
fe->ops.tuner_ops.release(fe);
- symbol_put_addr(fe->ops.tuner_ops.release);
+ dvb_detach(fe->ops.tuner_ops.release);
}
if (fe->ops.analog_ops.release) {
fe->ops.analog_ops.release(fe);
- symbol_put_addr(fe->ops.analog_ops.release);
+ dvb_detach(fe->ops.analog_ops.release);
}
ptr = (void*)fe->ops.release;
if (ptr) {
fe->ops.release(fe);
- symbol_put_addr(ptr);
+ dvb_detach(ptr);
}
}
#else
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h
index 371b6caf486c..d398de4b6ef4 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb-core/dvb_frontend.h
@@ -405,6 +405,11 @@ struct dtv_frontend_properties {
struct dtv_fe_stats block_count;
};
+#define DVB_FE_NO_EXIT 0
+#define DVB_FE_NORMAL_EXIT 1
+#define DVB_FE_DEVICE_REMOVED 2
+#define DVB_FE_DEVICE_RESUME 3
+
struct dvb_frontend {
struct dvb_frontend_ops ops;
struct dvb_adapter *dvb;
@@ -418,6 +423,7 @@ struct dvb_frontend {
#define DVB_FRONTEND_COMPONENT_DEMOD 1
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
int id;
+ unsigned int exit;
};
extern int dvb_register_frontend(struct dvb_adapter *dvb,
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index 8a86b3025637..059e6117f22b 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -1276,7 +1276,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
if ((if_num = get_if(dvbnet)) < 0)
return -EINVAL;
- net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup);
+ net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb",
+ NET_NAME_UNKNOWN, dvb_net_setup);
if (!net)
return -ENOMEM;
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index 93a9470d3f0c..f96b28e7fc95 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -136,11 +136,15 @@ extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
__r; \
})
+#define dvb_detach(FUNC) symbol_put_addr(FUNC)
+
#else
#define dvb_attach(FUNCTION, ARGS...) ({ \
FUNCTION(ARGS); \
})
+#define dvb_detach(FUNC) {}
+
#endif
#endif /* #ifndef _DVBDEV_H_ */
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 1469d44acb22..fe0ddcca192c 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -63,6 +63,15 @@ config DVB_TDA18271C2DD
Say Y when you want to support this tuner.
+config DVB_SI2165
+ tristate "Silicon Labs si2165 based"
+ depends on DVB_CORE && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ A DVB-C/T demodulator.
+
+ Say Y when you want to support this frontend.
+
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
@@ -446,6 +455,15 @@ config DVB_RTL2832
help
Say Y when you want to support this frontend.
+config DVB_RTL2832_SDR
+ tristate "Realtek RTL2832 SDR"
+ depends on DVB_CORE && I2C && I2C_MUX && VIDEO_V4L2 && MEDIA_SDR_SUPPORT && USB
+ select DVB_RTL2832
+ select VIDEOBUF2_VMALLOC
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y when you want to support this SDR module.
+
config DVB_SI2168
tristate "Silicon Labs Si2168"
depends on DVB_CORE && I2C && I2C_MUX
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index dda0bee36f29..edf103d45920 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -5,6 +5,11 @@
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/
+# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
+ifdef CONFIG_DVB_RTL2832_SDR
+ ccflags-y += -I$(srctree)/drivers/media/usb/dvb-usb-v2
+endif
+
stb0899-objs := stb0899_drv.o stb0899_algo.o
stv0900-objs := stv0900_core.o stv0900_sw.o
drxd-objs := drxd_firm.o drxd_hard.o
@@ -100,10 +105,12 @@ obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
+obj-$(CONFIG_DVB_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
+obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index fb504f1e9125..ecf6388d2200 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -470,7 +470,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe)
break;
default:
goto err;
- break;
}
for (i = 0; i < len; i++) {
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 23a0d05ba426..33aa9410b624 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -220,7 +220,7 @@ static void setup_vbi(struct au8522_state *state, int aud_input)
}
-static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+static void setup_decoder_defaults(struct au8522_state *state, bool is_svideo)
{
int i;
int filter_coef_type;
@@ -237,13 +237,10 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
/* Other decoder registers */
au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
- if (input_mode == 0x23) {
- /* S-Video input mapping */
+ if (is_svideo)
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
- } else {
- /* All other modes (CVBS/ATVRF etc.) */
+ else
au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
- }
au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
AU8522_TVDEC_PGA_REG012H_CVBS);
@@ -251,12 +248,23 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
AU8522_TVDED_DBG_MODE_REG060H_CVBS);
- au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
- AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
- AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
- AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
- au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
- AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
+
+ if (state->std == V4L2_STD_PAL_M) {
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_AUTO);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M);
+ } else {
+ /* NTSC */
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_FIELD_LEN_525 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_LINE_LEN_63_492 |
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_SUBCARRIER_NTSC_MN);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC);
+ }
au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
@@ -275,8 +283,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
- if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
- input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ if (is_svideo) {
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
@@ -317,8 +324,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
setup_vbi(state, 0);
- if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
- input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ if (is_svideo) {
/* Despite what the table says, for the HVR-950q we still need
to be in CVBS mode for the S-Video input (reason unknown). */
/* filter_coef_type = 3; */
@@ -346,7 +352,7 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
au8522_writereg(state, AU8522_REG436H, 0x3c);
}
-static void au8522_setup_cvbs_mode(struct au8522_state *state)
+static void au8522_setup_cvbs_mode(struct au8522_state *state, u8 input_mode)
{
/* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
@@ -358,16 +364,16 @@ static void au8522_setup_cvbs_mode(struct au8522_state *state)
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
- au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
- AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
- setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+ setup_decoder_defaults(state, false);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
}
-static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state,
+ u8 input_mode)
{
/* here we're going to try the pre-programmed route */
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
@@ -384,24 +390,22 @@ static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
/* Set input mode to CVBS on channel 4 with SIF audio input enabled */
- au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
- AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
- setup_decoder_defaults(state,
- AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+ setup_decoder_defaults(state, false);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
}
-static void au8522_setup_svideo_mode(struct au8522_state *state)
+static void au8522_setup_svideo_mode(struct au8522_state *state,
+ u8 input_mode)
{
au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
/* Set input to Y on Channe1, C on Channel 3 */
- au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
- AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H, input_mode);
/* PGA in automatic mode */
au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
@@ -409,8 +413,7 @@ static void au8522_setup_svideo_mode(struct au8522_state *state)
/* Enable clamping control */
au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
- setup_decoder_defaults(state,
- AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+ setup_decoder_defaults(state, true);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
@@ -432,8 +435,9 @@ static void disable_audio_input(struct au8522_state *state)
}
/* 0=disable, 1=SIF */
-static void set_audio_input(struct au8522_state *state, int aud_input)
+static void set_audio_input(struct au8522_state *state)
{
+ int aud_input = state->aud_input;
int i;
/* Note that this function needs to be used in conjunction with setting
@@ -465,8 +469,9 @@ static void set_audio_input(struct au8522_state *state, int aud_input)
au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
msleep(150);
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
- msleep(1);
- au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+ msleep(10);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
msleep(50);
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
@@ -539,58 +544,109 @@ static int au8522_s_register(struct v4l2_subdev *sd,
}
#endif
+static void au8522_video_set(struct au8522_state *state)
+{
+ u8 input_mode;
+
+ au8522_writereg(state, 0xa4, 1 << 5);
+
+ switch (state->vid_input) {
+ case AU8522_COMPOSITE_CH1:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH1;
+ au8522_setup_cvbs_mode(state, input_mode);
+ break;
+ case AU8522_COMPOSITE_CH2:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH2;
+ au8522_setup_cvbs_mode(state, input_mode);
+ break;
+ case AU8522_COMPOSITE_CH3:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH3;
+ au8522_setup_cvbs_mode(state, input_mode);
+ break;
+ case AU8522_COMPOSITE_CH4:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4;
+ au8522_setup_cvbs_mode(state, input_mode);
+ break;
+ case AU8522_SVIDEO_CH13:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13;
+ au8522_setup_svideo_mode(state, input_mode);
+ break;
+ case AU8522_SVIDEO_CH24:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24;
+ au8522_setup_svideo_mode(state, input_mode);
+ break;
+ default:
+ case AU8522_COMPOSITE_CH4_SIF:
+ input_mode = AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF;
+ au8522_setup_cvbs_tuner_mode(state, input_mode);
+ break;
+ }
+}
+
static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
{
struct au8522_state *state = to_state(sd);
if (enable) {
+ /*
+ * Clear out any state associated with the digital side of the
+ * chip, so that when it gets powered back up it won't think
+ * that it is already tuned
+ */
+ state->current_frequency = 0;
+
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
0x01);
- msleep(1);
- au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
- AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ msleep(10);
+
+ au8522_video_set(state);
+ set_audio_input(state);
+
+ state->operational_mode = AU8522_ANALOG_MODE;
} else {
/* This does not completely power down the device
(it only reduces it from around 140ma to 80ma) */
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
1 << 5);
+ state->operational_mode = AU8522_SUSPEND_MODE;
}
return 0;
}
-static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
- state->operational_mode = AU8522_ANALOG_MODE;
-
- /* Clear out any state associated with the digital side of the
- chip, so that when it gets powered back up it won't think
- that it is already tuned */
- state->current_frequency = 0;
+ switch(input) {
+ case AU8522_COMPOSITE_CH1:
+ case AU8522_SVIDEO_CH13:
+ case AU8522_COMPOSITE_CH4_SIF:
+ state->vid_input = input;
+ break;
+ default:
+ printk(KERN_ERR "au8522 mode not currently supported\n");
+ return -EINVAL;
+ }
- au8522_writereg(state, 0xa4, 1 << 5);
+ if (state->operational_mode == AU8522_ANALOG_MODE)
+ au8522_video_set(state);
return 0;
}
-static int au8522_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
+static int au8522_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct au8522_state *state = to_state(sd);
- au8522_reset(sd, 0);
-
- if (input == AU8522_COMPOSITE_CH1) {
- au8522_setup_cvbs_mode(state);
- } else if (input == AU8522_SVIDEO_CH13) {
- au8522_setup_svideo_mode(state);
- } else if (input == AU8522_COMPOSITE_CH4_SIF) {
- au8522_setup_cvbs_tuner_mode(state);
- } else {
- printk(KERN_ERR "au8522 mode not currently supported\n");
+ if ((std & (V4L2_STD_PAL_M | V4L2_STD_NTSC_M)) == 0)
return -EINVAL;
- }
+
+ state->std = std;
+
+ if (state->operational_mode == AU8522_ANALOG_MODE)
+ au8522_video_set(state);
+
return 0;
}
@@ -598,7 +654,12 @@ static int au8522_s_audio_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{
struct au8522_state *state = to_state(sd);
- set_audio_input(state, input);
+
+ state->aud_input = input;
+
+ if (state->operational_mode == AU8522_ANALOG_MODE)
+ set_audio_input(state);
+
return 0;
}
@@ -629,7 +690,6 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
static const struct v4l2_subdev_core_ops au8522_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .reset = au8522_reset,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = au8522_g_register,
.s_register = au8522_s_register,
@@ -647,6 +707,7 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
static const struct v4l2_subdev_video_ops au8522_video_ops = {
.s_routing = au8522_s_video_routing,
.s_stream = au8522_s_stream,
+ .s_std = au8522_s_std,
};
static const struct v4l2_subdev_ops au8522_ops = {
@@ -729,6 +790,7 @@ static int au8522_probe(struct i2c_client *client,
}
state->c = client;
+ state->std = V4L2_STD_NTSC_M;
state->vid_input = AU8522_COMPOSITE_CH1;
state->aud_input = AU8522_AUDIO_NONE;
state->id = 8522;
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index aa0f16d6b610..b8aca1c84786 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -37,6 +37,7 @@
#define AU8522_ANALOG_MODE 0
#define AU8522_DIGITAL_MODE 1
+#define AU8522_SUSPEND_MODE 2
struct au8522_state {
struct i2c_client *c;
@@ -347,6 +348,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
/* Format control 2 */
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_AUTODETECT 0x00
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_NTSC 0x01
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M 0x02
#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h
index 82b3d93718f8..6095dbcf7850 100644
--- a/drivers/media/dvb-frontends/cxd2820r.h
+++ b/drivers/media/dvb-frontends/cxd2820r.h
@@ -52,6 +52,12 @@ struct cxd2820r_config {
*/
u8 ts_mode;
+ /* TS clock inverted.
+ * Default: 0
+ * Values: 0, 1
+ */
+ bool ts_clock_inv;
+
/* IF AGC polarity.
* Default: 0
* Values: 0, 1
diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c
index 5c6ab4921bf1..0f4657e01cde 100644
--- a/drivers/media/dvb-frontends/cxd2820r_c.c
+++ b/drivers/media/dvb-frontends/cxd2820r_c.c
@@ -45,6 +45,7 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe)
{ 0x1008b, 0x07, 0xff },
{ 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
{ 0x10070, priv->cfg.ts_mode, 0xff },
+ { 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 },
};
dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__,
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c
index fa184ca2dd68..9b5a45b907bc 100644
--- a/drivers/media/dvb-frontends/cxd2820r_t.c
+++ b/drivers/media/dvb-frontends/cxd2820r_t.c
@@ -46,6 +46,7 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
{ 0x00088, 0x01, 0xff },
{ 0x00070, priv->cfg.ts_mode, 0xff },
+ { 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 },
{ 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x000a5, 0x00, 0x01 },
{ 0x00082, 0x20, 0x60 },
diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c
index 2ba130e245b6..9c0c4f42175c 100644
--- a/drivers/media/dvb-frontends/cxd2820r_t2.c
+++ b/drivers/media/dvb-frontends/cxd2820r_t2.c
@@ -47,6 +47,7 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
{ 0x02083, 0x0a, 0xff },
{ 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
{ 0x02070, priv->cfg.ts_mode, 0xff },
+ { 0x02071, !priv->cfg.ts_clock_inv << 6, 0x40 },
{ 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
{ 0x02567, 0x07, 0x0f },
{ 0x02569, 0x03, 0x03 },
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
index 3ee22ff76315..68e2af2650d3 100644
--- a/drivers/media/dvb-frontends/dib0090.c
+++ b/drivers/media/dvb-frontends/dib0090.c
@@ -2557,10 +2557,19 @@ static int dib0090_set_params(struct dvb_frontend *fe)
do {
ret = dib0090_tune(fe);
- if (ret != FE_CALLBACK_TIME_NEVER)
- msleep(ret / 10);
- else
+ if (ret == FE_CALLBACK_TIME_NEVER)
break;
+
+ /*
+ * Despite dib0090_tune returns time at a 0.1 ms range,
+ * the actual sleep time depends on CONFIG_HZ. The worse case
+ * is when CONFIG_HZ=100. In such case, the minimum granularity
+ * is 10ms. On some real field tests, the tuner sometimes don't
+ * lock when this timer is lower than 10ms. So, enforce a 10ms
+ * granularity and use usleep_range() instead of msleep().
+ */
+ ret = 10 * (ret + 99)/100;
+ usleep_range(ret * 1000, (ret + 1) * 1000);
} while (state->tune_state != CT_TUNER_STOP);
return 0;
diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
index 148bf79236fb..dcb9a15ef0c2 100644
--- a/drivers/media/dvb-frontends/dib7000m.c
+++ b/drivers/media/dvb-frontends/dib7000m.c
@@ -1041,10 +1041,7 @@ static int dib7000m_tune(struct dvb_frontend *demod)
u16 value;
// we are already tuned - just resuming from suspend
- if (ch != NULL)
- dib7000m_set_channel(state, ch, 0);
- else
- return -EINVAL;
+ dib7000m_set_channel(state, ch, 0);
// restart demod
ret |= dib7000m_write_word(state, 898, 0x4000);
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index effb87f773b0..661760d60232 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
+#include <asm/div64.h>
#include "dvb_math.h"
#include "dvb_frontend.h"
@@ -72,6 +73,12 @@ struct dib7000p_state {
struct mutex i2c_buffer_lock;
u8 input_mode_mpeg;
+
+ /* for DVBv5 stats */
+ s64 old_ucb;
+ unsigned long per_jiffies_stats;
+ unsigned long ber_jiffies_stats;
+ unsigned long get_stats_time;
};
enum dib7000p_power_mode {
@@ -401,7 +408,7 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
return 0;
}
-int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
+static int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
{
struct dib7000p_state *state = demod->demodulator_priv;
if (value > 4095)
@@ -409,9 +416,8 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
state->wbd_ref = value;
return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
}
-EXPORT_SYMBOL(dib7000p_set_wbd_ref);
-int dib7000p_get_agc_values(struct dvb_frontend *fe,
+static int dib7000p_get_agc_values(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
{
struct dib7000p_state *state = fe->demodulator_priv;
@@ -427,14 +433,12 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe,
return 0;
}
-EXPORT_SYMBOL(dib7000p_get_agc_values);
-int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
+static int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
{
struct dib7000p_state *state = fe->demodulator_priv;
return dib7000p_write_word(state, 108, v);
}
-EXPORT_SYMBOL(dib7000p_set_agc1_min);
static void dib7000p_reset_pll(struct dib7000p_state *state)
{
@@ -478,7 +482,7 @@ static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
return internal;
}
-int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
+static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
@@ -513,7 +517,6 @@ int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config
}
return -EIO;
}
-EXPORT_SYMBOL(dib7000p_update_pll);
static int dib7000p_reset_gpio(struct dib7000p_state *st)
{
@@ -546,12 +549,11 @@ static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
return 0;
}
-int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
+static int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
{
struct dib7000p_state *state = demod->demodulator_priv;
return dib7000p_cfg_gpio(state, num, dir, val);
}
-EXPORT_SYMBOL(dib7000p_set_gpio);
static u16 dib7000p_defaults[] = {
// auto search configuration
@@ -636,6 +638,8 @@ static u16 dib7000p_defaults[] = {
0,
};
+static void dib7000p_reset_stats(struct dvb_frontend *fe);
+
static int dib7000p_demod_reset(struct dib7000p_state *state)
{
dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
@@ -934,7 +938,7 @@ static void dib7000p_update_timf(struct dib7000p_state *state)
}
-u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
+static u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
{
struct dib7000p_state *state = fe->demodulator_priv;
switch (op) {
@@ -950,7 +954,6 @@ u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
dib7000p_set_bandwidth(state, state->current_bandwidth);
return state->timf;
}
-EXPORT_SYMBOL(dib7000p_ctrl_timf);
static void dib7000p_set_channel(struct dib7000p_state *state,
struct dtv_frontend_properties *ch, u8 seq)
@@ -1360,6 +1363,9 @@ static int dib7000p_tune(struct dvb_frontend *demod)
dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
+
+ dib7000p_reset_stats(demod);
+
return 0;
}
@@ -1552,6 +1558,8 @@ static int dib7000p_set_frontend(struct dvb_frontend *fe)
return ret;
}
+static int dib7000p_get_stats(struct dvb_frontend *fe, fe_status_t stat);
+
static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
{
struct dib7000p_state *state = fe->demodulator_priv;
@@ -1570,6 +1578,8 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
if ((lock & 0x0038) == 0x38)
*stat |= FE_HAS_LOCK;
+ dib7000p_get_stats(fe, *stat);
+
return 0;
}
@@ -1595,7 +1605,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength
return 0;
}
-static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
+static u32 dib7000p_get_snr(struct dvb_frontend *fe)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 val;
@@ -1625,10 +1635,351 @@ static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
else
result -= intlog10(2) * 10 * noise_exp - 100;
+ return result;
+}
+
+static int dib7000p_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ u32 result;
+
+ result = dib7000p_get_snr(fe);
+
*snr = result / ((1 << 24) / 10);
return 0;
}
+static void dib7000p_reset_stats(struct dvb_frontend *demod)
+{
+ struct dib7000p_state *state = demod->demodulator_priv;
+ struct dtv_frontend_properties *c = &demod->dtv_property_cache;
+ u32 ucb;
+
+ memset(&c->strength, 0, sizeof(c->strength));
+ memset(&c->cnr, 0, sizeof(c->cnr));
+ memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
+ memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
+ memset(&c->block_error, 0, sizeof(c->block_error));
+
+ c->strength.len = 1;
+ c->cnr.len = 1;
+ c->block_error.len = 1;
+ c->block_count.len = 1;
+ c->post_bit_error.len = 1;
+ c->post_bit_count.len = 1;
+
+ c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ c->strength.stat[0].uvalue = 0;
+
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+ dib7000p_read_unc_blocks(demod, &ucb);
+
+ state->old_ucb = ucb;
+ state->ber_jiffies_stats = 0;
+ state->per_jiffies_stats = 0;
+}
+
+struct linear_segments {
+ unsigned x;
+ signed y;
+};
+
+/*
+ * Table to estimate signal strength in dBm.
+ * This table should be empirically determinated by measuring the signal
+ * strength generated by a RF generator directly connected into
+ * a device.
+ * This table was determinated by measuring the signal strength generated
+ * by a DTA-2111 RF generator directly connected into a dib7000p device
+ * (a Hauppauge Nova-TD stick), using a good quality 3 meters length
+ * RC6 cable and good RC6 connectors, connected directly to antenna 1.
+ * As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
+ * were used, for the lower power values.
+ * The real value can actually be on other devices, or even at the
+ * second antena input, depending on several factors, like if LNA
+ * is enabled or not, if diversity is enabled, type of connectors, etc.
+ * Yet, it is better to use this measure in dB than a random non-linear
+ * percentage value, especially for antenna adjustments.
+ * On my tests, the precision of the measure using this table is about
+ * 0.5 dB, with sounds reasonable enough to adjust antennas.
+ */
+#define DB_OFFSET 131000
+
+static struct linear_segments strength_to_db_table[] = {
+ { 63630, DB_OFFSET - 20500},
+ { 62273, DB_OFFSET - 21000},
+ { 60162, DB_OFFSET - 22000},
+ { 58730, DB_OFFSET - 23000},
+ { 58294, DB_OFFSET - 24000},
+ { 57778, DB_OFFSET - 25000},
+ { 57320, DB_OFFSET - 26000},
+ { 56779, DB_OFFSET - 27000},
+ { 56293, DB_OFFSET - 28000},
+ { 55724, DB_OFFSET - 29000},
+ { 55145, DB_OFFSET - 30000},
+ { 54680, DB_OFFSET - 31000},
+ { 54293, DB_OFFSET - 32000},
+ { 53813, DB_OFFSET - 33000},
+ { 53427, DB_OFFSET - 34000},
+ { 52981, DB_OFFSET - 35000},
+
+ { 52636, DB_OFFSET - 36000},
+ { 52014, DB_OFFSET - 37000},
+ { 51674, DB_OFFSET - 38000},
+ { 50692, DB_OFFSET - 39000},
+ { 49824, DB_OFFSET - 40000},
+ { 49052, DB_OFFSET - 41000},
+ { 48436, DB_OFFSET - 42000},
+ { 47836, DB_OFFSET - 43000},
+ { 47368, DB_OFFSET - 44000},
+ { 46468, DB_OFFSET - 45000},
+ { 45597, DB_OFFSET - 46000},
+ { 44586, DB_OFFSET - 47000},
+ { 43667, DB_OFFSET - 48000},
+ { 42673, DB_OFFSET - 49000},
+ { 41816, DB_OFFSET - 50000},
+ { 40876, DB_OFFSET - 51000},
+ { 0, 0},
+};
+
+static u32 interpolate_value(u32 value, struct linear_segments *segments,
+ unsigned len)
+{
+ u64 tmp64;
+ u32 dx;
+ s32 dy;
+ int i, ret;
+
+ if (value >= segments[0].x)
+ return segments[0].y;
+ if (value < segments[len-1].x)
+ return segments[len-1].y;
+
+ for (i = 1; i < len - 1; i++) {
+ /* If value is identical, no need to interpolate */
+ if (value == segments[i].x)
+ return segments[i].y;
+ if (value > segments[i].x)
+ break;
+ }
+
+ /* Linear interpolation between the two (x,y) points */
+ dy = segments[i - 1].y - segments[i].y;
+ dx = segments[i - 1].x - segments[i].x;
+
+ tmp64 = value - segments[i].x;
+ tmp64 *= dy;
+ do_div(tmp64, dx);
+ ret = segments[i].y + tmp64;
+
+ return ret;
+}
+
+/* FIXME: may require changes - this one was borrowed from dib8000 */
+static u32 dib7000p_get_time_us(struct dvb_frontend *demod, int layer)
+{
+ struct dtv_frontend_properties *c = &demod->dtv_property_cache;
+ u64 time_us, tmp64;
+ u32 tmp, denom;
+ int guard, rate_num, rate_denum = 1, bits_per_symbol;
+ int interleaving = 0, fft_div;
+
+ switch (c->guard_interval) {
+ case GUARD_INTERVAL_1_4:
+ guard = 4;
+ break;
+ case GUARD_INTERVAL_1_8:
+ guard = 8;
+ break;
+ case GUARD_INTERVAL_1_16:
+ guard = 16;
+ break;
+ default:
+ case GUARD_INTERVAL_1_32:
+ guard = 32;
+ break;
+ }
+
+ switch (c->transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ fft_div = 4;
+ break;
+ case TRANSMISSION_MODE_4K:
+ fft_div = 2;
+ break;
+ default:
+ case TRANSMISSION_MODE_8K:
+ fft_div = 1;
+ break;
+ }
+
+ switch (c->modulation) {
+ case DQPSK:
+ case QPSK:
+ bits_per_symbol = 2;
+ break;
+ case QAM_16:
+ bits_per_symbol = 4;
+ break;
+ default:
+ case QAM_64:
+ bits_per_symbol = 6;
+ break;
+ }
+
+ switch ((c->hierarchy == 0 || 1 == 1) ? c->code_rate_HP : c->code_rate_LP) {
+ case FEC_1_2:
+ rate_num = 1;
+ rate_denum = 2;
+ break;
+ case FEC_2_3:
+ rate_num = 2;
+ rate_denum = 3;
+ break;
+ case FEC_3_4:
+ rate_num = 3;
+ rate_denum = 4;
+ break;
+ case FEC_5_6:
+ rate_num = 5;
+ rate_denum = 6;
+ break;
+ default:
+ case FEC_7_8:
+ rate_num = 7;
+ rate_denum = 8;
+ break;
+ }
+
+ interleaving = interleaving;
+
+ denom = bits_per_symbol * rate_num * fft_div * 384;
+
+ /* If calculus gets wrong, wait for 1s for the next stats */
+ if (!denom)
+ return 0;
+
+ /* Estimate the period for the total bit rate */
+ time_us = rate_denum * (1008 * 1562500L);
+ tmp64 = time_us;
+ do_div(tmp64, guard);
+ time_us = time_us + tmp64;
+ time_us += denom / 2;
+ do_div(time_us, denom);
+
+ tmp = 1008 * 96 * interleaving;
+ time_us += tmp + tmp / guard;
+
+ return time_us;
+}
+
+static int dib7000p_get_stats(struct dvb_frontend *demod, fe_status_t stat)
+{
+ struct dib7000p_state *state = demod->demodulator_priv;
+ struct dtv_frontend_properties *c = &demod->dtv_property_cache;
+ int i;
+ int show_per_stats = 0;
+ u32 time_us = 0, val, snr;
+ u64 blocks, ucb;
+ s32 db;
+ u16 strength;
+
+ /* Get Signal strength */
+ dib7000p_read_signal_strength(demod, &strength);
+ val = strength;
+ db = interpolate_value(val,
+ strength_to_db_table,
+ ARRAY_SIZE(strength_to_db_table)) - DB_OFFSET;
+ c->strength.stat[0].svalue = db;
+
+ /* UCB/BER/CNR measures require lock */
+ if (!(stat & FE_HAS_LOCK)) {
+ c->cnr.len = 1;
+ c->block_count.len = 1;
+ c->block_error.len = 1;
+ c->post_bit_error.len = 1;
+ c->post_bit_count.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return 0;
+ }
+
+ /* Check if time for stats was elapsed */
+ if (time_after(jiffies, state->per_jiffies_stats)) {
+ state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
+
+ /* Get SNR */
+ snr = dib7000p_get_snr(demod);
+ if (snr)
+ snr = (1000L * snr) >> 24;
+ else
+ snr = 0;
+ c->cnr.stat[0].svalue = snr;
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+
+ /* Get UCB measures */
+ dib7000p_read_unc_blocks(demod, &val);
+ ucb = val - state->old_ucb;
+ if (val < state->old_ucb)
+ ucb += 0x100000000LL;
+
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[0].uvalue = ucb;
+
+ /* Estimate the number of packets based on bitrate */
+ if (!time_us)
+ time_us = dib7000p_get_time_us(demod, -1);
+
+ if (time_us) {
+ blocks = 1250000ULL * 1000000ULL;
+ do_div(blocks, time_us * 8 * 204);
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].uvalue += blocks;
+ }
+
+ show_per_stats = 1;
+ }
+
+ /* Get post-BER measures */
+ if (time_after(jiffies, state->ber_jiffies_stats)) {
+ time_us = dib7000p_get_time_us(demod, -1);
+ state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
+
+ dprintk("Next all layers stats available in %u us.", time_us);
+
+ dib7000p_read_ber(demod, &val);
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue += val;
+
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].uvalue += 100000000;
+ }
+
+ /* Get PER measures */
+ if (show_per_stats) {
+ dib7000p_read_unc_blocks(demod, &val);
+
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[0].uvalue += val;
+
+ time_us = dib7000p_get_time_us(demod, i);
+ if (time_us) {
+ blocks = 1250000ULL * 1000000ULL;
+ do_div(blocks, time_us * 8 * 204);
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].uvalue += blocks;
+ }
+ }
+ return 0;
+}
+
static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1000;
@@ -1643,7 +1994,7 @@ static void dib7000p_release(struct dvb_frontend *demod)
kfree(st);
}
-int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+static int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{
u8 *tx, *rx;
struct i2c_msg msg[2] = {
@@ -1688,16 +2039,14 @@ rx_memory_error:
kfree(tx);
return ret;
}
-EXPORT_SYMBOL(dib7000pc_detection);
-struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
+static struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
{
struct dib7000p_state *st = demod->demodulator_priv;
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
}
-EXPORT_SYMBOL(dib7000p_get_i2c_master);
-int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 val = dib7000p_read_word(state, 235) & 0xffef;
@@ -1705,17 +2054,15 @@ int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
dprintk("PID filter enabled %d", onoff);
return dib7000p_write_word(state, 235, val);
}
-EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
-int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
}
-EXPORT_SYMBOL(dib7000p_pid_filter);
-int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
+static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
{
struct dib7000p_state *dpst;
int k = 0;
@@ -1774,7 +2121,6 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
kfree(dpst);
return 0;
}
-EXPORT_SYMBOL(dib7000p_i2c_enumeration);
static const s32 lut_1000ln_mant[] = {
6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
@@ -2032,12 +2378,11 @@ static struct i2c_algorithm dib7090_tuner_xfer_algo = {
.functionality = dib7000p_i2c_func,
};
-struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
+static struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
{
struct dib7000p_state *st = fe->demodulator_priv;
return &st->dib7090_tuner_adap;
}
-EXPORT_SYMBOL(dib7090_get_i2c_tuner);
static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
{
@@ -2329,7 +2674,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
return ret;
}
-int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 en_cur_state;
@@ -2352,15 +2697,13 @@ int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
return 0;
}
-EXPORT_SYMBOL(dib7090_tuner_sleep);
-int dib7090_get_adc_power(struct dvb_frontend *fe)
+static int dib7090_get_adc_power(struct dvb_frontend *fe)
{
return dib7000p_get_adc_power(fe);
}
-EXPORT_SYMBOL(dib7090_get_adc_power);
-int dib7090_slave_reset(struct dvb_frontend *fe)
+static int dib7090_slave_reset(struct dvb_frontend *fe)
{
struct dib7000p_state *state = fe->demodulator_priv;
u16 reg;
@@ -2371,10 +2714,9 @@ int dib7090_slave_reset(struct dvb_frontend *fe)
dib7000p_write_word(state, 1032, 0xffff);
return 0;
}
-EXPORT_SYMBOL(dib7090_slave_reset);
static struct dvb_frontend_ops dib7000p_ops;
-struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
+static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
{
struct dvb_frontend *demod;
struct dib7000p_state *st;
@@ -2423,6 +2765,8 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
dib7000p_demod_reset(st);
+ dib7000p_reset_stats(demod);
+
if (st->version == SOC7090) {
dib7090_set_output_mode(demod, st->cfg.output_mode);
dib7090_set_diversity_in(demod, 0);
@@ -2434,6 +2778,31 @@ error:
kfree(st);
return NULL;
}
+
+void *dib7000p_attach(struct dib7000p_ops *ops)
+{
+ if (!ops)
+ return NULL;
+
+ ops->slave_reset = dib7090_slave_reset;
+ ops->get_adc_power = dib7090_get_adc_power;
+ ops->dib7000pc_detection = dib7000pc_detection;
+ ops->get_i2c_tuner = dib7090_get_i2c_tuner;
+ ops->tuner_sleep = dib7090_tuner_sleep;
+ ops->init = dib7000p_init;
+ ops->set_agc1_min = dib7000p_set_agc1_min;
+ ops->set_gpio = dib7000p_set_gpio;
+ ops->i2c_enumeration = dib7000p_i2c_enumeration;
+ ops->pid_filter = dib7000p_pid_filter;
+ ops->pid_filter_ctrl = dib7000p_pid_filter_ctrl;
+ ops->get_i2c_master = dib7000p_get_i2c_master;
+ ops->update_pll = dib7000p_update_pll;
+ ops->ctrl_timf = dib7000p_ctrl_timf;
+ ops->get_agc_values = dib7000p_get_agc_values;
+ ops->set_wbd_ref = dib7000p_set_wbd_ref;
+
+ return ops;
+}
EXPORT_SYMBOL(dib7000p_attach);
static struct dvb_frontend_ops dib7000p_ops = {
diff --git a/drivers/media/dvb-frontends/dib7000p.h b/drivers/media/dvb-frontends/dib7000p.h
index d08cdff59bdf..1fea0e972654 100644
--- a/drivers/media/dvb-frontends/dib7000p.h
+++ b/drivers/media/dvb-frontends/dib7000p.h
@@ -46,121 +46,34 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-#if IS_ENABLED(CONFIG_DVB_DIB7000P)
-extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
-extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
-extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
-extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
-extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
-extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
-extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
-extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
-extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
-extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
-extern int dib7090_get_adc_power(struct dvb_frontend *fe);
-extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
-extern int dib7090_slave_reset(struct dvb_frontend *fe);
-extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
+struct dib7000p_ops {
+ int (*set_wbd_ref)(struct dvb_frontend *demod, u16 value);
+ int (*get_agc_values)(struct dvb_frontend *fe,
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
-extern int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v);
-#else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-
-static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
+ int (*set_agc1_min)(struct dvb_frontend *fe, u16 v);
+ int (*update_pll)(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
+ int (*set_gpio)(struct dvb_frontend *demod, u8 num, u8 dir, u8 val);
+ u32 (*ctrl_timf)(struct dvb_frontend *fe, u8 op, u32 timf);
+ int (*dib7000pc_detection)(struct i2c_adapter *i2c_adap);
+ struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating);
+ int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
+ int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
+ int (*i2c_enumeration)(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
+ struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
+ int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
+ int (*get_adc_power)(struct dvb_frontend *fe);
+ int (*slave_reset)(struct dvb_frontend *fe);
+ struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
+};
-static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
+#if IS_ENABLED(CONFIG_DVB_DIB7000P)
+void *dib7000p_attach(struct dib7000p_ops *ops);
+#else
+static inline void *dib7000p_attach(struct dib7000p_ops *ops)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-
-static inline int dib7090_slave_reset(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
- u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
#endif
#endif
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 1632d78a5479..61e31f2d2f71 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -115,7 +115,7 @@ struct dib8000_state {
u16 found_guard;
u8 subchannel;
u8 symbol_duration;
- u32 timeout;
+ unsigned long timeout;
u8 longest_intlv_layer;
u16 output_mode;
@@ -588,8 +588,8 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s
break;
case DIBX000_ADC_OFF: // leave the VBG voltage on
- reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
- reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+ reg_907 = (1 << 13) | (1 << 12);
+ reg_908 = (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 1);
break;
case DIBX000_VBG_ENABLE:
@@ -656,7 +656,7 @@ static int dib8000_sad_calib(struct dib8000_state *state)
return 0;
}
-int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+static int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
struct dib8000_state *state = fe->demodulator_priv;
if (value > 4095)
@@ -664,7 +664,6 @@ int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
state->wbd_ref = value;
return dib8000_write_word(state, 106, value);
}
-EXPORT_SYMBOL(dib8000_set_wbd_ref);
static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
{
@@ -739,7 +738,7 @@ static void dib8000_reset_pll(struct dib8000_state *state)
dib8000_reset_pll_common(state, pll);
}
-int dib8000_update_pll(struct dvb_frontend *fe,
+static int dib8000_update_pll(struct dvb_frontend *fe,
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
{
struct dib8000_state *state = fe->demodulator_priv;
@@ -815,8 +814,6 @@ int dib8000_update_pll(struct dvb_frontend *fe,
return 0;
}
-EXPORT_SYMBOL(dib8000_update_pll);
-
static int dib8000_reset_gpio(struct dib8000_state *st)
{
@@ -849,13 +846,12 @@ static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
return 0;
}
-int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+static int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
{
struct dib8000_state *state = fe->demodulator_priv;
return dib8000_cfg_gpio(state, num, dir, val);
}
-EXPORT_SYMBOL(dib8000_set_gpio);
static const u16 dib8000_defaults[] = {
/* auto search configuration - lock0 by default waiting
* for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
@@ -1054,6 +1050,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
dib8000_write_word(state, 770, 0xffff);
dib8000_write_word(state, 771, 0xffff);
dib8000_write_word(state, 772, 0xfffc);
+ dib8000_write_word(state, 898, 0x000c); /* restart sad */
if (state->revision == 0x8090)
dib8000_write_word(state, 1280, 0x0045);
else
@@ -1228,20 +1225,19 @@ static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
return 0;
}
-void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
+static void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
{
struct dib8000_state *state = fe->demodulator_priv;
dib8000_set_adc_state(state, DIBX000_ADC_ON);
dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
}
-EXPORT_SYMBOL(dib8000_pwm_agc_reset);
static int dib8000_agc_soft_split(struct dib8000_state *state)
{
u16 agc, split_offset;
if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
- return FE_CALLBACK_TIME_NEVER;
+ return 0;
// n_agc_global
agc = dib8000_read_word(state, 390);
@@ -1881,14 +1877,13 @@ static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
.functionality = dib8096p_i2c_func,
};
-struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
+static struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
{
struct dib8000_state *st = fe->demodulator_priv;
return &st->dib8096p_tuner_adap;
}
-EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
-int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
+static int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
struct dib8000_state *state = fe->demodulator_priv;
u16 en_cur_state;
@@ -1912,14 +1907,13 @@ int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
return 0;
}
-EXPORT_SYMBOL(dib8096p_tuner_sleep);
static const s32 lut_1000ln_mant[] =
{
908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
};
-s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
+static s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
{
struct dib8000_state *state = fe->demodulator_priv;
u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
@@ -1937,9 +1931,8 @@ s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
}
return val;
}
-EXPORT_SYMBOL(dib8000_get_adc_power);
-int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
+static int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
{
struct dib8000_state *state = fe->demodulator_priv;
int val = 0;
@@ -1957,7 +1950,6 @@ int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
return val;
}
-EXPORT_SYMBOL(dib8090p_get_dc_power);
static void dib8000_update_timf(struct dib8000_state *state)
{
@@ -1968,7 +1960,7 @@ static void dib8000_update_timf(struct dib8000_state *state)
dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
}
-u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
+static u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
{
struct dib8000_state *state = fe->demodulator_priv;
@@ -1986,21 +1978,11 @@ u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
return state->timf;
}
-EXPORT_SYMBOL(dib8000_ctrl_timf);
static const u16 adc_target_16dB[11] = {
- (1 << 13) - 825 - 117,
- (1 << 13) - 837 - 117,
- (1 << 13) - 811 - 117,
- (1 << 13) - 766 - 117,
- (1 << 13) - 737 - 117,
- (1 << 13) - 693 - 117,
- (1 << 13) - 648 - 117,
- (1 << 13) - 619 - 117,
- (1 << 13) - 575 - 117,
- (1 << 13) - 531 - 117,
- (1 << 13) - 501 - 117
+ 7250, 7238, 7264, 7309, 7338, 7382, 7427, 7456, 7500, 7544, 7574
};
+
static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
@@ -2043,9 +2025,8 @@ static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 ma
break;
}
- if ((c->layer[layer_index].interleaving > 0) && ((c->layer[layer_index].interleaving <= 3) || (c->layer[layer_index].interleaving == 4 && c->isdbt_sb_mode == 1)))
- time_intlv = c->layer[layer_index].interleaving;
- else
+ time_intlv = fls(c->layer[layer_index].interleaving);
+ if (time_intlv > 3 && !(time_intlv == 4 && c->isdbt_sb_mode == 1))
time_intlv = 0;
dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
@@ -2362,6 +2343,9 @@ static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq
int init_prbs;
struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
+ if (autosearching)
+ c->isdbt_partial_reception = 1;
+
/* P_mode */
dib8000_write_word(state, 10, (seq << 4));
@@ -2856,12 +2840,12 @@ static void dib8000_set_sync_wait(struct dib8000_state *state)
dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
}
-static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
+static unsigned long dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
{
if (mode == SYMBOL_DEPENDENT_ON)
- return systime() + (delay * state->symbol_duration);
- else
- return systime() + delay;
+ delay *= state->symbol_duration;
+
+ return jiffies + usecs_to_jiffies(delay * 100);
}
static s32 dib8000_get_status(struct dvb_frontend *fe)
@@ -2870,21 +2854,19 @@ static s32 dib8000_get_status(struct dvb_frontend *fe)
return state->status;
}
-enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
+static enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
{
struct dib8000_state *state = fe->demodulator_priv;
return state->tune_state;
}
-EXPORT_SYMBOL(dib8000_get_tune_state);
-int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
+static int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
{
struct dib8000_state *state = fe->demodulator_priv;
state->tune_state = tune_state;
return 0;
}
-EXPORT_SYMBOL(dib8000_set_tune_state);
static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
{
@@ -3015,8 +2997,8 @@ static int dib8000_tune(struct dvb_frontend *fe)
u16 locks, deeper_interleaver = 0, i;
int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
- u32 *timeout = &state->timeout;
- u32 now = systime();
+ unsigned long *timeout = &state->timeout;
+ unsigned long now = jiffies;
#ifdef DIB8000_AGC_FREEZE
u16 agc1, agc2;
#endif
@@ -3026,318 +3008,327 @@ static int dib8000_tune(struct dvb_frontend *fe)
#if 0
if (*tune_state < CT_DEMOD_STOP)
- dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
+ dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u jiffies = %lu",
+ state->channel_parameters_set, *tune_state, state->autosearch_state, now);
#endif
switch (*tune_state) {
case CT_DEMOD_START: /* 30 */
- dib8000_reset_stats(fe);
+ dib8000_reset_stats(fe);
- if (state->revision == 0x8090)
- dib8090p_init_sdram(state);
- state->status = FE_STATUS_TUNE_PENDING;
- state->channel_parameters_set = is_manual_mode(c);
+ if (state->revision == 0x8090)
+ dib8090p_init_sdram(state);
+ state->status = FE_STATUS_TUNE_PENDING;
+ state->channel_parameters_set = is_manual_mode(c);
- dprintk("Tuning channel on %s search mode",
- state->channel_parameters_set ? "manual" : "auto");
+ dprintk("Tuning channel on %s search mode",
+ state->channel_parameters_set ? "manual" : "auto");
- dib8000_viterbi_state(state, 0); /* force chan dec in restart */
+ dib8000_viterbi_state(state, 0); /* force chan dec in restart */
- /* Layer monitor */
- dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
+ /* Layer monitor */
+ dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
- dib8000_set_frequency_offset(state);
- dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
+ dib8000_set_frequency_offset(state);
+ dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
- if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
+ if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
#ifdef DIB8000_AGC_FREEZE
- if (state->revision != 0x8090) {
- state->agc1_max = dib8000_read_word(state, 108);
- state->agc1_min = dib8000_read_word(state, 109);
- state->agc2_max = dib8000_read_word(state, 110);
- state->agc2_min = dib8000_read_word(state, 111);
- agc1 = dib8000_read_word(state, 388);
- agc2 = dib8000_read_word(state, 389);
- dib8000_write_word(state, 108, agc1);
- dib8000_write_word(state, 109, agc1);
- dib8000_write_word(state, 110, agc2);
- dib8000_write_word(state, 111, agc2);
- }
-#endif
- state->autosearch_state = AS_SEARCHING_FFT;
- state->found_nfft = TRANSMISSION_MODE_AUTO;
- state->found_guard = GUARD_INTERVAL_AUTO;
- *tune_state = CT_DEMOD_SEARCH_NEXT;
- } else { /* we already know the channel struct so TUNE only ! */
- state->autosearch_state = AS_DONE;
- *tune_state = CT_DEMOD_STEP_3;
+ if (state->revision != 0x8090) {
+ state->agc1_max = dib8000_read_word(state, 108);
+ state->agc1_min = dib8000_read_word(state, 109);
+ state->agc2_max = dib8000_read_word(state, 110);
+ state->agc2_min = dib8000_read_word(state, 111);
+ agc1 = dib8000_read_word(state, 388);
+ agc2 = dib8000_read_word(state, 389);
+ dib8000_write_word(state, 108, agc1);
+ dib8000_write_word(state, 109, agc1);
+ dib8000_write_word(state, 110, agc2);
+ dib8000_write_word(state, 111, agc2);
}
- state->symbol_duration = dib8000_get_symbol_duration(state);
- break;
+#endif
+ state->autosearch_state = AS_SEARCHING_FFT;
+ state->found_nfft = TRANSMISSION_MODE_AUTO;
+ state->found_guard = GUARD_INTERVAL_AUTO;
+ *tune_state = CT_DEMOD_SEARCH_NEXT;
+ } else { /* we already know the channel struct so TUNE only ! */
+ state->autosearch_state = AS_DONE;
+ *tune_state = CT_DEMOD_STEP_3;
+ }
+ state->symbol_duration = dib8000_get_symbol_duration(state);
+ break;
case CT_DEMOD_SEARCH_NEXT: /* 51 */
- dib8000_autosearch_start(fe);
- if (state->revision == 0x8090)
- ret = 50;
- else
- ret = 15;
- *tune_state = CT_DEMOD_STEP_1;
- break;
+ dib8000_autosearch_start(fe);
+ if (state->revision == 0x8090)
+ ret = 50;
+ else
+ ret = 15;
+ *tune_state = CT_DEMOD_STEP_1;
+ break;
case CT_DEMOD_STEP_1: /* 31 */
- switch (dib8000_autosearch_irq(fe)) {
- case 1: /* fail */
- state->status = FE_STATUS_TUNE_FAILED;
- state->autosearch_state = AS_DONE;
- *tune_state = CT_DEMOD_STOP; /* else we are done here */
- break;
- case 2: /* Succes */
- state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
- *tune_state = CT_DEMOD_STEP_3;
- if (state->autosearch_state == AS_SEARCHING_GUARD)
- *tune_state = CT_DEMOD_STEP_2;
- else
- state->autosearch_state = AS_DONE;
- break;
- case 3: /* Autosearch FFT max correlation endded */
- *tune_state = CT_DEMOD_STEP_2;
- break;
- }
+ switch (dib8000_autosearch_irq(fe)) {
+ case 1: /* fail */
+ state->status = FE_STATUS_TUNE_FAILED;
+ state->autosearch_state = AS_DONE;
+ *tune_state = CT_DEMOD_STOP; /* else we are done here */
+ break;
+ case 2: /* Succes */
+ state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
+ *tune_state = CT_DEMOD_STEP_3;
+ if (state->autosearch_state == AS_SEARCHING_GUARD)
+ *tune_state = CT_DEMOD_STEP_2;
+ else
+ state->autosearch_state = AS_DONE;
break;
+ case 3: /* Autosearch FFT max correlation endded */
+ *tune_state = CT_DEMOD_STEP_2;
+ break;
+ }
+ break;
case CT_DEMOD_STEP_2:
- switch (state->autosearch_state) {
- case AS_SEARCHING_FFT:
- /* searching for the correct FFT */
- if (state->revision == 0x8090) {
- corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
- corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
- corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
- } else {
- corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
- corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
- corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
- }
- /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
+ switch (state->autosearch_state) {
+ case AS_SEARCHING_FFT:
+ /* searching for the correct FFT */
+ if (state->revision == 0x8090) {
+ corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
+ corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
+ corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
+ } else {
+ corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
+ corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
+ corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
+ }
+ /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
- max_value = 0;
- for (find_index = 1 ; find_index < 3 ; find_index++) {
- if (corm[max_value] < corm[find_index])
- max_value = find_index ;
- }
+ max_value = 0;
+ for (find_index = 1 ; find_index < 3 ; find_index++) {
+ if (corm[max_value] < corm[find_index])
+ max_value = find_index ;
+ }
- switch (max_value) {
- case 0:
- state->found_nfft = TRANSMISSION_MODE_2K;
- break;
- case 1:
- state->found_nfft = TRANSMISSION_MODE_4K;
- break;
- case 2:
- default:
- state->found_nfft = TRANSMISSION_MODE_8K;
- break;
- }
- /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
-
- *tune_state = CT_DEMOD_SEARCH_NEXT;
- state->autosearch_state = AS_SEARCHING_GUARD;
- if (state->revision == 0x8090)
- ret = 50;
- else
- ret = 10;
- break;
- case AS_SEARCHING_GUARD:
- /* searching for the correct guard interval */
- if (state->revision == 0x8090)
- state->found_guard = dib8000_read_word(state, 572) & 0x3;
- else
- state->found_guard = dib8000_read_word(state, 570) & 0x3;
- /* dprintk("guard interval found=%i", state->found_guard); */
-
- *tune_state = CT_DEMOD_STEP_3;
- break;
+ switch (max_value) {
+ case 0:
+ state->found_nfft = TRANSMISSION_MODE_2K;
+ break;
+ case 1:
+ state->found_nfft = TRANSMISSION_MODE_4K;
+ break;
+ case 2:
default:
- /* the demod should never be in this state */
- state->status = FE_STATUS_TUNE_FAILED;
- state->autosearch_state = AS_DONE;
- *tune_state = CT_DEMOD_STOP; /* else we are done here */
- break;
+ state->found_nfft = TRANSMISSION_MODE_8K;
+ break;
}
+ /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
+
+ *tune_state = CT_DEMOD_SEARCH_NEXT;
+ state->autosearch_state = AS_SEARCHING_GUARD;
+ if (state->revision == 0x8090)
+ ret = 50;
+ else
+ ret = 10;
break;
+ case AS_SEARCHING_GUARD:
+ /* searching for the correct guard interval */
+ if (state->revision == 0x8090)
+ state->found_guard = dib8000_read_word(state, 572) & 0x3;
+ else
+ state->found_guard = dib8000_read_word(state, 570) & 0x3;
+ /* dprintk("guard interval found=%i", state->found_guard); */
- case CT_DEMOD_STEP_3: /* 33 */
- state->symbol_duration = dib8000_get_symbol_duration(state);
- dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
- dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
- *tune_state = CT_DEMOD_STEP_4;
+ *tune_state = CT_DEMOD_STEP_3;
break;
+ default:
+ /* the demod should never be in this state */
+ state->status = FE_STATUS_TUNE_FAILED;
+ state->autosearch_state = AS_DONE;
+ *tune_state = CT_DEMOD_STOP; /* else we are done here */
+ break;
+ }
+ break;
+
+ case CT_DEMOD_STEP_3: /* 33 */
+ dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
+ dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
+ *tune_state = CT_DEMOD_STEP_4;
+ break;
case CT_DEMOD_STEP_4: /* (34) */
- dib8000_demod_restart(state);
+ dib8000_demod_restart(state);
- dib8000_set_sync_wait(state);
- dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
+ dib8000_set_sync_wait(state);
+ dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
- locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
- /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */
- *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
- *tune_state = CT_DEMOD_STEP_5;
- break;
+ locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
+ /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */
+ *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
+ *tune_state = CT_DEMOD_STEP_5;
+ break;
case CT_DEMOD_STEP_5: /* (35) */
- locks = dib8000_read_lock(fe);
- if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
- dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
- if (!state->differential_constellation) {
- /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
- *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
- *tune_state = CT_DEMOD_STEP_7;
- } else {
- *tune_state = CT_DEMOD_STEP_8;
- }
- } else if (now > *timeout) {
- *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
+ locks = dib8000_read_lock(fe);
+ if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
+ dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
+ if (!state->differential_constellation) {
+ /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
+ *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
+ *tune_state = CT_DEMOD_STEP_7;
+ } else {
+ *tune_state = CT_DEMOD_STEP_8;
}
- break;
+ } else if (time_after(now, *timeout)) {
+ *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
+ }
+ break;
case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
- if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
- /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
- if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
- *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
- else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
- *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
- dib8000_viterbi_state(state, 1); /* start viterbi chandec */
- dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
- state->status = FE_STATUS_TUNE_FAILED;
- }
- } else {
+ if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
+ /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
+ if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
+ *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
+ else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
+ *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
dib8000_viterbi_state(state, 1); /* start viterbi chandec */
dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
- *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
state->status = FE_STATUS_TUNE_FAILED;
}
- break;
+ } else {
+ dib8000_viterbi_state(state, 1); /* start viterbi chandec */
+ dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
+ *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
+ state->status = FE_STATUS_TUNE_FAILED;
+ }
+ break;
case CT_DEMOD_STEP_7: /* 37 */
- locks = dib8000_read_lock(fe);
- if (locks & (1<<10)) { /* lmod4_lock */
- ret = 14; /* wait for 14 symbols */
- *tune_state = CT_DEMOD_STEP_8;
- } else if (now > *timeout)
- *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
- break;
+ locks = dib8000_read_lock(fe);
+ if (locks & (1<<10)) { /* lmod4_lock */
+ ret = 14; /* wait for 14 symbols */
+ *tune_state = CT_DEMOD_STEP_8;
+ } else if (time_after(now, *timeout))
+ *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
+ break;
case CT_DEMOD_STEP_8: /* 38 */
- dib8000_viterbi_state(state, 1); /* start viterbi chandec */
- dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
-
- /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
- if (c->isdbt_sb_mode
- && c->isdbt_sb_subchannel < 14
- && !state->differential_constellation) {
- state->subchannel = 0;
- *tune_state = CT_DEMOD_STEP_11;
- } else {
- *tune_state = CT_DEMOD_STEP_9;
- state->status = FE_STATUS_LOCKED;
- }
- break;
+ dib8000_viterbi_state(state, 1); /* start viterbi chandec */
+ dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
+
+ /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
+ if (c->isdbt_sb_mode
+ && c->isdbt_sb_subchannel < 14
+ && !state->differential_constellation) {
+ state->subchannel = 0;
+ *tune_state = CT_DEMOD_STEP_11;
+ } else {
+ *tune_state = CT_DEMOD_STEP_9;
+ state->status = FE_STATUS_LOCKED;
+ }
+ break;
case CT_DEMOD_STEP_9: /* 39 */
- if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
- /* defines timeout for mpeg lock depending on interleaver length of longest layer */
- for (i = 0; i < 3; i++) {
- if (c->layer[i].interleaving >= deeper_interleaver) {
- dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
- if (c->layer[i].segment_count > 0) { /* valid layer */
- deeper_interleaver = c->layer[0].interleaving;
- state->longest_intlv_layer = i;
- }
+ if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
+ /* defines timeout for mpeg lock depending on interleaver length of longest layer */
+ for (i = 0; i < 3; i++) {
+ if (c->layer[i].interleaving >= deeper_interleaver) {
+ dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
+ if (c->layer[i].segment_count > 0) { /* valid layer */
+ deeper_interleaver = c->layer[0].interleaving;
+ state->longest_intlv_layer = i;
}
}
+ }
- if (deeper_interleaver == 0)
- locks = 2; /* locks is the tmp local variable name */
- else if (deeper_interleaver == 3)
- locks = 8;
- else
- locks = 2 * deeper_interleaver;
+ if (deeper_interleaver == 0)
+ locks = 2; /* locks is the tmp local variable name */
+ else if (deeper_interleaver == 3)
+ locks = 8;
+ else
+ locks = 2 * deeper_interleaver;
- if (state->diversity_onoff != 0) /* because of diversity sync */
- locks *= 2;
+ if (state->diversity_onoff != 0) /* because of diversity sync */
+ locks *= 2;
- *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
- dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
+ *timeout = now + msecs_to_jiffies(200 * locks); /* give the mpeg lock 800ms if sram is present */
+ dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %ld",
+ deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
- *tune_state = CT_DEMOD_STEP_10;
- } else
- *tune_state = CT_DEMOD_STOP;
- break;
+ *tune_state = CT_DEMOD_STEP_10;
+ } else
+ *tune_state = CT_DEMOD_STOP;
+ break;
case CT_DEMOD_STEP_10: /* 40 */
- locks = dib8000_read_lock(fe);
- if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
- dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
- if (c->isdbt_sb_mode
- && c->isdbt_sb_subchannel < 14
- && !state->differential_constellation)
- /* signal to the upper layer, that there was a channel found and the parameters can be read */
- state->status = FE_STATUS_DEMOD_SUCCESS;
- else
+ locks = dib8000_read_lock(fe);
+ if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
+ dprintk("ISDB-T layer locks: Layer A %s, Layer B %s, Layer C %s",
+ c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled",
+ c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled",
+ c->layer[2].segment_count ? (locks >> 5) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled");
+ if (c->isdbt_sb_mode
+ && c->isdbt_sb_subchannel < 14
+ && !state->differential_constellation)
+ /* signal to the upper layer, that there was a channel found and the parameters can be read */
+ state->status = FE_STATUS_DEMOD_SUCCESS;
+ else
+ state->status = FE_STATUS_DATA_LOCKED;
+ *tune_state = CT_DEMOD_STOP;
+ } else if (time_after(now, *timeout)) {
+ if (c->isdbt_sb_mode
+ && c->isdbt_sb_subchannel < 14
+ && !state->differential_constellation) { /* continue to try init prbs autosearch */
+ state->subchannel += 3;
+ *tune_state = CT_DEMOD_STEP_11;
+ } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
+ if (locks & (0x7 << 5)) {
+ dprintk("Not all ISDB-T layers locked in %d ms: Layer A %s, Layer B %s, Layer C %s",
+ jiffies_to_msecs(now - *timeout),
+ c->layer[0].segment_count ? (locks >> 7) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled",
+ c->layer[1].segment_count ? (locks >> 6) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled",
+ c->layer[2].segment_count ? (locks >> 5) & 0x1 ? "locked" : "NOT LOCKED" : "not enabled");
+
state->status = FE_STATUS_DATA_LOCKED;
+ } else
+ state->status = FE_STATUS_TUNE_FAILED;
*tune_state = CT_DEMOD_STOP;
- } else if (now > *timeout) {
- if (c->isdbt_sb_mode
- && c->isdbt_sb_subchannel < 14
- && !state->differential_constellation) { /* continue to try init prbs autosearch */
- state->subchannel += 3;
- *tune_state = CT_DEMOD_STEP_11;
- } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
- if (locks & (0x7<<5)) {
- dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
- state->status = FE_STATUS_DATA_LOCKED;
- } else
- state->status = FE_STATUS_TUNE_FAILED;
- *tune_state = CT_DEMOD_STOP;
- }
}
- break;
+ }
+ break;
case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
- if (state->subchannel <= 41) {
- dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
- *tune_state = CT_DEMOD_STEP_9;
- } else {
- *tune_state = CT_DEMOD_STOP;
- state->status = FE_STATUS_TUNE_FAILED;
- }
- break;
+ if (state->subchannel <= 41) {
+ dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
+ *tune_state = CT_DEMOD_STEP_9;
+ } else {
+ *tune_state = CT_DEMOD_STOP;
+ state->status = FE_STATUS_TUNE_FAILED;
+ }
+ break;
default:
- break;
+ break;
}
/* tuning is finished - cleanup the demod */
switch (*tune_state) {
case CT_DEMOD_STOP: /* (42) */
#ifdef DIB8000_AGC_FREEZE
- if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
- dib8000_write_word(state, 108, state->agc1_max);
- dib8000_write_word(state, 109, state->agc1_min);
- dib8000_write_word(state, 110, state->agc2_max);
- dib8000_write_word(state, 111, state->agc2_min);
- state->agc1_max = 0;
- state->agc1_min = 0;
- state->agc2_max = 0;
- state->agc2_min = 0;
- }
+ if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
+ dib8000_write_word(state, 108, state->agc1_max);
+ dib8000_write_word(state, 109, state->agc1_min);
+ dib8000_write_word(state, 110, state->agc2_max);
+ dib8000_write_word(state, 111, state->agc2_min);
+ state->agc1_max = 0;
+ state->agc1_min = 0;
+ state->agc2_max = 0;
+ state->agc2_min = 0;
+ }
#endif
- ret = FE_CALLBACK_TIME_NEVER;
- break;
+ ret = 0;
+ break;
default:
- break;
+ break;
}
if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
@@ -3408,7 +3399,7 @@ static int dib8000_get_frontend(struct dvb_frontend *fe)
if (!(stat & FE_HAS_SYNC))
return 0;
- dprintk("TMCC lock");
+ dprintk("dib8000_get_frontend: TMCC lock");
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
if (stat&FE_HAS_SYNC) {
@@ -3444,91 +3435,117 @@ static int dib8000_get_frontend(struct dvb_frontend *fe)
switch ((val & 0x30) >> 4) {
case 1:
fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
+ dprintk("dib8000_get_frontend: transmission mode 2K");
+ break;
+ case 2:
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
+ dprintk("dib8000_get_frontend: transmission mode 4K");
break;
case 3:
default:
fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+ dprintk("dib8000_get_frontend: transmission mode 8K");
break;
}
switch (val & 0x3) {
case 0:
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
- dprintk("dib8000_get_frontend GI = 1/32 ");
+ dprintk("dib8000_get_frontend: Guard Interval = 1/32 ");
break;
case 1:
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
- dprintk("dib8000_get_frontend GI = 1/16 ");
+ dprintk("dib8000_get_frontend: Guard Interval = 1/16 ");
break;
case 2:
- dprintk("dib8000_get_frontend GI = 1/8 ");
+ dprintk("dib8000_get_frontend: Guard Interval = 1/8 ");
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
break;
case 3:
- dprintk("dib8000_get_frontend GI = 1/4 ");
+ dprintk("dib8000_get_frontend: Guard Interval = 1/4 ");
fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
break;
}
val = dib8000_read_word(state, 505);
fe->dtv_property_cache.isdbt_partial_reception = val & 1;
- dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
+ dprintk("dib8000_get_frontend: partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
for (i = 0; i < 3; i++) {
- val = dib8000_read_word(state, 493 + i);
- fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
- dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
+ int show;
+
+ val = dib8000_read_word(state, 493 + i) & 0x0f;
+ fe->dtv_property_cache.layer[i].segment_count = val;
+
+ if (val == 0 || val > 13)
+ show = 0;
+ else
+ show = 1;
+
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d segments = %d ",
+ i, fe->dtv_property_cache.layer[i].segment_count);
val = dib8000_read_word(state, 499 + i) & 0x3;
/* Interleaving can be 0, 1, 2 or 4 */
if (val == 3)
val = 4;
fe->dtv_property_cache.layer[i].interleaving = val;
- dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ",
- i, fe->dtv_property_cache.layer[i].interleaving);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d time_intlv = %d ",
+ i, fe->dtv_property_cache.layer[i].interleaving);
val = dib8000_read_word(state, 481 + i);
switch (val & 0x7) {
case 1:
fe->dtv_property_cache.layer[i].fec = FEC_1_2;
- dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d Code Rate = 1/2 ", i);
break;
case 2:
fe->dtv_property_cache.layer[i].fec = FEC_2_3;
- dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d Code Rate = 2/3 ", i);
break;
case 3:
fe->dtv_property_cache.layer[i].fec = FEC_3_4;
- dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d Code Rate = 3/4 ", i);
break;
case 5:
fe->dtv_property_cache.layer[i].fec = FEC_5_6;
- dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d Code Rate = 5/6 ", i);
break;
default:
fe->dtv_property_cache.layer[i].fec = FEC_7_8;
- dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d Code Rate = 7/8 ", i);
break;
}
val = dib8000_read_word(state, 487 + i);
switch (val & 0x3) {
case 0:
- dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
fe->dtv_property_cache.layer[i].modulation = DQPSK;
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d DQPSK ", i);
break;
case 1:
fe->dtv_property_cache.layer[i].modulation = QPSK;
- dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d QPSK ", i);
break;
case 2:
fe->dtv_property_cache.layer[i].modulation = QAM_16;
- dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d QAM16 ", i);
break;
case 3:
default:
- dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
fe->dtv_property_cache.layer[i].modulation = QAM_64;
+ if (show)
+ dprintk("dib8000_get_frontend: Layer %d QAM64 ", i);
break;
}
}
@@ -3554,9 +3571,9 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
{
struct dib8000_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
- int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
+ int l, i, active, time, time_slave = 0;
u8 exit_condition, index_frontend;
- u32 delay, callback_time;
+ unsigned long delay, callback_time;
if (c->frequency == 0) {
dprintk("dib8000: must at least specify frequency ");
@@ -3608,15 +3625,24 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
time = dib8000_agc_startup(state->fe[0]);
for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
time_slave = dib8000_agc_startup(state->fe[index_frontend]);
- if (time == FE_CALLBACK_TIME_NEVER)
+ if (time == 0)
time = time_slave;
- else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
+ else if ((time_slave != 0) && (time_slave > time))
time = time_slave;
}
- if (time != FE_CALLBACK_TIME_NEVER)
- msleep(time / 10);
- else
+ if (time == 0)
break;
+
+ /*
+ * Despite dib8000_agc_startup returns time at a 0.1 ms range,
+ * the actual sleep time depends on CONFIG_HZ. The worse case
+ * is when CONFIG_HZ=100. In such case, the minimum granularity
+ * is 10ms. On some real field tests, the tuner sometimes don't
+ * lock when this timer is lower than 10ms. So, enforce a 10ms
+ * granularity.
+ */
+ time = 10 * (time + 99)/100;
+ usleep_range(time * 1000, (time + 1) * 1000);
exit_condition = 1;
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
@@ -3631,11 +3657,14 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
active = 1;
do {
- callback_time = FE_CALLBACK_TIME_NEVER;
+ callback_time = 0;
for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
delay = dib8000_tune(state->fe[index_frontend]);
- if (delay != FE_CALLBACK_TIME_NEVER)
- delay += systime();
+ if (delay != 0) {
+ delay = jiffies + usecs_to_jiffies(100 * delay);
+ if (!callback_time || delay < callback_time)
+ callback_time = delay;
+ }
/* we are in autosearch */
if (state->channel_parameters_set == 0) { /* searching */
@@ -3646,6 +3675,7 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
if (l != index_frontend) { /* and for all frontend except the successful one */
+ dprintk("Restarting frontend %d\n", l);
dib8000_tune_restart_from_demod(state->fe[l]);
state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
@@ -3664,8 +3694,6 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
}
}
}
- if (delay < callback_time)
- callback_time = delay;
}
/* tuning is done when the master frontend is done (failed or success) */
if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
@@ -3681,12 +3709,12 @@ static int dib8000_set_frontend(struct dvb_frontend *fe)
dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
}
- if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
+ if ((active == 1) && (callback_time == 0)) {
dprintk("strange callback time something went wrong");
active = 0;
}
- while ((active == 1) && (systime() < callback_time))
+ while ((active == 1) && (time_before(jiffies, callback_time)))
msleep(100);
} while (active);
@@ -4201,7 +4229,7 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat)
return 0;
}
-int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
+static int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
{
struct dib8000_state *state = fe->demodulator_priv;
u8 index_frontend = 1;
@@ -4217,9 +4245,8 @@ int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_
dprintk("too many slave frontend");
return -ENOMEM;
}
-EXPORT_SYMBOL(dib8000_set_slave_frontend);
-int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
+static int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
{
struct dib8000_state *state = fe->demodulator_priv;
u8 index_frontend = 1;
@@ -4235,9 +4262,8 @@ int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
dprintk("no frontend to be removed");
return -ENODEV;
}
-EXPORT_SYMBOL(dib8000_remove_slave_frontend);
-struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+static struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
{
struct dib8000_state *state = fe->demodulator_priv;
@@ -4245,10 +4271,8 @@ struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int sla
return NULL;
return state->fe[slave_index];
}
-EXPORT_SYMBOL(dib8000_get_slave_frontend);
-
-int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
u8 default_addr, u8 first_addr, u8 is_dib8096p)
{
int k = 0, ret = 0;
@@ -4325,7 +4349,6 @@ error_memory_read:
return ret;
}
-EXPORT_SYMBOL(dib8000_i2c_enumeration);
static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1000;
@@ -4348,15 +4371,13 @@ static void dib8000_release(struct dvb_frontend *fe)
kfree(st);
}
-struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+static struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
{
struct dib8000_state *st = fe->demodulator_priv;
return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
}
-EXPORT_SYMBOL(dib8000_get_i2c_master);
-
-int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
+static int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
{
struct dib8000_state *st = fe->demodulator_priv;
u16 val = dib8000_read_word(st, 299) & 0xffef;
@@ -4365,15 +4386,13 @@ int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
dprintk("pid filter enabled %d", onoff);
return dib8000_write_word(st, 299, val);
}
-EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
-int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
+static int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
{
struct dib8000_state *st = fe->demodulator_priv;
dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
}
-EXPORT_SYMBOL(dib8000_pid_filter);
static const struct dvb_frontend_ops dib8000_ops = {
.delsys = { SYS_ISDBT },
@@ -4405,12 +4424,12 @@ static const struct dvb_frontend_ops dib8000_ops = {
.read_ucblocks = dib8000_read_unc_blocks,
};
-struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
{
struct dvb_frontend *fe;
struct dib8000_state *state;
- dprintk("dib8000_attach");
+ dprintk("dib8000_init");
state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
if (state == NULL)
@@ -4467,6 +4486,33 @@ error:
return NULL;
}
+void *dib8000_attach(struct dib8000_ops *ops)
+{
+ if (!ops)
+ return NULL;
+
+ ops->pwm_agc_reset = dib8000_pwm_agc_reset;
+ ops->get_dc_power = dib8090p_get_dc_power;
+ ops->set_gpio = dib8000_set_gpio;
+ ops->get_slave_frontend = dib8000_get_slave_frontend;
+ ops->set_tune_state = dib8000_set_tune_state;
+ ops->pid_filter_ctrl = dib8000_pid_filter_ctrl;
+ ops->remove_slave_frontend = dib8000_remove_slave_frontend;
+ ops->get_adc_power = dib8000_get_adc_power;
+ ops->update_pll = dib8000_update_pll;
+ ops->tuner_sleep = dib8096p_tuner_sleep;
+ ops->get_tune_state = dib8000_get_tune_state;
+ ops->get_i2c_tuner = dib8096p_get_i2c_tuner;
+ ops->set_slave_frontend = dib8000_set_slave_frontend;
+ ops->pid_filter = dib8000_pid_filter;
+ ops->ctrl_timf = dib8000_ctrl_timf;
+ ops->init = dib8000_init;
+ ops->get_i2c_master = dib8000_get_i2c_master;
+ ops->i2c_enumeration = dib8000_i2c_enumeration;
+ ops->set_wbd_ref = dib8000_set_wbd_ref;
+
+ return ops;
+}
EXPORT_SYMBOL(dib8000_attach);
MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb-frontends/dib8000.h b/drivers/media/dvb-frontends/dib8000.h
index b8c11e52c512..84cc10383dcd 100644
--- a/drivers/media/dvb-frontends/dib8000.h
+++ b/drivers/media/dvb-frontends/dib8000.h
@@ -39,134 +39,34 @@ struct dib8000_config {
#define DEFAULT_DIB8000_I2C_ADDRESS 18
-#if IS_ENABLED(CONFIG_DVB_DIB8000)
-extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
-extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
-
-extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+struct dib8000_ops {
+ int (*set_wbd_ref)(struct dvb_frontend *fe, u16 value);
+ int (*update_pll)(struct dvb_frontend *fe,
+ struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
+ int (*set_gpio)(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
+ void (*pwm_agc_reset)(struct dvb_frontend *fe);
+ struct i2c_adapter *(*get_i2c_tuner)(struct dvb_frontend *fe);
+ int (*tuner_sleep)(struct dvb_frontend *fe, int onoff);
+ s32 (*get_adc_power)(struct dvb_frontend *fe, u8 mode);
+ int (*get_dc_power)(struct dvb_frontend *fe, u8 IQ);
+ u32 (*ctrl_timf)(struct dvb_frontend *fe, uint8_t op, uint32_t timf);
+ enum frontend_tune_state (*get_tune_state)(struct dvb_frontend *fe);
+ int (*set_tune_state)(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
+ int (*set_slave_frontend)(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
+ int (*remove_slave_frontend)(struct dvb_frontend *fe);
+ struct dvb_frontend *(*get_slave_frontend)(struct dvb_frontend *fe, int slave_index);
+ int (*i2c_enumeration)(struct i2c_adapter *host, int no_of_demods,
u8 default_addr, u8 first_addr, u8 is_dib8096p);
+ struct i2c_adapter *(*get_i2c_master)(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
+ int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff);
+ int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
+ struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
+};
-extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
-extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
-extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
-extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
-extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
-extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
-extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
-extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
-extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
-extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
-extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
-extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
- uint8_t op, uint32_t timf);
-extern int dib8000_update_pll(struct dvb_frontend *fe,
- struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
-extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
-extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
-extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
+#if IS_ENABLED(CONFIG_DVB_DIB8000)
+void *dib8000_attach(struct dib8000_ops *ops);
#else
-static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-
-static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
- int no_of_demods, u8 default_addr, u8 first_addr,
- u8 is_dib8096p)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return CT_SHUTDOWN;
-}
-static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-}
-static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
- uint8_t op, uint32_t timf)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return 0;
-}
-static inline int dib8000_update_pll(struct dvb_frontend *fe,
- struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return -ENODEV;
-}
-
-static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
+static inline int dib8000_attach(struct dib8000_ops *ops)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index e540cfb13bac..f75dec443783 100644
--- a/drivers/media/dvb-frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
@@ -1040,13 +1040,18 @@ static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 addres
if (address >= 1024 || !state->platform.risc.fw_is_running)
return -EINVAL;
+ if (len > 18)
+ return -EINVAL;
+
/* dprintk( "APB access thru wr fw %d %x", address, attribute); */
- mb[0] = (unsigned short)address;
- for (i = 0; i < len && i < 20; i += 2)
- mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
+ mb[0] = (u16)address;
+ for (i = 0; i + 1 < len; i += 2)
+ mb[1 + i / 2] = b[i] << 8 | b[i + 1];
+ if (len & 1)
+ mb[1 + len / 2] = b[len - 1] << 8;
- dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
+ dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);
return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
}
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 9482954fd453..7ca7a21df183 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -2159,7 +2159,7 @@ int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
@@ -2252,7 +2252,7 @@ static int hi_cfg_command(const struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -2363,7 +2363,7 @@ hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16
/* if ( powerdown_cmd == true ) */
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -2434,7 +2434,7 @@ static int init_hi(const struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -2650,7 +2650,7 @@ static int get_device_capabilities(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -3338,7 +3338,7 @@ ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_o
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*----------------------------------------------------------------------------*/
@@ -3421,7 +3421,7 @@ static int set_mpegtei_handling(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*----------------------------------------------------------------------------*/
@@ -3464,7 +3464,7 @@ static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*----------------------------------------------------------------------------*/
@@ -3508,7 +3508,7 @@ static int set_mpeg_start_width(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*----------------------------------------------------------------------------*/
@@ -3652,7 +3652,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -3854,7 +3854,7 @@ ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*---------------------------------------------------------------------------*/
@@ -3969,7 +3969,7 @@ static int smart_ant_init(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
@@ -4109,7 +4109,7 @@ static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -4178,7 +4178,7 @@ int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 a
return 0;
rw_error:
- return -EIO;
+ return rc;
}
@@ -4290,7 +4290,7 @@ static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -4349,7 +4349,7 @@ static int adc_synchronization(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -4734,7 +4734,7 @@ static int init_agc(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -4831,7 +4831,7 @@ set_frequency(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -4879,7 +4879,7 @@ static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
#endif
@@ -5097,7 +5097,7 @@ set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -5326,7 +5326,7 @@ set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -5362,7 +5362,7 @@ static int set_iqm_af(struct drx_demod_instance *demod, bool active)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -5470,7 +5470,7 @@ static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -5686,7 +5686,7 @@ static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -6192,7 +6192,7 @@ static int set_vsb(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -6231,7 +6231,7 @@ static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -6276,7 +6276,7 @@ static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -6321,7 +6321,7 @@ static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
@@ -6434,7 +6434,7 @@ static int power_down_qam(struct drx_demod_instance *demod, bool primary)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -6646,7 +6646,7 @@ set_qam_measurement(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -6881,7 +6881,7 @@ static int set_qam16(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -7116,7 +7116,7 @@ static int set_qam32(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -7351,7 +7351,7 @@ static int set_qam64(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -7586,7 +7586,7 @@ static int set_qam128(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -7821,7 +7821,7 @@ static int set_qam256(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -8650,7 +8650,7 @@ set_qam(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -8831,7 +8831,7 @@ static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *c
return 0;
rw_error:
- return -EIO;
+ return rc;
}
@@ -8984,7 +8984,7 @@ qam64auto(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -9068,7 +9068,7 @@ qam256auto(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -9273,7 +9273,7 @@ rw_error:
/* restore starting value */
if (auto_flag)
channel->constellation = DRX_CONSTELLATION_AUTO;
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -9344,7 +9344,7 @@ get_qamrs_err_count(struct i2c_device_addr *dev_addr,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -9425,8 +9425,8 @@ static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
*sig_strength = 0;
return 0;
- rw_error:
- return -EIO;
+rw_error:
+ return rc;
}
/**
@@ -9643,7 +9643,7 @@ rw_error:
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
- return -EIO;
+ return rc;
}
#endif /* #ifndef DRXJ_VSB_ONLY */
@@ -9810,7 +9810,7 @@ power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, boo
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -9840,7 +9840,7 @@ static int power_down_aud(struct drx_demod_instance *demod)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -9874,7 +9874,7 @@ static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/**
@@ -10398,7 +10398,7 @@ static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_par
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -10638,7 +10638,7 @@ ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*=============================================================================
@@ -10756,7 +10756,7 @@ ctrl_sig_quality(struct drx_demod_instance *demod,
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -10844,7 +10844,7 @@ ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_st
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -10941,7 +10941,7 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
rw_error:
/* Don't know what the standard is now ... try again */
ext_attr->standard = DRX_STANDARD_UNKNOWN;
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -11222,7 +11222,7 @@ ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -11303,7 +11303,7 @@ ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain
return 0;
rw_error:
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -11315,6 +11315,7 @@ rw_error:
static int drx_ctrl_u_code(struct drx_demod_instance *demod,
struct drxu_code_info *mc_info,
enum drxu_code_action action);
+static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
/**
* \fn drxj_open()
@@ -11527,10 +11528,11 @@ static int drxj_open(struct drx_demod_instance *demod)
ext_attr->aud_data = drxj_default_aud_data_g;
demod->my_common_attr->is_opened = true;
+ drxj_set_lna_state(demod, false);
return 0;
rw_error:
common_attr->is_opened = false;
- return -EIO;
+ return rc;
}
/*============================================================================*/
@@ -11578,7 +11580,7 @@ static int drxj_close(struct drx_demod_instance *demod)
rw_error:
DRX_ATTR_ISOPENED(demod) = false;
- return -EIO;
+ return rc;
}
/*
@@ -11890,6 +11892,33 @@ release:
return rc;
}
+/* caller is expeced to check if lna is supported before enabling */
+static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
+{
+ struct drxuio_cfg uio_cfg;
+ struct drxuio_data uio_data;
+ int result;
+
+ uio_cfg.uio = DRX_UIO1;
+ uio_cfg.mode = DRX_UIO_MODE_READWRITE;
+ /* Configure user-I/O #3: enable read/write */
+ result = ctrl_set_uio_cfg(demod, &uio_cfg);
+ if (result) {
+ pr_err("Failed to setup LNA GPIO!\n");
+ return result;
+ }
+
+ uio_data.uio = DRX_UIO1;
+ uio_data.value = state;
+ result = ctrl_uio_write(demod, &uio_data);
+ if (result != 0) {
+ pr_err("Failed to %sable LNA!\n",
+ state ? "en" : "dis");
+ return result;
+ }
+ return 0;
+}
+
/*
* The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
*
@@ -12040,7 +12069,6 @@ static int drx39xxj_set_frontend(struct dvb_frontend *fe)
enum drx_standard standard = DRX_STANDARD_8VSB;
struct drx_channel channel;
int result;
- struct drxuio_data uio_data;
static const struct drx_channel def_channel = {
/* frequency */ 0,
/* bandwidth */ DRX_BANDWIDTH_6MHZ,
@@ -12125,13 +12153,7 @@ static int drx39xxj_set_frontend(struct dvb_frontend *fe)
return -EINVAL;
}
/* Just for giggles, let's shut off the LNA again.... */
- uio_data.uio = DRX_UIO1;
- uio_data.value = false;
- result = ctrl_uio_write(demod, &uio_data);
- if (result != 0) {
- pr_err("Failed to disable LNA!\n");
- return 0;
- }
+ drxj_set_lna_state(demod, false);
/* After set_frontend, except for strength, stats aren't available */
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
@@ -12180,21 +12202,28 @@ static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
static int drx39xxj_init(struct dvb_frontend *fe)
{
- /* Bring the demod out of sleep */
- drx39xxj_set_powerstate(fe, 1);
+ struct drx39xxj_state *state = fe->demodulator_priv;
+ struct drx_demod_instance *demod = state->demod;
+ int rc = 0;
- return 0;
+ if (fe->exit == DVB_FE_DEVICE_RESUME) {
+ /* so drxj_open() does what it needs to do */
+ demod->my_common_attr->is_opened = false;
+ rc = drxj_open(demod);
+ if (rc != 0)
+ pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
+ } else
+ drx39xxj_set_powerstate(fe, 1);
+
+ return rc;
}
static int drx39xxj_set_lna(struct dvb_frontend *fe)
{
- int result;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct drx39xxj_state *state = fe->demodulator_priv;
struct drx_demod_instance *demod = state->demod;
struct drxj_data *ext_attr = demod->my_ext_attr;
- struct drxuio_cfg uio_cfg;
- struct drxuio_data uio_data;
if (c->lna) {
if (!ext_attr->has_lna) {
@@ -12204,26 +12233,7 @@ static int drx39xxj_set_lna(struct dvb_frontend *fe)
}
}
- /* Turn off the LNA */
- uio_cfg.uio = DRX_UIO1;
- uio_cfg.mode = DRX_UIO_MODE_READWRITE;
- /* Configure user-I/O #3: enable read/write */
- result = ctrl_set_uio_cfg(demod, &uio_cfg);
- if (result) {
- pr_err("Failed to setup LNA GPIO!\n");
- return result;
- }
-
- uio_data.uio = DRX_UIO1;
- uio_data.value = c->lna;
- result = ctrl_uio_write(demod, &uio_data);
- if (result != 0) {
- pr_err("Failed to %sable LNA!\n",
- c->lna ? "en" : "dis");
- return result;
- }
-
- return 0;
+ return drxj_set_lna_state(demod, c->lna);
}
static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
@@ -12238,7 +12248,9 @@ static void drx39xxj_release(struct dvb_frontend *fe)
struct drx39xxj_state *state = fe->demodulator_priv;
struct drx_demod_instance *demod = state->demod;
- drxj_close(demod);
+ /* if device is removed don't access it */
+ if (fe->exit != DVB_FE_DEVICE_REMOVED)
+ drxj_close(demod);
kfree(demod->my_ext_attr);
kfree(demod->my_common_attr);
@@ -12259,8 +12271,6 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
struct drxj_data *demod_ext_attr = NULL;
struct drx_demod_instance *demod = NULL;
struct dtv_frontend_properties *p;
- struct drxuio_cfg uio_cfg;
- struct drxuio_data uio_data;
int result;
/* allocate memory for the internal state */
@@ -12272,22 +12282,20 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
if (demod == NULL)
goto error;
- demod_addr = kmalloc(sizeof(struct i2c_device_addr), GFP_KERNEL);
+ demod_addr = kmemdup(&drxj_default_addr_g,
+ sizeof(struct i2c_device_addr), GFP_KERNEL);
if (demod_addr == NULL)
goto error;
- memcpy(demod_addr, &drxj_default_addr_g,
- sizeof(struct i2c_device_addr));
- demod_comm_attr = kmalloc(sizeof(struct drx_common_attr), GFP_KERNEL);
+ demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
+ sizeof(struct drx_common_attr), GFP_KERNEL);
if (demod_comm_attr == NULL)
goto error;
- memcpy(demod_comm_attr, &drxj_default_comm_attr_g,
- sizeof(struct drx_common_attr));
- demod_ext_attr = kmalloc(sizeof(struct drxj_data), GFP_KERNEL);
+ demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
+ GFP_KERNEL);
if (demod_ext_attr == NULL)
goto error;
- memcpy(demod_ext_attr, &drxj_data_g, sizeof(struct drxj_data));
/* setup the state */
state->i2c = i2c;
@@ -12313,24 +12321,6 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
goto error;
}
- /* Turn off the LNA */
- uio_cfg.uio = DRX_UIO1;
- uio_cfg.mode = DRX_UIO_MODE_READWRITE;
- /* Configure user-I/O #3: enable read/write */
- result = ctrl_set_uio_cfg(demod, &uio_cfg);
- if (result) {
- pr_err("Failed to setup LNA GPIO!\n");
- goto error;
- }
-
- uio_data.uio = DRX_UIO1;
- uio_data.value = false;
- result = ctrl_uio_write(demod, &uio_data);
- if (result != 0) {
- pr_err("Failed to disable LNA!\n");
- goto error;
- }
-
/* create dvb_frontend */
memcpy(&state->frontend.ops, &drx39xxj_ops,
sizeof(struct dvb_frontend_ops));
diff --git a/drivers/media/dvb-frontends/drxd.h b/drivers/media/dvb-frontends/drxd.h
index 5f1d6b5f1685..d998e4d5a7fc 100644
--- a/drivers/media/dvb-frontends/drxd.h
+++ b/drivers/media/dvb-frontends/drxd.h
@@ -69,5 +69,4 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config,
}
#endif
-extern int drxd_config_i2c(struct dvb_frontend *, int);
#endif
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 5b87ece69414..ae2276db77bc 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -2840,7 +2840,7 @@ static int drxd_init(struct dvb_frontend *fe)
return err;
}
-int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
+static int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
{
struct drxd_state *state = fe->demodulator_priv;
@@ -2849,7 +2849,6 @@ int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
return DRX_ConfigureI2CBridge(state, onoff);
}
-EXPORT_SYMBOL(drxd_config_i2c);
static int drxd_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *sets)
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
index 2ef8ce13fb60..dfe0c2f7f1ef 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -879,7 +879,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * ln(X) / ln(10) dB */
tmp = DIV_ROUND_CLOSEST(tmp, 8 * M88DS3103_SNR_ITERATIONS);
if (tmp)
- *snr = 100ul * intlog2(tmp) / intlog2(10);
+ *snr = div_u64((u64) 100 * intlog2(tmp), intlog2(10));
else
*snr = 0;
break;
@@ -908,7 +908,7 @@ static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *snr)
/* SNR(X) dB = 10 * log10(X) dB */
if (signal > noise) {
tmp = signal / noise;
- *snr = 100ul * intlog10(tmp) / (1 << 24);
+ *snr = div_u64((u64) 100 * intlog10(tmp), (1 << 24));
} else {
*snr = 0;
}
@@ -926,6 +926,86 @@ err:
return ret;
}
+static int m88ds3103_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct m88ds3103_priv *priv = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret;
+ unsigned int utmp;
+ u8 buf[3], u8tmp;
+ dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+
+ switch (c->delivery_system) {
+ case SYS_DVBS:
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x04);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_rd_reg(priv, 0xf8, &u8tmp);
+ if (ret)
+ goto err;
+
+ if (!(u8tmp & 0x10)) {
+ u8tmp |= 0x10;
+
+ ret = m88ds3103_rd_regs(priv, 0xf6, buf, 2);
+ if (ret)
+ goto err;
+
+ priv->ber = (buf[1] << 8) | (buf[0] << 0);
+
+ /* restart counters */
+ ret = m88ds3103_wr_reg(priv, 0xf8, u8tmp);
+ if (ret)
+ goto err;
+ }
+ break;
+ case SYS_DVBS2:
+ ret = m88ds3103_rd_regs(priv, 0xd5, buf, 3);
+ if (ret)
+ goto err;
+
+ utmp = (buf[2] << 16) | (buf[1] << 8) | (buf[0] << 0);
+
+ if (utmp > 3000) {
+ ret = m88ds3103_rd_regs(priv, 0xf7, buf, 2);
+ if (ret)
+ goto err;
+
+ priv->ber = (buf[1] << 8) | (buf[0] << 0);
+
+ /* restart counters */
+ ret = m88ds3103_wr_reg(priv, 0xd1, 0x01);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x01);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xf9, 0x00);
+ if (ret)
+ goto err;
+
+ ret = m88ds3103_wr_reg(priv, 0xd1, 0x00);
+ if (ret)
+ goto err;
+ }
+ break;
+ default:
+ dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ *ber = priv->ber;
+
+ return 0;
+err:
+ dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
+}
static int m88ds3103_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t fe_sec_tone_mode)
@@ -1284,6 +1364,7 @@ static struct dvb_frontend_ops m88ds3103_ops = {
.read_status = m88ds3103_read_status,
.read_snr = m88ds3103_read_snr,
+ .read_ber = m88ds3103_read_ber,
.diseqc_send_master_cmd = m88ds3103_diseqc_send_master_cmd,
.diseqc_send_burst = m88ds3103_diseqc_send_burst,
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index 84c3c06df622..9169fdd143cf 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -22,6 +22,7 @@
#include "dvb_math.h"
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
+#include <linux/math64.h>
#define M88DS3103_FIRMWARE "dvb-demod-m88ds3103.fw"
#define M88DS3103_MCLK_KHZ 96000
@@ -34,6 +35,7 @@ struct m88ds3103_priv {
struct dvb_frontend fe;
fe_delivery_system_t delivery_system;
fe_status_t fe_status;
+ u32 ber;
bool warm; /* FW running */
struct i2c_adapter *i2c_adapter;
};
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 2f458bb188c7..b931179c70a4 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -459,6 +459,9 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
unsigned layer)
{
int rc;
+ int interleaving[] = {
+ 0, 1, 2, 4, 8
+ };
static unsigned char reg[] = {
[0] = 0x88, /* Layer A */
@@ -475,20 +478,7 @@ static int mb86a20s_get_interleaving(struct mb86a20s_state *state,
if (rc < 0)
return rc;
- switch ((rc >> 4) & 0x07) {
- case 1:
- return GUARD_INTERVAL_1_4;
- case 2:
- return GUARD_INTERVAL_1_8;
- case 3:
- return GUARD_INTERVAL_1_16;
- case 4:
- return GUARD_INTERVAL_1_32;
-
- default:
- case 0:
- return GUARD_INTERVAL_AUTO;
- }
+ return interleaving[(rc >> 4) & 0x07];
}
static int mb86a20s_get_segment_count(struct mb86a20s_state *state,
@@ -566,7 +556,7 @@ static u32 isdbt_rate[3][5][4] = {
static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
u32 modulation, u32 forward_error_correction,
- u32 interleaving,
+ u32 guard_interval,
u32 segment)
{
struct mb86a20s_state *state = fe->demodulator_priv;
@@ -574,7 +564,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
int mod, fec, guard;
/*
- * If modulation/fec/interleaving is not detected, the default is
+ * If modulation/fec/guard is not detected, the default is
* to consider the lowest bit rate, to avoid taking too long time
* to get BER.
*/
@@ -612,7 +602,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
break;
}
- switch (interleaving) {
+ switch (guard_interval) {
default:
case GUARD_INTERVAL_1_4:
guard = 0;
@@ -703,7 +693,7 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
c->layer[layer].interleaving = rc;
mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation,
c->layer[layer].fec,
- c->layer[layer].interleaving,
+ c->guard_interval,
c->layer[layer].segment_count);
}
@@ -721,11 +711,10 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
rc = mb86a20s_readreg(state, 0x07);
if (rc < 0)
return rc;
+ c->transmission_mode = TRANSMISSION_MODE_AUTO;
if ((rc & 0x60) == 0x20) {
- switch (rc & 0x0c >> 2) {
- case 0:
- c->transmission_mode = TRANSMISSION_MODE_2K;
- break;
+ /* Only modes 2 and 3 are supported */
+ switch ((rc >> 2) & 0x03) {
case 1:
c->transmission_mode = TRANSMISSION_MODE_4K;
break;
@@ -734,7 +723,9 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
break;
}
}
+ c->guard_interval = GUARD_INTERVAL_AUTO;
if (!(rc & 0x10)) {
+ /* Guard interval 1/32 is not supported */
switch (rc & 0x3) {
case 0:
c->guard_interval = GUARD_INTERVAL_1_4;
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index 093df6b6ae35..023e0f49c786 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -35,6 +35,10 @@
#include <linux/jiffies.h>
#include <linux/math64.h>
+static bool rtl2832_sdr_emulated_fmt;
+module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644);
+MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)");
+
#define MAX_BULK_BUFS (10)
#define BULK_BUFFER_SIZE (128 * 512)
@@ -80,15 +84,18 @@ static const struct v4l2_frequency_band bands_fm[] = {
struct rtl2832_sdr_format {
char *name;
u32 pixelformat;
+ u32 buffersize;
};
static struct rtl2832_sdr_format formats[] = {
{
- .name = "IQ U8",
- .pixelformat = V4L2_SDR_FMT_CU8,
+ .name = "Complex U8",
+ .pixelformat = V4L2_SDR_FMT_CU8,
+ .buffersize = BULK_BUFFER_SIZE,
}, {
- .name = "IQ U16LE (emulated)",
+ .name = "Complex U16LE (emulated)",
.pixelformat = V4L2_SDR_FMT_CU16LE,
+ .buffersize = BULK_BUFFER_SIZE * 2,
},
};
@@ -139,6 +146,8 @@ struct rtl2832_sdr_state {
unsigned int f_adc, f_tuner;
u32 pixelformat;
+ u32 buffersize;
+ unsigned int num_formats;
/* Controls */
struct v4l2_ctrl_handler hdl;
@@ -348,6 +357,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
/* convert u8 to u16 */
unsigned int i;
u16 *u16dst = dst;
+
for (i = 0; i < src_len; i++)
*u16dst++ = (src[i] << 8) | (src[i] >> 0);
dst_len = 2 * src_len;
@@ -359,6 +369,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
#define MSECS 10000UL
unsigned int samples = s->sample - s->sample_measured;
+
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
s->sample_measured = s->sample;
dev_dbg(&s->udev->dev,
@@ -560,11 +571,13 @@ static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
{
unsigned long flags = 0;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) {
struct rtl2832_sdr_frame_buf *buf;
+
buf = list_entry(s->queued_bufs.next,
struct rtl2832_sdr_frame_buf, list);
list_del(&buf->list);
@@ -577,6 +590,7 @@ static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
{
struct rtl2832_sdr_state *s = fe->sec_priv;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->vb_queue_lock);
@@ -598,6 +612,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
@@ -615,14 +630,14 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+
dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
/* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers;
*nplanes = 1;
- /* 2 = max 16-bit sample returned */
- sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
+ sizes[0] = PAGE_ALIGN(s->buffersize);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]);
return 0;
@@ -665,6 +680,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u8 buf[4], u8tmp1, u8tmp2;
u64 u64tmp;
u32 u32tmp;
+
dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
@@ -935,7 +951,8 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_state *s)
/*
* bandwidth (Hz)
*/
- bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
+ bandwidth_auto = v4l2_ctrl_find(&s->hdl,
+ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
c->bandwidth_hz = s->f_adc;
@@ -987,6 +1004,7 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
int ret;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (!s->udev)
@@ -1035,6 +1053,7 @@ err:
static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
{
struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->v4l2_lock);
@@ -1068,6 +1087,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
__func__, v->index, v->type);
@@ -1094,6 +1114,7 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (v->index > 1)
@@ -1105,6 +1126,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
struct v4l2_frequency_band *band)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
__func__, band->tuner, band->type, band->index);
@@ -1130,6 +1152,7 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
int ret = 0;
+
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
__func__, f->tuner, f->type);
@@ -1193,9 +1216,10 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
- if (f->index >= NUM_FORMATS)
+ if (f->index >= s->num_formats)
return -EINVAL;
strlcpy(f->description, formats[f->index].name, sizeof(f->description));
@@ -1208,9 +1232,12 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
f->fmt.sdr.pixelformat = s->pixelformat;
+ f->fmt.sdr.buffersize = s->buffersize;
+
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
return 0;
@@ -1222,6 +1249,7 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
struct vb2_queue *q = &s->vb_queue;
int i;
+
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
@@ -1229,15 +1257,19 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
return -EBUSY;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
+ for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
- s->pixelformat = f->fmt.sdr.pixelformat;
+ s->pixelformat = formats[i].pixelformat;
+ s->buffersize = formats[i].buffersize;
+ f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
}
}
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
@@ -1247,16 +1279,20 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
{
struct rtl2832_sdr_state *s = video_drvdata(file);
int i;
+
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
+ for (i = 0; i < s->num_formats; i++) {
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+ f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
+ }
}
f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
@@ -1316,8 +1352,9 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
struct dvb_frontend *fe = s->fe;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
+
dev_dbg(&s->udev->dev,
- "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
+ "%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
__func__, ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step);
@@ -1327,14 +1364,16 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
/* TODO: these controls should be moved to tuner drivers */
if (s->bandwidth_auto->val) {
/* Round towards the closest legal value */
- s32 val = s->f_adc + s->bandwidth->step / 2;
+ s32 val = s->f_adc + div_u64(s->bandwidth->step, 2);
u32 offset;
- val = clamp(val, s->bandwidth->minimum, s->bandwidth->maximum);
+
+ val = clamp_t(s32, val, s->bandwidth->minimum,
+ s->bandwidth->maximum);
offset = val - s->bandwidth->minimum;
- offset = s->bandwidth->step * (offset / s->bandwidth->step);
+ offset = s->bandwidth->step *
+ div_u64(offset, s->bandwidth->step);
s->bandwidth->val = s->bandwidth->minimum + offset;
}
-
c->bandwidth_hz = s->bandwidth->val;
if (!test_bit(POWER_ON, &s->flags))
@@ -1390,7 +1429,11 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->cfg = cfg;
s->f_adc = bands_adc[0].rangelow;
s->f_tuner = bands_fm[0].rangelow;
- s->pixelformat = V4L2_SDR_FMT_CU8;
+ s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+ s->num_formats = NUM_FORMATS;
+ if (rtl2832_sdr_emulated_fmt == false)
+ s->num_formats -= 1;
mutex_init(&s->v4l2_lock);
mutex_init(&s->vb_queue_lock);
@@ -1420,15 +1463,24 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
break;
case RTL2832_TUNER_R820T:
v4l2_ctrl_handler_init(&s->hdl, 2);
- s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 0, 8000000, 100000, 0);
+ s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
+ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
+ 0, 1, 1, 1);
+ s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
+ V4L2_CID_RF_TUNER_BANDWIDTH,
+ 0, 8000000, 100000, 0);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break;
case RTL2832_TUNER_FC0012:
case RTL2832_TUNER_FC0013:
v4l2_ctrl_handler_init(&s->hdl, 2);
- s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
- s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops, V4L2_CID_RF_TUNER_BANDWIDTH, 6000000, 8000000, 1000000, 6000000);
+ s->bandwidth_auto = v4l2_ctrl_new_std(&s->hdl, ops,
+ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO,
+ 0, 1, 1, 1);
+ s->bandwidth = v4l2_ctrl_new_std(&s->hdl, ops,
+ V4L2_CID_RF_TUNER_BANDWIDTH,
+ 6000000, 8000000, 1000000,
+ 6000000);
v4l2_ctrl_auto_cluster(2, &s->bandwidth_auto, 0, false);
break;
default:
@@ -1448,7 +1500,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->vdev = rtl2832_sdr_template;
s->vdev.queue = &s->vb_queue;
s->vdev.queue->lock = &s->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
video_set_drvdata(&s->vdev, s);
/* Register the v4l2_device structure */
@@ -1480,6 +1531,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
KBUILD_MODNAME);
+ dev_notice(&s->udev->dev,
+ "%s: SDR API is still slightly experimental and functionality changes may follow\n",
+ KBUILD_MODNAME);
return fe;
err_unregister_v4l2_dev:
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h
index b865fadf184f..b865fadf184f 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.h
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
new file mode 100644
index 000000000000..3a2d6c5aded6
--- /dev/null
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -0,0 +1,1040 @@
+/*
+ Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+
+ Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
+
+ 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.
+
+ References:
+ http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "si2165_priv.h"
+#include "si2165.h"
+
+/* Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx
+ * uses 16 MHz xtal */
+
+/* Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx
+ * uses 24 MHz clock provided by tuner */
+
+struct si2165_state {
+ struct i2c_adapter *i2c;
+
+ struct dvb_frontend frontend;
+
+ struct si2165_config config;
+
+ /* chip revision */
+ u8 revcode;
+ /* chip type */
+ u8 chip_type;
+
+ /* calculated by xtal and div settings */
+ u32 fvco_hz;
+ u32 sys_clk;
+ u32 adc_clk;
+
+ bool has_dvbc;
+ bool has_dvbt;
+ bool firmware_loaded;
+};
+
+#define DEBUG_OTHER 0x01
+#define DEBUG_I2C_WRITE 0x02
+#define DEBUG_I2C_READ 0x04
+#define DEBUG_REG_READ 0x08
+#define DEBUG_REG_WRITE 0x10
+#define DEBUG_FW_LOAD 0x20
+
+static int debug = 0x00;
+
+#define dprintk(args...) \
+ do { \
+ if (debug & DEBUG_OTHER) \
+ printk(KERN_DEBUG "si2165: " args); \
+ } while (0)
+
+#define deb_i2c_write(args...) \
+ do { \
+ if (debug & DEBUG_I2C_WRITE) \
+ printk(KERN_DEBUG "si2165: i2c write: " args); \
+ } while (0)
+
+#define deb_i2c_read(args...) \
+ do { \
+ if (debug & DEBUG_I2C_READ) \
+ printk(KERN_DEBUG "si2165: i2c read: " args); \
+ } while (0)
+
+#define deb_readreg(args...) \
+ do { \
+ if (debug & DEBUG_REG_READ) \
+ printk(KERN_DEBUG "si2165: reg read: " args); \
+ } while (0)
+
+#define deb_writereg(args...) \
+ do { \
+ if (debug & DEBUG_REG_WRITE) \
+ printk(KERN_DEBUG "si2165: reg write: " args); \
+ } while (0)
+
+#define deb_fw_load(args...) \
+ do { \
+ if (debug & DEBUG_FW_LOAD) \
+ printk(KERN_DEBUG "si2165: fw load: " args); \
+ } while (0)
+
+static int si2165_write(struct si2165_state *state, const u16 reg,
+ const u8 *src, const int count)
+{
+ int ret;
+ struct i2c_msg msg;
+ u8 buf[2 + 4]; /* write a maximum of 4 bytes of data */
+
+ if (count + 2 > sizeof(buf)) {
+ dev_warn(&state->i2c->dev,
+ "%s: i2c wr reg=%04x: count=%d is too big!\n",
+ KBUILD_MODNAME, reg, count);
+ return -EINVAL;
+ }
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ memcpy(buf + 2, src, count);
+
+ msg.addr = state->config.i2c_addr;
+ msg.flags = 0;
+ msg.buf = buf;
+ msg.len = count + 2;
+
+ if (debug & DEBUG_I2C_WRITE)
+ deb_i2c_write("reg: 0x%04x, data: %*ph\n", reg, count, src);
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+
+ if (ret != 1) {
+ dev_err(&state->i2c->dev, "%s: ret == %d\n", __func__, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int si2165_read(struct si2165_state *state,
+ const u16 reg, u8 *val, const int count)
+{
+ int ret;
+ u8 reg_buf[] = { reg >> 8, reg & 0xff };
+ struct i2c_msg msg[] = {
+ { .addr = state->config.i2c_addr,
+ .flags = 0, .buf = reg_buf, .len = 2 },
+ { .addr = state->config.i2c_addr,
+ .flags = I2C_M_RD, .buf = val, .len = count },
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2) {
+ dev_err(&state->i2c->dev, "%s: error (addr %02x reg %04x error (ret == %i)\n",
+ __func__, state->config.i2c_addr, reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+
+ if (debug & DEBUG_I2C_READ)
+ deb_i2c_read("reg: 0x%04x, data: %*ph\n", reg, count, val);
+
+ return 0;
+}
+
+static int si2165_readreg8(struct si2165_state *state,
+ const u16 reg, u8 *val)
+{
+ int ret;
+
+ ret = si2165_read(state, reg, val, 1);
+ deb_readreg("R(0x%04x)=0x%02x\n", reg, *val);
+ return ret;
+}
+
+static int si2165_readreg16(struct si2165_state *state,
+ const u16 reg, u16 *val)
+{
+ u8 buf[2];
+
+ int ret = si2165_read(state, reg, buf, 2);
+ *val = buf[0] | buf[1] << 8;
+ deb_readreg("R(0x%04x)=0x%04x\n", reg, *val);
+ return ret;
+}
+
+static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val)
+{
+ return si2165_write(state, reg, &val, 1);
+}
+
+static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val)
+{
+ u8 buf[2] = { val & 0xff, (val >> 8) & 0xff };
+
+ return si2165_write(state, reg, buf, 2);
+}
+
+static int si2165_writereg24(struct si2165_state *state, const u16 reg, u32 val)
+{
+ u8 buf[3] = { val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff };
+
+ return si2165_write(state, reg, buf, 3);
+}
+
+static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
+{
+ u8 buf[4] = {
+ val & 0xff,
+ (val >> 8) & 0xff,
+ (val >> 16) & 0xff,
+ (val >> 24) & 0xff
+ };
+ return si2165_write(state, reg, buf, 4);
+}
+
+static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
+ u8 val, u8 mask)
+{
+ int ret;
+ u8 tmp;
+
+ if (mask != 0xff) {
+ ret = si2165_readreg8(state, reg, &tmp);
+ if (ret < 0)
+ goto err;
+
+ val &= mask;
+ tmp &= ~mask;
+ val |= tmp;
+ }
+
+ ret = si2165_writereg8(state, reg, val);
+err:
+ return ret;
+}
+
+static int si2165_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *s)
+{
+ s->min_delay_ms = 1000;
+ return 0;
+}
+
+static int si2165_init_pll(struct si2165_state *state)
+{
+ u32 ref_freq_Hz = state->config.ref_freq_Hz;
+ u8 divr = 1; /* 1..7 */
+ u8 divp = 1; /* only 1 or 4 */
+ u8 divn = 56; /* 1..63 */
+ u8 divm = 8;
+ u8 divl = 12;
+ u8 buf[4];
+
+ /* hardcoded values can be deleted if calculation is verified
+ * or it yields the same values as the windows driver */
+ switch (ref_freq_Hz) {
+ case 16000000u:
+ divn = 56;
+ break;
+ case 24000000u:
+ divr = 2;
+ divp = 4;
+ divn = 19;
+ break;
+ default:
+ /* ref_freq / divr must be between 4 and 16 MHz */
+ if (ref_freq_Hz > 16000000u)
+ divr = 2;
+
+ /* now select divn and divp such that
+ * fvco is in 1624..1824 MHz */
+ if (1624000000u * divr > ref_freq_Hz * 2u * 63u)
+ divp = 4;
+
+ /* is this already correct regarding rounding? */
+ divn = 1624000000u * divr / (ref_freq_Hz * 2u * divp);
+ break;
+ }
+
+ /* adc_clk and sys_clk depend on xtal and pll settings */
+ state->fvco_hz = ref_freq_Hz / divr
+ * 2u * divn * divp;
+ state->adc_clk = state->fvco_hz / (divm * 4u);
+ state->sys_clk = state->fvco_hz / (divl * 2u);
+
+ /* write pll registers 0x00a0..0x00a3 at once */
+ buf[0] = divl;
+ buf[1] = divm;
+ buf[2] = (divn & 0x3f) | ((divp == 1) ? 0x40 : 0x00) | 0x80;
+ buf[3] = divr;
+ return si2165_write(state, 0x00a0, buf, 4);
+}
+
+static int si2165_adjust_pll_divl(struct si2165_state *state, u8 divl)
+{
+ state->sys_clk = state->fvco_hz / (divl * 2u);
+ return si2165_writereg8(state, 0x00a0, divl); /* pll_divl */
+}
+
+static u32 si2165_get_fe_clk(struct si2165_state *state)
+{
+ /* assume Oversampling mode Ovr4 is used */
+ return state->adc_clk;
+}
+
+static bool si2165_wait_init_done(struct si2165_state *state)
+{
+ int ret = -EINVAL;
+ u8 val = 0;
+ int i;
+
+ for (i = 0; i < 3; ++i) {
+ si2165_readreg8(state, 0x0054, &val);
+ if (val == 0x01)
+ return 0;
+ usleep_range(1000, 50000);
+ }
+ dev_err(&state->i2c->dev, "%s: init_done was not set\n",
+ KBUILD_MODNAME);
+ return ret;
+}
+
+static int si2165_upload_firmware_block(struct si2165_state *state,
+ const u8 *data, u32 len, u32 *poffset, u32 block_count)
+{
+ int ret;
+ u8 buf_ctrl[4] = { 0x00, 0x00, 0x00, 0xc0 };
+ u8 wordcount;
+ u32 cur_block = 0;
+ u32 offset = poffset ? *poffset : 0;
+
+ if (len < 4)
+ return -EINVAL;
+ if (len % 4 != 0)
+ return -EINVAL;
+
+ deb_fw_load("si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n",
+ len, offset, block_count);
+ while (offset+12 <= len && cur_block < block_count) {
+ deb_fw_load("si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+ len, offset, cur_block, block_count);
+ wordcount = data[offset];
+ if (wordcount < 1 || data[offset+1] ||
+ data[offset+2] || data[offset+3]) {
+ dev_warn(&state->i2c->dev,
+ "%s: bad fw data[0..3] = %*ph\n",
+ KBUILD_MODNAME, 4, data);
+ return -EINVAL;
+ }
+
+ if (offset + 8 + wordcount * 4 > len) {
+ dev_warn(&state->i2c->dev,
+ "%s: len is too small for block len=%d, wordcount=%d\n",
+ KBUILD_MODNAME, len, wordcount);
+ return -EINVAL;
+ }
+
+ buf_ctrl[0] = wordcount - 1;
+
+ ret = si2165_write(state, 0x0364, buf_ctrl, 4);
+ if (ret < 0)
+ goto error;
+ ret = si2165_write(state, 0x0368, data+offset+4, 4);
+ if (ret < 0)
+ goto error;
+
+ offset += 8;
+
+ while (wordcount > 0) {
+ ret = si2165_write(state, 0x36c, data+offset, 4);
+ if (ret < 0)
+ goto error;
+ wordcount--;
+ offset += 4;
+ }
+ cur_block++;
+ }
+
+ deb_fw_load("si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+ len, offset, cur_block, block_count);
+
+ if (poffset)
+ *poffset = offset;
+
+ deb_fw_load("si2165_upload_firmware_block returned offset=0x%x\n",
+ offset);
+
+ return 0;
+error:
+ return ret;
+}
+
+static int si2165_upload_firmware(struct si2165_state *state)
+{
+ /* int ret; */
+ u8 val[3];
+ u16 val16;
+ int ret;
+
+ const struct firmware *fw = NULL;
+ u8 *fw_file = SI2165_FIRMWARE;
+ const u8 *data;
+ u32 len;
+ u32 offset;
+ u8 patch_version;
+ u8 block_count;
+ u16 crc_expected;
+
+ /* request the firmware, this will block and timeout */
+ ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
+ if (ret) {
+ dev_warn(&state->i2c->dev, "%s: firmare file '%s' not found\n",
+ KBUILD_MODNAME, fw_file);
+ goto error;
+ }
+
+ data = fw->data;
+ len = fw->size;
+
+ dev_info(&state->i2c->dev, "%s: downloading firmware from file '%s' size=%d\n",
+ KBUILD_MODNAME, fw_file, len);
+
+ if (len % 4 != 0) {
+ dev_warn(&state->i2c->dev, "%s: firmware size is not multiple of 4\n",
+ KBUILD_MODNAME);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* check header (8 bytes) */
+ if (len < 8) {
+ dev_warn(&state->i2c->dev, "%s: firmware header is missing\n",
+ KBUILD_MODNAME);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (data[0] != 1 || data[1] != 0) {
+ dev_warn(&state->i2c->dev, "%s: firmware file version is wrong\n",
+ KBUILD_MODNAME);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ patch_version = data[2];
+ block_count = data[4];
+ crc_expected = data[7] << 8 | data[6];
+
+ /* start uploading fw */
+ /* boot/wdog status */
+ ret = si2165_writereg8(state, 0x0341, 0x00);
+ if (ret < 0)
+ goto error;
+ /* reset */
+ ret = si2165_writereg8(state, 0x00c0, 0x00);
+ if (ret < 0)
+ goto error;
+ /* boot/wdog status */
+ ret = si2165_readreg8(state, 0x0341, val);
+ if (ret < 0)
+ goto error;
+
+ /* enable reset on error */
+ ret = si2165_readreg8(state, 0x035c, val);
+ if (ret < 0)
+ goto error;
+ ret = si2165_readreg8(state, 0x035c, val);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x035c, 0x02);
+ if (ret < 0)
+ goto error;
+
+ /* start right after the header */
+ offset = 8;
+
+ dev_info(&state->i2c->dev, "%s: si2165_upload_firmware extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
+ KBUILD_MODNAME, patch_version, block_count, crc_expected);
+
+ ret = si2165_upload_firmware_block(state, data, len, &offset, 1);
+ if (ret < 0)
+ goto error;
+
+ ret = si2165_writereg8(state, 0x0344, patch_version);
+ if (ret < 0)
+ goto error;
+
+ /* reset crc */
+ ret = si2165_writereg8(state, 0x0379, 0x01);
+ if (ret)
+ return ret;
+
+ ret = si2165_upload_firmware_block(state, data, len,
+ &offset, block_count);
+ if (ret < 0) {
+ dev_err(&state->i2c->dev,
+ "%s: firmare could not be uploaded\n",
+ KBUILD_MODNAME);
+ goto error;
+ }
+
+ /* read crc */
+ ret = si2165_readreg16(state, 0x037a, &val16);
+ if (ret)
+ goto error;
+
+ if (val16 != crc_expected) {
+ dev_err(&state->i2c->dev,
+ "%s: firmware crc mismatch %04x != %04x\n",
+ KBUILD_MODNAME, val16, crc_expected);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ret = si2165_upload_firmware_block(state, data, len, &offset, 5);
+ if (ret)
+ goto error;
+
+ if (len != offset) {
+ dev_err(&state->i2c->dev,
+ "%s: firmare len mismatch %04x != %04x\n",
+ KBUILD_MODNAME, len, offset);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* reset watchdog error register */
+ ret = si2165_writereg_mask8(state, 0x0341, 0x02, 0x02);
+ if (ret < 0)
+ goto error;
+
+ /* enable reset on error */
+ ret = si2165_writereg_mask8(state, 0x035c, 0x01, 0x01);
+ if (ret < 0)
+ goto error;
+
+ dev_info(&state->i2c->dev, "%s: fw load finished\n", KBUILD_MODNAME);
+
+ ret = 0;
+ state->firmware_loaded = true;
+error:
+ if (fw) {
+ release_firmware(fw);
+ fw = NULL;
+ }
+
+ return ret;
+}
+
+static int si2165_init(struct dvb_frontend *fe)
+{
+ int ret = 0;
+ struct si2165_state *state = fe->demodulator_priv;
+ u8 val;
+ u8 patch_version = 0x00;
+
+ dprintk("%s: called\n", __func__);
+
+ /* powerup */
+ ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+ if (ret < 0)
+ goto error;
+ /* dsp_clock_enable */
+ ret = si2165_writereg8(state, 0x0104, 0x01);
+ if (ret < 0)
+ goto error;
+ ret = si2165_readreg8(state, 0x0000, &val); /* verify chip_mode */
+ if (ret < 0)
+ goto error;
+ if (val != state->config.chip_mode) {
+ dev_err(&state->i2c->dev, "%s: could not set chip_mode\n",
+ KBUILD_MODNAME);
+ return -EINVAL;
+ }
+
+ /* agc */
+ ret = si2165_writereg8(state, 0x018b, 0x00);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x0190, 0x01);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x0170, 0x00);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x0171, 0x07);
+ if (ret < 0)
+ goto error;
+ /* rssi pad */
+ ret = si2165_writereg8(state, 0x0646, 0x00);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x0641, 0x00);
+ if (ret < 0)
+ goto error;
+
+ ret = si2165_init_pll(state);
+ if (ret < 0)
+ goto error;
+
+ /* enable chip_init */
+ ret = si2165_writereg8(state, 0x0050, 0x01);
+ if (ret < 0)
+ goto error;
+ /* set start_init */
+ ret = si2165_writereg8(state, 0x0096, 0x01);
+ if (ret < 0)
+ goto error;
+ ret = si2165_wait_init_done(state);
+ if (ret < 0)
+ goto error;
+
+ /* disable chip_init */
+ ret = si2165_writereg8(state, 0x0050, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* ber_pkt */
+ ret = si2165_writereg16(state, 0x0470 , 0x7530);
+ if (ret < 0)
+ goto error;
+
+ ret = si2165_readreg8(state, 0x0344, &patch_version);
+ if (ret < 0)
+ goto error;
+
+ ret = si2165_writereg8(state, 0x00cb, 0x00);
+ if (ret < 0)
+ goto error;
+
+ /* dsp_addr_jump */
+ ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+ if (ret < 0)
+ goto error;
+ /* boot/wdog status */
+ ret = si2165_readreg8(state, 0x0341, &val);
+ if (ret < 0)
+ goto error;
+
+ if (patch_version == 0x00) {
+ ret = si2165_upload_firmware(state);
+ if (ret < 0)
+ goto error;
+ }
+
+ /* write adc values after each reset*/
+ ret = si2165_writereg8(state, 0x012a, 0x46);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x012c, 0x00);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x012e, 0x0a);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x012f, 0xff);
+ if (ret < 0)
+ goto error;
+ ret = si2165_writereg8(state, 0x0123, 0x70);
+ if (ret < 0)
+ goto error;
+
+ return 0;
+error:
+ return ret;
+}
+
+static int si2165_sleep(struct dvb_frontend *fe)
+{
+ int ret;
+ struct si2165_state *state = fe->demodulator_priv;
+
+ /* dsp clock disable */
+ ret = si2165_writereg8(state, 0x0104, 0x00);
+ if (ret < 0)
+ return ret;
+ /* chip mode */
+ ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int si2165_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ int ret;
+ u8 fec_lock = 0;
+ struct si2165_state *state = fe->demodulator_priv;
+
+ if (!state->has_dvbt)
+ return -EINVAL;
+
+ /* check fec_lock */
+ ret = si2165_readreg8(state, 0x4e0, &fec_lock);
+ if (ret < 0)
+ return ret;
+ *status = 0;
+ if (fec_lock & 0x01) {
+ *status |= FE_HAS_SIGNAL;
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_LOCK;
+ }
+
+ return 0;
+}
+
+static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
+{
+ u64 oversamp;
+ u32 reg_value;
+
+ oversamp = si2165_get_fe_clk(state);
+ oversamp <<= 23;
+ do_div(oversamp, dvb_rate);
+ reg_value = oversamp & 0x3fffffff;
+
+ /* oversamp, usbdump contained 0x03100000; */
+ return si2165_writereg32(state, 0x00e4, reg_value);
+}
+
+static int si2165_set_if_freq_shift(struct si2165_state *state, u32 IF)
+{
+ u64 if_freq_shift;
+ s32 reg_value = 0;
+ u32 fe_clk = si2165_get_fe_clk(state);
+
+ if_freq_shift = IF;
+ if_freq_shift <<= 29;
+
+ do_div(if_freq_shift, fe_clk);
+ reg_value = (s32)if_freq_shift;
+
+ if (state->config.inversion)
+ reg_value = -reg_value;
+
+ reg_value = reg_value & 0x1fffffff;
+
+ /* if_freq_shift, usbdump contained 0x023ee08f; */
+ return si2165_writereg32(state, 0x00e8, reg_value);
+}
+
+static int si2165_set_parameters(struct dvb_frontend *fe)
+{
+ int ret;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+ struct si2165_state *state = fe->demodulator_priv;
+ u8 val[3];
+ u32 IF;
+ u32 dvb_rate = 0;
+ u16 bw10k;
+
+ dprintk("%s: called\n", __func__);
+
+ if (!fe->ops.tuner_ops.get_if_frequency) {
+ dev_err(&state->i2c->dev,
+ "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n",
+ KBUILD_MODNAME);
+ return -EINVAL;
+ }
+
+ if (!state->has_dvbt)
+ return -EINVAL;
+
+ if (p->bandwidth_hz > 0) {
+ dvb_rate = p->bandwidth_hz * 8 / 7;
+ bw10k = p->bandwidth_hz / 10000;
+ } else {
+ dvb_rate = 8 * 8 / 7;
+ bw10k = 800;
+ }
+
+ /* standard = DVB-T */
+ ret = si2165_writereg8(state, 0x00ec, 0x01);
+ if (ret < 0)
+ return ret;
+ ret = si2165_adjust_pll_divl(state, 12);
+ if (ret < 0)
+ return ret;
+
+ fe->ops.tuner_ops.get_if_frequency(fe, &IF);
+ ret = si2165_set_if_freq_shift(state, IF);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x08f8, 0x00);
+ if (ret < 0)
+ return ret;
+ /* ts output config */
+ ret = si2165_writereg8(state, 0x04e4, 0x20);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg16(state, 0x04ef, 0x00fe);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg24(state, 0x04f4, 0x555555);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x04e5, 0x01);
+ if (ret < 0)
+ return ret;
+ /* bandwidth in 10KHz steps */
+ ret = si2165_writereg16(state, 0x0308, bw10k);
+ if (ret < 0)
+ return ret;
+ ret = si2165_set_oversamp(state, dvb_rate);
+ if (ret < 0)
+ return ret;
+ /* impulsive_noise_remover */
+ ret = si2165_writereg8(state, 0x031c, 0x01);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x00cb, 0x00);
+ if (ret < 0)
+ return ret;
+ /* agc2 */
+ ret = si2165_writereg8(state, 0x016e, 0x41);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x016c, 0x0e);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x016d, 0x10);
+ if (ret < 0)
+ return ret;
+ /* agc */
+ ret = si2165_writereg8(state, 0x015b, 0x03);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x0150, 0x78);
+ if (ret < 0)
+ return ret;
+ /* agc */
+ ret = si2165_writereg8(state, 0x01a0, 0x78);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x01c8, 0x68);
+ if (ret < 0)
+ return ret;
+ /* freq_sync_range */
+ ret = si2165_writereg16(state, 0x030c, 0x0064);
+ if (ret < 0)
+ return ret;
+ /* gp_reg0 */
+ ret = si2165_readreg8(state, 0x0387, val);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x0387, 0x00);
+ if (ret < 0)
+ return ret;
+ /* dsp_addr_jump */
+ ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+ if (ret < 0)
+ return ret;
+
+ if (fe->ops.tuner_ops.set_params)
+ fe->ops.tuner_ops.set_params(fe);
+
+ /* recalc if_freq_shift if IF might has changed */
+ fe->ops.tuner_ops.get_if_frequency(fe, &IF);
+ ret = si2165_set_if_freq_shift(state, IF);
+ if (ret < 0)
+ return ret;
+
+ /* boot/wdog status */
+ ret = si2165_readreg8(state, 0x0341, val);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg8(state, 0x0341, 0x00);
+ if (ret < 0)
+ return ret;
+ /* reset all */
+ ret = si2165_writereg8(state, 0x00c0, 0x00);
+ if (ret < 0)
+ return ret;
+ /* gp_reg0 */
+ ret = si2165_writereg32(state, 0x0384, 0x00000000);
+ if (ret < 0)
+ return ret;
+ /* start_synchro */
+ ret = si2165_writereg8(state, 0x02e0, 0x01);
+ if (ret < 0)
+ return ret;
+ /* boot/wdog status */
+ ret = si2165_readreg8(state, 0x0341, val);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void si2165_release(struct dvb_frontend *fe)
+{
+ struct si2165_state *state = fe->demodulator_priv;
+
+ dprintk("%s: called\n", __func__);
+ kfree(state);
+}
+
+static struct dvb_frontend_ops si2165_ops = {
+ .info = {
+ .name = "Silicon Labs Si2165",
+ .caps = FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_MUTE_TS |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_RECOVER
+ },
+
+ .get_tune_settings = si2165_get_tune_settings,
+
+ .init = si2165_init,
+ .sleep = si2165_sleep,
+
+ .set_frontend = si2165_set_parameters,
+ .read_status = si2165_read_status,
+
+ .release = si2165_release,
+};
+
+struct dvb_frontend *si2165_attach(const struct si2165_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct si2165_state *state = NULL;
+ int n;
+ int io_ret;
+ u8 val;
+
+ if (config == NULL || i2c == NULL)
+ goto error;
+
+ /* allocate memory for the internal state */
+ state = kzalloc(sizeof(struct si2165_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->i2c = i2c;
+ state->config = *config;
+
+ if (state->config.ref_freq_Hz < 4000000
+ || state->config.ref_freq_Hz > 27000000) {
+ dev_err(&state->i2c->dev, "%s: ref_freq of %d Hz not supported by this driver\n",
+ KBUILD_MODNAME, state->config.ref_freq_Hz);
+ goto error;
+ }
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &si2165_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* powerup */
+ io_ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+ if (io_ret < 0)
+ goto error;
+
+ io_ret = si2165_readreg8(state, 0x0000, &val);
+ if (io_ret < 0)
+ goto error;
+ if (val != state->config.chip_mode)
+ goto error;
+
+ io_ret = si2165_readreg8(state, 0x0023 , &state->revcode);
+ if (io_ret < 0)
+ goto error;
+
+ io_ret = si2165_readreg8(state, 0x0118, &state->chip_type);
+ if (io_ret < 0)
+ goto error;
+
+ /* powerdown */
+ io_ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+ if (io_ret < 0)
+ goto error;
+
+ dev_info(&state->i2c->dev, "%s: hardware revision 0x%02x, chip type 0x%02x\n",
+ KBUILD_MODNAME, state->revcode, state->chip_type);
+
+ /* It is a guess that register 0x0118 (chip type?) can be used to
+ * differ between si2161, si2163 and si2165
+ * Only si2165 has been tested.
+ */
+ if (state->revcode == 0x03 && state->chip_type == 0x07) {
+ state->has_dvbt = true;
+ state->has_dvbc = true;
+ } else {
+ dev_err(&state->i2c->dev, "%s: Unsupported chip.\n",
+ KBUILD_MODNAME);
+ goto error;
+ }
+
+ n = 0;
+ if (state->has_dvbt) {
+ state->frontend.ops.delsys[n++] = SYS_DVBT;
+ strlcat(state->frontend.ops.info.name, " DVB-T",
+ sizeof(state->frontend.ops.info.name));
+ }
+ if (state->has_dvbc)
+ dev_warn(&state->i2c->dev, "%s: DVB-C is not yet supported.\n",
+ KBUILD_MODNAME);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(si2165_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(SI2165_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2165.h b/drivers/media/dvb-frontends/si2165.h
new file mode 100644
index 000000000000..efaa08123b92
--- /dev/null
+++ b/drivers/media/dvb-frontends/si2165.h
@@ -0,0 +1,62 @@
+/*
+ Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+
+ Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
+
+ 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.
+
+ References:
+ http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+*/
+
+#ifndef _DVB_SI2165_H
+#define _DVB_SI2165_H
+
+#include <linux/dvb/frontend.h>
+
+enum {
+ SI2165_MODE_OFF = 0x00,
+ SI2165_MODE_PLL_EXT = 0x20,
+ SI2165_MODE_PLL_XTAL = 0x21
+};
+
+struct si2165_config {
+ /* i2c addr
+ * possible values: 0x64,0x65,0x66,0x67 */
+ u8 i2c_addr;
+
+ /* external clock or XTAL */
+ u8 chip_mode;
+
+ /* frequency of external clock or xtal in Hz
+ * possible values: 4000000, 16000000, 20000000, 240000000, 27000000
+ */
+ u32 ref_freq_Hz;
+
+ /* invert the spectrum */
+ bool inversion;
+};
+
+#if IS_ENABLED(CONFIG_DVB_SI2165)
+struct dvb_frontend *si2165_attach(
+ const struct si2165_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *si2165_attach(
+ const struct si2165_config *config,
+ struct i2c_adapter *i2c)
+{
+ pr_warn("%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_SI2165 */
+
+#endif /* _DVB_SI2165_H */
diff --git a/drivers/media/dvb-frontends/si2165_priv.h b/drivers/media/dvb-frontends/si2165_priv.h
new file mode 100644
index 000000000000..d4cc93fe1096
--- /dev/null
+++ b/drivers/media/dvb-frontends/si2165_priv.h
@@ -0,0 +1,23 @@
+/*
+ Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+
+ Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
+
+ 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 _DVB_SI2165_PRIV
+#define _DVB_SI2165_PRIV
+
+#define SI2165_FIRMWARE "dvb-demod-si2165.fw"
+
+#endif /* _DVB_SI2165_PRIV */
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 8637d2ed7623..8f81d979de30 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -60,7 +60,7 @@ static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
jiffies_to_msecs(jiffies) -
(jiffies_to_msecs(timeout) - TIMEOUT));
- if (!(cmd->args[0] >> 7) & 0x01) {
+ if (!((cmd->args[0] >> 7) & 0x01)) {
ret = -ETIMEDOUT;
goto err_mutex_unlock;
}
@@ -95,20 +95,17 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
switch (c->delivery_system) {
case SYS_DVBT:
- cmd.args[0] = 0xa0;
- cmd.args[1] = 0x01;
+ memcpy(cmd.args, "\xa0\x01", 2);
cmd.wlen = 2;
cmd.rlen = 13;
break;
case SYS_DVBC_ANNEX_A:
- cmd.args[0] = 0x90;
- cmd.args[1] = 0x01;
+ memcpy(cmd.args, "\x90\x01", 2);
cmd.wlen = 2;
cmd.rlen = 9;
break;
case SYS_DVBT2:
- cmd.args[0] = 0x50;
- cmd.args[1] = 0x01;
+ memcpy(cmd.args, "\x50\x01", 2);
cmd.wlen = 2;
cmd.rlen = 14;
break;
@@ -144,6 +141,15 @@ static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
s->fe_status = *status;
+ if (*status & FE_HAS_LOCK) {
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
+ } else {
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+
dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
__func__, *status, cmd.rlen, cmd.args);
@@ -243,51 +249,23 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
@@ -295,124 +273,66 @@ static int si2168_set_frontend(struct dvb_frontend *fe)
memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
cmd.args[4] = delivery_system | bandwidth;
cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
+ /* set DVB-C symbol rate */
+ if (c->delivery_system == SYS_DVBC_ANNEX_A) {
+ memcpy(cmd.args, "\x14\x00\x02\x11", 4);
+ cmd.args[4] = (c->symbol_rate / 1000) & 0xff;
+ cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
+ cmd.wlen = 6;
+ cmd.rlen = 4;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+ }
memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6);
+ memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6);
- cmd.wlen = 6;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
+ memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
+ memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
cmd.wlen = 6;
- cmd.rlen = 1;
+ cmd.rlen = 4;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- cmd.args[0] = 0x85;
+ memcpy(cmd.args, "\x85", 1);
cmd.wlen = 1;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
@@ -432,72 +352,60 @@ static int si2168_init(struct dvb_frontend *fe)
struct si2168 *s = fe->demodulator_priv;
int ret, len, remaining;
const struct firmware *fw = NULL;
- u8 *fw_file = SI2168_FIRMWARE;
+ u8 *fw_file;
const unsigned int i2c_wr_max = 8;
struct si2168_cmd cmd;
+ unsigned int chip_id;
dev_dbg(&s->client->dev, "%s:\n", __func__);
- cmd.args[0] = 0x13;
- cmd.wlen = 1;
- cmd.rlen = 0;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- cmd.args[0] = 0xc0;
- cmd.args[1] = 0x12;
- cmd.args[2] = 0x00;
- cmd.args[3] = 0x0c;
- cmd.args[4] = 0x00;
- cmd.args[5] = 0x0d;
- cmd.args[6] = 0x16;
- cmd.args[7] = 0x00;
- cmd.args[8] = 0x00;
- cmd.args[9] = 0x00;
- cmd.args[10] = 0x00;
- cmd.args[11] = 0x00;
- cmd.args[12] = 0x00;
+ memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
cmd.wlen = 13;
cmd.rlen = 0;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- cmd.args[0] = 0xc0;
- cmd.args[1] = 0x06;
- cmd.args[2] = 0x01;
- cmd.args[3] = 0x0f;
- cmd.args[4] = 0x00;
- cmd.args[5] = 0x20;
- cmd.args[6] = 0x20;
- cmd.args[7] = 0x01;
+ memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
cmd.wlen = 8;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- cmd.args[0] = 0x02;
+ /* query chip revision */
+ memcpy(cmd.args, "\x02", 1);
cmd.wlen = 1;
cmd.rlen = 13;
ret = si2168_cmd_execute(s, &cmd);
if (ret)
goto err;
- cmd.args[0] = 0x05;
- cmd.args[1] = 0x00;
- cmd.args[2] = 0xaa;
- cmd.args[3] = 0x4d;
- cmd.args[4] = 0x56;
- cmd.args[5] = 0x40;
- cmd.args[6] = 0x00;
- cmd.args[7] = 0x00;
- cmd.wlen = 8;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+ cmd.args[4] << 0;
+
+ #define SI2168_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
+ #define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
+ #define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
+
+ switch (chip_id) {
+ case SI2168_A20:
+ fw_file = SI2168_A20_FIRMWARE;
+ break;
+ case SI2168_A30:
+ fw_file = SI2168_A30_FIRMWARE;
+ break;
+ case SI2168_B40:
+ fw_file = SI2168_B40_FIRMWARE;
+ break;
+ default:
+ dev_err(&s->client->dev,
+ "%s: unkown chip version Si21%d-%c%c%c\n",
+ KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+ cmd.args[3], cmd.args[4]);
+ ret = -EINVAL;
goto err;
+ }
/* cold state - try to download firmware */
dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
@@ -506,9 +414,22 @@ static int si2168_init(struct dvb_frontend *fe)
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &s->client->dev);
if (ret) {
- dev_err(&s->client->dev, "%s: firmare file '%s' not found\n",
- KBUILD_MODNAME, fw_file);
- goto err;
+ /* fallback mechanism to handle old name for Si2168 B40 fw */
+ if (chip_id == SI2168_B40) {
+ fw_file = SI2168_B40_FIRMWARE_FALLBACK;
+ ret = request_firmware(&fw, fw_file, &s->client->dev);
+ }
+
+ if (ret == 0) {
+ dev_notice(&s->client->dev,
+ "%s: please install firmware file '%s'\n",
+ KBUILD_MODNAME, SI2168_B40_FIRMWARE);
+ } else {
+ dev_err(&s->client->dev,
+ "%s: firmware file '%s' not found\n",
+ KBUILD_MODNAME, fw_file);
+ goto err;
+ }
}
dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
@@ -534,8 +455,7 @@ static int si2168_init(struct dvb_frontend *fe)
release_firmware(fw);
fw = NULL;
- cmd.args[0] = 0x01;
- cmd.args[1] = 0x01;
+ memcpy(cmd.args, "\x01\x01", 2);
cmd.wlen = 2;
cmd.rlen = 1;
ret = si2168_cmd_execute(s, &cmd);
@@ -559,12 +479,24 @@ err:
static int si2168_sleep(struct dvb_frontend *fe)
{
struct si2168 *s = fe->demodulator_priv;
+ int ret;
+ struct si2168_cmd cmd;
dev_dbg(&s->client->dev, "%s:\n", __func__);
s->active = false;
+ memcpy(cmd.args, "\x13", 1);
+ cmd.wlen = 1;
+ cmd.rlen = 0;
+ ret = si2168_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
return 0;
+err:
+ dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
static int si2168_get_tune_settings(struct dvb_frontend *fe,
@@ -674,7 +606,6 @@ static int si2168_probe(struct i2c_client *client,
struct si2168_config *config = client->dev.platform_data;
struct si2168 *s;
int ret;
- struct si2168_cmd cmd;
dev_dbg(&client->dev, "%s:\n", __func__);
@@ -688,18 +619,13 @@ static int si2168_probe(struct i2c_client *client,
s->client = client;
mutex_init(&s->i2c_mutex);
- /* check if the demod is there */
- cmd.wlen = 0;
- cmd.rlen = 1;
- ret = si2168_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
/* create mux i2c adapter for tuner */
s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
0, 0, 0, si2168_select, si2168_deselect);
- if (s->adapter == NULL)
+ if (s->adapter == NULL) {
+ ret = -ENODEV;
goto err;
+ }
/* create dvb_frontend */
memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
@@ -757,4 +683,6 @@ module_i2c_driver(si2168_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(SI2168_FIRMWARE);
+MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
+MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
+MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 2a343e896f40..ebbf502ec313 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -22,7 +22,10 @@
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
-#define SI2168_FIRMWARE "dvb-demod-si2168-01.fw"
+#define SI2168_A20_FIRMWARE "dvb-demod-si2168-a20-01.fw"
+#define SI2168_A30_FIRMWARE "dvb-demod-si2168-a30-01.fw"
+#define SI2168_B40_FIRMWARE "dvb-demod-si2168-b40-01.fw"
+#define SI2168_B40_FIRMWARE_FALLBACK "dvb-demod-si2168-02.fw"
/* state struct */
struct si2168 {
@@ -36,9 +39,9 @@ struct si2168 {
};
/* firmare command struct */
-#define SI2157_ARGLEN 30
+#define SI2168_ARGLEN 30
struct si2168_cmd {
- u8 args[SI2157_ARGLEN];
+ u8 args[SI2168_ARGLEN];
unsigned wlen;
unsigned rlen;
};
diff --git a/drivers/media/dvb-frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h
index 6314d18c797a..6edc15365847 100644
--- a/drivers/media/dvb-frontends/stb6100_cfg.h
+++ b/drivers/media/dvb-frontends/stb6100_cfg.h
@@ -21,17 +21,14 @@
static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
- if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@@ -42,18 +39,16 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.frequency = frequency;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
+
if (tuner_ops->set_state) {
- if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@@ -68,12 +63,9 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
struct tuner_state t_state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
- if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@@ -84,18 +76,16 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.bandwidth = bandwidth;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
+
if (tuner_ops->set_state) {
- if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
diff --git a/drivers/media/dvb-frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h
index 112163a48622..bd8a0ec9e2cc 100644
--- a/drivers/media/dvb-frontends/stb6100_proc.h
+++ b/drivers/media/dvb-frontends/stb6100_proc.h
@@ -19,15 +19,11 @@
static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@@ -49,16 +45,13 @@ static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
state.frequency = frequency;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
+
if (tuner_ops->set_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@@ -79,15 +72,11 @@ static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
@@ -109,16 +98,13 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
state.bandwidth = bandwidth;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
+
if (tuner_ops->set_state) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index 458772739423..59b6e661acc0 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -922,18 +922,13 @@ static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
u32 freq = 0;
int err = 0;
dprintk("%s:\n", __func__);
-
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_frequency) {
err = tuner_ops->get_frequency(fe, &freq);
if (err < 0) {
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 522fe00f5eee..9619be5d4827 100644
--- a/drivers/media/dvb-frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -668,6 +668,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
u8 mode, rolloff, pilot, inversion, div;
+ fe_modulation_t modulation;
dev_dbg(&priv->i2c->dev,
"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
@@ -702,10 +703,13 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
switch (c->delivery_system) {
case SYS_DVBS:
+ modulation = QPSK;
rolloff = 0;
pilot = 2;
break;
case SYS_DVBS2:
+ modulation = c->modulation;
+
switch (c->rolloff) {
case ROLLOFF_20:
rolloff = 2;
@@ -750,7 +754,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
- c->modulation == TDA10071_MODCOD[i].modulation &&
+ modulation == TDA10071_MODCOD[i].modulation &&
c->fec_inner == TDA10071_MODCOD[i].fec) {
mode = TDA10071_MODCOD[i].val;
dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
@@ -834,10 +838,10 @@ static int tda10071_get_frontend(struct dvb_frontend *fe)
switch ((buf[1] >> 0) & 0x01) {
case 0:
- c->inversion = INVERSION_OFF;
+ c->inversion = INVERSION_ON;
break;
case 1:
- c->inversion = INVERSION_ON;
+ c->inversion = INVERSION_OFF;
break;
}
@@ -856,7 +860,7 @@ static int tda10071_get_frontend(struct dvb_frontend *fe)
if (ret)
goto error;
- c->symbol_rate = (buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0);
+ c->symbol_rate = ((buf[0] << 16) | (buf[1] << 8) | (buf[2] << 0)) * 1000;
return ret;
error:
diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
index 4baf14bfb65a..420486192736 100644
--- a/drivers/media/dvb-frontends/tda10071_priv.h
+++ b/drivers/media/dvb-frontends/tda10071_priv.h
@@ -55,6 +55,7 @@ static struct tda10071_modcod {
{ SYS_DVBS2, QPSK, FEC_8_9, 0x0a },
{ SYS_DVBS2, QPSK, FEC_9_10, 0x0b },
/* 8PSK */
+ { SYS_DVBS2, PSK_8, FEC_AUTO, 0x00 },
{ SYS_DVBS2, PSK_8, FEC_3_5, 0x0c },
{ SYS_DVBS2, PSK_8, FEC_2_3, 0x0d },
{ SYS_DVBS2, PSK_8, FEC_3_4, 0x0e },
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index 2c54586ac07f..de0a1c110972 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -1030,7 +1030,7 @@ static int ChannelConfiguration(struct tda_state *state,
state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
if ((Standard == HF_FM_Radio) && state->m_bFMInput)
- state->m_Regs[EP4] |= 80;
+ state->m_Regs[EP4] |= 0x80;
state->m_Regs[MPD] &= ~0x80;
if (Standard > HF_AnalogMax)
diff --git a/drivers/media/dvb-frontends/tda18271c2dd_maps.h b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
index b87661b9df14..f3bca5c237d7 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd_maps.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd_maps.h
@@ -5,7 +5,7 @@ enum HF_S {
HF_DVBC_8MHZ, HF_DVBC
};
-struct SStandardParam m_StandardTable[] = {
+static struct SStandardParam m_StandardTable[] = {
{ 0, 0, 0x00, 0x00 }, /* HF_None */
{ 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */
{ 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */
@@ -27,7 +27,7 @@ struct SStandardParam m_StandardTable[] = {
{ 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */
};
-struct SMap m_BP_Filter_Map[] = {
+static struct SMap m_BP_Filter_Map[] = {
{ 62000000, 0x00 },
{ 84000000, 0x01 },
{ 100000000, 0x02 },
@@ -799,14 +799,14 @@ static struct SRFBandMap m_RF_Band_Map[7] = {
{ 865000000, 489500000, 697500000, 842000000},
};
-u8 m_Thermometer_Map_1[16] = {
+static u8 m_Thermometer_Map_1[16] = {
60, 62, 66, 64,
74, 72, 68, 70,
90, 88, 84, 86,
76, 78, 82, 80,
};
-u8 m_Thermometer_Map_2[16] = {
+static u8 m_Thermometer_Map_2[16] = {
92, 94, 98, 96,
106, 104, 100, 102,
122, 120, 116, 118,
diff --git a/drivers/media/dvb-frontends/tda8261_cfg.h b/drivers/media/dvb-frontends/tda8261_cfg.h
index 46710744173b..04a19e14ee5a 100644
--- a/drivers/media/dvb-frontends/tda8261_cfg.h
+++ b/drivers/media/dvb-frontends/tda8261_cfg.h
@@ -19,17 +19,14 @@
static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
- if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@@ -41,18 +38,16 @@ static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
- struct dvb_frontend_ops *frontend_ops = NULL;
- struct dvb_tuner_ops *tuner_ops = NULL;
+ struct dvb_frontend_ops *frontend_ops = &fe->ops;
+ struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
t_state.frequency = frequency;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
+
if (tuner_ops->set_state) {
- if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
+ err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
@@ -68,12 +63,9 @@ static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
struct tuner_state t_state;
int err = 0;
- if (&fe->ops)
- frontend_ops = &fe->ops;
- if (&frontend_ops->tuner_ops)
- tuner_ops = &frontend_ops->tuner_ops;
if (tuner_ops->get_state) {
- if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
+ err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
+ if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 441053be7f55..f40b4cf6107a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -551,6 +551,7 @@ config VIDEO_MT9V032
tristate "Micron MT9V032 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
+ select REGMAP_I2C
---help---
This is a Video4Linux2 sensor-level driver for the Micron
MT9V032 752x480 CMOS sensor.
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index ac1cdbe251a3..821178dcb08e 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -663,7 +663,6 @@ static int adv7180_remove(struct i2c_client *client)
if (state->irq > 0)
free_irq(client->irq, state);
- v4l2_device_unregister_subdev(sd);
adv7180_exit_controls(state);
mutex_destroy(&state->mutex);
return 0;
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 1778d320272e..d4fa213ba74a 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -2588,8 +2588,11 @@ static const struct adv7604_reg_seq adv7604_recommended_settings_hdmi[] = {
};
static const struct adv7604_reg_seq adv7611_recommended_settings_hdmi[] = {
+ /* ADV7611 Register Settings Recommendations Rev 1.5, May 2014 */
{ ADV7604_REG(ADV7604_PAGE_CP, 0x6c), 0x00 },
- { ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x0c },
+ { ADV7604_REG(ADV7604_PAGE_HDMI, 0x9b), 0x03 },
+ { ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x08 },
+ { ADV7604_REG(ADV7604_PAGE_HDMI, 0x85), 0x1f },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x87), 0x70 },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xda },
{ ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x01 },
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index c8fe1358ec9e..8311f1a9a38e 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -62,8 +62,8 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
/* ----------------------------------------------------------------------- */
-static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
- int size, int offset)
+static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *ptoggle, int size, int offset)
{
unsigned char buf[6];
int start, range, toggle, dev, code, ircode;
@@ -86,19 +86,10 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
if (!start)
/* no key pressed */
return 0;
- /*
- * Hauppauge remotes (black/silver) always use
- * specific device ids. If we do not filter the
- * device ids then messages destined for devices
- * such as TVs (id=0) will get through causing
- * mis-fired events.
- *
- * We also filter out invalid key presses which
- * produce annoying debug log entries.
- */
- ircode= (start << 12) | (toggle << 11) | (dev << 6) | code;
- if ((ircode & 0x1fff)==0x1fff)
- /* invalid key press */
+
+ /* filter out invalid key presses */
+ ircode = (start << 12) | (toggle << 11) | (dev << 6) | code;
+ if ((ircode & 0x1fff) == 0x1fff)
return 0;
if (!range)
@@ -107,18 +98,20 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
dprintk(1,"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
start, range, toggle, dev, code);
- /* return key */
- *ir_key = (dev << 8) | code;
- *ir_raw = ircode;
+ *protocol = RC_TYPE_RC5;
+ *scancode = RC_SCANCODE_RC5(dev, code);
+ *ptoggle = toggle;
return 1;
}
-static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_haup(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
- return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
+ return get_key_haup_common (ir, protocol, scancode, toggle, 3, 0);
}
-static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
int ret;
unsigned char buf[1] = { 0 };
@@ -133,10 +126,11 @@ static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (ret != 1)
return (ret < 0) ? ret : -EINVAL;
- return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
+ return get_key_haup_common(ir, protocol, scancode, toggle, 6, 3);
}
-static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pixelview(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
@@ -145,12 +139,15 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
dprintk(1,"read error\n");
return -EIO;
}
- *ir_key = b;
- *ir_raw = b;
+
+ *protocol = RC_TYPE_OTHER;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
-static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char buf[4];
@@ -168,13 +165,14 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if(buf[0] != 0x1 || buf[1] != 0xfe)
return 0;
- *ir_key = buf[2];
- *ir_raw = (buf[2] << 8) | buf[3];
-
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = buf[2];
+ *toggle = 0;
return 1;
}
-static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_knc1(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
@@ -197,13 +195,14 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
/* keep old data */
return 1;
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
-static int get_key_avermedia_cardbus(struct IR_i2c *ir,
- u32 *ir_key, u32 *ir_raw)
+static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char subaddr, key, keygroup;
struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
@@ -237,12 +236,11 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
}
key |= (keygroup & 1) << 6;
- *ir_key = key;
- *ir_raw = key;
- if (!strcmp(ir->ir_codes, RC_MAP_AVERMEDIA_M733A_RM_K6)) {
- *ir_key |= keygroup << 8;
- *ir_raw |= keygroup << 8;
- }
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = key;
+ if (ir->c->addr == 0x41) /* AVerMedia EM78P153 */
+ *scancode |= keygroup << 8;
+ *toggle = 0;
return 1;
}
@@ -250,19 +248,22 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
static int ir_key_poll(struct IR_i2c *ir)
{
- static u32 ir_key, ir_raw;
+ enum rc_type protocol;
+ u32 scancode;
+ u8 toggle;
int rc;
dprintk(3, "%s\n", __func__);
- rc = ir->get_key(ir, &ir_key, &ir_raw);
+ rc = ir->get_key(ir, &protocol, &scancode, &toggle);
if (rc < 0) {
dprintk(2,"error\n");
return rc;
}
if (rc) {
- dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key);
- rc_keydown(ir->rc, ir_key, 0);
+ dprintk(1, "%s: proto = 0x%04x, scancode = 0x%08x\n",
+ __func__, protocol, scancode);
+ rc_keydown(ir->rc, protocol, scancode, toggle);
}
return 0;
}
@@ -327,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
case 0x6b:
name = "FusionHDTV";
ir->get_key = get_key_fusionhdtv;
- rc_type = RC_BIT_RC5;
+ rc_type = RC_BIT_UNKNOWN;
ir_codes = RC_MAP_FUSIONHDTV_MCE;
break;
case 0x40:
@@ -431,8 +432,8 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
* Initialize the other fields of rc_dev
*/
rc->map_name = ir->ir_codes;
- rc_set_allowed_protocols(rc, rc_type);
- rc_set_enabled_protocols(rc, rc_type);
+ rc->allowed_protocols = rc_type;
+ rc->enabled_protocols = rc_type;
if (!rc->driver_name)
rc->driver_name = MODULE_NAME;
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 40172b8d8ea2..d044bce312e0 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1,5 +1,5 @@
/*
- * Driver for MT9V032 CMOS Image Sensor from Micron
+ * Driver for MT9V022, MT9V024, MT9V032, and MT9V034 CMOS Image Sensors
*
* Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
*
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/log2.h>
#include <linux/mutex.h>
+#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
@@ -87,6 +88,7 @@
#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5)
#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6)
#define MT9V032_READ_MODE_DARK_ROWS (1 << 7)
+#define MT9V032_READ_MODE_RESERVED 0x0300
#define MT9V032_PIXEL_OPERATION_MODE 0x0f
#define MT9V034_PIXEL_OPERATION_MODE_HDR (1 << 0)
#define MT9V034_PIXEL_OPERATION_MODE_COLOR (1 << 1)
@@ -133,8 +135,12 @@
#define MT9V032_THERMAL_INFO 0xc1
enum mt9v032_model {
- MT9V032_MODEL_V032_COLOR,
- MT9V032_MODEL_V032_MONO,
+ MT9V032_MODEL_V022_COLOR, /* MT9V022IX7ATC */
+ MT9V032_MODEL_V022_MONO, /* MT9V022IX7ATM */
+ MT9V032_MODEL_V024_COLOR, /* MT9V024IA7XTC */
+ MT9V032_MODEL_V024_MONO, /* MT9V024IA7XTM */
+ MT9V032_MODEL_V032_COLOR, /* MT9V032C12STM */
+ MT9V032_MODEL_V032_MONO, /* MT9V032C12STC */
MT9V032_MODEL_V034_COLOR,
MT9V032_MODEL_V034_MONO,
};
@@ -160,14 +166,14 @@ struct mt9v032_model_info {
};
static const struct mt9v032_model_version mt9v032_versions[] = {
- { MT9V032_CHIP_ID_REV1, "MT9V032 rev1/2" },
- { MT9V032_CHIP_ID_REV3, "MT9V032 rev3" },
- { MT9V034_CHIP_ID_REV1, "MT9V034 rev1" },
+ { MT9V032_CHIP_ID_REV1, "MT9V022/MT9V032 rev1/2" },
+ { MT9V032_CHIP_ID_REV3, "MT9V022/MT9V032 rev3" },
+ { MT9V034_CHIP_ID_REV1, "MT9V024/MT9V034 rev1" },
};
static const struct mt9v032_model_data mt9v032_model_data[] = {
{
- /* MT9V032 revisions 1/2/3 */
+ /* MT9V022, MT9V032 revisions 1/2/3 */
.min_row_time = 660,
.min_hblank = MT9V032_HORIZONTAL_BLANKING_MIN,
.min_vblank = MT9V032_VERTICAL_BLANKING_MIN,
@@ -176,7 +182,7 @@ static const struct mt9v032_model_data mt9v032_model_data[] = {
.max_shutter = MT9V032_TOTAL_SHUTTER_WIDTH_MAX,
.pclk_reg = MT9V032_PIXEL_CLOCK,
}, {
- /* MT9V034 */
+ /* MT9V024, MT9V034 */
.min_row_time = 690,
.min_hblank = MT9V034_HORIZONTAL_BLANKING_MIN,
.min_vblank = MT9V034_VERTICAL_BLANKING_MIN,
@@ -188,6 +194,22 @@ static const struct mt9v032_model_data mt9v032_model_data[] = {
};
static const struct mt9v032_model_info mt9v032_models[] = {
+ [MT9V032_MODEL_V022_COLOR] = {
+ .data = &mt9v032_model_data[0],
+ .color = true,
+ },
+ [MT9V032_MODEL_V022_MONO] = {
+ .data = &mt9v032_model_data[0],
+ .color = false,
+ },
+ [MT9V032_MODEL_V024_COLOR] = {
+ .data = &mt9v032_model_data[1],
+ .color = true,
+ },
+ [MT9V032_MODEL_V024_MONO] = {
+ .data = &mt9v032_model_data[1],
+ .color = false,
+ },
[MT9V032_MODEL_V032_COLOR] = {
.data = &mt9v032_model_data[0],
.color = true,
@@ -224,6 +246,7 @@ struct mt9v032 {
struct mutex power_lock;
int power_count;
+ struct regmap *regmap;
struct clk *clk;
struct mt9v032_platform_data *pdata;
@@ -231,7 +254,6 @@ struct mt9v032 {
const struct mt9v032_model_version *version;
u32 sysclk;
- u16 chip_control;
u16 aec_agc;
u16 hblank;
struct {
@@ -245,40 +267,10 @@ static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
return container_of(sd, struct mt9v032, subdev);
}
-static int mt9v032_read(struct i2c_client *client, const u8 reg)
-{
- s32 data = i2c_smbus_read_word_swapped(client, reg);
- dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
- data, reg);
- return data;
-}
-
-static int mt9v032_write(struct i2c_client *client, const u8 reg,
- const u16 data)
-{
- dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
- data, reg);
- return i2c_smbus_write_word_swapped(client, reg, data);
-}
-
-static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
- u16 value = (mt9v032->chip_control & ~clear) | set;
- int ret;
-
- ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
- if (ret < 0)
- return ret;
-
- mt9v032->chip_control = value;
- return 0;
-}
-
static int
mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ struct regmap *map = mt9v032->regmap;
u16 value = mt9v032->aec_agc;
int ret;
@@ -287,7 +279,7 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
else
value &= ~which;
- ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
+ ret = regmap_write(map, MT9V032_AEC_AGC_ENABLE, value);
if (ret < 0)
return ret;
@@ -298,23 +290,23 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
static int
mt9v032_update_hblank(struct mt9v032 *mt9v032)
{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
struct v4l2_rect *crop = &mt9v032->crop;
unsigned int min_hblank = mt9v032->model->data->min_hblank;
unsigned int hblank;
if (mt9v032->version->version == MT9V034_CHIP_ID_REV1)
min_hblank += (mt9v032->hratio - 1) * 10;
- min_hblank = max_t(unsigned int, (int)mt9v032->model->data->min_row_time - crop->width,
- (int)min_hblank);
+ min_hblank = max_t(int, mt9v032->model->data->min_row_time - crop->width,
+ min_hblank);
hblank = max_t(unsigned int, mt9v032->hblank, min_hblank);
- return mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING, hblank);
+ return regmap_write(mt9v032->regmap, MT9V032_HORIZONTAL_BLANKING,
+ hblank);
}
static int mt9v032_power_on(struct mt9v032 *mt9v032)
{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ struct regmap *map = mt9v032->regmap;
int ret;
ret = clk_set_rate(mt9v032->clk, mt9v032->sysclk);
@@ -328,15 +320,15 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
udelay(1);
/* Reset the chip and stop data read out */
- ret = mt9v032_write(client, MT9V032_RESET, 1);
+ ret = regmap_write(map, MT9V032_RESET, 1);
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_RESET, 0);
+ ret = regmap_write(map, MT9V032_RESET, 0);
if (ret < 0)
return ret;
- return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
+ return regmap_write(map, MT9V032_CHIP_CONTROL, 0);
}
static void mt9v032_power_off(struct mt9v032 *mt9v032)
@@ -346,7 +338,7 @@ static void mt9v032_power_off(struct mt9v032 *mt9v032)
static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
{
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ struct regmap *map = mt9v032->regmap;
int ret;
if (!on) {
@@ -360,14 +352,14 @@ static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
/* Configure the pixel clock polarity */
if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
- ret = mt9v032_write(client, mt9v032->model->data->pclk_reg,
+ ret = regmap_write(map, mt9v032->model->data->pclk_reg,
MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
if (ret < 0)
return ret;
}
/* Disable the noise correction algorithm and restore the controls. */
- ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
+ ret = regmap_write(map, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
if (ret < 0)
return ret;
@@ -411,38 +403,39 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
| MT9V032_CHIP_CONTROL_DOUT_ENABLE
| MT9V032_CHIP_CONTROL_SEQUENTIAL;
- struct i2c_client *client = v4l2_get_subdevdata(subdev);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
struct v4l2_rect *crop = &mt9v032->crop;
+ struct regmap *map = mt9v032->regmap;
unsigned int hbin;
unsigned int vbin;
int ret;
if (!enable)
- return mt9v032_set_chip_control(mt9v032, mode, 0);
+ return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, 0);
/* Configure the window size and row/column bin */
hbin = fls(mt9v032->hratio) - 1;
vbin = fls(mt9v032->vratio) - 1;
- ret = mt9v032_write(client, MT9V032_READ_MODE,
- hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT |
- vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT);
+ ret = regmap_update_bits(map, MT9V032_READ_MODE,
+ ~MT9V032_READ_MODE_RESERVED,
+ hbin << MT9V032_READ_MODE_COLUMN_BIN_SHIFT |
+ vbin << MT9V032_READ_MODE_ROW_BIN_SHIFT);
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
+ ret = regmap_write(map, MT9V032_COLUMN_START, crop->left);
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
+ ret = regmap_write(map, MT9V032_ROW_START, crop->top);
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
+ ret = regmap_write(map, MT9V032_WINDOW_WIDTH, crop->width);
if (ret < 0)
return ret;
- ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
+ ret = regmap_write(map, MT9V032_WINDOW_HEIGHT, crop->height);
if (ret < 0)
return ret;
@@ -451,7 +444,7 @@ static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
return ret;
/* Switch to master "normal" mode */
- return mt9v032_set_chip_control(mt9v032, 0, mode);
+ return regmap_update_bits(map, MT9V032_CHIP_CONTROL, mode, mode);
}
static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
@@ -633,7 +626,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9v032 *mt9v032 =
container_of(ctrl->handler, struct mt9v032, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+ struct regmap *map = mt9v032->regmap;
u32 freq;
u16 data;
@@ -643,23 +636,23 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->val);
case V4L2_CID_GAIN:
- return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
+ return regmap_write(map, MT9V032_ANALOG_GAIN, ctrl->val);
case V4L2_CID_EXPOSURE_AUTO:
return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
!ctrl->val);
case V4L2_CID_EXPOSURE:
- return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
- ctrl->val);
+ return regmap_write(map, MT9V032_TOTAL_SHUTTER_WIDTH,
+ ctrl->val);
case V4L2_CID_HBLANK:
mt9v032->hblank = ctrl->val;
return mt9v032_update_hblank(mt9v032);
case V4L2_CID_VBLANK:
- return mt9v032_write(client, MT9V032_VERTICAL_BLANKING,
- ctrl->val);
+ return regmap_write(map, MT9V032_VERTICAL_BLANKING,
+ ctrl->val);
case V4L2_CID_PIXEL_RATE:
case V4L2_CID_LINK_FREQ:
@@ -667,7 +660,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
break;
freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
- mt9v032->pixel_rate->val64 = freq;
+ *mt9v032->pixel_rate->p_new.p_s64 = freq;
mt9v032->sysclk = freq;
break;
@@ -696,7 +689,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
| MT9V032_TEST_PATTERN_FLIP;
break;
}
- return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
+ return regmap_write(map, MT9V032_TEST_PATTERN, data);
}
return 0;
@@ -764,7 +757,7 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
struct i2c_client *client = v4l2_get_subdevdata(subdev);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
unsigned int i;
- s32 version;
+ u32 version;
int ret;
dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
@@ -777,10 +770,10 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
}
/* Read and check the sensor version */
- version = mt9v032_read(client, MT9V032_CHIP_VERSION);
- if (version < 0) {
+ ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version);
+ if (ret < 0) {
dev_err(&client->dev, "Failed reading chip version\n");
- return version;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(mt9v032_versions); ++i) {
@@ -867,6 +860,13 @@ static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
.close = mt9v032_close,
};
+static const struct regmap_config mt9v032_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = 0xff,
+ .cache_type = REGCACHE_RBTREE,
+};
+
/* -----------------------------------------------------------------------------
* Driver initialization and probing
*/
@@ -890,6 +890,10 @@ static int mt9v032_probe(struct i2c_client *client,
if (!mt9v032)
return -ENOMEM;
+ mt9v032->regmap = devm_regmap_init_i2c(client, &mt9v032_regmap_config);
+ if (IS_ERR(mt9v032->regmap))
+ return PTR_ERR(mt9v032->regmap);
+
mt9v032->clk = devm_clk_get(&client->dev, NULL);
if (IS_ERR(mt9v032->clk))
return PTR_ERR(mt9v032->clk);
@@ -931,7 +935,7 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->pixel_rate =
v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
+ V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (pdata && pdata->link_freqs) {
unsigned int def = 0;
@@ -984,10 +988,19 @@ static int mt9v032_probe(struct i2c_client *client,
mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+ if (ret < 0)
+ goto err;
+ mt9v032->subdev.dev = &client->dev;
+ ret = v4l2_async_register_subdev(&mt9v032->subdev);
if (ret < 0)
- v4l2_ctrl_handler_free(&mt9v032->ctrls);
+ goto err;
+ return 0;
+
+err:
+ media_entity_cleanup(&mt9v032->subdev.entity);
+ v4l2_ctrl_handler_free(&mt9v032->ctrls);
return ret;
}
@@ -996,6 +1009,7 @@ static int mt9v032_remove(struct i2c_client *client)
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+ v4l2_async_unregister_subdev(subdev);
v4l2_ctrl_handler_free(&mt9v032->ctrls);
v4l2_device_unregister_subdev(subdev);
media_entity_cleanup(&subdev->entity);
@@ -1004,6 +1018,10 @@ static int mt9v032_remove(struct i2c_client *client)
}
static const struct i2c_device_id mt9v032_id[] = {
+ { "mt9v022", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_COLOR] },
+ { "mt9v022m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V022_MONO] },
+ { "mt9v024", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_COLOR] },
+ { "mt9v024m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V024_MONO] },
{ "mt9v032", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_COLOR] },
{ "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] },
{ "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] },
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index 271d0b7967a6..7eae48766e2b 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -554,6 +554,7 @@ static int noon010_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
nf = noon010_try_fmt(sd, &fmt->format);
noon010_try_frame_size(&fmt->format, &size);
fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
+ fmt->format.field = V4L2_FIELD_NONE;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
if (fh) {
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
index 2750de634270..1fcc76fd1bbf 100644
--- a/drivers/media/i2c/s5k4ecgx.c
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -594,6 +594,7 @@ static int s5k4ecgx_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
pf = s5k4ecgx_try_fmt(sd, &fmt->format);
s5k4ecgx_try_frame_size(&fmt->format, &fsize);
fmt->format.colorspace = V4L2_COLORSPACE_JPEG;
+ fmt->format.field = V4L2_FIELD_NONE;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
if (fh) {
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 2d768ef67cc5..564f05f2c9ef 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1313,6 +1313,8 @@ static int s5k5baf_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
const struct s5k5baf_pixfmt *pixfmt;
int ret = 0;
+ mf->field = V4L2_FIELD_NONE;
+
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(fh, fmt->pad) = *mf;
return 0;
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index 7bc2271ca009..c11a40850ed1 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -115,6 +115,7 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf)
fmt = find_sensor_format(mf);
mf->code = fmt->code;
+ mf->field = V4L2_FIELD_NONE;
v4l_bound_align_image(&mf->width, S5K6A3_SENSOR_MIN_WIDTH,
S5K6A3_SENSOR_MAX_WIDTH, 0,
&mf->height, S5K6A3_SENSOR_MIN_HEIGHT,
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 06fb03291d59..1eaf975d3612 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -297,8 +297,8 @@ static int smiapp_pll_update(struct smiapp_sensor *sensor)
if (rval < 0)
return rval;
- sensor->pixel_rate_parray->cur.val64 = pll->vt_pix_clk_freq_hz;
- sensor->pixel_rate_csi->cur.val64 = pll->pixel_rate_csi;
+ *sensor->pixel_rate_parray->p_cur.p_s64 = pll->vt_pix_clk_freq_hz;
+ *sensor->pixel_rate_csi->p_cur.p_s64 = pll->pixel_rate_csi;
return 0;
}
@@ -533,7 +533,7 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
sensor->pixel_rate_parray = v4l2_ctrl_new_std(
&sensor->pixel_array->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
+ V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (sensor->pixel_array->ctrl_handler.error) {
dev_err(&client->dev,
@@ -562,7 +562,7 @@ static int smiapp_init_controls(struct smiapp_sensor *sensor)
sensor->pixel_rate_csi = v4l2_ctrl_new_std(
&sensor->src->ctrl_handler, &smiapp_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
+ V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
if (sensor->src->ctrl_handler.error) {
dev_err(&client->dev,
@@ -1554,6 +1554,7 @@ static int __smiapp_get_format(struct v4l2_subdev *subdev,
fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
fmt->format.width = r->width;
fmt->format.height = r->height;
+ fmt->format.field = V4L2_FIELD_NONE;
}
return 0;
@@ -1687,6 +1688,7 @@ static int smiapp_set_format(struct v4l2_subdev *subdev,
fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
fmt->format.width &= ~1;
fmt->format.height &= ~1;
+ fmt->format.field = V4L2_FIELD_NONE;
fmt->format.width =
clamp(fmt->format.width,
@@ -2544,9 +2546,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev)
}
snprintf(this->sd.name,
- sizeof(this->sd.name), "%s %d-%4.4x %s",
- sensor->minfo.name, i2c_adapter_id(client->adapter),
- client->addr, _this->name);
+ sizeof(this->sd.name), "%s %s %d-%4.4x",
+ sensor->minfo.name, _this->name,
+ i2c_adapter_id(client->adapter), client->addr);
this->sink_fmt.width =
sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
@@ -2674,6 +2676,7 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->width = sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1;
try_fmt->height = sensor->limits[SMIAPP_LIMIT_Y_ADDR_MAX] + 1;
try_fmt->code = mbus_code;
+ try_fmt->field = V4L2_FIELD_NONE;
try_crop->top = 0;
try_crop->left = 0;
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index df97033fa6ef..dbd8c142d6ef 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -403,7 +403,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->val <= ctrl->default_value) {
/* Pack it into 0..1 step 0.125, register values 0..8 */
unsigned long range = ctrl->default_value - ctrl->minimum;
- data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
+ data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&client->dev, "Setting gain %d\n", data);
data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
@@ -413,7 +413,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
/* Pack it into 1.125..15 variable step, register values 9..67 */
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = ctrl->maximum - ctrl->default_value - 1;
- unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
+ unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
111 + range / 2) / range + 9;
if (gain <= 32)
@@ -434,7 +434,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
unsigned long range = exp->maximum - exp->minimum;
- unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
+ unsigned long shutter = ((exp->val - (s32)exp->minimum) * 1048 +
range / 2) / range + 1;
dev_dbg(&client->dev,
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index ccf59406a172..b51e8562e775 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -931,6 +931,12 @@ static int mt9m111_probe(struct i2c_client *client,
struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
int ret;
+ if (client->dev.of_node) {
+ ssdd = devm_kzalloc(&client->dev, sizeof(*ssdd), GFP_KERNEL);
+ if (!ssdd)
+ return -ENOMEM;
+ client->dev.platform_data = ssdd;
+ }
if (!ssdd) {
dev_err(&client->dev, "mt9m111: driver needs platform data\n");
return -EINVAL;
@@ -1015,6 +1021,11 @@ static int mt9m111_remove(struct i2c_client *client)
return 0;
}
+static const struct of_device_id mt9m111_of_match[] = {
+ { .compatible = "micron,mt9m111", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt9m111_of_match);
static const struct i2c_device_id mt9m111_id[] = {
{ "mt9m111", 0 },
@@ -1025,6 +1036,7 @@ MODULE_DEVICE_TABLE(i2c, mt9m111_id);
static struct i2c_driver mt9m111_i2c_driver = {
.driver = {
.name = "mt9m111",
+ .of_match_table = of_match_ptr(mt9m111_of_match),
},
.probe = mt9m111_probe,
.remove = mt9m111_remove,
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index ee7bb0ffcecb..f8358c4071a9 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -474,7 +474,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->val <= ctrl->default_value) {
/* Pack it into 0..1 step 0.125, register values 0..8 */
unsigned long range = ctrl->default_value - ctrl->minimum;
- data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
+ data = ((ctrl->val - (s32)ctrl->minimum) * 8 + range / 2) / range;
dev_dbg(&client->dev, "Setting gain %d\n", data);
data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@@ -485,7 +485,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = ctrl->maximum - ctrl->default_value - 1;
/* calculated gain: map 65..127 to 9..1024 step 0.125 */
- unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
+ unsigned long gain = ((ctrl->val - (s32)ctrl->default_value - 1) *
1015 + range / 2) / range + 9;
if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
@@ -507,7 +507,7 @@ static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
unsigned int range = exp->maximum - exp->minimum;
- unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
+ unsigned int shutter = ((exp->val - (s32)exp->minimum) * 1048 +
range / 2) / range + 1;
u32 old;
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index f9f95f815b1a..99022c8d76eb 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -583,7 +583,7 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
/* mt9v022 has minimum == default */
unsigned long range = gain->maximum - gain->minimum;
/* Valid values 16 to 64, 32 to 64 must be even. */
- unsigned long gain_val = ((gain->val - gain->minimum) *
+ unsigned long gain_val = ((gain->val - (s32)gain->minimum) *
48 + range / 2) / range + 16;
if (gain_val >= 32)
@@ -608,7 +608,7 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
} else {
struct v4l2_ctrl *exp = mt9v022->exposure;
unsigned long range = exp->maximum - exp->minimum;
- unsigned long shutter = ((exp->val - exp->minimum) *
+ unsigned long shutter = ((exp->val - (s32)exp->minimum) *
479 + range / 2) / range + 1;
/*
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index a9121254e37a..193e7d6c29c8 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -56,38 +56,29 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[1];
int rc;
- struct i2c_msg msg[] = {
- { .addr = c->addr, .flags = 0,
- .buf = &addr, .len = 1 },
- { .addr = c->addr, .flags = I2C_M_RD,
- .buf = buffer, .len = 1 }
- };
-
- rc = i2c_transfer(c->adapter, msg, 2);
- if (rc < 0 || rc != 2) {
- v4l2_err(sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
- return rc < 0 ? rc : -EIO;
+
+ rc = i2c_smbus_read_byte_data(c, addr);
+ if (rc < 0) {
+ v4l2_err(sd, "i2c i/o error: rc == %d\n", rc);
+ return rc;
}
- v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
+ v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, rc);
- return (buffer[0]);
+ return rc;
}
static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
unsigned char value)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
- unsigned char buffer[2];
int rc;
- buffer[0] = addr;
- buffer[1] = value;
- v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
- if (2 != (rc = i2c_master_send(c, buffer, 2)))
- v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
+ v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", addr, value);
+ rc = i2c_smbus_write_byte_data(c, addr, value);
+ if (rc < 0)
+ v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d\n", rc);
}
static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
@@ -1148,10 +1139,10 @@ static int tvp5150_probe(struct i2c_client *c,
/* Is TVP5150A */
if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) {
v4l2_info(sd, "tvp%02x%02xa detected.\n",
- tvp5150_id[2], tvp5150_id[3]);
+ tvp5150_id[0], tvp5150_id[1]);
} else {
v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
- tvp5150_id[2], tvp5150_id[3]);
+ tvp5150_id[0], tvp5150_id[1]);
v4l2_info(sd, "*** Rom ver is %d.%d\n",
tvp5150_id[2], tvp5150_id[3]);
}
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 88b97c9e64ac..73a432934bd8 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -106,8 +106,6 @@ static long media_device_enum_entities(struct media_device *mdev,
if (ent->name) {
strncpy(u_ent.name, ent->name, sizeof(u_ent.name));
u_ent.name[sizeof(u_ent.name) - 1] = '\0';
- } else {
- memset(u_ent.name, 0, sizeof(u_ent.name));
}
u_ent.type = ent->type;
u_ent.revision = ent->revision;
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c
index 416507a83668..67b9da1dc43f 100644
--- a/drivers/media/parport/bw-qcam.c
+++ b/drivers/media/parport/bw-qcam.c
@@ -759,7 +759,6 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pix->sizeimage = pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
- pix->priv = 0;
return 0;
}
@@ -785,7 +784,6 @@ static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
pix->sizeimage = pix->width * pix->height;
/* Just a guess */
pix->colorspace = V4L2_COLORSPACE_SRGB;
- pix->priv = 0;
return 0;
}
@@ -990,7 +988,6 @@ static struct qcam *qcam_init(struct parport *port)
qcam->vdev.fops = &qcam_fops;
qcam->vdev.lock = &qcam->lock;
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
- set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
qcam->vdev.release = video_device_release_empty;
video_set_drvdata(&qcam->vdev, qcam);
diff --git a/drivers/media/parport/c-qcam.c b/drivers/media/parport/c-qcam.c
index ec51e1f12e82..b9010bd3ed3e 100644
--- a/drivers/media/parport/c-qcam.c
+++ b/drivers/media/parport/c-qcam.c
@@ -761,7 +761,6 @@ static struct qcam *qcam_init(struct parport *port)
qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
qcam->vdev.release = video_device_release_empty;
qcam->vdev.ctrl_handler = &qcam->hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
video_set_drvdata(&qcam->vdev, qcam);
mutex_init(&qcam->lock);
diff --git a/drivers/media/parport/pms.c b/drivers/media/parport/pms.c
index 66c957a02ba7..9bc105b3db1b 100644
--- a/drivers/media/parport/pms.c
+++ b/drivers/media/parport/pms.c
@@ -1091,7 +1091,6 @@ static int pms_probe(struct device *pdev, unsigned int card)
dev->vdev.release = video_device_release_empty;
dev->vdev.lock = &dev->lock;
dev->vdev.tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
video_set_drvdata(&dev->vdev, dev);
dev->std = V4L2_STD_NTSC_M;
dev->height = 240;
diff --git a/drivers/media/parport/w9966.c b/drivers/media/parport/w9966.c
index db2a6003a1c3..f7502f3a6a3c 100644
--- a/drivers/media/parport/w9966.c
+++ b/drivers/media/parport/w9966.c
@@ -883,7 +883,6 @@ static int w9966_init(struct w9966 *cam, struct parport *port)
cam->vdev.ioctl_ops = &w9966_ioctl_ops;
cam->vdev.release = video_device_release_empty;
cam->vdev.ctrl_handler = &cam->hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
video_set_drvdata(&cam->vdev, cam);
mutex_init(&cam->lock);
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index 53196f1366f3..5c16c9c2203e 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -19,6 +19,7 @@ if MEDIA_ANALOG_TV_SUPPORT
source "drivers/media/pci/ivtv/Kconfig"
source "drivers/media/pci/zoran/Kconfig"
source "drivers/media/pci/saa7146/Kconfig"
+source "drivers/media/pci/solo6x10/Kconfig"
endif
if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 35cc57862c01..e5b53fb569ef 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
obj-$(CONFIG_VIDEO_MEYE) += meye/
obj-$(CONFIG_STA2X11_VIP) += sta2x11/
+obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index da780f42b121..970e542d3a51 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3886,7 +3886,6 @@ static struct video_device *vdev_init(struct bttv *btv,
vfd->v4l2_dev = &btv->c.v4l2_dev;
vfd->release = video_device_release;
vfd->debug = bttv_debug;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
video_set_drvdata(vfd, btv);
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index 5930bce16658..67c8d6b2c335 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -73,12 +73,12 @@ static void ir_handle_key(struct bttv *btv)
if ((ir->mask_keydown && (gpio & ir->mask_keydown)) ||
(ir->mask_keyup && !(gpio & ir->mask_keyup))) {
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
} else {
/* HACK: Probably, ir->mask_keydown is missing
for this board */
if (btv->c.type == BTTV_BOARD_WINFAST2000)
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
rc_keyup(ir->dev);
}
@@ -103,7 +103,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
gpio, data,
(gpio & ir->mask_keyup) ? " up" : "up/down");
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
if (keyup)
rc_keyup(ir->dev);
} else {
@@ -117,7 +117,7 @@ static void ir_enltv_handle_key(struct bttv *btv)
if (keyup)
rc_keyup(ir->dev);
else
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
}
ir->last_gpio = data | keyup;
@@ -154,10 +154,10 @@ static void bttv_input_timer(unsigned long data)
* testing.
*/
-#define RC5_START(x) (((x) >> 12) & 3)
-#define RC5_TOGGLE(x) (((x) >> 11) & 1)
-#define RC5_ADDR(x) (((x) >> 6) & 31)
-#define RC5_INSTR(x) ((x) & 63)
+#define RC5_START(x) (((x) >> 12) & 0x03)
+#define RC5_TOGGLE(x) (((x) >> 11) & 0x01)
+#define RC5_ADDR(x) (((x) >> 6) & 0x1f)
+#define RC5_INSTR(x) (((x) >> 0) & 0x3f)
/* decode raw bit pattern to RC5 code */
static u32 bttv_rc5_decode(unsigned int code)
@@ -195,8 +195,8 @@ static void bttv_rc5_timer_end(unsigned long data)
{
struct bttv_ir *ir = (struct bttv_ir *)data;
struct timeval tv;
- u32 gap;
- u32 rc5 = 0;
+ u32 gap, rc5, scancode;
+ u8 toggle, command, system;
/* get time */
do_gettimeofday(&tv);
@@ -221,26 +221,29 @@ static void bttv_rc5_timer_end(unsigned long data)
if (ir->last_bit < 20) {
/* ignore spurious codes (caused by light/other remotes) */
dprintk("short code: %x\n", ir->code);
- } else {
- ir->code = (ir->code << ir->shift_by) | 1;
- rc5 = bttv_rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != ir->start) {
- pr_info(DEVNAME ":"
- " rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == ir->addr) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code */
- rc_keydown(ir->dev, instr, toggle);
- dprintk("instruction %x, toggle %x\n",
- instr, toggle);
- }
+ return;
}
+
+ ir->code = (ir->code << ir->shift_by) | 1;
+ rc5 = bttv_rc5_decode(ir->code);
+
+ toggle = RC5_TOGGLE(rc5);
+ system = RC5_ADDR(rc5);
+ command = RC5_INSTR(rc5);
+
+ switch (RC5_START(rc5)) {
+ case 0x3:
+ break;
+ case 0x2:
+ command += 0x40;
+ break;
+ default:
+ return;
+ }
+
+ scancode = RC_SCANCODE_RC5(system, command);
+ rc_keydown(ir->dev, RC_TYPE_RC5, scancode, toggle);
+ dprintk("scancode %x, toggle %x\n", scancode, toggle);
}
static int bttv_rc5_irq(struct bttv *btv)
@@ -310,8 +313,6 @@ static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
/* set timer_end for code completion */
setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir);
ir->shift_by = 1;
- ir->start = 3;
- ir->addr = 0x0;
ir->rc5_remote_gap = ir_rc5_remote_gap;
}
}
@@ -335,7 +336,8 @@ static void bttv_ir_stop(struct bttv *btv)
* Get_key functions used by I2C remotes
*/
-static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pv951(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
@@ -362,8 +364,9 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
* the device is bound to the vendor-provided RC.
*/
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
@@ -490,8 +493,8 @@ int bttv_input_init(struct bttv *btv)
ir->polling = 50; // ms
break;
case BTTV_BOARD_NEBULA_DIGITV:
- ir_codes = RC_MAP_NEBULA;
- ir->rc5_gpio = true;
+ ir_codes = RC_MAP_NEBULA;
+ ir->rc5_gpio = true;
break;
case BTTV_BOARD_MACHTV_MAGICTV:
ir_codes = RC_MAP_APAC_VIEWCOMP;
@@ -514,7 +517,8 @@ int bttv_input_init(struct bttv *btv)
ir->mask_keycode);
break;
}
- if (NULL == ir_codes) {
+
+ if (!ir_codes) {
dprintk("Ooops: IR config error [card=%d]\n", btv->c.type);
err = -ENODEV;
goto err_out_free;
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index 6eefb595d0fa..9fe19488b30b 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -133,8 +133,6 @@ struct bttv_ir {
u32 polling;
u32 last_gpio;
int shift_by;
- int start; // What should RC5_START() be
- int addr; // What RC5_ADDR() should be.
int rc5_remote_gap;
/* RC5 gpio */
diff --git a/drivers/media/pci/cx18/cx18-alsa.h b/drivers/media/pci/cx18/cx18-alsa.h
index 447da374c9e8..2718be28bf5f 100644
--- a/drivers/media/pci/cx18/cx18-alsa.h
+++ b/drivers/media/pci/cx18/cx18-alsa.h
@@ -49,7 +49,6 @@ static inline void snd_cx18_unlock(struct snd_cx18_card *cxsc)
}
#define CX18_ALSA_DBGFLG_WARN (1 << 0)
-#define CX18_ALSA_DBGFLG_WARN (1 << 0)
#define CX18_ALSA_DBGFLG_INFO (1 << 1)
#define CX18_ALSA_DEBUG(x, type, fmt, args...) \
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index fefb2cd35838..6f2b59042b73 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -156,7 +156,6 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
pixfmt->height = cx->cxhdl.height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = s->pixelformat;
pixfmt->sizeimage = s->vb_bytes_per_frame;
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index 843c62b2f482..f3541b5156ce 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -375,7 +375,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
s->video_dev->release = video_device_release;
s->video_dev->tvnorms = V4L2_STD_ALL;
s->video_dev->lock = &cx->serialize_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
cx18_set_funcs(s->video_dev);
return 0;
}
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
index d1dcb1d2e087..e12c006e6e2d 100644
--- a/drivers/media/pci/cx23885/Kconfig
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -31,12 +31,14 @@ config VIDEO_CX23885
select DVB_TDA10071 if MEDIA_SUBDRV_AUTOSELECT
select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
---help---
This is a video4linux driver for Conexant 23885 based
TV cards.
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 95666eee7b27..bf89fc88692e 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1266,7 +1266,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- if (UNSET == dev->tuner_type)
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
@@ -1284,7 +1284,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- if (UNSET == dev->tuner_type)
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
/* Update the A/V core */
@@ -1299,7 +1299,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- if (UNSET == dev->tuner_type)
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
@@ -1347,7 +1347,7 @@ static int vidioc_querycap(struct file *file, void *priv,
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
0;
- if (UNSET != dev->tuner_type)
+ if (dev->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 79f20c8c842e..c2b608007190 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -619,7 +619,12 @@ struct cx23885_board cx23885_boards[] = {
},
[CX23885_BOARD_HAUPPAUGE_HVR4400] = {
.name = "Hauppauge WinTV-HVR4400",
+ .porta = CX23885_ANALOG_VIDEO,
.portb = CX23885_MPEG_DVB,
+ .portc = CX23885_MPEG_DVB,
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60, /* 0xc0 >> 1 */
+ .tuner_bus = 1,
},
[CX23885_BOARD_AVERMEDIA_HC81R] = {
.name = "AVerTV Hybrid Express Slim HC81R",
@@ -649,7 +654,31 @@ struct cx23885_board cx23885_boards[] = {
CX25840_NONE1_CH3,
.amux = CX25840_AUDIO6,
} },
- }
+ },
+ [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2] = {
+ .name = "DViCO FusionHDTV DVB-T Dual Express2",
+ .portb = CX23885_MPEG_DVB,
+ .portc = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_HAUPPAUGE_IMPACTVCBE] = {
+ .name = "Hauppauge ImpactVCB-e",
+ .tuner_type = TUNER_ABSENT,
+ .porta = CX23885_ANALOG_VIDEO,
+ .input = {{
+ .type = CX23885_VMUX_COMPOSITE1,
+ .vmux = CX25840_VIN7_CH3 |
+ CX25840_VIN4_CH2 |
+ CX25840_VIN6_CH1,
+ .amux = CX25840_AUDIO7,
+ }, {
+ .type = CX23885_VMUX_SVIDEO,
+ .vmux = CX25840_VIN7_CH3 |
+ CX25840_VIN4_CH2 |
+ CX25840_VIN8_CH1 |
+ CX25840_SVIDEO_ON,
+ .amux = CX25840_AUDIO7,
+ } },
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -897,6 +926,14 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x1461,
.subdevice = 0xd939,
.card = CX23885_BOARD_AVERMEDIA_HC81R,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x7133,
+ .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE,
+ }, {
+ .subvendor = 0x18ac,
+ .subdevice = 0xdb98,
+ .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -977,6 +1014,9 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
case 71009:
/* WinTV-HVR1200 (PCIe, Retail, full height)
* DVB-T and basic analog */
+ case 71100:
+ /* WinTV-ImpactVCB-e (PCIe, Retail, half height)
+ * Basic analog */
case 71359:
/* WinTV-HVR1200 (PCIe, OEM, half height)
* DVB-T and basic analog */
@@ -1137,6 +1177,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
+ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2:
/* Two identical tuners on two different i2c buses,
* we need to reset the correct gpio. */
if (port->nr == 1)
@@ -1280,6 +1321,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
cx_set(GP0_IO, 0x000f000f);
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
+ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2:
/* GPIO-0 portb xc3028 reset */
/* GPIO-1 portb zl10353 reset */
/* GPIO-2 portc xc3028 reset */
@@ -1449,13 +1491,16 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
break;
case CX23885_BOARD_HAUPPAUGE_HVR4400:
/* GPIO-8 tda10071 demod reset */
+ /* GPIO-9 si2165 demod reset */
/* Put the parts into reset and back */
- cx23885_gpio_enable(dev, GPIO_8, 1);
- cx23885_gpio_clear(dev, GPIO_8);
+ cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1);
+
+ cx23885_gpio_clear(dev, GPIO_8 | GPIO_9);
mdelay(100);
- cx23885_gpio_set(dev, GPIO_8);
+ cx23885_gpio_set(dev, GPIO_8 | GPIO_9);
mdelay(100);
+
break;
case CX23885_BOARD_AVERMEDIA_HC81R:
cx_clear(MC417_CTL, 1);
@@ -1585,6 +1630,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg);
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
+ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2:
request_module("ir-kbd-i2c");
break;
}
@@ -1701,6 +1747,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1850:
case CX23885_BOARD_HAUPPAUGE_HVR1290:
case CX23885_BOARD_HAUPPAUGE_HVR4400:
+ case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE:
if (dev->i2c_bus[0].i2c_rc == 0)
hauppauge_eeprom(dev, eeprom+0xc0);
break;
@@ -1720,6 +1767,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
+ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2:
ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -1799,6 +1847,9 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
@@ -1807,6 +1858,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1200:
case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_HAUPPAUGE_HVR1400:
+ case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000:
@@ -1835,6 +1887,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1800:
+ case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE:
case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index 4be01b3bd4f5..968fecc32f9c 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -44,6 +44,7 @@
#include "tuner-xc2028.h"
#include "tuner-simple.h"
#include "dib7000p.h"
+#include "dib0070.h"
#include "dibx000_common.h"
#include "zl10353.h"
#include "stv0900.h"
@@ -71,6 +72,7 @@
#include "tda10071.h"
#include "a8293.h"
#include "mb86a20s.h"
+#include "si2165.h"
static unsigned int debug;
@@ -302,6 +304,11 @@ static struct tda18271_config hauppauge_hvr1210_tuner_config = {
.output_opt = TDA18271_OUTPUT_LT_OFF,
};
+static struct tda18271_config hauppauge_hvr4400_tuner_config = {
+ .gate = TDA18271_GATE_DIGITAL,
+ .output_opt = TDA18271_OUTPUT_LT_OFF,
+};
+
static struct tda18271_std_map hauppauge_hvr127x_std_map = {
.atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
.if_lvl = 1, .rfagc_top = 0x58 },
@@ -702,6 +709,12 @@ static const struct a8293_config hauppauge_a8293_config = {
.i2c_addr = 0x0b,
};
+static const struct si2165_config hauppauge_hvr4400_si2165_config = {
+ .i2c_addr = 0x64,
+ .chip_mode = SI2165_MODE_PLL_XTAL,
+ .ref_freq_Hz = 16000000,
+};
+
static int netup_altera_fpga_rw(void *device, int flag, int data, int read)
{
struct cx23885_dev *dev = (struct cx23885_dev *)device;
@@ -746,8 +759,108 @@ static int netup_altera_fpga_rw(void *device, int flag, int data, int read)
return 0;
};
+static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+ struct dib7000p_ops *dib7000p_ops = fe->sec_priv;
+
+ return dib7000p_ops->set_gpio(fe, 8, 0, !onoff);
+}
+
+static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+ return 0;
+}
+
+static struct dib0070_config dib7070p_dib0070_config = {
+ .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+ .reset = dib7070_tuner_reset,
+ .sleep = dib7070_tuner_sleep,
+ .clock_khz = 12000,
+ .freq_offset_khz_vhf = 550,
+ /* .flip_chip = 1, */
+};
+
+/* DIB7070 generic */
+static struct dibx000_agc_config dib7070_agc_config = {
+ .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+
+ /*
+ * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
+ * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+ * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
+ */
+ .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
+ (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
+ .inv_gain = 600,
+ .time_stabiliz = 10,
+ .alpha_level = 0,
+ .thlock = 118,
+ .wbd_inv = 0,
+ .wbd_ref = 3530,
+ .wbd_sel = 1,
+ .wbd_alpha = 5,
+ .agc1_max = 65535,
+ .agc1_min = 0,
+ .agc2_max = 65535,
+ .agc2_min = 0,
+ .agc1_pt1 = 0,
+ .agc1_pt2 = 40,
+ .agc1_pt3 = 183,
+ .agc1_slope1 = 206,
+ .agc1_slope2 = 255,
+ .agc2_pt1 = 72,
+ .agc2_pt2 = 152,
+ .agc2_slope1 = 88,
+ .agc2_slope2 = 90,
+ .alpha_mant = 17,
+ .alpha_exp = 27,
+ .beta_mant = 23,
+ .beta_exp = 51,
+ .perform_agc_softsplit = 0,
+};
+
+static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
+ .internal = 60000,
+ .sampling = 15000,
+ .pll_prediv = 1,
+ .pll_ratio = 20,
+ .pll_range = 3,
+ .pll_reset = 1,
+ .pll_bypass = 0,
+ .enable_refdiv = 0,
+ .bypclk_div = 0,
+ .IO_CLK_en_core = 1,
+ .ADClkSrc = 1,
+ .modulo = 2,
+ /* refsel, sel, freq_15k */
+ .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
+ .ifreq = (0 << 25) | 0,
+ .timf = 20452225,
+ .xtal_hz = 12000000,
+};
+
+static struct dib7000p_config dib7070p_dib7000p_config = {
+ /* .output_mode = OUTMODE_MPEG2_FIFO, */
+ .output_mode = OUTMODE_MPEG2_SERIAL,
+ /* .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, */
+ .output_mpeg2_in_188_bytes = 1,
+
+ .agc_config_count = 1,
+ .agc = &dib7070_agc_config,
+ .bw = &dib7070_bw_config_12_mhz,
+ .tuner_is_baseband = 1,
+ .spur_protect = 1,
+
+ .gpio_dir = 0xfcef, /* DIB7000P_GPIO_DEFAULT_DIRECTIONS, */
+ .gpio_val = 0x0110, /* DIB7000P_GPIO_DEFAULT_VALUES, */
+ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+ .hostbus_diversity = 1,
+};
+
static int dvb_register(struct cx23885_tsport *port)
{
+ struct dib7000p_ops dib7000p_ops;
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
@@ -925,8 +1038,11 @@ static int dvb_register(struct cx23885_tsport *port)
break;
case CX23885_BOARD_HAUPPAUGE_HVR1400:
i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(dib7000p_attach,
- &i2c_bus->i2c_adap,
+
+ if (!dvb_attach(dib7000p_attach, &dib7000p_ops))
+ return -ENODEV;
+
+ fe0->dvb.frontend = dib7000p_ops.init(&i2c_bus->i2c_adap,
0x12, &hauppauge_hvr1400_dib7000_config);
if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
@@ -989,6 +1105,30 @@ static int dvb_register(struct cx23885_tsport *port)
}
break;
}
+ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2: {
+ i2c_bus = &dev->i2c_bus[port->nr - 1];
+ /* cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); */
+ /* cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); */
+
+ if (!dvb_attach(dib7000p_attach, &dib7000p_ops))
+ return -ENODEV;
+
+ if (dib7000p_ops.i2c_enumeration(&i2c_bus->i2c_adap, 1, 0x12, &dib7070p_dib7000p_config) < 0) {
+ printk(KERN_WARNING "Unable to enumerate dib7000p\n");
+ return -ENODEV;
+ }
+ fe0->dvb.frontend = dib7000p_ops.init(&i2c_bus->i2c_adap, 0x80, &dib7070p_dib7000p_config);
+ if (fe0->dvb.frontend != NULL) {
+ struct i2c_adapter *tun_i2c;
+
+ fe0->dvb.frontend->sec_priv = kmalloc(sizeof(dib7000p_ops), GFP_KERNEL);
+ memcpy(fe0->dvb.frontend->sec_priv, &dib7000p_ops, sizeof(dib7000p_ops));
+ tun_i2c = dib7000p_ops.get_i2c_master(fe0->dvb.frontend, DIBX000_I2C_INTERFACE_TUNER, 1);
+ if (!dvb_attach(dib0070_attach, fe0->dvb.frontend, tun_i2c, &dib7070p_dib0070_config))
+ return -ENODEV;
+ }
+ break;
+ }
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
@@ -1331,13 +1471,34 @@ static int dvb_register(struct cx23885_tsport *port)
break;
case CX23885_BOARD_HAUPPAUGE_HVR4400:
i2c_bus = &dev->i2c_bus[0];
- fe0->dvb.frontend = dvb_attach(tda10071_attach,
+ i2c_bus2 = &dev->i2c_bus[1];
+ switch (port->nr) {
+ /* port b */
+ case 1:
+ fe0->dvb.frontend = dvb_attach(tda10071_attach,
&hauppauge_tda10071_config,
&i2c_bus->i2c_adap);
- if (fe0->dvb.frontend != NULL) {
- dvb_attach(a8293_attach, fe0->dvb.frontend,
- &i2c_bus->i2c_adap,
- &hauppauge_a8293_config);
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(a8293_attach, fe0->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ &hauppauge_a8293_config))
+ goto frontend_detach;
+ }
+ break;
+ /* port c */
+ case 2:
+ fe0->dvb.frontend = dvb_attach(si2165_attach,
+ &hauppauge_hvr4400_si2165_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL) {
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = 0;
+ if (!dvb_attach(tda18271_attach,
+ fe0->dvb.frontend,
+ 0x60, &i2c_bus2->i2c_adap,
+ &hauppauge_hvr4400_tuner_config))
+ goto frontend_detach;
+ }
+ break;
}
break;
default:
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 097d0a0b5f57..1940c18e186c 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -346,7 +346,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
}
rc->dev.parent = &dev->pci->dev;
rc->driver_type = driver_type;
- rc_set_allowed_protocols(rc, allowed_protos);
+ rc->allowed_protocols = allowed_protos;
rc->priv = kernel_ir;
rc->open = cx23885_input_ir_open;
rc->close = cx23885_input_ir_close;
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index e0a59523cf3c..91e4cb457296 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -507,6 +507,7 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) ||
(dev->board == CX23885_BOARD_MPX885) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) ||
+ (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
@@ -1156,7 +1157,7 @@ static int vidioc_querycap(struct file *file, void *priv,
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE;
- if (UNSET != dev->tuner_type)
+ if (dev->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
@@ -1474,7 +1475,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- if (unlikely(UNSET == dev->tuner_type))
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
@@ -1490,7 +1491,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
- if (UNSET == dev->tuner_type)
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
@@ -1506,7 +1507,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct cx23885_fh *fh = priv;
struct cx23885_dev *dev = fh->dev;
- if (unlikely(UNSET == dev->tuner_type))
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
/* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
@@ -1522,7 +1523,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, const struct v4l2_frequency
{
struct v4l2_control ctrl;
- if (unlikely(UNSET == dev->tuner_type))
+ if (dev->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (unlikely(f->tuner != 0))
return -EINVAL;
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 0fa4048ab872..0e086c03da67 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -96,6 +96,8 @@
#define CX23885_BOARD_TBS_6981 40
#define CX23885_BOARD_TBS_6980 41
#define CX23885_BOARD_LEADTEK_WINFAST_PXPVR2200 42
+#define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43
+#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index d270819fd875..3a419f134584 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -576,7 +576,6 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3;
f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -615,7 +614,6 @@ static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -867,7 +865,6 @@ static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv,
f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1109,7 +1106,6 @@ int cx25821_video_register(struct cx25821_dev *dev)
else
vdev->vfl_dir = VFL_DIR_TX;
vdev->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
video_set_drvdata(vdev, chan);
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index e061c88b697e..71630238027b 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1045,7 +1045,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
core->name, type, core->board.name);
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
return vfd;
}
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c
index f991696a6c59..3f1342c98b46 100644
--- a/drivers/media/pci/cx88/cx88-input.c
+++ b/drivers/media/pci/cx88/cx88-input.c
@@ -130,25 +130,41 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
data = (data << 4) | ((gpio_key & 0xf0) >> 4);
- rc_keydown(ir->dev, data, 0);
+ rc_keydown(ir->dev, RC_TYPE_UNKNOWN, data, 0);
+
+ } else if (ir->core->boardnr == CX88_BOARD_PROLINK_PLAYTVPVR ||
+ ir->core->boardnr == CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO) {
+ /* bit cleared on keydown, NEC scancode, 0xAAAACC, A = 0x866b */
+ u16 addr;
+ u8 cmd;
+ u32 scancode;
+
+ addr = (data >> 8) & 0xffff;
+ cmd = (data >> 0) & 0x00ff;
+ scancode = RC_SCANCODE_NECX(addr, cmd);
+
+ if (0 == (gpio & ir->mask_keyup))
+ rc_keydown_notimeout(ir->dev, RC_TYPE_NEC, scancode, 0);
+ else
+ rc_keyup(ir->dev);
} else if (ir->mask_keydown) {
/* bit set on keydown */
if (gpio & ir->mask_keydown)
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
else
rc_keyup(ir->dev);
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
if (0 == (gpio & ir->mask_keyup))
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
else
rc_keyup(ir->dev);
} else {
/* can't distinguish keydown/up :-/ */
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
rc_keyup(ir->dev);
}
}
@@ -329,6 +345,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
* 002-T mini RC, provided with newer PV hardware
*/
ir_codes = RC_MAP_PIXELVIEW_MK12;
+ rc_type = RC_BIT_NEC;
ir->gpio_addr = MO_GP1_IO;
ir->mask_keyup = 0x80;
ir->polling = 10; /* ms */
@@ -416,7 +433,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_TWINHAN_VP1027_DVBS:
ir_codes = RC_MAP_TWINHAN_VP1027_DVBS;
- rc_type = RC_BIT_NEC;
ir->sampling = 0xff00; /* address */
break;
}
@@ -462,14 +478,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
dev->priv = core;
dev->open = cx88_ir_open;
dev->close = cx88_ir_close;
- dev->scanmask = hardware_mask;
+ dev->scancode_mask = hardware_mask;
if (ir->sampling) {
dev->driver_type = RC_DRIVER_IR_RAW;
dev->timeout = 10 * 1000 * 1000; /* 10 ms */
} else {
dev->driver_type = RC_DRIVER_SCANCODE;
- rc_set_allowed_protocols(dev, rc_type);
+ dev->allowed_protocols = rc_type;
}
ir->core = core;
@@ -539,7 +555,8 @@ void cx88_ir_irq(struct cx88_core *core)
ir_raw_event_handle(ir->dev);
}
-static int get_key_pvr2000(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pvr2000(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
int flags, code;
@@ -563,8 +580,9 @@ static int get_key_pvr2000(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
dprintk("IR Key/Flags: (0x%02x/0x%02x)\n",
code & 0xff, flags & 0xff);
- *ir_key = code & 0xff;
- *ir_raw = code;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = code & 0xff;
+ *toggle = 0;
return 1;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index fb52bda8d45f..da8f848be3b8 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -1663,11 +1663,40 @@ static struct ddb_info ddb_octopus_le = {
.port_num = 2,
};
+static struct ddb_info ddb_octopus_mini = {
+ .type = DDB_OCTOPUS,
+ .name = "Digital Devices Octopus Mini",
+ .port_num = 4,
+};
+
static struct ddb_info ddb_v6 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6 DVB adapter",
.port_num = 3,
};
+static struct ddb_info ddb_v6_5 = {
+ .type = DDB_OCTOPUS,
+ .name = "Digital Devices Cine S2 V6.5 DVB adapter",
+ .port_num = 4,
+};
+
+static struct ddb_info ddb_dvbct = {
+ .type = DDB_OCTOPUS,
+ .name = "Digital Devices DVBCT V6.1 DVB adapter",
+ .port_num = 3,
+};
+
+static struct ddb_info ddb_satixS2v3 = {
+ .type = DDB_OCTOPUS,
+ .name = "Mystique SaTiX-S2 V3 DVB adapter",
+ .port_num = 3,
+};
+
+static struct ddb_info ddb_octopusv3 = {
+ .type = DDB_OCTOPUS,
+ .name = "Digital Devices Octopus V3 DVB adapter",
+ .port_num = 4,
+};
#define DDVID 0xdd01 /* Digital Devices Vendor ID */
@@ -1680,8 +1709,12 @@ static const struct pci_device_id ddb_id_tbl[] = {
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
- DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus),
+ DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini),
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
+ DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
+ DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
+ DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
+ DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3),
/* in case sub-ids got deleted in flash */
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
{0}
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index e60ac35fc10c..e8826c535ccd 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -678,7 +678,8 @@ static void dm1105_emit_key(struct work_struct *work)
data = (ircom >> 8) & 0x7f;
- rc_keydown(ir->dev, data, 0);
+ /* FIXME: UNKNOWN because we don't generate a full NEC scancode (yet?) */
+ rc_keydown(ir->dev, RC_TYPE_UNKNOWN, data, 0);
}
/* work handler */
diff --git a/drivers/media/pci/ivtv/ivtv-controls.c b/drivers/media/pci/ivtv/ivtv-controls.c
index c60424601cb9..2b0ab26e11e8 100644
--- a/drivers/media/pci/ivtv/ivtv-controls.c
+++ b/drivers/media/pci/ivtv/ivtv-controls.c
@@ -135,8 +135,8 @@ static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
/* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
control cluster */
case V4L2_CID_MPEG_VIDEO_DEC_PTS:
- return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
- &itv->ctrl_frame->val64);
+ return ivtv_g_pts_frame(itv, itv->ctrl_pts->p_new.p_s64,
+ itv->ctrl_frame->p_new.p_s64);
}
return 0;
}
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index ceed2d87abfd..1a41ba5c7d30 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
@@ -148,7 +148,8 @@ static const char * const hw_devicenames[] = {
"ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */
};
-static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_adaptec(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char keybuf[4];
@@ -167,9 +168,9 @@ static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
keybuf[2] &= 0x7f;
keybuf[3] |= 0x80;
- *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
- *ir_raw = *ir_key;
-
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
+ *toggle = 0;
return 1;
}
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index b3667a00db3a..3e0cb77d5930 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -351,7 +351,6 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pixfmt->height = itv->cxhdl.height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
/* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
@@ -418,7 +417,6 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
pixfmt->height = itv->main_rect.height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
case IVTV_YUV_MODE_INTERLACED:
@@ -1384,7 +1382,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
fb->fmt.bytesperline = fb->fmt.width;
fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->fmt.priv = 0;
if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
fb->fmt.bytesperline *= 2;
if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
diff --git a/drivers/media/pci/ivtv/ivtv-streams.c b/drivers/media/pci/ivtv/ivtv-streams.c
index 70dad588a677..f0a1cc472313 100644
--- a/drivers/media/pci/ivtv/ivtv-streams.c
+++ b/drivers/media/pci/ivtv/ivtv-streams.c
@@ -251,7 +251,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
v4l2_disable_ioctl(s->vdev, VIDIOC_G_TUNER);
v4l2_disable_ioctl(s->vdev, VIDIOC_S_STD);
}
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
ivtv_set_funcs(s->vdev);
return 0;
}
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index 54d5c821007c..aeae54708811 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1166,7 +1166,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
f->fmt.pix.sizeimage = f->fmt.pix.height *
f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1232,7 +1231,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
f->fmt.pix.sizeimage = f->fmt.pix.height *
f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1749,7 +1747,6 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
v4l2_ctrl_handler_setup(&meye.hdl);
meye.vdev->ctrl_handler = &meye.hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &meye.vdev->flags);
if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
video_nr) < 0) {
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index 970e83308525..826228c3800e 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -910,7 +910,6 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev,
{
dma_addr_t tmp;
u32 i, j;
- int status = 0;
u32 SCListMemSize = pRingBuffer->NumBuffers
* ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) :
NUM_SCATTER_GATHER_ENTRIES)
@@ -1010,14 +1009,12 @@ static int AllocateRingBuffers(struct pci_dev *pci_dev,
}
- return status;
+ return 0;
}
static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
struct SRingBufferDescriptor *pRingBuffer)
{
- int status = 0;
-
/* Copy pointer to scatter gather list in TSRingbuffer
structure for buffer 2
Load number of buffer
@@ -1038,7 +1035,7 @@ static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer,
pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1;
Cur = Cur->Next;
}
- return status;
+ return 0;
}
static u32 RingBufferSizes[MAX_STREAM] = {
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index be19a051a492..9ff03a69ced4 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -811,7 +811,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, saa7134_boards[dev->board].name);
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
video_set_drvdata(vfd, dev);
return vfd;
}
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index e65c760e4e8b..e4ea85fd1b23 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -130,7 +130,6 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -148,7 +147,6 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -166,7 +164,6 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -179,7 +176,7 @@ static const struct v4l2_file_operations ts_fops =
.read = vb2_fop_read,
.poll = vb2_fop_poll,
.mmap = vb2_fop_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops ts_ioctl_ops = {
@@ -270,7 +267,6 @@ static int empress_init(struct saa7134_dev *dev)
snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
"%s empress (%s)", dev->name,
saa7134_boards[dev->board].name);
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->empress_dev->flags);
v4l2_ctrl_handler_init(hdl, 21);
v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
if (dev->empress_sd)
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 6f4312663bdf..dc3d6516edf7 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -83,14 +83,14 @@ static int build_key(struct saa7134_dev *dev)
if (data == ir->mask_keycode)
rc_keyup(ir->dev);
else
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
return 0;
}
if (ir->polling) {
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
} else {
rc_keyup(ir->dev);
}
@@ -98,7 +98,7 @@ static int build_key(struct saa7134_dev *dev)
else { /* IRQ driven mode - handle key press and release in one go */
if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
(ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
- rc_keydown_notimeout(ir->dev, data, 0);
+ rc_keydown_notimeout(ir->dev, RC_TYPE_UNKNOWN, data, 0);
rc_keyup(ir->dev);
}
}
@@ -108,7 +108,8 @@ static int build_key(struct saa7134_dev *dev)
/* --------------------- Chip specific I2C key builders ----------------- */
-static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
int gpio;
int attempt = 0;
@@ -132,10 +133,6 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (0x40000 & ~gpio)
return 0; /* No button press */
- /* No button press - only before first key pressed */
- if (b == 0xFF)
- return 0;
-
/* poll IR chip */
/* weak up the IR chip */
b = 0;
@@ -158,13 +155,14 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return -EIO;
}
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
-static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
+static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
int gpio;
@@ -205,14 +203,15 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
/* Button pressed */
dprintk("get_key_msi_tvanywhere_plus: Key = 0x%02X\n", b);
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
/* copied and modified from get_key_msi_tvanywhere_plus() */
-static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
+static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
unsigned int gpio;
@@ -253,12 +252,14 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key,
/* Button pressed */
dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b);
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
-static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_purpletv(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char b;
@@ -276,12 +277,14 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (b & 0x80)
return 1;
- *ir_key = b;
- *ir_raw = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
+ *toggle = 0;
return 1;
}
-static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_hvr1110(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char buf[5];
@@ -299,14 +302,20 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
* by preserving it into two separate readings
* buf[4] bits 0 and 1, and buf[1] and buf[2] are always
* zero.
+ *
+ * Note that the keymap which the hvr1110 uses is RC5.
+ *
+ * FIXME: start bits could maybe be used...?
*/
- *ir_key = 0x1fff & ((buf[3] << 8) | (buf[4] >> 2));
- *ir_raw = *ir_key;
+ *protocol = RC_TYPE_RC5;
+ *scancode = RC_SCANCODE_RC5(buf[3] & 0x1f, buf[4] >> 2);
+ *toggle = !!(buf[3] & 0x40);
return 1;
}
-static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
unsigned char data[12];
u32 gpio;
@@ -332,17 +341,18 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (data[9] != (unsigned char)(~data[8]))
return 0;
- *ir_raw = ((data[10] << 16) | (data[11] << 8) | (data[9] << 0));
- *ir_key = *ir_raw;
-
+ *protocol = RC_TYPE_NEC;
+ *scancode = RC_SCANCODE_NECX(data[11] << 8 | data[10], data[9]);
+ *toggle = 0;
return 1;
}
/* Common (grey or coloured) pinnacle PCTV remote handling
*
*/
-static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
- int parity_offset, int marker, int code_modulo)
+static int get_key_pinnacle(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle, int parity_offset,
+ int marker, int code_modulo)
{
unsigned char b[4];
unsigned int start = 0,parity = 0,code = 0;
@@ -377,11 +387,11 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
code %= code_modulo;
- *ir_raw = code;
- *ir_key = code;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = code;
+ *toggle = 0;
i2cdprintk("Pinnacle PCTV key %02x\n", code);
-
return 1;
}
@@ -394,10 +404,11 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
*
* Sylvain Pasche <sylvain.pasche@gmail.com>
*/
-static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pinnacle_grey(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
- return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
+ return get_key_pinnacle(ir, protocol, scancode, toggle, 1, 0xfe, 0xff);
}
@@ -405,7 +416,8 @@ static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
*
* Ricardo Cerqueira <v4l@cerqueira.org>
*/
-static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_pinnacle_color(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *scancode, u8 *toggle)
{
/* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
*
@@ -413,7 +425,7 @@ static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
* codes < 128
*/
- return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
+ return get_key_pinnacle(ir, protocol, scancode, toggle, 2, 0x80, 0x88);
}
void saa7134_input_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index d37599980768..0cfa2ca6a32a 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1235,7 +1235,6 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1315,7 +1314,6 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c
index 5c5cc3ebf9bd..16ae71592e8c 100644
--- a/drivers/media/pci/saa7164/saa7164-dvb.c
+++ b/drivers/media/pci/saa7164/saa7164-dvb.c
@@ -242,16 +242,14 @@ static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (dvb->feeding++ == 0) {
- /* Start transport */
- ret = saa7164_dvb_start_port(port);
- }
- mutex_unlock(&dvb->lock);
- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
- __func__, port->nr, dvb->feeding);
+ mutex_lock(&dvb->lock);
+ if (dvb->feeding++ == 0) {
+ /* Start transport */
+ ret = saa7164_dvb_start_port(port);
}
+ mutex_unlock(&dvb->lock);
+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+ __func__, port->nr, dvb->feeding);
return ret;
}
@@ -266,16 +264,14 @@ static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
- if (dvb) {
- mutex_lock(&dvb->lock);
- if (--dvb->feeding == 0) {
- /* Stop transport */
- ret = saa7164_dvb_stop_streaming(port);
- }
- mutex_unlock(&dvb->lock);
- dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
- __func__, port->nr, dvb->feeding);
+ mutex_lock(&dvb->lock);
+ if (--dvb->feeding == 0) {
+ /* Stop transport */
+ ret = saa7164_dvb_stop_streaming(port);
}
+ mutex_unlock(&dvb->lock);
+ dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+ __func__, port->nr, dvb->feeding);
return ret;
}
diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/media/pci/solo6x10/Kconfig
index 6a1906fa1117..d9e06a6bf1eb 100644
--- a/drivers/staging/media/solo6x10/Kconfig
+++ b/drivers/media/pci/solo6x10/Kconfig
@@ -1,6 +1,7 @@
-config SOLO6X10
+config VIDEO_SOLO6X10
tristate "Bluecherry / Softlogic 6x10 capture cards (MPEG-4/H.264)"
depends on PCI && VIDEO_DEV && SND && I2C
+ select BITREVERSE
select FONT_SUPPORT
select FONT_8x16
select VIDEOBUF2_DMA_SG
diff --git a/drivers/staging/media/solo6x10/Makefile b/drivers/media/pci/solo6x10/Makefile
index 7aae118947b2..f4742266ef7c 100644
--- a/drivers/staging/media/solo6x10/Makefile
+++ b/drivers/media/pci/solo6x10/Makefile
@@ -2,4 +2,4 @@ solo6x10-y := solo6x10-core.o solo6x10-i2c.o solo6x10-p2m.o solo6x10-v4l2.o \
solo6x10-tw28.o solo6x10-gpio.o solo6x10-disp.o solo6x10-enc.o \
solo6x10-v4l2-enc.o solo6x10-g723.o solo6x10-eeprom.o
-obj-$(CONFIG_SOLO6X10) += solo6x10.o
+obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10.o
diff --git a/drivers/staging/media/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
index f67046955ef6..172583d736fe 100644
--- a/drivers/staging/media/solo6x10/solo6x10-core.c
+++ b/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
@@ -307,8 +303,8 @@ static ssize_t p2m_timeout_store(struct device *dev,
struct solo_dev *solo_dev =
container_of(dev, struct solo_dev, dev);
unsigned long ms;
-
int ret = kstrtoul(buf, 10, &ms);
+
if (ret < 0 || ms > 200)
return -EINVAL;
solo_dev->p2m_jiffies = msecs_to_jiffies(ms);
diff --git a/drivers/staging/media/solo6x10/solo6x10-disp.c b/drivers/media/pci/solo6x10/solo6x10-disp.c
index 145295a5db72..5ea9cac03968 100644
--- a/drivers/staging/media/solo6x10/solo6x10-disp.c
+++ b/drivers/media/pci/solo6x10/solo6x10-disp.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
@@ -211,21 +207,25 @@ int solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val)
}
int solo_set_motion_block(struct solo_dev *solo_dev, u8 ch,
- const struct solo_motion_thresholds *thresholds)
+ const u16 *thresholds)
{
+ const unsigned size = sizeof(u16) * 64;
u32 off = SOLO_MOT_FLAG_AREA + ch * SOLO_MOT_THRESH_SIZE * 2;
- u16 buf[64];
+ u16 *buf;
int x, y;
int ret = 0;
- memset(buf, 0, sizeof(buf));
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
for (y = 0; y < SOLO_MOTION_SZ; y++) {
for (x = 0; x < SOLO_MOTION_SZ; x++)
- buf[x] = cpu_to_le16(thresholds->thresholds[y][x]);
+ buf[x] = cpu_to_le16(thresholds[y * SOLO_MOTION_SZ + x]);
ret |= solo_p2m_dma(solo_dev, 1, buf,
- SOLO_MOTION_EXT_ADDR(solo_dev) + off + y * sizeof(buf),
- sizeof(buf), 0, 0);
+ SOLO_MOTION_EXT_ADDR(solo_dev) + off + y * size,
+ size, 0, 0);
}
+ kfree(buf);
return ret;
}
diff --git a/drivers/staging/media/solo6x10/solo6x10-eeprom.c b/drivers/media/pci/solo6x10/solo6x10-eeprom.c
index 9d1c9bb53d6b..af40b3aba410 100644
--- a/drivers/staging/media/solo6x10/solo6x10-eeprom.c
+++ b/drivers/media/pci/solo6x10/solo6x10-eeprom.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/media/solo6x10/solo6x10-enc.c b/drivers/media/pci/solo6x10/solo6x10-enc.c
index 2db53b68c62f..d19c0aef5abc 100644
--- a/drivers/staging/media/solo6x10/solo6x10-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-enc.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/media/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c
index 74f037b6166c..c7141f2e63bd 100644
--- a/drivers/staging/media/solo6x10/solo6x10-g723.c
+++ b/drivers/media/pci/solo6x10/solo6x10-g723.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/media/solo6x10/solo6x10-gpio.c b/drivers/media/pci/solo6x10/solo6x10-gpio.c
index 73276dc92875..6d3b4a36bc11 100644
--- a/drivers/staging/media/solo6x10/solo6x10-gpio.c
+++ b/drivers/media/pci/solo6x10/solo6x10-gpio.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/media/solo6x10/solo6x10-i2c.c b/drivers/media/pci/solo6x10/solo6x10-i2c.c
index 01aa417c9258..c908672b2c40 100644
--- a/drivers/staging/media/solo6x10/solo6x10-i2c.c
+++ b/drivers/media/pci/solo6x10/solo6x10-i2c.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* XXX: The SOLO6x10 i2c does not have separate interrupts for each i2c
diff --git a/drivers/staging/media/solo6x10/solo6x10-jpeg.h b/drivers/media/pci/solo6x10/solo6x10-jpeg.h
index c5218ceeabca..1c66a46da514 100644
--- a/drivers/staging/media/solo6x10/solo6x10-jpeg.h
+++ b/drivers/media/pci/solo6x10/solo6x10-jpeg.h
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SOLO6X10_JPEG_H
@@ -110,7 +106,7 @@ static const unsigned char jpeg_header[] = {
/* This is the byte marker for the start of the DQT */
#define DQT_START 17
#define DQT_LEN 138
-const unsigned char jpeg_dqt[4][DQT_LEN] = {
+static const unsigned char jpeg_dqt[4][DQT_LEN] = {
{
0xff, 0xdb, 0x00, 0x43, 0x00,
0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07,
diff --git a/drivers/staging/media/solo6x10/solo6x10-offsets.h b/drivers/media/pci/solo6x10/solo6x10-offsets.h
index 13eeb4470dcf..d6aea7c2a676 100644
--- a/drivers/staging/media/solo6x10/solo6x10-offsets.h
+++ b/drivers/media/pci/solo6x10/solo6x10-offsets.h
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SOLO6X10_OFFSETS_H
diff --git a/drivers/staging/media/solo6x10/solo6x10-p2m.c b/drivers/media/pci/solo6x10/solo6x10-p2m.c
index 7f2f2472655b..8c8484674d2f 100644
--- a/drivers/staging/media/solo6x10/solo6x10-p2m.c
+++ b/drivers/media/pci/solo6x10/solo6x10-p2m.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/staging/media/solo6x10/solo6x10-regs.h b/drivers/media/pci/solo6x10/solo6x10-regs.h
index 428f6c951180..e34ac56ab101 100644
--- a/drivers/staging/media/solo6x10/solo6x10-regs.h
+++ b/drivers/media/pci/solo6x10/solo6x10-regs.h
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SOLO6X10_REGISTERS_H
diff --git a/drivers/staging/media/solo6x10/solo6x10-tw28.c b/drivers/media/pci/solo6x10/solo6x10-tw28.c
index 36daa1720b54..edd0781ee4b5 100644
--- a/drivers/staging/media/solo6x10/solo6x10-tw28.c
+++ b/drivers/media/pci/solo6x10/solo6x10-tw28.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
@@ -214,6 +210,7 @@ static void tw_write_and_verify(struct solo_dev *solo_dev, u8 addr, u8 off,
for (i = 0; i < 5; i++) {
u8 rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, addr, off);
+
if (rval == val)
return;
diff --git a/drivers/staging/media/solo6x10/solo6x10-tw28.h b/drivers/media/pci/solo6x10/solo6x10-tw28.h
index 1a02c87d4cf0..0966b45057a3 100644
--- a/drivers/staging/media/solo6x10/solo6x10-tw28.h
+++ b/drivers/media/pci/solo6x10/solo6x10-tw28.h
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SOLO6X10_TW28_H
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index b8ff113c20f4..28023f9f1dc7 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
@@ -243,6 +239,8 @@ static int solo_enc_on(struct solo_enc_dev *solo_enc)
if (solo_enc->bw_weight > solo_dev->enc_bw_remain)
return -EBUSY;
solo_enc->sequence = 0;
+ solo_enc->motion_last_state = false;
+ solo_enc->frames_since_last_motion = 0;
solo_dev->enc_bw_remain -= solo_enc->bw_weight;
if (solo_enc->type == SOLO_ENC_TYPE_EXT)
@@ -476,8 +474,9 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len);
/* may discard all previous data in vbuf->sgl */
- dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
- DMA_FROM_DEVICE);
+ if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
+ DMA_FROM_DEVICE))
+ return -ENOMEM;
ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf,
vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev),
frame_size, SOLO_JPEG_EXT_ADDR(solo_dev),
@@ -523,8 +522,9 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN);
/* may discard all previous data in vbuf->sgl */
- dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
- DMA_FROM_DEVICE);
+ if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
+ DMA_FROM_DEVICE))
+ return -ENOMEM;
ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
SOLO_MP4E_EXT_ADDR(solo_dev),
SOLO_MP4E_EXT_SIZE(solo_dev));
@@ -544,15 +544,6 @@ static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
const vop_header *vh = enc_buf->vh;
int ret;
- /* Check for motion flags */
- vb->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_MOTION_ON |
- V4L2_BUF_FLAG_MOTION_DETECTED);
- if (solo_is_motion_on(solo_enc)) {
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_MOTION_ON;
- if (enc_buf->motion)
- vb->v4l2_buf.flags |= V4L2_BUF_FLAG_MOTION_DETECTED;
- }
-
switch (solo_enc->fmt) {
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_H264:
@@ -564,9 +555,49 @@ static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
}
if (!ret) {
+ bool send_event = false;
+
vb->v4l2_buf.sequence = solo_enc->sequence++;
vb->v4l2_buf.timestamp.tv_sec = vop_sec(vh);
vb->v4l2_buf.timestamp.tv_usec = vop_usec(vh);
+
+ /* Check for motion flags */
+ if (solo_is_motion_on(solo_enc)) {
+ /* It takes a few frames for the hardware to detect
+ * motion. Once it does it clears the motion detection
+ * register and it takes again a few frames before
+ * motion is seen. This means in practice that when the
+ * motion field is 1, it will go back to 0 for the next
+ * frame. This leads to motion detection event being
+ * sent all the time, which is not what we want.
+ * Instead wait a few frames before deciding that the
+ * motion has halted. After some experimentation it
+ * turns out that waiting for 5 frames works well.
+ */
+ if (enc_buf->motion == 0 &&
+ solo_enc->motion_last_state &&
+ solo_enc->frames_since_last_motion++ > 5)
+ send_event = true;
+ else if (enc_buf->motion) {
+ solo_enc->frames_since_last_motion = 0;
+ send_event = !solo_enc->motion_last_state;
+ }
+ }
+
+ if (send_event) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_MOTION_DET,
+ .u.motion_det = {
+ .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
+ .frame_sequence = vb->v4l2_buf.sequence,
+ .region_mask = enc_buf->motion ? 1 : 0,
+ },
+ };
+
+ solo_enc->motion_last_state = enc_buf->motion;
+ solo_enc->frames_since_last_motion = 0;
+ v4l2_event_queue(solo_enc->vfd, &ev);
+ }
}
vb2_buffer_done(vb, ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
@@ -669,6 +700,7 @@ static int solo_ring_thread(void *data)
for (;;) {
long timeout = schedule_timeout_interruptible(HZ);
+
if (timeout == -ERESTARTSYS || kthread_should_stop())
break;
solo_irq_off(solo_dev, SOLO_IRQ_ENCODER);
@@ -715,6 +747,7 @@ static int solo_ring_start(struct solo_dev *solo_dev)
SOLO6X10_NAME "_ring");
if (IS_ERR(solo_dev->ring_thread)) {
int err = PTR_ERR(solo_dev->ring_thread);
+
solo_dev->ring_thread = NULL;
return err;
}
@@ -1068,31 +1101,6 @@ static int solo_s_parm(struct file *file, void *priv,
return solo_g_parm(file, priv, sp);
}
-static long solo_enc_default(struct file *file, void *fh,
- bool valid_prio, unsigned int cmd, void *arg)
-{
- struct solo_enc_dev *solo_enc = video_drvdata(file);
- struct solo_dev *solo_dev = solo_enc->solo_dev;
- struct solo_motion_thresholds *thresholds = arg;
-
- switch (cmd) {
- case SOLO_IOC_G_MOTION_THRESHOLDS:
- *thresholds = solo_enc->motion_thresholds;
- return 0;
-
- case SOLO_IOC_S_MOTION_THRESHOLDS:
- if (!valid_prio)
- return -EBUSY;
- solo_enc->motion_thresholds = *thresholds;
- if (solo_enc->motion_enabled && !solo_enc->motion_global)
- return solo_set_motion_block(solo_dev, solo_enc->ch,
- &solo_enc->motion_thresholds);
- return 0;
- default:
- return -ENOTTY;
- }
-}
-
static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct solo_enc_dev *solo_enc =
@@ -1110,30 +1118,43 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->val);
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
solo_enc->gop = ctrl->val;
+ solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch), solo_enc->gop);
+ solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch), solo_enc->gop);
return 0;
- case V4L2_CID_MOTION_THRESHOLD:
- solo_enc->motion_thresh = ctrl->val;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ solo_enc->qp = ctrl->val;
+ solo_reg_write(solo_dev, SOLO_VE_CH_QP(solo_enc->ch), solo_enc->qp);
+ solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(solo_enc->ch), solo_enc->qp);
+ return 0;
+ case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD:
+ solo_enc->motion_thresh = ctrl->val << 8;
if (!solo_enc->motion_global || !solo_enc->motion_enabled)
return 0;
return solo_set_motion_threshold(solo_dev, solo_enc->ch,
- ctrl->val);
- case V4L2_CID_MOTION_MODE:
- solo_enc->motion_global = ctrl->val == 1;
- solo_enc->motion_enabled = ctrl->val > 0;
+ solo_enc->motion_thresh);
+ case V4L2_CID_DETECT_MD_MODE:
+ solo_enc->motion_global = ctrl->val == V4L2_DETECT_MD_MODE_GLOBAL;
+ solo_enc->motion_enabled = ctrl->val > V4L2_DETECT_MD_MODE_DISABLED;
if (ctrl->val) {
if (solo_enc->motion_global)
- solo_set_motion_threshold(solo_dev,
- solo_enc->ch, solo_enc->motion_thresh);
+ err = solo_set_motion_threshold(solo_dev, solo_enc->ch,
+ solo_enc->motion_thresh);
else
- solo_set_motion_block(solo_dev, solo_enc->ch,
- &solo_enc->motion_thresholds);
+ err = solo_set_motion_block(solo_dev, solo_enc->ch,
+ solo_enc->md_thresholds->p_cur.p_u16);
+ if (err)
+ return err;
}
solo_motion_toggle(solo_enc, ctrl->val);
return 0;
+ case V4L2_CID_DETECT_MD_THRESHOLD_GRID:
+ if (solo_enc->motion_enabled && !solo_enc->motion_global)
+ return solo_set_motion_block(solo_dev, solo_enc->ch,
+ solo_enc->md_thresholds->p_new.p_u16);
+ break;
case V4L2_CID_OSD_TEXT:
- strcpy(solo_enc->osd_text, ctrl->string);
- err = solo_osd_print(solo_enc);
- return err;
+ strcpy(solo_enc->osd_text, ctrl->p_new.p_char);
+ return solo_osd_print(solo_enc);
default:
return -EINVAL;
}
@@ -1141,6 +1162,21 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
+static int solo_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+
+ switch (sub->type) {
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ case V4L2_EVENT_MOTION_DET:
+ /* Allow for up to 30 events (1 second for NTSC) to be
+ * stored. */
+ return v4l2_event_subscribe(fh, sub, 30, NULL);
+ }
+ return -EINVAL;
+}
+
static const struct v4l2_file_operations solo_enc_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -1179,9 +1215,8 @@ static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = {
.vidioc_g_parm = solo_g_parm,
/* Logging and events */
.vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_subscribe_event = solo_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_default = solo_enc_default,
};
static const struct video_device solo_enc_template = {
@@ -1197,33 +1232,6 @@ static const struct v4l2_ctrl_ops solo_ctrl_ops = {
.s_ctrl = solo_s_ctrl,
};
-static const struct v4l2_ctrl_config solo_motion_threshold_ctrl = {
- .ops = &solo_ctrl_ops,
- .id = V4L2_CID_MOTION_THRESHOLD,
- .name = "Motion Detection Threshold",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .max = 0xffff,
- .def = SOLO_DEF_MOT_THRESH,
- .step = 1,
- .flags = V4L2_CTRL_FLAG_SLIDER,
-};
-
-static const char * const solo_motion_mode_menu[] = {
- "Disabled",
- "Global Threshold",
- "Regional Threshold",
- NULL
-};
-
-static const struct v4l2_ctrl_config solo_motion_enable_ctrl = {
- .ops = &solo_ctrl_ops,
- .id = V4L2_CID_MOTION_MODE,
- .name = "Motion Detection Mode",
- .type = V4L2_CTRL_TYPE_MENU,
- .qmenu = solo_motion_mode_menu,
- .max = 2,
-};
-
static const struct v4l2_ctrl_config solo_osd_text_ctrl = {
.ops = &solo_ctrl_ops,
.id = V4L2_CID_OSD_TEXT,
@@ -1233,13 +1241,22 @@ static const struct v4l2_ctrl_config solo_osd_text_ctrl = {
.step = 1,
};
+/* Motion Detection Threshold matrix */
+static const struct v4l2_ctrl_config solo_md_thresholds = {
+ .ops = &solo_ctrl_ops,
+ .id = V4L2_CID_DETECT_MD_THRESHOLD_GRID,
+ .dims = { SOLO_MOTION_SZ, SOLO_MOTION_SZ },
+ .def = SOLO_DEF_MOT_THRESH,
+ .max = 65535,
+ .step = 1,
+};
+
static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
u8 ch, unsigned nr)
{
struct solo_enc_dev *solo_enc;
struct v4l2_ctrl_handler *hdl;
int ret;
- int x, y;
solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL);
if (!solo_enc)
@@ -1260,9 +1277,18 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
V4L2_CID_SHARPNESS, 0, 15, 1, 0);
v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 255, 1, solo_dev->fps);
- v4l2_ctrl_new_custom(hdl, &solo_motion_threshold_ctrl, NULL);
- v4l2_ctrl_new_custom(hdl, &solo_motion_enable_ctrl, NULL);
+ v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 0, 31, 1, SOLO_DEFAULT_QP);
+ v4l2_ctrl_new_std_menu(hdl, &solo_ctrl_ops,
+ V4L2_CID_DETECT_MD_MODE,
+ V4L2_DETECT_MD_MODE_THRESHOLD_GRID, 0,
+ V4L2_DETECT_MD_MODE_DISABLED);
+ v4l2_ctrl_new_std(hdl, &solo_ctrl_ops,
+ V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD, 0, 0xff, 1,
+ SOLO_DEF_MOT_THRESH >> 8);
v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL);
+ solo_enc->md_thresholds =
+ v4l2_ctrl_new_custom(hdl, &solo_md_thresholds, NULL);
if (hdl->error) {
ret = hdl->error;
goto hdl_free;
@@ -1283,11 +1309,6 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
solo_enc->mode = SOLO_ENC_MODE_CIF;
solo_enc->motion_global = true;
solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
- for (y = 0; y < SOLO_MOTION_SZ; y++)
- for (x = 0; x < SOLO_MOTION_SZ; x++)
- solo_enc->motion_thresholds.thresholds[y][x] =
- SOLO_DEF_MOT_THRESH;
-
solo_enc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
solo_enc->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
solo_enc->vidq.ops = &solo_enc_video_qops;
@@ -1326,7 +1347,6 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev,
solo_enc->vfd->ctrl_handler = hdl;
solo_enc->vfd->queue = &solo_enc->vidq;
solo_enc->vfd->lock = &solo_enc->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags);
video_set_drvdata(solo_enc->vfd, solo_enc);
ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr);
if (ret < 0)
@@ -1381,6 +1401,7 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
if (i != solo_dev->nr_chans) {
int ret = PTR_ERR(solo_dev->v4l2_enc[i]);
+
while (i--)
solo_enc_free(solo_dev->v4l2_enc[i]);
pci_free_consistent(solo_dev->pdev, solo_dev->vh_size,
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
index 5d0100eb38e6..63ae8a61f603 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
@@ -98,6 +94,7 @@ static int solo_v4l2_ch_ext_4up(struct solo_dev *solo_dev, u8 idx, int on)
if (!on) {
u8 i;
+
for (i = ch; i < ch + 4; i++)
solo_win_setup(solo_dev, i, solo_dev->video_hsize,
solo_vlines(solo_dev),
@@ -206,6 +203,7 @@ static void solo_fillbuf(struct solo_dev *solo_dev,
if (erase_off(solo_dev)) {
void *p = vb2_plane_vaddr(vb, 0);
int image_size = solo_image_size(solo_dev);
+
for (i = 0; i < image_size; i += 2) {
((u8 *)p)[i] = 0x80;
((u8 *)p)[i + 1] = 0x00;
@@ -275,6 +273,7 @@ static int solo_thread(void *data)
for (;;) {
long timeout = schedule_timeout_interruptible(HZ);
+
if (timeout == -ERESTARTSYS || kthread_should_stop())
break;
solo_thread_try(solo_dev);
@@ -414,6 +413,7 @@ static int solo_enum_input(struct file *file, void *priv,
if (input->index >= solo_dev->nr_chans) {
int ret = solo_enum_ext_input(solo_dev, input);
+
if (ret < 0)
return ret;
} else {
@@ -666,7 +666,6 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
goto fail;
}
solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &solo_dev->vfd->flags);
video_set_drvdata(solo_dev->vfd, solo_dev);
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h
index 8964f8be158e..c6154b00fcbd 100644
--- a/drivers/staging/media/solo6x10/solo6x10.h
+++ b/drivers/media/pci/solo6x10/solo6x10.h
@@ -16,10 +16,6 @@
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __SOLO6X10_H
@@ -96,14 +92,7 @@
#define SOLO_DEFAULT_QP 3
-#ifndef V4L2_BUF_FLAG_MOTION_ON
-#define V4L2_BUF_FLAG_MOTION_ON 0x10000
-#define V4L2_BUF_FLAG_MOTION_DETECTED 0x20000
-#endif
-
#define SOLO_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
-#define V4L2_CID_MOTION_MODE (SOLO_CID_CUSTOM_BASE+0)
-#define V4L2_CID_MOTION_THRESHOLD (SOLO_CID_CUSTOM_BASE+1)
#define V4L2_CID_MOTION_TRACE (SOLO_CID_CUSTOM_BASE+2)
#define V4L2_CID_OSD_TEXT (SOLO_CID_CUSTOM_BASE+3)
@@ -113,19 +102,10 @@
* effect, 44x30 samples are used for NTSC, and 44x36 for PAL.
* The 5th sample on the 10th row is (10*64)+5 = 645.
*
- * Using a 64x64 array will result in a problem on some architectures like
- * the powerpc where the size of the argument is limited to 13 bits.
- * Since both PAL and NTSC do not use the full table anyway I've chosen
- * to limit the array to 45x45 (45*16 = 720, which is the maximum PAL/NTSC
- * width).
+ * Internally it is stored as a 45x45 array (45*16 = 720, which is the
+ * maximum PAL/NTSC width).
*/
#define SOLO_MOTION_SZ (45)
-struct solo_motion_thresholds {
- __u16 thresholds[SOLO_MOTION_SZ][SOLO_MOTION_SZ];
-};
-
-#define SOLO_IOC_G_MOTION_THRESHOLDS _IOR('V', BASE_VIDIOC_PRIVATE+0, struct solo_motion_thresholds)
-#define SOLO_IOC_S_MOTION_THRESHOLDS _IOW('V', BASE_VIDIOC_PRIVATE+1, struct solo_motion_thresholds)
enum SOLO_I2C_STATE {
IIC_STATE_IDLE,
@@ -168,6 +148,7 @@ struct solo_enc_dev {
struct solo_dev *solo_dev;
/* V4L2 Items */
struct v4l2_ctrl_handler hdl;
+ struct v4l2_ctrl *md_thresholds;
struct video_device *vfd;
/* General accounting */
struct mutex lock;
@@ -176,9 +157,10 @@ struct solo_enc_dev {
u8 mode, gop, qp, interlaced, interval;
u8 bw_weight;
u16 motion_thresh;
- struct solo_motion_thresholds motion_thresholds;
bool motion_global;
bool motion_enabled;
+ bool motion_last_state;
+ u8 frames_since_last_motion;
u16 width;
u16 height;
@@ -404,7 +386,7 @@ void solo_update_mode(struct solo_enc_dev *solo_enc);
/* Set the threshold for motion detection */
int solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val);
int solo_set_motion_block(struct solo_dev *solo_dev, u8 ch,
- const struct solo_motion_thresholds *thresholds);
+ const u16 *thresholds);
#define SOLO_DEF_MOT_THRESH 0x0300
/* Write text on OSD */
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index d2abd3b5c2bf..365bd21301ba 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -640,7 +640,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1093,7 +1092,6 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev,
vip->video_dev = &video_dev_template;
vip->video_dev->v4l2_dev = &vip->v4l2_dev;
vip->video_dev->queue = &vip->vb_vidq;
- set_bit(V4L2_FL_USE_FH_PRIO, &vip->video_dev->flags);
video_set_drvdata(vip->video_dev, vip);
ret = video_register_device(vip->video_dev, VFL_TYPE_GRABBER, -1);
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 0acf9202103d..1feeeff3681b 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -161,14 +161,14 @@ static void msp430_ir_interrupt(unsigned long data)
return;
if (budget_ci->ir.full_rc5) {
- rc_keydown(dev,
- budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
- (command & 0x20) ? 1 : 0);
+ rc_keydown(dev, RC_TYPE_RC5,
+ RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key),
+ !!(command & 0x20));
return;
}
/* FIXME: We should generate complete scancodes for all devices */
- rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
+ rc_keydown(dev, RC_TYPE_UNKNOWN, budget_ci->ir.ir_key, !!(command & 0x20));
}
static int msp430_ir_init(struct budget_ci *budget_ci)
@@ -234,7 +234,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
break;
}
if (!budget_ci->ir.full_rc5)
- dev->scanmask = 0xff;
+ dev->scancode_mask = 0xff;
error = rc_register_device(dev);
if (error) {
diff --git a/drivers/media/pci/zoran/zr36050.h b/drivers/media/pci/zoran/zr36050.h
index 9f52f0cdde50..ea083adda045 100644
--- a/drivers/media/pci/zoran/zr36050.h
+++ b/drivers/media/pci/zoran/zr36050.h
@@ -126,7 +126,6 @@ struct zr36050 {
/* zr36050 mode register bits */
#define ZR050_MO_COMP 0x80
-#define ZR050_MO_COMP 0x80
#define ZR050_MO_ATP 0x40
#define ZR050_MO_PASS2 0x20
#define ZR050_MO_TLM 0x10
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 8108c698b548..6d86646d9743 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -96,6 +96,7 @@ config VIDEO_OMAP3
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3
select ARM_DMA_USE_IOMMU
select OMAP_IOMMU
+ select VIDEOBUF2_DMA_CONTIG
---help---
Driver for an OMAP 3 camera controller.
@@ -142,6 +143,7 @@ config VIDEO_CODA
select SRAM
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
+ select GENERIC_ALLOCATOR
---help---
Coda is a range of video codec IPs that supports
H.264, MPEG-4, and other video formats.
@@ -165,12 +167,13 @@ config VIDEO_SAMSUNG_S5P_G2D
2d graphics accelerator.
config VIDEO_SAMSUNG_S5P_JPEG
- tristate "Samsung S5P/Exynos4 JPEG codec driver"
+ tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver"
depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS)
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
---help---
- This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
+ This is a v4l2 driver for Samsung S5P, EXYNOS3250
+ and EXYNOS4 JPEG codec
config VIDEO_SAMSUNG_S5P_MFC
tristate "Samsung S5P MFC Video Codec"
diff --git a/drivers/media/platform/arv.c b/drivers/media/platform/arv.c
index e9410e41ae0c..03c5098499c4 100644
--- a/drivers/media/platform/arv.c
+++ b/drivers/media/platform/arv.c
@@ -773,7 +773,6 @@ static int __init ar_init(void)
ar->vdev.fops = &ar_fops;
ar->vdev.ioctl_ops = &ar_ioctl_ops;
ar->vdev.release = video_device_release_empty;
- set_bit(V4L2_FL_USE_FH_PRIO, &ar->vdev.flags);
video_set_drvdata(&ar->vdev, ar);
if (vga) {
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 16e4b1c525c4..9b5daa65841c 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -446,7 +446,7 @@ static void bcap_stop_streaming(struct vb2_queue *vq)
while (!list_empty(&bcap_dev->dma_queue)) {
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
struct bcap_buffer, list);
- list_del(&bcap_dev->cur_frm->list);
+ list_del_init(&bcap_dev->cur_frm->list);
vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
}
}
@@ -533,7 +533,7 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
}
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
struct bcap_buffer, list);
- list_del(&bcap_dev->cur_frm->list);
+ list_del_init(&bcap_dev->cur_frm->list);
} else {
/* clear error flag, we will get a new frame */
if (ppi->err)
@@ -583,7 +583,7 @@ static int bcap_streamon(struct file *file, void *priv,
bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
struct bcap_buffer, list);
/* remove buffer from the dma queue */
- list_del(&bcap_dev->cur_frm->list);
+ list_del_init(&bcap_dev->cur_frm->list);
addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
/* update DMA address */
ppi->ops->update_addr(ppi, (unsigned long)addr);
@@ -939,7 +939,7 @@ static int bcap_probe(struct platform_device *pdev)
bcap_dev->cfg = config;
- bcap_dev->ppi = ppi_create_instance(config->ppi_info);
+ bcap_dev->ppi = ppi_create_instance(pdev, config->ppi_info);
if (!bcap_dev->ppi) {
v4l2_err(pdev->dev.driver, "Unable to create ppi\n");
ret = -ENODEV;
@@ -966,7 +966,6 @@ static int bcap_probe(struct platform_device *pdev)
vfd->ioctl_ops = &bcap_ioctl_ops;
vfd->tvnorms = 0;
vfd->v4l2_dev = &bcap_dev->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name));
bcap_dev->video_dev = vfd;
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 15e9c2bac2b1..cff63e511e6d 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/platform_device.h>
#include <asm/bfin_ppi.h>
#include <asm/blackfin.h>
@@ -205,6 +206,20 @@ static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
int dma_config, bytes_per_line;
int hcount, hdelay, samples_per_line;
+#ifdef CONFIG_PINCTRL
+ static const char * const pin_state[] = {"8bit", "16bit", "24bit"};
+ struct pinctrl *pctrl;
+ struct pinctrl_state *pstate;
+
+ if (params->dlen > 24 || params->dlen <= 0)
+ return -EINVAL;
+ pctrl = devm_pinctrl_get(ppi->dev);
+ pstate = pinctrl_lookup_state(pctrl,
+ pin_state[(params->dlen + 7) / 8 - 1]);
+ if (pinctrl_select_state(pctrl, pstate))
+ return -EINVAL;
+#endif
+
bytes_per_line = params->width * params->bpp / 8;
/* convert parameters unit from pixels to samples */
hcount = params->width * params->bpp / params->dlen;
@@ -307,26 +322,30 @@ static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr)
set_dma_start_addr(ppi->info->dma_ch, addr);
}
-struct ppi_if *ppi_create_instance(const struct ppi_info *info)
+struct ppi_if *ppi_create_instance(struct platform_device *pdev,
+ const struct ppi_info *info)
{
struct ppi_if *ppi;
if (!info || !info->pin_req)
return NULL;
+#ifndef CONFIG_PINCTRL
if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
- pr_err("request peripheral failed\n");
+ dev_err(&pdev->dev, "request peripheral failed\n");
return NULL;
}
+#endif
ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
if (!ppi) {
peripheral_free_list(info->pin_req);
- pr_err("unable to allocate memory for ppi handle\n");
+ dev_err(&pdev->dev, "unable to allocate memory for ppi handle\n");
return NULL;
}
ppi->ops = &ppi_ops;
ppi->info = info;
+ ppi->dev = &pdev->dev;
pr_info("ppi probe success\n");
return ppi;
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index b1783791d426..3a6d1d2b429e 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -12,6 +12,7 @@
*/
#include <linux/clk.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/genalloc.h>
@@ -22,10 +23,12 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/of.h>
#include <linux/platform_data/coda.h>
+#include <linux/reset.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -41,22 +44,18 @@
#define CODADX6_MAX_INSTANCES 4
-#define CODA_FMO_BUF_SIZE 32
-#define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
-#define CODA7_WORK_BUF_SIZE (128 * 1024)
-#define CODA7_TEMP_BUF_SIZE (304 * 1024)
#define CODA_PARA_BUF_SIZE (10 * 1024)
#define CODA_ISRAM_SIZE (2048 * 2)
-#define CODADX6_IRAM_SIZE 0xb000
-#define CODA7_IRAM_SIZE 0x14000
#define CODA7_PS_BUF_SIZE 0x28000
+#define CODA9_PS_SAVE_SIZE (512 * 1024)
#define CODA_MAX_FRAMEBUFFERS 8
#define CODA_MAX_FRAME_SIZE 0x100000
#define FMO_SLICE_SAVE_BUF_SIZE (32)
#define CODA_DEFAULT_GAMMA 4096
+#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */
#define MIN_W 176
#define MIN_H 144
@@ -84,6 +83,7 @@ enum coda_inst_type {
enum coda_product {
CODA_DX6 = 0xf001,
CODA_7541 = 0xf012,
+ CODA_960 = 0xf020,
};
struct coda_fmt {
@@ -105,20 +105,26 @@ struct coda_devtype {
struct coda_codec *codecs;
unsigned int num_codecs;
size_t workbuf_size;
+ size_t tempbuf_size;
+ size_t iram_size;
};
/* Per-queue, driver-specific private data */
struct coda_q_data {
unsigned int width;
unsigned int height;
+ unsigned int bytesperline;
unsigned int sizeimage;
unsigned int fourcc;
+ struct v4l2_rect rect;
};
struct coda_aux_buf {
void *vaddr;
dma_addr_t paddr;
u32 size;
+ struct debugfs_blob_wrapper blob;
+ struct dentry *dentry;
};
struct coda_dev {
@@ -130,32 +136,38 @@ struct coda_dev {
void __iomem *regs_base;
struct clk *clk_per;
struct clk *clk_ahb;
+ struct reset_control *rstc;
struct coda_aux_buf codebuf;
struct coda_aux_buf tempbuf;
struct coda_aux_buf workbuf;
struct gen_pool *iram_pool;
- long unsigned int iram_vaddr;
- long unsigned int iram_paddr;
- unsigned long iram_size;
+ struct coda_aux_buf iram;
spinlock_t irqlock;
struct mutex dev_mutex;
struct mutex coda_mutex;
+ struct workqueue_struct *workqueue;
struct v4l2_m2m_dev *m2m_dev;
struct vb2_alloc_ctx *alloc_ctx;
struct list_head instances;
unsigned long instance_mask;
- struct delayed_work timeout;
+ struct dentry *debugfs_root;
};
struct coda_params {
u8 rot_mode;
u8 h264_intra_qp;
u8 h264_inter_qp;
+ u8 h264_min_qp;
+ u8 h264_max_qp;
+ u8 h264_deblk_enabled;
+ u8 h264_deblk_alpha;
+ u8 h264_deblk_beta;
u8 mpeg4_intra_qp;
u8 mpeg4_inter_qp;
u8 gop_size;
+ int intra_refresh;
int codec_mode;
int codec_mode_aux;
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
@@ -175,13 +187,34 @@ struct coda_iram_info {
phys_addr_t buf_btp_use;
phys_addr_t search_ram_paddr;
int search_ram_size;
+ int remaining;
+ phys_addr_t next_paddr;
+};
+
+struct gdi_tiled_map {
+ int xy2ca_map[16];
+ int xy2ba_map[16];
+ int xy2ra_map[16];
+ int rbc2axi_map[32];
+ int xy2rbc_config;
+ int map_type;
+#define GDI_LINEAR_FRAME_MAP 0
+};
+
+struct coda_timestamp {
+ struct list_head list;
+ u32 sequence;
+ struct v4l2_timecode timecode;
+ struct timeval timestamp;
};
struct coda_ctx {
struct coda_dev *dev;
struct mutex buffer_mutex;
struct list_head list;
- struct work_struct skip_run;
+ struct work_struct pic_run_work;
+ struct work_struct seq_end_work;
+ struct completion completion;
int aborting;
int initialized;
int streamon_out;
@@ -189,12 +222,12 @@ struct coda_ctx {
u32 isequence;
u32 qsequence;
u32 osequence;
+ u32 sequence_offset;
struct coda_q_data q_data[2];
enum coda_inst_type inst_type;
struct coda_codec *codec;
enum v4l2_colorspace colorspace;
struct coda_params params;
- struct v4l2_m2m_ctx *m2m_ctx;
struct v4l2_ctrl_handler ctrls;
struct v4l2_fh fh;
int gopcounter;
@@ -204,19 +237,26 @@ struct coda_ctx {
struct kfifo bitstream_fifo;
struct mutex bitstream_mutex;
struct coda_aux_buf bitstream;
- bool prescan_failed;
+ bool hold;
struct coda_aux_buf parabuf;
struct coda_aux_buf psbuf;
struct coda_aux_buf slicebuf;
struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS];
+ u32 frame_types[CODA_MAX_FRAMEBUFFERS];
+ struct coda_timestamp frame_timestamps[CODA_MAX_FRAMEBUFFERS];
+ u32 frame_errors[CODA_MAX_FRAMEBUFFERS];
+ struct list_head timestamp_list;
struct coda_aux_buf workbuf;
int num_internal_frames;
int idx;
int reg_idx;
struct coda_iram_info iram_info;
+ struct gdi_tiled_map tiled_map;
u32 bit_stream_param;
u32 frm_dis_flg;
+ u32 frame_mem_ctrl;
int display_idx;
+ struct dentry *debugfs_entry;
};
static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff,
@@ -264,15 +304,23 @@ static void coda_command_async(struct coda_ctx *ctx, int cmd)
{
struct coda_dev *dev = ctx->dev;
- if (dev->devtype->product == CODA_7541) {
+ if (dev->devtype->product == CODA_960 ||
+ dev->devtype->product == CODA_7541) {
/* Restore context related registers to CODA */
coda_write(dev, ctx->bit_stream_param,
CODA_REG_BIT_BIT_STREAM_PARAM);
coda_write(dev, ctx->frm_dis_flg,
CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx));
+ coda_write(dev, ctx->frame_mem_ctrl,
+ CODA_REG_BIT_FRAME_MEM_CTRL);
coda_write(dev, ctx->workbuf.paddr, CODA_REG_BIT_WORK_BUF_ADDR);
}
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
+ coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
+ }
+
coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
coda_write(dev, ctx->idx, CODA_REG_BIT_RUN_INDEX);
@@ -290,6 +338,39 @@ static int coda_command_sync(struct coda_ctx *ctx, int cmd)
return coda_wait_timeout(dev);
}
+static int coda_hw_reset(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+ unsigned long timeout;
+ unsigned int idx;
+ int ret;
+
+ if (!dev->rstc)
+ return -ENOENT;
+
+ idx = coda_read(dev, CODA_REG_BIT_RUN_INDEX);
+
+ timeout = jiffies + msecs_to_jiffies(100);
+ coda_write(dev, 0x11, CODA9_GDI_BUS_CTRL);
+ while (coda_read(dev, CODA9_GDI_BUS_STATUS) != 0x77) {
+ if (time_after(jiffies, timeout))
+ return -ETIME;
+ cpu_relax();
+ }
+
+ ret = reset_control_reset(dev->rstc);
+ if (ret < 0)
+ return ret;
+
+ coda_write(dev, 0x00, CODA9_GDI_BUS_CTRL);
+ coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
+ coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN);
+ ret = coda_wait_timeout(dev);
+ coda_write(dev, idx, CODA_REG_BIT_RUN_INDEX);
+
+ return ret;
+}
+
static struct coda_q_data *get_q_data(struct coda_ctx *ctx,
enum v4l2_buf_type type)
{
@@ -299,9 +380,8 @@ static struct coda_q_data *get_q_data(struct coda_ctx *ctx,
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
return &(ctx->q_data[V4L2_M2M_DST]);
default:
- BUG();
+ return NULL;
}
- return NULL;
}
/*
@@ -348,6 +428,13 @@ static struct coda_codec coda7_codecs[] = {
CODA_CODEC(CODA7_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080),
};
+static struct coda_codec coda9_codecs[] = {
+ CODA_CODEC(CODA9_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080),
+};
+
static bool coda_format_is_yuv(u32 fourcc)
{
switch (fourcc) {
@@ -426,6 +513,8 @@ static char *coda_product_name(int product)
return "CodaDx6";
case CODA_7541:
return "CODA7541";
+ case CODA_960:
+ return "CODA960";
default:
snprintf(buf, sizeof(buf), "(0x%04x)", product);
return buf;
@@ -515,7 +604,7 @@ static int coda_enum_fmt_vid_cap(struct file *file, void *priv,
struct coda_q_data *q_data_src;
/* If the source format is already fixed, only list matching formats */
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
if (vb2_is_streaming(src_vq)) {
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
@@ -535,24 +624,18 @@ static int coda_enum_fmt_vid_out(struct file *file, void *priv,
static int coda_g_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct vb2_queue *vq;
struct coda_q_data *q_data;
struct coda_ctx *ctx = fh_to_ctx(priv);
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
q_data = get_q_data(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.pixelformat = q_data->fourcc;
f->fmt.pix.width = q_data->width;
f->fmt.pix.height = q_data->height;
- if (coda_format_is_yuv(f->fmt.pix.pixelformat))
- f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
- else /* encoded formats h.264/mpeg4 */
- f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.bytesperline = q_data->bytesperline;
f->fmt.pix.sizeimage = q_data->sizeimage;
f->fmt.pix.colorspace = ctx->colorspace;
@@ -592,14 +675,16 @@ static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
break;
default:
q_data = get_q_data(ctx, f->type);
+ if (!q_data)
+ return -EINVAL;
f->fmt.pix.pixelformat = q_data->fourcc;
}
switch (f->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
- /* Frame stride must be multiple of 8 */
- f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
+ /* Frame stride must be multiple of 8, but 16 for h.264 */
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
f->fmt.pix.height * 3 / 2;
break;
@@ -613,8 +698,6 @@ static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
BUG();
}
- f->fmt.pix.priv = 0;
-
return 0;
}
@@ -630,7 +713,7 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
* If the source format is already fixed, try to find a codec that
* converts to the given destination format
*/
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
if (vb2_is_streaming(src_vq)) {
struct coda_q_data *q_data_src;
@@ -653,9 +736,9 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,
/* The h.264 decoder only returns complete 16x16 macroblocks */
if (codec && codec->src_fourcc == V4L2_PIX_FMT_H264) {
- f->fmt.pix.width = round_up(f->fmt.pix.width, 16);
+ f->fmt.pix.width = f->fmt.pix.width;
f->fmt.pix.height = round_up(f->fmt.pix.height, 16);
- f->fmt.pix.bytesperline = f->fmt.pix.width;
+ f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 16);
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
f->fmt.pix.height * 3 / 2;
}
@@ -684,7 +767,7 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
struct coda_q_data *q_data;
struct vb2_queue *vq;
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
if (!vq)
return -EINVAL;
@@ -700,7 +783,12 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
q_data->fourcc = f->fmt.pix.pixelformat;
q_data->width = f->fmt.pix.width;
q_data->height = f->fmt.pix.height;
+ q_data->bytesperline = f->fmt.pix.bytesperline;
q_data->sizeimage = f->fmt.pix.sizeimage;
+ q_data->rect.left = 0;
+ q_data->rect.top = 0;
+ q_data->rect.width = f->fmt.pix.width;
+ q_data->rect.height = f->fmt.pix.height;
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
@@ -739,36 +827,12 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
return ret;
}
-static int coda_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct coda_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int coda_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct coda_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
static int coda_qbuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
struct coda_ctx *ctx = fh_to_ctx(priv);
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int coda_expbuf(struct file *file, void *priv,
- struct v4l2_exportbuffer *eb)
-{
- struct coda_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+ return v4l2_m2m_qbuf(file, ctx->fh.m2m_ctx, buf);
}
static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx,
@@ -776,7 +840,7 @@ static bool coda_buf_is_end_of_stream(struct coda_ctx *ctx,
{
struct vb2_queue *src_vq;
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ src_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
return ((ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) &&
(buf->sequence == (ctx->qsequence - 1)));
@@ -788,7 +852,7 @@ static int coda_dqbuf(struct file *file, void *priv,
struct coda_ctx *ctx = fh_to_ctx(priv);
int ret;
- ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+ ret = v4l2_m2m_dqbuf(file, ctx->fh.m2m_ctx, buf);
/* If this is the last capture buffer, emit an end-of-stream event */
if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
@@ -803,38 +867,48 @@ static int coda_dqbuf(struct file *file, void *priv,
return ret;
}
-static int coda_create_bufs(struct file *file, void *priv,
- struct v4l2_create_buffers *create)
+static int coda_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
{
- struct coda_ctx *ctx = fh_to_ctx(priv);
-
- return v4l2_m2m_create_bufs(file, ctx->m2m_ctx, create);
-}
-
-static int coda_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct coda_ctx *ctx = fh_to_ctx(priv);
+ struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_q_data *q_data;
+ struct v4l2_rect r, *rsel;
- return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
+ q_data = get_q_data(ctx, s->type);
+ if (!q_data)
+ return -EINVAL;
-static int coda_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct coda_ctx *ctx = fh_to_ctx(priv);
- int ret;
+ r.left = 0;
+ r.top = 0;
+ r.width = q_data->width;
+ r.height = q_data->height;
+ rsel = &q_data->rect;
+
+ switch (s->target) {
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ rsel = &r;
+ /* fallthrough */
+ case V4L2_SEL_TGT_CROP:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ break;
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+ case V4L2_SEL_TGT_COMPOSE_PADDED:
+ rsel = &r;
+ /* fallthrough */
+ case V4L2_SEL_TGT_COMPOSE:
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
- /*
- * This indirectly calls __vb2_queue_cancel, which dequeues all buffers.
- * We therefore have to lock it against running hardware in this context,
- * which still needs the buffers.
- */
- mutex_lock(&ctx->buffer_mutex);
- ret = v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
- mutex_unlock(&ctx->buffer_mutex);
+ s->r = *rsel;
- return ret;
+ return 0;
}
static int coda_try_decoder_cmd(struct file *file, void *fh,
@@ -856,6 +930,7 @@ static int coda_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *dc)
{
struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_dev *dev = ctx->dev;
int ret;
ret = coda_try_decoder_cmd(file, fh, dc);
@@ -869,6 +944,15 @@ static int coda_decoder_cmd(struct file *file, void *fh,
/* Set the strem-end flag on this context */
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ if ((dev->devtype->product == CODA_960) &&
+ coda_isbusy(dev) &&
+ (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) {
+ /* If this context is currently running, update the hardware flag */
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
+ ctx->hold = false;
+ v4l2_m2m_try_schedule(ctx->fh.m2m_ctx);
+
return 0;
}
@@ -896,16 +980,18 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_try_fmt_vid_out = coda_try_fmt_vid_out,
.vidioc_s_fmt_vid_out = coda_s_fmt_vid_out,
- .vidioc_reqbufs = coda_reqbufs,
- .vidioc_querybuf = coda_querybuf,
+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
.vidioc_qbuf = coda_qbuf,
- .vidioc_expbuf = coda_expbuf,
+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
.vidioc_dqbuf = coda_dqbuf,
- .vidioc_create_bufs = coda_create_bufs,
+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
- .vidioc_streamon = coda_streamon,
- .vidioc_streamoff = coda_streamoff,
+ .vidioc_streamon = v4l2_m2m_ioctl_streamon,
+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
+
+ .vidioc_g_selection = coda_g_selection,
.vidioc_try_decoder_cmd = coda_try_decoder_cmd,
.vidioc_decoder_cmd = coda_decoder_cmd,
@@ -916,13 +1002,6 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
static int coda_start_decoding(struct coda_ctx *ctx);
-static void coda_skip_run(struct work_struct *work)
-{
- struct coda_ctx *ctx = container_of(work, struct coda_ctx, skip_run);
-
- v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
-}
-
static inline int coda_get_bitstream_payload(struct coda_ctx *ctx)
{
return kfifo_len(&ctx->bitstream_fifo);
@@ -975,7 +1054,7 @@ static int coda_bitstream_queue(struct coda_ctx *ctx, struct vb2_buffer *src_buf
dma_sync_single_for_device(&ctx->dev->plat_dev->dev, ctx->bitstream.paddr,
ctx->bitstream.size, DMA_TO_DEVICE);
- ctx->qsequence++;
+ src_buf->v4l2_buf.sequence = ctx->qsequence++;
return 0;
}
@@ -1003,7 +1082,7 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
if (ctx == v4l2_m2m_get_curr_priv(ctx->dev->m2m_dev))
coda_kfifo_sync_to_device_write(ctx);
- ctx->prescan_failed = false;
+ ctx->hold = false;
return true;
}
@@ -1011,12 +1090,26 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
static void coda_fill_bitstream(struct coda_ctx *ctx)
{
struct vb2_buffer *src_buf;
+ struct coda_timestamp *ts;
- while (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0) {
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) {
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
if (coda_bitstream_try_queue(ctx, src_buf)) {
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+ /*
+ * Source buffer is queued in the bitstream ringbuffer;
+ * queue the timestamp and mark source buffer as done
+ */
+ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+
+ ts = kmalloc(sizeof(*ts), GFP_KERNEL);
+ if (ts) {
+ ts->sequence = src_buf->v4l2_buf.sequence;
+ ts->timecode = src_buf->v4l2_buf.timecode;
+ ts->timestamp = src_buf->v4l2_buf.timestamp;
+ list_add_tail(&ts->list, &ctx->timestamp_list);
+ }
+
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
} else {
break;
@@ -1024,6 +1117,27 @@ static void coda_fill_bitstream(struct coda_ctx *ctx)
}
}
+static void coda_set_gdi_regs(struct coda_ctx *ctx)
+{
+ struct gdi_tiled_map *tiled_map = &ctx->tiled_map;
+ struct coda_dev *dev = ctx->dev;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ coda_write(dev, tiled_map->xy2ca_map[i],
+ CODA9_GDI_XY2_CAS_0 + 4 * i);
+ for (i = 0; i < 4; i++)
+ coda_write(dev, tiled_map->xy2ba_map[i],
+ CODA9_GDI_XY2_BA_0 + 4 * i);
+ for (i = 0; i < 16; i++)
+ coda_write(dev, tiled_map->xy2ra_map[i],
+ CODA9_GDI_XY2_RAS_0 + 4 * i);
+ coda_write(dev, tiled_map->xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
+ for (i = 0; i < 32; i++)
+ coda_write(dev, tiled_map->rbc2axi_map[i],
+ CODA9_GDI_RBC2_AXI_0 + 4 * i);
+}
+
/*
* Mem-to-mem operations.
*/
@@ -1035,7 +1149,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
u32 stridey, height;
u32 picture_y, picture_cb, picture_cr;
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
if (ctx->params.rot_mode & CODA_ROT_90) {
@@ -1056,7 +1170,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"bitstream payload: %d, skipping\n",
coda_get_bitstream_payload(ctx));
- schedule_work(&ctx->skip_run);
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
return -EAGAIN;
}
@@ -1065,13 +1179,16 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
int ret = coda_start_decoding(ctx);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to start decoding\n");
- schedule_work(&ctx->skip_run);
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
return -EAGAIN;
} else {
ctx->initialized = 1;
}
}
+ if (dev->devtype->product == CODA_960)
+ coda_set_gdi_regs(ctx);
+
/* Set rotator output */
picture_y = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
if (q_data_dst->fourcc == V4L2_PIX_FMT_YVU420) {
@@ -1082,10 +1199,26 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
picture_cb = picture_y + stridey * height;
picture_cr = picture_cb + stridey / 2 * height / 2;
}
- coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y);
- coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB);
- coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR);
- coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE);
+
+ if (dev->devtype->product == CODA_960) {
+ /*
+ * The CODA960 seems to have an internal list of buffers with
+ * 64 entries that includes the registered frame buffers as
+ * well as the rotator buffer output.
+ * ROT_INDEX needs to be < 0x40, but > ctx->num_internal_frames.
+ */
+ coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->v4l2_buf.index,
+ CODA9_CMD_DEC_PIC_ROT_INDEX);
+ coda_write(dev, picture_y, CODA9_CMD_DEC_PIC_ROT_ADDR_Y);
+ coda_write(dev, picture_cb, CODA9_CMD_DEC_PIC_ROT_ADDR_CB);
+ coda_write(dev, picture_cr, CODA9_CMD_DEC_PIC_ROT_ADDR_CR);
+ coda_write(dev, stridey, CODA9_CMD_DEC_PIC_ROT_STRIDE);
+ } else {
+ coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y);
+ coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB);
+ coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR);
+ coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE);
+ }
coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode,
CODA_CMD_DEC_PIC_ROT_MODE);
@@ -1095,6 +1228,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
case CODA_7541:
coda_write(dev, CODA_PRE_SCAN_EN, CODA_CMD_DEC_PIC_OPTION);
break;
+ case CODA_960:
+ coda_write(dev, (1 << 10), CODA_CMD_DEC_PIC_OPTION); /* 'hardcode to use interrupt disable mode'? */
+ break;
}
coda_write(dev, 0, CODA_CMD_DEC_PIC_SKIP_NUM);
@@ -1116,8 +1252,8 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
u32 pic_stream_buffer_addr, pic_stream_buffer_size;
u32 dst_fourcc;
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
dst_fourcc = q_data_dst->fourcc;
@@ -1139,6 +1275,9 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
}
+ if (dev->devtype->product == CODA_960)
+ coda_set_gdi_regs(ctx);
+
/*
* Copy headers at the beginning of the first frame for H.264 only.
* In MPEG4 they are already copied by the coda.
@@ -1205,51 +1344,93 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
switch (q_data_src->fourcc) {
case V4L2_PIX_FMT_YVU420:
/* Switch Cb and Cr for YVU420 format */
- picture_cr = picture_y + q_data_src->width * q_data_src->height;
- picture_cb = picture_cr + q_data_src->width / 2 *
+ picture_cr = picture_y + q_data_src->bytesperline *
+ q_data_src->height;
+ picture_cb = picture_cr + q_data_src->bytesperline / 2 *
q_data_src->height / 2;
break;
case V4L2_PIX_FMT_YUV420:
default:
- picture_cb = picture_y + q_data_src->width * q_data_src->height;
- picture_cr = picture_cb + q_data_src->width / 2 *
+ picture_cb = picture_y + q_data_src->bytesperline *
+ q_data_src->height;
+ picture_cr = picture_cb + q_data_src->bytesperline / 2 *
q_data_src->height / 2;
break;
}
- coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
- coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
- coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 4/*FIXME: 0*/, CODA9_CMD_ENC_PIC_SRC_INDEX);
+ coda_write(dev, q_data_src->width, CODA9_CMD_ENC_PIC_SRC_STRIDE);
+ coda_write(dev, 0, CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC);
+
+ coda_write(dev, picture_y, CODA9_CMD_ENC_PIC_SRC_ADDR_Y);
+ coda_write(dev, picture_cb, CODA9_CMD_ENC_PIC_SRC_ADDR_CB);
+ coda_write(dev, picture_cr, CODA9_CMD_ENC_PIC_SRC_ADDR_CR);
+ } else {
+ coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
+ coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
+ coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
+ }
coda_write(dev, force_ipicture << 1 & 0x2,
CODA_CMD_ENC_PIC_OPTION);
coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
coda_write(dev, pic_stream_buffer_size / 1024,
CODA_CMD_ENC_PIC_BB_SIZE);
+
+ if (!ctx->streamon_out) {
+ /* After streamoff on the output side, set the stream end flag */
+ ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
}
static void coda_device_run(void *m2m_priv)
{
struct coda_ctx *ctx = m2m_priv;
struct coda_dev *dev = ctx->dev;
- int ret;
+
+ queue_work(dev->workqueue, &ctx->pic_run_work);
+}
+
+static void coda_free_framebuffers(struct coda_ctx *ctx);
+static void coda_free_context_buffers(struct coda_ctx *ctx);
+
+static void coda_seq_end_work(struct work_struct *work)
+{
+ struct coda_ctx *ctx = container_of(work, struct coda_ctx, seq_end_work);
+ struct coda_dev *dev = ctx->dev;
mutex_lock(&ctx->buffer_mutex);
+ mutex_lock(&dev->coda_mutex);
- /*
- * If streamoff dequeued all buffers before we could get the lock,
- * just bail out immediately.
- */
- if ((!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) &&
- ctx->inst_type != CODA_INST_DECODER) ||
- !v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
- v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
- "%d: device_run without buffers\n", ctx->idx);
- mutex_unlock(&ctx->buffer_mutex);
- schedule_work(&ctx->skip_run);
- return;
+ v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
+ "%d: %s: sent command 'SEQ_END' to coda\n", ctx->idx, __func__);
+ if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
+ v4l2_err(&dev->v4l2_dev,
+ "CODA_COMMAND_SEQ_END failed\n");
}
+ kfifo_init(&ctx->bitstream_fifo,
+ ctx->bitstream.vaddr, ctx->bitstream.size);
+
+ coda_free_framebuffers(ctx);
+ coda_free_context_buffers(ctx);
+
+ mutex_unlock(&dev->coda_mutex);
+ mutex_unlock(&ctx->buffer_mutex);
+}
+
+static void coda_finish_decode(struct coda_ctx *ctx);
+static void coda_finish_encode(struct coda_ctx *ctx);
+
+static void coda_pic_run_work(struct work_struct *work)
+{
+ struct coda_ctx *ctx = container_of(work, struct coda_ctx, pic_run_work);
+ struct coda_dev *dev = ctx->dev;
+ int ret;
+
+ mutex_lock(&ctx->buffer_mutex);
mutex_lock(&dev->coda_mutex);
if (ctx->inst_type == CODA_INST_DECODER) {
@@ -1268,12 +1449,30 @@ static void coda_device_run(void *m2m_priv)
coda_write(dev, ctx->iram_info.axi_sram_use,
CODA7_REG_BIT_AXI_SRAM_USE);
- /* 1 second timeout in case CODA locks up */
- schedule_delayed_work(&dev->timeout, HZ);
-
if (ctx->inst_type == CODA_INST_DECODER)
coda_kfifo_sync_to_device_full(ctx);
coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
+
+ if (!wait_for_completion_timeout(&ctx->completion, msecs_to_jiffies(1000))) {
+ dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout\n");
+
+ ctx->hold = true;
+
+ coda_hw_reset(ctx);
+ } else if (!ctx->aborting) {
+ if (ctx->inst_type == CODA_INST_DECODER)
+ coda_finish_decode(ctx);
+ else
+ coda_finish_encode(ctx);
+ }
+
+ if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out))
+ queue_work(dev->workqueue, &ctx->seq_end_work);
+
+ mutex_unlock(&dev->coda_mutex);
+ mutex_unlock(&ctx->buffer_mutex);
+
+ v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
}
static int coda_job_ready(void *m2m_priv)
@@ -1285,20 +1484,20 @@ static int coda_job_ready(void *m2m_priv)
* and 1 frame are needed. In the decoder case,
* the compressed frame can be in the bitstream.
*/
- if (!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) &&
+ if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) &&
ctx->inst_type != CODA_INST_DECODER) {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"not ready: not enough video buffers.\n");
return 0;
}
- if (!v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
+ if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"not ready: not enough video capture buffers.\n");
return 0;
}
- if (ctx->prescan_failed ||
+ if (ctx->hold ||
((ctx->inst_type == CODA_INST_DECODER) &&
(coda_get_bitstream_payload(ctx) < 512) &&
!(ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG))) {
@@ -1351,6 +1550,32 @@ static struct v4l2_m2m_ops coda_m2m_ops = {
.unlock = coda_unlock,
};
+static void coda_set_tiled_map_type(struct coda_ctx *ctx, int tiled_map_type)
+{
+ struct gdi_tiled_map *tiled_map = &ctx->tiled_map;
+ int luma_map, chro_map, i;
+
+ memset(tiled_map, 0, sizeof(*tiled_map));
+
+ luma_map = 64;
+ chro_map = 64;
+ tiled_map->map_type = tiled_map_type;
+ for (i = 0; i < 16; i++)
+ tiled_map->xy2ca_map[i] = luma_map << 8 | chro_map;
+ for (i = 0; i < 4; i++)
+ tiled_map->xy2ba_map[i] = luma_map << 8 | chro_map;
+ for (i = 0; i < 16; i++)
+ tiled_map->xy2ra_map[i] = luma_map << 8 | chro_map;
+
+ if (tiled_map_type == GDI_LINEAR_FRAME_MAP) {
+ tiled_map->xy2rbc_config = 0;
+ } else {
+ dev_err(&ctx->dev->plat_dev->dev, "invalid map type: %d\n",
+ tiled_map_type);
+ return;
+ }
+}
+
static void set_default_params(struct coda_ctx *ctx)
{
int max_w;
@@ -1370,10 +1595,19 @@ static void set_default_params(struct coda_ctx *ctx)
ctx->q_data[V4L2_M2M_DST].fourcc = ctx->codec->dst_fourcc;
ctx->q_data[V4L2_M2M_SRC].width = max_w;
ctx->q_data[V4L2_M2M_SRC].height = max_h;
+ ctx->q_data[V4L2_M2M_SRC].bytesperline = max_w;
ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2;
ctx->q_data[V4L2_M2M_DST].width = max_w;
ctx->q_data[V4L2_M2M_DST].height = max_h;
+ ctx->q_data[V4L2_M2M_DST].bytesperline = 0;
ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
+ ctx->q_data[V4L2_M2M_SRC].rect.width = max_w;
+ ctx->q_data[V4L2_M2M_SRC].rect.height = max_h;
+ ctx->q_data[V4L2_M2M_DST].rect.width = max_w;
+ ctx->q_data[V4L2_M2M_DST].rect.height = max_h;
+
+ if (ctx->dev->devtype->product == CODA_960)
+ coda_set_tiled_map_type(ctx, GDI_LINEAR_FRAME_MAP);
}
/*
@@ -1423,6 +1657,7 @@ static int coda_buf_prepare(struct vb2_buffer *vb)
static void coda_buf_queue(struct vb2_buffer *vb)
{
struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data;
q_data = get_q_data(ctx, vb->vb2_queue->type);
@@ -1437,29 +1672,24 @@ static void coda_buf_queue(struct vb2_buffer *vb)
* For backwards compatibility, queuing an empty buffer marks
* the stream end
*/
- if (vb2_get_plane_payload(vb, 0) == 0)
+ if (vb2_get_plane_payload(vb, 0) == 0) {
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ if ((dev->devtype->product == CODA_960) &&
+ coda_isbusy(dev) &&
+ (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) {
+ /* if this decoder instance is running, set the stream end flag */
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
+ }
mutex_lock(&ctx->bitstream_mutex);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
coda_fill_bitstream(ctx);
mutex_unlock(&ctx->bitstream_mutex);
} else {
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+ v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
}
}
-static void coda_wait_prepare(struct vb2_queue *q)
-{
- struct coda_ctx *ctx = vb2_get_drv_priv(q);
- coda_unlock(ctx);
-}
-
-static void coda_wait_finish(struct vb2_queue *q)
-{
- struct coda_ctx *ctx = vb2_get_drv_priv(q);
- coda_lock(ctx);
-}
-
static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
{
struct coda_dev *dev = ctx->dev;
@@ -1472,7 +1702,8 @@ static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
}
static int coda_alloc_aux_buf(struct coda_dev *dev,
- struct coda_aux_buf *buf, size_t size)
+ struct coda_aux_buf *buf, size_t size,
+ const char *name, struct dentry *parent)
{
buf->vaddr = dma_alloc_coherent(&dev->plat_dev->dev, size, &buf->paddr,
GFP_KERNEL);
@@ -1481,13 +1712,23 @@ static int coda_alloc_aux_buf(struct coda_dev *dev,
buf->size = size;
+ if (name && parent) {
+ buf->blob.data = buf->vaddr;
+ buf->blob.size = size;
+ buf->dentry = debugfs_create_blob(name, 0644, parent, &buf->blob);
+ if (!buf->dentry)
+ dev_warn(&dev->plat_dev->dev,
+ "failed to create debugfs entry %s\n", name);
+ }
+
return 0;
}
static inline int coda_alloc_context_buf(struct coda_ctx *ctx,
- struct coda_aux_buf *buf, size_t size)
+ struct coda_aux_buf *buf, size_t size,
+ const char *name)
{
- return coda_alloc_aux_buf(ctx->dev, buf, size);
+ return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry);
}
static void coda_free_aux_buf(struct coda_dev *dev,
@@ -1499,6 +1740,7 @@ static void coda_free_aux_buf(struct coda_dev *dev,
buf->vaddr = NULL;
buf->size = 0;
}
+ debugfs_remove(buf->dentry);
}
static void coda_free_framebuffers(struct coda_ctx *ctx)
@@ -1512,25 +1754,35 @@ static void coda_free_framebuffers(struct coda_ctx *ctx)
static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc)
{
struct coda_dev *dev = ctx->dev;
- int height = q_data->height;
+ int width, height;
dma_addr_t paddr;
int ysize;
int ret;
int i;
- if (ctx->codec && ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
- height = round_up(height, 16);
- ysize = round_up(q_data->width, 8) * height;
+ if (ctx->codec && (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
+ ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264)) {
+ width = round_up(q_data->width, 16);
+ height = round_up(q_data->height, 16);
+ } else {
+ width = round_up(q_data->width, 8);
+ height = q_data->height;
+ }
+ ysize = width * height;
/* Allocate frame buffers */
for (i = 0; i < ctx->num_internal_frames; i++) {
size_t size;
+ char *name;
- size = q_data->sizeimage;
+ size = ysize + ysize / 2;
if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 &&
dev->devtype->product != CODA_DX6)
- ctx->internal_frames[i].size += ysize/4;
- ret = coda_alloc_context_buf(ctx, &ctx->internal_frames[i], size);
+ size += ysize / 4;
+ name = kasprintf(GFP_KERNEL, "fb%d", i);
+ ret = coda_alloc_context_buf(ctx, &ctx->internal_frames[i],
+ size, name);
+ kfree(name);
if (ret < 0) {
coda_free_framebuffers(ctx);
return ret;
@@ -1579,23 +1831,48 @@ static int coda_h264_padding(int size, char *p)
return nal_size;
}
+static phys_addr_t coda_iram_alloc(struct coda_iram_info *iram, size_t size)
+{
+ phys_addr_t ret;
+
+ size = round_up(size, 1024);
+ if (size > iram->remaining)
+ return 0;
+ iram->remaining -= size;
+
+ ret = iram->next_paddr;
+ iram->next_paddr += size;
+
+ return ret;
+}
+
static void coda_setup_iram(struct coda_ctx *ctx)
{
struct coda_iram_info *iram_info = &ctx->iram_info;
struct coda_dev *dev = ctx->dev;
- int ipacdc_size;
- int bitram_size;
- int dbk_size;
- int ovl_size;
int mb_width;
- int me_size;
- int size;
+ int dbk_bits;
+ int bit_bits;
+ int ip_bits;
memset(iram_info, 0, sizeof(*iram_info));
- size = dev->iram_size;
+ iram_info->next_paddr = dev->iram.paddr;
+ iram_info->remaining = dev->iram.size;
- if (dev->devtype->product == CODA_DX6)
+ switch (dev->devtype->product) {
+ case CODA_7541:
+ dbk_bits = CODA7_USE_HOST_DBK_ENABLE | CODA7_USE_DBK_ENABLE;
+ bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE;
+ ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE;
+ break;
+ case CODA_960:
+ dbk_bits = CODA9_USE_HOST_DBK_ENABLE | CODA9_USE_DBK_ENABLE;
+ bit_bits = CODA9_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE;
+ ip_bits = CODA9_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE;
+ break;
+ default: /* CODA_DX6 */
return;
+ }
if (ctx->inst_type == CODA_INST_ENCODER) {
struct coda_q_data *q_data_src;
@@ -1604,111 +1881,63 @@ static void coda_setup_iram(struct coda_ctx *ctx)
mb_width = DIV_ROUND_UP(q_data_src->width, 16);
/* Prioritize in case IRAM is too small for everything */
- me_size = round_up(round_up(q_data_src->width, 16) * 36 + 2048,
- 1024);
- iram_info->search_ram_size = me_size;
- if (size >= iram_info->search_ram_size) {
- if (dev->devtype->product == CODA_7541)
- iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE;
- iram_info->search_ram_paddr = dev->iram_paddr;
- size -= iram_info->search_ram_size;
- } else {
- pr_err("IRAM is smaller than the search ram size\n");
- goto out;
+ if (dev->devtype->product == CODA_7541) {
+ iram_info->search_ram_size = round_up(mb_width * 16 *
+ 36 + 2048, 1024);
+ iram_info->search_ram_paddr = coda_iram_alloc(iram_info,
+ iram_info->search_ram_size);
+ if (!iram_info->search_ram_paddr) {
+ pr_err("IRAM is smaller than the search ram size\n");
+ goto out;
+ }
+ iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE |
+ CODA7_USE_ME_ENABLE;
}
/* Only H.264BP and H.263P3 are considered */
- dbk_size = round_up(128 * mb_width, 1024);
- if (size >= dbk_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE;
- iram_info->buf_dbk_y_use = dev->iram_paddr +
- iram_info->search_ram_size;
- iram_info->buf_dbk_c_use = iram_info->buf_dbk_y_use +
- dbk_size / 2;
- size -= dbk_size;
- } else {
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 64 * mb_width);
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 64 * mb_width);
+ if (!iram_info->buf_dbk_c_use)
goto out;
- }
+ iram_info->axi_sram_use |= dbk_bits;
- bitram_size = round_up(128 * mb_width, 1024);
- if (size >= bitram_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_BIT_ENABLE;
- iram_info->buf_bit_use = iram_info->buf_dbk_c_use +
- dbk_size / 2;
- size -= bitram_size;
- } else {
+ iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ if (!iram_info->buf_bit_use)
goto out;
- }
+ iram_info->axi_sram_use |= bit_bits;
- ipacdc_size = round_up(128 * mb_width, 1024);
- if (size >= ipacdc_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_IP_ENABLE;
- iram_info->buf_ip_ac_dc_use = iram_info->buf_bit_use +
- bitram_size;
- size -= ipacdc_size;
- }
+ iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ if (!iram_info->buf_ip_ac_dc_use)
+ goto out;
+ iram_info->axi_sram_use |= ip_bits;
/* OVL and BTP disabled for encoder */
} else if (ctx->inst_type == CODA_INST_DECODER) {
struct coda_q_data *q_data_dst;
- int mb_height;
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
mb_width = DIV_ROUND_UP(q_data_dst->width, 16);
- mb_height = DIV_ROUND_UP(q_data_dst->height, 16);
-
- dbk_size = round_up(256 * mb_width, 1024);
- if (size >= dbk_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE;
- iram_info->buf_dbk_y_use = dev->iram_paddr;
- iram_info->buf_dbk_c_use = dev->iram_paddr +
- dbk_size / 2;
- size -= dbk_size;
- } else {
+
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ if (!iram_info->buf_dbk_c_use)
goto out;
- }
+ iram_info->axi_sram_use |= dbk_bits;
- bitram_size = round_up(128 * mb_width, 1024);
- if (size >= bitram_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_BIT_ENABLE;
- iram_info->buf_bit_use = iram_info->buf_dbk_c_use +
- dbk_size / 2;
- size -= bitram_size;
- } else {
+ iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ if (!iram_info->buf_bit_use)
goto out;
- }
+ iram_info->axi_sram_use |= bit_bits;
- ipacdc_size = round_up(128 * mb_width, 1024);
- if (size >= ipacdc_size) {
- iram_info->axi_sram_use |= CODA7_USE_HOST_IP_ENABLE;
- iram_info->buf_ip_ac_dc_use = iram_info->buf_bit_use +
- bitram_size;
- size -= ipacdc_size;
- } else {
+ iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
+ if (!iram_info->buf_ip_ac_dc_use)
goto out;
- }
+ iram_info->axi_sram_use |= ip_bits;
- ovl_size = round_up(80 * mb_width, 1024);
+ /* OVL and BTP unused as there is no VC1 support yet */
}
out:
- switch (dev->devtype->product) {
- case CODA_DX6:
- break;
- case CODA_7541:
- /* i.MX53 uses secondary AXI for IRAM access */
- if (iram_info->axi_sram_use & CODA7_USE_HOST_BIT_ENABLE)
- iram_info->axi_sram_use |= CODA7_USE_BIT_ENABLE;
- if (iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE)
- iram_info->axi_sram_use |= CODA7_USE_IP_ENABLE;
- if (iram_info->axi_sram_use & CODA7_USE_HOST_DBK_ENABLE)
- iram_info->axi_sram_use |= CODA7_USE_DBK_ENABLE;
- if (iram_info->axi_sram_use & CODA7_USE_HOST_OVL_ENABLE)
- iram_info->axi_sram_use |= CODA7_USE_OVL_ENABLE;
- if (iram_info->axi_sram_use & CODA7_USE_HOST_ME_ENABLE)
- iram_info->axi_sram_use |= CODA7_USE_ME_ENABLE;
- }
-
if (!(iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE))
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"IRAM smaller than needed\n");
@@ -1746,13 +1975,8 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
size_t size;
int ret;
- switch (dev->devtype->product) {
- case CODA_7541:
- size = CODA7_WORK_BUF_SIZE;
- break;
- default:
+ if (dev->devtype->product == CODA_DX6)
return 0;
- }
if (ctx->psbuf.vaddr) {
v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n");
@@ -1772,7 +1996,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
/* worst case slice size */
size = (DIV_ROUND_UP(q_data->width, 16) *
DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512;
- ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size);
+ ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, "slicebuf");
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to allocate %d byte slice buffer",
ctx->slicebuf.size);
@@ -1781,14 +2005,18 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
}
if (dev->devtype->product == CODA_7541) {
- ret = coda_alloc_context_buf(ctx, &ctx->psbuf, CODA7_PS_BUF_SIZE);
+ ret = coda_alloc_context_buf(ctx, &ctx->psbuf, CODA7_PS_BUF_SIZE, "psbuf");
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to allocate psmem buffer");
goto err;
}
}
- ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size);
+ size = dev->devtype->workbuf_size;
+ if (dev->devtype->product == CODA_960 &&
+ q_data->fourcc == V4L2_PIX_FMT_H264)
+ size += CODA9_PS_SAVE_SIZE;
+ ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf");
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to allocate %d byte context buffer",
ctx->workbuf.size);
@@ -1834,12 +2062,17 @@ static int coda_start_decoding(struct coda_ctx *ctx)
coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START);
coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE);
val = 0;
- if (dev->devtype->product == CODA_7541)
+ if ((dev->devtype->product == CODA_7541) ||
+ (dev->devtype->product == CODA_960))
val |= CODA_REORDER_ENABLE;
coda_write(dev, val, CODA_CMD_DEC_SEQ_OPTION);
ctx->params.codec_mode = ctx->codec->mode;
- ctx->params.codec_mode_aux = 0;
+ if (dev->devtype->product == CODA_960 &&
+ src_fourcc == V4L2_PIX_FMT_MPEG4)
+ ctx->params.codec_mode_aux = CODA_MP4_AUX_MPEG4;
+ else
+ ctx->params.codec_mode_aux = 0;
if (src_fourcc == V4L2_PIX_FMT_H264) {
if (dev->devtype->product == CODA_7541) {
coda_write(dev, ctx->psbuf.paddr,
@@ -1847,6 +2080,13 @@ static int coda_start_decoding(struct coda_ctx *ctx)
coda_write(dev, (CODA7_PS_BUF_SIZE / 1024),
CODA_CMD_DEC_SEQ_PS_BB_SIZE);
}
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 0, CODA_CMD_DEC_SEQ_X264_MV_EN);
+ coda_write(dev, 512, CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE);
+ }
+ }
+ if (dev->devtype->product != CODA_960) {
+ coda_write(dev, 0, CODA_CMD_DEC_SEQ_SRC_SIZE);
}
if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
@@ -1888,7 +2128,7 @@ static int coda_start_decoding(struct coda_ctx *ctx)
v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "%s instance %d now: %dx%d\n",
__func__, ctx->idx, width, height);
- ctx->num_internal_frames = coda_read(dev, CODA_RET_DEC_SEQ_FRAME_NEED) + 1;
+ ctx->num_internal_frames = coda_read(dev, CODA_RET_DEC_SEQ_FRAME_NEED);
if (ctx->num_internal_frames > CODA_MAX_FRAMEBUFFERS) {
v4l2_err(&dev->v4l2_dev,
"not enough framebuffers to decode (%d < %d)\n",
@@ -1896,6 +2136,21 @@ static int coda_start_decoding(struct coda_ctx *ctx)
return -EINVAL;
}
+ if (src_fourcc == V4L2_PIX_FMT_H264) {
+ u32 left_right;
+ u32 top_bottom;
+
+ left_right = coda_read(dev, CODA_RET_DEC_SEQ_CROP_LEFT_RIGHT);
+ top_bottom = coda_read(dev, CODA_RET_DEC_SEQ_CROP_TOP_BOTTOM);
+
+ q_data_dst->rect.left = (left_right >> 10) & 0x3ff;
+ q_data_dst->rect.top = (top_bottom >> 10) & 0x3ff;
+ q_data_dst->rect.width = width - q_data_dst->rect.left -
+ (left_right & 0x3ff);
+ q_data_dst->rect.height = height - q_data_dst->rect.top -
+ (top_bottom & 0x3ff);
+ }
+
ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc);
if (ret < 0)
return ret;
@@ -1918,6 +2173,20 @@ static int coda_start_decoding(struct coda_ctx *ctx)
CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
coda_write(dev, ctx->iram_info.buf_ovl_use,
CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, ctx->iram_info.buf_btp_use,
+ CODA9_CMD_SET_FRAME_AXI_BTP_ADDR);
+ }
+
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, -1, CODA9_CMD_SET_FRAME_DELAY);
+
+ coda_write(dev, 0x20262024, CODA9_CMD_SET_FRAME_CACHE_SIZE);
+ coda_write(dev, 2 << CODA9_CACHE_PAGEMERGE_OFFSET |
+ 32 << CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET |
+ 8 << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET |
+ 8 << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET,
+ CODA9_CMD_SET_FRAME_CACHE_CONFIG);
}
if (src_fourcc == V4L2_PIX_FMT_H264) {
@@ -1931,8 +2200,16 @@ static int coda_start_decoding(struct coda_ctx *ctx)
int max_mb_x = 1920 / 16;
int max_mb_y = 1088 / 16;
int max_mb_num = max_mb_x * max_mb_y;
+
coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y,
CODA7_CMD_SET_FRAME_MAX_DEC_SIZE);
+ } else if (dev->devtype->product == CODA_960) {
+ int max_mb_x = 1920 / 16;
+ int max_mb_y = 1088 / 16;
+ int max_mb_num = max_mb_x * max_mb_y;
+
+ coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y,
+ CODA9_CMD_SET_FRAME_MAX_DEC_SIZE);
}
if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
@@ -1948,34 +2225,49 @@ static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
int header_code, u8 *header, int *size)
{
struct coda_dev *dev = ctx->dev;
+ size_t bufsize;
int ret;
+ int i;
+
+ if (dev->devtype->product == CODA_960)
+ memset(vb2_plane_vaddr(buf, 0), 0, 64);
coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
+ bufsize = vb2_plane_size(buf, 0);
+ if (dev->devtype->product == CODA_960)
+ bufsize /= 1024;
+ coda_write(dev, bufsize, CODA_CMD_ENC_HEADER_BB_SIZE);
coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
return ret;
}
- *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+
+ if (dev->devtype->product == CODA_960) {
+ for (i = 63; i > 0; i--)
+ if (((char *)vb2_plane_vaddr(buf, 0))[i] != 0)
+ break;
+ *size = i + 1;
+ } else {
+ *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ }
memcpy(header, vb2_plane_vaddr(buf, 0), *size);
return 0;
}
+static int coda_start_encoding(struct coda_ctx *ctx);
+
static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
- u32 bitstream_buf, bitstream_size;
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_src, *q_data_dst;
- struct vb2_buffer *buf;
u32 dst_fourcc;
- u32 value;
int ret = 0;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
@@ -2007,13 +2299,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
/* Allow decoder device_run with no new buffers queued */
if (ctx->inst_type == CODA_INST_DECODER)
- v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true);
+ v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true);
ctx->gopcounter = ctx->params.gop_size - 1;
- buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- bitstream_size = q_data_dst->sizeimage;
dst_fourcc = q_data_dst->fourcc;
ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
@@ -2032,16 +2321,36 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
mutex_lock(&dev->coda_mutex);
ret = coda_start_decoding(ctx);
mutex_unlock(&dev->coda_mutex);
- if (ret == -EAGAIN) {
+ if (ret == -EAGAIN)
return 0;
- } else if (ret < 0) {
+ else if (ret < 0)
return ret;
- } else {
- ctx->initialized = 1;
- return 0;
- }
+ } else {
+ ret = coda_start_encoding(ctx);
}
+ ctx->initialized = 1;
+ return ret;
+}
+
+static int coda_start_encoding(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ struct coda_q_data *q_data_src, *q_data_dst;
+ u32 bitstream_buf, bitstream_size;
+ struct vb2_buffer *buf;
+ int gamma, ret, value;
+ u32 dst_fourcc;
+
+ q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ dst_fourcc = q_data_dst->fourcc;
+
+ buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
+ bitstream_size = q_data_dst->sizeimage;
+
if (!coda_is_initialized(dev)) {
v4l2_err(v4l2_dev, "coda is not initialized.\n");
return -EFAULT;
@@ -2057,14 +2366,23 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
coda_write(dev, CODADX6_STREAM_BUF_DYNALLOC_EN |
CODADX6_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
break;
- default:
+ case CODA_960:
+ coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
+ /* fallthrough */
+ case CODA_7541:
coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN |
CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
+ break;
}
+ value = coda_read(dev, CODA_REG_BIT_FRAME_MEM_CTRL);
+ value &= ~(1 << 2 | 0x7 << 9);
+ ctx->frame_mem_ctrl = value;
+ coda_write(dev, value, CODA_REG_BIT_FRAME_MEM_CTRL);
+
if (dev->devtype->product == CODA_DX6) {
/* Configure the coda */
- coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
+ coda_write(dev, dev->iram.paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
}
/* Could set rotation here if needed */
@@ -2073,7 +2391,16 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
break;
- default:
+ case CODA_7541:
+ if (dst_fourcc == V4L2_PIX_FMT_H264) {
+ value = (round_up(q_data_src->width, 16) &
+ CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
+ value |= (round_up(q_data_src->height, 16) &
+ CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
+ break;
+ }
+ /* fallthrough */
+ case CODA_960:
value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
}
@@ -2084,12 +2411,28 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
ctx->params.codec_mode = ctx->codec->mode;
switch (dst_fourcc) {
case V4L2_PIX_FMT_MPEG4:
- coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, CODA9_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
+ else
+ coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
break;
case V4L2_PIX_FMT_H264:
- coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
- coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, CODA9_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
+ else
+ coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
+ if (ctx->params.h264_deblk_enabled) {
+ value = ((ctx->params.h264_deblk_alpha &
+ CODA_264PARAM_DEBLKFILTEROFFSETALPHA_MASK) <<
+ CODA_264PARAM_DEBLKFILTEROFFSETALPHA_OFFSET) |
+ ((ctx->params.h264_deblk_beta &
+ CODA_264PARAM_DEBLKFILTEROFFSETBETA_MASK) <<
+ CODA_264PARAM_DEBLKFILTEROFFSETBETA_OFFSET);
+ } else {
+ value = 1 << CODA_264PARAM_DISABLEDEBLK_OFFSET;
+ }
+ coda_write(dev, value, CODA_CMD_ENC_SEQ_264_PARA);
break;
default:
v4l2_err(v4l2_dev,
@@ -2121,42 +2464,75 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
/* Rate control enabled */
value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK) << CODA_RATECONTROL_BITRATE_OFFSET;
value |= 1 & CODA_RATECONTROL_ENABLE_MASK;
+ if (dev->devtype->product == CODA_960)
+ value |= BIT(31); /* disable autoskip */
} else {
value = 0;
}
coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_PARA);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_BUF_SIZE);
- coda_write(dev, 0, CODA_CMD_ENC_SEQ_INTRA_REFRESH);
+ coda_write(dev, ctx->params.intra_refresh,
+ CODA_CMD_ENC_SEQ_INTRA_REFRESH);
coda_write(dev, bitstream_buf, CODA_CMD_ENC_SEQ_BB_START);
coda_write(dev, bitstream_size / 1024, CODA_CMD_ENC_SEQ_BB_SIZE);
- /* set default gamma */
- value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
- coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
- if (CODA_DEFAULT_GAMMA > 0) {
- if (dev->devtype->product == CODA_DX6)
- value = 1 << CODADX6_OPTION_GAMMA_OFFSET;
- else
- value = 1 << CODA7_OPTION_GAMMA_OFFSET;
+ value = 0;
+ if (dev->devtype->product == CODA_960)
+ gamma = CODA9_DEFAULT_GAMMA;
+ else
+ gamma = CODA_DEFAULT_GAMMA;
+ if (gamma > 0) {
+ coda_write(dev, (gamma & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET,
+ CODA_CMD_ENC_SEQ_RC_GAMMA);
+ }
+
+ if (ctx->params.h264_min_qp || ctx->params.h264_max_qp) {
+ coda_write(dev,
+ ctx->params.h264_min_qp << CODA_QPMIN_OFFSET |
+ ctx->params.h264_max_qp << CODA_QPMAX_OFFSET,
+ CODA_CMD_ENC_SEQ_RC_QP_MIN_MAX);
+ }
+ if (dev->devtype->product == CODA_960) {
+ if (ctx->params.h264_max_qp)
+ value |= 1 << CODA9_OPTION_RCQPMAX_OFFSET;
+ if (CODA_DEFAULT_GAMMA > 0)
+ value |= 1 << CODA9_OPTION_GAMMA_OFFSET;
} else {
- value = 0;
+ if (CODA_DEFAULT_GAMMA > 0) {
+ if (dev->devtype->product == CODA_DX6)
+ value |= 1 << CODADX6_OPTION_GAMMA_OFFSET;
+ else
+ value |= 1 << CODA7_OPTION_GAMMA_OFFSET;
+ }
+ if (ctx->params.h264_min_qp)
+ value |= 1 << CODA7_OPTION_RCQPMIN_OFFSET;
+ if (ctx->params.h264_max_qp)
+ value |= 1 << CODA7_OPTION_RCQPMAX_OFFSET;
}
coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_INTERVAL_MODE);
+
coda_setup_iram(ctx);
if (dst_fourcc == V4L2_PIX_FMT_H264) {
- if (dev->devtype->product == CODA_DX6) {
+ switch (dev->devtype->product) {
+ case CODA_DX6:
value = FMO_SLICE_SAVE_BUF_SIZE << 7;
coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
- } else {
+ break;
+ case CODA_7541:
coda_write(dev, ctx->iram_info.search_ram_paddr,
CODA7_CMD_ENC_SEQ_SEARCH_BASE);
coda_write(dev, ctx->iram_info.search_ram_size,
CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
+ break;
+ case CODA_960:
+ coda_write(dev, 0, CODA9_CMD_ENC_SEQ_ME_OPTION);
+ coda_write(dev, 0, CODA9_CMD_ENC_SEQ_INTRA_WEIGHT);
}
}
@@ -2172,7 +2548,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
goto out;
}
- ctx->num_internal_frames = 2;
+ if (dev->devtype->product == CODA_960)
+ ctx->num_internal_frames = 4;
+ else
+ ctx->num_internal_frames = 2;
ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
if (ret < 0) {
v4l2_err(v4l2_dev, "failed to allocate framebuffers\n");
@@ -2180,10 +2559,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
}
coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
- coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
- if (dev->devtype->product == CODA_7541)
- coda_write(dev, round_up(q_data_src->width, 8),
+ coda_write(dev, q_data_src->bytesperline,
+ CODA_CMD_SET_FRAME_BUF_STRIDE);
+ if (dev->devtype->product == CODA_7541) {
+ coda_write(dev, q_data_src->bytesperline,
CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
+ }
if (dev->devtype->product != CODA_DX6) {
coda_write(dev, ctx->iram_info.buf_bit_use,
CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
@@ -2195,7 +2576,16 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
coda_write(dev, ctx->iram_info.buf_ovl_use,
CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, ctx->iram_info.buf_btp_use,
+ CODA9_CMD_SET_FRAME_AXI_BTP_ADDR);
+
+ /* FIXME */
+ coda_write(dev, ctx->internal_frames[2].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_A);
+ coda_write(dev, ctx->internal_frames[3].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_B);
+ }
}
+
ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
if (ret < 0) {
v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
@@ -2203,7 +2593,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
}
/* Save stream headers */
- buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
switch (dst_fourcc) {
case V4L2_PIX_FMT_H264:
/*
@@ -2279,6 +2669,17 @@ static void coda_stop_streaming(struct vb2_queue *q)
"%s: output\n", __func__);
ctx->streamon_out = 0;
+ if (ctx->inst_type == CODA_INST_DECODER &&
+ coda_isbusy(dev) && ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX)) {
+ /* if this decoder instance is running, set the stream end flag */
+ if (dev->devtype->product == CODA_960) {
+ u32 val = coda_read(dev, CODA_REG_BIT_BIT_STREAM_PARAM);
+
+ val |= CODA_BIT_STREAM_END_FLAG;
+ coda_write(dev, val, CODA_REG_BIT_BIT_STREAM_PARAM);
+ ctx->bit_stream_param = val;
+ }
+ }
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
ctx->isequence = 0;
@@ -2288,9 +2689,18 @@ static void coda_stop_streaming(struct vb2_queue *q)
ctx->streamon_cap = 0;
ctx->osequence = 0;
+ ctx->sequence_offset = 0;
}
if (!ctx->streamon_out && !ctx->streamon_cap) {
+ struct coda_timestamp *ts;
+
+ while (!list_empty(&ctx->timestamp_list)) {
+ ts = list_first_entry(&ctx->timestamp_list,
+ struct coda_timestamp, list);
+ list_del(&ts->list);
+ kfree(ts);
+ }
kfifo_init(&ctx->bitstream_fifo,
ctx->bitstream.vaddr, ctx->bitstream.size);
ctx->runcounter = 0;
@@ -2301,10 +2711,10 @@ static struct vb2_ops coda_qops = {
.queue_setup = coda_queue_setup,
.buf_prepare = coda_buf_prepare,
.buf_queue = coda_buf_queue,
- .wait_prepare = coda_wait_prepare,
- .wait_finish = coda_wait_finish,
.start_streaming = coda_start_streaming,
.stop_streaming = coda_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
};
static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -2340,6 +2750,22 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
ctx->params.h264_inter_qp = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
+ ctx->params.h264_min_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
+ ctx->params.h264_max_qp = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
+ ctx->params.h264_deblk_alpha = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
+ ctx->params.h264_deblk_beta = ctrl->val;
+ break;
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+ ctx->params.h264_deblk_enabled = (ctrl->val ==
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED);
+ break;
case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
ctx->params.mpeg4_intra_qp = ctrl->val;
break;
@@ -2357,6 +2783,9 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
break;
+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
+ ctx->params.intra_refresh = ctrl->val;
+ break;
default:
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"Invalid control, id=%d, val=%d\n",
@@ -2384,9 +2813,23 @@ static int coda_ctrls_setup(struct coda_ctx *ctx)
v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16);
v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 25);
+ V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 0, 51, 1, 25);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 0, 51, 1, 25);
+ if (ctx->dev->devtype->product != CODA_960) {
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 0, 51, 1, 12);
+ }
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 0, 51, 1, 51);
v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 25);
+ V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, 0, 15, 1, 0);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, 0, 15, 1, 0);
+ v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED, 0x0,
+ V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED);
v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, 1, 31, 1, 2);
v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
@@ -2404,6 +2847,8 @@ static int coda_ctrls_setup(struct coda_ctx *ctx)
V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
(1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE),
V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+ v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, 0, 1920 * 1088 / 256, 1, 0);
if (ctx->ctrls.error) {
v4l2_err(&ctx->dev->v4l2_dev, "control initialization error (%d)",
@@ -2427,6 +2872,7 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->ops = &coda_qops;
src_vq->mem_ops = &vb2_dma_contig_memops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ src_vq->lock = &ctx->dev->dev_mutex;
ret = vb2_queue_init(src_vq);
if (ret)
@@ -2439,6 +2885,7 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->ops = &coda_qops;
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ dst_vq->lock = &ctx->dev->dev_mutex;
return vb2_queue_init(dst_vq);
}
@@ -2458,6 +2905,7 @@ static int coda_open(struct file *file)
{
struct coda_dev *dev = video_drvdata(file);
struct coda_ctx *ctx = NULL;
+ char *name;
int ret;
int idx;
@@ -2472,7 +2920,13 @@ static int coda_open(struct file *file)
}
set_bit(idx, &dev->instance_mask);
- INIT_WORK(&ctx->skip_run, coda_skip_run);
+ name = kasprintf(GFP_KERNEL, "context%d", idx);
+ ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root);
+ kfree(name);
+
+ init_completion(&ctx->completion);
+ INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
+ INIT_WORK(&ctx->seq_end_work, coda_seq_end_work);
v4l2_fh_init(&ctx->fh, video_devdata(file));
file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh);
@@ -2480,12 +2934,20 @@ static int coda_open(struct file *file)
ctx->idx = idx;
switch (dev->devtype->product) {
case CODA_7541:
+ case CODA_960:
ctx->reg_idx = 0;
break;
default:
ctx->reg_idx = idx;
}
+ /* Power up and upload firmware if necessary */
+ ret = pm_runtime_get_sync(&dev->plat_dev->dev);
+ if (ret < 0) {
+ v4l2_err(&dev->v4l2_dev, "failed to power up: %d\n", ret);
+ goto err_pm_get;
+ }
+
ret = clk_prepare_enable(dev->clk_per);
if (ret)
goto err_clk_per;
@@ -2495,15 +2957,16 @@ static int coda_open(struct file *file)
goto err_clk_ahb;
set_default_params(ctx);
- ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
&coda_queue_init);
- if (IS_ERR(ctx->m2m_ctx)) {
- ret = PTR_ERR(ctx->m2m_ctx);
+ if (IS_ERR(ctx->fh.m2m_ctx)) {
+ ret = PTR_ERR(ctx->fh.m2m_ctx);
v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
__func__, ret);
goto err_ctx_init;
}
+
ret = coda_ctrls_setup(ctx);
if (ret) {
v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n");
@@ -2512,7 +2975,8 @@ static int coda_open(struct file *file)
ctx->fh.ctrl_handler = &ctx->ctrls;
- ret = coda_alloc_context_buf(ctx, &ctx->parabuf, CODA_PARA_BUF_SIZE);
+ ret = coda_alloc_context_buf(ctx, &ctx->parabuf, CODA_PARA_BUF_SIZE,
+ "parabuf");
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf");
goto err_dma_alloc;
@@ -2530,6 +2994,7 @@ static int coda_open(struct file *file)
ctx->bitstream.vaddr, ctx->bitstream.size);
mutex_init(&ctx->bitstream_mutex);
mutex_init(&ctx->buffer_mutex);
+ INIT_LIST_HEAD(&ctx->timestamp_list);
coda_lock(ctx);
list_add(&ctx->list, &dev->instances);
@@ -2548,12 +3013,14 @@ err_dma_writecombine:
err_dma_alloc:
v4l2_ctrl_handler_free(&ctx->ctrls);
err_ctrls_setup:
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
err_ctx_init:
clk_disable_unprepare(dev->clk_ahb);
err_clk_ahb:
clk_disable_unprepare(dev->clk_per);
err_clk_per:
+ pm_runtime_put_sync(&dev->plat_dev->dev);
+err_pm_get:
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
clear_bit(ctx->idx, &dev->instance_mask);
@@ -2570,20 +3037,16 @@ static int coda_release(struct file *file)
v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Releasing instance %p\n",
ctx);
+ debugfs_remove_recursive(ctx->debugfs_entry);
+
/* If this instance is running, call .job_abort and wait for it to end */
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
/* In case the instance was not running, we still need to call SEQ_END */
- mutex_lock(&dev->coda_mutex);
- v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
- "%s: sent command 'SEQ_END' to coda\n", __func__);
- if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
- v4l2_err(&dev->v4l2_dev,
- "CODA_COMMAND_SEQ_END failed\n");
- mutex_unlock(&dev->coda_mutex);
- return -ETIMEDOUT;
+ if (ctx->initialized) {
+ queue_work(dev->workqueue, &ctx->seq_end_work);
+ flush_work(&ctx->seq_end_work);
}
- mutex_unlock(&dev->coda_mutex);
coda_free_framebuffers(ctx);
@@ -2601,6 +3064,7 @@ static int coda_release(struct file *file)
v4l2_ctrl_handler_free(&ctx->ctrls);
clk_disable_unprepare(dev->clk_ahb);
clk_disable_unprepare(dev->clk_per);
+ pm_runtime_put_sync(&dev->plat_dev->dev);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
clear_bit(ctx->idx, &dev->instance_mask);
@@ -2609,32 +3073,13 @@ static int coda_release(struct file *file)
return 0;
}
-static unsigned int coda_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct coda_ctx *ctx = fh_to_ctx(file->private_data);
- int ret;
-
- coda_lock(ctx);
- ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
- coda_unlock(ctx);
- return ret;
-}
-
-static int coda_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct coda_ctx *ctx = fh_to_ctx(file->private_data);
-
- return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
static const struct v4l2_file_operations coda_fops = {
.owner = THIS_MODULE,
.open = coda_open,
.release = coda_release,
- .poll = coda_poll,
+ .poll = v4l2_m2m_fop_poll,
.unlocked_ioctl = video_ioctl2,
- .mmap = coda_mmap,
+ .mmap = v4l2_m2m_fop_mmap,
};
static void coda_finish_decode(struct coda_ctx *ctx)
@@ -2643,14 +3088,16 @@ static void coda_finish_decode(struct coda_ctx *ctx)
struct coda_q_data *q_data_src;
struct coda_q_data *q_data_dst;
struct vb2_buffer *dst_buf;
+ struct coda_timestamp *ts;
int width, height;
int decoded_idx;
int display_idx;
u32 src_fourcc;
int success;
+ u32 err_mb;
u32 val;
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
/* Update kfifo out pointer from coda bitstream read pointer */
coda_kfifo_sync_from_device(ctx);
@@ -2693,19 +3140,34 @@ static void coda_finish_decode(struct coda_ctx *ctx)
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- val = coda_read(dev, CODA_RET_DEC_PIC_TYPE);
- if ((val & 0x7) == 0) {
- dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
+ /* frame crop information */
+ if (src_fourcc == V4L2_PIX_FMT_H264) {
+ u32 left_right;
+ u32 top_bottom;
+
+ left_right = coda_read(dev, CODA_RET_DEC_PIC_CROP_LEFT_RIGHT);
+ top_bottom = coda_read(dev, CODA_RET_DEC_PIC_CROP_TOP_BOTTOM);
+
+ if (left_right == 0xffffffff && top_bottom == 0xffffffff) {
+ /* Keep current crop information */
+ } else {
+ struct v4l2_rect *rect = &q_data_dst->rect;
+
+ rect->left = left_right >> 16 & 0xffff;
+ rect->top = top_bottom >> 16 & 0xffff;
+ rect->width = width - rect->left -
+ (left_right & 0xffff);
+ rect->height = height - rect->top -
+ (top_bottom & 0xffff);
+ }
} else {
- dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
- dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
+ /* no cropping */
}
- val = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB);
- if (val > 0)
+ err_mb = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB);
+ if (err_mb > 0)
v4l2_err(&dev->v4l2_dev,
- "errors in %d macroblocks\n", val);
+ "errors in %d macroblocks\n", err_mb);
if (dev->devtype->product == CODA_7541) {
val = coda_read(dev, CODA_RET_DEC_PIC_OPTION);
@@ -2713,7 +3175,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
/* not enough bitstream data */
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"prescan failed: %d\n", val);
- ctx->prescan_failed = true;
+ ctx->hold = true;
return;
}
}
@@ -2741,13 +3203,38 @@ static void coda_finish_decode(struct coda_ctx *ctx)
if (decoded_idx == -1) {
/* no frame was decoded, but we might have a display frame */
- if (display_idx < 0 && ctx->display_idx < 0)
- ctx->prescan_failed = true;
+ if (display_idx >= 0 && display_idx < ctx->num_internal_frames)
+ ctx->sequence_offset++;
+ else if (ctx->display_idx < 0)
+ ctx->hold = true;
} else if (decoded_idx == -2) {
/* no frame was decoded, we still return the remaining buffers */
} else if (decoded_idx < 0 || decoded_idx >= ctx->num_internal_frames) {
v4l2_err(&dev->v4l2_dev,
"decoded frame index out of range: %d\n", decoded_idx);
+ } else {
+ ts = list_first_entry(&ctx->timestamp_list,
+ struct coda_timestamp, list);
+ list_del(&ts->list);
+ val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
+ val -= ctx->sequence_offset;
+ if (val != (ts->sequence & 0xffff)) {
+ v4l2_err(&dev->v4l2_dev,
+ "sequence number mismatch (%d(%d) != %d)\n",
+ val, ctx->sequence_offset, ts->sequence);
+ }
+ ctx->frame_timestamps[decoded_idx] = *ts;
+ kfree(ts);
+
+ val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7;
+ if (val == 0)
+ ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME;
+ else if (val == 1)
+ ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_PFRAME;
+ else
+ ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_BFRAME;
+
+ ctx->frame_errors[decoded_idx] = err_mb;
}
if (display_idx == -1) {
@@ -2755,7 +3242,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
* no more frames to be decoded, but there could still
* be rotator output to dequeue
*/
- ctx->prescan_failed = true;
+ ctx->hold = true;
} else if (display_idx == -3) {
/* possibly prescan failure */
} else if (display_idx < 0 || display_idx >= ctx->num_internal_frames) {
@@ -2767,13 +3254,21 @@ static void coda_finish_decode(struct coda_ctx *ctx)
/* If a frame was copied out, return it */
if (ctx->display_idx >= 0 &&
ctx->display_idx < ctx->num_internal_frames) {
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
dst_buf->v4l2_buf.sequence = ctx->osequence++;
+ dst_buf->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+ V4L2_BUF_FLAG_PFRAME |
+ V4L2_BUF_FLAG_BFRAME);
+ dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx];
+ ts = &ctx->frame_timestamps[ctx->display_idx];
+ dst_buf->v4l2_buf.timecode = ts->timecode;
+ dst_buf->v4l2_buf.timestamp = ts->timestamp;
+
vb2_set_plane_payload(dst_buf, 0, width * height * 3 / 2);
- v4l2_m2m_buf_done(dst_buf, success ? VB2_BUF_STATE_DONE :
- VB2_BUF_STATE_ERROR);
+ v4l2_m2m_buf_done(dst_buf, ctx->frame_errors[display_idx] ?
+ VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
"job finished: decoding frame (%d) (%s)\n",
@@ -2795,8 +3290,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
struct coda_dev *dev = ctx->dev;
u32 wr_ptr, start_ptr;
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
/* Get results from the coda */
start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
@@ -2833,6 +3328,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
ctx->gopcounter--;
@@ -2851,8 +3348,6 @@ static irqreturn_t coda_irq_handler(int irq, void *data)
struct coda_dev *dev = data;
struct coda_ctx *ctx;
- cancel_delayed_work(&dev->timeout);
-
/* read status register to attend the IRQ */
coda_read(dev, CODA_REG_BIT_INT_STATUS);
coda_write(dev, CODA_REG_BIT_INT_CLEAR_SET,
@@ -2868,7 +3363,6 @@ static irqreturn_t coda_irq_handler(int irq, void *data)
if (ctx->aborting) {
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"task has been aborted\n");
- goto out;
}
if (coda_isbusy(ctx->dev)) {
@@ -2877,60 +3371,15 @@ static irqreturn_t coda_irq_handler(int irq, void *data)
return IRQ_NONE;
}
- if (ctx->inst_type == CODA_INST_DECODER)
- coda_finish_decode(ctx);
- else
- coda_finish_encode(ctx);
-
-out:
- if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out)) {
- v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
- "%s: sent command 'SEQ_END' to coda\n", __func__);
- if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
- v4l2_err(&dev->v4l2_dev,
- "CODA_COMMAND_SEQ_END failed\n");
- }
-
- kfifo_init(&ctx->bitstream_fifo,
- ctx->bitstream.vaddr, ctx->bitstream.size);
-
- coda_free_framebuffers(ctx);
- coda_free_context_buffers(ctx);
- }
-
- mutex_unlock(&dev->coda_mutex);
- mutex_unlock(&ctx->buffer_mutex);
-
- v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
+ complete(&ctx->completion);
return IRQ_HANDLED;
}
-static void coda_timeout(struct work_struct *work)
-{
- struct coda_ctx *ctx;
- struct coda_dev *dev = container_of(to_delayed_work(work),
- struct coda_dev, timeout);
-
- dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout, stopping all streams\n");
-
- mutex_lock(&dev->dev_mutex);
- list_for_each_entry(ctx, &dev->instances, list) {
- if (mutex_is_locked(&ctx->buffer_mutex))
- mutex_unlock(&ctx->buffer_mutex);
- v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
- v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- }
- mutex_unlock(&dev->dev_mutex);
-
- mutex_unlock(&dev->coda_mutex);
- ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
- v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
-}
-
static u32 coda_supported_firmwares[] = {
CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5),
CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50),
+ CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5),
};
static bool coda_firmware_supported(u32 vernum)
@@ -2945,19 +3394,21 @@ static bool coda_firmware_supported(u32 vernum)
static int coda_hw_init(struct coda_dev *dev)
{
- u16 product, major, minor, release;
u32 data;
u16 *p;
int i, ret;
ret = clk_prepare_enable(dev->clk_per);
if (ret)
- return ret;
+ goto err_clk_per;
ret = clk_prepare_enable(dev->clk_ahb);
if (ret)
goto err_clk_ahb;
+ if (dev->rstc)
+ reset_control_reset(dev->rstc);
+
/*
* Copy the first CODA_ISRAM_SIZE in the internal SRAM.
* The 16-bit chars in the code buffer are in memory access
@@ -2985,7 +3436,8 @@ static int coda_hw_init(struct coda_dev *dev)
coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4);
/* Tell the BIT where to find everything it needs */
- if (dev->devtype->product == CODA_7541) {
+ if (dev->devtype->product == CODA_960 ||
+ dev->devtype->product == CODA_7541) {
coda_write(dev, dev->tempbuf.paddr,
CODA_REG_BIT_TEMP_BUF_ADDR);
coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM);
@@ -3005,7 +3457,10 @@ static int coda_hw_init(struct coda_dev *dev)
default:
coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
}
- coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, 1 << 12, CODA_REG_BIT_FRAME_MEM_CTRL);
+ else
+ coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
if (dev->devtype->product != CODA_DX6)
coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
@@ -3022,17 +3477,46 @@ static int coda_hw_init(struct coda_dev *dev)
coda_write(dev, data, CODA_REG_BIT_CODE_RESET);
coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN);
- /* Load firmware */
+ clk_disable_unprepare(dev->clk_ahb);
+ clk_disable_unprepare(dev->clk_per);
+
+ return 0;
+
+err_clk_ahb:
+ clk_disable_unprepare(dev->clk_per);
+err_clk_per:
+ return ret;
+}
+
+static int coda_check_firmware(struct coda_dev *dev)
+{
+ u16 product, major, minor, release;
+ u32 data;
+ int ret;
+
+ ret = clk_prepare_enable(dev->clk_per);
+ if (ret)
+ goto err_clk_per;
+
+ ret = clk_prepare_enable(dev->clk_ahb);
+ if (ret)
+ goto err_clk_ahb;
+
coda_write(dev, 0, CODA_CMD_FIRMWARE_VERNUM);
coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
coda_write(dev, 0, CODA_REG_BIT_RUN_INDEX);
coda_write(dev, 0, CODA_REG_BIT_RUN_COD_STD);
coda_write(dev, CODA_COMMAND_FIRMWARE_GET, CODA_REG_BIT_RUN_COMMAND);
if (coda_wait_timeout(dev)) {
- clk_disable_unprepare(dev->clk_per);
- clk_disable_unprepare(dev->clk_ahb);
v4l2_err(&dev->v4l2_dev, "firmware get command error\n");
- return -EIO;
+ ret = -EIO;
+ goto err_run_cmd;
+ }
+
+ if (dev->devtype->product == CODA_960) {
+ data = coda_read(dev, CODA9_CMD_FIRMWARE_CODE_REV);
+ v4l2_info(&dev->v4l2_dev, "Firmware code revision: %d\n",
+ data);
}
/* Check we are compatible with the loaded firmware */
@@ -3066,8 +3550,11 @@ static int coda_hw_init(struct coda_dev *dev)
return 0;
+err_run_cmd:
+ clk_disable_unprepare(dev->clk_ahb);
err_clk_ahb:
clk_disable_unprepare(dev->clk_per);
+err_clk_per:
return ret;
}
@@ -3083,7 +3570,8 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
}
/* allocate auxiliary per-device code buffer for the BIT processor */
- ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size);
+ ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf",
+ dev->debugfs_root);
if (ret < 0) {
dev_err(&pdev->dev, "failed to allocate code buffer\n");
return;
@@ -3093,10 +3581,37 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
memcpy(dev->codebuf.vaddr, fw->data, fw->size);
release_firmware(fw);
- ret = coda_hw_init(dev);
- if (ret) {
- v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
- return;
+ if (pm_runtime_enabled(&pdev->dev) && pdev->dev.pm_domain) {
+ /*
+ * Enabling power temporarily will cause coda_hw_init to be
+ * called via coda_runtime_resume by the pm domain.
+ */
+ ret = pm_runtime_get_sync(&dev->plat_dev->dev);
+ if (ret < 0) {
+ v4l2_err(&dev->v4l2_dev, "failed to power on: %d\n",
+ ret);
+ return;
+ }
+
+ ret = coda_check_firmware(dev);
+ if (ret < 0)
+ return;
+
+ pm_runtime_put_sync(&dev->plat_dev->dev);
+ } else {
+ /*
+ * If runtime pm is disabled or pm_domain is not set,
+ * initialize once manually.
+ */
+ ret = coda_hw_init(dev);
+ if (ret < 0) {
+ v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
+ return;
+ }
+
+ ret = coda_check_firmware(dev);
+ if (ret < 0)
+ return;
}
dev->vfd.fops = &coda_fops,
@@ -3150,20 +3665,45 @@ static int coda_firmware_request(struct coda_dev *dev)
enum coda_platform {
CODA_IMX27,
CODA_IMX53,
+ CODA_IMX6Q,
+ CODA_IMX6DL,
};
static const struct coda_devtype coda_devdata[] = {
[CODA_IMX27] = {
- .firmware = "v4l-codadx6-imx27.bin",
- .product = CODA_DX6,
- .codecs = codadx6_codecs,
- .num_codecs = ARRAY_SIZE(codadx6_codecs),
+ .firmware = "v4l-codadx6-imx27.bin",
+ .product = CODA_DX6,
+ .codecs = codadx6_codecs,
+ .num_codecs = ARRAY_SIZE(codadx6_codecs),
+ .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024,
+ .iram_size = 0xb000,
},
[CODA_IMX53] = {
- .firmware = "v4l-coda7541-imx53.bin",
- .product = CODA_7541,
- .codecs = coda7_codecs,
- .num_codecs = ARRAY_SIZE(coda7_codecs),
+ .firmware = "v4l-coda7541-imx53.bin",
+ .product = CODA_7541,
+ .codecs = coda7_codecs,
+ .num_codecs = ARRAY_SIZE(coda7_codecs),
+ .workbuf_size = 128 * 1024,
+ .tempbuf_size = 304 * 1024,
+ .iram_size = 0x14000,
+ },
+ [CODA_IMX6Q] = {
+ .firmware = "v4l-coda960-imx6q.bin",
+ .product = CODA_960,
+ .codecs = coda9_codecs,
+ .num_codecs = ARRAY_SIZE(coda9_codecs),
+ .workbuf_size = 80 * 1024,
+ .tempbuf_size = 204 * 1024,
+ .iram_size = 0x21000,
+ },
+ [CODA_IMX6DL] = {
+ .firmware = "v4l-coda960-imx6dl.bin",
+ .product = CODA_960,
+ .codecs = coda9_codecs,
+ .num_codecs = ARRAY_SIZE(coda9_codecs),
+ .workbuf_size = 80 * 1024,
+ .tempbuf_size = 204 * 1024,
+ .iram_size = 0x20000,
},
};
@@ -3178,6 +3718,8 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids);
static const struct of_device_id coda_dt_ids[] = {
{ .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
{ .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
+ { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] },
+ { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, coda_dt_ids);
@@ -3204,7 +3746,6 @@ static int coda_probe(struct platform_device *pdev)
spin_lock_init(&dev->irqlock);
INIT_LIST_HEAD(&dev->instances);
- INIT_DELAYED_WORK(&dev->timeout, coda_timeout);
dev->plat_dev = pdev;
dev->clk_per = devm_clk_get(&pdev->dev, "per");
@@ -3229,13 +3770,25 @@ static int coda_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get irq resource\n");
- return -ENOENT;
+ return irq;
}
- if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler,
- IRQF_ONESHOT, dev_name(&pdev->dev), dev) < 0) {
- dev_err(&pdev->dev, "failed to request irq\n");
- return -ENOENT;
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler,
+ IRQF_ONESHOT, dev_name(&pdev->dev), dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request irq: %d\n", ret);
+ return ret;
+ }
+
+ dev->rstc = devm_reset_control_get_optional(&pdev->dev, NULL);
+ if (IS_ERR(dev->rstc)) {
+ ret = PTR_ERR(dev->rstc);
+ if (ret == -ENOENT || ret == -ENOSYS) {
+ dev->rstc = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed get reset control: %d\n", ret);
+ return ret;
+ }
}
/* Get IRAM pool from device tree or platform data */
@@ -3266,24 +3819,26 @@ static int coda_probe(struct platform_device *pdev)
return -EINVAL;
}
+ dev->debugfs_root = debugfs_create_dir("coda", NULL);
+ if (!dev->debugfs_root)
+ dev_warn(&pdev->dev, "failed to create debugfs root\n");
+
/* allocate auxiliary per-device buffers for the BIT processor */
- switch (dev->devtype->product) {
- case CODA_DX6:
+ if (dev->devtype->product == CODA_DX6) {
ret = coda_alloc_aux_buf(dev, &dev->workbuf,
- CODADX6_WORK_BUF_SIZE);
+ dev->devtype->workbuf_size, "workbuf",
+ dev->debugfs_root);
if (ret < 0) {
dev_err(&pdev->dev, "failed to allocate work buffer\n");
v4l2_device_unregister(&dev->v4l2_dev);
return ret;
}
- break;
- case CODA_7541:
- dev->tempbuf.size = CODA7_TEMP_BUF_SIZE;
- break;
}
- if (dev->tempbuf.size) {
+
+ if (dev->devtype->tempbuf_size) {
ret = coda_alloc_aux_buf(dev, &dev->tempbuf,
- dev->tempbuf.size);
+ dev->devtype->tempbuf_size, "tempbuf",
+ dev->debugfs_root);
if (ret < 0) {
dev_err(&pdev->dev, "failed to allocate temp buffer\n");
v4l2_device_unregister(&dev->v4l2_dev);
@@ -3291,23 +3846,29 @@ static int coda_probe(struct platform_device *pdev)
}
}
- switch (dev->devtype->product) {
- case CODA_DX6:
- dev->iram_size = CODADX6_IRAM_SIZE;
- break;
- case CODA_7541:
- dev->iram_size = CODA7_IRAM_SIZE;
- break;
- }
- dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool,
- dev->iram_size, (dma_addr_t *)&dev->iram_paddr);
- if (!dev->iram_vaddr) {
+ dev->iram.size = dev->devtype->iram_size;
+ dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size,
+ &dev->iram.paddr);
+ if (!dev->iram.vaddr) {
dev_err(&pdev->dev, "unable to alloc iram\n");
return -ENOMEM;
}
+ dev->iram.blob.data = dev->iram.vaddr;
+ dev->iram.blob.size = dev->iram.size;
+ dev->iram.dentry = debugfs_create_blob("iram", 0644, dev->debugfs_root,
+ &dev->iram.blob);
+
+ dev->workqueue = alloc_workqueue("coda", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+ if (!dev->workqueue) {
+ dev_err(&pdev->dev, "unable to alloc workqueue\n");
+ return -ENOMEM;
+ }
+
platform_set_drvdata(pdev, dev);
+ pm_runtime_enable(&pdev->dev);
+
return coda_firmware_request(dev);
}
@@ -3318,17 +3879,41 @@ static int coda_remove(struct platform_device *pdev)
video_unregister_device(&dev->vfd);
if (dev->m2m_dev)
v4l2_m2m_release(dev->m2m_dev);
+ pm_runtime_disable(&pdev->dev);
if (dev->alloc_ctx)
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
v4l2_device_unregister(&dev->v4l2_dev);
- if (dev->iram_vaddr)
- gen_pool_free(dev->iram_pool, dev->iram_vaddr, dev->iram_size);
+ destroy_workqueue(dev->workqueue);
+ if (dev->iram.vaddr)
+ gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr,
+ dev->iram.size);
coda_free_aux_buf(dev, &dev->codebuf);
coda_free_aux_buf(dev, &dev->tempbuf);
coda_free_aux_buf(dev, &dev->workbuf);
+ debugfs_remove_recursive(dev->debugfs_root);
return 0;
}
+#ifdef CONFIG_PM_RUNTIME
+static int coda_runtime_resume(struct device *dev)
+{
+ struct coda_dev *cdev = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (dev->pm_domain) {
+ ret = coda_hw_init(cdev);
+ if (ret)
+ v4l2_err(&cdev->v4l2_dev, "HW initialization failed\n");
+ }
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops coda_pm_ops = {
+ SET_RUNTIME_PM_OPS(NULL, coda_runtime_resume, NULL)
+};
+
static struct platform_driver coda_driver = {
.probe = coda_probe,
.remove = coda_remove,
@@ -3336,6 +3921,7 @@ static struct platform_driver coda_driver = {
.name = CODA_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(coda_dt_ids),
+ .pm = &coda_pm_ops,
},
.id_table = coda_platform_ids,
};
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
index 4e32e2edea62..c791275e307b 100644
--- a/drivers/media/platform/coda.h
+++ b/drivers/media/platform/coda.h
@@ -27,6 +27,14 @@
#define CODA_REG_BIT_CODE_RESET 0x014
#define CODA_REG_RESET_ENABLE (1 << 0)
#define CODA_REG_BIT_CUR_PC 0x018
+#define CODA9_REG_BIT_SW_RESET 0x024
+#define CODA9_SW_RESET_BPU_CORE 0x008
+#define CODA9_SW_RESET_BPU_BUS 0x010
+#define CODA9_SW_RESET_VCE_CORE 0x020
+#define CODA9_SW_RESET_VCE_BUS 0x040
+#define CODA9_SW_RESET_GDI_CORE 0x080
+#define CODA9_SW_RESET_GDI_BUS 0x100
+#define CODA9_REG_BIT_SW_RESET_STATUS 0x034
/* Static SW registers */
#define CODA_REG_BIT_CODE_BUF_ADDR 0x100
@@ -39,9 +47,11 @@
#define CODADX6_STREAM_BUF_PIC_FLUSH (1 << 2)
#define CODA7_STREAM_BUF_DYNALLOC_EN (1 << 5)
#define CODADX6_STREAM_BUF_DYNALLOC_EN (1 << 4)
-#define CODA_STREAM_CHKDIS_OFFSET (1 << 1)
+#define CODADX6_STREAM_CHKDIS_OFFSET (1 << 1)
+#define CODA7_STREAM_SEL_64BITS_ENDIAN (1 << 1)
#define CODA_STREAM_ENDIAN_SELECT (1 << 0)
#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110
+#define CODA_FRAME_CHROMA_INTERLEAVE (1 << 2)
#define CODA_IMAGE_ENDIAN_SELECT (1 << 0)
#define CODA_REG_BIT_BIT_STREAM_PARAM 0x114
#define CODA_BIT_STREAM_END_FLAG (1 << 2)
@@ -52,13 +62,21 @@
#define CODA_REG_BIT_FRM_DIS_FLG(x) (0x150 + 4 * (x))
#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR 0x140
#define CODA7_REG_BIT_AXI_SRAM_USE 0x140
+#define CODA9_USE_HOST_BTP_ENABLE (1 << 13)
+#define CODA9_USE_HOST_OVL_ENABLE (1 << 12)
#define CODA7_USE_HOST_ME_ENABLE (1 << 11)
+#define CODA9_USE_HOST_DBK_ENABLE (3 << 10)
#define CODA7_USE_HOST_OVL_ENABLE (1 << 10)
#define CODA7_USE_HOST_DBK_ENABLE (1 << 9)
+#define CODA9_USE_HOST_IP_ENABLE (1 << 9)
#define CODA7_USE_HOST_IP_ENABLE (1 << 8)
+#define CODA9_USE_HOST_BIT_ENABLE (1 << 8)
#define CODA7_USE_HOST_BIT_ENABLE (1 << 7)
+#define CODA9_USE_BTP_ENABLE (1 << 5)
#define CODA7_USE_ME_ENABLE (1 << 4)
+#define CODA9_USE_OVL_ENABLE (1 << 4)
#define CODA7_USE_OVL_ENABLE (1 << 3)
+#define CODA9_USE_DBK_ENABLE (3 << 2)
#define CODA7_USE_DBK_ENABLE (1 << 2)
#define CODA7_USE_IP_ENABLE (1 << 1)
#define CODA7_USE_BIT_ENABLE (1 << 0)
@@ -93,6 +111,18 @@
#define CODA7_MODE_ENCODE_H264 8
#define CODA7_MODE_ENCODE_MP4 11
#define CODA7_MODE_ENCODE_MJPG 13
+#define CODA9_MODE_DECODE_H264 0
+#define CODA9_MODE_DECODE_VC1 1
+#define CODA9_MODE_DECODE_MP2 2
+#define CODA9_MODE_DECODE_MP4 3
+#define CODA9_MODE_DECODE_DV3 3
+#define CODA9_MODE_DECODE_RV 4
+#define CODA9_MODE_DECODE_AVS 5
+#define CODA9_MODE_DECODE_MJPG 6
+#define CODA9_MODE_DECODE_VPX 7
+#define CODA9_MODE_ENCODE_H264 8
+#define CODA9_MODE_ENCODE_MP4 11
+#define CODA9_MODE_ENCODE_MJPG 13
#define CODA_MODE_INVALID 0xffff
#define CODA_REG_BIT_INT_ENABLE 0x170
#define CODA_INT_INTERRUPT_ENABLE (1 << 3)
@@ -129,6 +159,7 @@
#define CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE 0x1a0
#define CODA7_RET_DEC_SEQ_ASPECT 0x1b0
+#define CODA9_RET_DEC_SEQ_BITRATE 0x1b4
#define CODA_RET_DEC_SEQ_SUCCESS 0x1c0
#define CODA_RET_DEC_SEQ_SRC_FMT 0x1c4 /* SRC_SIZE on CODA7 */
#define CODA_RET_DEC_SEQ_SRC_SIZE 0x1c4
@@ -145,13 +176,19 @@
#define CODA_RET_DEC_SEQ_FRATE_DR 0x1e8
#define CODA_RET_DEC_SEQ_JPG_PARA 0x1e4
#define CODA_RET_DEC_SEQ_JPG_THUMB_IND 0x1e8
+#define CODA9_RET_DEC_SEQ_HEADER_REPORT 0x1ec
/* Decoder Picture Run */
#define CODA_CMD_DEC_PIC_ROT_MODE 0x180
#define CODA_CMD_DEC_PIC_ROT_ADDR_Y 0x184
+#define CODA9_CMD_DEC_PIC_ROT_INDEX 0x184
#define CODA_CMD_DEC_PIC_ROT_ADDR_CB 0x188
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_Y 0x188
#define CODA_CMD_DEC_PIC_ROT_ADDR_CR 0x18c
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_CB 0x18c
#define CODA_CMD_DEC_PIC_ROT_STRIDE 0x190
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_CR 0x190
+#define CODA9_CMD_DEC_PIC_ROT_STRIDE 0x1b8
#define CODA_CMD_DEC_PIC_OPTION 0x194
#define CODA_PRE_SCAN_EN (1 << 0)
@@ -183,25 +220,39 @@
#define CODA_RET_DEC_PIC_CROP_TOP_BOTTOM 0x1e4
#define CODA_RET_DEC_PIC_FRAME_NEED 0x1ec
+#define CODA9_RET_DEC_PIC_VP8_PIC_REPORT 0x1e8
+#define CODA9_RET_DEC_PIC_ASPECT 0x1f0
+#define CODA9_RET_DEC_PIC_VP8_SCALE_INFO 0x1f0
+#define CODA9_RET_DEC_PIC_FRATE_NR 0x1f4
+#define CODA9_RET_DEC_PIC_FRATE_DR 0x1f8
+
/* Encoder Sequence Initialization */
#define CODA_CMD_ENC_SEQ_BB_START 0x180
#define CODA_CMD_ENC_SEQ_BB_SIZE 0x184
#define CODA_CMD_ENC_SEQ_OPTION 0x188
#define CODA7_OPTION_AVCINTRA16X16ONLY_OFFSET 9
+#define CODA9_OPTION_MVC_PREFIX_NAL_OFFSET 9
#define CODA7_OPTION_GAMMA_OFFSET 8
+#define CODA9_OPTION_MVC_PARASET_REFRESH_OFFSET 8
#define CODA7_OPTION_RCQPMAX_OFFSET 7
+#define CODA9_OPTION_GAMMA_OFFSET 7
#define CODADX6_OPTION_GAMMA_OFFSET 7
#define CODA7_OPTION_RCQPMIN_OFFSET 6
+#define CODA9_OPTION_RCQPMAX_OFFSET 6
#define CODA_OPTION_LIMITQP_OFFSET 6
#define CODA_OPTION_RCINTRAQP_OFFSET 5
#define CODA_OPTION_FMO_OFFSET 4
+#define CODA9_OPTION_MVC_INTERVIEW_OFFSET 4
#define CODA_OPTION_AVC_AUD_OFFSET 2
#define CODA_OPTION_SLICEREPORT_OFFSET 1
#define CODA_CMD_ENC_SEQ_COD_STD 0x18c
#define CODA_STD_MPEG4 0
+#define CODA9_STD_H264 0
#define CODA_STD_H263 1
#define CODA_STD_H264 2
#define CODA_STD_MJPG 3
+#define CODA9_STD_MPEG4 3
+
#define CODA_CMD_ENC_SEQ_SRC_SIZE 0x190
#define CODA7_PICWIDTH_OFFSET 16
#define CODA7_PICWIDTH_MASK 0xffff
@@ -268,15 +319,26 @@
#define CODA7_CMD_ENC_SEQ_SEARCH_BASE 0x1b8
#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE 0x1bc
#define CODA7_CMD_ENC_SEQ_INTRA_QP 0x1c4
-#define CODA_CMD_ENC_SEQ_RC_QP_MAX 0x1c8
+#define CODA_CMD_ENC_SEQ_RC_QP_MIN_MAX 0x1c8
+#define CODA_QPMIN_OFFSET 8
+#define CODA_QPMIN_MASK 0x3f
#define CODA_QPMAX_OFFSET 0
#define CODA_QPMAX_MASK 0x3f
#define CODA_CMD_ENC_SEQ_RC_GAMMA 0x1cc
#define CODA_GAMMA_OFFSET 0
#define CODA_GAMMA_MASK 0xffff
+#define CODA_CMD_ENC_SEQ_RC_INTERVAL_MODE 0x1d0
+#define CODA9_CMD_ENC_SEQ_INTRA_WEIGHT 0x1d4
+#define CODA9_CMD_ENC_SEQ_ME_OPTION 0x1d8
#define CODA_RET_ENC_SEQ_SUCCESS 0x1c0
/* Encoder Picture Run */
+#define CODA9_CMD_ENC_PIC_SRC_INDEX 0x180
+#define CODA9_CMD_ENC_PIC_SRC_STRIDE 0x184
+#define CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC 0x1a4
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_Y 0x1a8
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_CB 0x1ac
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_CR 0x1b0
#define CODA_CMD_ENC_PIC_SRC_ADDR_Y 0x180
#define CODA_CMD_ENC_PIC_SRC_ADDR_CB 0x184
#define CODA_CMD_ENC_PIC_SRC_ADDR_CR 0x188
@@ -291,7 +353,11 @@
#define CODA_MIR_VER (0x1 << 2)
#define CODA_MIR_HOR (0x2 << 2)
#define CODA_MIR_VER_HOR (0x3 << 2)
-#define CODA_CMD_ENC_PIC_OPTION 0x194
+#define CODA_CMD_ENC_PIC_OPTION 0x194
+#define CODA_FORCE_IPICTURE BIT(1)
+#define CODA_REPORT_MB_INFO BIT(3)
+#define CODA_REPORT_MV_INFO BIT(4)
+#define CODA_REPORT_SLICE_INFO BIT(5)
#define CODA_CMD_ENC_PIC_BB_START 0x198
#define CODA_CMD_ENC_PIC_BB_SIZE 0x19c
#define CODA_RET_ENC_FRAME_NUM 0x1c0
@@ -306,13 +372,30 @@
#define CODA_CMD_SET_FRAME_BUF_STRIDE 0x184
#define CODA_CMD_SET_FRAME_SLICE_BB_START 0x188
#define CODA_CMD_SET_FRAME_SLICE_BB_SIZE 0x18c
+#define CODA9_CMD_SET_FRAME_SUBSAMP_A 0x188
+#define CODA9_CMD_SET_FRAME_SUBSAMP_B 0x18c
#define CODA7_CMD_SET_FRAME_AXI_BIT_ADDR 0x190
#define CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR 0x194
#define CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR 0x198
#define CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR 0x19c
#define CODA7_CMD_SET_FRAME_AXI_OVL_ADDR 0x1a0
#define CODA7_CMD_SET_FRAME_MAX_DEC_SIZE 0x1a4
+#define CODA9_CMD_SET_FRAME_AXI_BTP_ADDR 0x1a4
#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE 0x1a8
+#define CODA9_CMD_SET_FRAME_CACHE_SIZE 0x1a8
+#define CODA9_CMD_SET_FRAME_CACHE_CONFIG 0x1ac
+#define CODA9_CACHE_BYPASS_OFFSET 28
+#define CODA9_CACHE_DUALCONF_OFFSET 26
+#define CODA9_CACHE_PAGEMERGE_OFFSET 24
+#define CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET 16
+#define CODA9_CACHE_CB_BUFFER_SIZE_OFFSET 8
+#define CODA9_CACHE_CR_BUFFER_SIZE_OFFSET 0
+#define CODA9_CMD_SET_FRAME_SUBSAMP_A_MVC 0x1b0
+#define CODA9_CMD_SET_FRAME_SUBSAMP_B_MVC 0x1b4
+#define CODA9_CMD_SET_FRAME_DP_BUF_BASE 0x1b0
+#define CODA9_CMD_SET_FRAME_DP_BUF_SIZE 0x1b4
+#define CODA9_CMD_SET_FRAME_MAX_DEC_SIZE 0x1b8
+#define CODA9_CMD_SET_FRAME_DELAY 0x1bc
/* Encoder Header */
#define CODA_CMD_ENC_HEADER_CODE 0x180
@@ -322,8 +405,11 @@
#define CODA_HEADER_MP4V_VOL 0
#define CODA_HEADER_MP4V_VOS 1
#define CODA_HEADER_MP4V_VIS 2
+#define CODA9_HEADER_FRAME_CROP (1 << 3)
#define CODA_CMD_ENC_HEADER_BB_START 0x184
#define CODA_CMD_ENC_HEADER_BB_SIZE 0x188
+#define CODA9_CMD_ENC_HEADER_FRAME_CROP_H 0x18c
+#define CODA9_CMD_ENC_HEADER_FRAME_CROP_V 0x190
/* Get Version */
#define CODA_CMD_FIRMWARE_VERNUM 0x1c0
@@ -334,5 +420,28 @@
#define CODA_FIRMWARE_VERNUM(product, major, minor, release) \
((product) << 16 | ((major) << 12) | \
((minor) << 8) | (release))
+#define CODA9_CMD_FIRMWARE_CODE_REV 0x1c4
+
+#define CODA9_GDMA_BASE 0x1000
+#define CODA9_GDI_WPROT_ERR_CLR (CODA9_GDMA_BASE + 0x0a0)
+#define CODA9_GDI_WPROT_RGN_EN (CODA9_GDMA_BASE + 0x0ac)
+
+#define CODA9_GDI_BUS_CTRL (CODA9_GDMA_BASE + 0x0f0)
+#define CODA9_GDI_BUS_STATUS (CODA9_GDMA_BASE + 0x0f4)
+
+#define CODA9_GDI_XY2_CAS_0 (CODA9_GDMA_BASE + 0x800)
+#define CODA9_GDI_XY2_CAS_F (CODA9_GDMA_BASE + 0x83c)
+
+#define CODA9_GDI_XY2_BA_0 (CODA9_GDMA_BASE + 0x840)
+#define CODA9_GDI_XY2_BA_1 (CODA9_GDMA_BASE + 0x844)
+#define CODA9_GDI_XY2_BA_2 (CODA9_GDMA_BASE + 0x848)
+#define CODA9_GDI_XY2_BA_3 (CODA9_GDMA_BASE + 0x84c)
+
+#define CODA9_GDI_XY2_RAS_0 (CODA9_GDMA_BASE + 0x850)
+#define CODA9_GDI_XY2_RAS_F (CODA9_GDMA_BASE + 0x88c)
+
+#define CODA9_GDI_XY2_RBC_CONFIG (CODA9_GDMA_BASE + 0x890)
+#define CODA9_GDI_RBC2_AXI_0 (CODA9_GDMA_BASE + 0x8a0)
+#define CODA9_GDI_RBC2_AXI_1F (CODA9_GDMA_BASE + 0x91c)
#endif
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 30fa08405d61..07e98df3d867 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -581,13 +581,8 @@ void ccdc_config_raw(void)
config_params->alaw.enable)
syn_mode |= CCDC_DATA_PACK_ENABLE;
-#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
- /* enable video port */
- val = CCDC_ENABLE_VIDEO_PORT;
-#else
/* disable video port */
val = CCDC_DISABLE_VIDEO_PORT;
-#endif
if (config_params->data_sz == CCDC_DATA_8BITS)
val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index bf5eff99452b..73496d953ba0 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -1709,7 +1709,6 @@ static int register_device(struct vpbe_layer *vpbe_display_layer,
vpbe_display_layer->disp_dev = disp_dev;
/* set the driver data in platform device */
platform_set_drvdata(pdev, disp_dev);
- set_bit(V4L2_FL_USE_FH_PRIO, &vpbe_display_layer->video_dev.flags);
video_set_drvdata(&vpbe_display_layer->video_dev,
vpbe_display_layer);
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index a51bda2fb637..ea7661a27479 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1916,7 +1916,6 @@ static int vpfe_probe(struct platform_device *pdev)
v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
"video_dev=%x\n", (int)&vpfe_dev->video_dev);
vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- set_bit(V4L2_FL_USE_FH_PRIO, &vpfe_dev->video_dev->flags);
ret = video_register_device(vpfe_dev->video_dev,
VFL_TYPE_GRABBER, -1);
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index a7ed16497903..b054b7eec53d 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -39,32 +39,10 @@ MODULE_VERSION(VPIF_CAPTURE_VERSION);
v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
static int debug = 1;
-static u32 ch0_numbuffers = 3;
-static u32 ch1_numbuffers = 3;
-static u32 ch0_bufsize = 1920 * 1080 * 2;
-static u32 ch1_bufsize = 720 * 576 * 2;
module_param(debug, int, 0644);
-module_param(ch0_numbuffers, uint, S_IRUGO);
-module_param(ch1_numbuffers, uint, S_IRUGO);
-module_param(ch0_bufsize, uint, S_IRUGO);
-module_param(ch1_bufsize, uint, S_IRUGO);
MODULE_PARM_DESC(debug, "Debug level 0-1");
-MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
-MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
-MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
-MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
-
-static struct vpif_config_params config_params = {
- .min_numbuffers = 3,
- .numbuffers[0] = 3,
- .numbuffers[1] = 3,
- .min_bufsize[0] = 720 * 480 * 2,
- .min_bufsize[1] = 720 * 480 * 2,
- .channel_bufsize[0] = 1920 * 1080 * 2,
- .channel_bufsize[1] = 720 * 576 * 2,
-};
#define VPIF_DRIVER_NAME "vpif_capture"
@@ -269,6 +247,7 @@ err:
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
}
+ spin_unlock_irqrestore(&common->irqlock, flags);
return ret;
}
@@ -520,10 +499,28 @@ static int vpif_update_std_info(struct channel_obj *ch)
common->width = std_info->width;
common->fmt.fmt.pix.height = std_info->height;
common->height = std_info->height;
+ common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
common->fmt.fmt.pix.bytesperline = std_info->width;
vpifparams->video_params.hpitch = std_info->width;
vpifparams->video_params.storage_mode = std_info->frm_fmt;
+ if (vid_ch->stdid)
+ common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ else
+ common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+
+ if (ch->vpifparams.std_info.frm_fmt)
+ common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+ else
+ common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
+ common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+ else
+ common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+
+ common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
return 0;
}
@@ -600,27 +597,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
}
/**
- * vpif_config_format: configure default frame format in the device
- * ch : ptr to channel object
- */
-static void vpif_config_format(struct channel_obj *ch)
-{
- struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
-
- vpif_dbg(2, debug, "vpif_config_format\n");
-
- common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
- common->fmt.fmt.pix.sizeimage
- = config_params.channel_bufsize[ch->channel_id];
-
- if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
- common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
- else
- common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
- common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-}
-
-/**
* vpif_get_default_field() - Get default field type based on interface
* @vpif_params - ptr to vpif params
*/
@@ -632,112 +608,6 @@ static inline enum v4l2_field vpif_get_default_field(
}
/**
- * vpif_check_format() - check given pixel format for compatibility
- * @ch - channel ptr
- * @pixfmt - Given pixel format
- * @update - update the values as per hardware requirement
- *
- * Check the application pixel format for S_FMT and update the input
- * values as per hardware limits for TRY_FMT. The default pixel and
- * field format is selected based on interface type.
- */
-static int vpif_check_format(struct channel_obj *ch,
- struct v4l2_pix_format *pixfmt,
- int update)
-{
- struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
- struct vpif_params *vpif_params = &ch->vpifparams;
- enum v4l2_field field = pixfmt->field;
- u32 sizeimage, hpitch, vpitch;
- int ret = -EINVAL;
-
- vpif_dbg(2, debug, "vpif_check_format\n");
- /**
- * first check for the pixel format. If if_type is Raw bayer,
- * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
- * V4L2_PIX_FMT_YUV422P is supported
- */
- if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
- if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pix format\n");
- goto exit;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
- }
- } else {
- if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pixel format\n");
- goto exit;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
- }
- }
-
- if (!(VPIF_VALID_FIELD(field))) {
- if (!update) {
- vpif_dbg(2, debug, "invalid field format\n");
- goto exit;
- }
- /**
- * By default use FIELD_NONE for RAW Bayer capture
- * and FIELD_INTERLACED for other interfaces
- */
- field = vpif_get_default_field(&vpif_params->iface);
- } else if (field == V4L2_FIELD_ANY)
- /* unsupported field. Use default */
- field = vpif_get_default_field(&vpif_params->iface);
-
- /* validate the hpitch */
- hpitch = pixfmt->bytesperline;
- if (hpitch < vpif_params->std_info.width) {
- if (!update) {
- vpif_dbg(2, debug, "invalid hpitch\n");
- goto exit;
- }
- hpitch = vpif_params->std_info.width;
- }
-
- sizeimage = pixfmt->sizeimage;
-
- vpitch = sizeimage / (hpitch * 2);
-
- /* validate the vpitch */
- if (vpitch < vpif_params->std_info.height) {
- if (!update) {
- vpif_dbg(2, debug, "Invalid vpitch\n");
- goto exit;
- }
- vpitch = vpif_params->std_info.height;
- }
-
- /* Check for 8 byte alignment */
- if (!ALIGN(hpitch, 8)) {
- if (!update) {
- vpif_dbg(2, debug, "invalid pitch alignment\n");
- goto exit;
- }
- /* adjust to next 8 byte boundary */
- hpitch = (((hpitch + 7) / 8) * 8);
- }
- /* if update is set, modify the bytesperline and sizeimage */
- if (update) {
- pixfmt->bytesperline = hpitch;
- pixfmt->sizeimage = hpitch * vpitch * 2;
- }
- /**
- * Image width and height is always based on current standard width and
- * height
- */
- pixfmt->width = common->fmt.fmt.pix.width;
- pixfmt->height = common->fmt.fmt.pix.height;
- return 0;
-exit:
- return ret;
-}
-
-/**
* vpif_config_addr() - function to configure buffer address in vpif
* @ch - channel ptr
* @muxmode - channel mux mode
@@ -947,9 +817,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
return -EINVAL;
}
- /* Configure the default format information */
- vpif_config_format(ch);
-
/* set standard in the sub device */
ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
@@ -976,10 +843,8 @@ static int vpif_enum_input(struct file *file, void *priv,
chan_cfg = &config->chan_config[ch->channel_id];
- if (input->index >= chan_cfg->input_count) {
- vpif_dbg(1, debug, "Invalid input index\n");
+ if (input->index >= chan_cfg->input_count)
return -EINVAL;
- }
memcpy(input, &chan_cfg->inputs[input->index].input,
sizeof(*input));
@@ -1068,8 +933,34 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
struct video_device *vdev = video_devdata(file);
struct channel_obj *ch = video_get_drvdata(vdev);
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+ struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+ struct vpif_params *vpif_params = &ch->vpifparams;
- return vpif_check_format(ch, pixfmt, 1);
+ /*
+ * to supress v4l-compliance warnings silently correct
+ * the pixelformat
+ */
+ if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
+ if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8)
+ pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
+ } else {
+ if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
+ pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+ }
+
+ common->fmt.fmt.pix.pixelformat = pixfmt->pixelformat;
+
+ vpif_update_std_info(ch);
+
+ pixfmt->field = common->fmt.fmt.pix.field;
+ pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
+ pixfmt->bytesperline = common->fmt.fmt.pix.width;
+ pixfmt->width = common->fmt.fmt.pix.width;
+ pixfmt->height = common->fmt.fmt.pix.height;
+ pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
+ pixfmt->priv = 0;
+
+ return 0;
}
@@ -1107,20 +998,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
struct video_device *vdev = video_devdata(file);
struct channel_obj *ch = video_get_drvdata(vdev);
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
- struct v4l2_pix_format *pixfmt;
- int ret = 0;
+ int ret;
vpif_dbg(2, debug, "%s\n", __func__);
if (vb2_is_busy(&common->buffer_queue))
return -EBUSY;
- pixfmt = &fmt->fmt.pix;
- /* Check for valid field format */
- ret = vpif_check_format(ch, pixfmt, 0);
-
+ ret = vpif_try_fmt_vid_cap(file, priv, fmt);
if (ret)
return ret;
+
/* store the format in the channel object */
common->fmt = *fmt;
return 0;
@@ -1410,36 +1298,9 @@ static struct v4l2_file_operations vpif_fops = {
*/
static int initialize_vpif(void)
{
- int err = 0, i, j;
+ int err, i, j;
int free_channel_objects_index;
- /* Default number of buffers should be 3 */
- if ((ch0_numbuffers > 0) &&
- (ch0_numbuffers < config_params.min_numbuffers))
- ch0_numbuffers = config_params.min_numbuffers;
- if ((ch1_numbuffers > 0) &&
- (ch1_numbuffers < config_params.min_numbuffers))
- ch1_numbuffers = config_params.min_numbuffers;
-
- /* Set buffer size to min buffers size if it is invalid */
- if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
- ch0_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
- if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
- ch1_bufsize =
- config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
-
- config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
- config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
- if (ch0_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
- = ch0_bufsize;
- }
- if (ch1_numbuffers) {
- config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
- = ch1_bufsize;
- }
-
/* Allocate memory for six channel objects */
for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
vpif_obj.dev[i] =
@@ -1495,6 +1356,11 @@ static int vpif_probe_complete(void)
if (err)
goto probe_out;
+ /* set initial format */
+ ch->video.stdid = V4L2_STD_525_60;
+ memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
+ vpif_update_std_info(ch);
+
/* Initialize vb2 queue */
q = &common->buffer_queue;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1532,7 +1398,6 @@ static int vpif_probe_complete(void)
vdev->vfl_dir = VFL_DIR_RX;
vdev->queue = q;
vdev->lock = &common->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
video_set_drvdata(ch->video_dev, ch);
err = video_register_device(vdev,
VFL_TYPE_GRABBER, (j ? 1 : 0));
@@ -1713,7 +1578,7 @@ static int vpif_remove(struct platform_device *device)
for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
- common = &ch->common[i];
+ common = &ch->common[VPIF_VIDEO_INDEX];
vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
/* Unregister video device */
video_unregister_device(ch->video_dev);
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 1ee17824f484..f65d28d38e66 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -119,15 +119,4 @@ struct vpif_device {
struct vpif_capture_config *config;
};
-struct vpif_config_params {
- u8 min_numbuffers;
- u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
- s8 device_type;
- u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
- u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
- u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
- u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
- u8 max_device_type;
-};
-
#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 5bb085b19bcb..a03ec7381cfe 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -233,6 +233,7 @@ err:
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
}
+ spin_unlock_irqrestore(&common->irqlock, flags);
return ret;
}
@@ -648,7 +649,6 @@ static int vpif_try_fmt_vid_out(struct file *file, void *priv,
pixfmt->width = common->fmt.fmt.pix.width;
pixfmt->height = common->fmt.fmt.pix.height;
pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
- pixfmt->priv = 0;
return 0;
}
@@ -1223,7 +1223,6 @@ static int vpif_probe_complete(void)
vdev->vfl_dir = VFL_DIR_TX;
vdev->queue = q;
vdev->lock = &common->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
video_set_drvdata(ch->video_dev, ch);
err = video_register_device(vdev, VFL_TYPE_GRABBER,
(j ? 3 : 2));
@@ -1387,7 +1386,7 @@ static int vpif_remove(struct platform_device *device)
for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
- common = &ch->common[i];
+ common = &ch->common[VPIF_VIDEO_INDEX];
vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
/* Unregister video device */
video_unregister_device(ch->video_dev);
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index c21d14fd61db..d36c507a0ba2 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -1002,7 +1002,7 @@ static int deinterlace_probe(struct platform_device *pdev)
dma_cap_mask_t mask;
int ret = 0;
- pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
+ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
if (!pcdev)
return -ENOMEM;
@@ -1012,7 +1012,7 @@ static int deinterlace_probe(struct platform_device *pdev)
dma_cap_set(DMA_INTERLEAVE, mask);
pcdev->dma_chan = dma_request_channel(mask, NULL, pcdev);
if (!pcdev->dma_chan)
- goto free_dev;
+ return -ENODEV;
if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) {
v4l2_err(&pcdev->v4l2_dev, "DMA does not support INTERLEAVE\n");
@@ -1078,8 +1078,6 @@ unreg_dev:
v4l2_device_unregister(&pcdev->v4l2_dev);
rel_dma:
dma_release_channel(pcdev->dma_chan);
-free_dev:
- kfree(pcdev);
return ret;
}
@@ -1094,7 +1092,6 @@ static int deinterlace_remove(struct platform_device *pdev)
v4l2_device_unregister(&pcdev->v4l2_dev);
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
dma_release_channel(pcdev->dma_chan);
- kfree(pcdev);
return 0;
}
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index 0714070ed7fa..c1b03cfd6ded 100644
--- a/drivers/media/platform/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -532,7 +532,6 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.priv = 0;
return 0;
}
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 9a726eacb29b..2d177fa58471 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -165,7 +165,6 @@ static int omap_vout_try_format(struct v4l2_pix_format *pix)
pix->pixelformat = omap_formats[ifmt].pixelformat;
pix->field = V4L2_FIELD_ANY;
- pix->priv = 0;
switch (pix->pixelformat) {
case V4L2_PIX_FMT_YUYV:
@@ -1896,7 +1895,6 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
pix->field = V4L2_FIELD_ANY;
pix->bytesperline = pix->width * 2;
pix->sizeimage = pix->bytesperline * pix->height;
- pix->priv = 0;
pix->colorspace = V4L2_COLORSPACE_JPEG;
vout->bpp = RGB565_BPP;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index deba425e3d8f..f33641384e15 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1172,7 +1172,6 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
goto err_vd_rel;
video_set_drvdata(vfd, vp);
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
v4l2_ctrl_handler_init(&vp->ctrl_handler, 1);
ctrl = v4l2_ctrl_new_std(&vp->ctrl_handler, &s3c_camif_video_ctrl_ops,
@@ -1271,6 +1270,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
}
mutex_unlock(&camif->lock);
+ mf->field = V4L2_FIELD_NONE;
mf->colorspace = V4L2_COLORSPACE_JPEG;
return 0;
}
@@ -1319,6 +1319,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %ux%u\n",
fmt->pad, mf->code, mf->width, mf->height);
+ mf->field = V4L2_FIELD_NONE;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mutex_lock(&camif->lock);
diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile
index a1a9169254c3..9e5f214c4667 100644
--- a/drivers/media/platform/s5p-jpeg/Makefile
+++ b/drivers/media/platform/s5p-jpeg/Makefile
@@ -1,2 +1,2 @@
-s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos4.o jpeg-hw-s5p.o
+s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos3250.o jpeg-hw-exynos4.o jpeg-hw-s5p.o
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index 0dcb796ecad9..e66acbc2a82d 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -1,6 +1,6 @@
/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
*
- * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
@@ -32,6 +32,7 @@
#include "jpeg-core.h"
#include "jpeg-hw-s5p.h"
#include "jpeg-hw-exynos4.h"
+#include "jpeg-hw-exynos3250.h"
#include "jpeg-regs.h"
static struct s5p_jpeg_fmt sjpeg_formats[] = {
@@ -41,6 +42,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
SJPEG_FMT_FLAG_DEC_OUTPUT |
SJPEG_FMT_FLAG_S5P |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
SJPEG_FMT_FLAG_EXYNOS4,
},
{
@@ -70,6 +72,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
},
{
+ .name = "YUV 4:2:2 packed, YCbYCr",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
+ },
+ {
.name = "YUV 4:2:2 packed, YCrYCb",
.fourcc = V4L2_PIX_FMT_YVYU,
.depth = 16,
@@ -83,6 +98,45 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
},
{
+ .name = "YUV 4:2:2 packed, YCrYCb",
+ .fourcc = V4L2_PIX_FMT_YVYU,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
+ },
+ {
+ .name = "YUV 4:2:2 packed, YCrYCb",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
+ },
+ {
+ .name = "YUV 4:2:2 packed, YCrYCb",
+ .fourcc = V4L2_PIX_FMT_VYUY,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
+ },
+ {
.name = "RGB565",
.fourcc = V4L2_PIX_FMT_RGB565,
.depth = 16,
@@ -100,6 +154,32 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.fourcc = V4L2_PIX_FMT_RGB565,
.depth = 16,
.colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
+ },
+ {
+ .name = "RGB565X",
+ .fourcc = V4L2_PIX_FMT_RGB565X,
+ .depth = 16,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
+ },
+ {
+ .name = "RGB565",
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .depth = 16,
+ .colplanes = 1,
.h_align = 0,
.v_align = 0,
.flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
@@ -121,6 +201,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
},
{
+ .name = "ARGB8888, 32 bpp",
+ .fourcc = V4L2_PIX_FMT_RGB32,
+ .depth = 32,
+ .colplanes = 1,
+ .h_align = 2,
+ .v_align = 0,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
+ },
+ {
.name = "YUV 4:4:4 planar, Y/CbCr",
.fourcc = V4L2_PIX_FMT_NV24,
.depth = 24,
@@ -190,9 +283,23 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.fourcc = V4L2_PIX_FMT_NV12,
.depth = 12,
.colplanes = 2,
+ .h_align = 3,
+ .v_align = 3,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
+ },
+ {
+ .name = "YUV 4:2:0 planar, Y/CbCr",
+ .fourcc = V4L2_PIX_FMT_NV12,
+ .depth = 12,
+ .colplanes = 2,
.h_align = 4,
.v_align = 4,
- .flags = SJPEG_FMT_FLAG_DEC_CAPTURE |
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
SJPEG_FMT_FLAG_S5P |
SJPEG_FMT_NON_RGB,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
@@ -202,10 +309,24 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.fourcc = V4L2_PIX_FMT_NV21,
.depth = 12,
.colplanes = 2,
+ .h_align = 3,
+ .v_align = 3,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
+ },
+ {
+ .name = "YUV 4:2:0 planar, Y/CrCb",
+ .fourcc = V4L2_PIX_FMT_NV21,
+ .depth = 12,
+ .colplanes = 2,
.h_align = 1,
.v_align = 1,
.flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
SJPEG_FMT_FLAG_EXYNOS4 |
SJPEG_FMT_NON_RGB,
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
@@ -224,6 +345,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = {
.subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
},
{
+ .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .depth = 12,
+ .colplanes = 3,
+ .h_align = 4,
+ .v_align = 4,
+ .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
+ SJPEG_FMT_FLAG_DEC_CAPTURE |
+ SJPEG_FMT_FLAG_EXYNOS3250 |
+ SJPEG_FMT_NON_RGB,
+ .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
+ },
+ {
.name = "Gray",
.fourcc = V4L2_PIX_FMT_GREY,
.depth = 8,
@@ -457,6 +591,16 @@ static int exynos4x12_decoded_subsampling[] = {
V4L2_JPEG_CHROMA_SUBSAMPLING_420,
};
+static int exynos3250_decoded_subsampling[] = {
+ V4L2_JPEG_CHROMA_SUBSAMPLING_444,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_422,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_420,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
+ -1,
+ -1,
+ V4L2_JPEG_CHROMA_SUBSAMPLING_411,
+};
+
static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
{
return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
@@ -471,14 +615,21 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
{
WARN_ON(ctx->subsampling > 3);
- if (ctx->jpeg->variant->version == SJPEG_S5P) {
+ switch (ctx->jpeg->variant->version) {
+ case SJPEG_S5P:
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
return ctx->subsampling;
- } else {
+ case SJPEG_EXYNOS3250:
+ if (ctx->subsampling > 3)
+ return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
+ return exynos3250_decoded_subsampling[ctx->subsampling];
+ case SJPEG_EXYNOS4:
if (ctx->subsampling > 2)
return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
return exynos4x12_decoded_subsampling[ctx->subsampling];
+ default:
+ return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
}
}
@@ -646,6 +797,7 @@ static int s5p_jpeg_open(struct file *file)
FMT_TYPE_OUTPUT);
cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
FMT_TYPE_CAPTURE);
+ ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
}
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
@@ -754,14 +906,14 @@ static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
while (notfound) {
c = get_byte(&jpeg_buffer);
if (c == -1)
- break;
+ return false;
if (c != 0xff)
continue;
do
c = get_byte(&jpeg_buffer);
while (c == 0xff);
if (c == -1)
- break;
+ return false;
if (c == 0)
continue;
length = 0;
@@ -981,7 +1133,8 @@ static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
return NULL;
}
-static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
+static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
+ u32 *w, unsigned int wmin, unsigned int wmax,
unsigned int walign,
u32 *h, unsigned int hmin, unsigned int hmax,
unsigned int halign)
@@ -993,13 +1146,27 @@ static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
w_step = 1 << walign;
h_step = 1 << halign;
+
+ if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) {
+ /*
+ * Rightmost and bottommost pixels are cropped by the
+ * Exynos3250 JPEG IP for RGB formats, for the specific
+ * width and height values respectively. This assignment
+ * will result in v4l_bound_align_image returning dimensions
+ * reduced by 1 for the aforementioned cases.
+ */
+ if (w_step == 4 && ((width & 3) == 1)) {
+ wmax = width;
+ hmax = height;
+ }
+ }
+
v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
if (*w < width && (*w + w_step) < wmax)
*w += w_step;
if (*h < height && (*h + h_step) < hmax)
*h += h_step;
-
}
static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
@@ -1015,12 +1182,12 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
/* V4L2 specification suggests the driver corrects the format struct
* if any of the dimensions is unsupported */
if (q_type == FMT_TYPE_OUTPUT)
- jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
+ jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
S5P_JPEG_MAX_WIDTH, 0,
&pix->height, S5P_JPEG_MIN_HEIGHT,
S5P_JPEG_MAX_HEIGHT, 0);
else
- jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
+ jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
S5P_JPEG_MAX_WIDTH, fmt->h_align,
&pix->height, S5P_JPEG_MIN_HEIGHT,
S5P_JPEG_MAX_HEIGHT, fmt->v_align);
@@ -1142,7 +1309,7 @@ static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
else
wh_align = 1;
- jpeg_bound_align_image(&w, S5P_JPEG_MIN_WIDTH,
+ jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
S5P_JPEG_MAX_WIDTH, wh_align,
&h, S5P_JPEG_MIN_HEIGHT,
S5P_JPEG_MAX_HEIGHT, wh_align);
@@ -1150,12 +1317,16 @@ static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
return w * h * fmt_depth >> 3;
}
+static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
+ struct v4l2_rect *r);
+
static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
{
struct vb2_queue *vq;
struct s5p_jpeg_q_data *q_data = NULL;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_ctrl *ctrl_subs;
+ struct v4l2_rect scale_rect;
unsigned int f_type;
vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
@@ -1200,6 +1371,35 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
if (ctrl_subs)
v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
+ ct->crop_altered = false;
+ }
+
+ /*
+ * For decoding init crop_rect with capture buffer dimmensions which
+ * contain aligned dimensions of the input JPEG image and do it only
+ * if crop rectangle hasn't been altered by the user space e.g. with
+ * S_SELECTION ioctl. For encoding assign output buffer dimensions.
+ */
+ if (!ct->crop_altered &&
+ ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
+ (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
+ ct->crop_rect.width = pix->width;
+ ct->crop_rect.height = pix->height;
+ }
+
+ /*
+ * Prevent downscaling to YUV420 format by more than 2
+ * for Exynos3250 SoC as it produces broken raw image
+ * in such cases.
+ */
+ if (ct->mode == S5P_JPEG_DECODE &&
+ f_type == FMT_TYPE_CAPTURE &&
+ ct->jpeg->variant->version == SJPEG_EXYNOS3250 &&
+ pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
+ ct->scale_factor > 2) {
+ scale_rect.width = ct->out_q.w / 2;
+ scale_rect.height = ct->out_q.h / 2;
+ exynos3250_jpeg_try_downscale(ct, &scale_rect);
}
return 0;
@@ -1229,6 +1429,101 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
}
+static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
+ struct v4l2_rect *r)
+{
+ int w_ratio, h_ratio, scale_factor, cur_ratio, i;
+
+ w_ratio = ctx->out_q.w / r->width;
+ h_ratio = ctx->out_q.h / r->height;
+
+ scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
+ scale_factor = clamp_val(scale_factor, 1, 8);
+
+ /* Align scale ratio to the nearest power of 2 */
+ for (i = 0; i <= 3; ++i) {
+ cur_ratio = 1 << i;
+ if (scale_factor <= cur_ratio) {
+ ctx->scale_factor = cur_ratio;
+ break;
+ }
+ }
+
+ r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
+ r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
+
+ ctx->crop_rect.width = r->width;
+ ctx->crop_rect.height = r->height;
+ ctx->crop_rect.left = 0;
+ ctx->crop_rect.top = 0;
+
+ ctx->crop_altered = true;
+
+ return 0;
+}
+
+/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
+static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
+{
+ if (a->left < b->left || a->top < b->top)
+ return 0;
+ if (a->left + a->width > b->left + b->width)
+ return 0;
+ if (a->top + a->height > b->top + b->height)
+ return 0;
+
+ return 1;
+}
+
+static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
+ struct v4l2_rect *r)
+{
+ struct v4l2_rect base_rect;
+ int w_step, h_step;
+
+ switch (ctx->cap_q.fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ w_step = 1;
+ h_step = 2;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ w_step = 2;
+ h_step = 2;
+ break;
+ default:
+ w_step = 1;
+ h_step = 1;
+ break;
+ }
+
+ base_rect.top = 0;
+ base_rect.left = 0;
+ base_rect.width = ctx->out_q.w;
+ base_rect.height = ctx->out_q.h;
+
+ r->width = round_down(r->width, w_step);
+ r->height = round_down(r->height, h_step);
+ r->left = round_down(r->left, 2);
+ r->top = round_down(r->top, 2);
+
+ if (!enclosed_rectangle(r, &base_rect))
+ return -EINVAL;
+
+ ctx->crop_rect.left = r->left;
+ ctx->crop_rect.top = r->top;
+ ctx->crop_rect.width = r->width;
+ ctx->crop_rect.height = r->height;
+
+ ctx->crop_altered = true;
+
+ return 0;
+}
+
+/*
+ * V4L2 controls
+ */
+
static int s5p_jpeg_g_selection(struct file *file, void *priv,
struct v4l2_selection *s)
{
@@ -1243,27 +1538,53 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv,
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
s->r.width = ctx->out_q.w;
s->r.height = ctx->out_q.h;
+ s->r.left = 0;
+ s->r.top = 0;
break;
+ case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_PADDED:
- s->r.width = ctx->cap_q.w;
- s->r.height = ctx->cap_q.h;
+ s->r.width = ctx->crop_rect.width;
+ s->r.height = ctx->crop_rect.height;
+ s->r.left = ctx->crop_rect.left;
+ s->r.top = ctx->crop_rect.top;
break;
default:
return -EINVAL;
}
- s->r.left = 0;
- s->r.top = 0;
return 0;
}
/*
* V4L2 controls
*/
+static int s5p_jpeg_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+{
+ struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
+ struct v4l2_rect *rect = &s->r;
+ int ret = -EINVAL;
+
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (s->target == V4L2_SEL_TGT_COMPOSE) {
+ if (ctx->mode != S5P_JPEG_DECODE)
+ return -EINVAL;
+ if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250)
+ ret = exynos3250_jpeg_try_downscale(ctx, rect);
+ } else if (s->target == V4L2_SEL_TGT_CROP) {
+ if (ctx->mode != S5P_JPEG_ENCODE)
+ return -EINVAL;
+ if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250)
+ ret = exynos3250_jpeg_try_crop(ctx, rect);
+ }
+
+ return ret;
+}
static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
@@ -1282,36 +1603,53 @@ static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
-static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
+static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
{
- struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&ctx->jpeg->slock, flags);
-
- if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
- if (ctx->jpeg->variant->version == SJPEG_S5P)
- goto error_free;
+ switch (ctx->jpeg->variant->version) {
+ case SJPEG_S5P:
+ return 0;
+ case SJPEG_EXYNOS3250:
+ /*
+ * The exynos3250 device can produce JPEG image only
+ * of 4:4:4 subsampling when given RGB32 source image.
+ */
+ if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
+ *ctrl_val = 0;
+ break;
+ case SJPEG_EXYNOS4:
/*
* The exynos4x12 device requires input raw image fourcc
* to be V4L2_PIX_FMT_GREY if gray jpeg format
* is to be set.
*/
if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
- ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
- ret = -EINVAL;
- goto error_free;
- }
- /*
- * The exynos4x12 device requires resulting jpeg subsampling
- * not to be lower than the input raw image subsampling.
- */
- if (ctx->out_q.fmt->subsampling > ctrl->val)
- ctrl->val = ctx->out_q.fmt->subsampling;
+ *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
+ return -EINVAL;
+ break;
}
-error_free:
+ /*
+ * The exynos4x12 and exynos3250 devices require resulting
+ * jpeg subsampling not to be lower than the input raw image
+ * subsampling.
+ */
+ if (ctx->out_q.fmt->subsampling > *ctrl_val)
+ *ctrl_val = ctx->out_q.fmt->subsampling;
+
+ return 0;
+}
+
+static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&ctx->jpeg->slock, flags);
+
+ if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
+ ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
+
spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
return ret;
}
@@ -1414,6 +1752,7 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
.vidioc_g_selection = s5p_jpeg_g_selection,
+ .vidioc_s_selection = s5p_jpeg_s_selection,
};
/*
@@ -1604,6 +1943,135 @@ static void exynos4_jpeg_device_run(void *priv)
spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
}
+static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct s5p_jpeg_fmt *fmt;
+ struct vb2_buffer *vb;
+ struct s5p_jpeg_addr jpeg_addr;
+ u32 pix_size;
+
+ pix_size = ctx->cap_q.w * ctx->cap_q.h;
+
+ if (ctx->mode == S5P_JPEG_ENCODE) {
+ vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ fmt = ctx->out_q.fmt;
+ } else {
+ vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ fmt = ctx->cap_q.fmt;
+ }
+
+ jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
+
+ if (fmt->colplanes == 2) {
+ jpeg_addr.cb = jpeg_addr.y + pix_size;
+ } else if (fmt->colplanes == 3) {
+ jpeg_addr.cb = jpeg_addr.y + pix_size;
+ if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
+ jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
+ else
+ jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
+ }
+
+ exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
+}
+
+static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
+{
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ struct vb2_buffer *vb;
+ unsigned int jpeg_addr = 0;
+
+ if (ctx->mode == S5P_JPEG_ENCODE)
+ vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+ else
+ vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+
+ jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
+}
+
+static void exynos3250_jpeg_device_run(void *priv)
+{
+ struct s5p_jpeg_ctx *ctx = priv;
+ struct s5p_jpeg *jpeg = ctx->jpeg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->jpeg->slock, flags);
+
+ exynos3250_jpeg_reset(jpeg->regs);
+ exynos3250_jpeg_set_dma_num(jpeg->regs);
+ exynos3250_jpeg_poweron(jpeg->regs);
+ exynos3250_jpeg_clk_set(jpeg->regs);
+ exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
+
+ if (ctx->mode == S5P_JPEG_ENCODE) {
+ exynos3250_jpeg_input_raw_fmt(jpeg->regs,
+ ctx->out_q.fmt->fourcc);
+ exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
+
+ /*
+ * JPEG IP allows storing 4 quantization tables
+ * We fill table 0 for luma and table 1 for chroma
+ */
+ s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
+ s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
+ /* use table 0 for Y */
+ exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
+ /* use table 1 for Cb and Cr*/
+ exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
+ exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
+
+ /* Y, Cb, Cr use Huffman table 0 */
+ exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
+ exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
+ exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
+ exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
+ exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
+ exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
+
+ exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
+ exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
+ exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
+ ctx->out_q.w);
+ exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
+ ctx->crop_rect.top);
+ exynos3250_jpeg_set_img_addr(ctx);
+ exynos3250_jpeg_set_jpeg_addr(ctx);
+ exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
+
+ /* ultimately comes from sizeimage from userspace */
+ exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
+
+ if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
+ ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
+ ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
+ exynos3250_jpeg_set_y16(jpeg->regs, true);
+ } else {
+ exynos3250_jpeg_set_img_addr(ctx);
+ exynos3250_jpeg_set_jpeg_addr(ctx);
+ exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
+ ctx->cap_q.w);
+ exynos3250_jpeg_offset(jpeg->regs, 0, 0);
+ exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
+ ctx->scale_factor);
+ exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
+ exynos3250_jpeg_output_raw_fmt(jpeg->regs,
+ ctx->cap_q.fmt->fourcc);
+ }
+
+ exynos3250_jpeg_interrupts_enable(jpeg->regs);
+
+ /* JPEG RGB to YCbCr conversion matrix */
+ exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
+
+ exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
+ jpeg->irq_status = 0;
+ exynos3250_jpeg_start(jpeg->regs);
+
+ spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
+}
+
static int s5p_jpeg_job_ready(void *priv)
{
struct s5p_jpeg_ctx *ctx = priv;
@@ -1621,8 +2089,14 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
.device_run = s5p_jpeg_device_run,
.job_ready = s5p_jpeg_job_ready,
.job_abort = s5p_jpeg_job_abort,
-}
-;
+};
+
+static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
+ .device_run = exynos3250_jpeg_device_run,
+ .job_ready = s5p_jpeg_job_ready,
+ .job_abort = s5p_jpeg_job_abort,
+};
+
static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
.device_run = exynos4_jpeg_device_run,
.job_ready = s5p_jpeg_job_ready,
@@ -1895,6 +2369,70 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
return IRQ_HANDLED;
}
+static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
+{
+ struct s5p_jpeg *jpeg = dev_id;
+ struct s5p_jpeg_ctx *curr_ctx;
+ struct vb2_buffer *src_buf, *dst_buf;
+ unsigned long payload_size = 0;
+ enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
+ bool interrupt_timeout = false;
+ u32 irq_status;
+
+ spin_lock(&jpeg->slock);
+
+ irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
+ if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
+ exynos3250_jpeg_clear_timer_status(jpeg->regs);
+ interrupt_timeout = true;
+ dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
+ }
+
+ irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
+ exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
+
+ jpeg->irq_status |= irq_status;
+
+ curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+
+ if (!curr_ctx)
+ goto exit_unlock;
+
+ if ((irq_status & EXYNOS3250_HEADER_STAT) &&
+ (curr_ctx->mode == S5P_JPEG_DECODE)) {
+ exynos3250_jpeg_rstart(jpeg->regs);
+ goto exit_unlock;
+ }
+
+ if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
+ EXYNOS3250_WDMA_DONE |
+ EXYNOS3250_RDMA_DONE |
+ EXYNOS3250_RESULT_STAT))
+ payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
+ else if (interrupt_timeout)
+ state = VB2_BUF_STATE_ERROR;
+ else
+ goto exit_unlock;
+
+ src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+ dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
+
+ dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
+ dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
+
+ v4l2_m2m_buf_done(src_buf, state);
+ if (curr_ctx->mode == S5P_JPEG_ENCODE)
+ vb2_set_plane_payload(dst_buf, 0, payload_size);
+ v4l2_m2m_buf_done(dst_buf, state);
+ v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
+
+ curr_ctx->subsampling =
+ exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
+exit_unlock:
+ spin_unlock(&jpeg->slock);
+ return IRQ_HANDLED;
+}
+
static void *jpeg_get_drv_data(struct device *dev);
/*
@@ -1950,6 +2488,10 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
}
dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
+ jpeg->sclk = clk_get(&pdev->dev, "sclk");
+ if (IS_ERR(jpeg->sclk))
+ dev_info(&pdev->dev, "sclk clock not available\n");
+
/* v4l2 device */
ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
if (ret) {
@@ -2057,6 +2599,8 @@ device_register_rollback:
clk_get_rollback:
clk_put(jpeg->clk);
+ if (!IS_ERR(jpeg->sclk))
+ clk_put(jpeg->sclk);
return ret;
}
@@ -2075,10 +2619,15 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
v4l2_m2m_release(jpeg->m2m_dev);
v4l2_device_unregister(&jpeg->v4l2_dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
+ if (!pm_runtime_status_suspended(&pdev->dev)) {
clk_disable_unprepare(jpeg->clk);
+ if (!IS_ERR(jpeg->sclk))
+ clk_disable_unprepare(jpeg->sclk);
+ }
clk_put(jpeg->clk);
+ if (!IS_ERR(jpeg->sclk))
+ clk_put(jpeg->sclk);
return 0;
}
@@ -2088,6 +2637,8 @@ static int s5p_jpeg_runtime_suspend(struct device *dev)
struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
clk_disable_unprepare(jpeg->clk);
+ if (!IS_ERR(jpeg->sclk))
+ clk_disable_unprepare(jpeg->sclk);
return 0;
}
@@ -2102,15 +2653,24 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
if (ret < 0)
return ret;
+ if (!IS_ERR(jpeg->sclk)) {
+ ret = clk_prepare_enable(jpeg->sclk);
+ if (ret < 0)
+ return ret;
+ }
+
spin_lock_irqsave(&jpeg->slock, flags);
/*
- * JPEG IP allows storing two Huffman tables for each component
+ * JPEG IP allows storing two Huffman tables for each component.
* We fill table 0 for each component and do this here only
- * for S5PC210 device as Exynos4x12 requires programming its
- * Huffman tables each time the encoding process is initialized.
+ * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires
+ * programming its Huffman tables each time the encoding process
+ * is initialized, and thus it is accomplished in the device_run
+ * callback of m2m_ops.
*/
- if (jpeg->variant->version == SJPEG_S5P) {
+ if (jpeg->variant->version == SJPEG_S5P ||
+ jpeg->variant->version == SJPEG_EXYNOS3250) {
s5p_jpeg_set_hdctbl(jpeg->regs);
s5p_jpeg_set_hdctblg(jpeg->regs);
s5p_jpeg_set_hactbl(jpeg->regs);
@@ -2150,6 +2710,13 @@ static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
.fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
};
+static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
+ .version = SJPEG_EXYNOS3250,
+ .jpeg_irq = exynos3250_jpeg_irq,
+ .m2m_ops = &exynos3250_jpeg_m2m_ops,
+ .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
+};
+
static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
.version = SJPEG_EXYNOS4,
.jpeg_irq = exynos4_jpeg_irq,
@@ -2162,8 +2729,11 @@ static const struct of_device_id samsung_jpeg_match[] = {
.compatible = "samsung,s5pv210-jpeg",
.data = &s5p_jpeg_drvdata,
}, {
+ .compatible = "samsung,exynos3250-jpeg",
+ .data = &exynos3250_jpeg_drvdata,
+ }, {
.compatible = "samsung,exynos4210-jpeg",
- .data = &s5p_jpeg_drvdata,
+ .data = &exynos4_jpeg_drvdata,
}, {
.compatible = "samsung,exynos4212-jpeg",
.data = &exynos4_jpeg_drvdata,
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 3e4786329727..764b32de326b 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -35,6 +35,8 @@
#define S5P_JPEG_COEF32 0x6e
#define S5P_JPEG_COEF33 0x13
+#define EXYNOS3250_IRQ_TIMEOUT 0x10000000
+
/* a selection of JPEG markers */
#define TEM 0x01
#define SOF0 0xc0
@@ -49,9 +51,10 @@
#define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2)
#define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3)
#define SJPEG_FMT_FLAG_S5P (1 << 4)
-#define SJPEG_FMT_FLAG_EXYNOS4 (1 << 5)
-#define SJPEG_FMT_RGB (1 << 6)
-#define SJPEG_FMT_NON_RGB (1 << 7)
+#define SJPEG_FMT_FLAG_EXYNOS3250 (1 << 5)
+#define SJPEG_FMT_FLAG_EXYNOS4 (1 << 6)
+#define SJPEG_FMT_RGB (1 << 7)
+#define SJPEG_FMT_NON_RGB (1 << 8)
#define S5P_JPEG_ENCODE 0
#define S5P_JPEG_DECODE 1
@@ -65,8 +68,9 @@
/* Version numbers */
-#define SJPEG_S5P 1
-#define SJPEG_EXYNOS4 2
+#define SJPEG_S5P 1
+#define SJPEG_EXYNOS3250 2
+#define SJPEG_EXYNOS4 3
enum exynos4_jpeg_result {
OK_ENC_OR_DEC,
@@ -95,8 +99,13 @@ enum exynos4_jpeg_img_quality_level {
* @regs: JPEG IP registers mapping
* @irq: JPEG IP irq
* @clk: JPEG IP clock
+ * @sclk: Exynos3250 JPEG IP special clock
* @dev: JPEG IP struct device
* @alloc_ctx: videobuf2 memory allocator's context
+ * @variant: driver variant to be used
+ * @irq_status interrupt flags set during single encode/decode
+ operation
+
*/
struct s5p_jpeg {
struct mutex lock;
@@ -111,9 +120,11 @@ struct s5p_jpeg {
unsigned int irq;
enum exynos4_jpeg_result irq_ret;
struct clk *clk;
+ struct clk *sclk;
struct device *dev;
void *alloc_ctx;
struct s5p_jpeg_variant *variant;
+ u32 irq_status;
};
struct s5p_jpeg_variant {
@@ -164,9 +175,15 @@ struct s5p_jpeg_q_data {
* @jpeg: JPEG IP device for this context
* @mode: compression (encode) operation or decompression (decode)
* @compr_quality: destination image quality in compression (encode) mode
+ * @restart_interval: JPEG restart interval for JPEG encoding
+ * @subsampling: subsampling of a raw format or a JPEG
* @out_q: source (output) queue information
- * @cap_fmt: destination (capture) queue queue information
+ * @cap_q: destination (capture) queue queue information
+ * @scale_factor: scale factor for JPEG decoding
+ * @crop_rect: a rectangle representing crop area of the output buffer
+ * @fh: V4L2 file handle
* @hdr_parsed: set if header has been parsed during decompression
+ * @crop_altered: set if crop rectangle has been altered by the user space
* @ctrl_handler: controls handler
*/
struct s5p_jpeg_ctx {
@@ -177,8 +194,11 @@ struct s5p_jpeg_ctx {
unsigned short subsampling;
struct s5p_jpeg_q_data out_q;
struct s5p_jpeg_q_data cap_q;
+ unsigned int scale_factor;
+ struct v4l2_rect crop_rect;
struct v4l2_fh fh;
bool hdr_parsed;
+ bool crop_altered;
struct v4l2_ctrl_handler ctrl_handler;
};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c
new file mode 100644
index 000000000000..d26e1f846553
--- /dev/null
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c
@@ -0,0 +1,487 @@
+/* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Author: Jacek Anaszewski <j.anaszewski@samsung.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.
+ */
+
+#include <linux/io.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+
+#include "jpeg-core.h"
+#include "jpeg-regs.h"
+#include "jpeg-hw-exynos3250.h"
+
+void exynos3250_jpeg_reset(void __iomem *regs)
+{
+ u32 reg = 0;
+ int count = 1000;
+
+ writel(1, regs + EXYNOS3250_SW_RESET);
+ /* no other way but polling for when JPEG IP becomes operational */
+ while (reg != 0 && --count > 0) {
+ udelay(1);
+ cpu_relax();
+ reg = readl(regs + EXYNOS3250_SW_RESET);
+ }
+
+ reg = 0;
+ count = 1000;
+
+ while (reg != 1 && --count > 0) {
+ writel(1, regs + EXYNOS3250_JPGDRI);
+ udelay(1);
+ cpu_relax();
+ reg = readl(regs + EXYNOS3250_JPGDRI);
+ }
+
+ writel(0, regs + EXYNOS3250_JPGDRI);
+}
+
+void exynos3250_jpeg_poweron(void __iomem *regs)
+{
+ writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
+}
+
+void exynos3250_jpeg_set_dma_num(void __iomem *regs)
+{
+ writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &
+ EXYNOS3250_WDMA_ISSUE_NUM_MASK) |
+ ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &
+ EXYNOS3250_RDMA_ISSUE_NUM_MASK) |
+ ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &
+ EXYNOS3250_ISSUE_GATHER_NUM_MASK),
+ regs + EXYNOS3250_DMA_ISSUE_NUM);
+}
+
+void exynos3250_jpeg_clk_set(void __iomem *base)
+{
+ u32 reg;
+
+ reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;
+
+ writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);
+}
+
+void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)
+{
+ u32 reg;
+
+ reg = readl(regs + EXYNOS3250_JPGCMOD) &
+ EXYNOS3250_MODE_Y16_MASK;
+
+ switch (fmt) {
+ case V4L2_PIX_FMT_RGB32:
+ reg |= EXYNOS3250_MODE_SEL_ARGB8888;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ reg |= EXYNOS3250_MODE_SEL_RGB565;
+ break;
+ case V4L2_PIX_FMT_RGB565X:
+ reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |
+ EXYNOS3250_SRC_SWAP_UV;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |
+ EXYNOS3250_SRC_SWAP_UV;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ reg |= EXYNOS3250_MODE_SEL_420_3P;
+ break;
+ default:
+ break;
+
+ }
+
+ writel(reg, regs + EXYNOS3250_JPGCMOD);
+}
+
+void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)
+{
+ u32 reg;
+
+ reg = readl(regs + EXYNOS3250_JPGCMOD);
+ if (y16)
+ reg |= EXYNOS3250_MODE_Y16;
+ else
+ reg &= ~EXYNOS3250_MODE_Y16_MASK;
+ writel(reg, regs + EXYNOS3250_JPGCMOD);
+}
+
+void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)
+{
+ u32 reg, m;
+
+ if (mode == S5P_JPEG_ENCODE)
+ m = EXYNOS3250_PROC_MODE_COMPR;
+ else
+ m = EXYNOS3250_PROC_MODE_DECOMPR;
+ reg = readl(regs + EXYNOS3250_JPGMOD);
+ reg &= ~EXYNOS3250_PROC_MODE_MASK;
+ reg |= m;
+ writel(reg, regs + EXYNOS3250_JPGMOD);
+}
+
+void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
+{
+ u32 reg, m = 0;
+
+ switch (mode) {
+ case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
+ m = EXYNOS3250_SUBSAMPLING_MODE_444;
+ break;
+ case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
+ m = EXYNOS3250_SUBSAMPLING_MODE_422;
+ break;
+ case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
+ m = EXYNOS3250_SUBSAMPLING_MODE_420;
+ break;
+ }
+
+ reg = readl(regs + EXYNOS3250_JPGMOD);
+ reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;
+ reg |= m;
+ writel(reg, regs + EXYNOS3250_JPGMOD);
+}
+
+unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_JPGMOD) &
+ EXYNOS3250_SUBSAMPLING_MODE_MASK;
+}
+
+void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)
+{
+ u32 reg;
+
+ reg = dri & EXYNOS3250_JPGDRI_MASK;
+ writel(reg, regs + EXYNOS3250_JPGDRI);
+}
+
+void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
+{
+ unsigned long reg;
+
+ reg = readl(regs + EXYNOS3250_QHTBL);
+ reg &= ~EXYNOS3250_QT_NUM_MASK(t);
+ reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &
+ EXYNOS3250_QT_NUM_MASK(t);
+ writel(reg, regs + EXYNOS3250_QHTBL);
+}
+
+void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
+{
+ unsigned long reg;
+
+ reg = readl(regs + EXYNOS3250_QHTBL);
+ reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);
+ /* this driver uses table 0 for all color components */
+ reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &
+ EXYNOS3250_HT_NUM_AC_MASK(t);
+ writel(reg, regs + EXYNOS3250_QHTBL);
+}
+
+void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
+{
+ unsigned long reg;
+
+ reg = readl(regs + EXYNOS3250_QHTBL);
+ reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);
+ /* this driver uses table 0 for all color components */
+ reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &
+ EXYNOS3250_HT_NUM_DC_MASK(t);
+ writel(reg, regs + EXYNOS3250_QHTBL);
+}
+
+void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)
+{
+ u32 reg;
+
+ reg = y & EXYNOS3250_JPGY_MASK;
+ writel(reg, regs + EXYNOS3250_JPGY);
+}
+
+void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)
+{
+ u32 reg;
+
+ reg = x & EXYNOS3250_JPGX_MASK;
+ writel(reg, regs + EXYNOS3250_JPGX);
+}
+
+unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_JPGY);
+}
+
+unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_JPGX);
+}
+
+void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
+{
+ u32 reg;
+
+ reg = readl(regs + EXYNOS3250_JPGINTSE);
+ reg |= (EXYNOS3250_JPEG_DONE_EN |
+ EXYNOS3250_WDMA_DONE_EN |
+ EXYNOS3250_RDMA_DONE_EN |
+ EXYNOS3250_ENC_STREAM_INT_EN |
+ EXYNOS3250_CORE_DONE_EN |
+ EXYNOS3250_ERR_INT_EN |
+ EXYNOS3250_HEAD_INT_EN);
+ writel(reg, regs + EXYNOS3250_JPGINTSE);
+}
+
+void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
+{
+ u32 reg;
+
+ reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
+ writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
+}
+
+void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
+{
+ u32 reg;
+
+ switch (fmt) {
+ case V4L2_PIX_FMT_RGB32:
+ reg = EXYNOS3250_OUT_FMT_ARGB8888;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ reg = EXYNOS3250_OUT_FMT_RGB565;
+ break;
+ case V4L2_PIX_FMT_RGB565X:
+ reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
+ EXYNOS3250_OUT_SWAP_UV;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
+ EXYNOS3250_OUT_SWAP_UV;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ reg = EXYNOS3250_OUT_FMT_420_3P;
+ break;
+ default:
+ reg = 0;
+ break;
+ }
+
+ writel(reg, regs + EXYNOS3250_OUTFORM);
+}
+
+void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
+{
+ writel(addr, regs + EXYNOS3250_JPG_JPGADR);
+}
+
+void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
+{
+ writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
+ writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
+ writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
+}
+
+void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
+ unsigned int width)
+{
+ u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
+
+ switch (img_fmt) {
+ case V4L2_PIX_FMT_RGB32:
+ reg_luma = 4 * width;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB565X:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_VYUY:
+ reg_luma = 2 * width;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ reg_luma = width;
+ reg_cb = reg_luma;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ reg_luma = width;
+ reg_cb = reg_cr = reg_luma / 2;
+ break;
+ default:
+ break;
+ }
+
+ writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
+ writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
+ writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
+}
+
+void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
+ unsigned int y_offset)
+{
+ u32 reg;
+
+ reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
+ EXYNOS3250_LUMA_YY_OFFSET_MASK;
+ reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
+ EXYNOS3250_LUMA_YX_OFFSET_MASK;
+
+ writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
+
+ reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
+ EXYNOS3250_CHROMA_YY_OFFSET_MASK;
+ reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
+ EXYNOS3250_CHROMA_YX_OFFSET_MASK;
+
+ writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
+
+ reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
+ EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
+ reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
+ EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
+
+ writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
+}
+
+void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
+{
+ if (mode == S5P_JPEG_ENCODE) {
+ writel(EXYNOS3250_JPEG_ENC_COEF1,
+ base + EXYNOS3250_JPG_COEF(1));
+ writel(EXYNOS3250_JPEG_ENC_COEF2,
+ base + EXYNOS3250_JPG_COEF(2));
+ writel(EXYNOS3250_JPEG_ENC_COEF3,
+ base + EXYNOS3250_JPG_COEF(3));
+ } else {
+ writel(EXYNOS3250_JPEG_DEC_COEF1,
+ base + EXYNOS3250_JPG_COEF(1));
+ writel(EXYNOS3250_JPEG_DEC_COEF2,
+ base + EXYNOS3250_JPG_COEF(2));
+ writel(EXYNOS3250_JPEG_DEC_COEF3,
+ base + EXYNOS3250_JPG_COEF(3));
+ }
+}
+
+void exynos3250_jpeg_start(void __iomem *regs)
+{
+ writel(1, regs + EXYNOS3250_JSTART);
+}
+
+void exynos3250_jpeg_rstart(void __iomem *regs)
+{
+ writel(1, regs + EXYNOS3250_JRSTART);
+}
+
+unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_JPGINTST);
+}
+
+void exynos3250_jpeg_clear_int_status(void __iomem *regs,
+ unsigned int value)
+{
+ return writel(value, regs + EXYNOS3250_JPGINTST);
+}
+
+unsigned int exynos3250_jpeg_operating(void __iomem *regs)
+{
+ return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
+}
+
+unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
+}
+
+void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
+ unsigned int size)
+{
+ writel(size & EXYNOS3250_DEC_STREAM_MASK,
+ regs + EXYNOS3250_DEC_STREAM_SIZE);
+}
+
+void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
+ unsigned int sratio)
+{
+ switch (sratio) {
+ case 1:
+ default:
+ sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
+ break;
+ case 2:
+ sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
+ break;
+ case 4:
+ sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
+ break;
+ case 8:
+ sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
+ break;
+ }
+
+ writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
+ regs + EXYNOS3250_DEC_SCALING_RATIO);
+}
+
+void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
+{
+ time_value &= EXYNOS3250_TIMER_INIT_MASK;
+
+ writel(EXYNOS3250_TIMER_INT_STAT | time_value,
+ regs + EXYNOS3250_TIMER_SE);
+}
+
+unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
+{
+ return readl(regs + EXYNOS3250_TIMER_ST);
+}
+
+void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
+{
+ writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);
+}
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h
new file mode 100644
index 000000000000..b6e3be8b5008
--- /dev/null
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h
@@ -0,0 +1,60 @@
+/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Author: Jacek Anaszewski <j.anaszewski@samsung.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.
+ */
+#ifndef JPEG_HW_EXYNOS3250_H_
+#define JPEG_HW_EXYNOS3250_H_
+
+#include <linux/io.h>
+#include <linux/videodev2.h>
+
+#include "jpeg-regs.h"
+
+void exynos3250_jpeg_reset(void __iomem *regs);
+void exynos3250_jpeg_poweron(void __iomem *regs);
+void exynos3250_jpeg_set_dma_num(void __iomem *regs);
+void exynos3250_jpeg_clk_set(void __iomem *base);
+void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt);
+void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt);
+void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16);
+void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode);
+void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode);
+unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs);
+void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri);
+void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n);
+void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t);
+void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t);
+void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y);
+void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x);
+void exynos3250_jpeg_interrupts_enable(void __iomem *regs);
+void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size);
+void exynos3250_jpeg_outform_raw(void __iomem *regs, unsigned long format);
+void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr);
+void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr);
+void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
+ unsigned int width);
+void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
+ unsigned int y_offset);
+void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode);
+void exynos3250_jpeg_start(void __iomem *regs);
+void exynos3250_jpeg_rstart(void __iomem *regs);
+unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs);
+void exynos3250_jpeg_clear_int_status(void __iomem *regs,
+ unsigned int value);
+unsigned int exynos3250_jpeg_operating(void __iomem *regs);
+unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs);
+void exynos3250_jpeg_dec_stream_size(void __iomem *regs, unsigned int size);
+void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, unsigned int sratio);
+void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value);
+unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs);
+void exynos3250_jpeg_set_timer_status(void __iomem *regs);
+void exynos3250_jpeg_clear_timer_status(void __iomem *regs);
+
+#endif /* JPEG_HW_EXYNOS3250_H_ */
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
index 57fb05bb8c77..050fc440248f 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
@@ -2,7 +2,7 @@
*
* Register definition file for Samsung JPEG codec driver
*
- * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
@@ -373,5 +373,250 @@
/* JPEG AC chrominance (values) Huffman table register */
#define EXYNOS4_HUFF_TBL_HACCV 0x310
+/* Register and bit definitions for Exynos 3250 */
+
+/* JPEG mode register */
+#define EXYNOS3250_JPGMOD 0x00
+#define EXYNOS3250_PROC_MODE_MASK (0x1 << 3)
+#define EXYNOS3250_PROC_MODE_DECOMPR (0x1 << 3)
+#define EXYNOS3250_PROC_MODE_COMPR (0x0 << 3)
+#define EXYNOS3250_SUBSAMPLING_MODE_MASK (0x7 << 0)
+#define EXYNOS3250_SUBSAMPLING_MODE_444 (0x0 << 0)
+#define EXYNOS3250_SUBSAMPLING_MODE_422 (0x1 << 0)
+#define EXYNOS3250_SUBSAMPLING_MODE_420 (0x2 << 0)
+#define EXYNOS3250_SUBSAMPLING_MODE_411 (0x6 << 0)
+#define EXYNOS3250_SUBSAMPLING_MODE_GRAY (0x3 << 0)
+
+/* JPEG operation status register */
+#define EXYNOS3250_JPGOPR 0x04
+#define EXYNOS3250_JPGOPR_MASK 0x01
+
+/* Quantization and Huffman tables register */
+#define EXYNOS3250_QHTBL 0x08
+#define EXYNOS3250_QT_NUM_SHIFT(t) ((((t) - 1) << 1) + 8)
+#define EXYNOS3250_QT_NUM_MASK(t) (0x3 << EXYNOS3250_QT_NUM_SHIFT(t))
+
+/* Huffman tables */
+#define EXYNOS3250_HT_NUM_AC_SHIFT(t) (((t) << 1) - 1)
+#define EXYNOS3250_HT_NUM_AC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_AC_SHIFT(t))
+
+#define EXYNOS3250_HT_NUM_DC_SHIFT(t) (((t) - 1) << 1)
+#define EXYNOS3250_HT_NUM_DC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_DC_SHIFT(t))
+
+/* JPEG restart interval register */
+#define EXYNOS3250_JPGDRI 0x0c
+#define EXYNOS3250_JPGDRI_MASK 0xffff
+
+/* JPEG vertical resolution register */
+#define EXYNOS3250_JPGY 0x10
+#define EXYNOS3250_JPGY_MASK 0xffff
+
+/* JPEG horizontal resolution register */
+#define EXYNOS3250_JPGX 0x14
+#define EXYNOS3250_JPGX_MASK 0xffff
+
+/* JPEG byte count register */
+#define EXYNOS3250_JPGCNT 0x18
+#define EXYNOS3250_JPGCNT_MASK 0xffffff
+
+/* JPEG interrupt mask register */
+#define EXYNOS3250_JPGINTSE 0x1c
+#define EXYNOS3250_JPEG_DONE_EN (1 << 11)
+#define EXYNOS3250_WDMA_DONE_EN (1 << 10)
+#define EXYNOS3250_RDMA_DONE_EN (1 << 9)
+#define EXYNOS3250_ENC_STREAM_INT_EN (1 << 8)
+#define EXYNOS3250_CORE_DONE_EN (1 << 5)
+#define EXYNOS3250_ERR_INT_EN (1 << 4)
+#define EXYNOS3250_HEAD_INT_EN (1 << 3)
+
+/* JPEG interrupt status register */
+#define EXYNOS3250_JPGINTST 0x20
+#define EXYNOS3250_JPEG_DONE (1 << 11)
+#define EXYNOS3250_WDMA_DONE (1 << 10)
+#define EXYNOS3250_RDMA_DONE (1 << 9)
+#define EXYNOS3250_ENC_STREAM_STAT (1 << 8)
+#define EXYNOS3250_RESULT_STAT (1 << 5)
+#define EXYNOS3250_STREAM_STAT (1 << 4)
+#define EXYNOS3250_HEADER_STAT (1 << 3)
+
+/*
+ * Base address of the luma component DMA buffer
+ * of the raw input or output image.
+ */
+#define EXYNOS3250_LUMA_BASE 0x100
+#define EXYNOS3250_SRC_TILE_EN_MASK 0x100
+
+/* Stride of source or destination luma raw image buffer */
+#define EXYNOS3250_LUMA_STRIDE 0x104
+
+/* Horizontal/vertical offset of active region in luma raw image buffer */
+#define EXYNOS3250_LUMA_XY_OFFSET 0x108
+#define EXYNOS3250_LUMA_YY_OFFSET_SHIFT 18
+#define EXYNOS3250_LUMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YY_OFFSET_SHIFT)
+#define EXYNOS3250_LUMA_YX_OFFSET_SHIFT 2
+#define EXYNOS3250_LUMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YX_OFFSET_SHIFT)
+
+/*
+ * Base address of the chroma(Cb) component DMA buffer
+ * of the raw input or output image.
+ */
+#define EXYNOS3250_CHROMA_BASE 0x10c
+
+/* Stride of source or destination chroma(Cb) raw image buffer */
+#define EXYNOS3250_CHROMA_STRIDE 0x110
+
+/* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */
+#define EXYNOS3250_CHROMA_XY_OFFSET 0x114
+#define EXYNOS3250_CHROMA_YY_OFFSET_SHIFT 18
+#define EXYNOS3250_CHROMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT)
+#define EXYNOS3250_CHROMA_YX_OFFSET_SHIFT 2
+#define EXYNOS3250_CHROMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT)
+
+/*
+ * Base address of the chroma(Cr) component DMA buffer
+ * of the raw input or output image.
+ */
+#define EXYNOS3250_CHROMA_CR_BASE 0x118
+
+/* Stride of source or destination chroma(Cr) raw image buffer */
+#define EXYNOS3250_CHROMA_CR_STRIDE 0x11c
+
+/* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */
+#define EXYNOS3250_CHROMA_CR_XY_OFFSET 0x120
+#define EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT 18
+#define EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT)
+#define EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT 2
+#define EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT)
+
+/* Raw image data r/w address register */
+#define EXYNOS3250_JPG_IMGADR 0x50
+
+/* Source or destination JPEG file DMA buffer address */
+#define EXYNOS3250_JPG_JPGADR 0x124
+
+/* Coefficients for RGB-to-YCbCr converter register */
+#define EXYNOS3250_JPG_COEF(n) (0x128 + (((n) - 1) << 2))
+#define EXYNOS3250_COEF_SHIFT(j) ((3 - (j)) << 3)
+#define EXYNOS3250_COEF_MASK(j) (0xff << EXYNOS3250_COEF_SHIFT(j))
+
+/* Raw input format setting */
+#define EXYNOS3250_JPGCMOD 0x134
+#define EXYNOS3250_SRC_TILE_EN (0x1 << 10)
+#define EXYNOS3250_SRC_NV_MASK (0x1 << 9)
+#define EXYNOS3250_SRC_NV12 (0x0 << 9)
+#define EXYNOS3250_SRC_NV21 (0x1 << 9)
+#define EXYNOS3250_SRC_BIG_ENDIAN_MASK (0x1 << 8)
+#define EXYNOS3250_SRC_BIG_ENDIAN (0x1 << 8)
+#define EXYNOS3250_MODE_SEL_MASK (0x7 << 5)
+#define EXYNOS3250_MODE_SEL_420_2P (0x0 << 5)
+#define EXYNOS3250_MODE_SEL_422_1P_LUM_CHR (0x1 << 5)
+#define EXYNOS3250_MODE_SEL_RGB565 (0x2 << 5)
+#define EXYNOS3250_MODE_SEL_422_1P_CHR_LUM (0x3 << 5)
+#define EXYNOS3250_MODE_SEL_ARGB8888 (0x4 << 5)
+#define EXYNOS3250_MODE_SEL_420_3P (0x5 << 5)
+#define EXYNOS3250_SRC_SWAP_RGB (0x1 << 3)
+#define EXYNOS3250_SRC_SWAP_UV (0x1 << 2)
+#define EXYNOS3250_MODE_Y16_MASK (0x1 << 1)
+#define EXYNOS3250_MODE_Y16 (0x1 << 1)
+#define EXYNOS3250_HALF_EN_MASK (0x1 << 0)
+#define EXYNOS3250_HALF_EN (0x1 << 0)
+
+/* Power on/off and clock down control */
+#define EXYNOS3250_JPGCLKCON 0x138
+#define EXYNOS3250_CLK_DOWN_READY (0x1 << 1)
+#define EXYNOS3250_POWER_ON (0x1 << 0)
+
+/* Start compression or decompression */
+#define EXYNOS3250_JSTART 0x13c
+
+/* Restart decompression after header analysis */
+#define EXYNOS3250_JRSTART 0x140
+
+/* JPEG SW reset register */
+#define EXYNOS3250_SW_RESET 0x144
+
+/* JPEG timer setting register */
+#define EXYNOS3250_TIMER_SE 0x148
+#define EXYNOS3250_TIMER_INT_EN_SHIFT 31
+#define EXYNOS3250_TIMER_INT_EN (1 << EXYNOS3250_TIMER_INT_EN_SHIFT)
+#define EXYNOS3250_TIMER_INIT_MASK 0x7fffffff
+
+/* JPEG timer status register */
+#define EXYNOS3250_TIMER_ST 0x14c
+#define EXYNOS3250_TIMER_INT_STAT_SHIFT 31
+#define EXYNOS3250_TIMER_INT_STAT (1 << EXYNOS3250_TIMER_INT_STAT_SHIFT)
+#define EXYNOS3250_TIMER_CNT_SHIFT 0
+#define EXYNOS3250_TIMER_CNT_MASK 0x7fffffff
+
+/* Command status register */
+#define EXYNOS3250_COMSTAT 0x150
+#define EXYNOS3250_CUR_PROC_MODE (0x1 << 1)
+#define EXYNOS3250_CUR_COM_MODE (0x1 << 0)
+
+/* JPEG decompression output format register */
+#define EXYNOS3250_OUTFORM 0x154
+#define EXYNOS3250_OUT_ALPHA_MASK (0xff << 24)
+#define EXYNOS3250_OUT_TILE_EN (0x1 << 10)
+#define EXYNOS3250_OUT_NV_MASK (0x1 << 9)
+#define EXYNOS3250_OUT_NV12 (0x0 << 9)
+#define EXYNOS3250_OUT_NV21 (0x1 << 9)
+#define EXYNOS3250_OUT_BIG_ENDIAN_MASK (0x1 << 8)
+#define EXYNOS3250_OUT_BIG_ENDIAN (0x1 << 8)
+#define EXYNOS3250_OUT_SWAP_RGB (0x1 << 7)
+#define EXYNOS3250_OUT_SWAP_UV (0x1 << 6)
+#define EXYNOS3250_OUT_FMT_MASK (0x7 << 0)
+#define EXYNOS3250_OUT_FMT_420_2P (0x0 << 0)
+#define EXYNOS3250_OUT_FMT_422_1P_LUM_CHR (0x1 << 0)
+#define EXYNOS3250_OUT_FMT_422_1P_CHR_LUM (0x3 << 0)
+#define EXYNOS3250_OUT_FMT_420_3P (0x4 << 0)
+#define EXYNOS3250_OUT_FMT_RGB565 (0x5 << 0)
+#define EXYNOS3250_OUT_FMT_ARGB8888 (0x6 << 0)
+
+/* Input JPEG stream byte size for decompression */
+#define EXYNOS3250_DEC_STREAM_SIZE 0x158
+#define EXYNOS3250_DEC_STREAM_MASK 0x1fffffff
+
+/* The upper bound of the byte size of output compressed stream */
+#define EXYNOS3250_ENC_STREAM_BOUND 0x15c
+#define EXYNOS3250_ENC_STREAM_BOUND_MASK 0xffffc0
+
+/* Scale-down ratio when decoding */
+#define EXYNOS3250_DEC_SCALING_RATIO 0x160
+#define EXYNOS3250_DEC_SCALE_FACTOR_MASK 0x3
+#define EXYNOS3250_DEC_SCALE_FACTOR_8_8 0x0
+#define EXYNOS3250_DEC_SCALE_FACTOR_4_8 0x1
+#define EXYNOS3250_DEC_SCALE_FACTOR_2_8 0x2
+#define EXYNOS3250_DEC_SCALE_FACTOR_1_8 0x3
+
+/* Error check */
+#define EXYNOS3250_CRC_RESULT 0x164
+
+/* RDMA and WDMA operation status register */
+#define EXYNOS3250_DMA_OPER_STATUS 0x168
+#define EXYNOS3250_WDMA_OPER_STATUS (0x1 << 1)
+#define EXYNOS3250_RDMA_OPER_STATUS (0x1 << 0)
+
+/* DMA issue gathering number and issue number settings */
+#define EXYNOS3250_DMA_ISSUE_NUM 0x16c
+#define EXYNOS3250_WDMA_ISSUE_NUM_SHIFT 16
+#define EXYNOS3250_WDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT)
+#define EXYNOS3250_RDMA_ISSUE_NUM_SHIFT 8
+#define EXYNOS3250_RDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT)
+#define EXYNOS3250_ISSUE_GATHER_NUM_SHIFT 0
+#define EXYNOS3250_ISSUE_GATHER_NUM_MASK (0x7 << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT)
+#define EXYNOS3250_DMA_MO_COUNT 0x7
+
+/* Version register */
+#define EXYNOS3250_VERSION 0x1fc
+
+/* RGB <-> YUV conversion coefficients */
+#define EXYNOS3250_JPEG_ENC_COEF1 0x01352e1e
+#define EXYNOS3250_JPEG_ENC_COEF2 0x00b0ae83
+#define EXYNOS3250_JPEG_ENC_COEF3 0x020cdc13
+
+#define EXYNOS3250_JPEG_DEC_COEF1 0x04a80199
+#define EXYNOS3250_JPEG_DEC_COEF2 0x04a9a064
+#define EXYNOS3250_JPEG_DEC_COEF3 0x04a80102
+
#endif /* JPEG_REGS_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 41723180d10c..d35b0418ab37 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -162,7 +162,7 @@ static void s5p_mfc_watchdog_worker(struct work_struct *work)
/* Double check if there is at least one instance running.
* If no instance is in memory than no firmware should be present */
if (dev->num_inst > 0) {
- ret = s5p_mfc_reload_firmware(dev);
+ ret = s5p_mfc_load_firmware(dev);
if (ret) {
mfc_err("Failed to reload FW\n");
goto unlock;
@@ -724,7 +724,7 @@ static int s5p_mfc_open(struct file *file)
ret = -ENOMEM;
goto err_alloc;
}
- v4l2_fh_init(&ctx->fh, video_devdata(file));
+ v4l2_fh_init(&ctx->fh, vdev);
file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh);
ctx->dev = dev;
@@ -1351,7 +1351,7 @@ static struct s5p_mfc_variant mfc_drvdata_v5 = {
.port_num = MFC_NUM_PORTS,
.buf_size = &buf_size_v5,
.buf_align = &mfc_buf_align_v5,
- .fw_name = "s5p-mfc.fw",
+ .fw_name[0] = "s5p-mfc.fw",
};
struct s5p_mfc_buf_size_v6 mfc_buf_size_v6 = {
@@ -1378,7 +1378,12 @@ static struct s5p_mfc_variant mfc_drvdata_v6 = {
.port_num = MFC_NUM_PORTS_V6,
.buf_size = &buf_size_v6,
.buf_align = &mfc_buf_align_v6,
- .fw_name = "s5p-mfc-v6.fw",
+ .fw_name[0] = "s5p-mfc-v6.fw",
+ /*
+ * v6-v2 firmware contains bug fixes and interface change
+ * for init buffer command
+ */
+ .fw_name[1] = "s5p-mfc-v6-v2.fw",
};
struct s5p_mfc_buf_size_v6 mfc_buf_size_v7 = {
@@ -1405,7 +1410,7 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = {
.port_num = MFC_NUM_PORTS_V7,
.buf_size = &buf_size_v7,
.buf_align = &mfc_buf_align_v7,
- .fw_name = "s5p-mfc-v7.fw",
+ .fw_name[0] = "s5p-mfc-v7.fw",
};
struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
@@ -1432,7 +1437,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = {
.port_num = MFC_NUM_PORTS_V8,
.buf_size = &buf_size_v8,
.buf_align = &mfc_buf_align_v8,
- .fw_name = "s5p-mfc-v8.fw",
+ .fw_name[0] = "s5p-mfc-v8.fw",
};
static struct platform_device_id mfc_driver_ids[] = {
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index b04360cd34f0..01816ffb384b 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -38,6 +38,8 @@
#define MFC_BANK2_ALIGN_ORDER 13
#define MFC_BASE_ALIGN_ORDER 17
+#define MFC_FW_MAX_VERSIONS 2
+
#include <media/videobuf2-dma-contig.h>
static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
@@ -163,6 +165,11 @@ enum s5p_mfc_decode_arg {
MFC_DEC_RES_CHANGE,
};
+enum s5p_mfc_fw_ver {
+ MFC_FW_V1,
+ MFC_FW_V2,
+};
+
#define MFC_BUF_FLAG_USED (1 << 0)
#define MFC_BUF_FLAG_EOS (1 << 1)
@@ -225,7 +232,7 @@ struct s5p_mfc_variant {
u32 version_bit;
struct s5p_mfc_buf_size *buf_size;
struct s5p_mfc_buf_align *buf_align;
- char *fw_name;
+ char *fw_name[MFC_FW_MAX_VERSIONS];
};
/**
@@ -287,6 +294,7 @@ struct s5p_mfc_priv_buf {
* @warn_start: hardware error code from which warnings start
* @mfc_ops: ops structure holding HW operation function pointers
* @mfc_cmds: cmd structure holding HW commands function pointers
+ * @fw_ver: loaded firmware sub-version
*
*/
struct s5p_mfc_dev {
@@ -331,6 +339,7 @@ struct s5p_mfc_dev {
struct s5p_mfc_hw_ops *mfc_ops;
struct s5p_mfc_hw_cmds *mfc_cmds;
const struct s5p_mfc_regs *mfc_regs;
+ enum s5p_mfc_fw_ver fw_ver;
};
/**
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 6c3f8f743900..ca9f78922832 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -38,8 +38,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
dev->fw_virt_addr = dma_alloc_coherent(dev->mem_dev_l, dev->fw_size,
&dev->bank1, GFP_KERNEL);
- if (IS_ERR_OR_NULL(dev->fw_virt_addr)) {
- dev->fw_virt_addr = NULL;
+ if (!dev->fw_virt_addr) {
mfc_err("Allocating bitprocessor buffer failed\n");
return -ENOMEM;
}
@@ -48,7 +47,7 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
bank2_virt = dma_alloc_coherent(dev->mem_dev_r, 1 << MFC_BASE_ALIGN_ORDER,
&bank2_dma_addr, GFP_KERNEL);
- if (IS_ERR(dev->fw_virt_addr)) {
+ if (!bank2_virt) {
mfc_err("Allocating bank2 base failed\n");
dma_free_coherent(dev->mem_dev_l, dev->fw_size,
dev->fw_virt_addr, dev->bank1);
@@ -78,47 +77,23 @@ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev)
int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
{
struct firmware *fw_blob;
- int err;
+ int i, err = -EINVAL;
/* Firmare has to be present as a separate file or compiled
* into kernel. */
mfc_debug_enter();
- err = request_firmware((const struct firmware **)&fw_blob,
- dev->variant->fw_name, dev->v4l2_dev.dev);
- if (err != 0) {
- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
- return -EINVAL;
- }
- if (fw_blob->size > dev->fw_size) {
- mfc_err("MFC firmware is too big to be loaded\n");
- release_firmware(fw_blob);
- return -ENOMEM;
- }
- if (!dev->fw_virt_addr) {
- mfc_err("MFC firmware is not allocated\n");
- release_firmware(fw_blob);
- return -EINVAL;
+ for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
+ if (!dev->variant->fw_name[i])
+ continue;
+ err = request_firmware((const struct firmware **)&fw_blob,
+ dev->variant->fw_name[i], dev->v4l2_dev.dev);
+ if (!err) {
+ dev->fw_ver = (enum s5p_mfc_fw_ver) i;
+ break;
+ }
}
- memcpy(dev->fw_virt_addr, fw_blob->data, fw_blob->size);
- wmb();
- release_firmware(fw_blob);
- mfc_debug_leave();
- return 0;
-}
-
-/* Reload firmware to MFC */
-int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
-{
- struct firmware *fw_blob;
- int err;
-
- /* Firmare has to be present as a separate file or compiled
- * into kernel. */
- mfc_debug_enter();
- err = request_firmware((const struct firmware **)&fw_blob,
- dev->variant->fw_name, dev->v4l2_dev.dev);
if (err != 0) {
mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
return -EINVAL;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index 4d93835dec9d..9103258b7df3 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -436,6 +436,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
int ret = 0;
struct v4l2_pix_format_mplane *pix_mp;
+ struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
mfc_debug_enter();
ret = vidioc_try_fmt(file, priv, f);
@@ -459,11 +460,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
pix_mp->height = 0;
pix_mp->width = 0;
- if (pix_mp->plane_fmt[0].sizeimage)
- ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
- else
+ if (pix_mp->plane_fmt[0].sizeimage == 0)
pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
DEF_CPB_SIZE;
+ else if (pix_mp->plane_fmt[0].sizeimage > buf_size->cpb)
+ ctx->dec_src_buf_size = buf_size->cpb;
+ else
+ ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
pix_mp->plane_fmt[0].bytesperline = 0;
ctx->state = MFCINST_INIT;
ret = 0;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index 4f5e0ead90c6..c1c12f8d8f68 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -48,6 +48,8 @@
#define WRITEL(data, reg) \
(WARN_ON_ONCE(!(reg)) ? 0 : writel((data), (reg)))
+#define IS_MFCV6_V2(dev) (!IS_MFCV7_PLUS(dev) && dev->fw_ver == MFC_FW_V2)
+
/* Allocate temporary buffers for decoding */
static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx)
{
@@ -1352,7 +1354,7 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
WRITEL(ctx->display_delay, mfc_regs->d_display_delay);
}
- if (IS_MFCV7_PLUS(dev)) {
+ if (IS_MFCV7_PLUS(dev) || IS_MFCV6_V2(dev)) {
WRITEL(reg, mfc_regs->d_dec_options);
reg = 0;
}
@@ -1367,7 +1369,7 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)
reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6);
- if (IS_MFCV7_PLUS(dev))
+ if (IS_MFCV7_PLUS(dev) || IS_MFCV6_V2(dev))
WRITEL(reg, mfc_regs->d_init_buffer_options);
else
WRITEL(reg, mfc_regs->d_dec_options);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index 11d5f1dada32..b6a8be97a96c 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -21,6 +21,8 @@
#include "s5p_mfc_pm.h"
#define MFC_GATE_CLK_NAME "mfc"
+#define MFC_SCLK_NAME "sclk-mfc"
+#define MFC_SCLK_RATE (200 * 1000000)
#define CLK_DEBUG
@@ -50,6 +52,20 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
goto err_p_ip_clk;
}
+ if (dev->variant->version != MFC_VERSION_V6) {
+ pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME);
+ if (IS_ERR(pm->clock)) {
+ mfc_info("Failed to get MFC special clock control\n");
+ } else {
+ clk_set_rate(pm->clock, MFC_SCLK_RATE);
+ ret = clk_prepare_enable(pm->clock);
+ if (ret) {
+ mfc_err("Failed to enable MFC special clock\n");
+ goto err_s_clk;
+ }
+ }
+ }
+
atomic_set(&pm->power, 0);
#ifdef CONFIG_PM_RUNTIME
pm->device = &dev->plat_dev->dev;
@@ -59,6 +75,9 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
atomic_set(&clk_ref, 0);
#endif
return 0;
+
+err_s_clk:
+ clk_put(pm->clock);
err_p_ip_clk:
clk_put(pm->clock_gate);
err_g_ip_clk:
@@ -67,6 +86,11 @@ err_g_ip_clk:
void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
{
+ if (dev->variant->version != MFC_VERSION_V6 &&
+ pm->clock) {
+ clk_disable_unprepare(pm->clock);
+ clk_put(pm->clock);
+ }
clk_unprepare(pm->clock_gate);
clk_put(pm->clock_gate);
#ifdef CONFIG_PM_RUNTIME
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 8a8dbc8fdfde..b4d2696501e4 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -1109,8 +1109,6 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
.ioctl_ops = &mxr_ioctl_ops,
};
strlcpy(layer->vfd.name, name, sizeof(layer->vfd.name));
- /* let framework control PRIORITY */
- set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags);
video_set_drvdata(&layer->vfd, layer);
layer->vfd.lock = &layer->mutex;
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 744e43b480bc..8dc279d4d561 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -425,7 +425,6 @@ static int sh_veu_g_fmt(struct sh_veu_file *veu_file, struct v4l2_format *f)
pix->bytesperline = vfmt->bytesperline;
pix->sizeimage = vfmt->bytesperline * pix->height *
vfmt->fmt->depth / vfmt->fmt->ydepth;
- pix->priv = 0;
dev_dbg(veu->dev, "%s(): type: %d, size %u @ %ux%u, fmt %x\n", __func__,
f->type, pix->sizeimage, pix->width, pix->height, pix->pixelformat);
@@ -473,7 +472,6 @@ static int sh_veu_try_fmt(struct v4l2_format *f, const struct sh_veu_format *fmt
pix->pixelformat = fmt->fourcc;
pix->colorspace = sh_veu_4cc2cspace(pix->pixelformat);
- pix->priv = 0;
pr_debug("%s(): type: %d, size %u\n", __func__, f->type, pix->sizeimage);
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index af39c4665554..6540847f4e1d 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -17,19 +17,6 @@ config SOC_CAMERA_PLATFORM
help
This is a generic SoC camera platform driver, useful for testing
-config MX1_VIDEO
- bool
-
-config VIDEO_MX1
- tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
- depends on BROKEN
- depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
- select FIQ
- select VIDEOBUF_DMA_CONTIG
- select MX1_VIDEO
- ---help---
- This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
-
config VIDEO_MX3
tristate "i.MX3x Camera Sensor Interface driver"
depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
@@ -47,6 +34,7 @@ config VIDEO_PXA27x
config VIDEO_RCAR_VIN
tristate "R-Car Video Input (VIN) support"
depends on VIDEO_DEV && SOC_CAMERA
+ depends on ARCH_SHMOBILE || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select SOC_CAMERA_SCALE_CROP
---help---
@@ -55,12 +43,14 @@ config VIDEO_RCAR_VIN
config VIDEO_SH_MOBILE_CSI2
tristate "SuperH Mobile MIPI CSI-2 Interface driver"
depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+ depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
---help---
This is a v4l2 driver for the SuperH MIPI CSI-2 Interface
config VIDEO_SH_MOBILE_CEU
tristate "SuperH Mobile CEU Interface driver"
depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
+ depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select SOC_CAMERA_SCALE_CROP
---help---
@@ -76,7 +66,7 @@ config VIDEO_OMAP1
config VIDEO_MX2
tristate "i.MX27 Camera Sensor Interface driver"
- depends on VIDEO_DEV && SOC_CAMERA && MACH_MX27
+ depends on VIDEO_DEV && SOC_CAMERA && SOC_IMX27
select VIDEOBUF2_DMA_CONTIG
---help---
This is a v4l2 driver for the i.MX27 Camera Sensor Interface
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
index 8aed26d7a64d..2826382dc9f8 100644
--- a/drivers/media/platform/soc_camera/Makefile
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
# soc-camera host drivers have to be linked after camera drivers
obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
-obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 38c723aca438..3408b045b3f1 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -25,6 +25,7 @@
#include <media/atmel-isi.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
+#include <media/v4l2-of.h>
#include <media/videobuf2-dma-contig.h>
#define MAX_BUFFER_NUM 32
@@ -33,6 +34,7 @@
#define VID_LIMIT_BYTES (16 * 1024 * 1024)
#define MIN_FRAME_RATE 15
#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
+#define ISI_DEFAULT_MCLK_FREQ 25000000
/* Frame buffer descriptor */
struct fbd {
@@ -84,7 +86,7 @@ struct atmel_isi {
struct clk *mck;
unsigned int irq;
- struct isi_platform_data *pdata;
+ struct isi_platform_data pdata;
u16 width_flags; /* max 12 bits */
struct list_head video_buffer_list;
@@ -350,7 +352,7 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
/* Enable linked list */
- cfg1 |= isi->pdata->frate | ISI_CFG1_DISCR;
+ cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
/* Enable codec path and ISI */
ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
@@ -795,7 +797,7 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
/* Make choises, based on platform preferences */
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (isi->pdata->hsync_act_low)
+ if (isi->pdata.hsync_act_low)
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
@@ -803,7 +805,7 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (isi->pdata->vsync_act_low)
+ if (isi->pdata.vsync_act_low)
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
@@ -811,7 +813,7 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
(common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (isi->pdata->pclk_act_falling)
+ if (isi->pdata.pclk_act_falling)
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
else
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
@@ -833,9 +835,9 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
- if (isi->pdata->has_emb_sync)
+ if (isi->pdata.has_emb_sync)
cfg1 |= ISI_CFG1_EMB_SYNC;
- if (isi->pdata->full_mode)
+ if (isi->pdata.full_mode)
cfg1 |= ISI_CFG1_FULL_MODE;
isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
@@ -876,6 +878,51 @@ static int atmel_isi_remove(struct platform_device *pdev)
return 0;
}
+static int atmel_isi_probe_dt(struct atmel_isi *isi,
+ struct platform_device *pdev)
+{
+ struct device_node *np= pdev->dev.of_node;
+ struct v4l2_of_endpoint ep;
+ int err;
+
+ /* Default settings for ISI */
+ isi->pdata.full_mode = 1;
+ isi->pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ;
+ isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
+
+ np = of_graph_get_next_endpoint(np, NULL);
+ if (!np) {
+ dev_err(&pdev->dev, "Could not find the endpoint\n");
+ return -EINVAL;
+ }
+
+ err = v4l2_of_parse_endpoint(np, &ep);
+ if (err) {
+ dev_err(&pdev->dev, "Could not parse the endpoint\n");
+ goto err_probe_dt;
+ }
+
+ switch (ep.bus.parallel.bus_width) {
+ case 8:
+ isi->pdata.data_width_flags = ISI_DATAWIDTH_8;
+ break;
+ case 10:
+ isi->pdata.data_width_flags =
+ ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10;
+ break;
+ default:
+ dev_err(&pdev->dev, "Unsupported bus width: %d\n",
+ ep.bus.parallel.bus_width);
+ err = -EINVAL;
+ goto err_probe_dt;
+ }
+
+err_probe_dt:
+ of_node_put(np);
+
+ return err;
+}
+
static int atmel_isi_probe(struct platform_device *pdev)
{
unsigned int irq;
@@ -887,7 +934,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
struct isi_platform_data *pdata;
pdata = dev->platform_data;
- if (!pdata || !pdata->data_width_flags) {
+ if ((!pdata || !pdata->data_width_flags) && !pdev->dev.of_node) {
dev_err(&pdev->dev,
"No config available for Atmel ISI\n");
return -EINVAL;
@@ -903,7 +950,14 @@ static int atmel_isi_probe(struct platform_device *pdev)
if (IS_ERR(isi->pclk))
return PTR_ERR(isi->pclk);
- isi->pdata = pdata;
+ if (pdata) {
+ memcpy(&isi->pdata, pdata, sizeof(isi->pdata));
+ } else {
+ ret = atmel_isi_probe_dt(isi, pdev);
+ if (ret)
+ return ret;
+ }
+
isi->active = NULL;
spin_lock_init(&isi->lock);
INIT_LIST_HEAD(&isi->video_buffer_list);
@@ -919,7 +973,7 @@ static int atmel_isi_probe(struct platform_device *pdev)
/* Set ISI_MCK's frequency, it should be faster than pixel
* clock.
*/
- ret = clk_set_rate(isi->mck, pdata->mck_hz);
+ ret = clk_set_rate(isi->mck, isi->pdata.mck_hz);
if (ret < 0)
return ret;
}
@@ -953,9 +1007,9 @@ static int atmel_isi_probe(struct platform_device *pdev)
goto err_ioremap;
}
- if (pdata->data_width_flags & ISI_DATAWIDTH_8)
+ if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8)
isi->width_flags = 1 << 7;
- if (pdata->data_width_flags & ISI_DATAWIDTH_10)
+ if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10)
isi->width_flags |= 1 << 9;
isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
@@ -980,6 +1034,11 @@ static int atmel_isi_probe(struct platform_device *pdev)
soc_host->v4l2_dev.dev = &pdev->dev;
soc_host->nr = pdev->id;
+ if (isi->pdata.asd_sizes) {
+ soc_host->asd = isi->pdata.asd;
+ soc_host->asd_sizes = isi->pdata.asd_sizes;
+ }
+
ret = soc_camera_host_register(soc_host);
if (ret) {
dev_err(&pdev->dev, "Unable to register soc camera host\n");
@@ -1000,11 +1059,18 @@ err_alloc_ctx:
return ret;
}
+static const struct of_device_id atmel_isi_of_match[] = {
+ { .compatible = "atmel,at91sam9g45-isi" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, atmel_isi_of_match);
+
static struct platform_driver atmel_isi_driver = {
.remove = atmel_isi_remove,
.driver = {
.name = "atmel_isi",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(atmel_isi_of_match),
},
};
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
deleted file mode 100644
index fea3e61476ae..000000000000
--- a/drivers/media/platform/soc_camera/mx1_camera.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
- *
- * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
- *
- * Based on PXA SoC camera driver
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * 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/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/videodev2.h>
-
-#include <media/soc_camera.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
-#include <media/videobuf-dma-contig.h>
-#include <media/soc_mediabus.h>
-
-#include <asm/dma.h>
-#include <asm/fiq.h>
-#include <mach/dma-mx1-mx2.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <linux/platform_data/camera-mx1.h>
-
-/*
- * CSI registers
- */
-#define CSICR1 0x00 /* CSI Control Register 1 */
-#define CSISR 0x08 /* CSI Status Register */
-#define CSIRXR 0x10 /* CSI RxFIFO Register */
-
-#define CSICR1_RXFF_LEVEL(x) (((x) & 0x3) << 19)
-#define CSICR1_SOF_POL (1 << 17)
-#define CSICR1_SOF_INTEN (1 << 16)
-#define CSICR1_MCLKDIV(x) (((x) & 0xf) << 12)
-#define CSICR1_MCLKEN (1 << 9)
-#define CSICR1_FCC (1 << 8)
-#define CSICR1_BIG_ENDIAN (1 << 7)
-#define CSICR1_CLR_RXFIFO (1 << 5)
-#define CSICR1_GCLK_MODE (1 << 4)
-#define CSICR1_DATA_POL (1 << 2)
-#define CSICR1_REDGE (1 << 1)
-#define CSICR1_EN (1 << 0)
-
-#define CSISR_SFF_OR_INT (1 << 25)
-#define CSISR_RFF_OR_INT (1 << 24)
-#define CSISR_STATFF_INT (1 << 21)
-#define CSISR_RXFF_INT (1 << 18)
-#define CSISR_SOF_INT (1 << 16)
-#define CSISR_DRDY (1 << 0)
-
-#define DRIVER_VERSION "0.0.2"
-#define DRIVER_NAME "mx1-camera"
-
-#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
- CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
-
-#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
- V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
- V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
-
-#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
-
-/*
- * Structures
- */
-
-/* buffer for one video frame */
-struct mx1_buffer {
- /* common v4l buffer stuff -- must be first */
- struct videobuf_buffer vb;
- enum v4l2_mbus_pixelcode code;
- int inwork;
-};
-
-/*
- * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
- * Interface. If anyone ever builds hardware to enable more than
- * one camera, they will have to modify this driver too
- */
-struct mx1_camera_dev {
- struct soc_camera_host soc_host;
- struct mx1_camera_pdata *pdata;
- struct mx1_buffer *active;
- struct resource *res;
- struct clk *clk;
- struct list_head capture;
-
- void __iomem *base;
- int dma_chan;
- unsigned int irq;
- unsigned long mclk;
-
- spinlock_t lock;
-};
-
-/*
- * Videobuf operations
- */
-static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
-{
- struct soc_camera_device *icd = vq->priv_data;
-
- *size = icd->sizeimage;
-
- if (!*count)
- *count = 32;
-
- if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
- *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
-
- dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
-
- return 0;
-}
-
-static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct videobuf_buffer *vb = &buf->vb;
-
- BUG_ON(in_interrupt());
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- /*
- * This waits until this buffer is out of danger, i.e., until it is no
- * longer in STATE_QUEUED or STATE_ACTIVE
- */
- videobuf_waiton(vq, vb, 0, 0);
- videobuf_dma_contig_free(vq, vb);
-
- vb->state = VIDEOBUF_NEEDS_INIT;
-}
-
-static int mx1_videobuf_prepare(struct videobuf_queue *vq,
- struct videobuf_buffer *vb, enum v4l2_field field)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
- int ret;
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- /* Added list head initialization on alloc */
- WARN_ON(!list_empty(&vb->queue));
-
- BUG_ON(NULL == icd->current_fmt);
-
- /*
- * I think, in buf_prepare you only have to protect global data,
- * the actual buffer is yours
- */
- buf->inwork = 1;
-
- if (buf->code != icd->current_fmt->code ||
- vb->width != icd->user_width ||
- vb->height != icd->user_height ||
- vb->field != field) {
- buf->code = icd->current_fmt->code;
- vb->width = icd->user_width;
- vb->height = icd->user_height;
- vb->field = field;
- vb->state = VIDEOBUF_NEEDS_INIT;
- }
-
- vb->size = icd->sizeimage;
- if (0 != vb->baddr && vb->bsize < vb->size) {
- ret = -EINVAL;
- goto out;
- }
-
- if (vb->state == VIDEOBUF_NEEDS_INIT) {
- ret = videobuf_iolock(vq, vb, NULL);
- if (ret)
- goto fail;
-
- vb->state = VIDEOBUF_PREPARED;
- }
-
- buf->inwork = 0;
-
- return 0;
-
-fail:
- free_buffer(vq, buf);
-out:
- buf->inwork = 0;
- return ret;
-}
-
-static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
-{
- struct videobuf_buffer *vbuf = &pcdev->active->vb;
- struct device *dev = pcdev->soc_host.icd->parent;
- int ret;
-
- if (unlikely(!pcdev->active)) {
- dev_err(dev, "DMA End IRQ with no active buffer\n");
- return -EFAULT;
- }
-
- /* setup sg list for future DMA */
- ret = imx_dma_setup_single(pcdev->dma_chan,
- videobuf_to_dma_contig(vbuf),
- vbuf->size, pcdev->res->start +
- CSIRXR, DMA_MODE_READ);
- if (unlikely(ret))
- dev_err(dev, "Failed to setup DMA sg list\n");
-
- return ret;
-}
-
-/* Called under spinlock_irqsave(&pcdev->lock, ...) */
-static void mx1_videobuf_queue(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-
- dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- list_add_tail(&vb->queue, &pcdev->capture);
-
- vb->state = VIDEOBUF_ACTIVE;
-
- if (!pcdev->active) {
- pcdev->active = buf;
-
- /* setup sg list for future DMA */
- if (!mx1_camera_setup_dma(pcdev)) {
- unsigned int temp;
- /* enable SOF irq */
- temp = __raw_readl(pcdev->base + CSICR1) |
- CSICR1_SOF_INTEN;
- __raw_writel(temp, pcdev->base + CSICR1);
- }
- }
-}
-
-static void mx1_videobuf_release(struct videobuf_queue *vq,
- struct videobuf_buffer *vb)
-{
- struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-#ifdef DEBUG
- struct soc_camera_device *icd = vq->priv_data;
- struct device *dev = icd->parent;
-
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- switch (vb->state) {
- case VIDEOBUF_ACTIVE:
- dev_dbg(dev, "%s (active)\n", __func__);
- break;
- case VIDEOBUF_QUEUED:
- dev_dbg(dev, "%s (queued)\n", __func__);
- break;
- case VIDEOBUF_PREPARED:
- dev_dbg(dev, "%s (prepared)\n", __func__);
- break;
- default:
- dev_dbg(dev, "%s (unknown)\n", __func__);
- break;
- }
-#endif
-
- free_buffer(vq, buf);
-}
-
-static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
- struct videobuf_buffer *vb,
- struct mx1_buffer *buf)
-{
- /* _init is used to debug races, see comment in mx1_camera_reqbufs() */
- list_del_init(&vb->queue);
- vb->state = VIDEOBUF_DONE;
- v4l2_get_timestamp(&vb->ts);
- vb->field_count++;
- wake_up(&vb->done);
-
- if (list_empty(&pcdev->capture)) {
- pcdev->active = NULL;
- return;
- }
-
- pcdev->active = list_entry(pcdev->capture.next,
- struct mx1_buffer, vb.queue);
-
- /* setup sg list for future DMA */
- if (likely(!mx1_camera_setup_dma(pcdev))) {
- unsigned int temp;
-
- /* enable SOF irq */
- temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
- __raw_writel(temp, pcdev->base + CSICR1);
- }
-}
-
-static void mx1_camera_dma_irq(int channel, void *data)
-{
- struct mx1_camera_dev *pcdev = data;
- struct device *dev = pcdev->soc_host.icd->parent;
- struct mx1_buffer *buf;
- struct videobuf_buffer *vb;
- unsigned long flags;
-
- spin_lock_irqsave(&pcdev->lock, flags);
-
- imx_dma_disable(channel);
-
- if (unlikely(!pcdev->active)) {
- dev_err(dev, "DMA End IRQ with no active buffer\n");
- goto out;
- }
-
- vb = &pcdev->active->vb;
- buf = container_of(vb, struct mx1_buffer, vb);
- WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
-
- mx1_camera_wakeup(pcdev, vb, buf);
-out:
- spin_unlock_irqrestore(&pcdev->lock, flags);
-}
-
-static struct videobuf_queue_ops mx1_videobuf_ops = {
- .buf_setup = mx1_videobuf_setup,
- .buf_prepare = mx1_videobuf_prepare,
- .buf_queue = mx1_videobuf_queue,
- .buf_release = mx1_videobuf_release,
-};
-
-static void mx1_camera_init_videobuf(struct videobuf_queue *q,
- struct soc_camera_device *icd)
-{
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
-
- videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent,
- &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_NONE,
- sizeof(struct mx1_buffer), icd, &ici->host_lock);
-}
-
-static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
-{
- unsigned int mclk = pcdev->mclk;
- unsigned long div;
- unsigned long lcdclk;
-
- lcdclk = clk_get_rate(pcdev->clk);
-
- /*
- * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
- * they get a nice Oops
- */
- div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
-
- dev_dbg(pcdev->soc_host.icd->parent,
- "System clock %lukHz, target freq %dkHz, divisor %lu\n",
- lcdclk / 1000, mclk / 1000, div);
-
- return div;
-}
-
-static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
-{
- unsigned int csicr1 = CSICR1_EN;
-
- dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Activate device\n");
-
- clk_prepare_enable(pcdev->clk);
-
- /* enable CSI before doing anything else */
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
- csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
- csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
-
- __raw_writel(csicr1, pcdev->base + CSICR1);
-}
-
-static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
-{
- dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Deactivate device\n");
-
- /* Disable all CSI interface */
- __raw_writel(0x00, pcdev->base + CSICR1);
-
- clk_disable_unprepare(pcdev->clk);
-}
-
-static int mx1_camera_add_device(struct soc_camera_device *icd)
-{
- dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
- icd->devnum);
-
- return 0;
-}
-
-static void mx1_camera_remove_device(struct soc_camera_device *icd)
-{
- dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
- icd->devnum);
-}
-
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface
- */
-static int mx1_camera_clock_start(struct soc_camera_host *ici)
-{
- struct mx1_camera_dev *pcdev = ici->priv;
-
- mx1_camera_activate(pcdev);
-
- return 0;
-}
-
-static void mx1_camera_clock_stop(struct soc_camera_host *ici)
-{
- struct mx1_camera_dev *pcdev = ici->priv;
- unsigned int csicr1;
-
- /* disable interrupts */
- csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- /* Stop DMA engine */
- imx_dma_disable(pcdev->dma_chan);
-
- mx1_camera_deactivate(pcdev);
-}
-
-static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct mx1_camera_dev *pcdev = ici->priv;
- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
- unsigned long common_flags;
- unsigned int csicr1;
- int ret;
-
- /* MX1 supports only 8bit buswidth */
- ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
- if (!ret) {
- common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
- if (!common_flags) {
- dev_warn(icd->parent,
- "Flags incompatible: camera 0x%x, host 0x%x\n",
- cfg.flags, CSI_BUS_FLAGS);
- return -EINVAL;
- }
- } else if (ret != -ENOIOCTLCMD) {
- return ret;
- } else {
- common_flags = CSI_BUS_FLAGS;
- }
-
- /* Make choises, based on platform choice */
- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
- else
- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
- }
-
- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
- else
- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
- }
-
- if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
- (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
- if (!pcdev->pdata ||
- pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
- else
- common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
- }
-
- cfg.flags = common_flags;
- ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
- if (ret < 0 && ret != -ENOIOCTLCMD) {
- dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
- common_flags, ret);
- return ret;
- }
-
- csicr1 = __raw_readl(pcdev->base + CSICR1);
-
- if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
- csicr1 |= CSICR1_REDGE;
- if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
- csicr1 |= CSICR1_SOF_POL;
- if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
- csicr1 |= CSICR1_DATA_POL;
-
- __raw_writel(csicr1, pcdev->base + CSICR1);
-
- return 0;
-}
-
-static int mx1_camera_set_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret, buswidth;
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- buswidth = xlate->host_fmt->bits_per_sample;
- if (buswidth > 8) {
- dev_warn(icd->parent,
- "bits-per-sample %d for format %x unsupported\n",
- buswidth, pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- if (mf.code != xlate->code)
- return -EINVAL;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
- icd->current_fmt = xlate;
-
- return ret;
-}
-
-static int mx1_camera_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
-{
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- const struct soc_camera_format_xlate *xlate;
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct v4l2_mbus_framefmt mf;
- int ret;
- /* TODO: limit to mx1 hardware capabilities */
-
- xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
- if (!xlate) {
- dev_warn(icd->parent, "Format %x not found\n",
- pix->pixelformat);
- return -EINVAL;
- }
-
- mf.width = pix->width;
- mf.height = pix->height;
- mf.field = pix->field;
- mf.colorspace = pix->colorspace;
- mf.code = xlate->code;
-
- /* limit to sensor capabilities */
- ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
- if (ret < 0)
- return ret;
-
- pix->width = mf.width;
- pix->height = mf.height;
- pix->field = mf.field;
- pix->colorspace = mf.colorspace;
-
- return 0;
-}
-
-static int mx1_camera_reqbufs(struct soc_camera_device *icd,
- struct v4l2_requestbuffers *p)
-{
- int i;
-
- /*
- * This is for locking debugging only. I removed spinlocks and now I
- * check whether .prepare is ever called on a linked buffer, or whether
- * a dma IRQ can occur for an in-work or unlinked buffer. Until now
- * it hadn't triggered
- */
- for (i = 0; i < p->count; i++) {
- struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i],
- struct mx1_buffer, vb);
- buf->inwork = 0;
- INIT_LIST_HEAD(&buf->vb.queue);
- }
-
- return 0;
-}
-
-static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
-{
- struct soc_camera_device *icd = file->private_data;
- struct mx1_buffer *buf;
-
- buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer,
- vb.stream);
-
- poll_wait(file, &buf->vb.done, pt);
-
- if (buf->vb.state == VIDEOBUF_DONE ||
- buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int mx1_camera_querycap(struct soc_camera_host *ici,
- struct v4l2_capability *cap)
-{
- /* cap->name is set by the friendly caller:-> */
- strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-
- return 0;
-}
-
-static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
- .owner = THIS_MODULE,
- .add = mx1_camera_add_device,
- .remove = mx1_camera_remove_device,
- .clock_start = mx1_camera_clock_start,
- .clock_stop = mx1_camera_clock_stop,
- .set_bus_param = mx1_camera_set_bus_param,
- .set_fmt = mx1_camera_set_fmt,
- .try_fmt = mx1_camera_try_fmt,
- .init_videobuf = mx1_camera_init_videobuf,
- .reqbufs = mx1_camera_reqbufs,
- .poll = mx1_camera_poll,
- .querycap = mx1_camera_querycap,
-};
-
-static struct fiq_handler fh = {
- .name = "csi_sof"
-};
-
-static int __init mx1_camera_probe(struct platform_device *pdev)
-{
- struct mx1_camera_dev *pcdev;
- struct resource *res;
- struct pt_regs regs;
- struct clk *clk;
- void __iomem *base;
- unsigned int irq;
- int err = 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || (int)irq <= 0) {
- err = -ENODEV;
- goto exit;
- }
-
- clk = clk_get(&pdev->dev, "csi_clk");
- if (IS_ERR(clk)) {
- err = PTR_ERR(clk);
- goto exit;
- }
-
- pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
- if (!pcdev) {
- dev_err(&pdev->dev, "Could not allocate pcdev\n");
- err = -ENOMEM;
- goto exit_put_clk;
- }
-
- pcdev->res = res;
- pcdev->clk = clk;
-
- pcdev->pdata = pdev->dev.platform_data;
-
- if (pcdev->pdata)
- pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
-
- if (!pcdev->mclk) {
- dev_warn(&pdev->dev,
- "mclk_10khz == 0! Please, fix your platform data. "
- "Using default 20MHz\n");
- pcdev->mclk = 20000000;
- }
-
- INIT_LIST_HEAD(&pcdev->capture);
- spin_lock_init(&pcdev->lock);
-
- /*
- * Request the regions.
- */
- if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
- err = -EBUSY;
- goto exit_kfree;
- }
-
- base = ioremap(res->start, resource_size(res));
- if (!base) {
- err = -ENOMEM;
- goto exit_release;
- }
- pcdev->irq = irq;
- pcdev->base = base;
-
- /* request dma */
- pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
- if (pcdev->dma_chan < 0) {
- dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
- err = -EBUSY;
- goto exit_iounmap;
- }
- dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
-
- imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
- pcdev);
-
- imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
- IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
- /* burst length : 16 words = 64 bytes */
- imx_dma_config_burstlen(pcdev->dma_chan, 0);
-
- /* request irq */
- err = claim_fiq(&fh);
- if (err) {
- dev_err(&pdev->dev, "Camera interrupt register failed\n");
- goto exit_free_dma;
- }
-
- set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
- &mx1_camera_sof_fiq_start);
-
- regs.ARM_r8 = (long)MX1_DMA_DIMR;
- regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
- regs.ARM_r10 = (long)pcdev->base + CSICR1;
- regs.ARM_fp = (long)pcdev->base + CSISR;
- regs.ARM_sp = 1 << pcdev->dma_chan;
- set_fiq_regs(&regs);
-
- mxc_set_irq_fiq(irq, 1);
- enable_fiq(irq);
-
- pcdev->soc_host.drv_name = DRIVER_NAME;
- pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
- pcdev->soc_host.priv = pcdev;
- pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
- pcdev->soc_host.nr = pdev->id;
- err = soc_camera_host_register(&pcdev->soc_host);
- if (err)
- goto exit_free_irq;
-
- dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
-
- return 0;
-
-exit_free_irq:
- disable_fiq(irq);
- mxc_set_irq_fiq(irq, 0);
- release_fiq(&fh);
-exit_free_dma:
- imx_dma_free(pcdev->dma_chan);
-exit_iounmap:
- iounmap(base);
-exit_release:
- release_mem_region(res->start, resource_size(res));
-exit_kfree:
- kfree(pcdev);
-exit_put_clk:
- clk_put(clk);
-exit:
- return err;
-}
-
-static int __exit mx1_camera_remove(struct platform_device *pdev)
-{
- struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
- struct mx1_camera_dev *pcdev = container_of(soc_host,
- struct mx1_camera_dev, soc_host);
- struct resource *res;
-
- imx_dma_free(pcdev->dma_chan);
- disable_fiq(pcdev->irq);
- mxc_set_irq_fiq(pcdev->irq, 0);
- release_fiq(&fh);
-
- clk_put(pcdev->clk);
-
- soc_camera_host_unregister(soc_host);
-
- iounmap(pcdev->base);
-
- res = pcdev->res;
- release_mem_region(res->start, resource_size(res));
-
- kfree(pcdev);
-
- dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
-
- return 0;
-}
-
-static struct platform_driver mx1_camera_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .remove = __exit_p(mx1_camera_remove),
-};
-
-module_platform_driver_probe(mx1_camera_driver, mx1_camera_probe);
-
-MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
-MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index d4df305fcc18..64dc80ccd6f9 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -34,6 +34,7 @@
#include <media/videobuf-dma-sg.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
+#include <media/v4l2-of.h>
#include <linux/videodev2.h>
@@ -1650,6 +1651,68 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.set_bus_param = pxa_camera_set_bus_param,
};
+static int pxa_camera_pdata_from_dt(struct device *dev,
+ struct pxa_camera_dev *pcdev)
+{
+ u32 mclk_rate;
+ struct device_node *np = dev->of_node;
+ struct v4l2_of_endpoint ep;
+ int err = of_property_read_u32(np, "clock-frequency",
+ &mclk_rate);
+ if (!err) {
+ pcdev->platform_flags |= PXA_CAMERA_MCLK_EN;
+ pcdev->mclk = mclk_rate;
+ }
+
+ np = of_graph_get_next_endpoint(np, NULL);
+ if (!np) {
+ dev_err(dev, "could not find endpoint\n");
+ return -EINVAL;
+ }
+
+ err = v4l2_of_parse_endpoint(np, &ep);
+ if (err) {
+ dev_err(dev, "could not parse endpoint\n");
+ goto out;
+ }
+
+ switch (ep.bus.parallel.bus_width) {
+ case 4:
+ pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_4;
+ break;
+ case 5:
+ pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_5;
+ break;
+ case 8:
+ pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_8;
+ break;
+ case 9:
+ pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_9;
+ break;
+ case 10:
+ pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
+ break;
+ default:
+ break;
+ };
+
+ if (ep.bus.parallel.flags & V4L2_MBUS_MASTER)
+ pcdev->platform_flags |= PXA_CAMERA_MASTER;
+ if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ pcdev->platform_flags |= PXA_CAMERA_HSP;
+ if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+ pcdev->platform_flags |= PXA_CAMERA_VSP;
+ if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+ pcdev->platform_flags |= PXA_CAMERA_PCLK_EN | PXA_CAMERA_PCP;
+ if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+ pcdev->platform_flags |= PXA_CAMERA_PCLK_EN;
+
+out:
+ of_node_put(np);
+
+ return err;
+}
+
static int pxa_camera_probe(struct platform_device *pdev)
{
struct pxa_camera_dev *pcdev;
@@ -1676,7 +1739,15 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->res = res;
pcdev->pdata = pdev->dev.platform_data;
- pcdev->platform_flags = pcdev->pdata->flags;
+ if (&pdev->dev.of_node && !pcdev->pdata) {
+ err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev);
+ } else {
+ pcdev->platform_flags = pcdev->pdata->flags;
+ pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
+ }
+ if (err < 0)
+ return err;
+
if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 |
PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) {
/*
@@ -1693,7 +1764,6 @@ static int pxa_camera_probe(struct platform_device *pdev)
pcdev->width_flags |= 1 << 8;
if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
pcdev->width_flags |= 1 << 9;
- pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
if (!pcdev->mclk) {
dev_warn(&pdev->dev,
"mclk == 0! Please, fix your platform data. "
@@ -1799,10 +1869,17 @@ static const struct dev_pm_ops pxa_camera_pm = {
.resume = pxa_camera_resume,
};
+static const struct of_device_id pxa_camera_of_match[] = {
+ { .compatible = "marvell,pxa270-qci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, pxa_camera_of_match);
+
static struct platform_driver pxa_camera_driver = {
.driver = {
.name = PXA_CAM_DRV_NAME,
.pm = &pxa_camera_pm,
+ .of_match_table = of_match_ptr(pxa_camera_of_match),
},
.probe = pxa_camera_probe,
.remove = pxa_camera_remove,
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index e594230e84d3..85d579f65f52 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -19,6 +19,8 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_data/camera-rcar.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -31,6 +33,7 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
+#include <media/v4l2-of.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-dma-contig.h>
@@ -126,13 +129,13 @@ struct rcar_vin_priv {
int sequence;
/* State of the VIN module in capturing mode */
enum rcar_vin_state state;
- struct rcar_vin_platform_data *pdata;
struct soc_camera_host ici;
struct list_head capture;
#define MAX_BUFFER_NUM 3
struct vb2_buffer *queue_buf[MAX_BUFFER_NUM];
struct vb2_alloc_ctx *alloc_ctx;
enum v4l2_field field;
+ unsigned int pdata_flags;
unsigned int vb_count;
unsigned int nr_hw_slots;
bool request_to_stop;
@@ -275,12 +278,12 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
break;
case V4L2_MBUS_FMT_YUYV8_2X8:
/* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
- vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
+ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
break;
case V4L2_MBUS_FMT_YUYV10_2X10:
/* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
- vnmc |= priv->pdata->flags & RCAR_VIN_BT656 ?
+ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
break;
default:
@@ -797,7 +800,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
/* Make choises, based on platform preferences */
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
- if (priv->pdata->flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
+ if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
@@ -805,7 +808,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
- if (priv->pdata->flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
+ if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
else
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
@@ -1390,6 +1393,17 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
.init_videobuf2 = rcar_vin_init_videobuf2,
};
+#ifdef CONFIG_OF
+static struct of_device_id rcar_vin_of_table[] = {
+ { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
+ { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
+ { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
+ { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
+#endif
+
static struct platform_device_id rcar_vin_id_table[] = {
{ "r8a7791-vin", RCAR_GEN2 },
{ "r8a7790-vin", RCAR_GEN2 },
@@ -1402,15 +1416,52 @@ MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
static int rcar_vin_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match = NULL;
struct rcar_vin_priv *priv;
struct resource *mem;
struct rcar_vin_platform_data *pdata;
+ unsigned int pdata_flags;
int irq, ret;
- pdata = pdev->dev.platform_data;
- if (!pdata || !pdata->flags) {
- dev_err(&pdev->dev, "platform data not set\n");
- return -EINVAL;
+ if (pdev->dev.of_node) {
+ struct v4l2_of_endpoint ep;
+ struct device_node *np;
+
+ match = of_match_device(of_match_ptr(rcar_vin_of_table),
+ &pdev->dev);
+
+ np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+ if (!np) {
+ dev_err(&pdev->dev, "could not find endpoint\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_of_parse_endpoint(np, &ep);
+ if (ret) {
+ dev_err(&pdev->dev, "could not parse endpoint\n");
+ return ret;
+ }
+
+ if (ep.bus_type == V4L2_MBUS_BT656)
+ pdata_flags = RCAR_VIN_BT656;
+ else {
+ pdata_flags = 0;
+ if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+ pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
+ if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
+ }
+
+ of_node_put(np);
+
+ dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata || !pdata->flags) {
+ dev_err(&pdev->dev, "platform data not set\n");
+ return -EINVAL;
+ }
+ pdata_flags = pdata->flags;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1441,12 +1492,18 @@ static int rcar_vin_probe(struct platform_device *pdev)
priv->ici.priv = priv;
priv->ici.v4l2_dev.dev = &pdev->dev;
- priv->ici.nr = pdev->id;
priv->ici.drv_name = dev_name(&pdev->dev);
priv->ici.ops = &rcar_vin_host_ops;
- priv->pdata = pdata;
- priv->chip = pdev->id_entry->driver_data;
+ priv->pdata_flags = pdata_flags;
+ if (!match) {
+ priv->ici.nr = pdev->id;
+ priv->chip = pdev->id_entry->driver_data;
+ } else {
+ priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
+ priv->chip = (enum chip_id)match->data;
+ };
+
spin_lock_init(&priv->lock);
INIT_LIST_HEAD(&priv->capture);
@@ -1487,6 +1544,7 @@ static struct platform_driver rcar_vin_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(rcar_vin_of_table),
},
.id_table = rcar_vin_id_table,
};
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 7fec8cdaf095..f4308fed5431 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -36,6 +36,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-of.h>
#include <media/videobuf-core.h>
#include <media/videobuf2-core.h>
@@ -1524,14 +1525,14 @@ static int scan_async_group(struct soc_camera_host *ici,
ret = soc_camera_dyn_pdev(&sdesc, sasc);
if (ret < 0)
- return ret;
+ goto eallocpdev;
sasc->sensor = &sasd->asd;
icd = soc_camera_add_pdev(sasc);
if (!icd) {
- platform_device_put(sasc->pdev);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto eaddpdev;
}
sasc->notifier.subdevs = asd;
@@ -1559,7 +1560,11 @@ static int scan_async_group(struct soc_camera_host *ici,
v4l2_clk_unregister(icd->clk);
eclkreg:
icd->clk = NULL;
- platform_device_unregister(sasc->pdev);
+ platform_device_del(sasc->pdev);
+eaddpdev:
+ platform_device_put(sasc->pdev);
+eallocpdev:
+ devm_kfree(ici->v4l2_dev.dev, sasc);
dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
return ret;
@@ -1581,6 +1586,130 @@ static void scan_async_host(struct soc_camera_host *ici)
#define scan_async_host(ici) do {} while (0)
#endif
+#ifdef CONFIG_OF
+
+struct soc_of_info {
+ struct soc_camera_async_subdev sasd;
+ struct soc_camera_async_client sasc;
+ struct v4l2_async_subdev *subdev;
+};
+
+static int soc_of_bind(struct soc_camera_host *ici,
+ struct device_node *ep,
+ struct device_node *remote)
+{
+ struct soc_camera_device *icd;
+ struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
+ struct soc_camera_async_client *sasc;
+ struct soc_of_info *info;
+ struct i2c_client *client;
+ char clk_name[V4L2_SUBDEV_NAME_SIZE];
+ int ret;
+
+ /* allocate a new subdev and add match info to it */
+ info = devm_kzalloc(ici->v4l2_dev.dev, sizeof(struct soc_of_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ info->sasd.asd.match.of.node = remote;
+ info->sasd.asd.match_type = V4L2_ASYNC_MATCH_OF;
+ info->subdev = &info->sasd.asd;
+
+ /* Or shall this be managed by the soc-camera device? */
+ sasc = &info->sasc;
+
+ /* HACK: just need a != NULL */
+ sdesc.host_desc.board_info = ERR_PTR(-ENODATA);
+
+ ret = soc_camera_dyn_pdev(&sdesc, sasc);
+ if (ret < 0)
+ goto eallocpdev;
+
+ sasc->sensor = &info->sasd.asd;
+
+ icd = soc_camera_add_pdev(sasc);
+ if (!icd) {
+ ret = -ENOMEM;
+ goto eaddpdev;
+ }
+
+ sasc->notifier.subdevs = &info->subdev;
+ sasc->notifier.num_subdevs = 1;
+ sasc->notifier.bound = soc_camera_async_bound;
+ sasc->notifier.unbind = soc_camera_async_unbind;
+ sasc->notifier.complete = soc_camera_async_complete;
+
+ icd->sasc = sasc;
+ icd->parent = ici->v4l2_dev.dev;
+
+ client = of_find_i2c_device_by_node(remote);
+
+ if (client)
+ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+ client->adapter->nr, client->addr);
+ else
+ snprintf(clk_name, sizeof(clk_name), "of-%s",
+ of_node_full_name(remote));
+
+ icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+ if (IS_ERR(icd->clk)) {
+ ret = PTR_ERR(icd->clk);
+ goto eclkreg;
+ }
+
+ ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
+ if (!ret)
+ return 0;
+eclkreg:
+ icd->clk = NULL;
+ platform_device_del(sasc->pdev);
+eaddpdev:
+ platform_device_put(sasc->pdev);
+eallocpdev:
+ devm_kfree(ici->v4l2_dev.dev, sasc);
+ dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
+
+ return ret;
+}
+
+static void scan_of_host(struct soc_camera_host *ici)
+{
+ struct device *dev = ici->v4l2_dev.dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *epn = NULL, *ren;
+ unsigned int i;
+
+ for (i = 0; ; i++) {
+ epn = of_graph_get_next_endpoint(np, epn);
+ if (!epn)
+ break;
+
+ ren = of_graph_get_remote_port(epn);
+ if (!ren) {
+ dev_notice(dev, "no remote for %s\n",
+ of_node_full_name(epn));
+ continue;
+ }
+
+ /* so we now have a remote node to connect */
+ if (!i)
+ soc_of_bind(ici, epn, ren->parent);
+
+ of_node_put(epn);
+ of_node_put(ren);
+
+ if (i) {
+ dev_err(dev, "multiple subdevices aren't supported yet!\n");
+ break;
+ }
+ }
+}
+
+#else
+static inline void scan_of_host(struct soc_camera_host *ici) { }
+#endif
+
/* Called during host-driver probe */
static int soc_camera_probe(struct soc_camera_host *ici,
struct soc_camera_device *icd)
@@ -1832,7 +1961,9 @@ int soc_camera_host_register(struct soc_camera_host *ici)
mutex_init(&ici->host_lock);
mutex_init(&ici->clk_lock);
- if (ici->asd_sizes)
+ if (ici->v4l2_dev.dev->of_node)
+ scan_of_host(ici);
+ else if (ici->asd_sizes)
/*
* No OF, host with a list of subdevices. Don't try to mix
* modes by initialising some groups statically and some
diff --git a/drivers/media/platform/vino.c b/drivers/media/platform/vino.c
index 470d35336119..91d44ea16f27 100644
--- a/drivers/media/platform/vino.c
+++ b/drivers/media/platform/vino.c
@@ -3147,7 +3147,6 @@ static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
pf->colorspace =
vino_data_formats[tempvcs.data_format].colorspace;
- pf->priv = 0;
return 0;
}
@@ -3175,8 +3174,6 @@ static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
pf->colorspace =
vino_data_formats[vcs->data_format].colorspace;
- pf->priv = 0;
-
spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
@@ -3219,8 +3216,6 @@ static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
pf->colorspace =
vino_data_formats[vcs->data_format].colorspace;
- pf->priv = 0;
-
spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c
index d00bf3df0f8a..80333714ffa7 100644
--- a/drivers/media/platform/vivi.c
+++ b/drivers/media/platform/vivi.c
@@ -648,13 +648,13 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
gen_text(dev, vbuf, line++ * 16, 16, str);
snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
dev->int32->cur.val,
- dev->int64->cur.val64,
+ *dev->int64->p_cur.p_s64,
dev->bitmask->cur.val);
gen_text(dev, vbuf, line++ * 16, 16, str);
snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
dev->boolean->cur.val,
dev->menu->qmenu[dev->menu->cur.val],
- dev->string->cur.string);
+ dev->string->p_cur.p_char);
gen_text(dev, vbuf, line++ * 16, 16, str);
snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
dev->int_menu->qmenu_int[dev->int_menu->cur.val],
@@ -1014,7 +1014,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
else
f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1236,7 +1235,7 @@ static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
.id = VIVI_CID_CUSTOM_BASE + 2,
.name = "Integer 32 Bits",
.type = V4L2_CTRL_TYPE_INTEGER,
- .min = 0x80000000,
+ .min = -0x80000000LL,
.max = 0x7fffffff,
.step = 1,
};
@@ -1246,6 +1245,9 @@ static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
.id = VIVI_CID_CUSTOM_BASE + 3,
.name = "Integer 64 Bits",
.type = V4L2_CTRL_TYPE_INTEGER64,
+ .min = LLONG_MIN,
+ .max = LLONG_MAX,
+ .step = 1,
};
static const char * const vivi_ctrl_menu_strings[] = {
@@ -1459,7 +1461,6 @@ static int __init vivi_create_instance(int inst)
vfd->debug = debug;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->queue = q;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
/*
* Provide a mutex to v4l2 core. It will be used to protect
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 6ca2cf20d545..12467191dff4 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -36,9 +36,9 @@ struct vsp1_rwpf;
struct vsp1_sru;
struct vsp1_uds;
-#define VPS1_MAX_RPF 5
-#define VPS1_MAX_UDS 3
-#define VPS1_MAX_WPF 4
+#define VSP1_MAX_RPF 5
+#define VSP1_MAX_UDS 3
+#define VSP1_MAX_WPF 4
struct vsp1_device {
struct device *dev;
@@ -55,10 +55,10 @@ struct vsp1_device {
struct vsp1_hsit *hst;
struct vsp1_lif *lif;
struct vsp1_lut *lut;
- struct vsp1_rwpf *rpf[VPS1_MAX_RPF];
+ struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
struct vsp1_sru *sru;
- struct vsp1_uds *uds[VPS1_MAX_UDS];
- struct vsp1_rwpf *wpf[VPS1_MAX_WPF];
+ struct vsp1_uds *uds[VSP1_MAX_UDS];
+ struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
struct list_head entities;
@@ -66,7 +66,7 @@ struct vsp1_device {
struct media_device media_dev;
};
-struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1);
+int vsp1_device_get(struct vsp1_device *vsp1);
void vsp1_device_put(struct vsp1_device *vsp1);
static inline u32 vsp1_read(struct vsp1_device *vsp1, u32 reg)
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index f80695480060..a0c1984c733e 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -18,6 +18,7 @@
#include "vsp1.h"
#include "vsp1_bru.h"
+#include "vsp1_rwpf.h"
#define BRU_MIN_SIZE 4U
#define BRU_MAX_SIZE 8190U
@@ -37,19 +38,47 @@ static inline void vsp1_bru_write(struct vsp1_bru *bru, u32 reg, u32 data)
}
/* -----------------------------------------------------------------------------
- * V4L2 Subdevice Core Operations
+ * Controls
*/
-static bool bru_is_input_enabled(struct vsp1_bru *bru, unsigned int input)
+static int bru_s_ctrl(struct v4l2_ctrl *ctrl)
{
- return media_entity_remote_pad(&bru->entity.pads[input]) != NULL;
+ struct vsp1_bru *bru =
+ container_of(ctrl->handler, struct vsp1_bru, ctrls);
+
+ if (!vsp1_entity_is_streaming(&bru->entity))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BG_COLOR:
+ vsp1_bru_write(bru, VI6_BRU_VIRRPF_COL, ctrl->val |
+ (0xff << VI6_BRU_VIRRPF_COL_A_SHIFT));
+ break;
+ }
+
+ return 0;
}
+static const struct v4l2_ctrl_ops bru_ctrl_ops = {
+ .s_ctrl = bru_s_ctrl,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Core Operations
+ */
+
static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
{
+ struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
struct vsp1_bru *bru = to_bru(subdev);
struct v4l2_mbus_framefmt *format;
+ unsigned int flags;
unsigned int i;
+ int ret;
+
+ ret = vsp1_entity_set_streaming(&bru->entity, enable);
+ if (ret < 0)
+ return ret;
if (!enable)
return 0;
@@ -62,18 +91,19 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
* to sane default values for now.
*/
- /* Disable both color data normalization and dithering. */
- vsp1_bru_write(bru, VI6_BRU_INCTRL, 0);
-
- /* Set the background position to cover the whole output image and
- * set its color to opaque black.
+ /* Disable dithering and enable color data normalization unless the
+ * format at the pipeline output is premultiplied.
*/
+ flags = pipe->output ? pipe->output->video.format.flags : 0;
+ vsp1_bru_write(bru, VI6_BRU_INCTRL,
+ flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ?
+ 0 : VI6_BRU_INCTRL_NRM);
+
+ /* Set the background position to cover the whole output image. */
vsp1_bru_write(bru, VI6_BRU_VIRRPF_SIZE,
(format->width << VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT) |
(format->height << VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT));
vsp1_bru_write(bru, VI6_BRU_VIRRPF_LOC, 0);
- vsp1_bru_write(bru, VI6_BRU_VIRRPF_COL,
- 0xff << VI6_BRU_VIRRPF_COL_A_SHIFT);
/* 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
@@ -84,6 +114,7 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
VI6_BRU_ROP_AROP(VI6_ROP_NOP));
for (i = 0; i < 4; ++i) {
+ bool premultiplied = false;
u32 ctrl = 0;
/* Configure all Blend/ROP units corresponding to an enabled BRU
@@ -91,11 +122,15 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
* disabled BRU inputs are used in ROP NOP mode to ignore the
* SRC input.
*/
- if (bru_is_input_enabled(bru, i))
+ if (bru->inputs[i].rpf) {
ctrl |= VI6_BRU_CTRL_RBC;
- else
+
+ premultiplied = bru->inputs[i].rpf->video.format.flags
+ & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
+ } else {
ctrl |= VI6_BRU_CTRL_CROP(VI6_ROP_NOP)
| VI6_BRU_CTRL_AROP(VI6_ROP_NOP);
+ }
/* Select the virtual RPF as the Blend/ROP unit A DST input to
* serve as a background color.
@@ -117,10 +152,18 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
*
* DSTc = DSTc * (1 - SRCa) + SRCc * SRCa
* DSTa = DSTa * (1 - SRCa) + SRCa
+ *
+ * when the SRC input isn't premultiplied, and to
+ *
+ * DSTc = DSTc * (1 - SRCa) + SRCc
+ * DSTa = DSTa * (1 - SRCa) + SRCa
+ *
+ * otherwise.
*/
vsp1_bru_write(bru, VI6_BRU_BLD(i),
VI6_BRU_BLD_CCMDX_255_SRC_A |
- VI6_BRU_BLD_CCMDY_SRC_A |
+ (premultiplied ? VI6_BRU_BLD_CCMDY_COEFY :
+ VI6_BRU_BLD_CCMDY_SRC_A) |
VI6_BRU_BLD_ACMDX_255_SRC_A |
VI6_BRU_BLD_ACMDY_COEFY |
(0xff << VI6_BRU_BLD_COEFY_SHIFT));
@@ -192,7 +235,7 @@ static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru,
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_crop(fh, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &bru->compose[pad];
+ return &bru->inputs[pad].compose;
default:
return NULL;
}
@@ -391,5 +434,19 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
vsp1_entity_init_formats(subdev, NULL);
+ /* Initialize the control handler. */
+ v4l2_ctrl_handler_init(&bru->ctrls, 1);
+ v4l2_ctrl_new_std(&bru->ctrls, &bru_ctrl_ops, V4L2_CID_BG_COLOR,
+ 0, 0xffffff, 1, 0);
+
+ bru->entity.subdev.ctrl_handler = &bru->ctrls;
+
+ if (bru->ctrls.error) {
+ dev_err(vsp1->dev, "bru: failed to initialize controls\n");
+ ret = bru->ctrls.error;
+ vsp1_entity_destroy(&bru->entity);
+ return ERR_PTR(ret);
+ }
+
return bru;
}
diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
index 37062704dbf6..16b1c6554911 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.h
+++ b/drivers/media/platform/vsp1/vsp1_bru.h
@@ -14,11 +14,13 @@
#define __VSP1_BRU_H__
#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include "vsp1_entity.h"
struct vsp1_device;
+struct vsp1_rwpf;
#define BRU_PAD_SINK(n) (n)
#define BRU_PAD_SOURCE 4
@@ -26,7 +28,12 @@ struct vsp1_device;
struct vsp1_bru {
struct vsp1_entity entity;
- struct v4l2_rect compose[4];
+ struct v4l2_ctrl_handler ctrls;
+
+ struct {
+ struct vsp1_rwpf *rpf;
+ struct v4l2_rect compose;
+ } inputs[4];
};
static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index c69ee0657f75..3e6601b5b4de 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -345,36 +345,32 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
* Increment the VSP1 reference count and initialize the device if the first
* reference is taken.
*
- * Return a pointer to the VSP1 device or NULL if an error occurred.
+ * Return 0 on success or a negative error code otherwise.
*/
-struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
+int vsp1_device_get(struct vsp1_device *vsp1)
{
- struct vsp1_device *__vsp1 = vsp1;
- int ret;
+ int ret = 0;
mutex_lock(&vsp1->lock);
if (vsp1->ref_count > 0)
goto done;
ret = clk_prepare_enable(vsp1->clock);
- if (ret < 0) {
- __vsp1 = NULL;
+ if (ret < 0)
goto done;
- }
ret = vsp1_device_init(vsp1);
if (ret < 0) {
clk_disable_unprepare(vsp1->clock);
- __vsp1 = NULL;
goto done;
}
done:
- if (__vsp1)
+ if (!ret)
vsp1->ref_count++;
mutex_unlock(&vsp1->lock);
- return __vsp1;
+ return ret;
}
/*
@@ -440,19 +436,19 @@ static int vsp1_validate_platform_data(struct platform_device *pdev,
return -EINVAL;
}
- if (pdata->rpf_count <= 0 || pdata->rpf_count > VPS1_MAX_RPF) {
+ if (pdata->rpf_count <= 0 || pdata->rpf_count > VSP1_MAX_RPF) {
dev_err(&pdev->dev, "invalid number of RPF (%u)\n",
pdata->rpf_count);
return -EINVAL;
}
- if (pdata->uds_count <= 0 || pdata->uds_count > VPS1_MAX_UDS) {
+ if (pdata->uds_count <= 0 || pdata->uds_count > VSP1_MAX_UDS) {
dev_err(&pdev->dev, "invalid number of UDS (%u)\n",
pdata->uds_count);
return -EINVAL;
}
- if (pdata->wpf_count <= 0 || pdata->wpf_count > VPS1_MAX_WPF) {
+ if (pdata->wpf_count <= 0 || pdata->wpf_count > VSP1_MAX_WPF) {
dev_err(&pdev->dev, "invalid number of WPF (%u)\n",
pdata->wpf_count);
return -EINVAL;
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 44167834285d..79af71d5e270 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -20,6 +20,42 @@
#include "vsp1.h"
#include "vsp1_entity.h"
+#include "vsp1_video.h"
+
+bool vsp1_entity_is_streaming(struct vsp1_entity *entity)
+{
+ bool streaming;
+
+ mutex_lock(&entity->lock);
+ streaming = entity->streaming;
+ mutex_unlock(&entity->lock);
+
+ return streaming;
+}
+
+int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming)
+{
+ int ret;
+
+ mutex_lock(&entity->lock);
+ entity->streaming = streaming;
+ mutex_unlock(&entity->lock);
+
+ if (!streaming)
+ return 0;
+
+ if (!entity->subdev.ctrl_handler)
+ return 0;
+
+ ret = v4l2_ctrl_handler_setup(entity->subdev.ctrl_handler);
+ if (ret < 0) {
+ mutex_lock(&entity->lock);
+ entity->streaming = false;
+ mutex_unlock(&entity->lock);
+ }
+
+ return ret;
+}
/* -----------------------------------------------------------------------------
* V4L2 Subdevice Operations
@@ -157,6 +193,8 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
if (i == ARRAY_SIZE(vsp1_routes))
return -EINVAL;
+ mutex_init(&entity->lock);
+
entity->vsp1 = vsp1;
entity->source_pad = num_pads - 1;
@@ -185,7 +223,11 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
void vsp1_entity_destroy(struct vsp1_entity *entity)
{
+ if (entity->video)
+ vsp1_video_cleanup(entity->video);
if (entity->subdev.ctrl_handler)
v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
media_entity_cleanup(&entity->subdev.entity);
+
+ mutex_destroy(&entity->lock);
}
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 7afbd8a7ba66..aa20aaa58208 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -14,10 +14,12 @@
#define __VSP1_ENTITY_H__
#include <linux/list.h>
+#include <linux/mutex.h>
#include <media/v4l2-subdev.h>
struct vsp1_device;
+struct vsp1_video;
enum vsp1_entity_type {
VSP1_ENTITY_BRU,
@@ -68,6 +70,11 @@ struct vsp1_entity {
struct v4l2_subdev subdev;
struct v4l2_mbus_framefmt *formats;
+
+ struct vsp1_video *video;
+
+ struct mutex lock; /* Protects the streaming field */
+ bool streaming;
};
static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev)
@@ -89,4 +96,7 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity,
void vsp1_entity_init_formats(struct v4l2_subdev *subdev,
struct v4l2_subdev_fh *fh);
+bool vsp1_entity_is_streaming(struct vsp1_entity *entity);
+int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming);
+
#endif /* __VSP1_ENTITY_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 3e74b44286f6..55f163d32d15 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -336,7 +336,9 @@
*/
#define VI6_SRU_CTRL0 0x2200
+#define VI6_SRU_CTRL0_PARAM0_MASK (0x1ff << 16)
#define VI6_SRU_CTRL0_PARAM0_SHIFT 16
+#define VI6_SRU_CTRL0_PARAM1_MASK (0x1f << 8)
#define VI6_SRU_CTRL0_PARAM1_SHIFT 8
#define VI6_SRU_CTRL0_MODE_UPSCALE (4 << 4)
#define VI6_SRU_CTRL0_PARAM2 (1 << 3)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index c3d98642a4aa..d14d26b718ef 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -39,6 +39,36 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data)
}
/* -----------------------------------------------------------------------------
+ * Controls
+ */
+
+static int rpf_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vsp1_rwpf *rpf =
+ container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
+ struct vsp1_pipeline *pipe;
+
+ if (!vsp1_entity_is_streaming(&rpf->entity))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ALPHA_COMPONENT:
+ vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
+ ctrl->val << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
+
+ pipe = to_vsp1_pipeline(&rpf->entity.subdev.entity);
+ vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, ctrl->val);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops rpf_ctrl_ops = {
+ .s_ctrl = rpf_s_ctrl,
+};
+
+/* -----------------------------------------------------------------------------
* V4L2 Subdevice Core Operations
*/
@@ -50,6 +80,11 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
const struct v4l2_rect *crop = &rpf->crop;
u32 pstride;
u32 infmt;
+ int ret;
+
+ ret = vsp1_entity_set_streaming(&rpf->entity, enable);
+ if (ret < 0)
+ return ret;
if (!enable)
return 0;
@@ -101,12 +136,13 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
(rpf->location.left << VI6_RPF_LOC_HCOORD_SHIFT) |
(rpf->location.top << VI6_RPF_LOC_VCOORD_SHIFT));
- /* Disable alpha, mask and color key. Set the alpha channel to a fixed
- * value of 255.
+ /* Use the alpha channel (extended to 8 bits) when available or an
+ * alpha value set through the V4L2_CID_ALPHA_COMPONENT control
+ * otherwise. Disable color keying.
*/
- vsp1_rpf_write(rpf, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_FIXED);
- vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET,
- 255 << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
+ vsp1_rpf_write(rpf, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_AEXT_EXT |
+ (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
+ : VI6_RPF_ALPH_SEL_ASEL_FIXED));
vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0);
vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0);
@@ -196,6 +232,20 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
vsp1_entity_init_formats(subdev, NULL);
+ /* Initialize the control handler. */
+ v4l2_ctrl_handler_init(&rpf->ctrls, 1);
+ v4l2_ctrl_new_std(&rpf->ctrls, &rpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
+ 0, 255, 1, 255);
+
+ rpf->entity.subdev.ctrl_handler = &rpf->ctrls;
+
+ if (rpf->ctrls.error) {
+ dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n",
+ index);
+ ret = rpf->ctrls.error;
+ goto error;
+ }
+
/* Initialize the video device. */
video = &rpf->video;
@@ -205,7 +255,9 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
ret = vsp1_video_init(video, &rpf->entity);
if (ret < 0)
- goto error_video;
+ goto error;
+
+ rpf->entity.video = video;
/* Connect the video device to the RPF. */
ret = media_entity_create_link(&rpf->video.video.entity, 0,
@@ -214,13 +266,11 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE);
if (ret < 0)
- goto error_link;
+ goto error;
return rpf;
-error_link:
- vsp1_video_cleanup(video);
-error_video:
- media_entity_cleanup(&rpf->entity.subdev.entity);
+error:
+ vsp1_entity_destroy(&rpf->entity);
return ERR_PTR(ret);
}
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index b4fb65e58770..28dd9e7b3838 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -14,6 +14,7 @@
#define __VSP1_RWPF_H__
#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include "vsp1.h"
@@ -26,6 +27,7 @@
struct vsp1_rwpf {
struct vsp1_entity entity;
struct vsp1_video video;
+ struct v4l2_ctrl_handler ctrls;
unsigned int max_width;
unsigned int max_height;
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index aa0e04c56f3f..b7d3c8b9f189 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -42,38 +42,6 @@ static inline void vsp1_sru_write(struct vsp1_sru *sru, u32 reg, u32 data)
#define V4L2_CID_VSP1_SRU_INTENSITY (V4L2_CID_USER_BASE + 1)
-static int sru_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct vsp1_sru *sru =
- container_of(ctrl->handler, struct vsp1_sru, ctrls);
-
- switch (ctrl->id) {
- case V4L2_CID_VSP1_SRU_INTENSITY:
- sru->intensity = ctrl->val;
- break;
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops sru_ctrl_ops = {
- .s_ctrl = sru_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config sru_intensity_control = {
- .ops = &sru_ctrl_ops,
- .id = V4L2_CID_VSP1_SRU_INTENSITY,
- .name = "Intensity",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .min = 1,
- .max = 6,
- .step = 1,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 Subdevice Core Operations
- */
-
struct vsp1_sru_param {
u32 ctrl0;
u32 ctrl2;
@@ -110,22 +78,66 @@ static const struct vsp1_sru_param vsp1_sru_params[] = {
},
};
+static int sru_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vsp1_sru *sru =
+ container_of(ctrl->handler, struct vsp1_sru, ctrls);
+ const struct vsp1_sru_param *param;
+ u32 value;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VSP1_SRU_INTENSITY:
+ param = &vsp1_sru_params[ctrl->val - 1];
+
+ value = vsp1_sru_read(sru, VI6_SRU_CTRL0);
+ value &= ~(VI6_SRU_CTRL0_PARAM0_MASK |
+ VI6_SRU_CTRL0_PARAM1_MASK);
+ value |= param->ctrl0;
+ vsp1_sru_write(sru, VI6_SRU_CTRL0, value);
+
+ vsp1_sru_write(sru, VI6_SRU_CTRL2, param->ctrl2);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops sru_ctrl_ops = {
+ .s_ctrl = sru_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config sru_intensity_control = {
+ .ops = &sru_ctrl_ops,
+ .id = V4L2_CID_VSP1_SRU_INTENSITY,
+ .name = "Intensity",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .min = 1,
+ .max = 6,
+ .def = 1,
+ .step = 1,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 Subdevice Core Operations
+ */
+
static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
{
struct vsp1_sru *sru = to_sru(subdev);
- const struct vsp1_sru_param *param;
struct v4l2_mbus_framefmt *input;
struct v4l2_mbus_framefmt *output;
- bool upscale;
u32 ctrl0;
+ int ret;
+
+ ret = vsp1_entity_set_streaming(&sru->entity, enable);
+ if (ret < 0)
+ return ret;
if (!enable)
return 0;
input = &sru->entity.formats[SRU_PAD_SINK];
output = &sru->entity.formats[SRU_PAD_SOURCE];
- upscale = input->width != output->width;
- param = &vsp1_sru_params[sru->intensity];
if (input->code == V4L2_MBUS_FMT_ARGB8888_1X32)
ctrl0 = VI6_SRU_CTRL0_PARAM2 | VI6_SRU_CTRL0_PARAM3
@@ -133,10 +145,18 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
else
ctrl0 = VI6_SRU_CTRL0_PARAM3;
- vsp1_sru_write(sru, VI6_SRU_CTRL0, param->ctrl0 | ctrl0 |
- (upscale ? VI6_SRU_CTRL0_MODE_UPSCALE : 0));
+ if (input->width != output->width)
+ ctrl0 |= VI6_SRU_CTRL0_MODE_UPSCALE;
+
+ /* Take the control handler lock to ensure that the CTRL0 value won't be
+ * changed behind our back by a set control operation.
+ */
+ mutex_lock(sru->ctrls.lock);
+ ctrl0 |= vsp1_sru_read(sru, VI6_SRU_CTRL0)
+ & (VI6_SRU_CTRL0_PARAM0_MASK | VI6_SRU_CTRL0_PARAM1_MASK);
+ mutex_unlock(sru->ctrls.lock);
+
vsp1_sru_write(sru, VI6_SRU_CTRL1, VI6_SRU_CTRL1_PARAM5);
- vsp1_sru_write(sru, VI6_SRU_CTRL2, param->ctrl2);
return 0;
}
@@ -348,8 +368,15 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&sru->ctrls, 1);
v4l2_ctrl_new_custom(&sru->ctrls, &sru_intensity_control, NULL);
- v4l2_ctrl_handler_setup(&sru->ctrls);
+
sru->entity.subdev.ctrl_handler = &sru->ctrls;
+ if (sru->ctrls.error) {
+ dev_err(vsp1->dev, "sru: failed to initialize controls\n");
+ ret = sru->ctrls.error;
+ vsp1_entity_destroy(&sru->entity);
+ return ERR_PTR(ret);
+ }
+
return sru;
}
diff --git a/drivers/media/platform/vsp1/vsp1_sru.h b/drivers/media/platform/vsp1/vsp1_sru.h
index 381870b74780..b6768bf3dc47 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.h
+++ b/drivers/media/platform/vsp1/vsp1_sru.h
@@ -28,7 +28,6 @@ struct vsp1_sru {
struct vsp1_entity entity;
struct v4l2_ctrl_handler ctrls;
- unsigned int intensity;
};
static inline struct vsp1_sru *to_sru(struct v4l2_subdev *subdev)
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 0293bdbb4401..de92ef4944b3 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -45,6 +45,11 @@ static inline void vsp1_uds_write(struct vsp1_uds *uds, u32 reg, u32 data)
* Scaling Computation
*/
+void vsp1_uds_set_alpha(struct vsp1_uds *uds, unsigned int alpha)
+{
+ vsp1_uds_write(uds, VI6_UDS_ALPVAL, alpha << VI6_UDS_ALPVAL_VAL0_SHIFT);
+}
+
/*
* uds_output_size - Return the output size for an input size and scaling ratio
* @input: input size in pixels
@@ -105,49 +110,56 @@ static unsigned int uds_compute_ratio(unsigned int input, unsigned int output)
return (input - 1) * 4096 / (output - 1);
}
-static void uds_compute_ratios(struct vsp1_uds *uds)
-{
- struct v4l2_mbus_framefmt *input = &uds->entity.formats[UDS_PAD_SINK];
- struct v4l2_mbus_framefmt *output =
- &uds->entity.formats[UDS_PAD_SOURCE];
-
- uds->hscale = uds_compute_ratio(input->width, output->width);
- uds->vscale = uds_compute_ratio(input->height, output->height);
-
- dev_dbg(uds->entity.vsp1->dev, "hscale %u vscale %u\n",
- uds->hscale, uds->vscale);
-}
-
/* -----------------------------------------------------------------------------
* V4L2 Subdevice Core Operations
*/
static int uds_s_stream(struct v4l2_subdev *subdev, int enable)
{
- const struct v4l2_mbus_framefmt *format;
struct vsp1_uds *uds = to_uds(subdev);
+ const struct v4l2_mbus_framefmt *output;
+ const struct v4l2_mbus_framefmt *input;
+ unsigned int hscale;
+ unsigned int vscale;
+ bool multitap;
if (!enable)
return 0;
- /* Enable multi-tap scaling. */
- vsp1_uds_write(uds, VI6_UDS_CTRL, VI6_UDS_CTRL_AON | VI6_UDS_CTRL_BC);
+ input = &uds->entity.formats[UDS_PAD_SINK];
+ output = &uds->entity.formats[UDS_PAD_SOURCE];
+
+ hscale = uds_compute_ratio(input->width, output->width);
+ vscale = uds_compute_ratio(input->height, output->height);
+
+ dev_dbg(uds->entity.vsp1->dev, "hscale %u vscale %u\n", hscale, vscale);
+
+ /* Multi-tap scaling can't be enabled along with alpha scaling when
+ * scaling down with a factor lower than or equal to 1/2 in either
+ * direction.
+ */
+ if (uds->scale_alpha && (hscale >= 8192 || vscale >= 8192))
+ multitap = false;
+ else
+ multitap = true;
+
+ vsp1_uds_write(uds, VI6_UDS_CTRL,
+ (uds->scale_alpha ? VI6_UDS_CTRL_AON : 0) |
+ (multitap ? VI6_UDS_CTRL_BC : 0));
vsp1_uds_write(uds, VI6_UDS_PASS_BWIDTH,
- (uds_passband_width(uds->hscale)
+ (uds_passband_width(hscale)
<< VI6_UDS_PASS_BWIDTH_H_SHIFT) |
- (uds_passband_width(uds->vscale)
+ (uds_passband_width(vscale)
<< VI6_UDS_PASS_BWIDTH_V_SHIFT));
/* Set the scaling ratios and the output size. */
- format = &uds->entity.formats[UDS_PAD_SOURCE];
-
vsp1_uds_write(uds, VI6_UDS_SCALE,
- (uds->hscale << VI6_UDS_SCALE_HFRAC_SHIFT) |
- (uds->vscale << VI6_UDS_SCALE_VFRAC_SHIFT));
+ (hscale << VI6_UDS_SCALE_HFRAC_SHIFT) |
+ (vscale << VI6_UDS_SCALE_VFRAC_SHIFT));
vsp1_uds_write(uds, VI6_UDS_CLIP_SIZE,
- (format->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) |
- (format->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT));
+ (output->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) |
+ (output->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT));
return 0;
}
@@ -280,9 +292,6 @@ static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
uds_try_format(uds, fh, UDS_PAD_SOURCE, format, fmt->which);
}
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- uds_compute_ratios(uds);
-
return 0;
}
diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
index 479d12df1180..031ac0da1b66 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.h
+++ b/drivers/media/platform/vsp1/vsp1_uds.h
@@ -25,9 +25,7 @@ struct vsp1_device;
struct vsp1_uds {
struct vsp1_entity entity;
-
- unsigned int hscale;
- unsigned int vscale;
+ bool scale_alpha;
};
static inline struct vsp1_uds *to_uds(struct v4l2_subdev *subdev)
@@ -37,4 +35,6 @@ static inline struct vsp1_uds *to_uds(struct v4l2_subdev *subdev)
struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index);
+void vsp1_uds_set_alpha(struct vsp1_uds *uds, unsigned int alpha);
+
#endif /* __VSP1_UDS_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 8a1253e51f04..915a20eb003e 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -31,6 +31,7 @@
#include "vsp1_bru.h"
#include "vsp1_entity.h"
#include "vsp1_rwpf.h"
+#include "vsp1_uds.h"
#include "vsp1_video.h"
#define VSP1_VIDEO_DEF_FORMAT V4L2_PIX_FMT_YUYV
@@ -50,70 +51,85 @@ static const struct vsp1_format_info vsp1_video_formats[] = {
{ V4L2_PIX_FMT_RGB332, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 8, 0, 0 }, false, false, 1, 1 },
- { V4L2_PIX_FMT_RGB444, V4L2_MBUS_FMT_ARGB8888_1X32,
+ 1, { 8, 0, 0 }, false, false, 1, 1, false },
+ { V4L2_PIX_FMT_ARGB444, V4L2_MBUS_FMT_ARGB8888_1X32,
+ VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS,
+ 1, { 16, 0, 0 }, false, false, 1, 1, true },
+ { V4L2_PIX_FMT_XRGB444, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS,
- 1, { 16, 0, 0 }, false, false, 1, 1 },
- { V4L2_PIX_FMT_RGB555, V4L2_MBUS_FMT_ARGB8888_1X32,
+ 1, { 16, 0, 0 }, false, false, 1, 1, true },
+ { V4L2_PIX_FMT_ARGB555, V4L2_MBUS_FMT_ARGB8888_1X32,
+ VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS,
+ 1, { 16, 0, 0 }, false, false, 1, 1, true },
+ { V4L2_PIX_FMT_XRGB555, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS,
- 1, { 16, 0, 0 }, false, false, 1, 1 },
+ 1, { 16, 0, 0 }, false, false, 1, 1, false },
{ V4L2_PIX_FMT_RGB565, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS,
- 1, { 16, 0, 0 }, false, false, 1, 1 },
+ 1, { 16, 0, 0 }, false, false, 1, 1, false },
{ V4L2_PIX_FMT_BGR24, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 24, 0, 0 }, false, false, 1, 1 },
+ 1, { 24, 0, 0 }, false, false, 1, 1, false },
{ V4L2_PIX_FMT_RGB24, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 24, 0, 0 }, false, false, 1, 1 },
- { V4L2_PIX_FMT_BGR32, V4L2_MBUS_FMT_ARGB8888_1X32,
+ 1, { 24, 0, 0 }, false, false, 1, 1, false },
+ { V4L2_PIX_FMT_ABGR32, V4L2_MBUS_FMT_ARGB8888_1X32,
+ VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
+ 1, { 32, 0, 0 }, false, false, 1, 1, true },
+ { V4L2_PIX_FMT_XBGR32, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
- 1, { 32, 0, 0 }, false, false, 1, 1 },
- { V4L2_PIX_FMT_RGB32, V4L2_MBUS_FMT_ARGB8888_1X32,
+ 1, { 32, 0, 0 }, false, false, 1, 1, false },
+ { V4L2_PIX_FMT_ARGB32, V4L2_MBUS_FMT_ARGB8888_1X32,
+ VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+ 1, { 32, 0, 0 }, false, false, 1, 1, true },
+ { V4L2_PIX_FMT_XRGB32, V4L2_MBUS_FMT_ARGB8888_1X32,
VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 32, 0, 0 }, false, false, 1, 1 },
+ 1, { 32, 0, 0 }, false, false, 1, 1, false },
{ V4L2_PIX_FMT_UYVY, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 16, 0, 0 }, false, false, 2, 1 },
+ 1, { 16, 0, 0 }, false, false, 2, 1, false },
{ V4L2_PIX_FMT_VYUY, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 16, 0, 0 }, false, true, 2, 1 },
+ 1, { 16, 0, 0 }, false, true, 2, 1, false },
{ V4L2_PIX_FMT_YUYV, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 16, 0, 0 }, true, false, 2, 1 },
+ 1, { 16, 0, 0 }, true, false, 2, 1, false },
{ V4L2_PIX_FMT_YVYU, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 1, { 16, 0, 0 }, true, true, 2, 1 },
+ 1, { 16, 0, 0 }, true, true, 2, 1, false },
{ V4L2_PIX_FMT_NV12M, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 2, { 8, 16, 0 }, false, false, 2, 2 },
+ 2, { 8, 16, 0 }, false, false, 2, 2, false },
{ V4L2_PIX_FMT_NV21M, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 2, { 8, 16, 0 }, false, true, 2, 2 },
+ 2, { 8, 16, 0 }, false, true, 2, 2, false },
{ V4L2_PIX_FMT_NV16M, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 2, { 8, 16, 0 }, false, false, 2, 1 },
+ 2, { 8, 16, 0 }, false, false, 2, 1, false },
{ V4L2_PIX_FMT_NV61M, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 2, { 8, 16, 0 }, false, true, 2, 1 },
+ 2, { 8, 16, 0 }, false, true, 2, 1, false },
{ V4L2_PIX_FMT_YUV420M, V4L2_MBUS_FMT_AYUV8_1X32,
VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
- 3, { 8, 8, 8 }, false, false, 2, 2 },
+ 3, { 8, 8, 8 }, false, false, 2, 2, false },
};
/*
@@ -181,11 +197,29 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
struct v4l2_pix_format_mplane *pix,
const struct vsp1_format_info **fmtinfo)
{
+ static const u32 xrgb_formats[][2] = {
+ { V4L2_PIX_FMT_RGB444, V4L2_PIX_FMT_XRGB444 },
+ { V4L2_PIX_FMT_RGB555, V4L2_PIX_FMT_XRGB555 },
+ { V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_XBGR32 },
+ { V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_XRGB32 },
+ };
+
const struct vsp1_format_info *info;
unsigned int width = pix->width;
unsigned int height = pix->height;
unsigned int i;
+ /* Backward compatibility: replace deprecated RGB formats by their XRGB
+ * equivalent. This selects the format older userspace applications want
+ * while still exposing the new format.
+ */
+ for (i = 0; i < ARRAY_SIZE(xrgb_formats); ++i) {
+ if (xrgb_formats[i][0] == pix->pixelformat) {
+ pix->pixelformat = xrgb_formats[i][1];
+ break;
+ }
+ }
+
/* Retrieve format information and select the default format if the
* requested format isn't supported.
*/
@@ -273,13 +307,14 @@ vsp1_video_format_adjust(struct vsp1_video *video,
* Pipeline Management
*/
-static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
+static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
+ struct vsp1_rwpf *input,
struct vsp1_rwpf *output)
{
struct vsp1_entity *entity;
unsigned int entities = 0;
struct media_pad *pad;
- bool uds_found = false;
+ bool bru_found = false;
input->location.left = 0;
input->location.top = 0;
@@ -301,10 +336,15 @@ static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
*/
if (entity->type == VSP1_ENTITY_BRU) {
struct vsp1_bru *bru = to_bru(&entity->subdev);
- struct v4l2_rect *rect = &bru->compose[pad->index];
+ struct v4l2_rect *rect =
+ &bru->inputs[pad->index].compose;
+
+ bru->inputs[pad->index].rpf = input;
input->location.left = rect->left;
input->location.top = rect->top;
+
+ bru_found = true;
}
/* We've reached the WPF, we're done. */
@@ -319,9 +359,12 @@ static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
/* UDS can't be chained. */
if (entity->type == VSP1_ENTITY_UDS) {
- if (uds_found)
+ if (pipe->uds)
return -EPIPE;
- uds_found = true;
+
+ pipe->uds = entity;
+ pipe->uds_input = bru_found ? pipe->bru
+ : &input->entity;
}
/* Follow the source link. The link setup operations ensure
@@ -340,6 +383,27 @@ static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
return 0;
}
+static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
+{
+ if (pipe->bru) {
+ struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(bru->inputs); ++i)
+ bru->inputs[i].rpf = NULL;
+ }
+
+ INIT_LIST_HEAD(&pipe->entities);
+ pipe->state = VSP1_PIPELINE_STOPPED;
+ pipe->buffers_ready = 0;
+ pipe->num_video = 0;
+ pipe->num_inputs = 0;
+ pipe->output = NULL;
+ pipe->bru = NULL;
+ pipe->lif = NULL;
+ pipe->uds = NULL;
+}
+
static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
struct vsp1_video *video)
{
@@ -395,7 +459,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
* contains no loop and that all branches end at the output WPF.
*/
for (i = 0; i < pipe->num_inputs; ++i) {
- ret = vsp1_pipeline_validate_branch(pipe->inputs[i],
+ ret = vsp1_pipeline_validate_branch(pipe, pipe->inputs[i],
pipe->output);
if (ret < 0)
goto error;
@@ -404,13 +468,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
return 0;
error:
- INIT_LIST_HEAD(&pipe->entities);
- pipe->buffers_ready = 0;
- pipe->num_video = 0;
- pipe->num_inputs = 0;
- pipe->output = NULL;
- pipe->bru = NULL;
- pipe->lif = NULL;
+ __vsp1_pipeline_cleanup(pipe);
return ret;
}
@@ -441,16 +499,8 @@ static void vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
mutex_lock(&pipe->lock);
/* If we're the last user clean up the pipeline. */
- if (--pipe->use_count == 0) {
- INIT_LIST_HEAD(&pipe->entities);
- pipe->state = VSP1_PIPELINE_STOPPED;
- pipe->buffers_ready = 0;
- pipe->num_video = 0;
- pipe->num_inputs = 0;
- pipe->output = NULL;
- pipe->bru = NULL;
- pipe->lif = NULL;
- }
+ if (--pipe->use_count == 0)
+ __vsp1_pipeline_cleanup(pipe);
mutex_unlock(&pipe->lock);
}
@@ -471,7 +521,8 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
int ret;
spin_lock_irqsave(&pipe->irqlock, flags);
- pipe->state = VSP1_PIPELINE_STOPPING;
+ if (pipe->state == VSP1_PIPELINE_RUNNING)
+ pipe->state = VSP1_PIPELINE_STOPPING;
spin_unlock_irqrestore(&pipe->irqlock, flags);
ret = wait_event_timeout(pipe->wq, pipe->state == VSP1_PIPELINE_STOPPED,
@@ -479,7 +530,7 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
ret = ret == 0 ? -ETIMEDOUT : 0;
list_for_each_entry(entity, &pipe->entities, list_pipe) {
- if (entity->route)
+ if (entity->route && entity->route->reg)
vsp1_write(entity->vsp1, entity->route->reg,
VI6_DPR_NODE_UNUSED);
@@ -576,6 +627,7 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
{
+ enum vsp1_pipeline_state state;
unsigned long flags;
unsigned int i;
@@ -591,11 +643,13 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
spin_lock_irqsave(&pipe->irqlock, flags);
+ state = pipe->state;
+ pipe->state = VSP1_PIPELINE_STOPPED;
+
/* If a stop has been requested, mark the pipeline as stopped and
* return.
*/
- if (pipe->state == VSP1_PIPELINE_STOPPING) {
- pipe->state = VSP1_PIPELINE_STOPPED;
+ if (state == VSP1_PIPELINE_STOPPING) {
wake_up(&pipe->wq);
goto done;
}
@@ -608,6 +662,47 @@ done:
spin_unlock_irqrestore(&pipe->irqlock, flags);
}
+/*
+ * Propagate the alpha value through the pipeline.
+ *
+ * As the UDS has restricted scaling capabilities when the alpha component needs
+ * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha
+ * value. The UDS then outputs a fixed alpha value which needs to be programmed
+ * from the input RPF alpha.
+ */
+void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
+ struct vsp1_entity *input,
+ unsigned int alpha)
+{
+ struct vsp1_entity *entity;
+ struct media_pad *pad;
+
+ pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
+
+ while (pad) {
+ if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ break;
+
+ entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
+
+ /* The BRU background color has a fixed alpha value set to 255,
+ * the output alpha value is thus always equal to 255.
+ */
+ if (entity->type == VSP1_ENTITY_BRU)
+ alpha = 255;
+
+ if (entity->type == VSP1_ENTITY_UDS) {
+ struct vsp1_uds *uds = to_uds(&entity->subdev);
+
+ vsp1_uds_set_alpha(uds, alpha);
+ break;
+ }
+
+ pad = &entity->pads[entity->source_pad];
+ pad = media_entity_remote_pad(pad);
+ }
+}
+
/* -----------------------------------------------------------------------------
* videobuf2 Queue Operations
*/
@@ -654,8 +749,6 @@ static int vsp1_video_buffer_prepare(struct vb2_buffer *vb)
if (vb->num_planes < format->num_planes)
return -EINVAL;
- buf->video = video;
-
for (i = 0; i < vb->num_planes; ++i) {
buf->addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
buf->length[i] = vb2_plane_size(vb, i);
@@ -717,6 +810,25 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
mutex_lock(&pipe->lock);
if (pipe->stream_count == pipe->num_video - 1) {
+ if (pipe->uds) {
+ 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 (pipe->uds_input->type == VSP1_ENTITY_BRU) {
+ uds->scale_alpha = false;
+ } else {
+ struct vsp1_rwpf *rpf =
+ to_rwpf(&pipe->uds_input->subdev);
+
+ uds->scale_alpha = rpf->video.fmtinfo->alpha;
+ }
+ }
+
list_for_each_entry(entity, &pipe->entities, list_pipe) {
vsp1_entity_route_setup(entity);
@@ -744,6 +856,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
{
struct vsp1_video *video = vb2_get_drv_priv(vq);
struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity);
+ struct vsp1_video_buffer *buffer;
unsigned long flags;
int ret;
@@ -761,6 +874,8 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
/* Remove all buffers from the IRQ queue. */
spin_lock_irqsave(&video->irqlock, flags);
+ list_for_each_entry(buffer, &video->irqqueue, queue)
+ vb2_buffer_done(&buffer->buf, VB2_BUF_STATE_ERROR);
INIT_LIST_HEAD(&video->irqqueue);
spin_unlock_irqrestore(&video->irqlock, flags);
}
@@ -950,8 +1065,8 @@ static int vsp1_video_open(struct file *file)
file->private_data = vfh;
- if (!vsp1_device_get(video->vsp1)) {
- ret = -EBUSY;
+ ret = vsp1_device_get(video->vsp1);
+ if (ret < 0) {
v4l2_fh_del(vfh);
kfree(vfh);
}
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index c04d48fa2999..fd2851a82e00 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -33,6 +33,7 @@ struct vsp1_video;
* @swap_uv: the U and V components are swapped (V comes before U)
* @hsub: horizontal subsampling factor
* @vsub: vertical subsampling factor
+ * @alpha: has an alpha channel
*/
struct vsp1_format_info {
u32 fourcc;
@@ -45,6 +46,7 @@ struct vsp1_format_info {
bool swap_uv;
unsigned int hsub;
unsigned int vsub;
+ bool alpha;
};
enum vsp1_pipeline_state {
@@ -73,10 +75,12 @@ struct vsp1_pipeline {
unsigned int num_video;
unsigned int num_inputs;
- struct vsp1_rwpf *inputs[VPS1_MAX_RPF];
+ struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
struct vsp1_rwpf *output;
struct vsp1_entity *bru;
struct vsp1_entity *lif;
+ struct vsp1_entity *uds;
+ struct vsp1_entity *uds_input;
struct list_head entities;
};
@@ -90,7 +94,6 @@ static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e)
}
struct vsp1_video_buffer {
- struct vsp1_video *video;
struct vb2_buffer buf;
struct list_head queue;
@@ -142,4 +145,8 @@ void vsp1_video_cleanup(struct vsp1_video *video);
void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
+void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
+ struct vsp1_entity *input,
+ unsigned int alpha);
+
#endif /* __VSP1_VIDEO_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1294340dcb36..6e057762c933 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -39,22 +39,56 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data)
}
/* -----------------------------------------------------------------------------
+ * Controls
+ */
+
+static int wpf_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vsp1_rwpf *wpf =
+ container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
+ u32 value;
+
+ if (!vsp1_entity_is_streaming(&wpf->entity))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ALPHA_COMPONENT:
+ value = vsp1_wpf_read(wpf, VI6_WPF_OUTFMT);
+ value &= ~VI6_WPF_OUTFMT_PDV_MASK;
+ value |= ctrl->val << VI6_WPF_OUTFMT_PDV_SHIFT;
+ vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, value);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops wpf_ctrl_ops = {
+ .s_ctrl = wpf_s_ctrl,
+};
+
+/* -----------------------------------------------------------------------------
* V4L2 Subdevice Core Operations
*/
static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
{
+ struct vsp1_pipeline *pipe = to_vsp1_pipeline(&subdev->entity);
struct vsp1_rwpf *wpf = to_rwpf(subdev);
- struct vsp1_pipeline *pipe =
- to_vsp1_pipeline(&wpf->entity.subdev.entity);
struct vsp1_device *vsp1 = wpf->entity.vsp1;
const struct v4l2_rect *crop = &wpf->crop;
unsigned int i;
u32 srcrpf = 0;
u32 outfmt = 0;
+ int ret;
+
+ ret = vsp1_entity_set_streaming(&wpf->entity, enable);
+ if (ret < 0)
+ return ret;
if (!enable) {
vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0);
+ vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, 0);
return 0;
}
@@ -99,6 +133,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT;
+ if (fmtinfo->alpha)
+ outfmt |= VI6_WPF_OUTFMT_PXA;
if (fmtinfo->swap_yc)
outfmt |= VI6_WPF_OUTFMT_SPYCS;
if (fmtinfo->swap_uv)
@@ -111,7 +147,13 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
wpf->entity.formats[RWPF_PAD_SOURCE].code)
outfmt |= VI6_WPF_OUTFMT_CSC;
+ /* Take the control handler lock to ensure that the PDV value won't be
+ * changed behind our back by a set control operation.
+ */
+ mutex_lock(wpf->ctrls.lock);
+ outfmt |= vsp1_wpf_read(wpf, VI6_WPF_OUTFMT) & VI6_WPF_OUTFMT_PDV_MASK;
vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt);
+ mutex_unlock(wpf->ctrls.lock);
vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index),
VI6_DPR_WPF_FPORCH_FP_WPFN);
@@ -207,6 +249,20 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
vsp1_entity_init_formats(subdev, NULL);
+ /* Initialize the control handler. */
+ v4l2_ctrl_handler_init(&wpf->ctrls, 1);
+ v4l2_ctrl_new_std(&wpf->ctrls, &wpf_ctrl_ops, V4L2_CID_ALPHA_COMPONENT,
+ 0, 255, 1, 255);
+
+ wpf->entity.subdev.ctrl_handler = &wpf->ctrls;
+
+ if (wpf->ctrls.error) {
+ dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
+ index);
+ ret = wpf->ctrls.error;
+ goto error;
+ }
+
/* Initialize the video device. */
video = &wpf->video;
@@ -216,7 +272,9 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
ret = vsp1_video_init(video, &wpf->entity);
if (ret < 0)
- goto error_video;
+ goto error;
+
+ wpf->entity.video = video;
/* Connect the video device to the WPF. All connections are immutable
* except for the WPF0 source link if a LIF is present.
@@ -229,15 +287,13 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
RWPF_PAD_SOURCE,
&wpf->video.video.entity, 0, flags);
if (ret < 0)
- goto error_link;
+ goto error;
wpf->entity.sink = &wpf->video.video.entity;
return wpf;
-error_link:
- vsp1_video_cleanup(video);
-error_video:
- media_entity_cleanup(&wpf->entity.subdev.entity);
+error:
+ vsp1_entity_destroy(&wpf->entity);
return ERR_PTR(ret);
}
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 142c2ee64d31..2262b8139ca1 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -390,7 +390,6 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
radio->videodev.release = video_device_release_empty;
radio->videodev.lock = &radio->v4l2_lock;
radio->videodev.ctrl_handler = &radio->hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->videodev.flags);
radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = FREQ_MIN * FREQ_MUL;
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index d719e59e2179..82affaedf067 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -650,7 +650,6 @@ static int __init cadet_init(void)
dev->vdev.ioctl_ops = &cadet_ioctl_ops;
dev->vdev.release = video_device_release_empty;
dev->vdev.lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
video_set_drvdata(&dev->vdev, dev);
res = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c
index 6ff350831d56..c309ee45a08e 100644
--- a/drivers/media/radio/radio-isa.c
+++ b/drivers/media/radio/radio-isa.c
@@ -253,7 +253,6 @@ static int radio_isa_common_probe(struct radio_isa_card *isa,
isa->vdev.fops = &radio_isa_fops;
isa->vdev.ioctl_ops = &radio_isa_ioctl_ops;
isa->vdev.release = video_device_release_empty;
- set_bit(V4L2_FL_USE_FH_PRIO, &isa->vdev.flags);
video_set_drvdata(&isa->vdev, isa);
isa->freq = FREQ_LOW;
isa->stereo = drv->has_stereo;
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 3d127825eceb..0c5d2db3b828 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -265,7 +265,7 @@ static int keene_s_ctrl(struct v4l2_ctrl *ctrl)
return keene_cmd_set(radio);
case V4L2_CID_AUDIO_COMPRESSION_GAIN:
- radio->tx = db2tx[(ctrl->val - ctrl->minimum) / ctrl->step];
+ radio->tx = db2tx[(ctrl->val - (s32)ctrl->minimum) / (s32)ctrl->step];
return keene_cmd_set(radio);
}
return -EINVAL;
@@ -380,7 +380,6 @@ static int usb_keene_probe(struct usb_interface *intf,
usb_set_intfdata(intf, &radio->v4l2_dev);
video_set_drvdata(&radio->vdev, radio);
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
/* at least 11ms is needed in order to settle hardware */
msleep(20);
diff --git a/drivers/media/radio/radio-ma901.c b/drivers/media/radio/radio-ma901.c
index a85b064cb7be..b3000ef85ee7 100644
--- a/drivers/media/radio/radio-ma901.c
+++ b/drivers/media/radio/radio-ma901.c
@@ -411,7 +411,6 @@ static int usb_ma901radio_probe(struct usb_interface *intf,
radio->vdev.ioctl_ops = &usb_ma901radio_ioctl_ops;
radio->vdev.release = video_device_release_empty;
radio->vdev.lock = &radio->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
radio->usbdev = interface_to_usbdev(intf);
radio->intf = intf;
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index a7e93d7477dd..998919e97dfe 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -1,20 +1,35 @@
-/* Miro PCM20 radio driver for Linux radio support
+/*
+ * Miro PCM20 radio driver for Linux radio support
* (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
* Thanks to Norberto Pellici for the ACI device interface specification
* The API part is based on the radiotrack driver by M. Kirkwood
* This driver relies on the aci mixer provided by the snd-miro
* ALSA driver.
* Look there for further info...
- */
-
-/* What ever you think about the ACI, version 0x07 is not very well!
- * I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
- * conditions... Robert
+ *
+ * From the original miro RDS sources:
+ *
+ * (c) 2001 Robert Siemer <Robert.Siemer@gmx.de>
+ *
+ * Many thanks to Fred Seidel <seidel@metabox.de>, the
+ * designer of the RDS decoder hardware. With his help
+ * I was able to code this driver.
+ * Thanks also to Norberto Pellicci, Dominic Mounteney
+ * <DMounteney@pinnaclesys.com> and www.teleauskunft.de
+ * for good hints on finding Fred. It was somewhat hard
+ * to locate him here in Germany... [:
+ *
+ * This code has been reintroduced and converted to use
+ * the new V4L2 RDS API by:
+ *
+ * Hans Verkuil <hans.verkuil@cisco.com>
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/videodev2.h>
+#include <linux/kthread.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
@@ -22,6 +37,22 @@
#include <media/v4l2-event.h>
#include <sound/aci.h>
+#define RDS_DATASHIFT 2 /* Bit 2 */
+#define RDS_DATAMASK (1 << RDS_DATASHIFT)
+#define RDS_BUSYMASK 0x10 /* Bit 4 */
+#define RDS_CLOCKMASK 0x08 /* Bit 3 */
+#define RDS_DATA(x) (((x) >> RDS_DATASHIFT) & 1)
+
+#define RDS_STATUS 0x01
+#define RDS_STATIONNAME 0x02
+#define RDS_TEXT 0x03
+#define RDS_ALTFREQ 0x04
+#define RDS_TIMEDATE 0x05
+#define RDS_PI_CODE 0x06
+#define RDS_PTYTATP 0x07
+#define RDS_RESET 0x08
+#define RDS_RXVALUE 0x09
+
static int radio_nr = -1;
module_param(radio_nr, int, 0);
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
@@ -30,6 +61,14 @@ struct pcm20 {
struct v4l2_device v4l2_dev;
struct video_device vdev;
struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_ctrl *rds_pty;
+ struct v4l2_ctrl *rds_ps_name;
+ struct v4l2_ctrl *rds_radio_test;
+ struct v4l2_ctrl *rds_ta;
+ struct v4l2_ctrl *rds_tp;
+ struct v4l2_ctrl *rds_ms;
+ /* thread for periodic RDS status checking */
+ struct task_struct *kthread;
unsigned long freq;
u32 audmode;
struct snd_miro_aci *aci;
@@ -41,6 +80,103 @@ static struct pcm20 pcm20_card = {
.audmode = V4L2_TUNER_MODE_STEREO,
};
+
+static int rds_waitread(struct snd_miro_aci *aci)
+{
+ u8 byte;
+ int i = 2000;
+
+ do {
+ byte = inb(aci->aci_port + ACI_REG_RDS);
+ i--;
+ } while ((byte & RDS_BUSYMASK) && i);
+
+ /*
+ * It's magic, but without this the data that you read later on
+ * is unreliable and full of bit errors. With this 1 usec delay
+ * everything is fine.
+ */
+ udelay(1);
+ return i ? byte : -1;
+}
+
+static int rds_rawwrite(struct snd_miro_aci *aci, u8 byte)
+{
+ if (rds_waitread(aci) >= 0) {
+ outb(byte, aci->aci_port + ACI_REG_RDS);
+ return 0;
+ }
+ return -1;
+}
+
+static int rds_write(struct snd_miro_aci *aci, u8 byte)
+{
+ u8 sendbuffer[8];
+ int i;
+
+ for (i = 7; i >= 0; i--)
+ sendbuffer[7 - i] = (byte & (1 << i)) ? RDS_DATAMASK : 0;
+ sendbuffer[0] |= RDS_CLOCKMASK;
+
+ for (i = 0; i < 8; i++)
+ rds_rawwrite(aci, sendbuffer[i]);
+ return 0;
+}
+
+static int rds_readcycle_nowait(struct snd_miro_aci *aci)
+{
+ outb(0, aci->aci_port + ACI_REG_RDS);
+ return rds_waitread(aci);
+}
+
+static int rds_readcycle(struct snd_miro_aci *aci)
+{
+ if (rds_rawwrite(aci, 0) < 0)
+ return -1;
+ return rds_waitread(aci);
+}
+
+static int rds_ack(struct snd_miro_aci *aci)
+{
+ int i = rds_readcycle(aci);
+
+ if (i < 0)
+ return -1;
+ if (i & RDS_DATAMASK)
+ return 0; /* ACK */
+ return 1; /* NACK */
+}
+
+static int rds_cmd(struct snd_miro_aci *aci, u8 cmd, u8 databuffer[], u8 datasize)
+{
+ int i, j;
+
+ rds_write(aci, cmd);
+
+ /* RDS_RESET doesn't need further processing */
+ if (cmd == RDS_RESET)
+ return 0;
+ if (rds_ack(aci))
+ return -EIO;
+ if (datasize == 0)
+ return 0;
+
+ /* to be able to use rds_readcycle_nowait()
+ I have to waitread() here */
+ if (rds_waitread(aci) < 0)
+ return -1;
+
+ memset(databuffer, 0, datasize);
+
+ for (i = 0; i < 8 * datasize; i++) {
+ j = rds_readcycle_nowait(aci);
+ if (j < 0)
+ return -EIO;
+ databuffer[i / 8] |= RDS_DATA(j) << (7 - (i % 8));
+ }
+ return 0;
+}
+
static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
{
unsigned char freql;
@@ -54,17 +190,10 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
freql = freq & 0xff;
freqh = freq >> 8;
+ rds_cmd(aci, RDS_RESET, NULL, 0);
return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
}
-static const struct v4l2_file_operations pcm20_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .poll = v4l2_ctrl_poll,
- .release = v4l2_fh_release,
- .unlocked_ioctl = video_ioctl2,
-};
-
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
@@ -73,16 +202,31 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
strlcpy(v->card, "Miro PCM20", sizeof(v->card));
snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", dev->v4l2_dev.name);
- v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
+static bool sanitize(char *p, int size)
+{
+ int i;
+ bool ret = true;
+
+ for (i = 0; i < size; i++) {
+ if (p[i] < 32) {
+ p[i] = ' ';
+ ret = false;
+ }
+ }
+ return ret;
+}
+
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct pcm20 *dev = video_drvdata(file);
int res;
+ u8 buf;
if (v->index)
return -EINVAL;
@@ -97,8 +241,12 @@ static int vidioc_g_tuner(struct file *file, void *priv,
res = snd_aci_cmd(dev->aci, ACI_READ_TUNERSTEREO, -1, -1);
v->rxsubchans = (res & 0x40) ? V4L2_TUNER_SUB_MONO :
V4L2_TUNER_SUB_STEREO;
- v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS;
v->audmode = dev->audmode;
+ res = rds_cmd(dev->aci, RDS_RXVALUE, &buf, 1);
+ if (res >= 0 && buf)
+ v->rxsubchans |= V4L2_TUNER_SUB_RDS;
return 0;
}
@@ -157,6 +305,115 @@ static int pcm20_s_ctrl(struct v4l2_ctrl *ctrl)
return -EINVAL;
}
+static int pcm20_thread(void *data)
+{
+ struct pcm20 *dev = data;
+ const unsigned no_rds_start_counter = 5;
+ const unsigned sleep_msecs = 2000;
+ unsigned no_rds_counter = no_rds_start_counter;
+
+ for (;;) {
+ char text_buffer[66];
+ u8 buf;
+ int res;
+
+ msleep_interruptible(sleep_msecs);
+
+ if (kthread_should_stop())
+ break;
+
+ res = rds_cmd(dev->aci, RDS_RXVALUE, &buf, 1);
+ if (res)
+ continue;
+ if (buf == 0) {
+ if (no_rds_counter == 0)
+ continue;
+ no_rds_counter--;
+ if (no_rds_counter)
+ continue;
+
+ /*
+ * No RDS seen for no_rds_start_counter * sleep_msecs
+ * milliseconds, clear all RDS controls to their
+ * default values.
+ */
+ v4l2_ctrl_s_ctrl_string(dev->rds_ps_name, "");
+ v4l2_ctrl_s_ctrl(dev->rds_ms, 1);
+ v4l2_ctrl_s_ctrl(dev->rds_ta, 0);
+ v4l2_ctrl_s_ctrl(dev->rds_tp, 0);
+ v4l2_ctrl_s_ctrl(dev->rds_pty, 0);
+ v4l2_ctrl_s_ctrl_string(dev->rds_radio_test, "");
+ continue;
+ }
+ no_rds_counter = no_rds_start_counter;
+
+ res = rds_cmd(dev->aci, RDS_STATUS, &buf, 1);
+ if (res)
+ continue;
+ if ((buf >> 3) & 1) {
+ res = rds_cmd(dev->aci, RDS_STATIONNAME, text_buffer, 8);
+ text_buffer[8] = 0;
+ if (!res && sanitize(text_buffer, 8))
+ v4l2_ctrl_s_ctrl_string(dev->rds_ps_name, text_buffer);
+ }
+ if ((buf >> 6) & 1) {
+ u8 pty;
+
+ res = rds_cmd(dev->aci, RDS_PTYTATP, &pty, 1);
+ if (!res) {
+ v4l2_ctrl_s_ctrl(dev->rds_ms, !!(pty & 0x01));
+ v4l2_ctrl_s_ctrl(dev->rds_ta, !!(pty & 0x02));
+ v4l2_ctrl_s_ctrl(dev->rds_tp, !!(pty & 0x80));
+ v4l2_ctrl_s_ctrl(dev->rds_pty, (pty >> 2) & 0x1f);
+ }
+ }
+ if ((buf >> 4) & 1) {
+ res = rds_cmd(dev->aci, RDS_TEXT, text_buffer, 65);
+ text_buffer[65] = 0;
+ if (!res && sanitize(text_buffer + 1, 64))
+ v4l2_ctrl_s_ctrl_string(dev->rds_radio_test, text_buffer + 1);
+ }
+ }
+ return 0;
+}
+
+static int pcm20_open(struct file *file)
+{
+ struct pcm20 *dev = video_drvdata(file);
+ int res = v4l2_fh_open(file);
+
+ if (!res && v4l2_fh_is_singular_file(file) &&
+ IS_ERR_OR_NULL(dev->kthread)) {
+ dev->kthread = kthread_run(pcm20_thread, dev, "%s",
+ dev->v4l2_dev.name);
+ if (IS_ERR(dev->kthread)) {
+ v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
+ v4l2_fh_release(file);
+ return PTR_ERR(dev->kthread);
+ }
+ }
+ return res;
+}
+
+static int pcm20_release(struct file *file)
+{
+ struct pcm20 *dev = video_drvdata(file);
+
+ if (v4l2_fh_is_singular_file(file) && !IS_ERR_OR_NULL(dev->kthread)) {
+ kthread_stop(dev->kthread);
+ dev->kthread = NULL;
+ }
+ return v4l2_fh_release(file);
+}
+
+static const struct v4l2_file_operations pcm20_fops = {
+ .owner = THIS_MODULE,
+ .open = pcm20_open,
+ .poll = v4l2_ctrl_poll,
+ .release = pcm20_release,
+ .unlocked_ioctl = video_ioctl2,
+};
+
static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
@@ -195,9 +452,21 @@ static int __init pcm20_init(void)
}
hdl = &dev->ctrl_handler;
- v4l2_ctrl_handler_init(hdl, 1);
+ v4l2_ctrl_handler_init(hdl, 7);
v4l2_ctrl_new_std(hdl, &pcm20_ctrl_ops,
V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+ dev->rds_pty = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_PTY, 0, 0x1f, 1, 0);
+ dev->rds_ps_name = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
+ dev->rds_radio_test = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
+ dev->rds_ta = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
+ dev->rds_tp = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
+ dev->rds_ms = v4l2_ctrl_new_std(hdl, NULL,
+ V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
v4l2_dev->ctrl_handler = hdl;
if (hdl->error) {
res = hdl->error;
@@ -210,7 +479,6 @@ static int __init pcm20_init(void)
dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
dev->vdev.release = video_device_release_empty;
dev->vdev.lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
video_set_drvdata(&dev->vdev, dev);
snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO,
dev->audmode == V4L2_TUNER_MODE_MONO, -1);
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index a360227ca3ab..c2927fd12615 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -32,7 +32,7 @@
* achievements (specifications given).
* Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
* in 2007. He allowed to use his driver to improve current mr800 radio driver.
- * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
+ * http://www.spinics.net/lists/linux-usb-devel/msg10109.html
*
* Version 0.01: First working version.
* It's required to blacklist AverMedia USB Radio
@@ -558,7 +558,6 @@ static int usb_amradio_probe(struct usb_interface *intf,
radio->vdev.ioctl_ops = &usb_amradio_ioctl_ops;
radio->vdev.release = video_device_release_empty;
radio->vdev.lock = &radio->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
radio->usbdev = interface_to_usbdev(intf);
radio->intf = intf;
diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c
index 7b3bdbb1be73..bfb3a6d051ba 100644
--- a/drivers/media/radio/radio-raremono.c
+++ b/drivers/media/radio/radio-raremono.c
@@ -361,7 +361,6 @@ static int usb_raremono_probe(struct usb_interface *intf,
usb_set_intfdata(intf, &radio->v4l2_dev);
video_set_drvdata(&radio->vdev, radio);
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
raremono_cmd_main(radio, BAND_FM, 95160);
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 6f4318ff0db3..d7ce8fe6b5ae 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -344,7 +344,6 @@ static int __init fmi_init(void)
fmi->vdev.fops = &fmi_fops;
fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
fmi->vdev.release = video_device_release_empty;
- set_bit(V4L2_FL_USE_FH_PRIO, &fmi->vdev.flags);
video_set_drvdata(&fmi->vdev, fmi);
mutex_init(&fmi->lock);
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 2fd9009f8663..633022b45f33 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -1470,7 +1470,6 @@ static int si476x_radio_probe(struct platform_device *pdev)
video_set_drvdata(&radio->videodev, radio);
platform_set_drvdata(pdev, radio);
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->videodev.flags);
radio->v4l2dev.ctrl_handler = &radio->ctrl_handler;
v4l2_ctrl_handler_init(&radio->ctrl_handler,
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 3ed1f5669f79..925049654c5b 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -478,7 +478,6 @@ static int tea5764_i2c_probe(struct i2c_client *client,
video_set_drvdata(&radio->vdev, radio);
radio->vdev.lock = &radio->mutex;
radio->vdev.v4l2_dev = v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
/* initialize and power off the chip */
tea5764_i2c_read(radio);
diff --git a/drivers/media/radio/radio-tea5777.c b/drivers/media/radio/radio-tea5777.c
index e2455970725a..83fe7ab358df 100644
--- a/drivers/media/radio/radio-tea5777.c
+++ b/drivers/media/radio/radio-tea5777.c
@@ -570,7 +570,6 @@ int radio_tea5777_init(struct radio_tea5777 *tea, struct module *owner)
tea->fops = tea575x_fops;
tea->fops.owner = owner;
tea->vd.fops = &tea->fops;
- set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
tea->vd.ctrl_handler = &tea->ctrl_handler;
v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index 0817964d9172..b9285e6584af 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -126,7 +126,6 @@ static int timbradio_probe(struct platform_device *pdev)
tr->video_dev.release = video_device_release_empty;
tr->video_dev.minor = -1;
tr->video_dev.lock = &tr->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &tr->video_dev.flags);
strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
err = v4l2_device_register(NULL, &tr->v4l2_dev);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 07ef40595efd..494fac061306 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -680,7 +680,6 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
radio->videodev.lock = &radio->lock;
radio->videodev.v4l2_dev = &radio->v4l2_dev;
radio->videodev.release = video_device_release_empty;
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->videodev.flags);
video_set_drvdata(&radio->videodev, radio);
/* get device and chip versions */
diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c
index ba4cfc946868..a47502a330f0 100644
--- a/drivers/media/radio/si4713/radio-platform-si4713.c
+++ b/drivers/media/radio/si4713/radio-platform-si4713.c
@@ -196,7 +196,6 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
rsdev->radio_dev = radio_si4713_vdev_template;
rsdev->radio_dev.v4l2_dev = &rsdev->v4l2_dev;
rsdev->radio_dev.ctrl_handler = sd->ctrl_handler;
- set_bit(V4L2_FL_USE_FH_PRIO, &rsdev->radio_dev.flags);
/* Serialize all access to the si4713 */
rsdev->radio_dev.lock = &rsdev->lock;
video_set_drvdata(&rsdev->radio_dev, rsdev);
diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c
index 86502b2786d0..a77319dcba05 100644
--- a/drivers/media/radio/si4713/radio-usb-si4713.c
+++ b/drivers/media/radio/si4713/radio-usb-si4713.c
@@ -492,7 +492,6 @@ static int usb_si4713_probe(struct usb_interface *intf,
radio->vdev.vfl_dir = VFL_DIR_TX;
video_set_drvdata(&radio->vdev, radio);
- set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
if (retval < 0) {
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c
index 07d5153811e8..b5765557ea3d 100644
--- a/drivers/media/radio/si4713/si4713.c
+++ b/drivers/media/radio/si4713/si4713.c
@@ -957,6 +957,41 @@ static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
*bit = 5;
*mask = 0x1F << 5;
break;
+ case V4L2_CID_RDS_TX_DYNAMIC_PTY:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 15;
+ *mask = 1 << 15;
+ break;
+ case V4L2_CID_RDS_TX_COMPRESSED:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 14;
+ *mask = 1 << 14;
+ break;
+ case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 13;
+ *mask = 1 << 13;
+ break;
+ case V4L2_CID_RDS_TX_MONO_STEREO:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 12;
+ *mask = 1 << 12;
+ break;
+ case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 10;
+ *mask = 1 << 10;
+ break;
+ case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 4;
+ *mask = 1 << 4;
+ break;
+ case V4L2_CID_RDS_TX_MUSIC_SPEECH:
+ *property = SI4713_TX_RDS_PS_MISC;
+ *bit = 3;
+ *mask = 1 << 3;
+ break;
case V4L2_CID_AUDIO_LIMITER_ENABLED:
*property = SI4713_TX_ACOMP_ENABLE;
*bit = 1;
@@ -1098,11 +1133,11 @@ static int si4713_s_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_RDS_TX_PS_NAME:
- ret = si4713_set_rds_ps_name(sdev, ctrl->string);
+ ret = si4713_set_rds_ps_name(sdev, ctrl->p_new.p_char);
break;
case V4L2_CID_RDS_TX_RADIO_TEXT:
- ret = si4713_set_rds_radio_text(sdev, ctrl->string);
+ ret = si4713_set_rds_radio_text(sdev, ctrl->p_new.p_char);
break;
case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
@@ -1122,6 +1157,17 @@ static int si4713_s_ctrl(struct v4l2_ctrl *ctrl)
}
break;
+ case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
+ case V4L2_CID_RDS_TX_ALT_FREQS:
+ if (sdev->rds_alt_freqs_enable->val) {
+ val = sdev->rds_alt_freqs->p_new.p_u32[0];
+ val = val / 100 - 876 + 0xe101;
+ } else {
+ val = 0xe0e0;
+ }
+ ret = si4713_write_property(sdev, SI4713_TX_RDS_PS_AF, val);
+ break;
+
default:
ret = si4713_choose_econtrol_action(sdev, ctrl->id, &bit,
&mask, &property, &mul, &table, &size);
@@ -1355,6 +1401,17 @@ static const struct v4l2_subdev_ops si4713_subdev_ops = {
.tuner = &si4713_subdev_tuner_ops,
};
+static const struct v4l2_ctrl_config si4713_alt_freqs_ctrl = {
+ .id = V4L2_CID_RDS_TX_ALT_FREQS,
+ .type = V4L2_CTRL_TYPE_U32,
+ .min = 87600,
+ .max = 107900,
+ .step = 100,
+ .def = 87600,
+ .dims = { 1 },
+ .elem_size = sizeof(u32),
+};
+
/*
* I2C driver interface
*/
@@ -1410,6 +1467,23 @@ static int si4713_probe(struct i2c_client *client,
V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, DEFAULT_RDS_PI);
sdev->rds_pty = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
V4L2_CID_RDS_TX_PTY, 0, 31, 1, DEFAULT_RDS_PTY);
+ sdev->rds_compressed = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
+ sdev->rds_art_head = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
+ sdev->rds_stereo = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
+ sdev->rds_tp = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
+ sdev->rds_ta = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
+ sdev->rds_ms = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
+ sdev->rds_dyn_pty = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
+ sdev->rds_alt_freqs_enable = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
+ V4L2_CID_RDS_TX_ALT_FREQS_ENABLE, 0, 1, 1, 0);
+ sdev->rds_alt_freqs = v4l2_ctrl_new_custom(hdl, &si4713_alt_freqs_ctrl, NULL);
sdev->rds_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
V4L2_CID_RDS_TX_DEVIATION, 0, MAX_RDS_DEVIATION,
10, DEFAULT_RDS_DEVIATION);
@@ -1476,7 +1550,7 @@ static int si4713_probe(struct i2c_client *client,
rval = hdl->error;
goto free_ctrls;
}
- v4l2_ctrl_cluster(20, &sdev->mute);
+ v4l2_ctrl_cluster(29, &sdev->mute);
sdev->sd.ctrl_handler = hdl;
if (client->irq) {
diff --git a/drivers/media/radio/si4713/si4713.h b/drivers/media/radio/si4713/si4713.h
index 4837cf6e0e1b..ed700e387605 100644
--- a/drivers/media/radio/si4713/si4713.h
+++ b/drivers/media/radio/si4713/si4713.h
@@ -211,6 +211,15 @@ struct si4713_device {
struct v4l2_ctrl *rds_pi;
struct v4l2_ctrl *rds_deviation;
struct v4l2_ctrl *rds_pty;
+ struct v4l2_ctrl *rds_compressed;
+ struct v4l2_ctrl *rds_art_head;
+ struct v4l2_ctrl *rds_stereo;
+ struct v4l2_ctrl *rds_ta;
+ struct v4l2_ctrl *rds_tp;
+ struct v4l2_ctrl *rds_ms;
+ struct v4l2_ctrl *rds_dyn_pty;
+ struct v4l2_ctrl *rds_alt_freqs_enable;
+ struct v4l2_ctrl *rds_alt_freqs;
struct v4l2_ctrl *compression_enabled;
struct v4l2_ctrl *compression_threshold;
struct v4l2_ctrl *compression_gain;
diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
index 7c14060a40b8..f1a0867789fe 100644
--- a/drivers/media/radio/tea575x.c
+++ b/drivers/media/radio/tea575x.c
@@ -523,7 +523,6 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
tea->fops = tea575x_fops;
tea->fops.owner = owner;
tea->vd.fops = &tea->fops;
- set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags);
/* disable hw_freq_seek if we can't use it */
if (tea->cannot_read_data)
v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 8fbd377e6311..5e626af8e313 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -84,18 +84,6 @@ config IR_SONY_DECODER
Enable this option if you have an infrared remote control which
uses the Sony protocol, and you need software decoding support.
-config IR_RC5_SZ_DECODER
- tristate "Enable IR raw decoder for the RC-5 (streamzap) protocol"
- depends on RC_CORE
- select BITREVERSE
- default y
-
- ---help---
- Enable this option if you have IR with RC-5 (streamzap) protocol,
- and if the IR is decoded in software. (The Streamzap PC Remote
- uses an IR protocol that is almost standard RC-5, but not quite,
- as it uses an additional bit).
-
config IR_SANYO_DECODER
tristate "Enable IR raw decoder for the Sanyo protocol"
depends on RC_CORE
@@ -125,6 +113,16 @@ config IR_MCE_KBD_DECODER
Enable this option if you have a Microsoft Remote Keyboard for
Windows Media Center Edition, which you would like to use with
a raw IR receiver in your system.
+
+config IR_XMP_DECODER
+ tristate "Enable IR raw decoder for the XMP protocol"
+ depends on RC_CORE
+ select BITREVERSE
+ default y
+
+ ---help---
+ Enable this option if you have IR with XMP protocol, and
+ if the IR is decoded in software
endif #RC_DECODERS
menuconfig RC_DEVICES
@@ -343,4 +341,14 @@ config RC_ST
If you're not sure, select N here.
+config IR_SUNXI
+ tristate "SUNXI IR remote control"
+ depends on RC_CORE
+ depends on ARCH_SUNXI
+ ---help---
+ Say Y if you want to use sunXi internal IR Controller
+
+ To compile this driver as a module, choose M here: the module will
+ be called sunxi-ir.
+
endif #RC_DEVICES
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index f8b54ff46601..9f9843a1af5f 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,4 +1,4 @@
-rc-core-objs := rc-main.o ir-raw.o
+rc-core-objs := rc-main.o rc-ir-raw.o
obj-y += keymaps/
@@ -9,11 +9,11 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
-obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
+obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
# stand-alone IR receivers/transmitters
obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o
@@ -32,4 +32,5 @@ obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o
obj-$(CONFIG_IR_IGUANA) += iguanair.o
obj-$(CONFIG_IR_TTUSBIR) += ttusbir.o
obj-$(CONFIG_RC_ST) += st_rc.o
+obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o
obj-$(CONFIG_IR_IMG) += img-ir/
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 2df7c5516013..a35631891cc0 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -279,46 +279,42 @@ struct ati_remote {
/* "Kinds" of messages sent from the hardware to the driver. */
#define KIND_END 0
-#define KIND_LITERAL 1 /* Simply pass to input system */
+#define KIND_LITERAL 1 /* Simply pass to input system as EV_KEY */
#define KIND_FILTERED 2 /* Add artificial key-up events, drop keyrepeats */
-#define KIND_LU 3 /* Directional keypad diagonals - left up, */
-#define KIND_RU 4 /* right up, */
-#define KIND_LD 5 /* left down, */
-#define KIND_RD 6 /* right down */
-#define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/
+#define KIND_ACCEL 3 /* Translate to EV_REL mouse-move events */
/* Translation table from hardware messages to input events. */
static const struct {
- short kind;
- unsigned char data;
- int type;
- unsigned int code;
- int value;
+ unsigned char kind;
+ unsigned char data; /* Raw key code from remote */
+ unsigned short code; /* Input layer translation */
} ati_remote_tbl[] = {
- /* Directional control pad axes */
- {KIND_ACCEL, 0x70, EV_REL, REL_X, -1}, /* left */
- {KIND_ACCEL, 0x71, EV_REL, REL_X, 1}, /* right */
- {KIND_ACCEL, 0x72, EV_REL, REL_Y, -1}, /* up */
- {KIND_ACCEL, 0x73, EV_REL, REL_Y, 1}, /* down */
- /* Directional control pad diagonals */
- {KIND_LU, 0x74, EV_REL, 0, 0}, /* left up */
- {KIND_RU, 0x75, EV_REL, 0, 0}, /* right up */
- {KIND_LD, 0x77, EV_REL, 0, 0}, /* left down */
- {KIND_RD, 0x76, EV_REL, 0, 0}, /* right down */
+ /* Directional control pad axes. Code is xxyy */
+ {KIND_ACCEL, 0x70, 0xff00}, /* left */
+ {KIND_ACCEL, 0x71, 0x0100}, /* right */
+ {KIND_ACCEL, 0x72, 0x00ff}, /* up */
+ {KIND_ACCEL, 0x73, 0x0001}, /* down */
- /* "Mouse button" buttons */
- {KIND_LITERAL, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */
- {KIND_LITERAL, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */
- {KIND_LITERAL, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
- {KIND_LITERAL, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
+ /* Directional control pad diagonals */
+ {KIND_ACCEL, 0x74, 0xffff}, /* left up */
+ {KIND_ACCEL, 0x75, 0x01ff}, /* right up */
+ {KIND_ACCEL, 0x77, 0xff01}, /* left down */
+ {KIND_ACCEL, 0x76, 0x0101}, /* right down */
+
+ /* "Mouse button" buttons. The code below uses the fact that the
+ * lsbit of the raw code is a down/up indicator. */
+ {KIND_LITERAL, 0x78, BTN_LEFT}, /* left btn down */
+ {KIND_LITERAL, 0x79, BTN_LEFT}, /* left btn up */
+ {KIND_LITERAL, 0x7c, BTN_RIGHT},/* right btn down */
+ {KIND_LITERAL, 0x7d, BTN_RIGHT},/* right btn up */
/* Artificial "doubleclick" events are generated by the hardware.
* They are mapped to the "side" and "extra" mouse buttons here. */
- {KIND_FILTERED, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
- {KIND_FILTERED, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
+ {KIND_FILTERED, 0x7a, BTN_SIDE}, /* left dblclick */
+ {KIND_FILTERED, 0x7e, BTN_EXTRA},/* right dblclick */
/* Non-mouse events are handled by rc-core */
- {KIND_END, 0x00, EV_MAX + 1, 0, 0}
+ {KIND_END, 0x00, 0}
};
/*
@@ -493,7 +489,6 @@ static void ati_remote_input_report(struct urb *urb)
unsigned char *data= ati_remote->inbuf;
struct input_dev *dev = ati_remote->idev;
int index = -1;
- int acc;
int remote_num;
unsigned char scancode;
u32 wheel_keycode = KEY_RESERVED;
@@ -507,8 +502,9 @@ static void ati_remote_input_report(struct urb *urb)
*/
/* Deal with strange looking inputs */
- if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
- ((data[3] & 0x0f) != 0x00) ) {
+ if ( urb->actual_length != 4 || data[0] != 0x14 ||
+ data[1] != (unsigned char)(data[2] + data[3] + 0xD5) ||
+ (data[3] & 0x0f) != 0x00) {
ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
return;
}
@@ -524,9 +520,9 @@ static void ati_remote_input_report(struct urb *urb)
remote_num = (data[3] >> 4) & 0x0f;
if (channel_mask & (1 << (remote_num + 1))) {
dbginfo(&ati_remote->interface->dev,
- "Masked input from channel 0x%02x: data %02x,%02x, "
+ "Masked input from channel 0x%02x: data %02x, "
"mask= 0x%02lx\n",
- remote_num, data[1], data[2], channel_mask);
+ remote_num, data[2], channel_mask);
return;
}
@@ -566,16 +562,16 @@ static void ati_remote_input_report(struct urb *urb)
}
if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value);
- input_sync(dev);
+ /*
+ * The lsbit of the raw key code is a down/up flag.
+ * Invert it to match the input layer's conventions.
+ */
+ input_event(dev, EV_KEY, ati_remote_tbl[index].code,
+ !(data[2] & 1));
ati_remote->old_jiffies = jiffies;
- return;
- }
- if (index < 0 || ati_remote_tbl[index].kind == KIND_FILTERED) {
+ } else if (index < 0 || ati_remote_tbl[index].kind == KIND_FILTERED) {
unsigned long now = jiffies;
/* Filter duplicate events which happen "too close" together. */
@@ -588,12 +584,11 @@ static void ati_remote_input_report(struct urb *urb)
ati_remote->first_jiffies = now;
}
- ati_remote->old_data = data[2];
ati_remote->old_jiffies = now;
- /* Ensure we skip at least the 4 first duplicate events (generated
- * by a single keypress), and continue skipping until repeat_delay
- * msecs have passed
+ /* Ensure we skip at least the 4 first duplicate events
+ * (generated by a single keypress), and continue skipping
+ * until repeat_delay msecs have passed.
*/
if (ati_remote->repeat_count > 0 &&
(ati_remote->repeat_count < 5 ||
@@ -601,7 +596,10 @@ static void ati_remote_input_report(struct urb *urb)
msecs_to_jiffies(repeat_delay))))
return;
- if (index < 0) {
+ if (index >= 0) {
+ input_event(dev, EV_KEY, ati_remote_tbl[index].code, 1);
+ input_event(dev, EV_KEY, ati_remote_tbl[index].code, 0);
+ } else {
/* Not a mouse event, hand it to rc-core. */
int count = 1;
@@ -622,61 +620,37 @@ static void ati_remote_input_report(struct urb *urb)
* it would cause ghost repeats which would be a
* regression for this driver.
*/
- rc_keydown_notimeout(ati_remote->rdev, scancode,
- data[2]);
+ rc_keydown_notimeout(ati_remote->rdev, RC_TYPE_OTHER,
+ scancode, data[2]);
rc_keyup(ati_remote->rdev);
}
- return;
+ goto nosync;
}
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 1);
- input_sync(dev);
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 0);
- input_sync(dev);
-
- } else {
+ } else if (ati_remote_tbl[index].kind == KIND_ACCEL) {
+ signed char dx = ati_remote_tbl[index].code >> 8;
+ signed char dy = ati_remote_tbl[index].code & 255;
/*
* Other event kinds are from the directional control pad, and
* have an acceleration factor applied to them. Without this
* acceleration, the control pad is mostly unusable.
*/
- acc = ati_remote_compute_accel(ati_remote);
-
- switch (ati_remote_tbl[index].kind) {
- case KIND_ACCEL:
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value * acc);
- break;
- case KIND_LU:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_RU:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_LD:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- case KIND_RD:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- default:
- dev_dbg(&ati_remote->interface->dev,
- "ati_remote kind=%d\n",
- ati_remote_tbl[index].kind);
- }
- input_sync(dev);
-
+ int acc = ati_remote_compute_accel(ati_remote);
+ if (dx)
+ input_report_rel(dev, REL_X, dx * acc);
+ if (dy)
+ input_report_rel(dev, REL_Y, dy * acc);
ati_remote->old_jiffies = jiffies;
- ati_remote->old_data = data[2];
+
+ } else {
+ dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
+ ati_remote_tbl[index].kind);
+ return;
}
+ input_sync(dev);
+nosync:
+ ati_remote->old_data = data[2];
}
/*
@@ -763,8 +737,9 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
- if (ati_remote_tbl[i].type == EV_KEY)
- set_bit(ati_remote_tbl[i].code, idev->keybit);
+ if (ati_remote_tbl[i].kind == KIND_LITERAL ||
+ ati_remote_tbl[i].kind == KIND_FILTERED)
+ __set_bit(ati_remote_tbl[i].code, idev->keybit);
input_set_drvdata(idev, ati_remote);
@@ -784,7 +759,7 @@ static void ati_remote_rc_init(struct ati_remote *ati_remote)
rdev->priv = ati_remote;
rdev->driver_type = RC_DRIVER_SCANCODE;
- rc_set_allowed_protocols(rdev, RC_BIT_OTHER);
+ rdev->allowed_protocols = RC_BIT_OTHER;
rdev->driver_name = "ati_remote";
rdev->open = ati_remote_rc_open;
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index fc9d23f2ed3f..d16d9b496b92 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -1059,7 +1059,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
learning_mode_force = false;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->priv = dev;
rdev->open = ene_open;
rdev->close = ene_close;
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 46b66e59438f..f0a1f7d31ee6 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -541,7 +541,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
/* Set up the rc device */
rdev->priv = fintek;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = fintek_open;
rdev->close = fintek_close;
rdev->input_name = FINTEK_DESCRIPTION;
@@ -686,12 +686,12 @@ static struct pnp_driver fintek_driver = {
.shutdown = fintek_shutdown,
};
-static int fintek_init(void)
+static int __init fintek_init(void)
{
return pnp_register_driver(&fintek_driver);
}
-static void fintek_exit(void)
+static void __exit fintek_exit(void)
{
pnp_unregister_driver(&fintek_driver);
}
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 29b5f89813b4..59853085bc88 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -145,9 +145,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
rcdev->dev.parent = &pdev->dev;
rcdev->driver_name = GPIO_IR_DRIVER_NAME;
if (pdata->allowed_protos)
- rc_set_allowed_protocols(rcdev, pdata->allowed_protos);
+ rcdev->allowed_protocols = pdata->allowed_protos;
else
- rc_set_allowed_protocols(rcdev, RC_BIT_ALL);
+ rcdev->allowed_protocols = RC_BIT_ALL;
rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
gpio_dev->rcdev = rcdev;
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 627ddfd61980..ee60e17fba05 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -495,7 +495,7 @@ static int iguanair_probe(struct usb_interface *intf,
usb_to_input_id(ir->udev, &rc->input_id);
rc->dev.parent = &intf->dev;
rc->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rc, RC_BIT_ALL);
+ rc->allowed_protocols = RC_BIT_ALL;
rc->priv = ir;
rc->open = iguanair_open;
rc->close = iguanair_close;
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c
index 6b7834834fb8..a0cac2f09109 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -3,6 +3,11 @@
*
* Copyright 2010-2014 Imagination Technologies Ltd.
*
+ * 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 contains core img-ir code for setting up the driver. The two interfaces
* (raw and hardware decode) are handled separately.
*/
diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c
index 0127dd257a57..bfb282a714e8 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.c
+++ b/drivers/media/rc/img-ir/img-ir-hw.c
@@ -3,6 +3,11 @@
*
* Copyright 2010-2014 Imagination Technologies Ltd.
*
+ * 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 ties into the input subsystem using the RC-core. Protocol support is
* provided in separate modules which provide the parameters and scancode
* translation functions to set up the hardware decoder and interpret the
@@ -507,7 +512,7 @@ unlock:
static int img_ir_set_normal_filter(struct rc_dev *dev,
struct rc_scancode_filter *sc_filter)
{
- return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter);
+ return img_ir_set_filter(dev, RC_FILTER_NORMAL, sc_filter);
}
static int img_ir_set_wakeup_filter(struct rc_dev *dev,
@@ -551,8 +556,8 @@ static void img_ir_set_decoder(struct img_ir_priv *priv,
hw->mode = IMG_IR_M_NORMAL;
/* clear the wakeup scancode filter */
- rdev->scancode_filters[RC_FILTER_WAKEUP].data = 0;
- rdev->scancode_filters[RC_FILTER_WAKEUP].mask = 0;
+ rdev->scancode_wakeup_filter.data = 0;
+ rdev->scancode_wakeup_filter.mask = 0;
/* clear raw filters */
_img_ir_set_filter(priv, NULL);
@@ -656,8 +661,8 @@ success:
wakeup_protocols = *ir_type;
if (!hw->decoder || !hw->decoder->filter)
wakeup_protocols = 0;
- rc_set_allowed_wakeup_protocols(rdev, wakeup_protocols);
- rc_set_enabled_wakeup_protocols(rdev, wakeup_protocols);
+ rdev->allowed_wakeup_protocols = wakeup_protocols;
+ rdev->enabled_wakeup_protocols = wakeup_protocols;
return 0;
}
@@ -671,9 +676,9 @@ static void img_ir_set_protocol(struct img_ir_priv *priv, u64 proto)
spin_unlock_irq(&rdev->rc_map.lock);
mutex_lock(&rdev->lock);
- rc_set_enabled_protocols(rdev, proto);
- rc_set_allowed_wakeup_protocols(rdev, proto);
- rc_set_enabled_wakeup_protocols(rdev, proto);
+ rdev->enabled_protocols = proto;
+ rdev->allowed_wakeup_protocols = proto;
+ rdev->enabled_wakeup_protocols = proto;
mutex_unlock(&rdev->lock);
}
@@ -790,9 +795,11 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
struct img_ir_priv_hw *hw = &priv->hw;
const struct img_ir_decoder *dec = hw->decoder;
int ret = IMG_IR_SCANCODE;
- int scancode;
+ u32 scancode;
+ enum rc_type protocol = RC_TYPE_UNKNOWN;
+
if (dec->scancode)
- ret = dec->scancode(len, raw, &scancode, hw->enabled_protocols);
+ ret = dec->scancode(len, raw, &protocol, &scancode, hw->enabled_protocols);
else if (len >= 32)
scancode = (u32)raw;
else if (len < 32)
@@ -801,7 +808,7 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw)
len, (unsigned long long)raw);
if (ret == IMG_IR_SCANCODE) {
dev_dbg(priv->dev, "decoded scan code %#x\n", scancode);
- rc_keydown(hw->rdev, scancode, 0);
+ rc_keydown(hw->rdev, protocol, scancode, 0);
img_ir_end_repeat(priv);
} else if (ret == IMG_IR_REPEATCODE) {
if (hw->mode == IMG_IR_M_REPEATING) {
@@ -996,7 +1003,7 @@ int img_ir_probe_hw(struct img_ir_priv *priv)
}
rdev->priv = priv;
rdev->map_name = RC_MAP_EMPTY;
- rc_set_allowed_protocols(rdev, img_ir_allowed_protos(priv));
+ rdev->allowed_protocols = img_ir_allowed_protos(priv);
rdev->input_name = "IMG Infrared Decoder";
rdev->s_filter = img_ir_set_normal_filter;
rdev->s_wakeup_filter = img_ir_set_wakeup_filter;
diff --git a/drivers/media/rc/img-ir/img-ir-hw.h b/drivers/media/rc/img-ir/img-ir-hw.h
index 6c9a94a81190..3e40ce87b898 100644
--- a/drivers/media/rc/img-ir/img-ir-hw.h
+++ b/drivers/media/rc/img-ir/img-ir-hw.h
@@ -2,6 +2,11 @@
* ImgTec IR Hardware Decoder found in PowerDown Controller.
*
* Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * 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.
*/
#ifndef _IMG_IR_HW_H_
@@ -157,7 +162,8 @@ struct img_ir_decoder {
struct img_ir_control control;
/* scancode logic */
- int (*scancode)(int len, u64 raw, int *scancode, u64 protocols);
+ int (*scancode)(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols);
int (*filter)(const struct rc_scancode_filter *in,
struct img_ir_filter *out, u64 protocols);
};
diff --git a/drivers/media/rc/img-ir/img-ir-jvc.c b/drivers/media/rc/img-ir/img-ir-jvc.c
index 10209d200efb..a60dda8bf706 100644
--- a/drivers/media/rc/img-ir/img-ir-jvc.c
+++ b/drivers/media/rc/img-ir/img-ir-jvc.c
@@ -2,12 +2,18 @@
* ImgTec IR Decoder setup for JVC protocol.
*
* Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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 "img-ir-hw.h"
/* Convert JVC data to a scancode */
-static int img_ir_jvc_scancode(int len, u64 raw, int *scancode, u64 protocols)
+static int img_ir_jvc_scancode(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols)
{
unsigned int cust, data;
@@ -17,6 +23,7 @@ static int img_ir_jvc_scancode(int len, u64 raw, int *scancode, u64 protocols)
cust = (raw >> 0) & 0xff;
data = (raw >> 8) & 0xff;
+ *protocol = RC_TYPE_JVC;
*scancode = cust << 8 | data;
return IMG_IR_SCANCODE;
}
diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c
index 751d9d945269..739897549b5b 100644
--- a/drivers/media/rc/img-ir/img-ir-nec.c
+++ b/drivers/media/rc/img-ir/img-ir-nec.c
@@ -2,13 +2,19 @@
* ImgTec IR Decoder setup for NEC protocol.
*
* Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * 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 "img-ir-hw.h"
#include <linux/bitrev.h>
/* Convert NEC data to a scancode */
-static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols)
+static int img_ir_nec_scancode(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols)
{
unsigned int addr, addr_inv, data, data_inv;
/* a repeat code has no data */
@@ -40,6 +46,7 @@ static int img_ir_nec_scancode(int len, u64 raw, int *scancode, u64 protocols)
*scancode = addr << 8 |
data;
}
+ *protocol = RC_TYPE_NEC;
return IMG_IR_SCANCODE;
}
diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c
index cfb01d9e571a..33f37ed87ad2 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.c
+++ b/drivers/media/rc/img-ir/img-ir-raw.c
@@ -3,6 +3,11 @@
*
* Copyright 2010-2014 Imagination Technologies Ltd.
*
+ * 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 ties into the input subsystem using the RC-core in raw mode. Raw IR
* signal edges are reported and decoded by generic software decoders.
*/
diff --git a/drivers/media/rc/img-ir/img-ir-raw.h b/drivers/media/rc/img-ir/img-ir-raw.h
index 9802ffd51b9a..4c9b7676e6fc 100644
--- a/drivers/media/rc/img-ir/img-ir-raw.h
+++ b/drivers/media/rc/img-ir/img-ir-raw.h
@@ -2,6 +2,11 @@
* ImgTec IR Raw Decoder found in PowerDown Controller.
*
* Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * 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.
*/
#ifndef _IMG_IR_RAW_H_
diff --git a/drivers/media/rc/img-ir/img-ir-sanyo.c b/drivers/media/rc/img-ir/img-ir-sanyo.c
index c2c763e08a41..6b0653ecdf5a 100644
--- a/drivers/media/rc/img-ir/img-ir-sanyo.c
+++ b/drivers/media/rc/img-ir/img-ir-sanyo.c
@@ -3,6 +3,11 @@
*
* Copyright 2012-2014 Imagination Technologies Ltd.
*
+ * 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.
+ *
* From ir-sanyo-decoder.c:
*
* This protocol uses the NEC protocol timings. However, data is formatted as:
@@ -18,7 +23,8 @@
#include "img-ir-hw.h"
/* Convert Sanyo data to a scancode */
-static int img_ir_sanyo_scancode(int len, u64 raw, int *scancode, u64 protocols)
+static int img_ir_sanyo_scancode(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols)
{
unsigned int addr, addr_inv, data, data_inv;
/* a repeat code has no data */
@@ -38,6 +44,7 @@ static int img_ir_sanyo_scancode(int len, u64 raw, int *scancode, u64 protocols)
return -EINVAL;
/* Normal Sanyo */
+ *protocol = RC_TYPE_SANYO;
*scancode = addr << 8 | data;
return IMG_IR_SCANCODE;
}
diff --git a/drivers/media/rc/img-ir/img-ir-sharp.c b/drivers/media/rc/img-ir/img-ir-sharp.c
index 3397cc5a6794..3300a38802ac 100644
--- a/drivers/media/rc/img-ir/img-ir-sharp.c
+++ b/drivers/media/rc/img-ir/img-ir-sharp.c
@@ -2,12 +2,18 @@
* ImgTec IR Decoder setup for Sharp protocol.
*
* Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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 "img-ir-hw.h"
/* Convert Sharp data to a scancode */
-static int img_ir_sharp_scancode(int len, u64 raw, int *scancode, u64 protocols)
+static int img_ir_sharp_scancode(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols)
{
unsigned int addr, cmd, exp, chk;
@@ -26,6 +32,7 @@ static int img_ir_sharp_scancode(int len, u64 raw, int *scancode, u64 protocols)
/* probably the second half of the message */
return -EINVAL;
+ *protocol = RC_TYPE_SHARP;
*scancode = addr << 8 | cmd;
return IMG_IR_SCANCODE;
}
diff --git a/drivers/media/rc/img-ir/img-ir-sony.c b/drivers/media/rc/img-ir/img-ir-sony.c
index 993409a51a71..3a0f17b0752c 100644
--- a/drivers/media/rc/img-ir/img-ir-sony.c
+++ b/drivers/media/rc/img-ir/img-ir-sony.c
@@ -2,40 +2,49 @@
* ImgTec IR Decoder setup for Sony (SIRC) protocol.
*
* Copyright 2012-2014 Imagination Technologies Ltd.
+ *
+ * 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 "img-ir-hw.h"
/* Convert Sony data to a scancode */
-static int img_ir_sony_scancode(int len, u64 raw, int *scancode, u64 protocols)
+static int img_ir_sony_scancode(int len, u64 raw, enum rc_type *protocol,
+ u32 *scancode, u64 enabled_protocols)
{
unsigned int dev, subdev, func;
switch (len) {
case 12:
- if (!(protocols & RC_BIT_SONY12))
+ if (!(enabled_protocols & RC_BIT_SONY12))
return -EINVAL;
func = raw & 0x7f; /* first 7 bits */
raw >>= 7;
dev = raw & 0x1f; /* next 5 bits */
subdev = 0;
+ *protocol = RC_TYPE_SONY12;
break;
case 15:
- if (!(protocols & RC_BIT_SONY15))
+ if (!(enabled_protocols & RC_BIT_SONY15))
return -EINVAL;
func = raw & 0x7f; /* first 7 bits */
raw >>= 7;
dev = raw & 0xff; /* next 8 bits */
subdev = 0;
+ *protocol = RC_TYPE_SONY15;
break;
case 20:
- if (!(protocols & RC_BIT_SONY20))
+ if (!(enabled_protocols & RC_BIT_SONY20))
return -EINVAL;
func = raw & 0x7f; /* first 7 bits */
raw >>= 7;
dev = raw & 0x1f; /* next 5 bits */
raw >>= 5;
subdev = raw & 0xff; /* next 8 bits */
+ *protocol = RC_TYPE_SONY20;
break;
default:
return -EINVAL;
diff --git a/drivers/media/rc/img-ir/img-ir.h b/drivers/media/rc/img-ir/img-ir.h
index afb189394af9..2ddf56083182 100644
--- a/drivers/media/rc/img-ir/img-ir.h
+++ b/drivers/media/rc/img-ir/img-ir.h
@@ -2,6 +2,11 @@
* ImgTec IR Decoder found in PowerDown Controller.
*
* Copyright 2010-2014 Imagination Technologies Ltd.
+ *
+ * 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.
*/
#ifndef _IMG_IR_H_
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 6f24e77b1488..7115e68ba697 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -78,11 +78,11 @@ static int display_open(struct inode *inode, struct file *file);
static int display_close(struct inode *inode, struct file *file);
/* VFD write operation */
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
size_t n_bytes, loff_t *pos);
/* LCD file_operations override function prototypes */
-static ssize_t lcd_write(struct file *file, const char *buf,
+static ssize_t lcd_write(struct file *file, const char __user *buf,
size_t n_bytes, loff_t *pos);
/*** G L O B A L S ***/
@@ -825,7 +825,7 @@ static struct attribute_group imon_rf_attr_group = {
* than 32 bytes are provided spaces will be appended to
* generate a full screen.
*/
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
size_t n_bytes, loff_t *pos)
{
int i;
@@ -912,7 +912,7 @@ exit:
* display whatever diacritics you need, and so on), but it's also
* a lot more complicated than most LCDs...
*/
-static ssize_t lcd_write(struct file *file, const char *buf,
+static ssize_t lcd_write(struct file *file, const char __user *buf,
size_t n_bytes, loff_t *pos)
{
int retval = 0;
@@ -1017,7 +1017,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
unsigned char ir_proto_packet[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
- if (*rc_type && !rc_protocols_allowed(rc, *rc_type))
+ if (*rc_type && !(*rc_type & rc->allowed_protocols))
dev_warn(dev, "Looks like you're trying to use an IR protocol "
"this device does not support\n");
@@ -1579,7 +1579,10 @@ static void imon_incoming_packet(struct imon_context *ictx,
if (press_type == 0)
rc_keyup(ictx->rdev);
else {
- rc_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle);
+ if (ictx->rc_type == RC_BIT_RC6_MCE)
+ rc_keydown(ictx->rdev,
+ ictx->rc_type == RC_BIT_RC6_MCE ? RC_TYPE_RC6_MCE : RC_TYPE_OTHER,
+ ictx->rc_scancode, ictx->rc_toggle);
spin_lock_irqsave(&ictx->kc_lock, flags);
ictx->last_keycode = ictx->kc;
spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1867,8 +1870,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
rdev->priv = ictx;
rdev->driver_type = RC_DRIVER_SCANCODE;
- /* iMON PAD or MCE */
- rc_set_allowed_protocols(rdev, RC_BIT_OTHER | RC_BIT_RC6_MCE);
+ rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE; /* iMON PAD or MCE */
rdev->change_protocol = imon_ir_change_protocol;
rdev->driver_name = MOD_NAME;
@@ -1881,7 +1883,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
if (ictx->product == 0xffdc) {
imon_get_ffdc_type(ictx);
- rc_set_allowed_protocols(rdev, ictx->rc_type);
+ rdev->allowed_protocols = ictx->rc_type;
}
imon_set_display_type(ictx);
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 4ea62a1dcfda..30bcf188d377 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -47,7 +47,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
struct jvc_dec *data = &dev->raw->jvc;
- if (!rc_protocols_enabled(dev, RC_BIT_JVC))
+ if (!(dev->enabled_protocols & RC_BIT_JVC))
return 0;
if (!is_timing_event(ev)) {
@@ -140,7 +140,7 @@ again:
scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
(bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
- rc_keydown(dev, scancode, data->toggle);
+ rc_keydown(dev, RC_TYPE_JVC, scancode, data->toggle);
data->first = false;
data->old_bits = data->bits;
} else if (data->bits == data->old_bits) {
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index d731da6c414d..ed2c8a1ed8ca 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct lirc_codec *lirc = &dev->raw->lirc;
int sample;
- if (!rc_protocols_enabled(dev, RC_BIT_LIRC))
+ if (!(dev->enabled_protocols & RC_BIT_LIRC))
return 0;
if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf)
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 0c55f794c8cf..9f3c9b59f30c 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -216,7 +216,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
u32 scancode;
unsigned long delay;
- if (!rc_protocols_enabled(dev, RC_BIT_MCE_KBD))
+ if (!(dev->enabled_protocols & RC_BIT_MCE_KBD))
return 0;
if (!is_timing_event(ev)) {
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 35c42e5e270b..7b81fec0820f 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -52,7 +52,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
u8 address, not_address, command, not_command;
bool send_32bits = false;
- if (!rc_protocols_enabled(dev, RC_BIT_NEC))
+ if (!(dev->enabled_protocols & RC_BIT_NEC))
return 0;
if (!is_timing_event(ev)) {
@@ -189,7 +189,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
if (data->is_nec_x)
data->necx_repeat = true;
- rc_keydown(dev, scancode, 0);
+ rc_keydown(dev, RC_TYPE_NEC, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 4295d9b250c8..2ef763928ca4 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -1,6 +1,7 @@
-/* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol
+/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
*
* Copyright (C) 2010 by Mauro Carvalho Chehab
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.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
@@ -13,23 +14,22 @@
*/
/*
- * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols.
- * There are other variants that use a different number of bits.
- * This is currently unsupported.
- * It considers a carrier of 36 kHz, with a total of 14/20 bits, where
- * the first two bits are start bits, and a third one is a filing bit
+ * This decoder handles the 14 bit RC5 protocol, 15 bit "StreamZap" protocol
+ * and 20 bit RC5x protocol.
*/
#include "rc-core-priv.h"
#include <linux/module.h>
#define RC5_NBITS 14
+#define RC5_SZ_NBITS 15
#define RC5X_NBITS 20
#define CHECK_RC5X_NBITS 8
#define RC5_UNIT 888888 /* ns */
#define RC5_BIT_START (1 * RC5_UNIT)
#define RC5_BIT_END (1 * RC5_UNIT)
#define RC5X_SPACE (4 * RC5_UNIT)
+#define RC5_TRAILER (10 * RC5_UNIT) /* In reality, approx 100 */
enum rc5_state {
STATE_INACTIVE,
@@ -51,8 +51,9 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct rc5_dec *data = &dev->raw->rc5;
u8 toggle;
u32 scancode;
+ enum rc_type protocol;
- if (!rc_protocols_enabled(dev, RC_BIT_RC5 | RC_BIT_RC5X))
+ if (!(dev->enabled_protocols & (RC_BIT_RC5 | RC_BIT_RC5X)))
return 0;
if (!is_timing_event(ev)) {
@@ -65,7 +66,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
goto out;
again:
- IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
+ IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n",
data->state, TO_US(ev.duration), TO_STR(ev.pulse));
if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
@@ -79,12 +80,15 @@ again:
data->state = STATE_BIT_START;
data->count = 1;
- /* We just need enough bits to get to STATE_CHECK_RC5X */
- data->wanted_bits = RC5X_NBITS;
decrease_duration(&ev, RC5_BIT_START);
goto again;
case STATE_BIT_START:
+ if (!ev.pulse && geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT / 2)) {
+ data->state = STATE_FINISHED;
+ goto again;
+ }
+
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
break;
@@ -99,9 +103,7 @@ again:
if (!is_transition(&ev, &dev->raw->prev_ev))
break;
- if (data->count == data->wanted_bits)
- data->state = STATE_FINISHED;
- else if (data->count == CHECK_RC5X_NBITS)
+ if (data->count == CHECK_RC5X_NBITS)
data->state = STATE_CHECK_RC5X;
else
data->state = STATE_BIT_START;
@@ -111,13 +113,10 @@ again:
case STATE_CHECK_RC5X:
if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT / 2)) {
- /* RC5X */
- data->wanted_bits = RC5X_NBITS;
+ data->is_rc5x = true;
decrease_duration(&ev, RC5X_SPACE);
- } else {
- /* RC5 */
- data->wanted_bits = RC5_NBITS;
- }
+ } else
+ data->is_rc5x = false;
data->state = STATE_BIT_START;
goto again;
@@ -125,10 +124,10 @@ again:
if (ev.pulse)
break;
- if (data->wanted_bits == RC5X_NBITS) {
+ if (data->is_rc5x && data->count == RC5X_NBITS) {
/* RC5X */
u8 xdata, command, system;
- if (!rc_protocols_enabled(dev, RC_BIT_RC5X)) {
+ if (!(dev->enabled_protocols & RC_BIT_RC5X)) {
data->state = STATE_INACTIVE;
return 0;
}
@@ -138,14 +137,12 @@ again:
toggle = (data->bits & 0x20000) ? 1 : 0;
command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 16 | command << 8 | xdata;
+ protocol = RC_TYPE_RC5X;
- IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
- scancode, toggle);
-
- } else {
+ } else if (!data->is_rc5x && data->count == RC5_NBITS) {
/* RC5 */
u8 command, system;
- if (!rc_protocols_enabled(dev, RC_BIT_RC5)) {
+ if (!(dev->enabled_protocols & RC_BIT_RC5)) {
data->state = STATE_INACTIVE;
return 0;
}
@@ -154,25 +151,41 @@ again:
toggle = (data->bits & 0x00800) ? 1 : 0;
command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 8 | command;
+ protocol = RC_TYPE_RC5;
- IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
- scancode, toggle);
- }
+ } else if (!data->is_rc5x && data->count == RC5_SZ_NBITS) {
+ /* RC5 StreamZap */
+ u8 command, system;
+ if (!(dev->enabled_protocols & RC_BIT_RC5_SZ)) {
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+ command = (data->bits & 0x0003F) >> 0;
+ system = (data->bits & 0x02FC0) >> 6;
+ toggle = (data->bits & 0x01000) ? 1 : 0;
+ scancode = system << 6 | command;
+ protocol = RC_TYPE_RC5_SZ;
- rc_keydown(dev, scancode, toggle);
+ } else
+ break;
+
+ IR_dprintk(1, "RC5(x/sz) scancode 0x%06x (p: %u, t: %u)\n",
+ scancode, protocol, toggle);
+
+ rc_keydown(dev, protocol, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
out:
- IR_dprintk(1, "RC5(x) decode failed at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ IR_dprintk(1, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n",
+ data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
data->state = STATE_INACTIVE;
return -EINVAL;
}
static struct ir_raw_handler rc5_handler = {
- .protocols = RC_BIT_RC5 | RC_BIT_RC5X,
+ .protocols = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ,
.decode = ir_rc5_decode,
};
@@ -180,7 +193,7 @@ static int __init ir_rc5_decode_init(void)
{
ir_raw_handler_register(&rc5_handler);
- printk(KERN_INFO "IR RC5(x) protocol handler initialized\n");
+ printk(KERN_INFO "IR RC5(x/sz) protocol handler initialized\n");
return 0;
}
@@ -193,6 +206,6 @@ module_init(ir_rc5_decode_init);
module_exit(ir_rc5_decode_exit);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mauro Carvalho Chehab");
+MODULE_AUTHOR("Mauro Carvalho Chehab and Jarod Wilson");
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("RC5(x) IR protocol decoder");
+MODULE_DESCRIPTION("RC5(x/sz) IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc5-sz-decoder.c b/drivers/media/rc/ir-rc5-sz-decoder.c
deleted file mode 100644
index dc18b7434db8..000000000000
--- a/drivers/media/rc/ir-rc5-sz-decoder.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ir-rc5-sz-decoder.c - handle RC5 Streamzap IR Pulse/Space protocol
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.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 version 2 of the License.
- *
- * 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.
- */
-
-/*
- * This code handles the 15 bit RC5-ish protocol used by the Streamzap
- * PC Remote.
- * It considers a carrier of 36 kHz, with a total of 15 bits, where
- * the first two bits are start bits, and a third one is a filing bit
- */
-
-#include "rc-core-priv.h"
-#include <linux/module.h>
-
-#define RC5_SZ_NBITS 15
-#define RC5_UNIT 888888 /* ns */
-#define RC5_BIT_START (1 * RC5_UNIT)
-#define RC5_BIT_END (1 * RC5_UNIT)
-
-enum rc5_sz_state {
- STATE_INACTIVE,
- STATE_BIT_START,
- STATE_BIT_END,
- STATE_FINISHED,
-};
-
-/**
- * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
- * @dev: the struct rc_dev descriptor of the device
- * @ev: the struct ir_raw_event descriptor of the pulse/space
- *
- * This function returns -EINVAL if the pulse violates the state machine
- */
-static int ir_rc5_sz_decode(struct rc_dev *dev, struct ir_raw_event ev)
-{
- struct rc5_sz_dec *data = &dev->raw->rc5_sz;
- u8 toggle, command, system;
- u32 scancode;
-
- if (!rc_protocols_enabled(dev, RC_BIT_RC5_SZ))
- return 0;
-
- if (!is_timing_event(ev)) {
- if (ev.reset)
- data->state = STATE_INACTIVE;
- return 0;
- }
-
- if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
- goto out;
-
-again:
- IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
-
- if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
- return 0;
-
- switch (data->state) {
-
- case STATE_INACTIVE:
- if (!ev.pulse)
- break;
-
- data->state = STATE_BIT_START;
- data->count = 1;
- data->wanted_bits = RC5_SZ_NBITS;
- decrease_duration(&ev, RC5_BIT_START);
- goto again;
-
- case STATE_BIT_START:
- if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
- break;
-
- data->bits <<= 1;
- if (!ev.pulse)
- data->bits |= 1;
- data->count++;
- data->state = STATE_BIT_END;
- return 0;
-
- case STATE_BIT_END:
- if (!is_transition(&ev, &dev->raw->prev_ev))
- break;
-
- if (data->count == data->wanted_bits)
- data->state = STATE_FINISHED;
- else
- data->state = STATE_BIT_START;
-
- decrease_duration(&ev, RC5_BIT_END);
- goto again;
-
- case STATE_FINISHED:
- if (ev.pulse)
- break;
-
- /* RC5-sz */
- command = (data->bits & 0x0003F) >> 0;
- system = (data->bits & 0x02FC0) >> 6;
- toggle = (data->bits & 0x01000) ? 1 : 0;
- scancode = system << 6 | command;
-
- IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
- scancode, toggle);
-
- rc_keydown(dev, scancode, toggle);
- data->state = STATE_INACTIVE;
- return 0;
- }
-
-out:
- IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
- data->state, TO_US(ev.duration), TO_STR(ev.pulse));
- data->state = STATE_INACTIVE;
- return -EINVAL;
-}
-
-static struct ir_raw_handler rc5_sz_handler = {
- .protocols = RC_BIT_RC5_SZ,
- .decode = ir_rc5_sz_decode,
-};
-
-static int __init ir_rc5_sz_decode_init(void)
-{
- ir_raw_handler_register(&rc5_sz_handler);
-
- printk(KERN_INFO "IR RC5 (streamzap) protocol handler initialized\n");
- return 0;
-}
-
-static void __exit ir_rc5_sz_decode_exit(void)
-{
- ir_raw_handler_unregister(&rc5_sz_handler);
-}
-
-module_init(ir_rc5_sz_decode_init);
-module_exit(ir_rc5_sz_decode_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("RC5 (streamzap) IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index cfbd64e3999c..f1f098e22f7e 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -88,10 +88,11 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct rc6_dec *data = &dev->raw->rc6;
u32 scancode;
u8 toggle;
+ enum rc_type protocol;
- if (!rc_protocols_enabled(dev, RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 |
- RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 |
- RC_BIT_RC6_MCE))
+ if (!(dev->enabled_protocols &
+ (RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 |
+ RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE)))
return 0;
if (!is_timing_event(ev)) {
@@ -233,9 +234,11 @@ again:
case RC6_MODE_0:
scancode = data->body;
toggle = data->toggle;
+ protocol = RC_TYPE_RC6_0;
IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
scancode, toggle);
break;
+
case RC6_MODE_6A:
if (data->count > CHAR_BIT * sizeof data->body) {
IR_dprintk(1, "RC6 too many (%u) data bits\n",
@@ -244,23 +247,39 @@ again:
}
scancode = data->body;
- if (data->count == RC6_6A_32_NBITS &&
- (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
- /* MCE RC */
- toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0;
- scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
- } else {
+ switch (data->count) {
+ case 20:
+ protocol = RC_TYPE_RC6_6A_20;
+ toggle = 0;
+ break;
+ case 24:
+ protocol = RC_BIT_RC6_6A_24;
toggle = 0;
+ break;
+ case 32:
+ if ((scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
+ protocol = RC_TYPE_RC6_MCE;
+ scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
+ toggle = !!(scancode & RC6_6A_MCE_TOGGLE_MASK);
+ } else {
+ protocol = RC_BIT_RC6_6A_32;
+ toggle = 0;
+ }
+ break;
+ default:
+ IR_dprintk(1, "RC6(6A) unsupported length\n");
+ goto out;
}
- IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
- scancode, toggle);
+
+ IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n",
+ protocol, scancode, toggle);
break;
default:
IR_dprintk(1, "RC6 unknown mode\n");
goto out;
}
- rc_keydown(dev, scancode, toggle);
+ rc_keydown(dev, protocol, scancode, toggle);
data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index eb715f04dc27..ad1dc6ae21fc 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -58,7 +58,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
u32 scancode;
u8 address, command, not_command;
- if (!rc_protocols_enabled(dev, RC_BIT_SANYO))
+ if (!(dev->enabled_protocols & RC_BIT_SANYO))
return 0;
if (!is_timing_event(ev)) {
@@ -167,7 +167,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
scancode = address << 8 | command;
IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode);
- rc_keydown(dev, scancode, 0);
+ rc_keydown(dev, RC_TYPE_SANYO, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
index 66d20394ceaa..b7acdbae8159 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -48,7 +48,7 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct sharp_dec *data = &dev->raw->sharp;
u32 msg, echo, address, command, scancode;
- if (!rc_protocols_enabled(dev, RC_BIT_SHARP))
+ if (!(dev->enabled_protocols & RC_BIT_SHARP))
return 0;
if (!is_timing_event(ev)) {
@@ -162,7 +162,7 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev)
scancode = address << 8 | command;
IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode);
- rc_keydown(dev, scancode, 0);
+ rc_keydown(dev, RC_TYPE_SHARP, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index 599c19a73360..d12dc3da5931 100644
--- a/drivers/media/rc/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -42,11 +42,12 @@ enum sony_state {
static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
{
struct sony_dec *data = &dev->raw->sony;
+ enum rc_type protocol;
u32 scancode;
u8 device, subdevice, function;
- if (!rc_protocols_enabled(dev, RC_BIT_SONY12 | RC_BIT_SONY15 |
- RC_BIT_SONY20))
+ if (!(dev->enabled_protocols &
+ (RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20)))
return 0;
if (!is_timing_event(ev)) {
@@ -124,31 +125,34 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
switch (data->count) {
case 12:
- if (!rc_protocols_enabled(dev, RC_BIT_SONY12)) {
+ if (!(dev->enabled_protocols & RC_BIT_SONY12)) {
data->state = STATE_INACTIVE;
return 0;
}
device = bitrev8((data->bits << 3) & 0xF8);
subdevice = 0;
function = bitrev8((data->bits >> 4) & 0xFE);
+ protocol = RC_TYPE_SONY12;
break;
case 15:
- if (!rc_protocols_enabled(dev, RC_BIT_SONY15)) {
+ if (!(dev->enabled_protocols & RC_BIT_SONY15)) {
data->state = STATE_INACTIVE;
return 0;
}
device = bitrev8((data->bits >> 0) & 0xFF);
subdevice = 0;
function = bitrev8((data->bits >> 7) & 0xFE);
+ protocol = RC_TYPE_SONY15;
break;
case 20:
- if (!rc_protocols_enabled(dev, RC_BIT_SONY20)) {
+ if (!(dev->enabled_protocols & RC_BIT_SONY20)) {
data->state = STATE_INACTIVE;
return 0;
}
device = bitrev8((data->bits >> 5) & 0xF8);
subdevice = bitrev8((data->bits >> 0) & 0xFF);
function = bitrev8((data->bits >> 12) & 0xFE);
+ protocol = RC_TYPE_SONY20;
break;
default:
IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
@@ -157,7 +161,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev)
scancode = device << 16 | subdevice << 8 | function;
IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode);
- rc_keydown(dev, scancode, 0);
+ rc_keydown(dev, protocol, scancode, 0);
data->state = STATE_INACTIVE;
return 0;
}
diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c
new file mode 100644
index 000000000000..1017d4816e8d
--- /dev/null
+++ b/drivers/media/rc/ir-xmp-decoder.c
@@ -0,0 +1,225 @@
+/* ir-xmp-decoder.c - handle XMP IR Pulse/Space protocol
+ *
+ * Copyright (C) 2014 by Marcel Mol
+ *
+ * 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 of the License.
+ *
+ * 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.
+ *
+ * - Based on info from http://www.hifi-remote.com
+ * - Ignore Toggle=9 frames
+ * - Ignore XMP-1 XMP-2 difference, always store 16 bit OBC
+ */
+
+#include <linux/bitrev.h>
+#include <linux/module.h>
+#include "rc-core-priv.h"
+
+#define XMP_UNIT 136000 /* ns */
+#define XMP_LEADER 210000 /* ns */
+#define XMP_NIBBLE_PREFIX 760000 /* ns */
+#define XMP_HALFFRAME_SPACE 13800000 /* ns */
+#define XMP_TRAILER_SPACE 20000000 /* should be 80ms but not all dureation supliers can go that high */
+
+enum xmp_state {
+ STATE_INACTIVE,
+ STATE_LEADER_PULSE,
+ STATE_NIBBLE_SPACE,
+};
+
+/**
+ * ir_xmp_decode() - Decode one XMP pulse or space
+ * @dev: the struct rc_dev descriptor of the device
+ * @duration: the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev)
+{
+ struct xmp_dec *data = &dev->raw->xmp;
+
+ if (!(dev->enabled_protocols & RC_BIT_XMP))
+ return 0;
+
+ if (!is_timing_event(ev)) {
+ if (ev.reset)
+ data->state = STATE_INACTIVE;
+ return 0;
+ }
+
+ IR_dprintk(2, "XMP decode started at state %d %d (%uus %s)\n",
+ data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse));
+
+ switch (data->state) {
+
+ case STATE_INACTIVE:
+ if (!ev.pulse)
+ break;
+
+ if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2)) {
+ data->count = 0;
+ data->state = STATE_NIBBLE_SPACE;
+ }
+
+ return 0;
+
+ case STATE_LEADER_PULSE:
+ if (!ev.pulse)
+ break;
+
+ if (eq_margin(ev.duration, XMP_LEADER, XMP_UNIT / 2))
+ data->state = STATE_NIBBLE_SPACE;
+
+ return 0;
+
+ case STATE_NIBBLE_SPACE:
+ if (ev.pulse)
+ break;
+
+ if (geq_margin(ev.duration, XMP_TRAILER_SPACE, XMP_NIBBLE_PREFIX)) {
+ int divider, i;
+ u8 addr, subaddr, subaddr2, toggle, oem, obc1, obc2, sum1, sum2;
+ u32 *n;
+ u32 scancode;
+
+ if (data->count != 16) {
+ IR_dprintk(2, "received TRAILER period at index %d: %u\n",
+ data->count, ev.duration);
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+ }
+
+ n = data->durations;
+ /*
+ * the 4th nibble should be 15 so base the divider on this
+ * to transform durations into nibbles. Substract 2000 from
+ * the divider to compensate for fluctuations in the signal
+ */
+ divider = (n[3] - XMP_NIBBLE_PREFIX) / 15 - 2000;
+ if (divider < 50) {
+ IR_dprintk(2, "divider to small %d.\n", divider);
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+ }
+
+ /* convert to nibbles and do some sanity checks */
+ for (i = 0; i < 16; i++)
+ n[i] = (n[i] - XMP_NIBBLE_PREFIX) / divider;
+ sum1 = (15 + n[0] + n[1] + n[2] + n[3] +
+ n[4] + n[5] + n[6] + n[7]) % 16;
+ sum2 = (15 + n[8] + n[9] + n[10] + n[11] +
+ n[12] + n[13] + n[14] + n[15]) % 16;
+
+ if (sum1 != 15 || sum2 != 15) {
+ IR_dprintk(2, "checksum errors sum1=0x%X sum2=0x%X\n",
+ sum1, sum2);
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+ }
+
+ subaddr = n[0] << 4 | n[2];
+ subaddr2 = n[8] << 4 | n[11];
+ oem = n[4] << 4 | n[5];
+ addr = n[6] << 4 | n[7];
+ toggle = n[10];
+ obc1 = n[12] << 4 | n[13];
+ obc2 = n[14] << 4 | n[15];
+ if (subaddr != subaddr2) {
+ IR_dprintk(2, "subaddress nibbles mismatch 0x%02X != 0x%02X\n",
+ subaddr, subaddr2);
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+ }
+ if (oem != 0x44)
+ IR_dprintk(1, "Warning: OEM nibbles 0x%02X. Expected 0x44\n",
+ oem);
+
+ scancode = addr << 24 | subaddr << 16 |
+ obc1 << 8 | obc2;
+ IR_dprintk(1, "XMP scancode 0x%06x\n", scancode);
+
+ if (toggle == 0) {
+ rc_keydown(dev, RC_TYPE_XMP, scancode, 0);
+ } else {
+ rc_repeat(dev);
+ IR_dprintk(1, "Repeat last key\n");
+ }
+ data->state = STATE_INACTIVE;
+
+ return 0;
+
+ } else if (geq_margin(ev.duration, XMP_HALFFRAME_SPACE, XMP_NIBBLE_PREFIX)) {
+ /* Expect 8 or 16 nibble pulses. 16 in case of 'final' frame */
+ if (data->count == 16) {
+ IR_dprintk(2, "received half frame pulse at index %d. Probably a final frame key-up event: %u\n",
+ data->count, ev.duration);
+ /*
+ * TODO: for now go back to half frame position
+ * so trailer can be found and key press
+ * can be handled.
+ */
+ data->count = 8;
+ }
+
+ else if (data->count != 8)
+ IR_dprintk(2, "received half frame pulse at index %d: %u\n",
+ data->count, ev.duration);
+ data->state = STATE_LEADER_PULSE;
+
+ return 0;
+
+ } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) {
+ /* store nibble raw data, decode after trailer */
+ if (data->count == 16) {
+ IR_dprintk(2, "to many pulses (%d) ignoring: %u\n",
+ data->count, ev.duration);
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+ }
+ data->durations[data->count] = ev.duration;
+ data->count++;
+ data->state = STATE_LEADER_PULSE;
+
+ return 0;
+
+ }
+
+ break;
+ }
+
+ IR_dprintk(1, "XMP decode failed at count %d state %d (%uus %s)\n",
+ data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+ data->state = STATE_INACTIVE;
+ return -EINVAL;
+}
+
+static struct ir_raw_handler xmp_handler = {
+ .protocols = RC_BIT_XMP,
+ .decode = ir_xmp_decode,
+};
+
+static int __init ir_xmp_decode_init(void)
+{
+ ir_raw_handler_register(&xmp_handler);
+
+ printk(KERN_INFO "IR XMP protocol handler initialized\n");
+ return 0;
+}
+
+static void __exit ir_xmp_decode_exit(void)
+{
+ ir_raw_handler_unregister(&xmp_handler);
+}
+
+module_init(ir_xmp_decode_init);
+module_exit(ir_xmp_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marcel Mol <marcel@mesa.nl>");
+MODULE_AUTHOR("MESA Consulting (http://www.mesa.nl)");
+MODULE_DESCRIPTION("XMP IR protocol decoder");
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index ab24cc6d3655..447fe35862dc 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1563,7 +1563,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
/* set up ir-core props */
rdev->priv = itdev;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = ite_open;
rdev->close = ite_close;
rdev->s_idle = ite_s_idle;
@@ -1709,12 +1709,12 @@ static struct pnp_driver ite_driver = {
.shutdown = ite_shutdown,
};
-static int ite_init(void)
+static int __init ite_init(void)
{
return pnp_register_driver(&ite_driver);
}
-static void ite_exit(void)
+static void __exit ite_exit(void)
{
pnp_unregister_driver(&ite_driver);
}
diff --git a/drivers/media/rc/keymaps/rc-ati-x10.c b/drivers/media/rc/keymaps/rc-ati-x10.c
index 81506440eded..4bdc709ec54d 100644
--- a/drivers/media/rc/keymaps/rc-ati-x10.c
+++ b/drivers/media/rc/keymaps/rc-ati-x10.c
@@ -26,7 +26,42 @@
#include <linux/module.h>
#include <media/rc-map.h>
+/*
+ * Intended usage comments below are from vendor-supplied
+ * Source: ATI REMOTE WONDERâ„¢ Installation Guide
+ * http://www2.ati.com/manuals/remctrl.pdf
+ *
+ * Scancodes were in strict left-right, top-bottom order on the
+ * original ATI Remote Wonder, but were moved on later models.
+ *
+ * Keys A-F are intended to be user-programmable.
+ */
+
static struct rc_map_table ati_x10[] = {
+ /* keyboard - Above the cursor pad */
+ { 0x00, KEY_A },
+ { 0x01, KEY_B },
+ { 0x02, KEY_POWER }, /* Power */
+
+ { 0x03, KEY_TV }, /* TV */
+ { 0x04, KEY_DVD }, /* DVD */
+ { 0x05, KEY_WWW }, /* WEB */
+ { 0x06, KEY_BOOKMARKS }, /* "book": Open Media Library */
+ { 0x07, KEY_EDIT }, /* "hand": Toggle left mouse button (grab) */
+
+ /* Mouse emulation pad goes here, handled by driver separately */
+
+ { 0x09, KEY_VOLUMEDOWN }, /* VOL + */
+ { 0x08, KEY_VOLUMEUP }, /* VOL - */
+ { 0x0a, KEY_MUTE }, /* MUTE */
+ { 0x0b, KEY_CHANNELUP }, /* CH + */
+ { 0x0c, KEY_CHANNELDOWN },/* CH - */
+
+ /*
+ * We could use KEY_NUMERIC_x for these, but the X11 protocol
+ * has problems with keycodes greater than 255, so avoid those high
+ * keycodes in default maps.
+ */
{ 0x0d, KEY_1 },
{ 0x0e, KEY_2 },
{ 0x0f, KEY_3 },
@@ -36,46 +71,45 @@ static struct rc_map_table ati_x10[] = {
{ 0x13, KEY_7 },
{ 0x14, KEY_8 },
{ 0x15, KEY_9 },
+ { 0x16, KEY_MENU }, /* "menu": DVD root menu */
+ /* KEY_NUMERIC_STAR? */
{ 0x17, KEY_0 },
- { 0x00, KEY_A },
- { 0x01, KEY_B },
+ { 0x18, KEY_SETUP }, /* "check": DVD setup menu */
+ /* KEY_NUMERIC_POUND? */
+
+ /* DVD navigation buttons */
{ 0x19, KEY_C },
+ { 0x1a, KEY_UP }, /* up */
{ 0x1b, KEY_D },
- { 0x21, KEY_E },
- { 0x23, KEY_F },
- { 0x18, KEY_KPENTER }, /* "check" */
- { 0x16, KEY_MENU }, /* "menu" */
- { 0x02, KEY_POWER }, /* Power */
- { 0x03, KEY_TV }, /* TV */
- { 0x04, KEY_DVD }, /* DVD */
- { 0x05, KEY_WWW }, /* WEB */
- { 0x06, KEY_BOOKMARKS }, /* "book" */
- { 0x07, KEY_EDIT }, /* "hand" */
- { 0x1c, KEY_COFFEE }, /* "timer" */
- { 0x20, KEY_FRONT }, /* "max" */
+ { 0x1c, KEY_PROPS }, /* "timer" Should be Data On Screen */
+ /* Symbol is "circle nailed to box" */
{ 0x1d, KEY_LEFT }, /* left */
+ { 0x1e, KEY_OK }, /* "OK" */
{ 0x1f, KEY_RIGHT }, /* right */
+ { 0x20, KEY_SCREEN }, /* "max" (X11 warning: 0x177) */
+ /* Should be AC View Toggle, but
+ that's not in <input/input.h>.
+ KEY_ZOOM (0x174)? */
+ { 0x21, KEY_E },
{ 0x22, KEY_DOWN }, /* down */
- { 0x1a, KEY_UP }, /* up */
- { 0x1e, KEY_OK }, /* "OK" */
- { 0x09, KEY_VOLUMEDOWN }, /* VOL + */
- { 0x08, KEY_VOLUMEUP }, /* VOL - */
- { 0x0a, KEY_MUTE }, /* MUTE */
- { 0x0b, KEY_CHANNELUP }, /* CH + */
- { 0x0c, KEY_CHANNELDOWN },/* CH - */
+ { 0x23, KEY_F },
+ /* Play/stop/pause buttons */
+ { 0x24, KEY_REWIND }, /* (<<) Rewind */
+ { 0x25, KEY_PLAY }, /* ( >) Play (KEY_PLAYCD?) */
+ { 0x26, KEY_FASTFORWARD }, /* (>>) Fast forward */
+
{ 0x27, KEY_RECORD }, /* ( o) red */
- { 0x25, KEY_PLAY }, /* ( >) */
- { 0x24, KEY_REWIND }, /* (<<) */
- { 0x26, KEY_FORWARD }, /* (>>) */
- { 0x28, KEY_STOP }, /* ([]) */
- { 0x29, KEY_PAUSE }, /* ('') */
- { 0x2b, KEY_PREVIOUS }, /* (<-) */
+ { 0x28, KEY_STOPCD }, /* ([]) Stop (KEY_STOP is something else!) */
+ { 0x29, KEY_PAUSE }, /* ('') Pause (KEY_PAUSECD?) */
+
+ /* Extra keys, not on the original ATI remote */
{ 0x2a, KEY_NEXT }, /* (>+) */
- { 0x2d, KEY_INFO }, /* PLAYING */
+ { 0x2b, KEY_PREVIOUS }, /* (<-) */
+ { 0x2d, KEY_INFO }, /* PLAYING (X11 warning: 0x166) */
{ 0x2e, KEY_HOME }, /* TOP */
{ 0x2f, KEY_END }, /* END */
- { 0x30, KEY_SELECT }, /* SELECT */
+ { 0x30, KEY_SELECT }, /* SELECT (X11 warning: 0x161) */
};
static struct rc_map_list ati_x10_map = {
diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index d6519f8ac95a..520a96f2ff86 100644
--- a/drivers/media/rc/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -30,8 +30,8 @@ static struct rc_map_table behold[] = {
/* 0x1c 0x12 *
* TV/FM POWER *
* */
- { 0x6b861c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
- { 0x6b8612, KEY_POWER },
+ { 0x866b1c, KEY_TUNER }, /* XXX KEY_TV / KEY_RADIO */
+ { 0x866b12, KEY_POWER },
/* 0x01 0x02 0x03 *
* 1 2 3 *
@@ -42,28 +42,28 @@ static struct rc_map_table behold[] = {
* 0x07 0x08 0x09 *
* 7 8 9 *
* */
- { 0x6b8601, KEY_1 },
- { 0x6b8602, KEY_2 },
- { 0x6b8603, KEY_3 },
- { 0x6b8604, KEY_4 },
- { 0x6b8605, KEY_5 },
- { 0x6b8606, KEY_6 },
- { 0x6b8607, KEY_7 },
- { 0x6b8608, KEY_8 },
- { 0x6b8609, KEY_9 },
+ { 0x866b01, KEY_1 },
+ { 0x866b02, KEY_2 },
+ { 0x866b03, KEY_3 },
+ { 0x866b04, KEY_4 },
+ { 0x866b05, KEY_5 },
+ { 0x866b06, KEY_6 },
+ { 0x866b07, KEY_7 },
+ { 0x866b08, KEY_8 },
+ { 0x866b09, KEY_9 },
/* 0x0a 0x00 0x17 *
* RECALL 0 MODE *
* */
- { 0x6b860a, KEY_AGAIN },
- { 0x6b8600, KEY_0 },
- { 0x6b8617, KEY_MODE },
+ { 0x866b0a, KEY_AGAIN },
+ { 0x866b00, KEY_0 },
+ { 0x866b17, KEY_MODE },
/* 0x14 0x10 *
* ASPECT FULLSCREEN *
* */
- { 0x6b8614, KEY_SCREEN },
- { 0x6b8610, KEY_ZOOM },
+ { 0x866b14, KEY_SCREEN },
+ { 0x866b10, KEY_ZOOM },
/* 0x0b *
* Up *
@@ -74,17 +74,17 @@ static struct rc_map_table behold[] = {
* 0x015 *
* Down *
* */
- { 0x6b860b, KEY_CHANNELUP },
- { 0x6b8618, KEY_VOLUMEDOWN },
- { 0x6b8616, KEY_OK }, /* XXX KEY_ENTER */
- { 0x6b860c, KEY_VOLUMEUP },
- { 0x6b8615, KEY_CHANNELDOWN },
+ { 0x866b0b, KEY_CHANNELUP },
+ { 0x866b18, KEY_VOLUMEDOWN },
+ { 0x866b16, KEY_OK }, /* XXX KEY_ENTER */
+ { 0x866b0c, KEY_VOLUMEUP },
+ { 0x866b15, KEY_CHANNELDOWN },
/* 0x11 0x0d *
* MUTE INFO *
* */
- { 0x6b8611, KEY_MUTE },
- { 0x6b860d, KEY_INFO },
+ { 0x866b11, KEY_MUTE },
+ { 0x866b0d, KEY_INFO },
/* 0x0f 0x1b 0x1a *
* RECORD PLAY/PAUSE STOP *
@@ -93,26 +93,26 @@ static struct rc_map_table behold[] = {
*TELETEXT AUDIO SOURCE *
* RED YELLOW *
* */
- { 0x6b860f, KEY_RECORD },
- { 0x6b861b, KEY_PLAYPAUSE },
- { 0x6b861a, KEY_STOP },
- { 0x6b860e, KEY_TEXT },
- { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
- { 0x6b861e, KEY_VIDEO },
+ { 0x866b0f, KEY_RECORD },
+ { 0x866b1b, KEY_PLAYPAUSE },
+ { 0x866b1a, KEY_STOP },
+ { 0x866b0e, KEY_TEXT },
+ { 0x866b1f, KEY_RED }, /*XXX KEY_AUDIO */
+ { 0x866b1e, KEY_VIDEO },
/* 0x1d 0x13 0x19 *
* SLEEP PREVIEW DVB *
* GREEN BLUE *
* */
- { 0x6b861d, KEY_SLEEP },
- { 0x6b8613, KEY_GREEN },
- { 0x6b8619, KEY_BLUE }, /* XXX KEY_SAT */
+ { 0x866b1d, KEY_SLEEP },
+ { 0x866b13, KEY_GREEN },
+ { 0x866b19, KEY_BLUE }, /* XXX KEY_SAT */
/* 0x58 0x5c *
* FREEZE SNAPSHOT *
* */
- { 0x6b8658, KEY_SLOW },
- { 0x6b865c, KEY_CAMERA },
+ { 0x866b58, KEY_SLOW },
+ { 0x866b5c, KEY_CAMERA },
};
diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index 8ec881adb7cf..4c50f33c7c41 100644
--- a/drivers/media/rc/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -14,68 +14,68 @@
#include <linux/module.h>
static struct rc_map_table nebula[] = {
- { 0x00, KEY_0 },
- { 0x01, KEY_1 },
- { 0x02, KEY_2 },
- { 0x03, KEY_3 },
- { 0x04, KEY_4 },
- { 0x05, KEY_5 },
- { 0x06, KEY_6 },
- { 0x07, KEY_7 },
- { 0x08, KEY_8 },
- { 0x09, KEY_9 },
- { 0x0a, KEY_TV },
- { 0x0b, KEY_AUX },
- { 0x0c, KEY_DVD },
- { 0x0d, KEY_POWER },
- { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */
- { 0x0f, KEY_AUDIO },
- { 0x10, KEY_INFO },
- { 0x11, KEY_F13 }, /* 16:9 */
- { 0x12, KEY_F14 }, /* 14:9 */
- { 0x13, KEY_EPG },
- { 0x14, KEY_EXIT },
- { 0x15, KEY_MENU },
- { 0x16, KEY_UP },
- { 0x17, KEY_DOWN },
- { 0x18, KEY_LEFT },
- { 0x19, KEY_RIGHT },
- { 0x1a, KEY_ENTER },
- { 0x1b, KEY_CHANNELUP },
- { 0x1c, KEY_CHANNELDOWN },
- { 0x1d, KEY_VOLUMEUP },
- { 0x1e, KEY_VOLUMEDOWN },
- { 0x1f, KEY_RED },
- { 0x20, KEY_GREEN },
- { 0x21, KEY_YELLOW },
- { 0x22, KEY_BLUE },
- { 0x23, KEY_SUBTITLE },
- { 0x24, KEY_F15 }, /* AD */
- { 0x25, KEY_TEXT },
- { 0x26, KEY_MUTE },
- { 0x27, KEY_REWIND },
- { 0x28, KEY_STOP },
- { 0x29, KEY_PLAY },
- { 0x2a, KEY_FASTFORWARD },
- { 0x2b, KEY_F16 }, /* chapter */
- { 0x2c, KEY_PAUSE },
- { 0x2d, KEY_PLAY },
- { 0x2e, KEY_RECORD },
- { 0x2f, KEY_F17 }, /* picture in picture */
- { 0x30, KEY_KPPLUS }, /* zoom in */
- { 0x31, KEY_KPMINUS }, /* zoom out */
- { 0x32, KEY_F18 }, /* capture */
- { 0x33, KEY_F19 }, /* web */
- { 0x34, KEY_EMAIL },
- { 0x35, KEY_PHONE },
- { 0x36, KEY_PC },
+ { 0x0000, KEY_0 },
+ { 0x0001, KEY_1 },
+ { 0x0002, KEY_2 },
+ { 0x0003, KEY_3 },
+ { 0x0004, KEY_4 },
+ { 0x0005, KEY_5 },
+ { 0x0006, KEY_6 },
+ { 0x0007, KEY_7 },
+ { 0x0008, KEY_8 },
+ { 0x0009, KEY_9 },
+ { 0x000a, KEY_TV },
+ { 0x000b, KEY_AUX },
+ { 0x000c, KEY_DVD },
+ { 0x000d, KEY_POWER },
+ { 0x000e, KEY_CAMERA }, /* labelled 'Picture' */
+ { 0x000f, KEY_AUDIO },
+ { 0x0010, KEY_INFO },
+ { 0x0011, KEY_F13 }, /* 16:9 */
+ { 0x0012, KEY_F14 }, /* 14:9 */
+ { 0x0013, KEY_EPG },
+ { 0x0014, KEY_EXIT },
+ { 0x0015, KEY_MENU },
+ { 0x0016, KEY_UP },
+ { 0x0017, KEY_DOWN },
+ { 0x0018, KEY_LEFT },
+ { 0x0019, KEY_RIGHT },
+ { 0x001a, KEY_ENTER },
+ { 0x001b, KEY_CHANNELUP },
+ { 0x001c, KEY_CHANNELDOWN },
+ { 0x001d, KEY_VOLUMEUP },
+ { 0x001e, KEY_VOLUMEDOWN },
+ { 0x001f, KEY_RED },
+ { 0x0020, KEY_GREEN },
+ { 0x0021, KEY_YELLOW },
+ { 0x0022, KEY_BLUE },
+ { 0x0023, KEY_SUBTITLE },
+ { 0x0024, KEY_F15 }, /* AD */
+ { 0x0025, KEY_TEXT },
+ { 0x0026, KEY_MUTE },
+ { 0x0027, KEY_REWIND },
+ { 0x0028, KEY_STOP },
+ { 0x0029, KEY_PLAY },
+ { 0x002a, KEY_FASTFORWARD },
+ { 0x002b, KEY_F16 }, /* chapter */
+ { 0x002c, KEY_PAUSE },
+ { 0x002d, KEY_PLAY },
+ { 0x002e, KEY_RECORD },
+ { 0x002f, KEY_F17 }, /* picture in picture */
+ { 0x0030, KEY_KPPLUS }, /* zoom in */
+ { 0x0031, KEY_KPMINUS }, /* zoom out */
+ { 0x0032, KEY_F18 }, /* capture */
+ { 0x0033, KEY_F19 }, /* web */
+ { 0x0034, KEY_EMAIL },
+ { 0x0035, KEY_PHONE },
+ { 0x0036, KEY_PC },
};
static struct rc_map_list nebula_map = {
.map = {
.scan = nebula,
.size = ARRAY_SIZE(nebula),
- .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
+ .rc_type = RC_TYPE_RC5,
.name = RC_MAP_NEBULA,
}
};
diff --git a/drivers/media/rc/keymaps/rc-streamzap.c b/drivers/media/rc/keymaps/rc-streamzap.c
index f9a07578d985..23c061174ed7 100644
--- a/drivers/media/rc/keymaps/rc-streamzap.c
+++ b/drivers/media/rc/keymaps/rc-streamzap.c
@@ -15,9 +15,7 @@
static struct rc_map_table streamzap[] = {
/*
* The Streamzap remote is almost, but not quite, RC-5, as it has an extra
- * bit in it, which throws the in-kernel RC-5 decoder for a loop. Currently,
- * an additional RC-5-sz decoder is being deployed to support it, but it
- * may be possible to merge it back with the standard RC-5 decoder.
+ * bit in it.
*/
{ 0x28c0, KEY_NUMERIC_0 },
{ 0x28c1, KEY_NUMERIC_1 },
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index d5c1df3c9db1..45b0894288e5 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -187,6 +187,7 @@
#define VENDOR_CONEXANT 0x0572
#define VENDOR_TWISTEDMELON 0x2596
#define VENDOR_HAUPPAUGE 0x2040
+#define VENDOR_PCTV 0x2013
enum mceusb_model_type {
MCE_GEN2 = 0, /* Most boards */
@@ -240,7 +241,6 @@ static const struct mceusb_model mceusb_model[] = {
* remotes, but we should have something handy,
* to allow testing it
*/
- .rc_map = RC_MAP_HAUPPAUGE,
.name = "Conexant Hybrid TV (cx231xx) MCE IR",
},
[CX_HYBRID_TV] = {
@@ -248,7 +248,6 @@ static const struct mceusb_model mceusb_model[] = {
.name = "Conexant Hybrid TV (cx231xx) MCE IR",
},
[HAUPPAUGE_CX_HYBRID_TV] = {
- .rc_map = RC_MAP_HAUPPAUGE,
.no_tx = 1, /* eeprom says it has no tx */
.name = "Conexant Hybrid TV (cx231xx) MCE IR no TX",
},
@@ -396,6 +395,13 @@ static struct usb_device_id mceusb_dev_table[] = {
/* Hauppauge WINTV-HVR-HVR 930C-HD - based on cx231xx */
{ USB_DEVICE(VENDOR_HAUPPAUGE, 0xb130),
.driver_info = HAUPPAUGE_CX_HYBRID_TV },
+ { USB_DEVICE(VENDOR_HAUPPAUGE, 0xb131),
+ .driver_info = HAUPPAUGE_CX_HYBRID_TV },
+ { USB_DEVICE(VENDOR_PCTV, 0x0259),
+ .driver_info = HAUPPAUGE_CX_HYBRID_TV },
+ { USB_DEVICE(VENDOR_PCTV, 0x025e),
+ .driver_info = HAUPPAUGE_CX_HYBRID_TV },
+
/* Terminating entry */
{ }
};
@@ -1192,8 +1198,10 @@ static void mceusb_flash_led(struct mceusb_dev *ir)
mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED));
}
-static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
+static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir,
+ struct usb_interface *intf)
{
+ struct usb_device *udev = usb_get_dev(interface_to_usbdev(intf));
struct device *dev = ir->dev;
struct rc_dev *rc;
int ret;
@@ -1219,7 +1227,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->dev.parent = dev;
rc->priv = ir;
rc->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rc, RC_BIT_ALL);
+ rc->allowed_protocols = RC_BIT_ALL;
rc->timeout = MS_TO_NS(100);
if (!ir->flags.no_tx) {
rc->s_tx_mask = mceusb_set_tx_mask;
@@ -1227,8 +1235,19 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->tx_ir = mceusb_tx_ir;
}
rc->driver_name = DRIVER_NAME;
- rc->map_name = mceusb_model[ir->model].rc_map ?
- mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
+
+ switch (le16_to_cpu(udev->descriptor.idVendor)) {
+ case VENDOR_HAUPPAUGE:
+ rc->map_name = RC_MAP_HAUPPAUGE;
+ break;
+ case VENDOR_PCTV:
+ rc->map_name = RC_MAP_PINNACLE_PCTV_HD;
+ break;
+ default:
+ rc->map_name = RC_MAP_RC6_MCE;
+ }
+ if (mceusb_model[ir->model].rc_map)
+ rc->map_name = mceusb_model[ir->model].rc_map;
ret = rc_register_device(rc);
if (ret < 0) {
@@ -1343,7 +1362,7 @@ static int mceusb_dev_probe(struct usb_interface *intf,
snprintf(name + strlen(name), sizeof(name) - strlen(name),
" %s", buf);
- ir->rc = mceusb_init_rc_dev(ir);
+ ir->rc = mceusb_init_rc_dev(ir, intf);
if (!ir->rc)
goto rc_dev_fail;
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index d244e1a83f43..7f4fd859bba5 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1044,7 +1044,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
/* Set up the rc device */
rdev->priv = nvt;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->open = nvt_open;
rdev->close = nvt_close;
rdev->tx_ir = nvt_tx_ir;
@@ -1221,12 +1221,12 @@ static struct pnp_driver nvt_driver = {
.shutdown = nvt_shutdown,
};
-static int nvt_init(void)
+static int __init nvt_init(void)
{
return pnp_register_driver(&nvt_driver);
}
-static void nvt_exit(void)
+static void __exit nvt_exit(void)
{
pnp_unregister_driver(&nvt_driver);
}
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index da536c93c978..b68d4f762734 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -54,7 +54,7 @@ struct ir_raw_event_ctrl {
int state;
u32 bits;
unsigned count;
- unsigned wanted_bits;
+ bool is_rc5x;
} rc5;
struct rc6_dec {
int state;
@@ -77,12 +77,6 @@ struct ir_raw_event_ctrl {
bool first;
bool toggle;
} jvc;
- struct rc5_sz_dec {
- int state;
- u32 bits;
- unsigned count;
- unsigned wanted_bits;
- } rc5_sz;
struct sanyo_dec {
int state;
unsigned count;
@@ -116,6 +110,11 @@ struct ir_raw_event_ctrl {
bool send_timeout_reports;
} lirc;
+ struct xmp_dec {
+ int state;
+ unsigned count;
+ u32 durations[16];
+ } xmp;
};
/* macros for IR decoders */
@@ -231,5 +230,12 @@ static inline void load_mce_kbd_decode(void) { }
static inline void load_lirc_codec(void) { }
#endif
+/* from ir-xmp-decoder.c */
+#ifdef CONFIG_IR_XMP_DECODER_MODULE
+#define load_xmp_decode() request_module_nowait("ir-xmp-decoder")
+#else
+static inline void load_xmp_decode(void) { }
+#endif
+
#endif /* _RC_CORE_PRIV */
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 763c9d131d0f..e8fff2add265 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -1,4 +1,4 @@
-/* ir-raw.c - handle IR pulse/space events
+/* rc-ir-raw.c - handle IR pulse/space events
*
* Copyright (C) 2010 by Mauro Carvalho Chehab
*
@@ -240,6 +240,12 @@ ir_raw_get_allowed_protocols(void)
return protocols;
}
+static int change_protocol(struct rc_dev *dev, u64 *rc_type)
+{
+ /* the caller will update dev->enabled_protocols */
+ return 0;
+}
+
/*
* Used to (un)register raw event clients
*/
@@ -256,7 +262,8 @@ int ir_raw_event_register(struct rc_dev *dev)
return -ENOMEM;
dev->raw->dev = dev;
- rc_set_enabled_protocols(dev, ~0);
+ dev->enabled_protocols = ~0;
+ dev->change_protocol = change_protocol;
rc = kfifo_alloc(&dev->raw->kfifo,
sizeof(struct ir_raw_event) * MAX_IR_EVENT_SIZE,
GFP_KERNEL);
@@ -355,6 +362,7 @@ void ir_raw_init(void)
load_sharp_decode();
load_mce_kbd_decode();
load_lirc_codec();
+ load_xmp_decode();
/* If needed, we may later add some init code. In this case,
it is needed to change the CONFIG_MODULE test at rc-core.h
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 0a88e0cf964f..63dace8198b0 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -195,7 +195,7 @@ static int __init loop_init(void)
rc->map_name = RC_MAP_EMPTY;
rc->priv = &loopdev;
rc->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rc, RC_BIT_ALL);
+ rc->allowed_protocols = RC_BIT_ALL;
rc->timeout = 100 * 1000 * 1000; /* 100 ms */
rc->min_timeout = 1;
rc->max_timeout = UINT_MAX;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 970b93d6f399..a7991c7d010a 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -285,8 +285,8 @@ static unsigned int ir_establish_scancode(struct rc_dev *dev,
* IR tables from other remotes. So, we support specifying a mask to
* indicate the valid bits of the scancodes.
*/
- if (dev->scanmask)
- scancode &= dev->scanmask;
+ if (dev->scancode_mask)
+ scancode &= dev->scancode_mask;
/* First check if we already have a mapping for this ir command */
for (i = 0; i < rc_map->len; i++) {
@@ -623,6 +623,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);
/**
* ir_do_keydown() - internal function to process a keypress
* @dev: the struct rc_dev descriptor of the device
+ * @protocol: the protocol of the keypress
* @scancode: the scancode of the keypress
* @keycode: the keycode of the keypress
* @toggle: the toggle value of the keypress
@@ -630,12 +631,13 @@ EXPORT_SYMBOL_GPL(rc_repeat);
* This function is used internally to register a keypress, it must be
* called with keylock held.
*/
-static void ir_do_keydown(struct rc_dev *dev, int scancode,
- u32 keycode, u8 toggle)
+static void ir_do_keydown(struct rc_dev *dev, enum rc_type protocol,
+ u32 scancode, u32 keycode, u8 toggle)
{
bool new_event = (!dev->keypressed ||
+ dev->last_protocol != protocol ||
dev->last_scancode != scancode ||
- dev->last_toggle != toggle);
+ dev->last_toggle != toggle);
if (new_event && dev->keypressed)
ir_do_keyup(dev, false);
@@ -645,13 +647,14 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
if (new_event && keycode != KEY_RESERVED) {
/* Register a keypress */
dev->keypressed = true;
+ dev->last_protocol = protocol;
dev->last_scancode = scancode;
dev->last_toggle = toggle;
dev->last_keycode = keycode;
IR_dprintk(1, "%s: key down event, "
- "key 0x%04x, scancode 0x%04x\n",
- dev->input_name, keycode, scancode);
+ "key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
+ dev->input_name, keycode, protocol, scancode);
input_report_key(dev->input_dev, keycode, 1);
led_trigger_event(led_feedback, LED_FULL);
@@ -663,20 +666,21 @@ static void ir_do_keydown(struct rc_dev *dev, int scancode,
/**
* rc_keydown() - generates input event for a key press
* @dev: the struct rc_dev descriptor of the device
- * @scancode: the scancode that we're seeking
+ * @protocol: the protocol for the keypress
+ * @scancode: the scancode for the keypress
* @toggle: the toggle value (protocol dependent, if the protocol doesn't
* support toggle values, this should be set to zero)
*
* This routine is used to signal that a key has been pressed on the
* remote control.
*/
-void rc_keydown(struct rc_dev *dev, int scancode, u8 toggle)
+void rc_keydown(struct rc_dev *dev, enum rc_type protocol, u32 scancode, u8 toggle)
{
unsigned long flags;
u32 keycode = rc_g_keycode_from_table(dev, scancode);
spin_lock_irqsave(&dev->keylock, flags);
- ir_do_keydown(dev, scancode, keycode, toggle);
+ ir_do_keydown(dev, protocol, scancode, keycode, toggle);
if (dev->keypressed) {
dev->keyup_jiffies = jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT);
@@ -690,20 +694,22 @@ EXPORT_SYMBOL_GPL(rc_keydown);
* rc_keydown_notimeout() - generates input event for a key press without
* an automatic keyup event at a later time
* @dev: the struct rc_dev descriptor of the device
- * @scancode: the scancode that we're seeking
+ * @protocol: the protocol for the keypress
+ * @scancode: the scancode for the keypress
* @toggle: the toggle value (protocol dependent, if the protocol doesn't
* support toggle values, this should be set to zero)
*
* This routine is used to signal that a key has been pressed on the
* remote control. The driver must manually call rc_keyup() at a later stage.
*/
-void rc_keydown_notimeout(struct rc_dev *dev, int scancode, u8 toggle)
+void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol,
+ u32 scancode, u8 toggle)
{
unsigned long flags;
u32 keycode = rc_g_keycode_from_table(dev, scancode);
spin_lock_irqsave(&dev->keylock, flags);
- ir_do_keydown(dev, scancode, keycode, toggle);
+ ir_do_keydown(dev, protocol, scancode, keycode, toggle);
spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
@@ -794,6 +800,7 @@ static struct {
{ RC_BIT_SHARP, "sharp" },
{ RC_BIT_MCE_KBD, "mce_kbd" },
{ RC_BIT_LIRC, "lirc" },
+ { RC_BIT_XMP, "xmp" },
};
/**
@@ -824,7 +831,7 @@ struct rc_filter_attribute {
/**
* show_protocols() - shows the current/wakeup IR protocol(s)
* @device: the device descriptor
- * @mattr: the device attribute struct (unused)
+ * @mattr: the device attribute struct
* @buf: a pointer to the output buffer
*
* This routine is a callback routine for input read the IR protocol type(s).
@@ -850,20 +857,20 @@ static ssize_t show_protocols(struct device *device,
mutex_lock(&dev->lock);
- enabled = dev->enabled_protocols[fattr->type];
- if (dev->driver_type == RC_DRIVER_SCANCODE ||
- fattr->type == RC_FILTER_WAKEUP)
- allowed = dev->allowed_protocols[fattr->type];
- else if (dev->raw)
- allowed = ir_raw_get_allowed_protocols();
- else {
- mutex_unlock(&dev->lock);
- return -ENODEV;
+ if (fattr->type == RC_FILTER_NORMAL) {
+ enabled = dev->enabled_protocols;
+ allowed = dev->allowed_protocols;
+ if (dev->raw && !allowed)
+ allowed = ir_raw_get_allowed_protocols();
+ } else {
+ enabled = dev->enabled_wakeup_protocols;
+ allowed = dev->allowed_wakeup_protocols;
}
- IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
- (long long)allowed,
- (long long)enabled);
+ mutex_unlock(&dev->lock);
+
+ IR_dprintk(1, "%s: allowed - 0x%llx, enabled - 0x%llx\n",
+ __func__, (long long)allowed, (long long)enabled);
for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
if (allowed & enabled & proto_names[i].type)
@@ -879,62 +886,29 @@ static ssize_t show_protocols(struct device *device,
tmp--;
*tmp = '\n';
- mutex_unlock(&dev->lock);
-
return tmp + 1 - buf;
}
/**
- * store_protocols() - changes the current/wakeup IR protocol(s)
- * @device: the device descriptor
- * @mattr: the device attribute struct (unused)
- * @buf: a pointer to the input buffer
- * @len: length of the input buffer
+ * parse_protocol_change() - parses a protocol change request
+ * @protocols: pointer to the bitmask of current protocols
+ * @buf: pointer to the buffer with a list of changes
*
- * This routine is for changing the IR protocol type.
- * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols.
- * Writing "+proto" will add a protocol to the list of enabled protocols.
- * Writing "-proto" will remove a protocol from the list of enabled protocols.
+ * Writing "+proto" will add a protocol to the protocol mask.
+ * Writing "-proto" will remove a protocol from protocol mask.
* Writing "proto" will enable only "proto".
* Writing "none" will disable all protocols.
- * Returns -EINVAL if an invalid protocol combination or unknown protocol name
- * is used, otherwise @len.
- *
- * dev->lock is taken to guard against races between device
- * registration, store_protocols and show_protocols.
+ * Returns the number of changes performed or a negative error code.
*/
-static ssize_t store_protocols(struct device *device,
- struct device_attribute *mattr,
- const char *data,
- size_t len)
+static int parse_protocol_change(u64 *protocols, const char *buf)
{
- struct rc_dev *dev = to_rc_dev(device);
- struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
- bool enable, disable;
const char *tmp;
- u64 old_type, type;
+ unsigned count = 0;
+ bool enable, disable;
u64 mask;
- int rc, i, count = 0;
- ssize_t ret;
- int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
- int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
- struct rc_scancode_filter local_filter, *filter;
-
- /* Device is being removed */
- if (!dev)
- return -EINVAL;
-
- mutex_lock(&dev->lock);
-
- if (dev->driver_type != RC_DRIVER_SCANCODE && !dev->raw) {
- IR_dprintk(1, "Protocol switching not supported\n");
- ret = -EINVAL;
- goto out;
- }
- old_type = dev->enabled_protocols[fattr->type];
- type = old_type;
+ int i;
- while ((tmp = strsep((char **) &data, " \n")) != NULL) {
+ while ((tmp = strsep((char **)&buf, " \n")) != NULL) {
if (!*tmp)
break;
@@ -960,76 +934,124 @@ static ssize_t store_protocols(struct device *device,
if (i == ARRAY_SIZE(proto_names)) {
IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
- ret = -EINVAL;
- goto out;
+ return -EINVAL;
}
count++;
if (enable)
- type |= mask;
+ *protocols |= mask;
else if (disable)
- type &= ~mask;
+ *protocols &= ~mask;
else
- type = mask;
+ *protocols = mask;
}
if (!count) {
IR_dprintk(1, "Protocol not specified\n");
- ret = -EINVAL;
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+/**
+ * store_protocols() - changes the current/wakeup IR protocol(s)
+ * @device: the device descriptor
+ * @mattr: the device attribute struct
+ * @buf: a pointer to the input buffer
+ * @len: length of the input buffer
+ *
+ * This routine is for changing the IR protocol type.
+ * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols.
+ * See parse_protocol_change() for the valid commands.
+ * Returns @len on success or a negative error code.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_protocols and show_protocols.
+ */
+static ssize_t store_protocols(struct device *device,
+ struct device_attribute *mattr,
+ const char *buf, size_t len)
+{
+ struct rc_dev *dev = to_rc_dev(device);
+ struct rc_filter_attribute *fattr = to_rc_filter_attr(mattr);
+ u64 *current_protocols;
+ int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
+ struct rc_scancode_filter *filter;
+ int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
+ u64 old_protocols, new_protocols;
+ ssize_t rc;
+
+ /* Device is being removed */
+ if (!dev)
+ return -EINVAL;
+
+ if (fattr->type == RC_FILTER_NORMAL) {
+ IR_dprintk(1, "Normal protocol change requested\n");
+ current_protocols = &dev->enabled_protocols;
+ change_protocol = dev->change_protocol;
+ filter = &dev->scancode_filter;
+ set_filter = dev->s_filter;
+ } else {
+ IR_dprintk(1, "Wakeup protocol change requested\n");
+ current_protocols = &dev->enabled_wakeup_protocols;
+ change_protocol = dev->change_wakeup_protocol;
+ filter = &dev->scancode_wakeup_filter;
+ set_filter = dev->s_wakeup_filter;
+ }
+
+ if (!change_protocol) {
+ IR_dprintk(1, "Protocol switching not supported\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->lock);
+
+ old_protocols = *current_protocols;
+ new_protocols = old_protocols;
+ rc = parse_protocol_change(&new_protocols, buf);
+ if (rc < 0)
+ goto out;
+
+ rc = change_protocol(dev, &new_protocols);
+ if (rc < 0) {
+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
+ (long long)new_protocols);
goto out;
}
- change_protocol = (fattr->type == RC_FILTER_NORMAL)
- ? dev->change_protocol : dev->change_wakeup_protocol;
- if (change_protocol) {
- rc = change_protocol(dev, &type);
- if (rc < 0) {
- IR_dprintk(1, "Error setting protocols to 0x%llx\n",
- (long long)type);
- ret = -EINVAL;
- goto out;
- }
+ if (new_protocols == old_protocols) {
+ rc = len;
+ goto out;
}
- dev->enabled_protocols[fattr->type] = type;
- IR_dprintk(1, "Current protocol(s): 0x%llx\n",
- (long long)type);
+ *current_protocols = new_protocols;
+ IR_dprintk(1, "Protocols changed to 0x%llx\n", (long long)new_protocols);
/*
* If the protocol is changed the filter needs updating.
* Try setting the same filter with the new protocol (if any).
* Fall back to clearing the filter.
*/
- filter = &dev->scancode_filters[fattr->type];
- set_filter = (fattr->type == RC_FILTER_NORMAL)
- ? dev->s_filter : dev->s_wakeup_filter;
-
- if (set_filter && old_type != type && filter->mask) {
- local_filter = *filter;
- if (!type) {
- /* no protocol => clear filter */
- ret = -1;
- } else {
- /* hardware filtering => try setting, otherwise clear */
- ret = set_filter(dev, &local_filter);
- }
- if (ret < 0) {
- /* clear the filter */
- local_filter.data = 0;
- local_filter.mask = 0;
- set_filter(dev, &local_filter);
- }
+ if (set_filter && filter->mask) {
+ if (new_protocols)
+ rc = set_filter(dev, filter);
+ else
+ rc = -1;
- /* commit the new filter */
- *filter = local_filter;
+ if (rc < 0) {
+ filter->data = 0;
+ filter->mask = 0;
+ set_filter(dev, filter);
+ }
}
- ret = len;
+ rc = len;
out:
mutex_unlock(&dev->lock);
- return ret;
+ return rc;
}
/**
@@ -1055,20 +1077,23 @@ static ssize_t show_filter(struct device *device,
{
struct rc_dev *dev = to_rc_dev(device);
struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
+ struct rc_scancode_filter *filter;
u32 val;
/* Device is being removed */
if (!dev)
return -EINVAL;
+ if (fattr->type == RC_FILTER_NORMAL)
+ filter = &dev->scancode_filter;
+ else
+ filter = &dev->scancode_wakeup_filter;
+
mutex_lock(&dev->lock);
- if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) ||
- (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter))
- val = 0;
- else if (fattr->mask)
- val = dev->scancode_filters[fattr->type].mask;
+ if (fattr->mask)
+ val = filter->mask;
else
- val = dev->scancode_filters[fattr->type].data;
+ val = filter->data;
mutex_unlock(&dev->lock);
return sprintf(buf, "%#x\n", val);
@@ -1095,15 +1120,15 @@ static ssize_t show_filter(struct device *device,
*/
static ssize_t store_filter(struct device *device,
struct device_attribute *attr,
- const char *buf,
- size_t count)
+ const char *buf, size_t len)
{
struct rc_dev *dev = to_rc_dev(device);
struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
- struct rc_scancode_filter local_filter, *filter;
+ struct rc_scancode_filter new_filter, *filter;
int ret;
unsigned long val;
int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);
+ u64 *enabled_protocols;
/* Device is being removed */
if (!dev)
@@ -1113,38 +1138,42 @@ static ssize_t store_filter(struct device *device,
if (ret < 0)
return ret;
- /* Can the scancode filter be set? */
- set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter :
- dev->s_wakeup_filter;
+ if (fattr->type == RC_FILTER_NORMAL) {
+ set_filter = dev->s_filter;
+ enabled_protocols = &dev->enabled_protocols;
+ filter = &dev->scancode_filter;
+ } else {
+ set_filter = dev->s_wakeup_filter;
+ enabled_protocols = &dev->enabled_wakeup_protocols;
+ filter = &dev->scancode_wakeup_filter;
+ }
+
if (!set_filter)
return -EINVAL;
mutex_lock(&dev->lock);
- /* Tell the driver about the new filter */
- filter = &dev->scancode_filters[fattr->type];
- local_filter = *filter;
+ new_filter = *filter;
if (fattr->mask)
- local_filter.mask = val;
+ new_filter.mask = val;
else
- local_filter.data = val;
+ new_filter.data = val;
- if (!dev->enabled_protocols[fattr->type] && local_filter.mask) {
+ if (!*enabled_protocols && val) {
/* refuse to set a filter unless a protocol is enabled */
ret = -EINVAL;
goto unlock;
}
- ret = set_filter(dev, &local_filter);
+ ret = set_filter(dev, &new_filter);
if (ret < 0)
goto unlock;
- /* Success, commit the new filter */
- *filter = local_filter;
+ *filter = new_filter;
unlock:
mutex_unlock(&dev->lock);
- return (ret < 0) ? ret : count;
+ return (ret < 0) ? ret : len;
}
static void rc_dev_release(struct device *device)
@@ -1315,7 +1344,7 @@ int rc_register_device(struct rc_dev *dev)
dev->dev.groups = dev->sysfs_groups;
dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp;
if (dev->s_filter)
- dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
+ dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
if (dev->s_wakeup_filter)
dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
if (dev->change_wakeup_protocol)
@@ -1395,7 +1424,7 @@ int rc_register_device(struct rc_dev *dev)
rc = dev->change_protocol(dev, &rc_type);
if (rc < 0)
goto out_raw;
- dev->enabled_protocols[RC_FILTER_NORMAL] = rc_type;
+ dev->enabled_protocols = rc_type;
}
mutex_unlock(&dev->lock);
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 79abbc8d9600..795b394a5d84 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -878,7 +878,7 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
rc->dev.parent = dev;
rc->priv = rr3;
rc->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rc, RC_BIT_ALL);
+ rc->allowed_protocols = RC_BIT_ALL;
rc->timeout = US_TO_NS(2750);
rc->tx_ir = redrat3_transmit_ir;
rc->s_tx_carrier = redrat3_set_tx_carrier;
diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index 22e4c1f28ab4..5c151351afa4 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -287,7 +287,7 @@ static int st_rc_probe(struct platform_device *pdev)
st_rc_hardware_init(rc_dev);
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
/* rx sampling rate is 10Mhz */
rdev->rx_resolution = 100;
rdev->timeout = US_TO_NS(MAX_SYMB_TIME);
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index bd5e4ff9e0ba..80c4feeb01ea 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -63,13 +63,6 @@ MODULE_DEVICE_TABLE(usb, streamzap_table);
/* number of samples buffered */
#define SZ_BUF_LEN 128
-/* from ir-rc5-sz-decoder.c */
-#ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
-#define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
-#else
-#define load_rc5_sz_decode() {}
-#endif
-
enum StreamzapDecoderState {
PulseSpace,
FullPulse,
@@ -316,7 +309,7 @@ static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
rdev->dev.parent = dev;
rdev->priv = sz;
rdev->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rdev, RC_BIT_ALL);
+ rdev->allowed_protocols = RC_BIT_ALL;
rdev->driver_name = DRIVER_NAME;
rdev->map_name = RC_MAP_STREAMZAP;
@@ -452,9 +445,6 @@ static int streamzap_probe(struct usb_interface *intf,
dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
usbdev->bus->busnum, usbdev->devnum);
- /* Load the streamzap not-quite-rc5 decoder too */
- load_rc5_sz_decode();
-
return 0;
rc_dev_fail:
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
new file mode 100644
index 000000000000..bcee8e1a4e9e
--- /dev/null
+++ b/drivers/media/rc/sunxi-cir.c
@@ -0,0 +1,318 @@
+/*
+ * Driver for Allwinner sunXi IR controller
+ *
+ * Copyright (C) 2014 Alexsey Shestacov <wingrime@linux-sunxi.org>
+ * Copyright (C) 2014 Alexander Bersenev <bay@hackerdom.ru>
+ *
+ * Based on sun5i-ir.c:
+ * Copyright (C) 2007-2012 Daniel Wang
+ * 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/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <media/rc-core.h>
+
+#define SUNXI_IR_DEV "sunxi-ir"
+
+/* Registers */
+/* IR Control */
+#define SUNXI_IR_CTL_REG 0x00
+/* Global Enable */
+#define REG_CTL_GEN BIT(0)
+/* RX block enable */
+#define REG_CTL_RXEN BIT(1)
+/* CIR mode */
+#define REG_CTL_MD (BIT(4) | BIT(5))
+
+/* Rx Config */
+#define SUNXI_IR_RXCTL_REG 0x10
+/* Pulse Polarity Invert flag */
+#define REG_RXCTL_RPPI BIT(2)
+
+/* Rx Data */
+#define SUNXI_IR_RXFIFO_REG 0x20
+
+/* Rx Interrupt Enable */
+#define SUNXI_IR_RXINT_REG 0x2C
+/* Rx FIFO Overflow */
+#define REG_RXINT_ROI_EN BIT(0)
+/* Rx Packet End */
+#define REG_RXINT_RPEI_EN BIT(1)
+/* Rx FIFO Data Available */
+#define REG_RXINT_RAI_EN BIT(4)
+
+/* Rx FIFO available byte level */
+#define REG_RXINT_RAL(val) (((val) << 8) & (GENMASK(11, 8)))
+
+/* Rx Interrupt Status */
+#define SUNXI_IR_RXSTA_REG 0x30
+/* RX FIFO Get Available Counter */
+#define REG_RXSTA_GET_AC(val) (((val) >> 8) & (GENMASK(5, 0)))
+/* Clear all interrupt status value */
+#define REG_RXSTA_CLEARALL 0xff
+
+/* IR Sample Config */
+#define SUNXI_IR_CIR_REG 0x34
+/* CIR_REG register noise threshold */
+#define REG_CIR_NTHR(val) (((val) << 2) & (GENMASK(7, 2)))
+/* CIR_REG register idle threshold */
+#define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8)))
+
+/* Hardware supported fifo size */
+#define SUNXI_IR_FIFO_SIZE 16
+/* How many messages in FIFO trigger IRQ */
+#define TRIGGER_LEVEL 8
+/* Required frequency for IR0 or IR1 clock in CIR mode */
+#define SUNXI_IR_BASE_CLK 8000000
+/* Frequency after IR internal divider */
+#define SUNXI_IR_CLK (SUNXI_IR_BASE_CLK / 64)
+/* Sample period in ns */
+#define SUNXI_IR_SAMPLE (1000000000ul / SUNXI_IR_CLK)
+/* Noise threshold in samples */
+#define SUNXI_IR_RXNOISE 1
+/* Idle Threshold in samples */
+#define SUNXI_IR_RXIDLE 20
+/* Time after which device stops sending data in ms */
+#define SUNXI_IR_TIMEOUT 120
+
+struct sunxi_ir {
+ spinlock_t ir_lock;
+ struct rc_dev *rc;
+ void __iomem *base;
+ int irq;
+ struct clk *clk;
+ struct clk *apb_clk;
+ const char *map_name;
+};
+
+static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id)
+{
+ unsigned long status;
+ unsigned char dt;
+ unsigned int cnt, rc;
+ struct sunxi_ir *ir = dev_id;
+ DEFINE_IR_RAW_EVENT(rawir);
+
+ spin_lock(&ir->ir_lock);
+
+ status = readl(ir->base + SUNXI_IR_RXSTA_REG);
+
+ /* clean all pending statuses */
+ writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
+
+ if (status & REG_RXINT_RAI_EN) {
+ /* How many messages in fifo */
+ rc = REG_RXSTA_GET_AC(status);
+ /* Sanity check */
+ rc = rc > SUNXI_IR_FIFO_SIZE ? SUNXI_IR_FIFO_SIZE : rc;
+ /* If we have data */
+ for (cnt = 0; cnt < rc; cnt++) {
+ /* for each bit in fifo */
+ dt = readb(ir->base + SUNXI_IR_RXFIFO_REG);
+ rawir.pulse = (dt & 0x80) != 0;
+ rawir.duration = ((dt & 0x7f) + 1) * SUNXI_IR_SAMPLE;
+ ir_raw_event_store_with_filter(ir->rc, &rawir);
+ }
+ }
+
+ if (status & REG_RXINT_ROI_EN) {
+ ir_raw_event_reset(ir->rc);
+ } else if (status & REG_RXINT_RPEI_EN) {
+ ir_raw_event_set_idle(ir->rc, true);
+ ir_raw_event_handle(ir->rc);
+ }
+
+ spin_unlock(&ir->ir_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sunxi_ir_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ unsigned long tmp = 0;
+
+ struct device *dev = &pdev->dev;
+ struct device_node *dn = dev->of_node;
+ struct resource *res;
+ struct sunxi_ir *ir;
+
+ ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL);
+ if (!ir)
+ return -ENOMEM;
+
+ /* Clock */
+ ir->apb_clk = devm_clk_get(dev, "apb");
+ if (IS_ERR(ir->apb_clk)) {
+ dev_err(dev, "failed to get a apb clock.\n");
+ return PTR_ERR(ir->apb_clk);
+ }
+ ir->clk = devm_clk_get(dev, "ir");
+ if (IS_ERR(ir->clk)) {
+ dev_err(dev, "failed to get a ir clock.\n");
+ return PTR_ERR(ir->clk);
+ }
+
+ ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK);
+ if (ret) {
+ dev_err(dev, "set ir base clock failed!\n");
+ return ret;
+ }
+
+ if (clk_prepare_enable(ir->apb_clk)) {
+ dev_err(dev, "try to enable apb_ir_clk failed\n");
+ return -EINVAL;
+ }
+
+ if (clk_prepare_enable(ir->clk)) {
+ dev_err(dev, "try to enable ir_clk failed\n");
+ ret = -EINVAL;
+ goto exit_clkdisable_apb_clk;
+ }
+
+ /* IO */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ir->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(ir->base)) {
+ dev_err(dev, "failed to map registers\n");
+ ret = PTR_ERR(ir->base);
+ goto exit_clkdisable_clk;
+ }
+
+ ir->rc = rc_allocate_device();
+ if (!ir->rc) {
+ dev_err(dev, "failed to allocate device\n");
+ ret = -ENOMEM;
+ goto exit_clkdisable_clk;
+ }
+
+ ir->rc->priv = ir;
+ ir->rc->input_name = SUNXI_IR_DEV;
+ ir->rc->input_phys = "sunxi-ir/input0";
+ ir->rc->input_id.bustype = BUS_HOST;
+ ir->rc->input_id.vendor = 0x0001;
+ ir->rc->input_id.product = 0x0001;
+ ir->rc->input_id.version = 0x0100;
+ ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL);
+ ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY;
+ ir->rc->dev.parent = dev;
+ ir->rc->driver_type = RC_DRIVER_IR_RAW;
+ ir->rc->allowed_protocols = RC_BIT_ALL;
+ ir->rc->rx_resolution = SUNXI_IR_SAMPLE;
+ ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT);
+ ir->rc->driver_name = SUNXI_IR_DEV;
+
+ ret = rc_register_device(ir->rc);
+ if (ret) {
+ dev_err(dev, "failed to register rc device\n");
+ goto exit_free_dev;
+ }
+
+ platform_set_drvdata(pdev, ir);
+
+ /* IRQ */
+ ir->irq = platform_get_irq(pdev, 0);
+ if (ir->irq < 0) {
+ dev_err(dev, "no irq resource\n");
+ ret = ir->irq;
+ goto exit_free_dev;
+ }
+
+ ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir);
+ if (ret) {
+ dev_err(dev, "failed request irq\n");
+ goto exit_free_dev;
+ }
+
+ /* Enable CIR Mode */
+ writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG);
+
+ /* Set noise threshold and idle threshold */
+ writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE),
+ ir->base + SUNXI_IR_CIR_REG);
+
+ /* Invert Input Signal */
+ writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG);
+
+ /* Clear All Rx Interrupt Status */
+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
+
+ /*
+ * Enable IRQ on overflow, packet end, FIFO available with trigger
+ * level
+ */
+ writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN |
+ REG_RXINT_RAI_EN | REG_RXINT_RAL(TRIGGER_LEVEL - 1),
+ ir->base + SUNXI_IR_RXINT_REG);
+
+ /* Enable IR Module */
+ tmp = readl(ir->base + SUNXI_IR_CTL_REG);
+ writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG);
+
+ dev_info(dev, "initialized sunXi IR driver\n");
+ return 0;
+
+exit_free_dev:
+ rc_free_device(ir->rc);
+exit_clkdisable_clk:
+ clk_disable_unprepare(ir->clk);
+exit_clkdisable_apb_clk:
+ clk_disable_unprepare(ir->apb_clk);
+
+ return ret;
+}
+
+static int sunxi_ir_remove(struct platform_device *pdev)
+{
+ unsigned long flags;
+ struct sunxi_ir *ir = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(ir->clk);
+ clk_disable_unprepare(ir->apb_clk);
+
+ spin_lock_irqsave(&ir->ir_lock, flags);
+ /* disable IR IRQ */
+ writel(0, ir->base + SUNXI_IR_RXINT_REG);
+ /* clear All Rx Interrupt Status */
+ writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
+ /* disable IR */
+ writel(0, ir->base + SUNXI_IR_CTL_REG);
+ spin_unlock_irqrestore(&ir->ir_lock, flags);
+
+ rc_unregister_device(ir->rc);
+ return 0;
+}
+
+static const struct of_device_id sunxi_ir_match[] = {
+ { .compatible = "allwinner,sun4i-a10-ir", },
+ {},
+};
+
+static struct platform_driver sunxi_ir_driver = {
+ .probe = sunxi_ir_probe,
+ .remove = sunxi_ir_remove,
+ .driver = {
+ .name = SUNXI_IR_DEV,
+ .owner = THIS_MODULE,
+ .of_match_table = sunxi_ir_match,
+ },
+};
+
+module_platform_driver(sunxi_ir_driver);
+
+MODULE_DESCRIPTION("Allwinner sunXi IR controller driver");
+MODULE_AUTHOR("Alexsey Shestacov <wingrime@linux-sunxi.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c
index c5be38e2a2fe..bc214e2b3a36 100644
--- a/drivers/media/rc/ttusbir.c
+++ b/drivers/media/rc/ttusbir.c
@@ -318,7 +318,7 @@ static int ttusbir_probe(struct usb_interface *intf,
usb_to_input_id(tt->udev, &rc->input_id);
rc->dev.parent = &intf->dev;
rc->driver_type = RC_DRIVER_IR_RAW;
- rc_set_allowed_protocols(rc, RC_BIT_ALL);
+ rc->allowed_protocols = RC_BIT_ALL;
rc->priv = tt;
rc->driver_name = DRIVER_NAME;
rc->map_name = RC_MAP_TT_1500;
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index a8b981f5ce2e..d839f73f6a05 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1082,7 +1082,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
data->dev->dev.parent = &device->dev;
data->dev->timeout = MS_TO_NS(100);
data->dev->rx_resolution = US_TO_NS(2);
- rc_set_allowed_protocols(data->dev, RC_BIT_ALL);
+ data->dev->allowed_protocols = RC_BIT_ALL;
err = rc_register_device(data->dev);
if (err)
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 22b6b8bb1d93..d79fd1ce5a18 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -1,7 +1,7 @@
# Analog TV tuners, auto-loaded via tuner.ko
config MEDIA_TUNER
tristate
- depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
+ depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT) && I2C
default y
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
@@ -16,7 +16,7 @@ config MEDIA_TUNER
menu "Customize TV tuners"
visible if !MEDIA_SUBDRV_AUTOSELECT
- depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
+ depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
@@ -71,6 +71,13 @@ config MEDIA_TUNER_TEA5767
help
Say Y here to include support for the Philips TEA5767 radio tuner.
+config MEDIA_TUNER_MSI001
+ tristate "Mirics MSi001"
+ depends on MEDIA_SUPPORT && SPI && VIDEO_V4L2
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ Mirics MSi001 silicon tuner driver.
+
config MEDIA_TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
depends on MEDIA_SUPPORT && I2C
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index a6ff0c628dfa..5591699755ba 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
+obj-$(CONFIG_MEDIA_TUNER_MSI001) += msi001.o
obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_MEDIA_TUNER_MT2063) += mt2063.o
obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
diff --git a/drivers/staging/media/msi3101/msi001.c b/drivers/media/tuners/msi001.c
index bd0b93cb6c53..ee99e372c943 100644
--- a/drivers/staging/media/msi3101/msi001.c
+++ b/drivers/media/tuners/msi001.c
@@ -381,7 +381,7 @@ static int msi001_s_ctrl(struct v4l2_ctrl *ctrl)
int ret;
dev_dbg(&s->spi->dev,
- "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
+ "%s: id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
__func__, ctrl->id, ctrl->name, ctrl->val,
ctrl->minimum, ctrl->maximum, ctrl->step);
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index 96ccfebce7ca..a759742cae7b 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -1545,7 +1545,7 @@ static int r820t_imr_cross(struct r820t_priv *priv,
cross[i].value = rc;
if (cross[i].value < tmp.value)
- memcpy(&tmp, &cross[i], sizeof(tmp));
+ tmp = cross[i];
}
if ((tmp.phase_y & 0x1f) == 1) { /* y-direction */
@@ -2300,7 +2300,6 @@ struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
case 0:
/* memory allocation failure */
goto err_no_gate;
- break;
case 1:
/* new tuner instance */
priv->cfg = cfg;
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index 271a752cee54..6c53edb73a63 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -1,5 +1,5 @@
/*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
@@ -16,54 +16,58 @@
#include "si2157_priv.h"
+static const struct dvb_tuner_ops si2157_ops;
+
/* execute firmware command */
static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd)
{
int ret;
- u8 buf[1];
unsigned long timeout;
mutex_lock(&s->i2c_mutex);
- if (cmd->len) {
+ if (cmd->wlen) {
/* write cmd and args for firmware */
- ret = i2c_master_send(s->client, cmd->args, cmd->len);
+ ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
if (ret < 0) {
goto err_mutex_unlock;
- } else if (ret != cmd->len) {
+ } else if (ret != cmd->wlen) {
ret = -EREMOTEIO;
goto err_mutex_unlock;
}
}
- /* wait cmd execution terminate */
- #define TIMEOUT 80
- timeout = jiffies + msecs_to_jiffies(TIMEOUT);
- while (!time_after(jiffies, timeout)) {
- ret = i2c_master_recv(s->client, buf, 1);
- if (ret < 0) {
- goto err_mutex_unlock;
- } else if (ret != 1) {
- ret = -EREMOTEIO;
- goto err_mutex_unlock;
+ if (cmd->rlen) {
+ /* wait cmd execution terminate */
+ #define TIMEOUT 80
+ timeout = jiffies + msecs_to_jiffies(TIMEOUT);
+ while (!time_after(jiffies, timeout)) {
+ ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
+ if (ret < 0) {
+ goto err_mutex_unlock;
+ } else if (ret != cmd->rlen) {
+ ret = -EREMOTEIO;
+ goto err_mutex_unlock;
+ }
+
+ /* firmware ready? */
+ if ((cmd->args[0] >> 7) & 0x01)
+ break;
}
- /* firmware ready? */
- if ((buf[0] >> 7) & 0x01)
- break;
- }
+ dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
+ __func__,
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - TIMEOUT));
- dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", __func__,
- jiffies_to_msecs(jiffies) -
- (jiffies_to_msecs(timeout) - TIMEOUT));
-
- if (!(buf[0] >> 7) & 0x01) {
- ret = -ETIMEDOUT;
- goto err_mutex_unlock;
- } else {
- ret = 0;
+ if (!((cmd->args[0] >> 7) & 0x01)) {
+ ret = -ETIMEDOUT;
+ goto err_mutex_unlock;
+ }
}
+ ret = 0;
+
err_mutex_unlock:
mutex_unlock(&s->i2c_mutex);
if (ret)
@@ -78,23 +82,133 @@ err:
static int si2157_init(struct dvb_frontend *fe)
{
struct si2157 *s = fe->tuner_priv;
+ int ret, len, remaining;
+ struct si2157_cmd cmd;
+ const struct firmware *fw = NULL;
+ u8 *fw_file;
+ unsigned int chip_id;
dev_dbg(&s->client->dev, "%s:\n", __func__);
+ /* configure? */
+ memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
+ cmd.wlen = 15;
+ cmd.rlen = 1;
+ ret = si2157_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
+ /* query chip revision */
+ memcpy(cmd.args, "\x02", 1);
+ cmd.wlen = 1;
+ cmd.rlen = 13;
+ ret = si2157_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
+ chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
+ cmd.args[4] << 0;
+
+ #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
+ #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
+
+ switch (chip_id) {
+ case SI2158_A20:
+ fw_file = SI2158_A20_FIRMWARE;
+ break;
+ case SI2157_A30:
+ goto skip_fw_download;
+ break;
+ default:
+ dev_err(&s->client->dev,
+ "%s: unkown chip version Si21%d-%c%c%c\n",
+ KBUILD_MODNAME, cmd.args[2], cmd.args[1],
+ cmd.args[3], cmd.args[4]);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* cold state - try to download firmware */
+ dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
+ KBUILD_MODNAME, si2157_ops.info.name);
+
+ /* request the firmware, this will block and timeout */
+ ret = request_firmware(&fw, fw_file, &s->client->dev);
+ if (ret) {
+ dev_err(&s->client->dev, "%s: firmware file '%s' not found\n",
+ KBUILD_MODNAME, fw_file);
+ goto err;
+ }
+
+ /* firmware should be n chunks of 17 bytes */
+ if (fw->size % 17 != 0) {
+ dev_err(&s->client->dev, "%s: firmware file '%s' is invalid\n",
+ KBUILD_MODNAME, fw_file);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
+ KBUILD_MODNAME, fw_file);
+
+ for (remaining = fw->size; remaining > 0; remaining -= 17) {
+ len = fw->data[fw->size - remaining];
+ memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
+ cmd.wlen = len;
+ cmd.rlen = 1;
+ ret = si2157_cmd_execute(s, &cmd);
+ if (ret) {
+ dev_err(&s->client->dev,
+ "%s: firmware download failed=%d\n",
+ KBUILD_MODNAME, ret);
+ goto err;
+ }
+ }
+
+ release_firmware(fw);
+ fw = NULL;
+
+skip_fw_download:
+ /* reboot the tuner with new firmware? */
+ memcpy(cmd.args, "\x01\x01", 2);
+ cmd.wlen = 2;
+ cmd.rlen = 1;
+ ret = si2157_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
s->active = true;
return 0;
+err:
+ if (fw)
+ release_firmware(fw);
+
+ dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
static int si2157_sleep(struct dvb_frontend *fe)
{
struct si2157 *s = fe->tuner_priv;
+ int ret;
+ struct si2157_cmd cmd;
dev_dbg(&s->client->dev, "%s:\n", __func__);
s->active = false;
+ memcpy(cmd.args, "\x13", 1);
+ cmd.wlen = 1;
+ cmd.rlen = 0;
+ ret = si2157_cmd_execute(s, &cmd);
+ if (ret)
+ goto err;
+
return 0;
+err:
+ dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
+ return ret;
}
static int si2157_set_params(struct dvb_frontend *fe)
@@ -103,6 +217,7 @@ static int si2157_set_params(struct dvb_frontend *fe)
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret;
struct si2157_cmd cmd;
+ u8 bandwidth, delivery_system;
dev_dbg(&s->client->dev,
"%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n",
@@ -114,50 +229,46 @@ static int si2157_set_params(struct dvb_frontend *fe)
goto err;
}
- /* configure? */
- cmd.args[0] = 0xc0;
- cmd.args[1] = 0x00;
- cmd.args[2] = 0x0c;
- cmd.args[3] = 0x00;
- cmd.args[4] = 0x00;
- cmd.args[5] = 0x01;
- cmd.args[6] = 0x01;
- cmd.args[7] = 0x01;
- cmd.args[8] = 0x01;
- cmd.args[9] = 0x01;
- cmd.args[10] = 0x01;
- cmd.args[11] = 0x02;
- cmd.args[12] = 0x00;
- cmd.args[13] = 0x00;
- cmd.args[14] = 0x01;
- cmd.len = 15;
- ret = si2157_cmd_execute(s, &cmd);
- if (ret)
- goto err;
-
- cmd.args[0] = 0x02;
- cmd.len = 1;
- ret = si2157_cmd_execute(s, &cmd);
- if (ret)
- goto err;
+ if (c->bandwidth_hz <= 6000000)
+ bandwidth = 0x06;
+ else if (c->bandwidth_hz <= 7000000)
+ bandwidth = 0x07;
+ else if (c->bandwidth_hz <= 8000000)
+ bandwidth = 0x08;
+ else
+ bandwidth = 0x0f;
+
+ switch (c->delivery_system) {
+ case SYS_DVBT:
+ case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
+ delivery_system = 0x20;
+ break;
+ case SYS_DVBC_ANNEX_A:
+ delivery_system = 0x30;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
- cmd.args[0] = 0x01;
- cmd.args[1] = 0x01;
- cmd.len = 2;
+ memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6);
+ cmd.args[4] = delivery_system | bandwidth;
+ if (s->inversion)
+ cmd.args[5] = 0x01;
+ cmd.wlen = 6;
+ cmd.rlen = 1;
ret = si2157_cmd_execute(s, &cmd);
if (ret)
goto err;
/* set frequency */
- cmd.args[0] = 0x41;
- cmd.args[1] = 0x00;
- cmd.args[2] = 0x00;
- cmd.args[3] = 0x00;
+ memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
cmd.args[4] = (c->frequency >> 0) & 0xff;
cmd.args[5] = (c->frequency >> 8) & 0xff;
cmd.args[6] = (c->frequency >> 16) & 0xff;
cmd.args[7] = (c->frequency >> 24) & 0xff;
- cmd.len = 8;
+ cmd.wlen = 8;
+ cmd.rlen = 1;
ret = si2157_cmd_execute(s, &cmd);
if (ret)
goto err;
@@ -168,9 +279,15 @@ err:
return ret;
}
-static const struct dvb_tuner_ops si2157_tuner_ops = {
+static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ *frequency = 5000000; /* default value of property 0x0706 */
+ return 0;
+}
+
+static const struct dvb_tuner_ops si2157_ops = {
.info = {
- .name = "Silicon Labs Si2157",
+ .name = "Silicon Labs Si2157/Si2158",
.frequency_min = 110000000,
.frequency_max = 862000000,
},
@@ -178,6 +295,7 @@ static const struct dvb_tuner_ops si2157_tuner_ops = {
.init = si2157_init,
.sleep = si2157_sleep,
.set_params = si2157_set_params,
+ .get_if_frequency = si2157_get_if_frequency,
};
static int si2157_probe(struct i2c_client *client,
@@ -198,22 +316,24 @@ static int si2157_probe(struct i2c_client *client,
s->client = client;
s->fe = cfg->fe;
+ s->inversion = cfg->inversion;
mutex_init(&s->i2c_mutex);
/* check if the tuner is there */
- cmd.len = 0;
+ cmd.wlen = 0;
+ cmd.rlen = 1;
ret = si2157_cmd_execute(s, &cmd);
if (ret)
goto err;
fe->tuner_priv = s;
- memcpy(&fe->ops.tuner_ops, &si2157_tuner_ops,
+ memcpy(&fe->ops.tuner_ops, &si2157_ops,
sizeof(struct dvb_tuner_ops));
i2c_set_clientdata(client, s);
dev_info(&s->client->dev,
- "%s: Silicon Labs Si2157 successfully attached\n",
+ "%s: Silicon Labs Si2157/Si2158 successfully attached\n",
KBUILD_MODNAME);
return 0;
err:
@@ -255,6 +375,7 @@ static struct i2c_driver si2157_driver = {
module_i2c_driver(si2157_driver);
-MODULE_DESCRIPTION("Silicon Labs Si2157 silicon tuner driver");
+MODULE_DESCRIPTION("Silicon Labs Si2157/Si2158 silicon tuner driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
index f469a092b66b..6da4d5d1c817 100644
--- a/drivers/media/tuners/si2157.h
+++ b/drivers/media/tuners/si2157.h
@@ -1,5 +1,5 @@
/*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
@@ -29,6 +29,11 @@ struct si2157_config {
* frontend
*/
struct dvb_frontend *fe;
+
+ /*
+ * Spectral Inversion
+ */
+ bool inversion;
};
#endif
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h
index 6cc6c6fdab7a..3ddab5e6b500 100644
--- a/drivers/media/tuners/si2157_priv.h
+++ b/drivers/media/tuners/si2157_priv.h
@@ -1,5 +1,5 @@
/*
- * Silicon Labs Si2157 silicon tuner driver
+ * Silicon Labs Si2157/2158 silicon tuner driver
*
* Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
*
@@ -17,6 +17,7 @@
#ifndef SI2157_PRIV_H
#define SI2157_PRIV_H
+#include <linux/firmware.h>
#include "si2157.h"
/* state struct */
@@ -25,13 +26,17 @@ struct si2157 {
struct i2c_client *client;
struct dvb_frontend *fe;
bool active;
+ bool inversion;
};
/* firmare command struct */
#define SI2157_ARGLEN 30
struct si2157_cmd {
u8 args[SI2157_ARGLEN];
- unsigned len;
+ unsigned wlen;
+ unsigned rlen;
};
+#define SI2158_A20_FIRMWARE "dvb-tuner-si2158-a20-01.fw"
+
#endif
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index 6ef93ee1fdcb..565eeebb3aeb 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1489,7 +1489,6 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
case 0:
/* memory allocation failure */
goto fail;
- break;
case 1:
/* new tuner instance */
priv->ctrl.max_len = 13;
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index 2018befabb5a..f9ab79e3432d 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -93,7 +93,7 @@ struct xc4000_priv {
struct firmware_description *firm;
int firm_size;
u32 if_khz;
- u32 freq_hz;
+ u32 freq_hz, freq_offset;
u32 bandwidth;
u8 video_standard;
u8 rf_mode;
@@ -116,6 +116,7 @@ struct xc4000_priv {
#define XC4000_AUDIO_STD_MONO 32
#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.fw"
+#define XC4000_DEFAULT_FIRMWARE_NEW "dvb-fe-xc4000-1.4.1.fw"
/* Misc Defines */
#define MAX_TV_STANDARD 24
@@ -730,13 +731,25 @@ static int xc4000_fwupload(struct dvb_frontend *fe)
char name[33];
const char *fname;
- if (firmware_name[0] != '\0')
+ if (firmware_name[0] != '\0') {
fname = firmware_name;
- else
- fname = XC4000_DEFAULT_FIRMWARE;
- dprintk(1, "Reading firmware %s\n", fname);
- rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
+ dprintk(1, "Reading custom firmware %s\n", fname);
+ rc = request_firmware(&fw, fname,
+ priv->i2c_props.adap->dev.parent);
+ } else {
+ fname = XC4000_DEFAULT_FIRMWARE_NEW;
+ dprintk(1, "Trying to read firmware %s\n", fname);
+ rc = request_firmware(&fw, fname,
+ priv->i2c_props.adap->dev.parent);
+ if (rc == -ENOENT) {
+ fname = XC4000_DEFAULT_FIRMWARE;
+ dprintk(1, "Trying to read firmware %s\n", fname);
+ rc = request_firmware(&fw, fname,
+ priv->i2c_props.adap->dev.parent);
+ }
+ }
+
if (rc < 0) {
if (rc == -ENOENT)
printk(KERN_ERR "Error: firmware %s not found.\n", fname);
@@ -746,6 +759,8 @@ static int xc4000_fwupload(struct dvb_frontend *fe)
return rc;
}
+ dprintk(1, "Loading Firmware: %s\n", fname);
+
p = fw->data;
endp = p + fw->size;
@@ -1157,14 +1172,14 @@ static int xc4000_set_params(struct dvb_frontend *fe)
case SYS_ATSC:
dprintk(1, "%s() VSB modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_AIR;
- priv->freq_hz = c->frequency - 1750000;
+ priv->freq_offset = 1750000;
priv->video_standard = XC4000_DTV6;
type = DTV6;
break;
case SYS_DVBC_ANNEX_B:
dprintk(1, "%s() QAM modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_CABLE;
- priv->freq_hz = c->frequency - 1750000;
+ priv->freq_offset = 1750000;
priv->video_standard = XC4000_DTV6;
type = DTV6;
break;
@@ -1173,23 +1188,23 @@ static int xc4000_set_params(struct dvb_frontend *fe)
dprintk(1, "%s() OFDM\n", __func__);
if (bw == 0) {
if (c->frequency < 400000000) {
- priv->freq_hz = c->frequency - 2250000;
+ priv->freq_offset = 2250000;
} else {
- priv->freq_hz = c->frequency - 2750000;
+ priv->freq_offset = 2750000;
}
priv->video_standard = XC4000_DTV7_8;
type = DTV78;
} else if (bw <= 6000000) {
priv->video_standard = XC4000_DTV6;
- priv->freq_hz = c->frequency - 1750000;
+ priv->freq_offset = 1750000;
type = DTV6;
} else if (bw <= 7000000) {
priv->video_standard = XC4000_DTV7;
- priv->freq_hz = c->frequency - 2250000;
+ priv->freq_offset = 2250000;
type = DTV7;
} else {
priv->video_standard = XC4000_DTV8;
- priv->freq_hz = c->frequency - 2750000;
+ priv->freq_offset = 2750000;
type = DTV8;
}
priv->rf_mode = XC_RF_MODE_AIR;
@@ -1200,6 +1215,8 @@ static int xc4000_set_params(struct dvb_frontend *fe)
goto fail;
}
+ priv->freq_hz = c->frequency - priv->freq_offset;
+
dprintk(1, "%s() frequency=%d (compensated)\n",
__func__, priv->freq_hz);
@@ -1520,7 +1537,7 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
{
struct xc4000_priv *priv = fe->tuner_priv;
- *freq = priv->freq_hz;
+ *freq = priv->freq_hz + priv->freq_offset;
if (debug) {
mutex_lock(&priv->lock);
@@ -1668,7 +1685,6 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
switch (instance) {
case 0:
goto fail;
- break;
case 1:
/* new tuner instance */
priv->bandwidth = 6000000;
@@ -1755,3 +1771,5 @@ EXPORT_SYMBOL(xc4000_attach);
MODULE_AUTHOR("Steven Toth, Davide Ferri");
MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(XC4000_DEFAULT_FIRMWARE_NEW);
+MODULE_FIRMWARE(XC4000_DEFAULT_FIRMWARE);
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 2b3d514be672..e135760f7d48 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -56,7 +56,7 @@ struct xc5000_priv {
u32 if_khz;
u16 xtal_khz;
- u32 freq_hz;
+ u32 freq_hz, freq_offset;
u32 bandwidth;
u8 video_standard;
u8 rf_mode;
@@ -625,48 +625,30 @@ static int xc_set_xtal(struct dvb_frontend *fe)
return ret;
}
-static int xc5000_fwupload(struct dvb_frontend *fe)
+static int xc5000_fwupload(struct dvb_frontend *fe,
+ const struct xc5000_fw_cfg *desired_fw,
+ const struct firmware *fw)
{
struct xc5000_priv *priv = fe->tuner_priv;
- const struct firmware *fw;
int ret;
- const struct xc5000_fw_cfg *desired_fw =
- xc5000_assign_firmware(priv->chip_id);
- priv->pll_register_no = desired_fw->pll_reg;
- priv->init_status_supported = desired_fw->init_status_supported;
- priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
/* request the firmware, this will block and timeout */
- printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
+ dprintk(1, "waiting for firmware upload (%s)...\n",
desired_fw->name);
- ret = request_firmware(&fw, desired_fw->name,
- priv->i2c_props.adap->dev.parent);
- if (ret) {
- printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
- goto out;
- } else {
- printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
- fw->size);
- ret = 0;
- }
+ priv->pll_register_no = desired_fw->pll_reg;
+ priv->init_status_supported = desired_fw->init_status_supported;
+ priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
- if (fw->size != desired_fw->size) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
- ret = -EINVAL;
- } else {
- printk(KERN_INFO "xc5000: firmware uploading...\n");
- ret = xc_load_i2c_sequence(fe, fw->data);
- if (0 == ret)
- ret = xc_set_xtal(fe);
- if (0 == ret)
- printk(KERN_INFO "xc5000: firmware upload complete...\n");
- else
- printk(KERN_ERR "xc5000: firmware upload failed...\n");
- }
-out:
- release_firmware(fw);
+ dprintk(1, "firmware uploading...\n");
+ ret = xc_load_i2c_sequence(fe, fw->data);
+ if (!ret) {
+ ret = xc_set_xtal(fe);
+ dprintk(1, "Firmware upload complete...\n");
+ } else
+ printk(KERN_ERR "xc5000: firmware upload failed...\n");
+
return ret;
}
@@ -749,13 +731,13 @@ static int xc5000_set_params(struct dvb_frontend *fe)
case SYS_ATSC:
dprintk(1, "%s() VSB modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_AIR;
- priv->freq_hz = freq - 1750000;
+ priv->freq_offset = 1750000;
priv->video_standard = DTV6;
break;
case SYS_DVBC_ANNEX_B:
dprintk(1, "%s() QAM modulation\n", __func__);
priv->rf_mode = XC_RF_MODE_CABLE;
- priv->freq_hz = freq - 1750000;
+ priv->freq_offset = 1750000;
priv->video_standard = DTV6;
break;
case SYS_ISDBT:
@@ -770,15 +752,15 @@ static int xc5000_set_params(struct dvb_frontend *fe)
switch (bw) {
case 6000000:
priv->video_standard = DTV6;
- priv->freq_hz = freq - 1750000;
+ priv->freq_offset = 1750000;
break;
case 7000000:
priv->video_standard = DTV7;
- priv->freq_hz = freq - 2250000;
+ priv->freq_offset = 2250000;
break;
case 8000000:
priv->video_standard = DTV8;
- priv->freq_hz = freq - 2750000;
+ priv->freq_offset = 2750000;
break;
default:
printk(KERN_ERR "xc5000 bandwidth not set!\n");
@@ -792,15 +774,15 @@ static int xc5000_set_params(struct dvb_frontend *fe)
priv->rf_mode = XC_RF_MODE_CABLE;
if (bw <= 6000000) {
priv->video_standard = DTV6;
- priv->freq_hz = freq - 1750000;
+ priv->freq_offset = 1750000;
b = 6;
} else if (bw <= 7000000) {
priv->video_standard = DTV7;
- priv->freq_hz = freq - 2250000;
+ priv->freq_offset = 2250000;
b = 7;
} else {
priv->video_standard = DTV7_8;
- priv->freq_hz = freq - 2750000;
+ priv->freq_offset = 2750000;
b = 8;
}
dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__,
@@ -811,6 +793,8 @@ static int xc5000_set_params(struct dvb_frontend *fe)
return -EINVAL;
}
+ priv->freq_hz = freq - priv->freq_offset;
+
dprintk(1, "%s() frequency=%d (compensated to %d)\n",
__func__, freq, priv->freq_hz);
@@ -1061,7 +1045,7 @@ static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
{
struct xc5000_priv *priv = fe->tuner_priv;
dprintk(1, "%s()\n", __func__);
- *freq = priv->freq_hz;
+ *freq = priv->freq_hz + priv->freq_offset;
return 0;
}
@@ -1099,42 +1083,65 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
{
struct xc5000_priv *priv = fe->tuner_priv;
- int ret = 0;
+ const struct xc5000_fw_cfg *desired_fw = xc5000_assign_firmware(priv->chip_id);
+ const struct firmware *fw;
+ int ret, i;
u16 pll_lock_status;
u16 fw_ck;
cancel_delayed_work(&priv->timer_sleep);
- if (force || xc5000_is_firmware_loaded(fe) != 0) {
+ if (!force && xc5000_is_firmware_loaded(fe) == 0)
+ return 0;
-fw_retry:
+ ret = request_firmware(&fw, desired_fw->name,
+ priv->i2c_props.adap->dev.parent);
+ if (ret) {
+ printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
+ return ret;
+ }
+
+ dprintk(1, "firmware read %Zu bytes.\n", fw->size);
+
+ if (fw->size != desired_fw->size) {
+ printk(KERN_ERR "xc5000: Firmware file with incorrect size\n");
+ ret = -EINVAL;
+ goto err;
+ }
- ret = xc5000_fwupload(fe);
+ /* Try up to 5 times to load firmware */
+ for (i = 0; i < 5; i++) {
+ if (i)
+ printk(KERN_CONT " - retrying to upload firmware.\n");
+
+ ret = xc5000_fwupload(fe, desired_fw, fw);
if (ret != 0)
- return ret;
+ goto err;
msleep(20);
if (priv->fw_checksum_supported) {
- if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
- != 0) {
- dprintk(1, "%s() FW checksum reading failed.\n",
- __func__);
- goto fw_retry;
+ if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)) {
+ printk(KERN_ERR
+ "xc5000: FW checksum reading failed.");
+ continue;
}
- if (fw_ck == 0) {
- dprintk(1, "%s() FW checksum failed = 0x%04x\n",
- __func__, fw_ck);
- goto fw_retry;
+ if (!fw_ck) {
+ printk(KERN_ERR
+ "xc5000: FW checksum failed = 0x%04x.",
+ fw_ck);
+ continue;
}
}
/* Start the tuner self-calibration process */
- ret |= xc_initialize(priv);
-
- if (ret != 0)
- goto fw_retry;
+ ret = xc_initialize(priv);
+ if (ret) {
+ printk(KERN_ERR
+ "xc5000: Can't request Self-callibration.");
+ continue;
+ }
/* Wait for calibration to complete.
* We could continue but XC5000 will clock stretch subsequent
@@ -1144,15 +1151,17 @@ fw_retry:
msleep(100);
if (priv->init_status_supported) {
- if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != 0) {
- dprintk(1, "%s() FW failed reading init status.\n",
- __func__);
- goto fw_retry;
+ if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck)) {
+ printk(KERN_ERR
+ "xc5000: FW failed reading init status.");
+ continue;
}
- if (fw_ck == 0) {
- dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
- goto fw_retry;
+ if (!fw_ck) {
+ printk(KERN_ERR
+ "xc5000: FW init status failed = 0x%04x.",
+ fw_ck);
+ continue;
}
}
@@ -1161,15 +1170,27 @@ fw_retry:
&pll_lock_status);
if (pll_lock_status > 63) {
/* PLL is unlocked, force reload of the firmware */
- printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
- goto fw_retry;
+ printk(KERN_ERR
+ "xc5000: PLL not running after fwload.");
+ continue;
}
}
/* Default to "CABLE" mode */
- ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+ ret = xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+ if (!ret)
+ break;
+ printk(KERN_ERR "xc5000: can't set to cable mode.");
}
+err:
+ if (!ret)
+ printk(KERN_INFO "xc5000: Firmware %s loaded and running.\n",
+ desired_fw->name);
+ else
+ printk(KERN_CONT " - too many retries. Giving up\n");
+
+ release_firmware(fw);
return ret;
}
@@ -1302,7 +1323,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
switch (instance) {
case 0:
goto fail;
- break;
case 1:
/* new tuner instance */
priv->bandwidth = 6000000;
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index 39d824e2bb69..94d51e092db3 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -27,6 +27,7 @@ source "drivers/media/usb/hdpvr/Kconfig"
source "drivers/media/usb/tlg2300/Kconfig"
source "drivers/media/usb/usbvision/Kconfig"
source "drivers/media/usb/stk1160/Kconfig"
+source "drivers/media/usb/go7007/Kconfig"
endif
if (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
@@ -52,5 +53,11 @@ if (MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
source "drivers/media/usb/em28xx/Kconfig"
endif
+if MEDIA_SDR_SUPPORT
+ comment "Software defined radio USB devices"
+source "drivers/media/usb/msi2500/Kconfig"
+source "drivers/media/usb/airspy/Kconfig"
+endif
+
endif #MEDIA_USB_SUPPORT
endif #USB
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 7ac4b143dce8..f438efffefc5 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -9,6 +9,8 @@ obj-y += zr364xx/ stkwebcam/ s2255/
obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
obj-$(CONFIG_USB_GSPCA) += gspca/
obj-$(CONFIG_USB_PWC) += pwc/
+obj-$(CONFIG_USB_MSI2500) += msi2500/
+obj-$(CONFIG_USB_AIRSPY) += airspy/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_AU0828) += au0828/
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
@@ -20,3 +22,4 @@ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_TM6000) += tm6000/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_USBTV) += usbtv/
+obj-$(CONFIG_VIDEO_GO7007) += go7007/
diff --git a/drivers/media/usb/airspy/Kconfig b/drivers/media/usb/airspy/Kconfig
new file mode 100644
index 000000000000..10b204cf4dbc
--- /dev/null
+++ b/drivers/media/usb/airspy/Kconfig
@@ -0,0 +1,10 @@
+config USB_AIRSPY
+ tristate "AirSpy"
+ depends on VIDEO_V4L2
+ select VIDEOBUF2_VMALLOC
+ ---help---
+ This is a video4linux2 driver for AirSpy SDR device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called airspy
+
diff --git a/drivers/media/usb/airspy/Makefile b/drivers/media/usb/airspy/Makefile
new file mode 100644
index 000000000000..8d8e61c1a349
--- /dev/null
+++ b/drivers/media/usb/airspy/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_AIRSPY) += airspy.o
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
new file mode 100644
index 000000000000..cb0e515d80ae
--- /dev/null
+++ b/drivers/media/usb/airspy/airspy.c
@@ -0,0 +1,1132 @@
+/*
+ * AirSpy SDR driver
+ *
+ * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
+ *
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* AirSpy USB API commands (from AirSpy Library) */
+enum {
+ CMD_INVALID = 0x00,
+ CMD_RECEIVER_MODE = 0x01,
+ CMD_SI5351C_WRITE = 0x02,
+ CMD_SI5351C_READ = 0x03,
+ CMD_R820T_WRITE = 0x04,
+ CMD_R820T_READ = 0x05,
+ CMD_SPIFLASH_ERASE = 0x06,
+ CMD_SPIFLASH_WRITE = 0x07,
+ CMD_SPIFLASH_READ = 0x08,
+ CMD_BOARD_ID_READ = 0x09,
+ CMD_VERSION_STRING_READ = 0x0a,
+ CMD_BOARD_PARTID_SERIALNO_READ = 0x0b,
+ CMD_SET_SAMPLE_RATE = 0x0c,
+ CMD_SET_FREQ = 0x0d,
+ CMD_SET_LNA_GAIN = 0x0e,
+ CMD_SET_MIXER_GAIN = 0x0f,
+ CMD_SET_VGA_GAIN = 0x10,
+ CMD_SET_LNA_AGC = 0x11,
+ CMD_SET_MIXER_AGC = 0x12,
+ CMD_SET_PACKING = 0x13,
+};
+
+/*
+ * bEndpointAddress 0x81 EP 1 IN
+ * Transfer Type Bulk
+ * wMaxPacketSize 0x0200 1x 512 bytes
+ */
+#define MAX_BULK_BUFS (6)
+#define BULK_BUFFER_SIZE (128 * 512)
+
+static const struct v4l2_frequency_band bands[] = {
+ {
+ .tuner = 0,
+ .type = V4L2_TUNER_ADC,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 20000000,
+ .rangehigh = 20000000,
+ },
+};
+
+static const struct v4l2_frequency_band bands_rf[] = {
+ {
+ .tuner = 1,
+ .type = V4L2_TUNER_RF,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 24000000,
+ .rangehigh = 1750000000,
+ },
+};
+
+/* stream formats */
+struct airspy_format {
+ char *name;
+ u32 pixelformat;
+ u32 buffersize;
+};
+
+/* format descriptions for capture and preview */
+static struct airspy_format formats[] = {
+ {
+ .name = "Real U12LE",
+ .pixelformat = V4L2_SDR_FMT_RU12LE,
+ .buffersize = BULK_BUFFER_SIZE,
+ },
+};
+
+static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
+
+/* intermediate buffers with raw data from the USB device */
+struct airspy_frame_buf {
+ struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
+ struct list_head list;
+};
+
+struct airspy {
+#define POWER_ON (1 << 1)
+#define URB_BUF (1 << 2)
+#define USB_STATE_URB_BUF (1 << 3)
+ unsigned long flags;
+
+ struct usb_device *udev;
+ struct video_device vdev;
+ struct v4l2_device v4l2_dev;
+
+ /* videobuf2 queue and queued buffers list */
+ struct vb2_queue vb_queue;
+ struct list_head queued_bufs;
+ spinlock_t queued_bufs_lock; /* Protects queued_bufs */
+ unsigned sequence; /* Buffer sequence counter */
+ unsigned int vb_full; /* vb is full and packets dropped */
+
+ /* Note if taking both locks v4l2_lock must always be locked first! */
+ struct mutex v4l2_lock; /* Protects everything else */
+ struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
+
+ struct urb *urb_list[MAX_BULK_BUFS];
+ int buf_num;
+ unsigned long buf_size;
+ u8 *buf_list[MAX_BULK_BUFS];
+ dma_addr_t dma_addr[MAX_BULK_BUFS];
+ int urbs_initialized;
+ int urbs_submitted;
+
+ /* USB control message buffer */
+ #define BUF_SIZE 24
+ u8 buf[BUF_SIZE];
+
+ /* Current configuration */
+ unsigned int f_adc;
+ unsigned int f_rf;
+ u32 pixelformat;
+ u32 buffersize;
+
+ /* Controls */
+ struct v4l2_ctrl_handler hdl;
+ struct v4l2_ctrl *lna_gain_auto;
+ struct v4l2_ctrl *lna_gain;
+ struct v4l2_ctrl *mixer_gain_auto;
+ struct v4l2_ctrl *mixer_gain;
+ struct v4l2_ctrl *if_gain;
+
+ /* Sample rate calc */
+ unsigned long jiffies_next;
+ unsigned int sample;
+ unsigned int sample_measured;
+};
+
+#define airspy_dbg_usb_control_msg(_udev, _r, _t, _v, _i, _b, _l) { \
+ char *_direction; \
+ if (_t & USB_DIR_IN) \
+ _direction = "<<<"; \
+ else \
+ _direction = ">>>"; \
+ dev_dbg(&_udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
+ "%s %*ph\n", __func__, _t, _r, _v & 0xff, _v >> 8, \
+ _i & 0xff, _i >> 8, _l & 0xff, _l >> 8, _direction, \
+ _l, _b); \
+}
+
+/* execute firmware command */
+static int airspy_ctrl_msg(struct airspy *s, u8 request, u16 value, u16 index,
+ u8 *data, u16 size)
+{
+ int ret;
+ unsigned int pipe;
+ u8 requesttype;
+
+ switch (request) {
+ case CMD_RECEIVER_MODE:
+ case CMD_SET_FREQ:
+ pipe = usb_sndctrlpipe(s->udev, 0);
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+ break;
+ case CMD_BOARD_ID_READ:
+ case CMD_VERSION_STRING_READ:
+ case CMD_BOARD_PARTID_SERIALNO_READ:
+ case CMD_SET_LNA_GAIN:
+ case CMD_SET_MIXER_GAIN:
+ case CMD_SET_VGA_GAIN:
+ case CMD_SET_LNA_AGC:
+ case CMD_SET_MIXER_AGC:
+ pipe = usb_rcvctrlpipe(s->udev, 0);
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+ break;
+ default:
+ dev_err(&s->udev->dev, "Unknown command %02x\n", request);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /* write request */
+ if (!(requesttype & USB_DIR_IN))
+ memcpy(s->buf, data, size);
+
+ ret = usb_control_msg(s->udev, pipe, request, requesttype, value,
+ index, s->buf, size, 1000);
+ airspy_dbg_usb_control_msg(s->udev, request, requesttype, value,
+ index, s->buf, size);
+ if (ret < 0) {
+ dev_err(&s->udev->dev,
+ "usb_control_msg() failed %d request %02x\n",
+ ret, request);
+ goto err;
+ }
+
+ /* read request */
+ if (requesttype & USB_DIR_IN)
+ memcpy(data, s->buf, size);
+
+ return 0;
+err:
+ return ret;
+}
+
+/* Private functions */
+static struct airspy_frame_buf *airspy_get_next_fill_buf(struct airspy *s)
+{
+ unsigned long flags = 0;
+ struct airspy_frame_buf *buf = NULL;
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ if (list_empty(&s->queued_bufs))
+ goto leave;
+
+ buf = list_entry(s->queued_bufs.next,
+ struct airspy_frame_buf, list);
+ list_del(&buf->list);
+leave:
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+ return buf;
+}
+
+static unsigned int airspy_convert_stream(struct airspy *s,
+ void *dst, void *src, unsigned int src_len)
+{
+ unsigned int dst_len;
+
+ if (s->pixelformat == V4L2_SDR_FMT_RU12LE) {
+ memcpy(dst, src, src_len);
+ dst_len = src_len;
+ } else {
+ dst_len = 0;
+ }
+
+ /* calculate samping rate and output it in 10 seconds intervals */
+ if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+ #define MSECS 10000UL
+ unsigned int samples = s->sample - s->sample_measured;
+ s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
+ s->sample_measured = s->sample;
+ dev_dbg(&s->udev->dev,
+ "slen=%d samples=%u msecs=%lu sample rate=%lu\n",
+ src_len, samples, MSECS,
+ samples * 1000UL / MSECS);
+ }
+
+ /* total number of samples */
+ s->sample += src_len / 2;
+
+ return dst_len;
+}
+
+/*
+ * This gets called for the bulk stream pipe. This is done in interrupt
+ * time, so it has to be fast, not crash, and not stall. Neat.
+ */
+static void airspy_urb_complete(struct urb *urb)
+{
+ struct airspy *s = urb->context;
+ struct airspy_frame_buf *fbuf;
+
+ dev_dbg_ratelimited(&s->udev->dev,
+ "%s: status=%d length=%d/%d errors=%d\n",
+ __func__, urb->status, urb->actual_length,
+ urb->transfer_buffer_length, urb->error_count);
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dev_err_ratelimited(&s->udev->dev, "URB failed %d\n",
+ urb->status);
+ break;
+ }
+
+ if (likely(urb->actual_length > 0)) {
+ void *ptr;
+ unsigned int len;
+ /* get free framebuffer */
+ fbuf = airspy_get_next_fill_buf(s);
+ if (unlikely(fbuf == NULL)) {
+ s->vb_full++;
+ dev_notice_ratelimited(&s->udev->dev,
+ "videobuf is full, %d packets dropped\n",
+ s->vb_full);
+ goto skip;
+ }
+
+ /* fill framebuffer */
+ ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+ len = airspy_convert_stream(s, ptr, urb->transfer_buffer,
+ urb->actual_length);
+ vb2_set_plane_payload(&fbuf->vb, 0, len);
+ v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);
+ fbuf->vb.v4l2_buf.sequence = s->sequence++;
+ vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ }
+skip:
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int airspy_kill_urbs(struct airspy *s)
+{
+ int i;
+
+ for (i = s->urbs_submitted - 1; i >= 0; i--) {
+ dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
+ /* stop the URB */
+ usb_kill_urb(s->urb_list[i]);
+ }
+ s->urbs_submitted = 0;
+
+ return 0;
+}
+
+static int airspy_submit_urbs(struct airspy *s)
+{
+ int i, ret;
+
+ for (i = 0; i < s->urbs_initialized; i++) {
+ dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
+ ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
+ if (ret) {
+ dev_err(&s->udev->dev,
+ "Could not submit URB no. %d - get them all back\n",
+ i);
+ airspy_kill_urbs(s);
+ return ret;
+ }
+ s->urbs_submitted++;
+ }
+
+ return 0;
+}
+
+static int airspy_free_stream_bufs(struct airspy *s)
+{
+ if (s->flags & USB_STATE_URB_BUF) {
+ while (s->buf_num) {
+ s->buf_num--;
+ dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
+ __func__, s->buf_num);
+ usb_free_coherent(s->udev, s->buf_size,
+ s->buf_list[s->buf_num],
+ s->dma_addr[s->buf_num]);
+ }
+ }
+ s->flags &= ~USB_STATE_URB_BUF;
+
+ return 0;
+}
+
+static int airspy_alloc_stream_bufs(struct airspy *s)
+{
+ s->buf_num = 0;
+ s->buf_size = BULK_BUFFER_SIZE;
+
+ dev_dbg(&s->udev->dev,
+ "%s: all in all I will use %u bytes for streaming\n",
+ __func__, MAX_BULK_BUFS * BULK_BUFFER_SIZE);
+
+ for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
+ s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
+ BULK_BUFFER_SIZE, GFP_ATOMIC,
+ &s->dma_addr[s->buf_num]);
+ if (!s->buf_list[s->buf_num]) {
+ dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
+ __func__, s->buf_num);
+ airspy_free_stream_bufs(s);
+ return -ENOMEM;
+ }
+
+ dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+ __func__, s->buf_num,
+ s->buf_list[s->buf_num],
+ (long long)s->dma_addr[s->buf_num]);
+ s->flags |= USB_STATE_URB_BUF;
+ }
+
+ return 0;
+}
+
+static int airspy_free_urbs(struct airspy *s)
+{
+ int i;
+
+ airspy_kill_urbs(s);
+
+ for (i = s->urbs_initialized - 1; i >= 0; i--) {
+ if (s->urb_list[i]) {
+ dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
+ __func__, i);
+ /* free the URBs */
+ usb_free_urb(s->urb_list[i]);
+ }
+ }
+ s->urbs_initialized = 0;
+
+ return 0;
+}
+
+static int airspy_alloc_urbs(struct airspy *s)
+{
+ int i, j;
+
+ /* allocate the URBs */
+ for (i = 0; i < MAX_BULK_BUFS; i++) {
+ dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+ s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!s->urb_list[i]) {
+ dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
+ for (j = 0; j < i; j++)
+ usb_free_urb(s->urb_list[j]);
+ return -ENOMEM;
+ }
+ usb_fill_bulk_urb(s->urb_list[i],
+ s->udev,
+ usb_rcvbulkpipe(s->udev, 0x81),
+ s->buf_list[i],
+ BULK_BUFFER_SIZE,
+ airspy_urb_complete, s);
+
+ s->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+ s->urb_list[i]->transfer_dma = s->dma_addr[i];
+ s->urbs_initialized++;
+ }
+
+ return 0;
+}
+
+/* Must be called with vb_queue_lock hold */
+static void airspy_cleanup_queued_bufs(struct airspy *s)
+{
+ unsigned long flags = 0;
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ while (!list_empty(&s->queued_bufs)) {
+ struct airspy_frame_buf *buf;
+ buf = list_entry(s->queued_bufs.next,
+ struct airspy_frame_buf, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ }
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+/* The user yanked out the cable... */
+static void airspy_disconnect(struct usb_interface *intf)
+{
+ struct v4l2_device *v = usb_get_intfdata(intf);
+ struct airspy *s = container_of(v, struct airspy, v4l2_dev);
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ mutex_lock(&s->vb_queue_lock);
+ mutex_lock(&s->v4l2_lock);
+ /* No need to keep the urbs around after disconnection */
+ s->udev = NULL;
+ v4l2_device_disconnect(&s->v4l2_dev);
+ video_unregister_device(&s->vdev);
+ mutex_unlock(&s->v4l2_lock);
+ mutex_unlock(&s->vb_queue_lock);
+
+ v4l2_device_put(&s->v4l2_dev);
+}
+
+/* Videobuf2 operations */
+static int airspy_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt, unsigned int *nbuffers,
+ unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct airspy *s = vb2_get_drv_priv(vq);
+
+ dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
+
+ /* Need at least 8 buffers */
+ if (vq->num_buffers + *nbuffers < 8)
+ *nbuffers = 8 - vq->num_buffers;
+ *nplanes = 1;
+ sizes[0] = PAGE_ALIGN(s->buffersize);
+
+ dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
+ __func__, *nbuffers, sizes[0]);
+ return 0;
+}
+
+static void airspy_buf_queue(struct vb2_buffer *vb)
+{
+ struct airspy *s = vb2_get_drv_priv(vb->vb2_queue);
+ struct airspy_frame_buf *buf =
+ container_of(vb, struct airspy_frame_buf, vb);
+ unsigned long flags = 0;
+
+ /* Check the device has not disconnected between prep and queuing */
+ if (unlikely(!s->udev)) {
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ list_add_tail(&buf->list, &s->queued_bufs);
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+static int airspy_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct airspy *s = vb2_get_drv_priv(vq);
+ int ret;
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (!s->udev)
+ return -ENODEV;
+
+ mutex_lock(&s->v4l2_lock);
+
+ set_bit(POWER_ON, &s->flags);
+
+ s->sequence = 0;
+
+ ret = airspy_alloc_stream_bufs(s);
+ if (ret)
+ goto err;
+
+ ret = airspy_alloc_urbs(s);
+ if (ret)
+ goto err;
+
+ ret = airspy_submit_urbs(s);
+ if (ret)
+ goto err;
+
+ /* start hardware streaming */
+ ret = airspy_ctrl_msg(s, CMD_RECEIVER_MODE, 1, 0, NULL, 0);
+ if (ret)
+ goto err;
+err:
+ mutex_unlock(&s->v4l2_lock);
+
+ return ret;
+}
+
+static void airspy_stop_streaming(struct vb2_queue *vq)
+{
+ struct airspy *s = vb2_get_drv_priv(vq);
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ mutex_lock(&s->v4l2_lock);
+
+ /* stop hardware streaming */
+ airspy_ctrl_msg(s, CMD_RECEIVER_MODE, 0, 0, NULL, 0);
+
+ airspy_kill_urbs(s);
+ airspy_free_urbs(s);
+ airspy_free_stream_bufs(s);
+
+ airspy_cleanup_queued_bufs(s);
+
+ clear_bit(POWER_ON, &s->flags);
+
+ mutex_unlock(&s->v4l2_lock);
+}
+
+static struct vb2_ops airspy_vb2_ops = {
+ .queue_setup = airspy_queue_setup,
+ .buf_queue = airspy_buf_queue,
+ .start_streaming = airspy_start_streaming,
+ .stop_streaming = airspy_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+static int airspy_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct airspy *s = video_drvdata(file);
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
+ usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
+ V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+
+ return 0;
+}
+
+static int airspy_enum_fmt_sdr_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct airspy *s = video_drvdata(file);
+
+ dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, f->index);
+
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+
+ strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+
+ return 0;
+}
+
+static int airspy_g_fmt_sdr_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct airspy *s = video_drvdata(file);
+
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&s->pixelformat);
+
+ f->fmt.sdr.pixelformat = s->pixelformat;
+ f->fmt.sdr.buffersize = s->buffersize;
+ memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+
+ return 0;
+}
+
+static int airspy_s_fmt_sdr_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct airspy *s = video_drvdata(file);
+ struct vb2_queue *q = &s->vb_queue;
+ int i;
+
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&f->fmt.sdr.pixelformat);
+
+ if (vb2_is_busy(q))
+ return -EBUSY;
+
+ memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+ s->pixelformat = formats[i].pixelformat;
+ s->buffersize = formats[i].buffersize;
+ f->fmt.sdr.buffersize = formats[i].buffersize;
+ return 0;
+ }
+ }
+
+ s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
+
+ return 0;
+}
+
+static int airspy_try_fmt_sdr_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct airspy *s = video_drvdata(file);
+ int i;
+
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&f->fmt.sdr.pixelformat);
+
+ memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+ f->fmt.sdr.buffersize = formats[i].buffersize;
+ return 0;
+ }
+ }
+
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
+
+ return 0;
+}
+
+static int airspy_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *v)
+{
+ struct airspy *s = video_drvdata(file);
+ int ret;
+
+ dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
+
+ if (v->index == 0)
+ ret = 0;
+ else if (v->index == 1)
+ ret = 0;
+ else
+ ret = -EINVAL;
+
+ return ret;
+}
+
+static int airspy_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
+{
+ struct airspy *s = video_drvdata(file);
+ int ret;
+
+ dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
+
+ if (v->index == 0) {
+ strlcpy(v->name, "AirSpy ADC", sizeof(v->name));
+ v->type = V4L2_TUNER_ADC;
+ v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = bands[0].rangelow;
+ v->rangehigh = bands[0].rangehigh;
+ ret = 0;
+ } else if (v->index == 1) {
+ strlcpy(v->name, "AirSpy RF", sizeof(v->name));
+ v->type = V4L2_TUNER_RF;
+ v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = bands_rf[0].rangelow;
+ v->rangehigh = bands_rf[0].rangehigh;
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int airspy_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct airspy *s = video_drvdata(file);
+ int ret = 0;
+ dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
+ __func__, f->tuner, f->type);
+
+ if (f->tuner == 0) {
+ f->type = V4L2_TUNER_ADC;
+ f->frequency = s->f_adc;
+ ret = 0;
+ } else if (f->tuner == 1) {
+ f->type = V4L2_TUNER_RF;
+ f->frequency = s->f_rf;
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int airspy_s_frequency(struct file *file, void *priv,
+ const struct v4l2_frequency *f)
+{
+ struct airspy *s = video_drvdata(file);
+ int ret;
+ u8 buf[4];
+
+ dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
+ __func__, f->tuner, f->type, f->frequency);
+
+ if (f->tuner == 0) {
+ s->f_adc = clamp_t(unsigned int, f->frequency,
+ bands[0].rangelow,
+ bands[0].rangehigh);
+ dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
+ __func__, s->f_adc);
+ ret = 0;
+ } else if (f->tuner == 1) {
+ s->f_rf = clamp_t(unsigned int, f->frequency,
+ bands_rf[0].rangelow,
+ bands_rf[0].rangehigh);
+ dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
+ __func__, s->f_rf);
+ buf[0] = (s->f_rf >> 0) & 0xff;
+ buf[1] = (s->f_rf >> 8) & 0xff;
+ buf[2] = (s->f_rf >> 16) & 0xff;
+ buf[3] = (s->f_rf >> 24) & 0xff;
+ ret = airspy_ctrl_msg(s, CMD_SET_FREQ, 0, 0, buf, 4);
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int airspy_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ struct airspy *s = video_drvdata(file);
+ int ret;
+ dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
+ __func__, band->tuner, band->type, band->index);
+
+ if (band->tuner == 0) {
+ if (band->index >= ARRAY_SIZE(bands)) {
+ ret = -EINVAL;
+ } else {
+ *band = bands[band->index];
+ ret = 0;
+ }
+ } else if (band->tuner == 1) {
+ if (band->index >= ARRAY_SIZE(bands_rf)) {
+ ret = -EINVAL;
+ } else {
+ *band = bands_rf[band->index];
+ ret = 0;
+ }
+ } else {
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct v4l2_ioctl_ops airspy_ioctl_ops = {
+ .vidioc_querycap = airspy_querycap,
+
+ .vidioc_enum_fmt_sdr_cap = airspy_enum_fmt_sdr_cap,
+ .vidioc_g_fmt_sdr_cap = airspy_g_fmt_sdr_cap,
+ .vidioc_s_fmt_sdr_cap = airspy_s_fmt_sdr_cap,
+ .vidioc_try_fmt_sdr_cap = airspy_try_fmt_sdr_cap,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+
+ .vidioc_g_tuner = airspy_g_tuner,
+ .vidioc_s_tuner = airspy_s_tuner,
+
+ .vidioc_g_frequency = airspy_g_frequency,
+ .vidioc_s_frequency = airspy_s_frequency,
+ .vidioc_enum_freq_bands = airspy_enum_freq_bands,
+
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+};
+
+static const struct v4l2_file_operations airspy_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+static struct video_device airspy_template = {
+ .name = "AirSpy SDR",
+ .release = video_device_release_empty,
+ .fops = &airspy_fops,
+ .ioctl_ops = &airspy_ioctl_ops,
+};
+
+static void airspy_video_release(struct v4l2_device *v)
+{
+ struct airspy *s = container_of(v, struct airspy, v4l2_dev);
+
+ v4l2_ctrl_handler_free(&s->hdl);
+ v4l2_device_unregister(&s->v4l2_dev);
+ kfree(s);
+}
+
+static int airspy_set_lna_gain(struct airspy *s)
+{
+ int ret;
+ u8 u8tmp;
+
+ dev_dbg(&s->udev->dev, "%s: lna auto=%d->%d val=%d->%d\n",
+ __func__, s->lna_gain_auto->cur.val,
+ s->lna_gain_auto->val, s->lna_gain->cur.val,
+ s->lna_gain->val);
+
+ ret = airspy_ctrl_msg(s, CMD_SET_LNA_AGC, 0, s->lna_gain_auto->val,
+ &u8tmp, 1);
+ if (ret)
+ goto err;
+
+ if (s->lna_gain_auto->val == false) {
+ ret = airspy_ctrl_msg(s, CMD_SET_LNA_GAIN, 0, s->lna_gain->val,
+ &u8tmp, 1);
+ if (ret)
+ goto err;
+ }
+err:
+ if (ret)
+ dev_dbg(&s->udev->dev, "%s: failed=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int airspy_set_mixer_gain(struct airspy *s)
+{
+ int ret;
+ u8 u8tmp;
+
+ dev_dbg(&s->udev->dev, "%s: mixer auto=%d->%d val=%d->%d\n",
+ __func__, s->mixer_gain_auto->cur.val,
+ s->mixer_gain_auto->val, s->mixer_gain->cur.val,
+ s->mixer_gain->val);
+
+ ret = airspy_ctrl_msg(s, CMD_SET_MIXER_AGC, 0, s->mixer_gain_auto->val,
+ &u8tmp, 1);
+ if (ret)
+ goto err;
+
+ if (s->mixer_gain_auto->val == false) {
+ ret = airspy_ctrl_msg(s, CMD_SET_MIXER_GAIN, 0,
+ s->mixer_gain->val, &u8tmp, 1);
+ if (ret)
+ goto err;
+ }
+err:
+ if (ret)
+ dev_dbg(&s->udev->dev, "%s: failed=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int airspy_set_if_gain(struct airspy *s)
+{
+ int ret;
+ u8 u8tmp;
+
+ dev_dbg(&s->udev->dev, "%s: val=%d->%d\n",
+ __func__, s->if_gain->cur.val, s->if_gain->val);
+
+ ret = airspy_ctrl_msg(s, CMD_SET_VGA_GAIN, 0, s->if_gain->val,
+ &u8tmp, 1);
+ if (ret)
+ goto err;
+err:
+ if (ret)
+ dev_dbg(&s->udev->dev, "%s: failed=%d\n", __func__, ret);
+
+ return ret;
+}
+
+static int airspy_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct airspy *s = container_of(ctrl->handler, struct airspy, hdl);
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:
+ case V4L2_CID_RF_TUNER_LNA_GAIN:
+ ret = airspy_set_lna_gain(s);
+ break;
+ case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:
+ case V4L2_CID_RF_TUNER_MIXER_GAIN:
+ ret = airspy_set_mixer_gain(s);
+ break;
+ case V4L2_CID_RF_TUNER_IF_GAIN:
+ ret = airspy_set_if_gain(s);
+ break;
+ default:
+ dev_dbg(&s->udev->dev, "%s: unknown ctrl: id=%d name=%s\n",
+ __func__, ctrl->id, ctrl->name);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops airspy_ctrl_ops = {
+ .s_ctrl = airspy_s_ctrl,
+};
+
+static int airspy_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct airspy *s = NULL;
+ int ret;
+ u8 u8tmp, buf[BUF_SIZE];
+
+ s = kzalloc(sizeof(struct airspy), GFP_KERNEL);
+ if (s == NULL) {
+ dev_err(&udev->dev,
+ "Could not allocate memory for airspy state\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&s->v4l2_lock);
+ mutex_init(&s->vb_queue_lock);
+ spin_lock_init(&s->queued_bufs_lock);
+ INIT_LIST_HEAD(&s->queued_bufs);
+ s->udev = udev;
+ s->f_adc = bands[0].rangelow;
+ s->f_rf = bands_rf[0].rangelow;
+ s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+
+ /* Detect device */
+ ret = airspy_ctrl_msg(s, CMD_BOARD_ID_READ, 0, 0, &u8tmp, 1);
+ if (ret == 0)
+ ret = airspy_ctrl_msg(s, CMD_VERSION_STRING_READ, 0, 0,
+ buf, BUF_SIZE);
+ if (ret) {
+ dev_err(&s->udev->dev, "Could not detect board\n");
+ goto err_free_mem;
+ }
+
+ buf[BUF_SIZE - 1] = '\0';
+
+ dev_info(&s->udev->dev, "Board ID: %02x\n", u8tmp);
+ dev_info(&s->udev->dev, "Firmware version: %s\n", buf);
+
+ /* Init videobuf2 queue structure */
+ s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
+ s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+ s->vb_queue.drv_priv = s;
+ s->vb_queue.buf_struct_size = sizeof(struct airspy_frame_buf);
+ s->vb_queue.ops = &airspy_vb2_ops;
+ s->vb_queue.mem_ops = &vb2_vmalloc_memops;
+ s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ ret = vb2_queue_init(&s->vb_queue);
+ if (ret) {
+ dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
+ goto err_free_mem;
+ }
+
+ /* Init video_device structure */
+ s->vdev = airspy_template;
+ s->vdev.queue = &s->vb_queue;
+ s->vdev.queue->lock = &s->vb_queue_lock;
+ video_set_drvdata(&s->vdev, s);
+
+ /* Register the v4l2_device structure */
+ s->v4l2_dev.release = airspy_video_release;
+ ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);
+ if (ret) {
+ dev_err(&s->udev->dev,
+ "Failed to register v4l2-device (%d)\n", ret);
+ goto err_free_mem;
+ }
+
+ /* Register controls */
+ v4l2_ctrl_handler_init(&s->hdl, 5);
+ s->lna_gain_auto = v4l2_ctrl_new_std(&s->hdl, &airspy_ctrl_ops,
+ V4L2_CID_RF_TUNER_LNA_GAIN_AUTO, 0, 1, 1, 0);
+ s->lna_gain = v4l2_ctrl_new_std(&s->hdl, &airspy_ctrl_ops,
+ V4L2_CID_RF_TUNER_LNA_GAIN, 0, 14, 1, 8);
+ v4l2_ctrl_auto_cluster(2, &s->lna_gain_auto, 0, false);
+ s->mixer_gain_auto = v4l2_ctrl_new_std(&s->hdl, &airspy_ctrl_ops,
+ V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO, 0, 1, 1, 0);
+ s->mixer_gain = v4l2_ctrl_new_std(&s->hdl, &airspy_ctrl_ops,
+ V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 15, 1, 8);
+ v4l2_ctrl_auto_cluster(2, &s->mixer_gain_auto, 0, false);
+ s->if_gain = v4l2_ctrl_new_std(&s->hdl, &airspy_ctrl_ops,
+ V4L2_CID_RF_TUNER_IF_GAIN, 0, 15, 1, 0);
+ if (s->hdl.error) {
+ ret = s->hdl.error;
+ dev_err(&s->udev->dev, "Could not initialize controls\n");
+ goto err_free_controls;
+ }
+
+ v4l2_ctrl_handler_setup(&s->hdl);
+
+ s->v4l2_dev.ctrl_handler = &s->hdl;
+ s->vdev.v4l2_dev = &s->v4l2_dev;
+ s->vdev.lock = &s->v4l2_lock;
+
+ ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
+ if (ret) {
+ dev_err(&s->udev->dev,
+ "Failed to register as video device (%d)\n",
+ ret);
+ goto err_unregister_v4l2_dev;
+ }
+ dev_info(&s->udev->dev, "Registered as %s\n",
+ video_device_node_name(&s->vdev));
+ dev_notice(&s->udev->dev,
+ "%s: SDR API is still slightly experimental and functionality changes may follow\n",
+ KBUILD_MODNAME);
+ return 0;
+
+err_free_controls:
+ v4l2_ctrl_handler_free(&s->hdl);
+err_unregister_v4l2_dev:
+ v4l2_device_unregister(&s->v4l2_dev);
+err_free_mem:
+ kfree(s);
+ return ret;
+}
+
+/* USB device ID list */
+static struct usb_device_id airspy_id_table[] = {
+ { USB_DEVICE(0x1d50, 0x60a1) }, /* AirSpy */
+ { }
+};
+MODULE_DEVICE_TABLE(usb, airspy_id_table);
+
+/* USB subsystem interface */
+static struct usb_driver airspy_driver = {
+ .name = KBUILD_MODNAME,
+ .probe = airspy_probe,
+ .disconnect = airspy_disconnect,
+ .id_table = airspy_id_table,
+};
+
+module_usb_driver(airspy_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("AirSpy SDR");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig
index 953a37c613b1..1d410ac8f9a8 100644
--- a/drivers/media/usb/au0828/Kconfig
+++ b/drivers/media/usb/au0828/Kconfig
@@ -20,9 +20,17 @@ config VIDEO_AU0828_V4L2
bool "Auvitek AU0828 v4l2 analog video support"
depends on VIDEO_AU0828 && VIDEO_V4L2
select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT
+ select VIDEO_TUNER
default y
---help---
This is a video4linux driver for Auvitek's USB device.
Choose Y here to include support for v4l2 analog video
capture within the au0828 driver.
+
+config VIDEO_AU0828_RC
+ bool "AU0828 Remote Controller support"
+ depends on RC_CORE
+ depends on VIDEO_AU0828
+ ---help---
+ Enables Remote Controller support on au0828 driver.
diff --git a/drivers/media/usb/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index be3bdf698022..3dc7539a5c4e 100644
--- a/drivers/media/usb/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -4,6 +4,10 @@ ifeq ($(CONFIG_VIDEO_AU0828_V4L2),y)
au0828-objs += au0828-video.o au0828-vbi.o
endif
+ifeq ($(CONFIG_VIDEO_AU0828_RC),y)
+ au0828-objs += au0828-input.o
+endif
+
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index 7fdadf9bc90b..2c6b7da137ed 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -46,7 +46,7 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR850",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
- .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -71,13 +71,14 @@ struct au0828_board au0828_boards[] = {
.name = "Hauppauge HVR950Q",
.tuner_type = TUNER_XC5000,
.tuner_addr = 0x61,
+ .has_ir_i2c = 1,
/* The au0828 hardware i2c implementation does not properly
support the xc5000's i2c clock stretching. So we need to
lower the clock frequency enough where the 15us clock
stretch fits inside of a normal clock cycle, or else the
au0828 fails to set the STOP bit. A 30 KHz clock puts the
clock pulse width at 18us */
- .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
@@ -108,7 +109,7 @@ struct au0828_board au0828_boards[] = {
.name = "DViCO FusionHDTV USB",
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .i2c_clk_divider = AU0828_I2C_CLK_20KHZ,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index ab45a6f9dcc9..56025e689442 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -32,10 +32,12 @@
* 2 = USB handling
* 4 = I2C related
* 8 = Bridge related
+ * 16 = IR related
*/
int au0828_debug;
module_param_named(debug, au0828_debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debug messages");
+MODULE_PARM_DESC(debug,
+ "set debug bitmask: 1=general, 2=USB, 4=I2C, 8=bridge, 16=IR");
static unsigned int disable_usb_speed_check;
module_param(disable_usb_speed_check, int, 0444);
@@ -151,6 +153,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
dprintk(1, "%s()\n", __func__);
+#ifdef CONFIG_VIDEO_AU0828_RC
+ au0828_rc_unregister(dev);
+#endif
/* Digital TV */
au0828_dvb_unregister(dev);
@@ -261,9 +266,15 @@ static int au0828_usb_probe(struct usb_interface *interface,
pr_err("%s() au0282_dev_register failed\n",
__func__);
+#ifdef CONFIG_VIDEO_AU0828_RC
+ /* Remote controller */
+ au0828_rc_register(dev);
+#endif
- /* Store the pointer to the au0828_dev so it can be accessed in
- au0828_usb_disconnect */
+ /*
+ * Store the pointer to the au0828_dev so it can be accessed in
+ * au0828_usb_disconnect
+ */
usb_set_intfdata(interface, dev);
printk(KERN_INFO "Registered device AU0828 [%s]\n",
@@ -279,6 +290,8 @@ static struct usb_driver au0828_usb_driver = {
.probe = au0828_usb_probe,
.disconnect = au0828_usb_disconnect,
.id_table = au0828_usb_id_table,
+
+ /* FIXME: Add suspend and resume functions */
};
static int __init au0828_init(void)
@@ -298,6 +311,10 @@ static int __init au0828_init(void)
printk(KERN_INFO "%s() Bridge Debugging is enabled\n",
__func__);
+ if (au0828_debug & 16)
+ printk(KERN_INFO "%s() IR Debugging is enabled\n",
+ __func__);
+
printk(KERN_INFO "au0828 driver loaded\n");
ret = usb_register(&au0828_usb_driver);
@@ -318,4 +335,4 @@ module_exit(au0828_exit);
MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.2");
+MODULE_VERSION("0.0.3");
diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c
index 17ec3651b10e..daaeaf1b089c 100644
--- a/drivers/media/usb/au0828/au0828-i2c.c
+++ b/drivers/media/usb/au0828/au0828-i2c.c
@@ -141,25 +141,27 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
{
int i, strobe = 0;
struct au0828_dev *dev = i2c_adap->algo_data;
+ u8 i2c_speed = dev->board.i2c_clk_divider;
dprintk(4, "%s()\n", __func__);
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
- /* Set the I2C clock */
if (((dev->board.tuner_type == TUNER_XC5000) ||
(dev->board.tuner_type == TUNER_XC5000C)) &&
- (dev->board.tuner_addr == msg->addr) &&
- (msg->len == 64)) {
- /* Hack to speed up firmware load. The xc5000 lets us do up
- to 400 KHz when in firmware download mode */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- AU0828_I2C_CLK_250KHZ);
- } else {
- /* Use the i2c clock speed in the board configuration */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- dev->board.i2c_clk_divider);
+ (dev->board.tuner_addr == msg->addr)) {
+ /*
+ * Due to I2C clock stretch, we need to use a lower speed
+ * on xc5000 for commands. However, firmware transfer can
+ * speed up to 400 KHz.
+ */
+ if (msg->len == 64)
+ i2c_speed = AU0828_I2C_CLK_250KHZ;
+ else
+ i2c_speed = AU0828_I2C_CLK_20KHZ;
}
+ /* Set the I2C clock */
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
/* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
@@ -228,15 +230,24 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
const struct i2c_msg *msg, int joined)
{
struct au0828_dev *dev = i2c_adap->algo_data;
+ u8 i2c_speed = dev->board.i2c_clk_divider;
int i;
dprintk(4, "%s()\n", __func__);
au0828_write(dev, AU0828_I2C_MULTIBYTE_MODE_2FF, 0x01);
+ /*
+ * Due to xc5000c clock stretch, we cannot use full speed at
+ * readings from xc5000, as otherwise they'll fail.
+ */
+ if (((dev->board.tuner_type == TUNER_XC5000) ||
+ (dev->board.tuner_type == TUNER_XC5000C)) &&
+ (dev->board.tuner_addr == msg->addr))
+ i2c_speed = AU0828_I2C_CLK_20KHZ;
+
/* Set the I2C clock */
- au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202,
- dev->board.i2c_clk_divider);
+ au0828_write(dev, AU0828_I2C_CLK_DIVIDER_202, i2c_speed);
/* Hardware needs 8 bit addresses */
au0828_write(dev, AU0828_I2C_DEST_ADDR_203, msg->addr << 1);
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
new file mode 100644
index 000000000000..fd0d3a90ce7d
--- /dev/null
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -0,0 +1,386 @@
+/*
+ handle au0828 IR remotes via linux kernel input layer.
+
+ Copyright (C) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
+ Copyright (c) 2014 Samsung Electronics Co., Ltd.
+
+ Based on em28xx-input.c.
+
+ 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/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <media/rc-core.h>
+
+#include "au0828.h"
+
+struct au0828_rc {
+ struct au0828_dev *dev;
+ struct rc_dev *rc;
+ char name[32];
+ char phys[32];
+
+ /* poll decoder */
+ int polling;
+ struct delayed_work work;
+
+ /* i2c slave address of external device (if used) */
+ u16 i2c_dev_addr;
+
+ int (*get_key_i2c)(struct au0828_rc *ir);
+};
+
+/*
+ * AU8522 has a builtin IR receiver. Add functions to get IR from it
+ */
+
+static int au8522_rc_write(struct au0828_rc *ir, u16 reg, u8 data)
+{
+ int rc;
+ char buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
+ struct i2c_msg msg = { .addr = ir->i2c_dev_addr, .flags = 0,
+ .buf = buf, .len = sizeof(buf) };
+
+ rc = i2c_transfer(ir->dev->i2c_client.adapter, &msg, 1);
+
+ if (rc < 0)
+ return rc;
+
+ return (rc == 1) ? 0 : -EIO;
+}
+
+static int au8522_rc_read(struct au0828_rc *ir, u16 reg, int val,
+ char *buf, int size)
+{
+ int rc;
+ char obuf[3];
+ struct i2c_msg msg[2] = { { .addr = ir->i2c_dev_addr, .flags = 0,
+ .buf = obuf, .len = 2 },
+ { .addr = ir->i2c_dev_addr, .flags = I2C_M_RD,
+ .buf = buf, .len = size } };
+
+ obuf[0] = 0x40 | reg >> 8;
+ obuf[1] = reg & 0xff;
+ if (val >= 0) {
+ obuf[2] = val;
+ msg[0].len++;
+ }
+
+ rc = i2c_transfer(ir->dev->i2c_client.adapter, msg, 2);
+
+ if (rc < 0)
+ return rc;
+
+ return (rc == 2) ? 0 : -EIO;
+}
+
+static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value)
+{
+ int rc;
+ char buf;
+
+ rc = au8522_rc_read(ir, reg, -1, &buf, 1);
+ if (rc < 0)
+ return rc;
+
+ buf = (buf & ~mask) | (value & mask);
+
+ return au8522_rc_write(ir, reg, buf);
+}
+
+#define au8522_rc_set(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), (bit))
+#define au8522_rc_clear(ir, reg, bit) au8522_rc_andor(ir, (reg), (bit), 0)
+
+/* Remote Controller time units */
+
+#define AU8522_UNIT 200000 /* ns */
+#define NEC_START_SPACE (4500000 / AU8522_UNIT)
+#define NEC_START_PULSE (562500 * 16)
+#define RC5_START_SPACE (4 * AU8522_UNIT)
+#define RC5_START_PULSE 888888
+
+static int au0828_get_key_au8522(struct au0828_rc *ir)
+{
+ unsigned char buf[40];
+ DEFINE_IR_RAW_EVENT(rawir);
+ int i, j, rc;
+ int prv_bit, bit, width;
+ bool first = true;
+
+ /* Check IR int */
+ rc = au8522_rc_read(ir, 0xe1, -1, buf, 1);
+ if (rc < 0 || !(buf[0] & (1 << 4)))
+ return 0;
+
+ /* Something arrived. Get the data */
+ rc = au8522_rc_read(ir, 0xe3, 0x11, buf, sizeof(buf));
+
+
+ if (rc < 0)
+ return rc;
+
+ /* Disable IR */
+ au8522_rc_clear(ir, 0xe0, 1 << 4);
+
+ usleep_range(45000, 46000);
+
+ /* Enable IR */
+ au8522_rc_set(ir, 0xe0, 1 << 4);
+
+ dprintk(16, "RC data received: %*ph\n", 40, buf);
+
+ prv_bit = (buf[0] >> 7) & 0x01;
+ width = 0;
+ for (i = 0; i < sizeof(buf); i++) {
+ for (j = 7; j >= 0; j--) {
+ bit = (buf[i] >> j) & 0x01;
+ if (bit == prv_bit) {
+ width++;
+ continue;
+ }
+
+ /*
+ * Fix an au8522 bug: the first pulse event
+ * is lost. So, we need to fake it, based on the
+ * protocol. That means that not all raw decoders
+ * will work, as we need to add a hack for each
+ * protocol, based on the first space.
+ * So, we only support RC5 and NEC.
+ */
+
+ if (first) {
+ first = false;
+
+ init_ir_raw_event(&rawir);
+ rawir.pulse = true;
+ if (width > NEC_START_SPACE - 2 &&
+ width < NEC_START_SPACE + 2) {
+ /* NEC protocol */
+ rawir.duration = NEC_START_PULSE;
+ dprintk(16, "Storing NEC start %s with duration %d",
+ rawir.pulse ? "pulse" : "space",
+ rawir.duration);
+ } else {
+ /* RC5 protocol */
+ rawir.duration = RC5_START_PULSE;
+ dprintk(16, "Storing RC5 start %s with duration %d",
+ rawir.pulse ? "pulse" : "space",
+ rawir.duration);
+ }
+ ir_raw_event_store(ir->rc, &rawir);
+ }
+
+ init_ir_raw_event(&rawir);
+ rawir.pulse = prv_bit ? false : true;
+ rawir.duration = AU8522_UNIT * width;
+ dprintk(16, "Storing %s with duration %d",
+ rawir.pulse ? "pulse" : "space",
+ rawir.duration);
+ ir_raw_event_store(ir->rc, &rawir);
+
+ width = 1;
+ prv_bit = bit;
+ }
+ }
+
+ init_ir_raw_event(&rawir);
+ rawir.pulse = prv_bit ? false : true;
+ rawir.duration = AU8522_UNIT * width;
+ dprintk(16, "Storing end %s with duration %d",
+ rawir.pulse ? "pulse" : "space",
+ rawir.duration);
+ ir_raw_event_store(ir->rc, &rawir);
+
+ ir_raw_event_handle(ir->rc);
+
+ return 1;
+}
+
+/*
+ * Generic IR code
+ */
+
+static void au0828_rc_work(struct work_struct *work)
+{
+ struct au0828_rc *ir = container_of(work, struct au0828_rc, work.work);
+ int rc;
+
+ rc = ir->get_key_i2c(ir);
+ if (rc < 0)
+ pr_info("Error while getting RC scancode\n");
+
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+}
+
+static int au0828_rc_start(struct rc_dev *rc)
+{
+ struct au0828_rc *ir = rc->priv;
+
+ INIT_DELAYED_WORK(&ir->work, au0828_rc_work);
+
+ /* Enable IR */
+ au8522_rc_set(ir, 0xe0, 1 << 4);
+
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+
+ return 0;
+}
+
+static void au0828_rc_stop(struct rc_dev *rc)
+{
+ struct au0828_rc *ir = rc->priv;
+
+ /* Disable IR */
+ au8522_rc_clear(ir, 0xe0, 1 << 4);
+
+ cancel_delayed_work_sync(&ir->work);
+}
+
+static int au0828_probe_i2c_ir(struct au0828_dev *dev)
+{
+ int i = 0;
+ const unsigned short addr_list[] = {
+ 0x47, I2C_CLIENT_END
+ };
+
+ while (addr_list[i] != I2C_CLIENT_END) {
+ if (i2c_probe_func_quick_read(dev->i2c_client.adapter,
+ addr_list[i]) == 1)
+ return addr_list[i];
+ i++;
+ }
+
+ return -ENODEV;
+}
+
+int au0828_rc_register(struct au0828_dev *dev)
+{
+ struct au0828_rc *ir;
+ struct rc_dev *rc;
+ int err = -ENOMEM;
+ u16 i2c_rc_dev_addr = 0;
+
+ if (!dev->board.has_ir_i2c)
+ return 0;
+
+ i2c_rc_dev_addr = au0828_probe_i2c_ir(dev);
+ if (!i2c_rc_dev_addr)
+ return -ENODEV;
+
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ rc = rc_allocate_device();
+ if (!ir || !rc)
+ goto error;
+
+ /* record handles to ourself */
+ ir->dev = dev;
+ dev->ir = ir;
+ ir->rc = rc;
+
+ rc->priv = ir;
+ rc->open = au0828_rc_start;
+ rc->close = au0828_rc_stop;
+
+ if (dev->board.has_ir_i2c) { /* external i2c device */
+ switch (dev->boardnr) {
+ case AU0828_BOARD_HAUPPAUGE_HVR950Q:
+ rc->map_name = RC_MAP_HAUPPAUGE;
+ ir->get_key_i2c = au0828_get_key_au8522;
+ break;
+ default:
+ err = -ENODEV;
+ goto error;
+ }
+
+ ir->i2c_dev_addr = i2c_rc_dev_addr;
+ }
+
+ /* This is how often we ask the chip for IR information */
+ ir->polling = 100; /* ms */
+
+ /* init input device */
+ snprintf(ir->name, sizeof(ir->name), "au0828 IR (%s)",
+ dev->board.name);
+
+ usb_make_path(dev->usbdev, ir->phys, sizeof(ir->phys));
+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
+
+ rc->input_name = ir->name;
+ rc->input_phys = ir->phys;
+ rc->input_id.bustype = BUS_USB;
+ rc->input_id.version = 1;
+ rc->input_id.vendor = le16_to_cpu(dev->usbdev->descriptor.idVendor);
+ rc->input_id.product = le16_to_cpu(dev->usbdev->descriptor.idProduct);
+ rc->dev.parent = &dev->usbdev->dev;
+ rc->driver_name = "au0828-input";
+ rc->driver_type = RC_DRIVER_IR_RAW;
+ rc->allowed_protocols = RC_BIT_NEC | RC_BIT_RC5;
+
+ /* all done */
+ err = rc_register_device(rc);
+ if (err)
+ goto error;
+
+ pr_info("Remote controller %s initalized\n", ir->name);
+
+ return 0;
+
+error:
+ dev->ir = NULL;
+ rc_free_device(rc);
+ kfree(ir);
+ return err;
+}
+
+void au0828_rc_unregister(struct au0828_dev *dev)
+{
+ struct au0828_rc *ir = dev->ir;
+
+ /* skip detach on non attached boards */
+ if (!ir)
+ return;
+
+ if (ir->rc)
+ rc_unregister_device(ir->rc);
+
+ /* done */
+ kfree(ir);
+ dev->ir = NULL;
+}
+
+int au0828_rc_suspend(struct au0828_dev *dev)
+{
+ struct au0828_rc *ir = dev->ir;
+
+ if (!ir)
+ return 0;
+
+ cancel_delayed_work_sync(&ir->work);
+
+ return 0;
+}
+
+int au0828_rc_resume(struct au0828_dev *dev)
+{
+ struct au0828_rc *ir = dev->ir;
+
+ if (!ir)
+ return 0;
+
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+
+ return 0;
+}
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 9038194513c5..98f7ea1d6d63 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -787,23 +787,40 @@ static int au0828_i2s_init(struct au0828_dev *dev)
/*
* Auvitek au0828 analog stream enable
- * Please set interface0 to AS5 before enable the stream
*/
static int au0828_analog_stream_enable(struct au0828_dev *d)
{
+ struct usb_interface *iface;
+ int ret, h, w;
+
dprintk(1, "au0828_analog_stream_enable called\n");
+
+ iface = usb_ifnum_to_if(d->usbdev, 0);
+ if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
+ dprintk(1, "Changing intf#0 to alt 5\n");
+ /* set au0828 interface0 to AS5 here again */
+ ret = usb_set_interface(d->usbdev, 0, 5);
+ if (ret < 0) {
+ printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
+ return -EBUSY;
+ }
+ }
+
+ h = d->height / 2 + 2;
+ w = d->width * 2;
+
au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
au0828_writereg(d, 0x106, 0x00);
/* set x position */
au0828_writereg(d, 0x110, 0x00);
au0828_writereg(d, 0x111, 0x00);
- au0828_writereg(d, 0x114, 0xa0);
- au0828_writereg(d, 0x115, 0x05);
+ au0828_writereg(d, 0x114, w & 0xff);
+ au0828_writereg(d, 0x115, w >> 8);
/* set y position */
au0828_writereg(d, 0x112, 0x00);
au0828_writereg(d, 0x113, 0x00);
- au0828_writereg(d, 0x116, 0xf2);
- au0828_writereg(d, 0x117, 0x00);
+ au0828_writereg(d, 0x116, h & 0xff);
+ au0828_writereg(d, 0x117, h >> 8);
au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
return 0;
@@ -1002,15 +1019,6 @@ static int au0828_v4l2_open(struct file *filp)
return -ERESTARTSYS;
}
if (dev->users == 0) {
- /* set au0828 interface0 to AS5 here again */
- ret = usb_set_interface(dev->usbdev, 0, 5);
- if (ret < 0) {
- mutex_unlock(&dev->lock);
- printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
- kfree(fh);
- return -EBUSY;
- }
-
au0828_analog_stream_enable(dev);
au0828_analog_stream_reset(dev);
@@ -1252,13 +1260,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
}
}
- /* set au0828 interface0 to AS5 here again */
- ret = usb_set_interface(dev->usbdev, 0, 5);
- if (ret < 0) {
- printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
- return -EBUSY;
- }
-
au0828_analog_stream_enable(dev);
return 0;
@@ -1364,9 +1365,11 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
i2c_gate_ctrl(dev, 1);
- /* FIXME: when we support something other than NTSC, we are going to
- have to make the au0828 bridge adjust the size of its capture
- buffer, which is currently hardcoded at 720x480 */
+ /*
+ * FIXME: when we support something other than 60Hz standards,
+ * we are going to have to make the au0828 bridge adjust the size
+ * of its capture buffer, which is currently hardcoded at 720x480
+ */
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, norm);
@@ -1723,6 +1726,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
dev->vid_timeout_running = 0;
del_timer_sync(&dev->vid_timeout);
+ au0828_analog_stream_disable(dev);
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
rc = au0828_stream_interrupt(dev);
if (rc != 0)
@@ -1915,7 +1919,7 @@ static const struct video_device au0828_video_template = {
.fops = &au0828_v4l_fops,
.release = video_device_release,
.ioctl_ops = &video_ioctl_ops,
- .tvnorms = V4L2_STD_NTSC_M,
+ .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
};
/**************************************************************************/
@@ -1928,7 +1932,8 @@ int au0828_analog_register(struct au0828_dev *dev,
struct usb_endpoint_descriptor *endpoint;
int i, ret;
- dprintk(1, "au0828_analog_register called!\n");
+ dprintk(1, "au0828_analog_register called for intf#%d!\n",
+ interface->cur_altsetting->desc.bInterfaceNumber);
/* set au0828 usb interface0 to as5 */
retval = usb_set_interface(dev->usbdev,
@@ -1952,6 +1957,9 @@ int au0828_analog_register(struct au0828_dev *dev,
dev->max_pkt_size = (tmp & 0x07ff) *
(((tmp & 0x1800) >> 11) + 1);
dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
+ dprintk(1,
+ "Found isoc endpoint 0x%02x, max size = %d\n",
+ dev->isoc_in_endpointaddr, dev->max_pkt_size);
}
}
if (!(dev->isoc_in_endpointaddr)) {
@@ -2008,14 +2016,12 @@ int au0828_analog_register(struct au0828_dev *dev,
*dev->vdev = au0828_video_template;
dev->vdev->v4l2_dev = &dev->v4l2_dev;
dev->vdev->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags);
strcpy(dev->vdev->name, "au0828a video");
/* Setup the VBI device */
*dev->vbi_dev = au0828_video_template;
dev->vbi_dev->v4l2_dev = &dev->v4l2_dev;
dev->vbi_dev->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags);
strcpy(dev->vbi_dev->name, "au0828a vbi");
/* Register the v4l2 device */
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 7112b9d956fa..96bec05d7dac 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -88,6 +88,7 @@ struct au0828_board {
unsigned int tuner_type;
unsigned char tuner_addr;
unsigned char i2c_clk_divider;
+ unsigned char has_ir_i2c:1;
struct au0828_input input[AU0828_MAX_INPUT];
};
@@ -213,6 +214,10 @@ struct au0828_dev {
struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler v4l2_ctrl_hdl;
#endif
+#ifdef CONFIG_VIDEO_AU0828_RC
+ struct au0828_rc *ir;
+#endif
+
int users;
unsigned int resources; /* resources in use */
struct video_device *vdev;
@@ -319,3 +324,9 @@ extern struct videobuf_queue_ops au0828_vbi_qops;
do { if (au0828_debug & level)\
printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\
} while (0)
+
+/* au0828-input.c */
+int au0828_rc_register(struct au0828_dev *dev);
+void au0828_rc_unregister(struct au0828_dev *dev);
+int au0828_rc_suspend(struct au0828_dev *dev);
+int au0828_rc_resume(struct au0828_dev *dev);
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index d5d42b6e94be..9caea8344547 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -1169,7 +1169,6 @@ int cpia2_register_camera(struct camera_data *cam)
cam->vdev.lock = &cam->v4l2_lock;
cam->vdev.ctrl_handler = hdl;
cam->vdev.v4l2_dev = &cam->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
reset_camera_struct_v4l(cam);
diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig
index f14c5e89a567..569aa298c03f 100644
--- a/drivers/media/usb/cx231xx/Kconfig
+++ b/drivers/media/usb/cx231xx/Kconfig
@@ -47,6 +47,8 @@ config VIDEO_CX231XX_DVB
select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT
select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI2165 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
---help---
This adds support for DVB cards based on the
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index 30a0c69fb42f..459bb0e98971 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1563,7 +1563,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.width = dev->ts1.width;
f->fmt.pix.height = dev->ts1.height;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- f->fmt.pix.priv = 0;
dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
dev->ts1.width, dev->ts1.height);
dprintk(3, "exit vidioc_g_fmt_vid_cap()\n");
@@ -1582,7 +1581,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.sizeimage = mpeglines * mpeglinesize;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- f->fmt.pix.priv = 0;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
dev->ts1.width, dev->ts1.height);
dprintk(3, "exit vidioc_try_fmt_vid_cap()\n");
@@ -1923,7 +1921,6 @@ static struct video_device *cx231xx_video_dev_alloc(
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->lock = &dev->lock;
vfd->release = video_device_release;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl;
video_set_drvdata(vfd, dev);
if (dev->tuner_type == TUNER_ABSENT) {
diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 89de00bf4f82..a428c10e1a16 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -352,6 +352,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev,
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_CNXT_VIDEO_GRABBER:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
case CX231XX_BOARD_HAUPPAUGE_USBLIVE2:
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 2ee03e4ddd86..8039b769f258 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -704,6 +704,84 @@ struct cx231xx_board cx231xx_boards[] = {
}
},
},
+ [CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx] = {
+ .name = "Hauppauge WinTV 930C-HD (1113xx) / PCTV QuatroStick 521e",
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60,
+ .tuner_gpio = RDE250_XCV_TUNER,
+ .tuner_sif_gpio = 0x05,
+ .tuner_scl_gpio = 0x1a,
+ .tuner_sda_gpio = 0x1b,
+ .decoder = CX231XX_AVDECODER,
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x0c,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 1,
+ .demod_i2c_master = 2,
+ .has_dvb = 1,
+ .demod_addr = 0x0e,
+ .norm = V4L2_STD_PAL,
+
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = NULL,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ } },
+ },
+ [CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx] = {
+ .name = "Hauppauge WinTV 930C-HD (1114xx) / PCTV QuatroStick 522e",
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = 0x60,
+ .tuner_gpio = RDE250_XCV_TUNER,
+ .tuner_sif_gpio = 0x05,
+ .tuner_scl_gpio = 0x1a,
+ .tuner_sda_gpio = 0x1b,
+ .decoder = CX231XX_AVDECODER,
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x0c,
+ .gpio_pin_status_mask = 0x4001000,
+ .tuner_i2c_master = 1,
+ .demod_i2c_master = 2,
+ .has_dvb = 1,
+ .demod_addr = 0x0e,
+ .norm = V4L2_STD_PAL,
+
+ .input = {{
+ .type = CX231XX_VMUX_TELEVISION,
+ .vmux = CX231XX_VIN_3_1,
+ .amux = CX231XX_AMUX_VIDEO,
+ .gpio = NULL,
+ }, {
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_2_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_1_1 |
+ (CX231XX_VIN_1_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ } },
+ },
};
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
@@ -733,10 +811,20 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC},
{USB_DEVICE(0x2040, 0xb120),
.driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
+ {USB_DEVICE(0x2040, 0xb130),
+ .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
+ {USB_DEVICE(0x2040, 0xb131),
+ .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
{USB_DEVICE(0x2040, 0xb140),
.driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER},
{USB_DEVICE(0x2040, 0xc200),
.driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
+ /* PCTV QuatroStick 521e */
+ {USB_DEVICE(0x2013, 0x0259),
+ .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx},
+ /* PCTV QuatroStick 522e */
+ {USB_DEVICE(0x2013, 0x025e),
+ .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx},
{USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
.driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
{USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
@@ -886,6 +974,50 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
}
+static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len)
+{
+ int ret = 0;
+ u8 addr = 0xa0 >> 1;
+ u8 start_offset = 0;
+ int len_todo = len;
+ u8 *eedata_cur = eedata;
+ int i;
+ struct i2c_msg msg_write = { .addr = addr, .flags = 0,
+ .buf = &start_offset, .len = 1 };
+ struct i2c_msg msg_read = { .addr = addr, .flags = I2C_M_RD };
+
+ /* mutex_lock(&dev->i2c_lock); */
+ cx231xx_enable_i2c_port_3(dev, false);
+
+ /* start reading at offset 0 */
+ ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_write, 1);
+ if (ret < 0) {
+ cx231xx_err("Can't read eeprom\n");
+ return ret;
+ }
+
+ while (len_todo > 0) {
+ msg_read.len = (len_todo > 64) ? 64 : len_todo;
+ msg_read.buf = eedata_cur;
+
+ ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_read, 1);
+ if (ret < 0) {
+ cx231xx_err("Can't read eeprom\n");
+ return ret;
+ }
+ eedata_cur += msg_read.len;
+ len_todo -= msg_read.len;
+ }
+
+ cx231xx_enable_i2c_port_3(dev, true);
+ /* mutex_unlock(&dev->i2c_lock); */
+
+ for (i = 0; i + 15 < len; i += 16)
+ cx231xx_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]);
+
+ return 0;
+}
+
void cx231xx_card_setup(struct cx231xx *dev)
{
@@ -917,6 +1049,21 @@ void cx231xx_card_setup(struct cx231xx *dev)
else
cx231xx_config_tuner(dev);
}
+
+ switch (dev->model) {
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
+ {
+ struct tveeprom tvee;
+ static u8 eeprom[256];
+
+ read_eeprom(dev, eeprom, sizeof(eeprom));
+ tveeprom_hauppauge_analog(&dev->i2c_bus[1].i2c_client,
+ &tvee, eeprom + 0xc0);
+ break;
+ }
+ }
+
}
/*
@@ -964,12 +1111,6 @@ void cx231xx_release_resources(struct cx231xx *dev)
/* Mark device as unused */
clear_bit(dev->devno, &cx231xx_devused);
-
- kfree(dev->video_mode.alt_max_pkt_size);
- kfree(dev->vbi_mode.alt_max_pkt_size);
- kfree(dev->sliced_cc_mode.alt_max_pkt_size);
- kfree(dev->ts1_mode.alt_max_pkt_size);
- kfree(dev);
}
/*
@@ -1003,7 +1144,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
dev->cx231xx_gpio_i2c_write = cx231xx_gpio_i2c_write;
/* Query cx231xx to find what pcb config it is related to */
- initialize_cx231xx(dev);
+ retval = initialize_cx231xx(dev);
+ if (retval < 0) {
+ cx231xx_errdev("Failed to read PCB config\n");
+ return retval;
+ }
/*To workaround error number=-71 on EP0 for VideoGrabber,
need set alt here.*/
@@ -1121,6 +1266,117 @@ static void flush_request_modules(struct cx231xx *dev)
#define flush_request_modules(dev)
#endif /* CONFIG_MODULES */
+static int cx231xx_init_v4l2(struct cx231xx *dev,
+ struct usb_device *udev,
+ struct usb_interface *interface,
+ int isoc_pipe)
+{
+ struct usb_interface *uif;
+ int i, idx;
+
+ /* Video Init */
+
+ /* compute alternate max packet sizes for video */
+ idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1;
+ if (idx >= dev->max_iad_interface_count) {
+ cx231xx_errdev("Video PCB interface #%d doesn't exist\n", idx);
+ return -ENODEV;
+ }
+
+ uif = udev->actconfig->interface[idx];
+
+ dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress;
+ dev->video_mode.num_alt = uif->num_altsetting;
+
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->video_mode.end_point_addr,
+ dev->video_mode.num_alt);
+
+ dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL);
+ if (dev->video_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->video_mode.num_alt; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
+ dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->video_mode.alt_max_pkt_size[i]);
+ }
+
+ /* VBI Init */
+
+ idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1;
+ if (idx >= dev->max_iad_interface_count) {
+ cx231xx_errdev("VBI PCB interface #%d doesn't exist\n", idx);
+ return -ENODEV;
+ }
+ uif = udev->actconfig->interface[idx];
+
+ dev->vbi_mode.end_point_addr =
+ uif->altsetting[0].endpoint[isoc_pipe].desc.
+ bEndpointAddress;
+
+ dev->vbi_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->vbi_mode.end_point_addr,
+ dev->vbi_mode.num_alt);
+
+ /* compute alternate max packet sizes for vbi */
+ dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL);
+ if (dev->vbi_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->vbi_mode.num_alt; i++) {
+ u16 tmp =
+ le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+ desc.wMaxPacketSize);
+ dev->vbi_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->vbi_mode.alt_max_pkt_size[i]);
+ }
+
+ /* Sliced CC VBI init */
+
+ /* compute alternate max packet sizes for sliced CC */
+ idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1;
+ if (idx >= dev->max_iad_interface_count) {
+ cx231xx_errdev("Sliced CC PCB interface #%d doesn't exist\n", idx);
+ return -ENODEV;
+ }
+ uif = udev->actconfig->interface[idx];
+
+ dev->sliced_cc_mode.end_point_addr =
+ uif->altsetting[0].endpoint[isoc_pipe].desc.
+ bEndpointAddress;
+
+ dev->sliced_cc_mode.num_alt = uif->num_altsetting;
+ cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
+ dev->sliced_cc_mode.end_point_addr,
+ dev->sliced_cc_mode.num_alt);
+ dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL);
+
+ if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
+ cx231xx_errdev("out of memory!\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
+ u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+ desc.wMaxPacketSize);
+ dev->sliced_cc_mode.alt_max_pkt_size[i] =
+ (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
+ cx231xx_info("Alternate setting %i, max size= %i\n", i,
+ dev->sliced_cc_mode.alt_max_pkt_size[i]);
+ }
+
+ return 0;
+}
+
/*
* cx231xx_usb_probe()
* checks for supported devices
@@ -1135,6 +1391,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
int nr = 0, ifnum;
int i, isoc_pipe = 0;
char *speed;
+ u8 idx;
struct usb_interface_assoc_descriptor *assoc_desc;
ifnum = interface->altsetting[0].desc.bInterfaceNumber;
@@ -1157,16 +1414,16 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
}
} while (test_and_set_bit(nr, &cx231xx_devused));
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
/* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
cx231xx_err(DRIVER_NAME ": out of memory!\n");
clear_bit(nr, &cx231xx_devused);
return -ENOMEM;
}
- udev = usb_get_dev(interface_to_usbdev(interface));
-
snprintf(dev->name, 29, "cx231xx #%d", nr);
dev->devno = nr;
dev->model = id->driver_info;
@@ -1185,8 +1442,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
dev->vbi_or_sliced_cc_mode = 0;
/* get maximum no.of IAD interfaces */
- assoc_desc = udev->actconfig->intf_assoc[0];
- dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
+ dev->max_iad_interface_count = udev->config->desc.bNumInterfaces;
/* init CIR module TBD */
@@ -1238,120 +1494,31 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
/* save our data pointer in this interface device */
usb_set_intfdata(interface, dev);
- /*
- * AV device initialization - only done at the last interface
- */
-
/* Create v4l2 device */
retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
if (retval) {
cx231xx_errdev("v4l2_device_register failed\n");
- retval = -EIO;
goto err_v4l2;
}
+
/* allocate device struct */
retval = cx231xx_init_dev(dev, udev, nr);
if (retval)
goto err_init;
- /* compute alternate max packet sizes for video */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.video_index + 1];
-
- dev->video_mode.end_point_addr = uif->altsetting[0].
- endpoint[isoc_pipe].desc.bEndpointAddress;
-
- dev->video_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->video_mode.end_point_addr,
- dev->video_mode.num_alt);
- dev->video_mode.alt_max_pkt_size =
- kmalloc(32 * dev->video_mode.num_alt, GFP_KERNEL);
-
- if (dev->video_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- retval = -ENOMEM;
- goto err_video_alt;
- }
-
- for (i = 0; i < dev->video_mode.num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->video_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->video_mode.alt_max_pkt_size[i]);
- }
-
- /* compute alternate max packet sizes for vbi */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.
- vanc_index + 1];
-
- dev->vbi_mode.end_point_addr =
- uif->altsetting[0].endpoint[isoc_pipe].desc.
- bEndpointAddress;
-
- dev->vbi_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->vbi_mode.end_point_addr,
- dev->vbi_mode.num_alt);
- dev->vbi_mode.alt_max_pkt_size =
- kmalloc(32 * dev->vbi_mode.num_alt, GFP_KERNEL);
-
- if (dev->vbi_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- retval = -ENOMEM;
- goto err_vbi_alt;
- }
-
- for (i = 0; i < dev->vbi_mode.num_alt; i++) {
- u16 tmp =
- le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->vbi_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->vbi_mode.alt_max_pkt_size[i]);
- }
-
- /* compute alternate max packet sizes for sliced CC */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].interface_info.
- hanc_index + 1];
-
- dev->sliced_cc_mode.end_point_addr =
- uif->altsetting[0].endpoint[isoc_pipe].desc.
- bEndpointAddress;
-
- dev->sliced_cc_mode.num_alt = uif->num_altsetting;
- cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
- dev->sliced_cc_mode.end_point_addr,
- dev->sliced_cc_mode.num_alt);
- dev->sliced_cc_mode.alt_max_pkt_size =
- kmalloc(32 * dev->sliced_cc_mode.num_alt, GFP_KERNEL);
-
- if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
- cx231xx_errdev("out of memory!\n");
- retval = -ENOMEM;
- goto err_sliced_cc_alt;
- }
-
- for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
- u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
- desc.wMaxPacketSize);
- dev->sliced_cc_mode.alt_max_pkt_size[i] =
- (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
- cx231xx_info("Alternate setting %i, max size= %i\n", i,
- dev->sliced_cc_mode.alt_max_pkt_size[i]);
- }
+ retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe);
+ if (retval)
+ goto err_init;
if (dev->current_pcb_config.ts1_source != 0xff) {
/* compute alternate max packet sizes for TS1 */
- uif = udev->actconfig->interface[dev->current_pcb_config.
- hs_config_info[0].
- interface_info.
- ts1_index + 1];
+ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1;
+ if (idx >= dev->max_iad_interface_count) {
+ cx231xx_errdev("TS1 PCB interface #%d doesn't exist\n", idx);
+ retval = -ENODEV;
+ goto err_video_alt;
+ }
+ uif = udev->actconfig->interface[idx];
dev->ts1_mode.end_point_addr =
uif->altsetting[0].endpoint[isoc_pipe].
@@ -1361,13 +1528,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
dev->ts1_mode.end_point_addr,
dev->ts1_mode.num_alt);
- dev->ts1_mode.alt_max_pkt_size =
- kmalloc(32 * dev->ts1_mode.num_alt, GFP_KERNEL);
+ dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL);
if (dev->ts1_mode.alt_max_pkt_size == NULL) {
cx231xx_errdev("out of memory!\n");
retval = -ENOMEM;
- goto err_ts1_alt;
+ goto err_video_alt;
}
for (i = 0; i < dev->ts1_mode.num_alt; i++) {
@@ -1394,12 +1560,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
request_modules(dev);
return 0;
-err_ts1_alt:
- kfree(dev->sliced_cc_mode.alt_max_pkt_size);
-err_sliced_cc_alt:
- kfree(dev->vbi_mode.alt_max_pkt_size);
-err_vbi_alt:
- kfree(dev->video_mode.alt_max_pkt_size);
err_video_alt:
/* cx231xx_uninit_dev: */
cx231xx_close_extension(dev);
@@ -1415,7 +1575,6 @@ err_v4l2:
err_if:
usb_put_dev(udev);
clear_bit(dev->devno, &cx231xx_devused);
- kfree(dev);
return retval;
}
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index 4ba3ce09b713..513194aa6561 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -726,6 +726,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
break;
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
errCode = cx231xx_set_power_mode(dev,
POLARIS_AVMODE_DIGITAL);
break;
@@ -744,6 +745,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
@@ -1379,6 +1381,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
case CX231XX_BOARD_CNXT_RDE_253S:
case CX231XX_BOARD_CNXT_RDU_253S:
case CX231XX_BOARD_HAUPPAUGE_EXETER:
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index 4504bc6a700b..1fa79741d199 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -32,7 +32,9 @@
#include "tda18271.h"
#include "s5h1411.h"
#include "lgdt3305.h"
+#include "si2165.h"
#include "mb86a20s.h"
+#include "si2157.h"
MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
@@ -67,6 +69,7 @@ struct cx231xx_dvb {
struct dmx_frontend fe_hw;
struct dmx_frontend fe_mem;
struct dvb_net net;
+ struct i2c_client *i2c_client_tuner;
};
static struct s5h1432_config dvico_s5h1432_config = {
@@ -151,6 +154,18 @@ static struct tda18271_config pv_tda18271_config = {
.small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
};
+static const struct si2165_config hauppauge_930C_HD_1113xx_si2165_config = {
+ .i2c_addr = 0x64,
+ .chip_mode = SI2165_MODE_PLL_XTAL,
+ .ref_freq_Hz = 16000000,
+};
+
+static const struct si2165_config pctv_quatro_stick_1114xx_si2165_config = {
+ .i2c_addr = 0x64,
+ .chip_mode = SI2165_MODE_PLL_EXT,
+ .ref_freq_Hz = 24000000,
+};
+
static inline void print_err_status(struct cx231xx *dev, int packet, int status)
{
char *errmsg = "Unknown";
@@ -549,11 +564,18 @@ fail_adapter:
static void unregister_dvb(struct cx231xx_dvb *dvb)
{
+ struct i2c_client *client;
dvb_net_release(&dvb->net);
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
dvb_dmxdev_release(&dvb->dmxdev);
dvb_dmx_release(&dvb->demux);
+ client = dvb->i2c_client_tuner;
+ /* remove I2C tuner */
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
dvb_unregister_frontend(dvb->frontend);
dvb_frontend_detach(dvb->frontend);
dvb_unregister_adapter(&dvb->adapter);
@@ -704,6 +726,89 @@ static int dvb_init(struct cx231xx *dev)
&hcw_tda18271_config);
break;
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
+
+ dev->dvb->frontend = dvb_attach(si2165_attach,
+ &hauppauge_930C_HD_1113xx_si2165_config,
+ &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap
+ );
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach SI2165 front end\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ dev->dvb->frontend->ops.i2c_gate_ctrl = 0;
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ dvb_attach(tda18271_attach, dev->dvb->frontend,
+ 0x60,
+ &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
+ &hcw_tda18271_config);
+
+ dev->cx231xx_reset_analog_tuner = NULL;
+ break;
+
+ case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
+ {
+ struct i2c_client *client;
+ struct i2c_board_info info;
+ struct si2157_config si2157_config;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+
+ dev->dvb->frontend = dvb_attach(si2165_attach,
+ &pctv_quatro_stick_1114xx_si2165_config,
+ &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap
+ );
+
+ if (dev->dvb->frontend == NULL) {
+ printk(DRIVER_NAME
+ ": Failed to attach SI2165 front end\n");
+ result = -EINVAL;
+ goto out_free;
+ }
+
+ dev->dvb->frontend->ops.i2c_gate_ctrl = 0;
+
+ /* define general-purpose callback pointer */
+ dvb->frontend->callback = cx231xx_tuner_callback;
+
+ /* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
+ si2157_config.fe = dev->dvb->frontend;
+ si2157_config.inversion = true;
+ strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &si2157_config;
+ request_module("si2157");
+
+ client = i2c_new_device(
+ &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap,
+ &info);
+ if (client == NULL || client->dev.driver == NULL) {
+ dvb_frontend_detach(dev->dvb->frontend);
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ if (!try_module_get(client->dev.driver->owner)) {
+ i2c_unregister_device(client);
+ dvb_frontend_detach(dev->dvb->frontend);
+ result = -ENODEV;
+ goto out_free;
+ }
+
+ dev->cx231xx_reset_analog_tuner = NULL;
+
+ dev->dvb->i2c_client_tuner = client;
+ break;
+ }
+
case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 46d52fac8680..05f0434919d4 100644
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
@@ -21,11 +21,12 @@
#include "cx231xx.h"
#include <linux/usb.h>
#include <linux/slab.h>
+#include <linux/bitrev.h>
#define MODULE_NAME "cx231xx-input"
-static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key,
- u32 *ir_raw)
+static int get_key_isdbt(struct IR_i2c *ir, enum rc_type *protocol,
+ u32 *pscancode, u8 *toggle)
{
int rc;
u8 cmd, scancode;
@@ -46,21 +47,14 @@ static int get_key_isdbt(struct IR_i2c *ir, u32 *ir_key,
if (cmd == 0xff)
return 0;
- scancode =
- ((cmd & 0x01) ? 0x80 : 0) |
- ((cmd & 0x02) ? 0x40 : 0) |
- ((cmd & 0x04) ? 0x20 : 0) |
- ((cmd & 0x08) ? 0x10 : 0) |
- ((cmd & 0x10) ? 0x08 : 0) |
- ((cmd & 0x20) ? 0x04 : 0) |
- ((cmd & 0x40) ? 0x02 : 0) |
- ((cmd & 0x80) ? 0x01 : 0);
+ scancode = bitrev8(cmd);
dev_dbg(&ir->rc->input_dev->dev, "cmd %02x, scan = %02x\n",
cmd, scancode);
- *ir_key = scancode;
- *ir_raw = scancode;
+ *protocol = RC_TYPE_OTHER;
+ *pscancode = scancode;
+ *toggle = 0;
return 1;
}
@@ -97,7 +91,7 @@ int cx231xx_ir_init(struct cx231xx *dev)
dev->init_data.get_key = get_key_isdbt;
dev->init_data.ir_codes = cx231xx_boards[dev->model].rc_map_name;
/* The i2c micro-controller only outputs the cmd part of NEC protocol */
- dev->init_data.rc_dev->scanmask = 0xff;
+ dev->init_data.rc_dev->scancode_mask = 0xff;
dev->init_data.rc_dev->driver_name = "cx231xx";
dev->init_data.type = RC_BIT_NEC;
info.addr = 0x30;
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c
index 2a34ceee4802..3052c4c20229 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c
@@ -654,8 +654,9 @@ static struct pcb_config cx231xx_Scenario[] = {
/*****************************************************************/
-u32 initialize_cx231xx(struct cx231xx *dev)
+int initialize_cx231xx(struct cx231xx *dev)
{
+ int retval;
u32 config_info = 0;
struct pcb_config *p_pcb_info;
u8 usb_speed = 1; /* from register,1--HS, 0--FS */
@@ -670,7 +671,10 @@ u32 initialize_cx231xx(struct cx231xx *dev)
/* read board config register to find out which
pcb config it is related to */
- cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, data, 4);
+ retval = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
+ data, 4);
+ if (retval < 0)
+ return retval;
config_info = le32_to_cpu(*((__le32 *)data));
usb_speed = (u8) (config_info & 0x1);
@@ -767,7 +771,7 @@ u32 initialize_cx231xx(struct cx231xx *dev)
cx231xx_info("bad senario!!!!!\n");
cx231xx_info("config_info=%x\n",
(config_info & SELFPOWER_MASK));
- return 1;
+ return -ENODEV;
}
}
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index b3c6190e0c69..4511dc5d199c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
@@ -221,6 +221,6 @@ enum INDEX_PCB_CONFIG{
/***************************************************************************/
struct cx231xx;
-u32 initialize_cx231xx(struct cx231xx *p_dev);
+int initialize_cx231xx(struct cx231xx *p_dev);
#endif
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 1f8751379e24..3b3ada6562ca 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -208,7 +208,7 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q,
static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
{
struct cx231xx_dmaqueue *dma_q = urb->context;
- int i, rc = 1;
+ int i;
unsigned char *p_buffer;
u32 bytes_parsed = 0, buffer_size = 0;
u8 sav_eav = 0;
@@ -299,13 +299,12 @@ static inline int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb)
bytes_parsed = 0;
}
- return rc;
+ return 1;
}
static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
{
struct cx231xx_dmaqueue *dma_q = urb->context;
- int rc = 1;
unsigned char *p_buffer;
u32 bytes_parsed = 0, buffer_size = 0;
u8 sav_eav = 0;
@@ -379,7 +378,7 @@ static inline int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb)
bytes_parsed = 0;
}
- return rc;
+ return 1;
}
@@ -886,7 +885,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -931,7 +929,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1620,7 +1617,7 @@ static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner
*/
static int cx231xx_v4l2_open(struct file *filp)
{
- int errCode = 0, radio = 0;
+ int radio = 0;
struct video_device *vdev = video_devdata(filp);
struct cx231xx *dev = video_drvdata(filp);
struct cx231xx_fh *fh;
@@ -1718,7 +1715,7 @@ static int cx231xx_v4l2_open(struct file *filp)
mutex_unlock(&dev->lock);
v4l2_fh_add(&fh->fh);
- return errCode;
+ return 0;
}
/*
@@ -2066,7 +2063,6 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev,
vfd->release = video_device_release;
vfd->debug = video_debug;
vfd->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index babca7fb85e2..aeb1bf42b88d 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -73,6 +73,8 @@
#define CX231XX_BOARD_ELGATO_VIDEO_CAPTURE_V2 16
#define CX231XX_BOARD_OTG102 17
#define CX231XX_BOARD_KWORLD_UB445_USB_HYBRID 18
+#define CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx 19
+#define CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx 20
/* Limits minimum and default number of buffers */
#define CX231XX_MIN_BUF 4
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 037e519bbaa2..66645b02c854 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -129,6 +129,7 @@ config DVB_USB_RTL28XXU
depends on DVB_USB_V2 && I2C_MUX
select DVB_RTL2830
select DVB_RTL2832
+ select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
index da47d2392f2a..5ca738ab44e0 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -1213,7 +1213,7 @@ static int af9015_rc_query(struct dvb_usb_device *d)
if ((state->rc_repeat != buf[6] || buf[0]) &&
!memcmp(&buf[12], state->rc_last, 4)) {
dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__);
- rc_keydown(d->rc_dev, state->rc_keycode, 0);
+ rc_repeat(d->rc_dev);
state->rc_repeat = buf[6];
return ret;
}
@@ -1233,18 +1233,22 @@ static int af9015_rc_query(struct dvb_usb_device *d)
if (buf[14] == (u8) ~buf[15]) {
if (buf[12] == (u8) ~buf[13]) {
/* NEC */
- state->rc_keycode = buf[12] << 8 | buf[14];
+ state->rc_keycode = RC_SCANCODE_NEC(buf[12],
+ buf[14]);
} else {
/* NEC extended*/
- state->rc_keycode = buf[12] << 16 |
- buf[13] << 8 | buf[14];
+ state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 |
+ buf[13],
+ buf[14]);
}
} else {
/* 32 bit NEC */
- state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
- buf[14] << 8 | buf[15];
+ state->rc_keycode = RC_SCANCODE_NEC32(buf[12] << 24 |
+ buf[13] << 16 |
+ buf[14] << 8 |
+ buf[15]);
}
- rc_keydown(d->rc_dev, state->rc_keycode, 0);
+ rc_keydown(d->rc_dev, RC_TYPE_NEC, state->rc_keycode, 0);
} else {
dev_dbg(&d->udev->dev, "%s: no key press\n", __func__);
/* Invalidate last keypress */
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 021e4d35e4d7..75ec1c659fdd 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -704,15 +704,41 @@ static int af9035_read_config(struct dvb_usb_device *d)
if (ret < 0)
goto err;
- if (tmp == 0x00)
- dev_dbg(&d->udev->dev,
- "%s: [%d]tuner not set, using default\n",
- __func__, i);
- else
+ dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
+ __func__, i, tmp);
+
+ /* tuner sanity check */
+ if (state->chip_type == 0x9135) {
+ if (state->chip_version == 0x02) {
+ /* IT9135 BX (v2) */
+ switch (tmp) {
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ state->af9033_config[i].tuner = tmp;
+ break;
+ }
+ } else {
+ /* IT9135 AX (v1) */
+ switch (tmp) {
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ state->af9033_config[i].tuner = tmp;
+ break;
+ }
+ }
+ } else {
+ /* AF9035 */
state->af9033_config[i].tuner = tmp;
+ }
- dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
- __func__, i, state->af9033_config[i].tuner);
+ if (state->af9033_config[i].tuner != tmp) {
+ dev_info(&d->udev->dev,
+ "%s: [%d] overriding tuner from %02x to %02x\n",
+ KBUILD_MODNAME, i, tmp,
+ state->af9033_config[i].tuner);
+ }
switch (state->af9033_config[i].tuner) {
case AF9033_TUNER_TUA9001:
@@ -773,6 +799,25 @@ static int af9035_read_config(struct dvb_usb_device *d)
addr += 0x10; /* shift for the 2nd tuner params */
}
+ /*
+ * These AVerMedia devices has a bad EEPROM content :-(
+ * Override some wrong values here.
+ */
+ if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA) {
+ switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
+ case USB_PID_AVERMEDIA_A835B_1835:
+ case USB_PID_AVERMEDIA_A835B_2835:
+ case USB_PID_AVERMEDIA_A835B_3835:
+ dev_info(&d->udev->dev,
+ "%s: overriding tuner from %02x to %02x\n",
+ KBUILD_MODNAME, state->af9033_config[0].tuner,
+ AF9033_TUNER_IT9135_60);
+
+ state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60;
+ break;
+ }
+ }
+
skip_eeprom:
/* get demod clock */
ret = af9035_rd_reg(d, 0x00d800, &tmp);
@@ -1287,19 +1332,20 @@ static int af9035_rc_query(struct dvb_usb_device *d)
if ((buf[2] + buf[3]) == 0xff) {
if ((buf[0] + buf[1]) == 0xff) {
/* NEC standard 16bit */
- key = buf[0] << 8 | buf[2];
+ key = RC_SCANCODE_NEC(buf[0], buf[2]);
} else {
/* NEC extended 24bit */
- key = buf[0] << 16 | buf[1] << 8 | buf[2];
+ key = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]);
}
} else {
/* NEC full code 32bit */
- key = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
+ key = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 |
+ buf[2] << 8 | buf[3]);
}
dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 4, buf);
- rc_keydown(d->rc_dev, key, 0);
+ rc_keydown(d->rc_dev, RC_TYPE_NEC, key, 0);
return 0;
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index eeab79bdd2aa..e4a2382196f0 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -1038,7 +1038,8 @@ static int anysee_rc_query(struct dvb_usb_device *d)
if (ircode[0]) {
dev_dbg(&d->udev->dev, "%s: key pressed %02x\n", __func__,
ircode[1]);
- rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
+ rc_keydown(d->rc_dev, RC_TYPE_NEC,
+ RC_SCANCODE_NEC(0x08, ircode[1]), 0);
}
return 0;
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index c3c4b98733bf..935dbaa80ef0 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -207,24 +207,27 @@ static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
static int az6007_rc_query(struct dvb_usb_device *d)
{
struct az6007_device_state *st = d_to_priv(d);
- unsigned code = 0;
+ unsigned code;
az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
if (st->data[1] == 0x44)
return 0;
- if ((st->data[1] ^ st->data[2]) == 0xff)
- code = st->data[1];
- else
- code = st->data[1] << 8 | st->data[2];
-
- if ((st->data[3] ^ st->data[4]) == 0xff)
- code = code << 8 | st->data[3];
- else
- code = code << 16 | st->data[3] << 8 | st->data[4];
+ if ((st->data[3] ^ st->data[4]) == 0xff) {
+ if ((st->data[1] ^ st->data[2]) == 0xff)
+ code = RC_SCANCODE_NEC(st->data[1], st->data[3]);
+ else
+ code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2],
+ st->data[3]);
+ } else {
+ code = RC_SCANCODE_NEC32(st->data[1] << 24 |
+ st->data[2] << 16 |
+ st->data[3] << 8 |
+ st->data[4]);
+ }
- rc_keydown(d->rc_dev, code, st->data[5]);
+ rc_keydown(d->rc_dev, RC_TYPE_NEC, code, st->data[5]);
return 0;
}
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index e35580618936..2e90310be2af 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -164,7 +164,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
dev->driver_name = (char *) d->props->driver_name;
dev->map_name = d->rc.map_name;
dev->driver_type = d->rc.driver_type;
- rc_set_allowed_protocols(dev, d->rc.allowed_protos);
+ dev->allowed_protocols = d->rc.allowed_protos;
dev->change_protocol = d->rc.change_protocol;
dev->priv = d;
@@ -253,13 +253,6 @@ static int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
return usb_urb_exitv2(&adap->stream);
}
-static int wait_schedule(void *ptr)
-{
- schedule();
-
- return 0;
-}
-
static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
@@ -273,8 +266,7 @@ static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
dvbdmxfeed->pid, dvbdmxfeed->index);
/* wait init is done */
- wait_on_bit(&adap->state_bits, ADAP_INIT, wait_schedule,
- TASK_UNINTERRUPTIBLE);
+ wait_on_bit(&adap->state_bits, ADAP_INIT, TASK_UNINTERRUPTIBLE);
if (adap->active_fe == -1)
return -EINVAL;
@@ -568,7 +560,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
if (!adap->suspend_resume_active) {
set_bit(ADAP_SLEEP, &adap->state_bits);
- wait_on_bit(&adap->state_bits, ADAP_STREAMING, wait_schedule,
+ wait_on_bit(&adap->state_bits, ADAP_STREAMING,
TASK_UNINTERRUPTIBLE);
}
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index f674dc024d06..e332af731187 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -125,14 +125,13 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define TUNER_RS2000 0x4
struct lme2510_state {
+ unsigned long int_urb_due;
u8 id;
u8 tuner_config;
u8 signal_lock;
u8 signal_level;
u8 signal_sn;
u8 time_key;
- u8 last_key;
- u8 key_timeout;
u8 i2c_talk_onoff;
u8 i2c_gate;
u8 i2c_tuner_gate_w;
@@ -287,14 +286,13 @@ static void lme2510_int_response(struct urb *lme_urb)
case 0xaa:
debug_data_snipet(1, "INT Remote data snipet", ibuf);
if ((ibuf[4] + ibuf[5]) == 0xff) {
- key = ibuf[5];
- key += (ibuf[3] > 0)
- ? (ibuf[3] ^ 0xff) << 8 : 0;
- key += (ibuf[2] ^ 0xff) << 16;
+ key = RC_SCANCODE_NECX((ibuf[2] ^ 0xff) << 8 |
+ (ibuf[3] > 0) ? (ibuf[3] ^ 0xff) : 0,
+ ibuf[5]);
deb_info(1, "INT Key =%08x", key);
if (adap_to_d(adap)->rc_dev != NULL)
rc_keydown(adap_to_d(adap)->rc_dev,
- key, 0);
+ RC_TYPE_NEC, key, 0);
}
break;
case 0xbb:
@@ -323,7 +321,7 @@ static void lme2510_int_response(struct urb *lme_urb)
}
break;
case TUNER_RS2000:
- if (ibuf[1] == 0x3 && ibuf[6] == 0xff)
+ if (ibuf[2] & 0x1)
st->signal_lock = 0xff;
else
st->signal_lock = 0x00;
@@ -343,7 +341,12 @@ static void lme2510_int_response(struct urb *lme_urb)
break;
}
}
+
usb_submit_urb(lme_urb, GFP_ATOMIC);
+
+ /* interrupt urb is due every 48 msecs while streaming
+ * add 12msecs for system lag */
+ st->int_urb_due = jiffies + msecs_to_jiffies(60);
}
static int lme2510_int_read(struct dvb_usb_adapter *adap)
@@ -584,14 +587,13 @@ static int lme2510_msg(struct dvb_usb_device *d,
switch (wbuf[3]) {
case 0x8c:
rbuf[0] = 0x55;
- rbuf[1] = 0xff;
- if (st->last_key == st->time_key) {
- st->key_timeout++;
- if (st->key_timeout > 5)
- rbuf[1] = 0;
- } else
- st->key_timeout = 0;
- st->last_key = st->time_key;
+ rbuf[1] = st->signal_lock;
+
+ /* If int_urb_due overdue
+ * set rbuf[1] to 0 to clear lock */
+ if (time_after(jiffies, st->int_urb_due))
+ rbuf[1] = 0;
+
break;
default:
lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index c7304fa8ab73..b8a707e57b99 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -129,7 +129,7 @@ int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
u8 addr, u8 mask, u8 data)
{
int ret;
- u8 val;
+ u8 val = 0;
if (mask != 0xff) {
ret = mxl111sf_read_reg(state, addr, &val);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index a676e4452847..27b1e0397e71 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1287,19 +1287,19 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d)
if (buf[2] == (u8) ~buf[3]) {
if (buf[0] == (u8) ~buf[1]) {
/* NEC standard (16 bit) */
- rc_code = buf[0] << 8 | buf[2];
+ rc_code = RC_SCANCODE_NEC(buf[0], buf[2]);
} else {
/* NEC extended (24 bit) */
- rc_code = buf[0] << 16 |
- buf[1] << 8 | buf[2];
+ rc_code = RC_SCANCODE_NECX(buf[0] << 8 | buf[1],
+ buf[2]);
}
} else {
/* NEC full (32 bit) */
- rc_code = buf[0] << 24 | buf[1] << 16 |
- buf[2] << 8 | buf[3];
+ rc_code = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 |
+ buf[2] << 8 | buf[3]);
}
- rc_keydown(d->rc_dev, rc_code, 0);
+ rc_keydown(d->rc_dev, RC_TYPE_NEC, rc_code, 0);
ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
if (ret)
@@ -1541,6 +1541,8 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
&rtl2832u_props, "Peak DVB-T USB", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20_RTL2832U,
&rtl2832u_props, "Sveon STV20", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV21,
+ &rtl2832u_props, "Sveon STV21", NULL) },
{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV27,
&rtl2832u_props, "Sveon STV27", NULL) },
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index c5d95662e2e1..10aef2188fbe 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -117,10 +117,12 @@ config DVB_USB_CXUSB
select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
select DVB_ATBM8830 if MEDIA_SUBDRV_AUTOSELECT
select DVB_LGS8GXX if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MAX2165 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -128,6 +130,7 @@ config DVB_USB_CXUSB
Medion MD95700 hybrid USB2.0 device.
DViCO FusionHDTV (Bluebird) USB2.0 devices
+ TechnoTrend TVStick CT2-4400
config DVB_USB_M920X
tristate "Uli m920x DVB-T USB2.0 support"
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index a1c641e18362..16bc579d1404 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -42,9 +42,11 @@
#include "dib0070.h"
#include "lgs8gxx.h"
#include "atbm8830.h"
+#include "si2168.h"
+#include "si2157.h"
/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE 64
+#define MAX_XFER_SIZE 80
/* debug */
static int dvb_usb_cxusb_debug;
@@ -144,6 +146,22 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
}
}
+static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff)
+{
+ u8 o[2], i;
+ int rc;
+
+ o[0] = 0x83;
+ o[1] = onoff;
+ rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
+
+ if (rc) {
+ deb_info("gpio_write failed.\n");
+ return -EIO;
+ }
+ return 0;
+}
+
/* I2C */
static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
@@ -505,6 +523,30 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
return 0;
}
+static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d)
+{
+ u8 i[2];
+ int ret;
+ u32 cmd, keycode;
+ u8 rc5_cmd, rc5_addr, rc5_toggle;
+
+ ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2);
+ if (ret)
+ return ret;
+
+ cmd = (i[0] << 8) | i[1];
+
+ if (cmd != 0xffff) {
+ rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */
+ rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */
+ rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */
+ keycode = (rc5_addr << 8) | rc5_cmd;
+ rc_keydown(d->rc_dev, RC_BIT_RC5, keycode, rc5_toggle);
+ }
+
+ return 0;
+}
+
static struct rc_map_table rc_map_dvico_mce_table[] = {
{ 0xfe02, KEY_TV },
{ 0xfe0e, KEY_MP3 },
@@ -1070,8 +1112,15 @@ static struct dib7000p_config cxusb_dualdig4_rev2_config = {
.hostbus_diversity = 1,
};
+struct dib0700_adapter_state {
+ int (*set_param_save)(struct dvb_frontend *);
+ struct dib7000p_ops dib7000p_ops;
+};
+
static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
err("set interface failed");
@@ -1079,14 +1128,17 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &cxusb_dualdig4_rev2_config) < 0) {
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &cxusb_dualdig4_rev2_config) < 0) {
printk(KERN_WARNING "Unable to enumerate dib7000p\n");
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
- &cxusb_dualdig4_rev2_config);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
+ &cxusb_dualdig4_rev2_config);
if (adap->fe_adap[0].fe == NULL)
return -EIO;
@@ -1095,7 +1147,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
{
- return dib7000p_set_gpio(fe, 8, 0, !onoff);
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
}
static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
@@ -1110,10 +1165,6 @@ static struct dib0070_config dib7070p_dib0070_config = {
.clock_khz = 12000,
};
-struct dib0700_adapter_state {
- int (*set_param_save) (struct dvb_frontend *);
-};
-
static int dib7070_set_param_override(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
@@ -1128,7 +1179,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe)
case BAND_UHF: offset = 550; break;
}
- dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+ state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
return state->set_param_save(fe);
}
@@ -1136,8 +1187,14 @@ static int dib7070_set_param_override(struct dvb_frontend *fe)
static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c =
- dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+ struct i2c_adapter *tun_i2c;
+
+ /*
+ * No need to call dvb7000p_attach here, as it was called
+ * already, as frontend_attach method is called first, and
+ * tuner_attach is only called on sucess.
+ */
+ tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
@@ -1286,6 +1343,74 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
return 0;
}
+static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap->dev;
+ struct cxusb_state *st = d->priv;
+ struct i2c_adapter *adapter;
+ struct i2c_client *client_demod;
+ struct i2c_client *client_tuner;
+ struct i2c_board_info info;
+ struct si2168_config si2168_config;
+ struct si2157_config si2157_config;
+
+ /* reset the tuner */
+ if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) {
+ err("clear tuner gpio failed");
+ return -EIO;
+ }
+ msleep(100);
+ if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) {
+ err("set tuner gpio failed");
+ return -EIO;
+ }
+ msleep(100);
+
+ /* attach frontend */
+ si2168_config.i2c_adapter = &adapter;
+ si2168_config.fe = &adap->fe_adap[0].fe;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2168", I2C_NAME_SIZE);
+ info.addr = 0x64;
+ info.platform_data = &si2168_config;
+ request_module(info.type);
+ client_demod = i2c_new_device(&d->i2c_adap, &info);
+ if (client_demod == NULL || client_demod->dev.driver == NULL)
+ return -ENODEV;
+
+ if (!try_module_get(client_demod->dev.driver->owner)) {
+ i2c_unregister_device(client_demod);
+ return -ENODEV;
+ }
+
+ st->i2c_client_demod = client_demod;
+
+ /* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
+ si2157_config.fe = adap->fe_adap[0].fe;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2157", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &si2157_config;
+ request_module(info.type);
+ client_tuner = i2c_new_device(adapter, &info);
+ if (client_tuner == NULL || client_tuner->dev.driver == NULL) {
+ module_put(client_demod->dev.driver->owner);
+ i2c_unregister_device(client_demod);
+ return -ENODEV;
+ }
+ if (!try_module_get(client_tuner->dev.driver->owner)) {
+ i2c_unregister_device(client_tuner);
+ module_put(client_demod->dev.driver->owner);
+ i2c_unregister_device(client_demod);
+ return -ENODEV;
+ }
+
+ st->i2c_client_tuner = client_tuner;
+
+ return 0;
+}
+
/*
* DViCO has shipped two devices with the same USB ID, but only one of them
* needs a firmware download. Check the device class details to see if they
@@ -1367,6 +1492,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
+static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties;
static int cxusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -1397,12 +1523,37 @@ static int cxusb_probe(struct usb_interface *intf,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
THIS_MODULE, NULL, adapter_nr) ||
+ 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties,
+ THIS_MODULE, NULL, adapter_nr) ||
0)
return 0;
return -EINVAL;
}
+static void cxusb_disconnect(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ struct cxusb_state *st = d->priv;
+ struct i2c_client *client;
+
+ /* remove I2C client for tuner */
+ client = st->i2c_client_tuner;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ /* remove I2C client for demodulator */
+ client = st->i2c_client_demod;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ dvb_usb_device_exit(intf);
+}
+
static struct usb_device_id cxusb_table [] = {
{ USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
@@ -1424,6 +1575,7 @@ static struct usb_device_id cxusb_table [] = {
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
{ USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
+ { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -2070,10 +2222,63 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
}
};
+static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .num_frontends = 1,
+ .fe = {{
+ .streaming_ctrl = cxusb_streaming_ctrl,
+ /* both frontend and tuner attached in the
+ same function */
+ .frontend_attach = cxusb_tt_ct2_4400_attach,
+
+ /* parameter for the MPEG2-data transfer */
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+ } },
+ },
+ },
+
+ .i2c_algo = &cxusb_i2c_algo,
+ .generic_bulk_ctrl_endpoint = 0x01,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+
+ .rc.core = {
+ .rc_codes = RC_MAP_TT_1500,
+ .allowed_protos = RC_BIT_RC5,
+ .rc_query = cxusb_tt_ct2_4400_rc_query,
+ .rc_interval = 150,
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ "TechnoTrend TVStick CT2-4400",
+ { NULL },
+ { &cxusb_table[20], NULL },
+ },
+ }
+};
+
static struct usb_driver cxusb_driver = {
.name = "dvb_usb_cxusb",
.probe = cxusb_probe,
- .disconnect = dvb_usb_device_exit,
+ .disconnect = cxusb_disconnect,
.id_table = cxusb_table,
};
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
index 1a51eafd31b9..527ff7905e15 100644
--- a/drivers/media/usb/dvb-usb/cxusb.h
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -30,6 +30,8 @@
struct cxusb_state {
u8 gpio_write_state[3];
+ struct i2c_client *i2c_client_demod;
+ struct i2c_client *i2c_client_tuner;
};
#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index c14285fa8271..50856dbf5496 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -658,13 +658,8 @@ out:
struct dib0700_rc_response {
u8 report_id;
u8 data_state;
- union {
- u16 system16;
- struct {
- u8 not_system;
- u8 system;
- };
- };
+ u8 system;
+ u8 not_system;
u8 data;
u8 not_data;
};
@@ -674,6 +669,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
{
struct dvb_usb_device *d = purb->context;
struct dib0700_rc_response *poll_reply;
+ enum rc_type protocol;
u32 uninitialized_var(keycode);
u8 toggle;
@@ -707,44 +703,55 @@ static void dib0700_rc_urb_completion(struct urb *purb)
switch (d->props.rc.core.protocol) {
case RC_BIT_NEC:
+ protocol = RC_TYPE_NEC;
toggle = 0;
/* NEC protocol sends repeat code as 0 0 0 FF */
- if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
- && (poll_reply->not_data == 0xff)) {
+ if (poll_reply->system == 0x00 &&
+ poll_reply->not_system == 0x00 &&
+ poll_reply->data == 0x00 &&
+ poll_reply->not_data == 0xff) {
poll_reply->data_state = 2;
break;
}
- if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
+ if ((poll_reply->data ^ poll_reply->not_data) != 0xff) {
+ deb_data("NEC32 protocol\n");
+ keycode = RC_SCANCODE_NEC32(poll_reply->system << 24 |
+ poll_reply->not_system << 16 |
+ poll_reply->data << 8 |
+ poll_reply->not_data);
+ } else if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
deb_data("NEC extended protocol\n");
- /* NEC extended code - 24 bits */
- keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
+ keycode = RC_SCANCODE_NECX(poll_reply->system << 8 |
+ poll_reply->not_system,
+ poll_reply->data);
+
} else {
deb_data("NEC normal protocol\n");
- /* normal NEC code - 16 bits */
- keycode = poll_reply->system << 8 | poll_reply->data;
+ keycode = RC_SCANCODE_NEC(poll_reply->system,
+ poll_reply->data);
}
break;
default:
deb_data("RC5 protocol\n");
- /* RC5 Protocol */
+ protocol = RC_TYPE_RC5;
toggle = poll_reply->report_id;
- keycode = poll_reply->system << 8 | poll_reply->data;
+ keycode = RC_SCANCODE_RC5(poll_reply->system, poll_reply->data);
break;
}
if ((poll_reply->data + poll_reply->not_data) != 0xff) {
/* Key failed integrity check */
- err("key failed integrity check: %04x %02x %02x",
- poll_reply->system,
+ err("key failed integrity check: %02x %02x %02x %02x",
+ poll_reply->system, poll_reply->not_system,
poll_reply->data, poll_reply->not_data);
goto resubmit;
}
- rc_keydown(d->rc_dev, keycode, toggle);
+ rc_keydown(d->rc_dev, protocol, keycode, toggle);
resubmit:
/* Clean the buffer before we requeue */
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 10e0db8d1850..ce47d3f1c850 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -32,6 +32,8 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif
struct dib0700_adapter_state {
int (*set_param_save) (struct dvb_frontend *);
const struct firmware *frontend_firmware;
+ struct dib7000p_ops dib7000p_ops;
+ struct dib8000_ops dib8000_ops;
};
/* Hauppauge Nova-T 500 (aka Bristol)
@@ -262,6 +264,11 @@ static struct mt2266_config stk7700d_mt2266_config[2] = {
static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
if (adap->id == 0) {
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(10);
@@ -272,16 +279,16 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
stk7700d_dib7000p_mt2266_config)
!= 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
}
- adap->fe_adap[0].fe =
- dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
0x80 + (adap->id << 1),
&stk7700d_dib7000p_mt2266_config[adap->id]);
@@ -290,6 +297,11 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
if (adap->id == 0) {
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(10);
@@ -301,16 +313,16 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
stk7700d_dib7000p_mt2266_config)
!= 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
}
- adap->fe_adap[0].fe =
- dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
0x80 + (adap->id << 1),
&stk7700d_dib7000p_mt2266_config[adap->id]);
@@ -320,7 +332,10 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
{
struct i2c_adapter *tun_i2c;
- tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+ struct dib0700_adapter_state *state = adap->priv;
+
+ tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
+ DIBX000_I2C_INTERFACE_TUNER, 1);
return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
}
@@ -397,12 +412,14 @@ static int stk7700ph_xc3028_callback(void *ptr, int component,
int command, int arg)
{
struct dvb_usb_adapter *adap = ptr;
+ struct dib0700_adapter_state *state = adap->priv;
switch (command) {
case XC2028_TUNER_RESET:
/* Send the tuner in then out of reset */
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
+ msleep(10);
+ state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
break;
case XC2028_RESET_CLK:
break;
@@ -428,12 +445,16 @@ static struct xc2028_config stk7700ph_xc3028_config = {
static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
{
struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
- dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
else
- dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(20);
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
@@ -445,14 +466,15 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
msleep(10);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
&stk7700ph_dib7700_xc3028_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
&stk7700ph_dib7700_xc3028_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -461,8 +483,9 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
{
struct i2c_adapter *tun_i2c;
+ struct dib0700_adapter_state *state = adap->priv;
- tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+ tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
stk7700ph_xc3028_config.i2c_adap = tun_i2c;
@@ -489,7 +512,8 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
{
u8 key[4];
- u32 keycode;
+ enum rc_type protocol;
+ u32 scancode;
u8 toggle;
int i;
struct dib0700_state *st = d->priv;
@@ -516,28 +540,29 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */
- d->last_event = 0;
switch (d->props.rc.core.protocol) {
case RC_BIT_NEC:
/* NEC protocol sends repeat code as 0 0 0 FF */
if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
- (key[3] == 0xff))
- keycode = d->last_event;
- else {
- keycode = key[3-2] << 8 | key[3-3];
- d->last_event = keycode;
+ (key[3] == 0xff)) {
+ rc_repeat(d->rc_dev);
+ return 0;
}
- rc_keydown(d->rc_dev, keycode, 0);
+ protocol = RC_TYPE_NEC;
+ scancode = RC_SCANCODE_NEC(key[3-2], key[3-3]);
+ toggle = 0;
break;
+
default:
/* RC-5 protocol changes toggle bit on new keypress */
- keycode = key[3-2] << 8 | key[3-3];
+ protocol = RC_TYPE_RC5;
+ scancode = RC_SCANCODE_RC5(key[3-2], key[3-3]);
toggle = key[3-1];
- rc_keydown(d->rc_dev, keycode, toggle);
-
break;
}
+
+ rc_keydown(d->rc_dev, protocol, scancode, toggle);
return 0;
}
@@ -673,6 +698,11 @@ static struct dib7000p_config stk7700p_dib7000p_config = {
static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
/* unless there is no real power management in DVB - we leave the device on GPIO6 */
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
@@ -689,11 +719,13 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
st->mt2060_if1[0] = 1220;
- if (dib7000pc_detection(&adap->dev->i2c_adap)) {
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
+ if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap)) {
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
st->is_dib7000pc = 1;
- } else
+ } else {
+ memset(&state->dib7000p_ops, 0, sizeof(state->dib7000p_ops));
adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
+ }
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -707,14 +739,16 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
struct dib0700_state *st = adap->dev->priv;
struct i2c_adapter *tun_i2c;
+ struct dib0700_adapter_state *state = adap->priv;
s8 a;
int if1=1220;
+
if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
}
if (st->is_dib7000pc)
- tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+ tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
else
tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
@@ -767,14 +801,20 @@ static struct dibx000_agc_config dib7070_agc_config = {
static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
deb_info("reset: %d", onoff);
- return dib7000p_set_gpio(fe, 8, 0, !onoff);
+ return state->dib7000p_ops.set_gpio(fe, 8, 0, !onoff);
}
static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
deb_info("sleep: %d", onoff);
- return dib7000p_set_gpio(fe, 9, 0, onoff);
+ return state->dib7000p_ops.set_gpio(fe, 9, 0, onoff);
}
static struct dib0070_config dib7070p_dib0070_config[2] = {
@@ -818,7 +858,7 @@ static int dib7070_set_param_override(struct dvb_frontend *fe)
default: offset = 550; break;
}
deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
- dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+ state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
return state->set_param_save(fe);
}
@@ -832,39 +872,39 @@ static int dib7770_set_param_override(struct dvb_frontend *fe)
u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
switch (band) {
case BAND_VHF:
- dib7000p_set_gpio(fe, 0, 0, 1);
+ state->dib7000p_ops.set_gpio(fe, 0, 0, 1);
offset = 850;
break;
case BAND_UHF:
default:
- dib7000p_set_gpio(fe, 0, 0, 0);
+ state->dib7000p_ops.set_gpio(fe, 0, 0, 0);
offset = 250;
break;
}
deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
- dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+ state->dib7000p_ops.set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
return state->set_param_save(fe);
}
static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
{
- struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+ struct dib0700_adapter_state *st = adap->priv;
+ struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
- if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
- &dib7770p_dib0070_config) == NULL)
- return -ENODEV;
+ if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
+ &dib7770p_dib0070_config) == NULL)
+ return -ENODEV;
- st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
- adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
- return 0;
+ st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+ adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
+ return 0;
}
static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+ struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
if (adap->id == 0) {
if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
@@ -882,28 +922,33 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
u16 pid, int onoff)
{
+ struct dib0700_adapter_state *state = adapter->priv;
struct dib0700_state *st = adapter->dev->priv;
+
if (st->is_dib7000pc)
- return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+ return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}
static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
{
struct dib0700_state *st = adapter->dev->priv;
+ struct dib0700_adapter_state *state = adapter->priv;
if (st->is_dib7000pc)
- return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+ return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}
static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
{
- return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+ struct dib0700_adapter_state *state = adapter->priv;
+ return state->dib7000p_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}
static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
{
- return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+ struct dib0700_adapter_state *state = adapter->priv;
+ return state->dib7000p_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}
static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
@@ -936,6 +981,11 @@ static struct dib7000p_config dib7070p_dib7000p_config = {
static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
@@ -954,14 +1004,15 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
&dib7070p_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
&dib7070p_dib7000p_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -988,6 +1039,11 @@ static struct dib7000p_config dib7770p_dib7000p_config = {
static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
@@ -1006,14 +1062,15 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
&dib7770p_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80,
&dib7770p_dib7000p_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -1161,12 +1218,18 @@ static struct dib8000_config dib807x_dib8000_config[2] = {
static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
{
- return dib8000_set_gpio(fe, 5, 0, !onoff);
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ return state->dib8000_ops.set_gpio(fe, 5, 0, !onoff);
}
static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
{
- return dib8000_set_gpio(fe, 0, 0, onoff);
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ return state->dib8000_ops.set_gpio(fe, 0, 0, onoff);
}
static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
@@ -1223,7 +1286,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe)
offset += 250; break;
}
deb_info("WBD for DiB8000: %d\n", offset);
- dib8000_set_wbd_ref(fe, offset);
+ state->dib8000_ops.set_wbd_ref(fe, offset);
return state->set_param_save(fe);
}
@@ -1231,7 +1294,7 @@ static int dib807x_set_param_override(struct dvb_frontend *fe)
static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
+ struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
if (adap->id == 0) {
@@ -1252,18 +1315,27 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
u16 pid, int onoff)
{
- return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
+ struct dib0700_adapter_state *state = adapter->priv;
+
+ return state->dib8000_ops.pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
}
static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
int onoff)
{
- return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
+ struct dib0700_adapter_state *state = adapter->priv;
+
+ return state->dib8000_ops.pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
}
/* STK807x */
static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
+
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
@@ -1279,10 +1351,10 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
0x80, 0);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80,
&dib807x_dib8000_config[0]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -1291,6 +1363,11 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
/* STK807xPVR */
static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
+
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
msleep(30);
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
@@ -1309,9 +1386,9 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
/* initialize IC 0 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80,
&dib807x_dib8000_config[0]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -1319,10 +1396,15 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
+
/* initialize IC 1 */
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82,
&dib807x_dib8000_config[1]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -1331,104 +1413,121 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
/* STK8096GP */
static struct dibx000_agc_config dib8090_agc_config[2] = {
{
- BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+ .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
* P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
* P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
- 787,
- 10,
-
- 0,
- 118,
-
- 0,
- 3530,
- 1,
- 5,
+ .inv_gain = 787,
+ .time_stabiliz = 10,
- 65535,
- 0,
+ .alpha_level = 0,
+ .thlock = 118,
- 65535,
- 0,
+ .wbd_inv = 0,
+ .wbd_ref = 3530,
+ .wbd_sel = 1,
+ .wbd_alpha = 5,
- 0,
- 32,
- 114,
- 143,
- 144,
- 114,
- 227,
- 116,
- 117,
+ .agc1_max = 65535,
+ .agc1_min = 0,
- 28,
- 26,
- 31,
- 51,
+ .agc2_max = 65535,
+ .agc2_min = 0,
- 0,
+ .agc1_pt1 = 0,
+ .agc1_pt2 = 32,
+ .agc1_pt3 = 114,
+ .agc1_slope1 = 143,
+ .agc1_slope2 = 144,
+ .agc2_pt1 = 114,
+ .agc2_pt2 = 227,
+ .agc2_slope1 = 116,
+ .agc2_slope2 = 117,
+
+ .alpha_mant = 28,
+ .alpha_exp = 26,
+ .beta_mant = 31,
+ .beta_exp = 51,
+
+ .perform_agc_softsplit = 0,
},
{
- BAND_CBAND,
+ .band_caps = BAND_CBAND,
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
* P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
* P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
- (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
+ .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
| (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
- 787,
- 10,
+ .inv_gain = 787,
+ .time_stabiliz = 10,
- 0,
- 118,
+ .alpha_level = 0,
+ .thlock = 118,
- 0,
- 3530,
- 1,
- 5,
+ .wbd_inv = 0,
+ .wbd_ref = 3530,
+ .wbd_sel = 1,
+ .wbd_alpha = 5,
- 0,
- 0,
+ .agc1_max = 0,
+ .agc1_min = 0,
- 65535,
- 0,
-
- 0,
- 32,
- 114,
- 143,
- 144,
- 114,
- 227,
- 116,
- 117,
-
- 28,
- 26,
- 31,
- 51,
+ .agc2_max = 65535,
+ .agc2_min = 0,
- 0,
+ .agc1_pt1 = 0,
+ .agc1_pt2 = 32,
+ .agc1_pt3 = 114,
+ .agc1_slope1 = 143,
+ .agc1_slope2 = 144,
+ .agc2_pt1 = 114,
+ .agc2_pt2 = 227,
+ .agc2_slope1 = 116,
+ .agc2_slope2 = 117,
+
+ .alpha_mant = 28,
+ .alpha_exp = 26,
+ .beta_mant = 31,
+ .beta_exp = 51,
+
+ .perform_agc_softsplit = 0,
}
};
static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
- 54000, 13500,
- 1, 18, 3, 1, 0,
- 0, 0, 1, 1, 2,
- (3 << 14) | (1 << 12) | (599 << 0),
- (0 << 25) | 0,
- 20199727,
- 12000000,
+ .internal = 54000,
+ .sampling = 13500,
+
+ .pll_prediv = 1,
+ .pll_ratio = 18,
+ .pll_range = 3,
+ .pll_reset = 1,
+ .pll_bypass = 0,
+
+ .enable_refdiv = 0,
+ .bypclk_div = 0,
+ .IO_CLK_en_core = 1,
+ .ADClkSrc = 1,
+ .modulo = 2,
+
+ .sad_cfg = (3 << 14) | (1 << 12) | (599 << 0),
+
+ .ifreq = (0 << 25) | 0,
+ .timf = 20199727,
+
+ .xtal_hz = 12000000,
};
static int dib8090_get_adc_power(struct dvb_frontend *fe)
{
- return dib8000_get_adc_power(fe, 1);
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ return state->dib8000_ops.get_adc_power(fe, 1);
}
static void dib8090_agc_control(struct dvb_frontend *fe, u8 restart)
@@ -1551,10 +1650,10 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
default:
deb_info("Warning : Rf frequency (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency);
case BAND_VHF:
- dib8000_set_gpio(fe, 3, 0, 1);
+ state->dib8000_ops.set_gpio(fe, 3, 0, 1);
break;
case BAND_UHF:
- dib8000_set_gpio(fe, 3, 0, 0);
+ state->dib8000_ops.set_gpio(fe, 3, 0, 0);
break;
}
@@ -1568,7 +1667,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
}
/** Update PLL if needed ratio **/
- dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
+ state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
/** Get optimize PLL ratio to remove spurious **/
pll_ratio = dib8090_compute_pll_parameters(fe);
@@ -1582,14 +1681,14 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
timf = 18179756;
/** Update ratio **/
- dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);
+ state->dib8000_ops.update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);
- dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, timf);
+ state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, timf);
if (band != BAND_CBAND) {
/* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */
target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
- dib8000_set_wbd_ref(fe, target);
+ state->dib8000_ops.set_wbd_ref(fe, target);
}
if (band == BAND_CBAND) {
@@ -1601,18 +1700,18 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
msleep(ret);
tune_state = dib0090_get_tune_state(fe);
if (tune_state == CT_AGC_STEP_0)
- dib8000_set_gpio(fe, 6, 0, 1);
+ state->dib8000_ops.set_gpio(fe, 6, 0, 1);
else if (tune_state == CT_AGC_STEP_1) {
dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
if (rf_gain_limit < 2000) /* activate the external attenuator in case of very high input power */
- dib8000_set_gpio(fe, 6, 0, 0);
+ state->dib8000_ops.set_gpio(fe, 6, 0, 0);
}
} while (tune_state < CT_AGC_STOP);
deb_info("switching to PWM AGC\n");
dib0090_pwm_gain_reset(fe);
- dib8000_pwm_agc_reset(fe);
- dib8000_set_tune_state(fe, CT_DEMOD_START);
+ state->dib8000_ops.pwm_agc_reset(fe);
+ state->dib8000_ops.set_tune_state(fe, CT_DEMOD_START);
} else {
/* for everything else than CBAND we are using standard AGC */
deb_info("not tuning in CBAND - standard AGC startup\n");
@@ -1625,7 +1724,7 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+ struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
return -ENODEV;
@@ -1637,6 +1736,11 @@ static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
+
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
@@ -1652,9 +1756,9 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -1663,16 +1767,16 @@ static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
struct i2c_adapter *tun_i2c;
- struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);
+ struct dvb_frontend *fe_slave = st->dib8000_ops.get_slave_frontend(adap->fe_adap[0].fe, 1);
if (fe_slave) {
- tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
+ tun_i2c = st->dib8000_ops.get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
return -ENODEV;
fe_slave->dvb = adap->fe_adap[0].fe->dvb;
fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
}
- tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+ tun_i2c = st->dib8000_ops.get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
return -ENODEV;
@@ -1685,6 +1789,10 @@ static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dvb_frontend *fe_slave;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
msleep(20);
@@ -1703,14 +1811,18 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
msleep(20);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
if (adap->fe_adap[0].fe == NULL)
return -ENODEV;
- fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
- dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
+ /* Needed to increment refcount */
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
+
+ fe_slave = state->dib8000_ops.init(&adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
+ state->dib8000_ops.set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
return fe_slave == NULL ? -ENODEV : 0;
}
@@ -1845,7 +1957,7 @@ static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
{ 0xFFFF, 0, 0, 0, 0, 0},
};
-static const struct dib0090_config tfe8096p_dib0090_config = {
+static struct dib0090_config tfe8096p_dib0090_config = {
.io.clock_khz = 12000,
.io.pll_bypass = 0,
.io.pll_range = 0,
@@ -1853,8 +1965,6 @@ static const struct dib0090_config tfe8096p_dib0090_config = {
.io.pll_loopdiv = 6,
.io.adc_clock_ratio = 0,
.io.pll_int_loop_filt = 0,
- .reset = dib8096p_tuner_sleep,
- .sleep = dib8096p_tuner_sleep,
.freq_offset_khz_uhf = -143,
.freq_offset_khz_vhf = -143,
@@ -1871,8 +1981,6 @@ static const struct dib0090_config tfe8096p_dib0090_config = {
.fref_clock_ratio = 1,
- .wbd = dib8096p_wbd_table,
-
.ls_cfg_pad_drv = 0,
.data_tx_drv = 0,
.low_if = NULL,
@@ -1983,15 +2091,15 @@ static int dib8096p_agc_startup(struct dvb_frontend *fe)
/* dib0090_get_wbd_target is returning any possible
temperature compensated wbd-target */
target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
- dib8000_set_wbd_ref(fe, target);
+ state->dib8000_ops.set_wbd_ref(fe, target);
if (dib8096p_get_best_sampling(fe, &adc) == 0) {
pll.pll_ratio = adc.pll_loopdiv;
pll.pll_prediv = adc.pll_prediv;
dib0700_set_i2c_speed(adap->dev, 200);
- dib8000_update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
- dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
+ state->dib8000_ops.update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
+ state->dib8000_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
dib0700_set_i2c_speed(adap->dev, 1000);
}
return 0;
@@ -2001,6 +2109,10 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
u32 fw_version;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib8000_attach, &state->dib8000_ops))
+ return -ENODEV;
dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
if (fw_version >= 0x10200)
@@ -2021,10 +2133,10 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(20);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
+ state->dib8000_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
- adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
- &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
+ adap->fe_adap[0].fe = state->dib8000_ops.init(&adap->dev->i2c_adap,
+ 0x80, &tfe8096p_dib8000_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -2032,13 +2144,17 @@ static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
+ struct i2c_adapter *tun_i2c = st->dib8000_ops.get_i2c_tuner(adap->fe_adap[0].fe);
+
+ tfe8096p_dib0090_config.reset = st->dib8000_ops.tuner_sleep;
+ tfe8096p_dib0090_config.sleep = st->dib8000_ops.tuner_sleep;
+ tfe8096p_dib0090_config.wbd = dib8096p_wbd_table;
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
&tfe8096p_dib0090_config) == NULL)
return -ENODEV;
- dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ st->dib8000_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
@@ -2479,14 +2595,14 @@ static int dib7090_agc_startup(struct dvb_frontend *fe)
memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
dib0090_pwm_gain_reset(fe);
target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
- dib7000p_set_wbd_ref(fe, target);
+ state->dib7000p_ops.set_wbd_ref(fe, target);
if (dib7090p_get_best_sampling(fe, &adc) == 0) {
pll.pll_ratio = adc.pll_loopdiv;
pll.pll_prediv = adc.pll_prediv;
- dib7000p_update_pll(fe, &pll);
- dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
+ state->dib7000p_ops.update_pll(fe, &pll);
+ state->dib7000p_ops.ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
}
return 0;
}
@@ -2501,14 +2617,17 @@ static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
static int tfe7790p_update_lna(struct dvb_frontend *fe, u16 agc_global)
{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
deb_info("update LNA: agc global=%i", agc_global);
if (agc_global < 25000) {
- dib7000p_set_gpio(fe, 8, 0, 0);
- dib7000p_set_agc1_min(fe, 0);
+ state->dib7000p_ops.set_gpio(fe, 8, 0, 0);
+ state->dib7000p_ops.set_agc1_min(fe, 0);
} else {
- dib7000p_set_gpio(fe, 8, 0, 1);
- dib7000p_set_agc1_min(fe, 32768);
+ state->dib7000p_ops.set_gpio(fe, 8, 0, 1);
+ state->dib7000p_ops.set_agc1_min(fe, 32768);
}
return 0;
@@ -2644,13 +2763,16 @@ static struct dib7000p_config nim7090_dib7000p_config = {
static int tfe7090p_pvr_update_lna(struct dvb_frontend *fe, u16 agc_global)
{
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
deb_info("TFE7090P-PVR update LNA: agc global=%i", agc_global);
if (agc_global < 25000) {
- dib7000p_set_gpio(fe, 5, 0, 0);
- dib7000p_set_agc1_min(fe, 0);
+ state->dib7000p_ops.set_gpio(fe, 5, 0, 0);
+ state->dib7000p_ops.set_agc1_min(fe, 0);
} else {
- dib7000p_set_gpio(fe, 5, 0, 1);
- dib7000p_set_agc1_min(fe, 32768);
+ state->dib7000p_ops.set_gpio(fe, 5, 0, 1);
+ state->dib7000p_ops.set_agc1_min(fe, 32768);
}
return 0;
@@ -2714,7 +2836,7 @@ static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
}
};
-static const struct dib0090_config nim7090_dib0090_config = {
+static struct dib0090_config nim7090_dib0090_config = {
.io.clock_khz = 12000,
.io.pll_bypass = 0,
.io.pll_range = 0,
@@ -2722,14 +2844,10 @@ static const struct dib0090_config nim7090_dib0090_config = {
.io.pll_loopdiv = 6,
.io.adc_clock_ratio = 0,
.io.pll_int_loop_filt = 0,
- .reset = dib7090_tuner_sleep,
- .sleep = dib7090_tuner_sleep,
.freq_offset_khz_uhf = 0,
.freq_offset_khz_vhf = 0,
- .get_adc_power = dib7090_get_adc_power,
-
.clkouttobamse = 1,
.analog_output = 0,
@@ -2776,7 +2894,7 @@ static struct dib7000p_config tfe7790p_dib7000p_config = {
.enMpegOutput = 1,
};
-static const struct dib0090_config tfe7790p_dib0090_config = {
+static struct dib0090_config tfe7790p_dib0090_config = {
.io.clock_khz = 12000,
.io.pll_bypass = 0,
.io.pll_range = 0,
@@ -2784,14 +2902,10 @@ static const struct dib0090_config tfe7790p_dib0090_config = {
.io.pll_loopdiv = 6,
.io.adc_clock_ratio = 0,
.io.pll_int_loop_filt = 0,
- .reset = dib7090_tuner_sleep,
- .sleep = dib7090_tuner_sleep,
.freq_offset_khz_uhf = 0,
.freq_offset_khz_vhf = 0,
- .get_adc_power = dib7090_get_adc_power,
-
.clkouttobamse = 1,
.analog_output = 0,
@@ -2813,7 +2927,7 @@ static const struct dib0090_config tfe7790p_dib0090_config = {
.force_crystal_mode = 1,
};
-static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
+static struct dib0090_config tfe7090pvr_dib0090_config[2] = {
{
.io.clock_khz = 12000,
.io.pll_bypass = 0,
@@ -2822,14 +2936,10 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
.io.pll_loopdiv = 6,
.io.adc_clock_ratio = 0,
.io.pll_int_loop_filt = 0,
- .reset = dib7090_tuner_sleep,
- .sleep = dib7090_tuner_sleep,
.freq_offset_khz_uhf = 50,
.freq_offset_khz_vhf = 70,
- .get_adc_power = dib7090_get_adc_power,
-
.clkouttobamse = 1,
.analog_output = 0,
@@ -2854,14 +2964,10 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
.io.pll_loopdiv = 6,
.io.adc_clock_ratio = 0,
.io.pll_int_loop_filt = 0,
- .reset = dib7090_tuner_sleep,
- .sleep = dib7090_tuner_sleep,
.freq_offset_khz_uhf = -50,
.freq_offset_khz_vhf = -70,
- .get_adc_power = dib7090_get_adc_power,
-
.clkouttobamse = 1,
.analog_output = 0,
@@ -2883,6 +2989,11 @@ static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(20);
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
@@ -2895,11 +3006,12 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
msleep(20);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -2907,12 +3019,16 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+ struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe);
+
+ nim7090_dib0090_config.reset = st->dib7000p_ops.tuner_sleep,
+ nim7090_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep,
+ nim7090_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power;
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
return -ENODEV;
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
@@ -2922,6 +3038,10 @@ static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
/* The TFE7090 requires the dib0700 to not be in master mode */
st->disable_streaming_master_mode = 1;
@@ -2939,17 +3059,18 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
/* initialize IC 0 */
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
dib0700_set_i2c_speed(adap->dev, 340);
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
if (adap->fe_adap[0].fe == NULL)
return -ENODEV;
- dib7090_slave_reset(adap->fe_adap[0].fe);
+ state->dib7000p_ops.slave_reset(adap->fe_adap[0].fe);
return 0;
}
@@ -2957,19 +3078,24 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
{
struct i2c_adapter *i2c;
+ struct dib0700_adapter_state *state = adap->priv;
if (adap->dev->adapter[0].fe_adap[0].fe == NULL) {
err("the master dib7090 has to be initialized first");
return -ENODEV; /* the master device has not been initialized */
}
- i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
- if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
+ i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
+ if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
dib0700_set_i2c_speed(adap->dev, 200);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -2978,12 +3104,16 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+ struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe);
+
+ tfe7090pvr_dib0090_config[0].reset = st->dib7000p_ops.tuner_sleep;
+ tfe7090pvr_dib0090_config[0].sleep = st->dib7000p_ops.tuner_sleep;
+ tfe7090pvr_dib0090_config[0].get_adc_power = st->dib7000p_ops.get_adc_power;
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
return -ENODEV;
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
@@ -2993,12 +3123,16 @@ static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
- struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+ struct i2c_adapter *tun_i2c = st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe);
+
+ tfe7090pvr_dib0090_config[1].reset = st->dib7000p_ops.tuner_sleep;
+ tfe7090pvr_dib0090_config[1].sleep = st->dib7000p_ops.tuner_sleep;
+ tfe7090pvr_dib0090_config[1].get_adc_power = st->dib7000p_ops.get_adc_power;
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
return -ENODEV;
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
@@ -3008,6 +3142,10 @@ static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
/* The TFE7790P requires the dib0700 to not be in master mode */
st->disable_streaming_master_mode = 1;
@@ -3024,13 +3162,14 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(20);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap,
1, 0x10, &tfe7790p_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap,
0x80, &tfe7790p_dib7000p_config);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
@@ -3040,13 +3179,18 @@ static int tfe7790p_tuner_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_adapter_state *st = adap->priv;
struct i2c_adapter *tun_i2c =
- dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+ st->dib7000p_ops.get_i2c_tuner(adap->fe_adap[0].fe);
+
+
+ tfe7790p_dib0090_config.reset = st->dib7000p_ops.tuner_sleep;
+ tfe7790p_dib0090_config.sleep = st->dib7000p_ops.tuner_sleep;
+ tfe7790p_dib0090_config.get_adc_power = st->dib7000p_ops.get_adc_power;
if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
&tfe7790p_dib0090_config) == NULL)
return -ENODEV;
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ st->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
@@ -3103,25 +3247,36 @@ static void stk7070pd_init(struct dvb_usb_device *dev)
static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
{
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
stk7070pd_init(adap->dev);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
stk7070pd_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
{
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
+
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}
@@ -3164,6 +3319,10 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *dev = adap->dev;
struct dib0700_state *st = dev->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
if (adap->id == 0) {
stk7070pd_init(dev);
@@ -3173,15 +3332,16 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
- if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
+ if (state->dib7000p_ops.i2c_enumeration(&dev->i2c_adap, 2, 18,
stk7070pd_dib7000p_config) != 0) {
- err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n",
__func__);
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&dev->i2c_adap,
adap->id == 0 ? 0x80 : 0x82,
&stk7070pd_dib7000p_config[adap->id]);
@@ -3291,12 +3451,13 @@ static int dib0700_xc4000_tuner_callback(void *priv, int component,
int command, int arg)
{
struct dvb_usb_adapter *adap = priv;
+ struct dib0700_adapter_state *state = adap->priv;
if (command == XC4000_TUNER_RESET) {
/* Reset the tuner */
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
+ state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
msleep(10);
- dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+ state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
} else {
err("xc4000: unknown tuner callback command: %d\n", command);
return -EINVAL;
@@ -3374,6 +3535,10 @@ static struct dib7000p_config pctv_340e_config = {
static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dib0700_state *st = adap->dev->priv;
+ struct dib0700_adapter_state *state = adap->priv;
+
+ if (!dvb_attach(dib7000p_attach, &state->dib7000p_ops))
+ return -ENODEV;
/* Power Supply on */
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
@@ -3397,12 +3562,13 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
msleep(500);
- if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
+ if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
/* Demodulator not found for some reason? */
+ dvb_detach(&state->dib7000p_ops);
return -ENODEV;
}
- adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
+ adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x12,
&pctv_340e_config);
st->is_dib7000pc = 1;
@@ -3420,9 +3586,10 @@ static struct xc4000_config dib7000p_xc4000_tunerconfig = {
static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
{
struct i2c_adapter *tun_i2c;
+ struct dib0700_adapter_state *state = adap->priv;
/* The xc4000 is not on the main i2c bus */
- tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
+ tun_i2c = state->dib7000p_ops.get_i2c_master(adap->fe_adap[0].fe,
DIBX000_I2C_INTERFACE_TUNER, 1);
if (tun_i2c == NULL) {
printk(KERN_ERR "Could not reach tuner i2c bus\n");
@@ -3636,6 +3803,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
}},
+ .size_of_priv = sizeof(struct dib0700_adapter_state),
},
},
diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
index e47c321b3ffc..32ab1392313f 100644
--- a/drivers/media/usb/dvb-usb/dibusb.h
+++ b/drivers/media/usb/dvb-usb/dibusb.h
@@ -36,7 +36,7 @@
/*
* i2c read
- * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
+ * bulk write: 0x02 ((7bit i2c_addr << 1) | 0x01) register_bytes length_word
* bulk read: byte_buffer (length_word bytes)
*/
#define DIBUSB_REQ_I2C_READ 0x02
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
index 4058aea9272f..7b5dae3077f6 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
@@ -272,7 +272,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
dev->driver_name = d->props.rc.core.module_name;
dev->map_name = d->props.rc.core.rc_codes;
dev->change_protocol = d->props.rc.core.change_protocol;
- rc_set_allowed_protocols(dev, d->props.rc.core.allowed_protos);
+ dev->allowed_protocols = d->props.rc.core.allowed_protos;
dev->driver_type = d->props.rc.core.driver_type;
usb_to_input_id(d->udev, &dev->input_id);
dev->input_name = "IR-receiver inside an USB DVB receiver";
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index ae0f56a32e4d..2add8c507ec9 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -1109,6 +1109,7 @@ static struct ds3000_config su3000_ds3000_config = {
static struct cxd2820r_config cxd2820r_config = {
.i2c_address = 0x6c, /* (0xd8 >> 1) */
.ts_mode = 0x38,
+ .ts_clock_inv = 1,
};
static struct tda18271_config tda18271_config = {
@@ -1387,20 +1388,27 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
static int t220_frontend_attach(struct dvb_usb_adapter *d)
{
- u8 obuf[3] = { 0xe, 0x80, 0 };
+ u8 obuf[3] = { 0xe, 0x87, 0 };
u8 ibuf[] = { 0 };
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
err("command 0x0e transfer failed.");
obuf[0] = 0xe;
- obuf[1] = 0x83;
+ obuf[1] = 0x86;
+ obuf[2] = 1;
+
+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
+ err("command 0x0e transfer failed.");
+
+ obuf[0] = 0xe;
+ obuf[1] = 0x80;
obuf[2] = 0;
if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
err("command 0x0e transfer failed.");
- msleep(100);
+ msleep(50);
obuf[0] = 0xe;
obuf[1] = 0x80;
@@ -1482,7 +1490,7 @@ static int dw2102_rc_query(struct dvb_usb_device *d)
if (msg.buf[0] != 0xff) {
deb_rc("%s: rc code: %x, %x\n",
__func__, key[0], key[1]);
- rc_keydown(d->rc_dev, key[0], 1);
+ rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0], 0);
}
}
@@ -1503,7 +1511,7 @@ static int prof_rc_query(struct dvb_usb_device *d)
if (msg.buf[0] != 0xff) {
deb_rc("%s: rc code: %x, %x\n",
__func__, key[0], key[1]);
- rc_keydown(d->rc_dev, key[0]^0xff, 1);
+ rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, key[0]^0xff, 0);
}
}
@@ -1524,7 +1532,8 @@ static int su3000_rc_query(struct dvb_usb_device *d)
if (msg.buf[0] != 0xff) {
deb_rc("%s: rc code: %x, %x\n",
__func__, key[0], key[1]);
- rc_keydown(d->rc_dev, key[1] << 8 | key[0], 1);
+ rc_keydown(d->rc_dev, RC_TYPE_RC5,
+ RC_SCANCODE_RC5(key[1], key[0]), 0);
}
}
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
index 0306cb778df4..abf8ab2e02e5 100644
--- a/drivers/media/usb/dvb-usb/m920x.c
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -245,7 +245,7 @@ static int m920x_rc_core_query(struct dvb_usb_device *d)
else if (state == REMOTE_KEY_REPEAT)
rc_repeat(d->rc_dev);
else
- rc_keydown(d->rc_dev, rc_state[1], 0);
+ rc_keydown(d->rc_dev, RC_TYPE_UNKNOWN, rc_state[1], 0);
out:
kfree(rc_state);
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 449a99605a87..bdfe8963591c 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -565,12 +565,12 @@ static int pctv452e_rc_query(struct dvb_usb_device *d)
if ((rx[3] == 9) && (rx[12] & 0x01)) {
/* got a "press" event */
- state->last_rc_key = (rx[7] << 8) | rx[6];
+ state->last_rc_key = RC_SCANCODE_RC5(rx[7], rx[6]);
if (debug > 2)
info("%s: cmd=0x%02x sys=0x%02x\n",
__func__, rx[6], rx[7]);
- rc_keydown(d->rc_dev, state->last_rc_key, 0);
+ rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0);
} else if (state->last_rc_key) {
rc_keyup(d->rc_dev);
state->last_rc_key = 0;
@@ -927,7 +927,7 @@ static struct dvb_usb_device_properties pctv452e_properties = {
.rc.core = {
.rc_codes = RC_MAP_DIB0700_RC5_TABLE,
- .allowed_protos = RC_BIT_UNKNOWN,
+ .allowed_protos = RC_BIT_RC5,
.rc_query = pctv452e_rc_query,
.rc_interval = 100,
},
@@ -980,7 +980,7 @@ static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
.rc.core = {
.rc_codes = RC_MAP_TT_1500,
- .allowed_protos = RC_BIT_UNKNOWN,
+ .allowed_protos = RC_BIT_RC5,
.rc_query = pctv452e_rc_query,
.rc_interval = 100,
},
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index d947e0379008..6b0b8b6b9e2a 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -710,7 +710,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = {
.isoc = {
.framesperurb = 32,
.framesize = 2048,
- .interval = 3,
+ .interval = 1,
}
}
},
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index 2ce3d19c58ef..f10717311e05 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -438,9 +438,9 @@ static int tt3650_rc_query(struct dvb_usb_device *d)
if (rx[8] & 0x01) {
/* got a "press" event */
- st->last_rc_key = (rx[3] << 8) | rx[2];
+ st->last_rc_key = RC_SCANCODE_RC5(rx[3], rx[2]);
deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
- rc_keydown(d->rc_dev, st->last_rc_key, rx[1]);
+ rc_keydown(d->rc_dev, RC_TYPE_RC5, st->last_rc_key, rx[1]);
} else if (st->last_rc_key) {
rc_keyup(d->rc_dev);
st->last_rc_key = 0;
@@ -747,7 +747,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
.rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */
.rc_codes = RC_MAP_TT_1500,
.rc_query = tt3650_rc_query,
- .allowed_protos = RC_BIT_UNKNOWN,
+ .allowed_protos = RC_BIT_RC5,
},
.num_adapters = 1,
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c
index 12d4c0326e31..6d2ea9afd57b 100644
--- a/drivers/media/usb/em28xx/em28xx-camera.c
+++ b/drivers/media/usb/em28xx/em28xx-camera.c
@@ -366,7 +366,7 @@ int em28xx_init_camera(struct em28xx *dev)
v4l2->sensor_xtal = 4300000;
pdata.xtal = v4l2->sensor_xtal;
if (NULL ==
- v4l2_i2c_new_subdev_board(&dev->v4l2->v4l2_dev, adap,
+ v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
&mt9v011_info, NULL)) {
ret = -ENODEV;
break;
@@ -423,7 +423,7 @@ int em28xx_init_camera(struct em28xx *dev)
v4l2->sensor_yres = 480;
subdev =
- v4l2_i2c_new_subdev_board(&dev->v4l2->v4l2_dev, adap,
+ v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
&ov2640_info, NULL);
if (NULL == subdev) {
ret = -ENODEV;
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 15ad47045553..a7e24848f6c8 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2280,6 +2280,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2875),
.driver_info = EM2820_BOARD_UNKNOWN },
+ { USB_DEVICE(0xeb1a, 0x2885), /* MSI Digivox Trio */
+ .driver_info = EM2884_BOARD_TERRATEC_H5 },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
{ USB_DEVICE(0xeb1a, 0xe303),
@@ -3522,7 +3524,6 @@ static struct usb_driver em28xx_usb_driver = {
.disconnect = em28xx_usb_disconnect,
.suspend = em28xx_usb_suspend,
.resume = em28xx_usb_resume,
- .reset_resume = em28xx_usb_resume,
.id_table = em28xx_id_table,
};
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index a121ed9561fd..3a3e243edf89 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -1213,9 +1213,17 @@ static int em28xx_dvb_init(struct em28xx *dev)
dvb->fe[0] = dvb_attach(lgdt3305_attach,
&em2870_lgdt3304_dev,
&dev->i2c_adap[dev->def_i2c_bus]);
- if (dvb->fe[0] != NULL)
- dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
- &dev->i2c_adap[dev->def_i2c_bus], &kworld_a340_config);
+ if (!dvb->fe[0]) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
+ &dev->i2c_adap[dev->def_i2c_bus],
+ &kworld_a340_config)) {
+ dvb_frontend_detach(dvb->fe[0]);
+ result = -EINVAL;
+ goto out_free;
+ }
break;
case EM28174_BOARD_PCTV_290E:
/* set default GPIO0 for LNA, used if GPIOLIB is undefined */
@@ -1545,6 +1553,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
dvb->i2c_client_demod = client;
/* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
si2157_config.fe = dvb->fe[0];
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "si2157", I2C_NAME_SIZE);
@@ -1645,10 +1654,14 @@ static int em28xx_dvb_fini(struct em28xx *dev)
if (dev->disconnected) {
/* We cannot tell the device to sleep
* once it has been unplugged. */
- if (dvb->fe[0])
+ if (dvb->fe[0]) {
prevent_sleep(&dvb->fe[0]->ops);
- if (dvb->fe[1])
+ dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED;
+ }
+ if (dvb->fe[1]) {
prevent_sleep(&dvb->fe[1]->ops);
+ dvb->fe[1]->exit = DVB_FE_DEVICE_REMOVED;
+ }
}
/* remove I2C tuner */
@@ -1712,7 +1725,6 @@ static int em28xx_dvb_resume(struct em28xx *dev)
em28xx_info("Resuming DVB extension");
if (dev->dvb) {
struct em28xx_dvb *dvb = dev->dvb;
- struct i2c_client *client = dvb->i2c_client_tuner;
if (dvb->fe[0]) {
ret = dvb_frontend_resume(dvb->fe[0]);
@@ -1723,22 +1735,6 @@ static int em28xx_dvb_resume(struct em28xx *dev)
ret = dvb_frontend_resume(dvb->fe[1]);
em28xx_info("fe1 resume %d", ret);
}
- /* remove I2C tuner */
- if (client) {
- module_put(client->dev.driver->owner);
- i2c_unregister_device(client);
- }
-
- /* remove I2C demod */
- client = dvb->i2c_client_demod;
- if (client) {
- module_put(client->dev.driver->owner);
- i2c_unregister_device(client);
- }
-
- em28xx_unregister_dvb(dvb);
- kfree(dvb);
- dev->dvb = NULL;
}
return 0;
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index b58d4ebf6419..1048c1a23fb6 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -501,6 +501,12 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
int addr, rc, i;
u8 reg;
+ /* prevent i2c xfer attempts after device is disconnected
+ some fe's try to do i2c writes/reads from their release
+ interfaces when called in disconnect path */
+ if (dev->disconnected)
+ return -ENODEV;
+
rc = rt_mutex_trylock(&dev->i2c_bus_lock);
if (rc < 0)
return rc;
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 56ef49df4f8d..ed843bd221ea 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/slab.h>
+#include <linux/bitrev.h>
#include "em28xx.h"
@@ -53,6 +54,7 @@ struct em28xx_ir_poll_result {
unsigned int toggle_bit:1;
unsigned int read_count:7;
+ enum rc_type protocol;
u32 scancode;
};
@@ -72,7 +74,7 @@ struct em28xx_IR {
/* i2c slave address of external device (if used) */
u16 i2c_dev_addr;
- int (*get_key_i2c)(struct i2c_client *, u32 *);
+ int (*get_key_i2c)(struct i2c_client *ir, enum rc_type *protocol, u32 *scancode);
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
};
@@ -80,7 +82,8 @@ struct em28xx_IR {
I2C IR based get keycodes - should be used with ir-kbd-i2c
**********************************************************/
-static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, u32 *ir_key)
+static int em28xx_get_key_terratec(struct i2c_client *i2c_dev,
+ enum rc_type *protocol, u32 *scancode)
{
unsigned char b;
@@ -98,14 +101,15 @@ static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, u32 *ir_key)
/* keep old data */
return 1;
- *ir_key = b;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = b;
return 1;
}
-static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, u32 *ir_key)
+static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev,
+ enum rc_type *protocol, u32 *scancode)
{
unsigned char buf[2];
- u16 code;
int size;
/* poll IR chip */
@@ -127,26 +131,13 @@ static int em28xx_get_key_em_haup(struct i2c_client *i2c_dev, u32 *ir_key)
* So, the code translation is not complete. Yet, it is enough to
* work with the provided RC5 IR.
*/
- code =
- ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */
- ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */
- ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */
- ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */
- ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */
- ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */
- ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */
- ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */
- ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */
- ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */
- ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */
-
- /* return key */
- *ir_key = code;
+ *protocol = RC_TYPE_RC5;
+ *scancode = (bitrev8(buf[1]) & 0x1f) << 8 | bitrev8(buf[0]) >> 2;
return 1;
}
static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev,
- u32 *ir_key)
+ enum rc_type *protocol, u32 *scancode)
{
unsigned char buf[3];
@@ -158,13 +149,13 @@ static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev,
if (buf[0] != 0x00)
return 0;
- *ir_key = buf[2]&0x3f;
-
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = buf[2] & 0x3f;
return 1;
}
static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev,
- u32 *ir_key)
+ enum rc_type *protocol, u32 *scancode)
{
unsigned char subaddr, keydetect, key;
@@ -184,7 +175,8 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev,
if (key == 0x00)
return 0;
- *ir_key = key;
+ *protocol = RC_TYPE_UNKNOWN;
+ *scancode = key;
return 1;
}
@@ -215,7 +207,22 @@ static int default_polling_getkey(struct em28xx_IR *ir,
poll_result->read_count = (msg[0] & 0x7f);
/* Remote Control Address/Data (Regs 0x46/0x47) */
- poll_result->scancode = msg[1] << 8 | msg[2];
+ switch (ir->rc_type) {
+ case RC_BIT_RC5:
+ poll_result->protocol = RC_TYPE_RC5;
+ poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]);
+ break;
+
+ case RC_BIT_NEC:
+ poll_result->protocol = RC_TYPE_NEC;
+ poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[2]);
+ break;
+
+ default:
+ poll_result->protocol = RC_TYPE_UNKNOWN;
+ poll_result->scancode = msg[1] << 8 | msg[2];
+ break;
+ }
return 0;
}
@@ -247,25 +254,32 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
*/
switch (ir->rc_type) {
case RC_BIT_RC5:
- poll_result->scancode = msg[1] << 8 | msg[2];
+ poll_result->protocol = RC_TYPE_RC5;
+ poll_result->scancode = RC_SCANCODE_RC5(msg[1], msg[2]);
break;
+
case RC_BIT_NEC:
+ poll_result->protocol = RC_TYPE_RC5;
+ poll_result->scancode = msg[1] << 8 | msg[2];
if ((msg[3] ^ msg[4]) != 0xff) /* 32 bits NEC */
- poll_result->scancode = (msg[1] << 24) |
- (msg[2] << 16) |
- (msg[3] << 8) |
- msg[4];
+ poll_result->scancode = RC_SCANCODE_NEC32((msg[1] << 24) |
+ (msg[2] << 16) |
+ (msg[3] << 8) |
+ (msg[4]));
else if ((msg[1] ^ msg[2]) != 0xff) /* 24 bits NEC */
- poll_result->scancode = (msg[1] << 16) |
- (msg[2] << 8) |
- msg[3];
+ poll_result->scancode = RC_SCANCODE_NECX(msg[1] << 8 |
+ msg[2], msg[3]);
else /* Normal NEC */
- poll_result->scancode = msg[1] << 8 | msg[3];
+ poll_result->scancode = RC_SCANCODE_NEC(msg[1], msg[3]);
break;
+
case RC_BIT_RC6_0:
- poll_result->scancode = msg[1] << 8 | msg[2];
+ poll_result->protocol = RC_TYPE_RC6_0;
+ poll_result->scancode = RC_SCANCODE_RC6_0(msg[1], msg[2]);
break;
+
default:
+ poll_result->protocol = RC_TYPE_UNKNOWN;
poll_result->scancode = (msg[1] << 24) | (msg[2] << 16) |
(msg[3] << 8) | msg[4];
break;
@@ -281,22 +295,24 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir)
{
struct em28xx *dev = ir->dev;
- static u32 ir_key;
+ static u32 scancode;
+ enum rc_type protocol;
int rc;
struct i2c_client client;
client.adapter = &ir->dev->i2c_adap[dev->def_i2c_bus];
client.addr = ir->i2c_dev_addr;
- rc = ir->get_key_i2c(&client, &ir_key);
+ rc = ir->get_key_i2c(&client, &protocol, &scancode);
if (rc < 0) {
dprintk("ir->get_key_i2c() failed: %d\n", rc);
return rc;
}
if (rc) {
- dprintk("%s: keycode = 0x%04x\n", __func__, ir_key);
- rc_keydown(ir->rc, ir_key, 0);
+ dprintk("%s: proto = 0x%04x, scancode = 0x%04x\n",
+ __func__, protocol, scancode);
+ rc_keydown(ir->rc, protocol, scancode, 0);
}
return 0;
}
@@ -319,10 +335,12 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
poll_result.scancode);
if (ir->full_code)
rc_keydown(ir->rc,
+ poll_result.protocol,
poll_result.scancode,
poll_result.toggle_bit);
else
rc_keydown(ir->rc,
+ RC_TYPE_UNKNOWN,
poll_result.scancode & 0xff,
poll_result.toggle_bit);
@@ -727,7 +745,7 @@ static int em28xx_ir_init(struct em28xx *dev)
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
rc->map_name = RC_MAP_HAUPPAUGE;
ir->get_key_i2c = em28xx_get_key_em_haup;
- rc_set_allowed_protocols(rc, RC_BIT_RC5);
+ rc->allowed_protocols = RC_BIT_RC5;
break;
case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE:
rc->map_name = RC_MAP_WINFAST_USBII_DELUXE;
@@ -743,7 +761,7 @@ static int em28xx_ir_init(struct em28xx *dev)
switch (dev->chip_id) {
case CHIP_ID_EM2860:
case CHIP_ID_EM2883:
- rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC);
+ rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC;
ir->get_key = default_polling_getkey;
break;
case CHIP_ID_EM2884:
@@ -751,8 +769,8 @@ static int em28xx_ir_init(struct em28xx *dev)
case CHIP_ID_EM28174:
case CHIP_ID_EM28178:
ir->get_key = em2874_polling_getkey;
- rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC |
- RC_BIT_RC6_0);
+ rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC |
+ RC_BIT_RC6_0;
break;
default:
err = -ENODEV;
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index f6b49c98e2c9..90dec2955f1c 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1227,8 +1227,7 @@ static void scale_to_size(struct em28xx *dev,
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
f->fmt.pix.width = v4l2->width;
@@ -1261,8 +1260,7 @@ static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
unsigned int width = f->fmt.pix.width;
unsigned int height = f->fmt.pix.height;
@@ -1355,8 +1353,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
*norm = dev->v4l2->norm;
@@ -1365,8 +1362,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, video, querystd, norm);
@@ -1375,8 +1371,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
struct v4l2_format f;
@@ -1408,8 +1403,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
static int vidioc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *p)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
int rc = 0;
@@ -1427,8 +1421,7 @@ static int vidioc_g_parm(struct file *file, void *priv,
static int vidioc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *p)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
p->parm.capture.readbuffers = EM28XX_MIN_BUF;
return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev,
@@ -1450,8 +1443,7 @@ static const char *iname[] = {
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *i)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
unsigned int n;
n = i->index;
@@ -1479,8 +1471,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
*i = dev->ctl_input;
@@ -1489,8 +1480,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
if (i >= MAX_EM28XX_INPUT)
return -EINVAL;
@@ -1503,8 +1493,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
switch (a->index) {
case EM28XX_AMUX_VIDEO:
@@ -1543,8 +1532,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
if (a->index >= MAX_EM28XX_INPUT)
return -EINVAL;
@@ -1563,8 +1551,7 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *t)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
if (0 != t->index)
return -EINVAL;
@@ -1578,8 +1565,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
if (0 != t->index)
return -EINVAL;
@@ -1591,8 +1577,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
if (0 != f->tuner)
@@ -1606,8 +1591,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct v4l2_frequency new_freq = *f;
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
if (0 != f->tuner)
@@ -1624,8 +1608,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_g_chip_info(struct file *file, void *priv,
struct v4l2_dbg_chip_info *chip)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
if (chip->match.addr > 1)
return -EINVAL;
@@ -1652,8 +1635,7 @@ static int em28xx_reg_len(int reg)
static int vidioc_g_register(struct file *file, void *priv,
struct v4l2_dbg_register *reg)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
int ret;
if (reg->match.addr > 1)
@@ -1693,8 +1675,7 @@ static int vidioc_g_register(struct file *file, void *priv,
static int vidioc_s_register(struct file *file, void *priv,
const struct v4l2_dbg_register *reg)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
__le16 buf;
if (reg->match.addr > 1)
@@ -1715,8 +1696,7 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct video_device *vdev = video_devdata(file);
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
@@ -1761,8 +1741,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_fmt *fmt;
unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev);
@@ -1806,8 +1785,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *format)
{
- struct em28xx_fh *fh = priv;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(file);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
format->fmt.vbi.samples_per_line = v4l2->vbi_width;
@@ -1840,7 +1818,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
static int radio_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *t)
{
- struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
+ struct em28xx *dev = video_drvdata(file);
if (unlikely(t->index > 0))
return -EINVAL;
@@ -1855,7 +1833,7 @@ static int radio_g_tuner(struct file *file, void *priv,
static int radio_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
- struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
+ struct em28xx *dev = video_drvdata(file);
if (0 != t->index)
return -EINVAL;
@@ -1890,7 +1868,7 @@ static int em28xx_v4l2_open(struct file *filp)
struct em28xx *dev = video_drvdata(filp);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
enum v4l2_buf_type fh_type = 0;
- struct em28xx_fh *fh;
+ int ret;
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER:
@@ -1905,24 +1883,23 @@ static int em28xx_v4l2_open(struct file *filp)
return -EINVAL;
}
- em28xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- v4l2->users);
+ em28xx_videodbg("open dev=%s type=%s\n",
+ video_device_node_name(vdev), v4l2_type_names[fh_type]);
if (mutex_lock_interruptible(&dev->lock))
return -ERESTARTSYS;
- fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
- if (!fh) {
- em28xx_errdev("em28xx-video.c: Out of memory?!\n");
+
+ ret = v4l2_fh_open(filp);
+ if (ret) {
+ em28xx_errdev("%s: v4l2_fh_open() returned error %d\n",
+ __func__, ret);
mutex_unlock(&dev->lock);
- return -ENOMEM;
+ return ret;
}
- v4l2_fh_init(&fh->fh, vdev);
- fh->dev = dev;
- fh->type = fh_type;
- filp->private_data = fh;
- if (v4l2->users == 0) {
+ if (v4l2_fh_is_singular_file(filp)) {
+ em28xx_videodbg("first opened filehandle, initializing device\n");
+
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
if (vdev->vfl_type != VFL_TYPE_RADIO)
@@ -1933,6 +1910,8 @@ static int em28xx_v4l2_open(struct file *filp)
* of some i2c devices
*/
em28xx_wake_i2c(dev);
+ } else {
+ em28xx_videodbg("further filehandles are already opened\n");
}
if (vdev->vfl_type == VFL_TYPE_RADIO) {
@@ -1942,10 +1921,8 @@ static int em28xx_v4l2_open(struct file *filp)
kref_get(&dev->ref);
kref_get(&v4l2->ref);
- v4l2->users++;
mutex_unlock(&dev->lock);
- v4l2_fh_add(&fh->fh);
return 0;
}
@@ -2046,17 +2023,15 @@ static int em28xx_v4l2_resume(struct em28xx *dev)
*/
static int em28xx_v4l2_close(struct file *filp)
{
- struct em28xx_fh *fh = filp->private_data;
- struct em28xx *dev = fh->dev;
+ struct em28xx *dev = video_drvdata(filp);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
int errCode;
- em28xx_videodbg("users=%d\n", v4l2->users);
-
- vb2_fop_release(filp);
mutex_lock(&dev->lock);
- if (v4l2->users == 1) {
+ if (v4l2_fh_is_singular_file(filp)) {
+ em28xx_videodbg("last opened filehandle, shutting down device\n");
+
/* No sense to try to write to the device */
if (dev->disconnected)
goto exit;
@@ -2075,10 +2050,12 @@ static int em28xx_v4l2_close(struct file *filp)
em28xx_errdev("cannot change alternate number to "
"0 (error=%i)\n", errCode);
}
+ } else {
+ em28xx_videodbg("further opened filehandles left\n");
}
exit:
- v4l2->users--;
+ vb2_fop_release(filp);
kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock);
kref_put(&dev->ref, em28xx_free_device);
@@ -2208,7 +2185,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
vfd->v4l2_dev = &dev->v4l2->v4l2_dev;
vfd->debug = video_debug;
vfd->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
if (dev->board.is_webcam)
vfd->tvnorms = 0;
@@ -2552,7 +2528,7 @@ static int em28xx_v4l2_init(struct em28xx *dev)
v4l2->vbi_dev->queue->lock = &v4l2->vb_vbi_queue_lock;
/* disable inapplicable ioctls */
- v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM);
+ v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_PARM);
if (dev->tuner_type == TUNER_ABSENT) {
v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_TUNER);
v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_TUNER);
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index b4c837d77e5d..84ef8efdb148 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -524,7 +524,6 @@ struct em28xx_v4l2 {
int sensor_yres;
int sensor_xtal;
- int users; /* user count for exclusive use */
int streaming_users; /* number of actively streaming users */
u32 frequency; /* selected tuner frequency */
@@ -576,13 +575,6 @@ struct em28xx_audio {
struct em28xx;
-struct em28xx_fh {
- struct v4l2_fh fh;
- struct em28xx *dev;
-
- enum v4l2_buf_type type;
-};
-
enum em28xx_i2c_algo_type {
EM28XX_I2C_ALGO_EM28XX = 0,
EM28XX_I2C_ALGO_EM2800,
diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/media/usb/go7007/Kconfig
index 95a3af644a92..95a3af644a92 100644
--- a/drivers/staging/media/go7007/Kconfig
+++ b/drivers/media/usb/go7007/Kconfig
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/media/usb/go7007/Makefile
index 9c6ad4a263ec..e99287c3b828 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/media/usb/go7007/Makefile
@@ -8,8 +8,4 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
s2250-y := s2250-board.o
-# Uncomment when the saa7134 patches get into upstream
-#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-
ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 6f1beca86b2b..95cffb771a62 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/module.h>
@@ -32,6 +28,7 @@
#include <linux/videodev2.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
#include "go7007-priv.h"
@@ -224,7 +221,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
return 0;
}
- printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type);
+ pr_info("go7007: probing for module i2c:%s failed\n", i2c->type);
return -EINVAL;
}
@@ -332,20 +329,33 @@ EXPORT_SYMBOL(go7007_register_encoder);
int go7007_start_encoder(struct go7007 *go)
{
u8 *fw;
- int fw_len, rv = 0, i;
+ int fw_len, rv = 0, i, x, y;
u16 intr_val, intr_data;
go->modet_enable = 0;
- if (!go->dvd_mode)
- for (i = 0; i < 4; ++i) {
- if (go->modet[i].enable) {
- go->modet_enable = 1;
- continue;
+ for (i = 0; i < 4; i++)
+ go->modet[i].enable = 0;
+
+ switch (v4l2_ctrl_g_ctrl(go->modet_mode)) {
+ case V4L2_DETECT_MD_MODE_GLOBAL:
+ memset(go->modet_map, 0, sizeof(go->modet_map));
+ go->modet[0].enable = 1;
+ go->modet_enable = 1;
+ break;
+ case V4L2_DETECT_MD_MODE_REGION_GRID:
+ for (y = 0; y < go->height / 16; y++) {
+ for (x = 0; x < go->width / 16; x++) {
+ int idx = y * go->width / 16 + x;
+
+ go->modet[go->modet_map[idx]].enable = 1;
}
- go->modet[i].pixel_threshold = 32767;
- go->modet[i].motion_threshold = 32767;
- go->modet[i].mb_threshold = 32767;
}
+ go->modet_enable = 1;
+ break;
+ }
+
+ if (go->dvd_mode)
+ go->modet_enable = 0;
if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
return -1;
@@ -383,44 +393,89 @@ static inline void store_byte(struct go7007_buffer *vb, u8 byte)
}
}
+static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *vb,
+ u32 motion_regions)
+{
+ if (motion_regions != go->modet_event_status) {
+ struct v4l2_event ev = {
+ .type = V4L2_EVENT_MOTION_DET,
+ .u.motion_det = {
+ .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
+ .frame_sequence = vb->vb.v4l2_buf.sequence,
+ .region_mask = motion_regions,
+ },
+ };
+
+ v4l2_event_queue(&go->vdev, &ev);
+ go->modet_event_status = motion_regions;
+ }
+}
+
/*
- * Deliver the last video buffer and get a new one to start writing to.
+ * Determine regions with motion and send a motion detection event
+ * in case of changes.
*/
-static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
+static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb)
{
- struct go7007_buffer *vb_tmp = NULL;
u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
+ unsigned motion[4] = { 0, 0, 0, 0 };
+ u32 motion_regions = 0;
+ unsigned stride = (go->width + 7) >> 3;
+ unsigned x, y;
int i;
- if (vb) {
- if (vb->modet_active) {
- if (*bytesused + 216 < GO7007_BUF_SIZE) {
- for (i = 0; i < 216; ++i)
- store_byte(vb, go->active_map[i]);
- *bytesused -= 216;
- } else
- vb->modet_active = 0;
+ for (i = 0; i < 216; ++i)
+ store_byte(vb, go->active_map[i]);
+ for (y = 0; y < go->height / 16; y++) {
+ for (x = 0; x < go->width / 16; x++) {
+ if (!(go->active_map[y * stride + (x >> 3)] & (1 << (x & 7))))
+ continue;
+ motion[go->modet_map[y * (go->width / 16) + x]]++;
}
- vb->vb.v4l2_buf.sequence = go->next_seq++;
- v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
- vb_tmp = vb;
+ }
+ motion_regions = ((motion[0] > 0) << 0) |
+ ((motion[1] > 0) << 1) |
+ ((motion[2] > 0) << 2) |
+ ((motion[3] > 0) << 3);
+ *bytesused -= 216;
+ go7007_set_motion_regions(go, vb, motion_regions);
+}
+
+/*
+ * Deliver the last video buffer and get a new one to start writing to.
+ */
+static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
+{
+ u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
+ struct go7007_buffer *vb_tmp = NULL;
+
+ if (vb == NULL) {
spin_lock(&go->spinlock);
- list_del(&vb->list);
- if (list_empty(&go->vidq_active))
- vb = NULL;
- else
- vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list);
- go->active_buf = vb;
+ if (!list_empty(&go->vidq_active))
+ vb = go->active_buf =
+ list_first_entry(&go->vidq_active, struct go7007_buffer, list);
spin_unlock(&go->spinlock);
- vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE);
+ go->next_seq++;
return vb;
}
+
+ vb->vb.v4l2_buf.sequence = go->next_seq++;
+ if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE)
+ go7007_motion_regions(go, vb);
+ else
+ go7007_set_motion_regions(go, vb, 0);
+
+ v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
+ vb_tmp = vb;
spin_lock(&go->spinlock);
- if (!list_empty(&go->vidq_active))
- vb = go->active_buf =
- list_first_entry(&go->vidq_active, struct go7007_buffer, list);
+ list_del(&vb->list);
+ if (list_empty(&go->vidq_active))
+ vb = NULL;
+ else
+ vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list);
+ go->active_buf = vb;
spin_unlock(&go->spinlock);
- go->next_seq++;
+ vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE);
return vb;
}
diff --git a/drivers/staging/media/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
index 814ce08bc44d..5f4c9b9e899a 100644
--- a/drivers/staging/media/go7007/go7007-fw.c
+++ b/drivers/media/usb/go7007/go7007-fw.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
/*
@@ -1432,22 +1428,26 @@ static int audio_to_package(struct go7007 *go, __le16 *code, int space)
static int modet_to_package(struct go7007 *go, __le16 *code, int space)
{
+ bool has_modet0 = go->modet[0].enable;
+ bool has_modet1 = go->modet[1].enable;
+ bool has_modet2 = go->modet[2].enable;
+ bool has_modet3 = go->modet[3].enable;
int ret, mb, i, addr, cnt = 0;
u16 pack[32];
u16 thresholds[] = {
0x200e, 0,
- 0xbf82, go->modet[0].pixel_threshold,
- 0xbf83, go->modet[1].pixel_threshold,
- 0xbf84, go->modet[2].pixel_threshold,
- 0xbf85, go->modet[3].pixel_threshold,
- 0xbf86, go->modet[0].motion_threshold,
- 0xbf87, go->modet[1].motion_threshold,
- 0xbf88, go->modet[2].motion_threshold,
- 0xbf89, go->modet[3].motion_threshold,
- 0xbf8a, go->modet[0].mb_threshold,
- 0xbf8b, go->modet[1].mb_threshold,
- 0xbf8c, go->modet[2].mb_threshold,
- 0xbf8d, go->modet[3].mb_threshold,
+ 0xbf82, has_modet0 ? go->modet[0].pixel_threshold : 32767,
+ 0xbf83, has_modet1 ? go->modet[1].pixel_threshold : 32767,
+ 0xbf84, has_modet2 ? go->modet[2].pixel_threshold : 32767,
+ 0xbf85, has_modet3 ? go->modet[3].pixel_threshold : 32767,
+ 0xbf86, has_modet0 ? go->modet[0].motion_threshold : 32767,
+ 0xbf87, has_modet1 ? go->modet[1].motion_threshold : 32767,
+ 0xbf88, has_modet2 ? go->modet[2].motion_threshold : 32767,
+ 0xbf89, has_modet3 ? go->modet[3].motion_threshold : 32767,
+ 0xbf8a, has_modet0 ? go->modet[0].mb_threshold : 32767,
+ 0xbf8b, has_modet1 ? go->modet[1].mb_threshold : 32767,
+ 0xbf8c, has_modet2 ? go->modet[2].mb_threshold : 32767,
+ 0xbf8d, has_modet3 ? go->modet[3].mb_threshold : 32767,
0xbf8e, 0,
0xbf8f, 0,
0, 0,
diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/media/usb/go7007/go7007-i2c.c
index 4cf4c0d65085..55addfa855d4 100644
--- a/drivers/staging/media/go7007/go7007-i2c.c
+++ b/drivers/media/usb/go7007/go7007-i2c.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/module.h>
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/media/usb/go7007/go7007-loader.c
index 491d0e697f5a..042f78a31283 100644
--- a/drivers/staging/media/go7007/go7007-loader.c
+++ b/drivers/media/usb/go7007/go7007-loader.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/module.h>
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/media/usb/go7007/go7007-priv.h
index 6e16af720504..2251c3f99d1d 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/media/usb/go7007/go7007-priv.h
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
/*
@@ -75,6 +71,20 @@ struct go7007;
#define GO7007_AUDIO_I2S_MASTER (1<<16)
#define GO7007_AUDIO_OKI_MODE (1<<17)
+#define GO7007_CID_CUSTOM_BASE (V4L2_CID_DETECT_CLASS_BASE + 0x1000)
+#define V4L2_CID_PIXEL_THRESHOLD0 (GO7007_CID_CUSTOM_BASE+1)
+#define V4L2_CID_MOTION_THRESHOLD0 (GO7007_CID_CUSTOM_BASE+2)
+#define V4L2_CID_MB_THRESHOLD0 (GO7007_CID_CUSTOM_BASE+3)
+#define V4L2_CID_PIXEL_THRESHOLD1 (GO7007_CID_CUSTOM_BASE+4)
+#define V4L2_CID_MOTION_THRESHOLD1 (GO7007_CID_CUSTOM_BASE+5)
+#define V4L2_CID_MB_THRESHOLD1 (GO7007_CID_CUSTOM_BASE+6)
+#define V4L2_CID_PIXEL_THRESHOLD2 (GO7007_CID_CUSTOM_BASE+7)
+#define V4L2_CID_MOTION_THRESHOLD2 (GO7007_CID_CUSTOM_BASE+8)
+#define V4L2_CID_MB_THRESHOLD2 (GO7007_CID_CUSTOM_BASE+9)
+#define V4L2_CID_PIXEL_THRESHOLD3 (GO7007_CID_CUSTOM_BASE+10)
+#define V4L2_CID_MOTION_THRESHOLD3 (GO7007_CID_CUSTOM_BASE+11)
+#define V4L2_CID_MB_THRESHOLD3 (GO7007_CID_CUSTOM_BASE+12)
+
struct go7007_board_info {
unsigned int flags;
int hpi_buffer_cap;
@@ -168,6 +178,7 @@ struct go7007 {
struct v4l2_ctrl *mpeg_video_aspect_ratio;
struct v4l2_ctrl *mpeg_video_b_frames;
struct v4l2_ctrl *mpeg_video_rep_seqheader;
+ struct v4l2_ctrl *modet_mode;
enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
spinlock_t spinlock;
struct mutex hw_lock;
@@ -216,6 +227,7 @@ struct go7007 {
} modet[4];
unsigned char modet_map[1624];
unsigned char active_map[216];
+ u32 modet_event_status;
/* Video streaming */
struct mutex queue_lock;
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c
index 2f62be905cd1..ece27ece8115 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/media/usb/go7007/go7007-usb.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c
index da7b5493e13e..ec799b4d88be 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/media/usb/go7007/go7007-v4l2.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/module.h>
@@ -36,7 +32,6 @@
#include <media/videobuf2-vmalloc.h>
#include <media/saa7115.h>
-#include "go7007.h"
#include "go7007-priv.h"
#define call_all(dev, o, f, args...) \
@@ -189,7 +184,7 @@ static void set_formatting(struct go7007 *go)
static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
{
int sensor_height = 0, sensor_width = 0;
- int width, height, i;
+ int width, height;
if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
return -EINVAL;
@@ -253,10 +248,6 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
go->height = height;
go->encoder_h_offset = go->board_info->sensor_h_offset;
go->encoder_v_offset = go->board_info->sensor_v_offset;
- for (i = 0; i < 4; ++i)
- go->modet[i].enable = 0;
- for (i = 0; i < 1624; ++i)
- go->modet_map[i] = 0;
if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
struct v4l2_mbus_framefmt mbus_fmt;
@@ -286,64 +277,6 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
return 0;
}
-#if 0
-static int clip_to_modet_map(struct go7007 *go, int region,
- struct v4l2_clip *clip_list)
-{
- struct v4l2_clip clip, *clip_ptr;
- int x, y, mbnum;
-
- /* Check if coordinates are OK and if any macroblocks are already
- * used by other regions (besides 0) */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- if (clip.c.left < 0 || (clip.c.left & 0xF) ||
- clip.c.width <= 0 || (clip.c.width & 0xF))
- return -EINVAL;
- if (clip.c.left + clip.c.width > go->width)
- return -EINVAL;
- if (clip.c.top < 0 || (clip.c.top & 0xF) ||
- clip.c.height <= 0 || (clip.c.height & 0xF))
- return -EINVAL;
- if (clip.c.top + clip.c.height > go->height)
- return -EINVAL;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- if (go->modet_map[mbnum] != 0 &&
- go->modet_map[mbnum] != region)
- return -EBUSY;
- }
- clip_ptr = clip.next;
- }
-
- /* Clear old region macroblocks */
- for (mbnum = 0; mbnum < 1624; ++mbnum)
- if (go->modet_map[mbnum] == region)
- go->modet_map[mbnum] = 0;
-
- /* Claim macroblocks in this list */
- clip_ptr = clip_list;
- while (clip_ptr) {
- if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
- return -EFAULT;
- for (y = 0; y < clip.c.height; y += 16)
- for (x = 0; x < clip.c.width; x += 16) {
- mbnum = (go->width >> 4) *
- ((clip.c.top + y) >> 4) +
- ((clip.c.left + x) >> 4);
- go->modet_map[mbnum] = region;
- }
- clip_ptr = clip.next;
- }
- return 0;
-}
-#endif
-
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@@ -495,6 +428,7 @@ static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
mutex_lock(&go->hw_lock);
go->next_seq = 0;
go->active_buf = NULL;
+ go->modet_event_status = 0;
q->streaming = 1;
if (go7007_start_encoder(go) < 0)
ret = -EIO;
@@ -850,41 +784,76 @@ static int vidioc_log_status(struct file *file, void *priv)
return call_all(&go->v4l2_dev, core, log_status);
}
-/* FIXME:
- Those ioctls are private, and not needed, since several standard
- extended controls already provide streaming control.
- So, those ioctls should be converted into vidioc_g_ext_ctrls()
- and vidioc_s_ext_ctrls()
- */
-
-#if 0
- case GO7007IOC_S_MD_PARAMS:
- {
- struct go7007_md_params *mdp = arg;
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
- if (mdp->region > 3)
- return -EINVAL;
- if (mdp->trigger > 0) {
- go->modet[mdp->region].pixel_threshold =
- mdp->pixel_threshold >> 1;
- go->modet[mdp->region].motion_threshold =
- mdp->motion_threshold >> 1;
- go->modet[mdp->region].mb_threshold =
- mdp->trigger >> 1;
- go->modet[mdp->region].enable = 1;
- } else
- go->modet[mdp->region].enable = 0;
- /* fall-through */
+ switch (sub->type) {
+ case V4L2_EVENT_CTRL:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+ case V4L2_EVENT_MOTION_DET:
+ /* Allow for up to 30 events (1 second for NTSC) to be
+ * stored. */
+ return v4l2_event_subscribe(fh, sub, 30, NULL);
}
- case GO7007IOC_S_MD_REGION:
- {
- struct go7007_md_region *region = arg;
+ return -EINVAL;
+}
- if (region->region < 1 || region->region > 3)
- return -EINVAL;
- return clip_to_modet_map(go, region->region, region->clips);
+
+static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct go7007 *go =
+ container_of(ctrl->handler, struct go7007, hdl);
+ unsigned y;
+ u8 *mt;
+
+ switch (ctrl->id) {
+ case V4L2_CID_PIXEL_THRESHOLD0:
+ go->modet[0].pixel_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MOTION_THRESHOLD0:
+ go->modet[0].motion_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MB_THRESHOLD0:
+ go->modet[0].mb_threshold = ctrl->val;
+ break;
+ case V4L2_CID_PIXEL_THRESHOLD1:
+ go->modet[1].pixel_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MOTION_THRESHOLD1:
+ go->modet[1].motion_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MB_THRESHOLD1:
+ go->modet[1].mb_threshold = ctrl->val;
+ break;
+ case V4L2_CID_PIXEL_THRESHOLD2:
+ go->modet[2].pixel_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MOTION_THRESHOLD2:
+ go->modet[2].motion_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MB_THRESHOLD2:
+ go->modet[2].mb_threshold = ctrl->val;
+ break;
+ case V4L2_CID_PIXEL_THRESHOLD3:
+ go->modet[3].pixel_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MOTION_THRESHOLD3:
+ go->modet[3].motion_threshold = ctrl->val;
+ break;
+ case V4L2_CID_MB_THRESHOLD3:
+ go->modet[3].mb_threshold = ctrl->val;
+ break;
+ case V4L2_CID_DETECT_MD_REGION_GRID:
+ mt = go->modet_map;
+ for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
+ memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
+ break;
+ default:
+ return -EINVAL;
}
-#endif
+ return 0;
+}
static struct v4l2_file_operations go7007_fops = {
.owner = THIS_MODULE,
@@ -926,7 +895,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_enum_framesizes = vidioc_enum_framesizes,
.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
.vidioc_log_status = vidioc_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_subscribe_event = vidioc_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
@@ -938,12 +907,144 @@ static struct video_device go7007_template = {
.tvnorms = V4L2_STD_ALL,
};
+static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
+ .s_ctrl = go7007_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_PIXEL_THRESHOLD0,
+ .name = "Pixel Threshold Region 0",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 20,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MOTION_THRESHOLD0,
+ .name = "Motion Threshold Region 0",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 80,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MB_THRESHOLD0,
+ .name = "MB Threshold Region 0",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 200,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_PIXEL_THRESHOLD1,
+ .name = "Pixel Threshold Region 1",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 20,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MOTION_THRESHOLD1,
+ .name = "Motion Threshold Region 1",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 80,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MB_THRESHOLD1,
+ .name = "MB Threshold Region 1",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 200,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_PIXEL_THRESHOLD2,
+ .name = "Pixel Threshold Region 2",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 20,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MOTION_THRESHOLD2,
+ .name = "Motion Threshold Region 2",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 80,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MB_THRESHOLD2,
+ .name = "MB Threshold Region 2",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 200,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_PIXEL_THRESHOLD3,
+ .name = "Pixel Threshold Region 3",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 20,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MOTION_THRESHOLD3,
+ .name = "Motion Threshold Region 3",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 80,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_MB_THRESHOLD3,
+ .name = "MB Threshold Region 3",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .def = 200,
+ .max = 32767,
+ .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
+ .ops = &go7007_ctrl_ops,
+ .id = V4L2_CID_DETECT_MD_REGION_GRID,
+ .dims = { 576 / 16, 720 / 16 },
+ .max = 3,
+ .step = 1,
+};
+
int go7007_v4l2_ctrl_init(struct go7007 *go)
{
struct v4l2_ctrl_handler *hdl = &go->hdl;
struct v4l2_ctrl *ctrl;
- v4l2_ctrl_handler_init(hdl, 13);
+ v4l2_ctrl_handler_init(hdl, 22);
go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
@@ -968,6 +1069,24 @@ int go7007_v4l2_ctrl_init(struct go7007 *go)
V4L2_JPEG_ACTIVE_MARKER_DHT);
if (ctrl)
ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
+ v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
+ go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
+ V4L2_CID_DETECT_MD_MODE,
+ V4L2_DETECT_MD_MODE_REGION_GRID,
+ 1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
+ V4L2_DETECT_MD_MODE_DISABLED);
if (hdl->error) {
int rv = hdl->error;
@@ -1001,7 +1120,6 @@ int go7007_v4l2_init(struct go7007 *go)
*vdev = go7007_template;
vdev->lock = &go->serialize_lock;
vdev->queue = &go->vidq;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
video_set_drvdata(vdev, go);
vdev->v4l2_dev = &go->v4l2_dev;
if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
index eaa2b0990a1b..bb846680bcd4 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/media/usb/go7007/s2250-board.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/module.h>
@@ -573,11 +569,12 @@ static int s2250_probe(struct i2c_client *client,
if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
data = kzalloc(16, GFP_KERNEL);
if (data != NULL) {
- int rc;
- rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
+ int rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
data, 16, 1);
+
if (rc > 0) {
u8 mask;
+
data[0] = 0;
mask = 1<<5;
data[0] &= ~mask;
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c
index 9eb2a20ae40a..d22d7d574672 100644
--- a/drivers/staging/media/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c
@@ -9,10 +9,6 @@
* 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
#include <linux/kernel.h>
diff --git a/drivers/media/usb/gspca/autogain_functions.c b/drivers/media/usb/gspca/autogain_functions.c
index 67db674bb044..0e9ee8b50bb7 100644
--- a/drivers/media/usb/gspca/autogain_functions.c
+++ b/drivers/media/usb/gspca/autogain_functions.c
@@ -121,9 +121,9 @@ int gspca_coarse_grained_expo_autogain(
orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
- gain_low = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
+ gain_low = (s32)(gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
5 * 2 + gspca_dev->gain->minimum;
- gain_high = (gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
+ gain_high = (s32)(gspca_dev->gain->maximum - gspca_dev->gain->minimum) /
5 * 4 + gspca_dev->gain->minimum;
/* If we are of a multiple of deadzone, do multiple steps to reach the
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index f3a7ace0fac9..e8cf23c91cef 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -603,10 +603,13 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
}
/*
- * look for an input transfer endpoint in an alternate setting
+ * look for an input transfer endpoint in an alternate setting.
+ *
+ * If xfer_ep is invalid, return the first valid ep found, otherwise
+ * look for exactly the ep with address equal to xfer_ep.
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- int xfer)
+ int xfer, int xfer_ep)
{
struct usb_host_endpoint *ep;
int i, attr;
@@ -616,7 +619,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
if (attr == xfer
&& ep->desc.wMaxPacketSize != 0
- && usb_endpoint_dir_in(&ep->desc))
+ && usb_endpoint_dir_in(&ep->desc)
+ && (xfer_ep < 0 || ep->desc.bEndpointAddress == xfer_ep))
return ep;
}
return NULL;
@@ -689,7 +693,8 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
found = 0;
for (j = 0; j < nbalt; j++) {
ep = alt_xfer(&intf->altsetting[j],
- USB_ENDPOINT_XFER_ISOC);
+ USB_ENDPOINT_XFER_ISOC,
+ gspca_dev->xfer_ep);
if (ep == NULL)
continue;
if (ep->desc.bInterval == 0) {
@@ -862,7 +867,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* if bulk or the subdriver forced an altsetting, get the endpoint */
if (gspca_dev->alt != 0) {
gspca_dev->alt--; /* (previous version compatibility) */
- ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer);
+ ep = alt_xfer(&intf->altsetting[gspca_dev->alt], xfer,
+ gspca_dev->xfer_ep);
if (ep == NULL) {
pr_err("bad altsetting %d\n", gspca_dev->alt);
return -EIO;
@@ -904,7 +910,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (!gspca_dev->cam.no_urb_create) {
PDEBUG(D_STREAM, "init transfer alt %d", alt);
ret = create_urbs(gspca_dev,
- alt_xfer(&intf->altsetting[alt], xfer));
+ alt_xfer(&intf->altsetting[alt], xfer,
+ gspca_dev->xfer_ep));
if (ret < 0) {
destroy_urbs(gspca_dev);
goto out;
@@ -1102,8 +1109,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct gspca_dev *gspca_dev = video_drvdata(file);
fmt->fmt.pix = gspca_dev->pixfmt;
- /* some drivers use priv internally, zero it before giving it to
- userspace */
+ /* some drivers use priv internally, zero it before giving it back to
+ the core */
fmt->fmt.pix.priv = 0;
return 0;
}
@@ -1139,8 +1146,8 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
fmt->fmt.pix.height = h;
gspca_dev->sd_desc->try_fmt(gspca_dev, fmt);
}
- /* some drivers use priv internally, zero it before giving it to
- userspace */
+ /* some drivers use priv internally, zero it before giving it back to
+ the core */
fmt->fmt.pix.priv = 0;
return mode; /* used when s_fmt */
}
@@ -2030,6 +2037,7 @@ int gspca_dev_probe2(struct usb_interface *intf,
}
gspca_dev->dev = dev;
gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;
+ gspca_dev->xfer_ep = -1;
/* check if any audio device */
if (dev->actconfig->desc.bNumInterfaces != 1) {
@@ -2058,7 +2066,6 @@ int gspca_dev_probe2(struct usb_interface *intf,
gspca_dev->vdev = gspca_template;
gspca_dev->vdev.v4l2_dev = &gspca_dev->v4l2_dev;
video_set_drvdata(&gspca_dev->vdev, gspca_dev);
- set_bit(V4L2_FL_USE_FH_PRIO, &gspca_dev->vdev.flags);
gspca_dev->module = module;
gspca_dev->present = 1;
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index 300642dc1a17..f06253cd7469 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -205,6 +205,7 @@ struct gspca_dev {
char memory; /* memory type (V4L2_MEMORY_xxx) */
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
+ int xfer_ep; /* USB transfer endpoint address */
u8 audio; /* presence of audio device */
/* (*) These variables are proteced by both usb_lock and queue_lock,
diff --git a/drivers/media/usb/gspca/kinect.c b/drivers/media/usb/gspca/kinect.c
index 081f05162809..45bc1f51c5d8 100644
--- a/drivers/media/usb/gspca/kinect.c
+++ b/drivers/media/usb/gspca/kinect.c
@@ -36,6 +36,8 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
MODULE_LICENSE("GPL");
+static bool depth_mode;
+
struct pkt_hdr {
uint8_t magic[2];
uint8_t pad;
@@ -73,6 +75,14 @@ struct sd {
#define FPS_HIGH 0x0100
+static const struct v4l2_pix_format depth_camera_mode[] = {
+ {640, 480, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 10 / 8,
+ .sizeimage = 640 * 480 * 10 / 8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = MODE_640x488 | FORMAT_Y10B},
+};
+
static const struct v4l2_pix_format video_camera_mode[] = {
{640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
.bytesperline = 640,
@@ -219,7 +229,7 @@ static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
}
/* this function is called at probe time */
-static int sd_config(struct gspca_dev *gspca_dev,
+static int sd_config_video(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -227,8 +237,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->cam_tag = 0;
- /* Only video stream is supported for now,
- * which has stream flag = 0x80 */
sd->stream_flag = 0x80;
cam = &gspca_dev->cam;
@@ -236,6 +244,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = video_camera_mode;
cam->nmodes = ARRAY_SIZE(video_camera_mode);
+ gspca_dev->xfer_ep = 0x81;
+
#if 0
/* Setting those values is not needed for video stream */
cam->npkt = 15;
@@ -245,6 +255,26 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
+static int sd_config_depth(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ sd->cam_tag = 0;
+
+ sd->stream_flag = 0x70;
+
+ cam = &gspca_dev->cam;
+
+ cam->cam_mode = depth_camera_mode;
+ cam->nmodes = ARRAY_SIZE(depth_camera_mode);
+
+ gspca_dev->xfer_ep = 0x82;
+
+ return 0;
+}
+
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
@@ -253,7 +283,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static int sd_start(struct gspca_dev *gspca_dev)
+static int sd_start_video(struct gspca_dev *gspca_dev)
{
int mode;
uint8_t fmt_reg, fmt_val;
@@ -325,12 +355,39 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
-static void sd_stopN(struct gspca_dev *gspca_dev)
+static int sd_start_depth(struct gspca_dev *gspca_dev)
+{
+ /* turn off IR-reset function */
+ write_register(gspca_dev, 0x105, 0x00);
+
+ /* reset depth stream */
+ write_register(gspca_dev, 0x06, 0x00);
+ /* Depth Stream Format 0x03: 11 bit stream | 0x02: 10 bit */
+ write_register(gspca_dev, 0x12, 0x02);
+ /* Depth Stream Resolution 1: standard (640x480) */
+ write_register(gspca_dev, 0x13, 0x01);
+ /* Depth Framerate / 0x1e (30): 30 fps */
+ write_register(gspca_dev, 0x14, 0x1e);
+ /* Depth Stream Control / 2: Open Depth Stream */
+ write_register(gspca_dev, 0x06, 0x02);
+ /* disable depth hflip / LSB = 0: Smoothing Disabled */
+ write_register(gspca_dev, 0x17, 0x00);
+
+ return 0;
+}
+
+static void sd_stopN_video(struct gspca_dev *gspca_dev)
{
/* reset video stream */
write_register(gspca_dev, 0x05, 0x00);
}
+static void sd_stopN_depth(struct gspca_dev *gspca_dev)
+{
+ /* reset depth stream */
+ write_register(gspca_dev, 0x06, 0x00);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -366,12 +423,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
}
/* sub-driver description */
-static const struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc_video = {
.name = MODULE_NAME,
- .config = sd_config,
+ .config = sd_config_video,
.init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
+ .start = sd_start_video,
+ .stopN = sd_stopN_video,
+ .pkt_scan = sd_pkt_scan,
+ /*
+ .get_streamparm = sd_get_streamparm,
+ .set_streamparm = sd_set_streamparm,
+ */
+};
+static const struct sd_desc sd_desc_depth = {
+ .name = MODULE_NAME,
+ .config = sd_config_depth,
+ .init = sd_init,
+ .start = sd_start_depth,
+ .stopN = sd_stopN_depth,
.pkt_scan = sd_pkt_scan,
/*
.get_streamparm = sd_get_streamparm,
@@ -391,8 +460,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
- THIS_MODULE);
+ if (depth_mode)
+ return gspca_dev_probe(intf, id, &sd_desc_depth,
+ sizeof(struct sd), THIS_MODULE);
+ else
+ return gspca_dev_probe(intf, id, &sd_desc_video,
+ sizeof(struct sd), THIS_MODULE);
}
static struct usb_driver sd_driver = {
@@ -408,3 +481,6 @@ static struct usb_driver sd_driver = {
};
module_usb_driver(sd_driver);
+
+module_param(depth_mode, bool, 0644);
+MODULE_PARM_DESC(depth_mode, "0=video 1=depth");
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 2fd1c5e31a0f..8b08bd0172f4 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -394,9 +394,9 @@ static void setbrightcont(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
for (i = 0; i < 10; i++) {
v = max[i];
- v += (sd->brightness->val - sd->brightness->maximum)
- * 150 / sd->brightness->maximum; /* 200 ? */
- v -= delta[i] * sd->contrast->val / sd->contrast->maximum;
+ v += (sd->brightness->val - (s32)sd->brightness->maximum)
+ * 150 / (s32)sd->brightness->maximum; /* 200 ? */
+ v -= delta[i] * sd->contrast->val / (s32)sd->contrast->maximum;
if (v < 0)
v = 0;
else if (v > 0xff)
@@ -419,7 +419,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x11, 0x01);
reg_w(gspca_dev, 0xff, 0x00); /* page 0 */
for (i = 0; i < 9; i++) {
- v = a[i] * sd->saturation->val / sd->saturation->maximum;
+ v = a[i] * sd->saturation->val / (s32)sd->saturation->maximum;
v += b[i];
reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
@@ -928,6 +928,7 @@ static const struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2620)},
{USB_DEVICE(0x093a, 0x2621)},
{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
+ {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
{USB_DEVICE(0x093a, 0x2625)},
{USB_DEVICE(0x093a, 0x2626)},
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
index ecbcb39feb71..6696b2ec34e9 100644
--- a/drivers/media/usb/gspca/sonixb.c
+++ b/drivers/media/usb/gspca/sonixb.c
@@ -913,7 +913,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
desired_avg_lum, deadzone))
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
} else {
- int gain_knee = gspca_dev->gain->maximum * 9 / 10;
+ int gain_knee = (s32)gspca_dev->gain->maximum * 9 / 10;
if (gspca_expo_autogain(gspca_dev, avg_lum, desired_avg_lum,
deadzone, gain_knee, sd->exposure_knee))
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 0500c4175d5f..59d15fd242ba 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -82,7 +82,7 @@ static void hdpvr_read_bulk_callback(struct urb *urb)
}
/*=========================================================================*/
-/* bufffer bits */
+/* buffer bits */
/* function expects dev->io_mutex to be hold by caller */
int hdpvr_cancel_queue(struct hdpvr_device *dev)
@@ -926,7 +926,7 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_AUDIO_ENCODING:
if (dev->flags & HDPVR_FLAG_AC3_CAP) {
opt->audio_codec = ctrl->val;
- return hdpvr_set_audio(dev, opt->audio_input,
+ return hdpvr_set_audio(dev, opt->audio_input + 1,
opt->audio_codec);
}
return 0;
@@ -1022,14 +1022,13 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = dev->bulk_in_size;
f->fmt.pix.bytesperline = 0;
- f->fmt.pix.priv = 0;
if (f->fmt.pix.width == 720) {
/* SDTV formats */
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
} else {
/* HDTV formats */
- f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE240M;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
f->fmt.pix.field = V4L2_FIELD_NONE;
}
return 0;
@@ -1198,7 +1197,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
V4L2_CID_MPEG_AUDIO_ENCODING,
ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
- 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
+ 0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
V4L2_CID_MPEG_VIDEO_ENCODING,
V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
@@ -1240,7 +1239,6 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
strcpy(dev->video_dev->name, "Hauppauge HD PVR");
dev->video_dev->v4l2_dev = &dev->v4l2_dev;
video_set_drvdata(dev->video_dev, dev);
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->video_dev->flags);
res = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum);
if (res < 0) {
diff --git a/drivers/media/usb/msi2500/Kconfig b/drivers/media/usb/msi2500/Kconfig
new file mode 100644
index 000000000000..9eff8a76ff0e
--- /dev/null
+++ b/drivers/media/usb/msi2500/Kconfig
@@ -0,0 +1,5 @@
+config USB_MSI2500
+ tristate "Mirics MSi2500"
+ depends on VIDEO_V4L2 && SPI
+ select VIDEOBUF2_VMALLOC
+ select MEDIA_TUNER_MSI001
diff --git a/drivers/media/usb/msi2500/Makefile b/drivers/media/usb/msi2500/Makefile
new file mode 100644
index 000000000000..b3bc2e53707f
--- /dev/null
+++ b/drivers/media/usb/msi2500/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_MSI2500) += msi2500.o
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/media/usb/msi2500/msi2500.c
index 08d0d096b881..26b133414032 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -34,6 +34,10 @@
#include <media/videobuf2-vmalloc.h>
#include <linux/spi/spi.h>
+static bool msi2500_emulated_fmt;
+module_param_named(emulated_formats, msi2500_emulated_fmt, bool, 0644);
+MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)");
+
/*
* iConfiguration 0
* bInterfaceNumber 0
@@ -51,11 +55,14 @@
#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
#define MAX_ISOC_ERRORS 20
-/* TODO: These should be moved to V4L2 API */
-#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
-#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
-#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
-#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
+/*
+ * TODO: These formats should be moved to V4L2 API. Formats are currently
+ * disabled from formats[] table, not visible to userspace.
+ */
+ /* signed 12-bit */
+#define MSI2500_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2')
+/* Mirics MSi2500 format 384 */
+#define MSI2500_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4')
static const struct v4l2_frequency_band bands[] = {
{
@@ -69,45 +76,50 @@ static const struct v4l2_frequency_band bands[] = {
};
/* stream formats */
-struct msi3101_format {
+struct msi2500_format {
char *name;
u32 pixelformat;
+ u32 buffersize;
};
/* format descriptions for capture and preview */
-static struct msi3101_format formats[] = {
+static struct msi2500_format formats[] = {
{
- .name = "IQ U8",
- .pixelformat = V4L2_SDR_FMT_CU8,
- }, {
- .name = "IQ U16LE",
- .pixelformat = V4L2_SDR_FMT_CU16LE,
+ .name = "Complex S8",
+ .pixelformat = V4L2_SDR_FMT_CS8,
+ .buffersize = 3 * 1008,
#if 0
}, {
- .name = "8-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S8,
- }, {
.name = "10+2-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_MSI2500_384,
+ .pixelformat = MSI2500_PIX_FMT_SDR_MSI2500_384,
}, {
.name = "12-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S12,
- }, {
- .name = "14-bit signed",
- .pixelformat = V4L2_PIX_FMT_SDR_S14,
+ .pixelformat = MSI2500_PIX_FMT_SDR_S12,
#endif
+ }, {
+ .name = "Complex S14LE",
+ .pixelformat = V4L2_SDR_FMT_CS14LE,
+ .buffersize = 3 * 1008,
+ }, {
+ .name = "Complex U8 (emulated)",
+ .pixelformat = V4L2_SDR_FMT_CU8,
+ .buffersize = 3 * 1008,
+ }, {
+ .name = "Complex U16LE (emulated)",
+ .pixelformat = V4L2_SDR_FMT_CU16LE,
+ .buffersize = 3 * 1008,
},
};
static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
-struct msi3101_frame_buf {
+struct msi2500_frame_buf {
struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
struct list_head list;
};
-struct msi3101_state {
+struct msi2500_state {
struct video_device vdev;
struct v4l2_device v4l2_dev;
struct v4l2_subdev *v4l2_subdev;
@@ -127,13 +139,13 @@ struct msi3101_state {
unsigned int f_adc;
u32 pixelformat;
+ u32 buffersize;
+ unsigned int num_formats;
unsigned int isoc_errors; /* number of contiguous ISOC errors */
unsigned int vb_full; /* vb is full and packets dropped */
struct urb *urbs[MAX_ISO_BUFS];
- int (*convert_stream)(struct msi3101_state *s, u8 *dst, u8 *src,
- unsigned int src_len);
/* Controls */
struct v4l2_ctrl_handler hdl;
@@ -145,17 +157,17 @@ struct msi3101_state {
};
/* Private functions */
-static struct msi3101_frame_buf *msi3101_get_next_fill_buf(
- struct msi3101_state *s)
+static struct msi2500_frame_buf *msi2500_get_next_fill_buf(
+ struct msi2500_state *s)
{
unsigned long flags = 0;
- struct msi3101_frame_buf *buf = NULL;
+ struct msi2500_frame_buf *buf = NULL;
spin_lock_irqsave(&s->queued_bufs_lock, flags);
if (list_empty(&s->queued_bufs))
goto leave;
- buf = list_entry(s->queued_bufs.next, struct msi3101_frame_buf, list);
+ buf = list_entry(s->queued_bufs.next, struct msi2500_frame_buf, list);
list_del(&buf->list);
leave:
spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
@@ -174,116 +186,8 @@ leave:
* +---------------------------------------------------------------------------
* signed 8-bit sample
* 504 * 2 = 1008 samples
- */
-static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 504 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 504) */
- s->next_sample = sample_num[i_max - 1] + 504;
-
- return dst_len;
-}
-
-static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, j, i_max, dst_len = 0;
- u32 sample_num[3];
- s8 *s8src;
- u8 *u8dst;
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
- u8dst = (u8 *) dst;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 504 x I+Q samples */
- src += 16;
-
- s8src = (s8 *) src;
- for (j = 0; j < 1008; j++)
- *u8dst++ = *s8src++ + 128;
-
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
- }
-
- /* next sample (sample = sample + i * 504) */
- s->next_sample = sample_num[i_max - 1] + 504;
-
- return dst_len;
-}
-
-/*
+ *
+ *
* +===========================================================================
* | 00-1023 | USB packet type '384'
* +===========================================================================
@@ -326,61 +230,8 @@ static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst,
* Number 2 (0b10) was never seen.
*
* 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
- */
-static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev,
- "%*ph %*ph\n", 12, &src[4], 24, &src[1000]);
-
- /* 384 x I+Q samples */
- src += 16;
- memcpy(dst, src, 984);
- src += 984 + 24;
- dst += 984;
- dst_len += 984;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu bits=%d.%d.%d.%d\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs,
- s->sample_ctrl_bit[0], s->sample_ctrl_bit[1],
- s->sample_ctrl_bit[2], s->sample_ctrl_bit[3]);
- }
-
- /* next sample (sample = sample + i * 384) */
- s->next_sample = sample_num[i_max - 1] + 384;
-
- return dst_len;
-}
-
-/*
+ *
+ *
* +===========================================================================
* | 00-1023 | USB packet type '336'
* +===========================================================================
@@ -391,59 +242,8 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
* | 16-1023 | samples
* +---------------------------------------------------------------------------
* signed 12-bit sample
- */
-static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
-
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 336 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 336) */
- s->next_sample = sample_num[i_max - 1] + 336;
-
- return dst_len;
-}
-
-/*
+ *
+ *
* +===========================================================================
* | 00-1023 | USB packet type '252'
* +===========================================================================
@@ -455,75 +255,24 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
* +---------------------------------------------------------------------------
* signed 14-bit sample
*/
-static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
-{
- int i, i_max, dst_len = 0;
- u32 sample_num[3];
-
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
-
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
- dev_dbg_ratelimited(&s->udev->dev,
- "%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
- }
- /*
- * Dump all unknown 'garbage' data - maybe we will discover
- * someday if there is something rational...
- */
- dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
-
- /* 252 x I+Q samples */
- src += 16;
- memcpy(dst, src, 1008);
- src += 1008;
- dst += 1008;
- dst_len += 1008;
- }
-
- /* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
- unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
- unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies_next = jiffies_now;
- s->sample = sample_num[i_max - 1];
- dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, msecs,
- samples * 1000UL / msecs);
- }
-
- /* next sample (sample = sample + i * 252) */
- s->next_sample = sample_num[i_max - 1] + 252;
-
- return dst_len;
-}
-
-static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
- u8 *src, unsigned int src_len)
+static int msi2500_convert_stream(struct msi2500_state *s, u8 *dst, u8 *src,
+ unsigned int src_len)
{
- int i, j, i_max, dst_len = 0;
- u32 sample_num[3];
- u16 *u16dst = (u16 *) dst;
- struct {signed int x:14;} se;
+ unsigned int i, j, transactions, dst_len = 0;
+ u32 sample[3];
- /* There could be 1-3 1024 bytes URB frames */
- i_max = src_len / 1024;
+ /* There could be 1-3 1024 byte transactions per packet */
+ transactions = src_len / 1024;
- for (i = 0; i < i_max; i++) {
- sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
- if (i == 0 && s->next_sample != sample_num[0]) {
+ for (i = 0; i < transactions; i++) {
+ sample[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 |
+ src[0] << 0;
+ if (i == 0 && s->next_sample != sample[0]) {
dev_dbg_ratelimited(&s->udev->dev,
"%d samples lost, %d %08x:%08x\n",
- sample_num[0] - s->next_sample,
- src_len, s->next_sample, sample_num[0]);
+ sample[0] - s->next_sample,
+ src_len, s->next_sample, sample[0]);
}
/*
@@ -532,49 +281,96 @@ static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
*/
dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
- /* 252 x I+Q samples */
- src += 16;
-
- for (j = 0; j < 1008; j += 4) {
- unsigned int usample[2];
- int ssample[2];
+ src += 16; /* skip header */
- usample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
- usample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
+ switch (s->pixelformat) {
+ case V4L2_SDR_FMT_CU8: /* 504 x IQ samples */
+ {
+ s8 *s8src = (s8 *) src;
+ u8 *u8dst = (u8 *) dst;
- /* sign extension from 14-bit to signed int */
- ssample[0] = se.x = usample[0];
- ssample[1] = se.x = usample[1];
+ for (j = 0; j < 1008; j++)
+ *u8dst++ = *s8src++ + 128;
- /* from signed to unsigned */
- usample[0] = ssample[0] + 8192;
- usample[1] = ssample[1] + 8192;
-
- /* from 14-bit to 16-bit */
- *u16dst++ = (usample[0] << 2) | (usample[0] >> 12);
- *u16dst++ = (usample[1] << 2) | (usample[1] >> 12);
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ s->next_sample = sample[i] + 504;
+ break;
}
+ case V4L2_SDR_FMT_CU16LE: /* 252 x IQ samples */
+ {
+ s16 *s16src = (s16 *) src;
+ u16 *u16dst = (u16 *) dst;
+ struct {signed int x:14; } se; /* sign extension */
+ unsigned int utmp;
+
+ for (j = 0; j < 1008; j += 2) {
+ /* sign extension from 14-bit to signed int */
+ se.x = *s16src++;
+ /* from signed int to unsigned int */
+ utmp = se.x + 8192;
+ /* from 14-bit to 16-bit */
+ *u16dst++ = utmp << 2 | utmp >> 12;
+ }
- src += 1008;
- dst += 1008;
- dst_len += 1008;
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ s->next_sample = sample[i] + 252;
+ break;
+ }
+ case MSI2500_PIX_FMT_SDR_MSI2500_384: /* 384 x IQ samples */
+ /* Dump unknown 'garbage' data */
+ dev_dbg_ratelimited(&s->udev->dev,
+ "%*ph\n", 24, &src[1000]);
+ memcpy(dst, src, 984);
+ src += 984 + 24;
+ dst += 984;
+ dst_len += 984;
+ s->next_sample = sample[i] + 384;
+ break;
+ case V4L2_SDR_FMT_CS8: /* 504 x IQ samples */
+ memcpy(dst, src, 1008);
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ s->next_sample = sample[i] + 504;
+ break;
+ case MSI2500_PIX_FMT_SDR_S12: /* 336 x IQ samples */
+ memcpy(dst, src, 1008);
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ s->next_sample = sample[i] + 336;
+ break;
+ case V4L2_SDR_FMT_CS14LE: /* 252 x IQ samples */
+ memcpy(dst, src, 1008);
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ s->next_sample = sample[i] + 252;
+ break;
+ default:
+ break;
+ }
}
- /* calculate samping rate and output it in 10 seconds intervals */
+ /* calculate sample rate and output it in 10 seconds intervals */
if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
-#define MSECS 10000UL
- unsigned int samples = sample_num[i_max - 1] - s->sample;
+ #define MSECS 10000UL
+ unsigned int msecs = jiffies_to_msecs(jiffies -
+ s->jiffies_next + msecs_to_jiffies(MSECS));
+ unsigned int samples = s->next_sample - s->sample;
+
s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
- s->sample = sample_num[i_max - 1];
+ s->sample = s->next_sample;
dev_dbg(&s->udev->dev,
- "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
- src_len, samples, MSECS,
- samples * 1000UL / MSECS);
+ "size=%u samples=%u msecs=%u sample rate=%lu\n",
+ src_len, samples, msecs,
+ samples * 1000UL / msecs);
}
- /* next sample (sample = sample + i * 252) */
- s->next_sample = sample_num[i_max - 1] + 252;
-
return dst_len;
}
@@ -582,12 +378,12 @@ static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
* This gets called for the Isochronous pipe (stream). This is done in interrupt
* time, so it has to be fast, not crash, and not stall. Neat.
*/
-static void msi3101_isoc_handler(struct urb *urb)
+static void msi2500_isoc_handler(struct urb *urb)
{
- struct msi3101_state *s = (struct msi3101_state *)urb->context;
+ struct msi2500_state *s = (struct msi2500_state *)urb->context;
int i, flen, fstatus;
unsigned char *iso_buf = NULL;
- struct msi3101_frame_buf *fbuf;
+ struct msi2500_frame_buf *fbuf;
if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN)) {
@@ -598,7 +394,7 @@ static void msi3101_isoc_handler(struct urb *urb)
if (unlikely(urb->status != 0)) {
dev_dbg(&s->udev->dev,
- "msi3101_isoc_handler() called with status %d\n",
+ "msi2500_isoc_handler() called with status %d\n",
urb->status);
/* Give up after a number of contiguous errors */
if (++s->isoc_errors > MAX_ISOC_ERRORS)
@@ -631,7 +427,7 @@ static void msi3101_isoc_handler(struct urb *urb)
iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
/* Get free framebuffer */
- fbuf = msi3101_get_next_fill_buf(s);
+ fbuf = msi2500_get_next_fill_buf(s);
if (unlikely(fbuf == NULL)) {
s->vb_full++;
dev_dbg_ratelimited(&s->udev->dev,
@@ -642,7 +438,7 @@ static void msi3101_isoc_handler(struct urb *urb)
/* fill framebuffer */
ptr = vb2_plane_vaddr(&fbuf->vb, 0);
- flen = s->convert_stream(s, ptr, iso_buf, flen);
+ flen = msi2500_convert_stream(s, ptr, iso_buf, flen);
vb2_set_plane_payload(&fbuf->vb, 0, flen);
vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
}
@@ -651,13 +447,14 @@ handler_end:
i = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(i != 0))
dev_dbg(&s->udev->dev,
- "Error (%d) re-submitting urb in msi3101_isoc_handler\n",
+ "Error (%d) re-submitting urb in msi2500_isoc_handler\n",
i);
}
-static void msi3101_iso_stop(struct msi3101_state *s)
+static void msi2500_iso_stop(struct msi2500_state *s)
{
int i;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
/* Unlinking ISOC buffers one by one */
@@ -670,9 +467,10 @@ static void msi3101_iso_stop(struct msi3101_state *s)
}
}
-static void msi3101_iso_free(struct msi3101_state *s)
+static void msi2500_iso_free(struct msi2500_state *s)
{
int i;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
/* Freeing ISOC buffers one by one */
@@ -692,20 +490,21 @@ static void msi3101_iso_free(struct msi3101_state *s)
}
/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static void msi3101_isoc_cleanup(struct msi3101_state *s)
+static void msi2500_isoc_cleanup(struct msi2500_state *s)
{
dev_dbg(&s->udev->dev, "%s:\n", __func__);
- msi3101_iso_stop(s);
- msi3101_iso_free(s);
+ msi2500_iso_stop(s);
+ msi2500_iso_free(s);
}
/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
-static int msi3101_isoc_init(struct msi3101_state *s)
+static int msi2500_isoc_init(struct msi2500_state *s)
{
struct usb_device *udev;
struct urb *urb;
int i, j, ret;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
s->isoc_errors = 0;
@@ -721,7 +520,7 @@ static int msi3101_isoc_init(struct msi3101_state *s)
if (urb == NULL) {
dev_err(&s->udev->dev,
"Failed to allocate urb %d\n", i);
- msi3101_isoc_cleanup(s);
+ msi2500_isoc_cleanup(s);
return -ENOMEM;
}
s->urbs[i] = urb;
@@ -737,11 +536,11 @@ static int msi3101_isoc_init(struct msi3101_state *s)
dev_err(&s->udev->dev,
"Failed to allocate urb buffer %d\n",
i);
- msi3101_isoc_cleanup(s);
+ msi2500_isoc_cleanup(s);
return -ENOMEM;
}
urb->transfer_buffer_length = ISO_BUFFER_SIZE;
- urb->complete = msi3101_isoc_handler;
+ urb->complete = msi2500_isoc_handler;
urb->context = s;
urb->start_frame = 0;
urb->number_of_packets = ISO_FRAMES_PER_DESC;
@@ -758,7 +557,7 @@ static int msi3101_isoc_init(struct msi3101_state *s)
dev_err(&s->udev->dev,
"isoc_init() submit_urb %d failed with error %d\n",
i, ret);
- msi3101_isoc_cleanup(s);
+ msi2500_isoc_cleanup(s);
return ret;
}
dev_dbg(&s->udev->dev, "URB 0x%p submitted.\n", s->urbs[i]);
@@ -769,16 +568,17 @@ static int msi3101_isoc_init(struct msi3101_state *s)
}
/* Must be called with vb_queue_lock hold */
-static void msi3101_cleanup_queued_bufs(struct msi3101_state *s)
+static void msi2500_cleanup_queued_bufs(struct msi2500_state *s)
{
unsigned long flags = 0;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
spin_lock_irqsave(&s->queued_bufs_lock, flags);
while (!list_empty(&s->queued_bufs)) {
- struct msi3101_frame_buf *buf;
+ struct msi2500_frame_buf *buf;
- buf = list_entry(s->queued_bufs.next, struct msi3101_frame_buf,
+ buf = list_entry(s->queued_bufs.next, struct msi2500_frame_buf,
list);
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
@@ -787,11 +587,12 @@ static void msi3101_cleanup_queued_bufs(struct msi3101_state *s)
}
/* The user yanked out the cable... */
-static void msi3101_disconnect(struct usb_interface *intf)
+static void msi2500_disconnect(struct usb_interface *intf)
{
struct v4l2_device *v = usb_get_intfdata(intf);
- struct msi3101_state *s =
- container_of(v, struct msi3101_state, v4l2_dev);
+ struct msi2500_state *s =
+ container_of(v, struct msi2500_state, v4l2_dev);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->vb_queue_lock);
@@ -807,10 +608,11 @@ static void msi3101_disconnect(struct usb_interface *intf)
v4l2_device_put(&s->v4l2_dev);
}
-static int msi3101_querycap(struct file *file, void *fh,
+static int msi2500_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
@@ -823,33 +625,28 @@ static int msi3101_querycap(struct file *file, void *fh,
}
/* Videobuf2 operations */
-static int msi3101_queue_setup(struct vb2_queue *vq,
+static int msi2500_queue_setup(struct vb2_queue *vq,
const struct v4l2_format *fmt, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
+ struct msi2500_state *s = vb2_get_drv_priv(vq);
+
dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
/* Absolute min and max number of buffers available for mmap() */
*nbuffers = clamp_t(unsigned int, *nbuffers, 8, 32);
*nplanes = 1;
- /*
- * 3, wMaxPacketSize 3x 1024 bytes
- * 504, max IQ sample pairs per 1024 frame
- * 2, two samples, I and Q
- * 2, 16-bit is enough for single sample
- */
- sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 2);
+ sizes[0] = PAGE_ALIGN(s->buffersize);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]);
return 0;
}
-static void msi3101_buf_queue(struct vb2_buffer *vb)
+static void msi2500_buf_queue(struct vb2_buffer *vb)
{
- struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
- struct msi3101_frame_buf *buf =
- container_of(vb, struct msi3101_frame_buf, vb);
+ struct msi2500_state *s = vb2_get_drv_priv(vb->vb2_queue);
+ struct msi2500_frame_buf *buf =
+ container_of(vb, struct msi2500_frame_buf, vb);
unsigned long flags = 0;
/* Check the device has not disconnected between prep and queuing */
@@ -868,18 +665,19 @@ static void msi3101_buf_queue(struct vb2_buffer *vb)
#define CMD_STOP_STREAMING 0x45
#define CMD_READ_UNKNOW 0x48
-#define msi3101_dbg_usb_control_msg(udev, r, t, v, _i, b, l) { \
- char *direction; \
- if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
- direction = ">>>"; \
+#define msi2500_dbg_usb_control_msg(_udev, _r, _t, _v, _i, _b, _l) { \
+ char *_direction; \
+ if (_t & USB_DIR_IN) \
+ _direction = "<<<"; \
else \
- direction = "<<<"; \
- dev_dbg(&udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
- "%s %*ph\n", __func__, t, r, v & 0xff, v >> 8, \
- _i & 0xff, _i >> 8, l & 0xff, l >> 8, direction, l, b); \
+ _direction = ">>>"; \
+ dev_dbg(&_udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
+ "%s %*ph\n", __func__, _t, _r, _v & 0xff, _v >> 8, \
+ _i & 0xff, _i >> 8, _l & 0xff, _l >> 8, _direction, \
+ _l, _b); \
}
-static int msi3101_ctrl_msg(struct msi3101_state *s, u8 cmd, u32 data)
+static int msi2500_ctrl_msg(struct msi2500_state *s, u8 cmd, u32 data)
{
int ret;
u8 request = cmd;
@@ -887,7 +685,7 @@ static int msi3101_ctrl_msg(struct msi3101_state *s, u8 cmd, u32 data)
u16 value = (data >> 0) & 0xffff;
u16 index = (data >> 16) & 0xffff;
- msi3101_dbg_usb_control_msg(s->udev,
+ msi2500_dbg_usb_control_msg(s->udev,
request, requesttype, value, index, NULL, 0);
ret = usb_control_msg(s->udev, usb_sndctrlpipe(s->udev, 0),
@@ -902,7 +700,7 @@ static int msi3101_ctrl_msg(struct msi3101_state *s, u8 cmd, u32 data)
#define F_REF 24000000
#define DIV_R_IN 2
-static int msi3101_set_usb_adc(struct msi3101_state *s)
+static int msi2500_set_usb_adc(struct msi2500_state *s)
{
int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract;
u32 reg3, reg4, reg7;
@@ -912,41 +710,36 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
f_sr = s->f_adc;
/* set tuner, subdev, filters according to sampling rate */
- bandwidth_auto = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
+ bandwidth_auto = v4l2_ctrl_find(&s->hdl,
+ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO);
if (v4l2_ctrl_g_ctrl(bandwidth_auto)) {
- bandwidth = v4l2_ctrl_find(&s->hdl, V4L2_CID_RF_TUNER_BANDWIDTH);
+ bandwidth = v4l2_ctrl_find(&s->hdl,
+ V4L2_CID_RF_TUNER_BANDWIDTH);
v4l2_ctrl_s_ctrl(bandwidth, s->f_adc);
}
/* select stream format */
switch (s->pixelformat) {
case V4L2_SDR_FMT_CU8:
- s->convert_stream = msi3101_convert_stream_504_u8;
- reg7 = 0x000c9407;
+ reg7 = 0x000c9407; /* 504 */
break;
case V4L2_SDR_FMT_CU16LE:
- s->convert_stream = msi3101_convert_stream_252_u16;
- reg7 = 0x00009407;
+ reg7 = 0x00009407; /* 252 */
break;
- case V4L2_PIX_FMT_SDR_S8:
- s->convert_stream = msi3101_convert_stream_504;
- reg7 = 0x000c9407;
+ case V4L2_SDR_FMT_CS8:
+ reg7 = 0x000c9407; /* 504 */
break;
- case V4L2_PIX_FMT_SDR_MSI2500_384:
- s->convert_stream = msi3101_convert_stream_384;
- reg7 = 0x0000a507;
+ case MSI2500_PIX_FMT_SDR_MSI2500_384:
+ reg7 = 0x0000a507; /* 384 */
break;
- case V4L2_PIX_FMT_SDR_S12:
- s->convert_stream = msi3101_convert_stream_336;
- reg7 = 0x00008507;
+ case MSI2500_PIX_FMT_SDR_S12:
+ reg7 = 0x00008507; /* 336 */
break;
- case V4L2_PIX_FMT_SDR_S14:
- s->convert_stream = msi3101_convert_stream_252;
- reg7 = 0x00009407;
+ case V4L2_SDR_FMT_CS14LE:
+ reg7 = 0x00009407; /* 252 */
break;
default:
- s->convert_stream = msi3101_convert_stream_504_u8;
- reg7 = 0x000c9407;
+ reg7 = 0x000c9407; /* 504 */
break;
}
@@ -1009,47 +802,49 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
dev_dbg(&s->udev->dev,
"%s: f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg3=%08x reg4=%08x\n",
- __func__, f_sr, f_vco, div_n, div_m, div_r_out, reg3, reg4);
+ __func__, f_sr, f_vco, div_n, div_m, div_r_out, reg3,
+ reg4);
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00608008);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00608008);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00000c05);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00000c05);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00020000);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00020000);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00480102);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00480102);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00f38008);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00f38008);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg7);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, reg7);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg4);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, reg4);
if (ret)
goto err;
- ret = msi3101_ctrl_msg(s, CMD_WREG, reg3);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, reg3);
if (ret)
goto err;
err:
return ret;
};
-static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count)
+static int msi2500_start_streaming(struct vb2_queue *vq, unsigned int count)
{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
+ struct msi2500_state *s = vb2_get_drv_priv(vq);
int ret;
+
dev_dbg(&s->udev->dev, "%s:\n", __func__);
if (!s->udev)
@@ -1061,37 +856,37 @@ static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count)
/* wake-up tuner */
v4l2_subdev_call(s->v4l2_subdev, core, s_power, 1);
- ret = msi3101_set_usb_adc(s);
+ ret = msi2500_set_usb_adc(s);
- ret = msi3101_isoc_init(s);
+ ret = msi2500_isoc_init(s);
if (ret)
- msi3101_cleanup_queued_bufs(s);
+ msi2500_cleanup_queued_bufs(s);
- ret = msi3101_ctrl_msg(s, CMD_START_STREAMING, 0);
+ ret = msi2500_ctrl_msg(s, CMD_START_STREAMING, 0);
mutex_unlock(&s->v4l2_lock);
return ret;
}
-static void msi3101_stop_streaming(struct vb2_queue *vq)
+static void msi2500_stop_streaming(struct vb2_queue *vq)
{
- struct msi3101_state *s = vb2_get_drv_priv(vq);
+ struct msi2500_state *s = vb2_get_drv_priv(vq);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
mutex_lock(&s->v4l2_lock);
if (s->udev)
- msi3101_isoc_cleanup(s);
+ msi2500_isoc_cleanup(s);
- msi3101_cleanup_queued_bufs(s);
+ msi2500_cleanup_queued_bufs(s);
/* according to tests, at least 700us delay is required */
msleep(20);
- if (!msi3101_ctrl_msg(s, CMD_STOP_STREAMING, 0)) {
+ if (!msi2500_ctrl_msg(s, CMD_STOP_STREAMING, 0)) {
/* sleep USB IF / ADC */
- msi3101_ctrl_msg(s, CMD_WREG, 0x01000003);
+ msi2500_ctrl_msg(s, CMD_WREG, 0x01000003);
}
/* sleep tuner */
@@ -1100,22 +895,23 @@ static void msi3101_stop_streaming(struct vb2_queue *vq)
mutex_unlock(&s->v4l2_lock);
}
-static struct vb2_ops msi3101_vb2_ops = {
- .queue_setup = msi3101_queue_setup,
- .buf_queue = msi3101_buf_queue,
- .start_streaming = msi3101_start_streaming,
- .stop_streaming = msi3101_stop_streaming,
+static struct vb2_ops msi2500_vb2_ops = {
+ .queue_setup = msi2500_queue_setup,
+ .buf_queue = msi2500_buf_queue,
+ .start_streaming = msi2500_start_streaming,
+ .stop_streaming = msi2500_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
};
-static int msi3101_enum_fmt_sdr_cap(struct file *file, void *priv,
+static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, f->index);
- if (f->index >= NUM_FORMATS)
+ if (f->index >= s->num_formats)
return -EINVAL;
strlcpy(f->description, formats[f->index].name, sizeof(f->description));
@@ -1124,25 +920,28 @@ static int msi3101_enum_fmt_sdr_cap(struct file *file, void *priv,
return 0;
}
-static int msi3101_g_fmt_sdr_cap(struct file *file, void *priv,
+static int msi2500_g_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
+
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&s->pixelformat);
- memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
f->fmt.sdr.pixelformat = s->pixelformat;
+ f->fmt.sdr.buffersize = s->buffersize;
+ memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
return 0;
}
-static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
+static int msi2500_s_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
struct vb2_queue *q = &s->vb_queue;
int i;
+
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
@@ -1150,43 +949,52 @@ static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
return -EBUSY;
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
+ for (i = 0; i < s->num_formats; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
- s->pixelformat = f->fmt.sdr.pixelformat;
+ s->pixelformat = formats[i].pixelformat;
+ s->buffersize = formats[i].buffersize;
+ f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
}
}
- f->fmt.sdr.pixelformat = formats[0].pixelformat;
s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
-static int msi3101_try_fmt_sdr_cap(struct file *file, void *priv,
+static int msi2500_try_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int i;
+
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
- for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
+ for (i = 0; i < s->num_formats; i++) {
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+ f->fmt.sdr.buffersize = formats[i].buffersize;
return 0;
+ }
}
f->fmt.sdr.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.buffersize = formats[0].buffersize;
return 0;
}
-static int msi3101_s_tuner(struct file *file, void *priv,
+static int msi2500_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int ret;
+
dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
if (v->index == 0)
@@ -1199,10 +1007,11 @@ static int msi3101_s_tuner(struct file *file, void *priv,
return ret;
}
-static int msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
+static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int ret;
+
dev_dbg(&s->udev->dev, "%s: index=%d\n", __func__, v->index);
if (v->index == 0) {
@@ -1221,11 +1030,12 @@ static int msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
return ret;
}
-static int msi3101_g_frequency(struct file *file, void *priv,
+static int msi2500_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int ret = 0;
+
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
__func__, f->tuner, f->type);
@@ -1242,11 +1052,12 @@ static int msi3101_g_frequency(struct file *file, void *priv,
return ret;
}
-static int msi3101_s_frequency(struct file *file, void *priv,
+static int msi2500_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int ret;
+
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
__func__, f->tuner, f->type, f->frequency);
@@ -1256,7 +1067,7 @@ static int msi3101_s_frequency(struct file *file, void *priv,
bands[0].rangehigh);
dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
__func__, s->f_adc);
- ret = msi3101_set_usb_adc(s);
+ ret = msi2500_set_usb_adc(s);
} else if (f->tuner == 1) {
ret = v4l2_subdev_call(s->v4l2_subdev, tuner, s_frequency, f);
} else {
@@ -1266,11 +1077,12 @@ static int msi3101_s_frequency(struct file *file, void *priv,
return ret;
}
-static int msi3101_enum_freq_bands(struct file *file, void *priv,
+static int msi2500_enum_freq_bands(struct file *file, void *priv,
struct v4l2_frequency_band *band)
{
- struct msi3101_state *s = video_drvdata(file);
+ struct msi2500_state *s = video_drvdata(file);
int ret;
+
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
__func__, band->tuner, band->type, band->index);
@@ -1291,13 +1103,13 @@ static int msi3101_enum_freq_bands(struct file *file, void *priv,
return ret;
}
-static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
- .vidioc_querycap = msi3101_querycap,
+static const struct v4l2_ioctl_ops msi2500_ioctl_ops = {
+ .vidioc_querycap = msi2500_querycap,
- .vidioc_enum_fmt_sdr_cap = msi3101_enum_fmt_sdr_cap,
- .vidioc_g_fmt_sdr_cap = msi3101_g_fmt_sdr_cap,
- .vidioc_s_fmt_sdr_cap = msi3101_s_fmt_sdr_cap,
- .vidioc_try_fmt_sdr_cap = msi3101_try_fmt_sdr_cap,
+ .vidioc_enum_fmt_sdr_cap = msi2500_enum_fmt_sdr_cap,
+ .vidioc_g_fmt_sdr_cap = msi2500_g_fmt_sdr_cap,
+ .vidioc_s_fmt_sdr_cap = msi2500_s_fmt_sdr_cap,
+ .vidioc_try_fmt_sdr_cap = msi2500_try_fmt_sdr_cap,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -1309,19 +1121,19 @@ static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
.vidioc_streamon = vb2_ioctl_streamon,
.vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_g_tuner = msi3101_g_tuner,
- .vidioc_s_tuner = msi3101_s_tuner,
+ .vidioc_g_tuner = msi2500_g_tuner,
+ .vidioc_s_tuner = msi2500_s_tuner,
- .vidioc_g_frequency = msi3101_g_frequency,
- .vidioc_s_frequency = msi3101_s_frequency,
- .vidioc_enum_freq_bands = msi3101_enum_freq_bands,
+ .vidioc_g_frequency = msi2500_g_frequency,
+ .vidioc_s_frequency = msi2500_s_frequency,
+ .vidioc_enum_freq_bands = msi2500_enum_freq_bands,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
.vidioc_log_status = v4l2_ctrl_log_status,
};
-static const struct v4l2_file_operations msi3101_fops = {
+static const struct v4l2_file_operations msi2500_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
.release = vb2_fop_release,
@@ -1331,27 +1143,27 @@ static const struct v4l2_file_operations msi3101_fops = {
.unlocked_ioctl = video_ioctl2,
};
-static struct video_device msi3101_template = {
+static struct video_device msi2500_template = {
.name = "Mirics MSi3101 SDR Dongle",
.release = video_device_release_empty,
- .fops = &msi3101_fops,
- .ioctl_ops = &msi3101_ioctl_ops,
+ .fops = &msi2500_fops,
+ .ioctl_ops = &msi2500_ioctl_ops,
};
-static void msi3101_video_release(struct v4l2_device *v)
+static void msi2500_video_release(struct v4l2_device *v)
{
- struct msi3101_state *s =
- container_of(v, struct msi3101_state, v4l2_dev);
+ struct msi2500_state *s =
+ container_of(v, struct msi2500_state, v4l2_dev);
v4l2_ctrl_handler_free(&s->hdl);
v4l2_device_unregister(&s->v4l2_dev);
kfree(s);
}
-static int msi3101_transfer_one_message(struct spi_master *master,
+static int msi2500_transfer_one_message(struct spi_master *master,
struct spi_message *m)
{
- struct msi3101_state *s = spi_master_get_devdata(master);
+ struct msi2500_state *s = spi_master_get_devdata(master);
struct spi_transfer *t;
int ret = 0;
u32 data;
@@ -1363,7 +1175,7 @@ static int msi3101_transfer_one_message(struct spi_master *master,
data |= ((u8 *)t->tx_buf)[0] << 8;
data |= ((u8 *)t->tx_buf)[1] << 16;
data |= ((u8 *)t->tx_buf)[2] << 24;
- ret = msi3101_ctrl_msg(s, CMD_WREG, data);
+ ret = msi2500_ctrl_msg(s, CMD_WREG, data);
}
m->status = ret;
@@ -1371,11 +1183,11 @@ static int msi3101_transfer_one_message(struct spi_master *master,
return ret;
}
-static int msi3101_probe(struct usb_interface *intf,
+static int msi2500_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
- struct msi3101_state *s = NULL;
+ struct msi2500_state *s = NULL;
struct v4l2_subdev *sd;
struct spi_master *master;
int ret;
@@ -1386,9 +1198,9 @@ static int msi3101_probe(struct usb_interface *intf,
.max_speed_hz = 12000000,
};
- s = kzalloc(sizeof(struct msi3101_state), GFP_KERNEL);
+ s = kzalloc(sizeof(struct msi2500_state), GFP_KERNEL);
if (s == NULL) {
- pr_err("Could not allocate memory for msi3101_state\n");
+ pr_err("Could not allocate memory for msi2500_state\n");
return -ENOMEM;
}
@@ -1398,14 +1210,18 @@ static int msi3101_probe(struct usb_interface *intf,
INIT_LIST_HEAD(&s->queued_bufs);
s->udev = udev;
s->f_adc = bands[0].rangelow;
- s->pixelformat = V4L2_SDR_FMT_CU8;
+ s->pixelformat = formats[0].pixelformat;
+ s->buffersize = formats[0].buffersize;
+ s->num_formats = NUM_FORMATS;
+ if (msi2500_emulated_fmt == false)
+ s->num_formats -= 2;
/* Init videobuf2 queue structure */
s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
s->vb_queue.drv_priv = s;
- s->vb_queue.buf_struct_size = sizeof(struct msi3101_frame_buf);
- s->vb_queue.ops = &msi3101_vb2_ops;
+ s->vb_queue.buf_struct_size = sizeof(struct msi2500_frame_buf);
+ s->vb_queue.ops = &msi2500_vb2_ops;
s->vb_queue.mem_ops = &vb2_vmalloc_memops;
s->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
ret = vb2_queue_init(&s->vb_queue);
@@ -1415,14 +1231,13 @@ static int msi3101_probe(struct usb_interface *intf,
}
/* Init video_device structure */
- s->vdev = msi3101_template;
+ s->vdev = msi2500_template;
s->vdev.queue = &s->vb_queue;
s->vdev.queue->lock = &s->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
video_set_drvdata(&s->vdev, s);
/* Register the v4l2_device structure */
- s->v4l2_dev.release = msi3101_video_release;
+ s->v4l2_dev.release = msi2500_video_release;
ret = v4l2_device_register(&intf->dev, &s->v4l2_dev);
if (ret) {
dev_err(&s->udev->dev,
@@ -1440,7 +1255,7 @@ static int msi3101_probe(struct usb_interface *intf,
s->master = master;
master->bus_num = 0;
master->num_chipselect = 1;
- master->transfer_one_message = msi3101_transfer_one_message;
+ master->transfer_one_message = msi2500_transfer_one_message;
spi_master_set_devdata(master, s);
ret = spi_register_master(master);
if (ret) {
@@ -1481,6 +1296,9 @@ static int msi3101_probe(struct usb_interface *intf,
}
dev_info(&s->udev->dev, "Registered as %s\n",
video_device_node_name(&s->vdev));
+ dev_notice(&s->udev->dev,
+ "%s: SDR API is still slightly experimental and functionality changes may follow\n",
+ KBUILD_MODNAME);
return 0;
@@ -1496,22 +1314,22 @@ err_free_mem:
}
/* USB device ID list */
-static struct usb_device_id msi3101_id_table[] = {
+static struct usb_device_id msi2500_id_table[] = {
{ USB_DEVICE(0x1df7, 0x2500) }, /* Mirics MSi3101 SDR Dongle */
{ USB_DEVICE(0x2040, 0xd300) }, /* Hauppauge WinTV 133559 LF */
{ }
};
-MODULE_DEVICE_TABLE(usb, msi3101_id_table);
+MODULE_DEVICE_TABLE(usb, msi2500_id_table);
/* USB subsystem interface */
-static struct usb_driver msi3101_driver = {
+static struct usb_driver msi2500_driver = {
.name = KBUILD_MODNAME,
- .probe = msi3101_probe,
- .disconnect = msi3101_disconnect,
- .id_table = msi3101_id_table,
+ .probe = msi2500_probe,
+ .disconnect = msi2500_disconnect,
+ .id_table = msi2500_id_table,
};
-module_usb_driver(msi3101_driver);
+module_usb_driver(msi2500_driver);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Mirics MSi3101 SDR Dongle");
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index 7c280f35eea9..1b158f1167ed 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -951,15 +951,9 @@ static long pvr2_v4l2_ioctl(struct file *file,
if (ret < 0) {
if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "pvr2_v4l2_do_ioctl failure, ret=%ld", ret);
- } else {
- if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
- pvr2_trace(PVR2_TRACE_V4LIOCTL,
- "pvr2_v4l2_do_ioctl failure, ret=%ld"
- " command was:", ret);
- v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw),
- cmd);
- }
+ "pvr2_v4l2_do_ioctl failure, ret=%ld"
+ " command was:", ret);
+ v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
}
} else {
pvr2_trace(PVR2_TRACE_V4LIOCTL,
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index a73b0bced96f..15b754da4a2c 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -1013,7 +1013,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
strcpy(pdev->vdev.name, name);
pdev->vdev.queue = &pdev->vb_queue;
pdev->vdev.queue->lock = &pdev->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
video_set_drvdata(&pdev->vdev, pdev);
pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index a44466bc7b86..2c901861034a 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -1676,7 +1676,6 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
vc->vdev.ctrl_handler = &vc->hdl;
vc->vdev.lock = &dev->lock;
vc->vdev.v4l2_dev = &dev->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &vc->vdev.flags);
video_set_drvdata(&vc->vdev, vc);
if (video_nr == -1)
ret = video_register_device(&vc->vdev,
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index 5461341a31cb..233054311a62 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -671,7 +671,6 @@ int stk1160_video_register(struct stk1160 *dev)
/* This will be used to set video_device parent */
dev->vdev.v4l2_dev = &dev->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
/* NTSC is default */
dev->norm = V4L2_STD_NTSC_M;
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index be77482c3070..3588dc38db87 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -923,7 +923,6 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
pix_format->bytesperline = 2 * pix_format->width;
pix_format->sizeimage = pix_format->bytesperline
* pix_format->height;
- pix_format->priv = 0;
return 0;
}
@@ -967,7 +966,6 @@ static int stk_try_fmt_vid_cap(struct file *filp,
fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline
* fmtd->fmt.pix.height;
- fmtd->fmt.pix.priv = 0;
return 0;
}
@@ -1266,7 +1264,6 @@ static int stk_register_video_device(struct stk_camera *dev)
dev->vdev.lock = &dev->lock;
dev->vdev.debug = debug;
dev->vdev.v4l2_dev = &dev->v4l2_dev;
- set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
video_set_drvdata(&dev->vdev, dev);
err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
if (err)
diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c
index 3316caa4733b..b31f4791b8ff 100644
--- a/drivers/media/usb/tlg2300/pd-main.c
+++ b/drivers/media/usb/tlg2300/pd-main.c
@@ -476,6 +476,8 @@ err_audio:
err_video:
v4l2_device_unregister(&pd->v4l2_dev);
err_v4l2:
+ usb_put_intf(pd->interface);
+ usb_put_dev(pd->udev);
kfree(pd);
return ret;
}
diff --git a/drivers/media/usb/tlg2300/pd-radio.c b/drivers/media/usb/tlg2300/pd-radio.c
index ea6070ba835e..b391194a840c 100644
--- a/drivers/media/usb/tlg2300/pd-radio.c
+++ b/drivers/media/usb/tlg2300/pd-radio.c
@@ -327,7 +327,6 @@ int poseidon_fm_init(struct poseidon *p)
}
vfd->v4l2_dev = &p->v4l2_dev;
vfd->ctrl_handler = hdl;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
video_set_drvdata(vfd, p);
return video_register_device(vfd, VFL_TYPE_RADIO, -1);
}
diff --git a/drivers/media/usb/tlg2300/pd-video.c b/drivers/media/usb/tlg2300/pd-video.c
index 8df668d06552..8cd7f02fcf9f 100644
--- a/drivers/media/usb/tlg2300/pd-video.c
+++ b/drivers/media/usb/tlg2300/pd-video.c
@@ -1321,7 +1321,6 @@ static void init_video_context(struct running_context *context)
.bytesperline = 720 * 2,
.sizeimage = 720 * 576 * 2,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- .priv = 0
};
}
diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c
index d1af5438c168..26b2ebb62547 100644
--- a/drivers/media/usb/tm6000/tm6000-input.c
+++ b/drivers/media/usb/tm6000/tm6000-input.c
@@ -162,11 +162,42 @@ static int tm6000_ir_config(struct tm6000_IR *ir)
return 0;
}
+static void tm6000_ir_keydown(struct tm6000_IR *ir,
+ const char *buf, unsigned int len)
+{
+ u8 device, command;
+ u32 scancode;
+ enum rc_type protocol;
+
+ if (len < 1)
+ return;
+
+ command = buf[0];
+ device = (len > 1 ? buf[1] : 0x0);
+ switch (ir->rc_type) {
+ case RC_BIT_RC5:
+ protocol = RC_TYPE_RC5;
+ scancode = RC_SCANCODE_RC5(device, command);
+ break;
+ case RC_BIT_NEC:
+ protocol = RC_TYPE_NEC;
+ scancode = RC_SCANCODE_NEC(device, command);
+ break;
+ default:
+ protocol = RC_TYPE_OTHER;
+ scancode = RC_SCANCODE_OTHER(device << 8 | command);
+ break;
+ }
+
+ dprintk(1, "%s, protocol: 0x%04x, scancode: 0x%08x\n",
+ __func__, protocol, scancode);
+ rc_keydown(ir->rc, protocol, scancode, 0);
+}
+
static void tm6000_ir_urb_received(struct urb *urb)
{
struct tm6000_core *dev = urb->context;
struct tm6000_IR *ir = dev->ir;
- struct tm6000_ir_poll_result poll_result;
char *buf;
dprintk(2, "%s\n",__func__);
@@ -184,12 +215,7 @@ static void tm6000_ir_urb_received(struct urb *urb)
DUMP_PREFIX_OFFSET,16, 1,
buf, urb->actual_length, false);
- poll_result.rc_data = buf[0];
- if (urb->actual_length > 1)
- poll_result.rc_data |= buf[1] << 8;
-
- dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
- rc_keydown(ir->rc, poll_result.rc_data, 0);
+ tm6000_ir_keydown(ir, urb->transfer_buffer, urb->actual_length);
usb_submit_urb(urb, GFP_ATOMIC);
/*
@@ -204,7 +230,6 @@ static void tm6000_ir_handle_key(struct work_struct *work)
{
struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
struct tm6000_core *dev = ir->dev;
- struct tm6000_ir_poll_result poll_result;
int rc;
u8 buf[2];
@@ -219,13 +244,8 @@ static void tm6000_ir_handle_key(struct work_struct *work)
if (rc < 0)
return;
- if (rc > 1)
- poll_result.rc_data = buf[0] | buf[1] << 8;
- else
- poll_result.rc_data = buf[0];
-
/* Check if something was read */
- if ((poll_result.rc_data & 0xff) == 0xff) {
+ if ((buf[0] & 0xff) == 0xff) {
if (!ir->pwled) {
tm6000_flash_led(dev, 1);
ir->pwled = 1;
@@ -233,8 +253,7 @@ static void tm6000_ir_handle_key(struct work_struct *work)
return;
}
- dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
- rc_keydown(ir->rc, poll_result.rc_data, 0);
+ tm6000_ir_keydown(ir, buf, rc);
tm6000_flash_led(dev, 0);
ir->pwled = 0;
@@ -422,9 +441,9 @@ int tm6000_ir_init(struct tm6000_core *dev)
ir->rc = rc;
/* input setup */
- rc_set_allowed_protocols(rc, RC_BIT_RC5 | RC_BIT_NEC);
+ rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC;
/* Neded, in order to support NEC remotes with 24 or 32 bits */
- rc->scanmask = 0xffff;
+ rc->scancode_mask = 0xffff;
rc->priv = ir;
rc->change_protocol = tm6000_ir_change_protocol;
if (dev->int_in.endp) {
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index e6b3d5d83d43..793577fc4633 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -918,7 +918,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
(f->fmt.pix.width * fh->fmt->depth) >> 3;
f->fmt.pix.sizeimage =
f->fmt.pix.height * f->fmt.pix.bytesperline;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -959,7 +958,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.width &= ~0x01;
f->fmt.pix.field = field;
- f->fmt.pix.priv = 0;
f->fmt.pix.bytesperline =
(f->fmt.pix.width * fmt->depth) >> 3;
@@ -1626,7 +1624,6 @@ static struct video_device *vdev_init(struct tm6000_core *dev,
vfd->release = video_device_release;
vfd->debug = tm6000_debug;
vfd->lock = &dev->lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index f8a60c197534..f166ffc9800a 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -791,8 +791,7 @@ static void ttusb_free_iso_urbs(struct ttusb *ttusb)
int i;
for (i = 0; i < ISO_BUF_COUNT; i++)
- if (ttusb->iso_urb[i])
- usb_free_urb(ttusb->iso_urb[i]);
+ usb_free_urb(ttusb->iso_urb[i]);
pci_free_consistent(NULL,
ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c
index 2f87ddfa469f..473fab81b602 100644
--- a/drivers/media/usb/usbtv/usbtv-core.c
+++ b/drivers/media/usb/usbtv/usbtv-core.c
@@ -91,6 +91,8 @@ static int usbtv_probe(struct usb_interface *intf,
return 0;
usbtv_video_fail:
+ usb_set_intfdata(intf, NULL);
+ usb_put_dev(usbtv->udev);
kfree(usbtv);
return ret;
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index 2967e808408b..030c5854b4b3 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -701,7 +701,6 @@ int usbtv_video_init(struct usbtv *usbtv)
usbtv->vdev.tvnorms = USBTV_TV_STD;
usbtv->vdev.queue = &usbtv->vb2q;
usbtv->vdev.lock = &usbtv->v4l2_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
video_set_drvdata(&usbtv->vdev, usbtv);
ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c
index 816b1cffab7d..302aa07c458f 100644
--- a/drivers/media/usb/usbvision/usbvision-core.c
+++ b/drivers/media/usb/usbvision/usbvision-core.c
@@ -1463,8 +1463,6 @@ static int usbvision_write_reg_irq(struct usb_usbvision *usbvision, int address,
static int usbvision_init_compression(struct usb_usbvision *usbvision)
{
- int err_code = 0;
-
usbvision->last_isoc_frame_num = -1;
usbvision->isoc_data_count = 0;
usbvision->isoc_packet_count = 0;
@@ -1475,7 +1473,7 @@ static int usbvision_init_compression(struct usb_usbvision *usbvision)
usbvision->request_intra = 1;
usbvision->isoc_measure_bandwidth_count = 0;
- return err_code;
+ return 0;
}
/* this function measures the used bandwidth since last call
@@ -1484,11 +1482,9 @@ static int usbvision_init_compression(struct usb_usbvision *usbvision)
*/
static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision)
{
- int err_code = 0;
-
if (usbvision->isoc_measure_bandwidth_count < 2) { /* this gives an average bandwidth of 3 frames */
usbvision->isoc_measure_bandwidth_count++;
- return err_code;
+ return 0;
}
if ((usbvision->isoc_packet_size > 0) && (usbvision->isoc_packet_count > 0)) {
usbvision->used_bandwidth = usbvision->isoc_data_count /
@@ -1499,7 +1495,7 @@ static int usbvision_measure_bandwidth(struct usb_usbvision *usbvision)
usbvision->isoc_data_count = 0;
usbvision->isoc_packet_count = 0;
usbvision->isoc_skip_count = 0;
- return err_code;
+ return 0;
}
static int usbvision_adjust_compression(struct usb_usbvision *usbvision)
@@ -1546,26 +1542,24 @@ static int usbvision_adjust_compression(struct usb_usbvision *usbvision)
static int usbvision_request_intra(struct usb_usbvision *usbvision)
{
- int err_code = 0;
unsigned char buffer[1];
PDEBUG(DBG_IRQ, "");
usbvision->request_intra = 1;
buffer[0] = 1;
usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return err_code;
+ return 0;
}
static int usbvision_unrequest_intra(struct usb_usbvision *usbvision)
{
- int err_code = 0;
unsigned char buffer[1];
PDEBUG(DBG_IRQ, "");
usbvision->request_intra = 0;
buffer[0] = 0;
usbvision_write_reg_irq(usbvision, USBVISION_FORCE_INTRA, buffer, 1);
- return err_code;
+ return 0;
}
/*******************************
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index ad47c5cb539a..f8135f4e3b52 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1746,7 +1746,6 @@ static int uvc_register_video(struct uvc_device *dev,
vdev->fops = &uvc_fops;
vdev->release = uvc_release;
vdev->prio = &stream->chain->prio;
- set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
vdev->vfl_dir = VFL_DIR_TX;
strlcpy(vdev->name, dev->name, sizeof vdev->name);
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
index 74d56df3347f..5c006277b8b1 100644
--- a/drivers/media/usb/zr364xx/zr364xx.c
+++ b/drivers/media/usb/zr364xx/zr364xx.c
@@ -806,7 +806,6 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
f->fmt.pix.field);
@@ -829,7 +828,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -866,7 +864,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
- f->fmt.pix.priv = 0;
cam->vb_vidq.field = f->fmt.pix.field;
if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
@@ -1456,7 +1453,6 @@ static int zr364xx_probe(struct usb_interface *intf,
cam->vdev.lock = &cam->lock;
cam->vdev.v4l2_dev = &cam->v4l2_dev;
cam->vdev.ctrl_handler = &cam->ctrl_handler;
- set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
video_set_drvdata(&cam->vdev, cam);
if (debug)
cam->vdev.debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 433d6d77942e..ccaa38f65cf1 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -111,9 +111,13 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
EXPORT_SYMBOL(v4l2_ctrl_check);
/* Fill in a struct v4l2_queryctrl */
-int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
+int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def)
{
const char *name;
+ s64 min = _min;
+ s64 max = _max;
+ u64 step = _step;
+ s64 def = _def;
v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
&min, &max, &step, &def, &qctrl->flags);
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 7e2411c36419..cca6c2f76b3a 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -540,7 +540,16 @@ struct v4l2_framebuffer32 {
__u32 capability;
__u32 flags;
compat_caddr_t base;
- struct v4l2_pix_format fmt;
+ struct {
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ __u32 field;
+ __u32 bytesperline;
+ __u32 sizeimage;
+ __u32 colorspace;
+ __u32 priv;
+ } fmt;
};
static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
@@ -550,10 +559,10 @@ static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
get_user(tmp, &up->base) ||
get_user(kp->capability, &up->capability) ||
- get_user(kp->flags, &up->flags))
+ get_user(kp->flags, &up->flags) ||
+ copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
return -EFAULT;
kp->base = compat_ptr(tmp);
- get_v4l2_pix_format(&kp->fmt, &up->fmt);
return 0;
}
@@ -564,9 +573,9 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
put_user(tmp, &up->base) ||
put_user(kp->capability, &up->capability) ||
- put_user(kp->flags, &up->flags))
+ put_user(kp->flags, &up->flags) ||
+ copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
return -EFAULT;
- put_v4l2_pix_format(&kp->fmt, &up->fmt);
return 0;
}
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 55c683254102..f030d6a9e044 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -462,6 +462,13 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
"RGB full range (0-255)",
NULL,
};
+ static const char * const detect_md_mode[] = {
+ "Disabled",
+ "Global",
+ "Threshold Grid",
+ "Region Grid",
+ NULL,
+ };
switch (id) {
@@ -553,6 +560,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
case V4L2_CID_DV_TX_RGB_RANGE:
case V4L2_CID_DV_RX_RGB_RANGE:
return dv_rgb_range;
+ case V4L2_CID_DETECT_MD_MODE:
+ return detect_md_mode;
default:
return NULL;
@@ -592,7 +601,7 @@ const char *v4l2_ctrl_get_name(u32 id)
{
switch (id) {
/* USER controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_USER_CLASS: return "User Controls";
case V4L2_CID_BRIGHTNESS: return "Brightness";
case V4L2_CID_CONTRAST: return "Contrast";
@@ -754,7 +763,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile";
/* CAMERA controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_CAMERA_CLASS: return "Camera Controls";
case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure";
case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute";
@@ -788,14 +797,23 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status";
case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
- /* FM Radio Modulator control */
- /* Keep the order of the 'case's the same as in videodev2.h! */
+ /* FM Radio Modulator controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls";
case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation";
case V4L2_CID_RDS_TX_PI: return "RDS Program ID";
case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
+ case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo";
+ case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head";
+ case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed";
+ case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY";
+ case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
+ case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
+ case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music";
+ case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies";
+ case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies";
case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
@@ -812,6 +830,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
/* Flash controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_FLASH_CLASS: return "Flash Controls";
case V4L2_CID_FLASH_LED_MODE: return "LED Mode";
case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source";
@@ -827,7 +846,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_FLASH_READY: return "Ready to Strobe";
/* JPEG encoder controls */
- /* Keep the order of the 'case's the same as in videodev2.h! */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls";
case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling";
case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval";
@@ -835,18 +854,21 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
/* Image source controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls";
case V4L2_CID_VBLANK: return "Vertical Blanking";
case V4L2_CID_HBLANK: return "Horizontal Blanking";
case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain";
/* Image processing controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
case V4L2_CID_LINK_FREQ: return "Link Frequency";
case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
case V4L2_CID_TEST_PATTERN: return "Test Pattern";
/* DV controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
case V4L2_CID_DV_CLASS: return "Digital Video Controls";
case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present";
case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present";
@@ -859,7 +881,6 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls";
case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis";
case V4L2_CID_RDS_RECEPTION: return "RDS Reception";
-
case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls";
case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto";
case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain";
@@ -870,6 +891,20 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto";
case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth";
case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock";
+ case V4L2_CID_RDS_RX_PTY: return "RDS Program Type";
+ case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name";
+ case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text";
+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
+ case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music";
+
+ /* Detection controls */
+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */
+ case V4L2_CID_DETECT_CLASS: return "Detection Controls";
+ case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode";
+ case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold";
+ case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid";
+ case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid";
default:
return NULL;
}
@@ -877,7 +912,7 @@ const char *v4l2_ctrl_get_name(u32 id)
EXPORT_SYMBOL(v4l2_ctrl_get_name);
void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
- s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags)
+ s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags)
{
*name = v4l2_ctrl_get_name(id);
*flags = 0;
@@ -924,6 +959,17 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
case V4L2_CID_RF_TUNER_PLL_LOCK:
+ case V4L2_CID_RDS_TX_MONO_STEREO:
+ case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
+ case V4L2_CID_RDS_TX_COMPRESSED:
+ case V4L2_CID_RDS_TX_DYNAMIC_PTY:
+ case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
+ case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
+ case V4L2_CID_RDS_TX_MUSIC_SPEECH:
+ case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
+ case V4L2_CID_RDS_RX_MUSIC_SPEECH:
*type = V4L2_CTRL_TYPE_BOOLEAN;
*min = 0;
*max = *step = 1;
@@ -988,6 +1034,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_TEST_PATTERN:
case V4L2_CID_TUNE_DEEMPHASIS:
case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
+ case V4L2_CID_DETECT_MD_MODE:
*type = V4L2_CTRL_TYPE_MENU;
break;
case V4L2_CID_LINK_FREQ:
@@ -995,6 +1042,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
break;
case V4L2_CID_RDS_TX_PS_NAME:
case V4L2_CID_RDS_TX_RADIO_TEXT:
+ case V4L2_CID_RDS_RX_PS_NAME:
+ case V4L2_CID_RDS_RX_RADIO_TEXT:
*type = V4L2_CTRL_TYPE_STRING;
break;
case V4L2_CID_ISO_SENSITIVITY:
@@ -1014,6 +1063,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_DV_CLASS:
case V4L2_CID_FM_RX_CLASS:
case V4L2_CID_RF_TUNER_CLASS:
+ case V4L2_CID_DETECT_CLASS:
*type = V4L2_CTRL_TYPE_CTRL_CLASS;
/* You can neither read not write these */
*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -1041,14 +1091,32 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
*type = V4L2_CTRL_TYPE_INTEGER;
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
break;
- case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
case V4L2_CID_MPEG_VIDEO_DEC_PTS:
- *flags |= V4L2_CTRL_FLAG_VOLATILE;
- /* Fall through */
+ *type = V4L2_CTRL_TYPE_INTEGER64;
+ *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
+ *min = *def = 0;
+ *max = 0x1ffffffffLL;
+ *step = 1;
+ break;
+ case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
+ *type = V4L2_CTRL_TYPE_INTEGER64;
+ *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
+ *min = *def = 0;
+ *max = 0x7fffffffffffffffLL;
+ *step = 1;
+ break;
case V4L2_CID_PIXEL_RATE:
*type = V4L2_CTRL_TYPE_INTEGER64;
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
- *min = *max = *step = *def = 0;
+ break;
+ case V4L2_CID_DETECT_MD_REGION_GRID:
+ *type = V4L2_CTRL_TYPE_U8;
+ break;
+ case V4L2_CID_DETECT_MD_THRESHOLD_GRID:
+ *type = V4L2_CTRL_TYPE_U16;
+ break;
+ case V4L2_CID_RDS_TX_ALT_FREQS:
+ *type = V4L2_CTRL_TYPE_U32;
break;
default:
*type = V4L2_CTRL_TYPE_INTEGER;
@@ -1090,6 +1158,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_RF_TUNER_MIXER_GAIN:
case V4L2_CID_RF_TUNER_IF_GAIN:
case V4L2_CID_RF_TUNER_BANDWIDTH:
+ case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD:
*flags |= V4L2_CTRL_FLAG_SLIDER;
break;
case V4L2_CID_PAN_RELATIVE:
@@ -1106,6 +1175,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_DV_TX_RXSENSE:
case V4L2_CID_DV_TX_EDID_PRESENT:
case V4L2_CID_DV_RX_POWER_PRESENT:
+ case V4L2_CID_RDS_RX_PTY:
+ case V4L2_CID_RDS_RX_PS_NAME:
+ case V4L2_CID_RDS_RX_RADIO_TEXT:
+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
+ case V4L2_CID_RDS_RX_MUSIC_SPEECH:
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
break;
case V4L2_CID_RF_TUNER_PLL_LOCK:
@@ -1115,20 +1190,6 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
}
EXPORT_SYMBOL(v4l2_ctrl_fill);
-/* Helper function to determine whether the control type is compatible with
- VIDIOC_G/S_CTRL. */
-static bool type_is_int(const struct v4l2_ctrl *ctrl)
-{
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER64:
- case V4L2_CTRL_TYPE_STRING:
- /* Nope, these need v4l2_ext_control */
- return false;
- default:
- return true;
- }
-}
-
static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
{
memset(ev->reserved, 0, sizeof(ev->reserved));
@@ -1137,10 +1198,10 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change
ev->u.ctrl.changes = changes;
ev->u.ctrl.type = ctrl->type;
ev->u.ctrl.flags = ctrl->flags;
- if (ctrl->type == V4L2_CTRL_TYPE_STRING)
+ if (ctrl->is_ptr)
ev->u.ctrl.value64 = 0;
else
- ev->u.ctrl.value64 = ctrl->cur.val64;
+ ev->u.ctrl.value64 = *ctrl->p_cur.p_s64;
ev->u.ctrl.minimum = ctrl->minimum;
ev->u.ctrl.maximum = ctrl->maximum;
if (ctrl->type == V4L2_CTRL_TYPE_MENU
@@ -1166,42 +1227,283 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
v4l2_event_queue_fh(sev->fh, &ev);
}
-/* Helper function: copy the current control value back to the caller */
-static int cur_to_user(struct v4l2_ext_control *c,
- struct v4l2_ctrl *ctrl)
+static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
+ union v4l2_ctrl_ptr ptr1,
+ union v4l2_ctrl_ptr ptr2)
+{
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_BUTTON:
+ return false;
+ case V4L2_CTRL_TYPE_STRING:
+ idx *= ctrl->elem_size;
+ /* strings are always 0-terminated */
+ return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx);
+ case V4L2_CTRL_TYPE_INTEGER64:
+ return ptr1.p_s64[idx] == ptr2.p_s64[idx];
+ case V4L2_CTRL_TYPE_U8:
+ return ptr1.p_u8[idx] == ptr2.p_u8[idx];
+ case V4L2_CTRL_TYPE_U16:
+ return ptr1.p_u16[idx] == ptr2.p_u16[idx];
+ case V4L2_CTRL_TYPE_U32:
+ return ptr1.p_u32[idx] == ptr2.p_u32[idx];
+ default:
+ if (ctrl->is_int)
+ return ptr1.p_s32[idx] == ptr2.p_s32[idx];
+ idx *= ctrl->elem_size;
+ return !memcmp(ptr1.p + idx, ptr2.p + idx, ctrl->elem_size);
+ }
+}
+
+static void std_init(const struct v4l2_ctrl *ctrl, u32 idx,
+ union v4l2_ctrl_ptr ptr)
+{
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_STRING:
+ idx *= ctrl->elem_size;
+ memset(ptr.p_char + idx, ' ', ctrl->minimum);
+ ptr.p_char[idx + ctrl->minimum] = '\0';
+ break;
+ case V4L2_CTRL_TYPE_INTEGER64:
+ ptr.p_s64[idx] = ctrl->default_value;
+ break;
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_BITMASK:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ ptr.p_s32[idx] = ctrl->default_value;
+ break;
+ case V4L2_CTRL_TYPE_U8:
+ ptr.p_u8[idx] = ctrl->default_value;
+ break;
+ case V4L2_CTRL_TYPE_U16:
+ ptr.p_u16[idx] = ctrl->default_value;
+ break;
+ case V4L2_CTRL_TYPE_U32:
+ ptr.p_u32[idx] = ctrl->default_value;
+ break;
+ default:
+ idx *= ctrl->elem_size;
+ memset(ptr.p + idx, 0, ctrl->elem_size);
+ break;
+ }
+}
+
+static void std_log(const struct v4l2_ctrl *ctrl)
+{
+ union v4l2_ctrl_ptr ptr = ctrl->p_cur;
+
+ if (ctrl->is_array) {
+ unsigned i;
+
+ for (i = 0; i < ctrl->nr_of_dims; i++)
+ pr_cont("[%u]", ctrl->dims[i]);
+ pr_cont(" ");
+ }
+
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ pr_cont("%d", *ptr.p_s32);
+ break;
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ pr_cont("%s", *ptr.p_s32 ? "true" : "false");
+ break;
+ case V4L2_CTRL_TYPE_MENU:
+ pr_cont("%s", ctrl->qmenu[*ptr.p_s32]);
+ break;
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]);
+ break;
+ case V4L2_CTRL_TYPE_BITMASK:
+ pr_cont("0x%08x", *ptr.p_s32);
+ break;
+ case V4L2_CTRL_TYPE_INTEGER64:
+ pr_cont("%lld", *ptr.p_s64);
+ break;
+ case V4L2_CTRL_TYPE_STRING:
+ pr_cont("%s", ptr.p_char);
+ break;
+ case V4L2_CTRL_TYPE_U8:
+ pr_cont("%u", (unsigned)*ptr.p_u8);
+ break;
+ case V4L2_CTRL_TYPE_U16:
+ pr_cont("%u", (unsigned)*ptr.p_u16);
+ break;
+ case V4L2_CTRL_TYPE_U32:
+ pr_cont("%u", (unsigned)*ptr.p_u32);
+ break;
+ default:
+ pr_cont("unknown type %d", ctrl->type);
+ break;
+ }
+}
+
+/*
+ * Round towards the closest legal value. Be careful when we are
+ * close to the maximum range of the control type to prevent
+ * wrap-arounds.
+ */
+#define ROUND_TO_RANGE(val, offset_type, ctrl) \
+({ \
+ offset_type offset; \
+ if ((ctrl)->maximum >= 0 && \
+ val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \
+ val = (ctrl)->maximum; \
+ else \
+ val += (s32)((ctrl)->step / 2); \
+ val = clamp_t(typeof(val), val, \
+ (ctrl)->minimum, (ctrl)->maximum); \
+ offset = (val) - (ctrl)->minimum; \
+ offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \
+ val = (ctrl)->minimum + offset; \
+ 0; \
+})
+
+/* Validate a new control */
+static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
+ union v4l2_ctrl_ptr ptr)
+{
+ size_t len;
+ u64 offset;
+ s64 val;
+
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl);
+ case V4L2_CTRL_TYPE_INTEGER64:
+ /*
+ * We can't use the ROUND_TO_RANGE define here due to
+ * the u64 divide that needs special care.
+ */
+ val = ptr.p_s64[idx];
+ if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2))
+ val = ctrl->maximum;
+ else
+ val += (s64)(ctrl->step / 2);
+ val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum);
+ offset = val - ctrl->minimum;
+ do_div(offset, ctrl->step);
+ ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step;
+ return 0;
+ case V4L2_CTRL_TYPE_U8:
+ return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl);
+ case V4L2_CTRL_TYPE_U16:
+ return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl);
+ case V4L2_CTRL_TYPE_U32:
+ return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl);
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ ptr.p_s32[idx] = !!ptr.p_s32[idx];
+ return 0;
+
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum)
+ return -ERANGE;
+ if (ctrl->menu_skip_mask & (1 << ptr.p_s32[idx]))
+ return -EINVAL;
+ if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
+ ctrl->qmenu[ptr.p_s32[idx]][0] == '\0')
+ return -EINVAL;
+ return 0;
+
+ case V4L2_CTRL_TYPE_BITMASK:
+ ptr.p_s32[idx] &= ctrl->maximum;
+ return 0;
+
+ case V4L2_CTRL_TYPE_BUTTON:
+ case V4L2_CTRL_TYPE_CTRL_CLASS:
+ ptr.p_s32[idx] = 0;
+ return 0;
+
+ case V4L2_CTRL_TYPE_STRING:
+ idx *= ctrl->elem_size;
+ len = strlen(ptr.p_char + idx);
+ if (len < ctrl->minimum)
+ return -ERANGE;
+ if ((len - (u32)ctrl->minimum) % (u32)ctrl->step)
+ return -ERANGE;
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ctrl_type_ops std_type_ops = {
+ .equal = std_equal,
+ .init = std_init,
+ .log = std_log,
+ .validate = std_validate,
+};
+
+/* Helper function: copy the given control value back to the caller */
+static int ptr_to_user(struct v4l2_ext_control *c,
+ struct v4l2_ctrl *ctrl,
+ union v4l2_ctrl_ptr ptr)
{
u32 len;
+ if (ctrl->is_ptr && !ctrl->is_string)
+ return copy_to_user(c->ptr, ptr.p, c->size) ?
+ -EFAULT : 0;
+
switch (ctrl->type) {
case V4L2_CTRL_TYPE_STRING:
- len = strlen(ctrl->cur.string);
+ len = strlen(ptr.p_char);
if (c->size < len + 1) {
- c->size = len + 1;
+ c->size = ctrl->elem_size;
return -ENOSPC;
}
- return copy_to_user(c->string, ctrl->cur.string,
- len + 1) ? -EFAULT : 0;
+ return copy_to_user(c->string, ptr.p_char, len + 1) ?
+ -EFAULT : 0;
case V4L2_CTRL_TYPE_INTEGER64:
- c->value64 = ctrl->cur.val64;
+ c->value64 = *ptr.p_s64;
break;
default:
- c->value = ctrl->cur.val;
+ c->value = *ptr.p_s32;
break;
}
return 0;
}
-/* Helper function: copy the caller-provider value as the new control value */
-static int user_to_new(struct v4l2_ext_control *c,
+/* Helper function: copy the current control value back to the caller */
+static int cur_to_user(struct v4l2_ext_control *c,
struct v4l2_ctrl *ctrl)
{
+ return ptr_to_user(c, ctrl, ctrl->p_cur);
+}
+
+/* Helper function: copy the new control value back to the caller */
+static int new_to_user(struct v4l2_ext_control *c,
+ struct v4l2_ctrl *ctrl)
+{
+ return ptr_to_user(c, ctrl, ctrl->p_new);
+}
+
+/* Helper function: copy the caller-provider value to the given control value */
+static int user_to_ptr(struct v4l2_ext_control *c,
+ struct v4l2_ctrl *ctrl,
+ union v4l2_ctrl_ptr ptr)
+{
int ret;
u32 size;
ctrl->is_new = 1;
+ if (ctrl->is_ptr && !ctrl->is_string) {
+ unsigned idx;
+
+ ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0;
+ if (ret || !ctrl->is_array)
+ return ret;
+ for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++)
+ ctrl->type_ops->init(ctrl, idx, ptr);
+ return 0;
+ }
+
switch (ctrl->type) {
case V4L2_CTRL_TYPE_INTEGER64:
- ctrl->val64 = c->value64;
+ *ptr.p_s64 = c->value64;
break;
case V4L2_CTRL_TYPE_STRING:
size = c->size;
@@ -1209,74 +1511,53 @@ static int user_to_new(struct v4l2_ext_control *c,
return -ERANGE;
if (size > ctrl->maximum + 1)
size = ctrl->maximum + 1;
- ret = copy_from_user(ctrl->string, c->string, size);
+ ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0;
if (!ret) {
- char last = ctrl->string[size - 1];
+ char last = ptr.p_char[size - 1];
- ctrl->string[size - 1] = 0;
+ ptr.p_char[size - 1] = 0;
/* If the string was longer than ctrl->maximum,
then return an error. */
- if (strlen(ctrl->string) == ctrl->maximum && last)
+ if (strlen(ptr.p_char) == ctrl->maximum && last)
return -ERANGE;
}
- return ret ? -EFAULT : 0;
+ return ret;
default:
- ctrl->val = c->value;
+ *ptr.p_s32 = c->value;
break;
}
return 0;
}
-/* Helper function: copy the new control value back to the caller */
-static int new_to_user(struct v4l2_ext_control *c,
+/* Helper function: copy the caller-provider value as the new control value */
+static int user_to_new(struct v4l2_ext_control *c,
struct v4l2_ctrl *ctrl)
{
- u32 len;
+ return user_to_ptr(c, ctrl, ctrl->p_new);
+}
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_STRING:
- len = strlen(ctrl->string);
- if (c->size < len + 1) {
- c->size = ctrl->maximum + 1;
- return -ENOSPC;
- }
- return copy_to_user(c->string, ctrl->string,
- len + 1) ? -EFAULT : 0;
- case V4L2_CTRL_TYPE_INTEGER64:
- c->value64 = ctrl->val64;
- break;
- default:
- c->value = ctrl->val;
- break;
- }
- return 0;
+/* Copy the one value to another. */
+static void ptr_to_ptr(struct v4l2_ctrl *ctrl,
+ union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to)
+{
+ if (ctrl == NULL)
+ return;
+ memcpy(to.p, from.p, ctrl->elems * ctrl->elem_size);
}
/* Copy the new value to the current value. */
static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
{
- bool changed = false;
+ bool changed;
if (ctrl == NULL)
return;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BUTTON:
- changed = true;
- break;
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- changed = strcmp(ctrl->string, ctrl->cur.string);
- strcpy(ctrl->cur.string, ctrl->string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- changed = ctrl->val64 != ctrl->cur.val64;
- ctrl->cur.val64 = ctrl->val64;
- break;
- default:
- changed = ctrl->val != ctrl->cur.val;
- ctrl->cur.val = ctrl->val;
- break;
- }
+
+ /* has_changed is set by cluster_changed */
+ changed = ctrl->has_changed;
+ if (changed)
+ ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur);
+
if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) {
/* Note: CH_FLAGS is only set for auto clusters. */
ctrl->flags &=
@@ -1305,62 +1586,47 @@ static void cur_to_new(struct v4l2_ctrl *ctrl)
{
if (ctrl == NULL)
return;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- strcpy(ctrl->string, ctrl->cur.string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- ctrl->val64 = ctrl->cur.val64;
- break;
- default:
- ctrl->val = ctrl->cur.val;
- break;
- }
+ ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
}
/* Return non-zero if one or more of the controls in the cluster has a new
value that differs from the current value. */
static int cluster_changed(struct v4l2_ctrl *master)
{
- int diff = 0;
+ bool changed = false;
+ unsigned idx;
int i;
- for (i = 0; !diff && i < master->ncontrols; i++) {
+ for (i = 0; i < master->ncontrols; i++) {
struct v4l2_ctrl *ctrl = master->cluster[i];
+ bool ctrl_changed = false;
if (ctrl == NULL)
continue;
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BUTTON:
- /* Button controls are always 'different' */
- return 1;
- case V4L2_CTRL_TYPE_STRING:
- /* strings are always 0-terminated */
- diff = strcmp(ctrl->string, ctrl->cur.string);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- diff = ctrl->val64 != ctrl->cur.val64;
- break;
- default:
- diff = ctrl->val != ctrl->cur.val;
- break;
- }
+ for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
+ ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
+ ctrl->p_cur, ctrl->p_new);
+ ctrl->has_changed = ctrl_changed;
+ changed |= ctrl->has_changed;
}
- return diff;
+ return changed;
}
/* Control range checking */
static int check_range(enum v4l2_ctrl_type type,
- s32 min, s32 max, u32 step, s32 def)
+ s64 min, s64 max, u64 step, s64 def)
{
switch (type) {
case V4L2_CTRL_TYPE_BOOLEAN:
if (step != 1 || max > 1 || min < 0)
return -ERANGE;
/* fall through */
+ case V4L2_CTRL_TYPE_U8:
+ case V4L2_CTRL_TYPE_U16:
+ case V4L2_CTRL_TYPE_U32:
case V4L2_CTRL_TYPE_INTEGER:
- if (step <= 0 || min > max || def < min || def > max)
+ case V4L2_CTRL_TYPE_INTEGER64:
+ if (step == 0 || min > max || def < min || def > max)
return -ERANGE;
return 0;
case V4L2_CTRL_TYPE_BITMASK:
@@ -1389,58 +1655,33 @@ static int check_range(enum v4l2_ctrl_type type,
static int validate_new(const struct v4l2_ctrl *ctrl,
struct v4l2_ext_control *c)
{
- size_t len;
- u32 offset;
- s32 val;
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- /* Round towards the closest legal value */
- val = c->value + ctrl->step / 2;
- val = clamp(val, ctrl->minimum, ctrl->maximum);
- offset = val - ctrl->minimum;
- offset = ctrl->step * (offset / ctrl->step);
- c->value = ctrl->minimum + offset;
- return 0;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- c->value = !!c->value;
- return 0;
-
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- if (c->value < ctrl->minimum || c->value > ctrl->maximum)
- return -ERANGE;
- if (ctrl->menu_skip_mask & (1 << c->value))
- return -EINVAL;
- if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
- ctrl->qmenu[c->value][0] == '\0')
- return -EINVAL;
- return 0;
-
- case V4L2_CTRL_TYPE_BITMASK:
- c->value &= ctrl->maximum;
- return 0;
-
- case V4L2_CTRL_TYPE_BUTTON:
- case V4L2_CTRL_TYPE_CTRL_CLASS:
- c->value = 0;
- return 0;
-
- case V4L2_CTRL_TYPE_INTEGER64:
- return 0;
+ union v4l2_ctrl_ptr ptr;
+ unsigned idx;
+ int err = 0;
- case V4L2_CTRL_TYPE_STRING:
- len = strlen(c->string);
- if (len < ctrl->minimum)
- return -ERANGE;
- if ((len - ctrl->minimum) % ctrl->step)
- return -ERANGE;
- return 0;
+ if (!ctrl->is_ptr) {
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_BITMASK:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_BUTTON:
+ case V4L2_CTRL_TYPE_CTRL_CLASS:
+ ptr.p_s32 = &c->value;
+ return ctrl->type_ops->validate(ctrl, 0, ptr);
- default:
- return -EINVAL;
+ case V4L2_CTRL_TYPE_INTEGER64:
+ ptr.p_s64 = &c->value64;
+ return ctrl->type_ops->validate(ctrl, 0, ptr);
+ default:
+ break;
+ }
}
+ ptr.p = c->ptr;
+ for (idx = 0; !err && idx < c->size / ctrl->elem_size; idx++)
+ err = ctrl->type_ops->validate(ctrl, idx, ptr);
+ return err;
}
static inline u32 node2id(struct list_head *node)
@@ -1522,7 +1763,7 @@ static struct v4l2_ctrl_ref *find_private_ref(
VIDIOC_G/S_CTRL. */
if (V4L2_CTRL_ID2CLASS(ref->ctrl->id) == V4L2_CTRL_CLASS_USER &&
V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) {
- if (!type_is_int(ref->ctrl))
+ if (!ref->ctrl->is_int)
continue;
if (id == 0)
return ref;
@@ -1592,8 +1833,12 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
u32 class_ctrl = V4L2_CTRL_ID2CLASS(id) | 1;
int bucket = id % hdl->nr_of_buckets; /* which bucket to use */
- /* Automatically add the control class if it is not yet present. */
- if (id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
+ /*
+ * Automatically add the control class if it is not yet present and
+ * the new control is not a compound control.
+ */
+ if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES &&
+ id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0))
return hdl->error;
@@ -1652,20 +1897,61 @@ unlock:
/* Add a new control */
static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
+ const struct v4l2_ctrl_type_ops *type_ops,
u32 id, const char *name, enum v4l2_ctrl_type type,
- s32 min, s32 max, u32 step, s32 def,
+ s64 min, s64 max, u64 step, s64 def,
+ const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size,
u32 flags, const char * const *qmenu,
const s64 *qmenu_int, void *priv)
{
struct v4l2_ctrl *ctrl;
- unsigned sz_extra = 0;
+ unsigned sz_extra;
+ unsigned nr_of_dims = 0;
+ unsigned elems = 1;
+ bool is_array;
+ unsigned tot_ctrl_size;
+ unsigned idx;
+ void *data;
int err;
if (hdl->error)
return NULL;
+ while (dims && dims[nr_of_dims]) {
+ elems *= dims[nr_of_dims];
+ nr_of_dims++;
+ if (nr_of_dims == V4L2_CTRL_MAX_DIMS)
+ break;
+ }
+ is_array = nr_of_dims > 0;
+
+ /* Prefill elem_size for all types handled by std_type_ops */
+ switch (type) {
+ case V4L2_CTRL_TYPE_INTEGER64:
+ elem_size = sizeof(s64);
+ break;
+ case V4L2_CTRL_TYPE_STRING:
+ elem_size = max + 1;
+ break;
+ case V4L2_CTRL_TYPE_U8:
+ elem_size = sizeof(u8);
+ break;
+ case V4L2_CTRL_TYPE_U16:
+ elem_size = sizeof(u16);
+ break;
+ case V4L2_CTRL_TYPE_U32:
+ elem_size = sizeof(u32);
+ break;
+ default:
+ if (type < V4L2_CTRL_COMPOUND_TYPES)
+ elem_size = sizeof(s32);
+ break;
+ }
+ tot_ctrl_size = elem_size * elems;
+
/* Sanity checks */
- if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE ||
+ if (id == 0 || name == NULL || !elem_size ||
+ id >= V4L2_CID_PRIVATE_BASE ||
(type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
(type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) {
handler_set_err(hdl, -ERANGE);
@@ -1680,13 +1966,23 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, -ERANGE);
return NULL;
}
+ if (is_array &&
+ (type == V4L2_CTRL_TYPE_BUTTON ||
+ type == V4L2_CTRL_TYPE_CTRL_CLASS)) {
+ handler_set_err(hdl, -EINVAL);
+ return NULL;
+ }
+ sz_extra = 0;
if (type == V4L2_CTRL_TYPE_BUTTON)
flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
flags |= V4L2_CTRL_FLAG_READ_ONLY;
- else if (type == V4L2_CTRL_TYPE_STRING)
- sz_extra += 2 * (max + 1);
+ else if (type == V4L2_CTRL_TYPE_INTEGER64 ||
+ type == V4L2_CTRL_TYPE_STRING ||
+ type >= V4L2_CTRL_COMPOUND_TYPES ||
+ is_array)
+ sz_extra += 2 * tot_ctrl_size;
ctrl = kzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
if (ctrl == NULL) {
@@ -1698,6 +1994,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
INIT_LIST_HEAD(&ctrl->ev_subs);
ctrl->handler = hdl;
ctrl->ops = ops;
+ ctrl->type_ops = type_ops ? type_ops : &std_type_ops;
ctrl->id = id;
ctrl->name = name;
ctrl->type = type;
@@ -1705,19 +2002,36 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
ctrl->minimum = min;
ctrl->maximum = max;
ctrl->step = step;
+ ctrl->default_value = def;
+ ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING;
+ ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string;
+ ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64;
+ ctrl->is_array = is_array;
+ ctrl->elems = elems;
+ ctrl->nr_of_dims = nr_of_dims;
+ if (nr_of_dims)
+ memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0]));
+ ctrl->elem_size = elem_size;
if (type == V4L2_CTRL_TYPE_MENU)
ctrl->qmenu = qmenu;
else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
ctrl->qmenu_int = qmenu_int;
ctrl->priv = priv;
- ctrl->cur.val = ctrl->val = ctrl->default_value = def;
+ ctrl->cur.val = ctrl->val = def;
+ data = &ctrl[1];
- if (ctrl->type == V4L2_CTRL_TYPE_STRING) {
- ctrl->cur.string = (char *)&ctrl[1] + sz_extra - (max + 1);
- ctrl->string = (char *)&ctrl[1] + sz_extra - 2 * (max + 1);
- if (ctrl->minimum)
- memset(ctrl->cur.string, ' ', ctrl->minimum);
+ if (!ctrl->is_int) {
+ ctrl->p_new.p = data;
+ ctrl->p_cur.p = data + tot_ctrl_size;
+ } else {
+ ctrl->p_new.p = &ctrl->val;
+ ctrl->p_cur.p = &ctrl->cur.val;
}
+ for (idx = 0; idx < elems; idx++) {
+ ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
+ ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
+ }
+
if (handler_new_ref(hdl, ctrl)) {
kfree(ctrl);
return NULL;
@@ -1738,10 +2052,10 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
const s64 *qmenu_int = cfg->qmenu_int;
enum v4l2_ctrl_type type = cfg->type;
u32 flags = cfg->flags;
- s32 min = cfg->min;
- s32 max = cfg->max;
- u32 step = cfg->step;
- s32 def = cfg->def;
+ s64 min = cfg->min;
+ s64 max = cfg->max;
+ u64 step = cfg->step;
+ s64 def = cfg->def;
if (name == NULL)
v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
@@ -1761,10 +2075,11 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
return NULL;
}
- ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name,
+ ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name,
type, min, max,
- is_menu ? cfg->menu_skip_mask : step,
- def, flags, qmenu, qmenu_int, priv);
+ is_menu ? cfg->menu_skip_mask : step, def,
+ cfg->dims, cfg->elem_size,
+ flags, qmenu, qmenu_int, priv);
if (ctrl)
ctrl->is_private = cfg->is_private;
return ctrl;
@@ -1774,35 +2089,39 @@ EXPORT_SYMBOL(v4l2_ctrl_new_custom);
/* Helper function for standard non-menu controls */
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
- u32 id, s32 min, s32 max, u32 step, s32 def)
+ u32 id, s64 min, s64 max, u64 step, s64 def)
{
const char *name;
enum v4l2_ctrl_type type;
u32 flags;
v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
- if (type == V4L2_CTRL_TYPE_MENU
- || type == V4L2_CTRL_TYPE_INTEGER_MENU) {
+ if (type == V4L2_CTRL_TYPE_MENU ||
+ type == V4L2_CTRL_TYPE_INTEGER_MENU ||
+ type >= V4L2_CTRL_COMPOUND_TYPES) {
handler_set_err(hdl, -EINVAL);
return NULL;
}
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- min, max, step, def, flags, NULL, NULL, NULL);
+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
+ min, max, step, def, NULL, 0,
+ flags, NULL, NULL, NULL);
}
EXPORT_SYMBOL(v4l2_ctrl_new_std);
/* Helper function for standard menu controls */
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
- u32 id, s32 max, s32 mask, s32 def)
+ u32 id, u8 _max, u64 mask, u8 _def)
{
const char * const *qmenu = NULL;
const s64 *qmenu_int = NULL;
unsigned int qmenu_int_len = 0;
const char *name;
enum v4l2_ctrl_type type;
- s32 min;
- s32 step;
+ s64 min;
+ s64 max = _max;
+ s64 def = _def;
+ u64 step;
u32 flags;
v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
@@ -1816,21 +2135,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, -EINVAL);
return NULL;
}
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- 0, max, mask, def, flags, qmenu, qmenu_int, NULL);
+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
+ 0, max, mask, def, NULL, 0,
+ flags, qmenu, qmenu_int, NULL);
}
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
/* Helper function for standard menu controls with driver defined menu */
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
- s32 mask, s32 def, const char * const *qmenu)
+ const struct v4l2_ctrl_ops *ops, u32 id, u8 _max,
+ u64 mask, u8 _def, const char * const *qmenu)
{
enum v4l2_ctrl_type type;
const char *name;
u32 flags;
- s32 step;
- s32 min;
+ u64 step;
+ s64 min;
+ s64 max = _max;
+ s64 def = _def;
/* v4l2_ctrl_new_std_menu_items() should only be called for
* standard controls without a standard menu.
@@ -1845,7 +2167,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, -EINVAL);
return NULL;
}
- return v4l2_ctrl_new(hdl, ops, id, name, type, 0, max, mask, def,
+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
+ 0, max, mask, def, NULL, 0,
flags, qmenu, NULL, NULL);
}
@@ -1854,12 +2177,14 @@ EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
/* Helper function for standard integer menu controls */
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
const struct v4l2_ctrl_ops *ops,
- u32 id, s32 max, s32 def, const s64 *qmenu_int)
+ u32 id, u8 _max, u8 _def, const s64 *qmenu_int)
{
const char *name;
enum v4l2_ctrl_type type;
- s32 min;
- s32 step;
+ s64 min;
+ u64 step;
+ s64 max = _max;
+ s64 def = _def;
u32 flags;
v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
@@ -1867,8 +2192,9 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
handler_set_err(hdl, -EINVAL);
return NULL;
}
- return v4l2_ctrl_new(hdl, ops, id, name, type,
- 0, max, 0, def, flags, NULL, qmenu_int, NULL);
+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
+ 0, max, 0, def, NULL, 0,
+ flags, NULL, qmenu_int, NULL);
}
EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
@@ -2048,45 +2374,21 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
return;
- printk(KERN_INFO "%s%s%s: ", prefix, colon, ctrl->name);
+ pr_info("%s%s%s: ", prefix, colon, ctrl->name);
+
+ ctrl->type_ops->log(ctrl);
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_INTEGER:
- printk(KERN_CONT "%d", ctrl->cur.val);
- break;
- case V4L2_CTRL_TYPE_BOOLEAN:
- printk(KERN_CONT "%s", ctrl->cur.val ? "true" : "false");
- break;
- case V4L2_CTRL_TYPE_MENU:
- printk(KERN_CONT "%s", ctrl->qmenu[ctrl->cur.val]);
- break;
- case V4L2_CTRL_TYPE_INTEGER_MENU:
- printk(KERN_CONT "%lld", ctrl->qmenu_int[ctrl->cur.val]);
- break;
- case V4L2_CTRL_TYPE_BITMASK:
- printk(KERN_CONT "0x%08x", ctrl->cur.val);
- break;
- case V4L2_CTRL_TYPE_INTEGER64:
- printk(KERN_CONT "%lld", ctrl->cur.val64);
- break;
- case V4L2_CTRL_TYPE_STRING:
- printk(KERN_CONT "%s", ctrl->cur.string);
- break;
- default:
- printk(KERN_CONT "unknown type %d", ctrl->type);
- break;
- }
if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
V4L2_CTRL_FLAG_GRABBED |
V4L2_CTRL_FLAG_VOLATILE)) {
if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
- printk(KERN_CONT " inactive");
+ pr_cont(" inactive");
if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)
- printk(KERN_CONT " grabbed");
+ pr_cont(" grabbed");
if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE)
- printk(KERN_CONT " volatile");
+ pr_cont(" volatile");
}
- printk(KERN_CONT "\n");
+ pr_cont("\n");
}
/* Log all controls owned by the handler */
@@ -2157,9 +2459,10 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
}
EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
-/* Implement VIDIOC_QUERYCTRL */
-int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
+/* Implement VIDIOC_QUERY_EXT_CTRL */
+int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
{
+ const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
u32 id = qc->id & V4L2_CTRL_ID_MASK;
struct v4l2_ctrl_ref *ref;
struct v4l2_ctrl *ctrl;
@@ -2172,7 +2475,20 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
/* Try to find it */
ref = find_ref(hdl, id);
- if ((qc->id & V4L2_CTRL_FLAG_NEXT_CTRL) && !list_empty(&hdl->ctrl_refs)) {
+ if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) {
+ bool is_compound;
+ /* Match any control that is not hidden */
+ unsigned mask = 1;
+ bool match = false;
+
+ if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) {
+ /* Match any hidden control */
+ match = true;
+ } else if ((qc->id & next_flags) == next_flags) {
+ /* Match any control, compound or not */
+ mask = 0;
+ }
+
/* Find the next control with ID > qc->id */
/* Did we reach the end of the control list? */
@@ -2180,19 +2496,34 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
ref = NULL; /* Yes, so there is no next control */
} else if (ref) {
/* We found a control with the given ID, so just get
- the next one in the list. */
- ref = list_entry(ref->node.next, typeof(*ref), node);
+ the next valid one in the list. */
+ list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) {
+ is_compound =
+ ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
+ if (id < ref->ctrl->id &&
+ (is_compound & mask) == match)
+ break;
+ }
+ if (&ref->node == &hdl->ctrl_refs)
+ ref = NULL;
} else {
/* No control with the given ID exists, so start
searching for the next largest ID. We know there
is one, otherwise the first 'if' above would have
been true. */
- list_for_each_entry(ref, &hdl->ctrl_refs, node)
- if (id < ref->ctrl->id)
+ list_for_each_entry(ref, &hdl->ctrl_refs, node) {
+ is_compound =
+ ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
+ if (id < ref->ctrl->id &&
+ (is_compound & mask) == match)
break;
+ }
+ if (&ref->node == &hdl->ctrl_refs)
+ ref = NULL;
}
}
mutex_unlock(hdl->lock);
+
if (!ref)
return -EINVAL;
@@ -2203,6 +2534,14 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
else
qc->id = ctrl->id;
strlcpy(qc->name, ctrl->name, sizeof(qc->name));
+ qc->flags = ctrl->flags;
+ qc->type = ctrl->type;
+ if (ctrl->is_ptr)
+ qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
+ qc->elem_size = ctrl->elem_size;
+ qc->elems = ctrl->elems;
+ qc->nr_of_dims = ctrl->nr_of_dims;
+ memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
qc->minimum = ctrl->minimum;
qc->maximum = ctrl->maximum;
qc->default_value = ctrl->default_value;
@@ -2211,15 +2550,50 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
qc->step = 1;
else
qc->step = ctrl->step;
- qc->flags = ctrl->flags;
- qc->type = ctrl->type;
+ return 0;
+}
+EXPORT_SYMBOL(v4l2_query_ext_ctrl);
+
+/* Implement VIDIOC_QUERYCTRL */
+int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
+{
+ struct v4l2_query_ext_ctrl qec = { qc->id };
+ int rc;
+
+ rc = v4l2_query_ext_ctrl(hdl, &qec);
+ if (rc)
+ return rc;
+
+ qc->id = qec.id;
+ qc->type = qec.type;
+ qc->flags = qec.flags;
+ strlcpy(qc->name, qec.name, sizeof(qc->name));
+ switch (qc->type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ case V4L2_CTRL_TYPE_STRING:
+ case V4L2_CTRL_TYPE_BITMASK:
+ qc->minimum = qec.minimum;
+ qc->maximum = qec.maximum;
+ qc->step = qec.step;
+ qc->default_value = qec.default_value;
+ break;
+ default:
+ qc->minimum = 0;
+ qc->maximum = 0;
+ qc->step = 0;
+ qc->default_value = 0;
+ break;
+ }
return 0;
}
EXPORT_SYMBOL(v4l2_queryctrl);
int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
- if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
+ if (qc->id & (V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND))
return -EINVAL;
return v4l2_queryctrl(sd->ctrl_handler, qc);
}
@@ -2319,7 +2693,8 @@ EXPORT_SYMBOL(v4l2_subdev_querymenu);
Find the controls in the control array and do some basic checks. */
static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
struct v4l2_ext_controls *cs,
- struct v4l2_ctrl_helper *helpers)
+ struct v4l2_ctrl_helper *helpers,
+ bool get)
{
struct v4l2_ctrl_helper *h;
bool have_clusters = false;
@@ -2351,6 +2726,18 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
have_clusters = true;
if (ctrl->cluster[0] != ctrl)
ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
+ if (ctrl->is_ptr && !ctrl->is_string) {
+ unsigned tot_size = ctrl->elems * ctrl->elem_size;
+
+ if (c->size < tot_size) {
+ if (get) {
+ c->size = tot_size;
+ return -ENOSPC;
+ }
+ return -EFAULT;
+ }
+ c->size = tot_size;
+ }
/* Store the ref to the master control of the cluster */
h->mref = ref;
h->ctrl = ctrl;
@@ -2431,7 +2818,7 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
return -ENOMEM;
}
- ret = prepare_ext_ctrls(hdl, cs, helpers);
+ ret = prepare_ext_ctrls(hdl, cs, helpers, true);
cs->error_idx = cs->count;
for (i = 0; !ret && i < cs->count; i++)
@@ -2493,11 +2880,11 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
int ret = 0;
int i;
- /* String controls are not supported. The new_to_user() and
+ /* Compound controls are not supported. The new_to_user() and
* cur_to_user() calls below would need to be modified not to access
* userspace memory when called from get_ctrl().
*/
- if (ctrl->type == V4L2_CTRL_TYPE_STRING)
+ if (!ctrl->is_int)
return -EINVAL;
if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
@@ -2523,7 +2910,7 @@ int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
struct v4l2_ext_control c;
int ret;
- if (ctrl == NULL || !type_is_int(ctrl))
+ if (ctrl == NULL || !ctrl->is_int)
return -EINVAL;
ret = get_ctrl(ctrl, &c);
control->value = c.value;
@@ -2542,7 +2929,7 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
struct v4l2_ext_control c;
/* It's a driver bug if this happens. */
- WARN_ON(!type_is_int(ctrl));
+ WARN_ON(!ctrl->is_int);
c.value = 0;
get_ctrl(ctrl, &c);
return c.value;
@@ -2554,7 +2941,7 @@ s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
struct v4l2_ext_control c;
/* It's a driver bug if this happens. */
- WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
+ WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
c.value = 0;
get_ctrl(ctrl, &c);
return c.value;
@@ -2678,7 +3065,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
if (!helpers)
return -ENOMEM;
}
- ret = prepare_ext_ctrls(hdl, cs, helpers);
+ ret = prepare_ext_ctrls(hdl, cs, helpers, false);
if (!ret)
ret = validate_ctrls(cs, helpers, set);
if (ret && set)
@@ -2783,26 +3170,22 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
struct v4l2_ctrl *master = ctrl->cluster[0];
int i;
- /* String controls are not supported. The user_to_new() and
- * cur_to_user() calls below would need to be modified not to access
- * userspace memory when called from set_ctrl().
- */
- if (ctrl->type == V4L2_CTRL_TYPE_STRING)
- return -EINVAL;
-
/* Reset the 'is_new' flags of the cluster */
for (i = 0; i < master->ncontrols; i++)
if (master->cluster[i])
master->cluster[i]->is_new = 0;
+ if (c)
+ user_to_new(c, ctrl);
+
/* For autoclusters with volatiles that are switched from auto to
manual mode we have to update the current volatile values since
those will become the initial manual values after such a switch. */
if (master->is_auto && master->has_volatiles && ctrl == master &&
- !is_cur_manual(master) && c->value == master->manual_mode_value)
+ !is_cur_manual(master) && ctrl->val == master->manual_mode_value)
update_from_auto_cluster(master);
- user_to_new(c, ctrl);
+ ctrl->is_new = 1;
return try_or_set_cluster(fh, master, true, ch_flags);
}
@@ -2829,7 +3212,7 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
struct v4l2_ext_control c;
int ret;
- if (ctrl == NULL || !type_is_int(ctrl))
+ if (ctrl == NULL || !ctrl->is_int)
return -EINVAL;
if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
@@ -2848,27 +3231,38 @@ int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *control)
}
EXPORT_SYMBOL(v4l2_subdev_s_ctrl);
-int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
+int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
{
- struct v4l2_ext_control c;
+ lockdep_assert_held(ctrl->handler->lock);
/* It's a driver bug if this happens. */
- WARN_ON(!type_is_int(ctrl));
- c.value = val;
- return set_ctrl_lock(NULL, ctrl, &c);
+ WARN_ON(!ctrl->is_int);
+ ctrl->val = val;
+ return set_ctrl(NULL, ctrl, NULL, 0);
}
-EXPORT_SYMBOL(v4l2_ctrl_s_ctrl);
+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);
-int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
+int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
{
- struct v4l2_ext_control c;
+ lockdep_assert_held(ctrl->handler->lock);
/* It's a driver bug if this happens. */
- WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
- c.value64 = val;
- return set_ctrl_lock(NULL, ctrl, &c);
+ WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
+ *ctrl->p_new.p_s64 = val;
+ return set_ctrl(NULL, ctrl, NULL, 0);
}
-EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64);
+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);
+
+int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
+{
+ lockdep_assert_held(ctrl->handler->lock);
+
+ /* It's a driver bug if this happens. */
+ WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING);
+ strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
+ return set_ctrl(NULL, ctrl, NULL, 0);
+}
+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
{
@@ -2886,40 +3280,47 @@ void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void
}
EXPORT_SYMBOL(v4l2_ctrl_notify);
-int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
- s32 min, s32 max, u32 step, s32 def)
+int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
+ s64 min, s64 max, u64 step, s64 def)
{
- int ret = check_range(ctrl->type, min, max, step, def);
+ int ret;
struct v4l2_ext_control c;
+ lockdep_assert_held(ctrl->handler->lock);
+
switch (ctrl->type) {
case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_INTEGER64:
case V4L2_CTRL_TYPE_BOOLEAN:
case V4L2_CTRL_TYPE_MENU:
case V4L2_CTRL_TYPE_INTEGER_MENU:
case V4L2_CTRL_TYPE_BITMASK:
+ case V4L2_CTRL_TYPE_U8:
+ case V4L2_CTRL_TYPE_U16:
+ case V4L2_CTRL_TYPE_U32:
+ if (ctrl->is_array)
+ return -EINVAL;
+ ret = check_range(ctrl->type, min, max, step, def);
if (ret)
return ret;
break;
default:
return -EINVAL;
}
- v4l2_ctrl_lock(ctrl);
ctrl->minimum = min;
ctrl->maximum = max;
ctrl->step = step;
ctrl->default_value = def;
- c.value = ctrl->cur.val;
+ c.value = *ctrl->p_cur.p_s32;
if (validate_new(ctrl, &c))
c.value = def;
- if (c.value != ctrl->cur.val)
+ if (c.value != *ctrl->p_cur.p_s32)
ret = set_ctrl(NULL, ctrl, &c, V4L2_EVENT_CTRL_CH_RANGE);
else
send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
- v4l2_ctrl_unlock(ctrl);
return ret;
}
-EXPORT_SYMBOL(v4l2_ctrl_modify_range);
+EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
{
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 634d863c05b4..33617c365acc 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -335,7 +335,7 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
return DEFAULT_POLLMASK;
if (video_is_registered(vdev))
res = vdev->fops->poll(filp, poll);
- if (vdev->debug)
+ if (vdev->debug > 2)
printk(KERN_DEBUG "%s: poll: %08x\n",
video_device_node_name(vdev), res);
return res;
@@ -563,20 +563,18 @@ static void determine_valid_ioctls(struct video_device *vdev)
/* vfl_type and vfl_dir independent ioctls */
SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap);
- if (ops->vidioc_g_priority ||
- test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
+ if (ops->vidioc_g_priority)
set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls);
- if (ops->vidioc_s_priority ||
- test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags))
+ if (ops->vidioc_s_priority)
set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls);
- SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
- SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
/* Note: the control handler can also be passed through the filehandle,
and that can't be tested here. If the bit for these control ioctls
is set, then the ioctl is valid. But if it is 0, then it can still
be valid if the filehandle passed the control handler. */
if (vdev->ctrl_handler || ops->vidioc_queryctrl)
set_bit(_IOC_NR(VIDIOC_QUERYCTRL), valid_ioctls);
+ if (vdev->ctrl_handler || ops->vidioc_query_ext_ctrl)
+ set_bit(_IOC_NR(VIDIOC_QUERY_EXT_CTRL), valid_ioctls);
if (vdev->ctrl_handler || ops->vidioc_g_ctrl || ops->vidioc_g_ext_ctrls)
set_bit(_IOC_NR(VIDIOC_G_CTRL), valid_ioctls);
if (vdev->ctrl_handler || ops->vidioc_s_ctrl || ops->vidioc_s_ext_ctrls)
@@ -684,6 +682,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs);
SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
+ SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
+ SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
if (is_vid || is_vbi) {
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 4ae54caadd03..ce1c9f5d9dee 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -610,10 +610,10 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
aspect.denominator = 9;
} else if (ratio == 34) {
aspect.numerator = 4;
- aspect.numerator = 3;
+ aspect.denominator = 3;
} else if (ratio == 68) {
aspect.numerator = 15;
- aspect.numerator = 9;
+ aspect.denominator = 9;
} else {
aspect.numerator = hor_landscape + 99;
aspect.denominator = 100;
diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index e57c002b4150..c97067a25bd2 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -37,6 +37,13 @@ void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
fh->ctrl_handler = vdev->ctrl_handler;
INIT_LIST_HEAD(&fh->list);
set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
+ /*
+ * determine_valid_ioctls() does not know if struct v4l2_fh
+ * is used by this driver, but here we do. So enable the
+ * prio ioctls here.
+ */
+ set_bit(_IOC_NR(VIDIOC_G_PRIORITY), vdev->valid_ioctls);
+ set_bit(_IOC_NR(VIDIOC_S_PRIORITY), vdev->valid_ioctls);
fh->prio = V4L2_PRIORITY_UNSET;
init_waitqueue_head(&fh->wait);
INIT_LIST_HEAD(&fh->available);
@@ -49,8 +56,7 @@ void v4l2_fh_add(struct v4l2_fh *fh)
{
unsigned long flags;
- if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
- v4l2_prio_open(fh->vdev->prio, &fh->prio);
+ v4l2_prio_open(fh->vdev->prio, &fh->prio);
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_add(&fh->list, &fh->vdev->fh_list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
@@ -78,8 +84,7 @@ void v4l2_fh_del(struct v4l2_fh *fh)
spin_lock_irqsave(&fh->vdev->fh_lock, flags);
list_del_init(&fh->list);
spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
- if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
- v4l2_prio_close(fh->vdev->prio, fh->prio);
+ v4l2_prio_close(fh->vdev->prio, fh->prio);
}
EXPORT_SYMBOL_GPL(v4l2_fh_del);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 16bffd851bf9..d15e16737eef 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -256,7 +256,8 @@ static void v4l_print_format(const void *arg, bool write_only)
pix = &p->fmt.pix;
pr_cont(", width=%u, height=%u, "
"pixelformat=%c%c%c%c, field=%s, "
- "bytesperline=%u, sizeimage=%u, colorspace=%d\n",
+ "bytesperline=%u, sizeimage=%u, colorspace=%d, "
+ "flags %u\n",
pix->width, pix->height,
(pix->pixelformat & 0xff),
(pix->pixelformat >> 8) & 0xff,
@@ -264,7 +265,7 @@ static void v4l_print_format(const void *arg, bool write_only)
(pix->pixelformat >> 24) & 0xff,
prt_names(pix->field, v4l2_field_names),
pix->bytesperline, pix->sizeimage,
- pix->colorspace);
+ pix->colorspace, pix->flags);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
@@ -525,6 +526,20 @@ static void v4l_print_queryctrl(const void *arg, bool write_only)
p->step, p->default_value, p->flags);
}
+static void v4l_print_query_ext_ctrl(const void *arg, bool write_only)
+{
+ const struct v4l2_query_ext_ctrl *p = arg;
+
+ pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, "
+ "step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, "
+ "nr_of_dims=%u, dims=%u,%u,%u,%u\n",
+ p->id, p->type, (int)sizeof(p->name), p->name,
+ p->minimum, p->maximum,
+ p->step, p->default_value, p->flags,
+ p->elem_size, p->elems, p->nr_of_dims,
+ p->dims[0], p->dims[1], p->dims[2], p->dims[3]);
+}
+
static void v4l_print_querymenu(const void *arg, bool write_only)
{
const struct v4l2_querymenu *p = arg;
@@ -959,13 +974,49 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
return -EINVAL;
}
+static void v4l_sanitize_format(struct v4l2_format *fmt)
+{
+ unsigned int offset;
+
+ /*
+ * The v4l2_pix_format structure has been extended with fields that were
+ * not previously required to be set to zero by applications. The priv
+ * field, when set to a magic value, indicates the the extended fields
+ * are valid. Otherwise they will contain undefined values. To simplify
+ * the API towards drivers zero the extended fields and set the priv
+ * field to the magic value when the extended pixel format structure
+ * isn't used by applications.
+ */
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return;
+
+ if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
+ return;
+
+ fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+
+ offset = offsetof(struct v4l2_pix_format, priv)
+ + sizeof(fmt->fmt.pix.priv);
+ memset(((void *)&fmt->fmt.pix) + offset, 0,
+ sizeof(fmt->fmt.pix) - offset);
+}
+
static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
+ int ret;
cap->version = LINUX_VERSION_CODE;
- return ops->vidioc_querycap(file, fh, cap);
+
+ ret = ops->vidioc_querycap(file, fh, cap);
+
+ cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
+ cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
+
+ return ret;
}
static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
@@ -1048,32 +1099,34 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
{
struct v4l2_fmtdesc *p = arg;
struct video_device *vfd = video_devdata(file);
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap))
break;
return ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap_mplane))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
break;
return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_overlay))
+ if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
break;
return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
break;
return ops->vidioc_enum_fmt_vid_out(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane))
+ if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
break;
return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_SDR_CAPTURE:
- if (unlikely(!is_rx || !ops->vidioc_enum_fmt_sdr_cap))
+ if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
break;
return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
}
@@ -1089,12 +1142,41 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+ int ret;
+
+ /*
+ * fmt can't be cleared for these overlay types due to the 'clips'
+ * 'clipcount' and 'bitmap' pointers in struct v4l2_window.
+ * Those are provided by the user. So handle these two overlay types
+ * first, and then just do a simple memset for the other types.
+ */
+ switch (p->type) {
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
+ struct v4l2_clip *clips = p->fmt.win.clips;
+ u32 clipcount = p->fmt.win.clipcount;
+ void *bitmap = p->fmt.win.bitmap;
+
+ memset(&p->fmt, 0, sizeof(p->fmt));
+ p->fmt.win.clips = clips;
+ p->fmt.win.clipcount = clipcount;
+ p->fmt.win.bitmap = bitmap;
+ break;
+ }
+ default:
+ memset(&p->fmt, 0, sizeof(p->fmt));
+ break;
+ }
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
break;
- return ops->vidioc_g_fmt_vid_cap(file, fh, arg);
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
break;
@@ -1114,7 +1196,11 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
break;
- return ops->vidioc_g_fmt_vid_out(file, fh, arg);
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
break;
@@ -1148,13 +1234,19 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+ int ret;
+
+ v4l_sanitize_format(p);
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_s_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
break;
@@ -1179,7 +1271,10 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_s_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
break;
@@ -1218,13 +1313,19 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+ int ret;
+
+ v4l_sanitize_format(p);
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_try_fmt_vid_cap(file, fh, arg);
+ ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
break;
@@ -1249,7 +1350,10 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
- return ops->vidioc_try_fmt_vid_out(file, fh, arg);
+ ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
+ /* just in case the driver zeroed it again */
+ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+ return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
break;
@@ -1502,7 +1606,18 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
struct v4l2_create_buffers *create = arg;
int ret = check_fmt(file, create->format.type);
- return ret ? ret : ops->vidioc_create_bufs(file, fh, create);
+ if (ret)
+ return ret;
+
+ v4l_sanitize_format(&create->format);
+
+ ret = ops->vidioc_create_bufs(file, fh, create);
+
+ if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+
+ return ret;
}
static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
@@ -1561,6 +1676,23 @@ static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops,
return -ENOTTY;
}
+static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ struct video_device *vfd = video_devdata(file);
+ struct v4l2_query_ext_ctrl *p = arg;
+ struct v4l2_fh *vfh =
+ test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+
+ if (vfh && vfh->ctrl_handler)
+ return v4l2_query_ext_ctrl(vfh->ctrl_handler, p);
+ if (vfd->ctrl_handler)
+ return v4l2_query_ext_ctrl(vfd->ctrl_handler, p);
+ if (ops->vidioc_query_ext_ctrl)
+ return ops->vidioc_query_ext_ctrl(file, fh, p);
+ return -ENOTTY;
+}
+
static int v4l_querymenu(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1751,37 +1883,41 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct v4l2_cropcap *p = arg;
- struct v4l2_selection s = { .type = p->type };
- int ret;
- if (ops->vidioc_cropcap)
- return ops->vidioc_cropcap(file, fh, p);
+ if (ops->vidioc_g_selection) {
+ struct v4l2_selection s = { .type = p->type };
+ int ret;
- /* obtaining bounds */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
- else
- s.target = V4L2_SEL_TGT_CROP_BOUNDS;
+ /* obtaining bounds */
+ if (V4L2_TYPE_IS_OUTPUT(p->type))
+ s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
+ else
+ s.target = V4L2_SEL_TGT_CROP_BOUNDS;
- ret = ops->vidioc_g_selection(file, fh, &s);
- if (ret)
- return ret;
- p->bounds = s.r;
+ ret = ops->vidioc_g_selection(file, fh, &s);
+ if (ret)
+ return ret;
+ p->bounds = s.r;
- /* obtaining defrect */
- if (V4L2_TYPE_IS_OUTPUT(p->type))
- s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
- else
- s.target = V4L2_SEL_TGT_CROP_DEFAULT;
+ /* obtaining defrect */
+ if (V4L2_TYPE_IS_OUTPUT(p->type))
+ s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+ else
+ s.target = V4L2_SEL_TGT_CROP_DEFAULT;
- ret = ops->vidioc_g_selection(file, fh, &s);
- if (ret)
- return ret;
- p->defrect = s.r;
+ ret = ops->vidioc_g_selection(file, fh, &s);
+ if (ret)
+ return ret;
+ p->defrect = s.r;
+ }
/* setting trivial pixelaspect */
p->pixelaspect.numerator = 1;
p->pixelaspect.denominator = 1;
+
+ if (ops->vidioc_cropcap)
+ return ops->vidioc_cropcap(file, fh, p);
+
return 0;
}
@@ -1951,8 +2087,11 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
if (type != p->type)
return -EINVAL;
}
- if (ops->vidioc_enum_freq_bands)
- return ops->vidioc_enum_freq_bands(file, fh, p);
+ if (ops->vidioc_enum_freq_bands) {
+ err = ops->vidioc_enum_freq_bands(file, fh, p);
+ if (err != -ENOTTY)
+ return err;
+ }
if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
struct v4l2_tuner t = {
.index = p->tuner,
@@ -2042,7 +2181,7 @@ struct v4l2_ioctl_info {
static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0),
IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)),
- IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)),
+ IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)),
@@ -2070,8 +2209,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, INFO_FL_CLEAR(v4l2_edid, edid)),
- IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_edid, edid)),
+ IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0),
+ IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
@@ -2084,8 +2223,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)),
IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, 0),
- IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO),
+ IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)),
+ IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)),
IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0),
IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
@@ -2121,6 +2260,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)),
IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
+ IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)),
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
@@ -2190,7 +2330,6 @@ static long __video_do_ioctl(struct file *file,
const struct v4l2_ioctl_info *info;
void *fh = file->private_data;
struct v4l2_fh *vfh = NULL;
- int use_fh_prio = 0;
int debug = vfd->debug;
long ret = -ENOTTY;
@@ -2200,10 +2339,8 @@ static long __video_do_ioctl(struct file *file,
return ret;
}
- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
+ if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
vfh = file->private_data;
- use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
- }
if (v4l2_is_known_ioctl(cmd)) {
info = &v4l2_ioctls[_IOC_NR(cmd)];
@@ -2212,7 +2349,7 @@ static long __video_do_ioctl(struct file *file,
!((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler))
goto done;
- if (use_fh_prio && (info->flags & INFO_FL_PRIO)) {
+ if (vfh && (info->flags & INFO_FL_PRIO)) {
ret = v4l2_prio_check(vfd->prio, vfh->prio);
if (ret)
goto done;
@@ -2237,7 +2374,7 @@ static long __video_do_ioctl(struct file *file,
ret = -ENOTTY;
} else {
ret = ops->vidioc_default(file, fh,
- use_fh_prio ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
+ vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0,
cmd, arg);
}
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 178ce96556c6..80c588f4e429 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -208,7 +208,7 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
* An example of the above could be an instance that requires more than one
* src/dst buffer per transaction.
*/
-static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
+void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
{
struct v4l2_m2m_dev *m2m_dev;
unsigned long flags_job, flags_out, flags_cap;
@@ -274,6 +274,7 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
v4l2_m2m_try_run(m2m_dev);
}
+EXPORT_SYMBOL_GPL(v4l2_m2m_try_schedule);
/**
* v4l2_m2m_cancel_job() - cancel pending jobs for the context
@@ -568,8 +569,12 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
if (m2m_ctx->m2m_dev->m2m_ops->lock)
m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
- else if (m2m_ctx->q_lock)
- mutex_lock(m2m_ctx->q_lock);
+ else if (m2m_ctx->q_lock) {
+ if (mutex_lock_interruptible(m2m_ctx->q_lock)) {
+ rc |= POLLERR;
+ goto end;
+ }
+ }
spin_lock_irqsave(&src_q->done_lock, flags);
if (!list_empty(&src_q->done_list))
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 058c1a6e8392..b4d235c13fbf 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -126,6 +126,57 @@ static int subdev_close(struct file *file)
return 0;
}
+#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+static int check_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_format *format)
+{
+ if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
+ format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
+ if (format->pad >= sd->entity.num_pads)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop)
+{
+ if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
+ crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
+ if (crop->pad >= sd->entity.num_pads)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int check_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_selection *sel)
+{
+ if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
+ sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return -EINVAL;
+
+ if (sel->pad >= sd->entity.num_pads)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int check_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
+{
+ if (edid->pad >= sd->entity.num_pads)
+ return -EINVAL;
+
+ if (edid->blocks && edid->edid == NULL)
+ return -EINVAL;
+
+ return 0;
+}
+#endif
+
static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct video_device *vdev = video_devdata(file);
@@ -133,12 +184,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct v4l2_fh *vfh = file->private_data;
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
+ int rval;
#endif
switch (cmd) {
case VIDIOC_QUERYCTRL:
return v4l2_queryctrl(vfh->ctrl_handler, arg);
+ case VIDIOC_QUERY_EXT_CTRL:
+ return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);
+
case VIDIOC_QUERYMENU:
return v4l2_querymenu(vfh->ctrl_handler, arg);
@@ -203,12 +258,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_G_FMT: {
struct v4l2_subdev_format *format = arg;
- if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
- format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (format->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_format(sd, format);
+ if (rval)
+ return rval;
return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
}
@@ -216,12 +268,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_S_FMT: {
struct v4l2_subdev_format *format = arg;
- if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
- format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (format->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_format(sd, format);
+ if (rval)
+ return rval;
return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
}
@@ -229,14 +278,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_G_CROP: {
struct v4l2_subdev_crop *crop = arg;
struct v4l2_subdev_selection sel;
- int rval;
-
- if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
- crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
- if (crop->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_crop(sd, crop);
+ if (rval)
+ return rval;
rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
if (rval != -ENOIOCTLCMD)
@@ -258,14 +303,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_S_CROP: {
struct v4l2_subdev_crop *crop = arg;
struct v4l2_subdev_selection sel;
- int rval;
-
- if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
- crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
- if (crop->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_crop(sd, crop);
+ if (rval)
+ return rval;
rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
if (rval != -ENOIOCTLCMD)
@@ -336,12 +377,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_G_SELECTION: {
struct v4l2_subdev_selection *sel = arg;
- if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
- sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (sel->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_selection(sd, sel);
+ if (rval)
+ return rval;
return v4l2_subdev_call(
sd, pad, get_selection, subdev_fh, sel);
@@ -350,12 +388,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_SUBDEV_S_SELECTION: {
struct v4l2_subdev_selection *sel = arg;
- if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
- sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
- return -EINVAL;
-
- if (sel->pad >= sd->entity.num_pads)
- return -EINVAL;
+ rval = check_selection(sd, sel);
+ if (rval)
+ return rval;
return v4l2_subdev_call(
sd, pad, set_selection, subdev_fh, sel);
@@ -364,10 +399,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_G_EDID: {
struct v4l2_subdev_edid *edid = arg;
- if (edid->pad >= sd->entity.num_pads)
- return -EINVAL;
- if (edid->blocks && edid->edid == NULL)
- return -EINVAL;
+ rval = check_edid(sd, edid);
+ if (rval)
+ return rval;
return v4l2_subdev_call(sd, pad, get_edid, edid);
}
@@ -375,10 +409,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_S_EDID: {
struct v4l2_subdev_edid *edid = arg;
- if (edid->pad >= sd->entity.num_pads)
- return -EINVAL;
- if (edid->blocks && edid->edid == NULL)
- return -EINVAL;
+ rval = check_edid(sd, edid);
+ if (rval)
+ return rval;
return v4l2_subdev_call(sd, pad, set_edid, edid);
}
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 828e7c10bd70..3c8cc023a5a5 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -211,13 +211,36 @@ EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
int nr_pages)
{
+ int i;
+
dprintk(1, "init kernel [%d pages]\n", nr_pages);
dma->direction = direction;
- dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+ dma->vaddr_pages = kcalloc(nr_pages, sizeof(*dma->vaddr_pages),
+ GFP_KERNEL);
+ if (!dma->vaddr_pages)
+ return -ENOMEM;
+
+ dma->dma_addr = kcalloc(nr_pages, sizeof(*dma->dma_addr), GFP_KERNEL);
+ if (!dma->dma_addr) {
+ kfree(dma->vaddr_pages);
+ return -ENOMEM;
+ }
+ for (i = 0; i < nr_pages; i++) {
+ void *addr;
+
+ addr = dma_alloc_coherent(dma->dev, PAGE_SIZE,
+ &(dma->dma_addr[i]), GFP_KERNEL);
+ if (addr == NULL)
+ goto out_free_pages;
+
+ dma->vaddr_pages[i] = virt_to_page(addr);
+ }
+ dma->vaddr = vmap(dma->vaddr_pages, nr_pages, VM_MAP | VM_IOREMAP,
+ PAGE_KERNEL);
if (NULL == dma->vaddr) {
dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
- return -ENOMEM;
+ goto out_free_pages;
}
dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
@@ -228,6 +251,19 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
dma->nr_pages = nr_pages;
return 0;
+out_free_pages:
+ while (i > 0) {
+ void *addr = page_address(dma->vaddr_pages[i]);
+ dma_free_coherent(dma->dev, PAGE_SIZE, addr, dma->dma_addr[i]);
+ i--;
+ }
+ kfree(dma->dma_addr);
+ dma->dma_addr = NULL;
+ kfree(dma->vaddr_pages);
+ dma->vaddr_pages = NULL;
+
+ return -ENOMEM;
+
}
EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
@@ -322,8 +358,21 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
dma->pages = NULL;
}
- vfree(dma->vaddr);
- dma->vaddr = NULL;
+ if (dma->dma_addr) {
+ for (i = 0; i < dma->nr_pages; i++) {
+ void *addr;
+
+ addr = page_address(dma->vaddr_pages[i]);
+ dma_free_coherent(dma->dev, PAGE_SIZE, addr,
+ dma->dma_addr[i]);
+ }
+ kfree(dma->dma_addr);
+ dma->dma_addr = NULL;
+ kfree(dma->vaddr_pages);
+ dma->vaddr_pages = NULL;
+ vunmap(dma->vaddr);
+ dma->vaddr = NULL;
+ }
if (dma->bus_addr)
dma->bus_addr = 0;
@@ -461,6 +510,11 @@ static int __videobuf_iolock(struct videobuf_queue *q,
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
+ if (!mem->dma.dev)
+ mem->dma.dev = q->dev;
+ else
+ WARN_ON(mem->dma.dev != q->dev);
+
switch (vb->memory) {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 7c4489c42365..c359006074a8 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -576,6 +576,7 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer
static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
{
unsigned int length;
+ unsigned int bytesused;
unsigned int plane;
if (!V4L2_TYPE_IS_OUTPUT(b->type))
@@ -583,21 +584,24 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b)
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
for (plane = 0; plane < vb->num_planes; ++plane) {
- length = (b->memory == V4L2_MEMORY_USERPTR)
+ length = (b->memory == V4L2_MEMORY_USERPTR ||
+ b->memory == V4L2_MEMORY_DMABUF)
? b->m.planes[plane].length
: vb->v4l2_planes[plane].length;
+ bytesused = b->m.planes[plane].bytesused
+ ? b->m.planes[plane].bytesused : length;
if (b->m.planes[plane].bytesused > length)
return -EINVAL;
if (b->m.planes[plane].data_offset > 0 &&
- b->m.planes[plane].data_offset >=
- b->m.planes[plane].bytesused)
+ b->m.planes[plane].data_offset >= bytesused)
return -EINVAL;
}
} else {
length = (b->memory == V4L2_MEMORY_USERPTR)
? b->length : vb->v4l2_planes[0].length;
+ bytesused = b->bytesused ? b->bytesused : length;
if (b->bytesused > length)
return -EINVAL;
@@ -1234,35 +1238,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
unsigned int plane;
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
- /* Fill in driver-provided information for OUTPUT types */
- if (V4L2_TYPE_IS_OUTPUT(b->type)) {
- bool bytesused_is_used;
-
- /* Check if bytesused == 0 for all planes */
- for (plane = 0; plane < vb->num_planes; ++plane)
- if (b->m.planes[plane].bytesused)
- break;
- bytesused_is_used = plane < vb->num_planes;
-
- /*
- * Will have to go up to b->length when API starts
- * accepting variable number of planes.
- *
- * If bytesused_is_used is false, then fall back to the
- * full buffer size. In that case userspace clearly
- * never bothered to set it and it's a safe assumption
- * that they really meant to use the full plane sizes.
- */
- for (plane = 0; plane < vb->num_planes; ++plane) {
- struct v4l2_plane *pdst = &v4l2_planes[plane];
- struct v4l2_plane *psrc = &b->m.planes[plane];
-
- pdst->bytesused = bytesused_is_used ?
- psrc->bytesused : psrc->length;
- pdst->data_offset = psrc->data_offset;
- }
- }
-
if (b->memory == V4L2_MEMORY_USERPTR) {
for (plane = 0; plane < vb->num_planes; ++plane) {
v4l2_planes[plane].m.userptr =
@@ -1279,6 +1254,28 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
b->m.planes[plane].length;
}
}
+
+ /* Fill in driver-provided information for OUTPUT types */
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ /*
+ * Will have to go up to b->length when API starts
+ * accepting variable number of planes.
+ *
+ * If bytesused == 0 for the output buffer, then fall
+ * back to the full buffer size. In that case
+ * userspace clearly never bothered to set it and
+ * it's a safe assumption that they really meant to
+ * use the full plane sizes.
+ */
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ struct v4l2_plane *pdst = &v4l2_planes[plane];
+ struct v4l2_plane *psrc = &b->m.planes[plane];
+
+ pdst->bytesused = psrc->bytesused ?
+ psrc->bytesused : pdst->length;
+ pdst->data_offset = psrc->data_offset;
+ }
+ }
} else {
/*
* Single-planar buffers do not use planes array,
@@ -1286,15 +1283,9 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
* In videobuf we use our internal V4l2_planes struct for
* single-planar buffers as well, for simplicity.
*
- * If bytesused == 0, then fall back to the full buffer size
- * as that's a sensible default.
+ * If bytesused == 0 for the output buffer, then fall back
+ * to the full buffer size as that's a sensible default.
*/
- if (V4L2_TYPE_IS_OUTPUT(b->type))
- v4l2_planes[0].bytesused =
- b->bytesused ? b->bytesused : b->length;
- else
- v4l2_planes[0].bytesused = 0;
-
if (b->memory == V4L2_MEMORY_USERPTR) {
v4l2_planes[0].m.userptr = b->m.userptr;
v4l2_planes[0].length = b->length;
@@ -1304,6 +1295,13 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b
v4l2_planes[0].m.fd = b->m.fd;
v4l2_planes[0].length = b->length;
}
+
+ if (V4L2_TYPE_IS_OUTPUT(b->type))
+ v4l2_planes[0].bytesused = b->bytesused ?
+ b->bytesused : v4l2_planes[0].length;
+ else
+ v4l2_planes[0].bytesused = 0;
+
}
/* Zero flags that the vb2 core handles */
@@ -1606,6 +1604,11 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
return -EINVAL;
}
+ if (q->error) {
+ dprintk(1, "fatal error occurred on queue\n");
+ return -EIO;
+ }
+
vb->state = VB2_BUF_STATE_PREPARING;
vb->v4l2_buf.timestamp.tv_sec = 0;
vb->v4l2_buf.timestamp.tv_usec = 0;
@@ -1750,12 +1753,14 @@ static int vb2_start_streaming(struct vb2_queue *q)
__enqueue_in_driver(vb);
/* Tell the driver to start streaming */
+ q->start_streaming_called = 1;
ret = call_qop(q, start_streaming, q,
atomic_read(&q->owned_by_drv_count));
- q->start_streaming_called = ret == 0;
if (!ret)
return 0;
+ q->start_streaming_called = 0;
+
dprintk(1, "driver refused to start streaming\n");
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
unsigned i;
@@ -1901,6 +1906,11 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
return -EINVAL;
}
+ if (q->error) {
+ dprintk(1, "Queue in error state, will not wait for buffers\n");
+ return -EIO;
+ }
+
if (!list_empty(&q->done_list)) {
/*
* Found a buffer that we were waiting for.
@@ -1926,7 +1936,8 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
*/
dprintk(3, "will sleep waiting for buffers\n");
ret = wait_event_interruptible(q->done_wq,
- !list_empty(&q->done_list) || !q->streaming);
+ !list_empty(&q->done_list) || !q->streaming ||
+ q->error);
/*
* We need to reevaluate both conditions again after reacquiring
@@ -2123,6 +2134,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
q->streaming = 0;
q->start_streaming_called = 0;
q->queued_count = 0;
+ q->error = 0;
/*
* Remove all buffers from videobuf's list...
@@ -2200,6 +2212,27 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
}
/**
+ * vb2_queue_error() - signal a fatal error on the queue
+ * @q: videobuf2 queue
+ *
+ * Flag that a fatal unrecoverable error has occurred and wake up all processes
+ * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing
+ * buffers will return -EIO.
+ *
+ * The error flag will be cleared when cancelling the queue, either from
+ * vb2_streamoff or vb2_queue_release. Drivers should thus not call this
+ * function before starting the stream, otherwise the error flag will remain set
+ * until the queue is released when closing the device node.
+ */
+void vb2_queue_error(struct vb2_queue *q)
+{
+ q->error = 1;
+
+ wake_up_all(&q->done_wq);
+}
+EXPORT_SYMBOL_GPL(vb2_queue_error);
+
+/**
* vb2_streamon - start streaming
* @q: videobuf2 queue
* @type: type argument passed from userspace to vidioc_streamon handler
@@ -2557,11 +2590,19 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
}
/*
- * There is nothing to wait for if no buffers have already been queued.
+ * There is nothing to wait for if no buffer has been queued and the
+ * queue isn't streaming, or if the error flag is set.
*/
- if (list_empty(&q->queued_list))
+ if ((list_empty(&q->queued_list) && !vb2_is_streaming(q)) || q->error)
return res | POLLERR;
+ /*
+ * For output streams you can write as long as there are fewer buffers
+ * queued than there are buffers available.
+ */
+ if (V4L2_TYPE_IS_OUTPUT(q->type) && q->queued_count < q->num_buffers)
+ return res | POLLOUT | POLLWRNORM;
+
if (list_empty(&q->done_list))
poll_wait(file, &q->done_wq, wait);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 880be0782dd9..4a02ade14b4f 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -98,6 +98,9 @@ static void *vb2_dc_vaddr(void *buf_priv)
{
struct vb2_dc_buf *buf = buf_priv;
+ if (!buf->vaddr && buf->db_attach)
+ buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf);
+
return buf->vaddr;
}
@@ -404,7 +407,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
if (WARN_ON(!buf->sgt_base))
return NULL;
- dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags);
+ dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags, NULL);
if (IS_ERR(dbuf))
return NULL;
@@ -735,6 +738,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
buf->dma_addr = sg_dma_address(sgt->sgl);
buf->dma_sgt = sgt;
+ buf->vaddr = NULL;
return 0;
}
@@ -754,6 +758,10 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
return;
}
+ if (buf->vaddr) {
+ dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
+ buf->vaddr = NULL;
+ }
dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
buf->dma_addr = 0;
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index c59e9c96e86d..fab81a143bd7 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -61,6 +61,16 @@ config TEGRA30_MC
analysis, especially for IOMMU/SMMU(System Memory Management
Unit) module.
+config FSL_CORENET_CF
+ tristate "Freescale CoreNet Error Reporting"
+ depends on FSL_SOC_BOOKE
+ help
+ Say Y for reporting of errors from the Freescale CoreNet
+ Coherency Fabric. Errors reported include accesses to
+ physical addresses that mapped by no local access window
+ (LAW) or an invalid LAW, as well as bad cache state that
+ represents a coherency violation.
+
config FSL_IFC
bool
depends on FSL_SOC
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 71160a2b7313..4055c47f45ab 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o
endif
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o
+obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
diff --git a/drivers/memory/fsl-corenet-cf.c b/drivers/memory/fsl-corenet-cf.c
new file mode 100644
index 000000000000..c9443fc136db
--- /dev/null
+++ b/drivers/memory/fsl-corenet-cf.c
@@ -0,0 +1,251 @@
+/*
+ * CoreNet Coherency Fabric error reporting
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * 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/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+enum ccf_version {
+ CCF1,
+ CCF2,
+};
+
+struct ccf_info {
+ enum ccf_version version;
+ int err_reg_offs;
+};
+
+static const struct ccf_info ccf1_info = {
+ .version = CCF1,
+ .err_reg_offs = 0xa00,
+};
+
+static const struct ccf_info ccf2_info = {
+ .version = CCF2,
+ .err_reg_offs = 0xe40,
+};
+
+static const struct of_device_id ccf_matches[] = {
+ {
+ .compatible = "fsl,corenet1-cf",
+ .data = &ccf1_info,
+ },
+ {
+ .compatible = "fsl,corenet2-cf",
+ .data = &ccf2_info,
+ },
+ {}
+};
+
+struct ccf_err_regs {
+ u32 errdet; /* 0x00 Error Detect Register */
+ /* 0x04 Error Enable (ccf1)/Disable (ccf2) Register */
+ u32 errdis;
+ /* 0x08 Error Interrupt Enable Register (ccf2 only) */
+ u32 errinten;
+ u32 cecar; /* 0x0c Error Capture Attribute Register */
+ u32 cecaddrh; /* 0x10 Error Capture Address High */
+ u32 cecaddrl; /* 0x14 Error Capture Address Low */
+ u32 cecar2; /* 0x18 Error Capture Attribute Register 2 */
+};
+
+/* LAE/CV also valid for errdis and errinten */
+#define ERRDET_LAE (1 << 0) /* Local Access Error */
+#define ERRDET_CV (1 << 1) /* Coherency Violation */
+#define ERRDET_CTYPE_SHIFT 26 /* Capture Type (ccf2 only) */
+#define ERRDET_CTYPE_MASK (0x1f << ERRDET_CTYPE_SHIFT)
+#define ERRDET_CAP (1 << 31) /* Capture Valid (ccf2 only) */
+
+#define CECAR_VAL (1 << 0) /* Valid (ccf1 only) */
+#define CECAR_UVT (1 << 15) /* Unavailable target ID (ccf1) */
+#define CECAR_SRCID_SHIFT_CCF1 24
+#define CECAR_SRCID_MASK_CCF1 (0xff << CECAR_SRCID_SHIFT_CCF1)
+#define CECAR_SRCID_SHIFT_CCF2 18
+#define CECAR_SRCID_MASK_CCF2 (0xff << CECAR_SRCID_SHIFT_CCF2)
+
+#define CECADDRH_ADDRH 0xff
+
+struct ccf_private {
+ const struct ccf_info *info;
+ struct device *dev;
+ void __iomem *regs;
+ struct ccf_err_regs __iomem *err_regs;
+};
+
+static irqreturn_t ccf_irq(int irq, void *dev_id)
+{
+ struct ccf_private *ccf = dev_id;
+ static DEFINE_RATELIMIT_STATE(ratelimit, DEFAULT_RATELIMIT_INTERVAL,
+ DEFAULT_RATELIMIT_BURST);
+ u32 errdet, cecar, cecar2;
+ u64 addr;
+ u32 src_id;
+ bool uvt = false;
+ bool cap_valid = false;
+
+ errdet = ioread32be(&ccf->err_regs->errdet);
+ cecar = ioread32be(&ccf->err_regs->cecar);
+ cecar2 = ioread32be(&ccf->err_regs->cecar2);
+ addr = ioread32be(&ccf->err_regs->cecaddrl);
+ addr |= ((u64)(ioread32be(&ccf->err_regs->cecaddrh) &
+ CECADDRH_ADDRH)) << 32;
+
+ if (!__ratelimit(&ratelimit))
+ goto out;
+
+ switch (ccf->info->version) {
+ case CCF1:
+ if (cecar & CECAR_VAL) {
+ if (cecar & CECAR_UVT)
+ uvt = true;
+
+ src_id = (cecar & CECAR_SRCID_MASK_CCF1) >>
+ CECAR_SRCID_SHIFT_CCF1;
+ cap_valid = true;
+ }
+
+ break;
+ case CCF2:
+ if (errdet & ERRDET_CAP) {
+ src_id = (cecar & CECAR_SRCID_MASK_CCF2) >>
+ CECAR_SRCID_SHIFT_CCF2;
+ cap_valid = true;
+ }
+
+ break;
+ }
+
+ dev_crit(ccf->dev, "errdet 0x%08x cecar 0x%08x cecar2 0x%08x\n",
+ errdet, cecar, cecar2);
+
+ if (errdet & ERRDET_LAE) {
+ if (uvt)
+ dev_crit(ccf->dev, "LAW Unavailable Target ID\n");
+ else
+ dev_crit(ccf->dev, "Local Access Window Error\n");
+ }
+
+ if (errdet & ERRDET_CV)
+ dev_crit(ccf->dev, "Coherency Violation\n");
+
+ if (cap_valid) {
+ dev_crit(ccf->dev, "address 0x%09llx, src id 0x%x\n",
+ addr, src_id);
+ }
+
+out:
+ iowrite32be(errdet, &ccf->err_regs->errdet);
+ return errdet ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int ccf_probe(struct platform_device *pdev)
+{
+ struct ccf_private *ccf;
+ struct resource *r;
+ const struct of_device_id *match;
+ int ret, irq;
+
+ match = of_match_device(ccf_matches, &pdev->dev);
+ if (WARN_ON(!match))
+ return -ENODEV;
+
+ ccf = devm_kzalloc(&pdev->dev, sizeof(*ccf), GFP_KERNEL);
+ if (!ccf)
+ return -ENOMEM;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+ return -ENXIO;
+ }
+
+ ccf->regs = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(ccf->regs)) {
+ dev_err(&pdev->dev, "%s: can't map mem resource\n", __func__);
+ return PTR_ERR(ccf->regs);
+ }
+
+ ccf->dev = &pdev->dev;
+ ccf->info = match->data;
+ ccf->err_regs = ccf->regs + ccf->info->err_reg_offs;
+
+ dev_set_drvdata(&pdev->dev, ccf);
+
+ irq = platform_get_irq(pdev, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "%s: no irq\n", __func__);
+ return -ENXIO;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: can't request irq\n", __func__);
+ return ret;
+ }
+
+ switch (ccf->info->version) {
+ case CCF1:
+ /* On CCF1 this register enables rather than disables. */
+ iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errdis);
+ break;
+
+ case CCF2:
+ iowrite32be(0, &ccf->err_regs->errdis);
+ iowrite32be(ERRDET_LAE | ERRDET_CV, &ccf->err_regs->errinten);
+ break;
+ }
+
+ return 0;
+}
+
+static int ccf_remove(struct platform_device *pdev)
+{
+ struct ccf_private *ccf = dev_get_drvdata(&pdev->dev);
+
+ switch (ccf->info->version) {
+ case CCF1:
+ iowrite32be(0, &ccf->err_regs->errdis);
+ break;
+
+ case CCF2:
+ /*
+ * We clear errdis on ccf1 because that's the only way to
+ * disable interrupts, but on ccf2 there's no need to disable
+ * detection.
+ */
+ iowrite32be(0, &ccf->err_regs->errinten);
+ break;
+ }
+
+ return 0;
+}
+
+static struct platform_driver ccf_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = ccf_matches,
+ },
+ .probe = ccf_probe,
+ .remove = ccf_remove,
+};
+
+module_platform_driver(ccf_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("Freescale CoreNet Coherency Fabric error reporting");
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index ebc0af7d769c..a896d948b79e 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -649,12 +649,10 @@ mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
case MPI_FUNCTION_CONFIG:
case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
- if (reply) {
- ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
- memcpy(ioc->mptbase_cmds.reply, reply,
- min(MPT_DEFAULT_FRAME_SIZE,
- 4 * reply->u.reply.MsgLength));
- }
+ ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
+ memcpy(ioc->mptbase_cmds.reply, reply,
+ min(MPT_DEFAULT_FRAME_SIZE,
+ 4 * reply->u.reply.MsgLength));
if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
complete(&ioc->mptbase_cmds.done);
@@ -1408,8 +1406,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
* in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
*
**/
-static void
-mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
+static const char*
+mpt_get_product_name(u16 vendor, u16 device, u8 revision)
{
char *product_str = NULL;
@@ -1635,8 +1633,7 @@ mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
}
out:
- if (product_str)
- sprintf(prod_name, "%s", product_str);
+ return product_str;
}
/**
@@ -1887,8 +1884,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
ioc->name, &ioc->facts, &ioc->pfacts[0]));
- mpt_get_product_name(pdev->vendor, pdev->device, pdev->revision,
- ioc->prod_name);
+ ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
+ pdev->revision);
switch (pdev->device)
{
@@ -7007,7 +7004,7 @@ EXPORT_SYMBOL(mpt_halt_firmware);
* IOC doesn't reply to any outstanding request. This will transfer IOC
* to READY state.
**/
-int
+static int
mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
{
int rc;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 76c05bc24cb7..8f14090b8b71 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -405,7 +405,7 @@ typedef struct _VirtTarget {
typedef struct _VirtDevice {
VirtTarget *vtarget;
u8 configured_lun;
- int lun;
+ u64 lun;
} VirtDevice;
/*
@@ -605,7 +605,7 @@ typedef struct _MPT_ADAPTER
int id; /* Unique adapter id N {0,1,2,...} */
int pci_irq; /* This irq */
char name[MPT_NAME_LENGTH]; /* "iocN" */
- char prod_name[MPT_NAME_LENGTH]; /* "LSIFC9x9" */
+ const char *prod_name; /* "LSIFC9x9" */
#ifdef CONFIG_FUSION_LOGGING
/* used in mpt_display_event_info */
char evStr[EVENT_DESCR_STR_SZ];
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 8a050e885688..b0a892a2bf1b 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1261,19 +1261,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
else
return -EFAULT;
- karg = kmalloc(data_size, GFP_KERNEL);
- if (karg == NULL) {
- printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
- __FILE__, __LINE__);
- return -ENOMEM;
- }
-
- if (copy_from_user(karg, uarg, data_size)) {
- printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
- "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
- __FILE__, __LINE__, uarg);
- kfree(karg);
- return -EFAULT;
+ karg = memdup_user(uarg, data_size);
+ if (IS_ERR(karg)) {
+ printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
+ __FILE__, __LINE__, PTR_ERR(karg));
+ return PTR_ERR(karg);
}
if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 02a3eefd6931..d8bf84aef602 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -204,7 +204,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
|| (loops > 0 && ioc->active == 0)) {
spin_unlock_irqrestore(shost->host_lock, flags);
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "mptfc_block_error_handler.%d: %d:%d, port status is "
+ "mptfc_block_error_handler.%d: %d:%llu, port status is "
"%x, active flag %d, deferring %s recovery.\n",
ioc->name, ioc->sh->host_no,
SCpnt->device->id, SCpnt->device->lun,
@@ -218,7 +218,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
|| ioc->active == 0) {
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "%s.%d: %d:%d, failing recovery, "
+ "%s.%d: %d:%llu, failing recovery, "
"port state %x, active %d, vdevice %p.\n", caller,
ioc->name, ioc->sh->host_no,
SCpnt->device->id, SCpnt->device->lun, ready,
@@ -226,7 +226,7 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
return FAILED;
}
dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
- "%s.%d: %d:%d, executing recovery.\n", caller,
+ "%s.%d: %d:%llu, executing recovery.\n", caller,
ioc->name, ioc->sh->host_no,
SCpnt->device->id, SCpnt->device->lun));
return (*func)(SCpnt);
@@ -525,8 +525,7 @@ mptfc_target_destroy(struct scsi_target *starget)
if (ri) /* better be! */
ri->starget = NULL;
}
- if (starget->hostdata)
- kfree(starget->hostdata);
+ kfree(starget->hostdata);
starget->hostdata = NULL;
}
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 711fcb5cec87..0707fa2c701b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -990,11 +990,10 @@ mptsas_queue_device_delete(MPT_ADAPTER *ioc,
MpiEventDataSasDeviceStatusChange_t *sas_event_data)
{
struct fw_event_work *fw_event;
- int sz;
- sz = offsetof(struct fw_event_work, event_data) +
- sizeof(MpiEventDataSasDeviceStatusChange_t);
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event) +
+ sizeof(MpiEventDataSasDeviceStatusChange_t),
+ GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
ioc->name, __func__, __LINE__);
@@ -1011,10 +1010,8 @@ static void
mptsas_queue_rescan(MPT_ADAPTER *ioc)
{
struct fw_event_work *fw_event;
- int sz;
- sz = offsetof(struct fw_event_work, event_data);
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
ioc->name, __func__, __LINE__);
@@ -1206,27 +1203,28 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
"(mf = %p, mr = %p)\n", ioc->name, mf, mr));
pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
- if (pScsiTmReply) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
- "\ttask_type = 0x%02X, iocstatus = 0x%04X "
- "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
- "term_cmnds = %d\n", ioc->name,
- pScsiTmReply->Bus, pScsiTmReply->TargetID,
- pScsiTmReply->TaskType,
- le16_to_cpu(pScsiTmReply->IOCStatus),
- le32_to_cpu(pScsiTmReply->IOCLogInfo),
- pScsiTmReply->ResponseCode,
- le32_to_cpu(pScsiTmReply->TerminationCount)));
-
- if (pScsiTmReply->ResponseCode)
- mptscsih_taskmgmt_response_code(ioc,
- pScsiTmReply->ResponseCode);
- }
-
- if (pScsiTmReply && (pScsiTmReply->TaskType ==
+ if (!pScsiTmReply)
+ return 0;
+
+ dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+ "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
+ "\ttask_type = 0x%02X, iocstatus = 0x%04X "
+ "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
+ "term_cmnds = %d\n", ioc->name,
+ pScsiTmReply->Bus, pScsiTmReply->TargetID,
+ pScsiTmReply->TaskType,
+ le16_to_cpu(pScsiTmReply->IOCStatus),
+ le32_to_cpu(pScsiTmReply->IOCLogInfo),
+ pScsiTmReply->ResponseCode,
+ le32_to_cpu(pScsiTmReply->TerminationCount)));
+
+ if (pScsiTmReply->ResponseCode)
+ mptscsih_taskmgmt_response_code(ioc,
+ pScsiTmReply->ResponseCode);
+
+ if (pScsiTmReply->TaskType ==
MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
- MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
+ MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET) {
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
memcpy(ioc->taskmgmt_cmds.reply, mr,
@@ -1575,7 +1573,7 @@ mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
mptsas_port_delete(ioc, phy_info->port_details);
}
-struct mptsas_phyinfo *
+static struct mptsas_phyinfo *
mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
struct mptsas_devinfo *sas_device)
{
@@ -3648,7 +3646,7 @@ mptsas_send_expander_event(struct fw_event_work *fw_event)
* @handle:
*
*/
-struct mptsas_portinfo *
+static struct mptsas_portinfo *
mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
{
struct mptsas_portinfo buffer, *port_info;
@@ -3763,7 +3761,7 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event)
printk(MYIOC_s_DEBUG_FMT
"SDEV OUTSTANDING CMDS"
"%d\n", ioc->name,
- sdev->device_busy));
+ atomic_read(&sdev->device_busy)));
}
}
@@ -3856,10 +3854,8 @@ retry_page:
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
sas_info->sas_address);
- if (phy_info) {
- mptsas_del_end_device(ioc, phy_info);
- goto redo_device_scan;
- }
+ mptsas_del_end_device(ioc, phy_info);
+ goto redo_device_scan;
} else
mptsas_volume_delete(ioc, sas_info->fw.id);
}
@@ -3870,9 +3866,8 @@ retry_page:
redo_expander_scan:
list_for_each_entry(port_info, &ioc->sas_topology, list) {
- if (port_info->phy_info &&
- (!(port_info->phy_info[0].identify.device_info &
- MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+ if (!(port_info->phy_info[0].identify.device_info &
+ MPI_SAS_DEVICE_INFO_SMP_TARGET))
continue;
found_expander = 0;
handle = 0xFFFF;
@@ -4983,7 +4978,7 @@ static int
mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
{
u32 event = le32_to_cpu(reply->Event);
- int sz, event_data_sz;
+ int event_data_sz;
struct fw_event_work *fw_event;
unsigned long delay;
@@ -5093,8 +5088,7 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
event_data_sz = ((reply->MsgLength * 4) -
offsetof(EventNotificationReply_t, Data));
- sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
- fw_event = kzalloc(sz, GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
if (!fw_event) {
printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
__func__, __LINE__);
@@ -5321,7 +5315,7 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return error;
}
-void
+static void
mptsas_shutdown(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
diff --git a/drivers/message/fusion/mptsas.h b/drivers/message/fusion/mptsas.h
index 57e86ab77661..c396483d3624 100644
--- a/drivers/message/fusion/mptsas.h
+++ b/drivers/message/fusion/mptsas.h
@@ -110,7 +110,7 @@ struct fw_event_work {
MPT_ADAPTER *ioc;
u32 event;
u8 retries;
- u8 __attribute__((aligned(4))) event_data[1];
+ char event_data[0] __aligned(4);
};
struct mptsas_discovery_event {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 2a1c6f21af27..e7dcb2583369 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -95,7 +95,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
- int lun, int ctx2abort, ulong timeout);
+ u64 lun, int ctx2abort, ulong timeout);
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
@@ -536,7 +536,7 @@ mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pSc
}
scsi_print_command(sc);
- printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %d\n",
+ printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
"resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
@@ -692,7 +692,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
*/
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
pScsiReply->ResponseInfo) {
- printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
+ printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
"FCP_ResponseInfo=%08xh\n", ioc->name,
sc->device->host->host_no, sc->device->channel,
sc->device->id, sc->device->lun,
@@ -1155,7 +1155,7 @@ mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSI
return;
ioc = hd->ioc;
if (time - hd->last_queue_full > 10 * HZ) {
- dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
+ dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
ioc->name, 0, sc->device->id, sc->device->lun));
hd->last_queue_full = time;
}
@@ -1271,15 +1271,13 @@ mptscsih_info(struct Scsi_Host *SChost)
h = shost_priv(SChost);
- if (h) {
- if (h->info_kbuf == NULL)
- if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
- return h->info_kbuf;
- h->info_kbuf[0] = '\0';
+ if (h->info_kbuf == NULL)
+ if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
+ return h->info_kbuf;
+ h->info_kbuf[0] = '\0';
- mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
- h->info_kbuf[size-1] = '\0';
- }
+ mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
+ h->info_kbuf[size-1] = '\0';
return h->info_kbuf;
}
@@ -1368,8 +1366,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt)
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if (vdevice
- && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+ if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
if (SCpnt->request && SCpnt->request->ioprio) {
@@ -1518,7 +1515,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
*
**/
int
-mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
int ctx2abort, ulong timeout)
{
MPT_FRAME_HDR *mf;
@@ -2380,7 +2377,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
vdevice = sdev->hostdata;
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "device @ %p, channel=%d, id=%d, lun=%d\n",
+ "device @ %p, channel=%d, id=%d, lun=%llu\n",
ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
if (ioc->bus_type == SPI)
dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
@@ -2971,7 +2968,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
+ (my_idx * MPT_SENSE_BUFFER_ALLOC));
devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
- "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
+ "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
ioc->name, __func__, cmd, io->channel, io->id, io->lun));
if (dir == MPI_SCSIIO_CONTROL_READ)
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 99e3390807f3..e1b1a198a62a 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -98,7 +98,7 @@ typedef struct _internal_cmd {
u8 cmd; /* SCSI Op Code */
u8 channel; /* bus number */
u8 id; /* SCSI ID (virtual) */
- int lun;
+ u64 lun;
u8 flags; /* Bit Field - See above */
u8 physDiskNum; /* Phys disk number, -1 else */
u8 rsvd2;
@@ -115,7 +115,7 @@ extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
extern const char * mptscsih_info(struct Scsi_Host *SChost);
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt);
extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
- u8 id, int lun, int ctx2abort, ulong timeout);
+ u8 id, u64 lun, int ctx2abort, ulong timeout);
extern void mptscsih_slave_destroy(struct scsi_device *device);
extern int mptscsih_slave_configure(struct scsi_device *device);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 49d11338294b..787933d43d32 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -461,8 +461,7 @@ static int mptspi_target_alloc(struct scsi_target *starget)
static void
mptspi_target_destroy(struct scsi_target *starget)
{
- if (starget->hostdata)
- kfree(starget->hostdata);
+ kfree(starget->hostdata);
starget->hostdata = NULL;
}
@@ -620,7 +619,7 @@ static void mptspi_read_parameters(struct scsi_target *starget)
spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
}
-int
+static int
mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
{
MPT_ADAPTER *ioc = hd->ioc;
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 1d31d7284cbd..8152e9fa9d95 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -78,7 +78,7 @@ static unsigned int i2o_scsi_max_lun = 255;
struct i2o_scsi_host {
struct Scsi_Host *scsi_host; /* pointer to the SCSI host */
struct i2o_controller *iop; /* pointer to the I2O controller */
- unsigned int lun; /* lun's used for block devices */
+ u64 lun; /* lun's used for block devices */
struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */
};
@@ -287,9 +287,8 @@ static int i2o_scsi_probe(struct device *dev)
}
if (le64_to_cpu(lun) >= scsi_host->max_lun) {
- osm_warn("SCSI device lun (%lu) >= max_lun of I2O host (%d)",
- (long unsigned int)le64_to_cpu(lun),
- scsi_host->max_lun);
+ osm_warn("SCSI device lun (%llu) >= max_lun of I2O host (%llu)",
+ le64_to_cpu(lun), scsi_host->max_lun);
return -EFAULT;
}
@@ -308,9 +307,9 @@ static int i2o_scsi_probe(struct device *dev)
if (rc)
goto err;
- osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %ld\n",
+ osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %llu\n",
i2o_dev->lct_data.tid, channel, le32_to_cpu(id),
- (long unsigned int)le64_to_cpu(lun));
+ le64_to_cpu(lun));
return 0;
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index 64751c2a1ace..e9d50644660c 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -158,7 +158,7 @@ static int device_irq_init_805(struct pm80x_chip *chip)
* PM805_INT_STATUS is under 32K clock domain, so need to
* add proper delay before the next I2C register access.
*/
- msleep(1);
+ usleep_range(1000, 3000);
if (ret < 0)
goto out;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index bcfc9e85b4a0..3a2604580164 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -2,7 +2,8 @@
* Base driver for Marvell 88PM8607
*
* Copyright (C) 2009 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.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
@@ -140,7 +141,8 @@ static struct resource codec_resources[] = {
/* Headset insertion or removal */
{PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,},
/* Audio short */
- {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
+ {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short",
+ IORESOURCE_IRQ,},
};
static struct resource battery_resources[] = {
@@ -150,10 +152,14 @@ static struct resource battery_resources[] = {
static struct resource charger_resources[] = {
{PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
- {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
- {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,},
- {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault", IORESOURCE_IRQ,},
- {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,},
+ {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done",
+ IORESOURCE_IRQ,},
+ {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout",
+ IORESOURCE_IRQ,},
+ {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault",
+ IORESOURCE_IRQ,},
+ {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature",
+ IORESOURCE_IRQ,},
{PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,},
{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
};
@@ -568,8 +574,8 @@ static struct irq_domain_ops pm860x_irq_domain_ops = {
static int device_irq_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
- struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
- : chip->companion;
+ struct i2c_client *i2c = (chip->id == CHIP_PM8607) ?
+ chip->client : chip->companion;
unsigned char status_buf[INT_STATUS_NUM];
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
int data, mask, ret = -EINVAL;
@@ -631,8 +637,8 @@ static int device_irq_init(struct pm860x_chip *chip,
if (!chip->core_irq)
goto out;
- ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
- "88pm860x", chip);
+ ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq,
+ flags | IRQF_ONESHOT, "88pm860x", chip);
if (ret) {
dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
chip->core_irq = 0;
@@ -871,7 +877,7 @@ static void device_rtc_init(struct pm860x_chip *chip,
{
int ret;
- if ((pdata == NULL))
+ if (!pdata)
return;
rtc_devs[0].platform_data = pdata->rtc;
@@ -997,8 +1003,9 @@ static void device_8607_init(struct pm860x_chip *chip,
ret);
break;
default:
- dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
- "Chip ID: %02x\n", ret);
+ dev_err(chip->dev,
+ "Failed to detect Marvell 88PM8607. Chip ID: %02x\n",
+ ret);
goto out;
}
@@ -1120,8 +1127,8 @@ static int pm860x_dt_init(struct device_node *np,
ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
&pdata->companion_addr);
if (ret) {
- dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
- "property\n");
+ dev_err(dev,
+ "Not found \"marvell,88pm860x-slave-addr\" property\n");
pdata->companion_addr = 0;
}
return 0;
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index ff8f803ce833..a93b4d0134a2 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -2,7 +2,8 @@
* I2C driver for Marvell 88PM860x
*
* Copyright (C) 2009 Marvell International Ltd.
- * Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.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/mfd/Kconfig b/drivers/mfd/Kconfig
index 6cc4b6acc22a..de5abf244746 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -13,7 +13,7 @@ config MFD_CORE
config MFD_CS5535
tristate "AMD CS5535 and CS5536 southbridge core functions"
select MFD_CORE
- depends on PCI && X86
+ depends on PCI && (X86_32 || (X86 && COMPILE_TEST))
---help---
This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality.
@@ -187,6 +187,7 @@ config MFD_MC13XXX
tristate
depends on (SPI_MASTER || I2C)
select MFD_CORE
+ select REGMAP_IRQ
help
Enable support for the Freescale MC13783 and MC13892 PMICs.
This driver provides common support for accessing the device,
@@ -253,6 +254,18 @@ config LPC_SCH
LPC bridge function of the Intel SCH provides support for
System Management Bus and General Purpose I/O.
+config INTEL_SOC_PMIC
+ bool "Support for Intel Atom SoC PMIC"
+ depends on I2C=y
+ select MFD_CORE
+ select REGMAP_I2C
+ select REGMAP_IRQ
+ help
+ Select this option to enable support for the PMIC device
+ on some Intel SoC systems. The PMIC provides ADC, GPIO,
+ thermal, charger and related power management functions
+ on these systems.
+
config MFD_INTEL_MSIC
bool "Intel MSIC"
depends on INTEL_SCU_IPC
@@ -367,14 +380,15 @@ config MFD_MAX14577
of the device.
config MFD_MAX77686
- bool "Maxim Semiconductor MAX77686 PMIC Support"
+ bool "Maxim Semiconductor MAX77686/802 PMIC Support"
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
+ select REGMAP_IRQ
select IRQ_DOMAIN
help
- Say yes here to add support for Maxim Semiconductor MAX77686.
- This is a Power Management IC with RTC on chip.
+ Say yes here to add support for Maxim Semiconductor MAX77686 and
+ MAX77802 which are Power Management IC with an RTC on chip.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the functionality
of the device.
@@ -384,6 +398,7 @@ config MFD_MAX77693
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
+ select REGMAP_IRQ
help
Say yes here to add support for Maxim Semiconductor MAX77693.
This is a companion Power Management IC with Flash, Haptic, Charger,
@@ -573,6 +588,7 @@ config MFD_SEC_CORE
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
+ select REGULATOR
help
Support for the Samsung Electronics MFD series.
This driver provides common support for accessing the device,
@@ -1056,7 +1072,7 @@ config MFD_LM3533
config MFD_TIMBERDALE
tristate "Timberdale FPGA"
select MFD_CORE
- depends on PCI && GPIOLIB
+ depends on PCI && GPIOLIB && (X86_32 || COMPILE_TEST)
---help---
This is the core driver for the timberdale FPGA. This device is a
multifunction device which exposes numerous platform devices.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8afedba535c7..f00148782d9b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -115,8 +115,8 @@ da9063-objs := da9063-core.o da9063-irq.o da9063-i2c.o
obj-$(CONFIG_MFD_DA9063) += da9063.o
obj-$(CONFIG_MFD_MAX14577) += max14577.o
-obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
-obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
+obj-$(CONFIG_MFD_MAX77686) += max77686.o
+obj-$(CONFIG_MFD_MAX77693) += max77693.o
obj-$(CONFIG_MFD_MAX8907) += max8907.o
max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o
@@ -169,3 +169,6 @@ obj-$(CONFIG_MFD_AS3711) += as3711.o
obj-$(CONFIG_MFD_AS3722) += as3722.o
obj-$(CONFIG_MFD_STW481X) += stw481x.o
obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o
+
+intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
+obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
index 14d9542a4eed..4e6e03d63e12 100644
--- a/drivers/mfd/aat2870-core.c
+++ b/drivers/mfd/aat2870-core.c
@@ -303,7 +303,10 @@ static ssize_t aat2870_reg_write_file(struct file *file,
while (*start == ' ')
start++;
- addr = simple_strtoul(start, &start, 16);
+ ret = kstrtoul(start, 16, &addr);
+ if (ret)
+ return ret;
+
if (addr >= AAT2870_REG_NUM) {
dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr);
return -EINVAL;
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index b348ae520629..4659ac1db039 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -91,8 +91,8 @@ static int ab3100_set_register_interruptible(struct ab3100 *ab3100,
err);
} else if (err != 2) {
dev_err(ab3100->dev,
- "write error (write register) "
- "%d bytes transferred (expected 2)\n",
+ "write error (write register)\n"
+ " %d bytes transferred (expected 2)\n",
err);
err = -EIO;
} else {
@@ -135,8 +135,8 @@ static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100,
err);
} else if (err != 2) {
dev_err(ab3100->dev,
- "write error (write test register) "
- "%d bytes transferred (expected 2)\n",
+ "write error (write test register)\n"
+ " %d bytes transferred (expected 2)\n",
err);
err = -EIO;
} else {
@@ -171,8 +171,8 @@ static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
goto get_reg_out_unlock;
} else if (err != 1) {
dev_err(ab3100->dev,
- "write error (send register address) "
- "%d bytes transferred (expected 1)\n",
+ "write error (send register address)\n"
+ " %d bytes transferred (expected 1)\n",
err);
err = -EIO;
goto get_reg_out_unlock;
@@ -189,8 +189,8 @@ static int ab3100_get_register_interruptible(struct ab3100 *ab3100,
goto get_reg_out_unlock;
} else if (err != 1) {
dev_err(ab3100->dev,
- "write error (read register) "
- "%d bytes transferred (expected 1)\n",
+ "write error (read register)\n"
+ " %d bytes transferred (expected 1)\n",
err);
err = -EIO;
goto get_reg_out_unlock;
@@ -237,8 +237,8 @@ static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
goto get_reg_page_out_unlock;
} else if (err != 1) {
dev_err(ab3100->dev,
- "write error (send first register address) "
- "%d bytes transferred (expected 1)\n",
+ "write error (send first register address)\n"
+ " %d bytes transferred (expected 1)\n",
err);
err = -EIO;
goto get_reg_page_out_unlock;
@@ -252,8 +252,8 @@ static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
goto get_reg_page_out_unlock;
} else if (err != numregs) {
dev_err(ab3100->dev,
- "write error (read register page) "
- "%d bytes transferred (expected %d)\n",
+ "write error (read register page)\n"
+ " %d bytes transferred (expected %d)\n",
err, numregs);
err = -EIO;
goto get_reg_page_out_unlock;
@@ -295,8 +295,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
goto get_maskset_unlock;
} else if (err != 1) {
dev_err(ab3100->dev,
- "write error (maskset send address) "
- "%d bytes transferred (expected 1)\n",
+ "write error (maskset send address)\n"
+ " %d bytes transferred (expected 1)\n",
err);
err = -EIO;
goto get_maskset_unlock;
@@ -310,8 +310,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
goto get_maskset_unlock;
} else if (err != 1) {
dev_err(ab3100->dev,
- "write error (maskset read register) "
- "%d bytes transferred (expected 1)\n",
+ "write error (maskset read register)\n"
+ " %d bytes transferred (expected 1)\n",
err);
err = -EIO;
goto get_maskset_unlock;
@@ -330,8 +330,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
goto get_maskset_unlock;
} else if (err != 2) {
dev_err(ab3100->dev,
- "write error (write register) "
- "%d bytes transferred (expected 2)\n",
+ "write error (write register)\n"
+ " %d bytes transferred (expected 2)\n",
err);
err = -EIO;
goto get_maskset_unlock;
@@ -371,7 +371,7 @@ EXPORT_SYMBOL(ab3100_event_register);
int ab3100_event_unregister(struct ab3100 *ab3100,
struct notifier_block *nb)
{
- return blocking_notifier_chain_unregister(&ab3100->event_subscribers,
+ return blocking_notifier_chain_unregister(&ab3100->event_subscribers,
nb);
}
EXPORT_SYMBOL(ab3100_event_unregister);
@@ -455,7 +455,7 @@ static int ab3100_registers_print(struct seq_file *s, void *p)
u8 value;
u8 reg;
- seq_printf(s, "AB3100 registers:\n");
+ seq_puts(s, "AB3100 registers:\n");
for (reg = 0; reg < 0xff; reg++) {
ab3100_get_register_interruptible(ab3100, reg, &value);
@@ -560,8 +560,8 @@ static ssize_t ab3100_get_set_reg(struct file *file,
ab3100_get_register_interruptible(ab3100, user_reg, &regvalue);
dev_info(ab3100->dev,
- "debug write reg[0x%02x] with 0x%02x, "
- "after readback: 0x%02x\n",
+ "debug write reg[0x%02x]\n"
+ " with 0x%02x, after readback: 0x%02x\n",
user_reg, user_value, regvalue);
}
return buf_size;
@@ -719,8 +719,7 @@ static int ab3100_setup(struct ab3100 *ab3100)
*/
if (ab3100->chip_id == 0xc4) {
dev_warn(ab3100->dev,
- "AB3100 P1E variant detected, "
- "forcing chip to 32KHz\n");
+ "AB3100 P1E variant detected forcing chip to 32KHz\n");
err = ab3100_set_test_register_interruptible(ab3100,
0x02, 0x08);
}
@@ -878,8 +877,7 @@ static int ab3100_probe(struct i2c_client *client,
&ab3100->chip_id);
if (err) {
dev_err(&client->dev,
- "could not communicate with the AB3100 analog "
- "baseband chip\n");
+ "failed to communicate with AB3100 chip\n");
goto exit_no_detect;
}
@@ -902,8 +900,8 @@ static int ab3100_probe(struct i2c_client *client,
if (ids[i].id == 0x0) {
dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n",
ab3100->chip_id);
- dev_err(&client->dev, "accepting it anyway. Please update "
- "the driver.\n");
+ dev_err(&client->dev,
+ "accepting it anyway. Please update the driver.\n");
goto exit_no_detect;
}
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index cf2e6a198c6b..ce48aa72bb42 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -148,8 +148,8 @@ static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = {
/* AB8540 support */
static const int ab8540_irq_regoffset[AB8540_NUM_IRQ_REGS] = {
- 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23,
- 25, 26, 27, 28, 29, 30, 31,
+ 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22,
+ 23, 25, 26, 27, 28, 29, 30, 31,
};
static const char ab8500_version_str[][7] = {
@@ -322,7 +322,7 @@ static int ab8500_mask_and_set_register(struct device *dev,
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
atomic_inc(&ab8500->transfer_ongoing);
- ret= mask_and_set_register_interruptible(ab8500, bank, reg,
+ ret = mask_and_set_register_interruptible(ab8500, bank, reg,
bitmask, bitvalues);
atomic_dec(&ab8500->transfer_ongoing);
return ret;
@@ -415,9 +415,11 @@ static void ab8500_irq_unmask(struct irq_data *data)
if (type & IRQ_TYPE_EDGE_FALLING) {
if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
ab8500->mask[index + 2] &= ~mask;
- else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
+ else if (offset >= AB9540_INT_GPIO50R &&
+ offset <= AB9540_INT_GPIO54R)
ab8500->mask[index + 1] &= ~mask;
- else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
+ else if (offset == AB8540_INT_GPIO43R ||
+ offset == AB8540_INT_GPIO44R)
/* Here the falling IRQ is one bit lower */
ab8500->mask[index] &= ~(mask << 1);
else
@@ -451,7 +453,7 @@ static void update_latch_offset(u8 *offset, int i)
/* Fix inconsistent ab8540 bit mapping... */
if (unlikely(*offset == 16))
*offset = 25;
- if ((i==3) && (*offset >= 24))
+ if ((i == 3) && (*offset >= 24))
*offset += 2;
}
@@ -573,8 +575,8 @@ static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
}
static struct irq_domain_ops ab8500_irq_ops = {
- .map = ab8500_irq_map,
- .xlate = irq_domain_xlate_twocell,
+ .map = ab8500_irq_map,
+ .xlate = irq_domain_xlate_twocell,
};
static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
@@ -607,8 +609,8 @@ int ab8500_suspend(struct ab8500 *ab8500)
{
if (atomic_read(&ab8500->transfer_ongoing))
return -EINVAL;
- else
- return 0;
+
+ return 0;
}
static struct resource ab8500_gpadc_resources[] = {
@@ -1551,7 +1553,7 @@ static struct attribute_group ab9540_attr_group = {
static int ab8500_probe(struct platform_device *pdev)
{
- static char *switch_off_status[] = {
+ static const char *switch_off_status[] = {
"Swoff bit programming",
"Thermal protection activation",
"Vbat lower then BattOk falling threshold",
@@ -1560,7 +1562,7 @@ static int ab8500_probe(struct platform_device *pdev)
"Battery level lower than power on reset threshold",
"Power on key 1 pressed longer than 10 seconds",
"DB8500 thermal shutdown"};
- static char *turn_on_status[] = {
+ static const char *turn_on_status[] = {
"Battery rising (Vbat)",
"Power On Key 1 dbF",
"Power On Key 2 dbF",
@@ -1579,7 +1581,7 @@ static int ab8500_probe(struct platform_device *pdev)
int i;
u8 value;
- ab8500 = devm_kzalloc(&pdev->dev, sizeof *ab8500, GFP_KERNEL);
+ ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL);
if (!ab8500)
return -ENOMEM;
@@ -1636,7 +1638,7 @@ static int ab8500_probe(struct platform_device *pdev)
ab8500->mask_size = AB8540_NUM_IRQ_REGS;
ab8500->irq_reg_offset = ab8540_irq_regoffset;
ab8500->it_latchhier_num = AB8540_IT_LATCHHIER_NUM;
- }/* Configure AB8500 or AB9540 IRQ */
+ } /* Configure AB8500 or AB9540 IRQ */
else if (is_ab9540(ab8500) || is_ab8505(ab8500)) {
ab8500->mask_size = AB9540_NUM_IRQ_REGS;
ab8500->irq_reg_offset = ab9540_irq_regoffset;
@@ -1646,10 +1648,12 @@ static int ab8500_probe(struct platform_device *pdev)
ab8500->irq_reg_offset = ab8500_irq_regoffset;
ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM;
}
- ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
+ ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size,
+ GFP_KERNEL);
if (!ab8500->mask)
return -ENOMEM;
- ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL);
+ ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size,
+ GFP_KERNEL);
if (!ab8500->oldmask)
return -ENOMEM;
@@ -1674,14 +1678,13 @@ static int ab8500_probe(struct platform_device *pdev)
if (value) {
for (i = 0; i < ARRAY_SIZE(switch_off_status); i++) {
if (value & 1)
- printk(KERN_CONT " \"%s\"",
- switch_off_status[i]);
+ pr_cont(" \"%s\"", switch_off_status[i]);
value = value >> 1;
}
- printk(KERN_CONT "\n");
+ pr_cont("\n");
} else {
- printk(KERN_CONT " None\n");
+ pr_cont(" None\n");
}
ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK,
AB8500_TURN_ON_STATUS, &value);
@@ -1692,12 +1695,12 @@ static int ab8500_probe(struct platform_device *pdev)
if (value) {
for (i = 0; i < ARRAY_SIZE(turn_on_status); i++) {
if (value & 1)
- printk("\"%s\" ", turn_on_status[i]);
+ pr_cont("\"%s\" ", turn_on_status[i]);
value = value >> 1;
}
- printk("\n");
+ pr_cont("\n");
} else {
- printk("None\n");
+ pr_cont("None\n");
}
if (plat && plat->init)
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index d1a22aae2df5..b2c7e3b1edfa 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -135,10 +135,10 @@ struct ab8500_prcmu_ranges {
/* hwreg- "mask" and "shift" entries ressources */
struct hwreg_cfg {
u32 bank; /* target bank */
- u32 addr; /* target address */
+ unsigned long addr; /* target address */
uint fmt; /* format */
- uint mask; /* read/write mask, applied before any bit shift */
- int shift; /* bit shift (read:right shift, write:left shift */
+ unsigned long mask; /* read/write mask, applied before any bit shift */
+ long shift; /* bit shift (read:right shift, write:left shift */
};
/* fmt bit #0: 0=hexa, 1=dec */
#define REG_FMT_DEC(c) ((c)->fmt & 0x1)
@@ -1304,16 +1304,17 @@ static int ab8500_registers_print(struct device *dev, u32 bank,
}
if (s) {
- err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
- bank, reg, value);
+ err = seq_printf(s,
+ " [0x%02X/0x%02X]: 0x%02X\n",
+ bank, reg, value);
if (err < 0) {
/* Error is not returned here since
* the output is wanted in any case */
return 0;
}
} else {
- printk(KERN_INFO" [0x%02X/0x%02X]: 0x%02X\n",
- bank, reg, value);
+ dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n",
+ bank, reg, value);
}
}
}
@@ -1325,7 +1326,7 @@ static int ab8500_print_bank_registers(struct seq_file *s, void *p)
struct device *dev = s->private;
u32 bank = debug_bank;
- seq_printf(s, AB8500_NAME_STRING " register values:\n");
+ seq_puts(s, AB8500_NAME_STRING " register values:\n");
seq_printf(s, " bank 0x%02X:\n", bank);
@@ -1350,12 +1351,11 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p)
{
struct device *dev = s->private;
unsigned int i;
- int err;
- seq_printf(s, AB8500_NAME_STRING " register values:\n");
+ seq_puts(s, AB8500_NAME_STRING " register values:\n");
for (i = 0; i < AB8500_NUM_BANKS; i++) {
- err = seq_printf(s, " bank 0x%02X:\n", i);
+ seq_printf(s, " bank 0x%02X:\n", i);
ab8500_registers_print(dev, i, s);
}
@@ -1367,10 +1367,10 @@ void ab8500_dump_all_banks(struct device *dev)
{
unsigned int i;
- printk(KERN_INFO"ab8500 register values:\n");
+ dev_info(dev, "ab8500 register values:\n");
for (i = 1; i < AB8500_NUM_BANKS; i++) {
- printk(KERN_INFO" bank 0x%02X:\n", i);
+ dev_info(dev, " bank 0x%02X:\n", i);
ab8500_registers_print(dev, i, NULL);
}
}
@@ -1384,8 +1384,6 @@ static struct ab8500_register_dump
u8 value;
} ab8500_complete_register_dump[DUMP_MAX_REGS];
-extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-
/* This shall only be called upon kernel panic! */
void ab8500_dump_all_banks_to_mem(void)
{
@@ -1393,8 +1391,7 @@ void ab8500_dump_all_banks_to_mem(void)
u8 bank;
int err = 0;
- pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" "
- "for crash analyze.\n");
+ pr_info("Saving all ABB registers for crash analysis.\n");
for (bank = 0; bank < AB8500_NUM_BANKS; bank++) {
for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
@@ -1564,7 +1561,7 @@ static ssize_t ab8500_val_write(struct file *file,
err = abx500_set_register_interruptible(dev,
(u8)debug_bank, debug_address, (u8)user_val);
if (err < 0) {
- printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__);
+ pr_err("abx500_set_reg failed %d, %d", err, __LINE__);
return -EINVAL;
}
@@ -1596,7 +1593,7 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
{
int line;
- seq_printf(s, "name: number: number of: wake:\n");
+ seq_puts(s, "name: number: number of: wake:\n");
for (line = 0; line < num_interrupt_lines; line++) {
struct irq_desc *desc = irq_to_desc(line + irq_first);
@@ -1722,7 +1719,8 @@ static int ab8500_print_modem_registers(struct seq_file *s, void *p)
static int ab8500_modem_open(struct inode *inode, struct file *file)
{
- return single_open(file, ab8500_print_modem_registers, inode->i_private);
+ return single_open(file, ab8500_print_modem_registers,
+ inode->i_private);
}
static const struct file_operations ab8500_modem_fops = {
@@ -1751,7 +1749,8 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
{
- return single_open(file, ab8500_gpadc_bat_ctrl_print, inode->i_private);
+ return single_open(file, ab8500_gpadc_bat_ctrl_print,
+ inode->i_private);
}
static const struct file_operations ab8500_gpadc_bat_ctrl_fops = {
@@ -1781,7 +1780,8 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
struct file *file)
{
- return single_open(file, ab8500_gpadc_btemp_ball_print, inode->i_private);
+ return single_open(file, ab8500_gpadc_btemp_ball_print,
+ inode->i_private);
}
static const struct file_operations ab8500_gpadc_btemp_ball_fops = {
@@ -1962,7 +1962,8 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
struct file *file)
{
- return single_open(file, ab8500_gpadc_main_bat_v_print, inode->i_private);
+ return single_open(file, ab8500_gpadc_main_bat_v_print,
+ inode->i_private);
}
static const struct file_operations ab8500_gpadc_main_bat_v_fops = {
@@ -2082,7 +2083,8 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
{
- return single_open(file, ab8500_gpadc_bk_bat_v_print, inode->i_private);
+ return single_open(file, ab8500_gpadc_bk_bat_v_print,
+ inode->i_private);
}
static const struct file_operations ab8500_gpadc_bk_bat_v_fops = {
@@ -2111,7 +2113,8 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
{
- return single_open(file, ab8500_gpadc_die_temp_print, inode->i_private);
+ return single_open(file, ab8500_gpadc_die_temp_print,
+ inode->i_private);
}
static const struct file_operations ab8500_gpadc_die_temp_fops = {
@@ -2190,8 +2193,9 @@ static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS,
avg_sample, trig_edge, trig_timer, conv_type);
- vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
- vbat_true_meas_raw);
+ vbat_true_meas_convert =
+ ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
+ vbat_true_meas_raw);
return seq_printf(s, "%d,0x%X\n",
vbat_true_meas_convert, vbat_true_meas_raw);
@@ -2285,7 +2289,8 @@ static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = {
.owner = THIS_MODULE,
};
-static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p)
+static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s,
+ void *p)
{
int vbat_true_meas_raw;
int vbat_true_meas_convert;
@@ -2314,7 +2319,8 @@ static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
inode->i_private);
}
-static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
+static const struct file_operations
+ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
.open = ab8540_gpadc_vbat_true_meas_and_ibat_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -2368,14 +2374,15 @@ static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h,
&vbat_l, &vbat_h, &ibat_l, &ibat_h);
return seq_printf(s, "VMAIN_L:0x%X\n"
- "VMAIN_H:0x%X\n"
- "BTEMP_L:0x%X\n"
- "BTEMP_H:0x%X\n"
- "VBAT_L:0x%X\n"
- "VBAT_H:0x%X\n"
- "IBAT_L:0x%X\n"
- "IBAT_H:0x%X\n",
- vmain_l, vmain_h, btemp_l, btemp_h, vbat_l, vbat_h, ibat_l, ibat_h);
+ "VMAIN_H:0x%X\n"
+ "BTEMP_L:0x%X\n"
+ "BTEMP_H:0x%X\n"
+ "VBAT_L:0x%X\n"
+ "VBAT_H:0x%X\n"
+ "IBAT_L:0x%X\n"
+ "IBAT_H:0x%X\n",
+ vmain_l, vmain_h, btemp_l, btemp_h,
+ vbat_l, vbat_h, ibat_l, ibat_h);
}
static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
@@ -2419,8 +2426,8 @@ static ssize_t ab8500_gpadc_avg_sample_write(struct file *file,
|| (user_avg_sample == SAMPLE_16)) {
avg_sample = (u8) user_avg_sample;
} else {
- dev_err(dev, "debugfs error input: "
- "should be egal to 1, 4, 8 or 16\n");
+ dev_err(dev,
+ "debugfs err input: should be egal to 1, 4, 8 or 16\n");
return -EINVAL;
}
@@ -2504,14 +2511,14 @@ static ssize_t ab8500_gpadc_trig_timer_write(struct file *file,
if (err)
return err;
- if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) {
- trig_timer = (u8) user_trig_timer;
- } else {
- dev_err(dev, "debugfs error input: "
- "should be beetween 0 to 255\n");
+ if (user_trig_timer & ~0xFF) {
+ dev_err(dev,
+ "debugfs error input: should be beetween 0 to 255\n");
return -EINVAL;
}
+ trig_timer = (u8) user_trig_timer;
+
return count;
}
@@ -2579,6 +2586,7 @@ static const struct file_operations ab8500_gpadc_conv_type_fops = {
static int strval_len(char *b)
{
char *s = b;
+
if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
s += 2;
for (; *s && (*s != ' ') && (*s != '\n'); s++) {
@@ -2643,13 +2651,17 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
b += (*(b+2) == ' ') ? 3 : 6;
if (strval_len(b) == 0)
return -EINVAL;
- loc.mask = simple_strtoul(b, &b, 0);
+ ret = kstrtoul(b, 0, &loc.mask);
+ if (ret)
+ return ret;
} else if ((!strncmp(b, "-s ", 3)) ||
(!strncmp(b, "-shift ", 7))) {
b += (*(b+2) == ' ') ? 3 : 7;
if (strval_len(b) == 0)
return -EINVAL;
- loc.shift = simple_strtol(b, &b, 0);
+ ret = kstrtol(b, 0, &loc.shift);
+ if (ret)
+ return ret;
} else {
return -EINVAL;
}
@@ -2657,29 +2669,36 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
/* get arg BANK and ADDRESS */
if (strval_len(b) == 0)
return -EINVAL;
- loc.bank = simple_strtoul(b, &b, 0);
+ ret = kstrtouint(b, 0, &loc.bank);
+ if (ret)
+ return ret;
while (*b == ' ')
b++;
if (strval_len(b) == 0)
return -EINVAL;
- loc.addr = simple_strtoul(b, &b, 0);
+ ret = kstrtoul(b, 0, &loc.addr);
+ if (ret)
+ return ret;
if (write) {
while (*b == ' ')
b++;
if (strval_len(b) == 0)
return -EINVAL;
- val = simple_strtoul(b, &b, 0);
+ ret = kstrtouint(b, 0, &val);
+ if (ret)
+ return ret;
}
/* args are ok, update target cfg (mainly for read) */
*cfg = loc;
#ifdef ABB_HWREG_DEBUG
- pr_warn("HWREG request: %s, %s, addr=0x%08X, mask=0x%X, shift=%d"
- "value=0x%X\n", (write) ? "write" : "read",
- REG_FMT_DEC(cfg) ? "decimal" : "hexa",
- cfg->addr, cfg->mask, cfg->shift, val);
+ pr_warn("HWREG request: %s, %s,\n"
+ " addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n",
+ (write) ? "write" : "read",
+ REG_FMT_DEC(cfg) ? "decimal" : "hexa",
+ cfg->addr, cfg->mask, cfg->shift, val);
#endif
if (!write)
@@ -2765,8 +2784,8 @@ static ssize_t show_irq(struct device *dev,
irq_index = name - irq_first;
if (irq_index >= num_irqs)
return -EINVAL;
- else
- return sprintf(buf, "%u\n", irq_count[irq_index]);
+
+ return sprintf(buf, "%u\n", irq_count[irq_index]);
}
static ssize_t ab8500_subscribe_write(struct file *file,
@@ -2815,7 +2834,7 @@ static ssize_t ab8500_subscribe_write(struct file *file,
dev_attr[irq_index]->attr.mode = S_IRUGO;
err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
if (err < 0) {
- printk(KERN_ERR "sysfs_create_file failed %d\n", err);
+ pr_info("sysfs_create_file failed %d\n", err);
return err;
}
@@ -2823,8 +2842,8 @@ static ssize_t ab8500_subscribe_write(struct file *file,
IRQF_SHARED | IRQF_NO_SUSPEND,
"ab8500-debug", &dev->kobj);
if (err < 0) {
- printk(KERN_ERR "request_threaded_irq failed %d, %lu\n",
- err, user_val);
+ pr_info("request_threaded_irq failed %d, %lu\n",
+ err, user_val);
sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
return err;
}
@@ -2946,6 +2965,7 @@ static int ab8500_debug_probe(struct platform_device *plf)
struct dentry *file;
struct ab8500 *ab8500;
struct resource *res;
+
debug_bank = AB8500_MISC;
debug_address = AB8500_REV_REG & 0x00FF;
@@ -2958,7 +2978,7 @@ static int ab8500_debug_probe(struct platform_device *plf)
return -ENOMEM;
dev_attr = devm_kzalloc(&plf->dev,
- sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
+ sizeof(*dev_attr)*num_irqs, GFP_KERNEL);
if (!dev_attr)
return -ENOMEM;
@@ -2969,23 +2989,20 @@ static int ab8500_debug_probe(struct platform_device *plf)
res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
if (!res) {
- dev_err(&plf->dev, "AB8500 irq not found, err %d\n",
- irq_first);
- return ENXIO;
+ dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first);
+ return -ENXIO;
}
irq_ab8500 = res->start;
irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
if (irq_first < 0) {
- dev_err(&plf->dev, "First irq not found, err %d\n",
- irq_first);
+ dev_err(&plf->dev, "First irq not found, err %d\n", irq_first);
return irq_first;
}
irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
if (irq_last < 0) {
- dev_err(&plf->dev, "Last irq not found, err %d\n",
- irq_last);
+ dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last);
return irq_last;
}
@@ -2994,37 +3011,41 @@ static int ab8500_debug_probe(struct platform_device *plf)
goto err;
ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING,
- ab8500_dir);
+ ab8500_dir);
if (!ab8500_gpadc_dir)
goto err;
- file = debugfs_create_file("all-bank-registers", S_IRUGO,
- ab8500_dir, &plf->dev, &ab8500_registers_fops);
+ file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
+ &plf->dev, &ab8500_registers_fops);
if (!file)
goto err;
- file = debugfs_create_file("all-banks", S_IRUGO,
- ab8500_dir, &plf->dev, &ab8500_all_banks_fops);
+ file = debugfs_create_file("all-banks", S_IRUGO, ab8500_dir,
+ &plf->dev, &ab8500_all_banks_fops);
if (!file)
goto err;
- file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_bank_fops);
+ file = debugfs_create_file("register-bank",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_dir, &plf->dev, &ab8500_bank_fops);
if (!file)
goto err;
- file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_address_fops);
+ file = debugfs_create_file("register-address",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_dir, &plf->dev, &ab8500_address_fops);
if (!file)
goto err;
- file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_val_fops);
+ file = debugfs_create_file("register-value",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_dir, &plf->dev, &ab8500_val_fops);
if (!file)
goto err;
- file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
+ file = debugfs_create_file("irq-subscribe",
+ (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
+ &plf->dev, &ab8500_subscribe_fops);
if (!file)
goto err;
@@ -3042,158 +3063,191 @@ static int ab8500_debug_probe(struct platform_device *plf)
num_interrupt_lines = AB8540_NR_IRQS;
}
- file = debugfs_create_file("interrupts", (S_IRUGO),
- ab8500_dir, &plf->dev, &ab8500_interrupts_fops);
+ file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir,
+ &plf->dev, &ab8500_interrupts_fops);
if (!file)
goto err;
- file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
+ file = debugfs_create_file("irq-unsubscribe",
+ (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
+ &plf->dev, &ab8500_unsubscribe_fops);
if (!file)
goto err;
file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
+ ab8500_dir, &plf->dev, &ab8500_hwreg_fops);
if (!file)
goto err;
- file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_modem_fops);
+ file = debugfs_create_file("all-modem-registers",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_dir, &plf->dev, &ab8500_modem_fops);
if (!file)
goto err;
file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_bat_ctrl_fops);
if (!file)
goto err;
file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops);
+ ab8500_gpadc_dir,
+ &plf->dev, &ab8500_gpadc_btemp_ball_fops);
if (!file)
goto err;
- file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops);
+ file = debugfs_create_file("main_charger_v",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_main_charger_v_fops);
if (!file)
goto err;
- file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops);
+ file = debugfs_create_file("acc_detect1",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_acc_detect1_fops);
if (!file)
goto err;
- file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops);
+ file = debugfs_create_file("acc_detect2",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_acc_detect2_fops);
if (!file)
goto err;
file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_aux1_fops);
if (!file)
goto err;
file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_aux2_fops);
if (!file)
goto err;
file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_main_bat_v_fops);
if (!file)
goto err;
file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_vbus_v_fops);
if (!file)
goto err;
- file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops);
+ file = debugfs_create_file("main_charger_c",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_main_charger_c_fops);
if (!file)
goto err;
- file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
+ file = debugfs_create_file("usb_charger_c",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir,
+ &plf->dev, &ab8500_gpadc_usb_charger_c_fops);
if (!file)
goto err;
file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_bk_bat_v_fops);
if (!file)
goto err;
file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_die_temp_fops);
if (!file)
goto err;
file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_id_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_usb_id_fops);
if (!file)
goto err;
if (is_ab8540(ab8500)) {
- file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops);
+ file = debugfs_create_file("xtal_temp",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8540_gpadc_xtal_temp_fops);
if (!file)
goto err;
- file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev,
- &ab8540_gpadc_vbat_true_meas_fops);
+ file = debugfs_create_file("vbattruemeas",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8540_gpadc_vbat_true_meas_fops);
if (!file)
goto err;
file = debugfs_create_file("batctrl_and_ibat",
- (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
- &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops);
+ (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir,
+ &plf->dev,
+ &ab8540_gpadc_bat_ctrl_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("vbatmeas_and_ibat",
- (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
- &plf->dev,
- &ab8540_gpadc_vbat_meas_and_ibat_fops);
+ (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8540_gpadc_vbat_meas_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("vbattruemeas_and_ibat",
- (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
- &plf->dev,
- &ab8540_gpadc_vbat_true_meas_and_ibat_fops);
+ (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir,
+ &plf->dev,
+ &ab8540_gpadc_vbat_true_meas_and_ibat_fops);
if (!file)
goto err;
file = debugfs_create_file("battemp_and_ibat",
- (S_IRUGO | S_IWUGO), ab8500_gpadc_dir,
+ (S_IRUGO | S_IWUGO),
+ ab8500_gpadc_dir,
&plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops);
if (!file)
goto err;
- file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops);
+ file = debugfs_create_file("otp_calib",
+ (S_IRUGO | S_IWUSR | S_IWGRP),
+ ab8500_gpadc_dir,
+ &plf->dev, &ab8540_gpadc_otp_calib_fops);
if (!file)
goto err;
}
file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_avg_sample_fops);
if (!file)
goto err;
file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_trig_edge_fops);
if (!file)
goto err;
file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_trig_timer_fops);
if (!file)
goto err;
file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops);
+ ab8500_gpadc_dir, &plf->dev,
+ &ab8500_gpadc_conv_type_fops);
if (!file)
goto err;
return 0;
err:
- if (ab8500_dir)
- debugfs_remove_recursive(ab8500_dir);
+ debugfs_remove_recursive(ab8500_dir);
dev_err(&plf->dev, "failed to create debugfs entries.\n");
return -ENOMEM;
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index cfc191abae4a..10a0cb90619a 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -123,6 +123,8 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
dev_err(arizona->dev, "AIF2 underclocked\n");
if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
dev_err(arizona->dev, "AIF1 underclocked\n");
+ if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS)
+ dev_err(arizona->dev, "ISRC3 underclocked\n");
if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
dev_err(arizona->dev, "ISRC2 underclocked\n");
if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS)
@@ -192,6 +194,8 @@ static irqreturn_t arizona_overclocked(int irq, void *data)
dev_err(arizona->dev, "ASRC sync WARP overclocked\n");
if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS)
dev_err(arizona->dev, "DSP1 overclocked\n");
+ if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS)
+ dev_err(arizona->dev, "ISRC3 overclocked\n");
if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS)
dev_err(arizona->dev, "ISRC2 overclocked\n");
if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS)
@@ -497,12 +501,12 @@ const struct dev_pm_ops arizona_pm_ops = {
EXPORT_SYMBOL_GPL(arizona_pm_ops);
#ifdef CONFIG_OF
-int arizona_of_get_type(struct device *dev)
+unsigned long arizona_of_get_type(struct device *dev)
{
const struct of_device_id *id = of_match_device(arizona_of_match, dev);
if (id)
- return (int)id->data;
+ return (unsigned long)id->data;
else
return 0;
}
@@ -578,17 +582,21 @@ static const struct mfd_cell early_devs[] = {
};
static const char *wm5102_supplies[] = {
+ "MICVDD",
"DBVDD2",
"DBVDD3",
"CPVDD",
"SPKVDDL",
"SPKVDDR",
- "MICVDD",
};
static const struct mfd_cell wm5102_devs[] = {
{ .name = "arizona-micsupp" },
- { .name = "arizona-extcon" },
+ {
+ .name = "arizona-extcon",
+ .parent_supplies = wm5102_supplies,
+ .num_parent_supplies = 1, /* We only need MICVDD */
+ },
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
@@ -601,7 +609,11 @@ static const struct mfd_cell wm5102_devs[] = {
static const struct mfd_cell wm5110_devs[] = {
{ .name = "arizona-micsupp" },
- { .name = "arizona-extcon" },
+ {
+ .name = "arizona-extcon",
+ .parent_supplies = wm5102_supplies,
+ .num_parent_supplies = 1, /* We only need MICVDD */
+ },
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
@@ -613,6 +625,7 @@ static const struct mfd_cell wm5110_devs[] = {
};
static const char *wm8997_supplies[] = {
+ "MICVDD",
"DBVDD2",
"CPVDD",
"SPKVDD",
@@ -620,7 +633,11 @@ static const char *wm8997_supplies[] = {
static const struct mfd_cell wm8997_devs[] = {
{ .name = "arizona-micsupp" },
- { .name = "arizona-extcon" },
+ {
+ .name = "arizona-extcon",
+ .parent_supplies = wm8997_supplies,
+ .num_parent_supplies = 1, /* We only need MICVDD */
+ },
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
@@ -683,7 +700,13 @@ int arizona_dev_init(struct arizona *arizona)
goto err_early;
}
- arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD");
+ /**
+ * Don't use devres here because the only device we have to get
+ * against is the MFD device and DCVDD will likely be supplied by
+ * one of its children. Meaning that the regulator will be
+ * destroyed by the time devres calls regulator put.
+ */
+ arizona->dcvdd = regulator_get(arizona->dev, "DCVDD");
if (IS_ERR(arizona->dcvdd)) {
ret = PTR_ERR(arizona->dcvdd);
dev_err(dev, "Failed to request DCVDD: %d\n", ret);
@@ -697,7 +720,7 @@ int arizona_dev_init(struct arizona *arizona)
"arizona /RESET");
if (ret != 0) {
dev_err(dev, "Failed to request /RESET: %d\n", ret);
- goto err_early;
+ goto err_dcvdd;
}
}
@@ -706,7 +729,7 @@ int arizona_dev_init(struct arizona *arizona)
if (ret != 0) {
dev_err(dev, "Failed to enable core supplies: %d\n",
ret);
- goto err_early;
+ goto err_dcvdd;
}
ret = regulator_enable(arizona->dcvdd);
@@ -1015,6 +1038,8 @@ err_reset:
err_enable:
regulator_bulk_disable(arizona->num_core_supplies,
arizona->core_supplies);
+err_dcvdd:
+ regulator_put(arizona->dcvdd);
err_early:
mfd_remove_devices(dev);
return ret;
@@ -1023,16 +1048,20 @@ EXPORT_SYMBOL_GPL(arizona_dev_init);
int arizona_dev_exit(struct arizona *arizona)
{
+ pm_runtime_disable(arizona->dev);
+
+ regulator_disable(arizona->dcvdd);
+ regulator_put(arizona->dcvdd);
+
mfd_remove_devices(arizona->dev);
arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
- pm_runtime_disable(arizona->dev);
arizona_irq_exit(arizona);
if (arizona->pdata.reset)
gpio_set_value_cansleep(arizona->pdata.reset, 0);
- regulator_disable(arizona->dcvdd);
- regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
+
+ regulator_bulk_disable(arizona->num_core_supplies,
arizona->core_supplies);
return 0;
}
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index beccb790c9ba..9d4156fb082a 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -24,11 +24,12 @@
#include "arizona.h"
static int arizona_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret, type;
+ unsigned long type;
+ int ret;
if (i2c->dev.of_node)
type = arizona_of_get_type(&i2c->dev);
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 17102f589100..d420dbc0e2b0 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -188,24 +188,33 @@ int arizona_irq_init(struct arizona *arizona)
int flags = IRQF_ONESHOT;
int ret, i;
const struct regmap_irq_chip *aod, *irq;
- bool ctrlif_error = true;
struct irq_data *irq_data;
+ arizona->ctrlif_error = true;
+
switch (arizona->type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
aod = &wm5102_aod;
irq = &wm5102_irq;
- ctrlif_error = false;
+ arizona->ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
aod = &wm5110_aod;
- irq = &wm5110_irq;
- ctrlif_error = false;
+ switch (arizona->rev) {
+ case 0 ... 2:
+ irq = &wm5110_irq;
+ break;
+ default:
+ irq = &wm5110_revd_irq;
+ break;
+ }
+
+ arizona->ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_WM8997
@@ -213,7 +222,7 @@ int arizona_irq_init(struct arizona *arizona)
aod = &wm8997_aod;
irq = &wm8997_irq;
- ctrlif_error = false;
+ arizona->ctrlif_error = false;
break;
#endif
default:
@@ -300,7 +309,7 @@ int arizona_irq_init(struct arizona *arizona)
}
/* Handle control interface errors in the core */
- if (ctrlif_error) {
+ if (arizona->ctrlif_error) {
i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
IRQF_ONESHOT,
@@ -345,7 +354,9 @@ int arizona_irq_init(struct arizona *arizona)
return 0;
err_main_irq:
- free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona);
+ if (arizona->ctrlif_error)
+ free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
+ arizona);
err_ctrlif:
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
err_boot_done:
@@ -361,7 +372,9 @@ err:
int arizona_irq_exit(struct arizona *arizona)
{
- free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona);
+ if (arizona->ctrlif_error)
+ free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
+ arizona);
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1),
arizona->irq_chip);
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 1ca554b18bef..5145d78bf07e 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -28,7 +28,8 @@ static int arizona_spi_probe(struct spi_device *spi)
const struct spi_device_id *id = spi_get_device_id(spi);
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret, type;
+ unsigned long type;
+ int ret;
if (spi->dev.of_node)
type = arizona_of_get_type(&spi->dev);
diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h
index b4cef777df73..fbe2843271c5 100644
--- a/drivers/mfd/arizona.h
+++ b/drivers/mfd/arizona.h
@@ -36,6 +36,7 @@ extern const struct regmap_irq_chip wm5102_irq;
extern const struct regmap_irq_chip wm5110_aod;
extern const struct regmap_irq_chip wm5110_irq;
+extern const struct regmap_irq_chip wm5110_revd_irq;
extern const struct regmap_irq_chip wm8997_aod;
extern const struct regmap_irq_chip wm8997_irq;
@@ -46,9 +47,9 @@ int arizona_irq_init(struct arizona *arizona);
int arizona_irq_exit(struct arizona *arizona);
#ifdef CONFIG_OF
-int arizona_of_get_type(struct device *dev);
+unsigned long arizona_of_get_type(struct device *dev);
#else
-static inline int arizona_of_get_type(struct device *dev)
+static inline unsigned long arizona_of_get_type(struct device *dev)
{
return 0;
}
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 9f6294f2a070..9fc4186d4132 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -899,13 +899,15 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
ds1wm_resources[0].end >>= asic->bus_shift;
/* MMC */
- asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
+ if (mem_sdio) {
+ asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
mem_sdio->start,
ASIC3_SD_CONFIG_SIZE >> asic->bus_shift);
- if (!asic->tmio_cnf) {
- ret = -ENOMEM;
- dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n");
- goto out;
+ if (!asic->tmio_cnf) {
+ ret = -ENOMEM;
+ dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n");
+ goto out;
+ }
}
asic3_mmc_resources[0].start >>= asic->bus_shift;
asic3_mmc_resources[0].end >>= asic->bus_shift;
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 38fe9bf0d169..4873f9c50452 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -25,64 +25,42 @@
#include <linux/mfd/cros_ec_commands.h>
int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
- struct cros_ec_msg *msg)
+ struct cros_ec_command *msg)
{
uint8_t *out;
int csum, i;
- BUG_ON(msg->out_len > EC_PROTO2_MAX_PARAM_SIZE);
+ BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
out = ec_dev->dout;
out[0] = EC_CMD_VERSION0 + msg->version;
- out[1] = msg->cmd;
- out[2] = msg->out_len;
+ out[1] = msg->command;
+ out[2] = msg->outsize;
csum = out[0] + out[1] + out[2];
- for (i = 0; i < msg->out_len; i++)
- csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->out_buf[i];
- out[EC_MSG_TX_HEADER_BYTES + msg->out_len] = (uint8_t)(csum & 0xff);
+ for (i = 0; i < msg->outsize; i++)
+ csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->outdata[i];
+ out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
- return EC_MSG_TX_PROTO_BYTES + msg->out_len;
+ return EC_MSG_TX_PROTO_BYTES + msg->outsize;
}
EXPORT_SYMBOL(cros_ec_prepare_tx);
-static int cros_ec_command_sendrecv(struct cros_ec_device *ec_dev,
- uint16_t cmd, void *out_buf, int out_len,
- void *in_buf, int in_len)
+int cros_ec_check_result(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg)
{
- struct cros_ec_msg msg;
-
- msg.version = cmd >> 8;
- msg.cmd = cmd & 0xff;
- msg.out_buf = out_buf;
- msg.out_len = out_len;
- msg.in_buf = in_buf;
- msg.in_len = in_len;
-
- return ec_dev->command_xfer(ec_dev, &msg);
-}
-
-static int cros_ec_command_recv(struct cros_ec_device *ec_dev,
- uint16_t cmd, void *buf, int buf_len)
-{
- return cros_ec_command_sendrecv(ec_dev, cmd, NULL, 0, buf, buf_len);
-}
-
-static int cros_ec_command_send(struct cros_ec_device *ec_dev,
- uint16_t cmd, void *buf, int buf_len)
-{
- return cros_ec_command_sendrecv(ec_dev, cmd, buf, buf_len, NULL, 0);
-}
-
-static irqreturn_t ec_irq_thread(int irq, void *data)
-{
- struct cros_ec_device *ec_dev = data;
-
- if (device_may_wakeup(ec_dev->dev))
- pm_wakeup_event(ec_dev->dev, 0);
-
- blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev);
-
- return IRQ_HANDLED;
+ switch (msg->result) {
+ case EC_RES_SUCCESS:
+ return 0;
+ case EC_RES_IN_PROGRESS:
+ dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
+ msg->command);
+ return -EAGAIN;
+ default:
+ dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
+ msg->command, msg->result);
+ return 0;
+ }
}
+EXPORT_SYMBOL(cros_ec_check_result);
static const struct mfd_cell cros_devs[] = {
{
@@ -102,12 +80,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
struct device *dev = ec_dev->dev;
int err = 0;
- BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
-
- ec_dev->command_send = cros_ec_command_send;
- ec_dev->command_recv = cros_ec_command_recv;
- ec_dev->command_sendrecv = cros_ec_command_sendrecv;
-
if (ec_dev->din_size) {
ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
if (!ec_dev->din)
@@ -119,42 +91,23 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
return -ENOMEM;
}
- if (!ec_dev->irq) {
- dev_dbg(dev, "no valid IRQ: %d\n", ec_dev->irq);
- return err;
- }
-
- err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "chromeos-ec", ec_dev);
- if (err) {
- dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err);
- return err;
- }
-
err = mfd_add_devices(dev, 0, cros_devs,
ARRAY_SIZE(cros_devs),
NULL, ec_dev->irq, NULL);
if (err) {
dev_err(dev, "failed to add mfd devices\n");
- goto fail_mfd;
+ return err;
}
- dev_info(dev, "Chrome EC (%s)\n", ec_dev->name);
+ dev_info(dev, "Chrome EC device registered\n");
return 0;
-
-fail_mfd:
- free_irq(ec_dev->irq, ec_dev);
-
- return err;
}
EXPORT_SYMBOL(cros_ec_register);
int cros_ec_remove(struct cros_ec_device *ec_dev)
{
mfd_remove_devices(ec_dev->dev);
- free_irq(ec_dev->irq, ec_dev);
return 0;
}
diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c
index 4f71be99a183..c0c30f4f946f 100644
--- a/drivers/mfd/cros_ec_i2c.c
+++ b/drivers/mfd/cros_ec_i2c.c
@@ -29,12 +29,13 @@ static inline struct cros_ec_device *to_ec_dev(struct device *dev)
return i2c_get_clientdata(client);
}
-static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
- struct cros_ec_msg *msg)
+static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg)
{
struct i2c_client *client = ec_dev->priv;
int ret = -ENOMEM;
int i;
+ int len;
int packet_len;
u8 *out_buf = NULL;
u8 *in_buf = NULL;
@@ -50,7 +51,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
* allocate larger packet (one byte for checksum, one byte for
* length, and one for result code)
*/
- packet_len = msg->in_len + 3;
+ packet_len = msg->insize + 3;
in_buf = kzalloc(packet_len, GFP_KERNEL);
if (!in_buf)
goto done;
@@ -61,7 +62,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
* allocate larger packet (one byte for checksum, one for
* command code, one for length, and one for command version)
*/
- packet_len = msg->out_len + 4;
+ packet_len = msg->outsize + 4;
out_buf = kzalloc(packet_len, GFP_KERNEL);
if (!out_buf)
goto done;
@@ -69,16 +70,16 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
i2c_msg[0].buf = (char *)out_buf;
out_buf[0] = EC_CMD_VERSION0 + msg->version;
- out_buf[1] = msg->cmd;
- out_buf[2] = msg->out_len;
+ out_buf[1] = msg->command;
+ out_buf[2] = msg->outsize;
/* copy message payload and compute checksum */
sum = out_buf[0] + out_buf[1] + out_buf[2];
- for (i = 0; i < msg->out_len; i++) {
- out_buf[3 + i] = msg->out_buf[i];
+ for (i = 0; i < msg->outsize; i++) {
+ out_buf[3 + i] = msg->outdata[i];
sum += out_buf[3 + i];
}
- out_buf[3 + msg->out_len] = sum;
+ out_buf[3 + msg->outsize] = sum;
/* send command to EC and read answer */
ret = i2c_transfer(client->adapter, i2c_msg, 2);
@@ -92,28 +93,34 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev,
}
/* check response error code */
- if (i2c_msg[1].buf[0]) {
- dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n",
- msg->cmd, i2c_msg[1].buf[0]);
- ret = -EINVAL;
+ msg->result = i2c_msg[1].buf[0];
+ ret = cros_ec_check_result(ec_dev, msg);
+ if (ret)
+ goto done;
+
+ len = in_buf[1];
+ if (len > msg->insize) {
+ dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
+ len, msg->insize);
+ ret = -ENOSPC;
goto done;
}
/* copy response packet payload and compute checksum */
sum = in_buf[0] + in_buf[1];
- for (i = 0; i < msg->in_len; i++) {
- msg->in_buf[i] = in_buf[2 + i];
+ for (i = 0; i < len; i++) {
+ msg->indata[i] = in_buf[2 + i];
sum += in_buf[2 + i];
}
dev_dbg(ec_dev->dev, "packet: %*ph, sum = %02x\n",
i2c_msg[1].len, in_buf, sum);
- if (sum != in_buf[2 + msg->in_len]) {
+ if (sum != in_buf[2 + len]) {
dev_err(ec_dev->dev, "bad packet checksum\n");
ret = -EBADMSG;
goto done;
}
- ret = 0;
+ ret = len;
done:
kfree(in_buf);
kfree(out_buf);
@@ -132,11 +139,10 @@ static int cros_ec_i2c_probe(struct i2c_client *client,
return -ENOMEM;
i2c_set_clientdata(client, ec_dev);
- ec_dev->name = "I2C";
ec_dev->dev = dev;
ec_dev->priv = client;
ec_dev->irq = client->irq;
- ec_dev->command_xfer = cros_ec_command_xfer;
+ ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c;
ec_dev->ec_name = client->name;
ec_dev->phys_name = client->adapter->name;
ec_dev->parent = &client->dev;
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index 0b8d32829166..588c700af39c 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -73,7 +73,7 @@
* if no record
* @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
* is sent when we want to turn off CS at the end of a transaction.
- * @lock: mutex to ensure only one user of cros_ec_command_spi_xfer at a time
+ * @lock: mutex to ensure only one user of cros_ec_cmd_xfer_spi at a time
*/
struct cros_ec_spi {
struct spi_device *spi;
@@ -210,13 +210,13 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
}
/**
- * cros_ec_command_spi_xfer - Transfer a message over SPI and receive the reply
+ * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
*
* @ec_dev: ChromeOS EC device
* @ec_msg: Message to transfer
*/
-static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
- struct cros_ec_msg *ec_msg)
+static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *ec_msg)
{
struct cros_ec_spi *ec_spi = ec_dev->priv;
struct spi_transfer trans;
@@ -225,7 +225,6 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
u8 *ptr;
int sum;
int ret = 0, final_ret;
- struct timespec ts;
/*
* We have the shared ec_dev buffer plus we do lots of separate spi_sync
@@ -239,11 +238,9 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
/* If it's too soon to do another transaction, wait */
if (ec_spi->last_transfer_ns) {
- struct timespec ts;
unsigned long delay; /* The delay completed so far */
- ktime_get_ts(&ts);
- delay = timespec_to_ns(&ts) - ec_spi->last_transfer_ns;
+ delay = ktime_get_ns() - ec_spi->last_transfer_ns;
if (delay < EC_SPI_RECOVERY_TIME_NS)
ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
}
@@ -261,27 +258,22 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
/* Get the response */
if (!ret) {
ret = cros_ec_spi_receive_response(ec_dev,
- ec_msg->in_len + EC_MSG_TX_PROTO_BYTES);
+ ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
} else {
dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
}
- /* turn off CS */
+ /*
+ * Turn off CS, possibly adding a delay to ensure the rising edge
+ * doesn't come too soon after the end of the data.
+ */
spi_message_init(&msg);
-
- if (ec_spi->end_of_msg_delay) {
- /*
- * Add delay for last transaction, to ensure the rising edge
- * doesn't come too soon after the end of the data.
- */
- memset(&trans, 0, sizeof(trans));
- trans.delay_usecs = ec_spi->end_of_msg_delay;
- spi_message_add_tail(&trans, &msg);
- }
+ memset(&trans, 0, sizeof(trans));
+ trans.delay_usecs = ec_spi->end_of_msg_delay;
+ spi_message_add_tail(&trans, &msg);
final_ret = spi_sync(ec_spi->spi, &msg);
- ktime_get_ts(&ts);
- ec_spi->last_transfer_ns = timespec_to_ns(&ts);
+ ec_spi->last_transfer_ns = ktime_get_ns();
if (!ret)
ret = final_ret;
if (ret < 0) {
@@ -289,20 +281,19 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
goto exit;
}
- /* check response error code */
ptr = ec_dev->din;
- if (ptr[0]) {
- dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n",
- ec_msg->cmd, ptr[0]);
- debug_packet(ec_dev->dev, "in_err", ptr, len);
- ret = -EINVAL;
+
+ /* check response error code */
+ ec_msg->result = ptr[0];
+ ret = cros_ec_check_result(ec_dev, ec_msg);
+ if (ret)
goto exit;
- }
+
len = ptr[1];
sum = ptr[0] + ptr[1];
- if (len > ec_msg->in_len) {
+ if (len > ec_msg->insize) {
dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
- len, ec_msg->in_len);
+ len, ec_msg->insize);
ret = -ENOSPC;
goto exit;
}
@@ -310,8 +301,8 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
/* copy response packet payload and compute checksum */
for (i = 0; i < len; i++) {
sum += ptr[i + 2];
- if (ec_msg->in_len)
- ec_msg->in_buf[i] = ptr[i + 2];
+ if (ec_msg->insize)
+ ec_msg->indata[i] = ptr[i + 2];
}
sum &= 0xff;
@@ -325,7 +316,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
goto exit;
}
- ret = 0;
+ ret = len;
exit:
mutex_unlock(&ec_spi->lock);
return ret;
@@ -368,11 +359,10 @@ static int cros_ec_spi_probe(struct spi_device *spi)
cros_ec_spi_dt_probe(ec_spi, dev);
spi_set_drvdata(spi, ec_dev);
- ec_dev->name = "SPI";
ec_dev->dev = dev;
ec_dev->priv = ec_spi;
ec_dev->irq = spi->irq;
- ec_dev->command_xfer = cros_ec_command_spi_xfer;
+ ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
ec_dev->ec_name = ec_spi->spi->modalias;
ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
ec_dev->parent = &ec_spi->spi->dev;
@@ -385,6 +375,8 @@ static int cros_ec_spi_probe(struct spi_device *spi)
return err;
}
+ device_init_wakeup(&spi->dev, true);
+
return 0;
}
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index e70ae315abc7..93db8bb8c8f0 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -153,9 +153,9 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
"Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
model, variant_id);
- if (variant_code != PMIC_DA9063_BB) {
- dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n",
- variant_code);
+ if (variant_code < PMIC_DA9063_BB && variant_code != PMIC_DA9063_AD) {
+ dev_err(da9063->dev,
+ "Cannot support variant code: 0x%02X\n", variant_code);
return -ENODEV;
}
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 8db5c805c64f..21fd8d9a217b 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -25,10 +25,10 @@
#include <linux/mfd/da9063/pdata.h>
#include <linux/mfd/da9063/registers.h>
-static const struct regmap_range da9063_readable_ranges[] = {
+static const struct regmap_range da9063_ad_readable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
- .range_max = DA9063_REG_SECOND_D,
+ .range_max = DA9063_AD_REG_SECOND_D,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
@@ -37,14 +37,14 @@ static const struct regmap_range da9063_readable_ranges[] = {
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_T_OFFSET,
- .range_max = DA9063_REG_GP_ID_19,
+ .range_max = DA9063_AD_REG_GP_ID_19,
}, {
.range_min = DA9063_REG_CHIP_ID,
.range_max = DA9063_REG_CHIP_VARIANT,
},
};
-static const struct regmap_range da9063_writeable_ranges[] = {
+static const struct regmap_range da9063_ad_writeable_ranges[] = {
{
.range_min = DA9063_REG_PAGE_CON,
.range_max = DA9063_REG_PAGE_CON,
@@ -53,7 +53,7 @@ static const struct regmap_range da9063_writeable_ranges[] = {
.range_max = DA9063_REG_VSYS_MON,
}, {
.range_min = DA9063_REG_COUNT_S,
- .range_max = DA9063_REG_ALARM_Y,
+ .range_max = DA9063_AD_REG_ALARM_Y,
}, {
.range_min = DA9063_REG_SEQ,
.range_max = DA9063_REG_ID_32_31,
@@ -62,14 +62,14 @@ static const struct regmap_range da9063_writeable_ranges[] = {
.range_max = DA9063_REG_AUTO3_LOW,
}, {
.range_min = DA9063_REG_CONFIG_I,
- .range_max = DA9063_REG_MON_REG_4,
+ .range_max = DA9063_AD_REG_MON_REG_4,
}, {
- .range_min = DA9063_REG_GP_ID_0,
- .range_max = DA9063_REG_GP_ID_19,
+ .range_min = DA9063_AD_REG_GP_ID_0,
+ .range_max = DA9063_AD_REG_GP_ID_19,
},
};
-static const struct regmap_range da9063_volatile_ranges[] = {
+static const struct regmap_range da9063_ad_volatile_ranges[] = {
{
.range_min = DA9063_REG_STATUS_A,
.range_max = DA9063_REG_EVENT_D,
@@ -81,26 +81,104 @@ static const struct regmap_range da9063_volatile_ranges[] = {
.range_max = DA9063_REG_ADC_MAN,
}, {
.range_min = DA9063_REG_ADC_RES_L,
- .range_max = DA9063_REG_SECOND_D,
+ .range_max = DA9063_AD_REG_SECOND_D,
}, {
- .range_min = DA9063_REG_MON_REG_5,
- .range_max = DA9063_REG_MON_REG_6,
+ .range_min = DA9063_AD_REG_MON_REG_5,
+ .range_max = DA9063_AD_REG_MON_REG_6,
},
};
-static const struct regmap_access_table da9063_readable_table = {
- .yes_ranges = da9063_readable_ranges,
- .n_yes_ranges = ARRAY_SIZE(da9063_readable_ranges),
+static const struct regmap_access_table da9063_ad_readable_table = {
+ .yes_ranges = da9063_ad_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_ad_readable_ranges),
};
-static const struct regmap_access_table da9063_writeable_table = {
- .yes_ranges = da9063_writeable_ranges,
- .n_yes_ranges = ARRAY_SIZE(da9063_writeable_ranges),
+static const struct regmap_access_table da9063_ad_writeable_table = {
+ .yes_ranges = da9063_ad_writeable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_ad_writeable_ranges),
};
-static const struct regmap_access_table da9063_volatile_table = {
- .yes_ranges = da9063_volatile_ranges,
- .n_yes_ranges = ARRAY_SIZE(da9063_volatile_ranges),
+static const struct regmap_access_table da9063_ad_volatile_table = {
+ .yes_ranges = da9063_ad_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_ad_volatile_ranges),
+};
+
+static const struct regmap_range da9063_bb_readable_ranges[] = {
+ {
+ .range_min = DA9063_REG_PAGE_CON,
+ .range_max = DA9063_BB_REG_SECOND_D,
+ }, {
+ .range_min = DA9063_REG_SEQ,
+ .range_max = DA9063_REG_ID_32_31,
+ }, {
+ .range_min = DA9063_REG_SEQ_A,
+ .range_max = DA9063_REG_AUTO3_LOW,
+ }, {
+ .range_min = DA9063_REG_T_OFFSET,
+ .range_max = DA9063_BB_REG_GP_ID_19,
+ }, {
+ .range_min = DA9063_REG_CHIP_ID,
+ .range_max = DA9063_REG_CHIP_VARIANT,
+ },
+};
+
+static const struct regmap_range da9063_bb_writeable_ranges[] = {
+ {
+ .range_min = DA9063_REG_PAGE_CON,
+ .range_max = DA9063_REG_PAGE_CON,
+ }, {
+ .range_min = DA9063_REG_FAULT_LOG,
+ .range_max = DA9063_REG_VSYS_MON,
+ }, {
+ .range_min = DA9063_REG_COUNT_S,
+ .range_max = DA9063_BB_REG_ALARM_Y,
+ }, {
+ .range_min = DA9063_REG_SEQ,
+ .range_max = DA9063_REG_ID_32_31,
+ }, {
+ .range_min = DA9063_REG_SEQ_A,
+ .range_max = DA9063_REG_AUTO3_LOW,
+ }, {
+ .range_min = DA9063_REG_CONFIG_I,
+ .range_max = DA9063_BB_REG_MON_REG_4,
+ }, {
+ .range_min = DA9063_BB_REG_GP_ID_0,
+ .range_max = DA9063_BB_REG_GP_ID_19,
+ },
+};
+
+static const struct regmap_range da9063_bb_volatile_ranges[] = {
+ {
+ .range_min = DA9063_REG_STATUS_A,
+ .range_max = DA9063_REG_EVENT_D,
+ }, {
+ .range_min = DA9063_REG_CONTROL_F,
+ .range_max = DA9063_REG_CONTROL_F,
+ }, {
+ .range_min = DA9063_REG_ADC_MAN,
+ .range_max = DA9063_REG_ADC_MAN,
+ }, {
+ .range_min = DA9063_REG_ADC_RES_L,
+ .range_max = DA9063_BB_REG_SECOND_D,
+ }, {
+ .range_min = DA9063_BB_REG_MON_REG_5,
+ .range_max = DA9063_BB_REG_MON_REG_6,
+ },
+};
+
+static const struct regmap_access_table da9063_bb_readable_table = {
+ .yes_ranges = da9063_bb_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_bb_readable_ranges),
+};
+
+static const struct regmap_access_table da9063_bb_writeable_table = {
+ .yes_ranges = da9063_bb_writeable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_bb_writeable_ranges),
+};
+
+static const struct regmap_access_table da9063_bb_volatile_table = {
+ .yes_ranges = da9063_bb_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(da9063_bb_volatile_ranges),
};
static const struct regmap_range_cfg da9063_range_cfg[] = {
@@ -123,10 +201,6 @@ static struct regmap_config da9063_regmap_config = {
.max_register = DA9063_REG_CHIP_VARIANT,
.cache_type = REGCACHE_RBTREE,
-
- .rd_table = &da9063_readable_table,
- .wr_table = &da9063_writeable_table,
- .volatile_table = &da9063_volatile_table,
};
static int da9063_i2c_probe(struct i2c_client *i2c,
@@ -143,6 +217,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
da9063->dev = &i2c->dev;
da9063->chip_irq = i2c->irq;
+ if (da9063->variant_code == PMIC_DA9063_AD) {
+ da9063_regmap_config.rd_table = &da9063_ad_readable_table;
+ da9063_regmap_config.wr_table = &da9063_ad_writeable_table;
+ da9063_regmap_config.volatile_table = &da9063_ad_volatile_table;
+ } else {
+ da9063_regmap_config.rd_table = &da9063_bb_readable_table;
+ da9063_regmap_config.wr_table = &da9063_bb_writeable_table;
+ da9063_regmap_config.volatile_table = &da9063_bb_volatile_table;
+ }
+
da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
if (IS_ERR(da9063->regmap)) {
ret = PTR_ERR(da9063->regmap);
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 7a55c0071fa8..4c826f78acd0 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -95,7 +95,7 @@ EXPORT_SYMBOL(dm355evm_msp_read);
* Many of the msp430 pins are just used as fixed-direction GPIOs.
* We could export a few more of them this way, if we wanted.
*/
-#define MSP_GPIO(bit,reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit))
+#define MSP_GPIO(bit, reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit))
static const u8 msp_gpios[] = {
/* eight leds */
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index 2ed774e7d342..5991faddd3c6 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -62,7 +62,7 @@ static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data)
struct spi_message m;
int status;
- memset(&t, 0, sizeof t);
+ memset(&t, 0, sizeof(t));
spi_message_init(&m);
t.len = sizeof(u32);
spi_message_add_tail(&t, &m);
@@ -211,7 +211,6 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
desc->irq_data.chip->irq_ack(&desc->irq_data);
queue_work(pcap->workqueue, &pcap->isr_work);
- return;
}
/* ADC */
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
index d7b2a75aca3e..b44f0203983b 100644
--- a/drivers/mfd/htc-i2cpld.c
+++ b/drivers/mfd/htc-i2cpld.c
@@ -332,18 +332,13 @@ static int htcpld_setup_chip_irq(
int chip_index)
{
struct htcpld_data *htcpld;
- struct device *dev = &pdev->dev;
- struct htcpld_core_platform_data *pdata;
struct htcpld_chip *chip;
- struct htcpld_chip_platform_data *plat_chip_data;
unsigned int irq, irq_end;
int ret = 0;
/* Get the platform and driver data */
- pdata = dev_get_platdata(dev);
htcpld = platform_get_drvdata(pdev);
chip = &htcpld->chip[chip_index];
- plat_chip_data = &pdata->chip[chip_index];
/* Setup irq handlers */
irq_end = chip->irq_start + chip->nirqs;
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index 049fd23af54a..443e7cddff28 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -27,7 +27,7 @@
/*
* MSIC interrupt tree is readable from SRAM at INTEL_MSIC_IRQ_PHYS_BASE.
- * Since IRQ block starts from address 0x002 we need to substract that from
+ * Since IRQ block starts from address 0x002 we need to subtract that from
* the actual IRQ status register address.
*/
#define MSIC_IRQ_STATUS(x) (INTEL_MSIC_IRQ_PHYS_BASE + ((x) - 2))
diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
new file mode 100644
index 000000000000..2720922f90b4
--- /dev/null
+++ b/drivers/mfd/intel_soc_pmic_core.c
@@ -0,0 +1,170 @@
+/*
+ * intel_soc_pmic_core.c - Intel SoC PMIC MFD Driver
+ *
+ * Copyright (C) 2013, 2014 Intel 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 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.
+ *
+ * Author: Yang, Bin <bin.yang@intel.com>
+ * Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/gpio/consumer.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+#include <linux/mfd/intel_soc_pmic.h>
+#include "intel_soc_pmic_core.h"
+
+/*
+ * On some boards the PMIC interrupt may come from a GPIO line.
+ * Try to lookup the ACPI table and see if such connection exists. If not,
+ * return -ENOENT and use the IRQ provided by I2C.
+ */
+static int intel_soc_pmic_find_gpio_irq(struct device *dev)
+{
+ struct gpio_desc *desc;
+ int irq;
+
+ desc = devm_gpiod_get_index(dev, "intel_soc_pmic", 0);
+ if (IS_ERR(desc))
+ return -ENOENT;
+
+ irq = gpiod_to_irq(desc);
+ if (irq < 0)
+ dev_warn(dev, "Can't get irq: %d\n", irq);
+
+ return irq;
+}
+
+static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *i2c_id)
+{
+ struct device *dev = &i2c->dev;
+ const struct acpi_device_id *id;
+ struct intel_soc_pmic_config *config;
+ struct intel_soc_pmic *pmic;
+ int ret;
+ int irq;
+
+ id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!id || !id->driver_data)
+ return -ENODEV;
+
+ config = (struct intel_soc_pmic_config *)id->driver_data;
+
+ pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
+ dev_set_drvdata(dev, pmic);
+
+ pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config);
+
+ irq = intel_soc_pmic_find_gpio_irq(dev);
+ pmic->irq = (irq < 0) ? i2c->irq : irq;
+
+ ret = regmap_add_irq_chip(pmic->regmap, pmic->irq,
+ config->irq_flags | IRQF_ONESHOT,
+ 0, config->irq_chip,
+ &pmic->irq_chip_data);
+ if (ret)
+ return ret;
+
+ ret = enable_irq_wake(pmic->irq);
+ if (ret)
+ dev_warn(dev, "Can't enable IRQ as wake source: %d\n", ret);
+
+ ret = mfd_add_devices(dev, -1, config->cell_dev,
+ config->n_cell_devs, NULL, 0,
+ regmap_irq_get_domain(pmic->irq_chip_data));
+ if (ret)
+ goto err_del_irq_chip;
+
+ return 0;
+
+err_del_irq_chip:
+ regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
+ return ret;
+}
+
+static int intel_soc_pmic_i2c_remove(struct i2c_client *i2c)
+{
+ struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev);
+
+ regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
+
+ mfd_remove_devices(&i2c->dev);
+
+ return 0;
+}
+
+static void intel_soc_pmic_shutdown(struct i2c_client *i2c)
+{
+ struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev);
+
+ disable_irq(pmic->irq);
+
+ return;
+}
+
+static int intel_soc_pmic_suspend(struct device *dev)
+{
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
+
+ disable_irq(pmic->irq);
+
+ return 0;
+}
+
+static int intel_soc_pmic_resume(struct device *dev)
+{
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
+
+ enable_irq(pmic->irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(intel_soc_pmic_pm_ops, intel_soc_pmic_suspend,
+ intel_soc_pmic_resume);
+
+static const struct i2c_device_id intel_soc_pmic_i2c_id[] = {
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id);
+
+#if defined(CONFIG_ACPI)
+static struct acpi_device_id intel_soc_pmic_acpi_match[] = {
+ {"INT33FD", (kernel_ulong_t)&intel_soc_pmic_config_crc},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match);
+#endif
+
+static struct i2c_driver intel_soc_pmic_i2c_driver = {
+ .driver = {
+ .name = "intel_soc_pmic_i2c",
+ .owner = THIS_MODULE,
+ .pm = &intel_soc_pmic_pm_ops,
+ .acpi_match_table = ACPI_PTR(intel_soc_pmic_acpi_match),
+ },
+ .probe = intel_soc_pmic_i2c_probe,
+ .remove = intel_soc_pmic_i2c_remove,
+ .id_table = intel_soc_pmic_i2c_id,
+ .shutdown = intel_soc_pmic_shutdown,
+};
+
+module_i2c_driver(intel_soc_pmic_i2c_driver);
+
+MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>");
+MODULE_AUTHOR("Zhu, Lejun <lejun.zhu@linux.intel.com>");
diff --git a/drivers/mfd/intel_soc_pmic_core.h b/drivers/mfd/intel_soc_pmic_core.h
new file mode 100644
index 000000000000..33aacd9baddc
--- /dev/null
+++ b/drivers/mfd/intel_soc_pmic_core.h
@@ -0,0 +1,32 @@
+/*
+ * intel_soc_pmic_core.h - Intel SoC PMIC MFD Driver
+ *
+ * Copyright (C) 2012-2014 Intel 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 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.
+ *
+ * Author: Yang, Bin <bin.yang@intel.com>
+ * Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
+ */
+
+#ifndef __INTEL_SOC_PMIC_CORE_H__
+#define __INTEL_SOC_PMIC_CORE_H__
+
+struct intel_soc_pmic_config {
+ unsigned long irq_flags;
+ struct mfd_cell *cell_dev;
+ int n_cell_devs;
+ struct regmap_config *regmap_config;
+ struct regmap_irq_chip *irq_chip;
+};
+
+extern struct intel_soc_pmic_config intel_soc_pmic_config_crc;
+
+#endif /* __INTEL_SOC_PMIC_CORE_H__ */
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c
new file mode 100644
index 000000000000..7107cab832e6
--- /dev/null
+++ b/drivers/mfd/intel_soc_pmic_crc.c
@@ -0,0 +1,158 @@
+/*
+ * intel_soc_pmic_crc.c - Device access for Crystal Cove PMIC
+ *
+ * Copyright (C) 2013, 2014 Intel 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 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.
+ *
+ * Author: Yang, Bin <bin.yang@intel.com>
+ * Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
+ */
+
+#include <linux/mfd/core.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+#include <linux/mfd/intel_soc_pmic.h>
+#include "intel_soc_pmic_core.h"
+
+#define CRYSTAL_COVE_MAX_REGISTER 0xC6
+
+#define CRYSTAL_COVE_REG_IRQLVL1 0x02
+#define CRYSTAL_COVE_REG_MIRQLVL1 0x0E
+
+#define CRYSTAL_COVE_IRQ_PWRSRC 0
+#define CRYSTAL_COVE_IRQ_THRM 1
+#define CRYSTAL_COVE_IRQ_BCU 2
+#define CRYSTAL_COVE_IRQ_ADC 3
+#define CRYSTAL_COVE_IRQ_CHGR 4
+#define CRYSTAL_COVE_IRQ_GPIO 5
+#define CRYSTAL_COVE_IRQ_VHDMIOCP 6
+
+static struct resource gpio_resources[] = {
+ {
+ .name = "GPIO",
+ .start = CRYSTAL_COVE_IRQ_GPIO,
+ .end = CRYSTAL_COVE_IRQ_GPIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pwrsrc_resources[] = {
+ {
+ .name = "PWRSRC",
+ .start = CRYSTAL_COVE_IRQ_PWRSRC,
+ .end = CRYSTAL_COVE_IRQ_PWRSRC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource adc_resources[] = {
+ {
+ .name = "ADC",
+ .start = CRYSTAL_COVE_IRQ_ADC,
+ .end = CRYSTAL_COVE_IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource thermal_resources[] = {
+ {
+ .name = "THERMAL",
+ .start = CRYSTAL_COVE_IRQ_THRM,
+ .end = CRYSTAL_COVE_IRQ_THRM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource bcu_resources[] = {
+ {
+ .name = "BCU",
+ .start = CRYSTAL_COVE_IRQ_BCU,
+ .end = CRYSTAL_COVE_IRQ_BCU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell crystal_cove_dev[] = {
+ {
+ .name = "crystal_cove_pwrsrc",
+ .num_resources = ARRAY_SIZE(pwrsrc_resources),
+ .resources = pwrsrc_resources,
+ },
+ {
+ .name = "crystal_cove_adc",
+ .num_resources = ARRAY_SIZE(adc_resources),
+ .resources = adc_resources,
+ },
+ {
+ .name = "crystal_cove_thermal",
+ .num_resources = ARRAY_SIZE(thermal_resources),
+ .resources = thermal_resources,
+ },
+ {
+ .name = "crystal_cove_bcu",
+ .num_resources = ARRAY_SIZE(bcu_resources),
+ .resources = bcu_resources,
+ },
+ {
+ .name = "crystal_cove_gpio",
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ .resources = gpio_resources,
+ },
+};
+
+static struct regmap_config crystal_cove_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CRYSTAL_COVE_MAX_REGISTER,
+ .cache_type = REGCACHE_NONE,
+};
+
+static const struct regmap_irq crystal_cove_irqs[] = {
+ [CRYSTAL_COVE_IRQ_PWRSRC] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_PWRSRC),
+ },
+ [CRYSTAL_COVE_IRQ_THRM] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_THRM),
+ },
+ [CRYSTAL_COVE_IRQ_BCU] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_BCU),
+ },
+ [CRYSTAL_COVE_IRQ_ADC] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_ADC),
+ },
+ [CRYSTAL_COVE_IRQ_CHGR] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_CHGR),
+ },
+ [CRYSTAL_COVE_IRQ_GPIO] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_GPIO),
+ },
+ [CRYSTAL_COVE_IRQ_VHDMIOCP] = {
+ .mask = BIT(CRYSTAL_COVE_IRQ_VHDMIOCP),
+ },
+};
+
+static struct regmap_irq_chip crystal_cove_irq_chip = {
+ .name = "Crystal Cove",
+ .irqs = crystal_cove_irqs,
+ .num_irqs = ARRAY_SIZE(crystal_cove_irqs),
+ .num_regs = 1,
+ .status_base = CRYSTAL_COVE_REG_IRQLVL1,
+ .mask_base = CRYSTAL_COVE_REG_MIRQLVL1,
+};
+
+struct intel_soc_pmic_config intel_soc_pmic_config_crc = {
+ .irq_flags = IRQF_TRIGGER_RISING,
+ .cell_dev = crystal_cove_dev,
+ .n_cell_devs = ARRAY_SIZE(crystal_cove_dev),
+ .regmap_config = &crystal_cove_regmap_config,
+ .irq_chip = &crystal_cove_irq_chip,
+};
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c
index 7e50fe0118e3..8df3266064e4 100644
--- a/drivers/mfd/ipaq-micro.c
+++ b/drivers/mfd/ipaq-micro.c
@@ -115,7 +115,7 @@ static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data)
} else {
dev_err(micro->dev,
"out of band RX message 0x%02x\n", id);
- if(!micro->msg)
+ if (!micro->msg)
dev_info(micro->dev, "no message queued\n");
else
dev_info(micro->dev, "expected message %02x\n",
@@ -126,13 +126,13 @@ static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data)
if (micro->key)
micro->key(micro->key_data, len, data);
else
- dev_dbg(micro->dev, "key message ignored, no handle \n");
+ dev_dbg(micro->dev, "key message ignored, no handle\n");
break;
case MSG_TOUCHSCREEN:
if (micro->ts)
micro->ts(micro->ts_data, len, data);
else
- dev_dbg(micro->dev, "touchscreen message ignored, no handle \n");
+ dev_dbg(micro->dev, "touchscreen message ignored, no handle\n");
break;
default:
dev_err(micro->dev,
@@ -154,7 +154,7 @@ static void micro_process_char(struct ipaq_micro *micro, u8 ch)
rx->state = STATE_ID; /* Next byte is the id and len */
break;
case STATE_ID: /* Looking for id and len byte */
- rx->id = (ch & 0xf0) >> 4 ;
+ rx->id = (ch & 0xf0) >> 4;
rx->len = (ch & 0x0f);
rx->index = 0;
rx->chksum = ch;
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c
index f7ff0188603d..bd2696136eee 100644
--- a/drivers/mfd/kempld-core.c
+++ b/drivers/mfd/kempld-core.c
@@ -24,7 +24,8 @@
#define MAX_ID_LEN 4
static char force_device_id[MAX_ID_LEN + 1] = "";
-module_param_string(force_device_id, force_device_id, sizeof(force_device_id), 0);
+module_param_string(force_device_id, force_device_id,
+ sizeof(force_device_id), 0);
MODULE_PARM_DESC(force_device_id, "Override detected product");
/*
@@ -36,7 +37,7 @@ static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
{
/* The mutex bit will read 1 until access has been granted */
while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY)
- msleep(1);
+ usleep_range(1000, 3000);
}
static void kempld_release_hardware_mutex(struct kempld_device_data *pld)
@@ -499,7 +500,7 @@ static struct platform_driver kempld_driver = {
.remove = kempld_remove,
};
-static struct dmi_system_id __initdata kempld_dmi_table[] = {
+static struct dmi_system_id kempld_dmi_table[] __initdata = {
{
.ident = "BHL6",
.matches = {
@@ -736,7 +737,8 @@ static int __init kempld_init(void)
int ret;
if (force_device_id[0]) {
- for (id = kempld_dmi_table; id->matches[0].slot != DMI_NONE; id++)
+ for (id = kempld_dmi_table;
+ id->matches[0].slot != DMI_NONE; id++)
if (strstr(id->ident, force_device_id))
if (id->callback && id->callback(id))
break;
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
index c84ded5f8ece..23982dbf014d 100644
--- a/drivers/mfd/lp8788-irq.c
+++ b/drivers/mfd/lp8788-irq.c
@@ -66,12 +66,14 @@ static inline u8 _irq_to_val(enum lp8788_int_id id, int enable)
static void lp8788_irq_enable(struct irq_data *data)
{
struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+
irqd->enabled[data->hwirq] = 1;
}
static void lp8788_irq_disable(struct irq_data *data)
{
struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+
irqd->enabled[data->hwirq] = 0;
}
diff --git a/drivers/mfd/max77686-irq.c b/drivers/mfd/max77686-irq.c
deleted file mode 100644
index cdc3280e2ec7..000000000000
--- a/drivers/mfd/max77686-irq.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * max77686-irq.c - Interrupt controller support for MAX77686
- *
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * Chiwoong Byun <woong.byun@samsung.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.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This driver is based on max8997-irq.c
- */
-
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/mfd/max77686.h>
-#include <linux/mfd/max77686-private.h>
-#include <linux/irqdomain.h>
-#include <linux/regmap.h>
-
-enum {
- MAX77686_DEBUG_IRQ_INFO = 1 << 0,
- MAX77686_DEBUG_IRQ_MASK = 1 << 1,
- MAX77686_DEBUG_IRQ_INT = 1 << 2,
-};
-
-static int debug_mask = 0;
-module_param(debug_mask, int, 0);
-MODULE_PARM_DESC(debug_mask, "Set debug_mask : 0x0=off 0x1=IRQ_INFO 0x2=IRQ_MASK 0x4=IRQ_INI)");
-
-static const u8 max77686_mask_reg[] = {
- [PMIC_INT1] = MAX77686_REG_INT1MSK,
- [PMIC_INT2] = MAX77686_REG_INT2MSK,
- [RTC_INT] = MAX77686_RTC_INTM,
-};
-
-static struct regmap *max77686_get_regmap(struct max77686_dev *max77686,
- enum max77686_irq_source src)
-{
- switch (src) {
- case PMIC_INT1 ... PMIC_INT2:
- return max77686->regmap;
- case RTC_INT:
- return max77686->rtc_regmap;
- default:
- return ERR_PTR(-EINVAL);
- }
-}
-
-struct max77686_irq_data {
- int mask;
- enum max77686_irq_source group;
-};
-
-#define DECLARE_IRQ(idx, _group, _mask) \
- [(idx)] = { .group = (_group), .mask = (_mask) }
-static const struct max77686_irq_data max77686_irqs[] = {
- DECLARE_IRQ(MAX77686_PMICIRQ_PWRONF, PMIC_INT1, 1 << 0),
- DECLARE_IRQ(MAX77686_PMICIRQ_PWRONR, PMIC_INT1, 1 << 1),
- DECLARE_IRQ(MAX77686_PMICIRQ_JIGONBF, PMIC_INT1, 1 << 2),
- DECLARE_IRQ(MAX77686_PMICIRQ_JIGONBR, PMIC_INT1, 1 << 3),
- DECLARE_IRQ(MAX77686_PMICIRQ_ACOKBF, PMIC_INT1, 1 << 4),
- DECLARE_IRQ(MAX77686_PMICIRQ_ACOKBR, PMIC_INT1, 1 << 5),
- DECLARE_IRQ(MAX77686_PMICIRQ_ONKEY1S, PMIC_INT1, 1 << 6),
- DECLARE_IRQ(MAX77686_PMICIRQ_MRSTB, PMIC_INT1, 1 << 7),
- DECLARE_IRQ(MAX77686_PMICIRQ_140C, PMIC_INT2, 1 << 0),
- DECLARE_IRQ(MAX77686_PMICIRQ_120C, PMIC_INT2, 1 << 1),
- DECLARE_IRQ(MAX77686_RTCIRQ_RTC60S, RTC_INT, 1 << 0),
- DECLARE_IRQ(MAX77686_RTCIRQ_RTCA1, RTC_INT, 1 << 1),
- DECLARE_IRQ(MAX77686_RTCIRQ_RTCA2, RTC_INT, 1 << 2),
- DECLARE_IRQ(MAX77686_RTCIRQ_SMPL, RTC_INT, 1 << 3),
- DECLARE_IRQ(MAX77686_RTCIRQ_RTC1S, RTC_INT, 1 << 4),
- DECLARE_IRQ(MAX77686_RTCIRQ_WTSR, RTC_INT, 1 << 5),
-};
-
-static void max77686_irq_lock(struct irq_data *data)
-{
- struct max77686_dev *max77686 = irq_get_chip_data(data->irq);
-
- if (debug_mask & MAX77686_DEBUG_IRQ_MASK)
- pr_info("%s\n", __func__);
-
- mutex_lock(&max77686->irqlock);
-}
-
-static void max77686_irq_sync_unlock(struct irq_data *data)
-{
- struct max77686_dev *max77686 = irq_get_chip_data(data->irq);
- int i;
-
- for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++) {
- u8 mask_reg = max77686_mask_reg[i];
- struct regmap *map = max77686_get_regmap(max77686, i);
-
- if (debug_mask & MAX77686_DEBUG_IRQ_MASK)
- pr_debug("%s: mask_reg[%d]=0x%x, cur=0x%x\n",
- __func__, i, mask_reg, max77686->irq_masks_cur[i]);
-
- if (mask_reg == MAX77686_REG_INVALID ||
- IS_ERR_OR_NULL(map))
- continue;
-
- max77686->irq_masks_cache[i] = max77686->irq_masks_cur[i];
-
- regmap_write(map, max77686_mask_reg[i],
- max77686->irq_masks_cur[i]);
- }
-
- mutex_unlock(&max77686->irqlock);
-}
-
-static const inline struct max77686_irq_data *to_max77686_irq(int irq)
-{
- struct irq_data *data = irq_get_irq_data(irq);
- return &max77686_irqs[data->hwirq];
-}
-
-static void max77686_irq_mask(struct irq_data *data)
-{
- struct max77686_dev *max77686 = irq_get_chip_data(data->irq);
- const struct max77686_irq_data *irq_data = to_max77686_irq(data->irq);
-
- max77686->irq_masks_cur[irq_data->group] |= irq_data->mask;
-
- if (debug_mask & MAX77686_DEBUG_IRQ_MASK)
- pr_info("%s: group=%d, cur=0x%x\n",
- __func__, irq_data->group,
- max77686->irq_masks_cur[irq_data->group]);
-}
-
-static void max77686_irq_unmask(struct irq_data *data)
-{
- struct max77686_dev *max77686 = irq_get_chip_data(data->irq);
- const struct max77686_irq_data *irq_data = to_max77686_irq(data->irq);
-
- max77686->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-
- if (debug_mask & MAX77686_DEBUG_IRQ_MASK)
- pr_info("%s: group=%d, cur=0x%x\n",
- __func__, irq_data->group,
- max77686->irq_masks_cur[irq_data->group]);
-}
-
-static struct irq_chip max77686_irq_chip = {
- .name = "max77686",
- .irq_bus_lock = max77686_irq_lock,
- .irq_bus_sync_unlock = max77686_irq_sync_unlock,
- .irq_mask = max77686_irq_mask,
- .irq_unmask = max77686_irq_unmask,
-};
-
-static irqreturn_t max77686_irq_thread(int irq, void *data)
-{
- struct max77686_dev *max77686 = data;
- unsigned int irq_reg[MAX77686_IRQ_GROUP_NR] = {};
- unsigned int irq_src;
- int ret;
- int i, cur_irq;
-
- ret = regmap_read(max77686->regmap, MAX77686_REG_INTSRC, &irq_src);
- if (ret < 0) {
- dev_err(max77686->dev, "Failed to read interrupt source: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- if (debug_mask & MAX77686_DEBUG_IRQ_INT)
- pr_info("%s: irq_src=0x%x\n", __func__, irq_src);
-
- if (irq_src == MAX77686_IRQSRC_PMIC) {
- ret = regmap_bulk_read(max77686->regmap,
- MAX77686_REG_INT1, irq_reg, 2);
- if (ret < 0) {
- dev_err(max77686->dev, "Failed to read interrupt source: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- if (debug_mask & MAX77686_DEBUG_IRQ_INT)
- pr_info("%s: int1=0x%x, int2=0x%x\n", __func__,
- irq_reg[PMIC_INT1], irq_reg[PMIC_INT2]);
- }
-
- if (irq_src & MAX77686_IRQSRC_RTC) {
- ret = regmap_read(max77686->rtc_regmap,
- MAX77686_RTC_INT, &irq_reg[RTC_INT]);
- if (ret < 0) {
- dev_err(max77686->dev, "Failed to read interrupt source: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- if (debug_mask & MAX77686_DEBUG_IRQ_INT)
- pr_info("%s: rtc int=0x%x\n", __func__,
- irq_reg[RTC_INT]);
-
- }
-
- for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++)
- irq_reg[i] &= ~max77686->irq_masks_cur[i];
-
- for (i = 0; i < MAX77686_IRQ_NR; i++) {
- if (irq_reg[max77686_irqs[i].group] & max77686_irqs[i].mask) {
- cur_irq = irq_find_mapping(max77686->irq_domain, i);
- if (cur_irq)
- handle_nested_irq(cur_irq);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-static int max77686_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
- struct max77686_dev *max77686 = d->host_data;
-
- irq_set_chip_data(irq, max77686);
- irq_set_chip_and_handler(irq, &max77686_irq_chip, handle_edge_irq);
- irq_set_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
-#else
- irq_set_noprobe(irq);
-#endif
- return 0;
-}
-
-static struct irq_domain_ops max77686_irq_domain_ops = {
- .map = max77686_irq_domain_map,
-};
-
-int max77686_irq_init(struct max77686_dev *max77686)
-{
- struct irq_domain *domain;
- int i;
- int ret;
- int val;
- struct regmap *map;
-
- mutex_init(&max77686->irqlock);
-
- if (max77686->irq_gpio && !max77686->irq) {
- max77686->irq = gpio_to_irq(max77686->irq_gpio);
-
- if (debug_mask & MAX77686_DEBUG_IRQ_INT) {
- ret = gpio_request(max77686->irq_gpio, "pmic_irq");
- if (ret < 0) {
- dev_err(max77686->dev,
- "Failed to request gpio %d with ret:"
- "%d\n", max77686->irq_gpio, ret);
- return IRQ_NONE;
- }
-
- gpio_direction_input(max77686->irq_gpio);
- val = gpio_get_value(max77686->irq_gpio);
- gpio_free(max77686->irq_gpio);
- pr_info("%s: gpio_irq=%x\n", __func__, val);
- }
- }
-
- if (!max77686->irq) {
- dev_err(max77686->dev, "irq is not specified\n");
- return -ENODEV;
- }
-
- /* Mask individual interrupt sources */
- for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++) {
- max77686->irq_masks_cur[i] = 0xff;
- max77686->irq_masks_cache[i] = 0xff;
- map = max77686_get_regmap(max77686, i);
-
- if (IS_ERR_OR_NULL(map))
- continue;
- if (max77686_mask_reg[i] == MAX77686_REG_INVALID)
- continue;
-
- regmap_write(map, max77686_mask_reg[i], 0xff);
- }
- domain = irq_domain_add_linear(NULL, MAX77686_IRQ_NR,
- &max77686_irq_domain_ops, max77686);
- if (!domain) {
- dev_err(max77686->dev, "could not create irq domain\n");
- return -ENODEV;
- }
- max77686->irq_domain = domain;
-
- ret = request_threaded_irq(max77686->irq, NULL, max77686_irq_thread,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "max77686-irq", max77686);
-
- if (ret)
- dev_err(max77686->dev, "Failed to request IRQ %d: %d\n",
- max77686->irq, ret);
-
-
- if (debug_mask & MAX77686_DEBUG_IRQ_INFO)
- pr_info("%s-\n", __func__);
-
- return 0;
-}
-
-void max77686_irq_exit(struct max77686_dev *max77686)
-{
- if (max77686->irq)
- free_irq(max77686->irq, max77686);
-}
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index ce869acf27ae..86e552348db4 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -1,5 +1,5 @@
/*
- * max77686.c - mfd core driver for the Maxim 77686
+ * max77686.c - mfd core driver for the Maxim 77686/802
*
* Copyright (C) 2012 Samsung Electronics
* Chiwoong Byun <woong.byun@smasung.com>
@@ -25,6 +25,8 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
@@ -41,15 +43,166 @@ static const struct mfd_cell max77686_devs[] = {
{ .name = "max77686-clk", },
};
+static const struct mfd_cell max77802_devs[] = {
+ { .name = "max77802-pmic", },
+ { .name = "max77802-clk", },
+ { .name = "max77802-rtc", },
+};
+
+static bool max77802_pmic_is_accessible_reg(struct device *dev,
+ unsigned int reg)
+{
+ return (reg >= MAX77802_REG_DEVICE_ID && reg < MAX77802_REG_PMIC_END);
+}
+
+static bool max77802_rtc_is_accessible_reg(struct device *dev,
+ unsigned int reg)
+{
+ return (reg >= MAX77802_RTC_INT && reg < MAX77802_RTC_END);
+}
+
+static bool max77802_is_accessible_reg(struct device *dev, unsigned int reg)
+{
+ return (max77802_pmic_is_accessible_reg(dev, reg) ||
+ max77802_rtc_is_accessible_reg(dev, reg));
+}
+
+static bool max77802_pmic_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ return (reg == MAX77802_REG_INTSRC || reg == MAX77802_REG_INT1 ||
+ reg == MAX77802_REG_INT2);
+}
+
+static bool max77802_rtc_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ return (reg == MAX77802_RTC_INT ||
+ reg == MAX77802_RTC_UPDATE0 ||
+ reg == MAX77802_RTC_UPDATE1);
+}
+
+static bool max77802_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ return (max77802_pmic_is_precious_reg(dev, reg) ||
+ max77802_rtc_is_precious_reg(dev, reg));
+}
+
+static bool max77802_pmic_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ return (max77802_is_precious_reg(dev, reg) ||
+ reg == MAX77802_REG_STATUS1 || reg == MAX77802_REG_STATUS2 ||
+ reg == MAX77802_REG_PWRON);
+}
+
+static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ return (max77802_rtc_is_precious_reg(dev, reg) ||
+ reg == MAX77802_RTC_SEC ||
+ reg == MAX77802_RTC_MIN ||
+ reg == MAX77802_RTC_HOUR ||
+ reg == MAX77802_RTC_WEEKDAY ||
+ reg == MAX77802_RTC_MONTH ||
+ reg == MAX77802_RTC_YEAR ||
+ reg == MAX77802_RTC_DATE);
+}
+
+static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ return (max77802_pmic_is_volatile_reg(dev, reg) ||
+ max77802_rtc_is_volatile_reg(dev, reg));
+}
+
static struct regmap_config max77686_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
-#ifdef CONFIG_OF
+static struct regmap_config max77686_rtc_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static struct regmap_config max77802_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = max77802_is_accessible_reg,
+ .readable_reg = max77802_is_accessible_reg,
+ .precious_reg = max77802_is_precious_reg,
+ .volatile_reg = max77802_is_volatile_reg,
+ .name = "max77802-pmic",
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static const struct regmap_irq max77686_irqs[] = {
+ /* INT1 interrupts */
+ { .reg_offset = 0, .mask = MAX77686_INT1_PWRONF_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_PWRONR_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBF_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBR_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBF_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBR_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_ONKEY1S_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_INT1_MRSTB_MSK, },
+ /* INT2 interrupts */
+ { .reg_offset = 1, .mask = MAX77686_INT2_140C_MSK, },
+ { .reg_offset = 1, .mask = MAX77686_INT2_120C_MSK, },
+};
+
+static const struct regmap_irq_chip max77686_irq_chip = {
+ .name = "max77686-pmic",
+ .status_base = MAX77686_REG_INT1,
+ .mask_base = MAX77686_REG_INT1MSK,
+ .num_regs = 2,
+ .irqs = max77686_irqs,
+ .num_irqs = ARRAY_SIZE(max77686_irqs),
+};
+
+static const struct regmap_irq max77686_rtc_irqs[] = {
+ /* RTC interrupts */
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_RTC60S_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_RTCA1_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_RTCA2_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_SMPL_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_RTC1S_MSK, },
+ { .reg_offset = 0, .mask = MAX77686_RTCINT_WTSR_MSK, },
+};
+
+static const struct regmap_irq_chip max77686_rtc_irq_chip = {
+ .name = "max77686-rtc",
+ .status_base = MAX77686_RTC_INT,
+ .mask_base = MAX77686_RTC_INTM,
+ .num_regs = 1,
+ .irqs = max77686_rtc_irqs,
+ .num_irqs = ARRAY_SIZE(max77686_rtc_irqs),
+};
+
+static const struct regmap_irq_chip max77802_irq_chip = {
+ .name = "max77802-pmic",
+ .status_base = MAX77802_REG_INT1,
+ .mask_base = MAX77802_REG_INT1MSK,
+ .num_regs = 2,
+ .irqs = max77686_irqs, /* same masks as 77686 */
+ .num_irqs = ARRAY_SIZE(max77686_irqs),
+};
+
+static const struct regmap_irq_chip max77802_rtc_irq_chip = {
+ .name = "max77802-rtc",
+ .status_base = MAX77802_RTC_INT,
+ .mask_base = MAX77802_RTC_INTM,
+ .num_regs = 1,
+ .irqs = max77686_rtc_irqs, /* same masks as 77686 */
+ .num_irqs = ARRAY_SIZE(max77686_rtc_irqs),
+};
+
static const struct of_device_id max77686_pmic_dt_match[] = {
- {.compatible = "maxim,max77686", .data = NULL},
- {},
+ {
+ .compatible = "maxim,max77686",
+ .data = (void *)TYPE_MAX77686,
+ },
+ {
+ .compatible = "maxim,max77802",
+ .data = (void *)TYPE_MAX77802,
+ },
+ { },
};
static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
@@ -58,53 +211,74 @@ static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
struct max77686_platform_data *pd;
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
- if (!pd) {
- dev_err(dev, "could not allocate memory for pdata\n");
+ if (!pd)
return NULL;
- }
dev->platform_data = pd;
return pd;
}
-#else
-static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
- *dev)
-{
- return 0;
-}
-#endif
static int max77686_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77686_dev *max77686 = NULL;
struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev);
+ const struct of_device_id *match;
unsigned int data;
int ret = 0;
+ const struct regmap_config *config;
+ const struct regmap_irq_chip *irq_chip;
+ const struct regmap_irq_chip *rtc_irq_chip;
+ struct regmap **rtc_regmap;
+ const struct mfd_cell *cells;
+ int n_devs;
- if (i2c->dev.of_node)
+ if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node && !pdata)
pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
if (!pdata) {
dev_err(&i2c->dev, "No platform data found.\n");
- return -EIO;
+ return -EINVAL;
}
max77686 = devm_kzalloc(&i2c->dev,
sizeof(struct max77686_dev), GFP_KERNEL);
- if (max77686 == NULL)
+ if (!max77686)
return -ENOMEM;
+ if (i2c->dev.of_node) {
+ match = of_match_node(max77686_pmic_dt_match, i2c->dev.of_node);
+ if (!match)
+ return -EINVAL;
+
+ max77686->type = (unsigned long)match->data;
+ } else
+ max77686->type = id->driver_data;
+
i2c_set_clientdata(i2c, max77686);
max77686->dev = &i2c->dev;
max77686->i2c = i2c;
- max77686->type = id->driver_data;
max77686->wakeup = pdata->wakeup;
- max77686->irq_gpio = pdata->irq_gpio;
max77686->irq = i2c->irq;
- max77686->regmap = devm_regmap_init_i2c(i2c, &max77686_regmap_config);
+ if (max77686->type == TYPE_MAX77686) {
+ config = &max77686_regmap_config;
+ irq_chip = &max77686_irq_chip;
+ rtc_irq_chip = &max77686_rtc_irq_chip;
+ rtc_regmap = &max77686->rtc_regmap;
+ cells = max77686_devs;
+ n_devs = ARRAY_SIZE(max77686_devs);
+ } else {
+ config = &max77802_regmap_config;
+ irq_chip = &max77802_irq_chip;
+ rtc_irq_chip = &max77802_rtc_irq_chip;
+ rtc_regmap = &max77686->regmap;
+ cells = max77802_devs;
+ n_devs = ARRAY_SIZE(max77802_devs);
+ }
+
+ max77686->regmap = devm_regmap_init_i2c(i2c, config);
if (IS_ERR(max77686->regmap)) {
ret = PTR_ERR(max77686->regmap);
dev_err(max77686->dev, "Failed to allocate register map: %d\n",
@@ -112,30 +286,68 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
return ret;
}
- if (regmap_read(max77686->regmap,
- MAX77686_REG_DEVICE_ID, &data) < 0) {
+ ret = regmap_read(max77686->regmap, MAX77686_REG_DEVICE_ID, &data);
+ if (ret < 0) {
dev_err(max77686->dev,
"device not found on this channel (this is not an error)\n");
return -ENODEV;
- } else
- dev_info(max77686->dev, "device found\n");
+ }
- max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
- if (!max77686->rtc) {
- dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n");
- return -ENODEV;
+ if (max77686->type == TYPE_MAX77686) {
+ max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
+ if (!max77686->rtc) {
+ dev_err(max77686->dev,
+ "Failed to allocate I2C device for RTC\n");
+ return -ENODEV;
+ }
+ i2c_set_clientdata(max77686->rtc, max77686);
+
+ max77686->rtc_regmap =
+ devm_regmap_init_i2c(max77686->rtc,
+ &max77686_rtc_regmap_config);
+ if (IS_ERR(max77686->rtc_regmap)) {
+ ret = PTR_ERR(max77686->rtc_regmap);
+ dev_err(max77686->dev,
+ "failed to allocate RTC regmap: %d\n",
+ ret);
+ goto err_unregister_i2c;
+ }
+ }
+
+ ret = regmap_add_irq_chip(max77686->regmap, max77686->irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
+ IRQF_SHARED, 0, irq_chip,
+ &max77686->irq_data);
+ if (ret) {
+ dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret);
+ goto err_unregister_i2c;
}
- i2c_set_clientdata(max77686->rtc, max77686);
- max77686_irq_init(max77686);
+ ret = regmap_add_irq_chip(*rtc_regmap, max77686->irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
+ IRQF_SHARED, 0, rtc_irq_chip,
+ &max77686->rtc_irq_data);
+ if (ret) {
+ dev_err(&i2c->dev, "failed to add RTC irq chip: %d\n", ret);
+ goto err_del_irqc;
+ }
- ret = mfd_add_devices(max77686->dev, -1, max77686_devs,
- ARRAY_SIZE(max77686_devs), NULL, 0, NULL);
+ ret = mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL, 0, NULL);
if (ret < 0) {
- mfd_remove_devices(max77686->dev);
- i2c_unregister_device(max77686->rtc);
+ dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret);
+ goto err_del_rtc_irqc;
}
+ return 0;
+
+err_del_rtc_irqc:
+ regmap_del_irq_chip(max77686->irq, max77686->rtc_irq_data);
+err_del_irqc:
+ regmap_del_irq_chip(max77686->irq, max77686->irq_data);
+err_unregister_i2c:
+ if (max77686->type == TYPE_MAX77686)
+ i2c_unregister_device(max77686->rtc);
+
return ret;
}
@@ -144,7 +356,12 @@ static int max77686_i2c_remove(struct i2c_client *i2c)
struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77686->dev);
- i2c_unregister_device(max77686->rtc);
+
+ regmap_del_irq_chip(max77686->irq, max77686->rtc_irq_data);
+ regmap_del_irq_chip(max77686->irq, max77686->irq_data);
+
+ if (max77686->type == TYPE_MAX77686)
+ i2c_unregister_device(max77686->rtc);
return 0;
}
@@ -155,10 +372,50 @@ static const struct i2c_device_id max77686_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, max77686_i2c_id);
+#ifdef CONFIG_PM_SLEEP
+static int max77686_suspend(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(max77686->irq);
+
+ /*
+ * IRQ must be disabled during suspend because if it happens
+ * while suspended it will be handled before resuming I2C.
+ *
+ * When device is woken up from suspend (e.g. by RTC wake alarm),
+ * an interrupt occurs before resuming I2C bus controller.
+ * Interrupt handler tries to read registers but this read
+ * will fail because I2C is still suspended.
+ */
+ disable_irq(max77686->irq);
+
+ return 0;
+}
+
+static int max77686_resume(struct device *dev)
+{
+ struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+ struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(max77686->irq);
+
+ enable_irq(max77686->irq);
+
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume);
+
static struct i2c_driver max77686_i2c_driver = {
.driver = {
.name = "max77686",
.owner = THIS_MODULE,
+ .pm = &max77686_pm,
.of_match_table = of_match_ptr(max77686_pmic_dt_match),
},
.probe = max77686_i2c_probe,
@@ -179,6 +436,6 @@ static void __exit max77686_i2c_exit(void)
}
module_exit(max77686_i2c_exit);
-MODULE_DESCRIPTION("MAXIM 77686 multi-function core driver");
+MODULE_DESCRIPTION("MAXIM 77686/802 multi-function core driver");
MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644
index 66b58fe77094..000000000000
--- a/drivers/mfd/max77693-irq.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * max77693-irq.c - Interrupt controller support for MAX77693
- *
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * SangYoung Son <hello.son@samsung.com>
- *
- * This program is not provided / owned by Maxim Integrated Products.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This driver is based on max8997-irq.c
- */
-
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/irqdomain.h>
-#include <linux/mfd/max77693.h>
-#include <linux/mfd/max77693-private.h>
-
-static const u8 max77693_mask_reg[] = {
- [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
- [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
- [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
- [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
- [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
- [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
-};
-
-static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
- enum max77693_irq_source src)
-{
- switch (src) {
- case LED_INT ... CHG_INT:
- return max77693->regmap;
- case MUIC_INT1 ... MUIC_INT3:
- return max77693->regmap_muic;
- default:
- return ERR_PTR(-EINVAL);
- }
-}
-
-struct max77693_irq_data {
- int mask;
- enum max77693_irq_source group;
-};
-
-#define DECLARE_IRQ(idx, _group, _mask) \
- [(idx)] = { .group = (_group), .mask = (_mask) }
-static const struct max77693_irq_data max77693_irqs[] = {
- DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0),
- DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1),
- DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2),
- DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3),
- DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4),
-
- DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0),
- DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1),
- DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3),
-
- DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0),
- DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2),
- DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3),
- DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4),
- DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6),
-
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3),
-
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5),
-
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
- DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5),
-};
-
-static void max77693_irq_lock(struct irq_data *data)
-{
- struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-
- mutex_lock(&max77693->irqlock);
-}
-
-static void max77693_irq_sync_unlock(struct irq_data *data)
-{
- struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
- int i;
-
- for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
- u8 mask_reg = max77693_mask_reg[i];
- struct regmap *map = max77693_get_regmap(max77693, i);
-
- if (mask_reg == MAX77693_REG_INVALID ||
- IS_ERR_OR_NULL(map))
- continue;
- max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
-
- max77693_write_reg(map, max77693_mask_reg[i],
- max77693->irq_masks_cur[i]);
- }
-
- mutex_unlock(&max77693->irqlock);
-}
-
-static const inline struct max77693_irq_data *
-irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
-{
- struct irq_data *data = irq_get_irq_data(irq);
- return &max77693_irqs[data->hwirq];
-}
-
-static void max77693_irq_mask(struct irq_data *data)
-{
- struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
- const struct max77693_irq_data *irq_data =
- irq_to_max77693_irq(max77693, data->irq);
-
- if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
- return;
-
- if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
- max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
- else
- max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
-}
-
-static void max77693_irq_unmask(struct irq_data *data)
-{
- struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
- const struct max77693_irq_data *irq_data =
- irq_to_max77693_irq(max77693, data->irq);
-
- if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
- return;
-
- if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
- max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
- else
- max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-}
-
-static struct irq_chip max77693_irq_chip = {
- .name = "max77693",
- .irq_bus_lock = max77693_irq_lock,
- .irq_bus_sync_unlock = max77693_irq_sync_unlock,
- .irq_mask = max77693_irq_mask,
- .irq_unmask = max77693_irq_unmask,
-};
-
-#define MAX77693_IRQSRC_CHG (1 << 0)
-#define MAX77693_IRQSRC_TOP (1 << 1)
-#define MAX77693_IRQSRC_FLASH (1 << 2)
-#define MAX77693_IRQSRC_MUIC (1 << 3)
-static irqreturn_t max77693_irq_thread(int irq, void *data)
-{
- struct max77693_dev *max77693 = data;
- u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
- u8 irq_src;
- int ret;
- int i, cur_irq;
-
- ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
- &irq_src);
- if (ret < 0) {
- dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
- ret);
- return IRQ_NONE;
- }
-
- if (irq_src & MAX77693_IRQSRC_CHG)
- /* CHG_INT */
- ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT,
- &irq_reg[CHG_INT]);
-
- if (irq_src & MAX77693_IRQSRC_TOP)
- /* TOPSYS_INT */
- ret = max77693_read_reg(max77693->regmap,
- MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]);
-
- if (irq_src & MAX77693_IRQSRC_FLASH)
- /* LED_INT */
- ret = max77693_read_reg(max77693->regmap,
- MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]);
-
- if (irq_src & MAX77693_IRQSRC_MUIC)
- /* MUIC INT1 ~ INT3 */
- max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
- MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);
-
- /* Apply masking */
- for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
- if (i >= MUIC_INT1 && i <= MUIC_INT3)
- irq_reg[i] &= max77693->irq_masks_cur[i];
- else
- irq_reg[i] &= ~max77693->irq_masks_cur[i];
- }
-
- /* Report */
- for (i = 0; i < MAX77693_IRQ_NR; i++) {
- if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
- cur_irq = irq_find_mapping(max77693->irq_domain, i);
- if (cur_irq)
- handle_nested_irq(cur_irq);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-int max77693_irq_resume(struct max77693_dev *max77693)
-{
- if (max77693->irq)
- max77693_irq_thread(0, max77693);
-
- return 0;
-}
-
-static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
- struct max77693_dev *max77693 = d->host_data;
-
- irq_set_chip_data(irq, max77693);
- irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq);
- irq_set_nested_thread(irq, 1);
-#ifdef CONFIG_ARM
- set_irq_flags(irq, IRQF_VALID);
-#else
- irq_set_noprobe(irq);
-#endif
- return 0;
-}
-
-static struct irq_domain_ops max77693_irq_domain_ops = {
- .map = max77693_irq_domain_map,
-};
-
-int max77693_irq_init(struct max77693_dev *max77693)
-{
- struct irq_domain *domain;
- int i;
- int ret = 0;
- u8 intsrc_mask;
-
- mutex_init(&max77693->irqlock);
-
- /* Mask individual interrupt sources */
- for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
- struct regmap *map;
- /* MUIC IRQ 0:MASK 1:NOT MASK */
- /* Other IRQ 1:MASK 0:NOT MASK */
- if (i >= MUIC_INT1 && i <= MUIC_INT3) {
- max77693->irq_masks_cur[i] = 0x00;
- max77693->irq_masks_cache[i] = 0x00;
- } else {
- max77693->irq_masks_cur[i] = 0xff;
- max77693->irq_masks_cache[i] = 0xff;
- }
- map = max77693_get_regmap(max77693, i);
-
- if (IS_ERR_OR_NULL(map))
- continue;
- if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
- continue;
- if (i >= MUIC_INT1 && i <= MUIC_INT3)
- max77693_write_reg(map, max77693_mask_reg[i], 0x00);
- else
- max77693_write_reg(map, max77693_mask_reg[i], 0xff);
- }
-
- domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
- &max77693_irq_domain_ops, max77693);
- if (!domain) {
- dev_err(max77693->dev, "could not create irq domain\n");
- ret = -ENODEV;
- goto err_irq;
- }
- max77693->irq_domain = domain;
-
- /* Unmask max77693 interrupt */
- ret = max77693_read_reg(max77693->regmap,
- MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
- if (ret < 0) {
- dev_err(max77693->dev, "fail to read PMIC register\n");
- goto err_irq;
- }
-
- intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
- intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
- intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
- ret = max77693_write_reg(max77693->regmap,
- MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
- if (ret < 0) {
- dev_err(max77693->dev, "fail to write PMIC register\n");
- goto err_irq;
- }
-
- ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "max77693-irq", max77693);
- if (ret)
- dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
- max77693->irq, ret);
-
-err_irq:
- return ret;
-}
-
-void max77693_irq_exit(struct max77693_dev *max77693)
-{
- if (max77693->irq)
- free_irq(max77693->irq, max77693);
-}
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index 7e05428c756d..249c139ef04a 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -49,62 +49,62 @@ static const struct mfd_cell max77693_devs[] = {
{ .name = "max77693-haptic", },
};
-int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest)
-{
- unsigned int val;
- int ret;
-
- ret = regmap_read(map, reg, &val);
- *dest = val;
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_read_reg);
-
-int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf)
-{
- int ret;
-
- ret = regmap_bulk_read(map, reg, buf, count);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_bulk_read);
-
-int max77693_write_reg(struct regmap *map, u8 reg, u8 value)
-{
- int ret;
-
- ret = regmap_write(map, reg, value);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_write_reg);
-
-int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf)
-{
- int ret;
+static const struct regmap_config max77693_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX77693_PMIC_REG_END,
+};
- ret = regmap_bulk_write(map, reg, buf, count);
+static const struct regmap_irq max77693_led_irqs[] = {
+ { .mask = LED_IRQ_FLED2_OPEN, },
+ { .mask = LED_IRQ_FLED2_SHORT, },
+ { .mask = LED_IRQ_FLED1_OPEN, },
+ { .mask = LED_IRQ_FLED1_SHORT, },
+ { .mask = LED_IRQ_MAX_FLASH, },
+};
- return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_bulk_write);
+static const struct regmap_irq_chip max77693_led_irq_chip = {
+ .name = "max77693-led",
+ .status_base = MAX77693_LED_REG_FLASH_INT,
+ .mask_base = MAX77693_LED_REG_FLASH_INT_MASK,
+ .mask_invert = false,
+ .num_regs = 1,
+ .irqs = max77693_led_irqs,
+ .num_irqs = ARRAY_SIZE(max77693_led_irqs),
+};
-int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask)
-{
- int ret;
+static const struct regmap_irq max77693_topsys_irqs[] = {
+ { .mask = TOPSYS_IRQ_T120C_INT, },
+ { .mask = TOPSYS_IRQ_T140C_INT, },
+ { .mask = TOPSYS_IRQ_LOWSYS_INT, },
+};
- ret = regmap_update_bits(map, reg, mask, val);
+static const struct regmap_irq_chip max77693_topsys_irq_chip = {
+ .name = "max77693-topsys",
+ .status_base = MAX77693_PMIC_REG_TOPSYS_INT,
+ .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
+ .mask_invert = false,
+ .num_regs = 1,
+ .irqs = max77693_topsys_irqs,
+ .num_irqs = ARRAY_SIZE(max77693_topsys_irqs),
+};
- return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_update_reg);
+static const struct regmap_irq max77693_charger_irqs[] = {
+ { .mask = CHG_IRQ_BYP_I, },
+ { .mask = CHG_IRQ_THM_I, },
+ { .mask = CHG_IRQ_BAT_I, },
+ { .mask = CHG_IRQ_CHG_I, },
+ { .mask = CHG_IRQ_CHGIN_I, },
+};
-static const struct regmap_config max77693_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = MAX77693_PMIC_REG_END,
+static const struct regmap_irq_chip max77693_charger_irq_chip = {
+ .name = "max77693-charger",
+ .status_base = MAX77693_CHG_REG_CHG_INT,
+ .mask_base = MAX77693_CHG_REG_CHG_INT_MASK,
+ .mask_invert = false,
+ .num_regs = 1,
+ .irqs = max77693_charger_irqs,
+ .num_irqs = ARRAY_SIZE(max77693_charger_irqs),
};
static const struct regmap_config max77693_regmap_muic_config = {
@@ -113,11 +113,42 @@ static const struct regmap_config max77693_regmap_muic_config = {
.max_register = MAX77693_MUIC_REG_END,
};
+static const struct regmap_irq max77693_muic_irqs[] = {
+ { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, },
+ { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, },
+ { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, },
+ { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, },
+
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, },
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, },
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, },
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, },
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, },
+ { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, },
+
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, },
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, },
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, },
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, },
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, },
+ { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, },
+};
+
+static const struct regmap_irq_chip max77693_muic_irq_chip = {
+ .name = "max77693-muic",
+ .status_base = MAX77693_MUIC_REG_INT1,
+ .mask_base = MAX77693_MUIC_REG_INTMASK1,
+ .mask_invert = true,
+ .num_regs = 3,
+ .irqs = max77693_muic_irqs,
+ .num_irqs = ARRAY_SIZE(max77693_muic_irqs),
+};
+
static int max77693_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77693_dev *max77693;
- u8 reg_data;
+ unsigned int reg_data;
int ret = 0;
max77693 = devm_kzalloc(&i2c->dev,
@@ -139,7 +170,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
return ret;
}
- ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
+ ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
&reg_data);
if (ret < 0) {
dev_err(max77693->dev, "device not found on this channel\n");
@@ -176,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
goto err_regmap_muic;
}
- ret = max77693_irq_init(max77693);
- if (ret < 0)
- goto err_irq;
+ ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &max77693_led_irq_chip,
+ &max77693->irq_data_led);
+ if (ret) {
+ dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+ goto err_regmap_muic;
+ }
+
+ ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &max77693_topsys_irq_chip,
+ &max77693->irq_data_topsys);
+ if (ret) {
+ dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+ goto err_irq_topsys;
+ }
+
+ ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &max77693_charger_irq_chip,
+ &max77693->irq_data_charger);
+ if (ret) {
+ dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+ goto err_irq_charger;
+ }
+
+ ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+ IRQF_ONESHOT | IRQF_SHARED |
+ IRQF_TRIGGER_FALLING, 0,
+ &max77693_muic_irq_chip,
+ &max77693->irq_data_muic);
+ if (ret) {
+ dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+ goto err_irq_muic;
+ }
pm_runtime_set_active(max77693->dev);
@@ -190,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
return ret;
err_mfd:
- max77693_irq_exit(max77693);
-err_irq:
+ mfd_remove_devices(max77693->dev);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+err_irq_muic:
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+err_irq_charger:
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+err_irq_topsys:
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
err_regmap_muic:
i2c_unregister_device(max77693->haptic);
err_i2c_haptic:
@@ -204,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77693->dev);
- max77693_irq_exit(max77693);
+
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
+
i2c_unregister_device(max77693->muic);
i2c_unregister_device(max77693->haptic);
@@ -222,8 +300,11 @@ static int max77693_suspend(struct device *dev)
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
- if (device_may_wakeup(dev))
- irq_set_irq_wake(max77693->irq, 1);
+ if (device_may_wakeup(dev)) {
+ enable_irq_wake(max77693->irq);
+ disable_irq(max77693->irq);
+ }
+
return 0;
}
@@ -232,9 +313,12 @@ static int max77693_resume(struct device *dev)
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
- if (device_may_wakeup(dev))
- irq_set_irq_wake(max77693->irq, 0);
- return max77693_irq_resume(max77693);
+ if (device_may_wakeup(dev)) {
+ disable_irq_wake(max77693->irq);
+ enable_irq(max77693->irq);
+ }
+
+ return 0;
}
static const struct dev_pm_ops max77693_pm = {
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index f3faf0c45ddd..97a787ab3d51 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -624,6 +624,7 @@ static void max8925_irq_sync_unlock(struct irq_data *data)
static void max8925_irq_enable(struct irq_data *data)
{
struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
+
max8925_irqs[data->irq - chip->irq_base].enable
= max8925_irqs[data->irq - chip->irq_base].offs;
}
@@ -631,6 +632,7 @@ static void max8925_irq_enable(struct irq_data *data)
static void max8925_irq_disable(struct irq_data *data)
{
struct max8925_chip *chip = irq_data_get_irq_chip_data(data);
+
max8925_irqs[data->irq - chip->irq_base].enable = 0;
}
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index a83eed5c15ca..ecbe78ead3b6 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -257,9 +257,11 @@ static struct i2c_driver max8925_driver = {
static int __init max8925_i2c_init(void)
{
int ret;
+
ret = i2c_add_driver(&max8925_driver);
if (ret != 0)
pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
+
return ret;
}
subsys_initcall(max8925_i2c_init);
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index acf5dd712eb2..2b6bc868cd3d 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -10,106 +10,18 @@
* Free Software Foundation.
*/
-#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/interrupt.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/mc13xxx.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
#include "mc13xxx.h"
#define MC13XXX_IRQSTAT0 0
-#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
-#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
-#define MC13XXX_IRQSTAT0_TSI (1 << 2)
-#define MC13783_IRQSTAT0_WHIGHI (1 << 3)
-#define MC13783_IRQSTAT0_WLOWI (1 << 4)
-#define MC13XXX_IRQSTAT0_CHGDETI (1 << 6)
-#define MC13783_IRQSTAT0_CHGOVI (1 << 7)
-#define MC13XXX_IRQSTAT0_CHGREVI (1 << 8)
-#define MC13XXX_IRQSTAT0_CHGSHORTI (1 << 9)
-#define MC13XXX_IRQSTAT0_CCCVI (1 << 10)
-#define MC13XXX_IRQSTAT0_CHGCURRI (1 << 11)
-#define MC13XXX_IRQSTAT0_BPONI (1 << 12)
-#define MC13XXX_IRQSTAT0_LOBATLI (1 << 13)
-#define MC13XXX_IRQSTAT0_LOBATHI (1 << 14)
-#define MC13783_IRQSTAT0_UDPI (1 << 15)
-#define MC13783_IRQSTAT0_USBI (1 << 16)
-#define MC13783_IRQSTAT0_IDI (1 << 19)
-#define MC13783_IRQSTAT0_SE1I (1 << 21)
-#define MC13783_IRQSTAT0_CKDETI (1 << 22)
-#define MC13783_IRQSTAT0_UDMI (1 << 23)
-
#define MC13XXX_IRQMASK0 1
-#define MC13XXX_IRQMASK0_ADCDONEM MC13XXX_IRQSTAT0_ADCDONEI
-#define MC13XXX_IRQMASK0_ADCBISDONEM MC13XXX_IRQSTAT0_ADCBISDONEI
-#define MC13XXX_IRQMASK0_TSM MC13XXX_IRQSTAT0_TSI
-#define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
-#define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
-#define MC13XXX_IRQMASK0_CHGDETM MC13XXX_IRQSTAT0_CHGDETI
-#define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
-#define MC13XXX_IRQMASK0_CHGREVM MC13XXX_IRQSTAT0_CHGREVI
-#define MC13XXX_IRQMASK0_CHGSHORTM MC13XXX_IRQSTAT0_CHGSHORTI
-#define MC13XXX_IRQMASK0_CCCVM MC13XXX_IRQSTAT0_CCCVI
-#define MC13XXX_IRQMASK0_CHGCURRM MC13XXX_IRQSTAT0_CHGCURRI
-#define MC13XXX_IRQMASK0_BPONM MC13XXX_IRQSTAT0_BPONI
-#define MC13XXX_IRQMASK0_LOBATLM MC13XXX_IRQSTAT0_LOBATLI
-#define MC13XXX_IRQMASK0_LOBATHM MC13XXX_IRQSTAT0_LOBATHI
-#define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
-#define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
-#define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
-#define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
-#define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
-#define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
-
#define MC13XXX_IRQSTAT1 3
-#define MC13XXX_IRQSTAT1_1HZI (1 << 0)
-#define MC13XXX_IRQSTAT1_TODAI (1 << 1)
-#define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
-#define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
-#define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
-#define MC13XXX_IRQSTAT1_SYSRSTI (1 << 6)
-#define MC13XXX_IRQSTAT1_RTCRSTI (1 << 7)
-#define MC13XXX_IRQSTAT1_PCI (1 << 8)
-#define MC13XXX_IRQSTAT1_WARMI (1 << 9)
-#define MC13XXX_IRQSTAT1_MEMHLDI (1 << 10)
-#define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
-#define MC13XXX_IRQSTAT1_THWARNLI (1 << 12)
-#define MC13XXX_IRQSTAT1_THWARNHI (1 << 13)
-#define MC13XXX_IRQSTAT1_CLKI (1 << 14)
-#define MC13783_IRQSTAT1_SEMAFI (1 << 15)
-#define MC13783_IRQSTAT1_MC2BI (1 << 17)
-#define MC13783_IRQSTAT1_HSDETI (1 << 18)
-#define MC13783_IRQSTAT1_HSLI (1 << 19)
-#define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
-#define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
-
#define MC13XXX_IRQMASK1 4
-#define MC13XXX_IRQMASK1_1HZM MC13XXX_IRQSTAT1_1HZI
-#define MC13XXX_IRQMASK1_TODAM MC13XXX_IRQSTAT1_TODAI
-#define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
-#define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
-#define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
-#define MC13XXX_IRQMASK1_SYSRSTM MC13XXX_IRQSTAT1_SYSRSTI
-#define MC13XXX_IRQMASK1_RTCRSTM MC13XXX_IRQSTAT1_RTCRSTI
-#define MC13XXX_IRQMASK1_PCM MC13XXX_IRQSTAT1_PCI
-#define MC13XXX_IRQMASK1_WARMM MC13XXX_IRQSTAT1_WARMI
-#define MC13XXX_IRQMASK1_MEMHLDM MC13XXX_IRQSTAT1_MEMHLDI
-#define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
-#define MC13XXX_IRQMASK1_THWARNLM MC13XXX_IRQSTAT1_THWARNLI
-#define MC13XXX_IRQMASK1_THWARNHM MC13XXX_IRQSTAT1_THWARNHI
-#define MC13XXX_IRQMASK1_CLKM MC13XXX_IRQSTAT1_CLKI
-#define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
-#define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
-#define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
-#define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
-#define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
-#define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
#define MC13XXX_REVISION 7
#define MC13XXX_REVISION_REVMETAL (0x07 << 0)
@@ -189,45 +101,21 @@ EXPORT_SYMBOL(mc13xxx_reg_rmw);
int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq)
{
- int ret;
- unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
- u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
- u32 mask;
-
- if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
- return -EINVAL;
-
- ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
- if (ret)
- return ret;
+ int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
- if (mask & irqbit)
- /* already masked */
- return 0;
+ disable_irq_nosync(virq);
- return mc13xxx_reg_write(mc13xxx, offmask, mask | irqbit);
+ return 0;
}
EXPORT_SYMBOL(mc13xxx_irq_mask);
int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq)
{
- int ret;
- unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1;
- u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
- u32 mask;
-
- if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
- return -EINVAL;
+ int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
- ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
- if (ret)
- return ret;
+ enable_irq(virq);
- if (!(mask & irqbit))
- /* already unmasked */
- return 0;
-
- return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit);
+ return 0;
}
EXPORT_SYMBOL(mc13xxx_irq_unmask);
@@ -239,7 +127,7 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
- if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
+ if (irq < 0 || irq >= ARRAY_SIZE(mc13xxx->irqs))
return -EINVAL;
if (enabled) {
@@ -266,147 +154,26 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq,
}
EXPORT_SYMBOL(mc13xxx_irq_status);
-int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq)
-{
- unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1;
- unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
-
- BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ);
-
- return mc13xxx_reg_write(mc13xxx, offstat, val);
-}
-EXPORT_SYMBOL(mc13xxx_irq_ack);
-
-int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq,
- irq_handler_t handler, const char *name, void *dev)
-{
- BUG_ON(!mutex_is_locked(&mc13xxx->lock));
- BUG_ON(!handler);
-
- if (irq < 0 || irq >= MC13XXX_NUM_IRQ)
- return -EINVAL;
-
- if (mc13xxx->irqhandler[irq])
- return -EBUSY;
-
- mc13xxx->irqhandler[irq] = handler;
- mc13xxx->irqdata[irq] = dev;
-
- return 0;
-}
-EXPORT_SYMBOL(mc13xxx_irq_request_nounmask);
-
int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
irq_handler_t handler, const char *name, void *dev)
{
- int ret;
+ int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
- ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev);
- if (ret)
- return ret;
-
- ret = mc13xxx_irq_unmask(mc13xxx, irq);
- if (ret) {
- mc13xxx->irqhandler[irq] = NULL;
- mc13xxx->irqdata[irq] = NULL;
- return ret;
- }
-
- return 0;
+ return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler,
+ 0, name, dev);
}
EXPORT_SYMBOL(mc13xxx_irq_request);
int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev)
{
- int ret;
- BUG_ON(!mutex_is_locked(&mc13xxx->lock));
+ int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
- if (irq < 0 || irq >= MC13XXX_NUM_IRQ || !mc13xxx->irqhandler[irq] ||
- mc13xxx->irqdata[irq] != dev)
- return -EINVAL;
-
- ret = mc13xxx_irq_mask(mc13xxx, irq);
- if (ret)
- return ret;
-
- mc13xxx->irqhandler[irq] = NULL;
- mc13xxx->irqdata[irq] = NULL;
+ devm_free_irq(mc13xxx->dev, virq, dev);
return 0;
}
EXPORT_SYMBOL(mc13xxx_irq_free);
-static inline irqreturn_t mc13xxx_irqhandler(struct mc13xxx *mc13xxx, int irq)
-{
- return mc13xxx->irqhandler[irq](irq, mc13xxx->irqdata[irq]);
-}
-
-/*
- * returns: number of handled irqs or negative error
- * locking: holds mc13xxx->lock
- */
-static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx,
- unsigned int offstat, unsigned int offmask, int baseirq)
-{
- u32 stat, mask;
- int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat);
- int num_handled = 0;
-
- if (ret)
- return ret;
-
- ret = mc13xxx_reg_read(mc13xxx, offmask, &mask);
- if (ret)
- return ret;
-
- while (stat & ~mask) {
- int irq = __ffs(stat & ~mask);
-
- stat &= ~(1 << irq);
-
- if (likely(mc13xxx->irqhandler[baseirq + irq])) {
- irqreturn_t handled;
-
- handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq);
- if (handled == IRQ_HANDLED)
- num_handled++;
- } else {
- dev_err(mc13xxx->dev,
- "BUG: irq %u but no handler\n",
- baseirq + irq);
-
- mask |= 1 << irq;
-
- ret = mc13xxx_reg_write(mc13xxx, offmask, mask);
- }
- }
-
- return num_handled;
-}
-
-static irqreturn_t mc13xxx_irq_thread(int irq, void *data)
-{
- struct mc13xxx *mc13xxx = data;
- irqreturn_t ret;
- int handled = 0;
-
- mc13xxx_lock(mc13xxx);
-
- ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT0,
- MC13XXX_IRQMASK0, 0);
- if (ret > 0)
- handled = 1;
-
- ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT1,
- MC13XXX_IRQMASK1, 24);
- if (ret > 0)
- handled = 1;
-
- mc13xxx_unlock(mc13xxx);
-
- return IRQ_RETVAL(handled);
-}
-
#define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask))
static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision)
{
@@ -475,8 +242,6 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
{
struct mc13xxx_adcdone_data *adcdone_data = data;
- mc13xxx_irq_ack(adcdone_data->mc13xxx, irq);
-
complete_all(&adcdone_data->done);
return IRQ_HANDLED;
@@ -544,7 +309,6 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__);
mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
mc13xxx_handler_adcdone, __func__, &adcdone_data);
- mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE);
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0);
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1);
@@ -599,7 +363,8 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
if (!cell.name)
return -ENOMEM;
- return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL);
+ return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0,
+ regmap_irq_get_domain(mc13xxx->irq_data));
}
static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
@@ -640,8 +405,8 @@ int mc13xxx_common_init(struct device *dev)
{
struct mc13xxx_platform_data *pdata = dev_get_platdata(dev);
struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
- int ret;
u32 revision;
+ int i, ret;
mc13xxx->dev = dev;
@@ -651,31 +416,32 @@ int mc13xxx_common_init(struct device *dev)
mc13xxx->variant->print_revision(mc13xxx, revision);
- /* mask all irqs */
- ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff);
- if (ret)
- return ret;
+ for (i = 0; i < ARRAY_SIZE(mc13xxx->irqs); i++) {
+ mc13xxx->irqs[i].reg_offset = i / MC13XXX_IRQ_PER_REG;
+ mc13xxx->irqs[i].mask = BIT(i % MC13XXX_IRQ_PER_REG);
+ }
- ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff);
+ mc13xxx->irq_chip.name = dev_name(dev);
+ mc13xxx->irq_chip.status_base = MC13XXX_IRQSTAT0;
+ mc13xxx->irq_chip.mask_base = MC13XXX_IRQMASK0;
+ mc13xxx->irq_chip.ack_base = MC13XXX_IRQSTAT0;
+ mc13xxx->irq_chip.irq_reg_stride = MC13XXX_IRQSTAT1 - MC13XXX_IRQSTAT0;
+ mc13xxx->irq_chip.init_ack_masked = true;
+ mc13xxx->irq_chip.use_ack = true;
+ mc13xxx->irq_chip.num_regs = MC13XXX_IRQ_REG_CNT;
+ mc13xxx->irq_chip.irqs = mc13xxx->irqs;
+ mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs);
+
+ ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT,
+ 0, &mc13xxx->irq_chip, &mc13xxx->irq_data);
if (ret)
return ret;
mutex_init(&mc13xxx->lock);
- ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread,
- IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx);
- if (ret)
- return ret;
-
if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata)
mc13xxx->flags = pdata->flags;
- if (mc13xxx->flags & MC13XXX_USE_ADC)
- mc13xxx_add_subdevice(mc13xxx, "%s-adc");
-
- if (mc13xxx->flags & MC13XXX_USE_RTC)
- mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
-
if (pdata) {
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
&pdata->regulators, sizeof(pdata->regulators));
@@ -699,6 +465,12 @@ int mc13xxx_common_init(struct device *dev)
mc13xxx_add_subdevice(mc13xxx, "%s-ts");
}
+ if (mc13xxx->flags & MC13XXX_USE_ADC)
+ mc13xxx_add_subdevice(mc13xxx, "%s-adc");
+
+ if (mc13xxx->flags & MC13XXX_USE_RTC)
+ mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
+
return 0;
}
EXPORT_SYMBOL_GPL(mc13xxx_common_init);
@@ -707,8 +479,8 @@ int mc13xxx_common_exit(struct device *dev)
{
struct mc13xxx *mc13xxx = dev_get_drvdata(dev);
- free_irq(mc13xxx->irq, mc13xxx);
mfd_remove_devices(dev);
+ regmap_del_irq_chip(mc13xxx->irq, mc13xxx->irq_data);
mutex_destroy(&mc13xxx->lock);
return 0;
diff --git a/drivers/mfd/mc13xxx.h b/drivers/mfd/mc13xxx.h
index ae7f1659f5d1..33677d1dcf66 100644
--- a/drivers/mfd/mc13xxx.h
+++ b/drivers/mfd/mc13xxx.h
@@ -13,7 +13,9 @@
#include <linux/regmap.h>
#include <linux/mfd/mc13xxx.h>
-#define MC13XXX_NUMREGS 0x3f
+#define MC13XXX_NUMREGS 0x3f
+#define MC13XXX_IRQ_REG_CNT 2
+#define MC13XXX_IRQ_PER_REG 24
struct mc13xxx;
@@ -33,13 +35,14 @@ struct mc13xxx {
struct device *dev;
const struct mc13xxx_variant *variant;
+ struct regmap_irq irqs[MC13XXX_IRQ_PER_REG * MC13XXX_IRQ_REG_CNT];
+ struct regmap_irq_chip irq_chip;
+ struct regmap_irq_chip_data *irq_data;
+
struct mutex lock;
int irq;
int flags;
- irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
- void *irqdata[MC13XXX_NUM_IRQ];
-
int adcflags;
};
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 62e5e3617eb0..7f5066e39752 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -137,6 +137,7 @@ EXPORT_SYMBOL(mcp_reg_read);
void mcp_enable(struct mcp *mcp)
{
unsigned long flags;
+
spin_lock_irqsave(&mcp->lock, flags);
if (mcp->use_count++ == 0)
mcp->ops->enable(mcp);
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index b48d80c367f9..33a9234b701c 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -445,7 +445,7 @@ static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap,
for (i = 0; i < omap->nports; i++) {
if (is_ehci_phy_mode(pdata->port_mode[i])) {
- reg &= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
+ reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
break;
}
}
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index d280d789e55a..28cb048f4760 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -25,52 +25,6 @@
#include <linux/mfd/palmas.h>
#include <linux/of_device.h>
-#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 | \
- PALMAS_EXT_CONTROL_ENABLE2 | \
- PALMAS_EXT_CONTROL_NSLEEP)
-
-struct palmas_sleep_requestor_info {
- int id;
- int reg_offset;
- int bit_pos;
-};
-
-#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \
- [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \
- .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \
- .reg_offset = _offset, \
- .bit_pos = _pos, \
- }
-
-static struct palmas_sleep_requestor_info sleep_req_info[] = {
- EXTERNAL_REQUESTOR(REGEN1, 0, 0),
- EXTERNAL_REQUESTOR(REGEN2, 0, 1),
- EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
- EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
- EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
- EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
- EXTERNAL_REQUESTOR(REGEN3, 0, 6),
- EXTERNAL_REQUESTOR(SMPS12, 1, 0),
- EXTERNAL_REQUESTOR(SMPS3, 1, 1),
- EXTERNAL_REQUESTOR(SMPS45, 1, 2),
- EXTERNAL_REQUESTOR(SMPS6, 1, 3),
- EXTERNAL_REQUESTOR(SMPS7, 1, 4),
- EXTERNAL_REQUESTOR(SMPS8, 1, 5),
- EXTERNAL_REQUESTOR(SMPS9, 1, 6),
- EXTERNAL_REQUESTOR(SMPS10, 1, 7),
- EXTERNAL_REQUESTOR(LDO1, 2, 0),
- EXTERNAL_REQUESTOR(LDO2, 2, 1),
- EXTERNAL_REQUESTOR(LDO3, 2, 2),
- EXTERNAL_REQUESTOR(LDO4, 2, 3),
- EXTERNAL_REQUESTOR(LDO5, 2, 4),
- EXTERNAL_REQUESTOR(LDO6, 2, 5),
- EXTERNAL_REQUESTOR(LDO7, 2, 6),
- EXTERNAL_REQUESTOR(LDO8, 2, 7),
- EXTERNAL_REQUESTOR(LDO9, 3, 0),
- EXTERNAL_REQUESTOR(LDOLN, 3, 1),
- EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
-};
-
static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
{
.reg_bits = 8,
@@ -92,6 +46,133 @@ static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
},
};
+static const struct regmap_irq tps65917_irqs[] = {
+ /* INT1 IRQs */
+ [TPS65917_RESERVED1] = {
+ .mask = TPS65917_RESERVED,
+ },
+ [TPS65917_PWRON_IRQ] = {
+ .mask = TPS65917_INT1_STATUS_PWRON,
+ },
+ [TPS65917_LONG_PRESS_KEY_IRQ] = {
+ .mask = TPS65917_INT1_STATUS_LONG_PRESS_KEY,
+ },
+ [TPS65917_RESERVED2] = {
+ .mask = TPS65917_RESERVED,
+ },
+ [TPS65917_PWRDOWN_IRQ] = {
+ .mask = TPS65917_INT1_STATUS_PWRDOWN,
+ },
+ [TPS65917_HOTDIE_IRQ] = {
+ .mask = TPS65917_INT1_STATUS_HOTDIE,
+ },
+ [TPS65917_VSYS_MON_IRQ] = {
+ .mask = TPS65917_INT1_STATUS_VSYS_MON,
+ },
+ [TPS65917_RESERVED3] = {
+ .mask = TPS65917_RESERVED,
+ },
+ /* INT2 IRQs*/
+ [TPS65917_RESERVED4] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 1,
+ },
+ [TPS65917_OTP_ERROR_IRQ] = {
+ .mask = TPS65917_INT2_STATUS_OTP_ERROR,
+ .reg_offset = 1,
+ },
+ [TPS65917_WDT_IRQ] = {
+ .mask = TPS65917_INT2_STATUS_WDT,
+ .reg_offset = 1,
+ },
+ [TPS65917_RESERVED5] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 1,
+ },
+ [TPS65917_RESET_IN_IRQ] = {
+ .mask = TPS65917_INT2_STATUS_RESET_IN,
+ .reg_offset = 1,
+ },
+ [TPS65917_FSD_IRQ] = {
+ .mask = TPS65917_INT2_STATUS_FSD,
+ .reg_offset = 1,
+ },
+ [TPS65917_SHORT_IRQ] = {
+ .mask = TPS65917_INT2_STATUS_SHORT,
+ .reg_offset = 1,
+ },
+ [TPS65917_RESERVED6] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 1,
+ },
+ /* INT3 IRQs */
+ [TPS65917_GPADC_AUTO_0_IRQ] = {
+ .mask = TPS65917_INT3_STATUS_GPADC_AUTO_0,
+ .reg_offset = 2,
+ },
+ [TPS65917_GPADC_AUTO_1_IRQ] = {
+ .mask = TPS65917_INT3_STATUS_GPADC_AUTO_1,
+ .reg_offset = 2,
+ },
+ [TPS65917_GPADC_EOC_SW_IRQ] = {
+ .mask = TPS65917_INT3_STATUS_GPADC_EOC_SW,
+ .reg_offset = 2,
+ },
+ [TPS65917_RESREVED6] = {
+ .mask = TPS65917_RESERVED6,
+ .reg_offset = 2,
+ },
+ [TPS65917_RESERVED7] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 2,
+ },
+ [TPS65917_RESERVED8] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 2,
+ },
+ [TPS65917_RESERVED9] = {
+ .mask = TPS65917_RESERVED,
+ .reg_offset = 2,
+ },
+ [TPS65917_VBUS_IRQ] = {
+ .mask = TPS65917_INT3_STATUS_VBUS,
+ .reg_offset = 2,
+ },
+ /* INT4 IRQs */
+ [TPS65917_GPIO_0_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_0,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_1_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_1,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_2_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_2,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_3_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_3,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_4_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_4,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_5_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_5,
+ .reg_offset = 3,
+ },
+ [TPS65917_GPIO_6_IRQ] = {
+ .mask = TPS65917_INT4_STATUS_GPIO_6,
+ .reg_offset = 3,
+ },
+ [TPS65917_RESERVED10] = {
+ .mask = TPS65917_RESERVED10,
+ .reg_offset = 3,
+ },
+};
+
static const struct regmap_irq palmas_irqs[] = {
/* INT1 IRQs */
[PALMAS_CHARG_DET_N_VBUS_OVV_IRQ] = {
@@ -232,13 +313,26 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
+static struct regmap_irq_chip tps65917_irq_chip = {
+ .name = "tps65917",
+ .irqs = tps65917_irqs,
+ .num_irqs = ARRAY_SIZE(tps65917_irqs),
+
+ .num_regs = 4,
+ .irq_reg_stride = 5,
+ .status_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE,
+ PALMAS_INT1_STATUS),
+ .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE,
+ PALMAS_INT1_MASK),
+};
+
int palmas_ext_control_req_config(struct palmas *palmas,
enum palmas_external_requestor_id id, int ext_ctrl, bool enable)
{
+ struct palmas_pmic_driver_data *pmic_ddata = palmas->pmic_ddata;
int preq_mask_bit = 0;
int reg_add = 0;
- int bit_pos;
- int ret;
+ int bit_pos, ret;
if (!(ext_ctrl & PALMAS_EXT_REQ))
return 0;
@@ -257,8 +351,8 @@ int palmas_ext_control_req_config(struct palmas *palmas,
preq_mask_bit = 2;
}
- bit_pos = sleep_req_info[id].bit_pos;
- reg_add += sleep_req_info[id].reg_offset;
+ bit_pos = pmic_ddata->sleep_req_info[id].bit_pos;
+ reg_add += pmic_ddata->sleep_req_info[id].reg_offset;
if (enable)
ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
reg_add, BIT(bit_pos), BIT(bit_pos));
@@ -357,14 +451,38 @@ static void palmas_power_off(void)
static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
static unsigned int tps659038_features;
+struct palmas_driver_data {
+ unsigned int *features;
+ struct regmap_irq_chip *irq_chip;
+};
+
+static struct palmas_driver_data palmas_data = {
+ .features = &palmas_features,
+ .irq_chip = &palmas_irq_chip,
+};
+
+static struct palmas_driver_data tps659038_data = {
+ .features = &tps659038_features,
+ .irq_chip = &palmas_irq_chip,
+};
+
+static struct palmas_driver_data tps65917_data = {
+ .features = &tps659038_features,
+ .irq_chip = &tps65917_irq_chip,
+};
+
static const struct of_device_id of_palmas_match_tbl[] = {
{
.compatible = "ti,palmas",
- .data = &palmas_features,
+ .data = &palmas_data,
},
{
.compatible = "ti,tps659038",
- .data = &tps659038_features,
+ .data = &tps659038_data,
+ },
+ {
+ .compatible = "ti,tps65917",
+ .data = &tps65917_data,
},
{ },
};
@@ -375,9 +493,10 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
{
struct palmas *palmas;
struct palmas_platform_data *pdata;
+ struct palmas_driver_data *driver_data;
struct device_node *node = i2c->dev.of_node;
int ret = 0, i;
- unsigned int reg, addr, *features;
+ unsigned int reg, addr;
int slave;
const struct of_device_id *match;
@@ -408,8 +527,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
if (!match)
return -ENODATA;
- features = (unsigned int *)match->data;
- palmas->features = *features;
+ driver_data = (struct palmas_driver_data *)match->data;
+ palmas->features = *driver_data->features;
for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
if (i == 0)
@@ -463,8 +582,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
regmap_write(palmas->regmap[slave], addr, reg);
ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
- IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
- &palmas->irq_data);
+ IRQF_ONESHOT | pdata->irq_flags, 0,
+ driver_data->irq_chip, &palmas->irq_data);
if (ret < 0)
goto err_i2c;
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 41ab5e34d2ac..c87f7a0a53f8 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -244,20 +244,20 @@ static int pcf50633_probe(struct i2c_client *client,
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
struct platform_device *pdev;
+ int j;
pdev = platform_device_alloc("pcf50633-regulator", i);
- if (!pdev) {
- dev_err(pcf->dev, "Cannot create regulator %d\n", i);
- continue;
- }
+ if (!pdev)
+ return -ENOMEM;
pdev->dev.parent = pcf->dev;
- if (platform_device_add_data(pdev, &pdata->reg_init_data[i],
- sizeof(pdata->reg_init_data[i])) < 0) {
+ ret = platform_device_add_data(pdev, &pdata->reg_init_data[i],
+ sizeof(pdata->reg_init_data[i]));
+ if (ret) {
platform_device_put(pdev);
- dev_err(pcf->dev, "Out of memory for regulator parameters %d\n",
- i);
- continue;
+ for (j = 0; j < i; j++)
+ platform_device_put(pcf->regulator_pdev[j]);
+ return ret;
}
pcf->regulator_pdev[i] = pdev;
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 959513803542..39904f77c049 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -186,11 +186,9 @@ static void pm8xxx_irq_mask_ack(struct irq_data *d)
{
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
unsigned int pmirq = irqd_to_hwirq(d);
- int irq_bit;
u8 block, config;
block = pmirq / 8;
- irq_bit = pmirq % 8;
config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
pm8xxx_config_irq(chip, block, config);
@@ -200,11 +198,9 @@ static void pm8xxx_irq_unmask(struct irq_data *d)
{
struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
unsigned int pmirq = irqd_to_hwirq(d);
- int irq_bit;
u8 block, config;
block = pmirq / 8;
- irq_bit = pmirq % 8;
config = chip->config[pmirq];
pm8xxx_config_irq(chip, block, config);
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 1d15735f9ef9..d01b8c249231 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -337,40 +337,64 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
int num_sg, bool read, int timeout)
{
- struct completion trans_done;
- u8 dir;
- int err = 0, i, count;
- long timeleft;
- unsigned long flags;
- struct scatterlist *sg;
- enum dma_data_direction dma_dir;
- u32 val;
- dma_addr_t addr;
- unsigned int len;
+ int err = 0, count;
dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+ count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
+ if (count < 1)
+ return -EINVAL;
+ dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
+
+ err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout);
+
+ rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
+
+int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int num_sg, bool read)
+{
+ enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
- /* don't transfer data during abort processing */
if (pcr->remove_pci)
return -EINVAL;
if ((sglist == NULL) || (num_sg <= 0))
return -EINVAL;
- if (read) {
- dir = DEVICE_TO_HOST;
- dma_dir = DMA_FROM_DEVICE;
- } else {
- dir = HOST_TO_DEVICE;
- dma_dir = DMA_TO_DEVICE;
- }
+ return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg);
- count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
- if (count < 1) {
- dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
+void rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int num_sg, bool read)
+{
+ enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+ dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg);
+
+int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int count, bool read, int timeout)
+{
+ struct completion trans_done;
+ struct scatterlist *sg;
+ dma_addr_t addr;
+ long timeleft;
+ unsigned long flags;
+ unsigned int len;
+ int i, err = 0;
+ u32 val;
+ u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE;
+
+ if (pcr->remove_pci)
+ return -ENODEV;
+
+ if ((sglist == NULL) || (count < 1))
return -EINVAL;
- }
- dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
pcr->sgi = 0;
@@ -400,12 +424,10 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
}
spin_lock_irqsave(&pcr->lock, flags);
-
if (pcr->trans_result == TRANS_RESULT_FAIL)
err = -EINVAL;
else if (pcr->trans_result == TRANS_NO_DEVICE)
err = -ENODEV;
-
spin_unlock_irqrestore(&pcr->lock, flags);
out:
@@ -413,8 +435,6 @@ out:
pcr->done = NULL;
spin_unlock_irqrestore(&pcr->lock, flags);
- dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
-
if ((err < 0) && (err != -ENODEV))
rtsx_pci_stop_cmd(pcr);
@@ -423,7 +443,7 @@ out:
return err;
}
-EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
+EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer);
int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
{
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index be06d0abbf19..dba7e2b6f8e9 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -28,8 +28,10 @@
#include <linux/mfd/samsung/s2mpa01.h>
#include <linux/mfd/samsung/s2mps11.h>
#include <linux/mfd/samsung/s2mps14.h>
+#include <linux/mfd/samsung/s2mpu02.h>
#include <linux/mfd/samsung/s5m8763.h>
#include <linux/mfd/samsung/s5m8767.h>
+#include <linux/regulator/machine.h>
#include <linux/regmap.h>
static const struct mfd_cell s5m8751_devs[] = {
@@ -89,6 +91,15 @@ static const struct mfd_cell s2mpa01_devs[] = {
},
};
+static const struct mfd_cell s2mpu02_devs[] = {
+ { .name = "s2mpu02-pmic", },
+ { .name = "s2mpu02-rtc", },
+ {
+ .name = "s2mpu02-clk",
+ .of_compatible = "samsung,s2mpu02-clk",
+ }
+};
+
#ifdef CONFIG_OF
static const struct of_device_id sec_dt_match[] = {
{ .compatible = "samsung,s5m8767-pmic",
@@ -103,6 +114,9 @@ static const struct of_device_id sec_dt_match[] = {
.compatible = "samsung,s2mpa01-pmic",
.data = (void *)S2MPA01,
}, {
+ .compatible = "samsung,s2mpu02-pmic",
+ .data = (void *)S2MPU02,
+ }, {
/* Sentinel */
},
};
@@ -132,6 +146,18 @@ static bool s2mps11_volatile(struct device *dev, unsigned int reg)
}
}
+static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case S2MPU02_REG_INT1M:
+ case S2MPU02_REG_INT2M:
+ case S2MPU02_REG_INT3M:
+ return false;
+ default:
+ return true;
+ }
+}
+
static bool s5m8763_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -177,6 +203,15 @@ static const struct regmap_config s2mps14_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
+static const struct regmap_config s2mpu02_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = S2MPU02_REG_DVSDATA,
+ .volatile_reg = s2mpu02_volatile,
+ .cache_type = REGCACHE_FLAT,
+};
+
static const struct regmap_config s5m8763_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -238,6 +273,7 @@ static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c,
#ifdef CONFIG_OF
if (i2c->dev.of_node) {
const struct of_device_id *match;
+
match = of_match_node(sec_dt_match, i2c->dev.of_node);
return (unsigned long)match->data;
}
@@ -250,9 +286,10 @@ static int sec_pmic_probe(struct i2c_client *i2c,
{
struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev);
const struct regmap_config *regmap;
+ const struct mfd_cell *sec_devs;
struct sec_pmic_dev *sec_pmic;
unsigned long device_type;
- int ret;
+ int ret, num_sec_devs;
sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
GFP_KERNEL);
@@ -297,6 +334,9 @@ static int sec_pmic_probe(struct i2c_client *i2c,
case S5M8767X:
regmap = &s5m8767_regmap_config;
break;
+ case S2MPU02:
+ regmap = &s2mpu02_regmap_config;
+ break;
default:
regmap = &sec_regmap_config;
break;
@@ -319,34 +359,39 @@ static int sec_pmic_probe(struct i2c_client *i2c,
switch (sec_pmic->device_type) {
case S5M8751X:
- ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs,
- ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL);
+ sec_devs = s5m8751_devs;
+ num_sec_devs = ARRAY_SIZE(s5m8751_devs);
break;
case S5M8763X:
- ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs,
- ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL);
+ sec_devs = s5m8763_devs;
+ num_sec_devs = ARRAY_SIZE(s5m8763_devs);
break;
case S5M8767X:
- ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs,
- ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL);
+ sec_devs = s5m8767_devs;
+ num_sec_devs = ARRAY_SIZE(s5m8767_devs);
break;
case S2MPA01:
- ret = mfd_add_devices(sec_pmic->dev, -1, s2mpa01_devs,
- ARRAY_SIZE(s2mpa01_devs), NULL, 0, NULL);
+ sec_devs = s2mpa01_devs;
+ num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
break;
case S2MPS11X:
- ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs,
- ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);
+ sec_devs = s2mps11_devs;
+ num_sec_devs = ARRAY_SIZE(s2mps11_devs);
break;
case S2MPS14X:
- ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs,
- ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL);
+ sec_devs = s2mps14_devs;
+ num_sec_devs = ARRAY_SIZE(s2mps14_devs);
+ break;
+ case S2MPU02:
+ sec_devs = s2mpu02_devs;
+ num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
break;
default:
/* If this happens the probe function is problem */
BUG();
}
-
+ ret = mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL,
+ 0, NULL);
if (ret)
goto err_mfd;
@@ -387,6 +432,15 @@ static int sec_pmic_suspend(struct device *dev)
*/
disable_irq(sec_pmic->irq);
+ switch (sec_pmic->device_type) {
+ case S2MPS14X:
+ case S2MPU02:
+ regulator_suspend_prepare(PM_SUSPEND_MEM);
+ break;
+ default:
+ break;
+ }
+
return 0;
}
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c
index 654e2c1dbf7a..f9a57869e3ec 100644
--- a/drivers/mfd/sec-irq.c
+++ b/drivers/mfd/sec-irq.c
@@ -20,6 +20,7 @@
#include <linux/mfd/samsung/irq.h>
#include <linux/mfd/samsung/s2mps11.h>
#include <linux/mfd/samsung/s2mps14.h>
+#include <linux/mfd/samsung/s2mpu02.h>
#include <linux/mfd/samsung/s5m8763.h>
#include <linux/mfd/samsung/s5m8767.h>
@@ -161,6 +162,77 @@ static const struct regmap_irq s2mps14_irqs[] = {
},
};
+static const struct regmap_irq s2mpu02_irqs[] = {
+ [S2MPU02_IRQ_PWRONF] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_PWRONF_MASK,
+ },
+ [S2MPU02_IRQ_PWRONR] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_PWRONR_MASK,
+ },
+ [S2MPU02_IRQ_JIGONBF] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_JIGONBF_MASK,
+ },
+ [S2MPU02_IRQ_JIGONBR] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_JIGONBR_MASK,
+ },
+ [S2MPU02_IRQ_ACOKBF] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_ACOKBF_MASK,
+ },
+ [S2MPU02_IRQ_ACOKBR] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_ACOKBR_MASK,
+ },
+ [S2MPU02_IRQ_PWRON1S] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_PWRON1S_MASK,
+ },
+ [S2MPU02_IRQ_MRB] = {
+ .reg_offset = 0,
+ .mask = S2MPS11_IRQ_MRB_MASK,
+ },
+ [S2MPU02_IRQ_RTC60S] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_RTC60S_MASK,
+ },
+ [S2MPU02_IRQ_RTCA1] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_RTCA1_MASK,
+ },
+ [S2MPU02_IRQ_RTCA0] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_RTCA0_MASK,
+ },
+ [S2MPU02_IRQ_SMPL] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_SMPL_MASK,
+ },
+ [S2MPU02_IRQ_RTC1S] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_RTC1S_MASK,
+ },
+ [S2MPU02_IRQ_WTSR] = {
+ .reg_offset = 1,
+ .mask = S2MPS11_IRQ_WTSR_MASK,
+ },
+ [S2MPU02_IRQ_INT120C] = {
+ .reg_offset = 2,
+ .mask = S2MPS11_IRQ_INT120C_MASK,
+ },
+ [S2MPU02_IRQ_INT140C] = {
+ .reg_offset = 2,
+ .mask = S2MPS11_IRQ_INT140C_MASK,
+ },
+ [S2MPU02_IRQ_TSD] = {
+ .reg_offset = 2,
+ .mask = S2MPS14_IRQ_TSD_MASK,
+ },
+};
+
static const struct regmap_irq s5m8767_irqs[] = {
[S5M8767_IRQ_PWRR] = {
.reg_offset = 0,
@@ -327,6 +399,16 @@ static const struct regmap_irq_chip s2mps14_irq_chip = {
.ack_base = S2MPS14_REG_INT1,
};
+static const struct regmap_irq_chip s2mpu02_irq_chip = {
+ .name = "s2mpu02",
+ .irqs = s2mpu02_irqs,
+ .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
+ .num_regs = 3,
+ .status_base = S2MPU02_REG_INT1,
+ .mask_base = S2MPU02_REG_INT1M,
+ .ack_base = S2MPU02_REG_INT1,
+};
+
static const struct regmap_irq_chip s5m8767_irq_chip = {
.name = "s5m8767",
.irqs = s5m8767_irqs,
@@ -351,6 +433,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
{
int ret = 0;
int type = sec_pmic->device_type;
+ const struct regmap_irq_chip *sec_irq_chip;
if (!sec_pmic->irq) {
dev_warn(sec_pmic->dev,
@@ -361,28 +444,19 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
switch (type) {
case S5M8763X:
- ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- sec_pmic->irq_base, &s5m8763_irq_chip,
- &sec_pmic->irq_data);
+ sec_irq_chip = &s5m8763_irq_chip;
break;
case S5M8767X:
- ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- sec_pmic->irq_base, &s5m8767_irq_chip,
- &sec_pmic->irq_data);
+ sec_irq_chip = &s5m8767_irq_chip;
break;
case S2MPS11X:
- ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- sec_pmic->irq_base, &s2mps11_irq_chip,
- &sec_pmic->irq_data);
+ sec_irq_chip = &s2mps11_irq_chip;
break;
case S2MPS14X:
- ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- sec_pmic->irq_base, &s2mps14_irq_chip,
- &sec_pmic->irq_data);
+ sec_irq_chip = &s2mps14_irq_chip;
+ break;
+ case S2MPU02:
+ sec_irq_chip = &s2mpu02_irq_chip;
break;
default:
dev_err(sec_pmic->dev, "Unknown device type %lu\n",
@@ -390,6 +464,10 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
return -EINVAL;
}
+ ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ sec_pmic->irq_base, sec_irq_chip,
+ &sec_pmic->irq_data);
if (ret != 0) {
dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
return ret;
diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c
index 6f1ef63086c9..2086b4665288 100644
--- a/drivers/mfd/si476x-cmd.c
+++ b/drivers/mfd/si476x-cmd.c
@@ -1228,8 +1228,8 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
}
static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
- struct si476x_rsq_status_args *rsqargs,
- struct si476x_rsq_status_report *report)
+ struct si476x_rsq_status_args *rsqargs,
+ struct si476x_rsq_status_report *report)
{
int err;
u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP];
@@ -1434,10 +1434,10 @@ typedef int (*tune_freq_func_t) (struct si476x_core *core,
struct si476x_tune_freq_args *tuneargs);
static struct {
- int (*power_up) (struct si476x_core *,
- struct si476x_power_up_args *);
- int (*power_down) (struct si476x_core *,
- struct si476x_power_down_args *);
+ int (*power_up)(struct si476x_core *,
+ struct si476x_power_up_args *);
+ int (*power_down)(struct si476x_core *,
+ struct si476x_power_down_args *);
tune_freq_func_t fm_tune_freq;
tune_freq_func_t am_tune_freq;
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index a45f9c0a330a..5c054031c3f8 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -68,7 +68,7 @@ MODULE_DEVICE_TABLE(of, stmpe_of_match);
static int
stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
- int partnum;
+ enum stmpe_partnum partnum;
const struct of_device_id *of_id;
i2c_ci.data = (void *)id;
@@ -85,7 +85,7 @@ stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
dev_info(&i2c->dev, "matching on node name, compatible is preferred\n");
partnum = id->driver_data;
} else
- partnum = (int)of_id->data;
+ partnum = (enum stmpe_partnum)of_id->data;
return stmpe_probe(&i2c_ci, partnum);
}
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 3b6bfa7184ad..02a17c388e87 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -1147,7 +1147,7 @@ static void stmpe_of_probe(struct stmpe_platform_data *pdata,
}
/* Called from client specific probe routines */
-int stmpe_probe(struct stmpe_client_info *ci, int partnum)
+int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
{
struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
struct device_node *np = ci->dev->of_node;
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index 9e4d21d37a11..2d045f26f193 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -97,7 +97,7 @@ struct stmpe_client_info {
void (*init)(struct stmpe *stmpe);
};
-int stmpe_probe(struct stmpe_client_info *ci, int partnum);
+int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum);
int stmpe_remove(struct stmpe *stmpe);
#define STMPE_ICR_LSB_HIGH (1 << 2)
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 718fc4d2adc0..283ab8d197e4 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -76,16 +76,46 @@ static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
},
};
+static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
+ {
+ .name = "sun8i-a23-apb0-clk",
+ .of_compatible = "allwinner,sun8i-a23-apb0-clk",
+ .num_resources = ARRAY_SIZE(sun6i_a31_apb0_clk_res),
+ .resources = sun6i_a31_apb0_clk_res,
+ },
+ {
+ .name = "sun6i-a31-apb0-gates-clk",
+ .of_compatible = "allwinner,sun8i-a23-apb0-gates-clk",
+ .num_resources = ARRAY_SIZE(sun6i_a31_apb0_gates_clk_res),
+ .resources = sun6i_a31_apb0_gates_clk_res,
+ },
+ {
+ .name = "sun6i-a31-apb0-clock-reset",
+ .of_compatible = "allwinner,sun6i-a31-clock-reset",
+ .num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
+ .resources = sun6i_a31_apb0_rstc_res,
+ },
+};
+
static const struct prcm_data sun6i_a31_prcm_data = {
.nsubdevs = ARRAY_SIZE(sun6i_a31_prcm_subdevs),
.subdevs = sun6i_a31_prcm_subdevs,
};
+static const struct prcm_data sun8i_a23_prcm_data = {
+ .nsubdevs = ARRAY_SIZE(sun8i_a23_prcm_subdevs),
+ .subdevs = sun8i_a23_prcm_subdevs,
+};
+
static const struct of_device_id sun6i_prcm_dt_ids[] = {
{
.compatible = "allwinner,sun6i-a31-prcm",
.data = &sun6i_a31_prcm_data,
},
+ {
+ .compatible = "allwinner,sun8i-a23-prcm",
+ .data = &sun8i_a23_prcm_data,
+ },
{ /* sentinel */ },
};
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index bd83accc0f6d..0072e668c208 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -236,7 +236,7 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
static struct irq_domain_ops tc3589x_irq_ops = {
.map = tc3589x_irq_map,
.unmap = tc3589x_irq_unmap,
- .xlate = irq_domain_xlate_twocell,
+ .xlate = irq_domain_xlate_onecell,
};
static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 591a331d8d83..e71f88000ae5 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -147,11 +147,10 @@ static int tc6387xb_probe(struct platform_device *dev)
int irq, ret;
iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!iomem) {
+ if (!iomem)
return -EINVAL;
- }
- tc6387xb = kzalloc(sizeof *tc6387xb, GFP_KERNEL);
+ tc6387xb = kzalloc(sizeof(*tc6387xb), GFP_KERNEL);
if (!tc6387xb)
return -ENOMEM;
@@ -189,7 +188,7 @@ static int tc6387xb_probe(struct platform_device *dev)
if (pdata && pdata->enable)
pdata->enable(dev);
- printk(KERN_INFO "Toshiba tc6387xb initialised\n");
+ dev_info(&dev->dev, "Toshiba tc6387xb initialised\n");
ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL);
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index b5dfa6e4e692..5de95c265c1a 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -141,7 +141,7 @@ static int tps6105x_probe(struct i2c_client *client,
int ret;
int i;
- tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL);
+ tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL);
if (!tps6105x)
return -ENOMEM;
@@ -154,7 +154,7 @@ static int tps6105x_probe(struct i2c_client *client,
ret = tps6105x_startup(tps6105x);
if (ret) {
dev_err(&client->dev, "chip initialization failed\n");
- goto fail;
+ return ret;
}
/* Remove warning texts when you implement new cell drivers */
@@ -187,16 +187,8 @@ static int tps6105x_probe(struct i2c_client *client,
tps6105x_cells[i].pdata_size = sizeof(*tps6105x);
}
- ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
- ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);
- if (ret)
- goto fail;
-
- return 0;
-
-fail:
- kfree(tps6105x);
- return ret;
+ return mfd_add_devices(&client->dev, 0, tps6105x_cells,
+ ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL);
}
static int tps6105x_remove(struct i2c_client *client)
@@ -210,7 +202,6 @@ static int tps6105x_remove(struct i2c_client *client)
TPS6105X_REG0_MODE_MASK,
TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
- kfree(tps6105x);
return 0;
}
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index f9e42ea1cb1a..f243e75d28f3 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -387,7 +387,7 @@ static const struct of_device_id tps65910_of_match[] = {
MODULE_DEVICE_TABLE(of, tps65910_of_match);
static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
- int *chip_id)
+ unsigned long *chip_id)
{
struct device_node *np = client->dev.of_node;
struct tps65910_board *board_info;
@@ -401,7 +401,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
return NULL;
}
- *chip_id = (int)match->data;
+ *chip_id = (unsigned long)match->data;
board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
GFP_KERNEL);
@@ -431,7 +431,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
#else
static inline
struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
- int *chip_id)
+ unsigned long *chip_id)
{
return NULL;
}
@@ -453,14 +453,14 @@ static void tps65910_power_off(void)
}
static int tps65910_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct tps65910 *tps65910;
struct tps65910_board *pmic_plat_data;
struct tps65910_board *of_pmic_plat_data = NULL;
struct tps65910_platform_data *init_data;
+ unsigned long chip_id = id->driver_data;
int ret = 0;
- int chip_id = id->driver_data;
pmic_plat_data = dev_get_platdata(&i2c->dev);
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index 69a5178bf152..de60ad98bd9f 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -32,10 +32,9 @@ static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr,
unsigned long spi_data = 1 << 23 | addr << 15 | *data;
struct spi_transfer xfer;
struct spi_message msg;
- u32 tx_buf, rx_buf;
+ u32 tx_buf;
tx_buf = spi_data;
- rx_buf = 0;
xfer.tx_buf = &tx_buf;
xfer.rx_buf = NULL;
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 596b1f657e21..b1dabba763cf 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -297,7 +297,7 @@ static irqreturn_t handle_twl4030_pih(int irq, void *devid)
ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr,
REG_PIH_ISR_P1);
if (ret) {
- pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret);
+ pr_warn("twl4030: I2C error %d reading PIH ISR\n", ret);
return IRQ_NONE;
}
@@ -338,7 +338,7 @@ static int twl4030_init_sih_modules(unsigned line)
irq_line = line;
/* disable all interrupts on our line */
- memset(buf, 0xff, sizeof buf);
+ memset(buf, 0xff, sizeof(buf));
sih = sih_modules;
for (i = 0; i < nr_sih_modules; i++, sih++) {
/* skip USB -- it's funky */
@@ -646,7 +646,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
if (status < 0)
return status;
- agent = kzalloc(sizeof *agent, GFP_KERNEL);
+ agent = kzalloc(sizeof(*agent), GFP_KERNEL);
if (!agent)
return -ENOMEM;
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index a6bb17d908b8..2807e1a95663 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -70,7 +70,7 @@ static int twl6030_interrupt_mapping[24] = {
BATDETECT_INTR_OFFSET, /* Bit 9 BAT */
SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */
MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */
- RSV_INTR_OFFSET, /* Bit 12 Reserved */
+ RSV_INTR_OFFSET, /* Bit 12 Reserved */
MADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */
MADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */
GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */
@@ -245,6 +245,7 @@ int twl6030_interrupt_unmask(u8 bit_mask, u8 offset)
{
int ret;
u8 unmask_value;
+
ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value,
REG_INT_STS_A + offset);
unmask_value &= (~(bit_mask));
@@ -258,6 +259,7 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset)
{
int ret;
u8 mask_value;
+
ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value,
REG_INT_STS_A + offset);
mask_value |= (bit_mask);
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index ae26d84b3a59..f9c06c542a41 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -700,7 +700,7 @@ static int twl6040_probe(struct i2c_client *client,
}
ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT,
- 0, &twl6040_irq_chip,&twl6040->irq_data);
+ 0, &twl6040_irq_chip, &twl6040->irq_data);
if (ret < 0)
goto gpio_err;
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index c8a993bd17ae..fb4d4bb0f47d 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -138,11 +138,11 @@ static const struct regmap_irq wm5102_irqs[ARIZONA_NUM_IRQ] = {
.reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1
},
- [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1
},
- [ARIZONA_IRQ_SPK_SHUTDOWN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1
},
[ARIZONA_IRQ_HPDET] = {
.reg_offset = 2, .mask = ARIZONA_HPDET_EINT1
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index 41a7f6fb7802..9b98ee559188 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -340,11 +340,11 @@ static const struct regmap_irq wm5110_irqs[ARIZONA_NUM_IRQ] = {
.reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1
},
- [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1
},
- [ARIZONA_IRQ_SPK_SHUTDOWN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1
},
[ARIZONA_IRQ_HPDET] = {
.reg_offset = 2, .mask = ARIZONA_HPDET_EINT1
@@ -416,16 +416,28 @@ static const struct regmap_irq wm5110_irqs[ARIZONA_NUM_IRQ] = {
[ARIZONA_IRQ_ISRC2_CFG_ERR] = {
.reg_offset = 3, .mask = ARIZONA_ISRC2_CFG_ERR_EINT1
},
+ [ARIZONA_IRQ_HP3R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP3R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP3L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP3L_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP2R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP2R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP2L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP2L_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP1R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP1R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP1L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP1L_DONE_EINT1
+ },
[ARIZONA_IRQ_BOOT_DONE] = {
.reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1
},
- [ARIZONA_IRQ_DCS_DAC_DONE] = {
- .reg_offset = 4, .mask = ARIZONA_DCS_DAC_DONE_EINT1
- },
- [ARIZONA_IRQ_DCS_HP_DONE] = {
- .reg_offset = 4, .mask = ARIZONA_DCS_HP_DONE_EINT1
- },
[ARIZONA_IRQ_FLL2_CLOCK_OK] = {
.reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1
},
@@ -445,6 +457,209 @@ const struct regmap_irq_chip wm5110_irq = {
};
EXPORT_SYMBOL_GPL(wm5110_irq);
+static const struct regmap_irq wm5110_revd_irqs[ARIZONA_NUM_IRQ] = {
+ [ARIZONA_IRQ_GP4] = { .reg_offset = 0, .mask = ARIZONA_GP4_EINT1 },
+ [ARIZONA_IRQ_GP3] = { .reg_offset = 0, .mask = ARIZONA_GP3_EINT1 },
+ [ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 },
+ [ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 },
+
+ [ARIZONA_IRQ_DSP4_RAM_RDY] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP4_RAM_RDY_EINT1
+ },
+ [ARIZONA_IRQ_DSP3_RAM_RDY] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP3_RAM_RDY_EINT1
+ },
+ [ARIZONA_IRQ_DSP2_RAM_RDY] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP2_RAM_RDY_EINT1
+ },
+ [ARIZONA_IRQ_DSP1_RAM_RDY] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP1_RAM_RDY_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ8] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ8_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ7] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ7_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ6] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ6_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ5] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ5_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ4] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ4_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ3] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ3_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ2] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ2_EINT1
+ },
+ [ARIZONA_IRQ_DSP_IRQ1] = {
+ .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1
+ },
+
+ [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1
+ },
+ [ARIZONA_IRQ_SPK_OVERHEAT] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1
+ },
+ [ARIZONA_IRQ_HPDET] = {
+ .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1
+ },
+ [ARIZONA_IRQ_MICDET] = {
+ .reg_offset = 2, .mask = ARIZONA_MICDET_EINT1
+ },
+ [ARIZONA_IRQ_WSEQ_DONE] = {
+ .reg_offset = 2, .mask = ARIZONA_WSEQ_DONE_EINT1
+ },
+ [ARIZONA_IRQ_DRC2_SIG_DET] = {
+ .reg_offset = 2, .mask = ARIZONA_DRC2_SIG_DET_EINT1
+ },
+ [ARIZONA_IRQ_DRC1_SIG_DET] = {
+ .reg_offset = 2, .mask = ARIZONA_DRC1_SIG_DET_EINT1
+ },
+ [ARIZONA_IRQ_ASRC2_LOCK] = {
+ .reg_offset = 2, .mask = ARIZONA_ASRC2_LOCK_EINT1
+ },
+ [ARIZONA_IRQ_ASRC1_LOCK] = {
+ .reg_offset = 2, .mask = ARIZONA_ASRC1_LOCK_EINT1
+ },
+ [ARIZONA_IRQ_UNDERCLOCKED] = {
+ .reg_offset = 2, .mask = ARIZONA_UNDERCLOCKED_EINT1
+ },
+ [ARIZONA_IRQ_OVERCLOCKED] = {
+ .reg_offset = 2, .mask = ARIZONA_OVERCLOCKED_EINT1
+ },
+ [ARIZONA_IRQ_FLL2_LOCK] = {
+ .reg_offset = 2, .mask = ARIZONA_FLL2_LOCK_EINT1
+ },
+ [ARIZONA_IRQ_FLL1_LOCK] = {
+ .reg_offset = 2, .mask = ARIZONA_FLL1_LOCK_EINT1
+ },
+ [ARIZONA_IRQ_CLKGEN_ERR] = {
+ .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_EINT1
+ },
+ [ARIZONA_IRQ_CLKGEN_ERR_ASYNC] = {
+ .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_ASYNC_EINT1
+ },
+
+ [ARIZONA_IRQ_CTRLIF_ERR] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_CTRLIF_ERR_EINT1
+ },
+ [ARIZONA_IRQ_MIXER_DROPPED_SAMPLES] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_MIXER_DROPPED_SAMPLE_EINT1
+ },
+ [ARIZONA_IRQ_ASYNC_CLK_ENA_LOW] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_ASYNC_CLK_ENA_LOW_EINT1
+ },
+ [ARIZONA_IRQ_SYSCLK_ENA_LOW] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_SYSCLK_ENA_LOW_EINT1
+ },
+ [ARIZONA_IRQ_ISRC1_CFG_ERR] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_ISRC1_CFG_ERR_EINT1
+ },
+ [ARIZONA_IRQ_ISRC2_CFG_ERR] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_ISRC2_CFG_ERR_EINT1
+ },
+ [ARIZONA_IRQ_ISRC3_CFG_ERR] = {
+ .reg_offset = 3, .mask = ARIZONA_V2_ISRC3_CFG_ERR_EINT1
+ },
+ [ARIZONA_IRQ_HP3R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP3R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP3L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP3L_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP2R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP2R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP2L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP2L_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP1R_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP1R_DONE_EINT1
+ },
+ [ARIZONA_IRQ_HP1L_DONE] = {
+ .reg_offset = 3, .mask = ARIZONA_HP1L_DONE_EINT1
+ },
+
+ [ARIZONA_IRQ_BOOT_DONE] = {
+ .reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1
+ },
+ [ARIZONA_IRQ_ASRC_CFG_ERR] = {
+ .reg_offset = 4, .mask = ARIZONA_V2_ASRC_CFG_ERR_EINT1
+ },
+ [ARIZONA_IRQ_FLL2_CLOCK_OK] = {
+ .reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1
+ },
+ [ARIZONA_IRQ_FLL1_CLOCK_OK] = {
+ .reg_offset = 4, .mask = ARIZONA_FLL1_CLOCK_OK_EINT1
+ },
+
+ [ARIZONA_IRQ_DSP_SHARED_WR_COLL] = {
+ .reg_offset = 5, .mask = ARIZONA_DSP_SHARED_WR_COLL_EINT1
+ },
+ [ARIZONA_IRQ_SPK_SHUTDOWN] = {
+ .reg_offset = 5, .mask = ARIZONA_SPK_SHUTDOWN_EINT1
+ },
+ [ARIZONA_IRQ_SPK1R_SHORT] = {
+ .reg_offset = 5, .mask = ARIZONA_SPK1R_SHORT_EINT1
+ },
+ [ARIZONA_IRQ_SPK1L_SHORT] = {
+ .reg_offset = 5, .mask = ARIZONA_SPK1L_SHORT_EINT1
+ },
+ [ARIZONA_IRQ_HP3R_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP3R_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP3R_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP3R_SC_POS_EINT1
+ },
+ [ARIZONA_IRQ_HP3L_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP3L_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP3L_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP3L_SC_POS_EINT1
+ },
+ [ARIZONA_IRQ_HP2R_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP2R_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP2R_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP2R_SC_POS_EINT1
+ },
+ [ARIZONA_IRQ_HP2L_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP2L_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP2L_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP2L_SC_POS_EINT1
+ },
+ [ARIZONA_IRQ_HP1R_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP1R_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP1R_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP1R_SC_POS_EINT1
+ },
+ [ARIZONA_IRQ_HP1L_SC_NEG] = {
+ .reg_offset = 5, .mask = ARIZONA_HP1L_SC_NEG_EINT1
+ },
+ [ARIZONA_IRQ_HP1L_SC_POS] = {
+ .reg_offset = 5, .mask = ARIZONA_HP1L_SC_POS_EINT1
+ },
+};
+
+const struct regmap_irq_chip wm5110_revd_irq = {
+ .name = "wm5110 IRQ",
+ .status_base = ARIZONA_INTERRUPT_STATUS_1,
+ .mask_base = ARIZONA_INTERRUPT_STATUS_1_MASK,
+ .ack_base = ARIZONA_INTERRUPT_STATUS_1,
+ .num_regs = 6,
+ .irqs = wm5110_revd_irqs,
+ .num_irqs = ARRAY_SIZE(wm5110_revd_irqs),
+};
+EXPORT_SYMBOL_GPL(wm5110_revd_irq);
+
static const struct reg_default wm5110_reg_default[] = {
{ 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */
{ 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */
@@ -1274,12 +1489,14 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */
{ 0x00000D0B, 0xFFFF }, /* R3339 - Interrupt Status 4 Mask */
{ 0x00000D0C, 0xFEFF }, /* R3340 - Interrupt Status 5 Mask */
+ { 0x00000D0D, 0xFFFF }, /* R3341 - Interrupt Status 6 Mask */
{ 0x00000D0F, 0x0000 }, /* R3343 - Interrupt Control */
{ 0x00000D18, 0xFFFF }, /* R3352 - IRQ2 Status 1 Mask */
{ 0x00000D19, 0xFFFF }, /* R3353 - IRQ2 Status 2 Mask */
{ 0x00000D1A, 0xFFFF }, /* R3354 - IRQ2 Status 3 Mask */
{ 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */
{ 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */
+ { 0x00000D1D, 0xFFFF }, /* R3357 - IRQ2 Status 6 Mask */
{ 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */
{ 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */
{ 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */
@@ -2311,22 +2528,26 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_INTERRUPT_STATUS_3:
case ARIZONA_INTERRUPT_STATUS_4:
case ARIZONA_INTERRUPT_STATUS_5:
+ case ARIZONA_INTERRUPT_STATUS_6:
case ARIZONA_INTERRUPT_STATUS_1_MASK:
case ARIZONA_INTERRUPT_STATUS_2_MASK:
case ARIZONA_INTERRUPT_STATUS_3_MASK:
case ARIZONA_INTERRUPT_STATUS_4_MASK:
case ARIZONA_INTERRUPT_STATUS_5_MASK:
+ case ARIZONA_INTERRUPT_STATUS_6_MASK:
case ARIZONA_INTERRUPT_CONTROL:
case ARIZONA_IRQ2_STATUS_1:
case ARIZONA_IRQ2_STATUS_2:
case ARIZONA_IRQ2_STATUS_3:
case ARIZONA_IRQ2_STATUS_4:
case ARIZONA_IRQ2_STATUS_5:
+ case ARIZONA_IRQ2_STATUS_6:
case ARIZONA_IRQ2_STATUS_1_MASK:
case ARIZONA_IRQ2_STATUS_2_MASK:
case ARIZONA_IRQ2_STATUS_3_MASK:
case ARIZONA_IRQ2_STATUS_4_MASK:
case ARIZONA_IRQ2_STATUS_5_MASK:
+ case ARIZONA_IRQ2_STATUS_6_MASK:
case ARIZONA_IRQ2_CONTROL:
case ARIZONA_INTERRUPT_RAW_STATUS_2:
case ARIZONA_INTERRUPT_RAW_STATUS_3:
@@ -2335,6 +2556,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_INTERRUPT_RAW_STATUS_6:
case ARIZONA_INTERRUPT_RAW_STATUS_7:
case ARIZONA_INTERRUPT_RAW_STATUS_8:
+ case ARIZONA_INTERRUPT_RAW_STATUS_9:
case ARIZONA_IRQ_PIN_STATUS:
case ARIZONA_AOD_WKUP_AND_TRIG:
case ARIZONA_AOD_IRQ1:
@@ -2610,11 +2832,13 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_INTERRUPT_STATUS_3:
case ARIZONA_INTERRUPT_STATUS_4:
case ARIZONA_INTERRUPT_STATUS_5:
+ case ARIZONA_INTERRUPT_STATUS_6:
case ARIZONA_IRQ2_STATUS_1:
case ARIZONA_IRQ2_STATUS_2:
case ARIZONA_IRQ2_STATUS_3:
case ARIZONA_IRQ2_STATUS_4:
case ARIZONA_IRQ2_STATUS_5:
+ case ARIZONA_IRQ2_STATUS_6:
case ARIZONA_INTERRUPT_RAW_STATUS_2:
case ARIZONA_INTERRUPT_RAW_STATUS_3:
case ARIZONA_INTERRUPT_RAW_STATUS_4:
@@ -2622,6 +2846,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_INTERRUPT_RAW_STATUS_6:
case ARIZONA_INTERRUPT_RAW_STATUS_7:
case ARIZONA_INTERRUPT_RAW_STATUS_8:
+ case ARIZONA_INTERRUPT_RAW_STATUS_9:
case ARIZONA_IRQ_PIN_STATUS:
case ARIZONA_AOD_WKUP_AND_TRIG:
case ARIZONA_AOD_IRQ1:
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index f919def05e24..6a16a8a6f9fa 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -58,10 +58,10 @@ static int wm8350_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id wm8350_i2c_id[] = {
- { "wm8350", 0 },
- { "wm8351", 0 },
- { "wm8352", 0 },
- { }
+ { "wm8350", 0 },
+ { "wm8351", 0 },
+ { "wm8352", 0 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id);
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index cd01f7962dfd..813ff50f95b6 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -497,7 +497,8 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
if (pdata && pdata->irq_base > 0)
irq_base = pdata->irq_base;
- wm8350->irq_base = irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
+ wm8350->irq_base =
+ irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
if (wm8350->irq_base < 0) {
dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
wm8350->irq_base);
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index 2fbce9c5950b..770a25696468 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -123,14 +123,23 @@ static struct reg_default wm1811_defaults[] = {
{ 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */
{ 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */
{ 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
+ { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
{ 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */
{ 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */
+ { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */
+ { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */
{ 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */
+ { 0x0431, 0x0068 }, /* R1073 - AIF1 DAC2 Noise Gate */
{ 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */
{ 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */
{ 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
{ 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
{ 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
+ { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */
+ { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */
+ { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
+ { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
+ { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
{ 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
{ 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
{ 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
@@ -152,6 +161,27 @@ static struct reg_default wm1811_defaults[] = {
{ 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
{ 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
{ 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */
+ { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
+ { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
+ { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
+ { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
+ { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
+ { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
+ { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
+ { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
+ { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
+ { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
+ { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
+ { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
+ { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
+ { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
+ { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
+ { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
+ { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
+ { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
+ { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
+ { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
+ { 0x04B4, 0x0000 }, /* R1204 - AIF1 DAC2 EQ Band 1 C */
{ 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */
{ 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */
{ 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */
@@ -194,6 +224,8 @@ static struct reg_default wm1811_defaults[] = {
{ 0x0605, 0x0000 }, /* R1541 - AIF2ADC Right Mixer Routing */
{ 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
{ 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
+ { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
+ { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right Mixer Routing */
{ 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */
{ 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */
{ 0x0612, 0x02C0 }, /* R1554 - AIF2TX Left Volume */
@@ -846,14 +878,23 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg)
case WM8994_AIF1_DAC1_LEFT_VOLUME:
case WM8994_AIF1_DAC1_RIGHT_VOLUME:
case WM8994_AIF1_ADC1_FILTERS:
+ case WM8994_AIF1_ADC2_FILTERS:
case WM8994_AIF1_DAC1_FILTERS_1:
case WM8994_AIF1_DAC1_FILTERS_2:
+ case WM8994_AIF1_DAC2_FILTERS_1:
+ case WM8994_AIF1_DAC2_FILTERS_2:
case WM8958_AIF1_DAC1_NOISE_GATE:
+ case WM8958_AIF1_DAC2_NOISE_GATE:
case WM8994_AIF1_DRC1_1:
case WM8994_AIF1_DRC1_2:
case WM8994_AIF1_DRC1_3:
case WM8994_AIF1_DRC1_4:
case WM8994_AIF1_DRC1_5:
+ case WM8994_AIF1_DRC2_1:
+ case WM8994_AIF1_DRC2_2:
+ case WM8994_AIF1_DRC2_3:
+ case WM8994_AIF1_DRC2_4:
+ case WM8994_AIF1_DRC2_5:
case WM8994_AIF1_DAC1_EQ_GAINS_1:
case WM8994_AIF1_DAC1_EQ_GAINS_2:
case WM8994_AIF1_DAC1_EQ_BAND_1_A:
@@ -875,6 +916,27 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg)
case WM8994_AIF1_DAC1_EQ_BAND_5_B:
case WM8994_AIF1_DAC1_EQ_BAND_5_PG:
case WM8994_AIF1_DAC1_EQ_BAND_1_C:
+ case WM8994_AIF1_DAC2_EQ_GAINS_1:
+ case WM8994_AIF1_DAC2_EQ_GAINS_2:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_2_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_3_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_C:
+ case WM8994_AIF1_DAC2_EQ_BAND_4_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_A:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_B:
+ case WM8994_AIF1_DAC2_EQ_BAND_5_PG:
+ case WM8994_AIF1_DAC2_EQ_BAND_1_C:
case WM8994_AIF2_ADC_LEFT_VOLUME:
case WM8994_AIF2_ADC_RIGHT_VOLUME:
case WM8994_AIF2_DAC_LEFT_VOLUME:
@@ -917,6 +979,8 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg)
case WM8994_DAC2_RIGHT_MIXER_ROUTING:
case WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING:
case WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING:
+ case WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING:
case WM8994_DAC1_LEFT_VOLUME:
case WM8994_DAC1_RIGHT_VOLUME:
case WM8994_DAC2_LEFT_VOLUME:
diff --git a/drivers/mfd/wm8997-tables.c b/drivers/mfd/wm8997-tables.c
index c7a81da64ee1..510da3b52324 100644
--- a/drivers/mfd/wm8997-tables.c
+++ b/drivers/mfd/wm8997-tables.c
@@ -65,11 +65,11 @@ static const struct regmap_irq wm8997_irqs[ARIZONA_NUM_IRQ] = {
[ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 },
[ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 },
- [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1
},
- [ARIZONA_IRQ_SPK_SHUTDOWN] = {
- .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1
+ [ARIZONA_IRQ_SPK_OVERHEAT] = {
+ .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1
},
[ARIZONA_IRQ_HPDET] = {
.reg_offset = 2, .mask = ARIZONA_HPDET_EINT1
@@ -174,10 +174,10 @@ static const struct reg_default wm8997_reg_default[] = {
{ 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */
{ 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */
{ 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */
- { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 3 */
- { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */
- { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */
- { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */
+ { 0x00000068, 0x01FF }, /* R104 - AlwaysOn Triggers Seq Select 3 */
+ { 0x00000069, 0x01FF }, /* R105 - AlwaysOn Triggers Seq Select 4 */
+ { 0x0000006A, 0x01FF }, /* R106 - AlwaysOn Triggers Seq Select 5 */
+ { 0x0000006B, 0x01FF }, /* R107 - AlwaysOn Triggers Seq Select 6 */
{ 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */
{ 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */
{ 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index 22de13727641..60843a275abd 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -83,10 +83,17 @@ EXPORT_SYMBOL(ssc_free);
static struct atmel_ssc_platform_data at91rm9200_config = {
.use_dma = 0,
+ .has_fslen_ext = 0,
+};
+
+static struct atmel_ssc_platform_data at91sam9rl_config = {
+ .use_dma = 0,
+ .has_fslen_ext = 1,
};
static struct atmel_ssc_platform_data at91sam9g45_config = {
.use_dma = 1,
+ .has_fslen_ext = 1,
};
static const struct platform_device_id atmel_ssc_devtypes[] = {
@@ -94,6 +101,9 @@ static const struct platform_device_id atmel_ssc_devtypes[] = {
.name = "at91rm9200_ssc",
.driver_data = (unsigned long) &at91rm9200_config,
}, {
+ .name = "at91sam9rl_ssc",
+ .driver_data = (unsigned long) &at91sam9rl_config,
+ }, {
.name = "at91sam9g45_ssc",
.driver_data = (unsigned long) &at91sam9g45_config,
}, {
@@ -107,6 +117,9 @@ static const struct of_device_id atmel_ssc_dt_ids[] = {
.compatible = "atmel,at91rm9200-ssc",
.data = &at91rm9200_config,
}, {
+ .compatible = "atmel,at91sam9rl-ssc",
+ .data = &at91sam9rl_config,
+ }, {
.compatible = "atmel,at91sam9g45-ssc",
.data = &at91sam9g45_config,
}, {
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index 99a04686e45f..7b55f8a152d4 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -1185,7 +1185,7 @@ static int bh1770_probe(struct i2c_client *client,
struct bh1770_chip *chip;
int err;
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
+ chip = devm_kzalloc(&client->dev, sizeof *chip, GFP_KERNEL);
if (!chip)
return -ENOMEM;
@@ -1198,8 +1198,7 @@ static int bh1770_probe(struct i2c_client *client,
if (client->dev.platform_data == NULL) {
dev_err(&client->dev, "platform data is mandatory\n");
- err = -EINVAL;
- goto fail1;
+ return -EINVAL;
}
chip->pdata = client->dev.platform_data;
@@ -1224,24 +1223,24 @@ static int bh1770_probe(struct i2c_client *client,
chip->regs[0].supply = reg_vcc;
chip->regs[1].supply = reg_vleds;
- err = regulator_bulk_get(&client->dev,
- ARRAY_SIZE(chip->regs), chip->regs);
+ err = devm_regulator_bulk_get(&client->dev,
+ ARRAY_SIZE(chip->regs), chip->regs);
if (err < 0) {
dev_err(&client->dev, "Cannot get regulators\n");
- goto fail1;
+ return err;
}
err = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
chip->regs);
if (err < 0) {
dev_err(&client->dev, "Cannot enable regulators\n");
- goto fail2;
+ return err;
}
usleep_range(BH1770_STARTUP_DELAY, BH1770_STARTUP_DELAY * 2);
err = bh1770_detect(chip);
if (err < 0)
- goto fail3;
+ goto fail0;
/* Start chip */
bh1770_chip_on(chip);
@@ -1252,14 +1251,14 @@ static int bh1770_probe(struct i2c_client *client,
if (chip->lux_corr == 0) {
dev_err(&client->dev, "Improper correction values\n");
err = -EINVAL;
- goto fail3;
+ goto fail0;
}
if (chip->pdata->setup_resources) {
err = chip->pdata->setup_resources();
if (err) {
err = -EINVAL;
- goto fail3;
+ goto fail0;
}
}
@@ -1267,7 +1266,7 @@ static int bh1770_probe(struct i2c_client *client,
&bh1770_attribute_group);
if (err < 0) {
dev_err(&chip->client->dev, "Sysfs registration failed\n");
- goto fail4;
+ goto fail1;
}
/*
@@ -1283,22 +1282,18 @@ static int bh1770_probe(struct i2c_client *client,
if (err) {
dev_err(&client->dev, "could not get IRQ %d\n",
client->irq);
- goto fail5;
+ goto fail2;
}
regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
return err;
-fail5:
+fail2:
sysfs_remove_group(&chip->client->dev.kobj,
&bh1770_attribute_group);
-fail4:
+fail1:
if (chip->pdata->release_resources)
chip->pdata->release_resources();
-fail3:
+fail0:
regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
-fail2:
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
-fail1:
- kfree(chip);
return err;
}
@@ -1322,8 +1317,6 @@ static int bh1770_remove(struct i2c_client *client)
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
- kfree(chip);
return 0;
}
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index 48ea33d15a79..4c4a59b25537 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -149,50 +149,35 @@ static int bh1780_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
- struct bh1780_data *ddata = NULL;
+ struct bh1780_data *ddata;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
- ret = -EIO;
- goto err_op_failed;
- }
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
- ddata = kzalloc(sizeof(struct bh1780_data), GFP_KERNEL);
- if (ddata == NULL) {
- ret = -ENOMEM;
- goto err_op_failed;
- }
+ ddata = devm_kzalloc(&client->dev, sizeof(struct bh1780_data),
+ GFP_KERNEL);
+ if (ddata == NULL)
+ return -ENOMEM;
ddata->client = client;
i2c_set_clientdata(client, ddata);
ret = bh1780_read(ddata, BH1780_REG_PARTID, "PART ID");
if (ret < 0)
- goto err_op_failed;
+ return ret;
dev_info(&client->dev, "Ambient Light Sensor, Rev : %d\n",
(ret & BH1780_REVMASK));
mutex_init(&ddata->lock);
- ret = sysfs_create_group(&client->dev.kobj, &bh1780_attr_group);
- if (ret)
- goto err_op_failed;
-
- return 0;
-
-err_op_failed:
- kfree(ddata);
- return ret;
+ return sysfs_create_group(&client->dev.kobj, &bh1780_attr_group);
}
static int bh1780_remove(struct i2c_client *client)
{
- struct bh1780_data *ddata;
-
- ddata = i2c_get_clientdata(client);
sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group);
- kfree(ddata);
return 0;
}
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 14d90eae605b..55e913b7eb11 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -954,10 +954,7 @@ static int data_debugfs_init(struct fpga_device *priv)
{
priv->dbg_entry = debugfs_create_file(drv_name, S_IRUGO, NULL, priv,
&data_debug_fops);
- if (IS_ERR(priv->dbg_entry))
- return PTR_ERR(priv->dbg_entry);
-
- return 0;
+ return PTR_ERR_OR_ZERO(priv->dbg_entry);
}
static void data_debugfs_exit(struct fpga_device *priv)
diff --git a/drivers/misc/dummy-irq.c b/drivers/misc/dummy-irq.c
index 4d0db15df115..acbbe0390be4 100644
--- a/drivers/misc/dummy-irq.c
+++ b/drivers/misc/dummy-irq.c
@@ -61,3 +61,4 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiri Kosina");
module_param(irq, uint, 0444);
MODULE_PARM_DESC(irq, "The IRQ to register for");
+MODULE_DESCRIPTION("Dummy IRQ handler driver");
diff --git a/drivers/misc/fuse/Makefile b/drivers/misc/fuse/Makefile
new file mode 100644
index 000000000000..0679c4febc89
--- /dev/null
+++ b/drivers/misc/fuse/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/misc/genwqe/Kconfig b/drivers/misc/genwqe/Kconfig
index 6069d8cd79d7..4c0a033cbfdb 100644
--- a/drivers/misc/genwqe/Kconfig
+++ b/drivers/misc/genwqe/Kconfig
@@ -11,3 +11,9 @@ menuconfig GENWQE
Enables PCIe card driver for IBM GenWQE accelerators.
The user-space interface is described in
include/linux/genwqe/genwqe_card.h.
+
+config GENWQE_PLATFORM_ERROR_RECOVERY
+ int "Use platform recovery procedures (0=off, 1=on)"
+ depends on GENWQE
+ default 1 if PPC64
+ default 0
diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c
index 74d51c9bb858..43bbabc96b6c 100644
--- a/drivers/misc/genwqe/card_base.c
+++ b/drivers/misc/genwqe/card_base.c
@@ -38,7 +38,6 @@
#include <linux/notifier.h>
#include <linux/device.h>
#include <linux/log2.h>
-#include <linux/genwqe/genwqe_card.h>
#include "card_base.h"
#include "card_ddcb.h"
@@ -58,7 +57,7 @@ static struct dentry *debugfs_genwqe;
static struct genwqe_dev *genwqe_devices[GENWQE_CARD_NO_MAX];
/* PCI structure for identifying device by PCI vendor and device ID */
-static DEFINE_PCI_DEVICE_TABLE(genwqe_device_table) = {
+static const struct pci_device_id genwqe_device_table[] = {
{ .vendor = PCI_VENDOR_ID_IBM,
.device = PCI_DEVICE_GENWQE,
.subvendor = PCI_SUBVENDOR_ID_IBM,
@@ -140,6 +139,12 @@ static struct genwqe_dev *genwqe_dev_alloc(void)
cd->class_genwqe = class_genwqe;
cd->debugfs_genwqe = debugfs_genwqe;
+ /*
+ * This comes from kernel config option and can be overritten via
+ * debugfs.
+ */
+ cd->use_platform_recovery = CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY;
+
init_waitqueue_head(&cd->queue_waitq);
spin_lock_init(&cd->file_lock);
@@ -761,6 +766,124 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd)
}
/**
+ * genwqe_pci_fundamental_reset() - trigger a PCIe fundamental reset on the slot
+ *
+ * Note: pci_set_pcie_reset_state() is not implemented on all archs, so this
+ * reset method will not work in all cases.
+ *
+ * Return: 0 on success or error code from pci_set_pcie_reset_state()
+ */
+static int genwqe_pci_fundamental_reset(struct pci_dev *pci_dev)
+{
+ int rc;
+
+ /*
+ * lock pci config space access from userspace,
+ * save state and issue PCIe fundamental reset
+ */
+ pci_cfg_access_lock(pci_dev);
+ pci_save_state(pci_dev);
+ rc = pci_set_pcie_reset_state(pci_dev, pcie_warm_reset);
+ if (!rc) {
+ /* keep PCIe reset asserted for 250ms */
+ msleep(250);
+ pci_set_pcie_reset_state(pci_dev, pcie_deassert_reset);
+ /* Wait for 2s to reload flash and train the link */
+ msleep(2000);
+ }
+ pci_restore_state(pci_dev);
+ pci_cfg_access_unlock(pci_dev);
+ return rc;
+}
+
+
+static int genwqe_platform_recovery(struct genwqe_dev *cd)
+{
+ struct pci_dev *pci_dev = cd->pci_dev;
+ int rc;
+
+ dev_info(&pci_dev->dev,
+ "[%s] resetting card for error recovery\n", __func__);
+
+ /* Clear out error injection flags */
+ cd->err_inject &= ~(GENWQE_INJECT_HARDWARE_FAILURE |
+ GENWQE_INJECT_GFIR_FATAL |
+ GENWQE_INJECT_GFIR_INFO);
+
+ genwqe_stop(cd);
+
+ /* Try recoverying the card with fundamental reset */
+ rc = genwqe_pci_fundamental_reset(pci_dev);
+ if (!rc) {
+ rc = genwqe_start(cd);
+ if (!rc)
+ dev_info(&pci_dev->dev,
+ "[%s] card recovered\n", __func__);
+ else
+ dev_err(&pci_dev->dev,
+ "[%s] err: cannot start card services! (err=%d)\n",
+ __func__, rc);
+ } else {
+ dev_err(&pci_dev->dev,
+ "[%s] card reset failed\n", __func__);
+ }
+
+ return rc;
+}
+
+/*
+ * genwqe_reload_bistream() - reload card bitstream
+ *
+ * Set the appropriate register and call fundamental reset to reaload the card
+ * bitstream.
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static int genwqe_reload_bistream(struct genwqe_dev *cd)
+{
+ struct pci_dev *pci_dev = cd->pci_dev;
+ int rc;
+
+ dev_info(&pci_dev->dev,
+ "[%s] resetting card for bitstream reload\n",
+ __func__);
+
+ genwqe_stop(cd);
+
+ /*
+ * Cause a CPLD reprogram with the 'next_bitstream'
+ * partition on PCIe hot or fundamental reset
+ */
+ __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET,
+ (cd->softreset & 0xcull) | 0x70ull);
+
+ rc = genwqe_pci_fundamental_reset(pci_dev);
+ if (rc) {
+ /*
+ * A fundamental reset failure can be caused
+ * by lack of support on the arch, so we just
+ * log the error and try to start the card
+ * again.
+ */
+ dev_err(&pci_dev->dev,
+ "[%s] err: failed to reset card for bitstream reload\n",
+ __func__);
+ }
+
+ rc = genwqe_start(cd);
+ if (rc) {
+ dev_err(&pci_dev->dev,
+ "[%s] err: cannot start card services! (err=%d)\n",
+ __func__, rc);
+ return rc;
+ }
+ dev_info(&pci_dev->dev,
+ "[%s] card reloaded\n", __func__);
+ return 0;
+}
+
+
+/**
* genwqe_health_thread() - Health checking thread
*
* This thread is only started for the PF of the card.
@@ -786,6 +909,7 @@ static int genwqe_health_thread(void *data)
struct pci_dev *pci_dev = cd->pci_dev;
u64 gfir, gfir_masked, slu_unitcfg, app_unitcfg;
+ health_thread_begin:
while (!kthread_should_stop()) {
rc = wait_event_interruptible_timeout(cd->health_waitq,
(genwqe_health_check_cond(cd, &gfir) ||
@@ -846,6 +970,13 @@ static int genwqe_health_thread(void *data)
}
}
+ if (cd->card_state == GENWQE_CARD_RELOAD_BITSTREAM) {
+ /* Userspace requested card bitstream reload */
+ rc = genwqe_reload_bistream(cd);
+ if (rc)
+ goto fatal_error;
+ }
+
cd->last_gfir = gfir;
cond_resched();
}
@@ -853,6 +984,28 @@ static int genwqe_health_thread(void *data)
return 0;
fatal_error:
+ if (cd->use_platform_recovery) {
+ /*
+ * Since we use raw accessors, EEH errors won't be detected
+ * by the platform until we do a non-raw MMIO or config space
+ * read
+ */
+ readq(cd->mmio + IO_SLC_CFGREG_GFIR);
+
+ /* We do nothing if the card is going over PCI recovery */
+ if (pci_channel_offline(pci_dev))
+ return -EIO;
+
+ /*
+ * If it's supported by the platform, we try a fundamental reset
+ * to recover from a fatal error. Otherwise, we continue to wait
+ * for an external recovery procedure to take care of it.
+ */
+ rc = genwqe_platform_recovery(cd);
+ if (!rc)
+ goto health_thread_begin;
+ }
+
dev_err(&pci_dev->dev,
"[%s] card unusable. Please trigger unbind!\n", __func__);
@@ -958,6 +1111,9 @@ static int genwqe_pci_setup(struct genwqe_dev *cd)
pci_set_master(pci_dev);
pci_enable_pcie_error_reporting(pci_dev);
+ /* EEH recovery requires PCIe fundamental reset */
+ pci_dev->needs_freset = 1;
+
/* request complete BAR-0 space (length = 0) */
cd->mmio_len = pci_resource_len(pci_dev, 0);
cd->mmio = pci_iomap(pci_dev, 0, 0);
@@ -1096,23 +1252,40 @@ static pci_ers_result_t genwqe_err_error_detected(struct pci_dev *pci_dev,
dev_err(&pci_dev->dev, "[%s] state=%d\n", __func__, state);
- if (pci_dev == NULL)
- return PCI_ERS_RESULT_NEED_RESET;
-
cd = dev_get_drvdata(&pci_dev->dev);
if (cd == NULL)
- return PCI_ERS_RESULT_NEED_RESET;
+ return PCI_ERS_RESULT_DISCONNECT;
- switch (state) {
- case pci_channel_io_normal:
- return PCI_ERS_RESULT_CAN_RECOVER;
- case pci_channel_io_frozen:
- return PCI_ERS_RESULT_NEED_RESET;
- case pci_channel_io_perm_failure:
+ /* Stop the card */
+ genwqe_health_check_stop(cd);
+ genwqe_stop(cd);
+
+ /*
+ * On permanent failure, the PCI code will call device remove
+ * after the return of this function.
+ * genwqe_stop() can be called twice.
+ */
+ if (state == pci_channel_io_perm_failure) {
return PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ genwqe_pci_remove(cd);
+ return PCI_ERS_RESULT_NEED_RESET;
}
+}
+
+static pci_ers_result_t genwqe_err_slot_reset(struct pci_dev *pci_dev)
+{
+ int rc;
+ struct genwqe_dev *cd = dev_get_drvdata(&pci_dev->dev);
- return PCI_ERS_RESULT_NEED_RESET;
+ rc = genwqe_pci_setup(cd);
+ if (!rc) {
+ return PCI_ERS_RESULT_RECOVERED;
+ } else {
+ dev_err(&pci_dev->dev,
+ "err: problems with PCI setup (err=%d)\n", rc);
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
}
static pci_ers_result_t genwqe_err_result_none(struct pci_dev *dev)
@@ -1120,8 +1293,22 @@ static pci_ers_result_t genwqe_err_result_none(struct pci_dev *dev)
return PCI_ERS_RESULT_NONE;
}
-static void genwqe_err_resume(struct pci_dev *dev)
+static void genwqe_err_resume(struct pci_dev *pci_dev)
{
+ int rc;
+ struct genwqe_dev *cd = dev_get_drvdata(&pci_dev->dev);
+
+ rc = genwqe_start(cd);
+ if (!rc) {
+ rc = genwqe_health_check_start(cd);
+ if (rc)
+ dev_err(&pci_dev->dev,
+ "err: cannot start health checking! (err=%d)\n",
+ rc);
+ } else {
+ dev_err(&pci_dev->dev,
+ "err: cannot start card services! (err=%d)\n", rc);
+ }
}
static int genwqe_sriov_configure(struct pci_dev *dev, int numvfs)
@@ -1144,7 +1331,7 @@ static struct pci_error_handlers genwqe_err_handler = {
.error_detected = genwqe_err_error_detected,
.mmio_enabled = genwqe_err_result_none,
.link_reset = genwqe_err_result_none,
- .slot_reset = genwqe_err_result_none,
+ .slot_reset = genwqe_err_slot_reset,
.resume = genwqe_err_resume,
};
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
index 0e608a288603..67abd8cb2247 100644
--- a/drivers/misc/genwqe/card_base.h
+++ b/drivers/misc/genwqe/card_base.h
@@ -291,6 +291,8 @@ struct genwqe_dev {
struct task_struct *health_thread;
wait_queue_head_t health_waitq;
+ int use_platform_recovery; /* use platform recovery mechanisms */
+
/* char device */
dev_t devnum_genwqe; /* major/minor num card */
struct class *class_genwqe; /* reference to class object */
diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c
index c8046db2d5a2..dc9851a5540e 100644
--- a/drivers/misc/genwqe/card_ddcb.c
+++ b/drivers/misc/genwqe/card_ddcb.c
@@ -1118,7 +1118,21 @@ static irqreturn_t genwqe_pf_isr(int irq, void *dev_id)
* safer, but slower for the good-case ... See above.
*/
gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR);
- if ((gfir & GFIR_ERR_TRIGGER) != 0x0) {
+ if (((gfir & GFIR_ERR_TRIGGER) != 0x0) &&
+ !pci_channel_offline(pci_dev)) {
+
+ if (cd->use_platform_recovery) {
+ /*
+ * Since we use raw accessors, EEH errors won't be
+ * detected by the platform until we do a non-raw
+ * MMIO or config space read
+ */
+ readq(cd->mmio + IO_SLC_CFGREG_GFIR);
+
+ /* Don't do anything if the PCI channel is frozen */
+ if (pci_channel_offline(pci_dev))
+ goto exit;
+ }
wake_up_interruptible(&cd->health_waitq);
@@ -1126,12 +1140,12 @@ static irqreturn_t genwqe_pf_isr(int irq, void *dev_id)
* By default GFIRs causes recovery actions. This
* count is just for debug when recovery is masked.
*/
- printk_ratelimited(KERN_ERR
- "%s %s: [%s] GFIR=%016llx\n",
- GENWQE_DEVNAME, dev_name(&pci_dev->dev),
- __func__, gfir);
+ dev_err_ratelimited(&pci_dev->dev,
+ "[%s] GFIR=%016llx\n",
+ __func__, gfir);
}
+ exit:
return IRQ_HANDLED;
}
@@ -1237,9 +1251,7 @@ int genwqe_setup_service_layer(struct genwqe_dev *cd)
}
rc = genwqe_set_interrupt_capability(cd, GENWQE_MSI_IRQS);
- if (rc > 0)
- rc = genwqe_set_interrupt_capability(cd, rc);
- if (rc != 0) {
+ if (rc) {
rc = -ENODEV;
goto stop_kthread;
}
diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c
index 0a33ade64109..c9b4d6d0eb99 100644
--- a/drivers/misc/genwqe/card_debugfs.c
+++ b/drivers/misc/genwqe/card_debugfs.c
@@ -485,6 +485,13 @@ int genwqe_init_debugfs(struct genwqe_dev *cd)
goto err1;
}
+ file = debugfs_create_u32("use_platform_recovery", 0666, root,
+ &cd->use_platform_recovery);
+ if (!file) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
cd->debugfs_root = root;
return 0;
err1:
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
index 1d2f163a1906..aae42555e2ca 100644
--- a/drivers/misc/genwqe/card_dev.c
+++ b/drivers/misc/genwqe/card_dev.c
@@ -1048,10 +1048,15 @@ static long genwqe_ioctl(struct file *filp, unsigned int cmd,
int rc = 0;
struct genwqe_file *cfile = (struct genwqe_file *)filp->private_data;
struct genwqe_dev *cd = cfile->cd;
+ struct pci_dev *pci_dev = cd->pci_dev;
struct genwqe_reg_io __user *io;
u64 val;
u32 reg_offs;
+ /* Return -EIO if card hit EEH */
+ if (pci_channel_offline(pci_dev))
+ return -EIO;
+
if (_IOC_TYPE(cmd) != GENWQE_IOC_CODE)
return -EINVAL;
diff --git a/drivers/misc/genwqe/card_sysfs.c b/drivers/misc/genwqe/card_sysfs.c
index a72a99266c3c..7232e40a3ad9 100644
--- a/drivers/misc/genwqe/card_sysfs.c
+++ b/drivers/misc/genwqe/card_sysfs.c
@@ -223,6 +223,30 @@ static ssize_t next_bitstream_store(struct device *dev,
}
static DEVICE_ATTR_RW(next_bitstream);
+static ssize_t reload_bitstream_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int reload;
+ struct genwqe_dev *cd = dev_get_drvdata(dev);
+
+ if (kstrtoint(buf, 0, &reload) < 0)
+ return -EINVAL;
+
+ if (reload == 0x1) {
+ if (cd->card_state == GENWQE_CARD_UNUSED ||
+ cd->card_state == GENWQE_CARD_USED)
+ cd->card_state = GENWQE_CARD_RELOAD_BITSTREAM;
+ else
+ return -EIO;
+ } else {
+ return -EINVAL;
+ }
+
+ return count;
+}
+static DEVICE_ATTR_WO(reload_bitstream);
+
/*
* Create device_attribute structures / params: name, mode, show, store
* additional flag if valid in VF
@@ -239,6 +263,7 @@ static struct attribute *genwqe_attributes[] = {
&dev_attr_status.attr,
&dev_attr_freerunning_timer.attr,
&dev_attr_queue_working_time.attr,
+ &dev_attr_reload_bitstream.attr,
NULL,
};
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 62cc6bb3f62e..a6400f09229c 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -53,12 +53,17 @@
*/
int __genwqe_writeq(struct genwqe_dev *cd, u64 byte_offs, u64 val)
{
+ struct pci_dev *pci_dev = cd->pci_dev;
+
if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
return -EIO;
if (cd->mmio == NULL)
return -EIO;
+ if (pci_channel_offline(pci_dev))
+ return -EIO;
+
__raw_writeq((__force u64)cpu_to_be64(val), cd->mmio + byte_offs);
return 0;
}
@@ -99,12 +104,17 @@ u64 __genwqe_readq(struct genwqe_dev *cd, u64 byte_offs)
*/
int __genwqe_writel(struct genwqe_dev *cd, u64 byte_offs, u32 val)
{
+ struct pci_dev *pci_dev = cd->pci_dev;
+
if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
return -EIO;
if (cd->mmio == NULL)
return -EIO;
+ if (pci_channel_offline(pci_dev))
+ return -EIO;
+
__raw_writel((__force u32)cpu_to_be32(val), cd->mmio + byte_offs);
return 0;
}
@@ -718,10 +728,12 @@ int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count)
int rc;
struct pci_dev *pci_dev = cd->pci_dev;
- rc = pci_enable_msi_exact(pci_dev, count);
- if (rc == 0)
- cd->flags |= GENWQE_FLAG_MSI_ENABLED;
- return rc;
+ rc = pci_enable_msi_range(pci_dev, 1, count);
+ if (rc < 0)
+ return rc;
+
+ cd->flags |= GENWQE_FLAG_MSI_ENABLED;
+ return 0;
}
/**
diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h
index cd5263163a6e..a506e9aa2d57 100644
--- a/drivers/misc/genwqe/genwqe_driver.h
+++ b/drivers/misc/genwqe/genwqe_driver.h
@@ -36,7 +36,7 @@
#include <asm/byteorder.h>
#include <linux/genwqe/genwqe_card.h>
-#define DRV_VERS_STRING "2.0.15"
+#define DRV_VERS_STRING "2.0.21"
/*
* Static minor number assignement, until we decide/implement
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 06f6ad29ceff..3336ddca45ac 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -145,7 +145,6 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
union ioc4_int_out int_out;
union ioc4_gpcr gpcr;
unsigned int state, last_state = 1;
- struct timespec start_ts, end_ts;
uint64_t start, end, period;
unsigned int count = 0;
@@ -174,10 +173,10 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
if (!last_state && state) {
count++;
if (count == IOC4_CALIBRATE_END) {
- ktime_get_ts(&end_ts);
+ end = ktime_get_ns();
break;
} else if (count == IOC4_CALIBRATE_DISCARD)
- ktime_get_ts(&start_ts);
+ start = ktime_get_ns();
}
last_state = state;
} while (1);
@@ -192,8 +191,6 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
* by which the IOC4 generates the square wave, to get the
* period of an IOC4 INT_OUT count.
*/
- end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec;
- start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec;
period = (end - start) /
(IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
diff --git a/drivers/misc/lattice-ecp3-config.c b/drivers/misc/lattice-ecp3-config.c
index 0a1565e63c71..7ffdb589841e 100644
--- a/drivers/misc/lattice-ecp3-config.c
+++ b/drivers/misc/lattice-ecp3-config.c
@@ -15,6 +15,7 @@
#include <linux/spi/spi.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <asm/unaligned.h>
#define FIRMWARE_NAME "lattice-ecp3.bit"
@@ -91,8 +92,8 @@ static void firmware_load(const struct firmware *fw, void *context)
/* Trying to speak with the FPGA via SPI... */
txbuf[0] = FPGA_CMD_READ_ID;
ret = spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
- dev_dbg(&spi->dev, "FPGA JTAG ID=%08x\n", *(u32 *)&rxbuf[4]);
- jedec_id = *(u32 *)&rxbuf[4];
+ jedec_id = get_unaligned_be32(&rxbuf[4]);
+ dev_dbg(&spi->dev, "FPGA JTAG ID=%08x\n", jedec_id);
for (i = 0; i < ARRAY_SIZE(ecp3_dev); i++) {
if (jedec_id == ecp3_dev[i].jedec_id)
@@ -109,7 +110,8 @@ static void firmware_load(const struct firmware *fw, void *context)
txbuf[0] = FPGA_CMD_READ_STATUS;
ret = spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
- dev_dbg(&spi->dev, "FPGA Status=%08x\n", *(u32 *)&rxbuf[4]);
+ status = get_unaligned_be32(&rxbuf[4]);
+ dev_dbg(&spi->dev, "FPGA Status=%08x\n", status);
buffer = kzalloc(fw->size + 8, GFP_KERNEL);
if (!buffer) {
@@ -141,7 +143,7 @@ static void firmware_load(const struct firmware *fw, void *context)
for (i = 0; i < FPGA_CLEAR_LOOP_COUNT; i++) {
txbuf[0] = FPGA_CMD_READ_STATUS;
ret = spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
- status = *(u32 *)&rxbuf[4];
+ status = get_unaligned_be32(&rxbuf[4]);
if (status == FPGA_STATUS_CLEARED)
break;
@@ -164,8 +166,8 @@ static void firmware_load(const struct firmware *fw, void *context)
txbuf[0] = FPGA_CMD_READ_STATUS;
ret = spi_write_then_read(spi, txbuf, 8, rxbuf, rx_len);
- dev_dbg(&spi->dev, "FPGA Status=%08x\n", *(u32 *)&rxbuf[4]);
- status = *(u32 *)&rxbuf[4];
+ status = get_unaligned_be32(&rxbuf[4]);
+ dev_dbg(&spi->dev, "FPGA Status=%08x\n", status);
/* Check result */
if (status & FPGA_STATUS_DONE)
@@ -196,7 +198,7 @@ static int lattice_ecp3_probe(struct spi_device *spi)
spi_set_drvdata(spi, data);
init_completion(&data->fw_loaded);
- err = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
+ err = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
FIRMWARE_NAME, &spi->dev,
GFP_KERNEL, spi, firmware_load);
if (err) {
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index d66a2f24f6b3..b5abe34120b8 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -870,3 +870,4 @@ module_init(lkdtm_module_init);
module_exit(lkdtm_module_exit);
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Kprobe module for testing crash dumps");
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 59d20c599b16..324e1de93687 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -459,7 +459,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
{
struct mei_device *dev;
struct mei_cl_cb *cb;
- int rets, err;
+ int rets;
if (WARN_ON(!cl || !cl->dev))
return -ENODEV;
@@ -491,6 +491,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
cl_err(dev, cl, "failed to disconnect.\n");
goto free;
}
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
mdelay(10); /* Wait for hardware disconnection ready */
list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
} else {
@@ -500,23 +501,18 @@ int mei_cl_disconnect(struct mei_cl *cl)
}
mutex_unlock(&dev->device_lock);
- err = wait_event_timeout(dev->wait_recvd_msg,
+ wait_event_timeout(dev->wait_recvd_msg,
MEI_FILE_DISCONNECTED == cl->state,
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
mutex_lock(&dev->device_lock);
+
if (MEI_FILE_DISCONNECTED == cl->state) {
rets = 0;
cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
} else {
- rets = -ENODEV;
- if (MEI_FILE_DISCONNECTED != cl->state)
- cl_err(dev, cl, "wrong status client disconnect.\n");
-
- if (err)
- cl_dbg(dev, cl, "wait failed disconnect err=%d\n", err);
-
- cl_err(dev, cl, "failed to disconnect from FW client.\n");
+ cl_dbg(dev, cl, "timeout on disconnect from FW client.\n");
+ rets = -ETIME;
}
mei_io_list_flush(&dev->ctrl_rd_list, cl);
@@ -616,6 +612,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
mutex_lock(&dev->device_lock);
if (cl->state != MEI_FILE_CONNECTED) {
+ cl->state = MEI_FILE_DISCONNECTED;
/* something went really wrong */
if (!cl->status)
cl->status = -EFAULT;
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index a7856c0ac576..c5feafdd58a8 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -115,6 +115,7 @@
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */
#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
+#define MEI_DEV_ID_WPT_LP_2 0x9CBB /* Wildcat Point LP 2 */
/* Host Firmware Status Registers in PCI Config Space */
#define PCI_CFG_HFS_1 0x40
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 6a2d272cea43..a9a0d08f758e 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -710,64 +710,10 @@ end:
return IRQ_HANDLED;
}
-/**
- * mei_me_fw_status - retrieve fw status from the pci config space
- *
- * @dev: the device structure
- * @fw_status: fw status registers storage
- *
- * returns 0 on success an error code otherwise
- */
-static int mei_me_fw_status(struct mei_device *dev,
- struct mei_fw_status *fw_status)
-{
- const u32 pci_cfg_reg[] = {PCI_CFG_HFS_1, PCI_CFG_HFS_2};
- int i;
-
- if (!fw_status)
- return -EINVAL;
-
- switch (dev->pdev->device) {
- case MEI_DEV_ID_IBXPK_1:
- case MEI_DEV_ID_IBXPK_2:
- case MEI_DEV_ID_CPT_1:
- case MEI_DEV_ID_PBG_1:
- case MEI_DEV_ID_PPT_1:
- case MEI_DEV_ID_PPT_2:
- case MEI_DEV_ID_PPT_3:
- case MEI_DEV_ID_LPT_H:
- case MEI_DEV_ID_LPT_W:
- case MEI_DEV_ID_LPT_LP:
- case MEI_DEV_ID_LPT_HR:
- case MEI_DEV_ID_WPT_LP:
- fw_status->count = 2;
- break;
- case MEI_DEV_ID_ICH10_1:
- case MEI_DEV_ID_ICH10_2:
- case MEI_DEV_ID_ICH10_3:
- case MEI_DEV_ID_ICH10_4:
- fw_status->count = 1;
- break;
- default:
- fw_status->count = 0;
- break;
- }
-
- for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
- int ret;
- ret = pci_read_config_dword(dev->pdev,
- pci_cfg_reg[i], &fw_status->status[i]);
- if (ret)
- return ret;
- }
- return 0;
-}
-
static const struct mei_hw_ops mei_me_hw_ops = {
.pg_state = mei_me_pg_state,
- .fw_status = mei_me_fw_status,
.host_is_ready = mei_me_host_is_ready,
.hw_is_ready = mei_me_hw_is_ready,
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 93273783dec5..f1cd166094f2 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -1042,40 +1042,8 @@ end:
return IRQ_HANDLED;
}
-
-/**
- * mei_txe_fw_status - retrieve fw status from the pci config space
- *
- * @dev: the device structure
- * @fw_status: fw status registers storage
- *
- * returns: 0 on success an error code otherwise
- */
-static int mei_txe_fw_status(struct mei_device *dev,
- struct mei_fw_status *fw_status)
-{
- const u32 pci_cfg_reg[] = {PCI_CFG_TXE_FW_STS0, PCI_CFG_TXE_FW_STS1};
- int i;
-
- if (!fw_status)
- return -EINVAL;
-
- fw_status->count = 2;
-
- for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) {
- int ret;
- ret = pci_read_config_dword(dev->pdev,
- pci_cfg_reg[i], &fw_status->status[i]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
static const struct mei_hw_ops mei_txe_hw_ops = {
- .fw_status = mei_txe_fw_status,
.host_is_ready = mei_txe_host_is_ready,
.pg_state = mei_txe_pg_state,
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 66f0a1a06451..401a3d526cd0 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -32,7 +32,6 @@
#include <linux/compat.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
-#include <linux/miscdevice.h>
#include <linux/mei.h>
@@ -49,19 +48,12 @@
*/
static int mei_open(struct inode *inode, struct file *file)
{
- struct miscdevice *misc = file->private_data;
- struct pci_dev *pdev;
- struct mei_cl *cl;
struct mei_device *dev;
+ struct mei_cl *cl;
int err;
- if (!misc->parent)
- return -ENODEV;
-
- pdev = container_of(misc->parent, struct pci_dev, dev);
-
- dev = pci_get_drvdata(pdev);
+ dev = container_of(inode->i_cdev, struct mei_device, cdev);
if (!dev)
return -ENODEV;
@@ -667,46 +659,148 @@ static const struct file_operations mei_fops = {
.llseek = no_llseek
};
-/*
- * Misc Device Struct
+static struct class *mei_class;
+static dev_t mei_devt;
+#define MEI_MAX_DEVS MINORMASK
+static DEFINE_MUTEX(mei_minor_lock);
+static DEFINE_IDR(mei_idr);
+
+/**
+ * mei_minor_get - obtain next free device minor number
+ *
+ * @dev: device pointer
+ *
+ * returns allocated minor, or -ENOSPC if no free minor left
*/
-static struct miscdevice mei_misc_device = {
- .name = "mei",
- .fops = &mei_fops,
- .minor = MISC_DYNAMIC_MINOR,
-};
+static int mei_minor_get(struct mei_device *dev)
+{
+ int ret;
+
+ mutex_lock(&mei_minor_lock);
+ ret = idr_alloc(&mei_idr, dev, 0, MEI_MAX_DEVS, GFP_KERNEL);
+ if (ret >= 0)
+ dev->minor = ret;
+ else if (ret == -ENOSPC)
+ dev_err(&dev->pdev->dev, "too many mei devices\n");
+ mutex_unlock(&mei_minor_lock);
+ return ret;
+}
-int mei_register(struct mei_device *dev)
+/**
+ * mei_minor_free - mark device minor number as free
+ *
+ * @dev: device pointer
+ */
+static void mei_minor_free(struct mei_device *dev)
{
- int ret;
- mei_misc_device.parent = &dev->pdev->dev;
- ret = misc_register(&mei_misc_device);
- if (ret)
+ mutex_lock(&mei_minor_lock);
+ idr_remove(&mei_idr, dev->minor);
+ mutex_unlock(&mei_minor_lock);
+}
+
+int mei_register(struct mei_device *dev, struct device *parent)
+{
+ struct device *clsdev; /* class device */
+ int ret, devno;
+
+ ret = mei_minor_get(dev);
+ if (ret < 0)
return ret;
- if (mei_dbgfs_register(dev, mei_misc_device.name))
- dev_err(&dev->pdev->dev, "cannot register debugfs\n");
+ /* Fill in the data structures */
+ devno = MKDEV(MAJOR(mei_devt), dev->minor);
+ cdev_init(&dev->cdev, &mei_fops);
+ dev->cdev.owner = mei_fops.owner;
+
+ /* Add the device */
+ ret = cdev_add(&dev->cdev, devno, 1);
+ if (ret) {
+ dev_err(parent, "unable to add device %d:%d\n",
+ MAJOR(mei_devt), dev->minor);
+ goto err_dev_add;
+ }
+
+ clsdev = device_create(mei_class, parent, devno,
+ NULL, "mei%d", dev->minor);
+
+ if (IS_ERR(clsdev)) {
+ dev_err(parent, "unable to create device %d:%d\n",
+ MAJOR(mei_devt), dev->minor);
+ ret = PTR_ERR(clsdev);
+ goto err_dev_create;
+ }
+
+ ret = mei_dbgfs_register(dev, dev_name(clsdev));
+ if (ret) {
+ dev_err(clsdev, "cannot register debugfs ret = %d\n", ret);
+ goto err_dev_dbgfs;
+ }
return 0;
+
+err_dev_dbgfs:
+ device_destroy(mei_class, devno);
+err_dev_create:
+ cdev_del(&dev->cdev);
+err_dev_add:
+ mei_minor_free(dev);
+ return ret;
}
EXPORT_SYMBOL_GPL(mei_register);
void mei_deregister(struct mei_device *dev)
{
+ int devno;
+
+ devno = dev->cdev.dev;
+ cdev_del(&dev->cdev);
+
mei_dbgfs_deregister(dev);
- misc_deregister(&mei_misc_device);
- mei_misc_device.parent = NULL;
+
+ device_destroy(mei_class, devno);
+
+ mei_minor_free(dev);
}
EXPORT_SYMBOL_GPL(mei_deregister);
static int __init mei_init(void)
{
- return mei_cl_bus_init();
+ int ret;
+
+ mei_class = class_create(THIS_MODULE, "mei");
+ if (IS_ERR(mei_class)) {
+ pr_err("couldn't create class\n");
+ ret = PTR_ERR(mei_class);
+ goto err;
+ }
+
+ ret = alloc_chrdev_region(&mei_devt, 0, MEI_MAX_DEVS, "mei");
+ if (ret < 0) {
+ pr_err("unable to allocate char dev region\n");
+ goto err_class;
+ }
+
+ ret = mei_cl_bus_init();
+ if (ret < 0) {
+ pr_err("unable to initialize bus\n");
+ goto err_chrdev;
+ }
+
+ return 0;
+
+err_chrdev:
+ unregister_chrdev_region(mei_devt, MEI_MAX_DEVS);
+err_class:
+ class_destroy(mei_class);
+err:
+ return ret;
}
static void __exit mei_exit(void)
{
+ unregister_chrdev_region(mei_devt, MEI_MAX_DEVS);
+ class_destroy(mei_class);
mei_cl_bus_exit();
}
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 5c7e990e2f22..0b0d6135543b 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -227,7 +227,6 @@ struct mei_cl {
/** struct mei_hw_ops
*
- * @fw_status - read FW status from PCI config space
* @host_is_ready - query for host readiness
* @hw_is_ready - query if hw is ready
@@ -255,8 +254,6 @@ struct mei_cl {
*/
struct mei_hw_ops {
- int (*fw_status)(struct mei_device *dev,
- struct mei_fw_status *fw_status);
bool (*host_is_ready)(struct mei_device *dev);
bool (*hw_is_ready)(struct mei_device *dev);
@@ -400,6 +397,10 @@ struct mei_cfg {
/**
* struct mei_device - MEI private device struct
+ * @pdev - pointer to pci device struct
+ * @cdev - character device
+ * @minor - minor number allocated for device
+ *
* @reset_count - limits the number of consecutive resets
* @hbm_state - state of host bus message protocol
* @pg_event - power gating event
@@ -412,6 +413,9 @@ struct mei_cfg {
*/
struct mei_device {
struct pci_dev *pdev; /* pointer to pci device struct */
+ struct cdev cdev;
+ int minor;
+
/*
* lists of queues
*/
@@ -741,7 +745,7 @@ static inline int mei_dbgfs_register(struct mei_device *dev, const char *name)
static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
#endif /* CONFIG_DEBUG_FS */
-int mei_register(struct mei_device *dev);
+int mei_register(struct mei_device *dev, struct device *parent);
void mei_deregister(struct mei_device *dev);
#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d internal=%1d comp=%1d"
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 1b46c64a649f..a0e9422b55a2 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -31,7 +31,6 @@
#include <linux/compat.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
-#include <linux/miscdevice.h>
#include <linux/pm_runtime.h>
@@ -82,6 +81,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)},
{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)},
{MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)},
+ {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch_cfg)},
/* required last entry */
{0, }
@@ -207,7 +207,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_ME_RPM_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
- err = mei_register(dev);
+ err = mei_register(dev, &pdev->dev);
if (err)
goto release_irq;
@@ -369,7 +369,7 @@ static int mei_me_pm_runtime_idle(struct device *device)
if (!dev)
return -ENODEV;
if (mei_write_is_idle(dev))
- pm_schedule_suspend(device, MEI_ME_RPM_TIMEOUT * 2);
+ pm_runtime_autosuspend(device);
return -EBUSY;
}
diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c
index 2343c6236df9..19de57368b7a 100644
--- a/drivers/misc/mei/pci-txe.c
+++ b/drivers/misc/mei/pci-txe.c
@@ -149,7 +149,7 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
- err = mei_register(dev);
+ err = mei_register(dev, &pdev->dev);
if (err)
goto release_irq;
@@ -306,7 +306,7 @@ static int mei_txe_pm_runtime_idle(struct device *device)
if (!dev)
return -ENODEV;
if (mei_write_is_idle(dev))
- pm_schedule_suspend(device, MEI_TXI_RPM_TIMEOUT * 2);
+ pm_runtime_autosuspend(device);
return -EBUSY;
}
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index 462a5b1d8651..cc4eef040c14 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -1,8 +1,25 @@
+comment "Intel MIC Bus Driver"
+
+config INTEL_MIC_BUS
+ tristate "Intel MIC Bus Driver"
+ depends on 64BIT && PCI && X86 && X86_DEV_DMA_OPS
+ help
+ This option is selected by any driver which registers a
+ device or driver on the MIC Bus, such as CONFIG_INTEL_MIC_HOST,
+ CONFIG_INTEL_MIC_CARD, CONFIG_INTEL_MIC_X100_DMA etc.
+
+ If you are building a host/card kernel with an Intel MIC device
+ then say M (recommended) or Y, else say N. If unsure say N.
+
+ More information about the Intel MIC family as well as the Linux
+ OS and tools for MIC to use with this driver are available from
+ <http://software.intel.com/en-us/mic-developer>.
+
comment "Intel MIC Host Driver"
config INTEL_MIC_HOST
tristate "Intel MIC Host Driver"
- depends on 64BIT && PCI && X86
+ depends on 64BIT && PCI && X86 && INTEL_MIC_BUS
select VHOST_RING
help
This enables Host Driver support for the Intel Many Integrated
@@ -22,7 +39,7 @@ comment "Intel MIC Card Driver"
config INTEL_MIC_CARD
tristate "Intel MIC Card Driver"
- depends on 64BIT && X86
+ depends on 64BIT && X86 && INTEL_MIC_BUS
select VIRTIO
help
This enables card driver support for the Intel Many Integrated
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile
index 05b34d683a58..e9bf148755e2 100644
--- a/drivers/misc/mic/Makefile
+++ b/drivers/misc/mic/Makefile
@@ -4,3 +4,4 @@
#
obj-$(CONFIG_INTEL_MIC_HOST) += host/
obj-$(CONFIG_INTEL_MIC_CARD) += card/
+obj-$(CONFIG_INTEL_MIC_BUS) += bus/
diff --git a/drivers/misc/mic/bus/Makefile b/drivers/misc/mic/bus/Makefile
new file mode 100644
index 000000000000..d85c7f2a0af4
--- /dev/null
+++ b/drivers/misc/mic/bus/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile - Intel MIC Linux driver.
+# Copyright(c) 2014, Intel Corporation.
+#
+obj-$(CONFIG_INTEL_MIC_BUS) += mic_bus.o
diff --git a/drivers/misc/mic/bus/mic_bus.c b/drivers/misc/mic/bus/mic_bus.c
new file mode 100644
index 000000000000..961ae90aae47
--- /dev/null
+++ b/drivers/misc/mic/bus/mic_bus.c
@@ -0,0 +1,218 @@
+/*
+ * Intel MIC Platform Software Stack (MPSS)
+ *
+ * Copyright(c) 2014 Intel Corporation.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Intel MIC Bus driver.
+ *
+ * This implementation is very similar to the the virtio bus driver
+ * implementation @ drivers/virtio/virtio.c
+ */
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/idr.h>
+#include <linux/mic_bus.h>
+
+/* Unique numbering for mbus devices. */
+static DEFINE_IDA(mbus_index_ida);
+
+static ssize_t device_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct mbus_device *dev = dev_to_mbus(d);
+ return sprintf(buf, "0x%04x\n", dev->id.device);
+}
+static DEVICE_ATTR_RO(device);
+
+static ssize_t vendor_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct mbus_device *dev = dev_to_mbus(d);
+ return sprintf(buf, "0x%04x\n", dev->id.vendor);
+}
+static DEVICE_ATTR_RO(vendor);
+
+static ssize_t modalias_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct mbus_device *dev = dev_to_mbus(d);
+ return sprintf(buf, "mbus:d%08Xv%08X\n",
+ dev->id.device, dev->id.vendor);
+}
+static DEVICE_ATTR_RO(modalias);
+
+static struct attribute *mbus_dev_attrs[] = {
+ &dev_attr_device.attr,
+ &dev_attr_vendor.attr,
+ &dev_attr_modalias.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(mbus_dev);
+
+static inline int mbus_id_match(const struct mbus_device *dev,
+ const struct mbus_device_id *id)
+{
+ if (id->device != dev->id.device && id->device != MBUS_DEV_ANY_ID)
+ return 0;
+
+ return id->vendor == MBUS_DEV_ANY_ID || id->vendor == dev->id.vendor;
+}
+
+/*
+ * This looks through all the IDs a driver claims to support. If any of them
+ * match, we return 1 and the kernel will call mbus_dev_probe().
+ */
+static int mbus_dev_match(struct device *dv, struct device_driver *dr)
+{
+ unsigned int i;
+ struct mbus_device *dev = dev_to_mbus(dv);
+ const struct mbus_device_id *ids;
+
+ ids = drv_to_mbus(dr)->id_table;
+ for (i = 0; ids[i].device; i++)
+ if (mbus_id_match(dev, &ids[i]))
+ return 1;
+ return 0;
+}
+
+static int mbus_uevent(struct device *dv, struct kobj_uevent_env *env)
+{
+ struct mbus_device *dev = dev_to_mbus(dv);
+
+ return add_uevent_var(env, "MODALIAS=mbus:d%08Xv%08X",
+ dev->id.device, dev->id.vendor);
+}
+
+static int mbus_dev_probe(struct device *d)
+{
+ int err;
+ struct mbus_device *dev = dev_to_mbus(d);
+ struct mbus_driver *drv = drv_to_mbus(dev->dev.driver);
+
+ err = drv->probe(dev);
+ if (!err)
+ if (drv->scan)
+ drv->scan(dev);
+ return err;
+}
+
+static int mbus_dev_remove(struct device *d)
+{
+ struct mbus_device *dev = dev_to_mbus(d);
+ struct mbus_driver *drv = drv_to_mbus(dev->dev.driver);
+
+ drv->remove(dev);
+ return 0;
+}
+
+static struct bus_type mic_bus = {
+ .name = "mic_bus",
+ .match = mbus_dev_match,
+ .dev_groups = mbus_dev_groups,
+ .uevent = mbus_uevent,
+ .probe = mbus_dev_probe,
+ .remove = mbus_dev_remove,
+};
+
+int mbus_register_driver(struct mbus_driver *driver)
+{
+ driver->driver.bus = &mic_bus;
+ return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(mbus_register_driver);
+
+void mbus_unregister_driver(struct mbus_driver *driver)
+{
+ driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(mbus_unregister_driver);
+
+static void mbus_release_dev(struct device *d)
+{
+ struct mbus_device *mbdev = dev_to_mbus(d);
+ kfree(mbdev);
+}
+
+struct mbus_device *
+mbus_register_device(struct device *pdev, int id, struct dma_map_ops *dma_ops,
+ struct mbus_hw_ops *hw_ops, void __iomem *mmio_va)
+{
+ int ret;
+ struct mbus_device *mbdev;
+
+ mbdev = kzalloc(sizeof(*mbdev), GFP_KERNEL);
+ if (!mbdev)
+ return ERR_PTR(-ENOMEM);
+
+ mbdev->mmio_va = mmio_va;
+ mbdev->dev.parent = pdev;
+ mbdev->id.device = id;
+ mbdev->id.vendor = MBUS_DEV_ANY_ID;
+ mbdev->dev.archdata.dma_ops = dma_ops;
+ mbdev->dev.dma_mask = &mbdev->dev.coherent_dma_mask;
+ dma_set_mask(&mbdev->dev, DMA_BIT_MASK(64));
+ mbdev->dev.release = mbus_release_dev;
+ mbdev->hw_ops = hw_ops;
+ mbdev->dev.bus = &mic_bus;
+
+ /* Assign a unique device index and hence name. */
+ ret = ida_simple_get(&mbus_index_ida, 0, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto free_mbdev;
+
+ mbdev->index = ret;
+ dev_set_name(&mbdev->dev, "mbus-dev%u", mbdev->index);
+ /*
+ * device_register() causes the bus infrastructure to look for a
+ * matching driver.
+ */
+ ret = device_register(&mbdev->dev);
+ if (ret)
+ goto ida_remove;
+ return mbdev;
+ida_remove:
+ ida_simple_remove(&mbus_index_ida, mbdev->index);
+free_mbdev:
+ kfree(mbdev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(mbus_register_device);
+
+void mbus_unregister_device(struct mbus_device *mbdev)
+{
+ int index = mbdev->index; /* save for after device release */
+
+ device_unregister(&mbdev->dev);
+ ida_simple_remove(&mbus_index_ida, index);
+}
+EXPORT_SYMBOL_GPL(mbus_unregister_device);
+
+static int __init mbus_init(void)
+{
+ return bus_register(&mic_bus);
+}
+
+static void __exit mbus_exit(void)
+{
+ bus_unregister(&mic_bus);
+ ida_destroy(&mbus_index_ida);
+}
+
+core_initcall(mbus_init);
+module_exit(mbus_exit);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) MIC Bus driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c
index d0980ff96833..83819eee553b 100644
--- a/drivers/misc/mic/card/mic_device.c
+++ b/drivers/misc/mic/card/mic_device.c
@@ -83,8 +83,8 @@ static int mic_shutdown_init(void)
int shutdown_db;
shutdown_db = mic_next_card_db();
- shutdown_cookie = mic_request_card_irq(mic_shutdown_isr,
- "Shutdown", mdrv, shutdown_db);
+ shutdown_cookie = mic_request_card_irq(mic_shutdown_isr, NULL,
+ "Shutdown", mdrv, shutdown_db);
if (IS_ERR(shutdown_cookie))
rc = PTR_ERR(shutdown_cookie);
else
@@ -136,7 +136,8 @@ static void mic_dp_uninit(void)
/**
* mic_request_card_irq - request an irq.
*
- * @func: The callback function that handles the interrupt.
+ * @handler: interrupt handler passed to request_threaded_irq.
+ * @thread_fn: thread fn. passed to request_threaded_irq.
* @name: The ASCII name of the callee requesting the irq.
* @data: private data that is returned back when calling the
* function handler.
@@ -149,17 +150,19 @@ static void mic_dp_uninit(void)
* error code.
*
*/
-struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
- const char *name, void *data, int index)
+struct mic_irq *
+mic_request_card_irq(irq_handler_t handler,
+ irq_handler_t thread_fn, const char *name,
+ void *data, int index)
{
int rc = 0;
unsigned long cookie;
struct mic_driver *mdrv = g_drv;
- rc = request_irq(mic_db_to_irq(mdrv, index), func,
- 0, name, data);
+ rc = request_threaded_irq(mic_db_to_irq(mdrv, index), handler,
+ thread_fn, 0, name, data);
if (rc) {
- dev_err(mdrv->dev, "request_irq failed rc = %d\n", rc);
+ dev_err(mdrv->dev, "request_threaded_irq failed rc = %d\n", rc);
goto err;
}
mdrv->irq_info.irq_usage_count[index]++;
@@ -172,9 +175,9 @@ err:
/**
* mic_free_card_irq - free irq.
*
- * @cookie: cookie obtained during a successful call to mic_request_irq
+ * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
* @data: private data specified by the calling function during the
- * mic_request_irq
+ * mic_request_threaded_irq
*
* returns: none.
*/
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h
index 306f502be95e..844be8fc9b22 100644
--- a/drivers/misc/mic/card/mic_device.h
+++ b/drivers/misc/mic/card/mic_device.h
@@ -30,6 +30,8 @@
#include <linux/workqueue.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
+#include <linux/interrupt.h>
+#include <linux/mic_bus.h>
/**
* struct mic_intr_info - Contains h/w specific interrupt sources info
@@ -70,6 +72,7 @@ struct mic_device {
* @hotplug_work: Hot plug work for adding/removing virtio devices.
* @irq_info: The OS specific irq information
* @intr_info: H/W specific interrupt information.
+ * @dma_mbdev: dma device on the MIC virtual bus.
*/
struct mic_driver {
char name[20];
@@ -80,6 +83,7 @@ struct mic_driver {
struct work_struct hotplug_work;
struct mic_irq_info irq_info;
struct mic_intr_info intr_info;
+ struct mbus_device *dma_mbdev;
};
/**
@@ -116,8 +120,9 @@ mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
int mic_driver_init(struct mic_driver *mdrv);
void mic_driver_uninit(struct mic_driver *mdrv);
int mic_next_card_db(void);
-struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
- const char *name, void *data, int intr_src);
+struct mic_irq *
+mic_request_card_irq(irq_handler_t handler, irq_handler_t thread_fn,
+ const char *name, void *data, int intr_src);
void mic_free_card_irq(struct mic_irq *cookie, void *data);
u32 mic_read_spad(struct mic_device *mdev, unsigned int idx);
void mic_send_intr(struct mic_device *mdev, int doorbell);
diff --git a/drivers/misc/mic/card/mic_virtio.c b/drivers/misc/mic/card/mic_virtio.c
index 653799b96bfa..f14b60080c21 100644
--- a/drivers/misc/mic/card/mic_virtio.c
+++ b/drivers/misc/mic/card/mic_virtio.c
@@ -417,7 +417,7 @@ static int mic_add_device(struct mic_device_desc __iomem *d,
virtio_db = mic_next_card_db();
mvdev->virtio_cookie = mic_request_card_irq(mic_virtio_intr_handler,
- "virtio intr", mvdev, virtio_db);
+ NULL, "virtio intr", mvdev, virtio_db);
if (IS_ERR(mvdev->virtio_cookie)) {
ret = PTR_ERR(mvdev->virtio_cookie);
goto kfree;
@@ -606,8 +606,9 @@ int mic_devices_init(struct mic_driver *mdrv)
mic_scan_devices(mdrv, !REMOVE_DEVICES);
config_db = mic_next_card_db();
- virtio_config_cookie = mic_request_card_irq(mic_extint_handler,
- "virtio_config_intr", mdrv, config_db);
+ virtio_config_cookie = mic_request_card_irq(mic_extint_handler, NULL,
+ "virtio_config_intr", mdrv,
+ config_db);
if (IS_ERR(virtio_config_cookie)) {
rc = PTR_ERR(virtio_config_cookie);
goto exit;
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c
index 2868945c9a4d..9d57545d64f6 100644
--- a/drivers/misc/mic/card/mic_x100.c
+++ b/drivers/misc/mic/card/mic_x100.c
@@ -148,6 +148,47 @@ void mic_card_unmap(struct mic_device *mdev, void __iomem *addr)
iounmap(addr);
}
+static inline struct mic_driver *mbdev_to_mdrv(struct mbus_device *mbdev)
+{
+ return dev_get_drvdata(mbdev->dev.parent);
+}
+
+static struct mic_irq *
+_mic_request_threaded_irq(struct mbus_device *mbdev,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ const char *name, void *data, int intr_src)
+{
+ int rc = 0;
+ unsigned int irq = intr_src;
+ unsigned long cookie = irq;
+
+ rc = request_threaded_irq(irq, handler, thread_fn, 0, name, data);
+ if (rc) {
+ dev_err(mbdev_to_mdrv(mbdev)->dev,
+ "request_threaded_irq failed rc = %d\n", rc);
+ return ERR_PTR(rc);
+ }
+ return (struct mic_irq *)cookie;
+}
+
+static void _mic_free_irq(struct mbus_device *mbdev,
+ struct mic_irq *cookie, void *data)
+{
+ unsigned long irq = (unsigned long)cookie;
+ free_irq(irq, data);
+}
+
+static void _mic_ack_interrupt(struct mbus_device *mbdev, int num)
+{
+ mic_ack_interrupt(&mbdev_to_mdrv(mbdev)->mdev);
+}
+
+static struct mbus_hw_ops mbus_hw_ops = {
+ .request_threaded_irq = _mic_request_threaded_irq,
+ .free_irq = _mic_free_irq,
+ .ack_interrupt = _mic_ack_interrupt,
+};
+
static int __init mic_probe(struct platform_device *pdev)
{
struct mic_driver *mdrv = &g_drv;
@@ -159,32 +200,41 @@ static int __init mic_probe(struct platform_device *pdev)
mdev->mmio.pa = MIC_X100_MMIO_BASE;
mdev->mmio.len = MIC_X100_MMIO_LEN;
- mdev->mmio.va = ioremap(MIC_X100_MMIO_BASE, MIC_X100_MMIO_LEN);
+ mdev->mmio.va = devm_ioremap(&pdev->dev, MIC_X100_MMIO_BASE,
+ MIC_X100_MMIO_LEN);
if (!mdev->mmio.va) {
dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
rc = -EIO;
goto done;
}
mic_hw_intr_init(mdrv);
+ platform_set_drvdata(pdev, mdrv);
+ mdrv->dma_mbdev = mbus_register_device(mdrv->dev, MBUS_DEV_DMA_MIC,
+ NULL, &mbus_hw_ops,
+ mdrv->mdev.mmio.va);
+ if (IS_ERR(mdrv->dma_mbdev)) {
+ rc = PTR_ERR(mdrv->dma_mbdev);
+ dev_err(&pdev->dev, "mbus_add_device failed rc %d\n", rc);
+ goto done;
+ }
rc = mic_driver_init(mdrv);
if (rc) {
dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc);
- goto iounmap;
+ goto remove_dma;
}
done:
return rc;
-iounmap:
- iounmap(mdev->mmio.va);
+remove_dma:
+ mbus_unregister_device(mdrv->dma_mbdev);
return rc;
}
static int mic_remove(struct platform_device *pdev)
{
struct mic_driver *mdrv = &g_drv;
- struct mic_device *mdev = &mdrv->mdev;
mic_driver_uninit(mdrv);
- iounmap(mdev->mmio.va);
+ mbus_unregister_device(mdrv->dma_mbdev);
return 0;
}
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c
index b75c6b5cc20f..ff2b0fb1a6be 100644
--- a/drivers/misc/mic/host/mic_boot.c
+++ b/drivers/misc/mic/host/mic_boot.c
@@ -23,11 +23,70 @@
#include <linux/pci.h>
#include <linux/mic_common.h>
+#include <linux/mic_bus.h>
#include "../common/mic_dev.h"
#include "mic_device.h"
#include "mic_smpt.h"
#include "mic_virtio.h"
+static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev)
+{
+ return dev_get_drvdata(mbdev->dev.parent);
+}
+
+static dma_addr_t
+mic_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ void *va = phys_to_virt(page_to_phys(page)) + offset;
+ struct mic_device *mdev = dev_get_drvdata(dev->parent);
+
+ return mic_map_single(mdev, va, size);
+}
+
+static void
+mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct mic_device *mdev = dev_get_drvdata(dev->parent);
+ mic_unmap_single(mdev, dma_addr, size);
+}
+
+static struct dma_map_ops mic_dma_ops = {
+ .map_page = mic_dma_map_page,
+ .unmap_page = mic_dma_unmap_page,
+};
+
+static struct mic_irq *
+_mic_request_threaded_irq(struct mbus_device *mbdev,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ const char *name, void *data, int intr_src)
+{
+ return mic_request_threaded_irq(mbdev_to_mdev(mbdev), handler,
+ thread_fn, name, data,
+ intr_src, MIC_INTR_DMA);
+}
+
+static void _mic_free_irq(struct mbus_device *mbdev,
+ struct mic_irq *cookie, void *data)
+{
+ return mic_free_irq(mbdev_to_mdev(mbdev), cookie, data);
+}
+
+static void _mic_ack_interrupt(struct mbus_device *mbdev, int num)
+{
+ struct mic_device *mdev = mbdev_to_mdev(mbdev);
+ mdev->ops->intr_workarounds(mdev);
+}
+
+static struct mbus_hw_ops mbus_hw_ops = {
+ .request_threaded_irq = _mic_request_threaded_irq,
+ .free_irq = _mic_free_irq,
+ .ack_interrupt = _mic_ack_interrupt,
+};
+
/**
* mic_reset - Reset the MIC device.
* @mdev: pointer to mic_device instance
@@ -95,9 +154,21 @@ retry:
*/
goto retry;
}
+ mdev->dma_mbdev = mbus_register_device(mdev->sdev->parent,
+ MBUS_DEV_DMA_HOST, &mic_dma_ops,
+ &mbus_hw_ops, mdev->mmio.va);
+ if (IS_ERR(mdev->dma_mbdev)) {
+ rc = PTR_ERR(mdev->dma_mbdev);
+ goto unlock_ret;
+ }
+ mdev->dma_ch = mic_request_dma_chan(mdev);
+ if (!mdev->dma_ch) {
+ rc = -ENXIO;
+ goto dma_remove;
+ }
rc = mdev->ops->load_mic_fw(mdev, buf);
if (rc)
- goto unlock_ret;
+ goto dma_release;
mic_smpt_restore(mdev);
mic_intr_restore(mdev);
mdev->intr_ops->enable_interrupts(mdev);
@@ -105,6 +176,11 @@ retry:
mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
mdev->ops->send_firmware_intr(mdev);
mic_set_state(mdev, MIC_ONLINE);
+ goto unlock_ret;
+dma_release:
+ dma_release_channel(mdev->dma_ch);
+dma_remove:
+ mbus_unregister_device(mdev->dma_mbdev);
unlock_ret:
mutex_unlock(&mdev->mic_mutex);
return rc;
@@ -122,6 +198,11 @@ void mic_stop(struct mic_device *mdev, bool force)
mutex_lock(&mdev->mic_mutex);
if (MIC_OFFLINE != mdev->state || force) {
mic_virtio_reset_devices(mdev);
+ if (mdev->dma_ch) {
+ dma_release_channel(mdev->dma_ch);
+ mdev->dma_ch = NULL;
+ }
+ mbus_unregister_device(mdev->dma_mbdev);
mic_bootparam_init(mdev);
mic_reset(mdev);
if (MIC_RESET_FAILED == mdev->state)
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h
index 0398c696d257..016bd15a7bd1 100644
--- a/drivers/misc/mic/host/mic_device.h
+++ b/drivers/misc/mic/host/mic_device.h
@@ -25,6 +25,8 @@
#include <linux/idr.h>
#include <linux/notifier.h>
#include <linux/irqreturn.h>
+#include <linux/dmaengine.h>
+#include <linux/mic_bus.h>
#include "mic_intr.h"
@@ -87,6 +89,8 @@ enum mic_stepping {
* @cdev: Character device for MIC.
* @vdev_list: list of virtio devices.
* @pm_notifier: Handles PM notifications from the OS.
+ * @dma_mbdev: MIC BUS DMA device.
+ * @dma_ch: DMA channel reserved by this driver for use by virtio devices.
*/
struct mic_device {
struct mic_mw mmio;
@@ -124,6 +128,8 @@ struct mic_device {
struct cdev cdev;
struct list_head vdev_list;
struct notifier_block pm_notifier;
+ struct mbus_device *dma_mbdev;
+ struct dma_chan *dma_ch;
};
/**
@@ -144,6 +150,7 @@ struct mic_device {
* @load_mic_fw: Load firmware segments required to boot the card
* into card memory. This includes the kernel, command line, ramdisk etc.
* @get_postcode: Get post code status from firmware.
+ * @dma_filter: DMA filter function to be used.
*/
struct mic_hw_ops {
u8 aper_bar;
@@ -159,6 +166,7 @@ struct mic_hw_ops {
void (*send_firmware_intr)(struct mic_device *mdev);
int (*load_mic_fw)(struct mic_device *mdev, const char *buf);
u32 (*get_postcode)(struct mic_device *mdev);
+ bool (*dma_filter)(struct dma_chan *chan, void *param);
};
/**
@@ -187,6 +195,22 @@ mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
iowrite32(val, mw->va + offset);
}
+static inline struct dma_chan *mic_request_dma_chan(struct mic_device *mdev)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+ chan = dma_request_channel(mask, mdev->ops->dma_filter,
+ mdev->sdev->parent);
+ if (chan)
+ return chan;
+ dev_err(mdev->sdev->parent, "%s %d unable to acquire channel\n",
+ __func__, __LINE__);
+ return NULL;
+}
+
void mic_sysfs_init(struct mic_device *mdev);
int mic_start(struct mic_device *mdev, const char *buf);
void mic_stop(struct mic_device *mdev, bool force);
diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c
index dbc5afde1392..d686f2846ac7 100644
--- a/drivers/misc/mic/host/mic_intr.c
+++ b/drivers/misc/mic/host/mic_intr.c
@@ -24,28 +24,29 @@
#include "../common/mic_dev.h"
#include "mic_device.h"
-/*
- * mic_invoke_callback - Invoke callback functions registered for
- * the corresponding source id.
- *
- * @mdev: pointer to the mic_device instance
- * @idx: The interrupt source id.
- *
- * Returns none.
- */
-static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
+static irqreturn_t mic_thread_fn(int irq, void *dev)
{
+ struct mic_device *mdev = dev;
+ struct mic_intr_info *intr_info = mdev->intr_info;
+ struct mic_irq_info *irq_info = &mdev->irq_info;
struct mic_intr_cb *intr_cb;
struct pci_dev *pdev = container_of(mdev->sdev->parent,
- struct pci_dev, dev);
+ struct pci_dev, dev);
+ int i;
- spin_lock(&mdev->irq_info.mic_intr_lock);
- list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
- if (intr_cb->func)
- intr_cb->func(pdev->irq, intr_cb->data);
- spin_unlock(&mdev->irq_info.mic_intr_lock);
+ spin_lock(&irq_info->mic_thread_lock);
+ for (i = intr_info->intr_start_idx[MIC_INTR_DB];
+ i < intr_info->intr_len[MIC_INTR_DB]; i++)
+ if (test_and_clear_bit(i, &irq_info->mask)) {
+ list_for_each_entry(intr_cb, &irq_info->cb_list[i],
+ list)
+ if (intr_cb->thread_fn)
+ intr_cb->thread_fn(pdev->irq,
+ intr_cb->data);
+ }
+ spin_unlock(&irq_info->mic_thread_lock);
+ return IRQ_HANDLED;
}
-
/**
* mic_interrupt - Generic interrupt handler for
* MSI and INTx based interrupts.
@@ -53,7 +54,11 @@ static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
static irqreturn_t mic_interrupt(int irq, void *dev)
{
struct mic_device *mdev = dev;
- struct mic_intr_info *info = mdev->intr_info;
+ struct mic_intr_info *intr_info = mdev->intr_info;
+ struct mic_irq_info *irq_info = &mdev->irq_info;
+ struct mic_intr_cb *intr_cb;
+ struct pci_dev *pdev = container_of(mdev->sdev->parent,
+ struct pci_dev, dev);
u32 mask;
int i;
@@ -61,12 +66,19 @@ static irqreturn_t mic_interrupt(int irq, void *dev)
if (!mask)
return IRQ_NONE;
- for (i = info->intr_start_idx[MIC_INTR_DB];
- i < info->intr_len[MIC_INTR_DB]; i++)
- if (mask & BIT(i))
- mic_invoke_callback(mdev, i);
-
- return IRQ_HANDLED;
+ spin_lock(&irq_info->mic_intr_lock);
+ for (i = intr_info->intr_start_idx[MIC_INTR_DB];
+ i < intr_info->intr_len[MIC_INTR_DB]; i++)
+ if (mask & BIT(i)) {
+ list_for_each_entry(intr_cb, &irq_info->cb_list[i],
+ list)
+ if (intr_cb->handler)
+ intr_cb->handler(pdev->irq,
+ intr_cb->data);
+ set_bit(i, &irq_info->mask);
+ }
+ spin_unlock(&irq_info->mic_intr_lock);
+ return IRQ_WAKE_THREAD;
}
/* Return the interrupt offset from the index. Index is 0 based. */
@@ -99,14 +111,15 @@ static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
*
* @mdev: pointer to the mic_device instance
* @idx: The source id to be registered.
- * @func: The function to be called when the source id receives
+ * @handler: The function to be called when the source id receives
* the interrupt.
+ * @thread_fn: thread fn. corresponding to the handler
* @data: Private data of the requester.
* Return the callback structure that was registered or an
* appropriate error on failure.
*/
static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
- u8 idx, irqreturn_t (*func) (int irq, void *dev),
+ u8 idx, irq_handler_t handler, irq_handler_t thread_fn,
void *data)
{
struct mic_intr_cb *intr_cb;
@@ -117,7 +130,8 @@ static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
if (!intr_cb)
return ERR_PTR(-ENOMEM);
- intr_cb->func = func;
+ intr_cb->handler = handler;
+ intr_cb->thread_fn = thread_fn;
intr_cb->data = data;
intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
0, 0, GFP_KERNEL);
@@ -126,9 +140,11 @@ static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
goto ida_fail;
}
+ spin_lock(&mdev->irq_info.mic_thread_lock);
spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+ spin_unlock(&mdev->irq_info.mic_thread_lock);
return intr_cb;
ida_fail:
@@ -152,8 +168,9 @@ static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
unsigned long flags;
int i;
+ spin_lock(&mdev->irq_info.mic_thread_lock);
+ spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
for (i = 0; i < MIC_NUM_OFFSETS; i++) {
- spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
intr_cb = list_entry(pos, struct mic_intr_cb, list);
if (intr_cb->cb_id == idx) {
@@ -163,11 +180,13 @@ static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
kfree(intr_cb);
spin_unlock_irqrestore(
&mdev->irq_info.mic_intr_lock, flags);
+ spin_unlock(&mdev->irq_info.mic_thread_lock);
return i;
}
}
- spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
}
+ spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+ spin_unlock(&mdev->irq_info.mic_thread_lock);
return MIC_NUM_OFFSETS;
}
@@ -242,6 +261,7 @@ static int mic_setup_callbacks(struct mic_device *mdev)
INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
ida_init(&mdev->irq_info.cb_ida);
spin_lock_init(&mdev->irq_info.mic_intr_lock);
+ spin_lock_init(&mdev->irq_info.mic_thread_lock);
return 0;
}
@@ -258,14 +278,12 @@ static void mic_release_callbacks(struct mic_device *mdev)
struct mic_intr_cb *intr_cb;
int i;
+ spin_lock(&mdev->irq_info.mic_thread_lock);
+ spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
for (i = 0; i < MIC_NUM_OFFSETS; i++) {
- spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
- if (list_empty(&mdev->irq_info.cb_list[i])) {
- spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
- flags);
+ if (list_empty(&mdev->irq_info.cb_list[i]))
break;
- }
list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
intr_cb = list_entry(pos, struct mic_intr_cb, list);
@@ -274,8 +292,9 @@ static void mic_release_callbacks(struct mic_device *mdev)
intr_cb->cb_id);
kfree(intr_cb);
}
- spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
}
+ spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
+ spin_unlock(&mdev->irq_info.mic_thread_lock);
ida_destroy(&mdev->irq_info.cb_ida);
kfree(mdev->irq_info.cb_list);
}
@@ -313,7 +332,8 @@ static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
goto err_nomem2;
}
- rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
+ rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
+ 0, "mic-msi", mdev);
if (rc) {
dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
goto err_irq_req_fail;
@@ -353,8 +373,8 @@ static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
goto err_nomem;
}
- rc = request_irq(pdev->irq, mic_interrupt,
- IRQF_SHARED, "mic-intx", mdev);
+ rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn,
+ IRQF_SHARED, "mic-intx", mdev);
if (rc)
goto err;
@@ -391,13 +411,14 @@ int mic_next_db(struct mic_device *mdev)
#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
/**
- * mic_request_irq - request an irq. mic_mutex needs
+ * mic_request_threaded_irq - request an irq. mic_mutex needs
* to be held before calling this function.
*
* @mdev: pointer to mic_device instance
- * @func: The callback function that handles the interrupt.
+ * @handler: The callback function that handles the interrupt.
* The function needs to call ack_interrupts
* (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
+ * @thread_fn: thread fn required by request_threaded_irq.
* @name: The ASCII name of the callee requesting the irq.
* @data: private data that is returned back when calling the
* function handler.
@@ -412,10 +433,11 @@ int mic_next_db(struct mic_device *mdev)
* error code.
*
*/
-struct mic_irq *mic_request_irq(struct mic_device *mdev,
- irqreturn_t (*func)(int irq, void *dev),
- const char *name, void *data, int intr_src,
- enum mic_intr_type type)
+struct mic_irq *
+mic_request_threaded_irq(struct mic_device *mdev,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ const char *name, void *data, int intr_src,
+ enum mic_intr_type type)
{
u16 offset;
int rc = 0;
@@ -444,7 +466,8 @@ struct mic_irq *mic_request_irq(struct mic_device *mdev,
goto err;
}
- rc = request_irq(msix->vector, func, 0, name, data);
+ rc = request_threaded_irq(msix->vector, handler, thread_fn,
+ 0, name, data);
if (rc) {
dev_dbg(mdev->sdev->parent,
"request irq failed rc = %d\n", rc);
@@ -458,8 +481,8 @@ struct mic_irq *mic_request_irq(struct mic_device *mdev,
dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
msix->vector, intr_src);
} else {
- intr_cb = mic_register_intr_callback(mdev,
- offset, func, data);
+ intr_cb = mic_register_intr_callback(mdev, offset, handler,
+ thread_fn, data);
if (IS_ERR(intr_cb)) {
dev_err(mdev->sdev->parent,
"No available callback entries for use\n");
@@ -487,9 +510,9 @@ err:
* needs to be held before calling this function.
*
* @mdev: pointer to mic_device instance
- * @cookie: cookie obtained during a successful call to mic_request_irq
+ * @cookie: cookie obtained during a successful call to mic_request_threaded_irq
* @data: private data specified by the calling function during the
- * mic_request_irq
+ * mic_request_threaded_irq
*
* returns: none.
*/
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h
index 6091aa97e116..9f783d4ad7f1 100644
--- a/drivers/misc/mic/host/mic_intr.h
+++ b/drivers/misc/mic/host/mic_intr.h
@@ -21,12 +21,15 @@
#ifndef _MIC_INTR_H_
#define _MIC_INTR_H_
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
/*
* The minimum number of msix vectors required for normal operation.
* 3 for virtio network, console and block devices.
* 1 for card shutdown notifications.
+ * 4 for host owned DMA channels.
*/
-#define MIC_MIN_MSIX 4
+#define MIC_MIN_MSIX 8
#define MIC_NUM_OFFSETS 32
/**
@@ -68,7 +71,11 @@ struct mic_intr_info {
* @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
* @cb_ida: callback ID allocator to track the callbacks registered.
* @mic_intr_lock: spinlock to protect the interrupt callback list.
+ * @mic_thread_lock: spinlock to protect the thread callback list.
+ * This lock is used to protect against thread_fn while
+ * mic_intr_lock is used to protect against interrupt handler.
* @cb_list: Array of callback lists one for each source.
+ * @mask: Mask used by the main thread fn to call the underlying thread fns.
*/
struct mic_irq_info {
int next_avail_src;
@@ -77,19 +84,23 @@ struct mic_irq_info {
u16 num_vectors;
struct ida cb_ida;
spinlock_t mic_intr_lock;
+ spinlock_t mic_thread_lock;
struct list_head *cb_list;
+ unsigned long mask;
};
/**
* struct mic_intr_cb - Interrupt callback structure.
*
- * @func: The callback function
+ * @handler: The callback function
+ * @thread_fn: The thread_fn.
* @data: Private data of the requester.
* @cb_id: The callback id. Identifies this callback.
* @list: list head pointing to the next callback structure.
*/
struct mic_intr_cb {
- irqreturn_t (*func) (int irq, void *data);
+ irq_handler_t handler;
+ irq_handler_t thread_fn;
void *data;
int cb_id;
struct list_head list;
@@ -124,11 +135,11 @@ struct mic_hw_intr_ops {
};
int mic_next_db(struct mic_device *mdev);
-struct mic_irq *mic_request_irq(struct mic_device *mdev,
- irqreturn_t (*func)(int irq, void *data),
- const char *name, void *data, int intr_src,
- enum mic_intr_type type);
-
+struct mic_irq *
+mic_request_threaded_irq(struct mic_device *mdev,
+ irq_handler_t handler, irq_handler_t thread_fn,
+ const char *name, void *data, int intr_src,
+ enum mic_intr_type type);
void mic_free_irq(struct mic_device *mdev,
struct mic_irq *cookie, void *data);
int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c
index c04a021e20c7..ab37a3117d23 100644
--- a/drivers/misc/mic/host/mic_main.c
+++ b/drivers/misc/mic/host/mic_main.c
@@ -38,7 +38,7 @@
static const char mic_driver_name[] = "mic";
-static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = {
+static const struct pci_device_id mic_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
@@ -389,8 +389,9 @@ static int mic_probe(struct pci_dev *pdev,
mutex_lock(&mdev->mic_mutex);
mdev->shutdown_db = mic_next_db(mdev);
- mdev->shutdown_cookie = mic_request_irq(mdev, mic_shutdown_db,
- "shutdown-interrupt", mdev, mdev->shutdown_db, MIC_INTR_DB);
+ mdev->shutdown_cookie = mic_request_threaded_irq(mdev, mic_shutdown_db,
+ NULL, "shutdown-interrupt", mdev,
+ mdev->shutdown_db, MIC_INTR_DB);
if (IS_ERR(mdev->shutdown_cookie)) {
rc = PTR_ERR(mdev->shutdown_cookie);
mutex_unlock(&mdev->mic_mutex);
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
index 7e1ef0ebbb80..a020e4eb435a 100644
--- a/drivers/misc/mic/host/mic_virtio.c
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -21,60 +21,157 @@
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
-
+#include <linux/dmaengine.h>
#include <linux/mic_common.h>
+
#include "../common/mic_dev.h"
#include "mic_device.h"
#include "mic_smpt.h"
#include "mic_virtio.h"
/*
- * Initiates the copies across the PCIe bus from card memory to
- * a user space buffer.
+ * Size of the internal buffer used during DMA's as an intermediate buffer
+ * for copy to/from user.
*/
-static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
- void __user *ubuf, size_t len, u64 addr)
+#define MIC_INT_DMA_BUF_SIZE PAGE_ALIGN(64 * 1024ULL)
+
+static int mic_sync_dma(struct mic_device *mdev, dma_addr_t dst,
+ dma_addr_t src, size_t len)
{
- int err;
- void __iomem *dbuf = mvdev->mdev->aper.va + addr;
- /*
- * We are copying from IO below an should ideally use something
- * like copy_to_user_fromio(..) if it existed.
- */
- if (copy_to_user(ubuf, (void __force *)dbuf, len)) {
- err = -EFAULT;
- dev_err(mic_dev(mvdev), "%s %d err %d\n",
+ int err = 0;
+ struct dma_async_tx_descriptor *tx;
+ struct dma_chan *mic_ch = mdev->dma_ch;
+
+ if (!mic_ch) {
+ err = -EBUSY;
+ goto error;
+ }
+
+ tx = mic_ch->device->device_prep_dma_memcpy(mic_ch, dst, src, len,
+ DMA_PREP_FENCE);
+ if (!tx) {
+ err = -ENOMEM;
+ goto error;
+ } else {
+ dma_cookie_t cookie = tx->tx_submit(tx);
+
+ err = dma_submit_error(cookie);
+ if (err)
+ goto error;
+ err = dma_sync_wait(mic_ch, cookie);
+ }
+error:
+ if (err)
+ dev_err(mdev->sdev->parent, "%s %d err %d\n",
__func__, __LINE__, err);
- goto err;
+ return err;
+}
+
+/*
+ * Initiates the copies across the PCIe bus from card memory to a user
+ * space buffer. When transfers are done using DMA, source/destination
+ * addresses and transfer length must follow the alignment requirements of
+ * the MIC DMA engine.
+ */
+static int mic_virtio_copy_to_user(struct mic_vdev *mvdev, void __user *ubuf,
+ size_t len, u64 daddr, size_t dlen,
+ int vr_idx)
+{
+ struct mic_device *mdev = mvdev->mdev;
+ void __iomem *dbuf = mdev->aper.va + daddr;
+ struct mic_vringh *mvr = &mvdev->mvr[vr_idx];
+ size_t dma_alignment = 1 << mdev->dma_ch->device->copy_align;
+ size_t dma_offset;
+ size_t partlen;
+ int err;
+
+ dma_offset = daddr - round_down(daddr, dma_alignment);
+ daddr -= dma_offset;
+ len += dma_offset;
+
+ while (len) {
+ partlen = min_t(size_t, len, MIC_INT_DMA_BUF_SIZE);
+
+ err = mic_sync_dma(mdev, mvr->buf_da, daddr,
+ ALIGN(partlen, dma_alignment));
+ if (err)
+ goto err;
+
+ if (copy_to_user(ubuf, mvr->buf + dma_offset,
+ partlen - dma_offset)) {
+ err = -EFAULT;
+ goto err;
+ }
+ daddr += partlen;
+ ubuf += partlen;
+ dbuf += partlen;
+ mvdev->in_bytes_dma += partlen;
+ mvdev->in_bytes += partlen;
+ len -= partlen;
+ dma_offset = 0;
}
- mvdev->in_bytes += len;
- err = 0;
+ return 0;
err:
+ dev_err(mic_dev(mvdev), "%s %d err %d\n", __func__, __LINE__, err);
return err;
}
/*
- * Initiates copies across the PCIe bus from a user space
- * buffer to card memory.
+ * Initiates copies across the PCIe bus from a user space buffer to card
+ * memory. When transfers are done using DMA, source/destination addresses
+ * and transfer length must follow the alignment requirements of the MIC
+ * DMA engine.
*/
-static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
- void __user *ubuf, size_t len, u64 addr)
+static int mic_virtio_copy_from_user(struct mic_vdev *mvdev, void __user *ubuf,
+ size_t len, u64 daddr, size_t dlen,
+ int vr_idx)
{
+ struct mic_device *mdev = mvdev->mdev;
+ void __iomem *dbuf = mdev->aper.va + daddr;
+ struct mic_vringh *mvr = &mvdev->mvr[vr_idx];
+ size_t dma_alignment = 1 << mdev->dma_ch->device->copy_align;
+ size_t partlen;
int err;
- void __iomem *dbuf = mvdev->mdev->aper.va + addr;
+
+ if (daddr & (dma_alignment - 1)) {
+ mvdev->tx_dst_unaligned += len;
+ goto memcpy;
+ } else if (ALIGN(len, dma_alignment) > dlen) {
+ mvdev->tx_len_unaligned += len;
+ goto memcpy;
+ }
+
+ while (len) {
+ partlen = min_t(size_t, len, MIC_INT_DMA_BUF_SIZE);
+
+ if (copy_from_user(mvr->buf, ubuf, partlen)) {
+ err = -EFAULT;
+ goto err;
+ }
+ err = mic_sync_dma(mdev, daddr, mvr->buf_da,
+ ALIGN(partlen, dma_alignment));
+ if (err)
+ goto err;
+ daddr += partlen;
+ ubuf += partlen;
+ dbuf += partlen;
+ mvdev->out_bytes_dma += partlen;
+ mvdev->out_bytes += partlen;
+ len -= partlen;
+ }
+memcpy:
/*
* We are copying to IO below and should ideally use something
* like copy_from_user_toio(..) if it existed.
*/
if (copy_from_user((void __force *)dbuf, ubuf, len)) {
err = -EFAULT;
- dev_err(mic_dev(mvdev), "%s %d err %d\n",
- __func__, __LINE__, err);
goto err;
}
mvdev->out_bytes += len;
- err = 0;
+ return 0;
err:
+ dev_err(mic_dev(mvdev), "%s %d err %d\n", __func__, __LINE__, err);
return err;
}
@@ -110,7 +207,8 @@ static inline u32 mic_vringh_iov_consumed(struct vringh_kiov *iov)
* way to override the VRINGH xfer(..) routines as of v3.10.
*/
static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
- void __user *ubuf, size_t len, bool read, size_t *out_len)
+ void __user *ubuf, size_t len, bool read, int vr_idx,
+ size_t *out_len)
{
int ret = 0;
size_t partlen, tot_len = 0;
@@ -118,13 +216,15 @@ static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
while (len && iov->i < iov->used) {
partlen = min(iov->iov[iov->i].iov_len, len);
if (read)
- ret = mic_virtio_copy_to_user(mvdev,
- ubuf, partlen,
- (u64)iov->iov[iov->i].iov_base);
+ ret = mic_virtio_copy_to_user(mvdev, ubuf, partlen,
+ (u64)iov->iov[iov->i].iov_base,
+ iov->iov[iov->i].iov_len,
+ vr_idx);
else
- ret = mic_virtio_copy_from_user(mvdev,
- ubuf, partlen,
- (u64)iov->iov[iov->i].iov_base);
+ ret = mic_virtio_copy_from_user(mvdev, ubuf, partlen,
+ (u64)iov->iov[iov->i].iov_base,
+ iov->iov[iov->i].iov_len,
+ vr_idx);
if (ret) {
dev_err(mic_dev(mvdev), "%s %d err %d\n",
__func__, __LINE__, ret);
@@ -192,8 +292,8 @@ static int _mic_virtio_copy(struct mic_vdev *mvdev,
ubuf = iov.iov_base;
}
/* Issue all the read descriptors first */
- ret = mic_vringh_copy(mvdev, riov, ubuf, len,
- MIC_VRINGH_READ, &out_len);
+ ret = mic_vringh_copy(mvdev, riov, ubuf, len, MIC_VRINGH_READ,
+ copy->vr_idx, &out_len);
if (ret) {
dev_err(mic_dev(mvdev), "%s %d err %d\n",
__func__, __LINE__, ret);
@@ -203,8 +303,8 @@ static int _mic_virtio_copy(struct mic_vdev *mvdev,
ubuf += out_len;
copy->out_len += out_len;
/* Issue the write descriptors next */
- ret = mic_vringh_copy(mvdev, wiov, ubuf, len,
- !MIC_VRINGH_READ, &out_len);
+ ret = mic_vringh_copy(mvdev, wiov, ubuf, len, !MIC_VRINGH_READ,
+ copy->vr_idx, &out_len);
if (ret) {
dev_err(mic_dev(mvdev), "%s %d err %d\n",
__func__, __LINE__, ret);
@@ -589,13 +689,19 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
dev_dbg(mdev->sdev->parent,
"%s %d index %d va %p info %p vr_size 0x%x\n",
__func__, __LINE__, i, vr->va, vr->info, vr_size);
+ mvr->buf = (void *)__get_free_pages(GFP_KERNEL,
+ get_order(MIC_INT_DMA_BUF_SIZE));
+ mvr->buf_da = mic_map_single(mvdev->mdev, mvr->buf,
+ MIC_INT_DMA_BUF_SIZE);
}
snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id,
mvdev->virtio_id);
mvdev->virtio_db = mic_next_db(mdev);
- mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler,
- irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB);
+ mvdev->virtio_cookie = mic_request_threaded_irq(mdev,
+ mic_virtio_intr_handler,
+ NULL, irqname, mvdev,
+ mvdev->virtio_db, MIC_INTR_DB);
if (IS_ERR(mvdev->virtio_cookie)) {
ret = PTR_ERR(mvdev->virtio_cookie);
dev_dbg(mdev->sdev->parent, "request irq failed\n");
@@ -671,6 +777,11 @@ skip_hot_remove:
vqconfig = mic_vq_config(mvdev->dd);
for (i = 0; i < mvdev->dd->num_vq; i++) {
struct mic_vringh *mvr = &mvdev->mvr[i];
+
+ mic_unmap_single(mvdev->mdev, mvr->buf_da,
+ MIC_INT_DMA_BUF_SIZE);
+ free_pages((unsigned long)mvr->buf,
+ get_order(MIC_INT_DMA_BUF_SIZE));
vringh_kiov_cleanup(&mvr->riov);
vringh_kiov_cleanup(&mvr->wiov);
mic_unmap_single(mdev, le64_to_cpu(vqconfig[i].address),
diff --git a/drivers/misc/mic/host/mic_virtio.h b/drivers/misc/mic/host/mic_virtio.h
index 184f3c84805b..d574efb853d9 100644
--- a/drivers/misc/mic/host/mic_virtio.h
+++ b/drivers/misc/mic/host/mic_virtio.h
@@ -46,18 +46,23 @@
* @vrh: The host VRINGH used for accessing the card vrings.
* @riov: The VRINGH read kernel IOV.
* @wiov: The VRINGH write kernel IOV.
- * @head: The VRINGH head index address passed to vringh_getdesc_kern(..).
* @vr_mutex: Mutex for synchronizing access to the VRING.
+ * @buf: Temporary kernel buffer used to copy in/out data
+ * from/to the card via DMA.
+ * @buf_da: dma address of buf.
* @mvdev: Back pointer to MIC virtio device for vringh_notify(..).
+ * @head: The VRINGH head index address passed to vringh_getdesc_kern(..).
*/
struct mic_vringh {
struct mic_vring vring;
struct vringh vrh;
struct vringh_kiov riov;
struct vringh_kiov wiov;
- u16 head;
struct mutex vr_mutex;
+ void *buf;
+ dma_addr_t buf_da;
struct mic_vdev *mvdev;
+ u16 head;
};
/**
@@ -69,6 +74,14 @@ struct mic_vringh {
* @poll_wake - Used for waking up threads blocked in poll.
* @out_bytes - Debug stats for number of bytes copied from host to card.
* @in_bytes - Debug stats for number of bytes copied from card to host.
+ * @out_bytes_dma - Debug stats for number of bytes copied from host to card
+ * using DMA.
+ * @in_bytes_dma - Debug stats for number of bytes copied from card to host
+ * using DMA.
+ * @tx_len_unaligned - Debug stats for number of bytes copied to the card where
+ * the transfer length did not have the required DMA alignment.
+ * @tx_dst_unaligned - Debug stats for number of bytes copied where the
+ * destination address on the card did not have the required DMA alignment.
* @mvr - Store per VRING data structures.
* @virtio_bh_work - Work struct used to schedule virtio bottom half handling.
* @dd - Virtio device descriptor.
@@ -84,6 +97,10 @@ struct mic_vdev {
int poll_wake;
unsigned long out_bytes;
unsigned long in_bytes;
+ unsigned long out_bytes_dma;
+ unsigned long in_bytes_dma;
+ unsigned long tx_len_unaligned;
+ unsigned long tx_dst_unaligned;
struct mic_vringh mvr[MIC_MAX_VRINGS];
struct work_struct virtio_bh_work;
struct mic_device_desc *dd;
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c
index 5562fdd3ef4e..b7a21e11dcdf 100644
--- a/drivers/misc/mic/host/mic_x100.c
+++ b/drivers/misc/mic/host/mic_x100.c
@@ -549,6 +549,13 @@ struct mic_smpt_ops mic_x100_smpt_ops = {
.set = mic_x100_smpt_set,
};
+static bool mic_x100_dma_filter(struct dma_chan *chan, void *param)
+{
+ if (chan->device->dev->parent == (struct device *)param)
+ return true;
+ return false;
+}
+
struct mic_hw_ops mic_x100_ops = {
.aper_bar = MIC_X100_APER_BAR,
.mmio_bar = MIC_X100_MMIO_BAR,
@@ -563,6 +570,7 @@ struct mic_hw_ops mic_x100_ops = {
.send_firmware_intr = mic_x100_send_firmware_intr,
.load_mic_fw = mic_x100_load_firmware,
.get_postcode = mic_x100_get_postcode,
+ .dma_filter = mic_x100_dma_filter,
};
struct mic_hw_intr_ops mic_x100_intr_ops = {
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 3fac67a5204c..557f9782c53c 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -544,7 +544,8 @@ xpnet_init(void)
* use ether_setup() to init the majority of our device
* structure and then override the necessary pieces.
*/
- xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, ether_setup);
+ xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, NET_NAME_UNKNOWN,
+ ether_setup);
if (xpnet_device == NULL) {
kfree(xpnet_broadcast_partitions);
return -ENOMEM;
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
index 9d3dbb28734b..21c2337bad68 100644
--- a/drivers/misc/ti-st/st_kim.c
+++ b/drivers/misc/ti-st/st_kim.c
@@ -244,7 +244,8 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
if (version & 0x8000)
maj_ver |= 0x0008;
- sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
+ sprintf(bts_scr_name, "ti-connectivity/TIInit_%d.%d.%d.bts",
+ chip, maj_ver, min_ver);
/* to be accessed later via sysfs entry */
kim_gdata->version.full = version;
@@ -287,7 +288,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)
long len = 0;
unsigned char *ptr = NULL;
unsigned char *action_ptr = NULL;
- unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
+ unsigned char bts_scr_name[40] = { 0 }; /* 40 char long bts scr name? */
int wr_room_space;
int cmd_size;
unsigned long timeout;
@@ -778,7 +779,7 @@ static int kim_probe(struct platform_device *pdev)
pr_info("sysfs entries created\n");
kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
- if (IS_ERR(kim_debugfs_dir)) {
+ if (!kim_debugfs_dir) {
pr_err(" debugfs entries creation failed ");
err = -EIO;
goto err_debugfs_dir;
@@ -788,7 +789,6 @@ static int kim_probe(struct platform_device *pdev)
kim_gdata, &version_debugfs_fops);
debugfs_create_file("protocols", S_IRUGO, kim_debugfs_dir,
kim_gdata, &list_debugfs_fops);
- pr_info(" debugfs entries created ");
return 0;
err_debugfs_dir:
diff --git a/drivers/misc/vexpress-syscfg.c b/drivers/misc/vexpress-syscfg.c
index 3250fc1df0aa..b3a812384a6f 100644
--- a/drivers/misc/vexpress-syscfg.c
+++ b/drivers/misc/vexpress-syscfg.c
@@ -130,7 +130,7 @@ static int vexpress_syscfg_write(void *context, unsigned int index,
return vexpress_syscfg_exec(func, index, true, &val);
}
-struct regmap_config vexpress_syscfg_regmap_config = {
+static struct regmap_config vexpress_syscfg_regmap_config = {
.lock = vexpress_config_lock,
.unlock = vexpress_config_unlock,
.reg_bits = 32,
@@ -276,7 +276,7 @@ int vexpress_syscfg_device_register(struct platform_device *pdev)
}
-int vexpress_syscfg_probe(struct platform_device *pdev)
+static int vexpress_syscfg_probe(struct platform_device *pdev)
{
struct vexpress_syscfg *syscfg;
struct resource *res;
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index e0d5017785e5..248399a881af 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -748,7 +748,7 @@ static void vmci_guest_remove_device(struct pci_dev *pdev)
/* The rest are managed resources and will be freed by PCI core */
}
-static DEFINE_PCI_DEVICE_TABLE(vmci_ids) = {
+static const struct pci_device_id vmci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_VMCI), },
{ 0 },
};
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index f5443a6c4915..9c9f6af29251 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -32,6 +32,7 @@
* (the low to high transition will not occur).
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
@@ -90,7 +91,7 @@ struct au1xmmc_host {
struct mmc_request *mrq;
u32 flags;
- u32 iobase;
+ void __iomem *iobase;
u32 clock;
u32 bus_width;
u32 power_mode;
@@ -118,6 +119,7 @@ struct au1xmmc_host {
struct au1xmmc_platform_data *platdata;
struct platform_device *pdev;
struct resource *ioarea;
+ struct clk *clk;
};
/* Status flags used by the host structure */
@@ -162,32 +164,33 @@ static inline int has_dbdma(void)
static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
{
- u32 val = au_readl(HOST_CONFIG(host));
+ u32 val = __raw_readl(HOST_CONFIG(host));
val |= mask;
- au_writel(val, HOST_CONFIG(host));
- au_sync();
+ __raw_writel(val, HOST_CONFIG(host));
+ wmb(); /* drain writebuffer */
}
static inline void FLUSH_FIFO(struct au1xmmc_host *host)
{
- u32 val = au_readl(HOST_CONFIG2(host));
+ u32 val = __raw_readl(HOST_CONFIG2(host));
- au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
- au_sync_delay(1);
+ __raw_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
+ mdelay(1);
/* SEND_STOP will turn off clock control - this re-enables it */
val &= ~SD_CONFIG2_DF;
- au_writel(val, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(val, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
}
static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
{
- u32 val = au_readl(HOST_CONFIG(host));
+ u32 val = __raw_readl(HOST_CONFIG(host));
val &= ~mask;
- au_writel(val, HOST_CONFIG(host));
- au_sync();
+ __raw_writel(val, HOST_CONFIG(host));
+ wmb(); /* drain writebuffer */
}
static inline void SEND_STOP(struct au1xmmc_host *host)
@@ -197,12 +200,13 @@ static inline void SEND_STOP(struct au1xmmc_host *host)
WARN_ON(host->status != HOST_S_DATA);
host->status = HOST_S_STOP;
- config2 = au_readl(HOST_CONFIG2(host));
- au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host));
- au_sync();
+ config2 = __raw_readl(HOST_CONFIG2(host));
+ __raw_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
/* Send the stop command */
- au_writel(STOP_CMD, HOST_CMD(host));
+ __raw_writel(STOP_CMD, HOST_CMD(host));
+ wmb(); /* drain writebuffer */
}
static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
@@ -296,28 +300,28 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
}
}
- au_writel(cmd->arg, HOST_CMDARG(host));
- au_sync();
+ __raw_writel(cmd->arg, HOST_CMDARG(host));
+ wmb(); /* drain writebuffer */
if (wait)
IRQ_OFF(host, SD_CONFIG_CR);
- au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
- au_sync();
+ __raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
+ wmb(); /* drain writebuffer */
/* Wait for the command to go on the line */
- while (au_readl(HOST_CMD(host)) & SD_CMD_GO)
+ while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO)
/* nop */;
/* Wait for the command to come back */
if (wait) {
- u32 status = au_readl(HOST_STATUS(host));
+ u32 status = __raw_readl(HOST_STATUS(host));
while (!(status & SD_STATUS_CR))
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
/* Clear the CR status */
- au_writel(SD_STATUS_CR, HOST_STATUS(host));
+ __raw_writel(SD_STATUS_CR, HOST_STATUS(host));
IRQ_ON(host, SD_CONFIG_CR);
}
@@ -339,11 +343,11 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
data = mrq->cmd->data;
if (status == 0)
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
/* The transaction is really over when the SD_STATUS_DB bit is clear */
while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
data->error = 0;
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
@@ -357,7 +361,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
data->error = -EILSEQ;
/* Clear the CRC bits */
- au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
+ __raw_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
data->bytes_xfered = 0;
@@ -380,7 +384,7 @@ static void au1xmmc_tasklet_data(unsigned long param)
{
struct au1xmmc_host *host = (struct au1xmmc_host *)param;
- u32 status = au_readl(HOST_STATUS(host));
+ u32 status = __raw_readl(HOST_STATUS(host));
au1xmmc_data_complete(host, status);
}
@@ -412,15 +416,15 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
max = AU1XMMC_MAX_TRANSFER;
for (count = 0; count < max; count++) {
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
if (!(status & SD_STATUS_TH))
break;
val = *sg_ptr++;
- au_writel((unsigned long)val, HOST_TXPORT(host));
- au_sync();
+ __raw_writel((unsigned long)val, HOST_TXPORT(host));
+ wmb(); /* drain writebuffer */
}
host->pio.len -= count;
@@ -472,7 +476,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
max = AU1XMMC_MAX_TRANSFER;
for (count = 0; count < max; count++) {
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
if (!(status & SD_STATUS_NE))
break;
@@ -494,7 +498,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
break;
}
- val = au_readl(HOST_RXPORT(host));
+ val = __raw_readl(HOST_RXPORT(host));
if (sg_ptr)
*sg_ptr++ = (unsigned char)(val & 0xFF);
@@ -537,10 +541,10 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136) {
- r[0] = au_readl(host->iobase + SD_RESP3);
- r[1] = au_readl(host->iobase + SD_RESP2);
- r[2] = au_readl(host->iobase + SD_RESP1);
- r[3] = au_readl(host->iobase + SD_RESP0);
+ r[0] = __raw_readl(host->iobase + SD_RESP3);
+ r[1] = __raw_readl(host->iobase + SD_RESP2);
+ r[2] = __raw_readl(host->iobase + SD_RESP1);
+ r[3] = __raw_readl(host->iobase + SD_RESP0);
/* The CRC is omitted from the response, so really
* we only got 120 bytes, but the engine expects
@@ -559,7 +563,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
* that means that the OSR data starts at bit 31,
* so we can just read RESP0 and return that.
*/
- cmd->resp[0] = au_readl(host->iobase + SD_RESP0);
+ cmd->resp[0] = __raw_readl(host->iobase + SD_RESP0);
}
}
@@ -586,7 +590,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
u32 mask = SD_STATUS_DB | SD_STATUS_NE;
while((status & mask) != mask)
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
}
au1xxx_dbdma_start(channel);
@@ -595,24 +599,17 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
{
- unsigned int pbus = get_au1x00_speed();
- unsigned int divisor;
+ unsigned int pbus = clk_get_rate(host->clk);
+ unsigned int divisor = ((pbus / rate) / 2) - 1;
u32 config;
- /* From databook:
- * divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1
- */
- pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2);
- pbus /= 2;
- divisor = ((pbus / rate) / 2) - 1;
-
- config = au_readl(HOST_CONFIG(host));
+ config = __raw_readl(HOST_CONFIG(host));
config &= ~(SD_CONFIG_DIV);
config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE;
- au_writel(config, HOST_CONFIG(host));
- au_sync();
+ __raw_writel(config, HOST_CONFIG(host));
+ wmb(); /* drain writebuffer */
}
static int au1xmmc_prepare_data(struct au1xmmc_host *host,
@@ -636,7 +633,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host,
if (host->dma.len == 0)
return -ETIMEDOUT;
- au_writel(data->blksz - 1, HOST_BLKSIZE(host));
+ __raw_writel(data->blksz - 1, HOST_BLKSIZE(host));
if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) {
int i;
@@ -723,31 +720,34 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
static void au1xmmc_reset_controller(struct au1xmmc_host *host)
{
/* Apply the clock */
- au_writel(SD_ENABLE_CE, HOST_ENABLE(host));
- au_sync_delay(1);
+ __raw_writel(SD_ENABLE_CE, HOST_ENABLE(host));
+ wmb(); /* drain writebuffer */
+ mdelay(1);
- au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
- au_sync_delay(5);
+ __raw_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
+ wmb(); /* drain writebuffer */
+ mdelay(5);
- au_writel(~0, HOST_STATUS(host));
- au_sync();
+ __raw_writel(~0, HOST_STATUS(host));
+ wmb(); /* drain writebuffer */
- au_writel(0, HOST_BLKSIZE(host));
- au_writel(0x001fffff, HOST_TIMEOUT(host));
- au_sync();
+ __raw_writel(0, HOST_BLKSIZE(host));
+ __raw_writel(0x001fffff, HOST_TIMEOUT(host));
+ wmb(); /* drain writebuffer */
- au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
- au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
- au_sync_delay(1);
+ __raw_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
+ mdelay(1);
- au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
/* Configure interrupts */
- au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
- au_sync();
+ __raw_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
+ wmb(); /* drain writebuffer */
}
@@ -767,7 +767,7 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
host->clock = ios->clock;
}
- config2 = au_readl(HOST_CONFIG2(host));
+ config2 = __raw_readl(HOST_CONFIG2(host));
switch (ios->bus_width) {
case MMC_BUS_WIDTH_8:
config2 |= SD_CONFIG2_BB;
@@ -780,8 +780,8 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB);
break;
}
- au_writel(config2, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(config2, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
}
#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
@@ -793,7 +793,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
struct au1xmmc_host *host = dev_id;
u32 status;
- status = au_readl(HOST_STATUS(host));
+ status = __raw_readl(HOST_STATUS(host));
if (!(status & SD_STATUS_I))
return IRQ_NONE; /* not ours */
@@ -839,8 +839,8 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
status);
}
- au_writel(status, HOST_STATUS(host));
- au_sync();
+ __raw_writel(status, HOST_STATUS(host));
+ wmb(); /* drain writebuffer */
return IRQ_HANDLED;
}
@@ -976,7 +976,7 @@ static int au1xmmc_probe(struct platform_device *pdev)
goto out1;
}
- host->iobase = (unsigned long)ioremap(r->start, 0x3c);
+ host->iobase = ioremap(r->start, 0x3c);
if (!host->iobase) {
dev_err(&pdev->dev, "cannot remap mmio\n");
goto out2;
@@ -1025,6 +1025,16 @@ static int au1xmmc_probe(struct platform_device *pdev)
goto out3;
}
+ host->clk = clk_get(&pdev->dev, ALCHEMY_PERIPH_CLK);
+ if (IS_ERR(host->clk)) {
+ dev_err(&pdev->dev, "cannot find clock\n");
+ goto out_irq;
+ }
+ if (clk_prepare_enable(host->clk)) {
+ dev_err(&pdev->dev, "cannot enable clock\n");
+ goto out_clk;
+ }
+
host->status = HOST_S_IDLE;
/* board-specific carddetect setup, if any */
@@ -1075,7 +1085,7 @@ static int au1xmmc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
- pr_info(DRIVER_NAME ": MMC Controller %d set up at %8.8X"
+ pr_info(DRIVER_NAME ": MMC Controller %d set up at %p"
" (mode=%s)\n", pdev->id, host->iobase,
host->flags & HOST_F_DMA ? "dma" : "pio");
@@ -1087,10 +1097,10 @@ out6:
led_classdev_unregister(host->platdata->led);
out5:
#endif
- au_writel(0, HOST_ENABLE(host));
- au_writel(0, HOST_CONFIG(host));
- au_writel(0, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(0, HOST_ENABLE(host));
+ __raw_writel(0, HOST_CONFIG(host));
+ __raw_writel(0, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
if (host->flags & HOST_F_DBDMA)
au1xmmc_dbdma_shutdown(host);
@@ -1101,7 +1111,10 @@ out5:
if (host->platdata && host->platdata->cd_setup &&
!(mmc->caps & MMC_CAP_NEEDS_POLL))
host->platdata->cd_setup(mmc, 0);
-
+out_clk:
+ clk_disable_unprepare(host->clk);
+ clk_put(host->clk);
+out_irq:
free_irq(host->irq, host);
out3:
iounmap((void *)host->iobase);
@@ -1130,10 +1143,10 @@ static int au1xmmc_remove(struct platform_device *pdev)
!(host->mmc->caps & MMC_CAP_NEEDS_POLL))
host->platdata->cd_setup(host->mmc, 0);
- au_writel(0, HOST_ENABLE(host));
- au_writel(0, HOST_CONFIG(host));
- au_writel(0, HOST_CONFIG2(host));
- au_sync();
+ __raw_writel(0, HOST_ENABLE(host));
+ __raw_writel(0, HOST_CONFIG(host));
+ __raw_writel(0, HOST_CONFIG2(host));
+ wmb(); /* drain writebuffer */
tasklet_kill(&host->data_task);
tasklet_kill(&host->finish_task);
@@ -1143,6 +1156,9 @@ static int au1xmmc_remove(struct platform_device *pdev)
au1xmmc_set_power(host, 0);
+ clk_disable_unprepare(host->clk);
+ clk_put(host->clk);
+
free_irq(host->irq, host);
iounmap((void *)host->iobase);
release_resource(host->ioarea);
@@ -1158,11 +1174,11 @@ static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state)
{
struct au1xmmc_host *host = platform_get_drvdata(pdev);
- au_writel(0, HOST_CONFIG2(host));
- au_writel(0, HOST_CONFIG(host));
- au_writel(0xffffffff, HOST_STATUS(host));
- au_writel(0, HOST_ENABLE(host));
- au_sync();
+ __raw_writel(0, HOST_CONFIG2(host));
+ __raw_writel(0, HOST_CONFIG(host));
+ __raw_writel(0xffffffff, HOST_STATUS(host));
+ __raw_writel(0, HOST_ENABLE(host));
+ wmb(); /* drain writebuffer */
return 0;
}
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 0d519649b575..dfde4a210238 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -24,6 +24,7 @@
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/workqueue.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
@@ -36,7 +37,10 @@ struct realtek_pci_sdmmc {
struct rtsx_pcr *pcr;
struct mmc_host *mmc;
struct mmc_request *mrq;
+ struct workqueue_struct *workq;
+#define SDMMC_WORKQ_NAME "rtsx_pci_sdmmc_workq"
+ struct work_struct work;
struct mutex host_mutex;
u8 ssc_depth;
@@ -48,6 +52,11 @@ struct realtek_pci_sdmmc {
int power_state;
#define SDMMC_POWER_ON 1
#define SDMMC_POWER_OFF 0
+
+ unsigned int sg_count;
+ s32 cookie;
+ unsigned int cookie_sg_count;
+ bool using_cookie;
};
static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
@@ -86,6 +95,77 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
#define sd_print_debug_regs(host)
#endif /* DEBUG */
+/*
+ * sd_pre_dma_transfer - do dma_map_sg() or using cookie
+ *
+ * @pre: if called in pre_req()
+ * return:
+ * 0 - do dma_map_sg()
+ * 1 - using cookie
+ */
+static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host,
+ struct mmc_data *data, bool pre)
+{
+ struct rtsx_pcr *pcr = host->pcr;
+ int read = data->flags & MMC_DATA_READ;
+ int count = 0;
+ int using_cookie = 0;
+
+ if (!pre && data->host_cookie && data->host_cookie != host->cookie) {
+ dev_err(sdmmc_dev(host),
+ "error: data->host_cookie = %d, host->cookie = %d\n",
+ data->host_cookie, host->cookie);
+ data->host_cookie = 0;
+ }
+
+ if (pre || data->host_cookie != host->cookie) {
+ count = rtsx_pci_dma_map_sg(pcr, data->sg, data->sg_len, read);
+ } else {
+ count = host->cookie_sg_count;
+ using_cookie = 1;
+ }
+
+ if (pre) {
+ host->cookie_sg_count = count;
+ if (++host->cookie < 0)
+ host->cookie = 1;
+ data->host_cookie = host->cookie;
+ } else {
+ host->sg_count = count;
+ }
+
+ return using_cookie;
+}
+
+static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
+ bool is_first_req)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct mmc_data *data = mrq->data;
+
+ if (data->host_cookie) {
+ dev_err(sdmmc_dev(host),
+ "error: reset data->host_cookie = %d\n",
+ data->host_cookie);
+ data->host_cookie = 0;
+ }
+
+ sd_pre_dma_transfer(host, data, true);
+ dev_dbg(sdmmc_dev(host), "pre dma sg: %d\n", host->cookie_sg_count);
+}
+
+static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
+ int err)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ struct mmc_data *data = mrq->data;
+ int read = data->flags & MMC_DATA_READ;
+
+ rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read);
+ data->host_cookie = 0;
+}
+
static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt,
u8 *buf, int buf_len, int timeout)
{
@@ -415,7 +495,7 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq)
rtsx_pci_send_cmd_no_wait(pcr);
- err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000);
+ err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read, 10000);
if (err < 0) {
sd_clear_error(host);
return err;
@@ -640,12 +720,24 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode)
return 0;
}
-static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+static inline int sd_rw_cmd(struct mmc_command *cmd)
{
- struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ return mmc_op_multi(cmd->opcode) ||
+ (cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
+ (cmd->opcode == MMC_WRITE_BLOCK);
+}
+
+static void sd_request(struct work_struct *work)
+{
+ struct realtek_pci_sdmmc *host = container_of(work,
+ struct realtek_pci_sdmmc, work);
struct rtsx_pcr *pcr = host->pcr;
+
+ struct mmc_host *mmc = host->mmc;
+ struct mmc_request *mrq = host->mrq;
struct mmc_command *cmd = mrq->cmd;
struct mmc_data *data = mrq->data;
+
unsigned int data_size = 0;
int err;
@@ -677,13 +769,13 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
if (mrq->data)
data_size = data->blocks * data->blksz;
- if (!data_size || mmc_op_multi(cmd->opcode) ||
- (cmd->opcode == MMC_READ_SINGLE_BLOCK) ||
- (cmd->opcode == MMC_WRITE_BLOCK)) {
+ if (!data_size || sd_rw_cmd(cmd)) {
sd_send_cmd_get_rsp(host, cmd);
if (!cmd->error && data_size) {
sd_rw_multi(host, mrq);
+ if (!host->using_cookie)
+ sdmmc_post_req(host->mmc, host->mrq, 0);
if (mmc_op_multi(cmd->opcode) && mrq->stop)
sd_send_cmd_get_rsp(host, mrq->stop);
@@ -712,6 +804,21 @@ finish:
mmc_request_done(mmc, mrq);
}
+static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct mmc_data *data = mrq->data;
+
+ mutex_lock(&host->host_mutex);
+ host->mrq = mrq;
+ mutex_unlock(&host->host_mutex);
+
+ if (sd_rw_cmd(mrq->cmd))
+ host->using_cookie = sd_pre_dma_transfer(host, data, false);
+
+ queue_work(host->workq, &host->work);
+}
+
static int sd_set_bus_width(struct realtek_pci_sdmmc *host,
unsigned char bus_width)
{
@@ -1146,6 +1253,8 @@ out:
}
static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
+ .pre_req = sdmmc_pre_req,
+ .post_req = sdmmc_post_req,
.request = sdmmc_request,
.set_ios = sdmmc_set_ios,
.get_ro = sdmmc_get_ro,
@@ -1224,10 +1333,16 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
return -ENOMEM;
host = mmc_priv(mmc);
+ host->workq = create_singlethread_workqueue(SDMMC_WORKQ_NAME);
+ if (!host->workq) {
+ mmc_free_host(mmc);
+ return -ENOMEM;
+ }
host->pcr = pcr;
host->mmc = mmc;
host->pdev = pdev;
host->power_state = SDMMC_POWER_OFF;
+ INIT_WORK(&host->work, sd_request);
platform_set_drvdata(pdev, host);
pcr->slots[RTSX_SD_CARD].p_dev = pdev;
pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event;
@@ -1255,6 +1370,8 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
pcr->slots[RTSX_SD_CARD].card_event = NULL;
mmc = host->mmc;
+ cancel_work_sync(&host->work);
+
mutex_lock(&host->host_mutex);
if (host->mrq) {
dev_dbg(&(pdev->dev),
@@ -1273,6 +1390,10 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev)
mmc_remove_host(mmc);
host->eject = true;
+ flush_workqueue(host->workq);
+ destroy_workqueue(host->workq);
+ host->workq = NULL;
+
mmc_free_host(mmc);
dev_dbg(&(pdev->dev),
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index e4ec355704a6..a7543ba3e190 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -52,6 +52,11 @@
/* Atmel chips */
#define AT49BV640D 0x02de
#define AT49BV640DT 0x02db
+/* Sharp chips */
+#define LH28F640BFHE_PTTL90 0x00b0
+#define LH28F640BFHE_PBTL90 0x00b1
+#define LH28F640BFHE_PTTL70A 0x00b2
+#define LH28F640BFHE_PBTL70A 0x00b3
static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -258,6 +263,36 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd)
(cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
};
+static int is_LH28F640BF(struct cfi_private *cfi)
+{
+ /* Sharp LH28F640BF Family */
+ if (cfi->mfr == CFI_MFR_SHARP && (
+ cfi->id == LH28F640BFHE_PTTL90 || cfi->id == LH28F640BFHE_PBTL90 ||
+ cfi->id == LH28F640BFHE_PTTL70A || cfi->id == LH28F640BFHE_PBTL70A))
+ return 1;
+ return 0;
+}
+
+static void fixup_LH28F640BF(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ struct cfi_pri_intelext *extp = cfi->cmdset_priv;
+
+ /* Reset the Partition Configuration Register on LH28F640BF
+ * to a single partition (PCR = 0x000): PCR is embedded into A0-A15. */
+ if (is_LH28F640BF(cfi)) {
+ printk(KERN_INFO "Reset Partition Config. Register: 1 Partition of 4 planes\n");
+ map_write(map, CMD(0x60), 0);
+ map_write(map, CMD(0x04), 0);
+
+ /* We have set one single partition thus
+ * Simultaneous Operations are not allowed */
+ printk(KERN_INFO "cfi_cmdset_0001: Simultaneous Operations disabled\n");
+ extp->FeatureSupport &= ~512;
+ }
+}
+
static void fixup_use_point(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
@@ -309,6 +344,8 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct },
{ CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb },
{ CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock },
+ { CFI_MFR_SHARP, CFI_ID_ANY, fixup_unlock_powerup_lock },
+ { CFI_MFR_SHARP, CFI_ID_ANY, fixup_LH28F640BF },
{ 0, 0, NULL }
};
@@ -1649,6 +1686,12 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
initial_adr = adr;
cmd_adr = adr & ~(wbufsize-1);
+ /* Sharp LH28F640BF chips need the first address for the
+ * Page Buffer Program command. See Table 5 of
+ * LH28F320BF, LH28F640BF, LH28F128BF Series (Appendix FUM00701) */
+ if (is_LH28F640BF(cfi))
+ cmd_adr = adr;
+
/* Let's determine this according to the interleave only once */
write_cmd = (cfi->cfiq->P_ID != P_ID_INTEL_PERFORMANCE) ? CMD(0xe8) : CMD(0xe9);
diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
index 7df86948e6d4..b4f61c7fc161 100644
--- a/drivers/mtd/devices/elm.c
+++ b/drivers/mtd/devices/elm.c
@@ -475,6 +475,7 @@ static int elm_context_save(struct elm_info *info)
ELM_SYNDROME_FRAGMENT_1 + offset);
regs->elm_syndrome_fragment_0[i] = elm_read_reg(info,
ELM_SYNDROME_FRAGMENT_0 + offset);
+ break;
default:
return -EINVAL;
}
@@ -520,6 +521,7 @@ static int elm_context_restore(struct elm_info *info)
regs->elm_syndrome_fragment_1[i]);
elm_write_reg(info, ELM_SYNDROME_FRAGMENT_0 + offset,
regs->elm_syndrome_fragment_0[i]);
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index bc5c518828d2..77d6c17b38c2 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -41,7 +41,7 @@ static u_char au_read_byte(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
u_char ret = readb(this->IO_ADDR_R);
- au_sync();
+ wmb(); /* drain writebuffer */
return ret;
}
@@ -56,7 +56,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
{
struct nand_chip *this = mtd->priv;
writeb(byte, this->IO_ADDR_W);
- au_sync();
+ wmb(); /* drain writebuffer */
}
/**
@@ -69,7 +69,7 @@ static u_char au_read_byte16(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R));
- au_sync();
+ wmb(); /* drain writebuffer */
return ret;
}
@@ -84,7 +84,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
{
struct nand_chip *this = mtd->priv;
writew(le16_to_cpu((u16) byte), this->IO_ADDR_W);
- au_sync();
+ wmb(); /* drain writebuffer */
}
/**
@@ -97,7 +97,7 @@ static u16 au_read_word(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
u16 ret = readw(this->IO_ADDR_R);
- au_sync();
+ wmb(); /* drain writebuffer */
return ret;
}
@@ -116,7 +116,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
for (i = 0; i < len; i++) {
writeb(buf[i], this->IO_ADDR_W);
- au_sync();
+ wmb(); /* drain writebuffer */
}
}
@@ -135,7 +135,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
for (i = 0; i < len; i++) {
buf[i] = readb(this->IO_ADDR_R);
- au_sync();
+ wmb(); /* drain writebuffer */
}
}
@@ -156,7 +156,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
for (i = 0; i < len; i++) {
writew(p[i], this->IO_ADDR_W);
- au_sync();
+ wmb(); /* drain writebuffer */
}
}
@@ -178,7 +178,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
for (i = 0; i < len; i++) {
p[i] = readw(this->IO_ADDR_R);
- au_sync();
+ wmb(); /* drain writebuffer */
}
}
@@ -223,26 +223,23 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
case NAND_CTL_SETNCE:
/* assert (force assert) chip enable */
- au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL);
+ alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL);
break;
case NAND_CTL_CLRNCE:
/* deassert chip enable */
- au_writel(0, MEM_STNDCTL);
+ alchemy_wrsmem(0, AU1000_MEM_STNDCTL);
break;
}
this->IO_ADDR_R = this->IO_ADDR_W;
- /* Drain the writebuffer */
- au_sync();
+ wmb(); /* Drain the writebuffer */
}
int au1550_device_ready(struct mtd_info *mtd)
{
- int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0;
- au_sync();
- return ret;
+ return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0;
}
/**
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 41167e9e991e..4f3e80c68a26 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -4047,8 +4047,10 @@ int nand_scan_tail(struct mtd_info *mtd)
ecc->layout->oobavail += ecc->layout->oobfree[i].length;
mtd->oobavail = ecc->layout->oobavail;
- /* ECC sanity check: warn noisily if it's too weak */
- WARN_ON(!nand_ecc_strength_good(mtd));
+ /* ECC sanity check: warn if it's too weak */
+ if (!nand_ecc_strength_good(mtd))
+ pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
+ mtd->name);
/*
* Set the number of read / write steps for one page depending on ECC
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index ab2607273e80..dcae2f6a2b11 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -32,10 +32,10 @@ config MTD_ONENAND_OMAP2
config MTD_ONENAND_SAMSUNG
tristate "OneNAND on Samsung SOC controller support"
- depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4
+ depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS4
help
Support for a OneNAND flash device connected to an Samsung SOC.
- S3C64XX/S5PC100 use command mapping method.
+ S3C64XX uses command mapping method.
S5PC110/S5PC210 use generic OneNAND method.
config MTD_ONENAND_OTP
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index efb819c3df2f..19cfb97adbc0 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -10,7 +10,7 @@
* published by the Free Software Foundation.
*
* Implementation:
- * S3C64XX and S5PC100: emulate the pseudo BufferRAM
+ * S3C64XX: emulate the pseudo BufferRAM
* S5PC110: use DMA
*/
@@ -32,7 +32,6 @@
enum soc_type {
TYPE_S3C6400,
TYPE_S3C6410,
- TYPE_S5PC100,
TYPE_S5PC110,
};
@@ -59,7 +58,6 @@ enum soc_type {
#define MAP_11 (0x3)
#define S3C64XX_CMD_MAP_SHIFT 24
-#define S5PC100_CMD_MAP_SHIFT 26
#define S3C6400_FBA_SHIFT 10
#define S3C6400_FPA_SHIFT 4
@@ -69,10 +67,6 @@ enum soc_type {
#define S3C6410_FPA_SHIFT 6
#define S3C6410_FSA_SHIFT 4
-#define S5PC100_FBA_SHIFT 13
-#define S5PC100_FPA_SHIFT 7
-#define S5PC100_FSA_SHIFT 5
-
/* S5PC110 specific definitions */
#define S5PC110_DMA_SRC_ADDR 0x400
#define S5PC110_DMA_SRC_CFG 0x404
@@ -195,11 +189,6 @@ static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val)
return (type << S3C64XX_CMD_MAP_SHIFT) | val;
}
-static unsigned int s5pc1xx_cmd_map(unsigned type, unsigned val)
-{
- return (type << S5PC100_CMD_MAP_SHIFT) | val;
-}
-
static unsigned int s3c6400_mem_addr(int fba, int fpa, int fsa)
{
return (fba << S3C6400_FBA_SHIFT) | (fpa << S3C6400_FPA_SHIFT) |
@@ -212,12 +201,6 @@ static unsigned int s3c6410_mem_addr(int fba, int fpa, int fsa)
(fsa << S3C6410_FSA_SHIFT);
}
-static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa)
-{
- return (fba << S5PC100_FBA_SHIFT) | (fpa << S5PC100_FPA_SHIFT) |
- (fsa << S5PC100_FSA_SHIFT);
-}
-
static void s3c_onenand_reset(void)
{
unsigned long timeout = 0x10000;
@@ -835,9 +818,6 @@ static void s3c_onenand_setup(struct mtd_info *mtd)
} else if (onenand->type == TYPE_S3C6410) {
onenand->mem_addr = s3c6410_mem_addr;
onenand->cmd_map = s3c64xx_cmd_map;
- } else if (onenand->type == TYPE_S5PC100) {
- onenand->mem_addr = s5pc100_mem_addr;
- onenand->cmd_map = s5pc1xx_cmd_map;
} else if (onenand->type == TYPE_S5PC110) {
/* Use generic onenand functions */
this->read_bufferram = s5pc110_read_bufferram;
@@ -1111,9 +1091,6 @@ static struct platform_device_id s3c_onenand_driver_ids[] = {
.name = "s3c6410-onenand",
.driver_data = TYPE_S3C6410,
}, {
- .name = "s5pc100-onenand",
- .driver_data = TYPE_S5PC100,
- }, {
.name = "s5pc110-onenand",
.driver_data = TYPE_S5PC110,
}, { },
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index b04e7d059888..0431b46d9fd9 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -125,7 +125,7 @@ static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
parent = *p;
av = rb_entry(parent, struct ubi_ainf_volume, rb);
- if (vol_id < av->vol_id)
+ if (vol_id > av->vol_id)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -423,7 +423,7 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
pnum, err);
ret = err > 0 ? UBI_BAD_FASTMAP : err;
goto out;
- } else if (ret == UBI_IO_BITFLIPS)
+ } else if (err == UBI_IO_BITFLIPS)
scrub = 1;
/*
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 89402c3b64f8..c6f6f69f8961 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -148,6 +148,7 @@ config VXLAN
tristate "Virtual eXtensible Local Area Network (VXLAN)"
depends on INET
select NET_IP_TUNNEL
+ select NET_UDP_TUNNEL
---help---
This allows one to create vxlan virtual interfaces that provide
Layer 2 Networks over Layer 3 Networks. VXLAN is often used
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3fef8a81c0f6..61aefdd1e173 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -61,15 +61,7 @@ obj-$(CONFIG_VMXNET3) += vmxnet3/
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
obj-$(CONFIG_XEN_NETDEV_BACKEND) += xen-netback/
-obj-$(CONFIG_USB_CATC) += usb/
-obj-$(CONFIG_USB_KAWETH) += usb/
-obj-$(CONFIG_USB_PEGASUS) += usb/
-obj-$(CONFIG_USB_RTL8150) += usb/
-obj-$(CONFIG_USB_HSO) += usb/
-obj-$(CONFIG_USB_USBNET) += usb/
-obj-$(CONFIG_USB_ZD1201) += usb/
-obj-$(CONFIG_USB_IPHETH) += usb/
-obj-$(CONFIG_USB_CDC_PHONET) += usb/
+obj-$(CONFIG_USB_NET_DRIVERS) += usb/
obj-$(CONFIG_HYPERV_NET) += hyperv/
obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index a956053608f9..3b790de6c976 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -346,7 +346,8 @@ struct net_device *alloc_arcdev(const char *name)
struct net_device *dev;
dev = alloc_netdev(sizeof(struct arcnet_local),
- name && *name ? name : "arc%d", arcdev_setup);
+ name && *name ? name : "arc%d", NET_NAME_UNKNOWN,
+ arcdev_setup);
if(dev) {
struct arcnet_local *lp = netdev_priv(dev);
spin_lock_init(&lp->lock);
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 0dfeaf5da3f2..ee2c73a9de39 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -20,8 +20,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>
@@ -301,8 +299,8 @@ static u16 __get_link_speed(struct port *port)
}
}
- pr_debug("Port %d Received link speed %d update from adapter\n",
- port->actor_port_number, speed);
+ netdev_dbg(slave->bond->dev, "Port %d Received link speed %d update from adapter\n",
+ port->actor_port_number, speed);
return speed;
}
@@ -329,14 +327,14 @@ static u8 __get_duplex(struct port *port)
switch (slave->duplex) {
case DUPLEX_FULL:
retval = 0x1;
- pr_debug("Port %d Received status full duplex update from adapter\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Port %d Received status full duplex update from adapter\n",
+ port->actor_port_number);
break;
case DUPLEX_HALF:
default:
retval = 0x0;
- pr_debug("Port %d Received status NOT full duplex update from adapter\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Port %d Received status NOT full duplex update from adapter\n",
+ port->actor_port_number);
break;
}
}
@@ -1079,9 +1077,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
/* detect loopback situation */
if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system),
&(port->actor_system))) {
- pr_err("%s: An illegal loopback occurred on adapter (%s)\n"
+ netdev_err(port->slave->bond->dev, "An illegal loopback occurred on adapter (%s)\n"
"Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
- port->slave->bond->dev->name,
port->slave->dev->name);
return;
}
@@ -1269,9 +1266,9 @@ static void ad_port_selection_logic(struct port *port)
port->next_port_in_aggregator = NULL;
port->actor_port_aggregator_identifier = 0;
- pr_debug("Port %d left LAG %d\n",
- port->actor_port_number,
- temp_aggregator->aggregator_identifier);
+ netdev_dbg(bond->dev, "Port %d left LAG %d\n",
+ port->actor_port_number,
+ temp_aggregator->aggregator_identifier);
/* if the aggregator is empty, clear its
* parameters, and set it ready to be attached
*/
@@ -1284,11 +1281,11 @@ static void ad_port_selection_logic(struct port *port)
/* meaning: the port was related to an aggregator
* but was not on the aggregator port list
*/
- pr_warn_ratelimited("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
- port->slave->bond->dev->name,
- port->actor_port_number,
- port->slave->dev->name,
- port->aggregator->aggregator_identifier);
+ net_warn_ratelimited("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
+ port->slave->bond->dev->name,
+ port->actor_port_number,
+ port->slave->dev->name,
+ port->aggregator->aggregator_identifier);
}
}
/* search on all aggregators for a suitable aggregator for this port */
@@ -1318,9 +1315,9 @@ static void ad_port_selection_logic(struct port *port)
port->next_port_in_aggregator = aggregator->lag_ports;
port->aggregator->num_of_ports++;
aggregator->lag_ports = port;
- pr_debug("Port %d joined LAG %d(existing LAG)\n",
- port->actor_port_number,
- port->aggregator->aggregator_identifier);
+ netdev_dbg(bond->dev, "Port %d joined LAG %d(existing LAG)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
/* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
@@ -1363,12 +1360,11 @@ static void ad_port_selection_logic(struct port *port)
/* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
- pr_debug("Port %d joined LAG %d(new LAG)\n",
- port->actor_port_number,
- port->aggregator->aggregator_identifier);
+ netdev_dbg(bond->dev, "Port %d joined LAG %d(new LAG)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
} else {
- pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n",
- port->slave->bond->dev->name,
+ netdev_err(bond->dev, "Port %d (on %s) did not find a suitable aggregator\n",
port->actor_port_number, port->slave->dev->name);
}
}
@@ -1445,9 +1441,9 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best,
break;
default:
- pr_warn_ratelimited("%s: Impossible agg select mode %d\n",
- curr->slave->bond->dev->name,
- __get_agg_selection_mode(curr->lag_ports));
+ net_warn_ratelimited("%s: Impossible agg select mode %d\n",
+ curr->slave->bond->dev->name,
+ __get_agg_selection_mode(curr->lag_ports));
break;
}
@@ -1539,40 +1535,40 @@ static void ad_agg_selection_logic(struct aggregator *agg)
/* if there is new best aggregator, activate it */
if (best) {
- pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
- best->aggregator_identifier, best->num_of_ports,
- best->actor_oper_aggregator_key,
- best->partner_oper_aggregator_key,
- best->is_individual, best->is_active);
- pr_debug("best ports %p slave %p %s\n",
- best->lag_ports, best->slave,
- best->slave ? best->slave->dev->name : "NULL");
+ netdev_dbg(bond->dev, "best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ best->aggregator_identifier, best->num_of_ports,
+ best->actor_oper_aggregator_key,
+ best->partner_oper_aggregator_key,
+ best->is_individual, best->is_active);
+ netdev_dbg(bond->dev, "best ports %p slave %p %s\n",
+ best->lag_ports, best->slave,
+ best->slave ? best->slave->dev->name : "NULL");
bond_for_each_slave_rcu(bond, slave, iter) {
agg = &(SLAVE_AD_INFO(slave)->aggregator);
- pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
- agg->aggregator_identifier, agg->num_of_ports,
- agg->actor_oper_aggregator_key,
- agg->partner_oper_aggregator_key,
- agg->is_individual, agg->is_active);
+ netdev_dbg(bond->dev, "Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ agg->aggregator_identifier, agg->num_of_ports,
+ agg->actor_oper_aggregator_key,
+ agg->partner_oper_aggregator_key,
+ agg->is_individual, agg->is_active);
}
/* check if any partner replys */
if (best->is_individual) {
- pr_warn_ratelimited("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
- best->slave ?
- best->slave->bond->dev->name : "NULL");
+ net_warn_ratelimited("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
+ best->slave ?
+ best->slave->bond->dev->name : "NULL");
}
best->is_active = 1;
- pr_debug("LAG %d chosen as the active LAG\n",
- best->aggregator_identifier);
- pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
- best->aggregator_identifier, best->num_of_ports,
- best->actor_oper_aggregator_key,
- best->partner_oper_aggregator_key,
- best->is_individual, best->is_active);
+ netdev_dbg(bond->dev, "LAG %d chosen as the active LAG\n",
+ best->aggregator_identifier);
+ netdev_dbg(bond->dev, "Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ best->aggregator_identifier, best->num_of_ports,
+ best->actor_oper_aggregator_key,
+ best->partner_oper_aggregator_key,
+ best->is_individual, best->is_active);
/* disable the ports that were related to the former
* active_aggregator
@@ -1908,13 +1904,13 @@ void bond_3ad_unbind_slave(struct slave *slave)
/* if slave is null, the whole port is not initialized */
if (!port->slave) {
- pr_warn("Warning: %s: Trying to unbind an uninitialized port on %s\n",
- slave->bond->dev->name, slave->dev->name);
+ netdev_warn(bond->dev, "Trying to unbind an uninitialized port on %s\n",
+ slave->dev->name);
return;
}
- pr_debug("Unbinding Link Aggregation Group %d\n",
- aggregator->aggregator_identifier);
+ netdev_dbg(bond->dev, "Unbinding Link Aggregation Group %d\n",
+ aggregator->aggregator_identifier);
/* Tell the partner that this port is not suitable for aggregation */
port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
@@ -1949,14 +1945,13 @@ void bond_3ad_unbind_slave(struct slave *slave)
* new aggregator
*/
if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
- pr_debug("Some port(s) related to LAG %d - replacing with LAG %d\n",
- aggregator->aggregator_identifier,
- new_aggregator->aggregator_identifier);
+ netdev_dbg(bond->dev, "Some port(s) related to LAG %d - replacing with LAG %d\n",
+ aggregator->aggregator_identifier,
+ new_aggregator->aggregator_identifier);
if ((new_aggregator->lag_ports == port) &&
new_aggregator->is_active) {
- pr_info("%s: Removing an active aggregator\n",
- aggregator->slave->bond->dev->name);
+ netdev_info(bond->dev, "Removing an active aggregator\n");
select_new_active_agg = 1;
}
@@ -1986,8 +1981,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
if (select_new_active_agg)
ad_agg_selection_logic(__get_first_agg(port));
} else {
- pr_warn("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
- slave->bond->dev->name);
+ netdev_warn(bond->dev, "unbinding aggregator, and could not find a new aggregator for its ports\n");
}
} else {
/* in case that the only port related to this
@@ -1996,8 +1990,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
select_new_active_agg = aggregator->is_active;
ad_clear_agg(aggregator);
if (select_new_active_agg) {
- pr_info("%s: Removing an active aggregator\n",
- slave->bond->dev->name);
+ netdev_info(bond->dev, "Removing an active aggregator\n");
/* select new active aggregator */
temp_aggregator = __get_first_agg(port);
if (temp_aggregator)
@@ -2006,7 +1999,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
}
}
- pr_debug("Unbinding port %d\n", port->actor_port_number);
+ netdev_dbg(bond->dev, "Unbinding port %d\n", port->actor_port_number);
/* find the aggregator that this port is connected to */
bond_for_each_slave(bond, slave_iter, iter) {
@@ -2029,8 +2022,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
select_new_active_agg = temp_aggregator->is_active;
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
- pr_info("%s: Removing an active aggregator\n",
- slave->bond->dev->name);
+ netdev_info(bond->dev, "Removing an active aggregator\n");
/* select new active aggregator */
ad_agg_selection_logic(__get_first_agg(port));
}
@@ -2081,8 +2073,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
/* select the active aggregator for the bond */
if (port) {
if (!port->slave) {
- pr_warn_ratelimited("%s: Warning: bond's first port is uninitialized\n",
- bond->dev->name);
+ net_warn_ratelimited("%s: Warning: bond's first port is uninitialized\n",
+ bond->dev->name);
goto re_arm;
}
@@ -2096,7 +2088,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
bond_for_each_slave_rcu(bond, slave, iter) {
port = &(SLAVE_AD_INFO(slave)->port);
if (!port->slave) {
- pr_warn_ratelimited("%s: Warning: Found an uninitialized port\n",
+ net_warn_ratelimited("%s: Warning: Found an uninitialized port\n",
bond->dev->name);
goto re_arm;
}
@@ -2158,16 +2150,16 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave,
port = &(SLAVE_AD_INFO(slave)->port);
if (!port->slave) {
- pr_warn_ratelimited("%s: Warning: port of slave %s is uninitialized\n",
- slave->dev->name, slave->bond->dev->name);
+ net_warn_ratelimited("%s: Warning: port of slave %s is uninitialized\n",
+ slave->dev->name, slave->bond->dev->name);
return ret;
}
switch (lacpdu->subtype) {
case AD_TYPE_LACPDU:
ret = RX_HANDLER_CONSUMED;
- pr_debug("Received LACPDU on port %d\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Received LACPDU on port %d\n",
+ port->actor_port_number);
/* Protect against concurrent state machines */
__get_state_machine_lock(port);
ad_rx_machine(lacpdu, port);
@@ -2182,20 +2174,20 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave,
switch (((struct bond_marker *)lacpdu)->tlv_type) {
case AD_MARKER_INFORMATION_SUBTYPE:
- pr_debug("Received Marker Information on port %d\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Received Marker Information on port %d\n",
+ port->actor_port_number);
ad_marker_info_received((struct bond_marker *)lacpdu, port);
break;
case AD_MARKER_RESPONSE_SUBTYPE:
- pr_debug("Received Marker Response on port %d\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Received Marker Response on port %d\n",
+ port->actor_port_number);
ad_marker_response_received((struct bond_marker *)lacpdu, port);
break;
default:
- pr_debug("Received an unknown Marker subtype on slot %d\n",
- port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Received an unknown Marker subtype on slot %d\n",
+ port->actor_port_number);
}
}
}
@@ -2216,8 +2208,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
/* if slave is null, the whole port is not initialized */
if (!port->slave) {
- pr_warn("Warning: %s: speed changed for uninitialized port on %s\n",
- slave->bond->dev->name, slave->dev->name);
+ netdev_warn(slave->bond->dev, "speed changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2226,7 +2218,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
port->actor_oper_port_key = port->actor_admin_port_key |=
(__get_link_speed(port) << 1);
- pr_debug("Port %d changed speed\n", port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Port %d changed speed\n", port->actor_port_number);
/* there is no need to reselect a new aggregator, just signal the
* state machines to reinitialize
*/
@@ -2249,8 +2241,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
/* if slave is null, the whole port is not initialized */
if (!port->slave) {
- pr_warn("%s: Warning: duplex changed for uninitialized port on %s\n",
- slave->bond->dev->name, slave->dev->name);
+ netdev_warn(slave->bond->dev, "duplex changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2259,7 +2251,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
port->actor_oper_port_key = port->actor_admin_port_key |=
__get_duplex(port);
- pr_debug("Port %d changed duplex\n", port->actor_port_number);
+ netdev_dbg(slave->bond->dev, "Port %d changed duplex\n", port->actor_port_number);
/* there is no need to reselect a new aggregator, just signal the
* state machines to reinitialize
*/
@@ -2283,8 +2275,8 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
/* if slave is null, the whole port is not initialized */
if (!port->slave) {
- pr_warn("Warning: %s: link status changed for uninitialized port on %s\n",
- slave->bond->dev->name, slave->dev->name);
+ netdev_warn(slave->bond->dev, "link status changed for uninitialized port on %s\n",
+ slave->dev->name);
return;
}
@@ -2311,9 +2303,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
port->actor_oper_port_key = (port->actor_admin_port_key &=
~AD_SPEED_KEY_BITS);
}
- pr_debug("Port %d changed link status to %s\n",
- port->actor_port_number,
- link == BOND_LINK_UP ? "UP" : "DOWN");
+ netdev_dbg(slave->bond->dev, "Port %d changed link status to %s\n",
+ port->actor_port_number,
+ link == BOND_LINK_UP ? "UP" : "DOWN");
/* there is no need to reselect a new aggregator, just signal the
* state machines to reinitialize
*/
@@ -2427,8 +2419,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
int agg_id;
if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
- pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
- dev->name);
+ netdev_dbg(dev, "__bond_3ad_get_active_agg_info failed\n");
goto err_free;
}
@@ -2436,7 +2427,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
agg_id = ad_info.aggregator_id;
if (slaves_in_agg == 0) {
- pr_debug("%s: Error: active aggregator is empty\n", dev->name);
+ netdev_dbg(dev, "active aggregator is empty\n");
goto err_free;
}
@@ -2462,8 +2453,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
}
if (slave_agg_no >= 0) {
- pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n",
- dev->name, agg_id);
+ netdev_err(dev, "Couldn't find a slave to tx on for aggregator ID %d\n",
+ agg_id);
goto err_free;
}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 76c0dade233f..95dd1f58c260 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -19,8 +19,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -202,6 +200,7 @@ static int tlb_initialize(struct bonding *bond)
static void tlb_deinitialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct tlb_up_slave *arr;
_lock_tx_hashtbl_bh(bond);
@@ -209,6 +208,10 @@ static void tlb_deinitialize(struct bonding *bond)
bond_info->tx_hashtbl = NULL;
_unlock_tx_hashtbl_bh(bond);
+
+ arr = rtnl_dereference(bond_info->slave_arr);
+ if (arr)
+ kfree_rcu(arr, rcu);
}
static long long compute_gap(struct slave *slave)
@@ -369,7 +372,7 @@ static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
if (arp->op_code == htons(ARPOP_REPLY)) {
/* update rx hash table for this ARP */
rlb_update_entry_from_arp(bond, arp);
- pr_debug("Server received an ARP Reply from client\n");
+ netdev_dbg(bond->dev, "Server received an ARP Reply from client\n");
}
out:
return RX_HANDLER_ANOTHER;
@@ -448,11 +451,13 @@ static struct slave *__rlb_next_rx_slave(struct bonding *bond)
*/
static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
{
- if (!bond->curr_active_slave)
+ struct slave *curr_active = bond_deref_active_protected(bond);
+
+ if (!curr_active)
return;
if (!bond->alb_info.primary_is_promisc) {
- if (!dev_set_promiscuity(bond->curr_active_slave->dev, 1))
+ if (!dev_set_promiscuity(curr_active->dev, 1))
bond->alb_info.primary_is_promisc = 1;
else
bond->alb_info.primary_is_promisc = 0;
@@ -460,7 +465,7 @@ static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
bond->alb_info.rlb_promisc_timeout_counter = 0;
- alb_send_learning_packets(bond->curr_active_slave, addr, true);
+ alb_send_learning_packets(curr_active, addr, true);
}
/* slave being removed should not be active at this point
@@ -509,7 +514,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
write_lock_bh(&bond->curr_slave_lock);
- if (slave != bond->curr_active_slave)
+ if (slave != bond_deref_active_protected(bond))
rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
write_unlock_bh(&bond->curr_slave_lock);
@@ -533,8 +538,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info->slave->dev->dev_addr,
client_info->mac_dst);
if (!skb) {
- pr_err("%s: Error: failed to create an ARP packet\n",
- client_info->slave->bond->dev->name);
+ netdev_err(client_info->slave->bond->dev,
+ "failed to create an ARP packet\n");
continue;
}
@@ -543,8 +548,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
if (client_info->vlan_id) {
skb = vlan_put_tag(skb, htons(ETH_P_8021Q), client_info->vlan_id);
if (!skb) {
- pr_err("%s: Error: failed to insert VLAN tag\n",
- client_info->slave->bond->dev->name);
+ netdev_err(client_info->slave->bond->dev,
+ "failed to insert VLAN tag\n");
continue;
}
}
@@ -628,8 +633,7 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
client_info = &(bond_info->rx_hashtbl[hash_index]);
if (!client_info->slave) {
- pr_err("%s: Error: found a client with no channel in the client's hash table\n",
- bond->dev->name);
+ netdev_err(bond->dev, "found a client with no channel in the client's hash table\n");
continue;
}
/*update all clients using this src_ip, that are not assigned
@@ -684,7 +688,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
* move the old client to primary (curr_active_slave) so
* that the new client can be assigned to this entry.
*/
- if (bond->curr_active_slave &&
+ if (curr_active_slave &&
client_info->slave != curr_active_slave) {
client_info->slave = curr_active_slave;
rlb_update_client(client_info);
@@ -765,7 +769,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
tx_slave = rlb_choose_channel(skb, bond);
if (tx_slave)
ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr);
- pr_debug("Server sent ARP Reply packet\n");
+ netdev_dbg(bond->dev, "Server sent ARP Reply packet\n");
} else if (arp->op_code == htons(ARPOP_REQUEST)) {
/* Create an entry in the rx_hashtbl for this client as a
* place holder.
@@ -785,7 +789,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
* updated with their assigned mac.
*/
rlb_req_update_subnet_clients(bond, arp->ip_src);
- pr_debug("Server sent ARP Request packet\n");
+ netdev_dbg(bond->dev, "Server sent ARP Request packet\n");
}
return tx_slave;
@@ -1024,8 +1028,7 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
if (vid) {
skb = vlan_put_tag(skb, vlan_proto, vid);
if (!skb) {
- pr_err("%s: Error: failed to insert VLAN tag\n",
- slave->bond->dev->name);
+ netdev_err(slave->bond->dev, "failed to insert VLAN tag\n");
return;
}
}
@@ -1039,7 +1042,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
struct bonding *bond = bond_get_bond_by_slave(slave);
struct net_device *upper;
struct list_head *iter;
- struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP];
+ struct bond_vlan_tag *tags;
/* send untagged */
alb_send_lp_vid(slave, mac_addr, 0, 0);
@@ -1067,10 +1070,12 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
* when strict_match is turned off.
*/
if (netif_is_macvlan(upper) && !strict_match) {
- memset(tags, 0, sizeof(tags));
- bond_verify_device_path(bond->dev, upper, tags);
+ tags = bond_verify_device_path(bond->dev, upper, 0);
+ if (IS_ERR_OR_NULL(tags))
+ BUG();
alb_send_lp_vid(slave, upper->dev_addr,
tags[0].vlan_proto, tags[0].vlan_id);
+ kfree(tags);
}
}
rcu_read_unlock();
@@ -1091,9 +1096,8 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
memcpy(s_addr.sa_data, addr, dev->addr_len);
s_addr.sa_family = dev->type;
if (dev_set_mac_address(dev, &s_addr)) {
- pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n"
- "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
- slave->bond->dev->name, dev->name);
+ netdev_err(slave->bond->dev, "dev_set_mac_address of dev %s failed! ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
+ dev->name);
return -EOPNOTSUPP;
}
return 0;
@@ -1221,7 +1225,7 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
*/
static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
{
- struct slave *has_bond_addr = bond->curr_active_slave;
+ struct slave *has_bond_addr = rcu_access_pointer(bond->curr_active_slave);
struct slave *tmp_slave1, *free_mac_slave = NULL;
struct list_head *iter;
@@ -1267,13 +1271,12 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
if (free_mac_slave) {
alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr);
- pr_warn("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
- bond->dev->name, slave->dev->name,
- free_mac_slave->dev->name);
+ netdev_warn(bond->dev, "the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
+ slave->dev->name, free_mac_slave->dev->name);
} else if (has_bond_addr) {
- pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n",
- bond->dev->name, slave->dev->name);
+ netdev_err(bond->dev, "the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n",
+ slave->dev->name);
return -EFAULT;
}
@@ -1406,9 +1409,39 @@ out:
return NETDEV_TX_OK;
}
+static int bond_tlb_update_slave_arr(struct bonding *bond,
+ struct slave *skipslave)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct slave *tx_slave;
+ struct list_head *iter;
+ struct tlb_up_slave *new_arr, *old_arr;
+
+ new_arr = kzalloc(offsetof(struct tlb_up_slave, arr[bond->slave_cnt]),
+ GFP_ATOMIC);
+ if (!new_arr)
+ return -ENOMEM;
+
+ bond_for_each_slave(bond, tx_slave, iter) {
+ if (!bond_slave_can_tx(tx_slave))
+ continue;
+ if (skipslave == tx_slave)
+ continue;
+ new_arr->arr[new_arr->count++] = tx_slave;
+ }
+
+ old_arr = rtnl_dereference(bond_info->slave_arr);
+ rcu_assign_pointer(bond_info->slave_arr, new_arr);
+ if (old_arr)
+ kfree_rcu(old_arr, rcu);
+
+ return 0;
+}
+
int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct ethhdr *eth_data;
struct slave *tx_slave = NULL;
u32 hash_index;
@@ -1429,12 +1462,12 @@ int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
hash_index & 0xFF,
skb->len);
} else {
- struct list_head *iter;
- int idx = hash_index % bond->slave_cnt;
+ struct tlb_up_slave *slaves;
- bond_for_each_slave_rcu(bond, tx_slave, iter)
- if (--idx < 0)
- break;
+ slaves = rcu_dereference(bond_info->slave_arr);
+ if (slaves && slaves->count)
+ tx_slave = slaves->arr[hash_index %
+ slaves->count];
}
break;
}
@@ -1575,7 +1608,7 @@ void bond_alb_monitor(struct work_struct *work)
* use mac of the slave device.
* In RLB mode, we always use strict matches.
*/
- strict_match = (slave != bond->curr_active_slave ||
+ strict_match = (slave != rcu_access_pointer(bond->curr_active_slave) ||
bond_info->rlb_enabled);
alb_send_learning_packets(slave, slave->dev->dev_addr,
strict_match);
@@ -1593,7 +1626,7 @@ void bond_alb_monitor(struct work_struct *work)
bond_for_each_slave_rcu(bond, slave, iter) {
tlb_clear_slave(bond, slave, 1);
- if (slave == bond->curr_active_slave) {
+ if (slave == rcu_access_pointer(bond->curr_active_slave)) {
SLAVE_TLB_INFO(slave).load =
bond_info->unbalanced_load /
BOND_TLB_REBALANCE_INTERVAL;
@@ -1625,7 +1658,8 @@ void bond_alb_monitor(struct work_struct *work)
* because a slave was disabled then
* it can now leave promiscuous mode.
*/
- dev_set_promiscuity(bond->curr_active_slave->dev, -1);
+ dev_set_promiscuity(rtnl_dereference(bond->curr_active_slave)->dev,
+ -1);
bond_info->primary_is_promisc = 0;
rtnl_unlock();
@@ -1698,6 +1732,11 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
bond->alb_info.rx_slave = NULL;
rlb_clear_slave(bond, slave);
}
+
+ if (bond_is_nondyn_tlb(bond))
+ if (bond_tlb_update_slave_arr(bond, slave))
+ pr_err("Failed to build slave-array for TLB mode.\n");
+
}
/* Caller must hold bond lock for read */
@@ -1721,6 +1760,11 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
*/
}
}
+
+ if (bond_is_nondyn_tlb(bond)) {
+ if (bond_tlb_update_slave_arr(bond, NULL))
+ pr_err("Failed to build slave-array for TLB mode.\n");
+ }
}
/**
@@ -1742,17 +1786,21 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
__acquires(&bond->curr_slave_lock)
{
struct slave *swap_slave;
+ struct slave *curr_active;
- if (bond->curr_active_slave == new_slave)
+ curr_active = rcu_dereference_protected(bond->curr_active_slave,
+ !new_slave ||
+ lockdep_is_held(&bond->curr_slave_lock));
+ if (curr_active == new_slave)
return;
- if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
- dev_set_promiscuity(bond->curr_active_slave->dev, -1);
+ if (curr_active && bond->alb_info.primary_is_promisc) {
+ dev_set_promiscuity(curr_active->dev, -1);
bond->alb_info.primary_is_promisc = 0;
bond->alb_info.rlb_promisc_timeout_counter = 0;
}
- swap_slave = bond->curr_active_slave;
+ swap_slave = curr_active;
rcu_assign_pointer(bond->curr_active_slave, new_slave);
if (!new_slave || !bond_has_slaves(bond))
@@ -1818,6 +1866,7 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
{
struct bonding *bond = netdev_priv(bond_dev);
struct sockaddr *sa = addr;
+ struct slave *curr_active;
struct slave *swap_slave;
int res;
@@ -1834,23 +1883,24 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
* Otherwise we'll need to pass the new address to it and handle
* duplications.
*/
- if (!bond->curr_active_slave)
+ curr_active = rtnl_dereference(bond->curr_active_slave);
+ if (!curr_active)
return 0;
swap_slave = bond_slave_has_mac(bond, bond_dev->dev_addr);
if (swap_slave) {
- alb_swap_mac_addr(swap_slave, bond->curr_active_slave);
- alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
+ alb_swap_mac_addr(swap_slave, curr_active);
+ alb_fasten_mac_swap(bond, swap_slave, curr_active);
} else {
- alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr);
+ alb_set_slave_mac_addr(curr_active, bond_dev->dev_addr);
read_lock(&bond->lock);
- alb_send_learning_packets(bond->curr_active_slave,
+ alb_send_learning_packets(curr_active,
bond_dev->dev_addr, false);
if (bond->alb_info.rlb_enabled) {
/* inform clients mac address has changed */
- rlb_req_update_slave_clients(bond, bond->curr_active_slave);
+ rlb_req_update_slave_clients(bond, curr_active);
}
read_unlock(&bond->lock);
}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 5fc76c01636c..aaeac61d03cf 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -139,12 +139,20 @@ struct tlb_slave_info {
*/
};
+struct tlb_up_slave {
+ unsigned int count;
+ struct rcu_head rcu;
+ struct slave *arr[0];
+};
+
struct alb_bond_info {
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
spinlock_t tx_hashtbl_lock;
u32 unbalanced_load;
int tx_rebalance_counter;
int lp_counter;
+ /* -------- non-dynamic tlb mode only ---------*/
+ struct tlb_up_slave __rcu *slave_arr; /* Up slaves */
/* -------- rlb parameters -------- */
int rlb_enabled;
struct rlb_client_info *rx_hashtbl; /* Receive hash table */
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c
index 658e761c4568..280971b227ea 100644
--- a/drivers/net/bonding/bond_debugfs.c
+++ b/drivers/net/bonding/bond_debugfs.c
@@ -69,8 +69,7 @@ void bond_debug_register(struct bonding *bond)
debugfs_create_dir(bond->dev->name, bonding_debug_root);
if (!bond->debug_dir) {
- pr_warn("%s: Warning: failed to register to debugfs\n",
- bond->dev->name);
+ netdev_warn(bond->dev, "failed to register to debugfs\n");
return;
}
@@ -98,8 +97,7 @@ void bond_debug_reregister(struct bonding *bond)
if (d) {
bond->debug_dir = d;
} else {
- pr_warn("%s: Warning: failed to reregister, so just unregister old one\n",
- bond->dev->name);
+ netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n");
bond_debug_unregister(bond);
}
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 3a451b6cd3d5..f0f5eab0fab1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -31,8 +31,6 @@
*
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -498,11 +496,10 @@ static int bond_set_promiscuity(struct bonding *bond, int inc)
int err = 0;
if (bond_uses_primary(bond)) {
- /* write lock already acquired */
- if (bond->curr_active_slave) {
- err = dev_set_promiscuity(bond->curr_active_slave->dev,
- inc);
- }
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+
+ if (curr_active)
+ err = dev_set_promiscuity(curr_active->dev, inc);
} else {
struct slave *slave;
@@ -524,11 +521,10 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
int err = 0;
if (bond_uses_primary(bond)) {
- /* write lock already acquired */
- if (bond->curr_active_slave) {
- err = dev_set_allmulti(bond->curr_active_slave->dev,
- inc);
- }
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+
+ if (curr_active)
+ err = dev_set_allmulti(curr_active->dev, inc);
} else {
struct slave *slave;
@@ -629,8 +625,8 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
static void bond_set_dev_addr(struct net_device *bond_dev,
struct net_device *slave_dev)
{
- pr_debug("bond_dev=%p slave_dev=%p slave_dev->addr_len=%d\n",
- bond_dev, slave_dev, slave_dev->addr_len);
+ netdev_dbg(bond_dev, "bond_dev=%p slave_dev=%p slave_dev->addr_len=%d\n",
+ bond_dev, slave_dev, slave_dev->addr_len);
memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
bond_dev->addr_assign_type = NET_ADDR_STOLEN;
call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev);
@@ -684,8 +680,8 @@ static void bond_do_fail_over_mac(struct bonding *bond,
rv = dev_set_mac_address(new_active->dev, &saddr);
if (rv) {
- pr_err("%s: Error %d setting MAC of slave %s\n",
- bond->dev->name, -rv, new_active->dev->name);
+ netdev_err(bond->dev, "Error %d setting MAC of slave %s\n",
+ -rv, new_active->dev->name);
goto out;
}
@@ -697,14 +693,14 @@ static void bond_do_fail_over_mac(struct bonding *bond,
rv = dev_set_mac_address(old_active->dev, &saddr);
if (rv)
- pr_err("%s: Error %d setting MAC of slave %s\n",
- bond->dev->name, -rv, new_active->dev->name);
+ netdev_err(bond->dev, "Error %d setting MAC of slave %s\n",
+ -rv, new_active->dev->name);
out:
write_lock_bh(&bond->curr_slave_lock);
break;
default:
- pr_err("%s: bond_do_fail_over_mac impossible: bad policy %d\n",
- bond->dev->name, bond->params.fail_over_mac);
+ netdev_err(bond->dev, "bond_do_fail_over_mac impossible: bad policy %d\n",
+ bond->params.fail_over_mac);
break;
}
@@ -713,7 +709,7 @@ out:
static bool bond_should_change_active(struct bonding *bond)
{
struct slave *prim = bond->primary_slave;
- struct slave *curr = bond->curr_active_slave;
+ struct slave *curr = bond_deref_active_protected(bond);
if (!prim || !curr || curr->link != BOND_LINK_UP)
return true;
@@ -765,8 +761,8 @@ static bool bond_should_notify_peers(struct bonding *bond)
slave = rcu_dereference(bond->curr_active_slave);
rcu_read_unlock();
- pr_debug("bond_should_notify_peers: bond %s slave %s\n",
- bond->dev->name, slave ? slave->dev->name : "NULL");
+ netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n",
+ slave ? slave->dev->name : "NULL");
if (!slave || !bond->send_peer_notif ||
test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
@@ -792,7 +788,11 @@ static bool bond_should_notify_peers(struct bonding *bond)
*/
void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
{
- struct slave *old_active = bond->curr_active_slave;
+ struct slave *old_active;
+
+ old_active = rcu_dereference_protected(bond->curr_active_slave,
+ !new_active ||
+ lockdep_is_held(&bond->curr_slave_lock));
if (old_active == new_active)
return;
@@ -802,9 +802,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (new_active->link == BOND_LINK_BACK) {
if (bond_uses_primary(bond)) {
- pr_info("%s: making interface %s the new active one %d ms earlier\n",
- bond->dev->name, new_active->dev->name,
- (bond->params.updelay - new_active->delay) * bond->params.miimon);
+ netdev_info(bond->dev, "making interface %s the new active one %d ms earlier\n",
+ new_active->dev->name,
+ (bond->params.updelay - new_active->delay) * bond->params.miimon);
}
new_active->delay = 0;
@@ -817,8 +817,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
} else {
if (bond_uses_primary(bond)) {
- pr_info("%s: making interface %s the new active one\n",
- bond->dev->name, new_active->dev->name);
+ netdev_info(bond->dev, "making interface %s the new active one\n",
+ new_active->dev->name);
}
}
}
@@ -900,18 +900,16 @@ void bond_select_active_slave(struct bonding *bond)
int rv;
best_slave = bond_find_best_slave(bond);
- if (best_slave != bond->curr_active_slave) {
+ if (best_slave != bond_deref_active_protected(bond)) {
bond_change_active_slave(bond, best_slave);
rv = bond_set_carrier(bond);
if (!rv)
return;
if (netif_carrier_ok(bond->dev)) {
- pr_info("%s: first active interface up!\n",
- bond->dev->name);
+ netdev_info(bond->dev, "first active interface up!\n");
} else {
- pr_info("%s: now running without any active interface!\n",
- bond->dev->name);
+ netdev_info(bond->dev, "now running without any active interface!\n");
}
}
}
@@ -1001,12 +999,6 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
netdev_features_t mask;
struct slave *slave;
- if (!bond_has_slaves(bond)) {
- /* Disable adding VLANs to empty bond. But why? --mq */
- features |= NETIF_F_VLAN_CHALLENGED;
- return features;
- }
-
mask = features;
features &= ~NETIF_F_ONE_FOR_ALL;
features |= NETIF_F_ALL_FOR_ALL;
@@ -1214,36 +1206,38 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (!bond->params.use_carrier &&
slave_dev->ethtool_ops->get_link == NULL &&
slave_ops->ndo_do_ioctl == NULL) {
- pr_warn("%s: Warning: no link monitoring support for %s\n",
- bond_dev->name, slave_dev->name);
+ netdev_warn(bond_dev, "no link monitoring support for %s\n",
+ slave_dev->name);
}
/* already enslaved */
if (slave_dev->flags & IFF_SLAVE) {
- pr_debug("Error: Device was already enslaved\n");
+ netdev_dbg(bond_dev, "Error: Device was already enslaved\n");
return -EBUSY;
}
if (bond_dev == slave_dev) {
- pr_err("%s: cannot enslave bond to itself.\n", bond_dev->name);
+ netdev_err(bond_dev, "cannot enslave bond to itself.\n");
return -EPERM;
}
/* vlan challenged mutual exclusion */
/* no need to lock since we're protected by rtnl_lock */
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
- pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
+ netdev_dbg(bond_dev, "%s is NETIF_F_VLAN_CHALLENGED\n",
+ slave_dev->name);
if (vlan_uses_dev(bond_dev)) {
- pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
- bond_dev->name, slave_dev->name, bond_dev->name);
+ netdev_err(bond_dev, "Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
+ slave_dev->name, bond_dev->name);
return -EPERM;
} else {
- pr_warn("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
- bond_dev->name, slave_dev->name,
- slave_dev->name, bond_dev->name);
+ netdev_warn(bond_dev, "enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
+ slave_dev->name, slave_dev->name,
+ bond_dev->name);
}
} else {
- pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
+ netdev_dbg(bond_dev, "%s is !NETIF_F_VLAN_CHALLENGED\n",
+ slave_dev->name);
}
/*
@@ -1253,8 +1247,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* enslaving it; the old ifenslave will not.
*/
if ((slave_dev->flags & IFF_UP)) {
- pr_err("%s is up - this may be due to an out of date ifenslave\n",
- slave_dev->name);
+ netdev_err(bond_dev, "%s is up - this may be due to an out of date ifenslave\n",
+ slave_dev->name);
res = -EPERM;
goto err_undo_flags;
}
@@ -1268,16 +1262,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
*/
if (!bond_has_slaves(bond)) {
if (bond_dev->type != slave_dev->type) {
- pr_debug("%s: change device type from %d to %d\n",
- bond_dev->name,
- bond_dev->type, slave_dev->type);
+ netdev_dbg(bond_dev, "change device type from %d to %d\n",
+ bond_dev->type, slave_dev->type);
res = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE,
bond_dev);
res = notifier_to_errno(res);
if (res) {
- pr_err("%s: refused to change device type\n",
- bond_dev->name);
+ netdev_err(bond_dev, "refused to change device type\n");
res = -EBUSY;
goto err_undo_flags;
}
@@ -1297,26 +1289,24 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_dev);
}
} else if (bond_dev->type != slave_dev->type) {
- pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it\n",
- slave_dev->name, slave_dev->type, bond_dev->type);
+ netdev_err(bond_dev, "%s ether type (%d) is different from other slaves (%d), can not enslave it\n",
+ slave_dev->name, slave_dev->type, bond_dev->type);
res = -EINVAL;
goto err_undo_flags;
}
if (slave_ops->ndo_set_mac_address == NULL) {
- if (!bond_has_slaves(bond)) {
- pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address\n",
- bond_dev->name);
- if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
+ netdev_warn(bond_dev, "The slave device specified does not support setting the MAC address\n");
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
+ bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
+ if (!bond_has_slaves(bond)) {
bond->params.fail_over_mac = BOND_FOM_ACTIVE;
- pr_warn("%s: Setting fail_over_mac to active for active-backup mode\n",
- bond_dev->name);
+ netdev_warn(bond_dev, "Setting fail_over_mac to active for active-backup mode\n");
+ } else {
+ netdev_err(bond_dev, "The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active\n");
+ res = -EOPNOTSUPP;
+ goto err_undo_flags;
}
- } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
- pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active\n",
- bond_dev->name);
- res = -EOPNOTSUPP;
- goto err_undo_flags;
}
}
@@ -1346,7 +1336,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
new_slave->original_mtu = slave_dev->mtu;
res = dev_set_mtu(slave_dev, bond->dev->mtu);
if (res) {
- pr_debug("Error %d calling dev_set_mtu\n", res);
+ netdev_dbg(bond_dev, "Error %d calling dev_set_mtu\n", res);
goto err_free;
}
@@ -1367,7 +1357,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
- pr_debug("Error %d calling set_mac_address\n", res);
+ netdev_dbg(bond_dev, "Error %d calling set_mac_address\n", res);
goto err_restore_mtu;
}
}
@@ -1375,7 +1365,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
- pr_debug("Opening slave %s failed\n", slave_dev->name);
+ netdev_dbg(bond_dev, "Opening slave %s failed\n", slave_dev->name);
goto err_restore_mac;
}
@@ -1425,8 +1415,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
res = vlan_vids_add_by_dev(slave_dev, bond_dev);
if (res) {
- pr_err("%s: Error: Couldn't add bond vlan ids to %s\n",
- bond_dev->name, slave_dev->name);
+ netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n",
+ slave_dev->name);
goto err_close;
}
@@ -1455,12 +1445,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* supported); thus, we don't need to change
* the messages for netif_carrier.
*/
- pr_warn("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details\n",
- bond_dev->name, slave_dev->name);
+ netdev_warn(bond_dev, "MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details\n",
+ slave_dev->name);
} else if (link_reporting == -1) {
/* unable get link status using mii/ethtool */
- pr_warn("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface\n",
- bond_dev->name, slave_dev->name);
+ netdev_warn(bond_dev, "can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface\n",
+ slave_dev->name);
}
}
@@ -1485,9 +1475,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (new_slave->link != BOND_LINK_DOWN)
new_slave->last_link_up = jiffies;
- pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
- new_slave->link == BOND_LINK_DOWN ? "DOWN" :
- (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
+ netdev_dbg(bond_dev, "Initial state of slave_dev is BOND_LINK_%s\n",
+ new_slave->link == BOND_LINK_DOWN ? "DOWN" :
+ (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
if (bond_uses_primary(bond) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
@@ -1528,7 +1518,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
break;
default:
- pr_debug("This slave is always active in trunk mode\n");
+ netdev_dbg(bond_dev, "This slave is always active in trunk mode\n");
/* always active in trunk mode */
bond_set_active_slave(new_slave);
@@ -1537,7 +1527,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* anyway (it holds no special properties of the bond device),
* so we can change it without calling change_active_interface()
*/
- if (!bond->curr_active_slave && new_slave->link == BOND_LINK_UP)
+ if (!rcu_access_pointer(bond->curr_active_slave) &&
+ new_slave->link == BOND_LINK_UP)
rcu_assign_pointer(bond->curr_active_slave, new_slave);
break;
@@ -1547,8 +1538,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
slave_dev->npinfo = bond->dev->npinfo;
if (slave_dev->npinfo) {
if (slave_enable_netpoll(new_slave)) {
- pr_info("Error, %s: master_dev is using netpoll, but new slave device does not support netpoll\n",
- bond_dev->name);
+ netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n");
res = -EBUSY;
goto err_detach;
}
@@ -1558,19 +1548,19 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
new_slave);
if (res) {
- pr_debug("Error %d calling netdev_rx_handler_register\n", res);
+ netdev_dbg(bond_dev, "Error %d calling netdev_rx_handler_register\n", res);
goto err_detach;
}
res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave);
if (res) {
- pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
+ netdev_dbg(bond_dev, "Error %d calling bond_master_upper_dev_link\n", res);
goto err_unregister;
}
res = bond_sysfs_slave_add(new_slave);
if (res) {
- pr_debug("Error %d calling bond_sysfs_slave_add\n", res);
+ netdev_dbg(bond_dev, "Error %d calling bond_sysfs_slave_add\n", res);
goto err_upper_unlink;
}
@@ -1586,10 +1576,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
unblock_netpoll_tx();
}
- pr_info("%s: Enslaving %s as %s interface with %s link\n",
- bond_dev->name, slave_dev->name,
- bond_is_active_slave(new_slave) ? "an active" : "a backup",
- new_slave->link != BOND_LINK_DOWN ? "an up" : "a down");
+ netdev_info(bond_dev, "Enslaving %s as %s interface with %s link\n",
+ slave_dev->name,
+ bond_is_active_slave(new_slave) ? "an active" : "a backup",
+ new_slave->link != BOND_LINK_DOWN ? "an up" : "a down");
/* enslave is successful */
return 0;
@@ -1608,7 +1598,7 @@ err_detach:
vlan_vids_del_by_dev(slave_dev, bond_dev);
if (bond->primary_slave == new_slave)
bond->primary_slave = NULL;
- if (bond->curr_active_slave == new_slave) {
+ if (rcu_access_pointer(bond->curr_active_slave) == new_slave) {
block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, NULL);
@@ -1674,8 +1664,8 @@ static int __bond_release_one(struct net_device *bond_dev,
/* slave is not a slave or master is not master of this slave */
if (!(slave_dev->flags & IFF_SLAVE) ||
!netdev_has_upper_dev(slave_dev, bond_dev)) {
- pr_err("%s: Error: cannot release %s\n",
- bond_dev->name, slave_dev->name);
+ netdev_err(bond_dev, "cannot release %s\n",
+ slave_dev->name);
return -EINVAL;
}
@@ -1684,8 +1674,8 @@ static int __bond_release_one(struct net_device *bond_dev,
slave = bond_get_slave_by_dev(bond, slave_dev);
if (!slave) {
/* not a slave of this bond */
- pr_info("%s: %s not enslaved\n",
- bond_dev->name, slave_dev->name);
+ netdev_info(bond_dev, "%s not enslaved\n",
+ slave_dev->name);
unblock_netpoll_tx();
return -EINVAL;
}
@@ -1705,23 +1695,21 @@ static int __bond_release_one(struct net_device *bond_dev,
write_unlock_bh(&bond->lock);
- pr_info("%s: Releasing %s interface %s\n",
- bond_dev->name,
- bond_is_active_slave(slave) ? "active" : "backup",
- slave_dev->name);
+ netdev_info(bond_dev, "Releasing %s interface %s\n",
+ bond_is_active_slave(slave) ? "active" : "backup",
+ slave_dev->name);
- oldcurrent = bond->curr_active_slave;
+ oldcurrent = rcu_access_pointer(bond->curr_active_slave);
- bond->current_arp_slave = NULL;
+ RCU_INIT_POINTER(bond->current_arp_slave, NULL);
if (!all && (!bond->params.fail_over_mac ||
BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)) {
if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) &&
bond_has_slaves(bond))
- pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s - set the HWaddr of %s to a different address to avoid conflicts\n",
- bond_dev->name, slave_dev->name,
- slave->perm_hwaddr,
- bond_dev->name, slave_dev->name);
+ netdev_warn(bond_dev, "the permanent HWaddr of %s - %pM - is still in use by %s - set the HWaddr of %s to a different address to avoid conflicts\n",
+ slave_dev->name, slave->perm_hwaddr,
+ bond_dev->name, slave_dev->name);
}
if (bond->primary_slave == slave)
@@ -1760,13 +1748,6 @@ static int __bond_release_one(struct net_device *bond_dev,
if (!bond_has_slaves(bond)) {
bond_set_carrier(bond);
eth_hw_addr_random(bond_dev);
-
- if (vlan_uses_dev(bond_dev)) {
- pr_warn("%s: Warning: clearing HW address of %s while it still has VLANs\n",
- bond_dev->name, bond_dev->name);
- pr_warn("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs\n",
- bond_dev->name);
- }
}
unblock_netpoll_tx();
@@ -1781,8 +1762,8 @@ static int __bond_release_one(struct net_device *bond_dev,
bond_compute_features(bond);
if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
(old_features & NETIF_F_VLAN_CHALLENGED))
- pr_info("%s: last VLAN challenged slave %s left bond %s - VLAN blocking is removed\n",
- bond_dev->name, slave_dev->name, bond_dev->name);
+ netdev_info(bond_dev, "last VLAN challenged slave %s left bond %s - VLAN blocking is removed\n",
+ slave_dev->name, bond_dev->name);
/* must do this from outside any spinlocks */
vlan_vids_del_by_dev(slave_dev, bond_dev);
@@ -1849,8 +1830,8 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
ret = bond_release(bond_dev, slave_dev);
if (ret == 0 && !bond_has_slaves(bond)) {
bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
- pr_info("%s: Destroying bond %s\n",
- bond_dev->name, bond_dev->name);
+ netdev_info(bond_dev, "Destroying bond %s\n",
+ bond_dev->name);
unregister_netdevice(bond_dev);
}
return ret;
@@ -1891,7 +1872,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
/*-------------------------------- Monitoring -------------------------------*/
-
+/* called with rcu_read_lock() */
static int bond_miimon_inspect(struct bonding *bond)
{
int link_state, commit = 0;
@@ -1899,7 +1880,7 @@ static int bond_miimon_inspect(struct bonding *bond)
struct slave *slave;
bool ignore_updelay;
- ignore_updelay = !bond->curr_active_slave ? true : false;
+ ignore_updelay = !rcu_dereference(bond->curr_active_slave);
bond_for_each_slave_rcu(bond, slave, iter) {
slave->new_link = BOND_LINK_NOCHANGE;
@@ -1914,14 +1895,13 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->link = BOND_LINK_FAIL;
slave->delay = bond->params.downdelay;
if (slave->delay) {
- pr_info("%s: link status down for %sinterface %s, disabling it in %d ms\n",
- bond->dev->name,
- (BOND_MODE(bond) ==
- BOND_MODE_ACTIVEBACKUP) ?
- (bond_is_active_slave(slave) ?
- "active " : "backup ") : "",
- slave->dev->name,
- bond->params.downdelay * bond->params.miimon);
+ netdev_info(bond->dev, "link status down for %sinterface %s, disabling it in %d ms\n",
+ (BOND_MODE(bond) ==
+ BOND_MODE_ACTIVEBACKUP) ?
+ (bond_is_active_slave(slave) ?
+ "active " : "backup ") : "",
+ slave->dev->name,
+ bond->params.downdelay * bond->params.miimon);
}
/*FALLTHRU*/
case BOND_LINK_FAIL:
@@ -1931,11 +1911,10 @@ static int bond_miimon_inspect(struct bonding *bond)
*/
slave->link = BOND_LINK_UP;
slave->last_link_up = jiffies;
- pr_info("%s: link status up again after %d ms for interface %s\n",
- bond->dev->name,
- (bond->params.downdelay - slave->delay) *
- bond->params.miimon,
- slave->dev->name);
+ netdev_info(bond->dev, "link status up again after %d ms for interface %s\n",
+ (bond->params.downdelay - slave->delay) *
+ bond->params.miimon,
+ slave->dev->name);
continue;
}
@@ -1956,21 +1935,20 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->delay = bond->params.updelay;
if (slave->delay) {
- pr_info("%s: link status up for interface %s, enabling it in %d ms\n",
- bond->dev->name, slave->dev->name,
- ignore_updelay ? 0 :
- bond->params.updelay *
- bond->params.miimon);
+ netdev_info(bond->dev, "link status up for interface %s, enabling it in %d ms\n",
+ slave->dev->name,
+ ignore_updelay ? 0 :
+ bond->params.updelay *
+ bond->params.miimon);
}
/*FALLTHRU*/
case BOND_LINK_BACK:
if (!link_state) {
slave->link = BOND_LINK_DOWN;
- pr_info("%s: link status down again after %d ms for interface %s\n",
- bond->dev->name,
- (bond->params.updelay - slave->delay) *
- bond->params.miimon,
- slave->dev->name);
+ netdev_info(bond->dev, "link status down again after %d ms for interface %s\n",
+ (bond->params.updelay - slave->delay) *
+ bond->params.miimon,
+ slave->dev->name);
continue;
}
@@ -2018,10 +1996,10 @@ static void bond_miimon_commit(struct bonding *bond)
bond_set_backup_slave(slave);
}
- pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex\n",
- bond->dev->name, slave->dev->name,
- slave->speed == SPEED_UNKNOWN ? 0 : slave->speed,
- slave->duplex ? "full" : "half");
+ netdev_info(bond->dev, "link status definitely up for interface %s, %u Mbps %s duplex\n",
+ slave->dev->name,
+ slave->speed == SPEED_UNKNOWN ? 0 : slave->speed,
+ slave->duplex ? "full" : "half");
/* notify ad that the link status has changed */
if (BOND_MODE(bond) == BOND_MODE_8023AD)
@@ -2048,8 +2026,8 @@ static void bond_miimon_commit(struct bonding *bond)
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
- pr_info("%s: link status definitely down for interface %s, disabling it\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "link status definitely down for interface %s, disabling it\n",
+ slave->dev->name);
if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_handle_link_change(slave,
@@ -2059,15 +2037,14 @@ static void bond_miimon_commit(struct bonding *bond)
bond_alb_handle_link_change(bond, slave,
BOND_LINK_DOWN);
- if (slave == bond->curr_active_slave)
+ if (slave == rcu_access_pointer(bond->curr_active_slave))
goto do_failover;
continue;
default:
- pr_err("%s: invalid new link %d on slave %s\n",
- bond->dev->name, slave->new_link,
- slave->dev->name);
+ netdev_err(bond->dev, "invalid new link %d on slave %s\n",
+ slave->new_link, slave->dev->name);
slave->new_link = BOND_LINK_NOCHANGE;
continue;
@@ -2168,10 +2145,10 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
struct bond_vlan_tag *tags)
{
struct sk_buff *skb;
- int i;
+ struct bond_vlan_tag *outer_tag = tags;
- pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n",
- arp_op, slave_dev->name, &dest_ip, &src_ip);
+ netdev_dbg(slave_dev, "arp %d on slave %s: dst %pI4 src %pI4\n",
+ arp_op, slave_dev->name, &dest_ip, &src_ip);
skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
NULL, slave_dev->dev_addr, NULL);
@@ -2181,30 +2158,42 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
return;
}
+ if (!tags || tags->vlan_proto == VLAN_N_VID)
+ goto xmit;
+
+ tags++;
+
/* Go through all the tags backwards and add them to the packet */
- for (i = BOND_MAX_VLAN_ENCAP - 1; i > 0; i--) {
- if (!tags[i].vlan_id)
+ while (tags->vlan_proto != VLAN_N_VID) {
+ if (!tags->vlan_id) {
+ tags++;
continue;
+ }
- pr_debug("inner tag: proto %X vid %X\n",
- ntohs(tags[i].vlan_proto), tags[i].vlan_id);
- skb = __vlan_put_tag(skb, tags[i].vlan_proto,
- tags[i].vlan_id);
+ netdev_dbg(slave_dev, "inner tag: proto %X vid %X\n",
+ ntohs(outer_tag->vlan_proto), tags->vlan_id);
+ skb = __vlan_put_tag(skb, tags->vlan_proto,
+ tags->vlan_id);
if (!skb) {
net_err_ratelimited("failed to insert inner VLAN tag\n");
return;
}
+
+ tags++;
}
/* Set the outer tag */
- if (tags[0].vlan_id) {
- pr_debug("outer tag: proto %X vid %X\n",
- ntohs(tags[0].vlan_proto), tags[0].vlan_id);
- skb = vlan_put_tag(skb, tags[0].vlan_proto, tags[0].vlan_id);
+ if (outer_tag->vlan_id) {
+ netdev_dbg(slave_dev, "outer tag: proto %X vid %X\n",
+ ntohs(outer_tag->vlan_proto), outer_tag->vlan_id);
+ skb = vlan_put_tag(skb, outer_tag->vlan_proto,
+ outer_tag->vlan_id);
if (!skb) {
net_err_ratelimited("failed to insert outer VLAN tag\n");
return;
}
}
+
+xmit:
arp_xmit(skb);
}
@@ -2214,46 +2203,50 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
* When the path is validated, collect any vlan information in the
* path.
*/
-bool bond_verify_device_path(struct net_device *start_dev,
- struct net_device *end_dev,
- struct bond_vlan_tag *tags)
+struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
+ struct net_device *end_dev,
+ int level)
{
+ struct bond_vlan_tag *tags;
struct net_device *upper;
struct list_head *iter;
- int idx;
- if (start_dev == end_dev)
- return true;
+ if (start_dev == end_dev) {
+ tags = kzalloc(sizeof(*tags) * (level + 1), GFP_ATOMIC);
+ if (!tags)
+ return ERR_PTR(-ENOMEM);
+ tags[level].vlan_proto = VLAN_N_VID;
+ return tags;
+ }
netdev_for_each_upper_dev_rcu(start_dev, upper, iter) {
- if (bond_verify_device_path(upper, end_dev, tags)) {
- if (is_vlan_dev(upper)) {
- idx = vlan_get_encap_level(upper);
- if (idx >= BOND_MAX_VLAN_ENCAP)
- return false;
-
- tags[idx].vlan_proto =
- vlan_dev_vlan_proto(upper);
- tags[idx].vlan_id = vlan_dev_vlan_id(upper);
- }
- return true;
+ tags = bond_verify_device_path(upper, end_dev, level + 1);
+ if (IS_ERR_OR_NULL(tags)) {
+ if (IS_ERR(tags))
+ return tags;
+ continue;
}
+ if (is_vlan_dev(upper)) {
+ tags[level].vlan_proto = vlan_dev_vlan_proto(upper);
+ tags[level].vlan_id = vlan_dev_vlan_id(upper);
+ }
+
+ return tags;
}
- return false;
+ return NULL;
}
static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
{
struct rtable *rt;
- struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP];
+ struct bond_vlan_tag *tags;
__be32 *targets = bond->params.arp_targets, addr;
int i;
- bool ret;
for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
- pr_debug("basa: target %pI4\n", &targets[i]);
- memset(tags, 0, sizeof(tags));
+ netdev_dbg(bond->dev, "basa: target %pI4\n", &targets[i]);
+ tags = NULL;
/* Find out through which dev should the packet go */
rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
@@ -2276,16 +2269,15 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
goto found;
rcu_read_lock();
- ret = bond_verify_device_path(bond->dev, rt->dst.dev, tags);
+ tags = bond_verify_device_path(bond->dev, rt->dst.dev, 0);
rcu_read_unlock();
- if (ret)
+ if (!IS_ERR_OR_NULL(tags))
goto found;
/* Not our device - skip */
- pr_debug("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
- bond->dev->name, &targets[i],
- rt->dst.dev ? rt->dst.dev->name : "NULL");
+ netdev_dbg(bond->dev, "no path to arp_ip_target %pI4 via rt.dev %s\n",
+ &targets[i], rt->dst.dev ? rt->dst.dev->name : "NULL");
ip_rt_put(rt);
continue;
@@ -2295,6 +2287,7 @@ found:
ip_rt_put(rt);
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
addr, tags);
+ kfree(tags);
}
}
@@ -2303,13 +2296,15 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
int i;
if (!sip || !bond_has_this_ip(bond, tip)) {
- pr_debug("bva: sip %pI4 tip %pI4 not found\n", &sip, &tip);
+ netdev_dbg(bond->dev, "bva: sip %pI4 tip %pI4 not found\n",
+ &sip, &tip);
return;
}
i = bond_get_targets_ip(bond->params.arp_targets, sip);
if (i == -1) {
- pr_debug("bva: sip %pI4 not found in targets\n", &sip);
+ netdev_dbg(bond->dev, "bva: sip %pI4 not found in targets\n",
+ &sip);
return;
}
slave->last_rx = jiffies;
@@ -2336,8 +2331,8 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
alen = arp_hdr_len(bond->dev);
- pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
- bond->dev->name, skb->dev->name);
+ netdev_dbg(bond->dev, "bond_arp_rcv: skb->dev %s\n",
+ skb->dev->name);
if (alen > skb_headlen(skb)) {
arp = kmalloc(alen, GFP_ATOMIC);
@@ -2361,10 +2356,10 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
arp_ptr += 4 + bond->dev->addr_len;
memcpy(&tip, arp_ptr, 4);
- pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
- bond->dev->name, slave->dev->name, bond_slave_state(slave),
- bond->params.arp_validate, slave_do_arp_validate(bond, slave),
- &sip, &tip);
+ netdev_dbg(bond->dev, "bond_arp_rcv: %s/%d av %d sv %d sip %pI4 tip %pI4\n",
+ slave->dev->name, bond_slave_state(slave),
+ bond->params.arp_validate, slave_do_arp_validate(bond, slave),
+ &sip, &tip);
curr_active_slave = rcu_dereference(bond->curr_active_slave);
@@ -2429,7 +2424,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
rcu_read_lock();
- oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
+ oldcurrent = rcu_dereference(bond->curr_active_slave);
/* see if any of the previous devices are up now (i.e. they have
* xmt and rcv traffic). the curr_active_slave does not come into
* the picture unless it is null. also, slave->last_link_up is not
@@ -2454,14 +2449,12 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
* is closed.
*/
if (!oldcurrent) {
- pr_info("%s: link status definitely up for interface %s\n",
- bond->dev->name,
- slave->dev->name);
+ netdev_info(bond->dev, "link status definitely up for interface %s\n",
+ slave->dev->name);
do_failover = 1;
} else {
- pr_info("%s: interface %s is now up\n",
- bond->dev->name,
- slave->dev->name);
+ netdev_info(bond->dev, "interface %s is now up\n",
+ slave->dev->name);
}
}
} else {
@@ -2480,8 +2473,8 @@ static void bond_loadbalance_arp_mon(struct work_struct *work)
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
- pr_info("%s: interface %s is now down\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "interface %s is now down\n",
+ slave->dev->name);
if (slave == oldcurrent)
do_failover = 1;
@@ -2577,7 +2570,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
* before being taken out
*/
if (!bond_is_active_slave(slave) &&
- !bond->current_arp_slave &&
+ !rcu_access_pointer(bond->current_arp_slave) &&
!bond_time_in_interval(bond, last_rx, 3)) {
slave->new_link = BOND_LINK_DOWN;
commit++;
@@ -2620,21 +2613,24 @@ static void bond_ab_arp_commit(struct bonding *bond)
case BOND_LINK_UP:
trans_start = dev_trans_start(slave->dev);
- if (bond->curr_active_slave != slave ||
- (!bond->curr_active_slave &&
+ if (rtnl_dereference(bond->curr_active_slave) != slave ||
+ (!rtnl_dereference(bond->curr_active_slave) &&
bond_time_in_interval(bond, trans_start, 1))) {
+ struct slave *current_arp_slave;
+
+ current_arp_slave = rtnl_dereference(bond->current_arp_slave);
slave->link = BOND_LINK_UP;
- if (bond->current_arp_slave) {
+ if (current_arp_slave) {
bond_set_slave_inactive_flags(
- bond->current_arp_slave,
+ current_arp_slave,
BOND_SLAVE_NOTIFY_NOW);
- bond->current_arp_slave = NULL;
+ RCU_INIT_POINTER(bond->current_arp_slave, NULL);
}
- pr_info("%s: link status definitely up for interface %s\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "link status definitely up for interface %s\n",
+ slave->dev->name);
- if (!bond->curr_active_slave ||
+ if (!rtnl_dereference(bond->curr_active_slave) ||
(slave == bond->primary_slave))
goto do_failover;
@@ -2650,20 +2646,19 @@ static void bond_ab_arp_commit(struct bonding *bond)
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
- pr_info("%s: link status definitely down for interface %s, disabling it\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "link status definitely down for interface %s, disabling it\n",
+ slave->dev->name);
- if (slave == bond->curr_active_slave) {
- bond->current_arp_slave = NULL;
+ if (slave == rtnl_dereference(bond->curr_active_slave)) {
+ RCU_INIT_POINTER(bond->current_arp_slave, NULL);
goto do_failover;
}
continue;
default:
- pr_err("%s: impossible: new_link %d on slave %s\n",
- bond->dev->name, slave->new_link,
- slave->dev->name);
+ netdev_err(bond->dev, "impossible: new_link %d on slave %s\n",
+ slave->new_link, slave->dev->name);
continue;
}
@@ -2694,9 +2689,9 @@ static bool bond_ab_arp_probe(struct bonding *bond)
bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
if (curr_arp_slave && curr_active_slave)
- pr_info("PROBE: c_arp %s && cas %s BAD\n",
- curr_arp_slave->dev->name,
- curr_active_slave->dev->name);
+ netdev_info(bond->dev, "PROBE: c_arp %s && cas %s BAD\n",
+ curr_arp_slave->dev->name,
+ curr_active_slave->dev->name);
if (curr_active_slave) {
bond_arp_send_all(bond, curr_active_slave);
@@ -2737,8 +2732,8 @@ static bool bond_ab_arp_probe(struct bonding *bond)
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_LATER);
- pr_info("%s: backup interface %s is now down\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "backup interface %s is now down\n",
+ slave->dev->name);
}
if (slave == curr_arp_slave)
found = true;
@@ -2934,9 +2929,8 @@ static int bond_slave_netdev_event(unsigned long event,
break;
}
- pr_info("%s: Primary slave changed to %s, reselecting active slave\n",
- bond->dev->name,
- bond->primary_slave ? slave_dev->name : "none");
+ netdev_info(bond->dev, "Primary slave changed to %s, reselecting active slave\n",
+ bond->primary_slave ? slave_dev->name : "none");
block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
@@ -2971,19 +2965,18 @@ static int bond_netdev_event(struct notifier_block *this,
{
struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
- pr_debug("event_dev: %s, event: %lx\n",
- event_dev ? event_dev->name : "None", event);
+ netdev_dbg(event_dev, "event: %lx\n", event);
if (!(event_dev->priv_flags & IFF_BONDING))
return NOTIFY_DONE;
if (event_dev->flags & IFF_MASTER) {
- pr_debug("IFF_MASTER\n");
+ netdev_dbg(event_dev, "IFF_MASTER\n");
return bond_master_netdev_event(event, event_dev);
}
if (event_dev->flags & IFF_SLAVE) {
- pr_debug("IFF_SLAVE\n");
+ netdev_dbg(event_dev, "IFF_SLAVE\n");
return bond_slave_netdev_event(event, event_dev);
}
@@ -2999,11 +2992,11 @@ static struct notifier_block bond_netdev_notifier = {
/* L2 hash helper */
static inline u32 bond_eth_hash(struct sk_buff *skb)
{
- struct ethhdr *data = (struct ethhdr *)skb->data;
-
- if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
- return data->h_dest[5] ^ data->h_source[5];
+ struct ethhdr *ep, hdr_tmp;
+ ep = skb_header_pointer(skb, 0, sizeof(hdr_tmp), &hdr_tmp);
+ if (ep)
+ return ep->h_dest[5] ^ ep->h_source[5] ^ ep->h_proto;
return 0;
}
@@ -3110,8 +3103,8 @@ static int bond_open(struct net_device *bond_dev)
if (bond_has_slaves(bond)) {
read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, iter) {
- if (bond_uses_primary(bond)
- && (slave != bond->curr_active_slave)) {
+ if (bond_uses_primary(bond) &&
+ slave != rcu_access_pointer(bond->curr_active_slave)) {
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
} else {
@@ -3225,7 +3218,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
struct net *net;
int res = 0;
- pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd);
+ netdev_dbg(bond_dev, "bond_ioctl: cmd=%d\n", cmd);
switch (cmd) {
case SIOCGMIIPHY:
@@ -3295,12 +3288,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
slave_dev = __dev_get_by_name(net, ifr->ifr_slave);
- pr_debug("slave_dev=%p:\n", slave_dev);
+ netdev_dbg(bond_dev, "slave_dev=%p:\n", slave_dev);
if (!slave_dev)
return -ENODEV;
- pr_debug("slave_dev->name=%s:\n", slave_dev->name);
+ netdev_dbg(bond_dev, "slave_dev->name=%s:\n", slave_dev->name);
switch (cmd) {
case BOND_ENSLAVE_OLD:
case SIOCBONDENSLAVE:
@@ -3427,8 +3420,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
struct list_head *iter;
int res = 0;
- pr_debug("bond=%p, name=%s, new_mtu=%d\n",
- bond, bond_dev ? bond_dev->name : "None", new_mtu);
+ netdev_dbg(bond_dev, "bond=%p, new_mtu=%d\n", bond, new_mtu);
/* Can't hold bond->lock with bh disabled here since
* some base drivers panic. On the other hand we can't
@@ -3446,8 +3438,8 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
*/
bond_for_each_slave(bond, slave, iter) {
- pr_debug("s %p c_m %p\n",
- slave, slave->dev->netdev_ops->ndo_change_mtu);
+ netdev_dbg(bond_dev, "s %p c_m %p\n",
+ slave, slave->dev->netdev_ops->ndo_change_mtu);
res = dev_set_mtu(slave->dev, new_mtu);
@@ -3460,7 +3452,8 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
* means changing their mtu from timer context, which
* is probably not a good idea.
*/
- pr_debug("err %d %s\n", res, slave->dev->name);
+ netdev_dbg(bond_dev, "err %d %s\n", res,
+ slave->dev->name);
goto unwind;
}
}
@@ -3479,8 +3472,8 @@ unwind:
tmp_res = dev_set_mtu(rollback_slave->dev, bond_dev->mtu);
if (tmp_res) {
- pr_debug("unwind err %d dev %s\n",
- tmp_res, rollback_slave->dev->name);
+ netdev_dbg(bond_dev, "unwind err %d dev %s\n",
+ tmp_res, rollback_slave->dev->name);
}
}
@@ -3506,8 +3499,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
return bond_alb_set_mac_address(bond_dev, addr);
- pr_debug("bond=%p, name=%s\n",
- bond, bond_dev ? bond_dev->name : "None");
+ netdev_dbg(bond_dev, "bond=%p\n", bond);
/* If fail_over_mac is enabled, do nothing and return success.
* Returning an error causes ifenslave to fail.
@@ -3535,7 +3527,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
*/
bond_for_each_slave(bond, slave, iter) {
- pr_debug("slave %p %s\n", slave, slave->dev->name);
+ netdev_dbg(bond_dev, "slave %p %s\n", slave, slave->dev->name);
res = dev_set_mac_address(slave->dev, addr);
if (res) {
/* TODO: consider downing the slave
@@ -3544,7 +3536,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
* breakage anyway until ARP finish
* updating, so...
*/
- pr_debug("err %d %s\n", res, slave->dev->name);
+ netdev_dbg(bond_dev, "err %d %s\n", res, slave->dev->name);
goto unwind;
}
}
@@ -3566,8 +3558,8 @@ unwind:
tmp_res = dev_set_mac_address(rollback_slave->dev, &tmp_sa);
if (tmp_res) {
- pr_debug("unwind err %d dev %s\n",
- tmp_res, rollback_slave->dev->name);
+ netdev_dbg(bond_dev, "unwind err %d dev %s\n",
+ tmp_res, rollback_slave->dev->name);
}
}
@@ -3814,8 +3806,7 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev
return bond_tlb_xmit(skb, dev);
default:
/* Should never happen, mode already checked */
- pr_err("%s: Error: Unknown bonding mode %d\n",
- dev->name, BOND_MODE(bond));
+ netdev_err(dev, "Unknown bonding mode %d\n", BOND_MODE(bond));
WARN_ON_ONCE(1);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
@@ -3956,13 +3947,6 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
- /* At first, we block adding VLANs. That's the only way to
- * prevent problems that occur when adding VLANs over an
- * empty bond. The block will be removed once non-challenged
- * slaves are enslaved.
- */
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-
/* don't acquire bond device's netif_tx_lock when
* transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4002,7 +3986,7 @@ static void bond_uninit(struct net_device *bond_dev)
/* Release the bonded slaves */
bond_for_each_slave(bond, slave, iter)
__bond_release_one(bond_dev, slave->dev, true);
- pr_info("%s: Released all slaves\n", bond_dev->name);
+ netdev_info(bond_dev, "Released all slaves\n");
list_del(&bond->bond_list);
@@ -4068,7 +4052,7 @@ static int bond_check_params(struct bond_params *params)
}
if (ad_select) {
- bond_opt_initstr(&newval, lacp_rate);
+ bond_opt_initstr(&newval, ad_select);
valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_SELECT),
&newval);
if (!valptr) {
@@ -4391,7 +4375,7 @@ static int bond_init(struct net_device *bond_dev)
struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- pr_debug("Begin bond_init for %s\n", bond_dev->name);
+ netdev_dbg(bond_dev, "Begin bond_init\n");
/*
* Initialize locks that may be required during
@@ -4440,7 +4424,7 @@ int bond_create(struct net *net, const char *name)
rtnl_lock();
bond_dev = alloc_netdev_mq(sizeof(struct bonding),
- name ? name : "bond%d",
+ name ? name : "bond%d", NET_NAME_UNKNOWN,
bond_setup, tx_queues);
if (!bond_dev) {
pr_err("%s: eek! can't alloc netdev!\n", name);
@@ -4481,7 +4465,6 @@ static void __net_exit bond_net_exit(struct net *net)
LIST_HEAD(list);
bond_destroy_sysfs(bn);
- bond_destroy_proc_dir(bn);
/* Kill off any bonds created after unregistering bond rtnl ops */
rtnl_lock();
@@ -4489,6 +4472,8 @@ static void __net_exit bond_net_exit(struct net *net)
unregister_netdevice_queue(bond->dev, &list);
unregister_netdevice_many(&list);
rtnl_unlock();
+
+ bond_destroy_proc_dir(bn);
}
static struct pernet_operations bond_net_ops = {
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index 5ab3c1847e67..d163e112f04c 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -9,8 +9,6 @@
* (at your option) any later version.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
@@ -181,8 +179,7 @@ static int bond_changelink(struct net_device *bond_dev,
int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
if (arp_interval && miimon) {
- pr_err("%s: ARP monitoring cannot be used with MII monitoring\n",
- bond->dev->name);
+ netdev_err(bond->dev, "ARP monitoring cannot be used with MII monitoring\n");
return -EINVAL;
}
@@ -207,8 +204,7 @@ static int bond_changelink(struct net_device *bond_dev,
i++;
}
if (i == 0 && bond->params.arp_interval)
- pr_warn("%s: Removing last arp target with arp_interval on\n",
- bond->dev->name);
+ netdev_warn(bond->dev, "Removing last arp target with arp_interval on\n");
if (err)
return err;
}
@@ -216,8 +212,7 @@ static int bond_changelink(struct net_device *bond_dev,
int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
if (arp_validate && miimon) {
- pr_err("%s: ARP validating cannot be used with MII monitoring\n",
- bond->dev->name);
+ netdev_err(bond->dev, "ARP validating cannot be used with MII monitoring\n");
return -EINVAL;
}
@@ -398,20 +393,31 @@ static size_t bond_get_size(const struct net_device *bond_dev)
0;
}
+static int bond_option_active_slave_get_ifindex(struct bonding *bond)
+{
+ const struct net_device *slave;
+ int ifindex;
+
+ rcu_read_lock();
+ slave = bond_option_active_slave_get_rcu(bond);
+ ifindex = slave ? slave->ifindex : 0;
+ rcu_read_unlock();
+ return ifindex;
+}
+
static int bond_fill_info(struct sk_buff *skb,
const struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- struct net_device *slave_dev = bond_option_active_slave_get(bond);
- struct nlattr *targets;
unsigned int packets_per_slave;
- int i, targets_added;
+ int ifindex, i, targets_added;
+ struct nlattr *targets;
if (nla_put_u8(skb, IFLA_BOND_MODE, BOND_MODE(bond)))
goto nla_put_failure;
- if (slave_dev &&
- nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
+ ifindex = bond_option_active_slave_get_ifindex(bond);
+ if (ifindex && nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, ifindex))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 540e0167bf24..dc73463c2c23 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -9,8 +9,6 @@
* (at your option) any later version.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/errno.h>
#include <linux/if.h>
#include <linux/netdevice.h>
@@ -544,9 +542,8 @@ static void bond_opt_dep_print(struct bonding *bond,
params = &bond->params;
modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode);
if (test_bit(params->mode, &opt->unsuppmodes))
- pr_err("%s: option %s: mode dependency failed, not supported in mode %s(%llu)\n",
- bond->dev->name, opt->name,
- modeval->string, modeval->value);
+ netdev_err(bond->dev, "option %s: mode dependency failed, not supported in mode %s(%llu)\n",
+ opt->name, modeval->string, modeval->value);
}
static void bond_opt_error_interpret(struct bonding *bond,
@@ -564,31 +561,30 @@ static void bond_opt_error_interpret(struct bonding *bond,
p = strchr(val->string, '\n');
if (p)
*p = '\0';
- pr_err("%s: option %s: invalid value (%s)\n",
- bond->dev->name, opt->name, val->string);
+ netdev_err(bond->dev, "option %s: invalid value (%s)\n",
+ opt->name, val->string);
} else {
- pr_err("%s: option %s: invalid value (%llu)\n",
- bond->dev->name, opt->name, val->value);
+ netdev_err(bond->dev, "option %s: invalid value (%llu)\n",
+ opt->name, val->value);
}
}
minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN);
maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX);
if (!maxval)
break;
- pr_err("%s: option %s: allowed values %llu - %llu\n",
- bond->dev->name, opt->name, minval ? minval->value : 0,
- maxval->value);
+ netdev_err(bond->dev, "option %s: allowed values %llu - %llu\n",
+ opt->name, minval ? minval->value : 0, maxval->value);
break;
case -EACCES:
bond_opt_dep_print(bond, opt);
break;
case -ENOTEMPTY:
- pr_err("%s: option %s: unable to set because the bond device has slaves\n",
- bond->dev->name, opt->name);
+ netdev_err(bond->dev, "option %s: unable to set because the bond device has slaves\n",
+ opt->name);
break;
case -EBUSY:
- pr_err("%s: option %s: unable to set because the bond device is up\n",
- bond->dev->name, opt->name);
+ netdev_err(bond->dev, "option %s: unable to set because the bond device is up\n",
+ opt->name);
break;
default:
break;
@@ -671,17 +667,18 @@ const struct bond_option *bond_opt_get(unsigned int option)
return &bond_opts[option];
}
-int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval)
+static int bond_option_mode_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
{
if (!bond_mode_uses_arp(newval->value) && bond->params.arp_interval) {
- pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
- bond->dev->name, newval->string);
+ netdev_info(bond->dev, "%s mode is incompatible with arp monitoring, start mii monitoring\n",
+ newval->string);
/* disable arp monitoring */
bond->params.arp_interval = 0;
/* set miimon to default value */
bond->params.miimon = BOND_DEFAULT_MIIMON;
- pr_info("%s: Setting MII monitoring interval to %d\n",
- bond->dev->name, bond->params.miimon);
+ netdev_info(bond->dev, "Setting MII monitoring interval to %d\n",
+ bond->params.miimon);
}
/* don't cache arp_validate between modes */
@@ -704,11 +701,6 @@ struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
return __bond_option_active_slave_get(bond, slave);
}
-struct net_device *bond_option_active_slave_get(struct bonding *bond)
-{
- return __bond_option_active_slave_get(bond, bond->curr_active_slave);
-}
-
static int bond_option_active_slave_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
@@ -727,14 +719,14 @@ static int bond_option_active_slave_set(struct bonding *bond,
if (slave_dev) {
if (!netif_is_bond_slave(slave_dev)) {
- pr_err("Device %s is not bonding slave\n",
- slave_dev->name);
+ netdev_err(bond->dev, "Device %s is not bonding slave\n",
+ slave_dev->name);
return -EINVAL;
}
if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
- pr_err("%s: Device %s is not our slave\n",
- bond->dev->name, slave_dev->name);
+ netdev_err(bond->dev, "Device %s is not our slave\n",
+ slave_dev->name);
return -EINVAL;
}
}
@@ -744,29 +736,29 @@ static int bond_option_active_slave_set(struct bonding *bond,
/* check to see if we are clearing active */
if (!slave_dev) {
- pr_info("%s: Clearing current active slave\n", bond->dev->name);
+ netdev_info(bond->dev, "Clearing current active slave\n");
RCU_INIT_POINTER(bond->curr_active_slave, NULL);
bond_select_active_slave(bond);
} else {
- struct slave *old_active = bond->curr_active_slave;
+ struct slave *old_active = bond_deref_active_protected(bond);
struct slave *new_active = bond_slave_get_rtnl(slave_dev);
BUG_ON(!new_active);
if (new_active == old_active) {
/* do nothing */
- pr_info("%s: %s is already the current active slave\n",
- bond->dev->name, new_active->dev->name);
+ netdev_info(bond->dev, "%s is already the current active slave\n",
+ new_active->dev->name);
} else {
if (old_active && (new_active->link == BOND_LINK_UP) &&
bond_slave_is_up(new_active)) {
- pr_info("%s: Setting %s as active slave\n",
- bond->dev->name, new_active->dev->name);
+ netdev_info(bond->dev, "Setting %s as active slave\n",
+ new_active->dev->name);
bond_change_active_slave(bond, new_active);
} else {
- pr_err("%s: Could not set %s as active slave; either %s is down or the link is down\n",
- bond->dev->name, new_active->dev->name,
- new_active->dev->name);
+ netdev_err(bond->dev, "Could not set %s as active slave; either %s is down or the link is down\n",
+ new_active->dev->name,
+ new_active->dev->name);
ret = -EINVAL;
}
}
@@ -785,20 +777,17 @@ static int bond_option_active_slave_set(struct bonding *bond,
static int bond_option_miimon_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting MII monitoring interval to %llu\n",
- bond->dev->name, newval->value);
+ netdev_info(bond->dev, "Setting MII monitoring interval to %llu\n",
+ newval->value);
bond->params.miimon = newval->value;
if (bond->params.updelay)
- pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value\n",
- bond->dev->name,
+ netdev_info(bond->dev, "Note: Updating updelay (to %d) since it is a multiple of the miimon value\n",
bond->params.updelay * bond->params.miimon);
if (bond->params.downdelay)
- pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
- bond->dev->name,
- bond->params.downdelay * bond->params.miimon);
+ netdev_info(bond->dev, "Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
+ bond->params.downdelay * bond->params.miimon);
if (newval->value && bond->params.arp_interval) {
- pr_info("%s: MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n",
- bond->dev->name);
+ netdev_info(bond->dev, "MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n");
bond->params.arp_interval = 0;
if (bond->params.arp_validate)
bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
@@ -830,20 +819,18 @@ static int bond_option_updelay_set(struct bonding *bond,
int value = newval->value;
if (!bond->params.miimon) {
- pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
- bond->dev->name);
+ netdev_err(bond->dev, "Unable to set up delay as MII monitoring is disabled\n");
return -EPERM;
}
if ((value % bond->params.miimon) != 0) {
- pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
- bond->dev->name, value,
- bond->params.miimon,
- (value / bond->params.miimon) *
- bond->params.miimon);
+ netdev_warn(bond->dev, "up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
+ value, bond->params.miimon,
+ (value / bond->params.miimon) *
+ bond->params.miimon);
}
bond->params.updelay = value / bond->params.miimon;
- pr_info("%s: Setting up delay to %d\n",
- bond->dev->name, bond->params.updelay * bond->params.miimon);
+ netdev_info(bond->dev, "Setting up delay to %d\n",
+ bond->params.updelay * bond->params.miimon);
return 0;
}
@@ -854,20 +841,18 @@ static int bond_option_downdelay_set(struct bonding *bond,
int value = newval->value;
if (!bond->params.miimon) {
- pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
- bond->dev->name);
+ netdev_err(bond->dev, "Unable to set down delay as MII monitoring is disabled\n");
return -EPERM;
}
if ((value % bond->params.miimon) != 0) {
- pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
- bond->dev->name, value,
- bond->params.miimon,
- (value / bond->params.miimon) *
- bond->params.miimon);
+ netdev_warn(bond->dev, "down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
+ value, bond->params.miimon,
+ (value / bond->params.miimon) *
+ bond->params.miimon);
}
bond->params.downdelay = value / bond->params.miimon;
- pr_info("%s: Setting down delay to %d\n",
- bond->dev->name, bond->params.downdelay * bond->params.miimon);
+ netdev_info(bond->dev, "Setting down delay to %d\n",
+ bond->params.downdelay * bond->params.miimon);
return 0;
}
@@ -875,8 +860,8 @@ static int bond_option_downdelay_set(struct bonding *bond,
static int bond_option_use_carrier_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting use_carrier to %llu\n",
- bond->dev->name, newval->value);
+ netdev_info(bond->dev, "Setting use_carrier to %llu\n",
+ newval->value);
bond->params.use_carrier = newval->value;
return 0;
@@ -889,18 +874,16 @@ static int bond_option_use_carrier_set(struct bonding *bond,
static int bond_option_arp_interval_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting ARP monitoring interval to %llu\n",
- bond->dev->name, newval->value);
+ netdev_info(bond->dev, "Setting ARP monitoring interval to %llu\n",
+ newval->value);
bond->params.arp_interval = newval->value;
if (newval->value) {
if (bond->params.miimon) {
- pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring\n",
- bond->dev->name, bond->dev->name);
+ netdev_info(bond->dev, "ARP monitoring cannot be used with MII monitoring. Disabling MII monitoring\n");
bond->params.miimon = 0;
}
if (!bond->params.arp_targets[0])
- pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified\n",
- bond->dev->name);
+ netdev_info(bond->dev, "ARP monitoring has been set up, but no ARP targets have been specified\n");
}
if (bond->dev->flags & IFF_UP) {
/* If the interface is up, we may need to fire off
@@ -944,24 +927,24 @@ static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)
int ind;
if (!bond_is_ip_target_ok(target)) {
- pr_err("%s: invalid ARP target %pI4 specified for addition\n",
- bond->dev->name, &target);
+ netdev_err(bond->dev, "invalid ARP target %pI4 specified for addition\n",
+ &target);
return -EINVAL;
}
if (bond_get_targets_ip(targets, target) != -1) { /* dup */
- pr_err("%s: ARP target %pI4 is already present\n",
- bond->dev->name, &target);
+ netdev_err(bond->dev, "ARP target %pI4 is already present\n",
+ &target);
return -EINVAL;
}
ind = bond_get_targets_ip(targets, 0); /* first free slot */
if (ind == -1) {
- pr_err("%s: ARP target table is full!\n", bond->dev->name);
+ netdev_err(bond->dev, "ARP target table is full!\n");
return -EINVAL;
}
- pr_info("%s: Adding ARP target %pI4\n", bond->dev->name, &target);
+ netdev_info(bond->dev, "Adding ARP target %pI4\n", &target);
_bond_options_arp_ip_target_set(bond, ind, target, jiffies);
@@ -989,23 +972,22 @@ static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target)
int ind, i;
if (!bond_is_ip_target_ok(target)) {
- pr_err("%s: invalid ARP target %pI4 specified for removal\n",
- bond->dev->name, &target);
+ netdev_err(bond->dev, "invalid ARP target %pI4 specified for removal\n",
+ &target);
return -EINVAL;
}
ind = bond_get_targets_ip(targets, target);
if (ind == -1) {
- pr_err("%s: unable to remove nonexistent ARP target %pI4\n",
- bond->dev->name, &target);
+ netdev_err(bond->dev, "unable to remove nonexistent ARP target %pI4\n",
+ &target);
return -EINVAL;
}
if (ind == 0 && !targets[1] && bond->params.arp_interval)
- pr_warn("%s: Removing last arp target with arp_interval on\n",
- bond->dev->name);
+ netdev_warn(bond->dev, "Removing last arp target with arp_interval on\n");
- pr_info("%s: Removing ARP target %pI4\n", bond->dev->name, &target);
+ netdev_info(bond->dev, "Removing ARP target %pI4\n", &target);
/* not to race with bond_arp_rcv */
write_lock_bh(&bond->lock);
@@ -1044,8 +1026,8 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
if (newval->string) {
if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) {
- pr_err("%s: invalid ARP target %pI4 specified\n",
- bond->dev->name, &target);
+ netdev_err(bond->dev, "invalid ARP target %pI4 specified\n",
+ &target);
return ret;
}
if (newval->string[0] == '+')
@@ -1053,8 +1035,7 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
else if (newval->string[0] == '-')
ret = bond_option_arp_ip_target_rem(bond, target);
else
- pr_err("no command found in arp_ip_targets file for bond %s - use +<addr> or -<addr>\n",
- bond->dev->name);
+ netdev_err(bond->dev, "no command found in arp_ip_targets file - use +<addr> or -<addr>\n");
} else {
target = newval->value;
ret = bond_option_arp_ip_target_add(bond, target);
@@ -1066,8 +1047,8 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
static int bond_option_arp_validate_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting arp_validate to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting arp_validate to %s (%llu)\n",
+ newval->string, newval->value);
if (bond->dev->flags & IFF_UP) {
if (!newval->value)
@@ -1083,8 +1064,8 @@ static int bond_option_arp_validate_set(struct bonding *bond,
static int bond_option_arp_all_targets_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting arp_all_targets to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting arp_all_targets to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.arp_all_targets = newval->value;
return 0;
@@ -1106,7 +1087,7 @@ static int bond_option_primary_set(struct bonding *bond,
*p = '\0';
/* check to see if we are clearing primary */
if (!strlen(primary)) {
- pr_info("%s: Setting primary slave to None\n", bond->dev->name);
+ netdev_info(bond->dev, "Setting primary slave to None\n");
bond->primary_slave = NULL;
memset(bond->params.primary, 0, sizeof(bond->params.primary));
bond_select_active_slave(bond);
@@ -1115,8 +1096,8 @@ static int bond_option_primary_set(struct bonding *bond,
bond_for_each_slave(bond, slave, iter) {
if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) {
- pr_info("%s: Setting %s as primary slave\n",
- bond->dev->name, slave->dev->name);
+ netdev_info(bond->dev, "Setting %s as primary slave\n",
+ slave->dev->name);
bond->primary_slave = slave;
strcpy(bond->params.primary, slave->dev->name);
bond_select_active_slave(bond);
@@ -1125,15 +1106,15 @@ static int bond_option_primary_set(struct bonding *bond,
}
if (bond->primary_slave) {
- pr_info("%s: Setting primary slave to None\n", bond->dev->name);
+ netdev_info(bond->dev, "Setting primary slave to None\n");
bond->primary_slave = NULL;
bond_select_active_slave(bond);
}
strncpy(bond->params.primary, primary, IFNAMSIZ);
bond->params.primary[IFNAMSIZ - 1] = 0;
- pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet\n",
- bond->dev->name, primary, bond->dev->name);
+ netdev_info(bond->dev, "Recording %s as primary, but it has not been enslaved to %s yet\n",
+ primary, bond->dev->name);
out:
write_unlock_bh(&bond->curr_slave_lock);
@@ -1146,8 +1127,8 @@ out:
static int bond_option_primary_reselect_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting primary_reselect to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting primary_reselect to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.primary_reselect = newval->value;
block_netpoll_tx();
@@ -1162,8 +1143,8 @@ static int bond_option_primary_reselect_set(struct bonding *bond,
static int bond_option_fail_over_mac_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting fail_over_mac to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting fail_over_mac to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.fail_over_mac = newval->value;
return 0;
@@ -1172,8 +1153,8 @@ static int bond_option_fail_over_mac_set(struct bonding *bond,
static int bond_option_xmit_hash_policy_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting xmit hash policy to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting xmit hash policy to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.xmit_policy = newval->value;
return 0;
@@ -1182,8 +1163,8 @@ static int bond_option_xmit_hash_policy_set(struct bonding *bond,
static int bond_option_resend_igmp_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting resend_igmp to %llu\n",
- bond->dev->name, newval->value);
+ netdev_info(bond->dev, "Setting resend_igmp to %llu\n",
+ newval->value);
bond->params.resend_igmp = newval->value;
return 0;
@@ -1221,8 +1202,8 @@ static int bond_option_all_slaves_active_set(struct bonding *bond,
static int bond_option_min_links_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting min links value to %llu\n",
- bond->dev->name, newval->value);
+ netdev_info(bond->dev, "Setting min links value to %llu\n",
+ newval->value);
bond->params.min_links = newval->value;
return 0;
@@ -1257,8 +1238,8 @@ static int bond_option_pps_set(struct bonding *bond,
static int bond_option_lacp_rate_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting LACP rate to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting LACP rate to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.lacp_fast = newval->value;
bond_3ad_update_lacp_rate(bond);
@@ -1268,8 +1249,8 @@ static int bond_option_lacp_rate_set(struct bonding *bond,
static int bond_option_ad_select_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting ad_select to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting ad_select to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.ad_select = newval->value;
return 0;
@@ -1330,7 +1311,7 @@ out:
return ret;
err_no_cmd:
- pr_info("invalid input for queue_id set for %s\n", bond->dev->name);
+ netdev_info(bond->dev, "invalid input for queue_id set\n");
ret = -EPERM;
goto out;
@@ -1352,20 +1333,20 @@ static int bond_option_slaves_set(struct bonding *bond,
dev = __dev_get_by_name(dev_net(bond->dev), ifname);
if (!dev) {
- pr_info("%s: interface %s does not exist!\n",
- bond->dev->name, ifname);
+ netdev_info(bond->dev, "interface %s does not exist!\n",
+ ifname);
ret = -ENODEV;
goto out;
}
switch (command[0]) {
case '+':
- pr_info("%s: Adding slave %s\n", bond->dev->name, dev->name);
+ netdev_info(bond->dev, "Adding slave %s\n", dev->name);
ret = bond_enslave(bond->dev, dev);
break;
case '-':
- pr_info("%s: Removing slave %s\n", bond->dev->name, dev->name);
+ netdev_info(bond->dev, "Removing slave %s\n", dev->name);
ret = bond_release(bond->dev, dev);
break;
@@ -1377,8 +1358,7 @@ out:
return ret;
err_no_cmd:
- pr_err("no command found in slaves file for bond %s - use +ifname or -ifname\n",
- bond->dev->name);
+ netdev_err(bond->dev, "no command found in slaves file - use +ifname or -ifname\n");
ret = -EPERM;
goto out;
}
@@ -1386,8 +1366,8 @@ err_no_cmd:
static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
- pr_info("%s: Setting dynamic-lb to %s (%llu)\n",
- bond->dev->name, newval->string, newval->value);
+ netdev_info(bond->dev, "Setting dynamic-lb to %s (%llu)\n",
+ newval->string, newval->value);
bond->params.tlb_dynamic_lb = newval->value;
return 0;
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index b215b479bb3a..de62c0385dfb 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -252,8 +252,8 @@ void bond_create_proc_entry(struct bonding *bond)
S_IRUGO, bn->proc_dir,
&bond_info_fops, bond);
if (bond->proc_entry == NULL)
- pr_warn("Warning: Cannot create /proc/net/%s/%s\n",
- DRV_NAME, bond_dev->name);
+ netdev_warn(bond_dev, "Cannot create /proc/net/%s/%s\n",
+ DRV_NAME, bond_dev->name);
else
memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index daed52f68ce1..98db8edd9c75 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -492,8 +492,9 @@ static ssize_t bonding_show_mii_status(struct device *d,
char *buf)
{
struct bonding *bond = to_bond(d);
+ bool active = !!rcu_access_pointer(bond->curr_active_slave);
- return sprintf(buf, "%s\n", bond->curr_active_slave ? "up" : "down");
+ return sprintf(buf, "%s\n", active ? "up" : "down");
}
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c
index 198677f58ce0..5cd532ca1cfe 100644
--- a/drivers/net/bonding/bond_sysfs_slave.c
+++ b/drivers/net/bonding/bond_sysfs_slave.c
@@ -125,7 +125,7 @@ int bond_sysfs_slave_add(struct slave *slave)
for (a = slave_attrs; *a; ++a) {
err = sysfs_create_file(&slave->kobj, &((*a)->attr));
if (err) {
- kobject_del(&slave->kobj);
+ kobject_put(&slave->kobj);
return err;
}
}
@@ -140,5 +140,5 @@ void bond_sysfs_slave_del(struct slave *slave)
for (a = slave_attrs; *a; ++a)
sysfs_remove_file(&slave->kobj, &((*a)->attr));
- kobject_del(&slave->kobj);
+ kobject_put(&slave->kobj);
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 0b4d9cde0b05..aace510d08d1 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -36,7 +36,6 @@
#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
-#define BOND_MAX_VLAN_ENCAP 2
#define BOND_MAX_ARP_TARGETS 16
#define BOND_DEFAULT_MIIMON 100
@@ -194,8 +193,8 @@ struct slave {
*/
struct bonding {
struct net_device *dev; /* first - useful for panic debug */
- struct slave *curr_active_slave;
- struct slave *current_arp_slave;
+ struct slave __rcu *curr_active_slave;
+ struct slave __rcu *current_arp_slave;
struct slave *primary_slave;
bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
@@ -232,6 +231,10 @@ struct bonding {
#define bond_slave_get_rtnl(dev) \
((struct slave *) rtnl_dereference(dev->rx_handler_data))
+#define bond_deref_active_protected(bond) \
+ rcu_dereference_protected(bond->curr_active_slave, \
+ lockdep_is_held(&bond->curr_slave_lock))
+
struct bond_vlan_tag {
__be16 vlan_proto;
unsigned short vlan_id;
@@ -265,6 +268,12 @@ static inline bool bond_is_lb(const struct bonding *bond)
BOND_MODE(bond) == BOND_MODE_ALB;
}
+static inline bool bond_is_nondyn_tlb(const struct bonding *bond)
+{
+ return (BOND_MODE(bond) == BOND_MODE_TLB) &&
+ (bond->params.tlb_dynamic_lb == 0);
+}
+
static inline bool bond_mode_uses_arp(int mode)
{
return mode != BOND_MODE_8023AD && mode != BOND_MODE_TLB &&
@@ -514,11 +523,10 @@ unsigned int bond_get_num_tx_queues(void);
int bond_netlink_init(void);
void bond_netlink_fini(void);
struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
-struct net_device *bond_option_active_slave_get(struct bonding *bond);
const char *bond_slave_link_status(s8 link);
-bool bond_verify_device_path(struct net_device *start_dev,
- struct net_device *end_dev,
- struct bond_vlan_tag *tags);
+struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev,
+ struct net_device *end_dev,
+ int level);
#ifdef CONFIG_PROC_FS
void bond_create_proc_entry(struct bonding *bond);
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index fc73865bb83a..27bbc56de15f 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -349,7 +349,8 @@ static int ldisc_open(struct tty_struct *tty)
result = snprintf(name, sizeof(name), "cf%s", tty->name);
if (result >= IFNAMSIZ)
return -EINVAL;
- dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
+ dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN,
+ caifdev_setup);
if (!dev)
return -ENOMEM;
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
index ff54c0eb2052..72ea9ff9bb9c 100644
--- a/drivers/net/caif/caif_spi.c
+++ b/drivers/net/caif/caif_spi.c
@@ -730,8 +730,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
int res;
dev = (struct cfspi_dev *)pdev->dev.platform_data;
- ndev = alloc_netdev(sizeof(struct cfspi),
- "cfspi%d", cfspi_setup);
+ ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d",
+ NET_NAME_UNKNOWN, cfspi_setup);
if (!dev)
return -ENODEV;
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
index 985608634f8c..a5fefb9059c5 100644
--- a/drivers/net/caif/caif_virtio.c
+++ b/drivers/net/caif/caif_virtio.c
@@ -661,7 +661,7 @@ static int cfv_probe(struct virtio_device *vdev)
int err = -EINVAL;
netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
- cfv_netdev_setup);
+ NET_NAME_UNKNOWN, cfv_netdev_setup);
if (!netdev)
return -ENOMEM;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index 824108cd9fd5..5dede6e64376 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -208,40 +208,31 @@ static int c_can_plat_probe(struct platform_device *pdev)
}
/* get the appropriate clk */
- clk = clk_get(&pdev->dev, NULL);
+ clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "no clock defined\n");
- ret = -ENODEV;
+ ret = PTR_ERR(clk);
goto exit;
}
/* get the platform data */
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- if (!mem || irq <= 0) {
+ if (irq <= 0) {
ret = -ENODEV;
- goto exit_free_clk;
- }
-
- if (!request_mem_region(mem->start, resource_size(mem),
- KBUILD_MODNAME)) {
- dev_err(&pdev->dev, "resource unavailable\n");
- ret = -ENODEV;
- goto exit_free_clk;
+ goto exit;
}
- addr = ioremap(mem->start, resource_size(mem));
- if (!addr) {
- dev_err(&pdev->dev, "failed to map can port\n");
- ret = -ENOMEM;
- goto exit_release_mem;
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ addr = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto exit;
}
/* allocate the c_can device */
dev = alloc_c_can_dev();
if (!dev) {
ret = -ENOMEM;
- goto exit_iounmap;
+ goto exit;
}
priv = netdev_priv(dev);
@@ -287,7 +278,8 @@ static int c_can_plat_probe(struct platform_device *pdev)
break;
}
- priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res);
+ priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
dev_info(&pdev->dev, "control memory is not used for raminit\n");
else
@@ -321,12 +313,6 @@ static int c_can_plat_probe(struct platform_device *pdev)
exit_free_device:
free_c_can_dev(dev);
-exit_iounmap:
- iounmap(addr);
-exit_release_mem:
- release_mem_region(mem->start, resource_size(mem));
-exit_free_clk:
- clk_put(clk);
exit:
dev_err(&pdev->dev, "probe failed\n");
@@ -336,18 +322,10 @@ exit:
static int c_can_plat_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
- struct c_can_priv *priv = netdev_priv(dev);
- struct resource *mem;
unregister_c_can_dev(dev);
free_c_can_dev(dev);
- iounmap(priv->base);
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem->start, resource_size(mem));
-
- clk_put(priv->priv);
return 0;
}
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index e318e87e2bfc..9f91fcba43f8 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -565,7 +565,7 @@ struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
else
size = sizeof_priv;
- dev = alloc_netdev(size, "can%d", can_setup);
+ dev = alloc_netdev(size, "can%d", NET_NAME_UNKNOWN, can_setup);
if (!dev)
return NULL;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index f31499a32d7d..d1692154ed1b 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -141,6 +141,7 @@ static void set_normal_mode(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
unsigned char status = priv->read_reg(priv, SJA1000_MOD);
+ u8 mod_reg_val = 0x00;
int i;
for (i = 0; i < 100; i++) {
@@ -158,9 +159,10 @@ static void set_normal_mode(struct net_device *dev)
/* set chip to normal mode */
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
- priv->write_reg(priv, SJA1000_MOD, MOD_LOM);
- else
- priv->write_reg(priv, SJA1000_MOD, 0x00);
+ mod_reg_val |= MOD_LOM;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK)
+ mod_reg_val |= MOD_STM;
+ priv->write_reg(priv, SJA1000_MOD, mod_reg_val);
udelay(10);
@@ -278,6 +280,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
uint8_t dlc;
canid_t id;
uint8_t dreg;
+ u8 cmd_reg_val = 0x00;
int i;
if (can_dropped_invalid_skb(dev, skb))
@@ -312,9 +315,14 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
can_put_echo_skb(skb, dev, 0);
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
- sja1000_write_cmdreg(priv, CMD_TR | CMD_AT);
+ cmd_reg_val |= CMD_AT;
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ cmd_reg_val |= CMD_SRR;
else
- sja1000_write_cmdreg(priv, CMD_TR);
+ cmd_reg_val |= CMD_TR;
+
+ sja1000_write_cmdreg(priv, cmd_reg_val);
return NETDEV_TX_OK;
}
@@ -622,9 +630,12 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
priv->can.do_set_bittiming = sja1000_set_bittiming;
priv->can.do_set_mode = sja1000_set_mode;
priv->can.do_get_berr_counter = sja1000_get_berr_counter;
- priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
- CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY |
- CAN_CTRLMODE_ONE_SHOT;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_ONE_SHOT |
+ CAN_CTRLMODE_BERR_REPORTING |
+ CAN_CTRLMODE_PRESUME_ACK;
spin_lock_init(&priv->cmdreg_lock);
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index ea4d4f1a6411..acb5b92ace92 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -529,7 +529,7 @@ static struct slcan *slc_alloc(dev_t line)
return NULL;
sprintf(name, "slcan%d", i);
- dev = alloc_netdev(sizeof(*sl), name, slc_setup);
+ dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, slc_setup);
if (!dev)
return NULL;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 29e272cc7a98..64c016a99af8 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -1496,7 +1496,6 @@ e100_set_config(struct net_device *dev, struct ifmap *map)
case IF_PORT_AUI:
spin_unlock(&np->lock);
return -EOPNOTSUPP;
- break;
default:
printk(KERN_ERR "%s: Invalid media selected", dev->name);
spin_unlock(&np->lock);
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 0932ffbf381b..ff435fbd1ad0 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -164,7 +164,7 @@ static int __init dummy_init_one(void)
struct net_device *dev_dummy;
int err;
- dev_dummy = alloc_netdev(0, "dummy%d", dummy_setup);
+ dev_dummy = alloc_netdev(0, "dummy%d", NET_NAME_UNKNOWN, dummy_setup);
if (!dev_dummy)
return -ENOMEM;
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 7a79b6046879..957e5c0cede3 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -585,7 +585,8 @@ static int __init eql_init_module(void)
pr_info("%s\n", version);
- dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup);
+ dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", NET_NAME_UNKNOWN,
+ eql_setup);
if (!dev_eql)
return -ENOMEM;
diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c
index 599311f0e05c..b96e8852b2d1 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -986,7 +986,7 @@ static void ethdev_setup(struct net_device *dev)
static struct net_device *____alloc_ei_netdev(int size)
{
return alloc_netdev(sizeof(struct ei_device) + size, "eth%d",
- ethdev_setup);
+ NET_NAME_UNKNOWN, ethdev_setup);
}
diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c
index 90e825e8abfe..65cf60f6718c 100644
--- a/drivers/net/ethernet/8390/mac8390.c
+++ b/drivers/net/ethernet/8390/mac8390.c
@@ -178,10 +178,8 @@ static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
case NUBUS_DRHW_APPLE_SONIC_LC:
case NUBUS_DRHW_SONNET:
return MAC8390_NONE;
- break;
default:
return MAC8390_APPLE;
- break;
}
break;
@@ -189,13 +187,10 @@ static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
switch (dev->dr_hw) {
case NUBUS_DRHW_ASANTE_LC:
return MAC8390_NONE;
- break;
case NUBUS_DRHW_CABLETRON:
return MAC8390_CABLETRON;
- break;
default:
return MAC8390_APPLE;
- break;
}
break;
@@ -220,10 +215,8 @@ static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
switch (dev->dr_hw) {
case NUBUS_DRHW_INTERLAN:
return MAC8390_INTERLAN;
- break;
default:
return MAC8390_KINETICS;
- break;
}
break;
@@ -563,7 +556,6 @@ static int __init mac8390_initdev(struct net_device *dev,
case ACCESS_UNKNOWN:
pr_err("Don't know how to access card memory!\n");
return -ENODEV;
- break;
case ACCESS_16:
/* 16 bit card, register map is reversed */
diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig
index f952fff6a9a9..c9cd3592ab73 100644
--- a/drivers/net/ethernet/adi/Kconfig
+++ b/drivers/net/ethernet/adi/Kconfig
@@ -52,8 +52,7 @@ config BFIN_TX_DESC_NUM
config BFIN_RX_DESC_NUM
int "Number of receive buffer packets"
depends on BFIN_MAC
- range 20 100 if BFIN_MAC_USE_L1
- range 20 800
+ range 20 64
default "20"
---help---
Set the number of buffer packets used in driver.
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index 7ae74d450e8f..afa66847e10b 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -1218,11 +1218,11 @@ out:
#define RX_ERROR_MASK (RX_LONG | RX_ALIGN | RX_CRC | RX_LEN | \
RX_FRAG | RX_ADDR | RX_DMAO | RX_PHY | RX_LATE | RX_RANGE)
-static void bfin_mac_rx(struct net_device *dev)
+static void bfin_mac_rx(struct bfin_mac_local *lp)
{
+ struct net_device *dev = lp->ndev;
struct sk_buff *skb, *new_skb;
unsigned short len;
- struct bfin_mac_local *lp __maybe_unused = netdev_priv(dev);
#if defined(BFIN_MAC_CSUM_OFFLOAD)
unsigned int i;
unsigned char fcs[ETH_FCS_LEN + 1];
@@ -1256,7 +1256,7 @@ static void bfin_mac_rx(struct net_device *dev)
current_rx_ptr->skb = new_skb;
current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
- len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
+ len = (unsigned short)(current_rx_ptr->status.status_word & RX_FRLEN);
/* Deduce Ethernet FCS length from Ethernet payload length */
len -= ETH_FCS_LEN;
skb_put(skb, len);
@@ -1294,7 +1294,8 @@ static void bfin_mac_rx(struct net_device *dev)
}
#endif
- netif_rx(skb);
+ napi_gro_receive(&lp->napi, skb);
+
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
out:
@@ -1302,41 +1303,52 @@ out:
current_rx_ptr = current_rx_ptr->next;
}
+static int bfin_mac_poll(struct napi_struct *napi, int budget)
+{
+ int i = 0;
+ struct bfin_mac_local *lp = container_of(napi,
+ struct bfin_mac_local,
+ napi);
+
+ while (current_rx_ptr->status.status_word != 0 && i < budget) {
+ bfin_mac_rx(lp);
+ i++;
+ }
+
+ if (i < budget) {
+ napi_complete(napi);
+ if (test_and_clear_bit(BFIN_MAC_RX_IRQ_DISABLED, &lp->flags))
+ enable_irq(IRQ_MAC_RX);
+ }
+
+ return i;
+}
+
/* interrupt routine to handle rx and error signal */
static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- int number = 0;
-
-get_one_packet:
- if (current_rx_ptr->status.status_word == 0) {
- /* no more new packet received */
- if (number == 0) {
- if (current_rx_ptr->next->status.status_word != 0) {
- current_rx_ptr = current_rx_ptr->next;
- goto real_rx;
- }
- }
- bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
- DMA_DONE | DMA_ERR);
- return IRQ_HANDLED;
+ struct bfin_mac_local *lp = netdev_priv(dev_id);
+ u32 status;
+
+ status = bfin_read_DMA1_IRQ_STATUS();
+
+ bfin_write_DMA1_IRQ_STATUS(status | DMA_DONE | DMA_ERR);
+ if (status & DMA_DONE) {
+ disable_irq_nosync(IRQ_MAC_RX);
+ set_bit(BFIN_MAC_RX_IRQ_DISABLED, &lp->flags);
+ napi_schedule(&lp->napi);
}
-real_rx:
- bfin_mac_rx(dev);
- number++;
- goto get_one_packet;
+ return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-static void bfin_mac_poll(struct net_device *dev)
+static void bfin_mac_poll_controller(struct net_device *dev)
{
struct bfin_mac_local *lp = netdev_priv(dev);
- disable_irq(IRQ_MAC_RX);
bfin_mac_interrupt(IRQ_MAC_RX, dev);
tx_reclaim_skb(lp);
- enable_irq(IRQ_MAC_RX);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -1428,14 +1440,13 @@ static void bfin_mac_timeout(struct net_device *dev)
tx_list_head = tx_list_head->next;
}
- if (netif_queue_stopped(lp->ndev))
- netif_wake_queue(lp->ndev);
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
bfin_mac_enable(lp->phydev);
/* We can accept TX packets again */
dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
}
static void bfin_mac_multicast_hash(struct net_device *dev)
@@ -1562,6 +1573,7 @@ static int bfin_mac_open(struct net_device *dev)
return ret;
pr_debug("hardware init finished\n");
+ napi_enable(&lp->napi);
netif_start_queue(dev);
netif_carrier_on(dev);
@@ -1579,6 +1591,7 @@ static int bfin_mac_close(struct net_device *dev)
pr_debug("%s: %s\n", dev->name, __func__);
netif_stop_queue(dev);
+ napi_disable(&lp->napi);
netif_carrier_off(dev);
phy_stop(lp->phydev);
@@ -1604,7 +1617,7 @@ static const struct net_device_ops bfin_mac_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = bfin_mac_poll,
+ .ndo_poll_controller = bfin_mac_poll_controller,
#endif
};
@@ -1689,6 +1702,9 @@ static int bfin_mac_probe(struct platform_device *pdev)
lp->tx_reclaim_timer.data = (unsigned long)lp;
lp->tx_reclaim_timer.function = tx_reclaim_skb_timeout;
+ lp->flags = 0;
+ netif_napi_add(ndev, &lp->napi, bfin_mac_poll, CONFIG_BFIN_RX_DESC_NUM);
+
spin_lock_init(&lp->lock);
/* now, enable interrupts */
@@ -1723,6 +1739,7 @@ out_err_phc:
out_err_reg_ndev:
free_irq(IRQ_MAC_RX, ndev);
out_err_request_irq:
+ netif_napi_del(&lp->napi);
out_err_mii_probe:
mdiobus_unregister(lp->mii_bus);
mdiobus_free(lp->mii_bus);
@@ -1743,6 +1760,8 @@ static int bfin_mac_remove(struct platform_device *pdev)
unregister_netdev(ndev);
+ netif_napi_del(&lp->napi);
+
free_irq(IRQ_MAC_RX, ndev);
free_netdev(ndev);
diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
index 6dec86ac97cd..d1217db70db4 100644
--- a/drivers/net/ethernet/adi/bfin_mac.h
+++ b/drivers/net/ethernet/adi/bfin_mac.h
@@ -26,6 +26,7 @@
#endif
#define TX_RECLAIM_JIFFIES (HZ / 5)
+#define BFIN_MAC_RX_IRQ_DISABLED 1
struct dma_descriptor {
struct dma_descriptor *next_dma_desc;
@@ -80,6 +81,8 @@ struct bfin_mac_local {
int irq_wake_requested;
struct timer_list tx_reclaim_timer;
struct net_device *ndev;
+ struct napi_struct napi;
+ unsigned long flags;
/* Data for EMAC_VLAN1 regs */
u16 vlan1_mask, vlan2_mask;
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index d81e7167a8b5..29b9f082475d 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -633,8 +633,10 @@ static void emac_rx(struct net_device *dev)
}
/* Move data from EMAC */
- skb = dev_alloc_skb(rxlen + 4);
- if (good_packet && skb) {
+ if (good_packet) {
+ skb = netdev_alloc_skb(dev, rxlen + 4);
+ if (!skb)
+ continue;
skb_reserve(skb, 2);
rdptr = (u8 *) skb_put(skb, rxlen - 4);
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
index bbaf36d9f5e1..8319c99331b0 100644
--- a/drivers/net/ethernet/amd/Kconfig
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -182,6 +182,9 @@ config AMD_XGBE
depends on OF_NET
select PHYLIB
select AMD_XGBE_PHY
+ select BITREVERSE
+ select CRC32
+ select PTP_1588_CLOCK
---help---
This driver supports the AMD 10GbE Ethernet device found on an
AMD SoC.
@@ -189,4 +192,14 @@ config AMD_XGBE
To compile this driver as a module, choose M here: the module
will be called amd-xgbe.
+config AMD_XGBE_DCB
+ bool "Data Center Bridging (DCB) support"
+ default n
+ depends on AMD_XGBE && DCB
+ ---help---
+ Say Y here to enable Data Center Bridging (DCB) support in the
+ driver.
+
+ If unsure, say N.
+
endif # NET_VENDOR_AMD
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 068dc7cad5fa..841e6558db68 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -101,7 +101,6 @@ Revision History:
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "MODULE_VERS);
MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
module_param_array(speed_duplex, int, NULL, 0);
MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
module_param_array(coalesce, bool, NULL, 0);
@@ -109,17 +108,9 @@ MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0
module_param_array(dynamic_ipg, bool, NULL, 0);
MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
-static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
-
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
- { 0, }
-
-};
-/*
-This function will read the PHY registers.
-*/
-static int amd8111e_read_phy(struct amd8111e_priv* lp, int phy_id, int reg, u32* val)
+/* This function will read the PHY registers. */
+static int amd8111e_read_phy(struct amd8111e_priv *lp,
+ int phy_id, int reg, u32 *val)
{
void __iomem *mmio = lp->mmio;
unsigned int reg_val;
@@ -146,10 +137,9 @@ err_phy_read:
}
-/*
-This function will write into PHY registers.
-*/
-static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val)
+/* This function will write into PHY registers. */
+static int amd8111e_write_phy(struct amd8111e_priv *lp,
+ int phy_id, int reg, u32 val)
{
unsigned int repeat = REPEAT_CNT;
void __iomem *mmio = lp->mmio;
@@ -176,12 +166,11 @@ err_phy_write:
return -EINVAL;
}
-/*
-This is the mii register read function provided to the mii interface.
-*/
-static int amd8111e_mdio_read(struct net_device * dev, int phy_id, int reg_num)
+
+/* This is the mii register read function provided to the mii interface. */
+static int amd8111e_mdio_read(struct net_device *dev, int phy_id, int reg_num)
{
- struct amd8111e_priv* lp = netdev_priv(dev);
+ struct amd8111e_priv *lp = netdev_priv(dev);
unsigned int reg_val;
amd8111e_read_phy(lp,phy_id,reg_num,&reg_val);
@@ -189,19 +178,18 @@ static int amd8111e_mdio_read(struct net_device * dev, int phy_id, int reg_num)
}
-/*
-This is the mii register write function provided to the mii interface.
-*/
-static void amd8111e_mdio_write(struct net_device * dev, int phy_id, int reg_num, int val)
+/* This is the mii register write function provided to the mii interface. */
+static void amd8111e_mdio_write(struct net_device *dev,
+ int phy_id, int reg_num, int val)
{
- struct amd8111e_priv* lp = netdev_priv(dev);
+ struct amd8111e_priv *lp = netdev_priv(dev);
amd8111e_write_phy(lp, phy_id, reg_num, val);
}
-/*
-This function will set PHY speed. During initialization sets the original speed to 100 full.
-*/
+/* This function will set PHY speed. During initialization sets
+ * the original speed to 100 full
+ */
static void amd8111e_set_ext_phy(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
@@ -240,14 +228,13 @@ static void amd8111e_set_ext_phy(struct net_device *dev)
}
-/*
-This function will unmap skb->data space and will free
-all transmit and receive skbuffs.
-*/
+/* This function will unmap skb->data space and will free
+ * all transmit and receive skbuffs.
+ */
static int amd8111e_free_skbs(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
- struct sk_buff* rx_skbuff;
+ struct sk_buff *rx_skbuff;
int i;
/* Freeing transmit skbs */
@@ -274,18 +261,18 @@ static int amd8111e_free_skbs(struct net_device *dev)
return 0;
}
-/*
-This will set the receive buffer length corresponding to the mtu size of networkinterface.
-*/
-static inline void amd8111e_set_rx_buff_len(struct net_device* dev)
+/* This will set the receive buffer length corresponding
+ * to the mtu size of networkinterface.
+ */
+static inline void amd8111e_set_rx_buff_len(struct net_device *dev)
{
- struct amd8111e_priv* lp = netdev_priv(dev);
+ struct amd8111e_priv *lp = netdev_priv(dev);
unsigned int mtu = dev->mtu;
if (mtu > ETH_DATA_LEN){
/* MTU + ethernet header + FCS
- + optional VLAN tag + skb reserve space 2 */
-
+ * + optional VLAN tag + skb reserve space 2
+ */
lp->rx_buff_len = mtu + ETH_HLEN + 10;
lp->options |= OPTION_JUMBO_ENABLE;
} else{
@@ -294,8 +281,10 @@ static inline void amd8111e_set_rx_buff_len(struct net_device* dev)
}
}
-/*
-This function will free all the previously allocated buffers, determine new receive buffer length and will allocate new receive buffers. This function also allocates and initializes both the transmitter and receive hardware descriptors.
+/* This function will free all the previously allocated buffers,
+ * determine new receive buffer length and will allocate new receive buffers.
+ * This function also allocates and initializes both the transmitter
+ * and receive hardware descriptors.
*/
static int amd8111e_init_ring(struct net_device *dev)
{
@@ -376,15 +365,18 @@ err_free_tx_ring:
err_no_mem:
return -ENOMEM;
}
-/* This function will set the interrupt coalescing according to the input arguments */
-static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
+
+/* This function will set the interrupt coalescing according
+ * to the input arguments
+ */
+static int amd8111e_set_coalesce(struct net_device *dev, enum coal_mode cmod)
{
unsigned int timeout;
unsigned int event_count;
struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio;
- struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf;
+ struct amd8111e_coalesce_conf *coal_conf = &lp->coal_conf;
switch(cmod)
@@ -435,9 +427,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
}
-/*
-This function initializes the device registers and starts the device.
-*/
+/* This function initializes the device registers and starts the device. */
static int amd8111e_restart(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
@@ -501,8 +491,7 @@ static int amd8111e_restart(struct net_device *dev)
/* Enable interrupt coalesce */
if(lp->options & OPTION_INTR_COAL_ENABLE){
- printk(KERN_INFO "%s: Interrupt Coalescing Enabled.\n",
- dev->name);
+ netdev_info(dev, "Interrupt Coalescing Enabled.\n");
amd8111e_set_coalesce(dev,ENABLE_COAL);
}
@@ -514,10 +503,9 @@ static int amd8111e_restart(struct net_device *dev)
readl(mmio+CMD0);
return 0;
}
-/*
-This function clears necessary the device registers.
-*/
-static void amd8111e_init_hw_default( struct amd8111e_priv* lp)
+
+/* This function clears necessary the device registers. */
+static void amd8111e_init_hw_default(struct amd8111e_priv *lp)
{
unsigned int reg_val;
unsigned int logic_filter[2] ={0,};
@@ -587,7 +575,7 @@ static void amd8111e_init_hw_default( struct amd8111e_priv* lp)
writew(MIB_CLEAR, mmio + MIB_ADDR);
/* Clear LARF */
- amd8111e_writeq(*(u64*)logic_filter,mmio+LADRF);
+ amd8111e_writeq(*(u64 *)logic_filter, mmio + LADRF);
/* SRAM_SIZE register */
reg_val = readl(mmio + SRAM_SIZE);
@@ -605,11 +593,10 @@ static void amd8111e_init_hw_default( struct amd8111e_priv* lp)
}
-/*
-This function disables the interrupt and clears all the pending
-interrupts in INT0
+/* This function disables the interrupt and clears all the pending
+ * interrupts in INT0
*/
-static void amd8111e_disable_interrupt(struct amd8111e_priv* lp)
+static void amd8111e_disable_interrupt(struct amd8111e_priv *lp)
{
u32 intr0;
@@ -625,10 +612,8 @@ static void amd8111e_disable_interrupt(struct amd8111e_priv* lp)
}
-/*
-This function stops the chip.
-*/
-static void amd8111e_stop_chip(struct amd8111e_priv* lp)
+/* This function stops the chip. */
+static void amd8111e_stop_chip(struct amd8111e_priv *lp)
{
writel(RUN, lp->mmio + CMD0);
@@ -636,10 +621,8 @@ static void amd8111e_stop_chip(struct amd8111e_priv* lp)
readl(lp->mmio + CMD0);
}
-/*
-This function frees the transmiter and receiver descriptor rings.
-*/
-static void amd8111e_free_ring(struct amd8111e_priv* lp)
+/* This function frees the transmiter and receiver descriptor rings. */
+static void amd8111e_free_ring(struct amd8111e_priv *lp)
{
/* Free transmit and receive descriptor rings */
if(lp->rx_ring){
@@ -659,12 +642,13 @@ static void amd8111e_free_ring(struct amd8111e_priv* lp)
}
-/*
-This function will free all the transmit skbs that are actually transmitted by the device. It will check the ownership of the skb before freeing the skb.
-*/
+/* This function will free all the transmit skbs that are actually
+ * transmitted by the device. It will check the ownership of the
+ * skb before freeing the skb.
+ */
static int amd8111e_tx(struct net_device *dev)
{
- struct amd8111e_priv* lp = netdev_priv(dev);
+ struct amd8111e_priv *lp = netdev_priv(dev);
int tx_index = lp->tx_complete_idx & TX_RING_DR_MOD_MASK;
int status;
/* Complete all the transmit packet */
@@ -724,21 +708,20 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
goto rx_not_empty;
do{
- /* process receive packets until we use the quota*/
- /* If we own the next entry, it's a new packet. Send it up. */
+ /* process receive packets until we use the quota.
+ * If we own the next entry, it's a new packet. Send it up.
+ */
while(1) {
status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
if (status & OWN_BIT)
break;
- /*
- * There is a tricky error noted by John Murphy,
+ /* There is a tricky error noted by John Murphy,
* <murf@perftech.com> to Russ Nelson: Even with
* full-sized * buffers it's possible for a
* jabber packet to use two buffers, with only
* the last correctly noting the error.
*/
-
if(status & ERR_BIT) {
/* reseting flags */
lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
@@ -771,7 +754,8 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
new_skb = netdev_alloc_skb(dev, lp->rx_buff_len);
if (!new_skb) {
/* if allocation fail,
- ignore that pkt and go to next one */
+ * ignore that pkt and go to next one
+ */
lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
lp->drv_rx_errors++;
goto err_next_pkt;
@@ -812,8 +796,8 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
}
/* Check the interrupt status register for more packets in the
- mean time. Process them since we have not used up our quota.*/
-
+ * mean time. Process them since we have not used up our quota.
+ */
intr0 = readl(mmio + INT0);
/*Ack receive packets */
writel(intr0 & RINT0,mmio + INT0);
@@ -833,10 +817,8 @@ rx_not_empty:
return num_rx_pkt;
}
-/*
-This function will indicate the link status to the kernel.
-*/
-static int amd8111e_link_change(struct net_device* dev)
+/* This function will indicate the link status to the kernel. */
+static int amd8111e_link_change(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
int status0,speed;
@@ -860,24 +842,26 @@ static int amd8111e_link_change(struct net_device* dev)
else if(speed == PHY_SPEED_100)
lp->link_config.speed = SPEED_100;
- printk(KERN_INFO "%s: Link is Up. Speed is %s Mbps %s Duplex\n", dev->name,
- (lp->link_config.speed == SPEED_100) ? "100": "10",
- (lp->link_config.duplex == DUPLEX_FULL)? "Full": "Half");
+ netdev_info(dev, "Link is Up. Speed is %s Mbps %s Duplex\n",
+ (lp->link_config.speed == SPEED_100) ?
+ "100" : "10",
+ (lp->link_config.duplex == DUPLEX_FULL) ?
+ "Full" : "Half");
+
netif_carrier_on(dev);
}
else{
lp->link_config.speed = SPEED_INVALID;
lp->link_config.duplex = DUPLEX_INVALID;
lp->link_config.autoneg = AUTONEG_INVALID;
- printk(KERN_INFO "%s: Link is Down.\n",dev->name);
+ netdev_info(dev, "Link is Down.\n");
netif_carrier_off(dev);
}
return 0;
}
-/*
-This function reads the mib counters.
-*/
+
+/* This function reads the mib counters. */
static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER)
{
unsigned int status;
@@ -895,8 +879,7 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER)
return data;
}
-/*
- * This function reads the mib registers and returns the hardware statistics.
+/* This function reads the mib registers and returns the hardware statistics.
* It updates previous internal driver statistics with new values.
*/
static struct net_device_stats *amd8111e_get_stats(struct net_device *dev)
@@ -992,13 +975,14 @@ static struct net_device_stats *amd8111e_get_stats(struct net_device *dev)
return new_stats;
}
+
/* This function recalculate the interrupt coalescing mode on every interrupt
-according to the datarate and the packet rate.
-*/
+ * according to the datarate and the packet rate.
+ */
static int amd8111e_calc_coalesce(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
- struct amd8111e_coalesce_conf * coal_conf = &lp->coal_conf;
+ struct amd8111e_coalesce_conf *coal_conf = &lp->coal_conf;
int tx_pkt_rate;
int rx_pkt_rate;
int tx_data_rate;
@@ -1126,13 +1110,14 @@ static int amd8111e_calc_coalesce(struct net_device *dev)
return 0;
}
-/*
-This is device interrupt function. It handles transmit, receive,link change and hardware timer interrupts.
-*/
+
+/* This is device interrupt function. It handles transmit,
+ * receive,link change and hardware timer interrupts.
+ */
static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
{
- struct net_device * dev = (struct net_device *) dev_id;
+ struct net_device *dev = (struct net_device *)dev_id;
struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio;
unsigned int intr0, intren0;
@@ -1168,7 +1153,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
/* Schedule a polling routine */
__napi_schedule(&lp->napi);
} else if (intren0 & RINTEN0) {
- printk("************Driver bug! interrupt while in poll\n");
+ netdev_dbg(dev, "************Driver bug! interrupt while in poll\n");
/* Fix by disable receive interrupts */
writel(RINTEN0, mmio + INTEN0);
}
@@ -1205,10 +1190,11 @@ static void amd8111e_poll(struct net_device *dev)
#endif
-/*
-This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down.
-*/
-static int amd8111e_close(struct net_device * dev)
+/* This function closes the network interface and updates
+ * the statistics so that most recent statistics will be
+ * available after the interface is down.
+ */
+static int amd8111e_close(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
netif_stop_queue(dev);
@@ -1238,9 +1224,11 @@ static int amd8111e_close(struct net_device * dev)
lp->opened = 0;
return 0;
}
-/* This function opens new interface.It requests irq for the device, initializes the device,buffers and descriptors, and starts the device.
-*/
-static int amd8111e_open(struct net_device * dev )
+
+/* This function opens new interface.It requests irq for the device,
+ * initializes the device,buffers and descriptors, and starts the device.
+ */
+static int amd8111e_open(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
@@ -1264,7 +1252,7 @@ static int amd8111e_open(struct net_device * dev )
/* Start ipg timer */
if(lp->options & OPTION_DYN_IPG_ENABLE){
add_timer(&lp->ipg_data.ipg_timer);
- printk(KERN_INFO "%s: Dynamic IPG Enabled.\n",dev->name);
+ netdev_info(dev, "Dynamic IPG Enabled\n");
}
lp->opened = 1;
@@ -1275,10 +1263,11 @@ static int amd8111e_open(struct net_device * dev )
return 0;
}
-/*
-This function checks if there is any transmit descriptors available to queue more packet.
-*/
-static int amd8111e_tx_queue_avail(struct amd8111e_priv* lp )
+
+/* This function checks if there is any transmit descriptors
+ * available to queue more packet.
+ */
+static int amd8111e_tx_queue_avail(struct amd8111e_priv *lp)
{
int tx_index = lp->tx_idx & TX_BUFF_MOD_MASK;
if (lp->tx_skbuff[tx_index])
@@ -1287,12 +1276,14 @@ static int amd8111e_tx_queue_avail(struct amd8111e_priv* lp )
return 0;
}
-/*
-This function will queue the transmit packets to the descriptors and will trigger the send operation. It also initializes the transmit descriptors with buffer physical address, byte count, ownership to hardware etc.
-*/
+/* This function will queue the transmit packets to the
+ * descriptors and will trigger the send operation. It also
+ * initializes the transmit descriptors with buffer physical address,
+ * byte count, ownership to hardware etc.
+ */
static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
- struct net_device * dev)
+ struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
int tx_index;
@@ -1338,9 +1329,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
spin_unlock_irqrestore(&lp->lock, flags);
return NETDEV_TX_OK;
}
-/*
-This function returns all the memory mapped registers of the device.
-*/
+/* This function returns all the memory mapped registers of the device. */
static void amd8111e_read_regs(struct amd8111e_priv *lp, u32 *buf)
{
void __iomem *mmio = lp->mmio;
@@ -1361,10 +1350,9 @@ static void amd8111e_read_regs(struct amd8111e_priv *lp, u32 *buf)
}
-/*
-This function sets promiscuos mode, all-multi mode or the multicast address
-list to the device.
-*/
+/* This function sets promiscuos mode, all-multi mode or the multicast address
+ * list to the device.
+ */
static void amd8111e_set_multicast_list(struct net_device *dev)
{
struct netdev_hw_addr *ha;
@@ -1383,14 +1371,14 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
/* get all multicast packet */
mc_filter[1] = mc_filter[0] = 0xffffffff;
lp->options |= OPTION_MULTICAST_ENABLE;
- amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
+ amd8111e_writeq(*(u64 *)mc_filter, lp->mmio + LADRF);
return;
}
if (netdev_mc_empty(dev)) {
/* get only own packets */
mc_filter[1] = mc_filter[0] = 0;
lp->options &= ~OPTION_MULTICAST_ENABLE;
- amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
+ amd8111e_writeq(*(u64 *)mc_filter, lp->mmio + LADRF);
/* disable promiscuous mode */
writel(PROM, lp->mmio + CMD2);
return;
@@ -1402,14 +1390,15 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
bit_num = (ether_crc_le(ETH_ALEN, ha->addr) >> 26) & 0x3f;
mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
}
- amd8111e_writeq(*(u64*)mc_filter,lp->mmio+ LADRF);
+ amd8111e_writeq(*(u64 *)mc_filter, lp->mmio + LADRF);
/* To eliminate PCI posting bug */
readl(lp->mmio + CMD2);
}
-static void amd8111e_get_drvinfo(struct net_device* dev, struct ethtool_drvinfo *info)
+static void amd8111e_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
{
struct amd8111e_priv *lp = netdev_priv(dev);
struct pci_dev *pci_dev = lp->pci_dev;
@@ -1501,11 +1490,11 @@ static const struct ethtool_ops ops = {
.set_wol = amd8111e_set_wol,
};
-/*
-This function handles all the ethtool ioctls. It gives driver info, gets/sets driver speed, gets memory mapped register values, forces auto negotiation, sets/gets WOL options for ethtool application.
-*/
-
-static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
+/* This function handles all the ethtool ioctls. It gives driver info,
+ * gets/sets driver speed, gets memory mapped register values, forces
+ * auto negotiation, sets/gets WOL options for ethtool application.
+ */
+static int amd8111e_ioctl(struct net_device *dev , struct ifreq *ifr, int cmd)
{
struct mii_ioctl_data *data = if_mii(ifr);
struct amd8111e_priv *lp = netdev_priv(dev);
@@ -1559,9 +1548,9 @@ static int amd8111e_set_mac_address(struct net_device *dev, void *p)
return 0;
}
-/*
-This function changes the mtu of the device. It restarts the device to initialize the descriptor with new receive buffers.
-*/
+/* This function changes the mtu of the device. It restarts the device to
+ * initialize the descriptor with new receive buffers.
+ */
static int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
{
struct amd8111e_priv *lp = netdev_priv(dev);
@@ -1572,7 +1561,8 @@ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
if (!netif_running(dev)) {
/* new_mtu will be used
- when device starts netxt time */
+ * when device starts netxt time
+ */
dev->mtu = new_mtu;
return 0;
}
@@ -1591,7 +1581,7 @@ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
-static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp)
+static int amd8111e_enable_magicpkt(struct amd8111e_priv *lp)
{
writel( VAL1|MPPLBA, lp->mmio + CMD3);
writel( VAL0|MPEN_SW, lp->mmio + CMD7);
@@ -1601,7 +1591,7 @@ static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp)
return 0;
}
-static int amd8111e_enable_link_change(struct amd8111e_priv* lp)
+static int amd8111e_enable_link_change(struct amd8111e_priv *lp)
{
/* Adapter is already stoped/suspended/interrupt-disabled */
@@ -1612,19 +1602,18 @@ static int amd8111e_enable_link_change(struct amd8111e_priv* lp)
return 0;
}
-/*
- * This function is called when a packet transmission fails to complete
+/* This function is called when a packet transmission fails to complete
* within a reasonable period, on the assumption that an interrupt have
* failed or the interface is locked up. This function will reinitialize
* the hardware.
*/
static void amd8111e_tx_timeout(struct net_device *dev)
{
- struct amd8111e_priv* lp = netdev_priv(dev);
+ struct amd8111e_priv *lp = netdev_priv(dev);
int err;
- printk(KERN_ERR "%s: transmit timed out, resetting\n",
- dev->name);
+ netdev_err(dev, "transmit timed out, resetting\n");
+
spin_lock_irq(&lp->lock);
err = amd8111e_restart(dev);
spin_unlock_irq(&lp->lock);
@@ -1701,22 +1690,10 @@ static int amd8111e_resume(struct pci_dev *pci_dev)
return 0;
}
-
-static void amd8111e_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- if (dev) {
- unregister_netdev(dev);
- iounmap(((struct amd8111e_priv *)netdev_priv(dev))->mmio);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- }
-}
-static void amd8111e_config_ipg(struct net_device* dev)
+static void amd8111e_config_ipg(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
- struct ipg_info* ipg_data = &lp->ipg_data;
+ struct ipg_info *ipg_data = &lp->ipg_data;
void __iomem *mmio = lp->mmio;
unsigned int prev_col_cnt = ipg_data->col_cnt;
unsigned int total_col_cnt;
@@ -1814,27 +1791,24 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
{
int err, i;
unsigned long reg_addr,reg_len;
- struct amd8111e_priv* lp;
- struct net_device* dev;
+ struct amd8111e_priv *lp;
+ struct net_device *dev;
err = pci_enable_device(pdev);
if(err){
- printk(KERN_ERR "amd8111e: Cannot enable new PCI device, "
- "exiting.\n");
+ dev_err(&pdev->dev, "Cannot enable new PCI device\n");
return err;
}
if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)){
- printk(KERN_ERR "amd8111e: Cannot find PCI base address, "
- "exiting.\n");
+ dev_err(&pdev->dev, "Cannot find PCI base address\n");
err = -ENODEV;
goto err_disable_pdev;
}
err = pci_request_regions(pdev, MODULE_NAME);
if(err){
- printk(KERN_ERR "amd8111e: Cannot obtain PCI resources, "
- "exiting.\n");
+ dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
goto err_disable_pdev;
}
@@ -1842,16 +1816,14 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
/* Find power-management capability. */
if (!pdev->pm_cap) {
- printk(KERN_ERR "amd8111e: No Power Management capability, "
- "exiting.\n");
+ dev_err(&pdev->dev, "No Power Management capability\n");
err = -ENODEV;
goto err_free_reg;
}
/* Initialize DMA */
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
- printk(KERN_ERR "amd8111e: DMA not supported,"
- "exiting.\n");
+ dev_err(&pdev->dev, "DMA not supported\n");
err = -ENODEV;
goto err_free_reg;
}
@@ -1878,10 +1850,9 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
spin_lock_init(&lp->lock);
- lp->mmio = ioremap(reg_addr, reg_len);
+ lp->mmio = devm_ioremap(&pdev->dev, reg_addr, reg_len);
if (!lp->mmio) {
- printk(KERN_ERR "amd8111e: Cannot map device registers, "
- "exiting\n");
+ dev_err(&pdev->dev, "Cannot map device registers\n");
err = -ENOMEM;
goto err_free_dev;
}
@@ -1923,9 +1894,8 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR "amd8111e: Cannot register net device, "
- "exiting.\n");
- goto err_iounmap;
+ dev_err(&pdev->dev, "Cannot register net device\n");
+ goto err_free_dev;
}
pci_set_drvdata(pdev, dev);
@@ -1942,21 +1912,17 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
}
/* display driver and device information */
-
chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28;
- printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n",
- dev->name,MODULE_VERS);
- printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %pM\n",
- dev->name, chip_version, dev->dev_addr);
+ dev_info(&pdev->dev, "AMD-8111e Driver Version: %s\n", MODULE_VERS);
+ dev_info(&pdev->dev, "[ Rev %x ] PCI 10/100BaseT Ethernet %pM\n",
+ chip_version, dev->dev_addr);
if (lp->ext_phy_id)
- printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n",
- dev->name, lp->ext_phy_id, lp->ext_phy_addr);
+ dev_info(&pdev->dev, "Found MII PHY ID 0x%08x at address 0x%02x\n",
+ lp->ext_phy_id, lp->ext_phy_addr);
else
- printk(KERN_INFO "%s: Couldn't detect MII PHY, assuming address 0x01\n",
- dev->name);
+ dev_info(&pdev->dev, "Couldn't detect MII PHY, assuming address 0x01\n");
+
return 0;
-err_iounmap:
- iounmap(lp->mmio);
err_free_dev:
free_netdev(dev);
@@ -1970,6 +1936,29 @@ err_disable_pdev:
}
+static void amd8111e_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ if (dev) {
+ unregister_netdev(dev);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ }
+}
+
+static const struct pci_device_id amd8111e_pci_tbl[] = {
+ {
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD8111E_7462,
+ },
+ {
+ .vendor = 0,
+ }
+};
+MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
+
static struct pci_driver amd8111e_driver = {
.name = MODULE_NAME,
.id_table = amd8111e_pci_tbl,
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index a78e4c136959..31c48a7ac2b6 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -89,6 +89,124 @@ MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+/* AU1000 MAC registers and bits */
+#define MAC_CONTROL 0x0
+# define MAC_RX_ENABLE (1 << 2)
+# define MAC_TX_ENABLE (1 << 3)
+# define MAC_DEF_CHECK (1 << 5)
+# define MAC_SET_BL(X) (((X) & 0x3) << 6)
+# define MAC_AUTO_PAD (1 << 8)
+# define MAC_DISABLE_RETRY (1 << 10)
+# define MAC_DISABLE_BCAST (1 << 11)
+# define MAC_LATE_COL (1 << 12)
+# define MAC_HASH_MODE (1 << 13)
+# define MAC_HASH_ONLY (1 << 15)
+# define MAC_PASS_ALL (1 << 16)
+# define MAC_INVERSE_FILTER (1 << 17)
+# define MAC_PROMISCUOUS (1 << 18)
+# define MAC_PASS_ALL_MULTI (1 << 19)
+# define MAC_FULL_DUPLEX (1 << 20)
+# define MAC_NORMAL_MODE 0
+# define MAC_INT_LOOPBACK (1 << 21)
+# define MAC_EXT_LOOPBACK (1 << 22)
+# define MAC_DISABLE_RX_OWN (1 << 23)
+# define MAC_BIG_ENDIAN (1 << 30)
+# define MAC_RX_ALL (1 << 31)
+#define MAC_ADDRESS_HIGH 0x4
+#define MAC_ADDRESS_LOW 0x8
+#define MAC_MCAST_HIGH 0xC
+#define MAC_MCAST_LOW 0x10
+#define MAC_MII_CNTRL 0x14
+# define MAC_MII_BUSY (1 << 0)
+# define MAC_MII_READ 0
+# define MAC_MII_WRITE (1 << 1)
+# define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6)
+# define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11)
+#define MAC_MII_DATA 0x18
+#define MAC_FLOW_CNTRL 0x1C
+# define MAC_FLOW_CNTRL_BUSY (1 << 0)
+# define MAC_FLOW_CNTRL_ENABLE (1 << 1)
+# define MAC_PASS_CONTROL (1 << 2)
+# define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16)
+#define MAC_VLAN1_TAG 0x20
+#define MAC_VLAN2_TAG 0x24
+
+/* Ethernet Controller Enable */
+# define MAC_EN_CLOCK_ENABLE (1 << 0)
+# define MAC_EN_RESET0 (1 << 1)
+# define MAC_EN_TOSS (0 << 2)
+# define MAC_EN_CACHEABLE (1 << 3)
+# define MAC_EN_RESET1 (1 << 4)
+# define MAC_EN_RESET2 (1 << 5)
+# define MAC_DMA_RESET (1 << 6)
+
+/* Ethernet Controller DMA Channels */
+/* offsets from MAC_TX_RING_ADDR address */
+#define MAC_TX_BUFF0_STATUS 0x0
+# define TX_FRAME_ABORTED (1 << 0)
+# define TX_JAB_TIMEOUT (1 << 1)
+# define TX_NO_CARRIER (1 << 2)
+# define TX_LOSS_CARRIER (1 << 3)
+# define TX_EXC_DEF (1 << 4)
+# define TX_LATE_COLL_ABORT (1 << 5)
+# define TX_EXC_COLL (1 << 6)
+# define TX_UNDERRUN (1 << 7)
+# define TX_DEFERRED (1 << 8)
+# define TX_LATE_COLL (1 << 9)
+# define TX_COLL_CNT_MASK (0xF << 10)
+# define TX_PKT_RETRY (1 << 31)
+#define MAC_TX_BUFF0_ADDR 0x4
+# define TX_DMA_ENABLE (1 << 0)
+# define TX_T_DONE (1 << 1)
+# define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+#define MAC_TX_BUFF0_LEN 0x8
+#define MAC_TX_BUFF1_STATUS 0x10
+#define MAC_TX_BUFF1_ADDR 0x14
+#define MAC_TX_BUFF1_LEN 0x18
+#define MAC_TX_BUFF2_STATUS 0x20
+#define MAC_TX_BUFF2_ADDR 0x24
+#define MAC_TX_BUFF2_LEN 0x28
+#define MAC_TX_BUFF3_STATUS 0x30
+#define MAC_TX_BUFF3_ADDR 0x34
+#define MAC_TX_BUFF3_LEN 0x38
+
+/* offsets from MAC_RX_RING_ADDR */
+#define MAC_RX_BUFF0_STATUS 0x0
+# define RX_FRAME_LEN_MASK 0x3fff
+# define RX_WDOG_TIMER (1 << 14)
+# define RX_RUNT (1 << 15)
+# define RX_OVERLEN (1 << 16)
+# define RX_COLL (1 << 17)
+# define RX_ETHER (1 << 18)
+# define RX_MII_ERROR (1 << 19)
+# define RX_DRIBBLING (1 << 20)
+# define RX_CRC_ERROR (1 << 21)
+# define RX_VLAN1 (1 << 22)
+# define RX_VLAN2 (1 << 23)
+# define RX_LEN_ERROR (1 << 24)
+# define RX_CNTRL_FRAME (1 << 25)
+# define RX_U_CNTRL_FRAME (1 << 26)
+# define RX_MCAST_FRAME (1 << 27)
+# define RX_BCAST_FRAME (1 << 28)
+# define RX_FILTER_FAIL (1 << 29)
+# define RX_PACKET_FILTER (1 << 30)
+# define RX_MISSED_FRAME (1 << 31)
+
+# define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \
+ RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
+ RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
+#define MAC_RX_BUFF0_ADDR 0x4
+# define RX_DMA_ENABLE (1 << 0)
+# define RX_T_DONE (1 << 1)
+# define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+# define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0)
+#define MAC_RX_BUFF1_STATUS 0x10
+#define MAC_RX_BUFF1_ADDR 0x14
+#define MAC_RX_BUFF2_STATUS 0x20
+#define MAC_RX_BUFF2_ADDR 0x24
+#define MAC_RX_BUFF3_STATUS 0x30
+#define MAC_RX_BUFF3_ADDR 0x34
+
/*
* Theory of operation
*
@@ -152,10 +270,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
if (force_reset || (!aup->mac_enabled)) {
writel(MAC_EN_CLOCK_ENABLE, aup->enable);
- au_sync_delay(2);
+ wmb(); /* drain writebuffer */
+ mdelay(2);
writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
| MAC_EN_CLOCK_ENABLE), aup->enable);
- au_sync_delay(2);
+ wmb(); /* drain writebuffer */
+ mdelay(2);
aup->mac_enabled = 1;
}
@@ -273,7 +393,8 @@ static void au1000_hard_stop(struct net_device *dev)
reg = readl(&aup->mac->control);
reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
writel(reg, &aup->mac->control);
- au_sync_delay(10);
+ wmb(); /* drain writebuffer */
+ mdelay(10);
}
static void au1000_enable_rx_tx(struct net_device *dev)
@@ -286,7 +407,8 @@ static void au1000_enable_rx_tx(struct net_device *dev)
reg = readl(&aup->mac->control);
reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
writel(reg, &aup->mac->control);
- au_sync_delay(10);
+ wmb(); /* drain writebuffer */
+ mdelay(10);
}
static void
@@ -336,7 +458,8 @@ au1000_adjust_link(struct net_device *dev)
reg |= MAC_DISABLE_RX_OWN;
}
writel(reg, &aup->mac->control);
- au_sync_delay(1);
+ wmb(); /* drain writebuffer */
+ mdelay(1);
au1000_enable_rx_tx(dev);
aup->old_duplex = phydev->duplex;
@@ -500,9 +623,11 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
au1000_hard_stop(dev);
writel(MAC_EN_CLOCK_ENABLE, aup->enable);
- au_sync_delay(2);
+ wmb(); /* drain writebuffer */
+ mdelay(2);
writel(0, aup->enable);
- au_sync_delay(2);
+ wmb(); /* drain writebuffer */
+ mdelay(2);
aup->tx_full = 0;
for (i = 0; i < NUM_RX_DMA; i++) {
@@ -652,7 +777,7 @@ static int au1000_init(struct net_device *dev)
for (i = 0; i < NUM_RX_DMA; i++)
aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
control = MAC_RX_ENABLE | MAC_TX_ENABLE;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
@@ -669,7 +794,7 @@ static int au1000_init(struct net_device *dev)
writel(control, &aup->mac->control);
writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
- au_sync();
+ wmb(); /* drain writebuffer */
spin_unlock_irqrestore(&aup->lock, flags);
return 0;
@@ -760,7 +885,7 @@ static int au1000_rx(struct net_device *dev)
}
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
- au_sync();
+ wmb(); /* drain writebuffer */
/* next descriptor */
prxd = aup->rx_dma_ring[aup->rx_head];
@@ -808,7 +933,7 @@ static void au1000_tx_ack(struct net_device *dev)
au1000_update_tx_stats(dev, ptxd->status);
ptxd->buff_stat &= ~TX_T_DONE;
ptxd->len = 0;
- au_sync();
+ wmb(); /* drain writebuffer */
aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -939,7 +1064,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
ps->tx_bytes += ptxd->len;
ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
return NETDEV_TX_OK;
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c
index 57397295887c..b584b78237df 100644
--- a/drivers/net/ethernet/amd/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -475,7 +475,7 @@ static void lance_init_ring(struct net_device *dev)
*lib_ptr(ib, rx_ptr, lp->type) = leptr;
if (ZERO)
printk("RX ptr: %8.8x(%8.8x)\n",
- leptr, lib_off(brx_ring, lp->type));
+ leptr, (uint)lib_off(brx_ring, lp->type));
/* Setup tx descriptor pointer */
leptr = offsetof(struct lance_init_block, btx_ring);
@@ -484,7 +484,7 @@ static void lance_init_ring(struct net_device *dev)
*lib_ptr(ib, tx_ptr, lp->type) = leptr;
if (ZERO)
printk("TX ptr: %8.8x(%8.8x)\n",
- leptr, lib_off(btx_ring, lp->type));
+ leptr, (uint)lib_off(btx_ring, lp->type));
if (ZERO)
printk("TX rings:\n");
@@ -499,8 +499,8 @@ static void lance_init_ring(struct net_device *dev)
/* The ones required by tmd2 */
*lib_ptr(ib, btx_ring[i].misc, lp->type) = 0;
if (i < 3 && ZERO)
- printk("%d: 0x%8.8x(0x%8.8x)\n",
- i, leptr, (uint)lp->tx_buf_ptr_cpu[i]);
+ printk("%d: %8.8x(%p)\n",
+ i, leptr, lp->tx_buf_ptr_cpu[i]);
}
/* Setup the Rx ring entries */
@@ -516,8 +516,8 @@ static void lance_init_ring(struct net_device *dev)
0xf000;
*lib_ptr(ib, brx_ring[i].mblength, lp->type) = 0;
if (i < 3 && ZERO)
- printk("%d: 0x%8.8x(0x%8.8x)\n",
- i, leptr, (uint)lp->rx_buf_ptr_cpu[i]);
+ printk("%d: %8.8x(%p)\n",
+ i, leptr, lp->rx_buf_ptr_cpu[i]);
}
iob();
}
diff --git a/drivers/net/ethernet/amd/xgbe/Makefile b/drivers/net/ethernet/amd/xgbe/Makefile
index 26cf9af1642f..171a7e68048d 100644
--- a/drivers/net/ethernet/amd/xgbe/Makefile
+++ b/drivers/net/ethernet/amd/xgbe/Makefile
@@ -1,6 +1,8 @@
obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o
amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
- xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o
+ xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o \
+ xgbe-ptp.o
+amd-xgbe-$(CONFIG_AMD_XGBE_DCB) += xgbe-dcb.o
amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index bf462ee86f5c..cc25a3a9e7cf 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -170,6 +170,8 @@
#define DMA_MR_SWR_WIDTH 1
#define DMA_SBMR_EAME_INDEX 11
#define DMA_SBMR_EAME_WIDTH 1
+#define DMA_SBMR_BLEN_256_INDEX 7
+#define DMA_SBMR_BLEN_256_WIDTH 1
#define DMA_SBMR_UNDEF_INDEX 0
#define DMA_SBMR_UNDEF_WIDTH 1
@@ -276,13 +278,6 @@
#define MAC_PFR 0x0008
#define MAC_WTR 0x000c
#define MAC_HTR0 0x0010
-#define MAC_HTR1 0x0014
-#define MAC_HTR2 0x0018
-#define MAC_HTR3 0x001c
-#define MAC_HTR4 0x0020
-#define MAC_HTR5 0x0024
-#define MAC_HTR6 0x0028
-#define MAC_HTR7 0x002c
#define MAC_VLANTR 0x0050
#define MAC_VLANHTR 0x0058
#define MAC_VLANIR 0x0060
@@ -312,9 +307,23 @@
#define MAC_MACA0LR 0x0304
#define MAC_MACA1HR 0x0308
#define MAC_MACA1LR 0x030c
+#define MAC_TSCR 0x0d00
+#define MAC_SSIR 0x0d04
+#define MAC_STSR 0x0d08
+#define MAC_STNR 0x0d0c
+#define MAC_STSUR 0x0d10
+#define MAC_STNUR 0x0d14
+#define MAC_TSAR 0x0d18
+#define MAC_TSSR 0x0d20
+#define MAC_TXSNR 0x0d30
+#define MAC_TXSSR 0x0d34
#define MAC_QTFCR_INC 4
#define MAC_MACA_INC 4
+#define MAC_HTR_INC 4
+
+#define MAC_RQC2_INC 4
+#define MAC_RQC2_Q_PER_REG 4
/* MAC register entry bit positions and sizes */
#define MAC_HWF0R_ADDMACADRSEL_INDEX 18
@@ -355,6 +364,8 @@
#define MAC_HWF1R_HASHTBLSZ_WIDTH 3
#define MAC_HWF1R_L3L4FNUM_INDEX 27
#define MAC_HWF1R_L3L4FNUM_WIDTH 4
+#define MAC_HWF1R_NUMTC_INDEX 21
+#define MAC_HWF1R_NUMTC_WIDTH 3
#define MAC_HWF1R_RSSEN_INDEX 20
#define MAC_HWF1R_RSSEN_WIDTH 1
#define MAC_HWF1R_RXFIFOSIZE_INDEX 0
@@ -377,22 +388,30 @@
#define MAC_HWF2R_TXCHCNT_WIDTH 4
#define MAC_HWF2R_TXQCNT_INDEX 6
#define MAC_HWF2R_TXQCNT_WIDTH 4
+#define MAC_IER_TSIE_INDEX 12
+#define MAC_IER_TSIE_WIDTH 1
#define MAC_ISR_MMCRXIS_INDEX 9
#define MAC_ISR_MMCRXIS_WIDTH 1
#define MAC_ISR_MMCTXIS_INDEX 10
#define MAC_ISR_MMCTXIS_WIDTH 1
#define MAC_ISR_PMTIS_INDEX 4
#define MAC_ISR_PMTIS_WIDTH 1
+#define MAC_ISR_TSIS_INDEX 12
+#define MAC_ISR_TSIS_WIDTH 1
#define MAC_MACA1HR_AE_INDEX 31
#define MAC_MACA1HR_AE_WIDTH 1
#define MAC_PFR_HMC_INDEX 2
#define MAC_PFR_HMC_WIDTH 1
+#define MAC_PFR_HPF_INDEX 10
+#define MAC_PFR_HPF_WIDTH 1
#define MAC_PFR_HUC_INDEX 1
#define MAC_PFR_HUC_WIDTH 1
#define MAC_PFR_PM_INDEX 4
#define MAC_PFR_PM_WIDTH 1
#define MAC_PFR_PR_INDEX 0
#define MAC_PFR_PR_WIDTH 1
+#define MAC_PFR_VTFE_INDEX 16
+#define MAC_PFR_VTFE_WIDTH 1
#define MAC_PMTCSR_MGKPKTEN_INDEX 1
#define MAC_PMTCSR_MGKPKTEN_WIDTH 1
#define MAC_PMTCSR_PWRDWN_INDEX 0
@@ -419,24 +438,80 @@
#define MAC_RCR_LM_WIDTH 1
#define MAC_RCR_RE_INDEX 0
#define MAC_RCR_RE_WIDTH 1
+#define MAC_RFCR_PFCE_INDEX 8
+#define MAC_RFCR_PFCE_WIDTH 1
#define MAC_RFCR_RFE_INDEX 0
#define MAC_RFCR_RFE_WIDTH 1
+#define MAC_RFCR_UP_INDEX 1
+#define MAC_RFCR_UP_WIDTH 1
#define MAC_RQC0R_RXQ0EN_INDEX 0
#define MAC_RQC0R_RXQ0EN_WIDTH 2
+#define MAC_SSIR_SNSINC_INDEX 8
+#define MAC_SSIR_SNSINC_WIDTH 8
+#define MAC_SSIR_SSINC_INDEX 16
+#define MAC_SSIR_SSINC_WIDTH 8
#define MAC_TCR_SS_INDEX 29
#define MAC_TCR_SS_WIDTH 2
#define MAC_TCR_TE_INDEX 0
#define MAC_TCR_TE_WIDTH 1
+#define MAC_TSCR_AV8021ASMEN_INDEX 28
+#define MAC_TSCR_AV8021ASMEN_WIDTH 1
+#define MAC_TSCR_SNAPTYPSEL_INDEX 16
+#define MAC_TSCR_SNAPTYPSEL_WIDTH 2
+#define MAC_TSCR_TSADDREG_INDEX 5
+#define MAC_TSCR_TSADDREG_WIDTH 1
+#define MAC_TSCR_TSCFUPDT_INDEX 1
+#define MAC_TSCR_TSCFUPDT_WIDTH 1
+#define MAC_TSCR_TSCTRLSSR_INDEX 9
+#define MAC_TSCR_TSCTRLSSR_WIDTH 1
+#define MAC_TSCR_TSENA_INDEX 0
+#define MAC_TSCR_TSENA_WIDTH 1
+#define MAC_TSCR_TSENALL_INDEX 8
+#define MAC_TSCR_TSENALL_WIDTH 1
+#define MAC_TSCR_TSEVNTENA_INDEX 14
+#define MAC_TSCR_TSEVNTENA_WIDTH 1
+#define MAC_TSCR_TSINIT_INDEX 2
+#define MAC_TSCR_TSINIT_WIDTH 1
+#define MAC_TSCR_TSIPENA_INDEX 11
+#define MAC_TSCR_TSIPENA_WIDTH 1
+#define MAC_TSCR_TSIPV4ENA_INDEX 13
+#define MAC_TSCR_TSIPV4ENA_WIDTH 1
+#define MAC_TSCR_TSIPV6ENA_INDEX 12
+#define MAC_TSCR_TSIPV6ENA_WIDTH 1
+#define MAC_TSCR_TSMSTRENA_INDEX 15
+#define MAC_TSCR_TSMSTRENA_WIDTH 1
+#define MAC_TSCR_TSVER2ENA_INDEX 10
+#define MAC_TSCR_TSVER2ENA_WIDTH 1
+#define MAC_TSCR_TXTSSTSM_INDEX 24
+#define MAC_TSCR_TXTSSTSM_WIDTH 1
+#define MAC_TSSR_TXTSC_INDEX 15
+#define MAC_TSSR_TXTSC_WIDTH 1
+#define MAC_TXSNR_TXTSSTSMIS_INDEX 31
+#define MAC_TXSNR_TXTSSTSMIS_WIDTH 1
+#define MAC_VLANHTR_VLHT_INDEX 0
+#define MAC_VLANHTR_VLHT_WIDTH 16
+#define MAC_VLANIR_VLTI_INDEX 20
+#define MAC_VLANIR_VLTI_WIDTH 1
+#define MAC_VLANIR_CSVL_INDEX 19
+#define MAC_VLANIR_CSVL_WIDTH 1
#define MAC_VLANTR_DOVLTC_INDEX 20
#define MAC_VLANTR_DOVLTC_WIDTH 1
#define MAC_VLANTR_ERSVLM_INDEX 19
#define MAC_VLANTR_ERSVLM_WIDTH 1
#define MAC_VLANTR_ESVL_INDEX 18
#define MAC_VLANTR_ESVL_WIDTH 1
+#define MAC_VLANTR_ETV_INDEX 16
+#define MAC_VLANTR_ETV_WIDTH 1
#define MAC_VLANTR_EVLS_INDEX 21
#define MAC_VLANTR_EVLS_WIDTH 2
#define MAC_VLANTR_EVLRXS_INDEX 24
#define MAC_VLANTR_EVLRXS_WIDTH 1
+#define MAC_VLANTR_VL_INDEX 0
+#define MAC_VLANTR_VL_WIDTH 16
+#define MAC_VLANTR_VTHM_INDEX 25
+#define MAC_VLANTR_VTHM_WIDTH 1
+#define MAC_VLANTR_VTIM_INDEX 17
+#define MAC_VLANTR_VTIM_WIDTH 1
#define MAC_VR_DEVID_INDEX 8
#define MAC_VR_DEVID_WIDTH 8
#define MAC_VR_SNPSVER_INDEX 0
@@ -638,6 +713,8 @@
#define MTL_RQDCM_INC 4
#define MTL_RQDCM_Q_PER_REG 4
+#define MTL_TCPM_INC 4
+#define MTL_TCPM_TC_PER_REG 4
/* MTL register entry bit positions and sizes */
#define MTL_OMR_ETSALG_INDEX 5
@@ -656,9 +733,6 @@
#define MTL_Q_TQOMR 0x00
#define MTL_Q_TQUR 0x04
#define MTL_Q_TQDR 0x08
-#define MTL_Q_TCECR 0x10
-#define MTL_Q_TCESR 0x14
-#define MTL_Q_TCQWR 0x18
#define MTL_Q_RQOMR 0x40
#define MTL_Q_RQMPOCR 0x44
#define MTL_Q_RQDR 0x4c
@@ -666,8 +740,6 @@
#define MTL_Q_ISR 0x74
/* MTL queue register entry bit positions and sizes */
-#define MTL_Q_TCQWR_QW_INDEX 0
-#define MTL_Q_TCQWR_QW_WIDTH 21
#define MTL_Q_RQOMR_EHFC_INDEX 7
#define MTL_Q_RQOMR_EHFC_WIDTH 1
#define MTL_Q_RQOMR_RFA_INDEX 8
@@ -682,6 +754,8 @@
#define MTL_Q_RQOMR_RTC_WIDTH 2
#define MTL_Q_TQOMR_FTQ_INDEX 0
#define MTL_Q_TQOMR_FTQ_WIDTH 1
+#define MTL_Q_TQOMR_Q2TCMAP_INDEX 8
+#define MTL_Q_TQOMR_Q2TCMAP_WIDTH 3
#define MTL_Q_TQOMR_TQS_INDEX 16
#define MTL_Q_TQOMR_TQS_WIDTH 10
#define MTL_Q_TQOMR_TSF_INDEX 1
@@ -728,10 +802,14 @@
#define MTL_TC_INC MTL_Q_INC
#define MTL_TC_ETSCR 0x10
+#define MTL_TC_ETSSR 0x14
+#define MTL_TC_QWR 0x18
/* MTL traffic class register entry bit positions and sizes */
#define MTL_TC_ETSCR_TSA_INDEX 0
#define MTL_TC_ETSCR_TSA_WIDTH 2
+#define MTL_TC_QWR_QW_INDEX 0
+#define MTL_TC_QWR_QW_WIDTH 21
/* MTL traffic class register value */
#define MTL_TSA_SP 0x00
@@ -764,9 +842,19 @@
#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2
#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1
+#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_INDEX 3
+#define RX_PACKET_ATTRIBUTES_CONTEXT_NEXT_WIDTH 1
+#define RX_PACKET_ATTRIBUTES_CONTEXT_INDEX 4
+#define RX_PACKET_ATTRIBUTES_CONTEXT_WIDTH 1
+#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_INDEX 5
+#define RX_PACKET_ATTRIBUTES_RX_TSTAMP_WIDTH 1
#define RX_NORMAL_DESC0_OVT_INDEX 0
#define RX_NORMAL_DESC0_OVT_WIDTH 16
+#define RX_NORMAL_DESC3_CDA_INDEX 27
+#define RX_NORMAL_DESC3_CDA_WIDTH 1
+#define RX_NORMAL_DESC3_CTXT_INDEX 30
+#define RX_NORMAL_DESC3_CTXT_WIDTH 1
#define RX_NORMAL_DESC3_ES_INDEX 15
#define RX_NORMAL_DESC3_ES_WIDTH 1
#define RX_NORMAL_DESC3_ETLT_INDEX 16
@@ -780,12 +868,19 @@
#define RX_NORMAL_DESC3_PL_INDEX 0
#define RX_NORMAL_DESC3_PL_WIDTH 14
+#define RX_CONTEXT_DESC3_TSA_INDEX 4
+#define RX_CONTEXT_DESC3_TSA_WIDTH 1
+#define RX_CONTEXT_DESC3_TSD_INDEX 6
+#define RX_CONTEXT_DESC3_TSD_WIDTH 1
+
#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_INDEX 0
#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_WIDTH 1
#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_INDEX 1
#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_WIDTH 1
#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 2
#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
+#define TX_PACKET_ATTRIBUTES_PTP_INDEX 3
+#define TX_PACKET_ATTRIBUTES_PTP_WIDTH 1
#define TX_CONTEXT_DESC2_MSS_INDEX 0
#define TX_CONTEXT_DESC2_MSS_WIDTH 15
@@ -802,6 +897,8 @@
#define TX_NORMAL_DESC2_HL_B1L_WIDTH 14
#define TX_NORMAL_DESC2_IC_INDEX 31
#define TX_NORMAL_DESC2_IC_WIDTH 1
+#define TX_NORMAL_DESC2_TTSE_INDEX 30
+#define TX_NORMAL_DESC2_TTSE_WIDTH 1
#define TX_NORMAL_DESC2_VTIR_INDEX 14
#define TX_NORMAL_DESC2_VTIR_WIDTH 2
#define TX_NORMAL_DESC3_CIC_INDEX 16
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c b/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c
new file mode 100644
index 000000000000..7d6a49b24321
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dcb.c
@@ -0,0 +1,270 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute 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 file 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 incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and 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.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * 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.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and 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.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * 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/netdevice.h>
+#include <net/dcbnl.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static int xgbe_dcb_ieee_getets(struct net_device *netdev,
+ struct ieee_ets *ets)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ /* Set number of supported traffic classes */
+ ets->ets_cap = pdata->hw_feat.tc_cnt;
+
+ if (pdata->ets) {
+ ets->cbs = pdata->ets->cbs;
+ memcpy(ets->tc_tx_bw, pdata->ets->tc_tx_bw,
+ sizeof(ets->tc_tx_bw));
+ memcpy(ets->tc_tsa, pdata->ets->tc_tsa,
+ sizeof(ets->tc_tsa));
+ memcpy(ets->prio_tc, pdata->ets->prio_tc,
+ sizeof(ets->prio_tc));
+ }
+
+ return 0;
+}
+
+static int xgbe_dcb_ieee_setets(struct net_device *netdev,
+ struct ieee_ets *ets)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ unsigned int i, tc_ets, tc_ets_weight;
+
+ tc_ets = 0;
+ tc_ets_weight = 0;
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+ DBGPR(" TC%u: tx_bw=%hhu, rx_bw=%hhu, tsa=%hhu\n", i,
+ ets->tc_tx_bw[i], ets->tc_rx_bw[i], ets->tc_tsa[i]);
+ DBGPR(" PRIO%u: TC=%hhu\n", i, ets->prio_tc[i]);
+
+ if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) &&
+ (i >= pdata->hw_feat.tc_cnt))
+ return -EINVAL;
+
+ if (ets->prio_tc[i] >= pdata->hw_feat.tc_cnt)
+ return -EINVAL;
+
+ switch (ets->tc_tsa[i]) {
+ case IEEE_8021QAZ_TSA_STRICT:
+ break;
+ case IEEE_8021QAZ_TSA_ETS:
+ tc_ets = 1;
+ tc_ets_weight += ets->tc_tx_bw[i];
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ }
+
+ /* Weights must add up to 100% */
+ if (tc_ets && (tc_ets_weight != 100))
+ return -EINVAL;
+
+ if (!pdata->ets) {
+ pdata->ets = devm_kzalloc(pdata->dev, sizeof(*pdata->ets),
+ GFP_KERNEL);
+ if (!pdata->ets)
+ return -ENOMEM;
+ }
+
+ memcpy(pdata->ets, ets, sizeof(*pdata->ets));
+
+ pdata->hw_if.config_dcb_tc(pdata);
+
+ return 0;
+}
+
+static int xgbe_dcb_ieee_getpfc(struct net_device *netdev,
+ struct ieee_pfc *pfc)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ /* Set number of supported PFC traffic classes */
+ pfc->pfc_cap = pdata->hw_feat.tc_cnt;
+
+ if (pdata->pfc) {
+ pfc->pfc_en = pdata->pfc->pfc_en;
+ pfc->mbc = pdata->pfc->mbc;
+ pfc->delay = pdata->pfc->delay;
+ }
+
+ return 0;
+}
+
+static int xgbe_dcb_ieee_setpfc(struct net_device *netdev,
+ struct ieee_pfc *pfc)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ DBGPR(" cap=%hhu, en=%hhx, mbc=%hhu, delay=%hhu\n",
+ pfc->pfc_cap, pfc->pfc_en, pfc->mbc, pfc->delay);
+
+ if (!pdata->pfc) {
+ pdata->pfc = devm_kzalloc(pdata->dev, sizeof(*pdata->pfc),
+ GFP_KERNEL);
+ if (!pdata->pfc)
+ return -ENOMEM;
+ }
+
+ memcpy(pdata->pfc, pfc, sizeof(*pdata->pfc));
+
+ pdata->hw_if.config_dcb_pfc(pdata);
+
+ return 0;
+}
+
+static u8 xgbe_dcb_getdcbx(struct net_device *netdev)
+{
+ return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
+}
+
+static u8 xgbe_dcb_setdcbx(struct net_device *netdev, u8 dcbx)
+{
+ u8 support = xgbe_dcb_getdcbx(netdev);
+
+ DBGPR(" DCBX=%#hhx\n", dcbx);
+
+ if (dcbx & ~support)
+ return 1;
+
+ if ((dcbx & support) != support)
+ return 1;
+
+ return 0;
+}
+
+static const struct dcbnl_rtnl_ops xgbe_dcbnl_ops = {
+ /* IEEE 802.1Qaz std */
+ .ieee_getets = xgbe_dcb_ieee_getets,
+ .ieee_setets = xgbe_dcb_ieee_setets,
+ .ieee_getpfc = xgbe_dcb_ieee_getpfc,
+ .ieee_setpfc = xgbe_dcb_ieee_setpfc,
+
+ /* DCBX configuration */
+ .getdcbx = xgbe_dcb_getdcbx,
+ .setdcbx = xgbe_dcb_setdcbx,
+};
+
+const struct dcbnl_rtnl_ops *xgbe_get_dcbnl_ops(void)
+{
+ return &xgbe_dcbnl_ops;
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
index 6bb76d5c817b..346592dca33c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
@@ -151,7 +151,7 @@ static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
{
char workarea[32];
ssize_t len;
- unsigned int scan_value;
+ int ret;
if (*ppos != 0)
return 0;
@@ -165,9 +165,8 @@ static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
return len;
workarea[len] = '\0';
- if (sscanf(workarea, "%x", &scan_value) == 1)
- *value = scan_value;
- else
+ ret = kstrtouint(workarea, 16, value);
+ if (ret)
return -EIO;
return len;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
index 6f1c85956d50..1c5d62e8dab6 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
@@ -131,7 +131,7 @@ static void xgbe_free_ring(struct xgbe_prv_data *pdata,
if (ring->rdata) {
for (i = 0; i < ring->rdesc_count; i++) {
- rdata = GET_DESC_DATA(ring, i);
+ rdata = XGBE_GET_DESC_DATA(ring, i);
xgbe_unmap_skb(pdata, rdata);
}
@@ -256,7 +256,7 @@ static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata)
rdesc_dma = ring->rdesc_dma;
for (j = 0; j < ring->rdesc_count; j++) {
- rdata = GET_DESC_DATA(ring, j);
+ rdata = XGBE_GET_DESC_DATA(ring, j);
rdata->rdesc = rdesc;
rdata->rdesc_dma = rdesc_dma;
@@ -298,7 +298,7 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
rdesc_dma = ring->rdesc_dma;
for (j = 0; j < ring->rdesc_count; j++) {
- rdata = GET_DESC_DATA(ring, j);
+ rdata = XGBE_GET_DESC_DATA(ring, j);
rdata->rdesc = rdesc;
rdata->rdesc_dma = rdesc_dma;
@@ -359,6 +359,15 @@ static void xgbe_unmap_skb(struct xgbe_prv_data *pdata,
rdata->len = 0;
rdata->interrupt = 0;
rdata->mapped_as_page = 0;
+
+ if (rdata->state_saved) {
+ rdata->state_saved = 0;
+ rdata->state.incomplete = 0;
+ rdata->state.context_next = 0;
+ rdata->state.skb = NULL;
+ rdata->state.len = 0;
+ rdata->state.error = 0;
+ }
}
static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
@@ -392,7 +401,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
if ((tso && (packet->mss != ring->tx.cur_mss)) ||
(vlan && (packet->vlan_ctag != ring->tx.cur_vlan_ctag)))
cur_index++;
- rdata = GET_DESC_DATA(ring, cur_index);
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
if (tso) {
DBGPR(" TSO packet\n");
@@ -413,12 +422,12 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
packet->length += packet->header_len;
cur_index++;
- rdata = GET_DESC_DATA(ring, cur_index);
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
}
/* Map the (remainder of the) packet */
for (datalen = skb_headlen(skb) - offset; datalen; ) {
- len = min_t(unsigned int, datalen, TX_MAX_BUF_SIZE);
+ len = min_t(unsigned int, datalen, XGBE_TX_MAX_BUF_SIZE);
skb_dma = dma_map_single(pdata->dev, skb->data + offset, len,
DMA_TO_DEVICE);
@@ -437,7 +446,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
packet->length += len;
cur_index++;
- rdata = GET_DESC_DATA(ring, cur_index);
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
}
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
@@ -447,7 +456,8 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
offset = 0;
for (datalen = skb_frag_size(frag); datalen; ) {
- len = min_t(unsigned int, datalen, TX_MAX_BUF_SIZE);
+ len = min_t(unsigned int, datalen,
+ XGBE_TX_MAX_BUF_SIZE);
skb_dma = skb_frag_dma_map(pdata->dev, frag, offset,
len, DMA_TO_DEVICE);
@@ -468,7 +478,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
packet->length += len;
cur_index++;
- rdata = GET_DESC_DATA(ring, cur_index);
+ rdata = XGBE_GET_DESC_DATA(ring, cur_index);
}
}
@@ -484,7 +494,7 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
err_out:
while (start_index < cur_index) {
- rdata = GET_DESC_DATA(ring, start_index++);
+ rdata = XGBE_GET_DESC_DATA(ring, start_index++);
xgbe_unmap_skb(pdata, rdata);
}
@@ -507,7 +517,7 @@ static void xgbe_realloc_skb(struct xgbe_channel *channel)
ring->rx.realloc_index);
for (i = 0; i < ring->dirty; i++) {
- rdata = GET_DESC_DATA(ring, ring->rx.realloc_index);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index);
/* Reset rdata values */
xgbe_unmap_skb(pdata, rdata);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 002293b0819d..edaca4496264 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -116,6 +116,8 @@
#include <linux/phy.h>
#include <linux/clk.h>
+#include <linux/bitrev.h>
+#include <linux/crc32.h>
#include "xgbe.h"
#include "xgbe-common.h"
@@ -129,7 +131,7 @@ static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,
DBGPR("-->xgbe_usec_to_riwt\n");
- rate = clk_get_rate(pdata->sysclock);
+ rate = clk_get_rate(pdata->sysclk);
/*
* Convert the input usec value to the watchdog timer value. Each
@@ -152,7 +154,7 @@ static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,
DBGPR("-->xgbe_riwt_to_usec\n");
- rate = clk_get_rate(pdata->sysclock);
+ rate = clk_get_rate(pdata->sysclk);
/*
* Convert the input watchdog timer value to the usec value. Each
@@ -245,7 +247,7 @@ static int xgbe_config_rsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
{
unsigned int i;
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RSF, val);
return 0;
@@ -255,7 +257,7 @@ static int xgbe_config_tsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
{
unsigned int i;
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TSF, val);
return 0;
@@ -266,7 +268,7 @@ static int xgbe_config_rx_threshold(struct xgbe_prv_data *pdata,
{
unsigned int i;
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RTC, val);
return 0;
@@ -277,7 +279,7 @@ static int xgbe_config_tx_threshold(struct xgbe_prv_data *pdata,
{
unsigned int i;
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TTC, val);
return 0;
@@ -341,12 +343,12 @@ static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
unsigned int i;
/* Clear MTL flow control */
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
/* Clear MAC flow control */
max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
- q_count = min_t(unsigned int, pdata->hw_feat.rx_q_cnt, max_q_count);
+ q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count);
reg = MAC_Q0TFCR;
for (i = 0; i < q_count; i++) {
reg_val = XGMAC_IOREAD(pdata, reg);
@@ -366,12 +368,12 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
unsigned int i;
/* Set MTL flow control */
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 1);
/* Set MAC flow control */
max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
- q_count = min_t(unsigned int, pdata->hw_feat.rx_q_cnt, max_q_count);
+ q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count);
reg = MAC_Q0TFCR;
for (i = 0; i < q_count; i++) {
reg_val = XGMAC_IOREAD(pdata, reg);
@@ -405,7 +407,9 @@ static int xgbe_enable_rx_flow_control(struct xgbe_prv_data *pdata)
static int xgbe_config_tx_flow_control(struct xgbe_prv_data *pdata)
{
- if (pdata->tx_pause)
+ struct ieee_pfc *pfc = pdata->pfc;
+
+ if (pdata->tx_pause || (pfc && pfc->pfc_en))
xgbe_enable_tx_flow_control(pdata);
else
xgbe_disable_tx_flow_control(pdata);
@@ -415,7 +419,9 @@ static int xgbe_config_tx_flow_control(struct xgbe_prv_data *pdata)
static int xgbe_config_rx_flow_control(struct xgbe_prv_data *pdata)
{
- if (pdata->rx_pause)
+ struct ieee_pfc *pfc = pdata->pfc;
+
+ if (pdata->rx_pause || (pfc && pfc->pfc_en))
xgbe_enable_rx_flow_control(pdata);
else
xgbe_disable_rx_flow_control(pdata);
@@ -425,8 +431,13 @@ static int xgbe_config_rx_flow_control(struct xgbe_prv_data *pdata)
static void xgbe_config_flow_control(struct xgbe_prv_data *pdata)
{
+ struct ieee_pfc *pfc = pdata->pfc;
+
xgbe_config_tx_flow_control(pdata);
xgbe_config_rx_flow_control(pdata);
+
+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE,
+ (pfc && pfc->pfc_en) ? 1 : 0);
}
static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata)
@@ -484,14 +495,18 @@ static void xgbe_enable_mtl_interrupts(struct xgbe_prv_data *pdata)
XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, mtl_q_isr);
/* No MTL interrupts to be enabled */
- XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, 0);
+ XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_IER, 0);
}
}
static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
{
- /* No MAC interrupts to be enabled */
- XGMAC_IOWRITE(pdata, MAC_IER, 0);
+ unsigned int mac_ier = 0;
+
+ /* Enable Timestamp interrupt */
+ XGMAC_SET_BITS(mac_ier, MAC_IER, TSIE, 1);
+
+ XGMAC_IOWRITE(pdata, MAC_IER, mac_ier);
/* Enable all counter interrupts */
XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xff);
@@ -547,24 +562,16 @@ static int xgbe_set_all_multicast_mode(struct xgbe_prv_data *pdata,
return 0;
}
-static int xgbe_set_addn_mac_addrs(struct xgbe_prv_data *pdata,
- unsigned int am_mode)
+static void xgbe_set_mac_reg(struct xgbe_prv_data *pdata,
+ struct netdev_hw_addr *ha, unsigned int *mac_reg)
{
- struct netdev_hw_addr *ha;
- unsigned int mac_reg;
unsigned int mac_addr_hi, mac_addr_lo;
u8 *mac_addr;
- unsigned int i;
-
- XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
- XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 0);
- i = 0;
- mac_reg = MAC_MACA1HR;
+ mac_addr_lo = 0;
+ mac_addr_hi = 0;
- netdev_for_each_uc_addr(ha, pdata->netdev) {
- mac_addr_lo = 0;
- mac_addr_hi = 0;
+ if (ha) {
mac_addr = (u8 *)&mac_addr_lo;
mac_addr[0] = ha->addr[0];
mac_addr[1] = ha->addr[1];
@@ -574,54 +581,93 @@ static int xgbe_set_addn_mac_addrs(struct xgbe_prv_data *pdata,
mac_addr[0] = ha->addr[4];
mac_addr[1] = ha->addr[5];
- DBGPR(" adding unicast address %pM at 0x%04x\n",
- ha->addr, mac_reg);
+ DBGPR(" adding mac address %pM at 0x%04x\n", ha->addr,
+ *mac_reg);
XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
+ }
- XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi);
- mac_reg += MAC_MACA_INC;
- XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo);
- mac_reg += MAC_MACA_INC;
+ XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_hi);
+ *mac_reg += MAC_MACA_INC;
+ XGMAC_IOWRITE(pdata, *mac_reg, mac_addr_lo);
+ *mac_reg += MAC_MACA_INC;
+}
- i++;
- }
+static void xgbe_set_mac_addn_addrs(struct xgbe_prv_data *pdata)
+{
+ struct net_device *netdev = pdata->netdev;
+ struct netdev_hw_addr *ha;
+ unsigned int mac_reg;
+ unsigned int addn_macs;
+
+ mac_reg = MAC_MACA1HR;
+ addn_macs = pdata->hw_feat.addn_mac;
- if (!am_mode) {
- netdev_for_each_mc_addr(ha, pdata->netdev) {
- mac_addr_lo = 0;
- mac_addr_hi = 0;
- mac_addr = (u8 *)&mac_addr_lo;
- mac_addr[0] = ha->addr[0];
- mac_addr[1] = ha->addr[1];
- mac_addr[2] = ha->addr[2];
- mac_addr[3] = ha->addr[3];
- mac_addr = (u8 *)&mac_addr_hi;
- mac_addr[0] = ha->addr[4];
- mac_addr[1] = ha->addr[5];
-
- DBGPR(" adding multicast address %pM at 0x%04x\n",
- ha->addr, mac_reg);
-
- XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
-
- XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi);
- mac_reg += MAC_MACA_INC;
- XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo);
- mac_reg += MAC_MACA_INC;
-
- i++;
+ if (netdev_uc_count(netdev) > addn_macs) {
+ xgbe_set_promiscuous_mode(pdata, 1);
+ } else {
+ netdev_for_each_uc_addr(ha, netdev) {
+ xgbe_set_mac_reg(pdata, ha, &mac_reg);
+ addn_macs--;
+ }
+
+ if (netdev_mc_count(netdev) > addn_macs) {
+ xgbe_set_all_multicast_mode(pdata, 1);
+ } else {
+ netdev_for_each_mc_addr(ha, netdev) {
+ xgbe_set_mac_reg(pdata, ha, &mac_reg);
+ addn_macs--;
+ }
}
}
/* Clear remaining additional MAC address entries */
- for (; i < pdata->hw_feat.addn_mac; i++) {
- XGMAC_IOWRITE(pdata, mac_reg, 0);
- mac_reg += MAC_MACA_INC;
- XGMAC_IOWRITE(pdata, mac_reg, 0);
- mac_reg += MAC_MACA_INC;
+ while (addn_macs--)
+ xgbe_set_mac_reg(pdata, NULL, &mac_reg);
+}
+
+static void xgbe_set_mac_hash_table(struct xgbe_prv_data *pdata)
+{
+ struct net_device *netdev = pdata->netdev;
+ struct netdev_hw_addr *ha;
+ unsigned int hash_reg;
+ unsigned int hash_table_shift, hash_table_count;
+ u32 hash_table[XGBE_MAC_HASH_TABLE_SIZE];
+ u32 crc;
+ unsigned int i;
+
+ hash_table_shift = 26 - (pdata->hw_feat.hash_table_size >> 7);
+ hash_table_count = pdata->hw_feat.hash_table_size / 32;
+ memset(hash_table, 0, sizeof(hash_table));
+
+ /* Build the MAC Hash Table register values */
+ netdev_for_each_uc_addr(ha, netdev) {
+ crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
+ crc >>= hash_table_shift;
+ hash_table[crc >> 5] |= (1 << (crc & 0x1f));
+ }
+
+ netdev_for_each_mc_addr(ha, netdev) {
+ crc = bitrev32(~crc32_le(~0, ha->addr, ETH_ALEN));
+ crc >>= hash_table_shift;
+ hash_table[crc >> 5] |= (1 << (crc & 0x1f));
}
+ /* Set the MAC Hash Table registers */
+ hash_reg = MAC_HTR0;
+ for (i = 0; i < hash_table_count; i++) {
+ XGMAC_IOWRITE(pdata, hash_reg, hash_table[i]);
+ hash_reg += MAC_HTR_INC;
+ }
+}
+
+static int xgbe_add_mac_addresses(struct xgbe_prv_data *pdata)
+{
+ if (pdata->hw_feat.hash_table_size)
+ xgbe_set_mac_hash_table(pdata);
+ else
+ xgbe_set_mac_addn_addrs(pdata);
+
return 0;
}
@@ -738,6 +784,89 @@ static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
return 0;
}
+static int xgbe_enable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
+{
+ /* Enable VLAN filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
+
+ /* Enable VLAN Hash Table filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
+
+ /* Disable VLAN tag inverse matching */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
+
+ /* Only filter on the lower 12-bits of the VLAN tag */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
+
+ /* In order for the VLAN Hash Table filtering to be effective,
+ * the VLAN tag identifier in the VLAN Tag Register must not
+ * be zero. Set the VLAN tag identifier to "1" to enable the
+ * VLAN Hash Table filtering. This implies that a VLAN tag of
+ * 1 will always pass filtering.
+ */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
+
+ return 0;
+}
+
+static int xgbe_disable_rx_vlan_filtering(struct xgbe_prv_data *pdata)
+{
+ /* Disable VLAN filtering */
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
+
+ return 0;
+}
+
+#ifndef CRCPOLY_LE
+#define CRCPOLY_LE 0xedb88320
+#endif
+static u32 xgbe_vid_crc32_le(__le16 vid_le)
+{
+ u32 poly = CRCPOLY_LE;
+ u32 crc = ~0;
+ u32 temp = 0;
+ unsigned char *data = (unsigned char *)&vid_le;
+ unsigned char data_byte = 0;
+ int i, bits;
+
+ bits = get_bitmask_order(VLAN_VID_MASK);
+ for (i = 0; i < bits; i++) {
+ if ((i % 8) == 0)
+ data_byte = data[i / 8];
+
+ temp = ((crc & 1) ^ data_byte) & 1;
+ crc >>= 1;
+ data_byte >>= 1;
+
+ if (temp)
+ crc ^= poly;
+ }
+
+ return crc;
+}
+
+static int xgbe_update_vlan_hash_table(struct xgbe_prv_data *pdata)
+{
+ u32 crc;
+ u16 vid;
+ __le16 vid_le;
+ u16 vlan_hash_table = 0;
+
+ /* Generate the VLAN Hash Table value */
+ for_each_set_bit(vid, pdata->active_vlans, VLAN_N_VID) {
+ /* Get the CRC32 value of the VLAN ID */
+ vid_le = cpu_to_le16(vid);
+ crc = bitrev32(~xgbe_vid_crc32_le(vid_le)) >> 28;
+
+ vlan_hash_table |= (1 << crc);
+ }
+
+ /* Set the VLAN Hash Table filtering register */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
+
+ return 0;
+}
+
static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata)
{
struct xgbe_ring_desc *rdesc = rdata->rdesc;
@@ -766,7 +895,7 @@ static void xgbe_tx_desc_init(struct xgbe_channel *channel)
/* Initialze all descriptors */
for (i = 0; i < ring->rdesc_count; i++) {
- rdata = GET_DESC_DATA(ring, i);
+ rdata = XGBE_GET_DESC_DATA(ring, i);
rdesc = rdata->rdesc;
/* Initialize Tx descriptor
@@ -791,7 +920,7 @@ static void xgbe_tx_desc_init(struct xgbe_channel *channel)
XGMAC_DMA_IOWRITE(channel, DMA_CH_TDRLR, ring->rdesc_count - 1);
/* Update the starting address of descriptor ring */
- rdata = GET_DESC_DATA(ring, start_index);
+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_HI,
upper_32_bits(rdata->rdesc_dma));
XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_LO,
@@ -848,7 +977,7 @@ static void xgbe_rx_desc_init(struct xgbe_channel *channel)
/* Initialize all descriptors */
for (i = 0; i < ring->rdesc_count; i++) {
- rdata = GET_DESC_DATA(ring, i);
+ rdata = XGBE_GET_DESC_DATA(ring, i);
rdesc = rdata->rdesc;
/* Initialize Rx descriptor
@@ -882,20 +1011,194 @@ static void xgbe_rx_desc_init(struct xgbe_channel *channel)
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDRLR, ring->rdesc_count - 1);
/* Update the starting address of descriptor ring */
- rdata = GET_DESC_DATA(ring, start_index);
+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_HI,
upper_32_bits(rdata->rdesc_dma));
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_LO,
lower_32_bits(rdata->rdesc_dma));
/* Update the Rx Descriptor Tail Pointer */
- rdata = GET_DESC_DATA(ring, start_index + ring->rdesc_count - 1);
+ rdata = XGBE_GET_DESC_DATA(ring, start_index + ring->rdesc_count - 1);
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
lower_32_bits(rdata->rdesc_dma));
DBGPR("<--rx_desc_init\n");
}
+static void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
+ unsigned int addend)
+{
+ /* Set the addend register value and tell the device */
+ XGMAC_IOWRITE(pdata, MAC_TSAR, addend);
+ XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
+
+ /* Wait for addend update to complete */
+ while (XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
+ udelay(5);
+}
+
+static void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
+ unsigned int nsec)
+{
+ /* Set the time values and tell the device */
+ XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
+ XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
+ XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
+
+ /* Wait for time update to complete */
+ while (XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
+ udelay(5);
+}
+
+static u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
+{
+ u64 nsec;
+
+ nsec = XGMAC_IOREAD(pdata, MAC_STSR);
+ nsec *= NSEC_PER_SEC;
+ nsec += XGMAC_IOREAD(pdata, MAC_STNR);
+
+ return nsec;
+}
+
+static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
+{
+ unsigned int tx_snr;
+ u64 nsec;
+
+ tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+ if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
+ return 0;
+
+ nsec = XGMAC_IOREAD(pdata, MAC_TXSSR);
+ nsec *= NSEC_PER_SEC;
+ nsec += tx_snr;
+
+ return nsec;
+}
+
+static void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
+ struct xgbe_ring_desc *rdesc)
+{
+ u64 nsec;
+
+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSA) &&
+ !XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSD)) {
+ nsec = le32_to_cpu(rdesc->desc1);
+ nsec <<= 32;
+ nsec |= le32_to_cpu(rdesc->desc0);
+ if (nsec != 0xffffffffffffffffULL) {
+ packet->rx_tstamp = nsec;
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ RX_TSTAMP, 1);
+ }
+ }
+}
+
+static int xgbe_config_tstamp(struct xgbe_prv_data *pdata,
+ unsigned int mac_tscr)
+{
+ /* Set one nano-second accuracy */
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
+
+ /* Set fine timestamp update */
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
+
+ /* Overwrite earlier timestamps */
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
+
+ XGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
+
+ /* Exit if timestamping is not enabled */
+ if (!XGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA))
+ return 0;
+
+ /* Initialize time registers */
+ XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, XGBE_TSTAMP_SSINC);
+ XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, XGBE_TSTAMP_SNSINC);
+ xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
+ xgbe_set_tstamp_time(pdata, 0, 0);
+
+ /* Initialize the timecounter */
+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
+ ktime_to_ns(ktime_get_real()));
+
+ return 0;
+}
+
+static void xgbe_config_dcb_tc(struct xgbe_prv_data *pdata)
+{
+ struct ieee_ets *ets = pdata->ets;
+ unsigned int total_weight, min_weight, weight;
+ unsigned int i;
+
+ if (!ets)
+ return;
+
+ /* Set Tx to deficit weighted round robin scheduling algorithm (when
+ * traffic class is using ETS algorithm)
+ */
+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_DWRR);
+
+ /* Set Traffic Class algorithms */
+ total_weight = pdata->netdev->mtu * pdata->hw_feat.tc_cnt;
+ min_weight = total_weight / 100;
+ if (!min_weight)
+ min_weight = 1;
+
+ for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
+ switch (ets->tc_tsa[i]) {
+ case IEEE_8021QAZ_TSA_STRICT:
+ DBGPR(" TC%u using SP\n", i);
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
+ MTL_TSA_SP);
+ break;
+ case IEEE_8021QAZ_TSA_ETS:
+ weight = total_weight * ets->tc_tx_bw[i] / 100;
+ weight = clamp(weight, min_weight, total_weight);
+
+ DBGPR(" TC%u using DWRR (weight %u)\n", i, weight);
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
+ MTL_TSA_ETS);
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW,
+ weight);
+ break;
+ }
+ }
+}
+
+static void xgbe_config_dcb_pfc(struct xgbe_prv_data *pdata)
+{
+ struct ieee_pfc *pfc = pdata->pfc;
+ struct ieee_ets *ets = pdata->ets;
+ unsigned int mask, reg, reg_val;
+ unsigned int tc, prio;
+
+ if (!pfc || !ets)
+ return;
+
+ for (tc = 0; tc < pdata->hw_feat.tc_cnt; tc++) {
+ mask = 0;
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++) {
+ if ((pfc->pfc_en & (1 << prio)) &&
+ (ets->prio_tc[prio] == tc))
+ mask |= (1 << prio);
+ }
+ mask &= 0xff;
+
+ DBGPR(" TC%u PFC mask=%#x\n", tc, mask);
+ reg = MTL_TCPM0R + (MTL_TCPM_INC * (tc / MTL_TCPM_TC_PER_REG));
+ reg_val = XGMAC_IOREAD(pdata, reg);
+
+ reg_val &= ~(0xff << ((tc % MTL_TCPM_TC_PER_REG) << 3));
+ reg_val |= (mask << ((tc % MTL_TCPM_TC_PER_REG) << 3));
+
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+ }
+
+ xgbe_config_flow_control(pdata);
+}
+
static void xgbe_pre_xmit(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
@@ -933,7 +1236,7 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
if (tx_coalesce && !channel->tx_timer_active)
ring->coalesce_count = 0;
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
rdesc = rdata->rdesc;
/* Create a context descriptor if this is a TSO packet */
@@ -977,7 +1280,7 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
}
ring->cur++;
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
rdesc = rdata->rdesc;
}
@@ -994,6 +1297,10 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, VTIR,
TX_NORMAL_DESC2_VLAN_INSERT);
+ /* Timestamp enablement check */
+ if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP))
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, TTSE, 1);
+
/* Set IC bit based on Tx coalescing settings */
XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
if (tx_coalesce && (!tx_frames ||
@@ -1034,7 +1341,7 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
for (i = ring->cur - start_index + 1; i < packet->rdesc_count; i++) {
ring->cur++;
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
rdesc = rdata->rdesc;
/* Update buffer address */
@@ -1074,7 +1381,7 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
wmb();
/* Set OWN bit for the first descriptor */
- rdata = GET_DESC_DATA(ring, start_index);
+ rdata = XGBE_GET_DESC_DATA(ring, start_index);
rdesc = rdata->rdesc;
XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
@@ -1088,7 +1395,7 @@ static void xgbe_pre_xmit(struct xgbe_channel *channel)
/* Issue a poll command to Tx DMA by writing address
* of next immediate free descriptor */
ring->cur++;
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
lower_32_bits(rdata->rdesc_dma));
@@ -1113,11 +1420,12 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
struct xgbe_ring_data *rdata;
struct xgbe_ring_desc *rdesc;
struct xgbe_packet_data *packet = &ring->packet_data;
+ struct net_device *netdev = channel->pdata->netdev;
unsigned int err, etlt;
DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur);
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
rdesc = rdata->rdesc;
/* Check for data availability */
@@ -1128,6 +1436,25 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
xgbe_dump_rx_desc(ring, rdesc, ring->cur);
#endif
+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, CTXT)) {
+ /* Timestamp Context Descriptor */
+ xgbe_get_rx_tstamp(packet, rdesc);
+
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ CONTEXT, 1);
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ CONTEXT_NEXT, 0);
+ return 0;
+ }
+
+ /* Normal Descriptor, be sure Context Descriptor bit is off */
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES, CONTEXT, 0);
+
+ /* Indicate if a Context Descriptor is next */
+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, CDA))
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ CONTEXT_NEXT, 1);
+
/* Get the packet length */
rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
@@ -1153,7 +1480,8 @@ static int xgbe_dev_read(struct xgbe_channel *channel)
DBGPR(" err=%u, etlt=%#x\n", err, etlt);
if (!err || (err && !etlt)) {
- if (etlt == 0x09) {
+ if ((etlt == 0x09) &&
+ (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
VLAN_CTAG, 1);
packet->vlan_ctag = XGMAC_GET_BITS_LE(rdesc->desc0,
@@ -1188,56 +1516,48 @@ static int xgbe_is_last_desc(struct xgbe_ring_desc *rdesc)
return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD);
}
-static void xgbe_save_interrupt_status(struct xgbe_channel *channel,
- enum xgbe_int_state int_state)
+static int xgbe_enable_int(struct xgbe_channel *channel,
+ enum xgbe_int int_id)
{
unsigned int dma_ch_ier;
- if (int_state == XGMAC_INT_STATE_SAVE) {
- channel->saved_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
- channel->saved_ier &= DMA_INTERRUPT_MASK;
- } else {
- dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
- dma_ch_ier |= channel->saved_ier;
- XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
- }
-}
+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
-static int xgbe_enable_int(struct xgbe_channel *channel,
- enum xgbe_int int_id)
-{
switch (int_id) {
- case XGMAC_INT_DMA_ISR_DC0IS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 1);
- break;
case XGMAC_INT_DMA_CH_SR_TI:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
break;
case XGMAC_INT_DMA_CH_SR_TPS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TXSE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 1);
break;
case XGMAC_INT_DMA_CH_SR_TBU:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TBUE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 1);
break;
case XGMAC_INT_DMA_CH_SR_RI:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RIE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
break;
case XGMAC_INT_DMA_CH_SR_RBU:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RBUE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1);
break;
case XGMAC_INT_DMA_CH_SR_RPS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RSE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TI_RI:
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
break;
case XGMAC_INT_DMA_CH_SR_FBE:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, FBEE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1);
break;
case XGMAC_INT_DMA_ALL:
- xgbe_save_interrupt_status(channel, XGMAC_INT_STATE_RESTORE);
+ dma_ch_ier |= channel->saved_ier;
break;
default:
return -1;
}
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+
return 0;
}
@@ -1246,42 +1566,44 @@ static int xgbe_disable_int(struct xgbe_channel *channel,
{
unsigned int dma_ch_ier;
+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
+
switch (int_id) {
- case XGMAC_INT_DMA_ISR_DC0IS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 0);
- break;
case XGMAC_INT_DMA_CH_SR_TI:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0);
break;
case XGMAC_INT_DMA_CH_SR_TPS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TXSE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TXSE, 0);
break;
case XGMAC_INT_DMA_CH_SR_TBU:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TBUE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TBUE, 0);
break;
case XGMAC_INT_DMA_CH_SR_RI:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RIE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0);
break;
case XGMAC_INT_DMA_CH_SR_RBU:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RBUE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 0);
break;
case XGMAC_INT_DMA_CH_SR_RPS:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RSE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RSE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TI_RI:
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 0);
break;
case XGMAC_INT_DMA_CH_SR_FBE:
- XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, FBEE, 0);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 0);
break;
case XGMAC_INT_DMA_ALL:
- xgbe_save_interrupt_status(channel, XGMAC_INT_STATE_SAVE);
-
- dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
- dma_ch_ier &= ~DMA_INTERRUPT_MASK;
- XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+ channel->saved_ier = dma_ch_ier & XGBE_DMA_INTERRUPT_MASK;
+ dma_ch_ier &= ~XGBE_DMA_INTERRUPT_MASK;
break;
default:
return -1;
}
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+
return 0;
}
@@ -1311,11 +1633,11 @@ static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
{
unsigned int i, count;
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1);
/* Poll Until Poll Condition */
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++) {
+ for (i = 0; i < pdata->tx_q_count; i++) {
count = 2000;
while (count-- && XGMAC_MTL_IOREAD_BITS(pdata, i,
MTL_Q_TQOMR, FTQ))
@@ -1335,6 +1657,7 @@ static void xgbe_config_dma_bus(struct xgbe_prv_data *pdata)
/* Set the System Bus mode */
XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, UNDEF, 1);
+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, BLEN_256, 1);
}
static void xgbe_config_dma_cache(struct xgbe_prv_data *pdata)
@@ -1342,23 +1665,23 @@ static void xgbe_config_dma_cache(struct xgbe_prv_data *pdata)
unsigned int arcache, awcache;
arcache = 0;
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, DMA_ARCACHE_SETTING);
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRD, DMA_ARDOMAIN_SETTING);
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, DMA_ARCACHE_SETTING);
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, TED, DMA_ARDOMAIN_SETTING);
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, DMA_ARCACHE_SETTING);
- XGMAC_SET_BITS(arcache, DMA_AXIARCR, THD, DMA_ARDOMAIN_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, pdata->arcache);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRD, pdata->axdomain);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, pdata->arcache);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TED, pdata->axdomain);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, pdata->arcache);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THD, pdata->axdomain);
XGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache);
awcache = 0;
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, DMA_AWCACHE_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWD, DMA_AWDOMAIN_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, DMA_AWCACHE_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, DMA_AWDOMAIN_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, DMA_AWCACHE_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, DMA_AWDOMAIN_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDC, DMA_AWCACHE_SETTING);
- XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDD, DMA_AWDOMAIN_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, pdata->awcache);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWD, pdata->axdomain);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, pdata->awcache);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, pdata->axdomain);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, pdata->awcache);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, pdata->axdomain);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDC, pdata->awcache);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDD, pdata->axdomain);
XGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache);
}
@@ -1366,14 +1689,15 @@ static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata)
{
unsigned int i;
- /* Set Tx to weighted round robin scheduling algorithm (when
- * traffic class is using ETS algorithm)
- */
+ /* Set Tx to weighted round robin scheduling algorithm */
XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_WRR);
- /* Set Tx traffic classes to strict priority algorithm */
- for (i = 0; i < XGBE_TC_CNT; i++)
- XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA, MTL_TSA_SP);
+ /* Set Tx traffic classes to use WRR algorithm with equal weights */
+ for (i = 0; i < pdata->hw_feat.tc_cnt; i++) {
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA,
+ MTL_TSA_ETS);
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_QWR, QW, 1);
+ }
/* Set Rx to strict priority algorithm */
XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP);
@@ -1388,66 +1712,66 @@ static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size,
/* Calculate Tx/Rx fifo share per queue */
switch (fifo_size) {
case 0:
- q_fifo_size = FIFO_SIZE_B(128);
+ q_fifo_size = XGBE_FIFO_SIZE_B(128);
break;
case 1:
- q_fifo_size = FIFO_SIZE_B(256);
+ q_fifo_size = XGBE_FIFO_SIZE_B(256);
break;
case 2:
- q_fifo_size = FIFO_SIZE_B(512);
+ q_fifo_size = XGBE_FIFO_SIZE_B(512);
break;
case 3:
- q_fifo_size = FIFO_SIZE_KB(1);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(1);
break;
case 4:
- q_fifo_size = FIFO_SIZE_KB(2);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(2);
break;
case 5:
- q_fifo_size = FIFO_SIZE_KB(4);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(4);
break;
case 6:
- q_fifo_size = FIFO_SIZE_KB(8);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(8);
break;
case 7:
- q_fifo_size = FIFO_SIZE_KB(16);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(16);
break;
case 8:
- q_fifo_size = FIFO_SIZE_KB(32);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(32);
break;
case 9:
- q_fifo_size = FIFO_SIZE_KB(64);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(64);
break;
case 10:
- q_fifo_size = FIFO_SIZE_KB(128);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(128);
break;
case 11:
- q_fifo_size = FIFO_SIZE_KB(256);
+ q_fifo_size = XGBE_FIFO_SIZE_KB(256);
break;
}
q_fifo_size = q_fifo_size / queue_count;
/* Set the queue fifo size programmable value */
- if (q_fifo_size >= FIFO_SIZE_KB(256))
+ if (q_fifo_size >= XGBE_FIFO_SIZE_KB(256))
p_fifo = XGMAC_MTL_FIFO_SIZE_256K;
- else if (q_fifo_size >= FIFO_SIZE_KB(128))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(128))
p_fifo = XGMAC_MTL_FIFO_SIZE_128K;
- else if (q_fifo_size >= FIFO_SIZE_KB(64))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(64))
p_fifo = XGMAC_MTL_FIFO_SIZE_64K;
- else if (q_fifo_size >= FIFO_SIZE_KB(32))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(32))
p_fifo = XGMAC_MTL_FIFO_SIZE_32K;
- else if (q_fifo_size >= FIFO_SIZE_KB(16))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(16))
p_fifo = XGMAC_MTL_FIFO_SIZE_16K;
- else if (q_fifo_size >= FIFO_SIZE_KB(8))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(8))
p_fifo = XGMAC_MTL_FIFO_SIZE_8K;
- else if (q_fifo_size >= FIFO_SIZE_KB(4))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(4))
p_fifo = XGMAC_MTL_FIFO_SIZE_4K;
- else if (q_fifo_size >= FIFO_SIZE_KB(2))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(2))
p_fifo = XGMAC_MTL_FIFO_SIZE_2K;
- else if (q_fifo_size >= FIFO_SIZE_KB(1))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_KB(1))
p_fifo = XGMAC_MTL_FIFO_SIZE_1K;
- else if (q_fifo_size >= FIFO_SIZE_B(512))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_B(512))
p_fifo = XGMAC_MTL_FIFO_SIZE_512;
- else if (q_fifo_size >= FIFO_SIZE_B(256))
+ else if (q_fifo_size >= XGBE_FIFO_SIZE_B(256))
p_fifo = XGMAC_MTL_FIFO_SIZE_256;
return p_fifo;
@@ -1459,13 +1783,13 @@ static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
unsigned int i;
fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size,
- pdata->hw_feat.tx_q_cnt);
+ pdata->tx_q_count);
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, fifo_size);
netdev_notice(pdata->netdev, "%d Tx queues, %d byte fifo per queue\n",
- pdata->hw_feat.tx_q_cnt, ((fifo_size + 1) * 256));
+ pdata->tx_q_count, ((fifo_size + 1) * 256));
}
static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
@@ -1474,27 +1798,84 @@ static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
unsigned int i;
fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.rx_fifo_size,
- pdata->hw_feat.rx_q_cnt);
+ pdata->rx_q_count);
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, fifo_size);
netdev_notice(pdata->netdev, "%d Rx queues, %d byte fifo per queue\n",
- pdata->hw_feat.rx_q_cnt, ((fifo_size + 1) * 256));
+ pdata->rx_q_count, ((fifo_size + 1) * 256));
}
-static void xgbe_config_rx_queue_mapping(struct xgbe_prv_data *pdata)
+static void xgbe_config_queue_mapping(struct xgbe_prv_data *pdata)
{
- unsigned int i, reg, reg_val;
- unsigned int q_count = pdata->hw_feat.rx_q_cnt;
+ unsigned int qptc, qptc_extra, queue;
+ unsigned int prio_queues;
+ unsigned int ppq, ppq_extra, prio;
+ unsigned int mask;
+ unsigned int i, j, reg, reg_val;
+
+ /* Map the MTL Tx Queues to Traffic Classes
+ * Note: Tx Queues >= Traffic Classes
+ */
+ qptc = pdata->tx_q_count / pdata->hw_feat.tc_cnt;
+ qptc_extra = pdata->tx_q_count % pdata->hw_feat.tc_cnt;
+
+ for (i = 0, queue = 0; i < pdata->hw_feat.tc_cnt; i++) {
+ for (j = 0; j < qptc; j++) {
+ DBGPR(" TXq%u mapped to TC%u\n", queue, i);
+ XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
+ Q2TCMAP, i);
+ pdata->q2tc_map[queue++] = i;
+ }
+
+ if (i < qptc_extra) {
+ DBGPR(" TXq%u mapped to TC%u\n", queue, i);
+ XGMAC_MTL_IOWRITE_BITS(pdata, queue, MTL_Q_TQOMR,
+ Q2TCMAP, i);
+ pdata->q2tc_map[queue++] = i;
+ }
+ }
+
+ /* Map the 8 VLAN priority values to available MTL Rx queues */
+ prio_queues = min_t(unsigned int, IEEE_8021QAZ_MAX_TCS,
+ pdata->rx_q_count);
+ ppq = IEEE_8021QAZ_MAX_TCS / prio_queues;
+ ppq_extra = IEEE_8021QAZ_MAX_TCS % prio_queues;
+
+ reg = MAC_RQC2R;
+ reg_val = 0;
+ for (i = 0, prio = 0; i < prio_queues;) {
+ mask = 0;
+ for (j = 0; j < ppq; j++) {
+ DBGPR(" PRIO%u mapped to RXq%u\n", prio, i);
+ mask |= (1 << prio);
+ pdata->prio2q_map[prio++] = i;
+ }
+
+ if (i < ppq_extra) {
+ DBGPR(" PRIO%u mapped to RXq%u\n", prio, i);
+ mask |= (1 << prio);
+ pdata->prio2q_map[prio++] = i;
+ }
+
+ reg_val |= (mask << ((i++ % MAC_RQC2_Q_PER_REG) << 3));
+
+ if ((i % MAC_RQC2_Q_PER_REG) && (i != prio_queues))
+ continue;
+
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+ reg += MAC_RQC2_INC;
+ reg_val = 0;
+ }
/* Select dynamic mapping of MTL Rx queue to DMA Rx channel */
reg = MTL_RQDCM0R;
reg_val = 0;
- for (i = 0; i < q_count;) {
+ for (i = 0; i < pdata->rx_q_count;) {
reg_val |= (0x80 << ((i++ % MTL_RQDCM_Q_PER_REG) << 3));
- if ((i % MTL_RQDCM_Q_PER_REG) && (i != q_count))
+ if ((i % MTL_RQDCM_Q_PER_REG) && (i != pdata->rx_q_count))
continue;
XGMAC_IOWRITE(pdata, reg, reg_val);
@@ -1508,7 +1889,7 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata)
{
unsigned int i;
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++) {
+ for (i = 0; i < pdata->rx_q_count; i++) {
/* Activate flow control when less than 4k left in fifo */
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2);
@@ -1520,6 +1901,13 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata)
static void xgbe_config_mac_address(struct xgbe_prv_data *pdata)
{
xgbe_set_mac_address(pdata, pdata->netdev->dev_addr);
+
+ /* Filtering is done using perfect filtering and hash filtering */
+ if (pdata->hw_feat.hash_table_size) {
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 1);
+ }
}
static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
@@ -1541,6 +1929,18 @@ static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata)
{
+ /* Indicate that VLAN Tx CTAGs come from context descriptors */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 0);
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, VLTI, 1);
+
+ /* Set the current VLAN Hash Table register value */
+ xgbe_update_vlan_hash_table(pdata);
+
+ if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+ xgbe_enable_rx_vlan_filtering(pdata);
+ else
+ xgbe_disable_rx_vlan_filtering(pdata);
+
if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
xgbe_enable_rx_vlan_stripping(pdata);
else
@@ -1881,7 +2281,7 @@ static void xgbe_enable_tx(struct xgbe_prv_data *pdata)
}
/* Enable each Tx queue */
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN,
MTL_Q_ENABLED);
@@ -1898,7 +2298,7 @@ static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
/* Disable each Tx queue */
- for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ for (i = 0; i < pdata->tx_q_count; i++)
XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, 0);
/* Disable each Tx DMA channel */
@@ -1927,7 +2327,7 @@ static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
/* Enable each Rx queue */
reg_val = 0;
- for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ for (i = 0; i < pdata->rx_q_count; i++)
reg_val |= (0x02 << (i << 1));
XGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val);
@@ -2061,9 +2461,7 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
* Initialize MTL related features
*/
xgbe_config_mtl_mode(pdata);
- xgbe_config_rx_queue_mapping(pdata);
- /*TODO: Program the priorities mapped to the Selected Traffic Classes
- in MTL_TC_Prty_Map0-3 registers */
+ xgbe_config_queue_mapping(pdata);
xgbe_config_tsf_mode(pdata, pdata->tx_sf_mode);
xgbe_config_rsf_mode(pdata, pdata->rx_sf_mode);
xgbe_config_tx_threshold(pdata, pdata->tx_threshold);
@@ -2071,15 +2469,13 @@ static int xgbe_init(struct xgbe_prv_data *pdata)
xgbe_config_tx_fifo_size(pdata);
xgbe_config_rx_fifo_size(pdata);
xgbe_config_flow_control_threshold(pdata);
- /*TODO: Queue to Traffic Class Mapping (Q2TCMAP) */
/*TODO: Error Packet and undersized good Packet forwarding enable
(FEP and FUP)
*/
+ xgbe_config_dcb_tc(pdata);
+ xgbe_config_dcb_pfc(pdata);
xgbe_enable_mtl_interrupts(pdata);
- /* Transmit Class Weight */
- XGMAC_IOWRITE_BITS(pdata, MTL_Q_TCQWR, QW, 0x10);
-
/*
* Initialize MAC related features
*/
@@ -2104,7 +2500,7 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
hw_if->set_promiscuous_mode = xgbe_set_promiscuous_mode;
hw_if->set_all_multicast_mode = xgbe_set_all_multicast_mode;
- hw_if->set_addn_mac_addrs = xgbe_set_addn_mac_addrs;
+ hw_if->add_mac_addresses = xgbe_add_mac_addresses;
hw_if->set_mac_address = xgbe_set_mac_address;
hw_if->enable_rx_csum = xgbe_enable_rx_csum;
@@ -2112,6 +2508,9 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
hw_if->enable_rx_vlan_stripping = xgbe_enable_rx_vlan_stripping;
hw_if->disable_rx_vlan_stripping = xgbe_disable_rx_vlan_stripping;
+ hw_if->enable_rx_vlan_filtering = xgbe_enable_rx_vlan_filtering;
+ hw_if->disable_rx_vlan_filtering = xgbe_disable_rx_vlan_filtering;
+ hw_if->update_vlan_hash_table = xgbe_update_vlan_hash_table;
hw_if->read_mmd_regs = xgbe_read_mmd_regs;
hw_if->write_mmd_regs = xgbe_write_mmd_regs;
@@ -2178,5 +2577,16 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
hw_if->rx_mmc_int = xgbe_rx_mmc_int;
hw_if->read_mmc_stats = xgbe_read_mmc_stats;
+ /* For PTP config */
+ hw_if->config_tstamp = xgbe_config_tstamp;
+ hw_if->update_tstamp_addend = xgbe_update_tstamp_addend;
+ hw_if->set_tstamp_time = xgbe_set_tstamp_time;
+ hw_if->get_tstamp_time = xgbe_get_tstamp_time;
+ hw_if->get_tx_tstamp = xgbe_get_tx_tstamp;
+
+ /* For Data Center Bridging config */
+ hw_if->config_dcb_tc = xgbe_config_dcb_tc;
+ hw_if->config_dcb_pfc = xgbe_config_dcb_pfc;
+
DBGPR("<--xgbe_init_function_ptrs\n");
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index cfe3d93b5f52..1f5487f4888c 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -121,6 +121,8 @@
#include <net/busy_poll.h>
#include <linux/clk.h>
#include <linux/if_ether.h>
+#include <linux/net_tstamp.h>
+#include <linux/phy.h>
#include "xgbe.h"
#include "xgbe-common.h"
@@ -144,9 +146,10 @@ static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu)
}
rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
- if (rx_buf_size < RX_MIN_BUF_SIZE)
- rx_buf_size = RX_MIN_BUF_SIZE;
- rx_buf_size = (rx_buf_size + RX_BUF_ALIGN - 1) & ~(RX_BUF_ALIGN - 1);
+ if (rx_buf_size < XGBE_RX_MIN_BUF_SIZE)
+ rx_buf_size = XGBE_RX_MIN_BUF_SIZE;
+ rx_buf_size = (rx_buf_size + XGBE_RX_BUF_ALIGN - 1) &
+ ~(XGBE_RX_BUF_ALIGN - 1);
return rx_buf_size;
}
@@ -155,16 +158,21 @@ static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata)
{
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_channel *channel;
+ enum xgbe_int int_id;
unsigned int i;
channel = pdata->channel;
for (i = 0; i < pdata->channel_count; i++, channel++) {
- if (channel->tx_ring)
- hw_if->enable_int(channel,
- XGMAC_INT_DMA_CH_SR_TI);
- if (channel->rx_ring)
- hw_if->enable_int(channel,
- XGMAC_INT_DMA_CH_SR_RI);
+ if (channel->tx_ring && channel->rx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_TI_RI;
+ else if (channel->tx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_TI;
+ else if (channel->rx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_RI;
+ else
+ continue;
+
+ hw_if->enable_int(channel, int_id);
}
}
@@ -172,16 +180,21 @@ static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata)
{
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_channel *channel;
+ enum xgbe_int int_id;
unsigned int i;
channel = pdata->channel;
for (i = 0; i < pdata->channel_count; i++, channel++) {
- if (channel->tx_ring)
- hw_if->disable_int(channel,
- XGMAC_INT_DMA_CH_SR_TI);
- if (channel->rx_ring)
- hw_if->disable_int(channel,
- XGMAC_INT_DMA_CH_SR_RI);
+ if (channel->tx_ring && channel->rx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_TI_RI;
+ else if (channel->tx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_TI;
+ else if (channel->rx_ring)
+ int_id = XGMAC_INT_DMA_CH_SR_RI;
+ else
+ continue;
+
+ hw_if->disable_int(channel, int_id);
}
}
@@ -191,7 +204,7 @@ static irqreturn_t xgbe_isr(int irq, void *data)
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_channel *channel;
unsigned int dma_isr, dma_ch_isr;
- unsigned int mac_isr;
+ unsigned int mac_isr, mac_tssr;
unsigned int i;
/* The DMA interrupt status register also reports MAC and MTL
@@ -244,6 +257,17 @@ static irqreturn_t xgbe_isr(int irq, void *data)
if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS))
hw_if->rx_mmc_int(pdata);
+
+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) {
+ mac_tssr = XGMAC_IOREAD(pdata, MAC_TSSR);
+
+ if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) {
+ /* Read Tx Timestamp to clear interrupt */
+ pdata->tx_tstamp =
+ hw_if->get_tx_tstamp(pdata);
+ schedule_work(&pdata->tx_tstamp_work);
+ }
+ }
}
DBGPR(" DMA_ISR = %08x\n", XGMAC_IOREAD(pdata, DMA_ISR));
@@ -364,6 +388,7 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
+ hw_feat->tc_cnt = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
hw_feat->hash_table_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
HASHTBLSZ);
hw_feat->l3l4_filter_num = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
@@ -377,6 +402,21 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM);
+ /* Translate the Hash Table size into actual number */
+ switch (hw_feat->hash_table_size) {
+ case 0:
+ break;
+ case 1:
+ hw_feat->hash_table_size = 64;
+ break;
+ case 2:
+ hw_feat->hash_table_size = 128;
+ break;
+ case 3:
+ hw_feat->hash_table_size = 256;
+ break;
+ }
+
/* The Queue and Channel counts are zero based so increment them
* to get the actual number
*/
@@ -396,9 +436,12 @@ static void xgbe_napi_enable(struct xgbe_prv_data *pdata, unsigned int add)
napi_enable(&pdata->napi);
}
-static void xgbe_napi_disable(struct xgbe_prv_data *pdata)
+static void xgbe_napi_disable(struct xgbe_prv_data *pdata, unsigned int del)
{
napi_disable(&pdata->napi);
+
+ if (del)
+ netif_napi_del(&pdata->napi);
}
void xgbe_init_tx_coalesce(struct xgbe_prv_data *pdata)
@@ -446,7 +489,7 @@ static void xgbe_free_tx_skbuff(struct xgbe_prv_data *pdata)
break;
for (j = 0; j < ring->rdesc_count; j++) {
- rdata = GET_DESC_DATA(ring, j);
+ rdata = XGBE_GET_DESC_DATA(ring, j);
desc_if->unmap_skb(pdata, rdata);
}
}
@@ -471,7 +514,7 @@ static void xgbe_free_rx_skbuff(struct xgbe_prv_data *pdata)
break;
for (j = 0; j < ring->rdesc_count; j++) {
- rdata = GET_DESC_DATA(ring, j);
+ rdata = XGBE_GET_DESC_DATA(ring, j);
desc_if->unmap_skb(pdata, rdata);
}
}
@@ -479,6 +522,114 @@ static void xgbe_free_rx_skbuff(struct xgbe_prv_data *pdata)
DBGPR("<--xgbe_free_rx_skbuff\n");
}
+static void xgbe_adjust_link(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct phy_device *phydev = pdata->phydev;
+ int new_state = 0;
+
+ if (phydev == NULL)
+ return;
+
+ if (phydev->link) {
+ /* Flow control support */
+ if (pdata->pause_autoneg) {
+ if (phydev->pause || phydev->asym_pause) {
+ pdata->tx_pause = 1;
+ pdata->rx_pause = 1;
+ } else {
+ pdata->tx_pause = 0;
+ pdata->rx_pause = 0;
+ }
+ }
+
+ if (pdata->tx_pause != pdata->phy_tx_pause) {
+ hw_if->config_tx_flow_control(pdata);
+ pdata->phy_tx_pause = pdata->tx_pause;
+ }
+
+ if (pdata->rx_pause != pdata->phy_rx_pause) {
+ hw_if->config_rx_flow_control(pdata);
+ pdata->phy_rx_pause = pdata->rx_pause;
+ }
+
+ /* Speed support */
+ if (phydev->speed != pdata->phy_speed) {
+ new_state = 1;
+
+ switch (phydev->speed) {
+ case SPEED_10000:
+ hw_if->set_xgmii_speed(pdata);
+ break;
+
+ case SPEED_2500:
+ hw_if->set_gmii_2500_speed(pdata);
+ break;
+
+ case SPEED_1000:
+ hw_if->set_gmii_speed(pdata);
+ break;
+ }
+ pdata->phy_speed = phydev->speed;
+ }
+
+ if (phydev->link != pdata->phy_link) {
+ new_state = 1;
+ pdata->phy_link = 1;
+ }
+ } else if (pdata->phy_link) {
+ new_state = 1;
+ pdata->phy_link = 0;
+ pdata->phy_speed = SPEED_UNKNOWN;
+ }
+
+ if (new_state)
+ phy_print_status(phydev);
+}
+
+static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+{
+ struct net_device *netdev = pdata->netdev;
+ struct phy_device *phydev = pdata->phydev;
+ int ret;
+
+ pdata->phy_link = -1;
+ pdata->phy_speed = SPEED_UNKNOWN;
+ pdata->phy_tx_pause = pdata->tx_pause;
+ pdata->phy_rx_pause = pdata->rx_pause;
+
+ ret = phy_connect_direct(netdev, phydev, &xgbe_adjust_link,
+ pdata->phy_mode);
+ if (ret) {
+ netdev_err(netdev, "phy_connect_direct failed\n");
+ return ret;
+ }
+
+ if (!phydev->drv || (phydev->drv->phy_id == 0)) {
+ netdev_err(netdev, "phy_id not valid\n");
+ ret = -ENODEV;
+ goto err_phy_connect;
+ }
+ DBGPR(" phy_connect_direct succeeded for PHY %s, link=%d\n",
+ dev_name(&phydev->dev), phydev->link);
+
+ return 0;
+
+err_phy_connect:
+ phy_disconnect(phydev);
+
+ return ret;
+}
+
+static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
+{
+ if (!pdata->phydev)
+ return;
+
+ phy_disconnect(pdata->phydev);
+}
+
int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
@@ -502,7 +653,7 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
netif_device_detach(netdev);
netif_tx_stop_all_queues(netdev);
- xgbe_napi_disable(pdata);
+ xgbe_napi_disable(pdata, 0);
/* Powerdown Tx/Rx */
hw_if->powerdown_tx(pdata);
@@ -591,7 +742,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
phy_stop(pdata->phydev);
netif_tx_stop_all_queues(netdev);
- xgbe_napi_disable(pdata);
+ xgbe_napi_disable(pdata, 1);
xgbe_stop_tx_timers(pdata);
@@ -639,6 +790,197 @@ static void xgbe_restart(struct work_struct *work)
rtnl_unlock();
}
+static void xgbe_tx_tstamp(struct work_struct *work)
+{
+ struct xgbe_prv_data *pdata = container_of(work,
+ struct xgbe_prv_data,
+ tx_tstamp_work);
+ struct skb_shared_hwtstamps hwtstamps;
+ u64 nsec;
+ unsigned long flags;
+
+ if (pdata->tx_tstamp) {
+ nsec = timecounter_cyc2time(&pdata->tstamp_tc,
+ pdata->tx_tstamp);
+
+ memset(&hwtstamps, 0, sizeof(hwtstamps));
+ hwtstamps.hwtstamp = ns_to_ktime(nsec);
+ skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
+ }
+
+ dev_kfree_skb_any(pdata->tx_tstamp_skb);
+
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+ pdata->tx_tstamp_skb = NULL;
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+}
+
+static int xgbe_get_hwtstamp_settings(struct xgbe_prv_data *pdata,
+ struct ifreq *ifreq)
+{
+ if (copy_to_user(ifreq->ifr_data, &pdata->tstamp_config,
+ sizeof(pdata->tstamp_config)))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int xgbe_set_hwtstamp_settings(struct xgbe_prv_data *pdata,
+ struct ifreq *ifreq)
+{
+ struct hwtstamp_config config;
+ unsigned int mac_tscr;
+
+ if (copy_from_user(&config, ifreq->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ if (config.flags)
+ return -EINVAL;
+
+ mac_tscr = 0;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ break;
+
+ case HWTSTAMP_TX_ON:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ break;
+
+ case HWTSTAMP_FILTER_ALL:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2, UDP, any kind of event packet */
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ /* PTP v1, UDP, any kind of event packet */
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2, UDP, Sync packet */
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ /* PTP v1, UDP, Sync packet */
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2, UDP, Delay_req packet */
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ /* PTP v1, UDP, Delay_req packet */
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* 802.AS1, Ethernet, any kind of event packet */
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* 802.AS1, Ethernet, Sync packet */
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* 802.AS1, Ethernet, Delay_req packet */
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2/802.AS1, any layer, any kind of event packet */
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2/802.AS1, any layer, Sync packet */
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ /* PTP v2/802.AS1, any layer, Delay_req packet */
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
+ XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
+ break;
+
+ default:
+ return -ERANGE;
+ }
+
+ pdata->hw_if.config_tstamp(pdata, mac_tscr);
+
+ memcpy(&pdata->tstamp_config, &config, sizeof(config));
+
+ return 0;
+}
+
+static void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
+ struct sk_buff *skb,
+ struct xgbe_packet_data *packet)
+{
+ unsigned long flags;
+
+ if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) {
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+ if (pdata->tx_tstamp_skb) {
+ /* Another timestamp in progress, ignore this one */
+ XGMAC_SET_BITS(packet->attributes,
+ TX_PACKET_ATTRIBUTES, PTP, 0);
+ } else {
+ pdata->tx_tstamp_skb = skb_get(skb);
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ }
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+ }
+
+ if (!XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP))
+ skb_tx_timestamp(skb);
+}
+
static void xgbe_prep_vlan(struct sk_buff *skb, struct xgbe_packet_data *packet)
{
if (vlan_tx_tag_present(skb))
@@ -682,7 +1024,8 @@ static int xgbe_is_tso(struct sk_buff *skb)
return 1;
}
-static void xgbe_packet_info(struct xgbe_ring *ring, struct sk_buff *skb,
+static void xgbe_packet_info(struct xgbe_prv_data *pdata,
+ struct xgbe_ring *ring, struct sk_buff *skb,
struct xgbe_packet_data *packet)
{
struct skb_frag_struct *frag;
@@ -724,16 +1067,21 @@ static void xgbe_packet_info(struct xgbe_ring *ring, struct sk_buff *skb,
VLAN_CTAG, 1);
}
+ if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+ (pdata->tstamp_config.tx_type == HWTSTAMP_TX_ON))
+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ PTP, 1);
+
for (len = skb_headlen(skb); len;) {
packet->rdesc_count++;
- len -= min_t(unsigned int, len, TX_MAX_BUF_SIZE);
+ len -= min_t(unsigned int, len, XGBE_TX_MAX_BUF_SIZE);
}
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i];
for (len = skb_frag_size(frag); len; ) {
packet->rdesc_count++;
- len -= min_t(unsigned int, len, TX_MAX_BUF_SIZE);
+ len -= min_t(unsigned int, len, XGBE_TX_MAX_BUF_SIZE);
}
}
}
@@ -747,26 +1095,38 @@ static int xgbe_open(struct net_device *netdev)
DBGPR("-->xgbe_open\n");
- /* Enable the clock */
- ret = clk_prepare_enable(pdata->sysclock);
- if (ret) {
- netdev_alert(netdev, "clk_prepare_enable failed\n");
+ /* Initialize the phy */
+ ret = xgbe_phy_init(pdata);
+ if (ret)
return ret;
+
+ /* Enable the clocks */
+ ret = clk_prepare_enable(pdata->sysclk);
+ if (ret) {
+ netdev_alert(netdev, "dma clk_prepare_enable failed\n");
+ goto err_phy_init;
+ }
+
+ ret = clk_prepare_enable(pdata->ptpclk);
+ if (ret) {
+ netdev_alert(netdev, "ptp clk_prepare_enable failed\n");
+ goto err_sysclk;
}
/* Calculate the Rx buffer size before allocating rings */
ret = xgbe_calc_rx_buf_size(netdev, netdev->mtu);
if (ret < 0)
- goto err_clk;
+ goto err_ptpclk;
pdata->rx_buf_size = ret;
/* Allocate the ring descriptors and buffers */
ret = desc_if->alloc_ring_resources(pdata);
if (ret)
- goto err_clk;
+ goto err_ptpclk;
- /* Initialize the device restart work struct */
+ /* Initialize the device restart and Tx timestamp work struct */
INIT_WORK(&pdata->restart_work, xgbe_restart);
+ INIT_WORK(&pdata->tx_tstamp_work, xgbe_tx_tstamp);
/* Request interrupts */
ret = devm_request_irq(pdata->dev, netdev->irq, xgbe_isr, 0,
@@ -795,8 +1155,14 @@ err_start:
err_irq:
desc_if->free_ring_resources(pdata);
-err_clk:
- clk_disable_unprepare(pdata->sysclock);
+err_ptpclk:
+ clk_disable_unprepare(pdata->ptpclk);
+
+err_sysclk:
+ clk_disable_unprepare(pdata->sysclk);
+
+err_phy_init:
+ xgbe_phy_exit(pdata);
return ret;
}
@@ -824,8 +1190,12 @@ static int xgbe_close(struct net_device *netdev)
pdata->irq_number = 0;
}
- /* Disable the clock */
- clk_disable_unprepare(pdata->sysclock);
+ /* Disable the clocks */
+ clk_disable_unprepare(pdata->ptpclk);
+ clk_disable_unprepare(pdata->sysclk);
+
+ /* Release the phy */
+ xgbe_phy_exit(pdata);
DBGPR("<--xgbe_close\n");
@@ -861,7 +1231,7 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
/* Calculate preliminary packet info */
memset(packet, 0, sizeof(*packet));
- xgbe_packet_info(ring, skb, packet);
+ xgbe_packet_info(pdata, ring, skb, packet);
/* Check that there are enough descriptors available */
if (packet->rdesc_count > xgbe_tx_avail_desc(ring)) {
@@ -885,6 +1255,8 @@ static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
goto tx_netdev_return;
}
+ xgbe_prep_tx_tstamp(pdata, skb, packet);
+
/* Configure required descriptor fields for transmission */
hw_if->pre_xmit(channel);
@@ -911,18 +1283,10 @@ static void xgbe_set_rx_mode(struct net_device *netdev)
pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
- if (netdev_uc_count(netdev) > pdata->hw_feat.addn_mac)
- pr_mode = 1;
- if (netdev_mc_count(netdev) > pdata->hw_feat.addn_mac)
- am_mode = 1;
- if ((netdev_uc_count(netdev) + netdev_mc_count(netdev)) >
- pdata->hw_feat.addn_mac)
- pr_mode = 1;
-
hw_if->set_promiscuous_mode(pdata, pr_mode);
hw_if->set_all_multicast_mode(pdata, am_mode);
- if (!pr_mode)
- hw_if->set_addn_mac_addrs(pdata, am_mode);
+
+ hw_if->add_mac_addresses(pdata);
DBGPR("<--xgbe_set_rx_mode\n");
}
@@ -947,6 +1311,27 @@ static int xgbe_set_mac_address(struct net_device *netdev, void *addr)
return 0;
}
+static int xgbe_ioctl(struct net_device *netdev, struct ifreq *ifreq, int cmd)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ int ret;
+
+ switch (cmd) {
+ case SIOCGHWTSTAMP:
+ ret = xgbe_get_hwtstamp_settings(pdata, ifreq);
+ break;
+
+ case SIOCSHWTSTAMP:
+ ret = xgbe_set_hwtstamp_settings(pdata, ifreq);
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
static int xgbe_change_mtu(struct net_device *netdev, int mtu)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
@@ -999,6 +1384,38 @@ static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
return s;
}
+static int xgbe_vlan_rx_add_vid(struct net_device *netdev, __be16 proto,
+ u16 vid)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+
+ DBGPR("-->%s\n", __func__);
+
+ set_bit(vid, pdata->active_vlans);
+ hw_if->update_vlan_hash_table(pdata);
+
+ DBGPR("<--%s\n", __func__);
+
+ return 0;
+}
+
+static int xgbe_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto,
+ u16 vid)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+
+ DBGPR("-->%s\n", __func__);
+
+ clear_bit(vid, pdata->active_vlans);
+ hw_if->update_vlan_hash_table(pdata);
+
+ DBGPR("<--%s\n", __func__);
+
+ return 0;
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void xgbe_poll_controller(struct net_device *netdev)
{
@@ -1016,31 +1433,58 @@ static void xgbe_poll_controller(struct net_device *netdev)
}
#endif /* End CONFIG_NET_POLL_CONTROLLER */
+static int xgbe_setup_tc(struct net_device *netdev, u8 tc)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ unsigned int offset, queue;
+ u8 i;
+
+ if (tc && (tc != pdata->hw_feat.tc_cnt))
+ return -EINVAL;
+
+ if (tc) {
+ netdev_set_num_tc(netdev, tc);
+ for (i = 0, queue = 0, offset = 0; i < tc; i++) {
+ while ((queue < pdata->tx_q_count) &&
+ (pdata->q2tc_map[queue] == i))
+ queue++;
+
+ DBGPR(" TC%u using TXq%u-%u\n", i, offset, queue - 1);
+ netdev_set_tc_queue(netdev, i, queue - offset, offset);
+ offset = queue;
+ }
+ } else {
+ netdev_reset_tc(netdev);
+ }
+
+ return 0;
+}
+
static int xgbe_set_features(struct net_device *netdev,
netdev_features_t features)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_hw_if *hw_if = &pdata->hw_if;
- unsigned int rxcsum_enabled, rxvlan_enabled;
+ unsigned int rxcsum, rxvlan, rxvlan_filter;
- rxcsum_enabled = !!(pdata->netdev_features & NETIF_F_RXCSUM);
- rxvlan_enabled = !!(pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX);
+ rxcsum = pdata->netdev_features & NETIF_F_RXCSUM;
+ rxvlan = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX;
+ rxvlan_filter = pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_FILTER;
- if ((features & NETIF_F_RXCSUM) && !rxcsum_enabled) {
+ if ((features & NETIF_F_RXCSUM) && !rxcsum)
hw_if->enable_rx_csum(pdata);
- netdev_alert(netdev, "state change - rxcsum enabled\n");
- } else if (!(features & NETIF_F_RXCSUM) && rxcsum_enabled) {
+ else if (!(features & NETIF_F_RXCSUM) && rxcsum)
hw_if->disable_rx_csum(pdata);
- netdev_alert(netdev, "state change - rxcsum disabled\n");
- }
- if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan_enabled) {
+ if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan)
hw_if->enable_rx_vlan_stripping(pdata);
- netdev_alert(netdev, "state change - rxvlan enabled\n");
- } else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) && rxvlan_enabled) {
+ else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) && rxvlan)
hw_if->disable_rx_vlan_stripping(pdata);
- netdev_alert(netdev, "state change - rxvlan disabled\n");
- }
+
+ if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) && !rxvlan_filter)
+ hw_if->enable_rx_vlan_filtering(pdata);
+ else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && rxvlan_filter)
+ hw_if->disable_rx_vlan_filtering(pdata);
pdata->netdev_features = features;
@@ -1056,11 +1500,15 @@ static const struct net_device_ops xgbe_netdev_ops = {
.ndo_set_rx_mode = xgbe_set_rx_mode,
.ndo_set_mac_address = xgbe_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = xgbe_ioctl,
.ndo_change_mtu = xgbe_change_mtu,
.ndo_get_stats64 = xgbe_get_stats64,
+ .ndo_vlan_rx_add_vid = xgbe_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = xgbe_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = xgbe_poll_controller,
#endif
+ .ndo_setup_tc = xgbe_setup_tc,
.ndo_set_features = xgbe_set_features,
};
@@ -1069,6 +1517,22 @@ struct net_device_ops *xgbe_get_netdev_ops(void)
return (struct net_device_ops *)&xgbe_netdev_ops;
}
+static void xgbe_rx_refresh(struct xgbe_channel *channel)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_ring *ring = channel->rx_ring;
+ struct xgbe_ring_data *rdata;
+
+ desc_if->realloc_skb(channel);
+
+ /* Update the Rx Tail Pointer Register with address of
+ * the last cleaned entry */
+ rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index - 1);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+}
+
static int xgbe_tx_poll(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
@@ -1089,8 +1553,9 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
spin_lock_irqsave(&ring->lock, flags);
- while ((processed < TX_DESC_MAX_PROC) && (ring->dirty < ring->cur)) {
- rdata = GET_DESC_DATA(ring, ring->dirty);
+ while ((processed < XGBE_TX_DESC_MAX_PROC) &&
+ (ring->dirty < ring->cur)) {
+ rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);
rdesc = rdata->rdesc;
if (!hw_if->tx_complete(rdesc))
@@ -1109,7 +1574,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
}
if ((ring->tx.queue_stopped == 1) &&
- (xgbe_tx_avail_desc(ring) > TX_DESC_MIN_FREE)) {
+ (xgbe_tx_avail_desc(ring) > XGBE_TX_DESC_MIN_FREE)) {
ring->tx.queue_stopped = 0;
netif_wake_subqueue(netdev, channel->queue_index);
}
@@ -1125,14 +1590,14 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
{
struct xgbe_prv_data *pdata = channel->pdata;
struct xgbe_hw_if *hw_if = &pdata->hw_if;
- struct xgbe_desc_if *desc_if = &pdata->desc_if;
struct xgbe_ring *ring = channel->rx_ring;
struct xgbe_ring_data *rdata;
struct xgbe_packet_data *packet;
struct net_device *netdev = pdata->netdev;
struct sk_buff *skb;
- unsigned int incomplete, error;
- unsigned int cur_len, put_len, max_len;
+ struct skb_shared_hwtstamps *hwtstamps;
+ unsigned int incomplete, error, context_next, context;
+ unsigned int len, put_len, max_len;
int received = 0;
DBGPR("-->xgbe_rx_poll: budget=%d\n", budget);
@@ -1141,18 +1606,32 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
if (!ring)
return 0;
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
packet = &ring->packet_data;
while (received < budget) {
DBGPR(" cur = %d\n", ring->cur);
- /* Clear the packet data information */
- memset(packet, 0, sizeof(*packet));
- skb = NULL;
- error = 0;
- cur_len = 0;
+ /* First time in loop see if we need to restore state */
+ if (!received && rdata->state_saved) {
+ incomplete = rdata->state.incomplete;
+ context_next = rdata->state.context_next;
+ skb = rdata->state.skb;
+ error = rdata->state.error;
+ len = rdata->state.len;
+ } else {
+ memset(packet, 0, sizeof(*packet));
+ incomplete = 0;
+ context_next = 0;
+ skb = NULL;
+ error = 0;
+ len = 0;
+ }
read_again:
- rdata = GET_DESC_DATA(ring, ring->cur);
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+
+ if (ring->dirty > (XGBE_RX_DESC_CNT >> 3))
+ xgbe_rx_refresh(channel);
if (hw_if->dev_read(channel))
break;
@@ -1168,9 +1647,15 @@ read_again:
incomplete = XGMAC_GET_BITS(packet->attributes,
RX_PACKET_ATTRIBUTES,
INCOMPLETE);
+ context_next = XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES,
+ CONTEXT_NEXT);
+ context = XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES,
+ CONTEXT);
/* Earlier error, just drain the remaining data */
- if (incomplete && error)
+ if ((incomplete || context_next) && error)
goto read_again;
if (error || packet->errors) {
@@ -1180,30 +1665,37 @@ read_again:
continue;
}
- put_len = rdata->len - cur_len;
- if (skb) {
- if (pskb_expand_head(skb, 0, put_len, GFP_ATOMIC)) {
- DBGPR("pskb_expand_head error\n");
- if (incomplete) {
- error = 1;
- goto read_again;
+ if (!context) {
+ put_len = rdata->len - len;
+ if (skb) {
+ if (pskb_expand_head(skb, 0, put_len,
+ GFP_ATOMIC)) {
+ DBGPR("pskb_expand_head error\n");
+ if (incomplete) {
+ error = 1;
+ goto read_again;
+ }
+
+ dev_kfree_skb(skb);
+ continue;
}
-
- dev_kfree_skb(skb);
- continue;
+ memcpy(skb_tail_pointer(skb), rdata->skb->data,
+ put_len);
+ } else {
+ skb = rdata->skb;
+ rdata->skb = NULL;
}
- memcpy(skb_tail_pointer(skb), rdata->skb->data,
- put_len);
- } else {
- skb = rdata->skb;
- rdata->skb = NULL;
+ skb_put(skb, put_len);
+ len += put_len;
}
- skb_put(skb, put_len);
- cur_len += put_len;
- if (incomplete)
+ if (incomplete || context_next)
goto read_again;
+ /* Stray Context Descriptor? */
+ if (!skb)
+ continue;
+
/* Be sure we don't exceed the configured MTU */
max_len = netdev->mtu + ETH_HLEN;
if (!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
@@ -1230,6 +1722,16 @@ read_again:
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
packet->vlan_ctag);
+ if (XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES, RX_TSTAMP)) {
+ u64 nsec;
+
+ nsec = timecounter_cyc2time(&pdata->tstamp_tc,
+ packet->rx_tstamp);
+ hwtstamps = skb_hwtstamps(skb);
+ hwtstamps->hwtstamp = ns_to_ktime(nsec);
+ }
+
skb->dev = netdev;
skb->protocol = eth_type_trans(skb, netdev);
skb_record_rx_queue(skb, channel->queue_index);
@@ -1239,14 +1741,15 @@ read_again:
napi_gro_receive(&pdata->napi, skb);
}
- if (received) {
- desc_if->realloc_skb(channel);
-
- /* Update the Rx Tail Pointer Register with address of
- * the last cleaned entry */
- rdata = GET_DESC_DATA(ring, ring->rx.realloc_index - 1);
- XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
- lower_32_bits(rdata->rdesc_dma));
+ /* Check if we need to save state before leaving */
+ if (received && (incomplete || context_next)) {
+ rdata = XGBE_GET_DESC_DATA(ring, ring->cur);
+ rdata->state_saved = 1;
+ rdata->state.incomplete = incomplete;
+ rdata->state.context_next = context_next;
+ rdata->state.skb = skb;
+ rdata->state.len = len;
+ rdata->state.error = error;
}
DBGPR("<--xgbe_rx_poll: received = %d\n", received);
@@ -1259,21 +1762,28 @@ static int xgbe_poll(struct napi_struct *napi, int budget)
struct xgbe_prv_data *pdata = container_of(napi, struct xgbe_prv_data,
napi);
struct xgbe_channel *channel;
- int processed;
+ int ring_budget;
+ int processed, last_processed;
unsigned int i;
DBGPR("-->xgbe_poll: budget=%d\n", budget);
- /* Cleanup Tx ring first */
- channel = pdata->channel;
- for (i = 0; i < pdata->channel_count; i++, channel++)
- xgbe_tx_poll(channel);
-
- /* Process Rx ring next */
processed = 0;
- channel = pdata->channel;
- for (i = 0; i < pdata->channel_count; i++, channel++)
- processed += xgbe_rx_poll(channel, budget - processed);
+ ring_budget = budget / pdata->rx_ring_count;
+ do {
+ last_processed = processed;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ /* Cleanup Tx ring first */
+ xgbe_tx_poll(channel);
+
+ /* Process Rx ring next */
+ if (ring_budget > (budget - processed))
+ ring_budget = budget - processed;
+ processed += xgbe_rx_poll(channel, ring_budget);
+ }
+ } while ((processed < budget) && (processed != last_processed));
/* If we processed everything, we are done */
if (processed < budget) {
@@ -1296,7 +1806,7 @@ void xgbe_dump_tx_desc(struct xgbe_ring *ring, unsigned int idx,
struct xgbe_ring_desc *rdesc;
while (count--) {
- rdata = GET_DESC_DATA(ring, idx);
+ rdata = XGBE_GET_DESC_DATA(ring, idx);
rdesc = rdata->rdesc;
DBGPR("TX_NORMAL_DESC[%d %s] = %08x:%08x:%08x:%08x\n", idx,
(flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
index 8909f2b51af1..a076aca138a1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
@@ -116,6 +116,7 @@
#include <linux/spinlock.h>
#include <linux/phy.h>
+#include <linux/net_tstamp.h>
#include "xgbe.h"
#include "xgbe-common.h"
@@ -289,13 +290,9 @@ static int xgbe_get_settings(struct net_device *netdev,
if (!pdata->phydev)
return -ENODEV;
- spin_lock_irq(&pdata->lock);
-
ret = phy_ethtool_gset(pdata->phydev, cmd);
cmd->transceiver = XCVR_EXTERNAL;
- spin_unlock_irq(&pdata->lock);
-
DBGPR("<--xgbe_get_settings\n");
return ret;
@@ -314,36 +311,32 @@ static int xgbe_set_settings(struct net_device *netdev,
if (!pdata->phydev)
return -ENODEV;
- spin_lock_irq(&pdata->lock);
-
speed = ethtool_cmd_speed(cmd);
- ret = -EINVAL;
if (cmd->phy_address != phydev->addr)
- goto unlock;
+ return -EINVAL;
if ((cmd->autoneg != AUTONEG_ENABLE) &&
(cmd->autoneg != AUTONEG_DISABLE))
- goto unlock;
+ return -EINVAL;
- if ((cmd->autoneg == AUTONEG_DISABLE) &&
- (((speed != SPEED_10000) && (speed != SPEED_1000)) ||
- (cmd->duplex != DUPLEX_FULL)))
- goto unlock;
+ if (cmd->autoneg == AUTONEG_DISABLE) {
+ switch (speed) {
+ case SPEED_10000:
+ case SPEED_2500:
+ case SPEED_1000:
+ break;
+ default:
+ return -EINVAL;
+ }
- if (cmd->autoneg == AUTONEG_ENABLE) {
- /* Clear settings needed to force speeds */
- phydev->supported &= ~SUPPORTED_1000baseT_Full;
- phydev->supported &= ~SUPPORTED_10000baseT_Full;
- } else {
- /* Add settings needed to force speed */
- phydev->supported |= SUPPORTED_1000baseT_Full;
- phydev->supported |= SUPPORTED_10000baseT_Full;
+ if (cmd->duplex != DUPLEX_FULL)
+ return -EINVAL;
}
cmd->advertising &= phydev->supported;
if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising)
- goto unlock;
+ return -EINVAL;
ret = 0;
phydev->autoneg = cmd->autoneg;
@@ -359,9 +352,6 @@ static int xgbe_set_settings(struct net_device *netdev,
if (netif_running(netdev))
ret = phy_start_aneg(phydev);
-unlock:
- spin_unlock_irq(&pdata->lock);
-
DBGPR("<--xgbe_set_settings\n");
return ret;
@@ -490,6 +480,39 @@ static int xgbe_set_coalesce(struct net_device *netdev,
return 0;
}
+static int xgbe_get_ts_info(struct net_device *netdev,
+ struct ethtool_ts_info *ts_info)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ ts_info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+
+ if (pdata->ptp_clock)
+ ts_info->phc_index = ptp_clock_index(pdata->ptp_clock);
+ else
+ ts_info->phc_index = -1;
+
+ ts_info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
+ ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_ALL);
+
+ return 0;
+}
+
static const struct ethtool_ops xgbe_ethtool_ops = {
.get_settings = xgbe_get_settings,
.set_settings = xgbe_set_settings,
@@ -502,6 +525,7 @@ static const struct ethtool_ops xgbe_ethtool_ops = {
.get_strings = xgbe_get_strings,
.get_ethtool_stats = xgbe_get_ethtool_stats,
.get_sset_count = xgbe_get_sset_count,
+ .get_ts_info = xgbe_get_ts_info,
};
struct ethtool_ops *xgbe_get_ethtool_ops(void)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
index c83584a26713..8aa6a9353f7b 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -245,18 +245,19 @@ static int xgbe_probe(struct platform_device *pdev)
spin_lock_init(&pdata->lock);
mutex_init(&pdata->xpcs_mutex);
+ spin_lock_init(&pdata->tstamp_lock);
/* Set and validate the number of descriptors for a ring */
- BUILD_BUG_ON_NOT_POWER_OF_2(TX_DESC_CNT);
- pdata->tx_desc_count = TX_DESC_CNT;
+ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT);
+ pdata->tx_desc_count = XGBE_TX_DESC_CNT;
if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
dev_err(dev, "tx descriptor count (%d) is not valid\n",
pdata->tx_desc_count);
ret = -EINVAL;
goto err_io;
}
- BUILD_BUG_ON_NOT_POWER_OF_2(RX_DESC_CNT);
- pdata->rx_desc_count = RX_DESC_CNT;
+ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT);
+ pdata->rx_desc_count = XGBE_RX_DESC_CNT;
if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
dev_err(dev, "rx descriptor count (%d) is not valid\n",
pdata->rx_desc_count);
@@ -265,10 +266,18 @@ static int xgbe_probe(struct platform_device *pdev)
}
/* Obtain the system clock setting */
- pdata->sysclock = devm_clk_get(dev, NULL);
- if (IS_ERR(pdata->sysclock)) {
- dev_err(dev, "devm_clk_get failed\n");
- ret = PTR_ERR(pdata->sysclock);
+ pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
+ if (IS_ERR(pdata->sysclk)) {
+ dev_err(dev, "dma devm_clk_get failed\n");
+ ret = PTR_ERR(pdata->sysclk);
+ goto err_io;
+ }
+
+ /* Obtain the PTP clock setting */
+ pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
+ if (IS_ERR(pdata->ptpclk)) {
+ dev_err(dev, "ptp devm_clk_get failed\n");
+ ret = PTR_ERR(pdata->ptpclk);
goto err_io;
}
@@ -294,8 +303,21 @@ static int xgbe_probe(struct platform_device *pdev)
/* Set the DMA mask */
if (!dev->dma_mask)
dev->dma_mask = &dev->coherent_dma_mask;
- *(dev->dma_mask) = DMA_BIT_MASK(40);
- dev->coherent_dma_mask = DMA_BIT_MASK(40);
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ if (ret) {
+ dev_err(dev, "dma_set_mask_and_coherent failed\n");
+ goto err_io;
+ }
+
+ if (of_property_read_bool(dev->of_node, "dma-coherent")) {
+ pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
+ pdata->arcache = XGBE_DMA_OS_ARCACHE;
+ pdata->awcache = XGBE_DMA_OS_AWCACHE;
+ } else {
+ pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
+ pdata->arcache = XGBE_DMA_SYS_ARCACHE;
+ pdata->awcache = XGBE_DMA_SYS_AWCACHE;
+ }
ret = platform_get_irq(pdev, 0);
if (ret < 0) {
@@ -336,10 +358,18 @@ static int xgbe_probe(struct platform_device *pdev)
/* Set default configuration data */
xgbe_default_config(pdata);
- /* Calculate the number of Tx and Rx rings to be created */
+ /* Calculate the number of Tx and Rx rings to be created
+ * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
+ * the number of Tx queues to the number of Tx channels
+ * enabled
+ * -Rx (DMA) Channels do not map 1-to-1 so use the actual
+ * number of Rx queues
+ */
pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(),
pdata->hw_feat.tx_ch_cnt);
- if (netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count)) {
+ pdata->tx_q_count = pdata->tx_ring_count;
+ ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
+ if (ret) {
dev_err(dev, "error setting real tx queue count\n");
goto err_io;
}
@@ -347,6 +377,7 @@ static int xgbe_probe(struct platform_device *pdev)
pdata->rx_ring_count = min_t(unsigned int,
netif_get_num_default_rss_queues(),
pdata->hw_feat.rx_ch_cnt);
+ pdata->rx_q_count = pdata->hw_feat.rx_q_cnt;
ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
if (ret) {
dev_err(dev, "error setting real rx queue count\n");
@@ -372,9 +403,12 @@ static int xgbe_probe(struct platform_device *pdev)
if (ret)
goto err_bus_id;
- /* Set network and ethtool operations */
+ /* Set device operations */
netdev->netdev_ops = xgbe_get_netdev_ops();
netdev->ethtool_ops = xgbe_get_ethtool_ops();
+#ifdef CONFIG_AMD_XGBE_DCB
+ netdev->dcbnl_ops = xgbe_get_dcbnl_ops();
+#endif
/* Set device features */
netdev->hw_features = NETIF_F_SG |
@@ -385,7 +419,8 @@ static int xgbe_probe(struct platform_device *pdev)
NETIF_F_TSO6 |
NETIF_F_GRO |
NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HW_VLAN_CTAG_TX;
+ NETIF_F_HW_VLAN_CTAG_TX |
+ NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->vlan_features |= NETIF_F_SG |
NETIF_F_IP_CSUM |
@@ -396,6 +431,8 @@ static int xgbe_probe(struct platform_device *pdev)
netdev->features |= netdev->hw_features;
pdata->netdev_features = netdev->features;
+ netdev->priv_flags |= IFF_UNICAST_FLT;
+
xgbe_init_rx_coalesce(pdata);
xgbe_init_tx_coalesce(pdata);
@@ -406,6 +443,8 @@ static int xgbe_probe(struct platform_device *pdev)
goto err_reg_netdev;
}
+ xgbe_ptp_register(pdata);
+
xgbe_debugfs_init(pdata);
netdev_notice(netdev, "net device enabled\n");
@@ -438,6 +477,8 @@ static int xgbe_remove(struct platform_device *pdev)
xgbe_debugfs_exit(pdata);
+ xgbe_ptp_unregister(pdata);
+
unregister_netdev(netdev);
xgbe_mdio_unregister(pdata);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
index ea7a5d6750ea..6d2221e023f4 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
@@ -116,7 +116,6 @@
#include <linux/module.h>
#include <linux/kmod.h>
-#include <linux/spinlock.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/of.h>
@@ -158,82 +157,6 @@ static int xgbe_mdio_write(struct mii_bus *mii, int prtad, int mmd_reg,
return 0;
}
-static void xgbe_adjust_link(struct net_device *netdev)
-{
- struct xgbe_prv_data *pdata = netdev_priv(netdev);
- struct xgbe_hw_if *hw_if = &pdata->hw_if;
- struct phy_device *phydev = pdata->phydev;
- unsigned long flags;
- int new_state = 0;
-
- if (phydev == NULL)
- return;
-
- DBGPR_MDIO("-->xgbe_adjust_link: address=%d, newlink=%d, curlink=%d\n",
- phydev->addr, phydev->link, pdata->phy_link);
-
- spin_lock_irqsave(&pdata->lock, flags);
-
- if (phydev->link) {
- /* Flow control support */
- if (pdata->pause_autoneg) {
- if (phydev->pause || phydev->asym_pause) {
- pdata->tx_pause = 1;
- pdata->rx_pause = 1;
- } else {
- pdata->tx_pause = 0;
- pdata->rx_pause = 0;
- }
- }
-
- if (pdata->tx_pause != pdata->phy_tx_pause) {
- hw_if->config_tx_flow_control(pdata);
- pdata->phy_tx_pause = pdata->tx_pause;
- }
-
- if (pdata->rx_pause != pdata->phy_rx_pause) {
- hw_if->config_rx_flow_control(pdata);
- pdata->phy_rx_pause = pdata->rx_pause;
- }
-
- /* Speed support */
- if (phydev->speed != pdata->phy_speed) {
- new_state = 1;
-
- switch (phydev->speed) {
- case SPEED_10000:
- hw_if->set_xgmii_speed(pdata);
- break;
-
- case SPEED_2500:
- hw_if->set_gmii_2500_speed(pdata);
- break;
-
- case SPEED_1000:
- hw_if->set_gmii_speed(pdata);
- break;
- }
- pdata->phy_speed = phydev->speed;
- }
-
- if (phydev->link != pdata->phy_link) {
- new_state = 1;
- pdata->phy_link = 1;
- }
- } else if (pdata->phy_link) {
- new_state = 1;
- pdata->phy_link = 0;
- pdata->phy_speed = SPEED_UNKNOWN;
- }
-
- if (new_state)
- phy_print_status(phydev);
-
- spin_unlock_irqrestore(&pdata->lock, flags);
-
- DBGPR_MDIO("<--xgbe_adjust_link\n");
-}
-
void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
{
struct device *dev = pdata->dev;
@@ -283,7 +206,6 @@ void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
int xgbe_mdio_register(struct xgbe_prv_data *pdata)
{
- struct net_device *netdev = pdata->netdev;
struct device_node *phy_node;
struct mii_bus *mii;
struct phy_device *phydev;
@@ -298,7 +220,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
return -EINVAL;
}
- /* Register with the MDIO bus */
mii = mdiobus_alloc();
if (mii == NULL) {
dev_err(pdata->dev, "mdiobus_alloc failed\n");
@@ -353,32 +274,8 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
pdata->mii = mii;
pdata->mdio_mmd = MDIO_MMD_PCS;
- pdata->phy_link = -1;
- pdata->phy_speed = SPEED_UNKNOWN;
- pdata->phy_tx_pause = pdata->tx_pause;
- pdata->phy_rx_pause = pdata->rx_pause;
-
- ret = phy_connect_direct(netdev, phydev, &xgbe_adjust_link,
- pdata->phy_mode);
- if (ret) {
- netdev_err(netdev, "phy_connect_direct failed\n");
- goto err_phy_device;
- }
-
- if (!phydev->drv || (phydev->drv->phy_id == 0)) {
- netdev_err(netdev, "phy_id not valid\n");
- ret = -ENODEV;
- goto err_phy_connect;
- }
- DBGPR(" phy_connect_direct succeeded for PHY %s, link=%d\n",
- dev_name(&phydev->dev), phydev->link);
-
phydev->autoneg = pdata->default_autoneg;
if (phydev->autoneg == AUTONEG_DISABLE) {
- /* Add settings needed to force speed */
- phydev->supported |= SUPPORTED_1000baseT_Full;
- phydev->supported |= SUPPORTED_10000baseT_Full;
-
phydev->speed = pdata->default_speed;
phydev->duplex = DUPLEX_FULL;
@@ -395,9 +292,6 @@ int xgbe_mdio_register(struct xgbe_prv_data *pdata)
return 0;
-err_phy_connect:
- phy_disconnect(phydev);
-
err_phy_device:
phy_device_free(phydev);
@@ -417,7 +311,6 @@ void xgbe_mdio_unregister(struct xgbe_prv_data *pdata)
{
DBGPR("-->xgbe_mdio_unregister\n");
- phy_disconnect(pdata->phydev);
pdata->phydev = NULL;
module_put(pdata->phy_module);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
new file mode 100644
index 000000000000..37e64cfa5718
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c
@@ -0,0 +1,285 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute 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 file 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 incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and 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.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * 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.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. 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 <COPYRIGHT HOLDER> 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.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and 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.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * 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/clk.h>
+#include <linux/clocksource.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/net_tstamp.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static cycle_t xgbe_cc_read(const struct cyclecounter *cc)
+{
+ struct xgbe_prv_data *pdata = container_of(cc,
+ struct xgbe_prv_data,
+ tstamp_cc);
+ u64 nsec;
+
+ nsec = pdata->hw_if.get_tstamp_time(pdata);
+
+ return nsec;
+}
+
+static int xgbe_adjfreq(struct ptp_clock_info *info, s32 delta)
+{
+ struct xgbe_prv_data *pdata = container_of(info,
+ struct xgbe_prv_data,
+ ptp_clock_info);
+ unsigned long flags;
+ u64 adjust;
+ u32 addend, diff;
+ unsigned int neg_adjust = 0;
+
+ if (delta < 0) {
+ neg_adjust = 1;
+ delta = -delta;
+ }
+
+ adjust = pdata->tstamp_addend;
+ adjust *= delta;
+ diff = div_u64(adjust, 1000000000UL);
+
+ addend = (neg_adjust) ? pdata->tstamp_addend - diff :
+ pdata->tstamp_addend + diff;
+
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+
+ pdata->hw_if.update_tstamp_addend(pdata, addend);
+
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+
+ return 0;
+}
+
+static int xgbe_adjtime(struct ptp_clock_info *info, s64 delta)
+{
+ struct xgbe_prv_data *pdata = container_of(info,
+ struct xgbe_prv_data,
+ ptp_clock_info);
+ unsigned long flags;
+ u64 nsec;
+
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+
+ nsec = timecounter_read(&pdata->tstamp_tc);
+
+ nsec += delta;
+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc, nsec);
+
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+
+ return 0;
+}
+
+static int xgbe_gettime(struct ptp_clock_info *info, struct timespec *ts)
+{
+ struct xgbe_prv_data *pdata = container_of(info,
+ struct xgbe_prv_data,
+ ptp_clock_info);
+ unsigned long flags;
+ u64 nsec;
+
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+
+ nsec = timecounter_read(&pdata->tstamp_tc);
+
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+
+ *ts = ns_to_timespec(nsec);
+
+ return 0;
+}
+
+static int xgbe_settime(struct ptp_clock_info *info, const struct timespec *ts)
+{
+ struct xgbe_prv_data *pdata = container_of(info,
+ struct xgbe_prv_data,
+ ptp_clock_info);
+ unsigned long flags;
+ u64 nsec;
+
+ nsec = timespec_to_ns(ts);
+
+ spin_lock_irqsave(&pdata->tstamp_lock, flags);
+
+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc, nsec);
+
+ spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
+
+ return 0;
+}
+
+static int xgbe_enable(struct ptp_clock_info *info,
+ struct ptp_clock_request *request, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+void xgbe_ptp_register(struct xgbe_prv_data *pdata)
+{
+ struct ptp_clock_info *info = &pdata->ptp_clock_info;
+ struct ptp_clock *clock;
+ struct cyclecounter *cc = &pdata->tstamp_cc;
+ u64 dividend;
+
+ snprintf(info->name, sizeof(info->name), "%s",
+ netdev_name(pdata->netdev));
+ info->owner = THIS_MODULE;
+ info->max_adj = clk_get_rate(pdata->ptpclk);
+ info->adjfreq = xgbe_adjfreq;
+ info->adjtime = xgbe_adjtime;
+ info->gettime = xgbe_gettime;
+ info->settime = xgbe_settime;
+ info->enable = xgbe_enable;
+
+ clock = ptp_clock_register(info, pdata->dev);
+ if (IS_ERR(clock)) {
+ dev_err(pdata->dev, "ptp_clock_register failed\n");
+ return;
+ }
+
+ pdata->ptp_clock = clock;
+
+ /* Calculate the addend:
+ * addend = 2^32 / (PTP ref clock / 50Mhz)
+ * = (2^32 * 50Mhz) / PTP ref clock
+ */
+ dividend = 50000000;
+ dividend <<= 32;
+ pdata->tstamp_addend = div_u64(dividend, clk_get_rate(pdata->ptpclk));
+
+ /* Setup the timecounter */
+ cc->read = xgbe_cc_read;
+ cc->mask = CLOCKSOURCE_MASK(64);
+ cc->mult = 1;
+ cc->shift = 0;
+
+ timecounter_init(&pdata->tstamp_tc, &pdata->tstamp_cc,
+ ktime_to_ns(ktime_get_real()));
+
+ /* Disable all timestamping to start */
+ XGMAC_IOWRITE(pdata, MAC_TCR, 0);
+ pdata->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
+ pdata->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+}
+
+void xgbe_ptp_unregister(struct xgbe_prv_data *pdata)
+{
+ if (pdata->ptp_clock)
+ ptp_clock_unregister(pdata->ptp_clock);
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index ab0627162c01..07bf70a82908 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -121,6 +121,12 @@
#include <linux/netdevice.h>
#include <linux/workqueue.h>
#include <linux/phy.h>
+#include <linux/if_vlan.h>
+#include <linux/bitops.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/clocksource.h>
+#include <linux/net_tstamp.h>
+#include <net/dcbnl.h>
#define XGBE_DRV_NAME "amd-xgbe"
@@ -128,22 +134,30 @@
#define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver"
/* Descriptor related defines */
-#define TX_DESC_CNT 512
-#define TX_DESC_MIN_FREE (TX_DESC_CNT >> 3)
-#define TX_DESC_MAX_PROC (TX_DESC_CNT >> 1)
-#define RX_DESC_CNT 512
+#define XGBE_TX_DESC_CNT 512
+#define XGBE_TX_DESC_MIN_FREE (XGBE_TX_DESC_CNT >> 3)
+#define XGBE_TX_DESC_MAX_PROC (XGBE_TX_DESC_CNT >> 1)
+#define XGBE_RX_DESC_CNT 512
-#define TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
+#define XGBE_TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
-#define RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
-#define RX_BUF_ALIGN 64
+#define XGBE_RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
+#define XGBE_RX_BUF_ALIGN 64
#define XGBE_MAX_DMA_CHANNELS 16
-#define DMA_ARDOMAIN_SETTING 0x2
-#define DMA_ARCACHE_SETTING 0xb
-#define DMA_AWDOMAIN_SETTING 0x2
-#define DMA_AWCACHE_SETTING 0x7
-#define DMA_INTERRUPT_MASK 0x31c7
+#define XGBE_MAX_QUEUES 16
+
+/* DMA cache settings - Outer sharable, write-back, write-allocate */
+#define XGBE_DMA_OS_AXDOMAIN 0x2
+#define XGBE_DMA_OS_ARCACHE 0xb
+#define XGBE_DMA_OS_AWCACHE 0xf
+
+/* DMA cache settings - System, no caches used */
+#define XGBE_DMA_SYS_AXDOMAIN 0x3
+#define XGBE_DMA_SYS_ARCACHE 0x0
+#define XGBE_DMA_SYS_AWCACHE 0x0
+
+#define XGBE_DMA_INTERRUPT_MASK 0x31c7
#define XGMAC_MIN_PACKET 60
#define XGMAC_STD_PACKET_MTU 1500
@@ -151,45 +165,53 @@
#define XGMAC_JUMBO_PACKET_MTU 9000
#define XGMAC_MAX_JUMBO_PACKET 9018
-#define MAX_MULTICAST_LIST 14
-#define TX_FLAGS_IP_PKT 0x00000001
-#define TX_FLAGS_TCP_PKT 0x00000002
-
/* MDIO bus phy name */
#define XGBE_PHY_NAME "amd_xgbe_phy"
#define XGBE_PRTAD 0
+/* Device-tree clock names */
+#define XGBE_DMA_CLOCK "dma_clk"
+#define XGBE_PTP_CLOCK "ptp_clk"
+
+/* Timestamp support - values based on 50MHz PTP clock
+ * 50MHz => 20 nsec
+ */
+#define XGBE_TSTAMP_SSINC 20
+#define XGBE_TSTAMP_SNSINC 0
+
/* Driver PMT macros */
#define XGMAC_DRIVER_CONTEXT 1
#define XGMAC_IOCTL_CONTEXT 2
-#define FIFO_SIZE_B(x) (x)
-#define FIFO_SIZE_KB(x) (x * 1024)
+#define XGBE_FIFO_SIZE_B(x) (x)
+#define XGBE_FIFO_SIZE_KB(x) (x * 1024)
-#define XGBE_TC_CNT 2
+#define XGBE_TC_MIN_QUANTUM 10
/* Helper macro for descriptor handling
- * Always use GET_DESC_DATA to access the descriptor data
+ * Always use XGBE_GET_DESC_DATA to access the descriptor data
* since the index is free-running and needs to be and-ed
* with the descriptor count value of the ring to index to
* the proper descriptor data.
*/
-#define GET_DESC_DATA(_ring, _idx) \
+#define XGBE_GET_DESC_DATA(_ring, _idx) \
((_ring)->rdata + \
((_idx) & ((_ring)->rdesc_count - 1)))
/* Default coalescing parameters */
-#define XGMAC_INIT_DMA_TX_USECS 100
-#define XGMAC_INIT_DMA_TX_FRAMES 16
+#define XGMAC_INIT_DMA_TX_USECS 50
+#define XGMAC_INIT_DMA_TX_FRAMES 25
#define XGMAC_MAX_DMA_RIWT 0xff
-#define XGMAC_INIT_DMA_RX_USECS 100
-#define XGMAC_INIT_DMA_RX_FRAMES 16
+#define XGMAC_INIT_DMA_RX_USECS 30
+#define XGMAC_INIT_DMA_RX_FRAMES 25
/* Flow control queue count */
#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8
+/* Maximum MAC address hash table size (256 bits = 8 bytes) */
+#define XGBE_MAC_HASH_TABLE_SIZE 8
struct xgbe_prv_data;
@@ -207,6 +229,8 @@ struct xgbe_packet_data {
unsigned short mss;
unsigned short vlan_ctag;
+
+ u64 rx_tstamp;
};
/* Common Rx and Tx descriptor mapping */
@@ -219,7 +243,7 @@ struct xgbe_ring_desc {
/* Structure used to hold information related to the descriptor
* and the packet associated with the descriptor (always use
- * use the GET_DESC_DATA macro to access this data from the ring)
+ * use the XGBE_GET_DESC_DATA macro to access this data from the ring)
*/
struct xgbe_ring_data {
struct xgbe_ring_desc *rdesc; /* Virtual address of descriptor */
@@ -235,6 +259,20 @@ struct xgbe_ring_data {
unsigned int interrupt; /* Interrupt indicator */
unsigned int mapped_as_page;
+
+ /* Incomplete receive save location. If the budget is exhausted
+ * or the last descriptor (last normal descriptor or a following
+ * context descriptor) has not been DMA'd yet the current state
+ * of the receive processing needs to be saved.
+ */
+ unsigned int state_saved;
+ struct {
+ unsigned int incomplete;
+ unsigned int context_next;
+ struct sk_buff *skb;
+ unsigned int len;
+ unsigned int error;
+ } state;
};
struct xgbe_ring {
@@ -250,7 +288,7 @@ struct xgbe_ring {
unsigned int rdesc_count;
/* Array of descriptor data corresponding the descriptor memory
- * (always use the GET_DESC_DATA macro to access this data)
+ * (always use the XGBE_GET_DESC_DATA macro to access this data)
*/
struct xgbe_ring_data *rdata;
@@ -304,13 +342,13 @@ struct xgbe_channel {
} ____cacheline_aligned;
enum xgbe_int {
- XGMAC_INT_DMA_ISR_DC0IS,
XGMAC_INT_DMA_CH_SR_TI,
XGMAC_INT_DMA_CH_SR_TPS,
XGMAC_INT_DMA_CH_SR_TBU,
XGMAC_INT_DMA_CH_SR_RI,
XGMAC_INT_DMA_CH_SR_RBU,
XGMAC_INT_DMA_CH_SR_RPS,
+ XGMAC_INT_DMA_CH_SR_TI_RI,
XGMAC_INT_DMA_CH_SR_FBE,
XGMAC_INT_DMA_ALL,
};
@@ -386,7 +424,7 @@ struct xgbe_hw_if {
int (*set_promiscuous_mode)(struct xgbe_prv_data *, unsigned int);
int (*set_all_multicast_mode)(struct xgbe_prv_data *, unsigned int);
- int (*set_addn_mac_addrs)(struct xgbe_prv_data *, unsigned int);
+ int (*add_mac_addresses)(struct xgbe_prv_data *);
int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr);
int (*enable_rx_csum)(struct xgbe_prv_data *);
@@ -394,6 +432,9 @@ struct xgbe_hw_if {
int (*enable_rx_vlan_stripping)(struct xgbe_prv_data *);
int (*disable_rx_vlan_stripping)(struct xgbe_prv_data *);
+ int (*enable_rx_vlan_filtering)(struct xgbe_prv_data *);
+ int (*disable_rx_vlan_filtering)(struct xgbe_prv_data *);
+ int (*update_vlan_hash_table)(struct xgbe_prv_data *);
int (*read_mmd_regs)(struct xgbe_prv_data *, int, int);
void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int);
@@ -457,6 +498,18 @@ struct xgbe_hw_if {
void (*rx_mmc_int)(struct xgbe_prv_data *);
void (*tx_mmc_int)(struct xgbe_prv_data *);
void (*read_mmc_stats)(struct xgbe_prv_data *);
+
+ /* For Timestamp config */
+ int (*config_tstamp)(struct xgbe_prv_data *, unsigned int);
+ void (*update_tstamp_addend)(struct xgbe_prv_data *, unsigned int);
+ void (*set_tstamp_time)(struct xgbe_prv_data *, unsigned int sec,
+ unsigned int nsec);
+ u64 (*get_tstamp_time)(struct xgbe_prv_data *);
+ u64 (*get_tx_tstamp)(struct xgbe_prv_data *);
+
+ /* For Data Center Bridging config */
+ void (*config_dcb_tc)(struct xgbe_prv_data *);
+ void (*config_dcb_pfc)(struct xgbe_prv_data *);
};
struct xgbe_desc_if {
@@ -498,6 +551,7 @@ struct xgbe_hw_features {
unsigned int tso; /* TCP Segmentation Offload */
unsigned int dma_debug; /* DMA Debug Registers */
unsigned int rss; /* Receive Side Scaling */
+ unsigned int tc_cnt; /* Number of Traffic Classes */
unsigned int hash_table_size; /* Hash Table Size */
unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
@@ -530,6 +584,11 @@ struct xgbe_prv_data {
struct xgbe_hw_if hw_if;
struct xgbe_desc_if desc_if;
+ /* AXI DMA settings */
+ unsigned int axdomain;
+ unsigned int arcache;
+ unsigned int awcache;
+
/* Rings for Tx/Rx on a DMA channel */
struct xgbe_channel *channel;
unsigned int channel_count;
@@ -538,6 +597,9 @@ struct xgbe_prv_data {
unsigned int rx_ring_count;
unsigned int rx_desc_count;
+ unsigned int tx_q_count;
+ unsigned int rx_q_count;
+
/* Tx/Rx common settings */
unsigned int pblx8;
@@ -589,8 +651,30 @@ struct xgbe_prv_data {
struct napi_struct napi;
struct xgbe_mmc_stats mmc_stats;
- /* System clock value used for Rx watchdog */
- struct clk *sysclock;
+ /* Filtering support */
+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+
+ /* Device clocks */
+ struct clk *sysclk;
+ struct clk *ptpclk;
+
+ /* Timestamp support */
+ spinlock_t tstamp_lock;
+ struct ptp_clock_info ptp_clock_info;
+ struct ptp_clock *ptp_clock;
+ struct hwtstamp_config tstamp_config;
+ struct cyclecounter tstamp_cc;
+ struct timecounter tstamp_tc;
+ unsigned int tstamp_addend;
+ struct work_struct tx_tstamp_work;
+ struct sk_buff *tx_tstamp_skb;
+ u64 tx_tstamp;
+
+ /* DCB support */
+ struct ieee_ets *ets;
+ struct ieee_pfc *pfc;
+ unsigned int q2tc_map[XGBE_MAX_QUEUES];
+ unsigned int prio2q_map[IEEE_8021QAZ_MAX_TCS];
/* Hardware features of the device */
struct xgbe_hw_features hw_feat;
@@ -617,10 +701,15 @@ void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *);
void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *);
struct net_device_ops *xgbe_get_netdev_ops(void);
struct ethtool_ops *xgbe_get_ethtool_ops(void);
+#ifdef CONFIG_AMD_XGBE_DCB
+const struct dcbnl_rtnl_ops *xgbe_get_dcbnl_ops(void);
+#endif
int xgbe_mdio_register(struct xgbe_prv_data *);
void xgbe_mdio_unregister(struct xgbe_prv_data *);
void xgbe_dump_phy_registers(struct xgbe_prv_data *);
+void xgbe_ptp_register(struct xgbe_prv_data *);
+void xgbe_ptp_unregister(struct xgbe_prv_data *);
void xgbe_dump_tx_desc(struct xgbe_ring *, unsigned int, unsigned int,
unsigned int);
void xgbe_dump_rx_desc(struct xgbe_ring *, struct xgbe_ring_desc *,
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index 53f85bf71526..36cc9bd07c47 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -105,12 +105,10 @@ struct buffer_state {
/**
* struct arc_emac_priv - Storage of EMAC's private information.
* @dev: Pointer to the current device.
- * @ndev: Pointer to the current network device.
* @phy_dev: Pointer to attached PHY device.
* @bus: Pointer to the current MII bus.
* @regs: Base address of EMAC memory-mapped control registers.
* @napi: Structure for NAPI.
- * @stats: Network device statistics.
* @rxbd: Pointer to Rx BD ring.
* @txbd: Pointer to Tx BD ring.
* @rxbd_dma: DMA handle for Rx BD ring.
@@ -127,7 +125,6 @@ struct buffer_state {
struct arc_emac_priv {
/* Devices */
struct device *dev;
- struct net_device *ndev;
struct phy_device *phy_dev;
struct mii_bus *bus;
@@ -135,7 +132,6 @@ struct arc_emac_priv {
struct clk *clk;
struct napi_struct napi;
- struct net_device_stats stats;
struct arc_emac_bd *rxbd;
struct arc_emac_bd *txbd;
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 18e2faccebb0..fe5cfeace6e3 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -140,7 +140,7 @@ static const struct ethtool_ops arc_emac_ethtool_ops = {
static void arc_emac_tx_clean(struct net_device *ndev)
{
struct arc_emac_priv *priv = netdev_priv(ndev);
- struct net_device_stats *stats = &priv->stats;
+ struct net_device_stats *stats = &ndev->stats;
unsigned int i;
for (i = 0; i < TX_BD_NUM; i++) {
@@ -202,7 +202,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
for (work_done = 0; work_done < budget; work_done++) {
unsigned int *last_rx_bd = &priv->last_rx_bd;
- struct net_device_stats *stats = &priv->stats;
+ struct net_device_stats *stats = &ndev->stats;
struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd];
unsigned int pktlen, info = le32_to_cpu(rxbd->info);
@@ -318,7 +318,7 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
{
struct net_device *ndev = dev_instance;
struct arc_emac_priv *priv = netdev_priv(ndev);
- struct net_device_stats *stats = &priv->stats;
+ struct net_device_stats *stats = &ndev->stats;
unsigned int status;
status = arc_reg_get(priv, R_STATUS);
@@ -529,7 +529,7 @@ static int arc_emac_stop(struct net_device *ndev)
static struct net_device_stats *arc_emac_stats(struct net_device *ndev)
{
struct arc_emac_priv *priv = netdev_priv(ndev);
- struct net_device_stats *stats = &priv->stats;
+ struct net_device_stats *stats = &ndev->stats;
unsigned long miss, rxerr;
u8 rxcrc, rxfram, rxoflow;
@@ -565,7 +565,7 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
{
struct arc_emac_priv *priv = netdev_priv(ndev);
unsigned int len, *txbd_curr = &priv->txbd_curr;
- struct net_device_stats *stats = &priv->stats;
+ struct net_device_stats *stats = &ndev->stats;
__le32 *info = &priv->txbd[*txbd_curr].info;
dma_addr_t addr;
@@ -720,7 +720,6 @@ static int arc_emac_probe(struct platform_device *pdev)
priv = netdev_priv(ndev);
priv->dev = &pdev->dev;
- priv->ndev = ndev;
priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs);
if (IS_ERR(priv->regs)) {
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index 1cda49a28f7f..52fdfe225978 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -639,7 +639,6 @@ int atl1c_phy_init(struct atl1c_hw *hw)
dev_err(&pdev->dev, "Wrong Media type %d\n",
hw->media_type);
return -1;
- break;
}
ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
@@ -682,7 +681,6 @@ int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
break;
default:
return -1;
- break;
}
if (phy_data & GIGA_PSSR_DPLX)
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
index 923063d2e5bb..113565da155f 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
@@ -618,7 +618,6 @@ int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex)
break;
default:
return AT_ERR_PHY_SPEED;
- break;
}
if (phy_data & MII_AT001_PSSR_DPLX)
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index b460db7919a2..1546d550ac97 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -910,7 +910,6 @@ static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex
if (netif_msg_hw(adapter))
dev_dbg(&pdev->dev, "error getting speed\n");
return ATLX_ERR_PHY_SPEED;
- break;
}
if (phy_data & MII_ATLX_PSSR_DPLX)
*duplex = FULL_DUPLEX;
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index 6746bd717146..c194bc687c30 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -2493,7 +2493,6 @@ static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
break;
default:
return ATLX_ERR_PHY_SPEED;
- break;
}
if (phy_data & MII_ATLX_PSSR_DPLX)
@@ -2933,11 +2932,9 @@ static int atl2_validate_option(int *value, struct atl2_option *opt)
case OPTION_ENABLED:
printk(KERN_INFO "%s Enabled\n", opt->name);
return 0;
- break;
case OPTION_DISABLED:
printk(KERN_INFO "%s Disabled\n", opt->name);
return 0;
- break;
}
break;
case range_option:
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 3e488094b073..7dcfb19a31c8 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -72,23 +72,23 @@ config BCMGENET
Broadcom BCM7xxx Set Top Box family chipset.
config BNX2
- tristate "Broadcom NetXtremeII support"
+ tristate "QLogic NetXtremeII support"
depends on PCI
select CRC32
select FW_LOADER
---help---
- This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
+ This driver supports QLogic NetXtremeII gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bnx2. This is recommended.
config CNIC
- tristate "Broadcom CNIC support"
+ tristate "QLogic CNIC support"
depends on PCI
select BNX2
select UIO
---help---
- This driver supports offload features of Broadcom NetXtremeII
+ This driver supports offload features of QLogic NetXtremeII
gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 141160ef249a..6f4e18644bd4 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -81,14 +81,14 @@ static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
{
#ifdef CONFIG_PHYS_ADDR_T_64BIT
__raw_writel(upper_32_bits(addr) & DESC_ADDR_HI_MASK,
- d + DESC_ADDR_HI_STATUS_LEN);
+ d + DESC_ADDR_HI_STATUS_LEN);
#endif
__raw_writel(lower_32_bits(addr), d + DESC_ADDR_LO);
}
static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
- struct dma_desc *desc,
- unsigned int port)
+ struct dma_desc *desc,
+ unsigned int port)
{
/* Ports are latched, so write upper address first */
tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
@@ -108,7 +108,7 @@ static int bcm_sysport_set_settings(struct net_device *dev,
}
static int bcm_sysport_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
+ struct ethtool_cmd *cmd)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
@@ -119,14 +119,14 @@ static int bcm_sysport_get_settings(struct net_device *dev,
}
static int bcm_sysport_set_rx_csum(struct net_device *dev,
- netdev_features_t wanted)
+ netdev_features_t wanted)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
u32 reg;
- priv->rx_csum_en = !!(wanted & NETIF_F_RXCSUM);
+ priv->rx_chk_en = !!(wanted & NETIF_F_RXCSUM);
reg = rxchk_readl(priv, RXCHK_CONTROL);
- if (priv->rx_csum_en)
+ if (priv->rx_chk_en)
reg |= RXCHK_EN;
else
reg &= ~RXCHK_EN;
@@ -134,7 +134,7 @@ static int bcm_sysport_set_rx_csum(struct net_device *dev,
/* If UniMAC forwards CRC, we need to skip over it to get
* a valid CHK bit to be set in the per-packet status word
*/
- if (priv->rx_csum_en && priv->crc_fwd)
+ if (priv->rx_chk_en && priv->crc_fwd)
reg |= RXCHK_SKIP_FCS;
else
reg &= ~RXCHK_SKIP_FCS;
@@ -145,7 +145,7 @@ static int bcm_sysport_set_rx_csum(struct net_device *dev,
}
static int bcm_sysport_set_tx_csum(struct net_device *dev,
- netdev_features_t wanted)
+ netdev_features_t wanted)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
u32 reg;
@@ -165,7 +165,7 @@ static int bcm_sysport_set_tx_csum(struct net_device *dev,
}
static int bcm_sysport_set_features(struct net_device *dev,
- netdev_features_t features)
+ netdev_features_t features)
{
netdev_features_t changed = features ^ dev->features;
netdev_features_t wanted = dev->wanted_features;
@@ -261,7 +261,7 @@ static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = {
/* RXCHK misc statistics */
STAT_RXCHK("rxchk_bad_csum", mib.rxchk_bad_csum, RXCHK_BAD_CSUM_CNTR),
STAT_RXCHK("rxchk_other_pkt_disc", mib.rxchk_other_pkt_disc,
- RXCHK_OTHER_DISC_CNTR),
+ RXCHK_OTHER_DISC_CNTR),
/* RBUF misc statistics */
STAT_RBUF("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, RBUF_OVFL_DISC_CNTR),
STAT_RBUF("rbuf_err_cnt", mib.rbuf_err_cnt, RBUF_ERR_PKT_CNTR),
@@ -270,7 +270,7 @@ static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = {
#define BCM_SYSPORT_STATS_LEN ARRAY_SIZE(bcm_sysport_gstrings_stats)
static void bcm_sysport_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+ struct ethtool_drvinfo *info)
{
strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
strlcpy(info->version, "0.1", sizeof(info->version));
@@ -303,7 +303,7 @@ static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
}
static void bcm_sysport_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
+ u32 stringset, u8 *data)
{
int i;
@@ -311,8 +311,8 @@ static void bcm_sysport_get_strings(struct net_device *dev,
case ETH_SS_STATS:
for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
memcpy(data + i * ETH_GSTRING_LEN,
- bcm_sysport_gstrings_stats[i].stat_string,
- ETH_GSTRING_LEN);
+ bcm_sysport_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
}
break;
default:
@@ -362,7 +362,7 @@ static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
}
static void bcm_sysport_get_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
+ struct ethtool_stats *stats, u64 *data)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
int i;
@@ -384,6 +384,64 @@ static void bcm_sysport_get_stats(struct net_device *dev,
}
}
+static void bcm_sysport_get_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+ wol->wolopts = priv->wolopts;
+
+ if (!(priv->wolopts & WAKE_MAGICSECURE))
+ return;
+
+ /* Return the programmed SecureOn password */
+ reg = umac_readl(priv, UMAC_PSW_MS);
+ put_unaligned_be16(reg, &wol->sopass[0]);
+ reg = umac_readl(priv, UMAC_PSW_LS);
+ put_unaligned_be32(reg, &wol->sopass[2]);
+}
+
+static int bcm_sysport_set_wol(struct net_device *dev,
+ struct ethtool_wolinfo *wol)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
+ u32 supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+
+ if (!device_can_wakeup(kdev))
+ return -ENOTSUPP;
+
+ if (wol->wolopts & ~supported)
+ return -EINVAL;
+
+ /* Program the SecureOn password */
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ umac_writel(priv, get_unaligned_be16(&wol->sopass[0]),
+ UMAC_PSW_MS);
+ umac_writel(priv, get_unaligned_be32(&wol->sopass[2]),
+ UMAC_PSW_LS);
+ }
+
+ /* Flag the device and relevant IRQ as wakeup capable */
+ if (wol->wolopts) {
+ device_set_wakeup_enable(kdev, 1);
+ enable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = 0;
+ } else {
+ device_set_wakeup_enable(kdev, 0);
+ /* Avoid unbalanced disable_irq_wake calls */
+ if (!priv->wol_irq_disabled)
+ disable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = 1;
+ }
+
+ priv->wolopts = wol->wolopts;
+
+ return 0;
+}
+
static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
{
dev_kfree_skb_any(cb->skb);
@@ -406,7 +464,7 @@ static int bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
}
mapping = dma_map_single(kdev, cb->skb->data,
- RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
ret = dma_mapping_error(kdev, mapping);
if (ret) {
bcm_sysport_free_cb(cb);
@@ -470,22 +528,20 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
to_process = p_index - priv->rx_c_index;
netif_dbg(priv, rx_status, ndev,
- "p_index=%d rx_c_index=%d to_process=%d\n",
- p_index, priv->rx_c_index, to_process);
-
- while ((processed < to_process) &&
- (processed < budget)) {
+ "p_index=%d rx_c_index=%d to_process=%d\n",
+ p_index, priv->rx_c_index, to_process);
+ while ((processed < to_process) && (processed < budget)) {
cb = &priv->rx_cbs[priv->rx_read_ptr];
skb = cb->skb;
dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
- RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
/* Extract the Receive Status Block prepended */
rsb = (struct bcm_rsb *)skb->data;
len = (rsb->rx_status_len >> DESC_LEN_SHIFT) & DESC_LEN_MASK;
status = (rsb->rx_status_len >> DESC_STATUS_SHIFT) &
- DESC_STATUS_MASK;
+ DESC_STATUS_MASK;
processed++;
priv->rx_read_ptr++;
@@ -493,9 +549,9 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
priv->rx_read_ptr = 0;
netif_dbg(priv, rx_status, ndev,
- "p=%d, c=%d, rd_ptr=%d, len=%d, flag=0x%04x\n",
- p_index, priv->rx_c_index, priv->rx_read_ptr,
- len, status);
+ "p=%d, c=%d, rd_ptr=%d, len=%d, flag=0x%04x\n",
+ p_index, priv->rx_c_index, priv->rx_read_ptr,
+ len, status);
if (unlikely(!skb)) {
netif_err(priv, rx_err, ndev, "out of memory!\n");
@@ -554,9 +610,9 @@ refill:
}
static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_priv *priv,
- struct bcm_sysport_cb *cb,
- unsigned int *bytes_compl,
- unsigned int *pkts_compl)
+ struct bcm_sysport_cb *cb,
+ unsigned int *bytes_compl,
+ unsigned int *pkts_compl)
{
struct device *kdev = &priv->pdev->dev;
struct net_device *ndev = priv->netdev;
@@ -565,8 +621,8 @@ static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_priv *priv,
ndev->stats.tx_bytes += cb->skb->len;
*bytes_compl += cb->skb->len;
dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
- dma_unmap_len(cb, dma_len),
- DMA_TO_DEVICE);
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
ndev->stats.tx_packets++;
(*pkts_compl)++;
bcm_sysport_free_cb(cb);
@@ -574,7 +630,7 @@ static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_priv *priv,
} else if (dma_unmap_addr(cb, dma_addr)) {
ndev->stats.tx_bytes += dma_unmap_len(cb, dma_len);
dma_unmap_page(kdev, dma_unmap_addr(cb, dma_addr),
- dma_unmap_len(cb, dma_len), DMA_TO_DEVICE);
+ dma_unmap_len(cb, dma_len), DMA_TO_DEVICE);
dma_unmap_addr_set(cb, dma_addr, 0);
}
}
@@ -608,8 +664,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
last_tx_cn = num_tx_cbs - last_c_index + c_index;
netif_dbg(priv, tx_done, ndev,
- "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
- ring->index, c_index, last_tx_cn, last_c_index);
+ "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
+ ring->index, c_index, last_tx_cn, last_c_index);
while (last_tx_cn-- > 0) {
cb = ring->cbs + last_c_index;
@@ -626,8 +682,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
netif_tx_wake_queue(txq);
netif_dbg(priv, tx_done, ndev,
- "ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
- ring->index, ring->c_index, pkts_compl, bytes_compl);
+ "ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
+ ring->index, ring->c_index, pkts_compl, bytes_compl);
return pkts_compl;
}
@@ -654,13 +710,13 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
work_done = bcm_sysport_tx_reclaim(ring->priv, ring);
- if (work_done < budget) {
+ if (work_done == 0) {
napi_complete(napi);
/* re-enable TX interrupt */
intrl2_1_mask_clear(ring->priv, BIT(ring->index));
}
- return work_done;
+ return 0;
}
static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv)
@@ -692,6 +748,20 @@ static int bcm_sysport_poll(struct napi_struct *napi, int budget)
return work_done;
}
+static void bcm_sysport_resume_from_wol(struct bcm_sysport_priv *priv)
+{
+ u32 reg;
+
+ /* Stop monitoring MPD interrupt */
+ intrl2_0_mask_set(priv, INTRL2_0_MPD);
+
+ /* Clear the MagicPacket detection logic */
+ reg = umac_readl(priv, UMAC_MPD_CTRL);
+ reg &= ~MPD_EN;
+ umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+ netif_dbg(priv, wol, priv->netdev, "resumed from WOL\n");
+}
/* RX and misc interrupt routine */
static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
@@ -722,6 +792,11 @@ static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
if (priv->irq0_stat & INTRL2_0_TX_RING_FULL)
bcm_sysport_tx_reclaim_all(priv);
+ if (priv->irq0_stat & INTRL2_0_MPD) {
+ netdev_info(priv->netdev, "Wake-on-LAN interrupt!\n");
+ bcm_sysport_resume_from_wol(priv);
+ }
+
return IRQ_HANDLED;
}
@@ -757,6 +832,15 @@ static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t bcm_sysport_wol_isr(int irq, void *dev_id)
+{
+ struct bcm_sysport_priv *priv = dev_id;
+
+ pm_wakeup_event(&priv->pdev->dev, 0);
+
+ return IRQ_HANDLED;
+}
+
static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
{
struct sk_buff *nskb;
@@ -804,8 +888,9 @@ static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
csum_info |= L4_LENGTH_VALID;
if (ip_proto == IPPROTO_UDP && ip_ver == ETH_P_IP)
csum_info |= L4_UDP;
- } else
+ } else {
csum_info = 0;
+ }
tsb->l4_ptr_dest_map = csum_info;
}
@@ -869,7 +954,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
if (dma_mapping_error(kdev, mapping)) {
netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n",
- skb->data, skb_len);
+ skb->data, skb_len);
ret = NETDEV_TX_OK;
goto out;
}
@@ -887,7 +972,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
len_status |= (skb_len << DESC_LEN_SHIFT);
len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
- DESC_STATUS_SHIFT;
+ DESC_STATUS_SHIFT;
if (skb->ip_summed == CHECKSUM_PARTIAL)
len_status |= (DESC_L4_CSUM << DESC_STATUS_SHIFT);
@@ -912,7 +997,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
netif_tx_stop_queue(txq);
netif_dbg(priv, tx_queued, dev, "ring=%d desc_count=%d, curr_desc=%d\n",
- ring->index, ring->desc_count, ring->curr_desc);
+ ring->index, ring->desc_count, ring->curr_desc);
ret = NETDEV_TX_OK;
out:
@@ -1010,7 +1095,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
return -ENOMEM;
}
- ring->cbs = kzalloc(sizeof(struct bcm_sysport_cb) * size, GFP_KERNEL);
+ ring->cbs = kcalloc(size, sizeof(struct bcm_sysport_cb), GFP_KERNEL);
if (!ring->cbs) {
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
return -ENOMEM;
@@ -1050,14 +1135,14 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
napi_enable(&ring->napi);
netif_dbg(priv, hw, priv->netdev,
- "TDMA cfg, size=%d, desc_cpu=%p\n",
- ring->size, ring->desc_cpu);
+ "TDMA cfg, size=%d, desc_cpu=%p\n",
+ ring->size, ring->desc_cpu);
return 0;
}
static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
- unsigned int index)
+ unsigned int index)
{
struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
struct device *kdev = &priv->pdev->dev;
@@ -1088,7 +1173,7 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
/* RDMA helper */
static inline int rdma_enable_set(struct bcm_sysport_priv *priv,
- unsigned int enable)
+ unsigned int enable)
{
unsigned int timeout = 1000;
u32 reg;
@@ -1115,7 +1200,7 @@ static inline int rdma_enable_set(struct bcm_sysport_priv *priv,
/* TDMA helper */
static inline int tdma_enable_set(struct bcm_sysport_priv *priv,
- unsigned int enable)
+ unsigned int enable)
{
unsigned int timeout = 1000;
u32 reg;
@@ -1153,8 +1238,8 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
priv->rx_bd_assign_index = 0;
priv->rx_c_index = 0;
priv->rx_read_ptr = 0;
- priv->rx_cbs = kzalloc(priv->num_rx_bds *
- sizeof(struct bcm_sysport_cb), GFP_KERNEL);
+ priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct bcm_sysport_cb),
+ GFP_KERNEL);
if (!priv->rx_cbs) {
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
return -ENOMEM;
@@ -1186,8 +1271,8 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
rdma_writel(priv, 1, RDMA_MBDONE_INTR);
netif_dbg(priv, hw, priv->netdev,
- "RDMA cfg, num_rx_bds=%d, rx_bds=%p\n",
- priv->num_rx_bds, priv->rx_bds);
+ "RDMA cfg, num_rx_bds=%d, rx_bds=%p\n",
+ priv->num_rx_bds, priv->rx_bds);
return 0;
}
@@ -1207,8 +1292,8 @@ static void bcm_sysport_fini_rx_ring(struct bcm_sysport_priv *priv)
cb = &priv->rx_cbs[i];
if (dma_unmap_addr(cb, dma_addr))
dma_unmap_single(&priv->pdev->dev,
- dma_unmap_addr(cb, dma_addr),
- RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ dma_unmap_addr(cb, dma_addr),
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
bcm_sysport_free_cb(cb);
}
@@ -1236,15 +1321,15 @@ static void bcm_sysport_set_rx_mode(struct net_device *dev)
}
static inline void umac_enable_set(struct bcm_sysport_priv *priv,
- unsigned int enable)
+ u32 mask, unsigned int enable)
{
u32 reg;
reg = umac_readl(priv, UMAC_CMD);
if (enable)
- reg |= CMD_RX_EN | CMD_TX_EN;
+ reg |= mask;
else
- reg &= ~(CMD_RX_EN | CMD_TX_EN);
+ reg &= ~mask;
umac_writel(priv, reg, UMAC_CMD);
/* UniMAC stops on a packet boundary, wait for a full-sized packet
@@ -1254,32 +1339,21 @@ static inline void umac_enable_set(struct bcm_sysport_priv *priv,
usleep_range(1000, 2000);
}
-static inline int umac_reset(struct bcm_sysport_priv *priv)
+static inline void umac_reset(struct bcm_sysport_priv *priv)
{
- unsigned int timeout = 0;
u32 reg;
- int ret = 0;
- umac_writel(priv, 0, UMAC_CMD);
- while (timeout++ < 1000) {
- reg = umac_readl(priv, UMAC_CMD);
- if (!(reg & CMD_SW_RESET))
- break;
-
- udelay(1);
- }
-
- if (timeout == 1000) {
- dev_err(&priv->pdev->dev,
- "timeout waiting for MAC to come out of reset\n");
- ret = -ETIMEDOUT;
- }
-
- return ret;
+ reg = umac_readl(priv, UMAC_CMD);
+ reg |= CMD_SW_RESET;
+ umac_writel(priv, reg, UMAC_CMD);
+ udelay(10);
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_SW_RESET;
+ umac_writel(priv, reg, UMAC_CMD);
}
static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
- unsigned char *addr)
+ unsigned char *addr)
{
umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
(addr[2] << 8) | addr[3], UMAC_MAC0);
@@ -1295,30 +1369,48 @@ static void topctrl_flush(struct bcm_sysport_priv *priv)
topctrl_writel(priv, 0, TX_FLUSH_CNTL);
}
+static void bcm_sysport_netif_start(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ /* Enable NAPI */
+ napi_enable(&priv->napi);
+
+ phy_start(priv->phydev);
+
+ /* Enable TX interrupts for the 32 TXQs */
+ intrl2_1_mask_clear(priv, 0xffffffff);
+
+ /* Last call before we start the real business */
+ netif_tx_start_all_queues(dev);
+}
+
+static void rbuf_init(struct bcm_sysport_priv *priv)
+{
+ u32 reg;
+
+ reg = rbuf_readl(priv, RBUF_CONTROL);
+ reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
+ rbuf_writel(priv, reg, RBUF_CONTROL);
+}
+
static int bcm_sysport_open(struct net_device *dev)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
unsigned int i;
- u32 reg;
int ret;
/* Reset UniMAC */
- ret = umac_reset(priv);
- if (ret) {
- netdev_err(dev, "UniMAC reset failed\n");
- return ret;
- }
+ umac_reset(priv);
/* Flush TX and RX FIFOs at TOPCTRL level */
topctrl_flush(priv);
/* Disable the UniMAC RX/TX */
- umac_enable_set(priv, 0);
+ umac_enable_set(priv, CMD_RX_EN | CMD_TX_EN, 0);
/* Enable RBUF 2bytes alignment and Receive Status Block */
- reg = rbuf_readl(priv, RBUF_CONTROL);
- reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
- rbuf_writel(priv, reg, RBUF_CONTROL);
+ rbuf_init(priv);
/* Set maximum frame length */
umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
@@ -1366,7 +1458,7 @@ static int bcm_sysport_open(struct net_device *dev)
ret = bcm_sysport_init_tx_ring(priv, i);
if (ret) {
netdev_err(dev, "failed to initialize TX ring %d\n",
- i);
+ i);
goto out_free_tx_ring;
}
}
@@ -1394,19 +1486,10 @@ static int bcm_sysport_open(struct net_device *dev)
if (ret)
goto out_clear_rx_int;
- /* Enable NAPI */
- napi_enable(&priv->napi);
-
/* Turn on UniMAC TX/RX */
- umac_enable_set(priv, 1);
-
- phy_start(priv->phydev);
+ umac_enable_set(priv, CMD_RX_EN | CMD_TX_EN, 1);
- /* Enable TX interrupts for the 32 TXQs */
- intrl2_1_mask_clear(priv, 0xffffffff);
-
- /* Last call before we start the real business */
- netif_tx_start_all_queues(dev);
+ bcm_sysport_netif_start(dev);
return 0;
@@ -1425,12 +1508,9 @@ out_phy_disconnect:
return ret;
}
-static int bcm_sysport_stop(struct net_device *dev)
+static void bcm_sysport_netif_stop(struct net_device *dev)
{
struct bcm_sysport_priv *priv = netdev_priv(dev);
- unsigned int i;
- u32 reg;
- int ret;
/* stop all software from updating hardware */
netif_tx_stop_all_queues(dev);
@@ -1442,11 +1522,18 @@ static int bcm_sysport_stop(struct net_device *dev)
intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
intrl2_1_mask_set(priv, 0xffffffff);
intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+}
+
+static int bcm_sysport_stop(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ int ret;
+
+ bcm_sysport_netif_stop(dev);
/* Disable UniMAC RX */
- reg = umac_readl(priv, UMAC_CMD);
- reg &= ~CMD_RX_EN;
- umac_writel(priv, reg, UMAC_CMD);
+ umac_enable_set(priv, CMD_RX_EN, 0);
ret = tdma_enable_set(priv, 0);
if (ret) {
@@ -1464,9 +1551,7 @@ static int bcm_sysport_stop(struct net_device *dev)
}
/* Disable UniMAC TX */
- reg = umac_readl(priv, UMAC_CMD);
- reg &= ~CMD_TX_EN;
- umac_writel(priv, reg, UMAC_CMD);
+ umac_enable_set(priv, CMD_TX_EN, 0);
/* Free RX/TX rings SW structures */
for (i = 0; i < dev->num_tx_queues; i++)
@@ -1492,6 +1577,8 @@ static struct ethtool_ops bcm_sysport_ethtool_ops = {
.get_strings = bcm_sysport_get_strings,
.get_ethtool_stats = bcm_sysport_get_stats,
.get_sset_count = bcm_sysport_get_sset_count,
+ .get_wol = bcm_sysport_get_wol,
+ .set_wol = bcm_sysport_set_wol,
};
static const struct net_device_ops bcm_sysport_netdev_ops = {
@@ -1533,6 +1620,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
priv->irq0 = platform_get_irq(pdev, 0);
priv->irq1 = platform_get_irq(pdev, 1);
+ priv->wol_irq = platform_get_irq(pdev, 2);
if (priv->irq0 <= 0 || priv->irq1 <= 0) {
dev_err(&pdev->dev, "invalid interrupts\n");
ret = -EINVAL;
@@ -1585,16 +1673,17 @@ static int bcm_sysport_probe(struct platform_device *pdev)
dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ /* Request the WOL interrupt and advertise suspend if available */
+ priv->wol_irq_disabled = 1;
+ ret = devm_request_irq(&pdev->dev, priv->wol_irq,
+ bcm_sysport_wol_isr, 0, dev->name, priv);
+ if (!ret)
+ device_set_wakeup_capable(&pdev->dev, 1);
+
/* Set the needed headroom once and for all */
BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8);
dev->needed_headroom += sizeof(struct bcm_tsb);
- /* We are interfaced to a switch which handles the multicast
- * filtering for us, so we do not support programming any
- * multicast hash table in this Ethernet MAC.
- */
- dev->flags &= ~IFF_MULTICAST;
-
/* libphy will adjust the link state accordingly */
netif_carrier_off(dev);
@@ -1606,10 +1695,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
dev_info(&pdev->dev,
- "Broadcom SYSTEMPORT" REV_FMT
- " at 0x%p (irqs: %d, %d, TXQs: %d, RXQs: %d)\n",
- (priv->rev >> 8) & 0xff, priv->rev & 0xff,
- priv->base, priv->irq0, priv->irq1, txq, rxq);
+ "Broadcom SYSTEMPORT" REV_FMT
+ " at 0x%p (irqs: %d, %d, TXQs: %d, RXQs: %d)\n",
+ (priv->rev >> 8) & 0xff, priv->rev & 0xff,
+ priv->base, priv->irq0, priv->irq1, txq, rxq);
return 0;
err:
@@ -1631,6 +1720,208 @@ static int bcm_sysport_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int bcm_sysport_suspend_to_wol(struct bcm_sysport_priv *priv)
+{
+ struct net_device *ndev = priv->netdev;
+ unsigned int timeout = 1000;
+ u32 reg;
+
+ /* Password has already been programmed */
+ reg = umac_readl(priv, UMAC_MPD_CTRL);
+ reg |= MPD_EN;
+ reg &= ~PSW_EN;
+ if (priv->wolopts & WAKE_MAGICSECURE)
+ reg |= PSW_EN;
+ umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+ /* Make sure RBUF entered WoL mode as result */
+ do {
+ reg = rbuf_readl(priv, RBUF_STATUS);
+ if (reg & RBUF_WOL_MODE)
+ break;
+
+ udelay(10);
+ } while (timeout-- > 0);
+
+ /* Do not leave the UniMAC RBUF matching only MPD packets */
+ if (!timeout) {
+ reg = umac_readl(priv, UMAC_MPD_CTRL);
+ reg &= ~MPD_EN;
+ umac_writel(priv, reg, UMAC_MPD_CTRL);
+ netif_err(priv, wol, ndev, "failed to enter WOL mode\n");
+ return -ETIMEDOUT;
+ }
+
+ /* UniMAC receive needs to be turned on */
+ umac_enable_set(priv, CMD_RX_EN, 1);
+
+ /* Enable the interrupt wake-up source */
+ intrl2_0_mask_clear(priv, INTRL2_0_MPD);
+
+ netif_dbg(priv, wol, ndev, "entered WOL mode\n");
+
+ return 0;
+}
+
+static int bcm_sysport_suspend(struct device *d)
+{
+ struct net_device *dev = dev_get_drvdata(d);
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ int ret = 0;
+ u32 reg;
+
+ if (!netif_running(dev))
+ return 0;
+
+ bcm_sysport_netif_stop(dev);
+
+ phy_suspend(priv->phydev);
+
+ netif_device_detach(dev);
+
+ /* Disable UniMAC RX */
+ umac_enable_set(priv, CMD_RX_EN, 0);
+
+ ret = rdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "RDMA timeout!\n");
+ return ret;
+ }
+
+ /* Disable RXCHK if enabled */
+ if (priv->rx_chk_en) {
+ reg = rxchk_readl(priv, RXCHK_CONTROL);
+ reg &= ~RXCHK_EN;
+ rxchk_writel(priv, reg, RXCHK_CONTROL);
+ }
+
+ /* Flush RX pipe */
+ if (!priv->wolopts)
+ topctrl_writel(priv, RX_FLUSH, RX_FLUSH_CNTL);
+
+ ret = tdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "TDMA timeout!\n");
+ return ret;
+ }
+
+ /* Wait for a packet boundary */
+ usleep_range(2000, 3000);
+
+ umac_enable_set(priv, CMD_TX_EN, 0);
+
+ topctrl_writel(priv, TX_FLUSH, TX_FLUSH_CNTL);
+
+ /* Free RX/TX rings SW structures */
+ for (i = 0; i < dev->num_tx_queues; i++)
+ bcm_sysport_fini_tx_ring(priv, i);
+ bcm_sysport_fini_rx_ring(priv);
+
+ /* Get prepared for Wake-on-LAN */
+ if (device_may_wakeup(d) && priv->wolopts)
+ ret = bcm_sysport_suspend_to_wol(priv);
+
+ return ret;
+}
+
+static int bcm_sysport_resume(struct device *d)
+{
+ struct net_device *dev = dev_get_drvdata(d);
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ u32 reg;
+ int ret;
+
+ if (!netif_running(dev))
+ return 0;
+
+ /* We may have been suspended and never received a WOL event that
+ * would turn off MPD detection, take care of that now
+ */
+ bcm_sysport_resume_from_wol(priv);
+
+ /* Initialize both hardware and software ring */
+ for (i = 0; i < dev->num_tx_queues; i++) {
+ ret = bcm_sysport_init_tx_ring(priv, i);
+ if (ret) {
+ netdev_err(dev, "failed to initialize TX ring %d\n",
+ i);
+ goto out_free_tx_rings;
+ }
+ }
+
+ /* Initialize linked-list */
+ tdma_writel(priv, TDMA_LL_RAM_INIT_BUSY, TDMA_STATUS);
+
+ /* Initialize RX ring */
+ ret = bcm_sysport_init_rx_ring(priv);
+ if (ret) {
+ netdev_err(dev, "failed to initialize RX ring\n");
+ goto out_free_rx_ring;
+ }
+
+ netif_device_attach(dev);
+
+ /* Enable RX interrupt and TX ring full interrupt */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+
+ /* RX pipe enable */
+ topctrl_writel(priv, 0, RX_FLUSH_CNTL);
+
+ ret = rdma_enable_set(priv, 1);
+ if (ret) {
+ netdev_err(dev, "failed to enable RDMA\n");
+ goto out_free_rx_ring;
+ }
+
+ /* Enable rxhck */
+ if (priv->rx_chk_en) {
+ reg = rxchk_readl(priv, RXCHK_CONTROL);
+ reg |= RXCHK_EN;
+ rxchk_writel(priv, reg, RXCHK_CONTROL);
+ }
+
+ rbuf_init(priv);
+
+ /* Set maximum frame length */
+ umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+
+ /* Set MAC address */
+ umac_set_hw_addr(priv, dev->dev_addr);
+
+ umac_enable_set(priv, CMD_RX_EN, 1);
+
+ /* TX pipe enable */
+ topctrl_writel(priv, 0, TX_FLUSH_CNTL);
+
+ umac_enable_set(priv, CMD_TX_EN, 1);
+
+ ret = tdma_enable_set(priv, 1);
+ if (ret) {
+ netdev_err(dev, "TDMA timeout!\n");
+ goto out_free_rx_ring;
+ }
+
+ phy_resume(priv->phydev);
+
+ bcm_sysport_netif_start(dev);
+
+ return 0;
+
+out_free_rx_ring:
+ bcm_sysport_fini_rx_ring(priv);
+out_free_tx_rings:
+ for (i = 0; i < dev->num_tx_queues; i++)
+ bcm_sysport_fini_tx_ring(priv, i);
+ return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(bcm_sysport_pm_ops,
+ bcm_sysport_suspend, bcm_sysport_resume);
+
static const struct of_device_id bcm_sysport_of_match[] = {
{ .compatible = "brcm,systemport-v1.00" },
{ .compatible = "brcm,systemport" },
@@ -1644,6 +1935,7 @@ static struct platform_driver bcm_sysport_driver = {
.name = "brcm-systemport",
.owner = THIS_MODULE,
.of_match_table = bcm_sysport_of_match,
+ .pm = &bcm_sysport_pm_ops,
},
};
module_platform_driver(bcm_sysport_driver);
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
index 281c08246037..b08dab828101 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.h
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -246,6 +246,15 @@ struct bcm_rsb {
#define MIB_RX_CNT_RST (1 << 0)
#define MIB_RUNT_CNT_RST (1 << 1)
#define MIB_TX_CNT_RST (1 << 2)
+
+#define UMAC_MPD_CTRL 0x620
+#define MPD_EN (1 << 0)
+#define MSEQ_LEN_SHIFT 16
+#define MSEQ_LEN_MASK 0xff
+#define PSW_EN (1 << 27)
+
+#define UMAC_PSW_MS 0x624
+#define UMAC_PSW_LS 0x628
#define UMAC_MDF_CTRL 0x650
#define UMAC_MDF_ADDR 0x654
@@ -642,6 +651,7 @@ struct bcm_sysport_priv {
struct platform_device *pdev;
int irq0;
int irq1;
+ int wol_irq;
/* Transmit rings */
struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
@@ -664,10 +674,12 @@ struct bcm_sysport_priv {
int old_duplex;
/* Misc fields */
- unsigned int rx_csum_en:1;
+ unsigned int rx_chk_en:1;
unsigned int tsb_en:1;
unsigned int crc_fwd:1;
u16 rev;
+ u32 wolopts;
+ unsigned int wol_irq_disabled:1;
/* MIB related fields */
struct bcm_sysport_mib mib;
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 67d2b0047371..e64c963fe775 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -1,6 +1,7 @@
-/* bnx2.c: Broadcom NX2 network driver.
+/* bnx2.c: QLogic NX2 network driver.
*
- * Copyright (c) 2004-2013 Broadcom Corporation
+ * Copyright (c) 2004-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
@@ -71,10 +72,10 @@
#define TX_TIMEOUT (5*HZ)
static char version[] =
- "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+ "QLogic NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver");
+MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/5716 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_FIRMWARE(FW_MIPS_FILE_06);
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h
index e341bc366fa5..28df35d35893 100644
--- a/drivers/net/ethernet/broadcom/bnx2.h
+++ b/drivers/net/ethernet/broadcom/bnx2.h
@@ -1,6 +1,7 @@
-/* bnx2.h: Broadcom NX2 network driver.
+/* bnx2.h: QLogic NX2 network driver.
*
- * Copyright (c) 2004-2013 Broadcom Corporation
+ * Copyright (c) 2004-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
diff --git a/drivers/net/ethernet/broadcom/bnx2_fw.h b/drivers/net/ethernet/broadcom/bnx2_fw.h
index 940eb91f209d..7db79c28b5ff 100644
--- a/drivers/net/ethernet/broadcom/bnx2_fw.h
+++ b/drivers/net/ethernet/broadcom/bnx2_fw.h
@@ -1,6 +1,7 @@
-/* bnx2_fw.h: Broadcom NX2 network driver.
+/* bnx2_fw.h: QLogic NX2 network driver.
*
* Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 4cab09d3f807..d777fae86988 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -346,6 +346,7 @@ struct sw_tx_bd {
u8 flags;
/* Set on the first BD descriptor when there is a split BD */
#define BNX2X_TSO_SPLIT_BD (1<<0)
+#define BNX2X_HAS_SECOND_PBD (1<<1)
};
struct sw_rx_page {
@@ -1482,6 +1483,7 @@ struct bnx2x {
union pf_vf_bulletin *pf2vf_bulletin;
dma_addr_t pf2vf_bulletin_mapping;
+ union pf_vf_bulletin shadow_bulletin;
struct pf_vf_bulletin_content old_bulletin;
u16 requested_nr_virtfn;
@@ -1507,8 +1509,10 @@ struct bnx2x {
/* TCP with Timestamp Option (32) + IPv6 (40) */
#define ETH_MAX_TPA_HEADER_SIZE 72
- /* Max supported alignment is 256 (8 shift) */
-#define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT)
+ /* Max supported alignment is 256 (8 shift)
+ * minimal alignment shift 6 is optimal for 57xxx HW performance
+ */
+#define BNX2X_RX_ALIGN_SHIFT max(6, min(8, L1_CACHE_SHIFT))
/* FW uses 2 Cache lines Alignment for start packet and size
*
@@ -1928,6 +1932,8 @@ struct bnx2x {
struct semaphore stats_sema;
u8 phys_port_id[ETH_ALEN];
+
+ struct bnx2x_link_report_data vf_link_vars;
};
/* Tx queues may be less or equal to Rx queues */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 47c5814114e1..4e6c82e20224 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -227,6 +227,12 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
--nbd;
bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) {
+ /* Skip second parse bd... */
+ --nbd;
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
/* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
@@ -797,7 +803,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
return;
}
- bnx2x_frag_free(fp, new_data);
+ if (new_data)
+ bnx2x_frag_free(fp, new_data);
drop:
/* drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
@@ -1185,29 +1192,38 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
static void bnx2x_fill_report_data(struct bnx2x *bp,
struct bnx2x_link_report_data *data)
{
- u16 line_speed = bnx2x_get_mf_speed(bp);
-
memset(data, 0, sizeof(*data));
- /* Fill the report data: effective line speed */
- data->line_speed = line_speed;
-
- /* Link is down */
- if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
- __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
- &data->link_report_flags);
-
- /* Full DUPLEX */
- if (bp->link_vars.duplex == DUPLEX_FULL)
- __set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
-
- /* Rx Flow Control is ON */
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
- __set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
-
- /* Tx Flow Control is ON */
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
- __set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
+ if (IS_PF(bp)) {
+ /* Fill the report data: effective line speed */
+ data->line_speed = bnx2x_get_mf_speed(bp);
+
+ /* Link is down */
+ if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &data->link_report_flags);
+
+ if (!BNX2X_NUM_ETH_QUEUES(bp))
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &data->link_report_flags);
+
+ /* Full DUPLEX */
+ if (bp->link_vars.duplex == DUPLEX_FULL)
+ __set_bit(BNX2X_LINK_REPORT_FD,
+ &data->link_report_flags);
+
+ /* Rx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ __set_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &data->link_report_flags);
+
+ /* Tx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ __set_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &data->link_report_flags);
+ } else { /* VF */
+ *data = bp->vf_link_vars;
+ }
}
/**
@@ -1261,6 +1277,10 @@ void __bnx2x_link_report(struct bnx2x *bp)
*/
memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
+ /* propagate status to VFs */
+ if (IS_PF(bp))
+ bnx2x_iov_link_update(bp);
+
if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
&cur_data.link_report_flags)) {
netif_carrier_off(bp->dev);
@@ -3888,6 +3908,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* set encapsulation flag in start BD */
SET_FLAG(tx_start_bd->general_data,
ETH_TX_START_BD_TUNNEL_EXIST, 1);
+
+ tx_buf->flags |= BNX2X_HAS_SECOND_PBD;
+
nbd++;
} else if (xmit_type & XMIT_CSUM) {
/* Set PBD in checksum offload case w/o encapsulation */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index 51a952c51cb1..fb26bc4c42a1 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -2303,8 +2303,8 @@ static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
return 0;
}
-static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
- u16 idval, u8 up)
+static int bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
+ u16 idval, u8 up)
{
struct bnx2x *bp = netdev_priv(netdev);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index bd0600cf7266..92fee842f954 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -216,6 +216,43 @@ static int bnx2x_get_port_type(struct bnx2x *bp)
return port_type;
}
+static int bnx2x_get_vf_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (bp->state == BNX2X_STATE_OPEN) {
+ if (test_bit(BNX2X_LINK_REPORT_FD,
+ &bp->vf_link_vars.link_report_flags))
+ cmd->duplex = DUPLEX_FULL;
+ else
+ cmd->duplex = DUPLEX_HALF;
+
+ ethtool_cmd_speed_set(cmd, bp->vf_link_vars.line_speed);
+ } else {
+ cmd->duplex = DUPLEX_UNKNOWN;
+ ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
+ }
+
+ cmd->port = PORT_OTHER;
+ cmd->phy_address = 0;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ DP(BNX2X_MSG_ETHTOOL, "ethtool_cmd: cmd %d\n"
+ " supported 0x%x advertising 0x%x speed %u\n"
+ " duplex %d port %d phy_address %d transceiver %d\n"
+ " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
+ cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+ cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+ return 0;
+}
+
static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -379,6 +416,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
break;
case PORT_FIBRE:
case PORT_DA:
+ case PORT_NONE:
if (!(bp->port.supported[0] & SUPPORTED_FIBRE ||
bp->port.supported[1] & SUPPORTED_FIBRE)) {
DP(BNX2X_MSG_ETHTOOL,
@@ -1110,6 +1148,10 @@ static u32 bnx2x_get_link(struct net_device *dev)
if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
return 0;
+ if (IS_VF(bp))
+ return !test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->vf_link_vars.link_report_flags);
+
return bp->link_vars.link_up;
}
@@ -3484,8 +3526,7 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
};
static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
- .get_settings = bnx2x_get_settings,
- .set_settings = bnx2x_set_settings,
+ .get_settings = bnx2x_get_vf_settings,
.get_drvinfo = bnx2x_get_drvinfo,
.get_msglevel = bnx2x_get_msglevel,
.set_msglevel = bnx2x_set_msglevel,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2887034523e0..3871ec49cc4d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -2698,6 +2698,14 @@ void bnx2x__link_status_update(struct bnx2x *bp)
bp->link_vars.duplex = DUPLEX_FULL;
bp->link_vars.flow_ctrl = BNX2X_FLOW_CTRL_NONE;
__bnx2x_link_report(bp);
+
+ bnx2x_sample_bulletin(bp);
+
+ /* if bulletin board did not have an update for link status
+ * __bnx2x_link_report will report current status
+ * but it will NOT duplicate report in case of already reported
+ * during sampling bulletin board.
+ */
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
}
}
@@ -12424,6 +12432,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_busy_poll = bnx2x_low_latency_recv,
#endif
.ndo_get_phys_port_id = bnx2x_get_phys_port_id,
+ .ndo_set_vf_link_state = bnx2x_set_vf_link_state,
};
static int bnx2x_set_coherency_mask(struct bnx2x *bp)
@@ -12937,7 +12946,7 @@ static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev, int cnic_cnt)
* without the default SB.
* For VFs there is no default SB, then we return (index+1).
*/
- pci_read_config_word(pdev, pdev->msix_cap + PCI_MSI_FLAGS, &control);
+ pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &control);
index = control & PCI_MSIX_FLAGS_QSIZE;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index eda8583f6fc0..662310c5f4e9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -24,6 +24,11 @@
#include <linux/crc32.h>
#include <linux/if_vlan.h>
+static int bnx2x_vf_op_prep(struct bnx2x *bp, int vfidx,
+ struct bnx2x_virtf **vf,
+ struct pf_vf_bulletin_content **bulletin,
+ bool test_queue);
+
/* General service functions */
static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid,
u16 pf_id)
@@ -597,8 +602,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf,
rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_DEL);
if (rc) {
BNX2X_ERR("Failed to remove multicasts\n");
- if (mc)
- kfree(mc);
+ kfree(mc);
return rc;
}
@@ -1328,6 +1332,8 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param,
/* Prepare the VFs event synchronization mechanism */
mutex_init(&bp->vfdb->event_mutex);
+ mutex_init(&bp->vfdb->bulletin_mutex);
+
return 0;
failed:
DP(BNX2X_MSG_IOV, "Failed err=%d\n", err);
@@ -1473,6 +1479,107 @@ static void bnx2x_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf,
vf->abs_vfid, q->sp_obj.func_id, q->cid);
}
+static int bnx2x_max_speed_cap(struct bnx2x *bp)
+{
+ u32 supported = bp->port.supported[bnx2x_get_link_cfg_idx(bp)];
+
+ if (supported &
+ (SUPPORTED_20000baseMLD2_Full | SUPPORTED_20000baseKR2_Full))
+ return 20000;
+
+ return 10000; /* assume lowest supported speed is 10G */
+}
+
+int bnx2x_iov_link_update_vf(struct bnx2x *bp, int idx)
+{
+ struct bnx2x_link_report_data *state = &bp->last_reported_link;
+ struct pf_vf_bulletin_content *bulletin;
+ struct bnx2x_virtf *vf;
+ bool update = true;
+ int rc = 0;
+
+ /* sanity and init */
+ rc = bnx2x_vf_op_prep(bp, idx, &vf, &bulletin, false);
+ if (rc)
+ return rc;
+
+ mutex_lock(&bp->vfdb->bulletin_mutex);
+
+ if (vf->link_cfg == IFLA_VF_LINK_STATE_AUTO) {
+ bulletin->valid_bitmap |= 1 << LINK_VALID;
+
+ bulletin->link_speed = state->line_speed;
+ bulletin->link_flags = 0;
+ if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &state->link_report_flags))
+ bulletin->link_flags |= VFPF_LINK_REPORT_LINK_DOWN;
+ if (test_bit(BNX2X_LINK_REPORT_FD,
+ &state->link_report_flags))
+ bulletin->link_flags |= VFPF_LINK_REPORT_FULL_DUPLEX;
+ if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &state->link_report_flags))
+ bulletin->link_flags |= VFPF_LINK_REPORT_RX_FC_ON;
+ if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &state->link_report_flags))
+ bulletin->link_flags |= VFPF_LINK_REPORT_TX_FC_ON;
+ } else if (vf->link_cfg == IFLA_VF_LINK_STATE_DISABLE &&
+ !(bulletin->link_flags & VFPF_LINK_REPORT_LINK_DOWN)) {
+ bulletin->valid_bitmap |= 1 << LINK_VALID;
+ bulletin->link_flags |= VFPF_LINK_REPORT_LINK_DOWN;
+ } else if (vf->link_cfg == IFLA_VF_LINK_STATE_ENABLE &&
+ (bulletin->link_flags & VFPF_LINK_REPORT_LINK_DOWN)) {
+ bulletin->valid_bitmap |= 1 << LINK_VALID;
+ bulletin->link_speed = bnx2x_max_speed_cap(bp);
+ bulletin->link_flags &= ~VFPF_LINK_REPORT_LINK_DOWN;
+ } else {
+ update = false;
+ }
+
+ if (update) {
+ DP(NETIF_MSG_LINK | BNX2X_MSG_IOV,
+ "vf %d mode %u speed %d flags %x\n", idx,
+ vf->link_cfg, bulletin->link_speed, bulletin->link_flags);
+
+ /* Post update on VF's bulletin board */
+ rc = bnx2x_post_vf_bulletin(bp, idx);
+ if (rc) {
+ BNX2X_ERR("failed to update VF[%d] bulletin\n", idx);
+ goto out;
+ }
+ }
+
+out:
+ mutex_unlock(&bp->vfdb->bulletin_mutex);
+ return rc;
+}
+
+int bnx2x_set_vf_link_state(struct net_device *dev, int idx, int link_state)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x_virtf *vf = BP_VF(bp, idx);
+
+ if (!vf)
+ return -EINVAL;
+
+ if (vf->link_cfg == link_state)
+ return 0; /* nothing todo */
+
+ vf->link_cfg = link_state;
+
+ return bnx2x_iov_link_update_vf(bp, idx);
+}
+
+void bnx2x_iov_link_update(struct bnx2x *bp)
+{
+ int vfid;
+
+ if (!IS_SRIOV(bp))
+ return;
+
+ for_each_vf(bp, vfid)
+ bnx2x_iov_link_update_vf(bp, vfid);
+}
+
/* called by bnx2x_nic_load */
int bnx2x_iov_nic_init(struct bnx2x *bp)
{
@@ -2510,22 +2617,23 @@ void bnx2x_disable_sriov(struct bnx2x *bp)
pci_disable_sriov(bp->pdev);
}
-static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx,
- struct bnx2x_virtf **vf,
- struct pf_vf_bulletin_content **bulletin)
+static int bnx2x_vf_op_prep(struct bnx2x *bp, int vfidx,
+ struct bnx2x_virtf **vf,
+ struct pf_vf_bulletin_content **bulletin,
+ bool test_queue)
{
if (bp->state != BNX2X_STATE_OPEN) {
- BNX2X_ERR("vf ndo called though PF is down\n");
+ BNX2X_ERR("PF is down - can't utilize iov-related functionality\n");
return -EINVAL;
}
if (!IS_SRIOV(bp)) {
- BNX2X_ERR("vf ndo called though sriov is disabled\n");
+ BNX2X_ERR("sriov is disabled - can't utilize iov-realted functionality\n");
return -EINVAL;
}
if (vfidx >= BNX2X_NR_VIRTFN(bp)) {
- BNX2X_ERR("vf ndo called for uninitialized VF. vfidx was %d BNX2X_NR_VIRTFN was %d\n",
+ BNX2X_ERR("VF is uninitialized - can't utilize iov-related functionality. vfidx was %d BNX2X_NR_VIRTFN was %d\n",
vfidx, BNX2X_NR_VIRTFN(bp));
return -EINVAL;
}
@@ -2535,19 +2643,18 @@ static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx,
*bulletin = BP_VF_BULLETIN(bp, vfidx);
if (!*vf) {
- BNX2X_ERR("vf ndo called but vf struct is null. vfidx was %d\n",
- vfidx);
+ BNX2X_ERR("Unable to get VF structure for vfidx %d\n", vfidx);
return -EINVAL;
}
- if (!(*vf)->vfqs) {
- BNX2X_ERR("vf ndo called but vfqs struct is null. Was ndo invoked before dynamically enabling SR-IOV? vfidx was %d\n",
+ if (test_queue && !(*vf)->vfqs) {
+ BNX2X_ERR("vfqs struct is null. Was this invoked before dynamically enabling SR-IOV? vfidx was %d\n",
vfidx);
return -EINVAL;
}
if (!*bulletin) {
- BNX2X_ERR("vf ndo called but Bulletin Board struct is null. vfidx was %d\n",
+ BNX2X_ERR("Bulletin Board struct is null for vfidx %d\n",
vfidx);
return -EINVAL;
}
@@ -2566,9 +2673,10 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
int rc;
/* sanity and init */
- rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
+ rc = bnx2x_vf_op_prep(bp, vfidx, &vf, &bulletin, true);
if (rc)
return rc;
+
mac_obj = &bnx2x_leading_vfq(vf, mac_obj);
vlan_obj = &bnx2x_leading_vfq(vf, vlan_obj);
if (!mac_obj || !vlan_obj) {
@@ -2591,6 +2699,7 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
VLAN_HLEN);
}
} else {
+ mutex_lock(&bp->vfdb->bulletin_mutex);
/* mac */
if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
/* mac configured by ndo so its in bulletin board */
@@ -2606,6 +2715,8 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
else
/* function has not been loaded yet. Show vlans as 0s */
memset(&ivi->vlan, 0, VLAN_HLEN);
+
+ mutex_unlock(&bp->vfdb->bulletin_mutex);
}
return 0;
@@ -2635,15 +2746,18 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
struct bnx2x_virtf *vf = NULL;
struct pf_vf_bulletin_content *bulletin = NULL;
- /* sanity and init */
- rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
- if (rc)
- return rc;
if (!is_valid_ether_addr(mac)) {
BNX2X_ERR("mac address invalid\n");
return -EINVAL;
}
+ /* sanity and init */
+ rc = bnx2x_vf_op_prep(bp, vfidx, &vf, &bulletin, true);
+ if (rc)
+ return rc;
+
+ mutex_lock(&bp->vfdb->bulletin_mutex);
+
/* update PF's copy of the VF's bulletin. Will no longer accept mac
* configuration requests from vf unless match this mac
*/
@@ -2652,6 +2766,10 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
/* Post update on VF's bulletin board */
rc = bnx2x_post_vf_bulletin(bp, vfidx);
+
+ /* release lock before checking return code */
+ mutex_unlock(&bp->vfdb->bulletin_mutex);
+
if (rc) {
BNX2X_ERR("failed to update VF[%d] bulletin\n", vfidx);
return rc;
@@ -2716,11 +2834,6 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
unsigned long accept_flags;
int rc;
- /* sanity and init */
- rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
- if (rc)
- return rc;
-
if (vlan > 4095) {
BNX2X_ERR("illegal vlan value %d\n", vlan);
return -EINVAL;
@@ -2729,18 +2842,27 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n",
vfidx, vlan, 0);
+ /* sanity and init */
+ rc = bnx2x_vf_op_prep(bp, vfidx, &vf, &bulletin, true);
+ if (rc)
+ return rc;
+
/* update PF's copy of the VF's bulletin. No point in posting the vlan
* to the VF since it doesn't have anything to do with it. But it useful
* to store it here in case the VF is not up yet and we can only
* configure the vlan later when it does. Treat vlan id 0 as remove the
* Host tag.
*/
+ mutex_lock(&bp->vfdb->bulletin_mutex);
+
if (vlan > 0)
bulletin->valid_bitmap |= 1 << VLAN_VALID;
else
bulletin->valid_bitmap &= ~(1 << VLAN_VALID);
bulletin->vlan = vlan;
+ mutex_unlock(&bp->vfdb->bulletin_mutex);
+
/* is vf initialized and queue set up? */
if (vf->state != VF_ENABLED ||
bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj)) !=
@@ -2850,10 +2972,9 @@ out:
* entire bulletin board excluding the crc field itself. Use the length field
* as the Bulletin Board was posted by a PF with possibly a different version
* from the vf which will sample it. Therefore, the length is computed by the
- * PF and the used blindly by the VF.
+ * PF and then used blindly by the VF.
*/
-u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
- struct pf_vf_bulletin_content *bulletin)
+u32 bnx2x_crc_vf_bulletin(struct pf_vf_bulletin_content *bulletin)
{
return crc32(BULLETIN_CRC_SEED,
((u8 *)bulletin) + sizeof(bulletin->crc),
@@ -2863,47 +2984,74 @@ u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
/* Check for new posts on the bulletin board */
enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp)
{
- struct pf_vf_bulletin_content bulletin = bp->pf2vf_bulletin->content;
+ struct pf_vf_bulletin_content *bulletin;
int attempts;
- /* bulletin board hasn't changed since last sample */
- if (bp->old_bulletin.version == bulletin.version)
- return PFVF_BULLETIN_UNCHANGED;
+ /* sampling structure in mid post may result with corrupted data
+ * validate crc to ensure coherency.
+ */
+ for (attempts = 0; attempts < BULLETIN_ATTEMPTS; attempts++) {
+ u32 crc;
- /* validate crc of new bulletin board */
- if (bp->old_bulletin.version != bp->pf2vf_bulletin->content.version) {
- /* sampling structure in mid post may result with corrupted data
- * validate crc to ensure coherency.
- */
- for (attempts = 0; attempts < BULLETIN_ATTEMPTS; attempts++) {
- bulletin = bp->pf2vf_bulletin->content;
- if (bulletin.crc == bnx2x_crc_vf_bulletin(bp,
- &bulletin))
- break;
- BNX2X_ERR("bad crc on bulletin board. Contained %x computed %x\n",
- bulletin.crc,
- bnx2x_crc_vf_bulletin(bp, &bulletin));
- }
- if (attempts >= BULLETIN_ATTEMPTS) {
- BNX2X_ERR("pf to vf bulletin board crc was wrong %d consecutive times. Aborting\n",
- attempts);
- return PFVF_BULLETIN_CRC_ERR;
- }
+ /* sample the bulletin board */
+ memcpy(&bp->shadow_bulletin, bp->pf2vf_bulletin,
+ sizeof(union pf_vf_bulletin));
+
+ crc = bnx2x_crc_vf_bulletin(&bp->shadow_bulletin.content);
+
+ if (bp->shadow_bulletin.content.crc == crc)
+ break;
+
+ BNX2X_ERR("bad crc on bulletin board. Contained %x computed %x\n",
+ bp->shadow_bulletin.content.crc, crc);
+ }
+
+ if (attempts >= BULLETIN_ATTEMPTS) {
+ BNX2X_ERR("pf to vf bulletin board crc was wrong %d consecutive times. Aborting\n",
+ attempts);
+ return PFVF_BULLETIN_CRC_ERR;
}
+ bulletin = &bp->shadow_bulletin.content;
+
+ /* bulletin board hasn't changed since last sample */
+ if (bp->old_bulletin.version == bulletin->version)
+ return PFVF_BULLETIN_UNCHANGED;
/* the mac address in bulletin board is valid and is new */
- if (bulletin.valid_bitmap & 1 << MAC_ADDR_VALID &&
- !ether_addr_equal(bulletin.mac, bp->old_bulletin.mac)) {
+ if (bulletin->valid_bitmap & 1 << MAC_ADDR_VALID &&
+ !ether_addr_equal(bulletin->mac, bp->old_bulletin.mac)) {
/* update new mac to net device */
- memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN);
+ memcpy(bp->dev->dev_addr, bulletin->mac, ETH_ALEN);
+ }
+
+ if (bulletin->valid_bitmap & (1 << LINK_VALID)) {
+ DP(BNX2X_MSG_IOV, "link update speed %d flags %x\n",
+ bulletin->link_speed, bulletin->link_flags);
+
+ bp->vf_link_vars.line_speed = bulletin->link_speed;
+ bp->vf_link_vars.link_report_flags = 0;
+ /* Link is down */
+ if (bulletin->link_flags & VFPF_LINK_REPORT_LINK_DOWN)
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->vf_link_vars.link_report_flags);
+ /* Full DUPLEX */
+ if (bulletin->link_flags & VFPF_LINK_REPORT_FULL_DUPLEX)
+ __set_bit(BNX2X_LINK_REPORT_FD,
+ &bp->vf_link_vars.link_report_flags);
+ /* Rx Flow Control is ON */
+ if (bulletin->link_flags & VFPF_LINK_REPORT_RX_FC_ON)
+ __set_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &bp->vf_link_vars.link_report_flags);
+ /* Tx Flow Control is ON */
+ if (bulletin->link_flags & VFPF_LINK_REPORT_TX_FC_ON)
+ __set_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &bp->vf_link_vars.link_report_flags);
+ __bnx2x_link_report(bp);
}
- /* the vlan in bulletin board is valid and is new */
- if (bulletin.valid_bitmap & 1 << VLAN_VALID)
- memcpy(&bulletin.vlan, &bp->old_bulletin.vlan, VLAN_HLEN);
-
/* copy new bulletin board to bp */
- bp->old_bulletin = bulletin;
+ memcpy(&bp->old_bulletin, bulletin,
+ sizeof(struct pf_vf_bulletin_content));
return PFVF_BULLETIN_UPDATED;
}
@@ -2948,6 +3096,8 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp)
if (!bp->pf2vf_bulletin)
goto alloc_mem_err;
+ bnx2x_vf_bulletin_finalize(&bp->pf2vf_bulletin->content, true);
+
return 0;
alloc_mem_err:
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 96c575e147a5..ca1055f3d8af 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -126,7 +126,11 @@ struct bnx2x_virtf {
#define VF_CACHE_LINE 0x0010
#define VF_CFG_VLAN 0x0020
#define VF_CFG_STATS_COALESCE 0x0040
-
+#define VF_CFG_EXT_BULLETIN 0x0080
+ u8 link_cfg; /* IFLA_VF_LINK_STATE_AUTO
+ * IFLA_VF_LINK_STATE_ENABLE
+ * IFLA_VF_LINK_STATE_DISABLE
+ */
u8 state;
#define VF_FREE 0 /* VF ready to be acquired holds no resc */
#define VF_ACQUIRED 1 /* VF acquired, but not initialized */
@@ -295,22 +299,22 @@ struct bnx2x_vfdb {
#define BP_VFDB(bp) ((bp)->vfdb)
/* vf array */
struct bnx2x_virtf *vfs;
-#define BP_VF(bp, idx) (&((bp)->vfdb->vfs[(idx)]))
-#define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[(idx)].var)
+#define BP_VF(bp, idx) (&((bp)->vfdb->vfs[idx]))
+#define bnx2x_vf(bp, idx, var) ((bp)->vfdb->vfs[idx].var)
/* queue array - for all vfs */
struct bnx2x_vf_queue *vfqs;
/* vf HW contexts */
struct hw_dma context[BNX2X_VF_CIDS/ILT_PAGE_CIDS];
-#define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[(i)])
+#define BP_VF_CXT_PAGE(bp, i) (&(bp)->vfdb->context[i])
/* SR-IOV information */
struct bnx2x_sriov sriov;
struct hw_dma mbx_dma;
#define BP_VF_MBX_DMA(bp) (&((bp)->vfdb->mbx_dma))
struct bnx2x_vf_mbx mbxs[BNX2X_MAX_NUM_OF_VFS];
-#define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[(vfid)]))
+#define BP_VF_MBX(bp, vfid) (&((bp)->vfdb->mbxs[vfid]))
struct hw_dma bulletin_dma;
#define BP_VF_BULLETIN_DMA(bp) (&((bp)->vfdb->bulletin_dma))
@@ -336,6 +340,9 @@ struct bnx2x_vfdb {
/* sp_rtnl synchronization */
struct mutex event_mutex;
u64 event_occur;
+
+ /* bulletin board update synchronization */
+ struct mutex bulletin_mutex;
};
/* queue access */
@@ -467,9 +474,10 @@ void bnx2x_vf_handle_flr_event(struct bnx2x *bp);
bool bnx2x_tlv_supported(u16 tlvtype);
-u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
- struct pf_vf_bulletin_content *bulletin);
+u32 bnx2x_crc_vf_bulletin(struct pf_vf_bulletin_content *bulletin);
int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf);
+void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
+ bool support_long);
enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
@@ -520,6 +528,11 @@ void bnx2x_iov_task(struct work_struct *work);
void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag);
+void bnx2x_iov_link_update(struct bnx2x *bp);
+int bnx2x_iov_link_update_vf(struct bnx2x *bp, int idx);
+
+int bnx2x_set_vf_link_state(struct net_device *dev, int vf, int link_state);
+
#else /* CONFIG_BNX2X_SRIOV */
static inline void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid,
@@ -579,6 +592,14 @@ static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {}
static inline void bnx2x_iov_task(struct work_struct *work) {}
static inline void bnx2x_schedule_iov_task(struct bnx2x *bp, enum bnx2x_iov_flag flag) {}
+static inline void bnx2x_iov_link_update(struct bnx2x *bp) {}
+static inline int bnx2x_iov_link_update_vf(struct bnx2x *bp, int idx) {return 0; }
+
+static inline int bnx2x_set_vf_link_state(struct net_device *dev, int vf,
+ int link_state) {return 0; }
+struct pf_vf_bulletin_content;
+static inline void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
+ bool support_long) {}
#endif /* CONFIG_BNX2X_SRIOV */
#endif /* bnx2x_sriov.h */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index d712d0ddd719..54e0427a9ee6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -251,6 +251,9 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length,
CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv));
+ /* Bulletin support for bulletin board with length > legacy length */
+ req->vfdev_info.caps |= VF_CAP_SUPPORT_EXT_BULLETIN;
+
/* add list termination tlv */
bnx2x_add_tlv(bp, req,
req->first_tlv.tl.length + sizeof(struct channel_tlv),
@@ -1232,6 +1235,41 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
bnx2x_vf_mbx_resp_send_msg(bp, vf, vfop_status);
}
+static bool bnx2x_vf_mbx_is_windows_vm(struct bnx2x *bp,
+ struct vfpf_acquire_tlv *acquire)
+{
+ /* Windows driver does one of three things:
+ * 1. Old driver doesn't have bulletin board address set.
+ * 2. 'Middle' driver sends mc_num == 32.
+ * 3. New driver sets the OS field.
+ */
+ if (!acquire->bulletin_addr ||
+ acquire->resc_request.num_mc_filters == 32 ||
+ ((acquire->vfdev_info.vf_os & VF_OS_MASK) ==
+ VF_OS_WINDOWS))
+ return true;
+
+ return false;
+}
+
+static int bnx2x_vf_mbx_acquire_chk_dorq(struct bnx2x *bp,
+ struct bnx2x_virtf *vf,
+ struct bnx2x_vf_mbx *mbx)
+{
+ /* Linux drivers which correctly set the doorbell size also
+ * send a physical port request
+ */
+ if (bnx2x_search_tlv_list(bp, &mbx->msg->req,
+ CHANNEL_TLV_PHYS_PORT_ID))
+ return 0;
+
+ /* Issue does not exist in windows VMs */
+ if (bnx2x_vf_mbx_is_windows_vm(bp, &mbx->msg->req.acquire))
+ return 0;
+
+ return -EOPNOTSUPP;
+}
+
static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
struct bnx2x_vf_mbx *mbx)
{
@@ -1247,12 +1285,32 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
acquire->resc_request.num_vlan_filters,
acquire->resc_request.num_mc_filters);
+ /* Prevent VFs with old drivers from loading, since they calculate
+ * CIDs incorrectly requiring a VF-flr [VM reboot] in order to recover
+ * while being upgraded.
+ */
+ rc = bnx2x_vf_mbx_acquire_chk_dorq(bp, vf, mbx);
+ if (rc) {
+ DP(BNX2X_MSG_IOV,
+ "VF [%d] - Can't support acquire request due to doorbell mismatch. Please update VM driver\n",
+ vf->abs_vfid);
+ goto out;
+ }
+
/* acquire the resources */
rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request);
/* store address of vf's bulletin board */
vf->bulletin_map = acquire->bulletin_addr;
+ if (acquire->vfdev_info.caps & VF_CAP_SUPPORT_EXT_BULLETIN) {
+ DP(BNX2X_MSG_IOV, "VF[%d] supports long bulletin boards\n",
+ vf->abs_vfid);
+ vf->cfg_flags |= VF_CFG_EXT_BULLETIN;
+ } else {
+ vf->cfg_flags &= ~VF_CFG_EXT_BULLETIN;
+ }
+out:
/* response */
bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc);
}
@@ -1273,6 +1331,10 @@ static void bnx2x_vf_mbx_init_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
if (init->flags & VFPF_INIT_FLG_STATS_COALESCE)
vf->cfg_flags |= VF_CFG_STATS_COALESCE;
+ /* Update VF's view of link state */
+ if (vf->cfg_flags & VF_CFG_EXT_BULLETIN)
+ bnx2x_iov_link_update_vf(bp, vf->index);
+
/* response */
bnx2x_vf_mbx_resp(bp, vf, rc);
}
@@ -2007,6 +2069,17 @@ void bnx2x_vf_mbx(struct bnx2x *bp)
}
}
+void bnx2x_vf_bulletin_finalize(struct pf_vf_bulletin_content *bulletin,
+ bool support_long)
+{
+ /* Older VFs contain a bug where they can't check CRC for bulletin
+ * boards of length greater than legacy size.
+ */
+ bulletin->length = support_long ? BULLETIN_CONTENT_SIZE :
+ BULLETIN_CONTENT_LEGACY_SIZE;
+ bulletin->crc = bnx2x_crc_vf_bulletin(bulletin);
+}
+
/* propagate local bulletin board to vf */
int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
{
@@ -2023,8 +2096,9 @@ int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
/* increment bulletin board version and compute crc */
bulletin->version++;
- bulletin->length = BULLETIN_CONTENT_SIZE;
- bulletin->crc = bnx2x_crc_vf_bulletin(bp, bulletin);
+ bnx2x_vf_bulletin_finalize(bulletin,
+ (bnx2x_vf(bp, vf, cfg_flags) &
+ VF_CFG_EXT_BULLETIN) ? true : false);
/* propagate bulletin board via dmae to vm memory */
rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
index e21e706762c9..15670c499a20 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
@@ -65,6 +65,7 @@ struct hw_sb_info {
#define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008
#define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010
#define BULLETIN_CONTENT_SIZE (sizeof(struct pf_vf_bulletin_content))
+#define BULLETIN_CONTENT_LEGACY_SIZE (32)
#define BULLETIN_ATTEMPTS 5 /* crc failures before throwing towel */
#define BULLETIN_CRC_SEED 0
@@ -117,7 +118,15 @@ struct vfpf_acquire_tlv {
/* the following fields are for debug purposes */
u8 vf_id; /* ME register value */
u8 vf_os; /* e.g. Linux, W2K8 */
- u8 padding[2];
+#define VF_OS_SUBVERSION_MASK (0x1f)
+#define VF_OS_MASK (0xe0)
+#define VF_OS_SHIFT (5)
+#define VF_OS_UNDEFINED (0 << VF_OS_SHIFT)
+#define VF_OS_WINDOWS (1 << VF_OS_SHIFT)
+
+ u8 padding;
+ u8 caps;
+#define VF_CAP_SUPPORT_EXT_BULLETIN (1 << 0)
} vfdev_info;
struct vf_pf_resc_request resc_request;
@@ -393,11 +402,23 @@ struct pf_vf_bulletin_content {
* to attempt to send messages on the
* channel after this bit is set
*/
+#define LINK_VALID 3 /* alert the VF thet a new link status
+ * update is available for it
+ */
u8 mac[ETH_ALEN];
u8 mac_padding[2];
u16 vlan;
u8 vlan_padding[6];
+
+ u16 link_speed; /* Effective line speed */
+ u8 link_speed_padding[6];
+ u32 link_flags; /* VFPF_LINK_REPORT_XXX flags */
+#define VFPF_LINK_REPORT_LINK_DOWN (1 << 0)
+#define VFPF_LINK_REPORT_FULL_DUPLEX (1 << 1)
+#define VFPF_LINK_REPORT_RX_FC_ON (1 << 2)
+#define VFPF_LINK_REPORT_TX_FC_ON (1 << 3)
+ u8 link_flags_padding[4];
};
union pf_vf_bulletin {
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 8244e2b14bb4..27861a6c7ca5 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1,13 +1,15 @@
-/* cnic.c: Broadcom CNIC core network driver.
+/* cnic.c: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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.
*
* Original skeleton written by: John(Zongxi) Chen (zongxi@broadcom.com)
- * Modified and maintained by: Michael Chan <mchan@broadcom.com>
+ * Previously modified and maintained by: Michael Chan <mchan@broadcom.com>
+ * Maintained By: Dept-HSGLinuxNICDev@qlogic.com
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -56,11 +58,11 @@
#define CNIC_MODULE_NAME "cnic"
static char version[] =
- "Broadcom NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
+ "QLogic NetXtreme II CNIC Driver " CNIC_MODULE_NAME " v" CNIC_MODULE_VERSION " (" CNIC_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com> and John(Zongxi) "
"Chen (zongxi@broadcom.com");
-MODULE_DESCRIPTION("Broadcom NetXtreme II CNIC Driver");
+MODULE_DESCRIPTION("QLogic NetXtreme II CNIC Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(CNIC_MODULE_VERSION);
diff --git a/drivers/net/ethernet/broadcom/cnic.h b/drivers/net/ethernet/broadcom/cnic.h
index d535ae4228b4..4baea81bae7a 100644
--- a/drivers/net/ethernet/broadcom/cnic.h
+++ b/drivers/net/ethernet/broadcom/cnic.h
@@ -1,6 +1,7 @@
-/* cnic.h: Broadcom CNIC core network driver.
+/* cnic.h: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h
index dcbca6997e8f..b38499774071 100644
--- a/drivers/net/ethernet/broadcom/cnic_defs.h
+++ b/drivers/net/ethernet/broadcom/cnic_defs.h
@@ -1,7 +1,8 @@
-/* cnic.c: Broadcom CNIC core network driver.
+/* cnic.c: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 5f4d5573a73d..8bb36c1c4d68 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -1,6 +1,7 @@
-/* cnic_if.h: Broadcom CNIC core network driver.
+/* cnic_if.h: QLogic CNIC core network driver.
*
* Copyright (c) 2006-2014 Broadcom Corporation
+ * Copyright (c) 2014 QLogic 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
diff --git a/drivers/net/ethernet/broadcom/genet/Makefile b/drivers/net/ethernet/broadcom/genet/Makefile
index 31f55a90a197..9b6885efa9e7 100644
--- a/drivers/net/ethernet/broadcom/genet/Makefile
+++ b/drivers/net/ethernet/broadcom/genet/Makefile
@@ -1,2 +1,2 @@
obj-$(CONFIG_BCMGENET) += genet.o
-genet-objs := bcmgenet.o bcmmii.o
+genet-objs := bcmgenet.o bcmmii.o bcmgenet_wol.o
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 5ba1cfbd60da..ce455aed5a2f 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -6,15 +6,6 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define pr_fmt(fmt) "bcmgenet: " fmt
@@ -79,13 +70,13 @@
TOTAL_DESC * DMA_DESC_SIZE)
static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv,
- void __iomem *d, u32 value)
+ void __iomem *d, u32 value)
{
__raw_writel(value, d + DMA_DESC_LENGTH_STATUS);
}
static inline u32 dmadesc_get_length_status(struct bcmgenet_priv *priv,
- void __iomem *d)
+ void __iomem *d)
{
return __raw_readl(d + DMA_DESC_LENGTH_STATUS);
}
@@ -98,7 +89,7 @@ static inline void dmadesc_set_addr(struct bcmgenet_priv *priv,
/* Register writes to GISB bus can take couple hundred nanoseconds
* and are done for each packet, save these expensive writes unless
- * the platform is explicitely configured for 64-bits/LPAE.
+ * the platform is explicitly configured for 64-bits/LPAE.
*/
#ifdef CONFIG_PHYS_ADDR_T_64BIT
if (priv->hw_params->flags & GENET_HAS_40BITS)
@@ -108,7 +99,7 @@ static inline void dmadesc_set_addr(struct bcmgenet_priv *priv,
/* Combined address + length/status setter */
static inline void dmadesc_set(struct bcmgenet_priv *priv,
- void __iomem *d, dma_addr_t addr, u32 val)
+ void __iomem *d, dma_addr_t addr, u32 val)
{
dmadesc_set_length_status(priv, d, val);
dmadesc_set_addr(priv, d, addr);
@@ -123,7 +114,7 @@ static inline dma_addr_t dmadesc_get_addr(struct bcmgenet_priv *priv,
/* Register writes to GISB bus can take couple hundred nanoseconds
* and are done for each packet, save these expensive writes unless
- * the platform is explicitely configured for 64-bits/LPAE.
+ * the platform is explicitly configured for 64-bits/LPAE.
*/
#ifdef CONFIG_PHYS_ADDR_T_64BIT
if (priv->hw_params->flags & GENET_HAS_40BITS)
@@ -242,7 +233,7 @@ static inline struct bcmgenet_priv *dev_to_priv(struct device *dev)
}
static inline u32 bcmgenet_tdma_readl(struct bcmgenet_priv *priv,
- enum dma_reg r)
+ enum dma_reg r)
{
return __raw_readl(priv->base + GENET_TDMA_REG_OFF +
DMA_RINGS_SIZE + bcmgenet_dma_regs[r]);
@@ -256,7 +247,7 @@ static inline void bcmgenet_tdma_writel(struct bcmgenet_priv *priv,
}
static inline u32 bcmgenet_rdma_readl(struct bcmgenet_priv *priv,
- enum dma_reg r)
+ enum dma_reg r)
{
return __raw_readl(priv->base + GENET_RDMA_REG_OFF +
DMA_RINGS_SIZE + bcmgenet_dma_regs[r]);
@@ -333,8 +324,8 @@ static const u8 genet_dma_ring_regs_v123[] = {
static const u8 *genet_dma_ring_regs;
static inline u32 bcmgenet_tdma_ring_readl(struct bcmgenet_priv *priv,
- unsigned int ring,
- enum dma_ring_reg r)
+ unsigned int ring,
+ enum dma_ring_reg r)
{
return __raw_readl(priv->base + GENET_TDMA_REG_OFF +
(DMA_RING_SIZE * ring) +
@@ -342,9 +333,8 @@ static inline u32 bcmgenet_tdma_ring_readl(struct bcmgenet_priv *priv,
}
static inline void bcmgenet_tdma_ring_writel(struct bcmgenet_priv *priv,
- unsigned int ring,
- u32 val,
- enum dma_ring_reg r)
+ unsigned int ring, u32 val,
+ enum dma_ring_reg r)
{
__raw_writel(val, priv->base + GENET_TDMA_REG_OFF +
(DMA_RING_SIZE * ring) +
@@ -352,8 +342,8 @@ static inline void bcmgenet_tdma_ring_writel(struct bcmgenet_priv *priv,
}
static inline u32 bcmgenet_rdma_ring_readl(struct bcmgenet_priv *priv,
- unsigned int ring,
- enum dma_ring_reg r)
+ unsigned int ring,
+ enum dma_ring_reg r)
{
return __raw_readl(priv->base + GENET_RDMA_REG_OFF +
(DMA_RING_SIZE * ring) +
@@ -361,9 +351,8 @@ static inline u32 bcmgenet_rdma_ring_readl(struct bcmgenet_priv *priv,
}
static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv,
- unsigned int ring,
- u32 val,
- enum dma_ring_reg r)
+ unsigned int ring, u32 val,
+ enum dma_ring_reg r)
{
__raw_writel(val, priv->base + GENET_RDMA_REG_OFF +
(DMA_RING_SIZE * ring) +
@@ -371,7 +360,7 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv,
}
static int bcmgenet_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
+ struct ethtool_cmd *cmd)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -385,7 +374,7 @@ static int bcmgenet_get_settings(struct net_device *dev,
}
static int bcmgenet_set_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
+ struct ethtool_cmd *cmd)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -458,7 +447,7 @@ static int bcmgenet_set_tx_csum(struct net_device *dev,
}
static int bcmgenet_set_features(struct net_device *dev,
- netdev_features_t features)
+ netdev_features_t features)
{
netdev_features_t changed = features ^ dev->features;
netdev_features_t wanted = dev->wanted_features;
@@ -625,12 +614,11 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = {
#define BCMGENET_STATS_LEN ARRAY_SIZE(bcmgenet_gstrings_stats)
static void bcmgenet_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
+ struct ethtool_drvinfo *info)
{
strlcpy(info->driver, "bcmgenet", sizeof(info->driver));
strlcpy(info->version, "v2.0", sizeof(info->version));
info->n_stats = BCMGENET_STATS_LEN;
-
}
static int bcmgenet_get_sset_count(struct net_device *dev, int string_set)
@@ -643,8 +631,8 @@ static int bcmgenet_get_sset_count(struct net_device *dev, int string_set)
}
}
-static void bcmgenet_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
+static void bcmgenet_get_strings(struct net_device *dev, u32 stringset,
+ u8 *data)
{
int i;
@@ -652,8 +640,8 @@ static void bcmgenet_get_strings(struct net_device *dev,
case ETH_SS_STATS:
for (i = 0; i < BCMGENET_STATS_LEN; i++) {
memcpy(data + i * ETH_GSTRING_LEN,
- bcmgenet_gstrings_stats[i].stat_string,
- ETH_GSTRING_LEN);
+ bcmgenet_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
}
break;
}
@@ -678,8 +666,8 @@ static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv)
case BCMGENET_STAT_RUNT:
if (s->type != BCMGENET_STAT_MIB_RX)
offset = BCMGENET_STAT_OFFSET;
- val = bcmgenet_umac_readl(priv, UMAC_MIB_START +
- j + offset);
+ val = bcmgenet_umac_readl(priv,
+ UMAC_MIB_START + j + offset);
break;
case BCMGENET_STAT_MISC:
val = bcmgenet_umac_readl(priv, s->reg_offset);
@@ -696,8 +684,8 @@ static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv)
}
static void bcmgenet_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats,
- u64 *data)
+ struct ethtool_stats *stats,
+ u64 *data)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
int i;
@@ -730,6 +718,8 @@ static struct ethtool_ops bcmgenet_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = bcmgenet_get_msglevel,
.set_msglevel = bcmgenet_set_msglevel,
+ .get_wol = bcmgenet_get_wol,
+ .set_wol = bcmgenet_set_wol,
};
/* Power down the unimac, based on mode. */
@@ -743,6 +733,10 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv,
phy_detach(priv->phydev);
break;
+ case GENET_POWER_WOL_MAGIC:
+ bcmgenet_wol_power_down_cfg(priv, mode);
+ break;
+
case GENET_POWER_PASSIVE:
/* Power down LED */
bcmgenet_mii_reset(priv->dev);
@@ -759,7 +753,7 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv,
}
static void bcmgenet_power_up(struct bcmgenet_priv *priv,
- enum bcmgenet_power_mode mode)
+ enum bcmgenet_power_mode mode)
{
u32 reg;
@@ -777,6 +771,9 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
/* enable APD */
reg |= EXT_PWR_DN_EN_LD;
break;
+ case GENET_POWER_WOL_MAGIC:
+ bcmgenet_wol_power_up_cfg(priv, mode);
+ return;
default:
break;
}
@@ -841,37 +838,37 @@ static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_priv *priv,
struct bcmgenet_tx_ring *ring)
{
bcmgenet_intrl2_0_writel(priv,
- UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
- INTRL2_CPU_MASK_SET);
+ UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
+ INTRL2_CPU_MASK_SET);
}
static inline void bcmgenet_tx_ring16_int_enable(struct bcmgenet_priv *priv,
struct bcmgenet_tx_ring *ring)
{
bcmgenet_intrl2_0_writel(priv,
- UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
- INTRL2_CPU_MASK_CLEAR);
+ UMAC_IRQ_TXDMA_BDONE | UMAC_IRQ_TXDMA_PDONE,
+ INTRL2_CPU_MASK_CLEAR);
}
static inline void bcmgenet_tx_ring_int_enable(struct bcmgenet_priv *priv,
- struct bcmgenet_tx_ring *ring)
+ struct bcmgenet_tx_ring *ring)
{
- bcmgenet_intrl2_1_writel(priv,
- (1 << ring->index), INTRL2_CPU_MASK_CLEAR);
+ bcmgenet_intrl2_1_writel(priv, (1 << ring->index),
+ INTRL2_CPU_MASK_CLEAR);
priv->int1_mask &= ~(1 << ring->index);
}
static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv,
struct bcmgenet_tx_ring *ring)
{
- bcmgenet_intrl2_1_writel(priv,
- (1 << ring->index), INTRL2_CPU_MASK_SET);
+ bcmgenet_intrl2_1_writel(priv, (1 << ring->index),
+ INTRL2_CPU_MASK_SET);
priv->int1_mask |= (1 << ring->index);
}
/* Unlocked version of the reclaim routine */
static void __bcmgenet_tx_reclaim(struct net_device *dev,
- struct bcmgenet_tx_ring *ring)
+ struct bcmgenet_tx_ring *ring)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
int last_tx_cn, last_c_index, num_tx_bds;
@@ -879,7 +876,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
struct netdev_queue *txq;
unsigned int c_index;
- /* Compute how many buffers are transmited since last xmit call */
+ /* Compute how many buffers are transmitted since last xmit call */
c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX);
txq = netdev_get_tx_queue(dev, ring->queue);
@@ -894,9 +891,9 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
last_tx_cn = num_tx_bds - last_c_index + c_index;
netif_dbg(priv, tx_done, dev,
- "%s ring=%d index=%d last_tx_cn=%d last_index=%d\n",
- __func__, ring->index,
- c_index, last_tx_cn, last_c_index);
+ "%s ring=%d index=%d last_tx_cn=%d last_index=%d\n",
+ __func__, ring->index,
+ c_index, last_tx_cn, last_c_index);
/* Reclaim transmitted buffers */
while (last_tx_cn-- > 0) {
@@ -904,17 +901,17 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
if (tx_cb_ptr->skb) {
dev->stats.tx_bytes += tx_cb_ptr->skb->len;
dma_unmap_single(&dev->dev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- tx_cb_ptr->skb->len,
- DMA_TO_DEVICE);
+ dma_unmap_addr(tx_cb_ptr, dma_addr),
+ tx_cb_ptr->skb->len,
+ DMA_TO_DEVICE);
bcmgenet_free_cb(tx_cb_ptr);
} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
dev->stats.tx_bytes +=
dma_unmap_len(tx_cb_ptr, dma_len);
dma_unmap_page(&dev->dev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- dma_unmap_len(tx_cb_ptr, dma_len),
- DMA_TO_DEVICE);
+ dma_unmap_addr(tx_cb_ptr, dma_addr),
+ dma_unmap_len(tx_cb_ptr, dma_len),
+ DMA_TO_DEVICE);
dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
}
dev->stats.tx_packets++;
@@ -934,7 +931,7 @@ static void __bcmgenet_tx_reclaim(struct net_device *dev,
}
static void bcmgenet_tx_reclaim(struct net_device *dev,
- struct bcmgenet_tx_ring *ring)
+ struct bcmgenet_tx_ring *ring)
{
unsigned long flags;
@@ -1008,11 +1005,11 @@ static int bcmgenet_xmit_single(struct net_device *dev,
return 0;
}
-/* Transmit a SKB fragement */
+/* Transmit a SKB fragment */
static int bcmgenet_xmit_frag(struct net_device *dev,
- skb_frag_t *frag,
- u16 dma_desc_flags,
- struct bcmgenet_tx_ring *ring)
+ skb_frag_t *frag,
+ u16 dma_desc_flags,
+ struct bcmgenet_tx_ring *ring)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = &priv->pdev->dev;
@@ -1027,11 +1024,11 @@ static int bcmgenet_xmit_frag(struct net_device *dev,
tx_cb_ptr->skb = NULL;
mapping = skb_frag_dma_map(kdev, frag, 0,
- skb_frag_size(frag), DMA_TO_DEVICE);
+ skb_frag_size(frag), DMA_TO_DEVICE);
ret = dma_mapping_error(kdev, mapping);
if (ret) {
netif_err(priv, tx_err, dev, "%s: Tx DMA map failed\n",
- __func__);
+ __func__);
return ret;
}
@@ -1039,8 +1036,8 @@ static int bcmgenet_xmit_frag(struct net_device *dev,
dma_unmap_len_set(tx_cb_ptr, dma_len, frag->size);
dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping,
- (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
- (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT));
+ (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
+ (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT));
ring->free_bds -= 1;
@@ -1103,8 +1100,9 @@ static int bcmgenet_put_tx_csum(struct net_device *dev, struct sk_buff *skb)
tx_csum_info |= STATUS_TX_CSUM_LV;
if (ip_proto == IPPROTO_UDP && ip_ver == ETH_P_IP)
tx_csum_info |= STATUS_TX_CSUM_PROTO_UDP;
- } else
+ } else {
tx_csum_info = 0;
+ }
status->tx_csum_info = tx_csum_info;
}
@@ -1144,11 +1142,16 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
if (ring->free_bds <= nr_frags + 1) {
netif_tx_stop_queue(txq);
netdev_err(dev, "%s: tx ring %d full when queue %d awake\n",
- __func__, index, ring->queue);
+ __func__, index, ring->queue);
ret = NETDEV_TX_BUSY;
goto out;
}
+ if (skb_padto(skb, ETH_ZLEN)) {
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
/* set the SKB transmit checksum */
if (priv->desc_64b_en) {
ret = bcmgenet_put_tx_csum(dev, skb);
@@ -1172,8 +1175,9 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
/* xmit fragment */
for (i = 0; i < nr_frags; i++) {
ret = bcmgenet_xmit_frag(dev,
- &skb_shinfo(skb)->frags[i],
- (i == nr_frags - 1) ? DMA_EOP : 0, ring);
+ &skb_shinfo(skb)->frags[i],
+ (i == nr_frags - 1) ? DMA_EOP : 0,
+ ring);
if (ret) {
ret = NETDEV_TX_OK;
goto out;
@@ -1186,7 +1190,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
* producer index, now write it down to the hardware
*/
bcmgenet_tdma_ring_writel(priv, ring->index,
- ring->prod_index, TDMA_PROD_INDEX);
+ ring->prod_index, TDMA_PROD_INDEX);
if (ring->free_bds <= (MAX_SKB_FRAGS + 1)) {
netif_tx_stop_queue(txq);
@@ -1200,16 +1204,14 @@ out:
}
-static int bcmgenet_rx_refill(struct bcmgenet_priv *priv,
- struct enet_cb *cb)
+static int bcmgenet_rx_refill(struct bcmgenet_priv *priv, struct enet_cb *cb)
{
struct device *kdev = &priv->pdev->dev;
struct sk_buff *skb;
dma_addr_t mapping;
int ret;
- skb = netdev_alloc_skb(priv->dev,
- priv->rx_buf_len + SKB_ALIGNMENT);
+ skb = netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT);
if (!skb)
return -ENOMEM;
@@ -1217,12 +1219,12 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv,
WARN_ON(cb->skb != NULL);
cb->skb = skb;
mapping = dma_map_single(kdev, skb->data,
- priv->rx_buf_len, DMA_FROM_DEVICE);
+ priv->rx_buf_len, DMA_FROM_DEVICE);
ret = dma_mapping_error(kdev, mapping);
if (ret) {
bcmgenet_free_cb(cb);
netif_err(priv, rx_err, priv->dev,
- "%s DMA map failed\n", __func__);
+ "%s DMA map failed\n", __func__);
return ret;
}
@@ -1257,8 +1259,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
unsigned int p_index;
unsigned int chksum_ok = 0;
- p_index = bcmgenet_rdma_ring_readl(priv,
- DESC_INDEX, RDMA_PROD_INDEX);
+ p_index = bcmgenet_rdma_ring_readl(priv, DESC_INDEX, RDMA_PROD_INDEX);
p_index &= DMA_P_INDEX_MASK;
if (p_index < priv->rx_c_index)
@@ -1268,11 +1269,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
rxpkttoprocess = p_index - priv->rx_c_index;
netif_dbg(priv, rx_status, dev,
- "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess);
+ "RDMA: rxpkttoprocess=%d\n", rxpkttoprocess);
while ((rxpktprocessed < rxpkttoprocess) &&
- (rxpktprocessed < budget)) {
-
+ (rxpktprocessed < budget)) {
/* Unmap the packet contents such that we can use the
* RSV from the 64 bytes descriptor when enabled and save
* a 32-bits register read
@@ -1280,15 +1280,17 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
cb = &priv->rx_cbs[priv->rx_read_ptr];
skb = cb->skb;
dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
+ priv->rx_buf_len, DMA_FROM_DEVICE);
if (!priv->desc_64b_en) {
- dma_length_status = dmadesc_get_length_status(priv,
- priv->rx_bds +
- (priv->rx_read_ptr *
- DMA_DESC_SIZE));
+ dma_length_status =
+ dmadesc_get_length_status(priv,
+ priv->rx_bds +
+ (priv->rx_read_ptr *
+ DMA_DESC_SIZE));
} else {
struct status_64 *status;
+
status = (struct status_64 *)skb->data;
dma_length_status = status->length_status;
}
@@ -1300,9 +1302,9 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
len = dma_length_status >> DMA_BUFLENGTH_SHIFT;
netif_dbg(priv, rx_status, dev,
- "%s: p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n",
- __func__, p_index, priv->rx_c_index, priv->rx_read_ptr,
- dma_length_status);
+ "%s:p_ind=%d c_ind=%d read_ptr=%d len_stat=0x%08x\n",
+ __func__, p_index, priv->rx_c_index,
+ priv->rx_read_ptr, dma_length_status);
rxpktprocessed++;
@@ -1318,7 +1320,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
netif_err(priv, rx_status, dev,
- "Droping fragmented packet!\n");
+ "dropping fragmented packet!\n");
dev->stats.rx_dropped++;
dev->stats.rx_errors++;
dev_kfree_skb_any(cb->skb);
@@ -1332,7 +1334,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
DMA_RX_LG |
DMA_RX_RXER))) {
netif_err(priv, rx_status, dev, "dma_flag=0x%x\n",
- (unsigned int)dma_flag);
+ (unsigned int)dma_flag);
if (dma_flag & DMA_RX_CRC_ERROR)
dev->stats.rx_crc_errors++;
if (dma_flag & DMA_RX_OV)
@@ -1351,7 +1353,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
} /* error packet */
chksum_ok = (dma_flag & priv->dma_rx_chk_bit) &&
- priv->desc_rxchk_en;
+ priv->desc_rxchk_en;
skb_put(skb, len);
if (priv->desc_64b_en) {
@@ -1408,17 +1410,9 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
if (cb->skb)
continue;
- /* set the DMA descriptor length once and for all
- * it will only change if we support dynamically sizing
- * priv->rx_buf_len, but we do not
- */
- dmadesc_set_length_status(priv, priv->rx_bd_assign_ptr,
- priv->rx_buf_len << DMA_BUFLENGTH_SHIFT);
-
ret = bcmgenet_rx_refill(priv, cb);
if (ret)
break;
-
}
return ret;
@@ -1434,8 +1428,8 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
if (dma_unmap_addr(cb, dma_addr)) {
dma_unmap_single(&priv->dev->dev,
- dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
+ dma_unmap_addr(cb, dma_addr),
+ priv->rx_buf_len, DMA_FROM_DEVICE);
dma_unmap_addr_set(cb, dma_addr, 0);
}
@@ -1444,6 +1438,24 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
}
}
+static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable)
+{
+ u32 reg;
+
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+ /* UniMAC stops on a packet boundary, wait for a full-size packet
+ * to be processed
+ */
+ if (enable == 0)
+ usleep_range(1000, 2000);
+}
+
static int reset_umac(struct bcmgenet_priv *priv)
{
struct device *kdev = &priv->pdev->dev;
@@ -1469,13 +1481,24 @@ static int reset_umac(struct bcmgenet_priv *priv)
if (timeout == 1000) {
dev_err(kdev,
- "timeout waiting for MAC to come out of resetn\n");
+ "timeout waiting for MAC to come out of reset\n");
return -ETIMEDOUT;
}
return 0;
}
+static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
+{
+ /* Mask all interrupts.*/
+ bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
+ bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
+ bcmgenet_intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+ bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
+ bcmgenet_intrl2_1_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
+ bcmgenet_intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+}
+
static int init_umac(struct bcmgenet_priv *priv)
{
struct device *kdev = &priv->pdev->dev;
@@ -1491,7 +1514,8 @@ static int init_umac(struct bcmgenet_priv *priv)
bcmgenet_umac_writel(priv, 0, UMAC_CMD);
/* clear tx/rx counter */
bcmgenet_umac_writel(priv,
- MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT, UMAC_MIB_CTRL);
+ MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT,
+ UMAC_MIB_CTRL);
bcmgenet_umac_writel(priv, 0, UMAC_MIB_CTRL);
bcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
@@ -1504,21 +1528,18 @@ static int init_umac(struct bcmgenet_priv *priv)
if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv))
bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL);
- /* Mask all interrupts.*/
- bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_MASK_SET);
- bcmgenet_intrl2_0_writel(priv, 0xFFFFFFFF, INTRL2_CPU_CLEAR);
- bcmgenet_intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+ bcmgenet_intr_disable(priv);
cpu_mask_clear = UMAC_IRQ_RXDMA_BDONE;
dev_dbg(kdev, "%s:Enabling RXDMA_BDONE interrupt\n", __func__);
- /* Monitor cable plug/unpluged event for internal PHY */
- if (phy_is_internal(priv->phydev))
+ /* Monitor cable plug/unplugged event for internal PHY */
+ if (phy_is_internal(priv->phydev)) {
cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
- else if (priv->ext_phy)
+ } else if (priv->ext_phy) {
cpu_mask_clear |= (UMAC_IRQ_LINK_DOWN | UMAC_IRQ_LINK_UP);
- else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
+ } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
reg = bcmgenet_bp_mc_get(priv);
reg |= BIT(priv->hw_params->bp_in_en_shift);
@@ -1534,8 +1555,7 @@ static int init_umac(struct bcmgenet_priv *priv)
if (priv->hw_params->flags & GENET_HAS_MDIO_INTR)
cpu_mask_clear |= UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR;
- bcmgenet_intrl2_0_writel(priv, cpu_mask_clear,
- INTRL2_CPU_MASK_CLEAR);
+ bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR);
/* Enable rx/tx engine.*/
dev_dbg(kdev, "done init umac\n");
@@ -1584,28 +1604,28 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
bcmgenet_tdma_ring_writel(priv, index, 1, DMA_MBUF_DONE_THRESH);
/* Disable rate control for now */
bcmgenet_tdma_ring_writel(priv, index, flow_period_val,
- TDMA_FLOW_PERIOD);
+ TDMA_FLOW_PERIOD);
/* Unclassified traffic goes to ring 16 */
bcmgenet_tdma_ring_writel(priv, index,
- ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH),
- DMA_RING_BUF_SIZE);
+ ((size << DMA_RING_SIZE_SHIFT) |
+ RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
first_bd = write_ptr;
/* Set start and end address, read and write pointers */
bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
- DMA_START_ADDR);
+ DMA_START_ADDR);
bcmgenet_tdma_ring_writel(priv, index, first_bd * words_per_bd,
- TDMA_READ_PTR);
+ TDMA_READ_PTR);
bcmgenet_tdma_ring_writel(priv, index, first_bd,
- TDMA_WRITE_PTR);
+ TDMA_WRITE_PTR);
bcmgenet_tdma_ring_writel(priv, index, end_ptr * words_per_bd - 1,
- DMA_END_ADDR);
+ DMA_END_ADDR);
}
/* Initialize a RDMA ring */
static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
- unsigned int index, unsigned int size)
+ unsigned int index, unsigned int size)
{
u32 words_per_bd = WORDS_PER_BD(priv);
int ret;
@@ -1616,8 +1636,8 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
priv->rx_bd_assign_index = 0;
priv->rx_c_index = 0;
priv->rx_read_ptr = 0;
- priv->rx_cbs = kzalloc(priv->num_rx_bds * sizeof(struct enet_cb),
- GFP_KERNEL);
+ priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb),
+ GFP_KERNEL);
if (!priv->rx_cbs)
return -ENOMEM;
@@ -1631,14 +1651,15 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_PROD_INDEX);
bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX);
bcmgenet_rdma_ring_writel(priv, index,
- ((size << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH),
- DMA_RING_BUF_SIZE);
+ ((size << DMA_RING_SIZE_SHIFT) |
+ RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
bcmgenet_rdma_ring_writel(priv, index, 0, DMA_START_ADDR);
bcmgenet_rdma_ring_writel(priv, index,
- words_per_bd * size - 1, DMA_END_ADDR);
+ words_per_bd * size - 1, DMA_END_ADDR);
bcmgenet_rdma_ring_writel(priv, index,
- (DMA_FC_THRESH_LO << DMA_XOFF_THRESHOLD_SHIFT) |
- DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH);
+ (DMA_FC_THRESH_LO <<
+ DMA_XOFF_THRESHOLD_SHIFT) |
+ DMA_FC_THRESH_HI, RDMA_XON_XOFF_THRESH);
bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_READ_PTR);
return ret;
@@ -1685,10 +1706,10 @@ static void bcmgenet_init_multiq(struct net_device *dev)
* (ring 16)
*/
bcmgenet_init_tx_ring(priv, i, priv->hw_params->bds_cnt,
- i * priv->hw_params->bds_cnt,
- (i + 1) * priv->hw_params->bds_cnt);
+ i * priv->hw_params->bds_cnt,
+ (i + 1) * priv->hw_params->bds_cnt);
- /* Configure ring as decriptor ring and setup priority */
+ /* Configure ring as descriptor ring and setup priority */
ring_cfg |= 1 << i;
dma_priority |= ((GENET_Q0_PRIORITY + i) <<
(GENET_MAX_MQ_CNT + 1) * i);
@@ -1754,11 +1775,11 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
/* Init tDma */
bcmgenet_tdma_writel(priv, DMA_MAX_BURST_LENGTH, DMA_SCB_BURST_SIZE);
- /* Initialize commont TX ring structures */
+ /* Initialize common TX ring structures */
priv->tx_bds = priv->base + priv->hw_params->tdma_offset;
priv->num_tx_bds = TOTAL_DESC;
- priv->tx_cbs = kzalloc(priv->num_tx_bds * sizeof(struct enet_cb),
- GFP_KERNEL);
+ priv->tx_cbs = kcalloc(priv->num_tx_bds, sizeof(struct enet_cb),
+ GFP_KERNEL);
if (!priv->tx_cbs) {
bcmgenet_fini_dma(priv);
return -ENOMEM;
@@ -1769,8 +1790,9 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv)
/* initialize special ring 16 */
bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_DEFAULT_BD_CNT,
- priv->hw_params->tx_queues * priv->hw_params->bds_cnt,
- TOTAL_DESC);
+ priv->hw_params->tx_queues *
+ priv->hw_params->bds_cnt,
+ TOTAL_DESC);
return 0;
}
@@ -1791,11 +1813,11 @@ static int bcmgenet_poll(struct napi_struct *napi, int budget)
priv->rx_c_index += work_done;
priv->rx_c_index &= DMA_C_INDEX_MASK;
bcmgenet_rdma_ring_writel(priv, DESC_INDEX,
- priv->rx_c_index, RDMA_CONS_INDEX);
+ priv->rx_c_index, RDMA_CONS_INDEX);
if (work_done < budget) {
napi_complete(napi);
- bcmgenet_intrl2_0_writel(priv,
- UMAC_IRQ_RXDMA_BDONE, INTRL2_CPU_MASK_CLEAR);
+ bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE,
+ INTRL2_CPU_MASK_CLEAR);
}
return work_done;
@@ -1809,11 +1831,18 @@ static void bcmgenet_irq_task(struct work_struct *work)
netif_dbg(priv, intr, priv->dev, "%s\n", __func__);
+ if (priv->irq0_stat & UMAC_IRQ_MPD_R) {
+ priv->irq0_stat &= ~UMAC_IRQ_MPD_R;
+ netif_dbg(priv, wol, priv->dev,
+ "magic packet detected, waking up\n");
+ bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
+ }
+
/* Link UP/DOWN event */
if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
- (priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
+ (priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
phy_mac_interrupt(priv->phydev,
- priv->irq0_stat & UMAC_IRQ_LINK_UP);
+ priv->irq0_stat & UMAC_IRQ_LINK_UP);
priv->irq0_stat &= ~(UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN);
}
}
@@ -1828,11 +1857,11 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
priv->irq1_stat =
bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) &
~priv->int1_mask;
- /* clear inerrupts*/
+ /* clear interrupts */
bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR);
netif_dbg(priv, intr, priv->dev,
- "%s: IRQ=0x%x\n", __func__, priv->irq1_stat);
+ "%s: IRQ=0x%x\n", __func__, priv->irq1_stat);
/* Check the MBDONE interrupts.
* packet is done, reclaim descriptors
*/
@@ -1841,7 +1870,7 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
for (index = 0; index < 16; index++) {
if (priv->irq1_stat & (1 << index))
bcmgenet_tx_reclaim(priv->dev,
- &priv->tx_rings[index]);
+ &priv->tx_rings[index]);
}
}
return IRQ_HANDLED;
@@ -1856,11 +1885,11 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
priv->irq0_stat =
bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) &
~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
- /* clear inerrupts*/
+ /* clear interrupts */
bcmgenet_intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
netif_dbg(priv, intr, priv->dev,
- "IRQ=0x%x\n", priv->irq0_stat);
+ "IRQ=0x%x\n", priv->irq0_stat);
if (priv->irq0_stat & (UMAC_IRQ_RXDMA_BDONE | UMAC_IRQ_RXDMA_PDONE)) {
/* We use NAPI(software interrupt throttling, if
@@ -1868,8 +1897,8 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
* Disable interrupt, will be enabled in the poll method.
*/
if (likely(napi_schedule_prep(&priv->napi))) {
- bcmgenet_intrl2_0_writel(priv,
- UMAC_IRQ_RXDMA_BDONE, INTRL2_CPU_MASK_SET);
+ bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_BDONE,
+ INTRL2_CPU_MASK_SET);
__napi_schedule(&priv->napi);
}
}
@@ -1890,7 +1919,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
}
if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
- priv->irq0_stat & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
+ priv->irq0_stat & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
priv->irq0_stat &= ~(UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR);
wake_up(&priv->wq);
}
@@ -1898,6 +1927,15 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t bcmgenet_wol_isr(int irq, void *dev_id)
+{
+ struct bcmgenet_priv *priv = dev_id;
+
+ pm_wakeup_event(&priv->pdev->dev, 0);
+
+ return IRQ_HANDLED;
+}
+
static void bcmgenet_umac_reset(struct bcmgenet_priv *priv)
{
u32 reg;
@@ -1913,7 +1951,7 @@ static void bcmgenet_umac_reset(struct bcmgenet_priv *priv)
}
static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv,
- unsigned char *addr)
+ unsigned char *addr)
{
bcmgenet_umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
(addr[2] << 8) | addr[3], UMAC_MAC0);
@@ -1922,14 +1960,8 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv,
static int bcmgenet_wol_resume(struct bcmgenet_priv *priv)
{
- int ret;
-
/* From WOL-enabled suspend, switch to regular clock */
- clk_disable(priv->clk_wol);
- /* init umac registers to synchronize s/w with h/w */
- ret = init_umac(priv);
- if (ret)
- return ret;
+ clk_disable_unprepare(priv->clk_wol);
phy_init_hw(priv->phydev);
/* Speed settings must be restored */
@@ -1974,6 +2006,23 @@ static void bcmgenet_enable_dma(struct bcmgenet_priv *priv, u32 dma_ctrl)
bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
}
+static void bcmgenet_netif_start(struct net_device *dev)
+{
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+
+ /* Start the network engine */
+ napi_enable(&priv->napi);
+
+ umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
+
+ if (phy_is_internal(priv->phydev))
+ bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
+
+ netif_tx_start_all_queues(dev);
+
+ phy_start(priv->phydev);
+}
+
static int bcmgenet_open(struct net_device *dev)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -1995,18 +2044,14 @@ static int bcmgenet_open(struct net_device *dev)
goto err_clk_disable;
/* disable ethernet MAC while updating its registers */
+ umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
+
+ /* Make sure we reflect the value of CRC_CMD_FWD */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
- reg &= ~(CMD_TX_EN | CMD_RX_EN);
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+ priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
bcmgenet_set_hw_addr(priv, dev->dev_addr);
- if (priv->wol_enabled) {
- ret = bcmgenet_wol_resume(priv);
- if (ret)
- return ret;
- }
-
if (phy_is_internal(priv->phydev)) {
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
reg |= EXT_ENERGY_DET_MASK;
@@ -2027,37 +2072,20 @@ static int bcmgenet_open(struct net_device *dev)
bcmgenet_enable_dma(priv, dma_ctrl);
ret = request_irq(priv->irq0, bcmgenet_isr0, IRQF_SHARED,
- dev->name, priv);
+ dev->name, priv);
if (ret < 0) {
netdev_err(dev, "can't request IRQ %d\n", priv->irq0);
goto err_fini_dma;
}
ret = request_irq(priv->irq1, bcmgenet_isr1, IRQF_SHARED,
- dev->name, priv);
+ dev->name, priv);
if (ret < 0) {
netdev_err(dev, "can't request IRQ %d\n", priv->irq1);
goto err_irq0;
}
- /* Start the network engine */
- napi_enable(&priv->napi);
-
- reg = bcmgenet_umac_readl(priv, UMAC_CMD);
- reg |= (CMD_TX_EN | CMD_RX_EN);
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
-
- /* Make sure we reflect the value of CRC_CMD_FWD */
- priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
-
- device_set_wakeup_capable(&dev->dev, 1);
-
- if (phy_is_internal(priv->phydev))
- bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
-
- netif_tx_start_all_queues(dev);
-
- phy_start(priv->phydev);
+ bcmgenet_netif_start(dev);
return 0;
@@ -2092,8 +2120,7 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
}
if (timeout == DMA_TIMEOUT_VAL) {
- netdev_warn(priv->dev,
- "Timed out while disabling TX DMA\n");
+ netdev_warn(priv->dev, "Timed out while disabling TX DMA\n");
ret = -ETIMEDOUT;
}
@@ -2116,41 +2143,47 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
}
if (timeout == DMA_TIMEOUT_VAL) {
- netdev_warn(priv->dev,
- "Timed out while disabling RX DMA\n");
- ret = -ETIMEDOUT;
+ netdev_warn(priv->dev, "Timed out while disabling RX DMA\n");
+ ret = -ETIMEDOUT;
}
return ret;
}
+static void bcmgenet_netif_stop(struct net_device *dev)
+{
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+
+ netif_tx_stop_all_queues(dev);
+ napi_disable(&priv->napi);
+ phy_stop(priv->phydev);
+
+ bcmgenet_intr_disable(priv);
+
+ /* Wait for pending work items to complete. Since interrupts are
+ * disabled no new work will be scheduled.
+ */
+ cancel_work_sync(&priv->bcmgenet_irq_work);
+}
+
static int bcmgenet_close(struct net_device *dev)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
int ret;
- u32 reg;
netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
- phy_stop(priv->phydev);
+ bcmgenet_netif_stop(dev);
/* Disable MAC receive */
- reg = bcmgenet_umac_readl(priv, UMAC_CMD);
- reg &= ~CMD_RX_EN;
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
-
- netif_tx_stop_all_queues(dev);
+ umac_enable_set(priv, CMD_RX_EN, false);
ret = bcmgenet_dma_teardown(priv);
if (ret)
return ret;
/* Disable MAC transmit. TX DMA disabled have to done before this */
- reg = bcmgenet_umac_readl(priv, UMAC_CMD);
- reg &= ~CMD_TX_EN;
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
-
- napi_disable(&priv->napi);
+ umac_enable_set(priv, CMD_TX_EN, false);
/* tx reclaim */
bcmgenet_tx_reclaim_all(dev);
@@ -2159,18 +2192,9 @@ static int bcmgenet_close(struct net_device *dev)
free_irq(priv->irq0, priv);
free_irq(priv->irq1, priv);
- /* Wait for pending work items to complete - we are stopping
- * the clock now. Since interrupts are disabled, no new work
- * will be scheduled.
- */
- cancel_work_sync(&priv->bcmgenet_irq_work);
-
if (phy_is_internal(priv->phydev))
bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
- if (priv->wol_enabled)
- clk_enable(priv->clk_wol);
-
if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk);
@@ -2199,12 +2223,11 @@ static inline void bcmgenet_set_mdf_addr(struct bcmgenet_priv *priv,
{
u32 reg;
- bcmgenet_umac_writel(priv,
- addr[0] << 8 | addr[1], UMAC_MDF_ADDR + (*i * 4));
- bcmgenet_umac_writel(priv,
- addr[2] << 24 | addr[3] << 16 |
- addr[4] << 8 | addr[5],
- UMAC_MDF_ADDR + ((*i + 1) * 4));
+ bcmgenet_umac_writel(priv, addr[0] << 8 | addr[1],
+ UMAC_MDF_ADDR + (*i * 4));
+ bcmgenet_umac_writel(priv, addr[2] << 24 | addr[3] << 16 |
+ addr[4] << 8 | addr[5],
+ UMAC_MDF_ADDR + ((*i + 1) * 4));
reg = bcmgenet_umac_readl(priv, UMAC_MDF_CTRL);
reg |= (1 << (MAX_MC_COUNT - *mc));
bcmgenet_umac_writel(priv, reg, UMAC_MDF_CTRL);
@@ -2221,7 +2244,7 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)
netif_dbg(priv, hw, dev, "%s: %08X\n", __func__, dev->flags);
- /* Promiscous mode */
+ /* Promiscuous mode */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (dev->flags & IFF_PROMISC) {
reg |= CMD_PROMISC;
@@ -2401,7 +2424,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
/* Print the GENET core version */
dev_info(&priv->pdev->dev, "GENET " GENET_VER_FMT,
- major, (reg >> 16) & 0x0f, reg & 0xffff);
+ major, (reg >> 16) & 0x0f, reg & 0xffff);
#ifdef CONFIG_PHYS_ADDR_T_64BIT
if (!(params->flags & GENET_HAS_40BITS))
@@ -2457,6 +2480,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
priv->irq0 = platform_get_irq(pdev, 0);
priv->irq1 = platform_get_irq(pdev, 1);
+ priv->wol_irq = platform_get_irq(pdev, 2);
if (!priv->irq0 || !priv->irq1) {
dev_err(&pdev->dev, "can't find IRQs\n");
err = -EINVAL;
@@ -2491,6 +2515,13 @@ static int bcmgenet_probe(struct platform_device *pdev)
dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
+ /* Request the WOL interrupt and advertise suspend if available */
+ priv->wol_irq_disabled = true;
+ err = devm_request_irq(&pdev->dev, priv->wol_irq, bcmgenet_wol_isr, 0,
+ dev->name, priv);
+ if (!err)
+ device_set_wakeup_capable(&pdev->dev, 1);
+
/* Set the needed headroom to account for any possible
* features enabling/disabling at runtime
*/
@@ -2535,14 +2566,17 @@ static int bcmgenet_probe(struct platform_device *pdev)
netif_set_real_num_tx_queues(priv->dev, priv->hw_params->tx_queues + 1);
netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1);
- err = register_netdev(dev);
- if (err)
- goto err_clk_disable;
+ /* libphy will determine the link state */
+ netif_carrier_off(dev);
/* Turn off the main clock, WOL clock is handled separately */
if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk);
+ err = register_netdev(dev);
+ if (err)
+ goto err;
+
return err;
err_clk_disable:
@@ -2565,6 +2599,111 @@ static int bcmgenet_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int bcmgenet_suspend(struct device *d)
+{
+ struct net_device *dev = dev_get_drvdata(d);
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+ int ret;
+
+ if (!netif_running(dev))
+ return 0;
+
+ bcmgenet_netif_stop(dev);
+
+ netif_device_detach(dev);
+
+ /* Disable MAC receive */
+ umac_enable_set(priv, CMD_RX_EN, false);
+
+ ret = bcmgenet_dma_teardown(priv);
+ if (ret)
+ return ret;
+
+ /* Disable MAC transmit. TX DMA disabled have to done before this */
+ umac_enable_set(priv, CMD_TX_EN, false);
+
+ /* tx reclaim */
+ bcmgenet_tx_reclaim_all(dev);
+ bcmgenet_fini_dma(priv);
+
+ /* Prepare the device for Wake-on-LAN and switch to the slow clock */
+ if (device_may_wakeup(d) && priv->wolopts) {
+ bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
+ clk_prepare_enable(priv->clk_wol);
+ }
+
+ /* Turn off the clocks */
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
+static int bcmgenet_resume(struct device *d)
+{
+ struct net_device *dev = dev_get_drvdata(d);
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+ unsigned long dma_ctrl;
+ int ret;
+ u32 reg;
+
+ if (!netif_running(dev))
+ return 0;
+
+ /* Turn on the clock */
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
+ bcmgenet_umac_reset(priv);
+
+ ret = init_umac(priv);
+ if (ret)
+ goto out_clk_disable;
+
+ if (priv->wolopts)
+ ret = bcmgenet_wol_resume(priv);
+
+ if (ret)
+ goto out_clk_disable;
+
+ /* disable ethernet MAC while updating its registers */
+ umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
+
+ bcmgenet_set_hw_addr(priv, dev->dev_addr);
+
+ if (phy_is_internal(priv->phydev)) {
+ reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
+ reg |= EXT_ENERGY_DET_MASK;
+ bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+ }
+
+ /* Disable RX/TX DMA and flush TX queues */
+ dma_ctrl = bcmgenet_dma_disable(priv);
+
+ /* Reinitialize TDMA and RDMA and SW housekeeping */
+ ret = bcmgenet_init_dma(priv);
+ if (ret) {
+ netdev_err(dev, "failed to initialize DMA\n");
+ goto out_clk_disable;
+ }
+
+ /* Always enable ring 16 - descriptor ring */
+ bcmgenet_enable_dma(priv, dma_ctrl);
+
+ netif_device_attach(dev);
+
+ bcmgenet_netif_start(dev);
+
+ return 0;
+
+out_clk_disable:
+ clk_disable_unprepare(priv->clk);
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(bcmgenet_pm_ops, bcmgenet_suspend, bcmgenet_resume);
static struct platform_driver bcmgenet_driver = {
.probe = bcmgenet_probe,
@@ -2573,6 +2712,7 @@ static struct platform_driver bcmgenet_driver = {
.name = "bcmgenet",
.owner = THIS_MODULE,
.of_match_table = bcmgenet_match,
+ .pm = &bcmgenet_pm_ops,
},
};
module_platform_driver(bcmgenet_driver);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 0f117105fed1..c862d0666771 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -4,18 +4,8 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
-*/
+ */
+
#ifndef __BCMGENET_H__
#define __BCMGENET_H__
@@ -331,9 +321,9 @@ struct bcmgenet_mib_counters {
#define EXT_ENERGY_DET_MASK (1 << 12)
#define EXT_RGMII_OOB_CTRL 0x0C
-#define RGMII_MODE_EN (1 << 0)
#define RGMII_LINK (1 << 4)
#define OOB_DISABLE (1 << 5)
+#define RGMII_MODE_EN (1 << 6)
#define ID_MODE_DIS (1 << 16)
#define EXT_GPHY_CTRL 0x1C
@@ -456,6 +446,7 @@ struct enet_cb {
enum bcmgenet_power_mode {
GENET_POWER_CABLE_SENSE = 0,
GENET_POWER_PASSIVE,
+ GENET_POWER_WOL_MAGIC,
};
struct bcmgenet_priv;
@@ -513,9 +504,9 @@ struct bcmgenet_tx_ring {
unsigned int cb_ptr; /* Tx ring initial CB ptr */
unsigned int end_ptr; /* Tx ring end CB ptr */
void (*int_enable)(struct bcmgenet_priv *priv,
- struct bcmgenet_tx_ring *);
+ struct bcmgenet_tx_ring *);
void (*int_disable)(struct bcmgenet_priv *priv,
- struct bcmgenet_tx_ring *);
+ struct bcmgenet_tx_ring *);
};
/* device context */
@@ -569,6 +560,8 @@ struct bcmgenet_priv {
int irq1;
unsigned int irq0_stat;
unsigned int irq1_stat;
+ int wol_irq;
+ bool wol_irq_disabled;
/* HW descriptors/checksum variables */
bool desc_64b_en;
@@ -583,7 +576,6 @@ struct bcmgenet_priv {
struct platform_device *pdev;
/* WOL */
- unsigned long wol_enabled;
struct clk *clk_wol;
u32 wolopts;
@@ -625,4 +617,12 @@ int bcmgenet_mii_config(struct net_device *dev);
void bcmgenet_mii_exit(struct net_device *dev);
void bcmgenet_mii_reset(struct net_device *dev);
+/* Wake-on-LAN routines */
+void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode);
+void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode);
+
#endif /* __BCMGENET_H__ */
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
new file mode 100644
index 000000000000..b82b7e4e06b2
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -0,0 +1,206 @@
+/*
+ * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
+ *
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "bcmgenet_wol: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/clk.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <net/arp.h>
+
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/phy.h>
+
+#include "bcmgenet.h"
+
+/* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet
+ * Detection is supported through ethtool
+ */
+void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+ wol->wolopts = priv->wolopts;
+ memset(wol->sopass, 0, sizeof(wol->sopass));
+
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_MS);
+ put_unaligned_be16(reg, &wol->sopass[0]);
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_LS);
+ put_unaligned_be32(reg, &wol->sopass[2]);
+ }
+}
+
+/* ethtool function - set WOL (Wake on LAN) settings.
+ * Only for magic packet detection mode.
+ */
+int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bcmgenet_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
+ u32 reg;
+
+ if (!device_can_wakeup(kdev))
+ return -ENOTSUPP;
+
+ if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE))
+ return -EINVAL;
+
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]),
+ UMAC_MPD_PW_MS);
+ bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]),
+ UMAC_MPD_PW_LS);
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+ reg |= MPD_PW_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+ }
+
+ /* Flag the device and relevant IRQ as wakeup capable */
+ if (wol->wolopts) {
+ device_set_wakeup_enable(kdev, 1);
+ enable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = false;
+ } else {
+ device_set_wakeup_enable(kdev, 0);
+ /* Avoid unbalanced disable_irq_wake calls */
+ if (!priv->wol_irq_disabled)
+ disable_irq_wake(priv->wol_irq);
+ priv->wol_irq_disabled = true;
+ }
+
+ priv->wolopts = wol->wolopts;
+
+ return 0;
+}
+
+static int bcmgenet_poll_wol_status(struct bcmgenet_priv *priv)
+{
+ struct net_device *dev = priv->dev;
+ int retries = 0;
+
+ while (!(bcmgenet_rbuf_readl(priv, RBUF_STATUS)
+ & RBUF_STATUS_WOL)) {
+ retries++;
+ if (retries > 5) {
+ netdev_crit(dev, "polling wol mode timeout\n");
+ return -ETIMEDOUT;
+ }
+ mdelay(1);
+ }
+
+ return retries;
+}
+
+int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode)
+{
+ struct net_device *dev = priv->dev;
+ u32 cpu_mask_clear;
+ int retries = 0;
+ u32 reg;
+
+ if (mode != GENET_POWER_WOL_MAGIC) {
+ netif_err(priv, wol, dev, "unsupported mode: %d\n", mode);
+ return -EINVAL;
+ }
+
+ /* disable RX */
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_RX_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+ mdelay(10);
+
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+ reg |= MPD_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+ /* Do not leave UniMAC in MPD mode only */
+ retries = bcmgenet_poll_wol_status(priv);
+ if (retries < 0) {
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+ reg &= ~MPD_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+ return retries;
+ }
+
+ netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n",
+ retries);
+
+ /* Enable CRC forward */
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ priv->crc_fwd_en = 1;
+ reg |= CMD_CRC_FWD;
+
+ /* Receiver must be enabled for WOL MP detection */
+ reg |= CMD_RX_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+ if (priv->hw_params->flags & GENET_HAS_EXT) {
+ reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
+ reg &= ~EXT_ENERGY_DET_MASK;
+ bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
+ }
+
+ /* Enable the MPD interrupt */
+ cpu_mask_clear = UMAC_IRQ_MPD_R;
+
+ bcmgenet_intrl2_0_writel(priv, cpu_mask_clear, INTRL2_CPU_MASK_CLEAR);
+
+ return 0;
+}
+
+void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+ enum bcmgenet_power_mode mode)
+{
+ u32 cpu_mask_set;
+ u32 reg;
+
+ if (mode != GENET_POWER_WOL_MAGIC) {
+ netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
+ return;
+ }
+
+ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
+ reg &= ~MPD_EN;
+ bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
+
+ /* Disable CRC Forward */
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_CRC_FWD;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+ priv->crc_fwd_en = 0;
+
+ /* Stop monitoring magic packet IRQ */
+ cpu_mask_set = UMAC_IRQ_MPD_R;
+
+ /* Stop monitoring magic packet IRQ */
+ bcmgenet_intrl2_0_writel(priv, cpu_mask_set, INTRL2_CPU_MASK_SET);
+}
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index add8d8596084..18961613d385 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -6,15 +6,6 @@
* 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
@@ -44,15 +35,15 @@ static int bcmgenet_mii_read(struct mii_bus *bus, int phy_id, int location)
u32 reg;
bcmgenet_umac_writel(priv, (MDIO_RD | (phy_id << MDIO_PMD_SHIFT) |
- (location << MDIO_REG_SHIFT)), UMAC_MDIO_CMD);
+ (location << MDIO_REG_SHIFT)), UMAC_MDIO_CMD);
/* Start MDIO transaction*/
reg = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
reg |= MDIO_START_BUSY;
bcmgenet_umac_writel(priv, reg, UMAC_MDIO_CMD);
wait_event_timeout(priv->wq,
- !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD)
- & MDIO_START_BUSY),
- HZ / 100);
+ !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD)
+ & MDIO_START_BUSY),
+ HZ / 100);
ret = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
if (ret & MDIO_READ_FAIL)
@@ -63,22 +54,22 @@ static int bcmgenet_mii_read(struct mii_bus *bus, int phy_id, int location)
/* write a value to the MII */
static int bcmgenet_mii_write(struct mii_bus *bus, int phy_id,
- int location, u16 val)
+ int location, u16 val)
{
struct net_device *dev = bus->priv;
struct bcmgenet_priv *priv = netdev_priv(dev);
u32 reg;
bcmgenet_umac_writel(priv, (MDIO_WR | (phy_id << MDIO_PMD_SHIFT) |
- (location << MDIO_REG_SHIFT) | (0xffff & val)),
- UMAC_MDIO_CMD);
+ (location << MDIO_REG_SHIFT) | (0xffff & val)),
+ UMAC_MDIO_CMD);
reg = bcmgenet_umac_readl(priv, UMAC_MDIO_CMD);
reg |= MDIO_START_BUSY;
bcmgenet_umac_writel(priv, reg, UMAC_MDIO_CMD);
wait_event_timeout(priv->wq,
- !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD) &
- MDIO_START_BUSY),
- HZ / 100);
+ !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD) &
+ MDIO_START_BUSY),
+ HZ / 100);
return 0;
}
@@ -136,17 +127,18 @@ static void bcmgenet_mii_setup(struct net_device *dev)
/* pause capability */
if (!phydev->pause)
cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+ }
+ if (status_changed) {
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
CMD_HD_EN |
CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
reg |= cmd_bits;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
- }
- if (status_changed)
phy_print_status(phydev);
+ }
}
void bcmgenet_mii_reset(struct net_device *dev)
@@ -247,7 +239,7 @@ int bcmgenet_mii_config(struct net_device *dev)
phy_name = "external MII";
phydev->supported &= PHY_BASIC_FEATURES;
bcmgenet_sys_writel(priv,
- PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
+ PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
break;
case PHY_INTERFACE_MODE_REVMII:
@@ -283,7 +275,7 @@ int bcmgenet_mii_config(struct net_device *dev)
reg |= RGMII_MODE_EN | id_mode_dis;
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
bcmgenet_sys_writel(priv,
- PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
+ PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
break;
default:
dev_err(kdev, "unknown phy mode: %d\n", priv->phy_interface);
@@ -362,7 +354,7 @@ static int bcmgenet_mii_probe(struct net_device *dev)
priv->mii_bus->irq[phydev->addr] = PHY_POLL;
pr_info("attached PHY at address %d [%s]\n",
- phydev->addr, phydev->drv->name);
+ phydev->addr, phydev->drv->name);
return 0;
}
@@ -387,9 +379,9 @@ static int bcmgenet_mii_alloc(struct bcmgenet_priv *priv)
bus->read = bcmgenet_mii_read;
bus->write = bcmgenet_mii_write;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d",
- priv->pdev->name, priv->pdev->id);
+ priv->pdev->name, priv->pdev->id);
- bus->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
if (!bus->irq) {
mdiobus_free(priv->mii_bus);
return -ENOMEM;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 8afa579e7c40..a3dd5dc64f4c 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -7830,17 +7830,18 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
-/* Use GSO to workaround a rare TSO bug that may be triggered when the
- * TSO header is greater than 80 bytes.
+/* Use GSO to workaround all TSO packets that meet HW bug conditions
+ * indicated in tg3_tx_frag_set()
*/
-static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
+static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
+ struct netdev_queue *txq, struct sk_buff *skb)
{
struct sk_buff *segs, *nskb;
u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
/* Estimate the number of fragments in the worst case */
- if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
- netif_stop_queue(tp->dev);
+ if (unlikely(tg3_tx_avail(tnapi) <= frag_cnt_est)) {
+ netif_tx_stop_queue(txq);
/* netif_tx_stop_queue() must be done before checking
* checking tx index in tg3_tx_avail() below, because in
@@ -7848,13 +7849,14 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
* netif_tx_queue_stopped().
*/
smp_mb();
- if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
+ if (tg3_tx_avail(tnapi) <= frag_cnt_est)
return NETDEV_TX_BUSY;
- netif_wake_queue(tp->dev);
+ netif_tx_wake_queue(txq);
}
- segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6));
+ segs = skb_gso_segment(skb, tp->dev->features &
+ ~(NETIF_F_TSO | NETIF_F_TSO6));
if (IS_ERR(segs) || !segs)
goto tg3_tso_bug_end;
@@ -7930,7 +7932,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!skb_is_gso_v6(skb)) {
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
tg3_flag(tp, TSO_BUG))
- return tg3_tso_bug(tp, skb);
+ return tg3_tso_bug(tp, tnapi, txq, skb);
ip_csum = iph->check;
ip_tot_len = iph->tot_len;
@@ -8061,7 +8063,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
iph->tot_len = ip_tot_len;
}
tcph->check = tcp_csum;
- return tg3_tso_bug(tp, skb);
+ return tg3_tso_bug(tp, tnapi, txq, skb);
}
/* If the workaround fails due to memory/mapping
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 3a77f9ead004..556aab75f490 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -600,9 +600,9 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
prefetch(bnad->netdev);
cq = ccb->sw_q;
- cmpl = &cq[ccb->producer_index];
while (packets < budget) {
+ cmpl = &cq[ccb->producer_index];
if (!cmpl->valid)
break;
/* The 'valid' field is set by the adapter, only after writing
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index 882cad71ad62..d26adac6ab99 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -997,10 +997,8 @@ bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
unsigned long flags = 0;
int ret = 0;
- /* Check if the flash read request is valid */
- if (eeprom->magic != (bnad->pcidev->vendor |
- (bnad->pcidev->device << 16)))
- return -EFAULT;
+ /* Fill the magic value */
+ eeprom->magic = bnad->pcidev->vendor | (bnad->pcidev->device << 16);
/* Query the flash partition based on the offset */
flash_part = bnad_get_flash_partition_by_offset(bnad,
diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c
index 6a68e8d93309..6f72771caea6 100644
--- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c
+++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c
@@ -68,10 +68,8 @@ bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off)
switch (asic_gen) {
case BFI_ASIC_GEN_CT:
return (bfi_image_ct_cna + off);
- break;
case BFI_ASIC_GEN_CT2:
return (bfi_image_ct2_cna + off);
- break;
default:
return NULL;
}
@@ -83,10 +81,8 @@ bfa_cb_image_get_size(enum bfi_asic_gen asic_gen)
switch (asic_gen) {
case BFI_ASIC_GEN_CT:
return bfi_image_ct_cna_size;
- break;
case BFI_ASIC_GEN_CT2:
return bfi_image_ct2_cna_size;
- break;
default:
return 0;
}
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index e9daa072ebb4..ca5d7798b265 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -52,6 +52,9 @@
| MACB_BIT(TXERR))
#define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP))
+#define MACB_MAX_TX_LEN ((unsigned int)((1 << MACB_TX_FRMLEN_SIZE) - 1))
+#define GEM_MAX_TX_LEN ((unsigned int)((1 << GEM_TX_FRMLEN_SIZE) - 1))
+
/*
* Graceful stop timeouts in us. We should allow up to
* 1 frame time (10 Mbits/s, full-duplex, ignoring collisions)
@@ -264,7 +267,8 @@ static void macb_handle_link_change(struct net_device *dev)
reg |= MACB_BIT(FD);
if (phydev->speed == SPEED_100)
reg |= MACB_BIT(SPD);
- if (phydev->speed == SPEED_1000)
+ if (phydev->speed == SPEED_1000 &&
+ bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
reg |= GEM_BIT(GBE);
macb_or_gem_writel(bp, NCFGR, reg);
@@ -337,7 +341,7 @@ static int macb_mii_probe(struct net_device *dev)
}
/* mask with MAC supported features */
- if (macb_is_gem(bp))
+ if (macb_is_gem(bp) && bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
phydev->supported &= PHY_GBIT_FEATURES;
else
phydev->supported &= PHY_BASIC_FEATURES;
@@ -467,6 +471,24 @@ static int macb_halt_tx(struct macb *bp)
return -ETIMEDOUT;
}
+static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb)
+{
+ if (tx_skb->mapping) {
+ if (tx_skb->mapped_as_page)
+ dma_unmap_page(&bp->pdev->dev, tx_skb->mapping,
+ tx_skb->size, DMA_TO_DEVICE);
+ else
+ dma_unmap_single(&bp->pdev->dev, tx_skb->mapping,
+ tx_skb->size, DMA_TO_DEVICE);
+ tx_skb->mapping = 0;
+ }
+
+ if (tx_skb->skb) {
+ dev_kfree_skb_any(tx_skb->skb);
+ tx_skb->skb = NULL;
+ }
+}
+
static void macb_tx_error_task(struct work_struct *work)
{
struct macb *bp = container_of(work, struct macb, tx_error_task);
@@ -504,10 +526,23 @@ static void macb_tx_error_task(struct work_struct *work)
skb = tx_skb->skb;
if (ctrl & MACB_BIT(TX_USED)) {
- netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
- macb_tx_ring_wrap(tail), skb->data);
- bp->stats.tx_packets++;
- bp->stats.tx_bytes += skb->len;
+ /* skb is set for the last buffer of the frame */
+ while (!skb) {
+ macb_tx_unmap(bp, tx_skb);
+ tail++;
+ tx_skb = macb_tx_skb(bp, tail);
+ skb = tx_skb->skb;
+ }
+
+ /* ctrl still refers to the first buffer descriptor
+ * since it's the only one written back by the hardware
+ */
+ if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) {
+ netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
+ macb_tx_ring_wrap(tail), skb->data);
+ bp->stats.tx_packets++;
+ bp->stats.tx_bytes += skb->len;
+ }
} else {
/*
* "Buffers exhausted mid-frame" errors may only happen
@@ -521,10 +556,7 @@ static void macb_tx_error_task(struct work_struct *work)
desc->ctrl = ctrl | MACB_BIT(TX_USED);
}
- dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
- DMA_TO_DEVICE);
- tx_skb->skb = NULL;
- dev_kfree_skb(skb);
+ macb_tx_unmap(bp, tx_skb);
}
/* Make descriptor updates visible to hardware */
@@ -572,20 +604,35 @@ static void macb_tx_interrupt(struct macb *bp)
ctrl = desc->ctrl;
+ /* TX_USED bit is only set by hardware on the very first buffer
+ * descriptor of the transmitted frame.
+ */
if (!(ctrl & MACB_BIT(TX_USED)))
break;
- tx_skb = macb_tx_skb(bp, tail);
- skb = tx_skb->skb;
+ /* Process all buffers of the current transmitted frame */
+ for (;; tail++) {
+ tx_skb = macb_tx_skb(bp, tail);
+ skb = tx_skb->skb;
+
+ /* First, update TX stats if needed */
+ if (skb) {
+ netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
+ macb_tx_ring_wrap(tail), skb->data);
+ bp->stats.tx_packets++;
+ bp->stats.tx_bytes += skb->len;
+ }
- netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
- macb_tx_ring_wrap(tail), skb->data);
- dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
- DMA_TO_DEVICE);
- bp->stats.tx_packets++;
- bp->stats.tx_bytes += skb->len;
- tx_skb->skb = NULL;
- dev_kfree_skb_irq(skb);
+ /* Now we can safely release resources */
+ macb_tx_unmap(bp, tx_skb);
+
+ /* skb is set only for the last buffer of the frame.
+ * WARNING: at this point skb has been freed by
+ * macb_tx_unmap().
+ */
+ if (skb)
+ break;
+ }
}
bp->tx_tail = tail;
@@ -718,6 +765,10 @@ static int gem_rx(struct macb *bp, int budget)
skb->protocol = eth_type_trans(skb, bp->dev);
skb_checksum_none_assert(skb);
+ if (bp->dev->features & NETIF_F_RXCSUM &&
+ !(bp->dev->flags & IFF_PROMISC) &&
+ GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
bp->stats.rx_packets++;
bp->stats.rx_bytes += skb->len;
@@ -1001,15 +1052,145 @@ static void macb_poll_controller(struct net_device *dev)
}
#endif
-static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static inline unsigned int macb_count_tx_descriptors(struct macb *bp,
+ unsigned int len)
+{
+ return (len + bp->max_tx_length - 1) / bp->max_tx_length;
+}
+
+static unsigned int macb_tx_map(struct macb *bp,
+ struct sk_buff *skb)
{
- struct macb *bp = netdev_priv(dev);
dma_addr_t mapping;
- unsigned int len, entry;
+ unsigned int len, entry, i, tx_head = bp->tx_head;
+ struct macb_tx_skb *tx_skb = NULL;
struct macb_dma_desc *desc;
- struct macb_tx_skb *tx_skb;
+ unsigned int offset, size, count = 0;
+ unsigned int f, nr_frags = skb_shinfo(skb)->nr_frags;
+ unsigned int eof = 1;
u32 ctrl;
+
+ /* First, map non-paged data */
+ len = skb_headlen(skb);
+ offset = 0;
+ while (len) {
+ size = min(len, bp->max_tx_length);
+ entry = macb_tx_ring_wrap(tx_head);
+ tx_skb = &bp->tx_skb[entry];
+
+ mapping = dma_map_single(&bp->pdev->dev,
+ skb->data + offset,
+ size, DMA_TO_DEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping))
+ goto dma_error;
+
+ /* Save info to properly release resources */
+ tx_skb->skb = NULL;
+ tx_skb->mapping = mapping;
+ tx_skb->size = size;
+ tx_skb->mapped_as_page = false;
+
+ len -= size;
+ offset += size;
+ count++;
+ tx_head++;
+ }
+
+ /* Then, map paged data from fragments */
+ for (f = 0; f < nr_frags; f++) {
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
+
+ len = skb_frag_size(frag);
+ offset = 0;
+ while (len) {
+ size = min(len, bp->max_tx_length);
+ entry = macb_tx_ring_wrap(tx_head);
+ tx_skb = &bp->tx_skb[entry];
+
+ mapping = skb_frag_dma_map(&bp->pdev->dev, frag,
+ offset, size, DMA_TO_DEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping))
+ goto dma_error;
+
+ /* Save info to properly release resources */
+ tx_skb->skb = NULL;
+ tx_skb->mapping = mapping;
+ tx_skb->size = size;
+ tx_skb->mapped_as_page = true;
+
+ len -= size;
+ offset += size;
+ count++;
+ tx_head++;
+ }
+ }
+
+ /* Should never happen */
+ if (unlikely(tx_skb == NULL)) {
+ netdev_err(bp->dev, "BUG! empty skb!\n");
+ return 0;
+ }
+
+ /* This is the last buffer of the frame: save socket buffer */
+ tx_skb->skb = skb;
+
+ /* Update TX ring: update buffer descriptors in reverse order
+ * to avoid race condition
+ */
+
+ /* Set 'TX_USED' bit in buffer descriptor at tx_head position
+ * to set the end of TX queue
+ */
+ i = tx_head;
+ entry = macb_tx_ring_wrap(i);
+ ctrl = MACB_BIT(TX_USED);
+ desc = &bp->tx_ring[entry];
+ desc->ctrl = ctrl;
+
+ do {
+ i--;
+ entry = macb_tx_ring_wrap(i);
+ tx_skb = &bp->tx_skb[entry];
+ desc = &bp->tx_ring[entry];
+
+ ctrl = (u32)tx_skb->size;
+ if (eof) {
+ ctrl |= MACB_BIT(TX_LAST);
+ eof = 0;
+ }
+ if (unlikely(entry == (TX_RING_SIZE - 1)))
+ ctrl |= MACB_BIT(TX_WRAP);
+
+ /* Set TX buffer descriptor */
+ desc->addr = tx_skb->mapping;
+ /* desc->addr must be visible to hardware before clearing
+ * 'TX_USED' bit in desc->ctrl.
+ */
+ wmb();
+ desc->ctrl = ctrl;
+ } while (i != bp->tx_head);
+
+ bp->tx_head = tx_head;
+
+ return count;
+
+dma_error:
+ netdev_err(bp->dev, "TX DMA map failed\n");
+
+ for (i = bp->tx_head; i != tx_head; i++) {
+ tx_skb = macb_tx_skb(bp, i);
+
+ macb_tx_unmap(bp, tx_skb);
+ }
+
+ return 0;
+}
+
+static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct macb *bp = netdev_priv(dev);
unsigned long flags;
+ unsigned int count, nr_frags, frag_size, f;
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
netdev_vdbg(bp->dev,
@@ -1020,44 +1201,34 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->data, 16, true);
#endif
- len = skb->len;
+ /* Count how many TX buffer descriptors are needed to send this
+ * socket buffer: skb fragments of jumbo frames may need to be
+ * splitted into many buffer descriptors.
+ */
+ count = macb_count_tx_descriptors(bp, skb_headlen(skb));
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ for (f = 0; f < nr_frags; f++) {
+ frag_size = skb_frag_size(&skb_shinfo(skb)->frags[f]);
+ count += macb_count_tx_descriptors(bp, frag_size);
+ }
+
spin_lock_irqsave(&bp->lock, flags);
/* This is a hard error, log it. */
- if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) {
+ if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < count) {
netif_stop_queue(dev);
spin_unlock_irqrestore(&bp->lock, flags);
- netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n",
bp->tx_head, bp->tx_tail);
return NETDEV_TX_BUSY;
}
- entry = macb_tx_ring_wrap(bp->tx_head);
- netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
- mapping = dma_map_single(&bp->pdev->dev, skb->data,
- len, DMA_TO_DEVICE);
- if (dma_mapping_error(&bp->pdev->dev, mapping)) {
+ /* Map socket buffer for DMA transfer */
+ if (!macb_tx_map(bp, skb)) {
dev_kfree_skb_any(skb);
goto unlock;
}
- bp->tx_head++;
- tx_skb = &bp->tx_skb[entry];
- tx_skb->skb = skb;
- tx_skb->mapping = mapping;
- netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
- skb->data, (unsigned long)mapping);
-
- ctrl = MACB_BF(TX_FRMLEN, len);
- ctrl |= MACB_BIT(TX_LAST);
- if (entry == (TX_RING_SIZE - 1))
- ctrl |= MACB_BIT(TX_WRAP);
-
- desc = &bp->tx_ring[entry];
- desc->addr = mapping;
- desc->ctrl = ctrl;
-
/* Make newly initialized descriptor visible to hardware */
wmb();
@@ -1342,7 +1513,7 @@ static u32 macb_dbw(struct macb *bp)
/*
* Configure the receive DMA engine
* - use the correct receive buffer size
- * - set the possibility to use INCR16 bursts
+ * - set best burst length for DMA operations
* (if not supported by FIFO, it will fallback to default)
* - set both rx/tx packet buffers to full memory size
* These are configurable parameters for GEM.
@@ -1354,24 +1525,20 @@ static void macb_configure_dma(struct macb *bp)
if (macb_is_gem(bp)) {
dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
- dmacfg |= GEM_BF(FBLDO, 16);
+ if (bp->dma_burst_length)
+ dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg);
dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
dmacfg &= ~GEM_BIT(ENDIA);
+ if (bp->dev->features & NETIF_F_HW_CSUM)
+ dmacfg |= GEM_BIT(TXCOEN);
+ else
+ dmacfg &= ~GEM_BIT(TXCOEN);
+ netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
+ dmacfg);
gem_writel(bp, DMACFG, dmacfg);
}
}
-/*
- * Configure peripheral capacities according to integration options used
- */
-static void macb_configure_caps(struct macb *bp)
-{
- if (macb_is_gem(bp)) {
- if (GEM_BFEXT(IRQCOR, gem_readl(bp, DCFG1)) == 0)
- bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
- }
-}
-
static void macb_init_hw(struct macb *bp)
{
u32 config;
@@ -1386,6 +1553,8 @@ static void macb_init_hw(struct macb *bp)
config |= MACB_BIT(BIG); /* Receive oversized frames */
if (bp->dev->flags & IFF_PROMISC)
config |= MACB_BIT(CAF); /* Copy All Frames */
+ else if (macb_is_gem(bp) && bp->dev->features & NETIF_F_RXCSUM)
+ config |= GEM_BIT(RXCOEN);
if (!(bp->dev->flags & IFF_BROADCAST))
config |= MACB_BIT(NBC); /* No BroadCast */
config |= macb_dbw(bp);
@@ -1394,7 +1563,6 @@ static void macb_init_hw(struct macb *bp)
bp->duplex = DUPLEX_HALF;
macb_configure_dma(bp);
- macb_configure_caps(bp);
/* Initialize TX and RX buffers */
macb_writel(bp, RBQP, bp->rx_ring_dma);
@@ -1500,13 +1668,22 @@ void macb_set_rx_mode(struct net_device *dev)
cfg = macb_readl(bp, NCFGR);
- if (dev->flags & IFF_PROMISC)
+ if (dev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
cfg |= MACB_BIT(CAF);
- else if (dev->flags & (~IFF_PROMISC))
- /* Disable promiscuous mode */
+
+ /* Disable RX checksum offload */
+ if (macb_is_gem(bp))
+ cfg &= ~GEM_BIT(RXCOEN);
+ } else {
+ /* Disable promiscuous mode */
cfg &= ~MACB_BIT(CAF);
+ /* Enable RX checksum offload only if requested */
+ if (macb_is_gem(bp) && dev->features & NETIF_F_RXCSUM)
+ cfg |= GEM_BIT(RXCOEN);
+ }
+
if (dev->flags & IFF_ALLMULTI) {
/* Enable all multicast mode */
macb_or_gem_writel(bp, HRB, -1);
@@ -1767,6 +1944,40 @@ int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
EXPORT_SYMBOL_GPL(macb_ioctl);
+static int macb_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct macb *bp = netdev_priv(netdev);
+ netdev_features_t changed = features ^ netdev->features;
+
+ /* TX checksum offload */
+ if ((changed & NETIF_F_HW_CSUM) && macb_is_gem(bp)) {
+ u32 dmacfg;
+
+ dmacfg = gem_readl(bp, DMACFG);
+ if (features & NETIF_F_HW_CSUM)
+ dmacfg |= GEM_BIT(TXCOEN);
+ else
+ dmacfg &= ~GEM_BIT(TXCOEN);
+ gem_writel(bp, DMACFG, dmacfg);
+ }
+
+ /* RX checksum offload */
+ if ((changed & NETIF_F_RXCSUM) && macb_is_gem(bp)) {
+ u32 netcfg;
+
+ netcfg = gem_readl(bp, NCFGR);
+ if (features & NETIF_F_RXCSUM &&
+ !(netdev->flags & IFF_PROMISC))
+ netcfg |= GEM_BIT(RXCOEN);
+ else
+ netcfg &= ~GEM_BIT(RXCOEN);
+ gem_writel(bp, NCFGR, netcfg);
+ }
+
+ return 0;
+}
+
static const struct net_device_ops macb_netdev_ops = {
.ndo_open = macb_open,
.ndo_stop = macb_close,
@@ -1780,20 +1991,77 @@ static const struct net_device_ops macb_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = macb_poll_controller,
#endif
+ .ndo_set_features = macb_set_features,
};
#if defined(CONFIG_OF)
+static struct macb_config pc302gem_config = {
+ .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
+ .dma_burst_length = 16,
+};
+
+static struct macb_config sama5d3_config = {
+ .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
+ .dma_burst_length = 16,
+};
+
+static struct macb_config sama5d4_config = {
+ .caps = 0,
+ .dma_burst_length = 4,
+};
+
static const struct of_device_id macb_dt_ids[] = {
{ .compatible = "cdns,at32ap7000-macb" },
{ .compatible = "cdns,at91sam9260-macb" },
{ .compatible = "cdns,macb" },
- { .compatible = "cdns,pc302-gem" },
- { .compatible = "cdns,gem" },
+ { .compatible = "cdns,pc302-gem", .data = &pc302gem_config },
+ { .compatible = "cdns,gem", .data = &pc302gem_config },
+ { .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config },
+ { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, macb_dt_ids);
#endif
+/*
+ * Configure peripheral capacities according to device tree
+ * and integration options used
+ */
+static void macb_configure_caps(struct macb *bp)
+{
+ u32 dcfg;
+ const struct of_device_id *match;
+ const struct macb_config *config;
+
+ if (bp->pdev->dev.of_node) {
+ match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node);
+ if (match && match->data) {
+ config = (const struct macb_config *)match->data;
+
+ bp->caps = config->caps;
+ /*
+ * As we have access to the matching node, configure
+ * DMA burst length as well
+ */
+ bp->dma_burst_length = config->dma_burst_length;
+ }
+ }
+
+ if (MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2)
+ bp->caps |= MACB_CAPS_MACB_IS_GEM;
+
+ if (macb_is_gem(bp)) {
+ dcfg = gem_readl(bp, DCFG1);
+ if (GEM_BFEXT(IRQCOR, dcfg) == 0)
+ bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
+ dcfg = gem_readl(bp, DCFG2);
+ if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
+ bp->caps |= MACB_CAPS_FIFO_MODE;
+ }
+
+ netdev_dbg(bp->dev, "Cadence caps 0x%08x\n", bp->caps);
+}
+
static int __init macb_probe(struct platform_device *pdev)
{
struct macb_platform_data *pdata;
@@ -1828,9 +2096,6 @@ static int __init macb_probe(struct platform_device *pdev)
SET_NETDEV_DEV(dev, &pdev->dev);
- /* TODO: Actually, we have some interesting features... */
- dev->features |= 0;
-
bp = netdev_priv(dev);
bp->pdev = pdev;
bp->dev = dev;
@@ -1897,19 +2162,33 @@ static int __init macb_probe(struct platform_device *pdev)
dev->base_addr = regs->start;
+ /* setup capacities */
+ macb_configure_caps(bp);
+
/* setup appropriated routines according to adapter type */
if (macb_is_gem(bp)) {
+ bp->max_tx_length = GEM_MAX_TX_LEN;
bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = gem_init_rings;
bp->macbgem_ops.mog_rx = gem_rx;
} else {
+ bp->max_tx_length = MACB_MAX_TX_LEN;
bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = macb_init_rings;
bp->macbgem_ops.mog_rx = macb_rx;
}
+ /* Set features */
+ dev->hw_features = NETIF_F_SG;
+ /* Checksum offload is only available on gem with packet buffer */
+ if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE))
+ dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+ if (bp->caps & MACB_CAPS_SG_DISABLED)
+ dev->hw_features &= ~NETIF_F_SG;
+ dev->features = dev->hw_features;
+
/* Set MII management clock divider */
config = macb_mdc_clk_div(bp);
config |= macb_dbw(bp);
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 51c02442160a..517c09d72c4a 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -164,6 +164,8 @@
#define GEM_CLK_SIZE 3
#define GEM_DBW_OFFSET 21
#define GEM_DBW_SIZE 2
+#define GEM_RXCOEN_OFFSET 24
+#define GEM_RXCOEN_SIZE 1
/* Constants for data bus width. */
#define GEM_DBW32 0
@@ -305,6 +307,12 @@
#define GEM_DBWDEF_OFFSET 25
#define GEM_DBWDEF_SIZE 3
+/* Bitfields in DCFG2. */
+#define GEM_RX_PKT_BUFF_OFFSET 20
+#define GEM_RX_PKT_BUFF_SIZE 1
+#define GEM_TX_PKT_BUFF_OFFSET 21
+#define GEM_TX_PKT_BUFF_SIZE 1
+
/* Constants for CLK */
#define MACB_CLK_DIV8 0
#define MACB_CLK_DIV16 1
@@ -326,7 +334,11 @@
#define MACB_MAN_CODE 2
/* Capability mask bits */
-#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x1
+#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x00000001
+#define MACB_CAPS_FIFO_MODE 0x10000000
+#define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
+#define MACB_CAPS_SG_DISABLED 0x40000000
+#define MACB_CAPS_MACB_IS_GEM 0x80000000
/* Bit manipulation macros */
#define MACB_BIT(name) \
@@ -442,6 +454,14 @@ struct macb_dma_desc {
#define MACB_RX_BROADCAST_OFFSET 31
#define MACB_RX_BROADCAST_SIZE 1
+/* RX checksum offload disabled: bit 24 clear in NCFGR */
+#define GEM_RX_TYPEID_MATCH_OFFSET 22
+#define GEM_RX_TYPEID_MATCH_SIZE 2
+
+/* RX checksum offload enabled: bit 24 set in NCFGR */
+#define GEM_RX_CSUM_OFFSET 22
+#define GEM_RX_CSUM_SIZE 2
+
#define MACB_TX_FRMLEN_OFFSET 0
#define MACB_TX_FRMLEN_SIZE 11
#define MACB_TX_LAST_OFFSET 15
@@ -459,14 +479,32 @@ struct macb_dma_desc {
#define MACB_TX_USED_OFFSET 31
#define MACB_TX_USED_SIZE 1
+#define GEM_TX_FRMLEN_OFFSET 0
+#define GEM_TX_FRMLEN_SIZE 14
+
+/* Buffer descriptor constants */
+#define GEM_RX_CSUM_NONE 0
+#define GEM_RX_CSUM_IP_ONLY 1
+#define GEM_RX_CSUM_IP_TCP 2
+#define GEM_RX_CSUM_IP_UDP 3
+
+/* limit RX checksum offload to TCP and UDP packets */
+#define GEM_RX_CSUM_CHECKED_MASK 2
+
/**
* struct macb_tx_skb - data about an skb which is being transmitted
- * @skb: skb currently being transmitted
- * @mapping: DMA address of the skb's data buffer
+ * @skb: skb currently being transmitted, only set for the last buffer
+ * of the frame
+ * @mapping: DMA address of the skb's fragment buffer
+ * @size: size of the DMA mapped buffer
+ * @mapped_as_page: true when buffer was mapped with skb_frag_dma_map(),
+ * false when buffer was mapped with dma_map_single()
*/
struct macb_tx_skb {
struct sk_buff *skb;
dma_addr_t mapping;
+ size_t size;
+ bool mapped_as_page;
};
/*
@@ -554,6 +592,11 @@ struct macb_or_gem_ops {
int (*mog_rx)(struct macb *bp, int budget);
};
+struct macb_config {
+ u32 caps;
+ unsigned int dma_burst_length;
+};
+
struct macb {
void __iomem *regs;
@@ -595,6 +638,7 @@ struct macb {
unsigned int duplex;
u32 caps;
+ unsigned int dma_burst_length;
phy_interface_t phy_interface;
@@ -602,6 +646,7 @@ struct macb {
struct sk_buff *skb; /* holds skb until xmit interrupt completes */
dma_addr_t skb_physaddr; /* phys addr from pci_map_single */
int skb_length; /* saved skb length for pci_unmap_single */
+ unsigned int max_tx_length;
};
extern const struct ethtool_ops macb_ethtool_ops;
@@ -615,7 +660,7 @@ void macb_get_hwaddr(struct macb *bp);
static inline bool macb_is_gem(struct macb *bp)
{
- return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2;
+ return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
}
#endif /* _MACB_H */
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
index 570222c33410..c3ce9df0041a 100644
--- a/drivers/net/ethernet/chelsio/Kconfig
+++ b/drivers/net/ethernet/chelsio/Kconfig
@@ -86,6 +86,17 @@ config CHELSIO_T4
To compile this driver as a module choose M here; the module
will be called cxgb4.
+config CHELSIO_T4_DCB
+ bool "Data Center Bridging (DCB) Support for Chelsio T4/T5 cards"
+ default n
+ depends on CHELSIO_T4 && DCB
+ ---help---
+ Enable DCB support through rtNetlink interface.
+ Say Y here if you want to enable Data Center Bridging (DCB) support
+ in the driver.
+
+ If unsure, say N.
+
config CHELSIO_T4VF
tristate "Chelsio Communications T4/T5 Virtual Function Ethernet support"
depends on PCI
diff --git a/drivers/net/ethernet/chelsio/cxgb4/Makefile b/drivers/net/ethernet/chelsio/cxgb4/Makefile
index 498667487f52..1df65c915b99 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/Makefile
+++ b/drivers/net/ethernet/chelsio/cxgb4/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_CHELSIO_T4) += cxgb4.o
cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o
+cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index f503dce4ab17..c9b922cc3e67 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -85,7 +85,8 @@ enum {
MEMWIN1_BASE_T5 = 0x52000,
MEMWIN2_APERTURE = 65536,
MEMWIN2_BASE = 0x30000,
- MEMWIN2_BASE_T5 = 0x54000,
+ MEMWIN2_APERTURE_T5 = 131072,
+ MEMWIN2_BASE_T5 = 0x60000,
};
enum dev_master {
@@ -309,6 +310,9 @@ struct adapter_params {
unsigned int ofldq_wr_cred;
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
+
+ unsigned int max_ordird_qp; /* Max read depth per RDMA QP */
+ unsigned int max_ird_adapter; /* Max read depth per adapter */
};
#include "t4fw_api.h"
@@ -373,6 +377,8 @@ enum {
struct adapter;
struct sge_rspq;
+#include "cxgb4_dcb.h"
+
struct port_info {
struct adapter *adapter;
u16 viid;
@@ -389,6 +395,9 @@ struct port_info {
u8 rss_mode;
struct link_config link_cfg;
u16 *rss;
+#ifdef CONFIG_CHELSIO_T4_DCB
+ struct port_dcb_info dcb; /* Data Center Bridging support */
+#endif
};
struct dentry;
@@ -603,6 +612,7 @@ struct l2t_data;
struct adapter {
void __iomem *regs;
void __iomem *bar2;
+ u32 t4_bar0;
struct pci_dev *pdev;
struct device *pdev_dev;
unsigned int mbox;
@@ -647,6 +657,7 @@ struct adapter {
struct dentry *debugfs_root;
spinlock_t stats_lock;
+ spinlock_t win0_lock ____cacheline_aligned_in_smp;
};
/* Defined bit width of user definable filter tuples
@@ -855,6 +866,7 @@ void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat);
void *t4_alloc_mem(size_t size);
void t4_free_sge_resources(struct adapter *adap);
+void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q);
irq_handler_t t4_intr_handler(struct adapter *adap);
netdev_tx_t t4_eth_xmit(struct sk_buff *skb, struct net_device *dev);
int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
@@ -941,6 +953,7 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
unsigned int data_reg, u32 *vals, unsigned int nregs,
unsigned int start_idx);
+void t4_hw_pci_read_cfg4(struct adapter *adapter, int reg, u32 *val);
struct fw_filter_wr;
@@ -952,8 +965,17 @@ int t4_wait_dev_ready(struct adapter *adap);
int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc);
int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
-int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
- __be32 *buf);
+
+#define T4_MEMORY_WRITE 0
+#define T4_MEMORY_READ 1
+int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr, u32 len,
+ __be32 *buf, int dir);
+static inline int t4_memory_write(struct adapter *adap, int mtype, u32 addr,
+ u32 len, __be32 *buf)
+{
+ return t4_memory_rw(adap, 0, mtype, addr, len, buf, 0);
+}
+
int t4_seeprom_wp(struct adapter *adapter, bool enable);
int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
@@ -1007,6 +1029,10 @@ int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int nparams, const u32 *params,
const u32 *val);
+int t4_set_params_nosleep(struct adapter *adap, unsigned int mbox,
+ unsigned int pf, unsigned int vf,
+ unsigned int nparams, const u32 *params,
+ const u32 *val);
int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
unsigned int rxqi, unsigned int rxq, unsigned int tc,
@@ -1025,6 +1051,8 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
int idx, const u8 *addr, bool persist, bool add_smt);
int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
bool ucast, u64 vec, bool sleep_ok);
+int t4_enable_vi_params(struct adapter *adap, unsigned int mbox,
+ unsigned int viid, bool rx_en, bool tx_en, bool dcb_en);
int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
bool rx_en, bool tx_en);
int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
@@ -1045,7 +1073,6 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
-int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len);
int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
u32 addr, u32 val);
void t4_sge_decode_idma_state(struct adapter *adapter, int state);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
new file mode 100644
index 000000000000..0d3a9df5be36
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -0,0 +1,971 @@
+/*
+ * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
+ *
+ * Written by Anish Bhatt (anish@chelsio.com)
+ * Casey Leedom (leedom@chelsio.com)
+ *
+ * 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 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 "COPYING".
+ *
+ */
+
+#include "cxgb4.h"
+
+/* Initialize a port's Data Center Bridging state. Typically used after a
+ * Link Down event.
+ */
+void cxgb4_dcb_state_init(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct port_dcb_info *dcb = &pi->dcb;
+
+ memset(dcb, 0, sizeof(struct port_dcb_info));
+ dcb->state = CXGB4_DCB_STATE_START;
+}
+
+/* Finite State machine for Data Center Bridging.
+ */
+void cxgb4_dcb_state_fsm(struct net_device *dev,
+ enum cxgb4_dcb_state_input input)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct port_dcb_info *dcb = &pi->dcb;
+ struct adapter *adap = pi->adapter;
+
+ switch (input) {
+ case CXGB4_DCB_INPUT_FW_DISABLED: {
+ /* Firmware tells us it's not doing DCB */
+ switch (dcb->state) {
+ case CXGB4_DCB_STATE_START: {
+ /* we're going to use Host DCB */
+ dcb->state = CXGB4_DCB_STATE_HOST;
+ dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
+ dcb->enabled = 1;
+ break;
+ }
+
+ case CXGB4_DCB_STATE_HOST: {
+ /* we're alreaady in Host DCB mode */
+ break;
+ }
+
+ default:
+ goto bad_state_transition;
+ }
+ break;
+ }
+
+ case CXGB4_DCB_INPUT_FW_ENABLED: {
+ /* Firmware tells us that it is doing DCB */
+ switch (dcb->state) {
+ case CXGB4_DCB_STATE_START: {
+ /* we're going to use Firmware DCB */
+ dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
+ dcb->supported = CXGB4_DCBX_FW_SUPPORT;
+ break;
+ }
+
+ case CXGB4_DCB_STATE_FW_INCOMPLETE:
+ case CXGB4_DCB_STATE_FW_ALLSYNCED: {
+ /* we're alreaady in firmware DCB mode */
+ break;
+ }
+
+ default:
+ goto bad_state_transition;
+ }
+ break;
+ }
+
+ case CXGB4_DCB_INPUT_FW_INCOMPLETE: {
+ /* Firmware tells us that its DCB state is incomplete */
+ switch (dcb->state) {
+ case CXGB4_DCB_STATE_FW_INCOMPLETE: {
+ /* we're already incomplete */
+ break;
+ }
+
+ case CXGB4_DCB_STATE_FW_ALLSYNCED: {
+ /* We were successfully running with firmware DCB but
+ * now it's telling us that it's in an "incomplete
+ * state. We need to reset back to a ground state
+ * of incomplete.
+ */
+ cxgb4_dcb_state_init(dev);
+ dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
+ dcb->supported = CXGB4_DCBX_FW_SUPPORT;
+ linkwatch_fire_event(dev);
+ break;
+ }
+
+ default:
+ goto bad_state_transition;
+ }
+ break;
+ }
+
+ case CXGB4_DCB_INPUT_FW_ALLSYNCED: {
+ /* Firmware tells us that its DCB state is complete */
+ switch (dcb->state) {
+ case CXGB4_DCB_STATE_FW_INCOMPLETE: {
+ dcb->state = CXGB4_DCB_STATE_FW_ALLSYNCED;
+ dcb->enabled = 1;
+ linkwatch_fire_event(dev);
+ break;
+ }
+
+ case CXGB4_DCB_STATE_FW_ALLSYNCED: {
+ /* we're already all sync'ed */
+ break;
+ }
+
+ default:
+ goto bad_state_transition;
+ }
+ break;
+ }
+
+ default:
+ goto bad_state_input;
+ }
+ return;
+
+bad_state_input:
+ dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: illegal input symbol %d\n",
+ input);
+ return;
+
+bad_state_transition:
+ dev_err(adap->pdev_dev, "cxgb4_dcb_state_fsm: bad state transition, state = %d, input = %d\n",
+ dcb->state, input);
+}
+
+/* Handle a DCB/DCBX update message from the firmware.
+ */
+void cxgb4_dcb_handle_fw_update(struct adapter *adap,
+ const struct fw_port_cmd *pcmd)
+{
+ const union fw_port_dcb *fwdcb = &pcmd->u.dcb;
+ int port = FW_PORT_CMD_PORTID_GET(be32_to_cpu(pcmd->op_to_portid));
+ struct net_device *dev = adap->port[port];
+ struct port_info *pi = netdev_priv(dev);
+ struct port_dcb_info *dcb = &pi->dcb;
+ int dcb_type = pcmd->u.dcb.pgid.type;
+
+ /* Handle Firmware DCB Control messages separately since they drive
+ * our state machine.
+ */
+ if (dcb_type == FW_PORT_DCB_TYPE_CONTROL) {
+ enum cxgb4_dcb_state_input input =
+ ((pcmd->u.dcb.control.all_syncd_pkd &
+ FW_PORT_CMD_ALL_SYNCD)
+ ? CXGB4_DCB_STATE_FW_ALLSYNCED
+ : CXGB4_DCB_STATE_FW_INCOMPLETE);
+
+ cxgb4_dcb_state_fsm(dev, input);
+ return;
+ }
+
+ /* It's weird, and almost certainly an error, to get Firmware DCB
+ * messages when we either haven't been told whether we're going to be
+ * doing Host or Firmware DCB; and even worse when we've been told
+ * that we're doing Host DCB!
+ */
+ if (dcb->state == CXGB4_DCB_STATE_START ||
+ dcb->state == CXGB4_DCB_STATE_HOST) {
+ dev_err(adap->pdev_dev, "Receiving Firmware DCB messages in State %d\n",
+ dcb->state);
+ return;
+ }
+
+ /* Now handle the general Firmware DCB update messages ...
+ */
+ switch (dcb_type) {
+ case FW_PORT_DCB_TYPE_PGID:
+ dcb->pgid = be32_to_cpu(fwdcb->pgid.pgid);
+ dcb->msgs |= CXGB4_DCB_FW_PGID;
+ break;
+
+ case FW_PORT_DCB_TYPE_PGRATE:
+ dcb->pg_num_tcs_supported = fwdcb->pgrate.num_tcs_supported;
+ memcpy(dcb->pgrate, &fwdcb->pgrate.pgrate,
+ sizeof(dcb->pgrate));
+ dcb->msgs |= CXGB4_DCB_FW_PGRATE;
+ break;
+
+ case FW_PORT_DCB_TYPE_PRIORATE:
+ memcpy(dcb->priorate, &fwdcb->priorate.strict_priorate,
+ sizeof(dcb->priorate));
+ dcb->msgs |= CXGB4_DCB_FW_PRIORATE;
+ break;
+
+ case FW_PORT_DCB_TYPE_PFC:
+ dcb->pfcen = fwdcb->pfc.pfcen;
+ dcb->pfc_num_tcs_supported = fwdcb->pfc.max_pfc_tcs;
+ dcb->msgs |= CXGB4_DCB_FW_PFC;
+ break;
+
+ case FW_PORT_DCB_TYPE_APP_ID: {
+ const struct fw_port_app_priority *fwap = &fwdcb->app_priority;
+ int idx = fwap->idx;
+ struct app_priority *ap = &dcb->app_priority[idx];
+
+ struct dcb_app app = {
+ .selector = fwap->sel_field,
+ .protocol = be16_to_cpu(fwap->protocolid),
+ .priority = fwap->user_prio_map,
+ };
+ int err;
+
+ err = dcb_setapp(dev, &app);
+ if (err)
+ dev_err(adap->pdev_dev,
+ "Failed DCB Set Application Priority: sel=%d, prot=%d, prio=%d, err=%d\n",
+ app.selector, app.protocol, app.priority, -err);
+
+ ap->user_prio_map = fwap->user_prio_map;
+ ap->sel_field = fwap->sel_field;
+ ap->protocolid = be16_to_cpu(fwap->protocolid);
+ dcb->msgs |= CXGB4_DCB_FW_APP_ID;
+ break;
+ }
+
+ default:
+ dev_err(adap->pdev_dev, "Unknown DCB update type received %x\n",
+ dcb_type);
+ break;
+ }
+}
+
+/* Data Center Bridging netlink operations.
+ */
+
+
+/* Get current DCB enabled/disabled state.
+ */
+static u8 cxgb4_getstate(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ return pi->dcb.enabled;
+}
+
+/* Set DCB enabled/disabled.
+ */
+static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ /* Firmware doesn't provide any mechanism to control the DCB state.
+ */
+ if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
+ return 1;
+
+ return 0;
+}
+
+static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
+ u8 *prio_type, u8 *pgid, u8 *bw_per,
+ u8 *up_tc_map, int local)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int err;
+
+ *prio_type = *pgid = *bw_per = *up_tc_map = 0;
+
+ if (local)
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ else
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+
+ pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
+ return;
+ }
+ *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
+
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
+ -err);
+ return;
+ }
+
+ *bw_per = pcmd.u.dcb.pgrate.pgrate[*pgid];
+ *up_tc_map = (1 << tc);
+
+ /* prio_type is link strict */
+ *prio_type = 0x2;
+}
+
+static void cxgb4_getpgtccfg_tx(struct net_device *dev, int tc,
+ u8 *prio_type, u8 *pgid, u8 *bw_per,
+ u8 *up_tc_map)
+{
+ return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 1);
+}
+
+
+static void cxgb4_getpgtccfg_rx(struct net_device *dev, int tc,
+ u8 *prio_type, u8 *pgid, u8 *bw_per,
+ u8 *up_tc_map)
+{
+ return cxgb4_getpgtccfg(dev, tc, prio_type, pgid, bw_per, up_tc_map, 0);
+}
+
+static void cxgb4_setpgtccfg_tx(struct net_device *dev, int tc,
+ u8 prio_type, u8 pgid, u8 bw_per,
+ u8 up_tc_map)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ u32 _pgid;
+ int err;
+
+ if (pgid == DCB_ATTR_VALUE_UNDEFINED)
+ return;
+ if (bw_per == DCB_ATTR_VALUE_UNDEFINED)
+ return;
+
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
+ return;
+ }
+
+ _pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
+ _pgid &= ~(0xF << (tc * 4));
+ _pgid |= pgid << (tc * 4);
+ pcmd.u.dcb.pgid.pgid = cpu_to_be32(_pgid);
+
+ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB write PGID failed with %d\n",
+ -err);
+ return;
+ }
+
+ memset(&pcmd, 0, sizeof(struct fw_port_cmd));
+
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
+ -err);
+ return;
+ }
+
+ pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
+
+ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
+ if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
+ pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS)
+ dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
+ -err);
+}
+
+static void cxgb4_getpgbwgcfg(struct net_device *dev, int pgid, u8 *bw_per,
+ int local)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int err;
+
+ if (local)
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ else
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+
+ pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
+ -err);
+ } else {
+ *bw_per = pcmd.u.dcb.pgrate.pgrate[pgid];
+ }
+}
+
+static void cxgb4_getpgbwgcfg_tx(struct net_device *dev, int pgid, u8 *bw_per)
+{
+ return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 1);
+}
+
+static void cxgb4_getpgbwgcfg_rx(struct net_device *dev, int pgid, u8 *bw_per)
+{
+ return cxgb4_getpgbwgcfg(dev, pgid, bw_per, 0);
+}
+
+static void cxgb4_setpgbwgcfg_tx(struct net_device *dev, int pgid,
+ u8 bw_per)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int err;
+
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
+ -err);
+ return;
+ }
+
+ pcmd.u.dcb.pgrate.pgrate[pgid] = bw_per;
+
+ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
+ if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
+ pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+
+ if (err != FW_PORT_DCB_CFG_SUCCESS)
+ dev_err(adap->pdev_dev, "DCB write PGRATE failed with %d\n",
+ -err);
+}
+
+/* Return whether the specified Traffic Class Priority has Priority Pause
+ * Frames enabled.
+ */
+static void cxgb4_getpfccfg(struct net_device *dev, int priority, u8 *pfccfg)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct port_dcb_info *dcb = &pi->dcb;
+
+ if (dcb->state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
+ priority >= CXGB4_MAX_PRIORITY)
+ *pfccfg = 0;
+ else
+ *pfccfg = (pi->dcb.pfcen >> priority) & 1;
+}
+
+/* Enable/disable Priority Pause Frames for the specified Traffic Class
+ * Priority.
+ */
+static void cxgb4_setpfccfg(struct net_device *dev, int priority, u8 pfccfg)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int err;
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED ||
+ priority >= CXGB4_MAX_PRIORITY)
+ return;
+
+ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
+ if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
+ pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
+
+ pcmd.u.dcb.pfc.type = FW_PORT_DCB_TYPE_PFC;
+ pcmd.u.dcb.pfc.pfcen = pi->dcb.pfcen;
+
+ if (pfccfg)
+ pcmd.u.dcb.pfc.pfcen |= (1 << priority);
+ else
+ pcmd.u.dcb.pfc.pfcen &= (~(1 << priority));
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB PFC write failed with %d\n", -err);
+ return;
+ }
+
+ pi->dcb.pfcen = pcmd.u.dcb.pfc.pfcen;
+}
+
+static u8 cxgb4_setall(struct net_device *dev)
+{
+ return 0;
+}
+
+/* Return DCB capabilities.
+ */
+static u8 cxgb4_getcap(struct net_device *dev, int cap_id, u8 *caps)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ switch (cap_id) {
+ case DCB_CAP_ATTR_PG:
+ case DCB_CAP_ATTR_PFC:
+ *caps = true;
+ break;
+
+ case DCB_CAP_ATTR_PG_TCS:
+ /* 8 priorities for PG represented by bitmap */
+ *caps = 0x80;
+ break;
+
+ case DCB_CAP_ATTR_PFC_TCS:
+ /* 8 priorities for PFC represented by bitmap */
+ *caps = 0x80;
+ break;
+
+ case DCB_CAP_ATTR_GSP:
+ *caps = true;
+ break;
+
+ case DCB_CAP_ATTR_UP2TC:
+ case DCB_CAP_ATTR_BCN:
+ *caps = false;
+ break;
+
+ case DCB_CAP_ATTR_DCBX:
+ *caps = pi->dcb.supported;
+ break;
+
+ default:
+ *caps = false;
+ }
+
+ return 0;
+}
+
+/* Return the number of Traffic Classes for the indicated Traffic Class ID.
+ */
+static int cxgb4_getnumtcs(struct net_device *dev, int tcs_id, u8 *num)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ switch (tcs_id) {
+ case DCB_NUMTCS_ATTR_PG:
+ if (pi->dcb.msgs & CXGB4_DCB_FW_PGRATE)
+ *num = pi->dcb.pg_num_tcs_supported;
+ else
+ *num = 0x8;
+ break;
+
+ case DCB_NUMTCS_ATTR_PFC:
+ *num = 0x8;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Set the number of Traffic Classes supported for the indicated Traffic Class
+ * ID.
+ */
+static int cxgb4_setnumtcs(struct net_device *dev, int tcs_id, u8 num)
+{
+ /* Setting the number of Traffic Classes isn't supported.
+ */
+ return -ENOSYS;
+}
+
+/* Return whether Priority Flow Control is enabled. */
+static u8 cxgb4_getpfcstate(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
+ return false;
+
+ return pi->dcb.pfcen != 0;
+}
+
+/* Enable/disable Priority Flow Control. */
+static void cxgb4_setpfcstate(struct net_device *dev, u8 state)
+{
+ /* We can't enable/disable Priority Flow Control but we also can't
+ * return an error ...
+ */
+}
+
+/* Return the Application User Priority Map associated with the specified
+ * Application ID.
+ */
+static int __cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id,
+ int peer)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int i;
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
+ return 0;
+
+ for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
+ struct fw_port_cmd pcmd;
+ int err;
+
+ if (peer)
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ else
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+
+ pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
+ pcmd.u.dcb.app_priority.idx = i;
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB APP read failed with %d\n",
+ -err);
+ return err;
+ }
+ if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id)
+ return pcmd.u.dcb.app_priority.user_prio_map;
+
+ /* exhausted app list */
+ if (!pcmd.u.dcb.app_priority.protocolid)
+ break;
+ }
+
+ return -EEXIST;
+}
+
+/* Return the Application User Priority Map associated with the specified
+ * Application ID.
+ */
+static int cxgb4_getapp(struct net_device *dev, u8 app_idtype, u16 app_id)
+{
+ return __cxgb4_getapp(dev, app_idtype, app_id, 0);
+}
+
+/* Write a new Application User Priority Map for the specified Application ID
+ */
+static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
+ u8 app_prio)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int i, err;
+
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
+ return -EINVAL;
+
+ /* DCB info gets thrown away on link up */
+ if (!netif_carrier_ok(dev))
+ return -ENOLINK;
+
+ if (app_idtype != DCB_APP_IDTYPE_ETHTYPE &&
+ app_idtype != DCB_APP_IDTYPE_PORTNUM)
+ return -EINVAL;
+
+ for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
+ INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
+ pcmd.u.dcb.app_priority.idx = i;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
+ -err);
+ return err;
+ }
+ if (be16_to_cpu(pcmd.u.dcb.app_priority.protocolid) == app_id) {
+ /* overwrite existing app table */
+ pcmd.u.dcb.app_priority.protocolid = 0;
+ break;
+ }
+ /* find first empty slot */
+ if (!pcmd.u.dcb.app_priority.protocolid)
+ break;
+ }
+
+ if (i == CXGB4_MAX_DCBX_APP_SUPPORTED) {
+ /* no empty slots available */
+ dev_err(adap->pdev_dev, "DCB app table full\n");
+ return -EBUSY;
+ }
+
+ /* write out new app table entry */
+ INIT_PORT_DCB_WRITE_CMD(pcmd, pi->port_id);
+ if (pi->dcb.state == CXGB4_DCB_STATE_HOST)
+ pcmd.op_to_portid |= cpu_to_be32(FW_PORT_CMD_APPLY);
+
+ pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
+ pcmd.u.dcb.app_priority.protocolid = cpu_to_be16(app_id);
+ pcmd.u.dcb.app_priority.sel_field = app_idtype;
+ pcmd.u.dcb.app_priority.user_prio_map = app_prio;
+ pcmd.u.dcb.app_priority.idx = i;
+
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB app table write failed with %d\n",
+ -err);
+ return err;
+ }
+
+ return 0;
+}
+
+/* Return whether IEEE Data Center Bridging has been negotiated.
+ */
+static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+ struct port_dcb_info *dcb = &pi->dcb;
+
+ return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
+ (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
+}
+
+/* Fill in the Application User Priority Map associated with the
+ * specified Application.
+ */
+static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
+{
+ int prio;
+
+ if (!cxgb4_ieee_negotiation_complete(dev))
+ return -EINVAL;
+ if (!(app->selector && app->protocol))
+ return -EINVAL;
+
+ prio = dcb_getapp(dev, app);
+ if (prio == 0) {
+ /* If app doesn't exist in dcb_app table, try firmware
+ * directly.
+ */
+ prio = __cxgb4_getapp(dev, app->selector, app->protocol, 0);
+ }
+
+ app->priority = prio;
+ return 0;
+}
+
+/* Write a new Application User Priority Map for the specified App id. */
+static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
+{
+ if (!cxgb4_ieee_negotiation_complete(dev))
+ return -EINVAL;
+ if (!(app->selector && app->protocol && app->priority))
+ return -EINVAL;
+
+ cxgb4_setapp(dev, app->selector, app->protocol, app->priority);
+ return dcb_setapp(dev, app);
+}
+
+/* Return our DCBX parameters.
+ */
+static u8 cxgb4_getdcbx(struct net_device *dev)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ /* This is already set by cxgb4_set_dcb_caps, so just return it */
+ return pi->dcb.supported;
+}
+
+/* Set our DCBX parameters.
+ */
+static u8 cxgb4_setdcbx(struct net_device *dev, u8 dcb_request)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ /* Filter out requests which exceed our capabilities.
+ */
+ if ((dcb_request & (CXGB4_DCBX_FW_SUPPORT | CXGB4_DCBX_HOST_SUPPORT))
+ != dcb_request)
+ return 1;
+
+ /* Can't set DCBX capabilities if DCBX isn't enabled. */
+ if (!pi->dcb.state)
+ return 1;
+
+ /* There's currently no mechanism to allow for the firmware DCBX
+ * negotiation to be changed from the Host Driver. If the caller
+ * requests exactly the same parameters that we already have then
+ * we'll allow them to be successfully "set" ...
+ */
+ if (dcb_request != pi->dcb.supported)
+ return 1;
+
+ pi->dcb.supported = dcb_request;
+ return 0;
+}
+
+static int cxgb4_getpeer_app(struct net_device *dev,
+ struct dcb_peer_app_info *info, u16 *app_count)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int i, err = 0;
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
+ return 1;
+
+ info->willing = 0;
+ info->error = 0;
+
+ *app_count = 0;
+ for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
+ pcmd.u.dcb.app_priority.idx = *app_count;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
+ -err);
+ return err;
+ }
+
+ /* find first empty slot */
+ if (!pcmd.u.dcb.app_priority.protocolid)
+ break;
+ }
+ *app_count = i;
+ return err;
+}
+
+static int cxgb4_getpeerapp_tbl(struct net_device *dev, struct dcb_app *table)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ int i, err = 0;
+
+ if (pi->dcb.state != CXGB4_DCB_STATE_FW_ALLSYNCED)
+ return 1;
+
+ for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.app_priority.type = FW_PORT_DCB_TYPE_APP_ID;
+ pcmd.u.dcb.app_priority.idx = i;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB app table read failed with %d\n",
+ -err);
+ return err;
+ }
+
+ /* find first empty slot */
+ if (!pcmd.u.dcb.app_priority.protocolid)
+ break;
+
+ table[i].selector = pcmd.u.dcb.app_priority.sel_field;
+ table[i].protocol =
+ be16_to_cpu(pcmd.u.dcb.app_priority.protocolid);
+ table[i].priority = pcmd.u.dcb.app_priority.user_prio_map;
+ }
+ return err;
+}
+
+/* Return Priority Group information.
+ */
+static int cxgb4_cee_peer_getpg(struct net_device *dev, struct cee_pg *pg)
+{
+ struct fw_port_cmd pcmd;
+ struct port_info *pi = netdev2pinfo(dev);
+ struct adapter *adap = pi->adapter;
+ u32 pgid;
+ int i, err;
+
+ /* We're always "willing" -- the Switch Fabric always dictates the
+ * DCBX parameters to us.
+ */
+ pg->willing = true;
+
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
+ return err;
+ }
+ pgid = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
+
+ for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
+ pg->prio_pg[i] = (pgid >> (i * 4)) & 0xF;
+
+ INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
+ pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
+ err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
+ if (err != FW_PORT_DCB_CFG_SUCCESS) {
+ dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
+ -err);
+ return err;
+ }
+
+ for (i = 0; i < CXGB4_MAX_PRIORITY; i++)
+ pg->pg_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
+
+ return 0;
+}
+
+/* Return Priority Flow Control information.
+ */
+static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
+{
+ struct port_info *pi = netdev2pinfo(dev);
+
+ cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
+ pfc->pfc_en = pi->dcb.pfcen;
+
+ return 0;
+}
+
+const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
+ .ieee_getapp = cxgb4_ieee_getapp,
+ .ieee_setapp = cxgb4_ieee_setapp,
+
+ /* CEE std */
+ .getstate = cxgb4_getstate,
+ .setstate = cxgb4_setstate,
+ .getpgtccfgtx = cxgb4_getpgtccfg_tx,
+ .getpgbwgcfgtx = cxgb4_getpgbwgcfg_tx,
+ .getpgtccfgrx = cxgb4_getpgtccfg_rx,
+ .getpgbwgcfgrx = cxgb4_getpgbwgcfg_rx,
+ .setpgtccfgtx = cxgb4_setpgtccfg_tx,
+ .setpgbwgcfgtx = cxgb4_setpgbwgcfg_tx,
+ .setpfccfg = cxgb4_setpfccfg,
+ .getpfccfg = cxgb4_getpfccfg,
+ .setall = cxgb4_setall,
+ .getcap = cxgb4_getcap,
+ .getnumtcs = cxgb4_getnumtcs,
+ .setnumtcs = cxgb4_setnumtcs,
+ .getpfcstate = cxgb4_getpfcstate,
+ .setpfcstate = cxgb4_setpfcstate,
+ .getapp = cxgb4_getapp,
+ .setapp = cxgb4_setapp,
+
+ /* DCBX configuration */
+ .getdcbx = cxgb4_getdcbx,
+ .setdcbx = cxgb4_setdcbx,
+
+ /* peer apps */
+ .peer_getappinfo = cxgb4_getpeer_app,
+ .peer_getapptable = cxgb4_getpeerapp_tbl,
+
+ /* CEE peer */
+ .cee_peer_getpg = cxgb4_cee_peer_getpg,
+ .cee_peer_getpfc = cxgb4_cee_peer_getpfc,
+};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h
new file mode 100644
index 000000000000..1ec1d834e257
--- /dev/null
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
+ *
+ * Written by Anish Bhatt (anish@chelsio.com)
+ *
+ * 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 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 "COPYING".
+ *
+ */
+
+#ifndef __CXGB4_DCB_H
+#define __CXGB4_DCB_H
+
+#include <linux/netdevice.h>
+#include <linux/dcbnl.h>
+#include <net/dcbnl.h>
+
+#ifdef CONFIG_CHELSIO_T4_DCB
+
+#define CXGB4_DCBX_FW_SUPPORT \
+ (DCB_CAP_DCBX_VER_CEE | \
+ DCB_CAP_DCBX_VER_IEEE | \
+ DCB_CAP_DCBX_LLD_MANAGED)
+#define CXGB4_DCBX_HOST_SUPPORT \
+ (DCB_CAP_DCBX_VER_CEE | \
+ DCB_CAP_DCBX_VER_IEEE | \
+ DCB_CAP_DCBX_HOST)
+
+#define CXGB4_MAX_PRIORITY CXGB4_MAX_DCBX_APP_SUPPORTED
+#define CXGB4_MAX_TCS CXGB4_MAX_DCBX_APP_SUPPORTED
+
+#define INIT_PORT_DCB_CMD(__pcmd, __port, __op, __action) \
+ do { \
+ memset(&(__pcmd), 0, sizeof(__pcmd)); \
+ (__pcmd).op_to_portid = \
+ cpu_to_be32(FW_CMD_OP(FW_PORT_CMD) | \
+ FW_CMD_REQUEST | \
+ FW_CMD_##__op | \
+ FW_PORT_CMD_PORTID(__port)); \
+ (__pcmd).action_to_len16 = \
+ cpu_to_be32(FW_PORT_CMD_ACTION(__action) | \
+ FW_LEN16(pcmd)); \
+ } while (0)
+
+#define INIT_PORT_DCB_READ_PEER_CMD(__pcmd, __port) \
+ INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_RECV)
+
+#define INIT_PORT_DCB_READ_LOCAL_CMD(__pcmd, __port) \
+ INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_TRANS)
+
+#define INIT_PORT_DCB_READ_SYNC_CMD(__pcmd, __port) \
+ INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_DET)
+
+#define INIT_PORT_DCB_WRITE_CMD(__pcmd, __port) \
+ INIT_PORT_DCB_CMD(__pcmd, __port, EXEC, FW_PORT_ACTION_L2_DCB_CFG)
+
+/* States we can be in for a port's Data Center Bridging.
+ */
+enum cxgb4_dcb_state {
+ CXGB4_DCB_STATE_START, /* initial unknown state */
+ CXGB4_DCB_STATE_HOST, /* we're using Host DCB (if at all) */
+ CXGB4_DCB_STATE_FW_INCOMPLETE, /* using firmware DCB, incomplete */
+ CXGB4_DCB_STATE_FW_ALLSYNCED, /* using firmware DCB, all sync'ed */
+};
+
+/* Data Center Bridging state input for the Finite State Machine.
+ */
+enum cxgb4_dcb_state_input {
+ /* Input from the firmware.
+ */
+ CXGB4_DCB_INPUT_FW_DISABLED, /* firmware DCB disabled */
+ CXGB4_DCB_INPUT_FW_ENABLED, /* firmware DCB enabled */
+ CXGB4_DCB_INPUT_FW_INCOMPLETE, /* firmware reports incomplete DCB */
+ CXGB4_DCB_INPUT_FW_ALLSYNCED, /* firmware reports all sync'ed */
+
+};
+
+/* Firmware DCB messages that we've received so far ...
+ */
+enum cxgb4_dcb_fw_msgs {
+ CXGB4_DCB_FW_PGID = 0x01,
+ CXGB4_DCB_FW_PGRATE = 0x02,
+ CXGB4_DCB_FW_PRIORATE = 0x04,
+ CXGB4_DCB_FW_PFC = 0x08,
+ CXGB4_DCB_FW_APP_ID = 0x10,
+};
+
+#define CXGB4_MAX_DCBX_APP_SUPPORTED 8
+
+/* Data Center Bridging support;
+ */
+struct port_dcb_info {
+ enum cxgb4_dcb_state state; /* DCB State Machine */
+ enum cxgb4_dcb_fw_msgs msgs; /* DCB Firmware messages received */
+ unsigned int supported; /* OS DCB capabilities supported */
+ bool enabled; /* OS Enabled state */
+
+ /* Cached copies of DCB information sent by the firmware (in Host
+ * Native Endian format).
+ */
+ u32 pgid; /* Priority Group[0..7] */
+ u8 pfcen; /* Priority Flow Control[0..7] */
+ u8 pg_num_tcs_supported; /* max PG Traffic Classes */
+ u8 pfc_num_tcs_supported; /* max PFC Traffic Classes */
+ u8 pgrate[8]; /* Priority Group Rate[0..7] */
+ u8 priorate[8]; /* Priority Rate[0..7] */
+ struct app_priority { /* Application Information */
+ u8 user_prio_map; /* Priority Map bitfield */
+ u8 sel_field; /* Protocol ID interpretation */
+ u16 protocolid; /* Protocol ID */
+ } app_priority[CXGB4_MAX_DCBX_APP_SUPPORTED];
+};
+
+void cxgb4_dcb_state_init(struct net_device *);
+void cxgb4_dcb_state_fsm(struct net_device *, enum cxgb4_dcb_state_input);
+void cxgb4_dcb_handle_fw_update(struct adapter *, const struct fw_port_cmd *);
+void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *);
+extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops;
+
+#define CXGB4_DCB_ENABLED true
+
+#else /* !CONFIG_CHELSIO_T4_DCB */
+
+static inline void cxgb4_dcb_state_init(struct net_device *dev)
+{
+}
+
+#define CXGB4_DCB_ENABLED false
+
+#endif /* !CONFIG_CHELSIO_T4_DCB */
+
+#endif /* __CXGB4_DCB_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a83271cf17c3..1a162d21d8ac 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -67,6 +67,7 @@
#include "t4_regs.h"
#include "t4_msg.h"
#include "t4fw_api.h"
+#include "cxgb4_dcb.h"
#include "l2t.h"
#include <../drivers/net/bonding/bonding.h>
@@ -223,6 +224,17 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0x4008, -1),
CH_DEVICE(0x4009, -1),
CH_DEVICE(0x400a, -1),
+ CH_DEVICE(0x400d, -1),
+ CH_DEVICE(0x400e, -1),
+ CH_DEVICE(0x4080, -1),
+ CH_DEVICE(0x4081, -1),
+ CH_DEVICE(0x4082, -1),
+ CH_DEVICE(0x4083, -1),
+ CH_DEVICE(0x4084, -1),
+ CH_DEVICE(0x4085, -1),
+ CH_DEVICE(0x4086, -1),
+ CH_DEVICE(0x4087, -1),
+ CH_DEVICE(0x4088, -1),
CH_DEVICE(0x4401, 4),
CH_DEVICE(0x4402, 4),
CH_DEVICE(0x4403, 4),
@@ -235,6 +247,15 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
CH_DEVICE(0x440a, 4),
CH_DEVICE(0x440d, 4),
CH_DEVICE(0x440e, 4),
+ CH_DEVICE(0x4480, 4),
+ CH_DEVICE(0x4481, 4),
+ CH_DEVICE(0x4482, 4),
+ CH_DEVICE(0x4483, 4),
+ CH_DEVICE(0x4484, 4),
+ CH_DEVICE(0x4485, 4),
+ CH_DEVICE(0x4486, 4),
+ CH_DEVICE(0x4487, 4),
+ CH_DEVICE(0x4488, 4),
CH_DEVICE(0x5001, 4),
CH_DEVICE(0x5002, 4),
CH_DEVICE(0x5003, 4),
@@ -391,6 +412,17 @@ module_param_array(num_vf, uint, NULL, 0644);
MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
#endif
+/* TX Queue select used to determine what algorithm to use for selecting TX
+ * queue. Select between the kernel provided function (select_queue=0) or user
+ * cxgb_select_queue function (select_queue=1)
+ *
+ * Default: select_queue=0
+ */
+static int select_queue;
+module_param(select_queue, int, 0644);
+MODULE_PARM_DESC(select_queue,
+ "Select between kernel provided method of selecting or driver method of selecting TX queue. Default is kernel method.");
+
/*
* The filter TCAM has a fixed portion and a variable portion. The fixed
* portion can match on source/destination IP IPv4/IPv6 addresses and TCP/UDP
@@ -458,6 +490,42 @@ static void link_report(struct net_device *dev)
}
}
+#ifdef CONFIG_CHELSIO_T4_DCB
+/* Set up/tear down Data Center Bridging Priority mapping for a net device. */
+static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable)
+{
+ struct port_info *pi = netdev_priv(dev);
+ struct adapter *adap = pi->adapter;
+ struct sge_eth_txq *txq = &adap->sge.ethtxq[pi->first_qset];
+ int i;
+
+ /* We use a simple mapping of Port TX Queue Index to DCB
+ * Priority when we're enabling DCB.
+ */
+ for (i = 0; i < pi->nqsets; i++, txq++) {
+ u32 name, value;
+ int err;
+
+ name = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+ FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH) |
+ FW_PARAMS_PARAM_YZ(txq->q.cntxt_id));
+ value = enable ? i : 0xffffffff;
+
+ /* Since we can be called while atomic (from "interrupt
+ * level") we need to issue the Set Parameters Commannd
+ * without sleeping (timeout < 0).
+ */
+ err = t4_set_params_nosleep(adap, adap->mbox, adap->fn, 0, 1,
+ &name, &value);
+
+ if (err)
+ dev_err(adap->pdev_dev,
+ "Can't %s DCB Priority on port %d, TX Queue %d: err=%d\n",
+ enable ? "set" : "unset", pi->port_id, i, -err);
+ }
+}
+#endif /* CONFIG_CHELSIO_T4_DCB */
+
void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
{
struct net_device *dev = adapter->port[port_id];
@@ -466,8 +534,13 @@ void t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat)
if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) {
if (link_stat)
netif_carrier_on(dev);
- else
+ else {
+#ifdef CONFIG_CHELSIO_T4_DCB
+ cxgb4_dcb_state_init(dev);
+ dcb_tx_queue_prio_enable(dev, false);
+#endif /* CONFIG_CHELSIO_T4_DCB */
netif_carrier_off(dev);
+ }
link_report(dev);
}
@@ -600,11 +673,49 @@ static int link_start(struct net_device *dev)
if (ret == 0)
ret = t4_link_start(pi->adapter, mb, pi->tx_chan,
&pi->link_cfg);
- if (ret == 0)
- ret = t4_enable_vi(pi->adapter, mb, pi->viid, true, true);
+ if (ret == 0) {
+ local_bh_disable();
+ ret = t4_enable_vi_params(pi->adapter, mb, pi->viid, true,
+ true, CXGB4_DCB_ENABLED);
+ local_bh_enable();
+ }
+
return ret;
}
+int cxgb4_dcb_enabled(const struct net_device *dev)
+{
+#ifdef CONFIG_CHELSIO_T4_DCB
+ struct port_info *pi = netdev_priv(dev);
+
+ return pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED;
+#else
+ return 0;
+#endif
+}
+EXPORT_SYMBOL(cxgb4_dcb_enabled);
+
+#ifdef CONFIG_CHELSIO_T4_DCB
+/* Handle a Data Center Bridging update message from the firmware. */
+static void dcb_rpl(struct adapter *adap, const struct fw_port_cmd *pcmd)
+{
+ int port = FW_PORT_CMD_PORTID_GET(ntohl(pcmd->op_to_portid));
+ struct net_device *dev = adap->port[port];
+ int old_dcb_enabled = cxgb4_dcb_enabled(dev);
+ int new_dcb_enabled;
+
+ cxgb4_dcb_handle_fw_update(adap, pcmd);
+ new_dcb_enabled = cxgb4_dcb_enabled(dev);
+
+ /* If the DCB has become enabled or disabled on the port then we're
+ * going to need to set up/tear down DCB Priority parameters for the
+ * TX Queues associated with the port.
+ */
+ if (new_dcb_enabled != old_dcb_enabled)
+ dcb_tx_queue_prio_enable(dev, new_dcb_enabled);
+}
+#endif /* CONFIG_CHELSIO_T4_DCB */
+
/* Clear a filter and release any of its resources that we own. This also
* clears the filter's "pending" status.
*/
@@ -709,8 +820,32 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
} else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) {
const struct cpl_fw6_msg *p = (void *)rsp;
- if (p->type == 0)
- t4_handle_fw_rpl(q->adap, p->data);
+#ifdef CONFIG_CHELSIO_T4_DCB
+ const struct fw_port_cmd *pcmd = (const void *)p->data;
+ unsigned int cmd = FW_CMD_OP_GET(ntohl(pcmd->op_to_portid));
+ unsigned int action =
+ FW_PORT_CMD_ACTION_GET(ntohl(pcmd->action_to_len16));
+
+ if (cmd == FW_PORT_CMD &&
+ action == FW_PORT_ACTION_GET_PORT_INFO) {
+ int port = FW_PORT_CMD_PORTID_GET(
+ be32_to_cpu(pcmd->op_to_portid));
+ struct net_device *dev = q->adap->port[port];
+ int state_input = ((pcmd->u.info.dcbxdis_pkd &
+ FW_PORT_CMD_DCBXDIS)
+ ? CXGB4_DCB_INPUT_FW_DISABLED
+ : CXGB4_DCB_INPUT_FW_ENABLED);
+
+ cxgb4_dcb_state_fsm(dev, state_input);
+ }
+
+ if (cmd == FW_PORT_CMD &&
+ action == FW_PORT_ACTION_L2_DCB_CFG)
+ dcb_rpl(q->adap, pcmd);
+ else
+#endif
+ if (p->type == 0)
+ t4_handle_fw_rpl(q->adap, p->data);
} else if (opcode == CPL_L2T_WRITE_RPL) {
const struct cpl_l2t_write_rpl *p = (void *)rsp;
@@ -1290,6 +1425,48 @@ static int del_filter_wr(struct adapter *adapter, int fidx)
return 0;
}
+static u16 cxgb_select_queue(struct net_device *dev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
+{
+ int txq;
+
+#ifdef CONFIG_CHELSIO_T4_DCB
+ /* If a Data Center Bridging has been successfully negotiated on this
+ * link then we'll use the skb's priority to map it to a TX Queue.
+ * The skb's priority is determined via the VLAN Tag Priority Code
+ * Point field.
+ */
+ if (cxgb4_dcb_enabled(dev)) {
+ u16 vlan_tci;
+ int err;
+
+ err = vlan_get_tag(skb, &vlan_tci);
+ if (unlikely(err)) {
+ if (net_ratelimit())
+ netdev_warn(dev,
+ "TX Packet without VLAN Tag on DCB Link\n");
+ txq = 0;
+ } else {
+ txq = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+ }
+ return txq;
+ }
+#endif /* CONFIG_CHELSIO_T4_DCB */
+
+ if (select_queue) {
+ txq = (skb_rx_queue_recorded(skb)
+ ? skb_get_rx_queue(skb)
+ : smp_processor_id());
+
+ while (unlikely(txq >= dev->real_num_tx_queues))
+ txq -= dev->real_num_tx_queues;
+
+ return txq;
+ }
+
+ return fallback(dev, skb) % dev->real_num_tx_queues;
+}
+
static inline int is_offload(const struct adapter *adap)
{
return adap->params.offload;
@@ -2912,6 +3089,8 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
loff_t avail = file_inode(file)->i_size;
unsigned int mem = (uintptr_t)file->private_data & 3;
struct adapter *adap = file->private_data - mem;
+ __be32 *data;
+ int ret;
if (pos < 0)
return -EINVAL;
@@ -2920,29 +3099,24 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count,
if (count > avail - pos)
count = avail - pos;
- while (count) {
- size_t len;
- int ret, ofst;
- __be32 data[16];
+ data = t4_alloc_mem(count);
+ if (!data)
+ return -ENOMEM;
- if ((mem == MEM_MC) || (mem == MEM_MC1))
- ret = t4_mc_read(adap, mem % MEM_MC, pos, data, NULL);
- else
- ret = t4_edc_read(adap, mem, pos, data, NULL);
- if (ret)
- return ret;
+ spin_lock(&adap->win0_lock);
+ ret = t4_memory_rw(adap, 0, mem, pos, count, data, T4_MEMORY_READ);
+ spin_unlock(&adap->win0_lock);
+ if (ret) {
+ t4_free_mem(data);
+ return ret;
+ }
+ ret = copy_to_user(buf, data, count);
- ofst = pos % sizeof(data);
- len = min(count, sizeof(data) - ofst);
- if (copy_to_user(buf, (u8 *)data + ofst, len))
- return -EFAULT;
+ t4_free_mem(data);
+ if (ret)
+ return -EFAULT;
- buf += len;
- pos += len;
- count -= len;
- }
- count = pos - *ppos;
- *ppos = pos;
+ *ppos = pos + count;
return count;
}
@@ -3274,8 +3448,8 @@ static int tid_init(struct tid_info *t)
return 0;
}
-static int cxgb4_clip_get(const struct net_device *dev,
- const struct in6_addr *lip)
+int cxgb4_clip_get(const struct net_device *dev,
+ const struct in6_addr *lip)
{
struct adapter *adap;
struct fw_clip_cmd c;
@@ -3289,9 +3463,10 @@ static int cxgb4_clip_get(const struct net_device *dev,
c.ip_lo = *(__be64 *)(lip->s6_addr + 8);
return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false);
}
+EXPORT_SYMBOL(cxgb4_clip_get);
-static int cxgb4_clip_release(const struct net_device *dev,
- const struct in6_addr *lip)
+int cxgb4_clip_release(const struct net_device *dev,
+ const struct in6_addr *lip)
{
struct adapter *adap;
struct fw_clip_cmd c;
@@ -3305,6 +3480,7 @@ static int cxgb4_clip_release(const struct net_device *dev,
c.ip_lo = *(__be64 *)(lip->s6_addr + 8);
return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, false);
}
+EXPORT_SYMBOL(cxgb4_clip_release);
/**
* cxgb4_create_server - create an IP server
@@ -3603,7 +3779,11 @@ static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
__be64 indices;
int ret;
- ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
+ spin_lock(&adap->win0_lock);
+ ret = t4_memory_rw(adap, 0, MEM_EDC0, addr,
+ sizeof(indices), (__be32 *)&indices,
+ T4_MEMORY_READ);
+ spin_unlock(&adap->win0_lock);
if (!ret) {
*cidx = (be64_to_cpu(indices) >> 25) & 0xffff;
*pidx = (be64_to_cpu(indices) >> 9) & 0xffff;
@@ -3657,6 +3837,85 @@ void cxgb4_enable_db_coalescing(struct net_device *dev)
}
EXPORT_SYMBOL(cxgb4_enable_db_coalescing);
+int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte)
+{
+ struct adapter *adap;
+ u32 offset, memtype, memaddr;
+ u32 edc0_size, edc1_size, mc0_size, mc1_size;
+ u32 edc0_end, edc1_end, mc0_end, mc1_end;
+ int ret;
+
+ adap = netdev2adap(dev);
+
+ offset = ((stag >> 8) * 32) + adap->vres.stag.start;
+
+ /* Figure out where the offset lands in the Memory Type/Address scheme.
+ * This code assumes that the memory is laid out starting at offset 0
+ * with no breaks as: EDC0, EDC1, MC0, MC1. All cards have both EDC0
+ * and EDC1. Some cards will have neither MC0 nor MC1, most cards have
+ * MC0, and some have both MC0 and MC1.
+ */
+ edc0_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM0_BAR)) << 20;
+ edc1_size = EDRAM_SIZE_GET(t4_read_reg(adap, MA_EDRAM1_BAR)) << 20;
+ mc0_size = EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR)) << 20;
+
+ edc0_end = edc0_size;
+ edc1_end = edc0_end + edc1_size;
+ mc0_end = edc1_end + mc0_size;
+
+ if (offset < edc0_end) {
+ memtype = MEM_EDC0;
+ memaddr = offset;
+ } else if (offset < edc1_end) {
+ memtype = MEM_EDC1;
+ memaddr = offset - edc0_end;
+ } else {
+ if (offset < mc0_end) {
+ memtype = MEM_MC0;
+ memaddr = offset - edc1_end;
+ } else if (is_t4(adap->params.chip)) {
+ /* T4 only has a single memory channel */
+ goto err;
+ } else {
+ mc1_size = EXT_MEM_SIZE_GET(
+ t4_read_reg(adap,
+ MA_EXT_MEMORY1_BAR)) << 20;
+ mc1_end = mc0_end + mc1_size;
+ if (offset < mc1_end) {
+ memtype = MEM_MC1;
+ memaddr = offset - mc0_end;
+ } else {
+ /* offset beyond the end of any memory */
+ goto err;
+ }
+ }
+ }
+
+ spin_lock(&adap->win0_lock);
+ ret = t4_memory_rw(adap, 0, memtype, memaddr, 32, tpte, T4_MEMORY_READ);
+ spin_unlock(&adap->win0_lock);
+ return ret;
+
+err:
+ dev_err(adap->pdev_dev, "stag %#x, offset %#x out of range\n",
+ stag, offset);
+ return -EINVAL;
+}
+EXPORT_SYMBOL(cxgb4_read_tpte);
+
+u64 cxgb4_read_sge_timestamp(struct net_device *dev)
+{
+ u32 hi, lo;
+ struct adapter *adap;
+
+ adap = netdev2adap(dev);
+ lo = t4_read_reg(adap, SGE_TIMESTAMP_LO);
+ hi = GET_TSVAL(t4_read_reg(adap, SGE_TIMESTAMP_HI));
+
+ return ((u64)hi << 32) | (u64)lo;
+}
+EXPORT_SYMBOL(cxgb4_read_sge_timestamp);
+
static struct pci_driver cxgb4_driver;
static void check_neigh_update(struct neighbour *neigh)
@@ -3899,6 +4158,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
unsigned short i;
lli.pdev = adap->pdev;
+ lli.pf = adap->fn;
lli.l2t = adap->l2t;
lli.tids = &adap->tids;
lli.ports = adap->port;
@@ -3919,6 +4179,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
lli.wr_cred = adap->params.ofldq_wr_cred;
lli.adapter_type = adap->params.chip;
lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2));
+ lli.cclk_ps = 1000000000 / adap->params.vpd.cclk;
lli.udb_density = 1 << QUEUESPERPAGEPF0_GET(
t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >>
(adap->fn * 4));
@@ -3933,8 +4194,12 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
lli.fw_vers = adap->params.fw_vers;
lli.dbfifo_int_thresh = dbfifo_int_thresh;
+ lli.sge_ingpadboundary = adap->sge.fl_align;
+ lli.sge_egrstatuspagesize = adap->sge.stat_len;
lli.sge_pktshift = adap->sge.pktshift;
lli.enable_fw_ofld_conn = adap->flags & FW_OFLD_CONN;
+ lli.max_ordird_qp = adap->params.max_ordird_qp;
+ lli.max_ird_adapter = adap->params.max_ird_adapter;
lli.ulptx_memwrite_dsgl = adap->params.ulptx_memwrite_dsgl;
handle = ulds[uld].add(&lli);
@@ -4598,6 +4863,7 @@ static const struct net_device_ops cxgb4_netdev_ops = {
.ndo_open = cxgb_open,
.ndo_stop = cxgb_close,
.ndo_start_xmit = t4_eth_xmit,
+ .ndo_select_queue = cxgb_select_queue,
.ndo_get_stats64 = cxgb_get_stats,
.ndo_set_rx_mode = cxgb_set_rxmode,
.ndo_set_mac_address = cxgb_set_mac_addr,
@@ -4617,20 +4883,75 @@ void t4_fatal_err(struct adapter *adap)
dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n");
}
+/* Return the specified PCI-E Configuration Space register from our Physical
+ * Function. We try first via a Firmware LDST Command since we prefer to let
+ * the firmware own all of these registers, but if that fails we go for it
+ * directly ourselves.
+ */
+static u32 t4_read_pcie_cfg4(struct adapter *adap, int reg)
+{
+ struct fw_ldst_cmd ldst_cmd;
+ u32 val;
+ int ret;
+
+ /* Construct and send the Firmware LDST Command to retrieve the
+ * specified PCI-E Configuration Space register.
+ */
+ memset(&ldst_cmd, 0, sizeof(ldst_cmd));
+ ldst_cmd.op_to_addrspace =
+ htonl(FW_CMD_OP(FW_LDST_CMD) |
+ FW_CMD_REQUEST |
+ FW_CMD_READ |
+ FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE));
+ ldst_cmd.cycles_to_len16 = htonl(FW_LEN16(ldst_cmd));
+ ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS(1);
+ ldst_cmd.u.pcie.ctrl_to_fn =
+ (FW_LDST_CMD_LC | FW_LDST_CMD_FN(adap->fn));
+ ldst_cmd.u.pcie.r = reg;
+ ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd),
+ &ldst_cmd);
+
+ /* If the LDST Command suucceeded, exctract the returned register
+ * value. Otherwise read it directly ourself.
+ */
+ if (ret == 0)
+ val = ntohl(ldst_cmd.u.pcie.data[0]);
+ else
+ t4_hw_pci_read_cfg4(adap, reg, &val);
+
+ return val;
+}
+
static void setup_memwin(struct adapter *adap)
{
- u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base;
+ u32 mem_win0_base, mem_win1_base, mem_win2_base, mem_win2_aperture;
- bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */
if (is_t4(adap->params.chip)) {
+ u32 bar0;
+
+ /* Truncation intentional: we only read the bottom 32-bits of
+ * the 64-bit BAR0/BAR1 ... We use the hardware backdoor
+ * mechanism to read BAR0 instead of using
+ * pci_resource_start() because we could be operating from
+ * within a Virtual Machine which is trapping our accesses to
+ * our Configuration Space and we need to set up the PCI-E
+ * Memory Window decoders with the actual addresses which will
+ * be coming across the PCI-E link.
+ */
+ bar0 = t4_read_pcie_cfg4(adap, PCI_BASE_ADDRESS_0);
+ bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
+ adap->t4_bar0 = bar0;
+
mem_win0_base = bar0 + MEMWIN0_BASE;
mem_win1_base = bar0 + MEMWIN1_BASE;
mem_win2_base = bar0 + MEMWIN2_BASE;
+ mem_win2_aperture = MEMWIN2_APERTURE;
} else {
/* For T5, only relative offset inside the PCIe BAR is passed */
mem_win0_base = MEMWIN0_BASE;
- mem_win1_base = MEMWIN1_BASE_T5;
+ mem_win1_base = MEMWIN1_BASE;
mem_win2_base = MEMWIN2_BASE_T5;
+ mem_win2_aperture = MEMWIN2_APERTURE_T5;
}
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0),
mem_win0_base | BIR(0) |
@@ -4640,16 +4961,19 @@ static void setup_memwin(struct adapter *adap)
WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2),
mem_win2_base | BIR(0) |
- WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
+ WINDOW(ilog2(mem_win2_aperture) - 10));
+ t4_read_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2));
}
static void setup_memwin_rdma(struct adapter *adap)
{
if (adap->vres.ocq.size) {
- unsigned int start, sz_kb;
+ u32 start;
+ unsigned int sz_kb;
- start = pci_resource_start(adap->pdev, 2) +
- OCQ_WIN_OFFSET(adap->pdev, &adap->vres);
+ start = t4_read_pcie_cfg4(adap, PCI_BASE_ADDRESS_2);
+ start &= PCI_BASE_ADDRESS_MEM_MASK;
+ start += OCQ_WIN_OFFSET(adap->pdev, &adap->vres);
sz_kb = roundup_pow_of_two(adap->vres.ocq.size) >> 10;
t4_write_reg(adap,
PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 3),
@@ -4862,7 +5186,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
adapter->fn, 0, 1, params, val);
if (ret == 0) {
/*
- * For t4_memory_write() below addresses and
+ * For t4_memory_rw() below addresses and
* sizes have to be in terms of multiples of 4
* bytes. So, if the Configuration File isn't
* a multiple of 4 bytes in length we'll have
@@ -4878,8 +5202,9 @@ static int adap_init0_config(struct adapter *adapter, int reset)
mtype = FW_PARAMS_PARAM_Y_GET(val[0]);
maddr = FW_PARAMS_PARAM_Z_GET(val[0]) << 16;
- ret = t4_memory_write(adapter, mtype, maddr,
- size, data);
+ spin_lock(&adapter->win0_lock);
+ ret = t4_memory_rw(adapter, 0, mtype, maddr,
+ size, data, T4_MEMORY_WRITE);
if (ret == 0 && resid != 0) {
union {
__be32 word;
@@ -4890,10 +5215,12 @@ static int adap_init0_config(struct adapter *adapter, int reset)
last.word = data[size >> 2];
for (i = resid; i < 4; i++)
last.buf[i] = 0;
- ret = t4_memory_write(adapter, mtype,
- maddr + size,
- 4, &last.word);
+ ret = t4_memory_rw(adapter, 0, mtype,
+ maddr + size,
+ 4, &last.word,
+ T4_MEMORY_WRITE);
}
+ spin_unlock(&adapter->win0_lock);
}
}
@@ -5637,6 +5964,22 @@ static int adap_init0(struct adapter *adap)
adap->vres.cq.size = val[3] - val[2] + 1;
adap->vres.ocq.start = val[4];
adap->vres.ocq.size = val[5] - val[4] + 1;
+
+ params[0] = FW_PARAM_DEV(MAXORDIRD_QP);
+ params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER);
+ ret = t4_query_params(adap, 0, 0, 0, 2, params, val);
+ if (ret < 0) {
+ adap->params.max_ordird_qp = 8;
+ adap->params.max_ird_adapter = 32 * adap->tids.ntids;
+ ret = 0;
+ } else {
+ adap->params.max_ordird_qp = val[0];
+ adap->params.max_ird_adapter = val[1];
+ }
+ dev_info(adap->pdev_dev,
+ "max_ordird_qp %d max_ird_adapter %d\n",
+ adap->params.max_ordird_qp,
+ adap->params.max_ird_adapter);
}
if (caps_cmd.iscsicaps) {
params[0] = FW_PARAM_PFVF(ISCSI_START);
@@ -5838,12 +6181,33 @@ static inline void init_rspq(struct adapter *adap, struct sge_rspq *q,
static void cfg_queues(struct adapter *adap)
{
struct sge *s = &adap->sge;
- int i, q10g = 0, n10g = 0, qidx = 0;
+ int i, n10g = 0, qidx = 0;
+#ifndef CONFIG_CHELSIO_T4_DCB
+ int q10g = 0;
+#endif
int ciq_size;
for_each_port(adap, i)
n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg);
+#ifdef CONFIG_CHELSIO_T4_DCB
+ /* For Data Center Bridging support we need to be able to support up
+ * to 8 Traffic Priorities; each of which will be assigned to its
+ * own TX Queue in order to prevent Head-Of-Line Blocking.
+ */
+ if (adap->params.nports * 8 > MAX_ETH_QSETS) {
+ dev_err(adap->pdev_dev, "MAX_ETH_QSETS=%d < %d!\n",
+ MAX_ETH_QSETS, adap->params.nports * 8);
+ BUG_ON(1);
+ }
+
+ for_each_port(adap, i) {
+ struct port_info *pi = adap2pinfo(adap, i);
+ pi->first_qset = qidx;
+ pi->nqsets = 8;
+ qidx += pi->nqsets;
+ }
+#else /* !CONFIG_CHELSIO_T4_DCB */
/*
* We default to 1 queue per non-10G port and up to # of cores queues
* per 10G port.
@@ -5860,6 +6224,7 @@ static void cfg_queues(struct adapter *adap)
pi->nqsets = is_x_10g_port(&pi->link_cfg) ? q10g : 1;
qidx += pi->nqsets;
}
+#endif /* !CONFIG_CHELSIO_T4_DCB */
s->ethqsets = qidx;
s->max_ethqsets = qidx; /* MSI-X may lower it later */
@@ -5978,8 +6343,14 @@ static int enable_msix(struct adapter *adap)
/* need nchan for each possible ULD */
ofld_need = 3 * nchan;
}
+#ifdef CONFIG_CHELSIO_T4_DCB
+ /* For Data Center Bridging we need 8 Ethernet TX Priority Queues for
+ * each port.
+ */
+ need = 8 * adap->params.nports + EXTRA_VECS + ofld_need;
+#else
need = adap->params.nports + EXTRA_VECS + ofld_need;
-
+#endif
want = pci_enable_msix_range(adap->pdev, entries, need, want);
if (want < 0)
return want;
@@ -6111,13 +6482,6 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
}
- /* We control everything through one PF */
- func = PCI_FUNC(pdev->devfn);
- if (func != ent->driver_data) {
- pci_save_state(pdev); /* to restore SR-IOV later */
- goto sriov;
- }
-
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "cannot enable PCI device\n");
@@ -6161,6 +6525,13 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_free_adapter;
}
+ /* We control everything through one PF */
+ func = SOURCEPF_GET(readl(adapter->regs + PL_WHOAMI));
+ if (func != ent->driver_data) {
+ pci_save_state(pdev); /* to restore SR-IOV later */
+ goto sriov;
+ }
+
adapter->pdev = pdev;
adapter->pdev_dev = &pdev->dev;
adapter->mbox = func;
@@ -6242,6 +6613,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->netdev_ops = &cxgb4_netdev_ops;
+#ifdef CONFIG_CHELSIO_T4_DCB
+ netdev->dcbnl_ops = &cxgb4_dcb_ops;
+ cxgb4_dcb_state_init(netdev);
+#endif
netdev->ethtool_ops = &cxgb_ethtool_ops;
}
@@ -6366,8 +6741,7 @@ static void remove_one(struct pci_dev *pdev)
if (adapter->port[i]->reg_state == NETREG_REGISTERED)
unregister_netdev(adapter->port[i]);
- if (adapter->debugfs_root)
- debugfs_remove_recursive(adapter->debugfs_root);
+ debugfs_remove_recursive(adapter->debugfs_root);
/* If we allocated filters, free up state associated with any
* valid filters ...
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 55e9daf7f9d4..1366ba620c87 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -172,6 +172,10 @@ int cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
unsigned char port, unsigned char mask);
int cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
unsigned int queue, bool ipv6);
+int cxgb4_clip_get(const struct net_device *dev, const struct in6_addr *lip);
+int cxgb4_clip_release(const struct net_device *dev,
+ const struct in6_addr *lip);
+
static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
{
skb_set_queue_mapping(skb, (queue << 1) | prio);
@@ -243,6 +247,7 @@ struct cxgb4_lld_info {
unsigned char fw_api_ver; /* FW API version */
unsigned int fw_vers; /* FW version */
unsigned int iscsi_iolen; /* iSCSI max I/O length */
+ unsigned int cclk_ps; /* Core clock period in psec */
unsigned short udb_density; /* # of user DB/page */
unsigned short ucq_density; /* # of user CQs/page */
unsigned short filt_mode; /* filter optional components */
@@ -251,10 +256,15 @@ struct cxgb4_lld_info {
void __iomem *gts_reg; /* address of GTS register */
void __iomem *db_reg; /* address of kernel doorbell */
int dbfifo_int_thresh; /* doorbell fifo int threshold */
+ unsigned int sge_ingpadboundary; /* SGE ingress padding boundary */
+ unsigned int sge_egrstatuspagesize; /* SGE egress status page size */
unsigned int sge_pktshift; /* Padding between CPL and */
/* packet data */
+ unsigned int pf; /* Physical Function we're using */
bool enable_fw_ofld_conn; /* Enable connection through fw */
/* WR */
+ unsigned int max_ordird_qp; /* Max ORD/IRD depth per RDMA QP */
+ unsigned int max_ird_adapter; /* Max IRD memory per adapter */
bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */
};
@@ -291,5 +301,7 @@ int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
int cxgb4_flush_eq_cache(struct net_device *dev);
void cxgb4_disable_db_coalescing(struct net_device *dev);
void cxgb4_enable_db_coalescing(struct net_device *dev);
+int cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte);
+u64 cxgb4_read_sge_timestamp(struct net_device *dev);
#endif /* !__CXGB4_OFLD_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
index 8a96572fdde0..96041397ee15 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.h b/drivers/net/ethernet/chelsio/cxgb4/l2t.h
index 85eb5c71358d..a30126ce90cb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index dd4355d248e4..b0bba32d69d5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -2480,6 +2480,22 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
}
/**
+ * t4_free_ofld_rxqs - free a block of consecutive Rx queues
+ * @adap: the adapter
+ * @n: number of queues
+ * @q: pointer to first queue
+ *
+ * Release the resources of a consecutive block of offload Rx queues.
+ */
+void t4_free_ofld_rxqs(struct adapter *adap, int n, struct sge_ofld_rxq *q)
+{
+ for ( ; n; n--, q++)
+ if (q->rspq.desc)
+ free_rspq_fl(adap, &q->rspq,
+ q->fl.size ? &q->fl : NULL);
+}
+
+/**
* t4_free_sge_resources - free SGE resources
* @adap: the adapter
*
@@ -2490,12 +2506,12 @@ void t4_free_sge_resources(struct adapter *adap)
int i;
struct sge_eth_rxq *eq = adap->sge.ethrxq;
struct sge_eth_txq *etq = adap->sge.ethtxq;
- struct sge_ofld_rxq *oq = adap->sge.ofldrxq;
/* clean up Ethernet Tx/Rx queues */
for (i = 0; i < adap->sge.ethqsets; i++, eq++, etq++) {
if (eq->rspq.desc)
- free_rspq_fl(adap, &eq->rspq, &eq->fl);
+ free_rspq_fl(adap, &eq->rspq,
+ eq->fl.size ? &eq->fl : NULL);
if (etq->q.desc) {
t4_eth_eq_free(adap, adap->fn, adap->fn, 0,
etq->q.cntxt_id);
@@ -2506,18 +2522,9 @@ void t4_free_sge_resources(struct adapter *adap)
}
/* clean up RDMA and iSCSI Rx queues */
- for (i = 0; i < adap->sge.ofldqsets; i++, oq++) {
- if (oq->rspq.desc)
- free_rspq_fl(adap, &oq->rspq, &oq->fl);
- }
- for (i = 0, oq = adap->sge.rdmarxq; i < adap->sge.rdmaqs; i++, oq++) {
- if (oq->rspq.desc)
- free_rspq_fl(adap, &oq->rspq, &oq->fl);
- }
- for (i = 0, oq = adap->sge.rdmaciq; i < adap->sge.rdmaciqs; i++, oq++) {
- if (oq->rspq.desc)
- free_rspq_fl(adap, &oq->rspq, &oq->fl);
- }
+ t4_free_ofld_rxqs(adap, adap->sge.ofldqsets, adap->sge.ofldrxq);
+ t4_free_ofld_rxqs(adap, adap->sge.rdmaqs, adap->sge.rdmarxq);
+ t4_free_ofld_rxqs(adap, adap->sge.rdmaciqs, adap->sge.rdmaciq);
/* clean up offload Tx queues */
for (i = 0; i < ARRAY_SIZE(adap->sge.ofldtxq); i++) {
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 931478e7bd28..a853133d8db8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -144,6 +144,30 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
}
/*
+ * Read a 32-bit PCI Configuration Space register via the PCI-E backdoor
+ * mechanism. This guarantees that we get the real value even if we're
+ * operating within a Virtual Machine and the Hypervisor is trapping our
+ * Configuration Space accesses.
+ */
+void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val)
+{
+ u32 req = ENABLE | FUNCTION(adap->fn) | reg;
+
+ if (is_t4(adap->params.chip))
+ req |= F_LOCALCFG;
+
+ t4_write_reg(adap, PCIE_CFG_SPACE_REQ, req);
+ *val = t4_read_reg(adap, PCIE_CFG_SPACE_DATA);
+
+ /* Reset ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a
+ * Configuration Space read. (None of the other fields matter when
+ * ENABLE is 0 so a simple register write is easier than a
+ * read-modify-write via t4_set_reg_field().)
+ */
+ t4_write_reg(adap, PCIE_CFG_SPACE_REQ, 0);
+}
+
+/*
* Get the reply to a mailbox command and store it in @rpl in big-endian order.
*/
static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
@@ -389,78 +413,41 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
return 0;
}
-/*
- * t4_mem_win_rw - read/write memory through PCIE memory window
- * @adap: the adapter
- * @addr: address of first byte requested
- * @data: MEMWIN0_APERTURE bytes of data containing the requested address
- * @dir: direction of transfer 1 => read, 0 => write
- *
- * Read/write MEMWIN0_APERTURE bytes of data from MC starting at a
- * MEMWIN0_APERTURE-byte-aligned address that covers the requested
- * address @addr.
- */
-static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir)
-{
- int i;
- u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn);
-
- /*
- * Setup offset into PCIE memory window. Address must be a
- * MEMWIN0_APERTURE-byte-aligned address. (Read back MA register to
- * ensure that changes propagate before we attempt to use the new
- * values.)
- */
- t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET,
- (addr & ~(MEMWIN0_APERTURE - 1)) | win_pf);
- t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET);
-
- /* Collecting data 4 bytes at a time upto MEMWIN0_APERTURE */
- for (i = 0; i < MEMWIN0_APERTURE; i = i+0x4) {
- if (dir)
- *data++ = (__force __be32) t4_read_reg(adap,
- (MEMWIN0_BASE + i));
- else
- t4_write_reg(adap, (MEMWIN0_BASE + i),
- (__force u32) *data++);
- }
-
- return 0;
-}
-
/**
* t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
* @adap: the adapter
+ * @win: PCI-E Memory Window to use
* @mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC
* @addr: address within indicated memory type
* @len: amount of memory to transfer
* @buf: host memory buffer
- * @dir: direction of transfer 1 => read, 0 => write
+ * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)
*
* Reads/writes an [almost] arbitrary memory region in the firmware: the
- * firmware memory address, length and host buffer must be aligned on
- * 32-bit boudaries. The memory is transferred as a raw byte sequence
- * from/to the firmware's memory. If this memory contains data
- * structures which contain multi-byte integers, it's the callers
- * responsibility to perform appropriate byte order conversions.
+ * firmware memory address and host buffer must be aligned on 32-bit
+ * boudaries; the length may be arbitrary. The memory is transferred as
+ * a raw byte sequence from/to the firmware's memory. If this memory
+ * contains data structures which contain multi-byte integers, it's the
+ * caller's responsibility to perform appropriate byte order conversions.
*/
-static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
- __be32 *buf, int dir)
+int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
+ u32 len, __be32 *buf, int dir)
{
- u32 pos, start, end, offset, memoffset;
- u32 edc_size, mc_size;
- int ret = 0;
- __be32 *data;
+ u32 pos, offset, resid, memoffset;
+ u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base;
- /*
- * Argument sanity checks ...
+ /* Argument sanity checks ...
*/
- if ((addr & 0x3) || (len & 0x3))
+ if (addr & 0x3)
return -EINVAL;
- data = vmalloc(MEMWIN0_APERTURE);
- if (!data)
- return -ENOMEM;
+ /* It's convenient to be able to handle lengths which aren't a
+ * multiple of 32-bits because we often end up transferring files to
+ * the firmware. So we'll handle that by normalizing the length here
+ * and then handling any residual transfer at the end.
+ */
+ resid = len & 0x3;
+ len -= resid;
/* Offset into the region of memory which is being accessed
* MEM_EDC0 = 0
@@ -481,66 +468,98 @@ static int t4_memory_rw(struct adapter *adap, int mtype, u32 addr, u32 len,
/* Determine the PCIE_MEM_ACCESS_OFFSET */
addr = addr + memoffset;
- /*
- * The underlaying EDC/MC read routines read MEMWIN0_APERTURE bytes
- * at a time so we need to round down the start and round up the end.
- * We'll start copying out of the first line at (addr - start) a word
- * at a time.
+ /* Each PCI-E Memory Window is programmed with a window size -- or
+ * "aperture" -- which controls the granularity of its mapping onto
+ * adapter memory. We need to grab that aperture in order to know
+ * how to use the specified window. The window is also programmed
+ * with the base address of the Memory Window in BAR0's address
+ * space. For T4 this is an absolute PCI-E Bus Address. For T5
+ * the address is relative to BAR0.
*/
- start = addr & ~(MEMWIN0_APERTURE-1);
- end = (addr + len + MEMWIN0_APERTURE-1) & ~(MEMWIN0_APERTURE-1);
- offset = (addr - start)/sizeof(__be32);
+ mem_reg = t4_read_reg(adap,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN,
+ win));
+ mem_aperture = 1 << (GET_WINDOW(mem_reg) + 10);
+ mem_base = GET_PCIEOFST(mem_reg) << 10;
+ if (is_t4(adap->params.chip))
+ mem_base -= adap->t4_bar0;
+ win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn);
- for (pos = start; pos < end; pos += MEMWIN0_APERTURE, offset = 0) {
+ /* Calculate our initial PCI-E Memory Window Position and Offset into
+ * that Window.
+ */
+ pos = addr & ~(mem_aperture-1);
+ offset = addr - pos;
- /*
- * If we're writing, copy the data from the caller's memory
- * buffer
+ /* Set up initial PCI-E Memory Window to cover the start of our
+ * transfer. (Read it back to ensure that changes propagate before we
+ * attempt to use the new value.)
+ */
+ t4_write_reg(adap,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win),
+ pos | win_pf);
+ t4_read_reg(adap,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
+
+ /* Transfer data to/from the adapter as long as there's an integral
+ * number of 32-bit transfers to complete.
+ */
+ while (len > 0) {
+ if (dir == T4_MEMORY_READ)
+ *buf++ = (__force __be32) t4_read_reg(adap,
+ mem_base + offset);
+ else
+ t4_write_reg(adap, mem_base + offset,
+ (__force u32) *buf++);
+ offset += sizeof(__be32);
+ len -= sizeof(__be32);
+
+ /* If we've reached the end of our current window aperture,
+ * move the PCI-E Memory Window on to the next. Note that
+ * doing this here after "len" may be 0 allows us to set up
+ * the PCI-E Memory Window for a possible final residual
+ * transfer below ...
*/
- if (!dir) {
- /*
- * If we're doing a partial write, then we need to do
- * a read-modify-write ...
- */
- if (offset || len < MEMWIN0_APERTURE) {
- ret = t4_mem_win_rw(adap, pos, data, 1);
- if (ret)
- break;
- }
- while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) &&
- len > 0) {
- data[offset++] = *buf++;
- len -= sizeof(__be32);
- }
+ if (offset == mem_aperture) {
+ pos += mem_aperture;
+ offset = 0;
+ t4_write_reg(adap,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET,
+ win), pos | win_pf);
+ t4_read_reg(adap,
+ PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET,
+ win));
}
-
- /*
- * Transfer a block of memory and bail if there's an error.
- */
- ret = t4_mem_win_rw(adap, pos, data, dir);
- if (ret)
- break;
-
- /*
- * If we're reading, copy the data into the caller's memory
- * buffer.
- */
- if (dir)
- while (offset < (MEMWIN0_APERTURE/sizeof(__be32)) &&
- len > 0) {
- *buf++ = data[offset++];
- len -= sizeof(__be32);
- }
}
- vfree(data);
- return ret;
-}
+ /* If the original transfer had a length which wasn't a multiple of
+ * 32-bits, now's where we need to finish off the transfer of the
+ * residual amount. The PCI-E Memory Window has already been moved
+ * above (if necessary) to cover this final transfer.
+ */
+ if (resid) {
+ union {
+ __be32 word;
+ char byte[4];
+ } last;
+ unsigned char *bp;
+ int i;
+
+ if (dir == T4_MEMORY_READ) {
+ last.word = (__force __be32) t4_read_reg(adap,
+ mem_base + offset);
+ for (bp = (unsigned char *)buf, i = resid; i < 4; i++)
+ bp[i] = last.byte[i];
+ } else {
+ last.word = *buf;
+ for (i = resid; i < 4; i++)
+ last.byte[i] = 0;
+ t4_write_reg(adap, mem_base + offset,
+ (__force u32) last.word);
+ }
+ }
-int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len,
- __be32 *buf)
-{
- return t4_memory_rw(adap, mtype, addr, len, buf, 0);
+ return 0;
}
#define EEPROM_STAT_ADDR 0x7bfc
@@ -1700,16 +1719,24 @@ static void mps_intr_handler(struct adapter *adapter)
*/
static void mem_intr_handler(struct adapter *adapter, int idx)
{
- static const char name[3][5] = { "EDC0", "EDC1", "MC" };
+ static const char name[4][7] = { "EDC0", "EDC1", "MC/MC0", "MC1" };
unsigned int addr, cnt_addr, v;
if (idx <= MEM_EDC1) {
addr = EDC_REG(EDC_INT_CAUSE, idx);
cnt_addr = EDC_REG(EDC_ECC_STATUS, idx);
+ } else if (idx == MEM_MC) {
+ if (is_t4(adapter->params.chip)) {
+ addr = MC_INT_CAUSE;
+ cnt_addr = MC_ECC_STATUS;
+ } else {
+ addr = MC_P_INT_CAUSE;
+ cnt_addr = MC_P_ECC_STATUS;
+ }
} else {
- addr = MC_INT_CAUSE;
- cnt_addr = MC_ECC_STATUS;
+ addr = MC_REG(MC_P_INT_CAUSE, 1);
+ cnt_addr = MC_REG(MC_P_ECC_STATUS, 1);
}
v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
@@ -1873,6 +1900,8 @@ int t4_slow_intr_handler(struct adapter *adapter)
pcie_intr_handler(adapter);
if (cause & MC)
mem_intr_handler(adapter, MEM_MC);
+ if (!is_t4(adapter->params.chip) && (cause & MC1))
+ mem_intr_handler(adapter, MEM_MC1);
if (cause & EDC0)
mem_intr_handler(adapter, MEM_EDC0);
if (cause & EDC1)
@@ -2505,39 +2534,6 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
}
/**
- * t4_mem_win_read_len - read memory through PCIE memory window
- * @adap: the adapter
- * @addr: address of first byte requested aligned on 32b.
- * @data: len bytes to hold the data read
- * @len: amount of data to read from window. Must be <=
- * MEMWIN0_APERATURE after adjusting for 16B for T4 and
- * 128B for T5 alignment requirements of the the memory window.
- *
- * Read len bytes of data from MC starting at @addr.
- */
-int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
-{
- int i, off;
- u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn);
-
- /* Align on a 2KB boundary.
- */
- off = addr & MEMWIN0_APERTURE;
- if ((addr & 3) || (len + off) > MEMWIN0_APERTURE)
- return -EINVAL;
-
- t4_write_reg(adap, PCIE_MEM_ACCESS_OFFSET,
- (addr & ~MEMWIN0_APERTURE) | win_pf);
- t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET);
-
- for (i = 0; i < len; i += 4)
- *data++ = (__force __be32) t4_read_reg(adap,
- (MEMWIN0_BASE + off + i));
-
- return 0;
-}
-
-/**
* t4_mdio_rd - read a PHY register through MDIO
* @adap: the adapter
* @mbox: mailbox to use for the FW command
@@ -3175,6 +3171,46 @@ int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
}
/**
+ * t4_set_params_nosleep - sets FW or device parameters
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @pf: the PF
+ * @vf: the VF
+ * @nparams: the number of parameters
+ * @params: the parameter names
+ * @val: the parameter values
+ *
+ * Does not ever sleep
+ * Sets the value of FW or device parameters. Up to 7 parameters can be
+ * specified at once.
+ */
+int t4_set_params_nosleep(struct adapter *adap, unsigned int mbox,
+ unsigned int pf, unsigned int vf,
+ unsigned int nparams, const u32 *params,
+ const u32 *val)
+{
+ struct fw_params_cmd c;
+ __be32 *p = &c.param[0].mnem;
+
+ if (nparams > 7)
+ return -EINVAL;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) |
+ FW_CMD_REQUEST | FW_CMD_WRITE |
+ FW_PARAMS_CMD_PFN(pf) |
+ FW_PARAMS_CMD_VFN(vf));
+ c.retval_len16 = cpu_to_be32(FW_LEN16(c));
+
+ while (nparams--) {
+ *p++ = cpu_to_be32(*params++);
+ *p++ = cpu_to_be32(*val++);
+ }
+
+ return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
* t4_set_params - sets FW or device parameters
* @adap: the adapter
* @mbox: mailbox to use for the FW command
@@ -3499,6 +3535,33 @@ int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
}
/**
+ * t4_enable_vi_params - enable/disable a virtual interface
+ * @adap: the adapter
+ * @mbox: mailbox to use for the FW command
+ * @viid: the VI id
+ * @rx_en: 1=enable Rx, 0=disable Rx
+ * @tx_en: 1=enable Tx, 0=disable Tx
+ * @dcb_en: 1=enable delivery of Data Center Bridging messages.
+ *
+ * Enables/disables a virtual interface. Note that setting DCB Enable
+ * only makes sense when enabling a Virtual Interface ...
+ */
+int t4_enable_vi_params(struct adapter *adap, unsigned int mbox,
+ unsigned int viid, bool rx_en, bool tx_en, bool dcb_en)
+{
+ struct fw_vi_enable_cmd c;
+
+ memset(&c, 0, sizeof(c));
+ c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
+ FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
+
+ c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) |
+ FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c) |
+ FW_VI_ENABLE_CMD_DCB_INFO(dcb_en));
+ return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL);
+}
+
+/**
* t4_enable_vi - enable/disable a virtual interface
* @adap: the adapter
* @mbox: mailbox to use for the FW command
@@ -3511,14 +3574,7 @@ int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
bool rx_en, bool tx_en)
{
- struct fw_vi_enable_cmd c;
-
- memset(&c, 0, sizeof(c));
- c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST |
- FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid));
- c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_IEN(rx_en) |
- FW_VI_ENABLE_CMD_EEN(tx_en) | FW_LEN16(c));
- return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+ return t4_enable_vi_params(adap, mbox, viid, rx_en, tx_en, 0);
}
/**
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
index 71b799b5b0f4..35e3d8e32881 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index 973eb11aa98a..52e08103f221 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -75,6 +75,7 @@ enum {
CPL_RX_DATA_DDP = 0x42,
CPL_PASS_ACCEPT_REQ = 0x44,
CPL_TRACE_PKT_T5 = 0x48,
+ CPL_RX_ISCSI_DDP = 0x49,
CPL_RDMA_READ_REQ = 0x60,
@@ -86,6 +87,7 @@ enum {
CPL_SGE_EGR_UPDATE = 0xA5,
CPL_TRACE_PKT = 0xB0,
+ CPL_ISCSI_DATA = 0xB2,
CPL_FW4_MSG = 0xC0,
CPL_FW4_PLD = 0xC1,
@@ -270,12 +272,15 @@ struct cpl_pass_accept_rpl {
#define RX_COALESCE_VALID(x) ((x) << 11)
#define RX_COALESCE(x) ((x) << 12)
#define PACE(x) ((x) << 16)
+#define RX_FC_VALID ((1U) << 19)
+#define RX_FC_DISABLE ((1U) << 20)
#define TX_QUEUE(x) ((x) << 23)
#define RX_CHANNEL(x) ((x) << 26)
#define CCTRL_ECN(x) ((x) << 27)
#define WND_SCALE_EN(x) ((x) << 28)
#define TSTAMPS_EN(x) ((x) << 29)
#define SACK_EN(x) ((x) << 30)
+#define T5_OPT_2_VALID ((1U) << 31)
__be64 opt0;
};
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 225ad8a5722d..e3146e83df20 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2003-2014 Chelsio Communications, 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
@@ -251,6 +251,12 @@
#define V_NOCOALESCE(x) ((x) << S_NOCOALESCE)
#define F_NOCOALESCE V_NOCOALESCE(1U)
+#define SGE_TIMESTAMP_LO 0x1098
+#define SGE_TIMESTAMP_HI 0x109c
+#define S_TSVAL 0
+#define M_TSVAL 0xfffffffU
+#define GET_TSVAL(x) (((x) >> S_TSVAL) & M_TSVAL)
+
#define SGE_TIMER_VALUE_0_AND_1 0x10b8
#define TIMERVALUE0_MASK 0xffff0000U
#define TIMERVALUE0_SHIFT 16
@@ -387,6 +393,8 @@
#define MSTGRPPERR 0x00000001U
#define PCIE_NONFAT_ERR 0x3010
+#define PCIE_CFG_SPACE_REQ 0x3060
+#define PCIE_CFG_SPACE_DATA 0x3064
#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
#define S_PCIEOFST 10
#define M_PCIEOFST 0x3fffffU
@@ -398,7 +406,11 @@
#define WINDOW_MASK 0x000000ffU
#define WINDOW_SHIFT 0
#define WINDOW(x) ((x) << WINDOW_SHIFT)
+#define GET_WINDOW(x) (((x) >> WINDOW_SHIFT) & WINDOW_MASK)
#define PCIE_MEM_ACCESS_OFFSET 0x306c
+#define ENABLE (1U << 30)
+#define FUNCTION(x) ((x) << 12)
+#define F_LOCALCFG (1U << 28)
#define S_PFNUM 0
#define V_PFNUM(x) ((x) << S_PFNUM)
@@ -436,11 +448,13 @@
#define TDUE 0x00010000U
#define MC_INT_CAUSE 0x7518
+#define MC_P_INT_CAUSE 0x41318
#define ECC_UE_INT_CAUSE 0x00000004U
#define ECC_CE_INT_CAUSE 0x00000002U
#define PERR_INT_CAUSE 0x00000001U
#define MC_ECC_STATUS 0x751c
+#define MC_P_ECC_STATUS 0x4131c
#define ECC_CECNT_MASK 0xffff0000U
#define ECC_CECNT_SHIFT 16
#define ECC_CECNT(x) ((x) << ECC_CECNT_SHIFT)
@@ -1089,6 +1103,7 @@
#define I2CM 0x00000002U
#define CIM 0x00000001U
+#define MC1 0x31
#define PL_INT_ENABLE 0x19410
#define PL_INT_MAP0 0x19414
#define PL_RST 0x19428
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index 9cc973fbcf26..ff709e3b3e7e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Chelsio T4 Ethernet driver for Linux.
*
- * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved.
+ * Copyright (c) 2009-2014 Chelsio Communications, 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
@@ -46,9 +46,11 @@ enum fw_retval {
FW_EFAULT = 14, /* bad address; fw bad */
FW_EBUSY = 16, /* resource busy */
FW_EEXIST = 17, /* file exists */
+ FW_ENODEV = 19, /* no such device */
FW_EINVAL = 22, /* invalid argument */
FW_ENOSPC = 28, /* no space left on device */
FW_ENOSYS = 38, /* functionality not implemented */
+ FW_ENODATA = 61, /* no data available */
FW_EPROTO = 71, /* protocol error */
FW_EADDRINUSE = 98, /* address already in use */
FW_EADDRNOTAVAIL = 99, /* cannot assigned requested address */
@@ -932,6 +934,8 @@ enum fw_params_param_dev {
FW_PARAMS_PARAM_DEV_FWREV = 0x0B,
FW_PARAMS_PARAM_DEV_TPREV = 0x0C,
FW_PARAMS_PARAM_DEV_CF = 0x0D,
+ FW_PARAMS_PARAM_DEV_MAXORDIRD_QP = 0x13, /* max supported QP IRD/ORD */
+ FW_PARAMS_PARAM_DEV_MAXIRD_ADAPTER = 0x14, /* max supported adap IRD */
FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17,
};
@@ -989,6 +993,7 @@ enum fw_params_param_dmaq {
FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_MNGT = 0x10,
FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11,
FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12,
+ FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH = 0x13,
};
#define FW_PARAMS_MNEM(x) ((x) << 24)
@@ -1422,6 +1427,7 @@ struct fw_vi_enable_cmd {
#define FW_VI_ENABLE_CMD_VIID(x) ((x) << 0)
#define FW_VI_ENABLE_CMD_IEN(x) ((x) << 31)
#define FW_VI_ENABLE_CMD_EEN(x) ((x) << 30)
+#define FW_VI_ENABLE_CMD_DCB_INFO(x) ((x) << 28)
#define FW_VI_ENABLE_CMD_LED (1U << 29)
/* VI VF stats offset definitions */
@@ -1594,6 +1600,9 @@ enum fw_port_action {
FW_PORT_ACTION_GET_PORT_INFO = 0x0003,
FW_PORT_ACTION_L2_PPP_CFG = 0x0004,
FW_PORT_ACTION_L2_DCB_CFG = 0x0005,
+ FW_PORT_ACTION_DCB_READ_TRANS = 0x0006,
+ FW_PORT_ACTION_DCB_READ_RECV = 0x0007,
+ FW_PORT_ACTION_DCB_READ_DET = 0x0008,
FW_PORT_ACTION_LOW_PWR_TO_NORMAL = 0x0010,
FW_PORT_ACTION_L1_LOW_PWR_EN = 0x0011,
FW_PORT_ACTION_L2_WOL_MODE_EN = 0x0012,
@@ -1637,6 +1646,14 @@ enum fw_port_dcb_type {
FW_PORT_DCB_TYPE_PRIORATE = 0x02,
FW_PORT_DCB_TYPE_PFC = 0x03,
FW_PORT_DCB_TYPE_APP_ID = 0x04,
+ FW_PORT_DCB_TYPE_CONTROL = 0x05,
+};
+
+enum fw_port_dcb_feature_state {
+ FW_PORT_DCB_FEATURE_STATE_PENDING = 0x0,
+ FW_PORT_DCB_FEATURE_STATE_SUCCESS = 0x1,
+ FW_PORT_DCB_FEATURE_STATE_ERROR = 0x2,
+ FW_PORT_DCB_FEATURE_STATE_TIMEOUT = 0x3,
};
struct fw_port_cmd {
@@ -1648,9 +1665,11 @@ struct fw_port_cmd {
__be32 r;
} l1cfg;
struct fw_port_l2cfg {
- __be16 ctlbf_to_ivlan0;
+ __u8 ctlbf;
+ __u8 ovlan3_to_ivlan0;
__be16 ivlantype;
- __be32 txipg_pkd;
+ __be16 txipg_force_pinfo;
+ __be16 mtu;
__be16 ovlan0mask;
__be16 ovlan0type;
__be16 ovlan1mask;
@@ -1666,24 +1685,60 @@ struct fw_port_cmd {
__be16 acap;
__be16 mtu;
__u8 cbllen;
- __u8 r9;
- __be32 r10;
- __be64 r11;
+ __u8 auxlinfo;
+ __u8 dcbxdis_pkd;
+ __u8 r8_lo[3];
+ __be64 r9;
} info;
- struct fw_port_ppp {
- __be32 pppen_to_ncsich;
- __be32 r11;
- } ppp;
- struct fw_port_dcb {
- __be16 cfg;
- u8 up_map;
- u8 sf_cfgrc;
- __be16 prot_ix;
- u8 pe7_to_pe0;
- u8 numTCPFCs;
- __be32 pgid0_to_pgid7;
- __be32 numTCs_oui;
- u8 pgpc[8];
+ struct fw_port_diags {
+ __u8 diagop;
+ __u8 r[3];
+ __be32 diagval;
+ } diags;
+ union fw_port_dcb {
+ struct fw_port_dcb_pgid {
+ __u8 type;
+ __u8 apply_pkd;
+ __u8 r10_lo[2];
+ __be32 pgid;
+ __be64 r11;
+ } pgid;
+ struct fw_port_dcb_pgrate {
+ __u8 type;
+ __u8 apply_pkd;
+ __u8 r10_lo[5];
+ __u8 num_tcs_supported;
+ __u8 pgrate[8];
+ } pgrate;
+ struct fw_port_dcb_priorate {
+ __u8 type;
+ __u8 apply_pkd;
+ __u8 r10_lo[6];
+ __u8 strict_priorate[8];
+ } priorate;
+ struct fw_port_dcb_pfc {
+ __u8 type;
+ __u8 pfcen;
+ __u8 r10[5];
+ __u8 max_pfc_tcs;
+ __be64 r11;
+ } pfc;
+ struct fw_port_app_priority {
+ __u8 type;
+ __u8 r10[2];
+ __u8 idx;
+ __u8 user_prio_map;
+ __u8 sel_field;
+ __be16 protocolid;
+ __be64 r12;
+ } app_priority;
+ struct fw_port_dcb_control {
+ __u8 type;
+ __u8 all_syncd_pkd;
+ __be16 pfc_state_to_app_state;
+ __be32 r11;
+ __be64 r12;
+ } control;
} dcb;
} u;
};
@@ -1720,6 +1775,10 @@ struct fw_port_cmd {
#define FW_PORT_CMD_MODTYPE_MASK 0x1f
#define FW_PORT_CMD_MODTYPE_GET(x) (((x) >> 0) & FW_PORT_CMD_MODTYPE_MASK)
+#define FW_PORT_CMD_DCBXDIS (1U << 7)
+#define FW_PORT_CMD_APPLY (1U << 7)
+#define FW_PORT_CMD_ALL_SYNCD (1U << 7)
+
#define FW_PORT_CMD_PPPEN(x) ((x) << 31)
#define FW_PORT_CMD_TPSRC(x) ((x) << 28)
#define FW_PORT_CMD_NCSISRC(x) ((x) << 24)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index ff1cdd1788b5..d8d28e82ade1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -2876,24 +2876,24 @@ static void cxgb4vf_pci_shutdown(struct pci_dev *pdev)
if (!adapter)
return;
- /*
- * Disable all Virtual Interfaces. This will shut down the
+ /* Disable all Virtual Interfaces. This will shut down the
* delivery of all ingress packets into the chip for these
* Virtual Interfaces.
*/
- for_each_port(adapter, pidx) {
- struct net_device *netdev;
- struct port_info *pi;
-
- if (!test_bit(pidx, &adapter->registered_device_map))
- continue;
-
- netdev = adapter->port[pidx];
- if (!netdev)
- continue;
+ for_each_port(adapter, pidx)
+ if (test_bit(pidx, &adapter->registered_device_map))
+ unregister_netdev(adapter->port[pidx]);
- pi = netdev_priv(netdev);
- t4vf_enable_vi(adapter, pi->viid, false, false);
+ /* Free up all Queues which will prevent further DMA and
+ * Interrupts allowing various internal pathways to drain.
+ */
+ t4vf_sge_stop(adapter);
+ if (adapter->flags & USING_MSIX) {
+ pci_disable_msix(adapter->pdev);
+ adapter->flags &= ~USING_MSIX;
+ } else if (adapter->flags & USING_MSI) {
+ pci_disable_msi(adapter->pdev);
+ adapter->flags &= ~USING_MSI;
}
/*
@@ -2901,6 +2901,7 @@ static void cxgb4vf_pci_shutdown(struct pci_dev *pdev)
* Interrupts allowing various internal pathways to drain.
*/
t4vf_free_sge_resources(adapter);
+ pci_set_drvdata(pdev, NULL);
}
/*
@@ -2924,6 +2925,15 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4vf_pci_tbl) = {
CH_DEVICE(0x480a, 0), /* T404-bt */
CH_DEVICE(0x480d, 0), /* T480-cr */
CH_DEVICE(0x480e, 0), /* T440-lp-cr */
+ CH_DEVICE(0x4880, 0),
+ CH_DEVICE(0x4880, 1),
+ CH_DEVICE(0x4880, 2),
+ CH_DEVICE(0x4880, 3),
+ CH_DEVICE(0x4880, 4),
+ CH_DEVICE(0x4880, 5),
+ CH_DEVICE(0x4880, 6),
+ CH_DEVICE(0x4880, 7),
+ CH_DEVICE(0x4880, 8),
CH_DEVICE(0x5800, 0), /* T580-dbg */
CH_DEVICE(0x5801, 0), /* T520-cr */
CH_DEVICE(0x5802, 0), /* T522-cr */
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index fe84fbabc0d4..9823a0ea7937 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -145,7 +145,6 @@ struct net_local {
int force; /* force various values; see FORCE* above. */
spinlock_t lock;
void __iomem *virt_addr;/* CS89x0 virtual address. */
- unsigned long size; /* Length of CS89x0 memory region. */
#if ALLOW_DMA
int use_dma; /* Flag: we're using dma */
int dma; /* DMA channel */
@@ -1854,41 +1853,29 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
lp = netdev_priv(dev);
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->irq = platform_get_irq(pdev, 0);
- if (mem_res == NULL || dev->irq <= 0) {
- dev_warn(&dev->dev, "memory/interrupt resource missing\n");
+ if (dev->irq <= 0) {
+ dev_warn(&dev->dev, "interrupt resource missing\n");
err = -ENXIO;
goto free;
}
- lp->size = resource_size(mem_res);
- if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) {
- dev_warn(&dev->dev, "request_mem_region() failed\n");
- err = -EBUSY;
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ virt_addr = devm_ioremap_resource(&pdev->dev, mem_res);
+ if (IS_ERR(virt_addr)) {
+ err = PTR_ERR(virt_addr);
goto free;
}
- virt_addr = ioremap(mem_res->start, lp->size);
- if (!virt_addr) {
- dev_warn(&dev->dev, "ioremap() failed\n");
- err = -ENOMEM;
- goto release;
- }
-
err = cs89x0_probe1(dev, virt_addr, 0);
if (err) {
dev_warn(&dev->dev, "no cs8900 or cs8920 detected\n");
- goto unmap;
+ goto free;
}
platform_set_drvdata(pdev, dev);
return 0;
-unmap:
- iounmap(virt_addr);
-release:
- release_mem_region(mem_res->start, lp->size);
free:
free_netdev(dev);
return err;
@@ -1897,17 +1884,12 @@ free:
static int cs89x0_platform_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
- struct net_local *lp = netdev_priv(dev);
- struct resource *mem_res;
/* This platform_get_resource() call will not return NULL, because
* the same call in cs89x0_platform_probe() has returned a non NULL
* value.
*/
- mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
unregister_netdev(dev);
- iounmap(lp->virt_addr);
- release_mem_region(mem_res->start, lp->size);
free_netdev(dev);
return 0;
}
diff --git a/drivers/net/ethernet/cisco/enic/Makefile b/drivers/net/ethernet/cisco/enic/Makefile
index 239e1e46545d..aadcaf7876ce 100644
--- a/drivers/net/ethernet/cisco/enic/Makefile
+++ b/drivers/net/ethernet/cisco/enic/Makefile
@@ -2,5 +2,5 @@ obj-$(CONFIG_ENIC) := enic.o
enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o \
- enic_ethtool.o enic_api.o
+ enic_ethtool.o enic_api.o enic_clsf.o
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 14f465f239d6..962510f391df 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -33,7 +33,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "2.1.1.50"
+#define DRV_VERSION "2.1.1.67"
#define DRV_COPYRIGHT "Copyright 2008-2013 Cisco Systems, Inc"
#define ENIC_BARS_MAX 6
@@ -99,6 +99,41 @@ struct enic_port_profile {
u8 mac_addr[ETH_ALEN];
};
+/* enic_rfs_fltr_node - rfs filter node in hash table
+ * @@keys: IPv4 5 tuple
+ * @flow_id: flow_id of clsf filter provided by kernel
+ * @fltr_id: filter id of clsf filter returned by adaptor
+ * @rq_id: desired rq index
+ * @node: hlist_node
+ */
+struct enic_rfs_fltr_node {
+ struct flow_keys keys;
+ u32 flow_id;
+ u16 fltr_id;
+ u16 rq_id;
+ struct hlist_node node;
+};
+
+/* enic_rfs_flw_tbl - rfs flow table
+ * @max: Maximum number of filters vNIC supports
+ * @free: Number of free filters available
+ * @toclean: hash table index to clean next
+ * @ht_head: hash table list head
+ * @lock: spin lock
+ * @rfs_may_expire: timer function for enic_rps_may_expire_flow
+ */
+struct enic_rfs_flw_tbl {
+ u16 max;
+ int free;
+
+#define ENIC_RFS_FLW_BITSHIFT (10)
+#define ENIC_RFS_FLW_MASK ((1 << ENIC_RFS_FLW_BITSHIFT) - 1)
+ u16 toclean:ENIC_RFS_FLW_BITSHIFT;
+ struct hlist_head ht_head[1 << ENIC_RFS_FLW_BITSHIFT];
+ spinlock_t lock;
+ struct timer_list rfs_may_expire;
+};
+
/* Per-instance private data structure */
struct enic {
struct net_device *netdev;
@@ -140,7 +175,7 @@ struct enic {
unsigned int rq_count;
u64 rq_truncated_pkts;
u64 rq_bad_fcs;
- struct napi_struct napi[ENIC_RQ_MAX];
+ struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX];
/* interrupt resource cache line section */
____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
@@ -150,6 +185,7 @@ struct enic {
/* completion queue cache line section */
____cacheline_aligned struct vnic_cq cq[ENIC_CQ_MAX];
unsigned int cq_count;
+ struct enic_rfs_flw_tbl rfs_h;
};
static inline struct device *enic_get_dev(struct enic *enic)
diff --git a/drivers/net/ethernet/cisco/enic/enic_api.c b/drivers/net/ethernet/cisco/enic/enic_api.c
index e13efbdaa2ed..b161f24522b8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_api.c
+++ b/drivers/net/ethernet/cisco/enic/enic_api.c
@@ -34,13 +34,13 @@ int enic_api_devcmd_proxy_by_index(struct net_device *netdev, int vf,
struct vnic_dev *vdev = enic->vdev;
spin_lock(&enic->enic_api_lock);
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
vnic_dev_cmd_proxy_by_index_start(vdev, vf);
err = vnic_dev_cmd(vdev, cmd, a0, a1, wait);
vnic_dev_cmd_proxy_end(vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
spin_unlock(&enic->enic_api_lock);
return err;
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c
new file mode 100644
index 000000000000..69dfd3c9e529
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c
@@ -0,0 +1,284 @@
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/netdevice.h>
+#include <linux/in.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <net/flow_keys.h>
+#include "enic_res.h"
+#include "enic_clsf.h"
+
+/* enic_addfltr_5t - Add ipv4 5tuple filter
+ * @enic: enic struct of vnic
+ * @keys: flow_keys of ipv4 5tuple
+ * @rq: rq number to steer to
+ *
+ * This function returns filter_id(hardware_id) of the filter
+ * added. In case of error it returns an negative number.
+ */
+int enic_addfltr_5t(struct enic *enic, struct flow_keys *keys, u16 rq)
+{
+ int res;
+ struct filter data;
+
+ switch (keys->ip_proto) {
+ case IPPROTO_TCP:
+ data.u.ipv4.protocol = PROTO_TCP;
+ break;
+ case IPPROTO_UDP:
+ data.u.ipv4.protocol = PROTO_UDP;
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ };
+ data.type = FILTER_IPV4_5TUPLE;
+ data.u.ipv4.src_addr = ntohl(keys->src);
+ data.u.ipv4.dst_addr = ntohl(keys->dst);
+ data.u.ipv4.src_port = ntohs(keys->port16[0]);
+ data.u.ipv4.dst_port = ntohs(keys->port16[1]);
+ data.u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+
+ spin_lock_bh(&enic->devcmd_lock);
+ res = vnic_dev_classifier(enic->vdev, CLSF_ADD, &rq, &data);
+ spin_unlock_bh(&enic->devcmd_lock);
+ res = (res == 0) ? rq : res;
+
+ return res;
+}
+
+/* enic_delfltr - Delete clsf filter
+ * @enic: enic struct of vnic
+ * @filter_id: filter_is(hardware_id) of filter to be deleted
+ *
+ * This function returns zero in case of success, negative number incase of
+ * error.
+ */
+int enic_delfltr(struct enic *enic, u16 filter_id)
+{
+ int ret;
+
+ spin_lock_bh(&enic->devcmd_lock);
+ ret = vnic_dev_classifier(enic->vdev, CLSF_DEL, &filter_id, NULL);
+ spin_unlock_bh(&enic->devcmd_lock);
+
+ return ret;
+}
+
+/* enic_rfs_flw_tbl_init - initialize enic->rfs_h members
+ * @enic: enic data
+ */
+void enic_rfs_flw_tbl_init(struct enic *enic)
+{
+ int i;
+
+ spin_lock_init(&enic->rfs_h.lock);
+ for (i = 0; i <= ENIC_RFS_FLW_MASK; i++)
+ INIT_HLIST_HEAD(&enic->rfs_h.ht_head[i]);
+ enic->rfs_h.max = enic->config.num_arfs;
+ enic->rfs_h.free = enic->rfs_h.max;
+ enic->rfs_h.toclean = 0;
+ enic_rfs_timer_start(enic);
+}
+
+void enic_rfs_flw_tbl_free(struct enic *enic)
+{
+ int i;
+
+ enic_rfs_timer_stop(enic);
+ spin_lock(&enic->rfs_h.lock);
+ enic->rfs_h.free = 0;
+ for (i = 0; i < (1 << ENIC_RFS_FLW_BITSHIFT); i++) {
+ struct hlist_head *hhead;
+ struct hlist_node *tmp;
+ struct enic_rfs_fltr_node *n;
+
+ hhead = &enic->rfs_h.ht_head[i];
+ hlist_for_each_entry_safe(n, tmp, hhead, node) {
+ enic_delfltr(enic, n->fltr_id);
+ hlist_del(&n->node);
+ kfree(n);
+ }
+ }
+ spin_unlock(&enic->rfs_h.lock);
+}
+
+struct enic_rfs_fltr_node *htbl_fltr_search(struct enic *enic, u16 fltr_id)
+{
+ int i;
+
+ for (i = 0; i < (1 << ENIC_RFS_FLW_BITSHIFT); i++) {
+ struct hlist_head *hhead;
+ struct hlist_node *tmp;
+ struct enic_rfs_fltr_node *n;
+
+ hhead = &enic->rfs_h.ht_head[i];
+ hlist_for_each_entry_safe(n, tmp, hhead, node)
+ if (n->fltr_id == fltr_id)
+ return n;
+ }
+
+ return NULL;
+}
+
+#ifdef CONFIG_RFS_ACCEL
+void enic_flow_may_expire(unsigned long data)
+{
+ struct enic *enic = (struct enic *)data;
+ bool res;
+ int j;
+
+ spin_lock(&enic->rfs_h.lock);
+ for (j = 0; j < ENIC_CLSF_EXPIRE_COUNT; j++) {
+ struct hlist_head *hhead;
+ struct hlist_node *tmp;
+ struct enic_rfs_fltr_node *n;
+
+ hhead = &enic->rfs_h.ht_head[enic->rfs_h.toclean++];
+ hlist_for_each_entry_safe(n, tmp, hhead, node) {
+ res = rps_may_expire_flow(enic->netdev, n->rq_id,
+ n->flow_id, n->fltr_id);
+ if (res) {
+ res = enic_delfltr(enic, n->fltr_id);
+ if (unlikely(res))
+ continue;
+ hlist_del(&n->node);
+ kfree(n);
+ enic->rfs_h.free++;
+ }
+ }
+ }
+ spin_unlock(&enic->rfs_h.lock);
+ mod_timer(&enic->rfs_h.rfs_may_expire, jiffies + HZ/4);
+}
+
+static struct enic_rfs_fltr_node *htbl_key_search(struct hlist_head *h,
+ struct flow_keys *k)
+{
+ struct enic_rfs_fltr_node *tpos;
+
+ hlist_for_each_entry(tpos, h, node)
+ if (tpos->keys.src == k->src &&
+ tpos->keys.dst == k->dst &&
+ tpos->keys.ports == k->ports &&
+ tpos->keys.ip_proto == k->ip_proto &&
+ tpos->keys.n_proto == k->n_proto)
+ return tpos;
+ return NULL;
+}
+
+int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+ u16 rxq_index, u32 flow_id)
+{
+ struct flow_keys keys;
+ struct enic_rfs_fltr_node *n;
+ struct enic *enic;
+ u16 tbl_idx;
+ int res, i;
+
+ enic = netdev_priv(dev);
+ res = skb_flow_dissect(skb, &keys);
+ if (!res || keys.n_proto != htons(ETH_P_IP) ||
+ (keys.ip_proto != IPPROTO_TCP && keys.ip_proto != IPPROTO_UDP))
+ return -EPROTONOSUPPORT;
+
+ tbl_idx = skb_get_hash_raw(skb) & ENIC_RFS_FLW_MASK;
+ spin_lock(&enic->rfs_h.lock);
+ n = htbl_key_search(&enic->rfs_h.ht_head[tbl_idx], &keys);
+
+ if (n) { /* entry already present */
+ if (rxq_index == n->rq_id) {
+ res = -EEXIST;
+ goto ret_unlock;
+ }
+
+ /* desired rq changed for the flow, we need to delete
+ * old fltr and add new one
+ *
+ * The moment we delete the fltr, the upcoming pkts
+ * are put it default rq based on rss. When we add
+ * new filter, upcoming pkts are put in desired queue.
+ * This could cause ooo pkts.
+ *
+ * Lets 1st try adding new fltr and then del old one.
+ */
+ i = --enic->rfs_h.free;
+ /* clsf tbl is full, we have to del old fltr first*/
+ if (unlikely(i < 0)) {
+ enic->rfs_h.free++;
+ res = enic_delfltr(enic, n->fltr_id);
+ if (unlikely(res < 0))
+ goto ret_unlock;
+ res = enic_addfltr_5t(enic, &keys, rxq_index);
+ if (res < 0) {
+ hlist_del(&n->node);
+ enic->rfs_h.free++;
+ goto ret_unlock;
+ }
+ /* add new fltr 1st then del old fltr */
+ } else {
+ int ret;
+
+ res = enic_addfltr_5t(enic, &keys, rxq_index);
+ if (res < 0) {
+ enic->rfs_h.free++;
+ goto ret_unlock;
+ }
+ ret = enic_delfltr(enic, n->fltr_id);
+ /* deleting old fltr failed. Add old fltr to list.
+ * enic_flow_may_expire() will try to delete it later.
+ */
+ if (unlikely(ret < 0)) {
+ struct enic_rfs_fltr_node *d;
+ struct hlist_head *head;
+
+ head = &enic->rfs_h.ht_head[tbl_idx];
+ d = kmalloc(sizeof(*d), GFP_ATOMIC);
+ if (d) {
+ d->fltr_id = n->fltr_id;
+ INIT_HLIST_NODE(&d->node);
+ hlist_add_head(&d->node, head);
+ }
+ } else {
+ enic->rfs_h.free++;
+ }
+ }
+ n->rq_id = rxq_index;
+ n->fltr_id = res;
+ n->flow_id = flow_id;
+ /* entry not present */
+ } else {
+ i = --enic->rfs_h.free;
+ if (i <= 0) {
+ enic->rfs_h.free++;
+ res = -EBUSY;
+ goto ret_unlock;
+ }
+
+ n = kmalloc(sizeof(*n), GFP_ATOMIC);
+ if (!n) {
+ res = -ENOMEM;
+ enic->rfs_h.free++;
+ goto ret_unlock;
+ }
+
+ res = enic_addfltr_5t(enic, &keys, rxq_index);
+ if (res < 0) {
+ kfree(n);
+ enic->rfs_h.free++;
+ goto ret_unlock;
+ }
+ n->rq_id = rxq_index;
+ n->fltr_id = res;
+ n->flow_id = flow_id;
+ n->keys = keys;
+ INIT_HLIST_NODE(&n->node);
+ hlist_add_head(&n->node, &enic->rfs_h.ht_head[tbl_idx]);
+ }
+
+ret_unlock:
+ spin_unlock(&enic->rfs_h.lock);
+ return res;
+}
+
+#endif /* CONFIG_RFS_ACCEL */
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.h b/drivers/net/ethernet/cisco/enic/enic_clsf.h
new file mode 100644
index 000000000000..6aa9f89d073b
--- /dev/null
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.h
@@ -0,0 +1,37 @@
+#ifndef _ENIC_CLSF_H_
+#define _ENIC_CLSF_H_
+
+#include "vnic_dev.h"
+#include "enic.h"
+
+#define ENIC_CLSF_EXPIRE_COUNT 128
+
+int enic_addfltr_5t(struct enic *enic, struct flow_keys *keys, u16 rq);
+int enic_delfltr(struct enic *enic, u16 filter_id);
+void enic_rfs_flw_tbl_init(struct enic *enic);
+void enic_rfs_flw_tbl_free(struct enic *enic);
+struct enic_rfs_fltr_node *htbl_fltr_search(struct enic *enic, u16 fltr_id);
+
+#ifdef CONFIG_RFS_ACCEL
+int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+ u16 rxq_index, u32 flow_id);
+void enic_flow_may_expire(unsigned long data);
+
+static inline void enic_rfs_timer_start(struct enic *enic)
+{
+ init_timer(&enic->rfs_h.rfs_may_expire);
+ enic->rfs_h.rfs_may_expire.function = enic_flow_may_expire;
+ enic->rfs_h.rfs_may_expire.data = (unsigned long)enic;
+ mod_timer(&enic->rfs_h.rfs_may_expire, jiffies + HZ/4);
+}
+
+static inline void enic_rfs_timer_stop(struct enic *enic)
+{
+ del_timer_sync(&enic->rfs_h.rfs_may_expire);
+}
+#else
+static inline void enic_rfs_timer_start(struct enic *enic) {}
+static inline void enic_rfs_timer_stop(struct enic *enic) {}
+#endif /* CONFIG_RFS_ACCEL */
+
+#endif /* _ENIC_CLSF_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.c b/drivers/net/ethernet/cisco/enic/enic_dev.c
index 3e27df522847..87ddc44b590e 100644
--- a/drivers/net/ethernet/cisco/enic/enic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.c
@@ -29,9 +29,9 @@ int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_fw_info(enic->vdev, fw_info);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -40,9 +40,9 @@ int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_stats_dump(enic->vdev, vstats);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -54,9 +54,9 @@ int enic_dev_add_station_addr(struct enic *enic)
if (!is_valid_ether_addr(enic->netdev->dev_addr))
return -EADDRNOTAVAIL;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -68,9 +68,9 @@ int enic_dev_del_station_addr(struct enic *enic)
if (!is_valid_ether_addr(enic->netdev->dev_addr))
return -EADDRNOTAVAIL;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -80,10 +80,10 @@ int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_packet_filter(enic->vdev, directed,
multicast, broadcast, promisc, allmulti);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -92,9 +92,9 @@ int enic_dev_add_addr(struct enic *enic, const u8 *addr)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_add_addr(enic->vdev, addr);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -103,9 +103,9 @@ int enic_dev_del_addr(struct enic *enic, const u8 *addr)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_del_addr(enic->vdev, addr);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -114,9 +114,9 @@ int enic_dev_notify_unset(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_notify_unset(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -125,9 +125,9 @@ int enic_dev_hang_notify(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_hang_notify(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -136,10 +136,10 @@ int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -148,9 +148,9 @@ int enic_dev_enable(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_enable_wait(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -159,9 +159,9 @@ int enic_dev_disable(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_disable(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -170,9 +170,9 @@ int enic_dev_intr_coal_timer_info(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_intr_coal_timer_info(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -181,9 +181,9 @@ int enic_vnic_dev_deinit(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_deinit(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -192,10 +192,10 @@ int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_init_prov2(enic->vdev,
(u8 *)vp, vic_provinfo_size(vp));
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -204,9 +204,9 @@ int enic_dev_deinit_done(struct enic *enic, int *status)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_deinit_done(enic->vdev, status);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -217,9 +217,9 @@ int enic_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
struct enic *enic = netdev_priv(netdev);
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = enic_add_vlan(enic, vid);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -230,9 +230,9 @@ int enic_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
struct enic *enic = netdev_priv(netdev);
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = enic_del_vlan(enic, vid);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -241,9 +241,9 @@ int enic_dev_enable2(struct enic *enic, int active)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_enable2(enic->vdev, active);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -252,9 +252,9 @@ int enic_dev_enable2_done(struct enic *enic, int *status)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = vnic_dev_enable2_done(enic->vdev, status);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
diff --git a/drivers/net/ethernet/cisco/enic/enic_dev.h b/drivers/net/ethernet/cisco/enic/enic_dev.h
index 36ea1ab25f6a..10bb970b2f35 100644
--- a/drivers/net/ethernet/cisco/enic/enic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/enic_dev.h
@@ -28,7 +28,7 @@
*/
#define ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnicdevcmdfn, ...) \
do { \
- spin_lock(&enic->devcmd_lock); \
+ spin_lock_bh(&enic->devcmd_lock); \
if (enic_is_valid_vf(enic, vf)) { \
vnic_dev_cmd_proxy_by_index_start(enic->vdev, vf); \
err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
@@ -36,7 +36,7 @@
} else { \
err = vnicdevcmdfn(enic->vdev, ##__VA_ARGS__); \
} \
- spin_unlock(&enic->devcmd_lock); \
+ spin_unlock_bh(&enic->devcmd_lock); \
} while (0)
int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info);
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index 2e50b5489d20..523c9ceb04c0 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -22,6 +22,7 @@
#include "enic_res.h"
#include "enic.h"
#include "enic_dev.h"
+#include "enic_clsf.h"
struct enic_stat {
char name[ETH_GSTRING_LEN];
@@ -231,7 +232,7 @@ static int enic_set_coalesce(struct net_device *netdev,
if (ecmd->use_adaptive_rx_coalesce ||
ecmd->rx_coalesce_usecs_low ||
ecmd->rx_coalesce_usecs_high)
- return -EOPNOTSUPP;
+ return -EINVAL;
intr = enic_legacy_io_intr();
vnic_intr_coalescing_timer_set(&enic->intr[intr],
@@ -243,34 +244,29 @@ static int enic_set_coalesce(struct net_device *netdev,
if (ecmd->use_adaptive_rx_coalesce ||
ecmd->rx_coalesce_usecs_low ||
ecmd->rx_coalesce_usecs_high)
- return -EOPNOTSUPP;
+ return -EINVAL;
vnic_intr_coalescing_timer_set(&enic->intr[0],
tx_coalesce_usecs);
break;
case VNIC_DEV_INTR_MODE_MSIX:
+ if (ecmd->rx_coalesce_usecs_high &&
+ (rx_coalesce_usecs_high <
+ rx_coalesce_usecs_low + ENIC_AIC_LARGE_PKT_DIFF))
+ return -EINVAL;
+
for (i = 0; i < enic->wq_count; i++) {
intr = enic_msix_wq_intr(enic, i);
vnic_intr_coalescing_timer_set(&enic->intr[intr],
tx_coalesce_usecs);
}
- if (rxcoal->use_adaptive_rx_coalesce) {
- if (!ecmd->use_adaptive_rx_coalesce) {
- rxcoal->use_adaptive_rx_coalesce = 0;
- enic_intr_coal_set_rx(enic, rx_coalesce_usecs);
- }
- } else {
- if (ecmd->use_adaptive_rx_coalesce)
- rxcoal->use_adaptive_rx_coalesce = 1;
- else
- enic_intr_coal_set_rx(enic, rx_coalesce_usecs);
- }
+ rxcoal->use_adaptive_rx_coalesce =
+ !!ecmd->use_adaptive_rx_coalesce;
+ if (!rxcoal->use_adaptive_rx_coalesce)
+ enic_intr_coal_set_rx(enic, rx_coalesce_usecs);
if (ecmd->rx_coalesce_usecs_high) {
- if (rx_coalesce_usecs_high <
- (rx_coalesce_usecs_low + ENIC_AIC_LARGE_PKT_DIFF))
- return -EINVAL;
rxcoal->range_end = rx_coalesce_usecs_high;
rxcoal->small_pkt_range_start = rx_coalesce_usecs_low;
rxcoal->large_pkt_range_start = rx_coalesce_usecs_low +
@@ -287,6 +283,102 @@ static int enic_set_coalesce(struct net_device *netdev,
return 0;
}
+static int enic_grxclsrlall(struct enic *enic, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+{
+ int j, ret = 0, cnt = 0;
+
+ cmd->data = enic->rfs_h.max - enic->rfs_h.free;
+ for (j = 0; j < (1 << ENIC_RFS_FLW_BITSHIFT); j++) {
+ struct hlist_head *hhead;
+ struct hlist_node *tmp;
+ struct enic_rfs_fltr_node *n;
+
+ hhead = &enic->rfs_h.ht_head[j];
+ hlist_for_each_entry_safe(n, tmp, hhead, node) {
+ if (cnt == cmd->rule_cnt)
+ return -EMSGSIZE;
+ rule_locs[cnt] = n->fltr_id;
+ cnt++;
+ }
+ }
+ cmd->rule_cnt = cnt;
+
+ return ret;
+}
+
+static int enic_grxclsrule(struct enic *enic, struct ethtool_rxnfc *cmd)
+{
+ struct ethtool_rx_flow_spec *fsp =
+ (struct ethtool_rx_flow_spec *)&cmd->fs;
+ struct enic_rfs_fltr_node *n;
+
+ n = htbl_fltr_search(enic, (u16)fsp->location);
+ if (!n)
+ return -EINVAL;
+ switch (n->keys.ip_proto) {
+ case IPPROTO_TCP:
+ fsp->flow_type = TCP_V4_FLOW;
+ break;
+ case IPPROTO_UDP:
+ fsp->flow_type = UDP_V4_FLOW;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ fsp->h_u.tcp_ip4_spec.ip4src = n->keys.src;
+ fsp->m_u.tcp_ip4_spec.ip4src = (__u32)~0;
+
+ fsp->h_u.tcp_ip4_spec.ip4dst = n->keys.dst;
+ fsp->m_u.tcp_ip4_spec.ip4dst = (__u32)~0;
+
+ fsp->h_u.tcp_ip4_spec.psrc = n->keys.port16[0];
+ fsp->m_u.tcp_ip4_spec.psrc = (__u16)~0;
+
+ fsp->h_u.tcp_ip4_spec.pdst = n->keys.port16[1];
+ fsp->m_u.tcp_ip4_spec.pdst = (__u16)~0;
+
+ fsp->ring_cookie = n->rq_id;
+
+ return 0;
+}
+
+static int enic_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+{
+ struct enic *enic = netdev_priv(dev);
+ int ret = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+ cmd->data = enic->rq_count;
+ break;
+ case ETHTOOL_GRXCLSRLCNT:
+ spin_lock_bh(&enic->rfs_h.lock);
+ cmd->rule_cnt = enic->rfs_h.max - enic->rfs_h.free;
+ cmd->data = enic->rfs_h.max;
+ spin_unlock_bh(&enic->rfs_h.lock);
+ break;
+ case ETHTOOL_GRXCLSRLALL:
+ spin_lock_bh(&enic->rfs_h.lock);
+ ret = enic_grxclsrlall(enic, cmd, rule_locs);
+ spin_unlock_bh(&enic->rfs_h.lock);
+ break;
+ case ETHTOOL_GRXCLSRULE:
+ spin_lock_bh(&enic->rfs_h.lock);
+ ret = enic_grxclsrule(enic, cmd);
+ spin_unlock_bh(&enic->rfs_h.lock);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
static const struct ethtool_ops enic_ethtool_ops = {
.get_settings = enic_get_settings,
.get_drvinfo = enic_get_drvinfo,
@@ -298,6 +390,7 @@ static const struct ethtool_ops enic_ethtool_ops = {
.get_ethtool_stats = enic_get_ethtool_stats,
.get_coalesce = enic_get_coalesce,
.set_coalesce = enic_set_coalesce,
+ .get_rxnfc = enic_get_rxnfc,
};
void enic_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index f32f828b7f3d..9348febc0743 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -39,6 +39,12 @@
#include <linux/prefetch.h>
#include <net/ip6_checksum.h>
#include <linux/ktime.h>
+#ifdef CONFIG_RFS_ACCEL
+#include <linux/cpu_rmap.h>
+#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#include <net/busy_poll.h>
+#endif
#include "cq_enet_desc.h"
#include "vnic_dev.h"
@@ -49,6 +55,7 @@
#include "enic.h"
#include "enic_dev.h"
#include "enic_pp.h"
+#include "enic_clsf.h"
#define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ)
#define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS)
@@ -309,40 +316,15 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
return IRQ_HANDLED;
}
-static irqreturn_t enic_isr_msix_rq(int irq, void *data)
+static irqreturn_t enic_isr_msix(int irq, void *data)
{
struct napi_struct *napi = data;
- /* schedule NAPI polling for RQ cleanup */
napi_schedule(napi);
return IRQ_HANDLED;
}
-static irqreturn_t enic_isr_msix_wq(int irq, void *data)
-{
- struct enic *enic = data;
- unsigned int cq;
- unsigned int intr;
- unsigned int wq_work_to_do = -1; /* no limit */
- unsigned int wq_work_done;
- unsigned int wq_irq;
-
- wq_irq = (u32)irq - enic->msix_entry[enic_msix_wq_intr(enic, 0)].vector;
- cq = enic_cq_wq(enic, wq_irq);
- intr = enic_msix_wq_intr(enic, wq_irq);
-
- wq_work_done = vnic_cq_service(&enic->cq[cq],
- wq_work_to_do, enic_wq_service, NULL);
-
- vnic_intr_return_credits(&enic->intr[intr],
- wq_work_done,
- 1 /* unmask intr */,
- 1 /* reset intr timer */);
-
- return IRQ_HANDLED;
-}
-
static irqreturn_t enic_isr_msix_err(int irq, void *data)
{
struct enic *enic = data;
@@ -1049,10 +1031,12 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
if (vlan_stripped)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
- if (netdev->features & NETIF_F_GRO)
- napi_gro_receive(&enic->napi[q_number], skb);
- else
+ skb_mark_napi_id(skb, &enic->napi[rq->index]);
+ if (enic_poll_busy_polling(rq) ||
+ !(netdev->features & NETIF_F_GRO))
netif_receive_skb(skb);
+ else
+ napi_gro_receive(&enic->napi[q_number], skb);
if (enic->rx_coalesce_setting.use_adaptive_rx_coalesce)
enic_intr_update_pkt_size(&cq->pkt_size_counter,
bytes_written);
@@ -1089,16 +1073,22 @@ static int enic_poll(struct napi_struct *napi, int budget)
unsigned int work_done, rq_work_done = 0, wq_work_done;
int err;
- /* Service RQ (first) and WQ
- */
+ wq_work_done = vnic_cq_service(&enic->cq[cq_wq], wq_work_to_do,
+ enic_wq_service, NULL);
+
+ if (!enic_poll_lock_napi(&enic->rq[cq_rq])) {
+ if (wq_work_done > 0)
+ vnic_intr_return_credits(&enic->intr[intr],
+ wq_work_done,
+ 0 /* dont unmask intr */,
+ 0 /* dont reset intr timer */);
+ return rq_work_done;
+ }
if (budget > 0)
rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
rq_work_to_do, enic_rq_service, NULL);
- wq_work_done = vnic_cq_service(&enic->cq[cq_wq],
- wq_work_to_do, enic_wq_service, NULL);
-
/* Accumulate intr event credits for this polling
* cycle. An intr event is the completion of a
* a WQ or RQ packet.
@@ -1130,6 +1120,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
napi_complete(napi);
vnic_intr_unmask(&enic->intr[intr]);
}
+ enic_poll_unlock_napi(&enic->rq[cq_rq]);
return rq_work_done;
}
@@ -1192,7 +1183,102 @@ static void enic_calc_int_moderation(struct enic *enic, struct vnic_rq *rq)
pkt_size_counter->small_pkt_bytes_cnt = 0;
}
-static int enic_poll_msix(struct napi_struct *napi, int budget)
+#ifdef CONFIG_RFS_ACCEL
+static void enic_free_rx_cpu_rmap(struct enic *enic)
+{
+ free_irq_cpu_rmap(enic->netdev->rx_cpu_rmap);
+ enic->netdev->rx_cpu_rmap = NULL;
+}
+
+static void enic_set_rx_cpu_rmap(struct enic *enic)
+{
+ int i, res;
+
+ if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX) {
+ enic->netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(enic->rq_count);
+ if (unlikely(!enic->netdev->rx_cpu_rmap))
+ return;
+ for (i = 0; i < enic->rq_count; i++) {
+ res = irq_cpu_rmap_add(enic->netdev->rx_cpu_rmap,
+ enic->msix_entry[i].vector);
+ if (unlikely(res)) {
+ enic_free_rx_cpu_rmap(enic);
+ return;
+ }
+ }
+ }
+}
+
+#else
+
+static void enic_free_rx_cpu_rmap(struct enic *enic)
+{
+}
+
+static void enic_set_rx_cpu_rmap(struct enic *enic)
+{
+}
+
+#endif /* CONFIG_RFS_ACCEL */
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+int enic_busy_poll(struct napi_struct *napi)
+{
+ struct net_device *netdev = napi->dev;
+ struct enic *enic = netdev_priv(netdev);
+ unsigned int rq = (napi - &enic->napi[0]);
+ unsigned int cq = enic_cq_rq(enic, rq);
+ unsigned int intr = enic_msix_rq_intr(enic, rq);
+ unsigned int work_to_do = -1; /* clean all pkts possible */
+ unsigned int work_done;
+
+ if (!enic_poll_lock_poll(&enic->rq[rq]))
+ return LL_FLUSH_BUSY;
+ work_done = vnic_cq_service(&enic->cq[cq], work_to_do,
+ enic_rq_service, NULL);
+
+ if (work_done > 0)
+ vnic_intr_return_credits(&enic->intr[intr],
+ work_done, 0, 0);
+ vnic_rq_fill(&enic->rq[rq], enic_rq_alloc_buf);
+ if (enic->rx_coalesce_setting.use_adaptive_rx_coalesce)
+ enic_calc_int_moderation(enic, &enic->rq[rq]);
+ enic_poll_unlock_poll(&enic->rq[rq]);
+
+ return work_done;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
+static int enic_poll_msix_wq(struct napi_struct *napi, int budget)
+{
+ struct net_device *netdev = napi->dev;
+ struct enic *enic = netdev_priv(netdev);
+ unsigned int wq_index = (napi - &enic->napi[0]) - enic->rq_count;
+ struct vnic_wq *wq = &enic->wq[wq_index];
+ unsigned int cq;
+ unsigned int intr;
+ unsigned int wq_work_to_do = -1; /* clean all desc possible */
+ unsigned int wq_work_done;
+ unsigned int wq_irq;
+
+ wq_irq = wq->index;
+ cq = enic_cq_wq(enic, wq_irq);
+ intr = enic_msix_wq_intr(enic, wq_irq);
+ wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do,
+ enic_wq_service, NULL);
+
+ vnic_intr_return_credits(&enic->intr[intr], wq_work_done,
+ 0 /* don't unmask intr */,
+ 1 /* reset intr timer */);
+ if (!wq_work_done) {
+ napi_complete(napi);
+ vnic_intr_unmask(&enic->intr[intr]);
+ }
+
+ return 0;
+}
+
+static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
{
struct net_device *netdev = napi->dev;
struct enic *enic = netdev_priv(netdev);
@@ -1203,6 +1289,8 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
unsigned int work_done = 0;
int err;
+ if (!enic_poll_lock_napi(&enic->rq[rq]))
+ return work_done;
/* Service RQ
*/
@@ -1248,6 +1336,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
enic_set_int_moderation(enic, &enic->rq[rq]);
vnic_intr_unmask(&enic->intr[intr]);
}
+ enic_poll_unlock_napi(&enic->rq[rq]);
return work_done;
}
@@ -1267,6 +1356,7 @@ static void enic_free_intr(struct enic *enic)
struct net_device *netdev = enic->netdev;
unsigned int i;
+ enic_free_rx_cpu_rmap(enic);
switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
free_irq(enic->pdev->irq, netdev);
@@ -1291,6 +1381,7 @@ static int enic_request_intr(struct enic *enic)
unsigned int i, intr;
int err = 0;
+ enic_set_rx_cpu_rmap(enic);
switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
@@ -1312,17 +1403,19 @@ static int enic_request_intr(struct enic *enic)
snprintf(enic->msix[intr].devname,
sizeof(enic->msix[intr].devname),
"%.11s-rx-%d", netdev->name, i);
- enic->msix[intr].isr = enic_isr_msix_rq;
+ enic->msix[intr].isr = enic_isr_msix;
enic->msix[intr].devid = &enic->napi[i];
}
for (i = 0; i < enic->wq_count; i++) {
+ int wq = enic_cq_wq(enic, i);
+
intr = enic_msix_wq_intr(enic, i);
snprintf(enic->msix[intr].devname,
sizeof(enic->msix[intr].devname),
"%.11s-tx-%d", netdev->name, i);
- enic->msix[intr].isr = enic_isr_msix_wq;
- enic->msix[intr].devid = enic;
+ enic->msix[intr].isr = enic_isr_msix;
+ enic->msix[intr].devid = &enic->napi[wq];
}
intr = enic_msix_err_intr(enic);
@@ -1421,7 +1514,7 @@ static int enic_dev_notify_set(struct enic *enic)
{
int err;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
switch (vnic_dev_get_intr_mode(enic->vdev)) {
case VNIC_DEV_INTR_MODE_INTX:
err = vnic_dev_notify_set(enic->vdev,
@@ -1435,7 +1528,7 @@ static int enic_dev_notify_set(struct enic *enic)
err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */);
break;
}
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -1494,15 +1587,20 @@ static int enic_open(struct net_device *netdev)
netif_tx_wake_all_queues(netdev);
- for (i = 0; i < enic->rq_count; i++)
+ for (i = 0; i < enic->rq_count; i++) {
+ enic_busy_poll_init_lock(&enic->rq[i]);
napi_enable(&enic->napi[i]);
-
+ }
+ if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
+ for (i = 0; i < enic->wq_count; i++)
+ napi_enable(&enic->napi[enic_cq_wq(enic, i)]);
enic_dev_enable(enic);
for (i = 0; i < enic->intr_count; i++)
vnic_intr_unmask(&enic->intr[i]);
enic_notify_timer_start(enic);
+ enic_rfs_flw_tbl_init(enic);
return 0;
@@ -1529,14 +1627,23 @@ static int enic_stop(struct net_device *netdev)
enic_synchronize_irqs(enic);
del_timer_sync(&enic->notify_timer);
+ enic_rfs_flw_tbl_free(enic);
enic_dev_disable(enic);
- for (i = 0; i < enic->rq_count; i++)
+ local_bh_disable();
+ for (i = 0; i < enic->rq_count; i++) {
napi_disable(&enic->napi[i]);
+ while (!enic_poll_lock_napi(&enic->rq[i]))
+ mdelay(1);
+ }
+ local_bh_enable();
netif_carrier_off(netdev);
netif_tx_disable(netdev);
+ if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
+ for (i = 0; i < enic->wq_count; i++)
+ napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
enic_dev_del_station_addr(enic);
@@ -1656,13 +1763,14 @@ static void enic_poll_controller(struct net_device *netdev)
case VNIC_DEV_INTR_MODE_MSIX:
for (i = 0; i < enic->rq_count; i++) {
intr = enic_msix_rq_intr(enic, i);
- enic_isr_msix_rq(enic->msix_entry[intr].vector,
- &enic->napi[i]);
+ enic_isr_msix(enic->msix_entry[intr].vector,
+ &enic->napi[i]);
}
for (i = 0; i < enic->wq_count; i++) {
intr = enic_msix_wq_intr(enic, i);
- enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
+ enic_isr_msix(enic->msix_entry[intr].vector,
+ &enic->napi[enic_cq_wq(enic, i)]);
}
break;
@@ -1758,11 +1866,11 @@ static int enic_set_rsskey(struct enic *enic)
memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key));
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = enic_set_rss_key(enic,
rss_key_buf_pa,
sizeof(union vnic_rss_key));
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key),
rss_key_buf_va, rss_key_buf_pa);
@@ -1785,11 +1893,11 @@ static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits)
for (i = 0; i < (1 << rss_hash_bits); i++)
(*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count;
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = enic_set_rss_cpu(enic,
rss_cpu_buf_pa,
sizeof(union vnic_rss_cpu));
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu),
rss_cpu_buf_va, rss_cpu_buf_pa);
@@ -1807,13 +1915,13 @@ static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu,
/* Enable VLAN tag stripping.
*/
- spin_lock(&enic->devcmd_lock);
+ spin_lock_bh(&enic->devcmd_lock);
err = enic_set_nic_cfg(enic,
rss_default_cpu, rss_hash_type,
rss_hash_bits, rss_base_cpu,
rss_enable, tso_ipid_split_en,
ig_vlan_strip_en);
- spin_unlock(&enic->devcmd_lock);
+ spin_unlock_bh(&enic->devcmd_lock);
return err;
}
@@ -2021,6 +2129,12 @@ static const struct net_device_ops enic_netdev_dynamic_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = enic_poll_controller,
#endif
+#ifdef CONFIG_RFS_ACCEL
+ .ndo_rx_flow_steer = enic_rx_flow_steer,
+#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = enic_busy_poll,
+#endif
};
static const struct net_device_ops enic_netdev_ops = {
@@ -2041,14 +2155,25 @@ static const struct net_device_ops enic_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = enic_poll_controller,
#endif
+#ifdef CONFIG_RFS_ACCEL
+ .ndo_rx_flow_steer = enic_rx_flow_steer,
+#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = enic_busy_poll,
+#endif
};
static void enic_dev_deinit(struct enic *enic)
{
unsigned int i;
- for (i = 0; i < enic->rq_count; i++)
+ for (i = 0; i < enic->rq_count; i++) {
+ napi_hash_del(&enic->napi[i]);
netif_napi_del(&enic->napi[i]);
+ }
+ if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
+ for (i = 0; i < enic->wq_count; i++)
+ netif_napi_del(&enic->napi[enic_cq_wq(enic, i)]);
enic_free_vnic_resources(enic);
enic_clear_intr_mode(enic);
@@ -2114,11 +2239,17 @@ static int enic_dev_init(struct enic *enic)
switch (vnic_dev_get_intr_mode(enic->vdev)) {
default:
netif_napi_add(netdev, &enic->napi[0], enic_poll, 64);
+ napi_hash_add(&enic->napi[0]);
break;
case VNIC_DEV_INTR_MODE_MSIX:
- for (i = 0; i < enic->rq_count; i++)
+ for (i = 0; i < enic->rq_count; i++) {
netif_napi_add(netdev, &enic->napi[i],
- enic_poll_msix, 64);
+ enic_poll_msix_rq, NAPI_POLL_WEIGHT);
+ napi_hash_add(&enic->napi[i]);
+ }
+ for (i = 0; i < enic->wq_count; i++)
+ netif_napi_add(netdev, &enic->napi[enic_cq_wq(enic, i)],
+ enic_poll_msix_wq, NAPI_POLL_WEIGHT);
break;
}
@@ -2386,6 +2517,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->features |= netdev->hw_features;
+#ifdef CONFIG_RFS_ACCEL
+ netdev->hw_features |= NETIF_F_NTUPLE;
+#endif
+
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/ethernet/cisco/enic/enic_res.c b/drivers/net/ethernet/cisco/enic/enic_res.c
index 31d658880c3c..9c96911fb2c8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_res.c
+++ b/drivers/net/ethernet/cisco/enic/enic_res.c
@@ -71,6 +71,7 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(intr_mode);
GET_CONFIG(intr_timer_usec);
GET_CONFIG(loop_tag);
+ GET_CONFIG(num_arfs);
c->wq_desc_count =
min_t(u32, ENIC_MAX_WQ_DESCS,
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index e86a45cb9e68..5abc496bcf29 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -312,12 +312,12 @@ static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
err = (int)readq(&devcmd->args[0]);
if (err == ERR_EINVAL &&
cmd == CMD_CAPABILITY)
- return err;
+ return -err;
if (err != ERR_ECMDUNKNOWN ||
cmd != CMD_CAPABILITY)
pr_err("Error %d devcmd %d\n",
err, _CMD_N(cmd));
- return err;
+ return -err;
}
if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
@@ -1048,3 +1048,64 @@ int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
return vnic_dev_cmd(vdev, CMD_SET_MAC_ADDR, &a0, &a1, wait);
}
+
+/* vnic_dev_classifier: Add/Delete classifier entries
+ * @vdev: vdev of the device
+ * @cmd: CLSF_ADD for Add filter
+ * CLSF_DEL for Delete filter
+ * @entry: In case of ADD filter, the caller passes the RQ number in this
+ * variable.
+ *
+ * This function stores the filter_id returned by the firmware in the
+ * same variable before return;
+ *
+ * In case of DEL filter, the caller passes the RQ number. Return
+ * value is irrelevant.
+ * @data: filter data
+ */
+int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
+ struct filter *data)
+{
+ u64 a0, a1;
+ int wait = 1000;
+ dma_addr_t tlv_pa;
+ int ret = -EINVAL;
+ struct filter_tlv *tlv, *tlv_va;
+ struct filter_action *action;
+ u64 tlv_size;
+
+ if (cmd == CLSF_ADD) {
+ tlv_size = sizeof(struct filter) +
+ sizeof(struct filter_action) +
+ 2 * sizeof(struct filter_tlv);
+ tlv_va = pci_alloc_consistent(vdev->pdev, tlv_size, &tlv_pa);
+ if (!tlv_va)
+ return -ENOMEM;
+ tlv = tlv_va;
+ a0 = tlv_pa;
+ a1 = tlv_size;
+ memset(tlv, 0, tlv_size);
+ tlv->type = CLSF_TLV_FILTER;
+ tlv->length = sizeof(struct filter);
+ *(struct filter *)&tlv->val = *data;
+
+ tlv = (struct filter_tlv *)((char *)tlv +
+ sizeof(struct filter_tlv) +
+ sizeof(struct filter));
+
+ tlv->type = CLSF_TLV_ACTION;
+ tlv->length = sizeof(struct filter_action);
+ action = (struct filter_action *)&tlv->val;
+ action->type = FILTER_ACTION_RQ_STEERING;
+ action->u.rq_idx = *entry;
+
+ ret = vnic_dev_cmd(vdev, CMD_ADD_FILTER, &a0, &a1, wait);
+ *entry = (u16)a0;
+ pci_free_consistent(vdev->pdev, tlv_size, tlv_va, tlv_pa);
+ } else if (cmd == CLSF_DEL) {
+ a0 = *entry;
+ ret = vnic_dev_cmd(vdev, CMD_DEL_FILTER, &a0, &a1, wait);
+ }
+
+ return ret;
+}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index 1f3b301f8225..1fb214efceba 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -133,5 +133,7 @@ int vnic_dev_enable2(struct vnic_dev *vdev, int active);
int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
+int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
+ struct filter *data);
#endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
index b9a0d78fd639..435d0cd96c22 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
@@ -603,6 +603,11 @@ struct filter_tlv {
u_int32_t val[0];
};
+enum {
+ CLSF_ADD = 0,
+ CLSF_DEL = 1,
+};
+
/*
* Writing cmd register causes STAT_BUSY to get set in status register.
* When cmd completes, STAT_BUSY will be cleared.
diff --git a/drivers/net/ethernet/cisco/enic/vnic_enet.h b/drivers/net/ethernet/cisco/enic/vnic_enet.h
index 609542848e02..75aced2de869 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_enet.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_enet.h
@@ -32,6 +32,8 @@ struct vnic_enet_config {
char devname[16];
u32 intr_timer_usec;
u16 loop_tag;
+ u16 vf_rq_count;
+ u16 num_arfs;
};
#define VENETF_TSO 0x1 /* TSO enabled */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.h b/drivers/net/ethernet/cisco/enic/vnic_rq.h
index ee7bc95af278..8111d5202df2 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.h
@@ -85,6 +85,21 @@ struct vnic_rq {
struct vnic_rq_buf *to_clean;
void *os_buf_head;
unsigned int pkts_outstanding;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#define ENIC_POLL_STATE_IDLE 0
+#define ENIC_POLL_STATE_NAPI (1 << 0) /* NAPI owns this poll */
+#define ENIC_POLL_STATE_POLL (1 << 1) /* poll owns this poll */
+#define ENIC_POLL_STATE_NAPI_YIELD (1 << 2) /* NAPI yielded this poll */
+#define ENIC_POLL_STATE_POLL_YIELD (1 << 3) /* poll yielded this poll */
+#define ENIC_POLL_YIELD (ENIC_POLL_STATE_NAPI_YIELD | \
+ ENIC_POLL_STATE_POLL_YIELD)
+#define ENIC_POLL_LOCKED (ENIC_POLL_STATE_NAPI | \
+ ENIC_POLL_STATE_POLL)
+#define ENIC_POLL_USER_PEND (ENIC_POLL_STATE_POLL | \
+ ENIC_POLL_STATE_POLL_YIELD)
+ unsigned int bpoll_state;
+ spinlock_t bpoll_lock;
+#endif /* CONFIG_NET_RX_BUSY_POLL */
};
static inline unsigned int vnic_rq_desc_avail(struct vnic_rq *rq)
@@ -197,6 +212,113 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
return 0;
}
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void enic_busy_poll_init_lock(struct vnic_rq *rq)
+{
+ spin_lock_init(&rq->bpoll_lock);
+ rq->bpoll_state = ENIC_POLL_STATE_IDLE;
+}
+
+static inline bool enic_poll_lock_napi(struct vnic_rq *rq)
+{
+ bool rc = true;
+
+ spin_lock(&rq->bpoll_lock);
+ if (rq->bpoll_state & ENIC_POLL_LOCKED) {
+ WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI);
+ rq->bpoll_state |= ENIC_POLL_STATE_NAPI_YIELD;
+ rc = false;
+ } else {
+ rq->bpoll_state = ENIC_POLL_STATE_NAPI;
+ }
+ spin_unlock(&rq->bpoll_lock);
+
+ return rc;
+}
+
+static inline bool enic_poll_unlock_napi(struct vnic_rq *rq)
+{
+ bool rc = false;
+
+ spin_lock(&rq->bpoll_lock);
+ WARN_ON(rq->bpoll_state &
+ (ENIC_POLL_STATE_POLL | ENIC_POLL_STATE_NAPI_YIELD));
+ if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD)
+ rc = true;
+ rq->bpoll_state = ENIC_POLL_STATE_IDLE;
+ spin_unlock(&rq->bpoll_lock);
+
+ return rc;
+}
+
+static inline bool enic_poll_lock_poll(struct vnic_rq *rq)
+{
+ bool rc = true;
+
+ spin_lock_bh(&rq->bpoll_lock);
+ if (rq->bpoll_state & ENIC_POLL_LOCKED) {
+ rq->bpoll_state |= ENIC_POLL_STATE_POLL_YIELD;
+ rc = false;
+ } else {
+ rq->bpoll_state |= ENIC_POLL_STATE_POLL;
+ }
+ spin_unlock_bh(&rq->bpoll_lock);
+
+ return rc;
+}
+
+static inline bool enic_poll_unlock_poll(struct vnic_rq *rq)
+{
+ bool rc = false;
+
+ spin_lock_bh(&rq->bpoll_lock);
+ WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI);
+ if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD)
+ rc = true;
+ rq->bpoll_state = ENIC_POLL_STATE_IDLE;
+ spin_unlock_bh(&rq->bpoll_lock);
+
+ return rc;
+}
+
+static inline bool enic_poll_busy_polling(struct vnic_rq *rq)
+{
+ WARN_ON(!(rq->bpoll_state & ENIC_POLL_LOCKED));
+ return rq->bpoll_state & ENIC_POLL_USER_PEND;
+}
+
+#else
+
+static inline void enic_busy_poll_init_lock(struct vnic_rq *rq)
+{
+}
+
+static inline bool enic_poll_lock_napi(struct vnic_rq *rq)
+{
+ return true;
+}
+
+static inline bool enic_poll_unlock_napi(struct vnic_rq *rq)
+{
+ return false;
+}
+
+static inline bool enic_poll_lock_poll(struct vnic_rq *rq)
+{
+ return false;
+}
+
+static inline bool enic_poll_unlock_poll(struct vnic_rq *rq)
+{
+ return false;
+}
+
+static inline bool enic_poll_ll_polling(struct vnic_rq *rq)
+{
+ return false;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
void vnic_rq_free(struct vnic_rq *rq);
int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
unsigned int desc_count, unsigned int desc_size);
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 13723c96d1a2..23084fb2090e 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -817,10 +817,12 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
/* release the resources */
- release_resource(db->data_req);
+ if (db->data_req)
+ release_resource(db->data_req);
kfree(db->data_req);
- release_resource(db->addr_req);
+ if (db->addr_req)
+ release_resource(db->addr_req);
kfree(db->addr_req);
}
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
index c05b66dfcc30..7091fa6ed096 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -3250,7 +3250,6 @@ srom_map_media(struct net_device *dev)
printk("%s: Bad media code [%d] detected in SROM!\n", dev->name,
lp->infoblock_media);
return -1;
- break;
}
return 0;
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
index e9b0faba3078..a379c3e4b57f 100644
--- a/drivers/net/ethernet/dnet.c
+++ b/drivers/net/ethernet/dnet.c
@@ -323,7 +323,8 @@ static int dnet_mii_init(struct dnet *bp)
bp->mii_bus->priv = bp;
- bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ bp->mii_bus->irq = devm_kmalloc(&bp->pdev->dev,
+ sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
if (!bp->mii_bus->irq) {
err = -ENOMEM;
goto err_out;
@@ -334,7 +335,7 @@ static int dnet_mii_init(struct dnet *bp)
if (mdiobus_register(bp->mii_bus)) {
err = -ENXIO;
- goto err_out_free_mdio_irq;
+ goto err_out;
}
if (dnet_mii_probe(bp->dev) != 0) {
@@ -346,8 +347,6 @@ static int dnet_mii_init(struct dnet *bp)
err_out_unregister_bus:
mdiobus_unregister(bp->mii_bus);
-err_out_free_mdio_irq:
- kfree(bp->mii_bus->irq);
err_out:
mdiobus_free(bp->mii_bus);
return err;
@@ -825,28 +824,14 @@ static int dnet_probe(struct platform_device *pdev)
struct net_device *dev;
struct dnet *bp;
struct phy_device *phydev;
- int err = -ENXIO;
- unsigned int mem_base, mem_size, irq;
+ int err;
+ unsigned int irq;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "no mmio resource defined\n");
- goto err_out;
- }
- mem_base = res->start;
- mem_size = resource_size(res);
irq = platform_get_irq(pdev, 0);
- if (!request_mem_region(mem_base, mem_size, DRV_NAME)) {
- dev_err(&pdev->dev, "no memory region available\n");
- err = -EBUSY;
- goto err_out;
- }
-
- err = -ENOMEM;
dev = alloc_etherdev(sizeof(*bp));
if (!dev)
- goto err_out_release_mem;
+ return -ENOMEM;
/* TODO: Actually, we have some interesting features... */
dev->features |= 0;
@@ -859,10 +844,10 @@ static int dnet_probe(struct platform_device *pdev)
spin_lock_init(&bp->lock);
- bp->regs = ioremap(mem_base, mem_size);
- if (!bp->regs) {
- dev_err(&pdev->dev, "failed to map registers, aborting.\n");
- err = -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ bp->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(bp->regs)) {
+ err = PTR_ERR(bp->regs);
goto err_out_free_dev;
}
@@ -871,7 +856,7 @@ static int dnet_probe(struct platform_device *pdev)
if (err) {
dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n",
irq, err);
- goto err_out_iounmap;
+ goto err_out_free_dev;
}
dev->netdev_ops = &dnet_netdev_ops;
@@ -908,7 +893,7 @@ static int dnet_probe(struct platform_device *pdev)
goto err_out_unregister_netdev;
dev_info(&pdev->dev, "Dave DNET at 0x%p (0x%08x) irq %d %pM\n",
- bp->regs, mem_base, dev->irq, dev->dev_addr);
+ bp->regs, (unsigned int)res->start, dev->irq, dev->dev_addr);
dev_info(&pdev->dev, "has %smdio, %sirq, %sgigabit, %sdma\n",
(bp->capabilities & DNET_HAS_MDIO) ? "" : "no ",
(bp->capabilities & DNET_HAS_IRQ) ? "" : "no ",
@@ -925,13 +910,8 @@ err_out_unregister_netdev:
unregister_netdev(dev);
err_out_free_irq:
free_irq(dev->irq, dev);
-err_out_iounmap:
- iounmap(bp->regs);
err_out_free_dev:
free_netdev(dev);
-err_out_release_mem:
- release_mem_region(mem_base, mem_size);
-err_out:
return err;
}
@@ -948,11 +928,9 @@ static int dnet_remove(struct platform_device *pdev)
if (bp->phy_dev)
phy_disconnect(bp->phy_dev);
mdiobus_unregister(bp->mii_bus);
- kfree(bp->mii_bus->irq);
mdiobus_free(bp->mii_bus);
unregister_netdev(dev);
free_irq(dev->irq, dev);
- iounmap(bp->regs);
free_netdev(dev);
}
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index c2f5d2d3b932..811f1351db7a 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -34,7 +34,7 @@
#include "be_hw.h"
#include "be_roce.h"
-#define DRV_VER "10.2u"
+#define DRV_VER "10.4u"
#define DRV_NAME "be2net"
#define BE_NAME "Emulex BladeEngine2"
#define BE3_NAME "Emulex BladeEngine3"
@@ -372,6 +372,7 @@ enum vf_state {
};
#define BE_FLAGS_LINK_STATUS_INIT 1
+#define BE_FLAGS_SRIOV_ENABLED (1 << 2)
#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
#define BE_FLAGS_VLAN_PROMISC (1 << 4)
#define BE_FLAGS_MCAST_PROMISC (1 << 5)
@@ -382,8 +383,10 @@ enum vf_state {
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
+
/* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1
+#define LANCER_DELETE_FW_DUMP 0x2
struct phy_info {
u8 transceiver;
@@ -411,6 +414,7 @@ struct be_resources {
u16 max_vlans; /* Number of vlans supported */
u16 max_evt_qs;
u32 if_cap_flags;
+ u32 vf_if_cap_flags; /* VF if capability flags */
};
struct rss_info {
@@ -500,6 +504,7 @@ struct be_adapter {
u32 flash_status;
struct completion et_cmd_compl;
+ struct be_resources pool_res; /* resources available for the port */
struct be_resources res; /* resources available for the func */
u16 num_vfs; /* Number of VFs provisioned by PF */
u8 virtfn;
@@ -523,9 +528,9 @@ struct be_adapter {
#define be_physfn(adapter) (!adapter->virtfn)
#define be_virtfn(adapter) (adapter->virtfn)
-#define sriov_enabled(adapter) (adapter->num_vfs > 0)
-#define sriov_want(adapter) (be_physfn(adapter) && \
- (num_vfs || pci_num_vf(adapter->pdev)))
+#define sriov_enabled(adapter) (adapter->flags & \
+ BE_FLAGS_SRIOV_ENABLED)
+
#define for_all_vfs(adapter, vf_cfg, i) \
for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
i++, vf_cfg++)
@@ -536,7 +541,7 @@ struct be_adapter {
#define be_max_vlans(adapter) (adapter->res.max_vlans)
#define be_max_uc(adapter) (adapter->res.max_uc_mac)
#define be_max_mc(adapter) (adapter->res.max_mcast_mac)
-#define be_max_vfs(adapter) (adapter->res.max_vfs)
+#define be_max_vfs(adapter) (adapter->pool_res.max_vfs)
#define be_max_rss(adapter) (adapter->res.max_rss_qs)
#define be_max_txqs(adapter) (adapter->res.max_tx_qs)
#define be_max_prio_txqs(adapter) (adapter->res.max_prio_tx_qs)
@@ -671,6 +676,8 @@ static inline void swap_dws(void *wrb, int len)
#endif /* __BIG_ENDIAN */
}
+#define be_cmd_status(status) (status > 0 ? -EIO : status)
+
static inline u8 is_tcp_pkt(struct sk_buff *skb)
{
u8 val = 0;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index f4ea3490f446..4370ec1952ac 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1749,8 +1749,7 @@ err:
}
/* Uses synchronous mcc */
-int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
- char *fw_on_flash)
+int be_cmd_get_fw_ver(struct be_adapter *adapter)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_fw_version *req;
@@ -1772,9 +1771,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
- strcpy(fw_ver, resp->firmware_version_string);
- if (fw_on_flash)
- strcpy(fw_on_flash, resp->fw_on_flash_version_string);
+ strcpy(adapter->fw_ver, resp->firmware_version_string);
+ strcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string);
}
err:
spin_unlock_bh(&adapter->mcc_lock);
@@ -1997,8 +1995,7 @@ err:
}
/* Uses mbox */
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
- u32 *mode, u32 *caps, u16 *asic_rev)
+int be_cmd_query_fw_cfg(struct be_adapter *adapter)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_query_fw_cfg *req;
@@ -2017,10 +2014,10 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
- *port_num = le32_to_cpu(resp->phys_port);
- *mode = le32_to_cpu(resp->function_mode);
- *caps = le32_to_cpu(resp->function_caps);
- *asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
+ adapter->port_num = le32_to_cpu(resp->phys_port);
+ adapter->function_mode = le32_to_cpu(resp->function_mode);
+ adapter->function_caps = le32_to_cpu(resp->function_caps);
+ adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
}
mutex_unlock(&adapter->mbox_lock);
@@ -2224,7 +2221,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
msecs_to_jiffies(60000)))
- status = -1;
+ status = -ETIMEDOUT;
else
status = adapter->flash_status;
@@ -2243,6 +2240,34 @@ err_unlock:
return status;
}
+int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
+{
+ struct lancer_cmd_req_delete_object *req;
+ struct be_mcc_wrb *wrb;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = embedded_payload(wrb);
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_DELETE_OBJECT,
+ sizeof(*req), wrb, NULL);
+
+ strcpy(req->object_name, obj_name);
+
+ status = be_mcc_notify_wait(adapter);
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
+}
+
int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name,
u32 *data_read, u32 *eof, u8 *addn_status)
@@ -2320,7 +2345,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
msecs_to_jiffies(40000)))
- status = -1;
+ status = -ETIMEDOUT;
else
status = adapter->flash_status;
@@ -3313,15 +3338,28 @@ err:
return status;
}
-static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
+/* Descriptor type */
+enum {
+ FUNC_DESC = 1,
+ VFT_DESC = 2
+};
+
+static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
+ int desc_type)
{
struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
+ struct be_nic_res_desc *nic;
int i;
for (i = 0; i < desc_count; i++) {
if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
- hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
- return (struct be_nic_res_desc *)hdr;
+ hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
+ nic = (struct be_nic_res_desc *)hdr;
+ if (desc_type == FUNC_DESC ||
+ (desc_type == VFT_DESC &&
+ nic->flags & (1 << VFT_SHIFT)))
+ return nic;
+ }
hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
hdr = (void *)hdr + hdr->desc_len;
@@ -3329,6 +3367,16 @@ static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
return NULL;
}
+static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count)
+{
+ return be_get_nic_desc(buf, desc_count, VFT_DESC);
+}
+
+static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count)
+{
+ return be_get_nic_desc(buf, desc_count, FUNC_DESC);
+}
+
static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
u32 desc_count)
{
@@ -3424,7 +3472,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
u32 desc_count = le32_to_cpu(resp->desc_count);
struct be_nic_res_desc *desc;
- desc = be_get_nic_desc(resp->func_param, desc_count);
+ desc = be_get_func_nic_desc(resp->func_param, desc_count);
if (!desc) {
status = -EINVAL;
goto err;
@@ -3440,76 +3488,17 @@ err:
return status;
}
-/* Uses mbox */
-static int be_cmd_get_profile_config_mbox(struct be_adapter *adapter,
- u8 domain, struct be_dma_mem *cmd)
-{
- struct be_mcc_wrb *wrb;
- struct be_cmd_req_get_profile_config *req;
- int status;
-
- if (mutex_lock_interruptible(&adapter->mbox_lock))
- return -1;
- wrb = wrb_from_mbox(adapter);
-
- req = cmd->va;
- be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_GET_PROFILE_CONFIG,
- cmd->size, wrb, cmd);
-
- req->type = ACTIVE_PROFILE_TYPE;
- req->hdr.domain = domain;
- if (!lancer_chip(adapter))
- req->hdr.version = 1;
-
- status = be_mbox_notify_wait(adapter);
-
- mutex_unlock(&adapter->mbox_lock);
- return status;
-}
-
-/* Uses sync mcc */
-static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter,
- u8 domain, struct be_dma_mem *cmd)
-{
- struct be_mcc_wrb *wrb;
- struct be_cmd_req_get_profile_config *req;
- int status;
-
- spin_lock_bh(&adapter->mcc_lock);
-
- wrb = wrb_from_mccq(adapter);
- if (!wrb) {
- status = -EBUSY;
- goto err;
- }
-
- req = cmd->va;
- be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_GET_PROFILE_CONFIG,
- cmd->size, wrb, cmd);
-
- req->type = ACTIVE_PROFILE_TYPE;
- req->hdr.domain = domain;
- if (!lancer_chip(adapter))
- req->hdr.version = 1;
-
- status = be_mcc_notify_wait(adapter);
-
-err:
- spin_unlock_bh(&adapter->mcc_lock);
- return status;
-}
-
-/* Uses sync mcc, if MCCQ is already created otherwise mbox */
+/* Will use MBOX only if MCCQ has not been created */
int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain)
{
struct be_cmd_resp_get_profile_config *resp;
+ struct be_cmd_req_get_profile_config *req;
+ struct be_nic_res_desc *vf_res;
struct be_pcie_res_desc *pcie;
struct be_port_res_desc *port;
struct be_nic_res_desc *nic;
- struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ struct be_mcc_wrb wrb = {0};
struct be_dma_mem cmd;
u32 desc_count;
int status;
@@ -3520,10 +3509,17 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
if (!cmd.va)
return -ENOMEM;
- if (!mccq->created)
- status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd);
- else
- status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd);
+ req = cmd.va;
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_PROFILE_CONFIG,
+ cmd.size, &wrb, &cmd);
+
+ req->hdr.domain = domain;
+ if (!lancer_chip(adapter))
+ req->hdr.version = 1;
+ req->type = ACTIVE_PROFILE_TYPE;
+
+ status = be_cmd_notify_wait(adapter, &wrb);
if (status)
goto err;
@@ -3539,48 +3535,52 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
if (port)
adapter->mc_type = port->mc_type;
- nic = be_get_nic_desc(resp->func_param, desc_count);
+ nic = be_get_func_nic_desc(resp->func_param, desc_count);
if (nic)
be_copy_nic_desc(res, nic);
+ vf_res = be_get_vft_desc(resp->func_param, desc_count);
+ if (vf_res)
+ res->vf_if_cap_flags = vf_res->cap_flags;
err:
if (cmd.va)
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
return status;
}
-int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
- int size, u8 version, u8 domain)
+/* Will use MBOX only if MCCQ has not been created */
+static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
+ int size, int count, u8 version, u8 domain)
{
struct be_cmd_req_set_profile_config *req;
- struct be_mcc_wrb *wrb;
+ struct be_mcc_wrb wrb = {0};
+ struct be_dma_mem cmd;
int status;
- spin_lock_bh(&adapter->mcc_lock);
-
- wrb = wrb_from_mccq(adapter);
- if (!wrb) {
- status = -EBUSY;
- goto err;
- }
+ memset(&cmd, 0, sizeof(struct be_dma_mem));
+ cmd.size = sizeof(struct be_cmd_req_set_profile_config);
+ cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
+ if (!cmd.va)
+ return -ENOMEM;
- req = embedded_payload(wrb);
+ req = cmd.va;
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
- OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req),
- wrb, NULL);
+ OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
+ &wrb, &cmd);
req->hdr.version = version;
req->hdr.domain = domain;
- req->desc_count = cpu_to_le32(1);
+ req->desc_count = cpu_to_le32(count);
memcpy(req->desc, desc, size);
- status = be_mcc_notify_wait(adapter);
-err:
- spin_unlock_bh(&adapter->mcc_lock);
+ status = be_cmd_notify_wait(adapter, &wrb);
+
+ if (cmd.va)
+ pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
return status;
}
/* Mark all fields invalid */
-void be_reset_nic_desc(struct be_nic_res_desc *nic)
+static void be_reset_nic_desc(struct be_nic_res_desc *nic)
{
memset(nic, 0, sizeof(*nic));
nic->unicast_mac_count = 0xFFFF;
@@ -3601,9 +3601,20 @@ void be_reset_nic_desc(struct be_nic_res_desc *nic)
nic->wol_param = 0x0F;
nic->tunnel_iface_count = 0xFFFF;
nic->direct_tenant_iface_count = 0xFFFF;
+ nic->bw_min = 0xFFFFFFFF;
nic->bw_max = 0xFFFFFFFF;
}
+/* Mark all fields invalid */
+static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
+{
+ memset(pcie, 0, sizeof(*pcie));
+ pcie->sriov_state = 0xFF;
+ pcie->pf_state = 0xFF;
+ pcie->pf_type = 0xFF;
+ pcie->num_vfs = 0xFFFF;
+}
+
int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
u8 domain)
{
@@ -3634,7 +3645,63 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
return be_cmd_set_profile_config(adapter, &nic_desc,
nic_desc.hdr.desc_len,
- version, domain);
+ 1, version, domain);
+}
+
+int be_cmd_set_sriov_config(struct be_adapter *adapter,
+ struct be_resources res, u16 num_vfs)
+{
+ struct {
+ struct be_pcie_res_desc pcie;
+ struct be_nic_res_desc nic_vft;
+ } __packed desc;
+ u16 vf_q_count;
+
+ if (BEx_chip(adapter) || lancer_chip(adapter))
+ return 0;
+
+ /* PF PCIE descriptor */
+ be_reset_pcie_desc(&desc.pcie);
+ desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
+ desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
+ desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
+ desc.pcie.pf_num = adapter->pdev->devfn;
+ desc.pcie.sriov_state = num_vfs ? 1 : 0;
+ desc.pcie.num_vfs = cpu_to_le16(num_vfs);
+
+ /* VF NIC Template descriptor */
+ be_reset_nic_desc(&desc.nic_vft);
+ desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
+ desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
+ desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) |
+ (1 << NOSV_SHIFT);
+ desc.nic_vft.pf_num = adapter->pdev->devfn;
+ desc.nic_vft.vf_num = 0;
+
+ if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
+ /* If number of VFs requested is 8 less than max supported,
+ * assign 8 queue pairs to the PF and divide the remaining
+ * resources evenly among the VFs
+ */
+ if (num_vfs < (be_max_vfs(adapter) - 8))
+ vf_q_count = (res.max_rss_qs - 8) / num_vfs;
+ else
+ vf_q_count = res.max_rss_qs / num_vfs;
+
+ desc.nic_vft.rq_count = cpu_to_le16(vf_q_count);
+ desc.nic_vft.txq_count = cpu_to_le16(vf_q_count);
+ desc.nic_vft.rssq_count = cpu_to_le16(vf_q_count - 1);
+ desc.nic_vft.cq_count = cpu_to_le16(3 * vf_q_count);
+ } else {
+ desc.nic_vft.txq_count = cpu_to_le16(1);
+ desc.nic_vft.rq_count = cpu_to_le16(1);
+ desc.nic_vft.rssq_count = cpu_to_le16(0);
+ /* One CQ for each TX, RX and MCCQ */
+ desc.nic_vft.cq_count = cpu_to_le16(3);
+ }
+
+ return be_cmd_set_profile_config(adapter, &desc,
+ 2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
}
int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
@@ -3686,7 +3753,7 @@ int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
}
return be_cmd_set_profile_config(adapter, &port_desc,
- RESOURCE_DESC_SIZE_V1, 1, 0);
+ RESOURCE_DESC_SIZE_V1, 1, 1, 0);
}
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
@@ -3766,13 +3833,19 @@ bool dump_present(struct be_adapter *adapter)
int lancer_initiate_dump(struct be_adapter *adapter)
{
+ struct device *dev = &adapter->pdev->dev;
int status;
+ if (dump_present(adapter)) {
+ dev_info(dev, "Previous dump not cleared, not forcing dump\n");
+ return -EEXIST;
+ }
+
/* give firmware reset and diagnostic dump */
status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
PHYSDEV_CONTROL_DD_MASK);
if (status < 0) {
- dev_err(&adapter->pdev->dev, "Firmware reset failed\n");
+ dev_err(dev, "FW reset failed\n");
return status;
}
@@ -3781,13 +3854,21 @@ int lancer_initiate_dump(struct be_adapter *adapter)
return status;
if (!dump_present(adapter)) {
- dev_err(&adapter->pdev->dev, "Dump image not present\n");
- return -1;
+ dev_err(dev, "FW dump not generated\n");
+ return -EIO;
}
return 0;
}
+int lancer_delete_dump(struct be_adapter *adapter)
+{
+ int status;
+
+ status = lancer_cmd_delete_object(adapter, LANCER_FW_DUMP_FILE);
+ return be_cmd_status(status);
+}
+
/* Uses sync mcc */
int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
{
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 59b3c056f329..5284b825bba2 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -231,6 +231,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_FN_PRIVILEGES 170
#define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172
+#define OPCODE_COMMON_DELETE_OBJECT 174
#define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193
#define OPCODE_COMMON_GET_IFACE_LIST 194
#define OPCODE_COMMON_ENABLE_DISABLE_VF 196
@@ -1081,11 +1082,6 @@ struct be_cmd_req_modify_eq_delay {
struct be_set_eqd set_eqd[MAX_EVT_QS];
} __packed;
-struct be_cmd_resp_modify_eq_delay {
- struct be_cmd_resp_hdr hdr;
- u32 rsvd0;
-} __packed;
-
/******************** Get FW Config *******************/
/* The HW can come up in either of the following multi-channel modes
* based on the skew/IPL.
@@ -1156,11 +1152,6 @@ struct be_cmd_req_enable_disable_beacon {
u8 status_duration;
} __packed;
-struct be_cmd_resp_enable_disable_beacon {
- struct be_cmd_resp_hdr resp_hdr;
- u32 rsvd0;
-} __packed;
-
struct be_cmd_req_get_beacon_state {
struct be_cmd_req_hdr hdr;
u8 port_num;
@@ -1263,6 +1254,13 @@ struct lancer_cmd_resp_read_object {
u32 eof;
};
+struct lancer_cmd_req_delete_object {
+ struct be_cmd_req_hdr hdr;
+ u32 rsvd1;
+ u32 rsvd2;
+ u8 object_name[104];
+};
+
/************************ WOL *******************************/
struct be_cmd_req_acpi_wol_magic_config{
struct be_cmd_req_hdr hdr;
@@ -1326,11 +1324,6 @@ struct be_cmd_req_set_lmode {
u8 loopback_state;
};
-struct be_cmd_resp_set_lmode {
- struct be_cmd_resp_hdr resp_hdr;
- u8 rsvd0[4];
-};
-
/********************** DDR DMA test *********************/
struct be_cmd_req_ddrdma_test {
struct be_cmd_req_hdr hdr;
@@ -1434,11 +1427,6 @@ struct be_cmd_req_set_qos {
u32 rsvd[7];
};
-struct be_cmd_resp_set_qos {
- struct be_cmd_resp_hdr hdr;
- u32 rsvd;
-};
-
/*********************** Controller Attributes ***********************/
struct be_cmd_req_cntl_attribs {
struct be_cmd_req_hdr hdr;
@@ -1572,11 +1560,6 @@ struct be_cmd_req_set_hsw_config {
u8 context[sizeof(struct amap_set_hsw_context) / 8];
} __packed;
-struct be_cmd_resp_set_hsw_config {
- struct be_cmd_resp_hdr hdr;
- u32 rsvd;
-};
-
struct amap_get_hsw_req_context {
u8 interface_id[16];
u8 rsvd0[14];
@@ -1835,6 +1818,7 @@ struct be_cmd_req_set_ext_fat_caps {
#define PORT_RESOURCE_DESC_TYPE_V1 0x55
#define MAX_RESOURCE_DESC 264
+#define VFT_SHIFT 3 /* VF template */
#define IMM_SHIFT 6 /* Immediate */
#define NOSV_SHIFT 7 /* No save */
@@ -1962,12 +1946,8 @@ struct be_cmd_req_set_profile_config {
struct be_cmd_req_hdr hdr;
u32 rsvd;
u32 desc_count;
- u8 desc[RESOURCE_DESC_SIZE_V1];
-};
-
-struct be_cmd_resp_set_profile_config {
- struct be_cmd_resp_hdr hdr;
-};
+ u8 desc[2 * RESOURCE_DESC_SIZE_V1];
+} __packed;
struct be_cmd_req_get_active_profile {
struct be_cmd_req_hdr hdr;
@@ -2070,16 +2050,14 @@ int be_cmd_reset(struct be_adapter *adapter);
int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd);
int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
-int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
- char *fw_on_flash);
+int be_cmd_get_fw_ver(struct be_adapter *adapter);
int be_cmd_modify_eqd(struct be_adapter *adapter, struct be_set_eqd *, int num);
int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
u32 num);
int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status);
int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc);
int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc);
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
- u32 *function_mode, u32 *function_caps, u16 *asic_rev);
+int be_cmd_query_fw_cfg(struct be_adapter *adapter);
int be_cmd_reset_function(struct be_adapter *adapter);
int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
u32 rss_hash_opts, u16 table_size, const u8 *rss_hkey);
@@ -2097,6 +2075,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name,
u32 *data_read, u32 *eof, u8 *addn_status);
+int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name);
int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
u16 optype, int offset);
int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
@@ -2150,6 +2129,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
struct be_fat_conf_params *cfgs);
int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask);
int lancer_initiate_dump(struct be_adapter *adapter);
+int lancer_delete_dump(struct be_adapter *adapter);
bool dump_present(struct be_adapter *adapter);
int lancer_test_and_set_rdy_state(struct be_adapter *adapter);
int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name);
@@ -2157,8 +2137,6 @@ int be_cmd_get_func_config(struct be_adapter *adapter,
struct be_resources *res);
int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain);
-int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
- int size, u8 version, u8 domain);
int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile);
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
int vf_num);
@@ -2168,3 +2146,5 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter,
int link_state, u8 domain);
int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port);
int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op);
+int be_cmd_set_sriov_config(struct be_adapter *adapter,
+ struct be_resources res, u16 num_vfs);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index e2da4d20dd3d..0cd3311409a8 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -643,7 +643,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
if (status)
dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
- return status;
+ return be_cmd_status(status);
}
static int be_set_phys_id(struct net_device *netdev,
@@ -681,22 +681,21 @@ static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
struct device *dev = &adapter->pdev->dev;
int status;
- if (!lancer_chip(adapter)) {
- dev_err(dev, "FW dump not supported\n");
+ if (!lancer_chip(adapter) ||
+ !check_privilege(adapter, MAX_PRIVILEGES))
return -EOPNOTSUPP;
- }
-
- if (dump_present(adapter)) {
- dev_err(dev, "Previous dump not cleared, not forcing dump\n");
- return 0;
- }
switch (dump->flag) {
case LANCER_INITIATE_FW_DUMP:
status = lancer_initiate_dump(adapter);
if (!status)
- dev_info(dev, "F/w dump initiated successfully\n");
+ dev_info(dev, "FW dump initiated successfully\n");
break;
+ case LANCER_DELETE_FW_DUMP:
+ status = lancer_delete_dump(adapter);
+ if (!status)
+ dev_info(dev, "FW dump deleted successfully\n");
+ break;
default:
dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag);
return -EINVAL;
@@ -762,7 +761,7 @@ static int be_test_ddr_dma(struct be_adapter *adapter)
err:
dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va,
ddrdma_cmd.dma);
- return ret;
+ return be_cmd_status(ret);
}
static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
@@ -885,7 +884,7 @@ static int be_read_eeprom(struct net_device *netdev,
dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va,
eeprom_cmd.dma);
- return status;
+ return be_cmd_status(status);
}
static u32 be_get_msg_level(struct net_device *netdev)
@@ -1042,7 +1041,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter,
if (!status)
adapter->rss_info.rss_flags = rss_flags;
- return status;
+ return be_cmd_status(status);
}
static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
@@ -1080,6 +1079,7 @@ static int be_set_channels(struct net_device *netdev,
struct ethtool_channels *ch)
{
struct be_adapter *adapter = netdev_priv(netdev);
+ int status;
if (ch->rx_count || ch->tx_count || ch->other_count ||
!ch->combined_count || ch->combined_count > be_max_qs(adapter))
@@ -1087,7 +1087,8 @@ static int be_set_channels(struct net_device *netdev,
adapter->cfg_num_qs = ch->combined_count;
- return be_update_queues(adapter);
+ status = be_update_queues(adapter);
+ return be_cmd_status(status);
}
static u32 be_get_rxfh_indir_size(struct net_device *netdev)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 34a26e42f19d..db4ff14ff18f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -81,10 +81,10 @@ static const char * const ue_status_low_desc[] = {
"P1_OB_LINK ",
"HOST_GPIO ",
"MBOX ",
- "AXGMAC0",
- "AXGMAC1",
- "JTAG",
- "MPU_INTPEND"
+ "ERX2 ",
+ "SPARE ",
+ "JTAG ",
+ "MPU_INTPEND "
};
/* UE Status High CSR */
static const char * const ue_status_hi_desc[] = {
@@ -109,16 +109,16 @@ static const char * const ue_status_hi_desc[] = {
"HOST5",
"HOST6",
"HOST7",
- "HOST8",
- "HOST9",
+ "ECRC",
+ "Poison TLP",
"NETC",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
+ "PERIPH",
+ "LLTXULP",
+ "D2P",
+ "RCON",
+ "LDMA",
+ "LLTXP",
+ "LLTXPB",
"Unknown"
};
@@ -1172,20 +1172,15 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
struct be_adapter *adapter = netdev_priv(netdev);
- int status = 0;
/* Packets with VID 0 are always received by Lancer by default */
if (lancer_chip(adapter) && vid == 0)
- goto ret;
+ return 0;
clear_bit(vid, adapter->vids);
- status = be_vid_config(adapter);
- if (!status)
- adapter->vlans_added--;
- else
- set_bit(vid, adapter->vids);
-ret:
- return status;
+ adapter->vlans_added--;
+
+ return be_vid_config(adapter);
}
static void be_clear_promisc(struct be_adapter *adapter)
@@ -1275,6 +1270,12 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs)
return -EINVAL;
+ /* Proceed further only if user provided MAC is different
+ * from active MAC
+ */
+ if (ether_addr_equal(mac, vf_cfg->mac_addr))
+ return 0;
+
if (BEx_chip(adapter)) {
be_cmd_pmac_del(adapter, vf_cfg->if_handle, vf_cfg->pmac_id,
vf + 1);
@@ -1286,13 +1287,15 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
vf + 1);
}
- if (status)
- dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
- mac, vf);
- else
- memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
+ if (status) {
+ dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed: %#x",
+ mac, vf, status);
+ return be_cmd_status(status);
+ }
- return status;
+ ether_addr_copy(vf_cfg->mac_addr, mac);
+
+ return 0;
}
static int be_get_vf_config(struct net_device *netdev, int vf,
@@ -1341,12 +1344,16 @@ static int be_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
vf + 1, vf_cfg->if_handle, 0);
}
- if (!status)
- vf_cfg->vlan_tag = vlan;
- else
- dev_info(&adapter->pdev->dev,
- "VLAN %d config on VF %d failed\n", vlan, vf);
- return status;
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "VLAN %d config on VF %d failed : %#x\n", vlan,
+ vf, status);
+ return be_cmd_status(status);
+ }
+
+ vf_cfg->vlan_tag = vlan;
+
+ return 0;
}
static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
@@ -1377,7 +1384,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
if (!link_status) {
dev_err(dev, "TX-rate setting not allowed when link is down\n");
- status = -EPERM;
+ status = -ENETDOWN;
goto err;
}
@@ -1408,7 +1415,7 @@ config_qos:
err:
dev_err(dev, "TX-rate setting of %dMbps on VF%d failed\n",
max_tx_rate, vf);
- return status;
+ return be_cmd_status(status);
}
static int be_set_vf_link_state(struct net_device *netdev, int vf,
int link_state)
@@ -1423,10 +1430,15 @@ static int be_set_vf_link_state(struct net_device *netdev, int vf,
return -EINVAL;
status = be_cmd_set_logical_link_config(adapter, link_state, vf+1);
- if (!status)
- adapter->vf_cfg[vf].plink_tracking = link_state;
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "Link state change on VF %d failed: %#x\n", vf, status);
+ return be_cmd_status(status);
+ }
- return status;
+ adapter->vf_cfg[vf].plink_tracking = link_state;
+
+ return 0;
}
static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts,
@@ -2028,7 +2040,7 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
*/
for (;;) {
rxcp = be_rx_compl_get(rxo);
- if (rxcp == NULL) {
+ if (!rxcp) {
if (lancer_chip(adapter))
break;
@@ -2902,7 +2914,7 @@ static int be_open(struct net_device *netdev)
for_all_evt_queues(adapter, eqo, i) {
napi_enable(&eqo->napi);
be_enable_busy_poll(eqo);
- be_eq_notify(adapter, eqo->q.id, true, false, 0);
+ be_eq_notify(adapter, eqo->q.id, true, true, 0);
}
adapter->flags |= BE_FLAGS_NAPI_ENABLED;
@@ -2935,8 +2947,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
GFP_KERNEL);
- if (cmd.va == NULL)
- return -1;
+ if (!cmd.va)
+ return -ENOMEM;
if (enable) {
status = pci_write_config_dword(adapter->pdev,
@@ -3043,6 +3055,7 @@ static void be_vf_clear(struct be_adapter *adapter)
done:
kfree(adapter->vf_cfg);
adapter->num_vfs = 0;
+ adapter->flags &= ~BE_FLAGS_SRIOV_ENABLED;
}
static void be_clear_queues(struct be_adapter *adapter)
@@ -3098,6 +3111,13 @@ static int be_clear(struct be_adapter *adapter)
if (sriov_enabled(adapter))
be_vf_clear(adapter);
+ /* Re-configure FW to distribute resources evenly across max-supported
+ * number of VFs, only when VFs are not already enabled.
+ */
+ if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev))
+ be_cmd_set_sriov_config(adapter, adapter->pool_res,
+ pci_sriov_get_totalvfs(adapter->pdev));
+
#ifdef CONFIG_BE2NET_VXLAN
be_disable_vxlan_offloads(adapter);
#endif
@@ -3170,19 +3190,6 @@ static int be_vf_setup(struct be_adapter *adapter)
u32 privileges;
old_vfs = pci_num_vf(adapter->pdev);
- if (old_vfs) {
- dev_info(dev, "%d VFs are already enabled\n", old_vfs);
- if (old_vfs != num_vfs)
- dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
- adapter->num_vfs = old_vfs;
- } else {
- if (num_vfs > be_max_vfs(adapter))
- dev_info(dev, "Device supports %d VFs and not %d\n",
- be_max_vfs(adapter), num_vfs);
- adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
- if (!adapter->num_vfs)
- return 0;
- }
status = be_vf_setup_init(adapter);
if (status)
@@ -3194,17 +3201,15 @@ static int be_vf_setup(struct be_adapter *adapter)
if (status)
goto err;
}
- } else {
- status = be_vfs_if_create(adapter);
- if (status)
- goto err;
- }
- if (old_vfs) {
status = be_vfs_mac_query(adapter);
if (status)
goto err;
} else {
+ status = be_vfs_if_create(adapter);
+ if (status)
+ goto err;
+
status = be_vf_eth_addr_config(adapter);
if (status)
goto err;
@@ -3243,6 +3248,8 @@ static int be_vf_setup(struct be_adapter *adapter)
goto err;
}
}
+
+ adapter->flags |= BE_FLAGS_SRIOV_ENABLED;
return 0;
err:
dev_err(dev, "VF setup failed\n");
@@ -3270,19 +3277,7 @@ static u8 be_convert_mc_type(u32 function_mode)
static void BEx_get_resources(struct be_adapter *adapter,
struct be_resources *res)
{
- struct pci_dev *pdev = adapter->pdev;
- bool use_sriov = false;
- int max_vfs = 0;
-
- if (be_physfn(adapter) && BE3_chip(adapter)) {
- be_cmd_get_profile_config(adapter, res, 0);
- /* Some old versions of BE3 FW don't report max_vfs value */
- if (res->max_vfs == 0) {
- max_vfs = pci_sriov_get_totalvfs(pdev);
- res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
- }
- use_sriov = res->max_vfs && sriov_want(adapter);
- }
+ bool use_sriov = adapter->num_vfs ? 1 : 0;
if (be_physfn(adapter))
res->max_uc_mac = BE_UC_PMAC_COUNT;
@@ -3326,7 +3321,7 @@ static void BEx_get_resources(struct be_adapter *adapter,
res->max_rx_qs = res->max_rss_qs + 1;
if (be_physfn(adapter))
- res->max_evt_qs = (res->max_vfs > 0) ?
+ res->max_evt_qs = (be_max_vfs(adapter) > 0) ?
BE3_SRIOV_MAX_EVT_QS : BE3_MAX_EVT_QS;
else
res->max_evt_qs = 1;
@@ -3349,6 +3344,51 @@ static void be_setup_init(struct be_adapter *adapter)
adapter->cmd_privileges = MIN_PRIVILEGES;
}
+static int be_get_sriov_config(struct be_adapter *adapter)
+{
+ struct device *dev = &adapter->pdev->dev;
+ struct be_resources res = {0};
+ int max_vfs, old_vfs;
+
+ /* Some old versions of BE3 FW don't report max_vfs value */
+ be_cmd_get_profile_config(adapter, &res, 0);
+
+ if (BE3_chip(adapter) && !res.max_vfs) {
+ max_vfs = pci_sriov_get_totalvfs(adapter->pdev);
+ res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
+ }
+
+ adapter->pool_res = res;
+
+ if (!be_max_vfs(adapter)) {
+ if (num_vfs)
+ dev_warn(dev, "device doesn't support SRIOV\n");
+ adapter->num_vfs = 0;
+ return 0;
+ }
+
+ pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter));
+
+ /* validate num_vfs module param */
+ old_vfs = pci_num_vf(adapter->pdev);
+ if (old_vfs) {
+ dev_info(dev, "%d VFs are already enabled\n", old_vfs);
+ if (old_vfs != num_vfs)
+ dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
+ adapter->num_vfs = old_vfs;
+ } else {
+ if (num_vfs > be_max_vfs(adapter)) {
+ dev_info(dev, "Resources unavailable to init %d VFs\n",
+ num_vfs);
+ dev_info(dev, "Limiting to %d VFs\n",
+ be_max_vfs(adapter));
+ }
+ adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
+ }
+
+ return 0;
+}
+
static int be_get_resources(struct be_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
@@ -3374,13 +3414,6 @@ static int be_get_resources(struct be_adapter *adapter)
res.max_evt_qs /= 2;
adapter->res = res;
- if (be_physfn(adapter)) {
- status = be_cmd_get_profile_config(adapter, &res, 0);
- if (status)
- return status;
- adapter->res.max_vfs = res.max_vfs;
- }
-
dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
be_max_txqs(adapter), be_max_rxqs(adapter),
be_max_rss(adapter), be_max_eqs(adapter),
@@ -3393,16 +3426,41 @@ static int be_get_resources(struct be_adapter *adapter)
return 0;
}
-/* Routine to query per function resource limits */
+static void be_sriov_config(struct be_adapter *adapter)
+{
+ struct device *dev = &adapter->pdev->dev;
+ int status;
+
+ status = be_get_sriov_config(adapter);
+ if (status) {
+ dev_err(dev, "Failed to query SR-IOV configuration\n");
+ dev_err(dev, "SR-IOV cannot be enabled\n");
+ return;
+ }
+
+ /* When the HW is in SRIOV capable configuration, the PF-pool
+ * resources are equally distributed across the max-number of
+ * VFs. The user may request only a subset of the max-vfs to be
+ * enabled. Based on num_vfs, redistribute the resources across
+ * num_vfs so that each VF will have access to more number of
+ * resources. This facility is not available in BE3 FW.
+ * Also, this is done by FW in Lancer chip.
+ */
+ if (be_max_vfs(adapter) && !pci_num_vf(adapter->pdev)) {
+ status = be_cmd_set_sriov_config(adapter,
+ adapter->pool_res,
+ adapter->num_vfs);
+ if (status)
+ dev_err(dev, "Failed to optimize SR-IOV resources\n");
+ }
+}
+
static int be_get_config(struct be_adapter *adapter)
{
u16 profile_id;
int status;
- status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
- &adapter->function_mode,
- &adapter->function_caps,
- &adapter->asic_rev);
+ status = be_cmd_query_fw_cfg(adapter);
if (status)
return status;
@@ -3413,6 +3471,9 @@ static int be_get_config(struct be_adapter *adapter)
"Using profile 0x%x\n", profile_id);
}
+ if (!BE2_chip(adapter) && be_physfn(adapter))
+ be_sriov_config(adapter);
+
status = be_get_resources(adapter);
if (status)
return status;
@@ -3571,7 +3632,7 @@ static int be_setup(struct be_adapter *adapter)
if (status)
goto err;
- be_cmd_get_fw_ver(adapter, adapter->fw_ver, adapter->fw_on_flash);
+ be_cmd_get_fw_ver(adapter);
if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
dev_err(dev, "Firmware on card is old(%s), IRQs may not work.",
@@ -3596,12 +3657,8 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_set_logical_link_config(adapter,
IFLA_VF_LINK_STATE_AUTO, 0);
- if (sriov_want(adapter)) {
- if (be_max_vfs(adapter))
- be_vf_setup(adapter);
- else
- dev_warn(dev, "device doesn't support SRIOV\n");
- }
+ if (adapter->num_vfs)
+ be_vf_setup(adapter);
status = be_cmd_get_phy_info(adapter);
if (!status && be_pause_supported(adapter))
@@ -3925,7 +3982,7 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
if (!fsec) {
dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
- return -1;
+ return -EINVAL;
}
for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) {
@@ -4094,7 +4151,7 @@ lancer_fw_exit:
static int be_get_ufi_type(struct be_adapter *adapter,
struct flash_file_hdr_g3 *fhdr)
{
- if (fhdr == NULL)
+ if (!fhdr)
goto be_get_ufi_exit;
if (skyhawk_chip(adapter) && fhdr->build[0] == '4')
@@ -4156,7 +4213,7 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
&flash_cmd,
num_imgs);
else {
- status = -1;
+ status = -EINVAL;
dev_err(&adapter->pdev->dev,
"Can't load BE3 UFI on BE3R\n");
}
@@ -4167,7 +4224,7 @@ static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
if (ufi_type == UFI_TYPE2)
status = be_flash_BEx(adapter, fw, &flash_cmd, 0);
else if (ufi_type == -1)
- status = -1;
+ status = -EINVAL;
dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
flash_cmd.dma);
@@ -4190,7 +4247,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
if (!netif_running(adapter->netdev)) {
dev_err(&adapter->pdev->dev,
"Firmware load not allowed (interface is down)\n");
- return -1;
+ return -ENETDOWN;
}
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
@@ -4205,8 +4262,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
status = be_fw_download(adapter, fw);
if (!status)
- be_cmd_get_fw_ver(adapter, adapter->fw_ver,
- adapter->fw_on_flash);
+ be_cmd_get_fw_ver(adapter);
fw_exit:
release_firmware(fw);
@@ -4437,12 +4493,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
if (BEx_chip(adapter) && be_physfn(adapter)) {
adapter->csr = pci_iomap(adapter->pdev, 2, 0);
- if (adapter->csr == NULL)
+ if (!adapter->csr)
return -ENOMEM;
}
addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
- if (addr == NULL)
+ if (!addr)
goto pci_map_err;
adapter->db = addr;
@@ -4505,7 +4561,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
rx_filter->va = dma_zalloc_coherent(&adapter->pdev->dev,
rx_filter->size, &rx_filter->dma,
GFP_KERNEL);
- if (rx_filter->va == NULL) {
+ if (!rx_filter->va) {
status = -ENOMEM;
goto free_mbox;
}
@@ -4554,8 +4610,8 @@ static int be_stats_init(struct be_adapter *adapter)
cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
GFP_KERNEL);
- if (cmd->va == NULL)
- return -1;
+ if (!cmd->va)
+ return -ENOMEM;
return 0;
}
@@ -4776,7 +4832,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
pci_set_master(pdev);
netdev = alloc_etherdev_mqs(sizeof(*adapter), MAX_TX_QS, MAX_RX_QS);
- if (netdev == NULL) {
+ if (!netdev) {
status = -ENOMEM;
goto rel_reg;
}
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 671d080105a7..bd53caf1c1eb 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -256,12 +256,6 @@ struct bufdesc_ex {
#define FLAG_RX_CSUM_ENABLED (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
#define FLAG_RX_CSUM_ERROR (BD_ENET_RX_ICE | BD_ENET_RX_PCR)
-struct fec_enet_delayed_work {
- struct delayed_work delay_work;
- bool timeout;
- bool trig_tx;
-};
-
/* The FEC buffer descriptors track the ring buffers. The rx_bd_base and
* tx_bd_base always point to the base of the buffer descriptors. The
* cur_rx and cur_tx point to the currently available buffer.
@@ -308,7 +302,6 @@ struct fec_enet_private {
struct platform_device *pdev;
- int opened;
int dev_id;
/* Phylib and MDIO interface */
@@ -328,6 +321,8 @@ struct fec_enet_private {
struct napi_struct napi;
int csum_flags;
+ struct work_struct tx_timeout_work;
+
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
unsigned long last_overflow_check;
@@ -340,7 +335,6 @@ struct fec_enet_private {
int hwts_rx_en;
int hwts_tx_en;
struct timer_list time_keep;
- struct fec_enet_delayed_work delay_work;
struct regulator *reg_phy;
};
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 77037fd377b8..66fe1f672499 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -320,6 +320,27 @@ static void *swap_buffer(void *bufaddr, int len)
return bufaddr;
}
+static void fec_dump(struct net_device *ndev)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct bufdesc *bdp = fep->tx_bd_base;
+ unsigned int index = 0;
+
+ netdev_info(ndev, "TX ring dump\n");
+ pr_info("Nr SC addr len SKB\n");
+
+ do {
+ pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
+ index,
+ bdp == fep->cur_tx ? 'S' : ' ',
+ bdp == fep->dirty_tx ? 'H' : ' ',
+ bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
+ fep->tx_skbuff[index]);
+ bdp = fec_enet_get_nextdesc(bdp, fep);
+ index++;
+ } while (bdp != fep->tx_bd_base);
+}
+
static inline bool is_ipv4_pkt(struct sk_buff *skb)
{
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
@@ -342,22 +363,6 @@ fec_enet_clear_csum(struct sk_buff *skb, struct net_device *ndev)
return 0;
}
-static void
-fec_enet_submit_work(struct bufdesc *bdp, struct fec_enet_private *fep)
-{
- const struct platform_device_id *id_entry =
- platform_get_device_id(fep->pdev);
- struct bufdesc *bdp_pre;
-
- bdp_pre = fec_enet_get_prevdesc(bdp, fep);
- if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
- !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
- fep->delay_work.trig_tx = true;
- schedule_delayed_work(&(fep->delay_work.delay_work),
- msecs_to_jiffies(1));
- }
-}
-
static int
fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
{
@@ -373,6 +378,7 @@ fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
skb_frag_t *this_frag;
unsigned int index;
void *bufaddr;
+ dma_addr_t addr;
int i;
for (frag = 0; frag < nr_frags; frag++) {
@@ -415,15 +421,16 @@ fec_enet_txq_submit_frag_skb(struct sk_buff *skb, struct net_device *ndev)
swap_buffer(bufaddr, frag_len);
}
- bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
- frag_len, DMA_TO_DEVICE);
- if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+ addr = dma_map_single(&fep->pdev->dev, bufaddr, frag_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, addr)) {
dev_kfree_skb_any(skb);
if (net_ratelimit())
netdev_err(ndev, "Tx DMA memory map failed\n");
goto dma_mapping_error;
}
+ bdp->cbd_bufaddr = addr;
bdp->cbd_datlen = frag_len;
bdp->cbd_sc = status;
}
@@ -450,6 +457,7 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
int nr_frags = skb_shinfo(skb)->nr_frags;
struct bufdesc *bdp, *last_bdp;
void *bufaddr;
+ dma_addr_t addr;
unsigned short status;
unsigned short buflen;
unsigned int estatus = 0;
@@ -490,12 +498,9 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
swap_buffer(bufaddr, buflen);
}
- /* Push the data cache so the CPM does not get stale memory
- * data.
- */
- bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr,
- buflen, DMA_TO_DEVICE);
- if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+ /* Push the data cache so the CPM does not get stale memory data. */
+ addr = dma_map_single(&fep->pdev->dev, bufaddr, buflen, DMA_TO_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, addr)) {
dev_kfree_skb_any(skb);
if (net_ratelimit())
netdev_err(ndev, "Tx DMA memory map failed\n");
@@ -537,6 +542,7 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
fep->tx_skbuff[index] = skb;
bdp->cbd_datlen = buflen;
+ bdp->cbd_bufaddr = addr;
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
@@ -544,8 +550,6 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
bdp->cbd_sc = status;
- fec_enet_submit_work(bdp, fep);
-
/* If this was the last BD in the ring, start at the beginning again. */
bdp = fec_enet_get_nextdesc(last_bdp, fep);
@@ -570,12 +574,12 @@ fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
unsigned short status;
unsigned int estatus = 0;
+ dma_addr_t addr;
status = bdp->cbd_sc;
status &= ~BD_ENET_TX_STATS;
status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
- bdp->cbd_datlen = size;
if (((unsigned long) data) & FEC_ALIGNMENT ||
id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) {
@@ -586,15 +590,17 @@ fec_enet_txq_put_data_tso(struct sk_buff *skb, struct net_device *ndev,
swap_buffer(data, size);
}
- bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, data,
- size, DMA_TO_DEVICE);
- if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+ addr = dma_map_single(&fep->pdev->dev, data, size, DMA_TO_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, addr)) {
dev_kfree_skb_any(skb);
if (net_ratelimit())
netdev_err(ndev, "Tx DMA memory map failed\n");
return NETDEV_TX_BUSY;
}
+ bdp->cbd_datlen = size;
+ bdp->cbd_bufaddr = addr;
+
if (fep->bufdesc_ex) {
if (skb->ip_summed == CHECKSUM_PARTIAL)
estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
@@ -732,8 +738,6 @@ static int fec_enet_txq_submit_tso(struct sk_buff *skb, struct net_device *ndev)
/* Save skb pointer */
fep->tx_skbuff[index] = skb;
- fec_enet_submit_work(bdp, fep);
-
skb_tx_timestamp(skb);
fep->cur_tx = bdp;
@@ -801,7 +805,7 @@ static void fec_enet_bd_init(struct net_device *dev)
/* Initialize the BD for every fragment in the page. */
bdp->cbd_sc = 0;
- if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) {
+ if (fep->tx_skbuff[i]) {
dev_kfree_skb_any(fep->tx_skbuff[i]);
fep->tx_skbuff[i] = NULL;
}
@@ -815,12 +819,13 @@ static void fec_enet_bd_init(struct net_device *dev)
fep->dirty_tx = bdp;
}
-/* This function is called to start or restart the FEC during a link
- * change. This only happens when switching between half and full
- * duplex.
+/*
+ * This function is called to start or restart the FEC during a link
+ * change, transmit timeout, or to reconfigure the FEC. The network
+ * packet processing for this device must be stopped before this call.
*/
static void
-fec_restart(struct net_device *ndev, int duplex)
+fec_restart(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
const struct platform_device_id *id_entry =
@@ -831,13 +836,6 @@ fec_restart(struct net_device *ndev, int duplex)
u32 rcntl = OPT_FRAME_SIZE | 0x04;
u32 ecntl = 0x2; /* ETHEREN */
- if (netif_running(ndev)) {
- netif_device_detach(ndev);
- napi_disable(&fep->napi);
- netif_stop_queue(ndev);
- netif_tx_lock_bh(ndev);
- }
-
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
@@ -878,7 +876,7 @@ fec_restart(struct net_device *ndev, int duplex)
}
/* Enable MII mode */
- if (duplex) {
+ if (fep->full_duplex == DUPLEX_FULL) {
/* FD enable */
writel(0x04, fep->hwp + FEC_X_CNTRL);
} else {
@@ -887,8 +885,6 @@ fec_restart(struct net_device *ndev, int duplex)
writel(0x0, fep->hwp + FEC_X_CNTRL);
}
- fep->full_duplex = duplex;
-
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
@@ -1006,13 +1002,6 @@ fec_restart(struct net_device *ndev, int duplex)
/* Enable interrupts we wish to service */
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
-
- if (netif_running(ndev)) {
- netif_tx_unlock_bh(ndev);
- netif_wake_queue(ndev);
- napi_enable(&fep->napi);
- netif_device_attach(ndev);
- }
}
static void
@@ -1050,29 +1039,44 @@ fec_timeout(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ fec_dump(ndev);
+
ndev->stats.tx_errors++;
- fep->delay_work.timeout = true;
- schedule_delayed_work(&(fep->delay_work.delay_work), 0);
+ schedule_work(&fep->tx_timeout_work);
}
-static void fec_enet_work(struct work_struct *work)
+static void fec_enet_timeout_work(struct work_struct *work)
{
struct fec_enet_private *fep =
- container_of(work,
- struct fec_enet_private,
- delay_work.delay_work.work);
+ container_of(work, struct fec_enet_private, tx_timeout_work);
+ struct net_device *ndev = fep->netdev;
- if (fep->delay_work.timeout) {
- fep->delay_work.timeout = false;
- fec_restart(fep->netdev, fep->full_duplex);
- netif_wake_queue(fep->netdev);
+ rtnl_lock();
+ if (netif_device_present(ndev) || netif_running(ndev)) {
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(ndev);
+ fec_restart(ndev);
+ netif_wake_queue(ndev);
+ netif_tx_unlock_bh(ndev);
+ napi_enable(&fep->napi);
}
+ rtnl_unlock();
+}
- if (fep->delay_work.trig_tx) {
- fep->delay_work.trig_tx = false;
- writel(0, fep->hwp + FEC_X_DES_ACTIVE);
- }
+static void
+fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
+ struct skb_shared_hwtstamps *hwtstamps)
+{
+ unsigned long flags;
+ u64 ns;
+
+ spin_lock_irqsave(&fep->tmreg_lock, flags);
+ ns = timecounter_cyc2time(&fep->tc, ts);
+ spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+ memset(hwtstamps, 0, sizeof(*hwtstamps));
+ hwtstamps->hwtstamp = ns_to_ktime(ns);
}
static void
@@ -1100,6 +1104,7 @@ fec_enet_tx(struct net_device *ndev)
index = fec_enet_get_bd_index(fep->tx_bd_base, bdp, fep);
skb = fep->tx_skbuff[index];
+ fep->tx_skbuff[index] = NULL;
if (!IS_TSO_HEADER(fep, bdp->cbd_bufaddr))
dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
bdp->cbd_datlen, DMA_TO_DEVICE);
@@ -1132,20 +1137,12 @@ fec_enet_tx(struct net_device *ndev)
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) &&
fep->bufdesc_ex) {
struct skb_shared_hwtstamps shhwtstamps;
- unsigned long flags;
struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
- memset(&shhwtstamps, 0, sizeof(shhwtstamps));
- spin_lock_irqsave(&fep->tmreg_lock, flags);
- shhwtstamps.hwtstamp = ns_to_ktime(
- timecounter_cyc2time(&fep->tc, ebdp->ts));
- spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+ fec_enet_hwtstamp(fep, ebdp->ts, &shhwtstamps);
skb_tstamp_tx(skb, &shhwtstamps);
}
- if (status & BD_ENET_TX_READY)
- netdev_err(ndev, "HEY! Enet xmit interrupt and TX_READY\n");
-
/* Deferred means some collisions occurred during transmit,
* but we eventually sent the packet OK.
*/
@@ -1154,7 +1151,6 @@ fec_enet_tx(struct net_device *ndev)
/* Free the sk buffer associated with this last transmit */
dev_kfree_skb_any(skb);
- fep->tx_skbuff[index] = NULL;
fep->dirty_tx = bdp;
@@ -1169,7 +1165,10 @@ fec_enet_tx(struct net_device *ndev)
netif_wake_queue(ndev);
}
}
- return;
+
+ /* ERR006538: Keep the transmitter going */
+ if (bdp != fep->cur_tx && readl(fep->hwp + FEC_X_DES_ACTIVE) == 0)
+ writel(0, fep->hwp + FEC_X_DES_ACTIVE);
}
/* During a receive, the cur_rx points to the current incoming buffer.
@@ -1215,8 +1214,7 @@ fec_enet_rx(struct net_device *ndev, int budget)
if ((status & BD_ENET_RX_LAST) == 0)
netdev_err(ndev, "rcv is not +last\n");
- if (!fep->opened)
- goto rx_processing_done;
+ writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT);
/* Check for errors. */
if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
@@ -1300,18 +1298,9 @@ fec_enet_rx(struct net_device *ndev, int budget)
skb->protocol = eth_type_trans(skb, ndev);
/* Get receive timestamp from the skb */
- if (fep->hwts_rx_en && fep->bufdesc_ex) {
- struct skb_shared_hwtstamps *shhwtstamps =
- skb_hwtstamps(skb);
- unsigned long flags;
-
- memset(shhwtstamps, 0, sizeof(*shhwtstamps));
-
- spin_lock_irqsave(&fep->tmreg_lock, flags);
- shhwtstamps->hwtstamp = ns_to_ktime(
- timecounter_cyc2time(&fep->tc, ebdp->ts));
- spin_unlock_irqrestore(&fep->tmreg_lock, flags);
- }
+ if (fep->hwts_rx_en && fep->bufdesc_ex)
+ fec_enet_hwtstamp(fep, ebdp->ts,
+ skb_hwtstamps(skb));
if (fep->bufdesc_ex &&
(fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
@@ -1369,29 +1358,25 @@ fec_enet_interrupt(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct fec_enet_private *fep = netdev_priv(ndev);
+ const unsigned napi_mask = FEC_ENET_RXF | FEC_ENET_TXF;
uint int_events;
irqreturn_t ret = IRQ_NONE;
- do {
- int_events = readl(fep->hwp + FEC_IEVENT);
- writel(int_events, fep->hwp + FEC_IEVENT);
+ int_events = readl(fep->hwp + FEC_IEVENT);
+ writel(int_events & ~napi_mask, fep->hwp + FEC_IEVENT);
- if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
- ret = IRQ_HANDLED;
+ if (int_events & napi_mask) {
+ ret = IRQ_HANDLED;
- /* Disable the RX interrupt */
- if (napi_schedule_prep(&fep->napi)) {
- writel(FEC_RX_DISABLED_IMASK,
- fep->hwp + FEC_IMASK);
- __napi_schedule(&fep->napi);
- }
- }
+ /* Disable the NAPI interrupts */
+ writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+ napi_schedule(&fep->napi);
+ }
- if (int_events & FEC_ENET_MII) {
- ret = IRQ_HANDLED;
- complete(&fep->mdio_done);
- }
- } while (int_events);
+ if (int_events & FEC_ENET_MII) {
+ ret = IRQ_HANDLED;
+ complete(&fep->mdio_done);
+ }
return ret;
}
@@ -1399,8 +1384,16 @@ fec_enet_interrupt(int irq, void *dev_id)
static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
{
struct net_device *ndev = napi->dev;
- int pkts = fec_enet_rx(ndev, budget);
struct fec_enet_private *fep = netdev_priv(ndev);
+ int pkts;
+
+ /*
+ * Clear any pending transmit or receive interrupts before
+ * processing the rings to avoid racing with the hardware.
+ */
+ writel(FEC_ENET_RXF | FEC_ENET_TXF, fep->hwp + FEC_IEVENT);
+
+ pkts = fec_enet_rx(ndev, budget);
fec_enet_tx(ndev);
@@ -1498,14 +1491,23 @@ static void fec_enet_adjust_link(struct net_device *ndev)
return;
}
- if (phy_dev->link) {
+ /*
+ * If the netdev is down, or is going down, we're not interested
+ * in link state events, so just mark our idea of the link as down
+ * and ignore the event.
+ */
+ if (!netif_running(ndev) || !netif_device_present(ndev)) {
+ fep->link = 0;
+ } else if (phy_dev->link) {
if (!fep->link) {
fep->link = phy_dev->link;
status_change = 1;
}
- if (fep->full_duplex != phy_dev->duplex)
+ if (fep->full_duplex != phy_dev->duplex) {
+ fep->full_duplex = phy_dev->duplex;
status_change = 1;
+ }
if (phy_dev->speed != fep->speed) {
fep->speed = phy_dev->speed;
@@ -1513,11 +1515,21 @@ static void fec_enet_adjust_link(struct net_device *ndev)
}
/* if any of the above changed restart the FEC */
- if (status_change)
- fec_restart(ndev, phy_dev->duplex);
+ if (status_change) {
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(ndev);
+ fec_restart(ndev);
+ netif_wake_queue(ndev);
+ netif_tx_unlock_bh(ndev);
+ napi_enable(&fep->napi);
+ }
} else {
if (fep->link) {
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(ndev);
fec_stop(ndev);
+ netif_tx_unlock_bh(ndev);
+ napi_enable(&fep->napi);
fep->link = phy_dev->link;
status_change = 1;
}
@@ -1667,6 +1679,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
/* mask with MAC supported features */
if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) {
phy_dev->supported &= PHY_GBIT_FEATURES;
+ phy_dev->supported &= ~SUPPORTED_1000baseT_Half;
#if !defined(CONFIG_M5272)
phy_dev->supported |= SUPPORTED_Pause;
#endif
@@ -1870,6 +1883,9 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
{
struct fec_enet_private *fep = netdev_priv(ndev);
+ if (!fep->phy_dev)
+ return -ENODEV;
+
if (pause->tx_pause != pause->rx_pause) {
netdev_info(ndev,
"hardware only support enable/disable both tx and rx");
@@ -1895,8 +1911,14 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
fec_stop(ndev);
phy_start_aneg(fep->phy_dev);
}
- if (netif_running(ndev))
- fec_restart(ndev, 0);
+ if (netif_running(ndev)) {
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(ndev);
+ fec_restart(ndev);
+ netif_wake_queue(ndev);
+ netif_tx_unlock_bh(ndev);
+ napi_enable(&fep->napi);
+ }
return 0;
}
@@ -2013,21 +2035,19 @@ static int fec_enet_nway_reset(struct net_device *dev)
}
static const struct ethtool_ops fec_enet_ethtool_ops = {
-#if !defined(CONFIG_M5272)
- .get_pauseparam = fec_enet_get_pauseparam,
- .set_pauseparam = fec_enet_set_pauseparam,
-#endif
.get_settings = fec_enet_get_settings,
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_ts_info = fec_enet_get_ts_info,
.nway_reset = fec_enet_nway_reset,
+ .get_link = ethtool_op_get_link,
#ifndef CONFIG_M5272
- .get_ethtool_stats = fec_enet_get_ethtool_stats,
+ .get_pauseparam = fec_enet_get_pauseparam,
+ .set_pauseparam = fec_enet_set_pauseparam,
.get_strings = fec_enet_get_strings,
+ .get_ethtool_stats = fec_enet_get_ethtool_stats,
.get_sset_count = fec_enet_get_sset_count,
#endif
+ .get_ts_info = fec_enet_get_ts_info,
};
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
@@ -2061,18 +2081,23 @@ static void fec_enet_free_buffers(struct net_device *ndev)
bdp = fep->rx_bd_base;
for (i = 0; i < fep->rx_ring_size; i++) {
skb = fep->rx_skbuff[i];
-
- if (bdp->cbd_bufaddr)
+ fep->rx_skbuff[i] = NULL;
+ if (skb) {
dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
- if (skb)
dev_kfree_skb(skb);
+ }
bdp = fec_enet_get_nextdesc(bdp, fep);
}
bdp = fep->tx_bd_base;
- for (i = 0; i < fep->tx_ring_size; i++)
+ for (i = 0; i < fep->tx_ring_size; i++) {
kfree(fep->tx_bounce[i]);
+ fep->tx_bounce[i] = NULL;
+ skb = fep->tx_skbuff[i];
+ fep->tx_skbuff[i] = NULL;
+ dev_kfree_skb(skb);
+ }
}
static int fec_enet_alloc_buffers(struct net_device *ndev)
@@ -2084,21 +2109,23 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
bdp = fep->rx_bd_base;
for (i = 0; i < fep->rx_ring_size; i++) {
+ dma_addr_t addr;
+
skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
- if (!skb) {
- fec_enet_free_buffers(ndev);
- return -ENOMEM;
- }
- fep->rx_skbuff[i] = skb;
+ if (!skb)
+ goto err_alloc;
- bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
+ addr = dma_map_single(&fep->pdev->dev, skb->data,
FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
- fec_enet_free_buffers(ndev);
+ if (dma_mapping_error(&fep->pdev->dev, addr)) {
+ dev_kfree_skb(skb);
if (net_ratelimit())
netdev_err(ndev, "Rx DMA memory map failed\n");
- return -ENOMEM;
+ goto err_alloc;
}
+
+ fep->rx_skbuff[i] = skb;
+ bdp->cbd_bufaddr = addr;
bdp->cbd_sc = BD_ENET_RX_EMPTY;
if (fep->bufdesc_ex) {
@@ -2116,6 +2143,8 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
bdp = fep->tx_bd_base;
for (i = 0; i < fep->tx_ring_size; i++) {
fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+ if (!fep->tx_bounce[i])
+ goto err_alloc;
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;
@@ -2133,6 +2162,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
bdp->cbd_sc |= BD_SC_WRAP;
return 0;
+
+ err_alloc:
+ fec_enet_free_buffers(ndev);
+ return -ENOMEM;
}
static int
@@ -2161,10 +2194,10 @@ fec_enet_open(struct net_device *ndev)
return ret;
}
+ fec_restart(ndev);
napi_enable(&fep->napi);
phy_start(fep->phy_dev);
netif_start_queue(ndev);
- fep->opened = 1;
return 0;
}
@@ -2173,17 +2206,17 @@ fec_enet_close(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- /* Don't know what to do yet. */
- napi_disable(&fep->napi);
- fep->opened = 0;
- netif_stop_queue(ndev);
- fec_stop(ndev);
+ phy_stop(fep->phy_dev);
- if (fep->phy_dev) {
- phy_stop(fep->phy_dev);
- phy_disconnect(fep->phy_dev);
+ if (netif_device_present(ndev)) {
+ napi_disable(&fep->napi);
+ netif_tx_disable(ndev);
+ fec_stop(ndev);
}
+ phy_disconnect(fep->phy_dev);
+ fep->phy_dev = NULL;
+
fec_enet_clk_enable(ndev, false);
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
fec_enet_free_buffers(ndev);
@@ -2310,12 +2343,21 @@ static void fec_poll_controller(struct net_device *dev)
}
#endif
+#define FEATURES_NEED_QUIESCE NETIF_F_RXCSUM
+
static int fec_set_features(struct net_device *netdev,
netdev_features_t features)
{
struct fec_enet_private *fep = netdev_priv(netdev);
netdev_features_t changed = features ^ netdev->features;
+ /* Quiesce the device if necessary */
+ if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(netdev);
+ fec_stop(netdev);
+ }
+
netdev->features = features;
/* Receive checksum has been changed */
@@ -2324,14 +2366,14 @@ static int fec_set_features(struct net_device *netdev,
fep->csum_flags |= FLAG_RX_CSUM_ENABLED;
else
fep->csum_flags &= ~FLAG_RX_CSUM_ENABLED;
+ }
- if (netif_running(netdev)) {
- fec_stop(netdev);
- fec_restart(netdev, fep->phy_dev->duplex);
- netif_wake_queue(netdev);
- } else {
- fec_restart(netdev, fep->phy_dev->duplex);
- }
+ /* Resume the device after updates */
+ if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
+ fec_restart(netdev);
+ netif_wake_queue(netdev);
+ netif_tx_unlock_bh(netdev);
+ napi_enable(&fep->napi);
}
return 0;
@@ -2432,7 +2474,7 @@ static int fec_enet_init(struct net_device *ndev)
ndev->hw_features = ndev->features;
- fec_restart(ndev, 0);
+ fec_restart(ndev);
return 0;
}
@@ -2615,7 +2657,7 @@ fec_probe(struct platform_device *pdev)
if (fep->bufdesc_ex && fep->ptp_clock)
netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);
- INIT_DELAYED_WORK(&(fep->delay_work.delay_work), fec_enet_work);
+ INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);
return 0;
failed_register:
@@ -2640,7 +2682,7 @@ fec_drv_remove(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
- cancel_delayed_work_sync(&(fep->delay_work.delay_work));
+ cancel_work_sync(&fep->tx_timeout_work);
unregister_netdev(ndev);
fec_enet_mii_remove(fep);
del_timer_sync(&fep->time_keep);
@@ -2654,17 +2696,22 @@ fec_drv_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
-static int
-fec_suspend(struct device *dev)
+static int __maybe_unused fec_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
+ rtnl_lock();
if (netif_running(ndev)) {
- fec_stop(ndev);
+ phy_stop(fep->phy_dev);
+ napi_disable(&fep->napi);
+ netif_tx_lock_bh(ndev);
netif_device_detach(ndev);
+ netif_tx_unlock_bh(ndev);
+ fec_stop(ndev);
}
+ rtnl_unlock();
+
fec_enet_clk_enable(ndev, false);
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
@@ -2674,8 +2721,7 @@ fec_suspend(struct device *dev)
return 0;
}
-static int
-fec_resume(struct device *dev)
+static int __maybe_unused fec_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -2692,10 +2738,16 @@ fec_resume(struct device *dev)
if (ret)
goto failed_clk;
+ rtnl_lock();
if (netif_running(ndev)) {
- fec_restart(ndev, fep->full_duplex);
+ fec_restart(ndev);
+ netif_tx_lock_bh(ndev);
netif_device_attach(ndev);
+ netif_tx_unlock_bh(ndev);
+ napi_enable(&fep->napi);
+ phy_start(fep->phy_dev);
}
+ rtnl_unlock();
return 0;
@@ -2704,7 +2756,6 @@ failed_clk:
regulator_disable(fep->reg_phy);
return ret;
}
-#endif /* CONFIG_PM_SLEEP */
static SIMPLE_DEV_PM_OPS(fec_pm_ops, fec_suspend, fec_resume);
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
index fc5413488496..1eedfba2ad3c 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
@@ -41,7 +41,6 @@
#ifdef CONFIG_8xx
#include <asm/8xx_immap.h>
#include <asm/pgtable.h>
-#include <asm/mpc8xx.h>
#include <asm/cpm1.h>
#endif
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
index b4bf02f57d43..90b3b19b7cd3 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
@@ -40,7 +40,6 @@
#ifdef CONFIG_8xx
#include <asm/8xx_immap.h>
#include <asm/pgtable.h>
-#include <asm/mpc8xx.h>
#include <asm/cpm1.h>
#endif
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index fab39e295441..8ceaf7a2660c 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2396,7 +2396,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
pr_err("Bad number of Rx threads value\n");
return -EINVAL;
- break;
}
switch (ug_info->numThreadsTx) {
@@ -2419,7 +2418,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (netif_msg_ifup(ugeth))
pr_err("Bad number of Tx threads value\n");
return -EINVAL;
- break;
}
/* Calculate rx_extended_features */
@@ -2990,11 +2988,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
if (ug_info->rxExtendedFiltering) {
size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
if (ug_info->largestexternallookupkeysize ==
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
+ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
size +=
THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8;
if (ug_info->largestexternallookupkeysize ==
- QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
+ QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)
size +=
THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16;
}
diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index 0c9d55c862ae..6e7db66069aa 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -46,7 +46,7 @@ struct tgec_mdio_controller {
#define MDIO_DATA_BSY (1 << 31)
/*
- * Wait untill the MDIO bus is free
+ * Wait until the MDIO bus is free
*/
static int xgmac_wait_until_free(struct device *dev,
struct tgec_mdio_controller __iomem *regs)
@@ -163,7 +163,7 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
/* Return all Fs if nothing was there */
if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER) {
dev_err(&bus->dev,
- "Error while reading PHY%d reg at %d.%d\n",
+ "Error while reading PHY%d reg at %d.%hhu\n",
phy_id, dev_addr, regnum);
return 0xffff;
}
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index d50f78afb56d..cca5bca44e73 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -1316,7 +1316,6 @@ static int e1000_set_phy_loopback(struct e1000_adapter *adapter)
case e1000_82547:
case e1000_82547_rev_2:
return e1000_integrated_phy_loopback(adapter);
- break;
default:
/* Default PHY loopback work is to read the MII
* control register and assert bit 14 (loopback mode).
@@ -1325,7 +1324,6 @@ static int e1000_set_phy_loopback(struct e1000_adapter *adapter)
phy_reg |= MII_CR_LOOPBACK;
e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
return 0;
- break;
}
return 8;
@@ -1344,7 +1342,6 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
case e1000_82545_rev_3:
case e1000_82546_rev_3:
return e1000_set_phy_loopback(adapter);
- break;
default:
rctl = er32(RCTL);
rctl |= E1000_RCTL_LBM_TCVR;
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.c b/drivers/net/ethernet/intel/e1000/e1000_hw.c
index e9b07ccc0eba..1acf5034db10 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_hw.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_hw.c
@@ -902,7 +902,6 @@ static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
default:
e_dbg("Flow control param set incorrectly\n");
return -E1000_ERR_CONFIG;
- break;
}
/* Since auto-negotiation is enabled, take the link out of reset (the
@@ -5041,7 +5040,6 @@ static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
break;
default:
return -E1000_ERR_PHY;
- break;
}
} else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
u16 cur_agc_value;
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c
index 218481e509f9..dc79ed85030b 100644
--- a/drivers/net/ethernet/intel/e1000e/82571.c
+++ b/drivers/net/ethernet/intel/e1000e/82571.c
@@ -95,7 +95,6 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
break;
default:
return -E1000_ERR_PHY;
- break;
}
/* This can only be done after all function pointers are setup. */
@@ -422,7 +421,6 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
break;
case e1000_82573:
return e1000e_get_phy_id(hw);
- break;
case e1000_82574:
case e1000_82583:
ret_val = e1e_rphy(hw, MII_PHYSID1, &phy_id);
@@ -440,7 +438,6 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
break;
default:
return -E1000_ERR_PHY;
- break;
}
return 0;
@@ -1458,7 +1455,6 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
break;
default:
return -E1000_ERR_PHY;
- break;
}
if (ret_val)
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h
index d18e89212575..bb7ab3c321d6 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -342,6 +342,7 @@
#define E1000_TIPG_IPGR2_SHIFT 20
#define MAX_JUMBO_FRAME_SIZE 0x3F00
+#define E1000_TX_PTR_GAP 0x1F
/* Extended Configuration Control and Size */
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 815e26c6d34b..865ce45f9ec3 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -1521,11 +1521,9 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
switch (hw->mac.type) {
case e1000_80003es2lan:
return e1000_set_es2lan_mac_loopback(adapter);
- break;
case e1000_82571:
case e1000_82572:
return e1000_set_82571_fiber_loopback(adapter);
- break;
default:
rctl = er32(RCTL);
rctl |= E1000_RCTL_LBM_TCVR;
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 8894ab8ed6bd..48b74a549155 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -572,7 +572,6 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
break;
default:
return -E1000_ERR_PHY;
- break;
}
return 0;
@@ -2445,7 +2444,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
return ret_val;
e1e_rphy(hw, PHY_REG(776, 20), &data);
data &= ~(0x3FF << 2);
- data |= (0x1A << 2);
+ data |= (E1000_TX_PTR_GAP << 2);
ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
if (ret_val)
return ret_val;
@@ -4606,14 +4605,23 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
/* Disable LPLU if both link partners support 100BaseT
* EEE and 100Full is advertised on both ends of the
- * link.
+ * link, and enable Auto Enable LPI since there will
+ * be no driver to enable LPI while in Sx.
*/
if ((eee_advert & I82579_EEE_100_SUPPORTED) &&
(dev_spec->eee_lp_ability &
I82579_EEE_100_SUPPORTED) &&
- (hw->phy.autoneg_advertised & ADVERTISE_100_FULL))
+ (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)) {
phy_ctrl &= ~(E1000_PHY_CTRL_D0A_LPLU |
E1000_PHY_CTRL_NOND0A_LPLU);
+
+ /* Set Auto Enable LPI after link up */
+ e1e_rphy_locked(hw,
+ I217_LPI_GPIO_CTRL, &phy_reg);
+ phy_reg |= I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
+ e1e_wphy_locked(hw,
+ I217_LPI_GPIO_CTRL, phy_reg);
+ }
}
/* For i217 Intel Rapid Start Technology support,
@@ -4710,6 +4718,11 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
return;
}
+ /* Clear Auto Enable LPI after link up */
+ e1e_rphy_locked(hw, I217_LPI_GPIO_CTRL, &phy_reg);
+ phy_reg &= ~I217_LPI_GPIO_CTRL_AUTO_EN_LPI;
+ e1e_wphy_locked(hw, I217_LPI_GPIO_CTRL, phy_reg);
+
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
/* Restore clear on SMB if no manageability engine
* is present
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
index 5515126c81c1..8066a498eaac 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -217,6 +217,10 @@
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_MASK 0x3F00
#define I217_INBAND_CTRL_LINK_STAT_TX_TIMEOUT_SHIFT 8
+/* Low Power Idle GPIO Control */
+#define I217_LPI_GPIO_CTRL PHY_REG(772, 18)
+#define I217_LPI_GPIO_CTRL_AUTO_EN_LPI 0x0800
+
/* PHY Low Power Idle Control */
#define I82579_LPI_CTRL PHY_REG(772, 20)
#define I82579_LPI_CTRL_100_ENABLE 0x2000
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c
index 8c386f3a15eb..30b74d590bee 100644
--- a/drivers/net/ethernet/intel/e1000e/mac.c
+++ b/drivers/net/ethernet/intel/e1000e/mac.c
@@ -787,7 +787,6 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
default:
e_dbg("Flow control param set incorrectly\n");
return -E1000_ERR_CONFIG;
- break;
}
ew32(TXCW, txcw);
diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c
index cb37ff1f1321..58856032298d 100644
--- a/drivers/net/ethernet/intel/e1000e/manage.c
+++ b/drivers/net/ethernet/intel/e1000e/manage.c
@@ -327,9 +327,12 @@ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
} else if ((hw->mac.type == e1000_82574) ||
(hw->mac.type == e1000_82583)) {
u16 data;
+ s32 ret_val;
factps = er32(FACTPS);
- e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+ ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+ if (ret_val)
+ return false;
if (!(factps & E1000_FACTPS_MNGCG) &&
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 201cc93f3625..65c3aef2bd36 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6033,6 +6033,28 @@ release:
return retval;
}
+static void e1000e_flush_lpic(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ret_val;
+
+ pm_runtime_get_sync(netdev->dev.parent);
+
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ goto fl_out;
+
+ pr_info("EEE TX LPI TIMER: %08X\n",
+ er32(LPIC) >> E1000_LPIC_LPIET_SHIFT);
+
+ hw->phy.ops.release(hw);
+
+fl_out:
+ pm_runtime_put_sync(netdev->dev.parent);
+}
+
static int e1000e_pm_freeze(struct device *dev)
{
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
@@ -6333,6 +6355,8 @@ static int e1000e_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ e1000e_flush_lpic(pdev);
+
e1000e_pm_freeze(dev);
return __e1000_shutdown(pdev, false);
@@ -6357,9 +6381,14 @@ static int e1000e_pm_runtime_idle(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ u16 eee_lp;
- if (!e1000e_has_link(adapter))
+ eee_lp = adapter->hw.dev_spec.ich8lan.eee_lp_ability;
+
+ if (!e1000e_has_link(adapter)) {
+ adapter->hw.dev_spec.ich8lan.eee_lp_ability = eee_lp;
pm_schedule_suspend(dev, 5 * MSEC_PER_SEC);
+ }
return -EBUSY;
}
@@ -6411,6 +6440,8 @@ static int e1000e_pm_runtime_suspend(struct device *dev)
static void e1000_shutdown(struct pci_dev *pdev)
{
+ e1000e_flush_lpic(pdev);
+
e1000e_pm_freeze(&pdev->dev);
__e1000_shutdown(pdev, false);
@@ -6708,6 +6739,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int bars, i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ s32 rval = 0;
if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
aspm_disable_flag = PCIE_LINK_STATE_L0S;
@@ -6940,15 +6972,19 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
(adapter->hw.bus.func == 1))
- e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_B,
- 1, &eeprom_data);
+ rval = e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL3_PORT_B,
+ 1, &eeprom_data);
else
- e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A,
- 1, &eeprom_data);
+ rval = e1000_read_nvm(&adapter->hw,
+ NVM_INIT_CONTROL3_PORT_A,
+ 1, &eeprom_data);
}
/* fetch WoL from EEPROM */
- if (eeprom_data & eeprom_apme_mask)
+ if (rval)
+ e_dbg("NVM read error getting WoL initial values: %d\n", rval);
+ else if (eeprom_data & eeprom_apme_mask)
adapter->eeprom_wol |= E1000_WUFC_MAG;
/* now that we have the eeprom settings, apply the special cases
@@ -6967,7 +7003,12 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
device_wakeup_enable(&pdev->dev);
/* save off EEPROM version number */
- e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
+ rval = e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
+
+ if (rval) {
+ e_dbg("NVM read error getting EEPROM version: %d\n", rval);
+ adapter->eeprom_vers = 0;
+ }
/* reset the hardware with the new settings */
e1000e_reset(adapter);
diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c
index b1f212b7baf7..fa6b1036a327 100644
--- a/drivers/net/ethernet/intel/e1000e/nvm.c
+++ b/drivers/net/ethernet/intel/e1000e/nvm.c
@@ -327,8 +327,10 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
ew32(EERD, eerd);
ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
- if (ret_val)
+ if (ret_val) {
+ e_dbg("NVM read error: %d\n", ret_val);
break;
+ }
data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
}
diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile
index d9eb80acac4f..4b94ddb29c24 100644
--- a/drivers/net/ethernet/intel/i40e/Makefile
+++ b/drivers/net/ethernet/intel/i40e/Makefile
@@ -44,3 +44,4 @@ i40e-objs := i40e_main.o \
i40e_virtchnl_pf.o
i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o
+i40e-$(CONFIG_FCOE:m=y) += i40e_fcoe.o
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 65985846345d..801da392a20e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -54,6 +54,9 @@
#include <linux/ptp_clock_kernel.h>
#include "i40e_type.h"
#include "i40e_prototype.h"
+#ifdef I40E_FCOE
+#include "i40e_fcoe.h"
+#endif
#include "i40e_virtchnl.h"
#include "i40e_virtchnl_pf.h"
#include "i40e_txrx.h"
@@ -79,11 +82,16 @@
#define I40E_MAX_QUEUES_PER_TC 64 /* should be a power of 2 */
#define I40E_FDIR_RING 0
#define I40E_FDIR_RING_COUNT 32
+#ifdef I40E_FCOE
+#define I40E_DEFAULT_FCOE 8 /* default number of QPs for FCoE */
+#define I40E_MINIMUM_FCOE 1 /* minimum number of QPs for FCoE */
+#endif /* I40E_FCOE */
#define I40E_MAX_AQ_BUF_SIZE 4096
#define I40E_AQ_LEN 32
#define I40E_AQ_WORK_LIMIT 16
#define I40E_MAX_USER_PRIORITY 8
#define I40E_DEFAULT_MSG_ENABLE 4
+#define I40E_QUEUE_WAIT_RETRY_LIMIT 10
#define I40E_NVM_VERSION_LO_SHIFT 0
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
@@ -133,7 +141,9 @@ enum i40e_state_t {
__I40E_EMP_RESET_REQUESTED,
__I40E_FILTER_OVERFLOW_PROMISC,
__I40E_SUSPENDED,
+ __I40E_PTP_TX_IN_PROGRESS,
__I40E_BAD_EEPROM,
+ __I40E_DOWN_REQUESTED,
};
enum i40e_interrupt_policy {
@@ -152,7 +162,7 @@ struct i40e_lump_tracking {
#define I40E_DEFAULT_ATR_SAMPLE_RATE 20
#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512
#define I40E_FDIR_BUFFER_FULL_MARGIN 10
-#define I40E_FDIR_BUFFER_HEAD_ROOM 200
+#define I40E_FDIR_BUFFER_HEAD_ROOM 32
enum i40e_fd_stat_idx {
I40E_FD_STAT_ATR,
@@ -222,6 +232,10 @@ struct i40e_pf {
u16 num_vmdq_msix; /* num queue vectors per vmdq pool */
u16 num_req_vfs; /* num vfs requested for this vf */
u16 num_vf_qps; /* num queue pairs per vf */
+#ifdef I40E_FCOE
+ u16 num_fcoe_qps; /* num fcoe queues this pf has set up */
+ u16 num_fcoe_msix; /* num queue vectors per fcoe pool */
+#endif /* I40E_FCOE */
u16 num_lan_qps; /* num lan queues this pf has set up */
u16 num_lan_msix; /* num queue vectors for the base pf vsi */
int queues_left; /* queues left unclaimed */
@@ -262,6 +276,9 @@ struct i40e_pf {
#define I40E_FLAG_VMDQ_ENABLED (u64)(1 << 7)
#define I40E_FLAG_FDIR_REQUIRES_REINIT (u64)(1 << 8)
#define I40E_FLAG_NEED_LINK_UPDATE (u64)(1 << 9)
+#ifdef I40E_FCOE
+#define I40E_FLAG_FCOE_ENABLED (u64)(1 << 11)
+#endif /* I40E_FCOE */
#define I40E_FLAG_IN_NETPOLL (u64)(1 << 12)
#define I40E_FLAG_16BYTE_RX_DESC_ENABLED (u64)(1 << 13)
#define I40E_FLAG_CLEAN_ADMINQ (u64)(1 << 14)
@@ -277,11 +294,16 @@ struct i40e_pf {
#ifdef CONFIG_I40E_VXLAN
#define I40E_FLAG_VXLAN_FILTER_SYNC (u64)(1 << 27)
#endif
+#define I40E_FLAG_PORT_ID_VALID (u64)(1 << 28)
#define I40E_FLAG_DCB_CAPABLE (u64)(1 << 29)
/* tracks features that get auto disabled by errors */
u64 auto_disable_flags;
+#ifdef I40E_FCOE
+ struct i40e_fcoe fcoe;
+
+#endif /* I40E_FCOE */
bool stat_offsets_loaded;
struct i40e_hw_port_stats stats;
struct i40e_hw_port_stats stats_offsets;
@@ -348,6 +370,7 @@ struct i40e_pf {
u32 rx_hwtstamp_cleared;
bool ptp_tx;
bool ptp_rx;
+ u16 rss_table_size;
};
struct i40e_mac_filter {
@@ -359,6 +382,7 @@ struct i40e_mac_filter {
bool is_vf; /* filter belongs to a VF */
bool is_netdev; /* filter belongs to a netdev */
bool changed; /* filter needs to be sync'd to the HW */
+ bool is_laa; /* filter is a Locally Administered Address */
};
struct i40e_veb {
@@ -402,6 +426,11 @@ struct i40e_vsi {
struct rtnl_link_stats64 net_stats_offsets;
struct i40e_eth_stats eth_stats;
struct i40e_eth_stats eth_stats_offsets;
+#ifdef I40E_FCOE
+ struct i40e_fcoe_stats fcoe_stats;
+ struct i40e_fcoe_stats fcoe_stats_offsets;
+ bool fcoe_stat_offsets_loaded;
+#endif
u32 tx_restart;
u32 tx_busy;
u32 rx_buf_failed;
@@ -578,6 +607,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input, bool add);
void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
int i40e_get_current_fd_count(struct i40e_pf *pf);
+int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
void i40e_set_ethtool_ops(struct net_device *netdev);
struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
@@ -591,6 +621,11 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
int i40e_vsi_release(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, enum i40e_vsi_type type,
struct i40e_vsi *start_vsi);
+#ifdef I40E_FCOE
+void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
+ struct i40e_vsi_context *ctxt,
+ u8 enabled_tc, bool is_add);
+#endif
int i40e_vsi_control_rings(struct i40e_vsi *vsi, bool enable);
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count);
struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid,
@@ -614,9 +649,24 @@ static inline void i40e_dbg_init(void) {}
static inline void i40e_dbg_exit(void) {}
#endif /* CONFIG_DEBUG_FS*/
void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector);
+void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector);
void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf);
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf);
+#ifdef I40E_FCOE
+struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
+ struct net_device *netdev,
+ struct rtnl_link_stats64 *storage);
+int i40e_set_mac(struct net_device *netdev, void *p);
+void i40e_set_rx_mode(struct net_device *netdev);
+#endif
int i40e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
+#ifdef I40E_FCOE
+void i40e_tx_timeout(struct net_device *netdev);
+int i40e_vlan_rx_add_vid(struct net_device *netdev,
+ __always_unused __be16 proto, u16 vid);
+int i40e_vlan_rx_kill_vid(struct net_device *netdev,
+ __always_unused __be16 proto, u16 vid);
+#endif
int i40e_vsi_open(struct i40e_vsi *vsi);
void i40e_vlan_stripping_disable(struct i40e_vsi *vsi);
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid);
@@ -626,6 +676,26 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
+#ifdef I40E_FCOE
+int i40e_open(struct net_device *netdev);
+int i40e_close(struct net_device *netdev);
+int i40e_setup_tc(struct net_device *netdev, u8 tc);
+void i40e_netpoll(struct net_device *netdev);
+int i40e_fcoe_enable(struct net_device *netdev);
+int i40e_fcoe_disable(struct net_device *netdev);
+int i40e_fcoe_vsi_init(struct i40e_vsi *vsi, struct i40e_vsi_context *ctxt);
+u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf);
+void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi);
+void i40e_fcoe_vsi_setup(struct i40e_pf *pf);
+int i40e_init_pf_fcoe(struct i40e_pf *pf);
+int i40e_fcoe_setup_ddp_resources(struct i40e_vsi *vsi);
+void i40e_fcoe_free_ddp_resources(struct i40e_vsi *vsi);
+int i40e_fcoe_handle_offload(struct i40e_ring *rx_ring,
+ union i40e_rx_desc *rx_desc,
+ struct sk_buff *skb);
+void i40e_fcoe_handle_status(struct i40e_ring *rx_ring,
+ union i40e_rx_desc *rx_desc, u8 prog_id);
+#endif /* I40E_FCOE */
void i40e_vlan_stripping_enable(struct i40e_vsi *vsi);
#ifdef CONFIG_I40E_DCB
void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 7a027499fc57..b29c157b1f57 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -38,8 +38,8 @@ static void i40e_resume_aq(struct i40e_hw *hw);
**/
static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
{
- return (desc->opcode == i40e_aqc_opc_nvm_erase) ||
- (desc->opcode == i40e_aqc_opc_nvm_update);
+ return (desc->opcode == cpu_to_le16(i40e_aqc_opc_nvm_erase)) ||
+ (desc->opcode == cpu_to_le16(i40e_aqc_opc_nvm_update));
}
/**
@@ -55,16 +55,24 @@ static void i40e_adminq_init_regs(struct i40e_hw *hw)
hw->aq.asq.tail = I40E_VF_ATQT1;
hw->aq.asq.head = I40E_VF_ATQH1;
hw->aq.asq.len = I40E_VF_ATQLEN1;
+ hw->aq.asq.bal = I40E_VF_ATQBAL1;
+ hw->aq.asq.bah = I40E_VF_ATQBAH1;
hw->aq.arq.tail = I40E_VF_ARQT1;
hw->aq.arq.head = I40E_VF_ARQH1;
hw->aq.arq.len = I40E_VF_ARQLEN1;
+ hw->aq.arq.bal = I40E_VF_ARQBAL1;
+ hw->aq.arq.bah = I40E_VF_ARQBAH1;
} else {
hw->aq.asq.tail = I40E_PF_ATQT;
hw->aq.asq.head = I40E_PF_ATQH;
hw->aq.asq.len = I40E_PF_ATQLEN;
+ hw->aq.asq.bal = I40E_PF_ATQBAL;
+ hw->aq.asq.bah = I40E_PF_ATQBAH;
hw->aq.arq.tail = I40E_PF_ARQT;
hw->aq.arq.head = I40E_PF_ARQH;
hw->aq.arq.len = I40E_PF_ARQLEN;
+ hw->aq.arq.bal = I40E_PF_ARQBAL;
+ hw->aq.arq.bah = I40E_PF_ARQBAH;
}
}
@@ -296,27 +304,18 @@ static i40e_status i40e_config_asq_regs(struct i40e_hw *hw)
i40e_status ret_code = 0;
u32 reg = 0;
- if (hw->mac.type == I40E_MAC_VF) {
- /* configure the transmit queue */
- wr32(hw, I40E_VF_ATQBAH1,
- upper_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_VF_ATQBAL1,
- lower_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_VF_ATQLEN1, (hw->aq.num_asq_entries |
- I40E_VF_ATQLEN1_ATQENABLE_MASK));
- reg = rd32(hw, I40E_VF_ATQBAL1);
- } else {
- /* configure the transmit queue */
- wr32(hw, I40E_PF_ATQBAH,
- upper_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_PF_ATQBAL,
- lower_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_PF_ATQLEN, (hw->aq.num_asq_entries |
- I40E_PF_ATQLEN_ATQENABLE_MASK));
- reg = rd32(hw, I40E_PF_ATQBAL);
- }
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.asq.head, 0);
+ wr32(hw, hw->aq.asq.tail, 0);
+
+ /* set starting point */
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ I40E_PF_ATQLEN_ATQENABLE_MASK));
+ wr32(hw, hw->aq.asq.bal, lower_32_bits(hw->aq.asq.desc_buf.pa));
+ wr32(hw, hw->aq.asq.bah, upper_32_bits(hw->aq.asq.desc_buf.pa));
/* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.asq.bal);
if (reg != lower_32_bits(hw->aq.asq.desc_buf.pa))
ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
@@ -334,30 +333,21 @@ static i40e_status i40e_config_arq_regs(struct i40e_hw *hw)
i40e_status ret_code = 0;
u32 reg = 0;
- if (hw->mac.type == I40E_MAC_VF) {
- /* configure the receive queue */
- wr32(hw, I40E_VF_ARQBAH1,
- upper_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_VF_ARQBAL1,
- lower_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_VF_ARQLEN1, (hw->aq.num_arq_entries |
- I40E_VF_ARQLEN1_ARQENABLE_MASK));
- reg = rd32(hw, I40E_VF_ARQBAL1);
- } else {
- /* configure the receive queue */
- wr32(hw, I40E_PF_ARQBAH,
- upper_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_PF_ARQBAL,
- lower_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_PF_ARQLEN, (hw->aq.num_arq_entries |
- I40E_PF_ARQLEN_ARQENABLE_MASK));
- reg = rd32(hw, I40E_PF_ARQBAL);
- }
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.arq.head, 0);
+ wr32(hw, hw->aq.arq.tail, 0);
+
+ /* set starting point */
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ I40E_PF_ARQLEN_ARQENABLE_MASK));
+ wr32(hw, hw->aq.arq.bal, lower_32_bits(hw->aq.arq.desc_buf.pa));
+ wr32(hw, hw->aq.arq.bah, upper_32_bits(hw->aq.arq.desc_buf.pa));
/* Update tail in the HW to post pre-allocated buffers */
wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1);
/* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.arq.bal);
if (reg != lower_32_bits(hw->aq.arq.desc_buf.pa))
ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
@@ -499,6 +489,8 @@ static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
wr32(hw, hw->aq.asq.head, 0);
wr32(hw, hw->aq.asq.tail, 0);
wr32(hw, hw->aq.asq.len, 0);
+ wr32(hw, hw->aq.asq.bal, 0);
+ wr32(hw, hw->aq.asq.bah, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.asq_mutex);
@@ -530,6 +522,8 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
wr32(hw, hw->aq.arq.head, 0);
wr32(hw, hw->aq.arq.tail, 0);
wr32(hw, hw->aq.arq.len, 0);
+ wr32(hw, hw->aq.arq.bal, 0);
+ wr32(hw, hw->aq.arq.bah, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.arq_mutex);
@@ -577,6 +571,9 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
/* Set up register offsets */
i40e_adminq_init_regs(hw);
+ /* setup ASQ command write back timeout */
+ hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT;
+
/* allocate the ASQ */
ret_code = i40e_init_asq(hw);
if (ret_code)
@@ -677,6 +674,10 @@ static u16 i40e_clean_asq(struct i40e_hw *hw)
desc = I40E_ADMINQ_DESC(*asq, ntc);
details = I40E_ADMINQ_DETAILS(*asq, ntc);
while (rd32(hw, hw->aq.asq.head) != ntc) {
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "%s: ntc %d head %d.\n", __func__, ntc,
+ rd32(hw, hw->aq.asq.head));
+
if (details->callback) {
I40E_ADMINQ_CALLBACK cb_func =
(I40E_ADMINQ_CALLBACK)details->callback;
@@ -736,6 +737,15 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
struct i40e_aq_desc *desc_on_ring;
bool cmd_completed = false;
u16 retval = 0;
+ u32 val = 0;
+
+ val = rd32(hw, hw->aq.asq.head);
+ if (val >= hw->aq.num_asq_entries) {
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "AQTX: head overrun at %d\n", val);
+ status = I40E_ERR_QUEUE_EMPTY;
+ goto asq_send_command_exit;
+ }
if (hw->aq.asq.count == 0) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
@@ -829,6 +839,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
}
/* bump the tail */
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff);
(hw->aq.asq.next_to_use)++;
if (hw->aq.asq.next_to_use == hw->aq.asq.count)
@@ -852,7 +863,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
/* ugh! delay while spin_lock */
udelay(delay_len);
total_delay += delay_len;
- } while (total_delay < I40E_ASQ_CMD_TIMEOUT);
+ } while (total_delay < hw->aq.asq_cmd_timeout);
}
/* if ready, copy the desc back to temp */
@@ -866,6 +877,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
I40E_DEBUG_AQ_MESSAGE,
"AQTX: Command completed with error 0x%X.\n",
retval);
+
/* strip off FW internal code */
retval &= 0xff;
}
@@ -877,8 +889,9 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
}
- if (i40e_is_nvm_update_op(desc))
- hw->aq.nvm_busy = true;
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "AQTX: desc and buffer writeback:\n");
+ i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff);
/* update the error if time out occurred */
if ((!cmd_completed) &&
@@ -889,6 +902,9 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
}
+ if (!status && i40e_is_nvm_update_op(desc))
+ hw->aq.nvm_busy = true;
+
asq_send_command_error:
mutex_unlock(&hw->aq.asq_mutex);
asq_send_command_exit:
@@ -951,10 +967,6 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
/* now clean the next descriptor */
desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc);
desc_idx = ntc;
- i40e_debug_aq(hw,
- I40E_DEBUG_AQ_COMMAND,
- (void *)desc,
- hw->aq.arq.r.arq_bi[desc_idx].va);
flags = le16_to_cpu(desc->flags);
if (flags & I40E_AQ_FLAG_ERR) {
@@ -965,17 +977,17 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
I40E_DEBUG_AQ_MESSAGE,
"AQRX: Event received with error 0x%X.\n",
hw->aq.arq_last_status);
- } else {
- e->desc = *desc;
- datalen = le16_to_cpu(desc->datalen);
- e->msg_size = min(datalen, e->msg_size);
- if (e->msg_buf != NULL && (e->msg_size != 0))
- memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
- e->msg_size);
}
- if (i40e_is_nvm_update_op(&e->desc))
- hw->aq.nvm_busy = false;
+ e->desc = *desc;
+ datalen = le16_to_cpu(desc->datalen);
+ e->msg_size = min(datalen, e->msg_size);
+ if (e->msg_buf != NULL && (e->msg_size != 0))
+ memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
+ e->msg_size);
+
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
+ i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
/* Restore the original datalen and buffer address in the desc,
* FW updates datalen to indicate the event message
@@ -1006,6 +1018,14 @@ clean_arq_element_out:
*pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
mutex_unlock(&hw->aq.arq_mutex);
+ if (i40e_is_nvm_update_op(&e->desc)) {
+ hw->aq.nvm_busy = false;
+ if (hw->aq.nvm_release_on_done) {
+ i40e_release_nvm(hw);
+ hw->aq.nvm_release_on_done = false;
+ }
+ }
+
return ret_code;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index b1552fbc48a0..ba38a89c79d6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -56,6 +56,8 @@ struct i40e_adminq_ring {
u32 head;
u32 tail;
u32 len;
+ u32 bah;
+ u32 bal;
};
/* ASQ transaction details */
@@ -82,6 +84,7 @@ struct i40e_arq_event_info {
struct i40e_adminq_info {
struct i40e_adminq_ring arq; /* receive queue */
struct i40e_adminq_ring asq; /* send queue */
+ u32 asq_cmd_timeout; /* send queue cmd write back timeout*/
u16 num_arq_entries; /* receive queue depth */
u16 num_asq_entries; /* send queue depth */
u16 arq_buf_size; /* receive queue buffer size */
@@ -91,6 +94,7 @@ struct i40e_adminq_info {
u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */
bool nvm_busy;
+ bool nvm_release_on_done;
struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */
@@ -100,6 +104,41 @@ struct i40e_adminq_info {
enum i40e_admin_queue_err arq_last_status;
};
+/**
+ * i40e_aq_rc_to_posix - convert errors to user-land codes
+ * aq_rc: AdminQ error code to convert
+ **/
+static inline int i40e_aq_rc_to_posix(u16 aq_rc)
+{
+ int aq_to_posix[] = {
+ 0, /* I40E_AQ_RC_OK */
+ -EPERM, /* I40E_AQ_RC_EPERM */
+ -ENOENT, /* I40E_AQ_RC_ENOENT */
+ -ESRCH, /* I40E_AQ_RC_ESRCH */
+ -EINTR, /* I40E_AQ_RC_EINTR */
+ -EIO, /* I40E_AQ_RC_EIO */
+ -ENXIO, /* I40E_AQ_RC_ENXIO */
+ -E2BIG, /* I40E_AQ_RC_E2BIG */
+ -EAGAIN, /* I40E_AQ_RC_EAGAIN */
+ -ENOMEM, /* I40E_AQ_RC_ENOMEM */
+ -EACCES, /* I40E_AQ_RC_EACCES */
+ -EFAULT, /* I40E_AQ_RC_EFAULT */
+ -EBUSY, /* I40E_AQ_RC_EBUSY */
+ -EEXIST, /* I40E_AQ_RC_EEXIST */
+ -EINVAL, /* I40E_AQ_RC_EINVAL */
+ -ENOTTY, /* I40E_AQ_RC_ENOTTY */
+ -ENOSPC, /* I40E_AQ_RC_ENOSPC */
+ -ENOSYS, /* I40E_AQ_RC_ENOSYS */
+ -ERANGE, /* I40E_AQ_RC_ERANGE */
+ -EPIPE, /* I40E_AQ_RC_EFLUSHED */
+ -ESPIPE, /* I40E_AQ_RC_BAD_ADDR */
+ -EROFS, /* I40E_AQ_RC_EMODE */
+ -EFBIG, /* I40E_AQ_RC_EFBIG */
+ };
+
+ return aq_to_posix[aq_rc];
+}
+
/* general information */
#define I40E_AQ_LARGE_BUF 512
#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 6e65f19dd6e5..df43e7c6777c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -554,7 +554,6 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
break;
default:
return I40E_ERR_DEVICE_NOT_SUPPORTED;
- break;
}
hw->phy.get_link_info = true;
@@ -655,6 +654,31 @@ i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
}
/**
+ * i40e_get_port_mac_addr - get Port MAC address
+ * @hw: pointer to the HW structure
+ * @mac_addr: pointer to Port MAC address
+ *
+ * Reads the adapter's Port MAC address
+ **/
+i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
+{
+ struct i40e_aqc_mac_address_read_data addrs;
+ i40e_status status;
+ u16 flags = 0;
+
+ status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
+ if (status)
+ return status;
+
+ if (flags & I40E_AQC_PORT_ADDR_VALID)
+ memcpy(mac_addr, &addrs.port_mac, sizeof(addrs.port_mac));
+ else
+ status = I40E_ERR_INVALID_MAC_ADDR;
+
+ return status;
+}
+
+/**
* i40e_pre_tx_queue_cfg - pre tx queue configure
* @hw: pointer to the HW structure
* @queue: target pf queue index
@@ -669,8 +693,10 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
u32 reg_block = 0;
u32 reg_val;
- if (abs_queue_idx >= 128)
+ if (abs_queue_idx >= 128) {
reg_block = abs_queue_idx / 128;
+ abs_queue_idx %= 128;
+ }
reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
@@ -683,6 +709,33 @@ void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
}
+#ifdef I40E_FCOE
+
+/**
+ * i40e_get_san_mac_addr - get SAN MAC address
+ * @hw: pointer to the HW structure
+ * @mac_addr: pointer to SAN MAC address
+ *
+ * Reads the adapter's SAN MAC address from NVM
+ **/
+i40e_status i40e_get_san_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
+{
+ struct i40e_aqc_mac_address_read_data addrs;
+ i40e_status status;
+ u16 flags = 0;
+
+ status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
+ if (status)
+ return status;
+
+ if (flags & I40E_AQC_SAN_ADDR_VALID)
+ memcpy(mac_addr, &addrs.pf_san_mac, sizeof(addrs.pf_san_mac));
+ else
+ status = I40E_ERR_INVALID_MAC_ADDR;
+
+ return status;
+}
+#endif
/**
* i40e_get_media_type - Gets media type
@@ -811,6 +864,99 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
}
/**
+ * i40e_clear_hw - clear out any left over hw state
+ * @hw: pointer to the hw struct
+ *
+ * Clear queues and interrupts, typically called at init time,
+ * but after the capabilities have been found so we know how many
+ * queues and msix vectors have been allocated.
+ **/
+void i40e_clear_hw(struct i40e_hw *hw)
+{
+ u32 num_queues, base_queue;
+ u32 num_pf_int;
+ u32 num_vf_int;
+ u32 num_vfs;
+ u32 i, j;
+ u32 val;
+ u32 eol = 0x7ff;
+
+ /* get number of interrupts, queues, and vfs */
+ val = rd32(hw, I40E_GLPCI_CNF2);
+ num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
+ I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
+ num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
+ I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
+
+ val = rd32(hw, I40E_PFLAN_QALLOC);
+ base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
+ I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
+ j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
+ I40E_PFLAN_QALLOC_LASTQ_SHIFT;
+ if (val & I40E_PFLAN_QALLOC_VALID_MASK)
+ num_queues = (j - base_queue) + 1;
+ else
+ num_queues = 0;
+
+ val = rd32(hw, I40E_PF_VT_PFALLOC);
+ i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
+ I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
+ j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
+ I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
+ if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
+ num_vfs = (j - i) + 1;
+ else
+ num_vfs = 0;
+
+ /* stop all the interrupts */
+ wr32(hw, I40E_PFINT_ICR0_ENA, 0);
+ val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
+ for (i = 0; i < num_pf_int - 2; i++)
+ wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
+
+ /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
+ val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
+ wr32(hw, I40E_PFINT_LNKLST0, val);
+ for (i = 0; i < num_pf_int - 2; i++)
+ wr32(hw, I40E_PFINT_LNKLSTN(i), val);
+ val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
+ for (i = 0; i < num_vfs; i++)
+ wr32(hw, I40E_VPINT_LNKLST0(i), val);
+ for (i = 0; i < num_vf_int - 2; i++)
+ wr32(hw, I40E_VPINT_LNKLSTN(i), val);
+
+ /* warn the HW of the coming Tx disables */
+ for (i = 0; i < num_queues; i++) {
+ u32 abs_queue_idx = base_queue + i;
+ u32 reg_block = 0;
+
+ if (abs_queue_idx >= 128) {
+ reg_block = abs_queue_idx / 128;
+ abs_queue_idx %= 128;
+ }
+
+ val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
+ val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
+ val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
+ val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
+
+ wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
+ }
+ udelay(400);
+
+ /* stop all the queues */
+ for (i = 0; i < num_queues; i++) {
+ wr32(hw, I40E_QINT_TQCTL(i), 0);
+ wr32(hw, I40E_QTX_ENA(i), 0);
+ wr32(hw, I40E_QINT_RQCTL(i), 0);
+ wr32(hw, I40E_QRX_ENA(i), 0);
+ }
+
+ /* short wait for all queue disables to settle */
+ udelay(50);
+}
+
+/**
* i40e_clear_pxe_mode - clear pxe operations mode
* @hw: pointer to the hw struct
*
@@ -942,6 +1088,164 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
/* Admin command wrappers */
/**
+ * i40e_aq_get_phy_capabilities
+ * @hw: pointer to the hw struct
+ * @abilities: structure for PHY capabilities to be filled
+ * @qualified_modules: report Qualified Modules
+ * @report_init: report init capabilities (active are default)
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Returns the various PHY abilities supported on the Port.
+ **/
+i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
+ bool qualified_modules, bool report_init,
+ struct i40e_aq_get_phy_abilities_resp *abilities,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ i40e_status status;
+ u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
+
+ if (!abilities)
+ return I40E_ERR_PARAM;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_phy_abilities);
+
+ desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
+ if (abilities_size > I40E_AQ_LARGE_BUF)
+ desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+
+ if (qualified_modules)
+ desc.params.external.param0 |=
+ cpu_to_le32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
+
+ if (report_init)
+ desc.params.external.param0 |=
+ cpu_to_le32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
+
+ status = i40e_asq_send_command(hw, &desc, abilities, abilities_size,
+ cmd_details);
+
+ if (hw->aq.asq_last_status == I40E_AQ_RC_EIO)
+ status = I40E_ERR_UNKNOWN_PHY;
+
+ return status;
+}
+
+/**
+ * i40e_aq_set_phy_config
+ * @hw: pointer to the hw struct
+ * @config: structure with PHY configuration to be set
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Set the various PHY configuration parameters
+ * supported on the Port.One or more of the Set PHY config parameters may be
+ * ignored in an MFP mode as the PF may not have the privilege to set some
+ * of the PHY Config parameters. This status will be indicated by the
+ * command response.
+ **/
+enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
+ struct i40e_aq_set_phy_config *config,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aq_set_phy_config *cmd =
+ (struct i40e_aq_set_phy_config *)&desc.params.raw;
+ enum i40e_status_code status;
+
+ if (!config)
+ return I40E_ERR_PARAM;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_phy_config);
+
+ *cmd = *config;
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
+ * i40e_set_fc
+ * @hw: pointer to the hw struct
+ *
+ * Set the requested flow control mode using set_phy_config.
+ **/
+enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
+ bool atomic_restart)
+{
+ enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_aq_set_phy_config config;
+ enum i40e_status_code status;
+ u8 pause_mask = 0x0;
+
+ *aq_failures = 0x0;
+
+ switch (fc_mode) {
+ case I40E_FC_FULL:
+ pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
+ pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
+ break;
+ case I40E_FC_RX_PAUSE:
+ pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
+ break;
+ case I40E_FC_TX_PAUSE:
+ pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
+ break;
+ default:
+ break;
+ }
+
+ /* Get the current phy config */
+ status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
+ NULL);
+ if (status) {
+ *aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
+ return status;
+ }
+
+ memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
+ /* clear the old pause settings */
+ config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
+ ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
+ /* set the new abilities */
+ config.abilities |= pause_mask;
+ /* If the abilities have changed, then set the new config */
+ if (config.abilities != abilities.abilities) {
+ /* Auto restart link so settings take effect */
+ if (atomic_restart)
+ config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+ /* Copy over all the old settings */
+ config.phy_type = abilities.phy_type;
+ config.link_speed = abilities.link_speed;
+ config.eee_capability = abilities.eee_capability;
+ config.eeer = abilities.eeer_val;
+ config.low_power_ctrl = abilities.d3_lpan;
+ status = i40e_aq_set_phy_config(hw, &config, NULL);
+
+ if (status)
+ *aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
+ }
+ /* Update the link info */
+ status = i40e_update_link_info(hw, true);
+ if (status) {
+ /* Wait a little bit (on 40G cards it sometimes takes a really
+ * long time for link to come back from the atomic reset)
+ * and try once more
+ */
+ msleep(1000);
+ status = i40e_update_link_info(hw, true);
+ }
+ if (status)
+ *aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
+
+ return status;
+}
+
+/**
* i40e_aq_clear_pxe_mode
* @hw: pointer to the hw struct
* @cmd_details: pointer to command details structure or NULL
@@ -971,12 +1275,14 @@ i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
/**
* i40e_aq_set_link_restart_an
* @hw: pointer to the hw struct
+ * @enable_link: if true: enable link, if false: disable link
* @cmd_details: pointer to command details structure or NULL
*
* Sets up the link and restarts the Auto-Negotiation over the link.
**/
i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
- struct i40e_asq_cmd_details *cmd_details)
+ bool enable_link,
+ struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_set_link_restart_an *cmd =
@@ -987,6 +1293,10 @@ i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
i40e_aqc_opc_set_link_restart_an);
cmd->command = I40E_AQ_PHY_RESTART_AN;
+ if (enable_link)
+ cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
+ else
+ cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
@@ -1011,6 +1321,7 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
(struct i40e_aqc_get_link_status *)&desc.params.raw;
struct i40e_link_status *hw_link_info = &hw->phy.link_info;
i40e_status status;
+ bool tx_pause, rx_pause;
u16 command_flags;
i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
@@ -1040,6 +1351,18 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
+ /* update fc info */
+ tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
+ rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
+ if (tx_pause & rx_pause)
+ hw->fc.current_mode = I40E_FC_FULL;
+ else if (tx_pause)
+ hw->fc.current_mode = I40E_FC_TX_PAUSE;
+ else if (rx_pause)
+ hw->fc.current_mode = I40E_FC_RX_PAUSE;
+ else
+ hw->fc.current_mode = I40E_FC_NONE;
+
if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
hw_link_info->crc_enable = true;
else
@@ -1062,6 +1385,35 @@ aq_get_link_info_exit:
}
/**
+ * i40e_update_link_info
+ * @hw: pointer to the hw struct
+ * @enable_lse: enable/disable LinkStatusEvent reporting
+ *
+ * Returns the link status of the adapter
+ **/
+i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse)
+{
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ i40e_status status;
+
+ status = i40e_aq_get_link_info(hw, enable_lse, NULL, NULL);
+ if (status)
+ return status;
+
+ status = i40e_aq_get_phy_capabilities(hw, false, false,
+ &abilities, NULL);
+ if (status)
+ return status;
+
+ if (abilities.abilities & I40E_AQ_PHY_AN_ENABLED)
+ hw->phy.link_info.an_enabled = true;
+ else
+ hw->phy.link_info.an_enabled = false;
+
+ return status;
+}
+
+/**
* i40e_aq_add_vsi
* @hw: pointer to the hw struct
* @vsi_ctx: pointer to a vsi context struct
@@ -1650,6 +2002,35 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
}
/**
+ * i40e_aq_debug_write_register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Write to a register using the admin queue commands
+ **/
+i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
+ u32 reg_addr, u64 reg_val,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_debug_reg_read_write *cmd =
+ (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
+ i40e_status status;
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
+
+ cmd->address = cpu_to_le32(reg_addr);
+ cmd->value_high = cpu_to_le32((u32)(reg_val >> 32));
+ cmd->value_low = cpu_to_le32((u32)(reg_val & 0xFFFFFFFF));
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
* i40e_aq_set_hmc_resource_profile
* @hw: pointer to the hw struct
* @profile: type of profile the HMC is to be set as
@@ -1796,6 +2177,47 @@ i40e_aq_read_nvm_exit:
return status;
}
+/**
+ * i40e_aq_erase_nvm
+ * @hw: pointer to the hw struct
+ * @module_pointer: module pointer location in words from the NVM beginning
+ * @offset: offset in the module (expressed in 4 KB from module's beginning)
+ * @length: length of the section to be erased (expressed in 4 KB)
+ * @last_command: tells if this is the last command in a series
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Erase the NVM sector using the admin queue commands
+ **/
+i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
+ u32 offset, u16 length, bool last_command,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_nvm_update *cmd =
+ (struct i40e_aqc_nvm_update *)&desc.params.raw;
+ i40e_status status;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000) {
+ status = I40E_ERR_PARAM;
+ goto i40e_aq_erase_nvm_exit;
+ }
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
+
+ /* If this is the last command in a series, set the proper flag. */
+ if (last_command)
+ cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
+ cmd->module_pointer = module_pointer;
+ cmd->offset = cpu_to_le32(offset);
+ cmd->length = cpu_to_le16(length);
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+i40e_aq_erase_nvm_exit:
+ return status;
+}
+
#define I40E_DEV_FUNC_CAP_SWITCH_MODE 0x01
#define I40E_DEV_FUNC_CAP_MGMT_MODE 0x02
#define I40E_DEV_FUNC_CAP_NPAR 0x03
@@ -1839,7 +2261,6 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
struct i40e_aqc_list_capabilities_element_resp *cap;
u32 number, logical_id, phys_id;
struct i40e_hw_capabilities *p;
- u32 reg_val;
u32 i = 0;
u16 id;
@@ -1910,11 +2331,7 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
break;
case I40E_DEV_FUNC_CAP_RSS:
p->rss = true;
- reg_val = rd32(hw, I40E_PFQF_CTL_0);
- if (reg_val & I40E_PFQF_CTL_0_HASHLUTSIZE_MASK)
- p->rss_table_size = number;
- else
- p->rss_table_size = 128;
+ p->rss_table_size = number;
p->rss_table_entry_width = logical_id;
break;
case I40E_DEV_FUNC_CAP_RX_QUEUES:
@@ -2031,6 +2448,53 @@ exit:
}
/**
+ * i40e_aq_update_nvm
+ * @hw: pointer to the hw struct
+ * @module_pointer: module pointer location in words from the NVM beginning
+ * @offset: byte offset from the module beginning
+ * @length: length of the section to be written (in bytes from the offset)
+ * @data: command buffer (size [bytes] = length)
+ * @last_command: tells if this is the last command in a series
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Update the NVM using the admin queue commands
+ **/
+i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
+ u32 offset, u16 length, void *data,
+ bool last_command,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_nvm_update *cmd =
+ (struct i40e_aqc_nvm_update *)&desc.params.raw;
+ i40e_status status;
+
+ /* In offset the highest byte must be zeroed. */
+ if (offset & 0xFF000000) {
+ status = I40E_ERR_PARAM;
+ goto i40e_aq_update_nvm_exit;
+ }
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
+
+ /* If this is the last command in a series, set the proper flag. */
+ if (last_command)
+ cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
+ cmd->module_pointer = module_pointer;
+ cmd->offset = cpu_to_le32(offset);
+ cmd->length = cpu_to_le16(length);
+
+ desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
+ if (length > I40E_AQ_LARGE_BUF)
+ desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+
+ status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
+
+i40e_aq_update_nvm_exit:
+ return status;
+}
+
+/**
* i40e_aq_get_lldp_mib
* @hw: pointer to the hw struct
* @bridge_type: type of bridge requested
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index cffdfc21290f..5a0cabeb35ed 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -697,6 +697,25 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
vsi->bw_ets_limit_credits[i],
vsi->bw_ets_max_quanta[i]);
}
+#ifdef I40E_FCOE
+ if (vsi->type == I40E_VSI_FCOE) {
+ dev_info(&pf->pdev->dev,
+ " fcoe_stats: rx_packets = %llu, rx_dwords = %llu, rx_dropped = %llu\n",
+ vsi->fcoe_stats.rx_fcoe_packets,
+ vsi->fcoe_stats.rx_fcoe_dwords,
+ vsi->fcoe_stats.rx_fcoe_dropped);
+ dev_info(&pf->pdev->dev,
+ " fcoe_stats: tx_packets = %llu, tx_dwords = %llu\n",
+ vsi->fcoe_stats.tx_fcoe_packets,
+ vsi->fcoe_stats.tx_fcoe_dwords);
+ dev_info(&pf->pdev->dev,
+ " fcoe_stats: bad_crc = %llu, last_error = %llu\n",
+ vsi->fcoe_stats.fcoe_bad_fccrc,
+ vsi->fcoe_stats.fcoe_last_error);
+ dev_info(&pf->pdev->dev, " fcoe_stats: ddp_count = %llu\n",
+ vsi->fcoe_stats.fcoe_ddp_count);
+ }
+#endif
}
/**
@@ -1238,7 +1257,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
} else if (strncmp(cmd_buf, "add pvid", 8) == 0) {
i40e_status ret;
u16 vid;
- int v;
+ unsigned int v;
cnt = sscanf(&cmd_buf[8], "%i %u", &vsi_seid, &v);
if (cnt != 2) {
@@ -1254,7 +1273,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
goto command_write_done;
}
- vid = (unsigned)v;
+ vid = v;
ret = i40e_vsi_add_pvid(vsi, vid);
if (!ret)
dev_info(&pf->pdev->dev,
@@ -1743,6 +1762,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_ATR_ENABLED, false);
} else if (strncmp(cmd_buf, "fd-atr on", 9) == 0) {
i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_ATR_ENABLED, true);
+ } else if (strncmp(cmd_buf, "fd current cnt", 14) == 0) {
+ dev_info(&pf->pdev->dev, "FD current total filter count for this interface: %d\n",
+ i40e_get_current_fd_count(pf));
} else if (strncmp(cmd_buf, "lldp", 4) == 0) {
if (strncmp(&cmd_buf[5], "stop", 4) == 0) {
int ret;
@@ -1830,7 +1852,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
ret = i40e_aq_get_lldp_mib(&pf->hw,
I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
- I40E_AQ_LLDP_MIB_LOCAL,
+ I40E_AQ_LLDP_MIB_REMOTE,
buff, I40E_LLDPDU_SIZE,
&llen, &rlen, NULL);
if (ret) {
@@ -1962,6 +1984,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, " rem fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n");
dev_info(&pf->pdev->dev, " fd-atr off\n");
dev_info(&pf->pdev->dev, " fd-atr on\n");
+ dev_info(&pf->pdev->dev, " fd current cnt");
dev_info(&pf->pdev->dev, " lldp start\n");
dev_info(&pf->pdev->dev, " lldp stop\n");
dev_info(&pf->pdev->dev, " lldp get local\n");
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 4a488ffcd6b0..e8ba7470700a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -155,6 +155,19 @@ static struct i40e_stats i40e_gstrings_stats[] = {
I40E_PF_STAT("rx_lpi_count", stats.rx_lpi_count),
};
+#ifdef I40E_FCOE
+static const struct i40e_stats i40e_gstrings_fcoe_stats[] = {
+ I40E_VSI_STAT("fcoe_bad_fccrc", fcoe_stats.fcoe_bad_fccrc),
+ I40E_VSI_STAT("rx_fcoe_dropped", fcoe_stats.rx_fcoe_dropped),
+ I40E_VSI_STAT("rx_fcoe_packets", fcoe_stats.rx_fcoe_packets),
+ I40E_VSI_STAT("rx_fcoe_dwords", fcoe_stats.rx_fcoe_dwords),
+ I40E_VSI_STAT("fcoe_ddp_count", fcoe_stats.fcoe_ddp_count),
+ I40E_VSI_STAT("fcoe_last_error", fcoe_stats.fcoe_last_error),
+ I40E_VSI_STAT("tx_fcoe_packets", fcoe_stats.tx_fcoe_packets),
+ I40E_VSI_STAT("tx_fcoe_dwords", fcoe_stats.tx_fcoe_dwords),
+};
+
+#endif /* I40E_FCOE */
#define I40E_QUEUE_STATS_LEN(n) \
(((struct i40e_netdev_priv *)netdev_priv((n)))->vsi->num_queue_pairs \
* 2 /* Tx and Rx together */ \
@@ -162,9 +175,17 @@ static struct i40e_stats i40e_gstrings_stats[] = {
#define I40E_GLOBAL_STATS_LEN ARRAY_SIZE(i40e_gstrings_stats)
#define I40E_NETDEV_STATS_LEN ARRAY_SIZE(i40e_gstrings_net_stats)
#define I40E_MISC_STATS_LEN ARRAY_SIZE(i40e_gstrings_misc_stats)
+#ifdef I40E_FCOE
+#define I40E_FCOE_STATS_LEN ARRAY_SIZE(i40e_gstrings_fcoe_stats)
+#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
+ I40E_FCOE_STATS_LEN + \
+ I40E_MISC_STATS_LEN + \
+ I40E_QUEUE_STATS_LEN((n)))
+#else
#define I40E_VSI_STATS_LEN(n) (I40E_NETDEV_STATS_LEN + \
I40E_MISC_STATS_LEN + \
I40E_QUEUE_STATS_LEN((n)))
+#endif /* I40E_FCOE */
#define I40E_PFC_STATS_LEN ( \
(FIELD_SIZEOF(struct i40e_pf, stats.priority_xoff_rx) + \
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_rx) + \
@@ -215,52 +236,135 @@ static int i40e_get_settings(struct net_device *netdev,
/* hardware is either in 40G mode or 10G mode
* NOTE: this section initializes supported and advertising
*/
+ if (!link_up) {
+ /* link is down and the driver needs to fall back on
+ * device ID to determine what kinds of info to display,
+ * it's mostly a guess that may change when link is up
+ */
+ switch (hw->device_id) {
+ case I40E_DEV_ID_QSFP_A:
+ case I40E_DEV_ID_QSFP_B:
+ case I40E_DEV_ID_QSFP_C:
+ /* pluggable QSFP */
+ ecmd->supported = SUPPORTED_40000baseSR4_Full |
+ SUPPORTED_40000baseCR4_Full |
+ SUPPORTED_40000baseLR4_Full;
+ ecmd->advertising = ADVERTISED_40000baseSR4_Full |
+ ADVERTISED_40000baseCR4_Full |
+ ADVERTISED_40000baseLR4_Full;
+ break;
+ case I40E_DEV_ID_KX_B:
+ /* backplane 40G */
+ ecmd->supported = SUPPORTED_40000baseKR4_Full;
+ ecmd->advertising = ADVERTISED_40000baseKR4_Full;
+ break;
+ case I40E_DEV_ID_KX_C:
+ /* backplane 10G */
+ ecmd->supported = SUPPORTED_10000baseKR_Full;
+ ecmd->advertising = ADVERTISED_10000baseKR_Full;
+ break;
+ default:
+ /* all the rest are 10G/1G */
+ ecmd->supported = SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full;
+ ecmd->advertising = ADVERTISED_10000baseT_Full |
+ ADVERTISED_1000baseT_Full;
+ break;
+ }
+
+ /* skip phy_type use as it is zero when link is down */
+ goto no_valid_phy_type;
+ }
+
switch (hw_link_info->phy_type) {
case I40E_PHY_TYPE_40GBASE_CR4:
case I40E_PHY_TYPE_40GBASE_CR4_CU:
- ecmd->supported = SUPPORTED_40000baseCR4_Full;
- ecmd->advertising = ADVERTISED_40000baseCR4_Full;
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_40000baseCR4_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_40000baseCR4_Full;
break;
case I40E_PHY_TYPE_40GBASE_KR4:
- ecmd->supported = SUPPORTED_40000baseKR4_Full;
- ecmd->advertising = ADVERTISED_40000baseKR4_Full;
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_40000baseKR4_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_40000baseKR4_Full;
break;
case I40E_PHY_TYPE_40GBASE_SR4:
+ case I40E_PHY_TYPE_XLPPI:
+ case I40E_PHY_TYPE_XLAUI:
ecmd->supported = SUPPORTED_40000baseSR4_Full;
- ecmd->advertising = ADVERTISED_40000baseSR4_Full;
break;
case I40E_PHY_TYPE_40GBASE_LR4:
ecmd->supported = SUPPORTED_40000baseLR4_Full;
- ecmd->advertising = ADVERTISED_40000baseLR4_Full;
break;
case I40E_PHY_TYPE_10GBASE_KX4:
- ecmd->supported = SUPPORTED_10000baseKX4_Full;
- ecmd->advertising = ADVERTISED_10000baseKX4_Full;
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_10000baseKX4_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_10000baseKX4_Full;
break;
case I40E_PHY_TYPE_10GBASE_KR:
- ecmd->supported = SUPPORTED_10000baseKR_Full;
- ecmd->advertising = ADVERTISED_10000baseKR_Full;
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_10000baseKR_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_10000baseKR_Full;
break;
- default:
- if (i40e_is_40G_device(hw->device_id)) {
- ecmd->supported = SUPPORTED_40000baseSR4_Full;
- ecmd->advertising = ADVERTISED_40000baseSR4_Full;
- } else {
- ecmd->supported = SUPPORTED_10000baseT_Full;
- ecmd->advertising = ADVERTISED_10000baseT_Full;
- }
+ case I40E_PHY_TYPE_10GBASE_SR:
+ case I40E_PHY_TYPE_10GBASE_LR:
+ ecmd->supported = SUPPORTED_10000baseT_Full;
+ break;
+ case I40E_PHY_TYPE_10GBASE_CR1_CU:
+ case I40E_PHY_TYPE_10GBASE_CR1:
+ case I40E_PHY_TYPE_10GBASE_T:
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_10000baseT_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_10000baseT_Full;
+ break;
+ case I40E_PHY_TYPE_XAUI:
+ case I40E_PHY_TYPE_XFI:
+ case I40E_PHY_TYPE_SFI:
+ case I40E_PHY_TYPE_10GBASE_SFPP_CU:
+ ecmd->supported = SUPPORTED_10000baseT_Full;
break;
+ case I40E_PHY_TYPE_1000BASE_KX:
+ case I40E_PHY_TYPE_1000BASE_T:
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_1000baseT_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_1000baseT_Full;
+ break;
+ case I40E_PHY_TYPE_100BASE_TX:
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_100baseT_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_100baseT_Full;
+ break;
+ case I40E_PHY_TYPE_SGMII:
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_100baseT_Full;
+ ecmd->advertising = ADVERTISED_Autoneg |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_100baseT_Full;
+ break;
+ default:
+ /* if we got here and link is up something bad is afoot */
+ WARN_ON(link_up);
}
- ecmd->supported |= SUPPORTED_Autoneg;
- ecmd->advertising |= ADVERTISED_Autoneg;
+no_valid_phy_type:
+ /* this is if autoneg is enabled or disabled */
ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
AUTONEG_ENABLE : AUTONEG_DISABLE);
switch (hw->phy.media_type) {
case I40E_MEDIA_TYPE_BACKPLANE:
- ecmd->supported |= SUPPORTED_Backplane;
- ecmd->advertising |= ADVERTISED_Backplane;
+ ecmd->supported |= SUPPORTED_Autoneg |
+ SUPPORTED_Backplane;
+ ecmd->advertising |= ADVERTISED_Autoneg |
+ ADVERTISED_Backplane;
ecmd->port = PORT_NONE;
break;
case I40E_MEDIA_TYPE_BASET:
@@ -276,7 +380,6 @@ static int i40e_get_settings(struct net_device *netdev,
break;
case I40E_MEDIA_TYPE_FIBER:
ecmd->supported |= SUPPORTED_FIBRE;
- ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_FIBRE;
break;
case I40E_MEDIA_TYPE_UNKNOWN:
@@ -287,6 +390,25 @@ static int i40e_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
+ ecmd->supported |= SUPPORTED_Pause;
+
+ switch (hw->fc.current_mode) {
+ case I40E_FC_FULL:
+ ecmd->advertising |= ADVERTISED_Pause;
+ break;
+ case I40E_FC_TX_PAUSE:
+ ecmd->advertising |= ADVERTISED_Asym_Pause;
+ break;
+ case I40E_FC_RX_PAUSE:
+ ecmd->advertising |= (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ default:
+ ecmd->advertising &= ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ break;
+ }
+
if (link_up) {
switch (link_speed) {
case I40E_LINK_SPEED_40GB:
@@ -296,6 +418,9 @@ static int i40e_get_settings(struct net_device *netdev,
case I40E_LINK_SPEED_10GB:
ethtool_cmd_speed_set(ecmd, SPEED_10000);
break;
+ case I40E_LINK_SPEED_1GB:
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
+ break;
default:
break;
}
@@ -309,6 +434,182 @@ static int i40e_get_settings(struct net_device *netdev,
}
/**
+ * i40e_set_settings - Set Speed and Duplex
+ * @netdev: network interface device structure
+ * @ecmd: ethtool command
+ *
+ * Set speed/duplex per media_types advertised/forced
+ **/
+static int i40e_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_aq_set_phy_config config;
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_hw *hw = &pf->hw;
+ struct ethtool_cmd safe_ecmd;
+ i40e_status status = 0;
+ bool change = false;
+ int err = 0;
+ u8 autoneg;
+ u32 advertise;
+
+ if (vsi != pf->vsi[pf->lan_vsi])
+ return -EOPNOTSUPP;
+
+ if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
+ hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
+ hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE)
+ return -EOPNOTSUPP;
+
+ /* get our own copy of the bits to check against */
+ memset(&safe_ecmd, 0, sizeof(struct ethtool_cmd));
+ i40e_get_settings(netdev, &safe_ecmd);
+
+ /* save autoneg and speed out of ecmd */
+ autoneg = ecmd->autoneg;
+ advertise = ecmd->advertising;
+
+ /* set autoneg and speed back to what they currently are */
+ ecmd->autoneg = safe_ecmd.autoneg;
+ ecmd->advertising = safe_ecmd.advertising;
+
+ ecmd->cmd = safe_ecmd.cmd;
+ /* If ecmd and safe_ecmd are not the same now, then they are
+ * trying to set something that we do not support
+ */
+ if (memcmp(ecmd, &safe_ecmd, sizeof(struct ethtool_cmd)))
+ return -EOPNOTSUPP;
+
+ while (test_bit(__I40E_CONFIG_BUSY, &vsi->state))
+ usleep_range(1000, 2000);
+
+ /* Get the current phy config */
+ status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
+ NULL);
+ if (status)
+ return -EAGAIN;
+
+ /* Copy link_speed and abilities to config in case they are not
+ * set below
+ */
+ memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
+ config.link_speed = abilities.link_speed;
+ config.abilities = abilities.abilities;
+
+ /* Check autoneg */
+ if (autoneg == AUTONEG_ENABLE) {
+ /* If autoneg is not supported, return error */
+ if (!(safe_ecmd.supported & SUPPORTED_Autoneg)) {
+ netdev_info(netdev, "Autoneg not supported on this phy\n");
+ return -EINVAL;
+ }
+ /* If autoneg was not already enabled */
+ if (!(hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED)) {
+ config.abilities = abilities.abilities |
+ I40E_AQ_PHY_ENABLE_AN;
+ change = true;
+ }
+ } else {
+ /* If autoneg is supported 10GBASE_T is the only phy that
+ * can disable it, so otherwise return error
+ */
+ if (safe_ecmd.supported & SUPPORTED_Autoneg &&
+ hw->phy.link_info.phy_type != I40E_PHY_TYPE_10GBASE_T) {
+ netdev_info(netdev, "Autoneg cannot be disabled on this phy\n");
+ return -EINVAL;
+ }
+ /* If autoneg is currently enabled */
+ if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
+ config.abilities = abilities.abilities |
+ ~I40E_AQ_PHY_ENABLE_AN;
+ change = true;
+ }
+ }
+
+ if (advertise & ~safe_ecmd.supported)
+ return -EINVAL;
+
+ if (advertise & ADVERTISED_100baseT_Full)
+ if (!(abilities.link_speed & I40E_LINK_SPEED_100MB)) {
+ config.link_speed |= I40E_LINK_SPEED_100MB;
+ change = true;
+ }
+ if (advertise & ADVERTISED_1000baseT_Full ||
+ advertise & ADVERTISED_1000baseKX_Full)
+ if (!(abilities.link_speed & I40E_LINK_SPEED_1GB)) {
+ config.link_speed |= I40E_LINK_SPEED_1GB;
+ change = true;
+ }
+ if (advertise & ADVERTISED_10000baseT_Full ||
+ advertise & ADVERTISED_10000baseKX4_Full ||
+ advertise & ADVERTISED_10000baseKR_Full)
+ if (!(abilities.link_speed & I40E_LINK_SPEED_10GB)) {
+ config.link_speed |= I40E_LINK_SPEED_10GB;
+ change = true;
+ }
+ if (advertise & ADVERTISED_40000baseKR4_Full ||
+ advertise & ADVERTISED_40000baseCR4_Full ||
+ advertise & ADVERTISED_40000baseSR4_Full ||
+ advertise & ADVERTISED_40000baseLR4_Full)
+ if (!(abilities.link_speed & I40E_LINK_SPEED_40GB)) {
+ config.link_speed |= I40E_LINK_SPEED_40GB;
+ change = true;
+ }
+
+ if (change) {
+ /* copy over the rest of the abilities */
+ config.phy_type = abilities.phy_type;
+ config.eee_capability = abilities.eee_capability;
+ config.eeer = abilities.eeer_val;
+ config.low_power_ctrl = abilities.d3_lpan;
+
+ /* If link is up set link and an so changes take effect */
+ if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
+ config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
+
+ /* make the aq call */
+ status = i40e_aq_set_phy_config(hw, &config, NULL);
+ if (status) {
+ netdev_info(netdev, "Set phy config failed with error %d.\n",
+ status);
+ return -EAGAIN;
+ }
+
+ status = i40e_update_link_info(hw, true);
+ if (status)
+ netdev_info(netdev, "Updating link info failed with error %d\n",
+ status);
+
+ } else {
+ netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");
+ }
+
+ return err;
+}
+
+static int i40e_nway_reset(struct net_device *netdev)
+{
+ /* restart autonegotiation */
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ bool link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
+ i40e_status ret = 0;
+
+ ret = i40e_aq_set_link_restart_an(hw, link_up, NULL);
+ if (ret) {
+ netdev_info(netdev, "link restart failed, aq_err=%d\n",
+ pf->hw.aq.asq_last_status);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
* i40e_get_pauseparam - Get Flow Control status
* Return tx/rx-pause status
**/
@@ -334,6 +635,85 @@ static void i40e_get_pauseparam(struct net_device *netdev,
}
}
+/**
+ * i40e_set_pauseparam - Set Flow Control parameter
+ * @netdev: network interface device structure
+ * @pause: return tx/rx flow control status
+ **/
+static int i40e_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_hw *hw = &pf->hw;
+ struct i40e_link_status *hw_link_info = &hw->phy.link_info;
+ bool link_up = hw_link_info->link_info & I40E_AQ_LINK_UP;
+ i40e_status status;
+ u8 aq_failures;
+ int err = 0;
+
+ if (vsi != pf->vsi[pf->lan_vsi])
+ return -EOPNOTSUPP;
+
+ if (pause->autoneg != ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE)) {
+ netdev_info(netdev, "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
+ return -EOPNOTSUPP;
+ }
+
+ /* If we have link and don't have autoneg */
+ if (!test_bit(__I40E_DOWN, &pf->state) &&
+ !(hw_link_info->an_info & I40E_AQ_AN_COMPLETED)) {
+ /* Send message that it might not necessarily work*/
+ netdev_info(netdev, "Autoneg did not complete so changing settings may not result in an actual change.\n");
+ }
+
+ if (hw->fc.current_mode == I40E_FC_PFC) {
+ netdev_info(netdev, "Priority flow control enabled. Cannot set link flow control.\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (pause->rx_pause && pause->tx_pause)
+ hw->fc.requested_mode = I40E_FC_FULL;
+ else if (pause->rx_pause && !pause->tx_pause)
+ hw->fc.requested_mode = I40E_FC_RX_PAUSE;
+ else if (!pause->rx_pause && pause->tx_pause)
+ hw->fc.requested_mode = I40E_FC_TX_PAUSE;
+ else if (!pause->rx_pause && !pause->tx_pause)
+ hw->fc.requested_mode = I40E_FC_NONE;
+ else
+ return -EINVAL;
+
+ /* Set the fc mode and only restart an if link is up*/
+ status = i40e_set_fc(hw, &aq_failures, link_up);
+
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_GET) {
+ netdev_info(netdev, "Set fc failed on the get_phy_capabilities call with error %d and status %d\n",
+ status, hw->aq.asq_last_status);
+ err = -EAGAIN;
+ }
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_SET) {
+ netdev_info(netdev, "Set fc failed on the set_phy_config call with error %d and status %d\n",
+ status, hw->aq.asq_last_status);
+ err = -EAGAIN;
+ }
+ if (aq_failures & I40E_SET_FC_AQ_FAIL_UPDATE) {
+ netdev_info(netdev, "Set fc failed on the update_link_info call with error %d and status %d\n",
+ status, hw->aq.asq_last_status);
+ err = -EAGAIN;
+ }
+
+ if (!test_bit(__I40E_DOWN, &pf->state)) {
+ /* Give it a little more time to try to come back */
+ msleep(75);
+ if (!test_bit(__I40E_DOWN, &pf->state))
+ return i40e_nway_reset(netdev);
+ }
+
+ return err;
+}
+
static u32 i40e_get_msglevel(struct net_device *netdev)
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
@@ -404,10 +784,33 @@ static int i40e_get_eeprom(struct net_device *netdev,
u8 *eeprom_buff;
u16 i, sectors;
bool last;
+ u32 magic;
+
#define I40E_NVM_SECTOR_SIZE 4096
if (eeprom->len == 0)
return -EINVAL;
+ /* check for NVMUpdate access method */
+ magic = hw->vendor_id | (hw->device_id << 16);
+ if (eeprom->magic && eeprom->magic != magic) {
+ int errno;
+
+ /* make sure it is the right magic for NVMUpdate */
+ if ((eeprom->magic >> 16) != hw->device_id)
+ return -EINVAL;
+
+ ret_val = i40e_nvmupd_command(hw,
+ (struct i40e_nvm_access *)eeprom,
+ bytes, &errno);
+ if (ret_val)
+ dev_info(&pf->pdev->dev,
+ "NVMUpdate read failed err=%d status=0x%x\n",
+ ret_val, hw->aq.asq_last_status);
+
+ return errno;
+ }
+
+ /* normal ethtool get_eeprom support */
eeprom->magic = hw->vendor_id | (hw->device_id << 16);
eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
@@ -434,7 +837,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
ret_val = i40e_aq_read_nvm(hw, 0x0,
eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
len,
- eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
+ (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
last, NULL);
if (ret_val) {
dev_info(&pf->pdev->dev,
@@ -446,7 +849,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
release_nvm:
i40e_release_nvm(hw);
- memcpy(bytes, eeprom_buff, eeprom->len);
+ memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
free_buff:
kfree(eeprom_buff);
return ret_val;
@@ -466,6 +869,39 @@ static int i40e_get_eeprom_len(struct net_device *netdev)
return val;
}
+static int i40e_set_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_hw *hw = &np->vsi->back->hw;
+ struct i40e_pf *pf = np->vsi->back;
+ int ret_val = 0;
+ int errno;
+ u32 magic;
+
+ /* normal ethtool set_eeprom is not supported */
+ magic = hw->vendor_id | (hw->device_id << 16);
+ if (eeprom->magic == magic)
+ return -EOPNOTSUPP;
+
+ /* check for NVMUpdate access method */
+ if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
+ return -EINVAL;
+
+ if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
+ test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
+ return -EBUSY;
+
+ ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
+ bytes, &errno);
+ if (ret_val)
+ dev_info(&pf->pdev->dev,
+ "NVMUpdate write failed err=%d status=0x%x\n",
+ ret_val, hw->aq.asq_last_status);
+
+ return errno;
+}
+
static void i40e_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
@@ -697,6 +1133,13 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
data[i++] = (i40e_gstrings_misc_stats[j].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
+#ifdef I40E_FCOE
+ for (j = 0; j < I40E_FCOE_STATS_LEN; j++) {
+ p = (char *)vsi + i40e_gstrings_fcoe_stats[j].stat_offset;
+ data[i++] = (i40e_gstrings_fcoe_stats[j].sizeof_stat ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ }
+#endif
rcu_read_lock();
for (j = 0; j < vsi->num_queue_pairs; j++) {
tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
@@ -778,6 +1221,13 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
i40e_gstrings_misc_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
+#ifdef I40E_FCOE
+ for (i = 0; i < I40E_FCOE_STATS_LEN; i++) {
+ snprintf(p, ETH_GSTRING_LEN, "%s",
+ i40e_gstrings_fcoe_stats[i].stat_string);
+ p += ETH_GSTRING_LEN;
+ }
+#endif
for (i = 0; i < vsi->num_queue_pairs; i++) {
snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i);
p += ETH_GSTRING_LEN;
@@ -1021,24 +1471,6 @@ static int i40e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-static int i40e_nway_reset(struct net_device *netdev)
-{
- /* restart autonegotiation */
- struct i40e_netdev_priv *np = netdev_priv(netdev);
- struct i40e_pf *pf = np->vsi->back;
- struct i40e_hw *hw = &pf->hw;
- i40e_status ret = 0;
-
- ret = i40e_aq_set_link_restart_an(hw, NULL);
- if (ret) {
- netdev_info(netdev, "link restart failed, aq_err=%d\n",
- pf->hw.aq.asq_last_status);
- return -EIO;
- }
-
- return 0;
-}
-
static int i40e_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state)
{
@@ -1105,17 +1537,36 @@ static int i40e_set_coalesce(struct net_device *netdev,
if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
vsi->work_limit = ec->tx_max_coalesced_frames_irq;
+ vector = vsi->base_vector;
if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
- (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
+ (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
vsi->rx_itr_setting = ec->rx_coalesce_usecs;
- else
+ } else if (ec->rx_coalesce_usecs == 0) {
+ vsi->rx_itr_setting = ec->rx_coalesce_usecs;
+ i40e_irq_dynamic_disable(vsi, vector);
+ if (ec->use_adaptive_rx_coalesce)
+ netif_info(pf, drv, netdev,
+ "Rx-secs=0, need to disable adaptive-Rx for a complete disable\n");
+ } else {
+ netif_info(pf, drv, netdev,
+ "Invalid value, Rx-usecs range is 0, 8-8160\n");
return -EINVAL;
+ }
if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) &&
- (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1)))
+ (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1))) {
vsi->tx_itr_setting = ec->tx_coalesce_usecs;
- else
+ } else if (ec->tx_coalesce_usecs == 0) {
+ vsi->tx_itr_setting = ec->tx_coalesce_usecs;
+ i40e_irq_dynamic_disable(vsi, vector);
+ if (ec->use_adaptive_tx_coalesce)
+ netif_info(pf, drv, netdev,
+ "Tx-secs=0, need to disable adaptive-Tx for a complete disable\n");
+ } else {
+ netif_info(pf, drv, netdev,
+ "Invalid value, Tx-usecs range is 0, 8-8160\n");
return -EINVAL;
+ }
if (ec->use_adaptive_rx_coalesce)
vsi->rx_itr_setting |= I40E_ITR_DYNAMIC;
@@ -1127,7 +1578,6 @@ static int i40e_set_coalesce(struct net_device *netdev,
else
vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC;
- vector = vsi->base_vector;
for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
q_vector = vsi->q_vectors[i];
q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
@@ -1498,7 +1948,7 @@ static int i40e_update_ethtool_fdir_entry(struct i40e_vsi *vsi,
/* add filter to the list */
if (parent)
- hlist_add_after(&parent->fdir_node, &input->fdir_node);
+ hlist_add_behind(&input->fdir_node, &parent->fdir_node);
else
hlist_add_head(&input->fdir_node,
&pf->fdir_filter_list);
@@ -1731,6 +2181,7 @@ static int i40e_set_channels(struct net_device *dev,
static const struct ethtool_ops i40e_ethtool_ops = {
.get_settings = i40e_get_settings,
+ .set_settings = i40e_set_settings,
.get_drvinfo = i40e_get_drvinfo,
.get_regs_len = i40e_get_regs_len,
.get_regs = i40e_get_regs,
@@ -1738,11 +2189,13 @@ static const struct ethtool_ops i40e_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_wol = i40e_get_wol,
.set_wol = i40e_set_wol,
+ .set_eeprom = i40e_set_eeprom,
.get_eeprom_len = i40e_get_eeprom_len,
.get_eeprom = i40e_get_eeprom,
.get_ringparam = i40e_get_ringparam,
.set_ringparam = i40e_set_ringparam,
.get_pauseparam = i40e_get_pauseparam,
+ .set_pauseparam = i40e_set_pauseparam,
.get_msglevel = i40e_get_msglevel,
.set_msglevel = i40e_set_msglevel,
.get_rxnfc = i40e_get_rxnfc,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.c b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
new file mode 100644
index 000000000000..6938fc1ad877
--- /dev/null
+++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.c
@@ -0,0 +1,1561 @@
+/*******************************************************************************
+ *
+ * Intel Ethernet Controller XL710 Family Linux Driver
+ * Copyright(c) 2013 - 2014 Intel 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.
+ *
+ * This program is distributed in the hope 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 full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ ******************************************************************************/
+
+
+#include <linux/if_ether.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fip.h>
+#include <scsi/fc/fc_fcoe.h>
+#include <scsi/libfc.h>
+#include <scsi/libfcoe.h>
+
+#include "i40e.h"
+#include "i40e_fcoe.h"
+
+/**
+ * i40e_rx_is_fip - returns true if the rx packet type is FIP
+ * @ptype: the packet type field from rx descriptor write-back
+ **/
+static inline bool i40e_rx_is_fip(u16 ptype)
+{
+ return ptype == I40E_RX_PTYPE_L2_FIP_PAY2;
+}
+
+/**
+ * i40e_rx_is_fcoe - returns true if the rx packet type is FCoE
+ * @ptype: the packet type field from rx descriptor write-back
+ **/
+static inline bool i40e_rx_is_fcoe(u16 ptype)
+{
+ return (ptype >= I40E_RX_PTYPE_L2_FCOE_PAY3) &&
+ (ptype <= I40E_RX_PTYPE_L2_FCOE_VFT_FCOTHER);
+}
+
+/**
+ * i40e_fcoe_sof_is_class2 - returns true if this is a FC Class 2 SOF
+ * @sof: the FCoE start of frame delimiter
+ **/
+static inline bool i40e_fcoe_sof_is_class2(u8 sof)
+{
+ return (sof == FC_SOF_I2) || (sof == FC_SOF_N2);
+}
+
+/**
+ * i40e_fcoe_sof_is_class3 - returns true if this is a FC Class 3 SOF
+ * @sof: the FCoE start of frame delimiter
+ **/
+static inline bool i40e_fcoe_sof_is_class3(u8 sof)
+{
+ return (sof == FC_SOF_I3) || (sof == FC_SOF_N3);
+}
+
+/**
+ * i40e_fcoe_sof_is_supported - returns true if the FC SOF is supported by HW
+ * @sof: the input SOF value from the frame
+ **/
+static inline bool i40e_fcoe_sof_is_supported(u8 sof)
+{
+ return i40e_fcoe_sof_is_class2(sof) ||
+ i40e_fcoe_sof_is_class3(sof);
+}
+
+/**
+ * i40e_fcoe_fc_sof - pull the SOF from FCoE header in the frame
+ * @skb: the frame whose EOF is to be pulled from
+ **/
+static inline int i40e_fcoe_fc_sof(struct sk_buff *skb, u8 *sof)
+{
+ *sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
+
+ if (!i40e_fcoe_sof_is_supported(*sof))
+ return -EINVAL;
+ return 0;
+}
+
+/**
+ * i40e_fcoe_eof_is_supported - returns true if the EOF is supported by HW
+ * @eof: the input EOF value from the frame
+ **/
+static inline bool i40e_fcoe_eof_is_supported(u8 eof)
+{
+ return (eof == FC_EOF_N) || (eof == FC_EOF_T) ||
+ (eof == FC_EOF_NI) || (eof == FC_EOF_A);
+}
+
+/**
+ * i40e_fcoe_fc_eof - pull EOF from FCoE trailer in the frame
+ * @skb: the frame whose EOF is to be pulled from
+ **/
+static inline int i40e_fcoe_fc_eof(struct sk_buff *skb, u8 *eof)
+{
+ /* the first byte of the last dword is EOF */
+ skb_copy_bits(skb, skb->len - 4, eof, 1);
+
+ if (!i40e_fcoe_eof_is_supported(*eof))
+ return -EINVAL;
+ return 0;
+}
+
+/**
+ * i40e_fcoe_ctxt_eof - convert input FC EOF for descriptor programming
+ * @eof: the input eof value from the frame
+ *
+ * The FC EOF is converted to the value understood by HW for descriptor
+ * programming. Never call this w/o calling i40e_fcoe_eof_is_supported()
+ * first.
+ **/
+static inline u32 i40e_fcoe_ctxt_eof(u8 eof)
+{
+ switch (eof) {
+ case FC_EOF_N:
+ return I40E_TX_DESC_CMD_L4T_EOFT_EOF_N;
+ case FC_EOF_T:
+ return I40E_TX_DESC_CMD_L4T_EOFT_EOF_T;
+ case FC_EOF_NI:
+ return I40E_TX_DESC_CMD_L4T_EOFT_EOF_NI;
+ case FC_EOF_A:
+ return I40E_TX_DESC_CMD_L4T_EOFT_EOF_A;
+ default:
+ /* FIXME: still returns 0 */
+ pr_err("Unrecognized EOF %x\n", eof);
+ return 0;
+ }
+}
+
+/**
+ * i40e_fcoe_xid_is_valid - returns true if the exchange id is valid
+ * @xid: the exchange id
+ **/
+static inline bool i40e_fcoe_xid_is_valid(u16 xid)
+{
+ return (xid != FC_XID_UNKNOWN) && (xid < I40E_FCOE_DDP_MAX);
+}
+
+/**
+ * i40e_fcoe_ddp_unmap - unmap the mapped sglist associated
+ * @pf: pointer to pf
+ * @ddp: sw DDP context
+ *
+ * Unmap the scatter-gather list associated with the given SW DDP context
+ *
+ * Returns: data length already ddp-ed in bytes
+ *
+ **/
+static inline void i40e_fcoe_ddp_unmap(struct i40e_pf *pf,
+ struct i40e_fcoe_ddp *ddp)
+{
+ if (test_and_set_bit(__I40E_FCOE_DDP_UNMAPPED, &ddp->flags))
+ return;
+
+ if (ddp->sgl) {
+ dma_unmap_sg(&pf->pdev->dev, ddp->sgl, ddp->sgc,
+ DMA_FROM_DEVICE);
+ ddp->sgl = NULL;
+ ddp->sgc = 0;
+ }
+
+ if (ddp->pool) {
+ dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
+ ddp->pool = NULL;
+ }
+}
+
+/**
+ * i40e_fcoe_ddp_clear - clear the given SW DDP context
+ * @ddp - SW DDP context
+ **/
+static inline void i40e_fcoe_ddp_clear(struct i40e_fcoe_ddp *ddp)
+{
+ memset(ddp, 0, sizeof(struct i40e_fcoe_ddp));
+ ddp->xid = FC_XID_UNKNOWN;
+ ddp->flags = __I40E_FCOE_DDP_NONE;
+}
+
+/**
+ * i40e_fcoe_progid_is_fcoe - check if the prog_id is for FCoE
+ * @id: the prog id for the programming status Rx descriptor write-back
+ **/
+static inline bool i40e_fcoe_progid_is_fcoe(u8 id)
+{
+ return (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) ||
+ (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS);
+}
+
+/**
+ * i40e_fcoe_fc_get_xid - get xid from the frame header
+ * @fh: the fc frame header
+ *
+ * In case the incoming frame's exchange is originated from
+ * the initiator, then received frame's exchange id is ANDed
+ * with fc_cpu_mask bits to get the same cpu on which exchange
+ * was originated, otherwise just use the current cpu.
+ *
+ * Returns ox_id if exchange originator, rx_id if responder
+ **/
+static inline u16 i40e_fcoe_fc_get_xid(struct fc_frame_header *fh)
+{
+ u32 f_ctl = ntoh24(fh->fh_f_ctl);
+
+ return (f_ctl & FC_FC_EX_CTX) ?
+ be16_to_cpu(fh->fh_ox_id) :
+ be16_to_cpu(fh->fh_rx_id);
+}
+
+/**
+ * i40e_fcoe_fc_frame_header - get fc frame header from skb
+ * @skb: packet
+ *
+ * This checks if there is a VLAN header and returns the data
+ * pointer to the start of the fc_frame_header.
+ *
+ * Returns pointer to the fc_frame_header
+ **/
+static inline struct fc_frame_header *i40e_fcoe_fc_frame_header(
+ struct sk_buff *skb)
+{
+ void *fh = skb->data + sizeof(struct fcoe_hdr);
+
+ if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q))
+ fh += sizeof(struct vlan_hdr);
+
+ return (struct fc_frame_header *)fh;
+}
+
+/**
+ * i40e_fcoe_ddp_put - release the DDP context for a given exchange id
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id that corresponding DDP context will be released
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_done
+ * and it is expected to be called by ULD, i.e., FCP layer of libfc
+ * to release the corresponding ddp context when the I/O is done.
+ *
+ * Returns : data length already ddp-ed in bytes
+ **/
+static int i40e_fcoe_ddp_put(struct net_device *netdev, u16 xid)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ int len = 0;
+ struct i40e_fcoe_ddp *ddp = &fcoe->ddp[xid];
+
+ if (!fcoe || !ddp)
+ goto out;
+
+ if (test_bit(__I40E_FCOE_DDP_DONE, &ddp->flags))
+ len = ddp->len;
+ i40e_fcoe_ddp_unmap(pf, ddp);
+out:
+ return len;
+}
+
+/**
+ * i40e_fcoe_sw_init - sets up the HW for FCoE
+ * @pf: pointer to pf
+ *
+ * Returns 0 if FCoE is supported otherwise the error code
+ **/
+int i40e_init_pf_fcoe(struct i40e_pf *pf)
+{
+ struct i40e_hw *hw = &pf->hw;
+ u32 val;
+
+ pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
+ pf->num_fcoe_qps = 0;
+ pf->fcoe_hmc_cntx_num = 0;
+ pf->fcoe_hmc_filt_num = 0;
+
+ if (!pf->hw.func_caps.fcoe) {
+ dev_info(&pf->pdev->dev, "FCoE capability is disabled\n");
+ return 0;
+ }
+
+ if (!pf->hw.func_caps.dcb) {
+ dev_warn(&pf->pdev->dev,
+ "Hardware is not DCB capable not enabling FCoE.\n");
+ return 0;
+ }
+
+ /* enable FCoE hash filter */
+ val = rd32(hw, I40E_PFQF_HENA(1));
+ val |= 1 << (I40E_FILTER_PCTYPE_FCOE_OX - 32);
+ val |= 1 << (I40E_FILTER_PCTYPE_FCOE_RX - 32);
+ val &= I40E_PFQF_HENA_PTYPE_ENA_MASK;
+ wr32(hw, I40E_PFQF_HENA(1), val);
+
+ /* enable flag */
+ pf->flags |= I40E_FLAG_FCOE_ENABLED;
+ pf->num_fcoe_qps = I40E_DEFAULT_FCOE;
+
+ /* Reserve 4K DDP contexts and 20K filter size for FCoE */
+ pf->fcoe_hmc_cntx_num = (1 << I40E_DMA_CNTX_SIZE_4K) *
+ I40E_DMA_CNTX_BASE_SIZE;
+ pf->fcoe_hmc_filt_num = pf->fcoe_hmc_cntx_num +
+ (1 << I40E_HASH_FILTER_SIZE_16K) *
+ I40E_HASH_FILTER_BASE_SIZE;
+
+ /* FCoE object: max 16K filter buckets and 4K DMA contexts */
+ pf->filter_settings.fcoe_filt_num = I40E_HASH_FILTER_SIZE_16K;
+ pf->filter_settings.fcoe_cntx_num = I40E_DMA_CNTX_SIZE_4K;
+
+ /* Setup max frame with FCoE_MTU plus L2 overheads */
+ val = rd32(hw, I40E_GLFCOE_RCTL);
+ val &= ~I40E_GLFCOE_RCTL_MAX_SIZE_MASK;
+ val |= ((FCOE_MTU + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
+ << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT);
+ wr32(hw, I40E_GLFCOE_RCTL, val);
+
+ dev_info(&pf->pdev->dev, "FCoE is supported.\n");
+ return 0;
+}
+
+/**
+ * i40e_get_fcoe_tc_map - Return TC map for FCoE APP
+ * @pf: pointer to pf
+ *
+ **/
+u8 i40e_get_fcoe_tc_map(struct i40e_pf *pf)
+{
+ struct i40e_ieee_app_priority_table app;
+ struct i40e_hw *hw = &pf->hw;
+ u8 enabled_tc = 0;
+ u8 tc, i;
+ /* Get the FCoE APP TLV */
+ struct i40e_dcbx_config *dcbcfg = &hw->local_dcbx_config;
+
+ for (i = 0; i < dcbcfg->numapps; i++) {
+ app = dcbcfg->app[i];
+ if (app.selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
+ app.protocolid == ETH_P_FCOE) {
+ tc = dcbcfg->etscfg.prioritytable[app.priority];
+ enabled_tc |= (1 << tc);
+ break;
+ }
+ }
+
+ /* TC0 if there is no TC defined for FCoE APP TLV */
+ enabled_tc = enabled_tc ? enabled_tc : 0x1;
+
+ return enabled_tc;
+}
+
+/**
+ * i40e_fcoe_vsi_init - prepares the VSI context for creating a FCoE VSI
+ * @vsi: pointer to the associated VSI struct
+ * @ctxt: pointer to the associated VSI context to be passed to HW
+ *
+ * Returns 0 on success or < 0 on error
+ **/
+int i40e_fcoe_vsi_init(struct i40e_vsi *vsi, struct i40e_vsi_context *ctxt)
+{
+ struct i40e_aqc_vsi_properties_data *info = &ctxt->info;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ u8 enabled_tc = 0;
+
+ if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
+ dev_err(&pf->pdev->dev,
+ "FCoE is not enabled for this device\n");
+ return -EPERM;
+ }
+
+ /* initialize the hardware for FCoE */
+ ctxt->pf_num = hw->pf_id;
+ ctxt->vf_num = 0;
+ ctxt->uplink_seid = vsi->uplink_seid;
+ ctxt->connection_type = 0x1;
+ ctxt->flags = I40E_AQ_VSI_TYPE_PF;
+
+ /* FCoE VSI would need the following sections */
+ info->valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID |
+ I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
+
+ /* FCoE VSI does not need these sections */
+ info->valid_sections &= cpu_to_le16(~(I40E_AQ_VSI_PROP_SECURITY_VALID |
+ I40E_AQ_VSI_PROP_VLAN_VALID |
+ I40E_AQ_VSI_PROP_CAS_PV_VALID |
+ I40E_AQ_VSI_PROP_INGRESS_UP_VALID |
+ I40E_AQ_VSI_PROP_EGRESS_UP_VALID));
+
+ enabled_tc = i40e_get_fcoe_tc_map(pf);
+ i40e_vsi_setup_queue_map(vsi, ctxt, enabled_tc, true);
+
+ /* set up queue option section: only enable FCoE */
+ info->queueing_opt_flags = I40E_AQ_VSI_QUE_OPT_FCOE_ENA;
+
+ return 0;
+}
+
+/**
+ * i40e_fcoe_enable - this is the implementation of ndo_fcoe_enable,
+ * indicating the upper FCoE protocol stack is ready to use FCoE
+ * offload features.
+ *
+ * @netdev: pointer to the netdev that FCoE is created on
+ *
+ * Returns 0 on success
+ *
+ * in RTNL
+ *
+ **/
+int i40e_fcoe_enable(struct net_device *netdev)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+
+ if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
+ netdev_err(netdev, "HW does not support FCoE.\n");
+ return -ENODEV;
+ }
+
+ if (vsi->type != I40E_VSI_FCOE) {
+ netdev_err(netdev, "interface does not support FCoE.\n");
+ return -EBUSY;
+ }
+
+ atomic_inc(&fcoe->refcnt);
+
+ return 0;
+}
+
+/**
+ * i40e_fcoe_disable- disables FCoE for upper FCoE protocol stack.
+ * @dev: pointer to the netdev that FCoE is created on
+ *
+ * Returns 0 on success
+ *
+ **/
+int i40e_fcoe_disable(struct net_device *netdev)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+
+ if (!(pf->flags & I40E_FLAG_FCOE_ENABLED)) {
+ netdev_err(netdev, "device does not support FCoE\n");
+ return -ENODEV;
+ }
+ if (vsi->type != I40E_VSI_FCOE)
+ return -EBUSY;
+
+ if (!atomic_dec_and_test(&fcoe->refcnt))
+ return -EINVAL;
+
+ netdev_info(netdev, "FCoE disabled\n");
+
+ return 0;
+}
+
+/**
+ * i40e_fcoe_dma_pool_free - free the per cpu pool for FCoE DDP
+ * @fcoe: the FCoE sw object
+ * @dev: the device that the pool is associated with
+ * @cpu: the cpu for this pool
+ *
+ **/
+static void i40e_fcoe_dma_pool_free(struct i40e_fcoe *fcoe,
+ struct device *dev,
+ unsigned int cpu)
+{
+ struct i40e_fcoe_ddp_pool *ddp_pool;
+
+ ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
+ if (!ddp_pool->pool) {
+ dev_warn(dev, "DDP pool already freed for cpu %d\n", cpu);
+ return;
+ }
+ dma_pool_destroy(ddp_pool->pool);
+ ddp_pool->pool = NULL;
+}
+
+/**
+ * i40e_fcoe_dma_pool_create - per cpu pool for FCoE DDP
+ * @fcoe: the FCoE sw object
+ * @dev: the device that the pool is associated with
+ * @cpu: the cpu for this pool
+ *
+ * Returns 0 on successful or non zero on failure
+ *
+ **/
+static int i40e_fcoe_dma_pool_create(struct i40e_fcoe *fcoe,
+ struct device *dev,
+ unsigned int cpu)
+{
+ struct i40e_fcoe_ddp_pool *ddp_pool;
+ struct dma_pool *pool;
+ char pool_name[32];
+
+ ddp_pool = per_cpu_ptr(fcoe->ddp_pool, cpu);
+ if (ddp_pool && ddp_pool->pool) {
+ dev_warn(dev, "DDP pool already allocated for cpu %d\n", cpu);
+ return 0;
+ }
+ snprintf(pool_name, sizeof(pool_name), "i40e_fcoe_ddp_%d", cpu);
+ pool = dma_pool_create(pool_name, dev, I40E_FCOE_DDP_PTR_MAX,
+ I40E_FCOE_DDP_PTR_ALIGN, PAGE_SIZE);
+ if (!pool) {
+ dev_err(dev, "dma_pool_create %s failed\n", pool_name);
+ return -ENOMEM;
+ }
+ ddp_pool->pool = pool;
+ return 0;
+}
+
+/**
+ * i40e_fcoe_free_ddp_resources - release FCoE DDP resources
+ * @vsi: the vsi FCoE is associated with
+ *
+ **/
+void i40e_fcoe_free_ddp_resources(struct i40e_vsi *vsi)
+{
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ int cpu, i;
+
+ /* do nothing if not FCoE VSI */
+ if (vsi->type != I40E_VSI_FCOE)
+ return;
+
+ /* do nothing if no DDP pools were allocated */
+ if (!fcoe->ddp_pool)
+ return;
+
+ for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
+ i40e_fcoe_ddp_put(vsi->netdev, i);
+
+ for_each_possible_cpu(cpu)
+ i40e_fcoe_dma_pool_free(fcoe, &pf->pdev->dev, cpu);
+
+ free_percpu(fcoe->ddp_pool);
+ fcoe->ddp_pool = NULL;
+
+ netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources released\n",
+ vsi->id, vsi->seid);
+}
+
+/**
+ * i40e_fcoe_setup_ddp_resources - allocate per cpu DDP resources
+ * @vsi: the VSI FCoE is associated with
+ *
+ * Returns 0 on successful or non zero on failure
+ *
+ **/
+int i40e_fcoe_setup_ddp_resources(struct i40e_vsi *vsi)
+{
+ struct i40e_pf *pf = vsi->back;
+ struct device *dev = &pf->pdev->dev;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ unsigned int cpu;
+ int i;
+
+ if (vsi->type != I40E_VSI_FCOE)
+ return -ENODEV;
+
+ /* do nothing if no DDP pools were allocated */
+ if (fcoe->ddp_pool)
+ return -EEXIST;
+
+ /* allocate per CPU memory to track DDP pools */
+ fcoe->ddp_pool = alloc_percpu(struct i40e_fcoe_ddp_pool);
+ if (!fcoe->ddp_pool) {
+ dev_err(&pf->pdev->dev, "failed to allocate percpu DDP\n");
+ return -ENOMEM;
+ }
+
+ /* allocate pci pool for each cpu */
+ for_each_possible_cpu(cpu) {
+ if (!i40e_fcoe_dma_pool_create(fcoe, dev, cpu))
+ continue;
+
+ dev_err(dev, "failed to alloc DDP pool on cpu:%d\n", cpu);
+ i40e_fcoe_free_ddp_resources(vsi);
+ return -ENOMEM;
+ }
+
+ /* initialize the sw context */
+ for (i = 0; i < I40E_FCOE_DDP_MAX; i++)
+ i40e_fcoe_ddp_clear(&fcoe->ddp[i]);
+
+ netdev_info(vsi->netdev, "VSI %d,%d FCoE DDP resources allocated\n",
+ vsi->id, vsi->seid);
+
+ return 0;
+}
+
+/**
+ * i40e_fcoe_handle_status - check the Programming Status for FCoE
+ * @rx_ring: the Rx ring for this descriptor
+ * @rx_desc: the Rx descriptor for Programming Status, not a packet descriptor.
+ *
+ * Check if this is the Rx Programming Status descriptor write-back for FCoE.
+ * This is used to verify if the context/filter programming or invalidation
+ * requested by SW to the HW is successful or not and take actions accordingly.
+ **/
+void i40e_fcoe_handle_status(struct i40e_ring *rx_ring,
+ union i40e_rx_desc *rx_desc, u8 prog_id)
+{
+ struct i40e_pf *pf = rx_ring->vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ struct i40e_fcoe_ddp *ddp;
+ u32 error;
+ u16 xid;
+ u64 qw;
+
+ /* we only care for FCoE here */
+ if (!i40e_fcoe_progid_is_fcoe(prog_id))
+ return;
+
+ xid = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param) &
+ (I40E_FCOE_DDP_MAX - 1);
+
+ if (!i40e_fcoe_xid_is_valid(xid))
+ return;
+
+ ddp = &fcoe->ddp[xid];
+ WARN_ON(xid != ddp->xid);
+
+ qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
+ error = (qw & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
+ I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;
+
+ /* DDP context programming status: failure or success */
+ if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) {
+ if (I40E_RX_PROG_FCOE_ERROR_TBL_FULL(error)) {
+ dev_err(&pf->pdev->dev, "xid %x ddp->xid %x TABLE FULL\n",
+ xid, ddp->xid);
+ ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_TBL_FULL_BIT;
+ }
+ if (I40E_RX_PROG_FCOE_ERROR_CONFLICT(error)) {
+ dev_err(&pf->pdev->dev, "xid %x ddp->xid %x CONFLICT\n",
+ xid, ddp->xid);
+ ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT;
+ }
+ }
+
+ /* DDP context invalidation status: failure or success */
+ if (prog_id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS) {
+ if (I40E_RX_PROG_FCOE_ERROR_INVLFAIL(error)) {
+ dev_err(&pf->pdev->dev, "xid %x ddp->xid %x INVALIDATION FAILURE\n",
+ xid, ddp->xid);
+ ddp->prerr |= I40E_RX_PROG_FCOE_ERROR_INVLFAIL_BIT;
+ }
+ /* clear the flag so we can retry invalidation */
+ clear_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags);
+ }
+
+ /* unmap DMA */
+ i40e_fcoe_ddp_unmap(pf, ddp);
+ i40e_fcoe_ddp_clear(ddp);
+}
+
+/**
+ * i40e_fcoe_handle_offload - check ddp status and mark it done
+ * @adapter: i40e adapter
+ * @rx_desc: advanced rx descriptor
+ * @skb: the skb holding the received data
+ *
+ * This checks ddp status.
+ *
+ * Returns : < 0 indicates an error or not a FCOE ddp, 0 indicates
+ * not passing the skb to ULD, > 0 indicates is the length of data
+ * being ddped.
+ *
+ **/
+int i40e_fcoe_handle_offload(struct i40e_ring *rx_ring,
+ union i40e_rx_desc *rx_desc,
+ struct sk_buff *skb)
+{
+ struct i40e_pf *pf = rx_ring->vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ struct fc_frame_header *fh = NULL;
+ struct i40e_fcoe_ddp *ddp = NULL;
+ u32 status, fltstat;
+ u32 error, fcerr;
+ int rc = -EINVAL;
+ u16 ptype;
+ u16 xid;
+ u64 qw;
+
+ /* check this rxd is for programming status */
+ qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
+ /* packet descriptor, check packet type */
+ ptype = (qw & I40E_RXD_QW1_PTYPE_MASK) >> I40E_RXD_QW1_PTYPE_SHIFT;
+ if (!i40e_rx_is_fcoe(ptype))
+ goto out_no_ddp;
+
+ error = (qw & I40E_RXD_QW1_ERROR_MASK) >> I40E_RXD_QW1_ERROR_SHIFT;
+ fcerr = (error >> I40E_RX_DESC_ERROR_L3L4E_SHIFT) &
+ I40E_RX_DESC_FCOE_ERROR_MASK;
+
+ /* check stateless offload error */
+ if (unlikely(fcerr == I40E_RX_DESC_ERROR_L3L4E_PROT)) {
+ dev_err(&pf->pdev->dev, "Protocol Error\n");
+ skb->ip_summed = CHECKSUM_NONE;
+ } else {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+
+ /* check hw status on ddp */
+ status = (qw & I40E_RXD_QW1_STATUS_MASK) >> I40E_RXD_QW1_STATUS_SHIFT;
+ fltstat = (status >> I40E_RX_DESC_STATUS_FLTSTAT_SHIFT) &
+ I40E_RX_DESC_FLTSTAT_FCMASK;
+
+ /* now we are ready to check DDP */
+ fh = i40e_fcoe_fc_frame_header(skb);
+ xid = i40e_fcoe_fc_get_xid(fh);
+ if (!i40e_fcoe_xid_is_valid(xid))
+ goto out_no_ddp;
+
+ /* non DDP normal receive, return to the protocol stack */
+ if (fltstat == I40E_RX_DESC_FLTSTAT_NOMTCH)
+ goto out_no_ddp;
+
+ /* do we have a sw ddp context setup ? */
+ ddp = &fcoe->ddp[xid];
+ if (!ddp->sgl)
+ goto out_no_ddp;
+
+ /* fetch xid from hw rxd wb, which should match up the sw ctxt */
+ xid = le16_to_cpu(rx_desc->wb.qword0.lo_dword.mirr_fcoe.fcoe_ctx_id);
+ if (ddp->xid != xid) {
+ dev_err(&pf->pdev->dev, "xid 0x%x does not match ctx_xid 0x%x\n",
+ ddp->xid, xid);
+ goto out_put_ddp;
+ }
+
+ /* the same exchange has already errored out */
+ if (ddp->fcerr) {
+ dev_err(&pf->pdev->dev, "xid 0x%x fcerr 0x%x reported fcer 0x%x\n",
+ xid, ddp->fcerr, fcerr);
+ goto out_put_ddp;
+ }
+
+ /* fcoe param is valid by now with correct DDPed length */
+ ddp->len = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fcoe_param);
+ ddp->fcerr = fcerr;
+ /* header posting only, useful only for target mode and debugging */
+ if (fltstat == I40E_RX_DESC_FLTSTAT_DDP) {
+ /* For target mode, we get header of the last packet but it
+ * does not have the FCoE trailer field, i.e., CRC and EOF
+ * Ordered Set since they are offloaded by the HW, so fill
+ * it up correspondingly to allow the packet to pass through
+ * to the upper protocol stack.
+ */
+ u32 f_ctl = ntoh24(fh->fh_f_ctl);
+
+ if ((f_ctl & FC_FC_END_SEQ) &&
+ (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA)) {
+ struct fcoe_crc_eof *crc = NULL;
+
+ crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
+ crc->fcoe_eof = FC_EOF_T;
+ } else {
+ /* otherwise, drop the header only frame */
+ rc = 0;
+ goto out_no_ddp;
+ }
+ }
+
+out_put_ddp:
+ /* either we got RSP or we have an error, unmap DMA in both cases */
+ i40e_fcoe_ddp_unmap(pf, ddp);
+ if (ddp->len && !ddp->fcerr) {
+ int pkts;
+
+ rc = ddp->len;
+ i40e_fcoe_ddp_clear(ddp);
+ ddp->len = rc;
+ pkts = DIV_ROUND_UP(rc, 2048);
+ rx_ring->stats.bytes += rc;
+ rx_ring->stats.packets += pkts;
+ rx_ring->q_vector->rx.total_bytes += rc;
+ rx_ring->q_vector->rx.total_packets += pkts;
+ set_bit(__I40E_FCOE_DDP_DONE, &ddp->flags);
+ }
+
+out_no_ddp:
+ return rc;
+}
+
+/**
+ * i40e_fcoe_ddp_setup - called to set up ddp context
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id requesting ddp
+ * @sgl: the scatter-gather list for this request
+ * @sgc: the number of scatter-gather items
+ * @target_mode: indicates this is a DDP request for target
+ *
+ * Returns : 1 for success and 0 for no DDP on this I/O
+ **/
+static int i40e_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc,
+ int target_mode)
+{
+ static const unsigned int bufflen = I40E_FCOE_DDP_BUF_MIN;
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_fcoe_ddp_pool *ddp_pool;
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ unsigned int i, j, dmacount;
+ struct i40e_fcoe_ddp *ddp;
+ unsigned int firstoff = 0;
+ unsigned int thisoff = 0;
+ unsigned int thislen = 0;
+ struct scatterlist *sg;
+ dma_addr_t addr = 0;
+ unsigned int len;
+
+ if (xid >= I40E_FCOE_DDP_MAX) {
+ dev_warn(&pf->pdev->dev, "xid=0x%x out-of-range\n", xid);
+ return 0;
+ }
+
+ /* no DDP if we are already down or resetting */
+ if (test_bit(__I40E_DOWN, &pf->state) ||
+ test_bit(__I40E_NEEDS_RESTART, &pf->state)) {
+ dev_info(&pf->pdev->dev, "xid=0x%x device in reset/down\n",
+ xid);
+ return 0;
+ }
+
+ ddp = &fcoe->ddp[xid];
+ if (ddp->sgl) {
+ dev_info(&pf->pdev->dev, "xid 0x%x w/ non-null sgl=%p nents=%d\n",
+ xid, ddp->sgl, ddp->sgc);
+ return 0;
+ }
+ i40e_fcoe_ddp_clear(ddp);
+
+ if (!fcoe->ddp_pool) {
+ dev_info(&pf->pdev->dev, "No DDP pool, xid 0x%x\n", xid);
+ return 0;
+ }
+
+ ddp_pool = per_cpu_ptr(fcoe->ddp_pool, get_cpu());
+ if (!ddp_pool->pool) {
+ dev_info(&pf->pdev->dev, "No percpu ddp pool, xid 0x%x\n", xid);
+ goto out_noddp;
+ }
+
+ /* setup dma from scsi command sgl */
+ dmacount = dma_map_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
+ if (dmacount == 0) {
+ dev_info(&pf->pdev->dev, "dma_map_sg for sgl %p, sgc %d failed\n",
+ sgl, sgc);
+ goto out_noddp_unmap;
+ }
+
+ /* alloc the udl from our ddp pool */
+ ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
+ if (!ddp->udl) {
+ dev_info(&pf->pdev->dev,
+ "Failed allocated ddp context, xid 0x%x\n", xid);
+ goto out_noddp_unmap;
+ }
+
+ j = 0;
+ ddp->len = 0;
+ for_each_sg(sgl, sg, dmacount, i) {
+ addr = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+ ddp->len += len;
+ while (len) {
+ /* max number of buffers allowed in one DDP context */
+ if (j >= I40E_FCOE_DDP_BUFFCNT_MAX) {
+ dev_info(&pf->pdev->dev,
+ "xid=%x:%d,%d,%d:addr=%llx not enough descriptors\n",
+ xid, i, j, dmacount, (u64)addr);
+ goto out_noddp_free;
+ }
+
+ /* get the offset of length of current buffer */
+ thisoff = addr & ((dma_addr_t)bufflen - 1);
+ thislen = min_t(unsigned int, (bufflen - thisoff), len);
+ /* all but the 1st buffer (j == 0)
+ * must be aligned on bufflen
+ */
+ if ((j != 0) && (thisoff))
+ goto out_noddp_free;
+
+ /* all but the last buffer
+ * ((i == (dmacount - 1)) && (thislen == len))
+ * must end at bufflen
+ */
+ if (((i != (dmacount - 1)) || (thislen != len)) &&
+ ((thislen + thisoff) != bufflen))
+ goto out_noddp_free;
+
+ ddp->udl[j] = (u64)(addr - thisoff);
+ /* only the first buffer may have none-zero offset */
+ if (j == 0)
+ firstoff = thisoff;
+ len -= thislen;
+ addr += thislen;
+ j++;
+ }
+ }
+ /* only the last buffer may have non-full bufflen */
+ ddp->lastsize = thisoff + thislen;
+ ddp->firstoff = firstoff;
+ ddp->list_len = j;
+ ddp->pool = ddp_pool->pool;
+ ddp->sgl = sgl;
+ ddp->sgc = sgc;
+ ddp->xid = xid;
+ if (target_mode)
+ set_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
+ set_bit(__I40E_FCOE_DDP_INITALIZED, &ddp->flags);
+
+ put_cpu();
+ return 1; /* Success */
+
+out_noddp_free:
+ dma_pool_free(ddp->pool, ddp->udl, ddp->udp);
+ i40e_fcoe_ddp_clear(ddp);
+
+out_noddp_unmap:
+ dma_unmap_sg(&pf->pdev->dev, sgl, sgc, DMA_FROM_DEVICE);
+out_noddp:
+ put_cpu();
+ return 0;
+}
+
+/**
+ * i40e_fcoe_ddp_get - called to set up ddp context in initiator mode
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id requesting ddp
+ * @sgl: the scatter-gather list for this request
+ * @sgc: the number of scatter-gather items
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
+ * and is expected to be called from ULD, e.g., FCP layer of libfc
+ * to set up ddp for the corresponding xid of the given sglist for
+ * the corresponding I/O.
+ *
+ * Returns : 1 for success and 0 for no ddp
+ **/
+static int i40e_fcoe_ddp_get(struct net_device *netdev, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc)
+{
+ return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);
+}
+
+/**
+ * i40e_fcoe_ddp_target - called to set up ddp context in target mode
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id requesting ddp
+ * @sgl: the scatter-gather list for this request
+ * @sgc: the number of scatter-gather items
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_target
+ * and is expected to be called from ULD, e.g., FCP layer of libfc
+ * to set up ddp for the corresponding xid of the given sglist for
+ * the corresponding I/O. The DDP in target mode is a write I/O request
+ * from the initiator.
+ *
+ * Returns : 1 for success and 0 for no ddp
+ **/
+static int i40e_fcoe_ddp_target(struct net_device *netdev, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc)
+{
+ return i40e_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);
+}
+
+/**
+ * i40e_fcoe_program_ddp - programs the HW DDP related descriptors
+ * @tx_ring: transmit ring for this packet
+ * @skb: the packet to be sent out
+ * @sof: the SOF to indicate class of service
+ *
+ * Determine if it is READ/WRITE command, and finds out if there is
+ * a matching SW DDP context for this command. DDP is applicable
+ * only in case of READ if initiator or WRITE in case of
+ * responder (via checking XFER_RDY).
+ *
+ * Note: caller checks sof and ddp sw context
+ *
+ * Returns : none
+ *
+ **/
+static void i40e_fcoe_program_ddp(struct i40e_ring *tx_ring,
+ struct sk_buff *skb,
+ struct i40e_fcoe_ddp *ddp, u8 sof)
+{
+ struct i40e_fcoe_filter_context_desc *filter_desc = NULL;
+ struct i40e_fcoe_queue_context_desc *queue_desc = NULL;
+ struct i40e_fcoe_ddp_context_desc *ddp_desc = NULL;
+ struct i40e_pf *pf = tx_ring->vsi->back;
+ u16 i = tx_ring->next_to_use;
+ struct fc_frame_header *fh;
+ u64 flags_rsvd_lanq = 0;
+ bool target_mode;
+
+ /* check if abort is still pending */
+ if (test_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags)) {
+ dev_warn(&pf->pdev->dev,
+ "DDP abort is still pending xid:%hx and ddp->flags:%lx:\n",
+ ddp->xid, ddp->flags);
+ return;
+ }
+
+ /* set the flag to indicate this is programmed */
+ if (test_and_set_bit(__I40E_FCOE_DDP_PROGRAMMED, &ddp->flags)) {
+ dev_warn(&pf->pdev->dev,
+ "DDP is already programmed for xid:%hx and ddp->flags:%lx:\n",
+ ddp->xid, ddp->flags);
+ return;
+ }
+
+ /* Prepare the DDP context descriptor */
+ ddp_desc = I40E_DDP_CONTEXT_DESC(tx_ring, i);
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
+ ddp_desc->type_cmd_foff_lsize =
+ cpu_to_le64(I40E_TX_DESC_DTYPE_DDP_CTX |
+ ((u64)I40E_FCOE_DDP_CTX_DESC_BSIZE_4K <<
+ I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT) |
+ ((u64)ddp->firstoff <<
+ I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT) |
+ ((u64)ddp->lastsize <<
+ I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT));
+ ddp_desc->rsvd = cpu_to_le64(0);
+
+ /* target mode needs last packet in the sequence */
+ target_mode = test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags);
+ if (target_mode)
+ ddp_desc->type_cmd_foff_lsize |=
+ cpu_to_le64(I40E_FCOE_DDP_CTX_DESC_LASTSEQH);
+
+ /* Prepare queue_context descriptor */
+ queue_desc = I40E_QUEUE_CONTEXT_DESC(tx_ring, i++);
+ if (i == tx_ring->count)
+ i = 0;
+ queue_desc->dmaindx_fbase = cpu_to_le64(ddp->xid | ((u64)ddp->udp));
+ queue_desc->flen_tph = cpu_to_le64(ddp->list_len |
+ ((u64)(I40E_FCOE_QUEUE_CTX_DESC_TPHRDESC |
+ I40E_FCOE_QUEUE_CTX_DESC_TPHDATA) <<
+ I40E_FCOE_QUEUE_CTX_QW1_TPH_SHIFT));
+
+ /* Prepare filter_context_desc */
+ filter_desc = I40E_FILTER_CONTEXT_DESC(tx_ring, i);
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
+ fh = (struct fc_frame_header *)skb_transport_header(skb);
+ filter_desc->param = cpu_to_le32(ntohl(fh->fh_parm_offset));
+ filter_desc->seqn = cpu_to_le16(ntohs(fh->fh_seq_cnt));
+ filter_desc->rsvd_dmaindx = cpu_to_le16(ddp->xid <<
+ I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT);
+
+ flags_rsvd_lanq = I40E_FCOE_FILTER_CTX_DESC_CTYP_DDP;
+ flags_rsvd_lanq |= (u64)(target_mode ?
+ I40E_FCOE_FILTER_CTX_DESC_ENODE_RSP :
+ I40E_FCOE_FILTER_CTX_DESC_ENODE_INIT);
+
+ flags_rsvd_lanq |= (u64)((sof == FC_SOF_I2 || sof == FC_SOF_N2) ?
+ I40E_FCOE_FILTER_CTX_DESC_FC_CLASS2 :
+ I40E_FCOE_FILTER_CTX_DESC_FC_CLASS3);
+
+ flags_rsvd_lanq |= ((u64)skb->queue_mapping <<
+ I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT);
+ filter_desc->flags_rsvd_lanq = cpu_to_le64(flags_rsvd_lanq);
+
+ /* By this time, all offload related descriptors has been programmed */
+ tx_ring->next_to_use = i;
+}
+
+/**
+ * i40e_fcoe_invalidate_ddp - invalidates DDP in case of abort
+ * @tx_ring: transmit ring for this packet
+ * @skb: the packet associated w/ this DDP invalidation, i.e., ABTS
+ * @ddp: the SW DDP context for this DDP
+ *
+ * Programs the Tx context descriptor to do DDP invalidation.
+ **/
+static void i40e_fcoe_invalidate_ddp(struct i40e_ring *tx_ring,
+ struct sk_buff *skb,
+ struct i40e_fcoe_ddp *ddp)
+{
+ struct i40e_tx_context_desc *context_desc;
+ int i;
+
+ if (test_and_set_bit(__I40E_FCOE_DDP_ABORTED, &ddp->flags))
+ return;
+
+ i = tx_ring->next_to_use;
+ context_desc = I40E_TX_CTXTDESC(tx_ring, i);
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
+ context_desc->tunneling_params = cpu_to_le32(0);
+ context_desc->l2tag2 = cpu_to_le16(0);
+ context_desc->rsvd = cpu_to_le16(0);
+ context_desc->type_cmd_tso_mss = cpu_to_le64(
+ I40E_TX_DESC_DTYPE_FCOE_CTX |
+ (I40E_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL <<
+ I40E_TXD_CTX_QW1_CMD_SHIFT) |
+ (I40E_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND <<
+ I40E_TXD_CTX_QW1_CMD_SHIFT));
+ tx_ring->next_to_use = i;
+}
+
+/**
+ * i40e_fcoe_handle_ddp - check we should setup or invalidate DDP
+ * @tx_ring: transmit ring for this packet
+ * @skb: the packet to be sent out
+ * @sof: the SOF to indicate class of service
+ *
+ * Determine if it is ABTS/READ/XFER_RDY, and finds out if there is
+ * a matching SW DDP context for this command. DDP is applicable
+ * only in case of READ if initiator or WRITE in case of
+ * responder (via checking XFER_RDY). In case this is an ABTS, send
+ * just invalidate the context.
+ **/
+static void i40e_fcoe_handle_ddp(struct i40e_ring *tx_ring,
+ struct sk_buff *skb, u8 sof)
+{
+ struct i40e_pf *pf = tx_ring->vsi->back;
+ struct i40e_fcoe *fcoe = &pf->fcoe;
+ struct fc_frame_header *fh;
+ struct i40e_fcoe_ddp *ddp;
+ u32 f_ctl;
+ u8 r_ctl;
+ u16 xid;
+
+ fh = (struct fc_frame_header *)skb_transport_header(skb);
+ f_ctl = ntoh24(fh->fh_f_ctl);
+ r_ctl = fh->fh_r_ctl;
+ ddp = NULL;
+
+ if ((r_ctl == FC_RCTL_DD_DATA_DESC) && (f_ctl & FC_FC_EX_CTX)) {
+ /* exchange responder? if so, XFER_RDY for write */
+ xid = ntohs(fh->fh_rx_id);
+ if (i40e_fcoe_xid_is_valid(xid)) {
+ ddp = &fcoe->ddp[xid];
+ if ((ddp->xid == xid) &&
+ (test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
+ i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
+ }
+ } else if (r_ctl == FC_RCTL_DD_UNSOL_CMD) {
+ /* exchange originator, check READ cmd */
+ xid = ntohs(fh->fh_ox_id);
+ if (i40e_fcoe_xid_is_valid(xid)) {
+ ddp = &fcoe->ddp[xid];
+ if ((ddp->xid == xid) &&
+ (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
+ i40e_fcoe_program_ddp(tx_ring, skb, ddp, sof);
+ }
+ } else if (r_ctl == FC_RCTL_BA_ABTS) {
+ /* exchange originator, check ABTS */
+ xid = ntohs(fh->fh_ox_id);
+ if (i40e_fcoe_xid_is_valid(xid)) {
+ ddp = &fcoe->ddp[xid];
+ if ((ddp->xid == xid) &&
+ (!test_bit(__I40E_FCOE_DDP_TARGET, &ddp->flags)))
+ i40e_fcoe_invalidate_ddp(tx_ring, skb, ddp);
+ }
+ }
+}
+
+/**
+ * i40e_fcoe_tso - set up FCoE TSO
+ * @tx_ring: ring to send buffer on
+ * @skb: send buffer
+ * @tx_flags: collected send information
+ * @hdr_len: the tso header length
+ * @sof: the SOF to indicate class of service
+ *
+ * Note must already have sof checked to be either class 2 or class 3 before
+ * calling this function.
+ *
+ * Returns 1 to indicate sequence segmentation offload is properly setup
+ * or returns 0 to indicate no tso is needed, otherwise returns error
+ * code to drop the frame.
+ **/
+static int i40e_fcoe_tso(struct i40e_ring *tx_ring,
+ struct sk_buff *skb,
+ u32 tx_flags, u8 *hdr_len, u8 sof)
+{
+ struct i40e_tx_context_desc *context_desc;
+ u32 cd_type, cd_cmd, cd_tso_len, cd_mss;
+ struct fc_frame_header *fh;
+ u64 cd_type_cmd_tso_mss;
+
+ /* must match gso type as FCoE */
+ if (!skb_is_gso(skb))
+ return 0;
+
+ /* is it the expected gso type for FCoE ?*/
+ if (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE) {
+ netdev_err(skb->dev,
+ "wrong gso type %d:expecting SKB_GSO_FCOE\n",
+ skb_shinfo(skb)->gso_type);
+ return -EINVAL;
+ }
+
+ /* header and trailer are inserted by hw */
+ *hdr_len = skb_transport_offset(skb) + sizeof(struct fc_frame_header) +
+ sizeof(struct fcoe_crc_eof);
+
+ /* check sof to decide a class 2 or 3 TSO */
+ if (likely(i40e_fcoe_sof_is_class3(sof)))
+ cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3;
+ else
+ cd_cmd = I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2;
+
+ /* param field valid? */
+ fh = (struct fc_frame_header *)skb_transport_header(skb);
+ if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
+ cd_cmd |= I40E_FCOE_TX_CTX_DESC_RELOFF;
+
+ /* fill the field values */
+ cd_type = I40E_TX_DESC_DTYPE_FCOE_CTX;
+ cd_tso_len = skb->len - *hdr_len;
+ cd_mss = skb_shinfo(skb)->gso_size;
+ cd_type_cmd_tso_mss =
+ ((u64)cd_type << I40E_TXD_CTX_QW1_DTYPE_SHIFT) |
+ ((u64)cd_cmd << I40E_TXD_CTX_QW1_CMD_SHIFT) |
+ ((u64)cd_tso_len << I40E_TXD_CTX_QW1_TSO_LEN_SHIFT) |
+ ((u64)cd_mss << I40E_TXD_CTX_QW1_MSS_SHIFT);
+
+ /* grab the next descriptor */
+ context_desc = I40E_TX_CTXTDESC(tx_ring, tx_ring->next_to_use);
+ tx_ring->next_to_use++;
+ if (tx_ring->next_to_use == tx_ring->count)
+ tx_ring->next_to_use = 0;
+
+ context_desc->tunneling_params = 0;
+ context_desc->l2tag2 = cpu_to_le16((tx_flags & I40E_TX_FLAGS_VLAN_MASK)
+ >> I40E_TX_FLAGS_VLAN_SHIFT);
+ context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);
+
+ return 1;
+}
+
+/**
+ * i40e_fcoe_tx_map - build the tx descriptor
+ * @tx_ring: ring to send buffer on
+ * @skb: send buffer
+ * @first: first buffer info buffer to use
+ * @tx_flags: collected send information
+ * @hdr_len: ptr to the size of the packet header
+ * @eof: the frame eof value
+ *
+ * Note, for FCoE, sof and eof are already checked
+ **/
+static void i40e_fcoe_tx_map(struct i40e_ring *tx_ring,
+ struct sk_buff *skb,
+ struct i40e_tx_buffer *first,
+ u32 tx_flags, u8 hdr_len, u8 eof)
+{
+ u32 td_offset = 0;
+ u32 td_cmd = 0;
+ u32 maclen;
+
+ /* insert CRC */
+ td_cmd = I40E_TX_DESC_CMD_ICRC;
+
+ /* setup MACLEN */
+ maclen = skb_network_offset(skb);
+ if (tx_flags & I40E_TX_FLAGS_SW_VLAN)
+ maclen += sizeof(struct vlan_hdr);
+
+ if (skb->protocol == htons(ETH_P_FCOE)) {
+ /* for FCoE, maclen should exclude ether type */
+ maclen -= 2;
+ /* setup type as FCoE and EOF insertion */
+ td_cmd |= (I40E_TX_DESC_CMD_FCOET | i40e_fcoe_ctxt_eof(eof));
+ /* setup FCoELEN and FCLEN */
+ td_offset |= ((((sizeof(struct fcoe_hdr) + 2) >> 2) <<
+ I40E_TX_DESC_LENGTH_IPLEN_SHIFT) |
+ ((sizeof(struct fc_frame_header) >> 2) <<
+ I40E_TX_DESC_LENGTH_L4_FC_LEN_SHIFT));
+ /* trim to exclude trailer */
+ pskb_trim(skb, skb->len - sizeof(struct fcoe_crc_eof));
+ }
+
+ /* MACLEN is ether header length in words not bytes */
+ td_offset |= (maclen >> 1) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;
+
+ return i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len,
+ td_cmd, td_offset);
+}
+
+/**
+ * i40e_fcoe_set_skb_header - adjust skb header point for FIP/FCoE/FC
+ * @skb: the skb to be adjusted
+ *
+ * Returns true if this skb is a FCoE/FIP or VLAN carried FCoE/FIP and then
+ * adjusts the skb header pointers correspondingly. Otherwise, returns false.
+ **/
+static inline int i40e_fcoe_set_skb_header(struct sk_buff *skb)
+{
+ __be16 protocol = skb->protocol;
+
+ skb_reset_mac_header(skb);
+ skb->mac_len = sizeof(struct ethhdr);
+ if (protocol == htons(ETH_P_8021Q)) {
+ struct vlan_ethhdr *veth = (struct vlan_ethhdr *)eth_hdr(skb);
+
+ protocol = veth->h_vlan_encapsulated_proto;
+ skb->mac_len += sizeof(struct vlan_hdr);
+ }
+
+ /* FCoE or FIP only */
+ if ((protocol != htons(ETH_P_FIP)) &&
+ (protocol != htons(ETH_P_FCOE)))
+ return -EINVAL;
+
+ /* set header to L2 of FCoE/FIP */
+ skb_set_network_header(skb, skb->mac_len);
+ if (protocol == htons(ETH_P_FIP))
+ return 0;
+
+ /* set header to L3 of FC */
+ skb_set_transport_header(skb, skb->mac_len + sizeof(struct fcoe_hdr));
+ return 0;
+}
+
+/**
+ * i40e_fcoe_xmit_frame - transmit buffer
+ * @skb: send buffer
+ * @netdev: the fcoe netdev
+ *
+ * Returns 0 if sent, else an error code
+ **/
+static netdev_tx_t i40e_fcoe_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct i40e_netdev_priv *np = netdev_priv(skb->dev);
+ struct i40e_vsi *vsi = np->vsi;
+ struct i40e_ring *tx_ring = vsi->tx_rings[skb->queue_mapping];
+ struct i40e_tx_buffer *first;
+ u32 tx_flags = 0;
+ u8 hdr_len = 0;
+ u8 sof = 0;
+ u8 eof = 0;
+ int fso;
+
+ if (i40e_fcoe_set_skb_header(skb))
+ goto out_drop;
+
+ if (!i40e_xmit_descriptor_count(skb, tx_ring))
+ return NETDEV_TX_BUSY;
+
+ /* prepare the xmit flags */
+ if (i40e_tx_prepare_vlan_flags(skb, tx_ring, &tx_flags))
+ goto out_drop;
+
+ /* record the location of the first descriptor for this packet */
+ first = &tx_ring->tx_bi[tx_ring->next_to_use];
+
+ /* FIP is a regular L2 traffic w/o offload */
+ if (skb->protocol == htons(ETH_P_FIP))
+ goto out_send;
+
+ /* check sof and eof, only supports FC Class 2 or 3 */
+ if (i40e_fcoe_fc_sof(skb, &sof) || i40e_fcoe_fc_eof(skb, &eof)) {
+ netdev_err(netdev, "SOF/EOF error:%02x - %02x\n", sof, eof);
+ goto out_drop;
+ }
+
+ /* always do FCCRC for FCoE */
+ tx_flags |= I40E_TX_FLAGS_FCCRC;
+
+ /* check we should do sequence offload */
+ fso = i40e_fcoe_tso(tx_ring, skb, tx_flags, &hdr_len, sof);
+ if (fso < 0)
+ goto out_drop;
+ else if (fso)
+ tx_flags |= I40E_TX_FLAGS_FSO;
+ else
+ i40e_fcoe_handle_ddp(tx_ring, skb, sof);
+
+out_send:
+ /* send out the packet */
+ i40e_fcoe_tx_map(tx_ring, skb, first, tx_flags, hdr_len, eof);
+
+ i40e_maybe_stop_tx(tx_ring, DESC_NEEDED);
+ return NETDEV_TX_OK;
+
+out_drop:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+/**
+ * i40e_fcoe_change_mtu - NDO callback to change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns error as operation not permitted
+ *
+ **/
+static int i40e_fcoe_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ netdev_warn(netdev, "MTU change is not supported on FCoE interfaces\n");
+ return -EPERM;
+}
+
+/**
+ * i40e_fcoe_set_features - set the netdev feature flags
+ * @netdev: ptr to the netdev being adjusted
+ * @features: the feature set that the stack is suggesting
+ *
+ **/
+static int i40e_fcoe_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_vsi *vsi = np->vsi;
+
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ i40e_vlan_stripping_enable(vsi);
+ else
+ i40e_vlan_stripping_disable(vsi);
+
+ return 0;
+}
+
+
+static const struct net_device_ops i40e_fcoe_netdev_ops = {
+ .ndo_open = i40e_open,
+ .ndo_stop = i40e_close,
+ .ndo_get_stats64 = i40e_get_netdev_stats_struct,
+ .ndo_set_rx_mode = i40e_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = i40e_set_mac,
+ .ndo_change_mtu = i40e_fcoe_change_mtu,
+ .ndo_do_ioctl = i40e_ioctl,
+ .ndo_tx_timeout = i40e_tx_timeout,
+ .ndo_vlan_rx_add_vid = i40e_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = i40e_vlan_rx_kill_vid,
+ .ndo_setup_tc = i40e_setup_tc,
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = i40e_netpoll,
+#endif
+ .ndo_start_xmit = i40e_fcoe_xmit_frame,
+ .ndo_fcoe_enable = i40e_fcoe_enable,
+ .ndo_fcoe_disable = i40e_fcoe_disable,
+ .ndo_fcoe_ddp_setup = i40e_fcoe_ddp_get,
+ .ndo_fcoe_ddp_done = i40e_fcoe_ddp_put,
+ .ndo_fcoe_ddp_target = i40e_fcoe_ddp_target,
+ .ndo_set_features = i40e_fcoe_set_features,
+};
+
+/**
+ * i40e_fcoe_config_netdev - prepares the VSI context for creating a FCoE VSI
+ * @vsi: pointer to the associated VSI struct
+ * @ctxt: pointer to the associated VSI context to be passed to HW
+ *
+ * Returns 0 on success or < 0 on error
+ **/
+void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi)
+{
+ struct i40e_hw *hw = &vsi->back->hw;
+ struct i40e_pf *pf = vsi->back;
+
+ if (vsi->type != I40E_VSI_FCOE)
+ return;
+
+ netdev->features = (NETIF_F_HW_VLAN_CTAG_TX |
+ NETIF_F_HW_VLAN_CTAG_RX |
+ NETIF_F_HW_VLAN_CTAG_FILTER);
+
+ netdev->vlan_features = netdev->features;
+ netdev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_TX |
+ NETIF_F_HW_VLAN_CTAG_RX |
+ NETIF_F_HW_VLAN_CTAG_FILTER);
+ netdev->fcoe_ddp_xid = I40E_FCOE_DDP_MAX - 1;
+ netdev->features |= NETIF_F_ALL_FCOE;
+ netdev->vlan_features |= NETIF_F_ALL_FCOE;
+ netdev->hw_features |= netdev->features;
+ netdev->priv_flags |= IFF_UNICAST_FLT;
+ netdev->priv_flags |= IFF_SUPP_NOFCS;
+
+ strlcpy(netdev->name, "fcoe%d", IFNAMSIZ-1);
+ netdev->mtu = FCOE_MTU;
+ SET_NETDEV_DEV(netdev, &pf->pdev->dev);
+ i40e_add_filter(vsi, hw->mac.san_addr, 0, false, false);
+ i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0, false, false);
+ i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0, false, false);
+ i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0, false, false);
+ i40e_add_filter(vsi, FIP_ALL_VN2VN_MACS, 0, false, false);
+ i40e_add_filter(vsi, FIP_ALL_P2P_MACS, 0, false, false);
+
+ /* use san mac */
+ ether_addr_copy(netdev->dev_addr, hw->mac.san_addr);
+ ether_addr_copy(netdev->perm_addr, hw->mac.san_addr);
+ /* fcoe netdev ops */
+ netdev->netdev_ops = &i40e_fcoe_netdev_ops;
+}
+
+/**
+ * i40e_fcoe_vsi_setup - allocate and set up FCoE VSI
+ * @pf: the pf that VSI is associated with
+ *
+ **/
+void i40e_fcoe_vsi_setup(struct i40e_pf *pf)
+{
+ struct i40e_vsi *vsi;
+ u16 seid;
+ int i;
+
+ if (!(pf->flags & I40E_FLAG_FCOE_ENABLED))
+ return;
+
+ BUG_ON(!pf->vsi[pf->lan_vsi]);
+
+ for (i = 0; i < pf->num_alloc_vsi; i++) {
+ vsi = pf->vsi[i];
+ if (vsi && vsi->type == I40E_VSI_FCOE) {
+ dev_warn(&pf->pdev->dev,
+ "FCoE VSI already created\n");
+ return;
+ }
+ }
+
+ seid = pf->vsi[pf->lan_vsi]->seid;
+ vsi = i40e_vsi_setup(pf, I40E_VSI_FCOE, seid, 0);
+ if (vsi) {
+ dev_dbg(&pf->pdev->dev,
+ "Successfully created FCoE VSI seid %d id %d uplink_seid %d pf seid %d\n",
+ vsi->seid, vsi->id, vsi->uplink_seid, seid);
+ } else {
+ dev_info(&pf->pdev->dev, "Failed to create FCoE VSI\n");
+ }
+}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_fcoe.h b/drivers/net/ethernet/intel/i40e/i40e_fcoe.h
new file mode 100644
index 000000000000..21e0f582031c
--- /dev/null
+++ b/drivers/net/ethernet/intel/i40e/i40e_fcoe.h
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ *
+ * Intel Ethernet Controller XL710 Family Linux Driver
+ * Copyright(c) 2013 - 2014 Intel 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.
+ *
+ * This program is distributed in the hope 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 full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ ******************************************************************************/
+
+#ifndef _I40E_FCOE_H_
+#define _I40E_FCOE_H_
+
+/* FCoE HW context helper macros */
+#define I40E_DDP_CONTEXT_DESC(R, i) \
+ (&(((struct i40e_fcoe_ddp_context_desc *)((R)->desc))[i]))
+
+#define I40E_QUEUE_CONTEXT_DESC(R, i) \
+ (&(((struct i40e_fcoe_queue_context_desc *)((R)->desc))[i]))
+
+#define I40E_FILTER_CONTEXT_DESC(R, i) \
+ (&(((struct i40e_fcoe_filter_context_desc *)((R)->desc))[i]))
+
+
+/* receive queue descriptor filter status for FCoE */
+#define I40E_RX_DESC_FLTSTAT_FCMASK 0x3
+#define I40E_RX_DESC_FLTSTAT_NOMTCH 0x0 /* no ddp context match */
+#define I40E_RX_DESC_FLTSTAT_NODDP 0x1 /* no ddp due to error */
+#define I40E_RX_DESC_FLTSTAT_DDP 0x2 /* DDPed payload, post header */
+#define I40E_RX_DESC_FLTSTAT_FCPRSP 0x3 /* FCP_RSP */
+
+/* receive queue descriptor error codes for FCoE */
+#define I40E_RX_DESC_FCOE_ERROR_MASK \
+ (I40E_RX_DESC_ERROR_L3L4E_PROT | \
+ I40E_RX_DESC_ERROR_L3L4E_FC | \
+ I40E_RX_DESC_ERROR_L3L4E_DMAC_ERR | \
+ I40E_RX_DESC_ERROR_L3L4E_DMAC_WARN)
+
+/* receive queue descriptor programming error */
+#define I40E_RX_PROG_FCOE_ERROR_TBL_FULL(e) \
+ (((e) >> I40E_RX_PROG_STATUS_DESC_FCOE_TBL_FULL_SHIFT) & 0x1)
+
+#define I40E_RX_PROG_FCOE_ERROR_CONFLICT(e) \
+ (((e) >> I40E_RX_PROG_STATUS_DESC_FCOE_CONFLICT_SHIFT) & 0x1)
+
+#define I40E_RX_PROG_FCOE_ERROR_TBL_FULL_BIT \
+ (1 << I40E_RX_PROG_STATUS_DESC_FCOE_TBL_FULL_SHIFT)
+#define I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT \
+ (1 << I40E_RX_PROG_STATUS_DESC_FCOE_CONFLICT_SHIFT)
+
+#define I40E_RX_PROG_FCOE_ERROR_INVLFAIL(e) \
+ I40E_RX_PROG_FCOE_ERROR_CONFLICT(e)
+#define I40E_RX_PROG_FCOE_ERROR_INVLFAIL_BIT \
+ I40E_RX_PROG_FCOE_ERROR_CONFLICT_BIT
+
+/* FCoE DDP related definitions */
+#define I40E_FCOE_MIN_XID 0x0000 /* the min xid supported by fcoe_sw */
+#define I40E_FCOE_MAX_XID 0x0FFF /* the max xid supported by fcoe_sw */
+#define I40E_FCOE_DDP_BUFFCNT_MAX 512 /* 9 bits bufcnt */
+#define I40E_FCOE_DDP_PTR_ALIGN 16
+#define I40E_FCOE_DDP_PTR_MAX (I40E_FCOE_DDP_BUFFCNT_MAX * sizeof(dma_addr_t))
+#define I40E_FCOE_DDP_BUF_MIN 4096
+#define I40E_FCOE_DDP_MAX 2048
+#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT 8
+
+/* supported netdev features for FCoE */
+#define I40E_FCOE_NETIF_FEATURES (NETIF_F_ALL_FCOE | \
+ NETIF_F_HW_VLAN_CTAG_TX | \
+ NETIF_F_HW_VLAN_CTAG_RX | \
+ NETIF_F_HW_VLAN_CTAG_FILTER)
+
+/* DDP context flags */
+enum i40e_fcoe_ddp_flags {
+ __I40E_FCOE_DDP_NONE = 1,
+ __I40E_FCOE_DDP_TARGET,
+ __I40E_FCOE_DDP_INITALIZED,
+ __I40E_FCOE_DDP_PROGRAMMED,
+ __I40E_FCOE_DDP_DONE,
+ __I40E_FCOE_DDP_ABORTED,
+ __I40E_FCOE_DDP_UNMAPPED,
+};
+
+/* DDP SW context struct */
+struct i40e_fcoe_ddp {
+ int len;
+ u16 xid;
+ u16 firstoff;
+ u16 lastsize;
+ u16 list_len;
+ u8 fcerr;
+ u8 prerr;
+ unsigned long flags;
+ unsigned int sgc;
+ struct scatterlist *sgl;
+ dma_addr_t udp;
+ u64 *udl;
+ struct dma_pool *pool;
+
+};
+
+struct i40e_fcoe_ddp_pool {
+ struct dma_pool *pool;
+};
+
+struct i40e_fcoe {
+ unsigned long mode;
+ atomic_t refcnt;
+ struct i40e_fcoe_ddp_pool __percpu *ddp_pool;
+ struct i40e_fcoe_ddp ddp[I40E_FCOE_DDP_MAX];
+};
+
+#endif /* _I40E_FCOE_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
index b45d8fedc5e7..732a02660330 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_hmc.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_hmc.h
@@ -127,7 +127,7 @@ struct i40e_hmc_info {
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \
(1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \
- val3 = (sd_index) | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, val1); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
@@ -146,7 +146,7 @@ struct i40e_hmc_info {
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \
- val3 = (sd_index) | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, 0); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
index 870ab1ee072c..4627588f4613 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
@@ -417,7 +417,6 @@ static i40e_status i40e_create_lan_hmc_object(struct i40e_hw *hw,
default:
ret_code = I40E_ERR_INVALID_SD_TYPE;
goto exit;
- break;
}
}
}
@@ -502,7 +501,6 @@ try_type_paged:
hw_dbg(hw, "i40e_configure_lan_hmc: Unknown SD type: %d\n",
ret_code);
goto configure_lan_hmc_out;
- break;
}
/* Configure and program the FPM registers so objects can be created */
@@ -747,6 +745,194 @@ static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
};
/**
+ * i40e_write_byte - replace HMC context byte
+ * @hmc_bits: pointer to the HMC memory
+ * @ce_info: a description of the struct to be read from
+ * @src: the struct to be read from
+ **/
+static void i40e_write_byte(u8 *hmc_bits,
+ struct i40e_context_ele *ce_info,
+ u8 *src)
+{
+ u8 src_byte, dest_byte, mask;
+ u8 *from, *dest;
+ u16 shift_width;
+
+ /* copy from the next struct field */
+ from = src + ce_info->offset;
+
+ /* prepare the bits and mask */
+ shift_width = ce_info->lsb % 8;
+ mask = ((u8)1 << ce_info->width) - 1;
+
+ src_byte = *from;
+ src_byte &= mask;
+
+ /* shift to correct alignment */
+ mask <<= shift_width;
+ src_byte <<= shift_width;
+
+ /* get the current bits from the target bit string */
+ dest = hmc_bits + (ce_info->lsb / 8);
+
+ memcpy(&dest_byte, dest, sizeof(dest_byte));
+
+ dest_byte &= ~mask; /* get the bits not changing */
+ dest_byte |= src_byte; /* add in the new bits */
+
+ /* put it all back */
+ memcpy(dest, &dest_byte, sizeof(dest_byte));
+}
+
+/**
+ * i40e_write_word - replace HMC context word
+ * @hmc_bits: pointer to the HMC memory
+ * @ce_info: a description of the struct to be read from
+ * @src: the struct to be read from
+ **/
+static void i40e_write_word(u8 *hmc_bits,
+ struct i40e_context_ele *ce_info,
+ u8 *src)
+{
+ u16 src_word, mask;
+ u8 *from, *dest;
+ u16 shift_width;
+ __le16 dest_word;
+
+ /* copy from the next struct field */
+ from = src + ce_info->offset;
+
+ /* prepare the bits and mask */
+ shift_width = ce_info->lsb % 8;
+ mask = ((u16)1 << ce_info->width) - 1;
+
+ /* don't swizzle the bits until after the mask because the mask bits
+ * will be in a different bit position on big endian machines
+ */
+ src_word = *(u16 *)from;
+ src_word &= mask;
+
+ /* shift to correct alignment */
+ mask <<= shift_width;
+ src_word <<= shift_width;
+
+ /* get the current bits from the target bit string */
+ dest = hmc_bits + (ce_info->lsb / 8);
+
+ memcpy(&dest_word, dest, sizeof(dest_word));
+
+ dest_word &= ~(cpu_to_le16(mask)); /* get the bits not changing */
+ dest_word |= cpu_to_le16(src_word); /* add in the new bits */
+
+ /* put it all back */
+ memcpy(dest, &dest_word, sizeof(dest_word));
+}
+
+/**
+ * i40e_write_dword - replace HMC context dword
+ * @hmc_bits: pointer to the HMC memory
+ * @ce_info: a description of the struct to be read from
+ * @src: the struct to be read from
+ **/
+static void i40e_write_dword(u8 *hmc_bits,
+ struct i40e_context_ele *ce_info,
+ u8 *src)
+{
+ u32 src_dword, mask;
+ u8 *from, *dest;
+ u16 shift_width;
+ __le32 dest_dword;
+
+ /* copy from the next struct field */
+ from = src + ce_info->offset;
+
+ /* prepare the bits and mask */
+ shift_width = ce_info->lsb % 8;
+
+ /* if the field width is exactly 32 on an x86 machine, then the shift
+ * operation will not work because the SHL instructions count is masked
+ * to 5 bits so the shift will do nothing
+ */
+ if (ce_info->width < 32)
+ mask = ((u32)1 << ce_info->width) - 1;
+ else
+ mask = 0xFFFFFFFF;
+
+ /* don't swizzle the bits until after the mask because the mask bits
+ * will be in a different bit position on big endian machines
+ */
+ src_dword = *(u32 *)from;
+ src_dword &= mask;
+
+ /* shift to correct alignment */
+ mask <<= shift_width;
+ src_dword <<= shift_width;
+
+ /* get the current bits from the target bit string */
+ dest = hmc_bits + (ce_info->lsb / 8);
+
+ memcpy(&dest_dword, dest, sizeof(dest_dword));
+
+ dest_dword &= ~(cpu_to_le32(mask)); /* get the bits not changing */
+ dest_dword |= cpu_to_le32(src_dword); /* add in the new bits */
+
+ /* put it all back */
+ memcpy(dest, &dest_dword, sizeof(dest_dword));
+}
+
+/**
+ * i40e_write_qword - replace HMC context qword
+ * @hmc_bits: pointer to the HMC memory
+ * @ce_info: a description of the struct to be read from
+ * @src: the struct to be read from
+ **/
+static void i40e_write_qword(u8 *hmc_bits,
+ struct i40e_context_ele *ce_info,
+ u8 *src)
+{
+ u64 src_qword, mask;
+ u8 *from, *dest;
+ u16 shift_width;
+ __le64 dest_qword;
+
+ /* copy from the next struct field */
+ from = src + ce_info->offset;
+
+ /* prepare the bits and mask */
+ shift_width = ce_info->lsb % 8;
+
+ /* if the field width is exactly 64 on an x86 machine, then the shift
+ * operation will not work because the SHL instructions count is masked
+ * to 6 bits so the shift will do nothing
+ */
+ if (ce_info->width < 64)
+ mask = ((u64)1 << ce_info->width) - 1;
+ else
+ mask = 0xFFFFFFFFFFFFFFFF;
+
+ /* don't swizzle the bits until after the mask because the mask bits
+ * will be in a different bit position on big endian machines
+ */
+ src_qword = *(u64 *)from;
+ src_qword &= mask;
+
+ /* shift to correct alignment */
+ mask <<= shift_width;
+ src_qword <<= shift_width;
+
+ /* get the current bits from the target bit string */
+ dest = hmc_bits + (ce_info->lsb / 8);
+
+ memcpy(&dest_qword, dest, sizeof(dest_qword));
+
+ dest_qword &= ~(cpu_to_le64(mask)); /* get the bits not changing */
+ dest_qword |= cpu_to_le64(src_qword); /* add in the new bits */
+
+ /* put it all back */
+ memcpy(dest, &dest_qword, sizeof(dest_qword));
+}
+
+/**
* i40e_clear_hmc_context - zero out the HMC context bits
* @hw: the hardware struct
* @context_bytes: pointer to the context bit array (DMA memory)
@@ -772,71 +958,28 @@ static i40e_status i40e_set_hmc_context(u8 *context_bytes,
struct i40e_context_ele *ce_info,
u8 *dest)
{
- u16 shift_width;
- u64 bitfield;
- u8 hi_byte;
- u8 hi_mask;
- u64 t_bits;
- u64 mask;
- u8 *p;
int f;
for (f = 0; ce_info[f].width != 0; f++) {
- /* clear out the field */
- bitfield = 0;
- /* copy from the next struct field */
- p = dest + ce_info[f].offset;
+ /* we have to deal with each element of the HMC using the
+ * correct size so that we are correct regardless of the
+ * endianness of the machine
+ */
switch (ce_info[f].size_of) {
case 1:
- bitfield = *p;
+ i40e_write_byte(context_bytes, &ce_info[f], dest);
break;
case 2:
- bitfield = cpu_to_le16(*(u16 *)p);
+ i40e_write_word(context_bytes, &ce_info[f], dest);
break;
case 4:
- bitfield = cpu_to_le32(*(u32 *)p);
+ i40e_write_dword(context_bytes, &ce_info[f], dest);
break;
case 8:
- bitfield = cpu_to_le64(*(u64 *)p);
+ i40e_write_qword(context_bytes, &ce_info[f], dest);
break;
}
-
- /* prepare the bits and mask */
- shift_width = ce_info[f].lsb % 8;
- mask = ((u64)1 << ce_info[f].width) - 1;
-
- /* save upper bytes for special case */
- hi_mask = (u8)((mask >> 56) & 0xff);
- hi_byte = (u8)((bitfield >> 56) & 0xff);
-
- /* shift to correct alignment */
- mask <<= shift_width;
- bitfield <<= shift_width;
-
- /* get the current bits from the target bit string */
- p = context_bytes + (ce_info[f].lsb / 8);
- memcpy(&t_bits, p, sizeof(u64));
-
- t_bits &= ~mask; /* get the bits not changing */
- t_bits |= bitfield; /* add in the new bits */
-
- /* put it all back */
- memcpy(p, &t_bits, sizeof(u64));
-
- /* deal with the special case if needed
- * example: 62 bit field that starts in bit 5 of first byte
- * will overlap 3 bits into byte 9
- */
- if ((shift_width + ce_info[f].width) > 64) {
- u8 byte;
-
- hi_mask >>= (8 - shift_width);
- hi_byte >>= (8 - shift_width);
- byte = p[8] & ~hi_mask; /* get the bits not changing */
- byte |= hi_byte; /* add in the new bits */
- p[8] = byte; /* put it back */
- }
}
return 0;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
index eb65fe23c4a7..e74128db5be5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
@@ -32,16 +32,22 @@ struct i40e_hw;
/* HMC element context information */
-/* Rx queue context data */
+/* Rx queue context data
+ *
+ * The sizes of the variables may be larger than needed due to crossing byte
+ * boundaries. If we do not have the width of the variable set to the correct
+ * size then we could end up shifting bits off the top of the variable when the
+ * variable is at the top of a byte and crosses over into the next byte.
+ */
struct i40e_hmc_obj_rxq {
u16 head;
- u8 cpuid;
+ u16 cpuid; /* bigger than needed, see above for reason */
u64 base;
u16 qlen;
#define I40E_RXQ_CTX_DBUFF_SHIFT 7
- u8 dbuff;
+ u16 dbuff; /* bigger than needed, see above for reason */
#define I40E_RXQ_CTX_HBUFF_SHIFT 6
- u8 hbuff;
+ u16 hbuff; /* bigger than needed, see above for reason */
u8 dtype;
u8 dsize;
u8 crcstrip;
@@ -50,16 +56,22 @@ struct i40e_hmc_obj_rxq {
u8 hsplit_0;
u8 hsplit_1;
u8 showiv;
- u16 rxmax;
+ u32 rxmax; /* bigger than needed, see above for reason */
u8 tphrdesc_ena;
u8 tphwdesc_ena;
u8 tphdata_ena;
u8 tphhead_ena;
- u8 lrxqthresh;
+ u16 lrxqthresh; /* bigger than needed, see above for reason */
u8 prefena; /* NOTE: normally must be set to 1 at init */
};
-/* Tx queue context data */
+/* Tx queue context data
+*
+* The sizes of the variables may be larger than needed due to crossing byte
+* boundaries. If we do not have the width of the variable set to the correct
+* size then we could end up shifting bits off the top of the variable when the
+* variable is at the top of a byte and crosses over into the next byte.
+*/
struct i40e_hmc_obj_txq {
u16 head;
u8 new_context;
@@ -69,7 +81,7 @@ struct i40e_hmc_obj_txq {
u8 fd_ena;
u8 alt_vlan_ena;
u16 thead_wb;
- u16 cpuid;
+ u8 cpuid;
u8 head_wb_ena;
u16 qlen;
u8 tphrdesc_ena;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 275ca9a1719e..51bc03072ed3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
#define DRV_VERSION_MAJOR 0
#define DRV_VERSION_MINOR 4
-#define DRV_VERSION_BUILD 10
+#define DRV_VERSION_BUILD 21
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
@@ -269,7 +269,11 @@ static void i40e_service_event_schedule(struct i40e_pf *pf)
* device is munged, not just the one netdev port, so go for the full
* reset.
**/
+#ifdef I40E_FCOE
+void i40e_tx_timeout(struct net_device *netdev)
+#else
static void i40e_tx_timeout(struct net_device *netdev)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -278,7 +282,7 @@ static void i40e_tx_timeout(struct net_device *netdev)
pf->tx_timeout_count++;
if (time_after(jiffies, (pf->tx_timeout_last_recovery + HZ*20)))
- pf->tx_timeout_recovery_level = 0;
+ pf->tx_timeout_recovery_level = 1;
pf->tx_timeout_last_recovery = jiffies;
netdev_info(netdev, "tx_timeout recovery level %d\n",
pf->tx_timeout_recovery_level);
@@ -304,8 +308,8 @@ static void i40e_tx_timeout(struct net_device *netdev)
break;
default:
netdev_err(netdev, "tx_timeout recovery unsuccessful\n");
- set_bit(__I40E_DOWN, &vsi->state);
- i40e_down(vsi);
+ set_bit(__I40E_DOWN_REQUESTED, &pf->state);
+ set_bit(__I40E_DOWN_REQUESTED, &vsi->state);
break;
}
i40e_service_event_schedule(pf);
@@ -349,9 +353,15 @@ struct rtnl_link_stats64 *i40e_get_vsi_stats_struct(struct i40e_vsi *vsi)
* Returns the address of the device statistics structure.
* The statistics are actually updated from the service task.
**/
+#ifdef I40E_FCOE
+struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
+ struct net_device *netdev,
+ struct rtnl_link_stats64 *stats)
+#else
static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
struct net_device *netdev,
struct rtnl_link_stats64 *stats)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_ring *tx_ring, *rx_ring;
@@ -444,9 +454,21 @@ void i40e_vsi_reset_stats(struct i40e_vsi *vsi)
**/
void i40e_pf_reset_stats(struct i40e_pf *pf)
{
+ int i;
+
memset(&pf->stats, 0, sizeof(pf->stats));
memset(&pf->stats_offsets, 0, sizeof(pf->stats_offsets));
pf->stat_offsets_loaded = false;
+
+ for (i = 0; i < I40E_MAX_VEB; i++) {
+ if (pf->veb[i]) {
+ memset(&pf->veb[i]->stats, 0,
+ sizeof(pf->veb[i]->stats));
+ memset(&pf->veb[i]->stats_offsets, 0,
+ sizeof(pf->veb[i]->stats_offsets));
+ pf->veb[i]->stat_offsets_loaded = false;
+ }
+ }
}
/**
@@ -624,6 +646,55 @@ static void i40e_update_veb_stats(struct i40e_veb *veb)
veb->stat_offsets_loaded = true;
}
+#ifdef I40E_FCOE
+/**
+ * i40e_update_fcoe_stats - Update FCoE-specific ethernet statistics counters.
+ * @vsi: the VSI that is capable of doing FCoE
+ **/
+static void i40e_update_fcoe_stats(struct i40e_vsi *vsi)
+{
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ struct i40e_fcoe_stats *ofs;
+ struct i40e_fcoe_stats *fs; /* device's eth stats */
+ int idx;
+
+ if (vsi->type != I40E_VSI_FCOE)
+ return;
+
+ idx = (pf->pf_seid - I40E_BASE_PF_SEID) + I40E_FCOE_PF_STAT_OFFSET;
+ fs = &vsi->fcoe_stats;
+ ofs = &vsi->fcoe_stats_offsets;
+
+ i40e_stat_update32(hw, I40E_GL_FCOEPRC(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->rx_fcoe_packets, &fs->rx_fcoe_packets);
+ i40e_stat_update48(hw, I40E_GL_FCOEDWRCH(idx), I40E_GL_FCOEDWRCL(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->rx_fcoe_dwords, &fs->rx_fcoe_dwords);
+ i40e_stat_update32(hw, I40E_GL_FCOERPDC(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->rx_fcoe_dropped, &fs->rx_fcoe_dropped);
+ i40e_stat_update32(hw, I40E_GL_FCOEPTC(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->tx_fcoe_packets, &fs->tx_fcoe_packets);
+ i40e_stat_update48(hw, I40E_GL_FCOEDWTCH(idx), I40E_GL_FCOEDWTCL(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->tx_fcoe_dwords, &fs->tx_fcoe_dwords);
+ i40e_stat_update32(hw, I40E_GL_FCOECRC(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->fcoe_bad_fccrc, &fs->fcoe_bad_fccrc);
+ i40e_stat_update32(hw, I40E_GL_FCOELAST(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->fcoe_last_error, &fs->fcoe_last_error);
+ i40e_stat_update32(hw, I40E_GL_FCOEDDPC(idx),
+ vsi->fcoe_stat_offsets_loaded,
+ &ofs->fcoe_ddp_count, &fs->fcoe_ddp_count);
+
+ vsi->fcoe_stat_offsets_loaded = true;
+}
+
+#endif
/**
* i40e_update_link_xoff_rx - Update XOFF received in link flow control mode
* @pf: the corresponding PF
@@ -1052,6 +1123,9 @@ void i40e_update_stats(struct i40e_vsi *vsi)
i40e_update_pf_stats(pf);
i40e_update_vsi_stats(vsi);
+#ifdef I40E_FCOE
+ i40e_update_fcoe_stats(vsi);
+#endif
}
/**
@@ -1303,7 +1377,11 @@ void i40e_del_filter(struct i40e_vsi *vsi,
*
* Returns 0 on success, negative on failure
**/
+#ifdef I40E_FCOE
+int i40e_set_mac(struct net_device *netdev, void *p)
+#else
static int i40e_set_mac(struct net_device *netdev, void *p)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -1315,9 +1393,6 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
netdev_info(netdev, "set mac address=%pM\n", addr->sa_data);
- if (ether_addr_equal(netdev->dev_addr, addr->sa_data))
- return 0;
-
if (test_bit(__I40E_DOWN, &vsi->back->state) ||
test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
return -EADDRNOTAVAIL;
@@ -1325,7 +1400,7 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
if (vsi->type == I40E_VSI_MAIN) {
i40e_status ret;
ret = i40e_aq_mac_address_write(&vsi->back->hw,
- I40E_AQC_WRITE_TYPE_LAA_ONLY,
+ I40E_AQC_WRITE_TYPE_LAA_WOL,
addr->sa_data, NULL);
if (ret) {
netdev_info(netdev,
@@ -1333,22 +1408,27 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
ret);
return -EADDRNOTAVAIL;
}
-
- ether_addr_copy(vsi->back->hw.mac.addr, addr->sa_data);
}
- /* In order to be sure to not drop any packets, add the new address
- * then delete the old one.
- */
- f = i40e_add_filter(vsi, addr->sa_data, I40E_VLAN_ANY, false, false);
- if (!f)
- return -ENOMEM;
+ f = i40e_find_mac(vsi, addr->sa_data, false, true);
+ if (!f) {
+ /* In order to be sure to not drop any packets, add the
+ * new address first then delete the old one.
+ */
+ f = i40e_add_filter(vsi, addr->sa_data, I40E_VLAN_ANY,
+ false, false);
+ if (!f)
+ return -ENOMEM;
- i40e_sync_vsi_filters(vsi);
- i40e_del_filter(vsi, netdev->dev_addr, I40E_VLAN_ANY, false, false);
- i40e_sync_vsi_filters(vsi);
+ i40e_sync_vsi_filters(vsi);
+ i40e_del_filter(vsi, netdev->dev_addr, I40E_VLAN_ANY,
+ false, false);
+ i40e_sync_vsi_filters(vsi);
+ }
- ether_addr_copy(netdev->dev_addr, addr->sa_data);
+ f->is_laa = true;
+ if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
+ ether_addr_copy(netdev->dev_addr, addr->sa_data);
return 0;
}
@@ -1362,10 +1442,17 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
*
* Setup VSI queue mapping for enabled traffic classes.
**/
+#ifdef I40E_FCOE
+void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
+ struct i40e_vsi_context *ctxt,
+ u8 enabled_tc,
+ bool is_add)
+#else
static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
struct i40e_vsi_context *ctxt,
u8 enabled_tc,
bool is_add)
+#endif
{
struct i40e_pf *pf = vsi->back;
u16 sections = 0;
@@ -1411,6 +1498,11 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
case I40E_VSI_MAIN:
qcount = min_t(int, pf->rss_size, num_tc_qps);
break;
+#ifdef I40E_FCOE
+ case I40E_VSI_FCOE:
+ qcount = num_tc_qps;
+ break;
+#endif
case I40E_VSI_FDIR:
case I40E_VSI_SRIOV:
case I40E_VSI_VMDQ2:
@@ -1477,7 +1569,11 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
* i40e_set_rx_mode - NDO callback to set the netdev filters
* @netdev: network interface device structure
**/
+#ifdef I40E_FCOE
+void i40e_set_rx_mode(struct net_device *netdev)
+#else
static void i40e_set_rx_mode(struct net_device *netdev)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_mac_filter *f, *ftmp;
@@ -2055,8 +2151,13 @@ int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
*
* net_device_ops implementation for adding vlan ids
**/
+#ifdef I40E_FCOE
+int i40e_vlan_rx_add_vid(struct net_device *netdev,
+ __always_unused __be16 proto, u16 vid)
+#else
static int i40e_vlan_rx_add_vid(struct net_device *netdev,
__always_unused __be16 proto, u16 vid)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -2089,8 +2190,13 @@ static int i40e_vlan_rx_add_vid(struct net_device *netdev,
*
* net_device_ops implementation for removing vlan ids
**/
+#ifdef I40E_FCOE
+int i40e_vlan_rx_kill_vid(struct net_device *netdev,
+ __always_unused __be16 proto, u16 vid)
+#else
static int i40e_vlan_rx_kill_vid(struct net_device *netdev,
__always_unused __be16 proto, u16 vid)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -2222,6 +2328,9 @@ static int i40e_vsi_setup_rx_resources(struct i40e_vsi *vsi)
for (i = 0; i < vsi->num_queue_pairs && !err; i++)
err = i40e_setup_rx_descriptors(vsi->rx_rings[i]);
+#ifdef I40E_FCOE
+ i40e_fcoe_setup_ddp_resources(vsi);
+#endif
return err;
}
@@ -2241,6 +2350,9 @@ static void i40e_vsi_free_rx_resources(struct i40e_vsi *vsi)
for (i = 0; i < vsi->num_queue_pairs; i++)
if (vsi->rx_rings[i] && vsi->rx_rings[i]->desc)
i40e_free_rx_resources(vsi->rx_rings[i]);
+#ifdef I40E_FCOE
+ i40e_fcoe_free_ddp_resources(vsi);
+#endif
}
/**
@@ -2282,6 +2394,9 @@ static int i40e_configure_tx_ring(struct i40e_ring *ring)
tx_ctx.qlen = ring->count;
tx_ctx.fd_ena = !!(vsi->back->flags & (I40E_FLAG_FD_SB_ENABLED |
I40E_FLAG_FD_ATR_ENABLED));
+#ifdef I40E_FCOE
+ tx_ctx.fc_ena = (vsi->type == I40E_VSI_FCOE);
+#endif
tx_ctx.timesync_ena = !!(vsi->back->flags & I40E_FLAG_PTP);
/* FDIR VSI tx ring can still use RS bit and writebacks */
if (vsi->type != I40E_VSI_FDIR)
@@ -2387,10 +2502,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
rx_ctx.rxmax = min_t(u16, vsi->max_frame,
(chain_len * ring->rx_buf_len));
- rx_ctx.tphrdesc_ena = 1;
- rx_ctx.tphwdesc_ena = 1;
- rx_ctx.tphdata_ena = 1;
- rx_ctx.tphhead_ena = 1;
if (hw->revision_id == 0)
rx_ctx.lrxqthresh = 0;
else
@@ -2398,6 +2509,9 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
rx_ctx.crcstrip = 1;
rx_ctx.l2tsel = 1;
rx_ctx.showiv = 1;
+#ifdef I40E_FCOE
+ rx_ctx.fc_ena = (vsi->type == I40E_VSI_FCOE);
+#endif
/* set the prefena field to 1 because the manual says to */
rx_ctx.prefena = 1;
@@ -2482,6 +2596,17 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
break;
}
+#ifdef I40E_FCOE
+ /* setup rx buffer for FCoE */
+ if ((vsi->type == I40E_VSI_FCOE) &&
+ (vsi->back->flags & I40E_FLAG_FCOE_ENABLED)) {
+ vsi->rx_hdr_len = 0;
+ vsi->rx_buf_len = I40E_RXBUFFER_3072;
+ vsi->max_frame = I40E_RXBUFFER_3072;
+ vsi->dtype = I40E_RX_DTYPE_NO_SPLIT;
+ }
+
+#endif /* I40E_FCOE */
/* round up for the chip's needs */
vsi->rx_hdr_len = ALIGN(vsi->rx_hdr_len,
(1 << I40E_RXQ_CTX_HBUFF_SHIFT));
@@ -2756,6 +2881,22 @@ void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector)
}
/**
+ * i40e_irq_dynamic_disable - Disable default interrupt generation settings
+ * @vsi: pointer to a vsi
+ * @vector: enable a particular Hw Interrupt vector
+ **/
+void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector)
+{
+ struct i40e_pf *pf = vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+ u32 val;
+
+ val = I40E_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
+ wr32(hw, I40E_PFINT_DYN_CTLN(vector - 1), val);
+ i40e_flush(hw);
+}
+
+/**
* i40e_msix_clean_rings - MSIX mode Interrupt Handler
* @irq: interrupt number
* @data: pointer to a q_vector
@@ -3057,16 +3198,33 @@ static bool i40e_clean_fdir_tx_irq(struct i40e_ring *tx_ring, int budget)
/* clear next_to_watch to prevent false hangs */
tx_buf->next_to_watch = NULL;
+ tx_desc->buffer_addr = 0;
+ tx_desc->cmd_type_offset_bsz = 0;
+ /* move past filter desc */
+ tx_buf++;
+ tx_desc++;
+ i++;
+ if (unlikely(!i)) {
+ i -= tx_ring->count;
+ tx_buf = tx_ring->tx_bi;
+ tx_desc = I40E_TX_DESC(tx_ring, 0);
+ }
/* unmap skb header data */
dma_unmap_single(tx_ring->dev,
dma_unmap_addr(tx_buf, dma),
dma_unmap_len(tx_buf, len),
DMA_TO_DEVICE);
+ if (tx_buf->tx_flags & I40E_TX_FLAGS_FD_SB)
+ kfree(tx_buf->raw_buf);
+ tx_buf->raw_buf = NULL;
+ tx_buf->tx_flags = 0;
+ tx_buf->next_to_watch = NULL;
dma_unmap_len_set(tx_buf, len, 0);
+ tx_desc->buffer_addr = 0;
+ tx_desc->cmd_type_offset_bsz = 0;
-
- /* move to the next desc and buffer to clean */
+ /* move us past the eop_desc for start of next FD desc */
tx_buf++;
tx_desc++;
i++;
@@ -3151,8 +3309,12 @@ static void i40e_vsi_map_rings_to_vectors(struct i40e_vsi *vsi)
/* If we don't have enough vectors for a 1-to-1 mapping, we'll have to
* group them so there are multiple queues per vector.
+ * It is also important to go through all the vectors available to be
+ * sure that if we don't use all the vectors, that the remaining vectors
+ * are cleared. This is especially important when decreasing the
+ * number of queues in use.
*/
- for (; v_start < q_vectors && qp_remaining; v_start++) {
+ for (; v_start < q_vectors; v_start++) {
struct i40e_q_vector *q_vector = vsi->q_vectors[v_start];
num_ringpairs = DIV_ROUND_UP(qp_remaining, q_vectors - v_start);
@@ -3205,7 +3367,11 @@ static int i40e_vsi_request_irq(struct i40e_vsi *vsi, char *basename)
* This is used by netconsole to send skbs without having to re-enable
* interrupts. It's not called while the normal interrupt routine is executing.
**/
+#ifdef I40E_FCOE
+void i40e_netpoll(struct net_device *netdev)
+#else
static void i40e_netpoll(struct net_device *netdev)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -3228,6 +3394,35 @@ static void i40e_netpoll(struct net_device *netdev)
#endif
/**
+ * i40e_pf_txq_wait - Wait for a PF's Tx queue to be enabled or disabled
+ * @pf: the PF being configured
+ * @pf_q: the PF queue
+ * @enable: enable or disable state of the queue
+ *
+ * This routine will wait for the given Tx queue of the PF to reach the
+ * enabled or disabled state.
+ * Returns -ETIMEDOUT in case of failing to reach the requested state after
+ * multiple retries; else will return 0 in case of success.
+ **/
+static int i40e_pf_txq_wait(struct i40e_pf *pf, int pf_q, bool enable)
+{
+ int i;
+ u32 tx_reg;
+
+ for (i = 0; i < I40E_QUEUE_WAIT_RETRY_LIMIT; i++) {
+ tx_reg = rd32(&pf->hw, I40E_QTX_ENA(pf_q));
+ if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
+ break;
+
+ udelay(10);
+ }
+ if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+/**
* i40e_vsi_control_tx - Start or stop a VSI's rings
* @vsi: the VSI being configured
* @enable: start or stop the rings
@@ -3236,7 +3431,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
{
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
- int i, j, pf_q;
+ int i, j, pf_q, ret = 0;
u32 tx_reg;
pf_q = vsi->base_queue;
@@ -3269,22 +3464,46 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
wr32(hw, I40E_QTX_ENA(pf_q), tx_reg);
/* wait for the change to finish */
- for (j = 0; j < 10; j++) {
- tx_reg = rd32(hw, I40E_QTX_ENA(pf_q));
- if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
- break;
-
- udelay(10);
- }
- if (j >= 10) {
- dev_info(&pf->pdev->dev, "Tx ring %d %sable timeout\n",
- pf_q, (enable ? "en" : "dis"));
- return -ETIMEDOUT;
+ ret = i40e_pf_txq_wait(pf, pf_q, enable);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: VSI seid %d Tx ring %d %sable timeout\n",
+ __func__, vsi->seid, pf_q,
+ (enable ? "en" : "dis"));
+ break;
}
}
if (hw->revision_id == 0)
mdelay(50);
+ return ret;
+}
+
+/**
+ * i40e_pf_rxq_wait - Wait for a PF's Rx queue to be enabled or disabled
+ * @pf: the PF being configured
+ * @pf_q: the PF queue
+ * @enable: enable or disable state of the queue
+ *
+ * This routine will wait for the given Rx queue of the PF to reach the
+ * enabled or disabled state.
+ * Returns -ETIMEDOUT in case of failing to reach the requested state after
+ * multiple retries; else will return 0 in case of success.
+ **/
+static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, bool enable)
+{
+ int i;
+ u32 rx_reg;
+
+ for (i = 0; i < I40E_QUEUE_WAIT_RETRY_LIMIT; i++) {
+ rx_reg = rd32(&pf->hw, I40E_QRX_ENA(pf_q));
+ if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
+ break;
+
+ udelay(10);
+ }
+ if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT)
+ return -ETIMEDOUT;
return 0;
}
@@ -3298,7 +3517,7 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
{
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
- int i, j, pf_q;
+ int i, j, pf_q, ret = 0;
u32 rx_reg;
pf_q = vsi->base_queue;
@@ -3323,22 +3542,17 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
wr32(hw, I40E_QRX_ENA(pf_q), rx_reg);
/* wait for the change to finish */
- for (j = 0; j < 10; j++) {
- rx_reg = rd32(hw, I40E_QRX_ENA(pf_q));
-
- if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
- break;
-
- udelay(10);
- }
- if (j >= 10) {
- dev_info(&pf->pdev->dev, "Rx ring %d %sable timeout\n",
- pf_q, (enable ? "en" : "dis"));
- return -ETIMEDOUT;
+ ret = i40e_pf_rxq_wait(pf, pf_q, enable);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+ "%s: VSI seid %d Rx ring %d %sable timeout\n",
+ __func__, vsi->seid, pf_q,
+ (enable ? "en" : "dis"));
+ break;
}
}
- return 0;
+ return ret;
}
/**
@@ -4107,12 +4321,20 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf)
continue;
/* - Enable all TCs for the LAN VSI
+#ifdef I40E_FCOE
+ * - For FCoE VSI only enable the TC configured
+ * as per the APP TLV
+#endif
* - For all others keep them at TC0 for now
*/
if (v == pf->lan_vsi)
tc_map = i40e_pf_get_tc_map(pf);
else
tc_map = i40e_pf_get_default_tc(pf);
+#ifdef I40E_FCOE
+ if (pf->vsi[v]->type == I40E_VSI_FCOE)
+ tc_map = i40e_get_fcoe_tc_map(pf);
+#endif /* #ifdef I40E_FCOE */
ret = i40e_vsi_config_tc(pf->vsi[v], tc_map);
if (ret) {
@@ -4231,8 +4453,12 @@ static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
static int i40e_up_complete(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
+ u8 set_fc_aq_fail = 0;
int err;
+ /* force flow control off */
+ i40e_set_fc(&pf->hw, &set_fc_aq_fail, true);
+
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
i40e_vsi_configure_msix(vsi);
else
@@ -4335,7 +4561,11 @@ void i40e_down(struct i40e_vsi *vsi)
* @netdev: net device to configure
* @tc: number of traffic classes to enable
**/
+#ifdef I40E_FCOE
+int i40e_setup_tc(struct net_device *netdev, u8 tc)
+#else
static int i40e_setup_tc(struct net_device *netdev, u8 tc)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -4400,7 +4630,11 @@ exit:
*
* Returns 0 on success, negative value on failure
**/
+#ifdef I40E_FCOE
+int i40e_open(struct net_device *netdev)
+#else
static int i40e_open(struct net_device *netdev)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -4536,7 +4770,11 @@ static void i40e_fdir_filter_exit(struct i40e_pf *pf)
*
* Returns 0, this is not allowed to fail
**/
+#ifdef I40E_FCOE
+int i40e_close(struct net_device *netdev)
+#else
static int i40e_close(struct net_device *netdev)
+#endif
{
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
@@ -4640,6 +4878,23 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags)
/* no further action needed, so return now */
return;
+ } else if (reset_flags & (1 << __I40E_DOWN_REQUESTED)) {
+ int v;
+
+ /* Find the VSI(s) that needs to be brought down */
+ dev_info(&pf->pdev->dev, "VSI down requested\n");
+ for (v = 0; v < pf->num_alloc_vsi; v++) {
+ struct i40e_vsi *vsi = pf->vsi[v];
+ if (vsi != NULL &&
+ test_bit(__I40E_DOWN_REQUESTED, &vsi->state)) {
+ set_bit(__I40E_DOWN, &vsi->state);
+ i40e_down(vsi);
+ clear_bit(__I40E_DOWN_REQUESTED, &vsi->state);
+ }
+ }
+
+ /* no further action needed, so return now */
+ return;
} else {
dev_info(&pf->pdev->dev,
"bad reset request 0x%08x\n", reset_flags);
@@ -4845,7 +5100,20 @@ static void i40e_service_event_complete(struct i40e_pf *pf)
}
/**
- * i40e_get_current_fd_count - Get the count of FD filters programmed in the HW
+ * i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
+ * @pf: board private structure
+ **/
+int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf)
+{
+ int val, fcnt_prog;
+
+ val = rd32(&pf->hw, I40E_PFQF_FDSTAT);
+ fcnt_prog = (val & I40E_PFQF_FDSTAT_GUARANT_CNT_MASK);
+ return fcnt_prog;
+}
+
+/**
+ * i40e_get_current_fd_count - Get the count of total FD filters programmed
* @pf: board private structure
**/
int i40e_get_current_fd_count(struct i40e_pf *pf)
@@ -4857,7 +5125,6 @@ int i40e_get_current_fd_count(struct i40e_pf *pf)
I40E_PFQF_FDSTAT_BEST_CNT_SHIFT);
return fcnt_prog;
}
-
/**
* i40e_fdir_check_and_reenable - Function to reenabe FD ATR or SB if disabled
* @pf: board private structure
@@ -4872,8 +5139,8 @@ void i40e_fdir_check_and_reenable(struct i40e_pf *pf)
if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
(pf->flags & I40E_FLAG_FD_SB_ENABLED))
return;
- fcnt_prog = i40e_get_current_fd_count(pf);
- fcnt_avail = i40e_get_fd_cnt_all(pf);
+ fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
+ fcnt_avail = pf->fdir_pf_filter_count;
if (fcnt_prog < (fcnt_avail - I40E_FDIR_BUFFER_HEAD_ROOM)) {
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
(pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
@@ -4922,6 +5189,9 @@ static void i40e_vsi_link_event(struct i40e_vsi *vsi, bool link_up)
switch (vsi->type) {
case I40E_VSI_MAIN:
+#ifdef I40E_FCOE
+ case I40E_VSI_FCOE:
+#endif
if (!vsi->netdev || !vsi->netdev_registered)
break;
@@ -5110,6 +5380,10 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
reset_flags |= (1 << __I40E_GLOBAL_RESET_REQUESTED);
clear_bit(__I40E_GLOBAL_RESET_REQUESTED, &pf->state);
}
+ if (test_bit(__I40E_DOWN_REQUESTED, &pf->state)) {
+ reset_flags |= (1 << __I40E_DOWN_REQUESTED);
+ clear_bit(__I40E_DOWN_REQUESTED, &pf->state);
+ }
/* If there's a recovery already waiting, it takes
* precedence before starting a new reset sequence.
@@ -5164,7 +5438,7 @@ static void i40e_handle_link_event(struct i40e_pf *pf,
* then see if the status changed while processing the
* initial event.
*/
- i40e_aq_get_link_info(&pf->hw, true, NULL, NULL);
+ i40e_update_link_info(&pf->hw, true);
i40e_link_event(pf);
}
@@ -5182,9 +5456,6 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
u32 oldval;
u32 val;
- if (!test_bit(__I40E_ADMINQ_EVENT_PENDING, &pf->state))
- return;
-
/* check for error indications */
val = rd32(&pf->hw, pf->hw.aq.arq.len);
oldval = val;
@@ -5228,10 +5499,9 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
do {
event.msg_size = I40E_MAX_AQ_BUF_SIZE; /* reinit each time */
ret = i40e_clean_arq_element(hw, &event, &pending);
- if (ret == I40E_ERR_ADMIN_QUEUE_NO_WORK) {
- dev_info(&pf->pdev->dev, "No ARQ event found\n");
+ if (ret == I40E_ERR_ADMIN_QUEUE_NO_WORK)
break;
- } else if (ret) {
+ else if (ret) {
dev_info(&pf->pdev->dev, "ARQ event error %d\n", ret);
break;
}
@@ -5463,6 +5733,20 @@ static void i40e_fdir_sb_setup(struct i40e_pf *pf)
struct i40e_vsi *vsi;
int i;
+ /* quick workaround for an NVM issue that leaves a critical register
+ * uninitialized
+ */
+ if (!rd32(&pf->hw, I40E_GLQF_HKEY(0))) {
+ static const u32 hkey[] = {
+ 0xe640d33f, 0xcdfe98ab, 0x73fa7161, 0x0d7a7d36,
+ 0xeacb7d61, 0xaa4f05b6, 0x9c5c89ed, 0xfc425ddb,
+ 0xa4654832, 0xfc7461d4, 0x8f827619, 0xf5c63c21,
+ 0x95b3a76d};
+
+ for (i = 0; i <= I40E_GLQF_HKEY_MAX_INDEX; i++)
+ wr32(&pf->hw, I40E_GLQF_HKEY(i), hkey[i]);
+ }
+
if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
return;
@@ -5512,7 +5796,7 @@ static void i40e_fdir_teardown(struct i40e_pf *pf)
*
* Close up the VFs and other things in prep for pf Reset.
**/
-static int i40e_prep_for_reset(struct i40e_pf *pf)
+static void i40e_prep_for_reset(struct i40e_pf *pf)
{
struct i40e_hw *hw = &pf->hw;
i40e_status ret = 0;
@@ -5520,7 +5804,7 @@ static int i40e_prep_for_reset(struct i40e_pf *pf)
clear_bit(__I40E_RESET_INTR_RECEIVED, &pf->state);
if (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state))
- return 0;
+ return;
dev_dbg(&pf->pdev->dev, "Tearing down internal switch for reset\n");
@@ -5537,13 +5821,10 @@ static int i40e_prep_for_reset(struct i40e_pf *pf)
/* call shutdown HMC */
if (hw->hmc.hmc_obj) {
ret = i40e_shutdown_lan_hmc(hw);
- if (ret) {
+ if (ret)
dev_warn(&pf->pdev->dev,
"shutdown_lan_hmc failed: %d\n", ret);
- clear_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state);
- }
}
- return ret;
}
/**
@@ -5629,7 +5910,12 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
goto end_core_reset;
}
#endif /* CONFIG_I40E_DCB */
+#ifdef I40E_FCOE
+ ret = i40e_init_pf_fcoe(pf);
+ if (ret)
+ dev_info(&pf->pdev->dev, "init_pf_fcoe failed: %d\n", ret);
+#endif
/* do basic switch setup */
ret = i40e_setup_pf_switch(pf, reinit);
if (ret)
@@ -5679,7 +5965,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
}
if (pf->vsi[pf->lan_vsi]->uplink_seid == pf->mac_seid) {
- dev_info(&pf->pdev->dev, "attempting to rebuild PF VSI\n");
+ dev_dbg(&pf->pdev->dev, "attempting to rebuild PF VSI\n");
/* no VEB, so rebuild only the Main VSI */
ret = i40e_add_vsi(pf->vsi[pf->lan_vsi]);
if (ret) {
@@ -5717,11 +6003,8 @@ end_core_reset:
**/
static void i40e_handle_reset_warning(struct i40e_pf *pf)
{
- i40e_status ret;
-
- ret = i40e_prep_for_reset(pf);
- if (!ret)
- i40e_reset_and_rebuild(pf, false);
+ i40e_prep_for_reset(pf);
+ i40e_reset_and_rebuild(pf, false);
}
/**
@@ -5734,6 +6017,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
{
struct i40e_hw *hw = &pf->hw;
bool mdd_detected = false;
+ bool pf_mdd_detected = false;
struct i40e_vf *vf;
u32 reg;
int i;
@@ -5744,26 +6028,28 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
/* find what triggered the MDD event */
reg = rd32(hw, I40E_GL_MDET_TX);
if (reg & I40E_GL_MDET_TX_VALID_MASK) {
- u8 func = (reg & I40E_GL_MDET_TX_FUNCTION_MASK)
- >> I40E_GL_MDET_TX_FUNCTION_SHIFT;
- u8 event = (reg & I40E_GL_MDET_TX_EVENT_SHIFT)
- >> I40E_GL_MDET_TX_EVENT_SHIFT;
- u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK)
- >> I40E_GL_MDET_TX_QUEUE_SHIFT;
+ u8 pf_num = (reg & I40E_GL_MDET_TX_PF_NUM_MASK) >>
+ I40E_GL_MDET_TX_PF_NUM_SHIFT;
+ u8 vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >>
+ I40E_GL_MDET_TX_VF_NUM_SHIFT;
+ u8 event = (reg & I40E_GL_MDET_TX_EVENT_SHIFT) >>
+ I40E_GL_MDET_TX_EVENT_SHIFT;
+ u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >>
+ I40E_GL_MDET_TX_QUEUE_SHIFT;
dev_info(&pf->pdev->dev,
- "Malicious Driver Detection event 0x%02x on TX queue %d of function 0x%02x\n",
- event, queue, func);
+ "Malicious Driver Detection event 0x%02x on TX queue %d pf number 0x%02x vf number 0x%02x\n",
+ event, queue, pf_num, vf_num);
wr32(hw, I40E_GL_MDET_TX, 0xffffffff);
mdd_detected = true;
}
reg = rd32(hw, I40E_GL_MDET_RX);
if (reg & I40E_GL_MDET_RX_VALID_MASK) {
- u8 func = (reg & I40E_GL_MDET_RX_FUNCTION_MASK)
- >> I40E_GL_MDET_RX_FUNCTION_SHIFT;
- u8 event = (reg & I40E_GL_MDET_RX_EVENT_SHIFT)
- >> I40E_GL_MDET_RX_EVENT_SHIFT;
- u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK)
- >> I40E_GL_MDET_RX_QUEUE_SHIFT;
+ u8 func = (reg & I40E_GL_MDET_RX_FUNCTION_MASK) >>
+ I40E_GL_MDET_RX_FUNCTION_SHIFT;
+ u8 event = (reg & I40E_GL_MDET_RX_EVENT_SHIFT) >>
+ I40E_GL_MDET_RX_EVENT_SHIFT;
+ u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >>
+ I40E_GL_MDET_RX_QUEUE_SHIFT;
dev_info(&pf->pdev->dev,
"Malicious Driver Detection event 0x%02x on RX queue %d of function 0x%02x\n",
event, queue, func);
@@ -5771,6 +6057,30 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
mdd_detected = true;
}
+ if (mdd_detected) {
+ reg = rd32(hw, I40E_PF_MDET_TX);
+ if (reg & I40E_PF_MDET_TX_VALID_MASK) {
+ wr32(hw, I40E_PF_MDET_TX, 0xFFFF);
+ dev_info(&pf->pdev->dev,
+ "MDD TX event is for this function 0x%08x, requesting PF reset.\n",
+ reg);
+ pf_mdd_detected = true;
+ }
+ reg = rd32(hw, I40E_PF_MDET_RX);
+ if (reg & I40E_PF_MDET_RX_VALID_MASK) {
+ wr32(hw, I40E_PF_MDET_RX, 0xFFFF);
+ dev_info(&pf->pdev->dev,
+ "MDD RX event is for this function 0x%08x, requesting PF reset.\n",
+ reg);
+ pf_mdd_detected = true;
+ }
+ /* Queue belongs to the PF, initiate a reset */
+ if (pf_mdd_detected) {
+ set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
+ i40e_service_event_schedule(pf);
+ }
+ }
+
/* see if one of the VFs needs its hand slapped */
for (i = 0; i < pf->num_alloc_vfs && mdd_detected; i++) {
vf = &(pf->vf[i]);
@@ -5860,6 +6170,12 @@ static void i40e_service_task(struct work_struct *work)
service_task);
unsigned long start_time = jiffies;
+ /* don't bother with service tasks if a reset is in progress */
+ if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state)) {
+ i40e_service_event_complete(pf);
+ return;
+ }
+
i40e_reset_subtask(pf);
i40e_handle_mdd_event(pf);
i40e_vc_process_vflr_event(pf);
@@ -5938,6 +6254,15 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
I40E_REQ_DESCRIPTOR_MULTIPLE);
break;
+#ifdef I40E_FCOE
+ case I40E_VSI_FCOE:
+ vsi->alloc_queue_pairs = pf->num_fcoe_qps;
+ vsi->num_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
+ I40E_REQ_DESCRIPTOR_MULTIPLE);
+ vsi->num_q_vectors = pf->num_fcoe_msix;
+ break;
+
+#endif /* I40E_FCOE */
default:
WARN_ON(1);
return -ENODATA;
@@ -6249,6 +6574,9 @@ static int i40e_init_msix(struct i40e_pf *pf)
* is governed by number of cpus in the system.
* - assumes symmetric Tx/Rx pairing
* - The number of VMDq pairs
+#ifdef I40E_FCOE
+ * - The number of FCOE qps.
+#endif
* Once we count this up, try the request.
*
* If we can't get what we want, we'll simplify to nearly nothing
@@ -6261,6 +6589,13 @@ static int i40e_init_msix(struct i40e_pf *pf)
if (pf->flags & I40E_FLAG_FD_SB_ENABLED)
v_budget++;
+#ifdef I40E_FCOE
+ if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
+ pf->num_fcoe_msix = pf->num_fcoe_qps;
+ v_budget += pf->num_fcoe_msix;
+ }
+
+#endif
/* Scale down if necessary, and the rings will share vectors */
v_budget = min_t(int, v_budget, hw->func_caps.num_msix_vectors);
@@ -6279,6 +6614,10 @@ static int i40e_init_msix(struct i40e_pf *pf)
* of these features based on the policy and at the end disable
* the features that did not get any vectors.
*/
+#ifdef I40E_FCOE
+ pf->num_fcoe_qps = 0;
+ pf->num_fcoe_msix = 0;
+#endif
pf->num_vmdq_msix = 0;
}
@@ -6309,9 +6648,24 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->num_lan_msix = 1;
break;
case 3:
+#ifdef I40E_FCOE
+ /* give one vector to FCoE */
+ if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
+ pf->num_lan_msix = 1;
+ pf->num_fcoe_msix = 1;
+ }
+#else
pf->num_lan_msix = 2;
+#endif
break;
default:
+#ifdef I40E_FCOE
+ /* give one vector to FCoE */
+ if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
+ pf->num_fcoe_msix = 1;
+ vec--;
+ }
+#endif
pf->num_lan_msix = min_t(int, (vec / 2),
pf->num_lan_qps);
pf->num_vmdq_vsis = min_t(int, (vec - pf->num_lan_msix),
@@ -6325,6 +6679,13 @@ static int i40e_init_msix(struct i40e_pf *pf)
dev_info(&pf->pdev->dev, "VMDq disabled, not enough MSI-X vectors\n");
pf->flags &= ~I40E_FLAG_VMDQ_ENABLED;
}
+#ifdef I40E_FCOE
+
+ if ((pf->flags & I40E_FLAG_FCOE_ENABLED) && (pf->num_fcoe_msix == 0)) {
+ dev_info(&pf->pdev->dev, "FCOE disabled, not enough MSI-X vectors\n");
+ pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
+ }
+#endif
return err;
}
@@ -6408,6 +6769,9 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
err = i40e_init_msix(pf);
if (err) {
pf->flags &= ~(I40E_FLAG_MSIX_ENABLED |
+#ifdef I40E_FCOE
+ I40E_FLAG_FCOE_ENABLED |
+#endif
I40E_FLAG_RSS_ENABLED |
I40E_FLAG_DCB_CAPABLE |
I40E_FLAG_SRIOV_ENABLED |
@@ -6492,6 +6856,7 @@ static int i40e_config_rss(struct i40e_pf *pf)
u32 lut = 0;
int i, j;
u64 hena;
+ u32 reg_val;
/* Fill out hash function seed */
for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
@@ -6504,8 +6869,19 @@ static int i40e_config_rss(struct i40e_pf *pf)
wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
+ /* Check capability and Set table size and register per hw expectation*/
+ reg_val = rd32(hw, I40E_PFQF_CTL_0);
+ if (hw->func_caps.rss_table_size == 512) {
+ reg_val |= I40E_PFQF_CTL_0_HASHLUTSIZE_512;
+ pf->rss_table_size = 512;
+ } else {
+ pf->rss_table_size = 128;
+ reg_val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_512;
+ }
+ wr32(hw, I40E_PFQF_CTL_0, reg_val);
+
/* Populate the LUT with max no. of queues in round robin fashion */
- for (i = 0, j = 0; i < pf->hw.func_caps.rss_table_size; i++, j++) {
+ for (i = 0, j = 0; i < pf->rss_table_size; i++, j++) {
/* The assumption is that lan qp count will be the highest
* qp count for any PF VSI that needs RSS.
@@ -6592,13 +6968,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
* maximum might end up larger than the available queues
*/
pf->rss_size_max = 0x1 << pf->hw.func_caps.rss_table_entry_width;
+ pf->rss_size = 1;
pf->rss_size_max = min_t(int, pf->rss_size_max,
pf->hw.func_caps.num_tx_qp);
if (pf->hw.func_caps.rss) {
pf->flags |= I40E_FLAG_RSS_ENABLED;
pf->rss_size = min_t(int, pf->rss_size_max, num_online_cpus());
- } else {
- pf->rss_size = 1;
}
/* MFP mode enabled */
@@ -6634,6 +7009,12 @@ static int i40e_sw_init(struct i40e_pf *pf)
pf->num_vmdq_qps = I40E_DEFAULT_QUEUES_PER_VMDQ;
}
+#ifdef I40E_FCOE
+ err = i40e_init_pf_fcoe(pf);
+ if (err)
+ dev_info(&pf->pdev->dev, "init_pf_fcoe failed: %d\n", err);
+
+#endif /* I40E_FCOE */
#ifdef CONFIG_PCI_IOV
if (pf->hw.func_caps.num_vfs) {
pf->num_vf_qps = I40E_DEFAULT_QUEUES_PER_VF;
@@ -6670,6 +7051,8 @@ static int i40e_sw_init(struct i40e_pf *pf)
pf->irq_pile->num_entries = pf->hw.func_caps.num_msix_vectors;
pf->irq_pile->search_hint = 0;
+ pf->tx_timeout_recovery_level = 1;
+
mutex_init(&pf->switch_mutex);
sw_init_done:
@@ -6702,9 +7085,11 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
i40e_fdir_filter_exit(pf);
}
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
- /* if ATR was disabled it can be re-enabled. */
- if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED))
- pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
+ pf->auto_disable_flags &= ~I40E_FLAG_FD_SB_ENABLED;
+ /* if ATR was auto disabled it can be re-enabled. */
+ if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
+ (pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
+ pf->auto_disable_flags &= ~I40E_FLAG_FD_ATR_ENABLED;
}
return need_reset;
}
@@ -6833,6 +7218,22 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
}
#endif
+static int i40e_get_phys_port_id(struct net_device *netdev,
+ struct netdev_phys_port_id *ppid)
+{
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_hw *hw = &pf->hw;
+
+ if (!(pf->flags & I40E_FLAG_PORT_ID_VALID))
+ return -EOPNOTSUPP;
+
+ ppid->id_len = min_t(int, sizeof(hw->mac.port_addr), sizeof(ppid->id));
+ memcpy(ppid->id, hw->mac.port_addr, ppid->id_len);
+
+ return 0;
+}
+
#ifdef HAVE_FDB_OPS
#ifdef USE_CONST_DEV_UC_CHAR
static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
@@ -6910,13 +7311,14 @@ static int i40e_ndo_fdb_del(struct ndmsg *ndm,
static int i40e_ndo_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
+ struct net_device *filter_dev,
int idx)
{
struct i40e_netdev_priv *np = netdev_priv(dev);
struct i40e_pf *pf = np->vsi->back;
if (pf->flags & I40E_FLAG_SRIOV_ENABLED)
- idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, filter_dev, idx);
return idx;
}
@@ -6940,6 +7342,10 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_poll_controller = i40e_netpoll,
#endif
.ndo_setup_tc = i40e_setup_tc,
+#ifdef I40E_FCOE
+ .ndo_fcoe_enable = i40e_fcoe_enable,
+ .ndo_fcoe_disable = i40e_fcoe_disable,
+#endif
.ndo_set_features = i40e_set_features,
.ndo_set_vf_mac = i40e_ndo_set_vf_mac,
.ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan,
@@ -6951,6 +7357,7 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_add_vxlan_port = i40e_add_vxlan_port,
.ndo_del_vxlan_port = i40e_del_vxlan_port,
#endif
+ .ndo_get_phys_port_id = i40e_get_phys_port_id,
#ifdef HAVE_FDB_OPS
.ndo_fdb_add = i40e_ndo_fdb_add,
#ifndef USE_DEFAULT_FDB_DEL_DUMP
@@ -7047,6 +7454,9 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
netdev->netdev_ops = &i40e_netdev_ops;
netdev->watchdog_timeo = 5 * HZ;
i40e_set_ethtool_ops(netdev);
+#ifdef I40E_FCOE
+ i40e_fcoe_config_netdev(netdev, vsi);
+#endif
return 0;
}
@@ -7166,7 +7576,6 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
* should be set to zero by default.
*/
ctxt.info.switch_id = 0;
- ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);
ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
/* Setup the VSI tx/rx queue map for TC0 only for now */
@@ -7200,6 +7609,16 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, true);
break;
+#ifdef I40E_FCOE
+ case I40E_VSI_FCOE:
+ ret = i40e_fcoe_vsi_init(vsi, &ctxt);
+ if (ret) {
+ dev_info(&pf->pdev->dev, "failed to initialize FCoE VSI\n");
+ return ret;
+ }
+ break;
+
+#endif /* I40E_FCOE */
default:
return -ENODEV;
}
@@ -7223,6 +7642,12 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
list_for_each_entry_safe(f, ftmp, &vsi->mac_filter_list, list) {
f->changed = true;
f_count++;
+
+ if (f->is_laa && vsi->type == I40E_VSI_MAIN) {
+ i40e_aq_mac_address_write(&vsi->back->hw,
+ I40E_AQC_WRITE_TYPE_LAA_WOL,
+ f->macaddr, NULL);
+ }
}
if (f_count) {
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
@@ -7552,6 +7977,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
/* setup the netdev if needed */
case I40E_VSI_MAIN:
case I40E_VSI_VMDQ2:
+ case I40E_VSI_FCOE:
ret = i40e_config_netdev(vsi);
if (ret)
goto err_netdev;
@@ -8090,7 +8516,6 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig)
**/
static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
{
- u32 rxfc = 0, txfc = 0, rxfc_reg;
int ret;
/* find out what's out there already */
@@ -8150,68 +8575,13 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
i40e_config_rss(pf);
/* fill in link information and enable LSE reporting */
- i40e_aq_get_link_info(&pf->hw, true, NULL, NULL);
+ i40e_update_link_info(&pf->hw, true);
i40e_link_event(pf);
/* Initialize user-specific link properties */
pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info &
I40E_AQ_AN_COMPLETED) ? true : false);
- /* requested_mode is set in probe or by ethtool */
- if (!pf->fc_autoneg_status)
- goto no_autoneg;
-
- if ((pf->hw.phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX) &&
- (pf->hw.phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX))
- pf->hw.fc.current_mode = I40E_FC_FULL;
- else if (pf->hw.phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX)
- pf->hw.fc.current_mode = I40E_FC_TX_PAUSE;
- else if (pf->hw.phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX)
- pf->hw.fc.current_mode = I40E_FC_RX_PAUSE;
- else
- pf->hw.fc.current_mode = I40E_FC_NONE;
- /* sync the flow control settings with the auto-neg values */
- switch (pf->hw.fc.current_mode) {
- case I40E_FC_FULL:
- txfc = 1;
- rxfc = 1;
- break;
- case I40E_FC_TX_PAUSE:
- txfc = 1;
- rxfc = 0;
- break;
- case I40E_FC_RX_PAUSE:
- txfc = 0;
- rxfc = 1;
- break;
- case I40E_FC_NONE:
- case I40E_FC_DEFAULT:
- txfc = 0;
- rxfc = 0;
- break;
- case I40E_FC_PFC:
- /* TBD */
- break;
- /* no default case, we have to handle all possibilities here */
- }
-
- wr32(&pf->hw, I40E_PRTDCB_FCCFG, txfc << I40E_PRTDCB_FCCFG_TFCE_SHIFT);
-
- rxfc_reg = rd32(&pf->hw, I40E_PRTDCB_MFLCN) &
- ~I40E_PRTDCB_MFLCN_RFCE_MASK;
- rxfc_reg |= (rxfc << I40E_PRTDCB_MFLCN_RFCE_SHIFT);
-
- wr32(&pf->hw, I40E_PRTDCB_MFLCN, rxfc_reg);
-
- goto fc_complete;
-
-no_autoneg:
- /* disable L2 flow control, user can turn it on if they wish */
- wr32(&pf->hw, I40E_PRTDCB_FCCFG, 0);
- wr32(&pf->hw, I40E_PRTDCB_MFLCN, rd32(&pf->hw, I40E_PRTDCB_MFLCN) &
- ~I40E_PRTDCB_MFLCN_RFCE_MASK);
-
-fc_complete:
i40e_ptp_init(pf);
return ret;
@@ -8226,6 +8596,9 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
int queues_left;
pf->num_lan_qps = 0;
+#ifdef I40E_FCOE
+ pf->num_fcoe_qps = 0;
+#endif
/* Find the max queues to be put into basic use. We'll always be
* using TC0, whether or not DCB is running, and TC0 will get the
@@ -8241,6 +8614,9 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
/* make sure all the fancies are disabled */
pf->flags &= ~(I40E_FLAG_RSS_ENABLED |
+#ifdef I40E_FCOE
+ I40E_FLAG_FCOE_ENABLED |
+#endif
I40E_FLAG_FD_SB_ENABLED |
I40E_FLAG_FD_ATR_ENABLED |
I40E_FLAG_DCB_CAPABLE |
@@ -8255,6 +8631,9 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
queues_left -= pf->num_lan_qps;
pf->flags &= ~(I40E_FLAG_RSS_ENABLED |
+#ifdef I40E_FCOE
+ I40E_FLAG_FCOE_ENABLED |
+#endif
I40E_FLAG_FD_SB_ENABLED |
I40E_FLAG_FD_ATR_ENABLED |
I40E_FLAG_DCB_ENABLED |
@@ -8270,6 +8649,22 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
queues_left -= pf->num_lan_qps;
}
+#ifdef I40E_FCOE
+ if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
+ if (I40E_DEFAULT_FCOE <= queues_left) {
+ pf->num_fcoe_qps = I40E_DEFAULT_FCOE;
+ } else if (I40E_MINIMUM_FCOE <= queues_left) {
+ pf->num_fcoe_qps = I40E_MINIMUM_FCOE;
+ } else {
+ pf->num_fcoe_qps = 0;
+ pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
+ dev_info(&pf->pdev->dev, "not enough queues for FCoE. FCoE feature will be disabled\n");
+ }
+
+ queues_left -= pf->num_fcoe_qps;
+ }
+
+#endif
if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
if (queues_left > 1) {
queues_left -= 1; /* save 1 queue for FD */
@@ -8294,6 +8689,9 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
}
pf->queues_left = queues_left;
+#ifdef I40E_FCOE
+ dev_info(&pf->pdev->dev, "fcoe queues = %d\n", pf->num_fcoe_qps);
+#endif
}
/**
@@ -8360,6 +8758,10 @@ static void i40e_print_features(struct i40e_pf *pf)
buf += sprintf(buf, "DCB ");
if (pf->flags & I40E_FLAG_PTP)
buf += sprintf(buf, "PTP ");
+#ifdef I40E_FCOE
+ if (pf->flags & I40E_FLAG_FCOE_ENABLED)
+ buf += sprintf(buf, "FCOE ");
+#endif
BUG_ON(buf > (string + INFO_STRING_LEN));
dev_info(&pf->pdev->dev, "%s\n", string);
@@ -8460,6 +8862,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Reset here to make sure all is clean and to define PF 'n' */
+ i40e_clear_hw(hw);
err = i40e_pf_reset(hw);
if (err) {
dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
@@ -8489,12 +8892,20 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(&pdev->dev, "%s\n", i40e_fw_version_str(hw));
if (err) {
dev_info(&pdev->dev,
- "init_adminq failed: %d expecting API %02x.%02x\n",
- err,
- I40E_FW_API_VERSION_MAJOR, I40E_FW_API_VERSION_MINOR);
+ "The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
goto err_pf_reset;
}
+ if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
+ hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR)
+ dev_info(&pdev->dev,
+ "The driver for the device detected a newer version of the NVM image than expected. Please install the most recent version of the network driver.\n");
+ else if (hw->aq.api_maj_ver < I40E_FW_API_VERSION_MAJOR ||
+ hw->aq.api_min_ver < (I40E_FW_API_VERSION_MINOR - 1))
+ dev_info(&pdev->dev,
+ "The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
+
+
i40e_verify_eeprom(pf);
/* Rev 0 hardware was never productized */
@@ -8535,6 +8946,21 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
dev_info(&pdev->dev, "MAC address: %pM\n", hw->mac.addr);
ether_addr_copy(hw->mac.perm_addr, hw->mac.addr);
+ i40e_get_port_mac_addr(hw, hw->mac.port_addr);
+ if (is_valid_ether_addr(hw->mac.port_addr))
+ pf->flags |= I40E_FLAG_PORT_ID_VALID;
+#ifdef I40E_FCOE
+ err = i40e_get_san_mac_addr(hw, hw->mac.san_addr);
+ if (err)
+ dev_info(&pdev->dev,
+ "(non-fatal) SAN MAC retrieval failed: %d\n", err);
+ if (!is_valid_ether_addr(hw->mac.san_addr)) {
+ dev_warn(&pdev->dev, "invalid SAN MAC address %pM, falling back to LAN MAC\n",
+ hw->mac.san_addr);
+ ether_addr_copy(hw->mac.san_addr, hw->mac.addr);
+ }
+ dev_info(&pf->pdev->dev, "SAN MAC: %pM\n", hw->mac.san_addr);
+#endif /* I40E_FCOE */
pci_set_drvdata(pdev, pf);
pci_save_state(pdev);
@@ -8651,6 +9077,11 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mod_timer(&pf->service_timer,
round_jiffies(jiffies + pf->service_timer_period));
+#ifdef I40E_FCOE
+ /* create FCoE interface */
+ i40e_fcoe_vsi_setup(pf);
+
+#endif
/* Get the negotiated link width and speed from PCI config space */
pcie_capability_read_word(pf->pdev, PCI_EXP_LNKSTA, &link_status);
@@ -8722,7 +9153,6 @@ static void i40e_remove(struct pci_dev *pdev)
{
struct i40e_pf *pf = pci_get_drvdata(pdev);
i40e_status ret_code;
- u32 reg;
int i;
i40e_dbg_pf_exit(pf);
@@ -8800,11 +9230,6 @@ static void i40e_remove(struct pci_dev *pdev)
kfree(pf->irq_pile);
kfree(pf->vsi);
- /* force a PF reset to clean anything leftover */
- reg = rd32(&pf->hw, I40E_PFGEN_CTRL);
- wr32(&pf->hw, I40E_PFGEN_CTRL, (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
- i40e_flush(&pf->hw);
-
iounmap(pf->hw.hw_addr);
kfree(pf);
pci_release_selected_regions(pdev,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 81299189a47d..97bda3dffd49 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -241,6 +241,46 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
}
/**
+ * i40e_write_nvm_aq - Writes Shadow RAM.
+ * @hw: pointer to the HW structure.
+ * @module_pointer: module pointer location in words from the NVM beginning
+ * @offset: offset in words from module start
+ * @words: number of words to write
+ * @data: buffer with words to write to the Shadow RAM
+ * @last_command: tells the AdminQ that this is the last command
+ *
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
+ **/
+i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
+ u32 offset, u16 words, void *data,
+ bool last_command)
+{
+ i40e_status ret_code = I40E_ERR_NVM;
+
+ /* Here we are checking the SR limit only for the flat memory model.
+ * We cannot do it for the module-based model, as we did not acquire
+ * the NVM resource yet (we cannot get the module pointer value).
+ * Firmware will check the module-based model.
+ */
+ if ((offset + words) > hw->nvm.sr_size)
+ hw_dbg(hw, "NVM write error: offset beyond Shadow RAM limit.\n");
+ else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
+ /* We can write only up to 4KB (one sector), in one AQ write */
+ hw_dbg(hw, "NVM write fail error: cannot write more than 4KB in a single write.\n");
+ else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
+ != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
+ /* A single write cannot spread over two sectors */
+ hw_dbg(hw, "NVM write error: cannot spread over two sectors in a single write.\n");
+ else
+ ret_code = i40e_aq_update_nvm(hw, module_pointer,
+ 2 * offset, /*bytes*/
+ 2 * words, /*bytes*/
+ data, last_command, NULL);
+
+ return ret_code;
+}
+
+/**
* i40e_calc_nvm_checksum - Calculates and returns the checksum
* @hw: pointer to hardware structure
* @checksum: pointer to the checksum
@@ -310,6 +350,27 @@ i40e_calc_nvm_checksum_exit:
}
/**
+ * i40e_update_nvm_checksum - Updates the NVM checksum
+ * @hw: pointer to hardware structure
+ *
+ * NVM ownership must be acquired before calling this function and released
+ * on ARQ completion event reception by caller.
+ * This function will commit SR to NVM.
+ **/
+i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
+{
+ i40e_status ret_code = 0;
+ u16 checksum;
+
+ ret_code = i40e_calc_nvm_checksum(hw, &checksum);
+ if (!ret_code)
+ ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
+ 1, &checksum, true);
+
+ return ret_code;
+}
+
+/**
* i40e_validate_nvm_checksum - Validate EEPROM checksum
* @hw: pointer to hardware structure
* @checksum: calculated checksum
@@ -324,13 +385,9 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
u16 checksum_sr = 0;
u16 checksum_local = 0;
- ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
- if (ret_code)
- goto i40e_validate_nvm_checksum_exit;
-
ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
if (ret_code)
- goto i40e_validate_nvm_checksum_free;
+ goto i40e_validate_nvm_checksum_exit;
/* Do not use i40e_read_nvm_word() because we do not want to take
* the synchronization semaphores twice here.
@@ -347,9 +404,456 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
if (checksum)
*checksum = checksum_local;
-i40e_validate_nvm_checksum_free:
- i40e_release_nvm(hw);
-
i40e_validate_nvm_checksum_exit:
return ret_code;
}
+
+static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno);
+static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno);
+static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno);
+static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ int *errno);
+static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ int *errno);
+static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno);
+static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno);
+static inline u8 i40e_nvmupd_get_module(u32 val)
+{
+ return (u8)(val & I40E_NVM_MOD_PNT_MASK);
+}
+static inline u8 i40e_nvmupd_get_transaction(u32 val)
+{
+ return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
+}
+
+/**
+ * i40e_nvmupd_command - Process an NVM update command
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * Dispatches command depending on what update state is current
+ **/
+i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status;
+
+ /* assume success */
+ *errno = 0;
+
+ switch (hw->nvmupd_state) {
+ case I40E_NVMUPD_STATE_INIT:
+ status = i40e_nvmupd_state_init(hw, cmd, bytes, errno);
+ break;
+
+ case I40E_NVMUPD_STATE_READING:
+ status = i40e_nvmupd_state_reading(hw, cmd, bytes, errno);
+ break;
+
+ case I40E_NVMUPD_STATE_WRITING:
+ status = i40e_nvmupd_state_writing(hw, cmd, bytes, errno);
+ break;
+
+ default:
+ /* invalid state, should never happen */
+ status = I40E_NOT_SUPPORTED;
+ *errno = -ESRCH;
+ break;
+ }
+ return status;
+}
+
+/**
+ * i40e_nvmupd_state_init - Handle NVM update state Init
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * Process legitimate commands of the Init state and conditionally set next
+ * state. Reject all other commands.
+ **/
+static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status = 0;
+ enum i40e_nvmupd_cmd upd_cmd;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
+
+ switch (upd_cmd) {
+ case I40E_NVMUPD_READ_SA:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
+ i40e_release_nvm(hw);
+ }
+ break;
+
+ case I40E_NVMUPD_READ_SNT:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
+ hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
+ }
+ break;
+
+ case I40E_NVMUPD_WRITE_ERA:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_nvmupd_nvm_erase(hw, cmd, errno);
+ if (status)
+ i40e_release_nvm(hw);
+ else
+ hw->aq.nvm_release_on_done = true;
+ }
+ break;
+
+ case I40E_NVMUPD_WRITE_SA:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
+ if (status)
+ i40e_release_nvm(hw);
+ else
+ hw->aq.nvm_release_on_done = true;
+ }
+ break;
+
+ case I40E_NVMUPD_WRITE_SNT:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
+ hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+ }
+ break;
+
+ case I40E_NVMUPD_CSUM_SA:
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
+ if (status) {
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+ } else {
+ status = i40e_update_nvm_checksum(hw);
+ if (status) {
+ *errno = hw->aq.asq_last_status ?
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+ -EIO;
+ i40e_release_nvm(hw);
+ } else {
+ hw->aq.nvm_release_on_done = true;
+ }
+ }
+ break;
+
+ default:
+ status = I40E_ERR_NVM;
+ *errno = -ESRCH;
+ break;
+ }
+ return status;
+}
+
+/**
+ * i40e_nvmupd_state_reading - Handle NVM update state Reading
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * NVM ownership is already held. Process legitimate commands and set any
+ * change in state; reject all other commands.
+ **/
+static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status;
+ enum i40e_nvmupd_cmd upd_cmd;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
+
+ switch (upd_cmd) {
+ case I40E_NVMUPD_READ_SA:
+ case I40E_NVMUPD_READ_CON:
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
+ break;
+
+ case I40E_NVMUPD_READ_LCB:
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
+ i40e_release_nvm(hw);
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+ break;
+
+ default:
+ status = I40E_NOT_SUPPORTED;
+ *errno = -ESRCH;
+ break;
+ }
+ return status;
+}
+
+/**
+ * i40e_nvmupd_state_writing - Handle NVM update state Writing
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * NVM ownership is already held. Process legitimate commands and set any
+ * change in state; reject all other commands
+ **/
+static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status;
+ enum i40e_nvmupd_cmd upd_cmd;
+
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
+
+ switch (upd_cmd) {
+ case I40E_NVMUPD_WRITE_CON:
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
+ break;
+
+ case I40E_NVMUPD_WRITE_LCB:
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
+ if (!status) {
+ hw->aq.nvm_release_on_done = true;
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+ }
+ break;
+
+ case I40E_NVMUPD_CSUM_CON:
+ status = i40e_update_nvm_checksum(hw);
+ if (status)
+ *errno = hw->aq.asq_last_status ?
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+ -EIO;
+ break;
+
+ case I40E_NVMUPD_CSUM_LCB:
+ status = i40e_update_nvm_checksum(hw);
+ if (status) {
+ *errno = hw->aq.asq_last_status ?
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+ -EIO;
+ } else {
+ hw->aq.nvm_release_on_done = true;
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+ }
+ break;
+
+ default:
+ status = I40E_NOT_SUPPORTED;
+ *errno = -ESRCH;
+ break;
+ }
+ return status;
+}
+
+/**
+ * i40e_nvmupd_validate_command - Validate given command
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @errno: pointer to return error code
+ *
+ * Return one of the valid command types or I40E_NVMUPD_INVALID
+ **/
+static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ int *errno)
+{
+ enum i40e_nvmupd_cmd upd_cmd;
+ u8 transaction, module;
+
+ /* anything that doesn't match a recognized case is an error */
+ upd_cmd = I40E_NVMUPD_INVALID;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+ module = i40e_nvmupd_get_module(cmd->config);
+
+ /* limits on data size */
+ if ((cmd->data_size < 1) ||
+ (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
+ hw_dbg(hw, "i40e_nvmupd_validate_command data_size %d\n",
+ cmd->data_size);
+ *errno = -EFAULT;
+ return I40E_NVMUPD_INVALID;
+ }
+
+ switch (cmd->command) {
+ case I40E_NVM_READ:
+ switch (transaction) {
+ case I40E_NVM_CON:
+ upd_cmd = I40E_NVMUPD_READ_CON;
+ break;
+ case I40E_NVM_SNT:
+ upd_cmd = I40E_NVMUPD_READ_SNT;
+ break;
+ case I40E_NVM_LCB:
+ upd_cmd = I40E_NVMUPD_READ_LCB;
+ break;
+ case I40E_NVM_SA:
+ upd_cmd = I40E_NVMUPD_READ_SA;
+ break;
+ }
+ break;
+
+ case I40E_NVM_WRITE:
+ switch (transaction) {
+ case I40E_NVM_CON:
+ upd_cmd = I40E_NVMUPD_WRITE_CON;
+ break;
+ case I40E_NVM_SNT:
+ upd_cmd = I40E_NVMUPD_WRITE_SNT;
+ break;
+ case I40E_NVM_LCB:
+ upd_cmd = I40E_NVMUPD_WRITE_LCB;
+ break;
+ case I40E_NVM_SA:
+ upd_cmd = I40E_NVMUPD_WRITE_SA;
+ break;
+ case I40E_NVM_ERA:
+ upd_cmd = I40E_NVMUPD_WRITE_ERA;
+ break;
+ case I40E_NVM_CSUM:
+ upd_cmd = I40E_NVMUPD_CSUM_CON;
+ break;
+ case (I40E_NVM_CSUM|I40E_NVM_SA):
+ upd_cmd = I40E_NVMUPD_CSUM_SA;
+ break;
+ case (I40E_NVM_CSUM|I40E_NVM_LCB):
+ upd_cmd = I40E_NVMUPD_CSUM_LCB;
+ break;
+ }
+ break;
+ }
+
+ if (upd_cmd == I40E_NVMUPD_INVALID) {
+ *errno = -EFAULT;
+ hw_dbg(hw,
+ "i40e_nvmupd_validate_command returns %d errno: %d\n",
+ upd_cmd, *errno);
+ }
+ return upd_cmd;
+}
+
+/**
+ * i40e_nvmupd_nvm_read - Read NVM
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * cmd structure contains identifiers and data buffer
+ **/
+static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status;
+ u8 module, transaction;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+ module = i40e_nvmupd_get_module(cmd->config);
+ last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
+ hw_dbg(hw, "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n",
+ module, cmd->offset, cmd->data_size);
+
+ status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
+ bytes, last, NULL);
+ hw_dbg(hw, "i40e_nvmupd_nvm_read status %d\n", status);
+ if (status)
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+
+ return status;
+}
+
+/**
+ * i40e_nvmupd_nvm_erase - Erase an NVM module
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @errno: pointer to return error code
+ *
+ * module, offset, data_size and data are in cmd structure
+ **/
+static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ int *errno)
+{
+ i40e_status status = 0;
+ u8 module, transaction;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+ module = i40e_nvmupd_get_module(cmd->config);
+ last = (transaction & I40E_NVM_LCB);
+ hw_dbg(hw, "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n",
+ module, cmd->offset, cmd->data_size);
+ status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
+ last, NULL);
+ hw_dbg(hw, "i40e_nvmupd_nvm_erase status %d\n", status);
+ if (status)
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+
+ return status;
+}
+
+/**
+ * i40e_nvmupd_nvm_write - Write NVM
+ * @hw: pointer to hardware structure
+ * @cmd: pointer to nvm update command buffer
+ * @bytes: pointer to the data buffer
+ * @errno: pointer to return error code
+ *
+ * module, offset, data_size and data are in cmd structure
+ **/
+static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *errno)
+{
+ i40e_status status = 0;
+ u8 module, transaction;
+ bool last;
+
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
+ module = i40e_nvmupd_get_module(cmd->config);
+ last = (transaction & I40E_NVM_LCB);
+ hw_dbg(hw, "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
+ module, cmd->offset, cmd->data_size);
+ status = i40e_aq_update_nvm(hw, module, cmd->offset,
+ (u16)cmd->data_size, bytes, last, NULL);
+ hw_dbg(hw, "i40e_nvmupd_nvm_write status %d\n", status);
+ if (status)
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+
+ return status;
+}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
index ecd0f0b663c9..045b5c4b98b3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h
@@ -78,4 +78,7 @@ do { \
} while (0)
typedef enum i40e_status_code i40e_status;
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+#define I40E_FCOE
+#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
#endif /* _I40E_OSDEP_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index a430699c41d5..949a9a01778b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -70,17 +70,31 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
u16 *fw_major_version, u16 *fw_minor_version,
u16 *api_major_version, u16 *api_minor_version,
struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
+ u32 reg_addr, u64 reg_val,
+ struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,
struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
+ bool qualified_modules, bool report_init,
+ struct i40e_aq_get_phy_abilities_resp *abilities,
+ struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
+ struct i40e_aq_set_phy_config *config,
+ struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
+ bool atomic_reset);
i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
- struct i40e_asq_cmd_details *cmd_details);
+ bool enable_link,
+ struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
bool enable_lse, struct i40e_link_status *link,
struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse);
i40e_status i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
u64 advt_reg,
struct i40e_asq_cmd_details *cmd_details);
@@ -139,6 +153,9 @@ i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
u32 offset, u16 length, void *data,
bool last_command,
struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
+ u32 offset, u16 length, bool last_command,
+ struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
void *buff, u16 buff_size, u16 *data_size,
enum i40e_admin_queue_opc list_type_opc,
@@ -216,12 +233,16 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
/* i40e_common */
i40e_status i40e_init_shared_code(struct i40e_hw *hw);
i40e_status i40e_pf_reset(struct i40e_hw *hw);
+void i40e_clear_hw(struct i40e_hw *hw);
void i40e_clear_pxe_mode(struct i40e_hw *hw);
bool i40e_get_link_status(struct i40e_hw *hw);
-i40e_status i40e_get_mac_addr(struct i40e_hw *hw,
- u8 *mac_addr);
+i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
+i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_validate_mac_addr(u8 *mac_addr);
void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable);
+#ifdef I40E_FCOE
+i40e_status i40e_get_san_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
+#endif
/* prototype for functions used for NVM access */
i40e_status i40e_init_nvm(struct i40e_hw *hw);
i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
@@ -233,8 +254,12 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
u16 *data);
i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
u16 *words, u16 *data);
+i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
u16 *checksum);
+i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
+ struct i40e_nvm_access *cmd,
+ u8 *bytes, int *);
void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index 101f439acda6..bb7fe98b3a6c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -25,7 +25,6 @@
******************************************************************************/
#include "i40e.h"
-#include <linux/export.h>
#include <linux/ptp_classify.h>
/* The XL710 timesync is very much like Intel's 82599 design when it comes to
@@ -216,7 +215,7 @@ static int i40e_ptp_settime(struct ptp_clock_info *ptp,
}
/**
- * i40e_ptp_enable - Enable/disable ancillary features of the PHC subsystem
+ * i40e_ptp_feature_enable - Enable/disable ancillary features of the PHC subsystem
* @ptp: The PTP clock structure
* @rq: The requested feature to change
* @on: Enable/disable flag
@@ -224,8 +223,8 @@ static int i40e_ptp_settime(struct ptp_clock_info *ptp,
* The XL710 does not support any of the ancillary features of the PHC
* subsystem, so this function may just return.
**/
-static int i40e_ptp_enable(struct ptp_clock_info *ptp,
- struct ptp_clock_request *rq, int on)
+static int i40e_ptp_feature_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
{
return -EOPNOTSUPP;
}
@@ -315,6 +314,7 @@ void i40e_ptp_tx_hwtstamp(struct i40e_pf *pf)
skb_tstamp_tx(pf->ptp_tx_skb, &shhwtstamps);
dev_kfree_skb_any(pf->ptp_tx_skb);
pf->ptp_tx_skb = NULL;
+ clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
}
/**
@@ -423,28 +423,23 @@ int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
}
/**
- * i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping
+ * i40e_ptp_set_timestamp_mode - setup hardware for requested timestamp mode
* @pf: Board private structure
- * @ifreq: ioctl data
+ * @config: hwtstamp settings requested or saved
*
- * Respond to the user filter requests and make the appropriate hardware
- * changes here. The XL710 cannot support splitting of the Tx/Rx timestamping
- * logic, so keep track in software of whether to indicate these timestamps
- * or not.
+ * Control hardware registers to enter the specific mode requested by the
+ * user. Also used during reset path to ensure that timestamp settings are
+ * maintained.
*
- * It is permissible to "upgrade" the user request to a broader filter, as long
- * as the user receives the timestamps they care about and the user is notified
- * the filter has been broadened.
+ * Note: modifies config in place, and may update the requested mode to be
+ * more broad if the specific filter is not directly supported.
**/
-int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
+static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
+ struct hwtstamp_config *config)
{
struct i40e_hw *hw = &pf->hw;
- struct hwtstamp_config *config = &pf->tstamp_config;
u32 pf_id, tsyntype, regval;
- if (copy_from_user(config, ifr->ifr_data, sizeof(*config)))
- return -EFAULT;
-
/* Reserved for future extensions. */
if (config->flags)
return -EINVAL;
@@ -452,8 +447,12 @@ int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
/* Confirm that 1588 is supported on this PF. */
pf_id = (rd32(hw, I40E_PRTTSYN_CTL0) & I40E_PRTTSYN_CTL0_PF_ID_MASK) >>
I40E_PRTTSYN_CTL0_PF_ID_SHIFT;
- if (hw->pf_id != pf_id)
- return -EINVAL;
+ if (hw->pf_id != pf_id) {
+ dev_err(&pf->pdev->dev,
+ "PF %d attempted to control timestamp mode on port %d, which is owned by PF %d\n",
+ hw->pf_id, hw->port, pf_id);
+ return -EPERM;
+ }
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
@@ -535,23 +534,59 @@ int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
wr32(hw, I40E_PRTTSYN_CTL1, regval);
}
- return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
+ return 0;
+}
+
+/**
+ * i40e_ptp_set_ts_config - ioctl interface to control the HW timestamping
+ * @pf: Board private structure
+ * @ifreq: ioctl data
+ *
+ * Respond to the user filter requests and make the appropriate hardware
+ * changes here. The XL710 cannot support splitting of the Tx/Rx timestamping
+ * logic, so keep track in software of whether to indicate these timestamps
+ * or not.
+ *
+ * It is permissible to "upgrade" the user request to a broader filter, as long
+ * as the user receives the timestamps they care about and the user is notified
+ * the filter has been broadened.
+ **/
+int i40e_ptp_set_ts_config(struct i40e_pf *pf, struct ifreq *ifr)
+{
+ struct hwtstamp_config config;
+ int err;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ err = i40e_ptp_set_timestamp_mode(pf, &config);
+ if (err)
+ return err;
+
+ /* save these settings for future reference */
+ pf->tstamp_config = config;
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0;
}
/**
- * i40e_ptp_init - Initialize the 1588 support and register the PHC
+ * i40e_ptp_create_clock - Create PTP clock device for userspace
* @pf: Board private structure
*
- * This function registers the device clock as a PHC. If it is successful, it
- * starts the clock in the hardware.
+ * This function creates a new PTP clock device. It only creates one if we
+ * don't already have one, so it is safe to call. Will return error if it
+ * can't create one, but success if we already have a device. Should be used
+ * by i40e_ptp_init to create clock initially, and prevent global resets from
+ * creating new clock devices.
**/
-void i40e_ptp_init(struct i40e_pf *pf)
+static long i40e_ptp_create_clock(struct i40e_pf *pf)
{
- struct i40e_hw *hw = &pf->hw;
- struct net_device *netdev = pf->vsi[pf->lan_vsi]->netdev;
+ /* no need to create a clock device if we already have one */
+ if (!IS_ERR_OR_NULL(pf->ptp_clock))
+ return 0;
- strncpy(pf->ptp_caps.name, "i40e", sizeof(pf->ptp_caps.name));
+ strncpy(pf->ptp_caps.name, i40e_driver_name, sizeof(pf->ptp_caps.name));
pf->ptp_caps.owner = THIS_MODULE;
pf->ptp_caps.max_adj = 999999999;
pf->ptp_caps.n_ext_ts = 0;
@@ -560,11 +595,46 @@ void i40e_ptp_init(struct i40e_pf *pf)
pf->ptp_caps.adjtime = i40e_ptp_adjtime;
pf->ptp_caps.gettime = i40e_ptp_gettime;
pf->ptp_caps.settime = i40e_ptp_settime;
- pf->ptp_caps.enable = i40e_ptp_enable;
+ pf->ptp_caps.enable = i40e_ptp_feature_enable;
/* Attempt to register the clock before enabling the hardware. */
pf->ptp_clock = ptp_clock_register(&pf->ptp_caps, &pf->pdev->dev);
if (IS_ERR(pf->ptp_clock)) {
+ return PTR_ERR(pf->ptp_clock);
+ }
+
+ /* clear the hwtstamp settings here during clock create, instead of
+ * during regular init, so that we can maintain settings across a
+ * reset or suspend.
+ */
+ pf->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
+ pf->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
+
+ return 0;
+}
+
+/**
+ * i40e_ptp_init - Initialize the 1588 support after device probe or reset
+ * @pf: Board private structure
+ *
+ * This function sets device up for 1588 support. The first time it is run, it
+ * will create a PHC clock device. It does not create a clock device if one
+ * already exists. It also reconfigures the device after a reset.
+ **/
+void i40e_ptp_init(struct i40e_pf *pf)
+{
+ struct net_device *netdev = pf->vsi[pf->lan_vsi]->netdev;
+ struct i40e_hw *hw = &pf->hw;
+ long err;
+
+ /* we have to initialize the lock first, since we can't control
+ * when the user will enter the PHC device entry points
+ */
+ spin_lock_init(&pf->tmreg_lock);
+
+ /* ensure we have a clock device */
+ err = i40e_ptp_create_clock(pf);
+ if (err) {
pf->ptp_clock = NULL;
dev_err(&pf->pdev->dev, "%s: ptp_clock_register failed\n",
__func__);
@@ -572,8 +642,6 @@ void i40e_ptp_init(struct i40e_pf *pf)
struct timespec ts;
u32 regval;
- spin_lock_init(&pf->tmreg_lock);
-
dev_info(&pf->pdev->dev, "%s: added PHC on %s\n", __func__,
netdev->name);
pf->flags |= I40E_FLAG_PTP;
@@ -589,8 +657,8 @@ void i40e_ptp_init(struct i40e_pf *pf)
/* Set the increment value per clock tick. */
i40e_ptp_set_increment(pf);
- /* reset the tstamp_config */
- memset(&pf->tstamp_config, 0, sizeof(pf->tstamp_config));
+ /* reset timestamping mode */
+ i40e_ptp_set_timestamp_mode(pf, &pf->tstamp_config);
/* Set the clock value. */
ts = ktime_to_timespec(ktime_get_real());
@@ -614,6 +682,7 @@ void i40e_ptp_stop(struct i40e_pf *pf)
if (pf->ptp_tx_skb) {
dev_kfree_skb_any(pf->ptp_tx_skb);
pf->ptp_tx_skb = NULL;
+ clear_bit_unlock(__I40E_PTP_TX_IN_PROGRESS, &pf->state);
}
if (pf->ptp_clock) {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h
index 947de98500f3..65d3c8bb2d5b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -27,4648 +27,3343 @@
#ifndef _I40E_REGISTER_H_
#define _I40E_REGISTER_H_
-#define I40E_GL_GP_FUSE(_i) (0x0009400C + ((_i) * 4)) /* _i=0...28 */
-#define I40E_GL_GP_FUSE_MAX_INDEX 28
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT 0
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_MASK (0xFFFFFFFF << I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ 0x0009C4F4
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_MASK (0x7 << I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_MASK (0x1F << I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB 0x0009C4F0
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_MASK (0x1F << I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_MASK (0x7 << I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC 0x0009C4EC
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT 0
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_MASK (0xFF << I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT 8
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_MASK (0xFF << I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_0 0x0009C4F8
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_MASK (0xFFFFFFFF << I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_1 0x0009C4FC
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_MASK (0xFFFFFFFF << I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT)
-#define I40E_PFPCI_PF_FLUSH_DONE 0x0009C800
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE 0x0009C600
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE1(_VF) (0x0009C600 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_PFPCI_VF_FLUSH_DONE1_MAX_INDEX 127
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VM_FLUSH_DONE 0x0009C880
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT)
-
-#define I40E_PF_ARQBAH 0x00080180
+#define I40E_GL_ARQBAH 0x000801C0 /* Reset: EMPR */
+#define I40E_GL_ARQBAH_ARQBAH_SHIFT 0
+#define I40E_GL_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAH_ARQBAH_SHIFT)
+#define I40E_GL_ARQBAL 0x000800C0 /* Reset: EMPR */
+#define I40E_GL_ARQBAL_ARQBAL_SHIFT 0
+#define I40E_GL_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAL_ARQBAL_SHIFT)
+#define I40E_GL_ARQH 0x000803C0 /* Reset: EMPR */
+#define I40E_GL_ARQH_ARQH_SHIFT 0
+#define I40E_GL_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_GL_ARQH_ARQH_SHIFT)
+#define I40E_GL_ARQT 0x000804C0 /* Reset: EMPR */
+#define I40E_GL_ARQT_ARQT_SHIFT 0
+#define I40E_GL_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_GL_ARQT_ARQT_SHIFT)
+#define I40E_GL_ATQBAH 0x00080140 /* Reset: EMPR */
+#define I40E_GL_ATQBAH_ATQBAH_SHIFT 0
+#define I40E_GL_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAH_ATQBAH_SHIFT)
+#define I40E_GL_ATQBAL 0x00080040 /* Reset: EMPR */
+#define I40E_GL_ATQBAL_ATQBAL_SHIFT 0
+#define I40E_GL_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAL_ATQBAL_SHIFT)
+#define I40E_GL_ATQH 0x00080340 /* Reset: EMPR */
+#define I40E_GL_ATQH_ATQH_SHIFT 0
+#define I40E_GL_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_GL_ATQH_ATQH_SHIFT)
+#define I40E_GL_ATQLEN 0x00080240 /* Reset: EMPR */
+#define I40E_GL_ATQLEN_ATQLEN_SHIFT 0
+#define I40E_GL_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_GL_ATQLEN_ATQLEN_SHIFT)
+#define I40E_GL_ATQLEN_ATQVFE_SHIFT 28
+#define I40E_GL_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQVFE_SHIFT)
+#define I40E_GL_ATQLEN_ATQOVFL_SHIFT 29
+#define I40E_GL_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_GL_ATQLEN_ATQCRIT_SHIFT 30
+#define I40E_GL_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_GL_ATQLEN_ATQENABLE_SHIFT 31
+#define I40E_GL_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_GL_ATQT 0x00080440 /* Reset: EMPR */
+#define I40E_GL_ATQT_ATQT_SHIFT 0
+#define I40E_GL_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_GL_ATQT_ATQT_SHIFT)
+#define I40E_PF_ARQBAH 0x00080180 /* Reset: EMPR */
#define I40E_PF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_PF_ARQBAH_ARQBAH_MASK (0xFFFFFFFF << I40E_PF_ARQBAH_ARQBAH_SHIFT)
-#define I40E_PF_ARQBAL 0x00080080
+#define I40E_PF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAH_ARQBAH_SHIFT)
+#define I40E_PF_ARQBAL 0x00080080 /* Reset: EMPR */
#define I40E_PF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_PF_ARQBAL_ARQBAL_MASK (0xFFFFFFFF << I40E_PF_ARQBAL_ARQBAL_SHIFT)
-#define I40E_PF_ARQH 0x00080380
+#define I40E_PF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAL_ARQBAL_SHIFT)
+#define I40E_PF_ARQH 0x00080380 /* Reset: EMPR */
#define I40E_PF_ARQH_ARQH_SHIFT 0
-#define I40E_PF_ARQH_ARQH_MASK (0x3FF << I40E_PF_ARQH_ARQH_SHIFT)
-#define I40E_PF_ARQLEN 0x00080280
+#define I40E_PF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_PF_ARQH_ARQH_SHIFT)
+#define I40E_PF_ARQLEN 0x00080280 /* Reset: EMPR */
#define I40E_PF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_PF_ARQLEN_ARQLEN_MASK (0x3FF << I40E_PF_ARQLEN_ARQLEN_SHIFT)
+#define I40E_PF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ARQLEN_ARQLEN_SHIFT)
#define I40E_PF_ARQLEN_ARQVFE_SHIFT 28
-#define I40E_PF_ARQLEN_ARQVFE_MASK (0x1 << I40E_PF_ARQLEN_ARQVFE_SHIFT)
+#define I40E_PF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQVFE_SHIFT)
#define I40E_PF_ARQLEN_ARQOVFL_SHIFT 29
-#define I40E_PF_ARQLEN_ARQOVFL_MASK (0x1 << I40E_PF_ARQLEN_ARQOVFL_SHIFT)
+#define I40E_PF_ARQLEN_ARQOVFL_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQOVFL_SHIFT)
#define I40E_PF_ARQLEN_ARQCRIT_SHIFT 30
-#define I40E_PF_ARQLEN_ARQCRIT_MASK (0x1 << I40E_PF_ARQLEN_ARQCRIT_SHIFT)
+#define I40E_PF_ARQLEN_ARQCRIT_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQCRIT_SHIFT)
#define I40E_PF_ARQLEN_ARQENABLE_SHIFT 31
-#define I40E_PF_ARQLEN_ARQENABLE_MASK (0x1 << I40E_PF_ARQLEN_ARQENABLE_SHIFT)
-#define I40E_PF_ARQT 0x00080480
+#define I40E_PF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQENABLE_SHIFT)
+#define I40E_PF_ARQT 0x00080480 /* Reset: EMPR */
#define I40E_PF_ARQT_ARQT_SHIFT 0
-#define I40E_PF_ARQT_ARQT_MASK (0x3FF << I40E_PF_ARQT_ARQT_SHIFT)
-#define I40E_PF_ATQBAH 0x00080100
+#define I40E_PF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_PF_ARQT_ARQT_SHIFT)
+#define I40E_PF_ATQBAH 0x00080100 /* Reset: EMPR */
#define I40E_PF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_PF_ATQBAH_ATQBAH_MASK (0xFFFFFFFF << I40E_PF_ATQBAH_ATQBAH_SHIFT)
-#define I40E_PF_ATQBAL 0x00080000
+#define I40E_PF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAH_ATQBAH_SHIFT)
+#define I40E_PF_ATQBAL 0x00080000 /* Reset: EMPR */
#define I40E_PF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_PF_ATQBAL_ATQBAL_MASK (0xFFFFFFFF << I40E_PF_ATQBAL_ATQBAL_SHIFT)
-#define I40E_PF_ATQH 0x00080300
+#define I40E_PF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAL_ATQBAL_SHIFT)
+#define I40E_PF_ATQH 0x00080300 /* Reset: EMPR */
#define I40E_PF_ATQH_ATQH_SHIFT 0
-#define I40E_PF_ATQH_ATQH_MASK (0x3FF << I40E_PF_ATQH_ATQH_SHIFT)
-#define I40E_PF_ATQLEN 0x00080200
+#define I40E_PF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_PF_ATQH_ATQH_SHIFT)
+#define I40E_PF_ATQLEN 0x00080200 /* Reset: EMPR */
#define I40E_PF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_PF_ATQLEN_ATQLEN_MASK (0x3FF << I40E_PF_ATQLEN_ATQLEN_SHIFT)
+#define I40E_PF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ATQLEN_ATQLEN_SHIFT)
#define I40E_PF_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_PF_ATQLEN_ATQVFE_MASK (0x1 << I40E_PF_ATQLEN_ATQVFE_SHIFT)
+#define I40E_PF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQVFE_SHIFT)
#define I40E_PF_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_PF_ATQLEN_ATQOVFL_MASK (0x1 << I40E_PF_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_PF_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQOVFL_SHIFT)
#define I40E_PF_ATQLEN_ATQCRIT_SHIFT 30
-#define I40E_PF_ATQLEN_ATQCRIT_MASK (0x1 << I40E_PF_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_PF_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQCRIT_SHIFT)
#define I40E_PF_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_PF_ATQLEN_ATQENABLE_MASK (0x1 << I40E_PF_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_PF_ATQT 0x00080400
+#define I40E_PF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_PF_ATQT 0x00080400 /* Reset: EMPR */
#define I40E_PF_ATQT_ATQT_SHIFT 0
-#define I40E_PF_ATQT_ATQT_MASK (0x3FF << I40E_PF_ATQT_ATQT_SHIFT)
-#define I40E_VF_ARQBAH(_VF) (0x00081400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_PF_ATQT_ATQT_SHIFT)
+#define I40E_VF_ARQBAH(_VF) (0x00081400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQBAH_MAX_INDEX 127
#define I40E_VF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH_ARQBAH_MASK (0xFFFFFFFF << I40E_VF_ARQBAH_ARQBAH_SHIFT)
-#define I40E_VF_ARQBAL(_VF) (0x00080C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH_ARQBAH_SHIFT)
+#define I40E_VF_ARQBAL(_VF) (0x00080C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQBAL_MAX_INDEX 127
#define I40E_VF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL_ARQBAL_MASK (0xFFFFFFFF << I40E_VF_ARQBAL_ARQBAL_SHIFT)
-#define I40E_VF_ARQH(_VF) (0x00082400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL_ARQBAL_SHIFT)
+#define I40E_VF_ARQH(_VF) (0x00082400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQH_MAX_INDEX 127
#define I40E_VF_ARQH_ARQH_SHIFT 0
-#define I40E_VF_ARQH_ARQH_MASK (0x3FF << I40E_VF_ARQH_ARQH_SHIFT)
-#define I40E_VF_ARQLEN(_VF) (0x00081C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH_ARQH_SHIFT)
+#define I40E_VF_ARQLEN(_VF) (0x00081C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQLEN_MAX_INDEX 127
#define I40E_VF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN_ARQLEN_MASK (0x3FF << I40E_VF_ARQLEN_ARQLEN_SHIFT)
+#define I40E_VF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN_ARQLEN_SHIFT)
#define I40E_VF_ARQLEN_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN_ARQVFE_MASK (0x1 << I40E_VF_ARQLEN_ARQVFE_SHIFT)
+#define I40E_VF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQVFE_SHIFT)
#define I40E_VF_ARQLEN_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN_ARQOVFL_MASK (0x1 << I40E_VF_ARQLEN_ARQOVFL_SHIFT)
+#define I40E_VF_ARQLEN_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQOVFL_SHIFT)
#define I40E_VF_ARQLEN_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN_ARQCRIT_MASK (0x1 << I40E_VF_ARQLEN_ARQCRIT_SHIFT)
+#define I40E_VF_ARQLEN_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQCRIT_SHIFT)
#define I40E_VF_ARQLEN_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN_ARQENABLE_MASK (0x1 << I40E_VF_ARQLEN_ARQENABLE_SHIFT)
-#define I40E_VF_ARQT(_VF) (0x00082C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQENABLE_SHIFT)
+#define I40E_VF_ARQT(_VF) (0x00082C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQT_MAX_INDEX 127
#define I40E_VF_ARQT_ARQT_SHIFT 0
-#define I40E_VF_ARQT_ARQT_MASK (0x3FF << I40E_VF_ARQT_ARQT_SHIFT)
-#define I40E_VF_ATQBAH(_VF) (0x00081000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT_ARQT_SHIFT)
+#define I40E_VF_ATQBAH(_VF) (0x00081000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQBAH_MAX_INDEX 127
#define I40E_VF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH_ATQBAH_MASK (0xFFFFFFFF << I40E_VF_ATQBAH_ATQBAH_SHIFT)
-#define I40E_VF_ATQBAL(_VF) (0x00080800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH_ATQBAH_SHIFT)
+#define I40E_VF_ATQBAL(_VF) (0x00080800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQBAL_MAX_INDEX 127
#define I40E_VF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL_ATQBAL_MASK (0xFFFFFFFF << I40E_VF_ATQBAL_ATQBAL_SHIFT)
-#define I40E_VF_ATQH(_VF) (0x00082000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL_ATQBAL_SHIFT)
+#define I40E_VF_ATQH(_VF) (0x00082000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQH_MAX_INDEX 127
#define I40E_VF_ATQH_ATQH_SHIFT 0
-#define I40E_VF_ATQH_ATQH_MASK (0x3FF << I40E_VF_ATQH_ATQH_SHIFT)
-#define I40E_VF_ATQLEN(_VF) (0x00081800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH_ATQH_SHIFT)
+#define I40E_VF_ATQLEN(_VF) (0x00081800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQLEN_MAX_INDEX 127
#define I40E_VF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN_ATQLEN_MASK (0x3FF << I40E_VF_ATQLEN_ATQLEN_SHIFT)
+#define I40E_VF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN_ATQLEN_SHIFT)
#define I40E_VF_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN_ATQVFE_MASK (0x1 << I40E_VF_ATQLEN_ATQVFE_SHIFT)
+#define I40E_VF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQVFE_SHIFT)
#define I40E_VF_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN_ATQOVFL_MASK (0x1 << I40E_VF_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_VF_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQOVFL_SHIFT)
#define I40E_VF_ATQLEN_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN_ATQCRIT_MASK (0x1 << I40E_VF_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_VF_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQCRIT_SHIFT)
#define I40E_VF_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN_ATQENABLE_MASK (0x1 << I40E_VF_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_VF_ATQT(_VF) (0x00082800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_VF_ATQT(_VF) (0x00082800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQT_MAX_INDEX 127
#define I40E_VF_ATQT_ATQT_SHIFT 0
-#define I40E_VF_ATQT_ATQT_MASK (0x3FF << I40E_VF_ATQT_ATQT_SHIFT)
-#define I40E_PRT_L2TAGSEN 0x001C0B20
+#define I40E_VF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT_ATQT_SHIFT)
+#define I40E_PRT_L2TAGSEN 0x001C0B20 /* Reset: CORER */
#define I40E_PRT_L2TAGSEN_ENABLE_SHIFT 0
-#define I40E_PRT_L2TAGSEN_ENABLE_MASK (0xFF << I40E_PRT_L2TAGSEN_ENABLE_SHIFT)
-#define I40E_PFCM_LAN_ERRDATA 0x0010C080
+#define I40E_PRT_L2TAGSEN_ENABLE_MASK I40E_MASK(0xFF, I40E_PRT_L2TAGSEN_ENABLE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA 0x0010C080 /* Reset: PFR */
#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_MASK (0xF << I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT)
#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_MASK (0x7 << I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT)
#define I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_LAN_ERRDATA_Q_NUM_MASK (0xFFF << I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO 0x0010C000
+#define I40E_PFCM_LAN_ERRDATA_Q_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO 0x0010C000 /* Reset: PFR */
#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_MASK (0x7 << I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_PFCM_LANCTXCTL 0x0010C300
+#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LANCTXCTL 0x0010C300 /* Reset: CORER */
#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT 0
-#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_MASK (0xFFF << I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT)
+#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT)
#define I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT 12
-#define I40E_PFCM_LANCTXCTL_SUB_LINE_MASK (0x7 << I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT)
+#define I40E_PFCM_LANCTXCTL_SUB_LINE_MASK I40E_MASK(0x7, I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT)
#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT 15
-#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_MASK (0x3 << I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT)
+#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT)
#define I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT 17
-#define I40E_PFCM_LANCTXCTL_OP_CODE_MASK (0x3 << I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT)
-#define I40E_PFCM_LANCTXDATA(_i) (0x0010C100 + ((_i) * 128)) /* _i=0...3 */
+#define I40E_PFCM_LANCTXCTL_OP_CODE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT)
+#define I40E_PFCM_LANCTXDATA(_i) (0x0010C100 + ((_i) * 128)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PFCM_LANCTXDATA_MAX_INDEX 3
#define I40E_PFCM_LANCTXDATA_DATA_SHIFT 0
-#define I40E_PFCM_LANCTXDATA_DATA_MASK (0xFFFFFFFF << I40E_PFCM_LANCTXDATA_DATA_SHIFT)
-#define I40E_PFCM_LANCTXSTAT 0x0010C380
+#define I40E_PFCM_LANCTXDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFCM_LANCTXDATA_DATA_SHIFT)
+#define I40E_PFCM_LANCTXSTAT 0x0010C380 /* Reset: CORER */
#define I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT 0
-#define I40E_PFCM_LANCTXSTAT_CTX_DONE_MASK (0x1 << I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT)
+#define I40E_PFCM_LANCTXSTAT_CTX_DONE_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT)
#define I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT 1
-#define I40E_PFCM_LANCTXSTAT_CTX_MISS_MASK (0x1 << I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT)
-#define I40E_PFCM_PE_ERRDATA 0x00138D00
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_MASK (0xF << I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_MASK (0x7 << I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_MASK (0x3FFFF << I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_PE_ERRINFO 0x00138C80
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_MASK (0x7 << I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRDATA1(_VF) (0x00138800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PFCM_LANCTXSTAT_CTX_MISS_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1(_VF) (0x00138800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFCM_PE_ERRDATA1_MAX_INDEX 127
#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_MASK (0xF << I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT)
#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_MASK (0x7 << I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT)
#define I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA1_Q_NUM_MASK (0x3FFFF << I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1(_VF) (0x00138400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFCM_PE_ERRDATA1_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1(_VF) (0x00138400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFCM_PE_ERRINFO1_MAX_INDEX 127
#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_MASK (0x1 << I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_MASK (0x7 << I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT)
-#define I40E_GLDCB_GENC 0x00083044
+#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT)
+#define I40E_GLDCB_GENC 0x00083044 /* Reset: CORER */
#define I40E_GLDCB_GENC_PCIRTT_SHIFT 0
-#define I40E_GLDCB_GENC_PCIRTT_MASK (0xFFFF << I40E_GLDCB_GENC_PCIRTT_SHIFT)
-#define I40E_GLDCB_RUPTI 0x00122618
+#define I40E_GLDCB_GENC_PCIRTT_MASK I40E_MASK(0xFFFF, I40E_GLDCB_GENC_PCIRTT_SHIFT)
+#define I40E_GLDCB_RUPTI 0x00122618 /* Reset: CORER */
#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT 0
-#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_MASK (0xFFFFFFFF << I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT)
-#define I40E_PRTDCB_FCCFG 0x001E4640
+#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT)
+#define I40E_PRTDCB_FCCFG 0x001E4640 /* Reset: GLOBR */
#define I40E_PRTDCB_FCCFG_TFCE_SHIFT 3
-#define I40E_PRTDCB_FCCFG_TFCE_MASK (0x3 << I40E_PRTDCB_FCCFG_TFCE_SHIFT)
-#define I40E_PRTDCB_FCRTV 0x001E4600
+#define I40E_PRTDCB_FCCFG_TFCE_MASK I40E_MASK(0x3, I40E_PRTDCB_FCCFG_TFCE_SHIFT)
+#define I40E_PRTDCB_FCRTV 0x001E4600 /* Reset: GLOBR */
#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT 0
-#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_MASK (0xFFFF << I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT)
-#define I40E_PRTDCB_FCTTVN(_i) (0x001E4580 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT)
+#define I40E_PRTDCB_FCTTVN(_i) (0x001E4580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: GLOBR */
#define I40E_PRTDCB_FCTTVN_MAX_INDEX 3
#define I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT 0
-#define I40E_PRTDCB_FCTTVN_TTV_2N_MASK (0xFFFF << I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT)
+#define I40E_PRTDCB_FCTTVN_TTV_2N_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT)
#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT 16
-#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_MASK (0xFFFF << I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT)
-#define I40E_PRTDCB_GENC 0x00083000
+#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT)
+#define I40E_PRTDCB_GENC 0x00083000 /* Reset: CORER */
#define I40E_PRTDCB_GENC_RESERVED_1_SHIFT 0
-#define I40E_PRTDCB_GENC_RESERVED_1_MASK (0x3 << I40E_PRTDCB_GENC_RESERVED_1_SHIFT)
+#define I40E_PRTDCB_GENC_RESERVED_1_MASK I40E_MASK(0x3, I40E_PRTDCB_GENC_RESERVED_1_SHIFT)
#define I40E_PRTDCB_GENC_NUMTC_SHIFT 2
-#define I40E_PRTDCB_GENC_NUMTC_MASK (0xF << I40E_PRTDCB_GENC_NUMTC_SHIFT)
+#define I40E_PRTDCB_GENC_NUMTC_MASK I40E_MASK(0xF, I40E_PRTDCB_GENC_NUMTC_SHIFT)
#define I40E_PRTDCB_GENC_FCOEUP_SHIFT 6
-#define I40E_PRTDCB_GENC_FCOEUP_MASK (0x7 << I40E_PRTDCB_GENC_FCOEUP_SHIFT)
+#define I40E_PRTDCB_GENC_FCOEUP_MASK I40E_MASK(0x7, I40E_PRTDCB_GENC_FCOEUP_SHIFT)
#define I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT 9
-#define I40E_PRTDCB_GENC_FCOEUP_VALID_MASK (0x1 << I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT)
+#define I40E_PRTDCB_GENC_FCOEUP_VALID_MASK I40E_MASK(0x1, I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT)
#define I40E_PRTDCB_GENC_PFCLDA_SHIFT 16
-#define I40E_PRTDCB_GENC_PFCLDA_MASK (0xFFFF << I40E_PRTDCB_GENC_PFCLDA_SHIFT)
-#define I40E_PRTDCB_GENS 0x00083020
+#define I40E_PRTDCB_GENC_PFCLDA_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_GENC_PFCLDA_SHIFT)
+#define I40E_PRTDCB_GENS 0x00083020 /* Reset: CORER */
#define I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT 0
-#define I40E_PRTDCB_GENS_DCBX_STATUS_MASK (0x7 << I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT)
-#define I40E_PRTDCB_MFLCN 0x001E2400
+#define I40E_PRTDCB_GENS_DCBX_STATUS_MASK I40E_MASK(0x7, I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT)
+#define I40E_PRTDCB_MFLCN 0x001E2400 /* Reset: GLOBR */
#define I40E_PRTDCB_MFLCN_PMCF_SHIFT 0
-#define I40E_PRTDCB_MFLCN_PMCF_MASK (0x1 << I40E_PRTDCB_MFLCN_PMCF_SHIFT)
+#define I40E_PRTDCB_MFLCN_PMCF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_PMCF_SHIFT)
#define I40E_PRTDCB_MFLCN_DPF_SHIFT 1
-#define I40E_PRTDCB_MFLCN_DPF_MASK (0x1 << I40E_PRTDCB_MFLCN_DPF_SHIFT)
+#define I40E_PRTDCB_MFLCN_DPF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_DPF_SHIFT)
#define I40E_PRTDCB_MFLCN_RPFCM_SHIFT 2
-#define I40E_PRTDCB_MFLCN_RPFCM_MASK (0x1 << I40E_PRTDCB_MFLCN_RPFCM_SHIFT)
+#define I40E_PRTDCB_MFLCN_RPFCM_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RPFCM_SHIFT)
#define I40E_PRTDCB_MFLCN_RFCE_SHIFT 3
-#define I40E_PRTDCB_MFLCN_RFCE_MASK (0x1 << I40E_PRTDCB_MFLCN_RFCE_SHIFT)
+#define I40E_PRTDCB_MFLCN_RFCE_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RFCE_SHIFT)
#define I40E_PRTDCB_MFLCN_RPFCE_SHIFT 4
-#define I40E_PRTDCB_MFLCN_RPFCE_MASK (0xFF << I40E_PRTDCB_MFLCN_RPFCE_SHIFT)
-#define I40E_PRTDCB_RETSC 0x001223E0
+#define I40E_PRTDCB_MFLCN_RPFCE_MASK I40E_MASK(0xFF, I40E_PRTDCB_MFLCN_RPFCE_SHIFT)
+#define I40E_PRTDCB_RETSC 0x001223E0 /* Reset: CORER */
#define I40E_PRTDCB_RETSC_ETS_MODE_SHIFT 0
-#define I40E_PRTDCB_RETSC_ETS_MODE_MASK (0x1 << I40E_PRTDCB_RETSC_ETS_MODE_SHIFT)
+#define I40E_PRTDCB_RETSC_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_ETS_MODE_SHIFT)
#define I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT 1
-#define I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK (0x1 << I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT)
+#define I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT)
#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT 2
-#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK (0xF << I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT)
+#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK I40E_MASK(0xF, I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT)
#define I40E_PRTDCB_RETSC_LLTC_SHIFT 8
-#define I40E_PRTDCB_RETSC_LLTC_MASK (0xFF << I40E_PRTDCB_RETSC_LLTC_SHIFT)
-#define I40E_PRTDCB_RETSTCC(_i) (0x00122180 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_RETSC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_RETSC_LLTC_SHIFT)
+#define I40E_PRTDCB_RETSTCC(_i) (0x00122180 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTDCB_RETSTCC_MAX_INDEX 7
#define I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT 0
-#define I40E_PRTDCB_RETSTCC_BWSHARE_MASK (0x7F << I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT)
+#define I40E_PRTDCB_RETSTCC_BWSHARE_MASK I40E_MASK(0x7F, I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT)
#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT 30
-#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK (0x1 << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT)
+#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT)
#define I40E_PRTDCB_RETSTCC_ETSTC_SHIFT 31
-#define I40E_PRTDCB_RETSTCC_ETSTC_MASK (0x1 << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT)
-#define I40E_PRTDCB_RPPMC 0x001223A0
+#define I40E_PRTDCB_RETSTCC_ETSTC_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSTCC_ETSTC_SHIFT)
+#define I40E_PRTDCB_RPPMC 0x001223A0 /* Reset: CORER */
#define I40E_PRTDCB_RPPMC_LANRPPM_SHIFT 0
-#define I40E_PRTDCB_RPPMC_LANRPPM_MASK (0xFF << I40E_PRTDCB_RPPMC_LANRPPM_SHIFT)
+#define I40E_PRTDCB_RPPMC_LANRPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_LANRPPM_SHIFT)
#define I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT 8
-#define I40E_PRTDCB_RPPMC_RDMARPPM_MASK (0xFF << I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT)
+#define I40E_PRTDCB_RPPMC_RDMARPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT)
#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT 16
-#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK (0xFF << I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT)
-#define I40E_PRTDCB_RUP 0x001C0B00
+#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT)
+#define I40E_PRTDCB_RUP 0x001C0B00 /* Reset: CORER */
#define I40E_PRTDCB_RUP_NOVLANUP_SHIFT 0
-#define I40E_PRTDCB_RUP_NOVLANUP_MASK (0x7 << I40E_PRTDCB_RUP_NOVLANUP_SHIFT)
-#define I40E_PRTDCB_RUP2TC 0x001C09A0
+#define I40E_PRTDCB_RUP_NOVLANUP_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP_NOVLANUP_SHIFT)
+#define I40E_PRTDCB_RUP2TC 0x001C09A0 /* Reset: CORER */
#define I40E_PRTDCB_RUP2TC_UP0TC_SHIFT 0
-#define I40E_PRTDCB_RUP2TC_UP0TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP0TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP0TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP0TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP1TC_SHIFT 3
-#define I40E_PRTDCB_RUP2TC_UP1TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP1TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP1TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP1TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP2TC_SHIFT 6
-#define I40E_PRTDCB_RUP2TC_UP2TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP2TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP2TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP2TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP3TC_SHIFT 9
-#define I40E_PRTDCB_RUP2TC_UP3TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP3TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP3TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP3TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP4TC_SHIFT 12
-#define I40E_PRTDCB_RUP2TC_UP4TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP4TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP4TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP4TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP5TC_SHIFT 15
-#define I40E_PRTDCB_RUP2TC_UP5TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP5TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP5TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP5TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP6TC_SHIFT 18
-#define I40E_PRTDCB_RUP2TC_UP6TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP6TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP6TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP6TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP7TC_SHIFT 21
-#define I40E_PRTDCB_RUP2TC_UP7TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP7TC_SHIFT)
-#define I40E_PRTDCB_TC2PFC 0x001C0980
+#define I40E_PRTDCB_RUP2TC_UP7TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP7TC_SHIFT)
+#define I40E_PRTDCB_TC2PFC 0x001C0980 /* Reset: CORER */
#define I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT 0
-#define I40E_PRTDCB_TC2PFC_TC2PFC_MASK (0xFF << I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT)
-#define I40E_PRTDCB_TCPMC 0x000A21A0
+#define I40E_PRTDCB_TC2PFC_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT)
+#define I40E_PRTDCB_TCMSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
+#define I40E_PRTDCB_TCMSTC_MAX_INDEX 7
+#define I40E_PRTDCB_TCMSTC_MSTC_SHIFT 0
+#define I40E_PRTDCB_TCMSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCMSTC_MSTC_SHIFT)
+#define I40E_PRTDCB_TCPMC 0x000A21A0 /* Reset: CORER */
#define I40E_PRTDCB_TCPMC_CPM_SHIFT 0
-#define I40E_PRTDCB_TCPMC_CPM_MASK (0x1FFF << I40E_PRTDCB_TCPMC_CPM_SHIFT)
+#define I40E_PRTDCB_TCPMC_CPM_MASK I40E_MASK(0x1FFF, I40E_PRTDCB_TCPMC_CPM_SHIFT)
#define I40E_PRTDCB_TCPMC_LLTC_SHIFT 13
-#define I40E_PRTDCB_TCPMC_LLTC_MASK (0xFF << I40E_PRTDCB_TCPMC_LLTC_SHIFT)
+#define I40E_PRTDCB_TCPMC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TCPMC_LLTC_SHIFT)
#define I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TCPMC_TCPM_MODE_MASK (0x1 << I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TCWSTC(_i) (0x000A2040 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_TCPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT)
+#define I40E_PRTDCB_TCWSTC(_i) (0x000A2040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTDCB_TCWSTC_MAX_INDEX 7
#define I40E_PRTDCB_TCWSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TCWSTC_MSTC_MASK (0xFFFFF << I40E_PRTDCB_TCWSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TDPMC 0x000A0180
+#define I40E_PRTDCB_TCWSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCWSTC_MSTC_SHIFT)
+#define I40E_PRTDCB_TDPMC 0x000A0180 /* Reset: CORER */
#define I40E_PRTDCB_TDPMC_DPM_SHIFT 0
-#define I40E_PRTDCB_TDPMC_DPM_MASK (0xFF << I40E_PRTDCB_TDPMC_DPM_SHIFT)
+#define I40E_PRTDCB_TDPMC_DPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_TDPMC_DPM_SHIFT)
#define I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TDPMC_TCPM_MODE_MASK (0x1 << I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TDPUC 0x00044100
-#define I40E_PRTDCB_TDPUC_MAX_TXFRAME_SHIFT 0
-#define I40E_PRTDCB_TDPUC_MAX_TXFRAME_MASK (0xFFFF << I40E_PRTDCB_TDPUC_MAX_TXFRAME_SHIFT)
-#define I40E_PRTDCB_TETSC_TCB 0x000AE060
+#define I40E_PRTDCB_TDPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT)
+#define I40E_PRTDCB_TETSC_TCB 0x000AE060 /* Reset: CORER */
#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_MASK (0x1 << I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT)
+#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT)
#define I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TCB_LLTC_MASK (0xFF << I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT)
-#define I40E_PRTDCB_TETSC_TPB 0x00098060
+#define I40E_PRTDCB_TETSC_TCB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT)
+#define I40E_PRTDCB_TETSC_TPB 0x00098060 /* Reset: CORER */
#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_MASK (0x1 << I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT)
+#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT)
#define I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TPB_LLTC_MASK (0xFF << I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT)
-#define I40E_PRTDCB_TFCS 0x001E4560
+#define I40E_PRTDCB_TETSC_TPB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT)
+#define I40E_PRTDCB_TFCS 0x001E4560 /* Reset: GLOBR */
#define I40E_PRTDCB_TFCS_TXOFF_SHIFT 0
-#define I40E_PRTDCB_TFCS_TXOFF_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF0_SHIFT 8
-#define I40E_PRTDCB_TFCS_TXOFF0_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF0_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF0_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF0_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF1_SHIFT 9
-#define I40E_PRTDCB_TFCS_TXOFF1_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF1_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF1_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF1_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF2_SHIFT 10
-#define I40E_PRTDCB_TFCS_TXOFF2_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF2_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF2_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF2_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF3_SHIFT 11
-#define I40E_PRTDCB_TFCS_TXOFF3_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF3_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF3_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF3_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF4_SHIFT 12
-#define I40E_PRTDCB_TFCS_TXOFF4_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF4_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF4_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF4_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF5_SHIFT 13
-#define I40E_PRTDCB_TFCS_TXOFF5_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF5_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF5_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF5_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF6_SHIFT 14
-#define I40E_PRTDCB_TFCS_TXOFF6_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF6_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF6_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF6_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF7_SHIFT 15
-#define I40E_PRTDCB_TFCS_TXOFF7_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF7_SHIFT)
-#define I40E_PRTDCB_TFWSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */
-#define I40E_PRTDCB_TFWSTC_MAX_INDEX 7
-#define I40E_PRTDCB_TFWSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TFWSTC_MSTC_MASK (0xFFFFF << I40E_PRTDCB_TFWSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TPFCTS(_i) (0x001E4660 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_TFCS_TXOFF7_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF7_SHIFT)
+#define I40E_PRTDCB_TPFCTS(_i) (0x001E4660 + ((_i) * 32)) /* _i=0...7 */ /* Reset: GLOBR */
#define I40E_PRTDCB_TPFCTS_MAX_INDEX 7
#define I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT 0
-#define I40E_PRTDCB_TPFCTS_PFCTIMER_MASK (0x3FFF << I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT)
-#define I40E_GLFCOE_RCTL 0x00269B94
+#define I40E_PRTDCB_TPFCTS_PFCTIMER_MASK I40E_MASK(0x3FFF, I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT)
+#define I40E_GLFCOE_RCTL 0x00269B94 /* Reset: CORER */
#define I40E_GLFCOE_RCTL_FCOEVER_SHIFT 0
-#define I40E_GLFCOE_RCTL_FCOEVER_MASK (0xF << I40E_GLFCOE_RCTL_FCOEVER_SHIFT)
+#define I40E_GLFCOE_RCTL_FCOEVER_MASK I40E_MASK(0xF, I40E_GLFCOE_RCTL_FCOEVER_SHIFT)
#define I40E_GLFCOE_RCTL_SAVBAD_SHIFT 4
-#define I40E_GLFCOE_RCTL_SAVBAD_MASK (0x1 << I40E_GLFCOE_RCTL_SAVBAD_SHIFT)
+#define I40E_GLFCOE_RCTL_SAVBAD_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_SAVBAD_SHIFT)
#define I40E_GLFCOE_RCTL_ICRC_SHIFT 5
-#define I40E_GLFCOE_RCTL_ICRC_MASK (0x1 << I40E_GLFCOE_RCTL_ICRC_SHIFT)
+#define I40E_GLFCOE_RCTL_ICRC_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_ICRC_SHIFT)
#define I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT 16
-#define I40E_GLFCOE_RCTL_MAX_SIZE_MASK (0x3FFF << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT)
-#define I40E_GL_FWSTS 0x00083048
+#define I40E_GLFCOE_RCTL_MAX_SIZE_MASK I40E_MASK(0x3FFF, I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT)
+#define I40E_GL_FWSTS 0x00083048 /* Reset: POR */
#define I40E_GL_FWSTS_FWS0B_SHIFT 0
-#define I40E_GL_FWSTS_FWS0B_MASK (0xFF << I40E_GL_FWSTS_FWS0B_SHIFT)
+#define I40E_GL_FWSTS_FWS0B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS0B_SHIFT)
#define I40E_GL_FWSTS_FWRI_SHIFT 9
-#define I40E_GL_FWSTS_FWRI_MASK (0x1 << I40E_GL_FWSTS_FWRI_SHIFT)
+#define I40E_GL_FWSTS_FWRI_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWRI_SHIFT)
#define I40E_GL_FWSTS_FWS1B_SHIFT 16
-#define I40E_GL_FWSTS_FWS1B_MASK (0xFF << I40E_GL_FWSTS_FWS1B_SHIFT)
-#define I40E_GLGEN_CLKSTAT 0x000B8184
+#define I40E_GL_FWSTS_FWS1B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS1B_SHIFT)
+#define I40E_GLGEN_CLKSTAT 0x000B8184 /* Reset: POR */
#define I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT 0
-#define I40E_GLGEN_CLKSTAT_CLKMODE_MASK (0x1 << I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT)
+#define I40E_GLGEN_CLKSTAT_CLKMODE_MASK I40E_MASK(0x1, I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT)
#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT 4
-#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_MASK (0x3 << I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_MASK I40E_MASK(0x3, I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT 8
-#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT 12
-#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT 16
-#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT 20
-#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_GPIO_CTL(_i) (0x00088100 + ((_i) * 4)) /* _i=0...29 */
+#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_GPIO_CTL(_i) (0x00088100 + ((_i) * 4)) /* _i=0...29 */ /* Reset: POR */
#define I40E_GLGEN_GPIO_CTL_MAX_INDEX 29
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT 0
-#define I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK (0x3 << I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT 3
-#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK (0x1 << I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT 4
-#define I40E_GLGEN_GPIO_CTL_PIN_DIR_MASK (0x1 << I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PIN_DIR_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT)
#define I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT 5
-#define I40E_GLGEN_GPIO_CTL_TRI_CTL_MASK (0x1 << I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_TRI_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT)
#define I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT 6
-#define I40E_GLGEN_GPIO_CTL_OUT_CTL_MASK (0x1 << I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_OUT_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT 7
-#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK (0x7 << I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK I40E_MASK(0x7, I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT 10
-#define I40E_GLGEN_GPIO_CTL_LED_INVRT_MASK (0x1 << I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_INVRT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT 11
-#define I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK (0x1 << I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT 12
-#define I40E_GLGEN_GPIO_CTL_LED_MODE_MASK (0xF << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_MODE_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
#define I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT 17
-#define I40E_GLGEN_GPIO_CTL_INT_MODE_MASK (0x3 << I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_INT_MODE_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT)
#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT 19
-#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_MASK (0x1 << I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT 20
-#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_MASK (0x3F << I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT)
-#define I40E_GLGEN_GPIO_SET 0x00088184
+#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_MASK I40E_MASK(0x3F, I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT)
+#define I40E_GLGEN_GPIO_SET 0x00088184 /* Reset: POR */
#define I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT 0
-#define I40E_GLGEN_GPIO_SET_GPIO_INDX_MASK (0x1F << I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT)
+#define I40E_GLGEN_GPIO_SET_GPIO_INDX_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT)
#define I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT 5
-#define I40E_GLGEN_GPIO_SET_SDP_DATA_MASK (0x1 << I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT)
+#define I40E_GLGEN_GPIO_SET_SDP_DATA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT)
#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT 6
-#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_MASK (0x1 << I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT)
-#define I40E_GLGEN_GPIO_STAT 0x0008817C
+#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT)
+#define I40E_GLGEN_GPIO_STAT 0x0008817C /* Reset: POR */
#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT 0
-#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_MASK (0x3FFFFFFF << I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT)
-#define I40E_GLGEN_GPIO_TRANSIT 0x00088180
+#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT)
+#define I40E_GLGEN_GPIO_TRANSIT 0x00088180 /* Reset: POR */
#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT 0
-#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_MASK (0x3FFFFFFF << I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT)
-#define I40E_GLGEN_I2CCMD(_i) (0x000881E0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT)
+#define I40E_GLGEN_I2CCMD(_i) (0x000881E0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_I2CCMD_MAX_INDEX 3
#define I40E_GLGEN_I2CCMD_DATA_SHIFT 0
-#define I40E_GLGEN_I2CCMD_DATA_MASK (0xFFFF << I40E_GLGEN_I2CCMD_DATA_SHIFT)
+#define I40E_GLGEN_I2CCMD_DATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_I2CCMD_DATA_SHIFT)
#define I40E_GLGEN_I2CCMD_REGADD_SHIFT 16
-#define I40E_GLGEN_I2CCMD_REGADD_MASK (0xFF << I40E_GLGEN_I2CCMD_REGADD_SHIFT)
+#define I40E_GLGEN_I2CCMD_REGADD_MASK I40E_MASK(0xFF, I40E_GLGEN_I2CCMD_REGADD_SHIFT)
#define I40E_GLGEN_I2CCMD_PHYADD_SHIFT 24
-#define I40E_GLGEN_I2CCMD_PHYADD_MASK (0x7 << I40E_GLGEN_I2CCMD_PHYADD_SHIFT)
+#define I40E_GLGEN_I2CCMD_PHYADD_MASK I40E_MASK(0x7, I40E_GLGEN_I2CCMD_PHYADD_SHIFT)
#define I40E_GLGEN_I2CCMD_OP_SHIFT 27
-#define I40E_GLGEN_I2CCMD_OP_MASK (0x1 << I40E_GLGEN_I2CCMD_OP_SHIFT)
+#define I40E_GLGEN_I2CCMD_OP_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_OP_SHIFT)
#define I40E_GLGEN_I2CCMD_RESET_SHIFT 28
-#define I40E_GLGEN_I2CCMD_RESET_MASK (0x1 << I40E_GLGEN_I2CCMD_RESET_SHIFT)
+#define I40E_GLGEN_I2CCMD_RESET_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_RESET_SHIFT)
#define I40E_GLGEN_I2CCMD_R_SHIFT 29
-#define I40E_GLGEN_I2CCMD_R_MASK (0x1 << I40E_GLGEN_I2CCMD_R_SHIFT)
+#define I40E_GLGEN_I2CCMD_R_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_R_SHIFT)
#define I40E_GLGEN_I2CCMD_E_SHIFT 31
-#define I40E_GLGEN_I2CCMD_E_MASK (0x1 << I40E_GLGEN_I2CCMD_E_SHIFT)
-#define I40E_GLGEN_I2CPARAMS(_i) (0x000881AC + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_I2CCMD_E_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_E_SHIFT)
+#define I40E_GLGEN_I2CPARAMS(_i) (0x000881AC + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_I2CPARAMS_MAX_INDEX 3
#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT 0
-#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_MASK (0x1F << I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_MASK I40E_MASK(0x1F, I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT)
#define I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT 5
-#define I40E_GLGEN_I2CPARAMS_READ_TIME_MASK (0x7 << I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_READ_TIME_MASK I40E_MASK(0x7, I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT)
#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT 8
-#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_SHIFT 9
-#define I40E_GLGEN_I2CPARAMS_CLK_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT 10
-#define I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT 11
-#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT 12
-#define I40E_GLGEN_I2CPARAMS_DATA_IN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT 13
-#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT 14
-#define I40E_GLGEN_I2CPARAMS_CLK_IN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT 15
-#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT)
#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT 31
-#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_MASK (0x1 << I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT)
-#define I40E_GLGEN_LED_CTL 0x00088178
+#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT)
+#define I40E_GLGEN_LED_CTL 0x00088178 /* Reset: POR */
#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT 0
-#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_MASK (0x1 << I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL(_i) (0x000881D0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL(_i) (0x000881D0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MDIO_CTRL_MAX_INDEX 3
#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT 0
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_MASK (0x1FFFF << I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_MASK I40E_MASK(0x1FFFF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT)
#define I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT 17
-#define I40E_GLGEN_MDIO_CTRL_CONTMDC_MASK (0x1 << I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL_CONTMDC_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT)
#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT 18
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_MASK (0x3FFF << I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL(_i) (0x000881C0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_MASK I40E_MASK(0x3FFF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL(_i) (0x000881C0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MDIO_I2C_SEL_MAX_INDEX 3
#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT 0
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK (0x1 << I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT 1
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK (0xF << I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT 5
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT 10
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT 15
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT 20
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT 25
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_MASK (0xF << I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT 31
-#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_MASK (0x1 << I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT)
-#define I40E_GLGEN_MSCA(_i) (0x0008818C + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT)
+#define I40E_GLGEN_MSCA(_i) (0x0008818C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MSCA_MAX_INDEX 3
#define I40E_GLGEN_MSCA_MDIADD_SHIFT 0
-#define I40E_GLGEN_MSCA_MDIADD_MASK (0xFFFF << I40E_GLGEN_MSCA_MDIADD_SHIFT)
+#define I40E_GLGEN_MSCA_MDIADD_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSCA_MDIADD_SHIFT)
#define I40E_GLGEN_MSCA_DEVADD_SHIFT 16
-#define I40E_GLGEN_MSCA_DEVADD_MASK (0x1F << I40E_GLGEN_MSCA_DEVADD_SHIFT)
+#define I40E_GLGEN_MSCA_DEVADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_DEVADD_SHIFT)
#define I40E_GLGEN_MSCA_PHYADD_SHIFT 21
-#define I40E_GLGEN_MSCA_PHYADD_MASK (0x1F << I40E_GLGEN_MSCA_PHYADD_SHIFT)
+#define I40E_GLGEN_MSCA_PHYADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_PHYADD_SHIFT)
#define I40E_GLGEN_MSCA_OPCODE_SHIFT 26
-#define I40E_GLGEN_MSCA_OPCODE_MASK (0x3 << I40E_GLGEN_MSCA_OPCODE_SHIFT)
+#define I40E_GLGEN_MSCA_OPCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_OPCODE_SHIFT)
#define I40E_GLGEN_MSCA_STCODE_SHIFT 28
-#define I40E_GLGEN_MSCA_STCODE_MASK (0x3 << I40E_GLGEN_MSCA_STCODE_SHIFT)
+#define I40E_GLGEN_MSCA_STCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_STCODE_SHIFT)
#define I40E_GLGEN_MSCA_MDICMD_SHIFT 30
-#define I40E_GLGEN_MSCA_MDICMD_MASK (0x1 << I40E_GLGEN_MSCA_MDICMD_SHIFT)
+#define I40E_GLGEN_MSCA_MDICMD_MASK I40E_MASK(0x1, I40E_GLGEN_MSCA_MDICMD_SHIFT)
#define I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT 31
-#define I40E_GLGEN_MSCA_MDIINPROGEN_MASK (0x1 << I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT)
-#define I40E_GLGEN_MSRWD(_i) (0x0008819C + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MSCA_MDIINPROGEN_MASK I40E_MASK(0x1, I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT)
+#define I40E_GLGEN_MSRWD(_i) (0x0008819C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MSRWD_MAX_INDEX 3
#define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
-#define I40E_GLGEN_MSRWD_MDIWRDATA_MASK (0xFFFF << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT)
+#define I40E_GLGEN_MSRWD_MDIWRDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT)
#define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
-#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK (0xFFFF << I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
-#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4
+#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4 /* Reset: PCIR */
#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
-#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK (0x1F << I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
-#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK (0xFF << I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
-#define I40E_GLGEN_PE_ENA 0x000B81A0
-#define I40E_GLGEN_PE_ENA_PE_ENA_SHIFT 0
-#define I40E_GLGEN_PE_ENA_PE_ENA_MASK (0x1 << I40E_GLGEN_PE_ENA_PE_ENA_SHIFT)
-#define I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_SHIFT 1
-#define I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_MASK (0x3 << I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_SHIFT)
-#define I40E_GLGEN_RSTAT 0x000B8188
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
+#define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
#define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
-#define I40E_GLGEN_RSTAT_DEVSTATE_MASK (0x3 << I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
+#define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
#define I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT 2
-#define I40E_GLGEN_RSTAT_RESET_TYPE_MASK (0x3 << I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT)
+#define I40E_GLGEN_RSTAT_RESET_TYPE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT)
#define I40E_GLGEN_RSTAT_CORERCNT_SHIFT 4
-#define I40E_GLGEN_RSTAT_CORERCNT_MASK (0x3 << I40E_GLGEN_RSTAT_CORERCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_CORERCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_CORERCNT_SHIFT)
#define I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT 6
-#define I40E_GLGEN_RSTAT_GLOBRCNT_MASK (0x3 << I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_GLOBRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT)
#define I40E_GLGEN_RSTAT_EMPRCNT_SHIFT 8
-#define I40E_GLGEN_RSTAT_EMPRCNT_MASK (0x3 << I40E_GLGEN_RSTAT_EMPRCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_EMPRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_EMPRCNT_SHIFT)
#define I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT 10
-#define I40E_GLGEN_RSTAT_TIME_TO_RST_MASK (0x3F << I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT)
-#define I40E_GLGEN_RSTCTL 0x000B8180
+#define I40E_GLGEN_RSTAT_TIME_TO_RST_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT)
+#define I40E_GLGEN_RSTCTL 0x000B8180 /* Reset: POR */
#define I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT 0
-#define I40E_GLGEN_RSTCTL_GRSTDEL_MASK (0x3F << I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT)
+#define I40E_GLGEN_RSTCTL_GRSTDEL_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT)
#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT 8
-#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_MASK (0x1 << I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT)
-#define I40E_GLGEN_RSTENA_EMP 0x000B818C
+#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_MASK I40E_MASK(0x1, I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT)
+#define I40E_GLGEN_RSTENA_EMP 0x000B818C /* Reset: POR */
#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT 0
-#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_MASK (0x1 << I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT)
-#define I40E_GLGEN_RTRIG 0x000B8190
+#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_MASK I40E_MASK(0x1, I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT)
+#define I40E_GLGEN_RTRIG 0x000B8190 /* Reset: CORER */
#define I40E_GLGEN_RTRIG_CORER_SHIFT 0
-#define I40E_GLGEN_RTRIG_CORER_MASK (0x1 << I40E_GLGEN_RTRIG_CORER_SHIFT)
+#define I40E_GLGEN_RTRIG_CORER_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_CORER_SHIFT)
#define I40E_GLGEN_RTRIG_GLOBR_SHIFT 1
-#define I40E_GLGEN_RTRIG_GLOBR_MASK (0x1 << I40E_GLGEN_RTRIG_GLOBR_SHIFT)
+#define I40E_GLGEN_RTRIG_GLOBR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_GLOBR_SHIFT)
#define I40E_GLGEN_RTRIG_EMPFWR_SHIFT 2
-#define I40E_GLGEN_RTRIG_EMPFWR_MASK (0x1 << I40E_GLGEN_RTRIG_EMPFWR_SHIFT)
-#define I40E_GLGEN_STAT 0x000B612C
+#define I40E_GLGEN_RTRIG_EMPFWR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_EMPFWR_SHIFT)
+#define I40E_GLGEN_STAT 0x000B612C /* Reset: POR */
#define I40E_GLGEN_STAT_HWRSVD0_SHIFT 0
-#define I40E_GLGEN_STAT_HWRSVD0_MASK (0x3 << I40E_GLGEN_STAT_HWRSVD0_SHIFT)
+#define I40E_GLGEN_STAT_HWRSVD0_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD0_SHIFT)
#define I40E_GLGEN_STAT_DCBEN_SHIFT 2
-#define I40E_GLGEN_STAT_DCBEN_MASK (0x1 << I40E_GLGEN_STAT_DCBEN_SHIFT)
+#define I40E_GLGEN_STAT_DCBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_DCBEN_SHIFT)
#define I40E_GLGEN_STAT_VTEN_SHIFT 3
-#define I40E_GLGEN_STAT_VTEN_MASK (0x1 << I40E_GLGEN_STAT_VTEN_SHIFT)
+#define I40E_GLGEN_STAT_VTEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_VTEN_SHIFT)
#define I40E_GLGEN_STAT_FCOEN_SHIFT 4
-#define I40E_GLGEN_STAT_FCOEN_MASK (0x1 << I40E_GLGEN_STAT_FCOEN_SHIFT)
+#define I40E_GLGEN_STAT_FCOEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_FCOEN_SHIFT)
#define I40E_GLGEN_STAT_EVBEN_SHIFT 5
-#define I40E_GLGEN_STAT_EVBEN_MASK (0x1 << I40E_GLGEN_STAT_EVBEN_SHIFT)
+#define I40E_GLGEN_STAT_EVBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_EVBEN_SHIFT)
#define I40E_GLGEN_STAT_HWRSVD1_SHIFT 6
-#define I40E_GLGEN_STAT_HWRSVD1_MASK (0x3 << I40E_GLGEN_STAT_HWRSVD1_SHIFT)
-#define I40E_GLGEN_VFLRSTAT(_i) (0x00092600 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_STAT_HWRSVD1_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD1_SHIFT)
+#define I40E_GLGEN_VFLRSTAT(_i) (0x00092600 + ((_i) * 4)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLGEN_VFLRSTAT_MAX_INDEX 3
#define I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT 0
-#define I40E_GLGEN_VFLRSTAT_VFLRE_MASK (0xFFFFFFFF << I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT)
-#define I40E_GLVFGEN_TIMER 0x000881BC
+#define I40E_GLGEN_VFLRSTAT_VFLRE_MASK I40E_MASK(0xFFFFFFFF, I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT)
+#define I40E_GLVFGEN_TIMER 0x000881BC /* Reset: CORER */
#define I40E_GLVFGEN_TIMER_GTIME_SHIFT 0
-#define I40E_GLVFGEN_TIMER_GTIME_MASK (0xFFFFFFFF << I40E_GLVFGEN_TIMER_GTIME_SHIFT)
-#define I40E_PFGEN_CTRL 0x00092400
+#define I40E_GLVFGEN_TIMER_GTIME_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVFGEN_TIMER_GTIME_SHIFT)
+#define I40E_PFGEN_CTRL 0x00092400 /* Reset: PFR */
#define I40E_PFGEN_CTRL_PFSWR_SHIFT 0
-#define I40E_PFGEN_CTRL_PFSWR_MASK (0x1 << I40E_PFGEN_CTRL_PFSWR_SHIFT)
-#define I40E_PFGEN_DRUN 0x00092500
+#define I40E_PFGEN_CTRL_PFSWR_MASK I40E_MASK(0x1, I40E_PFGEN_CTRL_PFSWR_SHIFT)
+#define I40E_PFGEN_DRUN 0x00092500 /* Reset: CORER */
#define I40E_PFGEN_DRUN_DRVUNLD_SHIFT 0
-#define I40E_PFGEN_DRUN_DRVUNLD_MASK (0x1 << I40E_PFGEN_DRUN_DRVUNLD_SHIFT)
-#define I40E_PFGEN_PORTNUM 0x001C0480
+#define I40E_PFGEN_DRUN_DRVUNLD_MASK I40E_MASK(0x1, I40E_PFGEN_DRUN_DRVUNLD_SHIFT)
+#define I40E_PFGEN_PORTNUM 0x001C0480 /* Reset: CORER */
#define I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT 0
-#define I40E_PFGEN_PORTNUM_PORT_NUM_MASK (0x3 << I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT)
-#define I40E_PFGEN_STATE 0x00088000
-#define I40E_PFGEN_STATE_PFPEEN_SHIFT 0
-#define I40E_PFGEN_STATE_PFPEEN_MASK (0x1 << I40E_PFGEN_STATE_PFPEEN_SHIFT)
+#define I40E_PFGEN_PORTNUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT)
+#define I40E_PFGEN_STATE 0x00088000 /* Reset: CORER */
+#define I40E_PFGEN_STATE_RESERVED_0_SHIFT 0
+#define I40E_PFGEN_STATE_RESERVED_0_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_RESERVED_0_SHIFT)
#define I40E_PFGEN_STATE_PFFCEN_SHIFT 1
-#define I40E_PFGEN_STATE_PFFCEN_MASK (0x1 << I40E_PFGEN_STATE_PFFCEN_SHIFT)
+#define I40E_PFGEN_STATE_PFFCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFFCEN_SHIFT)
#define I40E_PFGEN_STATE_PFLINKEN_SHIFT 2
-#define I40E_PFGEN_STATE_PFLINKEN_MASK (0x1 << I40E_PFGEN_STATE_PFLINKEN_SHIFT)
+#define I40E_PFGEN_STATE_PFLINKEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFLINKEN_SHIFT)
#define I40E_PFGEN_STATE_PFSCEN_SHIFT 3
-#define I40E_PFGEN_STATE_PFSCEN_MASK (0x1 << I40E_PFGEN_STATE_PFSCEN_SHIFT)
-#define I40E_PRTGEN_CNF 0x000B8120
+#define I40E_PFGEN_STATE_PFSCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFSCEN_SHIFT)
+#define I40E_PRTGEN_CNF 0x000B8120 /* Reset: POR */
#define I40E_PRTGEN_CNF_PORT_DIS_SHIFT 0
-#define I40E_PRTGEN_CNF_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_PORT_DIS_SHIFT)
#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT 1
-#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT)
#define I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT 2
-#define I40E_PRTGEN_CNF_EMP_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT)
-#define I40E_PRTGEN_CNF2 0x000B8160
+#define I40E_PRTGEN_CNF_EMP_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF2 0x000B8160 /* Reset: POR */
#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT 0
-#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_MASK (0x1 << I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT)
-#define I40E_PRTGEN_STATUS 0x000B8100
+#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT)
+#define I40E_PRTGEN_STATUS 0x000B8100 /* Reset: POR */
#define I40E_PRTGEN_STATUS_PORT_VALID_SHIFT 0
-#define I40E_PRTGEN_STATUS_PORT_VALID_MASK (0x1 << I40E_PRTGEN_STATUS_PORT_VALID_SHIFT)
+#define I40E_PRTGEN_STATUS_PORT_VALID_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_VALID_SHIFT)
#define I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT 1
-#define I40E_PRTGEN_STATUS_PORT_ACTIVE_MASK (0x1 << I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT)
-#define I40E_VFGEN_RSTAT1(_VF) (0x00074400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PRTGEN_STATUS_PORT_ACTIVE_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT)
+#define I40E_VFGEN_RSTAT1(_VF) (0x00074400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFGEN_RSTAT1_MAX_INDEX 127
#define I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT1_VFR_STATE_MASK (0x3 << I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT)
-#define I40E_VPGEN_VFRSTAT(_VF) (0x00091C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFGEN_RSTAT1_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT)
+#define I40E_VPGEN_VFRSTAT(_VF) (0x00091C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPGEN_VFRSTAT_MAX_INDEX 127
#define I40E_VPGEN_VFRSTAT_VFRD_SHIFT 0
-#define I40E_VPGEN_VFRSTAT_VFRD_MASK (0x1 << I40E_VPGEN_VFRSTAT_VFRD_SHIFT)
-#define I40E_VPGEN_VFRTRIG(_VF) (0x00091800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPGEN_VFRSTAT_VFRD_MASK I40E_MASK(0x1, I40E_VPGEN_VFRSTAT_VFRD_SHIFT)
+#define I40E_VPGEN_VFRTRIG(_VF) (0x00091800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPGEN_VFRTRIG_MAX_INDEX 127
#define I40E_VPGEN_VFRTRIG_VFSWR_SHIFT 0
-#define I40E_VPGEN_VFRTRIG_VFSWR_MASK (0x1 << I40E_VPGEN_VFRTRIG_VFSWR_SHIFT)
-#define I40E_VSIGEN_RSTAT(_VSI) (0x00090800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPGEN_VFRTRIG_VFSWR_MASK I40E_MASK(0x1, I40E_VPGEN_VFRTRIG_VFSWR_SHIFT)
+#define I40E_VSIGEN_RSTAT(_VSI) (0x00090800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_VSIGEN_RSTAT_MAX_INDEX 383
#define I40E_VSIGEN_RSTAT_VMRD_SHIFT 0
-#define I40E_VSIGEN_RSTAT_VMRD_MASK (0x1 << I40E_VSIGEN_RSTAT_VMRD_SHIFT)
-#define I40E_VSIGEN_RTRIG(_VSI) (0x00090000 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VSIGEN_RSTAT_VMRD_MASK I40E_MASK(0x1, I40E_VSIGEN_RSTAT_VMRD_SHIFT)
+#define I40E_VSIGEN_RTRIG(_VSI) (0x00090000 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_VSIGEN_RTRIG_MAX_INDEX 383
#define I40E_VSIGEN_RTRIG_VMSWR_SHIFT 0
-#define I40E_VSIGEN_RTRIG_VMSWR_MASK (0x1 << I40E_VSIGEN_RTRIG_VMSWR_SHIFT)
-#define I40E_GLHMC_APBVTINUSEBASE(_i) (0x000C4a00 + ((_i) * 4))
-#define I40E_GLHMC_APBVTINUSEBASE_MAX_INDEX 15
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_MASK (0xFFFFFF << I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_CEQPART(_i) (0x001312C0 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_CEQPART_MAX_INDEX 15
-#define I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_CEQPART_PMCEQBASE_MASK (0xFF << I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_MASK (0x1FF << I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_DBCQPART(_i) (0x00131240 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_DBCQPART_MAX_INDEX 15
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_MASK (0x3FFF << I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_MASK (0x7FFF << I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_DBQPPART(_i) (0x00138D80 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_DBQPPART_MAX_INDEX 15
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_MASK (0x3FFF << I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_MASK (0x7FFF << I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_FCOEDDPBASE(_i) (0x000C6600 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_VSIGEN_RTRIG_VMSWR_MASK I40E_MASK(0x1, I40E_VSIGEN_RTRIG_VMSWR_SHIFT)
+#define I40E_GLHMC_FCOEDDPBASE(_i) (0x000C6600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT 0
-#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK (0xFFFFFF << I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT)
-#define I40E_GLHMC_FCOEDDPCNT(_i) (0x000C6700 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT)
+#define I40E_GLHMC_FCOEDDPCNT(_i) (0x000C6700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPCNT_MAX_INDEX 15
#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT 0
-#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_MASK (0xFFFFF << I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT)
-#define I40E_GLHMC_FCOEDDPOBJSZ 0x000C2010
+#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_MASK I40E_MASK(0xFFFFF, I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT)
+#define I40E_GLHMC_FCOEDDPOBJSZ 0x000C2010 /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_MASK (0xF << I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT)
-#define I40E_GLHMC_FCOEFBASE(_i) (0x000C6800 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT)
+#define I40E_GLHMC_FCOEFBASE(_i) (0x000C6800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEFBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT 0
-#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK (0xFFFFFF << I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT)
-#define I40E_GLHMC_FCOEFCNT(_i) (0x000C6900 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT)
+#define I40E_GLHMC_FCOEFCNT(_i) (0x000C6900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEFCNT_MAX_INDEX 15
#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT 0
-#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_MASK (0x7FFFFF << I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT)
-#define I40E_GLHMC_FCOEFMAX 0x000C20D0
+#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_MASK I40E_MASK(0x7FFFFF, I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT)
+#define I40E_GLHMC_FCOEFMAX 0x000C20D0 /* Reset: CORER */
#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT 0
-#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK (0xFFFF << I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT)
-#define I40E_GLHMC_FCOEFOBJSZ 0x000C2018
+#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK I40E_MASK(0xFFFF, I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT)
+#define I40E_GLHMC_FCOEFOBJSZ 0x000C2018 /* Reset: CORER */
#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_MASK (0xF << I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT)
-#define I40E_GLHMC_FCOEMAX 0x000C2014
+#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT)
+#define I40E_GLHMC_FCOEMAX 0x000C2014 /* Reset: CORER */
#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT 0
-#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_MASK (0x1FFF << I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT)
-#define I40E_GLHMC_FSIAVBASE(_i) (0x000C5600 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_MASK I40E_MASK(0x1FFF, I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT)
+#define I40E_GLHMC_FSIAVBASE(_i) (0x000C5600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIAVBASE_MAX_INDEX 15
#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_MASK (0xFFFFFF << I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_FSIAVCNT(_i) (0x000C5700 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT)
+#define I40E_GLHMC_FSIAVCNT(_i) (0x000C5700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIAVCNT_MAX_INDEX 15
#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_MASK (0x1FFFFFFF << I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT)
+#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT)
#define I40E_GLHMC_FSIAVCNT_RSVD_SHIFT 29
-#define I40E_GLHMC_FSIAVCNT_RSVD_MASK (0x7 << I40E_GLHMC_FSIAVCNT_RSVD_SHIFT)
-#define I40E_GLHMC_FSIAVMAX 0x000C2068
+#define I40E_GLHMC_FSIAVCNT_RSVD_MASK I40E_MASK(0x7, I40E_GLHMC_FSIAVCNT_RSVD_SHIFT)
+#define I40E_GLHMC_FSIAVMAX 0x000C2068 /* Reset: CORER */
#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT 0
-#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_MASK (0x1FFFF << I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT)
-#define I40E_GLHMC_FSIAVOBJSZ 0x000C2064
+#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_MASK I40E_MASK(0x1FFFF, I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT)
+#define I40E_GLHMC_FSIAVOBJSZ 0x000C2064 /* Reset: CORER */
#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_MASK (0xF << I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT)
-#define I40E_GLHMC_FSIMCBASE(_i) (0x000C6000 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT)
+#define I40E_GLHMC_FSIMCBASE(_i) (0x000C6000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIMCBASE_MAX_INDEX 15
#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT 0
-#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_MASK (0xFFFFFF << I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT)
-#define I40E_GLHMC_FSIMCCNT(_i) (0x000C6100 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT)
+#define I40E_GLHMC_FSIMCCNT(_i) (0x000C6100 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIMCCNT_MAX_INDEX 15
#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_MASK (0x1FFFFFFF << I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT)
-#define I40E_GLHMC_FSIMCMAX 0x000C2060
+#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT)
+#define I40E_GLHMC_FSIMCMAX 0x000C2060 /* Reset: CORER */
#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT 0
-#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_MASK (0x3FFF << I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT)
-#define I40E_GLHMC_FSIMCOBJSZ 0x000C205c
+#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_MASK I40E_MASK(0x3FFF, I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT)
+#define I40E_GLHMC_FSIMCOBJSZ 0x000C205c /* Reset: CORER */
#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_MASK (0xF << I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT)
-#define I40E_GLHMC_LANQMAX 0x000C2008
+#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT)
+#define I40E_GLHMC_LANQMAX 0x000C2008 /* Reset: CORER */
#define I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT 0
-#define I40E_GLHMC_LANQMAX_PMLANQMAX_MASK (0x7FF << I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT)
-#define I40E_GLHMC_LANRXBASE(_i) (0x000C6400 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANQMAX_PMLANQMAX_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT)
+#define I40E_GLHMC_LANRXBASE(_i) (0x000C6400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANRXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT 0
-#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK (0xFFFFFF << I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT)
-#define I40E_GLHMC_LANRXCNT(_i) (0x000C6500 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT)
+#define I40E_GLHMC_LANRXCNT(_i) (0x000C6500 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANRXCNT_MAX_INDEX 15
#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT 0
-#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_MASK (0x7FF << I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT)
-#define I40E_GLHMC_LANRXOBJSZ 0x000C200c
+#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT)
+#define I40E_GLHMC_LANRXOBJSZ 0x000C200c /* Reset: CORER */
#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_MASK (0xF << I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT)
-#define I40E_GLHMC_LANTXBASE(_i) (0x000C6200 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT)
+#define I40E_GLHMC_LANTXBASE(_i) (0x000C6200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANTXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT 0
-#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK (0xFFFFFF << I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT)
+#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT)
#define I40E_GLHMC_LANTXBASE_RSVD_SHIFT 24
-#define I40E_GLHMC_LANTXBASE_RSVD_MASK (0xFF << I40E_GLHMC_LANTXBASE_RSVD_SHIFT)
-#define I40E_GLHMC_LANTXCNT(_i) (0x000C6300 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANTXBASE_RSVD_MASK I40E_MASK(0xFF, I40E_GLHMC_LANTXBASE_RSVD_SHIFT)
+#define I40E_GLHMC_LANTXCNT(_i) (0x000C6300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANTXCNT_MAX_INDEX 15
#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT 0
-#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_MASK (0x7FF << I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT)
-#define I40E_GLHMC_LANTXOBJSZ 0x000C2004
+#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT)
+#define I40E_GLHMC_LANTXOBJSZ 0x000C2004 /* Reset: CORER */
#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_MASK (0xF << I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT)
-#define I40E_GLHMC_PEARPBASE(_i) (0x000C4800 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEARPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_MASK (0xFFFFFF << I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_PEARPCNT(_i) (0x000C4900 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEARPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_PEARPMAX 0x000C2038
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT 0
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_MASK (0x1FFFF << I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT)
-#define I40E_GLHMC_PEARPOBJSZ 0x000C2034
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_MASK (0x7 << I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT)
-#define I40E_GLHMC_PECQBASE(_i) (0x000C4200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PECQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_MASK (0xFFFFFF << I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_PECQCNT(_i) (0x000C4300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PECQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_PECQOBJSZ 0x000C2020
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_MASK (0xF << I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTCNT(_i) (0x000C4700 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEHTCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_PEHTEBASE(_i) (0x000C4600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEHTEBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_MASK (0xFFFFFF << I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_PEHTEOBJSZ 0x000C202c
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_MASK (0xF << I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTMAX 0x000C2030
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT 0
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_MASK (0x1FFFFF << I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT)
-#define I40E_GLHMC_PEMRBASE(_i) (0x000C4c00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEMRBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_MASK (0xFFFFFF << I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_PEMRCNT(_i) (0x000C4d00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEMRCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_MASK (0x1FFFFFFF << I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_PEMRMAX 0x000C2040
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT 0
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_MASK (0x7FFFFF << I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT)
-#define I40E_GLHMC_PEMROBJSZ 0x000C203c
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT 0
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_MASK (0xF << I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT)
-#define I40E_GLHMC_PEPBLBASE(_i) (0x000C5800 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEPBLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_PEPBLCNT(_i) (0x000C5900 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEPBLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_PEPBLMAX 0x000C206c
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT 0
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_MASK (0x1FFFFFFF << I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT)
-#define I40E_GLHMC_PEQ1BASE(_i) (0x000C5200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1BASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_MASK (0xFFFFFF << I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_PEQ1CNT(_i) (0x000C5300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1CNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_PEQ1FLBASE(_i) (0x000C5400 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1FLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_PEQ1FLCNT(_i) (0x000C5500 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1FLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_SHIFT 0
-#define I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_SHIFT)
-#define I40E_GLHMC_PEQ1FLMAX 0x000C2058
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT 0
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_MASK (0x3FFFFFF << I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT)
-#define I40E_GLHMC_PEQ1MAX 0x000C2054
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT 0
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_MASK (0x3FFFFFF << I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT)
-#define I40E_GLHMC_PEQ1OBJSZ 0x000C2050
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_MASK (0xF << I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT)
-#define I40E_GLHMC_PEQPBASE(_i) (0x000C4000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_MASK (0xFFFFFF << I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_PEQPCNT(_i) (0x000C4100 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_PEQPOBJSZ 0x000C201c
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_MASK (0xF << I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT)
-#define I40E_GLHMC_PESRQBASE(_i) (0x000C4400 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PESRQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_MASK (0xFFFFFF << I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_PESRQCNT(_i) (0x000C4500 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PESRQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_PESRQMAX 0x000C2028
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT 0
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_MASK (0xFFFF << I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT)
-#define I40E_GLHMC_PESRQOBJSZ 0x000C2024
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_MASK (0xF << I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT)
-#define I40E_GLHMC_PESRQOBJSZ_RSVD_SHIFT 4
-#define I40E_GLHMC_PESRQOBJSZ_RSVD_MASK (0xFFFFFFF << I40E_GLHMC_PESRQOBJSZ_RSVD_SHIFT)
-#define I40E_GLHMC_PETIMERBASE(_i) (0x000C5A00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PETIMERBASE_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_MASK (0xFFFFFF << I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_PETIMERCNT(_i) (0x000C5B00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PETIMERCNT_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_PETIMERMAX 0x000C2084
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT 0
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_MASK (0x1FFFFFFF << I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT)
-#define I40E_GLHMC_PETIMEROBJSZ 0x000C2080
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT 0
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_MASK (0xF << I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT)
-#define I40E_GLHMC_PEXFBASE(_i) (0x000C4e00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_MASK (0xFFFFFF << I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_PEXFCNT(_i) (0x000C4f00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_PEXFFLBASE(_i) (0x000C5000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFFLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_PEXFFLCNT(_i) (0x000C5100 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFFLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_SHIFT 0
-#define I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_SHIFT)
-#define I40E_GLHMC_PEXFFLMAX 0x000C204c
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT 0
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_MASK (0x1FFFFFF << I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT)
-#define I40E_GLHMC_PEXFMAX 0x000C2048
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT 0
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_MASK (0x3FFFFFF << I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT)
-#define I40E_GLHMC_PEXFOBJSZ 0x000C2044
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_MASK (0xF << I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT)
-#define I40E_GLHMC_PEXFOBJSZ_RSVD_SHIFT 4
-#define I40E_GLHMC_PEXFOBJSZ_RSVD_MASK (0xFFFFFFF << I40E_GLHMC_PEXFOBJSZ_RSVD_SHIFT)
-#define I40E_GLHMC_PFASSIGN(_i) (0x000C0c00 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT)
+#define I40E_GLHMC_PFASSIGN(_i) (0x000C0c00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_PFASSIGN_MAX_INDEX 15
#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT 0
-#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_MASK (0xF << I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT)
-#define I40E_GLHMC_SDPART(_i) (0x000C0800 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_MASK I40E_MASK(0xF, I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT)
+#define I40E_GLHMC_SDPART(_i) (0x000C0800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_SDPART_MAX_INDEX 15
#define I40E_GLHMC_SDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_SDPART_PMSDBASE_MASK (0xFFF << I40E_GLHMC_SDPART_PMSDBASE_SHIFT)
+#define I40E_GLHMC_SDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_SDPART_PMSDBASE_SHIFT)
#define I40E_GLHMC_SDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_SDPART_PMSDSIZE_MASK (0x1FFF << I40E_GLHMC_SDPART_PMSDSIZE_SHIFT)
-#define I40E_GLHMC_VFAPBVTINUSEBASE(_i) (0x000Cca00 + ((_i) * 4))
-#define I40E_GLHMC_VFAPBVTINUSEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_MASK (0xFFFFFF << I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART(_i) (0x00132240 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFCEQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_MASK (0xFF << I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_MASK (0x1FF << I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART(_i) (0x00132140 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFDBCQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_MASK (0x3FFF << I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_MASK (0x7FFF << I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART(_i) (0x00138E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFDBQPPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_MASK (0x3FFF << I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_MASK (0x7FFF << I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_VFFSIAVBASE(_i) (0x000Cd600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFFSIAVBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_MASK (0xFFFFFF << I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_VFFSIAVCNT(_i) (0x000Cd700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFFSIAVCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT)
-#define I40E_GLHMC_VFFSIAVCNT_RSVD_SHIFT 29
-#define I40E_GLHMC_VFFSIAVCNT_RSVD_MASK (0x7 << I40E_GLHMC_VFFSIAVCNT_RSVD_SHIFT)
-#define I40E_GLHMC_VFPDINV(_i) (0x000C8300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPDINV_MAX_INDEX 31
-#define I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT 0
-#define I40E_GLHMC_VFPDINV_PMSDIDX_MASK (0xFFF << I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT)
-#define I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT 16
-#define I40E_GLHMC_VFPDINV_PMPDIDX_MASK (0x1FF << I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT)
-#define I40E_GLHMC_VFPEARPBASE(_i) (0x000Cc800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEARPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_VFPEARPCNT(_i) (0x000Cc900 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEARPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_VFPECQBASE(_i) (0x000Cc200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPECQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_VFPECQCNT(_i) (0x000Cc300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPECQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTCNT(_i) (0x000Cc700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEHTCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTEBASE(_i) (0x000Cc600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEHTEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRBASE(_i) (0x000Ccc00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEMRBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRCNT(_i) (0x000Ccd00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEMRCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_VFPEPBLBASE(_i) (0x000Cd800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEPBLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_VFPEPBLCNT(_i) (0x000Cd900 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEPBLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1BASE(_i) (0x000Cd200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1BASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_VFPEQ1CNT(_i) (0x000Cd300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1CNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1FLBASE(_i) (0x000Cd400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1FLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_VFPEQ1FLCNT(_i) (0x000Cd500 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1FLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_SHIFT)
-#define I40E_GLHMC_VFPEQPBASE(_i) (0x000Cc000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_VFPEQPCNT(_i) (0x000Cc100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_VFPESRQBASE(_i) (0x000Cc400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPESRQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_VFPESRQCNT(_i) (0x000Cc500 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPESRQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_VFPETIMERBASE(_i) (0x000CDA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPETIMERBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_VFPETIMERCNT(_i) (0x000CDB00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPETIMERCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFBASE(_i) (0x000Cce00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_VFPEXFCNT(_i) (0x000Ccf00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFFLBASE(_i) (0x000Cd000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFFLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_VFPEXFFLCNT(_i) (0x000Cd100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFFLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_SHIFT)
-#define I40E_GLHMC_VFSDPART(_i) (0x000C8800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFSDPART_MAX_INDEX 31
-#define I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_VFSDPART_PMSDBASE_MASK (0xFFF << I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT)
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_MASK (0x1FFF << I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT)
-#define I40E_PFHMC_ERRORDATA 0x000C0500
+#define I40E_GLHMC_SDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_SDPART_PMSDSIZE_SHIFT)
+#define I40E_PFHMC_ERRORDATA 0x000C0500 /* Reset: PFR */
#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT 0
-#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_MASK (0x3FFFFFFF << I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT)
-#define I40E_PFHMC_ERRORINFO 0x000C0400
+#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_MASK I40E_MASK(0x3FFFFFFF, I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT)
+#define I40E_PFHMC_ERRORINFO 0x000C0400 /* Reset: PFR */
#define I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT 0
-#define I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK (0x1F << I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT)
+#define I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT)
#define I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT 7
-#define I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK (0x1 << I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT)
+#define I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT)
#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT 8
-#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK (0xF << I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT)
+#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK I40E_MASK(0xF, I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT)
#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT 16
-#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK (0x1F << I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT)
+#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT)
#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT 31
-#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK (0x1 << I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT)
-#define I40E_PFHMC_PDINV 0x000C0300
+#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT)
+#define I40E_PFHMC_PDINV 0x000C0300 /* Reset: PFR */
#define I40E_PFHMC_PDINV_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_PDINV_PMSDIDX_MASK (0xFFF << I40E_PFHMC_PDINV_PMSDIDX_SHIFT)
+#define I40E_PFHMC_PDINV_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_PDINV_PMSDIDX_SHIFT)
#define I40E_PFHMC_PDINV_PMPDIDX_SHIFT 16
-#define I40E_PFHMC_PDINV_PMPDIDX_MASK (0x1FF << I40E_PFHMC_PDINV_PMPDIDX_SHIFT)
-#define I40E_PFHMC_SDCMD 0x000C0000
+#define I40E_PFHMC_PDINV_PMPDIDX_MASK I40E_MASK(0x1FF, I40E_PFHMC_PDINV_PMPDIDX_SHIFT)
+#define I40E_PFHMC_SDCMD 0x000C0000 /* Reset: PFR */
#define I40E_PFHMC_SDCMD_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_SDCMD_PMSDIDX_MASK (0xFFF << I40E_PFHMC_SDCMD_PMSDIDX_SHIFT)
+#define I40E_PFHMC_SDCMD_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_SDCMD_PMSDIDX_SHIFT)
#define I40E_PFHMC_SDCMD_PMSDWR_SHIFT 31
-#define I40E_PFHMC_SDCMD_PMSDWR_MASK (0x1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT)
-#define I40E_PFHMC_SDDATAHIGH 0x000C0200
+#define I40E_PFHMC_SDCMD_PMSDWR_MASK I40E_MASK(0x1, I40E_PFHMC_SDCMD_PMSDWR_SHIFT)
+#define I40E_PFHMC_SDDATAHIGH 0x000C0200 /* Reset: PFR */
#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT 0
-#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_MASK (0xFFFFFFFF << I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT)
-#define I40E_PFHMC_SDDATALOW 0x000C0100
+#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT)
+#define I40E_PFHMC_SDDATALOW 0x000C0100 /* Reset: PFR */
#define I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT 0
-#define I40E_PFHMC_SDDATALOW_PMSDVALID_MASK (0x1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDVALID_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT 1
-#define I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK (0x1 << I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT 2
-#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK (0x3FF << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK I40E_MASK(0x3FF, I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT 12
-#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK (0xFFFFF << I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
-#define I40E_GL_UFUSE 0x00094008
+#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK I40E_MASK(0xFFFFF, I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
+#define I40E_GL_GP_FUSE(_i) (0x0009400C + ((_i) * 4)) /* _i=0...28 */ /* Reset: POR */
+#define I40E_GL_GP_FUSE_MAX_INDEX 28
+#define I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT 0
+#define I40E_GL_GP_FUSE_GL_GP_FUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT)
+#define I40E_GL_UFUSE 0x00094008 /* Reset: POR */
#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT 1
-#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_MASK (0x1 << I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT)
+#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_MASK I40E_MASK(0x1, I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT)
#define I40E_GL_UFUSE_NIC_ID_SHIFT 2
-#define I40E_GL_UFUSE_NIC_ID_MASK (0x1 << I40E_GL_UFUSE_NIC_ID_SHIFT)
+#define I40E_GL_UFUSE_NIC_ID_MASK I40E_MASK(0x1, I40E_GL_UFUSE_NIC_ID_SHIFT)
#define I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT 10
-#define I40E_GL_UFUSE_ULT_LOCKOUT_MASK (0x1 << I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT)
+#define I40E_GL_UFUSE_ULT_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT)
#define I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT 11
-#define I40E_GL_UFUSE_CLS_LOCKOUT_MASK (0x1 << I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT)
-#define I40E_EMPINT_GPIO_ENA 0x00088188
+#define I40E_GL_UFUSE_CLS_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT)
+#define I40E_EMPINT_GPIO_ENA 0x00088188 /* Reset: POR */
#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT)
-#define I40E_PFGEN_PORTMDIO_NUM 0x0003F100
+#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT)
+#define I40E_PFGEN_PORTMDIO_NUM 0x0003F100 /* Reset: CORER */
#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT 0
-#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_MASK (0x3 << I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT)
+#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT)
#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT 4
-#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK (0x1 << I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT)
-#define I40E_PFINT_AEQCTL 0x00038700
+#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK I40E_MASK(0x1, I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT)
+#define I40E_PFINT_AEQCTL 0x00038700 /* Reset: CORER */
#define I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_AEQCTL_MSIX_INDX_MASK (0xFF << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_AEQCTL_ITR_INDX_MASK (0x3 << I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_AEQCTL_MSIX0_INDX_MASK (0x7 << I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_PFINT_AEQCTL_CAUSE_ENA_MASK (0x1 << I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_PFINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_AEQCTL_INTEVENT_MASK (0x1 << I40E_PFINT_AEQCTL_INTEVENT_SHIFT)
-#define I40E_PFINT_CEQCTL(_INTPF) (0x00036800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_INTEVENT_SHIFT)
+#define I40E_PFINT_CEQCTL(_INTPF) (0x00036800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_PFINT_CEQCTL_MAX_INDEX 511
#define I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_CEQCTL_MSIX_INDX_MASK (0xFF << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_CEQCTL_ITR_INDX_MASK (0x3 << I40E_PFINT_CEQCTL_ITR_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_ITR_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_CEQCTL_MSIX0_INDX_MASK (0x7 << I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_PFINT_CEQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK (0x1 << I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_CEQCTL_INTEVENT_MASK (0x1 << I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
-#define I40E_PFINT_DYN_CTL0 0x00038480
+#define I40E_PFINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
+#define I40E_PFINT_DYN_CTL0 0x00038480 /* Reset: PFR */
#define I40E_PFINT_DYN_CTL0_INTENA_SHIFT 0
-#define I40E_PFINT_DYN_CTL0_INTENA_MASK (0x1 << I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
#define I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT 1
-#define I40E_PFINT_DYN_CTL0_CLEARPBA_MASK (0x1 << I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_CLEARPBA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT)
#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT 2
-#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK (0x1 << I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
#define I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT 3
-#define I40E_PFINT_DYN_CTL0_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTL0_INTERVAL_MASK (0xFFF << I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT)
+#define I40E_PFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK (0x1 << I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
-#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
-#define I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK (0x1 << I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT)
-#define I40E_PFINT_DYN_CTLN(_INTPF) (0x00034800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT)
+#define I40E_PFINT_DYN_CTLN(_INTPF) (0x00034800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_DYN_CTLN_MAX_INDEX 511
#define I40E_PFINT_DYN_CTLN_INTENA_SHIFT 0
-#define I40E_PFINT_DYN_CTLN_INTENA_MASK (0x1 << I40E_PFINT_DYN_CTLN_INTENA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT 1
-#define I40E_PFINT_DYN_CTLN_CLEARPBA_MASK (0x1 << I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT)
#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT 2
-#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK (0x1 << I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
#define I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT 3
-#define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK (0xFFF << I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
+#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK (0x1 << I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_PFINT_DYN_CTLN_INTENA_MSK_MASK (0x1 << I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_PFINT_GPIO_ENA 0x00088080
+#define I40E_PFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT)
+#define I40E_PFINT_GPIO_ENA 0x00088080 /* Reset: CORER */
#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT)
-#define I40E_PFINT_ICR0 0x00038780
+#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT)
+#define I40E_PFINT_ICR0 0x00038780 /* Reset: CORER */
#define I40E_PFINT_ICR0_INTEVENT_SHIFT 0
-#define I40E_PFINT_ICR0_INTEVENT_MASK (0x1 << I40E_PFINT_ICR0_INTEVENT_SHIFT)
+#define I40E_PFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_INTEVENT_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_0_SHIFT 1
-#define I40E_PFINT_ICR0_QUEUE_0_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_0_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_0_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_PFINT_ICR0_QUEUE_1_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_1_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_1_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_PFINT_ICR0_QUEUE_2_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_2_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_2_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_PFINT_ICR0_QUEUE_3_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_3_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_3_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_4_SHIFT 5
-#define I40E_PFINT_ICR0_QUEUE_4_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_4_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_4_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_4_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_5_SHIFT 6
-#define I40E_PFINT_ICR0_QUEUE_5_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_5_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_5_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_5_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_6_SHIFT 7
-#define I40E_PFINT_ICR0_QUEUE_6_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_6_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_6_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_6_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_7_SHIFT 8
-#define I40E_PFINT_ICR0_QUEUE_7_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_7_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_7_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_7_SHIFT)
#define I40E_PFINT_ICR0_ECC_ERR_SHIFT 16
-#define I40E_PFINT_ICR0_ECC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ECC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ECC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ECC_ERR_SHIFT)
#define I40E_PFINT_ICR0_MAL_DETECT_SHIFT 19
-#define I40E_PFINT_ICR0_MAL_DETECT_MASK (0x1 << I40E_PFINT_ICR0_MAL_DETECT_SHIFT)
+#define I40E_PFINT_ICR0_MAL_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_MAL_DETECT_SHIFT)
#define I40E_PFINT_ICR0_GRST_SHIFT 20
-#define I40E_PFINT_ICR0_GRST_MASK (0x1 << I40E_PFINT_ICR0_GRST_SHIFT)
+#define I40E_PFINT_ICR0_GRST_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GRST_SHIFT)
#define I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT 21
-#define I40E_PFINT_ICR0_PCI_EXCEPTION_MASK (0x1 << I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT)
+#define I40E_PFINT_ICR0_PCI_EXCEPTION_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT)
#define I40E_PFINT_ICR0_GPIO_SHIFT 22
-#define I40E_PFINT_ICR0_GPIO_MASK (0x1 << I40E_PFINT_ICR0_GPIO_SHIFT)
+#define I40E_PFINT_ICR0_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GPIO_SHIFT)
#define I40E_PFINT_ICR0_TIMESYNC_SHIFT 23
-#define I40E_PFINT_ICR0_TIMESYNC_MASK (0x1 << I40E_PFINT_ICR0_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_STORM_DETECT_SHIFT 24
+#define I40E_PFINT_ICR0_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_STORM_DETECT_SHIFT)
#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK (0x1 << I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
+#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_HMC_ERR_SHIFT 26
-#define I40E_PFINT_ICR0_HMC_ERR_MASK (0x1 << I40E_PFINT_ICR0_HMC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_PE_CRITERR_SHIFT 28
-#define I40E_PFINT_ICR0_PE_CRITERR_MASK (0x1 << I40E_PFINT_ICR0_PE_CRITERR_SHIFT)
+#define I40E_PFINT_ICR0_PE_CRITERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_PE_CRITERR_SHIFT)
#define I40E_PFINT_ICR0_VFLR_SHIFT 29
-#define I40E_PFINT_ICR0_VFLR_MASK (0x1 << I40E_PFINT_ICR0_VFLR_SHIFT)
+#define I40E_PFINT_ICR0_VFLR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_VFLR_SHIFT)
#define I40E_PFINT_ICR0_ADMINQ_SHIFT 30
-#define I40E_PFINT_ICR0_ADMINQ_MASK (0x1 << I40E_PFINT_ICR0_ADMINQ_SHIFT)
+#define I40E_PFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ADMINQ_SHIFT)
#define I40E_PFINT_ICR0_SWINT_SHIFT 31
-#define I40E_PFINT_ICR0_SWINT_MASK (0x1 << I40E_PFINT_ICR0_SWINT_SHIFT)
-#define I40E_PFINT_ICR0_ENA 0x00038800
+#define I40E_PFINT_ICR0_SWINT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_SWINT_SHIFT)
+#define I40E_PFINT_ICR0_ENA 0x00038800 /* Reset: CORER */
#define I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT 16
-#define I40E_PFINT_ICR0_ENA_ECC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_ECC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT 19
-#define I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK (0x1 << I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT)
+#define I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT)
#define I40E_PFINT_ICR0_ENA_GRST_SHIFT 20
-#define I40E_PFINT_ICR0_ENA_GRST_MASK (0x1 << I40E_PFINT_ICR0_ENA_GRST_SHIFT)
+#define I40E_PFINT_ICR0_ENA_GRST_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_GRST_SHIFT)
#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT 21
-#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK (0x1 << I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT)
+#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT)
#define I40E_PFINT_ICR0_ENA_GPIO_SHIFT 22
-#define I40E_PFINT_ICR0_ENA_GPIO_MASK (0x1 << I40E_PFINT_ICR0_ENA_GPIO_SHIFT)
+#define I40E_PFINT_ICR0_ENA_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_GPIO_SHIFT)
#define I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT 23
-#define I40E_PFINT_ICR0_ENA_TIMESYNC_MASK (0x1 << I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_ENA_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT 24
+#define I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT)
#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK (0x1 << I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
+#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT 26
-#define I40E_PFINT_ICR0_ENA_HMC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT 28
-#define I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_VFLR_SHIFT 29
-#define I40E_PFINT_ICR0_ENA_VFLR_MASK (0x1 << I40E_PFINT_ICR0_ENA_VFLR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_VFLR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_VFLR_SHIFT)
#define I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT 30
-#define I40E_PFINT_ICR0_ENA_ADMINQ_MASK (0x1 << I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT)
+#define I40E_PFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT)
#define I40E_PFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_PFINT_ICR0_ENA_RSVD_MASK (0x1 << I40E_PFINT_ICR0_ENA_RSVD_SHIFT)
-#define I40E_PFINT_ITR0(_i) (0x00038000 + ((_i) * 128)) /* _i=0...2 */
+#define I40E_PFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_RSVD_SHIFT)
+#define I40E_PFINT_ITR0(_i) (0x00038000 + ((_i) * 128)) /* _i=0...2 */ /* Reset: PFR */
#define I40E_PFINT_ITR0_MAX_INDEX 2
#define I40E_PFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITR0_INTERVAL_MASK (0xFFF << I40E_PFINT_ITR0_INTERVAL_SHIFT)
-#define I40E_PFINT_ITRN(_i, _INTPF) (0x00030000 + ((_i) * 2048 + (_INTPF) * 4))
+#define I40E_PFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITR0_INTERVAL_SHIFT)
+#define I40E_PFINT_ITRN(_i, _INTPF) (0x00030000 + ((_i) * 2048 + (_INTPF) * 4)) /* _i=0...2, _INTPF=0...511 */ /* Reset: PFR */
#define I40E_PFINT_ITRN_MAX_INDEX 2
#define I40E_PFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITRN_INTERVAL_MASK (0xFFF << I40E_PFINT_ITRN_INTERVAL_SHIFT)
-#define I40E_PFINT_LNKLST0 0x00038500
+#define I40E_PFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITRN_INTERVAL_SHIFT)
+#define I40E_PFINT_LNKLST0 0x00038500 /* Reset: PFR */
#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
-#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK (0x7FF << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT)
+#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT)
#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_MASK (0x3 << I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
-#define I40E_PFINT_LNKLSTN(_INTPF) (0x00035000 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
+#define I40E_PFINT_LNKLSTN(_INTPF) (0x00035000 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_LNKLSTN_MAX_INDEX 511
#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
-#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK (0x7FF << I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
+#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK (0x3 << I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_PFINT_RATE0 0x00038580
+#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
+#define I40E_PFINT_RATE0 0x00038580 /* Reset: PFR */
#define I40E_PFINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATE0_INTERVAL_MASK (0x3F << I40E_PFINT_RATE0_INTERVAL_SHIFT)
+#define I40E_PFINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATE0_INTERVAL_SHIFT)
#define I40E_PFINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATE0_INTRL_ENA_MASK (0x1 << I40E_PFINT_RATE0_INTRL_ENA_SHIFT)
-#define I40E_PFINT_RATEN(_INTPF) (0x00035800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATE0_INTRL_ENA_SHIFT)
+#define I40E_PFINT_RATEN(_INTPF) (0x00035800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_RATEN_MAX_INDEX 511
#define I40E_PFINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATEN_INTERVAL_MASK (0x3F << I40E_PFINT_RATEN_INTERVAL_SHIFT)
+#define I40E_PFINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATEN_INTERVAL_SHIFT)
#define I40E_PFINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATEN_INTRL_ENA_MASK (0x1 << I40E_PFINT_RATEN_INTRL_ENA_SHIFT)
-#define I40E_PFINT_STAT_CTL0 0x00038400
+#define I40E_PFINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATEN_INTRL_ENA_SHIFT)
+#define I40E_PFINT_STAT_CTL0 0x00038400 /* Reset: PFR */
#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK (0x3 << I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
-#define I40E_QINT_RQCTL(_Q) (0x0003A000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
+#define I40E_QINT_RQCTL(_Q) (0x0003A000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QINT_RQCTL_MAX_INDEX 1535
#define I40E_QINT_RQCTL_MSIX_INDX_SHIFT 0
-#define I40E_QINT_RQCTL_MSIX_INDX_MASK (0xFF << I40E_QINT_RQCTL_MSIX_INDX_SHIFT)
+#define I40E_QINT_RQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_RQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_RQCTL_ITR_INDX_SHIFT 11
-#define I40E_QINT_RQCTL_ITR_INDX_MASK (0x3 << I40E_QINT_RQCTL_ITR_INDX_SHIFT)
+#define I40E_QINT_RQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_QINT_RQCTL_ITR_INDX_SHIFT)
#define I40E_QINT_RQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_QINT_RQCTL_MSIX0_INDX_MASK (0x7 << I40E_QINT_RQCTL_MSIX0_INDX_SHIFT)
+#define I40E_QINT_RQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_QINT_RQCTL_MSIX0_INDX_SHIFT)
#define I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_QINT_RQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_QINT_RQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_RQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_QINT_RQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_RQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_QINT_RQCTL_CAUSE_ENA_MASK (0x1 << I40E_QINT_RQCTL_CAUSE_ENA_SHIFT)
+#define I40E_QINT_RQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_RQCTL_INTEVENT_SHIFT 31
-#define I40E_QINT_RQCTL_INTEVENT_MASK (0x1 << I40E_QINT_RQCTL_INTEVENT_SHIFT)
-#define I40E_QINT_TQCTL(_Q) (0x0003C000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QINT_RQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_INTEVENT_SHIFT)
+#define I40E_QINT_TQCTL(_Q) (0x0003C000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QINT_TQCTL_MAX_INDEX 1535
#define I40E_QINT_TQCTL_MSIX_INDX_SHIFT 0
-#define I40E_QINT_TQCTL_MSIX_INDX_MASK (0xFF << I40E_QINT_TQCTL_MSIX_INDX_SHIFT)
+#define I40E_QINT_TQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_TQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_TQCTL_ITR_INDX_SHIFT 11
-#define I40E_QINT_TQCTL_ITR_INDX_MASK (0x3 << I40E_QINT_TQCTL_ITR_INDX_SHIFT)
+#define I40E_QINT_TQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_QINT_TQCTL_ITR_INDX_SHIFT)
#define I40E_QINT_TQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_QINT_TQCTL_MSIX0_INDX_MASK (0x7 << I40E_QINT_TQCTL_MSIX0_INDX_SHIFT)
+#define I40E_QINT_TQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_QINT_TQCTL_MSIX0_INDX_SHIFT)
#define I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_QINT_TQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_QINT_TQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_TQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_QINT_TQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_TQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_QINT_TQCTL_CAUSE_ENA_MASK (0x1 << I40E_QINT_TQCTL_CAUSE_ENA_SHIFT)
+#define I40E_QINT_TQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_TQCTL_INTEVENT_SHIFT 31
-#define I40E_QINT_TQCTL_INTEVENT_MASK (0x1 << I40E_QINT_TQCTL_INTEVENT_SHIFT)
-#define I40E_VFINT_DYN_CTL0(_VF) (0x0002A400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_QINT_TQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_INTEVENT_SHIFT)
+#define I40E_VFINT_DYN_CTL0(_VF) (0x0002A400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTL0_MAX_INDEX 127
#define I40E_VFINT_DYN_CTL0_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL0_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTL0_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL0_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL0_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL0_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT)
-#define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT)
+#define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTLN_MAX_INDEX 511
#define I40E_VFINT_DYN_CTLN_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTLN_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0(_VF) (0x0002BC00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT)
+#define I40E_VFINT_ICR0(_VF) (0x0002BC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VFINT_ICR0_MAX_INDEX 127
#define I40E_VFINT_ICR0_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR0_INTEVENT_MASK (0x1 << I40E_VFINT_ICR0_INTEVENT_SHIFT)
+#define I40E_VFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_INTEVENT_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR0_QUEUE_0_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_0_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_0_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR0_QUEUE_1_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_1_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_1_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR0_QUEUE_2_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_2_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_2_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR0_QUEUE_3_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_3_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_3_SHIFT)
#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_SWINT_SHIFT 31
-#define I40E_VFINT_ICR0_SWINT_MASK (0x1 << I40E_VFINT_ICR0_SWINT_SHIFT)
-#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_ICR0_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_SWINT_SHIFT)
+#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VFINT_ICR0_ENA_MAX_INDEX 127
#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA_RSVD_MASK (0x1 << I40E_VFINT_ICR0_ENA_RSVD_SHIFT)
-#define I40E_VFINT_ITR0(_i, _VF) (0x00028000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...2, _VF=0...127 */
+#define I40E_VFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_RSVD_SHIFT)
+#define I40E_VFINT_ITR0(_i, _VF) (0x00028000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...2, _VF=0...127 */ /* Reset: VFR */
#define I40E_VFINT_ITR0_MAX_INDEX 2
#define I40E_VFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR0_INTERVAL_MASK (0xFFF << I40E_VFINT_ITR0_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN(_i, _INTVF) (0x00020000 + ((_i) * 2048 + (_INTVF) * 4))
+#define I40E_VFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR0_INTERVAL_SHIFT)
+#define I40E_VFINT_ITRN(_i, _INTVF) (0x00020000 + ((_i) * 2048 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...511 */ /* Reset: VFR */
#define I40E_VFINT_ITRN_MAX_INDEX 2
#define I40E_VFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN_INTERVAL_MASK (0xFFF << I40E_VFINT_ITRN_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL0(_VF) (0x0002A000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN_INTERVAL_SHIFT)
+#define I40E_VFINT_STAT_CTL0(_VF) (0x0002A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFINT_STAT_CTL0_MAX_INDEX 127
#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_MASK (0x3 << I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
-#define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPINT_AEQCTL_MAX_INDEX 127
#define I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_AEQCTL_MSIX_INDX_MASK (0xFF << I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_AEQCTL_ITR_INDX_MASK (0x3 << I40E_VPINT_AEQCTL_ITR_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_AEQCTL_ITR_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_AEQCTL_MSIX0_INDX_MASK (0x7 << I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_VPINT_AEQCTL_CAUSE_ENA_MASK (0x1 << I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_VPINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT)
#define I40E_VPINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_AEQCTL_INTEVENT_MASK (0x1 << I40E_VPINT_AEQCTL_INTEVENT_SHIFT)
-#define I40E_VPINT_CEQCTL(_INTVF) (0x00026800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_INTEVENT_SHIFT)
+#define I40E_VPINT_CEQCTL(_INTVF) (0x00026800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_VPINT_CEQCTL_MAX_INDEX 511
#define I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_CEQCTL_MSIX_INDX_MASK (0xFF << I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_CEQCTL_ITR_INDX_MASK (0x3 << I40E_VPINT_CEQCTL_ITR_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_ITR_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_CEQCTL_MSIX0_INDX_MASK (0x7 << I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_VPINT_CEQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_VPINT_CEQCTL_CAUSE_ENA_MASK (0x1 << I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_VPINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_VPINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_CEQCTL_INTEVENT_MASK (0x1 << I40E_VPINT_CEQCTL_INTEVENT_SHIFT)
-#define I40E_VPINT_LNKLST0(_VF) (0x0002A800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_INTEVENT_SHIFT)
+#define I40E_VPINT_LNKLST0(_VF) (0x0002A800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPINT_LNKLST0_MAX_INDEX 127
#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
-#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK (0x7FF << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT)
+#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT)
#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_MASK (0x3 << I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
-#define I40E_VPINT_LNKLSTN(_INTVF) (0x00025000 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
+#define I40E_VPINT_LNKLSTN(_INTVF) (0x00025000 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VPINT_LNKLSTN_MAX_INDEX 511
#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
-#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK (0x7FF << I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
+#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
-#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK (0x3 << I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_VPINT_RATE0(_VF) (0x0002AC00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
+#define I40E_VPINT_RATE0(_VF) (0x0002AC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPINT_RATE0_MAX_INDEX 127
#define I40E_VPINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATE0_INTERVAL_MASK (0x3F << I40E_VPINT_RATE0_INTERVAL_SHIFT)
+#define I40E_VPINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATE0_INTERVAL_SHIFT)
#define I40E_VPINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATE0_INTRL_ENA_MASK (0x1 << I40E_VPINT_RATE0_INTRL_ENA_SHIFT)
-#define I40E_VPINT_RATEN(_INTVF) (0x00025800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATE0_INTRL_ENA_SHIFT)
+#define I40E_VPINT_RATEN(_INTVF) (0x00025800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VPINT_RATEN_MAX_INDEX 511
#define I40E_VPINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATEN_INTERVAL_MASK (0x3F << I40E_VPINT_RATEN_INTERVAL_SHIFT)
+#define I40E_VPINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATEN_INTERVAL_SHIFT)
#define I40E_VPINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATEN_INTRL_ENA_MASK (0x1 << I40E_VPINT_RATEN_INTRL_ENA_SHIFT)
-#define I40E_GL_RDPU_CNTRL 0x00051060
+#define I40E_VPINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATEN_INTRL_ENA_SHIFT)
+#define I40E_GL_RDPU_CNTRL 0x00051060 /* Reset: CORER */
#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT 0
-#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_MASK (0x1 << I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT)
+#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_MASK I40E_MASK(0x1, I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT)
#define I40E_GL_RDPU_CNTRL_ECO_SHIFT 1
-#define I40E_GL_RDPU_CNTRL_ECO_MASK (0x7FFFFFFF << I40E_GL_RDPU_CNTRL_ECO_SHIFT)
-#define I40E_GLLAN_RCTL_0 0x0012A500
+#define I40E_GL_RDPU_CNTRL_ECO_MASK I40E_MASK(0x7FFFFFFF, I40E_GL_RDPU_CNTRL_ECO_SHIFT)
+#define I40E_GLLAN_RCTL_0 0x0012A500 /* Reset: CORER */
#define I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT 0
-#define I40E_GLLAN_RCTL_0_PXE_MODE_MASK (0x1 << I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT)
-#define I40E_GLLAN_TSOMSK_F 0x000442D8
+#define I40E_GLLAN_RCTL_0_PXE_MODE_MASK I40E_MASK(0x1, I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT)
+#define I40E_GLLAN_TSOMSK_F 0x000442D8 /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT 0
-#define I40E_GLLAN_TSOMSK_F_TCPMSKF_MASK (0xFFF << I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT)
-#define I40E_GLLAN_TSOMSK_L 0x000442E0
+#define I40E_GLLAN_TSOMSK_F_TCPMSKF_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT)
+#define I40E_GLLAN_TSOMSK_L 0x000442E0 /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT 0
-#define I40E_GLLAN_TSOMSK_L_TCPMSKL_MASK (0xFFF << I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT)
-#define I40E_GLLAN_TSOMSK_M 0x000442DC
+#define I40E_GLLAN_TSOMSK_L_TCPMSKL_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT)
+#define I40E_GLLAN_TSOMSK_M 0x000442DC /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT 0
-#define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK (0xFFF << I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT)
-#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000E6500 + ((_i) * 4)) /* i=0..11 */
+#define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000e6500 + ((_i) * 4)) /* _i=0...11 */ /* Reset: CORER */
+#define I40E_GLLAN_TXPRE_QDIS_MAX_INDEX 11
#define I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT 0
-#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK (0x7FF << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK I40E_MASK(0x7FF, I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT 16
+#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT 30
-#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT 31
-#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT)
-
-#define I40E_PFLAN_QALLOC 0x001C0400
+#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT)
+#define I40E_PFLAN_QALLOC 0x001C0400 /* Reset: CORER */
#define I40E_PFLAN_QALLOC_FIRSTQ_SHIFT 0
-#define I40E_PFLAN_QALLOC_FIRSTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_FIRSTQ_SHIFT)
+#define I40E_PFLAN_QALLOC_FIRSTQ_MASK I40E_MASK(0x7FF, I40E_PFLAN_QALLOC_FIRSTQ_SHIFT)
#define I40E_PFLAN_QALLOC_LASTQ_SHIFT 16
-#define I40E_PFLAN_QALLOC_LASTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_LASTQ_SHIFT)
+#define I40E_PFLAN_QALLOC_LASTQ_MASK I40E_MASK(0x7FF, I40E_PFLAN_QALLOC_LASTQ_SHIFT)
#define I40E_PFLAN_QALLOC_VALID_SHIFT 31
-#define I40E_PFLAN_QALLOC_VALID_MASK (0x1 << I40E_PFLAN_QALLOC_VALID_SHIFT)
-#define I40E_QRX_ENA(_Q) (0x00120000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_PFLAN_QALLOC_VALID_MASK I40E_MASK(0x1, I40E_PFLAN_QALLOC_VALID_SHIFT)
+#define I40E_QRX_ENA(_Q) (0x00120000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QRX_ENA_MAX_INDEX 1535
#define I40E_QRX_ENA_QENA_REQ_SHIFT 0
-#define I40E_QRX_ENA_QENA_REQ_MASK (0x1 << I40E_QRX_ENA_QENA_REQ_SHIFT)
+#define I40E_QRX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_REQ_SHIFT)
#define I40E_QRX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QRX_ENA_FAST_QDIS_MASK (0x1 << I40E_QRX_ENA_FAST_QDIS_SHIFT)
+#define I40E_QRX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QRX_ENA_FAST_QDIS_SHIFT)
#define I40E_QRX_ENA_QENA_STAT_SHIFT 2
-#define I40E_QRX_ENA_QENA_STAT_MASK (0x1 << I40E_QRX_ENA_QENA_STAT_SHIFT)
-#define I40E_QRX_TAIL(_Q) (0x00128000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QRX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_STAT_SHIFT)
+#define I40E_QRX_TAIL(_Q) (0x00128000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QRX_TAIL_MAX_INDEX 1535
#define I40E_QRX_TAIL_TAIL_SHIFT 0
-#define I40E_QRX_TAIL_TAIL_MASK (0x1FFF << I40E_QRX_TAIL_TAIL_SHIFT)
-#define I40E_QTX_CTL(_Q) (0x00104000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QRX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL_TAIL_SHIFT)
+#define I40E_QTX_CTL(_Q) (0x00104000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QTX_CTL_MAX_INDEX 1535
#define I40E_QTX_CTL_PFVF_Q_SHIFT 0
-#define I40E_QTX_CTL_PFVF_Q_MASK (0x3 << I40E_QTX_CTL_PFVF_Q_SHIFT)
+#define I40E_QTX_CTL_PFVF_Q_MASK I40E_MASK(0x3, I40E_QTX_CTL_PFVF_Q_SHIFT)
#define I40E_QTX_CTL_PF_INDX_SHIFT 2
-#define I40E_QTX_CTL_PF_INDX_MASK (0xF << I40E_QTX_CTL_PF_INDX_SHIFT)
+#define I40E_QTX_CTL_PF_INDX_MASK I40E_MASK(0xF, I40E_QTX_CTL_PF_INDX_SHIFT)
#define I40E_QTX_CTL_VFVM_INDX_SHIFT 7
-#define I40E_QTX_CTL_VFVM_INDX_MASK (0x1FF << I40E_QTX_CTL_VFVM_INDX_SHIFT)
-#define I40E_QTX_ENA(_Q) (0x00100000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_CTL_VFVM_INDX_MASK I40E_MASK(0x1FF, I40E_QTX_CTL_VFVM_INDX_SHIFT)
+#define I40E_QTX_ENA(_Q) (0x00100000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QTX_ENA_MAX_INDEX 1535
#define I40E_QTX_ENA_QENA_REQ_SHIFT 0
-#define I40E_QTX_ENA_QENA_REQ_MASK (0x1 << I40E_QTX_ENA_QENA_REQ_SHIFT)
+#define I40E_QTX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_REQ_SHIFT)
#define I40E_QTX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QTX_ENA_FAST_QDIS_MASK (0x1 << I40E_QTX_ENA_FAST_QDIS_SHIFT)
+#define I40E_QTX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QTX_ENA_FAST_QDIS_SHIFT)
#define I40E_QTX_ENA_QENA_STAT_SHIFT 2
-#define I40E_QTX_ENA_QENA_STAT_MASK (0x1 << I40E_QTX_ENA_QENA_STAT_SHIFT)
-#define I40E_QTX_HEAD(_Q) (0x000E4000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_STAT_SHIFT)
+#define I40E_QTX_HEAD(_Q) (0x000E4000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QTX_HEAD_MAX_INDEX 1535
#define I40E_QTX_HEAD_HEAD_SHIFT 0
-#define I40E_QTX_HEAD_HEAD_MASK (0x1FFF << I40E_QTX_HEAD_HEAD_SHIFT)
+#define I40E_QTX_HEAD_HEAD_MASK I40E_MASK(0x1FFF, I40E_QTX_HEAD_HEAD_SHIFT)
#define I40E_QTX_HEAD_RS_PENDING_SHIFT 16
-#define I40E_QTX_HEAD_RS_PENDING_MASK (0x1 << I40E_QTX_HEAD_RS_PENDING_SHIFT)
-#define I40E_QTX_TAIL(_Q) (0x00108000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_HEAD_RS_PENDING_MASK I40E_MASK(0x1, I40E_QTX_HEAD_RS_PENDING_SHIFT)
+#define I40E_QTX_TAIL(_Q) (0x00108000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QTX_TAIL_MAX_INDEX 1535
#define I40E_QTX_TAIL_TAIL_SHIFT 0
-#define I40E_QTX_TAIL_TAIL_MASK (0x1FFF << I40E_QTX_TAIL_TAIL_SHIFT)
-#define I40E_VPLAN_MAPENA(_VF) (0x00074000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_QTX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL_TAIL_SHIFT)
+#define I40E_VPLAN_MAPENA(_VF) (0x00074000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPLAN_MAPENA_MAX_INDEX 127
#define I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT 0
-#define I40E_VPLAN_MAPENA_TXRX_ENA_MASK (0x1 << I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT)
-#define I40E_VPLAN_QTABLE(_i, _VF) (0x00070000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */
+#define I40E_VPLAN_MAPENA_TXRX_ENA_MASK I40E_MASK(0x1, I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT)
+#define I40E_VPLAN_QTABLE(_i, _VF) (0x00070000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: VFR */
#define I40E_VPLAN_QTABLE_MAX_INDEX 15
#define I40E_VPLAN_QTABLE_QINDEX_SHIFT 0
-#define I40E_VPLAN_QTABLE_QINDEX_MASK (0x7FF << I40E_VPLAN_QTABLE_QINDEX_SHIFT)
-#define I40E_VSILAN_QBASE(_VSI) (0x0020C800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPLAN_QTABLE_QINDEX_MASK I40E_MASK(0x7FF, I40E_VPLAN_QTABLE_QINDEX_SHIFT)
+#define I40E_VSILAN_QBASE(_VSI) (0x0020C800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
#define I40E_VSILAN_QBASE_MAX_INDEX 383
#define I40E_VSILAN_QBASE_VSIBASE_SHIFT 0
-#define I40E_VSILAN_QBASE_VSIBASE_MASK (0x7FF << I40E_VSILAN_QBASE_VSIBASE_SHIFT)
+#define I40E_VSILAN_QBASE_VSIBASE_MASK I40E_MASK(0x7FF, I40E_VSILAN_QBASE_VSIBASE_SHIFT)
#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT 11
-#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK (0x1 << I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT)
-#define I40E_VSILAN_QTABLE(_i, _VSI) (0x00200000 + ((_i) * 2048 + (_VSI) * 4))
+#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK I40E_MASK(0x1, I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT)
+#define I40E_VSILAN_QTABLE(_i, _VSI) (0x00200000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...7, _VSI=0...383 */ /* Reset: PFR */
#define I40E_VSILAN_QTABLE_MAX_INDEX 7
#define I40E_VSILAN_QTABLE_QINDEX_0_SHIFT 0
-#define I40E_VSILAN_QTABLE_QINDEX_0_MASK (0x7FF << I40E_VSILAN_QTABLE_QINDEX_0_SHIFT)
+#define I40E_VSILAN_QTABLE_QINDEX_0_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_0_SHIFT)
#define I40E_VSILAN_QTABLE_QINDEX_1_SHIFT 16
-#define I40E_VSILAN_QTABLE_QINDEX_1_MASK (0x7FF << I40E_VSILAN_QTABLE_QINDEX_1_SHIFT)
-#define I40E_PRTGL_SAH 0x001E2140
+#define I40E_VSILAN_QTABLE_QINDEX_1_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_1_SHIFT)
+#define I40E_PRTGL_SAH 0x001E2140 /* Reset: GLOBR */
#define I40E_PRTGL_SAH_FC_SAH_SHIFT 0
-#define I40E_PRTGL_SAH_FC_SAH_MASK (0xFFFF << I40E_PRTGL_SAH_FC_SAH_SHIFT)
+#define I40E_PRTGL_SAH_FC_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTGL_SAH_FC_SAH_SHIFT)
#define I40E_PRTGL_SAH_MFS_SHIFT 16
-#define I40E_PRTGL_SAH_MFS_MASK (0xFFFF << I40E_PRTGL_SAH_MFS_SHIFT)
-#define I40E_PRTGL_SAL 0x001E2120
+#define I40E_PRTGL_SAH_MFS_MASK I40E_MASK(0xFFFF, I40E_PRTGL_SAH_MFS_SHIFT)
+#define I40E_PRTGL_SAL 0x001E2120 /* Reset: GLOBR */
#define I40E_PRTGL_SAL_FC_SAL_SHIFT 0
-#define I40E_PRTGL_SAL_FC_SAL_MASK (0xFFFFFFFF << I40E_PRTGL_SAL_FC_SAL_SHIFT)
-#define I40E_PRTMAC_HLCTLA 0x001E4760
-#define I40E_PRTMAC_HLCTLA_DROP_US_PKTS_SHIFT 0
-#define I40E_PRTMAC_HLCTLA_DROP_US_PKTS_MASK (0x1 << I40E_PRTMAC_HLCTLA_DROP_US_PKTS_SHIFT)
-#define I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_SHIFT 1
-#define I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_MASK (0x1 << I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_SHIFT)
-#define I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_SHIFT 2
-#define I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_MASK (0x1 << I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_SHIFT)
-#define I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_SHIFT 4
-#define I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_MASK (0x7 << I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_SHIFT)
-#define I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_SHIFT 7
-#define I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_MASK (0x1 << I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP 0x001E3130
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP 0x001E3290
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP 0x001E3310
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP 0x001E3100
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP 0x001E3280
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP 0x001E3300
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP 0x001E30E0
+#define I40E_PRTGL_SAL_FC_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTGL_SAL_FC_SAL_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP 0x001E30E0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP 0x001E3260
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP 0x001E3260 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP 0x001E32E0
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP 0x001E32E0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL 0x001E3360
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL 0x001E3360 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1 0x001E3110
+#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1 0x001E3110 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2 0x001E3120
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2 0x001E3120 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE 0x001E30C0
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE 0x001E30C0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK (0x1FF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1 0x001E3140
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1 0x001E3140 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2 0x001E3150
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2 0x001E3150 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE 0x001E3000
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE 0x001E30D0
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE 0x001E30D0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK (0x1FF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E3370 + ((_i) * 16))
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E3370 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX 8
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3400 + ((_i) * 16))
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3400 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MAX_INDEX 8
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1 0x001E34B0
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1 0x001E34B0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2 0x001E34C0
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2 0x001E34C0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT)
-#define I40E_PRTMAC_HSECTL1 0x001E3560
-#define I40E_PRTMAC_HSECTL1_DROP_US_PKTS_SHIFT 0
-#define I40E_PRTMAC_HSECTL1_DROP_US_PKTS_MASK (0x1 << I40E_PRTMAC_HSECTL1_DROP_US_PKTS_SHIFT)
-#define I40E_PRTMAC_HSECTL1_PAD_US_PKT_SHIFT 3
-#define I40E_PRTMAC_HSECTL1_PAD_US_PKT_MASK (0x1 << I40E_PRTMAC_HSECTL1_PAD_US_PKT_SHIFT)
-#define I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_SHIFT 4
-#define I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_MASK (0x7 << I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_SHIFT)
-#define I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_SHIFT 7
-#define I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_MASK (0x1 << I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_SHIFT)
-#define I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_SHIFT 30
-#define I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_MASK (0x1 << I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_SHIFT)
-#define I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_SHIFT 31
-#define I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_MASK (0x1 << I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A 0x0008C480
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A 0x0008C480 /* Reset: GLOBR */
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B 0x0008C484
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B 0x0008C484 /* Reset: GLOBR */
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT)
-#define I40E_GL_MNG_FWSM 0x000B6134
-#define I40E_GL_MNG_FWSM_FW_MODES_SHIFT 1
-#define I40E_GL_MNG_FWSM_FW_MODES_MASK (0x7 << I40E_GL_MNG_FWSM_FW_MODES_SHIFT)
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT 6
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_MASK (0x1 << I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT)
+#define I40E_GL_FWRESETCNT 0x00083100 /* Reset: POR */
+#define I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT 0
+#define I40E_GL_FWRESETCNT_FWRESETCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT)
+#define I40E_GL_MNG_FWSM 0x000B6134 /* Reset: POR */
+#define I40E_GL_MNG_FWSM_FW_MODES_SHIFT 0
+#define I40E_GL_MNG_FWSM_FW_MODES_MASK I40E_MASK(0x3, I40E_GL_MNG_FWSM_FW_MODES_SHIFT)
+#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT 10
+#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT)
#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT 11
-#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_MASK (0xF << I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT)
+#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_MASK I40E_MASK(0xF, I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT)
#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT 15
-#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_MASK (0x1 << I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT)
+#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT)
#define I40E_GL_MNG_FWSM_RESET_CNT_SHIFT 16
-#define I40E_GL_MNG_FWSM_RESET_CNT_MASK (0x7 << I40E_GL_MNG_FWSM_RESET_CNT_SHIFT)
+#define I40E_GL_MNG_FWSM_RESET_CNT_MASK I40E_MASK(0x7, I40E_GL_MNG_FWSM_RESET_CNT_SHIFT)
#define I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT 19
-#define I40E_GL_MNG_FWSM_EXT_ERR_IND_MASK (0x3F << I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT)
-#define I40E_GL_MNG_FWSM_RSVD_SHIFT 25
-#define I40E_GL_MNG_FWSM_RSVD_MASK (0x1 << I40E_GL_MNG_FWSM_RSVD_SHIFT)
+#define I40E_GL_MNG_FWSM_EXT_ERR_IND_MASK I40E_MASK(0x3F, I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT 26
-#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT 27
-#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT 28
-#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT 29
-#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_HWARB_CTRL 0x000B6130
+#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_HWARB_CTRL 0x000B6130 /* Reset: POR */
#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT 0
-#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_MASK (0x1 << I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT)
-#define I40E_PRT_MNG_FTFT_DATA(_i) (0x000852A0 + ((_i) * 32)) /* _i=0...31 */
+#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_MASK I40E_MASK(0x1, I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT)
+#define I40E_PRT_MNG_FTFT_DATA(_i) (0x000852A0 + ((_i) * 32)) /* _i=0...31 */ /* Reset: POR */
#define I40E_PRT_MNG_FTFT_DATA_MAX_INDEX 31
#define I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT 0
-#define I40E_PRT_MNG_FTFT_DATA_DWORD_MASK (0xFFFFFFFF << I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT)
-#define I40E_PRT_MNG_FTFT_LENGTH 0x00085260
+#define I40E_PRT_MNG_FTFT_DATA_DWORD_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT)
+#define I40E_PRT_MNG_FTFT_LENGTH 0x00085260 /* Reset: POR */
#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_MASK (0xFF << I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PRT_MNG_FTFT_MASK(_i) (0x00085160 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT)
+#define I40E_PRT_MNG_FTFT_MASK(_i) (0x00085160 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_FTFT_MASK_MAX_INDEX 7
#define I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT 0
-#define I40E_PRT_MNG_FTFT_MASK_MASK_MASK (0xFFFF << I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT)
-#define I40E_PRT_MNG_MANC 0x00256A20
+#define I40E_PRT_MNG_FTFT_MASK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT)
+#define I40E_PRT_MNG_MANC 0x00256A20 /* Reset: POR */
#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT 0
-#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_MASK (0x1 << I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT)
+#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT)
#define I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT 1
-#define I40E_PRT_MNG_MANC_NCSI_DISCARD_MASK (0x1 << I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT)
+#define I40E_PRT_MNG_MANC_NCSI_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT)
#define I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT 17
-#define I40E_PRT_MNG_MANC_RCV_TCO_EN_MASK (0x1 << I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT)
+#define I40E_PRT_MNG_MANC_RCV_TCO_EN_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT)
#define I40E_PRT_MNG_MANC_RCV_ALL_SHIFT 19
-#define I40E_PRT_MNG_MANC_RCV_ALL_MASK (0x1 << I40E_PRT_MNG_MANC_RCV_ALL_SHIFT)
+#define I40E_PRT_MNG_MANC_RCV_ALL_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_ALL_SHIFT)
#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT 25
-#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_MASK (0x1 << I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT)
+#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT)
#define I40E_PRT_MNG_MANC_NET_TYPE_SHIFT 26
-#define I40E_PRT_MNG_MANC_NET_TYPE_MASK (0x1 << I40E_PRT_MNG_MANC_NET_TYPE_SHIFT)
+#define I40E_PRT_MNG_MANC_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NET_TYPE_SHIFT)
#define I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT 28
-#define I40E_PRT_MNG_MANC_EN_BMC2OS_MASK (0x1 << I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT)
+#define I40E_PRT_MNG_MANC_EN_BMC2OS_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT)
#define I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT 29
-#define I40E_PRT_MNG_MANC_EN_BMC2NET_MASK (0x1 << I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT)
-#define I40E_PRT_MNG_MAVTV(_i) (0x00255900 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRT_MNG_MANC_EN_BMC2NET_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT)
+#define I40E_PRT_MNG_MAVTV(_i) (0x00255900 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MAVTV_MAX_INDEX 7
#define I40E_PRT_MNG_MAVTV_VID_SHIFT 0
-#define I40E_PRT_MNG_MAVTV_VID_MASK (0xFFF << I40E_PRT_MNG_MAVTV_VID_SHIFT)
-#define I40E_PRT_MNG_MDEF(_i) (0x00255D00 + ((_i) * 32))
+#define I40E_PRT_MNG_MAVTV_VID_MASK I40E_MASK(0xFFF, I40E_PRT_MNG_MAVTV_VID_SHIFT)
+#define I40E_PRT_MNG_MDEF(_i) (0x00255D00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEF_MAX_INDEX 7
#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_MASK (0xF << I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT 4
-#define I40E_PRT_MNG_MDEF_BROADCAST_AND_MASK (0x1 << I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_BROADCAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT 5
-#define I40E_PRT_MNG_MDEF_VLAN_AND_MASK (0xFF << I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_VLAN_AND_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT 13
-#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_MASK (0xF << I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT 17
-#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_MASK (0xF << I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT 21
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_MASK (0xF << I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_BROADCAST_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_BROADCAST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT 26
-#define I40E_PRT_MNG_MDEF_MULTICAST_AND_MASK (0x1 << I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_MULTICAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT 29
-#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT 30
-#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT 31
-#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT(_i) (0x00255F00 + ((_i) * 32))
+#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT(_i) (0x00255F00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEF_EXT_MAX_INDEX 7
#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_MASK (0xF << I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT 4
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_MASK (0xF << I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT 8
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_MASK (0xFFFF << I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT 24
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT 26
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT 29
-#define I40E_PRT_MNG_MDEF_EXT_MLD_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_MLD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT 30
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT 31
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT)
-#define I40E_PRT_MNG_MDEFVSI(_i) (0x00256580 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT)
+#define I40E_PRT_MNG_MDEFVSI(_i) (0x00256580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEFVSI_MAX_INDEX 3
#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT 0
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_MASK (0xFFFF << I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT)
+#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT)
#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT 16
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_MASK (0xFFFF << I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT)
-#define I40E_PRT_MNG_METF(_i) (0x00256780 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT)
+#define I40E_PRT_MNG_METF(_i) (0x00256780 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_METF_MAX_INDEX 3
#define I40E_PRT_MNG_METF_ETYPE_SHIFT 0
-#define I40E_PRT_MNG_METF_ETYPE_MASK (0xFFFF << I40E_PRT_MNG_METF_ETYPE_SHIFT)
+#define I40E_PRT_MNG_METF_ETYPE_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_METF_ETYPE_SHIFT)
#define I40E_PRT_MNG_METF_POLARITY_SHIFT 30
-#define I40E_PRT_MNG_METF_POLARITY_MASK (0x1 << I40E_PRT_MNG_METF_POLARITY_SHIFT)
-#define I40E_PRT_MNG_MFUTP(_i) (0x00254E00 + ((_i) * 32)) /* _i=0...15 */
+#define I40E_PRT_MNG_METF_POLARITY_MASK I40E_MASK(0x1, I40E_PRT_MNG_METF_POLARITY_SHIFT)
+#define I40E_PRT_MNG_MFUTP(_i) (0x00254E00 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
#define I40E_PRT_MNG_MFUTP_MAX_INDEX 15
#define I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT 0
-#define I40E_PRT_MNG_MFUTP_MFUTP_N_MASK (0xFFFF << I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT)
+#define I40E_PRT_MNG_MFUTP_MFUTP_N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT)
#define I40E_PRT_MNG_MFUTP_UDP_SHIFT 16
-#define I40E_PRT_MNG_MFUTP_UDP_MASK (0x1 << I40E_PRT_MNG_MFUTP_UDP_SHIFT)
+#define I40E_PRT_MNG_MFUTP_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_UDP_SHIFT)
#define I40E_PRT_MNG_MFUTP_TCP_SHIFT 17
-#define I40E_PRT_MNG_MFUTP_TCP_MASK (0x1 << I40E_PRT_MNG_MFUTP_TCP_SHIFT)
+#define I40E_PRT_MNG_MFUTP_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_TCP_SHIFT)
#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT 18
-#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_MASK (0x1 << I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT)
-#define I40E_PRT_MNG_MIPAF4(_i) (0x00256280 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT)
+#define I40E_PRT_MNG_MIPAF4(_i) (0x00256280 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MIPAF4_MAX_INDEX 3
#define I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF4_MIPAF_MASK (0xFFFFFFFF << I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MIPAF6(_i) (0x00254200 + ((_i) * 32)) /* _i=0...15 */
+#define I40E_PRT_MNG_MIPAF4_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT)
+#define I40E_PRT_MNG_MIPAF6(_i) (0x00254200 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
#define I40E_PRT_MNG_MIPAF6_MAX_INDEX 15
#define I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF6_MIPAF_MASK (0xFFFFFFFF << I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MMAH(_i) (0x00256380 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MIPAF6_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT)
+#define I40E_PRT_MNG_MMAH(_i) (0x00256380 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MMAH_MAX_INDEX 3
#define I40E_PRT_MNG_MMAH_MMAH_SHIFT 0
-#define I40E_PRT_MNG_MMAH_MMAH_MASK (0xFFFF << I40E_PRT_MNG_MMAH_MMAH_SHIFT)
-#define I40E_PRT_MNG_MMAL(_i) (0x00256480 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MMAH_MMAH_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MMAH_MMAH_SHIFT)
+#define I40E_PRT_MNG_MMAL(_i) (0x00256480 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MMAL_MAX_INDEX 3
#define I40E_PRT_MNG_MMAL_MMAL_SHIFT 0
-#define I40E_PRT_MNG_MMAL_MMAL_MASK (0xFFFFFFFF << I40E_PRT_MNG_MMAL_MMAL_SHIFT)
-#define I40E_PRT_MNG_MNGONLY 0x00256A60
+#define I40E_PRT_MNG_MMAL_MMAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MMAL_MMAL_SHIFT)
+#define I40E_PRT_MNG_MNGONLY 0x00256A60 /* Reset: POR */
#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT 0
-#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_MASK (0xFF << I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT)
-#define I40E_PRT_MNG_MSFM 0x00256AA0
+#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT)
+#define I40E_PRT_MNG_MSFM 0x00256AA0 /* Reset: POR */
#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT 0
-#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT 1
-#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT 2
-#define I40E_PRT_MNG_MSFM_PORT_298_UDP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_298_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT 3
-#define I40E_PRT_MNG_MSFM_PORT_298_TCP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_298_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT 4
-#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT 5
-#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT 6
-#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT 7
-#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT)
-#define I40E_MSIX_PBA(_i) (0x00004900 + ((_i) * 4)) /* _i=0...5 */
+#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT)
+#define I40E_MSIX_PBA(_i) (0x00001000 + ((_i) * 4)) /* _i=0...5 */ /* Reset: FLR */
#define I40E_MSIX_PBA_MAX_INDEX 5
#define I40E_MSIX_PBA_PENBIT_SHIFT 0
-#define I40E_MSIX_PBA_PENBIT_MASK (0xFFFFFFFF << I40E_MSIX_PBA_PENBIT_SHIFT)
-#define I40E_MSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_PBA_PENBIT_SHIFT)
+#define I40E_MSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TADD_MAX_INDEX 128
#define I40E_MSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_MSIX_TADD_MSIXTADD10_MASK (0x3 << I40E_MSIX_TADD_MSIXTADD10_SHIFT)
+#define I40E_MSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_MSIX_TADD_MSIXTADD10_SHIFT)
#define I40E_MSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_MSIX_TADD_MSIXTADD_MASK (0x3FFFFFFF << I40E_MSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_MSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_MSIX_TADD_MSIXTADD_SHIFT)
+#define I40E_MSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TMSG_MAX_INDEX 128
#define I40E_MSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_MSIX_TMSG_MSIXTMSG_MASK (0xFFFFFFFF << I40E_MSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_MSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TMSG_MSIXTMSG_SHIFT)
+#define I40E_MSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TUADD_MAX_INDEX 128
#define I40E_MSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_MSIX_TUADD_MSIXTUADD_MASK (0xFFFFFFFF << I40E_MSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_MSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TUADD_MSIXTUADD_SHIFT)
+#define I40E_MSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TVCTRL_MAX_INDEX 128
#define I40E_MSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_MSIX_TVCTRL_MASK_MASK (0x1 << I40E_MSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFMSIX_PBA1(_i) (0x00004944 + ((_i) * 4)) /* _i=0...19 */
+#define I40E_MSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_MSIX_TVCTRL_MASK_SHIFT)
+#define I40E_VFMSIX_PBA1(_i) (0x00002000 + ((_i) * 4)) /* _i=0...19 */ /* Reset: VFLR */
#define I40E_VFMSIX_PBA1_MAX_INDEX 19
#define I40E_VFMSIX_PBA1_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA1_PENBIT_MASK (0xFFFFFFFF << I40E_VFMSIX_PBA1_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_PBA1_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA1_PENBIT_SHIFT)
+#define I40E_VFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TADD1_MAX_INDEX 639
#define I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD1_MSIXTADD10_MASK (0x3 << I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT)
+#define I40E_VFMSIX_TADD1_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT)
#define I40E_VFMSIX_TADD1_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD1_MSIXTADD_MASK (0x3FFFFFFF << I40E_VFMSIX_TADD1_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TADD1_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD1_MSIXTADD_SHIFT)
+#define I40E_VFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TMSG1_MAX_INDEX 639
#define I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG1_MSIXTMSG_MASK (0xFFFFFFFF << I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TMSG1_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT)
+#define I40E_VFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TUADD1_MAX_INDEX 639
#define I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD1_MSIXTUADD_MASK (0xFFFFFFFF << I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TUADD1_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT)
+#define I40E_VFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TVCTRL1_MAX_INDEX 639
#define I40E_VFMSIX_TVCTRL1_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL1_MASK_MASK (0x1 << I40E_VFMSIX_TVCTRL1_MASK_SHIFT)
-#define I40E_GLNVM_FLA 0x000B6108
+#define I40E_VFMSIX_TVCTRL1_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL1_MASK_SHIFT)
+#define I40E_GLNVM_FLA 0x000B6108 /* Reset: POR */
#define I40E_GLNVM_FLA_FL_SCK_SHIFT 0
-#define I40E_GLNVM_FLA_FL_SCK_MASK (0x1 << I40E_GLNVM_FLA_FL_SCK_SHIFT)
+#define I40E_GLNVM_FLA_FL_SCK_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SCK_SHIFT)
#define I40E_GLNVM_FLA_FL_CE_SHIFT 1
-#define I40E_GLNVM_FLA_FL_CE_MASK (0x1 << I40E_GLNVM_FLA_FL_CE_SHIFT)
+#define I40E_GLNVM_FLA_FL_CE_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_CE_SHIFT)
#define I40E_GLNVM_FLA_FL_SI_SHIFT 2
-#define I40E_GLNVM_FLA_FL_SI_MASK (0x1 << I40E_GLNVM_FLA_FL_SI_SHIFT)
+#define I40E_GLNVM_FLA_FL_SI_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SI_SHIFT)
#define I40E_GLNVM_FLA_FL_SO_SHIFT 3
-#define I40E_GLNVM_FLA_FL_SO_MASK (0x1 << I40E_GLNVM_FLA_FL_SO_SHIFT)
+#define I40E_GLNVM_FLA_FL_SO_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SO_SHIFT)
#define I40E_GLNVM_FLA_FL_REQ_SHIFT 4
-#define I40E_GLNVM_FLA_FL_REQ_MASK (0x1 << I40E_GLNVM_FLA_FL_REQ_SHIFT)
+#define I40E_GLNVM_FLA_FL_REQ_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_REQ_SHIFT)
#define I40E_GLNVM_FLA_FL_GNT_SHIFT 5
-#define I40E_GLNVM_FLA_FL_GNT_MASK (0x1 << I40E_GLNVM_FLA_FL_GNT_SHIFT)
+#define I40E_GLNVM_FLA_FL_GNT_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_GNT_SHIFT)
#define I40E_GLNVM_FLA_LOCKED_SHIFT 6
-#define I40E_GLNVM_FLA_LOCKED_MASK (0x1 << I40E_GLNVM_FLA_LOCKED_SHIFT)
+#define I40E_GLNVM_FLA_LOCKED_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_LOCKED_SHIFT)
#define I40E_GLNVM_FLA_FL_SADDR_SHIFT 18
-#define I40E_GLNVM_FLA_FL_SADDR_MASK (0x7FF << I40E_GLNVM_FLA_FL_SADDR_SHIFT)
+#define I40E_GLNVM_FLA_FL_SADDR_MASK I40E_MASK(0x7FF, I40E_GLNVM_FLA_FL_SADDR_SHIFT)
#define I40E_GLNVM_FLA_FL_BUSY_SHIFT 30
-#define I40E_GLNVM_FLA_FL_BUSY_MASK (0x1 << I40E_GLNVM_FLA_FL_BUSY_SHIFT)
+#define I40E_GLNVM_FLA_FL_BUSY_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_BUSY_SHIFT)
#define I40E_GLNVM_FLA_FL_DER_SHIFT 31
-#define I40E_GLNVM_FLA_FL_DER_MASK (0x1 << I40E_GLNVM_FLA_FL_DER_SHIFT)
-#define I40E_GLNVM_FLASHID 0x000B6104
+#define I40E_GLNVM_FLA_FL_DER_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_DER_SHIFT)
+#define I40E_GLNVM_FLASHID 0x000B6104 /* Reset: POR */
#define I40E_GLNVM_FLASHID_FLASHID_SHIFT 0
-#define I40E_GLNVM_FLASHID_FLASHID_MASK (0xFFFFFF << I40E_GLNVM_FLASHID_FLASHID_SHIFT)
-#define I40E_GLNVM_GENS 0x000B6100
+#define I40E_GLNVM_FLASHID_FLASHID_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_FLASHID_FLASHID_SHIFT)
+#define I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT 31
+#define I40E_GLNVM_FLASHID_FLEEP_PERF_MASK I40E_MASK(0x1, I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT)
+#define I40E_GLNVM_GENS 0x000B6100 /* Reset: POR */
#define I40E_GLNVM_GENS_NVM_PRES_SHIFT 0
-#define I40E_GLNVM_GENS_NVM_PRES_MASK (0x1 << I40E_GLNVM_GENS_NVM_PRES_SHIFT)
+#define I40E_GLNVM_GENS_NVM_PRES_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_NVM_PRES_SHIFT)
#define I40E_GLNVM_GENS_SR_SIZE_SHIFT 5
-#define I40E_GLNVM_GENS_SR_SIZE_MASK (0x7 << I40E_GLNVM_GENS_SR_SIZE_SHIFT)
+#define I40E_GLNVM_GENS_SR_SIZE_MASK I40E_MASK(0x7, I40E_GLNVM_GENS_SR_SIZE_SHIFT)
#define I40E_GLNVM_GENS_BANK1VAL_SHIFT 8
-#define I40E_GLNVM_GENS_BANK1VAL_MASK (0x1 << I40E_GLNVM_GENS_BANK1VAL_SHIFT)
+#define I40E_GLNVM_GENS_BANK1VAL_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_BANK1VAL_SHIFT)
#define I40E_GLNVM_GENS_ALT_PRST_SHIFT 23
-#define I40E_GLNVM_GENS_ALT_PRST_MASK (0x1 << I40E_GLNVM_GENS_ALT_PRST_SHIFT)
+#define I40E_GLNVM_GENS_ALT_PRST_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_ALT_PRST_SHIFT)
#define I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT 25
-#define I40E_GLNVM_GENS_FL_AUTO_RD_MASK (0x1 << I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT)
-#define I40E_GLNVM_PROTCSR(_i) (0x000B6010 + ((_i) * 4)) /* _i=0...59 */
+#define I40E_GLNVM_GENS_FL_AUTO_RD_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT)
+#define I40E_GLNVM_PROTCSR(_i) (0x000B6010 + ((_i) * 4)) /* _i=0...59 */ /* Reset: POR */
#define I40E_GLNVM_PROTCSR_MAX_INDEX 59
#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT 0
-#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_MASK (0xFFFFFF << I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT)
-#define I40E_GLNVM_SRCTL 0x000B6110
+#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT)
+#define I40E_GLNVM_SRCTL 0x000B6110 /* Reset: POR */
#define I40E_GLNVM_SRCTL_SRBUSY_SHIFT 0
-#define I40E_GLNVM_SRCTL_SRBUSY_MASK (0x1 << I40E_GLNVM_SRCTL_SRBUSY_SHIFT)
+#define I40E_GLNVM_SRCTL_SRBUSY_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_SRBUSY_SHIFT)
#define I40E_GLNVM_SRCTL_ADDR_SHIFT 14
-#define I40E_GLNVM_SRCTL_ADDR_MASK (0x7FFF << I40E_GLNVM_SRCTL_ADDR_SHIFT)
+#define I40E_GLNVM_SRCTL_ADDR_MASK I40E_MASK(0x7FFF, I40E_GLNVM_SRCTL_ADDR_SHIFT)
#define I40E_GLNVM_SRCTL_WRITE_SHIFT 29
-#define I40E_GLNVM_SRCTL_WRITE_MASK (0x1 << I40E_GLNVM_SRCTL_WRITE_SHIFT)
+#define I40E_GLNVM_SRCTL_WRITE_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_WRITE_SHIFT)
#define I40E_GLNVM_SRCTL_START_SHIFT 30
-#define I40E_GLNVM_SRCTL_START_MASK (0x1 << I40E_GLNVM_SRCTL_START_SHIFT)
+#define I40E_GLNVM_SRCTL_START_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_START_SHIFT)
#define I40E_GLNVM_SRCTL_DONE_SHIFT 31
-#define I40E_GLNVM_SRCTL_DONE_MASK (0x1 << I40E_GLNVM_SRCTL_DONE_SHIFT)
-#define I40E_GLNVM_SRDATA 0x000B6114
+#define I40E_GLNVM_SRCTL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_DONE_SHIFT)
+#define I40E_GLNVM_SRDATA 0x000B6114 /* Reset: POR */
#define I40E_GLNVM_SRDATA_WRDATA_SHIFT 0
-#define I40E_GLNVM_SRDATA_WRDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_WRDATA_SHIFT)
+#define I40E_GLNVM_SRDATA_WRDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_WRDATA_SHIFT)
#define I40E_GLNVM_SRDATA_RDDATA_SHIFT 16
-#define I40E_GLNVM_SRDATA_RDDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_RDDATA_SHIFT)
-#define I40E_GLNVM_ULD 0x000B6008
+#define I40E_GLNVM_SRDATA_RDDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_RDDATA_SHIFT)
+#define I40E_GLNVM_ULD 0x000B6008 /* Reset: POR */
#define I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT 0
-#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT 1
-#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT 2
-#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT 3
-#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT 4
-#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT 5
-#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT 6
-#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT 7
-#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT 8
-#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT 9
-#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
-
-#define I40E_GLPCI_BYTCTH 0x0009C484
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
+#define I40E_GLPCI_BYTCTH 0x0009C484 /* Reset: PCIR */
#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_BYTCTL 0x0009C488
+#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
+#define I40E_GLPCI_BYTCTL 0x0009C488 /* Reset: PCIR */
#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_CAPCTRL 0x000BE4A4
+#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT)
+#define I40E_GLPCI_CAPCTRL 0x000BE4A4 /* Reset: PCIR */
#define I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT 0
-#define I40E_GLPCI_CAPCTRL_VPD_EN_MASK (0x1 << I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP 0x000BE4A8
+#define I40E_GLPCI_CAPCTRL_VPD_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP 0x000BE4A8 /* Reset: PCIR */
#define I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT 0
-#define I40E_GLPCI_CAPSUP_PCIE_VER_MASK (0x1 << I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT)
+#define I40E_GLPCI_CAPSUP_PCIE_VER_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT)
#define I40E_GLPCI_CAPSUP_LTR_EN_SHIFT 2
-#define I40E_GLPCI_CAPSUP_LTR_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_LTR_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_LTR_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LTR_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_TPH_EN_SHIFT 3
-#define I40E_GLPCI_CAPSUP_TPH_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_TPH_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_TPH_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_TPH_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ARI_EN_SHIFT 4
-#define I40E_GLPCI_CAPSUP_ARI_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ARI_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ARI_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ARI_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_IOV_EN_SHIFT 5
-#define I40E_GLPCI_CAPSUP_IOV_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_IOV_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_IOV_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IOV_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ACS_EN_SHIFT 6
-#define I40E_GLPCI_CAPSUP_ACS_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ACS_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ACS_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ACS_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_SEC_EN_SHIFT 7
-#define I40E_GLPCI_CAPSUP_SEC_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_SEC_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_SEC_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_SEC_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT 16
-#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT 17
-#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_IDO_EN_SHIFT 18
-#define I40E_GLPCI_CAPSUP_IDO_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_IDO_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_IDO_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IDO_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT 19
-#define I40E_GLPCI_CAPSUP_MSI_MASK_MASK (0x1 << I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT)
+#define I40E_GLPCI_CAPSUP_MSI_MASK_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT)
#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT 20
-#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT 30
-#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_MASK (0x1 << I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT)
+#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT)
#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT 31
-#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_MASK (0x1 << I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT)
-#define I40E_GLPCI_CNF 0x000BE4C0
+#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT)
+#define I40E_GLPCI_CNF 0x000BE4C0 /* Reset: POR */
#define I40E_GLPCI_CNF_FLEX10_SHIFT 1
-#define I40E_GLPCI_CNF_FLEX10_MASK (0x1 << I40E_GLPCI_CNF_FLEX10_SHIFT)
+#define I40E_GLPCI_CNF_FLEX10_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_FLEX10_SHIFT)
#define I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT 2
-#define I40E_GLPCI_CNF_WAKE_PIN_EN_MASK (0x1 << I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT)
-#define I40E_GLPCI_CNF2 0x000BE494
+#define I40E_GLPCI_CNF_WAKE_PIN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT)
+#define I40E_GLPCI_CNF2 0x000BE494 /* Reset: PCIR */
#define I40E_GLPCI_CNF2_RO_DIS_SHIFT 0
-#define I40E_GLPCI_CNF2_RO_DIS_MASK (0x1 << I40E_GLPCI_CNF2_RO_DIS_SHIFT)
+#define I40E_GLPCI_CNF2_RO_DIS_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_RO_DIS_SHIFT)
#define I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT 1
-#define I40E_GLPCI_CNF2_CACHELINE_SIZE_MASK (0x1 << I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT)
+#define I40E_GLPCI_CNF2_CACHELINE_SIZE_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT 2
-#define I40E_GLPCI_CNF2_MSI_X_PF_N_MASK (0x7FF << I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT)
+#define I40E_GLPCI_CNF2_MSI_X_PF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT 13
-#define I40E_GLPCI_CNF2_MSI_X_VF_N_MASK (0x7FF << I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT)
-#define I40E_GLPCI_DREVID 0x0009C480
+#define I40E_GLPCI_CNF2_MSI_X_VF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT)
+#define I40E_GLPCI_DREVID 0x0009C480 /* Reset: PCIR */
#define I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT 0
-#define I40E_GLPCI_DREVID_DEFAULT_REVID_MASK (0xFF << I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT)
-#define I40E_GLPCI_GSCL_1 0x0009C48C
+#define I40E_GLPCI_DREVID_DEFAULT_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT)
+#define I40E_GLPCI_GSCL_1 0x0009C48C /* Reset: PCIR */
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT 0
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT 1
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT 2
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT 3
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT 4
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT 5
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT 6
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT 7
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT 8
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT 9
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_MASK (0x1F << I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT 14
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT 15
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_MASK (0x1F << I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT 28
-#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT 29
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT 30
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT 31
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT)
-#define I40E_GLPCI_GSCL_2 0x0009C490
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT)
+#define I40E_GLPCI_GSCL_2 0x0009C490 /* Reset: PCIR */
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT 0
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT 8
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT 16
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT 24
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT)
-#define I40E_GLPCI_GSCL_5_8(_i) (0x0009C494 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT)
+#define I40E_GLPCI_GSCL_5_8(_i) (0x0009C494 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
#define I40E_GLPCI_GSCL_5_8_MAX_INDEX 3
#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT 0
-#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_MASK (0xFFFF << I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT)
+#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT)
#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT 16
-#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_MASK (0xFFFF << I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT)
-#define I40E_GLPCI_GSCN_0_3(_i) (0x0009C4A4 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT)
+#define I40E_GLPCI_GSCN_0_3(_i) (0x0009C4A4 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
#define I40E_GLPCI_GSCN_0_3_MAX_INDEX 3
#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT 0
-#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_MASK (0xFFFFFFFF << I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT)
-#define I40E_GLPCI_LATCT 0x0009C4B4
+#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT)
+#define I40E_GLPCI_LATCT 0x0009C4B4 /* Reset: PCIR */
#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT 0
-#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_MASK (0xFFFFFFFF << I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT)
-#define I40E_GLPCI_LBARCTRL 0x000BE484
+#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT)
+#define I40E_GLPCI_LBARCTRL 0x000BE484 /* Reset: POR */
#define I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT 0
-#define I40E_GLPCI_LBARCTRL_PREFBAR_MASK (0x1 << I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT)
+#define I40E_GLPCI_LBARCTRL_PREFBAR_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT)
#define I40E_GLPCI_LBARCTRL_BAR32_SHIFT 1
-#define I40E_GLPCI_LBARCTRL_BAR32_MASK (0x1 << I40E_GLPCI_LBARCTRL_BAR32_SHIFT)
+#define I40E_GLPCI_LBARCTRL_BAR32_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_BAR32_SHIFT)
#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT 3
-#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_MASK (0x1 << I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT 4
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_MASK (0x3 << I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT 4
+#define I40E_GLPCI_LBARCTRL_RSVD_4_MASK I40E_MASK(0x3, I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT)
#define I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT 6
-#define I40E_GLPCI_LBARCTRL_FL_SIZE_MASK (0x7 << I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT 10
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_MASK (0x1 << I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_FL_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT 10
+#define I40E_GLPCI_LBARCTRL_RSVD_10_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT)
#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT 11
-#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_MASK (0x7 << I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT)
-#define I40E_GLPCI_LINKCAP 0x000BE4AC
+#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT)
+#define I40E_GLPCI_LINKCAP 0x000BE4AC /* Reset: PCIR */
#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT 0
-#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_MASK (0x3F << I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT)
+#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_MASK I40E_MASK(0x3F, I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT)
#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT 6
-#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_MASK (0x7 << I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT)
+#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_MASK I40E_MASK(0x7, I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT)
#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT 9
-#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_MASK (0xF << I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT)
-#define I40E_GLPCI_PCIERR 0x000BE4FC
+#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_MASK I40E_MASK(0xF, I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT)
+#define I40E_GLPCI_PCIERR 0x000BE4FC /* Reset: PCIR */
#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT 0
-#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK (0xFFFFFFFF << I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
-#define I40E_GLPCI_PCITEST2 0x000BE4BC
-#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT 0
-#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_MASK (0x1 << I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT)
-#define I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT 1
-#define I40E_GLPCI_PCITEST2_TAG_ALLOC_MASK (0x1 << I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT)
-
-#define I40E_GLPCI_PKTCT 0x0009C4BC
+#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
+#define I40E_GLPCI_PKTCT 0x0009C4BC /* Reset: PCIR */
#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT 0
-#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK (0xFFFFFFFF << I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)
-#define I40E_GLPCI_PMSUP 0x000BE4B0
+#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)
+#define I40E_GLPCI_PM_MUX_NPQ 0x0009C4F4 /* Reset: PCIR */
+#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT 0
+#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT 16
+#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_PFB 0x0009C4F0 /* Reset: PCIR */
+#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT 0
+#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT 16
+#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PMSUP 0x000BE4B0 /* Reset: PCIR */
#define I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT 0
-#define I40E_GLPCI_PMSUP_ASPM_SUP_MASK (0x3 << I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT)
+#define I40E_GLPCI_PMSUP_ASPM_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT)
#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT 2
-#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT 5
-#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT 8
-#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT 11
-#define I40E_GLPCI_PMSUP_L1_ACC_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L1_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT 14
-#define I40E_GLPCI_PMSUP_SLOT_CLK_MASK (0x1 << I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT)
+#define I40E_GLPCI_PMSUP_SLOT_CLK_MASK I40E_MASK(0x1, I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT)
#define I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT 15
-#define I40E_GLPCI_PMSUP_OBFF_SUP_MASK (0x3 << I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT)
-#define I40E_GLPCI_PWRDATA 0x000BE490
+#define I40E_GLPCI_PMSUP_OBFF_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT)
+#define I40E_GLPCI_PQ_MAX_USED_SPC 0x0009C4EC /* Reset: PCIR */
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT 0
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT)
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT 8
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT)
+#define I40E_GLPCI_PWRDATA 0x000BE490 /* Reset: PCIR */
#define I40E_GLPCI_PWRDATA_D0_POWER_SHIFT 0
-#define I40E_GLPCI_PWRDATA_D0_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_D0_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_D0_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D0_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT 8
-#define I40E_GLPCI_PWRDATA_COMM_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_COMM_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_D3_POWER_SHIFT 16
-#define I40E_GLPCI_PWRDATA_D3_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_D3_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_D3_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D3_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT 24
-#define I40E_GLPCI_PWRDATA_DATA_SCALE_MASK (0x3 << I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT)
-#define I40E_GLPCI_REVID 0x000BE4B4
+#define I40E_GLPCI_PWRDATA_DATA_SCALE_MASK I40E_MASK(0x3, I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT)
+#define I40E_GLPCI_REVID 0x000BE4B4 /* Reset: PCIR */
#define I40E_GLPCI_REVID_NVM_REVID_SHIFT 0
-#define I40E_GLPCI_REVID_NVM_REVID_MASK (0xFF << I40E_GLPCI_REVID_NVM_REVID_SHIFT)
-#define I40E_GLPCI_SERH 0x000BE49C
+#define I40E_GLPCI_REVID_NVM_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_REVID_NVM_REVID_SHIFT)
+#define I40E_GLPCI_SERH 0x000BE49C /* Reset: PCIR */
#define I40E_GLPCI_SERH_SER_NUM_H_SHIFT 0
-#define I40E_GLPCI_SERH_SER_NUM_H_MASK (0xFFFF << I40E_GLPCI_SERH_SER_NUM_H_SHIFT)
-#define I40E_GLPCI_SERL 0x000BE498
+#define I40E_GLPCI_SERH_SER_NUM_H_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SERH_SER_NUM_H_SHIFT)
+#define I40E_GLPCI_SERL 0x000BE498 /* Reset: PCIR */
#define I40E_GLPCI_SERL_SER_NUM_L_SHIFT 0
-#define I40E_GLPCI_SERL_SER_NUM_L_MASK (0xFFFFFFFF << I40E_GLPCI_SERL_SER_NUM_L_SHIFT)
-#define I40E_GLPCI_SUBSYSID 0x000BE48C
-#define I40E_GLPCI_SUBSYSID_SUB_VEN_ID_SHIFT 0
-#define I40E_GLPCI_SUBSYSID_SUB_VEN_ID_MASK (0xFFFF << I40E_GLPCI_SUBSYSID_SUB_VEN_ID_SHIFT)
-#define I40E_GLPCI_SUBSYSID_SUB_ID_SHIFT 16
-#define I40E_GLPCI_SUBSYSID_SUB_ID_MASK (0xFFFF << I40E_GLPCI_SUBSYSID_SUB_ID_SHIFT)
-#define I40E_GLPCI_UPADD 0x000BE4F8
+#define I40E_GLPCI_SERL_SER_NUM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SERL_SER_NUM_L_SHIFT)
+#define I40E_GLPCI_SPARE_BITS_0 0x0009C4F8 /* Reset: PCIR */
+#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT 0
+#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT)
+#define I40E_GLPCI_SPARE_BITS_1 0x0009C4FC /* Reset: PCIR */
+#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT 0
+#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT)
+#define I40E_GLPCI_SUBVENID 0x000BE48C /* Reset: PCIR */
+#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT 0
+#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT)
+#define I40E_GLPCI_UPADD 0x000BE4F8 /* Reset: PCIR */
#define I40E_GLPCI_UPADD_ADDRESS_SHIFT 1
-#define I40E_GLPCI_UPADD_ADDRESS_MASK (0x7FFFFFFF << I40E_GLPCI_UPADD_ADDRESS_SHIFT)
-#define I40E_GLPCI_VFSUP 0x000BE4B8
+#define I40E_GLPCI_UPADD_ADDRESS_MASK I40E_MASK(0x7FFFFFFF, I40E_GLPCI_UPADD_ADDRESS_SHIFT)
+#define I40E_GLPCI_VENDORID 0x000BE518 /* Reset: PCIR */
+#define I40E_GLPCI_VENDORID_VENDORID_SHIFT 0
+#define I40E_GLPCI_VENDORID_VENDORID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_VENDORID_VENDORID_SHIFT)
+#define I40E_GLPCI_VFSUP 0x000BE4B8 /* Reset: PCIR */
#define I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT 0
-#define I40E_GLPCI_VFSUP_VF_PREFETCH_MASK (0x1 << I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT)
+#define I40E_GLPCI_VFSUP_VF_PREFETCH_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT)
#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT 1
-#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_MASK (0x1 << I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT)
-#define I40E_PF_FUNC_RID 0x0009C000
+#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT)
+#define I40E_PF_FUNC_RID 0x0009C000 /* Reset: PCIR */
#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT 0
-#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_MASK (0x7 << I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT)
+#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_MASK I40E_MASK(0x7, I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT)
#define I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT 3
-#define I40E_PF_FUNC_RID_DEVICE_NUMBER_MASK (0x1F << I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT)
+#define I40E_PF_FUNC_RID_DEVICE_NUMBER_MASK I40E_MASK(0x1F, I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT)
#define I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT 8
-#define I40E_PF_FUNC_RID_BUS_NUMBER_MASK (0xFF << I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT)
-#define I40E_PF_PCI_CIAA 0x0009C080
+#define I40E_PF_FUNC_RID_BUS_NUMBER_MASK I40E_MASK(0xFF, I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT)
+#define I40E_PF_PCI_CIAA 0x0009C080 /* Reset: FLR */
#define I40E_PF_PCI_CIAA_ADDRESS_SHIFT 0
-#define I40E_PF_PCI_CIAA_ADDRESS_MASK (0xFFF << I40E_PF_PCI_CIAA_ADDRESS_SHIFT)
+#define I40E_PF_PCI_CIAA_ADDRESS_MASK I40E_MASK(0xFFF, I40E_PF_PCI_CIAA_ADDRESS_SHIFT)
#define I40E_PF_PCI_CIAA_VF_NUM_SHIFT 12
-#define I40E_PF_PCI_CIAA_VF_NUM_MASK (0x7F << I40E_PF_PCI_CIAA_VF_NUM_SHIFT)
-#define I40E_PF_PCI_CIAD 0x0009C100
+#define I40E_PF_PCI_CIAA_VF_NUM_MASK I40E_MASK(0x7F, I40E_PF_PCI_CIAA_VF_NUM_SHIFT)
+#define I40E_PF_PCI_CIAD 0x0009C100 /* Reset: FLR */
#define I40E_PF_PCI_CIAD_DATA_SHIFT 0
-#define I40E_PF_PCI_CIAD_DATA_MASK (0xFFFFFFFF << I40E_PF_PCI_CIAD_DATA_SHIFT)
-#define I40E_PFPCI_CLASS 0x000BE400
+#define I40E_PF_PCI_CIAD_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_PCI_CIAD_DATA_SHIFT)
+#define I40E_PFPCI_CLASS 0x000BE400 /* Reset: PCIR */
#define I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT 0
-#define I40E_PFPCI_CLASS_STORAGE_CLASS_MASK (0x1 << I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT)
-#define I40E_PFPCI_CNF 0x000BE000
+#define I40E_PFPCI_CLASS_STORAGE_CLASS_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT)
+#define I40E_PFPCI_CLASS_RESERVED_1_SHIFT 1
+#define I40E_PFPCI_CLASS_RESERVED_1_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_RESERVED_1_SHIFT)
+#define I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT 2
+#define I40E_PFPCI_CLASS_PF_IS_LAN_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT)
+#define I40E_PFPCI_CNF 0x000BE000 /* Reset: PCIR */
#define I40E_PFPCI_CNF_MSI_EN_SHIFT 2
-#define I40E_PFPCI_CNF_MSI_EN_MASK (0x1 << I40E_PFPCI_CNF_MSI_EN_SHIFT)
+#define I40E_PFPCI_CNF_MSI_EN_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_MSI_EN_SHIFT)
#define I40E_PFPCI_CNF_EXROM_DIS_SHIFT 3
-#define I40E_PFPCI_CNF_EXROM_DIS_MASK (0x1 << I40E_PFPCI_CNF_EXROM_DIS_SHIFT)
+#define I40E_PFPCI_CNF_EXROM_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_EXROM_DIS_SHIFT)
#define I40E_PFPCI_CNF_IO_BAR_SHIFT 4
-#define I40E_PFPCI_CNF_IO_BAR_MASK (0x1 << I40E_PFPCI_CNF_IO_BAR_SHIFT)
+#define I40E_PFPCI_CNF_IO_BAR_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_IO_BAR_SHIFT)
#define I40E_PFPCI_CNF_INT_PIN_SHIFT 5
-#define I40E_PFPCI_CNF_INT_PIN_MASK (0x3 << I40E_PFPCI_CNF_INT_PIN_SHIFT)
-#define I40E_PFPCI_FACTPS 0x0009C180
+#define I40E_PFPCI_CNF_INT_PIN_MASK I40E_MASK(0x3, I40E_PFPCI_CNF_INT_PIN_SHIFT)
+#define I40E_PFPCI_DEVID 0x000BE080 /* Reset: PCIR */
+#define I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT 0
+#define I40E_PFPCI_DEVID_PF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT)
+#define I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT 16
+#define I40E_PFPCI_DEVID_VF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT)
+#define I40E_PFPCI_FACTPS 0x0009C180 /* Reset: FLR */
#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT 0
-#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_MASK (0x3 << I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT)
+#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_MASK I40E_MASK(0x3, I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT)
#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT 3
-#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_MASK (0x1 << I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT)
-#define I40E_PFPCI_FUNC 0x000BE200
+#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_MASK I40E_MASK(0x1, I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT)
+#define I40E_PFPCI_FUNC 0x000BE200 /* Reset: POR */
#define I40E_PFPCI_FUNC_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_FUNC_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_FUNC_DIS_SHIFT)
#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT 1
-#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT)
#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT 2
-#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_MASK (0x1 << I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT)
-#define I40E_PFPCI_FUNC2 0x000BE180
+#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT)
+#define I40E_PFPCI_FUNC2 0x000BE180 /* Reset: PCIR */
#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT)
-#define I40E_PFPCI_ICAUSE 0x0009C200
+#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_ICAUSE 0x0009C200 /* Reset: PFR */
#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT 0
-#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_MASK (0xFFFFFFFF << I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT)
-#define I40E_PFPCI_IENA 0x0009C280
+#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT)
+#define I40E_PFPCI_IENA 0x0009C280 /* Reset: PFR */
#define I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT 0
-#define I40E_PFPCI_IENA_PCIE_ERR_EN_MASK (0xFFFFFFFF << I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT)
-#define I40E_PFPCI_PFDEVID 0x000BE080
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_SHIFT 0
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_MASK (0xFFFF << I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_SHIFT)
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_SHIFT 16
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_MASK (0xFFFF << I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_SHIFT)
-#define I40E_PFPCI_PM 0x000BE300
+#define I40E_PFPCI_IENA_PCIE_ERR_EN_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT)
+#define I40E_PFPCI_PF_FLUSH_DONE 0x0009C800 /* Reset: PCIR */
+#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_PM 0x000BE300 /* Reset: POR */
#define I40E_PFPCI_PM_PME_EN_SHIFT 0
-#define I40E_PFPCI_PM_PME_EN_MASK (0x1 << I40E_PFPCI_PM_PME_EN_SHIFT)
-#define I40E_PFPCI_STATUS1 0x000BE280
+#define I40E_PFPCI_PM_PME_EN_MASK I40E_MASK(0x1, I40E_PFPCI_PM_PME_EN_SHIFT)
+#define I40E_PFPCI_STATUS1 0x000BE280 /* Reset: POR */
#define I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT 0
-#define I40E_PFPCI_STATUS1_FUNC_VALID_MASK (0x1 << I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT)
-#define I40E_PFPCI_VFDEVID 0x000BE100
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_SHIFT 0
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_MASK (0xFFFF << I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_SHIFT)
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_SHIFT 16
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_MASK (0xFFFF << I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_SHIFT)
-#define I40E_PFPCI_VMINDEX 0x0009C300
+#define I40E_PFPCI_STATUS1_FUNC_VALID_MASK I40E_MASK(0x1, I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT)
+#define I40E_PFPCI_SUBSYSID 0x000BE100 /* Reset: PCIR */
+#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT 0
+#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT)
+#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT 16
+#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT)
+#define I40E_PFPCI_VF_FLUSH_DONE 0x0000E400 /* Reset: PCIR */
+#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VF_FLUSH_DONE1(_VF) (0x0009C600 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: PCIR */
+#define I40E_PFPCI_VF_FLUSH_DONE1_MAX_INDEX 127
+#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VM_FLUSH_DONE 0x0009C880 /* Reset: PCIR */
+#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VMINDEX 0x0009C300 /* Reset: PCIR */
#define I40E_PFPCI_VMINDEX_VMINDEX_SHIFT 0
-#define I40E_PFPCI_VMINDEX_VMINDEX_MASK (0x1FF << I40E_PFPCI_VMINDEX_VMINDEX_SHIFT)
-#define I40E_PFPCI_VMPEND 0x0009C380
+#define I40E_PFPCI_VMINDEX_VMINDEX_MASK I40E_MASK(0x1FF, I40E_PFPCI_VMINDEX_VMINDEX_SHIFT)
+#define I40E_PFPCI_VMPEND 0x0009C380 /* Reset: PCIR */
#define I40E_PFPCI_VMPEND_PENDING_SHIFT 0
-#define I40E_PFPCI_VMPEND_PENDING_MASK (0x1 << I40E_PFPCI_VMPEND_PENDING_SHIFT)
-#define I40E_GLPE_CPUSTATUS0 0x0000D040
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT 0
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT)
-#define I40E_GLPE_CPUSTATUS1 0x0000D044
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT 0
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT)
-#define I40E_GLPE_CPUSTATUS2 0x0000D048
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT 0
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT)
-#define I40E_GLPE_PFFLMOBJCTRL(_i) (0x0000D480 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPE_PFFLMOBJCTRL_MAX_INDEX 15
-#define I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
-#define I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK (0x7 << I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
-#define I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_MASK (0x7 << I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMOBJCTRL_MAX_INDEX 31
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK (0x7 << I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_MASK (0x7 << I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMQ1ALLOCERR(_i) (0x0000C700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMQ1ALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFFLMXMITALLOCERR(_i) (0x0000C600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMXMITALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFUDACTRL(_i) (0x0000C000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFUDACTRL_MAX_INDEX 31
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_MASK (0x1 << I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN(_i) (0x0000C100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFUDAUCFBQPN_MAX_INDEX 31
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT 0
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_MASK (0x3FFFF << I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT 31
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_MASK (0x1 << I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_AEQALLOC 0x00131180
-#define I40E_PFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_PFPE_AEQALLOC_AECOUNT_MASK (0xFFFFFFFF << I40E_PFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_PFPE_CCQPHIGH 0x00008200
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_PFPE_CCQPLOW 0x00008180
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_MASK (0xFFFFFFFF << I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_PFPE_CCQPSTATUS 0x00008100
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_MASK (0x1 << I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_MASK (0x1 << I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_PFPE_CQACK 0x00131100
-#define I40E_PFPE_CQACK_PECQID_SHIFT 0
-#define I40E_PFPE_CQACK_PECQID_MASK (0x1FFFF << I40E_PFPE_CQACK_PECQID_SHIFT)
-#define I40E_PFPE_CQARM 0x00131080
-#define I40E_PFPE_CQARM_PECQID_SHIFT 0
-#define I40E_PFPE_CQARM_PECQID_MASK (0x1FFFF << I40E_PFPE_CQARM_PECQID_SHIFT)
-#define I40E_PFPE_CQPDB 0x00008000
-#define I40E_PFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_PFPE_CQPDB_WQHEAD_MASK (0x7FF << I40E_PFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_PFPE_CQPERRCODES 0x00008880
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_MASK (0xFFFF << I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_PFPE_CQPTAIL 0x00008080
-#define I40E_PFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_PFPE_CQPTAIL_WQTAIL_MASK (0x7FF << I40E_PFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_MASK (0x1 << I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_PFPE_FLMQ1ALLOCERR 0x00008980
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_FLMXMITALLOCERR 0x00008900
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_IPCONFIG0 0x00008280
-#define I40E_PFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_PFPE_IPCONFIG0_PEIPID_MASK (0xFFFF << I40E_PFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_MASK (0x1 << I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-
-#define I40E_PFPE_MRTEIDXMASK 0x00008600
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK (0x1F << I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_PFPE_RCVUNEXPECTEDERROR 0x00008680
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_PFPE_TCPNOWTIMER 0x00008580
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_MASK (0xFFFFFFFF << I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_PFPE_UDACTRL 0x00008700
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_MASK (0x1 << I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN 0x00008780
-#define I40E_PFPE_UDAUCFBQPN_QPN_SHIFT 0
-#define I40E_PFPE_UDAUCFBQPN_QPN_MASK (0x3FFFF << I40E_PFPE_UDAUCFBQPN_QPN_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN_VALID_SHIFT 31
-#define I40E_PFPE_UDAUCFBQPN_VALID_MASK (0x1 << I40E_PFPE_UDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_WQEALLOC 0x00138C00
-#define I40E_PFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_PFPE_WQEALLOC_PEQPID_MASK (0x3FFFF << I40E_PFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_MASK (0xFFF << I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_VFPE_AEQALLOC(_VF) (0x00130C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_AEQALLOC_MAX_INDEX 127
-#define I40E_VFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC_AECOUNT_MASK (0xFFFFFFFF << I40E_VFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH(_VF) (0x00001000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPHIGH_MAX_INDEX 127
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW(_VF) (0x00000C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPLOW_MAX_INDEX 127
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_MASK (0xFFFFFFFF << I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS(_VF) (0x00000800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPSTATUS_MAX_INDEX 127
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_MASK (0x1 << I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_MASK (0x1 << I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK(_VF) (0x00130800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQACK_MAX_INDEX 127
-#define I40E_VFPE_CQACK_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK_PECQID_MASK (0x1FFFF << I40E_VFPE_CQACK_PECQID_SHIFT)
-#define I40E_VFPE_CQARM(_VF) (0x00130400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQARM_MAX_INDEX 127
-#define I40E_VFPE_CQARM_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM_PECQID_MASK (0x1FFFF << I40E_VFPE_CQARM_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB(_VF) (0x00000000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPDB_MAX_INDEX 127
-#define I40E_VFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB_WQHEAD_MASK (0x7FF << I40E_VFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES(_VF) (0x00001800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPERRCODES_MAX_INDEX 127
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL(_VF) (0x00000400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPTAIL_MAX_INDEX 127
-#define I40E_VFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL_WQTAIL_MASK (0x7FF << I40E_VFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_MASK (0x1 << I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG0(_VF) (0x00001400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_IPCONFIG0_MAX_INDEX 127
-#define I40E_VFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG0_PEIPID_MASK (0xFFFF << I40E_VFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_MASK (0x1 << I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK(_VF) (0x00003000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_MRTEIDXMASK_MAX_INDEX 127
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK (0x1F << I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR(_VF) (0x00003400 + ((_VF) * 4))
-#define I40E_VFPE_RCVUNEXPECTEDERROR_MAX_INDEX 127
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER(_VF) (0x00002C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_TCPNOWTIMER_MAX_INDEX 127
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_MASK (0xFFFFFFFF << I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC(_VF) (0x00138000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_WQEALLOC_MAX_INDEX 127
-#define I40E_VFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC_PEQPID_MASK (0x3FFFF << I40E_VFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_MASK (0xFFF << I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_GLPES_PFIP4RXDISCARD(_i) (0x00010600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSHI(_i) (0x00010804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSLO(_i) (0x00010800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSHI(_i) (0x00010A04 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSLO(_i) (0x00010A00 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSHI(_i) (0x00010C04 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSLO(_i) (0x00010C00 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSHI(_i) (0x00010204 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSLO(_i) (0x00010200 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSHI(_i) (0x00010404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSLO(_i) (0x00010400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXTRUNC(_i) (0x00010700 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSHI(_i) (0x00011E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSLO(_i) (0x00011E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSHI(_i) (0x00012004 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSLO(_i) (0x00012000 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSHI(_i) (0x00012204 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSLO(_i) (0x00012200 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXNOROUTE(_i) (0x00012E00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSHI(_i) (0x00011A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSLO(_i) (0x00011A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSHI(_i) (0x00011C04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSLO(_i) (0x00011C00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXDISCARD(_i) (0x00011200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSHI(_i) (0x00011404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSLO(_i) (0x00011400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSHI(_i) (0x00011604 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSLO(_i) (0x00011600 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSHI(_i) (0x00011804 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSLO(_i) (0x00011800 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSHI(_i) (0x00010E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSLO(_i) (0x00010E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSHI(_i) (0x00011004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSLO(_i) (0x00011000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXTRUNC(_i) (0x00011300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSHI(_i) (0x00012804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSLO(_i) (0x00012800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSHI(_i) (0x00012A04 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSLO(_i) (0x00012A00 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSHI(_i) (0x00012C04 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSLO(_i) (0x00012C00 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXNOROUTE(_i) (0x00012F00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSHI(_i) (0x00012404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSLO(_i) (0x00012400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSHI(_i) (0x00012604 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSLO(_i) (0x00012600 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSHI(_i) (0x00013E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSLO(_i) (0x00013E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSHI(_i) (0x00014004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSLO(_i) (0x00014000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSHI(_i) (0x00013C04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSLO(_i) (0x00013C00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSHI(_i) (0x00014404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSLO(_i) (0x00014400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSHI(_i) (0x00014604 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSLO(_i) (0x00014600 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSHI(_i) (0x00014204 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSLO(_i) (0x00014200 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDHI(_i) (0x00014804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVBNDHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDLO(_i) (0x00014800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVBNDLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_PFRDMAVINVHI(_i) (0x00014A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVINVHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_PFRDMAVINVLO(_i) (0x00014A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVINVLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_PFRXVLANERR(_i) (0x00010000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFRXVLANERR_MAX_INDEX 15
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_MASK (0xFFFFFF << I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_PFTCPRTXSEG(_i) (0x00013600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRTXSEG_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_PFTCPRXOPTERR(_i) (0x00013200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXOPTERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_MASK (0xFFFFFF << I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_PFTCPRXPROTOERR(_i) (0x00013300 + ((_i) * 4))
-#define I40E_GLPES_PFTCPRXPROTOERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_MASK (0xFFFFFF << I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSHI(_i) (0x00013004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXSEGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_MASK (0xFFFF << I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSLO(_i) (0x00013000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXSEGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGHI(_i) (0x00013404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPTXSEGHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_MASK (0xFFFF << I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGLO(_i) (0x00013400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPTXSEGLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSHI(_i) (0x00013804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPRXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSLO(_i) (0x00013800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPRXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSHI(_i) (0x00013A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPTXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSLO(_i) (0x00013A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPTXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSHI 0x0001E014
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_MASK (0xFFFFFF << I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSLO 0x0001E010
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPHI 0x0001E01C
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_MASK (0xFFFFFF << I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPLO 0x0001E018
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT)
-#define I40E_GLPES_RDMARXOOONOMARK 0x0001E004
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT 0
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT)
-#define I40E_GLPES_RDMARXUNALIGN 0x0001E000
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT 0
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLEHI 0x0001E044
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLELO 0x0001E040
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLEHI 0x0001E02C
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLELO 0x0001E028
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKHI 0x0001E024
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKSLO 0x0001E020
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLEHI 0x0001E03C
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLELO 0x0001E038
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLEHI 0x0001E034
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLELO 0x0001E030
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXUNEXPERR 0x0001E008
-#define I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_SHIFT 0
-#define I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_MASK (0xFFFFFF << I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTHI 0x0001E04C
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTLO 0x0001E048
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTHI 0x0001E054
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTLO 0x0001E050
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSHI 0x0001E05C
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSLO 0x0001E058
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXDISCARD(_i) (0x00018600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSHI(_i) (0x00018804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSLO(_i) (0x00018800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSHI(_i) (0x00018A04 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSLO(_i) (0x00018A00 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSHI(_i) (0x00018C04 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSLO(_i) (0x00018C00 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSHI(_i) (0x00018204 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSLO(_i) (0x00018200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSHI(_i) (0x00018404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSLO(_i) (0x00018400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXTRUNC(_i) (0x00018700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSHI(_i) (0x00019E04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSLO(_i) (0x00019E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSHI(_i) (0x0001A004 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSLO(_i) (0x0001A000 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSHI(_i) (0x0001A204 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSLO(_i) (0x0001A200 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXNOROUTE(_i) (0x0001AE00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSHI(_i) (0x00019A04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSLO(_i) (0x00019A00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSHI(_i) (0x00019C04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSLO(_i) (0x00019C00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXDISCARD(_i) (0x00019200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSHI(_i) (0x00019404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSLO(_i) (0x00019400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSHI(_i) (0x00019604 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSLO(_i) (0x00019600 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSHI(_i) (0x00019804 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSLO(_i) (0x00019800 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSHI(_i) (0x00018E04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSLO(_i) (0x00018E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSHI(_i) (0x00019004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSLO(_i) (0x00019000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXTRUNC(_i) (0x00019300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSHI(_i) (0x0001A804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSLO(_i) (0x0001A800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSHI(_i) (0x0001AA04 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSLO(_i) (0x0001AA00 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSHI(_i) (0x0001AC04 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSLO(_i) (0x0001AC00 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXNOROUTE(_i) (0x0001AF00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSHI(_i) (0x0001A404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSLO(_i) (0x0001A400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSHI(_i) (0x0001A604 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSLO(_i) (0x0001A600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSHI(_i) (0x0001BE04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSLO(_i) (0x0001BE00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSHI(_i) (0x0001C004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSLO(_i) (0x0001C000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSHI(_i) (0x0001BC04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSLO(_i) (0x0001BC00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSHI(_i) (0x0001C404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSLO(_i) (0x0001C400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSHI(_i) (0x0001C604 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSLO(_i) (0x0001C600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSHI(_i) (0x0001C204 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSLO(_i) (0x0001C200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDHI(_i) (0x0001C804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVBNDHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDLO(_i) (0x0001C800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVBNDLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_VFRDMAVINVHI(_i) (0x0001CA04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVINVHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_VFRDMAVINVLO(_i) (0x0001CA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVINVLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_VFRXVLANERR(_i) (0x00018000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRXVLANERR_MAX_INDEX 31
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_MASK (0xFFFFFF << I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_VFTCPRTXSEG(_i) (0x0001B600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRTXSEG_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_VFTCPRXOPTERR(_i) (0x0001B200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXOPTERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_MASK (0xFFFFFF << I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_VFTCPRXPROTOERR(_i) (0x0001B300 + ((_i) * 4))
-#define I40E_GLPES_VFTCPRXPROTOERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_MASK (0xFFFFFF << I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSHI(_i) (0x0001B004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXSEGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_MASK (0xFFFF << I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSLO(_i) (0x0001B000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXSEGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGHI(_i) (0x0001B404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPTXSEGHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_MASK (0xFFFF << I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGLO(_i) (0x0001B400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPTXSEGLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSHI(_i) (0x0001B804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPRXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSLO(_i) (0x0001B800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPRXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSHI(_i) (0x0001BA04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPTXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSLO(_i) (0x0001BA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPTXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_PRTPM_EEE_STAT 0x001E4320
+#define I40E_PFPCI_VMPEND_PENDING_MASK I40E_MASK(0x1, I40E_PFPCI_VMPEND_PENDING_SHIFT)
+#define I40E_PRTPM_EEE_STAT 0x001E4320 /* Reset: GLOBR */
#define I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT 29
-#define I40E_PRTPM_EEE_STAT_EEE_NEG_MASK (0x1 << I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT)
+#define I40E_PRTPM_EEE_STAT_EEE_NEG_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT)
#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT 30
-#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK (0x1 << I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
+#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT 31
-#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK (0x1 << I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
-#define I40E_PRTPM_EEEC 0x001E4380
+#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
+#define I40E_PRTPM_EEEC 0x001E4380 /* Reset: GLOBR */
#define I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT 16
-#define I40E_PRTPM_EEEC_TW_WAKE_MIN_MASK (0x3F << I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT)
+#define I40E_PRTPM_EEEC_TW_WAKE_MIN_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT)
#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT 24
-#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_MASK (0x3 << I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT)
+#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_MASK I40E_MASK(0x3, I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT)
#define I40E_PRTPM_EEEC_TEEE_DLY_SHIFT 26
-#define I40E_PRTPM_EEEC_TEEE_DLY_MASK (0x3F << I40E_PRTPM_EEEC_TEEE_DLY_SHIFT)
-#define I40E_PRTPM_EEEFWD 0x001E4400
+#define I40E_PRTPM_EEEC_TEEE_DLY_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TEEE_DLY_SHIFT)
+#define I40E_PRTPM_EEEFWD 0x001E4400 /* Reset: GLOBR */
#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT 31
-#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_MASK (0x1 << I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT)
-#define I40E_PRTPM_EEER 0x001E4360
+#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_MASK I40E_MASK(0x1, I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT)
+#define I40E_PRTPM_EEER 0x001E4360 /* Reset: GLOBR */
#define I40E_PRTPM_EEER_TW_SYSTEM_SHIFT 0
-#define I40E_PRTPM_EEER_TW_SYSTEM_MASK (0xFFFF << I40E_PRTPM_EEER_TW_SYSTEM_SHIFT)
+#define I40E_PRTPM_EEER_TW_SYSTEM_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEER_TW_SYSTEM_SHIFT)
#define I40E_PRTPM_EEER_TX_LPI_EN_SHIFT 16
-#define I40E_PRTPM_EEER_TX_LPI_EN_MASK (0x1 << I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
-#define I40E_PRTPM_EEETXC 0x001E43E0
+#define I40E_PRTPM_EEER_TX_LPI_EN_MASK I40E_MASK(0x1, I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
+#define I40E_PRTPM_EEETXC 0x001E43E0 /* Reset: GLOBR */
#define I40E_PRTPM_EEETXC_TW_PHY_SHIFT 0
-#define I40E_PRTPM_EEETXC_TW_PHY_MASK (0xFFFF << I40E_PRTPM_EEETXC_TW_PHY_SHIFT)
-#define I40E_PRTPM_GC 0x000B8140
+#define I40E_PRTPM_EEETXC_TW_PHY_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEETXC_TW_PHY_SHIFT)
+#define I40E_PRTPM_GC 0x000B8140 /* Reset: POR */
#define I40E_PRTPM_GC_EMP_LINK_ON_SHIFT 0
-#define I40E_PRTPM_GC_EMP_LINK_ON_MASK (0x1 << I40E_PRTPM_GC_EMP_LINK_ON_SHIFT)
+#define I40E_PRTPM_GC_EMP_LINK_ON_MASK I40E_MASK(0x1, I40E_PRTPM_GC_EMP_LINK_ON_SHIFT)
#define I40E_PRTPM_GC_MNG_VETO_SHIFT 1
-#define I40E_PRTPM_GC_MNG_VETO_MASK (0x1 << I40E_PRTPM_GC_MNG_VETO_SHIFT)
+#define I40E_PRTPM_GC_MNG_VETO_MASK I40E_MASK(0x1, I40E_PRTPM_GC_MNG_VETO_SHIFT)
#define I40E_PRTPM_GC_RATD_SHIFT 2
-#define I40E_PRTPM_GC_RATD_MASK (0x1 << I40E_PRTPM_GC_RATD_SHIFT)
+#define I40E_PRTPM_GC_RATD_MASK I40E_MASK(0x1, I40E_PRTPM_GC_RATD_SHIFT)
#define I40E_PRTPM_GC_LCDMP_SHIFT 3
-#define I40E_PRTPM_GC_LCDMP_MASK (0x1 << I40E_PRTPM_GC_LCDMP_SHIFT)
+#define I40E_PRTPM_GC_LCDMP_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LCDMP_SHIFT)
#define I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT 31
-#define I40E_PRTPM_GC_LPLU_ASSERTED_MASK (0x1 << I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT)
-#define I40E_PRTPM_RLPIC 0x001E43A0
+#define I40E_PRTPM_GC_LPLU_ASSERTED_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT)
+#define I40E_PRTPM_RLPIC 0x001E43A0 /* Reset: GLOBR */
#define I40E_PRTPM_RLPIC_ERLPIC_SHIFT 0
-#define I40E_PRTPM_RLPIC_ERLPIC_MASK (0xFFFFFFFF << I40E_PRTPM_RLPIC_ERLPIC_SHIFT)
-#define I40E_PRTPM_TLPIC 0x001E43C0
+#define I40E_PRTPM_RLPIC_ERLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_RLPIC_ERLPIC_SHIFT)
+#define I40E_PRTPM_TLPIC 0x001E43C0 /* Reset: GLOBR */
#define I40E_PRTPM_TLPIC_ETLPIC_SHIFT 0
-#define I40E_PRTPM_TLPIC_ETLPIC_MASK (0xFFFFFFFF << I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
-#define I40E_GLRPB_DPSS 0x000AC828
+#define I40E_PRTPM_TLPIC_ETLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
+#define I40E_GLRPB_DPSS 0x000AC828 /* Reset: CORER */
#define I40E_GLRPB_DPSS_DPS_TCN_SHIFT 0
-#define I40E_GLRPB_DPSS_DPS_TCN_MASK (0xFFFFF << I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
-#define I40E_GLRPB_GHW 0x000AC830
+#define I40E_GLRPB_DPSS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
+#define I40E_GLRPB_GHW 0x000AC830 /* Reset: CORER */
#define I40E_GLRPB_GHW_GHW_SHIFT 0
-#define I40E_GLRPB_GHW_GHW_MASK (0xFFFFF << I40E_GLRPB_GHW_GHW_SHIFT)
-#define I40E_GLRPB_GLW 0x000AC834
+#define I40E_GLRPB_GHW_GHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GHW_GHW_SHIFT)
+#define I40E_GLRPB_GLW 0x000AC834 /* Reset: CORER */
#define I40E_GLRPB_GLW_GLW_SHIFT 0
-#define I40E_GLRPB_GLW_GLW_MASK (0xFFFFF << I40E_GLRPB_GLW_GLW_SHIFT)
-#define I40E_GLRPB_PHW 0x000AC844
+#define I40E_GLRPB_GLW_GLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GLW_GLW_SHIFT)
+#define I40E_GLRPB_PHW 0x000AC844 /* Reset: CORER */
#define I40E_GLRPB_PHW_PHW_SHIFT 0
-#define I40E_GLRPB_PHW_PHW_MASK (0xFFFFF << I40E_GLRPB_PHW_PHW_SHIFT)
-#define I40E_GLRPB_PLW 0x000AC848
+#define I40E_GLRPB_PHW_PHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PHW_PHW_SHIFT)
+#define I40E_GLRPB_PLW 0x000AC848 /* Reset: CORER */
#define I40E_GLRPB_PLW_PLW_SHIFT 0
-#define I40E_GLRPB_PLW_PLW_MASK (0xFFFFF << I40E_GLRPB_PLW_PLW_SHIFT)
-#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_GLRPB_PLW_PLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PLW_PLW_SHIFT)
+#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DHW_MAX_INDEX 7
#define I40E_PRTRPB_DHW_DHW_TCN_SHIFT 0
-#define I40E_PRTRPB_DHW_DHW_TCN_MASK (0xFFFFF << I40E_PRTRPB_DHW_DHW_TCN_SHIFT)
-#define I40E_PRTRPB_DLW(_i) (0x000AC220 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DHW_DHW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DHW_DHW_TCN_SHIFT)
+#define I40E_PRTRPB_DLW(_i) (0x000AC220 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DLW_MAX_INDEX 7
#define I40E_PRTRPB_DLW_DLW_TCN_SHIFT 0
-#define I40E_PRTRPB_DLW_DLW_TCN_MASK (0xFFFFF << I40E_PRTRPB_DLW_DLW_TCN_SHIFT)
-#define I40E_PRTRPB_DPS(_i) (0x000AC320 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DLW_DLW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DLW_DLW_TCN_SHIFT)
+#define I40E_PRTRPB_DPS(_i) (0x000AC320 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DPS_MAX_INDEX 7
#define I40E_PRTRPB_DPS_DPS_TCN_SHIFT 0
-#define I40E_PRTRPB_DPS_DPS_TCN_MASK (0xFFFFF << I40E_PRTRPB_DPS_DPS_TCN_SHIFT)
-#define I40E_PRTRPB_SHT(_i) (0x000AC480 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DPS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DPS_DPS_TCN_SHIFT)
+#define I40E_PRTRPB_SHT(_i) (0x000AC480 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_SHT_MAX_INDEX 7
#define I40E_PRTRPB_SHT_SHT_TCN_SHIFT 0
-#define I40E_PRTRPB_SHT_SHT_TCN_MASK (0xFFFFF << I40E_PRTRPB_SHT_SHT_TCN_SHIFT)
-#define I40E_PRTRPB_SHW 0x000AC580
+#define I40E_PRTRPB_SHT_SHT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHT_SHT_TCN_SHIFT)
+#define I40E_PRTRPB_SHW 0x000AC580 /* Reset: CORER */
#define I40E_PRTRPB_SHW_SHW_SHIFT 0
-#define I40E_PRTRPB_SHW_SHW_MASK (0xFFFFF << I40E_PRTRPB_SHW_SHW_SHIFT)
-#define I40E_PRTRPB_SLT(_i) (0x000AC5A0 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_SHW_SHW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHW_SHW_SHIFT)
+#define I40E_PRTRPB_SLT(_i) (0x000AC5A0 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_SLT_MAX_INDEX 7
#define I40E_PRTRPB_SLT_SLT_TCN_SHIFT 0
-#define I40E_PRTRPB_SLT_SLT_TCN_MASK (0xFFFFF << I40E_PRTRPB_SLT_SLT_TCN_SHIFT)
-#define I40E_PRTRPB_SLW 0x000AC6A0
+#define I40E_PRTRPB_SLT_SLT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLT_SLT_TCN_SHIFT)
+#define I40E_PRTRPB_SLW 0x000AC6A0 /* Reset: CORER */
#define I40E_PRTRPB_SLW_SLW_SHIFT 0
-#define I40E_PRTRPB_SLW_SLW_MASK (0xFFFFF << I40E_PRTRPB_SLW_SLW_SHIFT)
-#define I40E_PRTRPB_SPS 0x000AC7C0
+#define I40E_PRTRPB_SLW_SLW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLW_SLW_SHIFT)
+#define I40E_PRTRPB_SPS 0x000AC7C0 /* Reset: CORER */
#define I40E_PRTRPB_SPS_SPS_SHIFT 0
-#define I40E_PRTRPB_SPS_SPS_MASK (0xFFFFF << I40E_PRTRPB_SPS_SPS_SHIFT)
-#define I40E_GLQF_APBVT(_i) (0x00260000 + ((_i) * 4)) /* _i=0...2047 */
-#define I40E_GLQF_APBVT_MAX_INDEX 2047
-#define I40E_GLQF_APBVT_APBVT_SHIFT 0
-#define I40E_GLQF_APBVT_APBVT_MASK (0xFFFFFFFF << I40E_GLQF_APBVT_APBVT_SHIFT)
-#define I40E_GLQF_CTL 0x00269BA4
+#define I40E_PRTRPB_SPS_SPS_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SPS_SPS_SHIFT)
+#define I40E_GLQF_CTL 0x00269BA4 /* Reset: CORER */
#define I40E_GLQF_CTL_HTOEP_SHIFT 1
-#define I40E_GLQF_CTL_HTOEP_MASK (0x1 << I40E_GLQF_CTL_HTOEP_SHIFT)
+#define I40E_GLQF_CTL_HTOEP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_SHIFT)
#define I40E_GLQF_CTL_HTOEP_FCOE_SHIFT 2
-#define I40E_GLQF_CTL_HTOEP_FCOE_MASK (0x1 << I40E_GLQF_CTL_HTOEP_FCOE_SHIFT)
+#define I40E_GLQF_CTL_HTOEP_FCOE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_FCOE_SHIFT)
#define I40E_GLQF_CTL_PCNT_ALLOC_SHIFT 3
-#define I40E_GLQF_CTL_PCNT_ALLOC_MASK (0x7 << I40E_GLQF_CTL_PCNT_ALLOC_SHIFT)
+#define I40E_GLQF_CTL_PCNT_ALLOC_MASK I40E_MASK(0x7, I40E_GLQF_CTL_PCNT_ALLOC_SHIFT)
+#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT 6
+#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT)
#define I40E_GLQF_CTL_RSVD_SHIFT 7
-#define I40E_GLQF_CTL_RSVD_MASK (0x1 << I40E_GLQF_CTL_RSVD_SHIFT)
+#define I40E_GLQF_CTL_RSVD_MASK I40E_MASK(0x1, I40E_GLQF_CTL_RSVD_SHIFT)
#define I40E_GLQF_CTL_MAXPEBLEN_SHIFT 8
-#define I40E_GLQF_CTL_MAXPEBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXPEBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXPEBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXPEBLEN_SHIFT)
#define I40E_GLQF_CTL_MAXFCBLEN_SHIFT 11
-#define I40E_GLQF_CTL_MAXFCBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXFCBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXFCBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFCBLEN_SHIFT)
#define I40E_GLQF_CTL_MAXFDBLEN_SHIFT 14
-#define I40E_GLQF_CTL_MAXFDBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXFDBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXFDBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFDBLEN_SHIFT)
#define I40E_GLQF_CTL_FDBEST_SHIFT 17
-#define I40E_GLQF_CTL_FDBEST_MASK (0xFF << I40E_GLQF_CTL_FDBEST_SHIFT)
+#define I40E_GLQF_CTL_FDBEST_MASK I40E_MASK(0xFF, I40E_GLQF_CTL_FDBEST_SHIFT)
#define I40E_GLQF_CTL_PROGPRIO_SHIFT 25
-#define I40E_GLQF_CTL_PROGPRIO_MASK (0x1 << I40E_GLQF_CTL_PROGPRIO_SHIFT)
+#define I40E_GLQF_CTL_PROGPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_PROGPRIO_SHIFT)
#define I40E_GLQF_CTL_INVALPRIO_SHIFT 26
-#define I40E_GLQF_CTL_INVALPRIO_MASK (0x1 << I40E_GLQF_CTL_INVALPRIO_SHIFT)
+#define I40E_GLQF_CTL_INVALPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_INVALPRIO_SHIFT)
#define I40E_GLQF_CTL_IGNORE_IP_SHIFT 27
-#define I40E_GLQF_CTL_IGNORE_IP_MASK (0x1 << I40E_GLQF_CTL_IGNORE_IP_SHIFT)
-#define I40E_GLQF_FDCNT_0 0x00269BAC
+#define I40E_GLQF_CTL_IGNORE_IP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_IGNORE_IP_SHIFT)
+#define I40E_GLQF_FDCNT_0 0x00269BAC /* Reset: CORER */
#define I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT 0
-#define I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK (0x1FFF << I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT)
+#define I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT)
#define I40E_GLQF_FDCNT_0_BESTCNT_SHIFT 13
-#define I40E_GLQF_FDCNT_0_BESTCNT_MASK (0x1FFF << I40E_GLQF_FDCNT_0_BESTCNT_SHIFT)
-#define I40E_GLQF_HSYM(_i) (0x00269D00 + ((_i) * 4)) /* _i=0...63 */
+#define I40E_GLQF_FDCNT_0_BESTCNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_BESTCNT_SHIFT)
+#define I40E_GLQF_HKEY(_i) (0x00270140 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
+#define I40E_GLQF_HKEY_MAX_INDEX 12
+#define I40E_GLQF_HKEY_KEY_0_SHIFT 0
+#define I40E_GLQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_0_SHIFT)
+#define I40E_GLQF_HKEY_KEY_1_SHIFT 8
+#define I40E_GLQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_1_SHIFT)
+#define I40E_GLQF_HKEY_KEY_2_SHIFT 16
+#define I40E_GLQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_2_SHIFT)
+#define I40E_GLQF_HKEY_KEY_3_SHIFT 24
+#define I40E_GLQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_3_SHIFT)
+#define I40E_GLQF_HSYM(_i) (0x00269D00 + ((_i) * 4)) /* _i=0...63 */ /* Reset: CORER */
#define I40E_GLQF_HSYM_MAX_INDEX 63
#define I40E_GLQF_HSYM_SYMH_ENA_SHIFT 0
-#define I40E_GLQF_HSYM_SYMH_ENA_MASK (0x1 << I40E_GLQF_HSYM_SYMH_ENA_SHIFT)
-#define I40E_GLQF_PCNT(_i) (0x00266800 + ((_i) * 4)) /* _i=0...511 */
+#define I40E_GLQF_HSYM_SYMH_ENA_MASK I40E_MASK(0x1, I40E_GLQF_HSYM_SYMH_ENA_SHIFT)
+#define I40E_GLQF_PCNT(_i) (0x00266800 + ((_i) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_GLQF_PCNT_MAX_INDEX 511
#define I40E_GLQF_PCNT_PCNT_SHIFT 0
-#define I40E_GLQF_PCNT_PCNT_MASK (0xFFFFFFFF << I40E_GLQF_PCNT_PCNT_SHIFT)
-#define I40E_GLQF_SWAP(_i, _j) (0x00267E00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */
+#define I40E_GLQF_PCNT_PCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_PCNT_PCNT_SHIFT)
+#define I40E_GLQF_SWAP(_i, _j) (0x00267E00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
#define I40E_GLQF_SWAP_MAX_INDEX 1
#define I40E_GLQF_SWAP_OFF0_SRC0_SHIFT 0
-#define I40E_GLQF_SWAP_OFF0_SRC0_MASK (0x3F << I40E_GLQF_SWAP_OFF0_SRC0_SHIFT)
+#define I40E_GLQF_SWAP_OFF0_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC0_SHIFT)
#define I40E_GLQF_SWAP_OFF0_SRC1_SHIFT 6
-#define I40E_GLQF_SWAP_OFF0_SRC1_MASK (0x3F << I40E_GLQF_SWAP_OFF0_SRC1_SHIFT)
+#define I40E_GLQF_SWAP_OFF0_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC1_SHIFT)
#define I40E_GLQF_SWAP_FLEN0_SHIFT 12
-#define I40E_GLQF_SWAP_FLEN0_MASK (0xF << I40E_GLQF_SWAP_FLEN0_SHIFT)
+#define I40E_GLQF_SWAP_FLEN0_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN0_SHIFT)
#define I40E_GLQF_SWAP_OFF1_SRC0_SHIFT 16
-#define I40E_GLQF_SWAP_OFF1_SRC0_MASK (0x3F << I40E_GLQF_SWAP_OFF1_SRC0_SHIFT)
+#define I40E_GLQF_SWAP_OFF1_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC0_SHIFT)
#define I40E_GLQF_SWAP_OFF1_SRC1_SHIFT 22
-#define I40E_GLQF_SWAP_OFF1_SRC1_MASK (0x3F << I40E_GLQF_SWAP_OFF1_SRC1_SHIFT)
+#define I40E_GLQF_SWAP_OFF1_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC1_SHIFT)
#define I40E_GLQF_SWAP_FLEN1_SHIFT 28
-#define I40E_GLQF_SWAP_FLEN1_MASK (0xF << I40E_GLQF_SWAP_FLEN1_SHIFT)
-#define I40E_PFQF_CTL_0 0x001C0AC0
+#define I40E_GLQF_SWAP_FLEN1_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN1_SHIFT)
+#define I40E_PFQF_CTL_0 0x001C0AC0 /* Reset: CORER */
#define I40E_PFQF_CTL_0_PEHSIZE_SHIFT 0
-#define I40E_PFQF_CTL_0_PEHSIZE_MASK (0x1F << I40E_PFQF_CTL_0_PEHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PEHSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_0_PEHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PEDSIZE_SHIFT 5
-#define I40E_PFQF_CTL_0_PEDSIZE_MASK (0x1F << I40E_PFQF_CTL_0_PEDSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PEDSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_0_PEDSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT 10
-#define I40E_PFQF_CTL_0_PFFCHSIZE_MASK (0xF << I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PFFCHSIZE_MASK I40E_MASK(0xF, I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT 14
-#define I40E_PFQF_CTL_0_PFFCDSIZE_MASK (0x3 << I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PFFCDSIZE_MASK I40E_MASK(0x3, I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT)
#define I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT 16
-#define I40E_PFQF_CTL_0_HASHLUTSIZE_MASK (0x1 << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_HASHLUTSIZE_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT)
#define I40E_PFQF_CTL_0_FD_ENA_SHIFT 17
-#define I40E_PFQF_CTL_0_FD_ENA_MASK (0x1 << I40E_PFQF_CTL_0_FD_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_FD_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_FD_ENA_SHIFT)
#define I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT 18
-#define I40E_PFQF_CTL_0_ETYPE_ENA_MASK (0x1 << I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_ETYPE_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT)
#define I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT 19
-#define I40E_PFQF_CTL_0_MACVLAN_ENA_MASK (0x1 << I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_MACVLAN_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT)
#define I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT 20
-#define I40E_PFQF_CTL_0_VFFCHSIZE_MASK (0xF << I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_VFFCHSIZE_MASK I40E_MASK(0xF, I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT 24
-#define I40E_PFQF_CTL_0_VFFCDSIZE_MASK (0x3 << I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT)
-#define I40E_PFQF_CTL_1 0x00245D80
+#define I40E_PFQF_CTL_0_VFFCDSIZE_MASK I40E_MASK(0x3, I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT)
+#define I40E_PFQF_CTL_1 0x00245D80 /* Reset: CORER */
#define I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT 0
-#define I40E_PFQF_CTL_1_CLEARFDTABLE_MASK (0x1 << I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT)
-#define I40E_PFQF_FDALLOC 0x00246280
+#define I40E_PFQF_CTL_1_CLEARFDTABLE_MASK I40E_MASK(0x1, I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT)
+#define I40E_PFQF_FDALLOC 0x00246280 /* Reset: CORER */
#define I40E_PFQF_FDALLOC_FDALLOC_SHIFT 0
-#define I40E_PFQF_FDALLOC_FDALLOC_MASK (0xFF << I40E_PFQF_FDALLOC_FDALLOC_SHIFT)
+#define I40E_PFQF_FDALLOC_FDALLOC_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDALLOC_SHIFT)
#define I40E_PFQF_FDALLOC_FDBEST_SHIFT 8
-#define I40E_PFQF_FDALLOC_FDBEST_MASK (0xFF << I40E_PFQF_FDALLOC_FDBEST_SHIFT)
-#define I40E_PFQF_FDSTAT 0x00246380
+#define I40E_PFQF_FDALLOC_FDBEST_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDBEST_SHIFT)
+#define I40E_PFQF_FDSTAT 0x00246380 /* Reset: CORER */
#define I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT 0
-#define I40E_PFQF_FDSTAT_GUARANT_CNT_MASK (0x1FFF << I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT)
+#define I40E_PFQF_FDSTAT_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT)
#define I40E_PFQF_FDSTAT_BEST_CNT_SHIFT 16
-#define I40E_PFQF_FDSTAT_BEST_CNT_MASK (0x1FFF << I40E_PFQF_FDSTAT_BEST_CNT_SHIFT)
-#define I40E_PFQF_HENA(_i) (0x00245900 + ((_i) * 128)) /* _i=0...1 */
+#define I40E_PFQF_FDSTAT_BEST_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_BEST_CNT_SHIFT)
+#define I40E_PFQF_HENA(_i) (0x00245900 + ((_i) * 128)) /* _i=0...1 */ /* Reset: CORER */
#define I40E_PFQF_HENA_MAX_INDEX 1
#define I40E_PFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_PFQF_HENA_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_PFQF_HENA_PTYPE_ENA_SHIFT)
-#define I40E_PFQF_HKEY(_i) (0x00244800 + ((_i) * 128)) /* _i=0...12 */
+#define I40E_PFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFQF_HENA_PTYPE_ENA_SHIFT)
+#define I40E_PFQF_HKEY(_i) (0x00244800 + ((_i) * 128)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_PFQF_HKEY_MAX_INDEX 12
#define I40E_PFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_PFQF_HKEY_KEY_0_MASK (0xFF << I40E_PFQF_HKEY_KEY_0_SHIFT)
+#define I40E_PFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_0_SHIFT)
#define I40E_PFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_PFQF_HKEY_KEY_1_MASK (0xFF << I40E_PFQF_HKEY_KEY_1_SHIFT)
+#define I40E_PFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_1_SHIFT)
#define I40E_PFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_PFQF_HKEY_KEY_2_MASK (0xFF << I40E_PFQF_HKEY_KEY_2_SHIFT)
+#define I40E_PFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_2_SHIFT)
#define I40E_PFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_PFQF_HKEY_KEY_3_MASK (0xFF << I40E_PFQF_HKEY_KEY_3_SHIFT)
-#define I40E_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */
+#define I40E_PFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_3_SHIFT)
+#define I40E_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_PFQF_HLUT_MAX_INDEX 127
#define I40E_PFQF_HLUT_LUT0_SHIFT 0
-#define I40E_PFQF_HLUT_LUT0_MASK (0x3F << I40E_PFQF_HLUT_LUT0_SHIFT)
+#define I40E_PFQF_HLUT_LUT0_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT0_SHIFT)
#define I40E_PFQF_HLUT_LUT1_SHIFT 8
-#define I40E_PFQF_HLUT_LUT1_MASK (0x3F << I40E_PFQF_HLUT_LUT1_SHIFT)
+#define I40E_PFQF_HLUT_LUT1_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT1_SHIFT)
#define I40E_PFQF_HLUT_LUT2_SHIFT 16
-#define I40E_PFQF_HLUT_LUT2_MASK (0x3F << I40E_PFQF_HLUT_LUT2_SHIFT)
+#define I40E_PFQF_HLUT_LUT2_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT2_SHIFT)
#define I40E_PFQF_HLUT_LUT3_SHIFT 24
-#define I40E_PFQF_HLUT_LUT3_MASK (0x3F << I40E_PFQF_HLUT_LUT3_SHIFT)
-#define I40E_PFQF_HREGION(_i) (0x00245400 + ((_i) * 128)) /* _i=0...7 */
-#define I40E_PFQF_HREGION_MAX_INDEX 7
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
-#define I40E_PFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_PFQF_HREGION_REGION_0_MASK (0x7 << I40E_PFQF_HREGION_REGION_0_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
-#define I40E_PFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_PFQF_HREGION_REGION_1_MASK (0x7 << I40E_PFQF_HREGION_REGION_1_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
-#define I40E_PFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_PFQF_HREGION_REGION_2_MASK (0x7 << I40E_PFQF_HREGION_REGION_2_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
-#define I40E_PFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_PFQF_HREGION_REGION_3_MASK (0x7 << I40E_PFQF_HREGION_REGION_3_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
-#define I40E_PFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_PFQF_HREGION_REGION_4_MASK (0x7 << I40E_PFQF_HREGION_REGION_4_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
-#define I40E_PFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_PFQF_HREGION_REGION_5_MASK (0x7 << I40E_PFQF_HREGION_REGION_5_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
-#define I40E_PFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_PFQF_HREGION_REGION_6_MASK (0x7 << I40E_PFQF_HREGION_REGION_6_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
-#define I40E_PFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_PFQF_HREGION_REGION_7_MASK (0x7 << I40E_PFQF_HREGION_REGION_7_SHIFT)
-#define I40E_PRTQF_CTL_0 0x00256E60
+#define I40E_PFQF_HLUT_LUT3_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT3_SHIFT)
+#define I40E_PRTQF_CTL_0 0x00256E60 /* Reset: CORER */
#define I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT 0
-#define I40E_PRTQF_CTL_0_HSYM_ENA_MASK (0x1 << I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT)
-#define I40E_PRTQF_FD_FLXINSET(_i) (0x00253800 + ((_i) * 32)) /* _i=0...63 */
+#define I40E_PRTQF_CTL_0_HSYM_ENA_MASK I40E_MASK(0x1, I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT)
+#define I40E_PRTQF_FD_FLXINSET(_i) (0x00253800 + ((_i) * 32)) /* _i=0...63 */ /* Reset: CORER */
#define I40E_PRTQF_FD_FLXINSET_MAX_INDEX 63
#define I40E_PRTQF_FD_FLXINSET_INSET_SHIFT 0
-#define I40E_PRTQF_FD_FLXINSET_INSET_MASK (0xFF << I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
-#define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */
+#define I40E_PRTQF_FD_FLXINSET_INSET_MASK I40E_MASK(0xFF, I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
+#define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
#define I40E_PRTQF_FD_MSK_MAX_INDEX 63
#define I40E_PRTQF_FD_MSK_MASK_SHIFT 0
-#define I40E_PRTQF_FD_MSK_MASK_MASK (0xFFFF << I40E_PRTQF_FD_MSK_MASK_SHIFT)
+#define I40E_PRTQF_FD_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRTQF_FD_MSK_MASK_SHIFT)
#define I40E_PRTQF_FD_MSK_OFFSET_SHIFT 16
-#define I40E_PRTQF_FD_MSK_OFFSET_MASK (0x3F << I40E_PRTQF_FD_MSK_OFFSET_SHIFT)
-#define I40E_PRTQF_FLX_PIT(_i) (0x00255200 + ((_i) * 32)) /* _i=0...8 */
+#define I40E_PRTQF_FD_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_PRTQF_FD_MSK_OFFSET_SHIFT)
+#define I40E_PRTQF_FLX_PIT(_i) (0x00255200 + ((_i) * 32)) /* _i=0...8 */ /* Reset: CORER */
#define I40E_PRTQF_FLX_PIT_MAX_INDEX 8
#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT 0
-#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK (0x1F << I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
+#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK I40E_MASK(0x1F, I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
#define I40E_PRTQF_FLX_PIT_FSIZE_SHIFT 5
-#define I40E_PRTQF_FLX_PIT_FSIZE_MASK (0x1F << I40E_PRTQF_FLX_PIT_FSIZE_SHIFT)
+#define I40E_PRTQF_FLX_PIT_FSIZE_MASK I40E_MASK(0x1F, I40E_PRTQF_FLX_PIT_FSIZE_SHIFT)
#define I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT 10
-#define I40E_PRTQF_FLX_PIT_DEST_OFF_MASK (0x3F << I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
-#define I40E_VFQF_HENA1(_i, _VF) (0x00230800 + ((_i) * 1024 + (_VF) * 4))
+#define I40E_PRTQF_FLX_PIT_DEST_OFF_MASK I40E_MASK(0x3F, I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
+#define I40E_VFQF_HENA1(_i, _VF) (0x00230800 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...1, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HENA1_MAX_INDEX 1
#define I40E_VFQF_HENA1_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA1_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_VFQF_HENA1_PTYPE_ENA_SHIFT)
-#define I40E_VFQF_HKEY1(_i, _VF) (0x00228000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...12, _VF=0...127 */
+#define I40E_VFQF_HENA1_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA1_PTYPE_ENA_SHIFT)
+#define I40E_VFQF_HKEY1(_i, _VF) (0x00228000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...12, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HKEY1_MAX_INDEX 12
#define I40E_VFQF_HKEY1_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY1_KEY_0_MASK (0xFF << I40E_VFQF_HKEY1_KEY_0_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_0_SHIFT)
#define I40E_VFQF_HKEY1_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY1_KEY_1_MASK (0xFF << I40E_VFQF_HKEY1_KEY_1_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_1_SHIFT)
#define I40E_VFQF_HKEY1_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY1_KEY_2_MASK (0xFF << I40E_VFQF_HKEY1_KEY_2_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_2_SHIFT)
#define I40E_VFQF_HKEY1_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY1_KEY_3_MASK (0xFF << I40E_VFQF_HKEY1_KEY_3_SHIFT)
-#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */
+#define I40E_VFQF_HKEY1_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_3_SHIFT)
+#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HLUT1_MAX_INDEX 15
#define I40E_VFQF_HLUT1_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT1_LUT0_MASK (0xF << I40E_VFQF_HLUT1_LUT0_SHIFT)
+#define I40E_VFQF_HLUT1_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT0_SHIFT)
#define I40E_VFQF_HLUT1_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT1_LUT1_MASK (0xF << I40E_VFQF_HLUT1_LUT1_SHIFT)
+#define I40E_VFQF_HLUT1_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT1_SHIFT)
#define I40E_VFQF_HLUT1_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT1_LUT2_MASK (0xF << I40E_VFQF_HLUT1_LUT2_SHIFT)
+#define I40E_VFQF_HLUT1_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT2_SHIFT)
#define I40E_VFQF_HLUT1_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT1_LUT3_MASK (0xF << I40E_VFQF_HLUT1_LUT3_SHIFT)
-#define I40E_VFQF_HREGION1(_i, _VF) (0x0022E000 + ((_i) * 1024 + (_VF) * 4))
+#define I40E_VFQF_HLUT1_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT3_SHIFT)
+#define I40E_VFQF_HREGION1(_i, _VF) (0x0022E000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...7, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HREGION1_MAX_INDEX 7
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT)
#define I40E_VFQF_HREGION1_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION1_REGION_0_MASK (0x7 << I40E_VFQF_HREGION1_REGION_0_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_0_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT)
#define I40E_VFQF_HREGION1_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION1_REGION_1_MASK (0x7 << I40E_VFQF_HREGION1_REGION_1_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_1_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT)
#define I40E_VFQF_HREGION1_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION1_REGION_2_MASK (0x7 << I40E_VFQF_HREGION1_REGION_2_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_2_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT)
#define I40E_VFQF_HREGION1_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION1_REGION_3_MASK (0x7 << I40E_VFQF_HREGION1_REGION_3_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_3_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT)
#define I40E_VFQF_HREGION1_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION1_REGION_4_MASK (0x7 << I40E_VFQF_HREGION1_REGION_4_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_4_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT)
#define I40E_VFQF_HREGION1_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION1_REGION_5_MASK (0x7 << I40E_VFQF_HREGION1_REGION_5_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_5_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT)
#define I40E_VFQF_HREGION1_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION1_REGION_6_MASK (0x7 << I40E_VFQF_HREGION1_REGION_6_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_6_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT)
#define I40E_VFQF_HREGION1_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION1_REGION_7_MASK (0x7 << I40E_VFQF_HREGION1_REGION_7_SHIFT)
-#define I40E_VPQF_CTL(_VF) (0x001C0000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFQF_HREGION1_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_7_SHIFT)
+#define I40E_VPQF_CTL(_VF) (0x001C0000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPQF_CTL_MAX_INDEX 127
#define I40E_VPQF_CTL_PEHSIZE_SHIFT 0
-#define I40E_VPQF_CTL_PEHSIZE_MASK (0x1F << I40E_VPQF_CTL_PEHSIZE_SHIFT)
+#define I40E_VPQF_CTL_PEHSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEHSIZE_SHIFT)
#define I40E_VPQF_CTL_PEDSIZE_SHIFT 5
-#define I40E_VPQF_CTL_PEDSIZE_MASK (0x1F << I40E_VPQF_CTL_PEDSIZE_SHIFT)
+#define I40E_VPQF_CTL_PEDSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEDSIZE_SHIFT)
#define I40E_VPQF_CTL_FCHSIZE_SHIFT 10
-#define I40E_VPQF_CTL_FCHSIZE_MASK (0xF << I40E_VPQF_CTL_FCHSIZE_SHIFT)
+#define I40E_VPQF_CTL_FCHSIZE_MASK I40E_MASK(0xF, I40E_VPQF_CTL_FCHSIZE_SHIFT)
#define I40E_VPQF_CTL_FCDSIZE_SHIFT 14
-#define I40E_VPQF_CTL_FCDSIZE_MASK (0x3 << I40E_VPQF_CTL_FCDSIZE_SHIFT)
-#define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPQF_CTL_FCDSIZE_MASK I40E_MASK(0x3, I40E_VPQF_CTL_FCDSIZE_SHIFT)
+#define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
#define I40E_VSIQF_CTL_MAX_INDEX 383
#define I40E_VSIQF_CTL_FCOE_ENA_SHIFT 0
-#define I40E_VSIQF_CTL_FCOE_ENA_MASK (0x1 << I40E_VSIQF_CTL_FCOE_ENA_SHIFT)
+#define I40E_VSIQF_CTL_FCOE_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_FCOE_ENA_SHIFT)
#define I40E_VSIQF_CTL_PETCP_ENA_SHIFT 1
-#define I40E_VSIQF_CTL_PETCP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PETCP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PETCP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PETCP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT 2
-#define I40E_VSIQF_CTL_PEUUDP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEUUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT 3
-#define I40E_VSIQF_CTL_PEMUDP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEMUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT 4
-#define I40E_VSIQF_CTL_PEUFRAG_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEUFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT 5
-#define I40E_VSIQF_CTL_PEMFRAG_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT)
-#define I40E_VSIQF_TCREGION(_i, _VSI) (0x00206000 + ((_i) * 2048 + (_VSI) * 4))
+#define I40E_VSIQF_CTL_PEMFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT)
+#define I40E_VSIQF_TCREGION(_i, _VSI) (0x00206000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...3, _VSI=0...383 */ /* Reset: PFR */
#define I40E_VSIQF_TCREGION_MAX_INDEX 3
#define I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT 0
-#define I40E_VSIQF_TCREGION_TC_OFFSET_MASK (0x1FF << I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_OFFSET_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT)
#define I40E_VSIQF_TCREGION_TC_SIZE_SHIFT 9
-#define I40E_VSIQF_TCREGION_TC_SIZE_MASK (0x7 << I40E_VSIQF_TCREGION_TC_SIZE_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_SIZE_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE_SHIFT)
#define I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT 16
-#define I40E_VSIQF_TCREGION_TC_OFFSET2_MASK (0x1FF << I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_OFFSET2_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT)
#define I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT 25
-#define I40E_VSIQF_TCREGION_TC_SIZE2_MASK (0x7 << I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT)
-#define I40E_GL_FCOECRC(_i) (0x00314d80 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_VSIQF_TCREGION_TC_SIZE2_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT)
+#define I40E_GL_FCOECRC(_i) (0x00314d80 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOECRC_MAX_INDEX 143
#define I40E_GL_FCOECRC_FCOECRC_SHIFT 0
-#define I40E_GL_FCOECRC_FCOECRC_MASK (0xFFFFFFFF << I40E_GL_FCOECRC_FCOECRC_SHIFT)
-#define I40E_GL_FCOEDDPC(_i) (0x00314480 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOECRC_FCOECRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOECRC_FCOECRC_SHIFT)
+#define I40E_GL_FCOEDDPC(_i) (0x00314480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDDPC_MAX_INDEX 143
#define I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT 0
-#define I40E_GL_FCOEDDPC_FCOEDDPC_MASK (0xFFFFFFFF << I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT)
-/* _i=0...143 */
-#define I40E_GL_FCOEDIFEC(_i) (0x00318480 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDDPC_FCOEDDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT)
+#define I40E_GL_FCOEDIFEC(_i) (0x00318480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIFEC_MAX_INDEX 143
#define I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT 0
-#define I40E_GL_FCOEDIFEC_FCOEDIFRC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT)
-#define I40E_GL_FCOEDIFRC(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */
-#define I40E_GL_FCOEDIFRC_MAX_INDEX 143
-#define I40E_GL_FCOEDIFRC_FCOEDIFRC_SHIFT 0
-#define I40E_GL_FCOEDIFRC_FCOEDIFRC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFRC_FCOEDIFRC_SHIFT)
-#define I40E_GL_FCOEDIFTCL(_i) (0x00354000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIFEC_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT)
+#define I40E_GL_FCOEDIFTCL(_i) (0x00354000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIFTCL_MAX_INDEX 143
#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT 0
-#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT)
-#define I40E_GL_FCOEDIXAC(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */
-#define I40E_GL_FCOEDIXAC_MAX_INDEX 143
-#define I40E_GL_FCOEDIXAC_FCOEDIXAC_SHIFT 0
-#define I40E_GL_FCOEDIXAC_FCOEDIXAC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXAC_FCOEDIXAC_SHIFT)
-#define I40E_GL_FCOEDIXEC(_i) (0x0034c000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT)
+#define I40E_GL_FCOEDIXEC(_i) (0x0034c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIXEC_MAX_INDEX 143
#define I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT 0
-#define I40E_GL_FCOEDIXEC_FCOEDIXEC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT)
-#define I40E_GL_FCOEDIXVC(_i) (0x00350000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIXEC_FCOEDIXEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT)
+#define I40E_GL_FCOEDIXVC(_i) (0x00350000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIXVC_MAX_INDEX 143
#define I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT 0
-#define I40E_GL_FCOEDIXVC_FCOEDIXVC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT)
-#define I40E_GL_FCOEDWRCH(_i) (0x00320004 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIXVC_FCOEDIXVC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT)
+#define I40E_GL_FCOEDWRCH(_i) (0x00320004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWRCH_MAX_INDEX 143
#define I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT 0
-#define I40E_GL_FCOEDWRCH_FCOEDWRCH_MASK (0xFFFF << I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT)
-#define I40E_GL_FCOEDWRCL(_i) (0x00320000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWRCH_FCOEDWRCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT)
+#define I40E_GL_FCOEDWRCL(_i) (0x00320000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWRCL_MAX_INDEX 143
#define I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT 0
-#define I40E_GL_FCOEDWRCL_FCOEDWRCL_MASK (0xFFFFFFFF << I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT)
-#define I40E_GL_FCOEDWTCH(_i) (0x00348084 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWRCL_FCOEDWRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT)
+#define I40E_GL_FCOEDWTCH(_i) (0x00348084 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWTCH_MAX_INDEX 143
#define I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT 0
-#define I40E_GL_FCOEDWTCH_FCOEDWTCH_MASK (0xFFFF << I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT)
-#define I40E_GL_FCOEDWTCL(_i) (0x00348080 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWTCH_FCOEDWTCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT)
+#define I40E_GL_FCOEDWTCL(_i) (0x00348080 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWTCL_MAX_INDEX 143
#define I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT 0
-#define I40E_GL_FCOEDWTCL_FCOEDWTCL_MASK (0xFFFFFFFF << I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT)
-#define I40E_GL_FCOELAST(_i) (0x00314000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWTCL_FCOEDWTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT)
+#define I40E_GL_FCOELAST(_i) (0x00314000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOELAST_MAX_INDEX 143
#define I40E_GL_FCOELAST_FCOELAST_SHIFT 0
-#define I40E_GL_FCOELAST_FCOELAST_MASK (0xFFFFFFFF << I40E_GL_FCOELAST_FCOELAST_SHIFT)
-#define I40E_GL_FCOEPRC(_i) (0x00315200 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOELAST_FCOELAST_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOELAST_FCOELAST_SHIFT)
+#define I40E_GL_FCOEPRC(_i) (0x00315200 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEPRC_MAX_INDEX 143
#define I40E_GL_FCOEPRC_FCOEPRC_SHIFT 0
-#define I40E_GL_FCOEPRC_FCOEPRC_MASK (0xFFFFFFFF << I40E_GL_FCOEPRC_FCOEPRC_SHIFT)
-#define I40E_GL_FCOEPTC(_i) (0x00344C00 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEPRC_FCOEPRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPRC_FCOEPRC_SHIFT)
+#define I40E_GL_FCOEPTC(_i) (0x00344C00 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEPTC_MAX_INDEX 143
#define I40E_GL_FCOEPTC_FCOEPTC_SHIFT 0
-#define I40E_GL_FCOEPTC_FCOEPTC_MASK (0xFFFFFFFF << I40E_GL_FCOEPTC_FCOEPTC_SHIFT)
-#define I40E_GL_FCOERPDC(_i) (0x00324000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEPTC_FCOEPTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPTC_FCOEPTC_SHIFT)
+#define I40E_GL_FCOERPDC(_i) (0x00324000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOERPDC_MAX_INDEX 143
#define I40E_GL_FCOERPDC_FCOERPDC_SHIFT 0
-#define I40E_GL_FCOERPDC_FCOERPDC_MASK (0xFFFFFFFF << I40E_GL_FCOERPDC_FCOERPDC_SHIFT)
-#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GL_FCOERPDC_FCOERPDC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOERPDC_FCOERPDC_SHIFT)
+#define I40E_GL_RXERR1_L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1_L_MAX_INDEX 143
+#define I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT 0
+#define I40E_GL_RXERR1_L_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT)
+#define I40E_GL_RXERR2_L(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR2_L_MAX_INDEX 143
+#define I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT 0
+#define I40E_GL_RXERR2_L_FCOEDIXAC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT)
+#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPRCH_MAX_INDEX 3
#define I40E_GLPRT_BPRCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPRCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_BPRCH_UPRCH_SHIFT)
-#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPRCH_UPRCH_SHIFT)
+#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPRCL_MAX_INDEX 3
#define I40E_GLPRT_BPRCL_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPRCL_UPRCH_MASK (0xFFFFFFFF << I40E_GLPRT_BPRCL_UPRCH_SHIFT)
-#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPRCL_UPRCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPRCL_UPRCH_SHIFT)
+#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPTCH_MAX_INDEX 3
#define I40E_GLPRT_BPTCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPTCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_BPTCH_UPRCH_SHIFT)
-#define I40E_GLPRT_BPTCL(_i) (0x00300A00 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPTCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPTCH_UPRCH_SHIFT)
+#define I40E_GLPRT_BPTCL(_i) (0x00300A00 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPTCL_MAX_INDEX 3
#define I40E_GLPRT_BPTCL_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPTCL_UPRCH_MASK (0xFFFFFFFF << I40E_GLPRT_BPTCL_UPRCH_SHIFT)
-#define I40E_GLPRT_CRCERRS(_i) (0x00300080 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPTCL_UPRCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPTCL_UPRCH_SHIFT)
+#define I40E_GLPRT_CRCERRS(_i) (0x00300080 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_CRCERRS_MAX_INDEX 3
#define I40E_GLPRT_CRCERRS_CRCERRS_SHIFT 0
-#define I40E_GLPRT_CRCERRS_CRCERRS_MASK (0xFFFFFFFF << I40E_GLPRT_CRCERRS_CRCERRS_SHIFT)
-#define I40E_GLPRT_GORCH(_i) (0x00300004 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_CRCERRS_CRCERRS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_CRCERRS_CRCERRS_SHIFT)
+#define I40E_GLPRT_GORCH(_i) (0x00300004 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GORCH_MAX_INDEX 3
#define I40E_GLPRT_GORCH_GORCH_SHIFT 0
-#define I40E_GLPRT_GORCH_GORCH_MASK (0xFFFF << I40E_GLPRT_GORCH_GORCH_SHIFT)
-#define I40E_GLPRT_GORCL(_i) (0x00300000 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GORCH_GORCH_SHIFT)
+#define I40E_GLPRT_GORCL(_i) (0x00300000 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GORCL_MAX_INDEX 3
#define I40E_GLPRT_GORCL_GORCL_SHIFT 0
-#define I40E_GLPRT_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLPRT_GORCL_GORCL_SHIFT)
-#define I40E_GLPRT_GOTCH(_i) (0x00300684 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GORCL_GORCL_SHIFT)
+#define I40E_GLPRT_GOTCH(_i) (0x00300684 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GOTCH_MAX_INDEX 3
#define I40E_GLPRT_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLPRT_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLPRT_GOTCH_GOTCH_SHIFT)
-#define I40E_GLPRT_GOTCL(_i) (0x00300680 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GOTCH_GOTCH_SHIFT)
+#define I40E_GLPRT_GOTCL(_i) (0x00300680 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GOTCL_MAX_INDEX 3
#define I40E_GLPRT_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLPRT_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLPRT_GOTCL_GOTCL_SHIFT)
-#define I40E_GLPRT_ILLERRC(_i) (0x003000E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GOTCL_GOTCL_SHIFT)
+#define I40E_GLPRT_ILLERRC(_i) (0x003000E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_ILLERRC_MAX_INDEX 3
#define I40E_GLPRT_ILLERRC_ILLERRC_SHIFT 0
-#define I40E_GLPRT_ILLERRC_ILLERRC_MASK (0xFFFFFFFF << I40E_GLPRT_ILLERRC_ILLERRC_SHIFT)
-#define I40E_GLPRT_LDPC(_i) (0x00300620 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_ILLERRC_ILLERRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ILLERRC_ILLERRC_SHIFT)
+#define I40E_GLPRT_LDPC(_i) (0x00300620 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LDPC_MAX_INDEX 3
#define I40E_GLPRT_LDPC_LDPC_SHIFT 0
-#define I40E_GLPRT_LDPC_LDPC_MASK (0xFFFFFFFF << I40E_GLPRT_LDPC_LDPC_SHIFT)
-#define I40E_GLPRT_LXOFFRXC(_i) (0x00300160 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LDPC_LDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LDPC_LDPC_SHIFT)
+#define I40E_GLPRT_LXOFFRXC(_i) (0x00300160 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXOFFRXC_MAX_INDEX 3
#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT)
-#define I40E_GLPRT_LXOFFTXC(_i) (0x003009A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT)
+#define I40E_GLPRT_LXOFFTXC(_i) (0x003009A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXOFFTXC_MAX_INDEX 3
#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT 0
-#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_MASK (0xFFFFFFFF << I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT)
-#define I40E_GLPRT_LXONRXC(_i) (0x00300140 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT)
+#define I40E_GLPRT_LXONRXC(_i) (0x00300140 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXONRXC_MAX_INDEX 3
#define I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT 0
-#define I40E_GLPRT_LXONRXC_LXONRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT)
-#define I40E_GLPRT_LXONTXC(_i) (0x00300980 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXONRXC_LXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT)
+#define I40E_GLPRT_LXONTXC(_i) (0x00300980 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXONTXC_MAX_INDEX 3
#define I40E_GLPRT_LXONTXC_LXONTXC_SHIFT 0
-#define I40E_GLPRT_LXONTXC_LXONTXC_MASK (0xFFFFFFFF << I40E_GLPRT_LXONTXC_LXONTXC_SHIFT)
-#define I40E_GLPRT_MLFC(_i) (0x00300020 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXONTXC_LXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONTXC_LXONTXC_SHIFT)
+#define I40E_GLPRT_MLFC(_i) (0x00300020 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MLFC_MAX_INDEX 3
#define I40E_GLPRT_MLFC_MLFC_SHIFT 0
-#define I40E_GLPRT_MLFC_MLFC_MASK (0xFFFFFFFF << I40E_GLPRT_MLFC_MLFC_SHIFT)
-#define I40E_GLPRT_MPRCH(_i) (0x003005C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MLFC_MLFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MLFC_MLFC_SHIFT)
+#define I40E_GLPRT_MPRCH(_i) (0x003005C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPRCH_MAX_INDEX 3
#define I40E_GLPRT_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLPRT_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLPRT_MPRCH_MPRCH_SHIFT)
-#define I40E_GLPRT_MPRCL(_i) (0x003005C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPRCH_MPRCH_SHIFT)
+#define I40E_GLPRT_MPRCL(_i) (0x003005C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPRCL_MAX_INDEX 3
#define I40E_GLPRT_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLPRT_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLPRT_MPRCL_MPRCL_SHIFT)
-#define I40E_GLPRT_MPTCH(_i) (0x003009E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPRCL_MPRCL_SHIFT)
+#define I40E_GLPRT_MPTCH(_i) (0x003009E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPTCH_MAX_INDEX 3
#define I40E_GLPRT_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLPRT_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLPRT_MPTCH_MPTCH_SHIFT)
-#define I40E_GLPRT_MPTCL(_i) (0x003009E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPTCH_MPTCH_SHIFT)
+#define I40E_GLPRT_MPTCL(_i) (0x003009E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPTCL_MAX_INDEX 3
#define I40E_GLPRT_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLPRT_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLPRT_MPTCL_MPTCL_SHIFT)
-#define I40E_GLPRT_MRFC(_i) (0x00300040 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPTCL_MPTCL_SHIFT)
+#define I40E_GLPRT_MRFC(_i) (0x00300040 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MRFC_MAX_INDEX 3
#define I40E_GLPRT_MRFC_MRFC_SHIFT 0
-#define I40E_GLPRT_MRFC_MRFC_MASK (0xFFFFFFFF << I40E_GLPRT_MRFC_MRFC_SHIFT)
-#define I40E_GLPRT_PRC1023H(_i) (0x00300504 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MRFC_MRFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MRFC_MRFC_SHIFT)
+#define I40E_GLPRT_PRC1023H(_i) (0x00300504 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1023H_MAX_INDEX 3
#define I40E_GLPRT_PRC1023H_PRC1023H_SHIFT 0
-#define I40E_GLPRT_PRC1023H_PRC1023H_MASK (0xFFFF << I40E_GLPRT_PRC1023H_PRC1023H_SHIFT)
-#define I40E_GLPRT_PRC1023L(_i) (0x00300500 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1023H_PRC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1023H_PRC1023H_SHIFT)
+#define I40E_GLPRT_PRC1023L(_i) (0x00300500 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1023L_MAX_INDEX 3
#define I40E_GLPRT_PRC1023L_PRC1023L_SHIFT 0
-#define I40E_GLPRT_PRC1023L_PRC1023L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC1023L_PRC1023L_SHIFT)
-#define I40E_GLPRT_PRC127H(_i) (0x003004A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1023L_PRC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1023L_PRC1023L_SHIFT)
+#define I40E_GLPRT_PRC127H(_i) (0x003004A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC127H_MAX_INDEX 3
#define I40E_GLPRT_PRC127H_PRC127H_SHIFT 0
-#define I40E_GLPRT_PRC127H_PRC127H_MASK (0xFFFF << I40E_GLPRT_PRC127H_PRC127H_SHIFT)
-#define I40E_GLPRT_PRC127L(_i) (0x003004A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC127H_PRC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC127H_PRC127H_SHIFT)
+#define I40E_GLPRT_PRC127L(_i) (0x003004A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC127L_MAX_INDEX 3
#define I40E_GLPRT_PRC127L_PRC127L_SHIFT 0
-#define I40E_GLPRT_PRC127L_PRC127L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC127L_PRC127L_SHIFT)
-#define I40E_GLPRT_PRC1522H(_i) (0x00300524 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC127L_PRC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC127L_PRC127L_SHIFT)
+#define I40E_GLPRT_PRC1522H(_i) (0x00300524 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1522H_MAX_INDEX 3
#define I40E_GLPRT_PRC1522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC1522H_PRC1522H_MASK (0xFFFF << I40E_GLPRT_PRC1522H_PRC1522H_SHIFT)
-#define I40E_GLPRT_PRC1522L(_i) (0x00300520 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1522H_PRC1522H_SHIFT)
+#define I40E_GLPRT_PRC1522L(_i) (0x00300520 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1522L_MAX_INDEX 3
#define I40E_GLPRT_PRC1522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC1522L_PRC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC1522L_PRC1522L_SHIFT)
-#define I40E_GLPRT_PRC255H(_i) (0x003004C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1522L_PRC1522L_SHIFT)
+#define I40E_GLPRT_PRC255H(_i) (0x003004C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC255H_MAX_INDEX 3
#define I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT 0
-#define I40E_GLPRT_PRC255H_PRTPRC255H_MASK (0xFFFF << I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT)
-#define I40E_GLPRT_PRC255L(_i) (0x003004C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC255H_PRTPRC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT)
+#define I40E_GLPRT_PRC255L(_i) (0x003004C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC255L_MAX_INDEX 3
#define I40E_GLPRT_PRC255L_PRC255L_SHIFT 0
-#define I40E_GLPRT_PRC255L_PRC255L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC255L_PRC255L_SHIFT)
-#define I40E_GLPRT_PRC511H(_i) (0x003004E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC255L_PRC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC255L_PRC255L_SHIFT)
+#define I40E_GLPRT_PRC511H(_i) (0x003004E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC511H_MAX_INDEX 3
#define I40E_GLPRT_PRC511H_PRC511H_SHIFT 0
-#define I40E_GLPRT_PRC511H_PRC511H_MASK (0xFFFF << I40E_GLPRT_PRC511H_PRC511H_SHIFT)
-#define I40E_GLPRT_PRC511L(_i) (0x003004E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC511H_PRC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC511H_PRC511H_SHIFT)
+#define I40E_GLPRT_PRC511L(_i) (0x003004E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC511L_MAX_INDEX 3
#define I40E_GLPRT_PRC511L_PRC511L_SHIFT 0
-#define I40E_GLPRT_PRC511L_PRC511L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC511L_PRC511L_SHIFT)
-#define I40E_GLPRT_PRC64H(_i) (0x00300484 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC511L_PRC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC511L_PRC511L_SHIFT)
+#define I40E_GLPRT_PRC64H(_i) (0x00300484 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC64H_MAX_INDEX 3
#define I40E_GLPRT_PRC64H_PRC64H_SHIFT 0
-#define I40E_GLPRT_PRC64H_PRC64H_MASK (0xFFFF << I40E_GLPRT_PRC64H_PRC64H_SHIFT)
-#define I40E_GLPRT_PRC64L(_i) (0x00300480 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC64H_PRC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC64H_PRC64H_SHIFT)
+#define I40E_GLPRT_PRC64L(_i) (0x00300480 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC64L_MAX_INDEX 3
#define I40E_GLPRT_PRC64L_PRC64L_SHIFT 0
-#define I40E_GLPRT_PRC64L_PRC64L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC64L_PRC64L_SHIFT)
-#define I40E_GLPRT_PRC9522H(_i) (0x00300544 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC64L_PRC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC64L_PRC64L_SHIFT)
+#define I40E_GLPRT_PRC9522H(_i) (0x00300544 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC9522H_MAX_INDEX 3
#define I40E_GLPRT_PRC9522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC9522H_PRC1522H_MASK (0xFFFF << I40E_GLPRT_PRC9522H_PRC1522H_SHIFT)
-#define I40E_GLPRT_PRC9522L(_i) (0x00300540 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC9522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC9522H_PRC1522H_SHIFT)
+#define I40E_GLPRT_PRC9522L(_i) (0x00300540 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC9522L_MAX_INDEX 3
#define I40E_GLPRT_PRC9522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC9522L_PRC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC9522L_PRC1522L_SHIFT)
-#define I40E_GLPRT_PTC1023H(_i) (0x00300724 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC9522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC9522L_PRC1522L_SHIFT)
+#define I40E_GLPRT_PTC1023H(_i) (0x00300724 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1023H_MAX_INDEX 3
#define I40E_GLPRT_PTC1023H_PTC1023H_SHIFT 0
-#define I40E_GLPRT_PTC1023H_PTC1023H_MASK (0xFFFF << I40E_GLPRT_PTC1023H_PTC1023H_SHIFT)
-#define I40E_GLPRT_PTC1023L(_i) (0x00300720 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1023H_PTC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1023H_PTC1023H_SHIFT)
+#define I40E_GLPRT_PTC1023L(_i) (0x00300720 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1023L_MAX_INDEX 3
#define I40E_GLPRT_PTC1023L_PTC1023L_SHIFT 0
-#define I40E_GLPRT_PTC1023L_PTC1023L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC1023L_PTC1023L_SHIFT)
-#define I40E_GLPRT_PTC127H(_i) (0x003006C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1023L_PTC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1023L_PTC1023L_SHIFT)
+#define I40E_GLPRT_PTC127H(_i) (0x003006C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC127H_MAX_INDEX 3
#define I40E_GLPRT_PTC127H_PTC127H_SHIFT 0
-#define I40E_GLPRT_PTC127H_PTC127H_MASK (0xFFFF << I40E_GLPRT_PTC127H_PTC127H_SHIFT)
-#define I40E_GLPRT_PTC127L(_i) (0x003006C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC127H_PTC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC127H_PTC127H_SHIFT)
+#define I40E_GLPRT_PTC127L(_i) (0x003006C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC127L_MAX_INDEX 3
#define I40E_GLPRT_PTC127L_PTC127L_SHIFT 0
-#define I40E_GLPRT_PTC127L_PTC127L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC127L_PTC127L_SHIFT)
-#define I40E_GLPRT_PTC1522H(_i) (0x00300744 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC127L_PTC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC127L_PTC127L_SHIFT)
+#define I40E_GLPRT_PTC1522H(_i) (0x00300744 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1522H_MAX_INDEX 3
#define I40E_GLPRT_PTC1522H_PTC1522H_SHIFT 0
-#define I40E_GLPRT_PTC1522H_PTC1522H_MASK (0xFFFF << I40E_GLPRT_PTC1522H_PTC1522H_SHIFT)
-#define I40E_GLPRT_PTC1522L(_i) (0x00300740 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1522H_PTC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1522H_PTC1522H_SHIFT)
+#define I40E_GLPRT_PTC1522L(_i) (0x00300740 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1522L_MAX_INDEX 3
#define I40E_GLPRT_PTC1522L_PTC1522L_SHIFT 0
-#define I40E_GLPRT_PTC1522L_PTC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC1522L_PTC1522L_SHIFT)
-#define I40E_GLPRT_PTC255H(_i) (0x003006E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1522L_PTC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1522L_PTC1522L_SHIFT)
+#define I40E_GLPRT_PTC255H(_i) (0x003006E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC255H_MAX_INDEX 3
#define I40E_GLPRT_PTC255H_PTC255H_SHIFT 0
-#define I40E_GLPRT_PTC255H_PTC255H_MASK (0xFFFF << I40E_GLPRT_PTC255H_PTC255H_SHIFT)
-#define I40E_GLPRT_PTC255L(_i) (0x003006E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC255H_PTC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC255H_PTC255H_SHIFT)
+#define I40E_GLPRT_PTC255L(_i) (0x003006E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC255L_MAX_INDEX 3
#define I40E_GLPRT_PTC255L_PTC255L_SHIFT 0
-#define I40E_GLPRT_PTC255L_PTC255L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC255L_PTC255L_SHIFT)
-#define I40E_GLPRT_PTC511H(_i) (0x00300704 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC255L_PTC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC255L_PTC255L_SHIFT)
+#define I40E_GLPRT_PTC511H(_i) (0x00300704 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC511H_MAX_INDEX 3
#define I40E_GLPRT_PTC511H_PTC511H_SHIFT 0
-#define I40E_GLPRT_PTC511H_PTC511H_MASK (0xFFFF << I40E_GLPRT_PTC511H_PTC511H_SHIFT)
-#define I40E_GLPRT_PTC511L(_i) (0x00300700 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC511H_PTC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC511H_PTC511H_SHIFT)
+#define I40E_GLPRT_PTC511L(_i) (0x00300700 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC511L_MAX_INDEX 3
#define I40E_GLPRT_PTC511L_PTC511L_SHIFT 0
-#define I40E_GLPRT_PTC511L_PTC511L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC511L_PTC511L_SHIFT)
-#define I40E_GLPRT_PTC64H(_i) (0x003006A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC511L_PTC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC511L_PTC511L_SHIFT)
+#define I40E_GLPRT_PTC64H(_i) (0x003006A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC64H_MAX_INDEX 3
#define I40E_GLPRT_PTC64H_PTC64H_SHIFT 0
-#define I40E_GLPRT_PTC64H_PTC64H_MASK (0xFFFF << I40E_GLPRT_PTC64H_PTC64H_SHIFT)
-#define I40E_GLPRT_PTC64L(_i) (0x003006A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC64H_PTC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC64H_PTC64H_SHIFT)
+#define I40E_GLPRT_PTC64L(_i) (0x003006A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC64L_MAX_INDEX 3
#define I40E_GLPRT_PTC64L_PTC64L_SHIFT 0
-#define I40E_GLPRT_PTC64L_PTC64L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC64L_PTC64L_SHIFT)
-#define I40E_GLPRT_PTC9522H(_i) (0x00300764 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC64L_PTC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC64L_PTC64L_SHIFT)
+#define I40E_GLPRT_PTC9522H(_i) (0x00300764 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC9522H_MAX_INDEX 3
#define I40E_GLPRT_PTC9522H_PTC9522H_SHIFT 0
-#define I40E_GLPRT_PTC9522H_PTC9522H_MASK (0xFFFF << I40E_GLPRT_PTC9522H_PTC9522H_SHIFT)
-#define I40E_GLPRT_PTC9522L(_i) (0x00300760 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC9522H_PTC9522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC9522H_PTC9522H_SHIFT)
+#define I40E_GLPRT_PTC9522L(_i) (0x00300760 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC9522L_MAX_INDEX 3
#define I40E_GLPRT_PTC9522L_PTC9522L_SHIFT 0
-#define I40E_GLPRT_PTC9522L_PTC9522L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC9522L_PTC9522L_SHIFT)
-#define I40E_GLPRT_PXOFFRXC(_i, _j) (0x00300280 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PTC9522L_PTC9522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC9522L_PTC9522L_SHIFT)
+#define I40E_GLPRT_PXOFFRXC(_i, _j) (0x00300280 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXOFFRXC_MAX_INDEX 3
#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT)
-#define I40E_GLPRT_PXOFFTXC(_i, _j) (0x00300880 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT)
+#define I40E_GLPRT_PXOFFTXC(_i, _j) (0x00300880 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXOFFTXC_MAX_INDEX 3
#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT)
-#define I40E_GLPRT_PXONRXC(_i, _j) (0x00300180 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT)
+#define I40E_GLPRT_PXONRXC(_i, _j) (0x00300180 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXONRXC_MAX_INDEX 3
#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT 0
-#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT)
-#define I40E_GLPRT_PXONTXC(_i, _j) (0x00300780 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT)
+#define I40E_GLPRT_PXONTXC(_i, _j) (0x00300780 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXONTXC_MAX_INDEX 3
#define I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT 0
-#define I40E_GLPRT_PXONTXC_PRPXONTXC_MASK (0xFFFFFFFF << I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT)
-#define I40E_GLPRT_RDPC(_i) (0x00300600 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PXONTXC_PRPXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT)
+#define I40E_GLPRT_RDPC(_i) (0x00300600 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RDPC_MAX_INDEX 3
#define I40E_GLPRT_RDPC_RDPC_SHIFT 0
-#define I40E_GLPRT_RDPC_RDPC_MASK (0xFFFFFFFF << I40E_GLPRT_RDPC_RDPC_SHIFT)
-#define I40E_GLPRT_RFC(_i) (0x00300560 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RDPC_RDPC_SHIFT)
+#define I40E_GLPRT_RFC(_i) (0x00300560 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RFC_MAX_INDEX 3
#define I40E_GLPRT_RFC_RFC_SHIFT 0
-#define I40E_GLPRT_RFC_RFC_MASK (0xFFFFFFFF << I40E_GLPRT_RFC_RFC_SHIFT)
-#define I40E_GLPRT_RJC(_i) (0x00300580 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RFC_RFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RFC_RFC_SHIFT)
+#define I40E_GLPRT_RJC(_i) (0x00300580 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RJC_MAX_INDEX 3
#define I40E_GLPRT_RJC_RJC_SHIFT 0
-#define I40E_GLPRT_RJC_RJC_MASK (0xFFFFFFFF << I40E_GLPRT_RJC_RJC_SHIFT)
-#define I40E_GLPRT_RLEC(_i) (0x003000A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RJC_RJC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RJC_RJC_SHIFT)
+#define I40E_GLPRT_RLEC(_i) (0x003000A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RLEC_MAX_INDEX 3
#define I40E_GLPRT_RLEC_RLEC_SHIFT 0
-#define I40E_GLPRT_RLEC_RLEC_MASK (0xFFFFFFFF << I40E_GLPRT_RLEC_RLEC_SHIFT)
-#define I40E_GLPRT_ROC(_i) (0x00300120 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RLEC_RLEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RLEC_RLEC_SHIFT)
+#define I40E_GLPRT_ROC(_i) (0x00300120 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_ROC_MAX_INDEX 3
#define I40E_GLPRT_ROC_ROC_SHIFT 0
-#define I40E_GLPRT_ROC_ROC_MASK (0xFFFFFFFF << I40E_GLPRT_ROC_ROC_SHIFT)
-#define I40E_GLPRT_RUC(_i) (0x00300100 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_ROC_ROC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ROC_ROC_SHIFT)
+#define I40E_GLPRT_RUC(_i) (0x00300100 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RUC_MAX_INDEX 3
#define I40E_GLPRT_RUC_RUC_SHIFT 0
-#define I40E_GLPRT_RUC_RUC_MASK (0xFFFFFFFF << I40E_GLPRT_RUC_RUC_SHIFT)
-#define I40E_GLPRT_RUPP(_i) (0x00300660 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RUC_RUC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUC_RUC_SHIFT)
+#define I40E_GLPRT_RUPP(_i) (0x00300660 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RUPP_MAX_INDEX 3
#define I40E_GLPRT_RUPP_RUPP_SHIFT 0
-#define I40E_GLPRT_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLPRT_RUPP_RUPP_SHIFT)
-#define I40E_GLPRT_RXON2OFFCNT(_i, _j) (0x00300380 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUPP_RUPP_SHIFT)
+#define I40E_GLPRT_RXON2OFFCNT(_i, _j) (0x00300380 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_RXON2OFFCNT_MAX_INDEX 3
#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT 0
-#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_MASK (0xFFFFFFFF << I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT)
-#define I40E_GLPRT_STDC(_i) (0x00300640 + ((_i) * 8)) /* _i=0...3 */
-#define I40E_GLPRT_STDC_MAX_INDEX 3
-#define I40E_GLPRT_STDC_STDC_SHIFT 0
-#define I40E_GLPRT_STDC_STDC_MASK (0xFFFFFFFF << I40E_GLPRT_STDC_STDC_SHIFT)
-#define I40E_GLPRT_TDOLD(_i) (0x00300A20 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT)
+#define I40E_GLPRT_TDOLD(_i) (0x00300A20 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_TDOLD_MAX_INDEX 3
#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT 0
-#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_MASK (0xFFFFFFFF << I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT)
-#define I40E_GLPRT_TDPC(_i) (0x00375400 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT)
+#define I40E_GLPRT_TDPC(_i) (0x00375400 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_TDPC_MAX_INDEX 3
#define I40E_GLPRT_TDPC_TDPC_SHIFT 0
-#define I40E_GLPRT_TDPC_TDPC_MASK (0xFFFFFFFF << I40E_GLPRT_TDPC_TDPC_SHIFT)
-#define I40E_GLPRT_UPRCH(_i) (0x003005A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_TDPC_TDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_TDPC_TDPC_SHIFT)
+#define I40E_GLPRT_UPRCH(_i) (0x003005A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPRCH_MAX_INDEX 3
#define I40E_GLPRT_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_UPRCH_UPRCH_SHIFT)
-#define I40E_GLPRT_UPRCL(_i) (0x003005A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPRCH_UPRCH_SHIFT)
+#define I40E_GLPRT_UPRCL(_i) (0x003005A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPRCL_MAX_INDEX 3
#define I40E_GLPRT_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLPRT_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLPRT_UPRCL_UPRCL_SHIFT)
-#define I40E_GLPRT_UPTCH(_i) (0x003009C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPRCL_UPRCL_SHIFT)
+#define I40E_GLPRT_UPTCH(_i) (0x003009C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPTCH_MAX_INDEX 3
#define I40E_GLPRT_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCH_UPTCH_MASK (0xFFFF << I40E_GLPRT_UPTCH_UPTCH_SHIFT)
-#define I40E_GLPRT_UPTCL(_i) (0x003009C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPTCH_UPTCH_SHIFT)
+#define I40E_GLPRT_UPTCL(_i) (0x003009C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPTCL_MAX_INDEX 3
#define I40E_GLPRT_UPTCL_VUPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCL_VUPTCH_MASK (0xFFFFFFFF << I40E_GLPRT_UPTCL_VUPTCH_SHIFT)
-#define I40E_GLSW_BPRCH(_i) (0x00370104 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLPRT_UPTCL_VUPTCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPTCL_VUPTCH_SHIFT)
+#define I40E_GLSW_BPRCH(_i) (0x00370104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPRCH_MAX_INDEX 15
#define I40E_GLSW_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLSW_BPRCH_BPRCH_MASK (0xFFFF << I40E_GLSW_BPRCH_BPRCH_SHIFT)
-#define I40E_GLSW_BPRCL(_i) (0x00370100 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPRCH_BPRCH_SHIFT)
+#define I40E_GLSW_BPRCL(_i) (0x00370100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPRCL_MAX_INDEX 15
#define I40E_GLSW_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLSW_BPRCL_BPRCL_MASK (0xFFFFFFFF << I40E_GLSW_BPRCL_BPRCL_SHIFT)
-#define I40E_GLSW_BPTCH(_i) (0x00340104 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPRCL_BPRCL_SHIFT)
+#define I40E_GLSW_BPTCH(_i) (0x00340104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPTCH_MAX_INDEX 15
#define I40E_GLSW_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLSW_BPTCH_BPTCH_MASK (0xFFFF << I40E_GLSW_BPTCH_BPTCH_SHIFT)
-#define I40E_GLSW_BPTCL(_i) (0x00340100 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPTCH_BPTCH_SHIFT)
+#define I40E_GLSW_BPTCL(_i) (0x00340100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPTCL_MAX_INDEX 15
#define I40E_GLSW_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLSW_BPTCL_BPTCL_MASK (0xFFFFFFFF << I40E_GLSW_BPTCL_BPTCL_SHIFT)
-#define I40E_GLSW_GORCH(_i) (0x0035C004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPTCL_BPTCL_SHIFT)
+#define I40E_GLSW_GORCH(_i) (0x0035C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GORCH_MAX_INDEX 15
#define I40E_GLSW_GORCH_GORCH_SHIFT 0
-#define I40E_GLSW_GORCH_GORCH_MASK (0xFFFF << I40E_GLSW_GORCH_GORCH_SHIFT)
-#define I40E_GLSW_GORCL(_i) (0x0035c000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GORCH_GORCH_SHIFT)
+#define I40E_GLSW_GORCL(_i) (0x0035c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GORCL_MAX_INDEX 15
#define I40E_GLSW_GORCL_GORCL_SHIFT 0
-#define I40E_GLSW_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLSW_GORCL_GORCL_SHIFT)
-#define I40E_GLSW_GOTCH(_i) (0x0032C004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GORCL_GORCL_SHIFT)
+#define I40E_GLSW_GOTCH(_i) (0x0032C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GOTCH_MAX_INDEX 15
#define I40E_GLSW_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLSW_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLSW_GOTCH_GOTCH_SHIFT)
-#define I40E_GLSW_GOTCL(_i) (0x0032c000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GOTCH_GOTCH_SHIFT)
+#define I40E_GLSW_GOTCL(_i) (0x0032c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GOTCL_MAX_INDEX 15
#define I40E_GLSW_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLSW_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLSW_GOTCL_GOTCL_SHIFT)
-#define I40E_GLSW_MPRCH(_i) (0x00370084 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GOTCL_GOTCL_SHIFT)
+#define I40E_GLSW_MPRCH(_i) (0x00370084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPRCH_MAX_INDEX 15
#define I40E_GLSW_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLSW_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLSW_MPRCH_MPRCH_SHIFT)
-#define I40E_GLSW_MPRCL(_i) (0x00370080 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPRCH_MPRCH_SHIFT)
+#define I40E_GLSW_MPRCL(_i) (0x00370080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPRCL_MAX_INDEX 15
#define I40E_GLSW_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLSW_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLSW_MPRCL_MPRCL_SHIFT)
-#define I40E_GLSW_MPTCH(_i) (0x00340084 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPRCL_MPRCL_SHIFT)
+#define I40E_GLSW_MPTCH(_i) (0x00340084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPTCH_MAX_INDEX 15
#define I40E_GLSW_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLSW_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLSW_MPTCH_MPTCH_SHIFT)
-#define I40E_GLSW_MPTCL(_i) (0x00340080 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPTCH_MPTCH_SHIFT)
+#define I40E_GLSW_MPTCL(_i) (0x00340080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPTCL_MAX_INDEX 15
#define I40E_GLSW_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLSW_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLSW_MPTCL_MPTCL_SHIFT)
-#define I40E_GLSW_RUPP(_i) (0x00370180 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPTCL_MPTCL_SHIFT)
+#define I40E_GLSW_RUPP(_i) (0x00370180 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_RUPP_MAX_INDEX 15
#define I40E_GLSW_RUPP_RUPP_SHIFT 0
-#define I40E_GLSW_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLSW_RUPP_RUPP_SHIFT)
-#define I40E_GLSW_TDPC(_i) (0x00348000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_RUPP_RUPP_SHIFT)
+#define I40E_GLSW_TDPC(_i) (0x00348000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_TDPC_MAX_INDEX 15
#define I40E_GLSW_TDPC_TDPC_SHIFT 0
-#define I40E_GLSW_TDPC_TDPC_MASK (0xFFFFFFFF << I40E_GLSW_TDPC_TDPC_SHIFT)
-#define I40E_GLSW_UPRCH(_i) (0x00370004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_TDPC_TDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_TDPC_TDPC_SHIFT)
+#define I40E_GLSW_UPRCH(_i) (0x00370004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPRCH_MAX_INDEX 15
#define I40E_GLSW_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLSW_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLSW_UPRCH_UPRCH_SHIFT)
-#define I40E_GLSW_UPRCL(_i) (0x00370000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPRCH_UPRCH_SHIFT)
+#define I40E_GLSW_UPRCL(_i) (0x00370000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPRCL_MAX_INDEX 15
#define I40E_GLSW_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLSW_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLSW_UPRCL_UPRCL_SHIFT)
-#define I40E_GLSW_UPTCH(_i) (0x00340004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPRCL_UPRCL_SHIFT)
+#define I40E_GLSW_UPTCH(_i) (0x00340004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPTCH_MAX_INDEX 15
#define I40E_GLSW_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLSW_UPTCH_UPTCH_MASK (0xFFFF << I40E_GLSW_UPTCH_UPTCH_SHIFT)
-#define I40E_GLSW_UPTCL(_i) (0x00340000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPTCH_UPTCH_SHIFT)
+#define I40E_GLSW_UPTCL(_i) (0x00340000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPTCL_MAX_INDEX 15
#define I40E_GLSW_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLSW_UPTCL_UPTCL_MASK (0xFFFFFFFF << I40E_GLSW_UPTCL_UPTCL_SHIFT)
-#define I40E_GLV_BPRCH(_i) (0x0036D804 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLSW_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPTCL_UPTCL_SHIFT)
+#define I40E_GLV_BPRCH(_i) (0x0036D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPRCH_MAX_INDEX 383
#define I40E_GLV_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLV_BPRCH_BPRCH_MASK (0xFFFF << I40E_GLV_BPRCH_BPRCH_SHIFT)
-#define I40E_GLV_BPRCL(_i) (0x0036d800 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPRCH_BPRCH_SHIFT)
+#define I40E_GLV_BPRCL(_i) (0x0036d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPRCL_MAX_INDEX 383
#define I40E_GLV_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLV_BPRCL_BPRCL_MASK (0xFFFFFFFF << I40E_GLV_BPRCL_BPRCL_SHIFT)
-#define I40E_GLV_BPTCH(_i) (0x0033D804 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPRCL_BPRCL_SHIFT)
+#define I40E_GLV_BPTCH(_i) (0x0033D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPTCH_MAX_INDEX 383
#define I40E_GLV_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLV_BPTCH_BPTCH_MASK (0xFFFF << I40E_GLV_BPTCH_BPTCH_SHIFT)
-#define I40E_GLV_BPTCL(_i) (0x0033d800 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPTCH_BPTCH_SHIFT)
+#define I40E_GLV_BPTCL(_i) (0x0033d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPTCL_MAX_INDEX 383
#define I40E_GLV_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLV_BPTCL_BPTCL_MASK (0xFFFFFFFF << I40E_GLV_BPTCL_BPTCL_SHIFT)
-#define I40E_GLV_GORCH(_i) (0x00358004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPTCL_BPTCL_SHIFT)
+#define I40E_GLV_GORCH(_i) (0x00358004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GORCH_MAX_INDEX 383
#define I40E_GLV_GORCH_GORCH_SHIFT 0
-#define I40E_GLV_GORCH_GORCH_MASK (0xFFFF << I40E_GLV_GORCH_GORCH_SHIFT)
-#define I40E_GLV_GORCL(_i) (0x00358000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GORCH_GORCH_SHIFT)
+#define I40E_GLV_GORCL(_i) (0x00358000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GORCL_MAX_INDEX 383
#define I40E_GLV_GORCL_GORCL_SHIFT 0
-#define I40E_GLV_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLV_GORCL_GORCL_SHIFT)
-#define I40E_GLV_GOTCH(_i) (0x00328004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GORCL_GORCL_SHIFT)
+#define I40E_GLV_GOTCH(_i) (0x00328004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GOTCH_MAX_INDEX 383
#define I40E_GLV_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLV_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLV_GOTCH_GOTCH_SHIFT)
-#define I40E_GLV_GOTCL(_i) (0x00328000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GOTCH_GOTCH_SHIFT)
+#define I40E_GLV_GOTCL(_i) (0x00328000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GOTCL_MAX_INDEX 383
#define I40E_GLV_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLV_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLV_GOTCL_GOTCL_SHIFT)
-#define I40E_GLV_MPRCH(_i) (0x0036CC04 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GOTCL_GOTCL_SHIFT)
+#define I40E_GLV_MPRCH(_i) (0x0036CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPRCH_MAX_INDEX 383
#define I40E_GLV_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLV_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLV_MPRCH_MPRCH_SHIFT)
-#define I40E_GLV_MPRCL(_i) (0x0036cc00 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPRCH_MPRCH_SHIFT)
+#define I40E_GLV_MPRCL(_i) (0x0036cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPRCL_MAX_INDEX 383
#define I40E_GLV_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLV_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLV_MPRCL_MPRCL_SHIFT)
-#define I40E_GLV_MPTCH(_i) (0x0033CC04 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPRCL_MPRCL_SHIFT)
+#define I40E_GLV_MPTCH(_i) (0x0033CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPTCH_MAX_INDEX 383
#define I40E_GLV_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLV_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLV_MPTCH_MPTCH_SHIFT)
-#define I40E_GLV_MPTCL(_i) (0x0033cc00 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPTCH_MPTCH_SHIFT)
+#define I40E_GLV_MPTCL(_i) (0x0033cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPTCL_MAX_INDEX 383
#define I40E_GLV_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLV_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLV_MPTCL_MPTCL_SHIFT)
-#define I40E_GLV_RDPC(_i) (0x00310000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPTCL_MPTCL_SHIFT)
+#define I40E_GLV_RDPC(_i) (0x00310000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_RDPC_MAX_INDEX 383
#define I40E_GLV_RDPC_RDPC_SHIFT 0
-#define I40E_GLV_RDPC_RDPC_MASK (0xFFFFFFFF << I40E_GLV_RDPC_RDPC_SHIFT)
-#define I40E_GLV_RUPP(_i) (0x0036E400 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RDPC_RDPC_SHIFT)
+#define I40E_GLV_RUPP(_i) (0x0036E400 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_RUPP_MAX_INDEX 383
#define I40E_GLV_RUPP_RUPP_SHIFT 0
-#define I40E_GLV_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLV_RUPP_RUPP_SHIFT)
-#define I40E_GLV_TEPC(_VSI) (0x00344000 + ((_VSI) * 8)) /* _i=0...383 */
+#define I40E_GLV_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RUPP_RUPP_SHIFT)
+#define I40E_GLV_TEPC(_VSI) (0x00344000 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_TEPC_MAX_INDEX 383
#define I40E_GLV_TEPC_TEPC_SHIFT 0
-#define I40E_GLV_TEPC_TEPC_MASK (0xFFFFFFFF << I40E_GLV_TEPC_TEPC_SHIFT)
-#define I40E_GLV_UPRCH(_i) (0x0036C004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_TEPC_TEPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_TEPC_TEPC_SHIFT)
+#define I40E_GLV_UPRCH(_i) (0x0036C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPRCH_MAX_INDEX 383
#define I40E_GLV_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLV_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLV_UPRCH_UPRCH_SHIFT)
-#define I40E_GLV_UPRCL(_i) (0x0036c000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPRCH_UPRCH_SHIFT)
+#define I40E_GLV_UPRCL(_i) (0x0036c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPRCL_MAX_INDEX 383
#define I40E_GLV_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLV_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLV_UPRCL_UPRCL_SHIFT)
-#define I40E_GLV_UPTCH(_i) (0x0033C004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPRCL_UPRCL_SHIFT)
+#define I40E_GLV_UPTCH(_i) (0x0033C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPTCH_MAX_INDEX 383
#define I40E_GLV_UPTCH_GLVUPTCH_SHIFT 0
-#define I40E_GLV_UPTCH_GLVUPTCH_MASK (0xFFFF << I40E_GLV_UPTCH_GLVUPTCH_SHIFT)
-#define I40E_GLV_UPTCL(_i) (0x0033c000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPTCH_GLVUPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPTCH_GLVUPTCH_SHIFT)
+#define I40E_GLV_UPTCL(_i) (0x0033c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPTCL_MAX_INDEX 383
#define I40E_GLV_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLV_UPTCL_UPTCL_MASK (0xFFFFFFFF << I40E_GLV_UPTCL_UPTCL_SHIFT)
-#define I40E_GLVEBTC_RBCH(_i, _j) (0x00364004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLV_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPTCL_UPTCL_SHIFT)
+#define I40E_GLVEBTC_RBCH(_i, _j) (0x00364004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RBCH_MAX_INDEX 7
#define I40E_GLVEBTC_RBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_RBCH_TCBCH_MASK (0xFFFF << I40E_GLVEBTC_RBCH_TCBCH_SHIFT)
-#define I40E_GLVEBTC_RBCL(_i, _j) (0x00364000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RBCH_TCBCH_SHIFT)
+#define I40E_GLVEBTC_RBCL(_i, _j) (0x00364000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RBCL_MAX_INDEX 7
#define I40E_GLVEBTC_RBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_RBCL_TCBCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_RBCL_TCBCL_SHIFT)
-#define I40E_GLVEBTC_RPCH(_i, _j) (0x00368004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RBCL_TCBCL_SHIFT)
+#define I40E_GLVEBTC_RPCH(_i, _j) (0x00368004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RPCH_MAX_INDEX 7
#define I40E_GLVEBTC_RPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_RPCH_TCPCH_MASK (0xFFFF << I40E_GLVEBTC_RPCH_TCPCH_SHIFT)
-#define I40E_GLVEBTC_RPCL(_i, _j) (0x00368000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RPCH_TCPCH_SHIFT)
+#define I40E_GLVEBTC_RPCL(_i, _j) (0x00368000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RPCL_MAX_INDEX 7
#define I40E_GLVEBTC_RPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_RPCL_TCPCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_RPCL_TCPCL_SHIFT)
-#define I40E_GLVEBTC_TBCH(_i, _j) (0x00334004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RPCL_TCPCL_SHIFT)
+#define I40E_GLVEBTC_TBCH(_i, _j) (0x00334004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TBCH_MAX_INDEX 7
#define I40E_GLVEBTC_TBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_TBCH_TCBCH_MASK (0xFFFF << I40E_GLVEBTC_TBCH_TCBCH_SHIFT)
-#define I40E_GLVEBTC_TBCL(_i, _j) (0x00334000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TBCH_TCBCH_SHIFT)
+#define I40E_GLVEBTC_TBCL(_i, _j) (0x00334000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TBCL_MAX_INDEX 7
#define I40E_GLVEBTC_TBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_TBCL_TCBCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_TBCL_TCBCL_SHIFT)
-#define I40E_GLVEBTC_TPCH(_i, _j) (0x00338004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TBCL_TCBCL_SHIFT)
+#define I40E_GLVEBTC_TPCH(_i, _j) (0x00338004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TPCH_MAX_INDEX 7
#define I40E_GLVEBTC_TPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_TPCH_TCPCH_MASK (0xFFFF << I40E_GLVEBTC_TPCH_TCPCH_SHIFT)
-#define I40E_GLVEBTC_TPCL(_i, _j) (0x00338000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TPCH_TCPCH_SHIFT)
+#define I40E_GLVEBTC_TPCL(_i, _j) (0x00338000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TPCL_MAX_INDEX 7
#define I40E_GLVEBTC_TPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_TPCL_TCPCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_TPCL_TCPCL_SHIFT)
-#define I40E_GLVEBVL_BPCH(_i) (0x00374804 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBTC_TPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TPCL_TCPCL_SHIFT)
+#define I40E_GLVEBVL_BPCH(_i) (0x00374804 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_BPCH_MAX_INDEX 127
#define I40E_GLVEBVL_BPCH_VLBPCH_SHIFT 0
-#define I40E_GLVEBVL_BPCH_VLBPCH_MASK (0xFFFF << I40E_GLVEBVL_BPCH_VLBPCH_SHIFT)
-#define I40E_GLVEBVL_BPCL(_i) (0x00374800 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_BPCH_VLBPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_BPCH_VLBPCH_SHIFT)
+#define I40E_GLVEBVL_BPCL(_i) (0x00374800 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_BPCL_MAX_INDEX 127
#define I40E_GLVEBVL_BPCL_VLBPCL_SHIFT 0
-#define I40E_GLVEBVL_BPCL_VLBPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_BPCL_VLBPCL_SHIFT)
-#define I40E_GLVEBVL_GORCH(_i) (0x00360004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_BPCL_VLBPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_BPCL_VLBPCL_SHIFT)
+#define I40E_GLVEBVL_GORCH(_i) (0x00360004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GORCH_MAX_INDEX 127
#define I40E_GLVEBVL_GORCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GORCH_VLBCH_MASK (0xFFFF << I40E_GLVEBVL_GORCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GORCL(_i) (0x00360000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GORCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GORCH_VLBCH_SHIFT)
+#define I40E_GLVEBVL_GORCL(_i) (0x00360000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GORCL_MAX_INDEX 127
#define I40E_GLVEBVL_GORCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GORCL_VLBCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_GORCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_GOTCH(_i) (0x00330004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GORCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GORCL_VLBCL_SHIFT)
+#define I40E_GLVEBVL_GOTCH(_i) (0x00330004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GOTCH_MAX_INDEX 127
#define I40E_GLVEBVL_GOTCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GOTCH_VLBCH_MASK (0xFFFF << I40E_GLVEBVL_GOTCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GOTCL(_i) (0x00330000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GOTCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GOTCH_VLBCH_SHIFT)
+#define I40E_GLVEBVL_GOTCL(_i) (0x00330000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GOTCL_MAX_INDEX 127
#define I40E_GLVEBVL_GOTCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GOTCL_VLBCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_GOTCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_MPCH(_i) (0x00374404 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GOTCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GOTCL_VLBCL_SHIFT)
+#define I40E_GLVEBVL_MPCH(_i) (0x00374404 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_MPCH_MAX_INDEX 127
#define I40E_GLVEBVL_MPCH_VLMPCH_SHIFT 0
-#define I40E_GLVEBVL_MPCH_VLMPCH_MASK (0xFFFF << I40E_GLVEBVL_MPCH_VLMPCH_SHIFT)
-#define I40E_GLVEBVL_MPCL(_i) (0x00374400 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_MPCH_VLMPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_MPCH_VLMPCH_SHIFT)
+#define I40E_GLVEBVL_MPCL(_i) (0x00374400 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_MPCL_MAX_INDEX 127
#define I40E_GLVEBVL_MPCL_VLMPCL_SHIFT 0
-#define I40E_GLVEBVL_MPCL_VLMPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_MPCL_VLMPCL_SHIFT)
-#define I40E_GLVEBVL_UPCH(_i) (0x00374004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_MPCL_VLMPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_MPCL_VLMPCL_SHIFT)
+#define I40E_GLVEBVL_UPCH(_i) (0x00374004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_UPCH_MAX_INDEX 127
#define I40E_GLVEBVL_UPCH_VLUPCH_SHIFT 0
-#define I40E_GLVEBVL_UPCH_VLUPCH_MASK (0xFFFF << I40E_GLVEBVL_UPCH_VLUPCH_SHIFT)
-#define I40E_GLVEBVL_UPCL(_i) (0x00374000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_UPCH_VLUPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_UPCH_VLUPCH_SHIFT)
+#define I40E_GLVEBVL_UPCL(_i) (0x00374000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_UPCL_MAX_INDEX 127
#define I40E_GLVEBVL_UPCL_VLUPCL_SHIFT 0
-#define I40E_GLVEBVL_UPCL_VLUPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_UPCL_VLUPCL_SHIFT)
-#define I40E_GL_MTG_FLU_MSK_H 0x00269F4C
+#define I40E_GLVEBVL_UPCL_VLUPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_UPCL_VLUPCL_SHIFT)
+#define I40E_GL_MTG_FLU_MSK_H 0x00269F4C /* Reset: CORER */
#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT 0
-#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_MASK (0xFFFF << I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT)
-#define I40E_GL_MTG_FLU_MSK_L 0x00269F44
-#define I40E_GL_MTG_FLU_MSK_L_MASK_LOW_SHIFT 0
-#define I40E_GL_MTG_FLU_MSK_L_MASK_LOW_MASK (0xFFFFFFFF << I40E_GL_MTG_FLU_MSK_L_MASK_LOW_SHIFT)
-#define I40E_GL_SWR_DEF_ACT(_i) (0x0026CF00 + ((_i) * 4)) /* _i=0...25 */
-#define I40E_GL_SWR_DEF_ACT_MAX_INDEX 25
+#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_MASK I40E_MASK(0xFFFF, I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT)
+#define I40E_GL_SWR_DEF_ACT(_i) (0x00270200 + ((_i) * 4)) /* _i=0...35 */ /* Reset: CORER */
+#define I40E_GL_SWR_DEF_ACT_MAX_INDEX 35
#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_MASK (0xFFFFFFFF << I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT)
-#define I40E_GL_SWR_DEF_ACT_EN 0x0026CF84
+#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT)
+#define I40E_GL_SWR_DEF_ACT_EN(_i) (0x0026CFB8 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
+#define I40E_GL_SWR_DEF_ACT_EN_MAX_INDEX 1
#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_MASK (0xFFFFFFFF << I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT)
-#define I40E_PRT_MSCCNT 0x00256BA0
-#define I40E_PRT_MSCCNT_CCOUNT_SHIFT 0
-#define I40E_PRT_MSCCNT_CCOUNT_MASK (0x1FFFFFF << I40E_PRT_MSCCNT_CCOUNT_SHIFT)
-#define I40E_PRT_SCSTS 0x00256C20
-#define I40E_PRT_SCSTS_BSCA_SHIFT 0
-#define I40E_PRT_SCSTS_BSCA_MASK (0x1 << I40E_PRT_SCSTS_BSCA_SHIFT)
-#define I40E_PRT_SCSTS_BSCAP_SHIFT 1
-#define I40E_PRT_SCSTS_BSCAP_MASK (0x1 << I40E_PRT_SCSTS_BSCAP_SHIFT)
-#define I40E_PRT_SCSTS_MSCA_SHIFT 2
-#define I40E_PRT_SCSTS_MSCA_MASK (0x1 << I40E_PRT_SCSTS_MSCA_SHIFT)
-#define I40E_PRT_SCSTS_MSCAP_SHIFT 3
-#define I40E_PRT_SCSTS_MSCAP_MASK (0x1 << I40E_PRT_SCSTS_MSCAP_SHIFT)
-#define I40E_PRT_SWT_BSCCNT 0x00256C60
-#define I40E_PRT_SWT_BSCCNT_CCOUNT_SHIFT 0
-#define I40E_PRT_SWT_BSCCNT_CCOUNT_MASK (0x1FFFFFF << I40E_PRT_SWT_BSCCNT_CCOUNT_SHIFT)
-#define I40E_PRTTSYN_ADJ 0x001E4280
+#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT)
+#define I40E_PRTTSYN_ADJ 0x001E4280 /* Reset: GLOBR */
#define I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT 0
-#define I40E_PRTTSYN_ADJ_TSYNADJ_MASK (0x7FFFFFFF << I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT)
+#define I40E_PRTTSYN_ADJ_TSYNADJ_MASK I40E_MASK(0x7FFFFFFF, I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT)
#define I40E_PRTTSYN_ADJ_SIGN_SHIFT 31
-#define I40E_PRTTSYN_ADJ_SIGN_MASK (0x1 << I40E_PRTTSYN_ADJ_SIGN_SHIFT)
-#define I40E_PRTTSYN_AUX_0(_i) (0x001E42A0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_ADJ_SIGN_MASK I40E_MASK(0x1, I40E_PRTTSYN_ADJ_SIGN_SHIFT)
+#define I40E_PRTTSYN_AUX_0(_i) (0x001E42A0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_AUX_0_MAX_INDEX 1
#define I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT 0
-#define I40E_PRTTSYN_AUX_0_OUT_ENA_MASK (0x1 << I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT)
#define I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT 1
-#define I40E_PRTTSYN_AUX_0_OUTMOD_MASK (0x3 << I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUTMOD_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT)
#define I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT 3
-#define I40E_PRTTSYN_AUX_0_OUTLVL_MASK (0x1 << I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUTLVL_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT)
#define I40E_PRTTSYN_AUX_0_PULSEW_SHIFT 8
-#define I40E_PRTTSYN_AUX_0_PULSEW_MASK (0xF << I40E_PRTTSYN_AUX_0_PULSEW_SHIFT)
+#define I40E_PRTTSYN_AUX_0_PULSEW_MASK I40E_MASK(0xF, I40E_PRTTSYN_AUX_0_PULSEW_SHIFT)
#define I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT 16
-#define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK (0x3 << I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT)
-#define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT)
+#define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_AUX_1_MAX_INDEX 1
#define I40E_PRTTSYN_AUX_1_INSTNT_SHIFT 0
-#define I40E_PRTTSYN_AUX_1_INSTNT_MASK (0x1 << I40E_PRTTSYN_AUX_1_INSTNT_SHIFT)
+#define I40E_PRTTSYN_AUX_1_INSTNT_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_INSTNT_SHIFT)
#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT 1
-#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_MASK (0x1 << I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT)
-#define I40E_PRTTSYN_CLKO(_i) (0x001E4240 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT)
+#define I40E_PRTTSYN_CLKO(_i) (0x001E4240 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_CLKO_MAX_INDEX 1
#define I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT 0
-#define I40E_PRTTSYN_CLKO_TSYNCLKO_MASK (0xFFFFFFFF << I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT)
-#define I40E_PRTTSYN_CTL0 0x001E4200
+#define I40E_PRTTSYN_CLKO_TSYNCLKO_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT)
+#define I40E_PRTTSYN_CTL0 0x001E4200 /* Reset: GLOBR */
#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT 0
-#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_MASK (0x1 << I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT)
+#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT)
#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT 1
-#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT 2
-#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT 3
-#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_PF_ID_SHIFT 8
-#define I40E_PRTTSYN_CTL0_PF_ID_MASK (0xF << I40E_PRTTSYN_CTL0_PF_ID_SHIFT)
+#define I40E_PRTTSYN_CTL0_PF_ID_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL0_PF_ID_SHIFT)
#define I40E_PRTTSYN_CTL0_TSYNACT_SHIFT 12
-#define I40E_PRTTSYN_CTL0_TSYNACT_MASK (0x3 << I40E_PRTTSYN_CTL0_TSYNACT_SHIFT)
+#define I40E_PRTTSYN_CTL0_TSYNACT_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL0_TSYNACT_SHIFT)
#define I40E_PRTTSYN_CTL0_TSYNENA_SHIFT 31
-#define I40E_PRTTSYN_CTL0_TSYNENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TSYNENA_SHIFT)
-#define I40E_PRTTSYN_CTL1 0x00085020
+#define I40E_PRTTSYN_CTL0_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TSYNENA_SHIFT)
+#define I40E_PRTTSYN_CTL1 0x00085020 /* Reset: CORER */
#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT 0
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK (0xFF << I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT)
+#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT)
#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT 8
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK (0xFF << I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT)
+#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT 16
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK (0xF << I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT)
+#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT)
#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT 20
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK (0xF << I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT)
+#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT 24
-#define I40E_PRTTSYN_CTL1_TSYNTYPE_MASK (0x3 << I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
+#define I40E_PRTTSYN_CTL1_TSYNTYPE_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
#define I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT 26
-#define I40E_PRTTSYN_CTL1_UDP_ENA_MASK (0x3 << I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL1_UDP_ENA_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNENA_SHIFT 31
-#define I40E_PRTTSYN_CTL1_TSYNENA_MASK (0x1 << I40E_PRTTSYN_CTL1_TSYNENA_SHIFT)
-#define I40E_PRTTSYN_EVNT_H(_i) (0x001E40C0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_CTL1_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL1_TSYNENA_SHIFT)
+#define I40E_PRTTSYN_EVNT_H(_i) (0x001E40C0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_EVNT_H_MAX_INDEX 1
#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT 0
-#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT)
-#define I40E_PRTTSYN_EVNT_L(_i) (0x001E4080 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT)
+#define I40E_PRTTSYN_EVNT_L(_i) (0x001E4080 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_EVNT_L_MAX_INDEX 1
#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT 0
-#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT)
-#define I40E_PRTTSYN_INC_H 0x001E4060
+#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT)
+#define I40E_PRTTSYN_INC_H 0x001E4060 /* Reset: GLOBR */
#define I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT 0
-#define I40E_PRTTSYN_INC_H_TSYNINC_H_MASK (0x3F << I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT)
-#define I40E_PRTTSYN_INC_L 0x001E4040
+#define I40E_PRTTSYN_INC_H_TSYNINC_H_MASK I40E_MASK(0x3F, I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT)
+#define I40E_PRTTSYN_INC_L 0x001E4040 /* Reset: GLOBR */
#define I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT 0
-#define I40E_PRTTSYN_INC_L_TSYNINC_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT)
-#define I40E_PRTTSYN_RXTIME_H(_i) (0x00085040 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTTSYN_INC_L_TSYNINC_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT)
+#define I40E_PRTTSYN_RXTIME_H(_i) (0x00085040 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PRTTSYN_RXTIME_H_MAX_INDEX 3
#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT)
-#define I40E_PRTTSYN_RXTIME_L(_i) (0x000850C0 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT)
+#define I40E_PRTTSYN_RXTIME_L(_i) (0x000850C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PRTTSYN_RXTIME_L_MAX_INDEX 3
#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT)
-#define I40E_PRTTSYN_STAT_0 0x001E4220
+#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT)
+#define I40E_PRTTSYN_STAT_0 0x001E4220 /* Reset: GLOBR */
#define I40E_PRTTSYN_STAT_0_EVENT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_0_EVENT0_MASK (0x1 << I40E_PRTTSYN_STAT_0_EVENT0_SHIFT)
+#define I40E_PRTTSYN_STAT_0_EVENT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT0_SHIFT)
#define I40E_PRTTSYN_STAT_0_EVENT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_0_EVENT1_MASK (0x1 << I40E_PRTTSYN_STAT_0_EVENT1_SHIFT)
+#define I40E_PRTTSYN_STAT_0_EVENT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT1_SHIFT)
#define I40E_PRTTSYN_STAT_0_TGT0_SHIFT 2
-#define I40E_PRTTSYN_STAT_0_TGT0_MASK (0x1 << I40E_PRTTSYN_STAT_0_TGT0_SHIFT)
+#define I40E_PRTTSYN_STAT_0_TGT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT0_SHIFT)
#define I40E_PRTTSYN_STAT_0_TGT1_SHIFT 3
-#define I40E_PRTTSYN_STAT_0_TGT1_MASK (0x1 << I40E_PRTTSYN_STAT_0_TGT1_SHIFT)
+#define I40E_PRTTSYN_STAT_0_TGT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT1_SHIFT)
#define I40E_PRTTSYN_STAT_0_TXTIME_SHIFT 4
-#define I40E_PRTTSYN_STAT_0_TXTIME_MASK (0x1 << I40E_PRTTSYN_STAT_0_TXTIME_SHIFT)
-#define I40E_PRTTSYN_STAT_1 0x00085140
+#define I40E_PRTTSYN_STAT_0_TXTIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TXTIME_SHIFT)
+#define I40E_PRTTSYN_STAT_1 0x00085140 /* Reset: CORER */
#define I40E_PRTTSYN_STAT_1_RXT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_1_RXT0_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT0_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT0_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_1_RXT1_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT1_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT1_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT2_SHIFT 2
-#define I40E_PRTTSYN_STAT_1_RXT2_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT2_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT2_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT2_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT3_SHIFT 3
-#define I40E_PRTTSYN_STAT_1_RXT3_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT3_SHIFT)
-#define I40E_PRTTSYN_TGT_H(_i) (0x001E4180 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_STAT_1_RXT3_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT3_SHIFT)
+#define I40E_PRTTSYN_TGT_H(_i) (0x001E4180 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_TGT_H_MAX_INDEX 1
#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT 0
-#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT)
-#define I40E_PRTTSYN_TGT_L(_i) (0x001E4140 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT)
+#define I40E_PRTTSYN_TGT_L(_i) (0x001E4140 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_TGT_L_MAX_INDEX 1
#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT 0
-#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT)
-#define I40E_PRTTSYN_TIME_H 0x001E4120
+#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT)
+#define I40E_PRTTSYN_TIME_H 0x001E4120 /* Reset: GLOBR */
#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT 0
-#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT)
-#define I40E_PRTTSYN_TIME_L 0x001E4100
+#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT)
+#define I40E_PRTTSYN_TIME_L 0x001E4100 /* Reset: GLOBR */
#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT 0
-#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT)
-#define I40E_PRTTSYN_TXTIME_H 0x001E41E0
+#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT)
+#define I40E_PRTTSYN_TXTIME_H 0x001E41E0 /* Reset: GLOBR */
#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT)
-#define I40E_PRTTSYN_TXTIME_L 0x001E41C0
+#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT)
+#define I40E_PRTTSYN_TXTIME_L 0x001E41C0 /* Reset: GLOBR */
#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT)
-#define I40E_GLSCD_QUANTA 0x000B2080
+#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT)
+#define I40E_GLSCD_QUANTA 0x000B2080 /* Reset: CORER */
#define I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT 0
-#define I40E_GLSCD_QUANTA_TSCDQUANTA_MASK (0x7 << I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT)
-#define I40E_GL_MDET_RX 0x0012A510
+#define I40E_GLSCD_QUANTA_TSCDQUANTA_MASK I40E_MASK(0x7, I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT)
+#define I40E_GL_MDET_RX 0x0012A510 /* Reset: CORER */
#define I40E_GL_MDET_RX_FUNCTION_SHIFT 0
-#define I40E_GL_MDET_RX_FUNCTION_MASK (0xFF << I40E_GL_MDET_RX_FUNCTION_SHIFT)
+#define I40E_GL_MDET_RX_FUNCTION_MASK I40E_MASK(0xFF, I40E_GL_MDET_RX_FUNCTION_SHIFT)
#define I40E_GL_MDET_RX_EVENT_SHIFT 8
-#define I40E_GL_MDET_RX_EVENT_MASK (0x1FF << I40E_GL_MDET_RX_EVENT_SHIFT)
+#define I40E_GL_MDET_RX_EVENT_MASK I40E_MASK(0x1FF, I40E_GL_MDET_RX_EVENT_SHIFT)
#define I40E_GL_MDET_RX_QUEUE_SHIFT 17
-#define I40E_GL_MDET_RX_QUEUE_MASK (0x3FFF << I40E_GL_MDET_RX_QUEUE_SHIFT)
+#define I40E_GL_MDET_RX_QUEUE_MASK I40E_MASK(0x3FFF, I40E_GL_MDET_RX_QUEUE_SHIFT)
#define I40E_GL_MDET_RX_VALID_SHIFT 31
-#define I40E_GL_MDET_RX_VALID_MASK (0x1 << I40E_GL_MDET_RX_VALID_SHIFT)
-#define I40E_GL_MDET_TX 0x000E6480
-#define I40E_GL_MDET_TX_FUNCTION_SHIFT 0
-#define I40E_GL_MDET_TX_FUNCTION_MASK (0xFF << I40E_GL_MDET_TX_FUNCTION_SHIFT)
-#define I40E_GL_MDET_TX_EVENT_SHIFT 8
-#define I40E_GL_MDET_TX_EVENT_MASK (0x1FF << I40E_GL_MDET_TX_EVENT_SHIFT)
-#define I40E_GL_MDET_TX_QUEUE_SHIFT 17
-#define I40E_GL_MDET_TX_QUEUE_MASK (0x3FFF << I40E_GL_MDET_TX_QUEUE_SHIFT)
+#define I40E_GL_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_GL_MDET_RX_VALID_SHIFT)
+#define I40E_GL_MDET_TX 0x000E6480 /* Reset: CORER */
+#define I40E_GL_MDET_TX_QUEUE_SHIFT 0
+#define I40E_GL_MDET_TX_QUEUE_MASK I40E_MASK(0xFFF, I40E_GL_MDET_TX_QUEUE_SHIFT)
+#define I40E_GL_MDET_TX_VF_NUM_SHIFT 12
+#define I40E_GL_MDET_TX_VF_NUM_MASK I40E_MASK(0x1FF, I40E_GL_MDET_TX_VF_NUM_SHIFT)
+#define I40E_GL_MDET_TX_PF_NUM_SHIFT 21
+#define I40E_GL_MDET_TX_PF_NUM_MASK I40E_MASK(0xF, I40E_GL_MDET_TX_PF_NUM_SHIFT)
+#define I40E_GL_MDET_TX_EVENT_SHIFT 25
+#define I40E_GL_MDET_TX_EVENT_MASK I40E_MASK(0x1F, I40E_GL_MDET_TX_EVENT_SHIFT)
#define I40E_GL_MDET_TX_VALID_SHIFT 31
-#define I40E_GL_MDET_TX_VALID_MASK (0x1 << I40E_GL_MDET_TX_VALID_SHIFT)
-#define I40E_PF_MDET_RX 0x0012A400
+#define I40E_GL_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_GL_MDET_TX_VALID_SHIFT)
+#define I40E_PF_MDET_RX 0x0012A400 /* Reset: CORER */
#define I40E_PF_MDET_RX_VALID_SHIFT 0
-#define I40E_PF_MDET_RX_VALID_MASK (0x1 << I40E_PF_MDET_RX_VALID_SHIFT)
-#define I40E_PF_MDET_TX 0x000E6400
+#define I40E_PF_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_PF_MDET_RX_VALID_SHIFT)
+#define I40E_PF_MDET_TX 0x000E6400 /* Reset: CORER */
#define I40E_PF_MDET_TX_VALID_SHIFT 0
-#define I40E_PF_MDET_TX_VALID_MASK (0x1 << I40E_PF_MDET_TX_VALID_SHIFT)
-#define I40E_PF_VT_PFALLOC 0x001C0500
+#define I40E_PF_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_PF_MDET_TX_VALID_SHIFT)
+#define I40E_PF_VT_PFALLOC 0x001C0500 /* Reset: CORER */
#define I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT 0
-#define I40E_PF_VT_PFALLOC_FIRSTVF_MASK (0xFF << I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT)
+#define I40E_PF_VT_PFALLOC_FIRSTVF_MASK I40E_MASK(0xFF, I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT)
#define I40E_PF_VT_PFALLOC_LASTVF_SHIFT 8
-#define I40E_PF_VT_PFALLOC_LASTVF_MASK (0xFF << I40E_PF_VT_PFALLOC_LASTVF_SHIFT)
+#define I40E_PF_VT_PFALLOC_LASTVF_MASK I40E_MASK(0xFF, I40E_PF_VT_PFALLOC_LASTVF_SHIFT)
#define I40E_PF_VT_PFALLOC_VALID_SHIFT 31
-#define I40E_PF_VT_PFALLOC_VALID_MASK (0x1 << I40E_PF_VT_PFALLOC_VALID_SHIFT)
-#define I40E_VP_MDET_RX(_VF) (0x0012A000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PF_VT_PFALLOC_VALID_MASK I40E_MASK(0x1, I40E_PF_VT_PFALLOC_VALID_SHIFT)
+#define I40E_VP_MDET_RX(_VF) (0x0012A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VP_MDET_RX_MAX_INDEX 127
#define I40E_VP_MDET_RX_VALID_SHIFT 0
-#define I40E_VP_MDET_RX_VALID_MASK (0x1 << I40E_VP_MDET_RX_VALID_SHIFT)
-#define I40E_VP_MDET_TX(_VF) (0x000E6000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VP_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_RX_VALID_SHIFT)
+#define I40E_VP_MDET_TX(_VF) (0x000E6000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VP_MDET_TX_MAX_INDEX 127
#define I40E_VP_MDET_TX_VALID_SHIFT 0
-#define I40E_VP_MDET_TX_VALID_MASK (0x1 << I40E_VP_MDET_TX_VALID_SHIFT)
-#define I40E_GLPM_WUMC 0x0006C800
+#define I40E_VP_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_TX_VALID_SHIFT)
+#define I40E_GLPM_WUMC 0x0006C800 /* Reset: POR */
#define I40E_GLPM_WUMC_NOTCO_SHIFT 0
-#define I40E_GLPM_WUMC_NOTCO_MASK (0x1 << I40E_GLPM_WUMC_NOTCO_SHIFT)
+#define I40E_GLPM_WUMC_NOTCO_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_NOTCO_SHIFT)
#define I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT 1
-#define I40E_GLPM_WUMC_SRST_PIN_VAL_MASK (0x1 << I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT)
+#define I40E_GLPM_WUMC_SRST_PIN_VAL_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT)
#define I40E_GLPM_WUMC_ROL_MODE_SHIFT 2
-#define I40E_GLPM_WUMC_ROL_MODE_MASK (0x1 << I40E_GLPM_WUMC_ROL_MODE_SHIFT)
+#define I40E_GLPM_WUMC_ROL_MODE_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_ROL_MODE_SHIFT)
#define I40E_GLPM_WUMC_RESERVED_4_SHIFT 3
-#define I40E_GLPM_WUMC_RESERVED_4_MASK (0x1FFF << I40E_GLPM_WUMC_RESERVED_4_SHIFT)
+#define I40E_GLPM_WUMC_RESERVED_4_MASK I40E_MASK(0x1FFF, I40E_GLPM_WUMC_RESERVED_4_SHIFT)
#define I40E_GLPM_WUMC_MNG_WU_PF_SHIFT 16
-#define I40E_GLPM_WUMC_MNG_WU_PF_MASK (0xFFFF << I40E_GLPM_WUMC_MNG_WU_PF_SHIFT)
-#define I40E_PFPM_APM 0x000B8080
+#define I40E_GLPM_WUMC_MNG_WU_PF_MASK I40E_MASK(0xFFFF, I40E_GLPM_WUMC_MNG_WU_PF_SHIFT)
+#define I40E_PFPM_APM 0x000B8080 /* Reset: POR */
#define I40E_PFPM_APM_APME_SHIFT 0
-#define I40E_PFPM_APM_APME_MASK (0x1 << I40E_PFPM_APM_APME_SHIFT)
-#define I40E_PFPM_FHFT_LENGTH(_i) (0x0006A000 + ((_i) * 128)) /* _i=0...7 */
+#define I40E_PFPM_APM_APME_MASK I40E_MASK(0x1, I40E_PFPM_APM_APME_SHIFT)
+#define I40E_PFPM_FHFT_LENGTH(_i) (0x0006A000 + ((_i) * 128)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PFPM_FHFT_LENGTH_MAX_INDEX 7
#define I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PFPM_FHFT_LENGTH_LENGTH_MASK (0xFF << I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PFPM_WUC 0x0006B200
+#define I40E_PFPM_FHFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT)
+#define I40E_PFPM_WUC 0x0006B200 /* Reset: POR */
#define I40E_PFPM_WUC_EN_APM_D0_SHIFT 5
-#define I40E_PFPM_WUC_EN_APM_D0_MASK (0x1 << I40E_PFPM_WUC_EN_APM_D0_SHIFT)
-#define I40E_PFPM_WUFC 0x0006B400
+#define I40E_PFPM_WUC_EN_APM_D0_MASK I40E_MASK(0x1, I40E_PFPM_WUC_EN_APM_D0_SHIFT)
+#define I40E_PFPM_WUFC 0x0006B400 /* Reset: POR */
#define I40E_PFPM_WUFC_LNKC_SHIFT 0
-#define I40E_PFPM_WUFC_LNKC_MASK (0x1 << I40E_PFPM_WUFC_LNKC_SHIFT)
+#define I40E_PFPM_WUFC_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_LNKC_SHIFT)
#define I40E_PFPM_WUFC_MAG_SHIFT 1
-#define I40E_PFPM_WUFC_MAG_MASK (0x1 << I40E_PFPM_WUFC_MAG_SHIFT)
+#define I40E_PFPM_WUFC_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MAG_SHIFT)
#define I40E_PFPM_WUFC_MNG_SHIFT 3
-#define I40E_PFPM_WUFC_MNG_MASK (0x1 << I40E_PFPM_WUFC_MNG_SHIFT)
+#define I40E_PFPM_WUFC_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MNG_SHIFT)
#define I40E_PFPM_WUFC_FLX0_ACT_SHIFT 4
-#define I40E_PFPM_WUFC_FLX0_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX0_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX0_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX1_ACT_SHIFT 5
-#define I40E_PFPM_WUFC_FLX1_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX1_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX1_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX2_ACT_SHIFT 6
-#define I40E_PFPM_WUFC_FLX2_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX2_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX2_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX3_ACT_SHIFT 7
-#define I40E_PFPM_WUFC_FLX3_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX3_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX3_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX4_ACT_SHIFT 8
-#define I40E_PFPM_WUFC_FLX4_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX4_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX4_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX5_ACT_SHIFT 9
-#define I40E_PFPM_WUFC_FLX5_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX5_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX5_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX6_ACT_SHIFT 10
-#define I40E_PFPM_WUFC_FLX6_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX6_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX6_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX7_ACT_SHIFT 11
-#define I40E_PFPM_WUFC_FLX7_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX7_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX7_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX0_SHIFT 16
-#define I40E_PFPM_WUFC_FLX0_MASK (0x1 << I40E_PFPM_WUFC_FLX0_SHIFT)
+#define I40E_PFPM_WUFC_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_SHIFT)
#define I40E_PFPM_WUFC_FLX1_SHIFT 17
-#define I40E_PFPM_WUFC_FLX1_MASK (0x1 << I40E_PFPM_WUFC_FLX1_SHIFT)
+#define I40E_PFPM_WUFC_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_SHIFT)
#define I40E_PFPM_WUFC_FLX2_SHIFT 18
-#define I40E_PFPM_WUFC_FLX2_MASK (0x1 << I40E_PFPM_WUFC_FLX2_SHIFT)
+#define I40E_PFPM_WUFC_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_SHIFT)
#define I40E_PFPM_WUFC_FLX3_SHIFT 19
-#define I40E_PFPM_WUFC_FLX3_MASK (0x1 << I40E_PFPM_WUFC_FLX3_SHIFT)
+#define I40E_PFPM_WUFC_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_SHIFT)
#define I40E_PFPM_WUFC_FLX4_SHIFT 20
-#define I40E_PFPM_WUFC_FLX4_MASK (0x1 << I40E_PFPM_WUFC_FLX4_SHIFT)
+#define I40E_PFPM_WUFC_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_SHIFT)
#define I40E_PFPM_WUFC_FLX5_SHIFT 21
-#define I40E_PFPM_WUFC_FLX5_MASK (0x1 << I40E_PFPM_WUFC_FLX5_SHIFT)
+#define I40E_PFPM_WUFC_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_SHIFT)
#define I40E_PFPM_WUFC_FLX6_SHIFT 22
-#define I40E_PFPM_WUFC_FLX6_MASK (0x1 << I40E_PFPM_WUFC_FLX6_SHIFT)
+#define I40E_PFPM_WUFC_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_SHIFT)
#define I40E_PFPM_WUFC_FLX7_SHIFT 23
-#define I40E_PFPM_WUFC_FLX7_MASK (0x1 << I40E_PFPM_WUFC_FLX7_SHIFT)
+#define I40E_PFPM_WUFC_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_SHIFT)
#define I40E_PFPM_WUFC_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUFC_FW_RST_WK_MASK (0x1 << I40E_PFPM_WUFC_FW_RST_WK_SHIFT)
-#define I40E_PFPM_WUS 0x0006B600
+#define I40E_PFPM_WUFC_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FW_RST_WK_SHIFT)
+#define I40E_PFPM_WUS 0x0006B600 /* Reset: POR */
#define I40E_PFPM_WUS_LNKC_SHIFT 0
-#define I40E_PFPM_WUS_LNKC_MASK (0x1 << I40E_PFPM_WUS_LNKC_SHIFT)
+#define I40E_PFPM_WUS_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUS_LNKC_SHIFT)
#define I40E_PFPM_WUS_MAG_SHIFT 1
-#define I40E_PFPM_WUS_MAG_MASK (0x1 << I40E_PFPM_WUS_MAG_SHIFT)
+#define I40E_PFPM_WUS_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MAG_SHIFT)
#define I40E_PFPM_WUS_PME_STATUS_SHIFT 2
-#define I40E_PFPM_WUS_PME_STATUS_MASK (0x1 << I40E_PFPM_WUS_PME_STATUS_SHIFT)
+#define I40E_PFPM_WUS_PME_STATUS_MASK I40E_MASK(0x1, I40E_PFPM_WUS_PME_STATUS_SHIFT)
#define I40E_PFPM_WUS_MNG_SHIFT 3
-#define I40E_PFPM_WUS_MNG_MASK (0x1 << I40E_PFPM_WUS_MNG_SHIFT)
+#define I40E_PFPM_WUS_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MNG_SHIFT)
#define I40E_PFPM_WUS_FLX0_SHIFT 16
-#define I40E_PFPM_WUS_FLX0_MASK (0x1 << I40E_PFPM_WUS_FLX0_SHIFT)
+#define I40E_PFPM_WUS_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX0_SHIFT)
#define I40E_PFPM_WUS_FLX1_SHIFT 17
-#define I40E_PFPM_WUS_FLX1_MASK (0x1 << I40E_PFPM_WUS_FLX1_SHIFT)
+#define I40E_PFPM_WUS_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX1_SHIFT)
#define I40E_PFPM_WUS_FLX2_SHIFT 18
-#define I40E_PFPM_WUS_FLX2_MASK (0x1 << I40E_PFPM_WUS_FLX2_SHIFT)
+#define I40E_PFPM_WUS_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX2_SHIFT)
#define I40E_PFPM_WUS_FLX3_SHIFT 19
-#define I40E_PFPM_WUS_FLX3_MASK (0x1 << I40E_PFPM_WUS_FLX3_SHIFT)
+#define I40E_PFPM_WUS_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX3_SHIFT)
#define I40E_PFPM_WUS_FLX4_SHIFT 20
-#define I40E_PFPM_WUS_FLX4_MASK (0x1 << I40E_PFPM_WUS_FLX4_SHIFT)
+#define I40E_PFPM_WUS_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX4_SHIFT)
#define I40E_PFPM_WUS_FLX5_SHIFT 21
-#define I40E_PFPM_WUS_FLX5_MASK (0x1 << I40E_PFPM_WUS_FLX5_SHIFT)
+#define I40E_PFPM_WUS_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX5_SHIFT)
#define I40E_PFPM_WUS_FLX6_SHIFT 22
-#define I40E_PFPM_WUS_FLX6_MASK (0x1 << I40E_PFPM_WUS_FLX6_SHIFT)
+#define I40E_PFPM_WUS_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX6_SHIFT)
#define I40E_PFPM_WUS_FLX7_SHIFT 23
-#define I40E_PFPM_WUS_FLX7_MASK (0x1 << I40E_PFPM_WUS_FLX7_SHIFT)
+#define I40E_PFPM_WUS_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX7_SHIFT)
#define I40E_PFPM_WUS_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUS_FW_RST_WK_MASK (0x1 << I40E_PFPM_WUS_FW_RST_WK_SHIFT)
-#define I40E_PRTPM_FHFHR 0x0006C000
+#define I40E_PFPM_WUS_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FW_RST_WK_SHIFT)
+#define I40E_PRTPM_FHFHR 0x0006C000 /* Reset: POR */
#define I40E_PRTPM_FHFHR_UNICAST_SHIFT 0
-#define I40E_PRTPM_FHFHR_UNICAST_MASK (0x1 << I40E_PRTPM_FHFHR_UNICAST_SHIFT)
+#define I40E_PRTPM_FHFHR_UNICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_UNICAST_SHIFT)
#define I40E_PRTPM_FHFHR_MULTICAST_SHIFT 1
-#define I40E_PRTPM_FHFHR_MULTICAST_MASK (0x1 << I40E_PRTPM_FHFHR_MULTICAST_SHIFT)
-#define I40E_PRTPM_SAH(_i) (0x001E44C0 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTPM_FHFHR_MULTICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_MULTICAST_SHIFT)
+#define I40E_PRTPM_SAH(_i) (0x001E44C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
#define I40E_PRTPM_SAH_MAX_INDEX 3
#define I40E_PRTPM_SAH_PFPM_SAH_SHIFT 0
-#define I40E_PRTPM_SAH_PFPM_SAH_MASK (0xFFFF << I40E_PRTPM_SAH_PFPM_SAH_SHIFT)
+#define I40E_PRTPM_SAH_PFPM_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTPM_SAH_PFPM_SAH_SHIFT)
#define I40E_PRTPM_SAH_PF_NUM_SHIFT 26
-#define I40E_PRTPM_SAH_PF_NUM_MASK (0xF << I40E_PRTPM_SAH_PF_NUM_SHIFT)
+#define I40E_PRTPM_SAH_PF_NUM_MASK I40E_MASK(0xF, I40E_PRTPM_SAH_PF_NUM_SHIFT)
#define I40E_PRTPM_SAH_MC_MAG_EN_SHIFT 30
-#define I40E_PRTPM_SAH_MC_MAG_EN_MASK (0x1 << I40E_PRTPM_SAH_MC_MAG_EN_SHIFT)
+#define I40E_PRTPM_SAH_MC_MAG_EN_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_MC_MAG_EN_SHIFT)
#define I40E_PRTPM_SAH_AV_SHIFT 31
-#define I40E_PRTPM_SAH_AV_MASK (0x1 << I40E_PRTPM_SAH_AV_SHIFT)
-#define I40E_PRTPM_SAL(_i) (0x001E4440 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTPM_SAH_AV_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_AV_SHIFT)
+#define I40E_PRTPM_SAL(_i) (0x001E4440 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
#define I40E_PRTPM_SAL_MAX_INDEX 3
#define I40E_PRTPM_SAL_PFPM_SAL_SHIFT 0
-#define I40E_PRTPM_SAL_PFPM_SAL_MASK (0xFFFFFFFF << I40E_PRTPM_SAL_PFPM_SAL_SHIFT)
-#define I40E_VF_ARQBAH1 0x00006000
+#define I40E_PRTPM_SAL_PFPM_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_SAL_PFPM_SAL_SHIFT)
+#define I40E_VF_ARQBAH1 0x00006000 /* Reset: EMPR */
#define I40E_VF_ARQBAH1_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH1_ARQBAH_MASK (0xFFFFFFFF << I40E_VF_ARQBAH1_ARQBAH_SHIFT)
-#define I40E_VF_ARQBAL1 0x00006C00
+#define I40E_VF_ARQBAH1_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH1_ARQBAH_SHIFT)
+#define I40E_VF_ARQBAL1 0x00006C00 /* Reset: EMPR */
#define I40E_VF_ARQBAL1_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL1_ARQBAL_MASK (0xFFFFFFFF << I40E_VF_ARQBAL1_ARQBAL_SHIFT)
-#define I40E_VF_ARQH1 0x00007400
+#define I40E_VF_ARQBAL1_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL1_ARQBAL_SHIFT)
+#define I40E_VF_ARQH1 0x00007400 /* Reset: EMPR */
#define I40E_VF_ARQH1_ARQH_SHIFT 0
-#define I40E_VF_ARQH1_ARQH_MASK (0x3FF << I40E_VF_ARQH1_ARQH_SHIFT)
-#define I40E_VF_ARQLEN1 0x00008000
+#define I40E_VF_ARQH1_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH1_ARQH_SHIFT)
+#define I40E_VF_ARQLEN1 0x00008000 /* Reset: EMPR */
#define I40E_VF_ARQLEN1_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN1_ARQLEN_MASK (0x3FF << I40E_VF_ARQLEN1_ARQLEN_SHIFT)
+#define I40E_VF_ARQLEN1_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN1_ARQLEN_SHIFT)
#define I40E_VF_ARQLEN1_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN1_ARQVFE_MASK (0x1 << I40E_VF_ARQLEN1_ARQVFE_SHIFT)
+#define I40E_VF_ARQLEN1_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQVFE_SHIFT)
#define I40E_VF_ARQLEN1_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN1_ARQOVFL_MASK (0x1 << I40E_VF_ARQLEN1_ARQOVFL_SHIFT)
+#define I40E_VF_ARQLEN1_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQOVFL_SHIFT)
#define I40E_VF_ARQLEN1_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN1_ARQCRIT_MASK (0x1 << I40E_VF_ARQLEN1_ARQCRIT_SHIFT)
+#define I40E_VF_ARQLEN1_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQCRIT_SHIFT)
#define I40E_VF_ARQLEN1_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN1_ARQENABLE_MASK (0x1 << I40E_VF_ARQLEN1_ARQENABLE_SHIFT)
-#define I40E_VF_ARQT1 0x00007000
+#define I40E_VF_ARQLEN1_ARQENABLE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQENABLE_SHIFT)
+#define I40E_VF_ARQT1 0x00007000 /* Reset: EMPR */
#define I40E_VF_ARQT1_ARQT_SHIFT 0
-#define I40E_VF_ARQT1_ARQT_MASK (0x3FF << I40E_VF_ARQT1_ARQT_SHIFT)
-#define I40E_VF_ATQBAH1 0x00007800
+#define I40E_VF_ARQT1_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT1_ARQT_SHIFT)
+#define I40E_VF_ATQBAH1 0x00007800 /* Reset: EMPR */
#define I40E_VF_ATQBAH1_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH1_ATQBAH_MASK (0xFFFFFFFF << I40E_VF_ATQBAH1_ATQBAH_SHIFT)
-#define I40E_VF_ATQBAL1 0x00007C00
+#define I40E_VF_ATQBAH1_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH1_ATQBAH_SHIFT)
+#define I40E_VF_ATQBAL1 0x00007C00 /* Reset: EMPR */
#define I40E_VF_ATQBAL1_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL1_ATQBAL_MASK (0xFFFFFFFF << I40E_VF_ATQBAL1_ATQBAL_SHIFT)
-#define I40E_VF_ATQH1 0x00006400
+#define I40E_VF_ATQBAL1_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL1_ATQBAL_SHIFT)
+#define I40E_VF_ATQH1 0x00006400 /* Reset: EMPR */
#define I40E_VF_ATQH1_ATQH_SHIFT 0
-#define I40E_VF_ATQH1_ATQH_MASK (0x3FF << I40E_VF_ATQH1_ATQH_SHIFT)
-#define I40E_VF_ATQLEN1 0x00006800
+#define I40E_VF_ATQH1_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH1_ATQH_SHIFT)
+#define I40E_VF_ATQLEN1 0x00006800 /* Reset: EMPR */
#define I40E_VF_ATQLEN1_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN1_ATQLEN_MASK (0x3FF << I40E_VF_ATQLEN1_ATQLEN_SHIFT)
+#define I40E_VF_ATQLEN1_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN1_ATQLEN_SHIFT)
#define I40E_VF_ATQLEN1_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN1_ATQVFE_MASK (0x1 << I40E_VF_ATQLEN1_ATQVFE_SHIFT)
+#define I40E_VF_ATQLEN1_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQVFE_SHIFT)
#define I40E_VF_ATQLEN1_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN1_ATQOVFL_MASK (0x1 << I40E_VF_ATQLEN1_ATQOVFL_SHIFT)
+#define I40E_VF_ATQLEN1_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQOVFL_SHIFT)
#define I40E_VF_ATQLEN1_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN1_ATQCRIT_MASK (0x1 << I40E_VF_ATQLEN1_ATQCRIT_SHIFT)
+#define I40E_VF_ATQLEN1_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQCRIT_SHIFT)
#define I40E_VF_ATQLEN1_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN1_ATQENABLE_MASK (0x1 << I40E_VF_ATQLEN1_ATQENABLE_SHIFT)
-#define I40E_VF_ATQT1 0x00008400
+#define I40E_VF_ATQLEN1_ATQENABLE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQENABLE_SHIFT)
+#define I40E_VF_ATQT1 0x00008400 /* Reset: EMPR */
#define I40E_VF_ATQT1_ATQT_SHIFT 0
-#define I40E_VF_ATQT1_ATQT_MASK (0x3FF << I40E_VF_ATQT1_ATQT_SHIFT)
-#define I40E_VFGEN_RSTAT 0x00008800
+#define I40E_VF_ATQT1_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT1_ATQT_SHIFT)
+#define I40E_VFGEN_RSTAT 0x00008800 /* Reset: VFR */
#define I40E_VFGEN_RSTAT_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT_VFR_STATE_MASK (0x3 << I40E_VFGEN_RSTAT_VFR_STATE_SHIFT)
-#define I40E_VFINT_DYN_CTL01 0x00005C00
+#define I40E_VFGEN_RSTAT_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT_VFR_STATE_SHIFT)
+#define I40E_VFINT_DYN_CTL01 0x00005C00 /* Reset: VFR */
#define I40E_VFINT_DYN_CTL01_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL01_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTL01_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL01_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL01_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL01_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL01_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTL01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL01_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT)
-#define I40E_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4))
+#define I40E_VFINT_DYN_CTL01_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT)
+#define I40E_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTLN1_MAX_INDEX 15
#define I40E_VFINT_DYN_CTLN1_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN1_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN1_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0_ENA1 0x00005000
+#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
+#define I40E_VFINT_ICR0_ENA1 0x00005000 /* Reset: CORER */
#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA1_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ENA1_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_ENA1_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA1_RSVD_MASK (0x1 << I40E_VFINT_ICR0_ENA1_RSVD_SHIFT)
-#define I40E_VFINT_ICR01 0x00004800
+#define I40E_VFINT_ICR0_ENA1_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_RSVD_SHIFT)
+#define I40E_VFINT_ICR01 0x00004800 /* Reset: CORER */
#define I40E_VFINT_ICR01_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR01_INTEVENT_MASK (0x1 << I40E_VFINT_ICR01_INTEVENT_SHIFT)
+#define I40E_VFINT_ICR01_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_INTEVENT_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR01_QUEUE_0_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_0_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_0_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR01_QUEUE_1_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_1_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_1_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR01_QUEUE_2_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_2_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_2_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR01_QUEUE_3_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_3_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_3_SHIFT)
#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR01_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR01_ADMINQ_MASK (0x1 << I40E_VFINT_ICR01_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR01_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_ADMINQ_SHIFT)
#define I40E_VFINT_ICR01_SWINT_SHIFT 31
-#define I40E_VFINT_ICR01_SWINT_MASK (0x1 << I40E_VFINT_ICR01_SWINT_SHIFT)
-#define I40E_VFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */
+#define I40E_VFINT_ICR01_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_SWINT_SHIFT)
+#define I40E_VFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */ /* Reset: VFR */
#define I40E_VFINT_ITR01_MAX_INDEX 2
#define I40E_VFINT_ITR01_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR01_INTERVAL_MASK (0xFFF << I40E_VFINT_ITR01_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4))
+#define I40E_VFINT_ITR01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR01_INTERVAL_SHIFT)
+#define I40E_VFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...15 */ /* Reset: VFR */
#define I40E_VFINT_ITRN1_MAX_INDEX 2
#define I40E_VFINT_ITRN1_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN1_INTERVAL_MASK (0xFFF << I40E_VFINT_ITRN1_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL01 0x00005400
+#define I40E_VFINT_ITRN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN1_INTERVAL_SHIFT)
+#define I40E_VFINT_STAT_CTL01 0x00005400 /* Reset: VFR */
#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_MASK (0x3 << I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
-#define I40E_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */
+#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
+#define I40E_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_QRX_TAIL1_MAX_INDEX 15
#define I40E_QRX_TAIL1_TAIL_SHIFT 0
-#define I40E_QRX_TAIL1_TAIL_MASK (0x1FFF << I40E_QRX_TAIL1_TAIL_SHIFT)
-#define I40E_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */
+#define I40E_QRX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL1_TAIL_SHIFT)
+#define I40E_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: PFR */
#define I40E_QTX_TAIL1_MAX_INDEX 15
#define I40E_QTX_TAIL1_TAIL_SHIFT 0
-#define I40E_QTX_TAIL1_TAIL_MASK (0x1FFF << I40E_QTX_TAIL1_TAIL_SHIFT)
-#define I40E_VFMSIX_PBA 0x00002000
+#define I40E_QTX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL1_TAIL_SHIFT)
+#define I40E_VFMSIX_PBA 0x00002000 /* Reset: VFLR */
#define I40E_VFMSIX_PBA_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA_PENBIT_MASK (0xFFFFFFFF << I40E_VFMSIX_PBA_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA_PENBIT_SHIFT)
+#define I40E_VFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TADD_MAX_INDEX 16
#define I40E_VFMSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD_MSIXTADD10_MASK (0x3 << I40E_VFMSIX_TADD_MSIXTADD10_SHIFT)
+#define I40E_VFMSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD_MSIXTADD10_SHIFT)
#define I40E_VFMSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD_MSIXTADD_MASK (0x3FFFFFFF << I40E_VFMSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD_MSIXTADD_SHIFT)
+#define I40E_VFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TMSG_MAX_INDEX 16
#define I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG_MSIXTMSG_MASK (0xFFFFFFFF << I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT)
+#define I40E_VFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TUADD_MAX_INDEX 16
#define I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD_MSIXTUADD_MASK (0xFFFFFFFF << I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT)
+#define I40E_VFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TVCTRL_MAX_INDEX 16
#define I40E_VFMSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL_MASK_MASK (0x1 << I40E_VFMSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFCM_PE_ERRDATA 0x0000DC00
+#define I40E_VFMSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL_MASK_SHIFT)
+#define I40E_VFCM_PE_ERRDATA 0x0000DC00 /* Reset: VFR */
#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_MASK (0xF << I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
#define I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA_Q_TYPE_MASK (0x7 << I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT)
#define I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA_Q_NUM_MASK (0x3FFFF << I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO 0x0000D800
+#define I40E_VFCM_PE_ERRDATA_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT)
+#define I40E_VFCM_PE_ERRINFO 0x0000D800 /* Reset: VFR */
#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
#define I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO_ERROR_INST_MASK (0x7 << I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT)
#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_VFPE_AEQALLOC1 0x0000A400
-#define I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC1_AECOUNT_MASK (0xFFFFFFFF << I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH1 0x00009800
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW1 0x0000AC00
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_MASK (0xFFFFFFFF << I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1 0x0000B800
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_MASK (0x1 << I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_MASK (0x1 << I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK1 0x0000B000
-#define I40E_VFPE_CQACK1_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK1_PECQID_MASK (0x1FFFF << I40E_VFPE_CQACK1_PECQID_SHIFT)
-#define I40E_VFPE_CQARM1 0x0000B400
-#define I40E_VFPE_CQARM1_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM1_PECQID_MASK (0x1FFFF << I40E_VFPE_CQARM1_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB1 0x0000BC00
-#define I40E_VFPE_CQPDB1_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB1_WQHEAD_MASK (0x7FF << I40E_VFPE_CQPDB1_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES1 0x00009C00
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL1 0x0000A000
-#define I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL1_WQTAIL_MASK (0x7FF << I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_MASK (0x1 << I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG01 0x00008C00
-#define I40E_VFPE_IPCONFIG01_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG01_PEIPID_MASK (0xFFFF << I40E_VFPE_IPCONFIG01_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_MASK (0x1 << I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK1 0x00009000
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_MASK (0x1F << I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR1 0x00009400
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER1 0x0000A800
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_MASK (0xFFFFFFFF << I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC1 0x0000C000
-#define I40E_VFPE_WQEALLOC1_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC1_PEQPID_MASK (0x3FFFF << I40E_VFPE_WQEALLOC1_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_MASK (0xFFF << I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT)
-#define I40E_VFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */
+#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
+#define I40E_VFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
#define I40E_VFQF_HENA_MAX_INDEX 1
#define I40E_VFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_VFQF_HENA_PTYPE_ENA_SHIFT)
-#define I40E_VFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */
+#define I40E_VFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA_PTYPE_ENA_SHIFT)
+#define I40E_VFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_VFQF_HKEY_MAX_INDEX 12
#define I40E_VFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY_KEY_0_MASK (0xFF << I40E_VFQF_HKEY_KEY_0_SHIFT)
+#define I40E_VFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_0_SHIFT)
#define I40E_VFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY_KEY_1_MASK (0xFF << I40E_VFQF_HKEY_KEY_1_SHIFT)
+#define I40E_VFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_1_SHIFT)
#define I40E_VFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY_KEY_2_MASK (0xFF << I40E_VFQF_HKEY_KEY_2_SHIFT)
+#define I40E_VFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_2_SHIFT)
#define I40E_VFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY_KEY_3_MASK (0xFF << I40E_VFQF_HKEY_KEY_3_SHIFT)
-#define I40E_VFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_VFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_3_SHIFT)
+#define I40E_VFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_VFQF_HLUT_MAX_INDEX 15
#define I40E_VFQF_HLUT_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT_LUT0_MASK (0xF << I40E_VFQF_HLUT_LUT0_SHIFT)
+#define I40E_VFQF_HLUT_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT0_SHIFT)
#define I40E_VFQF_HLUT_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT_LUT1_MASK (0xF << I40E_VFQF_HLUT_LUT1_SHIFT)
+#define I40E_VFQF_HLUT_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT1_SHIFT)
#define I40E_VFQF_HLUT_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT_LUT2_MASK (0xF << I40E_VFQF_HLUT_LUT2_SHIFT)
+#define I40E_VFQF_HLUT_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT2_SHIFT)
#define I40E_VFQF_HLUT_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT_LUT3_MASK (0xF << I40E_VFQF_HLUT_LUT3_SHIFT)
-#define I40E_VFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */
+#define I40E_VFQF_HLUT_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT3_SHIFT)
+#define I40E_VFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_VFQF_HREGION_MAX_INDEX 7
#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
#define I40E_VFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION_REGION_0_MASK (0x7 << I40E_VFQF_HREGION_REGION_0_SHIFT)
+#define I40E_VFQF_HREGION_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_0_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
#define I40E_VFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION_REGION_1_MASK (0x7 << I40E_VFQF_HREGION_REGION_1_SHIFT)
+#define I40E_VFQF_HREGION_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_1_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
#define I40E_VFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION_REGION_2_MASK (0x7 << I40E_VFQF_HREGION_REGION_2_SHIFT)
+#define I40E_VFQF_HREGION_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_2_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
#define I40E_VFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION_REGION_3_MASK (0x7 << I40E_VFQF_HREGION_REGION_3_SHIFT)
+#define I40E_VFQF_HREGION_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_3_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
#define I40E_VFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION_REGION_4_MASK (0x7 << I40E_VFQF_HREGION_REGION_4_SHIFT)
+#define I40E_VFQF_HREGION_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_4_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
#define I40E_VFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION_REGION_5_MASK (0x7 << I40E_VFQF_HREGION_REGION_5_SHIFT)
+#define I40E_VFQF_HREGION_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_5_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
#define I40E_VFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION_REGION_6_MASK (0x7 << I40E_VFQF_HREGION_REGION_6_SHIFT)
+#define I40E_VFQF_HREGION_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_6_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
#define I40E_VFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION_REGION_7_MASK (0x7 << I40E_VFQF_HREGION_REGION_7_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS 0x00270110
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_SHIFT 0
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_SHIFT 8
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_SHIFT 16
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_SHIFT 24
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_MASK (0x7 << I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_SHIFT)
+#define I40E_VFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_7_SHIFT)
#endif
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index e49f31dbd5d8..a51aa37b7b5a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -39,6 +39,7 @@ static inline __le64 build_ctob(u32 td_cmd, u32 td_offset, unsigned int size,
}
#define I40E_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS)
+#define I40E_FD_CLEAN_DELAY 10
/**
* i40e_program_fdir_filter - Program a Flow Director filter
* @fdir_data: Packet data that will be filter parameters
@@ -50,7 +51,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
struct i40e_pf *pf, bool add)
{
struct i40e_filter_program_desc *fdir_desc;
- struct i40e_tx_buffer *tx_buf;
+ struct i40e_tx_buffer *tx_buf, *first;
struct i40e_tx_desc *tx_desc;
struct i40e_ring *tx_ring;
unsigned int fpt, dcc;
@@ -58,6 +59,7 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
struct device *dev;
dma_addr_t dma;
u32 td_cmd = 0;
+ u16 delay = 0;
u16 i;
/* find existing FDIR VSI */
@@ -71,6 +73,17 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
tx_ring = vsi->tx_rings[0];
dev = tx_ring->dev;
+ /* we need two descriptors to add/del a filter and we can wait */
+ do {
+ if (I40E_DESC_UNUSED(tx_ring) > 1)
+ break;
+ msleep_interruptible(1);
+ delay++;
+ } while (delay < I40E_FD_CLEAN_DELAY);
+
+ if (!(I40E_DESC_UNUSED(tx_ring) > 1))
+ return -EAGAIN;
+
dma = dma_map_single(dev, raw_packet,
I40E_FDIR_MAX_RAW_PACKET_SIZE, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma))
@@ -79,8 +92,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
/* grab the next descriptor */
i = tx_ring->next_to_use;
fdir_desc = I40E_TX_FDIRDESC(tx_ring, i);
+ first = &tx_ring->tx_bi[i];
+ memset(first, 0, sizeof(struct i40e_tx_buffer));
- tx_ring->next_to_use = (i + 1 < tx_ring->count) ? i + 1 : 0;
+ tx_ring->next_to_use = ((i + 1) < tx_ring->count) ? i + 1 : 0;
fpt = (fdir_data->q_index << I40E_TXD_FLTR_QW0_QINDEX_SHIFT) &
I40E_TXD_FLTR_QW0_QINDEX_MASK;
@@ -100,8 +115,6 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT) &
I40E_TXD_FLTR_QW0_DEST_VSI_MASK;
- fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(fpt);
-
dcc = I40E_TX_DESC_DTYPE_FILTER_PROG;
if (add)
@@ -124,6 +137,8 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
I40E_TXD_FLTR_QW1_CNTINDEX_MASK;
}
+ fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(fpt);
+ fdir_desc->rsvd = cpu_to_le32(0);
fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dcc);
fdir_desc->fd_id = cpu_to_le32(fdir_data->fd_id);
@@ -132,7 +147,9 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
tx_desc = I40E_TX_DESC(tx_ring, i);
tx_buf = &tx_ring->tx_bi[i];
- tx_ring->next_to_use = (i + 1 < tx_ring->count) ? i + 1 : 0;
+ tx_ring->next_to_use = ((i + 1) < tx_ring->count) ? i + 1 : 0;
+
+ memset(tx_buf, 0, sizeof(struct i40e_tx_buffer));
/* record length, and DMA address */
dma_unmap_len_set(tx_buf, len, I40E_FDIR_MAX_RAW_PACKET_SIZE);
@@ -141,6 +158,9 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
tx_desc->buffer_addr = cpu_to_le64(dma);
td_cmd = I40E_TXD_CMD | I40E_TX_DESC_CMD_DUMMY;
+ tx_buf->tx_flags = I40E_TX_FLAGS_FD_SB;
+ tx_buf->raw_buf = (void *)raw_packet;
+
tx_desc->cmd_type_offset_bsz =
build_ctob(td_cmd, 0, I40E_FDIR_MAX_RAW_PACKET_SIZE, 0);
@@ -148,14 +168,12 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
tx_buf->time_stamp = jiffies;
/* Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
+ * know there are new descriptors to fetch.
*/
wmb();
/* Mark the data descriptor to be watched */
- tx_buf->next_to_watch = tx_desc;
+ first->next_to_watch = tx_desc;
writel(tx_ring->next_to_use, tx_ring->tail);
return 0;
@@ -170,24 +188,27 @@ dma_fail:
* i40e_add_del_fdir_udpv4 - Add/Remove UDPv4 filters
* @vsi: pointer to the targeted VSI
* @fd_data: the flow director data required for the FDir descriptor
- * @raw_packet: the pre-allocated packet buffer for FDir
* @add: true adds a filter, false removes it
*
* Returns 0 if the filters were successfully added or removed
**/
static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
struct i40e_fdir_filter *fd_data,
- u8 *raw_packet, bool add)
+ bool add)
{
struct i40e_pf *pf = vsi->back;
struct udphdr *udp;
struct iphdr *ip;
bool err = false;
+ u8 *raw_packet;
int ret;
static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
0x45, 0, 0, 0x1c, 0, 0, 0x40, 0, 0x40, 0x11, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
+ if (!raw_packet)
+ return -ENOMEM;
memcpy(raw_packet, packet, I40E_UDPIP_DUMMY_PACKET_LEN);
ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
@@ -220,19 +241,19 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
* i40e_add_del_fdir_tcpv4 - Add/Remove TCPv4 filters
* @vsi: pointer to the targeted VSI
* @fd_data: the flow director data required for the FDir descriptor
- * @raw_packet: the pre-allocated packet buffer for FDir
* @add: true adds a filter, false removes it
*
* Returns 0 if the filters were successfully added or removed
**/
static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
struct i40e_fdir_filter *fd_data,
- u8 *raw_packet, bool add)
+ bool add)
{
struct i40e_pf *pf = vsi->back;
struct tcphdr *tcp;
struct iphdr *ip;
bool err = false;
+ u8 *raw_packet;
int ret;
/* Dummy packet */
static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
@@ -240,6 +261,9 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x11,
0x0, 0x72, 0, 0, 0, 0};
+ raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
+ if (!raw_packet)
+ return -ENOMEM;
memcpy(raw_packet, packet, I40E_TCPIP_DUMMY_PACKET_LEN);
ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
@@ -271,19 +295,6 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
fd_data->pctype, ret);
}
- fd_data->pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-
- ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add);
- if (ret) {
- dev_info(&pf->pdev->dev,
- "Filter command send failed for PCTYPE %d (ret = %d)\n",
- fd_data->pctype, ret);
- err = true;
- } else {
- dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d (ret = %d)\n",
- fd_data->pctype, ret);
- }
-
return err ? -EOPNOTSUPP : 0;
}
@@ -292,14 +303,13 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
* a specific flow spec
* @vsi: pointer to the targeted VSI
* @fd_data: the flow director data required for the FDir descriptor
- * @raw_packet: the pre-allocated packet buffer for FDir
* @add: true adds a filter, false removes it
*
* Always returns -EOPNOTSUPP
**/
static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
struct i40e_fdir_filter *fd_data,
- u8 *raw_packet, bool add)
+ bool add)
{
return -EOPNOTSUPP;
}
@@ -310,33 +320,36 @@ static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi,
* a specific flow spec
* @vsi: pointer to the targeted VSI
* @fd_data: the flow director data required for the FDir descriptor
- * @raw_packet: the pre-allocated packet buffer for FDir
* @add: true adds a filter, false removes it
*
* Returns 0 if the filters were successfully added or removed
**/
static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi,
struct i40e_fdir_filter *fd_data,
- u8 *raw_packet, bool add)
+ bool add)
{
struct i40e_pf *pf = vsi->back;
struct iphdr *ip;
bool err = false;
+ u8 *raw_packet;
int ret;
int i;
static char packet[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0,
0x45, 0, 0, 0x14, 0, 0, 0x40, 0, 0x40, 0x10, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
- memcpy(raw_packet, packet, I40E_IP_DUMMY_PACKET_LEN);
- ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
-
- ip->saddr = fd_data->src_ip[0];
- ip->daddr = fd_data->dst_ip[0];
- ip->protocol = 0;
-
for (i = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
i <= I40E_FILTER_PCTYPE_FRAG_IPV4; i++) {
+ raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
+ if (!raw_packet)
+ return -ENOMEM;
+ memcpy(raw_packet, packet, I40E_IP_DUMMY_PACKET_LEN);
+ ip = (struct iphdr *)(raw_packet + IP_HEADER_OFFSET);
+
+ ip->saddr = fd_data->src_ip[0];
+ ip->daddr = fd_data->dst_ip[0];
+ ip->protocol = 0;
+
fd_data->pctype = i;
ret = i40e_program_fdir_filter(fd_data, raw_packet, pf, add);
@@ -366,50 +379,34 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input, bool add)
{
struct i40e_pf *pf = vsi->back;
- u8 *raw_packet;
int ret;
- /* Populate the Flow Director that we have at the moment
- * and allocate the raw packet buffer for the calling functions
- */
- raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_SIZE, GFP_KERNEL);
- if (!raw_packet)
- return -ENOMEM;
-
switch (input->flow_type & ~FLOW_EXT) {
case TCP_V4_FLOW:
- ret = i40e_add_del_fdir_tcpv4(vsi, input, raw_packet,
- add);
+ ret = i40e_add_del_fdir_tcpv4(vsi, input, add);
break;
case UDP_V4_FLOW:
- ret = i40e_add_del_fdir_udpv4(vsi, input, raw_packet,
- add);
+ ret = i40e_add_del_fdir_udpv4(vsi, input, add);
break;
case SCTP_V4_FLOW:
- ret = i40e_add_del_fdir_sctpv4(vsi, input, raw_packet,
- add);
+ ret = i40e_add_del_fdir_sctpv4(vsi, input, add);
break;
case IPV4_FLOW:
- ret = i40e_add_del_fdir_ipv4(vsi, input, raw_packet,
- add);
+ ret = i40e_add_del_fdir_ipv4(vsi, input, add);
break;
case IP_USER_FLOW:
switch (input->ip4_proto) {
case IPPROTO_TCP:
- ret = i40e_add_del_fdir_tcpv4(vsi, input,
- raw_packet, add);
+ ret = i40e_add_del_fdir_tcpv4(vsi, input, add);
break;
case IPPROTO_UDP:
- ret = i40e_add_del_fdir_udpv4(vsi, input,
- raw_packet, add);
+ ret = i40e_add_del_fdir_udpv4(vsi, input, add);
break;
case IPPROTO_SCTP:
- ret = i40e_add_del_fdir_sctpv4(vsi, input,
- raw_packet, add);
+ ret = i40e_add_del_fdir_sctpv4(vsi, input, add);
break;
default:
- ret = i40e_add_del_fdir_ipv4(vsi, input,
- raw_packet, add);
+ ret = i40e_add_del_fdir_ipv4(vsi, input, add);
break;
}
break;
@@ -419,7 +416,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
ret = -EINVAL;
}
- kfree(raw_packet);
+ /* The buffer allocated here is freed by the i40e_clean_tx_ring() */
return ret;
}
@@ -450,22 +447,24 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
rx_desc->wb.qword0.hi_dword.fd_id);
/* filter programming failed most likely due to table full */
- fcnt_prog = i40e_get_current_fd_count(pf);
- fcnt_avail = i40e_get_fd_cnt_all(pf);
+ fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
+ fcnt_avail = pf->fdir_pf_filter_count;
/* If ATR is running fcnt_prog can quickly change,
* if we are very close to full, it makes sense to disable
* FD ATR/SB and then re-enable it when there is room.
*/
if (fcnt_prog >= (fcnt_avail - I40E_FDIR_BUFFER_FULL_MARGIN)) {
/* Turn off ATR first */
- if (pf->flags & I40E_FLAG_FD_ATR_ENABLED) {
- pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
+ if ((pf->flags & I40E_FLAG_FD_ATR_ENABLED) &&
+ !(pf->auto_disable_flags &
+ I40E_FLAG_FD_ATR_ENABLED)) {
dev_warn(&pdev->dev, "FD filter space full, ATR for further flows will be turned off\n");
pf->auto_disable_flags |=
I40E_FLAG_FD_ATR_ENABLED;
pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
- } else if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
- pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
+ } else if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
+ !(pf->auto_disable_flags &
+ I40E_FLAG_FD_SB_ENABLED)) {
dev_warn(&pdev->dev, "FD filter space full, new ntuple rules will not be added\n");
pf->auto_disable_flags |=
I40E_FLAG_FD_SB_ENABLED;
@@ -491,7 +490,11 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
struct i40e_tx_buffer *tx_buffer)
{
if (tx_buffer->skb) {
- dev_kfree_skb_any(tx_buffer->skb);
+ if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+ kfree(tx_buffer->raw_buf);
+ else
+ dev_kfree_skb_any(tx_buffer->skb);
+
if (dma_unmap_len(tx_buffer, len))
dma_unmap_single(ring->dev,
dma_unmap_addr(tx_buffer, dma),
@@ -893,6 +896,11 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring,
if (id == I40E_RX_PROG_STATUS_DESC_FD_FILTER_STATUS)
i40e_fd_handle_status(rx_ring, rx_desc, id);
+#ifdef I40E_FCOE
+ else if ((id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS) ||
+ (id == I40E_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS))
+ i40e_fcoe_handle_status(rx_ring, rx_desc, id);
+#endif
}
/**
@@ -1234,8 +1242,6 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
/* likely incorrect csum if alternate IP extension headers found */
if (ipv6 &&
- decoded.inner_prot == I40E_RX_PTYPE_INNER_PROT_TCP &&
- rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) &&
rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
/* don't increment checksum err here, non-fatal err */
return;
@@ -1488,6 +1494,12 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
vlan_tag = rx_status & (1 << I40E_RX_DESC_STATUS_L2TAG1P_SHIFT)
? le16_to_cpu(rx_desc->wb.qword0.lo_dword.l2tag1)
: 0;
+#ifdef I40E_FCOE
+ if (!i40e_fcoe_handle_offload(rx_ring, rx_desc, skb)) {
+ dev_kfree_skb_any(skb);
+ goto next_desc;
+ }
+#endif
i40e_receive_skb(rx_ring, skb, vlan_tag);
rx_ring->netdev->last_rx = jiffies;
@@ -1701,7 +1713,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
I40E_TXD_FLTR_QW1_CNTINDEX_MASK;
fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype);
+ fdir_desc->rsvd = cpu_to_le32(0);
fdir_desc->dtype_cmd_cntindex = cpu_to_le32(dtype_cmd);
+ fdir_desc->fd_id = cpu_to_le32(0);
}
/**
@@ -1716,9 +1730,15 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
* Returns error code indicate the frame should be dropped upon error and the
* otherwise returns 0 to indicate the flags has been set properly.
**/
+#ifdef I40E_FCOE
+int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
+ struct i40e_ring *tx_ring,
+ u32 *flags)
+#else
static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
struct i40e_ring *tx_ring,
u32 *flags)
+#endif
{
__be16 protocol = skb->protocol;
u32 tx_flags = 0;
@@ -1740,9 +1760,8 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
}
/* Insert 802.1p priority into VLAN header */
- if ((tx_ring->vsi->back->flags & I40E_FLAG_DCB_ENABLED) &&
- ((tx_flags & (I40E_TX_FLAGS_HW_VLAN | I40E_TX_FLAGS_SW_VLAN)) ||
- (skb->priority != TC_PRIO_CONTROL))) {
+ if ((tx_flags & (I40E_TX_FLAGS_HW_VLAN | I40E_TX_FLAGS_SW_VLAN)) ||
+ (skb->priority != TC_PRIO_CONTROL)) {
tx_flags &= ~I40E_TX_FLAGS_VLAN_PRIO_MASK;
tx_flags |= (skb->priority & 0x7) <<
I40E_TX_FLAGS_VLAN_PRIO_SHIFT;
@@ -1850,7 +1869,8 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
* we are not already transmitting a packet to be timestamped
*/
pf = i40e_netdev_to_pf(tx_ring->netdev);
- if (pf->ptp_tx && !pf->ptp_tx_skb) {
+ if (pf->ptp_tx &&
+ !test_and_set_bit_lock(__I40E_PTP_TX_IN_PROGRESS, &pf->state)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
pf->ptp_tx_skb = skb_get(skb);
} else {
@@ -2000,6 +2020,7 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring,
/* cpu_to_le32 and assign to struct fields */
context_desc->tunneling_params = cpu_to_le32(cd_tunneling);
context_desc->l2tag2 = cpu_to_le16(cd_l2tag2);
+ context_desc->rsvd = cpu_to_le16(0);
context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);
}
@@ -2013,9 +2034,15 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring,
* @td_cmd: the command field in the descriptor
* @td_offset: offset for checksum or crc
**/
+#ifdef I40E_FCOE
+void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
+ struct i40e_tx_buffer *first, u32 tx_flags,
+ const u8 hdr_len, u32 td_cmd, u32 td_offset)
+#else
static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
struct i40e_tx_buffer *first, u32 tx_flags,
const u8 hdr_len, u32 td_cmd, u32 td_offset)
+#endif
{
unsigned int data_len = skb->data_len;
unsigned int size = skb_headlen(skb);
@@ -2192,7 +2219,11 @@ static inline int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
*
* Returns 0 if stop is not needed
**/
+#ifdef I40E_FCOE
+int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+#else
static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
+#endif
{
if (likely(I40E_DESC_UNUSED(tx_ring) >= size))
return 0;
@@ -2208,8 +2239,13 @@ static int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size)
* there is not enough descriptors available in this ring since we need at least
* one descriptor.
**/
+#ifdef I40E_FCOE
+int i40e_xmit_descriptor_count(struct sk_buff *skb,
+ struct i40e_ring *tx_ring)
+#else
static int i40e_xmit_descriptor_count(struct sk_buff *skb,
struct i40e_ring *tx_ring)
+#endif
{
unsigned int f;
int count = 0;
@@ -2278,13 +2314,13 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
else if (tso)
tx_flags |= I40E_TX_FLAGS_TSO;
- skb_tx_timestamp(skb);
-
tsyn = i40e_tsyn(tx_ring, skb, tx_flags, &cd_type_cmd_tso_mss);
if (tsyn)
tx_flags |= I40E_TX_FLAGS_TSYN;
+ skb_tx_timestamp(skb);
+
/* always enable CRC insertion offload */
td_cmd |= I40E_TX_DESC_CMD_ICRC;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index 0277894fe1c4..73f4fa425697 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -75,7 +75,6 @@ enum i40e_dyn_idx_t {
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) | \
((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | \
- ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) | \
@@ -132,6 +131,7 @@ enum i40e_dyn_idx_t {
#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6)
#define I40E_TX_FLAGS_FSO (u32)(1 << 7)
#define I40E_TX_FLAGS_TSYN (u32)(1 << 8)
+#define I40E_TX_FLAGS_FD_SB (u32)(1 << 9)
#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000
#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -140,7 +140,10 @@ enum i40e_dyn_idx_t {
struct i40e_tx_buffer {
struct i40e_tx_desc *next_to_watch;
unsigned long time_stamp;
- struct sk_buff *skb;
+ union {
+ struct sk_buff *skb;
+ void *raw_buf;
+ };
unsigned int bytecount;
unsigned short gso_segs;
DEFINE_DMA_UNMAP_ADDR(dma);
@@ -287,4 +290,13 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring);
void i40e_free_tx_resources(struct i40e_ring *tx_ring);
void i40e_free_rx_resources(struct i40e_ring *rx_ring);
int i40e_napi_poll(struct napi_struct *napi, int budget);
+#ifdef I40E_FCOE
+void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
+ struct i40e_tx_buffer *first, u32 tx_flags,
+ const u8 hdr_len, u32 td_cmd, u32 td_offset);
+int i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
+int i40e_xmit_descriptor_count(struct sk_buff *skb, struct i40e_ring *tx_ring);
+int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
+ struct i40e_ring *tx_ring, u32 *flags);
+#endif
#endif /* _I40E_TXRX_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 9d39ff23c5fb..ce04d9093db6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -50,6 +50,9 @@
(d) == I40E_DEV_ID_QSFP_B || \
(d) == I40E_DEV_ID_QSFP_C)
+/* I40E_MASK is a macro used on 32 bit registers */
+#define I40E_MASK(mask, shift) (mask << shift)
+
#define I40E_MAX_VSI_QP 16
#define I40E_MAX_VF_VSI 3
#define I40E_MAX_CHAINED_RX_BUFFERS 5
@@ -137,6 +140,14 @@ enum i40e_fc_mode {
I40E_FC_DEFAULT
};
+enum i40e_set_fc_aq_failures {
+ I40E_SET_FC_AQ_FAIL_NONE = 0,
+ I40E_SET_FC_AQ_FAIL_GET = 1,
+ I40E_SET_FC_AQ_FAIL_SET = 2,
+ I40E_SET_FC_AQ_FAIL_UPDATE = 4,
+ I40E_SET_FC_AQ_FAIL_SET_UPDATE = 6
+};
+
enum i40e_vsi_type {
I40E_VSI_MAIN = 0,
I40E_VSI_VMDQ1,
@@ -163,6 +174,7 @@ struct i40e_link_status {
u8 an_info;
u8 ext_info;
u8 loopback;
+ bool an_enabled;
/* is Link Status Event notification to SW enabled */
bool lse_enable;
u16 max_frame_size;
@@ -234,6 +246,7 @@ struct i40e_mac_info {
u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN];
u8 san_addr[ETH_ALEN];
+ u8 port_addr[ETH_ALEN];
u16 max_fcoeq;
};
@@ -256,6 +269,61 @@ struct i40e_nvm_info {
u32 eetrack; /* NVM data version */
};
+/* definitions used in NVM update support */
+
+enum i40e_nvmupd_cmd {
+ I40E_NVMUPD_INVALID,
+ I40E_NVMUPD_READ_CON,
+ I40E_NVMUPD_READ_SNT,
+ I40E_NVMUPD_READ_LCB,
+ I40E_NVMUPD_READ_SA,
+ I40E_NVMUPD_WRITE_ERA,
+ I40E_NVMUPD_WRITE_CON,
+ I40E_NVMUPD_WRITE_SNT,
+ I40E_NVMUPD_WRITE_LCB,
+ I40E_NVMUPD_WRITE_SA,
+ I40E_NVMUPD_CSUM_CON,
+ I40E_NVMUPD_CSUM_SA,
+ I40E_NVMUPD_CSUM_LCB,
+};
+
+enum i40e_nvmupd_state {
+ I40E_NVMUPD_STATE_INIT,
+ I40E_NVMUPD_STATE_READING,
+ I40E_NVMUPD_STATE_WRITING
+};
+
+/* nvm_access definition and its masks/shifts need to be accessible to
+ * application, core driver, and shared code. Where is the right file?
+ */
+#define I40E_NVM_READ 0xB
+#define I40E_NVM_WRITE 0xC
+
+#define I40E_NVM_MOD_PNT_MASK 0xFF
+
+#define I40E_NVM_TRANS_SHIFT 8
+#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
+#define I40E_NVM_CON 0x0
+#define I40E_NVM_SNT 0x1
+#define I40E_NVM_LCB 0x2
+#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
+#define I40E_NVM_ERA 0x4
+#define I40E_NVM_CSUM 0x8
+
+#define I40E_NVM_ADAPT_SHIFT 16
+#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
+
+#define I40E_NVMUPD_MAX_DATA 4096
+#define I40E_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
+
+struct i40e_nvm_access {
+ u32 command;
+ u32 config;
+ u32 offset; /* in bytes */
+ u32 data_size; /* in bytes */
+ u8 data[1];
+};
+
/* PCI bus types */
enum i40e_bus_type {
i40e_bus_type_unknown = 0,
@@ -391,6 +459,9 @@ struct i40e_hw {
/* Admin Queue info */
struct i40e_adminq_info aq;
+ /* state of nvm update process */
+ enum i40e_nvmupd_state nvmupd_state;
+
/* HMC info */
struct i40e_hmc_info hmc; /* HMC info struct */
@@ -875,7 +946,6 @@ enum i40e_filter_pctype {
I40E_FILTER_PCTYPE_FRAG_IPV4 = 36,
/* Note: Values 37-40 are reserved for future use */
I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41,
- I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN = 42,
I40E_FILTER_PCTYPE_NONF_IPV6_TCP = 43,
I40E_FILTER_PCTYPE_NONF_IPV6_SCTP = 44,
I40E_FILTER_PCTYPE_NONF_IPV6_OTHER = 45,
@@ -981,6 +1051,25 @@ struct i40e_eth_stats {
u64 tx_errors; /* tepc */
};
+#ifdef I40E_FCOE
+/* Statistics collected per function for FCoE */
+struct i40e_fcoe_stats {
+ u64 rx_fcoe_packets; /* fcoeprc */
+ u64 rx_fcoe_dwords; /* focedwrc */
+ u64 rx_fcoe_dropped; /* fcoerpdc */
+ u64 tx_fcoe_packets; /* fcoeptc */
+ u64 tx_fcoe_dwords; /* focedwtc */
+ u64 fcoe_bad_fccrc; /* fcoecrc */
+ u64 fcoe_last_error; /* fcoelast */
+ u64 fcoe_ddp_count; /* fcoeddpc */
+};
+
+/* offset to per function FCoE statistics block */
+#define I40E_FCOE_VF_STAT_OFFSET 0
+#define I40E_FCOE_PF_STAT_OFFSET 128
+#define I40E_FCOE_STAT_MAX (I40E_FCOE_PF_STAT_OFFSET + I40E_MAX_PF)
+
+#endif
/* Statistics collected by the MAC */
struct i40e_hw_port_stats {
/* eth stats collected by the port */
@@ -1061,6 +1150,125 @@ struct i40e_hw_port_stats {
#define I40E_SRRD_SRCTL_ATTEMPTS 100000
+#ifdef I40E_FCOE
+/* FCoE Tx context descriptor - Use the i40e_tx_context_desc struct */
+
+enum i40E_fcoe_tx_ctx_desc_cmd_bits {
+ I40E_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND = 0x00, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2 = 0x01, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3 = 0x05, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS2 = 0x02, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS3 = 0x06, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS2 = 0x03, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS3 = 0x07, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL = 0x08, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_OPCODE_DWO_CTX_INVL = 0x09, /* 4 BITS */
+ I40E_FCOE_TX_CTX_DESC_RELOFF = 0x10,
+ I40E_FCOE_TX_CTX_DESC_CLRSEQ = 0x20,
+ I40E_FCOE_TX_CTX_DESC_DIFENA = 0x40,
+ I40E_FCOE_TX_CTX_DESC_IL2TAG2 = 0x80
+};
+
+/* FCoE DDP Context descriptor */
+struct i40e_fcoe_ddp_context_desc {
+ __le64 rsvd;
+ __le64 type_cmd_foff_lsize;
+};
+
+#define I40E_FCOE_DDP_CTX_QW1_DTYPE_SHIFT 0
+#define I40E_FCOE_DDP_CTX_QW1_DTYPE_MASK (0xFULL << \
+ I40E_FCOE_DDP_CTX_QW1_DTYPE_SHIFT)
+
+#define I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT 4
+#define I40E_FCOE_DDP_CTX_QW1_CMD_MASK (0xFULL << \
+ I40E_FCOE_DDP_CTX_QW1_CMD_SHIFT)
+
+enum i40e_fcoe_ddp_ctx_desc_cmd_bits {
+ I40E_FCOE_DDP_CTX_DESC_BSIZE_512B = 0x00, /* 2 BITS */
+ I40E_FCOE_DDP_CTX_DESC_BSIZE_4K = 0x01, /* 2 BITS */
+ I40E_FCOE_DDP_CTX_DESC_BSIZE_8K = 0x02, /* 2 BITS */
+ I40E_FCOE_DDP_CTX_DESC_BSIZE_16K = 0x03, /* 2 BITS */
+ I40E_FCOE_DDP_CTX_DESC_DIFENA = 0x04, /* 1 BIT */
+ I40E_FCOE_DDP_CTX_DESC_LASTSEQH = 0x08, /* 1 BIT */
+};
+
+#define I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT 16
+#define I40E_FCOE_DDP_CTX_QW1_FOFF_MASK (0x3FFFULL << \
+ I40E_FCOE_DDP_CTX_QW1_FOFF_SHIFT)
+
+#define I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT 32
+#define I40E_FCOE_DDP_CTX_QW1_LSIZE_MASK (0x3FFFULL << \
+ I40E_FCOE_DDP_CTX_QW1_LSIZE_SHIFT)
+
+/* FCoE DDP/DWO Queue Context descriptor */
+struct i40e_fcoe_queue_context_desc {
+ __le64 dmaindx_fbase; /* 0:11 DMAINDX, 12:63 FBASE */
+ __le64 flen_tph; /* 0:12 FLEN, 13:15 TPH */
+};
+
+#define I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT 0
+#define I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_MASK (0xFFFULL << \
+ I40E_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT)
+
+#define I40E_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT 12
+#define I40E_FCOE_QUEUE_CTX_QW0_FBASE_MASK (0xFFFFFFFFFFFFFULL << \
+ I40E_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT)
+
+#define I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT 0
+#define I40E_FCOE_QUEUE_CTX_QW1_FLEN_MASK (0x1FFFULL << \
+ I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
+
+#define I40E_FCOE_QUEUE_CTX_QW1_TPH_SHIFT 13
+#define I40E_FCOE_QUEUE_CTX_QW1_TPH_MASK (0x7ULL << \
+ I40E_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
+
+enum i40e_fcoe_queue_ctx_desc_tph_bits {
+ I40E_FCOE_QUEUE_CTX_DESC_TPHRDESC = 0x1,
+ I40E_FCOE_QUEUE_CTX_DESC_TPHDATA = 0x2
+};
+
+#define I40E_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT 30
+#define I40E_FCOE_QUEUE_CTX_QW1_RECIPE_MASK (0x3ULL << \
+ I40E_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT)
+
+/* FCoE DDP/DWO Filter Context descriptor */
+struct i40e_fcoe_filter_context_desc {
+ __le32 param;
+ __le16 seqn;
+
+ /* 48:51(0:3) RSVD, 52:63(4:15) DMAINDX */
+ __le16 rsvd_dmaindx;
+
+ /* 0:7 FLAGS, 8:52 RSVD, 53:63 LANQ */
+ __le64 flags_rsvd_lanq;
+};
+
+#define I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT 4
+#define I40E_FCOE_FILTER_CTX_QW0_DMAINDX_MASK (0xFFF << \
+ I40E_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT)
+
+enum i40e_fcoe_filter_ctx_desc_flags_bits {
+ I40E_FCOE_FILTER_CTX_DESC_CTYP_DDP = 0x00,
+ I40E_FCOE_FILTER_CTX_DESC_CTYP_DWO = 0x01,
+ I40E_FCOE_FILTER_CTX_DESC_ENODE_INIT = 0x00,
+ I40E_FCOE_FILTER_CTX_DESC_ENODE_RSP = 0x02,
+ I40E_FCOE_FILTER_CTX_DESC_FC_CLASS2 = 0x00,
+ I40E_FCOE_FILTER_CTX_DESC_FC_CLASS3 = 0x04
+};
+
+#define I40E_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT 0
+#define I40E_FCOE_FILTER_CTX_QW1_FLAGS_MASK (0xFFULL << \
+ I40E_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT)
+
+#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT 8
+#define I40E_FCOE_FILTER_CTX_QW1_PCTYPE_MASK (0x3FULL << \
+ I40E_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT)
+
+#define I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT 53
+#define I40E_FCOE_FILTER_CTX_QW1_LANQINDX_MASK (0x7FFULL << \
+ I40E_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT)
+
+#endif /* I40E_FCOE */
enum i40e_switch_element_types {
I40E_SWITCH_ELEMENT_TYPE_MAC = 1,
I40E_SWITCH_ELEMENT_TYPE_PF = 2,
@@ -1162,4 +1370,7 @@ enum i40e_reset_type {
I40E_RESET_GLOBR = 2,
I40E_RESET_EMPR = 3,
};
+
+/* RSS Hash Table Size */
+#define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
#endif /* _I40E_TYPE_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index f5b9d2062573..89672551dce9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -347,10 +347,6 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_idx,
rx_ctx.dsize = 1;
/* default values */
- rx_ctx.tphrdesc_ena = 1;
- rx_ctx.tphwdesc_ena = 1;
- rx_ctx.tphdata_ena = 1;
- rx_ctx.tphhead_ena = 1;
rx_ctx.lrxqthresh = 2;
rx_ctx.crcstrip = 1;
rx_ctx.prefena = 1;
@@ -673,7 +669,7 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
*/
for (i = 0; i < 100; i++) {
/* vf reset requires driver to first reset the
- * vf & than poll the status register to make sure
+ * vf and then poll the status register to make sure
* that the requested op was completed
* successfully
*/
@@ -1009,7 +1005,7 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
{
struct i40e_pf *pf = vf->pf;
struct i40e_hw *hw = &pf->hw;
- int true_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
+ int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
i40e_status aq_ret;
/* single place to detect unsuccessful return values */
@@ -1029,7 +1025,7 @@ static int i40e_vc_send_msg_to_vf(struct i40e_vf *vf, u32 v_opcode,
vf->num_valid_msgs++;
}
- aq_ret = i40e_aq_send_msg_to_vf(hw, true_vf_id, v_opcode, v_retval,
+ aq_ret = i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
msg, msglen, NULL);
if (aq_ret) {
dev_err(&pf->pdev->dev,
@@ -1167,8 +1163,8 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf,
(struct i40e_virtchnl_promisc_info *)msg;
struct i40e_pf *pf = vf->pf;
struct i40e_hw *hw = &pf->hw;
+ struct i40e_vsi *vsi;
bool allmulti = false;
- bool promisc = false;
i40e_status aq_ret;
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
@@ -1178,17 +1174,10 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf,
aq_ret = I40E_ERR_PARAM;
goto error_param;
}
-
- if (info->flags & I40E_FLAG_VF_UNICAST_PROMISC)
- promisc = true;
- aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, info->vsi_id,
- promisc, NULL);
- if (aq_ret)
- goto error_param;
-
+ vsi = pf->vsi[info->vsi_id];
if (info->flags & I40E_FLAG_VF_MULTICAST_PROMISC)
allmulti = true;
- aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, info->vsi_id,
+ aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
allmulti, NULL);
error_param:
@@ -1939,15 +1928,17 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
{
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf = pf->vf;
+ int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
int i;
for (i = 0; i < pf->num_alloc_vfs; i++) {
/* Ignore return value on purpose - a given VF may fail, but
* we need to keep going and send to all of them
*/
- i40e_aq_send_msg_to_vf(hw, vf->vf_id, v_opcode, v_retval,
+ i40e_aq_send_msg_to_vf(hw, abs_vf_id, v_opcode, v_retval,
msg, msglen, NULL);
vf++;
+ abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
}
}
@@ -1963,6 +1954,7 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf)
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf = pf->vf;
struct i40e_link_status *ls = &pf->hw.phy.link_info;
+ int abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
int i;
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
@@ -1977,10 +1969,11 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf)
ls->link_info & I40E_AQ_LINK_UP;
pfe.event_data.link_event.link_speed = ls->link_speed;
}
- i40e_aq_send_msg_to_vf(hw, vf->vf_id, I40E_VIRTCHNL_OP_EVENT,
+ i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe, sizeof(pfe),
NULL);
vf++;
+ abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
}
}
@@ -2009,10 +2002,11 @@ void i40e_vc_notify_reset(struct i40e_pf *pf)
void i40e_vc_notify_vf_reset(struct i40e_vf *vf)
{
struct i40e_virtchnl_pf_event pfe;
+ int abs_vf_id = vf->vf_id + vf->pf->hw.func_caps.vf_base_id;
pfe.event = I40E_VIRTCHNL_EVENT_RESET_IMPENDING;
pfe.severity = I40E_PF_EVENT_SEVERITY_CERTAIN_DOOM;
- i40e_aq_send_msg_to_vf(&vf->pf->hw, vf->vf_id, I40E_VIRTCHNL_OP_EVENT,
+ i40e_aq_send_msg_to_vf(&vf->pf->hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
I40E_SUCCESS, (u8 *)&pfe,
sizeof(struct i40e_virtchnl_pf_event), NULL);
}
@@ -2077,6 +2071,8 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
}
ether_addr_copy(vf->default_lan_addr.addr, mac);
vf->pf_set_mac = true;
+ /* Force the VF driver stop so it has to reload with new MAC address */
+ i40e_vc_disable_vf(pf, vf);
dev_info(&pf->pdev->dev, "Reload the VF driver to make this change effective.\n");
ret = 0;
@@ -2347,6 +2343,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
struct i40e_virtchnl_pf_event pfe;
struct i40e_hw *hw = &pf->hw;
struct i40e_vf *vf;
+ int abs_vf_id;
int ret = 0;
/* validate the request */
@@ -2357,6 +2354,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
}
vf = &pf->vf[vf_id];
+ abs_vf_id = vf->vf_id + hw->func_caps.vf_base_id;
pfe.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE;
pfe.severity = I40E_PF_EVENT_SEVERITY_INFO;
@@ -2386,7 +2384,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
goto error_out;
}
/* Notify the VF of its new link state */
- i40e_aq_send_msg_to_vf(hw, vf->vf_id, I40E_VIRTCHNL_OP_EVENT,
+ i40e_aq_send_msg_to_vf(hw, abs_vf_id, I40E_VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe, sizeof(pfe), NULL);
error_out:
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index eb67cce3e8f9..003006033614 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -53,16 +53,24 @@ static void i40e_adminq_init_regs(struct i40e_hw *hw)
hw->aq.asq.tail = I40E_VF_ATQT1;
hw->aq.asq.head = I40E_VF_ATQH1;
hw->aq.asq.len = I40E_VF_ATQLEN1;
+ hw->aq.asq.bal = I40E_VF_ATQBAL1;
+ hw->aq.asq.bah = I40E_VF_ATQBAH1;
hw->aq.arq.tail = I40E_VF_ARQT1;
hw->aq.arq.head = I40E_VF_ARQH1;
hw->aq.arq.len = I40E_VF_ARQLEN1;
+ hw->aq.arq.bal = I40E_VF_ARQBAL1;
+ hw->aq.arq.bah = I40E_VF_ARQBAH1;
} else {
hw->aq.asq.tail = I40E_PF_ATQT;
hw->aq.asq.head = I40E_PF_ATQH;
hw->aq.asq.len = I40E_PF_ATQLEN;
+ hw->aq.asq.bal = I40E_PF_ATQBAL;
+ hw->aq.asq.bah = I40E_PF_ATQBAH;
hw->aq.arq.tail = I40E_PF_ARQT;
hw->aq.arq.head = I40E_PF_ARQH;
hw->aq.arq.len = I40E_PF_ARQLEN;
+ hw->aq.arq.bal = I40E_PF_ARQBAL;
+ hw->aq.arq.bah = I40E_PF_ARQBAH;
}
}
@@ -294,27 +302,18 @@ static i40e_status i40e_config_asq_regs(struct i40e_hw *hw)
i40e_status ret_code = 0;
u32 reg = 0;
- if (hw->mac.type == I40E_MAC_VF) {
- /* configure the transmit queue */
- wr32(hw, I40E_VF_ATQBAH1,
- upper_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_VF_ATQBAL1,
- lower_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_VF_ATQLEN1, (hw->aq.num_asq_entries |
- I40E_VF_ATQLEN1_ATQENABLE_MASK));
- reg = rd32(hw, I40E_VF_ATQBAL1);
- } else {
- /* configure the transmit queue */
- wr32(hw, I40E_PF_ATQBAH,
- upper_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_PF_ATQBAL,
- lower_32_bits(hw->aq.asq.desc_buf.pa));
- wr32(hw, I40E_PF_ATQLEN, (hw->aq.num_asq_entries |
- I40E_PF_ATQLEN_ATQENABLE_MASK));
- reg = rd32(hw, I40E_PF_ATQBAL);
- }
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.asq.head, 0);
+ wr32(hw, hw->aq.asq.tail, 0);
+
+ /* set starting point */
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ I40E_PF_ATQLEN_ATQENABLE_MASK));
+ wr32(hw, hw->aq.asq.bal, lower_32_bits(hw->aq.asq.desc_buf.pa));
+ wr32(hw, hw->aq.asq.bah, upper_32_bits(hw->aq.asq.desc_buf.pa));
/* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.asq.bal);
if (reg != lower_32_bits(hw->aq.asq.desc_buf.pa))
ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
@@ -332,30 +331,21 @@ static i40e_status i40e_config_arq_regs(struct i40e_hw *hw)
i40e_status ret_code = 0;
u32 reg = 0;
- if (hw->mac.type == I40E_MAC_VF) {
- /* configure the receive queue */
- wr32(hw, I40E_VF_ARQBAH1,
- upper_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_VF_ARQBAL1,
- lower_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_VF_ARQLEN1, (hw->aq.num_arq_entries |
- I40E_VF_ARQLEN1_ARQENABLE_MASK));
- reg = rd32(hw, I40E_VF_ARQBAL1);
- } else {
- /* configure the receive queue */
- wr32(hw, I40E_PF_ARQBAH,
- upper_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_PF_ARQBAL,
- lower_32_bits(hw->aq.arq.desc_buf.pa));
- wr32(hw, I40E_PF_ARQLEN, (hw->aq.num_arq_entries |
- I40E_PF_ARQLEN_ARQENABLE_MASK));
- reg = rd32(hw, I40E_PF_ARQBAL);
- }
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.arq.head, 0);
+ wr32(hw, hw->aq.arq.tail, 0);
+
+ /* set starting point */
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ I40E_PF_ARQLEN_ARQENABLE_MASK));
+ wr32(hw, hw->aq.arq.bal, lower_32_bits(hw->aq.arq.desc_buf.pa));
+ wr32(hw, hw->aq.arq.bah, upper_32_bits(hw->aq.arq.desc_buf.pa));
/* Update tail in the HW to post pre-allocated buffers */
wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1);
/* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.arq.bal);
if (reg != lower_32_bits(hw->aq.arq.desc_buf.pa))
ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
@@ -497,6 +487,8 @@ static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
wr32(hw, hw->aq.asq.head, 0);
wr32(hw, hw->aq.asq.tail, 0);
wr32(hw, hw->aq.asq.len, 0);
+ wr32(hw, hw->aq.asq.bal, 0);
+ wr32(hw, hw->aq.asq.bah, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.asq_mutex);
@@ -528,6 +520,8 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
wr32(hw, hw->aq.arq.head, 0);
wr32(hw, hw->aq.arq.tail, 0);
wr32(hw, hw->aq.arq.len, 0);
+ wr32(hw, hw->aq.arq.bal, 0);
+ wr32(hw, hw->aq.arq.bah, 0);
/* make sure lock is available */
mutex_lock(&hw->aq.arq_mutex);
@@ -573,6 +567,9 @@ i40e_status i40evf_init_adminq(struct i40e_hw *hw)
/* Set up register offsets */
i40e_adminq_init_regs(hw);
+ /* setup ASQ command write back timeout */
+ hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT;
+
/* allocate the ASQ */
ret_code = i40e_init_asq(hw);
if (ret_code)
@@ -630,6 +627,10 @@ static u16 i40e_clean_asq(struct i40e_hw *hw)
desc = I40E_ADMINQ_DESC(*asq, ntc);
details = I40E_ADMINQ_DETAILS(*asq, ntc);
while (rd32(hw, hw->aq.asq.head) != ntc) {
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "%s: ntc %d head %d.\n", __func__, ntc,
+ rd32(hw, hw->aq.asq.head));
+
if (details->callback) {
I40E_ADMINQ_CALLBACK cb_func =
(I40E_ADMINQ_CALLBACK)details->callback;
@@ -690,17 +691,20 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
struct i40e_aq_desc *desc_on_ring;
bool cmd_completed = false;
u16 retval = 0;
+ u32 val = 0;
- if (hw->aq.asq.count == 0) {
+ val = rd32(hw, hw->aq.asq.head);
+ if (val >= hw->aq.num_asq_entries) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
- "AQTX: Admin queue not initialized.\n");
+ "AQTX: head overrun at %d\n", val);
status = I40E_ERR_QUEUE_EMPTY;
goto asq_send_command_exit;
}
- if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
- i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
- status = I40E_ERR_NVM;
+ if (hw->aq.asq.count == 0) {
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "AQTX: Admin queue not initialized.\n");
+ status = I40E_ERR_QUEUE_EMPTY;
goto asq_send_command_exit;
}
@@ -783,6 +787,7 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
}
/* bump the tail */
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff);
(hw->aq.asq.next_to_use)++;
if (hw->aq.asq.next_to_use == hw->aq.asq.count)
@@ -806,7 +811,7 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
/* ugh! delay while spin_lock */
udelay(delay_len);
total_delay += delay_len;
- } while (total_delay < I40E_ASQ_CMD_TIMEOUT);
+ } while (total_delay < hw->aq.asq_cmd_timeout);
}
/* if ready, copy the desc back to temp */
@@ -820,6 +825,7 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
I40E_DEBUG_AQ_MESSAGE,
"AQTX: Command completed with error 0x%X.\n",
retval);
+
/* strip off FW internal code */
retval &= 0xff;
}
@@ -834,6 +840,10 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
if (i40e_is_nvm_update_op(desc))
hw->aq.nvm_busy = true;
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+ "AQTX: desc and buffer writeback:\n");
+ i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff);
+
/* update the error if time out occurred */
if ((!cmd_completed) &&
(!details->async && !details->postpone)) {
@@ -905,10 +915,6 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
/* now clean the next descriptor */
desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc);
desc_idx = ntc;
- i40evf_debug_aq(hw,
- I40E_DEBUG_AQ_COMMAND,
- (void *)desc,
- hw->aq.arq.r.arq_bi[desc_idx].va);
flags = le16_to_cpu(desc->flags);
if (flags & I40E_AQ_FLAG_ERR) {
@@ -919,18 +925,21 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
I40E_DEBUG_AQ_MESSAGE,
"AQRX: Event received with error 0x%X.\n",
hw->aq.arq_last_status);
- } else {
- e->desc = *desc;
- datalen = le16_to_cpu(desc->datalen);
- e->msg_size = min(datalen, e->msg_size);
- if (e->msg_buf != NULL && (e->msg_size != 0))
- memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
- e->msg_size);
}
+ e->desc = *desc;
+ datalen = le16_to_cpu(desc->datalen);
+ e->msg_size = min(datalen, e->msg_size);
+ if (e->msg_buf != NULL && (e->msg_size != 0))
+ memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
+ e->msg_size);
+
if (i40e_is_nvm_update_op(&e->desc))
hw->aq.nvm_busy = false;
+ i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
+ i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
+
/* Restore the original datalen and buffer address in the desc,
* FW updates datalen to indicate the event message
* size
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index e3472c62e155..91a5c5bd80f3 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -56,6 +56,8 @@ struct i40e_adminq_ring {
u32 head;
u32 tail;
u32 len;
+ u32 bah;
+ u32 bal;
};
/* ASQ transaction details */
@@ -82,6 +84,7 @@ struct i40e_arq_event_info {
struct i40e_adminq_info {
struct i40e_adminq_ring arq; /* receive queue */
struct i40e_adminq_ring asq; /* send queue */
+ u32 asq_cmd_timeout; /* send queue cmd write back timeout*/
u16 num_arq_entries; /* receive queue depth */
u16 num_asq_entries; /* send queue depth */
u16 arq_buf_size; /* receive queue buffer size */
@@ -91,6 +94,7 @@ struct i40e_adminq_info {
u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */
bool nvm_busy;
+ bool nvm_release_on_done;
struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */
@@ -100,6 +104,41 @@ struct i40e_adminq_info {
enum i40e_admin_queue_err arq_last_status;
};
+/**
+ * i40e_aq_rc_to_posix - convert errors to user-land codes
+ * aq_rc: AdminQ error code to convert
+ **/
+static inline int i40e_aq_rc_to_posix(u16 aq_rc)
+{
+ int aq_to_posix[] = {
+ 0, /* I40E_AQ_RC_OK */
+ -EPERM, /* I40E_AQ_RC_EPERM */
+ -ENOENT, /* I40E_AQ_RC_ENOENT */
+ -ESRCH, /* I40E_AQ_RC_ESRCH */
+ -EINTR, /* I40E_AQ_RC_EINTR */
+ -EIO, /* I40E_AQ_RC_EIO */
+ -ENXIO, /* I40E_AQ_RC_ENXIO */
+ -E2BIG, /* I40E_AQ_RC_E2BIG */
+ -EAGAIN, /* I40E_AQ_RC_EAGAIN */
+ -ENOMEM, /* I40E_AQ_RC_ENOMEM */
+ -EACCES, /* I40E_AQ_RC_EACCES */
+ -EFAULT, /* I40E_AQ_RC_EFAULT */
+ -EBUSY, /* I40E_AQ_RC_EBUSY */
+ -EEXIST, /* I40E_AQ_RC_EEXIST */
+ -EINVAL, /* I40E_AQ_RC_EINVAL */
+ -ENOTTY, /* I40E_AQ_RC_ENOTTY */
+ -ENOSPC, /* I40E_AQ_RC_ENOSPC */
+ -ENOSYS, /* I40E_AQ_RC_ENOSYS */
+ -ERANGE, /* I40E_AQ_RC_ERANGE */
+ -EPIPE, /* I40E_AQ_RC_EFLUSHED */
+ -ESPIPE, /* I40E_AQ_RC_BAD_ADDR */
+ -EROFS, /* I40E_AQ_RC_EMODE */
+ -EFBIG, /* I40E_AQ_RC_EFBIG */
+ };
+
+ return aq_to_posix[aq_rc];
+}
+
/* general information */
#define I40E_AQ_LARGE_BUF 512
#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c
index a43155afdbe2..4ea90bf239bb 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c
@@ -551,6 +551,7 @@ i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
+ struct i40e_asq_cmd_details details;
i40e_status status;
i40evf_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
@@ -565,7 +566,6 @@ i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
desc.datalen = cpu_to_le16(msglen);
}
if (!cmd_details) {
- struct i40e_asq_cmd_details details;
memset(&details, 0, sizeof(details));
details.async = true;
cmd_details = &details;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_hmc.h b/drivers/net/ethernet/intel/i40evf/i40e_hmc.h
index a2ad9a4e399d..931c88044300 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_hmc.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_hmc.h
@@ -127,7 +127,7 @@ struct i40e_hmc_info {
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \
(1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \
- val3 = (sd_index) | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, val1); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
@@ -146,7 +146,7 @@ struct i40e_hmc_info {
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \
- val3 = (sd_index) | (1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, 0); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
index d6f762241537..a5d79877354c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
@@ -32,16 +32,22 @@ struct i40e_hw;
/* HMC element context information */
-/* Rx queue context data */
+/* Rx queue context data
+ *
+ * The sizes of the variables may be larger than needed due to crossing byte
+ * boundaries. If we do not have the width of the variable set to the correct
+ * size then we could end up shifting bits off the top of the variable when the
+ * variable is at the top of a byte and crosses over into the next byte.
+ */
struct i40e_hmc_obj_rxq {
u16 head;
- u8 cpuid;
+ u16 cpuid; /* bigger than needed, see above for reason */
u64 base;
u16 qlen;
#define I40E_RXQ_CTX_DBUFF_SHIFT 7
- u8 dbuff;
+ u16 dbuff; /* bigger than needed, see above for reason */
#define I40E_RXQ_CTX_HBUFF_SHIFT 6
- u8 hbuff;
+ u16 hbuff; /* bigger than needed, see above for reason */
u8 dtype;
u8 dsize;
u8 crcstrip;
@@ -50,16 +56,22 @@ struct i40e_hmc_obj_rxq {
u8 hsplit_0;
u8 hsplit_1;
u8 showiv;
- u16 rxmax;
+ u32 rxmax; /* bigger than needed, see above for reason */
u8 tphrdesc_ena;
u8 tphwdesc_ena;
u8 tphdata_ena;
u8 tphhead_ena;
- u8 lrxqthresh;
+ u16 lrxqthresh; /* bigger than needed, see above for reason */
u8 prefena; /* NOTE: normally must be set to 1 at init */
};
-/* Tx queue context data */
+/* Tx queue context data
+*
+* The sizes of the variables may be larger than needed due to crossing byte
+* boundaries. If we do not have the width of the variable set to the correct
+* size then we could end up shifting bits off the top of the variable when the
+* variable is at the top of a byte and crosses over into the next byte.
+*/
struct i40e_hmc_obj_txq {
u16 head;
u8 new_context;
@@ -69,7 +81,7 @@ struct i40e_hmc_obj_txq {
u8 fd_ena;
u8 alt_vlan_ena;
u16 thead_wb;
- u16 cpuid;
+ u8 cpuid;
u8 head_wb_ena;
u16 qlen;
u8 tphrdesc_ena;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_register.h b/drivers/net/ethernet/intel/i40evf/i40e_register.h
index 369839655818..c1f6a59bfea0 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_register.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_register.h
@@ -27,4648 +27,3343 @@
#ifndef _I40E_REGISTER_H_
#define _I40E_REGISTER_H_
-#define I40E_GL_GP_FUSE(_i) (0x0009400C + ((_i) * 4)) /* _i=0...28 */
-#define I40E_GL_GP_FUSE_MAX_INDEX 28
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT 0
-#define I40E_GL_GP_FUSE_GL_GP_FUSE_MASK (0xFFFFFFFF << I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ 0x0009C4F4
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_MASK (0x7 << I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_MASK (0x1F << I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB 0x0009C4F0
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT 0
-#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_MASK (0x1F << I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT 16
-#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_MASK (0x7 << I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC 0x0009C4EC
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT 0
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_MASK (0xFF << I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT)
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT 8
-#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_MASK (0xFF << I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_0 0x0009C4F8
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_MASK (0xFFFFFFFF << I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT)
-#define I40E_GLPCI_SPARE_BITS_1 0x0009C4FC
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT 0
-#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_MASK (0xFFFFFFFF << I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT)
-#define I40E_PFPCI_PF_FLUSH_DONE 0x0009C800
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE 0x0009C600
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VF_FLUSH_DONE1(_VF) (0x0009C600 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_PFPCI_VF_FLUSH_DONE1_MAX_INDEX 127
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT)
-#define I40E_PFPCI_VM_FLUSH_DONE 0x0009C880
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT 0
-#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_MASK (0x1 << I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT)
-
-#define I40E_PF_ARQBAH 0x00080180
+#define I40E_GL_ARQBAH 0x000801C0 /* Reset: EMPR */
+#define I40E_GL_ARQBAH_ARQBAH_SHIFT 0
+#define I40E_GL_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAH_ARQBAH_SHIFT)
+#define I40E_GL_ARQBAL 0x000800C0 /* Reset: EMPR */
+#define I40E_GL_ARQBAL_ARQBAL_SHIFT 0
+#define I40E_GL_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ARQBAL_ARQBAL_SHIFT)
+#define I40E_GL_ARQH 0x000803C0 /* Reset: EMPR */
+#define I40E_GL_ARQH_ARQH_SHIFT 0
+#define I40E_GL_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_GL_ARQH_ARQH_SHIFT)
+#define I40E_GL_ARQT 0x000804C0 /* Reset: EMPR */
+#define I40E_GL_ARQT_ARQT_SHIFT 0
+#define I40E_GL_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_GL_ARQT_ARQT_SHIFT)
+#define I40E_GL_ATQBAH 0x00080140 /* Reset: EMPR */
+#define I40E_GL_ATQBAH_ATQBAH_SHIFT 0
+#define I40E_GL_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAH_ATQBAH_SHIFT)
+#define I40E_GL_ATQBAL 0x00080040 /* Reset: EMPR */
+#define I40E_GL_ATQBAL_ATQBAL_SHIFT 0
+#define I40E_GL_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_ATQBAL_ATQBAL_SHIFT)
+#define I40E_GL_ATQH 0x00080340 /* Reset: EMPR */
+#define I40E_GL_ATQH_ATQH_SHIFT 0
+#define I40E_GL_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_GL_ATQH_ATQH_SHIFT)
+#define I40E_GL_ATQLEN 0x00080240 /* Reset: EMPR */
+#define I40E_GL_ATQLEN_ATQLEN_SHIFT 0
+#define I40E_GL_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_GL_ATQLEN_ATQLEN_SHIFT)
+#define I40E_GL_ATQLEN_ATQVFE_SHIFT 28
+#define I40E_GL_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQVFE_SHIFT)
+#define I40E_GL_ATQLEN_ATQOVFL_SHIFT 29
+#define I40E_GL_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_GL_ATQLEN_ATQCRIT_SHIFT 30
+#define I40E_GL_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_GL_ATQLEN_ATQENABLE_SHIFT 31
+#define I40E_GL_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_GL_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_GL_ATQT 0x00080440 /* Reset: EMPR */
+#define I40E_GL_ATQT_ATQT_SHIFT 0
+#define I40E_GL_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_GL_ATQT_ATQT_SHIFT)
+#define I40E_PF_ARQBAH 0x00080180 /* Reset: EMPR */
#define I40E_PF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_PF_ARQBAH_ARQBAH_MASK (0xFFFFFFFF << I40E_PF_ARQBAH_ARQBAH_SHIFT)
-#define I40E_PF_ARQBAL 0x00080080
+#define I40E_PF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAH_ARQBAH_SHIFT)
+#define I40E_PF_ARQBAL 0x00080080 /* Reset: EMPR */
#define I40E_PF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_PF_ARQBAL_ARQBAL_MASK (0xFFFFFFFF << I40E_PF_ARQBAL_ARQBAL_SHIFT)
-#define I40E_PF_ARQH 0x00080380
+#define I40E_PF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ARQBAL_ARQBAL_SHIFT)
+#define I40E_PF_ARQH 0x00080380 /* Reset: EMPR */
#define I40E_PF_ARQH_ARQH_SHIFT 0
-#define I40E_PF_ARQH_ARQH_MASK (0x3FF << I40E_PF_ARQH_ARQH_SHIFT)
-#define I40E_PF_ARQLEN 0x00080280
+#define I40E_PF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_PF_ARQH_ARQH_SHIFT)
+#define I40E_PF_ARQLEN 0x00080280 /* Reset: EMPR */
#define I40E_PF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_PF_ARQLEN_ARQLEN_MASK (0x3FF << I40E_PF_ARQLEN_ARQLEN_SHIFT)
+#define I40E_PF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ARQLEN_ARQLEN_SHIFT)
#define I40E_PF_ARQLEN_ARQVFE_SHIFT 28
-#define I40E_PF_ARQLEN_ARQVFE_MASK (0x1 << I40E_PF_ARQLEN_ARQVFE_SHIFT)
+#define I40E_PF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQVFE_SHIFT)
#define I40E_PF_ARQLEN_ARQOVFL_SHIFT 29
-#define I40E_PF_ARQLEN_ARQOVFL_MASK (0x1 << I40E_PF_ARQLEN_ARQOVFL_SHIFT)
+#define I40E_PF_ARQLEN_ARQOVFL_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQOVFL_SHIFT)
#define I40E_PF_ARQLEN_ARQCRIT_SHIFT 30
-#define I40E_PF_ARQLEN_ARQCRIT_MASK (0x1 << I40E_PF_ARQLEN_ARQCRIT_SHIFT)
+#define I40E_PF_ARQLEN_ARQCRIT_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQCRIT_SHIFT)
#define I40E_PF_ARQLEN_ARQENABLE_SHIFT 31
-#define I40E_PF_ARQLEN_ARQENABLE_MASK (0x1 << I40E_PF_ARQLEN_ARQENABLE_SHIFT)
-#define I40E_PF_ARQT 0x00080480
+#define I40E_PF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1, I40E_PF_ARQLEN_ARQENABLE_SHIFT)
+#define I40E_PF_ARQT 0x00080480 /* Reset: EMPR */
#define I40E_PF_ARQT_ARQT_SHIFT 0
-#define I40E_PF_ARQT_ARQT_MASK (0x3FF << I40E_PF_ARQT_ARQT_SHIFT)
-#define I40E_PF_ATQBAH 0x00080100
+#define I40E_PF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_PF_ARQT_ARQT_SHIFT)
+#define I40E_PF_ATQBAH 0x00080100 /* Reset: EMPR */
#define I40E_PF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_PF_ATQBAH_ATQBAH_MASK (0xFFFFFFFF << I40E_PF_ATQBAH_ATQBAH_SHIFT)
-#define I40E_PF_ATQBAL 0x00080000
+#define I40E_PF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAH_ATQBAH_SHIFT)
+#define I40E_PF_ATQBAL 0x00080000 /* Reset: EMPR */
#define I40E_PF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_PF_ATQBAL_ATQBAL_MASK (0xFFFFFFFF << I40E_PF_ATQBAL_ATQBAL_SHIFT)
-#define I40E_PF_ATQH 0x00080300
+#define I40E_PF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_ATQBAL_ATQBAL_SHIFT)
+#define I40E_PF_ATQH 0x00080300 /* Reset: EMPR */
#define I40E_PF_ATQH_ATQH_SHIFT 0
-#define I40E_PF_ATQH_ATQH_MASK (0x3FF << I40E_PF_ATQH_ATQH_SHIFT)
-#define I40E_PF_ATQLEN 0x00080200
+#define I40E_PF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_PF_ATQH_ATQH_SHIFT)
+#define I40E_PF_ATQLEN 0x00080200 /* Reset: EMPR */
#define I40E_PF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_PF_ATQLEN_ATQLEN_MASK (0x3FF << I40E_PF_ATQLEN_ATQLEN_SHIFT)
+#define I40E_PF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_PF_ATQLEN_ATQLEN_SHIFT)
#define I40E_PF_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_PF_ATQLEN_ATQVFE_MASK (0x1 << I40E_PF_ATQLEN_ATQVFE_SHIFT)
+#define I40E_PF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQVFE_SHIFT)
#define I40E_PF_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_PF_ATQLEN_ATQOVFL_MASK (0x1 << I40E_PF_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_PF_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQOVFL_SHIFT)
#define I40E_PF_ATQLEN_ATQCRIT_SHIFT 30
-#define I40E_PF_ATQLEN_ATQCRIT_MASK (0x1 << I40E_PF_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_PF_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQCRIT_SHIFT)
#define I40E_PF_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_PF_ATQLEN_ATQENABLE_MASK (0x1 << I40E_PF_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_PF_ATQT 0x00080400
+#define I40E_PF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_PF_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_PF_ATQT 0x00080400 /* Reset: EMPR */
#define I40E_PF_ATQT_ATQT_SHIFT 0
-#define I40E_PF_ATQT_ATQT_MASK (0x3FF << I40E_PF_ATQT_ATQT_SHIFT)
-#define I40E_VF_ARQBAH(_VF) (0x00081400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_PF_ATQT_ATQT_SHIFT)
+#define I40E_VF_ARQBAH(_VF) (0x00081400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQBAH_MAX_INDEX 127
#define I40E_VF_ARQBAH_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH_ARQBAH_MASK (0xFFFFFFFF << I40E_VF_ARQBAH_ARQBAH_SHIFT)
-#define I40E_VF_ARQBAL(_VF) (0x00080C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQBAH_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH_ARQBAH_SHIFT)
+#define I40E_VF_ARQBAL(_VF) (0x00080C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQBAL_MAX_INDEX 127
#define I40E_VF_ARQBAL_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL_ARQBAL_MASK (0xFFFFFFFF << I40E_VF_ARQBAL_ARQBAL_SHIFT)
-#define I40E_VF_ARQH(_VF) (0x00082400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQBAL_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL_ARQBAL_SHIFT)
+#define I40E_VF_ARQH(_VF) (0x00082400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQH_MAX_INDEX 127
#define I40E_VF_ARQH_ARQH_SHIFT 0
-#define I40E_VF_ARQH_ARQH_MASK (0x3FF << I40E_VF_ARQH_ARQH_SHIFT)
-#define I40E_VF_ARQLEN(_VF) (0x00081C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQH_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH_ARQH_SHIFT)
+#define I40E_VF_ARQLEN(_VF) (0x00081C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQLEN_MAX_INDEX 127
#define I40E_VF_ARQLEN_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN_ARQLEN_MASK (0x3FF << I40E_VF_ARQLEN_ARQLEN_SHIFT)
+#define I40E_VF_ARQLEN_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN_ARQLEN_SHIFT)
#define I40E_VF_ARQLEN_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN_ARQVFE_MASK (0x1 << I40E_VF_ARQLEN_ARQVFE_SHIFT)
+#define I40E_VF_ARQLEN_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQVFE_SHIFT)
#define I40E_VF_ARQLEN_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN_ARQOVFL_MASK (0x1 << I40E_VF_ARQLEN_ARQOVFL_SHIFT)
+#define I40E_VF_ARQLEN_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQOVFL_SHIFT)
#define I40E_VF_ARQLEN_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN_ARQCRIT_MASK (0x1 << I40E_VF_ARQLEN_ARQCRIT_SHIFT)
+#define I40E_VF_ARQLEN_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQCRIT_SHIFT)
#define I40E_VF_ARQLEN_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN_ARQENABLE_MASK (0x1 << I40E_VF_ARQLEN_ARQENABLE_SHIFT)
-#define I40E_VF_ARQT(_VF) (0x00082C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQLEN_ARQENABLE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN_ARQENABLE_SHIFT)
+#define I40E_VF_ARQT(_VF) (0x00082C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ARQT_MAX_INDEX 127
#define I40E_VF_ARQT_ARQT_SHIFT 0
-#define I40E_VF_ARQT_ARQT_MASK (0x3FF << I40E_VF_ARQT_ARQT_SHIFT)
-#define I40E_VF_ATQBAH(_VF) (0x00081000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ARQT_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT_ARQT_SHIFT)
+#define I40E_VF_ATQBAH(_VF) (0x00081000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQBAH_MAX_INDEX 127
#define I40E_VF_ATQBAH_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH_ATQBAH_MASK (0xFFFFFFFF << I40E_VF_ATQBAH_ATQBAH_SHIFT)
-#define I40E_VF_ATQBAL(_VF) (0x00080800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQBAH_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH_ATQBAH_SHIFT)
+#define I40E_VF_ATQBAL(_VF) (0x00080800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQBAL_MAX_INDEX 127
#define I40E_VF_ATQBAL_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL_ATQBAL_MASK (0xFFFFFFFF << I40E_VF_ATQBAL_ATQBAL_SHIFT)
-#define I40E_VF_ATQH(_VF) (0x00082000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQBAL_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL_ATQBAL_SHIFT)
+#define I40E_VF_ATQH(_VF) (0x00082000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQH_MAX_INDEX 127
#define I40E_VF_ATQH_ATQH_SHIFT 0
-#define I40E_VF_ATQH_ATQH_MASK (0x3FF << I40E_VF_ATQH_ATQH_SHIFT)
-#define I40E_VF_ATQLEN(_VF) (0x00081800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQH_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH_ATQH_SHIFT)
+#define I40E_VF_ATQLEN(_VF) (0x00081800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQLEN_MAX_INDEX 127
#define I40E_VF_ATQLEN_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN_ATQLEN_MASK (0x3FF << I40E_VF_ATQLEN_ATQLEN_SHIFT)
+#define I40E_VF_ATQLEN_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN_ATQLEN_SHIFT)
#define I40E_VF_ATQLEN_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN_ATQVFE_MASK (0x1 << I40E_VF_ATQLEN_ATQVFE_SHIFT)
+#define I40E_VF_ATQLEN_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQVFE_SHIFT)
#define I40E_VF_ATQLEN_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN_ATQOVFL_MASK (0x1 << I40E_VF_ATQLEN_ATQOVFL_SHIFT)
+#define I40E_VF_ATQLEN_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQOVFL_SHIFT)
#define I40E_VF_ATQLEN_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN_ATQCRIT_MASK (0x1 << I40E_VF_ATQLEN_ATQCRIT_SHIFT)
+#define I40E_VF_ATQLEN_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQCRIT_SHIFT)
#define I40E_VF_ATQLEN_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN_ATQENABLE_MASK (0x1 << I40E_VF_ATQLEN_ATQENABLE_SHIFT)
-#define I40E_VF_ATQT(_VF) (0x00082800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VF_ATQLEN_ATQENABLE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN_ATQENABLE_SHIFT)
+#define I40E_VF_ATQT(_VF) (0x00082800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
#define I40E_VF_ATQT_MAX_INDEX 127
#define I40E_VF_ATQT_ATQT_SHIFT 0
-#define I40E_VF_ATQT_ATQT_MASK (0x3FF << I40E_VF_ATQT_ATQT_SHIFT)
-#define I40E_PRT_L2TAGSEN 0x001C0B20
+#define I40E_VF_ATQT_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT_ATQT_SHIFT)
+#define I40E_PRT_L2TAGSEN 0x001C0B20 /* Reset: CORER */
#define I40E_PRT_L2TAGSEN_ENABLE_SHIFT 0
-#define I40E_PRT_L2TAGSEN_ENABLE_MASK (0xFF << I40E_PRT_L2TAGSEN_ENABLE_SHIFT)
-#define I40E_PFCM_LAN_ERRDATA 0x0010C080
+#define I40E_PRT_L2TAGSEN_ENABLE_MASK I40E_MASK(0xFF, I40E_PRT_L2TAGSEN_ENABLE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA 0x0010C080 /* Reset: PFR */
#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_MASK (0xF << I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_PFCM_LAN_ERRDATA_ERROR_CODE_SHIFT)
#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_MASK (0x7 << I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT)
+#define I40E_PFCM_LAN_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRDATA_Q_TYPE_SHIFT)
#define I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_LAN_ERRDATA_Q_NUM_MASK (0xFFF << I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_LAN_ERRINFO 0x0010C000
+#define I40E_PFCM_LAN_ERRDATA_Q_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LAN_ERRDATA_Q_NUM_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO 0x0010C000 /* Reset: PFR */
#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_PFCM_LAN_ERRINFO_ERROR_VALID_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_MASK (0x7 << I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_PFCM_LAN_ERRINFO_ERROR_INST_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_DBL_ERROR_CNT_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLU_ERROR_CNT_SHIFT)
#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_PFCM_LANCTXCTL(_pf) (0x0010C300 + ((_pf) * 4))/* _pf=0..15 */
+#define I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_LAN_ERRINFO_RLS_ERROR_CNT_SHIFT)
+#define I40E_PFCM_LANCTXCTL 0x0010C300 /* Reset: CORER */
#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT 0
-#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_MASK (0xFFF << I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT)
+#define I40E_PFCM_LANCTXCTL_QUEUE_NUM_MASK I40E_MASK(0xFFF, I40E_PFCM_LANCTXCTL_QUEUE_NUM_SHIFT)
#define I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT 12
-#define I40E_PFCM_LANCTXCTL_SUB_LINE_MASK (0x7 << I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT)
+#define I40E_PFCM_LANCTXCTL_SUB_LINE_MASK I40E_MASK(0x7, I40E_PFCM_LANCTXCTL_SUB_LINE_SHIFT)
#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT 15
-#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_MASK (0x3 << I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT)
+#define I40E_PFCM_LANCTXCTL_QUEUE_TYPE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_QUEUE_TYPE_SHIFT)
#define I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT 17
-#define I40E_PFCM_LANCTXCTL_OP_CODE_MASK (0x3 << I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT)
-#define I40E_PFCM_LANCTXDATA(_i, _pf) (0x0010C100 + ((_i) * 4) + ((_pf) * 16))/* _i=0...3 _pf=0..15 */
+#define I40E_PFCM_LANCTXCTL_OP_CODE_MASK I40E_MASK(0x3, I40E_PFCM_LANCTXCTL_OP_CODE_SHIFT)
+#define I40E_PFCM_LANCTXDATA(_i) (0x0010C100 + ((_i) * 128)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PFCM_LANCTXDATA_MAX_INDEX 3
#define I40E_PFCM_LANCTXDATA_DATA_SHIFT 0
-#define I40E_PFCM_LANCTXDATA_DATA_MASK (0xFFFFFFFF << I40E_PFCM_LANCTXDATA_DATA_SHIFT)
-#define I40E_PFCM_LANCTXSTAT(_pf) (0x0010C380 + ((_pf) * 4))/* _pf=0..15 */
+#define I40E_PFCM_LANCTXDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFCM_LANCTXDATA_DATA_SHIFT)
+#define I40E_PFCM_LANCTXSTAT 0x0010C380 /* Reset: CORER */
#define I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT 0
-#define I40E_PFCM_LANCTXSTAT_CTX_DONE_MASK (0x1 << I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT)
+#define I40E_PFCM_LANCTXSTAT_CTX_DONE_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_DONE_SHIFT)
#define I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT 1
-#define I40E_PFCM_LANCTXSTAT_CTX_MISS_MASK (0x1 << I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT)
-#define I40E_PFCM_PE_ERRDATA 0x00138D00
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_MASK (0xF << I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_PFCM_PE_ERRDATA_Q_TYPE_MASK (0x7 << I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT)
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_PFCM_PE_ERRDATA_Q_NUM_MASK (0x3FFFF << I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_PFCM_PE_ERRINFO 0x00138C80
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_PFCM_PE_ERRINFO_ERROR_INST_MASK (0x7 << I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_VFCM_PE_ERRDATA1(_VF) (0x00138800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PFCM_LANCTXSTAT_CTX_MISS_MASK I40E_MASK(0x1, I40E_PFCM_LANCTXSTAT_CTX_MISS_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1(_VF) (0x00138800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFCM_PE_ERRDATA1_MAX_INDEX 127
#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_MASK (0xF << I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA1_ERROR_CODE_SHIFT)
#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_MASK (0x7 << I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA1_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA1_Q_TYPE_SHIFT)
#define I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA1_Q_NUM_MASK (0x3FFFF << I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO1(_VF) (0x00138400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFCM_PE_ERRDATA1_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA1_Q_NUM_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1(_VF) (0x00138400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFCM_PE_ERRINFO1_MAX_INDEX 127
#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_MASK (0x1 << I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO1_ERROR_VALID_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_MASK (0x7 << I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO1_ERROR_INST_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_DBL_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLU_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT)
-#define I40E_GLDCB_GENC 0x00083044
+#define I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO1_RLS_ERROR_CNT_SHIFT)
+#define I40E_GLDCB_GENC 0x00083044 /* Reset: CORER */
#define I40E_GLDCB_GENC_PCIRTT_SHIFT 0
-#define I40E_GLDCB_GENC_PCIRTT_MASK (0xFFFF << I40E_GLDCB_GENC_PCIRTT_SHIFT)
-#define I40E_GLDCB_RUPTI 0x00122618
+#define I40E_GLDCB_GENC_PCIRTT_MASK I40E_MASK(0xFFFF, I40E_GLDCB_GENC_PCIRTT_SHIFT)
+#define I40E_GLDCB_RUPTI 0x00122618 /* Reset: CORER */
#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT 0
-#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_MASK (0xFFFFFFFF << I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT)
-#define I40E_PRTDCB_FCCFG 0x001E4640
+#define I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLDCB_RUPTI_PFCTIMEOUT_UP_SHIFT)
+#define I40E_PRTDCB_FCCFG 0x001E4640 /* Reset: GLOBR */
#define I40E_PRTDCB_FCCFG_TFCE_SHIFT 3
-#define I40E_PRTDCB_FCCFG_TFCE_MASK (0x3 << I40E_PRTDCB_FCCFG_TFCE_SHIFT)
-#define I40E_PRTDCB_FCRTV 0x001E4600
+#define I40E_PRTDCB_FCCFG_TFCE_MASK I40E_MASK(0x3, I40E_PRTDCB_FCCFG_TFCE_SHIFT)
+#define I40E_PRTDCB_FCRTV 0x001E4600 /* Reset: GLOBR */
#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT 0
-#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_MASK (0xFFFF << I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT)
-#define I40E_PRTDCB_FCTTVN(_i) (0x001E4580 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTDCB_FCRTV_FC_REFRESH_TH_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCRTV_FC_REFRESH_TH_SHIFT)
+#define I40E_PRTDCB_FCTTVN(_i) (0x001E4580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: GLOBR */
#define I40E_PRTDCB_FCTTVN_MAX_INDEX 3
#define I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT 0
-#define I40E_PRTDCB_FCTTVN_TTV_2N_MASK (0xFFFF << I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT)
+#define I40E_PRTDCB_FCTTVN_TTV_2N_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_SHIFT)
#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT 16
-#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_MASK (0xFFFF << I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT)
-#define I40E_PRTDCB_GENC 0x00083000
+#define I40E_PRTDCB_FCTTVN_TTV_2N_P1_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_FCTTVN_TTV_2N_P1_SHIFT)
+#define I40E_PRTDCB_GENC 0x00083000 /* Reset: CORER */
#define I40E_PRTDCB_GENC_RESERVED_1_SHIFT 0
-#define I40E_PRTDCB_GENC_RESERVED_1_MASK (0x3 << I40E_PRTDCB_GENC_RESERVED_1_SHIFT)
+#define I40E_PRTDCB_GENC_RESERVED_1_MASK I40E_MASK(0x3, I40E_PRTDCB_GENC_RESERVED_1_SHIFT)
#define I40E_PRTDCB_GENC_NUMTC_SHIFT 2
-#define I40E_PRTDCB_GENC_NUMTC_MASK (0xF << I40E_PRTDCB_GENC_NUMTC_SHIFT)
+#define I40E_PRTDCB_GENC_NUMTC_MASK I40E_MASK(0xF, I40E_PRTDCB_GENC_NUMTC_SHIFT)
#define I40E_PRTDCB_GENC_FCOEUP_SHIFT 6
-#define I40E_PRTDCB_GENC_FCOEUP_MASK (0x7 << I40E_PRTDCB_GENC_FCOEUP_SHIFT)
+#define I40E_PRTDCB_GENC_FCOEUP_MASK I40E_MASK(0x7, I40E_PRTDCB_GENC_FCOEUP_SHIFT)
#define I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT 9
-#define I40E_PRTDCB_GENC_FCOEUP_VALID_MASK (0x1 << I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT)
+#define I40E_PRTDCB_GENC_FCOEUP_VALID_MASK I40E_MASK(0x1, I40E_PRTDCB_GENC_FCOEUP_VALID_SHIFT)
#define I40E_PRTDCB_GENC_PFCLDA_SHIFT 16
-#define I40E_PRTDCB_GENC_PFCLDA_MASK (0xFFFF << I40E_PRTDCB_GENC_PFCLDA_SHIFT)
-#define I40E_PRTDCB_GENS 0x00083020
+#define I40E_PRTDCB_GENC_PFCLDA_MASK I40E_MASK(0xFFFF, I40E_PRTDCB_GENC_PFCLDA_SHIFT)
+#define I40E_PRTDCB_GENS 0x00083020 /* Reset: CORER */
#define I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT 0
-#define I40E_PRTDCB_GENS_DCBX_STATUS_MASK (0x7 << I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT)
-#define I40E_PRTDCB_MFLCN 0x001E2400
+#define I40E_PRTDCB_GENS_DCBX_STATUS_MASK I40E_MASK(0x7, I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT)
+#define I40E_PRTDCB_MFLCN 0x001E2400 /* Reset: GLOBR */
#define I40E_PRTDCB_MFLCN_PMCF_SHIFT 0
-#define I40E_PRTDCB_MFLCN_PMCF_MASK (0x1 << I40E_PRTDCB_MFLCN_PMCF_SHIFT)
+#define I40E_PRTDCB_MFLCN_PMCF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_PMCF_SHIFT)
#define I40E_PRTDCB_MFLCN_DPF_SHIFT 1
-#define I40E_PRTDCB_MFLCN_DPF_MASK (0x1 << I40E_PRTDCB_MFLCN_DPF_SHIFT)
+#define I40E_PRTDCB_MFLCN_DPF_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_DPF_SHIFT)
#define I40E_PRTDCB_MFLCN_RPFCM_SHIFT 2
-#define I40E_PRTDCB_MFLCN_RPFCM_MASK (0x1 << I40E_PRTDCB_MFLCN_RPFCM_SHIFT)
+#define I40E_PRTDCB_MFLCN_RPFCM_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RPFCM_SHIFT)
#define I40E_PRTDCB_MFLCN_RFCE_SHIFT 3
-#define I40E_PRTDCB_MFLCN_RFCE_MASK (0x1 << I40E_PRTDCB_MFLCN_RFCE_SHIFT)
+#define I40E_PRTDCB_MFLCN_RFCE_MASK I40E_MASK(0x1, I40E_PRTDCB_MFLCN_RFCE_SHIFT)
#define I40E_PRTDCB_MFLCN_RPFCE_SHIFT 4
-#define I40E_PRTDCB_MFLCN_RPFCE_MASK (0xFF << I40E_PRTDCB_MFLCN_RPFCE_SHIFT)
-#define I40E_PRTDCB_RETSC 0x001223E0
+#define I40E_PRTDCB_MFLCN_RPFCE_MASK I40E_MASK(0xFF, I40E_PRTDCB_MFLCN_RPFCE_SHIFT)
+#define I40E_PRTDCB_RETSC 0x001223E0 /* Reset: CORER */
#define I40E_PRTDCB_RETSC_ETS_MODE_SHIFT 0
-#define I40E_PRTDCB_RETSC_ETS_MODE_MASK (0x1 << I40E_PRTDCB_RETSC_ETS_MODE_SHIFT)
+#define I40E_PRTDCB_RETSC_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_ETS_MODE_SHIFT)
#define I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT 1
-#define I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK (0x1 << I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT)
+#define I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT)
#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT 2
-#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK (0xF << I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT)
+#define I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK I40E_MASK(0xF, I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT)
#define I40E_PRTDCB_RETSC_LLTC_SHIFT 8
-#define I40E_PRTDCB_RETSC_LLTC_MASK (0xFF << I40E_PRTDCB_RETSC_LLTC_SHIFT)
-#define I40E_PRTDCB_RETSTCC(_i) (0x00122180 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_RETSC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_RETSC_LLTC_SHIFT)
+#define I40E_PRTDCB_RETSTCC(_i) (0x00122180 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTDCB_RETSTCC_MAX_INDEX 7
#define I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT 0
-#define I40E_PRTDCB_RETSTCC_BWSHARE_MASK (0x7F << I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT)
+#define I40E_PRTDCB_RETSTCC_BWSHARE_MASK I40E_MASK(0x7F, I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT)
#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT 30
-#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK (0x1 << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT)
+#define I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT)
#define I40E_PRTDCB_RETSTCC_ETSTC_SHIFT 31
-#define I40E_PRTDCB_RETSTCC_ETSTC_MASK (0x1 << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT)
-#define I40E_PRTDCB_RPPMC 0x001223A0
+#define I40E_PRTDCB_RETSTCC_ETSTC_MASK I40E_MASK(0x1, I40E_PRTDCB_RETSTCC_ETSTC_SHIFT)
+#define I40E_PRTDCB_RPPMC 0x001223A0 /* Reset: CORER */
#define I40E_PRTDCB_RPPMC_LANRPPM_SHIFT 0
-#define I40E_PRTDCB_RPPMC_LANRPPM_MASK (0xFF << I40E_PRTDCB_RPPMC_LANRPPM_SHIFT)
+#define I40E_PRTDCB_RPPMC_LANRPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_LANRPPM_SHIFT)
#define I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT 8
-#define I40E_PRTDCB_RPPMC_RDMARPPM_MASK (0xFF << I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT)
+#define I40E_PRTDCB_RPPMC_RDMARPPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RDMARPPM_SHIFT)
#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT 16
-#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK (0xFF << I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT)
-#define I40E_PRTDCB_RUP 0x001C0B00
+#define I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK I40E_MASK(0xFF, I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT)
+#define I40E_PRTDCB_RUP 0x001C0B00 /* Reset: CORER */
#define I40E_PRTDCB_RUP_NOVLANUP_SHIFT 0
-#define I40E_PRTDCB_RUP_NOVLANUP_MASK (0x7 << I40E_PRTDCB_RUP_NOVLANUP_SHIFT)
-#define I40E_PRTDCB_RUP2TC 0x001C09A0
+#define I40E_PRTDCB_RUP_NOVLANUP_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP_NOVLANUP_SHIFT)
+#define I40E_PRTDCB_RUP2TC 0x001C09A0 /* Reset: CORER */
#define I40E_PRTDCB_RUP2TC_UP0TC_SHIFT 0
-#define I40E_PRTDCB_RUP2TC_UP0TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP0TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP0TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP0TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP1TC_SHIFT 3
-#define I40E_PRTDCB_RUP2TC_UP1TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP1TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP1TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP1TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP2TC_SHIFT 6
-#define I40E_PRTDCB_RUP2TC_UP2TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP2TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP2TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP2TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP3TC_SHIFT 9
-#define I40E_PRTDCB_RUP2TC_UP3TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP3TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP3TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP3TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP4TC_SHIFT 12
-#define I40E_PRTDCB_RUP2TC_UP4TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP4TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP4TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP4TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP5TC_SHIFT 15
-#define I40E_PRTDCB_RUP2TC_UP5TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP5TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP5TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP5TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP6TC_SHIFT 18
-#define I40E_PRTDCB_RUP2TC_UP6TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP6TC_SHIFT)
+#define I40E_PRTDCB_RUP2TC_UP6TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP6TC_SHIFT)
#define I40E_PRTDCB_RUP2TC_UP7TC_SHIFT 21
-#define I40E_PRTDCB_RUP2TC_UP7TC_MASK (0x7 << I40E_PRTDCB_RUP2TC_UP7TC_SHIFT)
-#define I40E_PRTDCB_TC2PFC 0x001C0980
+#define I40E_PRTDCB_RUP2TC_UP7TC_MASK I40E_MASK(0x7, I40E_PRTDCB_RUP2TC_UP7TC_SHIFT)
+#define I40E_PRTDCB_TC2PFC 0x001C0980 /* Reset: CORER */
#define I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT 0
-#define I40E_PRTDCB_TC2PFC_TC2PFC_MASK (0xFF << I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT)
-#define I40E_PRTDCB_TCPMC 0x000A21A0
+#define I40E_PRTDCB_TC2PFC_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT)
+#define I40E_PRTDCB_TCMSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
+#define I40E_PRTDCB_TCMSTC_MAX_INDEX 7
+#define I40E_PRTDCB_TCMSTC_MSTC_SHIFT 0
+#define I40E_PRTDCB_TCMSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCMSTC_MSTC_SHIFT)
+#define I40E_PRTDCB_TCPMC 0x000A21A0 /* Reset: CORER */
#define I40E_PRTDCB_TCPMC_CPM_SHIFT 0
-#define I40E_PRTDCB_TCPMC_CPM_MASK (0x1FFF << I40E_PRTDCB_TCPMC_CPM_SHIFT)
+#define I40E_PRTDCB_TCPMC_CPM_MASK I40E_MASK(0x1FFF, I40E_PRTDCB_TCPMC_CPM_SHIFT)
#define I40E_PRTDCB_TCPMC_LLTC_SHIFT 13
-#define I40E_PRTDCB_TCPMC_LLTC_MASK (0xFF << I40E_PRTDCB_TCPMC_LLTC_SHIFT)
+#define I40E_PRTDCB_TCPMC_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TCPMC_LLTC_SHIFT)
#define I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TCPMC_TCPM_MODE_MASK (0x1 << I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TCWSTC(_i) (0x000A2040 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_TCPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT)
+#define I40E_PRTDCB_TCWSTC(_i) (0x000A2040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTDCB_TCWSTC_MAX_INDEX 7
#define I40E_PRTDCB_TCWSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TCWSTC_MSTC_MASK (0xFFFFF << I40E_PRTDCB_TCWSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TDPMC 0x000A0180
+#define I40E_PRTDCB_TCWSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCWSTC_MSTC_SHIFT)
+#define I40E_PRTDCB_TDPMC 0x000A0180 /* Reset: CORER */
#define I40E_PRTDCB_TDPMC_DPM_SHIFT 0
-#define I40E_PRTDCB_TDPMC_DPM_MASK (0xFF << I40E_PRTDCB_TDPMC_DPM_SHIFT)
+#define I40E_PRTDCB_TDPMC_DPM_MASK I40E_MASK(0xFF, I40E_PRTDCB_TDPMC_DPM_SHIFT)
#define I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT 30
-#define I40E_PRTDCB_TDPMC_TCPM_MODE_MASK (0x1 << I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT)
-#define I40E_PRTDCB_TDPUC 0x00044100
-#define I40E_PRTDCB_TDPUC_MAX_TXFRAME_SHIFT 0
-#define I40E_PRTDCB_TDPUC_MAX_TXFRAME_MASK (0xFFFF << I40E_PRTDCB_TDPUC_MAX_TXFRAME_SHIFT)
-#define I40E_PRTDCB_TETSC_TCB 0x000AE060
+#define I40E_PRTDCB_TDPMC_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT)
+#define I40E_PRTDCB_TETSC_TCB 0x000AE060 /* Reset: CORER */
#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_MASK (0x1 << I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT)
+#define I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TCB_EN_LL_STRICT_PRIORITY_SHIFT)
#define I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TCB_LLTC_MASK (0xFF << I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT)
-#define I40E_PRTDCB_TETSC_TPB 0x00098060
+#define I40E_PRTDCB_TETSC_TCB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TCB_LLTC_SHIFT)
+#define I40E_PRTDCB_TETSC_TPB 0x00098060 /* Reset: CORER */
#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT 0
-#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_MASK (0x1 << I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT)
+#define I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_MASK I40E_MASK(0x1, I40E_PRTDCB_TETSC_TPB_EN_LL_STRICT_PRIORITY_SHIFT)
#define I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT 8
-#define I40E_PRTDCB_TETSC_TPB_LLTC_MASK (0xFF << I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT)
-#define I40E_PRTDCB_TFCS 0x001E4560
+#define I40E_PRTDCB_TETSC_TPB_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TETSC_TPB_LLTC_SHIFT)
+#define I40E_PRTDCB_TFCS 0x001E4560 /* Reset: GLOBR */
#define I40E_PRTDCB_TFCS_TXOFF_SHIFT 0
-#define I40E_PRTDCB_TFCS_TXOFF_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF0_SHIFT 8
-#define I40E_PRTDCB_TFCS_TXOFF0_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF0_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF0_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF0_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF1_SHIFT 9
-#define I40E_PRTDCB_TFCS_TXOFF1_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF1_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF1_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF1_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF2_SHIFT 10
-#define I40E_PRTDCB_TFCS_TXOFF2_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF2_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF2_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF2_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF3_SHIFT 11
-#define I40E_PRTDCB_TFCS_TXOFF3_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF3_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF3_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF3_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF4_SHIFT 12
-#define I40E_PRTDCB_TFCS_TXOFF4_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF4_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF4_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF4_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF5_SHIFT 13
-#define I40E_PRTDCB_TFCS_TXOFF5_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF5_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF5_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF5_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF6_SHIFT 14
-#define I40E_PRTDCB_TFCS_TXOFF6_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF6_SHIFT)
+#define I40E_PRTDCB_TFCS_TXOFF6_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF6_SHIFT)
#define I40E_PRTDCB_TFCS_TXOFF7_SHIFT 15
-#define I40E_PRTDCB_TFCS_TXOFF7_MASK (0x1 << I40E_PRTDCB_TFCS_TXOFF7_SHIFT)
-#define I40E_PRTDCB_TFWSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */
-#define I40E_PRTDCB_TFWSTC_MAX_INDEX 7
-#define I40E_PRTDCB_TFWSTC_MSTC_SHIFT 0
-#define I40E_PRTDCB_TFWSTC_MSTC_MASK (0xFFFFF << I40E_PRTDCB_TFWSTC_MSTC_SHIFT)
-#define I40E_PRTDCB_TPFCTS(_i) (0x001E4660 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTDCB_TFCS_TXOFF7_MASK I40E_MASK(0x1, I40E_PRTDCB_TFCS_TXOFF7_SHIFT)
+#define I40E_PRTDCB_TPFCTS(_i) (0x001E4660 + ((_i) * 32)) /* _i=0...7 */ /* Reset: GLOBR */
#define I40E_PRTDCB_TPFCTS_MAX_INDEX 7
#define I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT 0
-#define I40E_PRTDCB_TPFCTS_PFCTIMER_MASK (0x3FFF << I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT)
-#define I40E_GLFCOE_RCTL 0x00269B94
+#define I40E_PRTDCB_TPFCTS_PFCTIMER_MASK I40E_MASK(0x3FFF, I40E_PRTDCB_TPFCTS_PFCTIMER_SHIFT)
+#define I40E_GLFCOE_RCTL 0x00269B94 /* Reset: CORER */
#define I40E_GLFCOE_RCTL_FCOEVER_SHIFT 0
-#define I40E_GLFCOE_RCTL_FCOEVER_MASK (0xF << I40E_GLFCOE_RCTL_FCOEVER_SHIFT)
+#define I40E_GLFCOE_RCTL_FCOEVER_MASK I40E_MASK(0xF, I40E_GLFCOE_RCTL_FCOEVER_SHIFT)
#define I40E_GLFCOE_RCTL_SAVBAD_SHIFT 4
-#define I40E_GLFCOE_RCTL_SAVBAD_MASK (0x1 << I40E_GLFCOE_RCTL_SAVBAD_SHIFT)
+#define I40E_GLFCOE_RCTL_SAVBAD_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_SAVBAD_SHIFT)
#define I40E_GLFCOE_RCTL_ICRC_SHIFT 5
-#define I40E_GLFCOE_RCTL_ICRC_MASK (0x1 << I40E_GLFCOE_RCTL_ICRC_SHIFT)
+#define I40E_GLFCOE_RCTL_ICRC_MASK I40E_MASK(0x1, I40E_GLFCOE_RCTL_ICRC_SHIFT)
#define I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT 16
-#define I40E_GLFCOE_RCTL_MAX_SIZE_MASK (0x3FFF << I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT)
-#define I40E_GL_FWSTS 0x00083048
+#define I40E_GLFCOE_RCTL_MAX_SIZE_MASK I40E_MASK(0x3FFF, I40E_GLFCOE_RCTL_MAX_SIZE_SHIFT)
+#define I40E_GL_FWSTS 0x00083048 /* Reset: POR */
#define I40E_GL_FWSTS_FWS0B_SHIFT 0
-#define I40E_GL_FWSTS_FWS0B_MASK (0xFF << I40E_GL_FWSTS_FWS0B_SHIFT)
+#define I40E_GL_FWSTS_FWS0B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS0B_SHIFT)
#define I40E_GL_FWSTS_FWRI_SHIFT 9
-#define I40E_GL_FWSTS_FWRI_MASK (0x1 << I40E_GL_FWSTS_FWRI_SHIFT)
+#define I40E_GL_FWSTS_FWRI_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWRI_SHIFT)
#define I40E_GL_FWSTS_FWS1B_SHIFT 16
-#define I40E_GL_FWSTS_FWS1B_MASK (0xFF << I40E_GL_FWSTS_FWS1B_SHIFT)
-#define I40E_GLGEN_CLKSTAT 0x000B8184
+#define I40E_GL_FWSTS_FWS1B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS1B_SHIFT)
+#define I40E_GLGEN_CLKSTAT 0x000B8184 /* Reset: POR */
#define I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT 0
-#define I40E_GLGEN_CLKSTAT_CLKMODE_MASK (0x1 << I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT)
+#define I40E_GLGEN_CLKSTAT_CLKMODE_MASK I40E_MASK(0x1, I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT)
#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT 4
-#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_MASK (0x3 << I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_U_CLK_SPEED_MASK I40E_MASK(0x3, I40E_GLGEN_CLKSTAT_U_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT 8
-#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P0_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT 12
-#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P1_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT 16
-#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P2_CLK_SPEED_SHIFT)
#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT 20
-#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_MASK (0x7 << I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT)
-#define I40E_GLGEN_GPIO_CTL(_i) (0x00088100 + ((_i) * 4)) /* _i=0...29 */
+#define I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_MASK I40E_MASK(0x7, I40E_GLGEN_CLKSTAT_P3_CLK_SPEED_SHIFT)
+#define I40E_GLGEN_GPIO_CTL(_i) (0x00088100 + ((_i) * 4)) /* _i=0...29 */ /* Reset: POR */
#define I40E_GLGEN_GPIO_CTL_MAX_INDEX 29
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT 0
-#define I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK (0x3 << I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT 3
-#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK (0x1 << I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT 4
-#define I40E_GLGEN_GPIO_CTL_PIN_DIR_MASK (0x1 << I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PIN_DIR_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_PIN_DIR_SHIFT)
#define I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT 5
-#define I40E_GLGEN_GPIO_CTL_TRI_CTL_MASK (0x1 << I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_TRI_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_TRI_CTL_SHIFT)
#define I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT 6
-#define I40E_GLGEN_GPIO_CTL_OUT_CTL_MASK (0x1 << I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_OUT_CTL_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_CTL_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT 7
-#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK (0x7 << I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK I40E_MASK(0x7, I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT 10
-#define I40E_GLGEN_GPIO_CTL_LED_INVRT_MASK (0x1 << I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_INVRT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_INVRT_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT 11
-#define I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK (0x1 << I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT)
#define I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT 12
-#define I40E_GLGEN_GPIO_CTL_LED_MODE_MASK (0xF << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_LED_MODE_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
#define I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT 17
-#define I40E_GLGEN_GPIO_CTL_INT_MODE_MASK (0x3 << I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_INT_MODE_MASK I40E_MASK(0x3, I40E_GLGEN_GPIO_CTL_INT_MODE_SHIFT)
#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT 19
-#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_MASK (0x1 << I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT)
+#define I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_CTL_OUT_DEFAULT_SHIFT)
#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT 20
-#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_MASK (0x3F << I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT)
-#define I40E_GLGEN_GPIO_SET 0x00088184
+#define I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_MASK I40E_MASK(0x3F, I40E_GLGEN_GPIO_CTL_PHY_PIN_NAME_SHIFT)
+#define I40E_GLGEN_GPIO_SET 0x00088184 /* Reset: POR */
#define I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT 0
-#define I40E_GLGEN_GPIO_SET_GPIO_INDX_MASK (0x1F << I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT)
+#define I40E_GLGEN_GPIO_SET_GPIO_INDX_MASK I40E_MASK(0x1F, I40E_GLGEN_GPIO_SET_GPIO_INDX_SHIFT)
#define I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT 5
-#define I40E_GLGEN_GPIO_SET_SDP_DATA_MASK (0x1 << I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT)
+#define I40E_GLGEN_GPIO_SET_SDP_DATA_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_SDP_DATA_SHIFT)
#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT 6
-#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_MASK (0x1 << I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT)
-#define I40E_GLGEN_GPIO_STAT 0x0008817C
+#define I40E_GLGEN_GPIO_SET_DRIVE_SDP_MASK I40E_MASK(0x1, I40E_GLGEN_GPIO_SET_DRIVE_SDP_SHIFT)
+#define I40E_GLGEN_GPIO_STAT 0x0008817C /* Reset: POR */
#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT 0
-#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_MASK (0x3FFFFFFF << I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT)
-#define I40E_GLGEN_GPIO_TRANSIT 0x00088180
+#define I40E_GLGEN_GPIO_STAT_GPIO_VALUE_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_STAT_GPIO_VALUE_SHIFT)
+#define I40E_GLGEN_GPIO_TRANSIT 0x00088180 /* Reset: POR */
#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT 0
-#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_MASK (0x3FFFFFFF << I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT)
-#define I40E_GLGEN_I2CCMD(_i) (0x000881E0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_GPIO_TRANSIT_GPIO_TRANSITION_SHIFT)
+#define I40E_GLGEN_I2CCMD(_i) (0x000881E0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_I2CCMD_MAX_INDEX 3
#define I40E_GLGEN_I2CCMD_DATA_SHIFT 0
-#define I40E_GLGEN_I2CCMD_DATA_MASK (0xFFFF << I40E_GLGEN_I2CCMD_DATA_SHIFT)
+#define I40E_GLGEN_I2CCMD_DATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_I2CCMD_DATA_SHIFT)
#define I40E_GLGEN_I2CCMD_REGADD_SHIFT 16
-#define I40E_GLGEN_I2CCMD_REGADD_MASK (0xFF << I40E_GLGEN_I2CCMD_REGADD_SHIFT)
+#define I40E_GLGEN_I2CCMD_REGADD_MASK I40E_MASK(0xFF, I40E_GLGEN_I2CCMD_REGADD_SHIFT)
#define I40E_GLGEN_I2CCMD_PHYADD_SHIFT 24
-#define I40E_GLGEN_I2CCMD_PHYADD_MASK (0x7 << I40E_GLGEN_I2CCMD_PHYADD_SHIFT)
+#define I40E_GLGEN_I2CCMD_PHYADD_MASK I40E_MASK(0x7, I40E_GLGEN_I2CCMD_PHYADD_SHIFT)
#define I40E_GLGEN_I2CCMD_OP_SHIFT 27
-#define I40E_GLGEN_I2CCMD_OP_MASK (0x1 << I40E_GLGEN_I2CCMD_OP_SHIFT)
+#define I40E_GLGEN_I2CCMD_OP_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_OP_SHIFT)
#define I40E_GLGEN_I2CCMD_RESET_SHIFT 28
-#define I40E_GLGEN_I2CCMD_RESET_MASK (0x1 << I40E_GLGEN_I2CCMD_RESET_SHIFT)
+#define I40E_GLGEN_I2CCMD_RESET_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_RESET_SHIFT)
#define I40E_GLGEN_I2CCMD_R_SHIFT 29
-#define I40E_GLGEN_I2CCMD_R_MASK (0x1 << I40E_GLGEN_I2CCMD_R_SHIFT)
+#define I40E_GLGEN_I2CCMD_R_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_R_SHIFT)
#define I40E_GLGEN_I2CCMD_E_SHIFT 31
-#define I40E_GLGEN_I2CCMD_E_MASK (0x1 << I40E_GLGEN_I2CCMD_E_SHIFT)
-#define I40E_GLGEN_I2CPARAMS(_i) (0x000881AC + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_I2CCMD_E_MASK I40E_MASK(0x1, I40E_GLGEN_I2CCMD_E_SHIFT)
+#define I40E_GLGEN_I2CPARAMS(_i) (0x000881AC + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_I2CPARAMS_MAX_INDEX 3
#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT 0
-#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_MASK (0x1F << I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_WRITE_TIME_MASK I40E_MASK(0x1F, I40E_GLGEN_I2CPARAMS_WRITE_TIME_SHIFT)
#define I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT 5
-#define I40E_GLGEN_I2CPARAMS_READ_TIME_MASK (0x7 << I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_READ_TIME_MASK I40E_MASK(0x7, I40E_GLGEN_I2CPARAMS_READ_TIME_SHIFT)
#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT 8
-#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2CBB_EN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_SHIFT 9
-#define I40E_GLGEN_I2CPARAMS_CLK_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT 10
-#define I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OUT_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT 11
-#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_OE_N_SHIFT)
#define I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT 12
-#define I40E_GLGEN_I2CPARAMS_DATA_IN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_DATA_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_DATA_IN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT 13
-#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_OE_N_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT 14
-#define I40E_GLGEN_I2CPARAMS_CLK_IN_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_IN_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_IN_SHIFT)
#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT 15
-#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_MASK (0x1 << I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT)
+#define I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_CLK_STRETCH_DIS_SHIFT)
#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT 31
-#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_MASK (0x1 << I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT)
-#define I40E_GLGEN_LED_CTL 0x00088178
+#define I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_MASK I40E_MASK(0x1, I40E_GLGEN_I2CPARAMS_I2C_DATA_ORDER_SHIFT)
+#define I40E_GLGEN_LED_CTL 0x00088178 /* Reset: POR */
#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT 0
-#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_MASK (0x1 << I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT)
-#define I40E_GLGEN_MDIO_CTRL(_i) (0x000881D0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_LED_CTL_GLOBAL_BLINK_MODE_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL(_i) (0x000881D0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MDIO_CTRL_MAX_INDEX 3
#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT 0
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_MASK (0x1FFFF << I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_MASK I40E_MASK(0x1FFFF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD2_SHIFT)
#define I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT 17
-#define I40E_GLGEN_MDIO_CTRL_CONTMDC_MASK (0x1 << I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT)
+#define I40E_GLGEN_MDIO_CTRL_CONTMDC_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_CTRL_CONTMDC_SHIFT)
#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT 18
-#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_MASK (0x3FFF << I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT)
-#define I40E_GLGEN_MDIO_I2C_SEL(_i) (0x000881C0 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_MASK I40E_MASK(0x3FFF, I40E_GLGEN_MDIO_CTRL_LEGACY_RSVD1_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL(_i) (0x000881C0 + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MDIO_I2C_SEL_MAX_INDEX 3
#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT 0
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK (0x1 << I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT 1
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK (0xF << I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT 5
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY0_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT 10
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY1_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT 15
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY2_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT 20
-#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_MASK (0x1F << I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_MASK I40E_MASK(0x1F, I40E_GLGEN_MDIO_I2C_SEL_PHY3_ADDRESS_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT 25
-#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_MASK (0xF << I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT)
+#define I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_MASK I40E_MASK(0xF, I40E_GLGEN_MDIO_I2C_SEL_MDIO_IF_MODE_SHIFT)
#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT 31
-#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_MASK (0x1 << I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT)
-#define I40E_GLGEN_MSCA(_i) (0x0008818C + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_MASK I40E_MASK(0x1, I40E_GLGEN_MDIO_I2C_SEL_EN_FAST_MODE_SHIFT)
+#define I40E_GLGEN_MSCA(_i) (0x0008818C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MSCA_MAX_INDEX 3
#define I40E_GLGEN_MSCA_MDIADD_SHIFT 0
-#define I40E_GLGEN_MSCA_MDIADD_MASK (0xFFFF << I40E_GLGEN_MSCA_MDIADD_SHIFT)
+#define I40E_GLGEN_MSCA_MDIADD_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSCA_MDIADD_SHIFT)
#define I40E_GLGEN_MSCA_DEVADD_SHIFT 16
-#define I40E_GLGEN_MSCA_DEVADD_MASK (0x1F << I40E_GLGEN_MSCA_DEVADD_SHIFT)
+#define I40E_GLGEN_MSCA_DEVADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_DEVADD_SHIFT)
#define I40E_GLGEN_MSCA_PHYADD_SHIFT 21
-#define I40E_GLGEN_MSCA_PHYADD_MASK (0x1F << I40E_GLGEN_MSCA_PHYADD_SHIFT)
+#define I40E_GLGEN_MSCA_PHYADD_MASK I40E_MASK(0x1F, I40E_GLGEN_MSCA_PHYADD_SHIFT)
#define I40E_GLGEN_MSCA_OPCODE_SHIFT 26
-#define I40E_GLGEN_MSCA_OPCODE_MASK (0x3 << I40E_GLGEN_MSCA_OPCODE_SHIFT)
+#define I40E_GLGEN_MSCA_OPCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_OPCODE_SHIFT)
#define I40E_GLGEN_MSCA_STCODE_SHIFT 28
-#define I40E_GLGEN_MSCA_STCODE_MASK (0x3 << I40E_GLGEN_MSCA_STCODE_SHIFT)
+#define I40E_GLGEN_MSCA_STCODE_MASK I40E_MASK(0x3, I40E_GLGEN_MSCA_STCODE_SHIFT)
#define I40E_GLGEN_MSCA_MDICMD_SHIFT 30
-#define I40E_GLGEN_MSCA_MDICMD_MASK (0x1 << I40E_GLGEN_MSCA_MDICMD_SHIFT)
+#define I40E_GLGEN_MSCA_MDICMD_MASK I40E_MASK(0x1, I40E_GLGEN_MSCA_MDICMD_SHIFT)
#define I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT 31
-#define I40E_GLGEN_MSCA_MDIINPROGEN_MASK (0x1 << I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT)
-#define I40E_GLGEN_MSRWD(_i) (0x0008819C + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_MSCA_MDIINPROGEN_MASK I40E_MASK(0x1, I40E_GLGEN_MSCA_MDIINPROGEN_SHIFT)
+#define I40E_GLGEN_MSRWD(_i) (0x0008819C + ((_i) * 4)) /* _i=0...3 */ /* Reset: POR */
#define I40E_GLGEN_MSRWD_MAX_INDEX 3
#define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
-#define I40E_GLGEN_MSRWD_MDIWRDATA_MASK (0xFFFF << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT)
+#define I40E_GLGEN_MSRWD_MDIWRDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT)
#define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
-#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK (0xFFFF << I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
-#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4
+#define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4 /* Reset: PCIR */
#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
-#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK (0x1F << I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
-#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK (0xFF << I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
-#define I40E_GLGEN_PE_ENA 0x000B81A0
-#define I40E_GLGEN_PE_ENA_PE_ENA_SHIFT 0
-#define I40E_GLGEN_PE_ENA_PE_ENA_MASK (0x1 << I40E_GLGEN_PE_ENA_PE_ENA_SHIFT)
-#define I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_SHIFT 1
-#define I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_MASK (0x3 << I40E_GLGEN_PE_ENA_PE_CLK_SRC_SEL_SHIFT)
-#define I40E_GLGEN_RSTAT 0x000B8188
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
+#define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
#define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
-#define I40E_GLGEN_RSTAT_DEVSTATE_MASK (0x3 << I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
+#define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
#define I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT 2
-#define I40E_GLGEN_RSTAT_RESET_TYPE_MASK (0x3 << I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT)
+#define I40E_GLGEN_RSTAT_RESET_TYPE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT)
#define I40E_GLGEN_RSTAT_CORERCNT_SHIFT 4
-#define I40E_GLGEN_RSTAT_CORERCNT_MASK (0x3 << I40E_GLGEN_RSTAT_CORERCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_CORERCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_CORERCNT_SHIFT)
#define I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT 6
-#define I40E_GLGEN_RSTAT_GLOBRCNT_MASK (0x3 << I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_GLOBRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_GLOBRCNT_SHIFT)
#define I40E_GLGEN_RSTAT_EMPRCNT_SHIFT 8
-#define I40E_GLGEN_RSTAT_EMPRCNT_MASK (0x3 << I40E_GLGEN_RSTAT_EMPRCNT_SHIFT)
+#define I40E_GLGEN_RSTAT_EMPRCNT_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_EMPRCNT_SHIFT)
#define I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT 10
-#define I40E_GLGEN_RSTAT_TIME_TO_RST_MASK (0x3F << I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT)
-#define I40E_GLGEN_RSTCTL 0x000B8180
+#define I40E_GLGEN_RSTAT_TIME_TO_RST_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTAT_TIME_TO_RST_SHIFT)
+#define I40E_GLGEN_RSTCTL 0x000B8180 /* Reset: POR */
#define I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT 0
-#define I40E_GLGEN_RSTCTL_GRSTDEL_MASK (0x3F << I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT)
+#define I40E_GLGEN_RSTCTL_GRSTDEL_MASK I40E_MASK(0x3F, I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT)
#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT 8
-#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_MASK (0x1 << I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT)
-#define I40E_GLGEN_RSTENA_EMP 0x000B818C
+#define I40E_GLGEN_RSTCTL_ECC_RST_ENA_MASK I40E_MASK(0x1, I40E_GLGEN_RSTCTL_ECC_RST_ENA_SHIFT)
+#define I40E_GLGEN_RSTENA_EMP 0x000B818C /* Reset: POR */
#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT 0
-#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_MASK (0x1 << I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT)
-#define I40E_GLGEN_RTRIG 0x000B8190
+#define I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_MASK I40E_MASK(0x1, I40E_GLGEN_RSTENA_EMP_EMP_RST_ENA_SHIFT)
+#define I40E_GLGEN_RTRIG 0x000B8190 /* Reset: CORER */
#define I40E_GLGEN_RTRIG_CORER_SHIFT 0
-#define I40E_GLGEN_RTRIG_CORER_MASK (0x1 << I40E_GLGEN_RTRIG_CORER_SHIFT)
+#define I40E_GLGEN_RTRIG_CORER_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_CORER_SHIFT)
#define I40E_GLGEN_RTRIG_GLOBR_SHIFT 1
-#define I40E_GLGEN_RTRIG_GLOBR_MASK (0x1 << I40E_GLGEN_RTRIG_GLOBR_SHIFT)
+#define I40E_GLGEN_RTRIG_GLOBR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_GLOBR_SHIFT)
#define I40E_GLGEN_RTRIG_EMPFWR_SHIFT 2
-#define I40E_GLGEN_RTRIG_EMPFWR_MASK (0x1 << I40E_GLGEN_RTRIG_EMPFWR_SHIFT)
-#define I40E_GLGEN_STAT 0x000B612C
+#define I40E_GLGEN_RTRIG_EMPFWR_MASK I40E_MASK(0x1, I40E_GLGEN_RTRIG_EMPFWR_SHIFT)
+#define I40E_GLGEN_STAT 0x000B612C /* Reset: POR */
#define I40E_GLGEN_STAT_HWRSVD0_SHIFT 0
-#define I40E_GLGEN_STAT_HWRSVD0_MASK (0x3 << I40E_GLGEN_STAT_HWRSVD0_SHIFT)
+#define I40E_GLGEN_STAT_HWRSVD0_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD0_SHIFT)
#define I40E_GLGEN_STAT_DCBEN_SHIFT 2
-#define I40E_GLGEN_STAT_DCBEN_MASK (0x1 << I40E_GLGEN_STAT_DCBEN_SHIFT)
+#define I40E_GLGEN_STAT_DCBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_DCBEN_SHIFT)
#define I40E_GLGEN_STAT_VTEN_SHIFT 3
-#define I40E_GLGEN_STAT_VTEN_MASK (0x1 << I40E_GLGEN_STAT_VTEN_SHIFT)
+#define I40E_GLGEN_STAT_VTEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_VTEN_SHIFT)
#define I40E_GLGEN_STAT_FCOEN_SHIFT 4
-#define I40E_GLGEN_STAT_FCOEN_MASK (0x1 << I40E_GLGEN_STAT_FCOEN_SHIFT)
+#define I40E_GLGEN_STAT_FCOEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_FCOEN_SHIFT)
#define I40E_GLGEN_STAT_EVBEN_SHIFT 5
-#define I40E_GLGEN_STAT_EVBEN_MASK (0x1 << I40E_GLGEN_STAT_EVBEN_SHIFT)
+#define I40E_GLGEN_STAT_EVBEN_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_EVBEN_SHIFT)
#define I40E_GLGEN_STAT_HWRSVD1_SHIFT 6
-#define I40E_GLGEN_STAT_HWRSVD1_MASK (0x3 << I40E_GLGEN_STAT_HWRSVD1_SHIFT)
-#define I40E_GLGEN_VFLRSTAT(_i) (0x00092600 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLGEN_STAT_HWRSVD1_MASK I40E_MASK(0x3, I40E_GLGEN_STAT_HWRSVD1_SHIFT)
+#define I40E_GLGEN_VFLRSTAT(_i) (0x00092600 + ((_i) * 4)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLGEN_VFLRSTAT_MAX_INDEX 3
#define I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT 0
-#define I40E_GLGEN_VFLRSTAT_VFLRE_MASK (0xFFFFFFFF << I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT)
-#define I40E_GLVFGEN_TIMER 0x000881BC
+#define I40E_GLGEN_VFLRSTAT_VFLRE_MASK I40E_MASK(0xFFFFFFFF, I40E_GLGEN_VFLRSTAT_VFLRE_SHIFT)
+#define I40E_GLVFGEN_TIMER 0x000881BC /* Reset: CORER */
#define I40E_GLVFGEN_TIMER_GTIME_SHIFT 0
-#define I40E_GLVFGEN_TIMER_GTIME_MASK (0xFFFFFFFF << I40E_GLVFGEN_TIMER_GTIME_SHIFT)
-#define I40E_PFGEN_CTRL 0x00092400
+#define I40E_GLVFGEN_TIMER_GTIME_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVFGEN_TIMER_GTIME_SHIFT)
+#define I40E_PFGEN_CTRL 0x00092400 /* Reset: PFR */
#define I40E_PFGEN_CTRL_PFSWR_SHIFT 0
-#define I40E_PFGEN_CTRL_PFSWR_MASK (0x1 << I40E_PFGEN_CTRL_PFSWR_SHIFT)
-#define I40E_PFGEN_DRUN 0x00092500
+#define I40E_PFGEN_CTRL_PFSWR_MASK I40E_MASK(0x1, I40E_PFGEN_CTRL_PFSWR_SHIFT)
+#define I40E_PFGEN_DRUN 0x00092500 /* Reset: CORER */
#define I40E_PFGEN_DRUN_DRVUNLD_SHIFT 0
-#define I40E_PFGEN_DRUN_DRVUNLD_MASK (0x1 << I40E_PFGEN_DRUN_DRVUNLD_SHIFT)
-#define I40E_PFGEN_PORTNUM 0x001C0480
+#define I40E_PFGEN_DRUN_DRVUNLD_MASK I40E_MASK(0x1, I40E_PFGEN_DRUN_DRVUNLD_SHIFT)
+#define I40E_PFGEN_PORTNUM 0x001C0480 /* Reset: CORER */
#define I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT 0
-#define I40E_PFGEN_PORTNUM_PORT_NUM_MASK (0x3 << I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT)
-#define I40E_PFGEN_STATE 0x00088000
-#define I40E_PFGEN_STATE_PFPEEN_SHIFT 0
-#define I40E_PFGEN_STATE_PFPEEN_MASK (0x1 << I40E_PFGEN_STATE_PFPEEN_SHIFT)
+#define I40E_PFGEN_PORTNUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT)
+#define I40E_PFGEN_STATE 0x00088000 /* Reset: CORER */
+#define I40E_PFGEN_STATE_RESERVED_0_SHIFT 0
+#define I40E_PFGEN_STATE_RESERVED_0_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_RESERVED_0_SHIFT)
#define I40E_PFGEN_STATE_PFFCEN_SHIFT 1
-#define I40E_PFGEN_STATE_PFFCEN_MASK (0x1 << I40E_PFGEN_STATE_PFFCEN_SHIFT)
+#define I40E_PFGEN_STATE_PFFCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFFCEN_SHIFT)
#define I40E_PFGEN_STATE_PFLINKEN_SHIFT 2
-#define I40E_PFGEN_STATE_PFLINKEN_MASK (0x1 << I40E_PFGEN_STATE_PFLINKEN_SHIFT)
+#define I40E_PFGEN_STATE_PFLINKEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFLINKEN_SHIFT)
#define I40E_PFGEN_STATE_PFSCEN_SHIFT 3
-#define I40E_PFGEN_STATE_PFSCEN_MASK (0x1 << I40E_PFGEN_STATE_PFSCEN_SHIFT)
-#define I40E_PRTGEN_CNF 0x000B8120
+#define I40E_PFGEN_STATE_PFSCEN_MASK I40E_MASK(0x1, I40E_PFGEN_STATE_PFSCEN_SHIFT)
+#define I40E_PRTGEN_CNF 0x000B8120 /* Reset: POR */
#define I40E_PRTGEN_CNF_PORT_DIS_SHIFT 0
-#define I40E_PRTGEN_CNF_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_PORT_DIS_SHIFT)
#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT 1
-#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF_ALLOW_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_ALLOW_PORT_DIS_SHIFT)
#define I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT 2
-#define I40E_PRTGEN_CNF_EMP_PORT_DIS_MASK (0x1 << I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT)
-#define I40E_PRTGEN_CNF2 0x000B8160
+#define I40E_PRTGEN_CNF_EMP_PORT_DIS_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF_EMP_PORT_DIS_SHIFT)
+#define I40E_PRTGEN_CNF2 0x000B8160 /* Reset: POR */
#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT 0
-#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_MASK (0x1 << I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT)
-#define I40E_PRTGEN_STATUS 0x000B8100
+#define I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_MASK I40E_MASK(0x1, I40E_PRTGEN_CNF2_ACTIVATE_PORT_LINK_SHIFT)
+#define I40E_PRTGEN_STATUS 0x000B8100 /* Reset: POR */
#define I40E_PRTGEN_STATUS_PORT_VALID_SHIFT 0
-#define I40E_PRTGEN_STATUS_PORT_VALID_MASK (0x1 << I40E_PRTGEN_STATUS_PORT_VALID_SHIFT)
+#define I40E_PRTGEN_STATUS_PORT_VALID_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_VALID_SHIFT)
#define I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT 1
-#define I40E_PRTGEN_STATUS_PORT_ACTIVE_MASK (0x1 << I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT)
-#define I40E_VFGEN_RSTAT1(_VF) (0x00074400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PRTGEN_STATUS_PORT_ACTIVE_MASK I40E_MASK(0x1, I40E_PRTGEN_STATUS_PORT_ACTIVE_SHIFT)
+#define I40E_VFGEN_RSTAT1(_VF) (0x00074400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFGEN_RSTAT1_MAX_INDEX 127
#define I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT1_VFR_STATE_MASK (0x3 << I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT)
-#define I40E_VPGEN_VFRSTAT(_VF) (0x00091C00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFGEN_RSTAT1_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT1_VFR_STATE_SHIFT)
+#define I40E_VPGEN_VFRSTAT(_VF) (0x00091C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPGEN_VFRSTAT_MAX_INDEX 127
#define I40E_VPGEN_VFRSTAT_VFRD_SHIFT 0
-#define I40E_VPGEN_VFRSTAT_VFRD_MASK (0x1 << I40E_VPGEN_VFRSTAT_VFRD_SHIFT)
-#define I40E_VPGEN_VFRTRIG(_VF) (0x00091800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPGEN_VFRSTAT_VFRD_MASK I40E_MASK(0x1, I40E_VPGEN_VFRSTAT_VFRD_SHIFT)
+#define I40E_VPGEN_VFRTRIG(_VF) (0x00091800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPGEN_VFRTRIG_MAX_INDEX 127
#define I40E_VPGEN_VFRTRIG_VFSWR_SHIFT 0
-#define I40E_VPGEN_VFRTRIG_VFSWR_MASK (0x1 << I40E_VPGEN_VFRTRIG_VFSWR_SHIFT)
-#define I40E_VSIGEN_RSTAT(_VSI) (0x00090800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPGEN_VFRTRIG_VFSWR_MASK I40E_MASK(0x1, I40E_VPGEN_VFRTRIG_VFSWR_SHIFT)
+#define I40E_VSIGEN_RSTAT(_VSI) (0x00090800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_VSIGEN_RSTAT_MAX_INDEX 383
#define I40E_VSIGEN_RSTAT_VMRD_SHIFT 0
-#define I40E_VSIGEN_RSTAT_VMRD_MASK (0x1 << I40E_VSIGEN_RSTAT_VMRD_SHIFT)
-#define I40E_VSIGEN_RTRIG(_VSI) (0x00090000 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VSIGEN_RSTAT_VMRD_MASK I40E_MASK(0x1, I40E_VSIGEN_RSTAT_VMRD_SHIFT)
+#define I40E_VSIGEN_RTRIG(_VSI) (0x00090000 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_VSIGEN_RTRIG_MAX_INDEX 383
#define I40E_VSIGEN_RTRIG_VMSWR_SHIFT 0
-#define I40E_VSIGEN_RTRIG_VMSWR_MASK (0x1 << I40E_VSIGEN_RTRIG_VMSWR_SHIFT)
-#define I40E_GLHMC_APBVTINUSEBASE(_i) (0x000C4a00 + ((_i) * 4))
-#define I40E_GLHMC_APBVTINUSEBASE_MAX_INDEX 15
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_MASK (0xFFFFFF << I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_CEQPART(_i) (0x001312C0 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_CEQPART_MAX_INDEX 15
-#define I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_CEQPART_PMCEQBASE_MASK (0xFF << I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_CEQPART_PMCEQSIZE_MASK (0x1FF << I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_DBCQPART(_i) (0x00131240 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_DBCQPART_MAX_INDEX 15
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_DBCQPART_PMDBCQBASE_MASK (0x3FFF << I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_MASK (0x7FFF << I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_DBQPPART(_i) (0x00138D80 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_DBQPPART_MAX_INDEX 15
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_DBQPPART_PMDBQPBASE_MASK (0x3FFF << I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_MASK (0x7FFF << I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_FCOEDDPBASE(_i) (0x000C6600 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_VSIGEN_RTRIG_VMSWR_MASK I40E_MASK(0x1, I40E_VSIGEN_RTRIG_VMSWR_SHIFT)
+#define I40E_GLHMC_FCOEDDPBASE(_i) (0x000C6600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT 0
-#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK (0xFFFFFF << I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT)
-#define I40E_GLHMC_FCOEDDPCNT(_i) (0x000C6700 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_SHIFT)
+#define I40E_GLHMC_FCOEDDPCNT(_i) (0x000C6700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPCNT_MAX_INDEX 15
#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT 0
-#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_MASK (0xFFFFF << I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT)
-#define I40E_GLHMC_FCOEDDPOBJSZ 0x000C2010
+#define I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_MASK I40E_MASK(0xFFFFF, I40E_GLHMC_FCOEDDPCNT_FPMFCOEDDPCNT_SHIFT)
+#define I40E_GLHMC_FCOEDDPOBJSZ 0x000C2010 /* Reset: CORER */
#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_MASK (0xF << I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT)
-#define I40E_GLHMC_FCOEFBASE(_i) (0x000C6800 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEDDPOBJSZ_PMFCOEDDPOBJSZ_SHIFT)
+#define I40E_GLHMC_FCOEFBASE(_i) (0x000C6800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEFBASE_MAX_INDEX 15
#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT 0
-#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK (0xFFFFFF << I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT)
-#define I40E_GLHMC_FCOEFCNT(_i) (0x000C6900 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_SHIFT)
+#define I40E_GLHMC_FCOEFCNT(_i) (0x000C6900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FCOEFCNT_MAX_INDEX 15
#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT 0
-#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_MASK (0x7FFFFF << I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT)
-#define I40E_GLHMC_FCOEFMAX 0x000C20D0
+#define I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_MASK I40E_MASK(0x7FFFFF, I40E_GLHMC_FCOEFCNT_FPMFCOEFCNT_SHIFT)
+#define I40E_GLHMC_FCOEFMAX 0x000C20D0 /* Reset: CORER */
#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT 0
-#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK (0xFFFF << I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT)
-#define I40E_GLHMC_FCOEFOBJSZ 0x000C2018
+#define I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK I40E_MASK(0xFFFF, I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT)
+#define I40E_GLHMC_FCOEFOBJSZ 0x000C2018 /* Reset: CORER */
#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT 0
-#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_MASK (0xF << I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT)
-#define I40E_GLHMC_FCOEMAX 0x000C2014
+#define I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FCOEFOBJSZ_PMFCOEFOBJSZ_SHIFT)
+#define I40E_GLHMC_FCOEMAX 0x000C2014 /* Reset: CORER */
#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT 0
-#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_MASK (0x1FFF << I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT)
-#define I40E_GLHMC_FSIAVBASE(_i) (0x000C5600 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FCOEMAX_PMFCOEMAX_MASK I40E_MASK(0x1FFF, I40E_GLHMC_FCOEMAX_PMFCOEMAX_SHIFT)
+#define I40E_GLHMC_FSIAVBASE(_i) (0x000C5600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIAVBASE_MAX_INDEX 15
#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_MASK (0xFFFFFF << I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_FSIAVCNT(_i) (0x000C5700 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIAVBASE_FPMFSIAVBASE_SHIFT)
+#define I40E_GLHMC_FSIAVCNT(_i) (0x000C5700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIAVCNT_MAX_INDEX 15
#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_MASK (0x1FFFFFFF << I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT)
+#define I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIAVCNT_FPMFSIAVCNT_SHIFT)
#define I40E_GLHMC_FSIAVCNT_RSVD_SHIFT 29
-#define I40E_GLHMC_FSIAVCNT_RSVD_MASK (0x7 << I40E_GLHMC_FSIAVCNT_RSVD_SHIFT)
-#define I40E_GLHMC_FSIAVMAX 0x000C2068
+#define I40E_GLHMC_FSIAVCNT_RSVD_MASK I40E_MASK(0x7, I40E_GLHMC_FSIAVCNT_RSVD_SHIFT)
+#define I40E_GLHMC_FSIAVMAX 0x000C2068 /* Reset: CORER */
#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT 0
-#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_MASK (0x1FFFF << I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT)
-#define I40E_GLHMC_FSIAVOBJSZ 0x000C2064
+#define I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_MASK I40E_MASK(0x1FFFF, I40E_GLHMC_FSIAVMAX_PMFSIAVMAX_SHIFT)
+#define I40E_GLHMC_FSIAVOBJSZ 0x000C2064 /* Reset: CORER */
#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_MASK (0xF << I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT)
-#define I40E_GLHMC_FSIMCBASE(_i) (0x000C6000 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIAVOBJSZ_PMFSIAVOBJSZ_SHIFT)
+#define I40E_GLHMC_FSIMCBASE(_i) (0x000C6000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIMCBASE_MAX_INDEX 15
#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT 0
-#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_MASK (0xFFFFFF << I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT)
-#define I40E_GLHMC_FSIMCCNT(_i) (0x000C6100 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_FSIMCBASE_FPMFSIMCBASE_SHIFT)
+#define I40E_GLHMC_FSIMCCNT(_i) (0x000C6100 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_FSIMCCNT_MAX_INDEX 15
#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_MASK (0x1FFFFFFF << I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT)
-#define I40E_GLHMC_FSIMCMAX 0x000C2060
+#define I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_FSIMCCNT_FPMFSIMCSZ_SHIFT)
+#define I40E_GLHMC_FSIMCMAX 0x000C2060 /* Reset: CORER */
#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT 0
-#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_MASK (0x3FFF << I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT)
-#define I40E_GLHMC_FSIMCOBJSZ 0x000C205c
+#define I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_MASK I40E_MASK(0x3FFF, I40E_GLHMC_FSIMCMAX_PMFSIMCMAX_SHIFT)
+#define I40E_GLHMC_FSIMCOBJSZ 0x000C205c /* Reset: CORER */
#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT 0
-#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_MASK (0xF << I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT)
-#define I40E_GLHMC_LANQMAX 0x000C2008
+#define I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_FSIMCOBJSZ_PMFSIMCOBJSZ_SHIFT)
+#define I40E_GLHMC_LANQMAX 0x000C2008 /* Reset: CORER */
#define I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT 0
-#define I40E_GLHMC_LANQMAX_PMLANQMAX_MASK (0x7FF << I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT)
-#define I40E_GLHMC_LANRXBASE(_i) (0x000C6400 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANQMAX_PMLANQMAX_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANQMAX_PMLANQMAX_SHIFT)
+#define I40E_GLHMC_LANRXBASE(_i) (0x000C6400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANRXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT 0
-#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK (0xFFFFFF << I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT)
-#define I40E_GLHMC_LANRXCNT(_i) (0x000C6500 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANRXBASE_FPMLANRXBASE_SHIFT)
+#define I40E_GLHMC_LANRXCNT(_i) (0x000C6500 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANRXCNT_MAX_INDEX 15
#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT 0
-#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_MASK (0x7FF << I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT)
-#define I40E_GLHMC_LANRXOBJSZ 0x000C200c
+#define I40E_GLHMC_LANRXCNT_FPMLANRXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANRXCNT_FPMLANRXCNT_SHIFT)
+#define I40E_GLHMC_LANRXOBJSZ 0x000C200c /* Reset: CORER */
#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_MASK (0xF << I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT)
-#define I40E_GLHMC_LANTXBASE(_i) (0x000C6200 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANRXOBJSZ_PMLANRXOBJSZ_SHIFT)
+#define I40E_GLHMC_LANTXBASE(_i) (0x000C6200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANTXBASE_MAX_INDEX 15
#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT 0
-#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK (0xFFFFFF << I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT)
+#define I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_LANTXBASE_FPMLANTXBASE_SHIFT)
#define I40E_GLHMC_LANTXBASE_RSVD_SHIFT 24
-#define I40E_GLHMC_LANTXBASE_RSVD_MASK (0xFF << I40E_GLHMC_LANTXBASE_RSVD_SHIFT)
-#define I40E_GLHMC_LANTXCNT(_i) (0x000C6300 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANTXBASE_RSVD_MASK I40E_MASK(0xFF, I40E_GLHMC_LANTXBASE_RSVD_SHIFT)
+#define I40E_GLHMC_LANTXCNT(_i) (0x000C6300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_LANTXCNT_MAX_INDEX 15
#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT 0
-#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_MASK (0x7FF << I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT)
-#define I40E_GLHMC_LANTXOBJSZ 0x000C2004
+#define I40E_GLHMC_LANTXCNT_FPMLANTXCNT_MASK I40E_MASK(0x7FF, I40E_GLHMC_LANTXCNT_FPMLANTXCNT_SHIFT)
+#define I40E_GLHMC_LANTXOBJSZ 0x000C2004 /* Reset: CORER */
#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT 0
-#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_MASK (0xF << I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT)
-#define I40E_GLHMC_PEARPBASE(_i) (0x000C4800 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEARPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_MASK (0xFFFFFF << I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_PEARPCNT(_i) (0x000C4900 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEARPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_PEARPMAX 0x000C2038
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT 0
-#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_MASK (0x1FFFF << I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT)
-#define I40E_GLHMC_PEARPOBJSZ 0x000C2034
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_MASK (0x7 << I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT)
-#define I40E_GLHMC_PECQBASE(_i) (0x000C4200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PECQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_PECQBASE_FPMPECQBASE_MASK (0xFFFFFF << I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_PECQCNT(_i) (0x000C4300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PECQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_PECQCNT_FPMPECQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_PECQOBJSZ 0x000C2020
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_MASK (0xF << I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTCNT(_i) (0x000C4700 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEHTCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_PEHTEBASE(_i) (0x000C4600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEHTEBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_MASK (0xFFFFFF << I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_PEHTEOBJSZ 0x000C202c
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_MASK (0xF << I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT)
-#define I40E_GLHMC_PEHTMAX 0x000C2030
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT 0
-#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_MASK (0x1FFFFF << I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT)
-#define I40E_GLHMC_PEMRBASE(_i) (0x000C4c00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEMRBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_MASK (0xFFFFFF << I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_PEMRCNT(_i) (0x000C4d00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEMRCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_MASK (0x1FFFFFFF << I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_PEMRMAX 0x000C2040
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT 0
-#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_MASK (0x7FFFFF << I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT)
-#define I40E_GLHMC_PEMROBJSZ 0x000C203c
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT 0
-#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_MASK (0xF << I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT)
-#define I40E_GLHMC_PEPBLBASE(_i) (0x000C5800 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEPBLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_PEPBLCNT(_i) (0x000C5900 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEPBLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_PEPBLMAX 0x000C206c
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT 0
-#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_MASK (0x1FFFFFFF << I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT)
-#define I40E_GLHMC_PEQ1BASE(_i) (0x000C5200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1BASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_MASK (0xFFFFFF << I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_PEQ1CNT(_i) (0x000C5300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1CNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_PEQ1FLBASE(_i) (0x000C5400 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1FLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_PEQ1FLCNT(_i) (0x000C5500 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQ1FLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_SHIFT 0
-#define I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQ1FLCNT_FPMPEQ1FLCNT_SHIFT)
-#define I40E_GLHMC_PEQ1FLMAX 0x000C2058
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT 0
-#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_MASK (0x3FFFFFF << I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT)
-#define I40E_GLHMC_PEQ1MAX 0x000C2054
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT 0
-#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_MASK (0x3FFFFFF << I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT)
-#define I40E_GLHMC_PEQ1OBJSZ 0x000C2050
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_MASK (0xF << I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT)
-#define I40E_GLHMC_PEQPBASE(_i) (0x000C4000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQPBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_MASK (0xFFFFFF << I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_PEQPCNT(_i) (0x000C4100 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEQPCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_PEQPOBJSZ 0x000C201c
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_MASK (0xF << I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT)
-#define I40E_GLHMC_PESRQBASE(_i) (0x000C4400 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PESRQBASE_MAX_INDEX 15
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_MASK (0xFFFFFF << I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_PESRQCNT(_i) (0x000C4500 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PESRQCNT_MAX_INDEX 15
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_PESRQMAX 0x000C2028
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT 0
-#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_MASK (0xFFFF << I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT)
-#define I40E_GLHMC_PESRQOBJSZ 0x000C2024
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT 0
-#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_MASK (0xF << I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT)
-#define I40E_GLHMC_PESRQOBJSZ_RSVD_SHIFT 4
-#define I40E_GLHMC_PESRQOBJSZ_RSVD_MASK (0xFFFFFFF << I40E_GLHMC_PESRQOBJSZ_RSVD_SHIFT)
-#define I40E_GLHMC_PETIMERBASE(_i) (0x000C5A00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PETIMERBASE_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_MASK (0xFFFFFF << I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_PETIMERCNT(_i) (0x000C5B00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PETIMERCNT_MAX_INDEX 15
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_PETIMERMAX 0x000C2084
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT 0
-#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_MASK (0x1FFFFFFF << I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT)
-#define I40E_GLHMC_PETIMEROBJSZ 0x000C2080
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT 0
-#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_MASK (0xF << I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT)
-#define I40E_GLHMC_PEXFBASE(_i) (0x000C4e00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_MASK (0xFFFFFF << I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_PEXFCNT(_i) (0x000C4f00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_PEXFFLBASE(_i) (0x000C5000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFFLBASE_MAX_INDEX 15
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_MASK (0xFFFFFF << I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_PEXFFLCNT(_i) (0x000C5100 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLHMC_PEXFFLCNT_MAX_INDEX 15
-#define I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_SHIFT 0
-#define I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_PEXFFLCNT_FPMPEXFFLCNT_SHIFT)
-#define I40E_GLHMC_PEXFFLMAX 0x000C204c
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT 0
-#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_MASK (0x1FFFFFF << I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT)
-#define I40E_GLHMC_PEXFMAX 0x000C2048
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT 0
-#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_MASK (0x3FFFFFF << I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT)
-#define I40E_GLHMC_PEXFOBJSZ 0x000C2044
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT 0
-#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_MASK (0xF << I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT)
-#define I40E_GLHMC_PEXFOBJSZ_RSVD_SHIFT 4
-#define I40E_GLHMC_PEXFOBJSZ_RSVD_MASK (0xFFFFFFF << I40E_GLHMC_PEXFOBJSZ_RSVD_SHIFT)
-#define I40E_GLHMC_PFASSIGN(_i) (0x000C0c00 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_LANTXOBJSZ_PMLANTXOBJSZ_SHIFT)
+#define I40E_GLHMC_PFASSIGN(_i) (0x000C0c00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_PFASSIGN_MAX_INDEX 15
#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT 0
-#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_MASK (0xF << I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT)
-#define I40E_GLHMC_SDPART(_i) (0x000C0800 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_MASK I40E_MASK(0xF, I40E_GLHMC_PFASSIGN_PMFCNPFASSIGN_SHIFT)
+#define I40E_GLHMC_SDPART(_i) (0x000C0800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLHMC_SDPART_MAX_INDEX 15
#define I40E_GLHMC_SDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_SDPART_PMSDBASE_MASK (0xFFF << I40E_GLHMC_SDPART_PMSDBASE_SHIFT)
+#define I40E_GLHMC_SDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_SDPART_PMSDBASE_SHIFT)
#define I40E_GLHMC_SDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_SDPART_PMSDSIZE_MASK (0x1FFF << I40E_GLHMC_SDPART_PMSDSIZE_SHIFT)
-#define I40E_GLHMC_VFAPBVTINUSEBASE(_i) (0x000Cca00 + ((_i) * 4))
-#define I40E_GLHMC_VFAPBVTINUSEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
-#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_MASK (0xFFFFFF << I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART(_i) (0x00132240 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFCEQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT 0
-#define I40E_GLHMC_VFCEQPART_PMCEQBASE_MASK (0xFF << I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT)
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT 16
-#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_MASK (0x1FF << I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART(_i) (0x00132140 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFDBCQPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT 0
-#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_MASK (0x3FFF << I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT)
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_MASK (0x7FFF << I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART(_i) (0x00138E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFDBQPPART_MAX_INDEX 31
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT 0
-#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_MASK (0x3FFF << I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT)
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT 16
-#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_MASK (0x7FFF << I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT)
-#define I40E_GLHMC_VFFSIAVBASE(_i) (0x000Cd600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFFSIAVBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT 0
-#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_MASK (0xFFFFFF << I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT)
-#define I40E_GLHMC_VFFSIAVCNT(_i) (0x000Cd700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFFSIAVCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT 0
-#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT)
-#define I40E_GLHMC_VFFSIAVCNT_RSVD_SHIFT 29
-#define I40E_GLHMC_VFFSIAVCNT_RSVD_MASK (0x7 << I40E_GLHMC_VFFSIAVCNT_RSVD_SHIFT)
-#define I40E_GLHMC_VFPDINV(_i) (0x000C8300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPDINV_MAX_INDEX 31
-#define I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT 0
-#define I40E_GLHMC_VFPDINV_PMSDIDX_MASK (0xFFF << I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT)
-#define I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT 16
-#define I40E_GLHMC_VFPDINV_PMPDIDX_MASK (0x1FF << I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT)
-#define I40E_GLHMC_VFPEARPBASE(_i) (0x000Cc800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEARPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT)
-#define I40E_GLHMC_VFPEARPCNT(_i) (0x000Cc900 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEARPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT)
-#define I40E_GLHMC_VFPECQBASE(_i) (0x000Cc200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPECQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT 0
-#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT)
-#define I40E_GLHMC_VFPECQCNT(_i) (0x000Cc300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPECQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT 0
-#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTCNT(_i) (0x000Cc700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEHTCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT 0
-#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT)
-#define I40E_GLHMC_VFPEHTEBASE(_i) (0x000Cc600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEHTEBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT 0
-#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRBASE(_i) (0x000Ccc00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEMRBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT 0
-#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT)
-#define I40E_GLHMC_VFPEMRCNT(_i) (0x000Ccd00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEMRCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT 0
-#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT)
-#define I40E_GLHMC_VFPEPBLBASE(_i) (0x000Cd800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEPBLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT)
-#define I40E_GLHMC_VFPEPBLCNT(_i) (0x000Cd900 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEPBLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1BASE(_i) (0x000Cd200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1BASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT)
-#define I40E_GLHMC_VFPEQ1CNT(_i) (0x000Cd300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1CNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT 0
-#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT)
-#define I40E_GLHMC_VFPEQ1FLBASE(_i) (0x000Cd400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1FLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
-#define I40E_GLHMC_VFPEQ1FLCNT(_i) (0x000Cd500 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQ1FLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQ1FLCNT_FPMPEQ1FLCNT_SHIFT)
-#define I40E_GLHMC_VFPEQPBASE(_i) (0x000Cc000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQPBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT 0
-#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT)
-#define I40E_GLHMC_VFPEQPCNT(_i) (0x000Cc100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEQPCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT 0
-#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT)
-#define I40E_GLHMC_VFPESRQBASE(_i) (0x000Cc400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPESRQBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT 0
-#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT)
-#define I40E_GLHMC_VFPESRQCNT(_i) (0x000Cc500 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPESRQCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT 0
-#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT)
-#define I40E_GLHMC_VFPETIMERBASE(_i) (0x000CDA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPETIMERBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT 0
-#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT)
-#define I40E_GLHMC_VFPETIMERCNT(_i) (0x000CDB00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPETIMERCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT 0
-#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFBASE(_i) (0x000Cce00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT)
-#define I40E_GLHMC_VFPEXFCNT(_i) (0x000Ccf00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT 0
-#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT)
-#define I40E_GLHMC_VFPEXFFLBASE(_i) (0x000Cd000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFFLBASE_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
-#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_MASK (0xFFFFFF << I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT)
-#define I40E_GLHMC_VFPEXFFLCNT(_i) (0x000Cd100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFPEXFFLCNT_MAX_INDEX 31
-#define I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_SHIFT 0
-#define I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_MASK (0x1FFFFFFF << I40E_GLHMC_VFPEXFFLCNT_FPMPEXFFLCNT_SHIFT)
-#define I40E_GLHMC_VFSDPART(_i) (0x000C8800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLHMC_VFSDPART_MAX_INDEX 31
-#define I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT 0
-#define I40E_GLHMC_VFSDPART_PMSDBASE_MASK (0xFFF << I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT)
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT 16
-#define I40E_GLHMC_VFSDPART_PMSDSIZE_MASK (0x1FFF << I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT)
-#define I40E_PFHMC_ERRORDATA 0x000C0500
+#define I40E_GLHMC_SDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_SDPART_PMSDSIZE_SHIFT)
+#define I40E_PFHMC_ERRORDATA 0x000C0500 /* Reset: PFR */
#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT 0
-#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_MASK (0x3FFFFFFF << I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT)
-#define I40E_PFHMC_ERRORINFO 0x000C0400
+#define I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_MASK I40E_MASK(0x3FFFFFFF, I40E_PFHMC_ERRORDATA_HMC_ERROR_DATA_SHIFT)
+#define I40E_PFHMC_ERRORINFO 0x000C0400 /* Reset: PFR */
#define I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT 0
-#define I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK (0x1F << I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT)
+#define I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT)
#define I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT 7
-#define I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK (0x1 << I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT)
+#define I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT)
#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT 8
-#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK (0xF << I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT)
+#define I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK I40E_MASK(0xF, I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT)
#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT 16
-#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK (0x1F << I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT)
+#define I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK I40E_MASK(0x1F, I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT)
#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT 31
-#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK (0x1 << I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT)
-#define I40E_PFHMC_PDINV 0x000C0300
+#define I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK I40E_MASK(0x1, I40E_PFHMC_ERRORINFO_ERROR_DETECTED_SHIFT)
+#define I40E_PFHMC_PDINV 0x000C0300 /* Reset: PFR */
#define I40E_PFHMC_PDINV_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_PDINV_PMSDIDX_MASK (0xFFF << I40E_PFHMC_PDINV_PMSDIDX_SHIFT)
+#define I40E_PFHMC_PDINV_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_PDINV_PMSDIDX_SHIFT)
#define I40E_PFHMC_PDINV_PMPDIDX_SHIFT 16
-#define I40E_PFHMC_PDINV_PMPDIDX_MASK (0x1FF << I40E_PFHMC_PDINV_PMPDIDX_SHIFT)
-#define I40E_PFHMC_SDCMD 0x000C0000
+#define I40E_PFHMC_PDINV_PMPDIDX_MASK I40E_MASK(0x1FF, I40E_PFHMC_PDINV_PMPDIDX_SHIFT)
+#define I40E_PFHMC_SDCMD 0x000C0000 /* Reset: PFR */
#define I40E_PFHMC_SDCMD_PMSDIDX_SHIFT 0
-#define I40E_PFHMC_SDCMD_PMSDIDX_MASK (0xFFF << I40E_PFHMC_SDCMD_PMSDIDX_SHIFT)
+#define I40E_PFHMC_SDCMD_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_PFHMC_SDCMD_PMSDIDX_SHIFT)
#define I40E_PFHMC_SDCMD_PMSDWR_SHIFT 31
-#define I40E_PFHMC_SDCMD_PMSDWR_MASK (0x1 << I40E_PFHMC_SDCMD_PMSDWR_SHIFT)
-#define I40E_PFHMC_SDDATAHIGH 0x000C0200
+#define I40E_PFHMC_SDCMD_PMSDWR_MASK I40E_MASK(0x1, I40E_PFHMC_SDCMD_PMSDWR_SHIFT)
+#define I40E_PFHMC_SDDATAHIGH 0x000C0200 /* Reset: PFR */
#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT 0
-#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_MASK (0xFFFFFFFF << I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT)
-#define I40E_PFHMC_SDDATALOW 0x000C0100
+#define I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_PFHMC_SDDATAHIGH_PMSDDATAHIGH_SHIFT)
+#define I40E_PFHMC_SDDATALOW 0x000C0100 /* Reset: PFR */
#define I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT 0
-#define I40E_PFHMC_SDDATALOW_PMSDVALID_MASK (0x1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDVALID_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT 1
-#define I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK (0x1 << I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK I40E_MASK(0x1, I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT 2
-#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK (0x3FF << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT)
+#define I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK I40E_MASK(0x3FF, I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT)
#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT 12
-#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK (0xFFFFF << I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
-#define I40E_GL_UFUSE 0x00094008
+#define I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK I40E_MASK(0xFFFFF, I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
+#define I40E_GL_GP_FUSE(_i) (0x0009400C + ((_i) * 4)) /* _i=0...28 */ /* Reset: POR */
+#define I40E_GL_GP_FUSE_MAX_INDEX 28
+#define I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT 0
+#define I40E_GL_GP_FUSE_GL_GP_FUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_GP_FUSE_GL_GP_FUSE_SHIFT)
+#define I40E_GL_UFUSE 0x00094008 /* Reset: POR */
#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT 1
-#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_MASK (0x1 << I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT)
+#define I40E_GL_UFUSE_FOUR_PORT_ENABLE_MASK I40E_MASK(0x1, I40E_GL_UFUSE_FOUR_PORT_ENABLE_SHIFT)
#define I40E_GL_UFUSE_NIC_ID_SHIFT 2
-#define I40E_GL_UFUSE_NIC_ID_MASK (0x1 << I40E_GL_UFUSE_NIC_ID_SHIFT)
+#define I40E_GL_UFUSE_NIC_ID_MASK I40E_MASK(0x1, I40E_GL_UFUSE_NIC_ID_SHIFT)
#define I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT 10
-#define I40E_GL_UFUSE_ULT_LOCKOUT_MASK (0x1 << I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT)
+#define I40E_GL_UFUSE_ULT_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_ULT_LOCKOUT_SHIFT)
#define I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT 11
-#define I40E_GL_UFUSE_CLS_LOCKOUT_MASK (0x1 << I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT)
-#define I40E_EMPINT_GPIO_ENA 0x00088188
+#define I40E_GL_UFUSE_CLS_LOCKOUT_MASK I40E_MASK(0x1, I40E_GL_UFUSE_CLS_LOCKOUT_SHIFT)
+#define I40E_EMPINT_GPIO_ENA 0x00088188 /* Reset: POR */
#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO0_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO1_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO2_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO3_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO4_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO5_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO6_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO7_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO8_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO9_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO10_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO11_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO12_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO13_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO14_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO15_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO16_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO17_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO18_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO19_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO20_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO21_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO22_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO23_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO24_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO25_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO26_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO27_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT)
+#define I40E_EMPINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO28_ENA_SHIFT)
#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_MASK (0x1 << I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT)
-#define I40E_PFGEN_PORTMDIO_NUM 0x0003F100
+#define I40E_EMPINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_EMPINT_GPIO_ENA_GPIO29_ENA_SHIFT)
+#define I40E_PFGEN_PORTMDIO_NUM 0x0003F100 /* Reset: CORER */
#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT 0
-#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_MASK (0x3 << I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT)
+#define I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_MASK I40E_MASK(0x3, I40E_PFGEN_PORTMDIO_NUM_PORT_NUM_SHIFT)
#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT 4
-#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK (0x1 << I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT)
-#define I40E_PFINT_AEQCTL 0x00038700
+#define I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK I40E_MASK(0x1, I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_SHIFT)
+#define I40E_PFINT_AEQCTL 0x00038700 /* Reset: CORER */
#define I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_AEQCTL_MSIX_INDX_MASK (0xFF << I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_AEQCTL_ITR_INDX_MASK (0x3 << I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_AEQCTL_ITR_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_AEQCTL_MSIX0_INDX_MASK (0x7 << I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_PFINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_PFINT_AEQCTL_CAUSE_ENA_MASK (0x1 << I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_PFINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_AEQCTL_INTEVENT_MASK (0x1 << I40E_PFINT_AEQCTL_INTEVENT_SHIFT)
-#define I40E_PFINT_CEQCTL(_INTPF) (0x00036800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_AEQCTL_INTEVENT_SHIFT)
+#define I40E_PFINT_CEQCTL(_INTPF) (0x00036800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_PFINT_CEQCTL_MAX_INDEX 511
#define I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_PFINT_CEQCTL_MSIX_INDX_MASK (0xFF << I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_PFINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_PFINT_CEQCTL_ITR_INDX_MASK (0x3 << I40E_PFINT_CEQCTL_ITR_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_ITR_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_PFINT_CEQCTL_MSIX0_INDX_MASK (0x7 << I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_PFINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_PFINT_CEQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_PFINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_CEQCTL_NEXTQ_INDX_SHIFT)
#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_PFINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK (0x1 << I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_PFINT_CEQCTL_INTEVENT_MASK (0x1 << I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
-#define I40E_PFINT_DYN_CTL0 0x00038480
+#define I40E_PFINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
+#define I40E_PFINT_DYN_CTL0 0x00038480 /* Reset: PFR */
#define I40E_PFINT_DYN_CTL0_INTENA_SHIFT 0
-#define I40E_PFINT_DYN_CTL0_INTENA_MASK (0x1 << I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
#define I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT 1
-#define I40E_PFINT_DYN_CTL0_CLEARPBA_MASK (0x1 << I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_CLEARPBA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_CLEARPBA_SHIFT)
#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT 2
-#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK (0x1 << I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
#define I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT 3
-#define I40E_PFINT_DYN_CTL0_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTL0_INTERVAL_MASK (0xFFF << I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT)
+#define I40E_PFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTL0_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK (0x1 << I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
-#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
-#define I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK (0x1 << I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT)
-#define I40E_PFINT_DYN_CTLN(_INTPF) (0x00034800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_MSK_SHIFT)
+#define I40E_PFINT_DYN_CTLN(_INTPF) (0x00034800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_DYN_CTLN_MAX_INDEX 511
#define I40E_PFINT_DYN_CTLN_INTENA_SHIFT 0
-#define I40E_PFINT_DYN_CTLN_INTENA_MASK (0x1 << I40E_PFINT_DYN_CTLN_INTENA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT 1
-#define I40E_PFINT_DYN_CTLN_CLEARPBA_MASK (0x1 << I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_CLEARPBA_SHIFT)
#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT 2
-#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK (0x1 << I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
#define I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT 3
-#define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK (0xFFF << I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
+#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK (0x1 << I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK (0x3 << I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
#define I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_PFINT_DYN_CTLN_INTENA_MSK_MASK (0x1 << I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_PFINT_GPIO_ENA 0x00088080
+#define I40E_PFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_INTENA_MSK_SHIFT)
+#define I40E_PFINT_GPIO_ENA 0x00088080 /* Reset: CORER */
#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT 0
-#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO0_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO0_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT 1
-#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO1_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO1_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT 2
-#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO2_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO2_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT 3
-#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO3_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO3_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT 4
-#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO4_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO4_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT 5
-#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO5_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO5_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT 6
-#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO6_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO6_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT 7
-#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO7_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO7_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT 8
-#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO8_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO8_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT 9
-#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO9_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO9_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT 10
-#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO10_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO10_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT 11
-#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO11_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO11_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT 12
-#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO12_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO12_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT 13
-#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO13_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO13_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT 14
-#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO14_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO14_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT 15
-#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO15_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO15_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT 16
-#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO16_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO16_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT 17
-#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO17_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO17_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT 18
-#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO18_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO18_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT 19
-#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO19_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO19_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT 20
-#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO20_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO20_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT 21
-#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO21_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO21_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT 22
-#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO22_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO22_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT 23
-#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO23_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO23_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT 24
-#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO24_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO24_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT 25
-#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO25_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO25_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT 26
-#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO26_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO26_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT 27
-#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO27_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO27_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT 28
-#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT)
+#define I40E_PFINT_GPIO_ENA_GPIO28_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO28_ENA_SHIFT)
#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT 29
-#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_MASK (0x1 << I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT)
-#define I40E_PFINT_ICR0 0x00038780
+#define I40E_PFINT_GPIO_ENA_GPIO29_ENA_MASK I40E_MASK(0x1, I40E_PFINT_GPIO_ENA_GPIO29_ENA_SHIFT)
+#define I40E_PFINT_ICR0 0x00038780 /* Reset: CORER */
#define I40E_PFINT_ICR0_INTEVENT_SHIFT 0
-#define I40E_PFINT_ICR0_INTEVENT_MASK (0x1 << I40E_PFINT_ICR0_INTEVENT_SHIFT)
+#define I40E_PFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_INTEVENT_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_0_SHIFT 1
-#define I40E_PFINT_ICR0_QUEUE_0_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_0_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_0_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_PFINT_ICR0_QUEUE_1_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_1_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_1_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_PFINT_ICR0_QUEUE_2_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_2_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_2_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_PFINT_ICR0_QUEUE_3_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_3_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_3_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_4_SHIFT 5
-#define I40E_PFINT_ICR0_QUEUE_4_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_4_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_4_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_4_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_5_SHIFT 6
-#define I40E_PFINT_ICR0_QUEUE_5_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_5_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_5_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_5_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_6_SHIFT 7
-#define I40E_PFINT_ICR0_QUEUE_6_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_6_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_6_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_6_SHIFT)
#define I40E_PFINT_ICR0_QUEUE_7_SHIFT 8
-#define I40E_PFINT_ICR0_QUEUE_7_MASK (0x1 << I40E_PFINT_ICR0_QUEUE_7_SHIFT)
+#define I40E_PFINT_ICR0_QUEUE_7_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_QUEUE_7_SHIFT)
#define I40E_PFINT_ICR0_ECC_ERR_SHIFT 16
-#define I40E_PFINT_ICR0_ECC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ECC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ECC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ECC_ERR_SHIFT)
#define I40E_PFINT_ICR0_MAL_DETECT_SHIFT 19
-#define I40E_PFINT_ICR0_MAL_DETECT_MASK (0x1 << I40E_PFINT_ICR0_MAL_DETECT_SHIFT)
+#define I40E_PFINT_ICR0_MAL_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_MAL_DETECT_SHIFT)
#define I40E_PFINT_ICR0_GRST_SHIFT 20
-#define I40E_PFINT_ICR0_GRST_MASK (0x1 << I40E_PFINT_ICR0_GRST_SHIFT)
+#define I40E_PFINT_ICR0_GRST_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GRST_SHIFT)
#define I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT 21
-#define I40E_PFINT_ICR0_PCI_EXCEPTION_MASK (0x1 << I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT)
+#define I40E_PFINT_ICR0_PCI_EXCEPTION_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_PCI_EXCEPTION_SHIFT)
#define I40E_PFINT_ICR0_GPIO_SHIFT 22
-#define I40E_PFINT_ICR0_GPIO_MASK (0x1 << I40E_PFINT_ICR0_GPIO_SHIFT)
+#define I40E_PFINT_ICR0_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_GPIO_SHIFT)
#define I40E_PFINT_ICR0_TIMESYNC_SHIFT 23
-#define I40E_PFINT_ICR0_TIMESYNC_MASK (0x1 << I40E_PFINT_ICR0_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_STORM_DETECT_SHIFT 24
+#define I40E_PFINT_ICR0_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_STORM_DETECT_SHIFT)
#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK (0x1 << I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
+#define I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_HMC_ERR_SHIFT 26
-#define I40E_PFINT_ICR0_HMC_ERR_MASK (0x1 << I40E_PFINT_ICR0_HMC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_PE_CRITERR_SHIFT 28
-#define I40E_PFINT_ICR0_PE_CRITERR_MASK (0x1 << I40E_PFINT_ICR0_PE_CRITERR_SHIFT)
+#define I40E_PFINT_ICR0_PE_CRITERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_PE_CRITERR_SHIFT)
#define I40E_PFINT_ICR0_VFLR_SHIFT 29
-#define I40E_PFINT_ICR0_VFLR_MASK (0x1 << I40E_PFINT_ICR0_VFLR_SHIFT)
+#define I40E_PFINT_ICR0_VFLR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_VFLR_SHIFT)
#define I40E_PFINT_ICR0_ADMINQ_SHIFT 30
-#define I40E_PFINT_ICR0_ADMINQ_MASK (0x1 << I40E_PFINT_ICR0_ADMINQ_SHIFT)
+#define I40E_PFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ADMINQ_SHIFT)
#define I40E_PFINT_ICR0_SWINT_SHIFT 31
-#define I40E_PFINT_ICR0_SWINT_MASK (0x1 << I40E_PFINT_ICR0_SWINT_SHIFT)
-#define I40E_PFINT_ICR0_ENA 0x00038800
+#define I40E_PFINT_ICR0_SWINT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_SWINT_SHIFT)
+#define I40E_PFINT_ICR0_ENA 0x00038800 /* Reset: CORER */
#define I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT 16
-#define I40E_PFINT_ICR0_ENA_ECC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_ECC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_ECC_ERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT 19
-#define I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK (0x1 << I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT)
+#define I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_MAL_DETECT_SHIFT)
#define I40E_PFINT_ICR0_ENA_GRST_SHIFT 20
-#define I40E_PFINT_ICR0_ENA_GRST_MASK (0x1 << I40E_PFINT_ICR0_ENA_GRST_SHIFT)
+#define I40E_PFINT_ICR0_ENA_GRST_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_GRST_SHIFT)
#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT 21
-#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK (0x1 << I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT)
+#define I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_SHIFT)
#define I40E_PFINT_ICR0_ENA_GPIO_SHIFT 22
-#define I40E_PFINT_ICR0_ENA_GPIO_MASK (0x1 << I40E_PFINT_ICR0_ENA_GPIO_SHIFT)
+#define I40E_PFINT_ICR0_ENA_GPIO_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_GPIO_SHIFT)
#define I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT 23
-#define I40E_PFINT_ICR0_ENA_TIMESYNC_MASK (0x1 << I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_ENA_TIMESYNC_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_TIMESYNC_SHIFT)
+#define I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT 24
+#define I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_STORM_DETECT_SHIFT)
#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK (0x1 << I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
+#define I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
#define I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT 26
-#define I40E_PFINT_ICR0_ENA_HMC_ERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_HMC_ERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_HMC_ERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT 28
-#define I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK (0x1 << I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_PE_CRITERR_SHIFT)
#define I40E_PFINT_ICR0_ENA_VFLR_SHIFT 29
-#define I40E_PFINT_ICR0_ENA_VFLR_MASK (0x1 << I40E_PFINT_ICR0_ENA_VFLR_SHIFT)
+#define I40E_PFINT_ICR0_ENA_VFLR_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_VFLR_SHIFT)
#define I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT 30
-#define I40E_PFINT_ICR0_ENA_ADMINQ_MASK (0x1 << I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT)
+#define I40E_PFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_ADMINQ_SHIFT)
#define I40E_PFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_PFINT_ICR0_ENA_RSVD_MASK (0x1 << I40E_PFINT_ICR0_ENA_RSVD_SHIFT)
-#define I40E_PFINT_ITR0(_i) (0x00038000 + ((_i) * 128)) /* _i=0...2 */
+#define I40E_PFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_ENA_RSVD_SHIFT)
+#define I40E_PFINT_ITR0(_i) (0x00038000 + ((_i) * 128)) /* _i=0...2 */ /* Reset: PFR */
#define I40E_PFINT_ITR0_MAX_INDEX 2
#define I40E_PFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITR0_INTERVAL_MASK (0xFFF << I40E_PFINT_ITR0_INTERVAL_SHIFT)
-#define I40E_PFINT_ITRN(_i, _INTPF) (0x00030000 + ((_i) * 2048 + (_INTPF) * 4))
+#define I40E_PFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITR0_INTERVAL_SHIFT)
+#define I40E_PFINT_ITRN(_i, _INTPF) (0x00030000 + ((_i) * 2048 + (_INTPF) * 4)) /* _i=0...2, _INTPF=0...511 */ /* Reset: PFR */
#define I40E_PFINT_ITRN_MAX_INDEX 2
#define I40E_PFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_PFINT_ITRN_INTERVAL_MASK (0xFFF << I40E_PFINT_ITRN_INTERVAL_SHIFT)
-#define I40E_PFINT_LNKLST0 0x00038500
+#define I40E_PFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_ITRN_INTERVAL_SHIFT)
+#define I40E_PFINT_LNKLST0 0x00038500 /* Reset: PFR */
#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
-#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK (0x7FF << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT)
+#define I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT)
#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_MASK (0x3 << I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
-#define I40E_PFINT_LNKLSTN(_INTPF) (0x00035000 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
+#define I40E_PFINT_LNKLSTN(_INTPF) (0x00035000 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_LNKLSTN_MAX_INDEX 511
#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
-#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK (0x7FF << I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
+#define I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
-#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK (0x3 << I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_PFINT_RATE0 0x00038580
+#define I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
+#define I40E_PFINT_RATE0 0x00038580 /* Reset: PFR */
#define I40E_PFINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATE0_INTERVAL_MASK (0x3F << I40E_PFINT_RATE0_INTERVAL_SHIFT)
+#define I40E_PFINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATE0_INTERVAL_SHIFT)
#define I40E_PFINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATE0_INTRL_ENA_MASK (0x1 << I40E_PFINT_RATE0_INTRL_ENA_SHIFT)
-#define I40E_PFINT_RATEN(_INTPF) (0x00035800 + ((_INTPF) * 4)) /* _i=0...511 */
+#define I40E_PFINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATE0_INTRL_ENA_SHIFT)
+#define I40E_PFINT_RATEN(_INTPF) (0x00035800 + ((_INTPF) * 4)) /* _i=0...511 */ /* Reset: PFR */
#define I40E_PFINT_RATEN_MAX_INDEX 511
#define I40E_PFINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_PFINT_RATEN_INTERVAL_MASK (0x3F << I40E_PFINT_RATEN_INTERVAL_SHIFT)
+#define I40E_PFINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_PFINT_RATEN_INTERVAL_SHIFT)
#define I40E_PFINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_PFINT_RATEN_INTRL_ENA_MASK (0x1 << I40E_PFINT_RATEN_INTRL_ENA_SHIFT)
-#define I40E_PFINT_STAT_CTL0 0x00038400
+#define I40E_PFINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_PFINT_RATEN_INTRL_ENA_SHIFT)
+#define I40E_PFINT_STAT_CTL0 0x00038400 /* Reset: PFR */
#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK (0x3 << I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
-#define I40E_QINT_RQCTL(_Q) (0x0003A000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
+#define I40E_QINT_RQCTL(_Q) (0x0003A000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QINT_RQCTL_MAX_INDEX 1535
#define I40E_QINT_RQCTL_MSIX_INDX_SHIFT 0
-#define I40E_QINT_RQCTL_MSIX_INDX_MASK (0xFF << I40E_QINT_RQCTL_MSIX_INDX_SHIFT)
+#define I40E_QINT_RQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_RQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_RQCTL_ITR_INDX_SHIFT 11
-#define I40E_QINT_RQCTL_ITR_INDX_MASK (0x3 << I40E_QINT_RQCTL_ITR_INDX_SHIFT)
+#define I40E_QINT_RQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_QINT_RQCTL_ITR_INDX_SHIFT)
#define I40E_QINT_RQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_QINT_RQCTL_MSIX0_INDX_MASK (0x7 << I40E_QINT_RQCTL_MSIX0_INDX_SHIFT)
+#define I40E_QINT_RQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_QINT_RQCTL_MSIX0_INDX_SHIFT)
#define I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_QINT_RQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_QINT_RQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_RQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_QINT_RQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_RQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_QINT_RQCTL_CAUSE_ENA_MASK (0x1 << I40E_QINT_RQCTL_CAUSE_ENA_SHIFT)
+#define I40E_QINT_RQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_RQCTL_INTEVENT_SHIFT 31
-#define I40E_QINT_RQCTL_INTEVENT_MASK (0x1 << I40E_QINT_RQCTL_INTEVENT_SHIFT)
-#define I40E_QINT_TQCTL(_Q) (0x0003C000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QINT_RQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_RQCTL_INTEVENT_SHIFT)
+#define I40E_QINT_TQCTL(_Q) (0x0003C000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QINT_TQCTL_MAX_INDEX 1535
#define I40E_QINT_TQCTL_MSIX_INDX_SHIFT 0
-#define I40E_QINT_TQCTL_MSIX_INDX_MASK (0xFF << I40E_QINT_TQCTL_MSIX_INDX_SHIFT)
+#define I40E_QINT_TQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_QINT_TQCTL_MSIX_INDX_SHIFT)
#define I40E_QINT_TQCTL_ITR_INDX_SHIFT 11
-#define I40E_QINT_TQCTL_ITR_INDX_MASK (0x3 << I40E_QINT_TQCTL_ITR_INDX_SHIFT)
+#define I40E_QINT_TQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_QINT_TQCTL_ITR_INDX_SHIFT)
#define I40E_QINT_TQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_QINT_TQCTL_MSIX0_INDX_MASK (0x7 << I40E_QINT_TQCTL_MSIX0_INDX_SHIFT)
+#define I40E_QINT_TQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_QINT_TQCTL_MSIX0_INDX_SHIFT)
#define I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_QINT_TQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_QINT_TQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)
#define I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_QINT_TQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_QINT_TQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_QINT_TQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_QINT_TQCTL_CAUSE_ENA_MASK (0x1 << I40E_QINT_TQCTL_CAUSE_ENA_SHIFT)
+#define I40E_QINT_TQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_CAUSE_ENA_SHIFT)
#define I40E_QINT_TQCTL_INTEVENT_SHIFT 31
-#define I40E_QINT_TQCTL_INTEVENT_MASK (0x1 << I40E_QINT_TQCTL_INTEVENT_SHIFT)
-#define I40E_VFINT_DYN_CTL0(_VF) (0x0002A400 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_QINT_TQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_QINT_TQCTL_INTEVENT_SHIFT)
+#define I40E_VFINT_DYN_CTL0(_VF) (0x0002A400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTL0_MAX_INDEX 127
#define I40E_VFINT_DYN_CTL0_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL0_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTL0_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL0_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL0_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL0_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL0_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTL0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL0_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL0_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL0_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT)
-#define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_INTENA_MSK_SHIFT)
+#define I40E_VFINT_DYN_CTLN(_INTVF) (0x00024800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTLN_MAX_INDEX 511
#define I40E_VFINT_DYN_CTLN_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTLN_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0(_VF) (0x0002BC00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_DYN_CTLN_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_INTENA_MSK_SHIFT)
+#define I40E_VFINT_ICR0(_VF) (0x0002BC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VFINT_ICR0_MAX_INDEX 127
#define I40E_VFINT_ICR0_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR0_INTEVENT_MASK (0x1 << I40E_VFINT_ICR0_INTEVENT_SHIFT)
+#define I40E_VFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_INTEVENT_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR0_QUEUE_0_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_0_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_0_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR0_QUEUE_1_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_1_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_1_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR0_QUEUE_2_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_2_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_2_SHIFT)
#define I40E_VFINT_ICR0_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR0_QUEUE_3_MASK (0x1 << I40E_VFINT_ICR0_QUEUE_3_SHIFT)
+#define I40E_VFINT_ICR0_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_QUEUE_3_SHIFT)
#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_SWINT_SHIFT 31
-#define I40E_VFINT_ICR0_SWINT_MASK (0x1 << I40E_VFINT_ICR0_SWINT_SHIFT)
-#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_ICR0_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_SWINT_SHIFT)
+#define I40E_VFINT_ICR0_ENA(_VF) (0x0002C000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VFINT_ICR0_ENA_MAX_INDEX 127
#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ENA_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_ENA_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA_RSVD_MASK (0x1 << I40E_VFINT_ICR0_ENA_RSVD_SHIFT)
-#define I40E_VFINT_ITR0(_i, _VF) (0x00028000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...2, _VF=0...127 */
+#define I40E_VFINT_ICR0_ENA_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA_RSVD_SHIFT)
+#define I40E_VFINT_ITR0(_i, _VF) (0x00028000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...2, _VF=0...127 */ /* Reset: VFR */
#define I40E_VFINT_ITR0_MAX_INDEX 2
#define I40E_VFINT_ITR0_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR0_INTERVAL_MASK (0xFFF << I40E_VFINT_ITR0_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN(_i, _INTVF) (0x00020000 + ((_i) * 2048 + (_INTVF) * 4))
+#define I40E_VFINT_ITR0_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR0_INTERVAL_SHIFT)
+#define I40E_VFINT_ITRN(_i, _INTVF) (0x00020000 + ((_i) * 2048 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...511 */ /* Reset: VFR */
#define I40E_VFINT_ITRN_MAX_INDEX 2
#define I40E_VFINT_ITRN_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN_INTERVAL_MASK (0xFFF << I40E_VFINT_ITRN_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL0(_VF) (0x0002A000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_ITRN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN_INTERVAL_SHIFT)
+#define I40E_VFINT_STAT_CTL0(_VF) (0x0002A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VFINT_STAT_CTL0_MAX_INDEX 127
#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_MASK (0x3 << I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
-#define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL(_VF) (0x0002B800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VPINT_AEQCTL_MAX_INDEX 127
#define I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_AEQCTL_MSIX_INDX_MASK (0xFF << I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_AEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_AEQCTL_ITR_INDX_MASK (0x3 << I40E_VPINT_AEQCTL_ITR_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_AEQCTL_ITR_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_AEQCTL_MSIX0_INDX_MASK (0x7 << I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_VPINT_AEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_AEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_VPINT_AEQCTL_CAUSE_ENA_MASK (0x1 << I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_VPINT_AEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_CAUSE_ENA_SHIFT)
#define I40E_VPINT_AEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_AEQCTL_INTEVENT_MASK (0x1 << I40E_VPINT_AEQCTL_INTEVENT_SHIFT)
-#define I40E_VPINT_CEQCTL(_INTVF) (0x00026800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_AEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_AEQCTL_INTEVENT_SHIFT)
+#define I40E_VPINT_CEQCTL(_INTVF) (0x00026800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_VPINT_CEQCTL_MAX_INDEX 511
#define I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT 0
-#define I40E_VPINT_CEQCTL_MSIX_INDX_MASK (0xFF << I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_MSIX_INDX_MASK I40E_MASK(0xFF, I40E_VPINT_CEQCTL_MSIX_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_ITR_INDX_SHIFT 11
-#define I40E_VPINT_CEQCTL_ITR_INDX_MASK (0x3 << I40E_VPINT_CEQCTL_ITR_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_ITR_INDX_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_ITR_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT 13
-#define I40E_VPINT_CEQCTL_MSIX0_INDX_MASK (0x7 << I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_MSIX0_INDX_MASK I40E_MASK(0x7, I40E_VPINT_CEQCTL_MSIX0_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT 16
-#define I40E_VPINT_CEQCTL_NEXTQ_INDX_MASK (0x7FF << I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT)
+#define I40E_VPINT_CEQCTL_NEXTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_CEQCTL_NEXTQ_INDX_SHIFT)
#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT 27
-#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_MASK (0x3 << I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT)
+#define I40E_VPINT_CEQCTL_NEXTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_CEQCTL_NEXTQ_TYPE_SHIFT)
#define I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT 30
-#define I40E_VPINT_CEQCTL_CAUSE_ENA_MASK (0x1 << I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT)
+#define I40E_VPINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_VPINT_CEQCTL_INTEVENT_SHIFT 31
-#define I40E_VPINT_CEQCTL_INTEVENT_MASK (0x1 << I40E_VPINT_CEQCTL_INTEVENT_SHIFT)
-#define I40E_VPINT_LNKLST0(_VF) (0x0002A800 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_VPINT_CEQCTL_INTEVENT_SHIFT)
+#define I40E_VPINT_LNKLST0(_VF) (0x0002A800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPINT_LNKLST0_MAX_INDEX 127
#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT 0
-#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK (0x7FF << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT)
+#define I40E_VPINT_LNKLST0_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT)
#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT 11
-#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_MASK (0x3 << I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
-#define I40E_VPINT_LNKLSTN(_INTVF) (0x00025000 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_LNKLST0_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)
+#define I40E_VPINT_LNKLSTN(_INTVF) (0x00025000 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VPINT_LNKLSTN_MAX_INDEX 511
#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT 0
-#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK (0x7FF << I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
+#define I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK I40E_MASK(0x7FF, I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT)
#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT 11
-#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK (0x3 << I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
-#define I40E_VPINT_RATE0(_VF) (0x0002AC00 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_MASK I40E_MASK(0x3, I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)
+#define I40E_VPINT_RATE0(_VF) (0x0002AC00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPINT_RATE0_MAX_INDEX 127
#define I40E_VPINT_RATE0_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATE0_INTERVAL_MASK (0x3F << I40E_VPINT_RATE0_INTERVAL_SHIFT)
+#define I40E_VPINT_RATE0_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATE0_INTERVAL_SHIFT)
#define I40E_VPINT_RATE0_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATE0_INTRL_ENA_MASK (0x1 << I40E_VPINT_RATE0_INTRL_ENA_SHIFT)
-#define I40E_VPINT_RATEN(_INTVF) (0x00025800 + ((_INTVF) * 4)) /* _i=0...511 */
+#define I40E_VPINT_RATE0_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATE0_INTRL_ENA_SHIFT)
+#define I40E_VPINT_RATEN(_INTVF) (0x00025800 + ((_INTVF) * 4)) /* _i=0...511 */ /* Reset: VFR */
#define I40E_VPINT_RATEN_MAX_INDEX 511
#define I40E_VPINT_RATEN_INTERVAL_SHIFT 0
-#define I40E_VPINT_RATEN_INTERVAL_MASK (0x3F << I40E_VPINT_RATEN_INTERVAL_SHIFT)
+#define I40E_VPINT_RATEN_INTERVAL_MASK I40E_MASK(0x3F, I40E_VPINT_RATEN_INTERVAL_SHIFT)
#define I40E_VPINT_RATEN_INTRL_ENA_SHIFT 6
-#define I40E_VPINT_RATEN_INTRL_ENA_MASK (0x1 << I40E_VPINT_RATEN_INTRL_ENA_SHIFT)
-#define I40E_GL_RDPU_CNTRL 0x00051060
+#define I40E_VPINT_RATEN_INTRL_ENA_MASK I40E_MASK(0x1, I40E_VPINT_RATEN_INTRL_ENA_SHIFT)
+#define I40E_GL_RDPU_CNTRL 0x00051060 /* Reset: CORER */
#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT 0
-#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_MASK (0x1 << I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT)
+#define I40E_GL_RDPU_CNTRL_RX_PAD_EN_MASK I40E_MASK(0x1, I40E_GL_RDPU_CNTRL_RX_PAD_EN_SHIFT)
#define I40E_GL_RDPU_CNTRL_ECO_SHIFT 1
-#define I40E_GL_RDPU_CNTRL_ECO_MASK (0x7FFFFFFF << I40E_GL_RDPU_CNTRL_ECO_SHIFT)
-#define I40E_GLLAN_RCTL_0 0x0012A500
+#define I40E_GL_RDPU_CNTRL_ECO_MASK I40E_MASK(0x7FFFFFFF, I40E_GL_RDPU_CNTRL_ECO_SHIFT)
+#define I40E_GLLAN_RCTL_0 0x0012A500 /* Reset: CORER */
#define I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT 0
-#define I40E_GLLAN_RCTL_0_PXE_MODE_MASK (0x1 << I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT)
-#define I40E_GLLAN_TSOMSK_F 0x000442D8
+#define I40E_GLLAN_RCTL_0_PXE_MODE_MASK I40E_MASK(0x1, I40E_GLLAN_RCTL_0_PXE_MODE_SHIFT)
+#define I40E_GLLAN_TSOMSK_F 0x000442D8 /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT 0
-#define I40E_GLLAN_TSOMSK_F_TCPMSKF_MASK (0xFFF << I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT)
-#define I40E_GLLAN_TSOMSK_L 0x000442E0
+#define I40E_GLLAN_TSOMSK_F_TCPMSKF_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_F_TCPMSKF_SHIFT)
+#define I40E_GLLAN_TSOMSK_L 0x000442E0 /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT 0
-#define I40E_GLLAN_TSOMSK_L_TCPMSKL_MASK (0xFFF << I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT)
-#define I40E_GLLAN_TSOMSK_M 0x000442DC
+#define I40E_GLLAN_TSOMSK_L_TCPMSKL_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_L_TCPMSKL_SHIFT)
+#define I40E_GLLAN_TSOMSK_M 0x000442DC /* Reset: CORER */
#define I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT 0
-#define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK (0xFFF << I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT)
-#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000E6500 + ((_i) * 4)) /* i=0..11 */
+#define I40E_GLLAN_TSOMSK_M_TCPMSKM_MASK I40E_MASK(0xFFF, I40E_GLLAN_TSOMSK_M_TCPMSKM_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS(_i) (0x000e6500 + ((_i) * 4)) /* _i=0...11 */ /* Reset: CORER */
+#define I40E_GLLAN_TXPRE_QDIS_MAX_INDEX 11
#define I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT 0
-#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK (0x7FF << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_QINDX_MASK I40E_MASK(0x7FF, I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT 16
+#define I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_QDIS_STAT_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT 30
-#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT)
+#define I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_SET_QDIS_SHIFT)
#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT 31
-#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK (0x1 << I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT)
-
-#define I40E_PFLAN_QALLOC 0x001C0400
+#define I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK I40E_MASK(0x1, I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_SHIFT)
+#define I40E_PFLAN_QALLOC 0x001C0400 /* Reset: CORER */
#define I40E_PFLAN_QALLOC_FIRSTQ_SHIFT 0
-#define I40E_PFLAN_QALLOC_FIRSTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_FIRSTQ_SHIFT)
+#define I40E_PFLAN_QALLOC_FIRSTQ_MASK I40E_MASK(0x7FF, I40E_PFLAN_QALLOC_FIRSTQ_SHIFT)
#define I40E_PFLAN_QALLOC_LASTQ_SHIFT 16
-#define I40E_PFLAN_QALLOC_LASTQ_MASK (0x7FF << I40E_PFLAN_QALLOC_LASTQ_SHIFT)
+#define I40E_PFLAN_QALLOC_LASTQ_MASK I40E_MASK(0x7FF, I40E_PFLAN_QALLOC_LASTQ_SHIFT)
#define I40E_PFLAN_QALLOC_VALID_SHIFT 31
-#define I40E_PFLAN_QALLOC_VALID_MASK (0x1 << I40E_PFLAN_QALLOC_VALID_SHIFT)
-#define I40E_QRX_ENA(_Q) (0x00120000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_PFLAN_QALLOC_VALID_MASK I40E_MASK(0x1, I40E_PFLAN_QALLOC_VALID_SHIFT)
+#define I40E_QRX_ENA(_Q) (0x00120000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QRX_ENA_MAX_INDEX 1535
#define I40E_QRX_ENA_QENA_REQ_SHIFT 0
-#define I40E_QRX_ENA_QENA_REQ_MASK (0x1 << I40E_QRX_ENA_QENA_REQ_SHIFT)
+#define I40E_QRX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_REQ_SHIFT)
#define I40E_QRX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QRX_ENA_FAST_QDIS_MASK (0x1 << I40E_QRX_ENA_FAST_QDIS_SHIFT)
+#define I40E_QRX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QRX_ENA_FAST_QDIS_SHIFT)
#define I40E_QRX_ENA_QENA_STAT_SHIFT 2
-#define I40E_QRX_ENA_QENA_STAT_MASK (0x1 << I40E_QRX_ENA_QENA_STAT_SHIFT)
-#define I40E_QRX_TAIL(_Q) (0x00128000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QRX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QRX_ENA_QENA_STAT_SHIFT)
+#define I40E_QRX_TAIL(_Q) (0x00128000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QRX_TAIL_MAX_INDEX 1535
#define I40E_QRX_TAIL_TAIL_SHIFT 0
-#define I40E_QRX_TAIL_TAIL_MASK (0x1FFF << I40E_QRX_TAIL_TAIL_SHIFT)
-#define I40E_QTX_CTL(_Q) (0x00104000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QRX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL_TAIL_SHIFT)
+#define I40E_QTX_CTL(_Q) (0x00104000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QTX_CTL_MAX_INDEX 1535
#define I40E_QTX_CTL_PFVF_Q_SHIFT 0
-#define I40E_QTX_CTL_PFVF_Q_MASK (0x3 << I40E_QTX_CTL_PFVF_Q_SHIFT)
+#define I40E_QTX_CTL_PFVF_Q_MASK I40E_MASK(0x3, I40E_QTX_CTL_PFVF_Q_SHIFT)
#define I40E_QTX_CTL_PF_INDX_SHIFT 2
-#define I40E_QTX_CTL_PF_INDX_MASK (0xF << I40E_QTX_CTL_PF_INDX_SHIFT)
+#define I40E_QTX_CTL_PF_INDX_MASK I40E_MASK(0xF, I40E_QTX_CTL_PF_INDX_SHIFT)
#define I40E_QTX_CTL_VFVM_INDX_SHIFT 7
-#define I40E_QTX_CTL_VFVM_INDX_MASK (0x1FF << I40E_QTX_CTL_VFVM_INDX_SHIFT)
-#define I40E_QTX_ENA(_Q) (0x00100000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_CTL_VFVM_INDX_MASK I40E_MASK(0x1FF, I40E_QTX_CTL_VFVM_INDX_SHIFT)
+#define I40E_QTX_ENA(_Q) (0x00100000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QTX_ENA_MAX_INDEX 1535
#define I40E_QTX_ENA_QENA_REQ_SHIFT 0
-#define I40E_QTX_ENA_QENA_REQ_MASK (0x1 << I40E_QTX_ENA_QENA_REQ_SHIFT)
+#define I40E_QTX_ENA_QENA_REQ_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_REQ_SHIFT)
#define I40E_QTX_ENA_FAST_QDIS_SHIFT 1
-#define I40E_QTX_ENA_FAST_QDIS_MASK (0x1 << I40E_QTX_ENA_FAST_QDIS_SHIFT)
+#define I40E_QTX_ENA_FAST_QDIS_MASK I40E_MASK(0x1, I40E_QTX_ENA_FAST_QDIS_SHIFT)
#define I40E_QTX_ENA_QENA_STAT_SHIFT 2
-#define I40E_QTX_ENA_QENA_STAT_MASK (0x1 << I40E_QTX_ENA_QENA_STAT_SHIFT)
-#define I40E_QTX_HEAD(_Q) (0x000E4000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_ENA_QENA_STAT_MASK I40E_MASK(0x1, I40E_QTX_ENA_QENA_STAT_SHIFT)
+#define I40E_QTX_HEAD(_Q) (0x000E4000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: CORER */
#define I40E_QTX_HEAD_MAX_INDEX 1535
#define I40E_QTX_HEAD_HEAD_SHIFT 0
-#define I40E_QTX_HEAD_HEAD_MASK (0x1FFF << I40E_QTX_HEAD_HEAD_SHIFT)
+#define I40E_QTX_HEAD_HEAD_MASK I40E_MASK(0x1FFF, I40E_QTX_HEAD_HEAD_SHIFT)
#define I40E_QTX_HEAD_RS_PENDING_SHIFT 16
-#define I40E_QTX_HEAD_RS_PENDING_MASK (0x1 << I40E_QTX_HEAD_RS_PENDING_SHIFT)
-#define I40E_QTX_TAIL(_Q) (0x00108000 + ((_Q) * 4)) /* _i=0...1535 */
+#define I40E_QTX_HEAD_RS_PENDING_MASK I40E_MASK(0x1, I40E_QTX_HEAD_RS_PENDING_SHIFT)
+#define I40E_QTX_TAIL(_Q) (0x00108000 + ((_Q) * 4)) /* _i=0...1535 */ /* Reset: PFR */
#define I40E_QTX_TAIL_MAX_INDEX 1535
#define I40E_QTX_TAIL_TAIL_SHIFT 0
-#define I40E_QTX_TAIL_TAIL_MASK (0x1FFF << I40E_QTX_TAIL_TAIL_SHIFT)
-#define I40E_VPLAN_MAPENA(_VF) (0x00074000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_QTX_TAIL_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL_TAIL_SHIFT)
+#define I40E_VPLAN_MAPENA(_VF) (0x00074000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPLAN_MAPENA_MAX_INDEX 127
#define I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT 0
-#define I40E_VPLAN_MAPENA_TXRX_ENA_MASK (0x1 << I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT)
-#define I40E_VPLAN_QTABLE(_i, _VF) (0x00070000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */
+#define I40E_VPLAN_MAPENA_TXRX_ENA_MASK I40E_MASK(0x1, I40E_VPLAN_MAPENA_TXRX_ENA_SHIFT)
+#define I40E_VPLAN_QTABLE(_i, _VF) (0x00070000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: VFR */
#define I40E_VPLAN_QTABLE_MAX_INDEX 15
#define I40E_VPLAN_QTABLE_QINDEX_SHIFT 0
-#define I40E_VPLAN_QTABLE_QINDEX_MASK (0x7FF << I40E_VPLAN_QTABLE_QINDEX_SHIFT)
-#define I40E_VSILAN_QBASE(_VSI) (0x0020C800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPLAN_QTABLE_QINDEX_MASK I40E_MASK(0x7FF, I40E_VPLAN_QTABLE_QINDEX_SHIFT)
+#define I40E_VSILAN_QBASE(_VSI) (0x0020C800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
#define I40E_VSILAN_QBASE_MAX_INDEX 383
#define I40E_VSILAN_QBASE_VSIBASE_SHIFT 0
-#define I40E_VSILAN_QBASE_VSIBASE_MASK (0x7FF << I40E_VSILAN_QBASE_VSIBASE_SHIFT)
+#define I40E_VSILAN_QBASE_VSIBASE_MASK I40E_MASK(0x7FF, I40E_VSILAN_QBASE_VSIBASE_SHIFT)
#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT 11
-#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK (0x1 << I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT)
-#define I40E_VSILAN_QTABLE(_i, _VSI) (0x00200000 + ((_i) * 2048 + (_VSI) * 4))
+#define I40E_VSILAN_QBASE_VSIQTABLE_ENA_MASK I40E_MASK(0x1, I40E_VSILAN_QBASE_VSIQTABLE_ENA_SHIFT)
+#define I40E_VSILAN_QTABLE(_i, _VSI) (0x00200000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...7, _VSI=0...383 */ /* Reset: PFR */
#define I40E_VSILAN_QTABLE_MAX_INDEX 7
#define I40E_VSILAN_QTABLE_QINDEX_0_SHIFT 0
-#define I40E_VSILAN_QTABLE_QINDEX_0_MASK (0x7FF << I40E_VSILAN_QTABLE_QINDEX_0_SHIFT)
+#define I40E_VSILAN_QTABLE_QINDEX_0_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_0_SHIFT)
#define I40E_VSILAN_QTABLE_QINDEX_1_SHIFT 16
-#define I40E_VSILAN_QTABLE_QINDEX_1_MASK (0x7FF << I40E_VSILAN_QTABLE_QINDEX_1_SHIFT)
-#define I40E_PRTGL_SAH 0x001E2140
+#define I40E_VSILAN_QTABLE_QINDEX_1_MASK I40E_MASK(0x7FF, I40E_VSILAN_QTABLE_QINDEX_1_SHIFT)
+#define I40E_PRTGL_SAH 0x001E2140 /* Reset: GLOBR */
#define I40E_PRTGL_SAH_FC_SAH_SHIFT 0
-#define I40E_PRTGL_SAH_FC_SAH_MASK (0xFFFF << I40E_PRTGL_SAH_FC_SAH_SHIFT)
+#define I40E_PRTGL_SAH_FC_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTGL_SAH_FC_SAH_SHIFT)
#define I40E_PRTGL_SAH_MFS_SHIFT 16
-#define I40E_PRTGL_SAH_MFS_MASK (0xFFFF << I40E_PRTGL_SAH_MFS_SHIFT)
-#define I40E_PRTGL_SAL 0x001E2120
+#define I40E_PRTGL_SAH_MFS_MASK I40E_MASK(0xFFFF, I40E_PRTGL_SAH_MFS_SHIFT)
+#define I40E_PRTGL_SAL 0x001E2120 /* Reset: GLOBR */
#define I40E_PRTGL_SAL_FC_SAL_SHIFT 0
-#define I40E_PRTGL_SAL_FC_SAL_MASK (0xFFFFFFFF << I40E_PRTGL_SAL_FC_SAL_SHIFT)
-#define I40E_PRTMAC_HLCTLA 0x001E4760
-#define I40E_PRTMAC_HLCTLA_DROP_US_PKTS_SHIFT 0
-#define I40E_PRTMAC_HLCTLA_DROP_US_PKTS_MASK (0x1 << I40E_PRTMAC_HLCTLA_DROP_US_PKTS_SHIFT)
-#define I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_SHIFT 1
-#define I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_MASK (0x1 << I40E_PRTMAC_HLCTLA_RX_FWRD_CTRL_SHIFT)
-#define I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_SHIFT 2
-#define I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_MASK (0x1 << I40E_PRTMAC_HLCTLA_CHOP_OS_PKT_SHIFT)
-#define I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_SHIFT 4
-#define I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_MASK (0x7 << I40E_PRTMAC_HLCTLA_TX_HYSTERESIS_SHIFT)
-#define I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_SHIFT 7
-#define I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_MASK (0x1 << I40E_PRTMAC_HLCTLA_HYS_FLUSH_PKT_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP 0x001E3130
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GCP_HSEC_CTL_RX_CHECK_SA_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP 0x001E3290
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_GPP_HSEC_CTL_RX_CHECK_SA_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP 0x001E3310
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_SA_PPP_HSEC_CTL_RX_CHECK_SA_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP 0x001E3100
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GCP_HSEC_CTL_RX_CHECK_UCAST_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP 0x001E3280
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_GPP_HSEC_CTL_RX_CHECK_UCAST_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP 0x001E3300
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_CHECK_UCAST_PPP_HSEC_CTL_RX_CHECK_UCAST_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP 0x001E30E0
+#define I40E_PRTGL_SAL_FC_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTGL_SAL_FC_SAL_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP 0x001E30E0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP 0x001E3260
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GCP_HSEC_CTL_RX_ENABLE_GCP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP 0x001E3260 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP 0x001E32E0
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_HSEC_CTL_RX_ENABLE_GPP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP 0x001E32E0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL 0x001E3360
+#define I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_HSEC_CTL_RX_ENABLE_PPP_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL 0x001E3360 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1 0x001E3110
+#define I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_MASK I40E_MASK(0x1, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL_HSEC_CTL_RX_FORWARD_CONTROL_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1 0x001E3110 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2 0x001E3120
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_HSEC_CTL_RX_PAUSE_DA_UCAST_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2 0x001E3120 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE 0x001E30C0
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_HSEC_CTL_RX_PAUSE_DA_UCAST_PART2_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE 0x001E30C0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK (0x1FF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1 0x001E3140
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1 0x001E3140 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2 0x001E3150
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART1_HSEC_CTL_RX_PAUSE_SA_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2 0x001E3150 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE 0x001E3000
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_MASK (0x1 << I40E_PRTMAC_HSEC_CTL_TX_ENABLE_HSEC_CTL_TX_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE 0x001E30D0
+#define I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_SA_PART2_HSEC_CTL_RX_PAUSE_SA_PART2_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE 0x001E30D0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK (0x1FF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E3370 + ((_i) * 16))
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_MASK I40E_MASK(0x1FF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(_i) (0x001E3370 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX 8
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3400 + ((_i) * 16))
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(_i) (0x001E3400 + ((_i) * 16)) /* _i=0...8 */ /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MAX_INDEX 8
#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1 0x001E34B0
+#define I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1 0x001E34B0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_MASK (0xFFFFFFFF << I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT)
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2 0x001E34C0
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART1_HSEC_CTL_TX_SA_PART1_SHIFT)
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2 0x001E34C0 /* Reset: GLOBR */
#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT 0
-#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_MASK (0xFFFF << I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT)
-#define I40E_PRTMAC_HSECTL1 0x001E3560
-#define I40E_PRTMAC_HSECTL1_DROP_US_PKTS_SHIFT 0
-#define I40E_PRTMAC_HSECTL1_DROP_US_PKTS_MASK (0x1 << I40E_PRTMAC_HSECTL1_DROP_US_PKTS_SHIFT)
-#define I40E_PRTMAC_HSECTL1_PAD_US_PKT_SHIFT 3
-#define I40E_PRTMAC_HSECTL1_PAD_US_PKT_MASK (0x1 << I40E_PRTMAC_HSECTL1_PAD_US_PKT_SHIFT)
-#define I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_SHIFT 4
-#define I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_MASK (0x7 << I40E_PRTMAC_HSECTL1_TX_HYSTERESIS_SHIFT)
-#define I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_SHIFT 7
-#define I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_MASK (0x1 << I40E_PRTMAC_HSECTL1_HYS_FLUSH_PKT_SHIFT)
-#define I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_SHIFT 30
-#define I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_MASK (0x1 << I40E_PRTMAC_HSECTL1_EN_SFD_CHECK_SHIFT)
-#define I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_SHIFT 31
-#define I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_MASK (0x1 << I40E_PRTMAC_HSECTL1_EN_PREAMBLE_CHECK_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A 0x0008C480
+#define I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_HSEC_CTL_TX_SA_PART2_HSEC_CTL_TX_SA_PART2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A 0x0008C480 /* Reset: GLOBR */
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_TX_LANE0_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT)
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B 0x0008C484
+#define I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_A_SWAP_RX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B 0x0008C484 /* Reset: GLOBR */
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT 0
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT 2
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT 4
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT 6
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_TX_LANE0_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT 8
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE3_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT 10
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE2_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT 12
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT)
#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT 14
-#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK (0x3 << I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT)
-#define I40E_GL_MNG_FWSM 0x000B6134
-#define I40E_GL_MNG_FWSM_FW_MODES_SHIFT 1
-#define I40E_GL_MNG_FWSM_FW_MODES_MASK (0x7 << I40E_GL_MNG_FWSM_FW_MODES_SHIFT)
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT 6
-#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_MASK (0x1 << I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT)
+#define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT)
+#define I40E_GL_FWRESETCNT 0x00083100 /* Reset: POR */
+#define I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT 0
+#define I40E_GL_FWRESETCNT_FWRESETCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT)
+#define I40E_GL_MNG_FWSM 0x000B6134 /* Reset: POR */
+#define I40E_GL_MNG_FWSM_FW_MODES_SHIFT 0
+#define I40E_GL_MNG_FWSM_FW_MODES_MASK I40E_MASK(0x3, I40E_GL_MNG_FWSM_FW_MODES_SHIFT)
+#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT 10
+#define I40E_GL_MNG_FWSM_EEP_RELOAD_IND_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_EEP_RELOAD_IND_SHIFT)
#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT 11
-#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_MASK (0xF << I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT)
+#define I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_MASK I40E_MASK(0xF, I40E_GL_MNG_FWSM_CRC_ERROR_MODULE_SHIFT)
#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT 15
-#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_MASK (0x1 << I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT)
+#define I40E_GL_MNG_FWSM_FW_STATUS_VALID_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_FW_STATUS_VALID_SHIFT)
#define I40E_GL_MNG_FWSM_RESET_CNT_SHIFT 16
-#define I40E_GL_MNG_FWSM_RESET_CNT_MASK (0x7 << I40E_GL_MNG_FWSM_RESET_CNT_SHIFT)
+#define I40E_GL_MNG_FWSM_RESET_CNT_MASK I40E_MASK(0x7, I40E_GL_MNG_FWSM_RESET_CNT_SHIFT)
#define I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT 19
-#define I40E_GL_MNG_FWSM_EXT_ERR_IND_MASK (0x3F << I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT)
-#define I40E_GL_MNG_FWSM_RSVD_SHIFT 25
-#define I40E_GL_MNG_FWSM_RSVD_MASK (0x1 << I40E_GL_MNG_FWSM_RSVD_SHIFT)
+#define I40E_GL_MNG_FWSM_EXT_ERR_IND_MASK I40E_MASK(0x3F, I40E_GL_MNG_FWSM_EXT_ERR_IND_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT 26
-#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES0_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT 27
-#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES1_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT 28
-#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES2_CONFIG_ERR_SHIFT)
#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT 29
-#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_MASK (0x1 << I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT)
-#define I40E_GL_MNG_HWARB_CTRL 0x000B6130
+#define I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_MASK I40E_MASK(0x1, I40E_GL_MNG_FWSM_PHY_SERDES3_CONFIG_ERR_SHIFT)
+#define I40E_GL_MNG_HWARB_CTRL 0x000B6130 /* Reset: POR */
#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT 0
-#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_MASK (0x1 << I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT)
-#define I40E_PRT_MNG_FTFT_DATA(_i) (0x000852A0 + ((_i) * 32)) /* _i=0...31 */
+#define I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_MASK I40E_MASK(0x1, I40E_GL_MNG_HWARB_CTRL_NCSI_ARB_EN_SHIFT)
+#define I40E_PRT_MNG_FTFT_DATA(_i) (0x000852A0 + ((_i) * 32)) /* _i=0...31 */ /* Reset: POR */
#define I40E_PRT_MNG_FTFT_DATA_MAX_INDEX 31
#define I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT 0
-#define I40E_PRT_MNG_FTFT_DATA_DWORD_MASK (0xFFFFFFFF << I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT)
-#define I40E_PRT_MNG_FTFT_LENGTH 0x00085260
+#define I40E_PRT_MNG_FTFT_DATA_DWORD_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_FTFT_DATA_DWORD_SHIFT)
+#define I40E_PRT_MNG_FTFT_LENGTH 0x00085260 /* Reset: POR */
#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_MASK (0xFF << I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PRT_MNG_FTFT_MASK(_i) (0x00085160 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRT_MNG_FTFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PRT_MNG_FTFT_LENGTH_LENGTH_SHIFT)
+#define I40E_PRT_MNG_FTFT_MASK(_i) (0x00085160 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_FTFT_MASK_MAX_INDEX 7
#define I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT 0
-#define I40E_PRT_MNG_FTFT_MASK_MASK_MASK (0xFFFF << I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT)
-#define I40E_PRT_MNG_MANC 0x00256A20
+#define I40E_PRT_MNG_FTFT_MASK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_FTFT_MASK_MASK_SHIFT)
+#define I40E_PRT_MNG_MANC 0x00256A20 /* Reset: POR */
#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT 0
-#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_MASK (0x1 << I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT)
+#define I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FLOW_CONTROL_DISCARD_SHIFT)
#define I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT 1
-#define I40E_PRT_MNG_MANC_NCSI_DISCARD_MASK (0x1 << I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT)
+#define I40E_PRT_MNG_MANC_NCSI_DISCARD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NCSI_DISCARD_SHIFT)
#define I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT 17
-#define I40E_PRT_MNG_MANC_RCV_TCO_EN_MASK (0x1 << I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT)
+#define I40E_PRT_MNG_MANC_RCV_TCO_EN_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_TCO_EN_SHIFT)
#define I40E_PRT_MNG_MANC_RCV_ALL_SHIFT 19
-#define I40E_PRT_MNG_MANC_RCV_ALL_MASK (0x1 << I40E_PRT_MNG_MANC_RCV_ALL_SHIFT)
+#define I40E_PRT_MNG_MANC_RCV_ALL_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_RCV_ALL_SHIFT)
#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT 25
-#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_MASK (0x1 << I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT)
+#define I40E_PRT_MNG_MANC_FIXED_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_FIXED_NET_TYPE_SHIFT)
#define I40E_PRT_MNG_MANC_NET_TYPE_SHIFT 26
-#define I40E_PRT_MNG_MANC_NET_TYPE_MASK (0x1 << I40E_PRT_MNG_MANC_NET_TYPE_SHIFT)
+#define I40E_PRT_MNG_MANC_NET_TYPE_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_NET_TYPE_SHIFT)
#define I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT 28
-#define I40E_PRT_MNG_MANC_EN_BMC2OS_MASK (0x1 << I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT)
+#define I40E_PRT_MNG_MANC_EN_BMC2OS_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2OS_SHIFT)
#define I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT 29
-#define I40E_PRT_MNG_MANC_EN_BMC2NET_MASK (0x1 << I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT)
-#define I40E_PRT_MNG_MAVTV(_i) (0x00255900 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRT_MNG_MANC_EN_BMC2NET_MASK I40E_MASK(0x1, I40E_PRT_MNG_MANC_EN_BMC2NET_SHIFT)
+#define I40E_PRT_MNG_MAVTV(_i) (0x00255900 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MAVTV_MAX_INDEX 7
#define I40E_PRT_MNG_MAVTV_VID_SHIFT 0
-#define I40E_PRT_MNG_MAVTV_VID_MASK (0xFFF << I40E_PRT_MNG_MAVTV_VID_SHIFT)
-#define I40E_PRT_MNG_MDEF(_i) (0x00255D00 + ((_i) * 32))
+#define I40E_PRT_MNG_MAVTV_VID_MASK I40E_MASK(0xFFF, I40E_PRT_MNG_MAVTV_VID_SHIFT)
+#define I40E_PRT_MNG_MDEF(_i) (0x00255D00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEF_MAX_INDEX 7
#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_MASK (0xF << I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_MAC_EXACT_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT 4
-#define I40E_PRT_MNG_MDEF_BROADCAST_AND_MASK (0x1 << I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_BROADCAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT 5
-#define I40E_PRT_MNG_MDEF_VLAN_AND_MASK (0xFF << I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_VLAN_AND_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MDEF_VLAN_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT 13
-#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_MASK (0xF << I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV4_ADDRESS_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT 17
-#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_MASK (0xF << I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_IPV6_ADDRESS_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT 21
-#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_MASK (0xF << I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_MAC_EXACT_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_MAC_EXACT_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_BROADCAST_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_BROADCAST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_BROADCAST_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT 26
-#define I40E_PRT_MNG_MDEF_MULTICAST_AND_MASK (0x1 << I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_MULTICAST_AND_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_MULTICAST_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_REQUEST_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_ARP_RESPONSE_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT 29
-#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_NEIGHBOR_DISCOVERY_134_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT 30
-#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_PORT_0X298_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X298_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT 31
-#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT)
-#define I40E_PRT_MNG_MDEF_EXT(_i) (0x00255F00 + ((_i) * 32))
+#define I40E_PRT_MNG_MDEF_PORT_0X26F_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_PORT_0X26F_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT(_i) (0x00255F00 + ((_i) * 32)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEF_EXT_MAX_INDEX 7
#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT 0
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_MASK (0xF << I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_AND_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT 4
-#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_MASK (0xF << I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_MASK I40E_MASK(0xF, I40E_PRT_MNG_MDEF_EXT_L2_ETHERTYPE_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT 8
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_MASK (0xFFFF << I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEF_EXT_FLEX_PORT_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT 24
-#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_FLEX_TCO_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT 25
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_135_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT 26
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_136_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT 27
-#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_NEIGHBOR_DISCOVERY_137_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT 28
-#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_ICMP_OR_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_ICMP_OR_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT 29
-#define I40E_PRT_MNG_MDEF_EXT_MLD_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_MLD_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_MLD_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT 30
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT)
+#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_NETWORK_TRAFFIC_SHIFT)
#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT 31
-#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_MASK (0x1 << I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT)
-#define I40E_PRT_MNG_MDEFVSI(_i) (0x00256580 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_MASK I40E_MASK(0x1, I40E_PRT_MNG_MDEF_EXT_APPLY_TO_HOST_TRAFFIC_SHIFT)
+#define I40E_PRT_MNG_MDEFVSI(_i) (0x00256580 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MDEFVSI_MAX_INDEX 3
#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT 0
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_MASK (0xFFFF << I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT)
+#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2N_SHIFT)
#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT 16
-#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_MASK (0xFFFF << I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT)
-#define I40E_PRT_MNG_METF(_i) (0x00256780 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MDEFVSI_MDEFVSI_2NP1_SHIFT)
+#define I40E_PRT_MNG_METF(_i) (0x00256780 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_METF_MAX_INDEX 3
#define I40E_PRT_MNG_METF_ETYPE_SHIFT 0
-#define I40E_PRT_MNG_METF_ETYPE_MASK (0xFFFF << I40E_PRT_MNG_METF_ETYPE_SHIFT)
+#define I40E_PRT_MNG_METF_ETYPE_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_METF_ETYPE_SHIFT)
#define I40E_PRT_MNG_METF_POLARITY_SHIFT 30
-#define I40E_PRT_MNG_METF_POLARITY_MASK (0x1 << I40E_PRT_MNG_METF_POLARITY_SHIFT)
-#define I40E_PRT_MNG_MFUTP(_i) (0x00254E00 + ((_i) * 32)) /* _i=0...15 */
+#define I40E_PRT_MNG_METF_POLARITY_MASK I40E_MASK(0x1, I40E_PRT_MNG_METF_POLARITY_SHIFT)
+#define I40E_PRT_MNG_MFUTP(_i) (0x00254E00 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
#define I40E_PRT_MNG_MFUTP_MAX_INDEX 15
#define I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT 0
-#define I40E_PRT_MNG_MFUTP_MFUTP_N_MASK (0xFFFF << I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT)
+#define I40E_PRT_MNG_MFUTP_MFUTP_N_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MFUTP_MFUTP_N_SHIFT)
#define I40E_PRT_MNG_MFUTP_UDP_SHIFT 16
-#define I40E_PRT_MNG_MFUTP_UDP_MASK (0x1 << I40E_PRT_MNG_MFUTP_UDP_SHIFT)
+#define I40E_PRT_MNG_MFUTP_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_UDP_SHIFT)
#define I40E_PRT_MNG_MFUTP_TCP_SHIFT 17
-#define I40E_PRT_MNG_MFUTP_TCP_MASK (0x1 << I40E_PRT_MNG_MFUTP_TCP_SHIFT)
+#define I40E_PRT_MNG_MFUTP_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_TCP_SHIFT)
#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT 18
-#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_MASK (0x1 << I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT)
-#define I40E_PRT_MNG_MIPAF4(_i) (0x00256280 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_MASK I40E_MASK(0x1, I40E_PRT_MNG_MFUTP_SOURCE_DESTINATION_SHIFT)
+#define I40E_PRT_MNG_MIPAF4(_i) (0x00256280 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MIPAF4_MAX_INDEX 3
#define I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF4_MIPAF_MASK (0xFFFFFFFF << I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MIPAF6(_i) (0x00254200 + ((_i) * 32)) /* _i=0...15 */
+#define I40E_PRT_MNG_MIPAF4_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF4_MIPAF_SHIFT)
+#define I40E_PRT_MNG_MIPAF6(_i) (0x00254200 + ((_i) * 32)) /* _i=0...15 */ /* Reset: POR */
#define I40E_PRT_MNG_MIPAF6_MAX_INDEX 15
#define I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT 0
-#define I40E_PRT_MNG_MIPAF6_MIPAF_MASK (0xFFFFFFFF << I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT)
-#define I40E_PRT_MNG_MMAH(_i) (0x00256380 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MIPAF6_MIPAF_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MIPAF6_MIPAF_SHIFT)
+#define I40E_PRT_MNG_MMAH(_i) (0x00256380 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MMAH_MAX_INDEX 3
#define I40E_PRT_MNG_MMAH_MMAH_SHIFT 0
-#define I40E_PRT_MNG_MMAH_MMAH_MASK (0xFFFF << I40E_PRT_MNG_MMAH_MMAH_SHIFT)
-#define I40E_PRT_MNG_MMAL(_i) (0x00256480 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRT_MNG_MMAH_MMAH_MASK I40E_MASK(0xFFFF, I40E_PRT_MNG_MMAH_MMAH_SHIFT)
+#define I40E_PRT_MNG_MMAL(_i) (0x00256480 + ((_i) * 32)) /* _i=0...3 */ /* Reset: POR */
#define I40E_PRT_MNG_MMAL_MAX_INDEX 3
#define I40E_PRT_MNG_MMAL_MMAL_SHIFT 0
-#define I40E_PRT_MNG_MMAL_MMAL_MASK (0xFFFFFFFF << I40E_PRT_MNG_MMAL_MMAL_SHIFT)
-#define I40E_PRT_MNG_MNGONLY 0x00256A60
+#define I40E_PRT_MNG_MMAL_MMAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRT_MNG_MMAL_MMAL_SHIFT)
+#define I40E_PRT_MNG_MNGONLY 0x00256A60 /* Reset: POR */
#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT 0
-#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_MASK (0xFF << I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT)
-#define I40E_PRT_MNG_MSFM 0x00256AA0
+#define I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_MASK I40E_MASK(0xFF, I40E_PRT_MNG_MNGONLY_EXCLUSIVE_TO_MANAGEABILITY_SHIFT)
+#define I40E_PRT_MNG_MSFM 0x00256AA0 /* Reset: POR */
#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT 0
-#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_26F_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_UDP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT 1
-#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_26F_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_26F_TCP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT 2
-#define I40E_PRT_MNG_MSFM_PORT_298_UDP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_298_UDP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_UDP_SHIFT)
#define I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT 3
-#define I40E_PRT_MNG_MSFM_PORT_298_TCP_MASK (0x1 << I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT)
+#define I40E_PRT_MNG_MSFM_PORT_298_TCP_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_PORT_298_TCP_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT 4
-#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_0_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_0_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT 5
-#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_1_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_1_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT 6
-#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT)
+#define I40E_PRT_MNG_MSFM_IPV6_2_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_2_MASK_SHIFT)
#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT 7
-#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_MASK (0x1 << I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT)
-#define I40E_MSIX_PBA(_i) (0x00004900 + ((_i) * 4)) /* _i=0...5 */
+#define I40E_PRT_MNG_MSFM_IPV6_3_MASK_MASK I40E_MASK(0x1, I40E_PRT_MNG_MSFM_IPV6_3_MASK_SHIFT)
+#define I40E_MSIX_PBA(_i) (0x00001000 + ((_i) * 4)) /* _i=0...5 */ /* Reset: FLR */
#define I40E_MSIX_PBA_MAX_INDEX 5
#define I40E_MSIX_PBA_PENBIT_SHIFT 0
-#define I40E_MSIX_PBA_PENBIT_MASK (0xFFFFFFFF << I40E_MSIX_PBA_PENBIT_SHIFT)
-#define I40E_MSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_PBA_PENBIT_SHIFT)
+#define I40E_MSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TADD_MAX_INDEX 128
#define I40E_MSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_MSIX_TADD_MSIXTADD10_MASK (0x3 << I40E_MSIX_TADD_MSIXTADD10_SHIFT)
+#define I40E_MSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_MSIX_TADD_MSIXTADD10_SHIFT)
#define I40E_MSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_MSIX_TADD_MSIXTADD_MASK (0x3FFFFFFF << I40E_MSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_MSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_MSIX_TADD_MSIXTADD_SHIFT)
+#define I40E_MSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TMSG_MAX_INDEX 128
#define I40E_MSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_MSIX_TMSG_MSIXTMSG_MASK (0xFFFFFFFF << I40E_MSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_MSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TMSG_MSIXTMSG_SHIFT)
+#define I40E_MSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TUADD_MAX_INDEX 128
#define I40E_MSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_MSIX_TUADD_MSIXTUADD_MASK (0xFFFFFFFF << I40E_MSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_MSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...128 */
+#define I40E_MSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_MSIX_TUADD_MSIXTUADD_SHIFT)
+#define I40E_MSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...128 */ /* Reset: FLR */
#define I40E_MSIX_TVCTRL_MAX_INDEX 128
#define I40E_MSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_MSIX_TVCTRL_MASK_MASK (0x1 << I40E_MSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFMSIX_PBA1(_i) (0x00004944 + ((_i) * 4)) /* _i=0...19 */
+#define I40E_MSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_MSIX_TVCTRL_MASK_SHIFT)
+#define I40E_VFMSIX_PBA1(_i) (0x00002000 + ((_i) * 4)) /* _i=0...19 */ /* Reset: VFLR */
#define I40E_VFMSIX_PBA1_MAX_INDEX 19
#define I40E_VFMSIX_PBA1_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA1_PENBIT_MASK (0xFFFFFFFF << I40E_VFMSIX_PBA1_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_PBA1_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA1_PENBIT_SHIFT)
+#define I40E_VFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TADD1_MAX_INDEX 639
#define I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD1_MSIXTADD10_MASK (0x3 << I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT)
+#define I40E_VFMSIX_TADD1_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD1_MSIXTADD10_SHIFT)
#define I40E_VFMSIX_TADD1_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD1_MSIXTADD_MASK (0x3FFFFFFF << I40E_VFMSIX_TADD1_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TADD1_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD1_MSIXTADD_SHIFT)
+#define I40E_VFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TMSG1_MAX_INDEX 639
#define I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG1_MSIXTMSG_MASK (0xFFFFFFFF << I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TMSG1_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG1_MSIXTMSG_SHIFT)
+#define I40E_VFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TUADD1_MAX_INDEX 639
#define I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD1_MSIXTUADD_MASK (0xFFFFFFFF << I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */
+#define I40E_VFMSIX_TUADD1_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD1_MSIXTUADD_SHIFT)
+#define I40E_VFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
#define I40E_VFMSIX_TVCTRL1_MAX_INDEX 639
#define I40E_VFMSIX_TVCTRL1_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL1_MASK_MASK (0x1 << I40E_VFMSIX_TVCTRL1_MASK_SHIFT)
-#define I40E_GLNVM_FLA 0x000B6108
+#define I40E_VFMSIX_TVCTRL1_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL1_MASK_SHIFT)
+#define I40E_GLNVM_FLA 0x000B6108 /* Reset: POR */
#define I40E_GLNVM_FLA_FL_SCK_SHIFT 0
-#define I40E_GLNVM_FLA_FL_SCK_MASK (0x1 << I40E_GLNVM_FLA_FL_SCK_SHIFT)
+#define I40E_GLNVM_FLA_FL_SCK_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SCK_SHIFT)
#define I40E_GLNVM_FLA_FL_CE_SHIFT 1
-#define I40E_GLNVM_FLA_FL_CE_MASK (0x1 << I40E_GLNVM_FLA_FL_CE_SHIFT)
+#define I40E_GLNVM_FLA_FL_CE_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_CE_SHIFT)
#define I40E_GLNVM_FLA_FL_SI_SHIFT 2
-#define I40E_GLNVM_FLA_FL_SI_MASK (0x1 << I40E_GLNVM_FLA_FL_SI_SHIFT)
+#define I40E_GLNVM_FLA_FL_SI_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SI_SHIFT)
#define I40E_GLNVM_FLA_FL_SO_SHIFT 3
-#define I40E_GLNVM_FLA_FL_SO_MASK (0x1 << I40E_GLNVM_FLA_FL_SO_SHIFT)
+#define I40E_GLNVM_FLA_FL_SO_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_SO_SHIFT)
#define I40E_GLNVM_FLA_FL_REQ_SHIFT 4
-#define I40E_GLNVM_FLA_FL_REQ_MASK (0x1 << I40E_GLNVM_FLA_FL_REQ_SHIFT)
+#define I40E_GLNVM_FLA_FL_REQ_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_REQ_SHIFT)
#define I40E_GLNVM_FLA_FL_GNT_SHIFT 5
-#define I40E_GLNVM_FLA_FL_GNT_MASK (0x1 << I40E_GLNVM_FLA_FL_GNT_SHIFT)
+#define I40E_GLNVM_FLA_FL_GNT_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_GNT_SHIFT)
#define I40E_GLNVM_FLA_LOCKED_SHIFT 6
-#define I40E_GLNVM_FLA_LOCKED_MASK (0x1 << I40E_GLNVM_FLA_LOCKED_SHIFT)
+#define I40E_GLNVM_FLA_LOCKED_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_LOCKED_SHIFT)
#define I40E_GLNVM_FLA_FL_SADDR_SHIFT 18
-#define I40E_GLNVM_FLA_FL_SADDR_MASK (0x7FF << I40E_GLNVM_FLA_FL_SADDR_SHIFT)
+#define I40E_GLNVM_FLA_FL_SADDR_MASK I40E_MASK(0x7FF, I40E_GLNVM_FLA_FL_SADDR_SHIFT)
#define I40E_GLNVM_FLA_FL_BUSY_SHIFT 30
-#define I40E_GLNVM_FLA_FL_BUSY_MASK (0x1 << I40E_GLNVM_FLA_FL_BUSY_SHIFT)
+#define I40E_GLNVM_FLA_FL_BUSY_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_BUSY_SHIFT)
#define I40E_GLNVM_FLA_FL_DER_SHIFT 31
-#define I40E_GLNVM_FLA_FL_DER_MASK (0x1 << I40E_GLNVM_FLA_FL_DER_SHIFT)
-#define I40E_GLNVM_FLASHID 0x000B6104
+#define I40E_GLNVM_FLA_FL_DER_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_FL_DER_SHIFT)
+#define I40E_GLNVM_FLASHID 0x000B6104 /* Reset: POR */
#define I40E_GLNVM_FLASHID_FLASHID_SHIFT 0
-#define I40E_GLNVM_FLASHID_FLASHID_MASK (0xFFFFFF << I40E_GLNVM_FLASHID_FLASHID_SHIFT)
-#define I40E_GLNVM_GENS 0x000B6100
+#define I40E_GLNVM_FLASHID_FLASHID_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_FLASHID_FLASHID_SHIFT)
+#define I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT 31
+#define I40E_GLNVM_FLASHID_FLEEP_PERF_MASK I40E_MASK(0x1, I40E_GLNVM_FLASHID_FLEEP_PERF_SHIFT)
+#define I40E_GLNVM_GENS 0x000B6100 /* Reset: POR */
#define I40E_GLNVM_GENS_NVM_PRES_SHIFT 0
-#define I40E_GLNVM_GENS_NVM_PRES_MASK (0x1 << I40E_GLNVM_GENS_NVM_PRES_SHIFT)
+#define I40E_GLNVM_GENS_NVM_PRES_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_NVM_PRES_SHIFT)
#define I40E_GLNVM_GENS_SR_SIZE_SHIFT 5
-#define I40E_GLNVM_GENS_SR_SIZE_MASK (0x7 << I40E_GLNVM_GENS_SR_SIZE_SHIFT)
+#define I40E_GLNVM_GENS_SR_SIZE_MASK I40E_MASK(0x7, I40E_GLNVM_GENS_SR_SIZE_SHIFT)
#define I40E_GLNVM_GENS_BANK1VAL_SHIFT 8
-#define I40E_GLNVM_GENS_BANK1VAL_MASK (0x1 << I40E_GLNVM_GENS_BANK1VAL_SHIFT)
+#define I40E_GLNVM_GENS_BANK1VAL_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_BANK1VAL_SHIFT)
#define I40E_GLNVM_GENS_ALT_PRST_SHIFT 23
-#define I40E_GLNVM_GENS_ALT_PRST_MASK (0x1 << I40E_GLNVM_GENS_ALT_PRST_SHIFT)
+#define I40E_GLNVM_GENS_ALT_PRST_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_ALT_PRST_SHIFT)
#define I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT 25
-#define I40E_GLNVM_GENS_FL_AUTO_RD_MASK (0x1 << I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT)
-#define I40E_GLNVM_PROTCSR(_i) (0x000B6010 + ((_i) * 4)) /* _i=0...59 */
+#define I40E_GLNVM_GENS_FL_AUTO_RD_MASK I40E_MASK(0x1, I40E_GLNVM_GENS_FL_AUTO_RD_SHIFT)
+#define I40E_GLNVM_PROTCSR(_i) (0x000B6010 + ((_i) * 4)) /* _i=0...59 */ /* Reset: POR */
#define I40E_GLNVM_PROTCSR_MAX_INDEX 59
#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT 0
-#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_MASK (0xFFFFFF << I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT)
-#define I40E_GLNVM_SRCTL 0x000B6110
+#define I40E_GLNVM_PROTCSR_ADDR_BLOCK_MASK I40E_MASK(0xFFFFFF, I40E_GLNVM_PROTCSR_ADDR_BLOCK_SHIFT)
+#define I40E_GLNVM_SRCTL 0x000B6110 /* Reset: POR */
#define I40E_GLNVM_SRCTL_SRBUSY_SHIFT 0
-#define I40E_GLNVM_SRCTL_SRBUSY_MASK (0x1 << I40E_GLNVM_SRCTL_SRBUSY_SHIFT)
+#define I40E_GLNVM_SRCTL_SRBUSY_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_SRBUSY_SHIFT)
#define I40E_GLNVM_SRCTL_ADDR_SHIFT 14
-#define I40E_GLNVM_SRCTL_ADDR_MASK (0x7FFF << I40E_GLNVM_SRCTL_ADDR_SHIFT)
+#define I40E_GLNVM_SRCTL_ADDR_MASK I40E_MASK(0x7FFF, I40E_GLNVM_SRCTL_ADDR_SHIFT)
#define I40E_GLNVM_SRCTL_WRITE_SHIFT 29
-#define I40E_GLNVM_SRCTL_WRITE_MASK (0x1 << I40E_GLNVM_SRCTL_WRITE_SHIFT)
+#define I40E_GLNVM_SRCTL_WRITE_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_WRITE_SHIFT)
#define I40E_GLNVM_SRCTL_START_SHIFT 30
-#define I40E_GLNVM_SRCTL_START_MASK (0x1 << I40E_GLNVM_SRCTL_START_SHIFT)
+#define I40E_GLNVM_SRCTL_START_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_START_SHIFT)
#define I40E_GLNVM_SRCTL_DONE_SHIFT 31
-#define I40E_GLNVM_SRCTL_DONE_MASK (0x1 << I40E_GLNVM_SRCTL_DONE_SHIFT)
-#define I40E_GLNVM_SRDATA 0x000B6114
+#define I40E_GLNVM_SRCTL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_SRCTL_DONE_SHIFT)
+#define I40E_GLNVM_SRDATA 0x000B6114 /* Reset: POR */
#define I40E_GLNVM_SRDATA_WRDATA_SHIFT 0
-#define I40E_GLNVM_SRDATA_WRDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_WRDATA_SHIFT)
+#define I40E_GLNVM_SRDATA_WRDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_WRDATA_SHIFT)
#define I40E_GLNVM_SRDATA_RDDATA_SHIFT 16
-#define I40E_GLNVM_SRDATA_RDDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_RDDATA_SHIFT)
-#define I40E_GLNVM_ULD 0x000B6008
+#define I40E_GLNVM_SRDATA_RDDATA_MASK I40E_MASK(0xFFFF, I40E_GLNVM_SRDATA_RDDATA_SHIFT)
+#define I40E_GLNVM_ULD 0x000B6008 /* Reset: POR */
#define I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT 0
-#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT 1
-#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT 2
-#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT 3
-#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT 4
-#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT 5
-#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT 6
-#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT 7
-#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT 8
-#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT 9
-#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
-
-#define I40E_GLPCI_BYTCTH 0x0009C484
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
+#define I40E_GLPCI_BYTCTH 0x0009C484 /* Reset: PCIR */
#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_BYTCTL 0x0009C488
+#define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
+#define I40E_GLPCI_BYTCTL 0x0009C488 /* Reset: PCIR */
#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT 0
-#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT)
-#define I40E_GLPCI_CAPCTRL 0x000BE4A4
+#define I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_BYTCTL_PCI_COUNT_BW_BCT_SHIFT)
+#define I40E_GLPCI_CAPCTRL 0x000BE4A4 /* Reset: PCIR */
#define I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT 0
-#define I40E_GLPCI_CAPCTRL_VPD_EN_MASK (0x1 << I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT)
-#define I40E_GLPCI_CAPSUP 0x000BE4A8
+#define I40E_GLPCI_CAPCTRL_VPD_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPCTRL_VPD_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP 0x000BE4A8 /* Reset: PCIR */
#define I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT 0
-#define I40E_GLPCI_CAPSUP_PCIE_VER_MASK (0x1 << I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT)
+#define I40E_GLPCI_CAPSUP_PCIE_VER_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_PCIE_VER_SHIFT)
#define I40E_GLPCI_CAPSUP_LTR_EN_SHIFT 2
-#define I40E_GLPCI_CAPSUP_LTR_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_LTR_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_LTR_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LTR_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_TPH_EN_SHIFT 3
-#define I40E_GLPCI_CAPSUP_TPH_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_TPH_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_TPH_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_TPH_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ARI_EN_SHIFT 4
-#define I40E_GLPCI_CAPSUP_ARI_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ARI_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ARI_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ARI_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_IOV_EN_SHIFT 5
-#define I40E_GLPCI_CAPSUP_IOV_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_IOV_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_IOV_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IOV_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ACS_EN_SHIFT 6
-#define I40E_GLPCI_CAPSUP_ACS_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ACS_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ACS_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ACS_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_SEC_EN_SHIFT 7
-#define I40E_GLPCI_CAPSUP_SEC_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_SEC_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_SEC_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_SEC_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT 16
-#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ECRC_GEN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_GEN_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT 17
-#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_ECRC_CHK_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_ECRC_CHK_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_IDO_EN_SHIFT 18
-#define I40E_GLPCI_CAPSUP_IDO_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_IDO_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_IDO_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_IDO_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT 19
-#define I40E_GLPCI_CAPSUP_MSI_MASK_MASK (0x1 << I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT)
+#define I40E_GLPCI_CAPSUP_MSI_MASK_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_MSI_MASK_SHIFT)
#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT 20
-#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_MASK (0x1 << I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT)
+#define I40E_GLPCI_CAPSUP_CSR_CONF_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_CSR_CONF_EN_SHIFT)
#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT 30
-#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_MASK (0x1 << I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT)
+#define I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_SUBSYS_ID_SHIFT)
#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT 31
-#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_MASK (0x1 << I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT)
-#define I40E_GLPCI_CNF 0x000BE4C0
+#define I40E_GLPCI_CAPSUP_LOAD_DEV_ID_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_LOAD_DEV_ID_SHIFT)
+#define I40E_GLPCI_CNF 0x000BE4C0 /* Reset: POR */
#define I40E_GLPCI_CNF_FLEX10_SHIFT 1
-#define I40E_GLPCI_CNF_FLEX10_MASK (0x1 << I40E_GLPCI_CNF_FLEX10_SHIFT)
+#define I40E_GLPCI_CNF_FLEX10_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_FLEX10_SHIFT)
#define I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT 2
-#define I40E_GLPCI_CNF_WAKE_PIN_EN_MASK (0x1 << I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT)
-#define I40E_GLPCI_CNF2 0x000BE494
+#define I40E_GLPCI_CNF_WAKE_PIN_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CNF_WAKE_PIN_EN_SHIFT)
+#define I40E_GLPCI_CNF2 0x000BE494 /* Reset: PCIR */
#define I40E_GLPCI_CNF2_RO_DIS_SHIFT 0
-#define I40E_GLPCI_CNF2_RO_DIS_MASK (0x1 << I40E_GLPCI_CNF2_RO_DIS_SHIFT)
+#define I40E_GLPCI_CNF2_RO_DIS_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_RO_DIS_SHIFT)
#define I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT 1
-#define I40E_GLPCI_CNF2_CACHELINE_SIZE_MASK (0x1 << I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT)
+#define I40E_GLPCI_CNF2_CACHELINE_SIZE_MASK I40E_MASK(0x1, I40E_GLPCI_CNF2_CACHELINE_SIZE_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT 2
-#define I40E_GLPCI_CNF2_MSI_X_PF_N_MASK (0x7FF << I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT)
+#define I40E_GLPCI_CNF2_MSI_X_PF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT)
#define I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT 13
-#define I40E_GLPCI_CNF2_MSI_X_VF_N_MASK (0x7FF << I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT)
-#define I40E_GLPCI_DREVID 0x0009C480
+#define I40E_GLPCI_CNF2_MSI_X_VF_N_MASK I40E_MASK(0x7FF, I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT)
+#define I40E_GLPCI_DREVID 0x0009C480 /* Reset: PCIR */
#define I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT 0
-#define I40E_GLPCI_DREVID_DEFAULT_REVID_MASK (0xFF << I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT)
-#define I40E_GLPCI_GSCL_1 0x0009C48C
+#define I40E_GLPCI_DREVID_DEFAULT_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_DREVID_DEFAULT_REVID_SHIFT)
+#define I40E_GLPCI_GSCL_1 0x0009C48C /* Reset: PCIR */
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT 0
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_0_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT 1
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_1_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT 2
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_2_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT 3
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_EN_3_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT 4
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_0_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_0_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT 5
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_1_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_1_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT 6
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_2_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_2_SHIFT)
#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT 7
-#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_MASK (0x1 << I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT)
+#define I40E_GLPCI_GSCL_1_LBC_ENABLE_3_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_LBC_ENABLE_3_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT 8
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT 9
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_MASK (0x1F << I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_LAT_EV_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT 14
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT 15
-#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_MASK (0x1F << I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT)
+#define I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_MASK I40E_MASK(0x1F, I40E_GLPCI_GSCL_1_PCI_COUNT_BW_EV_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT 28
-#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_64_BIT_EN_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT 29
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_RESET_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT 30
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT)
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_STOP_SHIFT)
#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT 31
-#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_MASK (0x1 << I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT)
-#define I40E_GLPCI_GSCL_2 0x0009C490
+#define I40E_GLPCI_GSCL_1_GIO_COUNT_START_MASK I40E_MASK(0x1, I40E_GLPCI_GSCL_1_GIO_COUNT_START_SHIFT)
+#define I40E_GLPCI_GSCL_2 0x0009C490 /* Reset: PCIR */
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT 0
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_0_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT 8
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_1_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT 16
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT)
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_2_SHIFT)
#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT 24
-#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_MASK (0xFF << I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT)
-#define I40E_GLPCI_GSCL_5_8(_i) (0x0009C494 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_MASK I40E_MASK(0xFF, I40E_GLPCI_GSCL_2_GIO_EVENT_NUM_3_SHIFT)
+#define I40E_GLPCI_GSCL_5_8(_i) (0x0009C494 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
#define I40E_GLPCI_GSCL_5_8_MAX_INDEX 3
#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT 0
-#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_MASK (0xFFFF << I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT)
+#define I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_THRESHOLD_N_SHIFT)
#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT 16
-#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_MASK (0xFFFF << I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT)
-#define I40E_GLPCI_GSCN_0_3(_i) (0x0009C4A4 + ((_i) * 4)) /* _i=0...3 */
+#define I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_MASK I40E_MASK(0xFFFF, I40E_GLPCI_GSCL_5_8_LBC_TIMER_N_SHIFT)
+#define I40E_GLPCI_GSCN_0_3(_i) (0x0009C4A4 + ((_i) * 4)) /* _i=0...3 */ /* Reset: PCIR */
#define I40E_GLPCI_GSCN_0_3_MAX_INDEX 3
#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT 0
-#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_MASK (0xFFFFFFFF << I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT)
-#define I40E_GLPCI_LATCT 0x0009C4B4
+#define I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_GSCN_0_3_EVENT_COUNTER_SHIFT)
+#define I40E_GLPCI_LATCT 0x0009C4B4 /* Reset: PCIR */
#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT 0
-#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_MASK (0xFFFFFFFF << I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT)
-#define I40E_GLPCI_LBARCTRL 0x000BE484
+#define I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_LATCT_PCI_COUNT_LAT_CT_SHIFT)
+#define I40E_GLPCI_LBARCTRL 0x000BE484 /* Reset: POR */
#define I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT 0
-#define I40E_GLPCI_LBARCTRL_PREFBAR_MASK (0x1 << I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT)
+#define I40E_GLPCI_LBARCTRL_PREFBAR_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_PREFBAR_SHIFT)
#define I40E_GLPCI_LBARCTRL_BAR32_SHIFT 1
-#define I40E_GLPCI_LBARCTRL_BAR32_MASK (0x1 << I40E_GLPCI_LBARCTRL_BAR32_SHIFT)
+#define I40E_GLPCI_LBARCTRL_BAR32_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_BAR32_SHIFT)
#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT 3
-#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_MASK (0x1 << I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT 4
-#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_MASK (0x3 << I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_FLASH_EXPOSE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT 4
+#define I40E_GLPCI_LBARCTRL_RSVD_4_MASK I40E_MASK(0x3, I40E_GLPCI_LBARCTRL_RSVD_4_SHIFT)
#define I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT 6
-#define I40E_GLPCI_LBARCTRL_FL_SIZE_MASK (0x7 << I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT)
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT 10
-#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_MASK (0x1 << I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_FL_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_FL_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT 10
+#define I40E_GLPCI_LBARCTRL_RSVD_10_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_RSVD_10_SHIFT)
#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT 11
-#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_MASK (0x7 << I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT)
-#define I40E_GLPCI_LINKCAP 0x000BE4AC
+#define I40E_GLPCI_LBARCTRL_EXROM_SIZE_MASK I40E_MASK(0x7, I40E_GLPCI_LBARCTRL_EXROM_SIZE_SHIFT)
+#define I40E_GLPCI_LINKCAP 0x000BE4AC /* Reset: PCIR */
#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT 0
-#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_MASK (0x3F << I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT)
+#define I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_MASK I40E_MASK(0x3F, I40E_GLPCI_LINKCAP_LINK_SPEEDS_VECTOR_SHIFT)
#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT 6
-#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_MASK (0x7 << I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT)
+#define I40E_GLPCI_LINKCAP_MAX_PAYLOAD_MASK I40E_MASK(0x7, I40E_GLPCI_LINKCAP_MAX_PAYLOAD_SHIFT)
#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT 9
-#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_MASK (0xF << I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT)
-#define I40E_GLPCI_PCIERR 0x000BE4FC
+#define I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_MASK I40E_MASK(0xF, I40E_GLPCI_LINKCAP_MAX_LINK_WIDTH_SHIFT)
+#define I40E_GLPCI_PCIERR 0x000BE4FC /* Reset: PCIR */
#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT 0
-#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK (0xFFFFFFFF << I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
-#define I40E_GLPCI_PCITEST2 0x000BE4BC
-#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT 0
-#define I40E_GLPCI_PCITEST2_IOV_TEST_MODE_MASK (0x1 << I40E_GLPCI_PCITEST2_IOV_TEST_MODE_SHIFT)
-#define I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT 1
-#define I40E_GLPCI_PCITEST2_TAG_ALLOC_MASK (0x1 << I40E_GLPCI_PCITEST2_TAG_ALLOC_SHIFT)
-
-#define I40E_GLPCI_PKTCT 0x0009C4BC
+#define I40E_GLPCI_PCIERR_PCIE_ERR_REP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PCIERR_PCIE_ERR_REP_SHIFT)
+#define I40E_GLPCI_PKTCT 0x0009C4BC /* Reset: PCIR */
#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT 0
-#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK (0xFFFFFFFF << I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)
-#define I40E_GLPCI_PMSUP 0x000BE4B0
+#define I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_PKTCT_PCI_COUNT_BW_PCT_SHIFT)
+#define I40E_GLPCI_PM_MUX_NPQ 0x0009C4F4 /* Reset: PCIR */
+#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT 0
+#define I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_NPQ_NPQ_NUM_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT 16
+#define I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_NPQ_INNER_NPQ_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_PFB 0x0009C4F0 /* Reset: PCIR */
+#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT 0
+#define I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_MASK I40E_MASK(0x1F, I40E_GLPCI_PM_MUX_PFB_PFB_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT 16
+#define I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_MASK I40E_MASK(0x7, I40E_GLPCI_PM_MUX_PFB_INNER_PORT_SEL_SHIFT)
+#define I40E_GLPCI_PMSUP 0x000BE4B0 /* Reset: PCIR */
#define I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT 0
-#define I40E_GLPCI_PMSUP_ASPM_SUP_MASK (0x3 << I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT)
+#define I40E_GLPCI_PMSUP_ASPM_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_ASPM_SUP_SHIFT)
#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT 2
-#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L0S_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_EXIT_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT 5
-#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L1_EXIT_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_EXIT_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT 8
-#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L0S_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L0S_ACC_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT 11
-#define I40E_GLPCI_PMSUP_L1_ACC_LAT_MASK (0x7 << I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT)
+#define I40E_GLPCI_PMSUP_L1_ACC_LAT_MASK I40E_MASK(0x7, I40E_GLPCI_PMSUP_L1_ACC_LAT_SHIFT)
#define I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT 14
-#define I40E_GLPCI_PMSUP_SLOT_CLK_MASK (0x1 << I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT)
+#define I40E_GLPCI_PMSUP_SLOT_CLK_MASK I40E_MASK(0x1, I40E_GLPCI_PMSUP_SLOT_CLK_SHIFT)
#define I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT 15
-#define I40E_GLPCI_PMSUP_OBFF_SUP_MASK (0x3 << I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT)
-#define I40E_GLPCI_PWRDATA 0x000BE490
+#define I40E_GLPCI_PMSUP_OBFF_SUP_MASK I40E_MASK(0x3, I40E_GLPCI_PMSUP_OBFF_SUP_SHIFT)
+#define I40E_GLPCI_PQ_MAX_USED_SPC 0x0009C4EC /* Reset: PCIR */
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT 0
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_12_SHIFT)
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT 8
+#define I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_MASK I40E_MASK(0xFF, I40E_GLPCI_PQ_MAX_USED_SPC_GLPCI_PQ_MAX_USED_SPC_13_SHIFT)
+#define I40E_GLPCI_PWRDATA 0x000BE490 /* Reset: PCIR */
#define I40E_GLPCI_PWRDATA_D0_POWER_SHIFT 0
-#define I40E_GLPCI_PWRDATA_D0_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_D0_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_D0_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D0_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT 8
-#define I40E_GLPCI_PWRDATA_COMM_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_COMM_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_COMM_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_D3_POWER_SHIFT 16
-#define I40E_GLPCI_PWRDATA_D3_POWER_MASK (0xFF << I40E_GLPCI_PWRDATA_D3_POWER_SHIFT)
+#define I40E_GLPCI_PWRDATA_D3_POWER_MASK I40E_MASK(0xFF, I40E_GLPCI_PWRDATA_D3_POWER_SHIFT)
#define I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT 24
-#define I40E_GLPCI_PWRDATA_DATA_SCALE_MASK (0x3 << I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT)
-#define I40E_GLPCI_REVID 0x000BE4B4
+#define I40E_GLPCI_PWRDATA_DATA_SCALE_MASK I40E_MASK(0x3, I40E_GLPCI_PWRDATA_DATA_SCALE_SHIFT)
+#define I40E_GLPCI_REVID 0x000BE4B4 /* Reset: PCIR */
#define I40E_GLPCI_REVID_NVM_REVID_SHIFT 0
-#define I40E_GLPCI_REVID_NVM_REVID_MASK (0xFF << I40E_GLPCI_REVID_NVM_REVID_SHIFT)
-#define I40E_GLPCI_SERH 0x000BE49C
+#define I40E_GLPCI_REVID_NVM_REVID_MASK I40E_MASK(0xFF, I40E_GLPCI_REVID_NVM_REVID_SHIFT)
+#define I40E_GLPCI_SERH 0x000BE49C /* Reset: PCIR */
#define I40E_GLPCI_SERH_SER_NUM_H_SHIFT 0
-#define I40E_GLPCI_SERH_SER_NUM_H_MASK (0xFFFF << I40E_GLPCI_SERH_SER_NUM_H_SHIFT)
-#define I40E_GLPCI_SERL 0x000BE498
+#define I40E_GLPCI_SERH_SER_NUM_H_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SERH_SER_NUM_H_SHIFT)
+#define I40E_GLPCI_SERL 0x000BE498 /* Reset: PCIR */
#define I40E_GLPCI_SERL_SER_NUM_L_SHIFT 0
-#define I40E_GLPCI_SERL_SER_NUM_L_MASK (0xFFFFFFFF << I40E_GLPCI_SERL_SER_NUM_L_SHIFT)
-#define I40E_GLPCI_SUBSYSID 0x000BE48C
-#define I40E_GLPCI_SUBSYSID_SUB_VEN_ID_SHIFT 0
-#define I40E_GLPCI_SUBSYSID_SUB_VEN_ID_MASK (0xFFFF << I40E_GLPCI_SUBSYSID_SUB_VEN_ID_SHIFT)
-#define I40E_GLPCI_SUBSYSID_SUB_ID_SHIFT 16
-#define I40E_GLPCI_SUBSYSID_SUB_ID_MASK (0xFFFF << I40E_GLPCI_SUBSYSID_SUB_ID_SHIFT)
-#define I40E_GLPCI_UPADD 0x000BE4F8
+#define I40E_GLPCI_SERL_SER_NUM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SERL_SER_NUM_L_SHIFT)
+#define I40E_GLPCI_SPARE_BITS_0 0x0009C4F8 /* Reset: PCIR */
+#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT 0
+#define I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_0_SPARE_BITS_SHIFT)
+#define I40E_GLPCI_SPARE_BITS_1 0x0009C4FC /* Reset: PCIR */
+#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT 0
+#define I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPCI_SPARE_BITS_1_SPARE_BITS_SHIFT)
+#define I40E_GLPCI_SUBVENID 0x000BE48C /* Reset: PCIR */
+#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT 0
+#define I40E_GLPCI_SUBVENID_SUB_VEN_ID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_SUBVENID_SUB_VEN_ID_SHIFT)
+#define I40E_GLPCI_UPADD 0x000BE4F8 /* Reset: PCIR */
#define I40E_GLPCI_UPADD_ADDRESS_SHIFT 1
-#define I40E_GLPCI_UPADD_ADDRESS_MASK (0x7FFFFFFF << I40E_GLPCI_UPADD_ADDRESS_SHIFT)
-#define I40E_GLPCI_VFSUP 0x000BE4B8
+#define I40E_GLPCI_UPADD_ADDRESS_MASK I40E_MASK(0x7FFFFFFF, I40E_GLPCI_UPADD_ADDRESS_SHIFT)
+#define I40E_GLPCI_VENDORID 0x000BE518 /* Reset: PCIR */
+#define I40E_GLPCI_VENDORID_VENDORID_SHIFT 0
+#define I40E_GLPCI_VENDORID_VENDORID_MASK I40E_MASK(0xFFFF, I40E_GLPCI_VENDORID_VENDORID_SHIFT)
+#define I40E_GLPCI_VFSUP 0x000BE4B8 /* Reset: PCIR */
#define I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT 0
-#define I40E_GLPCI_VFSUP_VF_PREFETCH_MASK (0x1 << I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT)
+#define I40E_GLPCI_VFSUP_VF_PREFETCH_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VF_PREFETCH_SHIFT)
#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT 1
-#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_MASK (0x1 << I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT)
-#define I40E_PF_FUNC_RID 0x0009C000
+#define I40E_GLPCI_VFSUP_VR_BAR_TYPE_MASK I40E_MASK(0x1, I40E_GLPCI_VFSUP_VR_BAR_TYPE_SHIFT)
+#define I40E_PF_FUNC_RID 0x0009C000 /* Reset: PCIR */
#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT 0
-#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_MASK (0x7 << I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT)
+#define I40E_PF_FUNC_RID_FUNCTION_NUMBER_MASK I40E_MASK(0x7, I40E_PF_FUNC_RID_FUNCTION_NUMBER_SHIFT)
#define I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT 3
-#define I40E_PF_FUNC_RID_DEVICE_NUMBER_MASK (0x1F << I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT)
+#define I40E_PF_FUNC_RID_DEVICE_NUMBER_MASK I40E_MASK(0x1F, I40E_PF_FUNC_RID_DEVICE_NUMBER_SHIFT)
#define I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT 8
-#define I40E_PF_FUNC_RID_BUS_NUMBER_MASK (0xFF << I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT)
-#define I40E_PF_PCI_CIAA 0x0009C080
+#define I40E_PF_FUNC_RID_BUS_NUMBER_MASK I40E_MASK(0xFF, I40E_PF_FUNC_RID_BUS_NUMBER_SHIFT)
+#define I40E_PF_PCI_CIAA 0x0009C080 /* Reset: FLR */
#define I40E_PF_PCI_CIAA_ADDRESS_SHIFT 0
-#define I40E_PF_PCI_CIAA_ADDRESS_MASK (0xFFF << I40E_PF_PCI_CIAA_ADDRESS_SHIFT)
+#define I40E_PF_PCI_CIAA_ADDRESS_MASK I40E_MASK(0xFFF, I40E_PF_PCI_CIAA_ADDRESS_SHIFT)
#define I40E_PF_PCI_CIAA_VF_NUM_SHIFT 12
-#define I40E_PF_PCI_CIAA_VF_NUM_MASK (0x7F << I40E_PF_PCI_CIAA_VF_NUM_SHIFT)
-#define I40E_PF_PCI_CIAD 0x0009C100
+#define I40E_PF_PCI_CIAA_VF_NUM_MASK I40E_MASK(0x7F, I40E_PF_PCI_CIAA_VF_NUM_SHIFT)
+#define I40E_PF_PCI_CIAD 0x0009C100 /* Reset: FLR */
#define I40E_PF_PCI_CIAD_DATA_SHIFT 0
-#define I40E_PF_PCI_CIAD_DATA_MASK (0xFFFFFFFF << I40E_PF_PCI_CIAD_DATA_SHIFT)
-#define I40E_PFPCI_CLASS 0x000BE400
+#define I40E_PF_PCI_CIAD_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_PF_PCI_CIAD_DATA_SHIFT)
+#define I40E_PFPCI_CLASS 0x000BE400 /* Reset: PCIR */
#define I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT 0
-#define I40E_PFPCI_CLASS_STORAGE_CLASS_MASK (0x1 << I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT)
-#define I40E_PFPCI_CNF 0x000BE000
+#define I40E_PFPCI_CLASS_STORAGE_CLASS_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_STORAGE_CLASS_SHIFT)
+#define I40E_PFPCI_CLASS_RESERVED_1_SHIFT 1
+#define I40E_PFPCI_CLASS_RESERVED_1_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_RESERVED_1_SHIFT)
+#define I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT 2
+#define I40E_PFPCI_CLASS_PF_IS_LAN_MASK I40E_MASK(0x1, I40E_PFPCI_CLASS_PF_IS_LAN_SHIFT)
+#define I40E_PFPCI_CNF 0x000BE000 /* Reset: PCIR */
#define I40E_PFPCI_CNF_MSI_EN_SHIFT 2
-#define I40E_PFPCI_CNF_MSI_EN_MASK (0x1 << I40E_PFPCI_CNF_MSI_EN_SHIFT)
+#define I40E_PFPCI_CNF_MSI_EN_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_MSI_EN_SHIFT)
#define I40E_PFPCI_CNF_EXROM_DIS_SHIFT 3
-#define I40E_PFPCI_CNF_EXROM_DIS_MASK (0x1 << I40E_PFPCI_CNF_EXROM_DIS_SHIFT)
+#define I40E_PFPCI_CNF_EXROM_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_EXROM_DIS_SHIFT)
#define I40E_PFPCI_CNF_IO_BAR_SHIFT 4
-#define I40E_PFPCI_CNF_IO_BAR_MASK (0x1 << I40E_PFPCI_CNF_IO_BAR_SHIFT)
+#define I40E_PFPCI_CNF_IO_BAR_MASK I40E_MASK(0x1, I40E_PFPCI_CNF_IO_BAR_SHIFT)
#define I40E_PFPCI_CNF_INT_PIN_SHIFT 5
-#define I40E_PFPCI_CNF_INT_PIN_MASK (0x3 << I40E_PFPCI_CNF_INT_PIN_SHIFT)
-#define I40E_PFPCI_FACTPS 0x0009C180
+#define I40E_PFPCI_CNF_INT_PIN_MASK I40E_MASK(0x3, I40E_PFPCI_CNF_INT_PIN_SHIFT)
+#define I40E_PFPCI_DEVID 0x000BE080 /* Reset: PCIR */
+#define I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT 0
+#define I40E_PFPCI_DEVID_PF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_PF_DEV_ID_SHIFT)
+#define I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT 16
+#define I40E_PFPCI_DEVID_VF_DEV_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_DEVID_VF_DEV_ID_SHIFT)
+#define I40E_PFPCI_FACTPS 0x0009C180 /* Reset: FLR */
#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT 0
-#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_MASK (0x3 << I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT)
+#define I40E_PFPCI_FACTPS_FUNC_POWER_STATE_MASK I40E_MASK(0x3, I40E_PFPCI_FACTPS_FUNC_POWER_STATE_SHIFT)
#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT 3
-#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_MASK (0x1 << I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT)
-#define I40E_PFPCI_FUNC 0x000BE200
+#define I40E_PFPCI_FACTPS_FUNC_AUX_EN_MASK I40E_MASK(0x1, I40E_PFPCI_FACTPS_FUNC_AUX_EN_SHIFT)
+#define I40E_PFPCI_FUNC 0x000BE200 /* Reset: POR */
#define I40E_PFPCI_FUNC_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_FUNC_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_FUNC_DIS_SHIFT)
#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT 1
-#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_ALLOW_FUNC_DIS_SHIFT)
#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT 2
-#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_MASK (0x1 << I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT)
-#define I40E_PFPCI_FUNC2 0x000BE180
+#define I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC_DIS_FUNC_ON_PORT_DIS_SHIFT)
+#define I40E_PFPCI_FUNC2 0x000BE180 /* Reset: PCIR */
#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT 0
-#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_MASK (0x1 << I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT)
-#define I40E_PFPCI_ICAUSE 0x0009C200
+#define I40E_PFPCI_FUNC2_EMP_FUNC_DIS_MASK I40E_MASK(0x1, I40E_PFPCI_FUNC2_EMP_FUNC_DIS_SHIFT)
+#define I40E_PFPCI_ICAUSE 0x0009C200 /* Reset: PFR */
#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT 0
-#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_MASK (0xFFFFFFFF << I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT)
-#define I40E_PFPCI_IENA 0x0009C280
+#define I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_ICAUSE_PCIE_ERR_CAUSE_SHIFT)
+#define I40E_PFPCI_IENA 0x0009C280 /* Reset: PFR */
#define I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT 0
-#define I40E_PFPCI_IENA_PCIE_ERR_EN_MASK (0xFFFFFFFF << I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT)
-#define I40E_PFPCI_PFDEVID 0x000BE080
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_SHIFT 0
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_MASK (0xFFFF << I40E_PFPCI_PFDEVID_PF_DEV_ID_LAN_SHIFT)
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_SHIFT 16
-#define I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_MASK (0xFFFF << I40E_PFPCI_PFDEVID_PF_DEV_ID_SAN_SHIFT)
-#define I40E_PFPCI_PM 0x000BE300
+#define I40E_PFPCI_IENA_PCIE_ERR_EN_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPCI_IENA_PCIE_ERR_EN_SHIFT)
+#define I40E_PFPCI_PF_FLUSH_DONE 0x0009C800 /* Reset: PCIR */
+#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_PF_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_PM 0x000BE300 /* Reset: POR */
#define I40E_PFPCI_PM_PME_EN_SHIFT 0
-#define I40E_PFPCI_PM_PME_EN_MASK (0x1 << I40E_PFPCI_PM_PME_EN_SHIFT)
-#define I40E_PFPCI_STATUS1 0x000BE280
+#define I40E_PFPCI_PM_PME_EN_MASK I40E_MASK(0x1, I40E_PFPCI_PM_PME_EN_SHIFT)
+#define I40E_PFPCI_STATUS1 0x000BE280 /* Reset: POR */
#define I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT 0
-#define I40E_PFPCI_STATUS1_FUNC_VALID_MASK (0x1 << I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT)
-#define I40E_PFPCI_VFDEVID 0x000BE100
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_SHIFT 0
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_MASK (0xFFFF << I40E_PFPCI_VFDEVID_VF_DEV_ID_LAN_SHIFT)
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_SHIFT 16
-#define I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_MASK (0xFFFF << I40E_PFPCI_VFDEVID_VF_DEV_ID_SAN_SHIFT)
-#define I40E_PFPCI_VMINDEX 0x0009C300
+#define I40E_PFPCI_STATUS1_FUNC_VALID_MASK I40E_MASK(0x1, I40E_PFPCI_STATUS1_FUNC_VALID_SHIFT)
+#define I40E_PFPCI_SUBSYSID 0x000BE100 /* Reset: PCIR */
+#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT 0
+#define I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_PF_SUBSYS_ID_SHIFT)
+#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT 16
+#define I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_MASK I40E_MASK(0xFFFF, I40E_PFPCI_SUBSYSID_VF_SUBSYS_ID_SHIFT)
+#define I40E_PFPCI_VF_FLUSH_DONE 0x0000E400 /* Reset: PCIR */
+#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VF_FLUSH_DONE1(_VF) (0x0009C600 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: PCIR */
+#define I40E_PFPCI_VF_FLUSH_DONE1_MAX_INDEX 127
+#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VF_FLUSH_DONE1_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VM_FLUSH_DONE 0x0009C880 /* Reset: PCIR */
+#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT 0
+#define I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_MASK I40E_MASK(0x1, I40E_PFPCI_VM_FLUSH_DONE_FLUSH_DONE_SHIFT)
+#define I40E_PFPCI_VMINDEX 0x0009C300 /* Reset: PCIR */
#define I40E_PFPCI_VMINDEX_VMINDEX_SHIFT 0
-#define I40E_PFPCI_VMINDEX_VMINDEX_MASK (0x1FF << I40E_PFPCI_VMINDEX_VMINDEX_SHIFT)
-#define I40E_PFPCI_VMPEND 0x0009C380
+#define I40E_PFPCI_VMINDEX_VMINDEX_MASK I40E_MASK(0x1FF, I40E_PFPCI_VMINDEX_VMINDEX_SHIFT)
+#define I40E_PFPCI_VMPEND 0x0009C380 /* Reset: PCIR */
#define I40E_PFPCI_VMPEND_PENDING_SHIFT 0
-#define I40E_PFPCI_VMPEND_PENDING_MASK (0x1 << I40E_PFPCI_VMPEND_PENDING_SHIFT)
-#define I40E_GLPE_CPUSTATUS0 0x0000D040
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT 0
-#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT)
-#define I40E_GLPE_CPUSTATUS1 0x0000D044
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT 0
-#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT)
-#define I40E_GLPE_CPUSTATUS2 0x0000D048
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT 0
-#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_MASK (0xFFFFFFFF << I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT)
-#define I40E_GLPE_PFFLMOBJCTRL(_i) (0x0000D480 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPE_PFFLMOBJCTRL_MAX_INDEX 15
-#define I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
-#define I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK (0x7 << I40E_GLPE_PFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
-#define I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_MASK (0x7 << I40E_GLPE_PFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMOBJCTRL_MAX_INDEX 31
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
-#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK (0x7 << I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
-#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_MASK (0x7 << I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
-#define I40E_GLPE_VFFLMQ1ALLOCERR(_i) (0x0000C700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMQ1ALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFFLMXMITALLOCERR(_i) (0x0000C600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFFLMXMITALLOCERR_MAX_INDEX 31
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_GLPE_VFUDACTRL(_i) (0x0000C000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFUDACTRL_MAX_INDEX 31
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_MASK (0x1 << I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_MASK (0x1 << I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN(_i) (0x0000C100 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPE_VFUDAUCFBQPN_MAX_INDEX 31
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT 0
-#define I40E_GLPE_VFUDAUCFBQPN_QPN_MASK (0x3FFFF << I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT)
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT 31
-#define I40E_GLPE_VFUDAUCFBQPN_VALID_MASK (0x1 << I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_AEQALLOC 0x00131180
-#define I40E_PFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_PFPE_AEQALLOC_AECOUNT_MASK (0xFFFFFFFF << I40E_PFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_PFPE_CCQPHIGH 0x00008200
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_PFPE_CCQPLOW 0x00008180
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_PFPE_CCQPLOW_PECCQPLOW_MASK (0xFFFFFFFF << I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_PFPE_CCQPSTATUS 0x00008100
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_MASK (0x1 << I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_MASK (0x1 << I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_PFPE_CQACK 0x00131100
-#define I40E_PFPE_CQACK_PECQID_SHIFT 0
-#define I40E_PFPE_CQACK_PECQID_MASK (0x1FFFF << I40E_PFPE_CQACK_PECQID_SHIFT)
-#define I40E_PFPE_CQARM 0x00131080
-#define I40E_PFPE_CQARM_PECQID_SHIFT 0
-#define I40E_PFPE_CQARM_PECQID_MASK (0x1FFFF << I40E_PFPE_CQARM_PECQID_SHIFT)
-#define I40E_PFPE_CQPDB 0x00008000
-#define I40E_PFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_PFPE_CQPDB_WQHEAD_MASK (0x7FF << I40E_PFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_PFPE_CQPERRCODES 0x00008880
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_MASK (0xFFFF << I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_PFPE_CQPTAIL 0x00008080
-#define I40E_PFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_PFPE_CQPTAIL_WQTAIL_MASK (0x7FF << I40E_PFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_MASK (0x1 << I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_PFPE_FLMQ1ALLOCERR 0x00008980
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_FLMXMITALLOCERR 0x00008900
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
-#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_MASK (0xFFFF << I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT)
-#define I40E_PFPE_IPCONFIG0 0x00008280
-#define I40E_PFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_PFPE_IPCONFIG0_PEIPID_MASK (0xFFFF << I40E_PFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_MASK (0x1 << I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-
-#define I40E_PFPE_MRTEIDXMASK 0x00008600
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK (0x1F << I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_PFPE_RCVUNEXPECTEDERROR 0x00008680
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_PFPE_TCPNOWTIMER 0x00008580
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_MASK (0xFFFFFFFF << I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_PFPE_UDACTRL 0x00008700
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT 0
-#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT 1
-#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT 2
-#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT 3
-#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_MASK (0x1 << I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT)
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
-#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_MASK (0x1 << I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN 0x00008780
-#define I40E_PFPE_UDAUCFBQPN_QPN_SHIFT 0
-#define I40E_PFPE_UDAUCFBQPN_QPN_MASK (0x3FFFF << I40E_PFPE_UDAUCFBQPN_QPN_SHIFT)
-#define I40E_PFPE_UDAUCFBQPN_VALID_SHIFT 31
-#define I40E_PFPE_UDAUCFBQPN_VALID_MASK (0x1 << I40E_PFPE_UDAUCFBQPN_VALID_SHIFT)
-#define I40E_PFPE_WQEALLOC 0x00138C00
-#define I40E_PFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_PFPE_WQEALLOC_PEQPID_MASK (0x3FFFF << I40E_PFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_MASK (0xFFF << I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_VFPE_AEQALLOC(_VF) (0x00130C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_AEQALLOC_MAX_INDEX 127
-#define I40E_VFPE_AEQALLOC_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC_AECOUNT_MASK (0xFFFFFFFF << I40E_VFPE_AEQALLOC_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH(_VF) (0x00001000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPHIGH_MAX_INDEX 127
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW(_VF) (0x00000C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPLOW_MAX_INDEX 127
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW_PECCQPLOW_MASK (0xFFFFFFFF << I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS(_VF) (0x00000800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CCQPSTATUS_MAX_INDEX 127
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_MASK (0x1 << I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_MASK (0x1 << I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK(_VF) (0x00130800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQACK_MAX_INDEX 127
-#define I40E_VFPE_CQACK_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK_PECQID_MASK (0x1FFFF << I40E_VFPE_CQACK_PECQID_SHIFT)
-#define I40E_VFPE_CQARM(_VF) (0x00130400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQARM_MAX_INDEX 127
-#define I40E_VFPE_CQARM_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM_PECQID_MASK (0x1FFFF << I40E_VFPE_CQARM_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB(_VF) (0x00000000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPDB_MAX_INDEX 127
-#define I40E_VFPE_CQPDB_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB_WQHEAD_MASK (0x7FF << I40E_VFPE_CQPDB_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES(_VF) (0x00001800 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPERRCODES_MAX_INDEX 127
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL(_VF) (0x00000400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_CQPTAIL_MAX_INDEX 127
-#define I40E_VFPE_CQPTAIL_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL_WQTAIL_MASK (0x7FF << I40E_VFPE_CQPTAIL_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_MASK (0x1 << I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG0(_VF) (0x00001400 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_IPCONFIG0_MAX_INDEX 127
-#define I40E_VFPE_IPCONFIG0_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG0_PEIPID_MASK (0xFFFF << I40E_VFPE_IPCONFIG0_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_MASK (0x1 << I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK(_VF) (0x00003000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_MRTEIDXMASK_MAX_INDEX 127
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK (0x1F << I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR(_VF) (0x00003400 + ((_VF) * 4))
-#define I40E_VFPE_RCVUNEXPECTEDERROR_MAX_INDEX 127
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER(_VF) (0x00002C00 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_TCPNOWTIMER_MAX_INDEX 127
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_MASK (0xFFFFFFFF << I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC(_VF) (0x00138000 + ((_VF) * 4)) /* _i=0...127 */
-#define I40E_VFPE_WQEALLOC_MAX_INDEX 127
-#define I40E_VFPE_WQEALLOC_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC_PEQPID_MASK (0x3FFFF << I40E_VFPE_WQEALLOC_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_MASK (0xFFF << I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
-#define I40E_GLPES_PFIP4RXDISCARD(_i) (0x00010600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSHI(_i) (0x00010804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXFRAGSLO(_i) (0x00010800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSHI(_i) (0x00010A04 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCOCTSLO(_i) (0x00010A00 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSHI(_i) (0x00010C04 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXMCPKTSLO(_i) (0x00010C00 + ((_i) * 8))
-#define I40E_GLPES_PFIP4RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSHI(_i) (0x00010204 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXOCTSLO(_i) (0x00010200 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSHI(_i) (0x00010404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4RXPKTSLO(_i) (0x00010400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4RXTRUNC(_i) (0x00010700 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSHI(_i) (0x00011E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXFRAGSLO(_i) (0x00011E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSHI(_i) (0x00012004 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCOCTSLO(_i) (0x00012000 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSHI(_i) (0x00012204 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXMCPKTSLO(_i) (0x00012200 + ((_i) * 8))
-#define I40E_GLPES_PFIP4TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXNOROUTE(_i) (0x00012E00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSHI(_i) (0x00011A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXOCTSLO(_i) (0x00011A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSHI(_i) (0x00011C04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP4TXPKTSLO(_i) (0x00011C00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP4TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXDISCARD(_i) (0x00011200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXDISCARD_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSHI(_i) (0x00011404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXFRAGSLO(_i) (0x00011400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSHI(_i) (0x00011604 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCOCTSLO(_i) (0x00011600 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSHI(_i) (0x00011804 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXMCPKTSLO(_i) (0x00011800 + ((_i) * 8))
-#define I40E_GLPES_PFIP6RXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSHI(_i) (0x00010E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXOCTSLO(_i) (0x00010E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSHI(_i) (0x00011004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6RXPKTSLO(_i) (0x00011000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6RXTRUNC(_i) (0x00011300 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6RXTRUNC_MAX_INDEX 15
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSHI(_i) (0x00012804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXFRAGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXFRAGSLO(_i) (0x00012800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXFRAGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSHI(_i) (0x00012A04 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCOCTSLO(_i) (0x00012A00 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSHI(_i) (0x00012C04 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXMCPKTSLO(_i) (0x00012C00 + ((_i) * 8))
-#define I40E_GLPES_PFIP6TXMCPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXNOROUTE(_i) (0x00012F00 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXNOROUTE_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSHI(_i) (0x00012404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXOCTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXOCTSLO(_i) (0x00012400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXOCTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSHI(_i) (0x00012604 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_PFIP6TXPKTSLO(_i) (0x00012600 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFIP6TXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSHI(_i) (0x00013E04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXRDSLO(_i) (0x00013E00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSHI(_i) (0x00014004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXSNDSLO(_i) (0x00014000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSHI(_i) (0x00013C04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMARXWRSLO(_i) (0x00013C00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMARXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSHI(_i) (0x00014404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXRDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXRDSLO(_i) (0x00014400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXRDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSHI(_i) (0x00014604 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXSNDSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXSNDSLO(_i) (0x00014600 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXSNDSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSHI(_i) (0x00014204 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXWRSHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_PFRDMATXWRSLO(_i) (0x00014200 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMATXWRSLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDHI(_i) (0x00014804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVBNDHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_PFRDMAVBNDLO(_i) (0x00014800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVBNDLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_PFRDMAVINVHI(_i) (0x00014A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVINVHI_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_PFRDMAVINVLO(_i) (0x00014A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFRDMAVINVLO_MAX_INDEX 15
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_MASK (0xFFFFFFFF << I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_PFRXVLANERR(_i) (0x00010000 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFRXVLANERR_MAX_INDEX 15
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_PFRXVLANERR_RXVLANERR_MASK (0xFFFFFF << I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_PFTCPRTXSEG(_i) (0x00013600 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRTXSEG_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_PFTCPRXOPTERR(_i) (0x00013200 + ((_i) * 4)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXOPTERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_MASK (0xFFFFFF << I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_PFTCPRXPROTOERR(_i) (0x00013300 + ((_i) * 4))
-#define I40E_GLPES_PFTCPRXPROTOERR_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_MASK (0xFFFFFF << I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSHI(_i) (0x00013004 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXSEGSHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_MASK (0xFFFF << I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_PFTCPRXSEGSLO(_i) (0x00013000 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPRXSEGSLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGHI(_i) (0x00013404 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPTXSEGHI_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_MASK (0xFFFF << I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_PFTCPTXSEGLO(_i) (0x00013400 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFTCPTXSEGLO_MAX_INDEX 15
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_MASK (0xFFFFFFFF << I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSHI(_i) (0x00013804 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPRXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPRXPKTSLO(_i) (0x00013800 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPRXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSHI(_i) (0x00013A04 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPTXPKTSHI_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_MASK (0xFFFF << I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_PFUDPTXPKTSLO(_i) (0x00013A00 + ((_i) * 8)) /* _i=0...15 */
-#define I40E_GLPES_PFUDPTXPKTSLO_MAX_INDEX 15
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSHI 0x0001E014
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_MASK (0xFFFFFF << I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT)
-#define I40E_GLPES_RDMARXMULTFPDUSLO 0x0001E010
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT 0
-#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPHI 0x0001E01C
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_MASK (0xFFFFFF << I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT)
-#define I40E_GLPES_RDMARXOOODDPLO 0x0001E018
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT 0
-#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT)
-#define I40E_GLPES_RDMARXOOONOMARK 0x0001E004
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT 0
-#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT)
-#define I40E_GLPES_RDMARXUNALIGN 0x0001E000
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT 0
-#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_MASK (0xFFFFFFFF << I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLEHI 0x0001E044
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXFOURHOLELO 0x0001E040
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLEHI 0x0001E02C
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXONEHOLELO 0x0001E028
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKHI 0x0001E024
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT)
-#define I40E_GLPES_TCPRXPUREACKSLO 0x0001E020
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT 0
-#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLEHI 0x0001E03C
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTHREEHOLELO 0x0001E038
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLEHI 0x0001E034
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_MASK (0xFFFFFF << I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT)
-#define I40E_GLPES_TCPRXTWOHOLELO 0x0001E030
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT 0
-#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_MASK (0xFFFFFFFF << I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT)
-#define I40E_GLPES_TCPRXUNEXPERR 0x0001E008
-#define I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_SHIFT 0
-#define I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_MASK (0xFFFFFF << I40E_GLPES_TCPRXUNEXPERR_TCPRXUNEXPERR_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTHI 0x0001E04C
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXRETRANSFASTLO 0x0001E048
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTHI 0x0001E054
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSFASTLO 0x0001E050
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSHI 0x0001E05C
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_MASK (0xFFFFFF << I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT)
-#define I40E_GLPES_TCPTXTOUTSLO 0x0001E058
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT 0
-#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_MASK (0xFFFFFFFF << I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXDISCARD(_i) (0x00018600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSHI(_i) (0x00018804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXFRAGSLO(_i) (0x00018800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSHI(_i) (0x00018A04 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCOCTSLO(_i) (0x00018A00 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSHI(_i) (0x00018C04 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXMCPKTSLO(_i) (0x00018C00 + ((_i) * 4))
-#define I40E_GLPES_VFIP4RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSHI(_i) (0x00018204 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXOCTSLO(_i) (0x00018200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSHI(_i) (0x00018404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4RXPKTSLO(_i) (0x00018400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4RXTRUNC(_i) (0x00018700 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSHI(_i) (0x00019E04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXFRAGSLO(_i) (0x00019E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSHI(_i) (0x0001A004 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCOCTSLO(_i) (0x0001A000 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSHI(_i) (0x0001A204 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXMCPKTSLO(_i) (0x0001A200 + ((_i) * 4))
-#define I40E_GLPES_VFIP4TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXNOROUTE(_i) (0x0001AE00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSHI(_i) (0x00019A04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXOCTSLO(_i) (0x00019A00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSHI(_i) (0x00019C04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP4TXPKTSLO(_i) (0x00019C00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP4TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXDISCARD(_i) (0x00019200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXDISCARD_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
-#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSHI(_i) (0x00019404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXFRAGSLO(_i) (0x00019400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSHI(_i) (0x00019604 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCOCTSLO(_i) (0x00019600 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSHI(_i) (0x00019804 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXMCPKTSLO(_i) (0x00019800 + ((_i) * 4))
-#define I40E_GLPES_VFIP6RXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSHI(_i) (0x00018E04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXOCTSLO(_i) (0x00018E00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSHI(_i) (0x00019004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6RXPKTSLO(_i) (0x00019000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6RXTRUNC(_i) (0x00019300 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6RXTRUNC_MAX_INDEX 31
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
-#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSHI(_i) (0x0001A804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXFRAGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXFRAGSLO(_i) (0x0001A800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXFRAGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSHI(_i) (0x0001AA04 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCOCTSLO(_i) (0x0001AA00 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSHI(_i) (0x0001AC04 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXMCPKTSLO(_i) (0x0001AC00 + ((_i) * 4))
-#define I40E_GLPES_VFIP6TXMCPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXNOROUTE(_i) (0x0001AF00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXNOROUTE_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
-#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_MASK (0xFFFFFF << I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSHI(_i) (0x0001A404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXOCTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXOCTSLO(_i) (0x0001A400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXOCTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSHI(_i) (0x0001A604 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
-#define I40E_GLPES_VFIP6TXPKTSLO(_i) (0x0001A600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFIP6TXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSHI(_i) (0x0001BE04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXRDSLO(_i) (0x0001BE00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSHI(_i) (0x0001C004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXSNDSLO(_i) (0x0001C000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSHI(_i) (0x0001BC04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMARXWRSLO(_i) (0x0001BC00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMARXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSHI(_i) (0x0001C404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXRDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXRDSLO(_i) (0x0001C400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXRDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSHI(_i) (0x0001C604 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXSNDSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXSNDSLO(_i) (0x0001C600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXSNDSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSHI(_i) (0x0001C204 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXWRSHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_MASK (0xFFFF << I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
-#define I40E_GLPES_VFRDMATXWRSLO(_i) (0x0001C200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMATXWRSLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
-#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDHI(_i) (0x0001C804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVBNDHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
-#define I40E_GLPES_VFRDMAVBNDLO(_i) (0x0001C800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVBNDLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
-#define I40E_GLPES_VFRDMAVINVHI(_i) (0x0001CA04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVINVHI_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT)
-#define I40E_GLPES_VFRDMAVINVLO(_i) (0x0001CA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRDMAVINVLO_MAX_INDEX 31
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT 0
-#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_MASK (0xFFFFFFFF << I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT)
-#define I40E_GLPES_VFRXVLANERR(_i) (0x00018000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFRXVLANERR_MAX_INDEX 31
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT 0
-#define I40E_GLPES_VFRXVLANERR_RXVLANERR_MASK (0xFFFFFF << I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT)
-#define I40E_GLPES_VFTCPRTXSEG(_i) (0x0001B600 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRTXSEG_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT 0
-#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT)
-#define I40E_GLPES_VFTCPRXOPTERR(_i) (0x0001B200 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXOPTERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_MASK (0xFFFFFF << I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
-#define I40E_GLPES_VFTCPRXPROTOERR(_i) (0x0001B300 + ((_i) * 4))
-#define I40E_GLPES_VFTCPRXPROTOERR_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
-#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_MASK (0xFFFFFF << I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSHI(_i) (0x0001B004 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXSEGSHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_MASK (0xFFFF << I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
-#define I40E_GLPES_VFTCPRXSEGSLO(_i) (0x0001B000 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPRXSEGSLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
-#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGHI(_i) (0x0001B404 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPTXSEGHI_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_MASK (0xFFFF << I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
-#define I40E_GLPES_VFTCPTXSEGLO(_i) (0x0001B400 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFTCPTXSEGLO_MAX_INDEX 31
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
-#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_MASK (0xFFFFFFFF << I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSHI(_i) (0x0001B804 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPRXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPRXPKTSLO(_i) (0x0001B800 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPRXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSHI(_i) (0x0001BA04 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPTXPKTSHI_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_MASK (0xFFFF << I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
-#define I40E_GLPES_VFUDPTXPKTSLO(_i) (0x0001BA00 + ((_i) * 4)) /* _i=0...31 */
-#define I40E_GLPES_VFUDPTXPKTSLO_MAX_INDEX 31
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
-#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_MASK (0xFFFFFFFF << I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
-#define I40E_PRTPM_EEE_STAT 0x001E4320
+#define I40E_PFPCI_VMPEND_PENDING_MASK I40E_MASK(0x1, I40E_PFPCI_VMPEND_PENDING_SHIFT)
+#define I40E_PRTPM_EEE_STAT 0x001E4320 /* Reset: GLOBR */
#define I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT 29
-#define I40E_PRTPM_EEE_STAT_EEE_NEG_MASK (0x1 << I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT)
+#define I40E_PRTPM_EEE_STAT_EEE_NEG_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_EEE_NEG_SHIFT)
#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT 30
-#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK (0x1 << I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
+#define I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT)
#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT 31
-#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK (0x1 << I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
-#define I40E_PRTPM_EEEC 0x001E4380
+#define I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK I40E_MASK(0x1, I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT)
+#define I40E_PRTPM_EEEC 0x001E4380 /* Reset: GLOBR */
#define I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT 16
-#define I40E_PRTPM_EEEC_TW_WAKE_MIN_MASK (0x3F << I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT)
+#define I40E_PRTPM_EEEC_TW_WAKE_MIN_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TW_WAKE_MIN_SHIFT)
#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT 24
-#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_MASK (0x3 << I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT)
+#define I40E_PRTPM_EEEC_TX_LU_LPI_DLY_MASK I40E_MASK(0x3, I40E_PRTPM_EEEC_TX_LU_LPI_DLY_SHIFT)
#define I40E_PRTPM_EEEC_TEEE_DLY_SHIFT 26
-#define I40E_PRTPM_EEEC_TEEE_DLY_MASK (0x3F << I40E_PRTPM_EEEC_TEEE_DLY_SHIFT)
-#define I40E_PRTPM_EEEFWD 0x001E4400
+#define I40E_PRTPM_EEEC_TEEE_DLY_MASK I40E_MASK(0x3F, I40E_PRTPM_EEEC_TEEE_DLY_SHIFT)
+#define I40E_PRTPM_EEEFWD 0x001E4400 /* Reset: GLOBR */
#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT 31
-#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_MASK (0x1 << I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT)
-#define I40E_PRTPM_EEER 0x001E4360
+#define I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_MASK I40E_MASK(0x1, I40E_PRTPM_EEEFWD_EEE_FW_CONFIG_DONE_SHIFT)
+#define I40E_PRTPM_EEER 0x001E4360 /* Reset: GLOBR */
#define I40E_PRTPM_EEER_TW_SYSTEM_SHIFT 0
-#define I40E_PRTPM_EEER_TW_SYSTEM_MASK (0xFFFF << I40E_PRTPM_EEER_TW_SYSTEM_SHIFT)
+#define I40E_PRTPM_EEER_TW_SYSTEM_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEER_TW_SYSTEM_SHIFT)
#define I40E_PRTPM_EEER_TX_LPI_EN_SHIFT 16
-#define I40E_PRTPM_EEER_TX_LPI_EN_MASK (0x1 << I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
-#define I40E_PRTPM_EEETXC 0x001E43E0
+#define I40E_PRTPM_EEER_TX_LPI_EN_MASK I40E_MASK(0x1, I40E_PRTPM_EEER_TX_LPI_EN_SHIFT)
+#define I40E_PRTPM_EEETXC 0x001E43E0 /* Reset: GLOBR */
#define I40E_PRTPM_EEETXC_TW_PHY_SHIFT 0
-#define I40E_PRTPM_EEETXC_TW_PHY_MASK (0xFFFF << I40E_PRTPM_EEETXC_TW_PHY_SHIFT)
-#define I40E_PRTPM_GC 0x000B8140
+#define I40E_PRTPM_EEETXC_TW_PHY_MASK I40E_MASK(0xFFFF, I40E_PRTPM_EEETXC_TW_PHY_SHIFT)
+#define I40E_PRTPM_GC 0x000B8140 /* Reset: POR */
#define I40E_PRTPM_GC_EMP_LINK_ON_SHIFT 0
-#define I40E_PRTPM_GC_EMP_LINK_ON_MASK (0x1 << I40E_PRTPM_GC_EMP_LINK_ON_SHIFT)
+#define I40E_PRTPM_GC_EMP_LINK_ON_MASK I40E_MASK(0x1, I40E_PRTPM_GC_EMP_LINK_ON_SHIFT)
#define I40E_PRTPM_GC_MNG_VETO_SHIFT 1
-#define I40E_PRTPM_GC_MNG_VETO_MASK (0x1 << I40E_PRTPM_GC_MNG_VETO_SHIFT)
+#define I40E_PRTPM_GC_MNG_VETO_MASK I40E_MASK(0x1, I40E_PRTPM_GC_MNG_VETO_SHIFT)
#define I40E_PRTPM_GC_RATD_SHIFT 2
-#define I40E_PRTPM_GC_RATD_MASK (0x1 << I40E_PRTPM_GC_RATD_SHIFT)
+#define I40E_PRTPM_GC_RATD_MASK I40E_MASK(0x1, I40E_PRTPM_GC_RATD_SHIFT)
#define I40E_PRTPM_GC_LCDMP_SHIFT 3
-#define I40E_PRTPM_GC_LCDMP_MASK (0x1 << I40E_PRTPM_GC_LCDMP_SHIFT)
+#define I40E_PRTPM_GC_LCDMP_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LCDMP_SHIFT)
#define I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT 31
-#define I40E_PRTPM_GC_LPLU_ASSERTED_MASK (0x1 << I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT)
-#define I40E_PRTPM_RLPIC 0x001E43A0
+#define I40E_PRTPM_GC_LPLU_ASSERTED_MASK I40E_MASK(0x1, I40E_PRTPM_GC_LPLU_ASSERTED_SHIFT)
+#define I40E_PRTPM_RLPIC 0x001E43A0 /* Reset: GLOBR */
#define I40E_PRTPM_RLPIC_ERLPIC_SHIFT 0
-#define I40E_PRTPM_RLPIC_ERLPIC_MASK (0xFFFFFFFF << I40E_PRTPM_RLPIC_ERLPIC_SHIFT)
-#define I40E_PRTPM_TLPIC 0x001E43C0
+#define I40E_PRTPM_RLPIC_ERLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_RLPIC_ERLPIC_SHIFT)
+#define I40E_PRTPM_TLPIC 0x001E43C0 /* Reset: GLOBR */
#define I40E_PRTPM_TLPIC_ETLPIC_SHIFT 0
-#define I40E_PRTPM_TLPIC_ETLPIC_MASK (0xFFFFFFFF << I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
-#define I40E_GLRPB_DPSS 0x000AC828
+#define I40E_PRTPM_TLPIC_ETLPIC_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_TLPIC_ETLPIC_SHIFT)
+#define I40E_GLRPB_DPSS 0x000AC828 /* Reset: CORER */
#define I40E_GLRPB_DPSS_DPS_TCN_SHIFT 0
-#define I40E_GLRPB_DPSS_DPS_TCN_MASK (0xFFFFF << I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
-#define I40E_GLRPB_GHW 0x000AC830
+#define I40E_GLRPB_DPSS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_DPSS_DPS_TCN_SHIFT)
+#define I40E_GLRPB_GHW 0x000AC830 /* Reset: CORER */
#define I40E_GLRPB_GHW_GHW_SHIFT 0
-#define I40E_GLRPB_GHW_GHW_MASK (0xFFFFF << I40E_GLRPB_GHW_GHW_SHIFT)
-#define I40E_GLRPB_GLW 0x000AC834
+#define I40E_GLRPB_GHW_GHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GHW_GHW_SHIFT)
+#define I40E_GLRPB_GLW 0x000AC834 /* Reset: CORER */
#define I40E_GLRPB_GLW_GLW_SHIFT 0
-#define I40E_GLRPB_GLW_GLW_MASK (0xFFFFF << I40E_GLRPB_GLW_GLW_SHIFT)
-#define I40E_GLRPB_PHW 0x000AC844
+#define I40E_GLRPB_GLW_GLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_GLW_GLW_SHIFT)
+#define I40E_GLRPB_PHW 0x000AC844 /* Reset: CORER */
#define I40E_GLRPB_PHW_PHW_SHIFT 0
-#define I40E_GLRPB_PHW_PHW_MASK (0xFFFFF << I40E_GLRPB_PHW_PHW_SHIFT)
-#define I40E_GLRPB_PLW 0x000AC848
+#define I40E_GLRPB_PHW_PHW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PHW_PHW_SHIFT)
+#define I40E_GLRPB_PLW 0x000AC848 /* Reset: CORER */
#define I40E_GLRPB_PLW_PLW_SHIFT 0
-#define I40E_GLRPB_PLW_PLW_MASK (0xFFFFF << I40E_GLRPB_PLW_PLW_SHIFT)
-#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_GLRPB_PLW_PLW_MASK I40E_MASK(0xFFFFF, I40E_GLRPB_PLW_PLW_SHIFT)
+#define I40E_PRTRPB_DHW(_i) (0x000AC100 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DHW_MAX_INDEX 7
#define I40E_PRTRPB_DHW_DHW_TCN_SHIFT 0
-#define I40E_PRTRPB_DHW_DHW_TCN_MASK (0xFFFFF << I40E_PRTRPB_DHW_DHW_TCN_SHIFT)
-#define I40E_PRTRPB_DLW(_i) (0x000AC220 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DHW_DHW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DHW_DHW_TCN_SHIFT)
+#define I40E_PRTRPB_DLW(_i) (0x000AC220 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DLW_MAX_INDEX 7
#define I40E_PRTRPB_DLW_DLW_TCN_SHIFT 0
-#define I40E_PRTRPB_DLW_DLW_TCN_MASK (0xFFFFF << I40E_PRTRPB_DLW_DLW_TCN_SHIFT)
-#define I40E_PRTRPB_DPS(_i) (0x000AC320 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DLW_DLW_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DLW_DLW_TCN_SHIFT)
+#define I40E_PRTRPB_DPS(_i) (0x000AC320 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_DPS_MAX_INDEX 7
#define I40E_PRTRPB_DPS_DPS_TCN_SHIFT 0
-#define I40E_PRTRPB_DPS_DPS_TCN_MASK (0xFFFFF << I40E_PRTRPB_DPS_DPS_TCN_SHIFT)
-#define I40E_PRTRPB_SHT(_i) (0x000AC480 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_DPS_DPS_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_DPS_DPS_TCN_SHIFT)
+#define I40E_PRTRPB_SHT(_i) (0x000AC480 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_SHT_MAX_INDEX 7
#define I40E_PRTRPB_SHT_SHT_TCN_SHIFT 0
-#define I40E_PRTRPB_SHT_SHT_TCN_MASK (0xFFFFF << I40E_PRTRPB_SHT_SHT_TCN_SHIFT)
-#define I40E_PRTRPB_SHW 0x000AC580
+#define I40E_PRTRPB_SHT_SHT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHT_SHT_TCN_SHIFT)
+#define I40E_PRTRPB_SHW 0x000AC580 /* Reset: CORER */
#define I40E_PRTRPB_SHW_SHW_SHIFT 0
-#define I40E_PRTRPB_SHW_SHW_MASK (0xFFFFF << I40E_PRTRPB_SHW_SHW_SHIFT)
-#define I40E_PRTRPB_SLT(_i) (0x000AC5A0 + ((_i) * 32)) /* _i=0...7 */
+#define I40E_PRTRPB_SHW_SHW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SHW_SHW_SHIFT)
+#define I40E_PRTRPB_SLT(_i) (0x000AC5A0 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_PRTRPB_SLT_MAX_INDEX 7
#define I40E_PRTRPB_SLT_SLT_TCN_SHIFT 0
-#define I40E_PRTRPB_SLT_SLT_TCN_MASK (0xFFFFF << I40E_PRTRPB_SLT_SLT_TCN_SHIFT)
-#define I40E_PRTRPB_SLW 0x000AC6A0
+#define I40E_PRTRPB_SLT_SLT_TCN_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLT_SLT_TCN_SHIFT)
+#define I40E_PRTRPB_SLW 0x000AC6A0 /* Reset: CORER */
#define I40E_PRTRPB_SLW_SLW_SHIFT 0
-#define I40E_PRTRPB_SLW_SLW_MASK (0xFFFFF << I40E_PRTRPB_SLW_SLW_SHIFT)
-#define I40E_PRTRPB_SPS 0x000AC7C0
+#define I40E_PRTRPB_SLW_SLW_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SLW_SLW_SHIFT)
+#define I40E_PRTRPB_SPS 0x000AC7C0 /* Reset: CORER */
#define I40E_PRTRPB_SPS_SPS_SHIFT 0
-#define I40E_PRTRPB_SPS_SPS_MASK (0xFFFFF << I40E_PRTRPB_SPS_SPS_SHIFT)
-#define I40E_GLQF_APBVT(_i) (0x00260000 + ((_i) * 4)) /* _i=0...2047 */
-#define I40E_GLQF_APBVT_MAX_INDEX 2047
-#define I40E_GLQF_APBVT_APBVT_SHIFT 0
-#define I40E_GLQF_APBVT_APBVT_MASK (0xFFFFFFFF << I40E_GLQF_APBVT_APBVT_SHIFT)
-#define I40E_GLQF_CTL 0x00269BA4
+#define I40E_PRTRPB_SPS_SPS_MASK I40E_MASK(0xFFFFF, I40E_PRTRPB_SPS_SPS_SHIFT)
+#define I40E_GLQF_CTL 0x00269BA4 /* Reset: CORER */
#define I40E_GLQF_CTL_HTOEP_SHIFT 1
-#define I40E_GLQF_CTL_HTOEP_MASK (0x1 << I40E_GLQF_CTL_HTOEP_SHIFT)
+#define I40E_GLQF_CTL_HTOEP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_SHIFT)
#define I40E_GLQF_CTL_HTOEP_FCOE_SHIFT 2
-#define I40E_GLQF_CTL_HTOEP_FCOE_MASK (0x1 << I40E_GLQF_CTL_HTOEP_FCOE_SHIFT)
+#define I40E_GLQF_CTL_HTOEP_FCOE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_HTOEP_FCOE_SHIFT)
#define I40E_GLQF_CTL_PCNT_ALLOC_SHIFT 3
-#define I40E_GLQF_CTL_PCNT_ALLOC_MASK (0x7 << I40E_GLQF_CTL_PCNT_ALLOC_SHIFT)
+#define I40E_GLQF_CTL_PCNT_ALLOC_MASK I40E_MASK(0x7, I40E_GLQF_CTL_PCNT_ALLOC_SHIFT)
+#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT 6
+#define I40E_GLQF_CTL_FD_AUTO_PCTYPE_MASK I40E_MASK(0x1, I40E_GLQF_CTL_FD_AUTO_PCTYPE_SHIFT)
#define I40E_GLQF_CTL_RSVD_SHIFT 7
-#define I40E_GLQF_CTL_RSVD_MASK (0x1 << I40E_GLQF_CTL_RSVD_SHIFT)
+#define I40E_GLQF_CTL_RSVD_MASK I40E_MASK(0x1, I40E_GLQF_CTL_RSVD_SHIFT)
#define I40E_GLQF_CTL_MAXPEBLEN_SHIFT 8
-#define I40E_GLQF_CTL_MAXPEBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXPEBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXPEBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXPEBLEN_SHIFT)
#define I40E_GLQF_CTL_MAXFCBLEN_SHIFT 11
-#define I40E_GLQF_CTL_MAXFCBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXFCBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXFCBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFCBLEN_SHIFT)
#define I40E_GLQF_CTL_MAXFDBLEN_SHIFT 14
-#define I40E_GLQF_CTL_MAXFDBLEN_MASK (0x7 << I40E_GLQF_CTL_MAXFDBLEN_SHIFT)
+#define I40E_GLQF_CTL_MAXFDBLEN_MASK I40E_MASK(0x7, I40E_GLQF_CTL_MAXFDBLEN_SHIFT)
#define I40E_GLQF_CTL_FDBEST_SHIFT 17
-#define I40E_GLQF_CTL_FDBEST_MASK (0xFF << I40E_GLQF_CTL_FDBEST_SHIFT)
+#define I40E_GLQF_CTL_FDBEST_MASK I40E_MASK(0xFF, I40E_GLQF_CTL_FDBEST_SHIFT)
#define I40E_GLQF_CTL_PROGPRIO_SHIFT 25
-#define I40E_GLQF_CTL_PROGPRIO_MASK (0x1 << I40E_GLQF_CTL_PROGPRIO_SHIFT)
+#define I40E_GLQF_CTL_PROGPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_PROGPRIO_SHIFT)
#define I40E_GLQF_CTL_INVALPRIO_SHIFT 26
-#define I40E_GLQF_CTL_INVALPRIO_MASK (0x1 << I40E_GLQF_CTL_INVALPRIO_SHIFT)
+#define I40E_GLQF_CTL_INVALPRIO_MASK I40E_MASK(0x1, I40E_GLQF_CTL_INVALPRIO_SHIFT)
#define I40E_GLQF_CTL_IGNORE_IP_SHIFT 27
-#define I40E_GLQF_CTL_IGNORE_IP_MASK (0x1 << I40E_GLQF_CTL_IGNORE_IP_SHIFT)
-#define I40E_GLQF_FDCNT_0 0x00269BAC
+#define I40E_GLQF_CTL_IGNORE_IP_MASK I40E_MASK(0x1, I40E_GLQF_CTL_IGNORE_IP_SHIFT)
+#define I40E_GLQF_FDCNT_0 0x00269BAC /* Reset: CORER */
#define I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT 0
-#define I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK (0x1FFF << I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT)
+#define I40E_GLQF_FDCNT_0_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_GUARANT_CNT_SHIFT)
#define I40E_GLQF_FDCNT_0_BESTCNT_SHIFT 13
-#define I40E_GLQF_FDCNT_0_BESTCNT_MASK (0x1FFF << I40E_GLQF_FDCNT_0_BESTCNT_SHIFT)
-#define I40E_GLQF_HSYM(_i) (0x00269D00 + ((_i) * 4)) /* _i=0...63 */
+#define I40E_GLQF_FDCNT_0_BESTCNT_MASK I40E_MASK(0x1FFF, I40E_GLQF_FDCNT_0_BESTCNT_SHIFT)
+#define I40E_GLQF_HKEY(_i) (0x00270140 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
+#define I40E_GLQF_HKEY_MAX_INDEX 12
+#define I40E_GLQF_HKEY_KEY_0_SHIFT 0
+#define I40E_GLQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_0_SHIFT)
+#define I40E_GLQF_HKEY_KEY_1_SHIFT 8
+#define I40E_GLQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_1_SHIFT)
+#define I40E_GLQF_HKEY_KEY_2_SHIFT 16
+#define I40E_GLQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_2_SHIFT)
+#define I40E_GLQF_HKEY_KEY_3_SHIFT 24
+#define I40E_GLQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_GLQF_HKEY_KEY_3_SHIFT)
+#define I40E_GLQF_HSYM(_i) (0x00269D00 + ((_i) * 4)) /* _i=0...63 */ /* Reset: CORER */
#define I40E_GLQF_HSYM_MAX_INDEX 63
#define I40E_GLQF_HSYM_SYMH_ENA_SHIFT 0
-#define I40E_GLQF_HSYM_SYMH_ENA_MASK (0x1 << I40E_GLQF_HSYM_SYMH_ENA_SHIFT)
-#define I40E_GLQF_PCNT(_i) (0x00266800 + ((_i) * 4)) /* _i=0...511 */
+#define I40E_GLQF_HSYM_SYMH_ENA_MASK I40E_MASK(0x1, I40E_GLQF_HSYM_SYMH_ENA_SHIFT)
+#define I40E_GLQF_PCNT(_i) (0x00266800 + ((_i) * 4)) /* _i=0...511 */ /* Reset: CORER */
#define I40E_GLQF_PCNT_MAX_INDEX 511
#define I40E_GLQF_PCNT_PCNT_SHIFT 0
-#define I40E_GLQF_PCNT_PCNT_MASK (0xFFFFFFFF << I40E_GLQF_PCNT_PCNT_SHIFT)
-#define I40E_GLQF_SWAP(_i, _j) (0x00267E00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */
+#define I40E_GLQF_PCNT_PCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_PCNT_PCNT_SHIFT)
+#define I40E_GLQF_SWAP(_i, _j) (0x00267E00 + ((_i) * 4 + (_j) * 8)) /* _i=0...1, _j=0...63 */ /* Reset: CORER */
#define I40E_GLQF_SWAP_MAX_INDEX 1
#define I40E_GLQF_SWAP_OFF0_SRC0_SHIFT 0
-#define I40E_GLQF_SWAP_OFF0_SRC0_MASK (0x3F << I40E_GLQF_SWAP_OFF0_SRC0_SHIFT)
+#define I40E_GLQF_SWAP_OFF0_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC0_SHIFT)
#define I40E_GLQF_SWAP_OFF0_SRC1_SHIFT 6
-#define I40E_GLQF_SWAP_OFF0_SRC1_MASK (0x3F << I40E_GLQF_SWAP_OFF0_SRC1_SHIFT)
+#define I40E_GLQF_SWAP_OFF0_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF0_SRC1_SHIFT)
#define I40E_GLQF_SWAP_FLEN0_SHIFT 12
-#define I40E_GLQF_SWAP_FLEN0_MASK (0xF << I40E_GLQF_SWAP_FLEN0_SHIFT)
+#define I40E_GLQF_SWAP_FLEN0_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN0_SHIFT)
#define I40E_GLQF_SWAP_OFF1_SRC0_SHIFT 16
-#define I40E_GLQF_SWAP_OFF1_SRC0_MASK (0x3F << I40E_GLQF_SWAP_OFF1_SRC0_SHIFT)
+#define I40E_GLQF_SWAP_OFF1_SRC0_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC0_SHIFT)
#define I40E_GLQF_SWAP_OFF1_SRC1_SHIFT 22
-#define I40E_GLQF_SWAP_OFF1_SRC1_MASK (0x3F << I40E_GLQF_SWAP_OFF1_SRC1_SHIFT)
+#define I40E_GLQF_SWAP_OFF1_SRC1_MASK I40E_MASK(0x3F, I40E_GLQF_SWAP_OFF1_SRC1_SHIFT)
#define I40E_GLQF_SWAP_FLEN1_SHIFT 28
-#define I40E_GLQF_SWAP_FLEN1_MASK (0xF << I40E_GLQF_SWAP_FLEN1_SHIFT)
-#define I40E_PFQF_CTL_0 0x001C0AC0
+#define I40E_GLQF_SWAP_FLEN1_MASK I40E_MASK(0xF, I40E_GLQF_SWAP_FLEN1_SHIFT)
+#define I40E_PFQF_CTL_0 0x001C0AC0 /* Reset: CORER */
#define I40E_PFQF_CTL_0_PEHSIZE_SHIFT 0
-#define I40E_PFQF_CTL_0_PEHSIZE_MASK (0x1F << I40E_PFQF_CTL_0_PEHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PEHSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_0_PEHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PEDSIZE_SHIFT 5
-#define I40E_PFQF_CTL_0_PEDSIZE_MASK (0x1F << I40E_PFQF_CTL_0_PEDSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PEDSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_0_PEDSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT 10
-#define I40E_PFQF_CTL_0_PFFCHSIZE_MASK (0xF << I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PFFCHSIZE_MASK I40E_MASK(0xF, I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT 14
-#define I40E_PFQF_CTL_0_PFFCDSIZE_MASK (0x3 << I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_PFFCDSIZE_MASK I40E_MASK(0x3, I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT)
#define I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT 16
-#define I40E_PFQF_CTL_0_HASHLUTSIZE_MASK (0x1 << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_HASHLUTSIZE_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT)
#define I40E_PFQF_CTL_0_FD_ENA_SHIFT 17
-#define I40E_PFQF_CTL_0_FD_ENA_MASK (0x1 << I40E_PFQF_CTL_0_FD_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_FD_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_FD_ENA_SHIFT)
#define I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT 18
-#define I40E_PFQF_CTL_0_ETYPE_ENA_MASK (0x1 << I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_ETYPE_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_ETYPE_ENA_SHIFT)
#define I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT 19
-#define I40E_PFQF_CTL_0_MACVLAN_ENA_MASK (0x1 << I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT)
+#define I40E_PFQF_CTL_0_MACVLAN_ENA_MASK I40E_MASK(0x1, I40E_PFQF_CTL_0_MACVLAN_ENA_SHIFT)
#define I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT 20
-#define I40E_PFQF_CTL_0_VFFCHSIZE_MASK (0xF << I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT)
+#define I40E_PFQF_CTL_0_VFFCHSIZE_MASK I40E_MASK(0xF, I40E_PFQF_CTL_0_VFFCHSIZE_SHIFT)
#define I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT 24
-#define I40E_PFQF_CTL_0_VFFCDSIZE_MASK (0x3 << I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT)
-#define I40E_PFQF_CTL_1 0x00245D80
+#define I40E_PFQF_CTL_0_VFFCDSIZE_MASK I40E_MASK(0x3, I40E_PFQF_CTL_0_VFFCDSIZE_SHIFT)
+#define I40E_PFQF_CTL_1 0x00245D80 /* Reset: CORER */
#define I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT 0
-#define I40E_PFQF_CTL_1_CLEARFDTABLE_MASK (0x1 << I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT)
-#define I40E_PFQF_FDALLOC 0x00246280
+#define I40E_PFQF_CTL_1_CLEARFDTABLE_MASK I40E_MASK(0x1, I40E_PFQF_CTL_1_CLEARFDTABLE_SHIFT)
+#define I40E_PFQF_FDALLOC 0x00246280 /* Reset: CORER */
#define I40E_PFQF_FDALLOC_FDALLOC_SHIFT 0
-#define I40E_PFQF_FDALLOC_FDALLOC_MASK (0xFF << I40E_PFQF_FDALLOC_FDALLOC_SHIFT)
+#define I40E_PFQF_FDALLOC_FDALLOC_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDALLOC_SHIFT)
#define I40E_PFQF_FDALLOC_FDBEST_SHIFT 8
-#define I40E_PFQF_FDALLOC_FDBEST_MASK (0xFF << I40E_PFQF_FDALLOC_FDBEST_SHIFT)
-#define I40E_PFQF_FDSTAT 0x00246380
+#define I40E_PFQF_FDALLOC_FDBEST_MASK I40E_MASK(0xFF, I40E_PFQF_FDALLOC_FDBEST_SHIFT)
+#define I40E_PFQF_FDSTAT 0x00246380 /* Reset: CORER */
#define I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT 0
-#define I40E_PFQF_FDSTAT_GUARANT_CNT_MASK (0x1FFF << I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT)
+#define I40E_PFQF_FDSTAT_GUARANT_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_GUARANT_CNT_SHIFT)
#define I40E_PFQF_FDSTAT_BEST_CNT_SHIFT 16
-#define I40E_PFQF_FDSTAT_BEST_CNT_MASK (0x1FFF << I40E_PFQF_FDSTAT_BEST_CNT_SHIFT)
-#define I40E_PFQF_HENA(_i) (0x00245900 + ((_i) * 128)) /* _i=0...1 */
+#define I40E_PFQF_FDSTAT_BEST_CNT_MASK I40E_MASK(0x1FFF, I40E_PFQF_FDSTAT_BEST_CNT_SHIFT)
+#define I40E_PFQF_HENA(_i) (0x00245900 + ((_i) * 128)) /* _i=0...1 */ /* Reset: CORER */
#define I40E_PFQF_HENA_MAX_INDEX 1
#define I40E_PFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_PFQF_HENA_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_PFQF_HENA_PTYPE_ENA_SHIFT)
-#define I40E_PFQF_HKEY(_i) (0x00244800 + ((_i) * 128)) /* _i=0...12 */
+#define I40E_PFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_PFQF_HENA_PTYPE_ENA_SHIFT)
+#define I40E_PFQF_HKEY(_i) (0x00244800 + ((_i) * 128)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_PFQF_HKEY_MAX_INDEX 12
#define I40E_PFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_PFQF_HKEY_KEY_0_MASK (0xFF << I40E_PFQF_HKEY_KEY_0_SHIFT)
+#define I40E_PFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_0_SHIFT)
#define I40E_PFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_PFQF_HKEY_KEY_1_MASK (0xFF << I40E_PFQF_HKEY_KEY_1_SHIFT)
+#define I40E_PFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_1_SHIFT)
#define I40E_PFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_PFQF_HKEY_KEY_2_MASK (0xFF << I40E_PFQF_HKEY_KEY_2_SHIFT)
+#define I40E_PFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_2_SHIFT)
#define I40E_PFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_PFQF_HKEY_KEY_3_MASK (0xFF << I40E_PFQF_HKEY_KEY_3_SHIFT)
-#define I40E_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */
+#define I40E_PFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_PFQF_HKEY_KEY_3_SHIFT)
+#define I40E_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_PFQF_HLUT_MAX_INDEX 127
#define I40E_PFQF_HLUT_LUT0_SHIFT 0
-#define I40E_PFQF_HLUT_LUT0_MASK (0x3F << I40E_PFQF_HLUT_LUT0_SHIFT)
+#define I40E_PFQF_HLUT_LUT0_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT0_SHIFT)
#define I40E_PFQF_HLUT_LUT1_SHIFT 8
-#define I40E_PFQF_HLUT_LUT1_MASK (0x3F << I40E_PFQF_HLUT_LUT1_SHIFT)
+#define I40E_PFQF_HLUT_LUT1_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT1_SHIFT)
#define I40E_PFQF_HLUT_LUT2_SHIFT 16
-#define I40E_PFQF_HLUT_LUT2_MASK (0x3F << I40E_PFQF_HLUT_LUT2_SHIFT)
+#define I40E_PFQF_HLUT_LUT2_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT2_SHIFT)
#define I40E_PFQF_HLUT_LUT3_SHIFT 24
-#define I40E_PFQF_HLUT_LUT3_MASK (0x3F << I40E_PFQF_HLUT_LUT3_SHIFT)
-#define I40E_PFQF_HREGION(_i) (0x00245400 + ((_i) * 128)) /* _i=0...7 */
-#define I40E_PFQF_HREGION_MAX_INDEX 7
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
-#define I40E_PFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_PFQF_HREGION_REGION_0_MASK (0x7 << I40E_PFQF_HREGION_REGION_0_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
-#define I40E_PFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_PFQF_HREGION_REGION_1_MASK (0x7 << I40E_PFQF_HREGION_REGION_1_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
-#define I40E_PFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_PFQF_HREGION_REGION_2_MASK (0x7 << I40E_PFQF_HREGION_REGION_2_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
-#define I40E_PFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_PFQF_HREGION_REGION_3_MASK (0x7 << I40E_PFQF_HREGION_REGION_3_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
-#define I40E_PFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_PFQF_HREGION_REGION_4_MASK (0x7 << I40E_PFQF_HREGION_REGION_4_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
-#define I40E_PFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_PFQF_HREGION_REGION_5_MASK (0x7 << I40E_PFQF_HREGION_REGION_5_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
-#define I40E_PFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_PFQF_HREGION_REGION_6_MASK (0x7 << I40E_PFQF_HREGION_REGION_6_SHIFT)
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_MASK (0x1 << I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
-#define I40E_PFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_PFQF_HREGION_REGION_7_MASK (0x7 << I40E_PFQF_HREGION_REGION_7_SHIFT)
-#define I40E_PRTQF_CTL_0 0x00256E60
+#define I40E_PFQF_HLUT_LUT3_MASK I40E_MASK(0x3F, I40E_PFQF_HLUT_LUT3_SHIFT)
+#define I40E_PRTQF_CTL_0 0x00256E60 /* Reset: CORER */
#define I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT 0
-#define I40E_PRTQF_CTL_0_HSYM_ENA_MASK (0x1 << I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT)
-#define I40E_PRTQF_FD_FLXINSET(_i) (0x00253800 + ((_i) * 32)) /* _i=0...63 */
+#define I40E_PRTQF_CTL_0_HSYM_ENA_MASK I40E_MASK(0x1, I40E_PRTQF_CTL_0_HSYM_ENA_SHIFT)
+#define I40E_PRTQF_FD_FLXINSET(_i) (0x00253800 + ((_i) * 32)) /* _i=0...63 */ /* Reset: CORER */
#define I40E_PRTQF_FD_FLXINSET_MAX_INDEX 63
#define I40E_PRTQF_FD_FLXINSET_INSET_SHIFT 0
-#define I40E_PRTQF_FD_FLXINSET_INSET_MASK (0xFF << I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
-#define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */
+#define I40E_PRTQF_FD_FLXINSET_INSET_MASK I40E_MASK(0xFF, I40E_PRTQF_FD_FLXINSET_INSET_SHIFT)
+#define I40E_PRTQF_FD_MSK(_i, _j) (0x00252000 + ((_i) * 64 + (_j) * 32)) /* _i=0...63, _j=0...1 */ /* Reset: CORER */
#define I40E_PRTQF_FD_MSK_MAX_INDEX 63
#define I40E_PRTQF_FD_MSK_MASK_SHIFT 0
-#define I40E_PRTQF_FD_MSK_MASK_MASK (0xFFFF << I40E_PRTQF_FD_MSK_MASK_SHIFT)
+#define I40E_PRTQF_FD_MSK_MASK_MASK I40E_MASK(0xFFFF, I40E_PRTQF_FD_MSK_MASK_SHIFT)
#define I40E_PRTQF_FD_MSK_OFFSET_SHIFT 16
-#define I40E_PRTQF_FD_MSK_OFFSET_MASK (0x3F << I40E_PRTQF_FD_MSK_OFFSET_SHIFT)
-#define I40E_PRTQF_FLX_PIT(_i) (0x00255200 + ((_i) * 32)) /* _i=0...8 */
+#define I40E_PRTQF_FD_MSK_OFFSET_MASK I40E_MASK(0x3F, I40E_PRTQF_FD_MSK_OFFSET_SHIFT)
+#define I40E_PRTQF_FLX_PIT(_i) (0x00255200 + ((_i) * 32)) /* _i=0...8 */ /* Reset: CORER */
#define I40E_PRTQF_FLX_PIT_MAX_INDEX 8
#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT 0
-#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK (0x1F << I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
+#define I40E_PRTQF_FLX_PIT_SOURCE_OFF_MASK I40E_MASK(0x1F, I40E_PRTQF_FLX_PIT_SOURCE_OFF_SHIFT)
#define I40E_PRTQF_FLX_PIT_FSIZE_SHIFT 5
-#define I40E_PRTQF_FLX_PIT_FSIZE_MASK (0x1F << I40E_PRTQF_FLX_PIT_FSIZE_SHIFT)
+#define I40E_PRTQF_FLX_PIT_FSIZE_MASK I40E_MASK(0x1F, I40E_PRTQF_FLX_PIT_FSIZE_SHIFT)
#define I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT 10
-#define I40E_PRTQF_FLX_PIT_DEST_OFF_MASK (0x3F << I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
-#define I40E_VFQF_HENA1(_i, _VF) (0x00230800 + ((_i) * 1024 + (_VF) * 4))
+#define I40E_PRTQF_FLX_PIT_DEST_OFF_MASK I40E_MASK(0x3F, I40E_PRTQF_FLX_PIT_DEST_OFF_SHIFT)
+#define I40E_VFQF_HENA1(_i, _VF) (0x00230800 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...1, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HENA1_MAX_INDEX 1
#define I40E_VFQF_HENA1_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA1_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_VFQF_HENA1_PTYPE_ENA_SHIFT)
-#define I40E_VFQF_HKEY1(_i, _VF) (0x00228000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...12, _VF=0...127 */
+#define I40E_VFQF_HENA1_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA1_PTYPE_ENA_SHIFT)
+#define I40E_VFQF_HKEY1(_i, _VF) (0x00228000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...12, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HKEY1_MAX_INDEX 12
#define I40E_VFQF_HKEY1_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY1_KEY_0_MASK (0xFF << I40E_VFQF_HKEY1_KEY_0_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_0_SHIFT)
#define I40E_VFQF_HKEY1_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY1_KEY_1_MASK (0xFF << I40E_VFQF_HKEY1_KEY_1_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_1_SHIFT)
#define I40E_VFQF_HKEY1_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY1_KEY_2_MASK (0xFF << I40E_VFQF_HKEY1_KEY_2_SHIFT)
+#define I40E_VFQF_HKEY1_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_2_SHIFT)
#define I40E_VFQF_HKEY1_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY1_KEY_3_MASK (0xFF << I40E_VFQF_HKEY1_KEY_3_SHIFT)
-#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */
+#define I40E_VFQF_HKEY1_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY1_KEY_3_SHIFT)
+#define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HLUT1_MAX_INDEX 15
#define I40E_VFQF_HLUT1_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT1_LUT0_MASK (0xF << I40E_VFQF_HLUT1_LUT0_SHIFT)
+#define I40E_VFQF_HLUT1_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT0_SHIFT)
#define I40E_VFQF_HLUT1_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT1_LUT1_MASK (0xF << I40E_VFQF_HLUT1_LUT1_SHIFT)
+#define I40E_VFQF_HLUT1_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT1_SHIFT)
#define I40E_VFQF_HLUT1_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT1_LUT2_MASK (0xF << I40E_VFQF_HLUT1_LUT2_SHIFT)
+#define I40E_VFQF_HLUT1_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT2_SHIFT)
#define I40E_VFQF_HLUT1_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT1_LUT3_MASK (0xF << I40E_VFQF_HLUT1_LUT3_SHIFT)
-#define I40E_VFQF_HREGION1(_i, _VF) (0x0022E000 + ((_i) * 1024 + (_VF) * 4))
+#define I40E_VFQF_HLUT1_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT1_LUT3_SHIFT)
+#define I40E_VFQF_HREGION1(_i, _VF) (0x0022E000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...7, _VF=0...127 */ /* Reset: CORER */
#define I40E_VFQF_HREGION1_MAX_INDEX 7
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_0_SHIFT)
#define I40E_VFQF_HREGION1_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION1_REGION_0_MASK (0x7 << I40E_VFQF_HREGION1_REGION_0_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_0_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_1_SHIFT)
#define I40E_VFQF_HREGION1_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION1_REGION_1_MASK (0x7 << I40E_VFQF_HREGION1_REGION_1_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_1_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_2_SHIFT)
#define I40E_VFQF_HREGION1_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION1_REGION_2_MASK (0x7 << I40E_VFQF_HREGION1_REGION_2_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_2_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_3_SHIFT)
#define I40E_VFQF_HREGION1_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION1_REGION_3_MASK (0x7 << I40E_VFQF_HREGION1_REGION_3_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_3_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_4_SHIFT)
#define I40E_VFQF_HREGION1_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION1_REGION_4_MASK (0x7 << I40E_VFQF_HREGION1_REGION_4_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_4_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_5_SHIFT)
#define I40E_VFQF_HREGION1_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION1_REGION_5_MASK (0x7 << I40E_VFQF_HREGION1_REGION_5_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_5_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_6_SHIFT)
#define I40E_VFQF_HREGION1_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION1_REGION_6_MASK (0x7 << I40E_VFQF_HREGION1_REGION_6_SHIFT)
+#define I40E_VFQF_HREGION1_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_6_SHIFT)
#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_MASK (0x1 << I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT)
+#define I40E_VFQF_HREGION1_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION1_OVERRIDE_ENA_7_SHIFT)
#define I40E_VFQF_HREGION1_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION1_REGION_7_MASK (0x7 << I40E_VFQF_HREGION1_REGION_7_SHIFT)
-#define I40E_VPQF_CTL(_VF) (0x001C0000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VFQF_HREGION1_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION1_REGION_7_SHIFT)
+#define I40E_VPQF_CTL(_VF) (0x001C0000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
#define I40E_VPQF_CTL_MAX_INDEX 127
#define I40E_VPQF_CTL_PEHSIZE_SHIFT 0
-#define I40E_VPQF_CTL_PEHSIZE_MASK (0x1F << I40E_VPQF_CTL_PEHSIZE_SHIFT)
+#define I40E_VPQF_CTL_PEHSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEHSIZE_SHIFT)
#define I40E_VPQF_CTL_PEDSIZE_SHIFT 5
-#define I40E_VPQF_CTL_PEDSIZE_MASK (0x1F << I40E_VPQF_CTL_PEDSIZE_SHIFT)
+#define I40E_VPQF_CTL_PEDSIZE_MASK I40E_MASK(0x1F, I40E_VPQF_CTL_PEDSIZE_SHIFT)
#define I40E_VPQF_CTL_FCHSIZE_SHIFT 10
-#define I40E_VPQF_CTL_FCHSIZE_MASK (0xF << I40E_VPQF_CTL_FCHSIZE_SHIFT)
+#define I40E_VPQF_CTL_FCHSIZE_MASK I40E_MASK(0xF, I40E_VPQF_CTL_FCHSIZE_SHIFT)
#define I40E_VPQF_CTL_FCDSIZE_SHIFT 14
-#define I40E_VPQF_CTL_FCDSIZE_MASK (0x3 << I40E_VPQF_CTL_FCDSIZE_SHIFT)
-#define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) /* _i=0...383 */
+#define I40E_VPQF_CTL_FCDSIZE_MASK I40E_MASK(0x3, I40E_VPQF_CTL_FCDSIZE_SHIFT)
+#define I40E_VSIQF_CTL(_VSI) (0x0020D800 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: PFR */
#define I40E_VSIQF_CTL_MAX_INDEX 383
#define I40E_VSIQF_CTL_FCOE_ENA_SHIFT 0
-#define I40E_VSIQF_CTL_FCOE_ENA_MASK (0x1 << I40E_VSIQF_CTL_FCOE_ENA_SHIFT)
+#define I40E_VSIQF_CTL_FCOE_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_FCOE_ENA_SHIFT)
#define I40E_VSIQF_CTL_PETCP_ENA_SHIFT 1
-#define I40E_VSIQF_CTL_PETCP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PETCP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PETCP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PETCP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT 2
-#define I40E_VSIQF_CTL_PEUUDP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEUUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUUDP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT 3
-#define I40E_VSIQF_CTL_PEMUDP_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEMUDP_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMUDP_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT 4
-#define I40E_VSIQF_CTL_PEUFRAG_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT)
+#define I40E_VSIQF_CTL_PEUFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEUFRAG_ENA_SHIFT)
#define I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT 5
-#define I40E_VSIQF_CTL_PEMFRAG_ENA_MASK (0x1 << I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT)
-#define I40E_VSIQF_TCREGION(_i, _VSI) (0x00206000 + ((_i) * 2048 + (_VSI) * 4))
+#define I40E_VSIQF_CTL_PEMFRAG_ENA_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_PEMFRAG_ENA_SHIFT)
+#define I40E_VSIQF_TCREGION(_i, _VSI) (0x00206000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...3, _VSI=0...383 */ /* Reset: PFR */
#define I40E_VSIQF_TCREGION_MAX_INDEX 3
#define I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT 0
-#define I40E_VSIQF_TCREGION_TC_OFFSET_MASK (0x1FF << I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_OFFSET_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET_SHIFT)
#define I40E_VSIQF_TCREGION_TC_SIZE_SHIFT 9
-#define I40E_VSIQF_TCREGION_TC_SIZE_MASK (0x7 << I40E_VSIQF_TCREGION_TC_SIZE_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_SIZE_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE_SHIFT)
#define I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT 16
-#define I40E_VSIQF_TCREGION_TC_OFFSET2_MASK (0x1FF << I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT)
+#define I40E_VSIQF_TCREGION_TC_OFFSET2_MASK I40E_MASK(0x1FF, I40E_VSIQF_TCREGION_TC_OFFSET2_SHIFT)
#define I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT 25
-#define I40E_VSIQF_TCREGION_TC_SIZE2_MASK (0x7 << I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT)
-#define I40E_GL_FCOECRC(_i) (0x00314d80 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_VSIQF_TCREGION_TC_SIZE2_MASK I40E_MASK(0x7, I40E_VSIQF_TCREGION_TC_SIZE2_SHIFT)
+#define I40E_GL_FCOECRC(_i) (0x00314d80 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOECRC_MAX_INDEX 143
#define I40E_GL_FCOECRC_FCOECRC_SHIFT 0
-#define I40E_GL_FCOECRC_FCOECRC_MASK (0xFFFFFFFF << I40E_GL_FCOECRC_FCOECRC_SHIFT)
-#define I40E_GL_FCOEDDPC(_i) (0x00314480 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOECRC_FCOECRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOECRC_FCOECRC_SHIFT)
+#define I40E_GL_FCOEDDPC(_i) (0x00314480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDDPC_MAX_INDEX 143
#define I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT 0
-#define I40E_GL_FCOEDDPC_FCOEDDPC_MASK (0xFFFFFFFF << I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT)
-/* _i=0...143 */
-#define I40E_GL_FCOEDIFEC(_i) (0x00318480 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDDPC_FCOEDDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDDPC_FCOEDDPC_SHIFT)
+#define I40E_GL_FCOEDIFEC(_i) (0x00318480 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIFEC_MAX_INDEX 143
#define I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT 0
-#define I40E_GL_FCOEDIFEC_FCOEDIFRC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT)
-#define I40E_GL_FCOEDIFRC(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */
-#define I40E_GL_FCOEDIFRC_MAX_INDEX 143
-#define I40E_GL_FCOEDIFRC_FCOEDIFRC_SHIFT 0
-#define I40E_GL_FCOEDIFRC_FCOEDIFRC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFRC_FCOEDIFRC_SHIFT)
-#define I40E_GL_FCOEDIFTCL(_i) (0x00354000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIFEC_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFEC_FCOEDIFRC_SHIFT)
+#define I40E_GL_FCOEDIFTCL(_i) (0x00354000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIFTCL_MAX_INDEX 143
#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT 0
-#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT)
-#define I40E_GL_FCOEDIXAC(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */
-#define I40E_GL_FCOEDIXAC_MAX_INDEX 143
-#define I40E_GL_FCOEDIXAC_FCOEDIXAC_SHIFT 0
-#define I40E_GL_FCOEDIXAC_FCOEDIXAC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXAC_FCOEDIXAC_SHIFT)
-#define I40E_GL_FCOEDIXEC(_i) (0x0034c000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIFTCL_FCOEDIFTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIFTCL_FCOEDIFTC_SHIFT)
+#define I40E_GL_FCOEDIXEC(_i) (0x0034c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIXEC_MAX_INDEX 143
#define I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT 0
-#define I40E_GL_FCOEDIXEC_FCOEDIXEC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT)
-#define I40E_GL_FCOEDIXVC(_i) (0x00350000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIXEC_FCOEDIXEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXEC_FCOEDIXEC_SHIFT)
+#define I40E_GL_FCOEDIXVC(_i) (0x00350000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDIXVC_MAX_INDEX 143
#define I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT 0
-#define I40E_GL_FCOEDIXVC_FCOEDIXVC_MASK (0xFFFFFFFF << I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT)
-#define I40E_GL_FCOEDWRCH(_i) (0x00320004 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDIXVC_FCOEDIXVC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDIXVC_FCOEDIXVC_SHIFT)
+#define I40E_GL_FCOEDWRCH(_i) (0x00320004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWRCH_MAX_INDEX 143
#define I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT 0
-#define I40E_GL_FCOEDWRCH_FCOEDWRCH_MASK (0xFFFF << I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT)
-#define I40E_GL_FCOEDWRCL(_i) (0x00320000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWRCH_FCOEDWRCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWRCH_FCOEDWRCH_SHIFT)
+#define I40E_GL_FCOEDWRCL(_i) (0x00320000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWRCL_MAX_INDEX 143
#define I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT 0
-#define I40E_GL_FCOEDWRCL_FCOEDWRCL_MASK (0xFFFFFFFF << I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT)
-#define I40E_GL_FCOEDWTCH(_i) (0x00348084 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWRCL_FCOEDWRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWRCL_FCOEDWRCL_SHIFT)
+#define I40E_GL_FCOEDWTCH(_i) (0x00348084 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWTCH_MAX_INDEX 143
#define I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT 0
-#define I40E_GL_FCOEDWTCH_FCOEDWTCH_MASK (0xFFFF << I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT)
-#define I40E_GL_FCOEDWTCL(_i) (0x00348080 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWTCH_FCOEDWTCH_MASK I40E_MASK(0xFFFF, I40E_GL_FCOEDWTCH_FCOEDWTCH_SHIFT)
+#define I40E_GL_FCOEDWTCL(_i) (0x00348080 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEDWTCL_MAX_INDEX 143
#define I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT 0
-#define I40E_GL_FCOEDWTCL_FCOEDWTCL_MASK (0xFFFFFFFF << I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT)
-#define I40E_GL_FCOELAST(_i) (0x00314000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEDWTCL_FCOEDWTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEDWTCL_FCOEDWTCL_SHIFT)
+#define I40E_GL_FCOELAST(_i) (0x00314000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOELAST_MAX_INDEX 143
#define I40E_GL_FCOELAST_FCOELAST_SHIFT 0
-#define I40E_GL_FCOELAST_FCOELAST_MASK (0xFFFFFFFF << I40E_GL_FCOELAST_FCOELAST_SHIFT)
-#define I40E_GL_FCOEPRC(_i) (0x00315200 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOELAST_FCOELAST_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOELAST_FCOELAST_SHIFT)
+#define I40E_GL_FCOEPRC(_i) (0x00315200 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEPRC_MAX_INDEX 143
#define I40E_GL_FCOEPRC_FCOEPRC_SHIFT 0
-#define I40E_GL_FCOEPRC_FCOEPRC_MASK (0xFFFFFFFF << I40E_GL_FCOEPRC_FCOEPRC_SHIFT)
-#define I40E_GL_FCOEPTC(_i) (0x00344C00 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEPRC_FCOEPRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPRC_FCOEPRC_SHIFT)
+#define I40E_GL_FCOEPTC(_i) (0x00344C00 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOEPTC_MAX_INDEX 143
#define I40E_GL_FCOEPTC_FCOEPTC_SHIFT 0
-#define I40E_GL_FCOEPTC_FCOEPTC_MASK (0xFFFFFFFF << I40E_GL_FCOEPTC_FCOEPTC_SHIFT)
-#define I40E_GL_FCOERPDC(_i) (0x00324000 + ((_i) * 8)) /* _i=0...143 */
+#define I40E_GL_FCOEPTC_FCOEPTC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOEPTC_FCOEPTC_SHIFT)
+#define I40E_GL_FCOERPDC(_i) (0x00324000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
#define I40E_GL_FCOERPDC_MAX_INDEX 143
#define I40E_GL_FCOERPDC_FCOERPDC_SHIFT 0
-#define I40E_GL_FCOERPDC_FCOERPDC_MASK (0xFFFFFFFF << I40E_GL_FCOERPDC_FCOERPDC_SHIFT)
-#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GL_FCOERPDC_FCOERPDC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOERPDC_FCOERPDC_SHIFT)
+#define I40E_GL_RXERR1_L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1_L_MAX_INDEX 143
+#define I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT 0
+#define I40E_GL_RXERR1_L_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT)
+#define I40E_GL_RXERR2_L(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR2_L_MAX_INDEX 143
+#define I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT 0
+#define I40E_GL_RXERR2_L_FCOEDIXAC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT)
+#define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPRCH_MAX_INDEX 3
#define I40E_GLPRT_BPRCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPRCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_BPRCH_UPRCH_SHIFT)
-#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPRCH_UPRCH_SHIFT)
+#define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPRCL_MAX_INDEX 3
#define I40E_GLPRT_BPRCL_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPRCL_UPRCH_MASK (0xFFFFFFFF << I40E_GLPRT_BPRCL_UPRCH_SHIFT)
-#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPRCL_UPRCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPRCL_UPRCH_SHIFT)
+#define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPTCH_MAX_INDEX 3
#define I40E_GLPRT_BPTCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPTCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_BPTCH_UPRCH_SHIFT)
-#define I40E_GLPRT_BPTCL(_i) (0x00300A00 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPTCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_BPTCH_UPRCH_SHIFT)
+#define I40E_GLPRT_BPTCL(_i) (0x00300A00 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_BPTCL_MAX_INDEX 3
#define I40E_GLPRT_BPTCL_UPRCH_SHIFT 0
-#define I40E_GLPRT_BPTCL_UPRCH_MASK (0xFFFFFFFF << I40E_GLPRT_BPTCL_UPRCH_SHIFT)
-#define I40E_GLPRT_CRCERRS(_i) (0x00300080 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_BPTCL_UPRCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_BPTCL_UPRCH_SHIFT)
+#define I40E_GLPRT_CRCERRS(_i) (0x00300080 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_CRCERRS_MAX_INDEX 3
#define I40E_GLPRT_CRCERRS_CRCERRS_SHIFT 0
-#define I40E_GLPRT_CRCERRS_CRCERRS_MASK (0xFFFFFFFF << I40E_GLPRT_CRCERRS_CRCERRS_SHIFT)
-#define I40E_GLPRT_GORCH(_i) (0x00300004 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_CRCERRS_CRCERRS_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_CRCERRS_CRCERRS_SHIFT)
+#define I40E_GLPRT_GORCH(_i) (0x00300004 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GORCH_MAX_INDEX 3
#define I40E_GLPRT_GORCH_GORCH_SHIFT 0
-#define I40E_GLPRT_GORCH_GORCH_MASK (0xFFFF << I40E_GLPRT_GORCH_GORCH_SHIFT)
-#define I40E_GLPRT_GORCL(_i) (0x00300000 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GORCH_GORCH_SHIFT)
+#define I40E_GLPRT_GORCL(_i) (0x00300000 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GORCL_MAX_INDEX 3
#define I40E_GLPRT_GORCL_GORCL_SHIFT 0
-#define I40E_GLPRT_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLPRT_GORCL_GORCL_SHIFT)
-#define I40E_GLPRT_GOTCH(_i) (0x00300684 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GORCL_GORCL_SHIFT)
+#define I40E_GLPRT_GOTCH(_i) (0x00300684 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GOTCH_MAX_INDEX 3
#define I40E_GLPRT_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLPRT_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLPRT_GOTCH_GOTCH_SHIFT)
-#define I40E_GLPRT_GOTCL(_i) (0x00300680 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_GOTCH_GOTCH_SHIFT)
+#define I40E_GLPRT_GOTCL(_i) (0x00300680 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_GOTCL_MAX_INDEX 3
#define I40E_GLPRT_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLPRT_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLPRT_GOTCL_GOTCL_SHIFT)
-#define I40E_GLPRT_ILLERRC(_i) (0x003000E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_GOTCL_GOTCL_SHIFT)
+#define I40E_GLPRT_ILLERRC(_i) (0x003000E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_ILLERRC_MAX_INDEX 3
#define I40E_GLPRT_ILLERRC_ILLERRC_SHIFT 0
-#define I40E_GLPRT_ILLERRC_ILLERRC_MASK (0xFFFFFFFF << I40E_GLPRT_ILLERRC_ILLERRC_SHIFT)
-#define I40E_GLPRT_LDPC(_i) (0x00300620 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_ILLERRC_ILLERRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ILLERRC_ILLERRC_SHIFT)
+#define I40E_GLPRT_LDPC(_i) (0x00300620 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LDPC_MAX_INDEX 3
#define I40E_GLPRT_LDPC_LDPC_SHIFT 0
-#define I40E_GLPRT_LDPC_LDPC_MASK (0xFFFFFFFF << I40E_GLPRT_LDPC_LDPC_SHIFT)
-#define I40E_GLPRT_LXOFFRXC(_i) (0x00300160 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LDPC_LDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LDPC_LDPC_SHIFT)
+#define I40E_GLPRT_LXOFFRXC(_i) (0x00300160 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXOFFRXC_MAX_INDEX 3
#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT)
-#define I40E_GLPRT_LXOFFTXC(_i) (0x003009A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFRXC_LXOFFRXCNT_SHIFT)
+#define I40E_GLPRT_LXOFFTXC(_i) (0x003009A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXOFFTXC_MAX_INDEX 3
#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT 0
-#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_MASK (0xFFFFFFFF << I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT)
-#define I40E_GLPRT_LXONRXC(_i) (0x00300140 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXOFFTXC_LXOFFTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXOFFTXC_LXOFFTXC_SHIFT)
+#define I40E_GLPRT_LXONRXC(_i) (0x00300140 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXONRXC_MAX_INDEX 3
#define I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT 0
-#define I40E_GLPRT_LXONRXC_LXONRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT)
-#define I40E_GLPRT_LXONTXC(_i) (0x00300980 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXONRXC_LXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONRXC_LXONRXCNT_SHIFT)
+#define I40E_GLPRT_LXONTXC(_i) (0x00300980 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_LXONTXC_MAX_INDEX 3
#define I40E_GLPRT_LXONTXC_LXONTXC_SHIFT 0
-#define I40E_GLPRT_LXONTXC_LXONTXC_MASK (0xFFFFFFFF << I40E_GLPRT_LXONTXC_LXONTXC_SHIFT)
-#define I40E_GLPRT_MLFC(_i) (0x00300020 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_LXONTXC_LXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_LXONTXC_LXONTXC_SHIFT)
+#define I40E_GLPRT_MLFC(_i) (0x00300020 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MLFC_MAX_INDEX 3
#define I40E_GLPRT_MLFC_MLFC_SHIFT 0
-#define I40E_GLPRT_MLFC_MLFC_MASK (0xFFFFFFFF << I40E_GLPRT_MLFC_MLFC_SHIFT)
-#define I40E_GLPRT_MPRCH(_i) (0x003005C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MLFC_MLFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MLFC_MLFC_SHIFT)
+#define I40E_GLPRT_MPRCH(_i) (0x003005C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPRCH_MAX_INDEX 3
#define I40E_GLPRT_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLPRT_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLPRT_MPRCH_MPRCH_SHIFT)
-#define I40E_GLPRT_MPRCL(_i) (0x003005C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPRCH_MPRCH_SHIFT)
+#define I40E_GLPRT_MPRCL(_i) (0x003005C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPRCL_MAX_INDEX 3
#define I40E_GLPRT_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLPRT_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLPRT_MPRCL_MPRCL_SHIFT)
-#define I40E_GLPRT_MPTCH(_i) (0x003009E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPRCL_MPRCL_SHIFT)
+#define I40E_GLPRT_MPTCH(_i) (0x003009E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPTCH_MAX_INDEX 3
#define I40E_GLPRT_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLPRT_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLPRT_MPTCH_MPTCH_SHIFT)
-#define I40E_GLPRT_MPTCL(_i) (0x003009E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_MPTCH_MPTCH_SHIFT)
+#define I40E_GLPRT_MPTCL(_i) (0x003009E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MPTCL_MAX_INDEX 3
#define I40E_GLPRT_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLPRT_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLPRT_MPTCL_MPTCL_SHIFT)
-#define I40E_GLPRT_MRFC(_i) (0x00300040 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MPTCL_MPTCL_SHIFT)
+#define I40E_GLPRT_MRFC(_i) (0x00300040 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_MRFC_MAX_INDEX 3
#define I40E_GLPRT_MRFC_MRFC_SHIFT 0
-#define I40E_GLPRT_MRFC_MRFC_MASK (0xFFFFFFFF << I40E_GLPRT_MRFC_MRFC_SHIFT)
-#define I40E_GLPRT_PRC1023H(_i) (0x00300504 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_MRFC_MRFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_MRFC_MRFC_SHIFT)
+#define I40E_GLPRT_PRC1023H(_i) (0x00300504 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1023H_MAX_INDEX 3
#define I40E_GLPRT_PRC1023H_PRC1023H_SHIFT 0
-#define I40E_GLPRT_PRC1023H_PRC1023H_MASK (0xFFFF << I40E_GLPRT_PRC1023H_PRC1023H_SHIFT)
-#define I40E_GLPRT_PRC1023L(_i) (0x00300500 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1023H_PRC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1023H_PRC1023H_SHIFT)
+#define I40E_GLPRT_PRC1023L(_i) (0x00300500 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1023L_MAX_INDEX 3
#define I40E_GLPRT_PRC1023L_PRC1023L_SHIFT 0
-#define I40E_GLPRT_PRC1023L_PRC1023L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC1023L_PRC1023L_SHIFT)
-#define I40E_GLPRT_PRC127H(_i) (0x003004A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1023L_PRC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1023L_PRC1023L_SHIFT)
+#define I40E_GLPRT_PRC127H(_i) (0x003004A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC127H_MAX_INDEX 3
#define I40E_GLPRT_PRC127H_PRC127H_SHIFT 0
-#define I40E_GLPRT_PRC127H_PRC127H_MASK (0xFFFF << I40E_GLPRT_PRC127H_PRC127H_SHIFT)
-#define I40E_GLPRT_PRC127L(_i) (0x003004A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC127H_PRC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC127H_PRC127H_SHIFT)
+#define I40E_GLPRT_PRC127L(_i) (0x003004A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC127L_MAX_INDEX 3
#define I40E_GLPRT_PRC127L_PRC127L_SHIFT 0
-#define I40E_GLPRT_PRC127L_PRC127L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC127L_PRC127L_SHIFT)
-#define I40E_GLPRT_PRC1522H(_i) (0x00300524 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC127L_PRC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC127L_PRC127L_SHIFT)
+#define I40E_GLPRT_PRC1522H(_i) (0x00300524 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1522H_MAX_INDEX 3
#define I40E_GLPRT_PRC1522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC1522H_PRC1522H_MASK (0xFFFF << I40E_GLPRT_PRC1522H_PRC1522H_SHIFT)
-#define I40E_GLPRT_PRC1522L(_i) (0x00300520 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC1522H_PRC1522H_SHIFT)
+#define I40E_GLPRT_PRC1522L(_i) (0x00300520 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC1522L_MAX_INDEX 3
#define I40E_GLPRT_PRC1522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC1522L_PRC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC1522L_PRC1522L_SHIFT)
-#define I40E_GLPRT_PRC255H(_i) (0x003004C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC1522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC1522L_PRC1522L_SHIFT)
+#define I40E_GLPRT_PRC255H(_i) (0x003004C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC255H_MAX_INDEX 3
#define I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT 0
-#define I40E_GLPRT_PRC255H_PRTPRC255H_MASK (0xFFFF << I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT)
-#define I40E_GLPRT_PRC255L(_i) (0x003004C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC255H_PRTPRC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC255H_PRTPRC255H_SHIFT)
+#define I40E_GLPRT_PRC255L(_i) (0x003004C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC255L_MAX_INDEX 3
#define I40E_GLPRT_PRC255L_PRC255L_SHIFT 0
-#define I40E_GLPRT_PRC255L_PRC255L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC255L_PRC255L_SHIFT)
-#define I40E_GLPRT_PRC511H(_i) (0x003004E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC255L_PRC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC255L_PRC255L_SHIFT)
+#define I40E_GLPRT_PRC511H(_i) (0x003004E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC511H_MAX_INDEX 3
#define I40E_GLPRT_PRC511H_PRC511H_SHIFT 0
-#define I40E_GLPRT_PRC511H_PRC511H_MASK (0xFFFF << I40E_GLPRT_PRC511H_PRC511H_SHIFT)
-#define I40E_GLPRT_PRC511L(_i) (0x003004E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC511H_PRC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC511H_PRC511H_SHIFT)
+#define I40E_GLPRT_PRC511L(_i) (0x003004E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC511L_MAX_INDEX 3
#define I40E_GLPRT_PRC511L_PRC511L_SHIFT 0
-#define I40E_GLPRT_PRC511L_PRC511L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC511L_PRC511L_SHIFT)
-#define I40E_GLPRT_PRC64H(_i) (0x00300484 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC511L_PRC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC511L_PRC511L_SHIFT)
+#define I40E_GLPRT_PRC64H(_i) (0x00300484 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC64H_MAX_INDEX 3
#define I40E_GLPRT_PRC64H_PRC64H_SHIFT 0
-#define I40E_GLPRT_PRC64H_PRC64H_MASK (0xFFFF << I40E_GLPRT_PRC64H_PRC64H_SHIFT)
-#define I40E_GLPRT_PRC64L(_i) (0x00300480 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC64H_PRC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC64H_PRC64H_SHIFT)
+#define I40E_GLPRT_PRC64L(_i) (0x00300480 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC64L_MAX_INDEX 3
#define I40E_GLPRT_PRC64L_PRC64L_SHIFT 0
-#define I40E_GLPRT_PRC64L_PRC64L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC64L_PRC64L_SHIFT)
-#define I40E_GLPRT_PRC9522H(_i) (0x00300544 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC64L_PRC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC64L_PRC64L_SHIFT)
+#define I40E_GLPRT_PRC9522H(_i) (0x00300544 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC9522H_MAX_INDEX 3
#define I40E_GLPRT_PRC9522H_PRC1522H_SHIFT 0
-#define I40E_GLPRT_PRC9522H_PRC1522H_MASK (0xFFFF << I40E_GLPRT_PRC9522H_PRC1522H_SHIFT)
-#define I40E_GLPRT_PRC9522L(_i) (0x00300540 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC9522H_PRC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PRC9522H_PRC1522H_SHIFT)
+#define I40E_GLPRT_PRC9522L(_i) (0x00300540 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PRC9522L_MAX_INDEX 3
#define I40E_GLPRT_PRC9522L_PRC1522L_SHIFT 0
-#define I40E_GLPRT_PRC9522L_PRC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PRC9522L_PRC1522L_SHIFT)
-#define I40E_GLPRT_PTC1023H(_i) (0x00300724 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PRC9522L_PRC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PRC9522L_PRC1522L_SHIFT)
+#define I40E_GLPRT_PTC1023H(_i) (0x00300724 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1023H_MAX_INDEX 3
#define I40E_GLPRT_PTC1023H_PTC1023H_SHIFT 0
-#define I40E_GLPRT_PTC1023H_PTC1023H_MASK (0xFFFF << I40E_GLPRT_PTC1023H_PTC1023H_SHIFT)
-#define I40E_GLPRT_PTC1023L(_i) (0x00300720 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1023H_PTC1023H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1023H_PTC1023H_SHIFT)
+#define I40E_GLPRT_PTC1023L(_i) (0x00300720 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1023L_MAX_INDEX 3
#define I40E_GLPRT_PTC1023L_PTC1023L_SHIFT 0
-#define I40E_GLPRT_PTC1023L_PTC1023L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC1023L_PTC1023L_SHIFT)
-#define I40E_GLPRT_PTC127H(_i) (0x003006C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1023L_PTC1023L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1023L_PTC1023L_SHIFT)
+#define I40E_GLPRT_PTC127H(_i) (0x003006C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC127H_MAX_INDEX 3
#define I40E_GLPRT_PTC127H_PTC127H_SHIFT 0
-#define I40E_GLPRT_PTC127H_PTC127H_MASK (0xFFFF << I40E_GLPRT_PTC127H_PTC127H_SHIFT)
-#define I40E_GLPRT_PTC127L(_i) (0x003006C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC127H_PTC127H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC127H_PTC127H_SHIFT)
+#define I40E_GLPRT_PTC127L(_i) (0x003006C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC127L_MAX_INDEX 3
#define I40E_GLPRT_PTC127L_PTC127L_SHIFT 0
-#define I40E_GLPRT_PTC127L_PTC127L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC127L_PTC127L_SHIFT)
-#define I40E_GLPRT_PTC1522H(_i) (0x00300744 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC127L_PTC127L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC127L_PTC127L_SHIFT)
+#define I40E_GLPRT_PTC1522H(_i) (0x00300744 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1522H_MAX_INDEX 3
#define I40E_GLPRT_PTC1522H_PTC1522H_SHIFT 0
-#define I40E_GLPRT_PTC1522H_PTC1522H_MASK (0xFFFF << I40E_GLPRT_PTC1522H_PTC1522H_SHIFT)
-#define I40E_GLPRT_PTC1522L(_i) (0x00300740 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1522H_PTC1522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC1522H_PTC1522H_SHIFT)
+#define I40E_GLPRT_PTC1522L(_i) (0x00300740 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC1522L_MAX_INDEX 3
#define I40E_GLPRT_PTC1522L_PTC1522L_SHIFT 0
-#define I40E_GLPRT_PTC1522L_PTC1522L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC1522L_PTC1522L_SHIFT)
-#define I40E_GLPRT_PTC255H(_i) (0x003006E4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC1522L_PTC1522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC1522L_PTC1522L_SHIFT)
+#define I40E_GLPRT_PTC255H(_i) (0x003006E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC255H_MAX_INDEX 3
#define I40E_GLPRT_PTC255H_PTC255H_SHIFT 0
-#define I40E_GLPRT_PTC255H_PTC255H_MASK (0xFFFF << I40E_GLPRT_PTC255H_PTC255H_SHIFT)
-#define I40E_GLPRT_PTC255L(_i) (0x003006E0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC255H_PTC255H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC255H_PTC255H_SHIFT)
+#define I40E_GLPRT_PTC255L(_i) (0x003006E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC255L_MAX_INDEX 3
#define I40E_GLPRT_PTC255L_PTC255L_SHIFT 0
-#define I40E_GLPRT_PTC255L_PTC255L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC255L_PTC255L_SHIFT)
-#define I40E_GLPRT_PTC511H(_i) (0x00300704 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC255L_PTC255L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC255L_PTC255L_SHIFT)
+#define I40E_GLPRT_PTC511H(_i) (0x00300704 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC511H_MAX_INDEX 3
#define I40E_GLPRT_PTC511H_PTC511H_SHIFT 0
-#define I40E_GLPRT_PTC511H_PTC511H_MASK (0xFFFF << I40E_GLPRT_PTC511H_PTC511H_SHIFT)
-#define I40E_GLPRT_PTC511L(_i) (0x00300700 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC511H_PTC511H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC511H_PTC511H_SHIFT)
+#define I40E_GLPRT_PTC511L(_i) (0x00300700 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC511L_MAX_INDEX 3
#define I40E_GLPRT_PTC511L_PTC511L_SHIFT 0
-#define I40E_GLPRT_PTC511L_PTC511L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC511L_PTC511L_SHIFT)
-#define I40E_GLPRT_PTC64H(_i) (0x003006A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC511L_PTC511L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC511L_PTC511L_SHIFT)
+#define I40E_GLPRT_PTC64H(_i) (0x003006A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC64H_MAX_INDEX 3
#define I40E_GLPRT_PTC64H_PTC64H_SHIFT 0
-#define I40E_GLPRT_PTC64H_PTC64H_MASK (0xFFFF << I40E_GLPRT_PTC64H_PTC64H_SHIFT)
-#define I40E_GLPRT_PTC64L(_i) (0x003006A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC64H_PTC64H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC64H_PTC64H_SHIFT)
+#define I40E_GLPRT_PTC64L(_i) (0x003006A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC64L_MAX_INDEX 3
#define I40E_GLPRT_PTC64L_PTC64L_SHIFT 0
-#define I40E_GLPRT_PTC64L_PTC64L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC64L_PTC64L_SHIFT)
-#define I40E_GLPRT_PTC9522H(_i) (0x00300764 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC64L_PTC64L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC64L_PTC64L_SHIFT)
+#define I40E_GLPRT_PTC9522H(_i) (0x00300764 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC9522H_MAX_INDEX 3
#define I40E_GLPRT_PTC9522H_PTC9522H_SHIFT 0
-#define I40E_GLPRT_PTC9522H_PTC9522H_MASK (0xFFFF << I40E_GLPRT_PTC9522H_PTC9522H_SHIFT)
-#define I40E_GLPRT_PTC9522L(_i) (0x00300760 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PTC9522H_PTC9522H_MASK I40E_MASK(0xFFFF, I40E_GLPRT_PTC9522H_PTC9522H_SHIFT)
+#define I40E_GLPRT_PTC9522L(_i) (0x00300760 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_PTC9522L_MAX_INDEX 3
#define I40E_GLPRT_PTC9522L_PTC9522L_SHIFT 0
-#define I40E_GLPRT_PTC9522L_PTC9522L_MASK (0xFFFFFFFF << I40E_GLPRT_PTC9522L_PTC9522L_SHIFT)
-#define I40E_GLPRT_PXOFFRXC(_i, _j) (0x00300280 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PTC9522L_PTC9522L_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PTC9522L_PTC9522L_SHIFT)
+#define I40E_GLPRT_PXOFFRXC(_i, _j) (0x00300280 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXOFFRXC_MAX_INDEX 3
#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT)
-#define I40E_GLPRT_PXOFFTXC(_i, _j) (0x00300880 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFRXC_PRPXOFFRXCNT_SHIFT)
+#define I40E_GLPRT_PXOFFTXC(_i, _j) (0x00300880 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXOFFTXC_MAX_INDEX 3
#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT 0
-#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT)
-#define I40E_GLPRT_PXONRXC(_i, _j) (0x00300180 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXOFFTXC_PRPXOFFTXCNT_SHIFT)
+#define I40E_GLPRT_PXONRXC(_i, _j) (0x00300180 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXONRXC_MAX_INDEX 3
#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT 0
-#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_MASK (0xFFFFFFFF << I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT)
-#define I40E_GLPRT_PXONTXC(_i, _j) (0x00300780 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_PXONRXC_PRPXONRXCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONRXC_PRPXONRXCNT_SHIFT)
+#define I40E_GLPRT_PXONTXC(_i, _j) (0x00300780 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_PXONTXC_MAX_INDEX 3
#define I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT 0
-#define I40E_GLPRT_PXONTXC_PRPXONTXC_MASK (0xFFFFFFFF << I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT)
-#define I40E_GLPRT_RDPC(_i) (0x00300600 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_PXONTXC_PRPXONTXC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_PXONTXC_PRPXONTXC_SHIFT)
+#define I40E_GLPRT_RDPC(_i) (0x00300600 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RDPC_MAX_INDEX 3
#define I40E_GLPRT_RDPC_RDPC_SHIFT 0
-#define I40E_GLPRT_RDPC_RDPC_MASK (0xFFFFFFFF << I40E_GLPRT_RDPC_RDPC_SHIFT)
-#define I40E_GLPRT_RFC(_i) (0x00300560 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RDPC_RDPC_SHIFT)
+#define I40E_GLPRT_RFC(_i) (0x00300560 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RFC_MAX_INDEX 3
#define I40E_GLPRT_RFC_RFC_SHIFT 0
-#define I40E_GLPRT_RFC_RFC_MASK (0xFFFFFFFF << I40E_GLPRT_RFC_RFC_SHIFT)
-#define I40E_GLPRT_RJC(_i) (0x00300580 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RFC_RFC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RFC_RFC_SHIFT)
+#define I40E_GLPRT_RJC(_i) (0x00300580 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RJC_MAX_INDEX 3
#define I40E_GLPRT_RJC_RJC_SHIFT 0
-#define I40E_GLPRT_RJC_RJC_MASK (0xFFFFFFFF << I40E_GLPRT_RJC_RJC_SHIFT)
-#define I40E_GLPRT_RLEC(_i) (0x003000A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RJC_RJC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RJC_RJC_SHIFT)
+#define I40E_GLPRT_RLEC(_i) (0x003000A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RLEC_MAX_INDEX 3
#define I40E_GLPRT_RLEC_RLEC_SHIFT 0
-#define I40E_GLPRT_RLEC_RLEC_MASK (0xFFFFFFFF << I40E_GLPRT_RLEC_RLEC_SHIFT)
-#define I40E_GLPRT_ROC(_i) (0x00300120 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RLEC_RLEC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RLEC_RLEC_SHIFT)
+#define I40E_GLPRT_ROC(_i) (0x00300120 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_ROC_MAX_INDEX 3
#define I40E_GLPRT_ROC_ROC_SHIFT 0
-#define I40E_GLPRT_ROC_ROC_MASK (0xFFFFFFFF << I40E_GLPRT_ROC_ROC_SHIFT)
-#define I40E_GLPRT_RUC(_i) (0x00300100 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_ROC_ROC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_ROC_ROC_SHIFT)
+#define I40E_GLPRT_RUC(_i) (0x00300100 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RUC_MAX_INDEX 3
#define I40E_GLPRT_RUC_RUC_SHIFT 0
-#define I40E_GLPRT_RUC_RUC_MASK (0xFFFFFFFF << I40E_GLPRT_RUC_RUC_SHIFT)
-#define I40E_GLPRT_RUPP(_i) (0x00300660 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RUC_RUC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUC_RUC_SHIFT)
+#define I40E_GLPRT_RUPP(_i) (0x00300660 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_RUPP_MAX_INDEX 3
#define I40E_GLPRT_RUPP_RUPP_SHIFT 0
-#define I40E_GLPRT_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLPRT_RUPP_RUPP_SHIFT)
-#define I40E_GLPRT_RXON2OFFCNT(_i, _j) (0x00300380 + ((_i) * 8 + (_j) * 32))
+#define I40E_GLPRT_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RUPP_RUPP_SHIFT)
+#define I40E_GLPRT_RXON2OFFCNT(_i, _j) (0x00300380 + ((_i) * 8 + (_j) * 32)) /* _i=0...3, _j=0...7 */ /* Reset: CORER */
#define I40E_GLPRT_RXON2OFFCNT_MAX_INDEX 3
#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT 0
-#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_MASK (0xFFFFFFFF << I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT)
-#define I40E_GLPRT_STDC(_i) (0x00300640 + ((_i) * 8)) /* _i=0...3 */
-#define I40E_GLPRT_STDC_MAX_INDEX 3
-#define I40E_GLPRT_STDC_STDC_SHIFT 0
-#define I40E_GLPRT_STDC_STDC_MASK (0xFFFFFFFF << I40E_GLPRT_STDC_STDC_SHIFT)
-#define I40E_GLPRT_TDOLD(_i) (0x00300A20 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_RXON2OFFCNT_PRRXON2OFFCNT_SHIFT)
+#define I40E_GLPRT_TDOLD(_i) (0x00300A20 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_TDOLD_MAX_INDEX 3
#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT 0
-#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_MASK (0xFFFFFFFF << I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT)
-#define I40E_GLPRT_TDPC(_i) (0x00375400 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_TDOLD_GLPRT_TDOLD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_TDOLD_GLPRT_TDOLD_SHIFT)
+#define I40E_GLPRT_TDPC(_i) (0x00375400 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_TDPC_MAX_INDEX 3
#define I40E_GLPRT_TDPC_TDPC_SHIFT 0
-#define I40E_GLPRT_TDPC_TDPC_MASK (0xFFFFFFFF << I40E_GLPRT_TDPC_TDPC_SHIFT)
-#define I40E_GLPRT_UPRCH(_i) (0x003005A4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_TDPC_TDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_TDPC_TDPC_SHIFT)
+#define I40E_GLPRT_UPRCH(_i) (0x003005A4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPRCH_MAX_INDEX 3
#define I40E_GLPRT_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLPRT_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLPRT_UPRCH_UPRCH_SHIFT)
-#define I40E_GLPRT_UPRCL(_i) (0x003005A0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPRCH_UPRCH_SHIFT)
+#define I40E_GLPRT_UPRCL(_i) (0x003005A0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPRCL_MAX_INDEX 3
#define I40E_GLPRT_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLPRT_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLPRT_UPRCL_UPRCL_SHIFT)
-#define I40E_GLPRT_UPTCH(_i) (0x003009C4 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPRCL_UPRCL_SHIFT)
+#define I40E_GLPRT_UPTCH(_i) (0x003009C4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPTCH_MAX_INDEX 3
#define I40E_GLPRT_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCH_UPTCH_MASK (0xFFFF << I40E_GLPRT_UPTCH_UPTCH_SHIFT)
-#define I40E_GLPRT_UPTCL(_i) (0x003009C0 + ((_i) * 8)) /* _i=0...3 */
+#define I40E_GLPRT_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLPRT_UPTCH_UPTCH_SHIFT)
+#define I40E_GLPRT_UPTCL(_i) (0x003009C0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_GLPRT_UPTCL_MAX_INDEX 3
#define I40E_GLPRT_UPTCL_VUPTCH_SHIFT 0
-#define I40E_GLPRT_UPTCL_VUPTCH_MASK (0xFFFFFFFF << I40E_GLPRT_UPTCL_VUPTCH_SHIFT)
-#define I40E_GLSW_BPRCH(_i) (0x00370104 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLPRT_UPTCL_VUPTCH_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPRT_UPTCL_VUPTCH_SHIFT)
+#define I40E_GLSW_BPRCH(_i) (0x00370104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPRCH_MAX_INDEX 15
#define I40E_GLSW_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLSW_BPRCH_BPRCH_MASK (0xFFFF << I40E_GLSW_BPRCH_BPRCH_SHIFT)
-#define I40E_GLSW_BPRCL(_i) (0x00370100 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPRCH_BPRCH_SHIFT)
+#define I40E_GLSW_BPRCL(_i) (0x00370100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPRCL_MAX_INDEX 15
#define I40E_GLSW_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLSW_BPRCL_BPRCL_MASK (0xFFFFFFFF << I40E_GLSW_BPRCL_BPRCL_SHIFT)
-#define I40E_GLSW_BPTCH(_i) (0x00340104 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPRCL_BPRCL_SHIFT)
+#define I40E_GLSW_BPTCH(_i) (0x00340104 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPTCH_MAX_INDEX 15
#define I40E_GLSW_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLSW_BPTCH_BPTCH_MASK (0xFFFF << I40E_GLSW_BPTCH_BPTCH_SHIFT)
-#define I40E_GLSW_BPTCL(_i) (0x00340100 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_BPTCH_BPTCH_SHIFT)
+#define I40E_GLSW_BPTCL(_i) (0x00340100 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_BPTCL_MAX_INDEX 15
#define I40E_GLSW_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLSW_BPTCL_BPTCL_MASK (0xFFFFFFFF << I40E_GLSW_BPTCL_BPTCL_SHIFT)
-#define I40E_GLSW_GORCH(_i) (0x0035C004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_BPTCL_BPTCL_SHIFT)
+#define I40E_GLSW_GORCH(_i) (0x0035C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GORCH_MAX_INDEX 15
#define I40E_GLSW_GORCH_GORCH_SHIFT 0
-#define I40E_GLSW_GORCH_GORCH_MASK (0xFFFF << I40E_GLSW_GORCH_GORCH_SHIFT)
-#define I40E_GLSW_GORCL(_i) (0x0035c000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GORCH_GORCH_SHIFT)
+#define I40E_GLSW_GORCL(_i) (0x0035c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GORCL_MAX_INDEX 15
#define I40E_GLSW_GORCL_GORCL_SHIFT 0
-#define I40E_GLSW_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLSW_GORCL_GORCL_SHIFT)
-#define I40E_GLSW_GOTCH(_i) (0x0032C004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GORCL_GORCL_SHIFT)
+#define I40E_GLSW_GOTCH(_i) (0x0032C004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GOTCH_MAX_INDEX 15
#define I40E_GLSW_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLSW_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLSW_GOTCH_GOTCH_SHIFT)
-#define I40E_GLSW_GOTCL(_i) (0x0032c000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_GOTCH_GOTCH_SHIFT)
+#define I40E_GLSW_GOTCL(_i) (0x0032c000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_GOTCL_MAX_INDEX 15
#define I40E_GLSW_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLSW_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLSW_GOTCL_GOTCL_SHIFT)
-#define I40E_GLSW_MPRCH(_i) (0x00370084 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_GOTCL_GOTCL_SHIFT)
+#define I40E_GLSW_MPRCH(_i) (0x00370084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPRCH_MAX_INDEX 15
#define I40E_GLSW_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLSW_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLSW_MPRCH_MPRCH_SHIFT)
-#define I40E_GLSW_MPRCL(_i) (0x00370080 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPRCH_MPRCH_SHIFT)
+#define I40E_GLSW_MPRCL(_i) (0x00370080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPRCL_MAX_INDEX 15
#define I40E_GLSW_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLSW_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLSW_MPRCL_MPRCL_SHIFT)
-#define I40E_GLSW_MPTCH(_i) (0x00340084 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPRCL_MPRCL_SHIFT)
+#define I40E_GLSW_MPTCH(_i) (0x00340084 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPTCH_MAX_INDEX 15
#define I40E_GLSW_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLSW_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLSW_MPTCH_MPTCH_SHIFT)
-#define I40E_GLSW_MPTCL(_i) (0x00340080 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_MPTCH_MPTCH_SHIFT)
+#define I40E_GLSW_MPTCL(_i) (0x00340080 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_MPTCL_MAX_INDEX 15
#define I40E_GLSW_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLSW_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLSW_MPTCL_MPTCL_SHIFT)
-#define I40E_GLSW_RUPP(_i) (0x00370180 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_MPTCL_MPTCL_SHIFT)
+#define I40E_GLSW_RUPP(_i) (0x00370180 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_RUPP_MAX_INDEX 15
#define I40E_GLSW_RUPP_RUPP_SHIFT 0
-#define I40E_GLSW_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLSW_RUPP_RUPP_SHIFT)
-#define I40E_GLSW_TDPC(_i) (0x00348000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_RUPP_RUPP_SHIFT)
+#define I40E_GLSW_TDPC(_i) (0x00348000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_TDPC_MAX_INDEX 15
#define I40E_GLSW_TDPC_TDPC_SHIFT 0
-#define I40E_GLSW_TDPC_TDPC_MASK (0xFFFFFFFF << I40E_GLSW_TDPC_TDPC_SHIFT)
-#define I40E_GLSW_UPRCH(_i) (0x00370004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_TDPC_TDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_TDPC_TDPC_SHIFT)
+#define I40E_GLSW_UPRCH(_i) (0x00370004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPRCH_MAX_INDEX 15
#define I40E_GLSW_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLSW_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLSW_UPRCH_UPRCH_SHIFT)
-#define I40E_GLSW_UPRCL(_i) (0x00370000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPRCH_UPRCH_SHIFT)
+#define I40E_GLSW_UPRCL(_i) (0x00370000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPRCL_MAX_INDEX 15
#define I40E_GLSW_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLSW_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLSW_UPRCL_UPRCL_SHIFT)
-#define I40E_GLSW_UPTCH(_i) (0x00340004 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPRCL_UPRCL_SHIFT)
+#define I40E_GLSW_UPTCH(_i) (0x00340004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPTCH_MAX_INDEX 15
#define I40E_GLSW_UPTCH_UPTCH_SHIFT 0
-#define I40E_GLSW_UPTCH_UPTCH_MASK (0xFFFF << I40E_GLSW_UPTCH_UPTCH_SHIFT)
-#define I40E_GLSW_UPTCL(_i) (0x00340000 + ((_i) * 8)) /* _i=0...15 */
+#define I40E_GLSW_UPTCH_UPTCH_MASK I40E_MASK(0xFFFF, I40E_GLSW_UPTCH_UPTCH_SHIFT)
+#define I40E_GLSW_UPTCL(_i) (0x00340000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_GLSW_UPTCL_MAX_INDEX 15
#define I40E_GLSW_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLSW_UPTCL_UPTCL_MASK (0xFFFFFFFF << I40E_GLSW_UPTCL_UPTCL_SHIFT)
-#define I40E_GLV_BPRCH(_i) (0x0036D804 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLSW_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLSW_UPTCL_UPTCL_SHIFT)
+#define I40E_GLV_BPRCH(_i) (0x0036D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPRCH_MAX_INDEX 383
#define I40E_GLV_BPRCH_BPRCH_SHIFT 0
-#define I40E_GLV_BPRCH_BPRCH_MASK (0xFFFF << I40E_GLV_BPRCH_BPRCH_SHIFT)
-#define I40E_GLV_BPRCL(_i) (0x0036d800 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPRCH_BPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPRCH_BPRCH_SHIFT)
+#define I40E_GLV_BPRCL(_i) (0x0036d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPRCL_MAX_INDEX 383
#define I40E_GLV_BPRCL_BPRCL_SHIFT 0
-#define I40E_GLV_BPRCL_BPRCL_MASK (0xFFFFFFFF << I40E_GLV_BPRCL_BPRCL_SHIFT)
-#define I40E_GLV_BPTCH(_i) (0x0033D804 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPRCL_BPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPRCL_BPRCL_SHIFT)
+#define I40E_GLV_BPTCH(_i) (0x0033D804 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPTCH_MAX_INDEX 383
#define I40E_GLV_BPTCH_BPTCH_SHIFT 0
-#define I40E_GLV_BPTCH_BPTCH_MASK (0xFFFF << I40E_GLV_BPTCH_BPTCH_SHIFT)
-#define I40E_GLV_BPTCL(_i) (0x0033d800 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPTCH_BPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_BPTCH_BPTCH_SHIFT)
+#define I40E_GLV_BPTCL(_i) (0x0033d800 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_BPTCL_MAX_INDEX 383
#define I40E_GLV_BPTCL_BPTCL_SHIFT 0
-#define I40E_GLV_BPTCL_BPTCL_MASK (0xFFFFFFFF << I40E_GLV_BPTCL_BPTCL_SHIFT)
-#define I40E_GLV_GORCH(_i) (0x00358004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_BPTCL_BPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_BPTCL_BPTCL_SHIFT)
+#define I40E_GLV_GORCH(_i) (0x00358004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GORCH_MAX_INDEX 383
#define I40E_GLV_GORCH_GORCH_SHIFT 0
-#define I40E_GLV_GORCH_GORCH_MASK (0xFFFF << I40E_GLV_GORCH_GORCH_SHIFT)
-#define I40E_GLV_GORCL(_i) (0x00358000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GORCH_GORCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GORCH_GORCH_SHIFT)
+#define I40E_GLV_GORCL(_i) (0x00358000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GORCL_MAX_INDEX 383
#define I40E_GLV_GORCL_GORCL_SHIFT 0
-#define I40E_GLV_GORCL_GORCL_MASK (0xFFFFFFFF << I40E_GLV_GORCL_GORCL_SHIFT)
-#define I40E_GLV_GOTCH(_i) (0x00328004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GORCL_GORCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GORCL_GORCL_SHIFT)
+#define I40E_GLV_GOTCH(_i) (0x00328004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GOTCH_MAX_INDEX 383
#define I40E_GLV_GOTCH_GOTCH_SHIFT 0
-#define I40E_GLV_GOTCH_GOTCH_MASK (0xFFFF << I40E_GLV_GOTCH_GOTCH_SHIFT)
-#define I40E_GLV_GOTCL(_i) (0x00328000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GOTCH_GOTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_GOTCH_GOTCH_SHIFT)
+#define I40E_GLV_GOTCL(_i) (0x00328000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_GOTCL_MAX_INDEX 383
#define I40E_GLV_GOTCL_GOTCL_SHIFT 0
-#define I40E_GLV_GOTCL_GOTCL_MASK (0xFFFFFFFF << I40E_GLV_GOTCL_GOTCL_SHIFT)
-#define I40E_GLV_MPRCH(_i) (0x0036CC04 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_GOTCL_GOTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_GOTCL_GOTCL_SHIFT)
+#define I40E_GLV_MPRCH(_i) (0x0036CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPRCH_MAX_INDEX 383
#define I40E_GLV_MPRCH_MPRCH_SHIFT 0
-#define I40E_GLV_MPRCH_MPRCH_MASK (0xFFFF << I40E_GLV_MPRCH_MPRCH_SHIFT)
-#define I40E_GLV_MPRCL(_i) (0x0036cc00 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPRCH_MPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPRCH_MPRCH_SHIFT)
+#define I40E_GLV_MPRCL(_i) (0x0036cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPRCL_MAX_INDEX 383
#define I40E_GLV_MPRCL_MPRCL_SHIFT 0
-#define I40E_GLV_MPRCL_MPRCL_MASK (0xFFFFFFFF << I40E_GLV_MPRCL_MPRCL_SHIFT)
-#define I40E_GLV_MPTCH(_i) (0x0033CC04 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPRCL_MPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPRCL_MPRCL_SHIFT)
+#define I40E_GLV_MPTCH(_i) (0x0033CC04 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPTCH_MAX_INDEX 383
#define I40E_GLV_MPTCH_MPTCH_SHIFT 0
-#define I40E_GLV_MPTCH_MPTCH_MASK (0xFFFF << I40E_GLV_MPTCH_MPTCH_SHIFT)
-#define I40E_GLV_MPTCL(_i) (0x0033cc00 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPTCH_MPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_MPTCH_MPTCH_SHIFT)
+#define I40E_GLV_MPTCL(_i) (0x0033cc00 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_MPTCL_MAX_INDEX 383
#define I40E_GLV_MPTCL_MPTCL_SHIFT 0
-#define I40E_GLV_MPTCL_MPTCL_MASK (0xFFFFFFFF << I40E_GLV_MPTCL_MPTCL_SHIFT)
-#define I40E_GLV_RDPC(_i) (0x00310000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_MPTCL_MPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_MPTCL_MPTCL_SHIFT)
+#define I40E_GLV_RDPC(_i) (0x00310000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_RDPC_MAX_INDEX 383
#define I40E_GLV_RDPC_RDPC_SHIFT 0
-#define I40E_GLV_RDPC_RDPC_MASK (0xFFFFFFFF << I40E_GLV_RDPC_RDPC_SHIFT)
-#define I40E_GLV_RUPP(_i) (0x0036E400 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_RDPC_RDPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RDPC_RDPC_SHIFT)
+#define I40E_GLV_RUPP(_i) (0x0036E400 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_RUPP_MAX_INDEX 383
#define I40E_GLV_RUPP_RUPP_SHIFT 0
-#define I40E_GLV_RUPP_RUPP_MASK (0xFFFFFFFF << I40E_GLV_RUPP_RUPP_SHIFT)
-#define I40E_GLV_TEPC(_VSI) (0x00344000 + ((_VSI) * 8)) /* _i=0...383 */
+#define I40E_GLV_RUPP_RUPP_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_RUPP_RUPP_SHIFT)
+#define I40E_GLV_TEPC(_VSI) (0x00344000 + ((_VSI) * 4)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_TEPC_MAX_INDEX 383
#define I40E_GLV_TEPC_TEPC_SHIFT 0
-#define I40E_GLV_TEPC_TEPC_MASK (0xFFFFFFFF << I40E_GLV_TEPC_TEPC_SHIFT)
-#define I40E_GLV_UPRCH(_i) (0x0036C004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_TEPC_TEPC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_TEPC_TEPC_SHIFT)
+#define I40E_GLV_UPRCH(_i) (0x0036C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPRCH_MAX_INDEX 383
#define I40E_GLV_UPRCH_UPRCH_SHIFT 0
-#define I40E_GLV_UPRCH_UPRCH_MASK (0xFFFF << I40E_GLV_UPRCH_UPRCH_SHIFT)
-#define I40E_GLV_UPRCL(_i) (0x0036c000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPRCH_UPRCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPRCH_UPRCH_SHIFT)
+#define I40E_GLV_UPRCL(_i) (0x0036c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPRCL_MAX_INDEX 383
#define I40E_GLV_UPRCL_UPRCL_SHIFT 0
-#define I40E_GLV_UPRCL_UPRCL_MASK (0xFFFFFFFF << I40E_GLV_UPRCL_UPRCL_SHIFT)
-#define I40E_GLV_UPTCH(_i) (0x0033C004 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPRCL_UPRCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPRCL_UPRCL_SHIFT)
+#define I40E_GLV_UPTCH(_i) (0x0033C004 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPTCH_MAX_INDEX 383
#define I40E_GLV_UPTCH_GLVUPTCH_SHIFT 0
-#define I40E_GLV_UPTCH_GLVUPTCH_MASK (0xFFFF << I40E_GLV_UPTCH_GLVUPTCH_SHIFT)
-#define I40E_GLV_UPTCL(_i) (0x0033c000 + ((_i) * 8)) /* _i=0...383 */
+#define I40E_GLV_UPTCH_GLVUPTCH_MASK I40E_MASK(0xFFFF, I40E_GLV_UPTCH_GLVUPTCH_SHIFT)
+#define I40E_GLV_UPTCL(_i) (0x0033c000 + ((_i) * 8)) /* _i=0...383 */ /* Reset: CORER */
#define I40E_GLV_UPTCL_MAX_INDEX 383
#define I40E_GLV_UPTCL_UPTCL_SHIFT 0
-#define I40E_GLV_UPTCL_UPTCL_MASK (0xFFFFFFFF << I40E_GLV_UPTCL_UPTCL_SHIFT)
-#define I40E_GLVEBTC_RBCH(_i, _j) (0x00364004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLV_UPTCL_UPTCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLV_UPTCL_UPTCL_SHIFT)
+#define I40E_GLVEBTC_RBCH(_i, _j) (0x00364004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RBCH_MAX_INDEX 7
#define I40E_GLVEBTC_RBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_RBCH_TCBCH_MASK (0xFFFF << I40E_GLVEBTC_RBCH_TCBCH_SHIFT)
-#define I40E_GLVEBTC_RBCL(_i, _j) (0x00364000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RBCH_TCBCH_SHIFT)
+#define I40E_GLVEBTC_RBCL(_i, _j) (0x00364000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RBCL_MAX_INDEX 7
#define I40E_GLVEBTC_RBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_RBCL_TCBCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_RBCL_TCBCL_SHIFT)
-#define I40E_GLVEBTC_RPCH(_i, _j) (0x00368004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RBCL_TCBCL_SHIFT)
+#define I40E_GLVEBTC_RPCH(_i, _j) (0x00368004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RPCH_MAX_INDEX 7
#define I40E_GLVEBTC_RPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_RPCH_TCPCH_MASK (0xFFFF << I40E_GLVEBTC_RPCH_TCPCH_SHIFT)
-#define I40E_GLVEBTC_RPCL(_i, _j) (0x00368000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_RPCH_TCPCH_SHIFT)
+#define I40E_GLVEBTC_RPCL(_i, _j) (0x00368000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_RPCL_MAX_INDEX 7
#define I40E_GLVEBTC_RPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_RPCL_TCPCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_RPCL_TCPCL_SHIFT)
-#define I40E_GLVEBTC_TBCH(_i, _j) (0x00334004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_RPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_RPCL_TCPCL_SHIFT)
+#define I40E_GLVEBTC_TBCH(_i, _j) (0x00334004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TBCH_MAX_INDEX 7
#define I40E_GLVEBTC_TBCH_TCBCH_SHIFT 0
-#define I40E_GLVEBTC_TBCH_TCBCH_MASK (0xFFFF << I40E_GLVEBTC_TBCH_TCBCH_SHIFT)
-#define I40E_GLVEBTC_TBCL(_i, _j) (0x00334000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TBCH_TCBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TBCH_TCBCH_SHIFT)
+#define I40E_GLVEBTC_TBCL(_i, _j) (0x00334000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TBCL_MAX_INDEX 7
#define I40E_GLVEBTC_TBCL_TCBCL_SHIFT 0
-#define I40E_GLVEBTC_TBCL_TCBCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_TBCL_TCBCL_SHIFT)
-#define I40E_GLVEBTC_TPCH(_i, _j) (0x00338004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TBCL_TCBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TBCL_TCBCL_SHIFT)
+#define I40E_GLVEBTC_TPCH(_i, _j) (0x00338004 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TPCH_MAX_INDEX 7
#define I40E_GLVEBTC_TPCH_TCPCH_SHIFT 0
-#define I40E_GLVEBTC_TPCH_TCPCH_MASK (0xFFFF << I40E_GLVEBTC_TPCH_TCPCH_SHIFT)
-#define I40E_GLVEBTC_TPCL(_i, _j) (0x00338000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */
+#define I40E_GLVEBTC_TPCH_TCPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBTC_TPCH_TCPCH_SHIFT)
+#define I40E_GLVEBTC_TPCL(_i, _j) (0x00338000 + ((_i) * 8 + (_j) * 64)) /* _i=0...7, _j=0...15 */ /* Reset: CORER */
#define I40E_GLVEBTC_TPCL_MAX_INDEX 7
#define I40E_GLVEBTC_TPCL_TCPCL_SHIFT 0
-#define I40E_GLVEBTC_TPCL_TCPCL_MASK (0xFFFFFFFF << I40E_GLVEBTC_TPCL_TCPCL_SHIFT)
-#define I40E_GLVEBVL_BPCH(_i) (0x00374804 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBTC_TPCL_TCPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBTC_TPCL_TCPCL_SHIFT)
+#define I40E_GLVEBVL_BPCH(_i) (0x00374804 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_BPCH_MAX_INDEX 127
#define I40E_GLVEBVL_BPCH_VLBPCH_SHIFT 0
-#define I40E_GLVEBVL_BPCH_VLBPCH_MASK (0xFFFF << I40E_GLVEBVL_BPCH_VLBPCH_SHIFT)
-#define I40E_GLVEBVL_BPCL(_i) (0x00374800 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_BPCH_VLBPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_BPCH_VLBPCH_SHIFT)
+#define I40E_GLVEBVL_BPCL(_i) (0x00374800 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_BPCL_MAX_INDEX 127
#define I40E_GLVEBVL_BPCL_VLBPCL_SHIFT 0
-#define I40E_GLVEBVL_BPCL_VLBPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_BPCL_VLBPCL_SHIFT)
-#define I40E_GLVEBVL_GORCH(_i) (0x00360004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_BPCL_VLBPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_BPCL_VLBPCL_SHIFT)
+#define I40E_GLVEBVL_GORCH(_i) (0x00360004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GORCH_MAX_INDEX 127
#define I40E_GLVEBVL_GORCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GORCH_VLBCH_MASK (0xFFFF << I40E_GLVEBVL_GORCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GORCL(_i) (0x00360000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GORCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GORCH_VLBCH_SHIFT)
+#define I40E_GLVEBVL_GORCL(_i) (0x00360000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GORCL_MAX_INDEX 127
#define I40E_GLVEBVL_GORCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GORCL_VLBCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_GORCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_GOTCH(_i) (0x00330004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GORCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GORCL_VLBCL_SHIFT)
+#define I40E_GLVEBVL_GOTCH(_i) (0x00330004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GOTCH_MAX_INDEX 127
#define I40E_GLVEBVL_GOTCH_VLBCH_SHIFT 0
-#define I40E_GLVEBVL_GOTCH_VLBCH_MASK (0xFFFF << I40E_GLVEBVL_GOTCH_VLBCH_SHIFT)
-#define I40E_GLVEBVL_GOTCL(_i) (0x00330000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GOTCH_VLBCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_GOTCH_VLBCH_SHIFT)
+#define I40E_GLVEBVL_GOTCL(_i) (0x00330000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_GOTCL_MAX_INDEX 127
#define I40E_GLVEBVL_GOTCL_VLBCL_SHIFT 0
-#define I40E_GLVEBVL_GOTCL_VLBCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_GOTCL_VLBCL_SHIFT)
-#define I40E_GLVEBVL_MPCH(_i) (0x00374404 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_GOTCL_VLBCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_GOTCL_VLBCL_SHIFT)
+#define I40E_GLVEBVL_MPCH(_i) (0x00374404 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_MPCH_MAX_INDEX 127
#define I40E_GLVEBVL_MPCH_VLMPCH_SHIFT 0
-#define I40E_GLVEBVL_MPCH_VLMPCH_MASK (0xFFFF << I40E_GLVEBVL_MPCH_VLMPCH_SHIFT)
-#define I40E_GLVEBVL_MPCL(_i) (0x00374400 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_MPCH_VLMPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_MPCH_VLMPCH_SHIFT)
+#define I40E_GLVEBVL_MPCL(_i) (0x00374400 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_MPCL_MAX_INDEX 127
#define I40E_GLVEBVL_MPCL_VLMPCL_SHIFT 0
-#define I40E_GLVEBVL_MPCL_VLMPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_MPCL_VLMPCL_SHIFT)
-#define I40E_GLVEBVL_UPCH(_i) (0x00374004 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_MPCL_VLMPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_MPCL_VLMPCL_SHIFT)
+#define I40E_GLVEBVL_UPCH(_i) (0x00374004 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_UPCH_MAX_INDEX 127
#define I40E_GLVEBVL_UPCH_VLUPCH_SHIFT 0
-#define I40E_GLVEBVL_UPCH_VLUPCH_MASK (0xFFFF << I40E_GLVEBVL_UPCH_VLUPCH_SHIFT)
-#define I40E_GLVEBVL_UPCL(_i) (0x00374000 + ((_i) * 8)) /* _i=0...127 */
+#define I40E_GLVEBVL_UPCH_VLUPCH_MASK I40E_MASK(0xFFFF, I40E_GLVEBVL_UPCH_VLUPCH_SHIFT)
+#define I40E_GLVEBVL_UPCL(_i) (0x00374000 + ((_i) * 8)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_GLVEBVL_UPCL_MAX_INDEX 127
#define I40E_GLVEBVL_UPCL_VLUPCL_SHIFT 0
-#define I40E_GLVEBVL_UPCL_VLUPCL_MASK (0xFFFFFFFF << I40E_GLVEBVL_UPCL_VLUPCL_SHIFT)
-#define I40E_GL_MTG_FLU_MSK_H 0x00269F4C
+#define I40E_GLVEBVL_UPCL_VLUPCL_MASK I40E_MASK(0xFFFFFFFF, I40E_GLVEBVL_UPCL_VLUPCL_SHIFT)
+#define I40E_GL_MTG_FLU_MSK_H 0x00269F4C /* Reset: CORER */
#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT 0
-#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_MASK (0xFFFF << I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT)
-#define I40E_GL_MTG_FLU_MSK_L 0x00269F44
-#define I40E_GL_MTG_FLU_MSK_L_MASK_LOW_SHIFT 0
-#define I40E_GL_MTG_FLU_MSK_L_MASK_LOW_MASK (0xFFFFFFFF << I40E_GL_MTG_FLU_MSK_L_MASK_LOW_SHIFT)
-#define I40E_GL_SWR_DEF_ACT(_i) (0x0026CF00 + ((_i) * 4)) /* _i=0...25 */
-#define I40E_GL_SWR_DEF_ACT_MAX_INDEX 25
+#define I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_MASK I40E_MASK(0xFFFF, I40E_GL_MTG_FLU_MSK_H_MASK_HIGH_SHIFT)
+#define I40E_GL_SWR_DEF_ACT(_i) (0x00270200 + ((_i) * 4)) /* _i=0...35 */ /* Reset: CORER */
+#define I40E_GL_SWR_DEF_ACT_MAX_INDEX 35
#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_MASK (0xFFFFFFFF << I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT)
-#define I40E_GL_SWR_DEF_ACT_EN 0x0026CF84
+#define I40E_GL_SWR_DEF_ACT_DEF_ACTION_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_DEF_ACTION_SHIFT)
+#define I40E_GL_SWR_DEF_ACT_EN(_i) (0x0026CFB8 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
+#define I40E_GL_SWR_DEF_ACT_EN_MAX_INDEX 1
#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT 0
-#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_MASK (0xFFFFFFFF << I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT)
-#define I40E_PRT_MSCCNT 0x00256BA0
-#define I40E_PRT_MSCCNT_CCOUNT_SHIFT 0
-#define I40E_PRT_MSCCNT_CCOUNT_MASK (0x1FFFFFF << I40E_PRT_MSCCNT_CCOUNT_SHIFT)
-#define I40E_PRT_SCSTS 0x00256C20
-#define I40E_PRT_SCSTS_BSCA_SHIFT 0
-#define I40E_PRT_SCSTS_BSCA_MASK (0x1 << I40E_PRT_SCSTS_BSCA_SHIFT)
-#define I40E_PRT_SCSTS_BSCAP_SHIFT 1
-#define I40E_PRT_SCSTS_BSCAP_MASK (0x1 << I40E_PRT_SCSTS_BSCAP_SHIFT)
-#define I40E_PRT_SCSTS_MSCA_SHIFT 2
-#define I40E_PRT_SCSTS_MSCA_MASK (0x1 << I40E_PRT_SCSTS_MSCA_SHIFT)
-#define I40E_PRT_SCSTS_MSCAP_SHIFT 3
-#define I40E_PRT_SCSTS_MSCAP_MASK (0x1 << I40E_PRT_SCSTS_MSCAP_SHIFT)
-#define I40E_PRT_SWT_BSCCNT 0x00256C60
-#define I40E_PRT_SWT_BSCCNT_CCOUNT_SHIFT 0
-#define I40E_PRT_SWT_BSCCNT_CCOUNT_MASK (0x1FFFFFF << I40E_PRT_SWT_BSCCNT_CCOUNT_SHIFT)
-#define I40E_PRTTSYN_ADJ 0x001E4280
+#define I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_SWR_DEF_ACT_EN_DEF_ACT_EN_BITMAP_SHIFT)
+#define I40E_PRTTSYN_ADJ 0x001E4280 /* Reset: GLOBR */
#define I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT 0
-#define I40E_PRTTSYN_ADJ_TSYNADJ_MASK (0x7FFFFFFF << I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT)
+#define I40E_PRTTSYN_ADJ_TSYNADJ_MASK I40E_MASK(0x7FFFFFFF, I40E_PRTTSYN_ADJ_TSYNADJ_SHIFT)
#define I40E_PRTTSYN_ADJ_SIGN_SHIFT 31
-#define I40E_PRTTSYN_ADJ_SIGN_MASK (0x1 << I40E_PRTTSYN_ADJ_SIGN_SHIFT)
-#define I40E_PRTTSYN_AUX_0(_i) (0x001E42A0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_ADJ_SIGN_MASK I40E_MASK(0x1, I40E_PRTTSYN_ADJ_SIGN_SHIFT)
+#define I40E_PRTTSYN_AUX_0(_i) (0x001E42A0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_AUX_0_MAX_INDEX 1
#define I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT 0
-#define I40E_PRTTSYN_AUX_0_OUT_ENA_MASK (0x1 << I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUT_ENA_SHIFT)
#define I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT 1
-#define I40E_PRTTSYN_AUX_0_OUTMOD_MASK (0x3 << I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUTMOD_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_OUTMOD_SHIFT)
#define I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT 3
-#define I40E_PRTTSYN_AUX_0_OUTLVL_MASK (0x1 << I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT)
+#define I40E_PRTTSYN_AUX_0_OUTLVL_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_OUTLVL_SHIFT)
#define I40E_PRTTSYN_AUX_0_PULSEW_SHIFT 8
-#define I40E_PRTTSYN_AUX_0_PULSEW_MASK (0xF << I40E_PRTTSYN_AUX_0_PULSEW_SHIFT)
+#define I40E_PRTTSYN_AUX_0_PULSEW_MASK I40E_MASK(0xF, I40E_PRTTSYN_AUX_0_PULSEW_SHIFT)
#define I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT 16
-#define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK (0x3 << I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT)
-#define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT)
+#define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_AUX_1_MAX_INDEX 1
#define I40E_PRTTSYN_AUX_1_INSTNT_SHIFT 0
-#define I40E_PRTTSYN_AUX_1_INSTNT_MASK (0x1 << I40E_PRTTSYN_AUX_1_INSTNT_SHIFT)
+#define I40E_PRTTSYN_AUX_1_INSTNT_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_INSTNT_SHIFT)
#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT 1
-#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_MASK (0x1 << I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT)
-#define I40E_PRTTSYN_CLKO(_i) (0x001E4240 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_AUX_1_SAMPLE_TIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_AUX_1_SAMPLE_TIME_SHIFT)
+#define I40E_PRTTSYN_CLKO(_i) (0x001E4240 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_CLKO_MAX_INDEX 1
#define I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT 0
-#define I40E_PRTTSYN_CLKO_TSYNCLKO_MASK (0xFFFFFFFF << I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT)
-#define I40E_PRTTSYN_CTL0 0x001E4200
+#define I40E_PRTTSYN_CLKO_TSYNCLKO_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_CLKO_TSYNCLKO_SHIFT)
+#define I40E_PRTTSYN_CTL0 0x001E4200 /* Reset: GLOBR */
#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT 0
-#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_MASK (0x1 << I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT)
+#define I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_CLEAR_TSYNTIMER_SHIFT)
#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT 1
-#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TXTIME_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT 2
-#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_EVENT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_EVENT_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT 3
-#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL0_TGT_INT_ENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TGT_INT_ENA_SHIFT)
#define I40E_PRTTSYN_CTL0_PF_ID_SHIFT 8
-#define I40E_PRTTSYN_CTL0_PF_ID_MASK (0xF << I40E_PRTTSYN_CTL0_PF_ID_SHIFT)
+#define I40E_PRTTSYN_CTL0_PF_ID_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL0_PF_ID_SHIFT)
#define I40E_PRTTSYN_CTL0_TSYNACT_SHIFT 12
-#define I40E_PRTTSYN_CTL0_TSYNACT_MASK (0x3 << I40E_PRTTSYN_CTL0_TSYNACT_SHIFT)
+#define I40E_PRTTSYN_CTL0_TSYNACT_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL0_TSYNACT_SHIFT)
#define I40E_PRTTSYN_CTL0_TSYNENA_SHIFT 31
-#define I40E_PRTTSYN_CTL0_TSYNENA_MASK (0x1 << I40E_PRTTSYN_CTL0_TSYNENA_SHIFT)
-#define I40E_PRTTSYN_CTL1 0x00085020
+#define I40E_PRTTSYN_CTL0_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL0_TSYNENA_SHIFT)
+#define I40E_PRTTSYN_CTL1 0x00085020 /* Reset: CORER */
#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT 0
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK (0xFF << I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT)
+#define I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE0_SHIFT)
#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT 8
-#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK (0xFF << I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT)
+#define I40E_PRTTSYN_CTL1_V1MESSTYPE1_MASK I40E_MASK(0xFF, I40E_PRTTSYN_CTL1_V1MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT 16
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK (0xF << I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT)
+#define I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE0_SHIFT)
#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT 20
-#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK (0xF << I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT)
+#define I40E_PRTTSYN_CTL1_V2MESSTYPE1_MASK I40E_MASK(0xF, I40E_PRTTSYN_CTL1_V2MESSTYPE1_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT 24
-#define I40E_PRTTSYN_CTL1_TSYNTYPE_MASK (0x3 << I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
+#define I40E_PRTTSYN_CTL1_TSYNTYPE_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT)
#define I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT 26
-#define I40E_PRTTSYN_CTL1_UDP_ENA_MASK (0x3 << I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT)
+#define I40E_PRTTSYN_CTL1_UDP_ENA_MASK I40E_MASK(0x3, I40E_PRTTSYN_CTL1_UDP_ENA_SHIFT)
#define I40E_PRTTSYN_CTL1_TSYNENA_SHIFT 31
-#define I40E_PRTTSYN_CTL1_TSYNENA_MASK (0x1 << I40E_PRTTSYN_CTL1_TSYNENA_SHIFT)
-#define I40E_PRTTSYN_EVNT_H(_i) (0x001E40C0 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_CTL1_TSYNENA_MASK I40E_MASK(0x1, I40E_PRTTSYN_CTL1_TSYNENA_SHIFT)
+#define I40E_PRTTSYN_EVNT_H(_i) (0x001E40C0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_EVNT_H_MAX_INDEX 1
#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT 0
-#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT)
-#define I40E_PRTTSYN_EVNT_L(_i) (0x001E4080 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_H_TSYNEVNT_H_SHIFT)
+#define I40E_PRTTSYN_EVNT_L(_i) (0x001E4080 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_EVNT_L_MAX_INDEX 1
#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT 0
-#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT)
-#define I40E_PRTTSYN_INC_H 0x001E4060
+#define I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_EVNT_L_TSYNEVNT_L_SHIFT)
+#define I40E_PRTTSYN_INC_H 0x001E4060 /* Reset: GLOBR */
#define I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT 0
-#define I40E_PRTTSYN_INC_H_TSYNINC_H_MASK (0x3F << I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT)
-#define I40E_PRTTSYN_INC_L 0x001E4040
+#define I40E_PRTTSYN_INC_H_TSYNINC_H_MASK I40E_MASK(0x3F, I40E_PRTTSYN_INC_H_TSYNINC_H_SHIFT)
+#define I40E_PRTTSYN_INC_L 0x001E4040 /* Reset: GLOBR */
#define I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT 0
-#define I40E_PRTTSYN_INC_L_TSYNINC_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT)
-#define I40E_PRTTSYN_RXTIME_H(_i) (0x00085040 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTTSYN_INC_L_TSYNINC_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_INC_L_TSYNINC_L_SHIFT)
+#define I40E_PRTTSYN_RXTIME_H(_i) (0x00085040 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PRTTSYN_RXTIME_H_MAX_INDEX 3
#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT)
-#define I40E_PRTTSYN_RXTIME_L(_i) (0x000850C0 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTTSYN_RXTIME_H_RXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_H_RXTIEM_H_SHIFT)
+#define I40E_PRTTSYN_RXTIME_L(_i) (0x000850C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: CORER */
#define I40E_PRTTSYN_RXTIME_L_MAX_INDEX 3
#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT)
-#define I40E_PRTTSYN_STAT_0 0x001E4220
+#define I40E_PRTTSYN_RXTIME_L_RXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_RXTIME_L_RXTIEM_L_SHIFT)
+#define I40E_PRTTSYN_STAT_0 0x001E4220 /* Reset: GLOBR */
#define I40E_PRTTSYN_STAT_0_EVENT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_0_EVENT0_MASK (0x1 << I40E_PRTTSYN_STAT_0_EVENT0_SHIFT)
+#define I40E_PRTTSYN_STAT_0_EVENT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT0_SHIFT)
#define I40E_PRTTSYN_STAT_0_EVENT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_0_EVENT1_MASK (0x1 << I40E_PRTTSYN_STAT_0_EVENT1_SHIFT)
+#define I40E_PRTTSYN_STAT_0_EVENT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_EVENT1_SHIFT)
#define I40E_PRTTSYN_STAT_0_TGT0_SHIFT 2
-#define I40E_PRTTSYN_STAT_0_TGT0_MASK (0x1 << I40E_PRTTSYN_STAT_0_TGT0_SHIFT)
+#define I40E_PRTTSYN_STAT_0_TGT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT0_SHIFT)
#define I40E_PRTTSYN_STAT_0_TGT1_SHIFT 3
-#define I40E_PRTTSYN_STAT_0_TGT1_MASK (0x1 << I40E_PRTTSYN_STAT_0_TGT1_SHIFT)
+#define I40E_PRTTSYN_STAT_0_TGT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TGT1_SHIFT)
#define I40E_PRTTSYN_STAT_0_TXTIME_SHIFT 4
-#define I40E_PRTTSYN_STAT_0_TXTIME_MASK (0x1 << I40E_PRTTSYN_STAT_0_TXTIME_SHIFT)
-#define I40E_PRTTSYN_STAT_1 0x00085140
+#define I40E_PRTTSYN_STAT_0_TXTIME_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_0_TXTIME_SHIFT)
+#define I40E_PRTTSYN_STAT_1 0x00085140 /* Reset: CORER */
#define I40E_PRTTSYN_STAT_1_RXT0_SHIFT 0
-#define I40E_PRTTSYN_STAT_1_RXT0_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT0_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT0_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT0_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT1_SHIFT 1
-#define I40E_PRTTSYN_STAT_1_RXT1_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT1_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT1_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT1_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT2_SHIFT 2
-#define I40E_PRTTSYN_STAT_1_RXT2_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT2_SHIFT)
+#define I40E_PRTTSYN_STAT_1_RXT2_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT2_SHIFT)
#define I40E_PRTTSYN_STAT_1_RXT3_SHIFT 3
-#define I40E_PRTTSYN_STAT_1_RXT3_MASK (0x1 << I40E_PRTTSYN_STAT_1_RXT3_SHIFT)
-#define I40E_PRTTSYN_TGT_H(_i) (0x001E4180 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_STAT_1_RXT3_MASK I40E_MASK(0x1, I40E_PRTTSYN_STAT_1_RXT3_SHIFT)
+#define I40E_PRTTSYN_TGT_H(_i) (0x001E4180 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_TGT_H_MAX_INDEX 1
#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT 0
-#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT)
-#define I40E_PRTTSYN_TGT_L(_i) (0x001E4140 + ((_i) * 32)) /* _i=0...1 */
+#define I40E_PRTTSYN_TGT_H_TSYNTGTT_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_H_TSYNTGTT_H_SHIFT)
+#define I40E_PRTTSYN_TGT_L(_i) (0x001E4140 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */
#define I40E_PRTTSYN_TGT_L_MAX_INDEX 1
#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT 0
-#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT)
-#define I40E_PRTTSYN_TIME_H 0x001E4120
+#define I40E_PRTTSYN_TGT_L_TSYNTGTT_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TGT_L_TSYNTGTT_L_SHIFT)
+#define I40E_PRTTSYN_TIME_H 0x001E4120 /* Reset: GLOBR */
#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT 0
-#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT)
-#define I40E_PRTTSYN_TIME_L 0x001E4100
+#define I40E_PRTTSYN_TIME_H_TSYNTIME_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_H_TSYNTIME_H_SHIFT)
+#define I40E_PRTTSYN_TIME_L 0x001E4100 /* Reset: GLOBR */
#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT 0
-#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT)
-#define I40E_PRTTSYN_TXTIME_H 0x001E41E0
+#define I40E_PRTTSYN_TIME_L_TSYNTIME_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TIME_L_TSYNTIME_L_SHIFT)
+#define I40E_PRTTSYN_TXTIME_H 0x001E41E0 /* Reset: GLOBR */
#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_MASK (0xFFFFFFFF << I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT)
-#define I40E_PRTTSYN_TXTIME_L 0x001E41C0
+#define I40E_PRTTSYN_TXTIME_H_TXTIEM_H_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_H_TXTIEM_H_SHIFT)
+#define I40E_PRTTSYN_TXTIME_L 0x001E41C0 /* Reset: GLOBR */
#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT 0
-#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_MASK (0xFFFFFFFF << I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT)
-#define I40E_GLSCD_QUANTA 0x000B2080
+#define I40E_PRTTSYN_TXTIME_L_TXTIEM_L_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTTSYN_TXTIME_L_TXTIEM_L_SHIFT)
+#define I40E_GLSCD_QUANTA 0x000B2080 /* Reset: CORER */
#define I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT 0
-#define I40E_GLSCD_QUANTA_TSCDQUANTA_MASK (0x7 << I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT)
-#define I40E_GL_MDET_RX 0x0012A510
+#define I40E_GLSCD_QUANTA_TSCDQUANTA_MASK I40E_MASK(0x7, I40E_GLSCD_QUANTA_TSCDQUANTA_SHIFT)
+#define I40E_GL_MDET_RX 0x0012A510 /* Reset: CORER */
#define I40E_GL_MDET_RX_FUNCTION_SHIFT 0
-#define I40E_GL_MDET_RX_FUNCTION_MASK (0xFF << I40E_GL_MDET_RX_FUNCTION_SHIFT)
+#define I40E_GL_MDET_RX_FUNCTION_MASK I40E_MASK(0xFF, I40E_GL_MDET_RX_FUNCTION_SHIFT)
#define I40E_GL_MDET_RX_EVENT_SHIFT 8
-#define I40E_GL_MDET_RX_EVENT_MASK (0x1FF << I40E_GL_MDET_RX_EVENT_SHIFT)
+#define I40E_GL_MDET_RX_EVENT_MASK I40E_MASK(0x1FF, I40E_GL_MDET_RX_EVENT_SHIFT)
#define I40E_GL_MDET_RX_QUEUE_SHIFT 17
-#define I40E_GL_MDET_RX_QUEUE_MASK (0x3FFF << I40E_GL_MDET_RX_QUEUE_SHIFT)
+#define I40E_GL_MDET_RX_QUEUE_MASK I40E_MASK(0x3FFF, I40E_GL_MDET_RX_QUEUE_SHIFT)
#define I40E_GL_MDET_RX_VALID_SHIFT 31
-#define I40E_GL_MDET_RX_VALID_MASK (0x1 << I40E_GL_MDET_RX_VALID_SHIFT)
-#define I40E_GL_MDET_TX 0x000E6480
-#define I40E_GL_MDET_TX_FUNCTION_SHIFT 0
-#define I40E_GL_MDET_TX_FUNCTION_MASK (0xFF << I40E_GL_MDET_TX_FUNCTION_SHIFT)
-#define I40E_GL_MDET_TX_EVENT_SHIFT 8
-#define I40E_GL_MDET_TX_EVENT_MASK (0x1FF << I40E_GL_MDET_TX_EVENT_SHIFT)
-#define I40E_GL_MDET_TX_QUEUE_SHIFT 17
-#define I40E_GL_MDET_TX_QUEUE_MASK (0x3FFF << I40E_GL_MDET_TX_QUEUE_SHIFT)
+#define I40E_GL_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_GL_MDET_RX_VALID_SHIFT)
+#define I40E_GL_MDET_TX 0x000E6480 /* Reset: CORER */
+#define I40E_GL_MDET_TX_QUEUE_SHIFT 0
+#define I40E_GL_MDET_TX_QUEUE_MASK I40E_MASK(0xFFF, I40E_GL_MDET_TX_QUEUE_SHIFT)
+#define I40E_GL_MDET_TX_VF_NUM_SHIFT 12
+#define I40E_GL_MDET_TX_VF_NUM_MASK I40E_MASK(0x1FF, I40E_GL_MDET_TX_VF_NUM_SHIFT)
+#define I40E_GL_MDET_TX_PF_NUM_SHIFT 21
+#define I40E_GL_MDET_TX_PF_NUM_MASK I40E_MASK(0xF, I40E_GL_MDET_TX_PF_NUM_SHIFT)
+#define I40E_GL_MDET_TX_EVENT_SHIFT 25
+#define I40E_GL_MDET_TX_EVENT_MASK I40E_MASK(0x1F, I40E_GL_MDET_TX_EVENT_SHIFT)
#define I40E_GL_MDET_TX_VALID_SHIFT 31
-#define I40E_GL_MDET_TX_VALID_MASK (0x1 << I40E_GL_MDET_TX_VALID_SHIFT)
-#define I40E_PF_MDET_RX 0x0012A400
+#define I40E_GL_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_GL_MDET_TX_VALID_SHIFT)
+#define I40E_PF_MDET_RX 0x0012A400 /* Reset: CORER */
#define I40E_PF_MDET_RX_VALID_SHIFT 0
-#define I40E_PF_MDET_RX_VALID_MASK (0x1 << I40E_PF_MDET_RX_VALID_SHIFT)
-#define I40E_PF_MDET_TX 0x000E6400
+#define I40E_PF_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_PF_MDET_RX_VALID_SHIFT)
+#define I40E_PF_MDET_TX 0x000E6400 /* Reset: CORER */
#define I40E_PF_MDET_TX_VALID_SHIFT 0
-#define I40E_PF_MDET_TX_VALID_MASK (0x1 << I40E_PF_MDET_TX_VALID_SHIFT)
-#define I40E_PF_VT_PFALLOC 0x001C0500
+#define I40E_PF_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_PF_MDET_TX_VALID_SHIFT)
+#define I40E_PF_VT_PFALLOC 0x001C0500 /* Reset: CORER */
#define I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT 0
-#define I40E_PF_VT_PFALLOC_FIRSTVF_MASK (0xFF << I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT)
+#define I40E_PF_VT_PFALLOC_FIRSTVF_MASK I40E_MASK(0xFF, I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT)
#define I40E_PF_VT_PFALLOC_LASTVF_SHIFT 8
-#define I40E_PF_VT_PFALLOC_LASTVF_MASK (0xFF << I40E_PF_VT_PFALLOC_LASTVF_SHIFT)
+#define I40E_PF_VT_PFALLOC_LASTVF_MASK I40E_MASK(0xFF, I40E_PF_VT_PFALLOC_LASTVF_SHIFT)
#define I40E_PF_VT_PFALLOC_VALID_SHIFT 31
-#define I40E_PF_VT_PFALLOC_VALID_MASK (0x1 << I40E_PF_VT_PFALLOC_VALID_SHIFT)
-#define I40E_VP_MDET_RX(_VF) (0x0012A000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_PF_VT_PFALLOC_VALID_MASK I40E_MASK(0x1, I40E_PF_VT_PFALLOC_VALID_SHIFT)
+#define I40E_VP_MDET_RX(_VF) (0x0012A000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VP_MDET_RX_MAX_INDEX 127
#define I40E_VP_MDET_RX_VALID_SHIFT 0
-#define I40E_VP_MDET_RX_VALID_MASK (0x1 << I40E_VP_MDET_RX_VALID_SHIFT)
-#define I40E_VP_MDET_TX(_VF) (0x000E6000 + ((_VF) * 4)) /* _i=0...127 */
+#define I40E_VP_MDET_RX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_RX_VALID_SHIFT)
+#define I40E_VP_MDET_TX(_VF) (0x000E6000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: CORER */
#define I40E_VP_MDET_TX_MAX_INDEX 127
#define I40E_VP_MDET_TX_VALID_SHIFT 0
-#define I40E_VP_MDET_TX_VALID_MASK (0x1 << I40E_VP_MDET_TX_VALID_SHIFT)
-#define I40E_GLPM_WUMC 0x0006C800
+#define I40E_VP_MDET_TX_VALID_MASK I40E_MASK(0x1, I40E_VP_MDET_TX_VALID_SHIFT)
+#define I40E_GLPM_WUMC 0x0006C800 /* Reset: POR */
#define I40E_GLPM_WUMC_NOTCO_SHIFT 0
-#define I40E_GLPM_WUMC_NOTCO_MASK (0x1 << I40E_GLPM_WUMC_NOTCO_SHIFT)
+#define I40E_GLPM_WUMC_NOTCO_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_NOTCO_SHIFT)
#define I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT 1
-#define I40E_GLPM_WUMC_SRST_PIN_VAL_MASK (0x1 << I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT)
+#define I40E_GLPM_WUMC_SRST_PIN_VAL_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_SRST_PIN_VAL_SHIFT)
#define I40E_GLPM_WUMC_ROL_MODE_SHIFT 2
-#define I40E_GLPM_WUMC_ROL_MODE_MASK (0x1 << I40E_GLPM_WUMC_ROL_MODE_SHIFT)
+#define I40E_GLPM_WUMC_ROL_MODE_MASK I40E_MASK(0x1, I40E_GLPM_WUMC_ROL_MODE_SHIFT)
#define I40E_GLPM_WUMC_RESERVED_4_SHIFT 3
-#define I40E_GLPM_WUMC_RESERVED_4_MASK (0x1FFF << I40E_GLPM_WUMC_RESERVED_4_SHIFT)
+#define I40E_GLPM_WUMC_RESERVED_4_MASK I40E_MASK(0x1FFF, I40E_GLPM_WUMC_RESERVED_4_SHIFT)
#define I40E_GLPM_WUMC_MNG_WU_PF_SHIFT 16
-#define I40E_GLPM_WUMC_MNG_WU_PF_MASK (0xFFFF << I40E_GLPM_WUMC_MNG_WU_PF_SHIFT)
-#define I40E_PFPM_APM 0x000B8080
+#define I40E_GLPM_WUMC_MNG_WU_PF_MASK I40E_MASK(0xFFFF, I40E_GLPM_WUMC_MNG_WU_PF_SHIFT)
+#define I40E_PFPM_APM 0x000B8080 /* Reset: POR */
#define I40E_PFPM_APM_APME_SHIFT 0
-#define I40E_PFPM_APM_APME_MASK (0x1 << I40E_PFPM_APM_APME_SHIFT)
-#define I40E_PFPM_FHFT_LENGTH(_i) (0x0006A000 + ((_i) * 128)) /* _i=0...7 */
+#define I40E_PFPM_APM_APME_MASK I40E_MASK(0x1, I40E_PFPM_APM_APME_SHIFT)
+#define I40E_PFPM_FHFT_LENGTH(_i) (0x0006A000 + ((_i) * 128)) /* _i=0...7 */ /* Reset: POR */
#define I40E_PFPM_FHFT_LENGTH_MAX_INDEX 7
#define I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT 0
-#define I40E_PFPM_FHFT_LENGTH_LENGTH_MASK (0xFF << I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT)
-#define I40E_PFPM_WUC 0x0006B200
+#define I40E_PFPM_FHFT_LENGTH_LENGTH_MASK I40E_MASK(0xFF, I40E_PFPM_FHFT_LENGTH_LENGTH_SHIFT)
+#define I40E_PFPM_WUC 0x0006B200 /* Reset: POR */
#define I40E_PFPM_WUC_EN_APM_D0_SHIFT 5
-#define I40E_PFPM_WUC_EN_APM_D0_MASK (0x1 << I40E_PFPM_WUC_EN_APM_D0_SHIFT)
-#define I40E_PFPM_WUFC 0x0006B400
+#define I40E_PFPM_WUC_EN_APM_D0_MASK I40E_MASK(0x1, I40E_PFPM_WUC_EN_APM_D0_SHIFT)
+#define I40E_PFPM_WUFC 0x0006B400 /* Reset: POR */
#define I40E_PFPM_WUFC_LNKC_SHIFT 0
-#define I40E_PFPM_WUFC_LNKC_MASK (0x1 << I40E_PFPM_WUFC_LNKC_SHIFT)
+#define I40E_PFPM_WUFC_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_LNKC_SHIFT)
#define I40E_PFPM_WUFC_MAG_SHIFT 1
-#define I40E_PFPM_WUFC_MAG_MASK (0x1 << I40E_PFPM_WUFC_MAG_SHIFT)
+#define I40E_PFPM_WUFC_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MAG_SHIFT)
#define I40E_PFPM_WUFC_MNG_SHIFT 3
-#define I40E_PFPM_WUFC_MNG_MASK (0x1 << I40E_PFPM_WUFC_MNG_SHIFT)
+#define I40E_PFPM_WUFC_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_MNG_SHIFT)
#define I40E_PFPM_WUFC_FLX0_ACT_SHIFT 4
-#define I40E_PFPM_WUFC_FLX0_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX0_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX0_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX1_ACT_SHIFT 5
-#define I40E_PFPM_WUFC_FLX1_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX1_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX1_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX2_ACT_SHIFT 6
-#define I40E_PFPM_WUFC_FLX2_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX2_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX2_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX3_ACT_SHIFT 7
-#define I40E_PFPM_WUFC_FLX3_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX3_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX3_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX4_ACT_SHIFT 8
-#define I40E_PFPM_WUFC_FLX4_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX4_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX4_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX5_ACT_SHIFT 9
-#define I40E_PFPM_WUFC_FLX5_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX5_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX5_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX6_ACT_SHIFT 10
-#define I40E_PFPM_WUFC_FLX6_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX6_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX6_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX7_ACT_SHIFT 11
-#define I40E_PFPM_WUFC_FLX7_ACT_MASK (0x1 << I40E_PFPM_WUFC_FLX7_ACT_SHIFT)
+#define I40E_PFPM_WUFC_FLX7_ACT_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_ACT_SHIFT)
#define I40E_PFPM_WUFC_FLX0_SHIFT 16
-#define I40E_PFPM_WUFC_FLX0_MASK (0x1 << I40E_PFPM_WUFC_FLX0_SHIFT)
+#define I40E_PFPM_WUFC_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX0_SHIFT)
#define I40E_PFPM_WUFC_FLX1_SHIFT 17
-#define I40E_PFPM_WUFC_FLX1_MASK (0x1 << I40E_PFPM_WUFC_FLX1_SHIFT)
+#define I40E_PFPM_WUFC_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX1_SHIFT)
#define I40E_PFPM_WUFC_FLX2_SHIFT 18
-#define I40E_PFPM_WUFC_FLX2_MASK (0x1 << I40E_PFPM_WUFC_FLX2_SHIFT)
+#define I40E_PFPM_WUFC_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX2_SHIFT)
#define I40E_PFPM_WUFC_FLX3_SHIFT 19
-#define I40E_PFPM_WUFC_FLX3_MASK (0x1 << I40E_PFPM_WUFC_FLX3_SHIFT)
+#define I40E_PFPM_WUFC_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX3_SHIFT)
#define I40E_PFPM_WUFC_FLX4_SHIFT 20
-#define I40E_PFPM_WUFC_FLX4_MASK (0x1 << I40E_PFPM_WUFC_FLX4_SHIFT)
+#define I40E_PFPM_WUFC_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX4_SHIFT)
#define I40E_PFPM_WUFC_FLX5_SHIFT 21
-#define I40E_PFPM_WUFC_FLX5_MASK (0x1 << I40E_PFPM_WUFC_FLX5_SHIFT)
+#define I40E_PFPM_WUFC_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX5_SHIFT)
#define I40E_PFPM_WUFC_FLX6_SHIFT 22
-#define I40E_PFPM_WUFC_FLX6_MASK (0x1 << I40E_PFPM_WUFC_FLX6_SHIFT)
+#define I40E_PFPM_WUFC_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX6_SHIFT)
#define I40E_PFPM_WUFC_FLX7_SHIFT 23
-#define I40E_PFPM_WUFC_FLX7_MASK (0x1 << I40E_PFPM_WUFC_FLX7_SHIFT)
+#define I40E_PFPM_WUFC_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FLX7_SHIFT)
#define I40E_PFPM_WUFC_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUFC_FW_RST_WK_MASK (0x1 << I40E_PFPM_WUFC_FW_RST_WK_SHIFT)
-#define I40E_PFPM_WUS 0x0006B600
+#define I40E_PFPM_WUFC_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUFC_FW_RST_WK_SHIFT)
+#define I40E_PFPM_WUS 0x0006B600 /* Reset: POR */
#define I40E_PFPM_WUS_LNKC_SHIFT 0
-#define I40E_PFPM_WUS_LNKC_MASK (0x1 << I40E_PFPM_WUS_LNKC_SHIFT)
+#define I40E_PFPM_WUS_LNKC_MASK I40E_MASK(0x1, I40E_PFPM_WUS_LNKC_SHIFT)
#define I40E_PFPM_WUS_MAG_SHIFT 1
-#define I40E_PFPM_WUS_MAG_MASK (0x1 << I40E_PFPM_WUS_MAG_SHIFT)
+#define I40E_PFPM_WUS_MAG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MAG_SHIFT)
#define I40E_PFPM_WUS_PME_STATUS_SHIFT 2
-#define I40E_PFPM_WUS_PME_STATUS_MASK (0x1 << I40E_PFPM_WUS_PME_STATUS_SHIFT)
+#define I40E_PFPM_WUS_PME_STATUS_MASK I40E_MASK(0x1, I40E_PFPM_WUS_PME_STATUS_SHIFT)
#define I40E_PFPM_WUS_MNG_SHIFT 3
-#define I40E_PFPM_WUS_MNG_MASK (0x1 << I40E_PFPM_WUS_MNG_SHIFT)
+#define I40E_PFPM_WUS_MNG_MASK I40E_MASK(0x1, I40E_PFPM_WUS_MNG_SHIFT)
#define I40E_PFPM_WUS_FLX0_SHIFT 16
-#define I40E_PFPM_WUS_FLX0_MASK (0x1 << I40E_PFPM_WUS_FLX0_SHIFT)
+#define I40E_PFPM_WUS_FLX0_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX0_SHIFT)
#define I40E_PFPM_WUS_FLX1_SHIFT 17
-#define I40E_PFPM_WUS_FLX1_MASK (0x1 << I40E_PFPM_WUS_FLX1_SHIFT)
+#define I40E_PFPM_WUS_FLX1_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX1_SHIFT)
#define I40E_PFPM_WUS_FLX2_SHIFT 18
-#define I40E_PFPM_WUS_FLX2_MASK (0x1 << I40E_PFPM_WUS_FLX2_SHIFT)
+#define I40E_PFPM_WUS_FLX2_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX2_SHIFT)
#define I40E_PFPM_WUS_FLX3_SHIFT 19
-#define I40E_PFPM_WUS_FLX3_MASK (0x1 << I40E_PFPM_WUS_FLX3_SHIFT)
+#define I40E_PFPM_WUS_FLX3_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX3_SHIFT)
#define I40E_PFPM_WUS_FLX4_SHIFT 20
-#define I40E_PFPM_WUS_FLX4_MASK (0x1 << I40E_PFPM_WUS_FLX4_SHIFT)
+#define I40E_PFPM_WUS_FLX4_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX4_SHIFT)
#define I40E_PFPM_WUS_FLX5_SHIFT 21
-#define I40E_PFPM_WUS_FLX5_MASK (0x1 << I40E_PFPM_WUS_FLX5_SHIFT)
+#define I40E_PFPM_WUS_FLX5_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX5_SHIFT)
#define I40E_PFPM_WUS_FLX6_SHIFT 22
-#define I40E_PFPM_WUS_FLX6_MASK (0x1 << I40E_PFPM_WUS_FLX6_SHIFT)
+#define I40E_PFPM_WUS_FLX6_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX6_SHIFT)
#define I40E_PFPM_WUS_FLX7_SHIFT 23
-#define I40E_PFPM_WUS_FLX7_MASK (0x1 << I40E_PFPM_WUS_FLX7_SHIFT)
+#define I40E_PFPM_WUS_FLX7_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FLX7_SHIFT)
#define I40E_PFPM_WUS_FW_RST_WK_SHIFT 31
-#define I40E_PFPM_WUS_FW_RST_WK_MASK (0x1 << I40E_PFPM_WUS_FW_RST_WK_SHIFT)
-#define I40E_PRTPM_FHFHR 0x0006C000
+#define I40E_PFPM_WUS_FW_RST_WK_MASK I40E_MASK(0x1, I40E_PFPM_WUS_FW_RST_WK_SHIFT)
+#define I40E_PRTPM_FHFHR 0x0006C000 /* Reset: POR */
#define I40E_PRTPM_FHFHR_UNICAST_SHIFT 0
-#define I40E_PRTPM_FHFHR_UNICAST_MASK (0x1 << I40E_PRTPM_FHFHR_UNICAST_SHIFT)
+#define I40E_PRTPM_FHFHR_UNICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_UNICAST_SHIFT)
#define I40E_PRTPM_FHFHR_MULTICAST_SHIFT 1
-#define I40E_PRTPM_FHFHR_MULTICAST_MASK (0x1 << I40E_PRTPM_FHFHR_MULTICAST_SHIFT)
-#define I40E_PRTPM_SAH(_i) (0x001E44C0 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTPM_FHFHR_MULTICAST_MASK I40E_MASK(0x1, I40E_PRTPM_FHFHR_MULTICAST_SHIFT)
+#define I40E_PRTPM_SAH(_i) (0x001E44C0 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
#define I40E_PRTPM_SAH_MAX_INDEX 3
#define I40E_PRTPM_SAH_PFPM_SAH_SHIFT 0
-#define I40E_PRTPM_SAH_PFPM_SAH_MASK (0xFFFF << I40E_PRTPM_SAH_PFPM_SAH_SHIFT)
+#define I40E_PRTPM_SAH_PFPM_SAH_MASK I40E_MASK(0xFFFF, I40E_PRTPM_SAH_PFPM_SAH_SHIFT)
#define I40E_PRTPM_SAH_PF_NUM_SHIFT 26
-#define I40E_PRTPM_SAH_PF_NUM_MASK (0xF << I40E_PRTPM_SAH_PF_NUM_SHIFT)
+#define I40E_PRTPM_SAH_PF_NUM_MASK I40E_MASK(0xF, I40E_PRTPM_SAH_PF_NUM_SHIFT)
#define I40E_PRTPM_SAH_MC_MAG_EN_SHIFT 30
-#define I40E_PRTPM_SAH_MC_MAG_EN_MASK (0x1 << I40E_PRTPM_SAH_MC_MAG_EN_SHIFT)
+#define I40E_PRTPM_SAH_MC_MAG_EN_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_MC_MAG_EN_SHIFT)
#define I40E_PRTPM_SAH_AV_SHIFT 31
-#define I40E_PRTPM_SAH_AV_MASK (0x1 << I40E_PRTPM_SAH_AV_SHIFT)
-#define I40E_PRTPM_SAL(_i) (0x001E4440 + ((_i) * 32)) /* _i=0...3 */
+#define I40E_PRTPM_SAH_AV_MASK I40E_MASK(0x1, I40E_PRTPM_SAH_AV_SHIFT)
+#define I40E_PRTPM_SAL(_i) (0x001E4440 + ((_i) * 32)) /* _i=0...3 */ /* Reset: PFR */
#define I40E_PRTPM_SAL_MAX_INDEX 3
#define I40E_PRTPM_SAL_PFPM_SAL_SHIFT 0
-#define I40E_PRTPM_SAL_PFPM_SAL_MASK (0xFFFFFFFF << I40E_PRTPM_SAL_PFPM_SAL_SHIFT)
-#define I40E_VF_ARQBAH1 0x00006000
+#define I40E_PRTPM_SAL_PFPM_SAL_MASK I40E_MASK(0xFFFFFFFF, I40E_PRTPM_SAL_PFPM_SAL_SHIFT)
+#define I40E_VF_ARQBAH1 0x00006000 /* Reset: EMPR */
#define I40E_VF_ARQBAH1_ARQBAH_SHIFT 0
-#define I40E_VF_ARQBAH1_ARQBAH_MASK (0xFFFFFFFF << I40E_VF_ARQBAH1_ARQBAH_SHIFT)
-#define I40E_VF_ARQBAL1 0x00006C00
+#define I40E_VF_ARQBAH1_ARQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAH1_ARQBAH_SHIFT)
+#define I40E_VF_ARQBAL1 0x00006C00 /* Reset: EMPR */
#define I40E_VF_ARQBAL1_ARQBAL_SHIFT 0
-#define I40E_VF_ARQBAL1_ARQBAL_MASK (0xFFFFFFFF << I40E_VF_ARQBAL1_ARQBAL_SHIFT)
-#define I40E_VF_ARQH1 0x00007400
+#define I40E_VF_ARQBAL1_ARQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ARQBAL1_ARQBAL_SHIFT)
+#define I40E_VF_ARQH1 0x00007400 /* Reset: EMPR */
#define I40E_VF_ARQH1_ARQH_SHIFT 0
-#define I40E_VF_ARQH1_ARQH_MASK (0x3FF << I40E_VF_ARQH1_ARQH_SHIFT)
-#define I40E_VF_ARQLEN1 0x00008000
+#define I40E_VF_ARQH1_ARQH_MASK I40E_MASK(0x3FF, I40E_VF_ARQH1_ARQH_SHIFT)
+#define I40E_VF_ARQLEN1 0x00008000 /* Reset: EMPR */
#define I40E_VF_ARQLEN1_ARQLEN_SHIFT 0
-#define I40E_VF_ARQLEN1_ARQLEN_MASK (0x3FF << I40E_VF_ARQLEN1_ARQLEN_SHIFT)
+#define I40E_VF_ARQLEN1_ARQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ARQLEN1_ARQLEN_SHIFT)
#define I40E_VF_ARQLEN1_ARQVFE_SHIFT 28
-#define I40E_VF_ARQLEN1_ARQVFE_MASK (0x1 << I40E_VF_ARQLEN1_ARQVFE_SHIFT)
+#define I40E_VF_ARQLEN1_ARQVFE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQVFE_SHIFT)
#define I40E_VF_ARQLEN1_ARQOVFL_SHIFT 29
-#define I40E_VF_ARQLEN1_ARQOVFL_MASK (0x1 << I40E_VF_ARQLEN1_ARQOVFL_SHIFT)
+#define I40E_VF_ARQLEN1_ARQOVFL_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQOVFL_SHIFT)
#define I40E_VF_ARQLEN1_ARQCRIT_SHIFT 30
-#define I40E_VF_ARQLEN1_ARQCRIT_MASK (0x1 << I40E_VF_ARQLEN1_ARQCRIT_SHIFT)
+#define I40E_VF_ARQLEN1_ARQCRIT_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQCRIT_SHIFT)
#define I40E_VF_ARQLEN1_ARQENABLE_SHIFT 31
-#define I40E_VF_ARQLEN1_ARQENABLE_MASK (0x1 << I40E_VF_ARQLEN1_ARQENABLE_SHIFT)
-#define I40E_VF_ARQT1 0x00007000
+#define I40E_VF_ARQLEN1_ARQENABLE_MASK I40E_MASK(0x1, I40E_VF_ARQLEN1_ARQENABLE_SHIFT)
+#define I40E_VF_ARQT1 0x00007000 /* Reset: EMPR */
#define I40E_VF_ARQT1_ARQT_SHIFT 0
-#define I40E_VF_ARQT1_ARQT_MASK (0x3FF << I40E_VF_ARQT1_ARQT_SHIFT)
-#define I40E_VF_ATQBAH1 0x00007800
+#define I40E_VF_ARQT1_ARQT_MASK I40E_MASK(0x3FF, I40E_VF_ARQT1_ARQT_SHIFT)
+#define I40E_VF_ATQBAH1 0x00007800 /* Reset: EMPR */
#define I40E_VF_ATQBAH1_ATQBAH_SHIFT 0
-#define I40E_VF_ATQBAH1_ATQBAH_MASK (0xFFFFFFFF << I40E_VF_ATQBAH1_ATQBAH_SHIFT)
-#define I40E_VF_ATQBAL1 0x00007C00
+#define I40E_VF_ATQBAH1_ATQBAH_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAH1_ATQBAH_SHIFT)
+#define I40E_VF_ATQBAL1 0x00007C00 /* Reset: EMPR */
#define I40E_VF_ATQBAL1_ATQBAL_SHIFT 0
-#define I40E_VF_ATQBAL1_ATQBAL_MASK (0xFFFFFFFF << I40E_VF_ATQBAL1_ATQBAL_SHIFT)
-#define I40E_VF_ATQH1 0x00006400
+#define I40E_VF_ATQBAL1_ATQBAL_MASK I40E_MASK(0xFFFFFFFF, I40E_VF_ATQBAL1_ATQBAL_SHIFT)
+#define I40E_VF_ATQH1 0x00006400 /* Reset: EMPR */
#define I40E_VF_ATQH1_ATQH_SHIFT 0
-#define I40E_VF_ATQH1_ATQH_MASK (0x3FF << I40E_VF_ATQH1_ATQH_SHIFT)
-#define I40E_VF_ATQLEN1 0x00006800
+#define I40E_VF_ATQH1_ATQH_MASK I40E_MASK(0x3FF, I40E_VF_ATQH1_ATQH_SHIFT)
+#define I40E_VF_ATQLEN1 0x00006800 /* Reset: EMPR */
#define I40E_VF_ATQLEN1_ATQLEN_SHIFT 0
-#define I40E_VF_ATQLEN1_ATQLEN_MASK (0x3FF << I40E_VF_ATQLEN1_ATQLEN_SHIFT)
+#define I40E_VF_ATQLEN1_ATQLEN_MASK I40E_MASK(0x3FF, I40E_VF_ATQLEN1_ATQLEN_SHIFT)
#define I40E_VF_ATQLEN1_ATQVFE_SHIFT 28
-#define I40E_VF_ATQLEN1_ATQVFE_MASK (0x1 << I40E_VF_ATQLEN1_ATQVFE_SHIFT)
+#define I40E_VF_ATQLEN1_ATQVFE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQVFE_SHIFT)
#define I40E_VF_ATQLEN1_ATQOVFL_SHIFT 29
-#define I40E_VF_ATQLEN1_ATQOVFL_MASK (0x1 << I40E_VF_ATQLEN1_ATQOVFL_SHIFT)
+#define I40E_VF_ATQLEN1_ATQOVFL_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQOVFL_SHIFT)
#define I40E_VF_ATQLEN1_ATQCRIT_SHIFT 30
-#define I40E_VF_ATQLEN1_ATQCRIT_MASK (0x1 << I40E_VF_ATQLEN1_ATQCRIT_SHIFT)
+#define I40E_VF_ATQLEN1_ATQCRIT_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQCRIT_SHIFT)
#define I40E_VF_ATQLEN1_ATQENABLE_SHIFT 31
-#define I40E_VF_ATQLEN1_ATQENABLE_MASK (0x1 << I40E_VF_ATQLEN1_ATQENABLE_SHIFT)
-#define I40E_VF_ATQT1 0x00008400
+#define I40E_VF_ATQLEN1_ATQENABLE_MASK I40E_MASK(0x1, I40E_VF_ATQLEN1_ATQENABLE_SHIFT)
+#define I40E_VF_ATQT1 0x00008400 /* Reset: EMPR */
#define I40E_VF_ATQT1_ATQT_SHIFT 0
-#define I40E_VF_ATQT1_ATQT_MASK (0x3FF << I40E_VF_ATQT1_ATQT_SHIFT)
-#define I40E_VFGEN_RSTAT 0x00008800
+#define I40E_VF_ATQT1_ATQT_MASK I40E_MASK(0x3FF, I40E_VF_ATQT1_ATQT_SHIFT)
+#define I40E_VFGEN_RSTAT 0x00008800 /* Reset: VFR */
#define I40E_VFGEN_RSTAT_VFR_STATE_SHIFT 0
-#define I40E_VFGEN_RSTAT_VFR_STATE_MASK (0x3 << I40E_VFGEN_RSTAT_VFR_STATE_SHIFT)
-#define I40E_VFINT_DYN_CTL01 0x00005C00
+#define I40E_VFGEN_RSTAT_VFR_STATE_MASK I40E_MASK(0x3, I40E_VFGEN_RSTAT_VFR_STATE_SHIFT)
+#define I40E_VFINT_DYN_CTL01 0x00005C00 /* Reset: VFR */
#define I40E_VFINT_DYN_CTL01_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTL01_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTL01_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTL01_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTL01_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL01_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTL01_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTL01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTL01_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTL01_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTL01_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT)
-#define I40E_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4))
+#define I40E_VFINT_DYN_CTL01_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_INTENA_MSK_SHIFT)
+#define I40E_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
#define I40E_VFINT_DYN_CTLN1_MAX_INDEX 15
#define I40E_VFINT_DYN_CTLN1_INTENA_SHIFT 0
-#define I40E_VFINT_DYN_CTLN1_INTENA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_INTENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_INTENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT 1
-#define I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_CLEARPBA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
-#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK (0x1 << I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
#define I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT 3
-#define I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT 5
-#define I40E_VFINT_DYN_CTLN1_INTERVAL_MASK (0xFFF << I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_DYN_CTLN1_INTERVAL_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT 24
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK (0x1 << I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT 25
-#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_MASK (0x3 << I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT 31
-#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_MASK (0x1 << I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
-#define I40E_VFINT_ICR0_ENA1 0x00005000
+#define I40E_VFINT_DYN_CTLN1_INTENA_MSK_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
+#define I40E_VFINT_ICR0_ENA1 0x00005000 /* Reset: CORER */
#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR0_ENA1_ADMINQ_MASK (0x1 << I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR0_ENA1_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_ADMINQ_SHIFT)
#define I40E_VFINT_ICR0_ENA1_RSVD_SHIFT 31
-#define I40E_VFINT_ICR0_ENA1_RSVD_MASK (0x1 << I40E_VFINT_ICR0_ENA1_RSVD_SHIFT)
-#define I40E_VFINT_ICR01 0x00004800
+#define I40E_VFINT_ICR0_ENA1_RSVD_MASK I40E_MASK(0x1, I40E_VFINT_ICR0_ENA1_RSVD_SHIFT)
+#define I40E_VFINT_ICR01 0x00004800 /* Reset: CORER */
#define I40E_VFINT_ICR01_INTEVENT_SHIFT 0
-#define I40E_VFINT_ICR01_INTEVENT_MASK (0x1 << I40E_VFINT_ICR01_INTEVENT_SHIFT)
+#define I40E_VFINT_ICR01_INTEVENT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_INTEVENT_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_0_SHIFT 1
-#define I40E_VFINT_ICR01_QUEUE_0_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_0_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_0_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_0_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_1_SHIFT 2
-#define I40E_VFINT_ICR01_QUEUE_1_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_1_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_1_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_1_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_2_SHIFT 3
-#define I40E_VFINT_ICR01_QUEUE_2_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_2_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_2_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_2_SHIFT)
#define I40E_VFINT_ICR01_QUEUE_3_SHIFT 4
-#define I40E_VFINT_ICR01_QUEUE_3_MASK (0x1 << I40E_VFINT_ICR01_QUEUE_3_SHIFT)
+#define I40E_VFINT_ICR01_QUEUE_3_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_QUEUE_3_SHIFT)
#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT 25
-#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK (0x1 << I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
+#define I40E_VFINT_ICR01_LINK_STAT_CHANGE_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
#define I40E_VFINT_ICR01_ADMINQ_SHIFT 30
-#define I40E_VFINT_ICR01_ADMINQ_MASK (0x1 << I40E_VFINT_ICR01_ADMINQ_SHIFT)
+#define I40E_VFINT_ICR01_ADMINQ_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_ADMINQ_SHIFT)
#define I40E_VFINT_ICR01_SWINT_SHIFT 31
-#define I40E_VFINT_ICR01_SWINT_MASK (0x1 << I40E_VFINT_ICR01_SWINT_SHIFT)
-#define I40E_VFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */
+#define I40E_VFINT_ICR01_SWINT_MASK I40E_MASK(0x1, I40E_VFINT_ICR01_SWINT_SHIFT)
+#define I40E_VFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */ /* Reset: VFR */
#define I40E_VFINT_ITR01_MAX_INDEX 2
#define I40E_VFINT_ITR01_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITR01_INTERVAL_MASK (0xFFF << I40E_VFINT_ITR01_INTERVAL_SHIFT)
-#define I40E_VFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4))
+#define I40E_VFINT_ITR01_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITR01_INTERVAL_SHIFT)
+#define I40E_VFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...15 */ /* Reset: VFR */
#define I40E_VFINT_ITRN1_MAX_INDEX 2
#define I40E_VFINT_ITRN1_INTERVAL_SHIFT 0
-#define I40E_VFINT_ITRN1_INTERVAL_MASK (0xFFF << I40E_VFINT_ITRN1_INTERVAL_SHIFT)
-#define I40E_VFINT_STAT_CTL01 0x00005400
+#define I40E_VFINT_ITRN1_INTERVAL_MASK I40E_MASK(0xFFF, I40E_VFINT_ITRN1_INTERVAL_SHIFT)
+#define I40E_VFINT_STAT_CTL01 0x00005400 /* Reset: VFR */
#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT 2
-#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_MASK (0x3 << I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
-#define I40E_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */
+#define I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_MASK I40E_MASK(0x3, I40E_VFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
+#define I40E_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_QRX_TAIL1_MAX_INDEX 15
#define I40E_QRX_TAIL1_TAIL_SHIFT 0
-#define I40E_QRX_TAIL1_TAIL_MASK (0x1FFF << I40E_QRX_TAIL1_TAIL_SHIFT)
-#define I40E_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */
+#define I40E_QRX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QRX_TAIL1_TAIL_SHIFT)
+#define I40E_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: PFR */
#define I40E_QTX_TAIL1_MAX_INDEX 15
#define I40E_QTX_TAIL1_TAIL_SHIFT 0
-#define I40E_QTX_TAIL1_TAIL_MASK (0x1FFF << I40E_QTX_TAIL1_TAIL_SHIFT)
-#define I40E_VFMSIX_PBA 0x00002000
+#define I40E_QTX_TAIL1_TAIL_MASK I40E_MASK(0x1FFF, I40E_QTX_TAIL1_TAIL_SHIFT)
+#define I40E_VFMSIX_PBA 0x00002000 /* Reset: VFLR */
#define I40E_VFMSIX_PBA_PENBIT_SHIFT 0
-#define I40E_VFMSIX_PBA_PENBIT_MASK (0xFFFFFFFF << I40E_VFMSIX_PBA_PENBIT_SHIFT)
-#define I40E_VFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_PBA_PENBIT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_PBA_PENBIT_SHIFT)
+#define I40E_VFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TADD_MAX_INDEX 16
#define I40E_VFMSIX_TADD_MSIXTADD10_SHIFT 0
-#define I40E_VFMSIX_TADD_MSIXTADD10_MASK (0x3 << I40E_VFMSIX_TADD_MSIXTADD10_SHIFT)
+#define I40E_VFMSIX_TADD_MSIXTADD10_MASK I40E_MASK(0x3, I40E_VFMSIX_TADD_MSIXTADD10_SHIFT)
#define I40E_VFMSIX_TADD_MSIXTADD_SHIFT 2
-#define I40E_VFMSIX_TADD_MSIXTADD_MASK (0x3FFFFFFF << I40E_VFMSIX_TADD_MSIXTADD_SHIFT)
-#define I40E_VFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TADD_MSIXTADD_MASK I40E_MASK(0x3FFFFFFF, I40E_VFMSIX_TADD_MSIXTADD_SHIFT)
+#define I40E_VFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TMSG_MAX_INDEX 16
#define I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT 0
-#define I40E_VFMSIX_TMSG_MSIXTMSG_MASK (0xFFFFFFFF << I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT)
-#define I40E_VFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TMSG_MSIXTMSG_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TMSG_MSIXTMSG_SHIFT)
+#define I40E_VFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TUADD_MAX_INDEX 16
#define I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT 0
-#define I40E_VFMSIX_TUADD_MSIXTUADD_MASK (0xFFFFFFFF << I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT)
-#define I40E_VFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */
+#define I40E_VFMSIX_TUADD_MSIXTUADD_MASK I40E_MASK(0xFFFFFFFF, I40E_VFMSIX_TUADD_MSIXTUADD_SHIFT)
+#define I40E_VFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
#define I40E_VFMSIX_TVCTRL_MAX_INDEX 16
#define I40E_VFMSIX_TVCTRL_MASK_SHIFT 0
-#define I40E_VFMSIX_TVCTRL_MASK_MASK (0x1 << I40E_VFMSIX_TVCTRL_MASK_SHIFT)
-#define I40E_VFCM_PE_ERRDATA 0x0000DC00
+#define I40E_VFMSIX_TVCTRL_MASK_MASK I40E_MASK(0x1, I40E_VFMSIX_TVCTRL_MASK_SHIFT)
+#define I40E_VFCM_PE_ERRDATA 0x0000DC00 /* Reset: VFR */
#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
-#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_MASK (0xF << I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_VFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
#define I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
-#define I40E_VFCM_PE_ERRDATA_Q_TYPE_MASK (0x7 << I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT)
+#define I40E_VFCM_PE_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRDATA_Q_TYPE_SHIFT)
#define I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT 8
-#define I40E_VFCM_PE_ERRDATA_Q_NUM_MASK (0x3FFFF << I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT)
-#define I40E_VFCM_PE_ERRINFO 0x0000D800
+#define I40E_VFCM_PE_ERRDATA_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_VFCM_PE_ERRDATA_Q_NUM_SHIFT)
+#define I40E_VFCM_PE_ERRINFO 0x0000D800 /* Reset: VFR */
#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
-#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_MASK (0x1 << I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_VFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
#define I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
-#define I40E_VFCM_PE_ERRINFO_ERROR_INST_MASK (0x7 << I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_VFCM_PE_ERRINFO_ERROR_INST_SHIFT)
#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
-#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
-#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
-#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK (0xFF << I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
-#define I40E_VFPE_AEQALLOC1 0x0000A400
-#define I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT 0
-#define I40E_VFPE_AEQALLOC1_AECOUNT_MASK (0xFFFFFFFF << I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT)
-#define I40E_VFPE_CCQPHIGH1 0x00009800
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT 0
-#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_MASK (0xFFFFFFFF << I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT)
-#define I40E_VFPE_CCQPLOW1 0x0000AC00
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT 0
-#define I40E_VFPE_CCQPLOW1_PECCQPLOW_MASK (0xFFFFFFFF << I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1 0x0000B800
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT 0
-#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_MASK (0x1 << I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT)
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT 31
-#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_MASK (0x1 << I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT)
-#define I40E_VFPE_CQACK1 0x0000B000
-#define I40E_VFPE_CQACK1_PECQID_SHIFT 0
-#define I40E_VFPE_CQACK1_PECQID_MASK (0x1FFFF << I40E_VFPE_CQACK1_PECQID_SHIFT)
-#define I40E_VFPE_CQARM1 0x0000B400
-#define I40E_VFPE_CQARM1_PECQID_SHIFT 0
-#define I40E_VFPE_CQARM1_PECQID_MASK (0x1FFFF << I40E_VFPE_CQARM1_PECQID_SHIFT)
-#define I40E_VFPE_CQPDB1 0x0000BC00
-#define I40E_VFPE_CQPDB1_WQHEAD_SHIFT 0
-#define I40E_VFPE_CQPDB1_WQHEAD_MASK (0x7FF << I40E_VFPE_CQPDB1_WQHEAD_SHIFT)
-#define I40E_VFPE_CQPERRCODES1 0x00009C00
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT 0
-#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT)
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT 16
-#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_MASK (0xFFFF << I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT)
-#define I40E_VFPE_CQPTAIL1 0x0000A000
-#define I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT 0
-#define I40E_VFPE_CQPTAIL1_WQTAIL_MASK (0x7FF << I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT)
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT 31
-#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_MASK (0x1 << I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT)
-#define I40E_VFPE_IPCONFIG01 0x00008C00
-#define I40E_VFPE_IPCONFIG01_PEIPID_SHIFT 0
-#define I40E_VFPE_IPCONFIG01_PEIPID_MASK (0xFFFF << I40E_VFPE_IPCONFIG01_PEIPID_SHIFT)
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT 16
-#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_MASK (0x1 << I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT)
-#define I40E_VFPE_MRTEIDXMASK1 0x00009000
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT 0
-#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_MASK (0x1F << I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT)
-#define I40E_VFPE_RCVUNEXPECTEDERROR1 0x00009400
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT 0
-#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_MASK (0xFFFFFF << I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT)
-#define I40E_VFPE_TCPNOWTIMER1 0x0000A800
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT 0
-#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_MASK (0xFFFFFFFF << I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT)
-#define I40E_VFPE_WQEALLOC1 0x0000C000
-#define I40E_VFPE_WQEALLOC1_PEQPID_SHIFT 0
-#define I40E_VFPE_WQEALLOC1_PEQPID_MASK (0x3FFFF << I40E_VFPE_WQEALLOC1_PEQPID_SHIFT)
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT 20
-#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_MASK (0xFFF << I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT)
-#define I40E_VFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */
+#define I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_VFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
+#define I40E_VFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
#define I40E_VFQF_HENA_MAX_INDEX 1
#define I40E_VFQF_HENA_PTYPE_ENA_SHIFT 0
-#define I40E_VFQF_HENA_PTYPE_ENA_MASK (0xFFFFFFFF << I40E_VFQF_HENA_PTYPE_ENA_SHIFT)
-#define I40E_VFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */
+#define I40E_VFQF_HENA_PTYPE_ENA_MASK I40E_MASK(0xFFFFFFFF, I40E_VFQF_HENA_PTYPE_ENA_SHIFT)
+#define I40E_VFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
#define I40E_VFQF_HKEY_MAX_INDEX 12
#define I40E_VFQF_HKEY_KEY_0_SHIFT 0
-#define I40E_VFQF_HKEY_KEY_0_MASK (0xFF << I40E_VFQF_HKEY_KEY_0_SHIFT)
+#define I40E_VFQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_0_SHIFT)
#define I40E_VFQF_HKEY_KEY_1_SHIFT 8
-#define I40E_VFQF_HKEY_KEY_1_MASK (0xFF << I40E_VFQF_HKEY_KEY_1_SHIFT)
+#define I40E_VFQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_1_SHIFT)
#define I40E_VFQF_HKEY_KEY_2_SHIFT 16
-#define I40E_VFQF_HKEY_KEY_2_MASK (0xFF << I40E_VFQF_HKEY_KEY_2_SHIFT)
+#define I40E_VFQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_2_SHIFT)
#define I40E_VFQF_HKEY_KEY_3_SHIFT 24
-#define I40E_VFQF_HKEY_KEY_3_MASK (0xFF << I40E_VFQF_HKEY_KEY_3_SHIFT)
-#define I40E_VFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */
+#define I40E_VFQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_VFQF_HKEY_KEY_3_SHIFT)
+#define I40E_VFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
#define I40E_VFQF_HLUT_MAX_INDEX 15
#define I40E_VFQF_HLUT_LUT0_SHIFT 0
-#define I40E_VFQF_HLUT_LUT0_MASK (0xF << I40E_VFQF_HLUT_LUT0_SHIFT)
+#define I40E_VFQF_HLUT_LUT0_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT0_SHIFT)
#define I40E_VFQF_HLUT_LUT1_SHIFT 8
-#define I40E_VFQF_HLUT_LUT1_MASK (0xF << I40E_VFQF_HLUT_LUT1_SHIFT)
+#define I40E_VFQF_HLUT_LUT1_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT1_SHIFT)
#define I40E_VFQF_HLUT_LUT2_SHIFT 16
-#define I40E_VFQF_HLUT_LUT2_MASK (0xF << I40E_VFQF_HLUT_LUT2_SHIFT)
+#define I40E_VFQF_HLUT_LUT2_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT2_SHIFT)
#define I40E_VFQF_HLUT_LUT3_SHIFT 24
-#define I40E_VFQF_HLUT_LUT3_MASK (0xF << I40E_VFQF_HLUT_LUT3_SHIFT)
-#define I40E_VFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */
+#define I40E_VFQF_HLUT_LUT3_MASK I40E_MASK(0xF, I40E_VFQF_HLUT_LUT3_SHIFT)
+#define I40E_VFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */ /* Reset: CORER */
#define I40E_VFQF_HREGION_MAX_INDEX 7
#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
#define I40E_VFQF_HREGION_REGION_0_SHIFT 1
-#define I40E_VFQF_HREGION_REGION_0_MASK (0x7 << I40E_VFQF_HREGION_REGION_0_SHIFT)
+#define I40E_VFQF_HREGION_REGION_0_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_0_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
#define I40E_VFQF_HREGION_REGION_1_SHIFT 5
-#define I40E_VFQF_HREGION_REGION_1_MASK (0x7 << I40E_VFQF_HREGION_REGION_1_SHIFT)
+#define I40E_VFQF_HREGION_REGION_1_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_1_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
#define I40E_VFQF_HREGION_REGION_2_SHIFT 9
-#define I40E_VFQF_HREGION_REGION_2_MASK (0x7 << I40E_VFQF_HREGION_REGION_2_SHIFT)
+#define I40E_VFQF_HREGION_REGION_2_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_2_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
#define I40E_VFQF_HREGION_REGION_3_SHIFT 13
-#define I40E_VFQF_HREGION_REGION_3_MASK (0x7 << I40E_VFQF_HREGION_REGION_3_SHIFT)
+#define I40E_VFQF_HREGION_REGION_3_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_3_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
#define I40E_VFQF_HREGION_REGION_4_SHIFT 17
-#define I40E_VFQF_HREGION_REGION_4_MASK (0x7 << I40E_VFQF_HREGION_REGION_4_SHIFT)
+#define I40E_VFQF_HREGION_REGION_4_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_4_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
#define I40E_VFQF_HREGION_REGION_5_SHIFT 21
-#define I40E_VFQF_HREGION_REGION_5_MASK (0x7 << I40E_VFQF_HREGION_REGION_5_SHIFT)
+#define I40E_VFQF_HREGION_REGION_5_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_5_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
#define I40E_VFQF_HREGION_REGION_6_SHIFT 25
-#define I40E_VFQF_HREGION_REGION_6_MASK (0x7 << I40E_VFQF_HREGION_REGION_6_SHIFT)
+#define I40E_VFQF_HREGION_REGION_6_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_6_SHIFT)
#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
-#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK (0x1 << I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
+#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
#define I40E_VFQF_HREGION_REGION_7_SHIFT 29
-#define I40E_VFQF_HREGION_REGION_7_MASK (0x7 << I40E_VFQF_HREGION_REGION_7_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS 0x00270110
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_SHIFT 0
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_WR_ACCESS_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_SHIFT 8
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_RD_ACCESS_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_SHIFT 16
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_MASK (0xFF << I40E_RCU_PST_FOC_ACCESS_STATUS_ERR_CNT_SHIFT)
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_SHIFT 24
-#define I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_MASK (0x7 << I40E_RCU_PST_FOC_ACCESS_STATUS_LAST_ERR_CODE_SHIFT)
+#define I40E_VFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_7_SHIFT)
#endif
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
index 48ebb6cd69f2..79bf96ca6489 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c
@@ -50,7 +50,11 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
struct i40e_tx_buffer *tx_buffer)
{
if (tx_buffer->skb) {
- dev_kfree_skb_any(tx_buffer->skb);
+ if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
+ kfree(tx_buffer->raw_buf);
+ else
+ dev_kfree_skb_any(tx_buffer->skb);
+
if (dma_unmap_len(tx_buffer, len))
dma_unmap_single(ring->dev,
dma_unmap_addr(tx_buffer, dma),
@@ -769,8 +773,6 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi,
/* likely incorrect csum if alternate IP extension headers found */
if (ipv6 &&
- decoded.inner_prot == I40E_RX_PTYPE_INNER_PROT_TCP &&
- rx_error & (1 << I40E_RX_DESC_ERROR_L4E_SHIFT) &&
rx_status & (1 << I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT))
/* don't increment checksum err here, non-fatal err */
return;
@@ -1336,6 +1338,7 @@ static void i40e_create_tx_ctx(struct i40e_ring *tx_ring,
/* cpu_to_le32 and assign to struct fields */
context_desc->tunneling_params = cpu_to_le32(cd_tunneling);
context_desc->l2tag2 = cpu_to_le16(cd_l2tag2);
+ context_desc->rsvd = cpu_to_le16(0);
context_desc->type_cmd_tso_mss = cpu_to_le64(cd_type_cmd_tso_mss);
}
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
index 30d248bc5d19..8bc6858163b0 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.h
@@ -75,7 +75,6 @@ enum i40e_dyn_idx_t {
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) | \
((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | \
- ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) | \
((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) | \
@@ -131,6 +130,7 @@ enum i40e_dyn_idx_t {
#define I40E_TX_FLAGS_IPV6 (u32)(1 << 5)
#define I40E_TX_FLAGS_FCCRC (u32)(1 << 6)
#define I40E_TX_FLAGS_FSO (u32)(1 << 7)
+#define I40E_TX_FLAGS_FD_SB (u32)(1 << 9)
#define I40E_TX_FLAGS_VLAN_MASK 0xffff0000
#define I40E_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define I40E_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -139,7 +139,10 @@ enum i40e_dyn_idx_t {
struct i40e_tx_buffer {
struct i40e_tx_desc *next_to_watch;
unsigned long time_stamp;
- struct sk_buff *skb;
+ union {
+ struct sk_buff *skb;
+ void *raw_buf;
+ };
unsigned int bytecount;
unsigned short gso_segs;
DEFINE_DMA_UNMAP_ADDR(dma);
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index d3cf5a69de54..15376436cead 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -50,6 +50,9 @@
(d) == I40E_DEV_ID_QSFP_B || \
(d) == I40E_DEV_ID_QSFP_C)
+/* I40E_MASK is a macro used on 32 bit registers */
+#define I40E_MASK(mask, shift) (mask << shift)
+
#define I40E_MAX_VSI_QP 16
#define I40E_MAX_VF_VSI 3
#define I40E_MAX_CHAINED_RX_BUFFERS 5
@@ -137,6 +140,14 @@ enum i40e_fc_mode {
I40E_FC_DEFAULT
};
+enum i40e_set_fc_aq_failures {
+ I40E_SET_FC_AQ_FAIL_NONE = 0,
+ I40E_SET_FC_AQ_FAIL_GET = 1,
+ I40E_SET_FC_AQ_FAIL_SET = 2,
+ I40E_SET_FC_AQ_FAIL_UPDATE = 4,
+ I40E_SET_FC_AQ_FAIL_SET_UPDATE = 6
+};
+
enum i40e_vsi_type {
I40E_VSI_MAIN = 0,
I40E_VSI_VMDQ1,
@@ -163,6 +174,7 @@ struct i40e_link_status {
u8 an_info;
u8 ext_info;
u8 loopback;
+ bool an_enabled;
/* is Link Status Event notification to SW enabled */
bool lse_enable;
u16 max_frame_size;
@@ -256,6 +268,61 @@ struct i40e_nvm_info {
u32 eetrack; /* NVM data version */
};
+/* definitions used in NVM update support */
+
+enum i40e_nvmupd_cmd {
+ I40E_NVMUPD_INVALID,
+ I40E_NVMUPD_READ_CON,
+ I40E_NVMUPD_READ_SNT,
+ I40E_NVMUPD_READ_LCB,
+ I40E_NVMUPD_READ_SA,
+ I40E_NVMUPD_WRITE_ERA,
+ I40E_NVMUPD_WRITE_CON,
+ I40E_NVMUPD_WRITE_SNT,
+ I40E_NVMUPD_WRITE_LCB,
+ I40E_NVMUPD_WRITE_SA,
+ I40E_NVMUPD_CSUM_CON,
+ I40E_NVMUPD_CSUM_SA,
+ I40E_NVMUPD_CSUM_LCB,
+};
+
+enum i40e_nvmupd_state {
+ I40E_NVMUPD_STATE_INIT,
+ I40E_NVMUPD_STATE_READING,
+ I40E_NVMUPD_STATE_WRITING
+};
+
+/* nvm_access definition and its masks/shifts need to be accessible to
+ * application, core driver, and shared code. Where is the right file?
+ */
+#define I40E_NVM_READ 0xB
+#define I40E_NVM_WRITE 0xC
+
+#define I40E_NVM_MOD_PNT_MASK 0xFF
+
+#define I40E_NVM_TRANS_SHIFT 8
+#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
+#define I40E_NVM_CON 0x0
+#define I40E_NVM_SNT 0x1
+#define I40E_NVM_LCB 0x2
+#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
+#define I40E_NVM_ERA 0x4
+#define I40E_NVM_CSUM 0x8
+
+#define I40E_NVM_ADAPT_SHIFT 16
+#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
+
+#define I40E_NVMUPD_MAX_DATA 4096
+#define I40E_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
+
+struct i40e_nvm_access {
+ u32 command;
+ u32 config;
+ u32 offset; /* in bytes */
+ u32 data_size; /* in bytes */
+ u8 data[1];
+};
+
/* PCI bus types */
enum i40e_bus_type {
i40e_bus_type_unknown = 0,
@@ -391,6 +458,9 @@ struct i40e_hw {
/* Admin Queue info */
struct i40e_adminq_info aq;
+ /* state of nvm update process */
+ enum i40e_nvmupd_state nvmupd_state;
+
/* HMC info */
struct i40e_hmc_info hmc; /* HMC info struct */
@@ -875,7 +945,6 @@ enum i40e_filter_pctype {
I40E_FILTER_PCTYPE_FRAG_IPV4 = 36,
/* Note: Values 37-40 are reserved for future use */
I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41,
- I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN = 42,
I40E_FILTER_PCTYPE_NONF_IPV6_TCP = 43,
I40E_FILTER_PCTYPE_NONF_IPV6_SCTP = 44,
I40E_FILTER_PCTYPE_NONF_IPV6_OTHER = 45,
@@ -1162,4 +1231,7 @@ enum i40e_reset_type {
I40E_RESET_GLOBR = 2,
I40E_RESET_EMPR = 3,
};
+
+/* RSS Hash Table Size */
+#define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
#endif /* _I40E_TYPE_H_ */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index 60407a9df0c1..efee6b290c0f 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -193,7 +193,7 @@ static void i40evf_set_msglevel(struct net_device *netdev, u32 data)
}
/**
- * i40evf_get_drvinto - Get driver info
+ * i40evf_get_drvinfo - Get driver info
* @netdev: network interface device structure
* @drvinfo: ethool driver info structure
*
@@ -632,7 +632,7 @@ static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
u32 hlut_val;
int i, j;
- for (i = 0, j = 0; i < I40E_VFQF_HLUT_MAX_INDEX; i++) {
+ for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
hlut_val = rd32(hw, I40E_VFQF_HLUT(i));
indir[j++] = hlut_val & 0xff;
indir[j++] = (hlut_val >> 8) & 0xff;
@@ -659,7 +659,7 @@ static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
u32 hlut_val;
int i, j;
- for (i = 0, j = 0; i < I40E_VFQF_HLUT_MAX_INDEX + 1; i++) {
+ for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
hlut_val = indir[j++];
hlut_val |= indir[j++] << 8;
hlut_val |= indir[j++] << 16;
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 7fc5f3b5d6bf..ab15f4d07e41 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -34,9 +34,9 @@ static int i40evf_close(struct net_device *netdev);
char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
- "Intel(R) XL710 X710 Virtual Function Network Driver";
+ "Intel(R) XL710/X710 Virtual Function Network Driver";
-#define DRV_VERSION "0.9.34"
+#define DRV_VERSION "0.9.40"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation.";
@@ -260,6 +260,12 @@ static void i40evf_fire_sw_int(struct i40evf_adapter *adapter,
int i;
uint32_t dyn_ctl;
+ if (mask & 1) {
+ dyn_ctl = rd32(hw, I40E_VFINT_DYN_CTL01);
+ dyn_ctl |= I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK |
+ I40E_VFINT_DYN_CTLN_CLEARPBA_MASK;
+ wr32(hw, I40E_VFINT_DYN_CTL01, dyn_ctl);
+ }
for (i = 1; i < adapter->num_msix_vectors; i++) {
if (mask & (1 << i)) {
dyn_ctl = rd32(hw, I40E_VFINT_DYN_CTLN1(i - 1));
@@ -278,6 +284,7 @@ void i40evf_irq_enable(struct i40evf_adapter *adapter, bool flush)
{
struct i40e_hw *hw = &adapter->hw;
+ i40evf_misc_irq_enable(adapter);
i40evf_irq_enable_queues(adapter, ~0);
if (flush)
@@ -520,7 +527,8 @@ static int i40evf_request_misc_irq(struct i40evf_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int err;
- sprintf(adapter->misc_vector_name, "i40evf:mbx");
+ snprintf(adapter->misc_vector_name,
+ sizeof(adapter->misc_vector_name) - 1, "i40evf:mbx");
err = request_irq(adapter->msix_entries[0].vector,
&i40evf_msix_aq, 0,
adapter->misc_vector_name, netdev);
@@ -761,7 +769,7 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section))
- mdelay(1);
+ udelay(1);
f = i40evf_find_filter(adapter, macaddr);
if (NULL == f) {
@@ -833,7 +841,7 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section))
- mdelay(1);
+ udelay(1);
/* remove filter if not in netdev list */
list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
bool found = false;
@@ -1290,12 +1298,16 @@ static void i40evf_watchdog_task(struct work_struct *work)
struct i40evf_adapter,
watchdog_task);
struct i40e_hw *hw = &adapter->hw;
+ uint32_t rstat_val;
if (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section))
goto restart_watchdog;
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) {
- if ((rd32(hw, I40E_VFGEN_RSTAT) & 0x3) == I40E_VFR_VFACTIVE) {
+ rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
+ I40E_VFGEN_RSTAT_VFR_STATE_MASK;
+ if ((rstat_val == I40E_VFR_VFACTIVE) ||
+ (rstat_val == I40E_VFR_COMPLETED)) {
/* A chance for redemption! */
dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attempting reinit.\n");
adapter->state = __I40EVF_STARTUP;
@@ -1321,8 +1333,11 @@ static void i40evf_watchdog_task(struct work_struct *work)
goto watchdog_done;
/* check for reset */
+ rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
+ I40E_VFGEN_RSTAT_VFR_STATE_MASK;
if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING) &&
- (rd32(hw, I40E_VFGEN_RSTAT) & 0x3) != I40E_VFR_VFACTIVE) {
+ (rstat_val != I40E_VFR_VFACTIVE) &&
+ (rstat_val != I40E_VFR_COMPLETED)) {
adapter->state = __I40EVF_RESETTING;
adapter->flags |= I40EVF_FLAG_RESET_PENDING;
dev_err(&adapter->pdev->dev, "Hardware reset detected\n");
@@ -1388,6 +1403,8 @@ static void i40evf_watchdog_task(struct work_struct *work)
watchdog_done:
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
restart_watchdog:
+ if (adapter->state == __I40EVF_REMOVE)
+ return;
if (adapter->aq_required)
mod_timer(&adapter->watchdog_timer,
jiffies + msecs_to_jiffies(20));
@@ -1488,7 +1505,8 @@ static void i40evf_reset_task(struct work_struct *work)
for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
I40E_VFGEN_RSTAT_VFR_STATE_MASK;
- if (rstat_val != I40E_VFR_VFACTIVE)
+ if ((rstat_val != I40E_VFR_VFACTIVE) &&
+ (rstat_val != I40E_VFR_COMPLETED))
break;
else
msleep(I40EVF_RESET_WAIT_MS);
@@ -1502,12 +1520,16 @@ static void i40evf_reset_task(struct work_struct *work)
for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
I40E_VFGEN_RSTAT_VFR_STATE_MASK;
- if (rstat_val == I40E_VFR_VFACTIVE)
+ if ((rstat_val == I40E_VFR_VFACTIVE) ||
+ (rstat_val == I40E_VFR_COMPLETED))
break;
else
msleep(I40EVF_RESET_WAIT_MS);
}
if (i == I40EVF_RESET_WAIT_COUNT) {
+ struct i40evf_mac_filter *f, *ftmp;
+ struct i40evf_vlan_filter *fv, *fvtmp;
+
/* reset never finished */
dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n",
rstat_val);
@@ -1520,9 +1542,23 @@ static void i40evf_reset_task(struct work_struct *work)
i40evf_free_all_tx_resources(adapter);
i40evf_free_all_rx_resources(adapter);
}
+
+ /* Delete all of the filters, both MAC and VLAN. */
+ list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list,
+ list) {
+ list_del(&f->list);
+ kfree(f);
+ }
+ list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list,
+ list) {
+ list_del(&fv->list);
+ kfree(fv);
+ }
+
i40evf_free_misc_irq(adapter);
i40evf_reset_interrupt_capability(adapter);
i40evf_free_queues(adapter);
+ i40evf_free_q_vectors(adapter);
kfree(adapter->vf_res);
i40evf_shutdown_adminq(hw);
adapter->netdev->flags &= ~IFF_UP;
@@ -1939,8 +1975,10 @@ static int i40evf_check_reset_complete(struct i40e_hw *hw)
int i;
for (i = 0; i < 100; i++) {
- rstat = rd32(hw, I40E_VFGEN_RSTAT);
- if (rstat == I40E_VFR_VFACTIVE)
+ rstat = rd32(hw, I40E_VFGEN_RSTAT) &
+ I40E_VFGEN_RSTAT_VFR_STATE_MASK;
+ if ((rstat == I40E_VFR_VFACTIVE) ||
+ (rstat == I40E_VFR_COMPLETED))
return 0;
udelay(10);
}
@@ -2006,7 +2044,6 @@ static void i40evf_init_task(struct work_struct *work)
}
adapter->state = __I40EVF_INIT_VERSION_CHECK;
goto restart;
- break;
case __I40EVF_INIT_VERSION_CHECK:
if (!i40evf_asq_done(hw)) {
dev_err(&pdev->dev, "Admin queue command never completed\n");
@@ -2018,17 +2055,20 @@ static void i40evf_init_task(struct work_struct *work)
if (err) {
dev_info(&pdev->dev, "Unable to verify API version (%d), retrying\n",
err);
+ if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) {
+ dev_info(&pdev->dev, "Resending request\n");
+ err = i40evf_send_api_ver(adapter);
+ }
goto err;
}
err = i40evf_send_vf_config_msg(adapter);
if (err) {
- dev_err(&pdev->dev, "Unable send config request (%d)\n",
+ dev_err(&pdev->dev, "Unable to send config request (%d)\n",
err);
goto err;
}
adapter->state = __I40EVF_INIT_GET_RESOURCES;
goto restart;
- break;
case __I40EVF_INIT_GET_RESOURCES:
/* aq msg sent, awaiting reply */
if (!adapter->vf_res) {
@@ -2097,8 +2137,6 @@ static void i40evf_init_task(struct work_struct *work)
ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr);
ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
- INIT_LIST_HEAD(&adapter->mac_filter_list);
- INIT_LIST_HEAD(&adapter->vlan_filter_list);
f = kzalloc(sizeof(*f), GFP_ATOMIC);
if (NULL == f)
goto err_sw_init;
@@ -2280,6 +2318,9 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->bus.device = PCI_SLOT(pdev->devfn);
hw->bus.func = PCI_FUNC(pdev->devfn);
+ INIT_LIST_HEAD(&adapter->mac_filter_list);
+ INIT_LIST_HEAD(&adapter->vlan_filter_list);
+
INIT_WORK(&adapter->reset_task, i40evf_reset_task);
INIT_WORK(&adapter->adminq_task, i40evf_adminq_task);
INIT_WORK(&adapter->watchdog_task, i40evf_watchdog_task);
@@ -2391,6 +2432,7 @@ static void i40evf_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct i40evf_adapter *adapter = netdev_priv(netdev);
+ struct i40evf_mac_filter *f, *ftmp;
struct i40e_hw *hw = &adapter->hw;
cancel_delayed_work_sync(&adapter->init_task);
@@ -2406,9 +2448,12 @@ static void i40evf_remove(struct pci_dev *pdev)
i40evf_misc_irq_disable(adapter);
i40evf_free_misc_irq(adapter);
i40evf_reset_interrupt_capability(adapter);
+ i40evf_free_q_vectors(adapter);
}
- del_timer_sync(&adapter->watchdog_timer);
+ if (adapter->watchdog_timer.function)
+ del_timer_sync(&adapter->watchdog_timer);
+
flush_scheduled_work();
if (hw->aq.asq.count)
@@ -2419,6 +2464,13 @@ static void i40evf_remove(struct pci_dev *pdev)
i40evf_free_queues(adapter);
kfree(adapter->vf_res);
+ /* If we got removed before an up/down sequence, we've got a filter
+ * hanging out there that we need to get rid of.
+ */
+ list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
+ list_del(&f->list);
+ kfree(f);
+ }
free_netdev(netdev);
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
index 2dc0bac76717..66d12f5b4ca8 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c
@@ -80,8 +80,9 @@ int i40evf_send_api_ver(struct i40evf_adapter *adapter)
* @adapter: adapter structure
*
* Compare API versions with the PF. Must be called after admin queue is
- * initialized. Returns 0 if API versions match, -EIO if
- * they do not, or I40E_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty.
+ * initialized. Returns 0 if API versions match, -EIO if they do not,
+ * I40E_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty, and any errors
+ * from the firmware are propagated.
**/
int i40evf_verify_api_ver(struct i40evf_adapter *adapter)
{
@@ -102,13 +103,13 @@ int i40evf_verify_api_ver(struct i40evf_adapter *adapter)
goto out_alloc;
err = (i40e_status)le32_to_cpu(event.desc.cookie_low);
- if (err) {
- err = -EIO;
+ if (err)
goto out_alloc;
- }
if ((enum i40e_virtchnl_ops)le32_to_cpu(event.desc.cookie_high) !=
I40E_VIRTCHNL_OP_VERSION) {
+ dev_info(&adapter->pdev->dev, "Invalid reply type %d from PF\n",
+ le32_to_cpu(event.desc.cookie_high));
err = -EIO;
goto out_alloc;
}
@@ -247,11 +248,11 @@ void i40evf_configure_queues(struct i40evf_adapter *adapter)
vqpi++;
}
+ adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES,
(u8 *)vqci, len);
kfree(vqci);
- adapter->aq_pending |= I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
- adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_QUEUES;
}
/**
@@ -274,10 +275,10 @@ void i40evf_enable_queues(struct i40evf_adapter *adapter)
vqs.vsi_id = adapter->vsi_res->vsi_id;
vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1;
vqs.rx_queues = vqs.tx_queues;
- i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
- (u8 *)&vqs, sizeof(vqs));
adapter->aq_pending |= I40EVF_FLAG_AQ_ENABLE_QUEUES;
adapter->aq_required &= ~I40EVF_FLAG_AQ_ENABLE_QUEUES;
+ i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
+ (u8 *)&vqs, sizeof(vqs));
}
/**
@@ -300,10 +301,10 @@ void i40evf_disable_queues(struct i40evf_adapter *adapter)
vqs.vsi_id = adapter->vsi_res->vsi_id;
vqs.tx_queues = (1 << adapter->vsi_res->num_queue_pairs) - 1;
vqs.rx_queues = vqs.tx_queues;
- i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES,
- (u8 *)&vqs, sizeof(vqs));
adapter->aq_pending |= I40EVF_FLAG_AQ_DISABLE_QUEUES;
adapter->aq_required &= ~I40EVF_FLAG_AQ_DISABLE_QUEUES;
+ i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DISABLE_QUEUES,
+ (u8 *)&vqs, sizeof(vqs));
}
/**
@@ -351,11 +352,11 @@ void i40evf_map_queues(struct i40evf_adapter *adapter)
vimi->vecmap[v_idx].txq_map = 0;
vimi->vecmap[v_idx].rxq_map = 0;
+ adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS;
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP,
(u8 *)vimi, len);
kfree(vimi);
- adapter->aq_pending |= I40EVF_FLAG_AQ_MAP_VECTORS;
- adapter->aq_required &= ~I40EVF_FLAG_AQ_MAP_VECTORS;
}
/**
@@ -412,12 +413,11 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
f->add = false;
}
}
+ adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
(u8 *)veal, len);
kfree(veal);
- adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
- adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_MAC_FILTER;
-
}
/**
@@ -474,11 +474,11 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
kfree(f);
}
}
+ adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
+ adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
(u8 *)veal, len);
kfree(veal);
- adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_MAC_FILTER;
- adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_MAC_FILTER;
}
/**
@@ -535,10 +535,10 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
f->add = false;
}
}
- i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
- kfree(vvfl);
adapter->aq_pending |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
adapter->aq_required &= ~I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
+ i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
+ kfree(vvfl);
}
/**
@@ -596,10 +596,10 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
kfree(f);
}
}
- i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
- kfree(vvfl);
adapter->aq_pending |= I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
adapter->aq_required &= ~I40EVF_FLAG_AQ_DEL_VLAN_FILTER;
+ i40evf_send_pf_msg(adapter, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)vvfl, len);
+ kfree(vvfl);
}
/**
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index a2db388cc31e..236a6183a865 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -579,7 +579,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
break;
default:
return -E1000_ERR_MAC_INIT;
- break;
}
/* Set media type */
@@ -837,7 +836,6 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
default:
ret_val = -E1000_ERR_PHY;
goto out;
- break;
}
ret_val = igb_get_phy_id(hw);
goto out;
@@ -1481,6 +1479,13 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
s32 ret_val;
u16 i, rar_count = mac->rar_entry_count;
+ if ((hw->mac.type >= e1000_i210) &&
+ !(igb_get_flash_presence_i210(hw))) {
+ ret_val = igb_pll_workaround_i210(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Initialize identification LED */
ret_val = igb_id_led_init(hw);
if (ret_val) {
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 2a8bb35c2df2..217f8138851b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -46,14 +46,15 @@
#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* SDP3 Data direction */
/* Physical Func Reset Done Indication */
-#define E1000_CTRL_EXT_PFRSTD 0x00004000
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
-#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_EIAME 0x01000000
-#define E1000_CTRL_EXT_IRCA 0x00000001
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
+#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_EIAME 0x01000000
+#define E1000_CTRL_EXT_IRCA 0x00000001
/* Interrupt delay cancellation */
/* Driver loaded bit for FW */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000
@@ -62,6 +63,7 @@
/* packet buffer parity error detection enabled */
/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_PHYPDEN 0x00100000
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
#define E1000_I2CCMD_OPCODE_READ 0x08000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 89925e405849..ce55ea5d750c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -567,4 +567,7 @@ struct net_device *igb_get_hw_dev(struct e1000_hw *hw);
/* These functions must be implemented by drivers */
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
+
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif /* _E1000_HW_H_ */
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index 337161f440dd..65d931669f81 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -834,3 +834,69 @@ s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
}
return ret_val;
}
+
+/**
+ * igb_pll_workaround_i210
+ * @hw: pointer to the HW structure
+ *
+ * Works around an errata in the PLL circuit where it occasionally
+ * provides the wrong clock frequency after power up.
+ **/
+s32 igb_pll_workaround_i210(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
+ u16 nvm_word, phy_word, pci_word, tmp_nvm;
+ int i;
+
+ /* Get and set needed register values */
+ wuc = rd32(E1000_WUC);
+ mdicnfg = rd32(E1000_MDICNFG);
+ reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
+ wr32(E1000_MDICNFG, reg_val);
+
+ /* Get data from NVM, or set default */
+ ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
+ &nvm_word);
+ if (ret_val)
+ nvm_word = E1000_INVM_DEFAULT_AL;
+ tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+ for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
+ /* check current state directly from internal PHY */
+ igb_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
+ E1000_PHY_PLL_FREQ_REG), &phy_word);
+ if ((phy_word & E1000_PHY_PLL_UNCONF)
+ != E1000_PHY_PLL_UNCONF) {
+ ret_val = 0;
+ break;
+ } else {
+ ret_val = -E1000_ERR_PHY;
+ }
+ /* directly reset the internal PHY */
+ ctrl = rd32(E1000_CTRL);
+ wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
+
+ ctrl_ext = rd32(E1000_CTRL_EXT);
+ ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
+ wr32(E1000_CTRL_EXT, ctrl_ext);
+
+ wr32(E1000_WUC, 0);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ pci_word |= E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ usleep_range(1000, 2000);
+ pci_word &= ~E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ /* restore WUC register */
+ wr32(E1000_WUC, wuc);
+ }
+ /* restore MDICNFG setting */
+ wr32(E1000_MDICNFG, mdicnfg);
+ return ret_val;
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index 9f34976687ba..3442b6357d01 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -33,6 +33,7 @@ s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data);
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data);
s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
bool igb_get_flash_presence_i210(struct e1000_hw *hw);
+s32 igb_pll_workaround_i210(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
@@ -78,4 +79,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
+/* PLL Defines */
+#define E1000_PCI_PMCSR 0x44
+#define E1000_PCI_PMCSR_D3 0x03
+#define E1000_MAX_PLL_TRIES 5
+#define E1000_PHY_PLL_UNCONF 0xFF
+#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000
+#define E1000_PHY_PLL_FREQ_REG 0x000E
+#define E1000_INVM_DEFAULT_AL 0x202F
+#define E1000_INVM_AUTOLOAD 0x0A
+#define E1000_INVM_PLL_WO_VAL 0x0010
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 1cc4b1a7e597..6f0490d0e981 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -66,6 +66,7 @@
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
+#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
@@ -354,6 +355,7 @@
#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
+#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
/* These act per VF so an array friendly macro is used */
#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index f145adbb55ac..cb14bbdfb056 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -57,8 +57,8 @@
#include "igb.h"
#define MAJ 5
-#define MIN 0
-#define BUILD 5
+#define MIN 2
+#define BUILD 13
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
__stringify(BUILD) "-k"
char igb_driver_name[] = "igb";
@@ -1630,6 +1630,8 @@ void igb_power_up_link(struct igb_adapter *adapter)
igb_power_up_phy_copper(&adapter->hw);
else
igb_power_up_serdes_link_82575(&adapter->hw);
+
+ igb_setup_link(&adapter->hw);
}
/**
@@ -4165,6 +4167,26 @@ static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event)
}
/**
+ * igb_check_lvmmc - check for malformed packets received
+ * and indicated in LVMMC register
+ * @adapter: pointer to adapter
+ **/
+static void igb_check_lvmmc(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 lvmmc;
+
+ lvmmc = rd32(E1000_LVMMC);
+ if (lvmmc) {
+ if (unlikely(net_ratelimit())) {
+ netdev_warn(adapter->netdev,
+ "malformed Tx packet detected and dropped, LVMMC:0x%08x\n",
+ lvmmc);
+ }
+ }
+}
+
+/**
* igb_watchdog - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
@@ -4359,6 +4381,11 @@ static void igb_watchdog_task(struct work_struct *work)
igb_spoof_check(adapter);
igb_ptp_rx_hang(adapter);
+ /* Check LVMMC register on i350/i354 only */
+ if ((adapter->hw.mac.type == e1000_i350) ||
+ (adapter->hw.mac.type == e1000_i354))
+ igb_check_lvmmc(adapter);
+
/* Reset the timer */
if (!test_bit(__IGB_DOWN, &adapter->state)) {
if (adapter->flags & IGB_FLAG_NEED_LINK_UPDATE)
@@ -7215,6 +7242,20 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_read_config_word(adapter->pdev, reg, value);
+}
+
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_write_config_word(adapter->pdev, reg, *value);
+}
+
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
@@ -7578,6 +7619,8 @@ static int igb_sriov_reinit(struct pci_dev *dev)
if (netif_running(netdev))
igb_close(netdev);
+ else
+ igb_reset(adapter);
igb_clear_interrupt_scheme(adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 15609331ec17..c5c97b483d7c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -122,7 +122,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val = 0;
+ s32 ret_val;
u16 list_offset, data_offset;
/* Identify the PHY */
@@ -147,28 +147,23 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
/* Call SFP+ identify routine to get the SFP+ module type */
ret_val = phy->ops.identify_sfp(hw);
- if (ret_val != 0)
- goto out;
- else if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) {
- ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
+ if (ret_val)
+ return ret_val;
+ if (hw->phy.sfp_type == ixgbe_sfp_type_unknown)
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
/* Check to see if SFP+ module is supported */
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
&list_offset,
&data_offset);
- if (ret_val != 0) {
- ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
+ if (ret_val)
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
break;
default:
break;
}
-out:
- return ret_val;
+ return 0;
}
/**
@@ -183,7 +178,7 @@ static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
{
u32 regval;
u32 i;
- s32 ret_val = 0;
+ s32 ret_val;
ret_val = ixgbe_start_hw_generic(hw);
@@ -203,11 +198,13 @@ static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
}
+ if (ret_val)
+ return ret_val;
+
/* set the completion timeout for interface */
- if (ret_val == 0)
- ixgbe_set_pcie_completion_timeout(hw);
+ ixgbe_set_pcie_completion_timeout(hw);
- return ret_val;
+ return 0;
}
/**
@@ -222,7 +219,6 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
bool *autoneg)
{
- s32 status = 0;
u32 autoc = 0;
/*
@@ -262,11 +258,10 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
break;
default:
- status = IXGBE_ERR_LINK_SETUP;
- break;
+ return IXGBE_ERR_LINK_SETUP;
}
- return status;
+ return 0;
}
/**
@@ -277,14 +272,12 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
**/
static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
{
- enum ixgbe_media_type media_type;
-
/* Detect if there is a copper PHY attached. */
switch (hw->phy.type) {
case ixgbe_phy_cu_unknown:
case ixgbe_phy_tn:
- media_type = ixgbe_media_type_copper;
- goto out;
+ return ixgbe_media_type_copper;
+
default:
break;
}
@@ -294,30 +287,27 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82598:
case IXGBE_DEV_ID_82598_BX:
/* Default device ID is mezzanine card KX/KX4 */
- media_type = ixgbe_media_type_backplane;
- break;
+ return ixgbe_media_type_backplane;
+
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
case IXGBE_DEV_ID_82598EB_XF_LR:
case IXGBE_DEV_ID_82598EB_SFP_LOM:
- media_type = ixgbe_media_type_fiber;
- break;
+ return ixgbe_media_type_fiber;
+
case IXGBE_DEV_ID_82598EB_CX4:
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- media_type = ixgbe_media_type_cx4;
- break;
+ return ixgbe_media_type_cx4;
+
case IXGBE_DEV_ID_82598AT:
case IXGBE_DEV_ID_82598AT2:
- media_type = ixgbe_media_type_copper;
- break;
+ return ixgbe_media_type_copper;
+
default:
- media_type = ixgbe_media_type_unknown;
- break;
+ return ixgbe_media_type_unknown;
}
-out:
- return media_type;
}
/**
@@ -328,7 +318,6 @@ out:
**/
static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
{
- s32 ret_val = 0;
u32 fctrl_reg;
u32 rmcs_reg;
u32 reg;
@@ -338,10 +327,8 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
bool link_up;
/* Validate the water mark configuration */
- if (!hw->fc.pause_time) {
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
+ if (!hw->fc.pause_time)
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
/* Low water mark of zero causes XOFF floods */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
@@ -350,8 +337,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
if (!hw->fc.low_water[i] ||
hw->fc.low_water[i] >= hw->fc.high_water[i]) {
hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
}
}
}
@@ -428,9 +414,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
break;
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
+ return IXGBE_ERR_CONFIG;
}
/* Set 802.3x based flow control settings. */
@@ -461,8 +445,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
/* Configure flow control refresh threshold value */
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-out:
- return ret_val;
+ return 0;
}
/**
@@ -598,7 +581,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
}
if (!*link_up)
- goto out;
+ return 0;
}
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
@@ -629,7 +612,6 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
(ixgbe_validate_link_ready(hw) != 0))
*link_up = false;
-out:
return 0;
}
@@ -646,7 +628,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete)
{
bool autoneg = false;
- s32 status = 0;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 autoc = curr_autoc;
@@ -657,7 +638,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
speed &= link_capabilities;
if (speed == IXGBE_LINK_SPEED_UNKNOWN)
- status = IXGBE_ERR_LINK_SETUP;
+ return IXGBE_ERR_LINK_SETUP;
/* Set KX4/KX support according to speed requested */
else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
@@ -671,17 +652,11 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
}
- if (status == 0) {
- /*
- * Setup and restart the link based on the new values in
- * ixgbe_hw This will write the AUTOC register based on the new
- * stored values
- */
- status = ixgbe_start_mac_link_82598(hw,
- autoneg_wait_to_complete);
- }
-
- return status;
+ /* Setup and restart the link based on the new values in
+ * ixgbe_hw This will write the AUTOC register based on the new
+ * stored values
+ */
+ return ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
}
@@ -718,7 +693,7 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
**/
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
s32 phy_status = 0;
u32 ctrl;
u32 gheccr;
@@ -728,8 +703,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
+ if (status)
+ return status;
/*
* Power up the Atlas Tx lanes if they are currently powered down.
@@ -771,7 +746,7 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
/* Init PHY and function pointers, perform SFP setup */
phy_status = hw->phy.ops.init(hw);
if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
+ return phy_status;
if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
goto mac_reset_top;
@@ -837,7 +812,6 @@ mac_reset_top:
*/
hw->mac.ops.init_rx_addrs(hw);
-reset_hw_out:
if (phy_status)
status = phy_status;
@@ -1110,106 +1084,6 @@ static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
}
/**
- * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
- u16 ext_ability = 0;
-
- hw->phy.ops.identify(hw);
-
- /* Copper PHY must be checked before AUTOC LMS to determine correct
- * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- case ixgbe_phy_cu_unknown:
- hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE,
- MDIO_MMD_PMAPMD, &ext_ability);
- if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
- goto out;
- default:
- break;
- }
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_AN:
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- else
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- break;
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- else /* XAUI */
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- case IXGBE_AUTOC_LMS_KX4_AN:
- case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- break;
- default:
- break;
- }
-
- if (hw->phy.type == ixgbe_phy_nl) {
- hw->phy.ops.identify_sfp(hw);
-
- switch (hw->phy.sfp_type) {
- case ixgbe_sfp_type_da_cu:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_sfp_type_sr:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case ixgbe_sfp_type_lr:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- default:
- physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- break;
- }
- }
-
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- break;
- case IXGBE_DEV_ID_82598EB_XF_LR:
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- default:
- break;
- }
-
-out:
- return physical_layer;
-}
-
-/**
* ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
* port devices.
* @hw: pointer to the HW structure
@@ -1286,7 +1160,6 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.start_hw = &ixgbe_start_hw_82598,
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82598,
- .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
.enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
index bc7c924240a5..cf55a0df877b 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
@@ -123,7 +123,7 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
{
- s32 ret_val = 0;
+ s32 ret_val;
u16 list_offset, data_offset, data_value;
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
@@ -133,16 +133,14 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
&data_offset);
- if (ret_val != 0)
- goto setup_sfp_out;
+ if (ret_val)
+ return ret_val;
/* PHY config will finish before releasing the semaphore */
ret_val = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
- if (ret_val != 0) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto setup_sfp_out;
- }
+ if (ret_val)
+ return IXGBE_ERR_SWFW_SYNC;
if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
goto setup_sfp_err;
@@ -169,13 +167,11 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
if (ret_val) {
hw_dbg(hw, " sfp module setup not complete\n");
- ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
- goto setup_sfp_out;
+ return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
}
}
-setup_sfp_out:
- return ret_val;
+ return 0;
setup_sfp_err:
/* Release the semaphore */
@@ -294,7 +290,7 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
struct ixgbe_phy_info *phy = &hw->phy;
- s32 ret_val = 0;
+ s32 ret_val;
u32 esdp;
if (hw->device_id == IXGBE_DEV_ID_82599_QSFP_SF_QP) {
@@ -355,7 +351,6 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
bool *autoneg)
{
- s32 status = 0;
u32 autoc = 0;
/* Determine 1G link capabilities off of SFP+ type */
@@ -367,7 +362,7 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = true;
- goto out;
+ return 0;
}
/*
@@ -430,9 +425,7 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
break;
default:
- status = IXGBE_ERR_LINK_SETUP;
- goto out;
- break;
+ return IXGBE_ERR_LINK_SETUP;
}
if (hw->phy.multispeed_fiber) {
@@ -446,8 +439,7 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
*autoneg = true;
}
-out:
- return status;
+ return 0;
}
/**
@@ -458,14 +450,12 @@ out:
**/
static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
{
- enum ixgbe_media_type media_type;
-
/* Detect if there is a copper PHY attached. */
switch (hw->phy.type) {
case ixgbe_phy_cu_unknown:
case ixgbe_phy_tn:
- media_type = ixgbe_media_type_copper;
- goto out;
+ return ixgbe_media_type_copper;
+
default:
break;
}
@@ -478,34 +468,31 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
case IXGBE_DEV_ID_82599_XAUI_LOM:
/* Default device ID is mezzanine card KX/KX4 */
- media_type = ixgbe_media_type_backplane;
- break;
+ return ixgbe_media_type_backplane;
+
case IXGBE_DEV_ID_82599_SFP:
case IXGBE_DEV_ID_82599_SFP_FCOE:
case IXGBE_DEV_ID_82599_SFP_EM:
case IXGBE_DEV_ID_82599_SFP_SF2:
case IXGBE_DEV_ID_82599_SFP_SF_QP:
case IXGBE_DEV_ID_82599EN_SFP:
- media_type = ixgbe_media_type_fiber;
- break;
+ return ixgbe_media_type_fiber;
+
case IXGBE_DEV_ID_82599_CX4:
- media_type = ixgbe_media_type_cx4;
- break;
+ return ixgbe_media_type_cx4;
+
case IXGBE_DEV_ID_82599_T3_LOM:
- media_type = ixgbe_media_type_copper;
- break;
+ return ixgbe_media_type_copper;
+
case IXGBE_DEV_ID_82599_LS:
- media_type = ixgbe_media_type_fiber_lco;
- break;
+ return ixgbe_media_type_fiber_lco;
+
case IXGBE_DEV_ID_82599_QSFP_SF_QP:
- media_type = ixgbe_media_type_fiber_qsfp;
- break;
+ return ixgbe_media_type_fiber_qsfp;
+
default:
- media_type = ixgbe_media_type_unknown;
- break;
+ return ixgbe_media_type_unknown;
}
-out:
- return media_type;
}
/**
@@ -555,7 +542,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
status = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (status)
- goto out;
+ return status;
got_lock = true;
}
@@ -592,7 +579,6 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
/* Add delay to filter out noises during initial link setup */
msleep(50);
-out:
return status;
}
@@ -959,7 +945,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete)
{
bool autoneg = false;
- s32 status = 0;
+ s32 status;
u32 pma_pmd_1g, link_mode, links_reg, i;
u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
@@ -975,15 +961,13 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
/* Check to see if speed passed in is supported. */
status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities,
&autoneg);
- if (status != 0)
- goto out;
+ if (status)
+ return status;
speed &= link_capabilities;
- if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
- status = IXGBE_ERR_LINK_SETUP;
- goto out;
- }
+ if (speed == IXGBE_LINK_SPEED_UNKNOWN)
+ return IXGBE_ERR_LINK_SETUP;
/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
if (hw->mac.orig_link_settings_stored)
@@ -1034,7 +1018,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
/* Restart link */
status = hw->mac.ops.prot_autoc_write(hw, autoc, false);
if (status)
- goto out;
+ return status;
/* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) {
@@ -1061,7 +1045,6 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
msleep(50);
}
-out:
return status;
}
@@ -1106,8 +1089,8 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
+ if (status)
+ return status;
/* flush pending Tx transactions */
ixgbe_clear_tx_pending(hw);
@@ -1118,7 +1101,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
status = hw->phy.ops.init(hw);
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
+ return status;
/* Setup SFP module if there is one present. */
if (hw->phy.sfp_setup_needed) {
@@ -1127,7 +1110,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
}
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
- goto reset_hw_out;
+ return status;
/* Reset PHY */
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
@@ -1217,7 +1200,7 @@ mac_reset_top:
hw->mac.orig_autoc,
false);
if (status)
- goto reset_hw_out;
+ return status;
}
if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
@@ -1259,7 +1242,6 @@ mac_reset_top:
hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
&hw->mac.wwpn_prefix);
-reset_hw_out:
return status;
}
@@ -1928,20 +1910,20 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
s32 ret_val = 0;
ret_val = ixgbe_start_hw_generic(hw);
- if (ret_val != 0)
- goto out;
+ if (ret_val)
+ return ret_val;
ret_val = ixgbe_start_hw_gen2(hw);
- if (ret_val != 0)
- goto out;
+ if (ret_val)
+ return ret_val;
/* We need to run link autotry after the driver loads */
hw->mac.autotry_restart = true;
- if (ret_val == 0)
- ret_val = ixgbe_verify_fw_version_82599(hw);
-out:
- return ret_val;
+ if (ret_val)
+ return ret_val;
+
+ return ixgbe_verify_fw_version_82599(hw);
}
/**
@@ -1954,16 +1936,15 @@ out:
**/
static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+ s32 status;
/* Detect PHY if not unknown - returns success if already detected. */
status = ixgbe_identify_phy_generic(hw);
- if (status != 0) {
+ if (status) {
/* 82599 10GBASE-T requires an external PHY */
if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper)
- goto out;
- else
- status = ixgbe_identify_module_generic(hw);
+ return status;
+ status = ixgbe_identify_module_generic(hw);
}
/* Set PHY type none if no PHY detected */
@@ -1974,142 +1955,12 @@ static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
/* Return error if SFP module has been detected but is not supported */
if (hw->phy.type == ixgbe_phy_sfp_unsupported)
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
-out:
return status;
}
/**
- * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
- u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
- u16 ext_ability = 0;
- u8 comp_codes_10g = 0;
- u8 comp_codes_1g = 0;
-
- hw->phy.ops.identify(hw);
-
- switch (hw->phy.type) {
- case ixgbe_phy_tn:
- case ixgbe_phy_cu_unknown:
- hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
- &ext_ability);
- if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
- goto out;
- default:
- break;
- }
-
- switch (autoc & IXGBE_AUTOC_LMS_MASK) {
- case IXGBE_AUTOC_LMS_1G_AN:
- case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
- if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
- IXGBE_PHYSICAL_LAYER_1000BASE_BX;
- goto out;
- } else
- /* SFI mode so read SFP module */
- goto sfp_check;
- break;
- case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
- if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
- else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI;
- goto out;
- break;
- case IXGBE_AUTOC_LMS_10G_SERIAL:
- if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
- goto out;
- } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
- goto sfp_check;
- break;
- case IXGBE_AUTOC_LMS_KX4_KX_KR:
- case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
- if (autoc & IXGBE_AUTOC_KX_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
- if (autoc & IXGBE_AUTOC_KX4_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
- if (autoc & IXGBE_AUTOC_KR_SUPP)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
- goto out;
- break;
- default:
- goto out;
- break;
- }
-
-sfp_check:
- /* SFP check must be done last since DA modules are sometimes used to
- * test KR mode - we need to id KR mode correctly before SFP module.
- * Call identify_sfp because the pluggable module may have changed */
- hw->phy.ops.identify_sfp(hw);
- if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
- goto out;
-
- switch (hw->phy.type) {
- case ixgbe_phy_sfp_passive_tyco:
- case ixgbe_phy_sfp_passive_unknown:
- case ixgbe_phy_qsfp_passive_unknown:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
- break;
- case ixgbe_phy_sfp_ftl_active:
- case ixgbe_phy_sfp_active_unknown:
- case ixgbe_phy_qsfp_active_unknown:
- physical_layer = IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA;
- break;
- case ixgbe_phy_sfp_avago:
- case ixgbe_phy_sfp_ftl:
- case ixgbe_phy_sfp_intel:
- case ixgbe_phy_sfp_unknown:
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_1GBE_COMP_CODES, &comp_codes_1g);
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
- if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_T;
- break;
- case ixgbe_phy_qsfp_intel:
- case ixgbe_phy_qsfp_unknown:
- hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_QSFP_10GBE_COMP, &comp_codes_10g);
- if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
- break;
- default:
- break;
- }
-
-out:
- return physical_layer;
-}
-
-/**
* ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
* @hw: pointer to hardware structure
* @regval: register value to write to RXCTRL
@@ -2151,26 +2002,24 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
u16 fw_version = 0;
/* firmware check is only necessary for SFI devices */
- if (hw->phy.media_type != ixgbe_media_type_fiber) {
- status = 0;
- goto fw_version_out;
- }
+ if (hw->phy.media_type != ixgbe_media_type_fiber)
+ return 0;
/* get the offset to the Firmware Module block */
offset = IXGBE_FW_PTR;
if (hw->eeprom.ops.read(hw, offset, &fw_offset))
goto fw_version_err;
- if ((fw_offset == 0) || (fw_offset == 0xFFFF))
- goto fw_version_out;
+ if (fw_offset == 0 || fw_offset == 0xFFFF)
+ return IXGBE_ERR_EEPROM_VERSION;
/* get the offset to the Pass Through Patch Configuration block */
offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR;
if (hw->eeprom.ops.read(hw, offset, &fw_ptp_cfg_offset))
goto fw_version_err;
- if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
- goto fw_version_out;
+ if (fw_ptp_cfg_offset == 0 || fw_ptp_cfg_offset == 0xFFFF)
+ return IXGBE_ERR_EEPROM_VERSION;
/* get the firmware version */
offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4;
@@ -2180,7 +2029,6 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
if (fw_version > 0x5)
status = 0;
-fw_version_out:
return status;
fw_version_err:
@@ -2197,37 +2045,33 @@ fw_version_err:
**/
static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
{
- bool lesm_enabled = false;
u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
s32 status;
/* get the offset to the Firmware Module block */
status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
- if ((status != 0) ||
- (fw_offset == 0) || (fw_offset == 0xFFFF))
- goto out;
+ if (status || fw_offset == 0 || fw_offset == 0xFFFF)
+ return false;
/* get the offset to the LESM Parameters block */
status = hw->eeprom.ops.read(hw, (fw_offset +
IXGBE_FW_LESM_PARAMETERS_PTR),
&fw_lesm_param_offset);
- if ((status != 0) ||
- (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
- goto out;
+ if (status ||
+ fw_lesm_param_offset == 0 || fw_lesm_param_offset == 0xFFFF)
+ return false;
/* get the lesm state word */
status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
IXGBE_FW_LESM_STATE_1),
&fw_lesm_state);
- if ((status == 0) &&
- (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
- lesm_enabled = true;
+ if (!status && (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
+ return true;
-out:
- return lesm_enabled;
+ return false;
}
/**
@@ -2245,22 +2089,16 @@ static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data)
{
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val = IXGBE_ERR_CONFIG;
- /*
- * If EEPROM is detected and can be addressed using 14 bits,
+ /* If EEPROM is detected and can be addressed using 14 bits,
* use EERD otherwise use bit bang
*/
- if ((eeprom->type == ixgbe_eeprom_spi) &&
- (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
- ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
- data);
- else
- ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
- words,
- data);
+ if (eeprom->type == ixgbe_eeprom_spi &&
+ offset + (words - 1) <= IXGBE_EERD_MAX_ADDR)
+ return ixgbe_read_eerd_buffer_generic(hw, offset, words, data);
- return ret_val;
+ return ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset, words,
+ data);
}
/**
@@ -2277,19 +2115,15 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
u16 offset, u16 *data)
{
struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
- s32 ret_val = IXGBE_ERR_CONFIG;
/*
* If EEPROM is detected and can be addressed using 14 bits,
* use EERD otherwise use bit bang
*/
- if ((eeprom->type == ixgbe_eeprom_spi) &&
- (offset <= IXGBE_EERD_MAX_ADDR))
- ret_val = ixgbe_read_eerd_generic(hw, offset, data);
- else
- ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
+ if (eeprom->type == ixgbe_eeprom_spi && offset <= IXGBE_EERD_MAX_ADDR)
+ return ixgbe_read_eerd_generic(hw, offset, data);
- return ret_val;
+ return ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
}
/**
@@ -2458,7 +2292,6 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.start_hw = &ixgbe_start_hw_82599,
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82599,
- .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
.enable_rx_dma = &ixgbe_enable_rx_dma_82599,
.disable_rx_buff = &ixgbe_disable_rx_buff_generic,
.enable_rx_buff = &ixgbe_enable_rx_buff_generic,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 4e5385a2a465..b5f484bf3fda 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -122,8 +122,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
*/
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
}
/*
@@ -143,7 +142,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
/* some MAC's need RMW protection on AUTOC */
ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp);
if (ret_val)
- goto out;
+ return ret_val;
/* only backplane uses autoc so fall though */
case ixgbe_media_type_fiber:
@@ -214,9 +213,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
break;
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
+ return IXGBE_ERR_CONFIG;
}
if (hw->mac.type != ixgbe_mac_X540) {
@@ -247,7 +244,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
*/
ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
if (ret_val)
- goto out;
+ return ret_val;
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
ixgbe_device_supports_autoneg_fc(hw)) {
@@ -256,7 +253,6 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
}
hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
-out:
return ret_val;
}
@@ -295,12 +291,11 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
/* Setup flow control */
ret_val = ixgbe_setup_fc(hw);
if (!ret_val)
- goto out;
+ return 0;
/* Clear adapter stopped flag */
hw->adapter_stopped = false;
-out:
return ret_val;
}
@@ -837,20 +832,16 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data)
{
- s32 status = 0;
+ s32 status;
u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
+ if (words == 0)
+ return IXGBE_ERR_INVALID_ARGUMENT;
- if (offset + words > hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ if (offset + words > hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
/*
* The EEPROM page size cannot be queried from the chip. We do lazy
@@ -875,7 +866,6 @@ s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
break;
}
-out:
return status;
}
@@ -900,64 +890,61 @@ static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
/* Prepare the EEPROM for writing */
status = ixgbe_acquire_eeprom(hw);
+ if (status)
+ return status;
- if (status == 0) {
- if (ixgbe_ready_eeprom(hw) != 0) {
- ixgbe_release_eeprom(hw);
- status = IXGBE_ERR_EEPROM;
- }
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ return IXGBE_ERR_EEPROM;
}
- if (status == 0) {
- for (i = 0; i < words; i++) {
- ixgbe_standby_eeprom(hw);
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
+
+ /* Send the WRITE ENABLE command (8 bit opcode) */
+ ixgbe_shift_out_eeprom_bits(hw,
+ IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- ixgbe_shift_out_eeprom_bits(hw,
- IXGBE_EEPROM_WREN_OPCODE_SPI,
- IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_standby_eeprom(hw);
- ixgbe_standby_eeprom(hw);
+ /* Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
- /*
- * Some SPI eeproms use the 8th address bit embedded
- * in the opcode
- */
- if ((hw->eeprom.address_bits == 8) &&
- ((offset + i) >= 128))
- write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, write_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
- hw->eeprom.address_bits);
-
- page_size = hw->eeprom.word_page_size;
-
- /* Send the data in burst via SPI*/
- do {
- word = data[i];
- word = (word >> 8) | (word << 8);
- ixgbe_shift_out_eeprom_bits(hw, word, 16);
-
- if (page_size == 0)
- break;
-
- /* do not wrap around page */
- if (((offset + i) & (page_size - 1)) ==
- (page_size - 1))
- break;
- } while (++i < words);
-
- ixgbe_standby_eeprom(hw);
- usleep_range(10000, 20000);
- }
- /* Done with writing - release the EEPROM */
- ixgbe_release_eeprom(hw);
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ page_size = hw->eeprom.word_page_size;
+
+ /* Send the data in burst via SPI */
+ do {
+ word = data[i];
+ word = (word >> 8) | (word << 8);
+ ixgbe_shift_out_eeprom_bits(hw, word, 16);
+
+ if (page_size == 0)
+ break;
+
+ /* do not wrap around page */
+ if (((offset + i) & (page_size - 1)) ==
+ (page_size - 1))
+ break;
+ } while (++i < words);
+
+ ixgbe_standby_eeprom(hw);
+ usleep_range(10000, 20000);
}
+ /* Done with writing - release the EEPROM */
+ ixgbe_release_eeprom(hw);
- return status;
+ return 0;
}
/**
@@ -971,19 +958,12 @@ static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
**/
s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
{
- s32 status;
-
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
+ if (offset >= hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
-out:
- return status;
+ return ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
}
/**
@@ -998,20 +978,16 @@ out:
s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data)
{
- s32 status = 0;
+ s32 status;
u16 i, count;
hw->eeprom.ops.init_params(hw);
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
+ if (words == 0)
+ return IXGBE_ERR_INVALID_ARGUMENT;
- if (offset + words > hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ if (offset + words > hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
/*
* We cannot hold synchronization semaphores for too long
@@ -1025,12 +1001,11 @@ s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
count, &data[i]);
- if (status != 0)
- break;
+ if (status)
+ return status;
}
-out:
- return status;
+ return 0;
}
/**
@@ -1052,41 +1027,38 @@ static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
/* Prepare the EEPROM for reading */
status = ixgbe_acquire_eeprom(hw);
+ if (status)
+ return status;
- if (status == 0) {
- if (ixgbe_ready_eeprom(hw) != 0) {
- ixgbe_release_eeprom(hw);
- status = IXGBE_ERR_EEPROM;
- }
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ return IXGBE_ERR_EEPROM;
}
- if (status == 0) {
- for (i = 0; i < words; i++) {
- ixgbe_standby_eeprom(hw);
- /*
- * Some SPI eeproms use the 8th address bit embedded
- * in the opcode
- */
- if ((hw->eeprom.address_bits == 8) &&
- ((offset + i) >= 128))
- read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- ixgbe_shift_out_eeprom_bits(hw, read_opcode,
- IXGBE_EEPROM_OPCODE_BITS);
- ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
- hw->eeprom.address_bits);
-
- /* Read the data. */
- word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
+ for (i = 0; i < words; i++) {
+ ixgbe_standby_eeprom(hw);
+ /* Some SPI eeproms use the 8th address bit embedded
+ * in the opcode
+ */
+ if ((hw->eeprom.address_bits == 8) &&
+ ((offset + i) >= 128))
+ read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
- /* End this read operation */
- ixgbe_release_eeprom(hw);
+ /* Send the READ command (opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+ hw->eeprom.address_bits);
+
+ /* Read the data. */
+ word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+ data[i] = (word_in >> 8) | (word_in << 8);
}
- return status;
+ /* End this read operation */
+ ixgbe_release_eeprom(hw);
+
+ return 0;
}
/**
@@ -1100,19 +1072,12 @@ static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data)
{
- s32 status;
-
hw->eeprom.ops.init_params(hw);
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
-
- status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+ if (offset >= hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
-out:
- return status;
+ return ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
}
/**
@@ -1128,20 +1093,16 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data)
{
u32 eerd;
- s32 status = 0;
+ s32 status;
u32 i;
hw->eeprom.ops.init_params(hw);
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
+ if (words == 0)
+ return IXGBE_ERR_INVALID_ARGUMENT;
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ if (offset >= hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
for (i = 0; i < words; i++) {
eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
@@ -1155,11 +1116,11 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
IXGBE_EEPROM_RW_REG_DATA);
} else {
hw_dbg(hw, "Eeprom read timed out\n");
- goto out;
+ return status;
}
}
-out:
- return status;
+
+ return 0;
}
/**
@@ -1175,7 +1136,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
u16 offset)
{
u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
- s32 status = 0;
+ s32 status;
u16 i;
for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
@@ -1185,12 +1146,12 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
IXGBE_EEPROM_PAGE_SIZE_MAX, data);
hw->eeprom.word_page_size = 0;
- if (status != 0)
- goto out;
+ if (status)
+ return status;
status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
- if (status != 0)
- goto out;
+ if (status)
+ return status;
/*
* When writing in burst more than the actual page size
@@ -1200,8 +1161,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
hw_dbg(hw, "Detected EEPROM page size = %d words.\n",
hw->eeprom.word_page_size);
-out:
- return status;
+ return 0;
}
/**
@@ -1230,20 +1190,16 @@ s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data)
{
u32 eewr;
- s32 status = 0;
+ s32 status;
u16 i;
hw->eeprom.ops.init_params(hw);
- if (words == 0) {
- status = IXGBE_ERR_INVALID_ARGUMENT;
- goto out;
- }
+ if (words == 0)
+ return IXGBE_ERR_INVALID_ARGUMENT;
- if (offset >= hw->eeprom.word_size) {
- status = IXGBE_ERR_EEPROM;
- goto out;
- }
+ if (offset >= hw->eeprom.word_size)
+ return IXGBE_ERR_EEPROM;
for (i = 0; i < words; i++) {
eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
@@ -1251,22 +1207,21 @@ s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
IXGBE_EEPROM_RW_REG_START;
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
+ if (status) {
hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
+ return status;
}
IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
- if (status != 0) {
+ if (status) {
hw_dbg(hw, "Eeprom write EEWR timed out\n");
- goto out;
+ return status;
}
}
-out:
- return status;
+ return 0;
}
/**
@@ -1294,7 +1249,6 @@ static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
{
u32 i;
u32 reg;
- s32 status = IXGBE_ERR_EEPROM;
for (i = 0; i < IXGBE_EERD_EEWR_ATTEMPTS; i++) {
if (ee_reg == IXGBE_NVM_POLL_READ)
@@ -1303,12 +1257,11 @@ static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
reg = IXGBE_READ_REG(hw, IXGBE_EEWR);
if (reg & IXGBE_EEPROM_RW_REG_DONE) {
- status = 0;
- break;
+ return 0;
}
udelay(5);
}
- return status;
+ return IXGBE_ERR_EEPROM;
}
/**
@@ -1320,47 +1273,42 @@ static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
**/
static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
{
- s32 status = 0;
u32 eec;
u32 i;
if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
- status = IXGBE_ERR_SWFW_SYNC;
-
- if (status == 0) {
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ return IXGBE_ERR_SWFW_SYNC;
- /* Request EEPROM Access */
- eec |= IXGBE_EEC_REQ;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
- for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
- eec = IXGBE_READ_REG(hw, IXGBE_EEC);
- if (eec & IXGBE_EEC_GNT)
- break;
- udelay(5);
- }
+ /* Request EEPROM Access */
+ eec |= IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- /* Release if grant not acquired */
- if (!(eec & IXGBE_EEC_GNT)) {
- eec &= ~IXGBE_EEC_REQ;
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- hw_dbg(hw, "Could not acquire EEPROM grant\n");
+ for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ if (eec & IXGBE_EEC_GNT)
+ break;
+ udelay(5);
+ }
- hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
- status = IXGBE_ERR_EEPROM;
- }
+ /* Release if grant not acquired */
+ if (!(eec & IXGBE_EEC_GNT)) {
+ eec &= ~IXGBE_EEC_REQ;
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ hw_dbg(hw, "Could not acquire EEPROM grant\n");
- /* Setup EEPROM for Read/Write */
- if (status == 0) {
- /* Clear CS and SK */
- eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
- IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
- IXGBE_WRITE_FLUSH(hw);
- udelay(1);
- }
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return IXGBE_ERR_EEPROM;
}
- return status;
+
+ /* Setup EEPROM for Read/Write */
+ /* Clear CS and SK */
+ eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
+ IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(1);
+ return 0;
}
/**
@@ -1371,7 +1319,6 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
**/
static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_ERR_EEPROM;
u32 timeout = 2000;
u32 i;
u32 swsm;
@@ -1383,68 +1330,60 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
* set and we have the semaphore
*/
swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI)) {
- status = 0;
+ if (!(swsm & IXGBE_SWSM_SMBI))
break;
- }
- udelay(50);
+ usleep_range(50, 100);
}
if (i == timeout) {
hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore not granted.\n");
- /*
- * this release is particularly important because our attempts
+ /* this release is particularly important because our attempts
* above to get the semaphore may have succeeded, and if there
* was a timeout, we should unconditionally clear the semaphore
* bits to free the driver to make progress
*/
ixgbe_release_eeprom_semaphore(hw);
- udelay(50);
- /*
- * one last try
+ usleep_range(50, 100);
+ /* one last try
* If the SMBI bit is 0 when we read it, then the bit will be
* set and we have the semaphore
*/
swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI))
- status = 0;
+ if (swsm & IXGBE_SWSM_SMBI) {
+ hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n");
+ return IXGBE_ERR_EEPROM;
+ }
}
/* Now get the semaphore between SW/FW through the SWESMBI bit */
- if (status == 0) {
- for (i = 0; i < timeout; i++) {
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ for (i = 0; i < timeout; i++) {
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- /* Set the SW EEPROM semaphore bit to request access */
- swsm |= IXGBE_SWSM_SWESMBI;
- IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+ /* Set the SW EEPROM semaphore bit to request access */
+ swsm |= IXGBE_SWSM_SWESMBI;
+ IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
- /*
- * If we set the bit successfully then we got the
- * semaphore.
- */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (swsm & IXGBE_SWSM_SWESMBI)
- break;
+ /* If we set the bit successfully then we got the
+ * semaphore.
+ */
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ if (swsm & IXGBE_SWSM_SWESMBI)
+ break;
- udelay(50);
- }
+ usleep_range(50, 100);
+ }
- /*
- * Release semaphores and return error if SW EEPROM semaphore
- * was not granted because we don't have access to the EEPROM
- */
- if (i >= timeout) {
- hw_dbg(hw, "SWESMBI Software EEPROM semaphore not granted.\n");
- ixgbe_release_eeprom_semaphore(hw);
- status = IXGBE_ERR_EEPROM;
- }
- } else {
- hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n");
+ /* Release semaphores and return error if SW EEPROM semaphore
+ * was not granted because we don't have access to the EEPROM
+ */
+ if (i >= timeout) {
+ hw_dbg(hw, "SWESMBI Software EEPROM semaphore not granted.\n");
+ ixgbe_release_eeprom_semaphore(hw);
+ return IXGBE_ERR_EEPROM;
}
- return status;
+ return 0;
}
/**
@@ -1471,7 +1410,6 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
**/
static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
{
- s32 status = 0;
u16 i;
u8 spi_stat_reg;
@@ -1498,10 +1436,10 @@ static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
*/
if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
hw_dbg(hw, "SPI EEPROM Status error\n");
- status = IXGBE_ERR_EEPROM;
+ return IXGBE_ERR_EEPROM;
}
- return status;
+ return 0;
}
/**
@@ -2100,17 +2038,14 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
**/
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
{
- s32 ret_val = 0;
u32 mflcn_reg, fccfg_reg;
u32 reg;
u32 fcrtl, fcrth;
int i;
/* Validate the water mark configuration. */
- if (!hw->fc.pause_time) {
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
- }
+ if (!hw->fc.pause_time)
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
/* Low water mark of zero causes XOFF floods */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
@@ -2119,8 +2054,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
if (!hw->fc.low_water[i] ||
hw->fc.low_water[i] >= hw->fc.high_water[i]) {
hw_dbg(hw, "Invalid water mark configuration\n");
- ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
- goto out;
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
}
}
}
@@ -2177,9 +2111,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
break;
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = IXGBE_ERR_CONFIG;
- goto out;
- break;
+ return IXGBE_ERR_CONFIG;
}
/* Set 802.3x based flow control settings. */
@@ -2215,8 +2147,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-out:
- return ret_val;
+ return 0;
}
/**
@@ -2277,7 +2208,7 @@ static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
{
u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+ s32 ret_val;
/*
* On multispeed fiber at 1g, bail out if
@@ -2288,7 +2219,7 @@ static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
(!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1))
- goto out;
+ return IXGBE_ERR_FC_NOT_NEGOTIATED;
pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
@@ -2299,7 +2230,6 @@ static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
IXGBE_PCS1GANA_SYM_PAUSE,
IXGBE_PCS1GANA_ASM_PAUSE);
-out:
return ret_val;
}
@@ -2312,7 +2242,7 @@ out:
static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
{
u32 links2, anlp1_reg, autoc_reg, links;
- s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
+ s32 ret_val;
/*
* On backplane, bail out if
@@ -2321,12 +2251,12 @@ static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
*/
links = IXGBE_READ_REG(hw, IXGBE_LINKS);
if ((links & IXGBE_LINKS_KX_AN_COMP) == 0)
- goto out;
+ return IXGBE_ERR_FC_NOT_NEGOTIATED;
if (hw->mac.type == ixgbe_mac_82599EB) {
links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)
- goto out;
+ return IXGBE_ERR_FC_NOT_NEGOTIATED;
}
/*
* Read the 10g AN autoc and LP ability registers and resolve
@@ -2339,7 +2269,6 @@ static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE,
IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE);
-out:
return ret_val;
}
@@ -2485,7 +2414,6 @@ static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
**/
static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
{
- s32 status = 0;
u32 i, poll;
u16 value;
@@ -2495,13 +2423,13 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
/* Exit if master requests are blocked */
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
ixgbe_removed(hw->hw_addr))
- goto out;
+ return 0;
/* Poll for master request bit to clear */
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
udelay(100);
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
- goto out;
+ return 0;
}
/*
@@ -2524,16 +2452,13 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
udelay(100);
value = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_DEVICE_STATUS);
if (ixgbe_removed(hw->hw_addr))
- goto out;
+ return 0;
if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
- goto out;
+ return 0;
}
hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n");
- status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
-
-out:
- return status;
+ return IXGBE_ERR_MASTER_REQUESTS_PENDING;
}
/**
@@ -2708,8 +2633,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
bool link_up = false;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- s32 ret_val = 0;
bool locked = false;
+ s32 ret_val;
/*
* Link must be up to auto-blink the LEDs;
@@ -2720,14 +2645,14 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
if (!link_up) {
ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
if (ret_val)
- goto out;
+ return ret_val;
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
if (ret_val)
- goto out;
+ return ret_val;
IXGBE_WRITE_FLUSH(hw);
@@ -2739,8 +2664,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
-out:
- return ret_val;
+ return 0;
}
/**
@@ -2752,19 +2676,19 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
{
u32 autoc_reg = 0;
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
- s32 ret_val = 0;
bool locked = false;
+ s32 ret_val;
ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
if (ret_val)
- goto out;
+ return ret_val;
autoc_reg &= ~IXGBE_AUTOC_FLU;
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
if (ret_val)
- goto out;
+ return ret_val;
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg &= ~IXGBE_LED_BLINK(index);
@@ -2772,8 +2696,7 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
-out:
- return ret_val;
+ return 0;
}
/**
@@ -2865,7 +2788,7 @@ san_mac_addr_clr:
**/
u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
{
- u16 msix_count = 1;
+ u16 msix_count;
u16 max_msix_count;
u16 pcie_offset;
@@ -2880,7 +2803,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
break;
default:
- return msix_count;
+ return 1;
}
msix_count = ixgbe_read_pci_cfg_word(hw, pcie_offset);
@@ -2918,10 +2841,10 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
if (ixgbe_removed(hw->hw_addr))
- goto done;
+ return 0;
if (!mpsar_lo && !mpsar_hi)
- goto done;
+ return 0;
if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
if (mpsar_lo) {
@@ -2943,7 +2866,6 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
/* was that the last pool using this rar? */
if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
hw->mac.ops.clear_rar(hw, rar);
-done:
return 0;
}
@@ -3312,14 +3234,14 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
if ((alt_san_mac_blk_offset == 0) ||
(alt_san_mac_blk_offset == 0xFFFF))
- goto wwn_prefix_out;
+ return 0;
/* check capability in alternative san mac address block */
offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET;
if (hw->eeprom.ops.read(hw, offset, &caps))
goto wwn_prefix_err;
if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN))
- goto wwn_prefix_out;
+ return 0;
/* get the corresponding prefix for WWNN/WWPN */
offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET;
@@ -3330,7 +3252,6 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix,
if (hw->eeprom.ops.read(hw, offset, wwpn_prefix))
goto wwn_prefix_err;
-wwn_prefix_out:
return 0;
wwn_prefix_err:
@@ -3524,21 +3445,17 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
u8 buf_len, dword_len;
- s32 ret_val = 0;
-
if (length == 0 || length & 0x3 ||
length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
hw_dbg(hw, "Buffer length failure.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
+ return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}
/* Check that the host interface is enabled. */
hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if ((hicr & IXGBE_HICR_EN) == 0) {
hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
+ return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
@@ -3566,8 +3483,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
if (i == IXGBE_HI_COMMAND_TIMEOUT ||
(!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
hw_dbg(hw, "Command has failed with no status valid.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
+ return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs */
@@ -3582,12 +3498,11 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
/* If there is any thing in data position pull it in */
buf_len = ((struct ixgbe_hic_hdr *)buffer)->buf_len;
if (buf_len == 0)
- goto out;
+ return 0;
if (length < (buf_len + hdr_size)) {
hw_dbg(hw, "Buffer not large enough for reply message.\n");
- ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND;
- goto out;
+ return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}
/* Calculate length in DWORDs, add 3 for odd lengths */
@@ -3599,8 +3514,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
le32_to_cpus(&buffer[bi]);
}
-out:
- return ret_val;
+ return 0;
}
/**
@@ -3621,12 +3535,10 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
{
struct ixgbe_hic_drv_info fw_cmd;
int i;
- s32 ret_val = 0;
+ s32 ret_val;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM) != 0) {
- ret_val = IXGBE_ERR_SWFW_SYNC;
- goto out;
- }
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM))
+ return IXGBE_ERR_SWFW_SYNC;
fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN;
@@ -3658,7 +3570,6 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
}
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM);
-out:
return ret_val;
}
@@ -3727,28 +3638,23 @@ static const u8 ixgbe_emc_therm_limit[4] = {
static s32 ixgbe_get_ets_data(struct ixgbe_hw *hw, u16 *ets_cfg,
u16 *ets_offset)
{
- s32 status = 0;
+ s32 status;
status = hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, ets_offset);
if (status)
- goto out;
+ return status;
- if ((*ets_offset == 0x0000) || (*ets_offset == 0xFFFF)) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
+ if ((*ets_offset == 0x0000) || (*ets_offset == 0xFFFF))
+ return IXGBE_NOT_IMPLEMENTED;
status = hw->eeprom.ops.read(hw, *ets_offset, ets_cfg);
if (status)
- goto out;
+ return status;
- if ((*ets_cfg & IXGBE_ETS_TYPE_MASK) != IXGBE_ETS_TYPE_EMC_SHIFTED) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
+ if ((*ets_cfg & IXGBE_ETS_TYPE_MASK) != IXGBE_ETS_TYPE_EMC_SHIFTED)
+ return IXGBE_NOT_IMPLEMENTED;
-out:
- return status;
+ return 0;
}
/**
@@ -3759,7 +3665,7 @@ out:
**/
s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
u16 ets_offset;
u16 ets_cfg;
u16 ets_sensor;
@@ -3768,14 +3674,12 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;
/* Only support thermal sensors attached to physical port 0 */
- if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
+ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1))
+ return IXGBE_NOT_IMPLEMENTED;
status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset);
if (status)
- goto out;
+ return status;
num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK);
if (num_sensors > IXGBE_MAX_SENSORS)
@@ -3788,7 +3692,7 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
status = hw->eeprom.ops.read(hw, (ets_offset + 1 + i),
&ets_sensor);
if (status)
- goto out;
+ return status;
sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >>
IXGBE_ETS_DATA_INDEX_SHIFT);
@@ -3801,11 +3705,11 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw)
IXGBE_I2C_THERMAL_SENSOR_ADDR,
&data->sensor[i].temp);
if (status)
- goto out;
+ return status;
}
}
-out:
- return status;
+
+ return 0;
}
/**
@@ -3817,7 +3721,7 @@ out:
**/
s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
u16 ets_offset;
u16 ets_cfg;
u16 ets_sensor;
@@ -3830,14 +3734,12 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
memset(data, 0, sizeof(struct ixgbe_thermal_sensor_data));
/* Only support thermal sensors attached to physical port 0 */
- if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) {
- status = IXGBE_NOT_IMPLEMENTED;
- goto out;
- }
+ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1))
+ return IXGBE_NOT_IMPLEMENTED;
status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset);
if (status)
- goto out;
+ return status;
low_thresh_delta = ((ets_cfg & IXGBE_ETS_LTHRES_DELTA_MASK) >>
IXGBE_ETS_LTHRES_DELTA_SHIFT);
@@ -3871,7 +3773,7 @@ s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw)
data->sensor[i].caution_thresh = therm_limit;
data->sensor[i].max_op_thresh = therm_limit - low_thresh_delta;
}
-out:
- return status;
+
+ return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
index a689ee0d4bed..48f35fc963f8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -87,7 +87,6 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
int min_credit;
int min_multiplier;
int min_percent = 100;
- s32 ret_val = 0;
/* Initialization values default for Tx settings */
u32 credit_refill = 0;
u32 credit_max = 0;
@@ -95,10 +94,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
u8 bw_percent = 0;
u8 i;
- if (dcb_config == NULL) {
- ret_val = DCB_ERR_CONFIG;
- goto out;
- }
+ if (!dcb_config)
+ return DCB_ERR_CONFIG;
min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
DCB_CREDIT_QUANTUM;
@@ -174,8 +171,7 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
p->data_credits_max = (u16)credit_max;
}
-out:
- return ret_val;
+ return 0;
}
void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
@@ -236,7 +232,7 @@ u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
/* If tc is 0 then DCB is likely not enabled or supported */
if (!tc)
- goto out;
+ return 0;
/*
* Test from maximum TC to 1 and report the first match we find. If
@@ -247,7 +243,7 @@ u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
break;
}
-out:
+
return tc;
}
@@ -269,7 +265,6 @@ void ixgbe_dcb_unpack_map(struct ixgbe_dcb_config *cfg, int direction, u8 *map)
s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
- s32 ret = 0;
u8 pfc_en;
u8 ptype[MAX_TRAFFIC_CLASS];
u8 bwgid[MAX_TRAFFIC_CLASS];
@@ -287,37 +282,31 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- ret = ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
- bwgid, ptype);
- break;
+ return ixgbe_dcb_hw_config_82598(hw, pfc_en, refill, max,
+ bwgid, ptype);
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
- ret = ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
- bwgid, ptype, prio_tc);
- break;
+ return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
+ bwgid, ptype, prio_tc);
default:
break;
}
- return ret;
+ return 0;
}
/* Helper routines to abstract HW specifics from DCB netlink ops */
s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
{
- int ret = -EINVAL;
-
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
- break;
+ return ixgbe_dcb_config_pfc_82598(hw, pfc_en);
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
- ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
- break;
+ return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
default:
break;
}
- return ret;
+ return -EINVAL;
}
s32 ixgbe_dcb_hw_ets(struct ixgbe_hw *hw, struct ieee_ets *ets, int max_frame)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index 5172b6b12c09..58a7f5312a96 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -153,7 +153,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int err = 0;
/* Fail command if not in CEE mode */
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
@@ -161,12 +160,10 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
/* verify there is something to do, if not then exit */
if (!state == !(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
- goto out;
+ return 0;
- err = ixgbe_setup_tc(netdev,
- state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0);
-out:
- return !!err;
+ return !!ixgbe_setup_tc(netdev,
+ state ? adapter->dcb_cfg.num_tcs.pg_tcs : 0);
}
static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
@@ -331,12 +328,12 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
/* Fail command if not in CEE mode */
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return ret;
+ return DCB_NO_HW_CHG;
adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter,
MAX_TRAFFIC_CLASS);
if (!adapter->dcb_set_bitmap)
- return ret;
+ return DCB_NO_HW_CHG;
if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
@@ -460,7 +457,6 @@ static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
break;
default:
return -EINVAL;
- break;
}
} else {
return -EINVAL;
@@ -495,10 +491,10 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
* @id: id is either ether type or TCP/UDP port number
*
* Returns : on success, returns a non-zero 802.1p user priority bitmap
- * otherwise returns 0 as the invalid user priority bitmap to indicate an
+ * otherwise returns -EINVAL as the invalid user priority bitmap to indicate an
* error.
*/
-static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
+static int ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct dcb_app app = {
@@ -507,7 +503,7 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
};
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
- return 0;
+ return -EINVAL;
return dcb_getapp(netdev, &app);
}
@@ -537,7 +533,7 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
- int i, err = 0;
+ int i, err;
__u8 max_tc = 0;
__u8 map_chg = 0;
@@ -574,17 +570,15 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs)
return -EINVAL;
- if (max_tc != netdev_get_num_tc(dev))
+ if (max_tc != netdev_get_num_tc(dev)) {
err = ixgbe_setup_tc(dev, max_tc);
- else if (map_chg)
+ if (err)
+ return err;
+ } else if (map_chg) {
ixgbe_dcbnl_devreset(dev);
+ }
- if (err)
- goto err_out;
-
- err = ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
-err_out:
- return err;
+ return ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
}
static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev,
@@ -648,10 +642,10 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
struct dcb_app *app)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
- int err = -EINVAL;
+ int err;
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
- return err;
+ return -EINVAL;
err = dcb_ieee_setapp(dev, app);
if (err)
@@ -663,7 +657,7 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
u8 app_mask = dcb_ieee_getapp_mask(dev, app);
if (app_mask & (1 << adapter->fcoe.up))
- return err;
+ return 0;
adapter->fcoe.up = app->priority;
ixgbe_dcbnl_devreset(dev);
@@ -706,7 +700,7 @@ static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,
u8 app_mask = dcb_ieee_getapp_mask(dev, app);
if (app_mask & (1 << adapter->fcoe.up))
- return err;
+ return 0;
adapter->fcoe.up = app_mask ?
ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index a452730a3278..e4100b5737b6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1408,7 +1408,6 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
default:
*data = 1;
return 1;
- break;
}
/*
@@ -2518,7 +2517,7 @@ static int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
/* add filter to the list */
if (parent)
- hlist_add_after(&parent->fdir_node, &input->fdir_node);
+ hlist_add_behind(&input->fdir_node, &parent->fdir_node);
else
hlist_add_head(&input->fdir_node,
&adapter->fdir_filter_list);
@@ -2866,7 +2865,6 @@ static int ixgbe_get_ts_info(struct net_device *dev,
break;
default:
return ethtool_op_get_ts_info(dev, info);
- break;
}
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index 25a3dfef33e8..2ad91cb04dab 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -67,23 +67,23 @@ static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp)
*/
int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
{
- int len = 0;
+ int len;
struct ixgbe_fcoe *fcoe;
struct ixgbe_adapter *adapter;
struct ixgbe_fcoe_ddp *ddp;
u32 fcbuff;
if (!netdev)
- goto out_ddp_put;
+ return 0;
if (xid >= IXGBE_FCOE_DDP_MAX)
- goto out_ddp_put;
+ return 0;
adapter = netdev_priv(netdev);
fcoe = &adapter->fcoe;
ddp = &fcoe->ddp[xid];
if (!ddp->udl)
- goto out_ddp_put;
+ return 0;
len = ddp->len;
/* if there an error, force to invalidate ddp context */
@@ -114,7 +114,6 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
ixgbe_fcoe_clear_ddp(ddp);
-out_ddp_put:
return len;
}
@@ -394,17 +393,17 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
xid = be16_to_cpu(fh->fh_rx_id);
if (xid >= IXGBE_FCOE_DDP_MAX)
- goto ddp_out;
+ return -EINVAL;
fcoe = &adapter->fcoe;
ddp = &fcoe->ddp[xid];
if (!ddp->udl)
- goto ddp_out;
+ return -EINVAL;
ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE |
IXGBE_RXDADV_ERR_FCERR);
if (ddp_err)
- goto ddp_out;
+ return -EINVAL;
switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) {
/* return 0 to bypass going to ULD for DDPed data */
@@ -447,7 +446,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
crc->fcoe_eof = FC_EOF_T;
}
-ddp_out:
+
return rc;
}
@@ -878,7 +877,6 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
*/
int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
{
- int rc = -EINVAL;
u16 prefix = 0xffff;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_mac_info *mac = &adapter->hw.mac;
@@ -903,9 +901,9 @@ int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
((u64) mac->san_addr[3] << 16) |
((u64) mac->san_addr[4] << 8) |
((u64) mac->san_addr[5]);
- rc = 0;
+ return 0;
}
- return rc;
+ return -EINVAL;
}
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f5aa3311ea28..5384ed30298a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -570,7 +570,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Print TX Ring Summary */
if (!netdev || !netif_running(netdev))
- goto exit;
+ return;
dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
pr_info(" %s %s %s %s\n",
@@ -685,7 +685,7 @@ rx_ring_summary:
/* Print RX Rings */
if (!netif_msg_rx_status(adapter))
- goto exit;
+ return;
dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
@@ -787,9 +787,6 @@ rx_ring_summary:
}
}
-
-exit:
- return;
}
static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
@@ -1011,7 +1008,6 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
u32 tx_done = ixgbe_get_tx_completed(tx_ring);
u32 tx_done_old = tx_ring->tx_stats.tx_done_old;
u32 tx_pending = ixgbe_get_tx_pending(tx_ring);
- bool ret = false;
clear_check_for_tx_hang(tx_ring);
@@ -1027,18 +1023,16 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
* run the check_tx_hang logic with a transmit completion
* pending but without time to complete it yet.
*/
- if ((tx_done_old == tx_done) && tx_pending) {
+ if (tx_done_old == tx_done && tx_pending)
/* make sure it is true for two checks in a row */
- ret = test_and_set_bit(__IXGBE_HANG_CHECK_ARMED,
- &tx_ring->state);
- } else {
- /* update completed stats and continue */
- tx_ring->tx_stats.tx_done_old = tx_done;
- /* reset the countdown */
- clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state);
- }
+ return test_and_set_bit(__IXGBE_HANG_CHECK_ARMED,
+ &tx_ring->state);
+ /* update completed stats and continue */
+ tx_ring->tx_stats.tx_done_old = tx_done;
+ /* reset the countdown */
+ clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state);
- return ret;
+ return false;
}
/**
@@ -4701,18 +4695,18 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
ret = hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (ret)
- goto link_cfg_out;
+ return ret;
speed = hw->phy.autoneg_advertised;
if ((!speed) && (hw->mac.ops.get_link_capabilities))
ret = hw->mac.ops.get_link_capabilities(hw, &speed,
&autoneg);
if (ret)
- goto link_cfg_out;
+ return ret;
if (hw->mac.ops.setup_link)
ret = hw->mac.ops.setup_link(hw, speed, link_up);
-link_cfg_out:
+
return ret;
}
@@ -7973,23 +7967,32 @@ static const struct net_device_ops ixgbe_netdev_ops = {
**/
static inline int ixgbe_enumerate_functions(struct ixgbe_adapter *adapter)
{
- struct list_head *entry;
+ struct pci_dev *entry, *pdev = adapter->pdev;
int physfns = 0;
/* Some cards can not use the generic count PCIe functions method,
* because they are behind a parent switch, so we hardcode these with
* the correct number of functions.
*/
- if (ixgbe_pcie_from_parent(&adapter->hw)) {
+ if (ixgbe_pcie_from_parent(&adapter->hw))
physfns = 4;
- } else {
- list_for_each(entry, &adapter->pdev->bus_list) {
- struct pci_dev *pdev =
- list_entry(entry, struct pci_dev, bus_list);
- /* don't count virtual functions */
- if (!pdev->is_virtfn)
- physfns++;
- }
+
+ list_for_each_entry(entry, &adapter->pdev->bus->devices, bus_list) {
+ /* don't count virtual functions */
+ if (entry->is_virtfn)
+ continue;
+
+ /* When the devices on the bus don't all match our device ID,
+ * we can't reliably determine the correct number of
+ * functions. This can occur if a function has been direct
+ * attached to a virtual machine using VT-d, for example. In
+ * this case, simply return -1 to indicate this.
+ */
+ if ((entry->vendor != pdev->vendor) ||
+ (entry->device != pdev->device))
+ return -1;
+
+ physfns++;
}
return physfns;
@@ -8161,7 +8164,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->netdev_ops = &ixgbe_netdev_ops;
ixgbe_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;
- strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+ strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
adapter->bd_number = cards_found;
@@ -8384,11 +8387,14 @@ skip_sriov:
expected_gts = ixgbe_enumerate_functions(adapter) * 10;
break;
}
- ixgbe_check_minimum_link(adapter, expected_gts);
- err = ixgbe_read_pba_string_generic(hw, part_str, IXGBE_PBANUM_LENGTH);
+ /* don't check link if we failed to enumerate functions */
+ if (expected_gts > 0)
+ ixgbe_check_minimum_link(adapter, expected_gts);
+
+ err = ixgbe_read_pba_string_generic(hw, part_str, sizeof(part_str));
if (err)
- strncpy(part_str, "Unknown", IXGBE_PBANUM_LENGTH);
+ strlcpy(part_str, "Unknown", sizeof(part_str));
if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
e_dev_info("MAC: %d, PHY: %d, SFP+: %d, PBA No: %s\n",
hw->mac.type, hw->phy.type, hw->phy.sfp_type,
@@ -8477,7 +8483,7 @@ err_alloc_etherdev:
pci_select_bars(pdev, IORESOURCE_MEM));
err_pci_reg:
err_dma:
- if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
+ if (!adapter || !test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
pci_disable_device(pdev);
return err;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
index 1918e0abf734..cc8f0128286c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -43,16 +43,15 @@
s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
/* limit read to size of mailbox */
if (size > mbx->size)
size = mbx->size;
- if (mbx->ops.read)
- ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+ if (!mbx->ops.read)
+ return IXGBE_ERR_MBX;
- return ret_val;
+ return mbx->ops.read(hw, msg, size, mbx_id);
}
/**
@@ -67,15 +66,14 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = 0;
if (size > mbx->size)
- ret_val = IXGBE_ERR_MBX;
+ return IXGBE_ERR_MBX;
- else if (mbx->ops.write)
- ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+ if (!mbx->ops.write)
+ return IXGBE_ERR_MBX;
- return ret_val;
+ return mbx->ops.write(hw, msg, size, mbx_id);
}
/**
@@ -88,12 +86,11 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
- if (mbx->ops.check_for_msg)
- ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+ if (!mbx->ops.check_for_msg)
+ return IXGBE_ERR_MBX;
- return ret_val;
+ return mbx->ops.check_for_msg(hw, mbx_id);
}
/**
@@ -106,12 +103,11 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
- if (mbx->ops.check_for_ack)
- ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+ if (!mbx->ops.check_for_ack)
+ return IXGBE_ERR_MBX;
- return ret_val;
+ return mbx->ops.check_for_ack(hw, mbx_id);
}
/**
@@ -124,12 +120,11 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
- if (mbx->ops.check_for_rst)
- ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+ if (!mbx->ops.check_for_rst)
+ return IXGBE_ERR_MBX;
- return ret_val;
+ return mbx->ops.check_for_rst(hw, mbx_id);
}
/**
@@ -145,17 +140,16 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_msg)
- goto out;
+ return IXGBE_ERR_MBX;
- while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
+ while (mbx->ops.check_for_msg(hw, mbx_id)) {
countdown--;
if (!countdown)
- break;
+ return IXGBE_ERR_MBX;
udelay(mbx->usec_delay);
}
-out:
- return countdown ? 0 : IXGBE_ERR_MBX;
+ return 0;
}
/**
@@ -171,17 +165,16 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_ack)
- goto out;
+ return IXGBE_ERR_MBX;
- while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
+ while (mbx->ops.check_for_ack(hw, mbx_id)) {
countdown--;
if (!countdown)
- break;
+ return IXGBE_ERR_MBX;
udelay(mbx->usec_delay);
}
-out:
- return countdown ? 0 : IXGBE_ERR_MBX;
+ return 0;
}
/**
@@ -198,18 +191,17 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
+ s32 ret_val;
if (!mbx->ops.read)
- goto out;
+ return IXGBE_ERR_MBX;
ret_val = ixgbe_poll_for_msg(hw, mbx_id);
+ if (ret_val)
+ return ret_val;
- /* if ack received read message, otherwise we timed out */
- if (!ret_val)
- ret_val = mbx->ops.read(hw, msg, size, mbx_id);
-out:
- return ret_val;
+ /* if ack received read message */
+ return mbx->ops.read(hw, msg, size, mbx_id);
}
/**
@@ -226,33 +218,31 @@ static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
u16 mbx_id)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
- s32 ret_val = IXGBE_ERR_MBX;
+ s32 ret_val;
/* exit if either we can't write or there isn't a defined timeout */
if (!mbx->ops.write || !mbx->timeout)
- goto out;
+ return IXGBE_ERR_MBX;
/* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+ if (ret_val)
+ return ret_val;
/* if msg sent wait until we receive an ack */
- if (!ret_val)
- ret_val = ixgbe_poll_for_ack(hw, mbx_id);
-out:
- return ret_val;
+ return ixgbe_poll_for_ack(hw, mbx_id);
}
static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
{
u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
- s32 ret_val = IXGBE_ERR_MBX;
if (mbvficr & mask) {
- ret_val = 0;
IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
+ return 0;
}
- return ret_val;
+ return IXGBE_ERR_MBX;
}
/**
@@ -264,17 +254,16 @@ static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
**/
static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
{
- s32 ret_val = IXGBE_ERR_MBX;
s32 index = IXGBE_MBVFICR_INDEX(vf_number);
u32 vf_bit = vf_number % 16;
if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
index)) {
- ret_val = 0;
hw->mbx.stats.reqs++;
+ return 0;
}
- return ret_val;
+ return IXGBE_ERR_MBX;
}
/**
@@ -286,17 +275,16 @@ static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
**/
static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
{
- s32 ret_val = IXGBE_ERR_MBX;
s32 index = IXGBE_MBVFICR_INDEX(vf_number);
u32 vf_bit = vf_number % 16;
if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
index)) {
- ret_val = 0;
hw->mbx.stats.acks++;
+ return 0;
}
- return ret_val;
+ return IXGBE_ERR_MBX;
}
/**
@@ -311,7 +299,6 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
u32 reg_offset = (vf_number < 32) ? 0 : 1;
u32 vf_shift = vf_number % 32;
u32 vflre = 0;
- s32 ret_val = IXGBE_ERR_MBX;
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
@@ -325,12 +312,12 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
}
if (vflre & (1 << vf_shift)) {
- ret_val = 0;
IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
hw->mbx.stats.rsts++;
+ return 0;
}
- return ret_val;
+ return IXGBE_ERR_MBX;
}
/**
@@ -342,7 +329,6 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
**/
static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
{
- s32 ret_val = IXGBE_ERR_MBX;
u32 p2v_mailbox;
/* Take ownership of the buffer */
@@ -351,9 +337,9 @@ static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
/* reserve mailbox for vf use */
p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
- ret_val = 0;
+ return 0;
- return ret_val;
+ return IXGBE_ERR_MBX;
}
/**
@@ -374,7 +360,7 @@ static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
/* lock the mailbox to prevent pf/vf race condition */
ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
- goto out_no_write;
+ return ret_val;
/* flush msg and acks as we are overwriting the message buffer */
ixgbe_check_for_msg_pf(hw, vf_number);
@@ -390,9 +376,7 @@ static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
/* update stats */
hw->mbx.stats.msgs_tx++;
-out_no_write:
- return ret_val;
-
+ return 0;
}
/**
@@ -415,7 +399,7 @@ static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
/* lock the mailbox to prevent pf/vf race condition */
ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
if (ret_val)
- goto out_no_read;
+ return ret_val;
/* copy the message to the mailbox memory buffer */
for (i = 0; i < size; i++)
@@ -427,8 +411,7 @@ static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
/* update stats */
hw->mbx.stats.msgs_rx++;
-out_no_read:
- return ret_val;
+ return 0;
}
#ifdef CONFIG_PCI_IOV
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index ff68b7a9deff..11f02ea78c4a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -57,7 +57,6 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw);
**/
s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
u32 phy_addr;
u16 ext_ability = 0;
@@ -84,18 +83,14 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
ixgbe_phy_generic;
}
- status = 0;
- break;
+ return 0;
}
}
/* clear value if nothing found */
- if (status != 0)
- hw->phy.mdio.prtad = 0;
- } else {
- status = 0;
+ hw->phy.mdio.prtad = 0;
+ return IXGBE_ERR_PHY_ADDR_INVALID;
}
-
- return status;
+ return 0;
}
/**
@@ -192,16 +187,16 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
status = ixgbe_identify_phy_generic(hw);
if (status != 0 || hw->phy.type == ixgbe_phy_none)
- goto out;
+ return status;
/* Don't reset PHY if it's shut down due to overtemp. */
if (!hw->phy.reset_if_overtemp &&
(IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
- goto out;
+ return 0;
/* Blocked by MNG FW so bail */
if (ixgbe_check_reset_blocked(hw))
- goto out;
+ return 0;
/*
* Perform soft PHY reset to the PHY_XS.
@@ -227,12 +222,11 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
}
if (ctrl & MDIO_CTRL1_RESET) {
- status = IXGBE_ERR_RESET_FAILED;
hw_dbg(hw, "PHY reset polling failed to complete.\n");
+ return IXGBE_ERR_RESET_FAILED;
}
-out:
- return status;
+ return 0;
}
/**
@@ -333,7 +327,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
phy_data);
hw->mac.ops.release_swfw_sync(hw, gssr);
} else {
- status = IXGBE_ERR_SWFW_SYNC;
+ return IXGBE_ERR_SWFW_SYNC;
}
return status;
@@ -436,7 +430,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
phy_data);
hw->mac.ops.release_swfw_sync(hw, gssr);
} else {
- status = IXGBE_ERR_SWFW_SYNC;
+ return IXGBE_ERR_SWFW_SYNC;
}
return status;
@@ -509,7 +503,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
/* Blocked by MNG FW so don't reset PHY */
if (ixgbe_check_reset_blocked(hw))
- return status;
+ return 0;
/* Restart PHY autonegotiation and wait for completion */
hw->phy.ops.read_reg(hw, MDIO_CTRL1,
@@ -535,8 +529,8 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
}
if (time_out == max_time_out) {
- status = IXGBE_ERR_LINK_SETUP;
hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out\n");
+ return IXGBE_ERR_LINK_SETUP;
}
return status;
@@ -585,7 +579,7 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
bool *autoneg)
{
- s32 status = IXGBE_ERR_LINK_SETUP;
+ s32 status;
u16 speed_ability;
*speed = 0;
@@ -616,7 +610,7 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up)
{
- s32 status = 0;
+ s32 status;
u32 time_out;
u32 max_time_out = 10;
u16 phy_link = 0;
@@ -662,7 +656,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
**/
s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
{
- s32 status = 0;
+ s32 status;
u32 time_out;
u32 max_time_out = 10;
u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
@@ -719,7 +713,7 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
/* Blocked by MNG FW so don't reset PHY */
if (ixgbe_check_reset_blocked(hw))
- return status;
+ return 0;
/* Restart PHY autonegotiation and wait for completion */
hw->phy.ops.read_reg(hw, MDIO_CTRL1,
@@ -744,8 +738,8 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
}
if (time_out == max_time_out) {
- status = IXGBE_ERR_LINK_SETUP;
hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out\n");
+ return IXGBE_ERR_LINK_SETUP;
}
return status;
@@ -759,7 +753,7 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
u16 *firmware_version)
{
- s32 status = 0;
+ s32 status;
status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
MDIO_MMD_VEND1,
@@ -776,7 +770,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw,
u16 *firmware_version)
{
- s32 status = 0;
+ s32 status;
status = hw->phy.ops.read_reg(hw, AQ_FW_REV,
MDIO_MMD_VEND1,
@@ -795,12 +789,12 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
bool end_data = false;
u16 list_offset, data_offset;
u16 phy_data = 0;
- s32 ret_val = 0;
+ s32 ret_val;
u32 i;
/* Blocked by MNG FW so bail */
if (ixgbe_check_reset_blocked(hw))
- goto out;
+ return 0;
hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
@@ -818,15 +812,14 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
if ((phy_data & MDIO_CTRL1_RESET) != 0) {
hw_dbg(hw, "PHY reset did not complete.\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
+ return IXGBE_ERR_PHY;
}
/* Get init offsets */
ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
&data_offset);
- if (ret_val != 0)
- goto out;
+ if (ret_val)
+ return ret_val;
ret_val = hw->eeprom.ops.read(hw, data_offset, &block_crc);
data_offset++;
@@ -876,18 +869,15 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
hw_dbg(hw, "SOL\n");
} else {
hw_dbg(hw, "Bad control value\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
+ return IXGBE_ERR_PHY;
}
break;
default:
hw_dbg(hw, "Bad control type\n");
- ret_val = IXGBE_ERR_PHY;
- goto out;
+ return IXGBE_ERR_PHY;
}
}
-out:
return ret_val;
err_eeprom:
@@ -903,34 +893,29 @@ err_eeprom:
**/
s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_ERR_SFP_NOT_PRESENT;
-
switch (hw->mac.ops.get_media_type(hw)) {
case ixgbe_media_type_fiber:
- status = ixgbe_identify_sfp_module_generic(hw);
- break;
+ return ixgbe_identify_sfp_module_generic(hw);
case ixgbe_media_type_fiber_qsfp:
- status = ixgbe_identify_qsfp_module_generic(hw);
- break;
+ return ixgbe_identify_qsfp_module_generic(hw);
default:
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- break;
+ return IXGBE_ERR_SFP_NOT_PRESENT;
}
- return status;
+ return IXGBE_ERR_SFP_NOT_PRESENT;
}
/**
* ixgbe_identify_sfp_module_generic - Identifies SFP modules
* @hw: pointer to hardware structure
-*
+ *
* Searches for and identifies the SFP module and assigns appropriate PHY type.
**/
s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
{
struct ixgbe_adapter *adapter = hw->back;
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+ s32 status;
u32 vendor_oui = 0;
enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
u8 identifier = 0;
@@ -943,15 +928,14 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- goto out;
+ return IXGBE_ERR_SFP_NOT_PRESENT;
}
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_IDENTIFIER,
&identifier);
- if (status != 0)
+ if (status)
goto err_read_i2c_eeprom;
/* LAN ID is needed for sfp_type determination */
@@ -959,239 +943,224 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- } else {
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_1GBE_COMP_CODES,
- &comp_codes_1g);
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_1GBE_COMP_CODES,
+ &comp_codes_1g);
- if (status != 0)
- goto err_read_i2c_eeprom;
+ if (status)
+ goto err_read_i2c_eeprom;
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_10GBE_COMP_CODES,
- &comp_codes_10g);
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES,
+ &comp_codes_10g);
- if (status != 0)
- goto err_read_i2c_eeprom;
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_CABLE_TECHNOLOGY,
- &cable_tech);
+ if (status)
+ goto err_read_i2c_eeprom;
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_CABLE_TECHNOLOGY,
+ &cable_tech);
- if (status != 0)
- goto err_read_i2c_eeprom;
+ if (status)
+ goto err_read_i2c_eeprom;
- /* ID Module
- * =========
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
- * 3 SFP_DA_CORE0 - 82599-specific
- * 4 SFP_DA_CORE1 - 82599-specific
- * 5 SFP_SR/LR_CORE0 - 82599-specific
- * 6 SFP_SR/LR_CORE1 - 82599-specific
- * 7 SFP_act_lmt_DA_CORE0 - 82599-specific
- * 8 SFP_act_lmt_DA_CORE1 - 82599-specific
- * 9 SFP_1g_cu_CORE0 - 82599-specific
- * 10 SFP_1g_cu_CORE1 - 82599-specific
- * 11 SFP_1g_sx_CORE0 - 82599-specific
- * 12 SFP_1g_sx_CORE1 - 82599-specific
- */
- if (hw->mac.type == ixgbe_mac_82598EB) {
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
- else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_sr;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_lr;
+ /* ID Module
+ * =========
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CORE0 - 82599-specific
+ * 4 SFP_DA_CORE1 - 82599-specific
+ * 5 SFP_SR/LR_CORE0 - 82599-specific
+ * 6 SFP_SR/LR_CORE1 - 82599-specific
+ * 7 SFP_act_lmt_DA_CORE0 - 82599-specific
+ * 8 SFP_act_lmt_DA_CORE1 - 82599-specific
+ * 9 SFP_1g_cu_CORE0 - 82599-specific
+ * 10 SFP_1g_cu_CORE1 - 82599-specific
+ * 11 SFP_1g_sx_CORE0 - 82599-specific
+ * 12 SFP_1g_sx_CORE1 - 82599-specific
+ */
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_sr;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_lr;
+ else
+ hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core0;
else
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
- } else if (hw->mac.type == ixgbe_mac_82599EB) {
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_cu_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_cu_core1;
- } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
- hw->phy.ops.read_i2c_eeprom(
- hw, IXGBE_SFF_CABLE_SPEC_COMP,
- &cable_spec);
- if (cable_spec &
- IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_act_lmt_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_da_act_lmt_core1;
- } else {
- hw->phy.sfp_type =
- ixgbe_sfp_type_unknown;
- }
- } else if (comp_codes_10g &
- (IXGBE_SFF_10GBASESR_CAPABLE |
- IXGBE_SFF_10GBASELR_CAPABLE)) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_srlr_core1;
- } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_cu_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_cu_core1;
- } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
- if (hw->bus.lan_id == 0)
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_sx_core0;
- else
- hw->phy.sfp_type =
- ixgbe_sfp_type_1g_sx_core1;
- } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core1;
+ } else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) {
+ hw->phy.ops.read_i2c_eeprom(
+ hw, IXGBE_SFF_CABLE_SPEC_COMP,
+ &cable_spec);
+ if (cable_spec &
+ IXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
if (hw->bus.lan_id == 0)
hw->phy.sfp_type =
- ixgbe_sfp_type_1g_lx_core0;
+ ixgbe_sfp_type_da_act_lmt_core0;
else
hw->phy.sfp_type =
- ixgbe_sfp_type_1g_lx_core1;
+ ixgbe_sfp_type_da_act_lmt_core1;
} else {
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_unknown;
}
+ } else if (comp_codes_10g &
+ (IXGBE_SFF_10GBASESR_CAPABLE |
+ IXGBE_SFF_10GBASELR_CAPABLE)) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core1;
+ } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_cu_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_cu_core1;
+ } else if (comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_sx_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_sx_core1;
+ } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_lx_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_lx_core1;
+ } else {
+ hw->phy.sfp_type = ixgbe_sfp_type_unknown;
}
+ }
- if (hw->phy.sfp_type != stored_sfp_type)
- hw->phy.sfp_setup_needed = true;
-
- /* Determine if the SFP+ PHY is dual speed or not. */
- hw->phy.multispeed_fiber = false;
- if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
- (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
- ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
- (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
- hw->phy.multispeed_fiber = true;
-
- /* Determine PHY vendor */
- if (hw->phy.type != ixgbe_phy_nl) {
- hw->phy.id = identifier;
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE0,
- &oui_bytes[0]);
-
- if (status != 0)
- goto err_read_i2c_eeprom;
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE1,
- &oui_bytes[1]);
-
- if (status != 0)
- goto err_read_i2c_eeprom;
-
- status = hw->phy.ops.read_i2c_eeprom(hw,
- IXGBE_SFF_VENDOR_OUI_BYTE2,
- &oui_bytes[2]);
-
- if (status != 0)
- goto err_read_i2c_eeprom;
-
- vendor_oui =
- ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
- (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
- (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
-
- switch (vendor_oui) {
- case IXGBE_SFF_VENDOR_OUI_TYCO:
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_passive_tyco;
- break;
- case IXGBE_SFF_VENDOR_OUI_FTL:
- if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
- hw->phy.type = ixgbe_phy_sfp_ftl_active;
- else
- hw->phy.type = ixgbe_phy_sfp_ftl;
- break;
- case IXGBE_SFF_VENDOR_OUI_AVAGO:
- hw->phy.type = ixgbe_phy_sfp_avago;
- break;
- case IXGBE_SFF_VENDOR_OUI_INTEL:
- hw->phy.type = ixgbe_phy_sfp_intel;
- break;
- default:
- if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_passive_unknown;
- else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
- hw->phy.type =
- ixgbe_phy_sfp_active_unknown;
- else
- hw->phy.type = ixgbe_phy_sfp_unknown;
- break;
- }
- }
+ if (hw->phy.sfp_type != stored_sfp_type)
+ hw->phy.sfp_setup_needed = true;
- /* Allow any DA cable vendor */
- if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
- IXGBE_SFF_DA_ACTIVE_CABLE)) {
- status = 0;
- goto out;
- }
+ /* Determine if the SFP+ PHY is dual speed or not. */
+ hw->phy.multispeed_fiber = false;
+ if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+ ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+ (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+ hw->phy.multispeed_fiber = true;
- /* Verify supported 1G SFP modules */
- if (comp_codes_10g == 0 &&
- !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
- hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
- }
+ /* Determine PHY vendor */
+ if (hw->phy.type != ixgbe_phy_nl) {
+ hw->phy.id = identifier;
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_VENDOR_OUI_BYTE0,
+ &oui_bytes[0]);
- /* Anything else 82598-based is supported */
- if (hw->mac.type == ixgbe_mac_82598EB) {
- status = 0;
- goto out;
- }
+ if (status != 0)
+ goto err_read_i2c_eeprom;
- hw->mac.ops.get_device_caps(hw, &enforce_sfp);
- if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
- !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
- /* Make sure we're a supported PHY type */
- if (hw->phy.type == ixgbe_phy_sfp_intel) {
- status = 0;
- } else {
- if (hw->allow_unsupported_sfp) {
- e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
- status = 0;
- } else {
- hw_dbg(hw,
- "SFP+ module not supported\n");
- hw->phy.type =
- ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- }
- }
- } else {
- status = 0;
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_VENDOR_OUI_BYTE1,
+ &oui_bytes[1]);
+
+ if (status != 0)
+ goto err_read_i2c_eeprom;
+
+ status = hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_VENDOR_OUI_BYTE2,
+ &oui_bytes[2]);
+
+ if (status != 0)
+ goto err_read_i2c_eeprom;
+
+ vendor_oui =
+ ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) |
+ (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) |
+ (oui_bytes[2] << IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT));
+
+ switch (vendor_oui) {
+ case IXGBE_SFF_VENDOR_OUI_TYCO:
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
+ hw->phy.type =
+ ixgbe_phy_sfp_passive_tyco;
+ break;
+ case IXGBE_SFF_VENDOR_OUI_FTL:
+ if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
+ hw->phy.type = ixgbe_phy_sfp_ftl_active;
+ else
+ hw->phy.type = ixgbe_phy_sfp_ftl;
+ break;
+ case IXGBE_SFF_VENDOR_OUI_AVAGO:
+ hw->phy.type = ixgbe_phy_sfp_avago;
+ break;
+ case IXGBE_SFF_VENDOR_OUI_INTEL:
+ hw->phy.type = ixgbe_phy_sfp_intel;
+ break;
+ default:
+ if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
+ hw->phy.type =
+ ixgbe_phy_sfp_passive_unknown;
+ else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
+ hw->phy.type =
+ ixgbe_phy_sfp_active_unknown;
+ else
+ hw->phy.type = ixgbe_phy_sfp_unknown;
+ break;
}
}
-out:
- return status;
+ /* Allow any DA cable vendor */
+ if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
+ IXGBE_SFF_DA_ACTIVE_CABLE))
+ return 0;
+
+ /* Verify supported 1G SFP modules */
+ if (comp_codes_10g == 0 &&
+ !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+
+ /* Anything else 82598-based is supported */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return 0;
+
+ hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+ if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
+ !(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
+ /* Make sure we're a supported PHY type */
+ if (hw->phy.type == ixgbe_phy_sfp_intel)
+ return 0;
+ if (hw->allow_unsupported_sfp) {
+ e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
+ return 0;
+ }
+ hw_dbg(hw, "SFP+ module not supported\n");
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+ return 0;
err_read_i2c_eeprom:
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
@@ -1211,7 +1180,7 @@ err_read_i2c_eeprom:
static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
{
struct ixgbe_adapter *adapter = hw->back;
- s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+ s32 status;
u32 vendor_oui = 0;
enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
u8 identifier = 0;
@@ -1226,8 +1195,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) {
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
- status = IXGBE_ERR_SFP_NOT_PRESENT;
- goto out;
+ return IXGBE_ERR_SFP_NOT_PRESENT;
}
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
@@ -1238,8 +1206,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
}
hw->phy.id = identifier;
@@ -1310,8 +1277,7 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
} else {
/* unsupported module type */
hw->phy.type = ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- goto out;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
}
}
@@ -1363,27 +1329,19 @@ static s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
hw->mac.ops.get_device_caps(hw, &enforce_sfp);
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
/* Make sure we're a supported PHY type */
- if (hw->phy.type == ixgbe_phy_qsfp_intel) {
- status = 0;
- } else {
- if (hw->allow_unsupported_sfp == true) {
- e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
- status = 0;
- } else {
- hw_dbg(hw,
- "QSFP module not supported\n");
- hw->phy.type =
- ixgbe_phy_sfp_unsupported;
- status = IXGBE_ERR_SFP_NOT_SUPPORTED;
- }
+ if (hw->phy.type == ixgbe_phy_qsfp_intel)
+ return 0;
+ if (hw->allow_unsupported_sfp) {
+ e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
+ return 0;
}
- } else {
- status = 0;
+ hw_dbg(hw, "QSFP module not supported\n");
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
}
+ return 0;
}
-
-out:
- return status;
+ return 0;
err_read_i2c_eeprom:
hw->phy.sfp_type = ixgbe_sfp_type_not_present;
@@ -1544,7 +1502,7 @@ s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data)
{
- s32 status = 0;
+ s32 status;
u32 max_retry = 10;
u32 retry = 0;
u16 swfw_mask = 0;
@@ -1557,10 +1515,8 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
swfw_mask = IXGBE_GSSR_PHY0_SM;
do {
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
- status = IXGBE_ERR_SWFW_SYNC;
- goto read_byte_out;
- }
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return IXGBE_ERR_SWFW_SYNC;
ixgbe_i2c_start(hw);
@@ -1617,7 +1573,6 @@ fail:
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-read_byte_out:
return status;
}
@@ -1633,7 +1588,7 @@ read_byte_out:
s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data)
{
- s32 status = 0;
+ s32 status;
u32 max_retry = 1;
u32 retry = 0;
u16 swfw_mask = 0;
@@ -1643,10 +1598,8 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
else
swfw_mask = IXGBE_GSSR_PHY0_SM;
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
- status = IXGBE_ERR_SWFW_SYNC;
- goto write_byte_out;
- }
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return IXGBE_ERR_SWFW_SYNC;
do {
ixgbe_i2c_start(hw);
@@ -1689,7 +1642,6 @@ fail:
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-write_byte_out:
return status;
}
@@ -1774,7 +1726,7 @@ static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
**/
static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
{
- s32 status = 0;
+ s32 status;
s32 i;
u32 i2cctl;
bool bit = false;
@@ -1893,11 +1845,11 @@ static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
*/
udelay(IXGBE_I2C_T_LOW);
} else {
- status = IXGBE_ERR_I2C;
hw_dbg(hw, "I2C data was not set to %X\n", data);
+ return IXGBE_ERR_I2C;
}
- return status;
+ return 0;
}
/**
* ixgbe_raise_i2c_clk - Raises the I2C SCL clock
@@ -1954,8 +1906,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
**/
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
{
- s32 status = 0;
-
if (data)
*i2cctl |= IXGBE_I2C_DATA_OUT;
else
@@ -1970,11 +1920,11 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
/* Verify data was set correctly */
*i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
if (data != ixgbe_get_i2c_data(i2cctl)) {
- status = IXGBE_ERR_I2C;
hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
+ return IXGBE_ERR_I2C;
}
- return status;
+ return 0;
}
/**
@@ -1986,14 +1936,9 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
**/
static bool ixgbe_get_i2c_data(u32 *i2cctl)
{
- bool data;
-
if (*i2cctl & IXGBE_I2C_DATA_IN)
- data = true;
- else
- data = false;
-
- return data;
+ return true;
+ return false;
}
/**
@@ -2038,20 +1983,17 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
**/
s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
{
- s32 status = 0;
u16 phy_data = 0;
if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
- goto out;
+ return 0;
/* Check that the LASI temp alarm status was triggered */
hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
MDIO_MMD_PMAPMD, &phy_data);
if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
- goto out;
+ return 0;
- status = IXGBE_ERR_OVERTEMP;
-out:
- return status;
+ return IXGBE_ERR_OVERTEMP;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 68f87ecb8a76..5fd4b5271f9a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -98,9 +98,11 @@
#define IXGBE_OVERFLOW_PERIOD (HZ * 30)
#define IXGBE_PTP_TX_TIMEOUT (HZ * 15)
-#ifndef NSECS_PER_SEC
-#define NSECS_PER_SEC 1000000000ULL
-#endif
+/* half of a one second clock period, for use with PPS signal. We have to use
+ * this instead of something pre-defined like IXGBE_PTP_PPS_HALF_SECOND, in
+ * order to force at least 64bits of precision for shifting
+ */
+#define IXGBE_PTP_PPS_HALF_SECOND 500000000ULL
/**
* ixgbe_ptp_setup_sdp
@@ -146,8 +148,8 @@ static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter)
IXGBE_TSAUXC_SDP0_INT);
/* clock period (or pulse length) */
- clktiml = (u32)(NSECS_PER_SEC << shift);
- clktimh = (u32)((NSECS_PER_SEC << shift) >> 32);
+ clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift);
+ clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32);
/*
* Account for the cyclecounter wrap-around value by
@@ -158,8 +160,8 @@ static void ixgbe_ptp_setup_sdp(struct ixgbe_adapter *adapter)
clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
ns = timecounter_cyc2time(&adapter->tc, clock_edge);
- div_u64_rem(ns, NSECS_PER_SEC, &rem);
- clock_edge += ((NSECS_PER_SEC - (u64)rem) << shift);
+ div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem);
+ clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift);
/* specify the initial clock start time */
trgttiml = (u32)clock_edge;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 16b3a1cd9db6..c14d4d89672f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -245,10 +245,10 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
if (pre_existing_vfs && pre_existing_vfs != num_vfs)
err = ixgbe_disable_sriov(adapter);
else if (pre_existing_vfs && pre_existing_vfs == num_vfs)
- goto out;
+ return num_vfs;
if (err)
- goto err_out;
+ return err;
/* While the SR-IOV capability structure reports total VFs to be
* 64 we limit the actual number that can be allocated to 63 so
@@ -256,16 +256,14 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
* PF. The PCI bus driver already checks for other values out of
* range.
*/
- if (num_vfs > IXGBE_MAX_VFS_DRV_LIMIT) {
- err = -EPERM;
- goto err_out;
- }
+ if (num_vfs > IXGBE_MAX_VFS_DRV_LIMIT)
+ return -EPERM;
adapter->num_vfs = num_vfs;
err = __ixgbe_enable_sriov(adapter);
if (err)
- goto err_out;
+ return err;
for (i = 0; i < adapter->num_vfs; i++)
ixgbe_vf_configuration(dev, (i | 0x10000000));
@@ -273,17 +271,14 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
err = pci_enable_sriov(dev, num_vfs);
if (err) {
e_dev_warn("Failed to enable PCI sriov: %d\n", err);
- goto err_out;
+ return err;
}
ixgbe_sriov_reinit(adapter);
-out:
return num_vfs;
-
-err_out:
- return err;
-#endif
+#else
return 0;
+#endif
}
static int ixgbe_pci_sriov_disable(struct pci_dev *dev)
@@ -807,7 +802,7 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
if (!add && adapter->netdev->flags & IFF_PROMISC) {
reg_ndx = ixgbe_find_vlvf_entry(hw, vid);
if (reg_ndx < 0)
- goto out;
+ return err;
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(reg_ndx));
/* See if any other pools are set for this VLAN filter
* entry other than the PF.
@@ -833,8 +828,6 @@ static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
ixgbe_set_vf_vlan(adapter, add, vid, VMDQ_P(0));
}
-out:
-
return err;
}
@@ -951,7 +944,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
/* this is a message we already processed, do nothing */
if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK))
- return retval;
+ return 0;
/* flush the ack before we write any messages back */
IXGBE_WRITE_FLUSH(hw);
@@ -966,7 +959,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
if (!adapter->vfinfo[vf].clear_to_send) {
msgbuf[0] |= IXGBE_VT_MSGTYPE_NACK;
ixgbe_write_mbx(hw, msgbuf, 1, vf);
- return retval;
+ return 0;
}
switch ((msgbuf[0] & 0xFFFF)) {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 9a89f98b35f0..e6b07c2a01fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2440,25 +2440,6 @@ typedef u32 ixgbe_link_speed;
IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
-
-/* Physical layer type */
-typedef u32 ixgbe_physical_layer;
-#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0
-#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001
-#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004
-#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008
-#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010
-#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020
-#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040
-#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080
-#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100
-#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
-#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
-#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800
-#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
-#define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000
-
/* Flow Control Data Sheet defined values
* Calculation and defines taken from 802.1bb Annex O
*/
@@ -2860,7 +2841,6 @@ struct ixgbe_mac_operations {
s32 (*start_hw)(struct ixgbe_hw *);
s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
- u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index 40dd798e1290..e88305d5d18d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2013 Intel Corporation.
+ Copyright(c) 1999 - 2014 Intel 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,
@@ -99,8 +99,8 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
status = hw->mac.ops.stop_adapter(hw);
- if (status != 0)
- goto reset_hw_out;
+ if (status)
+ return status;
/* flush pending Tx transactions */
ixgbe_clear_tx_pending(hw);
@@ -168,7 +168,6 @@ mac_reset_top:
hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix,
&hw->mac.wwpn_prefix);
-reset_hw_out:
return status;
}
@@ -182,40 +181,13 @@ reset_hw_out:
**/
static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
{
- s32 ret_val = 0;
+ s32 ret_val;
ret_val = ixgbe_start_hw_generic(hw);
- if (ret_val != 0)
- goto out;
+ if (ret_val)
+ return ret_val;
- ret_val = ixgbe_start_hw_gen2(hw);
-out:
- return ret_val;
-}
-
-/**
- * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
- * @hw: pointer to hardware structure
- *
- * Determines physical layer capabilities of the current configuration.
- **/
-static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
-{
- u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
- u16 ext_ability = 0;
-
- hw->phy.ops.identify(hw);
-
- hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
- &ext_ability);
- if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
- physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
- if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
- physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
-
- return physical_layer;
+ return ixgbe_start_hw_gen2(hw);
}
/**
@@ -258,13 +230,12 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
**/
static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
{
- s32 status = 0;
+ s32 status;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_read_eerd_generic(hw, offset, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ status = ixgbe_read_eerd_generic(hw, offset, data);
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
@@ -282,14 +253,12 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
u16 offset, u16 words, u16 *data)
{
- s32 status = 0;
+ s32 status;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_read_eerd_buffer_generic(hw, offset,
- words, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data);
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
@@ -305,12 +274,12 @@ static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
**/
static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
{
- s32 status = 0;
+ s32 status;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
- status = ixgbe_write_eewr_generic(hw, offset, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ status = ixgbe_write_eewr_generic(hw, offset, data);
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
@@ -328,14 +297,12 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
u16 offset, u16 words, u16 *data)
{
- s32 status = 0;
+ s32 status;
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
- 0)
- status = ixgbe_write_eewr_buffer_generic(hw, offset,
- words, data);
- else
- status = IXGBE_ERR_SWFW_SYNC;
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
+
+ status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data);
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
return status;
@@ -430,44 +397,37 @@ static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
u16 checksum;
u16 read_checksum = 0;
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
+ /* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != 0) {
+ if (status) {
hw_dbg(hw, "EEPROM read failed\n");
- goto out;
+ return status;
}
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
- /*
- * Do not use hw->eeprom.ops.read because we do not want to take
- * the synchronization semaphores twice here.
- */
- ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
- &read_checksum);
+ checksum = hw->eeprom.ops.calc_checksum(hw);
- /*
- * Verify read checksum from EEPROM is the same as
- * calculated checksum
- */
- if (read_checksum != checksum)
- status = IXGBE_ERR_EEPROM_CHECKSUM;
-
- /* If the user cares, return the calculated checksum */
- if (checksum_val)
- *checksum_val = checksum;
- } else {
- status = IXGBE_ERR_SWFW_SYNC;
- }
+ /* Do not use hw->eeprom.ops.read because we do not want to take
+ * the synchronization semaphores twice here.
+ */
+ status = ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
+ &read_checksum);
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
-out:
+
+ /* If the user cares, return the calculated checksum */
+ if (checksum_val)
+ *checksum_val = checksum;
+
+ /* Verify read and calculated checksums are the same */
+ if (read_checksum != checksum)
+ return IXGBE_ERR_EEPROM_CHECKSUM;
+
return status;
}
@@ -484,34 +444,29 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
s32 status;
u16 checksum;
- /*
- * Read the first word from the EEPROM. If this times out or fails, do
+ /* Read the first word from the EEPROM. If this times out or fails, do
* not continue or we could be in for a very long wait while every
* EEPROM read fails
*/
status = hw->eeprom.ops.read(hw, 0, &checksum);
-
- if (status != 0)
+ if (status) {
hw_dbg(hw, "EEPROM read failed\n");
+ return status;
+ }
- if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
- checksum = hw->eeprom.ops.calc_checksum(hw);
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM))
+ return IXGBE_ERR_SWFW_SYNC;
- /*
- * Do not use hw->eeprom.ops.write because we do not want to
- * take the synchronization semaphores twice here.
- */
- status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
- checksum);
+ checksum = hw->eeprom.ops.calc_checksum(hw);
- if (status == 0)
+ /* Do not use hw->eeprom.ops.write because we do not want to
+ * take the synchronization semaphores twice here.
+ */
+ status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM, checksum);
+ if (!status)
status = ixgbe_update_flash_X540(hw);
- else
- status = IXGBE_ERR_SWFW_SYNC;
- }
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
-
return status;
}
@@ -525,12 +480,12 @@ static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
{
u32 flup;
- s32 status = IXGBE_ERR_EEPROM;
+ s32 status;
status = ixgbe_poll_flash_update_done_X540(hw);
if (status == IXGBE_ERR_EEPROM) {
hw_dbg(hw, "Flash update time out\n");
- goto out;
+ return status;
}
flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP;
@@ -556,7 +511,7 @@ static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw)
else
hw_dbg(hw, "Flash update time out\n");
}
-out:
+
return status;
}
@@ -571,17 +526,14 @@ static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
{
u32 i;
u32 reg;
- s32 status = IXGBE_ERR_EEPROM;
for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) {
reg = IXGBE_READ_REG(hw, IXGBE_EEC);
- if (reg & IXGBE_EEC_FLUDONE) {
- status = 0;
- break;
- }
+ if (reg & IXGBE_EEC_FLUDONE)
+ return 0;
udelay(5);
}
- return status;
+ return IXGBE_ERR_EEPROM;
}
/**
@@ -676,46 +628,44 @@ static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask)
}
/**
- * ixgbe_get_nvm_semaphore - Get hardware semaphore
+ * ixgbe_get_swfw_sync_semaphore - Get hardware semaphore
* @hw: pointer to hardware structure
*
* Sets the hardware semaphores so SW/FW can gain control of shared resources
- **/
+ */
static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
{
- s32 status = IXGBE_ERR_EEPROM;
u32 timeout = 2000;
u32 i;
u32 swsm;
/* Get SMBI software semaphore between device drivers first */
for (i = 0; i < timeout; i++) {
- /*
- * If the SMBI bit is 0 when we read it, then the bit will be
+ /* If the SMBI bit is 0 when we read it, then the bit will be
* set and we have the semaphore
*/
swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- if (!(swsm & IXGBE_SWSM_SMBI)) {
- status = 0;
+ if (!(swsm & IXGBE_SWSM_SMBI))
break;
- }
- udelay(50);
+ usleep_range(50, 100);
+ }
+
+ if (i == timeout) {
+ hw_dbg(hw,
+ "Software semaphore SMBI between device drivers not granted.\n");
+ return IXGBE_ERR_EEPROM;
}
/* Now get the semaphore between SW/FW through the REGSMP bit */
- if (status) {
- for (i = 0; i < timeout; i++) {
- swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
- if (!(swsm & IXGBE_SWFW_REGSMP))
- break;
+ for (i = 0; i < timeout; i++) {
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
+ if (!(swsm & IXGBE_SWFW_REGSMP))
+ return 0;
- udelay(50);
- }
- } else {
- hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n");
+ usleep_range(50, 100);
}
- return status;
+ return IXGBE_ERR_EEPROM;
}
/**
@@ -811,8 +761,6 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.start_hw = &ixgbe_start_hw_X540,
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_X540,
- .get_supported_physical_layer =
- &ixgbe_get_supported_physical_layer_X540,
.enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic,
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h
index 3061d1890471..aa8cc8dc25d1 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.h
@@ -49,7 +49,6 @@ struct ixgbe_mac_operations {
s32 (*start_hw)(struct ixgbe_hw *);
s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
- u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
s32 (*stop_adapter)(struct ixgbe_hw *);
s32 (*get_bus_info)(struct ixgbe_hw *);
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
index 68e6a6613e9a..1b4fc7c639e6 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -54,6 +54,14 @@ config MVNETA
driver, which should be used for the older Marvell SoCs
(Dove, Orion, Discovery, Kirkwood).
+config MVPP2
+ tristate "Marvell Armada 375 network interface support"
+ depends on MACH_ARMADA_375
+ select MVMDIO
+ ---help---
+ This driver supports the network interface units in the
+ Marvell ARMADA 375 SoC.
+
config PXA168_ETH
tristate "Marvell pxa168 ethernet support"
depends on CPU_PXA168
diff --git a/drivers/net/ethernet/marvell/Makefile b/drivers/net/ethernet/marvell/Makefile
index 5c4a7765ff0e..f6425bd2884b 100644
--- a/drivers/net/ethernet/marvell/Makefile
+++ b/drivers/net/ethernet/marvell/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_MVMDIO) += mvmdio.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
obj-$(CONFIG_MVNETA) += mvneta.o
+obj-$(CONFIG_MVPP2) += mvpp2.o
obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 45beca17fa50..dadd9a5f6323 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1207,7 +1207,7 @@ static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto,
command = l3_offs << MVNETA_TX_L3_OFF_SHIFT;
command |= ip_hdr_len << MVNETA_TX_IP_HLEN_SHIFT;
- if (l3_proto == swab16(ETH_P_IP))
+ if (l3_proto == htons(ETH_P_IP))
command |= MVNETA_TXD_IP_CSUM;
else
command |= MVNETA_TX_L3_IP6;
@@ -2529,7 +2529,7 @@ static void mvneta_adjust_link(struct net_device *ndev)
if (phydev->speed == SPEED_1000)
val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
- else
+ else if (phydev->speed == SPEED_100)
val |= MVNETA_GMAC_CONFIG_MII_SPEED;
mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
new file mode 100644
index 000000000000..ece83f101526
--- /dev/null
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -0,0 +1,6426 @@
+/*
+ * Driver for Marvell PPv2 network controller for Armada 375 SoC.
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Marcin Wojtas <mw@semihalf.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/inetdevice.h>
+#include <linux/mbus.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/cpumask.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_address.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+#include <uapi/linux/ppp_defs.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+/* RX Fifo Registers */
+#define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port))
+#define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port))
+#define MVPP2_RX_MIN_PKT_SIZE_REG 0x60
+#define MVPP2_RX_FIFO_INIT_REG 0x64
+
+/* RX DMA Top Registers */
+#define MVPP2_RX_CTRL_REG(port) (0x140 + 4 * (port))
+#define MVPP2_RX_LOW_LATENCY_PKT_SIZE(s) (((s) & 0xfff) << 16)
+#define MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK BIT(31)
+#define MVPP2_POOL_BUF_SIZE_REG(pool) (0x180 + 4 * (pool))
+#define MVPP2_POOL_BUF_SIZE_OFFSET 5
+#define MVPP2_RXQ_CONFIG_REG(rxq) (0x800 + 4 * (rxq))
+#define MVPP2_SNOOP_PKT_SIZE_MASK 0x1ff
+#define MVPP2_SNOOP_BUF_HDR_MASK BIT(9)
+#define MVPP2_RXQ_POOL_SHORT_OFFS 20
+#define MVPP2_RXQ_POOL_SHORT_MASK 0x700000
+#define MVPP2_RXQ_POOL_LONG_OFFS 24
+#define MVPP2_RXQ_POOL_LONG_MASK 0x7000000
+#define MVPP2_RXQ_PACKET_OFFSET_OFFS 28
+#define MVPP2_RXQ_PACKET_OFFSET_MASK 0x70000000
+#define MVPP2_RXQ_DISABLE_MASK BIT(31)
+
+/* Parser Registers */
+#define MVPP2_PRS_INIT_LOOKUP_REG 0x1000
+#define MVPP2_PRS_PORT_LU_MAX 0xf
+#define MVPP2_PRS_PORT_LU_MASK(port) (0xff << ((port) * 4))
+#define MVPP2_PRS_PORT_LU_VAL(port, val) ((val) << ((port) * 4))
+#define MVPP2_PRS_INIT_OFFS_REG(port) (0x1004 + ((port) & 4))
+#define MVPP2_PRS_INIT_OFF_MASK(port) (0x3f << (((port) % 4) * 8))
+#define MVPP2_PRS_INIT_OFF_VAL(port, val) ((val) << (((port) % 4) * 8))
+#define MVPP2_PRS_MAX_LOOP_REG(port) (0x100c + ((port) & 4))
+#define MVPP2_PRS_MAX_LOOP_MASK(port) (0xff << (((port) % 4) * 8))
+#define MVPP2_PRS_MAX_LOOP_VAL(port, val) ((val) << (((port) % 4) * 8))
+#define MVPP2_PRS_TCAM_IDX_REG 0x1100
+#define MVPP2_PRS_TCAM_DATA_REG(idx) (0x1104 + (idx) * 4)
+#define MVPP2_PRS_TCAM_INV_MASK BIT(31)
+#define MVPP2_PRS_SRAM_IDX_REG 0x1200
+#define MVPP2_PRS_SRAM_DATA_REG(idx) (0x1204 + (idx) * 4)
+#define MVPP2_PRS_TCAM_CTRL_REG 0x1230
+#define MVPP2_PRS_TCAM_EN_MASK BIT(0)
+
+/* Classifier Registers */
+#define MVPP2_CLS_MODE_REG 0x1800
+#define MVPP2_CLS_MODE_ACTIVE_MASK BIT(0)
+#define MVPP2_CLS_PORT_WAY_REG 0x1810
+#define MVPP2_CLS_PORT_WAY_MASK(port) (1 << (port))
+#define MVPP2_CLS_LKP_INDEX_REG 0x1814
+#define MVPP2_CLS_LKP_INDEX_WAY_OFFS 6
+#define MVPP2_CLS_LKP_TBL_REG 0x1818
+#define MVPP2_CLS_LKP_TBL_RXQ_MASK 0xff
+#define MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK BIT(25)
+#define MVPP2_CLS_FLOW_INDEX_REG 0x1820
+#define MVPP2_CLS_FLOW_TBL0_REG 0x1824
+#define MVPP2_CLS_FLOW_TBL1_REG 0x1828
+#define MVPP2_CLS_FLOW_TBL2_REG 0x182c
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port) (0x1980 + ((port) * 4))
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS 3
+#define MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK 0x7
+#define MVPP2_CLS_SWFWD_P2HQ_REG(port) (0x19b0 + ((port) * 4))
+#define MVPP2_CLS_SWFWD_PCTRL_REG 0x19d0
+#define MVPP2_CLS_SWFWD_PCTRL_MASK(port) (1 << (port))
+
+/* Descriptor Manager Top Registers */
+#define MVPP2_RXQ_NUM_REG 0x2040
+#define MVPP2_RXQ_DESC_ADDR_REG 0x2044
+#define MVPP2_RXQ_DESC_SIZE_REG 0x2048
+#define MVPP2_RXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_RXQ_STATUS_UPDATE_REG(rxq) (0x3000 + 4 * (rxq))
+#define MVPP2_RXQ_NUM_PROCESSED_OFFSET 0
+#define MVPP2_RXQ_NUM_NEW_OFFSET 16
+#define MVPP2_RXQ_STATUS_REG(rxq) (0x3400 + 4 * (rxq))
+#define MVPP2_RXQ_OCCUPIED_MASK 0x3fff
+#define MVPP2_RXQ_NON_OCCUPIED_OFFSET 16
+#define MVPP2_RXQ_NON_OCCUPIED_MASK 0x3fff0000
+#define MVPP2_RXQ_THRESH_REG 0x204c
+#define MVPP2_OCCUPIED_THRESH_OFFSET 0
+#define MVPP2_OCCUPIED_THRESH_MASK 0x3fff
+#define MVPP2_RXQ_INDEX_REG 0x2050
+#define MVPP2_TXQ_NUM_REG 0x2080
+#define MVPP2_TXQ_DESC_ADDR_REG 0x2084
+#define MVPP2_TXQ_DESC_SIZE_REG 0x2088
+#define MVPP2_TXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_AGGR_TXQ_UPDATE_REG 0x2090
+#define MVPP2_TXQ_THRESH_REG 0x2094
+#define MVPP2_TRANSMITTED_THRESH_OFFSET 16
+#define MVPP2_TRANSMITTED_THRESH_MASK 0x3fff0000
+#define MVPP2_TXQ_INDEX_REG 0x2098
+#define MVPP2_TXQ_PREF_BUF_REG 0x209c
+#define MVPP2_PREF_BUF_PTR(desc) ((desc) & 0xfff)
+#define MVPP2_PREF_BUF_SIZE_4 (BIT(12) | BIT(13))
+#define MVPP2_PREF_BUF_SIZE_16 (BIT(12) | BIT(14))
+#define MVPP2_PREF_BUF_THRESH(val) ((val) << 17)
+#define MVPP2_TXQ_DRAIN_EN_MASK BIT(31)
+#define MVPP2_TXQ_PENDING_REG 0x20a0
+#define MVPP2_TXQ_PENDING_MASK 0x3fff
+#define MVPP2_TXQ_INT_STATUS_REG 0x20a4
+#define MVPP2_TXQ_SENT_REG(txq) (0x3c00 + 4 * (txq))
+#define MVPP2_TRANSMITTED_COUNT_OFFSET 16
+#define MVPP2_TRANSMITTED_COUNT_MASK 0x3fff0000
+#define MVPP2_TXQ_RSVD_REQ_REG 0x20b0
+#define MVPP2_TXQ_RSVD_REQ_Q_OFFSET 16
+#define MVPP2_TXQ_RSVD_RSLT_REG 0x20b4
+#define MVPP2_TXQ_RSVD_RSLT_MASK 0x3fff
+#define MVPP2_TXQ_RSVD_CLR_REG 0x20b8
+#define MVPP2_TXQ_RSVD_CLR_OFFSET 16
+#define MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu) (0x2100 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu) (0x2140 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_DESC_SIZE_MASK 0x3ff0
+#define MVPP2_AGGR_TXQ_STATUS_REG(cpu) (0x2180 + 4 * (cpu))
+#define MVPP2_AGGR_TXQ_PENDING_MASK 0x3fff
+#define MVPP2_AGGR_TXQ_INDEX_REG(cpu) (0x21c0 + 4 * (cpu))
+
+/* MBUS bridge registers */
+#define MVPP2_WIN_BASE(w) (0x4000 + ((w) << 2))
+#define MVPP2_WIN_SIZE(w) (0x4020 + ((w) << 2))
+#define MVPP2_WIN_REMAP(w) (0x4040 + ((w) << 2))
+#define MVPP2_BASE_ADDR_ENABLE 0x4060
+
+/* Interrupt Cause and Mask registers */
+#define MVPP2_ISR_RX_THRESHOLD_REG(rxq) (0x5200 + 4 * (rxq))
+#define MVPP2_ISR_RXQ_GROUP_REG(rxq) (0x5400 + 4 * (rxq))
+#define MVPP2_ISR_ENABLE_REG(port) (0x5420 + 4 * (port))
+#define MVPP2_ISR_ENABLE_INTERRUPT(mask) ((mask) & 0xffff)
+#define MVPP2_ISR_DISABLE_INTERRUPT(mask) (((mask) << 16) & 0xffff0000)
+#define MVPP2_ISR_RX_TX_CAUSE_REG(port) (0x5480 + 4 * (port))
+#define MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK 0xffff
+#define MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK 0xff0000
+#define MVPP2_CAUSE_RX_FIFO_OVERRUN_MASK BIT(24)
+#define MVPP2_CAUSE_FCS_ERR_MASK BIT(25)
+#define MVPP2_CAUSE_TX_FIFO_UNDERRUN_MASK BIT(26)
+#define MVPP2_CAUSE_TX_EXCEPTION_SUM_MASK BIT(29)
+#define MVPP2_CAUSE_RX_EXCEPTION_SUM_MASK BIT(30)
+#define MVPP2_CAUSE_MISC_SUM_MASK BIT(31)
+#define MVPP2_ISR_RX_TX_MASK_REG(port) (0x54a0 + 4 * (port))
+#define MVPP2_ISR_PON_RX_TX_MASK_REG 0x54bc
+#define MVPP2_PON_CAUSE_RXQ_OCCUP_DESC_ALL_MASK 0xffff
+#define MVPP2_PON_CAUSE_TXP_OCCUP_DESC_ALL_MASK 0x3fc00000
+#define MVPP2_PON_CAUSE_MISC_SUM_MASK BIT(31)
+#define MVPP2_ISR_MISC_CAUSE_REG 0x55b0
+
+/* Buffer Manager registers */
+#define MVPP2_BM_POOL_BASE_REG(pool) (0x6000 + ((pool) * 4))
+#define MVPP2_BM_POOL_BASE_ADDR_MASK 0xfffff80
+#define MVPP2_BM_POOL_SIZE_REG(pool) (0x6040 + ((pool) * 4))
+#define MVPP2_BM_POOL_SIZE_MASK 0xfff0
+#define MVPP2_BM_POOL_READ_PTR_REG(pool) (0x6080 + ((pool) * 4))
+#define MVPP2_BM_POOL_GET_READ_PTR_MASK 0xfff0
+#define MVPP2_BM_POOL_PTRS_NUM_REG(pool) (0x60c0 + ((pool) * 4))
+#define MVPP2_BM_POOL_PTRS_NUM_MASK 0xfff0
+#define MVPP2_BM_BPPI_READ_PTR_REG(pool) (0x6100 + ((pool) * 4))
+#define MVPP2_BM_BPPI_PTRS_NUM_REG(pool) (0x6140 + ((pool) * 4))
+#define MVPP2_BM_BPPI_PTR_NUM_MASK 0x7ff
+#define MVPP2_BM_BPPI_PREFETCH_FULL_MASK BIT(16)
+#define MVPP2_BM_POOL_CTRL_REG(pool) (0x6200 + ((pool) * 4))
+#define MVPP2_BM_START_MASK BIT(0)
+#define MVPP2_BM_STOP_MASK BIT(1)
+#define MVPP2_BM_STATE_MASK BIT(4)
+#define MVPP2_BM_LOW_THRESH_OFFS 8
+#define MVPP2_BM_LOW_THRESH_MASK 0x7f00
+#define MVPP2_BM_LOW_THRESH_VALUE(val) ((val) << \
+ MVPP2_BM_LOW_THRESH_OFFS)
+#define MVPP2_BM_HIGH_THRESH_OFFS 16
+#define MVPP2_BM_HIGH_THRESH_MASK 0x7f0000
+#define MVPP2_BM_HIGH_THRESH_VALUE(val) ((val) << \
+ MVPP2_BM_HIGH_THRESH_OFFS)
+#define MVPP2_BM_INTR_CAUSE_REG(pool) (0x6240 + ((pool) * 4))
+#define MVPP2_BM_RELEASED_DELAY_MASK BIT(0)
+#define MVPP2_BM_ALLOC_FAILED_MASK BIT(1)
+#define MVPP2_BM_BPPE_EMPTY_MASK BIT(2)
+#define MVPP2_BM_BPPE_FULL_MASK BIT(3)
+#define MVPP2_BM_AVAILABLE_BP_LOW_MASK BIT(4)
+#define MVPP2_BM_INTR_MASK_REG(pool) (0x6280 + ((pool) * 4))
+#define MVPP2_BM_PHY_ALLOC_REG(pool) (0x6400 + ((pool) * 4))
+#define MVPP2_BM_PHY_ALLOC_GRNTD_MASK BIT(0)
+#define MVPP2_BM_VIRT_ALLOC_REG 0x6440
+#define MVPP2_BM_PHY_RLS_REG(pool) (0x6480 + ((pool) * 4))
+#define MVPP2_BM_PHY_RLS_MC_BUFF_MASK BIT(0)
+#define MVPP2_BM_PHY_RLS_PRIO_EN_MASK BIT(1)
+#define MVPP2_BM_PHY_RLS_GRNTD_MASK BIT(2)
+#define MVPP2_BM_VIRT_RLS_REG 0x64c0
+#define MVPP2_BM_MC_RLS_REG 0x64c4
+#define MVPP2_BM_MC_ID_MASK 0xfff
+#define MVPP2_BM_FORCE_RELEASE_MASK BIT(12)
+
+/* TX Scheduler registers */
+#define MVPP2_TXP_SCHED_PORT_INDEX_REG 0x8000
+#define MVPP2_TXP_SCHED_Q_CMD_REG 0x8004
+#define MVPP2_TXP_SCHED_ENQ_MASK 0xff
+#define MVPP2_TXP_SCHED_DISQ_OFFSET 8
+#define MVPP2_TXP_SCHED_CMD_1_REG 0x8010
+#define MVPP2_TXP_SCHED_PERIOD_REG 0x8018
+#define MVPP2_TXP_SCHED_MTU_REG 0x801c
+#define MVPP2_TXP_MTU_MAX 0x7FFFF
+#define MVPP2_TXP_SCHED_REFILL_REG 0x8020
+#define MVPP2_TXP_REFILL_TOKENS_ALL_MASK 0x7ffff
+#define MVPP2_TXP_REFILL_PERIOD_ALL_MASK 0x3ff00000
+#define MVPP2_TXP_REFILL_PERIOD_MASK(v) ((v) << 20)
+#define MVPP2_TXP_SCHED_TOKEN_SIZE_REG 0x8024
+#define MVPP2_TXP_TOKEN_SIZE_MAX 0xffffffff
+#define MVPP2_TXQ_SCHED_REFILL_REG(q) (0x8040 + ((q) << 2))
+#define MVPP2_TXQ_REFILL_TOKENS_ALL_MASK 0x7ffff
+#define MVPP2_TXQ_REFILL_PERIOD_ALL_MASK 0x3ff00000
+#define MVPP2_TXQ_REFILL_PERIOD_MASK(v) ((v) << 20)
+#define MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(q) (0x8060 + ((q) << 2))
+#define MVPP2_TXQ_TOKEN_SIZE_MAX 0x7fffffff
+#define MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(q) (0x8080 + ((q) << 2))
+#define MVPP2_TXQ_TOKEN_CNTR_MAX 0xffffffff
+
+/* TX general registers */
+#define MVPP2_TX_SNOOP_REG 0x8800
+#define MVPP2_TX_PORT_FLUSH_REG 0x8810
+#define MVPP2_TX_PORT_FLUSH_MASK(port) (1 << (port))
+
+/* LMS registers */
+#define MVPP2_SRC_ADDR_MIDDLE 0x24
+#define MVPP2_SRC_ADDR_HIGH 0x28
+#define MVPP2_PHY_AN_CFG0_REG 0x34
+#define MVPP2_PHY_AN_STOP_SMI0_MASK BIT(7)
+#define MVPP2_MIB_COUNTERS_BASE(port) (0x1000 + ((port) >> 1) * \
+ 0x400 + (port) * 0x400)
+#define MVPP2_MIB_LATE_COLLISION 0x7c
+#define MVPP2_ISR_SUM_MASK_REG 0x220c
+#define MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG 0x305c
+#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT 0x27
+
+/* Per-port registers */
+#define MVPP2_GMAC_CTRL_0_REG 0x0
+#define MVPP2_GMAC_PORT_EN_MASK BIT(0)
+#define MVPP2_GMAC_MAX_RX_SIZE_OFFS 2
+#define MVPP2_GMAC_MAX_RX_SIZE_MASK 0x7ffc
+#define MVPP2_GMAC_MIB_CNTR_EN_MASK BIT(15)
+#define MVPP2_GMAC_CTRL_1_REG 0x4
+#define MVPP2_GMAC_PERIODIC_XON_EN_MASK BIT(1)
+#define MVPP2_GMAC_GMII_LB_EN_MASK BIT(5)
+#define MVPP2_GMAC_PCS_LB_EN_BIT 6
+#define MVPP2_GMAC_PCS_LB_EN_MASK BIT(6)
+#define MVPP2_GMAC_SA_LOW_OFFS 7
+#define MVPP2_GMAC_CTRL_2_REG 0x8
+#define MVPP2_GMAC_INBAND_AN_MASK BIT(0)
+#define MVPP2_GMAC_PCS_ENABLE_MASK BIT(3)
+#define MVPP2_GMAC_PORT_RGMII_MASK BIT(4)
+#define MVPP2_GMAC_PORT_RESET_MASK BIT(6)
+#define MVPP2_GMAC_AUTONEG_CONFIG 0xc
+#define MVPP2_GMAC_FORCE_LINK_DOWN BIT(0)
+#define MVPP2_GMAC_FORCE_LINK_PASS BIT(1)
+#define MVPP2_GMAC_CONFIG_MII_SPEED BIT(5)
+#define MVPP2_GMAC_CONFIG_GMII_SPEED BIT(6)
+#define MVPP2_GMAC_AN_SPEED_EN BIT(7)
+#define MVPP2_GMAC_FC_ADV_EN BIT(9)
+#define MVPP2_GMAC_CONFIG_FULL_DUPLEX BIT(12)
+#define MVPP2_GMAC_AN_DUPLEX_EN BIT(13)
+#define MVPP2_GMAC_PORT_FIFO_CFG_1_REG 0x1c
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_OFFS 6
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK 0x1fc0
+#define MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v) (((v) << 6) & \
+ MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK)
+
+#define MVPP2_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff
+
+/* Descriptor ring Macros */
+#define MVPP2_QUEUE_NEXT_DESC(q, index) \
+ (((index) < (q)->last_desc) ? ((index) + 1) : 0)
+
+/* Various constants */
+
+/* Coalescing */
+#define MVPP2_TXDONE_COAL_PKTS_THRESH 15
+#define MVPP2_RX_COAL_PKTS 32
+#define MVPP2_RX_COAL_USEC 100
+
+/* The two bytes Marvell header. Either contains a special value used
+ * by Marvell switches when a specific hardware mode is enabled (not
+ * supported by this driver) or is filled automatically by zeroes on
+ * the RX side. Those two bytes being at the front of the Ethernet
+ * header, they allow to have the IP header aligned on a 4 bytes
+ * boundary automatically: the hardware skips those two bytes on its
+ * own.
+ */
+#define MVPP2_MH_SIZE 2
+#define MVPP2_ETH_TYPE_LEN 2
+#define MVPP2_PPPOE_HDR_SIZE 8
+#define MVPP2_VLAN_TAG_LEN 4
+
+/* Lbtd 802.3 type */
+#define MVPP2_IP_LBDT_TYPE 0xfffa
+
+#define MVPP2_CPU_D_CACHE_LINE_SIZE 32
+#define MVPP2_TX_CSUM_MAX_SIZE 9800
+
+/* Timeout constants */
+#define MVPP2_TX_DISABLE_TIMEOUT_MSEC 1000
+#define MVPP2_TX_PENDING_TIMEOUT_MSEC 1000
+
+#define MVPP2_TX_MTU_MAX 0x7ffff
+
+/* Maximum number of T-CONTs of PON port */
+#define MVPP2_MAX_TCONT 16
+
+/* Maximum number of supported ports */
+#define MVPP2_MAX_PORTS 4
+
+/* Maximum number of TXQs used by single port */
+#define MVPP2_MAX_TXQ 8
+
+/* Maximum number of RXQs used by single port */
+#define MVPP2_MAX_RXQ 8
+
+/* Dfault number of RXQs in use */
+#define MVPP2_DEFAULT_RXQ 4
+
+/* Total number of RXQs available to all ports */
+#define MVPP2_RXQ_TOTAL_NUM (MVPP2_MAX_PORTS * MVPP2_MAX_RXQ)
+
+/* Max number of Rx descriptors */
+#define MVPP2_MAX_RXD 128
+
+/* Max number of Tx descriptors */
+#define MVPP2_MAX_TXD 1024
+
+/* Amount of Tx descriptors that can be reserved at once by CPU */
+#define MVPP2_CPU_DESC_CHUNK 64
+
+/* Max number of Tx descriptors in each aggregated queue */
+#define MVPP2_AGGR_TXQ_SIZE 256
+
+/* Descriptor aligned size */
+#define MVPP2_DESC_ALIGNED_SIZE 32
+
+/* Descriptor alignment mask */
+#define MVPP2_TX_DESC_ALIGN (MVPP2_DESC_ALIGNED_SIZE - 1)
+
+/* RX FIFO constants */
+#define MVPP2_RX_FIFO_PORT_DATA_SIZE 0x2000
+#define MVPP2_RX_FIFO_PORT_ATTR_SIZE 0x80
+#define MVPP2_RX_FIFO_PORT_MIN_PKT 0x80
+
+/* RX buffer constants */
+#define MVPP2_SKB_SHINFO_SIZE \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
+
+#define MVPP2_RX_PKT_SIZE(mtu) \
+ ALIGN((mtu) + MVPP2_MH_SIZE + MVPP2_VLAN_TAG_LEN + \
+ ETH_HLEN + ETH_FCS_LEN, MVPP2_CPU_D_CACHE_LINE_SIZE)
+
+#define MVPP2_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD)
+#define MVPP2_RX_TOTAL_SIZE(buf_size) ((buf_size) + MVPP2_SKB_SHINFO_SIZE)
+#define MVPP2_RX_MAX_PKT_SIZE(total_size) \
+ ((total_size) - NET_SKB_PAD - MVPP2_SKB_SHINFO_SIZE)
+
+#define MVPP2_BIT_TO_BYTE(bit) ((bit) / 8)
+
+/* IPv6 max L3 address size */
+#define MVPP2_MAX_L3_ADDR_SIZE 16
+
+/* Port flags */
+#define MVPP2_F_LOOPBACK BIT(0)
+
+/* Marvell tag types */
+enum mvpp2_tag_type {
+ MVPP2_TAG_TYPE_NONE = 0,
+ MVPP2_TAG_TYPE_MH = 1,
+ MVPP2_TAG_TYPE_DSA = 2,
+ MVPP2_TAG_TYPE_EDSA = 3,
+ MVPP2_TAG_TYPE_VLAN = 4,
+ MVPP2_TAG_TYPE_LAST = 5
+};
+
+/* Parser constants */
+#define MVPP2_PRS_TCAM_SRAM_SIZE 256
+#define MVPP2_PRS_TCAM_WORDS 6
+#define MVPP2_PRS_SRAM_WORDS 4
+#define MVPP2_PRS_FLOW_ID_SIZE 64
+#define MVPP2_PRS_FLOW_ID_MASK 0x3f
+#define MVPP2_PRS_TCAM_ENTRY_INVALID 1
+#define MVPP2_PRS_TCAM_DSA_TAGGED_BIT BIT(5)
+#define MVPP2_PRS_IPV4_HEAD 0x40
+#define MVPP2_PRS_IPV4_HEAD_MASK 0xf0
+#define MVPP2_PRS_IPV4_MC 0xe0
+#define MVPP2_PRS_IPV4_MC_MASK 0xf0
+#define MVPP2_PRS_IPV4_BC_MASK 0xff
+#define MVPP2_PRS_IPV4_IHL 0x5
+#define MVPP2_PRS_IPV4_IHL_MASK 0xf
+#define MVPP2_PRS_IPV6_MC 0xff
+#define MVPP2_PRS_IPV6_MC_MASK 0xff
+#define MVPP2_PRS_IPV6_HOP_MASK 0xff
+#define MVPP2_PRS_TCAM_PROTO_MASK 0xff
+#define MVPP2_PRS_TCAM_PROTO_MASK_L 0x3f
+#define MVPP2_PRS_DBL_VLANS_MAX 100
+
+/* Tcam structure:
+ * - lookup ID - 4 bits
+ * - port ID - 1 byte
+ * - additional information - 1 byte
+ * - header data - 8 bytes
+ * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(5)->(0).
+ */
+#define MVPP2_PRS_AI_BITS 8
+#define MVPP2_PRS_PORT_MASK 0xff
+#define MVPP2_PRS_LU_MASK 0xf
+#define MVPP2_PRS_TCAM_DATA_BYTE(offs) \
+ (((offs) - ((offs) % 2)) * 2 + ((offs) % 2))
+#define MVPP2_PRS_TCAM_DATA_BYTE_EN(offs) \
+ (((offs) * 2) - ((offs) % 2) + 2)
+#define MVPP2_PRS_TCAM_AI_BYTE 16
+#define MVPP2_PRS_TCAM_PORT_BYTE 17
+#define MVPP2_PRS_TCAM_LU_BYTE 20
+#define MVPP2_PRS_TCAM_EN_OFFS(offs) ((offs) + 2)
+#define MVPP2_PRS_TCAM_INV_WORD 5
+/* Tcam entries ID */
+#define MVPP2_PE_DROP_ALL 0
+#define MVPP2_PE_FIRST_FREE_TID 1
+#define MVPP2_PE_LAST_FREE_TID (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
+#define MVPP2_PE_IP6_EXT_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
+#define MVPP2_PE_MAC_MC_IP6 (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
+#define MVPP2_PE_IP6_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
+#define MVPP2_PE_IP4_ADDR_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 27)
+#define MVPP2_PE_LAST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 26)
+#define MVPP2_PE_FIRST_DEFAULT_FLOW (MVPP2_PRS_TCAM_SRAM_SIZE - 19)
+#define MVPP2_PE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 18)
+#define MVPP2_PE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 17)
+#define MVPP2_PE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 16)
+#define MVPP2_PE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 15)
+#define MVPP2_PE_ETYPE_EDSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 14)
+#define MVPP2_PE_ETYPE_EDSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 13)
+#define MVPP2_PE_ETYPE_DSA_TAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 12)
+#define MVPP2_PE_ETYPE_DSA_UNTAGGED (MVPP2_PRS_TCAM_SRAM_SIZE - 11)
+#define MVPP2_PE_MH_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 10)
+#define MVPP2_PE_DSA_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 9)
+#define MVPP2_PE_IP6_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 8)
+#define MVPP2_PE_IP4_PROTO_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 7)
+#define MVPP2_PE_ETH_TYPE_UN (MVPP2_PRS_TCAM_SRAM_SIZE - 6)
+#define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 5)
+#define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 4)
+#define MVPP2_PE_MAC_MC_ALL (MVPP2_PRS_TCAM_SRAM_SIZE - 3)
+#define MVPP2_PE_MAC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2)
+#define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+
+/* Sram structure
+ * The fields are represented by MVPP2_PRS_TCAM_DATA_REG(3)->(0).
+ */
+#define MVPP2_PRS_SRAM_RI_OFFS 0
+#define MVPP2_PRS_SRAM_RI_WORD 0
+#define MVPP2_PRS_SRAM_RI_CTRL_OFFS 32
+#define MVPP2_PRS_SRAM_RI_CTRL_WORD 1
+#define MVPP2_PRS_SRAM_RI_CTRL_BITS 32
+#define MVPP2_PRS_SRAM_SHIFT_OFFS 64
+#define MVPP2_PRS_SRAM_SHIFT_SIGN_BIT 72
+#define MVPP2_PRS_SRAM_UDF_OFFS 73
+#define MVPP2_PRS_SRAM_UDF_BITS 8
+#define MVPP2_PRS_SRAM_UDF_MASK 0xff
+#define MVPP2_PRS_SRAM_UDF_SIGN_BIT 81
+#define MVPP2_PRS_SRAM_UDF_TYPE_OFFS 82
+#define MVPP2_PRS_SRAM_UDF_TYPE_MASK 0x7
+#define MVPP2_PRS_SRAM_UDF_TYPE_L3 1
+#define MVPP2_PRS_SRAM_UDF_TYPE_L4 4
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS 85
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK 0x3
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD 1
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_IP4_ADD 2
+#define MVPP2_PRS_SRAM_OP_SEL_SHIFT_IP6_ADD 3
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS 87
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_BITS 2
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_MASK 0x3
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_ADD 0
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_IP4_ADD 2
+#define MVPP2_PRS_SRAM_OP_SEL_UDF_IP6_ADD 3
+#define MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS 89
+#define MVPP2_PRS_SRAM_AI_OFFS 90
+#define MVPP2_PRS_SRAM_AI_CTRL_OFFS 98
+#define MVPP2_PRS_SRAM_AI_CTRL_BITS 8
+#define MVPP2_PRS_SRAM_AI_MASK 0xff
+#define MVPP2_PRS_SRAM_NEXT_LU_OFFS 106
+#define MVPP2_PRS_SRAM_NEXT_LU_MASK 0xf
+#define MVPP2_PRS_SRAM_LU_DONE_BIT 110
+#define MVPP2_PRS_SRAM_LU_GEN_BIT 111
+
+/* Sram result info bits assignment */
+#define MVPP2_PRS_RI_MAC_ME_MASK 0x1
+#define MVPP2_PRS_RI_DSA_MASK 0x2
+#define MVPP2_PRS_RI_VLAN_MASK 0xc
+#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
+#define MVPP2_PRS_RI_VLAN_SINGLE BIT(2)
+#define MVPP2_PRS_RI_VLAN_DOUBLE BIT(3)
+#define MVPP2_PRS_RI_VLAN_TRIPLE (BIT(2) | BIT(3))
+#define MVPP2_PRS_RI_CPU_CODE_MASK 0x70
+#define MVPP2_PRS_RI_CPU_CODE_RX_SPEC BIT(4)
+#define MVPP2_PRS_RI_L2_CAST_MASK 0x600
+#define MVPP2_PRS_RI_L2_UCAST ~(BIT(9) | BIT(10))
+#define MVPP2_PRS_RI_L2_MCAST BIT(9)
+#define MVPP2_PRS_RI_L2_BCAST BIT(10)
+#define MVPP2_PRS_RI_PPPOE_MASK 0x800
+#define MVPP2_PRS_RI_L3_PROTO_MASK 0x7000
+#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
+#define MVPP2_PRS_RI_L3_IP4 BIT(12)
+#define MVPP2_PRS_RI_L3_IP4_OPT BIT(13)
+#define MVPP2_PRS_RI_L3_IP4_OTHER (BIT(12) | BIT(13))
+#define MVPP2_PRS_RI_L3_IP6 BIT(14)
+#define MVPP2_PRS_RI_L3_IP6_EXT (BIT(12) | BIT(14))
+#define MVPP2_PRS_RI_L3_ARP (BIT(13) | BIT(14))
+#define MVPP2_PRS_RI_L3_ADDR_MASK 0x18000
+#define MVPP2_PRS_RI_L3_UCAST ~(BIT(15) | BIT(16))
+#define MVPP2_PRS_RI_L3_MCAST BIT(15)
+#define MVPP2_PRS_RI_L3_BCAST (BIT(15) | BIT(16))
+#define MVPP2_PRS_RI_IP_FRAG_MASK 0x20000
+#define MVPP2_PRS_RI_UDF3_MASK 0x300000
+#define MVPP2_PRS_RI_UDF3_RX_SPECIAL BIT(21)
+#define MVPP2_PRS_RI_L4_PROTO_MASK 0x1c00000
+#define MVPP2_PRS_RI_L4_TCP BIT(22)
+#define MVPP2_PRS_RI_L4_UDP BIT(23)
+#define MVPP2_PRS_RI_L4_OTHER (BIT(22) | BIT(23))
+#define MVPP2_PRS_RI_UDF7_MASK 0x60000000
+#define MVPP2_PRS_RI_UDF7_IP6_LITE BIT(29)
+#define MVPP2_PRS_RI_DROP_MASK 0x80000000
+
+/* Sram additional info bits assignment */
+#define MVPP2_PRS_IPV4_DIP_AI_BIT BIT(0)
+#define MVPP2_PRS_IPV6_NO_EXT_AI_BIT BIT(0)
+#define MVPP2_PRS_IPV6_EXT_AI_BIT BIT(1)
+#define MVPP2_PRS_IPV6_EXT_AH_AI_BIT BIT(2)
+#define MVPP2_PRS_IPV6_EXT_AH_LEN_AI_BIT BIT(3)
+#define MVPP2_PRS_IPV6_EXT_AH_L4_AI_BIT BIT(4)
+#define MVPP2_PRS_SINGLE_VLAN_AI 0
+#define MVPP2_PRS_DBL_VLAN_AI_BIT BIT(7)
+
+/* DSA/EDSA type */
+#define MVPP2_PRS_TAGGED true
+#define MVPP2_PRS_UNTAGGED false
+#define MVPP2_PRS_EDSA true
+#define MVPP2_PRS_DSA false
+
+/* MAC entries, shadow udf */
+enum mvpp2_prs_udf {
+ MVPP2_PRS_UDF_MAC_DEF,
+ MVPP2_PRS_UDF_MAC_RANGE,
+ MVPP2_PRS_UDF_L2_DEF,
+ MVPP2_PRS_UDF_L2_DEF_COPY,
+ MVPP2_PRS_UDF_L2_USER,
+};
+
+/* Lookup ID */
+enum mvpp2_prs_lookup {
+ MVPP2_PRS_LU_MH,
+ MVPP2_PRS_LU_MAC,
+ MVPP2_PRS_LU_DSA,
+ MVPP2_PRS_LU_VLAN,
+ MVPP2_PRS_LU_L2,
+ MVPP2_PRS_LU_PPPOE,
+ MVPP2_PRS_LU_IP4,
+ MVPP2_PRS_LU_IP6,
+ MVPP2_PRS_LU_FLOWS,
+ MVPP2_PRS_LU_LAST,
+};
+
+/* L3 cast enum */
+enum mvpp2_prs_l3_cast {
+ MVPP2_PRS_L3_UNI_CAST,
+ MVPP2_PRS_L3_MULTI_CAST,
+ MVPP2_PRS_L3_BROAD_CAST
+};
+
+/* Classifier constants */
+#define MVPP2_CLS_FLOWS_TBL_SIZE 512
+#define MVPP2_CLS_FLOWS_TBL_DATA_WORDS 3
+#define MVPP2_CLS_LKP_TBL_SIZE 64
+
+/* BM constants */
+#define MVPP2_BM_POOLS_NUM 8
+#define MVPP2_BM_LONG_BUF_NUM 1024
+#define MVPP2_BM_SHORT_BUF_NUM 2048
+#define MVPP2_BM_POOL_SIZE_MAX (16*1024 - MVPP2_BM_POOL_PTR_ALIGN/4)
+#define MVPP2_BM_POOL_PTR_ALIGN 128
+#define MVPP2_BM_SWF_LONG_POOL(port) ((port > 2) ? 2 : port)
+#define MVPP2_BM_SWF_SHORT_POOL 3
+
+/* BM cookie (32 bits) definition */
+#define MVPP2_BM_COOKIE_POOL_OFFS 8
+#define MVPP2_BM_COOKIE_CPU_OFFS 24
+
+/* BM short pool packet size
+ * These value assure that for SWF the total number
+ * of bytes allocated for each buffer will be 512
+ */
+#define MVPP2_BM_SHORT_PKT_SIZE MVPP2_RX_MAX_PKT_SIZE(512)
+
+enum mvpp2_bm_type {
+ MVPP2_BM_FREE,
+ MVPP2_BM_SWF_LONG,
+ MVPP2_BM_SWF_SHORT
+};
+
+/* Definitions */
+
+/* Shared Packet Processor resources */
+struct mvpp2 {
+ /* Shared registers' base addresses */
+ void __iomem *base;
+ void __iomem *lms_base;
+
+ /* Common clocks */
+ struct clk *pp_clk;
+ struct clk *gop_clk;
+
+ /* List of pointers to port structures */
+ struct mvpp2_port **port_list;
+
+ /* Aggregated TXQs */
+ struct mvpp2_tx_queue *aggr_txqs;
+
+ /* BM pools */
+ struct mvpp2_bm_pool *bm_pools;
+
+ /* PRS shadow table */
+ struct mvpp2_prs_shadow *prs_shadow;
+ /* PRS auxiliary table for double vlan entries control */
+ bool *prs_double_vlans;
+
+ /* Tclk value */
+ u32 tclk;
+};
+
+struct mvpp2_pcpu_stats {
+ struct u64_stats_sync syncp;
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+};
+
+struct mvpp2_port {
+ u8 id;
+
+ int irq;
+
+ struct mvpp2 *priv;
+
+ /* Per-port registers' base address */
+ void __iomem *base;
+
+ struct mvpp2_rx_queue **rxqs;
+ struct mvpp2_tx_queue **txqs;
+ struct net_device *dev;
+
+ int pkt_size;
+
+ u32 pending_cause_rx;
+ struct napi_struct napi;
+
+ /* Flags */
+ unsigned long flags;
+
+ u16 tx_ring_size;
+ u16 rx_ring_size;
+ struct mvpp2_pcpu_stats __percpu *stats;
+
+ struct phy_device *phy_dev;
+ phy_interface_t phy_interface;
+ struct device_node *phy_node;
+ unsigned int link;
+ unsigned int duplex;
+ unsigned int speed;
+
+ struct mvpp2_bm_pool *pool_long;
+ struct mvpp2_bm_pool *pool_short;
+
+ /* Index of first port's physical RXQ */
+ u8 first_rxq;
+};
+
+/* The mvpp2_tx_desc and mvpp2_rx_desc structures describe the
+ * layout of the transmit and reception DMA descriptors, and their
+ * layout is therefore defined by the hardware design
+ */
+
+#define MVPP2_TXD_L3_OFF_SHIFT 0
+#define MVPP2_TXD_IP_HLEN_SHIFT 8
+#define MVPP2_TXD_L4_CSUM_FRAG BIT(13)
+#define MVPP2_TXD_L4_CSUM_NOT BIT(14)
+#define MVPP2_TXD_IP_CSUM_DISABLE BIT(15)
+#define MVPP2_TXD_PADDING_DISABLE BIT(23)
+#define MVPP2_TXD_L4_UDP BIT(24)
+#define MVPP2_TXD_L3_IP6 BIT(26)
+#define MVPP2_TXD_L_DESC BIT(28)
+#define MVPP2_TXD_F_DESC BIT(29)
+
+#define MVPP2_RXD_ERR_SUMMARY BIT(15)
+#define MVPP2_RXD_ERR_CODE_MASK (BIT(13) | BIT(14))
+#define MVPP2_RXD_ERR_CRC 0x0
+#define MVPP2_RXD_ERR_OVERRUN BIT(13)
+#define MVPP2_RXD_ERR_RESOURCE (BIT(13) | BIT(14))
+#define MVPP2_RXD_BM_POOL_ID_OFFS 16
+#define MVPP2_RXD_BM_POOL_ID_MASK (BIT(16) | BIT(17) | BIT(18))
+#define MVPP2_RXD_HWF_SYNC BIT(21)
+#define MVPP2_RXD_L4_CSUM_OK BIT(22)
+#define MVPP2_RXD_IP4_HEADER_ERR BIT(24)
+#define MVPP2_RXD_L4_TCP BIT(25)
+#define MVPP2_RXD_L4_UDP BIT(26)
+#define MVPP2_RXD_L3_IP4 BIT(28)
+#define MVPP2_RXD_L3_IP6 BIT(30)
+#define MVPP2_RXD_BUF_HDR BIT(31)
+
+struct mvpp2_tx_desc {
+ u32 command; /* Options used by HW for packet transmitting.*/
+ u8 packet_offset; /* the offset from the buffer beginning */
+ u8 phys_txq; /* destination queue ID */
+ u16 data_size; /* data size of transmitted packet in bytes */
+ u32 buf_phys_addr; /* physical addr of transmitted buffer */
+ u32 buf_cookie; /* cookie for access to TX buffer in tx path */
+ u32 reserved1[3]; /* hw_cmd (for future use, BM, PON, PNC) */
+ u32 reserved2; /* reserved (for future use) */
+};
+
+struct mvpp2_rx_desc {
+ u32 status; /* info about received packet */
+ u16 reserved1; /* parser_info (for future use, PnC) */
+ u16 data_size; /* size of received packet in bytes */
+ u32 buf_phys_addr; /* physical address of the buffer */
+ u32 buf_cookie; /* cookie for access to RX buffer in rx path */
+ u16 reserved2; /* gem_port_id (for future use, PON) */
+ u16 reserved3; /* csum_l4 (for future use, PnC) */
+ u8 reserved4; /* bm_qset (for future use, BM) */
+ u8 reserved5;
+ u16 reserved6; /* classify_info (for future use, PnC) */
+ u32 reserved7; /* flow_id (for future use, PnC) */
+ u32 reserved8;
+};
+
+/* Per-CPU Tx queue control */
+struct mvpp2_txq_pcpu {
+ int cpu;
+
+ /* Number of Tx DMA descriptors in the descriptor ring */
+ int size;
+
+ /* Number of currently used Tx DMA descriptor in the
+ * descriptor ring
+ */
+ int count;
+
+ /* Number of Tx DMA descriptors reserved for each CPU */
+ int reserved_num;
+
+ /* Array of transmitted skb */
+ struct sk_buff **tx_skb;
+
+ /* Index of last TX DMA descriptor that was inserted */
+ int txq_put_index;
+
+ /* Index of the TX DMA descriptor to be cleaned up */
+ int txq_get_index;
+};
+
+struct mvpp2_tx_queue {
+ /* Physical number of this Tx queue */
+ u8 id;
+
+ /* Logical number of this Tx queue */
+ u8 log_id;
+
+ /* Number of Tx DMA descriptors in the descriptor ring */
+ int size;
+
+ /* Number of currently used Tx DMA descriptor in the descriptor ring */
+ int count;
+
+ /* Per-CPU control of physical Tx queues */
+ struct mvpp2_txq_pcpu __percpu *pcpu;
+
+ /* Array of transmitted skb */
+ struct sk_buff **tx_skb;
+
+ u32 done_pkts_coal;
+
+ /* Virtual address of thex Tx DMA descriptors array */
+ struct mvpp2_tx_desc *descs;
+
+ /* DMA address of the Tx DMA descriptors array */
+ dma_addr_t descs_phys;
+
+ /* Index of the last Tx DMA descriptor */
+ int last_desc;
+
+ /* Index of the next Tx DMA descriptor to process */
+ int next_desc_to_proc;
+};
+
+struct mvpp2_rx_queue {
+ /* RX queue number, in the range 0-31 for physical RXQs */
+ u8 id;
+
+ /* Num of rx descriptors in the rx descriptor ring */
+ int size;
+
+ u32 pkts_coal;
+ u32 time_coal;
+
+ /* Virtual address of the RX DMA descriptors array */
+ struct mvpp2_rx_desc *descs;
+
+ /* DMA address of the RX DMA descriptors array */
+ dma_addr_t descs_phys;
+
+ /* Index of the last RX DMA descriptor */
+ int last_desc;
+
+ /* Index of the next RX DMA descriptor to process */
+ int next_desc_to_proc;
+
+ /* ID of port to which physical RXQ is mapped */
+ int port;
+
+ /* Port's logic RXQ number to which physical RXQ is mapped */
+ int logic_rxq;
+};
+
+union mvpp2_prs_tcam_entry {
+ u32 word[MVPP2_PRS_TCAM_WORDS];
+ u8 byte[MVPP2_PRS_TCAM_WORDS * 4];
+};
+
+union mvpp2_prs_sram_entry {
+ u32 word[MVPP2_PRS_SRAM_WORDS];
+ u8 byte[MVPP2_PRS_SRAM_WORDS * 4];
+};
+
+struct mvpp2_prs_entry {
+ u32 index;
+ union mvpp2_prs_tcam_entry tcam;
+ union mvpp2_prs_sram_entry sram;
+};
+
+struct mvpp2_prs_shadow {
+ bool valid;
+ bool finish;
+
+ /* Lookup ID */
+ int lu;
+
+ /* User defined offset */
+ int udf;
+
+ /* Result info */
+ u32 ri;
+ u32 ri_mask;
+};
+
+struct mvpp2_cls_flow_entry {
+ u32 index;
+ u32 data[MVPP2_CLS_FLOWS_TBL_DATA_WORDS];
+};
+
+struct mvpp2_cls_lookup_entry {
+ u32 lkpid;
+ u32 way;
+ u32 data;
+};
+
+struct mvpp2_bm_pool {
+ /* Pool number in the range 0-7 */
+ int id;
+ enum mvpp2_bm_type type;
+
+ /* Buffer Pointers Pool External (BPPE) size */
+ int size;
+ /* Number of buffers for this pool */
+ int buf_num;
+ /* Pool buffer size */
+ int buf_size;
+ /* Packet size */
+ int pkt_size;
+
+ /* BPPE virtual base address */
+ u32 *virt_addr;
+ /* BPPE physical base address */
+ dma_addr_t phys_addr;
+
+ /* Ports using BM pool */
+ u32 port_map;
+
+ /* Occupied buffers indicator */
+ atomic_t in_use;
+ int in_use_thresh;
+
+ spinlock_t lock;
+};
+
+struct mvpp2_buff_hdr {
+ u32 next_buff_phys_addr;
+ u32 next_buff_virt_addr;
+ u16 byte_count;
+ u16 info;
+ u8 reserved1; /* bm_qset (for future use, BM) */
+};
+
+/* Buffer header info bits */
+#define MVPP2_B_HDR_INFO_MC_ID_MASK 0xfff
+#define MVPP2_B_HDR_INFO_MC_ID(info) ((info) & MVPP2_B_HDR_INFO_MC_ID_MASK)
+#define MVPP2_B_HDR_INFO_LAST_OFFS 12
+#define MVPP2_B_HDR_INFO_LAST_MASK BIT(12)
+#define MVPP2_B_HDR_INFO_IS_LAST(info) \
+ ((info & MVPP2_B_HDR_INFO_LAST_MASK) >> MVPP2_B_HDR_INFO_LAST_OFFS)
+
+/* Static declaractions */
+
+/* Number of RXQs used by single port */
+static int rxq_number = MVPP2_DEFAULT_RXQ;
+/* Number of TXQs used by single port */
+static int txq_number = MVPP2_MAX_TXQ;
+
+#define MVPP2_DRIVER_NAME "mvpp2"
+#define MVPP2_DRIVER_VERSION "1.0"
+
+/* Utility/helper methods */
+
+static void mvpp2_write(struct mvpp2 *priv, u32 offset, u32 data)
+{
+ writel(data, priv->base + offset);
+}
+
+static u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
+{
+ return readl(priv->base + offset);
+}
+
+static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
+{
+ txq_pcpu->txq_get_index++;
+ if (txq_pcpu->txq_get_index == txq_pcpu->size)
+ txq_pcpu->txq_get_index = 0;
+}
+
+static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
+ struct sk_buff *skb)
+{
+ txq_pcpu->tx_skb[txq_pcpu->txq_put_index] = skb;
+ txq_pcpu->txq_put_index++;
+ if (txq_pcpu->txq_put_index == txq_pcpu->size)
+ txq_pcpu->txq_put_index = 0;
+}
+
+/* Get number of physical egress port */
+static inline int mvpp2_egress_port(struct mvpp2_port *port)
+{
+ return MVPP2_MAX_TCONT + port->id;
+}
+
+/* Get number of physical TXQ */
+static inline int mvpp2_txq_phys(int port, int txq)
+{
+ return (MVPP2_MAX_TCONT + port) * MVPP2_MAX_TXQ + txq;
+}
+
+/* Parser configuration routines */
+
+/* Update parser tcam and sram hw entries */
+static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
+{
+ int i;
+
+ if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+ return -EINVAL;
+
+ /* Clear entry invalidation bit */
+ pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK;
+
+ /* Write tcam index - indirect access */
+ mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+ mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam.word[i]);
+
+ /* Write sram index - indirect access */
+ mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
+ mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram.word[i]);
+
+ return 0;
+}
+
+/* Read tcam entry from hw */
+static int mvpp2_prs_hw_read(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
+{
+ int i;
+
+ if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
+ return -EINVAL;
+
+ /* Write tcam index - indirect access */
+ mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);
+
+ pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] = mvpp2_read(priv,
+ MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD));
+ if (pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] & MVPP2_PRS_TCAM_INV_MASK)
+ return MVPP2_PRS_TCAM_ENTRY_INVALID;
+
+ for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+ pe->tcam.word[i] = mvpp2_read(priv, MVPP2_PRS_TCAM_DATA_REG(i));
+
+ /* Write sram index - indirect access */
+ mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index);
+ for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
+ pe->sram.word[i] = mvpp2_read(priv, MVPP2_PRS_SRAM_DATA_REG(i));
+
+ return 0;
+}
+
+/* Invalidate tcam hw entry */
+static void mvpp2_prs_hw_inv(struct mvpp2 *priv, int index)
+{
+ /* Write index - indirect access */
+ mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, index);
+ mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD),
+ MVPP2_PRS_TCAM_INV_MASK);
+}
+
+/* Enable shadow table entry and set its lookup ID */
+static void mvpp2_prs_shadow_set(struct mvpp2 *priv, int index, int lu)
+{
+ priv->prs_shadow[index].valid = true;
+ priv->prs_shadow[index].lu = lu;
+}
+
+/* Update ri fields in shadow table entry */
+static void mvpp2_prs_shadow_ri_set(struct mvpp2 *priv, int index,
+ unsigned int ri, unsigned int ri_mask)
+{
+ priv->prs_shadow[index].ri_mask = ri_mask;
+ priv->prs_shadow[index].ri = ri;
+}
+
+/* Update lookup field in tcam sw entry */
+static void mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *pe, unsigned int lu)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_LU_BYTE);
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_LU_BYTE] = lu;
+ pe->tcam.byte[enable_off] = MVPP2_PRS_LU_MASK;
+}
+
+/* Update mask for single port in tcam sw entry */
+static void mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *pe,
+ unsigned int port, bool add)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+
+ if (add)
+ pe->tcam.byte[enable_off] &= ~(1 << port);
+ else
+ pe->tcam.byte[enable_off] |= 1 << port;
+}
+
+/* Update port map in tcam sw entry */
+static void mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *pe,
+ unsigned int ports)
+{
+ unsigned char port_mask = MVPP2_PRS_PORT_MASK;
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_PORT_BYTE] = 0;
+ pe->tcam.byte[enable_off] &= ~port_mask;
+ pe->tcam.byte[enable_off] |= ~ports & MVPP2_PRS_PORT_MASK;
+}
+
+/* Obtain port map from tcam sw entry */
+static unsigned int mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *pe)
+{
+ int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE);
+
+ return ~(pe->tcam.byte[enable_off]) & MVPP2_PRS_PORT_MASK;
+}
+
+/* Set byte of data and its enable bits in tcam sw entry */
+static void mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *pe,
+ unsigned int offs, unsigned char byte,
+ unsigned char enable)
+{
+ pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)] = byte;
+ pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)] = enable;
+}
+
+/* Get byte of data and its enable bits from tcam sw entry */
+static void mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *pe,
+ unsigned int offs, unsigned char *byte,
+ unsigned char *enable)
+{
+ *byte = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)];
+ *enable = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)];
+}
+
+/* Compare tcam data bytes with a pattern */
+static bool mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offs,
+ u16 data)
+{
+ int off = MVPP2_PRS_TCAM_DATA_BYTE(offs);
+ u16 tcam_data;
+
+ tcam_data = (8 << pe->tcam.byte[off + 1]) | pe->tcam.byte[off];
+ if (tcam_data != data)
+ return false;
+ return true;
+}
+
+/* Update ai bits in tcam sw entry */
+static void mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *pe,
+ unsigned int bits, unsigned int enable)
+{
+ int i, ai_idx = MVPP2_PRS_TCAM_AI_BYTE;
+
+ for (i = 0; i < MVPP2_PRS_AI_BITS; i++) {
+
+ if (!(enable & BIT(i)))
+ continue;
+
+ if (bits & BIT(i))
+ pe->tcam.byte[ai_idx] |= 1 << i;
+ else
+ pe->tcam.byte[ai_idx] &= ~(1 << i);
+ }
+
+ pe->tcam.byte[MVPP2_PRS_TCAM_EN_OFFS(ai_idx)] |= enable;
+}
+
+/* Get ai bits from tcam sw entry */
+static int mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *pe)
+{
+ return pe->tcam.byte[MVPP2_PRS_TCAM_AI_BYTE];
+}
+
+/* Set ethertype in tcam sw entry */
+static void mvpp2_prs_match_etype(struct mvpp2_prs_entry *pe, int offset,
+ unsigned short ethertype)
+{
+ mvpp2_prs_tcam_data_byte_set(pe, offset + 0, ethertype >> 8, 0xff);
+ mvpp2_prs_tcam_data_byte_set(pe, offset + 1, ethertype & 0xff, 0xff);
+}
+
+/* Set bits in sram sw entry */
+static void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, int bit_num,
+ int val)
+{
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(bit_num)] |= (val << (bit_num % 8));
+}
+
+/* Clear bits in sram sw entry */
+static void mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *pe, int bit_num,
+ int val)
+{
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(bit_num)] &= ~(val << (bit_num % 8));
+}
+
+/* Update ri bits in sram sw entry */
+static void mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *pe,
+ unsigned int bits, unsigned int mask)
+{
+ unsigned int i;
+
+ for (i = 0; i < MVPP2_PRS_SRAM_RI_CTRL_BITS; i++) {
+ int ri_off = MVPP2_PRS_SRAM_RI_OFFS;
+
+ if (!(mask & BIT(i)))
+ continue;
+
+ if (bits & BIT(i))
+ mvpp2_prs_sram_bits_set(pe, ri_off + i, 1);
+ else
+ mvpp2_prs_sram_bits_clear(pe, ri_off + i, 1);
+
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_RI_CTRL_OFFS + i, 1);
+ }
+}
+
+/* Obtain ri bits from sram sw entry */
+static int mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *pe)
+{
+ return pe->sram.word[MVPP2_PRS_SRAM_RI_WORD];
+}
+
+/* Update ai bits in sram sw entry */
+static void mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *pe,
+ unsigned int bits, unsigned int mask)
+{
+ unsigned int i;
+ int ai_off = MVPP2_PRS_SRAM_AI_OFFS;
+
+ for (i = 0; i < MVPP2_PRS_SRAM_AI_CTRL_BITS; i++) {
+
+ if (!(mask & BIT(i)))
+ continue;
+
+ if (bits & BIT(i))
+ mvpp2_prs_sram_bits_set(pe, ai_off + i, 1);
+ else
+ mvpp2_prs_sram_bits_clear(pe, ai_off + i, 1);
+
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_AI_CTRL_OFFS + i, 1);
+ }
+}
+
+/* Read ai bits from sram sw entry */
+static int mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *pe)
+{
+ u8 bits;
+ int ai_off = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_AI_OFFS);
+ int ai_en_off = ai_off + 1;
+ int ai_shift = MVPP2_PRS_SRAM_AI_OFFS % 8;
+
+ bits = (pe->sram.byte[ai_off] >> ai_shift) |
+ (pe->sram.byte[ai_en_off] << (8 - ai_shift));
+
+ return bits;
+}
+
+/* In sram sw entry set lookup ID field of the tcam key to be used in the next
+ * lookup interation
+ */
+static void mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *pe,
+ unsigned int lu)
+{
+ int sram_next_off = MVPP2_PRS_SRAM_NEXT_LU_OFFS;
+
+ mvpp2_prs_sram_bits_clear(pe, sram_next_off,
+ MVPP2_PRS_SRAM_NEXT_LU_MASK);
+ mvpp2_prs_sram_bits_set(pe, sram_next_off, lu);
+}
+
+/* In the sram sw entry set sign and value of the next lookup offset
+ * and the offset value generated to the classifier
+ */
+static void mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *pe, int shift,
+ unsigned int op)
+{
+ /* Set sign */
+ if (shift < 0) {
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
+ shift = 0 - shift;
+ } else {
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
+ }
+
+ /* Set value */
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_SHIFT_OFFS)] =
+ (unsigned char)shift;
+
+ /* Reset and set operation */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, op);
+
+ /* Set base offset as current */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
+}
+
+/* In the sram sw entry set sign and value of the user defined offset
+ * generated to the classifier
+ */
+static void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe,
+ unsigned int type, int offset,
+ unsigned int op)
+{
+ /* Set sign */
+ if (offset < 0) {
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
+ offset = 0 - offset;
+ } else {
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
+ }
+
+ /* Set value */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_OFFS,
+ MVPP2_PRS_SRAM_UDF_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_OFFS, offset);
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_UDF_OFFS +
+ MVPP2_PRS_SRAM_UDF_BITS)] &=
+ ~(MVPP2_PRS_SRAM_UDF_MASK >> (8 - (MVPP2_PRS_SRAM_UDF_OFFS % 8)));
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_UDF_OFFS +
+ MVPP2_PRS_SRAM_UDF_BITS)] |=
+ (offset >> (8 - (MVPP2_PRS_SRAM_UDF_OFFS % 8)));
+
+ /* Set offset type */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS,
+ MVPP2_PRS_SRAM_UDF_TYPE_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, type);
+
+ /* Set offset operation */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, op);
+
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS +
+ MVPP2_PRS_SRAM_OP_SEL_UDF_BITS)] &=
+ ~(MVPP2_PRS_SRAM_OP_SEL_UDF_MASK >>
+ (8 - (MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS % 8)));
+
+ pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS +
+ MVPP2_PRS_SRAM_OP_SEL_UDF_BITS)] |=
+ (op >> (8 - (MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS % 8)));
+
+ /* Set base offset as current */
+ mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
+}
+
+/* Find parser flow entry */
+static struct mvpp2_prs_entry *mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return NULL;
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
+
+ /* Go through the all entires with MVPP2_PRS_LU_FLOWS */
+ for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) {
+ u8 bits;
+
+ if (!priv->prs_shadow[tid].valid ||
+ priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(priv, pe);
+ bits = mvpp2_prs_sram_ai_get(pe);
+
+ /* Sram store classification lookup ID in AI bits [5:0] */
+ if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow)
+ return pe;
+ }
+ kfree(pe);
+
+ return NULL;
+}
+
+/* Return first free tcam index, seeking from start to end */
+static int mvpp2_prs_tcam_first_free(struct mvpp2 *priv, unsigned char start,
+ unsigned char end)
+{
+ int tid;
+
+ if (start > end)
+ swap(start, end);
+
+ if (end >= MVPP2_PRS_TCAM_SRAM_SIZE)
+ end = MVPP2_PRS_TCAM_SRAM_SIZE - 1;
+
+ for (tid = start; tid <= end; tid++) {
+ if (!priv->prs_shadow[tid].valid)
+ return tid;
+ }
+
+ return -EINVAL;
+}
+
+/* Enable/disable dropping all mac da's */
+static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
+{
+ struct mvpp2_prs_entry pe;
+
+ if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {
+ /* Entry exist - update port only */
+ pe.index = MVPP2_PE_DROP_ALL;
+ mvpp2_prs_hw_read(priv, &pe);
+ } else {
+ /* Entry doesn't exist - create new */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = MVPP2_PE_DROP_ALL;
+
+ /* Non-promiscuous mode for all ports - DROP unknown packets */
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_DROP_MASK);
+
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Set port to promiscuous mode */
+static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port, bool add)
+{
+ struct mvpp2_prs_entry pe;
+
+ /* Promiscous mode - Accept unknown packets */
+
+ if (priv->prs_shadow[MVPP2_PE_MAC_PROMISCUOUS].valid) {
+ /* Entry exist - update port only */
+ pe.index = MVPP2_PE_MAC_PROMISCUOUS;
+ mvpp2_prs_hw_read(priv, &pe);
+ } else {
+ /* Entry doesn't exist - create new */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = MVPP2_PE_MAC_PROMISCUOUS;
+
+ /* Continue - set next lookup */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
+
+ /* Set result info bits */
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_UCAST,
+ MVPP2_PRS_RI_L2_CAST_MASK);
+
+ /* Shift to ethertype */
+ mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Accept multicast */
+static void mvpp2_prs_mac_multi_set(struct mvpp2 *priv, int port, int index,
+ bool add)
+{
+ struct mvpp2_prs_entry pe;
+ unsigned char da_mc;
+
+ /* Ethernet multicast address first byte is
+ * 0x01 for IPv4 and 0x33 for IPv6
+ */
+ da_mc = (index == MVPP2_PE_MAC_MC_ALL) ? 0x01 : 0x33;
+
+ if (priv->prs_shadow[index].valid) {
+ /* Entry exist - update port only */
+ pe.index = index;
+ mvpp2_prs_hw_read(priv, &pe);
+ } else {
+ /* Entry doesn't exist - create new */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+ pe.index = index;
+
+ /* Continue - set next lookup */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
+
+ /* Set result info bits */
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_MCAST,
+ MVPP2_PRS_RI_L2_CAST_MASK);
+
+ /* Update tcam entry data first byte */
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, da_mc, 0xff);
+
+ /* Shift to ethertype */
+ mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Set entry for dsa packets */
+static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
+ bool tagged, bool extend)
+{
+ struct mvpp2_prs_entry pe;
+ int tid, shift;
+
+ if (extend) {
+ tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED;
+ shift = 8;
+ } else {
+ tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED;
+ shift = 4;
+ }
+
+ if (priv->prs_shadow[tid].valid) {
+ /* Entry exist - update port only */
+ pe.index = tid;
+ mvpp2_prs_hw_read(priv, &pe);
+ } else {
+ /* Entry doesn't exist - create new */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = tid;
+
+ /* Shift 4 bytes if DSA tag or 8 bytes in case of EDSA tag*/
+ mvpp2_prs_sram_shift_set(&pe, shift,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA);
+
+ if (tagged) {
+ /* Set tagged bit in DSA tag */
+ mvpp2_prs_tcam_data_byte_set(&pe, 0,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
+ /* Clear all ai bits for next iteration */
+ mvpp2_prs_sram_ai_update(&pe, 0,
+ MVPP2_PRS_SRAM_AI_MASK);
+ /* If packet is tagged continue check vlans */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ } else {
+ /* Set result info bits to 'no vlans' */
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ }
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Set entry for dsa ethertype */
+static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
+ bool add, bool tagged, bool extend)
+{
+ struct mvpp2_prs_entry pe;
+ int tid, shift, port_mask;
+
+ if (extend) {
+ tid = tagged ? MVPP2_PE_ETYPE_EDSA_TAGGED :
+ MVPP2_PE_ETYPE_EDSA_UNTAGGED;
+ port_mask = 0;
+ shift = 8;
+ } else {
+ tid = tagged ? MVPP2_PE_ETYPE_DSA_TAGGED :
+ MVPP2_PE_ETYPE_DSA_UNTAGGED;
+ port_mask = MVPP2_PRS_PORT_MASK;
+ shift = 4;
+ }
+
+ if (priv->prs_shadow[tid].valid) {
+ /* Entry exist - update port only */
+ pe.index = tid;
+ mvpp2_prs_hw_read(priv, &pe);
+ } else {
+ /* Entry doesn't exist - create new */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = tid;
+
+ /* Set ethertype */
+ mvpp2_prs_match_etype(&pe, 0, ETH_P_EDSA);
+ mvpp2_prs_match_etype(&pe, 2, 0);
+
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DSA_MASK,
+ MVPP2_PRS_RI_DSA_MASK);
+ /* Shift ethertype + 2 byte reserved + tag*/
+ mvpp2_prs_sram_shift_set(&pe, 2 + MVPP2_ETH_TYPE_LEN + shift,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA);
+
+ if (tagged) {
+ /* Set tagged bit in DSA tag */
+ mvpp2_prs_tcam_data_byte_set(&pe,
+ MVPP2_ETH_TYPE_LEN + 2 + 3,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
+ MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
+ /* Clear all ai bits for next iteration */
+ mvpp2_prs_sram_ai_update(&pe, 0,
+ MVPP2_PRS_SRAM_AI_MASK);
+ /* If packet is tagged continue check vlans */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ } else {
+ /* Set result info bits to 'no vlans' */
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ }
+ /* Mask/unmask all ports, depending on dsa type */
+ mvpp2_prs_tcam_port_map_set(&pe, port_mask);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(&pe, port, add);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Search for existing single/triple vlan entry */
+static struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2 *priv,
+ unsigned short tpid, int ai)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return NULL;
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+
+ /* Go through the all entries with MVPP2_PRS_LU_VLAN */
+ for (tid = MVPP2_PE_FIRST_FREE_TID;
+ tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ unsigned int ri_bits, ai_bits;
+ bool match;
+
+ if (!priv->prs_shadow[tid].valid ||
+ priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+
+ pe->index = tid;
+
+ mvpp2_prs_hw_read(priv, pe);
+ match = mvpp2_prs_tcam_data_cmp(pe, 0, swab16(tpid));
+ if (!match)
+ continue;
+
+ /* Get vlan type */
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
+
+ /* Get current ai value from tcam */
+ ai_bits = mvpp2_prs_tcam_ai_get(pe);
+ /* Clear double vlan bit */
+ ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT;
+
+ if (ai != ai_bits)
+ continue;
+
+ if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
+ ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
+ return pe;
+ }
+ kfree(pe);
+
+ return NULL;
+}
+
+/* Add/update single/triple vlan entry */
+static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
+ unsigned int port_map)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid_aux, tid;
+
+ pe = mvpp2_prs_vlan_find(priv, tpid, ai);
+
+ if (!pe) {
+ /* Create new tcam entry */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_LAST_FREE_TID,
+ MVPP2_PE_FIRST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return -ENOMEM;
+
+ /* Get last double vlan tid */
+ for (tid_aux = MVPP2_PE_LAST_FREE_TID;
+ tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) {
+ unsigned int ri_bits;
+
+ if (!priv->prs_shadow[tid_aux].valid ||
+ priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+
+ pe->index = tid_aux;
+ mvpp2_prs_hw_read(priv, pe);
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
+ MVPP2_PRS_RI_VLAN_DOUBLE)
+ break;
+ }
+
+ if (tid <= tid_aux)
+ return -EINVAL;
+
+ memset(pe, 0 , sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ pe->index = tid;
+
+ mvpp2_prs_match_etype(pe, 0, tpid);
+
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_L2);
+ /* Shift 4 bytes - skip 1 vlan tag */
+ mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Clear all ai bits for next iteration */
+ mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+
+ if (ai == MVPP2_PRS_SINGLE_VLAN_AI) {
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_SINGLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ } else {
+ ai |= MVPP2_PRS_DBL_VLAN_AI_BIT;
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_TRIPLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ }
+ mvpp2_prs_tcam_ai_update(pe, ai, MVPP2_PRS_SRAM_AI_MASK);
+
+ mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_VLAN);
+ }
+ /* Update ports' mask */
+ mvpp2_prs_tcam_port_map_set(pe, port_map);
+
+ mvpp2_prs_hw_write(priv, pe);
+
+ kfree(pe);
+
+ return 0;
+}
+
+/* Get first free double vlan ai number */
+static int mvpp2_prs_double_vlan_ai_free_get(struct mvpp2 *priv)
+{
+ int i;
+
+ for (i = 1; i < MVPP2_PRS_DBL_VLANS_MAX; i++) {
+ if (!priv->prs_double_vlans[i])
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+/* Search for existing double vlan entry */
+static struct mvpp2_prs_entry *mvpp2_prs_double_vlan_find(struct mvpp2 *priv,
+ unsigned short tpid1,
+ unsigned short tpid2)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return NULL;
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+
+ /* Go through the all entries with MVPP2_PRS_LU_VLAN */
+ for (tid = MVPP2_PE_FIRST_FREE_TID;
+ tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ unsigned int ri_mask;
+ bool match;
+
+ if (!priv->prs_shadow[tid].valid ||
+ priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(priv, pe);
+
+ match = mvpp2_prs_tcam_data_cmp(pe, 0, swab16(tpid1))
+ && mvpp2_prs_tcam_data_cmp(pe, 4, swab16(tpid2));
+
+ if (!match)
+ continue;
+
+ ri_mask = mvpp2_prs_sram_ri_get(pe) & MVPP2_PRS_RI_VLAN_MASK;
+ if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE)
+ return pe;
+ }
+ kfree(pe);
+
+ return NULL;
+}
+
+/* Add or update double vlan entry */
+static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
+ unsigned short tpid2,
+ unsigned int port_map)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid_aux, tid, ai;
+
+ pe = mvpp2_prs_double_vlan_find(priv, tpid1, tpid2);
+
+ if (!pe) {
+ /* Create new tcam entry */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return -ENOMEM;
+
+ /* Set ai value for new double vlan entry */
+ ai = mvpp2_prs_double_vlan_ai_free_get(priv);
+ if (ai < 0)
+ return ai;
+
+ /* Get first single/triple vlan tid */
+ for (tid_aux = MVPP2_PE_FIRST_FREE_TID;
+ tid_aux <= MVPP2_PE_LAST_FREE_TID; tid_aux++) {
+ unsigned int ri_bits;
+
+ if (!priv->prs_shadow[tid_aux].valid ||
+ priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
+ continue;
+
+ pe->index = tid_aux;
+ mvpp2_prs_hw_read(priv, pe);
+ ri_bits = mvpp2_prs_sram_ri_get(pe);
+ ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
+ if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
+ ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
+ break;
+ }
+
+ if (tid >= tid_aux)
+ return -ERANGE;
+
+ memset(pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ pe->index = tid;
+
+ priv->prs_double_vlans[ai] = true;
+
+ mvpp2_prs_match_etype(pe, 0, tpid1);
+ mvpp2_prs_match_etype(pe, 4, tpid2);
+
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN);
+ /* Shift 8 bytes - skip 2 vlan tags */
+ mvpp2_prs_sram_shift_set(pe, 2 * MVPP2_VLAN_TAG_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+ mvpp2_prs_sram_ai_update(pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT,
+ MVPP2_PRS_SRAM_AI_MASK);
+
+ mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_VLAN);
+ }
+
+ /* Update ports' mask */
+ mvpp2_prs_tcam_port_map_set(pe, port_map);
+ mvpp2_prs_hw_write(priv, pe);
+
+ kfree(pe);
+ return 0;
+}
+
+/* IPv4 header parsing for fragmentation and L4 offset */
+static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,
+ unsigned int ri, unsigned int ri_mask)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) &&
+ (proto != IPPROTO_IGMP))
+ return -EINVAL;
+
+ /* Fragmented packet */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = tid;
+
+ /* Set next lu to IPv4 */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Set L4 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct iphdr) - 4,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK,
+ ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Not fragmented packet */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe.index = tid;
+ /* Clear ri before updating */
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* IPv4 L3 multicast or broadcast */
+static int mvpp2_prs_ip4_cast(struct mvpp2 *priv, unsigned short l3_cast)
+{
+ struct mvpp2_prs_entry pe;
+ int mask, tid;
+
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = tid;
+
+ switch (l3_cast) {
+ case MVPP2_PRS_L3_MULTI_CAST:
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV4_MC,
+ MVPP2_PRS_IPV4_MC_MASK);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ break;
+ case MVPP2_PRS_L3_BROAD_CAST:
+ mask = MVPP2_PRS_IPV4_BC_MASK;
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 1, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 2, mask, mask);
+ mvpp2_prs_tcam_data_byte_set(&pe, 3, mask, mask);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_BCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Set entries for protocols over IPv6 */
+static int mvpp2_prs_ip6_proto(struct mvpp2 *priv, unsigned short proto,
+ unsigned int ri, unsigned int ri_mask)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) &&
+ (proto != IPPROTO_ICMPV6) && (proto != IPPROTO_IPIP))
+ return -EINVAL;
+
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ipv6hdr) - 6,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, proto, MVPP2_PRS_TCAM_PROTO_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Write HW */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* IPv6 L3 multicast entry */
+static int mvpp2_prs_ip6_cast(struct mvpp2 *priv, unsigned short l3_cast)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ if (l3_cast != MVPP2_PRS_L3_MULTI_CAST)
+ return -EINVAL;
+
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Shift back to IPv6 NH */
+ mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV6_MC,
+ MVPP2_PRS_IPV6_MC_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Parser per-port initialization */
+static void mvpp2_prs_hw_port_init(struct mvpp2 *priv, int port, int lu_first,
+ int lu_max, int offset)
+{
+ u32 val;
+
+ /* Set lookup ID */
+ val = mvpp2_read(priv, MVPP2_PRS_INIT_LOOKUP_REG);
+ val &= ~MVPP2_PRS_PORT_LU_MASK(port);
+ val |= MVPP2_PRS_PORT_LU_VAL(port, lu_first);
+ mvpp2_write(priv, MVPP2_PRS_INIT_LOOKUP_REG, val);
+
+ /* Set maximum number of loops for packet received from port */
+ val = mvpp2_read(priv, MVPP2_PRS_MAX_LOOP_REG(port));
+ val &= ~MVPP2_PRS_MAX_LOOP_MASK(port);
+ val |= MVPP2_PRS_MAX_LOOP_VAL(port, lu_max);
+ mvpp2_write(priv, MVPP2_PRS_MAX_LOOP_REG(port), val);
+
+ /* Set initial offset for packet header extraction for the first
+ * searching loop
+ */
+ val = mvpp2_read(priv, MVPP2_PRS_INIT_OFFS_REG(port));
+ val &= ~MVPP2_PRS_INIT_OFF_MASK(port);
+ val |= MVPP2_PRS_INIT_OFF_VAL(port, offset);
+ mvpp2_write(priv, MVPP2_PRS_INIT_OFFS_REG(port), val);
+}
+
+/* Default flow entries initialization for all ports */
+static void mvpp2_prs_def_flow_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int port;
+
+ for (port = 0; port < MVPP2_MAX_PORTS; port++) {
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ pe.index = MVPP2_PE_FIRST_DEFAULT_FLOW - port;
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, 0);
+
+ /* Set flow ID*/
+ mvpp2_prs_sram_ai_update(&pe, port, MVPP2_PRS_FLOW_ID_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_hw_write(priv, &pe);
+ }
+}
+
+/* Set default entry for Marvell Header field */
+static void mvpp2_prs_mh_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+
+ pe.index = MVPP2_PE_MH_DEFAULT;
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MH);
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_MH_SIZE,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_MAC);
+
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MH);
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Set default entires (place holder) for promiscuous, non-promiscuous and
+ * multicast MAC addresses
+ */
+static void mvpp2_prs_mac_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+
+ /* Non-promiscuous mode for all ports - DROP unknown packets */
+ pe.index = MVPP2_PE_MAC_NON_PROMISCUOUS;
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
+
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_DROP_MASK);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* place holders only - no ports */
+ mvpp2_prs_mac_drop_all_set(priv, 0, false);
+ mvpp2_prs_mac_promisc_set(priv, 0, false);
+ mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_ALL, 0, false);
+ mvpp2_prs_mac_multi_set(priv, MVPP2_PE_MAC_MC_IP6, 0, false);
+}
+
+/* Set default entries for various types of dsa packets */
+static void mvpp2_prs_dsa_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+
+ /* None tagged EDSA entry - place holder */
+ mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_EDSA);
+
+ /* Tagged EDSA entry - place holder */
+ mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+
+ /* None tagged DSA entry - place holder */
+ mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_UNTAGGED,
+ MVPP2_PRS_DSA);
+
+ /* Tagged DSA entry - place holder */
+ mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+
+ /* None tagged EDSA ethertype entry - place holder*/
+ mvpp2_prs_dsa_tag_ethertype_set(priv, 0, false,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+
+ /* Tagged EDSA ethertype entry - place holder*/
+ mvpp2_prs_dsa_tag_ethertype_set(priv, 0, false,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+
+ /* None tagged DSA ethertype entry */
+ mvpp2_prs_dsa_tag_ethertype_set(priv, 0, true,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+
+ /* Tagged DSA ethertype entry */
+ mvpp2_prs_dsa_tag_ethertype_set(priv, 0, true,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+
+ /* Set default entry, in case DSA or EDSA tag not found */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);
+ pe.index = MVPP2_PE_DSA_DEFAULT;
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+
+ /* Shift 0 bytes */
+ mvpp2_prs_sram_shift_set(&pe, 0, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
+
+ /* Clear all sram ai bits for next iteration */
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ mvpp2_prs_hw_write(priv, &pe);
+}
+
+/* Match basic ethertypes */
+static int mvpp2_prs_etype_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ /* Ethertype: PPPoE */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, ETH_P_PPP_SES);
+
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_PPPOE_HDR_SIZE,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_PPPOE_MASK,
+ MVPP2_PRS_RI_PPPOE_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = false;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_PPPOE_MASK,
+ MVPP2_PRS_RI_PPPOE_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Ethertype: ARP */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, ETH_P_ARP);
+
+ /* Generate flow in the next iteration*/
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_ARP,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = true;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_ARP,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Ethertype: LBTD */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, MVPP2_IP_LBDT_TYPE);
+
+ /* Generate flow in the next iteration*/
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = true;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Ethertype: IPv4 without options */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, ETH_P_IP);
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
+ MVPP2_PRS_IPV4_HEAD_MASK |
+ MVPP2_PRS_IPV4_IHL_MASK);
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Skip eth_type + 4 bytes of IP header */
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = false;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Ethertype: IPv4 with options */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe.index = tid;
+
+ /* Clear tcam data before updating */
+ pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(MVPP2_ETH_TYPE_LEN)] = 0x0;
+ pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(MVPP2_ETH_TYPE_LEN)] = 0x0;
+
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD,
+ MVPP2_PRS_IPV4_HEAD_MASK);
+
+ /* Clear ri before updating */
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = false;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Ethertype: IPv6 without options */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, ETH_P_IPV6);
+
+ /* Skip DIP of IPV6 header */
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 +
+ MVPP2_MAX_L3_ADDR_SIZE,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = false;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Default entry for MVPP2_PRS_LU_L2 - Unknown ethtype */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+ pe.index = MVPP2_PE_ETH_TYPE_UN;
+
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Generate flow in the next iteration*/
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Set L3 offset even it's unknown L3 */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+ priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+ priv->prs_shadow[pe.index].finish = true;
+ mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Configure vlan entries and detect up to 2 successive VLAN tags.
+ * Possible options:
+ * 0x8100, 0x88A8
+ * 0x8100, 0x8100
+ * 0x8100
+ * 0x88A8
+ */
+static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int err;
+
+ priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
+ MVPP2_PRS_DBL_VLANS_MAX,
+ GFP_KERNEL);
+ if (!priv->prs_double_vlans)
+ return -ENOMEM;
+
+ /* Double VLAN: 0x8100, 0x88A8 */
+ err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021Q, ETH_P_8021AD,
+ MVPP2_PRS_PORT_MASK);
+ if (err)
+ return err;
+
+ /* Double VLAN: 0x8100, 0x8100 */
+ err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021Q, ETH_P_8021Q,
+ MVPP2_PRS_PORT_MASK);
+ if (err)
+ return err;
+
+ /* Single VLAN: 0x88a8 */
+ err = mvpp2_prs_vlan_add(priv, ETH_P_8021AD, MVPP2_PRS_SINGLE_VLAN_AI,
+ MVPP2_PRS_PORT_MASK);
+ if (err)
+ return err;
+
+ /* Single VLAN: 0x8100 */
+ err = mvpp2_prs_vlan_add(priv, ETH_P_8021Q, MVPP2_PRS_SINGLE_VLAN_AI,
+ MVPP2_PRS_PORT_MASK);
+ if (err)
+ return err;
+
+ /* Set default double vlan entry */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ pe.index = MVPP2_PE_VLAN_DBL;
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ /* Clear ai for next iterations */
+ mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,
+ MVPP2_PRS_RI_VLAN_MASK);
+
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_DBL_VLAN_AI_BIT,
+ MVPP2_PRS_DBL_VLAN_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Set default vlan none entry */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
+ pe.index = MVPP2_PE_VLAN_NONE;
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
+ MVPP2_PRS_RI_VLAN_MASK);
+
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Set entries for PPPoE ethertype */
+static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int tid;
+
+ /* IPv4 over PPPoE with options */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, PPP_IP);
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Skip eth_type + 4 bytes of IP header */
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* IPv4 over PPPoE without options */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe.index = tid;
+
+ mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
+ MVPP2_PRS_IPV4_HEAD_MASK |
+ MVPP2_PRS_IPV4_IHL_MASK);
+
+ /* Clear ri before updating */
+ pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
+ pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* IPv6 over PPPoE */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+
+ mvpp2_prs_match_etype(&pe, 0, PPP_IPV6);
+
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+ /* Skip eth_type + 4 bytes of IPv6 header */
+ mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Set L3 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Non-IP over PPPoE */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);
+ pe.index = tid;
+
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
+ MVPP2_PRS_RI_L3_PROTO_MASK);
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ /* Set L3 offset even if it's unknown L3 */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
+ MVPP2_ETH_TYPE_LEN,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Initialize entries for IPv4 */
+static int mvpp2_prs_ip4_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int err;
+
+ /* Set entries for TCP, UDP and IGMP over IPv4 */
+ err = mvpp2_prs_ip4_proto(priv, IPPROTO_TCP, MVPP2_PRS_RI_L4_TCP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip4_proto(priv, IPPROTO_UDP, MVPP2_PRS_RI_L4_UDP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip4_proto(priv, IPPROTO_IGMP,
+ MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ if (err)
+ return err;
+
+ /* IPv4 Broadcast */
+ err = mvpp2_prs_ip4_cast(priv, MVPP2_PRS_L3_BROAD_CAST);
+ if (err)
+ return err;
+
+ /* IPv4 Multicast */
+ err = mvpp2_prs_ip4_cast(priv, MVPP2_PRS_L3_MULTI_CAST);
+ if (err)
+ return err;
+
+ /* Default IPv4 entry for unknown protocols */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = MVPP2_PE_IP4_PROTO_UN;
+
+ /* Set next lu to IPv4 */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+ /* Set L4 offset */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct iphdr) - 4,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Default IPv4 entry for unicast address */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);
+ pe.index = MVPP2_PE_IP4_ADDR_UN;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,
+ MVPP2_PRS_IPV4_DIP_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Initialize entries for IPv6 */
+static int mvpp2_prs_ip6_init(struct mvpp2 *priv)
+{
+ struct mvpp2_prs_entry pe;
+ int tid, err;
+
+ /* Set entries for TCP, UDP and ICMP over IPv6 */
+ err = mvpp2_prs_ip6_proto(priv, IPPROTO_TCP,
+ MVPP2_PRS_RI_L4_TCP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip6_proto(priv, IPPROTO_UDP,
+ MVPP2_PRS_RI_L4_UDP,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip6_proto(priv, IPPROTO_ICMPV6,
+ MVPP2_PRS_RI_CPU_CODE_RX_SPEC |
+ MVPP2_PRS_RI_UDF3_RX_SPECIAL,
+ MVPP2_PRS_RI_CPU_CODE_MASK |
+ MVPP2_PRS_RI_UDF3_MASK);
+ if (err)
+ return err;
+
+ /* IPv4 is the last header. This is similar case as 6-TCP or 17-UDP */
+ /* Result Info: UDF7=1, DS lite */
+ err = mvpp2_prs_ip6_proto(priv, IPPROTO_IPIP,
+ MVPP2_PRS_RI_UDF7_IP6_LITE,
+ MVPP2_PRS_RI_UDF7_MASK);
+ if (err)
+ return err;
+
+ /* IPv6 multicast */
+ err = mvpp2_prs_ip6_cast(priv, MVPP2_PRS_L3_MULTI_CAST);
+ if (err)
+ return err;
+
+ /* Entry for checking hop limit */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ MVPP2_PE_LAST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = tid;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN |
+ MVPP2_PRS_RI_DROP_MASK,
+ MVPP2_PRS_RI_L3_PROTO_MASK |
+ MVPP2_PRS_RI_DROP_MASK);
+
+ mvpp2_prs_tcam_data_byte_set(&pe, 1, 0x00, MVPP2_PRS_IPV6_HOP_MASK);
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Default IPv6 entry for unknown protocols */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_PROTO_UN;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+ /* Set L4 offset relatively to our current place */
+ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+ sizeof(struct ipv6hdr) - 4,
+ MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
+
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Default IPv6 entry for unknown ext protocols */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_EXT_PROTO_UN;
+
+ /* Finished: go to flowid generation */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
+ mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,
+ MVPP2_PRS_RI_L4_PROTO_MASK);
+
+ mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_EXT_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ /* Default IPv6 entry for unicast address */
+ memset(&pe, 0, sizeof(struct mvpp2_prs_entry));
+ mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ pe.index = MVPP2_PE_IP6_ADDR_UN;
+
+ /* Finished: go to IPv6 again */
+ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
+ MVPP2_PRS_RI_L3_ADDR_MASK);
+ mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,
+ MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Shift back to IPV6 NH */
+ mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
+ /* Unmask all ports */
+ mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
+
+ /* Update shadow table and hw entry */
+ mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);
+ mvpp2_prs_hw_write(priv, &pe);
+
+ return 0;
+}
+
+/* Parser default initialization */
+static int mvpp2_prs_default_init(struct platform_device *pdev,
+ struct mvpp2 *priv)
+{
+ int err, index, i;
+
+ /* Enable tcam table */
+ mvpp2_write(priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
+
+ /* Clear all tcam and sram entries */
+ for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++) {
+ mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, index);
+ for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)
+ mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), 0);
+
+ mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, index);
+ for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)
+ mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), 0);
+ }
+
+ /* Invalidate all tcam entries */
+ for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++)
+ mvpp2_prs_hw_inv(priv, index);
+
+ priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
+ sizeof(struct mvpp2_prs_shadow),
+ GFP_KERNEL);
+ if (!priv->prs_shadow)
+ return -ENOMEM;
+
+ /* Always start from lookup = 0 */
+ for (index = 0; index < MVPP2_MAX_PORTS; index++)
+ mvpp2_prs_hw_port_init(priv, index, MVPP2_PRS_LU_MH,
+ MVPP2_PRS_PORT_LU_MAX, 0);
+
+ mvpp2_prs_def_flow_init(priv);
+
+ mvpp2_prs_mh_init(priv);
+
+ mvpp2_prs_mac_init(priv);
+
+ mvpp2_prs_dsa_init(priv);
+
+ err = mvpp2_prs_etype_init(priv);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_vlan_init(pdev, priv);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_pppoe_init(priv);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip6_init(priv);
+ if (err)
+ return err;
+
+ err = mvpp2_prs_ip4_init(priv);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+/* Compare MAC DA with tcam entry data */
+static bool mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe,
+ const u8 *da, unsigned char *mask)
+{
+ unsigned char tcam_byte, tcam_mask;
+ int index;
+
+ for (index = 0; index < ETH_ALEN; index++) {
+ mvpp2_prs_tcam_data_byte_get(pe, index, &tcam_byte, &tcam_mask);
+ if (tcam_mask != mask[index])
+ return false;
+
+ if ((tcam_mask & tcam_byte) != (da[index] & mask[index]))
+ return false;
+ }
+
+ return true;
+}
+
+/* Find tcam entry with matched pair <MAC DA, port> */
+static struct mvpp2_prs_entry *
+mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
+ unsigned char *mask, int udf_type)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return NULL;
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
+
+ /* Go through the all entires with MVPP2_PRS_LU_MAC */
+ for (tid = MVPP2_PE_FIRST_FREE_TID;
+ tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ unsigned int entry_pmap;
+
+ if (!priv->prs_shadow[tid].valid ||
+ (priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) ||
+ (priv->prs_shadow[tid].udf != udf_type))
+ continue;
+
+ pe->index = tid;
+ mvpp2_prs_hw_read(priv, pe);
+ entry_pmap = mvpp2_prs_tcam_port_map_get(pe);
+
+ if (mvpp2_prs_mac_range_equals(pe, da, mask) &&
+ entry_pmap == pmap)
+ return pe;
+ }
+ kfree(pe);
+
+ return NULL;
+}
+
+/* Update parser's mac da entry */
+static int mvpp2_prs_mac_da_accept(struct mvpp2 *priv, int port,
+ const u8 *da, bool add)
+{
+ struct mvpp2_prs_entry *pe;
+ unsigned int pmap, len, ri;
+ unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int tid;
+
+ /* Scan TCAM and see if entry with this <MAC DA, port> already exist */
+ pe = mvpp2_prs_mac_da_range_find(priv, (1 << port), da, mask,
+ MVPP2_PRS_UDF_MAC_DEF);
+
+ /* No such entry */
+ if (!pe) {
+ if (!add)
+ return 0;
+
+ /* Create new TCAM entry */
+ /* Find first range mac entry*/
+ for (tid = MVPP2_PE_FIRST_FREE_TID;
+ tid <= MVPP2_PE_LAST_FREE_TID; tid++)
+ if (priv->prs_shadow[tid].valid &&
+ (priv->prs_shadow[tid].lu == MVPP2_PRS_LU_MAC) &&
+ (priv->prs_shadow[tid].udf ==
+ MVPP2_PRS_UDF_MAC_RANGE))
+ break;
+
+ /* Go through the all entries from first to last */
+ tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+ tid - 1);
+ if (tid < 0)
+ return tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return -1;
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
+ pe->index = tid;
+
+ /* Mask all ports */
+ mvpp2_prs_tcam_port_map_set(pe, 0);
+ }
+
+ /* Update port mask */
+ mvpp2_prs_tcam_port_set(pe, port, add);
+
+ /* Invalidate the entry if no ports are left enabled */
+ pmap = mvpp2_prs_tcam_port_map_get(pe);
+ if (pmap == 0) {
+ if (add) {
+ kfree(pe);
+ return -1;
+ }
+ mvpp2_prs_hw_inv(priv, pe->index);
+ priv->prs_shadow[pe->index].valid = false;
+ kfree(pe);
+ return 0;
+ }
+
+ /* Continue - set next lookup */
+ mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_DSA);
+
+ /* Set match on DA */
+ len = ETH_ALEN;
+ while (len--)
+ mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff);
+
+ /* Set result info bits */
+ if (is_broadcast_ether_addr(da))
+ ri = MVPP2_PRS_RI_L2_BCAST;
+ else if (is_multicast_ether_addr(da))
+ ri = MVPP2_PRS_RI_L2_MCAST;
+ else
+ ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK;
+
+ mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK |
+ MVPP2_PRS_RI_MAC_ME_MASK);
+ mvpp2_prs_shadow_ri_set(priv, pe->index, ri, MVPP2_PRS_RI_L2_CAST_MASK |
+ MVPP2_PRS_RI_MAC_ME_MASK);
+
+ /* Shift to ethertype */
+ mvpp2_prs_sram_shift_set(pe, 2 * ETH_ALEN,
+ MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+
+ /* Update shadow table and hw entry */
+ priv->prs_shadow[pe->index].udf = MVPP2_PRS_UDF_MAC_DEF;
+ mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_MAC);
+ mvpp2_prs_hw_write(priv, pe);
+
+ kfree(pe);
+
+ return 0;
+}
+
+static int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ int err;
+
+ /* Remove old parser entry */
+ err = mvpp2_prs_mac_da_accept(port->priv, port->id, dev->dev_addr,
+ false);
+ if (err)
+ return err;
+
+ /* Add new parser entry */
+ err = mvpp2_prs_mac_da_accept(port->priv, port->id, da, true);
+ if (err)
+ return err;
+
+ /* Set addr in the device */
+ ether_addr_copy(dev->dev_addr, da);
+
+ return 0;
+}
+
+/* Delete all port's multicast simple (not range) entries */
+static void mvpp2_prs_mcast_del_all(struct mvpp2 *priv, int port)
+{
+ struct mvpp2_prs_entry pe;
+ int index, tid;
+
+ for (tid = MVPP2_PE_FIRST_FREE_TID;
+ tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
+ unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
+
+ if (!priv->prs_shadow[tid].valid ||
+ (priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) ||
+ (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
+ continue;
+
+ /* Only simple mac entries */
+ pe.index = tid;
+ mvpp2_prs_hw_read(priv, &pe);
+
+ /* Read mac addr from entry */
+ for (index = 0; index < ETH_ALEN; index++)
+ mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],
+ &da_mask[index]);
+
+ if (is_multicast_ether_addr(da) && !is_broadcast_ether_addr(da))
+ /* Delete this entry */
+ mvpp2_prs_mac_da_accept(priv, port, da, false);
+ }
+}
+
+static int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
+{
+ switch (type) {
+ case MVPP2_TAG_TYPE_EDSA:
+ /* Add port to EDSA entries */
+ mvpp2_prs_dsa_tag_set(priv, port, true,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(priv, port, true,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ /* Remove port from DSA entries */
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ break;
+
+ case MVPP2_TAG_TYPE_DSA:
+ /* Add port to DSA entries */
+ mvpp2_prs_dsa_tag_set(priv, port, true,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(priv, port, true,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ /* Remove port from EDSA entries */
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ break;
+
+ case MVPP2_TAG_TYPE_MH:
+ case MVPP2_TAG_TYPE_NONE:
+ /* Remove port form EDSA and DSA entries */
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
+ mvpp2_prs_dsa_tag_set(priv, port, false,
+ MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
+ break;
+
+ default:
+ if ((type < 0) || (type > MVPP2_TAG_TYPE_EDSA))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Set prs flow for the port */
+static int mvpp2_prs_def_flow(struct mvpp2_port *port)
+{
+ struct mvpp2_prs_entry *pe;
+ int tid;
+
+ pe = mvpp2_prs_flow_find(port->priv, port->id);
+
+ /* Such entry not exist */
+ if (!pe) {
+ /* Go through the all entires from last to first */
+ tid = mvpp2_prs_tcam_first_free(port->priv,
+ MVPP2_PE_LAST_FREE_TID,
+ MVPP2_PE_FIRST_FREE_TID);
+ if (tid < 0)
+ return tid;
+
+ pe = kzalloc(sizeof(*pe), GFP_KERNEL);
+ if (!pe)
+ return -ENOMEM;
+
+ mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
+ pe->index = tid;
+
+ /* Set flow ID*/
+ mvpp2_prs_sram_ai_update(pe, port->id, MVPP2_PRS_FLOW_ID_MASK);
+ mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
+
+ /* Update shadow table */
+ mvpp2_prs_shadow_set(port->priv, pe->index, MVPP2_PRS_LU_FLOWS);
+ }
+
+ mvpp2_prs_tcam_port_map_set(pe, (1 << port->id));
+ mvpp2_prs_hw_write(port->priv, pe);
+ kfree(pe);
+
+ return 0;
+}
+
+/* Classifier configuration routines */
+
+/* Update classification flow table registers */
+static void mvpp2_cls_flow_write(struct mvpp2 *priv,
+ struct mvpp2_cls_flow_entry *fe)
+{
+ mvpp2_write(priv, MVPP2_CLS_FLOW_INDEX_REG, fe->index);
+ mvpp2_write(priv, MVPP2_CLS_FLOW_TBL0_REG, fe->data[0]);
+ mvpp2_write(priv, MVPP2_CLS_FLOW_TBL1_REG, fe->data[1]);
+ mvpp2_write(priv, MVPP2_CLS_FLOW_TBL2_REG, fe->data[2]);
+}
+
+/* Update classification lookup table register */
+static void mvpp2_cls_lookup_write(struct mvpp2 *priv,
+ struct mvpp2_cls_lookup_entry *le)
+{
+ u32 val;
+
+ val = (le->way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | le->lkpid;
+ mvpp2_write(priv, MVPP2_CLS_LKP_INDEX_REG, val);
+ mvpp2_write(priv, MVPP2_CLS_LKP_TBL_REG, le->data);
+}
+
+/* Classifier default initialization */
+static void mvpp2_cls_init(struct mvpp2 *priv)
+{
+ struct mvpp2_cls_lookup_entry le;
+ struct mvpp2_cls_flow_entry fe;
+ int index;
+
+ /* Enable classifier */
+ mvpp2_write(priv, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK);
+
+ /* Clear classifier flow table */
+ memset(&fe.data, 0, MVPP2_CLS_FLOWS_TBL_DATA_WORDS);
+ for (index = 0; index < MVPP2_CLS_FLOWS_TBL_SIZE; index++) {
+ fe.index = index;
+ mvpp2_cls_flow_write(priv, &fe);
+ }
+
+ /* Clear classifier lookup table */
+ le.data = 0;
+ for (index = 0; index < MVPP2_CLS_LKP_TBL_SIZE; index++) {
+ le.lkpid = index;
+ le.way = 0;
+ mvpp2_cls_lookup_write(priv, &le);
+
+ le.way = 1;
+ mvpp2_cls_lookup_write(priv, &le);
+ }
+}
+
+static void mvpp2_cls_port_config(struct mvpp2_port *port)
+{
+ struct mvpp2_cls_lookup_entry le;
+ u32 val;
+
+ /* Set way for the port */
+ val = mvpp2_read(port->priv, MVPP2_CLS_PORT_WAY_REG);
+ val &= ~MVPP2_CLS_PORT_WAY_MASK(port->id);
+ mvpp2_write(port->priv, MVPP2_CLS_PORT_WAY_REG, val);
+
+ /* Pick the entry to be accessed in lookup ID decoding table
+ * according to the way and lkpid.
+ */
+ le.lkpid = port->id;
+ le.way = 0;
+ le.data = 0;
+
+ /* Set initial CPU queue for receiving packets */
+ le.data &= ~MVPP2_CLS_LKP_TBL_RXQ_MASK;
+ le.data |= port->first_rxq;
+
+ /* Disable classification engines */
+ le.data &= ~MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK;
+
+ /* Update lookup ID table entry */
+ mvpp2_cls_lookup_write(port->priv, &le);
+}
+
+/* Set CPU queue number for oversize packets */
+static void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port)
+{
+ u32 val;
+
+ mvpp2_write(port->priv, MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port->id),
+ port->first_rxq & MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK);
+
+ mvpp2_write(port->priv, MVPP2_CLS_SWFWD_P2HQ_REG(port->id),
+ (port->first_rxq >> MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS));
+
+ val = mvpp2_read(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG);
+ val |= MVPP2_CLS_SWFWD_PCTRL_MASK(port->id);
+ mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val);
+}
+
+/* Buffer Manager configuration routines */
+
+/* Create pool */
+static int mvpp2_bm_pool_create(struct platform_device *pdev,
+ struct mvpp2 *priv,
+ struct mvpp2_bm_pool *bm_pool, int size)
+{
+ int size_bytes;
+ u32 val;
+
+ size_bytes = sizeof(u32) * size;
+ bm_pool->virt_addr = dma_alloc_coherent(&pdev->dev, size_bytes,
+ &bm_pool->phys_addr,
+ GFP_KERNEL);
+ if (!bm_pool->virt_addr)
+ return -ENOMEM;
+
+ if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVPP2_BM_POOL_PTR_ALIGN)) {
+ dma_free_coherent(&pdev->dev, size_bytes, bm_pool->virt_addr,
+ bm_pool->phys_addr);
+ dev_err(&pdev->dev, "BM pool %d is not %d bytes aligned\n",
+ bm_pool->id, MVPP2_BM_POOL_PTR_ALIGN);
+ return -ENOMEM;
+ }
+
+ mvpp2_write(priv, MVPP2_BM_POOL_BASE_REG(bm_pool->id),
+ bm_pool->phys_addr);
+ mvpp2_write(priv, MVPP2_BM_POOL_SIZE_REG(bm_pool->id), size);
+
+ val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id));
+ val |= MVPP2_BM_START_MASK;
+ mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);
+
+ bm_pool->type = MVPP2_BM_FREE;
+ bm_pool->size = size;
+ bm_pool->pkt_size = 0;
+ bm_pool->buf_num = 0;
+ atomic_set(&bm_pool->in_use, 0);
+ spin_lock_init(&bm_pool->lock);
+
+ return 0;
+}
+
+/* Set pool buffer size */
+static void mvpp2_bm_pool_bufsize_set(struct mvpp2 *priv,
+ struct mvpp2_bm_pool *bm_pool,
+ int buf_size)
+{
+ u32 val;
+
+ bm_pool->buf_size = buf_size;
+
+ val = ALIGN(buf_size, 1 << MVPP2_POOL_BUF_SIZE_OFFSET);
+ mvpp2_write(priv, MVPP2_POOL_BUF_SIZE_REG(bm_pool->id), val);
+}
+
+/* Free all buffers from the pool */
+static void mvpp2_bm_bufs_free(struct mvpp2 *priv, struct mvpp2_bm_pool *bm_pool)
+{
+ int i;
+
+ for (i = 0; i < bm_pool->buf_num; i++) {
+ u32 vaddr;
+
+ /* Get buffer virtual adress (indirect access) */
+ mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id));
+ vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG);
+ if (!vaddr)
+ break;
+ dev_kfree_skb_any((struct sk_buff *)vaddr);
+ }
+
+ /* Update BM driver with number of buffers removed from pool */
+ bm_pool->buf_num -= i;
+}
+
+/* Cleanup pool */
+static int mvpp2_bm_pool_destroy(struct platform_device *pdev,
+ struct mvpp2 *priv,
+ struct mvpp2_bm_pool *bm_pool)
+{
+ u32 val;
+
+ mvpp2_bm_bufs_free(priv, bm_pool);
+ if (bm_pool->buf_num) {
+ WARN(1, "cannot free all buffers in pool %d\n", bm_pool->id);
+ return 0;
+ }
+
+ val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id));
+ val |= MVPP2_BM_STOP_MASK;
+ mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(bm_pool->id), val);
+
+ dma_free_coherent(&pdev->dev, sizeof(u32) * bm_pool->size,
+ bm_pool->virt_addr,
+ bm_pool->phys_addr);
+ return 0;
+}
+
+static int mvpp2_bm_pools_init(struct platform_device *pdev,
+ struct mvpp2 *priv)
+{
+ int i, err, size;
+ struct mvpp2_bm_pool *bm_pool;
+
+ /* Create all pools with maximum size */
+ size = MVPP2_BM_POOL_SIZE_MAX;
+ for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
+ bm_pool = &priv->bm_pools[i];
+ bm_pool->id = i;
+ err = mvpp2_bm_pool_create(pdev, priv, bm_pool, size);
+ if (err)
+ goto err_unroll_pools;
+ mvpp2_bm_pool_bufsize_set(priv, bm_pool, 0);
+ }
+ return 0;
+
+err_unroll_pools:
+ dev_err(&pdev->dev, "failed to create BM pool %d, size %d\n", i, size);
+ for (i = i - 1; i >= 0; i--)
+ mvpp2_bm_pool_destroy(pdev, priv, &priv->bm_pools[i]);
+ return err;
+}
+
+static int mvpp2_bm_init(struct platform_device *pdev, struct mvpp2 *priv)
+{
+ int i, err;
+
+ for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
+ /* Mask BM all interrupts */
+ mvpp2_write(priv, MVPP2_BM_INTR_MASK_REG(i), 0);
+ /* Clear BM cause register */
+ mvpp2_write(priv, MVPP2_BM_INTR_CAUSE_REG(i), 0);
+ }
+
+ /* Allocate and initialize BM pools */
+ priv->bm_pools = devm_kcalloc(&pdev->dev, MVPP2_BM_POOLS_NUM,
+ sizeof(struct mvpp2_bm_pool), GFP_KERNEL);
+ if (!priv->bm_pools)
+ return -ENOMEM;
+
+ err = mvpp2_bm_pools_init(pdev, priv);
+ if (err < 0)
+ return err;
+ return 0;
+}
+
+/* Attach long pool to rxq */
+static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port,
+ int lrxq, int long_pool)
+{
+ u32 val;
+ int prxq;
+
+ /* Get queue physical ID */
+ prxq = port->rxqs[lrxq]->id;
+
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_POOL_LONG_MASK;
+ val |= ((long_pool << MVPP2_RXQ_POOL_LONG_OFFS) &
+ MVPP2_RXQ_POOL_LONG_MASK);
+
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+/* Attach short pool to rxq */
+static void mvpp2_rxq_short_pool_set(struct mvpp2_port *port,
+ int lrxq, int short_pool)
+{
+ u32 val;
+ int prxq;
+
+ /* Get queue physical ID */
+ prxq = port->rxqs[lrxq]->id;
+
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_POOL_SHORT_MASK;
+ val |= ((short_pool << MVPP2_RXQ_POOL_SHORT_OFFS) &
+ MVPP2_RXQ_POOL_SHORT_MASK);
+
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+/* Allocate skb for BM pool */
+static struct sk_buff *mvpp2_skb_alloc(struct mvpp2_port *port,
+ struct mvpp2_bm_pool *bm_pool,
+ dma_addr_t *buf_phys_addr,
+ gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+ dma_addr_t phys_addr;
+
+ skb = __dev_alloc_skb(bm_pool->pkt_size, gfp_mask);
+ if (!skb)
+ return NULL;
+
+ phys_addr = dma_map_single(port->dev->dev.parent, skb->head,
+ MVPP2_RX_BUF_SIZE(bm_pool->pkt_size),
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(port->dev->dev.parent, phys_addr))) {
+ dev_kfree_skb_any(skb);
+ return NULL;
+ }
+ *buf_phys_addr = phys_addr;
+
+ return skb;
+}
+
+/* Set pool number in a BM cookie */
+static inline u32 mvpp2_bm_cookie_pool_set(u32 cookie, int pool)
+{
+ u32 bm;
+
+ bm = cookie & ~(0xFF << MVPP2_BM_COOKIE_POOL_OFFS);
+ bm |= ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS);
+
+ return bm;
+}
+
+/* Get pool number from a BM cookie */
+static inline int mvpp2_bm_cookie_pool_get(u32 cookie)
+{
+ return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF;
+}
+
+/* Release buffer to BM */
+static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
+ u32 buf_phys_addr, u32 buf_virt_addr)
+{
+ mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_virt_addr);
+ mvpp2_write(port->priv, MVPP2_BM_PHY_RLS_REG(pool), buf_phys_addr);
+}
+
+/* Release multicast buffer */
+static void mvpp2_bm_pool_mc_put(struct mvpp2_port *port, int pool,
+ u32 buf_phys_addr, u32 buf_virt_addr,
+ int mc_id)
+{
+ u32 val = 0;
+
+ val |= (mc_id & MVPP2_BM_MC_ID_MASK);
+ mvpp2_write(port->priv, MVPP2_BM_MC_RLS_REG, val);
+
+ mvpp2_bm_pool_put(port, pool,
+ buf_phys_addr | MVPP2_BM_PHY_RLS_MC_BUFF_MASK,
+ buf_virt_addr);
+}
+
+/* Refill BM pool */
+static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm,
+ u32 phys_addr, u32 cookie)
+{
+ int pool = mvpp2_bm_cookie_pool_get(bm);
+
+ mvpp2_bm_pool_put(port, pool, phys_addr, cookie);
+}
+
+/* Allocate buffers for the pool */
+static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
+ struct mvpp2_bm_pool *bm_pool, int buf_num)
+{
+ struct sk_buff *skb;
+ int i, buf_size, total_size;
+ u32 bm;
+ dma_addr_t phys_addr;
+
+ buf_size = MVPP2_RX_BUF_SIZE(bm_pool->pkt_size);
+ total_size = MVPP2_RX_TOTAL_SIZE(buf_size);
+
+ if (buf_num < 0 ||
+ (buf_num + bm_pool->buf_num > bm_pool->size)) {
+ netdev_err(port->dev,
+ "cannot allocate %d buffers for pool %d\n",
+ buf_num, bm_pool->id);
+ return 0;
+ }
+
+ bm = mvpp2_bm_cookie_pool_set(0, bm_pool->id);
+ for (i = 0; i < buf_num; i++) {
+ skb = mvpp2_skb_alloc(port, bm_pool, &phys_addr, GFP_KERNEL);
+ if (!skb)
+ break;
+
+ mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
+ }
+
+ /* Update BM driver with number of buffers added to pool */
+ bm_pool->buf_num += i;
+ bm_pool->in_use_thresh = bm_pool->buf_num / 4;
+
+ netdev_dbg(port->dev,
+ "%s pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n",
+ bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long",
+ bm_pool->id, bm_pool->pkt_size, buf_size, total_size);
+
+ netdev_dbg(port->dev,
+ "%s pool %d: %d of %d buffers added\n",
+ bm_pool->type == MVPP2_BM_SWF_SHORT ? "short" : " long",
+ bm_pool->id, i, buf_num);
+ return i;
+}
+
+/* Notify the driver that BM pool is being used as specific type and return the
+ * pool pointer on success
+ */
+static struct mvpp2_bm_pool *
+mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
+ int pkt_size)
+{
+ unsigned long flags = 0;
+ struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
+ int num;
+
+ if (new_pool->type != MVPP2_BM_FREE && new_pool->type != type) {
+ netdev_err(port->dev, "mixing pool types is forbidden\n");
+ return NULL;
+ }
+
+ spin_lock_irqsave(&new_pool->lock, flags);
+
+ if (new_pool->type == MVPP2_BM_FREE)
+ new_pool->type = type;
+
+ /* Allocate buffers in case BM pool is used as long pool, but packet
+ * size doesn't match MTU or BM pool hasn't being used yet
+ */
+ if (((type == MVPP2_BM_SWF_LONG) && (pkt_size > new_pool->pkt_size)) ||
+ (new_pool->pkt_size == 0)) {
+ int pkts_num;
+
+ /* Set default buffer number or free all the buffers in case
+ * the pool is not empty
+ */
+ pkts_num = new_pool->buf_num;
+ if (pkts_num == 0)
+ pkts_num = type == MVPP2_BM_SWF_LONG ?
+ MVPP2_BM_LONG_BUF_NUM :
+ MVPP2_BM_SHORT_BUF_NUM;
+ else
+ mvpp2_bm_bufs_free(port->priv, new_pool);
+
+ new_pool->pkt_size = pkt_size;
+
+ /* Allocate buffers for this pool */
+ num = mvpp2_bm_bufs_add(port, new_pool, pkts_num);
+ if (num != pkts_num) {
+ WARN(1, "pool %d: %d of %d allocated\n",
+ new_pool->id, num, pkts_num);
+ /* We need to undo the bufs_add() allocations */
+ spin_unlock_irqrestore(&new_pool->lock, flags);
+ return NULL;
+ }
+ }
+
+ mvpp2_bm_pool_bufsize_set(port->priv, new_pool,
+ MVPP2_RX_BUF_SIZE(new_pool->pkt_size));
+
+ spin_unlock_irqrestore(&new_pool->lock, flags);
+
+ return new_pool;
+}
+
+/* Initialize pools for swf */
+static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
+{
+ unsigned long flags = 0;
+ int rxq;
+
+ if (!port->pool_long) {
+ port->pool_long =
+ mvpp2_bm_pool_use(port, MVPP2_BM_SWF_LONG_POOL(port->id),
+ MVPP2_BM_SWF_LONG,
+ port->pkt_size);
+ if (!port->pool_long)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&port->pool_long->lock, flags);
+ port->pool_long->port_map |= (1 << port->id);
+ spin_unlock_irqrestore(&port->pool_long->lock, flags);
+
+ for (rxq = 0; rxq < rxq_number; rxq++)
+ mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
+ }
+
+ if (!port->pool_short) {
+ port->pool_short =
+ mvpp2_bm_pool_use(port, MVPP2_BM_SWF_SHORT_POOL,
+ MVPP2_BM_SWF_SHORT,
+ MVPP2_BM_SHORT_PKT_SIZE);
+ if (!port->pool_short)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&port->pool_short->lock, flags);
+ port->pool_short->port_map |= (1 << port->id);
+ spin_unlock_irqrestore(&port->pool_short->lock, flags);
+
+ for (rxq = 0; rxq < rxq_number; rxq++)
+ mvpp2_rxq_short_pool_set(port, rxq,
+ port->pool_short->id);
+ }
+
+ return 0;
+}
+
+static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2_bm_pool *port_pool = port->pool_long;
+ int num, pkts_num = port_pool->buf_num;
+ int pkt_size = MVPP2_RX_PKT_SIZE(mtu);
+
+ /* Update BM pool with new buffer size */
+ mvpp2_bm_bufs_free(port->priv, port_pool);
+ if (port_pool->buf_num) {
+ WARN(1, "cannot free all buffers in pool %d\n", port_pool->id);
+ return -EIO;
+ }
+
+ port_pool->pkt_size = pkt_size;
+ num = mvpp2_bm_bufs_add(port, port_pool, pkts_num);
+ if (num != pkts_num) {
+ WARN(1, "pool %d: %d of %d allocated\n",
+ port_pool->id, num, pkts_num);
+ return -EIO;
+ }
+
+ mvpp2_bm_pool_bufsize_set(port->priv, port_pool,
+ MVPP2_RX_BUF_SIZE(port_pool->pkt_size));
+ dev->mtu = mtu;
+ netdev_update_features(dev);
+ return 0;
+}
+
+static inline void mvpp2_interrupts_enable(struct mvpp2_port *port)
+{
+ int cpu, cpu_mask = 0;
+
+ for_each_present_cpu(cpu)
+ cpu_mask |= 1 << cpu;
+ mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
+ MVPP2_ISR_ENABLE_INTERRUPT(cpu_mask));
+}
+
+static inline void mvpp2_interrupts_disable(struct mvpp2_port *port)
+{
+ int cpu, cpu_mask = 0;
+
+ for_each_present_cpu(cpu)
+ cpu_mask |= 1 << cpu;
+ mvpp2_write(port->priv, MVPP2_ISR_ENABLE_REG(port->id),
+ MVPP2_ISR_DISABLE_INTERRUPT(cpu_mask));
+}
+
+/* Mask the current CPU's Rx/Tx interrupts */
+static void mvpp2_interrupts_mask(void *arg)
+{
+ struct mvpp2_port *port = arg;
+
+ mvpp2_write(port->priv, MVPP2_ISR_RX_TX_MASK_REG(port->id), 0);
+}
+
+/* Unmask the current CPU's Rx/Tx interrupts */
+static void mvpp2_interrupts_unmask(void *arg)
+{
+ struct mvpp2_port *port = arg;
+
+ mvpp2_write(port->priv, MVPP2_ISR_RX_TX_MASK_REG(port->id),
+ (MVPP2_CAUSE_MISC_SUM_MASK |
+ MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK |
+ MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK));
+}
+
+/* Port configuration routines */
+
+static void mvpp2_port_mii_set(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_2_REG);
+
+ switch (port->phy_interface) {
+ case PHY_INTERFACE_MODE_SGMII:
+ val |= MVPP2_GMAC_INBAND_AN_MASK;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ val |= MVPP2_GMAC_PORT_RGMII_MASK;
+ default:
+ val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
+ }
+
+ writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+}
+
+static void mvpp2_port_fc_adv_enable(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+ val |= MVPP2_GMAC_FC_ADV_EN;
+ writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+}
+
+static void mvpp2_port_enable(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+ val |= MVPP2_GMAC_PORT_EN_MASK;
+ val |= MVPP2_GMAC_MIB_CNTR_EN_MASK;
+ writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+}
+
+static void mvpp2_port_disable(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+ val &= ~(MVPP2_GMAC_PORT_EN_MASK);
+ writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+}
+
+/* Set IEEE 802.3x Flow Control Xon Packet Transmission Mode */
+static void mvpp2_port_periodic_xon_disable(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_1_REG) &
+ ~MVPP2_GMAC_PERIODIC_XON_EN_MASK;
+ writel(val, port->base + MVPP2_GMAC_CTRL_1_REG);
+}
+
+/* Configure loopback port */
+static void mvpp2_port_loopback_set(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_1_REG);
+
+ if (port->speed == 1000)
+ val |= MVPP2_GMAC_GMII_LB_EN_MASK;
+ else
+ val &= ~MVPP2_GMAC_GMII_LB_EN_MASK;
+
+ if (port->phy_interface == PHY_INTERFACE_MODE_SGMII)
+ val |= MVPP2_GMAC_PCS_LB_EN_MASK;
+ else
+ val &= ~MVPP2_GMAC_PCS_LB_EN_MASK;
+
+ writel(val, port->base + MVPP2_GMAC_CTRL_1_REG);
+}
+
+static void mvpp2_port_reset(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
+ ~MVPP2_GMAC_PORT_RESET_MASK;
+ writel(val, port->base + MVPP2_GMAC_CTRL_2_REG);
+
+ while (readl(port->base + MVPP2_GMAC_CTRL_2_REG) &
+ MVPP2_GMAC_PORT_RESET_MASK)
+ continue;
+}
+
+/* Change maximum receive size of the port */
+static inline void mvpp2_gmac_max_rx_size_set(struct mvpp2_port *port)
+{
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_CTRL_0_REG);
+ val &= ~MVPP2_GMAC_MAX_RX_SIZE_MASK;
+ val |= (((port->pkt_size - MVPP2_MH_SIZE) / 2) <<
+ MVPP2_GMAC_MAX_RX_SIZE_OFFS);
+ writel(val, port->base + MVPP2_GMAC_CTRL_0_REG);
+}
+
+/* Set defaults to the MVPP2 port */
+static void mvpp2_defaults_set(struct mvpp2_port *port)
+{
+ int tx_port_num, val, queue, ptxq, lrxq;
+
+ /* Configure port to loopback if needed */
+ if (port->flags & MVPP2_F_LOOPBACK)
+ mvpp2_port_loopback_set(port);
+
+ /* Update TX FIFO MIN Threshold */
+ val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+ val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
+ /* Min. TX threshold must be less than minimal packet length */
+ val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2);
+ writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+
+ /* Disable Legacy WRR, Disable EJP, Release from reset */
+ tx_port_num = mvpp2_egress_port(port);
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG,
+ tx_port_num);
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_CMD_1_REG, 0);
+
+ /* Close bandwidth for all queues */
+ for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) {
+ ptxq = mvpp2_txq_phys(port->id, queue);
+ mvpp2_write(port->priv,
+ MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(ptxq), 0);
+ }
+
+ /* Set refill period to 1 usec, refill tokens
+ * and bucket size to maximum
+ */
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PERIOD_REG,
+ port->priv->tclk / USEC_PER_SEC);
+ val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_REFILL_REG);
+ val &= ~MVPP2_TXP_REFILL_PERIOD_ALL_MASK;
+ val |= MVPP2_TXP_REFILL_PERIOD_MASK(1);
+ val |= MVPP2_TXP_REFILL_TOKENS_ALL_MASK;
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_REFILL_REG, val);
+ val = MVPP2_TXP_TOKEN_SIZE_MAX;
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);
+
+ /* Set MaximumLowLatencyPacketSize value to 256 */
+ mvpp2_write(port->priv, MVPP2_RX_CTRL_REG(port->id),
+ MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK |
+ MVPP2_RX_LOW_LATENCY_PKT_SIZE(256));
+
+ /* Enable Rx cache snoop */
+ for (lrxq = 0; lrxq < rxq_number; lrxq++) {
+ queue = port->rxqs[lrxq]->id;
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
+ val |= MVPP2_SNOOP_PKT_SIZE_MASK |
+ MVPP2_SNOOP_BUF_HDR_MASK;
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
+ }
+
+ /* At default, mask all interrupts to all present cpus */
+ mvpp2_interrupts_disable(port);
+}
+
+/* Enable/disable receiving packets */
+static void mvpp2_ingress_enable(struct mvpp2_port *port)
+{
+ u32 val;
+ int lrxq, queue;
+
+ for (lrxq = 0; lrxq < rxq_number; lrxq++) {
+ queue = port->rxqs[lrxq]->id;
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
+ val &= ~MVPP2_RXQ_DISABLE_MASK;
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
+ }
+}
+
+static void mvpp2_ingress_disable(struct mvpp2_port *port)
+{
+ u32 val;
+ int lrxq, queue;
+
+ for (lrxq = 0; lrxq < rxq_number; lrxq++) {
+ queue = port->rxqs[lrxq]->id;
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(queue));
+ val |= MVPP2_RXQ_DISABLE_MASK;
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(queue), val);
+ }
+}
+
+/* Enable transmit via physical egress queue
+ * - HW starts take descriptors from DRAM
+ */
+static void mvpp2_egress_enable(struct mvpp2_port *port)
+{
+ u32 qmap;
+ int queue;
+ int tx_port_num = mvpp2_egress_port(port);
+
+ /* Enable all initialized TXs. */
+ qmap = 0;
+ for (queue = 0; queue < txq_number; queue++) {
+ struct mvpp2_tx_queue *txq = port->txqs[queue];
+
+ if (txq->descs != NULL)
+ qmap |= (1 << queue);
+ }
+
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG, qmap);
+}
+
+/* Disable transmit via physical egress queue
+ * - HW doesn't take descriptors from DRAM
+ */
+static void mvpp2_egress_disable(struct mvpp2_port *port)
+{
+ u32 reg_data;
+ int delay;
+ int tx_port_num = mvpp2_egress_port(port);
+
+ /* Issue stop command for active channels only */
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
+ reg_data = (mvpp2_read(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG)) &
+ MVPP2_TXP_SCHED_ENQ_MASK;
+ if (reg_data != 0)
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG,
+ (reg_data << MVPP2_TXP_SCHED_DISQ_OFFSET));
+
+ /* Wait for all Tx activity to terminate. */
+ delay = 0;
+ do {
+ if (delay >= MVPP2_TX_DISABLE_TIMEOUT_MSEC) {
+ netdev_warn(port->dev,
+ "Tx stop timed out, status=0x%08x\n",
+ reg_data);
+ break;
+ }
+ mdelay(1);
+ delay++;
+
+ /* Check port TX Command register that all
+ * Tx queues are stopped
+ */
+ reg_data = mvpp2_read(port->priv, MVPP2_TXP_SCHED_Q_CMD_REG);
+ } while (reg_data & MVPP2_TXP_SCHED_ENQ_MASK);
+}
+
+/* Rx descriptors helper methods */
+
+/* Get number of Rx descriptors occupied by received packets */
+static inline int
+mvpp2_rxq_received(struct mvpp2_port *port, int rxq_id)
+{
+ u32 val = mvpp2_read(port->priv, MVPP2_RXQ_STATUS_REG(rxq_id));
+
+ return val & MVPP2_RXQ_OCCUPIED_MASK;
+}
+
+/* Update Rx queue status with the number of occupied and available
+ * Rx descriptor slots.
+ */
+static inline void
+mvpp2_rxq_status_update(struct mvpp2_port *port, int rxq_id,
+ int used_count, int free_count)
+{
+ /* Decrement the number of used descriptors and increment count
+ * increment the number of free descriptors.
+ */
+ u32 val = used_count | (free_count << MVPP2_RXQ_NUM_NEW_OFFSET);
+
+ mvpp2_write(port->priv, MVPP2_RXQ_STATUS_UPDATE_REG(rxq_id), val);
+}
+
+/* Get pointer to next RX descriptor to be processed by SW */
+static inline struct mvpp2_rx_desc *
+mvpp2_rxq_next_desc_get(struct mvpp2_rx_queue *rxq)
+{
+ int rx_desc = rxq->next_desc_to_proc;
+
+ rxq->next_desc_to_proc = MVPP2_QUEUE_NEXT_DESC(rxq, rx_desc);
+ prefetch(rxq->descs + rxq->next_desc_to_proc);
+ return rxq->descs + rx_desc;
+}
+
+/* Set rx queue offset */
+static void mvpp2_rxq_offset_set(struct mvpp2_port *port,
+ int prxq, int offset)
+{
+ u32 val;
+
+ /* Convert offset from bytes to units of 32 bytes */
+ offset = offset >> 5;
+
+ val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
+ val &= ~MVPP2_RXQ_PACKET_OFFSET_MASK;
+
+ /* Offset is in */
+ val |= ((offset << MVPP2_RXQ_PACKET_OFFSET_OFFS) &
+ MVPP2_RXQ_PACKET_OFFSET_MASK);
+
+ mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
+}
+
+/* Obtain BM cookie information from descriptor */
+static u32 mvpp2_bm_cookie_build(struct mvpp2_rx_desc *rx_desc)
+{
+ int pool = (rx_desc->status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+ MVPP2_RXD_BM_POOL_ID_OFFS;
+ int cpu = smp_processor_id();
+
+ return ((pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) |
+ ((cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS);
+}
+
+/* Tx descriptors helper methods */
+
+/* Get number of Tx descriptors waiting to be transmitted by HW */
+static int mvpp2_txq_pend_desc_num_get(struct mvpp2_port *port,
+ struct mvpp2_tx_queue *txq)
+{
+ u32 val;
+
+ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
+ val = mvpp2_read(port->priv, MVPP2_TXQ_PENDING_REG);
+
+ return val & MVPP2_TXQ_PENDING_MASK;
+}
+
+/* Get pointer to next Tx descriptor to be processed (send) by HW */
+static struct mvpp2_tx_desc *
+mvpp2_txq_next_desc_get(struct mvpp2_tx_queue *txq)
+{
+ int tx_desc = txq->next_desc_to_proc;
+
+ txq->next_desc_to_proc = MVPP2_QUEUE_NEXT_DESC(txq, tx_desc);
+ return txq->descs + tx_desc;
+}
+
+/* Update HW with number of aggregated Tx descriptors to be sent */
+static void mvpp2_aggr_txq_pend_desc_add(struct mvpp2_port *port, int pending)
+{
+ /* aggregated access - relevant TXQ number is written in TX desc */
+ mvpp2_write(port->priv, MVPP2_AGGR_TXQ_UPDATE_REG, pending);
+}
+
+
+/* Check if there are enough free descriptors in aggregated txq.
+ * If not, update the number of occupied descriptors and repeat the check.
+ */
+static int mvpp2_aggr_desc_num_check(struct mvpp2 *priv,
+ struct mvpp2_tx_queue *aggr_txq, int num)
+{
+ if ((aggr_txq->count + num) > aggr_txq->size) {
+ /* Update number of occupied aggregated Tx descriptors */
+ int cpu = smp_processor_id();
+ u32 val = mvpp2_read(priv, MVPP2_AGGR_TXQ_STATUS_REG(cpu));
+
+ aggr_txq->count = val & MVPP2_AGGR_TXQ_PENDING_MASK;
+ }
+
+ if ((aggr_txq->count + num) > aggr_txq->size)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/* Reserved Tx descriptors allocation request */
+static int mvpp2_txq_alloc_reserved_desc(struct mvpp2 *priv,
+ struct mvpp2_tx_queue *txq, int num)
+{
+ u32 val;
+
+ val = (txq->id << MVPP2_TXQ_RSVD_REQ_Q_OFFSET) | num;
+ mvpp2_write(priv, MVPP2_TXQ_RSVD_REQ_REG, val);
+
+ val = mvpp2_read(priv, MVPP2_TXQ_RSVD_RSLT_REG);
+
+ return val & MVPP2_TXQ_RSVD_RSLT_MASK;
+}
+
+/* Check if there are enough reserved descriptors for transmission.
+ * If not, request chunk of reserved descriptors and check again.
+ */
+static int mvpp2_txq_reserved_desc_num_proc(struct mvpp2 *priv,
+ struct mvpp2_tx_queue *txq,
+ struct mvpp2_txq_pcpu *txq_pcpu,
+ int num)
+{
+ int req, cpu, desc_count;
+
+ if (txq_pcpu->reserved_num >= num)
+ return 0;
+
+ /* Not enough descriptors reserved! Update the reserved descriptor
+ * count and check again.
+ */
+
+ desc_count = 0;
+ /* Compute total of used descriptors */
+ for_each_present_cpu(cpu) {
+ struct mvpp2_txq_pcpu *txq_pcpu_aux;
+
+ txq_pcpu_aux = per_cpu_ptr(txq->pcpu, cpu);
+ desc_count += txq_pcpu_aux->count;
+ desc_count += txq_pcpu_aux->reserved_num;
+ }
+
+ req = max(MVPP2_CPU_DESC_CHUNK, num - txq_pcpu->reserved_num);
+ desc_count += req;
+
+ if (desc_count >
+ (txq->size - (num_present_cpus() * MVPP2_CPU_DESC_CHUNK)))
+ return -ENOMEM;
+
+ txq_pcpu->reserved_num += mvpp2_txq_alloc_reserved_desc(priv, txq, req);
+
+ /* OK, the descriptor cound has been updated: check again. */
+ if (txq_pcpu->reserved_num < num)
+ return -ENOMEM;
+ return 0;
+}
+
+/* Release the last allocated Tx descriptor. Useful to handle DMA
+ * mapping failures in the Tx path.
+ */
+static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq)
+{
+ if (txq->next_desc_to_proc == 0)
+ txq->next_desc_to_proc = txq->last_desc - 1;
+ else
+ txq->next_desc_to_proc--;
+}
+
+/* Set Tx descriptors fields relevant for CSUM calculation */
+static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
+ int ip_hdr_len, int l4_proto)
+{
+ u32 command;
+
+ /* fields: L3_offset, IP_hdrlen, L3_type, G_IPv4_chk,
+ * G_L4_chk, L4_type required only for checksum calculation
+ */
+ command = (l3_offs << MVPP2_TXD_L3_OFF_SHIFT);
+ command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
+ command |= MVPP2_TXD_IP_CSUM_DISABLE;
+
+ if (l3_proto == swab16(ETH_P_IP)) {
+ command &= ~MVPP2_TXD_IP_CSUM_DISABLE; /* enable IPv4 csum */
+ command &= ~MVPP2_TXD_L3_IP6; /* enable IPv4 */
+ } else {
+ command |= MVPP2_TXD_L3_IP6; /* enable IPv6 */
+ }
+
+ if (l4_proto == IPPROTO_TCP) {
+ command &= ~MVPP2_TXD_L4_UDP; /* enable TCP */
+ command &= ~MVPP2_TXD_L4_CSUM_FRAG; /* generate L4 csum */
+ } else if (l4_proto == IPPROTO_UDP) {
+ command |= MVPP2_TXD_L4_UDP; /* enable UDP */
+ command &= ~MVPP2_TXD_L4_CSUM_FRAG; /* generate L4 csum */
+ } else {
+ command |= MVPP2_TXD_L4_CSUM_NOT;
+ }
+
+ return command;
+}
+
+/* Get number of sent descriptors and decrement counter.
+ * The number of sent descriptors is returned.
+ * Per-CPU access
+ */
+static inline int mvpp2_txq_sent_desc_proc(struct mvpp2_port *port,
+ struct mvpp2_tx_queue *txq)
+{
+ u32 val;
+
+ /* Reading status reg resets transmitted descriptor counter */
+ val = mvpp2_read(port->priv, MVPP2_TXQ_SENT_REG(txq->id));
+
+ return (val & MVPP2_TRANSMITTED_COUNT_MASK) >>
+ MVPP2_TRANSMITTED_COUNT_OFFSET;
+}
+
+static void mvpp2_txq_sent_counter_clear(void *arg)
+{
+ struct mvpp2_port *port = arg;
+ int queue;
+
+ for (queue = 0; queue < txq_number; queue++) {
+ int id = port->txqs[queue]->id;
+
+ mvpp2_read(port->priv, MVPP2_TXQ_SENT_REG(id));
+ }
+}
+
+/* Set max sizes for Tx queues */
+static void mvpp2_txp_max_tx_size_set(struct mvpp2_port *port)
+{
+ u32 val, size, mtu;
+ int txq, tx_port_num;
+
+ mtu = port->pkt_size * 8;
+ if (mtu > MVPP2_TXP_MTU_MAX)
+ mtu = MVPP2_TXP_MTU_MAX;
+
+ /* WA for wrong Token bucket update: Set MTU value = 3*real MTU value */
+ mtu = 3 * mtu;
+
+ /* Indirect access to registers */
+ tx_port_num = mvpp2_egress_port(port);
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
+
+ /* Set MTU */
+ val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_MTU_REG);
+ val &= ~MVPP2_TXP_MTU_MAX;
+ val |= mtu;
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_MTU_REG, val);
+
+ /* TXP token size and all TXQs token size must be larger that MTU */
+ val = mvpp2_read(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG);
+ size = val & MVPP2_TXP_TOKEN_SIZE_MAX;
+ if (size < mtu) {
+ size = mtu;
+ val &= ~MVPP2_TXP_TOKEN_SIZE_MAX;
+ val |= size;
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val);
+ }
+
+ for (txq = 0; txq < txq_number; txq++) {
+ val = mvpp2_read(port->priv,
+ MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq));
+ size = val & MVPP2_TXQ_TOKEN_SIZE_MAX;
+
+ if (size < mtu) {
+ size = mtu;
+ val &= ~MVPP2_TXQ_TOKEN_SIZE_MAX;
+ val |= size;
+ mvpp2_write(port->priv,
+ MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq),
+ val);
+ }
+ }
+}
+
+/* Set the number of packets that will be received before Rx interrupt
+ * will be generated by HW.
+ */
+static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,
+ struct mvpp2_rx_queue *rxq, u32 pkts)
+{
+ u32 val;
+
+ val = (pkts & MVPP2_OCCUPIED_THRESH_MASK);
+ mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, val);
+
+ rxq->pkts_coal = pkts;
+}
+
+/* Set the time delay in usec before Rx interrupt */
+static void mvpp2_rx_time_coal_set(struct mvpp2_port *port,
+ struct mvpp2_rx_queue *rxq, u32 usec)
+{
+ u32 val;
+
+ val = (port->priv->tclk / USEC_PER_SEC) * usec;
+ mvpp2_write(port->priv, MVPP2_ISR_RX_THRESHOLD_REG(rxq->id), val);
+
+ rxq->time_coal = usec;
+}
+
+/* Set threshold for TX_DONE pkts coalescing */
+static void mvpp2_tx_done_pkts_coal_set(void *arg)
+{
+ struct mvpp2_port *port = arg;
+ int queue;
+ u32 val;
+
+ for (queue = 0; queue < txq_number; queue++) {
+ struct mvpp2_tx_queue *txq = port->txqs[queue];
+
+ val = (txq->done_pkts_coal << MVPP2_TRANSMITTED_THRESH_OFFSET) &
+ MVPP2_TRANSMITTED_THRESH_MASK;
+ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(port->priv, MVPP2_TXQ_THRESH_REG, val);
+ }
+}
+
+/* Free Tx queue skbuffs */
+static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
+ struct mvpp2_tx_queue *txq,
+ struct mvpp2_txq_pcpu *txq_pcpu, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ struct mvpp2_tx_desc *tx_desc = txq->descs +
+ txq_pcpu->txq_get_index;
+ struct sk_buff *skb = txq_pcpu->tx_skb[txq_pcpu->txq_get_index];
+
+ mvpp2_txq_inc_get(txq_pcpu);
+
+ if (!skb)
+ continue;
+
+ dma_unmap_single(port->dev->dev.parent, tx_desc->buf_phys_addr,
+ tx_desc->data_size, DMA_TO_DEVICE);
+ dev_kfree_skb_any(skb);
+ }
+}
+
+static inline struct mvpp2_rx_queue *mvpp2_get_rx_queue(struct mvpp2_port *port,
+ u32 cause)
+{
+ int queue = fls(cause) - 1;
+
+ return port->rxqs[queue];
+}
+
+static inline struct mvpp2_tx_queue *mvpp2_get_tx_queue(struct mvpp2_port *port,
+ u32 cause)
+{
+ int queue = fls(cause >> 16) - 1;
+
+ return port->txqs[queue];
+}
+
+/* Handle end of transmission */
+static void mvpp2_txq_done(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
+ struct mvpp2_txq_pcpu *txq_pcpu)
+{
+ struct netdev_queue *nq = netdev_get_tx_queue(port->dev, txq->log_id);
+ int tx_done;
+
+ if (txq_pcpu->cpu != smp_processor_id())
+ netdev_err(port->dev, "wrong cpu on the end of Tx processing\n");
+
+ tx_done = mvpp2_txq_sent_desc_proc(port, txq);
+ if (!tx_done)
+ return;
+ mvpp2_txq_bufs_free(port, txq, txq_pcpu, tx_done);
+
+ txq_pcpu->count -= tx_done;
+
+ if (netif_tx_queue_stopped(nq))
+ if (txq_pcpu->size - txq_pcpu->count >= MAX_SKB_FRAGS + 1)
+ netif_tx_wake_queue(nq);
+}
+
+/* Rx/Tx queue initialization/cleanup methods */
+
+/* Allocate and initialize descriptors for aggr TXQ */
+static int mvpp2_aggr_txq_init(struct platform_device *pdev,
+ struct mvpp2_tx_queue *aggr_txq,
+ int desc_num, int cpu,
+ struct mvpp2 *priv)
+{
+ /* Allocate memory for TX descriptors */
+ aggr_txq->descs = dma_alloc_coherent(&pdev->dev,
+ desc_num * MVPP2_DESC_ALIGNED_SIZE,
+ &aggr_txq->descs_phys, GFP_KERNEL);
+ if (!aggr_txq->descs)
+ return -ENOMEM;
+
+ /* Make sure descriptor address is cache line size aligned */
+ BUG_ON(aggr_txq->descs !=
+ PTR_ALIGN(aggr_txq->descs, MVPP2_CPU_D_CACHE_LINE_SIZE));
+
+ aggr_txq->last_desc = aggr_txq->size - 1;
+
+ /* Aggr TXQ no reset WA */
+ aggr_txq->next_desc_to_proc = mvpp2_read(priv,
+ MVPP2_AGGR_TXQ_INDEX_REG(cpu));
+
+ /* Set Tx descriptors queue starting address */
+ /* indirect access */
+ mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu),
+ aggr_txq->descs_phys);
+ mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu), desc_num);
+
+ return 0;
+}
+
+/* Create a specified Rx queue */
+static int mvpp2_rxq_init(struct mvpp2_port *port,
+ struct mvpp2_rx_queue *rxq)
+
+{
+ rxq->size = port->rx_ring_size;
+
+ /* Allocate memory for RX descriptors */
+ rxq->descs = dma_alloc_coherent(port->dev->dev.parent,
+ rxq->size * MVPP2_DESC_ALIGNED_SIZE,
+ &rxq->descs_phys, GFP_KERNEL);
+ if (!rxq->descs)
+ return -ENOMEM;
+
+ BUG_ON(rxq->descs !=
+ PTR_ALIGN(rxq->descs, MVPP2_CPU_D_CACHE_LINE_SIZE));
+
+ rxq->last_desc = rxq->size - 1;
+
+ /* Zero occupied and non-occupied counters - direct access */
+ mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
+
+ /* Set Rx descriptors queue starting address - indirect access */
+ mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, rxq->descs_phys);
+ mvpp2_write(port->priv, MVPP2_RXQ_DESC_SIZE_REG, rxq->size);
+ mvpp2_write(port->priv, MVPP2_RXQ_INDEX_REG, 0);
+
+ /* Set Offset */
+ mvpp2_rxq_offset_set(port, rxq->id, NET_SKB_PAD);
+
+ /* Set coalescing pkts and time */
+ mvpp2_rx_pkts_coal_set(port, rxq, rxq->pkts_coal);
+ mvpp2_rx_time_coal_set(port, rxq, rxq->time_coal);
+
+ /* Add number of descriptors ready for receiving packets */
+ mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);
+
+ return 0;
+}
+
+/* Push packets received by the RXQ to BM pool */
+static void mvpp2_rxq_drop_pkts(struct mvpp2_port *port,
+ struct mvpp2_rx_queue *rxq)
+{
+ int rx_received, i;
+
+ rx_received = mvpp2_rxq_received(port, rxq->id);
+ if (!rx_received)
+ return;
+
+ for (i = 0; i < rx_received; i++) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
+ u32 bm = mvpp2_bm_cookie_build(rx_desc);
+
+ mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr,
+ rx_desc->buf_cookie);
+ }
+ mvpp2_rxq_status_update(port, rxq->id, rx_received, rx_received);
+}
+
+/* Cleanup Rx queue */
+static void mvpp2_rxq_deinit(struct mvpp2_port *port,
+ struct mvpp2_rx_queue *rxq)
+{
+ mvpp2_rxq_drop_pkts(port, rxq);
+
+ if (rxq->descs)
+ dma_free_coherent(port->dev->dev.parent,
+ rxq->size * MVPP2_DESC_ALIGNED_SIZE,
+ rxq->descs,
+ rxq->descs_phys);
+
+ rxq->descs = NULL;
+ rxq->last_desc = 0;
+ rxq->next_desc_to_proc = 0;
+ rxq->descs_phys = 0;
+
+ /* Clear Rx descriptors queue starting address and size;
+ * free descriptor number
+ */
+ mvpp2_write(port->priv, MVPP2_RXQ_STATUS_REG(rxq->id), 0);
+ mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
+ mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, 0);
+ mvpp2_write(port->priv, MVPP2_RXQ_DESC_SIZE_REG, 0);
+}
+
+/* Create and initialize a Tx queue */
+static int mvpp2_txq_init(struct mvpp2_port *port,
+ struct mvpp2_tx_queue *txq)
+{
+ u32 val;
+ int cpu, desc, desc_per_txq, tx_port_num;
+ struct mvpp2_txq_pcpu *txq_pcpu;
+
+ txq->size = port->tx_ring_size;
+
+ /* Allocate memory for Tx descriptors */
+ txq->descs = dma_alloc_coherent(port->dev->dev.parent,
+ txq->size * MVPP2_DESC_ALIGNED_SIZE,
+ &txq->descs_phys, GFP_KERNEL);
+ if (!txq->descs)
+ return -ENOMEM;
+
+ /* Make sure descriptor address is cache line size aligned */
+ BUG_ON(txq->descs !=
+ PTR_ALIGN(txq->descs, MVPP2_CPU_D_CACHE_LINE_SIZE));
+
+ txq->last_desc = txq->size - 1;
+
+ /* Set Tx descriptors queue starting address - indirect access */
+ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(port->priv, MVPP2_TXQ_DESC_ADDR_REG, txq->descs_phys);
+ mvpp2_write(port->priv, MVPP2_TXQ_DESC_SIZE_REG, txq->size &
+ MVPP2_TXQ_DESC_SIZE_MASK);
+ mvpp2_write(port->priv, MVPP2_TXQ_INDEX_REG, 0);
+ mvpp2_write(port->priv, MVPP2_TXQ_RSVD_CLR_REG,
+ txq->id << MVPP2_TXQ_RSVD_CLR_OFFSET);
+ val = mvpp2_read(port->priv, MVPP2_TXQ_PENDING_REG);
+ val &= ~MVPP2_TXQ_PENDING_MASK;
+ mvpp2_write(port->priv, MVPP2_TXQ_PENDING_REG, val);
+
+ /* Calculate base address in prefetch buffer. We reserve 16 descriptors
+ * for each existing TXQ.
+ * TCONTS for PON port must be continuous from 0 to MVPP2_MAX_TCONT
+ * GBE ports assumed to be continious from 0 to MVPP2_MAX_PORTS
+ */
+ desc_per_txq = 16;
+ desc = (port->id * MVPP2_MAX_TXQ * desc_per_txq) +
+ (txq->log_id * desc_per_txq);
+
+ mvpp2_write(port->priv, MVPP2_TXQ_PREF_BUF_REG,
+ MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 |
+ MVPP2_PREF_BUF_THRESH(desc_per_txq/2));
+
+ /* WRR / EJP configuration - indirect access */
+ tx_port_num = mvpp2_egress_port(port);
+ mvpp2_write(port->priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, tx_port_num);
+
+ val = mvpp2_read(port->priv, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id));
+ val &= ~MVPP2_TXQ_REFILL_PERIOD_ALL_MASK;
+ val |= MVPP2_TXQ_REFILL_PERIOD_MASK(1);
+ val |= MVPP2_TXQ_REFILL_TOKENS_ALL_MASK;
+ mvpp2_write(port->priv, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id), val);
+
+ val = MVPP2_TXQ_TOKEN_SIZE_MAX;
+ mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq->log_id),
+ val);
+
+ for_each_present_cpu(cpu) {
+ txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+ txq_pcpu->size = txq->size;
+ txq_pcpu->tx_skb = kmalloc(txq_pcpu->size *
+ sizeof(*txq_pcpu->tx_skb),
+ GFP_KERNEL);
+ if (!txq_pcpu->tx_skb) {
+ dma_free_coherent(port->dev->dev.parent,
+ txq->size * MVPP2_DESC_ALIGNED_SIZE,
+ txq->descs, txq->descs_phys);
+ return -ENOMEM;
+ }
+
+ txq_pcpu->count = 0;
+ txq_pcpu->reserved_num = 0;
+ txq_pcpu->txq_put_index = 0;
+ txq_pcpu->txq_get_index = 0;
+ }
+
+ return 0;
+}
+
+/* Free allocated TXQ resources */
+static void mvpp2_txq_deinit(struct mvpp2_port *port,
+ struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ int cpu;
+
+ for_each_present_cpu(cpu) {
+ txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+ kfree(txq_pcpu->tx_skb);
+ }
+
+ if (txq->descs)
+ dma_free_coherent(port->dev->dev.parent,
+ txq->size * MVPP2_DESC_ALIGNED_SIZE,
+ txq->descs, txq->descs_phys);
+
+ txq->descs = NULL;
+ txq->last_desc = 0;
+ txq->next_desc_to_proc = 0;
+ txq->descs_phys = 0;
+
+ /* Set minimum bandwidth for disabled TXQs */
+ mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0);
+
+ /* Set Tx descriptors queue starting address and size */
+ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
+ mvpp2_write(port->priv, MVPP2_TXQ_DESC_ADDR_REG, 0);
+ mvpp2_write(port->priv, MVPP2_TXQ_DESC_SIZE_REG, 0);
+}
+
+/* Cleanup Tx ports */
+static void mvpp2_txq_clean(struct mvpp2_port *port, struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ int delay, pending, cpu;
+ u32 val;
+
+ mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
+ val = mvpp2_read(port->priv, MVPP2_TXQ_PREF_BUF_REG);
+ val |= MVPP2_TXQ_DRAIN_EN_MASK;
+ mvpp2_write(port->priv, MVPP2_TXQ_PREF_BUF_REG, val);
+
+ /* The napi queue has been stopped so wait for all packets
+ * to be transmitted.
+ */
+ delay = 0;
+ do {
+ if (delay >= MVPP2_TX_PENDING_TIMEOUT_MSEC) {
+ netdev_warn(port->dev,
+ "port %d: cleaning queue %d timed out\n",
+ port->id, txq->log_id);
+ break;
+ }
+ mdelay(1);
+ delay++;
+
+ pending = mvpp2_txq_pend_desc_num_get(port, txq);
+ } while (pending);
+
+ val &= ~MVPP2_TXQ_DRAIN_EN_MASK;
+ mvpp2_write(port->priv, MVPP2_TXQ_PREF_BUF_REG, val);
+
+ for_each_present_cpu(cpu) {
+ txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+
+ /* Release all packets */
+ mvpp2_txq_bufs_free(port, txq, txq_pcpu, txq_pcpu->count);
+
+ /* Reset queue */
+ txq_pcpu->count = 0;
+ txq_pcpu->txq_put_index = 0;
+ txq_pcpu->txq_get_index = 0;
+ }
+}
+
+/* Cleanup all Tx queues */
+static void mvpp2_cleanup_txqs(struct mvpp2_port *port)
+{
+ struct mvpp2_tx_queue *txq;
+ int queue;
+ u32 val;
+
+ val = mvpp2_read(port->priv, MVPP2_TX_PORT_FLUSH_REG);
+
+ /* Reset Tx ports and delete Tx queues */
+ val |= MVPP2_TX_PORT_FLUSH_MASK(port->id);
+ mvpp2_write(port->priv, MVPP2_TX_PORT_FLUSH_REG, val);
+
+ for (queue = 0; queue < txq_number; queue++) {
+ txq = port->txqs[queue];
+ mvpp2_txq_clean(port, txq);
+ mvpp2_txq_deinit(port, txq);
+ }
+
+ on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);
+
+ val &= ~MVPP2_TX_PORT_FLUSH_MASK(port->id);
+ mvpp2_write(port->priv, MVPP2_TX_PORT_FLUSH_REG, val);
+}
+
+/* Cleanup all Rx queues */
+static void mvpp2_cleanup_rxqs(struct mvpp2_port *port)
+{
+ int queue;
+
+ for (queue = 0; queue < rxq_number; queue++)
+ mvpp2_rxq_deinit(port, port->rxqs[queue]);
+}
+
+/* Init all Rx queues for port */
+static int mvpp2_setup_rxqs(struct mvpp2_port *port)
+{
+ int queue, err;
+
+ for (queue = 0; queue < rxq_number; queue++) {
+ err = mvpp2_rxq_init(port, port->rxqs[queue]);
+ if (err)
+ goto err_cleanup;
+ }
+ return 0;
+
+err_cleanup:
+ mvpp2_cleanup_rxqs(port);
+ return err;
+}
+
+/* Init all tx queues for port */
+static int mvpp2_setup_txqs(struct mvpp2_port *port)
+{
+ struct mvpp2_tx_queue *txq;
+ int queue, err;
+
+ for (queue = 0; queue < txq_number; queue++) {
+ txq = port->txqs[queue];
+ err = mvpp2_txq_init(port, txq);
+ if (err)
+ goto err_cleanup;
+ }
+
+ on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
+ on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);
+ return 0;
+
+err_cleanup:
+ mvpp2_cleanup_txqs(port);
+ return err;
+}
+
+/* The callback for per-port interrupt */
+static irqreturn_t mvpp2_isr(int irq, void *dev_id)
+{
+ struct mvpp2_port *port = (struct mvpp2_port *)dev_id;
+
+ mvpp2_interrupts_disable(port);
+
+ napi_schedule(&port->napi);
+
+ return IRQ_HANDLED;
+}
+
+/* Adjust link */
+static void mvpp2_link_event(struct net_device *dev)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ struct phy_device *phydev = port->phy_dev;
+ int status_change = 0;
+ u32 val;
+
+ if (phydev->link) {
+ if ((port->speed != phydev->speed) ||
+ (port->duplex != phydev->duplex)) {
+ u32 val;
+
+ val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+ val &= ~(MVPP2_GMAC_CONFIG_MII_SPEED |
+ MVPP2_GMAC_CONFIG_GMII_SPEED |
+ MVPP2_GMAC_CONFIG_FULL_DUPLEX |
+ MVPP2_GMAC_AN_SPEED_EN |
+ MVPP2_GMAC_AN_DUPLEX_EN);
+
+ if (phydev->duplex)
+ val |= MVPP2_GMAC_CONFIG_FULL_DUPLEX;
+
+ if (phydev->speed == SPEED_1000)
+ val |= MVPP2_GMAC_CONFIG_GMII_SPEED;
+ else if (phydev->speed == SPEED_100)
+ val |= MVPP2_GMAC_CONFIG_MII_SPEED;
+
+ writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+
+ port->duplex = phydev->duplex;
+ port->speed = phydev->speed;
+ }
+ }
+
+ if (phydev->link != port->link) {
+ if (!phydev->link) {
+ port->duplex = -1;
+ port->speed = 0;
+ }
+
+ port->link = phydev->link;
+ status_change = 1;
+ }
+
+ if (status_change) {
+ if (phydev->link) {
+ val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+ val |= (MVPP2_GMAC_FORCE_LINK_PASS |
+ MVPP2_GMAC_FORCE_LINK_DOWN);
+ writel(val, port->base + MVPP2_GMAC_AUTONEG_CONFIG);
+ mvpp2_egress_enable(port);
+ mvpp2_ingress_enable(port);
+ } else {
+ mvpp2_ingress_disable(port);
+ mvpp2_egress_disable(port);
+ }
+ phy_print_status(phydev);
+ }
+}
+
+/* Main RX/TX processing routines */
+
+/* Display more error info */
+static void mvpp2_rx_error(struct mvpp2_port *port,
+ struct mvpp2_rx_desc *rx_desc)
+{
+ u32 status = rx_desc->status;
+
+ switch (status & MVPP2_RXD_ERR_CODE_MASK) {
+ case MVPP2_RXD_ERR_CRC:
+ netdev_err(port->dev, "bad rx status %08x (crc error), size=%d\n",
+ status, rx_desc->data_size);
+ break;
+ case MVPP2_RXD_ERR_OVERRUN:
+ netdev_err(port->dev, "bad rx status %08x (overrun error), size=%d\n",
+ status, rx_desc->data_size);
+ break;
+ case MVPP2_RXD_ERR_RESOURCE:
+ netdev_err(port->dev, "bad rx status %08x (resource error), size=%d\n",
+ status, rx_desc->data_size);
+ break;
+ }
+}
+
+/* Handle RX checksum offload */
+static void mvpp2_rx_csum(struct mvpp2_port *port, u32 status,
+ struct sk_buff *skb)
+{
+ if (((status & MVPP2_RXD_L3_IP4) &&
+ !(status & MVPP2_RXD_IP4_HEADER_ERR)) ||
+ (status & MVPP2_RXD_L3_IP6))
+ if (((status & MVPP2_RXD_L4_UDP) ||
+ (status & MVPP2_RXD_L4_TCP)) &&
+ (status & MVPP2_RXD_L4_CSUM_OK)) {
+ skb->csum = 0;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ return;
+ }
+
+ skb->ip_summed = CHECKSUM_NONE;
+}
+
+/* Reuse skb if possible, or allocate a new skb and add it to BM pool */
+static int mvpp2_rx_refill(struct mvpp2_port *port,
+ struct mvpp2_bm_pool *bm_pool,
+ u32 bm, int is_recycle)
+{
+ struct sk_buff *skb;
+ dma_addr_t phys_addr;
+
+ if (is_recycle &&
+ (atomic_read(&bm_pool->in_use) < bm_pool->in_use_thresh))
+ return 0;
+
+ /* No recycle or too many buffers are in use, so allocate a new skb */
+ skb = mvpp2_skb_alloc(port, bm_pool, &phys_addr, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
+ atomic_dec(&bm_pool->in_use);
+ return 0;
+}
+
+/* Handle tx checksum */
+static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
+{
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ int ip_hdr_len = 0;
+ u8 l4_proto;
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *ip4h = ip_hdr(skb);
+
+ /* Calculate IPv4 checksum and L4 checksum */
+ ip_hdr_len = ip4h->ihl;
+ l4_proto = ip4h->protocol;
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+
+ /* Read l4_protocol from one of IPv6 extra headers */
+ if (skb_network_header_len(skb) > 0)
+ ip_hdr_len = (skb_network_header_len(skb) >> 2);
+ l4_proto = ip6h->nexthdr;
+ } else {
+ return MVPP2_TXD_L4_CSUM_NOT;
+ }
+
+ return mvpp2_txq_desc_csum(skb_network_offset(skb),
+ skb->protocol, ip_hdr_len, l4_proto);
+ }
+
+ return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
+}
+
+static void mvpp2_buff_hdr_rx(struct mvpp2_port *port,
+ struct mvpp2_rx_desc *rx_desc)
+{
+ struct mvpp2_buff_hdr *buff_hdr;
+ struct sk_buff *skb;
+ u32 rx_status = rx_desc->status;
+ u32 buff_phys_addr;
+ u32 buff_virt_addr;
+ u32 buff_phys_addr_next;
+ u32 buff_virt_addr_next;
+ int mc_id;
+ int pool_id;
+
+ pool_id = (rx_status & MVPP2_RXD_BM_POOL_ID_MASK) >>
+ MVPP2_RXD_BM_POOL_ID_OFFS;
+ buff_phys_addr = rx_desc->buf_phys_addr;
+ buff_virt_addr = rx_desc->buf_cookie;
+
+ do {
+ skb = (struct sk_buff *)buff_virt_addr;
+ buff_hdr = (struct mvpp2_buff_hdr *)skb->head;
+
+ mc_id = MVPP2_B_HDR_INFO_MC_ID(buff_hdr->info);
+
+ buff_phys_addr_next = buff_hdr->next_buff_phys_addr;
+ buff_virt_addr_next = buff_hdr->next_buff_virt_addr;
+
+ /* Release buffer */
+ mvpp2_bm_pool_mc_put(port, pool_id, buff_phys_addr,
+ buff_virt_addr, mc_id);
+
+ buff_phys_addr = buff_phys_addr_next;
+ buff_virt_addr = buff_virt_addr_next;
+
+ } while (!MVPP2_B_HDR_INFO_IS_LAST(buff_hdr->info));
+}
+
+/* Main rx processing */
+static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
+ struct mvpp2_rx_queue *rxq)
+{
+ struct net_device *dev = port->dev;
+ int rx_received, rx_filled, i;
+ u32 rcvd_pkts = 0;
+ u32 rcvd_bytes = 0;
+
+ /* Get number of received packets and clamp the to-do */
+ rx_received = mvpp2_rxq_received(port, rxq->id);
+ if (rx_todo > rx_received)
+ rx_todo = rx_received;
+
+ rx_filled = 0;
+ for (i = 0; i < rx_todo; i++) {
+ struct mvpp2_rx_desc *rx_desc = mvpp2_rxq_next_desc_get(rxq);
+ struct mvpp2_bm_pool *bm_pool;
+ struct sk_buff *skb;
+ u32 bm, rx_status;
+ int pool, rx_bytes, err;
+
+ rx_filled++;
+ rx_status = rx_desc->status;
+ rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE;
+
+ bm = mvpp2_bm_cookie_build(rx_desc);
+ pool = mvpp2_bm_cookie_pool_get(bm);
+ bm_pool = &port->priv->bm_pools[pool];
+ /* Check if buffer header is used */
+ if (rx_status & MVPP2_RXD_BUF_HDR) {
+ mvpp2_buff_hdr_rx(port, rx_desc);
+ continue;
+ }
+
+ /* In case of an error, release the requested buffer pointer
+ * to the Buffer Manager. This request process is controlled
+ * by the hardware, and the information about the buffer is
+ * comprised by the RX descriptor.
+ */
+ if (rx_status & MVPP2_RXD_ERR_SUMMARY) {
+ dev->stats.rx_errors++;
+ mvpp2_rx_error(port, rx_desc);
+ mvpp2_pool_refill(port, bm, rx_desc->buf_phys_addr,
+ rx_desc->buf_cookie);
+ continue;
+ }
+
+ skb = (struct sk_buff *)rx_desc->buf_cookie;
+
+ rcvd_pkts++;
+ rcvd_bytes += rx_bytes;
+ atomic_inc(&bm_pool->in_use);
+
+ skb_reserve(skb, MVPP2_MH_SIZE);
+ skb_put(skb, rx_bytes);
+ skb->protocol = eth_type_trans(skb, dev);
+ mvpp2_rx_csum(port, rx_status, skb);
+
+ napi_gro_receive(&port->napi, skb);
+
+ err = mvpp2_rx_refill(port, bm_pool, bm, 0);
+ if (err) {
+ netdev_err(port->dev, "failed to refill BM pools\n");
+ rx_filled--;
+ }
+ }
+
+ if (rcvd_pkts) {
+ struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->rx_packets += rcvd_pkts;
+ stats->rx_bytes += rcvd_bytes;
+ u64_stats_update_end(&stats->syncp);
+ }
+
+ /* Update Rx queue management counters */
+ wmb();
+ mvpp2_rxq_status_update(port, rxq->id, rx_todo, rx_filled);
+
+ return rx_todo;
+}
+
+static inline void
+tx_desc_unmap_put(struct device *dev, struct mvpp2_tx_queue *txq,
+ struct mvpp2_tx_desc *desc)
+{
+ dma_unmap_single(dev, desc->buf_phys_addr,
+ desc->data_size, DMA_TO_DEVICE);
+ mvpp2_txq_desc_put(txq);
+}
+
+/* Handle tx fragmentation processing */
+static int mvpp2_tx_frag_process(struct mvpp2_port *port, struct sk_buff *skb,
+ struct mvpp2_tx_queue *aggr_txq,
+ struct mvpp2_tx_queue *txq)
+{
+ struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu);
+ struct mvpp2_tx_desc *tx_desc;
+ int i;
+ dma_addr_t buf_phys_addr;
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ void *addr = page_address(frag->page.p) + frag->page_offset;
+
+ tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
+ tx_desc->phys_txq = txq->id;
+ tx_desc->data_size = frag->size;
+
+ buf_phys_addr = dma_map_single(port->dev->dev.parent, addr,
+ tx_desc->data_size,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(port->dev->dev.parent, buf_phys_addr)) {
+ mvpp2_txq_desc_put(txq);
+ goto error;
+ }
+
+ tx_desc->packet_offset = buf_phys_addr & MVPP2_TX_DESC_ALIGN;
+ tx_desc->buf_phys_addr = buf_phys_addr & (~MVPP2_TX_DESC_ALIGN);
+
+ if (i == (skb_shinfo(skb)->nr_frags - 1)) {
+ /* Last descriptor */
+ tx_desc->command = MVPP2_TXD_L_DESC;
+ mvpp2_txq_inc_put(txq_pcpu, skb);
+ } else {
+ /* Descriptor in the middle: Not First, Not Last */
+ tx_desc->command = 0;
+ mvpp2_txq_inc_put(txq_pcpu, NULL);
+ }
+ }
+
+ return 0;
+
+error:
+ /* Release all descriptors that were used to map fragments of
+ * this packet, as well as the corresponding DMA mappings
+ */
+ for (i = i - 1; i >= 0; i--) {
+ tx_desc = txq->descs + i;
+ tx_desc_unmap_put(port->dev->dev.parent, txq, tx_desc);
+ }
+
+ return -ENOMEM;
+}
+
+/* Main tx processing */
+static int mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2_tx_queue *txq, *aggr_txq;
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ struct mvpp2_tx_desc *tx_desc;
+ dma_addr_t buf_phys_addr;
+ int frags = 0;
+ u16 txq_id;
+ u32 tx_cmd;
+
+ txq_id = skb_get_queue_mapping(skb);
+ txq = port->txqs[txq_id];
+ txq_pcpu = this_cpu_ptr(txq->pcpu);
+ aggr_txq = &port->priv->aggr_txqs[smp_processor_id()];
+
+ frags = skb_shinfo(skb)->nr_frags + 1;
+
+ /* Check number of available descriptors */
+ if (mvpp2_aggr_desc_num_check(port->priv, aggr_txq, frags) ||
+ mvpp2_txq_reserved_desc_num_proc(port->priv, txq,
+ txq_pcpu, frags)) {
+ frags = 0;
+ goto out;
+ }
+
+ /* Get a descriptor for the first part of the packet */
+ tx_desc = mvpp2_txq_next_desc_get(aggr_txq);
+ tx_desc->phys_txq = txq->id;
+ tx_desc->data_size = skb_headlen(skb);
+
+ buf_phys_addr = dma_map_single(dev->dev.parent, skb->data,
+ tx_desc->data_size, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev->dev.parent, buf_phys_addr))) {
+ mvpp2_txq_desc_put(txq);
+ frags = 0;
+ goto out;
+ }
+ tx_desc->packet_offset = buf_phys_addr & MVPP2_TX_DESC_ALIGN;
+ tx_desc->buf_phys_addr = buf_phys_addr & ~MVPP2_TX_DESC_ALIGN;
+
+ tx_cmd = mvpp2_skb_tx_csum(port, skb);
+
+ if (frags == 1) {
+ /* First and Last descriptor */
+ tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
+ tx_desc->command = tx_cmd;
+ mvpp2_txq_inc_put(txq_pcpu, skb);
+ } else {
+ /* First but not Last */
+ tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_PADDING_DISABLE;
+ tx_desc->command = tx_cmd;
+ mvpp2_txq_inc_put(txq_pcpu, NULL);
+
+ /* Continue with other skb fragments */
+ if (mvpp2_tx_frag_process(port, skb, aggr_txq, txq)) {
+ tx_desc_unmap_put(port->dev->dev.parent, txq, tx_desc);
+ frags = 0;
+ goto out;
+ }
+ }
+
+ txq_pcpu->reserved_num -= frags;
+ txq_pcpu->count += frags;
+ aggr_txq->count += frags;
+
+ /* Enable transmit */
+ wmb();
+ mvpp2_aggr_txq_pend_desc_add(port, frags);
+
+ if (txq_pcpu->size - txq_pcpu->count < MAX_SKB_FRAGS + 1) {
+ struct netdev_queue *nq = netdev_get_tx_queue(dev, txq_id);
+
+ netif_tx_stop_queue(nq);
+ }
+out:
+ if (frags > 0) {
+ struct mvpp2_pcpu_stats *stats = this_cpu_ptr(port->stats);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->tx_packets++;
+ stats->tx_bytes += skb->len;
+ u64_stats_update_end(&stats->syncp);
+ } else {
+ dev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static inline void mvpp2_cause_error(struct net_device *dev, int cause)
+{
+ if (cause & MVPP2_CAUSE_FCS_ERR_MASK)
+ netdev_err(dev, "FCS error\n");
+ if (cause & MVPP2_CAUSE_RX_FIFO_OVERRUN_MASK)
+ netdev_err(dev, "rx fifo overrun error\n");
+ if (cause & MVPP2_CAUSE_TX_FIFO_UNDERRUN_MASK)
+ netdev_err(dev, "tx fifo underrun error\n");
+}
+
+static void mvpp2_txq_done_percpu(void *arg)
+{
+ struct mvpp2_port *port = arg;
+ u32 cause_rx_tx, cause_tx, cause_misc;
+
+ /* Rx/Tx cause register
+ *
+ * Bits 0-15: each bit indicates received packets on the Rx queue
+ * (bit 0 is for Rx queue 0).
+ *
+ * Bits 16-23: each bit indicates transmitted packets on the Tx queue
+ * (bit 16 is for Tx queue 0).
+ *
+ * Each CPU has its own Rx/Tx cause register
+ */
+ cause_rx_tx = mvpp2_read(port->priv,
+ MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
+ cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+ cause_misc = cause_rx_tx & MVPP2_CAUSE_MISC_SUM_MASK;
+
+ if (cause_misc) {
+ mvpp2_cause_error(port->dev, cause_misc);
+
+ /* Clear the cause register */
+ mvpp2_write(port->priv, MVPP2_ISR_MISC_CAUSE_REG, 0);
+ mvpp2_write(port->priv, MVPP2_ISR_RX_TX_CAUSE_REG(port->id),
+ cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
+ }
+
+ /* Release TX descriptors */
+ if (cause_tx) {
+ struct mvpp2_tx_queue *txq = mvpp2_get_tx_queue(port, cause_tx);
+ struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu);
+
+ if (txq_pcpu->count)
+ mvpp2_txq_done(port, txq, txq_pcpu);
+ }
+}
+
+static int mvpp2_poll(struct napi_struct *napi, int budget)
+{
+ u32 cause_rx_tx, cause_rx;
+ int rx_done = 0;
+ struct mvpp2_port *port = netdev_priv(napi->dev);
+
+ on_each_cpu(mvpp2_txq_done_percpu, port, 1);
+
+ cause_rx_tx = mvpp2_read(port->priv,
+ MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
+ cause_rx = cause_rx_tx & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK;
+
+ /* Process RX packets */
+ cause_rx |= port->pending_cause_rx;
+ while (cause_rx && budget > 0) {
+ int count;
+ struct mvpp2_rx_queue *rxq;
+
+ rxq = mvpp2_get_rx_queue(port, cause_rx);
+ if (!rxq)
+ break;
+
+ count = mvpp2_rx(port, budget, rxq);
+ rx_done += count;
+ budget -= count;
+ if (budget > 0) {
+ /* Clear the bit associated to this Rx queue
+ * so that next iteration will continue from
+ * the next Rx queue.
+ */
+ cause_rx &= ~(1 << rxq->logic_rxq);
+ }
+ }
+
+ if (budget > 0) {
+ cause_rx = 0;
+ napi_complete(napi);
+
+ mvpp2_interrupts_enable(port);
+ }
+ port->pending_cause_rx = cause_rx;
+ return rx_done;
+}
+
+/* Set hw internals when starting port */
+static void mvpp2_start_dev(struct mvpp2_port *port)
+{
+ mvpp2_gmac_max_rx_size_set(port);
+ mvpp2_txp_max_tx_size_set(port);
+
+ napi_enable(&port->napi);
+
+ /* Enable interrupts on all CPUs */
+ mvpp2_interrupts_enable(port);
+
+ mvpp2_port_enable(port);
+ phy_start(port->phy_dev);
+ netif_tx_start_all_queues(port->dev);
+}
+
+/* Set hw internals when stopping port */
+static void mvpp2_stop_dev(struct mvpp2_port *port)
+{
+ /* Stop new packets from arriving to RXQs */
+ mvpp2_ingress_disable(port);
+
+ mdelay(10);
+
+ /* Disable interrupts on all CPUs */
+ mvpp2_interrupts_disable(port);
+
+ napi_disable(&port->napi);
+
+ netif_carrier_off(port->dev);
+ netif_tx_stop_all_queues(port->dev);
+
+ mvpp2_egress_disable(port);
+ mvpp2_port_disable(port);
+ phy_stop(port->phy_dev);
+}
+
+/* Return positive if MTU is valid */
+static inline int mvpp2_check_mtu_valid(struct net_device *dev, int mtu)
+{
+ if (mtu < 68) {
+ netdev_err(dev, "cannot change mtu to less than 68\n");
+ return -EINVAL;
+ }
+
+ /* 9676 == 9700 - 20 and rounding to 8 */
+ if (mtu > 9676) {
+ netdev_info(dev, "illegal MTU value %d, round to 9676\n", mtu);
+ mtu = 9676;
+ }
+
+ if (!IS_ALIGNED(MVPP2_RX_PKT_SIZE(mtu), 8)) {
+ netdev_info(dev, "illegal MTU value %d, round to %d\n", mtu,
+ ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8));
+ mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8);
+ }
+
+ return mtu;
+}
+
+static int mvpp2_check_ringparam_valid(struct net_device *dev,
+ struct ethtool_ringparam *ring)
+{
+ u16 new_rx_pending = ring->rx_pending;
+ u16 new_tx_pending = ring->tx_pending;
+
+ if (ring->rx_pending == 0 || ring->tx_pending == 0)
+ return -EINVAL;
+
+ if (ring->rx_pending > MVPP2_MAX_RXD)
+ new_rx_pending = MVPP2_MAX_RXD;
+ else if (!IS_ALIGNED(ring->rx_pending, 16))
+ new_rx_pending = ALIGN(ring->rx_pending, 16);
+
+ if (ring->tx_pending > MVPP2_MAX_TXD)
+ new_tx_pending = MVPP2_MAX_TXD;
+ else if (!IS_ALIGNED(ring->tx_pending, 32))
+ new_tx_pending = ALIGN(ring->tx_pending, 32);
+
+ if (ring->rx_pending != new_rx_pending) {
+ netdev_info(dev, "illegal Rx ring size value %d, round to %d\n",
+ ring->rx_pending, new_rx_pending);
+ ring->rx_pending = new_rx_pending;
+ }
+
+ if (ring->tx_pending != new_tx_pending) {
+ netdev_info(dev, "illegal Tx ring size value %d, round to %d\n",
+ ring->tx_pending, new_tx_pending);
+ ring->tx_pending = new_tx_pending;
+ }
+
+ return 0;
+}
+
+static void mvpp2_get_mac_address(struct mvpp2_port *port, unsigned char *addr)
+{
+ u32 mac_addr_l, mac_addr_m, mac_addr_h;
+
+ mac_addr_l = readl(port->base + MVPP2_GMAC_CTRL_1_REG);
+ mac_addr_m = readl(port->priv->lms_base + MVPP2_SRC_ADDR_MIDDLE);
+ mac_addr_h = readl(port->priv->lms_base + MVPP2_SRC_ADDR_HIGH);
+ addr[0] = (mac_addr_h >> 24) & 0xFF;
+ addr[1] = (mac_addr_h >> 16) & 0xFF;
+ addr[2] = (mac_addr_h >> 8) & 0xFF;
+ addr[3] = mac_addr_h & 0xFF;
+ addr[4] = mac_addr_m & 0xFF;
+ addr[5] = (mac_addr_l >> MVPP2_GMAC_SA_LOW_OFFS) & 0xFF;
+}
+
+static int mvpp2_phy_connect(struct mvpp2_port *port)
+{
+ struct phy_device *phy_dev;
+
+ phy_dev = of_phy_connect(port->dev, port->phy_node, mvpp2_link_event, 0,
+ port->phy_interface);
+ if (!phy_dev) {
+ netdev_err(port->dev, "cannot connect to phy\n");
+ return -ENODEV;
+ }
+ phy_dev->supported &= PHY_GBIT_FEATURES;
+ phy_dev->advertising = phy_dev->supported;
+
+ port->phy_dev = phy_dev;
+ port->link = 0;
+ port->duplex = 0;
+ port->speed = 0;
+
+ return 0;
+}
+
+static void mvpp2_phy_disconnect(struct mvpp2_port *port)
+{
+ phy_disconnect(port->phy_dev);
+ port->phy_dev = NULL;
+}
+
+static int mvpp2_open(struct net_device *dev)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ unsigned char mac_bcast[ETH_ALEN] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int err;
+
+ err = mvpp2_prs_mac_da_accept(port->priv, port->id, mac_bcast, true);
+ if (err) {
+ netdev_err(dev, "mvpp2_prs_mac_da_accept BC failed\n");
+ return err;
+ }
+ err = mvpp2_prs_mac_da_accept(port->priv, port->id,
+ dev->dev_addr, true);
+ if (err) {
+ netdev_err(dev, "mvpp2_prs_mac_da_accept MC failed\n");
+ return err;
+ }
+ err = mvpp2_prs_tag_mode_set(port->priv, port->id, MVPP2_TAG_TYPE_MH);
+ if (err) {
+ netdev_err(dev, "mvpp2_prs_tag_mode_set failed\n");
+ return err;
+ }
+ err = mvpp2_prs_def_flow(port);
+ if (err) {
+ netdev_err(dev, "mvpp2_prs_def_flow failed\n");
+ return err;
+ }
+
+ /* Allocate the Rx/Tx queues */
+ err = mvpp2_setup_rxqs(port);
+ if (err) {
+ netdev_err(port->dev, "cannot allocate Rx queues\n");
+ return err;
+ }
+
+ err = mvpp2_setup_txqs(port);
+ if (err) {
+ netdev_err(port->dev, "cannot allocate Tx queues\n");
+ goto err_cleanup_rxqs;
+ }
+
+ err = request_irq(port->irq, mvpp2_isr, 0, dev->name, port);
+ if (err) {
+ netdev_err(port->dev, "cannot request IRQ %d\n", port->irq);
+ goto err_cleanup_txqs;
+ }
+
+ /* In default link is down */
+ netif_carrier_off(port->dev);
+
+ err = mvpp2_phy_connect(port);
+ if (err < 0)
+ goto err_free_irq;
+
+ /* Unmask interrupts on all CPUs */
+ on_each_cpu(mvpp2_interrupts_unmask, port, 1);
+
+ mvpp2_start_dev(port);
+
+ return 0;
+
+err_free_irq:
+ free_irq(port->irq, port);
+err_cleanup_txqs:
+ mvpp2_cleanup_txqs(port);
+err_cleanup_rxqs:
+ mvpp2_cleanup_rxqs(port);
+ return err;
+}
+
+static int mvpp2_stop(struct net_device *dev)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ mvpp2_stop_dev(port);
+ mvpp2_phy_disconnect(port);
+
+ /* Mask interrupts on all CPUs */
+ on_each_cpu(mvpp2_interrupts_mask, port, 1);
+
+ free_irq(port->irq, port);
+ mvpp2_cleanup_rxqs(port);
+ mvpp2_cleanup_txqs(port);
+
+ return 0;
+}
+
+static void mvpp2_set_rx_mode(struct net_device *dev)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ struct mvpp2 *priv = port->priv;
+ struct netdev_hw_addr *ha;
+ int id = port->id;
+ bool allmulti = dev->flags & IFF_ALLMULTI;
+
+ mvpp2_prs_mac_promisc_set(priv, id, dev->flags & IFF_PROMISC);
+ mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_ALL, allmulti);
+ mvpp2_prs_mac_multi_set(priv, id, MVPP2_PE_MAC_MC_IP6, allmulti);
+
+ /* Remove all port->id's mcast enries */
+ mvpp2_prs_mcast_del_all(priv, id);
+
+ if (allmulti && !netdev_mc_empty(dev)) {
+ netdev_for_each_mc_addr(ha, dev)
+ mvpp2_prs_mac_da_accept(priv, id, ha->addr, true);
+ }
+}
+
+static int mvpp2_set_mac_address(struct net_device *dev, void *p)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ const struct sockaddr *addr = p;
+ int err;
+
+ if (!is_valid_ether_addr(addr->sa_data)) {
+ err = -EADDRNOTAVAIL;
+ goto error;
+ }
+
+ if (!netif_running(dev)) {
+ err = mvpp2_prs_update_mac_da(dev, addr->sa_data);
+ if (!err)
+ return 0;
+ /* Reconfigure parser to accept the original MAC address */
+ err = mvpp2_prs_update_mac_da(dev, dev->dev_addr);
+ if (err)
+ goto error;
+ }
+
+ mvpp2_stop_dev(port);
+
+ err = mvpp2_prs_update_mac_da(dev, addr->sa_data);
+ if (!err)
+ goto out_start;
+
+ /* Reconfigure parser accept the original MAC address */
+ err = mvpp2_prs_update_mac_da(dev, dev->dev_addr);
+ if (err)
+ goto error;
+out_start:
+ mvpp2_start_dev(port);
+ mvpp2_egress_enable(port);
+ mvpp2_ingress_enable(port);
+ return 0;
+
+error:
+ netdev_err(dev, "fail to change MAC address\n");
+ return err;
+}
+
+static int mvpp2_change_mtu(struct net_device *dev, int mtu)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ int err;
+
+ mtu = mvpp2_check_mtu_valid(dev, mtu);
+ if (mtu < 0) {
+ err = mtu;
+ goto error;
+ }
+
+ if (!netif_running(dev)) {
+ err = mvpp2_bm_update_mtu(dev, mtu);
+ if (!err) {
+ port->pkt_size = MVPP2_RX_PKT_SIZE(mtu);
+ return 0;
+ }
+
+ /* Reconfigure BM to the original MTU */
+ err = mvpp2_bm_update_mtu(dev, dev->mtu);
+ if (err)
+ goto error;
+ }
+
+ mvpp2_stop_dev(port);
+
+ err = mvpp2_bm_update_mtu(dev, mtu);
+ if (!err) {
+ port->pkt_size = MVPP2_RX_PKT_SIZE(mtu);
+ goto out_start;
+ }
+
+ /* Reconfigure BM to the original MTU */
+ err = mvpp2_bm_update_mtu(dev, dev->mtu);
+ if (err)
+ goto error;
+
+out_start:
+ mvpp2_start_dev(port);
+ mvpp2_egress_enable(port);
+ mvpp2_ingress_enable(port);
+
+ return 0;
+
+error:
+ netdev_err(dev, "fail to change MTU\n");
+ return err;
+}
+
+static struct rtnl_link_stats64 *
+mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ unsigned int start;
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ struct mvpp2_pcpu_stats *cpu_stats;
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+
+ cpu_stats = per_cpu_ptr(port->stats, cpu);
+ do {
+ start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
+ rx_packets = cpu_stats->rx_packets;
+ rx_bytes = cpu_stats->rx_bytes;
+ tx_packets = cpu_stats->tx_packets;
+ tx_bytes = cpu_stats->tx_bytes;
+ } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
+
+ stats->rx_packets += rx_packets;
+ stats->rx_bytes += rx_bytes;
+ stats->tx_packets += tx_packets;
+ stats->tx_bytes += tx_bytes;
+ }
+
+ stats->rx_errors = dev->stats.rx_errors;
+ stats->rx_dropped = dev->stats.rx_dropped;
+ stats->tx_dropped = dev->stats.tx_dropped;
+
+ return stats;
+}
+
+static int mvpp2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ int ret;
+
+ if (!port->phy_dev)
+ return -ENOTSUPP;
+
+ ret = phy_mii_ioctl(port->phy_dev, ifr, cmd);
+ if (!ret)
+ mvpp2_link_event(dev);
+
+ return ret;
+}
+
+/* Ethtool methods */
+
+/* Get settings (phy address, speed) for ethtools */
+static int mvpp2_ethtool_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ if (!port->phy_dev)
+ return -ENODEV;
+ return phy_ethtool_gset(port->phy_dev, cmd);
+}
+
+/* Set settings (phy address, speed) for ethtools */
+static int mvpp2_ethtool_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ if (!port->phy_dev)
+ return -ENODEV;
+ return phy_ethtool_sset(port->phy_dev, cmd);
+}
+
+/* Set interrupt coalescing for ethtools */
+static int mvpp2_ethtool_set_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *c)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ int queue;
+
+ for (queue = 0; queue < rxq_number; queue++) {
+ struct mvpp2_rx_queue *rxq = port->rxqs[queue];
+
+ rxq->time_coal = c->rx_coalesce_usecs;
+ rxq->pkts_coal = c->rx_max_coalesced_frames;
+ mvpp2_rx_pkts_coal_set(port, rxq, rxq->pkts_coal);
+ mvpp2_rx_time_coal_set(port, rxq, rxq->time_coal);
+ }
+
+ for (queue = 0; queue < txq_number; queue++) {
+ struct mvpp2_tx_queue *txq = port->txqs[queue];
+
+ txq->done_pkts_coal = c->tx_max_coalesced_frames;
+ }
+
+ on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
+ return 0;
+}
+
+/* get coalescing for ethtools */
+static int mvpp2_ethtool_get_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *c)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ c->rx_coalesce_usecs = port->rxqs[0]->time_coal;
+ c->rx_max_coalesced_frames = port->rxqs[0]->pkts_coal;
+ c->tx_max_coalesced_frames = port->txqs[0]->done_pkts_coal;
+ return 0;
+}
+
+static void mvpp2_ethtool_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strlcpy(drvinfo->driver, MVPP2_DRIVER_NAME,
+ sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, MVPP2_DRIVER_VERSION,
+ sizeof(drvinfo->version));
+ strlcpy(drvinfo->bus_info, dev_name(&dev->dev),
+ sizeof(drvinfo->bus_info));
+}
+
+static void mvpp2_ethtool_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+
+ ring->rx_max_pending = MVPP2_MAX_RXD;
+ ring->tx_max_pending = MVPP2_MAX_TXD;
+ ring->rx_pending = port->rx_ring_size;
+ ring->tx_pending = port->tx_ring_size;
+}
+
+static int mvpp2_ethtool_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ring)
+{
+ struct mvpp2_port *port = netdev_priv(dev);
+ u16 prev_rx_ring_size = port->rx_ring_size;
+ u16 prev_tx_ring_size = port->tx_ring_size;
+ int err;
+
+ err = mvpp2_check_ringparam_valid(dev, ring);
+ if (err)
+ return err;
+
+ if (!netif_running(dev)) {
+ port->rx_ring_size = ring->rx_pending;
+ port->tx_ring_size = ring->tx_pending;
+ return 0;
+ }
+
+ /* The interface is running, so we have to force a
+ * reallocation of the queues
+ */
+ mvpp2_stop_dev(port);
+ mvpp2_cleanup_rxqs(port);
+ mvpp2_cleanup_txqs(port);
+
+ port->rx_ring_size = ring->rx_pending;
+ port->tx_ring_size = ring->tx_pending;
+
+ err = mvpp2_setup_rxqs(port);
+ if (err) {
+ /* Reallocate Rx queues with the original ring size */
+ port->rx_ring_size = prev_rx_ring_size;
+ ring->rx_pending = prev_rx_ring_size;
+ err = mvpp2_setup_rxqs(port);
+ if (err)
+ goto err_out;
+ }
+ err = mvpp2_setup_txqs(port);
+ if (err) {
+ /* Reallocate Tx queues with the original ring size */
+ port->tx_ring_size = prev_tx_ring_size;
+ ring->tx_pending = prev_tx_ring_size;
+ err = mvpp2_setup_txqs(port);
+ if (err)
+ goto err_clean_rxqs;
+ }
+
+ mvpp2_start_dev(port);
+ mvpp2_egress_enable(port);
+ mvpp2_ingress_enable(port);
+
+ return 0;
+
+err_clean_rxqs:
+ mvpp2_cleanup_rxqs(port);
+err_out:
+ netdev_err(dev, "fail to change ring parameters");
+ return err;
+}
+
+/* Device ops */
+
+static const struct net_device_ops mvpp2_netdev_ops = {
+ .ndo_open = mvpp2_open,
+ .ndo_stop = mvpp2_stop,
+ .ndo_start_xmit = mvpp2_tx,
+ .ndo_set_rx_mode = mvpp2_set_rx_mode,
+ .ndo_set_mac_address = mvpp2_set_mac_address,
+ .ndo_change_mtu = mvpp2_change_mtu,
+ .ndo_get_stats64 = mvpp2_get_stats64,
+ .ndo_do_ioctl = mvpp2_ioctl,
+};
+
+static const struct ethtool_ops mvpp2_eth_tool_ops = {
+ .get_link = ethtool_op_get_link,
+ .get_settings = mvpp2_ethtool_get_settings,
+ .set_settings = mvpp2_ethtool_set_settings,
+ .set_coalesce = mvpp2_ethtool_set_coalesce,
+ .get_coalesce = mvpp2_ethtool_get_coalesce,
+ .get_drvinfo = mvpp2_ethtool_get_drvinfo,
+ .get_ringparam = mvpp2_ethtool_get_ringparam,
+ .set_ringparam = mvpp2_ethtool_set_ringparam,
+};
+
+/* Driver initialization */
+
+static void mvpp2_port_power_up(struct mvpp2_port *port)
+{
+ mvpp2_port_mii_set(port);
+ mvpp2_port_periodic_xon_disable(port);
+ mvpp2_port_fc_adv_enable(port);
+ mvpp2_port_reset(port);
+}
+
+/* Initialize port HW */
+static int mvpp2_port_init(struct mvpp2_port *port)
+{
+ struct device *dev = port->dev->dev.parent;
+ struct mvpp2 *priv = port->priv;
+ struct mvpp2_txq_pcpu *txq_pcpu;
+ int queue, cpu, err;
+
+ if (port->first_rxq + rxq_number > MVPP2_RXQ_TOTAL_NUM)
+ return -EINVAL;
+
+ /* Disable port */
+ mvpp2_egress_disable(port);
+ mvpp2_port_disable(port);
+
+ port->txqs = devm_kcalloc(dev, txq_number, sizeof(*port->txqs),
+ GFP_KERNEL);
+ if (!port->txqs)
+ return -ENOMEM;
+
+ /* Associate physical Tx queues to this port and initialize.
+ * The mapping is predefined.
+ */
+ for (queue = 0; queue < txq_number; queue++) {
+ int queue_phy_id = mvpp2_txq_phys(port->id, queue);
+ struct mvpp2_tx_queue *txq;
+
+ txq = devm_kzalloc(dev, sizeof(*txq), GFP_KERNEL);
+ if (!txq)
+ return -ENOMEM;
+
+ txq->pcpu = alloc_percpu(struct mvpp2_txq_pcpu);
+ if (!txq->pcpu) {
+ err = -ENOMEM;
+ goto err_free_percpu;
+ }
+
+ txq->id = queue_phy_id;
+ txq->log_id = queue;
+ txq->done_pkts_coal = MVPP2_TXDONE_COAL_PKTS_THRESH;
+ for_each_present_cpu(cpu) {
+ txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+ txq_pcpu->cpu = cpu;
+ }
+
+ port->txqs[queue] = txq;
+ }
+
+ port->rxqs = devm_kcalloc(dev, rxq_number, sizeof(*port->rxqs),
+ GFP_KERNEL);
+ if (!port->rxqs) {
+ err = -ENOMEM;
+ goto err_free_percpu;
+ }
+
+ /* Allocate and initialize Rx queue for this port */
+ for (queue = 0; queue < rxq_number; queue++) {
+ struct mvpp2_rx_queue *rxq;
+
+ /* Map physical Rx queue to port's logical Rx queue */
+ rxq = devm_kzalloc(dev, sizeof(*rxq), GFP_KERNEL);
+ if (!rxq)
+ goto err_free_percpu;
+ /* Map this Rx queue to a physical queue */
+ rxq->id = port->first_rxq + queue;
+ rxq->port = port->id;
+ rxq->logic_rxq = queue;
+
+ port->rxqs[queue] = rxq;
+ }
+
+ /* Configure Rx queue group interrupt for this port */
+ mvpp2_write(priv, MVPP2_ISR_RXQ_GROUP_REG(port->id), rxq_number);
+
+ /* Create Rx descriptor rings */
+ for (queue = 0; queue < rxq_number; queue++) {
+ struct mvpp2_rx_queue *rxq = port->rxqs[queue];
+
+ rxq->size = port->rx_ring_size;
+ rxq->pkts_coal = MVPP2_RX_COAL_PKTS;
+ rxq->time_coal = MVPP2_RX_COAL_USEC;
+ }
+
+ mvpp2_ingress_disable(port);
+
+ /* Port default configuration */
+ mvpp2_defaults_set(port);
+
+ /* Port's classifier configuration */
+ mvpp2_cls_oversize_rxq_set(port);
+ mvpp2_cls_port_config(port);
+
+ /* Provide an initial Rx packet size */
+ port->pkt_size = MVPP2_RX_PKT_SIZE(port->dev->mtu);
+
+ /* Initialize pools for swf */
+ err = mvpp2_swf_bm_pool_init(port);
+ if (err)
+ goto err_free_percpu;
+
+ return 0;
+
+err_free_percpu:
+ for (queue = 0; queue < txq_number; queue++) {
+ if (!port->txqs[queue])
+ continue;
+ free_percpu(port->txqs[queue]->pcpu);
+ }
+ return err;
+}
+
+/* Ports initialization */
+static int mvpp2_port_probe(struct platform_device *pdev,
+ struct device_node *port_node,
+ struct mvpp2 *priv,
+ int *next_first_rxq)
+{
+ struct device_node *phy_node;
+ struct mvpp2_port *port;
+ struct net_device *dev;
+ struct resource *res;
+ const char *dt_mac_addr;
+ const char *mac_from;
+ char hw_mac_addr[ETH_ALEN];
+ u32 id;
+ int features;
+ int phy_mode;
+ int priv_common_regs_num = 2;
+ int err, i;
+
+ dev = alloc_etherdev_mqs(sizeof(struct mvpp2_port), txq_number,
+ rxq_number);
+ if (!dev)
+ return -ENOMEM;
+
+ phy_node = of_parse_phandle(port_node, "phy", 0);
+ if (!phy_node) {
+ dev_err(&pdev->dev, "missing phy\n");
+ err = -ENODEV;
+ goto err_free_netdev;
+ }
+
+ phy_mode = of_get_phy_mode(port_node);
+ if (phy_mode < 0) {
+ dev_err(&pdev->dev, "incorrect phy mode\n");
+ err = phy_mode;
+ goto err_free_netdev;
+ }
+
+ if (of_property_read_u32(port_node, "port-id", &id)) {
+ err = -EINVAL;
+ dev_err(&pdev->dev, "missing port-id value\n");
+ goto err_free_netdev;
+ }
+
+ dev->tx_queue_len = MVPP2_MAX_TXD;
+ dev->watchdog_timeo = 5 * HZ;
+ dev->netdev_ops = &mvpp2_netdev_ops;
+ dev->ethtool_ops = &mvpp2_eth_tool_ops;
+
+ port = netdev_priv(dev);
+
+ port->irq = irq_of_parse_and_map(port_node, 0);
+ if (port->irq <= 0) {
+ err = -EINVAL;
+ goto err_free_netdev;
+ }
+
+ if (of_property_read_bool(port_node, "marvell,loopback"))
+ port->flags |= MVPP2_F_LOOPBACK;
+
+ port->priv = priv;
+ port->id = id;
+ port->first_rxq = *next_first_rxq;
+ port->phy_node = phy_node;
+ port->phy_interface = phy_mode;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM,
+ priv_common_regs_num + id);
+ port->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(port->base)) {
+ err = PTR_ERR(port->base);
+ goto err_free_irq;
+ }
+
+ /* Alloc per-cpu stats */
+ port->stats = netdev_alloc_pcpu_stats(struct mvpp2_pcpu_stats);
+ if (!port->stats) {
+ err = -ENOMEM;
+ goto err_free_irq;
+ }
+
+ dt_mac_addr = of_get_mac_address(port_node);
+ if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
+ mac_from = "device tree";
+ ether_addr_copy(dev->dev_addr, dt_mac_addr);
+ } else {
+ mvpp2_get_mac_address(port, hw_mac_addr);
+ if (is_valid_ether_addr(hw_mac_addr)) {
+ mac_from = "hardware";
+ ether_addr_copy(dev->dev_addr, hw_mac_addr);
+ } else {
+ mac_from = "random";
+ eth_hw_addr_random(dev);
+ }
+ }
+
+ port->tx_ring_size = MVPP2_MAX_TXD;
+ port->rx_ring_size = MVPP2_MAX_RXD;
+ port->dev = dev;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = mvpp2_port_init(port);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to init port %d\n", id);
+ goto err_free_stats;
+ }
+ mvpp2_port_power_up(port);
+
+ netif_napi_add(dev, &port->napi, mvpp2_poll, NAPI_POLL_WEIGHT);
+ features = NETIF_F_SG | NETIF_F_IP_CSUM;
+ dev->features = features | NETIF_F_RXCSUM;
+ dev->hw_features |= features | NETIF_F_RXCSUM | NETIF_F_GRO;
+ dev->vlan_features |= features;
+
+ err = register_netdev(dev);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register netdev\n");
+ goto err_free_txq_pcpu;
+ }
+ netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
+
+ /* Increment the first Rx queue number to be used by the next port */
+ *next_first_rxq += rxq_number;
+ priv->port_list[id] = port;
+ return 0;
+
+err_free_txq_pcpu:
+ for (i = 0; i < txq_number; i++)
+ free_percpu(port->txqs[i]->pcpu);
+err_free_stats:
+ free_percpu(port->stats);
+err_free_irq:
+ irq_dispose_mapping(port->irq);
+err_free_netdev:
+ free_netdev(dev);
+ return err;
+}
+
+/* Ports removal routine */
+static void mvpp2_port_remove(struct mvpp2_port *port)
+{
+ int i;
+
+ unregister_netdev(port->dev);
+ free_percpu(port->stats);
+ for (i = 0; i < txq_number; i++)
+ free_percpu(port->txqs[i]->pcpu);
+ irq_dispose_mapping(port->irq);
+ free_netdev(port->dev);
+}
+
+/* Initialize decoding windows */
+static void mvpp2_conf_mbus_windows(const struct mbus_dram_target_info *dram,
+ struct mvpp2 *priv)
+{
+ u32 win_enable;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ mvpp2_write(priv, MVPP2_WIN_BASE(i), 0);
+ mvpp2_write(priv, MVPP2_WIN_SIZE(i), 0);
+
+ if (i < 4)
+ mvpp2_write(priv, MVPP2_WIN_REMAP(i), 0);
+ }
+
+ win_enable = 0;
+
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+
+ mvpp2_write(priv, MVPP2_WIN_BASE(i),
+ (cs->base & 0xffff0000) | (cs->mbus_attr << 8) |
+ dram->mbus_dram_target_id);
+
+ mvpp2_write(priv, MVPP2_WIN_SIZE(i),
+ (cs->size - 1) & 0xffff0000);
+
+ win_enable |= (1 << i);
+ }
+
+ mvpp2_write(priv, MVPP2_BASE_ADDR_ENABLE, win_enable);
+}
+
+/* Initialize Rx FIFO's */
+static void mvpp2_rx_fifo_init(struct mvpp2 *priv)
+{
+ int port;
+
+ for (port = 0; port < MVPP2_MAX_PORTS; port++) {
+ mvpp2_write(priv, MVPP2_RX_DATA_FIFO_SIZE_REG(port),
+ MVPP2_RX_FIFO_PORT_DATA_SIZE);
+ mvpp2_write(priv, MVPP2_RX_ATTR_FIFO_SIZE_REG(port),
+ MVPP2_RX_FIFO_PORT_ATTR_SIZE);
+ }
+
+ mvpp2_write(priv, MVPP2_RX_MIN_PKT_SIZE_REG,
+ MVPP2_RX_FIFO_PORT_MIN_PKT);
+ mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
+}
+
+/* Initialize network controller common part HW */
+static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv)
+{
+ const struct mbus_dram_target_info *dram_target_info;
+ int err, i;
+ u32 val;
+
+ /* Checks for hardware constraints */
+ if (rxq_number % 4 || (rxq_number > MVPP2_MAX_RXQ) ||
+ (txq_number > MVPP2_MAX_TXQ)) {
+ dev_err(&pdev->dev, "invalid queue size parameter\n");
+ return -EINVAL;
+ }
+
+ /* MBUS windows configuration */
+ dram_target_info = mv_mbus_dram_info();
+ if (dram_target_info)
+ mvpp2_conf_mbus_windows(dram_target_info, priv);
+
+ /* Disable HW PHY polling */
+ val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
+ val |= MVPP2_PHY_AN_STOP_SMI0_MASK;
+ writel(val, priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
+
+ /* Allocate and initialize aggregated TXQs */
+ priv->aggr_txqs = devm_kcalloc(&pdev->dev, num_present_cpus(),
+ sizeof(struct mvpp2_tx_queue),
+ GFP_KERNEL);
+ if (!priv->aggr_txqs)
+ return -ENOMEM;
+
+ for_each_present_cpu(i) {
+ priv->aggr_txqs[i].id = i;
+ priv->aggr_txqs[i].size = MVPP2_AGGR_TXQ_SIZE;
+ err = mvpp2_aggr_txq_init(pdev, &priv->aggr_txqs[i],
+ MVPP2_AGGR_TXQ_SIZE, i, priv);
+ if (err < 0)
+ return err;
+ }
+
+ /* Rx Fifo Init */
+ mvpp2_rx_fifo_init(priv);
+
+ /* Reset Rx queue group interrupt configuration */
+ for (i = 0; i < MVPP2_MAX_PORTS; i++)
+ mvpp2_write(priv, MVPP2_ISR_RXQ_GROUP_REG(i), rxq_number);
+
+ writel(MVPP2_EXT_GLOBAL_CTRL_DEFAULT,
+ priv->lms_base + MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG);
+
+ /* Allow cache snoop when transmiting packets */
+ mvpp2_write(priv, MVPP2_TX_SNOOP_REG, 0x1);
+
+ /* Buffer Manager initialization */
+ err = mvpp2_bm_init(pdev, priv);
+ if (err < 0)
+ return err;
+
+ /* Parser default initialization */
+ err = mvpp2_prs_default_init(pdev, priv);
+ if (err < 0)
+ return err;
+
+ /* Classifier default initialization */
+ mvpp2_cls_init(priv);
+
+ return 0;
+}
+
+static int mvpp2_probe(struct platform_device *pdev)
+{
+ struct device_node *dn = pdev->dev.of_node;
+ struct device_node *port_node;
+ struct mvpp2 *priv;
+ struct resource *res;
+ int port_count, first_rxq;
+ int err;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct mvpp2), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ priv->lms_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->lms_base))
+ return PTR_ERR(priv->lms_base);
+
+ priv->pp_clk = devm_clk_get(&pdev->dev, "pp_clk");
+ if (IS_ERR(priv->pp_clk))
+ return PTR_ERR(priv->pp_clk);
+ err = clk_prepare_enable(priv->pp_clk);
+ if (err < 0)
+ return err;
+
+ priv->gop_clk = devm_clk_get(&pdev->dev, "gop_clk");
+ if (IS_ERR(priv->gop_clk)) {
+ err = PTR_ERR(priv->gop_clk);
+ goto err_pp_clk;
+ }
+ err = clk_prepare_enable(priv->gop_clk);
+ if (err < 0)
+ goto err_pp_clk;
+
+ /* Get system's tclk rate */
+ priv->tclk = clk_get_rate(priv->pp_clk);
+
+ /* Initialize network controller */
+ err = mvpp2_init(pdev, priv);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to initialize controller\n");
+ goto err_gop_clk;
+ }
+
+ port_count = of_get_available_child_count(dn);
+ if (port_count == 0) {
+ dev_err(&pdev->dev, "no ports enabled\n");
+ err = -ENODEV;
+ goto err_gop_clk;
+ }
+
+ priv->port_list = devm_kcalloc(&pdev->dev, port_count,
+ sizeof(struct mvpp2_port *),
+ GFP_KERNEL);
+ if (!priv->port_list) {
+ err = -ENOMEM;
+ goto err_gop_clk;
+ }
+
+ /* Initialize ports */
+ first_rxq = 0;
+ for_each_available_child_of_node(dn, port_node) {
+ err = mvpp2_port_probe(pdev, port_node, priv, &first_rxq);
+ if (err < 0)
+ goto err_gop_clk;
+ }
+
+ platform_set_drvdata(pdev, priv);
+ return 0;
+
+err_gop_clk:
+ clk_disable_unprepare(priv->gop_clk);
+err_pp_clk:
+ clk_disable_unprepare(priv->pp_clk);
+ return err;
+}
+
+static int mvpp2_remove(struct platform_device *pdev)
+{
+ struct mvpp2 *priv = platform_get_drvdata(pdev);
+ struct device_node *dn = pdev->dev.of_node;
+ struct device_node *port_node;
+ int i = 0;
+
+ for_each_available_child_of_node(dn, port_node) {
+ if (priv->port_list[i])
+ mvpp2_port_remove(priv->port_list[i]);
+ i++;
+ }
+
+ for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
+ struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i];
+
+ mvpp2_bm_pool_destroy(pdev, priv, bm_pool);
+ }
+
+ for_each_present_cpu(i) {
+ struct mvpp2_tx_queue *aggr_txq = &priv->aggr_txqs[i];
+
+ dma_free_coherent(&pdev->dev,
+ MVPP2_AGGR_TXQ_SIZE * MVPP2_DESC_ALIGNED_SIZE,
+ aggr_txq->descs,
+ aggr_txq->descs_phys);
+ }
+
+ clk_disable_unprepare(priv->pp_clk);
+ clk_disable_unprepare(priv->gop_clk);
+
+ return 0;
+}
+
+static const struct of_device_id mvpp2_match[] = {
+ { .compatible = "marvell,armada-375-pp2" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mvpp2_match);
+
+static struct platform_driver mvpp2_driver = {
+ .probe = mvpp2_probe,
+ .remove = mvpp2_remove,
+ .driver = {
+ .name = MVPP2_DRIVER_NAME,
+ .of_match_table = mvpp2_match,
+ },
+};
+
+module_platform_driver(mvpp2_driver);
+
+MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com");
+MODULE_AUTHOR("Marcin Wojtas <mw@semihalf.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index 80f725228f5b..56022d647837 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -294,8 +294,6 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
init_completion(&cq->free);
cq->irq = priv->eq_table.eq[cq->vector].irq;
- cq->irq_affinity_change = false;
-
return 0;
err_radix:
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 4b2130760eed..82322b1c8411 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -128,11 +128,16 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
mlx4_warn(mdev, "Failed assigning an EQ to %s, falling back to legacy EQ's\n",
name);
}
+
}
} else {
cq->vector = (cq->ring + 1 + priv->port) %
mdev->dev->caps.num_comp_vectors;
}
+
+ cq->irq_desc =
+ irq_to_desc(mlx4_eq_get_irq(mdev->dev,
+ cq->vector));
} else {
/* For TX we use the same irq per
ring we assigned for the RX */
@@ -187,8 +192,6 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
mlx4_en_unmap_buffer(&cq->wqres.buf);
mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
if (priv->mdev->dev->caps.comp_pool && cq->vector) {
- if (!cq->is_tx)
- irq_set_affinity_hint(cq->mcq.irq, NULL);
mlx4_release_eq(priv->mdev->dev, cq->vector);
}
cq->vector = 0;
@@ -204,6 +207,7 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
if (!cq->is_tx) {
napi_hash_del(&cq->napi);
synchronize_rcu();
+ irq_set_affinity_hint(cq->mcq.irq, NULL);
}
netif_napi_del(&cq->napi);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index fa1a069e14e6..e22f24f784fc 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -98,6 +98,10 @@ mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
drvinfo->eedump_len = 0;
}
+static const char mlx4_en_priv_flags[][ETH_GSTRING_LEN] = {
+ "blueflame",
+};
+
static const char main_strings[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -235,6 +239,8 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
case ETH_SS_TEST:
return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
+ case ETH_SS_PRIV_FLAGS:
+ return ARRAY_SIZE(mlx4_en_priv_flags);
default:
return -EOPNOTSUPP;
}
@@ -358,6 +364,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
#endif
}
break;
+ case ETH_SS_PRIV_FLAGS:
+ for (i = 0; i < ARRAY_SIZE(mlx4_en_priv_flags); i++)
+ strcpy(data + i * ETH_GSTRING_LEN,
+ mlx4_en_priv_flags[i]);
+ break;
+
}
}
@@ -417,6 +429,8 @@ static int mlx4_en_get_coalesce(struct net_device *dev,
coal->tx_coalesce_usecs = priv->tx_usecs;
coal->tx_max_coalesced_frames = priv->tx_frames;
+ coal->tx_max_coalesced_frames_irq = priv->tx_work_limit;
+
coal->rx_coalesce_usecs = priv->rx_usecs;
coal->rx_max_coalesced_frames = priv->rx_frames;
@@ -426,6 +440,7 @@ static int mlx4_en_get_coalesce(struct net_device *dev,
coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
coal->rate_sample_interval = priv->sample_interval;
coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
+
return 0;
}
@@ -434,6 +449,9 @@ static int mlx4_en_set_coalesce(struct net_device *dev,
{
struct mlx4_en_priv *priv = netdev_priv(dev);
+ if (!coal->tx_max_coalesced_frames_irq)
+ return -EINVAL;
+
priv->rx_frames = (coal->rx_max_coalesced_frames ==
MLX4_EN_AUTO_CONF) ?
MLX4_EN_RX_COAL_TARGET :
@@ -457,6 +475,7 @@ static int mlx4_en_set_coalesce(struct net_device *dev,
priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
priv->sample_interval = coal->rate_sample_interval;
priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
+ priv->tx_work_limit = coal->tx_max_coalesced_frames_irq;
return mlx4_en_moderation_update(priv);
}
@@ -1202,6 +1221,49 @@ static int mlx4_en_get_ts_info(struct net_device *dev,
return ret;
}
+static int mlx4_en_set_priv_flags(struct net_device *dev, u32 flags)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ bool bf_enabled_new = !!(flags & MLX4_EN_PRIV_FLAGS_BLUEFLAME);
+ bool bf_enabled_old = !!(priv->pflags & MLX4_EN_PRIV_FLAGS_BLUEFLAME);
+ int i;
+
+ if (bf_enabled_new == bf_enabled_old)
+ return 0; /* Nothing to do */
+
+ if (bf_enabled_new) {
+ bool bf_supported = true;
+
+ for (i = 0; i < priv->tx_ring_num; i++)
+ bf_supported &= priv->tx_ring[i]->bf_alloced;
+
+ if (!bf_supported) {
+ en_err(priv, "BlueFlame is not supported\n");
+ return -EINVAL;
+ }
+
+ priv->pflags |= MLX4_EN_PRIV_FLAGS_BLUEFLAME;
+ } else {
+ priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;
+ }
+
+ for (i = 0; i < priv->tx_ring_num; i++)
+ priv->tx_ring[i]->bf_enabled = bf_enabled_new;
+
+ en_info(priv, "BlueFlame %s\n",
+ bf_enabled_new ? "Enabled" : "Disabled");
+
+ return 0;
+}
+
+static u32 mlx4_en_get_priv_flags(struct net_device *dev)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+
+ return priv->pflags;
+}
+
+
const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_drvinfo = mlx4_en_get_drvinfo,
.get_settings = mlx4_en_get_settings,
@@ -1229,6 +1291,8 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
.get_channels = mlx4_en_get_channels,
.set_channels = mlx4_en_set_channels,
.get_ts_info = mlx4_en_get_ts_info,
+ .set_priv_flags = mlx4_en_set_priv_flags,
+ .get_priv_flags = mlx4_en_get_priv_flags,
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index f953c1d7eae6..3626fdf4cb5d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -129,8 +129,10 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
int i;
params->udp_rss = udp_rss;
- params->num_tx_rings_p_up = min_t(int, num_online_cpus(),
- MLX4_EN_MAX_TX_RING_P_UP);
+ params->num_tx_rings_p_up = mlx4_low_memory_profile() ?
+ MLX4_EN_MIN_TX_RING_P_UP :
+ min_t(int, num_online_cpus(), MLX4_EN_MAX_TX_RING_P_UP);
+
if (params->udp_rss && !(mdev->dev->caps.flags
& MLX4_DEV_CAP_FLAG_UDP_RSS)) {
mlx4_warn(mdev, "UDP RSS is not supported on this device\n");
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 7d4fb7bf2593..bb536aa613f4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -644,6 +644,7 @@ static int mlx4_en_get_qp(struct mlx4_en_priv *priv)
goto alloc_err;
}
memcpy(entry->mac, priv->dev->dev_addr, sizeof(entry->mac));
+ memcpy(priv->current_mac, entry->mac, sizeof(priv->current_mac));
entry->reg_id = reg_id;
hlist_add_head_rcu(&entry->hlist,
@@ -760,21 +761,22 @@ static int mlx4_en_replace_mac(struct mlx4_en_priv *priv, int qpn,
return __mlx4_replace_mac(dev, priv->port, qpn, new_mac_u64);
}
-static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)
+static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv,
+ unsigned char new_mac[ETH_ALEN + 2])
{
int err = 0;
if (priv->port_up) {
/* Remove old MAC and insert the new one */
err = mlx4_en_replace_mac(priv, priv->base_qpn,
- priv->dev->dev_addr, priv->prev_mac);
+ new_mac, priv->current_mac);
if (err)
en_err(priv, "Failed changing HW MAC address\n");
} else
en_dbg(HW, priv, "Port is down while registering mac, exiting...\n");
- memcpy(priv->prev_mac, priv->dev->dev_addr,
- sizeof(priv->prev_mac));
+ if (!err)
+ memcpy(priv->current_mac, new_mac, sizeof(priv->current_mac));
return err;
}
@@ -784,14 +786,17 @@ static int mlx4_en_set_mac(struct net_device *dev, void *addr)
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_en_dev *mdev = priv->mdev;
struct sockaddr *saddr = addr;
+ unsigned char new_mac[ETH_ALEN + 2];
int err;
if (!is_valid_ether_addr(saddr->sa_data))
return -EADDRNOTAVAIL;
mutex_lock(&mdev->state_lock);
- memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
- err = mlx4_en_do_set_mac(priv);
+ memcpy(new_mac, saddr->sa_data, ETH_ALEN);
+ err = mlx4_en_do_set_mac(priv, new_mac);
+ if (!err)
+ memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
mutex_unlock(&mdev->state_lock);
return err;
@@ -940,11 +945,6 @@ static void mlx4_en_set_promisc_mode(struct mlx4_en_priv *priv,
0, MLX4_MCAST_DISABLE);
if (err)
en_err(priv, "Failed disabling multicast filter\n");
-
- /* Disable port VLAN filter */
- err = mlx4_SET_VLAN_FLTR(mdev->dev, priv);
- if (err)
- en_err(priv, "Failed disabling VLAN filter\n");
}
}
@@ -993,11 +993,6 @@ static void mlx4_en_clear_promisc_mode(struct mlx4_en_priv *priv,
en_err(priv, "Failed disabling promiscuous mode\n");
break;
}
-
- /* Enable port VLAN filter */
- err = mlx4_SET_VLAN_FLTR(mdev->dev, priv);
- if (err)
- en_err(priv, "Failed enabling VLAN filter\n");
}
static void mlx4_en_do_multicast(struct mlx4_en_priv *priv,
@@ -1166,7 +1161,8 @@ static void mlx4_en_do_uc_filter(struct mlx4_en_priv *priv,
}
/* MAC address of the port is not in uc list */
- if (ether_addr_equal_64bits(entry->mac, dev->dev_addr))
+ if (ether_addr_equal_64bits(entry->mac,
+ priv->current_mac))
found = true;
if (!found) {
@@ -1476,7 +1472,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
}
if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
- mlx4_en_do_set_mac(priv);
+ mlx4_en_do_set_mac(priv, priv->current_mac);
mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
}
mutex_unlock(&mdev->state_lock);
@@ -2336,7 +2332,7 @@ static void mlx4_en_add_vxlan_port(struct net_device *dev,
struct mlx4_en_priv *priv = netdev_priv(dev);
__be16 current_port;
- if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS))
+ if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
return;
if (sa_family == AF_INET6)
@@ -2469,10 +2465,12 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->port = port;
priv->port_up = false;
priv->flags = prof->flags;
+ priv->pflags = MLX4_EN_PRIV_FLAGS_BLUEFLAME;
priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
MLX4_WQE_CTRL_SOLICITED);
priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up;
priv->tx_ring_num = prof->tx_ring_num;
+ priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK;
priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS,
GFP_KERNEL);
@@ -2534,7 +2532,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
}
}
- memcpy(priv->prev_mac, dev->dev_addr, sizeof(priv->prev_mac));
+ memcpy(priv->current_mac, dev->dev_addr, sizeof(priv->current_mac));
priv->stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
DS_SIZE * MLX4_EN_MAX_RX_FRAGS);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index d2d415732d99..9c909d23f14c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -40,6 +40,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/vmalloc.h>
+#include <linux/irq.h>
#include "mlx4_en.h"
@@ -334,8 +335,9 @@ void mlx4_en_set_num_rx_rings(struct mlx4_en_dev *mdev)
dev->caps.comp_pool/
dev->caps.num_ports) - 1;
- num_rx_rings = min_t(int, num_of_eqs,
- netif_get_num_default_rss_queues());
+ num_rx_rings = mlx4_low_memory_profile() ? MIN_RX_RINGS :
+ min_t(int, num_of_eqs,
+ netif_get_num_default_rss_queues());
mdev->profile.prof[i].rx_ring_num =
rounddown_pow_of_two(num_rx_rings);
}
@@ -782,6 +784,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
PKT_HASH_TYPE_L3);
skb_record_rx_queue(gro_skb, cq->ring);
+ skb_mark_napi_id(gro_skb, &cq->napi);
if (ring->hwtstamp_rx_filter == HWTSTAMP_FILTER_ALL) {
timestamp = mlx4_en_get_cqe_ts(cqe);
@@ -896,16 +899,25 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
/* If we used up all the quota - we're probably not done yet... */
if (done == budget) {
+ int cpu_curr;
+ const struct cpumask *aff;
+
INC_PERF_COUNTER(priv->pstats.napi_quota);
- if (unlikely(cq->mcq.irq_affinity_change)) {
- cq->mcq.irq_affinity_change = false;
+
+ cpu_curr = smp_processor_id();
+ aff = irq_desc_get_irq_data(cq->irq_desc)->affinity;
+
+ if (unlikely(!cpumask_test_cpu(cpu_curr, aff))) {
+ /* Current cpu is not according to smp_irq_affinity -
+ * probably affinity changed. need to stop this NAPI
+ * poll, and restart it on the right CPU
+ */
napi_complete(napi);
mlx4_en_arm_cq(priv, cq);
return 0;
}
} else {
/* Done for now */
- cq->mcq.irq_affinity_change = false;
napi_complete(napi);
mlx4_en_arm_cq(priv, cq);
}
@@ -922,7 +934,7 @@ static const int frag_sizes[] = {
void mlx4_en_calc_rx_buf(struct net_device *dev)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- int eff_mtu = dev->mtu + ETH_HLEN + VLAN_HLEN + ETH_LLC_SNAP_SIZE;
+ int eff_mtu = dev->mtu + ETH_HLEN + VLAN_HLEN;
int buf_size = 0;
int i = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
index 03e5f6ac67e7..49d5afc7cfb8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
@@ -159,7 +159,8 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
if (priv->mdev->dev->caps.flags &
MLX4_DEV_CAP_FLAG_UC_LOOPBACK) {
buf[3] = mlx4_en_test_registers(priv);
- buf[4] = mlx4_en_test_loopback(priv);
+ if (priv->port_up)
+ buf[4] = mlx4_en_test_loopback(priv);
}
if (carrier_ok)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 8be7483f8236..dae3da6d8dd0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -126,8 +126,13 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
ring->bf.uar = &mdev->priv_uar;
ring->bf.uar->map = mdev->uar_map;
ring->bf_enabled = false;
- } else
- ring->bf_enabled = true;
+ ring->bf_alloced = false;
+ priv->pflags &= ~MLX4_EN_PRIV_FLAGS_BLUEFLAME;
+ } else {
+ ring->bf_alloced = true;
+ ring->bf_enabled = !!(priv->pflags &
+ MLX4_EN_PRIV_FLAGS_BLUEFLAME);
+ }
ring->hwtstamp_tx_type = priv->hwtstamp_config.tx_type;
ring->queue_index = queue_index;
@@ -161,7 +166,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring *ring = *pring;
en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
- if (ring->bf_enabled)
+ if (ring->bf_alloced)
mlx4_bf_free(mdev->dev, &ring->bf);
mlx4_qp_remove(mdev->dev, &ring->qp);
mlx4_qp_free(mdev->dev, &ring->qp);
@@ -195,7 +200,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
ring->cqn, user_prio, &ring->context);
- if (ring->bf_enabled)
+ if (ring->bf_alloced)
ring->context.usr_page = cpu_to_be32(ring->bf.uar->index);
err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, &ring->context,
@@ -351,9 +356,8 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
return cnt;
}
-static int mlx4_en_process_tx_cq(struct net_device *dev,
- struct mlx4_en_cq *cq,
- int budget)
+static bool mlx4_en_process_tx_cq(struct net_device *dev,
+ struct mlx4_en_cq *cq)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
struct mlx4_cq *mcq = &cq->mcq;
@@ -372,9 +376,10 @@ static int mlx4_en_process_tx_cq(struct net_device *dev,
int factor = priv->cqe_factor;
u64 timestamp = 0;
int done = 0;
+ int budget = priv->tx_work_limit;
if (!priv->port_up)
- return 0;
+ return true;
index = cons_index & size_mask;
cqe = &buf[(index << factor) + factor];
@@ -447,7 +452,7 @@ static int mlx4_en_process_tx_cq(struct net_device *dev,
netif_tx_wake_queue(ring->tx_queue);
ring->wake_queue++;
}
- return done;
+ return done < budget;
}
void mlx4_en_tx_irq(struct mlx4_cq *mcq)
@@ -467,24 +472,16 @@ int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget)
struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
struct net_device *dev = cq->dev;
struct mlx4_en_priv *priv = netdev_priv(dev);
- int done;
+ int clean_complete;
- done = mlx4_en_process_tx_cq(dev, cq, budget);
+ clean_complete = mlx4_en_process_tx_cq(dev, cq);
+ if (!clean_complete)
+ return budget;
- /* If we used up all the quota - we're probably not done yet... */
- if (done < budget) {
- /* Done for now */
- cq->mcq.irq_affinity_change = false;
- napi_complete(napi);
- mlx4_en_arm_cq(priv, cq);
- return done;
- } else if (unlikely(cq->mcq.irq_affinity_change)) {
- cq->mcq.irq_affinity_change = false;
- napi_complete(napi);
- mlx4_en_arm_cq(priv, cq);
- return 0;
- }
- return budget;
+ napi_complete(napi);
+ mlx4_en_arm_cq(priv, cq);
+
+ return 0;
}
static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index d954ec1eac17..2a004b347e1d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -53,11 +53,6 @@ enum {
MLX4_EQ_ENTRY_SIZE = 0x20
};
-struct mlx4_irq_notify {
- void *arg;
- struct irq_affinity_notify notify;
-};
-
#define MLX4_EQ_STATUS_OK ( 0 << 28)
#define MLX4_EQ_STATUS_WRITE_FAIL (10 << 28)
#define MLX4_EQ_OWNER_SW ( 0 << 24)
@@ -1088,57 +1083,6 @@ static void mlx4_unmap_clr_int(struct mlx4_dev *dev)
iounmap(priv->clr_base);
}
-static void mlx4_irq_notifier_notify(struct irq_affinity_notify *notify,
- const cpumask_t *mask)
-{
- struct mlx4_irq_notify *n = container_of(notify,
- struct mlx4_irq_notify,
- notify);
- struct mlx4_priv *priv = (struct mlx4_priv *)n->arg;
- struct radix_tree_iter iter;
- void **slot;
-
- radix_tree_for_each_slot(slot, &priv->cq_table.tree, &iter, 0) {
- struct mlx4_cq *cq = (struct mlx4_cq *)(*slot);
-
- if (cq->irq == notify->irq)
- cq->irq_affinity_change = true;
- }
-}
-
-static void mlx4_release_irq_notifier(struct kref *ref)
-{
- struct mlx4_irq_notify *n = container_of(ref, struct mlx4_irq_notify,
- notify.kref);
- kfree(n);
-}
-
-static void mlx4_assign_irq_notifier(struct mlx4_priv *priv,
- struct mlx4_dev *dev, int irq)
-{
- struct mlx4_irq_notify *irq_notifier = NULL;
- int err = 0;
-
- irq_notifier = kzalloc(sizeof(*irq_notifier), GFP_KERNEL);
- if (!irq_notifier) {
- mlx4_warn(dev, "Failed to allocate irq notifier. irq %d\n",
- irq);
- return;
- }
-
- irq_notifier->notify.irq = irq;
- irq_notifier->notify.notify = mlx4_irq_notifier_notify;
- irq_notifier->notify.release = mlx4_release_irq_notifier;
- irq_notifier->arg = priv;
- err = irq_set_affinity_notifier(irq, &irq_notifier->notify);
- if (err) {
- kfree(irq_notifier);
- irq_notifier = NULL;
- mlx4_warn(dev, "Failed to set irq notifier. irq %d\n", irq);
- }
-}
-
-
int mlx4_alloc_eq_table(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1409,8 +1353,6 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap,
continue;
/*we dont want to break here*/
}
- mlx4_assign_irq_notifier(priv, dev,
- priv->eq_table.eq[vec].irq);
eq_set_ci(&priv->eq_table.eq[vec], 1);
}
@@ -1427,6 +1369,14 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap,
}
EXPORT_SYMBOL(mlx4_assign_eq);
+int mlx4_eq_get_irq(struct mlx4_dev *dev, int vec)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+
+ return priv->eq_table.eq[vec].irq;
+}
+EXPORT_SYMBOL(mlx4_eq_get_irq);
+
void mlx4_release_eq(struct mlx4_dev *dev, int vec)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1438,9 +1388,6 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
Belonging to a legacy EQ*/
mutex_lock(&priv->msix_ctl.pool_lock);
if (priv->msix_ctl.pool_bm & 1ULL << i) {
- irq_set_affinity_notifier(
- priv->eq_table.eq[vec].irq,
- NULL);
free_irq(priv->eq_table.eq[vec].irq,
&priv->eq_table.eq[vec]);
priv->msix_ctl.pool_bm &= ~(1ULL << i);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 82ab427290c3..80b8c5f30e4e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -120,6 +120,16 @@ static struct mlx4_profile default_profile = {
.num_mtt = 1 << 20, /* It is really num mtt segements */
};
+static struct mlx4_profile low_mem_profile = {
+ .num_qp = 1 << 17,
+ .num_srq = 1 << 6,
+ .rdmarc_per_qp = 1 << 4,
+ .num_cq = 1 << 8,
+ .num_mcg = 1 << 8,
+ .num_mpt = 1 << 9,
+ .num_mtt = 1 << 7,
+};
+
static int log_num_mac = 7;
module_param_named(log_num_mac, log_num_mac, int, 0444);
MODULE_PARM_DESC(log_num_mac, "Log2 max number of MACs per ETH port (1-7)");
@@ -129,6 +139,8 @@ module_param_named(log_num_vlan, log_num_vlan, int, 0444);
MODULE_PARM_DESC(log_num_vlan, "Log2 max number of VLANs per ETH port (0-7)");
/* Log2 max number of VLANs per ETH port (0-7) */
#define MLX4_LOG_NUM_VLANS 7
+#define MLX4_MIN_LOG_NUM_VLANS 0
+#define MLX4_MIN_LOG_NUM_MAC 1
static bool use_prio;
module_param_named(use_prio, use_prio, bool, 0444);
@@ -287,8 +299,13 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
if (mlx4_is_mfunc(dev))
dev->caps.flags &= ~MLX4_DEV_CAP_FLAG_SENSE_SUPPORT;
- dev->caps.log_num_macs = log_num_mac;
- dev->caps.log_num_vlans = MLX4_LOG_NUM_VLANS;
+ if (mlx4_low_memory_profile()) {
+ dev->caps.log_num_macs = MLX4_MIN_LOG_NUM_MAC;
+ dev->caps.log_num_vlans = MLX4_MIN_LOG_NUM_VLANS;
+ } else {
+ dev->caps.log_num_macs = log_num_mac;
+ dev->caps.log_num_vlans = MLX4_LOG_NUM_VLANS;
+ }
for (i = 1; i <= dev->caps.num_ports; ++i) {
dev->caps.port_type[i] = MLX4_PORT_TYPE_NONE;
@@ -1587,7 +1604,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
if (mlx4_is_master(dev))
mlx4_parav_master_pf_caps(dev);
- profile = default_profile;
+ if (mlx4_low_memory_profile()) {
+ mlx4_info(dev, "Running from within kdump kernel. Using low memory profile\n");
+ profile = low_mem_profile;
+ } else {
+ profile = default_profile;
+ }
if (dev->caps.steering_mode ==
MLX4_STEERING_MODE_DEVICE_MANAGED)
profile.num_mcg = MLX4_FS_NUM_MCG;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 4c36def8e10f..d80e7a6fac74 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -270,7 +270,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
* we need to add it as a duplicate to this entry
* for future references */
list_for_each_entry(dqp, &entry->duplicates, list) {
- if (qpn == pqp->qpn)
+ if (qpn == dqp->qpn)
return 0; /* qp is already duplicated */
}
@@ -324,24 +324,22 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
return true;
}
-/* I a steering entry contains only promisc QPs, it can be removed. */
-static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
- enum mlx4_steer_type steer,
- unsigned int index, u32 tqpn)
+/* Returns true if all the QPs != tqpn contained in this entry
+ * are Promisc QPs. Returns false otherwise.
+ */
+static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port,
+ enum mlx4_steer_type steer,
+ unsigned int index, u32 tqpn,
+ u32 *members_count)
{
- struct mlx4_steer *s_steer;
struct mlx4_cmd_mailbox *mailbox;
struct mlx4_mgm *mgm;
- struct mlx4_steer_index *entry = NULL, *tmp_entry;
- u32 qpn;
- u32 members_count;
+ u32 m_count;
bool ret = false;
int i;
if (port < 1 || port > dev->caps.num_ports)
- return NULL;
-
- s_steer = &mlx4_priv(dev)->steer[port - 1];
+ return false;
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
@@ -350,21 +348,61 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
if (mlx4_READ_ENTRY(dev, index, mailbox))
goto out;
- members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- for (i = 0; i < members_count; i++) {
- qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
+ m_count = be32_to_cpu(mgm->members_count) & 0xffffff;
+ if (members_count)
+ *members_count = m_count;
+
+ for (i = 0; i < m_count; i++) {
+ u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
/* the qp is not promisc, the entry can't be removed */
goto out;
}
}
- /* All the qps currently registered for this entry are promiscuous,
+ ret = true;
+out:
+ mlx4_free_cmd_mailbox(dev, mailbox);
+ return ret;
+}
+
+/* IF a steering entry contains only promisc QPs, it can be removed. */
+static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
+ enum mlx4_steer_type steer,
+ unsigned int index, u32 tqpn)
+{
+ struct mlx4_steer *s_steer;
+ struct mlx4_steer_index *entry = NULL, *tmp_entry;
+ u32 members_count;
+ bool ret = false;
+
+ if (port < 1 || port > dev->caps.num_ports)
+ return NULL;
+
+ s_steer = &mlx4_priv(dev)->steer[port - 1];
+
+ if (!promisc_steering_entry(dev, port, steer, index,
+ tqpn, &members_count))
+ goto out;
+
+ /* All the qps currently registered for this entry are promiscuous,
* Checking for duplicates */
ret = true;
list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) {
if (entry->index == index) {
- if (list_empty(&entry->duplicates)) {
+ if (list_empty(&entry->duplicates) ||
+ members_count == 1) {
+ struct mlx4_promisc_qp *pqp, *tmp_pqp;
+ /* If there is only 1 entry in duplicates then
+ * this is the QP we want to delete, going over
+ * the list and deleting the entry.
+ */
list_del(&entry->list);
+ list_for_each_entry_safe(pqp, tmp_pqp,
+ &entry->duplicates,
+ list) {
+ list_del(&pqp->list);
+ kfree(pqp);
+ }
kfree(entry);
} else {
/* This entry contains duplicates so it shouldn't be removed */
@@ -375,7 +413,6 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
}
out:
- mlx4_free_cmd_mailbox(dev, mailbox);
return ret;
}
@@ -421,42 +458,57 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
}
mgm = mailbox->buf;
- /* the promisc qp needs to be added for each one of the steering
- * entries, if it already exists, needs to be added as a duplicate
- * for this entry */
- list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
- err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
- if (err)
- goto out_mailbox;
+ if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
+ /* The promisc QP needs to be added for each one of the steering
+ * entries. If it already exists, needs to be added as
+ * a duplicate for this entry.
+ */
+ list_for_each_entry(entry,
+ &s_steer->steer_entries[steer],
+ list) {
+ err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
+ if (err)
+ goto out_mailbox;
- members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- prot = be32_to_cpu(mgm->members_count) >> 30;
- found = false;
- for (i = 0; i < members_count; i++) {
- if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
- /* Entry already exists, add to duplicates */
- dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
- if (!dqp) {
+ members_count = be32_to_cpu(mgm->members_count) &
+ 0xffffff;
+ prot = be32_to_cpu(mgm->members_count) >> 30;
+ found = false;
+ for (i = 0; i < members_count; i++) {
+ if ((be32_to_cpu(mgm->qp[i]) &
+ MGM_QPN_MASK) == qpn) {
+ /* Entry already exists.
+ * Add to duplicates.
+ */
+ dqp = kmalloc(sizeof(*dqp), GFP_KERNEL);
+ if (!dqp) {
+ err = -ENOMEM;
+ goto out_mailbox;
+ }
+ dqp->qpn = qpn;
+ list_add_tail(&dqp->list,
+ &entry->duplicates);
+ found = true;
+ }
+ }
+ if (!found) {
+ /* Need to add the qpn to mgm */
+ if (members_count ==
+ dev->caps.num_qp_per_mgm) {
+ /* entry is full */
err = -ENOMEM;
goto out_mailbox;
}
- dqp->qpn = qpn;
- list_add_tail(&dqp->list, &entry->duplicates);
- found = true;
- }
- }
- if (!found) {
- /* Need to add the qpn to mgm */
- if (members_count == dev->caps.num_qp_per_mgm) {
- /* entry is full */
- err = -ENOMEM;
- goto out_mailbox;
+ mgm->qp[members_count++] =
+ cpu_to_be32(qpn & MGM_QPN_MASK);
+ mgm->members_count =
+ cpu_to_be32(members_count |
+ (prot << 30));
+ err = mlx4_WRITE_ENTRY(dev, entry->index,
+ mailbox);
+ if (err)
+ goto out_mailbox;
}
- mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK);
- mgm->members_count = cpu_to_be32(members_count | (prot << 30));
- err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
- if (err)
- goto out_mailbox;
}
}
@@ -465,8 +517,14 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
/* now need to add all the promisc qps to default entry */
memset(mgm, 0, sizeof *mgm);
members_count = 0;
- list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list)
+ list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) {
+ if (members_count == dev->caps.num_qp_per_mgm) {
+ /* entry is full */
+ err = -ENOMEM;
+ goto out_list;
+ }
mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK);
+ }
mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30);
err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox);
@@ -495,13 +553,13 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
struct mlx4_steer *s_steer;
struct mlx4_cmd_mailbox *mailbox;
struct mlx4_mgm *mgm;
- struct mlx4_steer_index *entry;
+ struct mlx4_steer_index *entry, *tmp_entry;
struct mlx4_promisc_qp *pqp;
struct mlx4_promisc_qp *dqp;
u32 members_count;
bool found;
bool back_to_list = false;
- int loc, i;
+ int i;
int err;
if (port < 1 || port > dev->caps.num_ports)
@@ -538,39 +596,73 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
if (err)
goto out_mailbox;
- /* remove the qp from all the steering entries*/
- list_for_each_entry(entry, &s_steer->steer_entries[steer], list) {
- found = false;
- list_for_each_entry(dqp, &entry->duplicates, list) {
- if (dqp->qpn == qpn) {
- found = true;
- break;
+ if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) {
+ /* Remove the QP from all the steering entries */
+ list_for_each_entry_safe(entry, tmp_entry,
+ &s_steer->steer_entries[steer],
+ list) {
+ found = false;
+ list_for_each_entry(dqp, &entry->duplicates, list) {
+ if (dqp->qpn == qpn) {
+ found = true;
+ break;
+ }
}
- }
- if (found) {
- /* a duplicate, no need to change the mgm,
- * only update the duplicates list */
- list_del(&dqp->list);
- kfree(dqp);
- } else {
- err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
- if (err)
- goto out_mailbox;
- members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- for (loc = -1, i = 0; i < members_count; ++i)
- if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn)
- loc = i;
-
- mgm->members_count = cpu_to_be32(--members_count |
- (MLX4_PROT_ETH << 30));
- mgm->qp[loc] = mgm->qp[i - 1];
- mgm->qp[i - 1] = 0;
+ if (found) {
+ /* A duplicate, no need to change the MGM,
+ * only update the duplicates list
+ */
+ list_del(&dqp->list);
+ kfree(dqp);
+ } else {
+ int loc = -1;
+
+ err = mlx4_READ_ENTRY(dev,
+ entry->index,
+ mailbox);
+ if (err)
+ goto out_mailbox;
+ members_count =
+ be32_to_cpu(mgm->members_count) &
+ 0xffffff;
+ if (!members_count) {
+ mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n",
+ qpn, entry->index);
+ list_del(&entry->list);
+ kfree(entry);
+ continue;
+ }
- err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
- if (err)
+ for (i = 0; i < members_count; ++i)
+ if ((be32_to_cpu(mgm->qp[i]) &
+ MGM_QPN_MASK) == qpn) {
+ loc = i;
+ break;
+ }
+
+ if (loc < 0) {
+ mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
+ qpn, entry->index);
+ err = -EINVAL;
goto out_mailbox;
- }
+ }
+ /* Copy the last QP in this MGM
+ * over removed QP
+ */
+ mgm->qp[loc] = mgm->qp[members_count - 1];
+ mgm->qp[members_count - 1] = 0;
+ mgm->members_count =
+ cpu_to_be32(--members_count |
+ (MLX4_PROT_ETH << 30));
+
+ err = mlx4_WRITE_ENTRY(dev,
+ entry->index,
+ mailbox);
+ if (err)
+ goto out_mailbox;
+ }
+ }
}
out_mailbox:
@@ -1062,7 +1154,7 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
struct mlx4_mgm *mgm;
u32 members_count;
int prev, index;
- int i, loc;
+ int i, loc = -1;
int err;
u8 port = gid[5];
bool removed_entry = false;
@@ -1085,15 +1177,20 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
goto out;
}
- /* if this pq is also a promisc qp, it shouldn't be removed */
+ /* If this QP is also a promisc QP, it shouldn't be removed only if
+ * at least one none promisc QP is also attached to this MCG
+ */
if (prot == MLX4_PROT_ETH &&
- check_duplicate_entry(dev, port, steer, index, qp->qpn))
- goto out;
+ check_duplicate_entry(dev, port, steer, index, qp->qpn) &&
+ !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL))
+ goto out;
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- for (loc = -1, i = 0; i < members_count; ++i)
- if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
+ for (i = 0; i < members_count; ++i)
+ if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
loc = i;
+ break;
+ }
if (loc == -1) {
mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
@@ -1101,15 +1198,15 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
goto out;
}
-
+ /* copy the last QP in this MGM over removed QP */
+ mgm->qp[loc] = mgm->qp[members_count - 1];
+ mgm->qp[members_count - 1] = 0;
mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
- mgm->qp[loc] = mgm->qp[i - 1];
- mgm->qp[i - 1] = 0;
if (prot == MLX4_PROT_ETH)
removed_entry = can_remove_steering_entry(dev, port, steer,
index, qp->qpn);
- if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
+ if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
goto out;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 1d8af7336807..13fbcd03c3e4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -62,11 +62,6 @@
#define INIT_HCA_TPT_MW_ENABLE (1 << 7)
-#define MLX4_NUM_UP 8
-#define MLX4_NUM_TC 8
-#define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */
-#define MLX4_RATELIMIT_DEFAULT 0xffff
-
struct mlx4_set_port_prio2tc_context {
u8 prio2tc[4];
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 0e15295bedd6..3de41be49425 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -93,6 +93,8 @@
* OS related constants and tunables
*/
+#define MLX4_EN_PRIV_FLAGS_BLUEFLAME 1
+
#define MLX4_EN_WATCHDOG_TIMEOUT (15 * HZ)
/* Use the maximum between 16384 and a single page */
@@ -119,6 +121,7 @@ enum {
#define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE)
#define MLX4_EN_SMALL_PKT_SIZE 64
+#define MLX4_EN_MIN_TX_RING_P_UP 1
#define MLX4_EN_MAX_TX_RING_P_UP 32
#define MLX4_EN_NUM_UP 8
#define MLX4_EN_DEF_TX_RING_SIZE 512
@@ -126,6 +129,8 @@ enum {
#define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \
MLX4_EN_NUM_UP)
+#define MLX4_EN_DEFAULT_TX_WORK 256
+
/* Target number of packets to coalesce with interrupt moderation */
#define MLX4_EN_RX_COAL_TARGET 44
#define MLX4_EN_RX_COAL_TIME 0x10
@@ -152,8 +157,6 @@ enum {
#define MLX4_EN_TX_POLL_MODER 16
#define MLX4_EN_TX_POLL_TIMEOUT (HZ / 4)
-#define ETH_LLC_SNAP_SIZE 8
-
#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN)
#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN)
#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN)
@@ -278,6 +281,7 @@ struct mlx4_en_tx_ring {
unsigned long wake_queue;
struct mlx4_bf bf;
bool bf_enabled;
+ bool bf_alloced;
struct netdev_queue *tx_queue;
int hwtstamp_tx_type;
int inline_thold;
@@ -343,6 +347,7 @@ struct mlx4_en_cq {
#define CQ_USER_PEND (MLX4_EN_CQ_STATE_POLL | MLX4_EN_CQ_STATE_POLL_YIELD)
spinlock_t poll_lock; /* protects from LLS/napi conflicts */
#endif /* CONFIG_NET_RX_BUSY_POLL */
+ struct irq_desc *irq_desc;
};
struct mlx4_en_port_profile {
@@ -532,7 +537,7 @@ struct mlx4_en_priv {
int registered;
int allocated;
int stride;
- unsigned char prev_mac[ETH_ALEN + 2];
+ unsigned char current_mac[ETH_ALEN + 2];
int mac_index;
unsigned max_mtu;
int base_qpn;
@@ -542,6 +547,7 @@ struct mlx4_en_priv {
__be32 ctrl_flags;
u32 flags;
u8 num_tx_rings_p_up;
+ u32 tx_work_limit;
u32 tx_ring_num;
u32 rx_ring_num;
u32 rx_skb_size;
@@ -590,6 +596,8 @@ struct mlx4_en_priv {
#endif
u64 tunnel_reg_id;
__be16 vxlan_port;
+
+ u32 pflags;
};
enum mlx4_en_wol {
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 7ab97174886d..9ba0c1ca10d5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -244,10 +244,16 @@ EXPORT_SYMBOL_GPL(mlx4_get_base_qpn);
void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{
- struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
- struct mlx4_mac_table *table = &info->mac_table;
+ struct mlx4_port_info *info;
+ struct mlx4_mac_table *table;
int index;
+ if (port < 1 || port > dev->caps.num_ports) {
+ mlx4_warn(dev, "invalid port number (%d), aborting...\n", port);
+ return;
+ }
+ info = &mlx4_priv(dev)->port[port];
+ table = &info->mac_table;
mutex_lock(&table->mutex);
index = find_index(dev, table, mac);
@@ -1051,14 +1057,26 @@ int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
for (i = 0; i < MLX4_NUM_TC; i++) {
struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i];
- u16 r = ratelimit && ratelimit[i] ? ratelimit[i] :
- MLX4_RATELIMIT_DEFAULT;
+ u16 r;
+
+ if (ratelimit && ratelimit[i]) {
+ if (ratelimit[i] <= MLX4_MAX_100M_UNITS_VAL) {
+ r = ratelimit[i];
+ tc->max_bw_units =
+ htons(MLX4_RATELIMIT_100M_UNITS);
+ } else {
+ r = ratelimit[i]/10;
+ tc->max_bw_units =
+ htons(MLX4_RATELIMIT_1G_UNITS);
+ }
+ tc->max_bw_value = htons(r);
+ } else {
+ tc->max_bw_value = htons(MLX4_RATELIMIT_DEFAULT);
+ tc->max_bw_units = htons(MLX4_RATELIMIT_1G_UNITS);
+ }
tc->pg = htons(pg[i]);
tc->bw_precentage = htons(tc_tx_bw[i]);
-
- tc->max_bw_units = htons(MLX4_RATELIMIT_UNITS);
- tc->max_bw_value = htons(r);
}
in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
index b215742b842f..56779c1c7811 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
@@ -56,7 +56,7 @@ int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, int max_direct,
if (size <= max_direct) {
buf->nbufs = 1;
buf->npages = 1;
- buf->page_shift = get_order(size) + PAGE_SHIFT;
+ buf->page_shift = (u8)get_order(size) + PAGE_SHIFT;
buf->direct.buf = dma_zalloc_coherent(&dev->pdev->dev,
size, &t, GFP_KERNEL);
if (!buf->direct.buf)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 87d1b018a9c3..65a7da69e2ac 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -464,7 +464,7 @@ static void dump_command(struct mlx5_core_dev *dev,
struct mlx5_cmd_msg *msg = input ? ent->in : ent->out;
struct mlx5_cmd_mailbox *next = msg->next;
int data_only;
- int offset = 0;
+ u32 offset = 0;
int dump_len;
data_only = !!(mlx5_core_debug_mask & (1 << MLX5_CMD_DATA));
@@ -548,7 +548,7 @@ static void cmd_work_handler(struct work_struct *work)
lay->status_own = CMD_OWNER_HW;
set_signature(ent, !cmd->checksum_disabled);
dump_command(dev, ent, 1);
- ktime_get_ts(&ent->ts1);
+ ent->ts1 = ktime_get_ns();
/* ring doorbell after the descriptor is valid */
wmb();
@@ -637,7 +637,6 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
{
struct mlx5_cmd *cmd = &dev->cmd;
struct mlx5_cmd_work_ent *ent;
- ktime_t t1, t2, delta;
struct mlx5_cmd_stats *stats;
int err = 0;
s64 ds;
@@ -668,10 +667,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
if (err == -ETIMEDOUT)
goto out;
- t1 = timespec_to_ktime(ent->ts1);
- t2 = timespec_to_ktime(ent->ts2);
- delta = ktime_sub(t2, t1);
- ds = ktime_to_ns(delta);
+ ds = ent->ts2 - ent->ts1;
op = be16_to_cpu(((struct mlx5_inbox_hdr *)in->first.data)->opcode);
if (op < ARRAY_SIZE(cmd->stats)) {
stats = &cmd->stats[op];
@@ -1135,7 +1131,6 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
void *context;
int err;
int i;
- ktime_t t1, t2, delta;
s64 ds;
struct mlx5_cmd_stats *stats;
unsigned long flags;
@@ -1149,7 +1144,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
sem = &cmd->pages_sem;
else
sem = &cmd->sem;
- ktime_get_ts(&ent->ts2);
+ ent->ts2 = ktime_get_ns();
memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out));
dump_command(dev, ent, 0);
if (!ent->ret) {
@@ -1163,10 +1158,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
}
free_ent(cmd, ent->idx);
if (ent->callback) {
- t1 = timespec_to_ktime(ent->ts1);
- t2 = timespec_to_ktime(ent->ts2);
- delta = ktime_sub(t2, t1);
- ds = ktime_to_ns(delta);
+ ds = ent->ts2 - ent->ts1;
if (ent->op < ARRAY_SIZE(cmd->stats)) {
stats = &cmd->stats[ent->op];
spin_lock_irqsave(&stats->lock, flags);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 7f39ebcd6ad0..4e8bd0b34bb0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -252,7 +252,9 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
case MLX5_PORT_CHANGE_SUBTYPE_GUID:
case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
- dev->event(dev, port_subtype_event(eqe->sub_type), &port);
+ if (dev->event)
+ dev->event(dev, port_subtype_event(eqe->sub_type),
+ (unsigned long)port);
break;
default:
mlx5_core_warn(dev, "Port event with unrecognized subtype: port %d, sub_type %d\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mad.c b/drivers/net/ethernet/mellanox/mlx5/core/mad.c
index 18d6fd5dd90b..fd80ecfa7195 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mad.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mad.c
@@ -37,7 +37,7 @@
#include "mlx5_core.h"
int mlx5_core_mad_ifc(struct mlx5_core_dev *dev, void *inb, void *outb,
- u16 opmod, int port)
+ u16 opmod, u8 port)
{
struct mlx5_mad_ifc_mbox_in *in = NULL;
struct mlx5_mad_ifc_mbox_out *out = NULL;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index ee24f132e319..f2716cc1f51d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -58,7 +58,100 @@ int mlx5_core_debug_mask;
module_param_named(debug_mask, mlx5_core_debug_mask, int, 0644);
MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec time, 3 = both. Default=0");
+#define MLX5_DEFAULT_PROF 2
+static int prof_sel = MLX5_DEFAULT_PROF;
+module_param_named(prof_sel, prof_sel, int, 0444);
+MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
+
struct workqueue_struct *mlx5_core_wq;
+static LIST_HEAD(intf_list);
+static LIST_HEAD(dev_list);
+static DEFINE_MUTEX(intf_mutex);
+
+struct mlx5_device_context {
+ struct list_head list;
+ struct mlx5_interface *intf;
+ void *context;
+};
+
+static struct mlx5_profile profile[] = {
+ [0] = {
+ .mask = 0,
+ },
+ [1] = {
+ .mask = MLX5_PROF_MASK_QP_SIZE,
+ .log_max_qp = 12,
+ },
+ [2] = {
+ .mask = MLX5_PROF_MASK_QP_SIZE |
+ MLX5_PROF_MASK_MR_CACHE,
+ .log_max_qp = 17,
+ .mr_cache[0] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[1] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[2] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[3] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[4] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[5] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[6] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[7] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[8] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[9] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[10] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[11] = {
+ .size = 500,
+ .limit = 250
+ },
+ .mr_cache[12] = {
+ .size = 64,
+ .limit = 32
+ },
+ .mr_cache[13] = {
+ .size = 32,
+ .limit = 16
+ },
+ .mr_cache[14] = {
+ .size = 16,
+ .limit = 8
+ },
+ .mr_cache[15] = {
+ .size = 8,
+ .limit = 4
+ },
+ },
+};
static int set_dma_caps(struct pci_dev *pdev)
{
@@ -218,7 +311,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
copy_rw_fields(&set_ctx->hca_cap, &query_out->hca_cap);
- if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE)
+ if (dev->profile && dev->profile->mask & MLX5_PROF_MASK_QP_SIZE)
set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp;
flags = be64_to_cpu(query_out->hca_cap.flags);
@@ -299,7 +392,7 @@ static int mlx5_core_disable_hca(struct mlx5_core_dev *dev)
return 0;
}
-int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
+static int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
{
struct mlx5_priv *priv = &dev->priv;
int err;
@@ -489,7 +582,7 @@ err_dbg:
}
EXPORT_SYMBOL(mlx5_dev_init);
-void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
+static void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
{
struct mlx5_priv *priv = &dev->priv;
@@ -516,7 +609,190 @@ void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
pci_disable_device(dev->pdev);
debugfs_remove(priv->dbg_root);
}
-EXPORT_SYMBOL(mlx5_dev_cleanup);
+
+static void mlx5_add_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
+{
+ struct mlx5_device_context *dev_ctx;
+ struct mlx5_core_dev *dev = container_of(priv, struct mlx5_core_dev, priv);
+
+ dev_ctx = kmalloc(sizeof(*dev_ctx), GFP_KERNEL);
+ if (!dev_ctx) {
+ pr_warn("mlx5_add_device: alloc context failed\n");
+ return;
+ }
+
+ dev_ctx->intf = intf;
+ dev_ctx->context = intf->add(dev);
+
+ if (dev_ctx->context) {
+ spin_lock_irq(&priv->ctx_lock);
+ list_add_tail(&dev_ctx->list, &priv->ctx_list);
+ spin_unlock_irq(&priv->ctx_lock);
+ } else {
+ kfree(dev_ctx);
+ }
+}
+
+static void mlx5_remove_device(struct mlx5_interface *intf, struct mlx5_priv *priv)
+{
+ struct mlx5_device_context *dev_ctx;
+ struct mlx5_core_dev *dev = container_of(priv, struct mlx5_core_dev, priv);
+
+ list_for_each_entry(dev_ctx, &priv->ctx_list, list)
+ if (dev_ctx->intf == intf) {
+ spin_lock_irq(&priv->ctx_lock);
+ list_del(&dev_ctx->list);
+ spin_unlock_irq(&priv->ctx_lock);
+
+ intf->remove(dev, dev_ctx->context);
+ kfree(dev_ctx);
+ return;
+ }
+}
+static int mlx5_register_device(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_interface *intf;
+
+ mutex_lock(&intf_mutex);
+ list_add_tail(&priv->dev_list, &dev_list);
+ list_for_each_entry(intf, &intf_list, list)
+ mlx5_add_device(intf, priv);
+ mutex_unlock(&intf_mutex);
+
+ return 0;
+}
+static void mlx5_unregister_device(struct mlx5_core_dev *dev)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_interface *intf;
+
+ mutex_lock(&intf_mutex);
+ list_for_each_entry(intf, &intf_list, list)
+ mlx5_remove_device(intf, priv);
+ list_del(&priv->dev_list);
+ mutex_unlock(&intf_mutex);
+}
+
+int mlx5_register_interface(struct mlx5_interface *intf)
+{
+ struct mlx5_priv *priv;
+
+ if (!intf->add || !intf->remove)
+ return -EINVAL;
+
+ mutex_lock(&intf_mutex);
+ list_add_tail(&intf->list, &intf_list);
+ list_for_each_entry(priv, &dev_list, dev_list)
+ mlx5_add_device(intf, priv);
+ mutex_unlock(&intf_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(mlx5_register_interface);
+
+void mlx5_unregister_interface(struct mlx5_interface *intf)
+{
+ struct mlx5_priv *priv;
+
+ mutex_lock(&intf_mutex);
+ list_for_each_entry(priv, &dev_list, dev_list)
+ mlx5_remove_device(intf, priv);
+ list_del(&intf->list);
+ mutex_unlock(&intf_mutex);
+}
+EXPORT_SYMBOL(mlx5_unregister_interface);
+
+static void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
+ unsigned long param)
+{
+ struct mlx5_priv *priv = &dev->priv;
+ struct mlx5_device_context *dev_ctx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->ctx_lock, flags);
+
+ list_for_each_entry(dev_ctx, &priv->ctx_list, list)
+ if (dev_ctx->intf->event)
+ dev_ctx->intf->event(dev, dev_ctx->context, event, param);
+
+ spin_unlock_irqrestore(&priv->ctx_lock, flags);
+}
+
+struct mlx5_core_event_handler {
+ void (*event)(struct mlx5_core_dev *dev,
+ enum mlx5_dev_event event,
+ void *data);
+};
+
+static int init_one(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct mlx5_core_dev *dev;
+ struct mlx5_priv *priv;
+ int err;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ dev_err(&pdev->dev, "kzalloc failed\n");
+ return -ENOMEM;
+ }
+ priv = &dev->priv;
+
+ pci_set_drvdata(pdev, dev);
+
+ if (prof_sel < 0 || prof_sel >= ARRAY_SIZE(profile)) {
+ pr_warn("selected profile out of range, selecting default (%d)\n",
+ MLX5_DEFAULT_PROF);
+ prof_sel = MLX5_DEFAULT_PROF;
+ }
+ dev->profile = &profile[prof_sel];
+ dev->event = mlx5_core_event;
+
+ err = mlx5_dev_init(dev, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "mlx5_dev_init failed %d\n", err);
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&priv->ctx_list);
+ spin_lock_init(&priv->ctx_lock);
+ err = mlx5_register_device(dev);
+ if (err) {
+ dev_err(&pdev->dev, "mlx5_register_device failed %d\n", err);
+ goto out_init;
+ }
+
+ return 0;
+
+out_init:
+ mlx5_dev_cleanup(dev);
+out:
+ kfree(dev);
+ return err;
+}
+static void remove_one(struct pci_dev *pdev)
+{
+ struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+
+ mlx5_unregister_device(dev);
+ mlx5_dev_cleanup(dev);
+ kfree(dev);
+}
+
+static const struct pci_device_id mlx5_core_pci_table[] = {
+ { PCI_VDEVICE(MELLANOX, 4113) }, /* MT4113 Connect-IB */
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);
+
+static struct pci_driver mlx5_core_driver = {
+ .name = DRIVER_NAME,
+ .id_table = mlx5_core_pci_table,
+ .probe = init_one,
+ .remove = remove_one
+};
static int __init init(void)
{
@@ -530,8 +806,15 @@ static int __init init(void)
}
mlx5_health_init();
+ err = pci_register_driver(&mlx5_core_driver);
+ if (err)
+ goto err_health;
+
return 0;
+err_health:
+ mlx5_health_cleanup();
+ destroy_workqueue(mlx5_core_wq);
err_debug:
mlx5_unregister_debugfs();
return err;
@@ -539,6 +822,7 @@ err_debug:
static void __exit cleanup(void)
{
+ pci_unregister_driver(&mlx5_core_driver);
mlx5_health_cleanup();
destroy_workqueue(mlx5_core_wq);
mlx5_unregister_debugfs();
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mr.c b/drivers/net/ethernet/mellanox/mlx5/core/mr.c
index ba0401d4af50..184c3615f479 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mr.c
@@ -94,6 +94,11 @@ int mlx5_core_create_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr,
write_lock_irq(&table->lock);
err = radix_tree_insert(&table->tree, mlx5_base_mkey(mr->key), mr);
write_unlock_irq(&table->lock);
+ if (err) {
+ mlx5_core_warn(dev, "failed radix tree insert of mr 0x%x, %d\n",
+ mlx5_base_mkey(mr->key), err);
+ mlx5_core_destroy_mkey(dev, mr);
+ }
return err;
}
@@ -104,12 +109,22 @@ int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr)
struct mlx5_mr_table *table = &dev->priv.mr_table;
struct mlx5_destroy_mkey_mbox_in in;
struct mlx5_destroy_mkey_mbox_out out;
+ struct mlx5_core_mr *deleted_mr;
unsigned long flags;
int err;
memset(&in, 0, sizeof(in));
memset(&out, 0, sizeof(out));
+ write_lock_irqsave(&table->lock, flags);
+ deleted_mr = radix_tree_delete(&table->tree, mlx5_base_mkey(mr->key));
+ write_unlock_irqrestore(&table->lock, flags);
+ if (!deleted_mr) {
+ mlx5_core_warn(dev, "failed radix tree delete of mr 0x%x\n",
+ mlx5_base_mkey(mr->key));
+ return -ENOENT;
+ }
+
in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_MKEY);
in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key));
err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
@@ -119,10 +134,6 @@ int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr)
if (out.hdr.status)
return mlx5_cmd_status_to_err(&out.hdr);
- write_lock_irqsave(&table->lock, flags);
- radix_tree_delete(&table->tree, mlx5_base_mkey(mr->key));
- write_unlock_irqrestore(&table->lock, flags);
-
return err;
}
EXPORT_SYMBOL(mlx5_core_destroy_mkey);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index c2a953ef0e67..d476918ef269 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -51,7 +51,7 @@ enum {
struct mlx5_pages_req {
struct mlx5_core_dev *dev;
- u32 func_id;
+ u16 func_id;
s32 npages;
struct work_struct work;
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 8c9ac870ecb1..313965853e10 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -86,7 +86,7 @@ struct mlx5_reg_pcap {
__be32 caps_31_0;
};
-int mlx5_set_port_caps(struct mlx5_core_dev *dev, int port_num, u32 caps)
+int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
{
struct mlx5_reg_pcap in;
struct mlx5_reg_pcap out;
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index c83d16dc7cd5..0eb47649191b 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1519,7 +1519,8 @@ static int ks_hw_init(struct ks_net *ks)
ks->all_mcast = 0;
ks->mcast_lst_size = 0;
- ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL);
+ ks->frame_head_info = devm_kmalloc(&ks->pdev->dev, MHEADER_SIZE,
+ GFP_KERNEL);
if (!ks->frame_head_info)
return false;
@@ -1537,44 +1538,41 @@ MODULE_DEVICE_TABLE(of, ks8851_ml_dt_ids);
static int ks8851_probe(struct platform_device *pdev)
{
- int err = -ENOMEM;
+ int err;
struct resource *io_d, *io_c;
struct net_device *netdev;
struct ks_net *ks;
u16 id, data;
const char *mac;
- io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
- if (!request_mem_region(io_d->start, resource_size(io_d), DRV_NAME))
- goto err_mem_region;
-
- if (!request_mem_region(io_c->start, resource_size(io_c), DRV_NAME))
- goto err_mem_region1;
-
netdev = alloc_etherdev(sizeof(struct ks_net));
if (!netdev)
- goto err_alloc_etherdev;
+ return -ENOMEM;
SET_NETDEV_DEV(netdev, &pdev->dev);
ks = netdev_priv(netdev);
ks->netdev = netdev;
- ks->hw_addr = ioremap(io_d->start, resource_size(io_d));
- if (!ks->hw_addr)
- goto err_ioremap;
+ io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ks->hw_addr = devm_ioremap_resource(&pdev->dev, io_d);
+ if (IS_ERR(ks->hw_addr)) {
+ err = PTR_ERR(ks->hw_addr);
+ goto err_free;
+ }
- ks->hw_addr_cmd = ioremap(io_c->start, resource_size(io_c));
- if (!ks->hw_addr_cmd)
- goto err_ioremap1;
+ io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ ks->hw_addr_cmd = devm_ioremap_resource(&pdev->dev, io_c);
+ if (IS_ERR(ks->hw_addr_cmd)) {
+ err = PTR_ERR(ks->hw_addr_cmd);
+ goto err_free;
+ }
netdev->irq = platform_get_irq(pdev, 0);
if ((int)netdev->irq < 0) {
err = netdev->irq;
- goto err_get_irq;
+ goto err_free;
}
ks->pdev = pdev;
@@ -1604,18 +1602,18 @@ static int ks8851_probe(struct platform_device *pdev)
if ((ks_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
netdev_err(netdev, "failed to read device ID\n");
err = -ENODEV;
- goto err_register;
+ goto err_free;
}
if (ks_read_selftest(ks)) {
netdev_err(netdev, "failed to read device ID\n");
err = -ENODEV;
- goto err_register;
+ goto err_free;
}
err = register_netdev(netdev);
if (err)
- goto err_register;
+ goto err_free;
platform_set_drvdata(pdev, netdev);
@@ -1663,32 +1661,17 @@ static int ks8851_probe(struct platform_device *pdev)
err_pdata:
unregister_netdev(netdev);
-err_register:
-err_get_irq:
- iounmap(ks->hw_addr_cmd);
-err_ioremap1:
- iounmap(ks->hw_addr);
-err_ioremap:
+err_free:
free_netdev(netdev);
-err_alloc_etherdev:
- release_mem_region(io_c->start, resource_size(io_c));
-err_mem_region1:
- release_mem_region(io_d->start, resource_size(io_d));
-err_mem_region:
return err;
}
static int ks8851_remove(struct platform_device *pdev)
{
struct net_device *netdev = platform_get_drvdata(pdev);
- struct ks_net *ks = netdev_priv(netdev);
- struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- kfree(ks->frame_head_info);
unregister_netdev(netdev);
- iounmap(ks->hw_addr);
free_netdev(netdev);
- release_mem_region(iomem->start, resource_size(iomem));
return 0;
}
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index 7a0deadd53bf..2eda153cb1e0 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -503,7 +503,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
skb_hwts = skb_hwtstamps(skb);
skb_hwts->hwtstamp = ns_to_ktime(ns);
- skb_hwts->syststamp.tv64 = 0;
}
/* rth_hash_type and rth_it_hit are non-zero regardless of
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index 7dc3e9b06d75..979c6980639f 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -247,28 +247,6 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
}
}
-static ktime_t ptp_to_ktime(u64 ptptime)
-{
- ktime_t ktimebase;
- u64 ptpbase;
- unsigned long flags;
-
- local_irq_save(flags);
- /* Fill the icache with the code */
- ktime_get_real();
- /* Flush all pending operations */
- mb();
- /* Read the time and PTP clock as close together as
- * possible. It is important that this sequence take the same
- * amount of time to reduce jitter
- */
- ktimebase = ktime_get_real();
- ptpbase = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_HI);
- local_irq_restore(flags);
-
- return ktime_sub_ns(ktimebase, ptpbase - ptptime);
-}
-
static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
{
union cvmx_mixx_orcnt mix_orcnt;
@@ -312,12 +290,12 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
/* Read the hardware TX timestamp if one was recorded */
if (unlikely(re.s.tstamp)) {
struct skb_shared_hwtstamps ts;
+ memset(&ts, 0, sizeof(ts));
/* Read the timestamp */
u64 ns = cvmx_read_csr(CVMX_MIXX_TSTAMP(p->port));
/* Remove the timestamp from the FIFO */
cvmx_write_csr(CVMX_MIXX_TSCTL(p->port), 0);
/* Tell the kernel about the timestamp */
- ts.syststamp = ptp_to_ktime(ns);
ts.hwtstamp = ns_to_ktime(ns);
skb_tstamp_tx(skb, &ts);
}
@@ -429,7 +407,6 @@ good:
struct skb_shared_hwtstamps *ts;
ts = skb_hwtstamps(skb);
ts->hwtstamp = ns_to_ktime(ns);
- ts->syststamp = ptp_to_ktime(ns);
__skb_pull(skb, 8);
}
skb->protocol = eth_type_trans(skb, netdev);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index be618b9e874f..16039d1497b8 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -39,8 +39,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 60
-#define QLCNIC_LINUX_VERSIONID "5.3.60"
+#define _QLCNIC_LINUX_SUBVERSION 61
+#define QLCNIC_LINUX_VERSIONID "5.3.61"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index 304e247bdf33..ffbae293cef5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -136,7 +136,7 @@ int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
rsp = qlcnic_poll_rsp(adapter);
if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
- dev_err(&pdev->dev, "card response timeout.\n");
+ dev_err(&pdev->dev, "command timeout, response = 0x%x\n", rsp);
cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1), &err);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
index 561cb11ca58c..a72bcddf160a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
@@ -926,7 +926,7 @@ static int qlcnic_dcb_get_num_tcs(struct net_device *netdev, int attr, u8 *num)
}
}
-static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
+static int qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct dcb_app app = {
@@ -935,7 +935,7 @@ static u8 qlcnic_dcb_get_app(struct net_device *netdev, u8 idtype, u16 id)
};
if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state))
- return 0;
+ return -EINVAL;
return dcb_getapp(netdev, &app);
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 1b7f3dbae289..141f116eb868 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1290,17 +1290,25 @@ static u64 *qlcnic_fill_stats(u64 *data, void *stats, int type)
void qlcnic_update_stats(struct qlcnic_adapter *adapter)
{
+ struct qlcnic_tx_queue_stats tx_stats;
struct qlcnic_host_tx_ring *tx_ring;
int ring;
+ memset(&tx_stats, 0, sizeof(tx_stats));
for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
- adapter->stats.xmit_on += tx_ring->tx_stats.xmit_on;
- adapter->stats.xmit_off += tx_ring->tx_stats.xmit_off;
- adapter->stats.xmitcalled += tx_ring->tx_stats.xmit_called;
- adapter->stats.xmitfinished += tx_ring->tx_stats.xmit_finished;
- adapter->stats.txbytes += tx_ring->tx_stats.tx_bytes;
+ tx_stats.xmit_on += tx_ring->tx_stats.xmit_on;
+ tx_stats.xmit_off += tx_ring->tx_stats.xmit_off;
+ tx_stats.xmit_called += tx_ring->tx_stats.xmit_called;
+ tx_stats.xmit_finished += tx_ring->tx_stats.xmit_finished;
+ tx_stats.tx_bytes += tx_ring->tx_stats.tx_bytes;
}
+
+ adapter->stats.xmit_on = tx_stats.xmit_on;
+ adapter->stats.xmit_off = tx_stats.xmit_off;
+ adapter->stats.xmitcalled = tx_stats.xmit_called;
+ adapter->stats.xmitfinished = tx_stats.xmit_finished;
+ adapter->stats.txbytes = tx_stats.tx_bytes;
}
static u64 *qlcnic_fill_tx_queue_stats(u64 *data, void *stats)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 4fc186713b66..59846daf1379 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -427,16 +427,17 @@ static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
}
static int qlcnic_fdb_dump(struct sk_buff *skb, struct netlink_callback *ncb,
- struct net_device *netdev, int idx)
+ struct net_device *netdev,
+ struct net_device *filter_dev, int idx)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
if (!adapter->fdb_mac_learn)
- return ndo_dflt_fdb_dump(skb, ncb, netdev, idx);
+ return ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
qlcnic_sriov_check(adapter))
- idx = ndo_dflt_fdb_dump(skb, ncb, netdev, idx);
+ idx = ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
return idx;
}
@@ -2323,14 +2324,14 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
if (err)
return err;
+ qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
+
err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "failed to register net device\n");
return err;
}
- qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
-
return 0;
}
@@ -2623,13 +2624,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto err_out_disable_mbx_intr;
+ if (adapter->portnum == 0)
+ qlcnic_set_drv_version(adapter);
+
err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
if (err)
goto err_out_disable_mbx_intr;
- if (adapter->portnum == 0)
- qlcnic_set_drv_version(adapter);
-
pci_set_drvdata(pdev, adapter);
if (qlcnic_82xx_check(adapter))
@@ -2980,17 +2981,43 @@ static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring)
}
}
-static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter)
+static void qlcnic_dump_rings(struct qlcnic_adapter *adapter)
{
+ struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct net_device *netdev = adapter->netdev;
+ struct qlcnic_host_rds_ring *rds_ring;
+ struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_host_tx_ring *tx_ring;
int ring;
if (!netdev || !netif_running(netdev))
return;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ if (!rds_ring)
+ continue;
+ netdev_info(netdev,
+ "rds_ring=%d crb_rcv_producer=%d producer=%u num_desc=%u\n",
+ ring, readl(rds_ring->crb_rcv_producer),
+ rds_ring->producer, rds_ring->num_desc);
+ }
+
+ for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
+ sds_ring = &(recv_ctx->sds_rings[ring]);
+ if (!sds_ring)
+ continue;
+ netdev_info(netdev,
+ "sds_ring=%d crb_sts_consumer=%d consumer=%u crb_intr_mask=%d num_desc=%u\n",
+ ring, readl(sds_ring->crb_sts_consumer),
+ sds_ring->consumer, readl(sds_ring->crb_intr_mask),
+ sds_ring->num_desc);
+ }
+
for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
+ if (!tx_ring)
+ continue;
netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n",
ring, tx_ring->ctx_id);
netdev_info(netdev,
@@ -3013,9 +3040,10 @@ static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter)
netdev_info(netdev, "Total desc=%d, Available desc=%d\n",
tx_ring->num_desc, qlcnic_tx_avail(tx_ring));
- if (netif_msg_tx_done(adapter->ahw))
+ if (netif_msg_tx_err(adapter->ahw))
dump_tx_ring_desc(tx_ring);
}
+
}
static void qlcnic_tx_timeout(struct net_device *netdev)
@@ -3025,16 +3053,18 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
if (test_bit(__QLCNIC_RESETTING, &adapter->state))
return;
- if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
- netdev_info(netdev, "Tx timeout, reset the adapter.\n");
+ qlcnic_dump_rings(adapter);
+
+ if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS ||
+ netif_msg_tx_err(adapter->ahw)) {
+ netdev_err(netdev, "Tx timeout, reset the adapter.\n");
if (qlcnic_82xx_check(adapter))
adapter->need_fw_reset = 1;
else if (qlcnic_83xx_check(adapter))
qlcnic_83xx_idc_request_reset(adapter,
QLCNIC_FORCE_FW_DUMP_KEY);
} else {
- netdev_info(netdev, "Tx timeout, reset adapter context.\n");
- qlcnic_dump_tx_rings(adapter);
+ netdev_err(netdev, "Tx timeout, reset adapter context.\n");
adapter->ahw->reset_context = 1;
}
}
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 2bc728e65e24..75b1693ec8bf 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -382,13 +382,6 @@ static int cp_get_eeprom(struct net_device *dev,
static int cp_set_eeprom(struct net_device *dev,
struct ethtool_eeprom *eeprom, u8 *data);
-static DEFINE_PCI_DEVICE_TABLE(cp_pci_tbl) = {
- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139), },
- { PCI_DEVICE(PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322), },
- { },
-};
-MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
-
static struct {
const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
@@ -1887,11 +1880,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
resource_size_t pciaddr;
unsigned int addr_len, i, pci_using_dac;
-#ifndef MODULE
- static int version_printed;
- if (version_printed++ == 0)
- pr_info("%s", version);
-#endif
+ pr_info_once("%s", version);
if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
@@ -2110,6 +2099,13 @@ static int cp_resume (struct pci_dev *pdev)
}
#endif /* CONFIG_PM */
+static const struct pci_device_id cp_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139), },
+ { PCI_DEVICE(PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322), },
+ { },
+};
+MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
+
static struct pci_driver cp_driver = {
.name = DRV_NAME,
.id_table = cp_pci_tbl,
@@ -2121,18 +2117,4 @@ static struct pci_driver cp_driver = {
#endif
};
-static int __init cp_init (void)
-{
-#ifdef MODULE
- pr_info("%s", version);
-#endif
- return pci_register_driver(&cp_driver);
-}
-
-static void __exit cp_exit (void)
-{
- pci_unregister_driver (&cp_driver);
-}
-
-module_init(cp_init);
-module_exit(cp_exit);
+module_pci_driver(cp_driver);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index be425ad5e824..9887bcb45b84 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -27,6 +27,8 @@
#include <linux/firmware.h>
#include <linux/pci-aspm.h>
#include <linux/prefetch.h>
+#include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -538,6 +540,7 @@ enum rtl_register_content {
MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
Jumbo_En0 = (1 << 2), /* 8168 only. Reserved in the 8168b */
+ Rdy_to_L23 = (1 << 1), /* L23 Enable */
Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
/* Config4 register */
@@ -626,39 +629,22 @@ enum rtl_tx_desc_bit_0 {
/* 8102e, 8168c and beyond. */
enum rtl_tx_desc_bit_1 {
+ /* First doubleword. */
+ TD1_GTSENV4 = (1 << 26), /* Giant Send for IPv4 */
+ TD1_GTSENV6 = (1 << 25), /* Giant Send for IPv6 */
+#define GTTCPHO_SHIFT 18
+#define GTTCPHO_MAX 0x7fU
+
/* Second doubleword. */
+#define TCPHO_SHIFT 18
+#define TCPHO_MAX 0x3ffU
#define TD1_MSS_SHIFT 18 /* MSS position (11 bits) */
- TD1_IP_CS = (1 << 29), /* Calculate IP checksum */
+ TD1_IPv6_CS = (1 << 28), /* Calculate IPv6 checksum */
+ TD1_IPv4_CS = (1 << 29), /* Calculate IPv4 checksum */
TD1_TCP_CS = (1 << 30), /* Calculate TCP/IP checksum */
TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */
};
-static const struct rtl_tx_desc_info {
- struct {
- u32 udp;
- u32 tcp;
- } checksum;
- u16 mss_shift;
- u16 opts_offset;
-} tx_desc_info [] = {
- [RTL_TD_0] = {
- .checksum = {
- .udp = TD0_IP_CS | TD0_UDP_CS,
- .tcp = TD0_IP_CS | TD0_TCP_CS
- },
- .mss_shift = TD0_MSS_SHIFT,
- .opts_offset = 0
- },
- [RTL_TD_1] = {
- .checksum = {
- .udp = TD1_IP_CS | TD1_UDP_CS,
- .tcp = TD1_IP_CS | TD1_TCP_CS
- },
- .mss_shift = TD1_MSS_SHIFT,
- .opts_offset = 1
- }
-};
-
enum rtl_rx_desc_bit {
/* Rx private */
PID1 = (1 << 18), /* Protocol ID bit 1/2 */
@@ -782,6 +768,7 @@ struct rtl8169_private {
unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
unsigned int (*link_ok)(void __iomem *);
int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
+ bool (*tso_csum)(struct rtl8169_private *, struct sk_buff *, u32 *);
struct {
DECLARE_BITMAP(flags, RTL_FLAG_MAX);
@@ -4239,6 +4226,8 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
break;
case RTL_GIGA_MAC_VER_40:
+ RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
+ break;
case RTL_GIGA_MAC_VER_41:
case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43:
@@ -4897,6 +4886,21 @@ static void rtl_enable_clock_request(struct pci_dev *pdev)
PCI_EXP_LNKCTL_CLKREQ_EN);
}
+static void rtl_pcie_state_l2l3_enable(struct rtl8169_private *tp, bool enable)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ u8 data;
+
+ data = RTL_R8(Config3);
+
+ if (enable)
+ data |= Rdy_to_L23;
+ else
+ data &= ~Rdy_to_L23;
+
+ RTL_W8(Config3, data);
+}
+
#define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
@@ -5246,6 +5250,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
};
rtl_hw_start_8168f(tp);
+ rtl_pcie_state_l2l3_enable(tp, false);
rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
@@ -5284,6 +5289,8 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC);
+
+ rtl_pcie_state_l2l3_enable(tp, false);
}
static void rtl_hw_start_8168g_2(struct rtl8169_private *tp)
@@ -5536,6 +5543,8 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
+
+ rtl_pcie_state_l2l3_enable(tp, false);
}
static void rtl_hw_start_8105e_2(struct rtl8169_private *tp)
@@ -5571,6 +5580,8 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, ERIAR_EXGMAC);
+
+ rtl_pcie_state_l2l3_enable(tp, false);
}
static void rtl_hw_start_8106(struct rtl8169_private *tp)
@@ -5583,6 +5594,8 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp)
RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
+
+ rtl_pcie_state_l2l3_enable(tp, false);
}
static void rtl_hw_start_8101(struct net_device *dev)
@@ -5941,32 +5954,179 @@ static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
}
-static inline bool rtl8169_tso_csum(struct rtl8169_private *tp,
- struct sk_buff *skb, u32 *opts)
+static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+/* r8169_csum_workaround()
+ * The hw limites the value the transport offset. When the offset is out of the
+ * range, calculate the checksum by sw.
+ */
+static void r8169_csum_workaround(struct rtl8169_private *tp,
+ struct sk_buff *skb)
+{
+ if (skb_shinfo(skb)->gso_size) {
+ netdev_features_t features = tp->dev->features;
+ struct sk_buff *segs, *nskb;
+
+ features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+ segs = skb_gso_segment(skb, features);
+ if (IS_ERR(segs) || !segs)
+ goto drop;
+
+ do {
+ nskb = segs;
+ segs = segs->next;
+ nskb->next = NULL;
+ rtl8169_start_xmit(nskb, tp->dev);
+ } while (segs);
+
+ dev_kfree_skb(skb);
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (skb_checksum_help(skb) < 0)
+ goto drop;
+
+ rtl8169_start_xmit(skb, tp->dev);
+ } else {
+ struct net_device_stats *stats;
+
+drop:
+ stats = &tp->dev->stats;
+ stats->tx_dropped++;
+ dev_kfree_skb(skb);
+ }
+}
+
+/* msdn_giant_send_check()
+ * According to the document of microsoft, the TCP Pseudo Header excludes the
+ * packet length for IPv6 TCP large packets.
+ */
+static int msdn_giant_send_check(struct sk_buff *skb)
+{
+ const struct ipv6hdr *ipv6h;
+ struct tcphdr *th;
+ int ret;
+
+ ret = skb_cow_head(skb, 0);
+ if (ret)
+ return ret;
+
+ ipv6h = ipv6_hdr(skb);
+ th = tcp_hdr(skb);
+
+ th->check = 0;
+ th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
+
+ return ret;
+}
+
+static inline __be16 get_protocol(struct sk_buff *skb)
+{
+ __be16 protocol;
+
+ if (skb->protocol == htons(ETH_P_8021Q))
+ protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ else
+ protocol = skb->protocol;
+
+ return protocol;
+}
+
+static bool rtl8169_tso_csum_v1(struct rtl8169_private *tp,
+ struct sk_buff *skb, u32 *opts)
{
- const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
u32 mss = skb_shinfo(skb)->gso_size;
- int offset = info->opts_offset;
if (mss) {
opts[0] |= TD_LSO;
- opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift;
+ opts[0] |= min(mss, TD_MSS_MAX) << TD0_MSS_SHIFT;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
+ if (ip->protocol == IPPROTO_TCP)
+ opts[0] |= TD0_IP_CS | TD0_TCP_CS;
+ else if (ip->protocol == IPPROTO_UDP)
+ opts[0] |= TD0_IP_CS | TD0_UDP_CS;
+ else
+ WARN_ON_ONCE(1);
+ }
+
+ return true;
+}
+
+static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
+ struct sk_buff *skb, u32 *opts)
+{
+ u32 transport_offset = (u32)skb_transport_offset(skb);
+ u32 mss = skb_shinfo(skb)->gso_size;
+
+ if (mss) {
+ if (transport_offset > GTTCPHO_MAX) {
+ netif_warn(tp, tx_err, tp->dev,
+ "Invalid transport offset 0x%x for TSO\n",
+ transport_offset);
+ return false;
+ }
+
+ switch (get_protocol(skb)) {
+ case htons(ETH_P_IP):
+ opts[0] |= TD1_GTSENV4;
+ break;
+
+ case htons(ETH_P_IPV6):
+ if (msdn_giant_send_check(skb))
+ return false;
+
+ opts[0] |= TD1_GTSENV6;
+ break;
+
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+
+ opts[0] |= transport_offset << GTTCPHO_SHIFT;
+ opts[1] |= min(mss, TD_MSS_MAX) << TD1_MSS_SHIFT;
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ u8 ip_protocol;
+
if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb);
- if (ip->protocol == IPPROTO_TCP)
- opts[offset] |= info->checksum.tcp;
- else if (ip->protocol == IPPROTO_UDP)
- opts[offset] |= info->checksum.udp;
+ if (transport_offset > TCPHO_MAX) {
+ netif_warn(tp, tx_err, tp->dev,
+ "Invalid transport offset 0x%x\n",
+ transport_offset);
+ return false;
+ }
+
+ switch (get_protocol(skb)) {
+ case htons(ETH_P_IP):
+ opts[1] |= TD1_IPv4_CS;
+ ip_protocol = ip_hdr(skb)->protocol;
+ break;
+
+ case htons(ETH_P_IPV6):
+ opts[1] |= TD1_IPv6_CS;
+ ip_protocol = ipv6_hdr(skb)->nexthdr;
+ break;
+
+ default:
+ ip_protocol = IPPROTO_RAW;
+ break;
+ }
+
+ if (ip_protocol == IPPROTO_TCP)
+ opts[1] |= TD1_TCP_CS;
+ else if (ip_protocol == IPPROTO_UDP)
+ opts[1] |= TD1_UDP_CS;
else
WARN_ON_ONCE(1);
+
+ opts[1] |= transport_offset << TCPHO_SHIFT;
} else {
if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
return rtl_skb_pad(skb);
}
+
return true;
}
@@ -5994,8 +6154,10 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb));
opts[0] = DescOwn;
- if (!rtl8169_tso_csum(tp, skb, opts))
- goto err_update_stats;
+ if (!tp->tso_csum(tp, skb, opts)) {
+ r8169_csum_workaround(tp, skb);
+ return NETDEV_TX_OK;
+ }
len = skb_headlen(skb);
mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
@@ -6060,7 +6222,6 @@ err_dma_1:
rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd);
err_dma_0:
dev_kfree_skb_any(skb);
-err_update_stats:
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
@@ -7145,6 +7306,14 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* 8110SCd requires hardware Rx VLAN - disallow toggling */
dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+ if (tp->txd_version == RTL_TD_0)
+ tp->tso_csum = rtl8169_tso_csum_v1;
+ else if (tp->txd_version == RTL_TD_1) {
+ tp->tso_csum = rtl8169_tso_csum_v2;
+ dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+ } else
+ WARN_ON_ONCE(1);
+
dev->hw_features |= NETIF_F_RXALL;
dev->hw_features |= NETIF_F_RXFCS;
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 7622213beef1..60e9c2cd051e 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1094,20 +1094,16 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* Free Rx skb ringbuffer */
if (mdp->rx_skbuff) {
- for (i = 0; i < mdp->num_rx_ring; i++) {
- if (mdp->rx_skbuff[i])
- dev_kfree_skb(mdp->rx_skbuff[i]);
- }
+ for (i = 0; i < mdp->num_rx_ring; i++)
+ dev_kfree_skb(mdp->rx_skbuff[i]);
}
kfree(mdp->rx_skbuff);
mdp->rx_skbuff = NULL;
/* Free Tx skb ringbuffer */
if (mdp->tx_skbuff) {
- for (i = 0; i < mdp->num_tx_ring; i++) {
- if (mdp->tx_skbuff[i])
- dev_kfree_skb(mdp->tx_skbuff[i]);
- }
+ for (i = 0; i < mdp->num_tx_ring; i++)
+ dev_kfree_skb(mdp->tx_skbuff[i]);
}
kfree(mdp->tx_skbuff);
mdp->tx_skbuff = NULL;
@@ -2077,13 +2073,11 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
rxdesc = &mdp->rx_ring[i];
rxdesc->status = 0;
rxdesc->addr = 0xBADF00D0;
- if (mdp->rx_skbuff[i])
- dev_kfree_skb(mdp->rx_skbuff[i]);
+ dev_kfree_skb(mdp->rx_skbuff[i]);
mdp->rx_skbuff[i] = NULL;
}
for (i = 0; i < mdp->num_tx_ring; i++) {
- if (mdp->tx_skbuff[i])
- dev_kfree_skb(mdp->tx_skbuff[i]);
+ dev_kfree_skb(mdp->tx_skbuff[i]);
mdp->tx_skbuff[i] = NULL;
}
@@ -2752,6 +2746,7 @@ static const struct of_device_id sh_eth_match_table[] = {
{ .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data },
{ .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data },
{ .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data },
+ { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data },
{ .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data },
{ }
};
@@ -2978,6 +2973,7 @@ static struct platform_device_id sh_eth_id_table[] = {
{ "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
{ "r8a7790-ether", (kernel_ulong_t)&r8a779x_data },
{ "r8a7791-ether", (kernel_ulong_t)&r8a779x_data },
+ { "r8a7794-ether", (kernel_ulong_t)&r8a779x_data },
{ }
};
MODULE_DEVICE_TABLE(platform, sh_eth_id_table);
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index b5ed30a39144..002d4cdc319f 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -755,6 +755,8 @@ static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type)
{ NULL, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
#define EF10_OTHER_STAT(ext_name) \
[EF10_STAT_ ## ext_name] = { #ext_name, 0, 0 }
+#define GENERIC_SW_STAT(ext_name) \
+ [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(tx_bytes, TX_BYTES),
@@ -798,6 +800,8 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(rx_align_error, RX_ALIGN_ERROR_PKTS),
EF10_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS),
EF10_DMA_STAT(rx_nodesc_drops, RX_NODESC_DROPS),
+ GENERIC_SW_STAT(rx_nodesc_trunc),
+ GENERIC_SW_STAT(rx_noskb_drops),
EF10_DMA_STAT(rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW),
EF10_DMA_STAT(rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW),
EF10_DMA_STAT(rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL),
@@ -841,7 +845,9 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
(1ULL << EF10_STAT_rx_gtjumbo) | \
(1ULL << EF10_STAT_rx_bad_gtjumbo) | \
(1ULL << EF10_STAT_rx_overflow) | \
- (1ULL << EF10_STAT_rx_nodesc_drops))
+ (1ULL << EF10_STAT_rx_nodesc_drops) | \
+ (1ULL << GENERIC_STAT_rx_nodesc_trunc) | \
+ (1ULL << GENERIC_STAT_rx_noskb_drops))
/* These statistics are only provided by the 10G MAC. For a 10G/40G
* switchable port we do not expose these because they might not
@@ -951,7 +957,7 @@ static int efx_ef10_try_update_nic_stats(struct efx_nic *efx)
stats[EF10_STAT_rx_bytes_minus_good_bytes];
efx_update_diff_stat(&stats[EF10_STAT_rx_bad_bytes],
stats[EF10_STAT_rx_bytes_minus_good_bytes]);
-
+ efx_update_sw_stats(efx, stats);
return 0;
}
@@ -990,7 +996,9 @@ static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats,
core_stats->tx_packets = stats[EF10_STAT_tx_packets];
core_stats->rx_bytes = stats[EF10_STAT_rx_bytes];
core_stats->tx_bytes = stats[EF10_STAT_tx_bytes];
- core_stats->rx_dropped = stats[EF10_STAT_rx_nodesc_drops];
+ core_stats->rx_dropped = stats[EF10_STAT_rx_nodesc_drops] +
+ stats[GENERIC_STAT_rx_nodesc_trunc] +
+ stats[GENERIC_STAT_rx_noskb_drops];
core_stats->multicast = stats[EF10_STAT_rx_multicast];
core_stats->rx_length_errors =
stats[EF10_STAT_rx_gtjumbo] +
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 1e274045970f..4cebe9d37816 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -272,6 +272,9 @@ static int efx_poll(struct napi_struct *napi, int budget)
struct efx_nic *efx = channel->efx;
int spent;
+ if (!efx_channel_lock_napi(channel))
+ return budget;
+
netif_vdbg(efx, intr, efx->net_dev,
"channel %d NAPI poll executing on CPU %d\n",
channel->channel, raw_smp_processor_id());
@@ -311,6 +314,7 @@ static int efx_poll(struct napi_struct *napi, int budget)
efx_nic_eventq_read_ack(channel);
}
+ efx_channel_unlock_napi(channel);
return spent;
}
@@ -357,7 +361,7 @@ static int efx_init_eventq(struct efx_channel *channel)
}
/* Enable event queue processing and NAPI */
-static void efx_start_eventq(struct efx_channel *channel)
+void efx_start_eventq(struct efx_channel *channel)
{
netif_dbg(channel->efx, ifup, channel->efx->net_dev,
"chan %d start event queue\n", channel->channel);
@@ -366,17 +370,20 @@ static void efx_start_eventq(struct efx_channel *channel)
channel->enabled = true;
smp_wmb();
+ efx_channel_enable(channel);
napi_enable(&channel->napi_str);
efx_nic_eventq_read_ack(channel);
}
/* Disable event queue processing and NAPI */
-static void efx_stop_eventq(struct efx_channel *channel)
+void efx_stop_eventq(struct efx_channel *channel)
{
if (!channel->enabled)
return;
napi_disable(&channel->napi_str);
+ while (!efx_channel_disable(channel))
+ usleep_range(1000, 20000);
channel->enabled = false;
}
@@ -1960,6 +1967,8 @@ static void efx_init_napi_channel(struct efx_channel *channel)
channel->napi_dev = efx->net_dev;
netif_napi_add(channel->napi_dev, &channel->napi_str,
efx_poll, napi_weight);
+ napi_hash_add(&channel->napi_str);
+ efx_channel_init_lock(channel);
}
static void efx_init_napi(struct efx_nic *efx)
@@ -1972,8 +1981,10 @@ static void efx_init_napi(struct efx_nic *efx)
static void efx_fini_napi_channel(struct efx_channel *channel)
{
- if (channel->napi_dev)
+ if (channel->napi_dev) {
netif_napi_del(&channel->napi_str);
+ napi_hash_del(&channel->napi_str);
+ }
channel->napi_dev = NULL;
}
@@ -2008,6 +2019,37 @@ static void efx_netpoll(struct net_device *net_dev)
#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static int efx_busy_poll(struct napi_struct *napi)
+{
+ struct efx_channel *channel =
+ container_of(napi, struct efx_channel, napi_str);
+ struct efx_nic *efx = channel->efx;
+ int budget = 4;
+ int old_rx_packets, rx_packets;
+
+ if (!netif_running(efx->net_dev))
+ return LL_FLUSH_FAILED;
+
+ if (!efx_channel_lock_poll(channel))
+ return LL_FLUSH_BUSY;
+
+ old_rx_packets = channel->rx_queue.rx_packets;
+ efx_process_channel(channel, budget);
+
+ rx_packets = channel->rx_queue.rx_packets - old_rx_packets;
+
+ /* There is no race condition with NAPI here.
+ * NAPI will automatically be rescheduled if it yielded during busy
+ * polling, because it was not able to take the lock and thus returned
+ * the full budget.
+ */
+ efx_channel_unlock_poll(channel);
+
+ return rx_packets;
+}
+#endif
+
/**************************************************************************
*
* Kernel net device interface
@@ -2177,6 +2219,9 @@ static const struct net_device_ops efx_farch_netdev_ops = {
.ndo_poll_controller = efx_netpoll,
#endif
.ndo_setup_tc = efx_setup_tc,
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = efx_busy_poll,
+#endif
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = efx_filter_rfs,
#endif
@@ -2197,6 +2242,9 @@ static const struct net_device_ops efx_ef10_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll,
#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = efx_busy_poll,
+#endif
#ifdef CONFIG_RFS_ACCEL
.ndo_rx_flow_steer = efx_filter_rfs,
#endif
@@ -2607,6 +2655,8 @@ static DEFINE_PCI_DEVICE_TABLE(efx_pci_table) = {
.driver_data = (unsigned long) &siena_a0_nic_type},
{PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x0903), /* SFC9120 PF */
.driver_data = (unsigned long) &efx_hunt_a0_nic_type},
+ {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x0923), /* SFC9140 PF */
+ .driver_data = (unsigned long) &efx_hunt_a0_nic_type},
{0} /* end of list */
};
@@ -2722,6 +2772,17 @@ static void efx_fini_struct(struct efx_nic *efx)
}
}
+void efx_update_sw_stats(struct efx_nic *efx, u64 *stats)
+{
+ u64 n_rx_nodesc_trunc = 0;
+ struct efx_channel *channel;
+
+ efx_for_each_channel(channel, efx)
+ n_rx_nodesc_trunc += channel->n_rx_nodesc_trunc;
+ stats[GENERIC_STAT_rx_nodesc_trunc] = n_rx_nodesc_trunc;
+ stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops);
+}
+
/**************************************************************************
*
* PCI interface
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 99032581336f..2587c582a821 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -194,11 +194,16 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
bool rx_may_override_tx);
void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
unsigned int *rx_usecs, bool *rx_adaptive);
+void efx_stop_eventq(struct efx_channel *channel);
+void efx_start_eventq(struct efx_channel *channel);
/* Dummy PHY ops for PHY drivers */
int efx_port_dummy_op_int(struct efx_nic *efx);
void efx_port_dummy_op_void(struct efx_nic *efx);
+/* Update the generic software stats in the passed stats array */
+void efx_update_sw_stats(struct efx_nic *efx, u64 *stats);
+
/* MTD */
#ifdef CONFIG_SFC_MTD
int efx_mtd_add(struct efx_nic *efx, struct efx_mtd_partition *parts,
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 74739c4b9997..cad258a78708 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -77,7 +77,6 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = {
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc),
- EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_nodesc_trunc),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_events),
EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_packets),
};
@@ -360,6 +359,37 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
return n;
}
+static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings)
+{
+ size_t n_stats = 0;
+ struct efx_channel *channel;
+
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_has_tx_queues(channel)) {
+ n_stats++;
+ if (strings != NULL) {
+ snprintf(strings, ETH_GSTRING_LEN,
+ "tx-%u.tx_packets",
+ channel->tx_queue[0].queue /
+ EFX_TXQ_TYPES);
+
+ strings += ETH_GSTRING_LEN;
+ }
+ }
+ }
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_has_rx_queue(channel)) {
+ n_stats++;
+ if (strings != NULL) {
+ snprintf(strings, ETH_GSTRING_LEN,
+ "rx-%d.rx_packets", channel->channel);
+ strings += ETH_GSTRING_LEN;
+ }
+ }
+ }
+ return n_stats;
+}
+
static int efx_ethtool_get_sset_count(struct net_device *net_dev,
int string_set)
{
@@ -368,8 +398,9 @@ static int efx_ethtool_get_sset_count(struct net_device *net_dev,
switch (string_set) {
case ETH_SS_STATS:
return efx->type->describe_stats(efx, NULL) +
- EFX_ETHTOOL_SW_STAT_COUNT +
- efx_ptp_describe_stats(efx, NULL);
+ EFX_ETHTOOL_SW_STAT_COUNT +
+ efx_describe_per_queue_stats(efx, NULL) +
+ efx_ptp_describe_stats(efx, NULL);
case ETH_SS_TEST:
return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
default:
@@ -391,6 +422,8 @@ static void efx_ethtool_get_strings(struct net_device *net_dev,
strlcpy(strings + i * ETH_GSTRING_LEN,
efx_sw_stat_desc[i].name, ETH_GSTRING_LEN);
strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN;
+ strings += (efx_describe_per_queue_stats(efx, strings) *
+ ETH_GSTRING_LEN);
efx_ptp_describe_stats(efx, strings);
break;
case ETH_SS_TEST:
@@ -410,6 +443,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
const struct efx_sw_stat_desc *stat;
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
+ struct efx_rx_queue *rx_queue;
int i;
spin_lock_bh(&efx->stats_lock);
@@ -445,6 +479,25 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
spin_unlock_bh(&efx->stats_lock);
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_has_tx_queues(channel)) {
+ *data = 0;
+ efx_for_each_channel_tx_queue(tx_queue, channel) {
+ *data += tx_queue->tx_packets;
+ }
+ data++;
+ }
+ }
+ efx_for_each_channel(channel, efx) {
+ if (efx_channel_has_rx_queue(channel)) {
+ *data = 0;
+ efx_for_each_channel_rx_queue(rx_queue, channel) {
+ *data += rx_queue->rx_packets;
+ }
+ data++;
+ }
+ }
+
efx_ptp_update_stats(efx, data);
}
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index fae25a418647..157037546d30 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -142,6 +142,8 @@
hw_name ## _ ## offset }
#define FALCON_OTHER_STAT(ext_name) \
[FALCON_STAT_ ## ext_name] = { #ext_name, 0, 0 }
+#define GENERIC_SW_STAT(ext_name) \
+ [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
static const struct efx_hw_stat_desc falcon_stat_desc[FALCON_STAT_COUNT] = {
FALCON_DMA_STAT(tx_bytes, XgTxOctets),
@@ -191,6 +193,8 @@ static const struct efx_hw_stat_desc falcon_stat_desc[FALCON_STAT_COUNT] = {
FALCON_DMA_STAT(rx_length_error, XgRxLengthError),
FALCON_DMA_STAT(rx_internal_error, XgRxInternalMACError),
FALCON_OTHER_STAT(rx_nodesc_drop_cnt),
+ GENERIC_SW_STAT(rx_nodesc_trunc),
+ GENERIC_SW_STAT(rx_noskb_drops),
};
static const unsigned long falcon_stat_mask[] = {
[0 ... BITS_TO_LONGS(FALCON_STAT_COUNT) - 1] = ~0UL,
@@ -2574,6 +2578,7 @@ static size_t falcon_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
stats[FALCON_STAT_rx_bytes] -
stats[FALCON_STAT_rx_good_bytes] -
stats[FALCON_STAT_rx_control] * 64);
+ efx_update_sw_stats(efx, stats);
}
if (full_stats)
@@ -2584,7 +2589,9 @@ static size_t falcon_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
core_stats->tx_packets = stats[FALCON_STAT_tx_packets];
core_stats->rx_bytes = stats[FALCON_STAT_rx_bytes];
core_stats->tx_bytes = stats[FALCON_STAT_tx_bytes];
- core_stats->rx_dropped = stats[FALCON_STAT_rx_nodesc_drop_cnt];
+ core_stats->rx_dropped = stats[FALCON_STAT_rx_nodesc_drop_cnt] +
+ stats[GENERIC_STAT_rx_nodesc_trunc] +
+ stats[GENERIC_STAT_rx_noskb_drops];
core_stats->multicast = stats[FALCON_STAT_rx_multicast];
core_stats->rx_length_errors =
stats[FALCON_STAT_rx_gtjumbo] +
diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c
index e5fc4e1574b5..fb19b70eac01 100644
--- a/drivers/net/ethernet/sfc/mcdi_port.c
+++ b/drivers/net/ethernet/sfc/mcdi_port.c
@@ -183,6 +183,8 @@ static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
result |= SUPPORTED_1000baseKX_Full;
if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
result |= SUPPORTED_10000baseKX4_Full;
+ if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
+ result |= SUPPORTED_40000baseKR4_Full;
break;
case MC_CMD_MEDIA_XFP:
@@ -190,6 +192,12 @@ static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
result |= SUPPORTED_FIBRE;
break;
+ case MC_CMD_MEDIA_QSFP_PLUS:
+ result |= SUPPORTED_FIBRE;
+ if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
+ result |= SUPPORTED_40000baseCR4_Full;
+ break;
+
case MC_CMD_MEDIA_BASE_T:
result |= SUPPORTED_TP;
if (cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
@@ -237,6 +245,8 @@ static u32 ethtool_to_mcdi_cap(u32 cap)
result |= (1 << MC_CMD_PHY_CAP_1000FDX_LBN);
if (cap & (SUPPORTED_10000baseT_Full | SUPPORTED_10000baseKX4_Full))
result |= (1 << MC_CMD_PHY_CAP_10000FDX_LBN);
+ if (cap & (SUPPORTED_40000baseCR4_Full | SUPPORTED_40000baseKR4_Full))
+ result |= (1 << MC_CMD_PHY_CAP_40000FDX_LBN);
if (cap & SUPPORTED_Pause)
result |= (1 << MC_CMD_PHY_CAP_PAUSE_LBN);
if (cap & SUPPORTED_Asym_Pause)
@@ -285,6 +295,7 @@ static u32 mcdi_to_ethtool_media(u32 media)
case MC_CMD_MEDIA_XFP:
case MC_CMD_MEDIA_SFP_PLUS:
+ case MC_CMD_MEDIA_QSFP_PLUS:
return PORT_FIBRE;
case MC_CMD_MEDIA_BASE_T:
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 5bdae8ed7c57..9ede32064685 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -28,6 +28,7 @@
#include <linux/vmalloc.h>
#include <linux/i2c.h>
#include <linux/mtd/mtd.h>
+#include <net/busy_poll.h>
#include "enum.h"
#include "bitfield.h"
@@ -249,6 +250,8 @@ struct efx_tx_queue {
unsigned int tso_packets;
unsigned int pushes;
unsigned int pio_packets;
+ /* Statistics to supplement MAC stats */
+ unsigned long tx_packets;
/* Members shared between paths and sometimes updated */
unsigned int empty_read_count ____cacheline_aligned_in_smp;
@@ -358,6 +361,8 @@ struct efx_rx_queue {
unsigned int recycle_count;
struct timer_list slow_fill;
unsigned int slow_fill_count;
+ /* Statistics to supplement MAC stats */
+ unsigned long rx_packets;
};
enum efx_sync_events_state {
@@ -383,6 +388,8 @@ enum efx_sync_events_state {
* @irq_moderation: IRQ moderation value (in hardware ticks)
* @napi_dev: Net device used with NAPI
* @napi_str: NAPI control structure
+ * @state: state for NAPI vs busy polling
+ * @state_lock: lock protecting @state
* @eventq: Event queue buffer
* @eventq_mask: Event queue pointer mask
* @eventq_read_ptr: Event queue read pointer
@@ -420,6 +427,22 @@ struct efx_channel {
unsigned int irq_moderation;
struct net_device *napi_dev;
struct napi_struct napi_str;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ unsigned int state;
+ spinlock_t state_lock;
+#define EFX_CHANNEL_STATE_IDLE 0
+#define EFX_CHANNEL_STATE_NAPI (1 << 0) /* NAPI owns this channel */
+#define EFX_CHANNEL_STATE_POLL (1 << 1) /* poll owns this channel */
+#define EFX_CHANNEL_STATE_DISABLED (1 << 2) /* channel is disabled */
+#define EFX_CHANNEL_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this channel */
+#define EFX_CHANNEL_STATE_POLL_YIELD (1 << 4) /* poll yielded this channel */
+#define EFX_CHANNEL_OWNED \
+ (EFX_CHANNEL_STATE_NAPI | EFX_CHANNEL_STATE_POLL)
+#define EFX_CHANNEL_LOCKED \
+ (EFX_CHANNEL_OWNED | EFX_CHANNEL_STATE_DISABLED)
+#define EFX_CHANNEL_USER_PEND \
+ (EFX_CHANNEL_STATE_POLL | EFX_CHANNEL_STATE_POLL_YIELD)
+#endif /* CONFIG_NET_RX_BUSY_POLL */
struct efx_special_buffer eventq;
unsigned int eventq_mask;
unsigned int eventq_read_ptr;
@@ -453,6 +476,135 @@ struct efx_channel {
u32 sync_timestamp_minor;
};
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void efx_channel_init_lock(struct efx_channel *channel)
+{
+ spin_lock_init(&channel->state_lock);
+}
+
+/* Called from the device poll routine to get ownership of a channel. */
+static inline bool efx_channel_lock_napi(struct efx_channel *channel)
+{
+ bool rc = true;
+
+ spin_lock_bh(&channel->state_lock);
+ if (channel->state & EFX_CHANNEL_LOCKED) {
+ WARN_ON(channel->state & EFX_CHANNEL_STATE_NAPI);
+ channel->state |= EFX_CHANNEL_STATE_NAPI_YIELD;
+ rc = false;
+ } else {
+ /* we don't care if someone yielded */
+ channel->state = EFX_CHANNEL_STATE_NAPI;
+ }
+ spin_unlock_bh(&channel->state_lock);
+ return rc;
+}
+
+static inline void efx_channel_unlock_napi(struct efx_channel *channel)
+{
+ spin_lock_bh(&channel->state_lock);
+ WARN_ON(channel->state &
+ (EFX_CHANNEL_STATE_POLL | EFX_CHANNEL_STATE_NAPI_YIELD));
+
+ channel->state &= EFX_CHANNEL_STATE_DISABLED;
+ spin_unlock_bh(&channel->state_lock);
+}
+
+/* Called from efx_busy_poll(). */
+static inline bool efx_channel_lock_poll(struct efx_channel *channel)
+{
+ bool rc = true;
+
+ spin_lock_bh(&channel->state_lock);
+ if ((channel->state & EFX_CHANNEL_LOCKED)) {
+ channel->state |= EFX_CHANNEL_STATE_POLL_YIELD;
+ rc = false;
+ } else {
+ /* preserve yield marks */
+ channel->state |= EFX_CHANNEL_STATE_POLL;
+ }
+ spin_unlock_bh(&channel->state_lock);
+ return rc;
+}
+
+/* Returns true if NAPI tried to get the channel while it was locked. */
+static inline void efx_channel_unlock_poll(struct efx_channel *channel)
+{
+ spin_lock_bh(&channel->state_lock);
+ WARN_ON(channel->state & EFX_CHANNEL_STATE_NAPI);
+
+ /* will reset state to idle, unless channel is disabled */
+ channel->state &= EFX_CHANNEL_STATE_DISABLED;
+ spin_unlock_bh(&channel->state_lock);
+}
+
+/* True if a socket is polling, even if it did not get the lock. */
+static inline bool efx_channel_busy_polling(struct efx_channel *channel)
+{
+ WARN_ON(!(channel->state & EFX_CHANNEL_OWNED));
+ return channel->state & EFX_CHANNEL_USER_PEND;
+}
+
+static inline void efx_channel_enable(struct efx_channel *channel)
+{
+ spin_lock_bh(&channel->state_lock);
+ channel->state = EFX_CHANNEL_STATE_IDLE;
+ spin_unlock_bh(&channel->state_lock);
+}
+
+/* False if the channel is currently owned. */
+static inline bool efx_channel_disable(struct efx_channel *channel)
+{
+ bool rc = true;
+
+ spin_lock_bh(&channel->state_lock);
+ if (channel->state & EFX_CHANNEL_OWNED)
+ rc = false;
+ channel->state |= EFX_CHANNEL_STATE_DISABLED;
+ spin_unlock_bh(&channel->state_lock);
+
+ return rc;
+}
+
+#else /* CONFIG_NET_RX_BUSY_POLL */
+
+static inline void efx_channel_init_lock(struct efx_channel *channel)
+{
+}
+
+static inline bool efx_channel_lock_napi(struct efx_channel *channel)
+{
+ return true;
+}
+
+static inline void efx_channel_unlock_napi(struct efx_channel *channel)
+{
+}
+
+static inline bool efx_channel_lock_poll(struct efx_channel *channel)
+{
+ return false;
+}
+
+static inline void efx_channel_unlock_poll(struct efx_channel *channel)
+{
+}
+
+static inline bool efx_channel_busy_polling(struct efx_channel *channel)
+{
+ return false;
+}
+
+static inline void efx_channel_enable(struct efx_channel *channel)
+{
+}
+
+static inline bool efx_channel_disable(struct efx_channel *channel)
+{
+ return true;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
/**
* struct efx_msi_context - Context for each MSI
* @efx: The associated NIC
@@ -777,6 +929,7 @@ struct vfdi_status;
* interrupt has occurred.
* @stats_lock: Statistics update lock. Must be held when calling
* efx_nic_type::{update,start,stop}_stats.
+ * @n_rx_noskb_drops: Count of RX packets dropped due to failure to allocate an skb
*
* This is stored in the private area of the &struct net_device.
*/
@@ -930,6 +1083,7 @@ struct efx_nic {
spinlock_t biu_lock;
int last_irq_cpu;
spinlock_t stats_lock;
+ atomic_t n_rx_noskb_drops;
};
static inline int efx_dev_registered(struct efx_nic *efx)
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index d3ad8ed8d901..60f85149fc4c 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -135,6 +135,13 @@ enum {
/* Size and alignment of buffer table entries (same) */
#define EFX_BUF_SIZE EFX_PAGE_SIZE
+/* NIC-generic software stats */
+enum {
+ GENERIC_STAT_rx_noskb_drops,
+ GENERIC_STAT_rx_nodesc_trunc,
+ GENERIC_STAT_COUNT
+};
+
/**
* struct falcon_board_type - board operations and type information
* @id: Board type id, as found in NVRAM
@@ -205,7 +212,7 @@ static inline bool falcon_spi_present(const struct falcon_spi_device *spi)
}
enum {
- FALCON_STAT_tx_bytes,
+ FALCON_STAT_tx_bytes = GENERIC_STAT_COUNT,
FALCON_STAT_tx_packets,
FALCON_STAT_tx_pause,
FALCON_STAT_tx_control,
@@ -290,7 +297,7 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
}
enum {
- SIENA_STAT_tx_bytes,
+ SIENA_STAT_tx_bytes = GENERIC_STAT_COUNT,
SIENA_STAT_tx_good_bytes,
SIENA_STAT_tx_bad_bytes,
SIENA_STAT_tx_packets,
@@ -361,7 +368,7 @@ struct siena_nic_data {
};
enum {
- EF10_STAT_tx_bytes,
+ EF10_STAT_tx_bytes = GENERIC_STAT_COUNT,
EF10_STAT_tx_packets,
EF10_STAT_tx_pause,
EF10_STAT_tx_control,
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 48588ddf81b0..c0ad95d2f63d 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -462,6 +462,7 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
skb_record_rx_queue(skb, channel->rx_queue.core_index);
+ skb_mark_napi_id(skb, &channel->napi_str);
gro_result = napi_gro_frags(napi);
if (gro_result != GRO_DROP)
channel->irq_mod_score += 2;
@@ -480,8 +481,10 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel,
skb = netdev_alloc_skb(efx->net_dev,
efx->rx_ip_align + efx->rx_prefix_size +
hdr_len);
- if (unlikely(skb == NULL))
+ if (unlikely(skb == NULL)) {
+ atomic_inc(&efx->n_rx_noskb_drops);
return NULL;
+ }
EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len);
@@ -518,6 +521,8 @@ static struct sk_buff *efx_rx_mk_skb(struct efx_channel *channel,
/* Move past the ethernet header */
skb->protocol = eth_type_trans(skb, efx->net_dev);
+ skb_mark_napi_id(skb, &channel->napi_str);
+
return skb;
}
@@ -528,6 +533,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
struct efx_rx_buffer *rx_buf;
+ rx_queue->rx_packets++;
+
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->flags |= flags;
@@ -662,7 +669,8 @@ void __efx_rx_packet(struct efx_channel *channel)
if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
- if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb)
+ if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb &&
+ !efx_channel_busy_polling(channel))
efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh);
else
efx_rx_deliver(channel, eh, rx_buf, channel->rx_pkt_n_frags);
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index 0fc5baef45b1..10b6173d557d 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -188,7 +188,7 @@ static int efx_test_eventq_irq(struct efx_nic *efx,
schedule_timeout_uninterruptible(wait);
efx_for_each_channel(channel, efx) {
- napi_disable(&channel->napi_str);
+ efx_stop_eventq(channel);
if (channel->eventq_read_ptr !=
read_ptr[channel->channel]) {
set_bit(channel->channel, &napi_ran);
@@ -200,8 +200,7 @@ static int efx_test_eventq_irq(struct efx_nic *efx,
if (efx_nic_event_test_irq_cpu(channel) >= 0)
clear_bit(channel->channel, &int_pend);
}
- napi_enable(&channel->napi_str);
- efx_nic_eventq_read_ack(channel);
+ efx_start_eventq(channel);
}
wait *= 2;
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 50ffefed492c..ae696855f21a 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -424,6 +424,8 @@ static void siena_remove_nic(struct efx_nic *efx)
{ #ext_name, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
#define SIENA_OTHER_STAT(ext_name) \
[SIENA_STAT_ ## ext_name] = { #ext_name, 0, 0 }
+#define GENERIC_SW_STAT(ext_name) \
+ [GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }
static const struct efx_hw_stat_desc siena_stat_desc[SIENA_STAT_COUNT] = {
SIENA_DMA_STAT(tx_bytes, TX_BYTES),
@@ -483,6 +485,8 @@ static const struct efx_hw_stat_desc siena_stat_desc[SIENA_STAT_COUNT] = {
SIENA_DMA_STAT(rx_length_error, RX_LENGTH_ERROR_PKTS),
SIENA_DMA_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS),
SIENA_DMA_STAT(rx_nodesc_drop_cnt, RX_NODESC_DROPS),
+ GENERIC_SW_STAT(rx_nodesc_trunc),
+ GENERIC_SW_STAT(rx_noskb_drops),
};
static const unsigned long siena_stat_mask[] = {
[0 ... BITS_TO_LONGS(SIENA_STAT_COUNT) - 1] = ~0UL,
@@ -528,6 +532,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
efx_update_diff_stat(&stats[SIENA_STAT_rx_good_bytes],
stats[SIENA_STAT_rx_bytes] -
stats[SIENA_STAT_rx_bad_bytes]);
+ efx_update_sw_stats(efx, stats);
return 0;
}
@@ -554,7 +559,9 @@ static size_t siena_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
core_stats->tx_packets = stats[SIENA_STAT_tx_packets];
core_stats->rx_bytes = stats[SIENA_STAT_rx_bytes];
core_stats->tx_bytes = stats[SIENA_STAT_tx_bytes];
- core_stats->rx_dropped = stats[SIENA_STAT_rx_nodesc_drop_cnt];
+ core_stats->rx_dropped = stats[SIENA_STAT_rx_nodesc_drop_cnt] +
+ stats[GENERIC_STAT_rx_nodesc_trunc] +
+ stats[GENERIC_STAT_rx_noskb_drops];
core_stats->multicast = stats[SIENA_STAT_rx_multicast];
core_stats->collisions = stats[SIENA_STAT_tx_collision];
core_stats->rx_length_errors =
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index ede8dcca0ff3..65c220f8661d 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -189,18 +189,6 @@ struct efx_short_copy_buffer {
u8 buf[L1_CACHE_BYTES];
};
-/* Copy in explicit 64-bit writes. */
-static void efx_memcpy_64(void __iomem *dest, void *src, size_t len)
-{
- u64 *src64 = src;
- u64 __iomem *dest64 = dest;
- size_t l64 = len / 8;
- size_t i;
-
- for (i = 0; i < l64; i++)
- writeq(src64[i], &dest64[i]);
-}
-
/* Copy to PIO, respecting that writes to PIO buffers must be dword aligned.
* Advances piobuf pointer. Leaves additional data in the copy buffer.
*/
@@ -210,7 +198,7 @@ static void efx_memcpy_toio_aligned(struct efx_nic *efx, u8 __iomem **piobuf,
{
int block_len = len & ~(sizeof(copy_buf->buf) - 1);
- efx_memcpy_64(*piobuf, data, block_len);
+ __iowrite64_copy(*piobuf, data, block_len >> 3);
*piobuf += block_len;
len -= block_len;
@@ -242,7 +230,8 @@ static void efx_memcpy_toio_aligned_cb(struct efx_nic *efx, u8 __iomem **piobuf,
if (copy_buf->used < sizeof(copy_buf->buf))
return;
- efx_memcpy_64(*piobuf, copy_buf->buf, sizeof(copy_buf->buf));
+ __iowrite64_copy(*piobuf, copy_buf->buf,
+ sizeof(copy_buf->buf) >> 3);
*piobuf += sizeof(copy_buf->buf);
data += copy_to_buf;
len -= copy_to_buf;
@@ -257,7 +246,8 @@ static void efx_flush_copy_buffer(struct efx_nic *efx, u8 __iomem *piobuf,
{
/* if there's anything in it, write the whole buffer, including junk */
if (copy_buf->used)
- efx_memcpy_64(piobuf, copy_buf->buf, sizeof(copy_buf->buf));
+ __iowrite64_copy(piobuf, copy_buf->buf,
+ sizeof(copy_buf->buf) >> 3);
}
/* Traverse skb structure and copy fragments in to PIO buffer.
@@ -316,8 +306,8 @@ efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
*/
BUILD_BUG_ON(L1_CACHE_BYTES >
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
- efx_memcpy_64(tx_queue->piobuf, skb->data,
- ALIGN(skb->len, L1_CACHE_BYTES));
+ __iowrite64_copy(tx_queue->piobuf, skb->data,
+ ALIGN(skb->len, L1_CACHE_BYTES) >> 3);
}
EFX_POPULATE_QWORD_5(buffer->option,
@@ -452,6 +442,8 @@ finish_packet:
/* Pass off to hardware */
efx_nic_push_buffers(tx_queue);
+ tx_queue->tx_packets++;
+
efx_tx_maybe_stop_queue(tx_queue);
return NETDEV_TX_OK;
@@ -1245,6 +1237,8 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
++tx_queue->tso_packets;
+ ++tx_queue->tx_packets;
+
return 0;
}
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 6072f093e6b4..7bea17c41dc9 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -2258,7 +2258,6 @@ static int sis900_set_config(struct net_device *dev, struct ifmap *map)
case IF_PORT_100BASEFX: /* 100BaseFx */
/* These Modes are not supported (are they?)*/
return -EOPNOTSUPP;
- break;
default:
return -EINVAL;
diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index 1c44e67c3067..9778cba9fc74 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -730,7 +730,7 @@ static void smc911x_phy_detect(struct net_device *dev)
lp->phy_type = id1 << 16 | id2;
}
- DBG(SMC_DEBUG_MISC, dev, "phy_id1=0x%x, phy_id2=0x%x phyaddr=0x%d\n",
+ DBG(SMC_DEBUG_MISC, dev, "phy_id1=0x%x, phy_id2=0x%x phyaddr=0x%x\n",
id1, id2, lp->mii.phy_id);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 74610f3aca9e..de507c32036c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -368,34 +368,36 @@ struct stmmac_dma_ops {
void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt);
};
+struct mac_device_info;
+
struct stmmac_ops {
/* MAC core initialization */
- void (*core_init) (void __iomem *ioaddr, int mtu);
+ void (*core_init)(struct mac_device_info *hw, int mtu);
/* Enable and verify that the IPC module is supported */
- int (*rx_ipc) (void __iomem *ioaddr);
+ int (*rx_ipc)(struct mac_device_info *hw);
/* Dump MAC registers */
- void (*dump_regs) (void __iomem *ioaddr);
+ void (*dump_regs)(struct mac_device_info *hw);
/* Handle extra events on specific interrupts hw dependent */
- int (*host_irq_status) (void __iomem *ioaddr,
- struct stmmac_extra_stats *x);
+ int (*host_irq_status)(struct mac_device_info *hw,
+ struct stmmac_extra_stats *x);
/* Multicast filter setting */
- void (*set_filter) (struct net_device *dev, int id);
+ void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
/* Flow control setting */
- void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
- unsigned int fc, unsigned int pause_time);
+ void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
+ unsigned int fc, unsigned int pause_time);
/* Set power management mode (e.g. magic frame) */
- void (*pmt) (void __iomem *ioaddr, unsigned long mode);
+ void (*pmt)(struct mac_device_info *hw, unsigned long mode);
/* Set/Get Unicast MAC addresses */
- void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
- unsigned int reg_n);
- void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
- unsigned int reg_n);
- void (*set_eee_mode) (void __iomem *ioaddr);
- void (*reset_eee_mode) (void __iomem *ioaddr);
- void (*set_eee_timer) (void __iomem *ioaddr, int ls, int tw);
- void (*set_eee_pls) (void __iomem *ioaddr, int link);
- void (*ctrl_ane) (void __iomem *ioaddr, bool restart);
- void (*get_adv) (void __iomem *ioaddr, struct rgmii_adv *adv);
+ void (*set_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
+ unsigned int reg_n);
+ void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
+ unsigned int reg_n);
+ void (*set_eee_mode)(struct mac_device_info *hw);
+ void (*reset_eee_mode)(struct mac_device_info *hw);
+ void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
+ void (*set_eee_pls)(struct mac_device_info *hw, int link);
+ void (*ctrl_ane)(struct mac_device_info *hw, bool restart);
+ void (*get_adv)(struct mac_device_info *hw, struct rgmii_adv *adv);
};
struct stmmac_hwtimestamp {
@@ -439,9 +441,14 @@ struct mac_device_info {
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
unsigned int synopsys_uid;
+ void __iomem *pcsr; /* vpointer to device CSRs */
+ int multicast_filter_bins;
+ int unicast_filter_entries;
+ int mcast_bits_log2;
};
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
+ int perfect_uc_entries);
struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index fd8a217556a1..ec632e666c56 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -20,7 +20,9 @@
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/stmmac.h>
+#include "stmmac.h"
#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
@@ -34,6 +36,7 @@ struct socfpga_dwmac {
u32 reg_shift;
struct device *dev;
struct regmap *sys_mgr_base_addr;
+ struct reset_control *stmmac_rst;
};
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
@@ -43,6 +46,13 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
u32 reg_offset, reg_shift;
int ret;
+ dwmac->stmmac_rst = devm_reset_control_get(dev,
+ STMMAC_RESOURCE_NAME);
+ if (IS_ERR(dwmac->stmmac_rst)) {
+ dev_info(dev, "Could not get reset control!\n");
+ return -EINVAL;
+ }
+
dwmac->interface = of_get_phy_mode(np);
sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
@@ -125,6 +135,65 @@ static void *socfpga_dwmac_probe(struct platform_device *pdev)
return dwmac;
}
+static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
+{
+ struct socfpga_dwmac *dwmac = priv;
+
+ /* On socfpga platform exit, assert and hold reset to the
+ * enet controller - the default state after a hard reset.
+ */
+ if (dwmac->stmmac_rst)
+ reset_control_assert(dwmac->stmmac_rst);
+}
+
+static int socfpga_dwmac_init(struct platform_device *pdev, void *priv)
+{
+ struct socfpga_dwmac *dwmac = priv;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct stmmac_priv *stpriv = NULL;
+ int ret = 0;
+
+ if (ndev)
+ stpriv = netdev_priv(ndev);
+
+ /* Assert reset to the enet controller before changing the phy mode */
+ if (dwmac->stmmac_rst)
+ reset_control_assert(dwmac->stmmac_rst);
+
+ /* Setup the phy mode in the system manager registers according to
+ * devicetree configuration
+ */
+ ret = socfpga_dwmac_setup(dwmac);
+
+ /* Deassert reset for the phy configuration to be sampled by
+ * the enet controller, and operation to start in requested mode
+ */
+ if (dwmac->stmmac_rst)
+ reset_control_deassert(dwmac->stmmac_rst);
+
+ /* Before the enet controller is suspended, the phy is suspended.
+ * This causes the phy clock to be gated. The enet controller is
+ * resumed before the phy, so the clock is still gated "off" when
+ * the enet controller is resumed. This code makes sure the phy
+ * is "resumed" before reinitializing the enet controller since
+ * the enet controller depends on an active phy clock to complete
+ * a DMA reset. A DMA reset will "time out" if executed
+ * with no phy clock input on the Synopsys enet controller.
+ * Verified through Synopsys Case #8000711656.
+ *
+ * Note that the phy clock is also gated when the phy is isolated.
+ * Phy "suspend" and "isolate" controls are located in phy basic
+ * control register 0, and can be modified by the phy driver
+ * framework.
+ */
+ if (stpriv && stpriv->phydev)
+ phy_resume(stpriv->phydev);
+
+ return ret;
+}
+
const struct stmmac_of_data socfpga_gmac_data = {
.setup = socfpga_dwmac_probe,
+ .init = socfpga_dwmac_init,
+ .exit = socfpga_dwmac_exit,
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index f37d90f114f5..71b5419256c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -87,7 +87,7 @@ enum power_event {
(reg * 8))
#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \
(reg * 8))
-#define GMAC_MAX_PERFECT_ADDRESSES 32
+#define GMAC_MAX_PERFECT_ADDRESSES 1
/* PCS registers (AN/TBI/SGMII/RGMII) offset */
#define GMAC_AN_CTRL 0x000000c0 /* AN control */
@@ -261,6 +261,7 @@ enum rtc_control {
#define GMAC_MMC_RX_INTR 0x104
#define GMAC_MMC_TX_INTR 0x108
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
+#define GMAC_EXTHASH_BASE 0x500
extern const struct stmmac_dma_ops dwmac1000_dma_ops;
#endif /* __DWMAC1000_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index b3e148ef5683..d8ef18786a1c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -32,8 +32,9 @@
#include <asm/io.h>
#include "dwmac1000.h"
-static void dwmac1000_core_init(void __iomem *ioaddr, int mtu)
+static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + GMAC_CONTROL);
value |= GMAC_CORE_INIT;
if (mtu > 1500)
@@ -52,8 +53,9 @@ static void dwmac1000_core_init(void __iomem *ioaddr, int mtu)
#endif
}
-static int dwmac1000_rx_ipc_enable(void __iomem *ioaddr)
+static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + GMAC_CONTROL);
value |= GMAC_CONTROL_IPC;
@@ -64,8 +66,9 @@ static int dwmac1000_rx_ipc_enable(void __iomem *ioaddr)
return !!(value & GMAC_CONTROL_IPC);
}
-static void dwmac1000_dump_regs(void __iomem *ioaddr)
+static void dwmac1000_dump_regs(struct mac_device_info *hw)
{
+ void __iomem *ioaddr = hw->pcsr;
int i;
pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
@@ -76,69 +79,98 @@ static void dwmac1000_dump_regs(void __iomem *ioaddr)
}
}
-static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
+ unsigned char *addr,
unsigned int reg_n)
{
+ void __iomem *ioaddr = hw->pcsr;
stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
GMAC_ADDR_LOW(reg_n));
}
-static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
+ unsigned char *addr,
unsigned int reg_n)
{
+ void __iomem *ioaddr = hw->pcsr;
stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
GMAC_ADDR_LOW(reg_n));
}
-static void dwmac1000_set_filter(struct net_device *dev, int id)
+static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
+ int mcbitslog2)
+{
+ int numhashregs, regs;
+
+ switch (mcbitslog2) {
+ case 6:
+ writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
+ writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
+ return;
+ break;
+ case 7:
+ numhashregs = 4;
+ break;
+ case 8:
+ numhashregs = 8;
+ break;
+ default:
+ pr_debug("STMMAC: err in setting mulitcast filter\n");
+ return;
+ break;
+ }
+ for (regs = 0; regs < numhashregs; regs++)
+ writel(mcfilterbits[regs],
+ ioaddr + GMAC_EXTHASH_BASE + regs * 4);
+}
+
+static void dwmac1000_set_filter(struct mac_device_info *hw,
+ struct net_device *dev)
{
void __iomem *ioaddr = (void __iomem *)dev->base_addr;
unsigned int value = 0;
- unsigned int perfect_addr_number;
+ unsigned int perfect_addr_number = hw->unicast_filter_entries;
+ u32 mc_filter[2];
+ int mcbitslog2 = hw->mcast_bits_log2;
pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
netdev_mc_count(dev), netdev_uc_count(dev));
- if (dev->flags & IFF_PROMISC)
+ memset(mc_filter, 0, sizeof(mc_filter));
+
+ if (dev->flags & IFF_PROMISC) {
value = GMAC_FRAME_FILTER_PR;
- else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
- || (dev->flags & IFF_ALLMULTI)) {
+ } else if (dev->flags & IFF_ALLMULTI) {
value = GMAC_FRAME_FILTER_PM; /* pass all multi */
- writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
- writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
} else if (!netdev_mc_empty(dev)) {
- u32 mc_filter[2];
struct netdev_hw_addr *ha;
/* Hash filter for multicast */
value = GMAC_FRAME_FILTER_HMC;
- memset(mc_filter, 0, sizeof(mc_filter));
netdev_for_each_mc_addr(ha, dev) {
- /* The upper 6 bits of the calculated CRC are used to
- * index the contens of the hash table
+ /* The upper n bits of the calculated CRC are used to
+ * index the contents of the hash table. The number of
+ * bits used depends on the hardware configuration
+ * selected at core configuration time.
*/
- int bit_nr = bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
+ int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
+ ETH_ALEN)) >>
+ (32 - mcbitslog2);
/* The most significant bit determines the register to
* use (H/L) while the other 5 bits determine the bit
* within the register.
*/
mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
}
- writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
- writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
}
- /* Extra 16 regs are available in cores newer than the 3.40. */
- if (id > DWMAC_CORE_3_40)
- perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES;
- else
- perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES / 2;
+ dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
/* Handle multiple unicast addresses (perfect filtering) */
if (netdev_uc_count(dev) > perfect_addr_number)
- /* Switch to promiscuous mode if more than 16 addrs
- * are required
+ /* Switch to promiscuous mode if more than unicast
+ * addresses are requested than supported by hardware.
*/
value |= GMAC_FRAME_FILTER_PR;
else {
@@ -146,7 +178,9 @@ static void dwmac1000_set_filter(struct net_device *dev, int id)
struct netdev_hw_addr *ha;
netdev_for_each_uc_addr(ha, dev) {
- dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
+ stmmac_get_mac_addr(ioaddr, ha->addr,
+ GMAC_ADDR_HIGH(reg),
+ GMAC_ADDR_LOW(reg));
reg++;
}
}
@@ -156,15 +190,13 @@ static void dwmac1000_set_filter(struct net_device *dev, int id)
value |= GMAC_FRAME_FILTER_RA;
#endif
writel(value, ioaddr + GMAC_FRAME_FILTER);
-
- pr_debug("\tFilter: 0x%08x\n\tHash: HI 0x%08x, LO 0x%08x\n",
- readl(ioaddr + GMAC_FRAME_FILTER),
- readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
}
-static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
+
+static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
+ void __iomem *ioaddr = hw->pcsr;
unsigned int flow = 0;
pr_debug("GMAC Flow-Control:\n");
@@ -185,8 +217,9 @@ static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
writel(flow, ioaddr + GMAC_FLOW_CTRL);
}
-static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
+static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
{
+ void __iomem *ioaddr = hw->pcsr;
unsigned int pmt = 0;
if (mode & WAKE_MAGIC) {
@@ -201,9 +234,10 @@ static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
writel(pmt, ioaddr + GMAC_PMT);
}
-static int dwmac1000_irq_status(void __iomem *ioaddr,
+static int dwmac1000_irq_status(struct mac_device_info *hw,
struct stmmac_extra_stats *x)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
int ret = 0;
@@ -268,8 +302,9 @@ static int dwmac1000_irq_status(void __iomem *ioaddr,
return ret;
}
-static void dwmac1000_set_eee_mode(void __iomem *ioaddr)
+static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value;
/* Enable the link status receive on RGMII, SGMII ore SMII
@@ -281,8 +316,9 @@ static void dwmac1000_set_eee_mode(void __iomem *ioaddr)
writel(value, ioaddr + LPI_CTRL_STATUS);
}
-static void dwmac1000_reset_eee_mode(void __iomem *ioaddr)
+static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value;
value = readl(ioaddr + LPI_CTRL_STATUS);
@@ -290,8 +326,9 @@ static void dwmac1000_reset_eee_mode(void __iomem *ioaddr)
writel(value, ioaddr + LPI_CTRL_STATUS);
}
-static void dwmac1000_set_eee_pls(void __iomem *ioaddr, int link)
+static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value;
value = readl(ioaddr + LPI_CTRL_STATUS);
@@ -304,8 +341,9 @@ static void dwmac1000_set_eee_pls(void __iomem *ioaddr, int link)
writel(value, ioaddr + LPI_CTRL_STATUS);
}
-static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw)
+static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
{
+ void __iomem *ioaddr = hw->pcsr;
int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
/* Program the timers in the LPI timer control register:
@@ -318,13 +356,11 @@ static void dwmac1000_set_eee_timer(void __iomem *ioaddr, int ls, int tw)
writel(value, ioaddr + LPI_TIMER_CTRL);
}
-static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart)
+static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
{
- u32 value;
-
- value = readl(ioaddr + GMAC_AN_CTRL);
+ void __iomem *ioaddr = hw->pcsr;
/* auto negotiation enable and External Loopback enable */
- value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
+ u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
if (restart)
value |= GMAC_AN_CTRL_RAN;
@@ -332,8 +368,9 @@ static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart)
writel(value, ioaddr + GMAC_AN_CTRL);
}
-static void dwmac1000_get_adv(void __iomem *ioaddr, struct rgmii_adv *adv)
+static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + GMAC_ANE_ADV);
if (value & GMAC_ANE_FD)
@@ -371,7 +408,8 @@ static const struct stmmac_ops dwmac1000_ops = {
.get_adv = dwmac1000_get_adv,
};
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
+ int perfect_uc_entries)
{
struct mac_device_info *mac;
u32 hwid = readl(ioaddr + GMAC_VERSION);
@@ -380,6 +418,14 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
if (!mac)
return NULL;
+ mac->pcsr = ioaddr;
+ mac->multicast_filter_bins = mcbins;
+ mac->unicast_filter_entries = perfect_uc_entries;
+ mac->mcast_bits_log2 = 0;
+
+ if (mac->multicast_filter_bins)
+ mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
mac->mac = &dwmac1000_ops;
mac->dma = &dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index 2ff767bcfdd0..f8dd773f246c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -32,8 +32,9 @@
#include <asm/io.h>
#include "dwmac100.h"
-static void dwmac100_core_init(void __iomem *ioaddr, int mtu)
+static void dwmac100_core_init(struct mac_device_info *hw, int mtu)
{
+ void __iomem *ioaddr = hw->pcsr;
u32 value = readl(ioaddr + MAC_CONTROL);
writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
@@ -43,8 +44,9 @@ static void dwmac100_core_init(void __iomem *ioaddr, int mtu)
#endif
}
-static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
+static void dwmac100_dump_mac_regs(struct mac_device_info *hw)
{
+ void __iomem *ioaddr = hw->pcsr;
pr_info("\t----------------------------------------------\n"
"\t DWMAC 100 CSR (base addr = 0x%p)\n"
"\t----------------------------------------------\n", ioaddr);
@@ -66,30 +68,35 @@ static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
readl(ioaddr + MAC_VLAN2));
}
-static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
+static int dwmac100_rx_ipc_enable(struct mac_device_info *hw)
{
return 0;
}
-static int dwmac100_irq_status(void __iomem *ioaddr,
+static int dwmac100_irq_status(struct mac_device_info *hw,
struct stmmac_extra_stats *x)
{
return 0;
}
-static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+static void dwmac100_set_umac_addr(struct mac_device_info *hw,
+ unsigned char *addr,
unsigned int reg_n)
{
+ void __iomem *ioaddr = hw->pcsr;
stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
}
-static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+static void dwmac100_get_umac_addr(struct mac_device_info *hw,
+ unsigned char *addr,
unsigned int reg_n)
{
+ void __iomem *ioaddr = hw->pcsr;
stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
}
-static void dwmac100_set_filter(struct net_device *dev, int id)
+static void dwmac100_set_filter(struct mac_device_info *hw,
+ struct net_device *dev)
{
void __iomem *ioaddr = (void __iomem *)dev->base_addr;
u32 value = readl(ioaddr + MAC_CONTROL);
@@ -137,9 +144,10 @@ static void dwmac100_set_filter(struct net_device *dev, int id)
writel(value, ioaddr + MAC_CONTROL);
}
-static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
+static void dwmac100_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time)
{
+ void __iomem *ioaddr = hw->pcsr;
unsigned int flow = MAC_FLOW_CTRL_ENABLE;
if (duplex)
@@ -148,7 +156,7 @@ static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
}
/* No PMT module supported on ST boards with this Eth chip. */
-static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
+static void dwmac100_pmt(struct mac_device_info *hw, unsigned long mode)
{
return;
}
@@ -175,6 +183,7 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
pr_info("\tDWMAC100\n");
+ mac->pcsr = ioaddr;
mac->mac = &dwmac100_ops;
mac->dma = &dwmac100_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index 7e6628a91514..1e2bcf5f89e1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -145,7 +145,7 @@ static void enh_desc_get_ext_status(void *data, struct stmmac_extra_stats *x,
x->rx_msg_type_delay_req++;
else if (p->des4.erx.msg_type == RDES_EXT_DELAY_RESP)
x->rx_msg_type_delay_resp++;
- else if (p->des4.erx.msg_type == RDES_EXT_DELAY_REQ)
+ else if (p->des4.erx.msg_type == RDES_EXT_PDELAY_REQ)
x->rx_msg_type_pdelay_req++;
else if (p->des4.erx.msg_type == RDES_EXT_PDELAY_RESP)
x->rx_msg_type_pdelay_resp++;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index c62e67f3c2f0..9af50bae4dde 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -262,7 +262,7 @@ static int stmmac_ethtool_getsettings(struct net_device *dev,
/* Get and convert ADV/LP_ADV from the HW AN registers */
if (priv->hw->mac->get_adv)
- priv->hw->mac->get_adv(priv->ioaddr, &adv);
+ priv->hw->mac->get_adv(priv->hw, &adv);
else
return -EOPNOTSUPP; /* should never happen indeed */
@@ -350,7 +350,7 @@ static int stmmac_ethtool_setsettings(struct net_device *dev,
spin_lock(&priv->lock);
if (priv->hw->mac->ctrl_ane)
- priv->hw->mac->ctrl_ane(priv->ioaddr, 1);
+ priv->hw->mac->ctrl_ane(priv->hw, 1);
spin_unlock(&priv->lock);
}
@@ -464,7 +464,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
if (netif_running(netdev))
ret = phy_start_aneg(phy);
} else
- priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
+ priv->hw->mac->flow_ctrl(priv->hw, phy->duplex,
priv->flow_ctrl, priv->pause);
return ret;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 057a1208e594..08addd653728 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -233,7 +233,7 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
/* Check and enter in LPI mode */
if ((priv->dirty_tx == priv->cur_tx) &&
(priv->tx_path_in_lpi_mode == false))
- priv->hw->mac->set_eee_mode(priv->ioaddr);
+ priv->hw->mac->set_eee_mode(priv->hw);
}
/**
@@ -244,7 +244,7 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
*/
void stmmac_disable_eee_mode(struct stmmac_priv *priv)
{
- priv->hw->mac->reset_eee_mode(priv->ioaddr);
+ priv->hw->mac->reset_eee_mode(priv->hw);
del_timer_sync(&priv->eee_ctrl_timer);
priv->tx_path_in_lpi_mode = false;
}
@@ -298,7 +298,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
if (priv->eee_active) {
pr_debug("stmmac: disable EEE\n");
del_timer_sync(&priv->eee_ctrl_timer);
- priv->hw->mac->set_eee_timer(priv->ioaddr, 0,
+ priv->hw->mac->set_eee_timer(priv->hw, 0,
tx_lpi_timer);
}
priv->eee_active = 0;
@@ -313,12 +313,12 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer);
add_timer(&priv->eee_ctrl_timer);
- priv->hw->mac->set_eee_timer(priv->ioaddr,
+ priv->hw->mac->set_eee_timer(priv->hw,
STMMAC_DEFAULT_LIT_LS,
tx_lpi_timer);
} else
/* Set HW EEE according to the speed */
- priv->hw->mac->set_eee_pls(priv->ioaddr,
+ priv->hw->mac->set_eee_pls(priv->hw,
priv->phydev->link);
pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
@@ -693,7 +693,7 @@ static void stmmac_adjust_link(struct net_device *dev)
}
/* Flow Control operation */
if (phydev->pause)
- priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
+ priv->hw->mac->flow_ctrl(priv->hw, phydev->duplex,
fc, pause_time);
if (phydev->speed != priv->speed) {
@@ -1531,8 +1531,7 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
static void stmmac_check_ether_addr(struct stmmac_priv *priv)
{
if (!is_valid_ether_addr(priv->dev->dev_addr)) {
- priv->hw->mac->get_umac_addr((void __iomem *)
- priv->dev->base_addr,
+ priv->hw->mac->get_umac_addr(priv->hw,
priv->dev->dev_addr, 0);
if (!is_valid_ether_addr(priv->dev->dev_addr))
eth_hw_addr_random(priv->dev);
@@ -1629,14 +1628,14 @@ static int stmmac_hw_setup(struct net_device *dev)
}
/* Copy the MAC addr into the HW */
- priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+ priv->hw->mac->set_umac_addr(priv->hw, dev->dev_addr, 0);
/* If required, perform hw setup of the bus. */
if (priv->plat->bus_setup)
priv->plat->bus_setup(priv->ioaddr);
/* Initialize the MAC Core */
- priv->hw->mac->core_init(priv->ioaddr, dev->mtu);
+ priv->hw->mac->core_init(priv->hw, dev->mtu);
/* Enable the MAC Rx/Tx */
stmmac_set_mac(priv->ioaddr, true);
@@ -1662,7 +1661,7 @@ static int stmmac_hw_setup(struct net_device *dev)
/* Dump DMA/MAC registers */
if (netif_msg_hw(priv)) {
- priv->hw->mac->dump_regs(priv->ioaddr);
+ priv->hw->mac->dump_regs(priv->hw);
priv->hw->dma->dump_regs(priv->ioaddr);
}
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
@@ -1677,7 +1676,7 @@ static int stmmac_hw_setup(struct net_device *dev)
}
if (priv->pcs && priv->hw->mac->ctrl_ane)
- priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
+ priv->hw->mac->ctrl_ane(priv->hw, 0);
return 0;
}
@@ -2226,7 +2225,7 @@ static void stmmac_set_rx_mode(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
spin_lock(&priv->lock);
- priv->hw->mac->set_filter(dev, priv->synopsys_id);
+ priv->hw->mac->set_filter(priv->hw, dev);
spin_unlock(&priv->lock);
}
@@ -2316,8 +2315,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
/* To handle GMAC own interrupts */
if (priv->plat->has_gmac) {
- int status = priv->hw->mac->host_irq_status((void __iomem *)
- dev->base_addr,
+ int status = priv->hw->mac->host_irq_status(priv->hw,
&priv->xstats);
if (unlikely(status)) {
/* For LPI we need to save the tx status */
@@ -2600,7 +2598,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
/* Identify the MAC HW device */
if (priv->plat->has_gmac) {
priv->dev->priv_flags |= IFF_UNICAST_FLT;
- mac = dwmac1000_setup(priv->ioaddr);
+ mac = dwmac1000_setup(priv->ioaddr,
+ priv->plat->multicast_filter_bins,
+ priv->plat->unicast_filter_entries);
} else {
mac = dwmac100_setup(priv->ioaddr);
}
@@ -2649,7 +2649,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
/* To use alternate (extended) or normal descriptor structures */
stmmac_selec_desc_mode(priv);
- ret = priv->hw->mac->rx_ipc(priv->ioaddr);
+ ret = priv->hw->mac->rx_ipc(priv->hw);
if (!ret) {
pr_warn(" RX IPC Checksum Offload not configured.\n");
priv->plat->rx_coe = STMMAC_RX_COE_NONE;
@@ -2869,7 +2869,7 @@ int stmmac_suspend(struct net_device *ndev)
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device)) {
- priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
+ priv->hw->mac->pmt(priv->hw, priv->wolopts);
priv->irq_wake = 1;
} else {
stmmac_set_mac(priv->ioaddr, false);
@@ -2878,6 +2878,10 @@ int stmmac_suspend(struct net_device *ndev)
clk_disable_unprepare(priv->stmmac_clk);
}
spin_unlock_irqrestore(&priv->lock, flags);
+
+ priv->oldlink = 0;
+ priv->speed = 0;
+ priv->oldduplex = -1;
return 0;
}
@@ -2898,7 +2902,7 @@ int stmmac_resume(struct net_device *ndev)
* from another devices (e.g. serial console).
*/
if (device_may_wakeup(priv->device)) {
- priv->hw->mac->pmt(priv->ioaddr, 0);
+ priv->hw->mac->pmt(priv->hw, 0);
priv->irq_wake = 0;
} else {
pinctrl_pm_select_default_state(priv->device);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index ea7a65be1f9a..bb524a932be4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -52,6 +52,59 @@ static const struct of_device_id stmmac_dt_ids[] = {
MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
#ifdef CONFIG_OF
+
+/* This function validates the number of Multicast filtering bins specified
+ * by the configuration through the device tree. The Synopsys GMAC supports
+ * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
+ * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
+ * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
+ * invalid and will cause the filtering algorithm to use Multicast
+ * promiscuous mode.
+ */
+static int dwmac1000_validate_mcast_bins(int mcast_bins)
+{
+ int x = mcast_bins;
+
+ switch (x) {
+ case HASH_TABLE_SIZE:
+ case 128:
+ case 256:
+ break;
+ default:
+ x = 0;
+ pr_info("Hash table entries set to unexpected value %d",
+ mcast_bins);
+ break;
+ }
+ return x;
+}
+
+/* This function validates the number of Unicast address entries supported
+ * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
+ * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
+ * logic. This function validates a valid, supported configuration is
+ * selected, and defaults to 1 Unicast address if an unsupported
+ * configuration is selected.
+ */
+static int dwmac1000_validate_ucast_entries(int ucast_entries)
+{
+ int x = ucast_entries;
+
+ switch (x) {
+ case 1:
+ case 32:
+ case 64:
+ case 128:
+ break;
+ default:
+ x = 1;
+ pr_info("Unicast table entries set to unexpected value %d\n",
+ ucast_entries);
+ break;
+ }
+ return x;
+}
+
static int stmmac_probe_config_dt(struct platform_device *pdev,
struct plat_stmmacenet_data *plat,
const char **mac)
@@ -115,6 +168,12 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
*/
plat->maxmtu = JUMBO_LEN;
+ /* Set default value for multicast hash bins */
+ plat->multicast_filter_bins = HASH_TABLE_SIZE;
+
+ /* Set default value for unicast filter entries */
+ plat->unicast_filter_entries = 1;
+
/*
* Currently only the properties needed on SPEAr600
* are provided. All other properties should be added
@@ -131,6 +190,14 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
* are clearly MTUs
*/
of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
+ of_property_read_u32(np, "snps,multicast-filter-bins",
+ &plat->multicast_filter_bins);
+ of_property_read_u32(np, "snps,perfect-filter-entries",
+ &plat->unicast_filter_entries);
+ plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
+ plat->unicast_filter_entries);
+ plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
+ plat->multicast_filter_bins);
plat->has_gmac = 1;
plat->pmt = 1;
}
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 79606f47a08e..db8ffde491b5 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -2584,7 +2584,6 @@ static int niu_determine_phy_disposition(struct niu *np)
break;
default:
return -EINVAL;
- break;
}
phy_addr_off = niu_atca_port_num[np->port];
break;
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 1c24a8f368bd..d813bfb1a847 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -610,6 +610,13 @@ static int __vnet_tx_trigger(struct vnet_port *port)
return err;
}
+static inline bool port_is_up(struct vnet_port *vnet)
+{
+ struct vio_driver_state *vio = &vnet->vio;
+
+ return !!(vio->hs_state & VIO_HS_COMPLETE);
+}
+
struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb)
{
unsigned int hash = vnet_hashfn(skb->data);
@@ -617,14 +624,19 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb)
struct vnet_port *port;
hlist_for_each_entry(port, hp, hash) {
+ if (!port_is_up(port))
+ continue;
if (ether_addr_equal(port->raddr, skb->data))
return port;
}
- port = NULL;
- if (!list_empty(&vp->port_list))
- port = list_entry(vp->port_list.next, struct vnet_port, list);
-
- return port;
+ list_for_each_entry(port, &vp->port_list, list) {
+ if (!port->switch_port)
+ continue;
+ if (!port_is_up(port))
+ continue;
+ return port;
+ }
+ return NULL;
}
struct vnet_port *tx_port_find(struct vnet *vp, struct sk_buff *skb)
@@ -1083,6 +1095,24 @@ static struct vnet *vnet_find_or_create(const u64 *local_mac)
return vp;
}
+static void vnet_cleanup(void)
+{
+ struct vnet *vp;
+ struct net_device *dev;
+
+ mutex_lock(&vnet_list_mutex);
+ while (!list_empty(&vnet_list)) {
+ vp = list_first_entry(&vnet_list, struct vnet, list);
+ list_del(&vp->list);
+ dev = vp->dev;
+ /* vio_unregister_driver() should have cleaned up port_list */
+ BUG_ON(!list_empty(&vp->port_list));
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ mutex_unlock(&vnet_list_mutex);
+}
+
static const char *local_mac_prop = "local-mac-address";
static struct vnet *vnet_find_parent(struct mdesc_handle *hp,
@@ -1240,7 +1270,6 @@ static int vnet_port_remove(struct vio_dev *vdev)
kfree(port);
- unregister_netdev(vp->dev);
}
return 0;
}
@@ -1268,6 +1297,7 @@ static int __init vnet_init(void)
static void __exit vnet_exit(void)
{
vio_unregister_driver(&vnet_port_driver);
+ vnet_cleanup();
}
module_init(vnet_init);
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index 53150c25a96b..1769700a6070 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_TI
bool "Texas Instruments (TI) devices"
default y
- depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX))
+ depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX || ARCH_KEYSTONE))
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -32,7 +32,7 @@ config TI_DAVINCI_EMAC
config TI_DAVINCI_MDIO
tristate "TI DaVinci MDIO Support"
- depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX )
+ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX || ARCH_KEYSTONE )
select PHYLIB
---help---
This driver supports TI's DaVinci MDIO module.
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 7399a52f7c26..3809f4ec2820 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -67,42 +67,42 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_RX_CONTROL 0x0014
#define CPMAC_RX_TEARDOWN 0x0018
#define CPMAC_MBP 0x0100
-# define MBP_RXPASSCRC 0x40000000
-# define MBP_RXQOS 0x20000000
-# define MBP_RXNOCHAIN 0x10000000
-# define MBP_RXCMF 0x01000000
-# define MBP_RXSHORT 0x00800000
-# define MBP_RXCEF 0x00400000
-# define MBP_RXPROMISC 0x00200000
-# define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16)
-# define MBP_RXBCAST 0x00002000
-# define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8)
-# define MBP_RXMCAST 0x00000020
-# define MBP_MCASTCHAN(channel) ((channel) & 0x7)
+#define MBP_RXPASSCRC 0x40000000
+#define MBP_RXQOS 0x20000000
+#define MBP_RXNOCHAIN 0x10000000
+#define MBP_RXCMF 0x01000000
+#define MBP_RXSHORT 0x00800000
+#define MBP_RXCEF 0x00400000
+#define MBP_RXPROMISC 0x00200000
+#define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16)
+#define MBP_RXBCAST 0x00002000
+#define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8)
+#define MBP_RXMCAST 0x00000020
+#define MBP_MCASTCHAN(channel) ((channel) & 0x7)
#define CPMAC_UNICAST_ENABLE 0x0104
#define CPMAC_UNICAST_CLEAR 0x0108
#define CPMAC_MAX_LENGTH 0x010c
#define CPMAC_BUFFER_OFFSET 0x0110
#define CPMAC_MAC_CONTROL 0x0160
-# define MAC_TXPTYPE 0x00000200
-# define MAC_TXPACE 0x00000040
-# define MAC_MII 0x00000020
-# define MAC_TXFLOW 0x00000010
-# define MAC_RXFLOW 0x00000008
-# define MAC_MTEST 0x00000004
-# define MAC_LOOPBACK 0x00000002
-# define MAC_FDX 0x00000001
+#define MAC_TXPTYPE 0x00000200
+#define MAC_TXPACE 0x00000040
+#define MAC_MII 0x00000020
+#define MAC_TXFLOW 0x00000010
+#define MAC_RXFLOW 0x00000008
+#define MAC_MTEST 0x00000004
+#define MAC_LOOPBACK 0x00000002
+#define MAC_FDX 0x00000001
#define CPMAC_MAC_STATUS 0x0164
-# define MAC_STATUS_QOS 0x00000004
-# define MAC_STATUS_RXFLOW 0x00000002
-# define MAC_STATUS_TXFLOW 0x00000001
+#define MAC_STATUS_QOS 0x00000004
+#define MAC_STATUS_RXFLOW 0x00000002
+#define MAC_STATUS_TXFLOW 0x00000001
#define CPMAC_TX_INT_ENABLE 0x0178
#define CPMAC_TX_INT_CLEAR 0x017c
#define CPMAC_MAC_INT_VECTOR 0x0180
-# define MAC_INT_STATUS 0x00080000
-# define MAC_INT_HOST 0x00040000
-# define MAC_INT_RX 0x00020000
-# define MAC_INT_TX 0x00010000
+#define MAC_INT_STATUS 0x00080000
+#define MAC_INT_HOST 0x00040000
+#define MAC_INT_RX 0x00020000
+#define MAC_INT_TX 0x00010000
#define CPMAC_MAC_EOI_VECTOR 0x0184
#define CPMAC_RX_INT_ENABLE 0x0198
#define CPMAC_RX_INT_CLEAR 0x019c
@@ -118,8 +118,8 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
#define CPMAC_TX_ACK(channel) (0x0640 + (channel) * 4)
#define CPMAC_RX_ACK(channel) (0x0660 + (channel) * 4)
#define CPMAC_REG_END 0x0680
-/*
- * Rx/Tx statistics
+
+/* Rx/Tx statistics
* TODO: use some of them to fill stats in cpmac_stats()
*/
#define CPMAC_STATS_RX_GOOD 0x0200
@@ -157,24 +157,24 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
/* MDIO bus */
#define CPMAC_MDIO_VERSION 0x0000
#define CPMAC_MDIO_CONTROL 0x0004
-# define MDIOC_IDLE 0x80000000
-# define MDIOC_ENABLE 0x40000000
-# define MDIOC_PREAMBLE 0x00100000
-# define MDIOC_FAULT 0x00080000
-# define MDIOC_FAULTDETECT 0x00040000
-# define MDIOC_INTTEST 0x00020000
-# define MDIOC_CLKDIV(div) ((div) & 0xff)
+#define MDIOC_IDLE 0x80000000
+#define MDIOC_ENABLE 0x40000000
+#define MDIOC_PREAMBLE 0x00100000
+#define MDIOC_FAULT 0x00080000
+#define MDIOC_FAULTDETECT 0x00040000
+#define MDIOC_INTTEST 0x00020000
+#define MDIOC_CLKDIV(div) ((div) & 0xff)
#define CPMAC_MDIO_ALIVE 0x0008
#define CPMAC_MDIO_LINK 0x000c
#define CPMAC_MDIO_ACCESS(channel) (0x0080 + (channel) * 8)
-# define MDIO_BUSY 0x80000000
-# define MDIO_WRITE 0x40000000
-# define MDIO_REG(reg) (((reg) & 0x1f) << 21)
-# define MDIO_PHY(phy) (((phy) & 0x1f) << 16)
-# define MDIO_DATA(data) ((data) & 0xffff)
+#define MDIO_BUSY 0x80000000
+#define MDIO_WRITE 0x40000000
+#define MDIO_REG(reg) (((reg) & 0x1f) << 21)
+#define MDIO_PHY(phy) (((phy) & 0x1f) << 16)
+#define MDIO_DATA(data) ((data) & 0xffff)
#define CPMAC_MDIO_PHYSEL(channel) (0x0084 + (channel) * 8)
-# define PHYSEL_LINKSEL 0x00000040
-# define PHYSEL_LINKINT 0x00000020
+#define PHYSEL_LINKSEL 0x00000040
+#define PHYSEL_LINKINT 0x00000020
struct cpmac_desc {
u32 hw_next;
@@ -224,12 +224,12 @@ static void cpmac_dump_regs(struct net_device *dev)
{
int i;
struct cpmac_priv *priv = netdev_priv(dev);
+
for (i = 0; i < CPMAC_REG_END; i += 4) {
if (i % 16 == 0) {
if (i)
- pr_cont("\n");
- printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
- priv->regs + i);
+ printk("\n");
+ printk("%s: reg[%p]:", dev->name, priv->regs + i);
}
printk(" %08x", cpmac_read(priv->regs, i));
}
@@ -239,7 +239,8 @@ static void cpmac_dump_regs(struct net_device *dev)
static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc)
{
int i;
- printk(KERN_DEBUG "%s: desc[%p]:", dev->name, desc);
+
+ printk("%s: desc[%p]:", dev->name, desc);
for (i = 0; i < sizeof(*desc) / 4; i++)
printk(" %08x", ((u32 *)desc)[i]);
printk("\n");
@@ -249,6 +250,7 @@ static void cpmac_dump_all_desc(struct net_device *dev)
{
struct cpmac_priv *priv = netdev_priv(dev);
struct cpmac_desc *dump = priv->rx_head;
+
do {
cpmac_dump_desc(dev, dump);
dump = dump->next;
@@ -258,13 +260,13 @@ static void cpmac_dump_all_desc(struct net_device *dev)
static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
{
int i;
- printk(KERN_DEBUG "%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
+
+ printk("%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
for (i = 0; i < skb->len; i++) {
if (i % 16 == 0) {
if (i)
- pr_cont("\n");
- printk(KERN_DEBUG "%s: data[%p]:", dev->name,
- skb->data + i);
+ printk("\n");
+ printk("%s: data[%p]:", dev->name, skb->data + i);
}
printk(" %02x", ((u8 *)skb->data)[i]);
}
@@ -281,6 +283,7 @@ static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
MDIO_PHY(phy_id));
while ((val = cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0))) & MDIO_BUSY)
cpu_relax();
+
return MDIO_DATA(val);
}
@@ -291,6 +294,7 @@ static int cpmac_mdio_write(struct mii_bus *bus, int phy_id,
cpu_relax();
cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_WRITE |
MDIO_REG(reg) | MDIO_PHY(phy_id) | MDIO_DATA(val));
+
return 0;
}
@@ -300,12 +304,13 @@ static int cpmac_mdio_reset(struct mii_bus *bus)
cpmac_clk = clk_get(&bus->dev, "cpmac");
if (IS_ERR(cpmac_clk)) {
- printk(KERN_ERR "unable to get cpmac clock\n");
+ pr_err("unable to get cpmac clock\n");
return -1;
}
ar7_device_reset(AR7_RESET_BIT_MDIO);
cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE |
MDIOC_CLKDIV(clk_get_rate(cpmac_clk) / 2200000 - 1));
+
return 0;
}
@@ -331,8 +336,7 @@ static void cpmac_set_multicast_list(struct net_device *dev)
cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, 0xffffffff);
cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, 0xffffffff);
} else {
- /*
- * cpmac uses some strange mac address hashing
+ /* cpmac uses some strange mac address hashing
* (not crc32)
*/
netdev_for_each_mc_addr(ha, dev) {
@@ -369,8 +373,8 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
if (unlikely(!desc->datalen)) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx: spurious interrupt\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx: spurious interrupt\n");
+
return NULL;
}
@@ -390,15 +394,14 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
DMA_FROM_DEVICE);
desc->hw_data = (u32)desc->data_mapping;
if (unlikely(netif_msg_pktdata(priv))) {
- printk(KERN_DEBUG "%s: received packet:\n",
- priv->dev->name);
+ netdev_dbg(priv->dev, "received packet:\n");
cpmac_dump_skb(priv->dev, result);
}
} else {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING
- "%s: low on skbs, dropping packet\n",
- priv->dev->name);
+ netdev_warn(priv->dev,
+ "low on skbs, dropping packet\n");
+
priv->dev->stats.rx_dropped++;
}
@@ -418,8 +421,8 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
spin_lock(&priv->rx_lock);
if (unlikely(!priv->rx_head)) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx: polling, but no queue\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx: polling, but no queue\n");
+
spin_unlock(&priv->rx_lock);
napi_complete(napi);
return 0;
@@ -432,15 +435,15 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if ((desc->dataflags & CPMAC_EOQ) != 0) {
/* The last update to eoq->hw_next didn't happen
- * soon enough, and the receiver stopped here.
- *Remember this descriptor so we can restart
- * the receiver after freeing some space.
- */
+ * soon enough, and the receiver stopped here.
+ * Remember this descriptor so we can restart
+ * the receiver after freeing some space.
+ */
if (unlikely(restart)) {
if (netif_msg_rx_err(priv))
- printk(KERN_ERR "%s: poll found a"
- " duplicate EOQ: %p and %p\n",
- priv->dev->name, restart, desc);
+ netdev_err(priv->dev, "poll found a"
+ " duplicate EOQ: %p and %p\n",
+ restart, desc);
goto fatal_error;
}
@@ -457,25 +460,27 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if (desc != priv->rx_head) {
/* We freed some buffers, but not the whole ring,
- * add what we did free to the rx list */
+ * add what we did free to the rx list
+ */
desc->prev->hw_next = (u32)0;
priv->rx_head->prev->hw_next = priv->rx_head->mapping;
}
/* Optimization: If we did not actually process an EOQ (perhaps because
* of quota limits), check to see if the tail of the queue has EOQ set.
- * We should immediately restart in that case so that the receiver can
- * restart and run in parallel with more packet processing.
- * This lets us handle slightly larger bursts before running
- * out of ring space (assuming dev->weight < ring_size) */
+ * We should immediately restart in that case so that the receiver can
+ * restart and run in parallel with more packet processing.
+ * This lets us handle slightly larger bursts before running
+ * out of ring space (assuming dev->weight < ring_size)
+ */
if (!restart &&
(priv->rx_head->prev->dataflags & (CPMAC_OWN|CPMAC_EOQ))
== CPMAC_EOQ &&
(priv->rx_head->dataflags & CPMAC_OWN) != 0) {
/* reset EOQ so the poll loop (above) doesn't try to
- * restart this when it eventually gets to this descriptor.
- */
+ * restart this when it eventually gets to this descriptor.
+ */
priv->rx_head->prev->dataflags &= ~CPMAC_EOQ;
restart = priv->rx_head;
}
@@ -484,15 +489,13 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
priv->dev->stats.rx_errors++;
priv->dev->stats.rx_fifo_errors++;
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: rx dma ring overrun\n",
- priv->dev->name);
+ netdev_warn(priv->dev, "rx dma ring overrun\n");
if (unlikely((restart->dataflags & CPMAC_OWN) == 0)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: cpmac_poll is trying to "
- "restart rx from a descriptor that's "
- "not free: %p\n",
- priv->dev->name, restart);
+ netdev_err(priv->dev, "cpmac_poll is trying "
+ "to restart rx from a descriptor "
+ "that's not free: %p\n", restart);
goto fatal_error;
}
@@ -502,11 +505,12 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
priv->rx_head = desc;
spin_unlock(&priv->rx_lock);
if (unlikely(netif_msg_rx_status(priv)))
- printk(KERN_DEBUG "%s: poll processed %d packets\n",
- priv->dev->name, received);
+ netdev_dbg(priv->dev, "poll processed %d packets\n", received);
+
if (processed == 0) {
/* we ran out of packets to read,
- * revert to interrupt-driven mode */
+ * revert to interrupt-driven mode
+ */
napi_complete(napi);
cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
return 0;
@@ -516,16 +520,15 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
fatal_error:
/* Something went horribly wrong.
- * Reset hardware to try to recover rather than wedging. */
-
+ * Reset hardware to try to recover rather than wedging.
+ */
if (netif_msg_drv(priv)) {
- printk(KERN_ERR "%s: cpmac_poll is confused. "
- "Resetting hardware\n", priv->dev->name);
+ netdev_err(priv->dev, "cpmac_poll is confused. "
+ "Resetting hardware\n");
cpmac_dump_all_desc(priv->dev);
- printk(KERN_DEBUG "%s: RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n",
- priv->dev->name,
- cpmac_read(priv->regs, CPMAC_RX_PTR(0)),
- cpmac_read(priv->regs, CPMAC_RX_ACK(0)));
+ netdev_dbg(priv->dev, "RX_PTR(0)=0x%08x RX_ACK(0)=0x%08x\n",
+ cpmac_read(priv->regs, CPMAC_RX_PTR(0)),
+ cpmac_read(priv->regs, CPMAC_RX_ACK(0)));
}
spin_unlock(&priv->rx_lock);
@@ -537,6 +540,7 @@ fatal_error:
cpmac_hw_stop(priv->dev);
if (!schedule_work(&priv->reset_work))
atomic_dec(&priv->reset_pending);
+
return 0;
}
@@ -560,8 +564,8 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
desc = &priv->desc_ring[queue];
if (unlikely(desc->dataflags & CPMAC_OWN)) {
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: tx dma ring full\n",
- dev->name);
+ netdev_warn(dev, "tx dma ring full\n");
+
return NETDEV_TX_BUSY;
}
@@ -575,8 +579,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
desc->datalen = len;
desc->buflen = len;
if (unlikely(netif_msg_tx_queued(priv)))
- printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb,
- skb->len);
+ netdev_dbg(dev, "sending 0x%p, len=%d\n", skb, skb->len);
if (unlikely(netif_msg_hw(priv)))
cpmac_dump_desc(dev, desc);
if (unlikely(netif_msg_pktdata(priv)))
@@ -602,8 +605,8 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
DMA_TO_DEVICE);
if (unlikely(netif_msg_tx_done(priv)))
- printk(KERN_DEBUG "%s: sent 0x%p, len=%d\n", dev->name,
- desc->skb, desc->skb->len);
+ netdev_dbg(dev, "sent 0x%p, len=%d\n",
+ desc->skb, desc->skb->len);
dev_kfree_skb_irq(desc->skb);
desc->skb = NULL;
@@ -611,8 +614,7 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
netif_wake_subqueue(dev, queue);
} else {
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING
- "%s: end_xmit: spurious interrupt\n", dev->name);
+ netdev_warn(dev, "end_xmit: spurious interrupt\n");
if (__netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
}
@@ -687,14 +689,14 @@ static void cpmac_clear_rx(struct net_device *dev)
struct cpmac_priv *priv = netdev_priv(dev);
struct cpmac_desc *desc;
int i;
+
if (unlikely(!priv->rx_head))
return;
desc = priv->rx_head;
for (i = 0; i < priv->ring_size; i++) {
if ((desc->dataflags & CPMAC_OWN) == 0) {
if (netif_msg_rx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: packet dropped\n",
- dev->name);
+ netdev_warn(dev, "packet dropped\n");
if (unlikely(netif_msg_hw(priv)))
cpmac_dump_desc(dev, desc);
desc->dataflags = CPMAC_OWN;
@@ -710,6 +712,7 @@ static void cpmac_clear_tx(struct net_device *dev)
{
struct cpmac_priv *priv = netdev_priv(dev);
int i;
+
if (unlikely(!priv->desc_ring))
return;
for (i = 0; i < CPMAC_QUEUES; i++) {
@@ -751,16 +754,16 @@ static void cpmac_check_status(struct net_device *dev)
if (rx_code || tx_code) {
if (netif_msg_drv(priv) && net_ratelimit()) {
/* Can't find any documentation on what these
- *error codes actually are. So just log them and hope..
+ * error codes actually are. So just log them and hope..
*/
if (rx_code)
- printk(KERN_WARNING "%s: host error %d on rx "
- "channel %d (macstatus %08x), resetting\n",
- dev->name, rx_code, rx_channel, macstatus);
+ netdev_warn(dev, "host error %d on rx "
+ "channel %d (macstatus %08x), resetting\n",
+ rx_code, rx_channel, macstatus);
if (tx_code)
- printk(KERN_WARNING "%s: host error %d on tx "
- "channel %d (macstatus %08x), resetting\n",
- dev->name, tx_code, tx_channel, macstatus);
+ netdev_warn(dev, "host error %d on tx "
+ "channel %d (macstatus %08x), resetting\n",
+ tx_code, tx_channel, macstatus);
}
netif_tx_stop_all_queues(dev);
@@ -785,8 +788,7 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);
if (unlikely(netif_msg_intr(priv)))
- printk(KERN_DEBUG "%s: interrupt status: 0x%08x\n", dev->name,
- status);
+ netdev_dbg(dev, "interrupt status: 0x%08x\n", status);
if (status & MAC_INT_TX)
cpmac_end_xmit(dev, (status & 7));
@@ -815,7 +817,7 @@ static void cpmac_tx_timeout(struct net_device *dev)
dev->stats.tx_errors++;
spin_unlock(&priv->lock);
if (netif_msg_tx_err(priv) && net_ratelimit())
- printk(KERN_WARNING "%s: transmit timeout\n", dev->name);
+ netdev_warn(dev, "transmit timeout\n");
atomic_inc(&priv->reset_pending);
barrier();
@@ -829,6 +831,7 @@ static void cpmac_tx_timeout(struct net_device *dev)
static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct cpmac_priv *priv = netdev_priv(dev);
+
if (!(netif_running(dev)))
return -EINVAL;
if (!priv->phy)
@@ -884,6 +887,7 @@ static int cpmac_set_ringparam(struct net_device *dev,
if (netif_running(dev))
return -EBUSY;
priv->ring_size = ring->rx_pending;
+
return 0;
}
@@ -951,8 +955,8 @@ static int cpmac_open(struct net_device *dev)
mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
if (!request_mem_region(mem->start, resource_size(mem), dev->name)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to request registers\n",
- dev->name);
+ netdev_err(dev, "failed to request registers\n");
+
res = -ENXIO;
goto fail_reserve;
}
@@ -960,8 +964,8 @@ static int cpmac_open(struct net_device *dev)
priv->regs = ioremap(mem->start, resource_size(mem));
if (!priv->regs) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to remap registers\n",
- dev->name);
+ netdev_err(dev, "failed to remap registers\n");
+
res = -ENXIO;
goto fail_remap;
}
@@ -1003,8 +1007,8 @@ static int cpmac_open(struct net_device *dev)
res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev);
if (res) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: failed to obtain irq\n",
- dev->name);
+ netdev_err(dev, "failed to obtain irq\n");
+
goto fail_irq;
}
@@ -1077,6 +1081,7 @@ static int cpmac_stop(struct net_device *dev)
dma_free_coherent(&dev->dev, sizeof(struct cpmac_desc) *
(CPMAC_QUEUES + priv->ring_size),
priv->desc_ring, priv->dma_ring);
+
return 0;
}
@@ -1121,7 +1126,7 @@ static int cpmac_probe(struct platform_device *pdev)
if (phy_id == PHY_MAX_ADDR) {
dev_err(&pdev->dev, "no PHY present, falling back "
- "to switch on MDIO bus 0\n");
+ "to switch on MDIO bus 0\n");
strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */
phy_id = pdev->id;
}
@@ -1137,7 +1142,7 @@ static int cpmac_probe(struct platform_device *pdev)
mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
if (!mem) {
rc = -ENODEV;
- goto fail;
+ goto out;
}
dev->irq = platform_get_irq_byname(pdev, "irq");
@@ -1162,44 +1167,48 @@ static int cpmac_probe(struct platform_device *pdev)
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
- printk(KERN_ERR "%s: Could not attach to PHY\n",
- dev->name);
+ dev_err(&pdev->dev, "Could not attach to PHY\n");
+
rc = PTR_ERR(priv->phy);
- goto fail;
+ goto out;
}
rc = register_netdev(dev);
if (rc) {
- printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
- dev->name);
+ dev_err(&pdev->dev, "Could not register net device\n");
goto fail;
}
if (netif_msg_probe(priv)) {
- printk(KERN_INFO
- "cpmac: device %s (regs: %p, irq: %d, phy: %s, "
- "mac: %pM)\n", dev->name, (void *)mem->start, dev->irq,
- priv->phy_name, dev->dev_addr);
+ dev_info(&pdev->dev, "regs: %p, irq: %d, phy: %s, "
+ "mac: %pM\n", (void *)mem->start, dev->irq,
+ priv->phy_name, dev->dev_addr);
}
+
return 0;
fail:
free_netdev(dev);
+out:
return rc;
}
static int cpmac_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
+
unregister_netdev(dev);
free_netdev(dev);
+
return 0;
}
static struct platform_driver cpmac_driver = {
- .driver.name = "cpmac",
- .driver.owner = THIS_MODULE,
- .probe = cpmac_probe,
+ .driver = {
+ .name = "cpmac",
+ .owner = THIS_MODULE,
+ },
+ .probe = cpmac_probe,
.remove = cpmac_remove,
};
@@ -1221,7 +1230,7 @@ int cpmac_init(void)
cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256);
if (!cpmac_mii->priv) {
- printk(KERN_ERR "Can't ioremap mdio registers\n");
+ pr_err("Can't ioremap mdio registers\n");
res = -ENXIO;
goto fail_alloc;
}
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index b988d16cd34e..999fb72688d2 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -884,14 +884,16 @@ static int cpsw_set_coalesce(struct net_device *ndev,
u32 addnl_dvdr = 1;
u32 coal_intvl = 0;
- if (!coal->rx_coalesce_usecs)
- return -EINVAL;
-
coal_intvl = coal->rx_coalesce_usecs;
int_ctrl = readl(&priv->wr_regs->int_control);
prescale = priv->bus_freq_mhz * 4;
+ if (!coal->rx_coalesce_usecs) {
+ int_ctrl &= ~(CPSW_INTPRESCALE_MASK | CPSW_INTPACEEN);
+ goto update_return;
+ }
+
if (coal_intvl < CPSW_CMINTMIN_INTVL)
coal_intvl = CPSW_CMINTMIN_INTVL;
@@ -919,6 +921,8 @@ static int cpsw_set_coalesce(struct net_device *ndev,
int_ctrl |= CPSW_INTPACEEN;
int_ctrl &= (~CPSW_INTPRESCALE_MASK);
int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK);
+
+update_return:
writel(int_ctrl, &priv->wr_regs->int_control);
cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl);
@@ -999,17 +1003,6 @@ static void cpsw_get_ethtool_stats(struct net_device *ndev,
}
}
-static inline int __show_stat(char *buf, int maxlen, const char *name, u32 val)
-{
- static char *leader = "........................................";
-
- if (!val)
- return 0;
- else
- return snprintf(buf, maxlen, "%s %s %10d\n", name,
- leader + strlen(name), val);
-}
-
static int cpsw_common_res_usage_state(struct cpsw_priv *priv)
{
u32 i;
@@ -1671,14 +1664,34 @@ static const struct net_device_ops cpsw_netdev_ops = {
.ndo_vlan_rx_kill_vid = cpsw_ndo_vlan_rx_kill_vid,
};
+static int cpsw_get_regs_len(struct net_device *ndev)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+
+ return priv->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32);
+}
+
+static void cpsw_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct cpsw_priv *priv = netdev_priv(ndev);
+ u32 *reg = p;
+
+ /* update CPSW IP version */
+ regs->version = priv->version;
+
+ cpsw_ale_dump(priv->ale, reg);
+}
+
static void cpsw_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
{
struct cpsw_priv *priv = netdev_priv(ndev);
- strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver));
+ strlcpy(info->driver, "cpsw", sizeof(info->driver));
strlcpy(info->version, "1.0", sizeof(info->version));
strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info));
+ info->regdump_len = cpsw_get_regs_len(ndev);
}
static u32 cpsw_get_msglevel(struct net_device *ndev)
@@ -1786,6 +1799,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
.get_ethtool_stats = cpsw_get_ethtool_stats,
.get_wol = cpsw_get_wol,
.set_wol = cpsw_set_wol,
+ .get_regs_len = cpsw_get_regs_len,
+ .get_regs = cpsw_get_regs,
};
static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c
index 7f893069c418..0579b2243bb6 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.c
+++ b/drivers/net/ethernet/ti/cpsw_ale.c
@@ -25,8 +25,6 @@
#include "cpsw_ale.h"
#define BITMASK(bits) (BIT(bits) - 1)
-#define ALE_ENTRY_BITS 68
-#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
#define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff)
#define ALE_VERSION_MINOR(rev) (rev & 0xff)
@@ -763,3 +761,13 @@ int cpsw_ale_destroy(struct cpsw_ale *ale)
kfree(ale);
return 0;
}
+
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
+{
+ int i;
+
+ for (i = 0; i < ale->params.ale_entries; i++) {
+ cpsw_ale_read(ale, i, data);
+ data += ALE_ENTRY_WORDS;
+ }
+}
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h
index de409c33b250..31cf43cab42e 100644
--- a/drivers/net/ethernet/ti/cpsw_ale.h
+++ b/drivers/net/ethernet/ti/cpsw_ale.h
@@ -80,6 +80,9 @@ enum cpsw_ale_port_state {
#define ALE_MCAST_FWD_LEARN 2
#define ALE_MCAST_FWD_2 3
+#define ALE_ENTRY_BITS 68
+#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
+
struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params);
int cpsw_ale_destroy(struct cpsw_ale *ale);
@@ -104,5 +107,6 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
int control, int value);
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data);
#endif
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 6b56f85951e5..ab92f67da035 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -256,23 +256,21 @@ static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
u16 ts_seqid, u8 ts_msgtype)
{
u16 *seqid;
- unsigned int offset;
+ unsigned int offset = 0;
u8 *msgtype, *data = skb->data;
- switch (ptp_class) {
- case PTP_CLASS_V1_IPV4:
- case PTP_CLASS_V2_IPV4:
- offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
- break;
- case PTP_CLASS_V1_IPV6:
- case PTP_CLASS_V2_IPV6:
- offset = OFF_PTP6;
+ if (ptp_class & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (ptp_class & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
break;
- case PTP_CLASS_V2_L2:
- offset = ETH_HLEN;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
break;
- case PTP_CLASS_V2_VLAN:
- offset = ETH_HLEN + VLAN_HLEN;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
break;
default:
return 0;
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 735dc53d4b01..2791f6f2db11 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -38,6 +38,7 @@
#include <linux/davinci_emac.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include <linux/pinctrl/consumer.h>
/*
@@ -95,6 +96,10 @@ struct davinci_mdio_data {
struct mii_bus *bus;
bool suspended;
unsigned long access_time; /* jiffies */
+ /* Indicates that driver shouldn't modify phy_mask in case
+ * if MDIO bus is registered from DT.
+ */
+ bool skip_scan;
};
static void __davinci_mdio_reset(struct davinci_mdio_data *data)
@@ -144,6 +149,9 @@ static int davinci_mdio_reset(struct mii_bus *bus)
dev_info(data->dev, "davinci mdio revision %d.%d\n",
(ver >> 8) & 0xff, ver & 0xff);
+ if (data->skip_scan)
+ return 0;
+
/* get phy mask from the alive register */
phy_mask = __raw_readl(&data->regs->alive);
if (phy_mask) {
@@ -369,8 +377,17 @@ static int davinci_mdio_probe(struct platform_device *pdev)
goto bail_out;
}
- /* register the mii bus */
- ret = mdiobus_register(data->bus);
+ /* register the mii bus
+ * Create PHYs from DT only in case if PHY child nodes are explicitly
+ * defined to support backward compatibility with DTs which assume that
+ * Davinci MDIO will always scan the bus for PHYs detection.
+ */
+ if (dev->of_node && of_get_child_count(dev->of_node)) {
+ data->skip_scan = true;
+ ret = of_mdiobus_register(data->bus, dev->of_node);
+ } else {
+ ret = mdiobus_register(data->bus);
+ }
if (ret)
goto bail_out;
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 62b19be5183d..6078342fe3f2 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -69,10 +69,6 @@ MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
MODULE_LICENSE("GPL");
-
-/* Define this to enable Link beat monitoring */
-#undef MONITOR
-
/* Turn on debugging. See Documentation/networking/tlan.txt for details */
static int debug;
module_param(debug, int, 0);
@@ -107,8 +103,10 @@ static struct board {
{ "Compaq Netelligent 10/100 TX Embedded UTP",
TLAN_ADAPTER_NONE, 0x83 },
{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
- { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
- { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
+ { "Olicom OC-2325", TLAN_ADAPTER_ACTIVITY_LED |
+ TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
+ { "Olicom OC-2326", TLAN_ADAPTER_ACTIVITY_LED |
+ TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
{ "Compaq NetFlex-3/E",
@@ -192,9 +190,7 @@ static void tlan_phy_power_up(struct net_device *);
static void tlan_phy_reset(struct net_device *);
static void tlan_phy_start_link(struct net_device *);
static void tlan_phy_finish_auto_neg(struct net_device *);
-#ifdef MONITOR
-static void tlan_phy_monitor(struct net_device *);
-#endif
+static void tlan_phy_monitor(unsigned long);
/*
static int tlan_phy_nop(struct net_device *);
@@ -337,6 +333,7 @@ static void tlan_stop(struct net_device *dev)
{
struct tlan_priv *priv = netdev_priv(dev);
+ del_timer_sync(&priv->media_timer);
tlan_read_and_clear_stats(dev, TLAN_RECORD);
outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
/* Reset and power down phy */
@@ -368,8 +365,10 @@ static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
static int tlan_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ int rc = pci_enable_device(pdev);
- pci_set_power_state(pdev, PCI_D0);
+ if (rc)
+ return rc;
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
netif_device_attach(dev);
@@ -781,7 +780,43 @@ static const struct net_device_ops tlan_netdev_ops = {
#endif
};
+static void tlan_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct tlan_priv *priv = netdev_priv(dev);
+
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ if (priv->pci_dev)
+ strlcpy(info->bus_info, pci_name(priv->pci_dev),
+ sizeof(info->bus_info));
+ else
+ strlcpy(info->bus_info, "EISA", sizeof(info->bus_info));
+ info->eedump_len = TLAN_EEPROM_SIZE;
+}
+
+static int tlan_get_eeprom_len(struct net_device *dev)
+{
+ return TLAN_EEPROM_SIZE;
+}
+
+static int tlan_get_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+
+ for (i = 0; i < TLAN_EEPROM_SIZE; i++)
+ if (tlan_ee_read_byte(dev, i, &data[i]))
+ return -EIO;
+ return 0;
+}
+
+static const struct ethtool_ops tlan_ethtool_ops = {
+ .get_drvinfo = tlan_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = tlan_get_eeprom_len,
+ .get_eeprom = tlan_get_eeprom,
+};
/***************************************************************
* tlan_init
@@ -830,7 +865,7 @@ static int tlan_init(struct net_device *dev)
priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
err = 0;
- for (i = 0; i < 6 ; i++)
+ for (i = 0; i < ETH_ALEN; i++)
err |= tlan_ee_read_byte(dev,
(u8) priv->adapter->addr_ofs + i,
(u8 *) &dev->dev_addr[i]);
@@ -838,12 +873,20 @@ static int tlan_init(struct net_device *dev)
pr_err("%s: Error reading MAC from eeprom: %d\n",
dev->name, err);
}
- dev->addr_len = 6;
+ /* Olicom OC-2325/OC-2326 have the address byte-swapped */
+ if (priv->adapter->addr_ofs == 0xf8) {
+ for (i = 0; i < ETH_ALEN; i += 2) {
+ char tmp = dev->dev_addr[i];
+ dev->dev_addr[i] = dev->dev_addr[i + 1];
+ dev->dev_addr[i + 1] = tmp;
+ }
+ }
netif_carrier_off(dev);
/* Device methods */
dev->netdev_ops = &tlan_netdev_ops;
+ dev->ethtool_ops = &tlan_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT;
return 0;
@@ -886,6 +929,7 @@ static int tlan_open(struct net_device *dev)
}
init_timer(&priv->timer);
+ init_timer(&priv->media_timer);
tlan_start(dev);
@@ -1156,9 +1200,6 @@ static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
static int tlan_close(struct net_device *dev)
{
- struct tlan_priv *priv = netdev_priv(dev);
-
- priv->neg_be_verbose = 0;
tlan_stop(dev);
free_irq(dev->irq, dev);
@@ -1808,11 +1849,6 @@ static void tlan_timer(unsigned long data)
priv->timer.function = NULL;
switch (priv->timer_type) {
-#ifdef MONITOR
- case TLAN_TIMER_LINK_BEAT:
- tlan_phy_monitor(dev);
- break;
-#endif
case TLAN_TIMER_PHY_PDOWN:
tlan_phy_power_down(dev);
break;
@@ -1856,8 +1892,6 @@ static void tlan_timer(unsigned long data)
}
-
-
/*****************************************************************************
******************************************************************************
@@ -2205,7 +2239,9 @@ tlan_reset_adapter(struct net_device *dev)
}
}
- if (priv->phy_num == 0)
+ /* don't power down internal PHY if we're going to use it */
+ if (priv->phy_num == 0 ||
+ (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))
data |= TLAN_NET_CFG_PHY_EN;
tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
@@ -2255,42 +2291,39 @@ tlan_finish_reset(struct net_device *dev)
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
udelay(1000);
tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
- if ((status & MII_GS_LINK) &&
- /* We only support link info on Nat.Sem. PHY's */
- (tlphy_id1 == NAT_SEM_ID1) &&
- (tlphy_id2 == NAT_SEM_ID2)) {
- tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
- tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
-
- netdev_info(dev,
- "Link active with %s %uMbps %s-Duplex\n",
- !(tlphy_par & TLAN_PHY_AN_EN_STAT)
- ? "forced" : "Autonegotiation enabled,",
- tlphy_par & TLAN_PHY_SPEED_100
- ? 100 : 10,
- tlphy_par & TLAN_PHY_DUPLEX_FULL
- ? "Full" : "Half");
-
- if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
- netdev_info(dev, "Partner capability:");
- for (i = 5; i < 10; i++)
- if (partner & (1 << i))
- pr_cont(" %s", media[i-5]);
- pr_cont("\n");
- }
-
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
-#ifdef MONITOR
- /* We have link beat..for now anyway */
- priv->link = 1;
- /*Enabling link beat monitoring */
- tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
-#endif
- } else if (status & MII_GS_LINK) {
- netdev_info(dev, "Link active\n");
- tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
- TLAN_LED_LINK);
+ if (status & MII_GS_LINK) {
+ /* We only support link info on Nat.Sem. PHY's */
+ if ((tlphy_id1 == NAT_SEM_ID1) &&
+ (tlphy_id2 == NAT_SEM_ID2)) {
+ tlan_mii_read_reg(dev, phy, MII_AN_LPA,
+ &partner);
+ tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR,
+ &tlphy_par);
+
+ netdev_info(dev,
+ "Link active, %s %uMbps %s-Duplex\n",
+ !(tlphy_par & TLAN_PHY_AN_EN_STAT)
+ ? "forced" : "Autonegotiation enabled,",
+ tlphy_par & TLAN_PHY_SPEED_100
+ ? 100 : 10,
+ tlphy_par & TLAN_PHY_DUPLEX_FULL
+ ? "Full" : "Half");
+
+ if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
+ netdev_info(dev, "Partner capability:");
+ for (i = 5; i < 10; i++)
+ if (partner & (1 << i))
+ pr_cont(" %s",
+ media[i-5]);
+ pr_cont("\n");
+ }
+ } else
+ netdev_info(dev, "Link active\n");
+ /* Enabling link beat monitoring */
+ priv->media_timer.function = tlan_phy_monitor;
+ priv->media_timer.data = (unsigned long) dev;
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
}
@@ -2312,6 +2345,7 @@ tlan_finish_reset(struct net_device *dev)
dev->base_addr + TLAN_HOST_CMD + 1);
outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
netif_carrier_on(dev);
} else {
netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
@@ -2494,9 +2528,10 @@ static void tlan_phy_power_down(struct net_device *dev)
value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
tlan_mii_sync(dev->base_addr);
tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
- if ((priv->phy_num == 0) &&
- (priv->phy[1] != TLAN_PHY_NONE) &&
- (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
+ if ((priv->phy_num == 0) && (priv->phy[1] != TLAN_PHY_NONE)) {
+ /* if using internal PHY, the external PHY must be powered on */
+ if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10)
+ value = MII_GC_ISOLATE; /* just isolate it from MII */
tlan_mii_sync(dev->base_addr);
tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
}
@@ -2538,6 +2573,7 @@ static void tlan_phy_reset(struct net_device *dev)
struct tlan_priv *priv = netdev_priv(dev);
u16 phy;
u16 value;
+ unsigned long timeout = jiffies + HZ;
phy = priv->phy[priv->phy_num];
@@ -2545,9 +2581,13 @@ static void tlan_phy_reset(struct net_device *dev)
tlan_mii_sync(dev->base_addr);
value = MII_GC_LOOPBK | MII_GC_RESET;
tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
- tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
- while (value & MII_GC_RESET)
+ do {
tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
+ if (time_after(jiffies, timeout)) {
+ netdev_err(dev, "PHY reset timeout\n");
+ return;
+ }
+ } while (value & MII_GC_RESET);
/* Wait for 500 ms and initialize.
* I don't remember why I wait this long.
@@ -2653,7 +2693,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
struct tlan_priv *priv = netdev_priv(dev);
u16 an_adv;
u16 an_lpa;
- u16 data;
u16 mode;
u16 phy;
u16 status;
@@ -2668,13 +2707,7 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
/* Wait for 8 sec to give the process
* more time. Perhaps we should fail after a while.
*/
- if (!priv->neg_be_verbose++) {
- pr_info("Giving autonegotiation more time.\n");
- pr_info("Please check that your adapter has\n");
- pr_info("been properly connected to a HUB or Switch.\n");
- pr_info("Trying to establish link in the background...\n");
- }
- tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
+ tlan_set_timer(dev, 2 * HZ, TLAN_TIMER_PHY_FINISH_AN);
return;
}
@@ -2687,13 +2720,11 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
else if (!(mode & 0x0080) && (mode & 0x0040))
priv->tlan_full_duplex = true;
+ /* switch to internal PHY for 10 Mbps */
if ((!(mode & 0x0180)) &&
(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
(priv->phy_num != 0)) {
priv->phy_num = 0;
- data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
- | TLAN_NET_CFG_PHY_EN;
- tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
return;
}
@@ -2717,7 +2748,6 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
}
-#ifdef MONITOR
/*********************************************************************
*
@@ -2727,18 +2757,18 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev)
* None
*
* Params:
- * dev The device structure of this device.
+ * data The device structure of this device.
*
*
* This function monitors PHY condition by reading the status
- * register via the MII bus. This can be used to give info
- * about link changes (up/down), and possible switch to alternate
- * media.
+ * register via the MII bus, controls LINK LED and notifies the
+ * kernel about link state.
*
*******************************************************************/
-void tlan_phy_monitor(struct net_device *dev)
+static void tlan_phy_monitor(unsigned long data)
{
+ struct net_device *dev = (struct net_device *) data;
struct tlan_priv *priv = netdev_priv(dev);
u16 phy;
u16 phy_status;
@@ -2750,30 +2780,40 @@ void tlan_phy_monitor(struct net_device *dev)
/* Check if link has been lost */
if (!(phy_status & MII_GS_LINK)) {
- if (priv->link) {
- priv->link = 0;
+ if (netif_carrier_ok(dev)) {
printk(KERN_DEBUG "TLAN: %s has lost link\n",
dev->name);
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, 0);
netif_carrier_off(dev);
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
- return;
+ if (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) {
+ /* power down internal PHY */
+ u16 data = MII_GC_PDOWN | MII_GC_LOOPBK |
+ MII_GC_ISOLATE;
+
+ tlan_mii_sync(dev->base_addr);
+ tlan_mii_write_reg(dev, priv->phy[0],
+ MII_GEN_CTL, data);
+ /* set to external PHY */
+ priv->phy_num = 1;
+ /* restart autonegotiation */
+ tlan_set_timer(dev, 4 * HZ / 10,
+ TLAN_TIMER_PHY_PDOWN);
+ return;
+ }
}
}
/* Link restablished? */
- if ((phy_status & MII_GS_LINK) && !priv->link) {
- priv->link = 1;
+ if ((phy_status & MII_GS_LINK) && !netif_carrier_ok(dev)) {
+ tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK);
printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
dev->name);
netif_carrier_on(dev);
}
-
- /* Setup a new monitor */
- tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
+ priv->media_timer.expires = jiffies + HZ;
+ add_timer(&priv->media_timer);
}
-#endif /* MONITOR */
-
/*****************************************************************************
******************************************************************************
diff --git a/drivers/net/ethernet/ti/tlan.h b/drivers/net/ethernet/ti/tlan.h
index 2eb33a250788..e9928411827e 100644
--- a/drivers/net/ethernet/ti/tlan.h
+++ b/drivers/net/ethernet/ti/tlan.h
@@ -195,6 +195,7 @@ struct tlan_priv {
u32 timer_set_at;
u32 timer_type;
struct timer_list timer;
+ struct timer_list media_timer;
struct board *adapter;
u32 adapter_rev;
u32 aui;
@@ -206,9 +207,7 @@ struct tlan_priv {
u8 tlan_rev;
u8 tlan_full_duplex;
spinlock_t lock;
- u8 link;
struct work_struct tlan_tqueue;
- u8 neg_be_verbose;
};
@@ -219,7 +218,6 @@ struct tlan_priv {
*
****************************************************************/
-#define TLAN_TIMER_LINK_BEAT 1
#define TLAN_TIMER_ACTIVITY 2
#define TLAN_TIMER_PHY_PDOWN 3
#define TLAN_TIMER_PHY_PUP 4
@@ -241,6 +239,7 @@ struct tlan_priv {
#define TLAN_EEPROM_ACK 0
#define TLAN_EEPROM_STOP 1
+#define TLAN_EEPROM_SIZE 256
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 4c70360967c2..69557a26f749 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -2201,8 +2201,8 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac)
/* Allocate the device structure. Normally, "name" is a
* template, instantiated by register_netdev(), but not for us.
*/
- dev = alloc_netdev_mqs(sizeof(*priv), name, tile_net_setup,
- NR_CPUS, 1);
+ dev = alloc_netdev_mqs(sizeof(*priv), name, NET_NAME_UNKNOWN,
+ tile_net_setup, NR_CPUS, 1);
if (!dev) {
pr_err("alloc_netdev_mqs(%s) failed\n", name);
return;
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
index e5a5c5d4ce0c..88c712126692 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -2292,7 +2292,8 @@ static struct net_device *tile_net_dev_init(const char *name)
* tile_net_setup(), and saves "name". Normally, "name" is a
* template, instantiated by register_netdev(), but not for us.
*/
- dev = alloc_netdev(sizeof(*priv), name, tile_net_setup);
+ dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN,
+ tile_net_setup);
if (!dev) {
pr_err("alloc_netdev(%s) failed\n", name);
return NULL;
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
index d568af1eb4f4..0a7f2e77557f 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
@@ -723,13 +723,10 @@ static int gelic_wl_get_scan(struct net_device *netdev,
/* If a scan in progress, caller should call me again */
ret = -EAGAIN;
goto out;
- break;
-
case GELIC_WL_SCAN_STAT_INIT:
/* last scan request failed or never issued */
ret = -ENODEV;
goto out;
- break;
case GELIC_WL_SCAN_STAT_GOT_LIST:
/* ok, use current list */
break;
@@ -1831,25 +1828,18 @@ static const char *wpasecstr(enum gelic_eurus_wpa_security sec)
switch (sec) {
case GELIC_EURUS_WPA_SEC_NONE:
return "NONE";
- break;
case GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP:
return "WPA_TKIP_TKIP";
- break;
case GELIC_EURUS_WPA_SEC_WPA_TKIP_AES:
return "WPA_TKIP_AES";
- break;
case GELIC_EURUS_WPA_SEC_WPA_AES_AES:
return "WPA_AES_AES";
- break;
case GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP:
return "WPA2_TKIP_TKIP";
- break;
case GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES:
return "WPA2_TKIP_AES";
- break;
case GELIC_EURUS_WPA_SEC_WPA2_AES_AES:
return "WPA2_AES_AES";
- break;
}
return "";
};
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 4ef818a7a6c6..8a6e5c2d6f95 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -72,7 +72,7 @@ void temac_iow(struct temac_local *lp, int offset, u32 value)
int temac_indirect_busywait(struct temac_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
if (time_before_eq(end, jiffies)) {
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
index d4abf478e2bb..3b67d60d4378 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -19,7 +19,7 @@
/* Wait till MDIO interface is ready to accept a new transaction.*/
int axienet_mdio_wait_until_ready(struct axienet_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) &
XAE_MDIO_MCR_READY_MASK)) {
if (time_before_eq(end, jiffies)) {
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 8c4aed3053eb..782bb9373cd8 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -695,7 +695,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
static int xemaclite_mdio_wait(struct net_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
/* wait for the MDIO interface to not be busy or timeout
after some time.
diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
index eb78203cd58e..6eb849a56da5 100644
--- a/drivers/net/fddi/defxx.c
+++ b/drivers/net/fddi/defxx.c
@@ -196,6 +196,7 @@
* 14 Jun 2005 macro Use irqreturn_t.
* 23 Oct 2006 macro Big-endian host support.
* 14 Dec 2006 macro TURBOchannel support.
+ * 01 Jul 2014 macro Fixes for DMA on 64-bit hosts.
*/
/* Include files */
@@ -224,8 +225,8 @@
/* Version information string should be updated prior to each new release! */
#define DRV_NAME "defxx"
-#define DRV_VERSION "v1.10"
-#define DRV_RELDATE "2006/12/14"
+#define DRV_VERSION "v1.11"
+#define DRV_RELDATE "2014/07/01"
static char version[] =
DRV_NAME ": " DRV_VERSION " " DRV_RELDATE
@@ -291,7 +292,11 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type);
static int dfx_rcv_init(DFX_board_t *bp, int get_buffers);
static void dfx_rcv_queue_process(DFX_board_t *bp);
+#ifdef DYNAMIC_BUFFERS
static void dfx_rcv_flush(DFX_board_t *bp);
+#else
+static inline void dfx_rcv_flush(DFX_board_t *bp) {}
+#endif
static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
struct net_device *dev);
@@ -1122,17 +1127,16 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name,
/* Display virtual and physical addresses if debug driver */
- DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n",
- print_name,
- (long)bp->descr_block_virt, bp->descr_block_phys);
- DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n",
- print_name, (long)bp->cmd_req_virt, bp->cmd_req_phys);
- DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n",
- print_name, (long)bp->cmd_rsp_virt, bp->cmd_rsp_phys);
- DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n",
- print_name, (long)bp->rcv_block_virt, bp->rcv_block_phys);
- DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n",
- print_name, (long)bp->cons_block_virt, bp->cons_block_phys);
+ DBG_printk("%s: Descriptor block virt = %p, phys = %pad\n",
+ print_name, bp->descr_block_virt, &bp->descr_block_phys);
+ DBG_printk("%s: Command Request buffer virt = %p, phys = %pad\n",
+ print_name, bp->cmd_req_virt, &bp->cmd_req_phys);
+ DBG_printk("%s: Command Response buffer virt = %p, phys = %pad\n",
+ print_name, bp->cmd_rsp_virt, &bp->cmd_rsp_phys);
+ DBG_printk("%s: Receive buffer block virt = %p, phys = %pad\n",
+ print_name, bp->rcv_block_virt, &bp->rcv_block_phys);
+ DBG_printk("%s: Consumer block virt = %p, phys = %pad\n",
+ print_name, bp->cons_block_virt, &bp->cons_block_phys);
return DFX_K_SUCCESS;
}
@@ -2849,7 +2853,7 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type)
* Align an sk_buff to a boundary power of 2
*
*/
-
+#ifdef DYNAMIC_BUFFERS
static void my_skb_align(struct sk_buff *skb, int n)
{
unsigned long x = (unsigned long)skb->data;
@@ -2859,7 +2863,7 @@ static void my_skb_align(struct sk_buff *skb, int n)
skb_reserve(skb, v - x);
}
-
+#endif
/*
* ================
@@ -2923,21 +2927,35 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers)
for (i = 0; i < (int)(bp->rcv_bufs_to_post); i++)
for (j = 0; (i + j) < (int)PI_RCV_DATA_K_NUM_ENTRIES; j += bp->rcv_bufs_to_post)
{
- struct sk_buff *newskb = __netdev_alloc_skb(bp->dev, NEW_SKB_SIZE, GFP_NOIO);
+ struct sk_buff *newskb;
+ dma_addr_t dma_addr;
+
+ newskb = __netdev_alloc_skb(bp->dev, NEW_SKB_SIZE,
+ GFP_NOIO);
if (!newskb)
return -ENOMEM;
- bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP |
- ((PI_RCV_DATA_K_SIZE_MAX / PI_ALIGN_K_RCV_DATA_BUFF) << PI_RCV_DESCR_V_SEG_LEN));
/*
* align to 128 bytes for compatibility with
* the old EISA boards.
*/
my_skb_align(newskb, 128);
+ dma_addr = dma_map_single(bp->bus_dev,
+ newskb->data,
+ PI_RCV_DATA_K_SIZE_MAX,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(bp->bus_dev, dma_addr)) {
+ dev_kfree_skb(newskb);
+ return -ENOMEM;
+ }
+ bp->descr_block_virt->rcv_data[i + j].long_0 =
+ (u32)(PI_RCV_DESCR_M_SOP |
+ ((PI_RCV_DATA_K_SIZE_MAX /
+ PI_ALIGN_K_RCV_DATA_BUFF) <<
+ PI_RCV_DESCR_V_SEG_LEN));
bp->descr_block_virt->rcv_data[i + j].long_1 =
- (u32)dma_map_single(bp->bus_dev, newskb->data,
- NEW_SKB_SIZE,
- DMA_FROM_DEVICE);
+ (u32)dma_addr;
+
/*
* p_rcv_buff_va is only used inside the
* kernel so we put the skb pointer here.
@@ -3004,7 +3022,7 @@ static void dfx_rcv_queue_process(
PI_TYPE_2_CONSUMER *p_type_2_cons; /* ptr to rcv/xmt consumer block register */
char *p_buff; /* ptr to start of packet receive buffer (FMC descriptor) */
u32 descr, pkt_len; /* FMC descriptor field and packet length */
- struct sk_buff *skb; /* pointer to a sk_buff to hold incoming packet data */
+ struct sk_buff *skb = NULL; /* pointer to a sk_buff to hold incoming packet data */
/* Service all consumed LLC receive frames */
@@ -3012,7 +3030,7 @@ static void dfx_rcv_queue_process(
while (bp->rcv_xmt_reg.index.rcv_comp != p_type_2_cons->index.rcv_cons)
{
/* Process any errors */
-
+ dma_addr_t dma_addr;
int entry;
entry = bp->rcv_xmt_reg.index.rcv_comp;
@@ -3021,6 +3039,11 @@ static void dfx_rcv_queue_process(
#else
p_buff = bp->p_rcv_buff_va[entry];
#endif
+ dma_addr = bp->descr_block_virt->rcv_data[entry].long_1;
+ dma_sync_single_for_cpu(bp->bus_dev,
+ dma_addr + RCV_BUFF_K_DESCR,
+ sizeof(u32),
+ DMA_FROM_DEVICE);
memcpy(&descr, p_buff + RCV_BUFF_K_DESCR, sizeof(u32));
if (descr & PI_FMC_DESCR_M_RCC_FLUSH)
@@ -3042,31 +3065,46 @@ static void dfx_rcv_queue_process(
bp->rcv_length_errors++;
else{
#ifdef DYNAMIC_BUFFERS
+ struct sk_buff *newskb = NULL;
+
if (pkt_len > SKBUFF_RX_COPYBREAK) {
- struct sk_buff *newskb;
+ dma_addr_t new_dma_addr;
- newskb = dev_alloc_skb(NEW_SKB_SIZE);
+ newskb = netdev_alloc_skb(bp->dev,
+ NEW_SKB_SIZE);
if (newskb){
+ my_skb_align(newskb, 128);
+ new_dma_addr = dma_map_single(
+ bp->bus_dev,
+ newskb->data,
+ PI_RCV_DATA_K_SIZE_MAX,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(
+ bp->bus_dev,
+ new_dma_addr)) {
+ dev_kfree_skb(newskb);
+ newskb = NULL;
+ }
+ }
+ if (newskb) {
rx_in_place = 1;
- my_skb_align(newskb, 128);
skb = (struct sk_buff *)bp->p_rcv_buff_va[entry];
dma_unmap_single(bp->bus_dev,
- bp->descr_block_virt->rcv_data[entry].long_1,
- NEW_SKB_SIZE,
+ dma_addr,
+ PI_RCV_DATA_K_SIZE_MAX,
DMA_FROM_DEVICE);
skb_reserve(skb, RCV_BUFF_K_PADDING);
bp->p_rcv_buff_va[entry] = (char *)newskb;
- bp->descr_block_virt->rcv_data[entry].long_1 =
- (u32)dma_map_single(bp->bus_dev,
- newskb->data,
- NEW_SKB_SIZE,
- DMA_FROM_DEVICE);
- } else
- skb = NULL;
- } else
+ bp->descr_block_virt->rcv_data[entry].long_1 = (u32)new_dma_addr;
+ }
+ }
+ if (!newskb)
#endif
- skb = dev_alloc_skb(pkt_len+3); /* alloc new buffer to pass up, add room for PRH */
+ /* Alloc new buffer to pass up,
+ * add room for PRH. */
+ skb = netdev_alloc_skb(bp->dev,
+ pkt_len + 3);
if (skb == NULL)
{
printk("%s: Could not allocate receive buffer. Dropping packet.\n", bp->dev->name);
@@ -3074,11 +3112,14 @@ static void dfx_rcv_queue_process(
break;
}
else {
-#ifndef DYNAMIC_BUFFERS
- if (! rx_in_place)
-#endif
- {
+ if (!rx_in_place) {
/* Receive buffer allocated, pass receive packet up */
+ dma_sync_single_for_cpu(
+ bp->bus_dev,
+ dma_addr +
+ RCV_BUFF_K_PADDING,
+ pkt_len + 3,
+ DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb,
p_buff + RCV_BUFF_K_PADDING,
@@ -3181,6 +3222,7 @@ static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
u8 prod; /* local transmit producer index */
PI_XMT_DESCR *p_xmt_descr; /* ptr to transmit descriptor block entry */
XMT_DRIVER_DESCR *p_xmt_drv_descr; /* ptr to transmit driver descriptor */
+ dma_addr_t dma_addr;
unsigned long flags;
netif_stop_queue(dev);
@@ -3228,6 +3270,20 @@ static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
}
}
+ /* Write the three PRH bytes immediately before the FC byte */
+
+ skb_push(skb, 3);
+ skb->data[0] = DFX_PRH0_BYTE; /* these byte values are defined */
+ skb->data[1] = DFX_PRH1_BYTE; /* in the Motorola FDDI MAC chip */
+ skb->data[2] = DFX_PRH2_BYTE; /* specification */
+
+ dma_addr = dma_map_single(bp->bus_dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(bp->bus_dev, dma_addr)) {
+ skb_pull(skb, 3);
+ return NETDEV_TX_BUSY;
+ }
+
spin_lock_irqsave(&bp->lock, flags);
/* Get the current producer and the next free xmt data descriptor */
@@ -3248,13 +3304,6 @@ static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
p_xmt_drv_descr = &(bp->xmt_drv_descr_blk[prod++]); /* also bump producer index */
- /* Write the three PRH bytes immediately before the FC byte */
-
- skb_push(skb,3);
- skb->data[0] = DFX_PRH0_BYTE; /* these byte values are defined */
- skb->data[1] = DFX_PRH1_BYTE; /* in the Motorola FDDI MAC chip */
- skb->data[2] = DFX_PRH2_BYTE; /* specification */
-
/*
* Write the descriptor with buffer info and bump producer
*
@@ -3283,8 +3332,7 @@ static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
*/
p_xmt_descr->long_0 = (u32) (PI_XMT_DESCR_M_SOP | PI_XMT_DESCR_M_EOP | ((skb->len) << PI_XMT_DESCR_V_SEG_LEN));
- p_xmt_descr->long_1 = (u32)dma_map_single(bp->bus_dev, skb->data,
- skb->len, DMA_TO_DEVICE);
+ p_xmt_descr->long_1 = (u32)dma_addr;
/*
* Verify that descriptor is actually available
@@ -3447,16 +3495,17 @@ static void dfx_rcv_flush( DFX_board_t *bp )
{
struct sk_buff *skb;
skb = (struct sk_buff *)bp->p_rcv_buff_va[i+j];
- if (skb)
+ if (skb) {
+ dma_unmap_single(bp->bus_dev,
+ bp->descr_block_virt->rcv_data[i+j].long_1,
+ PI_RCV_DATA_K_SIZE_MAX,
+ DMA_FROM_DEVICE);
dev_kfree_skb(skb);
+ }
bp->p_rcv_buff_va[i+j] = NULL;
}
}
-#else
-static inline void dfx_rcv_flush( DFX_board_t *bp )
-{
-}
#endif /* DYNAMIC_BUFFERS */
/*
diff --git a/drivers/net/fddi/defxx.h b/drivers/net/fddi/defxx.h
index 19a6f64df198..adb63f3f7b4a 100644
--- a/drivers/net/fddi/defxx.h
+++ b/drivers/net/fddi/defxx.h
@@ -1693,7 +1693,7 @@ typedef union
/* Only execute special print call when debug driver was built */
#ifdef DEFXX_DEBUG
-#define DBG_printk(args...) printk(## args)
+#define DBG_printk(args...) printk(args)
#else
#define DBG_printk(args...)
#endif
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 66e2b19ef709..c3c4051a089d 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -596,7 +596,8 @@ static int sixpack_open(struct tty_struct *tty)
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
- dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
+ dev = alloc_netdev(sizeof(struct sixpack), "sp%d", NET_NAME_UNKNOWN,
+ sp_setup);
if (!dev) {
err = -ENOMEM;
goto out;
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 484f77ec2ce1..a98c153f371e 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -1206,7 +1206,7 @@ static int __init init_baycomepp(void)
struct net_device *dev;
dev = alloc_netdev(sizeof(struct baycom_state), "bce%d",
- baycom_epp_dev_setup);
+ NET_NAME_UNKNOWN, baycom_epp_dev_setup);
if (!dev) {
printk(KERN_WARNING "bce%d : out of memory\n", i);
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index d50b23cf9ea9..c2894e43840e 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -501,8 +501,8 @@ static int bpq_new_device(struct net_device *edev)
struct net_device *ndev;
struct bpqdev *bpq;
- ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d",
- bpq_setup);
+ ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d", NET_NAME_UNKNOWN,
+ bpq_setup);
if (!ndev)
return -ENOMEM;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 6636022a1027..0fad408f24aa 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -466,7 +466,7 @@ static int __init setup_adapter(int card_base, int type, int n)
if (!info)
goto out;
- info->dev[0] = alloc_netdev(0, "", dev_setup);
+ info->dev[0] = alloc_netdev(0, "", NET_NAME_UNKNOWN, dev_setup);
if (!info->dev[0]) {
printk(KERN_ERR "dmascc: "
"could not allocate memory for %s at %#3x\n",
@@ -474,7 +474,7 @@ static int __init setup_adapter(int card_base, int type, int n)
goto out1;
}
- info->dev[1] = alloc_netdev(0, "", dev_setup);
+ info->dev[1] = alloc_netdev(0, "", NET_NAME_UNKNOWN, dev_setup);
if (!info->dev[1]) {
printk(KERN_ERR "dmascc: "
"could not allocate memory for %s at %#3x\n",
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 5d78c1d08abd..c67a27245072 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -699,7 +699,7 @@ struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
if (privsize < sizeof(struct hdlcdrv_state))
privsize = sizeof(struct hdlcdrv_state);
- dev = alloc_netdev(privsize, ifname, hdlcdrv_setup);
+ dev = alloc_netdev(privsize, ifname, NET_NAME_UNKNOWN, hdlcdrv_setup);
if (!dev)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 8a6c720a4cc9..f990bb1c3e02 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -734,7 +734,8 @@ static int mkiss_open(struct tty_struct *tty)
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
- dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
+ dev = alloc_netdev(sizeof(struct mkiss), "ax%d", NET_NAME_UNKNOWN,
+ ax_setup);
if (!dev) {
err = -ENOMEM;
goto out;
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 4bc6ee8e7987..57be9e0e98a6 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1515,7 +1515,7 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc)
int err;
struct net_device *dev;
- dev = alloc_netdev(0, name, scc_net_setup);
+ dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, scc_net_setup);
if (!dev)
return -ENOMEM;
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 81901659cc9e..717433cfb81d 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -1147,7 +1147,7 @@ static int __init yam_init_driver(void)
sprintf(name, "yam%d", i);
dev = alloc_netdev(sizeof(struct yam_port), name,
- yam_setup);
+ NET_NAME_UNKNOWN, yam_setup);
if (!dev) {
pr_err("yam: cannot allocate net device\n");
err = -ENOMEM;
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 6cc37c15e0bf..d5e07def6a59 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -170,6 +170,7 @@ struct rndis_device {
enum rndis_device_state state;
bool link_state;
+ bool link_change;
atomic_t new_req_id;
spinlock_t request_lock;
@@ -185,7 +186,7 @@ int netvsc_device_remove(struct hv_device *device);
int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet);
void netvsc_linkstatus_callback(struct hv_device *device_obj,
- unsigned int status);
+ struct rndis_message *resp);
int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
struct ndis_tcp_ip_checksum_info *csum_info);
@@ -584,7 +585,7 @@ struct nvsp_message {
#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
-#define NETVSC_SEND_BUFFER_SIZE (1024 * 1024) /* 1MB */
+#define NETVSC_SEND_BUFFER_SIZE (1024 * 1024 * 15) /* 15MB */
#define NETVSC_INVALID_INDEX -1
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 4ed38eaecea8..66979cf7fca6 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -193,8 +193,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device)
}
if (net_device->send_buf) {
/* Free up the receive buffer */
- free_pages((unsigned long)net_device->send_buf,
- get_order(net_device->send_buf_size));
+ vfree(net_device->send_buf);
net_device->send_buf = NULL;
}
kfree(net_device->send_section_map);
@@ -303,9 +302,7 @@ static int netvsc_init_buf(struct hv_device *device)
/* Now setup the send buffer.
*/
- net_device->send_buf =
- (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
- get_order(net_device->send_buf_size));
+ net_device->send_buf = vzalloc(net_device->send_buf_size);
if (!net_device->send_buf) {
netdev_err(ndev, "unable to allocate send "
"buffer of size %d\n", net_device->send_buf_size);
@@ -378,8 +375,10 @@ static int netvsc_init_buf(struct hv_device *device)
net_device->send_section_map =
kzalloc(net_device->map_words * sizeof(ulong), GFP_KERNEL);
- if (net_device->send_section_map == NULL)
+ if (net_device->send_section_map == NULL) {
+ ret = -ENOMEM;
goto cleanup;
+ }
goto exit;
@@ -1094,9 +1093,7 @@ close:
vmbus_close(device->channel);
cleanup:
-
- if (net_device)
- kfree(net_device);
+ kfree(net_device);
return ret;
}
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 4fd71b75e666..a9c5eaadc426 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -579,8 +579,9 @@ drop:
* netvsc_linkstatus_callback - Link up/down notification
*/
void netvsc_linkstatus_callback(struct hv_device *device_obj,
- unsigned int status)
+ struct rndis_message *resp)
{
+ struct rndis_indicate_status *indicate = &resp->msg.indicate_status;
struct net_device *net;
struct net_device_context *ndev_ctx;
struct netvsc_device *net_device;
@@ -589,7 +590,19 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
net_device = hv_get_drvdata(device_obj);
rdev = net_device->extension;
- rdev->link_state = status != 1;
+ switch (indicate->status) {
+ case RNDIS_STATUS_MEDIA_CONNECT:
+ rdev->link_state = false;
+ break;
+ case RNDIS_STATUS_MEDIA_DISCONNECT:
+ rdev->link_state = true;
+ break;
+ case RNDIS_STATUS_NETWORK_CHANGE:
+ rdev->link_change = true;
+ break;
+ default:
+ return;
+ }
net = net_device->ndev;
@@ -597,7 +610,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
return;
ndev_ctx = netdev_priv(net);
- if (status == 1) {
+ if (!rdev->link_state) {
schedule_delayed_work(&ndev_ctx->dwork, 0);
schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
} else {
@@ -736,6 +749,14 @@ static int netvsc_set_mac_addr(struct net_device *ndev, void *p)
return err;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void netvsc_poll_controller(struct net_device *net)
+{
+ /* As netvsc_start_xmit() works synchronous we don't have to
+ * trigger anything here.
+ */
+}
+#endif
static const struct ethtool_ops ethtool_ops = {
.get_drvinfo = netvsc_get_drvinfo,
@@ -751,6 +772,9 @@ static const struct net_device_ops device_ops = {
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = netvsc_set_mac_addr,
.ndo_select_queue = netvsc_select_queue,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = netvsc_poll_controller,
+#endif
};
/*
@@ -767,7 +791,9 @@ static void netvsc_link_change(struct work_struct *w)
struct net_device *net;
struct netvsc_device *net_device;
struct rndis_device *rdev;
- bool notify;
+ bool notify, refresh = false;
+ char *argv[] = { "/etc/init.d/network", "restart", NULL };
+ char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
rtnl_lock();
@@ -782,10 +808,17 @@ static void netvsc_link_change(struct work_struct *w)
} else {
netif_carrier_on(net);
notify = true;
+ if (rdev->link_change) {
+ rdev->link_change = false;
+ refresh = true;
+ }
}
rtnl_unlock();
+ if (refresh)
+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+
if (notify)
netdev_notify_peers(net);
}
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 99c527adae5b..2b86f0b6f6d1 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -320,25 +320,6 @@ static void rndis_filter_receive_response(struct rndis_device *dev,
}
}
-static void rndis_filter_receive_indicate_status(struct rndis_device *dev,
- struct rndis_message *resp)
-{
- struct rndis_indicate_status *indicate =
- &resp->msg.indicate_status;
-
- if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
- netvsc_linkstatus_callback(
- dev->net_dev->dev, 1);
- } else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
- netvsc_linkstatus_callback(
- dev->net_dev->dev, 0);
- } else {
- /*
- * TODO:
- */
- }
-}
-
/*
* Get the Per-Packet-Info with the specified type
* return NULL if not found.
@@ -464,7 +445,7 @@ int rndis_filter_receive(struct hv_device *dev,
case RNDIS_MSG_INDICATE:
/* notification msgs */
- rndis_filter_receive_indicate_status(rndis_dev, rndis_msg);
+ netvsc_linkstatus_callback(dev, rndis_msg);
break;
default:
netdev_err(ndev,
diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
index 3e89beab64fd..391a916622a9 100644
--- a/drivers/net/ieee802154/Kconfig
+++ b/drivers/net/ieee802154/Kconfig
@@ -34,6 +34,7 @@ config IEEE802154_AT86RF230
depends on IEEE802154_DRIVERS && MAC802154
tristate "AT86RF230/231/233/212 transceiver driver"
depends on SPI
+ select REGMAP_SPI
---help---
Say Y here to enable the at86rf230/231/233/212 SPI 802.15.4 wireless
controller.
@@ -51,3 +52,14 @@ config IEEE802154_MRF24J40
This driver can also be built as a module. To do so, say M here.
the module will be called 'mrf24j40'.
+
+config IEEE802154_CC2520
+ depends on IEEE802154_DRIVERS && MAC802154
+ tristate "CC2520 transceiver driver"
+ depends on SPI
+ ---help---
+ Say Y here to enable the CC2520 SPI 802.15.4 wireless
+ controller.
+
+ This driver can also be built as a module. To do so, say M here.
+ the module will be called 'cc2520'.
diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile
index abb0c08decb0..655cb95e6e24 100644
--- a/drivers/net/ieee802154/Makefile
+++ b/drivers/net/ieee802154/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
+obj-$(CONFIG_IEEE802154_CC2520) += cc2520.o
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index 50899416f668..c9d2a752abd7 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -19,6 +19,7 @@
* Written by:
* Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
* Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
+ * Alexander Aring <aar@pengutronix.de>
*/
#include <linux/kernel.h>
#include <linux/module.h>
@@ -26,43 +27,75 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/spi/spi.h>
#include <linux/spi/at86rf230.h>
+#include <linux/regmap.h>
#include <linux/skbuff.h>
#include <linux/of_gpio.h>
+#include <net/ieee802154.h>
#include <net/mac802154.h>
#include <net/wpan-phy.h>
-struct at86rf230_local {
- struct spi_device *spi;
+struct at86rf230_local;
+/* at86rf2xx chip depend data.
+ * All timings are in us.
+ */
+struct at86rf2xx_chip_data {
+ u16 t_sleep_cycle;
+ u16 t_channel_switch;
+ u16 t_reset_to_off;
+ u16 t_off_to_aack;
+ u16 t_off_to_tx_on;
+ u16 t_frame;
+ u16 t_p_ack;
+ /* short interframe spacing time */
+ u16 t_sifs;
+ /* long interframe spacing time */
+ u16 t_lifs;
+ /* completion timeout for tx in msecs */
+ u16 t_tx_timeout;
+ int rssi_base_val;
- u8 part;
- u8 vers;
+ int (*set_channel)(struct at86rf230_local *, int, int);
+ int (*get_desense_steps)(struct at86rf230_local *, s32);
+};
- u8 buf[2];
- struct mutex bmux;
+#define AT86RF2XX_MAX_BUF (127 + 3)
- struct work_struct irqwork;
- struct completion tx_complete;
+struct at86rf230_state_change {
+ struct at86rf230_local *lp;
+
+ struct spi_message msg;
+ struct spi_transfer trx;
+ u8 buf[AT86RF2XX_MAX_BUF];
+
+ void (*complete)(void *context);
+ u8 from_state;
+ u8 to_state;
+};
+
+struct at86rf230_local {
+ struct spi_device *spi;
struct ieee802154_dev *dev;
+ struct at86rf2xx_chip_data *data;
+ struct regmap *regmap;
- spinlock_t lock;
- bool irq_busy;
- bool is_tx;
- bool tx_aret;
+ struct completion state_complete;
+ struct at86rf230_state_change state;
- int rssi_base_val;
-};
+ struct at86rf230_state_change irq;
-static bool is_rf212(struct at86rf230_local *local)
-{
- return local->part == 7;
-}
+ bool tx_aret;
+ bool is_tx;
+ /* spinlock for is_tx protection */
+ spinlock_t lock;
+ struct completion tx_complete;
+ struct sk_buff *tx_skb;
+ struct at86rf230_state_change tx;
+};
#define RG_TRX_STATUS (0x01)
#define SR_TRX_STATUS 0x01, 0x1f, 0
@@ -256,344 +289,753 @@ static bool is_rf212(struct at86rf230_local *local)
#define STATE_BUSY_RX_AACK_NOCLK 0x1E
#define STATE_TRANSITION_IN_PROGRESS 0x1F
+#define AT86RF2XX_NUMREGS 0x3F
+
static int
-__at86rf230_detect_device(struct spi_device *spi, u16 *man_id, u8 *part,
- u8 *version)
+at86rf230_async_state_change(struct at86rf230_local *lp,
+ struct at86rf230_state_change *ctx,
+ const u8 state, void (*complete)(void *context));
+
+static inline int
+__at86rf230_write(struct at86rf230_local *lp,
+ unsigned int addr, unsigned int data)
{
- u8 data[4];
- u8 *buf = kmalloc(2, GFP_KERNEL);
- int status;
- struct spi_message msg;
- struct spi_transfer xfer = {
- .len = 2,
- .tx_buf = buf,
- .rx_buf = buf,
- };
- u8 reg;
-
- if (!buf)
- return -ENOMEM;
+ return regmap_write(lp->regmap, addr, data);
+}
- for (reg = RG_PART_NUM; reg <= RG_MAN_ID_1; reg++) {
- buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
- buf[1] = 0xff;
- dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
+static inline int
+__at86rf230_read(struct at86rf230_local *lp,
+ unsigned int addr, unsigned int *data)
+{
+ return regmap_read(lp->regmap, addr, data);
+}
- status = spi_sync(spi, &msg);
- dev_vdbg(&spi->dev, "status = %d\n", status);
- if (msg.status)
- status = msg.status;
+static inline int
+at86rf230_read_subreg(struct at86rf230_local *lp,
+ unsigned int addr, unsigned int mask,
+ unsigned int shift, unsigned int *data)
+{
+ int rc;
- dev_vdbg(&spi->dev, "status = %d\n", status);
- dev_vdbg(&spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&spi->dev, "buf[1] = %02x\n", buf[1]);
+ rc = __at86rf230_read(lp, addr, data);
+ if (rc > 0)
+ *data = (*data & mask) >> shift;
- if (status == 0)
- data[reg - RG_PART_NUM] = buf[1];
- else
- break;
+ return rc;
+}
+
+static inline int
+at86rf230_write_subreg(struct at86rf230_local *lp,
+ unsigned int addr, unsigned int mask,
+ unsigned int shift, unsigned int data)
+{
+ return regmap_update_bits(lp->regmap, addr, mask, data << shift);
+}
+
+static bool
+at86rf230_reg_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case RG_TRX_STATE:
+ case RG_TRX_CTRL_0:
+ case RG_TRX_CTRL_1:
+ case RG_PHY_TX_PWR:
+ case RG_PHY_ED_LEVEL:
+ case RG_PHY_CC_CCA:
+ case RG_CCA_THRES:
+ case RG_RX_CTRL:
+ case RG_SFD_VALUE:
+ case RG_TRX_CTRL_2:
+ case RG_ANT_DIV:
+ case RG_IRQ_MASK:
+ case RG_VREG_CTRL:
+ case RG_BATMON:
+ case RG_XOSC_CTRL:
+ case RG_RX_SYN:
+ case RG_XAH_CTRL_1:
+ case RG_FTN_CTRL:
+ case RG_PLL_CF:
+ case RG_PLL_DCU:
+ case RG_SHORT_ADDR_0:
+ case RG_SHORT_ADDR_1:
+ case RG_PAN_ID_0:
+ case RG_PAN_ID_1:
+ case RG_IEEE_ADDR_0:
+ case RG_IEEE_ADDR_1:
+ case RG_IEEE_ADDR_2:
+ case RG_IEEE_ADDR_3:
+ case RG_IEEE_ADDR_4:
+ case RG_IEEE_ADDR_5:
+ case RG_IEEE_ADDR_6:
+ case RG_IEEE_ADDR_7:
+ case RG_XAH_CTRL_0:
+ case RG_CSMA_SEED_0:
+ case RG_CSMA_SEED_1:
+ case RG_CSMA_BE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+at86rf230_reg_readable(struct device *dev, unsigned int reg)
+{
+ bool rc;
+
+ /* all writeable are also readable */
+ rc = at86rf230_reg_writeable(dev, reg);
+ if (rc)
+ return rc;
+
+ /* readonly regs */
+ switch (reg) {
+ case RG_TRX_STATUS:
+ case RG_PHY_RSSI:
+ case RG_IRQ_STATUS:
+ case RG_PART_NUM:
+ case RG_VERSION_NUM:
+ case RG_MAN_ID_1:
+ case RG_MAN_ID_0:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+at86rf230_reg_volatile(struct device *dev, unsigned int reg)
+{
+ /* can be changed during runtime */
+ switch (reg) {
+ case RG_TRX_STATUS:
+ case RG_TRX_STATE:
+ case RG_PHY_RSSI:
+ case RG_PHY_ED_LEVEL:
+ case RG_IRQ_STATUS:
+ case RG_VREG_CTRL:
+ return true;
+ default:
+ return false;
}
+}
- if (status == 0) {
- *part = data[0];
- *version = data[1];
- *man_id = (data[3] << 8) | data[2];
+static bool
+at86rf230_reg_precious(struct device *dev, unsigned int reg)
+{
+ /* don't clear irq line on read */
+ switch (reg) {
+ case RG_IRQ_STATUS:
+ return true;
+ default:
+ return false;
}
+}
- kfree(buf);
+static struct regmap_config at86rf230_regmap_spi_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .write_flag_mask = CMD_REG | CMD_WRITE,
+ .read_flag_mask = CMD_REG,
+ .cache_type = REGCACHE_RBTREE,
+ .max_register = AT86RF2XX_NUMREGS,
+ .writeable_reg = at86rf230_reg_writeable,
+ .readable_reg = at86rf230_reg_readable,
+ .volatile_reg = at86rf230_reg_volatile,
+ .precious_reg = at86rf230_reg_precious,
+};
- return status;
+static void
+at86rf230_async_error_recover(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+
+ at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL);
}
-static int
-__at86rf230_write(struct at86rf230_local *lp, u8 addr, u8 data)
+static void
+at86rf230_async_error(struct at86rf230_local *lp,
+ struct at86rf230_state_change *ctx, int rc)
{
- u8 *buf = lp->buf;
- int status;
- struct spi_message msg;
- struct spi_transfer xfer = {
- .len = 2,
- .tx_buf = buf,
- };
-
- buf[0] = (addr & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
- buf[1] = data;
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
-
- status = spi_sync(lp->spi, &msg);
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- if (msg.status)
- status = msg.status;
-
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
-
- return status;
+ dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
+
+ at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
+ at86rf230_async_error_recover);
}
+/* Generic function to get some register value in async mode */
static int
-__at86rf230_read_subreg(struct at86rf230_local *lp,
- u8 addr, u8 mask, int shift, u8 *data)
+at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
+ struct at86rf230_state_change *ctx,
+ void (*complete)(void *context))
{
- u8 *buf = lp->buf;
- int status;
- struct spi_message msg;
- struct spi_transfer xfer = {
- .len = 2,
- .tx_buf = buf,
- .rx_buf = buf,
- };
-
- buf[0] = (addr & CMD_REG_MASK) | CMD_REG;
- buf[1] = 0xff;
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- spi_message_init(&msg);
- spi_message_add_tail(&xfer, &msg);
-
- status = spi_sync(lp->spi, &msg);
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- if (msg.status)
- status = msg.status;
-
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
-
- if (status == 0)
- *data = (buf[1] & mask) >> shift;
-
- return status;
+ u8 *tx_buf = ctx->buf;
+
+ tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
+ ctx->trx.len = 2;
+ ctx->msg.complete = complete;
+ return spi_async(lp->spi, &ctx->msg);
}
-static int
-at86rf230_read_subreg(struct at86rf230_local *lp,
- u8 addr, u8 mask, int shift, u8 *data)
+static void
+at86rf230_async_state_assert(void *context)
{
- int status;
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ const u8 *buf = ctx->buf;
+ const u8 trx_state = buf[1] & 0x1f;
+
+ /* Assert state change */
+ if (trx_state != ctx->to_state) {
+ /* Special handling if transceiver state is in
+ * STATE_BUSY_RX_AACK and a SHR was detected.
+ */
+ if (trx_state == STATE_BUSY_RX_AACK) {
+ /* Undocumented race condition. If we send a state
+ * change to STATE_RX_AACK_ON the transceiver could
+ * change his state automatically to STATE_BUSY_RX_AACK
+ * if a SHR was detected. This is not an error, but we
+ * can't assert this.
+ */
+ if (ctx->to_state == STATE_RX_AACK_ON)
+ goto done;
+
+ /* If we change to STATE_TX_ON without forcing and
+ * transceiver state is STATE_BUSY_RX_AACK, we wait
+ * 'tFrame + tPAck' receiving time. In this time the
+ * PDU should be received. If the transceiver is still
+ * in STATE_BUSY_RX_AACK, we run a force state change
+ * to STATE_TX_ON. This is a timeout handling, if the
+ * transceiver stucks in STATE_BUSY_RX_AACK.
+ */
+ if (ctx->to_state == STATE_TX_ON) {
+ at86rf230_async_state_change(lp, ctx,
+ STATE_FORCE_TX_ON,
+ ctx->complete);
+ return;
+ }
+ }
+
- mutex_lock(&lp->bmux);
- status = __at86rf230_read_subreg(lp, addr, mask, shift, data);
- mutex_unlock(&lp->bmux);
+ dev_warn(&lp->spi->dev, "unexcept state change from 0x%02x to 0x%02x. Actual state: 0x%02x\n",
+ ctx->from_state, ctx->to_state, trx_state);
+ }
- return status;
+done:
+ if (ctx->complete)
+ ctx->complete(context);
}
-static int
-at86rf230_write_subreg(struct at86rf230_local *lp,
- u8 addr, u8 mask, int shift, u8 data)
+/* Do state change timing delay. */
+static void
+at86rf230_async_state_delay(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ struct at86rf2xx_chip_data *c = lp->data;
+ bool force = false;
+ int rc;
+
+ /* The force state changes are will show as normal states in the
+ * state status subregister. We change the to_state to the
+ * corresponding one and remember if it was a force change, this
+ * differs if we do a state change from STATE_BUSY_RX_AACK.
+ */
+ switch (ctx->to_state) {
+ case STATE_FORCE_TX_ON:
+ ctx->to_state = STATE_TX_ON;
+ force = true;
+ break;
+ case STATE_FORCE_TRX_OFF:
+ ctx->to_state = STATE_TRX_OFF;
+ force = true;
+ break;
+ default:
+ break;
+ }
+
+ switch (ctx->from_state) {
+ case STATE_TRX_OFF:
+ switch (ctx->to_state) {
+ case STATE_RX_AACK_ON:
+ usleep_range(c->t_off_to_aack, c->t_off_to_aack + 10);
+ goto change;
+ case STATE_TX_ON:
+ usleep_range(c->t_off_to_tx_on,
+ c->t_off_to_tx_on + 10);
+ goto change;
+ default:
+ break;
+ }
+ break;
+ case STATE_BUSY_RX_AACK:
+ switch (ctx->to_state) {
+ case STATE_TX_ON:
+ /* Wait for worst case receiving time if we
+ * didn't make a force change from BUSY_RX_AACK
+ * to TX_ON.
+ */
+ if (!force) {
+ usleep_range(c->t_frame + c->t_p_ack,
+ c->t_frame + c->t_p_ack + 1000);
+ goto change;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ /* Default value, means RESET state */
+ case STATE_P_ON:
+ switch (ctx->to_state) {
+ case STATE_TRX_OFF:
+ usleep_range(c->t_reset_to_off, c->t_reset_to_off + 10);
+ goto change;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Default delay is 1us in the most cases */
+ udelay(1);
+
+change:
+ rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
+ at86rf230_async_state_assert);
+ if (rc)
+ dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
+}
+
+static void
+at86rf230_async_state_change_start(void *context)
{
- int status;
- u8 val;
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ u8 *buf = ctx->buf;
+ const u8 trx_state = buf[1] & 0x1f;
+ int rc;
- mutex_lock(&lp->bmux);
- status = __at86rf230_read_subreg(lp, addr, 0xff, 0, &val);
- if (status)
- goto out;
+ /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
+ if (trx_state == STATE_TRANSITION_IN_PROGRESS) {
+ udelay(1);
+ rc = at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
+ at86rf230_async_state_change_start);
+ if (rc)
+ dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
+ return;
+ }
- val &= ~mask;
- val |= (data << shift) & mask;
+ /* Check if we already are in the state which we change in */
+ if (trx_state == ctx->to_state) {
+ if (ctx->complete)
+ ctx->complete(context);
+ return;
+ }
- status = __at86rf230_write(lp, addr, val);
-out:
- mutex_unlock(&lp->bmux);
+ /* Set current state to the context of state change */
+ ctx->from_state = trx_state;
- return status;
+ /* Going into the next step for a state change which do a timing
+ * relevant delay.
+ */
+ buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
+ buf[1] = ctx->to_state;
+ ctx->trx.len = 2;
+ ctx->msg.complete = at86rf230_async_state_delay;
+ rc = spi_async(lp->spi, &ctx->msg);
+ if (rc)
+ dev_err(&lp->spi->dev, "spi_async error %d\n", rc);
}
static int
-at86rf230_write_fbuf(struct at86rf230_local *lp, u8 *data, u8 len)
+at86rf230_async_state_change(struct at86rf230_local *lp,
+ struct at86rf230_state_change *ctx,
+ const u8 state, void (*complete)(void *context))
{
- u8 *buf = lp->buf;
- int status;
- struct spi_message msg;
- struct spi_transfer xfer_head = {
- .len = 2,
- .tx_buf = buf,
-
- };
- struct spi_transfer xfer_buf = {
- .len = len,
- .tx_buf = data,
- };
-
- mutex_lock(&lp->bmux);
- buf[0] = CMD_WRITE | CMD_FB;
- buf[1] = len + 2; /* 2 bytes for CRC that isn't written */
-
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
-
- spi_message_init(&msg);
- spi_message_add_tail(&xfer_head, &msg);
- spi_message_add_tail(&xfer_buf, &msg);
-
- status = spi_sync(lp->spi, &msg);
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- if (msg.status)
- status = msg.status;
-
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
-
- mutex_unlock(&lp->bmux);
- return status;
+ /* Initialization for the state change context */
+ ctx->to_state = state;
+ ctx->complete = complete;
+ return at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
+ at86rf230_async_state_change_start);
}
+static void
+at86rf230_sync_state_change_complete(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+
+ complete(&lp->state_complete);
+}
+
+/* This function do a sync framework above the async state change.
+ * Some callbacks of the IEEE 802.15.4 driver interface need to be
+ * handled synchronously.
+ */
static int
-at86rf230_read_fbuf(struct at86rf230_local *lp, u8 *data, u8 *len, u8 *lqi)
+at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state)
{
- u8 *buf = lp->buf;
- int status;
- struct spi_message msg;
- struct spi_transfer xfer_head = {
- .len = 2,
- .tx_buf = buf,
- .rx_buf = buf,
- };
- struct spi_transfer xfer_head1 = {
- .len = 2,
- .tx_buf = buf,
- .rx_buf = buf,
- };
- struct spi_transfer xfer_buf = {
- .len = 0,
- .rx_buf = data,
- };
-
- mutex_lock(&lp->bmux);
+ int rc;
- buf[0] = CMD_FB;
- buf[1] = 0x00;
+ rc = at86rf230_async_state_change(lp, &lp->state, state,
+ at86rf230_sync_state_change_complete);
+ if (rc) {
+ at86rf230_async_error(lp, &lp->state, rc);
+ return rc;
+ }
- spi_message_init(&msg);
- spi_message_add_tail(&xfer_head, &msg);
+ rc = wait_for_completion_timeout(&lp->state_complete,
+ msecs_to_jiffies(100));
+ if (!rc)
+ return -ETIMEDOUT;
- status = spi_sync(lp->spi, &msg);
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
+ return 0;
+}
- xfer_buf.len = *(buf + 1) + 1;
- *len = buf[1];
+static void
+at86rf230_tx_complete(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
- buf[0] = CMD_FB;
- buf[1] = 0x00;
+ complete(&lp->tx_complete);
+}
- spi_message_init(&msg);
- spi_message_add_tail(&xfer_head1, &msg);
- spi_message_add_tail(&xfer_buf, &msg);
+static void
+at86rf230_tx_on(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ int rc;
+
+ rc = at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON,
+ at86rf230_tx_complete);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+}
- status = spi_sync(lp->spi, &msg);
+static void
+at86rf230_tx_trac_error(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ int rc;
- if (msg.status)
- status = msg.status;
+ rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
+ at86rf230_tx_on);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+}
- dev_vdbg(&lp->spi->dev, "status = %d\n", status);
- dev_vdbg(&lp->spi->dev, "buf[0] = %02x\n", buf[0]);
- dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]);
+static void
+at86rf230_tx_trac_check(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ const u8 *buf = ctx->buf;
+ const u8 trac = (buf[1] & 0xe0) >> 5;
+ int rc;
- if (status) {
- if (lqi && (*len > lp->buf[1]))
- *lqi = data[lp->buf[1]];
+ /* If trac status is different than zero we need to do a state change
+ * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver
+ * state to TX_ON.
+ */
+ if (trac) {
+ rc = at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
+ at86rf230_tx_trac_error);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+ return;
}
- mutex_unlock(&lp->bmux);
- return status;
+ at86rf230_tx_on(context);
}
-static int
-at86rf230_ed(struct ieee802154_dev *dev, u8 *level)
+
+static void
+at86rf230_tx_trac_status(void *context)
{
- might_sleep();
- BUG_ON(!level);
- *level = 0xbe;
- return 0;
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ int rc;
+
+ rc = at86rf230_async_read_reg(lp, RG_TRX_STATE, ctx,
+ at86rf230_tx_trac_check);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+}
+
+static void
+at86rf230_rx(struct at86rf230_local *lp,
+ const u8 *data, u8 len)
+{
+ u8 lqi;
+ struct sk_buff *skb;
+ u8 rx_local_buf[AT86RF2XX_MAX_BUF];
+
+ if (len < 2)
+ return;
+
+ /* read full frame buffer and invalid lqi value to lowest
+ * indicator if frame was is in a corrupted state.
+ */
+ if (len > IEEE802154_MTU) {
+ lqi = 0;
+ len = IEEE802154_MTU;
+ dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
+ } else {
+ lqi = data[len];
+ }
+
+ memcpy(rx_local_buf, data, len);
+ enable_irq(lp->spi->irq);
+
+ skb = alloc_skb(IEEE802154_MTU, GFP_ATOMIC);
+ if (!skb) {
+ dev_vdbg(&lp->spi->dev, "failed to allocate sk_buff\n");
+ return;
+ }
+
+ memcpy(skb_put(skb, len), rx_local_buf, len);
+
+ /* We do not put CRC into the frame */
+ skb_trim(skb, len - 2);
+
+ ieee802154_rx_irqsafe(lp->dev, skb, lqi);
+}
+
+static void
+at86rf230_rx_read_frame_complete(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ const u8 *buf = lp->irq.buf;
+ const u8 len = buf[1];
+
+ at86rf230_rx(lp, buf + 2, len);
}
static int
-at86rf230_state(struct ieee802154_dev *dev, int state)
+at86rf230_rx_read_frame(struct at86rf230_local *lp)
{
- struct at86rf230_local *lp = dev->priv;
+ u8 *buf = lp->irq.buf;
+
+ buf[0] = CMD_FB;
+ lp->irq.trx.len = AT86RF2XX_MAX_BUF;
+ lp->irq.msg.complete = at86rf230_rx_read_frame_complete;
+ return spi_async(lp->spi, &lp->irq.msg);
+}
+
+static void
+at86rf230_rx_trac_check(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
int rc;
- u8 val;
- u8 desired_status;
- might_sleep();
+ /* Possible check on trac status here. This could be useful to make
+ * some stats why receive is failed. Not used at the moment, but it's
+ * maybe timing relevant. Datasheet doesn't say anything about this.
+ * The programming guide say do it so.
+ */
- if (state == STATE_FORCE_TX_ON)
- desired_status = STATE_TX_ON;
- else if (state == STATE_FORCE_TRX_OFF)
- desired_status = STATE_TRX_OFF;
- else
- desired_status = state;
+ rc = at86rf230_rx_read_frame(lp);
+ if (rc) {
+ enable_irq(lp->spi->irq);
+ at86rf230_async_error(lp, ctx, rc);
+ }
+}
+
+static int
+at86rf230_irq_trx_end(struct at86rf230_local *lp)
+{
+ spin_lock(&lp->lock);
+ if (lp->is_tx) {
+ lp->is_tx = 0;
+ spin_unlock(&lp->lock);
+ enable_irq(lp->spi->irq);
+
+ if (lp->tx_aret)
+ return at86rf230_async_state_change(lp, &lp->irq,
+ STATE_FORCE_TX_ON,
+ at86rf230_tx_trac_status);
+ else
+ return at86rf230_async_state_change(lp, &lp->irq,
+ STATE_RX_AACK_ON,
+ at86rf230_tx_complete);
+ } else {
+ spin_unlock(&lp->lock);
+ return at86rf230_async_read_reg(lp, RG_TRX_STATE, &lp->irq,
+ at86rf230_rx_trac_check);
+ }
+}
- do {
- rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
+static void
+at86rf230_irq_status(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ const u8 *buf = lp->irq.buf;
+ const u8 irq = buf[1];
+ int rc;
+
+ if (irq & IRQ_TRX_END) {
+ rc = at86rf230_irq_trx_end(lp);
if (rc)
- goto err;
- } while (val == STATE_TRANSITION_IN_PROGRESS);
+ at86rf230_async_error(lp, ctx, rc);
+ } else {
+ enable_irq(lp->spi->irq);
+ dev_err(&lp->spi->dev, "not supported irq %02x received\n",
+ irq);
+ }
+}
- if (val == desired_status)
- return 0;
+static irqreturn_t at86rf230_isr(int irq, void *data)
+{
+ struct at86rf230_local *lp = data;
+ struct at86rf230_state_change *ctx = &lp->irq;
+ u8 *buf = ctx->buf;
+ int rc;
- /* state is equal to phy states */
- rc = at86rf230_write_subreg(lp, SR_TRX_CMD, state);
- if (rc)
- goto err;
+ disable_irq_nosync(lp->spi->irq);
- do {
- rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &val);
- if (rc)
- goto err;
- } while (val == STATE_TRANSITION_IN_PROGRESS);
+ buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG;
+ ctx->trx.len = 2;
+ ctx->msg.complete = at86rf230_irq_status;
+ rc = spi_async(lp->spi, &ctx->msg);
+ if (rc) {
+ at86rf230_async_error(lp, ctx, rc);
+ return IRQ_NONE;
+ }
+ return IRQ_HANDLED;
+}
- if (val == desired_status ||
- (desired_status == STATE_RX_ON && val == STATE_BUSY_RX) ||
- (desired_status == STATE_RX_AACK_ON && val == STATE_BUSY_RX_AACK))
- return 0;
+static void
+at86rf230_write_frame_complete(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ u8 *buf = ctx->buf;
+ int rc;
- pr_err("unexpected state change: %d, asked for %d\n", val, state);
- return -EBUSY;
+ buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
+ buf[1] = STATE_BUSY_TX;
+ ctx->trx.len = 2;
+ ctx->msg.complete = NULL;
+ rc = spi_async(lp->spi, &ctx->msg);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+}
-err:
- pr_err("error: %d\n", rc);
- return rc;
+static void
+at86rf230_write_frame(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ struct sk_buff *skb = lp->tx_skb;
+ u8 *buf = lp->tx.buf;
+ int rc;
+
+ spin_lock(&lp->lock);
+ lp->is_tx = 1;
+ spin_unlock(&lp->lock);
+
+ buf[0] = CMD_FB | CMD_WRITE;
+ buf[1] = skb->len + 2;
+ memcpy(buf + 2, skb->data, skb->len);
+ lp->tx.trx.len = skb->len + 2;
+ lp->tx.msg.complete = at86rf230_write_frame_complete;
+ rc = spi_async(lp->spi, &lp->tx.msg);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
+}
+
+static void
+at86rf230_xmit_tx_on(void *context)
+{
+ struct at86rf230_state_change *ctx = context;
+ struct at86rf230_local *lp = ctx->lp;
+ int rc;
+
+ rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
+ at86rf230_write_frame);
+ if (rc)
+ at86rf230_async_error(lp, ctx, rc);
}
static int
-at86rf230_start(struct ieee802154_dev *dev)
+at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
{
struct at86rf230_local *lp = dev->priv;
- u8 rc;
+ struct at86rf230_state_change *ctx = &lp->tx;
- rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
- if (rc)
- return rc;
+ void (*tx_complete)(void *context) = at86rf230_write_frame;
+ int rc;
- rc = at86rf230_state(dev, STATE_TX_ON);
- if (rc)
+ lp->tx_skb = skb;
+
+ /* In ARET mode we need to go into STATE_TX_ARET_ON after we
+ * are in STATE_TX_ON. The pfad differs here, so we change
+ * the complete handler.
+ */
+ if (lp->tx_aret)
+ tx_complete = at86rf230_xmit_tx_on;
+
+ rc = at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
+ tx_complete);
+ if (rc) {
+ at86rf230_async_error(lp, ctx, rc);
return rc;
+ }
+ rc = wait_for_completion_interruptible_timeout(&lp->tx_complete,
+ msecs_to_jiffies(lp->data->t_tx_timeout));
+ if (!rc) {
+ at86rf230_async_error(lp, ctx, rc);
+ return -ETIMEDOUT;
+ }
+
+ /* Interfame spacing time, which is phy depend.
+ * TODO
+ * Move this handling in MAC 802.15.4 layer.
+ * This is currently a workaround to avoid fragmenation issues.
+ */
+ if (skb->len > 18)
+ usleep_range(lp->data->t_lifs, lp->data->t_lifs + 10);
+ else
+ usleep_range(lp->data->t_sifs, lp->data->t_sifs + 10);
+
+ return 0;
+}
- return at86rf230_state(dev, STATE_RX_AACK_ON);
+static int
+at86rf230_ed(struct ieee802154_dev *dev, u8 *level)
+{
+ might_sleep();
+ BUG_ON(!level);
+ *level = 0xbe;
+ return 0;
+}
+
+static int
+at86rf230_start(struct ieee802154_dev *dev)
+{
+ return at86rf230_sync_state_change(dev->priv, STATE_RX_AACK_ON);
}
static void
at86rf230_stop(struct ieee802154_dev *dev)
{
- at86rf230_state(dev, STATE_FORCE_TRX_OFF);
+ at86rf230_sync_state_change(dev->priv, STATE_FORCE_TRX_OFF);
}
static int
-at86rf230_set_channel(struct at86rf230_local *lp, int page, int channel)
+at86rf23x_set_channel(struct at86rf230_local *lp, int page, int channel)
{
- lp->rssi_base_val = -91;
-
return at86rf230_write_subreg(lp, SR_CHANNEL, channel);
}
@@ -611,10 +1053,10 @@ at86rf212_set_channel(struct at86rf230_local *lp, int page, int channel)
if (page == 0) {
rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 0);
- lp->rssi_base_val = -100;
+ lp->data->rssi_base_val = -100;
} else {
rc = at86rf230_write_subreg(lp, SR_BPSK_QPSK, 1);
- lp->rssi_base_val = -98;
+ lp->data->rssi_base_val = -98;
}
if (rc < 0)
return rc;
@@ -636,14 +1078,13 @@ at86rf230_channel(struct ieee802154_dev *dev, int page, int channel)
return -EINVAL;
}
- if (is_rf212(lp))
- rc = at86rf212_set_channel(lp, page, channel);
- else
- rc = at86rf230_set_channel(lp, page, channel);
+ rc = lp->data->set_channel(lp, page, channel);
if (rc < 0)
return rc;
- msleep(1); /* Wait for PLL */
+ /* Wait for PLL */
+ usleep_range(lp->data->t_channel_switch,
+ lp->data->t_channel_switch + 10);
dev->phy->current_channel = channel;
dev->phy->current_page = page;
@@ -651,92 +1092,6 @@ at86rf230_channel(struct ieee802154_dev *dev, int page, int channel)
}
static int
-at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
-{
- struct at86rf230_local *lp = dev->priv;
- int rc;
- unsigned long flags;
-
- spin_lock_irqsave(&lp->lock, flags);
- if (lp->irq_busy) {
- spin_unlock_irqrestore(&lp->lock, flags);
- return -EBUSY;
- }
- spin_unlock_irqrestore(&lp->lock, flags);
-
- might_sleep();
-
- rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
- if (rc)
- goto err;
-
- spin_lock_irqsave(&lp->lock, flags);
- lp->is_tx = 1;
- reinit_completion(&lp->tx_complete);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- rc = at86rf230_write_fbuf(lp, skb->data, skb->len);
- if (rc)
- goto err_rx;
-
- if (lp->tx_aret) {
- rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_TX_ARET_ON);
- if (rc)
- goto err_rx;
- }
-
- rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_BUSY_TX);
- if (rc)
- goto err_rx;
-
- rc = wait_for_completion_interruptible(&lp->tx_complete);
- if (rc < 0)
- goto err_rx;
-
- return at86rf230_start(dev);
-err_rx:
- at86rf230_start(dev);
-err:
- pr_err("error: %d\n", rc);
-
- spin_lock_irqsave(&lp->lock, flags);
- lp->is_tx = 0;
- spin_unlock_irqrestore(&lp->lock, flags);
-
- return rc;
-}
-
-static int at86rf230_rx(struct at86rf230_local *lp)
-{
- u8 len = 128, lqi = 0;
- struct sk_buff *skb;
-
- skb = alloc_skb(len, GFP_KERNEL);
-
- if (!skb)
- return -ENOMEM;
-
- if (at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi))
- goto err;
-
- if (len < 2)
- goto err;
-
- skb_trim(skb, len - 2); /* We do not put CRC into the frame */
-
- ieee802154_rx_irqsafe(lp->dev, skb, lqi);
-
- dev_dbg(&lp->spi->dev, "READ_FBUF: %d %x\n", len, lqi);
-
- return 0;
-err:
- pr_debug("received frame is too small\n");
-
- kfree_skb(skb);
- return -EINVAL;
-}
-
-static int
at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev,
struct ieee802154_hw_addr_filt *filt,
unsigned long changed)
@@ -784,7 +1139,7 @@ at86rf230_set_hw_addr_filt(struct ieee802154_dev *dev,
}
static int
-at86rf212_set_txpower(struct ieee802154_dev *dev, int db)
+at86rf230_set_txpower(struct ieee802154_dev *dev, int db)
{
struct at86rf230_local *lp = dev->priv;
@@ -803,7 +1158,7 @@ at86rf212_set_txpower(struct ieee802154_dev *dev, int db)
}
static int
-at86rf212_set_lbt(struct ieee802154_dev *dev, bool on)
+at86rf230_set_lbt(struct ieee802154_dev *dev, bool on)
{
struct at86rf230_local *lp = dev->priv;
@@ -811,7 +1166,7 @@ at86rf212_set_lbt(struct ieee802154_dev *dev, bool on)
}
static int
-at86rf212_set_cca_mode(struct ieee802154_dev *dev, u8 mode)
+at86rf230_set_cca_mode(struct ieee802154_dev *dev, u8 mode)
{
struct at86rf230_local *lp = dev->priv;
@@ -819,21 +1174,31 @@ at86rf212_set_cca_mode(struct ieee802154_dev *dev, u8 mode)
}
static int
-at86rf212_set_cca_ed_level(struct ieee802154_dev *dev, s32 level)
+at86rf212_get_desens_steps(struct at86rf230_local *lp, s32 level)
+{
+ return (level - lp->data->rssi_base_val) * 100 / 207;
+}
+
+static int
+at86rf23x_get_desens_steps(struct at86rf230_local *lp, s32 level)
+{
+ return (level - lp->data->rssi_base_val) / 2;
+}
+
+static int
+at86rf230_set_cca_ed_level(struct ieee802154_dev *dev, s32 level)
{
struct at86rf230_local *lp = dev->priv;
- int desens_steps;
- if (level < lp->rssi_base_val || level > 30)
+ if (level < lp->data->rssi_base_val || level > 30)
return -EINVAL;
- desens_steps = (level - lp->rssi_base_val) * 100 / 207;
-
- return at86rf230_write_subreg(lp, SR_CCA_ED_THRES, desens_steps);
+ return at86rf230_write_subreg(lp, SR_CCA_ED_THRES,
+ lp->data->get_desense_steps(lp, level));
}
static int
-at86rf212_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be,
+at86rf230_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be,
u8 retries)
{
struct at86rf230_local *lp = dev->priv;
@@ -854,7 +1219,7 @@ at86rf212_set_csma_params(struct ieee802154_dev *dev, u8 min_be, u8 max_be,
}
static int
-at86rf212_set_frame_retries(struct ieee802154_dev *dev, s8 retries)
+at86rf230_set_frame_retries(struct ieee802154_dev *dev, s8 retries)
{
struct at86rf230_local *lp = dev->priv;
int rc = 0;
@@ -878,110 +1243,84 @@ static struct ieee802154_ops at86rf230_ops = {
.start = at86rf230_start,
.stop = at86rf230_stop,
.set_hw_addr_filt = at86rf230_set_hw_addr_filt,
+ .set_txpower = at86rf230_set_txpower,
+ .set_lbt = at86rf230_set_lbt,
+ .set_cca_mode = at86rf230_set_cca_mode,
+ .set_cca_ed_level = at86rf230_set_cca_ed_level,
+ .set_csma_params = at86rf230_set_csma_params,
+ .set_frame_retries = at86rf230_set_frame_retries,
};
-static struct ieee802154_ops at86rf212_ops = {
- .owner = THIS_MODULE,
- .xmit = at86rf230_xmit,
- .ed = at86rf230_ed,
- .set_channel = at86rf230_channel,
- .start = at86rf230_start,
- .stop = at86rf230_stop,
- .set_hw_addr_filt = at86rf230_set_hw_addr_filt,
- .set_txpower = at86rf212_set_txpower,
- .set_lbt = at86rf212_set_lbt,
- .set_cca_mode = at86rf212_set_cca_mode,
- .set_cca_ed_level = at86rf212_set_cca_ed_level,
- .set_csma_params = at86rf212_set_csma_params,
- .set_frame_retries = at86rf212_set_frame_retries,
+static struct at86rf2xx_chip_data at86rf233_data = {
+ .t_sleep_cycle = 330,
+ .t_channel_switch = 11,
+ .t_reset_to_off = 26,
+ .t_off_to_aack = 80,
+ .t_off_to_tx_on = 80,
+ .t_frame = 4096,
+ .t_p_ack = 545,
+ .t_sifs = 192,
+ .t_lifs = 480,
+ .t_tx_timeout = 2000,
+ .rssi_base_val = -91,
+ .set_channel = at86rf23x_set_channel,
+ .get_desense_steps = at86rf23x_get_desens_steps
};
-static void at86rf230_irqwork(struct work_struct *work)
-{
- struct at86rf230_local *lp =
- container_of(work, struct at86rf230_local, irqwork);
- u8 status = 0, val;
- int rc;
- unsigned long flags;
-
- rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
- status |= val;
-
- status &= ~IRQ_PLL_LOCK; /* ignore */
- status &= ~IRQ_RX_START; /* ignore */
- status &= ~IRQ_AMI; /* ignore */
- status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
-
- if (status & IRQ_TRX_END) {
- status &= ~IRQ_TRX_END;
- spin_lock_irqsave(&lp->lock, flags);
- if (lp->is_tx) {
- lp->is_tx = 0;
- spin_unlock_irqrestore(&lp->lock, flags);
- complete(&lp->tx_complete);
- } else {
- spin_unlock_irqrestore(&lp->lock, flags);
- at86rf230_rx(lp);
- }
- }
-
- spin_lock_irqsave(&lp->lock, flags);
- lp->irq_busy = 0;
- spin_unlock_irqrestore(&lp->lock, flags);
-}
-
-static void at86rf230_irqwork_level(struct work_struct *work)
-{
- struct at86rf230_local *lp =
- container_of(work, struct at86rf230_local, irqwork);
-
- at86rf230_irqwork(work);
-
- enable_irq(lp->spi->irq);
-}
-
-static irqreturn_t at86rf230_isr(int irq, void *data)
-{
- struct at86rf230_local *lp = data;
- unsigned long flags;
-
- spin_lock_irqsave(&lp->lock, flags);
- lp->irq_busy = 1;
- spin_unlock_irqrestore(&lp->lock, flags);
-
- schedule_work(&lp->irqwork);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t at86rf230_isr_level(int irq, void *data)
-{
- disable_irq_nosync(irq);
+static struct at86rf2xx_chip_data at86rf231_data = {
+ .t_sleep_cycle = 330,
+ .t_channel_switch = 24,
+ .t_reset_to_off = 37,
+ .t_off_to_aack = 110,
+ .t_off_to_tx_on = 110,
+ .t_frame = 4096,
+ .t_p_ack = 545,
+ .t_sifs = 192,
+ .t_lifs = 480,
+ .t_tx_timeout = 2000,
+ .rssi_base_val = -91,
+ .set_channel = at86rf23x_set_channel,
+ .get_desense_steps = at86rf23x_get_desens_steps
+};
- return at86rf230_isr(irq, data);
-}
+static struct at86rf2xx_chip_data at86rf212_data = {
+ .t_sleep_cycle = 330,
+ .t_channel_switch = 11,
+ .t_reset_to_off = 26,
+ .t_off_to_aack = 200,
+ .t_off_to_tx_on = 200,
+ .t_frame = 4096,
+ .t_p_ack = 545,
+ .t_sifs = 192,
+ .t_lifs = 480,
+ .t_tx_timeout = 2000,
+ .rssi_base_val = -100,
+ .set_channel = at86rf212_set_channel,
+ .get_desense_steps = at86rf212_get_desens_steps
+};
static int at86rf230_hw_init(struct at86rf230_local *lp)
{
- int rc, irq_pol, irq_type;
- u8 dvdd;
+ int rc, irq_type, irq_pol = IRQ_ACTIVE_HIGH;
+ unsigned int dvdd;
u8 csma_seed[2];
- rc = at86rf230_write_subreg(lp, SR_TRX_CMD, STATE_FORCE_TRX_OFF);
+ rc = at86rf230_sync_state_change(lp, STATE_FORCE_TRX_OFF);
if (rc)
return rc;
irq_type = irq_get_trigger_type(lp->spi->irq);
- /* configure irq polarity, defaults to high active */
- if (irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+ if (irq_type == IRQ_TYPE_EDGE_FALLING)
irq_pol = IRQ_ACTIVE_LOW;
- else
- irq_pol = IRQ_ACTIVE_HIGH;
rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, irq_pol);
if (rc)
return rc;
+ rc = at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1);
+ if (rc)
+ return rc;
+
rc = at86rf230_write_subreg(lp, SR_IRQ_MASK, IRQ_TRX_END);
if (rc)
return rc;
@@ -1004,7 +1343,8 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
if (rc)
return rc;
/* Wait the next SLEEP cycle */
- msleep(100);
+ usleep_range(lp->data->t_sleep_cycle,
+ lp->data->t_sleep_cycle + 100);
rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd);
if (rc)
@@ -1037,18 +1377,111 @@ done:
return pdata;
}
+static int
+at86rf230_detect_device(struct at86rf230_local *lp)
+{
+ unsigned int part, version, val;
+ u16 man_id = 0;
+ const char *chip;
+ int rc;
+
+ rc = __at86rf230_read(lp, RG_MAN_ID_0, &val);
+ if (rc)
+ return rc;
+ man_id |= val;
+
+ rc = __at86rf230_read(lp, RG_MAN_ID_1, &val);
+ if (rc)
+ return rc;
+ man_id |= (val << 8);
+
+ rc = __at86rf230_read(lp, RG_PART_NUM, &part);
+ if (rc)
+ return rc;
+
+ rc = __at86rf230_read(lp, RG_PART_NUM, &version);
+ if (rc)
+ return rc;
+
+ if (man_id != 0x001f) {
+ dev_err(&lp->spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
+ man_id >> 8, man_id & 0xFF);
+ return -EINVAL;
+ }
+
+ lp->dev->extra_tx_headroom = 0;
+ lp->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
+ IEEE802154_HW_TXPOWER | IEEE802154_HW_CSMA;
+
+ switch (part) {
+ case 2:
+ chip = "at86rf230";
+ rc = -ENOTSUPP;
+ break;
+ case 3:
+ chip = "at86rf231";
+ lp->data = &at86rf231_data;
+ lp->dev->phy->channels_supported[0] = 0x7FFF800;
+ break;
+ case 7:
+ chip = "at86rf212";
+ if (version == 1) {
+ lp->data = &at86rf212_data;
+ lp->dev->flags |= IEEE802154_HW_LBT;
+ lp->dev->phy->channels_supported[0] = 0x00007FF;
+ lp->dev->phy->channels_supported[2] = 0x00007FF;
+ } else {
+ rc = -ENOTSUPP;
+ }
+ break;
+ case 11:
+ chip = "at86rf233";
+ lp->data = &at86rf233_data;
+ lp->dev->phy->channels_supported[0] = 0x7FFF800;
+ break;
+ default:
+ chip = "unkown";
+ rc = -ENOTSUPP;
+ break;
+ }
+
+ dev_info(&lp->spi->dev, "Detected %s chip version %d\n", chip, version);
+
+ return rc;
+}
+
+static void
+at86rf230_setup_spi_messages(struct at86rf230_local *lp)
+{
+ lp->state.lp = lp;
+ spi_message_init(&lp->state.msg);
+ lp->state.msg.context = &lp->state;
+ lp->state.trx.tx_buf = lp->state.buf;
+ lp->state.trx.rx_buf = lp->state.buf;
+ spi_message_add_tail(&lp->state.trx, &lp->state.msg);
+
+ lp->irq.lp = lp;
+ spi_message_init(&lp->irq.msg);
+ lp->irq.msg.context = &lp->irq;
+ lp->irq.trx.tx_buf = lp->irq.buf;
+ lp->irq.trx.rx_buf = lp->irq.buf;
+ spi_message_add_tail(&lp->irq.trx, &lp->irq.msg);
+
+ lp->tx.lp = lp;
+ spi_message_init(&lp->tx.msg);
+ lp->tx.msg.context = &lp->tx;
+ lp->tx.trx.tx_buf = lp->tx.buf;
+ lp->tx.trx.rx_buf = lp->tx.buf;
+ spi_message_add_tail(&lp->tx.trx, &lp->tx.msg);
+}
+
static int at86rf230_probe(struct spi_device *spi)
{
struct at86rf230_platform_data *pdata;
struct ieee802154_dev *dev;
struct at86rf230_local *lp;
- u16 man_id = 0;
- u8 part = 0, version = 0, status;
- irq_handler_t irq_handler;
- work_func_t irq_worker;
+ unsigned int status;
int rc, irq_type;
- const char *chip;
- struct ieee802154_ops *ops = NULL;
if (!spi->irq) {
dev_err(&spi->dev, "no IRQ specified\n");
@@ -1084,107 +1517,60 @@ static int at86rf230_probe(struct spi_device *spi)
usleep_range(120, 240);
}
- rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
- if (rc < 0)
- return rc;
-
- if (man_id != 0x001f) {
- dev_err(&spi->dev, "Non-Atmel dev found (MAN_ID %02x %02x)\n",
- man_id >> 8, man_id & 0xFF);
- return -EINVAL;
- }
-
- switch (part) {
- case 2:
- chip = "at86rf230";
- /* FIXME: should be easy to support; */
- break;
- case 3:
- chip = "at86rf231";
- ops = &at86rf230_ops;
- break;
- case 7:
- chip = "at86rf212";
- if (version == 1)
- ops = &at86rf212_ops;
- break;
- case 11:
- chip = "at86rf233";
- ops = &at86rf230_ops;
- break;
- default:
- chip = "UNKNOWN";
- break;
- }
-
- dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
- if (!ops)
- return -ENOTSUPP;
-
- dev = ieee802154_alloc_device(sizeof(*lp), ops);
+ dev = ieee802154_alloc_device(sizeof(*lp), &at86rf230_ops);
if (!dev)
return -ENOMEM;
lp = dev->priv;
lp->dev = dev;
- lp->part = part;
- lp->vers = version;
-
lp->spi = spi;
-
dev->parent = &spi->dev;
- dev->extra_tx_headroom = 0;
- dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
- irq_type = irq_get_trigger_type(spi->irq);
- if (!irq_type)
- irq_type = IRQF_TRIGGER_RISING;
- if (irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
- irq_worker = at86rf230_irqwork;
- irq_handler = at86rf230_isr;
- } else {
- irq_worker = at86rf230_irqwork_level;
- irq_handler = at86rf230_isr_level;
+ lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config);
+ if (IS_ERR(lp->regmap)) {
+ rc = PTR_ERR(lp->regmap);
+ dev_err(&spi->dev, "Failed to allocate register map: %d\n",
+ rc);
+ goto free_dev;
}
- mutex_init(&lp->bmux);
- INIT_WORK(&lp->irqwork, irq_worker);
+ at86rf230_setup_spi_messages(lp);
+
+ rc = at86rf230_detect_device(lp);
+ if (rc < 0)
+ goto free_dev;
+
spin_lock_init(&lp->lock);
init_completion(&lp->tx_complete);
+ init_completion(&lp->state_complete);
spi_set_drvdata(spi, lp);
- if (is_rf212(lp)) {
- dev->phy->channels_supported[0] = 0x00007FF;
- dev->phy->channels_supported[2] = 0x00007FF;
- } else {
- dev->phy->channels_supported[0] = 0x7FFF800;
- }
-
rc = at86rf230_hw_init(lp);
if (rc)
- goto err_hw_init;
+ goto free_dev;
/* Read irq status register to reset irq line */
rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
if (rc)
- goto err_hw_init;
+ goto free_dev;
+
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (!irq_type)
+ irq_type = IRQF_TRIGGER_RISING;
- rc = devm_request_irq(&spi->dev, spi->irq, irq_handler,
- IRQF_SHARED | irq_type,
- dev_name(&spi->dev), lp);
+ rc = devm_request_irq(&spi->dev, spi->irq, at86rf230_isr,
+ IRQF_SHARED | irq_type, dev_name(&spi->dev), lp);
if (rc)
- goto err_hw_init;
+ goto free_dev;
rc = ieee802154_register_device(lp->dev);
if (rc)
- goto err_hw_init;
+ goto free_dev;
return rc;
-err_hw_init:
- flush_work(&lp->irqwork);
- mutex_destroy(&lp->bmux);
+free_dev:
ieee802154_free_device(lp->dev);
return rc;
@@ -1197,8 +1583,6 @@ static int at86rf230_remove(struct spi_device *spi)
/* mask all at86rf230 irq's */
at86rf230_write_subreg(lp, SR_IRQ_MASK, 0);
ieee802154_unregister_device(lp->dev);
- flush_work(&lp->irqwork);
- mutex_destroy(&lp->bmux);
ieee802154_free_device(lp->dev);
dev_dbg(&spi->dev, "unregistered at86rf230\n");
diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
new file mode 100644
index 000000000000..8a5ac7ab2300
--- /dev/null
+++ b/drivers/net/ieee802154/cc2520.c
@@ -0,0 +1,1039 @@
+/* Driver for TI CC2520 802.15.4 Wireless-PAN Networking controller
+ *
+ * Copyright (C) 2014 Varka Bhadram <varkab@cdac.in>
+ * Md.Jamal Mohiuddin <mjmohiuddin@cdac.in>
+ * P Sowjanya <sowjanyap@cdac.in>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/cc2520.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/skbuff.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/of_gpio.h>
+
+#include <net/mac802154.h>
+#include <net/wpan-phy.h>
+#include <net/ieee802154.h>
+
+#define SPI_COMMAND_BUFFER 3
+#define HIGH 1
+#define LOW 0
+#define STATE_IDLE 0
+#define RSSI_VALID 0
+#define RSSI_OFFSET 78
+
+#define CC2520_RAM_SIZE 640
+#define CC2520_FIFO_SIZE 128
+
+#define CC2520RAM_TXFIFO 0x100
+#define CC2520RAM_RXFIFO 0x180
+#define CC2520RAM_IEEEADDR 0x3EA
+#define CC2520RAM_PANID 0x3F2
+#define CC2520RAM_SHORTADDR 0x3F4
+
+#define CC2520_FREG_MASK 0x3F
+
+/* status byte values */
+#define CC2520_STATUS_XOSC32M_STABLE (1 << 7)
+#define CC2520_STATUS_RSSI_VALID (1 << 6)
+#define CC2520_STATUS_TX_UNDERFLOW (1 << 3)
+
+/* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
+#define CC2520_MINCHANNEL 11
+#define CC2520_MAXCHANNEL 26
+#define CC2520_CHANNEL_SPACING 5
+
+/* command strobes */
+#define CC2520_CMD_SNOP 0x00
+#define CC2520_CMD_IBUFLD 0x02
+#define CC2520_CMD_SIBUFEX 0x03
+#define CC2520_CMD_SSAMPLECCA 0x04
+#define CC2520_CMD_SRES 0x0f
+#define CC2520_CMD_MEMORY_MASK 0x0f
+#define CC2520_CMD_MEMORY_READ 0x10
+#define CC2520_CMD_MEMORY_WRITE 0x20
+#define CC2520_CMD_RXBUF 0x30
+#define CC2520_CMD_RXBUFCP 0x38
+#define CC2520_CMD_RXBUFMOV 0x32
+#define CC2520_CMD_TXBUF 0x3A
+#define CC2520_CMD_TXBUFCP 0x3E
+#define CC2520_CMD_RANDOM 0x3C
+#define CC2520_CMD_SXOSCON 0x40
+#define CC2520_CMD_STXCAL 0x41
+#define CC2520_CMD_SRXON 0x42
+#define CC2520_CMD_STXON 0x43
+#define CC2520_CMD_STXONCCA 0x44
+#define CC2520_CMD_SRFOFF 0x45
+#define CC2520_CMD_SXOSCOFF 0x46
+#define CC2520_CMD_SFLUSHRX 0x47
+#define CC2520_CMD_SFLUSHTX 0x48
+#define CC2520_CMD_SACK 0x49
+#define CC2520_CMD_SACKPEND 0x4A
+#define CC2520_CMD_SNACK 0x4B
+#define CC2520_CMD_SRXMASKBITSET 0x4C
+#define CC2520_CMD_SRXMASKBITCLR 0x4D
+#define CC2520_CMD_RXMASKAND 0x4E
+#define CC2520_CMD_RXMASKOR 0x4F
+#define CC2520_CMD_MEMCP 0x50
+#define CC2520_CMD_MEMCPR 0x52
+#define CC2520_CMD_MEMXCP 0x54
+#define CC2520_CMD_MEMXWR 0x56
+#define CC2520_CMD_BCLR 0x58
+#define CC2520_CMD_BSET 0x59
+#define CC2520_CMD_CTR_UCTR 0x60
+#define CC2520_CMD_CBCMAC 0x64
+#define CC2520_CMD_UCBCMAC 0x66
+#define CC2520_CMD_CCM 0x68
+#define CC2520_CMD_UCCM 0x6A
+#define CC2520_CMD_ECB 0x70
+#define CC2520_CMD_ECBO 0x72
+#define CC2520_CMD_ECBX 0x74
+#define CC2520_CMD_INC 0x78
+#define CC2520_CMD_ABORT 0x7F
+#define CC2520_CMD_REGISTER_READ 0x80
+#define CC2520_CMD_REGISTER_WRITE 0xC0
+
+/* status registers */
+#define CC2520_CHIPID 0x40
+#define CC2520_VERSION 0x42
+#define CC2520_EXTCLOCK 0x44
+#define CC2520_MDMCTRL0 0x46
+#define CC2520_MDMCTRL1 0x47
+#define CC2520_FREQEST 0x48
+#define CC2520_RXCTRL 0x4A
+#define CC2520_FSCTRL 0x4C
+#define CC2520_FSCAL0 0x4E
+#define CC2520_FSCAL1 0x4F
+#define CC2520_FSCAL2 0x50
+#define CC2520_FSCAL3 0x51
+#define CC2520_AGCCTRL0 0x52
+#define CC2520_AGCCTRL1 0x53
+#define CC2520_AGCCTRL2 0x54
+#define CC2520_AGCCTRL3 0x55
+#define CC2520_ADCTEST0 0x56
+#define CC2520_ADCTEST1 0x57
+#define CC2520_ADCTEST2 0x58
+#define CC2520_MDMTEST0 0x5A
+#define CC2520_MDMTEST1 0x5B
+#define CC2520_DACTEST0 0x5C
+#define CC2520_DACTEST1 0x5D
+#define CC2520_ATEST 0x5E
+#define CC2520_DACTEST2 0x5F
+#define CC2520_PTEST0 0x60
+#define CC2520_PTEST1 0x61
+#define CC2520_RESERVED 0x62
+#define CC2520_DPUBIST 0x7A
+#define CC2520_ACTBIST 0x7C
+#define CC2520_RAMBIST 0x7E
+
+/* frame registers */
+#define CC2520_FRMFILT0 0x00
+#define CC2520_FRMFILT1 0x01
+#define CC2520_SRCMATCH 0x02
+#define CC2520_SRCSHORTEN0 0x04
+#define CC2520_SRCSHORTEN1 0x05
+#define CC2520_SRCSHORTEN2 0x06
+#define CC2520_SRCEXTEN0 0x08
+#define CC2520_SRCEXTEN1 0x09
+#define CC2520_SRCEXTEN2 0x0A
+#define CC2520_FRMCTRL0 0x0C
+#define CC2520_FRMCTRL1 0x0D
+#define CC2520_RXENABLE0 0x0E
+#define CC2520_RXENABLE1 0x0F
+#define CC2520_EXCFLAG0 0x10
+#define CC2520_EXCFLAG1 0x11
+#define CC2520_EXCFLAG2 0x12
+#define CC2520_EXCMASKA0 0x14
+#define CC2520_EXCMASKA1 0x15
+#define CC2520_EXCMASKA2 0x16
+#define CC2520_EXCMASKB0 0x18
+#define CC2520_EXCMASKB1 0x19
+#define CC2520_EXCMASKB2 0x1A
+#define CC2520_EXCBINDX0 0x1C
+#define CC2520_EXCBINDX1 0x1D
+#define CC2520_EXCBINDY0 0x1E
+#define CC2520_EXCBINDY1 0x1F
+#define CC2520_GPIOCTRL0 0x20
+#define CC2520_GPIOCTRL1 0x21
+#define CC2520_GPIOCTRL2 0x22
+#define CC2520_GPIOCTRL3 0x23
+#define CC2520_GPIOCTRL4 0x24
+#define CC2520_GPIOCTRL5 0x25
+#define CC2520_GPIOPOLARITY 0x26
+#define CC2520_GPIOCTRL 0x28
+#define CC2520_DPUCON 0x2A
+#define CC2520_DPUSTAT 0x2C
+#define CC2520_FREQCTRL 0x2E
+#define CC2520_FREQTUNE 0x2F
+#define CC2520_TXPOWER 0x30
+#define CC2520_TXCTRL 0x31
+#define CC2520_FSMSTAT0 0x32
+#define CC2520_FSMSTAT1 0x33
+#define CC2520_FIFOPCTRL 0x34
+#define CC2520_FSMCTRL 0x35
+#define CC2520_CCACTRL0 0x36
+#define CC2520_CCACTRL1 0x37
+#define CC2520_RSSI 0x38
+#define CC2520_RSSISTAT 0x39
+#define CC2520_RXFIRST 0x3C
+#define CC2520_RXFIFOCNT 0x3E
+#define CC2520_TXFIFOCNT 0x3F
+
+/* Driver private information */
+struct cc2520_private {
+ struct spi_device *spi; /* SPI device structure */
+ struct ieee802154_dev *dev; /* IEEE-802.15.4 device */
+ u8 *buf; /* SPI TX/Rx data buffer */
+ struct mutex buffer_mutex; /* SPI buffer mutex */
+ bool is_tx; /* Flag for sync b/w Tx and Rx */
+ int fifo_pin; /* FIFO GPIO pin number */
+ struct work_struct fifop_irqwork;/* Workqueue for FIFOP */
+ spinlock_t lock; /* Lock for is_tx*/
+ struct completion tx_complete; /* Work completion for Tx */
+};
+
+/* Generic Functions */
+static int
+cc2520_cmd_strobe(struct cc2520_private *priv, u8 cmd)
+{
+ int ret;
+ u8 status = 0xff;
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer.len++] = cmd;
+ dev_vdbg(&priv->spi->dev,
+ "command strobe buf[0] = %02x\n",
+ priv->buf[0]);
+
+ ret = spi_sync(priv->spi, &msg);
+ if (!ret)
+ status = priv->buf[0];
+ dev_vdbg(&priv->spi->dev,
+ "buf[0] = %02x\n", priv->buf[0]);
+ mutex_unlock(&priv->buffer_mutex);
+
+ return ret;
+}
+
+static int
+cc2520_get_status(struct cc2520_private *priv, u8 *status)
+{
+ int ret;
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer.len++] = CC2520_CMD_SNOP;
+ dev_vdbg(&priv->spi->dev,
+ "get status command buf[0] = %02x\n", priv->buf[0]);
+
+ ret = spi_sync(priv->spi, &msg);
+ if (!ret)
+ *status = priv->buf[0];
+ dev_vdbg(&priv->spi->dev,
+ "buf[0] = %02x\n", priv->buf[0]);
+ mutex_unlock(&priv->buffer_mutex);
+
+ return ret;
+}
+
+static int
+cc2520_write_register(struct cc2520_private *priv, u8 reg, u8 value)
+{
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+
+ if (reg <= CC2520_FREG_MASK) {
+ priv->buf[xfer.len++] = CC2520_CMD_REGISTER_WRITE | reg;
+ priv->buf[xfer.len++] = value;
+ } else {
+ priv->buf[xfer.len++] = CC2520_CMD_MEMORY_WRITE;
+ priv->buf[xfer.len++] = reg;
+ priv->buf[xfer.len++] = value;
+ }
+ status = spi_sync(priv->spi, &msg);
+ if (msg.status)
+ status = msg.status;
+
+ mutex_unlock(&priv->buffer_mutex);
+
+ return status;
+}
+
+static int
+cc2520_write_ram(struct cc2520_private *priv, u16 reg, u8 len, u8 *data)
+{
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer_head = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+
+ struct spi_transfer xfer_buf = {
+ .len = len,
+ .tx_buf = data,
+ };
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer_head.len++] = (CC2520_CMD_MEMORY_WRITE |
+ ((reg >> 8) & 0xff));
+ priv->buf[xfer_head.len++] = reg & 0xff;
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head, &msg);
+ spi_message_add_tail(&xfer_buf, &msg);
+
+ status = spi_sync(priv->spi, &msg);
+ dev_dbg(&priv->spi->dev, "spi status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+
+ mutex_unlock(&priv->buffer_mutex);
+ return status;
+}
+
+static int
+cc2520_read_register(struct cc2520_private *priv, u8 reg, u8 *data)
+{
+ int status;
+ struct spi_message msg;
+ struct spi_transfer xfer1 = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+
+ struct spi_transfer xfer2 = {
+ .len = 1,
+ .rx_buf = data,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer1, &msg);
+ spi_message_add_tail(&xfer2, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer1.len++] = CC2520_CMD_MEMORY_READ;
+ priv->buf[xfer1.len++] = reg;
+
+ status = spi_sync(priv->spi, &msg);
+ dev_dbg(&priv->spi->dev,
+ "spi status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+
+ mutex_unlock(&priv->buffer_mutex);
+
+ return status;
+}
+
+static int
+cc2520_write_txfifo(struct cc2520_private *priv, u8 *data, u8 len)
+{
+ int status;
+
+ /* length byte must include FCS even
+ * if it is calculated in the hardware
+ */
+ int len_byte = len + 2;
+
+ struct spi_message msg;
+
+ struct spi_transfer xfer_head = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+ struct spi_transfer xfer_len = {
+ .len = 1,
+ .tx_buf = &len_byte,
+ };
+ struct spi_transfer xfer_buf = {
+ .len = len,
+ .tx_buf = data,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head, &msg);
+ spi_message_add_tail(&xfer_len, &msg);
+ spi_message_add_tail(&xfer_buf, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer_head.len++] = CC2520_CMD_TXBUF;
+ dev_vdbg(&priv->spi->dev,
+ "TX_FIFO cmd buf[0] = %02x\n", priv->buf[0]);
+
+ status = spi_sync(priv->spi, &msg);
+ dev_vdbg(&priv->spi->dev, "status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+ dev_vdbg(&priv->spi->dev, "status = %d\n", status);
+ dev_vdbg(&priv->spi->dev, "buf[0] = %02x\n", priv->buf[0]);
+ mutex_unlock(&priv->buffer_mutex);
+
+ return status;
+}
+
+static int
+cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi)
+{
+ int status;
+ struct spi_message msg;
+
+ struct spi_transfer xfer_head = {
+ .len = 0,
+ .tx_buf = priv->buf,
+ .rx_buf = priv->buf,
+ };
+ struct spi_transfer xfer_buf = {
+ .len = len,
+ .rx_buf = data,
+ };
+
+ spi_message_init(&msg);
+ spi_message_add_tail(&xfer_head, &msg);
+ spi_message_add_tail(&xfer_buf, &msg);
+
+ mutex_lock(&priv->buffer_mutex);
+ priv->buf[xfer_head.len++] = CC2520_CMD_RXBUF;
+
+ dev_vdbg(&priv->spi->dev, "read rxfifo buf[0] = %02x\n", priv->buf[0]);
+ dev_vdbg(&priv->spi->dev, "buf[1] = %02x\n", priv->buf[1]);
+
+ status = spi_sync(priv->spi, &msg);
+ dev_vdbg(&priv->spi->dev, "status = %d\n", status);
+ if (msg.status)
+ status = msg.status;
+ dev_vdbg(&priv->spi->dev, "status = %d\n", status);
+ dev_vdbg(&priv->spi->dev,
+ "return status buf[0] = %02x\n", priv->buf[0]);
+ dev_vdbg(&priv->spi->dev, "length buf[1] = %02x\n", priv->buf[1]);
+
+ mutex_unlock(&priv->buffer_mutex);
+
+ return status;
+}
+
+static int cc2520_start(struct ieee802154_dev *dev)
+{
+ return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON);
+}
+
+static void cc2520_stop(struct ieee802154_dev *dev)
+{
+ cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF);
+}
+
+static int
+cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
+{
+ struct cc2520_private *priv = dev->priv;
+ unsigned long flags;
+ int rc;
+ u8 status = 0;
+
+ rc = cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
+ if (rc)
+ goto err_tx;
+
+ rc = cc2520_write_txfifo(priv, skb->data, skb->len);
+ if (rc)
+ goto err_tx;
+
+ rc = cc2520_get_status(priv, &status);
+ if (rc)
+ goto err_tx;
+
+ if (status & CC2520_STATUS_TX_UNDERFLOW) {
+ dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n");
+ goto err_tx;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+ BUG_ON(priv->is_tx);
+ priv->is_tx = 1;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ rc = cc2520_cmd_strobe(priv, CC2520_CMD_STXONCCA);
+ if (rc)
+ goto err;
+
+ rc = wait_for_completion_interruptible(&priv->tx_complete);
+ if (rc < 0)
+ goto err;
+
+ cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHTX);
+ cc2520_cmd_strobe(priv, CC2520_CMD_SRXON);
+
+ return rc;
+err:
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->is_tx = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+err_tx:
+ return rc;
+}
+
+
+static int cc2520_rx(struct cc2520_private *priv)
+{
+ u8 len = 0, lqi = 0, bytes = 1;
+ struct sk_buff *skb;
+
+ cc2520_read_rxfifo(priv, &len, bytes, &lqi);
+
+ if (len < 2 || len > IEEE802154_MTU)
+ return -EINVAL;
+
+ skb = alloc_skb(len, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ if (cc2520_read_rxfifo(priv, skb_put(skb, len), len, &lqi)) {
+ dev_dbg(&priv->spi->dev, "frame reception failed\n");
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+
+ skb_trim(skb, skb->len - 2);
+
+ ieee802154_rx_irqsafe(priv->dev, skb, lqi);
+
+ dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
+
+ return 0;
+}
+
+static int
+cc2520_ed(struct ieee802154_dev *dev, u8 *level)
+{
+ struct cc2520_private *priv = dev->priv;
+ u8 status = 0xff;
+ u8 rssi;
+ int ret;
+
+ ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
+ if (ret)
+ return ret;
+
+ if (status != RSSI_VALID)
+ return -EINVAL;
+
+ ret = cc2520_read_register(priv , CC2520_RSSI, &rssi);
+ if (ret)
+ return ret;
+
+ /* level = RSSI(rssi) - OFFSET [dBm] : offset is 76dBm */
+ *level = rssi - RSSI_OFFSET;
+
+ return 0;
+}
+
+static int
+cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel)
+{
+ struct cc2520_private *priv = dev->priv;
+ int ret;
+
+ might_sleep();
+ dev_dbg(&priv->spi->dev, "trying to set channel\n");
+
+ BUG_ON(page != 0);
+ BUG_ON(channel < CC2520_MINCHANNEL);
+ BUG_ON(channel > CC2520_MAXCHANNEL);
+
+ ret = cc2520_write_register(priv, CC2520_FREQCTRL,
+ 11 + 5*(channel - 11));
+
+ return ret;
+}
+
+static int
+cc2520_filter(struct ieee802154_dev *dev,
+ struct ieee802154_hw_addr_filt *filt, unsigned long changed)
+{
+ struct cc2520_private *priv = dev->priv;
+
+ if (changed & IEEE802515_AFILT_PANID_CHANGED) {
+ u16 panid = le16_to_cpu(filt->pan_id);
+
+ dev_vdbg(&priv->spi->dev,
+ "cc2520_filter called for pan id\n");
+ cc2520_write_ram(priv, CC2520RAM_PANID,
+ sizeof(panid), (u8 *)&panid);
+ }
+
+ if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) {
+ dev_vdbg(&priv->spi->dev,
+ "cc2520_filter called for IEEE addr\n");
+ cc2520_write_ram(priv, CC2520RAM_IEEEADDR,
+ sizeof(filt->ieee_addr),
+ (u8 *)&filt->ieee_addr);
+ }
+
+ if (changed & IEEE802515_AFILT_SADDR_CHANGED) {
+ u16 addr = le16_to_cpu(filt->short_addr);
+
+ dev_vdbg(&priv->spi->dev,
+ "cc2520_filter called for saddr\n");
+ cc2520_write_ram(priv, CC2520RAM_SHORTADDR,
+ sizeof(addr), (u8 *)&addr);
+ }
+
+ if (changed & IEEE802515_AFILT_PANC_CHANGED) {
+ dev_vdbg(&priv->spi->dev,
+ "cc2520_filter called for panc change\n");
+ if (filt->pan_coord)
+ cc2520_write_register(priv, CC2520_FRMFILT0, 0x02);
+ else
+ cc2520_write_register(priv, CC2520_FRMFILT0, 0x00);
+ }
+
+ return 0;
+}
+
+static struct ieee802154_ops cc2520_ops = {
+ .owner = THIS_MODULE,
+ .start = cc2520_start,
+ .stop = cc2520_stop,
+ .xmit = cc2520_tx,
+ .ed = cc2520_ed,
+ .set_channel = cc2520_set_channel,
+ .set_hw_addr_filt = cc2520_filter,
+};
+
+static int cc2520_register(struct cc2520_private *priv)
+{
+ int ret = -ENOMEM;
+
+ priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops);
+ if (!priv->dev)
+ goto err_ret;
+
+ priv->dev->priv = priv;
+ priv->dev->parent = &priv->spi->dev;
+ priv->dev->extra_tx_headroom = 0;
+
+ /* We do support only 2.4 Ghz */
+ priv->dev->phy->channels_supported[0] = 0x7FFF800;
+ priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
+
+ dev_vdbg(&priv->spi->dev, "registered cc2520\n");
+ ret = ieee802154_register_device(priv->dev);
+ if (ret)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ ieee802154_free_device(priv->dev);
+err_ret:
+ return ret;
+}
+
+static void cc2520_fifop_irqwork(struct work_struct *work)
+{
+ struct cc2520_private *priv
+ = container_of(work, struct cc2520_private, fifop_irqwork);
+
+ dev_dbg(&priv->spi->dev, "fifop interrupt received\n");
+
+ if (gpio_get_value(priv->fifo_pin))
+ cc2520_rx(priv);
+ else
+ dev_dbg(&priv->spi->dev, "rxfifo overflow\n");
+
+ cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
+ cc2520_cmd_strobe(priv, CC2520_CMD_SFLUSHRX);
+}
+
+static irqreturn_t cc2520_fifop_isr(int irq, void *data)
+{
+ struct cc2520_private *priv = data;
+
+ schedule_work(&priv->fifop_irqwork);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t cc2520_sfd_isr(int irq, void *data)
+{
+ struct cc2520_private *priv = data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->is_tx) {
+ priv->is_tx = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dev_dbg(&priv->spi->dev, "SFD for TX\n");
+ complete(&priv->tx_complete);
+ } else {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dev_dbg(&priv->spi->dev, "SFD for RX\n");
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int cc2520_hw_init(struct cc2520_private *priv)
+{
+ u8 status = 0, state = 0xff;
+ int ret;
+ int timeout = 100;
+
+ ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
+ if (ret)
+ goto err_ret;
+
+ if (state != STATE_IDLE)
+ return -EINVAL;
+
+ do {
+ ret = cc2520_get_status(priv, &status);
+ if (ret)
+ goto err_ret;
+
+ if (timeout-- <= 0) {
+ dev_err(&priv->spi->dev, "oscillator start failed!\n");
+ return ret;
+ }
+ udelay(1);
+ } while (!(status & CC2520_STATUS_XOSC32M_STABLE));
+
+ dev_vdbg(&priv->spi->dev, "oscillator brought up\n");
+
+ /* Registers default value: section 28.1 in Datasheet */
+ ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_MDMCTRL0, 0x85);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_MDMCTRL1, 0x14);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_RXCTRL, 0x3f);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FSCTRL, 0x5a);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FSCAL1, 0x2b);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_ADCTEST1, 0x0e);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_ADCTEST2, 0x03);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FRMCTRL0, 0x60);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FRMCTRL1, 0x03);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FRMFILT0, 0x00);
+ if (ret)
+ goto err_ret;
+
+ ret = cc2520_write_register(priv, CC2520_FIFOPCTRL, 127);
+ if (ret)
+ goto err_ret;
+
+ return 0;
+
+err_ret:
+ return ret;
+}
+
+static struct cc2520_platform_data *
+cc2520_get_platform_data(struct spi_device *spi)
+{
+ struct cc2520_platform_data *pdata;
+ struct device_node *np = spi->dev.of_node;
+ struct cc2520_private *priv = spi_get_drvdata(spi);
+
+ if (!np)
+ return spi->dev.platform_data;
+
+ pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ goto done;
+
+ pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
+ priv->fifo_pin = pdata->fifo;
+
+ pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);
+
+ pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
+ pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
+ pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
+ pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);
+
+ spi->dev.platform_data = pdata;
+
+done:
+ return pdata;
+}
+
+static int cc2520_probe(struct spi_device *spi)
+{
+ struct cc2520_private *priv;
+ struct pinctrl *pinctrl;
+ struct cc2520_platform_data *pdata;
+ int ret;
+
+ priv = devm_kzalloc(&spi->dev,
+ sizeof(struct cc2520_private), GFP_KERNEL);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto err_ret;
+ }
+
+ spi_set_drvdata(spi, priv);
+
+ pinctrl = devm_pinctrl_get_select_default(&spi->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&spi->dev,
+ "pinctrl pins are not configured");
+
+ pdata = cc2520_get_platform_data(spi);
+ if (!pdata) {
+ dev_err(&spi->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
+ priv->spi = spi;
+
+ priv->buf = devm_kzalloc(&spi->dev,
+ SPI_COMMAND_BUFFER, GFP_KERNEL);
+ if (!priv->buf) {
+ ret = -ENOMEM;
+ goto err_ret;
+ }
+
+ mutex_init(&priv->buffer_mutex);
+ INIT_WORK(&priv->fifop_irqwork, cc2520_fifop_irqwork);
+ spin_lock_init(&priv->lock);
+ init_completion(&priv->tx_complete);
+
+ /* Request all the gpio's */
+ if (!gpio_is_valid(pdata->fifo)) {
+ dev_err(&spi->dev, "fifo gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->fifo,
+ GPIOF_IN, "fifo");
+ if (ret)
+ goto err_hw_init;
+
+ if (!gpio_is_valid(pdata->cca)) {
+ dev_err(&spi->dev, "cca gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->cca,
+ GPIOF_IN, "cca");
+ if (ret)
+ goto err_hw_init;
+
+ if (!gpio_is_valid(pdata->fifop)) {
+ dev_err(&spi->dev, "fifop gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->fifop,
+ GPIOF_IN, "fifop");
+ if (ret)
+ goto err_hw_init;
+
+ if (!gpio_is_valid(pdata->sfd)) {
+ dev_err(&spi->dev, "sfd gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->sfd,
+ GPIOF_IN, "sfd");
+ if (ret)
+ goto err_hw_init;
+
+ if (!gpio_is_valid(pdata->reset)) {
+ dev_err(&spi->dev, "reset gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->reset,
+ GPIOF_OUT_INIT_LOW, "reset");
+ if (ret)
+ goto err_hw_init;
+
+ if (!gpio_is_valid(pdata->vreg)) {
+ dev_err(&spi->dev, "vreg gpio is not valid\n");
+ ret = -EINVAL;
+ goto err_hw_init;
+ }
+
+ ret = devm_gpio_request_one(&spi->dev, pdata->vreg,
+ GPIOF_OUT_INIT_LOW, "vreg");
+ if (ret)
+ goto err_hw_init;
+
+
+ gpio_set_value(pdata->vreg, HIGH);
+ usleep_range(100, 150);
+
+ gpio_set_value(pdata->reset, HIGH);
+ usleep_range(200, 250);
+
+ ret = cc2520_hw_init(priv);
+ if (ret)
+ goto err_hw_init;
+
+ /* Set up fifop interrupt */
+ ret = devm_request_irq(&spi->dev,
+ gpio_to_irq(pdata->fifop),
+ cc2520_fifop_isr,
+ IRQF_TRIGGER_RISING,
+ dev_name(&spi->dev),
+ priv);
+ if (ret) {
+ dev_err(&spi->dev, "could not get fifop irq\n");
+ goto err_hw_init;
+ }
+
+ /* Set up sfd interrupt */
+ ret = devm_request_irq(&spi->dev,
+ gpio_to_irq(pdata->sfd),
+ cc2520_sfd_isr,
+ IRQF_TRIGGER_FALLING,
+ dev_name(&spi->dev),
+ priv);
+ if (ret) {
+ dev_err(&spi->dev, "could not get sfd irq\n");
+ goto err_hw_init;
+ }
+
+ ret = cc2520_register(priv);
+ if (ret)
+ goto err_hw_init;
+
+ return 0;
+
+err_hw_init:
+ mutex_destroy(&priv->buffer_mutex);
+ flush_work(&priv->fifop_irqwork);
+
+err_ret:
+ return ret;
+}
+
+static int cc2520_remove(struct spi_device *spi)
+{
+ struct cc2520_private *priv = spi_get_drvdata(spi);
+
+ mutex_destroy(&priv->buffer_mutex);
+ flush_work(&priv->fifop_irqwork);
+
+ ieee802154_unregister_device(priv->dev);
+ ieee802154_free_device(priv->dev);
+
+ return 0;
+}
+
+static const struct spi_device_id cc2520_ids[] = {
+ {"cc2520", },
+ {},
+};
+MODULE_DEVICE_TABLE(spi, cc2520_ids);
+
+static const struct of_device_id cc2520_of_ids[] = {
+ {.compatible = "ti,cc2520", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, cc2520_of_ids);
+
+/* SPI driver structure */
+static struct spi_driver cc2520_driver = {
+ .driver = {
+ .name = "cc2520",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(cc2520_of_ids),
+ },
+ .id_table = cc2520_ids,
+ .probe = cc2520_probe,
+ .remove = cc2520_remove,
+};
+module_spi_driver(cc2520_driver);
+
+MODULE_AUTHOR("Varka Bhadram <varkab@cdac.in>");
+MODULE_DESCRIPTION("CC2520 Transceiver Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ieee802154/fakehard.c b/drivers/net/ieee802154/fakehard.c
index 78f18be3bbf2..9ce854f43917 100644
--- a/drivers/net/ieee802154/fakehard.c
+++ b/drivers/net/ieee802154/fakehard.c
@@ -343,7 +343,8 @@ static int ieee802154fake_probe(struct platform_device *pdev)
if (!phy)
return -ENOMEM;
- dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d", ieee802154_fake_setup);
+ dev = alloc_netdev(sizeof(struct fakehard_priv), "hardwpan%d",
+ NET_NAME_UNKNOWN, ieee802154_fake_setup);
if (!dev) {
wpan_phy_free(phy);
return -ENOMEM;
diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
index 4048062011ba..9e6a124b13f2 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -610,10 +610,95 @@ out:
return IRQ_HANDLED;
}
+static int mrf24j40_hw_init(struct mrf24j40 *devrec)
+{
+ int ret;
+ u8 val;
+
+ /* Initialize the device.
+ From datasheet section 3.2: Initialization. */
+ ret = write_short_reg(devrec, REG_SOFTRST, 0x07);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_PACON2, 0x98);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_TXSTBL, 0x95);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON0, 0x03);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON1, 0x01);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON2, 0x80);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON6, 0x90);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON7, 0x80);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_RFCON8, 0x10);
+ if (ret)
+ goto err_ret;
+
+ ret = write_long_reg(devrec, REG_SLPCON1, 0x21);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_BBREG2, 0x80);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_CCAEDTH, 0x60);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_BBREG6, 0x40);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_RFCTL, 0x04);
+ if (ret)
+ goto err_ret;
+
+ ret = write_short_reg(devrec, REG_RFCTL, 0x0);
+ if (ret)
+ goto err_ret;
+
+ udelay(192);
+
+ /* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
+ ret = read_short_reg(devrec, REG_RXMCR, &val);
+ if (ret)
+ goto err_ret;
+
+ val &= ~0x3; /* Clear RX mode (normal) */
+
+ ret = write_short_reg(devrec, REG_RXMCR, val);
+ if (ret)
+ goto err_ret;
+
+ return 0;
+
+err_ret:
+ return ret;
+}
+
static int mrf24j40_probe(struct spi_device *spi)
{
int ret = -ENOMEM;
- u8 val;
struct mrf24j40 *devrec;
printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq);
@@ -650,31 +735,9 @@ static int mrf24j40_probe(struct spi_device *spi)
if (ret)
goto err_register_device;
- /* Initialize the device.
- From datasheet section 3.2: Initialization. */
- write_short_reg(devrec, REG_SOFTRST, 0x07);
- write_short_reg(devrec, REG_PACON2, 0x98);
- write_short_reg(devrec, REG_TXSTBL, 0x95);
- write_long_reg(devrec, REG_RFCON0, 0x03);
- write_long_reg(devrec, REG_RFCON1, 0x01);
- write_long_reg(devrec, REG_RFCON2, 0x80);
- write_long_reg(devrec, REG_RFCON6, 0x90);
- write_long_reg(devrec, REG_RFCON7, 0x80);
- write_long_reg(devrec, REG_RFCON8, 0x10);
- write_long_reg(devrec, REG_SLPCON1, 0x21);
- write_short_reg(devrec, REG_BBREG2, 0x80);
- write_short_reg(devrec, REG_CCAEDTH, 0x60);
- write_short_reg(devrec, REG_BBREG6, 0x40);
- write_short_reg(devrec, REG_RFCTL, 0x04);
- write_short_reg(devrec, REG_RFCTL, 0x0);
- udelay(192);
-
- /* Set RX Mode. RXMCR<1:0>: 0x0 normal, 0x1 promisc, 0x2 error */
- ret = read_short_reg(devrec, REG_RXMCR, &val);
+ ret = mrf24j40_hw_init(devrec);
if (ret)
- goto err_read_reg;
- val &= ~0x3; /* Clear RX mode (normal) */
- write_short_reg(devrec, REG_RXMCR, val);
+ goto err_hw_init;
ret = devm_request_threaded_irq(&spi->dev,
spi->irq,
@@ -692,7 +755,7 @@ static int mrf24j40_probe(struct spi_device *spi)
return 0;
err_irq:
-err_read_reg:
+err_hw_init:
ieee802154_unregister_device(devrec->dev);
err_register_device:
ieee802154_free_device(devrec->dev);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 46a7790be004..d2d4a3d2237f 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -269,8 +269,8 @@ static int __init ifb_init_one(int index)
struct ifb_private *dp;
int err;
- dev_ifb = alloc_netdev(sizeof(struct ifb_private),
- "ifb%d", ifb_setup);
+ dev_ifb = alloc_netdev(sizeof(struct ifb_private), "ifb%d",
+ NET_NAME_UNKNOWN, ifb_setup);
if (!dev_ifb)
return -ENOMEM;
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 5f91e3e01c04..aab2cf72d025 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -18,6 +18,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/interrupt.h>
@@ -175,6 +176,7 @@ struct au1k_private {
struct resource *ioarea;
struct au1k_irda_platform_data *platdata;
+ struct clk *irda_clk;
};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
@@ -514,9 +516,39 @@ static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
static int au1k_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
- u32 enable, ring_address;
+ u32 enable, ring_address, phyck;
+ struct clk *c;
int i;
+ c = clk_get(NULL, "irda_clk");
+ if (IS_ERR(c))
+ return PTR_ERR(c);
+ i = clk_prepare_enable(c);
+ if (i) {
+ clk_put(c);
+ return i;
+ }
+
+ switch (clk_get_rate(c)) {
+ case 40000000:
+ phyck = IR_PHYCLK_40MHZ;
+ break;
+ case 48000000:
+ phyck = IR_PHYCLK_48MHZ;
+ break;
+ case 56000000:
+ phyck = IR_PHYCLK_56MHZ;
+ break;
+ case 64000000:
+ phyck = IR_PHYCLK_64MHZ;
+ break;
+ default:
+ clk_disable_unprepare(c);
+ clk_put(c);
+ return -EINVAL;
+ }
+ aup->irda_clk = c;
+
enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
enable |= IR_BE;
@@ -545,7 +577,7 @@ static int au1k_init(struct net_device *dev)
irda_write(aup, IR_RING_SIZE,
(RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));
- irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
+ irda_write(aup, IR_CONFIG_2, phyck | IR_ONE_PIN);
irda_write(aup, IR_RING_ADDR_CMPR, 0);
au1k_irda_set_speed(dev, 9600);
@@ -619,6 +651,9 @@ static int au1k_irda_stop(struct net_device *dev)
free_irq(aup->irq_tx, dev);
free_irq(aup->irq_rx, dev);
+ clk_disable_unprepare(aup->irda_clk);
+ clk_put(aup->irda_clk);
+
return 0;
}
@@ -853,6 +888,7 @@ static int au1k_irda_probe(struct platform_device *pdev)
struct au1k_private *aup;
struct net_device *dev;
struct resource *r;
+ struct clk *c;
int err;
dev = alloc_irdadev(sizeof(struct au1k_private));
@@ -886,6 +922,14 @@ static int au1k_irda_probe(struct platform_device *pdev)
if (!aup->ioarea)
goto out;
+ /* bail out early if clock doesn't exist */
+ c = clk_get(NULL, "irda_clk");
+ if (IS_ERR(c)) {
+ err = PTR_ERR(c);
+ goto out;
+ }
+ clk_put(c);
+
aup->iobase = ioremap_nocache(r->start, resource_size(r));
if (!aup->iobase)
goto out2;
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index 96fe3659012d..e638893e98a9 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -553,8 +553,8 @@ static int kingsun_probe(struct usb_interface *intf,
return 0;
free_mem:
- if (kingsun->out_buf) kfree(kingsun->out_buf);
- if (kingsun->in_buf) kfree(kingsun->in_buf);
+ kfree(kingsun->out_buf);
+ kfree(kingsun->in_buf);
free_netdev(net);
err_out1:
return ret;
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index bb96409f8c05..8f2262540561 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -195,7 +195,7 @@ static __net_init int loopback_net_init(struct net *net)
int err;
err = -ENOMEM;
- dev = alloc_netdev(0, "lo", loopback_setup);
+ dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
if (!dev)
goto out;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 958df383068a..ef8a5c20236a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -646,6 +646,7 @@ static int macvlan_init(struct net_device *dev)
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
dev->features |= ALWAYS_ON_FEATURES;
+ dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
dev->gso_max_size = lowerdev->gso_max_size;
dev->iflink = lowerdev->ifindex;
dev->hard_header_len = lowerdev->hard_header_len;
diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c
index b57c22442867..f3230eef41fd 100644
--- a/drivers/net/phy/amd-xgbe-phy.c
+++ b/drivers/net/phy/amd-xgbe-phy.c
@@ -74,7 +74,6 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/uaccess.h>
-#include <asm/irq.h>
MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
@@ -85,6 +84,8 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
#define XGBE_PHY_ID 0x000162d0
#define XGBE_PHY_MASK 0xfffffff0
+#define XGBE_PHY_SPEEDSET_PROPERTY "amd,speed-set"
+
#define XGBE_AN_INT_CMPLT 0x01
#define XGBE_AN_INC_LINK 0x02
#define XGBE_AN_PG_RCV 0x04
@@ -94,6 +95,8 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
#define XNP_MP_FORMATTED (1 << 13)
#define XNP_NP_EXCHANGE (1 << 15)
+#define XGBE_PHY_RATECHANGE_COUNT 500
+
#ifndef MDIO_PMA_10GBR_PMD_CTRL
#define MDIO_PMA_10GBR_PMD_CTRL 0x0096
#endif
@@ -116,10 +119,13 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
#endif
/* SerDes integration register offsets */
+#define SIR0_KR_RT_1 0x002c
#define SIR0_STATUS 0x0040
#define SIR1_SPEED 0x0000
/* SerDes integration register entry bit positions and sizes */
+#define SIR0_KR_RT_1_RESET_INDEX 11
+#define SIR0_KR_RT_1_RESET_WIDTH 1
#define SIR0_STATUS_RX_READY_INDEX 0
#define SIR0_STATUS_RX_READY_WIDTH 1
#define SIR0_STATUS_TX_READY_INDEX 8
@@ -145,7 +151,7 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver");
#define SPEED_2500_CDR 0x2
#define SPEED_2500_PLL 0x0
-#define SPEED_2500_RATE 0x2
+#define SPEED_2500_RATE 0x1
#define SPEED_2500_TXAMP 0xf
#define SPEED_2500_WORD 0x1
@@ -192,6 +198,16 @@ do { \
(_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \
} while (0)
+#define XSIR_GET_BITS(_var, _prefix, _field) \
+ GET_BITS((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH)
+
+#define XSIR_SET_BITS(_var, _prefix, _field, _val) \
+ SET_BITS((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH, (_val))
+
/* Macros for reading or writing SerDes integration registers
* The ioread macros will get bit fields or full values using the
* register definitions formed using the input names
@@ -292,6 +308,11 @@ enum amd_xgbe_phy_mode {
AMD_XGBE_MODE_KX,
};
+enum amd_xgbe_phy_speedset {
+ AMD_XGBE_PHY_SPEEDSET_1000_10000,
+ AMD_XGBE_PHY_SPEEDSET_2500_10000,
+};
+
struct amd_xgbe_phy_priv {
struct platform_device *pdev;
struct device *dev;
@@ -311,6 +332,7 @@ struct amd_xgbe_phy_priv {
/* Maintain link status for re-starting auto-negotiation */
unsigned int link;
enum amd_xgbe_phy_mode mode;
+ unsigned int speed_set;
/* Auto-negotiation state machine support */
struct mutex an_mutex;
@@ -380,14 +402,25 @@ static void amd_xgbe_phy_serdes_start_ratechange(struct phy_device *phydev)
static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev)
{
struct amd_xgbe_phy_priv *priv = phydev->priv;
+ unsigned int wait;
+ u16 status;
/* Release Rx and Tx ratechange */
XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 0);
/* Wait for Rx and Tx ready */
- while (!XSIR0_IOREAD_BITS(priv, SIR0_STATUS, RX_READY) &&
- !XSIR0_IOREAD_BITS(priv, SIR0_STATUS, TX_READY))
- usleep_range(10, 20);
+ wait = XGBE_PHY_RATECHANGE_COUNT;
+ while (wait--) {
+ usleep_range(50, 75);
+
+ status = XSIR0_IOREAD(priv, SIR0_STATUS);
+ if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) &&
+ XSIR_GET_BITS(status, SIR0_STATUS, TX_READY))
+ return;
+ }
+
+ netdev_dbg(phydev->attached_dev, "SerDes rx/tx not ready (%#hx)\n",
+ status);
}
static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev)
@@ -546,10 +579,14 @@ static int amd_xgbe_phy_switch_mode(struct phy_device *phydev)
int ret;
/* If we are in KR switch to KX, and vice-versa */
- if (priv->mode == AMD_XGBE_MODE_KR)
- ret = amd_xgbe_phy_gmii_mode(phydev);
- else
+ if (priv->mode == AMD_XGBE_MODE_KR) {
+ if (priv->speed_set == AMD_XGBE_PHY_SPEEDSET_1000_10000)
+ ret = amd_xgbe_phy_gmii_mode(phydev);
+ else
+ ret = amd_xgbe_phy_gmii_2500_mode(phydev);
+ } else {
ret = amd_xgbe_phy_xgmii_mode(phydev);
+ }
return ret;
}
@@ -602,9 +639,13 @@ static enum amd_xgbe_phy_an amd_xgbe_an_tx_training(struct phy_device *phydev,
if (ret < 0)
return AMD_XGBE_AN_ERROR;
+ XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 1);
+
ret |= 0x01;
phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, ret);
+ XSIR0_IOWRITE_BITS(priv, SIR0_KR_RT_1, RESET, 0);
+
return AMD_XGBE_AN_EVENT;
}
@@ -713,7 +754,8 @@ static enum amd_xgbe_phy_an amd_xgbe_an_start(struct phy_device *phydev)
else
ret &= ~0x80;
- if (phydev->supported & SUPPORTED_1000baseKX_Full)
+ if ((phydev->supported & SUPPORTED_1000baseKX_Full) ||
+ (phydev->supported & SUPPORTED_2500baseX_Full))
ret |= 0x20;
else
ret &= ~0x20;
@@ -815,6 +857,7 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
struct phy_device *phydev = priv->phydev;
enum amd_xgbe_phy_an cur_state;
int sleep;
+ unsigned int an_supported = 0;
while (1) {
mutex_lock(&priv->an_mutex);
@@ -824,6 +867,7 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
switch (priv->an_state) {
case AMD_XGBE_AN_START:
priv->an_state = amd_xgbe_an_start(phydev);
+ an_supported = 0;
break;
case AMD_XGBE_AN_EVENT:
@@ -832,6 +876,7 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
case AMD_XGBE_AN_PAGE_RECEIVED:
priv->an_state = amd_xgbe_an_page_received(phydev);
+ an_supported++;
break;
case AMD_XGBE_AN_INCOMPAT_LINK:
@@ -839,6 +884,11 @@ static void amd_xgbe_an_state_machine(struct work_struct *work)
break;
case AMD_XGBE_AN_COMPLETE:
+ netdev_info(phydev->attached_dev, "%s successful\n",
+ an_supported ? "Auto negotiation"
+ : "Parallel detection");
+ /* fall through */
+
case AMD_XGBE_AN_NO_LINK:
case AMD_XGBE_AN_EXIT:
goto exit_unlock;
@@ -896,14 +946,22 @@ static int amd_xgbe_phy_soft_reset(struct phy_device *phydev)
static int amd_xgbe_phy_config_init(struct phy_device *phydev)
{
+ struct amd_xgbe_phy_priv *priv = phydev->priv;
+
/* Initialize supported features */
phydev->supported = SUPPORTED_Autoneg;
phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
phydev->supported |= SUPPORTED_Backplane;
- phydev->supported |= SUPPORTED_1000baseKX_Full |
- SUPPORTED_2500baseX_Full;
phydev->supported |= SUPPORTED_10000baseKR_Full |
SUPPORTED_10000baseR_FEC;
+ switch (priv->speed_set) {
+ case AMD_XGBE_PHY_SPEEDSET_1000_10000:
+ phydev->supported |= SUPPORTED_1000baseKX_Full;
+ break;
+ case AMD_XGBE_PHY_SPEEDSET_2500_10000:
+ phydev->supported |= SUPPORTED_2500baseX_Full;
+ break;
+ }
phydev->advertising = phydev->supported;
/* Turn off and clear interrupts */
@@ -1020,9 +1078,9 @@ static int amd_xgbe_phy_update_link(struct phy_device *phydev)
* (re-)established (cable connected after the interface is
* up, etc.), the link status may report no link. If there
* is no link, try switching modes and checking the status
- * again.
+ * again if auto negotiation is enabled.
*/
- check_again = 1;
+ check_again = (phydev->autoneg == AUTONEG_ENABLE) ? 1 : 0;
again:
/* Link status is latched low, so read once to clear
* and then read again to get current state
@@ -1038,8 +1096,10 @@ again:
phydev->link = (ret & MDIO_STAT1_LSTATUS) ? 1 : 0;
if (!phydev->link) {
- ret = amd_xgbe_phy_switch_mode(phydev);
if (check_again) {
+ ret = amd_xgbe_phy_switch_mode(phydev);
+ if (ret < 0)
+ return ret;
check_again = 0;
goto again;
}
@@ -1059,6 +1119,7 @@ again:
static int amd_xgbe_phy_read_status(struct phy_device *phydev)
{
+ struct amd_xgbe_phy_priv *priv = phydev->priv;
u32 mmd_mask = phydev->c45_ids.devices_in_package;
int ret, mode, ad_ret, lp_ret;
@@ -1108,9 +1169,19 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
return ret;
}
} else {
- phydev->speed = SPEED_1000;
+ int (*mode_fcn)(struct phy_device *);
+
+ if (priv->speed_set ==
+ AMD_XGBE_PHY_SPEEDSET_1000_10000) {
+ phydev->speed = SPEED_1000;
+ mode_fcn = amd_xgbe_phy_gmii_mode;
+ } else {
+ phydev->speed = SPEED_2500;
+ mode_fcn = amd_xgbe_phy_gmii_2500_mode;
+ }
+
if (mode == MDIO_PCS_CTRL2_10GBR) {
- ret = amd_xgbe_phy_gmii_mode(phydev);
+ ret = mode_fcn(phydev);
if (ret < 0)
return ret;
}
@@ -1118,8 +1189,15 @@ static int amd_xgbe_phy_read_status(struct phy_device *phydev)
phydev->duplex = DUPLEX_FULL;
} else {
- phydev->speed = (mode == MDIO_PCS_CTRL2_10GBR) ? SPEED_10000
- : SPEED_1000;
+ if (mode == MDIO_PCS_CTRL2_10GBR) {
+ phydev->speed = SPEED_10000;
+ } else {
+ if (priv->speed_set ==
+ AMD_XGBE_PHY_SPEEDSET_1000_10000)
+ phydev->speed = SPEED_1000;
+ else
+ phydev->speed = SPEED_2500;
+ }
phydev->duplex = DUPLEX_FULL;
phydev->pause = 0;
phydev->asym_pause = 0;
@@ -1176,6 +1254,8 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
struct platform_device *pdev;
struct device *dev;
char *wq_name;
+ const __be32 *property;
+ unsigned int speed_set;
int ret;
if (!phydev->dev.of_node)
@@ -1227,6 +1307,26 @@ static int amd_xgbe_phy_probe(struct phy_device *phydev)
goto err_sir0;
}
+ /* Get the device speed set property */
+ speed_set = 0;
+ property = of_get_property(dev->of_node, XGBE_PHY_SPEEDSET_PROPERTY,
+ NULL);
+ if (property)
+ speed_set = be32_to_cpu(*property);
+
+ switch (speed_set) {
+ case 0:
+ priv->speed_set = AMD_XGBE_PHY_SPEEDSET_1000_10000;
+ break;
+ case 1:
+ priv->speed_set = AMD_XGBE_PHY_SPEEDSET_2500_10000;
+ break;
+ default:
+ dev_err(dev, "invalid amd,speed-set property\n");
+ ret = -EINVAL;
+ goto err_sir1;
+ }
+
priv->link = 1;
ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL2);
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 6a999e6814a0..c301e4cb37ca 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -40,6 +40,7 @@
#define LAYER2 0x01
#define MAX_RXTS 64
#define N_EXT_TS 6
+#define N_PER_OUT 7
#define PSF_PTPVER 2
#define PSF_EVNT 0x4000
#define PSF_RX 0x2000
@@ -47,7 +48,6 @@
#define EXT_EVENT 1
#define CAL_EVENT 7
#define CAL_TRIGGER 7
-#define PER_TRIGGER 6
#define DP83640_N_PINS 12
#define MII_DP83640_MICR 0x11
@@ -74,7 +74,10 @@
#define ENDIAN_FLAG PSF_ENDIAN
#endif
-#define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb))
+struct dp83640_skb_info {
+ int ptp_type;
+ unsigned long tmo;
+};
struct phy_rxts {
u16 ns_lo; /* ns[15:0] */
@@ -300,23 +303,23 @@ static u64 phy2txts(struct phy_txts *p)
}
static int periodic_output(struct dp83640_clock *clock,
- struct ptp_clock_request *clkreq, bool on)
+ struct ptp_clock_request *clkreq, bool on,
+ int trigger)
{
struct dp83640_private *dp83640 = clock->chosen;
struct phy_device *phydev = dp83640->phydev;
u32 sec, nsec, pwidth;
- u16 gpio, ptp_trig, trigger, val;
+ u16 gpio, ptp_trig, val;
if (on) {
- gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PEROUT, 0);
+ gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PEROUT,
+ trigger);
if (gpio < 1)
return -EINVAL;
} else {
gpio = 0;
}
- trigger = PER_TRIGGER;
-
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
(gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT |
@@ -353,6 +356,11 @@ static int periodic_output(struct dp83640_clock *clock,
ext_write(0, phydev, PAGE4, PTP_TDR, sec >> 16); /* sec[31:16] */
ext_write(0, phydev, PAGE4, PTP_TDR, pwidth & 0xffff); /* ns[15:0] */
ext_write(0, phydev, PAGE4, PTP_TDR, pwidth >> 16); /* ns[31:16] */
+ /* Triggers 0 and 1 has programmable pulsewidth2 */
+ if (trigger < 2) {
+ ext_write(0, phydev, PAGE4, PTP_TDR, pwidth & 0xffff);
+ ext_write(0, phydev, PAGE4, PTP_TDR, pwidth >> 16);
+ }
/*enable trigger*/
val &= ~TRIG_LOAD;
@@ -491,9 +499,9 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
- if (rq->perout.index != 0)
+ if (rq->perout.index >= N_PER_OUT)
return -EINVAL;
- return periodic_output(clock, rq, on);
+ return periodic_output(clock, rq, on, rq->perout.index);
default:
break;
@@ -505,6 +513,16 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
static int ptp_dp83640_verify(struct ptp_clock_info *ptp, unsigned int pin,
enum ptp_pin_function func, unsigned int chan)
{
+ struct dp83640_clock *clock =
+ container_of(ptp, struct dp83640_clock, caps);
+
+ if (clock->caps.pin_config[pin].func == PTP_PF_PHYSYNC &&
+ !list_empty(&clock->phylist))
+ return 1;
+
+ if (func == PTP_PF_PHYSYNC)
+ return 1;
+
return 0;
}
@@ -594,7 +612,11 @@ static void recalibrate(struct dp83640_clock *clock)
u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val;
trigger = CAL_TRIGGER;
- cal_gpio = gpio_tab[CALIBRATE_GPIO];
+ cal_gpio = 1 + ptp_find_pin(clock->ptp_clock, PTP_PF_PHYSYNC, 0);
+ if (cal_gpio < 1) {
+ pr_err("PHY calibration pin not avaible - PHY is not calibrated.");
+ return;
+ }
mutex_lock(&clock->extreg_lock);
@@ -736,6 +758,9 @@ static int decode_evnt(struct dp83640_private *dp83640,
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
+ /* Compensate for input path and synchronization delays */
+ event.timestamp -= 35;
+
for (i = 0; i < N_EXT_TS; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
@@ -746,10 +771,51 @@ static int decode_evnt(struct dp83640_private *dp83640,
return parsed * sizeof(u16);
}
+static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
+{
+ u16 *seqid;
+ unsigned int offset = 0;
+ u8 *msgtype, *data = skb_mac_header(skb);
+
+ /* check sequenceID, messageType, 12 bit hash of offset 20-29 */
+
+ if (type & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (type & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
+ break;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
+ break;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
+ break;
+ default:
+ return 0;
+ }
+
+ if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
+ return 0;
+
+ if (unlikely(type & PTP_CLASS_V1))
+ msgtype = data + offset + OFF_PTP_CONTROL;
+ else
+ msgtype = data + offset;
+
+ seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+
+ return rxts->msgtype == (*msgtype & 0xf) &&
+ rxts->seqid == ntohs(*seqid);
+}
+
static void decode_rxts(struct dp83640_private *dp83640,
struct phy_rxts *phy_rxts)
{
struct rxts *rxts;
+ struct skb_shared_hwtstamps *shhwtstamps = NULL;
+ struct sk_buff *skb;
unsigned long flags;
spin_lock_irqsave(&dp83640->rx_lock, flags);
@@ -763,7 +829,26 @@ static void decode_rxts(struct dp83640_private *dp83640,
rxts = list_first_entry(&dp83640->rxpool, struct rxts, list);
list_del_init(&rxts->list);
phy2rxts(phy_rxts, rxts);
- list_add_tail(&rxts->list, &dp83640->rxts);
+
+ spin_lock_irqsave(&dp83640->rx_queue.lock, flags);
+ skb_queue_walk(&dp83640->rx_queue, skb) {
+ struct dp83640_skb_info *skb_info;
+
+ skb_info = (struct dp83640_skb_info *)skb->cb;
+ if (match(skb, skb_info->ptp_type, rxts)) {
+ __skb_unlink(skb, &dp83640->rx_queue);
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(rxts->ns);
+ netif_rx_ni(skb);
+ list_add(&rxts->list, &dp83640->rxpool);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&dp83640->rx_queue.lock, flags);
+
+ if (!shhwtstamps)
+ list_add_tail(&rxts->list, &dp83640->rxts);
out:
spin_unlock_irqrestore(&dp83640->rx_lock, flags);
}
@@ -837,20 +922,18 @@ static int is_sync(struct sk_buff *skb, int type)
u8 *data = skb->data, *msgtype;
unsigned int offset = 0;
- switch (type) {
- case PTP_CLASS_V1_IPV4:
- case PTP_CLASS_V2_IPV4:
- offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
- break;
- case PTP_CLASS_V1_IPV6:
- case PTP_CLASS_V2_IPV6:
- offset = OFF_PTP6;
+ if (type & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (type & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
break;
- case PTP_CLASS_V2_L2:
- offset = ETH_HLEN;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
break;
- case PTP_CLASS_V2_VLAN:
- offset = ETH_HLEN + VLAN_HLEN;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
break;
default:
return 0;
@@ -867,47 +950,6 @@ static int is_sync(struct sk_buff *skb, int type)
return (*msgtype & 0xf) == 0;
}
-static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
-{
- u16 *seqid;
- unsigned int offset;
- u8 *msgtype, *data = skb_mac_header(skb);
-
- /* check sequenceID, messageType, 12 bit hash of offset 20-29 */
-
- switch (type) {
- case PTP_CLASS_V1_IPV4:
- case PTP_CLASS_V2_IPV4:
- offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
- break;
- case PTP_CLASS_V1_IPV6:
- case PTP_CLASS_V2_IPV6:
- offset = OFF_PTP6;
- break;
- case PTP_CLASS_V2_L2:
- offset = ETH_HLEN;
- break;
- case PTP_CLASS_V2_VLAN:
- offset = ETH_HLEN + VLAN_HLEN;
- break;
- default:
- return 0;
- }
-
- if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
- return 0;
-
- if (unlikely(type & PTP_CLASS_V1))
- msgtype = data + offset + OFF_PTP_CONTROL;
- else
- msgtype = data + offset;
-
- seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
-
- return rxts->msgtype == (*msgtype & 0xf) &&
- rxts->seqid == ntohs(*seqid);
-}
-
static void dp83640_free_clocks(void)
{
struct dp83640_clock *clock;
@@ -944,7 +986,7 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
clock->caps.n_ext_ts = N_EXT_TS;
- clock->caps.n_per_out = 1;
+ clock->caps.n_per_out = N_PER_OUT;
clock->caps.n_pins = DP83640_N_PINS;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
@@ -1284,47 +1326,34 @@ static void rx_timestamp_work(struct work_struct *work)
{
struct dp83640_private *dp83640 =
container_of(work, struct dp83640_private, ts_work);
- struct list_head *this, *next;
- struct rxts *rxts;
- struct skb_shared_hwtstamps *shhwtstamps;
struct sk_buff *skb;
- unsigned int type;
- unsigned long flags;
- /* Deliver each deferred packet, with or without a time stamp. */
-
- while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) {
- type = SKB_PTP_TYPE(skb);
- spin_lock_irqsave(&dp83640->rx_lock, flags);
- list_for_each_safe(this, next, &dp83640->rxts) {
- rxts = list_entry(this, struct rxts, list);
- if (match(skb, type, rxts)) {
- shhwtstamps = skb_hwtstamps(skb);
- memset(shhwtstamps, 0, sizeof(*shhwtstamps));
- shhwtstamps->hwtstamp = ns_to_ktime(rxts->ns);
- list_del_init(&rxts->list);
- list_add(&rxts->list, &dp83640->rxpool);
- break;
- }
+ /* Deliver expired packets. */
+ while ((skb = skb_dequeue(&dp83640->rx_queue))) {
+ struct dp83640_skb_info *skb_info;
+
+ skb_info = (struct dp83640_skb_info *)skb->cb;
+ if (!time_after(jiffies, skb_info->tmo)) {
+ skb_queue_head(&dp83640->rx_queue, skb);
+ break;
}
- spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+
netif_rx_ni(skb);
}
- /* Clear out expired time stamps. */
-
- spin_lock_irqsave(&dp83640->rx_lock, flags);
- prune_rx_ts(dp83640);
- spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+ if (!skb_queue_empty(&dp83640->rx_queue))
+ schedule_work(&dp83640->ts_work);
}
static bool dp83640_rxtstamp(struct phy_device *phydev,
struct sk_buff *skb, int type)
{
struct dp83640_private *dp83640 = phydev->priv;
-
- if (!dp83640->hwts_rx_en)
- return false;
+ struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb;
+ struct list_head *this, *next;
+ struct rxts *rxts;
+ struct skb_shared_hwtstamps *shhwtstamps = NULL;
+ unsigned long flags;
if (is_status_frame(skb, type)) {
decode_status_frame(dp83640, skb);
@@ -1332,9 +1361,30 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
return true;
}
- SKB_PTP_TYPE(skb) = type;
- skb_queue_tail(&dp83640->rx_queue, skb);
- schedule_work(&dp83640->ts_work);
+ if (!dp83640->hwts_rx_en)
+ return false;
+
+ spin_lock_irqsave(&dp83640->rx_lock, flags);
+ list_for_each_safe(this, next, &dp83640->rxts) {
+ rxts = list_entry(this, struct rxts, list);
+ if (match(skb, type, rxts)) {
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(rxts->ns);
+ netif_rx_ni(skb);
+ list_del_init(&rxts->list);
+ list_add(&rxts->list, &dp83640->rxpool);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+
+ if (!shhwtstamps) {
+ skb_info->ptp_type = type;
+ skb_info->tmo = jiffies + 2;
+ skb_queue_tail(&dp83640->rx_queue, skb);
+ schedule_work(&dp83640->ts_work);
+ }
return true;
}
@@ -1355,7 +1405,6 @@ static void dp83640_txtstamp(struct phy_device *phydev,
case HWTSTAMP_TX_ON:
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
skb_queue_tail(&dp83640->tx_queue, skb);
- schedule_work(&dp83640->ts_work);
break;
case HWTSTAMP_TX_OFF:
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 2e58aa54484c..4eaadcfcb0fe 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -187,6 +187,50 @@ struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np)
return d ? to_mii_bus(d) : NULL;
}
EXPORT_SYMBOL(of_mdio_find_bus);
+
+/* Walk the list of subnodes of a mdio bus and look for a node that matches the
+ * phy's address with its 'reg' property. If found, set the of_node pointer for
+ * the phy. This allows auto-probed pyh devices to be supplied with information
+ * passed in via DT.
+ */
+static void of_mdiobus_link_phydev(struct mii_bus *mdio,
+ struct phy_device *phydev)
+{
+ struct device *dev = &phydev->dev;
+ struct device_node *child;
+
+ if (dev->of_node || !mdio->dev.of_node)
+ return;
+
+ for_each_available_child_of_node(mdio->dev.of_node, child) {
+ int addr;
+ int ret;
+
+ ret = of_property_read_u32(child, "reg", &addr);
+ if (ret < 0) {
+ dev_err(dev, "%s has invalid PHY address\n",
+ child->full_name);
+ continue;
+ }
+
+ /* A PHY must have a reg property in the range [0-31] */
+ if (addr >= PHY_MAX_ADDR) {
+ dev_err(dev, "%s PHY address %i is too large\n",
+ child->full_name, addr);
+ continue;
+ }
+
+ if (addr == phydev->addr) {
+ dev->of_node = child;
+ return;
+ }
+ }
+}
+#else /* !IS_ENABLED(CONFIG_OF_MDIO) */
+static inline void of_mdiobus_link_phydev(struct mii_bus *mdio,
+ struct phy_device *phydev)
+{
+}
#endif
/**
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index bc7c7d2f75f2..fd0ea7c50ee6 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -420,6 +420,26 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
return 0;
}
+/* This routine returns -1 as an indication to the caller that the
+ * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
+ * MMD extended PHY registers.
+ */
+static int
+ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
+ int regnum)
+{
+ return -1;
+}
+
+/* This routine does nothing since the Micrel ksz9021 does not support
+ * standard IEEE MMD extended PHY registers.
+ */
+static void
+ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
+ int regnum, u32 val)
+{
+}
+
static struct phy_driver ksphy_driver[] = {
{
.phy_id = PHY_ID_KS8737,
@@ -565,6 +585,8 @@ static struct phy_driver ksphy_driver[] = {
.config_intr = ksz9021_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
+ .read_mmd_indirect = ksz9021_rd_mmd_phyreg,
+ .write_mmd_indirect = ksz9021_wr_mmd_phyreg,
.driver = { .owner = THIS_MODULE, },
}, {
.phy_id = PHY_ID_KSZ9031,
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f7c61812ea4a..c94e2a27446a 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -138,11 +138,31 @@ struct phy_setting {
/* A mapping of all SUPPORTED settings to speed/duplex */
static const struct phy_setting settings[] = {
{
- .speed = 10000,
+ .speed = SPEED_10000,
+ .duplex = DUPLEX_FULL,
+ .setting = SUPPORTED_10000baseKR_Full,
+ },
+ {
+ .speed = SPEED_10000,
+ .duplex = DUPLEX_FULL,
+ .setting = SUPPORTED_10000baseKX4_Full,
+ },
+ {
+ .speed = SPEED_10000,
.duplex = DUPLEX_FULL,
.setting = SUPPORTED_10000baseT_Full,
},
{
+ .speed = SPEED_2500,
+ .duplex = DUPLEX_FULL,
+ .setting = SUPPORTED_2500baseX_Full,
+ },
+ {
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+ .setting = SUPPORTED_1000baseKX_Full,
+ },
+ {
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
.setting = SUPPORTED_1000baseT_Full,
@@ -922,7 +942,7 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
/**
* phy_read_mmd_indirect - reads data from the MMD registers
- * @bus: the target MII bus
+ * @phydev: The PHY device bus
* @prtad: MMD Address
* @devad: MMD DEVAD
* @addr: PHY address on the MII bus
@@ -935,18 +955,26 @@ static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
* 3) Read reg 14 // Read MMD data
*/
-static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
- int addr)
+static int phy_read_mmd_indirect(struct phy_device *phydev, int prtad,
+ int devad, int addr)
{
- mmd_phy_indirect(bus, prtad, devad, addr);
+ struct phy_driver *phydrv = phydev->drv;
+ int value = -1;
- /* Read the content of the MMD's selected register */
- return bus->read(bus, addr, MII_MMD_DATA);
+ if (phydrv->read_mmd_indirect == NULL) {
+ mmd_phy_indirect(phydev->bus, prtad, devad, addr);
+
+ /* Read the content of the MMD's selected register */
+ value = phydev->bus->read(phydev->bus, addr, MII_MMD_DATA);
+ } else {
+ value = phydrv->read_mmd_indirect(phydev, prtad, devad, addr);
+ }
+ return value;
}
/**
* phy_write_mmd_indirect - writes data to the MMD registers
- * @bus: the target MII bus
+ * @phydev: The PHY device
* @prtad: MMD Address
* @devad: MMD DEVAD
* @addr: PHY address on the MII bus
@@ -960,13 +988,19 @@ static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
* 3) Write reg 13 // MMD Data Command for MMD DEVAD
* 3) Write reg 14 // Write MMD data
*/
-static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
- int addr, u32 data)
+static void phy_write_mmd_indirect(struct phy_device *phydev, int prtad,
+ int devad, int addr, u32 data)
{
- mmd_phy_indirect(bus, prtad, devad, addr);
+ struct phy_driver *phydrv = phydev->drv;
- /* Write the data into MMD's selected register */
- bus->write(bus, addr, MII_MMD_DATA, data);
+ if (phydrv->write_mmd_indirect == NULL) {
+ mmd_phy_indirect(phydev->bus, prtad, devad, addr);
+
+ /* Write the data into MMD's selected register */
+ phydev->bus->write(phydev->bus, addr, MII_MMD_DATA, data);
+ } else {
+ phydrv->write_mmd_indirect(phydev, prtad, devad, addr, data);
+ }
}
/**
@@ -1000,7 +1034,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
return status;
/* First check if the EEE ability is supported */
- eee_cap = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
+ eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
MDIO_MMD_PCS, phydev->addr);
if (eee_cap < 0)
return eee_cap;
@@ -1012,12 +1046,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
/* Check which link settings negotiated and verify it in
* the EEE advertising registers.
*/
- eee_lp = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
+ eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
MDIO_MMD_AN, phydev->addr);
if (eee_lp < 0)
return eee_lp;
- eee_adv = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
+ eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
MDIO_MMD_AN, phydev->addr);
if (eee_adv < 0)
return eee_adv;
@@ -1032,15 +1066,16 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
/* Configure the PHY to stop receiving xMII
* clock while it is signaling LPI.
*/
- int val = phy_read_mmd_indirect(phydev->bus, MDIO_CTRL1,
+ int val = phy_read_mmd_indirect(phydev, MDIO_CTRL1,
MDIO_MMD_PCS,
phydev->addr);
if (val < 0)
return val;
val |= MDIO_PCS_CTRL1_CLKSTOP_EN;
- phy_write_mmd_indirect(phydev->bus, MDIO_CTRL1,
- MDIO_MMD_PCS, phydev->addr, val);
+ phy_write_mmd_indirect(phydev, MDIO_CTRL1,
+ MDIO_MMD_PCS, phydev->addr,
+ val);
}
return 0; /* EEE supported */
@@ -1059,7 +1094,7 @@ EXPORT_SYMBOL(phy_init_eee);
*/
int phy_get_eee_err(struct phy_device *phydev)
{
- return phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_WK_ERR,
+ return phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_WK_ERR,
MDIO_MMD_PCS, phydev->addr);
}
EXPORT_SYMBOL(phy_get_eee_err);
@@ -1077,21 +1112,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
int val;
/* Get Supported EEE */
- val = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
+ val = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
MDIO_MMD_PCS, phydev->addr);
if (val < 0)
return val;
data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
/* Get advertisement EEE */
- val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
+ val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
MDIO_MMD_AN, phydev->addr);
if (val < 0)
return val;
data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
/* Get LP advertisement EEE */
- val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
+ val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
MDIO_MMD_AN, phydev->addr);
if (val < 0)
return val;
@@ -1112,7 +1147,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
{
int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
- phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
+ phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
phydev->addr, val);
return 0;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 35d753d22f78..ca5ec3e18d36 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -355,7 +355,7 @@ int phy_device_register(struct phy_device *phydev)
phydev->bus->phy_map[phydev->addr] = phydev;
/* Run all of the fixups for this PHY */
- err = phy_init_hw(phydev);
+ err = phy_scan_fixups(phydev);
if (err) {
pr_err("PHY %d failed to initialize\n", phydev->addr);
goto out;
@@ -575,6 +575,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32 flags, phy_interface_t interface)
{
struct device *d = &phydev->dev;
+ struct module *bus_module;
int err;
/* Assume that if there is no driver, that it doesn't
@@ -599,6 +600,14 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
return -EBUSY;
}
+ /* Increment the bus module reference count */
+ bus_module = phydev->bus->dev.driver ?
+ phydev->bus->dev.driver->owner : NULL;
+ if (!try_module_get(bus_module)) {
+ dev_err(&dev->dev, "failed to get the bus module\n");
+ return -EIO;
+ }
+
phydev->attached_dev = dev;
dev->phydev = phydev;
@@ -664,6 +673,10 @@ EXPORT_SYMBOL(phy_attach);
void phy_detach(struct phy_device *phydev)
{
int i;
+
+ if (phydev->bus->dev.driver)
+ module_put(phydev->bus->dev.driver->owner);
+
phydev->attached_dev->phydev = NULL;
phydev->attached_dev = NULL;
phy_suspend(phydev);
@@ -696,6 +709,7 @@ int phy_suspend(struct phy_device *phydev)
return phydrv->suspend(phydev);
return 0;
}
+EXPORT_SYMBOL(phy_suspend);
int phy_resume(struct phy_device *phydev)
{
@@ -705,6 +719,7 @@ int phy_resume(struct phy_device *phydev)
return phydrv->resume(phydev);
return 0;
}
+EXPORT_SYMBOL(phy_resume);
/* Generic PHY support and helper functions */
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index 22b047f1fcdc..eab57fc5b967 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -277,7 +277,7 @@ static int ks8995_probe(struct spi_device *spi)
/* Chip description */
pdata = spi->dev.platform_data;
- ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+ ks = devm_kzalloc(&spi->dev, sizeof(*ks), GFP_KERNEL);
if (!ks)
return -ENOMEM;
@@ -291,14 +291,14 @@ static int ks8995_probe(struct spi_device *spi)
err = spi_setup(spi);
if (err) {
dev_err(&spi->dev, "spi_setup failed, err=%d\n", err);
- goto err_drvdata;
+ return err;
}
err = ks8995_read(ks, ids, KS8995_REG_ID0, sizeof(ids));
if (err < 0) {
dev_err(&spi->dev, "unable to read id registers, err=%d\n",
err);
- goto err_drvdata;
+ return err;
}
switch (ids[0]) {
@@ -306,8 +306,7 @@ static int ks8995_probe(struct spi_device *spi)
break;
default:
dev_err(&spi->dev, "unknown family id:%02x\n", ids[0]);
- err = -ENODEV;
- goto err_drvdata;
+ return -ENODEV;
}
memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr));
@@ -320,24 +319,24 @@ static int ks8995_probe(struct spi_device *spi)
dev_err(&spi->dev,
"unable to read chip id register, err=%d\n",
err);
- goto err_drvdata;
+ return err;
}
if ((val & 0x80) == 0) {
dev_err(&spi->dev, "unknown chip:%02x,0\n", ids[1]);
- goto err_drvdata;
+ return err;
}
ks->regs_attr.size = KSZ8864_REGS_SIZE;
}
err = ks8995_reset(ks);
if (err)
- goto err_drvdata;
+ return err;
err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr);
if (err) {
dev_err(&spi->dev, "unable to create sysfs file, err=%d\n",
err);
- goto err_drvdata;
+ return err;
}
if (get_chip_id(ids[1]) == CHIPID_M) {
@@ -350,21 +349,12 @@ static int ks8995_probe(struct spi_device *spi)
}
return 0;
-
-err_drvdata:
- kfree(ks);
- return err;
}
static int ks8995_remove(struct spi_device *spi)
{
- struct ks8995_data *ks8995;
-
- ks8995 = spi_get_drvdata(spi);
sysfs_remove_bin_file(&spi->dev.kobj, &ks8995_registers_attr);
- kfree(ks8995);
-
return 0;
}
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 91d6c1272fcf..fa0d71727894 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -143,8 +143,8 @@ struct ppp {
struct sk_buff_head mrq; /* MP: receive reconstruction queue */
#endif /* CONFIG_PPP_MULTILINK */
#ifdef CONFIG_PPP_FILTER
- struct sk_filter *pass_filter; /* filter for packets to pass */
- struct sk_filter *active_filter;/* filter for pkts to reset idle */
+ struct bpf_prog *pass_filter; /* filter for packets to pass */
+ struct bpf_prog *active_filter; /* filter for pkts to reset idle */
#endif /* CONFIG_PPP_FILTER */
struct net *ppp_net; /* the net we belong to */
struct ppp_link_stats stats64; /* 64 bit network stats */
@@ -539,7 +539,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
{
struct sock_fprog uprog;
struct sock_filter *code = NULL;
- int len, err;
+ int len;
if (copy_from_user(&uprog, arg, sizeof(uprog)))
return -EFAULT;
@@ -554,12 +554,6 @@ static int get_filter(void __user *arg, struct sock_filter **p)
if (IS_ERR(code))
return PTR_ERR(code);
- err = sk_chk_filter(code, uprog.len);
- if (err) {
- kfree(code);
- return err;
- }
-
*p = code;
return uprog.len;
}
@@ -661,6 +655,10 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
ppp_lock(ppp);
cflags = ppp->flags & ~val;
+#ifdef CONFIG_PPP_MULTILINK
+ if (!(ppp->flags & SC_MULTILINK) && (val & SC_MULTILINK))
+ ppp->nextseq = 0;
+#endif
ppp->flags = val & SC_FLAG_BITS;
ppp_unlock(ppp);
if (cflags & SC_CCP_OPEN)
@@ -763,10 +761,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
};
ppp_lock(ppp);
- if (ppp->pass_filter)
- sk_unattached_filter_destroy(ppp->pass_filter);
- err = sk_unattached_filter_create(&ppp->pass_filter,
- &fprog);
+ if (ppp->pass_filter) {
+ bpf_prog_destroy(ppp->pass_filter);
+ ppp->pass_filter = NULL;
+ }
+ if (fprog.filter != NULL)
+ err = bpf_prog_create(&ppp->pass_filter,
+ &fprog);
+ else
+ err = 0;
kfree(code);
ppp_unlock(ppp);
}
@@ -784,10 +787,15 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
};
ppp_lock(ppp);
- if (ppp->active_filter)
- sk_unattached_filter_destroy(ppp->active_filter);
- err = sk_unattached_filter_create(&ppp->active_filter,
- &fprog);
+ if (ppp->active_filter) {
+ bpf_prog_destroy(ppp->active_filter);
+ ppp->active_filter = NULL;
+ }
+ if (fprog.filter != NULL)
+ err = bpf_prog_create(&ppp->active_filter,
+ &fprog);
+ else
+ err = 0;
kfree(code);
ppp_unlock(ppp);
}
@@ -1197,7 +1205,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
a four-byte PPP header on each packet */
*skb_push(skb, 2) = 1;
if (ppp->pass_filter &&
- SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
+ BPF_PROG_RUN(ppp->pass_filter, skb) == 0) {
if (ppp->debug & 1)
netdev_printk(KERN_DEBUG, ppp->dev,
"PPP: outbound frame "
@@ -1207,7 +1215,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
}
/* if this packet passes the active filter, record the time */
if (!(ppp->active_filter &&
- SK_RUN_FILTER(ppp->active_filter, skb) == 0))
+ BPF_PROG_RUN(ppp->active_filter, skb) == 0))
ppp->last_xmit = jiffies;
skb_pull(skb, 2);
#else
@@ -1831,7 +1839,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
*skb_push(skb, 2) = 0;
if (ppp->pass_filter &&
- SK_RUN_FILTER(ppp->pass_filter, skb) == 0) {
+ BPF_PROG_RUN(ppp->pass_filter, skb) == 0) {
if (ppp->debug & 1)
netdev_printk(KERN_DEBUG, ppp->dev,
"PPP: inbound frame "
@@ -1840,7 +1848,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
return;
}
if (!(ppp->active_filter &&
- SK_RUN_FILTER(ppp->active_filter, skb) == 0))
+ BPF_PROG_RUN(ppp->active_filter, skb) == 0))
ppp->last_recv = jiffies;
__skb_pull(skb, 2);
} else
@@ -2665,7 +2673,8 @@ ppp_create_interface(struct net *net, int unit, int *retp)
int ret = -ENOMEM;
int i;
- dev = alloc_netdev(sizeof(struct ppp), "", ppp_setup);
+ dev = alloc_netdev(sizeof(struct ppp), "", NET_NAME_UNKNOWN,
+ ppp_setup);
if (!dev)
goto out1;
@@ -2820,12 +2829,12 @@ static void ppp_destroy_interface(struct ppp *ppp)
#endif /* CONFIG_PPP_MULTILINK */
#ifdef CONFIG_PPP_FILTER
if (ppp->pass_filter) {
- sk_unattached_filter_destroy(ppp->pass_filter);
+ bpf_prog_destroy(ppp->pass_filter);
ppp->pass_filter = NULL;
}
if (ppp->active_filter) {
- sk_unattached_filter_destroy(ppp->active_filter);
+ bpf_prog_destroy(ppp->active_filter);
ppp->active_filter = NULL;
}
#endif /* CONFIG_PPP_FILTER */
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 2ea7efd11857..6c9c16d76935 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -675,7 +675,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.hdrlen = (sizeof(struct pppoe_hdr) +
dev->hard_header_len);
- po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr);
+ po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
index 1252d9c726a7..079f7adfcde5 100644
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -396,7 +396,6 @@ found:
ntohs(cs->cs_ip.tot_len) == hlen)
break;
goto uncompressed;
- break;
case SPECIAL_I:
case SPECIAL_D:
/* actual changes match one of our special case encodings --
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index 87526443841f..05387b1e2e95 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -749,7 +749,7 @@ static struct slip *sl_alloc(dev_t line)
return NULL;
sprintf(name, "sl%d", i);
- dev = alloc_netdev(sizeof(*sl), name, sl_setup);
+ dev = alloc_netdev(sizeof(*sl), name, NET_NAME_UNKNOWN, sl_setup);
if (!dev)
return NULL;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index b4958c7ffa84..ef10302ec936 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2045,16 +2045,10 @@ static void team_setup(struct net_device *dev)
static int team_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
- int err;
-
if (tb[IFLA_ADDRESS] == NULL)
eth_hw_addr_random(dev);
- err = register_netdevice(dev);
- if (err)
- return err;
-
- return 0;
+ return register_netdevice(dev);
}
static int team_validate(struct nlattr *tb[], struct nlattr *data[])
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
index a58dfebb5512..a1536d0d83a9 100644
--- a/drivers/net/team/team_mode_loadbalance.c
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -58,7 +58,7 @@ struct lb_priv_ex {
};
struct lb_priv {
- struct sk_filter __rcu *fp;
+ struct bpf_prog __rcu *fp;
lb_select_tx_port_func_t __rcu *select_tx_port_func;
struct lb_pcpu_stats __percpu *pcpu_stats;
struct lb_priv_ex *ex; /* priv extension */
@@ -174,14 +174,14 @@ static lb_select_tx_port_func_t *lb_select_tx_port_get_func(const char *name)
static unsigned int lb_get_skb_hash(struct lb_priv *lb_priv,
struct sk_buff *skb)
{
- struct sk_filter *fp;
+ struct bpf_prog *fp;
uint32_t lhash;
unsigned char *c;
fp = rcu_dereference_bh(lb_priv->fp);
if (unlikely(!fp))
return 0;
- lhash = SK_RUN_FILTER(fp, skb);
+ lhash = BPF_PROG_RUN(fp, skb);
c = (char *) &lhash;
return c[0] ^ c[1] ^ c[2] ^ c[3];
}
@@ -271,8 +271,8 @@ static void __fprog_destroy(struct sock_fprog_kern *fprog)
static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
{
struct lb_priv *lb_priv = get_lb_priv(team);
- struct sk_filter *fp = NULL;
- struct sk_filter *orig_fp;
+ struct bpf_prog *fp = NULL;
+ struct bpf_prog *orig_fp = NULL;
struct sock_fprog_kern *fprog = NULL;
int err;
@@ -281,7 +281,7 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
ctx->data.bin_val.ptr);
if (err)
return err;
- err = sk_unattached_filter_create(&fp, fprog);
+ err = bpf_prog_create(&fp, fprog);
if (err) {
__fprog_destroy(fprog);
return err;
@@ -293,11 +293,15 @@ static int lb_bpf_func_set(struct team *team, struct team_gsetter_ctx *ctx)
__fprog_destroy(lb_priv->ex->orig_fprog);
orig_fp = rcu_dereference_protected(lb_priv->fp,
lockdep_is_held(&team->lock));
- sk_unattached_filter_destroy(orig_fp);
}
rcu_assign_pointer(lb_priv->fp, fp);
lb_priv->ex->orig_fprog = fprog;
+
+ if (orig_fp) {
+ synchronize_rcu();
+ bpf_prog_destroy(orig_fp);
+ }
return 0;
}
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 98bad1fb1bfb..acaaf6784179 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1633,7 +1633,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
name = ifr->ifr_name;
dev = alloc_netdev_mqs(sizeof(struct tun_struct), name,
- tun_setup, queues, queues);
+ NET_NAME_UNKNOWN, tun_setup, queues,
+ queues);
if (!dev)
return -ENOMEM;
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 7e7269fd3707..37eed4d84e9c 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -1,12 +1,16 @@
#
# USB Network devices configuration
#
-comment "Networking support is needed for USB Network Adapter support"
- depends on USB && !NET
+comment "Host-side USB support is needed for USB Network Adapter support"
+ depends on !USB && NET
-menu "USB Network Adapters"
+menuconfig USB_NET_DRIVERS
+ tristate "USB Network Adapters"
+ default USB if USB
depends on USB && NET
+if USB_NET_DRIVERS
+
config USB_CATC
tristate "USB CATC NetMate-based Ethernet device support"
select CRC32
@@ -568,5 +572,4 @@ config USB_VL600
http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
-
-endmenu
+endif # USB_NET_DRIVERS
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 054e59ca6946..be4275721039 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -23,6 +23,8 @@
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/usbnet.h>
+#include <uapi/linux/mdio.h>
+#include <linux/mdio.h>
#define AX88179_PHY_ID 0x03
#define AX_EEPROM_LEN 0x100
@@ -170,8 +172,12 @@
#define GMII_PHY_PAGE_SELECT 0x1f
#define GMII_PHY_PGSEL_EXT 0x0007
#define GMII_PHY_PGSEL_PAGE0 0x0000
+ #define GMII_PHY_PGSEL_PAGE3 0x0003
+ #define GMII_PHY_PGSEL_PAGE5 0x0005
struct ax88179_data {
+ u8 eee_enabled;
+ u8 eee_active;
u16 rxctl;
u16 reserved;
};
@@ -373,6 +379,60 @@ static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
}
+static inline int ax88179_phy_mmd_indirect(struct usbnet *dev, u16 prtad,
+ u16 devad)
+{
+ u16 tmp16;
+ int ret;
+
+ tmp16 = devad;
+ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_MMD_CTRL, 2, &tmp16);
+
+ tmp16 = prtad;
+ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_MMD_DATA, 2, &tmp16);
+
+ tmp16 = devad | MII_MMD_CTRL_NOINCR;
+ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_MMD_CTRL, 2, &tmp16);
+
+ return ret;
+}
+
+static int
+ax88179_phy_read_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad)
+{
+ int ret;
+ u16 tmp16;
+
+ ax88179_phy_mmd_indirect(dev, prtad, devad);
+
+ ret = ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_MMD_DATA, 2, &tmp16);
+ if (ret < 0)
+ return ret;
+
+ return tmp16;
+}
+
+static int
+ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad,
+ u16 data)
+{
+ int ret;
+
+ ax88179_phy_mmd_indirect(dev, prtad, devad);
+
+ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_MMD_DATA, 2, &data);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
@@ -572,6 +632,185 @@ static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
return mii_ethtool_sset(&dev->mii, cmd);
}
+static int
+ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_eee *data)
+{
+ int val;
+
+ /* Get Supported EEE */
+ val = ax88179_phy_read_mmd_indirect(dev, MDIO_PCS_EEE_ABLE,
+ MDIO_MMD_PCS);
+ if (val < 0)
+ return val;
+ data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
+
+ /* Get advertisement EEE */
+ val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_ADV,
+ MDIO_MMD_AN);
+ if (val < 0)
+ return val;
+ data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+ /* Get LP advertisement EEE */
+ val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_LPABLE,
+ MDIO_MMD_AN);
+ if (val < 0)
+ return val;
+ data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+ return 0;
+}
+
+static int
+ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_eee *data)
+{
+ u16 tmp16 = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
+
+ return ax88179_phy_write_mmd_indirect(dev, MDIO_AN_EEE_ADV,
+ MDIO_MMD_AN, tmp16);
+}
+
+static int ax88179_chk_eee(struct usbnet *dev)
+{
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+ struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+
+ mii_ethtool_gset(&dev->mii, &ecmd);
+
+ if (ecmd.duplex & DUPLEX_FULL) {
+ int eee_lp, eee_cap, eee_adv;
+ u32 lp, cap, adv, supported = 0;
+
+ eee_cap = ax88179_phy_read_mmd_indirect(dev,
+ MDIO_PCS_EEE_ABLE,
+ MDIO_MMD_PCS);
+ if (eee_cap < 0) {
+ priv->eee_active = 0;
+ return false;
+ }
+
+ cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
+ if (!cap) {
+ priv->eee_active = 0;
+ return false;
+ }
+
+ eee_lp = ax88179_phy_read_mmd_indirect(dev,
+ MDIO_AN_EEE_LPABLE,
+ MDIO_MMD_AN);
+ if (eee_lp < 0) {
+ priv->eee_active = 0;
+ return false;
+ }
+
+ eee_adv = ax88179_phy_read_mmd_indirect(dev,
+ MDIO_AN_EEE_ADV,
+ MDIO_MMD_AN);
+
+ if (eee_adv < 0) {
+ priv->eee_active = 0;
+ return false;
+ }
+
+ adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
+ lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
+ supported = (ecmd.speed == SPEED_1000) ?
+ SUPPORTED_1000baseT_Full :
+ SUPPORTED_100baseT_Full;
+
+ if (!(lp & adv & supported)) {
+ priv->eee_active = 0;
+ return false;
+ }
+
+ priv->eee_active = 1;
+ return true;
+ }
+
+ priv->eee_active = 0;
+ return false;
+}
+
+static void ax88179_disable_eee(struct usbnet *dev)
+{
+ u16 tmp16;
+
+ tmp16 = GMII_PHY_PGSEL_PAGE3;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ GMII_PHY_PAGE_SELECT, 2, &tmp16);
+
+ tmp16 = 0x3246;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_PHYADDR, 2, &tmp16);
+
+ tmp16 = GMII_PHY_PGSEL_PAGE0;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ GMII_PHY_PAGE_SELECT, 2, &tmp16);
+}
+
+static void ax88179_enable_eee(struct usbnet *dev)
+{
+ u16 tmp16;
+
+ tmp16 = GMII_PHY_PGSEL_PAGE3;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ GMII_PHY_PAGE_SELECT, 2, &tmp16);
+
+ tmp16 = 0x3247;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_PHYADDR, 2, &tmp16);
+
+ tmp16 = GMII_PHY_PGSEL_PAGE5;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ GMII_PHY_PAGE_SELECT, 2, &tmp16);
+
+ tmp16 = 0x0680;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ MII_BMSR, 2, &tmp16);
+
+ tmp16 = GMII_PHY_PGSEL_PAGE0;
+ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+ GMII_PHY_PAGE_SELECT, 2, &tmp16);
+}
+
+static int ax88179_get_eee(struct net_device *net, struct ethtool_eee *edata)
+{
+ struct usbnet *dev = netdev_priv(net);
+ struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+
+ edata->eee_enabled = priv->eee_enabled;
+ edata->eee_active = priv->eee_active;
+
+ return ax88179_ethtool_get_eee(dev, edata);
+}
+
+static int ax88179_set_eee(struct net_device *net, struct ethtool_eee *edata)
+{
+ struct usbnet *dev = netdev_priv(net);
+ struct ax88179_data *priv = (struct ax88179_data *)dev->data;
+ int ret = -EOPNOTSUPP;
+
+ priv->eee_enabled = edata->eee_enabled;
+ if (!priv->eee_enabled) {
+ ax88179_disable_eee(dev);
+ } else {
+ priv->eee_enabled = ax88179_chk_eee(dev);
+ if (!priv->eee_enabled)
+ return -EOPNOTSUPP;
+
+ ax88179_enable_eee(dev);
+ }
+
+ ret = ax88179_ethtool_set_eee(dev, edata);
+ if (ret)
+ return ret;
+
+ mii_nway_restart(&dev->mii);
+
+ usbnet_link_change(dev, 0, 0);
+
+ return ret;
+}
static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{
@@ -589,6 +828,8 @@ static const struct ethtool_ops ax88179_ethtool_ops = {
.get_eeprom = ax88179_get_eeprom,
.get_settings = ax88179_get_settings,
.set_settings = ax88179_set_settings,
+ .get_eee = ax88179_get_eee,
+ .set_eee = ax88179_set_eee,
.nway_reset = usbnet_nway_reset,
};
@@ -980,6 +1221,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
u16 *tmp16;
u8 *tmp;
struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+ struct ethtool_eee eee_data;
usbnet_get_endpoints(dev, intf);
@@ -1062,6 +1304,15 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
ax88179_led_setting(dev);
+ ax179_data->eee_enabled = 0;
+ ax179_data->eee_active = 0;
+
+ ax88179_disable_eee(dev);
+
+ ax88179_ethtool_get_eee(dev, &eee_data);
+ eee_data.advertised = 0;
+ ax88179_ethtool_set_eee(dev, &eee_data);
+
/* Restart autoneg */
mii_nway_restart(&dev->mii);
@@ -1261,6 +1512,8 @@ static int ax88179_link_reset(struct usbnet *dev)
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
2, 2, &mode);
+ ax179_data->eee_enabled = ax88179_chk_eee(dev);
+
netif_carrier_on(dev->net);
return 0;
@@ -1271,6 +1524,8 @@ static int ax88179_reset(struct usbnet *dev)
u8 buf[5];
u16 *tmp16;
u8 *tmp;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+ struct ethtool_eee eee_data;
tmp16 = (u16 *)buf;
tmp = (u8 *)buf;
@@ -1340,6 +1595,15 @@ static int ax88179_reset(struct usbnet *dev)
ax88179_led_setting(dev);
+ ax179_data->eee_enabled = 0;
+ ax179_data->eee_active = 0;
+
+ ax88179_disable_eee(dev);
+
+ ax88179_ethtool_get_eee(dev, &eee_data);
+ eee_data.advertised = 0;
+ ax88179_ethtool_set_eee(dev, &eee_data);
+
/* Restart autoneg */
mii_nway_restart(&dev->mii);
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index 6358d420e185..2ec1500d0077 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -387,7 +387,7 @@ static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *i
return -EINVAL;
dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size,
- ifname, usbpn_setup);
+ ifname, NET_NAME_UNKNOWN, usbpn_setup);
if (!dev)
return -ENOMEM;
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 9ea4bfe5d318..2a32d9167d3b 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -341,6 +341,22 @@ next_desc:
usb_driver_release_interface(driver, info->data);
return -ENODEV;
}
+
+ /* Some devices don't initialise properly. In particular
+ * the packet filter is not reset. There are devices that
+ * don't do reset all the way. So the packet filter should
+ * be set to a sane initial value.
+ */
+ usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ USB_CDC_SET_ETHERNET_PACKET_FILTER,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | USB_CDC_PACKET_TYPE_BROADCAST,
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ NULL,
+ 0,
+ USB_CTRL_SET_TIMEOUT
+ );
return 0;
bad_desc:
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index 91f0919fe278..6ea98cff2d3b 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -85,14 +85,28 @@ static int always_connected (struct usbnet *dev)
*
*-------------------------------------------------------------------------*/
+static void m5632_recover(struct usbnet *dev)
+{
+ struct usb_device *udev = dev->udev;
+ struct usb_interface *intf = dev->intf;
+ int r;
+
+ r = usb_lock_device_for_reset(udev, intf);
+ if (r < 0)
+ return;
+
+ usb_reset_device(udev);
+ usb_unlock_device(udev);
+}
+
static const struct driver_info ali_m5632_info = {
.description = "ALi M5632",
.flags = FLAG_POINTTOPOINT,
+ .recover = m5632_recover,
};
#endif
-
#ifdef CONFIG_USB_AN2720
#define HAVE_HARDWARE
@@ -326,12 +340,23 @@ static const struct usb_device_id products [] = {
MODULE_DEVICE_TABLE(usb, products);
/*-------------------------------------------------------------------------*/
+static int dummy_prereset(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static int dummy_postreset(struct usb_interface *intf)
+{
+ return 0;
+}
static struct usb_driver cdc_subset_driver = {
.name = "cdc_subset",
.probe = usbnet_probe,
.suspend = usbnet_suspend,
.resume = usbnet_resume,
+ .pre_reset = dummy_prereset,
+ .post_reset = dummy_postreset,
.disconnect = usbnet_disconnect,
.id_table = products,
.disable_hub_initiated_lpm = 1,
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index a3a05869309d..babda7d8693e 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -258,10 +258,8 @@ struct hso_serial {
* so as not to drop characters on the floor.
*/
int curr_rx_urb_idx;
- u16 curr_rx_urb_offset;
u8 rx_urb_filled[MAX_RX_URBS];
struct tasklet_struct unthrottle_tasklet;
- struct work_struct retry_unthrottle_workqueue;
};
struct hso_device {
@@ -469,6 +467,7 @@ static const struct usb_device_id hso_ids[] = {
{USB_DEVICE(0x0af0, 0x8800)},
{USB_DEVICE(0x0af0, 0x8900)},
{USB_DEVICE(0x0af0, 0x9000)},
+ {USB_DEVICE(0x0af0, 0x9200)}, /* Option GTM671WFS */
{USB_DEVICE(0x0af0, 0xd035)},
{USB_DEVICE(0x0af0, 0xd055)},
{USB_DEVICE(0x0af0, 0xd155)},
@@ -1252,14 +1251,6 @@ static void hso_unthrottle(struct tty_struct *tty)
tasklet_hi_schedule(&serial->unthrottle_tasklet);
}
-static void hso_unthrottle_workfunc(struct work_struct *work)
-{
- struct hso_serial *serial =
- container_of(work, struct hso_serial,
- retry_unthrottle_workqueue);
- hso_unthrottle_tasklet(serial);
-}
-
/* open the requested serial port */
static int hso_serial_open(struct tty_struct *tty, struct file *filp)
{
@@ -1295,8 +1286,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
tasklet_init(&serial->unthrottle_tasklet,
(void (*)(unsigned long))hso_unthrottle_tasklet,
(unsigned long)serial);
- INIT_WORK(&serial->retry_unthrottle_workqueue,
- hso_unthrottle_workfunc);
result = hso_start_serial_device(serial->parent, GFP_KERNEL);
if (result) {
hso_stop_serial_device(serial->parent);
@@ -1345,7 +1334,6 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
if (!usb_gone)
hso_stop_serial_device(serial->parent);
tasklet_kill(&serial->unthrottle_tasklet);
- cancel_work_sync(&serial->retry_unthrottle_workqueue);
}
if (!usb_gone)
@@ -2013,8 +2001,7 @@ static void ctrl_callback(struct urb *urb)
static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
{
struct tty_struct *tty;
- int write_length_remaining = 0;
- int curr_write_len;
+ int count;
/* Sanity check */
if (urb == NULL || serial == NULL) {
@@ -2024,29 +2011,28 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
tty = tty_port_tty_get(&serial->port);
+ if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
+ tty_kref_put(tty);
+ return -1;
+ }
+
/* Push data to tty */
- write_length_remaining = urb->actual_length -
- serial->curr_rx_urb_offset;
D1("data to push to tty");
- while (write_length_remaining) {
- if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
- tty_kref_put(tty);
- return -1;
- }
- curr_write_len = tty_insert_flip_string(&serial->port,
- urb->transfer_buffer + serial->curr_rx_urb_offset,
- write_length_remaining);
- serial->curr_rx_urb_offset += curr_write_len;
- write_length_remaining -= curr_write_len;
+ count = tty_buffer_request_room(&serial->port, urb->actual_length);
+ if (count >= urb->actual_length) {
+ tty_insert_flip_string(&serial->port, urb->transfer_buffer,
+ urb->actual_length);
tty_flip_buffer_push(&serial->port);
+ } else {
+ dev_warn(&serial->parent->usb->dev,
+ "dropping data, %d bytes lost\n", urb->actual_length);
}
+
tty_kref_put(tty);
- if (write_length_remaining == 0) {
- serial->curr_rx_urb_offset = 0;
- serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
- }
- return write_length_remaining;
+ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
+
+ return 0;
}
@@ -2217,7 +2203,6 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
}
}
serial->curr_rx_urb_idx = 0;
- serial->curr_rx_urb_offset = 0;
if (serial->tx_urb)
usb_kill_urb(serial->tx_urb);
@@ -2520,7 +2505,8 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
/* allocate our network device, then we can put in our private data */
/* call hso_net_init to do the basic initialization */
- net = alloc_netdev(sizeof(struct hso_net), "hso%d", hso_net_init);
+ net = alloc_netdev(sizeof(struct hso_net), "hso%d", NET_NAME_UNKNOWN,
+ hso_net_init);
if (!net) {
dev_err(&interface->dev, "Unable to create ethernet device\n");
goto exit;
diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c
index 5d95a13dbe2a..735f7dadb9a0 100644
--- a/drivers/net/usb/huawei_cdc_ncm.c
+++ b/drivers/net/usb/huawei_cdc_ncm.c
@@ -194,6 +194,9 @@ static const struct usb_device_id huawei_cdc_ncm_devs[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76),
.driver_info = (unsigned long)&huawei_cdc_ncm_info,
},
+ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16),
+ .driver_info = (unsigned long)&huawei_cdc_ncm_info,
+ },
/* Terminating entry */
{
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index cf62d7e8329f..22756db53dca 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -667,6 +667,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
+ {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
{QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
@@ -741,6 +742,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x19d2, 0x1424, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1425, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */
+ {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
@@ -756,6 +758,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 25431965a625..87f710476217 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -59,6 +59,7 @@
#define PLA_WDT6_CTRL 0xe428
#define PLA_TCR0 0xe610
#define PLA_TCR1 0xe612
+#define PLA_MTPS 0xe615
#define PLA_TXFIFO_CTRL 0xe618
#define PLA_RSTTALLY 0xe800
#define PLA_CR 0xe813
@@ -180,6 +181,10 @@
/* PLA_TCR1 */
#define VERSION_MASK 0x7cf0
+/* PLA_MTPS */
+#define MTPS_JUMBO (12 * 1024 / 64)
+#define MTPS_DEFAULT (6 * 1024 / 64)
+
/* PLA_RSTTALLY */
#define TALLY_RESET 0x0001
@@ -282,7 +287,7 @@
/* USB_DEV_STAT */
#define STAT_SPEED_MASK 0x0006
#define STAT_SPEED_HIGH 0x0000
-#define STAT_SPEED_FULL 0x0001
+#define STAT_SPEED_FULL 0x0002
/* USB_TX_AGG */
#define TX_AGG_MAX_THRESHOLD 0x03
@@ -440,8 +445,11 @@ enum rtl_register_content {
#define BYTE_EN_START_MASK 0x0f
#define BYTE_EN_END_MASK 0xf0
+#define RTL8153_MAX_PACKET 9216 /* 9K */
+#define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - VLAN_HLEN)
#define RTL8152_RMS (VLAN_ETH_FRAME_LEN + VLAN_HLEN)
-#define RTL8152_TX_TIMEOUT (HZ)
+#define RTL8153_RMS RTL8153_MAX_PACKET
+#define RTL8152_TX_TIMEOUT (5 * HZ)
/* rtl8152 flags */
enum rtl8152_flags {
@@ -1359,7 +1367,7 @@ static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
struct sk_buff_head seg_list;
struct sk_buff *segs, *nskb;
- features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+ features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
segs = skb_gso_segment(skb, features);
if (IS_ERR(segs) || !segs)
goto drop;
@@ -2292,9 +2300,8 @@ static void r8152b_exit_oob(struct r8152 *tp)
/* rx share fifo credit full threshold */
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL);
- ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_DEV_STAT);
- ocp_data &= STAT_SPEED_MASK;
- if (ocp_data == STAT_SPEED_FULL) {
+ if (tp->udev->speed == USB_SPEED_FULL ||
+ tp->udev->speed == USB_SPEED_LOW) {
/* rx share fifo credit near full threshold */
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1,
RXFIFO_THR2_FULL);
@@ -2522,7 +2529,8 @@ static void r8153_first_init(struct r8152 *tp)
ocp_data &= ~CPCR_RX_VLAN;
ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
+ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO);
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0);
ocp_data |= TCR0_AUTO_FIFO;
@@ -2572,7 +2580,7 @@ static void r8153_enter_oob(struct r8152 *tp)
mdelay(1);
}
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS);
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
ocp_data &= ~TEREDO_WAKE_MASK;
@@ -3204,8 +3212,13 @@ static void rtl8152_get_ethtool_stats(struct net_device *dev,
struct r8152 *tp = netdev_priv(dev);
struct tally_counter tally;
+ if (usb_autopm_get_interface(tp->intf) < 0)
+ return;
+
generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA);
+ usb_autopm_put_interface(tp->intf);
+
data[0] = le64_to_cpu(tally.tx_packets);
data[1] = le64_to_cpu(tally.rx_packets);
data[2] = le64_to_cpu(tally.tx_errors);
@@ -3284,6 +3297,26 @@ out:
return res;
}
+static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct r8152 *tp = netdev_priv(dev);
+
+ switch (tp->version) {
+ case RTL_VER_01:
+ case RTL_VER_02:
+ return eth_change_mtu(dev, new_mtu);
+ default:
+ break;
+ }
+
+ if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
static const struct net_device_ops rtl8152_netdev_ops = {
.ndo_open = rtl8152_open,
.ndo_stop = rtl8152_close,
@@ -3292,8 +3325,7 @@ static const struct net_device_ops rtl8152_netdev_ops = {
.ndo_tx_timeout = rtl8152_tx_timeout,
.ndo_set_rx_mode = rtl8152_set_rx_mode,
.ndo_set_mac_address = rtl8152_set_mac_address,
-
- .ndo_change_mtu = eth_change_mtu,
+ .ndo_change_mtu = rtl8152_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 424db65e4396..d07bf4cb893f 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1714,6 +1714,18 @@ static int smsc95xx_resume(struct usb_interface *intf)
return ret;
}
+static int smsc95xx_reset_resume(struct usb_interface *intf)
+{
+ struct usbnet *dev = usb_get_intfdata(intf);
+ int ret;
+
+ ret = smsc95xx_reset(dev);
+ if (ret < 0)
+ return ret;
+
+ return smsc95xx_resume(intf);
+}
+
static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
{
skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
@@ -2004,7 +2016,7 @@ static struct usb_driver smsc95xx_driver = {
.probe = usbnet_probe,
.suspend = smsc95xx_suspend,
.resume = smsc95xx_resume,
- .reset_resume = smsc95xx_resume,
+ .reset_resume = smsc95xx_reset_resume,
.disconnect = usbnet_disconnect,
.disable_hub_initiated_lpm = 1,
.supports_autosuspend = 1,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9e96c427558..5173821a9575 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1218,8 +1218,12 @@ void usbnet_tx_timeout (struct net_device *net)
unlink_urbs (dev, &dev->txq);
tasklet_schedule (&dev->bh);
-
- // FIXME: device recovery -- reset?
+ /* this needs to be handled individually because the generic layer
+ * doesn't know what is sufficient and could not restore private
+ * information if a remedy of an unconditional reset were used.
+ */
+ if (dev->driver_info->recover)
+ (dev->driver_info->recover)(dev);
}
EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index b4a10bcb66a0..8ad596573d17 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -248,6 +248,21 @@ static void veth_dev_free(struct net_device *dev)
free_netdev(dev);
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void veth_poll_controller(struct net_device *dev)
+{
+ /* veth only receives frames when its peer sends one
+ * Since it's a synchronous operation, we are guaranteed
+ * never to have pending data when we poll for it so
+ * there is nothing to do here.
+ *
+ * We need this though so netpoll recognizes us as an interface that
+ * supports polling, which enables bridge devices in virt setups to
+ * still use netconsole
+ */
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
static const struct net_device_ops veth_netdev_ops = {
.ndo_init = veth_dev_init,
.ndo_open = veth_open,
@@ -257,6 +272,9 @@ static const struct net_device_ops veth_netdev_ops = {
.ndo_get_stats64 = veth_get_stats64,
.ndo_set_rx_mode = veth_set_multicast_list,
.ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = veth_poll_controller,
+#endif
};
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
@@ -317,6 +335,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
struct veth_priv *priv;
char ifname[IFNAMSIZ];
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
+ unsigned char name_assign_type;
struct ifinfomsg *ifmp;
struct net *net;
@@ -344,16 +363,20 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
tbp = tb;
}
- if (tbp[IFLA_IFNAME])
+ if (tbp[IFLA_IFNAME]) {
nla_strlcpy(ifname, tbp[IFLA_IFNAME], IFNAMSIZ);
- else
+ name_assign_type = NET_NAME_USER;
+ } else {
snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
+ name_assign_type = NET_NAME_ENUM;
+ }
net = rtnl_link_get_net(src_net, tbp);
if (IS_ERR(net))
return PTR_ERR(net);
- peer = rtnl_create_link(net, ifname, &veth_link_ops, tbp);
+ peer = rtnl_create_link(net, ifname, name_assign_type,
+ &veth_link_ops, tbp);
if (IS_ERR(peer)) {
put_net(net);
return PTR_ERR(peer);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7d9f84a91f37..59caa06f34a6 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/average.h>
+#include <net/busy_poll.h>
static int napi_weight = NAPI_POLL_WEIGHT;
module_param(napi_weight, int, 0444);
@@ -521,6 +522,8 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len)
skb_shinfo(skb)->gso_segs = 0;
}
+ skb_mark_napi_id(skb, &rq->napi);
+
netif_receive_skb(skb);
return;
@@ -725,15 +728,12 @@ static void refill_work(struct work_struct *work)
}
}
-static int virtnet_poll(struct napi_struct *napi, int budget)
+static int virtnet_receive(struct receive_queue *rq, int budget)
{
- struct receive_queue *rq =
- container_of(napi, struct receive_queue, napi);
struct virtnet_info *vi = rq->vq->vdev->priv;
+ unsigned int len, received = 0;
void *buf;
- unsigned int r, len, received = 0;
-again:
while (received < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
receive_buf(rq, buf, len);
@@ -745,6 +745,18 @@ again:
schedule_delayed_work(&vi->refill, 0);
}
+ return received;
+}
+
+static int virtnet_poll(struct napi_struct *napi, int budget)
+{
+ struct receive_queue *rq =
+ container_of(napi, struct receive_queue, napi);
+ unsigned int r, received = 0;
+
+again:
+ received += virtnet_receive(rq, budget - received);
+
/* Out of packets? */
if (received < budget) {
r = virtqueue_enable_cb_prepare(rq->vq);
@@ -760,6 +772,43 @@ again:
return received;
}
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/* must be called with local_bh_disable()d */
+static int virtnet_busy_poll(struct napi_struct *napi)
+{
+ struct receive_queue *rq =
+ container_of(napi, struct receive_queue, napi);
+ struct virtnet_info *vi = rq->vq->vdev->priv;
+ int r, received = 0, budget = 4;
+
+ if (!(vi->status & VIRTIO_NET_S_LINK_UP))
+ return LL_FLUSH_FAILED;
+
+ if (!napi_schedule_prep(napi))
+ return LL_FLUSH_BUSY;
+
+ virtqueue_disable_cb(rq->vq);
+
+again:
+ received += virtnet_receive(rq, budget);
+
+ r = virtqueue_enable_cb_prepare(rq->vq);
+ clear_bit(NAPI_STATE_SCHED, &napi->state);
+ if (unlikely(virtqueue_poll(rq->vq, r)) &&
+ napi_schedule_prep(napi)) {
+ virtqueue_disable_cb(rq->vq);
+ if (received < budget) {
+ budget -= received;
+ goto again;
+ } else {
+ __napi_schedule(napi);
+ }
+ }
+
+ return received;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
static int virtnet_open(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -1347,6 +1396,9 @@ static const struct net_device_ops virtnet_netdev = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = virtnet_netpoll,
#endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ .ndo_busy_poll = virtnet_busy_poll,
+#endif
};
static void virtnet_config_changed_work(struct work_struct *work)
@@ -1552,6 +1604,7 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
vi->rq[i].pages = NULL;
netif_napi_add(vi->dev, &vi->rq[i].napi, virtnet_poll,
napi_weight);
+ napi_hash_add(&vi->rq[i].napi);
sg_init_table(vi->rq[i].sg, ARRAY_SIZE(vi->rq[i].sg));
ewma_init(&vi->rq[i].mrg_avg_pkt_len, 1, RECEIVE_AVG_WEIGHT);
@@ -1853,11 +1906,13 @@ static int virtnet_freeze(struct virtio_device *vdev)
netif_device_detach(vi->dev);
cancel_delayed_work_sync(&vi->refill);
- if (netif_running(vi->dev))
+ if (netif_running(vi->dev)) {
for (i = 0; i < vi->max_queue_pairs; i++) {
napi_disable(&vi->rq[i].napi);
+ napi_hash_del(&vi->rq[i].napi);
netif_napi_del(&vi->rq[i].napi);
}
+ }
remove_vq_common(vi);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index b76f7dcde0db..d0db371c30a7 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -766,7 +766,7 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
gdesc->dword[3] = 0;
netdev_dbg(adapter->netdev,
- "txd[%u]: 0x%llu %u %u\n",
+ "txd[%u]: 0x%llx %u %u\n",
tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index ade33ef82823..1fb7b37d1402 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -33,6 +33,7 @@
#include <net/ip_tunnels.h>
#include <net/icmp.h>
#include <net/udp.h>
+#include <net/udp_tunnel.h>
#include <net/rtnetlink.h>
#include <net/route.h>
#include <net/dsfield.h>
@@ -339,7 +340,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
ndm->ndm_state = fdb->state;
ndm->ndm_ifindex = vxlan->dev->ifindex;
ndm->ndm_flags = fdb->flags;
- ndm->ndm_type = NDA_DST;
+ ndm->ndm_type = RTN_UNICAST;
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
goto nla_put_failure;
@@ -933,7 +934,8 @@ out:
/* Dump forwarding table */
static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
- struct net_device *dev, int idx)
+ struct net_device *dev,
+ struct net_device *filter_dev, int idx)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned int h;
@@ -1570,25 +1572,6 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
return false;
}
-/* Compute source port for outgoing packet
- * first choice to use L4 flow hash since it will spread
- * better and maybe available from hardware
- * secondary choice is to use jhash on the Ethernet header
- */
-__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb)
-{
- unsigned int range = (port_max - port_min) + 1;
- u32 hash;
-
- hash = skb_get_hash(skb);
- if (!hash)
- hash = jhash(skb->data, 2 * ETH_ALEN,
- (__force u32) skb->protocol);
-
- return htons((((u64) hash * range) >> 32) + port_min);
-}
-EXPORT_SYMBOL_GPL(vxlan_src_port);
-
static inline struct sk_buff *vxlan_handle_offloads(struct sk_buff *skb,
bool udp_csum)
{
@@ -1807,7 +1790,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
if (tos == 1)
tos = ip_tunnel_get_dsfield(old_iph, skb);
- src_port = vxlan_src_port(vxlan->port_min, vxlan->port_max, skb);
+ src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->port_min,
+ vxlan->port_max, true);
if (dst->sa.sa_family == AF_INET) {
memset(&fl4, 0, sizeof(fl4));
@@ -2235,7 +2219,6 @@ static void vxlan_setup(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned int h;
- int low, high;
eth_hw_addr_random(dev);
ether_setup(dev);
@@ -2272,9 +2255,6 @@ static void vxlan_setup(struct net_device *dev)
vxlan->age_timer.function = vxlan_cleanup;
vxlan->age_timer.data = (unsigned long) vxlan;
- inet_get_local_port_range(dev_net(dev), &low, &high);
- vxlan->port_min = low;
- vxlan->port_max = high;
vxlan->dst_port = htons(vxlan_port);
vxlan->dev = dev;
@@ -2360,102 +2340,37 @@ static void vxlan_del_work(struct work_struct *work)
kfree_rcu(vs, rcu);
}
-#if IS_ENABLED(CONFIG_IPV6)
-/* Create UDP socket for encapsulation receive. AF_INET6 socket
- * could be used for both IPv4 and IPv6 communications, but
- * users may set bindv6only=1.
- */
-static struct socket *create_v6_sock(struct net *net, __be16 port, u32 flags)
+static struct socket *vxlan_create_sock(struct net *net, bool ipv6,
+ __be16 port, u32 flags)
{
- struct sock *sk;
struct socket *sock;
- struct sockaddr_in6 vxlan_addr = {
- .sin6_family = AF_INET6,
- .sin6_port = port,
- };
- int rc, val = 1;
-
- rc = sock_create_kern(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock);
- if (rc < 0) {
- pr_debug("UDPv6 socket create failed\n");
- return ERR_PTR(rc);
- }
-
- /* Put in proper namespace */
- sk = sock->sk;
- sk_change_net(sk, net);
-
- kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
- (char *)&val, sizeof(val));
- rc = kernel_bind(sock, (struct sockaddr *)&vxlan_addr,
- sizeof(struct sockaddr_in6));
- if (rc < 0) {
- pr_debug("bind for UDPv6 socket %pI6:%u (%d)\n",
- &vxlan_addr.sin6_addr, ntohs(vxlan_addr.sin6_port), rc);
- sk_release_kernel(sk);
- return ERR_PTR(rc);
- }
- /* At this point, IPv6 module should have been loaded in
- * sock_create_kern().
- */
- BUG_ON(!ipv6_stub);
-
- /* Disable multicast loopback */
- inet_sk(sk)->mc_loop = 0;
-
- if (flags & VXLAN_F_UDP_ZERO_CSUM6_TX)
- udp_set_no_check6_tx(sk, true);
-
- if (flags & VXLAN_F_UDP_ZERO_CSUM6_RX)
- udp_set_no_check6_rx(sk, true);
-
- return sock;
-}
-
-#else
-
-static struct socket *create_v6_sock(struct net *net, __be16 port, u32 flags)
-{
- return ERR_PTR(-EPFNOSUPPORT);
-}
-#endif
+ struct udp_port_cfg udp_conf;
+ int err;
-static struct socket *create_v4_sock(struct net *net, __be16 port, u32 flags)
-{
- struct sock *sk;
- struct socket *sock;
- struct sockaddr_in vxlan_addr = {
- .sin_family = AF_INET,
- .sin_addr.s_addr = htonl(INADDR_ANY),
- .sin_port = port,
- };
- int rc;
+ memset(&udp_conf, 0, sizeof(udp_conf));
- /* Create UDP socket for encapsulation receive. */
- rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
- if (rc < 0) {
- pr_debug("UDP socket create failed\n");
- return ERR_PTR(rc);
+ if (ipv6) {
+ udp_conf.family = AF_INET6;
+ udp_conf.use_udp6_tx_checksums =
+ !!(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
+ udp_conf.use_udp6_rx_checksums =
+ !!(flags & VXLAN_F_UDP_ZERO_CSUM6_RX);
+ } else {
+ udp_conf.family = AF_INET;
+ udp_conf.local_ip.s_addr = INADDR_ANY;
+ udp_conf.use_udp_checksums =
+ !!(flags & VXLAN_F_UDP_CSUM);
}
- /* Put in proper namespace */
- sk = sock->sk;
- sk_change_net(sk, net);
+ udp_conf.local_udp_port = port;
- rc = kernel_bind(sock, (struct sockaddr *) &vxlan_addr,
- sizeof(vxlan_addr));
- if (rc < 0) {
- pr_debug("bind for UDP socket %pI4:%u (%d)\n",
- &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
- sk_release_kernel(sk);
- return ERR_PTR(rc);
- }
+ /* Open UDP socket */
+ err = udp_sock_create(net, &udp_conf, &sock);
+ if (err < 0)
+ return ERR_PTR(err);
/* Disable multicast loopback */
- inet_sk(sk)->mc_loop = 0;
-
- if (!(flags & VXLAN_F_UDP_CSUM))
- sock->sk->sk_no_check_tx = 1;
+ inet_sk(sock->sk)->mc_loop = 0;
return sock;
}
@@ -2481,10 +2396,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port,
INIT_WORK(&vs->del_work, vxlan_del_work);
- if (ipv6)
- sock = create_v6_sock(net, port, flags);
- else
- sock = create_v4_sock(net, port, flags);
+ sock = vxlan_create_sock(net, ipv6, port, flags);
if (IS_ERR(sock)) {
kfree(vs);
return ERR_CAST(sock);
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 19f7cb2cdef3..43c9960dce1c 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -255,7 +255,6 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EINVAL;
return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF);
- break;
default:
return -EOPNOTSUPP;
@@ -327,8 +326,8 @@ static int dlci_add(struct dlci_add *dlci)
goto err1;
/* create device name */
- master = alloc_netdev( sizeof(struct dlci_local), "dlci%d",
- dlci_setup);
+ master = alloc_netdev(sizeof(struct dlci_local), "dlci%d",
+ NET_NAME_UNKNOWN, dlci_setup);
if (!master) {
err = -ENOMEM;
goto err1;
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 93ace042d0aa..1f041271f7fe 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2363,7 +2363,7 @@ static char *type_strings[] = {
"FarSync TE1"
};
-static void
+static int
fst_init_card(struct fst_card_info *card)
{
int i;
@@ -2374,24 +2374,21 @@ fst_init_card(struct fst_card_info *card)
* we'll have to revise it in some way then.
*/
for (i = 0; i < card->nports; i++) {
- err = register_hdlc_device(card->ports[i].dev);
- if (err < 0) {
- int j;
+ err = register_hdlc_device(card->ports[i].dev);
+ if (err < 0) {
pr_err("Cannot register HDLC device for port %d (errno %d)\n",
- i, -err);
- for (j = i; j < card->nports; j++) {
- free_netdev(card->ports[j].dev);
- card->ports[j].dev = NULL;
- }
- card->nports = i;
- break;
- }
+ i, -err);
+ while (i--)
+ unregister_hdlc_device(card->ports[i].dev);
+ return err;
+ }
}
pr_info("%s-%s: %s IRQ%d, %d ports\n",
port_to_dev(&card->ports[0])->name,
port_to_dev(&card->ports[card->nports - 1])->name,
type_strings[card->type], card->irq, card->nports);
+ return 0;
}
static const struct net_device_ops fst_ops = {
@@ -2447,15 +2444,12 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Try to enable the device */
if ((err = pci_enable_device(pdev)) != 0) {
pr_err("Failed to enable card. Err %d\n", -err);
- kfree(card);
- return err;
+ goto enable_fail;
}
if ((err = pci_request_regions(pdev, "FarSync")) !=0) {
pr_err("Failed to allocate regions. Err %d\n", -err);
- pci_disable_device(pdev);
- kfree(card);
- return err;
+ goto regions_fail;
}
/* Get virtual addresses of memory regions */
@@ -2464,30 +2458,21 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
card->phys_ctlmem = pci_resource_start(pdev, 3);
if ((card->mem = ioremap(card->phys_mem, FST_MEMSIZE)) == NULL) {
pr_err("Physical memory remap failed\n");
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- kfree(card);
- return -ENODEV;
+ err = -ENODEV;
+ goto ioremap_physmem_fail;
}
if ((card->ctlmem = ioremap(card->phys_ctlmem, 0x10)) == NULL) {
pr_err("Control memory remap failed\n");
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- iounmap(card->mem);
- kfree(card);
- return -ENODEV;
+ err = -ENODEV;
+ goto ioremap_ctlmem_fail;
}
dbg(DBG_PCI, "kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem);
/* Register the interrupt handler */
if (request_irq(pdev->irq, fst_intr, IRQF_SHARED, FST_DEV_NAME, card)) {
pr_err("Unable to register interrupt %d\n", card->irq);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- iounmap(card->ctlmem);
- iounmap(card->mem);
- kfree(card);
- return -ENODEV;
+ err = -ENODEV;
+ goto irq_fail;
}
/* Record info we need */
@@ -2513,13 +2498,8 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
while (i--)
free_netdev(card->ports[i].dev);
pr_err("FarSync: out of memory\n");
- free_irq(card->irq, card);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- iounmap(card->ctlmem);
- iounmap(card->mem);
- kfree(card);
- return -ENODEV;
+ err = -ENOMEM;
+ goto hdlcdev_fail;
}
card->ports[i].dev = dev;
card->ports[i].card = card;
@@ -2565,9 +2545,16 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, card);
/* Remainder of card setup */
+ if (no_of_cards_added >= FST_MAX_CARDS) {
+ pr_err("FarSync: too many cards\n");
+ err = -ENOMEM;
+ goto card_array_fail;
+ }
fst_card_array[no_of_cards_added] = card;
card->card_no = no_of_cards_added++; /* Record instance and bump it */
- fst_init_card(card);
+ err = fst_init_card(card);
+ if (err)
+ goto init_card_fail;
if (card->family == FST_FAMILY_TXU) {
/*
* Allocate a dma buffer for transmit and receives
@@ -2577,29 +2564,46 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
&card->rx_dma_handle_card);
if (card->rx_dma_handle_host == NULL) {
pr_err("Could not allocate rx dma buffer\n");
- fst_disable_intr(card);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- iounmap(card->ctlmem);
- iounmap(card->mem);
- kfree(card);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto rx_dma_fail;
}
card->tx_dma_handle_host =
pci_alloc_consistent(card->device, FST_MAX_MTU,
&card->tx_dma_handle_card);
if (card->tx_dma_handle_host == NULL) {
pr_err("Could not allocate tx dma buffer\n");
- fst_disable_intr(card);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- iounmap(card->ctlmem);
- iounmap(card->mem);
- kfree(card);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto tx_dma_fail;
}
}
return 0; /* Success */
+
+tx_dma_fail:
+ pci_free_consistent(card->device, FST_MAX_MTU,
+ card->rx_dma_handle_host,
+ card->rx_dma_handle_card);
+rx_dma_fail:
+ fst_disable_intr(card);
+ for (i = 0 ; i < card->nports ; i++)
+ unregister_hdlc_device(card->ports[i].dev);
+init_card_fail:
+ fst_card_array[card->card_no] = NULL;
+card_array_fail:
+ for (i = 0 ; i < card->nports ; i++)
+ free_netdev(card->ports[i].dev);
+hdlcdev_fail:
+ free_irq(card->irq, card);
+irq_fail:
+ iounmap(card->ctlmem);
+ioremap_ctlmem_fail:
+ iounmap(card->mem);
+ioremap_physmem_fail:
+ pci_release_regions(pdev);
+regions_fail:
+ pci_disable_device(pdev);
+enable_fail:
+ kfree(card);
+ return err;
}
/*
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 9c33ca918e19..51f6cee8aab2 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -256,7 +256,8 @@ static void hdlc_setup(struct net_device *dev)
struct net_device *alloc_hdlcdev(void *priv)
{
struct net_device *dev;
- dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", hdlc_setup);
+ dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d",
+ NET_NAME_UNKNOWN, hdlc_setup);
if (dev)
dev_to_hdlc(dev)->priv = priv;
return dev;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 7c6cb4f31798..7cc64eac0fa3 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1075,10 +1075,11 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
used = pvc_is_used(pvc);
if (type == ARPHRD_ETHER) {
- dev = alloc_netdev(0, "pvceth%d", ether_setup);
+ dev = alloc_netdev(0, "pvceth%d", NET_NAME_UNKNOWN,
+ ether_setup);
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
} else
- dev = alloc_netdev(0, "pvc%d", pvc_setup);
+ dev = alloc_netdev(0, "pvc%d", NET_NAME_UNKNOWN, pvc_setup);
if (!dev) {
netdev_warn(frad, "Memory squeeze on fr_pvc()\n");
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index a33a46fa88dd..2f5eda8a7227 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -325,8 +325,8 @@ static int lapbeth_new_device(struct net_device *dev)
ASSERT_RTNL();
- ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d",
- lapbeth_setup);
+ ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
+ lapbeth_setup);
if (!ndev)
goto out;
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 1b89ecf0959e..758c4ba1e97c 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -227,7 +227,8 @@ int __init sbni_probe(int unit)
struct net_device *dev;
int err;
- dev = alloc_netdev(sizeof(struct net_local), "sbni", sbni_devsetup);
+ dev = alloc_netdev(sizeof(struct net_local), "sbni",
+ NET_NAME_UNKNOWN, sbni_devsetup);
if (!dev)
return -ENOMEM;
@@ -1477,8 +1478,8 @@ int __init init_module( void )
int err;
while( num < SBNI_MAX_NUM_CARDS ) {
- dev = alloc_netdev(sizeof(struct net_local),
- "sbni%d", sbni_devsetup);
+ dev = alloc_netdev(sizeof(struct net_local), "sbni%d",
+ NET_NAME_UNKNOWN, sbni_devsetup);
if( !dev)
break;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index cdd45fb8a1f6..421ac5f85699 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -1631,7 +1631,8 @@ static int __init init_sdla(void)
printk("%s.\n", version);
- sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
+ sdla = alloc_netdev(sizeof(struct frad_local), "sdla0",
+ NET_NAME_UNKNOWN, setup_sdla);
if (!sdla)
return -ENOMEM;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 5895f1978691..5c47b011a9d7 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -81,8 +81,8 @@ static struct x25_asy *x25_asy_alloc(void)
char name[IFNAMSIZ];
sprintf(name, "x25asy%d", i);
- dev = alloc_netdev(sizeof(struct x25_asy),
- name, x25_asy_setup);
+ dev = alloc_netdev(sizeof(struct x25_asy), name,
+ NET_NAME_UNKNOWN, x25_asy_setup);
if (!dev)
return NULL;
@@ -122,8 +122,12 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
{
struct x25_asy *sl = netdev_priv(dev);
unsigned char *xbuff, *rbuff;
- int len = 2 * newmtu;
+ int len;
+ if (newmtu > 65534)
+ return -EINVAL;
+
+ len = 2 * newmtu;
xbuff = kmalloc(len + 4, GFP_ATOMIC);
rbuff = kmalloc(len + 4, GFP_ATOMIC);
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index cd15a93d9084..e7f5910a6519 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -472,7 +472,7 @@ int i2400mu_probe(struct usb_interface *iface,
/* Allocate instance [calls i2400m_netdev_setup() on it]. */
result = -ENOMEM;
- net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d",
+ net_dev = alloc_netdev(sizeof(*i2400mu), "wmx%d", NET_NAME_UNKNOWN,
i2400mu_netdev_setup);
if (net_dev == NULL) {
dev_err(dev, "no memory for network device instance\n");
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index b2137e8f7ca6..16604bdf5197 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -189,6 +189,7 @@ config USB_NET_RNDIS_WLAN
tristate "Wireless RNDIS USB support"
depends on USB
depends on CFG80211
+ select USB_NET_DRIVERS
select USB_USBNET
select USB_NET_CDCETHER
select USB_NET_RNDIS_HOST
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 64747d457bb3..b39807579a8a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2685,7 +2685,8 @@ static struct net_device *init_wifidev(struct airo_info *ai,
struct net_device *ethdev)
{
int err;
- struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup);
+ struct net_device *dev = alloc_netdev(0, "wifi%d", NET_NAME_UNKNOWN,
+ wifi_setup);
if (!dev)
return NULL;
dev->ml_priv = ethdev->ml_priv;
@@ -2785,7 +2786,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
CapabilityRid cap_rid;
/* Create the network device object. */
- dev = alloc_netdev(sizeof(*ai), "", ether_setup);
+ dev = alloc_netdev(sizeof(*ai), "", NET_NAME_UNKNOWN, ether_setup);
if (!dev) {
airo_print_err("", "Couldn't alloc_etherdev");
return NULL;
@@ -7817,7 +7818,6 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
case AIRORRID: ridcode = comp->ridnum; break;
default:
return -EINVAL;
- break;
}
if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index d48776e4f343..334c2ece855a 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1955,8 +1955,9 @@ static void at76_dwork_hw_scan(struct work_struct *work)
static int at76_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
+ struct cfg80211_scan_request *req = &hw_req->req;
struct at76_priv *priv = hw->priv;
struct at76_req_scan scan;
u8 *ssid = NULL;
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a889fd66fc63..fd9e5305e77f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -63,6 +63,7 @@ enum ath_op_flags {
ATH_OP_PRIM_STA_VIF,
ATH_OP_HW_RESET,
ATH_OP_SCANNING,
+ ATH_OP_MULTI_CHANNEL,
};
enum ath_bus_type {
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index d185dc0cd12b..4333107ecf37 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -603,16 +603,19 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
if (ret)
return ret;
- src_ring->hw_index =
- ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
- src_ring->hw_index &= nentries_mask;
+ read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
+ if (read_index == 0xffffffff)
+ return -ENODEV;
+
+ read_index &= nentries_mask;
+ src_ring->hw_index = read_index;
ath10k_pci_sleep(ar);
}
read_index = src_ring->hw_index;
- if ((read_index == sw_index) || (read_index == 0xffffffff))
+ if (read_index == sw_index)
return -EIO;
sbase = src_ring->shadow_base;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 82017f56e661..93adb8c58969 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -795,10 +795,14 @@ int ath10k_core_start(struct ath10k *ar)
if (status)
goto err_htc_stop;
- ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
+ if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
+ ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
+ else
+ ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
+
INIT_LIST_HEAD(&ar->arvifs);
- if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
+ if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) {
ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
ar->hw_params.name,
ar->target_version,
@@ -807,6 +811,12 @@ int ath10k_core_start(struct ath10k *ar)
ar->fw_api,
ar->htt.target_version_major,
ar->htt.target_version_minor);
+ ath10k_info("debug %d debugfs %d tracing %d dfs %d\n",
+ config_enabled(CONFIG_ATH10K_DEBUG),
+ config_enabled(CONFIG_ATH10K_DEBUGFS),
+ config_enabled(CONFIG_ATH10K_TRACING),
+ config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
+ }
__set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
@@ -984,7 +994,9 @@ err_unregister_mac:
err_release_fw:
ath10k_core_free_firmware_files(ar);
err:
- device_release_driver(ar->dev);
+ /* TODO: It's probably a good idea to release device from the driver
+ * but calling device_release_driver() here will cause a deadlock.
+ */
return;
}
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 68ceef61933d..83a5fa91531d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -290,6 +290,9 @@ struct ath10k_debug {
struct ath_dfs_pool_stats dfs_pool_stats;
u32 fw_dbglog_mask;
+
+ u8 htt_max_amsdu;
+ u8 htt_max_ampdu;
};
enum ath10k_state {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 1b7ff4ba122c..3030158c478e 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
.llseek = default_llseek,
};
+static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath10k *ar = file->private_data;
+ char buf[64];
+ u8 amsdu = 3, ampdu = 64;
+ unsigned int len;
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (ar->debug.htt_max_amsdu)
+ amsdu = ar->debug.htt_max_amsdu;
+
+ if (ar->debug.htt_max_ampdu)
+ ampdu = ar->debug.htt_max_ampdu;
+
+ mutex_unlock(&ar->conf_mutex);
+
+ len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath10k *ar = file->private_data;
+ int res;
+ char buf[64];
+ unsigned int amsdu, ampdu;
+
+ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+
+ /* make sure that buf is null terminated */
+ buf[sizeof(buf) - 1] = 0;
+
+ res = sscanf(buf, "%u %u", &amsdu, &ampdu);
+
+ if (res != 2)
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+
+ res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
+ if (res)
+ goto out;
+
+ res = count;
+ ar->debug.htt_max_amsdu = amsdu;
+ ar->debug.htt_max_ampdu = ampdu;
+
+out:
+ mutex_unlock(&ar->conf_mutex);
+ return res;
+}
+
+static const struct file_operations fops_htt_max_amsdu_ampdu = {
+ .read = ath10k_read_htt_max_amsdu_ampdu,
+ .write = ath10k_write_htt_max_amsdu_ampdu,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
static ssize_t ath10k_read_fw_dbglog(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
@@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
* warning from del_timer(). */
if (ar->debug.htt_stats_mask != 0)
cancel_delayed_work(&ar->debug.htt_stats_dwork);
+
+ ar->debug.htt_max_amsdu = 0;
+ ar->debug.htt_max_ampdu = 0;
}
static ssize_t ath10k_write_simulate_radar(struct file *file,
@@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_htt_stats_mask);
+ debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
+ ar->debug.debugfs_phy, ar,
+ &fops_htt_max_amsdu_ampdu);
+
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_fw_dbglog);
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index e493db4b4a41..5fdc40d3b378 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -546,7 +546,7 @@ static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
int ath10k_htc_wait_target(struct ath10k_htc *htc)
{
- int status = 0;
+ int i, status = 0;
struct ath10k_htc_svc_conn_req conn_req;
struct ath10k_htc_svc_conn_resp conn_resp;
struct ath10k_htc_msg *msg;
@@ -556,10 +556,26 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
status = wait_for_completion_timeout(&htc->ctl_resp,
ATH10K_HTC_WAIT_TIMEOUT_HZ);
- if (status <= 0) {
+ if (status == 0) {
+ /* Workaround: In some cases the PCI HIF doesn't
+ * receive interrupt for the control response message
+ * even if the buffer was completed. It is suspected
+ * iomap writes unmasking PCI CE irqs aren't propagated
+ * properly in KVM PCI-passthrough sometimes.
+ */
+ ath10k_warn("failed to receive control response completion, polling..\n");
+
+ for (i = 0; i < CE_COUNT; i++)
+ ath10k_hif_send_complete_check(htc->ar, i, 1);
+
+ status = wait_for_completion_timeout(&htc->ctl_resp,
+ ATH10K_HTC_WAIT_TIMEOUT_HZ);
+
if (status == 0)
status = -ETIMEDOUT;
+ }
+ if (status < 0) {
ath10k_err("ctl_resp never came in (%d)\n", status);
return status;
}
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 9a263462c793..6c93f3885ee5 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -240,16 +240,10 @@ struct htt_oob_sync_req {
__le16 rsvd0;
} __packed;
-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0
-
struct htt_aggr_conf {
u8 max_num_ampdu_subframes;
- union {
- /* dont use bitfields; undefined behaviour */
- u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
- u8 max_num_amsdu_subframes:5;
- } __packed;
+ /* amsdu_subframes is limited by 0x1F mask */
+ u8 max_num_amsdu_subframes;
} __packed;
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
@@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
+int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
+ u8 max_subfrms_ampdu,
+ u8 max_subfrms_amsdu);
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 6c102b1312ff..80cdac15588a 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -21,6 +21,7 @@
#include "txrx.h"
#include "debug.h"
#include "trace.h"
+#include "mac.h"
#include <linux/log2.h>
@@ -307,12 +308,12 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
u8 **fw_desc, int *fw_desc_len,
struct sk_buff **head_msdu,
- struct sk_buff **tail_msdu)
+ struct sk_buff **tail_msdu,
+ u32 *attention)
{
int msdu_len, msdu_chaining = 0;
struct sk_buff *msdu;
struct htt_rx_desc *rx_desc;
- bool corrupted = false;
lockdep_assert_held(&htt->rx_ring.lock);
@@ -358,6 +359,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
break;
}
+ *attention |= __le32_to_cpu(rx_desc->attention.flags) &
+ (RX_ATTENTION_FLAGS_TKIP_MIC_ERR |
+ RX_ATTENTION_FLAGS_DECRYPT_ERR |
+ RX_ATTENTION_FLAGS_FCS_ERR |
+ RX_ATTENTION_FLAGS_MGMT_TYPE);
/*
* Copy the FW rx descriptor for this MSDU from the rx
* indication message into the MSDU's netbuf. HL uses the
@@ -439,9 +445,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
RX_MSDU_END_INFO0_LAST_MSDU;
- if (msdu_chaining && !last_msdu)
- corrupted = true;
-
if (last_msdu) {
msdu->next = NULL;
break;
@@ -457,20 +460,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
msdu_chaining = -1;
/*
- * Apparently FW sometimes reports weird chained MSDU sequences with
- * more than one rx descriptor. This seems like a bug but needs more
- * analyzing. For the time being fix it by dropping such sequences to
- * avoid blowing up the host system.
- */
- if (corrupted) {
- ath10k_warn("failed to pop chained msdus, dropping\n");
- ath10k_htt_rx_free_msdu_chain(*head_msdu);
- *head_msdu = NULL;
- *tail_msdu = NULL;
- msdu_chaining = -EINVAL;
- }
-
- /*
* Don't refill the ring yet.
*
* First, the elements popped here are still in use - it is not
@@ -1233,13 +1222,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail;
+ attention = 0;
msdu_head = NULL;
msdu_tail = NULL;
ret = ath10k_htt_rx_amsdu_pop(htt,
&fw_desc,
&fw_desc_len,
&msdu_head,
- &msdu_tail);
+ &msdu_tail,
+ &attention);
if (ret < 0) {
ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
@@ -1251,7 +1242,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
rxd = container_of((void *)msdu_head->data,
struct htt_rx_desc,
msdu_payload);
- attention = __le32_to_cpu(rxd->attention.flags);
if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
status,
@@ -1304,6 +1294,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
u8 *fw_desc;
int fw_desc_len, hdrlen, paramlen;
int trim;
+ u32 attention = 0;
fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes);
fw_desc = (u8 *)frag->fw_msdu_rx_desc;
@@ -1313,7 +1304,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
spin_lock_bh(&htt->rx_ring.lock);
ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
- &msdu_head, &msdu_tail);
+ &msdu_head, &msdu_tail,
+ &attention);
spin_unlock_bh(&htt->rx_ring.lock);
ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
@@ -1330,10 +1322,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
hdr = (struct ieee80211_hdr *)msdu_head->data;
rxd = (void *)msdu_head->data - sizeof(*rxd);
- tkip_mic_err = !!(__le32_to_cpu(rxd->attention.flags) &
- RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
- decrypt_err = !!(__le32_to_cpu(rxd->attention.flags) &
- RX_ATTENTION_FLAGS_DECRYPT_ERR);
+ tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
+ decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR);
fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
RX_MSDU_START_INFO1_DECAP_FORMAT);
@@ -1440,6 +1430,86 @@ static void ath10k_htt_rx_frm_tx_compl(struct ath10k *ar,
}
}
+static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
+{
+ struct htt_rx_addba *ev = &resp->rx_addba;
+ struct ath10k_peer *peer;
+ struct ath10k_vif *arvif;
+ u16 info0, tid, peer_id;
+
+ info0 = __le16_to_cpu(ev->info0);
+ tid = MS(info0, HTT_RX_BA_INFO0_TID);
+ peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
+
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx addba tid %hu peer_id %hu size %hhu\n",
+ tid, peer_id, ev->window_size);
+
+ spin_lock_bh(&ar->data_lock);
+ peer = ath10k_peer_find_by_id(ar, peer_id);
+ if (!peer) {
+ ath10k_warn("received addba event for invalid peer_id: %hu\n",
+ peer_id);
+ spin_unlock_bh(&ar->data_lock);
+ return;
+ }
+
+ arvif = ath10k_get_arvif(ar, peer->vdev_id);
+ if (!arvif) {
+ ath10k_warn("received addba event for invalid vdev_id: %u\n",
+ peer->vdev_id);
+ spin_unlock_bh(&ar->data_lock);
+ return;
+ }
+
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx start rx ba session sta %pM tid %hu size %hhu\n",
+ peer->addr, tid, ev->window_size);
+
+ ieee80211_start_rx_ba_session_offl(arvif->vif, peer->addr, tid);
+ spin_unlock_bh(&ar->data_lock);
+}
+
+static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
+{
+ struct htt_rx_delba *ev = &resp->rx_delba;
+ struct ath10k_peer *peer;
+ struct ath10k_vif *arvif;
+ u16 info0, tid, peer_id;
+
+ info0 = __le16_to_cpu(ev->info0);
+ tid = MS(info0, HTT_RX_BA_INFO0_TID);
+ peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
+
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx delba tid %hu peer_id %hu\n",
+ tid, peer_id);
+
+ spin_lock_bh(&ar->data_lock);
+ peer = ath10k_peer_find_by_id(ar, peer_id);
+ if (!peer) {
+ ath10k_warn("received addba event for invalid peer_id: %hu\n",
+ peer_id);
+ spin_unlock_bh(&ar->data_lock);
+ return;
+ }
+
+ arvif = ath10k_get_arvif(ar, peer->vdev_id);
+ if (!arvif) {
+ ath10k_warn("received addba event for invalid vdev_id: %u\n",
+ peer->vdev_id);
+ spin_unlock_bh(&ar->data_lock);
+ return;
+ }
+
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx stop rx ba session sta %pM tid %hu\n",
+ peer->addr, tid);
+
+ ieee80211_stop_rx_ba_session_offl(arvif->vif, peer->addr, tid);
+ spin_unlock_bh(&ar->data_lock);
+}
+
void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
{
struct ath10k_htt *htt = &ar->htt;
@@ -1534,9 +1604,25 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
trace_ath10k_htt_stats(skb->data, skb->len);
break;
case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
+ /* Firmware can return tx frames if it's unable to fully
+ * process them and suspects host may be able to fix it. ath10k
+ * sends all tx frames as already inspected so this shouldn't
+ * happen unless fw has a bug.
+ */
+ ath10k_warn("received an unexpected htt tx inspect event\n");
+ break;
case HTT_T2H_MSG_TYPE_RX_ADDBA:
+ ath10k_htt_rx_addba(ar, resp);
+ break;
case HTT_T2H_MSG_TYPE_RX_DELBA:
- case HTT_T2H_MSG_TYPE_RX_FLUSH:
+ ath10k_htt_rx_delba(ar, resp);
+ break;
+ case HTT_T2H_MSG_TYPE_RX_FLUSH: {
+ /* Ignore this event because mac80211 takes care of Rx
+ * aggregation reordering.
+ */
+ break;
+ }
default:
ath10k_dbg(ATH10K_DBG_HTT, "htt event (%d) not handled\n",
resp->hdr.msg_type);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 7064354d1f4f..8b27bfcc1de3 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
return 0;
}
+int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
+ u8 max_subfrms_ampdu,
+ u8 max_subfrms_amsdu)
+{
+ struct htt_aggr_conf *aggr_conf;
+ struct sk_buff *skb;
+ struct htt_cmd *cmd;
+ int len;
+ int ret;
+
+ /* Firmware defaults are: amsdu = 3 and ampdu = 64 */
+
+ if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
+ return -EINVAL;
+
+ if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
+ return -EINVAL;
+
+ len = sizeof(cmd->hdr);
+ len += sizeof(cmd->aggr_conf);
+
+ skb = ath10k_htc_alloc_skb(len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+ cmd = (struct htt_cmd *)skb->data;
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
+
+ aggr_conf = &cmd->aggr_conf;
+ aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
+ aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
+
+ ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
+ aggr_conf->max_num_amsdu_subframes,
+ aggr_conf->max_num_ampdu_subframes);
+
+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
+ if (ret) {
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ return 0;
+}
+
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct device *dev = htt->ar->dev;
@@ -485,6 +531,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD;
flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD;
+ /* Prevent firmware from sending up tx inspection requests. There's
+ * nothing ath10k can do with frames requested for inspection so force
+ * it to simply rely a regular tx completion with discard status.
+ */
+ flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;
+
skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
skb_cb->htt.txbuf->cmd_tx.flags0 = flags0;
skb_cb->htt.txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index a21080028c54..9d61bb157189 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1865,15 +1865,13 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar,
return 0;
}
-/*
- * Frames sent to the FW have to be in "Native Wifi" format.
- * Strip the QoS field from the 802.11 header.
+/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
+ * Control in the header.
*/
-static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control,
- struct sk_buff *skb)
+static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (void *)skb->data;
+ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
u8 *qos_ctl;
if (!ieee80211_is_data_qos(hdr->frame_control))
@@ -1883,6 +1881,16 @@ static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw,
memmove(skb->data + IEEE80211_QOS_CTL_LEN,
skb->data, (void *)qos_ctl - (void *)skb->data);
skb_pull(skb, IEEE80211_QOS_CTL_LEN);
+
+ /* Fw/Hw generates a corrupted QoS Control Field for QoS NullFunc
+ * frames. Powersave is handled by the fw/hw so QoS NyllFunc frames are
+ * used only for CQM purposes (e.g. hostapd station keepalive ping) so
+ * it is safe to downgrade to NullFunc.
+ */
+ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) {
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+ cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+ }
}
static void ath10k_tx_wep_key_work(struct work_struct *work)
@@ -1919,14 +1927,13 @@ unlock:
mutex_unlock(&arvif->ar->conf_mutex);
}
-static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
+static void ath10k_tx_h_update_wep_key(struct ieee80211_vif *vif,
+ struct ieee80211_key_conf *key,
+ struct sk_buff *skb)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_vif *vif = info->control.vif;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
struct ath10k *ar = arvif->ar;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_key_conf *key = info->control.hw_key;
if (!ieee80211_has_protected(hdr->frame_control))
return;
@@ -1948,11 +1955,11 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
ieee80211_queue_work(ar->hw, &arvif->wep_key_work);
}
-static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb)
+static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_vif *vif = info->control.vif;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
/* This is case only for P2P_GO */
@@ -2254,33 +2261,28 @@ static void ath10k_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
{
+ struct ath10k *ar = hw->priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_vif *vif = info->control.vif;
+ struct ieee80211_key_conf *key = info->control.hw_key;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ath10k *ar = hw->priv;
- u8 tid, vdev_id;
/* We should disable CCK RATE due to P2P */
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
ath10k_dbg(ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
- /* we must calculate tid before we apply qos workaround
- * as we'd lose the qos control field */
- tid = ath10k_tx_h_get_tid(hdr);
- vdev_id = ath10k_tx_h_get_vdev_id(ar, info);
+ ATH10K_SKB_CB(skb)->htt.is_offchan = false;
+ ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
+ ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, info);
/* it makes no sense to process injected frames like that */
- if (info->control.vif &&
- info->control.vif->type != NL80211_IFTYPE_MONITOR) {
- ath10k_tx_h_qos_workaround(hw, control, skb);
- ath10k_tx_h_update_wep_key(skb);
- ath10k_tx_h_add_p2p_noa_ie(ar, skb);
- ath10k_tx_h_seq_no(skb);
+ if (vif && vif->type != NL80211_IFTYPE_MONITOR) {
+ ath10k_tx_h_nwifi(hw, skb);
+ ath10k_tx_h_update_wep_key(vif, key, skb);
+ ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
+ ath10k_tx_h_seq_no(vif, skb);
}
- ATH10K_SKB_CB(skb)->vdev_id = vdev_id;
- ATH10K_SKB_CB(skb)->htt.is_offchan = false;
- ATH10K_SKB_CB(skb)->htt.tid = tid;
-
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
spin_lock_bh(&ar->data_lock);
ATH10K_SKB_CB(skb)->htt.is_offchan = true;
@@ -3137,10 +3139,11 @@ exit:
static int ath10k_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
struct ath10k *ar = hw->priv;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+ struct cfg80211_scan_request *req = &hw_req->req;
struct wmi_start_scan_arg arg;
int ret = 0;
int i;
@@ -4330,6 +4333,38 @@ static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return 0;
}
+static int ath10k_ampdu_action(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+ u8 buf_size)
+{
+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+
+ ath10k_dbg(ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
+ arvif->vdev_id, sta->addr, tid, action);
+
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ case IEEE80211_AMPDU_RX_STOP:
+ /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
+ * creation/removal. Do we need to verify this?
+ */
+ return 0;
+ case IEEE80211_AMPDU_TX_START:
+ case IEEE80211_AMPDU_TX_STOP_CONT:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
+ /* Firmware offloads Tx aggregation entirely so deny mac80211
+ * Tx aggregation requests.
+ */
+ return -EOPNOTSUPP;
+ }
+
+ return -EINVAL;
+}
+
static const struct ieee80211_ops ath10k_ops = {
.tx = ath10k_tx,
.start = ath10k_start,
@@ -4357,6 +4392,7 @@ static const struct ieee80211_ops ath10k_ops = {
.set_bitrate_mask = ath10k_set_bitrate_mask,
.sta_rc_update = ath10k_sta_rc_update,
.get_tsf = ath10k_get_tsf,
+ .ampdu_action = ath10k_ampdu_action,
#ifdef CONFIG_PM
.suspend = ath10k_suspend,
.resume = ath10k_resume,
@@ -4697,7 +4733,6 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP);
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
@@ -4767,6 +4802,8 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->iface_combinations = ath10k_if_comb;
ar->hw->wiphy->n_iface_combinations =
ARRAY_SIZE(ath10k_if_comb);
+
+ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
}
ar->hw->netdev_features = NETIF_F_HW_CSUM;
diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h
index ba1021997b8f..ef4f84376d7c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -43,11 +43,11 @@ static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
return (struct ath10k_vif *)vif->drv_priv;
}
-static inline void ath10k_tx_h_seq_no(struct sk_buff *skb)
+static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif,
+ struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_vif *vif = info->control.vif;
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index d0004d59c97e..0ffff205478d 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -726,18 +726,12 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
unsigned int nbytes, max_nbytes;
unsigned int transfer_id;
unsigned int flags;
- int err;
+ int err, num_replenish = 0;
while (ath10k_ce_completed_recv_next(ce_state, &transfer_context,
&ce_data, &nbytes, &transfer_id,
&flags) == 0) {
- err = ath10k_pci_post_rx_pipe(pipe_info, 1);
- if (unlikely(err)) {
- /* FIXME: retry */
- ath10k_warn("failed to replenish CE rx ring %d: %d\n",
- pipe_info->pipe_num, err);
- }
-
+ num_replenish++;
skb = transfer_context;
max_nbytes = skb->len + skb_tailroom(skb);
dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
@@ -753,6 +747,13 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
skb_put(skb, nbytes);
cb->rx_completion(ar, skb, pipe_info->pipe_num);
}
+
+ err = ath10k_pci_post_rx_pipe(pipe_info, num_replenish);
+ if (unlikely(err)) {
+ /* FIXME: retry */
+ ath10k_warn("failed to replenish CE rx ring %d (%d bufs): %d\n",
+ pipe_info->pipe_num, num_replenish, err);
+ }
}
static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
@@ -1362,8 +1363,6 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
}
- init_completion(&xfer.done);
-
ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
if (ret)
goto err_resp;
@@ -1414,10 +1413,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
&nbytes, &transfer_id))
return;
- if (xfer->wait_for_resp)
- return;
-
- complete(&xfer->done);
+ xfer->tx_done = true;
}
static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
@@ -1438,7 +1434,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
}
xfer->resp_len = nbytes;
- complete(&xfer->done);
+ xfer->rx_done = true;
}
static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
@@ -1451,7 +1447,7 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
ath10k_pci_bmi_send_done(tx_pipe);
ath10k_pci_bmi_recv_data(rx_pipe);
- if (completion_done(&xfer->done))
+ if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
return 0;
schedule();
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index dfdebb4157aa..940129209990 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -38,7 +38,8 @@
#define DIAG_TRANSFER_LIMIT 2048
struct bmi_xfer {
- struct completion done;
+ bool tx_done;
+ bool rx_done;
bool wait_for_resp;
u32 resp_len;
};
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 82669a77e553..f4fa22d1d591 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -119,8 +119,7 @@ struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
return NULL;
}
-static struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar,
- int peer_id)
+struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, int peer_id)
{
struct ath10k_peer *peer;
diff --git a/drivers/net/wireless/ath/ath10k/txrx.h b/drivers/net/wireless/ath/ath10k/txrx.h
index aee3e20058f8..a90e09f5c7f2 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.h
+++ b/drivers/net/wireless/ath/ath10k/txrx.h
@@ -24,6 +24,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr);
+struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, int peer_id);
int ath10k_wait_for_peer_created(struct ath10k *ar, int vdev_id,
const u8 *addr);
int ath10k_wait_for_peer_deleted(struct ath10k *ar, int vdev_id,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 4b7782a529ac..c2c87c916b5a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1432,7 +1432,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
continue;
}
- ath10k_tx_h_seq_no(bcn);
+ ath10k_tx_h_seq_no(arvif->vif, bcn);
ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info);
ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info);
@@ -2106,7 +2106,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd_hdr;
enum wmi_event_id id;
- u16 len;
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2114,8 +2113,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
return;
- len = skb->len;
-
trace_ath10k_wmi_event(id, skb->data, skb->len);
switch (id) {
@@ -2225,7 +2222,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd_hdr;
enum wmi_10x_event_id id;
- u16 len;
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2233,8 +2229,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
return;
- len = skb->len;
-
trace_ath10k_wmi_event(id, skb->data, skb->len);
switch (id) {
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 74bd54d6aceb..85316bb3f8c6 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1285,6 +1285,7 @@ struct ath5k_hw {
#define ATH_STAT_STARTED 3 /* opened & irqs enabled */
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
+ unsigned int fif_filter_flags; /* Current FIF_* filter flags */
struct ieee80211_channel *curchan; /* current h/w channel */
u16 nvifs;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4b18434ba697..8ad2550bce7f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1382,6 +1382,9 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
rxs->flag = 0;
if (unlikely(rs->rs_status & AR5K_RXERR_MIC))
rxs->flag |= RX_FLAG_MMIC_ERROR;
+ if (unlikely(rs->rs_status & AR5K_RXERR_CRC))
+ rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
+
/*
* always extend the mac timestamp, since this information is
@@ -1449,6 +1452,8 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
ah->stats.rx_bytes_count += rs->rs_datalen;
if (unlikely(rs->rs_status)) {
+ unsigned int filters;
+
if (rs->rs_status & AR5K_RXERR_CRC)
ah->stats.rxerr_crc++;
if (rs->rs_status & AR5K_RXERR_FIFO)
@@ -1457,7 +1462,20 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
ah->stats.rxerr_phy++;
if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32)
ah->stats.rxerr_phy_code[rs->rs_phyerr]++;
- return false;
+
+ /*
+ * Treat packets that underwent a CCK or OFDM reset as having a bad CRC.
+ * These restarts happen when the radio resynchronizes to a stronger frame
+ * while receiving a weaker frame. Here we receive the prefix of the weak
+ * frame. Since these are incomplete packets, mark their CRC as invalid.
+ */
+ if (rs->rs_phyerr == AR5K_RX_PHY_ERROR_OFDM_RESTART ||
+ rs->rs_phyerr == AR5K_RX_PHY_ERROR_CCK_RESTART) {
+ rs->rs_status |= AR5K_RXERR_CRC;
+ rs->rs_status &= ~AR5K_RXERR_PHY;
+ } else {
+ return false;
+ }
}
if (rs->rs_status & AR5K_RXERR_DECRYPT) {
/*
@@ -1480,8 +1498,15 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
return true;
}
- /* reject any frames with non-crypto errors */
- if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
+ /*
+ * Reject any frames with non-crypto errors, and take into account the
+ * current FIF_* filters.
+ */
+ filters = AR5K_RXERR_DECRYPT;
+ if (ah->fif_filter_flags & FIF_FCSFAIL)
+ filters |= AR5K_RXERR_CRC;
+
+ if (rs->rs_status & ~filters)
return false;
}
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index afb23b3cc7be..b65c38fdaa4b 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -473,6 +473,8 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
/* Set the cached hw filter flags, this will later actually
* be set in HW */
ah->filter_flags = rfilt;
+ /* Store current FIF filter flags */
+ ah->fif_filter_flags = *new_flags;
mutex_unlock(&ah->lock);
}
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
index 18fdd69e1f71..397a52f2628b 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.h
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
(void) (check_type == val); \
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
- *val = le32_to_cpu(tmp); \
+ if (!ret) \
+ *val = le32_to_cpu(tmp); \
ret; \
})
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 0e26f4a34fda..e535807c3d89 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
if (info->inactivity_timeout) {
inactivity_timeout = info->inactivity_timeout;
- if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
+ if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+ ar->fw_capabilities))
inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
60);
@@ -3636,7 +3637,7 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
struct net_device *ndev;
struct ath6kl_vif *vif;
- ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
+ ndev = alloc_netdev(sizeof(*vif), name, NET_NAME_UNKNOWN, ether_setup);
if (!ndev)
return NULL;
@@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
ath6kl_band_5ghz.ht_cap.ht_supported = false;
}
- if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
+ if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+ ar->fw_capabilities)) {
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index b0b652042760..0df74b245af4 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
/* FIXME: we should free all firmwares in the error cases below */
+ /*
+ * Backwards compatibility support for older ar6004 firmware images
+ * which do not set these feature flags.
+ */
+ if (ar->target_type == TARGET_TYPE_AR6004 &&
+ ar->fw_api <= 4) {
+ __set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+ ar->fw_capabilities);
+ __set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+ ar->fw_capabilities);
+
+ if (ar->hw.id == AR6004_HW_1_3_VERSION)
+ __set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+ ar->fw_capabilities);
+ }
+
/* Indicate that WMI is enabled (although not ready yet) */
set_bit(WMI_ENABLED, &ar->flag);
ar->wmi = ath6kl_wmi_init(ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 26b0f92424e1..2b78c863d030 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -136,6 +136,21 @@ enum ath6kl_fw_capability {
*/
ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
+ /* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
+ ATH6KL_FW_CAPABILITY_64BIT_RATES,
+
+ /* WMI_AP_CONN_INACT_CMDID uses minutes as units */
+ ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+
+ /* use low priority endpoint for all data */
+ ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+
+ /* ratetable is the 2 stream version (max MCS15) */
+ ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
+
+ /* firmare doesn't support IP checksumming */
+ ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
+
/* this needs to be last */
ATH6KL_FW_CAPABILITY_MAX,
};
@@ -149,15 +164,13 @@ struct ath6kl_fw_ie {
};
enum ath6kl_hw_flags {
- ATH6KL_HW_64BIT_RATES = BIT(0),
- ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
- ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
};
#define ATH6KL_FW_API2_FILE "fw-2.bin"
#define ATH6KL_FW_API3_FILE "fw-3.bin"
#define ATH6KL_FW_API4_FILE "fw-4.bin"
+#define ATH6KL_FW_API5_FILE "fw-5.bin"
/* AR6003 1.0 definitions */
#define AR6003_HW_1_0_VERSION 0x300002ba
@@ -215,8 +228,21 @@ enum ath6kl_hw_flags {
#define AR6004_HW_1_3_VERSION 0x31c8088a
#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
-#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
-#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin"
+#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE "utf.bin"
+#define AR6004_HW_1_3_UTF_FIRMWARE_FILE "utf.bin"
+#define AR6004_HW_1_3_TESTSCRIPT_FILE "nullTestFlow.bin"
+#define AR6004_HW_1_3_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
+#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
+
+/* AR6004 3.0 definitions */
+#define AR6004_HW_3_0_VERSION 0x31C809F8
+#define AR6004_HW_3_0_FW_DIR "ath6k/AR6004/hw3.0"
+#define AR6004_HW_3_0_FIRMWARE_FILE "fw.ram.bin"
+#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE "utf.bin"
+#define AR6004_HW_3_0_UTF_FIRMWARE_FILE "utf.bin"
+#define AR6004_HW_3_0_TESTSCRIPT_FILE "nullTestFlow.bin"
+#define AR6004_HW_3_0_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
+#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
/* Per STA data, used in AP mode */
#define STA_PS_AWAKE BIT(0)
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index 756fe52a12c8..ca1a18c86c0d 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
static void htc_rxctrl_complete(struct htc_target *context,
struct htc_packet *packet)
{
- /* TODO, can't really receive HTC control messages yet.... */
- ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
+ struct sk_buff *skb = packet->skb;
+
+ if (packet->endpoint == ENDPOINT_0 &&
+ packet->status == -ECANCELED &&
+ skb != NULL)
+ dev_kfree_skb(skb);
}
/* htc pipe initialization */
@@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
{
- /* TODO */
+ struct htc_endpoint *endpoint;
+ struct htc_packet *packet, *tmp_pkt;
+ int i;
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ endpoint = &target->endpoint[i];
+
+ spin_lock_bh(&target->rx_lock);
+
+ list_for_each_entry_safe(packet, tmp_pkt,
+ &endpoint->rx_bufq, list) {
+ list_del(&packet->list);
+ spin_unlock_bh(&target->rx_lock);
+ ath6kl_dbg(ATH6KL_DBG_HTC,
+ "htc rx flush pkt 0x%p len %d ep %d\n",
+ packet, packet->buf_len,
+ packet->endpoint);
+ dev_kfree_skb(packet->pkt_cntxt);
+ spin_lock_bh(&target->rx_lock);
+ }
+
+ spin_unlock_bh(&target->rx_lock);
+ }
}
static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index d5ef211f261c..fffd52355123 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
.board_addr = 0x433900,
.refclk_hz = 26000000,
.uarttx_pin = 11,
- .flags = ATH6KL_HW_64BIT_RATES |
- ATH6KL_HW_AP_INACTIVITY_MINS,
+ .flags = 0,
.fw = {
.dir = AR6004_HW_1_0_FW_DIR,
@@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
.board_addr = 0x43d400,
.refclk_hz = 40000000,
.uarttx_pin = 11,
- .flags = ATH6KL_HW_64BIT_RATES |
- ATH6KL_HW_AP_INACTIVITY_MINS,
+ .flags = 0,
.fw = {
.dir = AR6004_HW_1_1_FW_DIR,
.fw = AR6004_HW_1_1_FIRMWARE_FILE,
@@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
.board_addr = 0x435c00,
.refclk_hz = 40000000,
.uarttx_pin = 11,
- .flags = ATH6KL_HW_64BIT_RATES |
- ATH6KL_HW_AP_INACTIVITY_MINS,
+ .flags = 0,
.fw = {
.dir = AR6004_HW_1_2_FW_DIR,
@@ -152,20 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
.board_ext_data_addr = 0x437000,
.reserved_ram_size = 7168,
.board_addr = 0x436400,
- .refclk_hz = 40000000,
+ .refclk_hz = 0,
.uarttx_pin = 11,
- .flags = ATH6KL_HW_64BIT_RATES |
- ATH6KL_HW_AP_INACTIVITY_MINS |
- ATH6KL_HW_MAP_LP_ENDPOINT,
+ .flags = 0,
.fw = {
.dir = AR6004_HW_1_3_FW_DIR,
.fw = AR6004_HW_1_3_FIRMWARE_FILE,
+ .tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
+ .utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
+ .testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
},
.fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
.fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
},
+ {
+ .id = AR6004_HW_3_0_VERSION,
+ .name = "ar6004 hw 3.0",
+ .dataset_patch_addr = 0,
+ .app_load_addr = 0x1234,
+ .board_ext_data_addr = 0,
+ .reserved_ram_size = 7168,
+ .board_addr = 0x436400,
+ .testscript_addr = 0,
+ .flags = 0,
+
+ .fw = {
+ .dir = AR6004_HW_3_0_FW_DIR,
+ .fw = AR6004_HW_3_0_FIRMWARE_FILE,
+ .tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
+ .utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
+ .testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
+ },
+
+ .fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
+ .fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
+ },
};
/*
@@ -601,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
* but possible in theory.
*/
- if (ar->target_type == TARGET_TYPE_AR6003) {
+ if ((ar->target_type == TARGET_TYPE_AR6003) ||
+ (ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
+ (ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
param = ar->hw.board_ext_data_addr;
ram_reserved_size = ar->hw.reserved_ram_size;
@@ -629,9 +651,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
return status;
/* Configure target refclk_hz */
- status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
- if (status)
- return status;
+ if (ar->hw.refclk_hz != 0) {
+ status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
+ ar->hw.refclk_hz);
+ if (status)
+ return status;
+ }
return 0;
}
@@ -1112,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
if (ret)
return ret;
+ ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
+ if (ret == 0) {
+ ar->fw_api = 5;
+ goto out;
+ }
+
ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
if (ret == 0) {
ar->fw_api = 4;
@@ -1161,11 +1192,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
ath6kl_bmi_write_hi32(ar, hi_board_data,
board_address);
} else {
- ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
+ ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
+ if (ret) {
+ ath6kl_err("Failed to get board file target address.\n");
+ return ret;
+ }
}
/* determine where in target ram to write extended board data */
- ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
+ ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
+ if (ret) {
+ ath6kl_err("Failed to get extended board file target address.\n");
+ return ret;
+ }
if (ar->target_type == TARGET_TYPE_AR6003 &&
board_ext_address == 0) {
@@ -1187,7 +1226,6 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
default:
WARN_ON(1);
return -EINVAL;
- break;
}
if (board_ext_address &&
@@ -1230,7 +1268,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
}
/* record the fact that Board Data IS initialized */
- ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
+ if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
+ (ar->version.target_ver == AR6004_HW_3_0_VERSION))
+ param = board_data_size;
+ else
+ param = 1;
+
+ ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
return ret;
}
@@ -1361,7 +1405,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
}
ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
- ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
+
+ if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
+ (ar->version.target_ver != AR6004_HW_3_0_VERSION))
+ ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
+
ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
return 0;
@@ -1567,6 +1615,11 @@ static const struct fw_capa_str_map {
{ ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
{ ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
{ ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
+ { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
+ { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
+ { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
+ { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
+ { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
};
static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d56554674da4..21516bc65785 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
struct ath6kl *ar = vif->ar;
struct target_stats *stats = &vif->target_stats;
struct tkip_ccmp_stats *ccmp_stats;
+ s32 rate;
u8 ac;
if (len < sizeof(*tgt_stats))
@@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
stats->tx_rts_fail_cnt +=
le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
- stats->tx_ucast_rate =
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
+
+ rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
+ stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
@@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
- stats->rx_ucast_rate =
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
+
+ rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
+ stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
@@ -1290,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
void init_netdev(struct net_device *dev)
{
+ struct ath6kl *ar = ath6kl_priv(dev);
+
dev->netdev_ops = &ath6kl_netdev_ops;
dev->destructor = free_netdev;
dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
@@ -1301,7 +1306,9 @@ void init_netdev(struct net_device *dev)
WMI_MAX_TX_META_SZ +
ATH6KL_HTC_ALIGN_BYTES, 4);
- dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+ if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
+ ar->fw_capabilities))
+ dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
return;
}
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 3afc5a463d06..c44325856b81 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
break;
case WMI_DATA_VI_SVC:
- if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+ if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+ ar->fw_capabilities))
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
else
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
break;
case WMI_DATA_VO_SVC:
- if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+ if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+ ar->fw_capabilities))
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
else
*ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -1208,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
/* table of devices that work with this driver */
static struct usb_device_id ath6kl_usb_ids[] = {
+ {USB_DEVICE(0x0cf3, 0x9375)},
{USB_DEVICE(0x0cf3, 0x9374)},
{ /* Terminating entry */ },
};
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 4d7f9e4712e9..94df345d08c2 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
{0, 0}
};
+static const s32 wmi_rate_tbl_mcs15[][2] = {
+ /* {W/O SGI, with SGI} */
+ {1000, 1000},
+ {2000, 2000},
+ {5500, 5500},
+ {11000, 11000},
+ {6000, 6000},
+ {9000, 9000},
+ {12000, 12000},
+ {18000, 18000},
+ {24000, 24000},
+ {36000, 36000},
+ {48000, 48000},
+ {54000, 54000},
+ {6500, 7200}, /* HT 20, MCS 0 */
+ {13000, 14400},
+ {19500, 21700},
+ {26000, 28900},
+ {39000, 43300},
+ {52000, 57800},
+ {58500, 65000},
+ {65000, 72200},
+ {13000, 14400}, /* HT 20, MCS 8 */
+ {26000, 28900},
+ {39000, 43300},
+ {52000, 57800},
+ {78000, 86700},
+ {104000, 115600},
+ {117000, 130000},
+ {130000, 144400}, /* HT 20, MCS 15 */
+ {13500, 15000}, /*HT 40, MCS 0 */
+ {27000, 30000},
+ {40500, 45000},
+ {54000, 60000},
+ {81000, 90000},
+ {108000, 120000},
+ {121500, 135000},
+ {135000, 150000},
+ {27000, 30000}, /*HT 40, MCS 8 */
+ {54000, 60000},
+ {81000, 90000},
+ {108000, 120000},
+ {162000, 180000},
+ {216000, 240000},
+ {243000, 270000},
+ {270000, 300000}, /*HT 40, MCS 15 */
+ {0, 0}
+};
+
/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
static const u8 up_to_ac[] = {
WMM_AC_BE,
@@ -2838,7 +2887,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
{
struct ath6kl *ar = wmi->parent_dev;
- if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
+ if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+ ar->fw_capabilities))
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
else
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
@@ -3279,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
NO_SYNC_WMIFLAG);
}
-s32 ath6kl_wmi_get_rate(s8 rate_index)
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
{
+ struct ath6kl *ar = wmi->parent_dev;
u8 sgi = 0;
+ s32 ret;
if (rate_index == RATE_AUTO)
return 0;
@@ -3292,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
sgi = 1;
}
- if (WARN_ON(rate_index > RATE_MCS_7_40))
- rate_index = RATE_MCS_7_40;
+ if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
+ ar->fw_capabilities)) {
+ if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
+ return 0;
+
+ ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
+ } else {
+ if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
+ return 0;
- return wmi_rate_tbl[(u32) rate_index][sgi];
+ ret = wmi_rate_tbl[(u32) rate_index][sgi];
+ }
+
+ return ret;
}
static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index bb23fc00111d..19f88b4a24fb 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
struct ath6kl_htcap *htcap);
int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
-s32 ath6kl_wmi_get_rate(s8 rate_index);
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
__be32 ips0, __be32 ips1);
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 8fcd586d1c39..6b4020a57984 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -5,7 +5,8 @@ ath9k-y += beacon.o \
recv.o \
xmit.o \
link.o \
- antenna.o
+ antenna.o \
+ channel.o
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index be3eb2a8d602..4173838f4684 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -113,6 +113,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
irq = res->start;
+ ath9k_fill_chanctx_ops();
hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
if (hw == NULL) {
dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 741b38ddcb37..59af9f9712da 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -281,7 +281,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
- | SM(i->txpower, AR_XmitPower)
+ | SM(i->txpower, AR_XmitPower0)
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
| (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
@@ -306,6 +306,10 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
| set11nRateFlags(i->rates, 2)
| set11nRateFlags(i->rates, 3)
| SM(i->rtscts_rate, AR_RTSCTSRate);
+
+ ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1);
+ ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2);
+ ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3);
}
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 235053ba7737..80c6eacbda53 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3535,7 +3535,8 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
{
int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
- if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
+ AR_SREV_9531(ah))
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index ec1da0cc25f5..ddef9eedbac6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -314,10 +314,17 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
qca953x_1p0_mac_core);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
qca953x_1p0_mac_postamble);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
- qca953x_1p0_baseband_core);
- INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
- qca953x_1p0_baseband_postamble);
+ if (AR_SREV_9531_20(ah)) {
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ qca953x_2p0_baseband_core);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ qca953x_2p0_baseband_postamble);
+ } else {
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ qca953x_1p0_baseband_core);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ qca953x_1p0_baseband_postamble);
+ }
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
qca953x_1p0_radio_core);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 729ffbf07343..71e38e85aa99 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -101,7 +101,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
- | SM(i->txpower, AR_XmitPower)
+ | SM(i->txpower, AR_XmitPower0)
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
@@ -151,6 +151,10 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
| SM(i->rtscts_rate, AR_RTSCTSRate);
ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
+
+ ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1);
+ ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2);
+ ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3);
}
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 8927fc34d84c..542a8d51d3b0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1552,13 +1552,15 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
u8 *ini_reloaded)
{
unsigned int regWrites = 0;
- u32 modesIndex;
+ u32 modesIndex, txgain_index;
if (IS_CHAN_5GHZ(chan))
modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
else
modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
+ txgain_index = AR_SREV_9531(ah) ? 1 : modesIndex;
+
if (modesIndex == ah->modes_index) {
*ini_reloaded = false;
goto set_rfmode;
@@ -1573,7 +1575,7 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
modesIndex);
- REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+ REG_WRITE_ARRAY(&ah->iniModesTxGain, txgain_index, regWrites);
if (AR_SREV_9462_20_OR_LATER(ah)) {
/*
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
index 8e5c3b9786e3..812a9d787bf3 100644
--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -219,7 +219,7 @@ static const u32 qca953x_1p0_baseband_core[][2] = {
{0x00009d04, 0x40206c10},
{0x00009d08, 0x009c4060},
{0x00009d0c, 0x9883800a},
- {0x00009d10, 0x01884061},
+ {0x00009d10, 0x018848c6},
{0x00009d14, 0x00c0040b},
{0x00009d18, 0x00000000},
{0x00009e08, 0x0038230c},
@@ -715,4 +715,203 @@ static const u32 qca953x_1p1_modes_no_xpa_tx_gain_table[][2] = {
{0x00016448, 0x6c927a70},
};
+static const u32 qca953x_2p0_baseband_core[][2] = {
+ /* Addr allmodes */
+ {0x00009800, 0xafe68e30},
+ {0x00009804, 0xfd14e000},
+ {0x00009808, 0x9c0a9f6b},
+ {0x0000980c, 0x04900000},
+ {0x00009814, 0x0280c00a},
+ {0x00009818, 0x00000000},
+ {0x0000981c, 0x00020028},
+ {0x00009834, 0x6400a190},
+ {0x00009838, 0x0108ecff},
+ {0x0000983c, 0x14000600},
+ {0x00009880, 0x201fff00},
+ {0x00009884, 0x00001042},
+ {0x000098a4, 0x00200400},
+ {0x000098b0, 0x32840bbe},
+ {0x000098bc, 0x00000002},
+ {0x000098d0, 0x004b6a8e},
+ {0x000098d4, 0x00000820},
+ {0x000098dc, 0x00000000},
+ {0x000098f0, 0x00000000},
+ {0x000098f4, 0x00000000},
+ {0x00009c04, 0xff55ff55},
+ {0x00009c08, 0x0320ff55},
+ {0x00009c0c, 0x00000000},
+ {0x00009c10, 0x00000000},
+ {0x00009c14, 0x00046384},
+ {0x00009c18, 0x05b6b440},
+ {0x00009c1c, 0x00b6b440},
+ {0x00009d00, 0xc080a333},
+ {0x00009d04, 0x40206c10},
+ {0x00009d08, 0x009c4060},
+ {0x00009d0c, 0x9883800a},
+ {0x00009d10, 0x018848c6},
+ {0x00009d14, 0x00c0040b},
+ {0x00009d18, 0x00000000},
+ {0x00009e08, 0x0038230c},
+ {0x00009e24, 0x990bb515},
+ {0x00009e28, 0x0c6f0000},
+ {0x00009e30, 0x06336f77},
+ {0x00009e34, 0x6af6532f},
+ {0x00009e38, 0x0cc80c00},
+ {0x00009e40, 0x0d261820},
+ {0x00009e4c, 0x00001004},
+ {0x00009e50, 0x00ff03f1},
+ {0x00009fc0, 0x813e4788},
+ {0x00009fc4, 0x0001efb5},
+ {0x00009fcc, 0x40000014},
+ {0x00009fd0, 0x02993b93},
+ {0x0000a20c, 0x00000000},
+ {0x0000a220, 0x00000000},
+ {0x0000a224, 0x00000000},
+ {0x0000a228, 0x10002310},
+ {0x0000a23c, 0x00000000},
+ {0x0000a244, 0x0c000000},
+ {0x0000a248, 0x00000140},
+ {0x0000a2a0, 0x00000007},
+ {0x0000a2c0, 0x00000007},
+ {0x0000a2c8, 0x00000000},
+ {0x0000a2d4, 0x00000000},
+ {0x0000a2ec, 0x00000000},
+ {0x0000a2f0, 0x00000000},
+ {0x0000a2f4, 0x00000000},
+ {0x0000a2f8, 0x00000000},
+ {0x0000a344, 0x00000000},
+ {0x0000a34c, 0x00000000},
+ {0x0000a350, 0x0000a000},
+ {0x0000a364, 0x00000000},
+ {0x0000a370, 0x00000000},
+ {0x0000a390, 0x00000001},
+ {0x0000a394, 0x00000444},
+ {0x0000a398, 0x001f0e0f},
+ {0x0000a39c, 0x0075393f},
+ {0x0000a3a0, 0xb79f6427},
+ {0x0000a3a4, 0x000400ff},
+ {0x0000a3a8, 0x6a6a6a6a},
+ {0x0000a3ac, 0x6a6a6a6a},
+ {0x0000a3b0, 0x00c8641a},
+ {0x0000a3b4, 0x0000001a},
+ {0x0000a3b8, 0x0088642a},
+ {0x0000a3bc, 0x000001fa},
+ {0x0000a3c0, 0x20202020},
+ {0x0000a3c4, 0x22222220},
+ {0x0000a3c8, 0x20200020},
+ {0x0000a3cc, 0x20202020},
+ {0x0000a3d0, 0x20202020},
+ {0x0000a3d4, 0x20202020},
+ {0x0000a3d8, 0x20202020},
+ {0x0000a3dc, 0x20202020},
+ {0x0000a3e0, 0x20202020},
+ {0x0000a3e4, 0x20202020},
+ {0x0000a3e8, 0x20202020},
+ {0x0000a3ec, 0x20202020},
+ {0x0000a3f0, 0x00000000},
+ {0x0000a3f4, 0x00000000},
+ {0x0000a3f8, 0x0c9bd380},
+ {0x0000a3fc, 0x000f0f01},
+ {0x0000a400, 0x8fa91f01},
+ {0x0000a404, 0x00000000},
+ {0x0000a408, 0x0e79e5c6},
+ {0x0000a40c, 0x00820820},
+ {0x0000a414, 0x1ce42108},
+ {0x0000a418, 0x2d001dce},
+ {0x0000a41c, 0x1ce73908},
+ {0x0000a420, 0x000001ce},
+ {0x0000a424, 0x1ce738e7},
+ {0x0000a428, 0x000001ce},
+ {0x0000a42c, 0x1ce739ce},
+ {0x0000a430, 0x1ce739ce},
+ {0x0000a434, 0x00000000},
+ {0x0000a438, 0x00001801},
+ {0x0000a43c, 0x00100000},
+ {0x0000a444, 0x00000000},
+ {0x0000a448, 0x05000080},
+ {0x0000a44c, 0x00000001},
+ {0x0000a450, 0x00010000},
+ {0x0000a458, 0x00000000},
+ {0x0000a644, 0xbfad9d74},
+ {0x0000a648, 0x0048060a},
+ {0x0000a64c, 0x00003c37},
+ {0x0000a670, 0x03020100},
+ {0x0000a674, 0x09080504},
+ {0x0000a678, 0x0d0c0b0a},
+ {0x0000a67c, 0x13121110},
+ {0x0000a680, 0x31301514},
+ {0x0000a684, 0x35343332},
+ {0x0000a688, 0x00000036},
+ {0x0000a690, 0x08000838},
+ {0x0000a7cc, 0x00000000},
+ {0x0000a7d0, 0x00000000},
+ {0x0000a7d4, 0x00000004},
+ {0x0000a7dc, 0x00000000},
+ {0x0000a8d0, 0x004b6a8e},
+ {0x0000a8d4, 0x00000820},
+ {0x0000a8dc, 0x00000000},
+ {0x0000a8f0, 0x00000000},
+ {0x0000a8f4, 0x00000000},
+ {0x0000b2d0, 0x00000080},
+ {0x0000b2d4, 0x00000000},
+ {0x0000b2ec, 0x00000000},
+ {0x0000b2f0, 0x00000000},
+ {0x0000b2f4, 0x00000000},
+ {0x0000b2f8, 0x00000000},
+ {0x0000b408, 0x0e79e5c0},
+ {0x0000b40c, 0x00820820},
+ {0x0000b420, 0x00000000},
+};
+
+static const u32 qca953x_2p0_baseband_postamble[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+ {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
+ {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+ {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+ {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+ {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+ {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
+ {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
+ {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
+ {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+ {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
+ {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
+ {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+ {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+ {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+ {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcf946222, 0xcf946222},
+ {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
+ {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+ {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+ {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0},
+ {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+ {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
+ {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+ {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
+ {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
+ {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+ {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+ {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+ {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
+ {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+ {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
+ {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+ {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
+ {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
+ {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
+ {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+ {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
+ {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
+ {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
+ {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+ {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
+ {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+ {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+ {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
+};
+
#endif /* INITVALS_953X_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2ca8f7e06174..7fc13a8da675 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/leds.h>
#include <linux/completion.h>
+#include <linux/time.h>
#include "common.h"
#include "debug.h"
@@ -35,10 +36,7 @@ extern struct ieee80211_ops ath9k_ops;
extern int ath9k_modparam_nohwcrypt;
extern int led_blink;
extern bool is_ath9k_unloaded;
-
-struct ath_config {
- u16 txpowlimit;
-};
+extern int ath9k_use_chanctx;
/*************************/
/* Descriptor Management */
@@ -167,7 +165,6 @@ struct ath_txq {
u32 axq_ampdu_depth;
bool stopped;
bool axq_tx_inprogress;
- struct list_head axq_acq;
struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
u8 txq_headidx;
u8 txq_tailidx;
@@ -185,7 +182,8 @@ struct ath_atx_ac {
struct ath_frame_info {
struct ath_buf *bf;
- int framelen;
+ u16 framelen;
+ s8 txq;
enum ath9k_key_type keytype;
u8 keyix;
u8 rtscts_rate;
@@ -280,8 +278,9 @@ struct ath_node {
struct ath_tx_control {
struct ath_txq *txq;
struct ath_node *an;
- u8 paprd;
struct ieee80211_sta *sta;
+ u8 paprd;
+ bool force_channel;
};
@@ -325,6 +324,116 @@ struct ath_rx {
u32 ampdu_ref;
};
+struct ath_chanctx {
+ struct cfg80211_chan_def chandef;
+ struct list_head vifs;
+ struct list_head acq[IEEE80211_NUM_ACS];
+ int hw_queue_base;
+
+ /* do not dereference, use for comparison only */
+ struct ieee80211_vif *primary_sta;
+
+ struct ath_beacon_config beacon;
+ struct ath9k_hw_cal_data caldata;
+ struct timespec tsf_ts;
+ u64 tsf_val;
+ u32 last_beacon;
+
+ u16 txpower;
+ bool offchannel;
+ bool stopped;
+ bool active;
+ bool assigned;
+ bool switch_after_beacon;
+};
+
+enum ath_chanctx_event {
+ ATH_CHANCTX_EVENT_BEACON_PREPARE,
+ ATH_CHANCTX_EVENT_BEACON_SENT,
+ ATH_CHANCTX_EVENT_TSF_TIMER,
+ ATH_CHANCTX_EVENT_BEACON_RECEIVED,
+ ATH_CHANCTX_EVENT_ASSOC,
+ ATH_CHANCTX_EVENT_SWITCH,
+ ATH_CHANCTX_EVENT_UNASSIGN,
+ ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL,
+};
+
+enum ath_chanctx_state {
+ ATH_CHANCTX_STATE_IDLE,
+ ATH_CHANCTX_STATE_WAIT_FOR_BEACON,
+ ATH_CHANCTX_STATE_WAIT_FOR_TIMER,
+ ATH_CHANCTX_STATE_SWITCH,
+ ATH_CHANCTX_STATE_FORCE_ACTIVE,
+};
+
+struct ath_chanctx_sched {
+ bool beacon_pending;
+ bool offchannel_pending;
+ enum ath_chanctx_state state;
+ u8 beacon_miss;
+
+ u32 next_tbtt;
+ u32 switch_start_time;
+ unsigned int offchannel_duration;
+ unsigned int channel_switch_time;
+
+ /* backup, in case the hardware timer fails */
+ struct timer_list timer;
+};
+
+enum ath_offchannel_state {
+ ATH_OFFCHANNEL_IDLE,
+ ATH_OFFCHANNEL_PROBE_SEND,
+ ATH_OFFCHANNEL_PROBE_WAIT,
+ ATH_OFFCHANNEL_SUSPEND,
+ ATH_OFFCHANNEL_ROC_START,
+ ATH_OFFCHANNEL_ROC_WAIT,
+ ATH_OFFCHANNEL_ROC_DONE,
+};
+
+struct ath_offchannel {
+ struct ath_chanctx chan;
+ struct timer_list timer;
+ struct cfg80211_scan_request *scan_req;
+ struct ieee80211_vif *scan_vif;
+ int scan_idx;
+ enum ath_offchannel_state state;
+ struct ieee80211_channel *roc_chan;
+ struct ieee80211_vif *roc_vif;
+ int roc_duration;
+ int duration;
+};
+#define ath_for_each_chanctx(_sc, _ctx) \
+ for (ctx = &sc->chanctx[0]; \
+ ctx <= &sc->chanctx[ARRAY_SIZE(sc->chanctx) - 1]; \
+ ctx++)
+
+void ath9k_fill_chanctx_ops(void);
+void ath9k_chanctx_force_active(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+static inline struct ath_chanctx *
+ath_chanctx_get(struct ieee80211_chanctx_conf *ctx)
+{
+ struct ath_chanctx **ptr = (void *) ctx->drv_priv;
+ return *ptr;
+}
+void ath_chanctx_init(struct ath_softc *sc);
+void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
+ struct cfg80211_chan_def *chandef);
+void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
+ struct cfg80211_chan_def *chandef);
+void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx);
+void ath_offchannel_timer(unsigned long data);
+void ath_offchannel_channel_change(struct ath_softc *sc);
+void ath_chanctx_offchan_switch(struct ath_softc *sc,
+ struct ieee80211_channel *chan);
+struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc,
+ bool active);
+void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
+ enum ath_chanctx_event ev);
+void ath_chanctx_timer(unsigned long data);
+
+int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
int ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
u32 ath_calcrxfilter(struct ath_softc *sc);
@@ -341,6 +450,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq);
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+void ath_txq_schedule_all(struct ath_softc *sc);
int ath_tx_init(struct ath_softc *sc, int nbufs);
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *q);
@@ -370,32 +480,47 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
/********/
struct ath_vif {
+ struct list_head list;
+
struct ieee80211_vif *vif;
struct ath_node mcast_node;
int av_bslot;
- bool primary_sta_vif;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
struct ath_buf *av_bcbuf;
+ struct ath_chanctx *chanctx;
/* P2P Client */
struct ieee80211_noa_data noa;
+
+ /* P2P GO */
+ u8 noa_index;
+ u32 offchannel_start;
+ u32 offchannel_duration;
+
+ u32 periodic_noa_start;
+ u32 periodic_noa_duration;
};
struct ath9k_vif_iter_data {
u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
u8 mask[ETH_ALEN]; /* bssid mask */
bool has_hw_macaddr;
+ u8 slottime;
+ bool beacons;
int naps; /* number of AP vifs */
int nmeshes; /* number of mesh vifs */
int nstations; /* number of station vifs */
int nwds; /* number of WDS vifs */
int nadhocs; /* number of adhoc vifs */
+ struct ieee80211_vif *primary_sta;
};
-void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
+void ath9k_calculate_iter_data(struct ath_softc *sc,
+ struct ath_chanctx *ctx,
struct ath9k_vif_iter_data *iter_data);
+void ath9k_calculate_summary_state(struct ath_softc *sc,
+ struct ath_chanctx *ctx);
/*******************/
/* Beacon Handling */
@@ -458,6 +583,7 @@ void ath9k_csa_update(struct ath_softc *sc);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
#define ATH_PLL_WORK_INTERVAL 100
+void ath_chanctx_work(struct work_struct *work);
void ath_tx_complete_poll_work(struct work_struct *work);
void ath_reset_work(struct work_struct *work);
bool ath_hw_check(struct ath_softc *sc);
@@ -473,6 +599,7 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
void ath_ps_full_sleep(unsigned long data);
void ath9k_p2p_ps_timer(void *priv);
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
+void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
/**********/
/* BTCOEX */
@@ -702,6 +829,8 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define PS_BEACON_SYNC BIT(4)
#define PS_WAIT_FOR_ANI BIT(5)
+#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
+
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -720,6 +849,7 @@ struct ath_softc {
struct mutex mutex;
struct work_struct paprd_work;
struct work_struct hw_reset_work;
+ struct work_struct chanctx_work;
struct completion paprd_complete;
wait_queue_head_t tx_wait;
@@ -738,23 +868,27 @@ struct ath_softc {
short nvifs;
unsigned long ps_usecount;
- struct ath_config config;
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
+ struct cfg80211_chan_def cur_chandef;
+ struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX];
+ struct ath_chanctx *cur_chan;
+ struct ath_chanctx *next_chan;
+ spinlock_t chan_lock;
+ struct ath_offchannel offchannel;
+ struct ath_chanctx_sched sched;
+
#ifdef CONFIG_MAC80211_LEDS
bool led_registered;
char led_name[32];
struct led_classdev led_cdev;
#endif
- struct ath9k_hw_cal_data caldata;
-
#ifdef CONFIG_ATH9K_DEBUGFS
struct ath9k_debug debug;
#endif
- struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work;
struct delayed_work hw_pll_work;
struct timer_list sleep_timer;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index e387f0b2954a..eaf8f058c151 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -80,7 +80,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
u8 chainmask = ah->txchainmask;
u8 rate = 0;
- sband = &common->sbands[common->hw->conf.chandef.chan->band];
+ sband = &common->sbands[sc->cur_chandef.chan->band];
rate = sband->bitrates[rateidx].hw_value;
if (vif->bss_conf.use_short_preamble)
rate |= sband->bitrates[rateidx].hw_value_short;
@@ -108,6 +108,55 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
}
+static void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
+ struct sk_buff *skb)
+{
+ static const u8 noa_ie_hdr[] = {
+ WLAN_EID_VENDOR_SPECIFIC, /* type */
+ 0, /* length */
+ 0x50, 0x6f, 0x9a, /* WFA OUI */
+ 0x09, /* P2P subtype */
+ 0x0c, /* Notice of Absence */
+ 0x00, /* LSB of little-endian len */
+ 0x00, /* MSB of little-endian len */
+ };
+
+ struct ieee80211_p2p_noa_attr *noa;
+ int noa_len, noa_desc, i = 0;
+ u8 *hdr;
+
+ if (!avp->offchannel_duration && !avp->periodic_noa_duration)
+ return;
+
+ noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration;
+ noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc;
+
+ hdr = skb_put(skb, sizeof(noa_ie_hdr));
+ memcpy(hdr, noa_ie_hdr, sizeof(noa_ie_hdr));
+ hdr[1] = sizeof(noa_ie_hdr) + noa_len - 2;
+ hdr[7] = noa_len;
+
+ noa = (void *) skb_put(skb, noa_len);
+ memset(noa, 0, noa_len);
+
+ noa->index = avp->noa_index;
+ if (avp->periodic_noa_duration) {
+ u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
+
+ noa->desc[i].count = 255;
+ noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start);
+ noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration);
+ noa->desc[i].interval = cpu_to_le32(interval);
+ i++;
+ }
+
+ if (avp->offchannel_duration) {
+ noa->desc[i].count = 1;
+ noa->desc[i].start_time = cpu_to_le32(avp->offchannel_start);
+ noa->desc[i].duration = cpu_to_le32(avp->offchannel_duration);
+ }
+}
+
static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
@@ -155,6 +204,9 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
+ if (vif->p2p)
+ ath9k_beacon_add_noa(sc, avp, skb);
+
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
@@ -249,7 +301,7 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
static int ath9k_beacon_choose_slot(struct ath_softc *sc)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
u16 intval;
u32 tsftu;
u64 tsf;
@@ -277,8 +329,8 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_vif *avp = (void *)vif->drv_priv;
+ struct ath_beacon_config *cur_conf = &avp->chanctx->beacon;
u32 tsfadjust;
if (avp->av_bslot == 0)
@@ -374,12 +426,19 @@ void ath9k_beacon_tasklet(unsigned long data)
vif = sc->beacon.bslot[slot];
/* EDMA devices check that in the tx completion function. */
- if (!edma && ath9k_csa_is_finished(sc, vif))
- return;
+ if (!edma) {
+ if (sc->sched.beacon_pending)
+ ath_chanctx_event(sc, NULL,
+ ATH_CHANCTX_EVENT_BEACON_SENT);
+
+ if (ath9k_csa_is_finished(sc, vif))
+ return;
+ }
if (!vif || !vif->bss_conf.enable_beacon)
return;
+ ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_BEACON_PREPARE);
bf = ath9k_beacon_generate(sc->hw, vif);
if (sc->beacon.bmisscnt != 0) {
@@ -500,7 +559,6 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_vif *avp = (void *)vif->drv_priv;
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
if ((vif->type != NL80211_IFTYPE_AP) ||
@@ -514,7 +572,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
if ((vif->type == NL80211_IFTYPE_STATION) &&
test_bit(ATH_OP_BEACONS, &common->op_flags) &&
- !avp->primary_sta_vif) {
+ vif != sc->cur_chan->primary_sta) {
ath_dbg(common, CONFIG,
"Beacon already configured for a station interface\n");
return false;
@@ -525,10 +583,11 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
}
static void ath9k_cache_beacon_config(struct ath_softc *sc,
+ struct ath_chanctx *ctx,
struct ieee80211_bss_conf *bss_conf)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ath_beacon_config *cur_conf = &ctx->beacon;
ath_dbg(common, BEACON,
"Caching beacon data for BSS: %pM\n", bss_conf->bssid);
@@ -564,20 +623,29 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
u32 changed)
{
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ struct ath_chanctx *ctx = avp->chanctx;
+ struct ath_beacon_config *cur_conf;
unsigned long flags;
bool skip_beacon = false;
+ if (!ctx)
+ return;
+
+ cur_conf = &avp->chanctx->beacon;
if (vif->type == NL80211_IFTYPE_AP)
ath9k_set_tsfadjust(sc, vif);
if (!ath9k_allow_beacon_config(sc, vif))
return;
- if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
- ath9k_cache_beacon_config(sc, bss_conf);
+ if (vif->type == NL80211_IFTYPE_STATION) {
+ ath9k_cache_beacon_config(sc, ctx, bss_conf);
+ if (ctx != sc->cur_chan)
+ return;
+
ath9k_set_beacon(sc);
set_bit(ATH_OP_BEACONS, &common->op_flags);
return;
@@ -593,10 +661,13 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
cur_conf->enable_beacon = false;
} else if (bss_conf->enable_beacon) {
cur_conf->enable_beacon = true;
- ath9k_cache_beacon_config(sc, bss_conf);
+ ath9k_cache_beacon_config(sc, ctx, bss_conf);
}
}
+ if (ctx != sc->cur_chan)
+ return;
+
/*
* Configure the HW beacon registers only when we have a valid
* beacon interval.
@@ -631,7 +702,7 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
void ath9k_set_beacon(struct ath_softc *sc)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
switch (sc->sc_ah->opmode) {
case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
new file mode 100644
index 000000000000..ba214ebdcd16
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 2014 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+/* Set/change channels. If the channel is really being changed, it's done
+ * by reseting the chip. To accomplish this we must first cleanup any pending
+ * DMA, then restart stuff.
+ */
+static int ath_set_channel(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_hw *hw = sc->hw;
+ struct ath9k_channel *hchan;
+ struct cfg80211_chan_def *chandef = &sc->cur_chan->chandef;
+ struct ieee80211_channel *chan = chandef->chan;
+ int pos = chan->hw_value;
+ int old_pos = -1;
+ int r;
+
+ if (test_bit(ATH_OP_INVALID, &common->op_flags))
+ return -EIO;
+
+ if (ah->curchan)
+ old_pos = ah->curchan - &ah->channels[0];
+
+ ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
+ chan->center_freq, chandef->width);
+
+ /* update survey stats for the old channel before switching */
+ spin_lock_bh(&common->cc_lock);
+ ath_update_survey_stats(sc);
+ spin_unlock_bh(&common->cc_lock);
+
+ ath9k_cmn_get_channel(hw, ah, chandef);
+
+ /* If the operating channel changes, change the survey in-use flags
+ * along with it.
+ * Reset the survey data for the new channel, unless we're switching
+ * back to the operating channel from an off-channel operation.
+ */
+ if (!sc->cur_chan->offchannel && sc->cur_survey != &sc->survey[pos]) {
+ if (sc->cur_survey)
+ sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+ sc->cur_survey = &sc->survey[pos];
+
+ memset(sc->cur_survey, 0, sizeof(struct survey_info));
+ sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+ } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+ memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+ }
+
+ hchan = &sc->sc_ah->channels[pos];
+ r = ath_reset_internal(sc, hchan);
+ if (r)
+ return r;
+
+ /* The most recent snapshot of channel->noisefloor for the old
+ * channel is only available after the hardware reset. Copy it to
+ * the survey stats now.
+ */
+ if (old_pos >= 0)
+ ath_update_survey_nf(sc, old_pos);
+
+ /* Enable radar pulse detection if on a DFS channel. Spectral
+ * scanning and radar detection can not be used concurrently.
+ */
+ if (hw->conf.radar_enabled) {
+ u32 rxfilter;
+
+ /* set HW specific DFS configuration */
+ ath9k_hw_set_radar_params(ah);
+ rxfilter = ath9k_hw_getrxfilter(ah);
+ rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
+ ATH9K_RX_FILTER_PHYERR;
+ ath9k_hw_setrxfilter(ah, rxfilter);
+ ath_dbg(common, DFS, "DFS enabled at freq %d\n",
+ chan->center_freq);
+ } else {
+ /* perform spectral scan if requested. */
+ if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
+ sc->spectral_mode == SPECTRAL_CHANSCAN)
+ ath9k_spectral_scan_trigger(hw);
+ }
+
+ return 0;
+}
+
+static bool
+ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+ bool powersave)
+{
+ struct ieee80211_vif *vif = avp->vif;
+ struct ieee80211_sta *sta = NULL;
+ struct ieee80211_hdr_3addr *nullfunc;
+ struct ath_tx_control txctl;
+ struct sk_buff *skb;
+ int band = sc->cur_chan->chandef.chan->band;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (!vif->bss_conf.assoc)
+ return false;
+
+ skb = ieee80211_nullfunc_get(sc->hw, vif);
+ if (!skb)
+ return false;
+
+ nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
+ if (powersave)
+ nullfunc->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_PM);
+
+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+ dev_kfree_skb_any(skb);
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ memset(&txctl, 0, sizeof(txctl));
+ txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+ txctl.sta = sta;
+ txctl.force_channel = true;
+ if (ath_tx_start(sc->hw, skb, &txctl)) {
+ ieee80211_free_txskb(sc->hw, skb);
+ return false;
+ }
+
+ return true;
+}
+
+void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_vif *avp;
+ bool active = false;
+ u8 n_active = 0;
+
+ if (!ctx)
+ return;
+
+ list_for_each_entry(avp, &ctx->vifs, list) {
+ struct ieee80211_vif *vif = avp->vif;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_STATION:
+ if (vif->bss_conf.assoc)
+ active = true;
+ break;
+ default:
+ active = true;
+ break;
+ }
+ }
+ ctx->active = active;
+
+ ath_for_each_chanctx(sc, ctx) {
+ if (!ctx->assigned || list_empty(&ctx->vifs))
+ continue;
+ n_active++;
+ }
+
+ if (n_active <= 1) {
+ clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags);
+ return;
+ }
+ if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
+ return;
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL);
+}
+
+static bool
+ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave)
+{
+ struct ath_vif *avp;
+ bool sent = false;
+
+ rcu_read_lock();
+ list_for_each_entry(avp, &sc->cur_chan->vifs, list) {
+ if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave))
+ sent = true;
+ }
+ rcu_read_unlock();
+
+ return sent;
+}
+
+static bool ath_chanctx_defer_switch(struct ath_softc *sc)
+{
+ if (sc->cur_chan == &sc->offchannel.chan)
+ return false;
+
+ switch (sc->sched.state) {
+ case ATH_CHANCTX_STATE_SWITCH:
+ return false;
+ case ATH_CHANCTX_STATE_IDLE:
+ if (!sc->cur_chan->switch_after_beacon)
+ return false;
+
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+static void ath_chanctx_set_next(struct ath_softc *sc, bool force)
+{
+ struct timespec ts;
+ bool measure_time = false;
+ bool send_ps = false;
+
+ spin_lock_bh(&sc->chan_lock);
+ if (!sc->next_chan) {
+ spin_unlock_bh(&sc->chan_lock);
+ return;
+ }
+
+ if (!force && ath_chanctx_defer_switch(sc)) {
+ spin_unlock_bh(&sc->chan_lock);
+ return;
+ }
+
+ if (sc->cur_chan != sc->next_chan) {
+ sc->cur_chan->stopped = true;
+ spin_unlock_bh(&sc->chan_lock);
+
+ if (sc->next_chan == &sc->offchannel.chan) {
+ getrawmonotonic(&ts);
+ measure_time = true;
+ }
+ __ath9k_flush(sc->hw, ~0, true);
+
+ if (ath_chanctx_send_ps_frame(sc, true))
+ __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false);
+
+ send_ps = true;
+ spin_lock_bh(&sc->chan_lock);
+
+ if (sc->cur_chan != &sc->offchannel.chan) {
+ getrawmonotonic(&sc->cur_chan->tsf_ts);
+ sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah);
+ }
+ }
+ sc->cur_chan = sc->next_chan;
+ sc->cur_chan->stopped = false;
+ sc->next_chan = NULL;
+ sc->sched.offchannel_duration = 0;
+ if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE)
+ sc->sched.state = ATH_CHANCTX_STATE_IDLE;
+
+ spin_unlock_bh(&sc->chan_lock);
+
+ if (sc->sc_ah->chip_fullsleep ||
+ memcmp(&sc->cur_chandef, &sc->cur_chan->chandef,
+ sizeof(sc->cur_chandef))) {
+ ath_set_channel(sc);
+ if (measure_time)
+ sc->sched.channel_switch_time =
+ ath9k_hw_get_tsf_offset(&ts, NULL);
+ }
+ if (send_ps)
+ ath_chanctx_send_ps_frame(sc, false);
+
+ ath_offchannel_channel_change(sc);
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH);
+}
+
+void ath_chanctx_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ chanctx_work);
+ mutex_lock(&sc->mutex);
+ ath_chanctx_set_next(sc, false);
+ mutex_unlock(&sc->mutex);
+}
+
+void ath_chanctx_init(struct ath_softc *sc)
+{
+ struct ath_chanctx *ctx;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *chan;
+ int i, j;
+
+ sband = &common->sbands[IEEE80211_BAND_2GHZ];
+ if (!sband->n_channels)
+ sband = &common->sbands[IEEE80211_BAND_5GHZ];
+
+ chan = &sband->channels[0];
+ for (i = 0; i < ATH9K_NUM_CHANCTX; i++) {
+ ctx = &sc->chanctx[i];
+ cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
+ INIT_LIST_HEAD(&ctx->vifs);
+ ctx->txpower = ATH_TXPOWER_MAX;
+ for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
+ INIT_LIST_HEAD(&ctx->acq[j]);
+ }
+ ctx = &sc->offchannel.chan;
+ cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
+ INIT_LIST_HEAD(&ctx->vifs);
+ ctx->txpower = ATH_TXPOWER_MAX;
+ for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
+ INIT_LIST_HEAD(&ctx->acq[j]);
+ sc->offchannel.chan.offchannel = true;
+
+}
+
+void ath9k_chanctx_force_active(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
+ bool changed = false;
+
+ if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
+ return;
+
+ if (!avp->chanctx)
+ return;
+
+ mutex_lock(&sc->mutex);
+
+ spin_lock_bh(&sc->chan_lock);
+ if (sc->next_chan || (sc->cur_chan != avp->chanctx)) {
+ sc->next_chan = avp->chanctx;
+ changed = true;
+ }
+ sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
+ spin_unlock_bh(&sc->chan_lock);
+
+ if (changed)
+ ath_chanctx_set_next(sc, true);
+
+ mutex_unlock(&sc->mutex);
+}
+
+void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
+ struct cfg80211_chan_def *chandef)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ spin_lock_bh(&sc->chan_lock);
+
+ if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&
+ (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {
+ sc->sched.offchannel_pending = true;
+ spin_unlock_bh(&sc->chan_lock);
+ return;
+ }
+
+ sc->next_chan = ctx;
+ if (chandef)
+ ctx->chandef = *chandef;
+
+ if (sc->next_chan == &sc->offchannel.chan) {
+ sc->sched.offchannel_duration =
+ TU_TO_USEC(sc->offchannel.duration) +
+ sc->sched.channel_switch_time;
+ }
+ spin_unlock_bh(&sc->chan_lock);
+ ieee80211_queue_work(sc->hw, &sc->chanctx_work);
+}
+
+void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
+ struct cfg80211_chan_def *chandef)
+{
+ bool cur_chan;
+
+ spin_lock_bh(&sc->chan_lock);
+ if (chandef)
+ memcpy(&ctx->chandef, chandef, sizeof(*chandef));
+ cur_chan = sc->cur_chan == ctx;
+ spin_unlock_bh(&sc->chan_lock);
+
+ if (!cur_chan)
+ return;
+
+ ath_set_channel(sc);
+}
+
+struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active)
+{
+ struct ath_chanctx *ctx;
+
+ ath_for_each_chanctx(sc, ctx) {
+ if (!ctx->assigned || list_empty(&ctx->vifs))
+ continue;
+ if (active && !ctx->active)
+ continue;
+
+ if (ctx->switch_after_beacon)
+ return ctx;
+ }
+
+ return &sc->chanctx[0];
+}
+
+void ath_chanctx_offchan_switch(struct ath_softc *sc,
+ struct ieee80211_channel *chan)
+{
+ struct cfg80211_chan_def chandef;
+
+ cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
+
+ ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef);
+}
+
+static struct ath_chanctx *
+ath_chanctx_get_next(struct ath_softc *sc, struct ath_chanctx *ctx)
+{
+ int idx = ctx - &sc->chanctx[0];
+
+ return &sc->chanctx[!idx];
+}
+
+static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc)
+{
+ struct ath_chanctx *prev, *cur;
+ struct timespec ts;
+ u32 cur_tsf, prev_tsf, beacon_int;
+ s32 offset;
+
+ beacon_int = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
+
+ cur = sc->cur_chan;
+ prev = ath_chanctx_get_next(sc, cur);
+
+ getrawmonotonic(&ts);
+ cur_tsf = (u32) cur->tsf_val +
+ ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts);
+
+ prev_tsf = prev->last_beacon - (u32) prev->tsf_val + cur_tsf;
+ prev_tsf -= ath9k_hw_get_tsf_offset(&prev->tsf_ts, &ts);
+
+ /* Adjust the TSF time of the AP chanctx to keep its beacons
+ * at half beacon interval offset relative to the STA chanctx.
+ */
+ offset = cur_tsf - prev_tsf;
+
+ /* Ignore stale data or spurious timestamps */
+ if (offset < 0 || offset > 3 * beacon_int)
+ return;
+
+ offset = beacon_int / 2 - (offset % beacon_int);
+ prev->tsf_val += offset;
+}
+
+void ath_chanctx_timer(unsigned long data)
+{
+ struct ath_softc *sc = (struct ath_softc *) data;
+
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
+}
+
+/* Configure the TSF based hardware timer for a channel switch.
+ * Also set up backup software timer, in case the gen timer fails.
+ * This could be caused by a hardware reset.
+ */
+static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)
+{
+ struct ath_hw *ah = sc->sc_ah;
+
+ ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);
+ tsf_time -= ath9k_hw_gettsf32(ah);
+ tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
+ mod_timer(&sc->sched.timer, tsf_time);
+}
+
+void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
+ enum ath_chanctx_event ev)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_beacon_config *cur_conf;
+ struct ath_vif *avp = NULL;
+ struct ath_chanctx *ctx;
+ u32 tsf_time;
+ u32 beacon_int;
+ bool noa_changed = false;
+
+ if (vif)
+ avp = (struct ath_vif *) vif->drv_priv;
+
+ spin_lock_bh(&sc->chan_lock);
+
+ switch (ev) {
+ case ATH_CHANCTX_EVENT_BEACON_PREPARE:
+ if (avp->offchannel_duration)
+ avp->offchannel_duration = 0;
+
+ if (avp->chanctx != sc->cur_chan)
+ break;
+
+ if (sc->sched.offchannel_pending) {
+ sc->sched.offchannel_pending = false;
+ sc->next_chan = &sc->offchannel.chan;
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
+ }
+
+ ctx = ath_chanctx_get_next(sc, sc->cur_chan);
+ if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) {
+ sc->next_chan = ctx;
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
+ }
+
+ /* if the timer missed its window, use the next interval */
+ if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
+
+ if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
+ break;
+
+ sc->sched.beacon_pending = true;
+ sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER);
+
+ cur_conf = &sc->cur_chan->beacon;
+ beacon_int = TU_TO_USEC(cur_conf->beacon_interval);
+
+ /* defer channel switch by a quarter beacon interval */
+ tsf_time = sc->sched.next_tbtt + beacon_int / 4;
+ sc->sched.switch_start_time = tsf_time;
+ sc->cur_chan->last_beacon = sc->sched.next_tbtt;
+
+ /* Prevent wrap-around issues */
+ if (avp->periodic_noa_duration &&
+ tsf_time - avp->periodic_noa_start > BIT(30))
+ avp->periodic_noa_duration = 0;
+
+ if (ctx->active && !avp->periodic_noa_duration) {
+ avp->periodic_noa_start = tsf_time;
+ avp->periodic_noa_duration =
+ TU_TO_USEC(cur_conf->beacon_interval) / 2 -
+ sc->sched.channel_switch_time;
+ noa_changed = true;
+ } else if (!ctx->active && avp->periodic_noa_duration) {
+ avp->periodic_noa_duration = 0;
+ noa_changed = true;
+ }
+
+ /* If at least two consecutive beacons were missed on the STA
+ * chanctx, stay on the STA channel for one extra beacon period,
+ * to resync the timer properly.
+ */
+ if (ctx->active && sc->sched.beacon_miss >= 2)
+ sc->sched.offchannel_duration = 3 * beacon_int / 2;
+
+ if (sc->sched.offchannel_duration) {
+ noa_changed = true;
+ avp->offchannel_start = tsf_time;
+ avp->offchannel_duration =
+ sc->sched.offchannel_duration;
+ }
+
+ if (noa_changed)
+ avp->noa_index++;
+ break;
+ case ATH_CHANCTX_EVENT_BEACON_SENT:
+ if (!sc->sched.beacon_pending)
+ break;
+
+ sc->sched.beacon_pending = false;
+ if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
+ break;
+
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
+ ath_chanctx_setup_timer(sc, sc->sched.switch_start_time);
+ break;
+ case ATH_CHANCTX_EVENT_TSF_TIMER:
+ if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
+ break;
+
+ if (!sc->cur_chan->switch_after_beacon &&
+ sc->sched.beacon_pending)
+ sc->sched.beacon_miss++;
+
+ sc->sched.state = ATH_CHANCTX_STATE_SWITCH;
+ ieee80211_queue_work(sc->hw, &sc->chanctx_work);
+ break;
+ case ATH_CHANCTX_EVENT_BEACON_RECEIVED:
+ if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
+ sc->cur_chan == &sc->offchannel.chan)
+ break;
+
+ ath_chanctx_adjust_tbtt_delta(sc);
+ sc->sched.beacon_pending = false;
+ sc->sched.beacon_miss = 0;
+
+ /* TSF time might have been updated by the incoming beacon,
+ * need update the channel switch timer to reflect the change.
+ */
+ tsf_time = sc->sched.switch_start_time;
+ tsf_time -= (u32) sc->cur_chan->tsf_val +
+ ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
+ tsf_time += ath9k_hw_gettsf32(ah);
+
+
+ ath_chanctx_setup_timer(sc, tsf_time);
+ break;
+ case ATH_CHANCTX_EVENT_ASSOC:
+ if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||
+ avp->chanctx != sc->cur_chan)
+ break;
+
+ sc->sched.state = ATH_CHANCTX_STATE_IDLE;
+ /* fall through */
+ case ATH_CHANCTX_EVENT_SWITCH:
+ if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
+ sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||
+ sc->cur_chan->switch_after_beacon ||
+ sc->cur_chan == &sc->offchannel.chan)
+ break;
+
+ /* If this is a station chanctx, stay active for a half
+ * beacon period (minus channel switch time)
+ */
+ sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
+ cur_conf = &sc->cur_chan->beacon;
+
+ sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
+
+ tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;
+ if (sc->sched.beacon_miss >= 2) {
+ sc->sched.beacon_miss = 0;
+ tsf_time *= 3;
+ }
+
+ tsf_time -= sc->sched.channel_switch_time;
+ tsf_time += ath9k_hw_gettsf32(sc->sc_ah);
+ sc->sched.switch_start_time = tsf_time;
+
+ ath_chanctx_setup_timer(sc, tsf_time);
+ sc->sched.beacon_pending = true;
+ break;
+ case ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL:
+ if (sc->cur_chan == &sc->offchannel.chan ||
+ sc->cur_chan->switch_after_beacon)
+ break;
+
+ sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
+ ieee80211_queue_work(sc->hw, &sc->chanctx_work);
+ break;
+ case ATH_CHANCTX_EVENT_UNASSIGN:
+ if (sc->cur_chan->assigned) {
+ if (sc->next_chan && !sc->next_chan->assigned &&
+ sc->next_chan != &sc->offchannel.chan)
+ sc->sched.state = ATH_CHANCTX_STATE_IDLE;
+ break;
+ }
+
+ ctx = ath_chanctx_get_next(sc, sc->cur_chan);
+ sc->sched.state = ATH_CHANCTX_STATE_IDLE;
+ if (!ctx->assigned)
+ break;
+
+ sc->next_chan = ctx;
+ ieee80211_queue_work(sc->hw, &sc->chanctx_work);
+ break;
+ }
+
+ spin_unlock_bh(&sc->chan_lock);
+}
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.c b/drivers/net/wireless/ath/ath9k/common-beacon.c
index 775d1d20ce0b..733be5178481 100644
--- a/drivers/net/wireless/ath/ath9k/common-beacon.c
+++ b/drivers/net/wireless/ath/ath9k/common-beacon.c
@@ -57,7 +57,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
struct ath9k_beacon_state *bs)
{
struct ath_common *common = ath9k_hw_common(ah);
- int dtim_intval;
+ int dtim_intval, sleepduration;
u64 tsf;
/* No need to configure beacon if we are not associated */
@@ -75,6 +75,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
* last beacon we received (which may be none).
*/
dtim_intval = conf->intval * conf->dtim_period;
+ sleepduration = ah->hw->conf.listen_interval * conf->intval;
/*
* Pull nexttbtt forward to reflect the current
@@ -112,7 +113,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
*/
bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
- conf->intval));
+ sleepduration));
if (bs->bs_sleepduration > bs->bs_dtimperiod)
bs->bs_sleepduration = bs->bs_dtimperiod;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 6cc42be48d4e..d2279365be6f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -202,7 +202,7 @@ static ssize_t write_file_ani(struct file *file,
if (kstrtoul(buf, 0, &ani))
return -EINVAL;
- if (ani < 0 || ani > 1)
+ if (ani > 1)
return -EINVAL;
common->disable_ani = !ani;
@@ -750,13 +750,13 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ieee80211_hw *hw = sc->hw;
struct ath9k_vif_iter_data iter_data;
+ struct ath_chanctx *ctx;
char buf[512];
unsigned int len = 0;
ssize_t retval = 0;
unsigned int reg;
- u32 rxfilter;
+ u32 rxfilter, i;
len += scnprintf(buf + len, sizeof(buf) - len,
"BSSID: %pM\n", common->curbssid);
@@ -826,14 +826,20 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
len += scnprintf(buf + len, sizeof(buf) - len, "\n");
- ath9k_calculate_iter_data(hw, NULL, &iter_data);
-
- len += scnprintf(buf + len, sizeof(buf) - len,
- "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
- " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
- iter_data.naps, iter_data.nstations, iter_data.nmeshes,
- iter_data.nwds, iter_data.nadhocs,
- sc->nvifs, sc->nbcnvifs);
+ i = 0;
+ ath_for_each_chanctx(sc, ctx) {
+ if (!ctx->assigned || list_empty(&ctx->vifs))
+ continue;
+ ath9k_calculate_iter_data(sc, ctx, &iter_data);
+
+ len += scnprintf(buf + len, sizeof(buf) - len,
+ "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i",
+ i++, iter_data.naps, iter_data.nstations,
+ iter_data.nmeshes, iter_data.nwds);
+ len += scnprintf(buf + len, sizeof(buf) - len,
+ " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
+ iter_data.nadhocs, sc->nvifs, sc->nbcnvifs);
+ }
if (len > sizeof(buf))
len = sizeof(buf);
@@ -1080,7 +1086,7 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
{
struct ath_softc *sc = file->private_data;
struct ath_hw *ah = sc->sc_ah;
- struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist;
+ struct ath9k_nfcal_hist *h = sc->cur_chan->caldata.nfCalHist;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
u32 len = 0, size = 1500;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2a8ed8375ec0..69bbea1184d2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -791,7 +791,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
refdiv = 5;
} else {
pll2_divint = 0x11;
- pll2_divfrac = 0x26666;
+ pll2_divfrac =
+ AR_SREV_9531(ah) ? 0x26665 : 0x26666;
refdiv = 1;
}
}
@@ -1730,11 +1731,27 @@ fail:
return -EINVAL;
}
+u32 ath9k_hw_get_tsf_offset(struct timespec *last, struct timespec *cur)
+{
+ struct timespec ts;
+ s64 usec;
+
+ if (!cur) {
+ getrawmonotonic(&ts);
+ cur = &ts;
+ }
+
+ usec = cur->tv_sec * 1000000ULL + cur->tv_nsec / 1000;
+ usec -= last->tv_sec * 1000000ULL + last->tv_nsec / 1000;
+
+ return (u32) usec;
+}
+EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
+
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool fastcc)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct timespec ts;
u32 saveLedState;
u32 saveDefAntenna;
u32 macStaId1;
@@ -1784,8 +1801,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
/* Save TSF before chip reset, a cold reset clears it */
tsf = ath9k_hw_gettsf64(ah);
- getrawmonotonic(&ts);
- usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
+ usec = ktime_to_us(ktime_get_raw());
saveLedState = REG_READ(ah, AR_CFG_LED) &
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1818,8 +1834,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
}
/* Restore TSF */
- getrawmonotonic(&ts);
- usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000 - usec;
+ usec = ktime_to_us(ktime_get_raw()) - usec;
ath9k_hw_settsf64(ah, tsf + usec);
if (AR_SREV_9280_20_OR_LATER(ah))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0acd4b5a4892..51b4ebe04c04 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1000,6 +1000,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
u64 ath9k_hw_gettsf64(struct ath_hw *ah);
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah);
+u32 ath9k_hw_get_tsf_offset(struct timespec *last, struct timespec *cur);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set);
void ath9k_hw_init_global_settings(struct ath_hw *ah);
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0246b990fe87..39419ea845cc 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -61,7 +61,7 @@ static int ath9k_ps_enable;
module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
-static int ath9k_use_chanctx;
+int ath9k_use_chanctx;
module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444);
MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency");
@@ -169,9 +169,9 @@ static void ath9k_reg_notifier(struct wiphy *wiphy,
/* Set tx power */
if (ah->curchan) {
- sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
+ sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
ath9k_ps_wakeup(sc);
- ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
+ ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
/* synchronize DFS detector if regulatory domain changed */
if (sc->dfs_detector != NULL)
@@ -335,7 +335,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
common->last_rssi = ATH_RSSI_DUMMY_MARKER;
- sc->config.txpowlimit = ATH_TXPOWER_MAX;
memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
sc->beacon.slottime = ATH9K_SLOT_TIME_9;
@@ -511,6 +510,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
sc->tx99_power = MAX_RATE_POWER + 1;
init_waitqueue_head(&sc->tx_wait);
+ sc->cur_chan = &sc->chanctx[0];
+ if (!ath9k_use_chanctx)
+ sc->cur_chan->hw_queue_base = 0;
if (!pdata || pdata->use_eeprom) {
ah->ah_flags |= AH_USE_EEPROM;
@@ -556,6 +558,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
spin_lock_init(&common->cc_lock);
spin_lock_init(&sc->sc_serial_rw);
spin_lock_init(&sc->sc_pm_lock);
+ spin_lock_init(&sc->chan_lock);
mutex_init(&sc->mutex);
tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
@@ -564,7 +567,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+ INIT_WORK(&sc->chanctx_work, ath_chanctx_work);
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+ setup_timer(&sc->offchannel.timer, ath_offchannel_timer,
+ (unsigned long)sc);
+ setup_timer(&sc->sched.timer, ath_chanctx_timer, (unsigned long)sc);
/*
* Cache line size is used to size and align various
@@ -599,6 +606,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
ath9k_cmn_init_crypto(sc->sc_ah);
ath9k_init_misc(sc);
ath_fill_led_pin(sc);
+ ath_chanctx_init(sc);
if (common->bus_ops->aspm_init)
common->bus_ops->aspm_init(common);
@@ -664,6 +672,12 @@ static const struct ieee80211_iface_limit wds_limits[] = {
{ .max = 2048, .types = BIT(NL80211_IFTYPE_WDS) },
};
+static const struct ieee80211_iface_limit if_limits_multi[] = {
+ { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO) },
+};
+
static const struct ieee80211_iface_limit if_dfs_limits[] = {
{ .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
@@ -672,6 +686,16 @@ static const struct ieee80211_iface_limit if_dfs_limits[] = {
BIT(NL80211_IFTYPE_ADHOC) },
};
+static const struct ieee80211_iface_combination if_comb_multi[] = {
+ {
+ .limits = if_limits_multi,
+ .n_limits = ARRAY_SIZE(if_limits_multi),
+ .max_interfaces = 2,
+ .num_different_channels = 2,
+ .beacon_int_infra_match = true,
+ },
+};
+
static const struct ieee80211_iface_combination if_comb[] = {
{
.limits = if_limits,
@@ -712,6 +736,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_SUPPORTS_RC_TABLE |
+ IEEE80211_HW_QUEUE_CONTROL |
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
if (ath9k_ps_enable)
@@ -739,12 +764,21 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->wiphy->iface_combinations = if_comb;
if (!ath9k_use_chanctx) {
+ hw->wiphy->iface_combinations = if_comb;
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_WDS);
- } else
- hw->wiphy->n_iface_combinations = 1;
+ } else {
+ hw->wiphy->iface_combinations = if_comb_multi;
+ hw->wiphy->n_iface_combinations =
+ ARRAY_SIZE(if_comb_multi);
+ hw->wiphy->max_scan_ssids = 255;
+ hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+ hw->wiphy->max_remain_on_channel_duration = 10000;
+ hw->chanctx_data_size = sizeof(void *);
+ hw->extra_beacon_tailroom =
+ sizeof(struct ieee80211_p2p_noa_attr) + 9;
+ }
}
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -756,9 +790,14 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
- hw->queues = 4;
+ /* allow 4 queues per channel context +
+ * 1 cab queue + 1 offchannel tx queue
+ */
+ hw->queues = 10;
+ /* last queue for offchannel */
+ hw->offchannel_tx_hw_queue = hw->queues - 1;
hw->max_rates = 4;
- hw->max_listen_interval = 1;
+ hw->max_listen_interval = 10;
hw->max_rate_tries = 10;
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 72a715fe8f24..2343f56e6498 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -178,7 +178,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
memset(tx_info, 0, sizeof(*tx_info));
- tx_info->band = hw->conf.chandef.chan->band;
+ tx_info->band = sc->cur_chandef.chan->band;
tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
tx_info->control.rates[0].idx = 0;
tx_info->control.rates[0].count = 1;
@@ -416,7 +416,7 @@ void ath_start_ani(struct ath_softc *sc)
if (common->disable_ani ||
!test_bit(ATH_OP_ANI_RUN, &common->op_flags) ||
- (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
+ sc->cur_chan->offchannel)
return;
common->ani.longcal_timer = timestamp;
@@ -440,7 +440,7 @@ void ath_check_ani(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
/*
* Check for the various conditions in which ANI has to
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index da7686757535..6c56cafa5ca4 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -346,8 +346,14 @@ struct ar5416_desc {
#define AR_FrameLen 0x00000fff
#define AR_VirtMoreFrag 0x00001000
#define AR_TxCtlRsvd00 0x0000e000
-#define AR_XmitPower 0x003f0000
-#define AR_XmitPower_S 16
+#define AR_XmitPower0 0x003f0000
+#define AR_XmitPower0_S 16
+#define AR_XmitPower1 0x3f000000
+#define AR_XmitPower1_S 24
+#define AR_XmitPower2 0x3f000000
+#define AR_XmitPower2_S 24
+#define AR_XmitPower3 0x3f000000
+#define AR_XmitPower3_S 24
#define AR_RTSEnable 0x00400000
#define AR_VEOL 0x00800000
#define AR_ClrDestMask 0x01000000
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 62ac95d6bb9d..e6ac8d2e610c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -19,9 +19,6 @@
#include "ath9k.h"
#include "btcoex.h"
-static void ath9k_set_assoc_state(struct ath_softc *sc,
- struct ieee80211_vif *vif);
-
u8 ath9k_parse_mpdudensity(u8 mpdudensity)
{
/*
@@ -63,9 +60,16 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
spin_lock_bh(&txq->axq_lock);
- if (txq->axq_depth || !list_empty(&txq->axq_acq))
+ if (txq->axq_depth)
pending = true;
+ if (txq->mac80211_qnum >= 0) {
+ struct list_head *list;
+
+ list = &sc->cur_chan->acq[txq->mac80211_qnum];
+ if (!list_empty(list))
+ pending = true;
+ }
spin_unlock_bh(&txq->axq_lock);
return pending;
}
@@ -227,13 +231,22 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
}
ath9k_cmn_update_txpow(ah, sc->curtxpow,
- sc->config.txpowlimit, &sc->curtxpow);
+ sc->cur_chan->txpower, &sc->curtxpow);
clear_bit(ATH_OP_HW_RESET, &common->op_flags);
- ath9k_hw_set_interrupts(ah);
- ath9k_hw_enable_interrupts(ah);
+ ath9k_calculate_summary_state(sc, sc->cur_chan);
+
+ if (!sc->cur_chan->offchannel && start) {
+ /* restore per chanctx TSF timer */
+ if (sc->cur_chan->tsf_val) {
+ u32 offset;
+
+ offset = ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts,
+ NULL);
+ ath9k_hw_settsf64(ah, sc->cur_chan->tsf_val + offset);
+ }
+
- if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) {
if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
goto work;
@@ -247,26 +260,35 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
}
work:
ath_restart_work(sc);
+ ath_txq_schedule_all(sc);
+ }
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (!ATH_TXQ_SETUP(sc, i))
- continue;
+ sc->gtt_cnt = 0;
- spin_lock_bh(&sc->tx.txq[i].axq_lock);
- ath_txq_schedule(sc, &sc->tx.txq[i]);
- spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+ ath9k_hw_set_interrupts(ah);
+ ath9k_hw_enable_interrupts(ah);
+
+ if (!ath9k_use_chanctx)
+ ieee80211_wake_queues(sc->hw);
+ else {
+ if (sc->cur_chan == &sc->offchannel.chan)
+ ieee80211_wake_queue(sc->hw,
+ sc->hw->offchannel_tx_hw_queue);
+ else {
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
+ ieee80211_wake_queue(sc->hw,
+ sc->cur_chan->hw_queue_base + i);
}
+ if (ah->opmode == NL80211_IFTYPE_AP)
+ ieee80211_wake_queue(sc->hw, sc->hw->queues - 2);
}
- sc->gtt_cnt = 0;
- ieee80211_wake_queues(sc->hw);
-
ath9k_p2p_ps_timer(sc);
return true;
}
-static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
+int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
@@ -279,9 +301,9 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
tasklet_disable(&sc->intr_tq);
spin_lock_bh(&sc->sc_pcu_lock);
- if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
+ if (!sc->cur_chan->offchannel) {
fastcc = false;
- caldata = &sc->caldata;
+ caldata = &sc->cur_chan->caldata;
}
if (!hchan) {
@@ -292,6 +314,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
if (!ath_prepare_reset(sc))
fastcc = false;
+ spin_lock_bh(&sc->chan_lock);
+ sc->cur_chandef = sc->cur_chan->chandef;
+ spin_unlock_bh(&sc->chan_lock);
+
ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
hchan->channel, IS_CHAN_HT40(hchan), fastcc);
@@ -307,7 +333,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
}
if (ath9k_hw_mci_is_enabled(sc->sc_ah) &&
- (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
+ sc->cur_chan->offchannel)
ath9k_mci_set_txpower(sc, true, false);
if (!ath_complete_reset(sc, true))
@@ -320,98 +346,6 @@ out:
return r;
}
-
-/*
- * Set/change channels. If the channel is really being changed, it's done
- * by reseting the chip. To accomplish this we must first cleanup any pending
- * DMA, then restart stuff.
-*/
-static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_hw *hw = sc->hw;
- struct ath9k_channel *hchan;
- struct ieee80211_channel *chan = chandef->chan;
- bool offchannel;
- int pos = chan->hw_value;
- int old_pos = -1;
- int r;
-
- if (test_bit(ATH_OP_INVALID, &common->op_flags))
- return -EIO;
-
- offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
-
- if (ah->curchan)
- old_pos = ah->curchan - &ah->channels[0];
-
- ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
- chan->center_freq, chandef->width);
-
- /* update survey stats for the old channel before switching */
- spin_lock_bh(&common->cc_lock);
- ath_update_survey_stats(sc);
- spin_unlock_bh(&common->cc_lock);
-
- ath9k_cmn_get_channel(hw, ah, chandef);
-
- /*
- * If the operating channel changes, change the survey in-use flags
- * along with it.
- * Reset the survey data for the new channel, unless we're switching
- * back to the operating channel from an off-channel operation.
- */
- if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
- if (sc->cur_survey)
- sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
-
- sc->cur_survey = &sc->survey[pos];
-
- memset(sc->cur_survey, 0, sizeof(struct survey_info));
- sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
- } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
- memset(&sc->survey[pos], 0, sizeof(struct survey_info));
- }
-
- hchan = &sc->sc_ah->channels[pos];
- r = ath_reset_internal(sc, hchan);
- if (r)
- return r;
-
- /*
- * The most recent snapshot of channel->noisefloor for the old
- * channel is only available after the hardware reset. Copy it to
- * the survey stats now.
- */
- if (old_pos >= 0)
- ath_update_survey_nf(sc, old_pos);
-
- /*
- * Enable radar pulse detection if on a DFS channel. Spectral
- * scanning and radar detection can not be used concurrently.
- */
- if (hw->conf.radar_enabled) {
- u32 rxfilter;
-
- /* set HW specific DFS configuration */
- ath9k_hw_set_radar_params(ah);
- rxfilter = ath9k_hw_getrxfilter(ah);
- rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
- ATH9K_RX_FILTER_PHYERR;
- ath9k_hw_setrxfilter(ah, rxfilter);
- ath_dbg(common, DFS, "DFS enabled at freq %d\n",
- chan->center_freq);
- } else {
- /* perform spectral scan if requested. */
- if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
- sc->spectral_mode == SPECTRAL_CHANSCAN)
- ath9k_spectral_scan_trigger(hw);
- }
-
- return 0;
-}
-
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
struct ieee80211_vif *vif)
{
@@ -712,7 +646,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+ struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
+ struct ath_chanctx *ctx = sc->cur_chan;
struct ath9k_channel *init_channel;
int r;
@@ -723,7 +658,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
- init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
+ init_channel = ath9k_cmn_get_channel(hw, ah, &ctx->chandef);
+ sc->cur_chandef = hw->conf.chandef;
/* Reset SERDES registers */
ath9k_hw_configpcipowersave(ah, false);
@@ -886,6 +822,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
struct ath_common *common = ath9k_hw_common(ah);
bool prev_idle;
+ cancel_work_sync(&sc->chanctx_work);
mutex_lock(&sc->mutex);
ath_cancel_work(sc);
@@ -934,7 +871,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
}
if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
+ ah->curchan = ath9k_cmn_get_channel(hw, ah,
+ &sc->cur_chan->chandef);
ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
ath9k_hw_phy_disable(ah);
@@ -979,18 +917,29 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
iter_data->has_hw_macaddr = true;
}
+ if (!vif->bss_conf.use_short_slot)
+ iter_data->slottime = ATH9K_SLOT_TIME_20;
+
switch (vif->type) {
case NL80211_IFTYPE_AP:
iter_data->naps++;
+ if (vif->bss_conf.enable_beacon)
+ iter_data->beacons = true;
break;
case NL80211_IFTYPE_STATION:
iter_data->nstations++;
+ if (vif->bss_conf.assoc && !iter_data->primary_sta)
+ iter_data->primary_sta = vif;
break;
case NL80211_IFTYPE_ADHOC:
iter_data->nadhocs++;
+ if (vif->bss_conf.enable_beacon)
+ iter_data->beacons = true;
break;
case NL80211_IFTYPE_MESH_POINT:
iter_data->nmeshes++;
+ if (vif->bss_conf.enable_beacon)
+ iter_data->beacons = true;
break;
case NL80211_IFTYPE_WDS:
iter_data->nwds++;
@@ -1000,26 +949,12 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
}
}
-static void ath9k_sta_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
- struct ath_softc *sc = data;
- struct ath_vif *avp = (void *)vif->drv_priv;
-
- if (vif->type != NL80211_IFTYPE_STATION)
- return;
-
- if (avp->primary_sta_vif)
- ath9k_set_assoc_state(sc, vif);
-}
-
/* Called with sc->mutex held. */
-void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
+void ath9k_calculate_iter_data(struct ath_softc *sc,
+ struct ath_chanctx *ctx,
struct ath9k_vif_iter_data *iter_data)
{
- struct ath_softc *sc = hw->priv;
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_vif *avp;
/*
* Pick the MAC address of the first interface as the new hardware
@@ -1028,29 +963,80 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
*/
memset(iter_data, 0, sizeof(*iter_data));
memset(&iter_data->mask, 0xff, ETH_ALEN);
+ iter_data->slottime = ATH9K_SLOT_TIME_9;
+
+ list_for_each_entry(avp, &ctx->vifs, list)
+ ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
+
+ if (ctx == &sc->offchannel.chan) {
+ struct ieee80211_vif *vif;
+
+ if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
+ vif = sc->offchannel.scan_vif;
+ else
+ vif = sc->offchannel.roc_vif;
+
+ if (vif)
+ ath9k_vif_iter(iter_data, vif->addr, vif);
+ iter_data->beacons = false;
+ }
+}
+
+static void ath9k_set_assoc_state(struct ath_softc *sc,
+ struct ieee80211_vif *vif, bool changed)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ unsigned long flags;
- if (vif)
- ath9k_vif_iter(iter_data, vif->addr, vif);
+ set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
+ /* Set the AID, BSSID and do beacon-sync only when
+ * the HW opmode is STATION.
+ *
+ * But the primary bit is set above in any case.
+ */
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ ether_addr_copy(common->curbssid, bss_conf->bssid);
+ common->curaid = bss_conf->aid;
+ ath9k_hw_write_associd(sc->sc_ah);
- /* Get list of all active MAC addresses */
- ieee80211_iterate_active_interfaces_atomic(
- sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
- ath9k_vif_iter, iter_data);
+ if (changed) {
+ common->last_rssi = ATH_RSSI_DUMMY_MARKER;
+ sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
- memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
+ spin_lock_irqsave(&sc->sc_pm_lock, flags);
+ sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+ }
+
+ if (ath9k_hw_mci_is_enabled(sc->sc_ah))
+ ath9k_mci_update_wlan_channels(sc, false);
+
+ ath_dbg(common, CONFIG,
+ "Primary Station interface: %pM, BSSID: %pM\n",
+ vif->addr, common->curbssid);
}
/* Called with sc->mutex held. */
-static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+void ath9k_calculate_summary_state(struct ath_softc *sc,
+ struct ath_chanctx *ctx)
{
- struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_vif_iter_data iter_data;
- enum nl80211_iftype old_opmode = ah->opmode;
- ath9k_calculate_iter_data(hw, vif, &iter_data);
+ ath_chanctx_check_active(sc, ctx);
+
+ if (ctx != sc->cur_chan)
+ return;
+
+ ath9k_ps_wakeup(sc);
+ ath9k_calculate_iter_data(sc, ctx, &iter_data);
+
+ if (iter_data.has_hw_macaddr)
+ ether_addr_copy(common->macaddr, iter_data.hw_macaddr);
memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
ath_hw_setbssidmask(common);
@@ -1073,24 +1059,57 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
ath9k_hw_setopmode(ah);
+ ctx->switch_after_beacon = false;
if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
ah->imask |= ATH9K_INT_TSFOOR;
- else
+ else {
ah->imask &= ~ATH9K_INT_TSFOOR;
+ if (iter_data.naps == 1 && iter_data.beacons)
+ ctx->switch_after_beacon = true;
+ }
+
+ ah->imask &= ~ATH9K_INT_SWBA;
+ if (ah->opmode == NL80211_IFTYPE_STATION) {
+ bool changed = (iter_data.primary_sta != ctx->primary_sta);
+ iter_data.beacons = true;
+ if (iter_data.primary_sta) {
+ ath9k_set_assoc_state(sc, iter_data.primary_sta,
+ changed);
+ if (!ctx->primary_sta ||
+ !ctx->primary_sta->bss_conf.assoc)
+ ctx->primary_sta = iter_data.primary_sta;
+ } else {
+ ctx->primary_sta = NULL;
+ memset(common->curbssid, 0, ETH_ALEN);
+ common->curaid = 0;
+ ath9k_hw_write_associd(sc->sc_ah);
+ if (ath9k_hw_mci_is_enabled(sc->sc_ah))
+ ath9k_mci_update_wlan_channels(sc, true);
+ }
+ } else if (iter_data.beacons) {
+ ah->imask |= ATH9K_INT_SWBA;
+ }
ath9k_hw_set_interrupts(ah);
- /*
- * If we are changing the opmode to STATION,
- * a beacon sync needs to be done.
- */
- if (ah->opmode == NL80211_IFTYPE_STATION &&
- old_opmode == NL80211_IFTYPE_AP &&
- test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
- ieee80211_iterate_active_interfaces_atomic(
- sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
- ath9k_sta_vif_iter, sc);
+ if (iter_data.beacons)
+ set_bit(ATH_OP_BEACONS, &common->op_flags);
+ else
+ clear_bit(ATH_OP_BEACONS, &common->op_flags);
+
+ if (ah->slottime != iter_data.slottime) {
+ ah->slottime = iter_data.slottime;
+ ath9k_hw_init_global_settings(ah);
}
+
+ if (iter_data.primary_sta)
+ set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
+ else
+ clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
+
+ ctx->primary_sta = iter_data.primary_sta;
+
+ ath9k_ps_restore(sc);
}
static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1101,6 +1120,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv;
struct ath_node *an = &avp->mcast_node;
+ int i;
mutex_lock(&sc->mutex);
@@ -1115,14 +1135,20 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
sc->nvifs++;
- ath9k_ps_wakeup(sc);
- ath9k_calculate_summary_state(hw, vif);
- ath9k_ps_restore(sc);
-
if (ath9k_uses_beacons(vif->type))
ath9k_beacon_assign_slot(sc, vif);
avp->vif = vif;
+ if (!ath9k_use_chanctx) {
+ avp->chanctx = sc->cur_chan;
+ list_add_tail(&avp->list, &avp->chanctx->vifs);
+ }
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
+ vif->hw_queue[i] = i;
+ if (vif->type == NL80211_IFTYPE_AP)
+ vif->cab_queue = hw->queues - 2;
+ else
+ vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
an->sc = sc;
an->sta = NULL;
@@ -1141,6 +1167,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ int i;
mutex_lock(&sc->mutex);
@@ -1157,13 +1185,19 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
vif->type = new_type;
vif->p2p = p2p;
- ath9k_ps_wakeup(sc);
- ath9k_calculate_summary_state(hw, vif);
- ath9k_ps_restore(sc);
-
if (ath9k_uses_beacons(vif->type))
ath9k_beacon_assign_slot(sc, vif);
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
+ vif->hw_queue[i] = i;
+
+ if (vif->type == NL80211_IFTYPE_AP)
+ vif->cab_queue = hw->queues - 2;
+ else
+ vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
+
+ ath9k_calculate_summary_state(sc, avp->chanctx);
+
mutex_unlock(&sc->mutex);
return 0;
}
@@ -1211,14 +1245,12 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
sc->nvifs--;
sc->tx99_vif = NULL;
+ if (!ath9k_use_chanctx)
+ list_del(&avp->list);
if (ath9k_uses_beacons(vif->type))
ath9k_beacon_remove_slot(sc, vif);
- ath9k_ps_wakeup(sc);
- ath9k_calculate_summary_state(hw, NULL);
- ath9k_ps_restore(sc);
-
ath_tx_node_cleanup(sc, &avp->mcast_node);
mutex_unlock(&sc->mutex);
@@ -1345,7 +1377,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
- bool reset_channel = false;
+ struct ath_chanctx *ctx = sc->cur_chan;
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
@@ -1361,7 +1393,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
* The chip needs a reset to properly wake up from
* full sleep
*/
- reset_channel = ah->chip_fullsleep;
+ ath_chanctx_set_channel(sc, ctx, &ctx->chandef);
}
}
@@ -1391,20 +1423,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
}
- if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
- if (ath_set_channel(sc, &hw->conf.chandef) < 0) {
- ath_err(common, "Unable to set channel\n");
- mutex_unlock(&sc->mutex);
- ath9k_ps_restore(sc);
- return -EINVAL;
- }
+ if (!ath9k_use_chanctx && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
+ ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
- sc->config.txpowlimit = 2 * conf->power_level;
+ sc->cur_chan->txpower = 2 * conf->power_level;
ath9k_cmn_update_txpow(ah, sc->curtxpow,
- sc->config.txpowlimit, &sc->curtxpow);
+ sc->cur_chan->txpower, &sc->curtxpow);
}
mutex_unlock(&sc->mutex);
@@ -1659,58 +1687,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
return ret;
}
-static void ath9k_set_assoc_state(struct ath_softc *sc,
- struct ieee80211_vif *vif)
-{
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_vif *avp = (void *)vif->drv_priv;
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- unsigned long flags;
-
- set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
- avp->primary_sta_vif = true;
-
- /*
- * Set the AID, BSSID and do beacon-sync only when
- * the HW opmode is STATION.
- *
- * But the primary bit is set above in any case.
- */
- if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
- return;
-
- memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
- common->curaid = bss_conf->aid;
- ath9k_hw_write_associd(sc->sc_ah);
-
- common->last_rssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
-
- spin_lock_irqsave(&sc->sc_pm_lock, flags);
- sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
- spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-
- if (ath9k_hw_mci_is_enabled(sc->sc_ah))
- ath9k_mci_update_wlan_channels(sc, false);
-
- ath_dbg(common, CONFIG,
- "Primary Station interface: %pM, BSSID: %pM\n",
- vif->addr, common->curbssid);
-}
-
-static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
- struct ath_softc *sc = data;
- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-
- if (test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
- return;
-
- if (bss_conf->assoc)
- ath9k_set_assoc_state(sc, vif);
-}
-
void ath9k_p2p_ps_timer(void *priv)
{
struct ath_softc *sc = priv;
@@ -1720,7 +1696,11 @@ void ath9k_p2p_ps_timer(void *priv)
struct ath_node *an;
u32 tsf;
- if (!avp)
+ del_timer_sync(&sc->sched.timer);
+ ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer);
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
+
+ if (!avp || avp->chanctx != sc->cur_chan)
return;
tsf = ath9k_hw_gettsf32(sc->sc_ah);
@@ -1795,26 +1775,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
bss_conf->bssid, bss_conf->assoc);
- if (avp->primary_sta_vif && !bss_conf->assoc) {
- clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
- avp->primary_sta_vif = false;
-
- if (ah->opmode == NL80211_IFTYPE_STATION)
- clear_bit(ATH_OP_BEACONS, &common->op_flags);
- }
-
- ieee80211_iterate_active_interfaces_atomic(
- sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
- ath9k_bss_assoc_iter, sc);
-
- if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags) &&
- ah->opmode == NL80211_IFTYPE_STATION) {
- memset(common->curbssid, 0, ETH_ALEN);
- common->curaid = 0;
- ath9k_hw_write_associd(sc->sc_ah);
- if (ath9k_hw_mci_is_enabled(sc->sc_ah))
- ath9k_mci_update_wlan_channels(sc, true);
- }
+ ath9k_calculate_summary_state(sc, avp->chanctx);
+ if (bss_conf->assoc)
+ ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_ASSOC);
}
if (changed & BSS_CHANGED_IBSS) {
@@ -1824,10 +1787,15 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
}
if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
- (changed & BSS_CHANGED_BEACON_INT))
+ (changed & BSS_CHANGED_BEACON_INT) ||
+ (changed & BSS_CHANGED_BEACON_INFO)) {
+ if (changed & BSS_CHANGED_BEACON_ENABLED)
+ ath9k_calculate_summary_state(sc, avp->chanctx);
ath9k_beacon_config(sc, vif, changed);
+ }
- if (changed & BSS_CHANGED_ERP_SLOT) {
+ if ((avp->chanctx == sc->cur_chan) &&
+ (changed & BSS_CHANGED_ERP_SLOT)) {
if (bss_conf->use_short_slot)
slottime = 9;
else
@@ -2032,23 +2000,30 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{
struct ath_softc *sc = hw->priv;
+
+ mutex_lock(&sc->mutex);
+ __ath9k_flush(hw, queues, drop);
+ mutex_unlock(&sc->mutex);
+}
+
+void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+ struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
int timeout = HZ / 5; /* 200 ms */
bool drain_txq;
+ int i;
- mutex_lock(&sc->mutex);
cancel_delayed_work_sync(&sc->tx_complete_work);
if (ah->ah_flags & AH_UNPLUGGED) {
ath_dbg(common, ANY, "Device has been unplugged!\n");
- mutex_unlock(&sc->mutex);
return;
}
if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
ath_dbg(common, ANY, "Device not present\n");
- mutex_unlock(&sc->mutex);
return;
}
@@ -2066,11 +2041,13 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ath_reset(sc);
ath9k_ps_restore(sc);
- ieee80211_wake_queues(hw);
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ ieee80211_wake_queue(sc->hw,
+ sc->cur_chan->hw_queue_base + i);
+ }
}
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
- mutex_unlock(&sc->mutex);
}
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
@@ -2230,6 +2207,403 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
clear_bit(ATH_OP_SCANNING, &common->op_flags);
}
+static int ath_scan_channel_duration(struct ath_softc *sc,
+ struct ieee80211_channel *chan)
+{
+ struct cfg80211_scan_request *req = sc->offchannel.scan_req;
+
+ if (!req->n_ssids || (chan->flags & IEEE80211_CHAN_NO_IR))
+ return (HZ / 9); /* ~110 ms */
+
+ return (HZ / 16); /* ~60 ms */
+}
+
+static void
+ath_scan_next_channel(struct ath_softc *sc)
+{
+ struct cfg80211_scan_request *req = sc->offchannel.scan_req;
+ struct ieee80211_channel *chan;
+
+ if (sc->offchannel.scan_idx >= req->n_channels) {
+ sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
+ ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),
+ NULL);
+ return;
+ }
+
+ chan = req->channels[sc->offchannel.scan_idx++];
+ sc->offchannel.duration = ath_scan_channel_duration(sc, chan);
+ sc->offchannel.state = ATH_OFFCHANNEL_PROBE_SEND;
+ ath_chanctx_offchan_switch(sc, chan);
+}
+
+static void ath_offchannel_next(struct ath_softc *sc)
+{
+ struct ieee80211_vif *vif;
+
+ if (sc->offchannel.scan_req) {
+ vif = sc->offchannel.scan_vif;
+ sc->offchannel.chan.txpower = vif->bss_conf.txpower;
+ ath_scan_next_channel(sc);
+ } else if (sc->offchannel.roc_vif) {
+ vif = sc->offchannel.roc_vif;
+ sc->offchannel.chan.txpower = vif->bss_conf.txpower;
+ sc->offchannel.duration = sc->offchannel.roc_duration;
+ sc->offchannel.state = ATH_OFFCHANNEL_ROC_START;
+ ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan);
+ } else {
+ ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),
+ NULL);
+ sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
+ if (sc->ps_idle)
+ ath_cancel_work(sc);
+ }
+}
+
+static void ath_roc_complete(struct ath_softc *sc, bool abort)
+{
+ sc->offchannel.roc_vif = NULL;
+ sc->offchannel.roc_chan = NULL;
+ if (!abort)
+ ieee80211_remain_on_channel_expired(sc->hw);
+ ath_offchannel_next(sc);
+ ath9k_ps_restore(sc);
+}
+
+static void ath_scan_complete(struct ath_softc *sc, bool abort)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+ sc->offchannel.scan_req = NULL;
+ sc->offchannel.scan_vif = NULL;
+ sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
+ ieee80211_scan_completed(sc->hw, abort);
+ clear_bit(ATH_OP_SCANNING, &common->op_flags);
+ ath_offchannel_next(sc);
+ ath9k_ps_restore(sc);
+}
+
+static void ath_scan_send_probe(struct ath_softc *sc,
+ struct cfg80211_ssid *ssid)
+{
+ struct cfg80211_scan_request *req = sc->offchannel.scan_req;
+ struct ieee80211_vif *vif = sc->offchannel.scan_vif;
+ struct ath_tx_control txctl = {};
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ int band = sc->offchannel.chan.chandef.chan->band;
+
+ skb = ieee80211_probereq_get(sc->hw, vif,
+ ssid->ssid, ssid->ssid_len, req->ie_len);
+ if (!skb)
+ return;
+
+ info = IEEE80211_SKB_CB(skb);
+ if (req->no_cck)
+ info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
+
+ if (req->ie_len)
+ memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
+
+ skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+ goto error;
+
+ txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+ txctl.force_channel = true;
+ if (ath_tx_start(sc->hw, skb, &txctl))
+ goto error;
+
+ return;
+
+error:
+ ieee80211_free_txskb(sc->hw, skb);
+}
+
+static void ath_scan_channel_start(struct ath_softc *sc)
+{
+ struct cfg80211_scan_request *req = sc->offchannel.scan_req;
+ int i;
+
+ if (!(sc->cur_chan->chandef.chan->flags & IEEE80211_CHAN_NO_IR) &&
+ req->n_ssids) {
+ for (i = 0; i < req->n_ssids; i++)
+ ath_scan_send_probe(sc, &req->ssids[i]);
+
+ }
+
+ sc->offchannel.state = ATH_OFFCHANNEL_PROBE_WAIT;
+ mod_timer(&sc->offchannel.timer, jiffies + sc->offchannel.duration);
+}
+
+void ath_offchannel_channel_change(struct ath_softc *sc)
+{
+ switch (sc->offchannel.state) {
+ case ATH_OFFCHANNEL_PROBE_SEND:
+ if (!sc->offchannel.scan_req)
+ return;
+
+ if (sc->cur_chan->chandef.chan !=
+ sc->offchannel.chan.chandef.chan)
+ return;
+
+ ath_scan_channel_start(sc);
+ break;
+ case ATH_OFFCHANNEL_IDLE:
+ if (!sc->offchannel.scan_req)
+ return;
+
+ ath_scan_complete(sc, false);
+ break;
+ case ATH_OFFCHANNEL_ROC_START:
+ if (sc->cur_chan != &sc->offchannel.chan)
+ break;
+
+ sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT;
+ mod_timer(&sc->offchannel.timer, jiffies +
+ msecs_to_jiffies(sc->offchannel.duration));
+ ieee80211_ready_on_channel(sc->hw);
+ break;
+ case ATH_OFFCHANNEL_ROC_DONE:
+ ath_roc_complete(sc, false);
+ break;
+ default:
+ break;
+ }
+}
+
+void ath_offchannel_timer(unsigned long data)
+{
+ struct ath_softc *sc = (struct ath_softc *)data;
+ struct ath_chanctx *ctx;
+
+ switch (sc->offchannel.state) {
+ case ATH_OFFCHANNEL_PROBE_WAIT:
+ if (!sc->offchannel.scan_req)
+ return;
+
+ /* get first active channel context */
+ ctx = ath_chanctx_get_oper_chan(sc, true);
+ if (ctx->active) {
+ sc->offchannel.state = ATH_OFFCHANNEL_SUSPEND;
+ ath_chanctx_switch(sc, ctx, NULL);
+ mod_timer(&sc->offchannel.timer, jiffies + HZ / 10);
+ break;
+ }
+ /* fall through */
+ case ATH_OFFCHANNEL_SUSPEND:
+ if (!sc->offchannel.scan_req)
+ return;
+
+ ath_scan_next_channel(sc);
+ break;
+ case ATH_OFFCHANNEL_ROC_START:
+ case ATH_OFFCHANNEL_ROC_WAIT:
+ ctx = ath_chanctx_get_oper_chan(sc, false);
+ sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE;
+ ath_chanctx_switch(sc, ctx, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_scan_request *hw_req)
+{
+ struct cfg80211_scan_request *req = &hw_req->req;
+ struct ath_softc *sc = hw->priv;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ int ret = 0;
+
+ mutex_lock(&sc->mutex);
+
+ if (WARN_ON(sc->offchannel.scan_req)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ath9k_ps_wakeup(sc);
+ set_bit(ATH_OP_SCANNING, &common->op_flags);
+ sc->offchannel.scan_vif = vif;
+ sc->offchannel.scan_req = req;
+ sc->offchannel.scan_idx = 0;
+
+ if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE)
+ ath_offchannel_next(sc);
+
+out:
+ mutex_unlock(&sc->mutex);
+
+ return ret;
+}
+
+static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct ath_softc *sc = hw->priv;
+
+ mutex_lock(&sc->mutex);
+ del_timer_sync(&sc->offchannel.timer);
+ ath_scan_complete(sc, true);
+ mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_remain_on_channel(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_channel *chan, int duration,
+ enum ieee80211_roc_type type)
+{
+ struct ath_softc *sc = hw->priv;
+ int ret = 0;
+
+ mutex_lock(&sc->mutex);
+
+ if (WARN_ON(sc->offchannel.roc_vif)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ath9k_ps_wakeup(sc);
+ sc->offchannel.roc_vif = vif;
+ sc->offchannel.roc_chan = chan;
+ sc->offchannel.roc_duration = duration;
+
+ if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE)
+ ath_offchannel_next(sc);
+
+out:
+ mutex_unlock(&sc->mutex);
+
+ return ret;
+}
+
+static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw)
+{
+ struct ath_softc *sc = hw->priv;
+
+ mutex_lock(&sc->mutex);
+
+ del_timer_sync(&sc->offchannel.timer);
+
+ if (sc->offchannel.roc_vif) {
+ if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
+ ath_roc_complete(sc, true);
+ }
+
+ mutex_unlock(&sc->mutex);
+
+ return 0;
+}
+
+static int ath9k_add_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *conf)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_chanctx *ctx, **ptr;
+ int pos;
+
+ mutex_lock(&sc->mutex);
+
+ ath_for_each_chanctx(sc, ctx) {
+ if (ctx->assigned)
+ continue;
+
+ ptr = (void *) conf->drv_priv;
+ *ptr = ctx;
+ ctx->assigned = true;
+ pos = ctx - &sc->chanctx[0];
+ ctx->hw_queue_base = pos * IEEE80211_NUM_ACS;
+ ath_chanctx_set_channel(sc, ctx, &conf->def);
+ mutex_unlock(&sc->mutex);
+ return 0;
+ }
+ mutex_unlock(&sc->mutex);
+ return -ENOSPC;
+}
+
+
+static void ath9k_remove_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *conf)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_chanctx *ctx = ath_chanctx_get(conf);
+
+ mutex_lock(&sc->mutex);
+ ctx->assigned = false;
+ ctx->hw_queue_base = -1;
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN);
+ mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_change_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *conf,
+ u32 changed)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_chanctx *ctx = ath_chanctx_get(conf);
+
+ mutex_lock(&sc->mutex);
+ ath_chanctx_set_channel(sc, ctx, &conf->def);
+ mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *conf)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ struct ath_chanctx *ctx = ath_chanctx_get(conf);
+ int i;
+
+ mutex_lock(&sc->mutex);
+ avp->chanctx = ctx;
+ list_add_tail(&avp->list, &ctx->vifs);
+ ath9k_calculate_summary_state(sc, ctx);
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
+ vif->hw_queue[i] = ctx->hw_queue_base + i;
+ mutex_unlock(&sc->mutex);
+
+ return 0;
+}
+
+static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *conf)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+ struct ath_chanctx *ctx = ath_chanctx_get(conf);
+ int ac;
+
+ mutex_lock(&sc->mutex);
+ avp->chanctx = NULL;
+ list_del(&avp->list);
+ ath9k_calculate_summary_state(sc, ctx);
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
+ vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
+ mutex_unlock(&sc->mutex);
+}
+
+void ath9k_fill_chanctx_ops(void)
+{
+ if (!ath9k_use_chanctx)
+ return;
+
+ ath9k_ops.hw_scan = ath9k_hw_scan;
+ ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan;
+ ath9k_ops.remain_on_channel = ath9k_remain_on_channel;
+ ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
+ ath9k_ops.add_chanctx = ath9k_add_chanctx;
+ ath9k_ops.remove_chanctx = ath9k_remove_chanctx;
+ ath9k_ops.change_chanctx = ath9k_change_chanctx;
+ ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx;
+ ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx;
+ ath9k_ops.mgd_prepare_tx = ath9k_chanctx_force_active;
+}
+
struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index a0dbcc412384..3f7a11edb82a 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -706,7 +706,7 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
return;
if (setchannel) {
- struct ath9k_hw_cal_data *caldata = &sc->caldata;
+ struct ath9k_hw_cal_data *caldata = &sc->cur_chan->caldata;
if (IS_CHAN_HT40PLUS(ah->curchan) &&
(ah->curchan->channel > caldata->channel) &&
(ah->curchan->channel <= caldata->channel + 20))
@@ -720,7 +720,7 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
mci_hw->concur_tx = concur_tx;
if (old_concur_tx != mci_hw->concur_tx)
- ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
+ ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
}
static void ath9k_mci_stomp_audio(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 4dec09e565ed..7a2b2c5caced 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -843,6 +843,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV;
}
+ ath9k_fill_chanctx_ops();
hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
if (!hw) {
dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9105a92364f7..74ab1d02013b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -259,7 +259,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP);
ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP);
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+ ath9k_hw_startpcureceive(sc->sc_ah, sc->cur_chan->offchannel);
}
static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -374,6 +374,7 @@ void ath_rx_cleanup(struct ath_softc *sc)
u32 ath_calcrxfilter(struct ath_softc *sc)
{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
u32 rfilt;
if (config_enabled(CONFIG_ATH9K_TX99))
@@ -424,6 +425,10 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah))
rfilt |= ATH9K_RX_FILTER_4ADDRESS;
+ if (ath9k_use_chanctx &&
+ test_bit(ATH_OP_SCANNING, &common->op_flags))
+ rfilt |= ATH9K_RX_FILTER_BEACON;
+
return rfilt;
}
@@ -457,7 +462,7 @@ int ath_startrecv(struct ath_softc *sc)
start_recv:
ath_opmode_init(sc);
- ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+ ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel);
return 0;
}
@@ -540,7 +545,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
sc->ps_flags &= ~PS_BEACON_SYNC;
ath_dbg(common, PS,
"Reconfigure beacon timers based on synchronized timestamp\n");
- if (!(WARN_ON_ONCE(sc->cur_beacon_conf.beacon_interval == 0)))
+ if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0)))
ath9k_set_beacon(sc);
if (sc->p2p_ps_vif)
ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
@@ -887,6 +892,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
return -EINVAL;
}
+ if (rx_stats->is_mybeacon) {
+ sc->sched.next_tbtt = rx_stats->rs_tstamp;
+ ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_BEACON_RECEIVED);
+ }
+
ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status);
rx_status->band = ah->curchan->chan->band;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index f1bbce3f7774..a1499700bcf2 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -813,6 +813,7 @@
#define AR_SREV_VERSION_9531 0x500
#define AR_SREV_REVISION_9531_10 0
#define AR_SREV_REVISION_9531_11 1
+#define AR_SREV_REVISION_9531_20 2
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -958,6 +959,9 @@
#define AR_SREV_9531_11(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_11))
+#define AR_SREV_9531_20(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20))
/* NOTE: When adding chips newer than Peacock, add chip check here */
#define AR_SREV_9580_10_OR_LATER(_ah) \
diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c
index 99f4de95c264..5fe29b9f8fa2 100644
--- a/drivers/net/wireless/ath/ath9k/spectral.c
+++ b/drivers/net/wireless/ath/ath9k/spectral.c
@@ -313,7 +313,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file,
if (kstrtoul(buf, 0, &val))
return -EINVAL;
- if (val < 0 || val > 1)
+ if (val > 1)
return -EINVAL;
sc->spec_config.short_repeat = val;
@@ -361,7 +361,7 @@ static ssize_t write_file_spectral_count(struct file *file,
if (kstrtoul(buf, 0, &val))
return -EINVAL;
- if (val < 0 || val > 255)
+ if (val > 255)
return -EINVAL;
sc->spec_config.count = val;
@@ -409,7 +409,7 @@ static ssize_t write_file_spectral_period(struct file *file,
if (kstrtoul(buf, 0, &val))
return -EINVAL;
- if (val < 0 || val > 255)
+ if (val > 255)
return -EINVAL;
sc->spec_config.period = val;
@@ -457,7 +457,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file,
if (kstrtoul(buf, 0, &val))
return -EINVAL;
- if (val < 0 || val > 15)
+ if (val > 15)
return -EINVAL;
sc->spec_config.fft_period = val;
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index a65cfb91adca..23972924c774 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -76,7 +76,7 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
tx_info = IEEE80211_SKB_CB(skb);
memset(tx_info, 0, sizeof(*tx_info));
rate = &tx_info->control.rates[0];
- tx_info->band = hw->conf.chandef.chan->band;
+ tx_info->band = sc->cur_chan->chandef.chan->band;
tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
tx_info->control.vif = sc->tx99_vif;
rate->count = 1;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 2879887f5691..a4f4f0da81f6 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -193,6 +193,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
u32 wow_triggers_enabled = 0;
int ret = 0;
+ cancel_work_sync(&sc->chanctx_work);
mutex_lock(&sc->mutex);
ath_cancel_work(sc);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 66acb2cbd9df..704fcbcbe20b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -103,9 +103,16 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
ieee80211_tx_status(sc->hw, skb);
}
-static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
+static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
{
struct ath_atx_ac *ac = tid->ac;
+ struct list_head *list;
+ struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
+ struct ath_chanctx *ctx = avp->chanctx;
+
+ if (!ctx)
+ return;
if (tid->sched)
return;
@@ -117,7 +124,9 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
return;
ac->sched = true;
- list_add_tail(&ac->list, &txq->axq_acq);
+
+ list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
+ list_add_tail(&ac->list, list);
}
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -147,21 +156,22 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
struct sk_buff *skb)
{
- int q;
-
- q = skb_get_queue_mapping(skb);
- if (txq == sc->tx.uapsdq)
- txq = sc->tx.txq_map[q];
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath_frame_info *fi = get_frame_info(skb);
+ int hw_queue;
+ int q = fi->txq;
- if (txq != sc->tx.txq_map[q])
+ if (q < 0)
return;
+ txq = sc->tx.txq_map[q];
if (WARN_ON(--txq->pending_frames < 0))
txq->pending_frames = 0;
+ hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
if (txq->stopped &&
txq->pending_frames < sc->tx.txq_max_pending[q]) {
- ieee80211_wake_queue(sc->hw, q);
+ ieee80211_wake_queue(sc->hw, hw_queue);
txq->stopped = false;
}
}
@@ -626,7 +636,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
skb_queue_splice_tail(&bf_pending, &tid->retry_q);
if (!an->sleeping) {
- ath_tx_queue_tid(txq, tid);
+ ath_tx_queue_tid(sc, txq, tid);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
tid->ac->clear_ps_filter = true;
@@ -887,6 +897,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
tx_info = IEEE80211_SKB_CB(skb);
tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
+ /*
+ * No aggregation session is running, but there may be frames
+ * from a previous session or a failed attempt in the queue.
+ * Send them out as normal data frames
+ */
+ if (!tid->active)
+ tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+
if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
bf->bf_state.bf_type = 0;
return bf;
@@ -1483,7 +1502,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
ac->clear_ps_filter = true;
if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(txq, tid);
+ ath_tx_queue_tid(sc, txq, tid);
ath_txq_schedule(sc, txq);
}
@@ -1507,7 +1526,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(txq, tid);
+ ath_tx_queue_tid(sc, txq, tid);
ath_txq_schedule(sc, txq);
}
@@ -1642,7 +1661,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
txq->axq_link = NULL;
__skb_queue_head_init(&txq->complete_q);
INIT_LIST_HEAD(&txq->axq_q);
- INIT_LIST_HEAD(&txq->axq_acq);
spin_lock_init(&txq->axq_lock);
txq->axq_depth = 0;
txq->axq_ampdu_depth = 0;
@@ -1686,7 +1704,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
int ath_cabq_update(struct ath_softc *sc)
{
struct ath9k_tx_queue_info qi;
- struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+ struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
int qnum = sc->beacon.cabq->axq_qnum;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
@@ -1804,7 +1822,7 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
}
-/* For each axq_acq entry, for each tid, try to schedule packets
+/* For each acq entry, for each tid, try to schedule packets
* for transmit until ampdu_depth has reached min Q depth.
*/
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
@@ -1812,19 +1830,31 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_atx_ac *ac, *last_ac;
struct ath_atx_tid *tid, *last_tid;
+ struct list_head *ac_list;
bool sent = false;
+ if (txq->mac80211_qnum < 0)
+ return;
+
+ spin_lock_bh(&sc->chan_lock);
+ ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
+ spin_unlock_bh(&sc->chan_lock);
+
if (test_bit(ATH_OP_HW_RESET, &common->op_flags) ||
- list_empty(&txq->axq_acq))
+ list_empty(ac_list))
return;
+ spin_lock_bh(&sc->chan_lock);
rcu_read_lock();
- last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
- while (!list_empty(&txq->axq_acq)) {
+ last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
+ while (!list_empty(ac_list)) {
bool stop = false;
- ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+ if (sc->cur_chan->stopped)
+ break;
+
+ ac = list_first_entry(ac_list, struct ath_atx_ac, list);
last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
list_del(&ac->list);
ac->sched = false;
@@ -1844,7 +1874,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
* are pending for the tid
*/
if (ath_tid_has_buffered(tid))
- ath_tx_queue_tid(txq, tid);
+ ath_tx_queue_tid(sc, txq, tid);
if (stop || tid == last_tid)
break;
@@ -1852,7 +1882,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
if (!list_empty(&ac->tid_q) && !ac->sched) {
ac->sched = true;
- list_add_tail(&ac->list, &txq->axq_acq);
+ list_add_tail(&ac->list, ac_list);
}
if (stop)
@@ -1863,12 +1893,27 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
break;
sent = false;
- last_ac = list_entry(txq->axq_acq.prev,
+ last_ac = list_entry(ac_list->prev,
struct ath_atx_ac, list);
}
}
rcu_read_unlock();
+ spin_unlock_bh(&sc->chan_lock);
+}
+
+void ath_txq_schedule_all(struct ath_softc *sc)
+{
+ struct ath_txq *txq;
+ int i;
+
+ for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ txq = sc->tx.txq_map[i];
+
+ spin_lock_bh(&txq->axq_lock);
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
+ }
}
/***********/
@@ -1999,6 +2044,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
an = (struct ath_node *) sta->drv_priv;
memset(fi, 0, sizeof(*fi));
+ fi->txq = -1;
if (hw_key)
fi->keyix = hw_key->hw_key_idx;
else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
@@ -2150,13 +2196,22 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = txctl->sta;
struct ieee80211_vif *vif = info->control.vif;
+ struct ath_frame_info *fi = get_frame_info(skb);
+ struct ath_vif *avp = NULL;
struct ath_softc *sc = hw->priv;
struct ath_txq *txq = txctl->txq;
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf;
- int q;
+ bool queue;
+ int q, hw_queue;
int ret;
+ if (vif)
+ avp = (void *)vif->drv_priv;
+
+ if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
+ txctl->force_channel = true;
+
ret = ath_tx_prepare(hw, skb, txctl);
if (ret)
return ret;
@@ -2168,24 +2223,41 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
*/
q = skb_get_queue_mapping(skb);
+ hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
ath_txq_lock(sc, txq);
- if (txq == sc->tx.txq_map[q] &&
- ++txq->pending_frames > sc->tx.txq_max_pending[q] &&
- !txq->stopped) {
- ieee80211_stop_queue(sc->hw, q);
- txq->stopped = true;
+ if (txq == sc->tx.txq_map[q]) {
+ fi->txq = q;
+ if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
+ !txq->stopped) {
+ ieee80211_stop_queue(sc->hw, hw_queue);
+ txq->stopped = true;
+ }
+ }
+
+ queue = ieee80211_is_data_present(hdr->frame_control);
+
+ /* Force queueing of all frames that belong to a virtual interface on
+ * a different channel context, to ensure that they are sent on the
+ * correct channel.
+ */
+ if (((avp && avp->chanctx != sc->cur_chan) ||
+ sc->cur_chan->stopped) && !txctl->force_channel) {
+ if (!txctl->an)
+ txctl->an = &avp->mcast_node;
+ info->flags &= ~IEEE80211_TX_CTL_PS_RESPONSE;
+ queue = true;
}
- if (txctl->an && ieee80211_is_data_present(hdr->frame_control))
+ if (txctl->an && queue)
tid = ath_get_skb_tid(sc, txctl->an, skb);
- if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
+ if (info->flags & (IEEE80211_TX_CTL_PS_RESPONSE |
+ IEEE80211_TX_CTL_TX_OFFCHAN)) {
ath_txq_unlock(sc, txq);
txq = sc->tx.uapsdq;
ath_txq_lock(sc, txq);
- } else if (txctl->an &&
- ieee80211_is_data_present(hdr->frame_control)) {
+ } else if (txctl->an && queue) {
WARN_ON(tid->ac->txq != txctl->txq);
if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
@@ -2198,7 +2270,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
TX_STAT_INC(txq->axq_qnum, a_queued_sw);
__skb_queue_tail(&tid->buf_q, skb);
if (!txctl->an->sleeping)
- ath_tx_queue_tid(txq, tid);
+ ath_tx_queue_tid(sc, txq, tid);
ath_txq_schedule(sc, txq);
goto out;
@@ -2244,8 +2316,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int max_duration;
max_duration =
- sc->cur_beacon_conf.beacon_interval * 1000 *
- sc->cur_beacon_conf.dtim_period / ATH_BCBUF;
+ sc->cur_chan->beacon.beacon_interval * 1000 *
+ sc->cur_chan->beacon.dtim_period / ATH_BCBUF;
do {
struct ath_frame_info *fi = get_frame_info(skb);
@@ -2560,6 +2632,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
sc->beacon.tx_processed = true;
sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
+ ath_chanctx_event(sc, NULL,
+ ATH_CHANCTX_EVENT_BEACON_SENT);
ath9k_csa_update(sc);
continue;
}
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index ab4ee7d39ad3..b80b2138ce3c 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1139,7 +1139,6 @@ static int carl9170_set_freq_cal_data(struct ar9170 *ar,
default:
return -EINVAL;
- break;
}
for (; i >= 0; i--) {
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 4ab5370ab7a6..b71d2b33532d 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -488,7 +488,6 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
wcn36xx_err("Unsupported key cmd 0x%x\n", cmd);
ret = -EOPNOTSUPP;
goto out;
- break;
}
out:
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 820d4ebd9322..4ac2c208c9ba 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -104,8 +104,8 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
return -EOPNOTSUPP;
}
-static int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
- struct station_info *sinfo)
+int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
+ struct station_info *sinfo)
{
struct wmi_notify_req_cmd cmd = {
.cid = cid,
@@ -287,6 +287,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
return -EBUSY;
}
+ wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
wil->scan_request = request;
mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
@@ -443,15 +444,15 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
return rc;
}
-static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- struct cfg80211_mgmt_tx_params *params,
- u64 *cookie)
+int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie)
{
const u8 *buf = params->buf;
size_t len = params->len;
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
int rc;
+ bool tx_status = false;
struct ieee80211_mgmt *mgmt_frame = (void *)buf;
struct wmi_sw_tx_req_cmd *cmd;
struct {
@@ -460,8 +461,10 @@ static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
} __packed evt;
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
- if (!cmd)
- return -ENOMEM;
+ if (!cmd) {
+ rc = -ENOMEM;
+ goto out;
+ }
memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
cmd->len = cpu_to_le16(len);
@@ -470,10 +473,12 @@ static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
if (rc == 0)
- rc = evt.evt.status;
+ tx_status = !evt.evt.status;
kfree(cmd);
-
+ out:
+ cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
+ tx_status, GFP_KERNEL);
return rc;
}
@@ -562,6 +567,34 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
return rc;
}
+static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
+{
+ print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
+ b->head, b->head_len);
+ print_hex_dump_bytes("tail ", DUMP_PREFIX_OFFSET,
+ b->tail, b->tail_len);
+ print_hex_dump_bytes("BCON IE ", DUMP_PREFIX_OFFSET,
+ b->beacon_ies, b->beacon_ies_len);
+ print_hex_dump_bytes("PROBE ", DUMP_PREFIX_OFFSET,
+ b->probe_resp, b->probe_resp_len);
+ print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
+ b->proberesp_ies, b->proberesp_ies_len);
+ print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
+ b->assocresp_ies, b->assocresp_ies_len);
+}
+
+static void wil_print_crypto(struct wil6210_priv *wil,
+ struct cfg80211_crypto_settings *c)
+{
+ wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
+ c->wpa_versions, c->cipher_group);
+ wil_dbg_misc(wil, "Pairwise ciphers [%d]\n", c->n_ciphers_pairwise);
+ wil_dbg_misc(wil, "AKM suites [%d]\n", c->n_akm_suites);
+ wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
+ c->control_port, be16_to_cpu(c->control_port_ethertype),
+ c->control_port_no_encrypt);
+}
+
static int wil_fix_bcon(struct wil6210_priv *wil,
struct cfg80211_beacon_data *bcon)
{
@@ -595,8 +628,11 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
struct wireless_dev *wdev = ndev->ieee80211_ptr;
struct ieee80211_channel *channel = info->chandef.chan;
struct cfg80211_beacon_data *bcon = &info->beacon;
+ struct cfg80211_crypto_settings *crypto = &info->crypto;
u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
+ wil_dbg_misc(wil, "%s()\n", __func__);
+
if (!channel) {
wil_err(wil, "AP: No channel???\n");
return -EINVAL;
@@ -604,11 +640,19 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
channel->center_freq, info->privacy ? "secure" : "open");
+ wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
+ info->privacy, info->auth_type);
+ wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
+ info->dtim_period);
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
info->ssid, info->ssid_len);
+ wil_print_bcon_data(bcon);
+ wil_print_crypto(wil, crypto);
- if (wil_fix_bcon(wil, bcon))
+ if (wil_fix_bcon(wil, bcon)) {
wil_dbg_misc(wil, "Fixed bcon\n");
+ wil_print_bcon_data(bcon);
+ }
mutex_lock(&wil->mutex);
@@ -663,6 +707,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
int rc = 0;
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+ wil_dbg_misc(wil, "%s()\n", __func__);
+
mutex_lock(&wil->mutex);
rc = wmi_pcp_stop(wil);
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 8d4bc4bfb664..8f66186adb8c 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -19,6 +19,7 @@
#include <linux/seq_file.h>
#include <linux/pci.h>
#include <linux/rtnetlink.h>
+#include <linux/power_supply.h>
#include "wil6210.h"
#include "txrx.h"
@@ -69,14 +70,32 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
struct vring *vring = &(wil->vring_tx[i]);
+ struct vring_tx_data *txdata = &wil->vring_tx_data[i];
+
if (vring->va) {
int cid = wil->vring2cid_tid[i][0];
int tid = wil->vring2cid_tid[i][1];
+ u32 swhead = vring->swhead;
+ u32 swtail = vring->swtail;
+ int used = (vring->size + swhead - swtail)
+ % vring->size;
+ int avail = vring->size - used - 1;
char name[10];
+ /* performance monitoring */
+ cycles_t now = get_cycles();
+ cycles_t idle = txdata->idle * 100;
+ cycles_t total = now - txdata->begin;
+
+ do_div(idle, total);
+ txdata->begin = now;
+ txdata->idle = 0ULL;
+
snprintf(name, sizeof(name), "tx_%2d", i);
- seq_printf(s, "\n%pM CID %d TID %d\n",
- wil->sta[cid].addr, cid, tid);
+ seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n",
+ wil->sta[cid].addr, cid, tid, used, avail,
+ (int)idle);
+
wil_print_vring(s, wil, name, vring, '_', 'H');
}
}
@@ -231,6 +250,26 @@ static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
&fops_iomem_x32);
}
+static int wil_debugfs_ulong_set(void *data, u64 val)
+{
+ *(ulong *)data = val;
+ return 0;
+}
+static int wil_debugfs_ulong_get(void *data, u64 *val)
+{
+ *val = *(ulong *)data;
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
+ wil_debugfs_ulong_set, "%llu\n");
+
+static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode,
+ struct dentry *parent,
+ ulong *value)
+{
+ return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong);
+}
+
static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
const char *name,
struct dentry *parent, u32 off)
@@ -284,11 +323,11 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
if (IS_ERR_OR_NULL(d))
return -ENODEV;
- wil_debugfs_create_iomem_x32("TRSH", S_IRUGO, d, wil->csr +
+ wil_debugfs_create_iomem_x32("TRSH", S_IRUGO | S_IWUSR, d, wil->csr +
HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
- wil_debugfs_create_iomem_x32("DATA", S_IRUGO, d, wil->csr +
+ wil_debugfs_create_iomem_x32("DATA", S_IRUGO | S_IWUSR, d, wil->csr +
HOSTADDR(RGF_DMA_ITR_CNT_DATA));
- wil_debugfs_create_iomem_x32("CTL", S_IRUGO, d, wil->csr +
+ wil_debugfs_create_iomem_x32("CTL", S_IRUGO | S_IWUSR, d, wil->csr +
HOSTADDR(RGF_DMA_ITR_CNT_CRL));
return 0;
@@ -397,6 +436,126 @@ static const struct file_operations fops_reset = {
.write = wil_write_file_reset,
.open = simple_open,
};
+/*---write channel 1..4 to rxon for it, 0 to rxoff---*/
+static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct wil6210_priv *wil = file->private_data;
+ int rc;
+ long channel;
+ bool on;
+
+ char *kbuf = kmalloc(len + 1, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ if (copy_from_user(kbuf, buf, len)) {
+ kfree(kbuf);
+ return -EIO;
+ }
+
+ kbuf[len] = '\0';
+ rc = kstrtol(kbuf, 0, &channel);
+ kfree(kbuf);
+ if (rc)
+ return rc;
+
+ if ((channel < 0) || (channel > 4)) {
+ wil_err(wil, "Invalid channel %ld\n", channel);
+ return -EINVAL;
+ }
+ on = !!channel;
+
+ if (on) {
+ rc = wmi_set_channel(wil, (int)channel);
+ if (rc)
+ return rc;
+ }
+
+ rc = wmi_rxon(wil, on);
+ if (rc)
+ return rc;
+
+ return len;
+}
+
+static const struct file_operations fops_rxon = {
+ .write = wil_write_file_rxon,
+ .open = simple_open,
+};
+/*---tx_mgmt---*/
+/* Write mgmt frame to this file to send it */
+static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct wil6210_priv *wil = file->private_data;
+ struct wiphy *wiphy = wil_to_wiphy(wil);
+ struct wireless_dev *wdev = wil_to_wdev(wil);
+ struct cfg80211_mgmt_tx_params params;
+ int rc;
+
+ void *frame = kmalloc(len, GFP_KERNEL);
+ if (!frame)
+ return -ENOMEM;
+
+ if (copy_from_user(frame, buf, len))
+ return -EIO;
+
+ params.buf = frame;
+ params.len = len;
+ params.chan = wdev->preset_chandef.chan;
+
+ rc = wil_cfg80211_mgmt_tx(wiphy, wdev, &params, NULL);
+
+ kfree(frame);
+ wil_info(wil, "%s() -> %d\n", __func__, rc);
+
+ return len;
+}
+
+static const struct file_operations fops_txmgmt = {
+ .write = wil_write_file_txmgmt,
+ .open = simple_open,
+};
+
+/* Write WMI command (w/o mbox header) to this file to send it
+ * WMI starts from wil6210_mbox_hdr_wmi header
+ */
+static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct wil6210_priv *wil = file->private_data;
+ struct wil6210_mbox_hdr_wmi *wmi;
+ void *cmd;
+ int cmdlen = len - sizeof(struct wil6210_mbox_hdr_wmi);
+ u16 cmdid;
+ int rc, rc1;
+
+ if (cmdlen <= 0)
+ return -EINVAL;
+
+ wmi = kmalloc(len, GFP_KERNEL);
+ if (!wmi)
+ return -ENOMEM;
+
+ rc = simple_write_to_buffer(wmi, len, ppos, buf, len);
+ if (rc < 0)
+ return rc;
+
+ cmd = &wmi[1];
+ cmdid = le16_to_cpu(wmi->id);
+
+ rc1 = wmi_send(wil, cmdid, cmd, cmdlen);
+ kfree(wmi);
+
+ wil_info(wil, "%s(0x%04x[%d]) -> %d\n", __func__, cmdid, cmdlen, rc1);
+
+ return rc;
+}
+
+static const struct file_operations fops_wmi = {
+ .write = wil_write_file_wmi,
+ .open = simple_open,
+};
static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
const char *prefix)
@@ -600,8 +759,8 @@ static int wil_temp_debugfs_show(struct seq_file *s, void *data)
return 0;
}
- print_temp(s, "MAC temperature :", t_m);
- print_temp(s, "Radio temperature :", t_r);
+ print_temp(s, "T_mac =", t_m);
+ print_temp(s, "T_radio =", t_r);
return 0;
}
@@ -618,6 +777,130 @@ static const struct file_operations fops_temp = {
.llseek = seq_lseek,
};
+/*---------freq------------*/
+static int wil_freq_debugfs_show(struct seq_file *s, void *data)
+{
+ struct wil6210_priv *wil = s->private;
+ struct wireless_dev *wdev = wil_to_wdev(wil);
+ u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
+
+ seq_printf(s, "Freq = %d\n", freq);
+
+ return 0;
+}
+
+static int wil_freq_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wil_freq_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations fops_freq = {
+ .open = wil_freq_seq_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+
+/*---------link------------*/
+static int wil_link_debugfs_show(struct seq_file *s, void *data)
+{
+ struct wil6210_priv *wil = s->private;
+ struct station_info sinfo;
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ struct wil_sta_info *p = &wil->sta[i];
+ char *status = "unknown";
+ switch (p->status) {
+ case wil_sta_unused:
+ status = "unused ";
+ break;
+ case wil_sta_conn_pending:
+ status = "pending ";
+ break;
+ case wil_sta_connected:
+ status = "connected";
+ break;
+ }
+ seq_printf(s, "[%d] %pM %s%s\n", i, p->addr, status,
+ (p->data_port_open ? " data_port_open" : ""));
+
+ if (p->status == wil_sta_connected) {
+ rc = wil_cid_fill_sinfo(wil, i, &sinfo);
+ if (rc)
+ return rc;
+
+ seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs);
+ seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs);
+ seq_printf(s, " SQ = %d\n", sinfo.signal);
+ }
+ }
+
+ return 0;
+}
+
+static int wil_link_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wil_link_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations fops_link = {
+ .open = wil_link_seq_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+
+/*---------info------------*/
+static int wil_info_debugfs_show(struct seq_file *s, void *data)
+{
+ struct wil6210_priv *wil = s->private;
+ struct net_device *ndev = wil_to_ndev(wil);
+ int is_ac = power_supply_is_system_supplied();
+ int rx = atomic_xchg(&wil->isr_count_rx, 0);
+ int tx = atomic_xchg(&wil->isr_count_tx, 0);
+ static ulong rxf_old, txf_old;
+ ulong rxf = ndev->stats.rx_packets;
+ ulong txf = ndev->stats.tx_packets;
+ unsigned int i;
+
+ /* >0 : AC; 0 : battery; <0 : error */
+ seq_printf(s, "AC powered : %d\n", is_ac);
+ seq_printf(s, "Rx irqs:packets : %8d : %8ld\n", rx, rxf - rxf_old);
+ seq_printf(s, "Tx irqs:packets : %8d : %8ld\n", tx, txf - txf_old);
+ rxf_old = rxf;
+ txf_old = txf;
+
+
+#define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \
+ " " __stringify(x) : ""
+
+ for (i = 0; i < ndev->num_tx_queues; i++) {
+ struct netdev_queue *txq = netdev_get_tx_queue(ndev, i);
+ unsigned long state = txq->state;
+
+ seq_printf(s, "Tx queue[%i] state : 0x%lx%s%s%s\n", i, state,
+ CHECK_QSTATE(DRV_XOFF),
+ CHECK_QSTATE(STACK_XOFF),
+ CHECK_QSTATE(FROZEN)
+ );
+ }
+#undef CHECK_QSTATE
+ return 0;
+}
+
+static int wil_info_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, wil_info_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations fops_info = {
+ .open = wil_info_seq_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+
/*---------Station matrix------------*/
static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
{
@@ -630,7 +913,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
else
seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_');
}
- seq_puts(s, "]\n");
+ seq_printf(s, "] last drop 0x%03x\n", r->ssn_last_drop);
}
static int wil_sta_debugfs_show(struct seq_file *s, void *data)
@@ -682,6 +965,26 @@ static const struct file_operations fops_sta = {
};
/*----------------*/
+static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
+ struct dentry *dbg)
+{
+ int i;
+ char name[32];
+
+ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
+ struct debugfs_blob_wrapper *blob = &wil->blobs[i];
+ const struct fw_map *map = &fw_mapping[i];
+
+ if (!map->name)
+ continue;
+
+ blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
+ blob->size = map->to - map->from;
+ snprintf(name, sizeof(name), "blob_%s", map->name);
+ wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob);
+ }
+}
+
int wil6210_debugfs_init(struct wil6210_priv *wil)
{
struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
@@ -703,6 +1006,10 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid);
debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg,
&wil->secure_pcp);
+ wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg,
+ &wil->status);
+ debugfs_create_u32("fw_version", S_IRUGO, dbg, &wil->fw_version);
+ debugfs_create_x32("hw_version", S_IRUGO, dbg, &wil->hw_version);
wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg,
HOSTADDR(RGF_USER_USER_ICR));
@@ -715,40 +1022,22 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
wil6210_debugfs_create_pseudo_ISR(wil, dbg);
wil6210_debugfs_create_ITR_CNT(wil, dbg);
+ wil_debugfs_create_iomem_x32("RGF_USER_USAGE_1", S_IRUGO, dbg,
+ wil->csr +
+ HOSTADDR(RGF_USER_USAGE_1));
debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr);
debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset);
+ debugfs_create_file("rxon", S_IWUSR, dbg, wil, &fops_rxon);
+ debugfs_create_file("tx_mgmt", S_IWUSR, dbg, wil, &fops_txmgmt);
+ debugfs_create_file("wmi_send", S_IWUSR, dbg, wil, &fops_wmi);
debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp);
+ debugfs_create_file("freq", S_IRUGO, dbg, wil, &fops_freq);
+ debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link);
+ debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info);
- wil->rgf_blob.data = (void * __force)wil->csr + 0;
- wil->rgf_blob.size = 0xa000;
- wil_debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob);
-
- wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000;
- wil->fw_code_blob.size = 0x40000;
- wil_debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg,
- &wil->fw_code_blob);
-
- wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000;
- wil->fw_data_blob.size = 0x8000;
- wil_debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg,
- &wil->fw_data_blob);
-
- wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000;
- wil->fw_peri_blob.size = 0x18000;
- wil_debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg,
- &wil->fw_peri_blob);
-
- wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000;
- wil->uc_code_blob.size = 0x10000;
- wil_debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg,
- &wil->uc_code_blob);
-
- wil->uc_data_blob.data = (void * __force)wil->csr + 0xb0000;
- wil->uc_data_blob.size = 0x4000;
- wil_debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg,
- &wil->uc_data_blob);
+ wil6210_debugfs_init_blobs(wil, dbg);
return 0;
}
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 73593aa3cd98..67f1002a03a1 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -208,6 +208,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
/* Rx IRQ will be enabled when NAPI processing finished */
+ atomic_inc(&wil->isr_count_rx);
return IRQ_HANDLED;
}
@@ -246,6 +247,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
/* Tx IRQ will be enabled when NAPI processing finished */
+ atomic_inc(&wil->isr_count_tx);
return IRQ_HANDLED;
}
@@ -257,6 +259,7 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
[1] = "EVENT=FW_ERROR",
[2] = NULL,
};
+ wil_err(wil, "Notify about firmware error\n");
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 11e6d9d22eae..3704d2a434f3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -61,11 +61,24 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
{
uint i;
+ struct net_device *ndev = wil_to_ndev(wil);
+ struct wireless_dev *wdev = wil->wdev;
struct wil_sta_info *sta = &wil->sta[cid];
+ wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
+ sta->status);
sta->data_port_open = false;
if (sta->status != wil_sta_unused) {
wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING);
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ /* AP-like interface */
+ cfg80211_del_sta(ndev, sta->addr, GFP_KERNEL);
+ break;
+ default:
+ break;
+ }
sta->status = wil_sta_unused;
}
@@ -119,11 +132,6 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid)
clear_bit(wil_status_fwconnecting, &wil->status);
break;
default:
- /* AP-like interface and monitor:
- * never scan, always connected
- */
- if (bssid)
- cfg80211_del_sta(ndev, bssid, GFP_KERNEL);
break;
}
}
@@ -306,8 +314,9 @@ static void wil_target_reset(struct wil6210_priv *wil)
int delay = 0;
u32 hw_state;
u32 rev_id;
+ bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW);
- wil_dbg_misc(wil, "Resetting...\n");
+ wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name);
/* register read */
#define R(a) ioread32(wil->csr + HOSTADDR(a))
@@ -320,35 +329,59 @@ static void wil_target_reset(struct wil6210_priv *wil)
wil->hw_version = R(RGF_USER_FW_REV_ID);
rev_id = wil->hw_version & 0xff;
+
+ /* Clear MAC link up */
+ S(RGF_HP_CTRL, BIT(15));
/* hpal_perst_from_pad_src_n_mask */
S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6));
/* car_perst_rst_src_n_mask */
S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7));
wmb(); /* order is important here */
+ if (is_sparrow) {
+ W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
+ wmb(); /* order is important here */
+ }
+
W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
wmb(); /* order is important here */
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
- W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000B0 : 0x00000170);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
wmb(); /* order is important here */
+ if (is_sparrow) {
+ W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
+ wmb(); /* order is important here */
+ }
+
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
wmb(); /* order is important here */
- W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
- if (rev_id == 1) {
- W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
- } else {
- W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
+ if (is_sparrow) {
+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
+ /* reset A2 PCIE AHB */
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
+
+ } else {
+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
+ if (rev_id == 1) {
+ /* reset A1 BOTH PCIE AHB & PCIE RGF */
+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
+ } else {
+ W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
+ W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
+ }
+
}
+
+ /* TODO: check order here!!! Erez code is different */
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
wmb(); /* order is important here */
@@ -363,7 +396,8 @@ static void wil_target_reset(struct wil6210_priv *wil)
}
} while (hw_state != HW_MACHINE_BOOT_DONE);
- if (rev_id == 2)
+ /* TODO: Erez check rev_id != 1 */
+ if (!is_sparrow && (rev_id != 1))
W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
@@ -465,6 +499,7 @@ void wil_link_on(struct wil6210_priv *wil)
wil_dbg_misc(wil, "%s()\n", __func__);
netif_carrier_on(ndev);
+ wil_dbg_misc(wil, "netif_tx_wake : link on\n");
netif_tx_wake_all_queues(ndev);
}
@@ -475,6 +510,7 @@ void wil_link_off(struct wil6210_priv *wil)
wil_dbg_misc(wil, "%s()\n", __func__);
netif_tx_stop_all_queues(ndev);
+ wil_dbg_misc(wil, "netif_tx_stop : link off\n");
netif_carrier_off(ndev);
}
@@ -552,6 +588,8 @@ static int __wil_down(struct wil6210_priv *wil)
napi_disable(&wil->napi_tx);
if (wil->scan_request) {
+ wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
+ wil->scan_request);
del_timer_sync(&wil->scan_timer);
cfg80211_scan_done(wil->scan_request, true);
wil->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 106b6dcb773a..7afce6e8c507 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -132,7 +132,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
- ndev = alloc_netdev(0, "wlan%d", ether_setup);
+ ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup);
if (!ndev) {
dev_err(dev, "alloc_netdev_mqs failed\n");
rc = -ENOMEM;
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 1e2e07b9d13d..d3fbfa28db62 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -15,7 +15,6 @@
*/
#include <linux/module.h>
-#include <linux/debugfs.h>
#include <linux/pci.h>
#include <linux/moduleparam.h>
@@ -27,11 +26,22 @@ MODULE_PARM_DESC(use_msi,
" Use MSI interrupt: "
"0 - don't, 1 - (default) - single, or 3");
+static bool debug_fw; /* = false; */
+module_param(debug_fw, bool, S_IRUGO);
+MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug");
+
/* Bus ops */
static int wil_if_pcie_enable(struct wil6210_priv *wil)
{
struct pci_dev *pdev = wil->pdev;
int rc;
+ /* on platforms with buggy ACPI, pdev->msi_enabled may be set to
+ * allow pci_enable_device to work. This indicates INTx was not routed
+ * and only MSI should be used
+ */
+ int msi_only = pdev->msi_enabled;
+
+ pdev->msi_enabled = 0;
pci_set_master(pdev);
@@ -63,6 +73,12 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
wil->n_msi = use_msi;
+ if ((wil->n_msi == 0) && msi_only) {
+ wil_err(wil, "Interrupt pin not routed, unable to use INTx\n");
+ rc = -ENODEV;
+ goto stop_master;
+ }
+
rc = wil6210_init_irq(wil, pdev->irq);
if (rc)
goto stop_master;
@@ -71,6 +87,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
mutex_lock(&wil->mutex);
rc = wil_reset(wil);
mutex_unlock(&wil->mutex);
+ if (debug_fw)
+ rc = 0;
if (rc)
goto release_irq;
@@ -104,10 +122,12 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct wil6210_priv *wil;
struct device *dev = &pdev->dev;
void __iomem *csr;
+ struct wil_board *board = (struct wil_board *)id->driver_data;
int rc;
/* check HW */
- dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n",
+ dev_info(&pdev->dev, WIL_NAME
+ " \"%s\" device found [%04x:%04x] (rev %x)\n", board->name,
(int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
@@ -119,9 +139,16 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rc = pci_enable_device(pdev);
if (rc) {
- dev_err(&pdev->dev, "pci_enable_device failed\n");
- return -ENODEV;
+ dev_err(&pdev->dev,
+ "pci_enable_device failed, retry with MSI only\n");
+ /* Work around for platforms that can't allocate IRQ:
+ * retry with MSI only
+ */
+ pdev->msi_enabled = 1;
+ rc = pci_enable_device(pdev);
}
+ if (rc)
+ return -ENODEV;
/* rollback to err_disable_pdev */
rc = pci_request_region(pdev, 0, WIL_NAME);
@@ -150,6 +177,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, wil);
wil->pdev = pdev;
+ wil->board = board;
wil6210_clear_irq(wil);
/* FW should raise IRQ when ready */
@@ -200,8 +228,21 @@ static void wil_pcie_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = {
- { PCI_DEVICE(0x1ae9, 0x0301) },
+static const struct wil_board wil_board_marlon = {
+ .board = WIL_BOARD_MARLON,
+ .name = "marlon",
+};
+
+static const struct wil_board wil_board_sparrow = {
+ .board = WIL_BOARD_SPARROW,
+ .name = "sparrow",
+};
+
+static const struct pci_device_id wil6210_pcie_ids[] = {
+ { PCI_DEVICE(0x1ae9, 0x0301),
+ .driver_data = (kernel_ulong_t)&wil_board_marlon },
+ { PCI_DEVICE(0x1ae9, 0x0310),
+ .driver_data = (kernel_ulong_t)&wil_board_sparrow },
{ /* end: all zeroes */ },
};
MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 747ae1275877..180ca4793904 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -116,6 +116,7 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
/* frame with out of date sequence number */
if (seq_less(seq, r->head_seq_num)) {
+ r->ssn_last_drop = seq;
dev_kfree_skb(skb);
goto out;
}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 0784ef3d4ce2..d3467943d39d 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -525,6 +525,17 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
ndev->stats.rx_bytes += len;
stats->rx_bytes += len;
}
+ {
+ static const char * const gro_res_str[] = {
+ [GRO_MERGED] = "GRO_MERGED",
+ [GRO_MERGED_FREE] = "GRO_MERGED_FREE",
+ [GRO_HELD] = "GRO_HELD",
+ [GRO_NORMAL] = "GRO_NORMAL",
+ [GRO_DROP] = "GRO_DROP",
+ };
+ wil_dbg_txrx(wil, "Rx complete %d bytes => %s,\n",
+ len, gro_res_str[rc]);
+ }
}
/**
@@ -760,7 +771,7 @@ static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
goto found;
}
- wil_err(wil, "Tx while no vrings active?\n");
+ wil_dbg_txrx(wil, "Tx while no vrings active?\n");
return NULL;
@@ -881,6 +892,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
int nr_frags = skb_shinfo(skb)->nr_frags;
uint f = 0;
int vring_index = vring - wil->vring_tx;
+ struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
uint i = swhead;
dma_addr_t pa;
@@ -953,6 +965,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);
+ if (wil_vring_is_empty(vring)) /* performance monitoring */
+ txdata->idle += get_cycles() - txdata->last_idle;
+
/* advance swhead */
wil_vring_advance_head(vring, nr_frags + 1);
wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
@@ -1016,15 +1031,17 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
vring = wil_tx_bcast(wil, skb);
}
if (!vring) {
- wil_err(wil, "No Tx VRING found for %pM\n", eth->h_dest);
+ wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
goto drop;
}
/* set up vring entry */
rc = wil_tx_vring(wil, vring, skb);
/* do we still have enough room in the vring? */
- if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))
+ if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring)) {
netif_tx_stop_all_queues(wil_to_ndev(wil));
+ wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
+ }
switch (rc) {
case 0:
@@ -1091,8 +1108,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
while (vring->swtail != new_swtail) {
struct vring_tx_desc dd, *d = &dd;
u16 dmalen;
- struct wil_ctx *ctx = &vring->ctx[vring->swtail];
- struct sk_buff *skb = ctx->skb;
+ struct sk_buff *skb;
+
+ ctx = &vring->ctx[vring->swtail];
+ skb = ctx->skb;
_d = &vring->va[vring->swtail].tx;
*d = *_d;
@@ -1132,8 +1151,16 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
done++;
}
}
- if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring))
+
+ if (wil_vring_is_empty(vring)) { /* performance monitoring */
+ wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid);
+ txdata->last_idle = get_cycles();
+ }
+
+ if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) {
+ wil_dbg_txrx(wil, "netif_tx_wake : ring not full\n");
netif_tx_wake_all_queues(wil_to_ndev(wil));
+ }
return done;
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index e25edc52398f..67e9624f7111 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -20,9 +20,17 @@
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
+#include <linux/timex.h>
#define WIL_NAME "wil6210"
+struct wil_board {
+ int board;
+#define WIL_BOARD_MARLON (1)
+#define WIL_BOARD_SPARROW (2)
+ const char * const name;
+};
+
/**
* extract bits [@b0:@b1] (inclusive) from the value @x
* it should be @b0 <= @b1, or result is incorrect
@@ -77,6 +85,7 @@ struct RGF_ICR {
} __packed;
/* registers - FW addresses */
+#define RGF_USER_USAGE_1 (0x880004)
#define RGF_USER_HW_MACHINE_STATE (0x8801dc)
#define HW_MACHINE_BOOT_DONE (0x3fffffd)
#define RGF_USER_USER_CPU_0 (0x8801e0)
@@ -92,6 +101,7 @@ struct RGF_ICR {
#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
#define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
+#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18)
#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
#define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
@@ -120,6 +130,7 @@ struct RGF_ICR {
#define BIT_DMA_PSEUDO_CAUSE_TX BIT(1)
#define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2)
+#define RGF_HP_CTRL (0x88265c)
#define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4)
/* popular locations */
@@ -134,6 +145,14 @@ struct RGF_ICR {
#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3)
/* Hardware definitions end */
+struct fw_map {
+ u32 from; /* linker address - from, inclusive */
+ u32 to; /* linker address - to, exclusive */
+ u32 host; /* PCI/Host address - BAR0 + 0x880000 */
+ const char *name; /* for debugfs */
+};
+/* array size should be in sync with actual definition in the wmi.c */
+extern const struct fw_map fw_mapping[7];
/**
* mk_cidxtid - construct @cidxtid field
@@ -251,7 +270,7 @@ struct vring {
*/
struct vring_tx_data {
int enabled;
-
+ cycles_t idle, last_idle, begin;
};
enum { /* for wil6210_priv.status */
@@ -303,6 +322,7 @@ struct wil_tid_ampdu_rx {
u16 ssn;
u16 buf_size;
u16 timeout;
+ u16 ssn_last_drop;
u8 dialog_token;
bool first_time; /* is it 1-st time this buffer used? */
};
@@ -363,6 +383,7 @@ struct wil6210_priv {
ulong status;
u32 fw_version;
u32 hw_version;
+ struct wil_board *board;
u8 n_mids; /* number of additional MIDs as reported by FW */
int recovery_count; /* num of FW recovery attempts in a short time */
unsigned long last_fw_recovery; /* jiffies of last fw recovery */
@@ -410,14 +431,10 @@ struct wil6210_priv {
struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
/* statistics */
struct wil6210_stats stats;
+ atomic_t isr_count_rx, isr_count_tx;
/* debugfs */
struct dentry *debug;
- struct debugfs_blob_wrapper fw_code_blob;
- struct debugfs_blob_wrapper fw_data_blob;
- struct debugfs_blob_wrapper fw_peri_blob;
- struct debugfs_blob_wrapper uc_code_blob;
- struct debugfs_blob_wrapper uc_data_blob;
- struct debugfs_blob_wrapper rgf_blob;
+ struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
};
#define wil_to_wiphy(i) (i->wdev->wiphy)
@@ -504,9 +521,14 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq);
void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
void wil6210_disable_irq(struct wil6210_priv *wil);
void wil6210_enable_irq(struct wil6210_priv *wil);
+int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
+ struct cfg80211_mgmt_tx_params *params,
+ u64 *cookie);
int wil6210_debugfs_init(struct wil6210_priv *wil);
void wil6210_debugfs_remove(struct wil6210_priv *wil);
+int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
+ struct station_info *sinfo);
struct wireless_dev *wil_cfg80211_init(struct device *dev);
void wil_wdev_free(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 6cc0e182cc70..1d1d0afdd2e1 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -65,17 +65,17 @@
/**
* @fw_mapping provides memory remapping table
+ *
+ * array size should be in sync with the declaration in the wil6210.h
*/
-static const struct {
- u32 from; /* linker address - from, inclusive */
- u32 to; /* linker address - to, exclusive */
- u32 host; /* PCI/Host address - BAR0 + 0x880000 */
-} fw_mapping[] = {
- {0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */
- {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
- {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
- {0x880000, 0x88a000, 0x880000}, /* various RGF */
- {0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */
+const struct fw_map fw_mapping[] = {
+ {0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */
+ {0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */
+ {0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
+ {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
+ {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
+ {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
+ {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
/*
* 920000..930000 ucode code RAM
* 930000..932000 ucode data RAM
@@ -327,6 +327,17 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
struct cfg80211_bss *bss;
+ u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
+ u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
+ u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
+ const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
+ size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
+ u.beacon.variable);
+ wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
+ wil_dbg_wmi(wil, "TSF : 0x%016llx\n", tsf);
+ wil_dbg_wmi(wil, "Beacon interval : %d\n", bi);
+ wil_hex_dump_wmi("IE ", DUMP_PREFIX_OFFSET, 16, 1, ie_buf,
+ ie_len, true);
bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
d_len, signal, GFP_KERNEL);
@@ -351,6 +362,9 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
bool aborted = (data->status != WMI_SCAN_SUCCESS);
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
+ wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
+ wil->scan_request, aborted);
+
del_timer_sync(&wil->scan_timer);
cfg80211_scan_done(wil->scan_request, aborted);
wil->scan_request = NULL;
@@ -668,14 +682,12 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
for (n = 0;; n++) {
u16 len;
+ bool q;
r->head = ioread32(wil->csr + HOST_MBOX +
offsetof(struct wil6210_mbox_ctl, rx.head));
- if (r->tail == r->head) {
- if (n == 0)
- wil_dbg_wmi(wil, "No events?\n");
- return;
- }
+ if (r->tail == r->head)
+ break;
wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n",
r->head, r->tail);
@@ -684,14 +696,14 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
sizeof(struct wil6210_mbox_ring_desc));
if (d_tail.sync == 0) {
wil_err(wil, "Mbox evt not owned by FW?\n");
- return;
+ break;
}
/* read cmd header from descriptor */
if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) {
wil_err(wil, "Mbox evt at 0x%08x?\n",
le32_to_cpu(d_tail.addr));
- return;
+ break;
}
len = le16_to_cpu(hdr.len);
wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n",
@@ -705,7 +717,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
event.wmi) + len, 4),
GFP_KERNEL);
if (!evt)
- return;
+ break;
evt->event.hdr = hdr;
cmd = (void *)&evt->event.wmi;
@@ -737,14 +749,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
spin_lock_irqsave(&wil->wmi_ev_lock, flags);
list_add_tail(&evt->list, &wil->pending_wmi_ev);
spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
- {
- int q = queue_work(wil->wmi_wq,
- &wil->wmi_event_worker);
- wil_dbg_wmi(wil, "queue_work -> %d\n", q);
- }
+ q = queue_work(wil->wmi_wq, &wil->wmi_event_worker);
+ wil_dbg_wmi(wil, "queue_work -> %d\n", q);
}
- if (n > 1)
- wil_dbg_wmi(wil, "%s -> %d events processed\n", __func__, n);
+ /* normally, 1 event per IRQ should be processed */
+ wil_dbg_wmi(wil, "%s -> %d events queued\n", __func__, n);
}
int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 40fd9b7b1426..64a5b672e30a 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -122,36 +122,41 @@ config B43_PIO
select SSB_BLOCKIO
default y
+config B43_PHY_G
+ bool "Support for G-PHY (802.11g) devices"
+ depends on B43 && B43_SSB
+ default y
+ ---help---
+ This PHY type can be found in the following chipsets:
+ PCI: BCM4306, BCM4311, BCM4318
+ SoC: BCM4712, BCM5352E
+
config B43_PHY_N
- bool "Support for 802.11n (N-PHY) devices"
+ bool "Support for N-PHY (the main 802.11n series) devices"
depends on B43
default y
---help---
- Support for the N-PHY.
-
- This enables support for devices with N-PHY.
-
- Say N if you expect high stability and performance. Saying Y will not
- affect other devices support and may provide support for basic needs.
+ This PHY type can be found in the following chipsets:
+ PCI: BCM4321, BCM4322,
+ BCM43222, BCM43224, BCM43225,
+ BCM43131, BCM43217, BCM43227, BCM43228
+ SoC: BCM4716, BCM4717, BCM4718, BCM5356, BCM5357, BCM5358
config B43_PHY_LP
- bool "Support for low-power (LP-PHY) devices"
+ bool "Support for LP-PHY (low-power 802.11g) devices"
depends on B43 && B43_SSB
default y
---help---
- Support for the LP-PHY.
The LP-PHY is a low-power PHY built into some notebooks
and embedded devices. It supports 802.11a/b/g
(802.11a support is optional, and currently disabled).
config B43_PHY_HT
- bool "Support for HT-PHY (high throughput) devices"
+ bool "Support for HT-PHY (high throughput 802.11n) devices"
depends on B43 && B43_BCMA
default y
---help---
- Support for the HT-PHY.
-
- Enables support for BCM4331 and possibly other chipsets with that PHY.
+ This PHY type with 3x3:3 MIMO can be found in the BCM4331 PCI chipset.
config B43_PHY_LCN
bool "Support for LCN-PHY devices (BROKEN)"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 098fe9ee7096..6e00b8804ada 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,13 +1,11 @@
b43-y += main.o
b43-y += bus.o
-b43-y += tables.o
+b43-$(CONFIG_B43_PHY_G) += phy_a.o phy_g.o tables.o lo.o wa.o
b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
b43-$(CONFIG_B43_PHY_N) += radio_2055.o
b43-$(CONFIG_B43_PHY_N) += radio_2056.o
b43-$(CONFIG_B43_PHY_N) += radio_2057.o
b43-y += phy_common.o
-b43-y += phy_g.o
-b43-y += phy_a.o
b43-$(CONFIG_B43_PHY_N) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
@@ -17,8 +15,6 @@ b43-$(CONFIG_B43_PHY_HT) += radio_2059.o
b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o
b43-y += sysfs.o
b43-y += xmit.o
-b43-y += lo.o
-b43-y += wa.o
b43-y += dma.o
b43-y += pio.o
b43-y += rfkill.o
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0d6a0bb1f876..2af1ac396eb4 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -122,7 +122,11 @@ static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1E, BCMA_ANY_CLASS),
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x28, BCMA_ANY_CLASS),
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x2A, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
@@ -206,6 +210,9 @@ static struct ieee80211_channel b43_2ghz_chantable[] = {
CHAN2G(13, 2472, 0),
CHAN2G(14, 2484, 0),
};
+
+/* No support for the last 3 channels (12, 13, 14) */
+#define b43_2ghz_chantable_limited_size 11
#undef CHAN2G
#define CHAN4G(_channel, _flags) { \
@@ -283,6 +290,14 @@ static struct ieee80211_channel b43_5ghz_nphy_chantable[] = {
CHAN5G(182, 0),
};
+static struct ieee80211_channel b43_5ghz_nphy_chantable_limited[] = {
+ CHAN5G(36, 0), CHAN5G(40, 0),
+ CHAN5G(44, 0), CHAN5G(48, 0),
+ CHAN5G(149, 0), CHAN5G(153, 0),
+ CHAN5G(157, 0), CHAN5G(161, 0),
+ CHAN5G(165, 0),
+};
+
static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
CHAN5G(34, 0), CHAN5G(36, 0),
CHAN5G(38, 0), CHAN5G(40, 0),
@@ -315,6 +330,14 @@ static struct ieee80211_supported_band b43_band_5GHz_nphy = {
.n_bitrates = b43_a_ratetable_size,
};
+static struct ieee80211_supported_band b43_band_5GHz_nphy_limited = {
+ .band = IEEE80211_BAND_5GHZ,
+ .channels = b43_5ghz_nphy_chantable_limited,
+ .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable_limited),
+ .bitrates = b43_a_ratetable,
+ .n_bitrates = b43_a_ratetable_size,
+};
+
static struct ieee80211_supported_band b43_band_5GHz_aphy = {
.band = IEEE80211_BAND_5GHZ,
.channels = b43_5ghz_aphy_chantable,
@@ -331,6 +354,14 @@ static struct ieee80211_supported_band b43_band_2GHz = {
.n_bitrates = b43_g_ratetable_size,
};
+static struct ieee80211_supported_band b43_band_2ghz_limited = {
+ .band = IEEE80211_BAND_2GHZ,
+ .channels = b43_2ghz_chantable,
+ .n_channels = b43_2ghz_chantable_limited_size,
+ .bitrates = b43_g_ratetable,
+ .n_bitrates = b43_g_ratetable_size,
+};
+
static void b43_wireless_core_exit(struct b43_wldev *dev);
static int b43_wireless_core_init(struct b43_wldev *dev);
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
@@ -2201,52 +2232,82 @@ err_format:
return -EPROTO;
}
+/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
struct b43_wldev *dev = ctx->dev;
struct b43_firmware *fw = &ctx->dev->fw;
+ struct b43_phy *phy = &dev->phy;
const u8 rev = ctx->dev->dev->core_rev;
const char *filename;
- u32 tmshigh;
int err;
- /* Files for HT and LCN were found by trying one by one */
-
/* Get microcode */
- if ((rev >= 5) && (rev <= 10)) {
- filename = "ucode5";
- } else if ((rev >= 11) && (rev <= 12)) {
- filename = "ucode11";
- } else if (rev == 13) {
- filename = "ucode13";
- } else if (rev == 14) {
- filename = "ucode14";
- } else if (rev == 15) {
+ filename = NULL;
+ switch (rev) {
+ case 42:
+ if (phy->type == B43_PHYTYPE_AC)
+ filename = "ucode42";
+ break;
+ case 40:
+ if (phy->type == B43_PHYTYPE_AC)
+ filename = "ucode40";
+ break;
+ case 33:
+ if (phy->type == B43_PHYTYPE_LCN40)
+ filename = "ucode33_lcn40";
+ break;
+ case 30:
+ if (phy->type == B43_PHYTYPE_N)
+ filename = "ucode30_mimo";
+ break;
+ case 29:
+ if (phy->type == B43_PHYTYPE_HT)
+ filename = "ucode29_mimo";
+ break;
+ case 26:
+ if (phy->type == B43_PHYTYPE_HT)
+ filename = "ucode26_mimo";
+ break;
+ case 28:
+ case 25:
+ if (phy->type == B43_PHYTYPE_N)
+ filename = "ucode25_mimo";
+ else if (phy->type == B43_PHYTYPE_LCN)
+ filename = "ucode25_lcn";
+ break;
+ case 24:
+ if (phy->type == B43_PHYTYPE_LCN)
+ filename = "ucode24_lcn";
+ break;
+ case 23:
+ if (phy->type == B43_PHYTYPE_N)
+ filename = "ucode16_mimo";
+ break;
+ case 16 ... 19:
+ if (phy->type == B43_PHYTYPE_N)
+ filename = "ucode16_mimo";
+ else if (phy->type == B43_PHYTYPE_LP)
+ filename = "ucode16_lp";
+ break;
+ case 15:
filename = "ucode15";
- } else {
- switch (dev->phy.type) {
- case B43_PHYTYPE_N:
- if (rev >= 16)
- filename = "ucode16_mimo";
- else
- goto err_no_ucode;
- break;
- case B43_PHYTYPE_HT:
- if (rev == 29)
- filename = "ucode29_mimo";
- else
- goto err_no_ucode;
- break;
- case B43_PHYTYPE_LCN:
- if (rev == 24)
- filename = "ucode24_mimo";
- else
- goto err_no_ucode;
- break;
- default:
- goto err_no_ucode;
- }
+ break;
+ case 14:
+ filename = "ucode14";
+ break;
+ case 13:
+ filename = "ucode13";
+ break;
+ case 11 ... 12:
+ filename = "ucode11";
+ break;
+ case 5 ... 10:
+ filename = "ucode5";
+ break;
}
+ if (!filename)
+ goto err_no_ucode;
err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
if (err)
goto err_load;
@@ -2268,117 +2329,121 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
goto err_load;
/* Get initvals */
+ filename = NULL;
switch (dev->phy.type) {
- case B43_PHYTYPE_A:
- if ((rev >= 5) && (rev <= 10)) {
- tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
- if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
- filename = "a0g1initvals5";
- else
- filename = "a0g0initvals5";
- } else
- goto err_no_initvals;
- break;
case B43_PHYTYPE_G:
- if ((rev >= 5) && (rev <= 10))
- filename = "b0g0initvals5";
- else if (rev >= 13)
+ if (rev == 13)
filename = "b0g0initvals13";
- else
- goto err_no_initvals;
+ else if (rev >= 5 && rev <= 10)
+ filename = "b0g0initvals5";
break;
case B43_PHYTYPE_N:
- if (rev >= 16)
+ if (rev == 30)
+ filename = "n16initvals30";
+ else if (rev == 28 || rev == 25)
+ filename = "n0initvals25";
+ else if (rev == 24)
+ filename = "n0initvals24";
+ else if (rev == 23)
+ filename = "n0initvals16"; /* What about n0initvals22? */
+ else if (rev >= 16 && rev <= 18)
filename = "n0initvals16";
- else if ((rev >= 11) && (rev <= 12))
+ else if (rev >= 11 && rev <= 12)
filename = "n0initvals11";
- else
- goto err_no_initvals;
break;
case B43_PHYTYPE_LP:
- if (rev == 13)
- filename = "lp0initvals13";
+ if (rev >= 16 && rev <= 18)
+ filename = "lp0initvals16";
+ else if (rev == 15)
+ filename = "lp0initvals15";
else if (rev == 14)
filename = "lp0initvals14";
- else if (rev >= 15)
- filename = "lp0initvals15";
- else
- goto err_no_initvals;
+ else if (rev == 13)
+ filename = "lp0initvals13";
break;
case B43_PHYTYPE_HT:
if (rev == 29)
filename = "ht0initvals29";
- else
- goto err_no_initvals;
+ else if (rev == 26)
+ filename = "ht0initvals26";
break;
case B43_PHYTYPE_LCN:
if (rev == 24)
filename = "lcn0initvals24";
- else
- goto err_no_initvals;
break;
- default:
- goto err_no_initvals;
+ case B43_PHYTYPE_LCN40:
+ if (rev == 33)
+ filename = "lcn400initvals33";
+ break;
+ case B43_PHYTYPE_AC:
+ if (rev == 42)
+ filename = "ac1initvals42";
+ else if (rev == 40)
+ filename = "ac0initvals40";
+ break;
}
+ if (!filename)
+ goto err_no_initvals;
err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
if (err)
goto err_load;
/* Get bandswitch initvals */
+ filename = NULL;
switch (dev->phy.type) {
- case B43_PHYTYPE_A:
- if ((rev >= 5) && (rev <= 10)) {
- tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
- if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
- filename = "a0g1bsinitvals5";
- else
- filename = "a0g0bsinitvals5";
- } else if (rev >= 11)
- filename = NULL;
- else
- goto err_no_initvals;
- break;
case B43_PHYTYPE_G:
- if ((rev >= 5) && (rev <= 10))
+ if (rev == 13)
+ filename = "b0g0bsinitvals13";
+ else if (rev >= 5 && rev <= 10)
filename = "b0g0bsinitvals5";
- else if (rev >= 11)
- filename = NULL;
- else
- goto err_no_initvals;
break;
case B43_PHYTYPE_N:
- if (rev >= 16)
+ if (rev == 30)
+ filename = "n16bsinitvals30";
+ else if (rev == 28 || rev == 25)
+ filename = "n0bsinitvals25";
+ else if (rev == 24)
+ filename = "n0bsinitvals24";
+ else if (rev == 23)
+ filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
+ else if (rev >= 16 && rev <= 18)
filename = "n0bsinitvals16";
- else if ((rev >= 11) && (rev <= 12))
+ else if (rev >= 11 && rev <= 12)
filename = "n0bsinitvals11";
- else
- goto err_no_initvals;
break;
case B43_PHYTYPE_LP:
- if (rev == 13)
- filename = "lp0bsinitvals13";
+ if (rev >= 16 && rev <= 18)
+ filename = "lp0bsinitvals16";
+ else if (rev == 15)
+ filename = "lp0bsinitvals15";
else if (rev == 14)
filename = "lp0bsinitvals14";
- else if (rev >= 15)
- filename = "lp0bsinitvals15";
- else
- goto err_no_initvals;
+ else if (rev == 13)
+ filename = "lp0bsinitvals13";
break;
case B43_PHYTYPE_HT:
if (rev == 29)
filename = "ht0bsinitvals29";
- else
- goto err_no_initvals;
+ else if (rev == 26)
+ filename = "ht0bsinitvals26";
break;
case B43_PHYTYPE_LCN:
if (rev == 24)
filename = "lcn0bsinitvals24";
- else
- goto err_no_initvals;
break;
- default:
- goto err_no_initvals;
+ case B43_PHYTYPE_LCN40:
+ if (rev == 33)
+ filename = "lcn400bsinitvals33";
+ break;
+ case B43_PHYTYPE_AC:
+ if (rev == 42)
+ filename = "ac1bsinitvals42";
+ else if (rev == 40)
+ filename = "ac0bsinitvals40";
+ break;
}
+ if (!filename)
+ goto err_no_initvals;
err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
if (err)
goto err_load;
@@ -2915,6 +2980,46 @@ void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
}
}
+/* brcms_b_switch_macfreq */
+void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
+{
+ u16 chip_id = dev->dev->chip_id;
+
+ if (chip_id == BCMA_CHIP_ID_BCM43131 ||
+ chip_id == BCMA_CHIP_ID_BCM43217 ||
+ chip_id == BCMA_CHIP_ID_BCM43222 ||
+ chip_id == BCMA_CHIP_ID_BCM43224 ||
+ chip_id == BCMA_CHIP_ID_BCM43225 ||
+ chip_id == BCMA_CHIP_ID_BCM43227 ||
+ chip_id == BCMA_CHIP_ID_BCM43228) {
+ switch (spurmode) {
+ case 2: /* 126 Mhz */
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
+ break;
+ case 1: /* 123 Mhz */
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
+ break;
+ default: /* 120 Mhz */
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
+ break;
+ }
+ } else if (dev->phy.type == B43_PHYTYPE_LCN) {
+ switch (spurmode) {
+ case 1: /* 82 Mhz */
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
+ break;
+ default: /* 80 Mhz */
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
+ break;
+ }
+ }
+}
+
static void b43_adjust_opmode(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
@@ -3798,38 +3903,29 @@ static void b43_set_retry_limits(struct b43_wldev *dev,
static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
- struct b43_wldev *dev;
- struct b43_phy *phy;
+ struct b43_wldev *dev = wl->current_dev;
+ struct b43_phy *phy = &dev->phy;
struct ieee80211_conf *conf = &hw->conf;
int antenna;
int err = 0;
- bool reload_bss = false;
mutex_lock(&wl->mutex);
-
- dev = wl->current_dev;
-
b43_mac_suspend(dev);
- /* Switch the band (if necessary). This might change the active core. */
- err = b43_switch_band(dev, conf->chandef.chan);
- if (err)
- goto out_unlock_mutex;
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ phy->chandef = &conf->chandef;
+ phy->channel = conf->chandef.chan->hw_value;
- /* Need to reload all settings if the core changed */
- if (dev != wl->current_dev) {
- dev = wl->current_dev;
- changed = ~0;
- reload_bss = true;
- }
-
- phy = &dev->phy;
+ /* Switch the band (if necessary). */
+ err = b43_switch_band(dev, conf->chandef.chan);
+ if (err)
+ goto out_mac_enable;
- if (conf_is_ht(conf))
- phy->is_40mhz =
- (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
- else
- phy->is_40mhz = false;
+ /* Switch to the requested channel.
+ * The firmware takes care of races with the TX handler.
+ */
+ b43_switch_channel(dev, phy->channel);
+ }
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
@@ -3838,11 +3934,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
if (!changed)
goto out_mac_enable;
- /* Switch to the requested channel.
- * The firmware takes care of races with the TX handler. */
- if (conf->chandef.chan->hw_value != phy->channel)
- b43_switch_channel(dev, conf->chandef.chan->hw_value);
-
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
/* Adjust the desired TX power level. */
@@ -3878,12 +3969,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
out_mac_enable:
b43_mac_enable(dev);
-out_unlock_mutex:
mutex_unlock(&wl->mutex);
- if (wl->vif && reload_bss)
- b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
-
return err;
}
@@ -4309,13 +4396,15 @@ static char *b43_phy_name(struct b43_wldev *dev, u8 phy_type)
static int b43_phy_versioning(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
+ const u8 core_rev = dev->dev->core_rev;
u32 tmp;
u8 analog_type;
u8 phy_type;
u8 phy_rev;
u16 radio_manuf;
- u16 radio_ver;
+ u16 radio_id;
u16 radio_rev;
+ u8 radio_ver;
int unsupported = 0;
/* Get PHY versioning */
@@ -4323,23 +4412,23 @@ static int b43_phy_versioning(struct b43_wldev *dev)
analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
phy_rev = (tmp & B43_PHYVER_VERSION);
+
+ /* LCNXN is continuation of N which run out of revisions */
+ if (phy_type == B43_PHYTYPE_LCNXN) {
+ phy_type = B43_PHYTYPE_N;
+ phy_rev += 16;
+ }
+
switch (phy_type) {
- case B43_PHYTYPE_A:
- if (phy_rev >= 4)
- unsupported = 1;
- break;
- case B43_PHYTYPE_B:
- if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
- && phy_rev != 7)
- unsupported = 1;
- break;
+#ifdef CONFIG_B43_PHY_G
case B43_PHYTYPE_G:
if (phy_rev > 9)
unsupported = 1;
break;
+#endif
#ifdef CONFIG_B43_PHY_N
case B43_PHYTYPE_N:
- if (phy_rev > 9)
+ if (phy_rev >= 19)
unsupported = 1;
break;
#endif
@@ -4374,7 +4463,17 @@ static int b43_phy_versioning(struct b43_wldev *dev)
analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
/* Get RADIO versioning */
- if (dev->dev->core_rev >= 24) {
+ if (core_rev == 40 || core_rev == 42) {
+ radio_manuf = 0x17F;
+
+ b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+ radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
+
+ b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+ radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
+
+ radio_ver = 0; /* Is there version somewhere? */
+ } else if (core_rev >= 24) {
u16 radio24[3];
for (tmp = 0; tmp < 3; tmp++) {
@@ -4382,12 +4481,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
}
- /* Broadcom uses "id" for our "ver" and has separated "ver" */
- /* radio_ver = (radio24[0] & 0xF0) >> 4; */
-
radio_manuf = 0x17F;
- radio_ver = (radio24[2] << 8) | radio24[1];
+ radio_id = (radio24[2] << 8) | radio24[1];
radio_rev = (radio24[0] & 0xF);
+ radio_ver = (radio24[0] & 0xF0) >> 4;
} else {
if (dev->dev->chip_id == 0x4317) {
if (dev->dev->chip_rev == 0)
@@ -4406,15 +4503,16 @@ static int b43_phy_versioning(struct b43_wldev *dev)
<< 16;
}
radio_manuf = (tmp & 0x00000FFF);
- radio_ver = (tmp & 0x0FFFF000) >> 12;
+ radio_id = (tmp & 0x0FFFF000) >> 12;
radio_rev = (tmp & 0xF0000000) >> 28;
+ radio_ver = 0; /* Probably not available on old hw */
}
if (radio_manuf != 0x17F /* Broadcom */)
unsupported = 1;
switch (phy_type) {
case B43_PHYTYPE_A:
- if (radio_ver != 0x2060)
+ if (radio_id != 0x2060)
unsupported = 1;
if (radio_rev != 1)
unsupported = 1;
@@ -4422,43 +4520,49 @@ static int b43_phy_versioning(struct b43_wldev *dev)
unsupported = 1;
break;
case B43_PHYTYPE_B:
- if ((radio_ver & 0xFFF0) != 0x2050)
+ if ((radio_id & 0xFFF0) != 0x2050)
unsupported = 1;
break;
case B43_PHYTYPE_G:
- if (radio_ver != 0x2050)
+ if (radio_id != 0x2050)
unsupported = 1;
break;
case B43_PHYTYPE_N:
- if (radio_ver != 0x2055 && radio_ver != 0x2056)
+ if (radio_id != 0x2055 && radio_id != 0x2056 &&
+ radio_id != 0x2057)
+ unsupported = 1;
+ if (radio_id == 0x2057 &&
+ !(radio_rev == 9 || radio_rev == 14))
unsupported = 1;
break;
case B43_PHYTYPE_LP:
- if (radio_ver != 0x2062 && radio_ver != 0x2063)
+ if (radio_id != 0x2062 && radio_id != 0x2063)
unsupported = 1;
break;
case B43_PHYTYPE_HT:
- if (radio_ver != 0x2059)
+ if (radio_id != 0x2059)
unsupported = 1;
break;
case B43_PHYTYPE_LCN:
- if (radio_ver != 0x2064)
+ if (radio_id != 0x2064)
unsupported = 1;
break;
default:
B43_WARN_ON(1);
}
if (unsupported) {
- b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
- "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
- radio_manuf, radio_ver, radio_rev);
+ b43err(dev->wl,
+ "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
+ radio_manuf, radio_id, radio_rev, radio_ver);
return -EOPNOTSUPP;
}
- b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
- radio_manuf, radio_ver, radio_rev);
+ b43info(dev->wl,
+ "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
+ radio_manuf, radio_id, radio_rev, radio_ver);
+ /* FIXME: b43 treats "id" as "ver" and ignores the real "ver" */
phy->radio_manuf = radio_manuf;
- phy->radio_ver = radio_ver;
+ phy->radio_ver = radio_id;
phy->radio_rev = radio_rev;
phy->analog = analog_type;
@@ -5066,12 +5170,24 @@ static int b43_setup_bands(struct b43_wldev *dev,
bool have_2ghz_phy, bool have_5ghz_phy)
{
struct ieee80211_hw *hw = dev->wl->hw;
+ struct b43_phy *phy = &dev->phy;
+ bool limited_2g;
+ bool limited_5g;
+
+ /* We don't support all 2 GHz channels on some devices */
+ limited_2g = phy->radio_ver == 0x2057 &&
+ (phy->radio_rev == 9 || phy->radio_rev == 14);
+ limited_5g = phy->radio_ver == 0x2057 &&
+ phy->radio_rev == 9;
if (have_2ghz_phy)
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
+ &b43_band_2ghz_limited : &b43_band_2GHz;
if (dev->phy.type == B43_PHYTYPE_N) {
if (have_5ghz_phy)
- hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = limited_5g ?
+ &b43_band_5GHz_nphy_limited :
+ &b43_band_5GHz_nphy;
} else {
if (have_5ghz_phy)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
@@ -5219,14 +5335,15 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
/* We don't support 5 GHz on some PHYs yet */
- switch (dev->phy.type) {
- case B43_PHYTYPE_A:
- case B43_PHYTYPE_G:
- case B43_PHYTYPE_N:
- case B43_PHYTYPE_LP:
- case B43_PHYTYPE_HT:
- b43warn(wl, "5 GHz band is unsupported on this PHY\n");
- have_5ghz_phy = false;
+ if (have_5ghz_phy) {
+ switch (dev->phy.type) {
+ case B43_PHYTYPE_A:
+ case B43_PHYTYPE_G:
+ case B43_PHYTYPE_LP:
+ case B43_PHYTYPE_HT:
+ b43warn(wl, "5 GHz band is unsupported on this PHY\n");
+ have_5ghz_phy = false;
+ }
}
if (!have_2ghz_phy && !have_5ghz_phy) {
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index f476fc337d64..9f22e4b4c132 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -99,6 +99,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
void b43_mac_suspend(struct b43_wldev *dev);
void b43_mac_enable(struct b43_wldev *dev);
void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
+void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode);
struct b43_request_fw_context;
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index a6c38104693d..25e40432d68b 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
{//TODO
}
-const struct b43_phy_operations b43_phyops_a = {
+static const struct b43_phy_operations b43_phyops_a = {
.allocate = b43_aphy_op_allocate,
.free = b43_aphy_op_free,
.prepare_structs = b43_aphy_op_prepare_structs,
diff --git a/drivers/net/wireless/b43/phy_a.h b/drivers/net/wireless/b43/phy_a.h
index 5cfaab7b16ee..f7d0d929a374 100644
--- a/drivers/net/wireless/b43/phy_a.h
+++ b/drivers/net/wireless/b43/phy_a.h
@@ -123,8 +123,4 @@ struct b43_phy_a {
*/
void b43_phy_inita(struct b43_wldev *dev);
-
-struct b43_phy_operations;
-extern const struct b43_phy_operations b43_phyops_a;
-
#endif /* LINUX_B43_PHY_A_H_ */
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08244b3b327e..3cbef21b4726 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *dev)
phy->ops = NULL;
switch (phy->type) {
- case B43_PHYTYPE_A:
- phy->ops = &b43_phyops_a;
- break;
case B43_PHYTYPE_G:
+#ifdef CONFIG_B43_PHY_G
phy->ops = &b43_phyops_g;
+#endif
break;
case B43_PHYTYPE_N:
#ifdef CONFIG_B43_PHY_N
@@ -94,7 +93,13 @@ int b43_phy_init(struct b43_wldev *dev)
const struct b43_phy_operations *ops = phy->ops;
int err;
- phy->channel = ops->get_default_chan(dev);
+ /* During PHY init we need to use some channel. On the first init this
+ * function is called *before* b43_op_config, so our pointer is NULL.
+ */
+ if (!phy->chandef) {
+ phy->chandef = &dev->wl->hw->conf.chandef;
+ phy->channel = phy->chandef->chan->hw_value;
+ }
phy->ops->switch_analog(dev, true);
b43_software_rfkill(dev, false);
@@ -106,9 +111,7 @@ int b43_phy_init(struct b43_wldev *dev)
}
phy->do_full_init = false;
- /* Make sure to switch hardware and firmware (SHM) to
- * the default channel. */
- err = b43_switch_channel(dev, ops->get_default_chan(dev));
+ err = b43_switch_channel(dev, phy->channel);
if (err) {
b43err(dev->wl, "PHY init: Channel switch to default failed\n");
goto err_phy_exit;
@@ -408,9 +411,6 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
u16 channelcookie, savedcookie;
int err;
- if (new_channel == B43_DEFAULT_CHANNEL)
- new_channel = phy->ops->get_default_chan(dev);
-
/* First we set the channel radio code to prevent the
* firmware from sending ghost packets.
*/
@@ -428,7 +428,6 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
if (err)
goto err_restore_cookie;
- dev->phy.channel = new_channel;
/* Wait for the radio to tune to the channel and stabilize. */
msleep(8);
@@ -547,10 +546,9 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
}
-bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
+bool b43_is_40mhz(struct b43_wldev *dev)
{
- return (channel_type == NL80211_CHAN_HT40MINUS ||
- channel_type == NL80211_CHAN_HT40PLUS);
+ return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 4ad6240d9ff4..3912274f71e3 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -228,9 +228,6 @@ struct b43_phy {
bool supports_2ghz;
bool supports_5ghz;
- /* HT info */
- bool is_40mhz;
-
/* Is GMODE (2 GHz mode) bit enabled? */
bool gmode;
@@ -267,9 +264,8 @@ struct b43_phy {
unsigned long next_txpwr_check_time;
/* Current channel */
+ struct cfg80211_chan_def *chandef;
unsigned int channel;
- u16 channel_freq;
- enum nl80211_channel_type channel_type;
/* PHY TX errors counter. */
atomic_t txerr_cnt;
@@ -400,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b43_wldev *dev);
* b43_switch_channel - Switch to another channel
*/
int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
-/**
- * B43_DEFAULT_CHANNEL - Switch to the default channel.
- */
-#define B43_DEFAULT_CHANNEL UINT_MAX
/**
* b43_software_rfkill - Turn the radio ON or OFF in software.
@@ -454,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
*/
void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
-bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
+bool b43_is_40mhz(struct b43_wldev *dev);
void b43_phy_force_clock(struct b43_wldev *dev, bool force);
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 5d6833f18498..f2974c6b1c01 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
u8 target[3];
s16 a1[3], b0[3], b1[3];
- u16 freq = dev->phy.channel_freq;
+ u16 freq = dev->phy.chandef->chan->center_freq;
int i, c;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index 0bafa3b17035..e76bbdf3247e 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -54,39 +54,6 @@ enum lcn_sense_type {
B43_SENSE_VBAT,
};
-/* In theory it's PHY common function, move if needed */
-/* brcms_b_switch_macfreq */
-static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode)
-{
- if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
- switch (spurmode) {
- case 2: /* 126 Mhz */
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
- break;
- case 1: /* 123 Mhz */
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
- break;
- default: /* 120 Mhz */
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
- break;
- }
- } else if (dev->phy.type == B43_PHYTYPE_LCN) {
- switch (spurmode) {
- case 1: /* 82 Mhz */
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
- break;
- default: /* 80 Mhz */
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
- break;
- }
- }
-}
-
/**************************************************
* Radio 2064.
**************************************************/
@@ -609,7 +576,7 @@ static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev,
b43_phy_write(dev, 0x93b, ((0 << 13) + 23));
b43_phy_write(dev, 0x93c, ((0 << 13) + 1989));
}
- b43_phy_switch_macfreq(dev, enable);
+ b43_mac_switch_freq(dev, enable);
}
/**************************************************
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 86569f6a8705..e2a3f0d5bcc2 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -36,6 +36,7 @@
#include "main.h"
struct nphy_txgains {
+ u16 tx_lpf[2];
u16 txgm[2];
u16 pga[2];
u16 pad[2];
@@ -43,6 +44,7 @@ struct nphy_txgains {
};
struct nphy_iqcal_params {
+ u16 tx_lpf;
u16 txgm;
u16 pga;
u16 pad;
@@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
B43_RFSEQ_UPDATE_GAINU,
};
+enum n_rf_ctl_over_cmd {
+ N_RF_CTL_OVER_CMD_RXRF_PU = 0,
+ N_RF_CTL_OVER_CMD_RX_PU = 1,
+ N_RF_CTL_OVER_CMD_TX_PU = 2,
+ N_RF_CTL_OVER_CMD_RX_GAIN = 3,
+ N_RF_CTL_OVER_CMD_TX_GAIN = 4,
+};
+
enum n_intc_override {
N_INTC_OVERRIDE_OFF = 0,
N_INTC_OVERRIDE_TRSW = 1,
@@ -140,11 +150,19 @@ ok:
b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
}
+static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
+ u16 value, u8 core, bool off,
+ u8 override_id)
+{
+ /* TODO */
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
u16 value, u8 core, bool off,
u8 override)
{
+ struct b43_phy *phy = &dev->phy;
const struct nphy_rf_control_override_rev7 *e;
u16 en_addrs[3][2] = {
{ 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
@@ -154,6 +172,11 @@ static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
u16 val_addr;
u8 i;
+ if (phy->rev >= 19 || phy->rev < 3) {
+ B43_WARN_ON(1);
+ return;
+ }
+
/* Remember: we can get NULL! */
e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
@@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
}
}
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
+static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
+ enum n_rf_ctl_over_cmd cmd,
+ u16 value, u8 core, bool off)
+{
+ struct b43_phy *phy = &dev->phy;
+ u16 tmp;
+
+ B43_WARN_ON(phy->rev < 7);
+
+ switch (cmd) {
+ case N_RF_CTL_OVER_CMD_RXRF_PU:
+ b43_nphy_rf_ctl_override_rev7(dev, 0x20, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x10, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x08, value, core, off, 1);
+ break;
+ case N_RF_CTL_OVER_CMD_RX_PU:
+ b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 2);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 0, core, off, 1);
+ break;
+ case N_RF_CTL_OVER_CMD_TX_PU:
+ b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 0);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 2);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 1, core, off, 1);
+ break;
+ case N_RF_CTL_OVER_CMD_RX_GAIN:
+ tmp = value & 0xFF;
+ b43_nphy_rf_ctl_override_rev7(dev, 0x0800, tmp, core, off, 0);
+ tmp = value >> 8;
+ b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
+ break;
+ case N_RF_CTL_OVER_CMD_TX_GAIN:
+ tmp = value & 0x7FFF;
+ b43_nphy_rf_ctl_override_rev7(dev, 0x1000, tmp, core, off, 0);
+ tmp = value >> 14;
+ b43_nphy_rf_ctl_override_rev7(dev, 0x4000, tmp, core, off, 0);
+ break;
+ }
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
u16 value, u8 core, bool off)
@@ -264,6 +331,8 @@ static void b43_nphy_rf_ctl_intc_override_rev7(struct b43_wldev *dev,
u16 reg, tmp, tmp2, val;
int core;
+ /* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
+
for (core = 0; core < 2; core++) {
if ((core_sel == 1 && core != 0) ||
(core_sel == 2 && core != 1))
@@ -274,6 +343,7 @@ static void b43_nphy_rf_ctl_intc_override_rev7(struct b43_wldev *dev,
switch (intc_override) {
case N_INTC_OVERRIDE_OFF:
b43_phy_write(dev, reg, 0);
+ b43_phy_mask(dev, 0x2ff, ~0x2000);
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
break;
case N_INTC_OVERRIDE_TRSW:
@@ -505,6 +575,14 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
}
}
+/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
+static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
+{
+ if (!offset)
+ offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
+ return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
{
@@ -590,44 +668,270 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
* Radio 0x2057
**************************************************/
-/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
+static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
+ const struct b43_nphy_chantabent_rev7 *e_r7,
+ const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
+{
+ if (e_r7_2g) {
+ b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
+ b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
+ b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
+ b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
+ b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
+ b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
+ b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
+ b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
+ b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
+ b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
+ b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
+
+ } else {
+ b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
+ b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
+ b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
+ b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
+ b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
+ b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
+ b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
+ b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
+ b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
+ b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
+ b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
+ b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
+ b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
+ b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
+ b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
+ b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
+ b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
+ b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
+ b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
+ b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
+ b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
+ }
+}
+
+static void b43_radio_2057_setup(struct b43_wldev *dev,
+ const struct b43_nphy_chantabent_rev7 *tabent_r7,
+ const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
+{
+ struct b43_phy *phy = &dev->phy;
+
+ b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
+
+ switch (phy->radio_rev) {
+ case 0 ... 4:
+ case 6:
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
+ b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
+ } else {
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
+ b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
+ }
+ break;
+ case 9: /* e.g. PHY rev 16 */
+ b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x20);
+ b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x18);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x38);
+ b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x0f);
+
+ if (b43_is_40mhz(dev)) {
+ /* TODO */
+ } else {
+ b43_radio_write(dev,
+ R2057_PAD_BIAS_FILTER_BWS_CORE0,
+ 0x3c);
+ b43_radio_write(dev,
+ R2057_PAD_BIAS_FILTER_BWS_CORE1,
+ 0x3c);
+ }
+ }
+ break;
+ case 14: /* 2 GHz only */
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1b);
+ b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x1f);
+ b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x1f);
+ break;
+ }
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ u16 txmix2g_tune_boost_pu = 0;
+ u16 pad2g_tune_pus = 0;
+
+ if (b43_nphy_ipa(dev)) {
+ switch (phy->radio_rev) {
+ case 9:
+ txmix2g_tune_boost_pu = 0x0041;
+ /* TODO */
+ break;
+ case 14:
+ txmix2g_tune_boost_pu = 0x21;
+ pad2g_tune_pus = 0x23;
+ break;
+ }
+ }
+
+ if (txmix2g_tune_boost_pu)
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+ txmix2g_tune_boost_pu);
+ if (pad2g_tune_pus)
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0,
+ pad2g_tune_pus);
+ if (txmix2g_tune_boost_pu)
+ b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+ txmix2g_tune_boost_pu);
+ if (pad2g_tune_pus)
+ b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1,
+ pad2g_tune_pus);
+ }
+
+ usleep_range(50, 100);
+
+ /* VCO calibration */
+ b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
+ b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
+ b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
+ b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
+ usleep_range(300, 600);
+}
+
+/* Calibrate resistors in LPF of PLL?
+ * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
+ */
static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
+ u16 saved_regs_phy[12];
+ u16 saved_regs_phy_rf[6];
+ u16 saved_regs_radio[2] = { };
+ static const u16 phy_to_store[] = {
+ B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2,
+ B43_NPHY_RFCTL_LUT_TRSW_LO1, B43_NPHY_RFCTL_LUT_TRSW_LO2,
+ B43_NPHY_RFCTL_RXG1, B43_NPHY_RFCTL_RXG2,
+ B43_NPHY_RFCTL_TXG1, B43_NPHY_RFCTL_TXG2,
+ B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
+ B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
+ };
+ static const u16 phy_to_store_rf[] = {
+ B43_NPHY_REV3_RFCTL_OVER0, B43_NPHY_REV3_RFCTL_OVER1,
+ B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
+ B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
+ };
u16 tmp;
+ int i;
- if (phy->radio_rev == 5) {
- b43_phy_mask(dev, 0x342, ~0x2);
+ /* Save */
+ for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
+ saved_regs_phy[i] = b43_phy_read(dev, phy_to_store[i]);
+ for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
+ saved_regs_phy_rf[i] = b43_phy_read(dev, phy_to_store_rf[i]);
+
+ /* Set */
+ for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
+ b43_phy_write(dev, phy_to_store[i], 0);
+ b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER0, 0x07ff);
+ b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER1, 0x07ff);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x07ff);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0x07ff);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0x007f);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0x007f);
+
+ switch (phy->radio_rev) {
+ case 5:
+ b43_phy_mask(dev, B43_NPHY_REV7_RF_CTL_OVER3, ~0x2);
udelay(10);
b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
- b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
+ b43_radio_maskset(dev, R2057v7_IQTEST_SEL_PU2, ~0x2, 0x1);
+ break;
+ case 9:
+ b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
+ b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
+ saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
+ b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x11);
+ break;
+ case 14:
+ saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
+ saved_regs_radio[1] = b43_radio_read(dev, R2057v7_IQTEST_SEL_PU2);
+ b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
+ b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
+ b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, 0x2);
+ b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x1);
+ break;
}
+ /* Enable */
b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
udelay(10);
- b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
- if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
+
+ /* Start */
+ b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
+ usleep_range(100, 200);
+
+ /* Stop */
+ b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
+
+ /* Wait and check for result */
+ if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
return 0;
}
- b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
+
+ /* Disable */
b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
- if (phy->radio_rev == 5) {
- b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
- b43_radio_mask(dev, 0x1ca, ~0x2);
- }
- if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
+ /* Restore */
+ for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
+ b43_phy_write(dev, phy_to_store_rf[i], saved_regs_phy_rf[i]);
+ for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
+ b43_phy_write(dev, phy_to_store[i], saved_regs_phy[i]);
+
+ switch (phy->radio_rev) {
+ case 0 ... 4:
+ case 6:
b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
tmp << 2);
+ break;
+ case 5:
+ b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
+ b43_radio_mask(dev, R2057v7_IQTEST_SEL_PU2, ~0x2);
+ break;
+ case 9:
+ b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
+ break;
+ case 14:
+ b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
+ b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, saved_regs_radio[1]);
+ break;
}
return tmp & 0x3e;
}
-/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
+/* Calibrate the internal RC oscillator?
+ * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
+ */
static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -635,49 +939,76 @@ static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
phy->radio_rev == 6);
u16 tmp;
+ /* Setup cal */
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
} else {
- b43_radio_write(dev, 0x1AE, 0x61);
- b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
+ b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
+ b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE9);
}
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
+
+ /* Start, wait, stop */
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
- if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
+ if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
5000000))
b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
+ usleep_range(35, 70);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
+ usleep_range(70, 140);
+
+ /* Setup cal */
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
} else {
- b43_radio_write(dev, 0x1AE, 0x69);
+ b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
}
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
+
+ /* Start, wait, stop */
+ usleep_range(35, 70);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
- if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
+ usleep_range(70, 140);
+ if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
5000000))
b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
+ usleep_range(35, 70);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
+ usleep_range(70, 140);
+
+ /* Setup cal */
if (special) {
b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
} else {
- b43_radio_write(dev, 0x1AE, 0x73);
+ b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
}
+
+ /* Start, wait, stop */
+ usleep_range(35, 70);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
- if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
+ usleep_range(70, 140);
+ if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
5000000)) {
b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
return 0;
}
tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
+ usleep_range(35, 70);
b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
+ usleep_range(70, 140);
+
+ if (special)
+ b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
+ else
+ b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
+
return tmp;
}
@@ -694,6 +1025,9 @@ static void b43_radio_2057_init_post(struct b43_wldev *dev)
{
b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
+ if (0) /* FIXME: Is this BCM43217 specific? */
+ b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x2);
+
b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
mdelay(2);
@@ -798,6 +1132,7 @@ static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
static void b43_radio_2056_setup(struct b43_wldev *dev,
const struct b43_nphy_channeltab_entry_rev3 *e)
{
+ struct b43_phy *phy = &dev->phy;
struct ssb_sprom *sprom = dev->dev->bus_sprom;
enum ieee80211_band band = b43_current_band(dev->wl);
u16 offset;
@@ -895,7 +1230,7 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
offset | B2056_TX_MIXG_BOOST_TUNE,
mixg_boost);
} else {
- bias = dev->phy.is_40mhz ? 0x40 : 0x20;
+ bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
b43_radio_write(dev,
offset | B2056_TX_INTPAG_IMAIN_STAT,
bias);
@@ -909,7 +1244,7 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
}
} else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
- u16 freq = dev->phy.channel_freq;
+ u16 freq = phy->chandef->chan->center_freq;
if (freq < 5100) {
paa_boost = 0xA;
pada_boost = 0x77;
@@ -1210,8 +1545,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
u16 bw, len, rot, angle;
struct b43_c32 *samples;
-
- bw = (dev->phy.is_40mhz) ? 40 : 20;
+ bw = b43_is_40mhz(dev) ? 40 : 20;
len = bw << 3;
if (test) {
@@ -1220,7 +1554,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
else
bw = 80;
- if (dev->phy.is_40mhz)
+ if (b43_is_40mhz(dev))
bw <<= 1;
len = bw << 1;
@@ -1248,8 +1582,10 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
- u16 wait, bool iqmode, bool dac_test)
+ u16 wait, bool iqmode, bool dac_test,
+ bool modify_bbmult)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
int i;
u16 seq_mode;
@@ -1257,17 +1593,35 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
b43_nphy_stay_in_carrier_search(dev, true);
+ if (phy->rev >= 7) {
+ bool lpf_bw3, lpf_bw4;
+
+ lpf_bw3 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
+ lpf_bw4 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER4) & 0x80;
+
+ if (lpf_bw3 || lpf_bw4) {
+ /* TODO */
+ } else {
+ u16 value = b43_nphy_read_lpf_ctl(dev, 0);
+ if (phy->rev >= 19)
+ b43_nphy_rf_ctl_override_rev19(dev, 0x80, value,
+ 0, false, 1);
+ else
+ b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
+ 0, false, 1);
+ nphy->lpf_bw_overrode_for_sample_play = true;
+ }
+ }
+
if ((nphy->bb_mult_save & 0x80000000) == 0) {
tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
}
- /* TODO: add modify_bbmult argument */
- if (!dev->phy.is_40mhz)
- tmp = 0x6464;
- else
- tmp = 0x4747;
- b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
+ if (modify_bbmult) {
+ tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
+ b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
+ }
b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
@@ -1285,10 +1639,8 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
} else {
- if (dac_test)
- b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
- else
- b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
+ tmp = dac_test ? 5 : 1;
+ b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
}
for (i = 0; i < 100; i++) {
if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
@@ -1388,6 +1740,12 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
}
}
+static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
+ enum n_rssi_type rssi_type)
+{
+ /* TODO */
+}
+
static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
enum n_rssi_type rssi_type)
{
@@ -1457,13 +1815,15 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
enum ieee80211_band band =
b43_current_band(dev->wl);
- if (b43_nphy_ipa(dev))
- val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
- else
- val = 0x11;
- reg = (i == 0) ? 0x2000 : 0x3000;
- reg |= B2055_PADDRV;
- b43_radio_write(dev, reg, val);
+ if (dev->phy.rev < 7) {
+ if (b43_nphy_ipa(dev))
+ val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
+ else
+ val = 0x11;
+ reg = (i == 0) ? B2056_TX0 : B2056_TX1;
+ reg |= B2056_TX_TX_SSI_MUX;
+ b43_radio_write(dev, reg, val);
+ }
reg = (i == 0) ?
B43_NPHY_AFECTL_OVER1 :
@@ -1550,7 +1910,9 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code,
static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
enum n_rssi_type type)
{
- if (dev->phy.rev >= 3)
+ if (dev->phy.rev >= 19)
+ b43_nphy_rssi_select_rev19(dev, code, type);
+ else if (dev->phy.rev >= 3)
b43_nphy_rev3_rssi_select(dev, code, type);
else
b43_nphy_rev2_rssi_select(dev, code, type);
@@ -1594,6 +1956,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
u16 save_regs_phy[9];
u16 s[2];
+ /* TODO: rev7+ is treated like rev3+, what about rev19+? */
+
if (dev->phy.rev >= 3) {
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
@@ -1675,6 +2039,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u16 saved_regs_phy_rfctl[2];
@@ -1692,12 +2057,14 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
- 0x342, 0x343, 0x346, 0x347,
+ B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
+ B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
0x2ff,
B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
B43_NPHY_RFCTL_CMD,
B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
- 0x340, 0x341, 0x344, 0x345,
+ B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
+ B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
};
u16 *regs_to_store;
@@ -1744,9 +2111,24 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
if (dev->phy.rev >= 7) {
- /* TODO */
+ b43_nphy_rf_ctl_override_one_to_many(dev,
+ N_RF_CTL_OVER_CMD_RXRF_PU,
+ 0, 0, false);
+ b43_nphy_rf_ctl_override_one_to_many(dev,
+ N_RF_CTL_OVER_CMD_RX_PU,
+ 1, 0, false);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x40, 1, 0, false, 0);
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ b43_nphy_rf_ctl_override_rev7(dev, 0x20, 0, 0, false,
+ 0);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
+ 0);
} else {
+ b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
+ 0);
+ b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
+ 0);
}
} else {
b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
@@ -1775,7 +2157,10 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
/* Grab RSSI results for every possible VCM */
for (vcm = 0; vcm < 8; vcm++) {
if (dev->phy.rev >= 7)
- ;
+ b43_radio_maskset(dev,
+ core ? R2057_NB_MASTER_CORE1 :
+ R2057_NB_MASTER_CORE0,
+ ~R2057_VCM_MASK, vcm);
else
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
0xE3, vcm << 2);
@@ -1806,7 +2191,10 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
/* Select the best VCM */
if (dev->phy.rev >= 7)
- ;
+ b43_radio_maskset(dev,
+ core ? R2057_NB_MASTER_CORE1 :
+ R2057_NB_MASTER_CORE0,
+ ~R2057_VCM_MASK, vcm);
else
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
0xE3, vcm_final << 2);
@@ -1876,6 +2264,10 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
}
if (dev->phy.rev >= 7) {
+ rssical_radio_regs[0] = b43_radio_read(dev,
+ R2057_NB_MASTER_CORE0);
+ rssical_radio_regs[1] = b43_radio_read(dev,
+ R2057_NB_MASTER_CORE1);
} else {
rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
B2056_RX_RSSI_MISC);
@@ -1897,9 +2289,9 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
/* Remember for which channel we store configuration */
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
+ nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
else
- nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
+ nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
/* End of calibration, restore configuration */
b43_nphy_classifier(dev, 7, class);
@@ -2076,7 +2468,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type)
*/
static void b43_nphy_rssi_cal(struct b43_wldev *dev)
{
- if (dev->phy.rev >= 3) {
+ if (dev->phy.rev >= 19) {
+ /* TODO */
+ } else if (dev->phy.rev >= 3) {
b43_nphy_rev3_rssi_cal(dev);
} else {
b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
@@ -2089,7 +2483,21 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev)
* Workarounds
**************************************************/
-static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
+static void b43_nphy_gain_ctl_workarounds_rev19(struct b43_wldev *dev)
+{
+ /* TODO */
+}
+
+static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
+{
+ struct b43_phy *phy = &dev->phy;
+
+ switch (phy->rev) {
+ /* TODO */
+ }
+}
+
+static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -2192,7 +2600,7 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
- if (!dev->phy.is_40mhz) {
+ if (!b43_is_40mhz(dev)) {
/* Set dwell lengths */
b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
@@ -2206,7 +2614,7 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
- if (!dev->phy.is_40mhz) {
+ if (!b43_is_40mhz(dev)) {
b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
@@ -2221,12 +2629,12 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
if (nphy->gain_boost) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
- dev->phy.is_40mhz)
+ b43_is_40mhz(dev))
code = 4;
else
code = 5;
} else {
- code = dev->phy.is_40mhz ? 6 : 7;
+ code = b43_is_40mhz(dev) ? 6 : 7;
}
/* Set HPVGA2 index */
@@ -2286,46 +2694,54 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
{
- if (dev->phy.rev >= 7)
- ; /* TODO */
+ if (dev->phy.rev >= 19)
+ b43_nphy_gain_ctl_workarounds_rev19(dev);
+ else if (dev->phy.rev >= 7)
+ b43_nphy_gain_ctl_workarounds_rev7(dev);
else if (dev->phy.rev >= 3)
- b43_nphy_gain_ctl_workarounds_rev3plus(dev);
+ b43_nphy_gain_ctl_workarounds_rev3(dev);
else
b43_nphy_gain_ctl_workarounds_rev1_2(dev);
}
-/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
-static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
-{
- if (!offset)
- offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
- return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
-}
-
static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct b43_phy *phy = &dev->phy;
+ /* TX to RX */
+ u8 tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, };
+ u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, };
+ /* RX to TX */
u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
0x1F };
u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
- u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
+ static const u16 ntab7_15e_16e[] = { 0, 0x10f, 0x10f };
u8 ntab7_138_146[] = { 0x11, 0x11 };
u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
- u16 lpf_20, lpf_40, lpf_11b;
- u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
- u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
+ u16 lpf_ofdm_20mhz[2], lpf_ofdm_40mhz[2], lpf_11b[2];
+ u16 bcap_val;
+ s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
+ u16 scap_val;
+ s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
bool rccal_ovrd = false;
- u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
u16 bias, conv, filt;
+ u32 noise_tbl[2];
+
u32 tmp32;
u8 core;
+ b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
+ b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01b3);
+ b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
+ b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016e);
+ b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00cd);
+ b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
+
if (phy->rev == 7) {
b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
@@ -2345,11 +2761,18 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
}
- if (phy->rev <= 8) {
+
+ if (phy->rev >= 16) {
+ b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x7ff);
+ b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x7ff);
+ } else if (phy->rev <= 8) {
b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0);
b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0);
}
- if (phy->rev >= 8)
+
+ if (phy->rev >= 16)
+ b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0xa0);
+ else if (phy->rev >= 8)
b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
@@ -2357,9 +2780,11 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
tmp32 &= 0xffffff;
b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
- b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
- b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
+ b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15d), 3, ntab7_15e_16e);
+ b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16d), 3, ntab7_15e_16e);
+ b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
+ ARRAY_SIZE(tx2rx_events));
if (b43_nphy_ipa(dev))
b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
@@ -2367,84 +2792,176 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000);
b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000);
- lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
- lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
- lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
+ for (core = 0; core < 2; core++) {
+ lpf_ofdm_20mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x154 + core * 0x10);
+ lpf_ofdm_40mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x159 + core * 0x10);
+ lpf_11b[core] = b43_nphy_read_lpf_ctl(dev, 0x152 + core * 0x10);
+ }
+
+ bcap_val = b43_radio_read(dev, R2057_RCCAL_BCAP_VAL);
+ scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
+
if (b43_nphy_ipa(dev)) {
- if ((phy->radio_rev == 5 && phy->is_40mhz) ||
- phy->radio_rev == 7 || phy->radio_rev == 8) {
- bcap_val = b43_radio_read(dev, 0x16b);
- scap_val = b43_radio_read(dev, 0x16a);
- scap_val_11b = scap_val;
- bcap_val_11b = bcap_val;
- if (phy->radio_rev == 5 && phy->is_40mhz) {
- scap_val_11n_20 = scap_val;
- bcap_val_11n_20 = bcap_val;
- scap_val_11n_40 = bcap_val_11n_40 = 0xc;
+ bool ghz2 = b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ;
+
+ switch (phy->radio_rev) {
+ case 5:
+ /* Check radio version (to be 0) by PHY rev for now */
+ if (phy->rev == 8 && b43_is_40mhz(dev)) {
+ for (core = 0; core < 2; core++) {
+ scap_val_11b[core] = scap_val;
+ bcap_val_11b[core] = bcap_val;
+ scap_val_11n_20[core] = scap_val;
+ bcap_val_11n_20[core] = bcap_val;
+ scap_val_11n_40[core] = 0xc;
+ bcap_val_11n_40[core] = 0xc;
+ }
+
rccal_ovrd = true;
- } else { /* Rev 7/8 */
- lpf_20 = 4;
- lpf_11b = 1;
+ }
+ if (phy->rev == 9) {
+ /* TODO: Radio version 1 (e.g. BCM5357B0) */
+ }
+ break;
+ case 7:
+ case 8:
+ for (core = 0; core < 2; core++) {
+ scap_val_11b[core] = scap_val;
+ bcap_val_11b[core] = bcap_val;
+ lpf_ofdm_20mhz[core] = 4;
+ lpf_11b[core] = 1;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
- scap_val_11n_20 = 0xc;
- bcap_val_11n_20 = 0xc;
- scap_val_11n_40 = 0xa;
- bcap_val_11n_40 = 0xa;
+ scap_val_11n_20[core] = 0xc;
+ bcap_val_11n_20[core] = 0xc;
+ scap_val_11n_40[core] = 0xa;
+ bcap_val_11n_40[core] = 0xa;
} else {
- scap_val_11n_20 = 0x14;
- bcap_val_11n_20 = 0x14;
- scap_val_11n_40 = 0xf;
- bcap_val_11n_40 = 0xf;
+ scap_val_11n_20[core] = 0x14;
+ bcap_val_11n_20[core] = 0x14;
+ scap_val_11n_40[core] = 0xf;
+ bcap_val_11n_40[core] = 0xf;
}
- rccal_ovrd = true;
}
+
+ rccal_ovrd = true;
+ break;
+ case 9:
+ for (core = 0; core < 2; core++) {
+ bcap_val_11b[core] = bcap_val;
+ scap_val_11b[core] = scap_val;
+ lpf_11b[core] = 1;
+
+ if (ghz2) {
+ bcap_val_11n_20[core] = bcap_val + 13;
+ scap_val_11n_20[core] = scap_val + 15;
+ } else {
+ bcap_val_11n_20[core] = bcap_val + 14;
+ scap_val_11n_20[core] = scap_val + 15;
+ }
+ lpf_ofdm_20mhz[core] = 4;
+
+ if (ghz2) {
+ bcap_val_11n_40[core] = bcap_val - 7;
+ scap_val_11n_40[core] = scap_val - 5;
+ } else {
+ bcap_val_11n_40[core] = bcap_val + 2;
+ scap_val_11n_40[core] = scap_val + 4;
+ }
+ lpf_ofdm_40mhz[core] = 4;
+ }
+
+ rccal_ovrd = true;
+ break;
+ case 14:
+ for (core = 0; core < 2; core++) {
+ bcap_val_11b[core] = bcap_val;
+ scap_val_11b[core] = scap_val;
+ lpf_11b[core] = 1;
+ }
+
+ bcap_val_11n_20[0] = bcap_val + 20;
+ scap_val_11n_20[0] = scap_val + 20;
+ lpf_ofdm_20mhz[0] = 3;
+
+ bcap_val_11n_20[1] = bcap_val + 16;
+ scap_val_11n_20[1] = scap_val + 16;
+ lpf_ofdm_20mhz[1] = 3;
+
+ bcap_val_11n_40[0] = bcap_val + 20;
+ scap_val_11n_40[0] = scap_val + 20;
+ lpf_ofdm_40mhz[0] = 4;
+
+ bcap_val_11n_40[1] = bcap_val + 10;
+ scap_val_11n_40[1] = scap_val + 10;
+ lpf_ofdm_40mhz[1] = 4;
+
+ rccal_ovrd = true;
+ break;
}
} else {
if (phy->radio_rev == 5) {
- lpf_20 = 1;
- lpf_40 = 3;
- bcap_val = b43_radio_read(dev, 0x16b);
- scap_val = b43_radio_read(dev, 0x16a);
- scap_val_11b = scap_val;
- bcap_val_11b = bcap_val;
- scap_val_11n_20 = 0x11;
- scap_val_11n_40 = 0x11;
- bcap_val_11n_20 = 0x13;
- bcap_val_11n_40 = 0x13;
+ for (core = 0; core < 2; core++) {
+ lpf_ofdm_20mhz[core] = 1;
+ lpf_ofdm_40mhz[core] = 3;
+ scap_val_11b[core] = scap_val;
+ bcap_val_11b[core] = bcap_val;
+ scap_val_11n_20[core] = 0x11;
+ scap_val_11n_40[core] = 0x11;
+ bcap_val_11n_20[core] = 0x13;
+ bcap_val_11n_40[core] = 0x13;
+ }
+
rccal_ovrd = true;
}
}
if (rccal_ovrd) {
- rx2tx_lut_20_11b = (bcap_val_11b << 8) |
- (scap_val_11b << 3) |
- lpf_11b;
- rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
- (scap_val_11n_20 << 3) |
- lpf_20;
- rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
- (scap_val_11n_40 << 3) |
- lpf_40;
+ u16 rx2tx_lut_20_11b[2], rx2tx_lut_20_11n[2], rx2tx_lut_40_11n[2];
+ u8 rx2tx_lut_extra = 1;
+
+ for (core = 0; core < 2; core++) {
+ bcap_val_11b[core] = clamp_val(bcap_val_11b[core], 0, 0x1f);
+ scap_val_11b[core] = clamp_val(scap_val_11b[core], 0, 0x1f);
+ bcap_val_11n_20[core] = clamp_val(bcap_val_11n_20[core], 0, 0x1f);
+ scap_val_11n_20[core] = clamp_val(scap_val_11n_20[core], 0, 0x1f);
+ bcap_val_11n_40[core] = clamp_val(bcap_val_11n_40[core], 0, 0x1f);
+ scap_val_11n_40[core] = clamp_val(scap_val_11n_40[core], 0, 0x1f);
+
+ rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
+ (bcap_val_11b[core] << 8) |
+ (scap_val_11b[core] << 3) |
+ lpf_11b[core];
+ rx2tx_lut_20_11n[core] = (rx2tx_lut_extra << 13) |
+ (bcap_val_11n_20[core] << 8) |
+ (scap_val_11n_20[core] << 3) |
+ lpf_ofdm_20mhz[core];
+ rx2tx_lut_40_11n[core] = (rx2tx_lut_extra << 13) |
+ (bcap_val_11n_40[core] << 8) |
+ (scap_val_11n_40[core] << 3) |
+ lpf_ofdm_40mhz[core];
+ }
+
for (core = 0; core < 2; core++) {
b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
- rx2tx_lut_20_11b);
+ rx2tx_lut_20_11b[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
- rx2tx_lut_20_11n);
+ rx2tx_lut_20_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
- rx2tx_lut_20_11n);
+ rx2tx_lut_20_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
- rx2tx_lut_40_11n);
+ rx2tx_lut_40_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
- rx2tx_lut_40_11n);
+ rx2tx_lut_40_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
- rx2tx_lut_40_11n);
+ rx2tx_lut_40_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
- rx2tx_lut_40_11n);
+ rx2tx_lut_40_11n[core]);
b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
- rx2tx_lut_40_11n);
+ rx2tx_lut_40_11n[core]);
}
- b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
}
+
b43_phy_write(dev, 0x32F, 0x3);
+
if (phy->radio_rev == 4 || phy->radio_rev == 6)
b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
@@ -2492,7 +3009,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
0x7f);
}
}
- if (phy->radio_rev == 3) {
+ switch (phy->radio_rev) {
+ case 3:
for (core = 0; core < 2; core++) {
if (core == 0) {
b43_radio_write(dev, 0x64,
@@ -2518,17 +3036,34 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
0x3E);
}
}
- } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
- if (!phy->is_40mhz) {
+ break;
+ case 7:
+ case 8:
+ if (!b43_is_40mhz(dev)) {
b43_radio_write(dev, 0x5F, 0x14);
b43_radio_write(dev, 0xE8, 0x12);
} else {
b43_radio_write(dev, 0x5F, 0x16);
b43_radio_write(dev, 0xE8, 0x16);
}
+ break;
+ case 14:
+ for (core = 0; core < 2; core++) {
+ int o = core ? 0x85 : 0;
+
+ b43_radio_write(dev, o + R2057_IPA2G_CASCONV_CORE0, 0x13);
+ b43_radio_write(dev, o + R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, 0x21);
+ b43_radio_write(dev, o + R2057_IPA2G_BIAS_FILTER_CORE0, 0xff);
+ b43_radio_write(dev, o + R2057_PAD2G_IDACS_CORE0, 0x88);
+ b43_radio_write(dev, o + R2057_PAD2G_TUNE_PUS_CORE0, 0x23);
+ b43_radio_write(dev, o + R2057_IPA2G_IMAIN_CORE0, 0x16);
+ b43_radio_write(dev, o + R2057_PAD_BIAS_FILTER_BWS_CORE0, 0x3e);
+ b43_radio_write(dev, o + R2057_BACKUP1_CORE0, 0x10);
+ }
+ break;
}
} else {
- u16 freq = phy->channel_freq;
+ u16 freq = phy->chandef->chan->center_freq;
if ((freq >= 5180 && freq <= 5230) ||
(freq >= 5745 && freq <= 5805)) {
b43_radio_write(dev, 0x7D, 0xFF);
@@ -2573,8 +3108,8 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
- b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
- b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0);
+ b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0);
b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
@@ -2585,20 +3120,20 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
- b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
+ b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x138), 2, ntab7_138_146);
b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
- b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
- b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
+ b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x133), 3, ntab7_133);
+ b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x146), 2, ntab7_138_146);
b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
- if (!phy->is_40mhz) {
- b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
- b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
- } else {
- b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
- b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
- }
+ b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x02), 1, noise_tbl);
+ noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
+ b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x02), 2, noise_tbl);
+
+ b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x7E), 1, noise_tbl);
+ noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
+ b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x7E), 2, noise_tbl);
b43_nphy_gain_ctl_workarounds(dev);
@@ -2691,7 +3226,7 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
- if (!dev->phy.is_40mhz) {
+ if (!b43_is_40mhz(dev)) {
b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
} else {
@@ -2926,6 +3461,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
b43_phy_set(dev, B43_NPHY_IQFLIP,
B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
+ /* TODO: rev19+ */
if (dev->phy.rev >= 7)
b43_nphy_workarounds_rev7plus(dev);
else if (dev->phy.rev >= 3)
@@ -2946,12 +3482,13 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
*/
static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
- bool iqmode, bool dac_test)
+ bool iqmode, bool dac_test, bool modify_bbmult)
{
u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
if (samp == 0)
return -1;
- b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
+ b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
+ modify_bbmult);
return 0;
}
@@ -2986,6 +3523,7 @@ static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
static void b43_nphy_stop_playback(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u16 tmp;
@@ -3006,6 +3544,15 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev)
nphy->bb_mult_save = 0;
}
+ if (phy->rev >= 7 && nphy->lpf_bw_overrode_for_sample_play) {
+ if (phy->rev >= 19)
+ b43_nphy_rf_ctl_override_rev19(dev, 0x80, 0, 0, true,
+ 1);
+ else
+ b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
+ nphy->lpf_bw_overrode_for_sample_play = false;
+ }
+
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 0);
}
@@ -3015,16 +3562,23 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
struct nphy_txgains target,
struct nphy_iqcal_params *params)
{
+ struct b43_phy *phy = &dev->phy;
int i, j, indx;
u16 gain;
if (dev->phy.rev >= 3) {
+ params->tx_lpf = target.tx_lpf[core]; /* Rev 7+ */
params->txgm = target.txgm[core];
params->pga = target.pga[core];
params->pad = target.pad[core];
params->ipa = target.ipa[core];
- params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
- (params->pad << 4) | (params->ipa);
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 3) | (params->ipa) | (params->tx_lpf << 15);
+ } else {
+ params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
+ }
for (j = 0; j < 5; j++)
params->ncorr[j] = 0x79;
} else {
@@ -3065,6 +3619,7 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u8 i;
u16 bmask, val, tmp;
@@ -3114,7 +3669,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
- if (dev->phy.rev < 2 && dev->phy.is_40mhz)
+ if (dev->phy.rev < 2 && b43_is_40mhz(dev))
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
} else {
b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
@@ -3134,12 +3689,25 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
if (band == IEEE80211_BAND_5GHZ) {
- b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
- ~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
- if (dev->phy.rev > 1)
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+ ~B43_NPHY_TXPCTL_CMD_INIT,
+ 0x32);
b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
~B43_NPHY_TXPCTL_INIT_PIDXI1,
+ 0x32);
+ } else {
+ b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+ ~B43_NPHY_TXPCTL_CMD_INIT,
0x64);
+ if (phy->rev > 1)
+ b43_phy_maskset(dev,
+ B43_NPHY_TXPCTL_INIT,
+ ~B43_NPHY_TXPCTL_INIT_PIDXI1,
+ 0x64);
+ }
}
if (dev->phy.rev >= 3) {
@@ -3156,6 +3724,10 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
}
}
+ if (phy->rev >= 7) {
+ /* TODO */
+ }
+
if (dev->phy.rev >= 3) {
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
@@ -3168,7 +3740,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
else if (dev->phy.rev < 2)
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
- if (dev->phy.rev < 2 && dev->phy.is_40mhz)
+ if (dev->phy.rev < 2 && b43_is_40mhz(dev))
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
if (b43_nphy_ipa(dev)) {
@@ -3184,18 +3756,20 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
struct ssb_sprom *sprom = dev->dev->bus_sprom;
u8 txpi[2], bbmult, i;
u16 tmp, radio_gain, dac_gain;
- u16 freq = dev->phy.channel_freq;
+ u16 freq = phy->chandef->chan->center_freq;
u32 txgain;
/* u32 gaintbl; rev3+ */
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 1);
+ /* TODO: rev19+ */
if (dev->phy.rev >= 7) {
txpi[0] = txpi[1] = 30;
} else if (dev->phy.rev >= 3) {
@@ -3234,7 +3808,11 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
*/
for (i = 0; i < 2; i++) {
- txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
+ const u32 *table = b43_nphy_get_tx_gain_table(dev);
+
+ if (!table)
+ break;
+ txgain = *(table + txpi[i]);
if (dev->phy.rev >= 3)
radio_gain = (txgain >> 16) & 0x1FFFF;
@@ -3294,7 +3872,9 @@ static void b43_nphy_ipa_internal_tssi_setup(struct b43_wldev *dev)
u8 core;
u16 r; /* routing */
- if (phy->rev >= 7) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
for (core = 0; core < 2; core++) {
r = core ? 0x190 : 0x170;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
@@ -3377,29 +3957,38 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
u32 tmp;
s32 rssi[4] = { };
- /* TODO: check if we can transmit */
+ if (phy->chandef->chan->flags & IEEE80211_CHAN_NO_IR)
+ return;
if (b43_nphy_ipa(dev))
b43_nphy_ipa_internal_tssi_setup(dev);
- if (phy->rev >= 7)
- b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
+ if (phy->rev >= 19)
+ b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, false, 0);
+ else if (phy->rev >= 7)
+ b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, false, 0);
else if (phy->rev >= 3)
b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
b43_nphy_stop_playback(dev);
- b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
+ b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
udelay(20);
tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
b43_nphy_stop_playback(dev);
+
b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
- if (phy->rev >= 7)
- b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
+ if (phy->rev >= 19)
+ b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, true, 0);
+ else if (phy->rev >= 7)
+ b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, true, 0);
else if (phy->rev >= 3)
b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
- if (phy->rev >= 3) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ return;
+ } else if (phy->rev >= 3) {
nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
} else {
@@ -3439,21 +4028,21 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
delta = 0;
switch (stf_mode) {
case 0:
- if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
+ if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
idx = 68;
} else {
delta = 1;
- idx = dev->phy.is_40mhz ? 52 : 4;
+ idx = b43_is_40mhz(dev) ? 52 : 4;
}
break;
case 1:
- idx = dev->phy.is_40mhz ? 76 : 28;
+ idx = b43_is_40mhz(dev) ? 76 : 28;
break;
case 2:
- idx = dev->phy.is_40mhz ? 84 : 36;
+ idx = b43_is_40mhz(dev) ? 84 : 36;
break;
case 3:
- idx = dev->phy.is_40mhz ? 92 : 44;
+ idx = b43_is_40mhz(dev) ? 92 : 44;
break;
}
@@ -3474,6 +4063,7 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -3483,7 +4073,7 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
s32 num, den, pwr;
u32 regval[64];
- u16 freq = dev->phy.channel_freq;
+ u16 freq = phy->chandef->chan->center_freq;
u16 tmp;
u16 r; /* routing */
u8 i, c;
@@ -3590,7 +4180,9 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
udelay(1);
}
- if (dev->phy.rev >= 7) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
@@ -3647,27 +4239,36 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
int i;
table = b43_nphy_get_tx_gain_table(dev);
+ if (!table)
+ return;
+
b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
- if (phy->rev >= 3) {
+ if (phy->rev < 3)
+ return;
+
#if 0
- nphy->gmval = (table[0] >> 16) & 0x7000;
+ nphy->gmval = (table[0] >> 16) & 0x7000;
#endif
- for (i = 0; i < 128; i++) {
+ for (i = 0; i < 128; i++) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ return;
+ } else if (phy->rev >= 7) {
+ /* TODO */
+ return;
+ } else {
pga_gain = (table[i] >> 24) & 0xF;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- rfpwr_offset =
- b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
+ rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
else
- rfpwr_offset =
- 0; /* FIXME */
- b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
- rfpwr_offset);
- b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
- rfpwr_offset);
+ rfpwr_offset = 0; /* FIXME */
}
+
+ b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
+ b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
}
}
@@ -3684,7 +4285,9 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
nphy->rfctrl_intc2_save = b43_phy_read(dev,
B43_NPHY_RFCTL_INTC2);
band = b43_current_band(dev->wl);
- if (dev->phy.rev >= 3) {
+ if (dev->phy.rev >= 7) {
+ tmp = 0x1480;
+ } else if (dev->phy.rev >= 3) {
if (band == IEEE80211_BAND_5GHZ)
tmp = 0x600;
else
@@ -3705,21 +4308,28 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
}
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
-static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
+/*
+ * TX low-pass filter bandwidth setup
+ * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
+ */
+static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
{
u16 tmp;
- if (dev->phy.rev >= 3) {
- if (b43_nphy_ipa(dev)) {
- tmp = 4;
- b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
- (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
- }
+ if (dev->phy.rev < 3 || dev->phy.rev >= 7)
+ return;
+
+ if (b43_nphy_ipa(dev))
+ tmp = b43_is_40mhz(dev) ? 5 : 4;
+ else
+ tmp = b43_is_40mhz(dev) ? 3 : 1;
+ b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
+ (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
- tmp = 1;
+ if (b43_nphy_ipa(dev)) {
+ tmp = b43_is_40mhz(dev) ? 4 : 1;
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
- (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
+ (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
}
}
@@ -3992,7 +4602,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
if (nphy->gband_spurwar_en) {
/* TODO: N PHY Adjust Analog Pfbw (7) */
- if (channel == 11 && dev->phy.is_40mhz)
+ if (channel == 11 && b43_is_40mhz(dev))
; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
else
; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
@@ -4124,7 +4734,13 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
}
- if (dev->phy.rev >= 7) {
+ if (dev->phy.rev >= 19) {
+ /* TODO */
+ } else if (dev->phy.rev >= 7) {
+ b43_radio_maskset(dev, R2057_NB_MASTER_CORE0, ~R2057_VCM_MASK,
+ rssical_radio_regs[0]);
+ b43_radio_maskset(dev, R2057_NB_MASTER_CORE1, ~R2057_VCM_MASK,
+ rssical_radio_regs[1]);
} else {
b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
rssical_radio_regs[0]);
@@ -4148,15 +4764,78 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
}
+static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
+{
+ /* TODO */
+}
+
+static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
+{
+ struct b43_phy *phy = &dev->phy;
+ struct b43_phy_n *nphy = dev->phy.n;
+ u16 *save = nphy->tx_rx_cal_radio_saveregs;
+ int core, off;
+ u16 r, tmp;
+
+ for (core = 0; core < 2; core++) {
+ r = core ? 0x20 : 0;
+ off = core * 11;
+
+ save[off + 0] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MASTER);
+ save[off + 1] = b43_radio_read(dev, r + R2057_TX0_IQCAL_VCM_HG);
+ save[off + 2] = b43_radio_read(dev, r + R2057_TX0_IQCAL_IDAC);
+ save[off + 3] = b43_radio_read(dev, r + R2057_TX0_TSSI_VCM);
+ save[off + 4] = 0;
+ save[off + 5] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MUX);
+ if (phy->radio_rev != 5)
+ save[off + 6] = b43_radio_read(dev, r + R2057_TX0_TSSIA);
+ save[off + 7] = b43_radio_read(dev, r + R2057_TX0_TSSIG);
+ save[off + 8] = b43_radio_read(dev, r + R2057_TX0_TSSI_MISC1);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0xA);
+ b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
+ b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
+ b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
+ b43_radio_write(dev, r + R2057_TX0_TSSIG, 0);
+ if (nphy->use_int_tx_iq_lo_cal) {
+ b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x4);
+ tmp = true ? 0x31 : 0x21; /* TODO */
+ b43_radio_write(dev, r + R2057_TX0_TSSIA, tmp);
+ }
+ b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
+ } else {
+ b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0x6);
+ b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
+ b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
+ b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
+
+ if (phy->radio_rev != 5)
+ b43_radio_write(dev, r + R2057_TX0_TSSIA, 0);
+ if (nphy->use_int_tx_iq_lo_cal) {
+ b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x6);
+ tmp = true ? 0x31 : 0x21; /* TODO */
+ b43_radio_write(dev, r + R2057_TX0_TSSIG, tmp);
+ }
+ b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
+ }
+ }
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u16 *save = nphy->tx_rx_cal_radio_saveregs;
u16 tmp;
u8 offset, i;
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ b43_nphy_tx_cal_radio_setup_rev19(dev);
+ } else if (phy->rev >= 7) {
+ b43_nphy_tx_cal_radio_setup_rev7(dev);
+ } else if (phy->rev >= 3) {
for (i = 0; i < 2; i++) {
tmp = (i == 0) ? 0x2000 : 0x3000;
offset = i * 11;
@@ -4265,41 +4944,62 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
}
}
+static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
+ const s16 *filter)
+{
+ int i;
+
+ offset = B43_PHY_N(offset);
+
+ for (i = 0; i < 15; i++, offset++)
+ b43_phy_write(dev, offset, filter[i]);
+}
+
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
- int i;
- for (i = 0; i < 15; i++)
- b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
- tbl_tx_filter_coef_rev4[2][i]);
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x2C5,
+ tbl_tx_filter_coef_rev4[2]);
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
{
- int i, j;
/* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
+ static const s16 dig_filter_phy_rev16[] = {
+ -375, 136, -407, 208, -1527,
+ 956, 93, 186, 93, 230,
+ -44, 230, 201, -191, 201,
+ };
+ int i;
for (i = 0; i < 3; i++)
- for (j = 0; j < 15; j++)
- b43_phy_write(dev, B43_PHY_N(offset[i] + j),
- tbl_tx_filter_coef_rev4[i][j]);
-
- if (dev->phy.is_40mhz) {
- for (j = 0; j < 15; j++)
- b43_phy_write(dev, B43_PHY_N(offset[0] + j),
- tbl_tx_filter_coef_rev4[3][j]);
- } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- for (j = 0; j < 15; j++)
- b43_phy_write(dev, B43_PHY_N(offset[0] + j),
- tbl_tx_filter_coef_rev4[5][j]);
- }
-
- if (dev->phy.channel == 14)
- for (j = 0; j < 15; j++)
- b43_phy_write(dev, B43_PHY_N(offset[0] + j),
- tbl_tx_filter_coef_rev4[6][j]);
+ b43_nphy_pa_set_tx_dig_filter(dev, offset[i],
+ tbl_tx_filter_coef_rev4[i]);
+
+ /* Verified with BCM43227 and BCM43228 */
+ if (dev->phy.rev == 16)
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
+
+ /* Verified with BCM43131 and BCM43217 */
+ if (dev->phy.rev == 17) {
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x195,
+ tbl_tx_filter_coef_rev4[1]);
+ }
+
+ if (b43_is_40mhz(dev)) {
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
+ tbl_tx_filter_coef_rev4[3]);
+ } else {
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
+ tbl_tx_filter_coef_rev4[5]);
+ if (dev->phy.channel == 14)
+ b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
+ tbl_tx_filter_coef_rev4[6]);
+ }
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
@@ -4321,7 +5021,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
b43_nphy_stay_in_carrier_search(dev, false);
for (i = 0; i < 2; ++i) {
- if (dev->phy.rev >= 3) {
+ if (dev->phy.rev >= 7) {
+ target.ipa[i] = curr_gain[i] & 0x0007;
+ target.pad[i] = (curr_gain[i] & 0x00F8) >> 3;
+ target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
+ target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
+ target.tx_lpf[i] = (curr_gain[i] & 0x8000) >> 15;
+ } else if (dev->phy.rev >= 3) {
target.ipa[i] = curr_gain[i] & 0x000F;
target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
@@ -4345,7 +5051,16 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
for (i = 0; i < 2; ++i) {
table = b43_nphy_get_tx_gain_table(dev);
- if (dev->phy.rev >= 3) {
+ if (!table)
+ break;
+
+ if (dev->phy.rev >= 7) {
+ target.ipa[i] = (table[index[i]] >> 16) & 0x7;
+ target.pad[i] = (table[index[i]] >> 19) & 0x1F;
+ target.pga[i] = (table[index[i]] >> 24) & 0xF;
+ target.txgm[i] = (table[index[i]] >> 28) & 0x7;
+ target.tx_lpf[i] = (table[index[i]] >> 31) & 0x1;
+ } else if (dev->phy.rev >= 3) {
target.ipa[i] = (table[index[i]] >> 16) & 0xF;
target.pad[i] = (table[index[i]] >> 20) & 0xF;
target.pga[i] = (table[index[i]] >> 24) & 0xF;
@@ -4394,6 +5109,8 @@ static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
+ struct b43_phy_n *nphy = dev->phy.n;
u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
u16 tmp;
@@ -4425,7 +5142,12 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
- b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
+ if (!nphy->use_int_tx_iq_lo_cal)
+ b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
+ 1, 3);
+ else
+ b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
+ 0, 3);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
@@ -4433,6 +5155,33 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
+
+ tmp = b43_nphy_read_lpf_ctl(dev, 0);
+ if (phy->rev >= 19)
+ b43_nphy_rf_ctl_override_rev19(dev, 0x80, tmp, 0, false,
+ 1);
+ else if (phy->rev >= 7)
+ b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
+ 1);
+
+ if (nphy->use_int_tx_iq_lo_cal && true /* FIXME */) {
+ if (phy->rev >= 19) {
+ b43_nphy_rf_ctl_override_rev19(dev, 0x8, 0, 0x3,
+ false, 0);
+ } else if (phy->rev >= 8) {
+ b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
+ false, 0);
+ } else if (phy->rev == 7) {
+ b43_radio_maskset(dev, R2057_OVR_REG0, 1 << 4, 1 << 4);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE0, ~1, 0);
+ b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE1, ~1, 0);
+ } else {
+ b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
+ b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
+ }
+ }
+ }
} else {
b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
@@ -4461,6 +5210,7 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
static void b43_nphy_save_cal(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
@@ -4485,7 +5235,26 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
/* TODO use some definitions */
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ txcal_radio_regs[0] = b43_radio_read(dev,
+ R2057_TX0_LOFT_FINE_I);
+ txcal_radio_regs[1] = b43_radio_read(dev,
+ R2057_TX0_LOFT_FINE_Q);
+ txcal_radio_regs[4] = b43_radio_read(dev,
+ R2057_TX0_LOFT_COARSE_I);
+ txcal_radio_regs[5] = b43_radio_read(dev,
+ R2057_TX0_LOFT_COARSE_Q);
+ txcal_radio_regs[2] = b43_radio_read(dev,
+ R2057_TX1_LOFT_FINE_I);
+ txcal_radio_regs[3] = b43_radio_read(dev,
+ R2057_TX1_LOFT_FINE_Q);
+ txcal_radio_regs[6] = b43_radio_read(dev,
+ R2057_TX1_LOFT_COARSE_I);
+ txcal_radio_regs[7] = b43_radio_read(dev,
+ R2057_TX1_LOFT_COARSE_Q);
+ } else if (phy->rev >= 3) {
txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
@@ -4500,8 +5269,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
}
- iqcal_chanspec->center_freq = dev->phy.channel_freq;
- iqcal_chanspec->channel_type = dev->phy.channel_type;
+ iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
+ iqcal_chanspec->channel_type =
+ cfg80211_get_chandef_type(dev->phy.chandef);
b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
if (nphy->hang_avoid)
@@ -4511,6 +5281,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
static void b43_nphy_restore_cal(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u16 coef[4];
@@ -4558,7 +5329,26 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
}
/* TODO use some definitions */
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ b43_radio_write(dev, R2057_TX0_LOFT_FINE_I,
+ txcal_radio_regs[0]);
+ b43_radio_write(dev, R2057_TX0_LOFT_FINE_Q,
+ txcal_radio_regs[1]);
+ b43_radio_write(dev, R2057_TX0_LOFT_COARSE_I,
+ txcal_radio_regs[4]);
+ b43_radio_write(dev, R2057_TX0_LOFT_COARSE_Q,
+ txcal_radio_regs[5]);
+ b43_radio_write(dev, R2057_TX1_LOFT_FINE_I,
+ txcal_radio_regs[2]);
+ b43_radio_write(dev, R2057_TX1_LOFT_FINE_Q,
+ txcal_radio_regs[3]);
+ b43_radio_write(dev, R2057_TX1_LOFT_COARSE_I,
+ txcal_radio_regs[6]);
+ b43_radio_write(dev, R2057_TX1_LOFT_COARSE_Q,
+ txcal_radio_regs[7]);
+ } else if (phy->rev >= 3) {
b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
@@ -4581,6 +5371,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
struct nphy_txgains target,
bool full, bool mphase)
{
+ struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
int i;
int error = 0;
@@ -4621,7 +5412,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
(dev->phy.rev == 5 && nphy->ipa2g_on &&
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
if (phy6or5x) {
- if (dev->phy.is_40mhz) {
+ if (b43_is_40mhz(dev)) {
b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
tbl_tx_iqlo_cal_loft_ladder_40);
b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
@@ -4634,18 +5425,24 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
}
}
- b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
+ } else {
+ b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
+ }
- if (!dev->phy.is_40mhz)
+ if (!b43_is_40mhz(dev))
freq = 2500;
else
freq = 5000;
if (nphy->mphase_cal_phase_id > 2)
- b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
- 0xFFFF, 0, true, false);
+ b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
+ 0xFFFF, 0, true, false, false);
else
- error = b43_nphy_tx_tone(dev, freq, 250, true, false);
+ error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
if (error == 0) {
if (nphy->mphase_cal_phase_id > 2) {
@@ -4773,9 +5570,9 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
nphy->txiqlocal_bestc);
nphy->txiqlocal_coeffsvalid = true;
nphy->txiqlocal_chanspec.center_freq =
- dev->phy.channel_freq;
+ phy->chandef->chan->center_freq;
nphy->txiqlocal_chanspec.channel_type =
- dev->phy.channel_type;
+ cfg80211_get_chandef_type(phy->chandef);
} else {
length = 11;
if (dev->phy.rev < 3)
@@ -4811,8 +5608,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
bool equal = true;
if (!nphy->txiqlocal_coeffsvalid ||
- nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
- nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
+ nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
+ nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
return;
b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -4968,11 +5765,11 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
if (playtone) {
ret = b43_nphy_tx_tone(dev, 4000,
(nphy->rxcalparams & 0xFFFF),
- false, false);
+ false, false, true);
playtone = false;
} else {
- b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
- false, false);
+ b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
+ false, true);
}
if (ret == 0) {
@@ -5028,6 +5825,9 @@ static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
struct nphy_txgains target, u8 type, bool debug)
{
+ if (dev->phy.rev >= 7)
+ type = 0;
+
if (dev->phy.rev >= 3)
return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
else
@@ -5114,6 +5914,9 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
{
+ if (dev->phy.rev >= 7)
+ return;
+
if (dev->phy.rev >= 3) {
if (!init)
return;
@@ -5189,6 +5992,10 @@ static int b43_phy_initn(struct b43_wldev *dev)
#endif
}
}
+ nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
+ phy->rev >= 7 ||
+ (phy->rev >= 5 &&
+ sprom->boardflags2_hi & B43_BFH2_INTERNDET_TXIQCAL);
nphy->deaf_count = 0;
b43_nphy_tables_init(dev);
nphy->crsminpwr_adjusted = false;
@@ -5198,6 +6005,16 @@ static int b43_phy_initn(struct b43_wldev *dev)
if (dev->phy.rev >= 3) {
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
+ if (phy->rev >= 7) {
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0);
+ b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0);
+ }
+ if (phy->rev >= 19) {
+ /* TODO */
+ }
+
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
} else {
@@ -5235,7 +6052,9 @@ static int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
- b43_nphy_update_mimo_config(dev, nphy->preamble_override);
+ if (phy->rev < 8)
+ b43_nphy_update_mimo_config(dev, nphy->preamble_override);
+
b43_nphy_update_txrx_chain(dev);
if (phy->rev < 2) {
@@ -5267,10 +6086,12 @@ static int b43_phy_initn(struct b43_wldev *dev)
b43_mac_phy_clock_set(dev, true);
- b43_nphy_pa_override(dev, false);
- b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
- b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
- b43_nphy_pa_override(dev, true);
+ if (phy->rev < 7) {
+ b43_nphy_pa_override(dev, false);
+ b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
+ b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+ b43_nphy_pa_override(dev, true);
+ }
b43_nphy_classifier(dev, 0, 0);
b43_nphy_read_clip_detection(dev, clip);
@@ -5344,7 +6165,7 @@ static int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
if (phy->rev >= 3 && phy->rev <= 6)
b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
- b43_nphy_tx_lp_fbw(dev);
+ b43_nphy_tx_lpf_bw(dev);
if (phy->rev >= 3)
b43_nphy_spur_workaround(dev);
@@ -5393,23 +6214,26 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
int ch = new_channel->hw_value;
-
- u16 old_band_5ghz;
u16 tmp16;
- old_band_5ghz =
- b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
- if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
+ if (new_channel->band == IEEE80211_BAND_5GHZ) {
+ /* Switch to 2 GHz for a moment to access B43_PHY_B_BBCFG */
+ b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
+
tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
- b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
+ /* Put BPHY in the reset */
+ b43_phy_set(dev, B43_PHY_B_BBCFG,
+ B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX);
b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
- } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
+ } else if (new_channel->band == IEEE80211_BAND_2GHZ) {
b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
- b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
+ /* Take BPHY out of the reset */
+ b43_phy_mask(dev, B43_PHY_B_BBCFG,
+ (u16)~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX));
b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
}
@@ -5430,35 +6254,49 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
if (dev->phy.rev < 3)
b43_nphy_adjust_lna_gain_table(dev);
- b43_nphy_tx_lp_fbw(dev);
+ b43_nphy_tx_lpf_bw(dev);
if (dev->phy.rev >= 3 &&
dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
- bool avoid = false;
+ u8 spuravoid = 0;
+
if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
- avoid = true;
- } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
- if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
- avoid = true;
- } else { /* 40MHz */
- if (nphy->aband_spurwar_en &&
- (ch == 38 || ch == 102 || ch == 118))
- avoid = dev->dev->chip_id == 0x4716;
+ spuravoid = 1;
+ } else if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 18) {
+ /* TODO */
+ } else if (phy->rev >= 17) {
+ /* TODO: Off for channels 1-11, but check 12-14! */
+ } else if (phy->rev >= 16) {
+ /* TODO: Off for 2 GHz, but check 5 GHz! */
+ } else if (phy->rev >= 7) {
+ if (!b43_is_40mhz(dev)) { /* 20MHz */
+ if (ch == 13 || ch == 14 || ch == 153)
+ spuravoid = 1;
+ } else { /* 40 MHz */
+ if (ch == 54)
+ spuravoid = 1;
+ }
+ } else {
+ if (!b43_is_40mhz(dev)) { /* 20MHz */
+ if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
+ spuravoid = 1;
+ } else { /* 40MHz */
+ if (nphy->aband_spurwar_en &&
+ (ch == 38 || ch == 102 || ch == 118))
+ spuravoid = dev->dev->chip_id == 0x4716;
+ }
}
- b43_nphy_pmu_spur_avoid(dev, avoid);
+ b43_nphy_pmu_spur_avoid(dev, spuravoid);
- if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
- dev->dev->chip_id == 43225) {
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
- avoid ? 0x5341 : 0x8889);
- b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
- }
+ b43_mac_switch_freq(dev, spuravoid);
if (dev->phy.rev == 3 || dev->phy.rev == 4)
; /* TODO: reset PLL */
- if (avoid)
+ if (spuravoid)
b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
else
b43_phy_mask(dev, B43_NPHY_BBCFG,
@@ -5484,10 +6322,20 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
+ const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
+ const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
u8 tmp;
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ return -ESRCH;
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ r2057_get_chantabent_rev7(dev, channel->center_freq,
+ &tabent_r7, &tabent_r7_2g);
+ if (!tabent_r7 && !tabent_r7_2g)
+ return -ESRCH;
+ } else if (phy->rev >= 3) {
tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
channel->center_freq);
if (!tabent_r3)
@@ -5502,20 +6350,38 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
/* Channel is set later in common code, but we need to set it on our
own to let this function's subcalls work properly. */
phy->channel = channel->hw_value;
- phy->channel_freq = channel->center_freq;
+#if 0
if (b43_channel_type_is_40mhz(phy->channel_type) !=
b43_channel_type_is_40mhz(channel_type))
; /* TODO: BMAC BW Set (channel_type) */
+#endif
- if (channel_type == NL80211_CHAN_HT40PLUS)
- b43_phy_set(dev, B43_NPHY_RXCTL,
- B43_NPHY_RXCTL_BSELU20);
- else if (channel_type == NL80211_CHAN_HT40MINUS)
- b43_phy_mask(dev, B43_NPHY_RXCTL,
- ~B43_NPHY_RXCTL_BSELU20);
+ if (channel_type == NL80211_CHAN_HT40PLUS) {
+ b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
+ if (phy->rev >= 7)
+ b43_phy_set(dev, 0x310, 0x8000);
+ } else if (channel_type == NL80211_CHAN_HT40MINUS) {
+ b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
+ if (phy->rev >= 7)
+ b43_phy_mask(dev, 0x310, (u16)~0x8000);
+ }
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
+ const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
+ &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
+
+ if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
+ tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
+ b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
+ b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
+ }
+
+ b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
+ b43_nphy_channel_setup(dev, phy_regs, channel);
+ } else if (phy->rev >= 3) {
tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
b43_radio_2056_setup(dev, tabent_r3);
@@ -5656,7 +6522,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
{
/* Register 1 is a 32-bit register. */
- B43_WARN_ON(reg == 1);
+ B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
if (dev->phy.rev >= 7)
reg |= 0x200; /* Radio 0x2057 */
@@ -5670,7 +6536,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
{
/* Register 1 is a 32-bit register. */
- B43_WARN_ON(reg == 1);
+ B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
@@ -5680,15 +6546,23 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
bool blocked)
{
+ struct b43_phy *phy = &dev->phy;
+
if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
b43err(dev->wl, "MAC not suspended\n");
if (blocked) {
- b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
- ~B43_NPHY_RFCTL_CMD_CHIP0PU);
- if (dev->phy.rev >= 7) {
+ if (phy->rev >= 19) {
/* TODO */
- } else if (dev->phy.rev >= 3) {
+ } else if (phy->rev >= 8) {
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_CHIP0PU);
+ } else if (phy->rev >= 7) {
+ /* Nothing needed */
+ } else if (phy->rev >= 3) {
+ b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+ ~B43_NPHY_RFCTL_CMD_CHIP0PU);
+
b43_radio_mask(dev, 0x09, ~0x2);
b43_radio_write(dev, 0x204D, 0);
@@ -5706,11 +6580,13 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
b43_radio_write(dev, 0x3064, 0);
}
} else {
- if (dev->phy.rev >= 7) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 7) {
if (!dev->phy.radio_on)
b43_radio_2057_init(dev);
b43_switch_channel(dev, dev->phy.channel);
- } else if (dev->phy.rev >= 3) {
+ } else if (phy->rev >= 3) {
if (!dev->phy.radio_on)
b43_radio_init2056(dev);
b43_switch_channel(dev, dev->phy.channel);
@@ -5723,10 +6599,13 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
{
+ struct b43_phy *phy = &dev->phy;
u16 override = on ? 0x0 : 0x7FFF;
u16 core = on ? 0xD : 0x00FD;
- if (dev->phy.rev >= 3) {
+ if (phy->rev >= 19) {
+ /* TODO */
+ } else if (phy->rev >= 3) {
if (on) {
b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index ecfbf66dbc3b..30bec815b969 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -366,11 +366,13 @@
#define B43_NPHY_TXF_40CO_B1S0 B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
#define B43_NPHY_TXF_40CO_B32S1 B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
#define B43_NPHY_TXF_40CO_B1S1 B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
+#define B43_NPHY_REV3_RFCTL_OVER0 B43_PHY_N(0x0E7)
#define B43_NPHY_TXF_40CO_B32S2 B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
#define B43_NPHY_TXF_40CO_B1S2 B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
#define B43_NPHY_BIST_STAT2 B43_PHY_N(0x0EA) /* BIST status 2 */
#define B43_NPHY_BIST_STAT3 B43_PHY_N(0x0EB) /* BIST status 3 */
#define B43_NPHY_RFCTL_OVER B43_PHY_N(0x0EC) /* RF control override */
+#define B43_NPHY_REV3_RFCTL_OVER1 B43_PHY_N(0x0EC)
#define B43_NPHY_MIMOCFG B43_PHY_N(0x0ED) /* MIMO config */
#define B43_NPHY_MIMOCFG_GFMIX 0x0004 /* Greenfield or mixed mode */
#define B43_NPHY_MIMOCFG_AUTO 0x0100 /* Greenfield/mixed mode auto */
@@ -857,7 +859,18 @@
#define B43_NPHY_REV3_C2_CLIP2_GAIN_A B43_PHY_N(0x2AF)
#define B43_NPHY_REV3_C2_CLIP2_GAIN_B B43_PHY_N(0x2B0)
+#define B43_NPHY_REV7_RF_CTL_MISC_REG3 B43_PHY_N(0x340)
+#define B43_NPHY_REV7_RF_CTL_MISC_REG4 B43_PHY_N(0x341)
+#define B43_NPHY_REV7_RF_CTL_OVER3 B43_PHY_N(0x342)
+#define B43_NPHY_REV7_RF_CTL_OVER4 B43_PHY_N(0x343)
+#define B43_NPHY_REV7_RF_CTL_MISC_REG5 B43_PHY_N(0x344)
+#define B43_NPHY_REV7_RF_CTL_MISC_REG6 B43_PHY_N(0x345)
+#define B43_NPHY_REV7_RF_CTL_OVER5 B43_PHY_N(0x346)
+#define B43_NPHY_REV7_RF_CTL_OVER6 B43_PHY_N(0x347)
+
#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
+#define B43_PHY_B_BBCFG_RSTCCA 0x4000 /* Reset CCA */
+#define B43_PHY_B_BBCFG_RSTRX 0x8000 /* Reset RX */
#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
struct b43_wldev;
@@ -935,6 +948,8 @@ struct b43_phy_n {
bool gain_boost;
bool elna_gain_config;
bool band5g_pwrgain;
+ bool use_int_tx_iq_lo_cal;
+ bool lpf_bw_overrode_for_sample_play;
u8 mphase_cal_phase_id;
u16 mphase_txcal_cmdidx;
diff --git a/drivers/net/wireless/b43/radio_2057.c b/drivers/net/wireless/b43/radio_2057.c
index d61d6830c5c7..ff1e026a61a1 100644
--- a/drivers/net/wireless/b43/radio_2057.c
+++ b/drivers/net/wireless/b43/radio_2057.c
@@ -26,7 +26,7 @@
#include "radio_2057.h"
#include "phy_common.h"
-static u16 r2057_rev4_init[42][2] = {
+static u16 r2057_rev4_init[][2] = {
{ 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
{ 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
{ 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
@@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
{ 0x1AB, 0x00 }, { 0x1AC, 0x00 },
};
-static u16 r2057_rev5_init[44][2] = {
+static u16 r2057_rev5_init[][2] = {
{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
@@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
{ 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
};
-static u16 r2057_rev5a_init[45][2] = {
+static u16 r2057_rev5a_init[][2] = {
{ 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
{ 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
{ 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
@@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
{ 0x1C2, 0x80 },
};
-static u16 r2057_rev7_init[54][2] = {
+static u16 r2057_rev7_init[][2] = {
{ 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
@@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
};
-static u16 r2057_rev8_init[54][2] = {
+/* TODO: Which devices should use it?
+static u16 r2057_rev8_init[][2] = {
{ 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
{ 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
{ 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
@@ -102,6 +103,436 @@ static u16 r2057_rev8_init[54][2] = {
{ 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
{ 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
};
+*/
+
+/* Extracted from MMIO dump of 6.30.223.141 */
+static u16 r2057_rev9_init[][2] = {
+ { 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
+ { 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
+ { 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
+ { 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
+ { 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
+ { 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
+ { 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
+ { 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
+};
+
+/* Extracted from MMIO dump of 6.30.223.248 */
+static u16 r2057_rev14_init[][2] = {
+ { 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
+ { 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
+ { 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
+ { 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
+ { 0x1d4, 0x0f },
+};
+
+#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
+ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
+ r20, r21, r22, r23, r24, r25, r26, r27) \
+ .radio_vcocal_countval0 = r00, \
+ .radio_vcocal_countval1 = r01, \
+ .radio_rfpll_refmaster_sparextalsize = r02, \
+ .radio_rfpll_loopfilter_r1 = r03, \
+ .radio_rfpll_loopfilter_c2 = r04, \
+ .radio_rfpll_loopfilter_c1 = r05, \
+ .radio_cp_kpd_idac = r06, \
+ .radio_rfpll_mmd0 = r07, \
+ .radio_rfpll_mmd1 = r08, \
+ .radio_vcobuf_tune = r09, \
+ .radio_logen_mx2g_tune = r10, \
+ .radio_logen_mx5g_tune = r11, \
+ .radio_logen_indbuf2g_tune = r12, \
+ .radio_logen_indbuf5g_tune = r13, \
+ .radio_txmix2g_tune_boost_pu_core0 = r14, \
+ .radio_pad2g_tune_pus_core0 = r15, \
+ .radio_pga_boost_tune_core0 = r16, \
+ .radio_txmix5g_boost_tune_core0 = r17, \
+ .radio_pad5g_tune_misc_pus_core0 = r18, \
+ .radio_lna2g_tune_core0 = r19, \
+ .radio_lna5g_tune_core0 = r20, \
+ .radio_txmix2g_tune_boost_pu_core1 = r21, \
+ .radio_pad2g_tune_pus_core1 = r22, \
+ .radio_pga_boost_tune_core1 = r23, \
+ .radio_txmix5g_boost_tune_core1 = r24, \
+ .radio_pad5g_tune_misc_pus_core1 = r25, \
+ .radio_lna2g_tune_core1 = r26, \
+ .radio_lna5g_tune_core1 = r27
+
+#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
+ r10, r11, r12, r13, r14, r15, r16, r17) \
+ .radio_vcocal_countval0 = r00, \
+ .radio_vcocal_countval1 = r01, \
+ .radio_rfpll_refmaster_sparextalsize = r02, \
+ .radio_rfpll_loopfilter_r1 = r03, \
+ .radio_rfpll_loopfilter_c2 = r04, \
+ .radio_rfpll_loopfilter_c1 = r05, \
+ .radio_cp_kpd_idac = r06, \
+ .radio_rfpll_mmd0 = r07, \
+ .radio_rfpll_mmd1 = r08, \
+ .radio_vcobuf_tune = r09, \
+ .radio_logen_mx2g_tune = r10, \
+ .radio_logen_indbuf2g_tune = r11, \
+ .radio_txmix2g_tune_boost_pu_core0 = r12, \
+ .radio_pad2g_tune_pus_core0 = r13, \
+ .radio_lna2g_tune_core0 = r14, \
+ .radio_txmix2g_tune_boost_pu_core1 = r15, \
+ .radio_pad2g_tune_pus_core1 = r16, \
+ .radio_lna2g_tune_core1 = r17
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5) \
+ .phy_regs.phy_bw1a = r0, \
+ .phy_regs.phy_bw2 = r1, \
+ .phy_regs.phy_bw3 = r2, \
+ .phy_regs.phy_bw4 = r3, \
+ .phy_regs.phy_bw5 = r4, \
+ .phy_regs.phy_bw6 = r5
+
+/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
+static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
+ {
+ .freq = 2412,
+ RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
+ 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
+ 0x03, 0xff),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ {
+ .freq = 2417,
+ RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
+ 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
+ 0x03, 0xff),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ {
+ .freq = 2422,
+ RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
+ 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
+ 0x03, 0xef),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ {
+ .freq = 2427,
+ RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
+ 0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
+ 0x03, 0xdf),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ {
+ .freq = 2432,
+ RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
+ 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
+ 0x03, 0xcf),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ {
+ .freq = 2437,
+ RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
+ 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
+ 0x03, 0xbf),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ {
+ .freq = 2442,
+ RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
+ 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
+ 0x03, 0xaf),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ {
+ .freq = 2447,
+ RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
+ 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
+ 0x03, 0x9f),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ {
+ .freq = 2452,
+ RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
+ 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
+ 0x03, 0x8f),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ {
+ .freq = 2457,
+ RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
+ 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
+ 0x03, 0x7f),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ {
+ .freq = 2462,
+ RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
+ 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
+ 0x03, 0x6f),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ {
+ .freq = 2467,
+ RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
+ 0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
+ 0x03, 0x5f),
+ PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+ },
+ {
+ .freq = 2472,
+ RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
+ 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
+ 0x03, 0x4f),
+ PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+ },
+ {
+ .freq = 2484,
+ RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
+ 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
+ 0x03, 0x3f),
+ PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
+ }
+};
+
+/* Extracted from MMIO dump of 6.30.223.248 */
+static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
+ {
+ .freq = 2412,
+ RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
+ 0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ {
+ .freq = 2417,
+ RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
+ 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ {
+ .freq = 2422,
+ RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
+ 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ {
+ .freq = 2427,
+ RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ {
+ .freq = 2432,
+ RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ {
+ .freq = 2437,
+ RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
+ 0x53, 0xff),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ {
+ .freq = 2442,
+ RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
+ 0x43, 0xff),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ {
+ .freq = 2447,
+ RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
+ 0x43, 0xff),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ {
+ .freq = 2452,
+ RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
+ 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
+ 0x43, 0xff),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ {
+ .freq = 2457,
+ RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
+ 0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
+ 0x43, 0xff),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ {
+ .freq = 2462,
+ RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
+ 0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
+ 0x43, 0xff),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+};
+
+/* Extracted from MMIO dump of 6.30.223.141 */
+static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
+ {
+ .freq = 2412,
+ RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
+ 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+ },
+ {
+ .freq = 2417,
+ RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
+ 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+ },
+ {
+ .freq = 2422,
+ RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
+ 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+ },
+ {
+ .freq = 2427,
+ RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
+ 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+ },
+ {
+ .freq = 2432,
+ RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
+ 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+ },
+ {
+ .freq = 2437,
+ RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
+ 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+ },
+ {
+ .freq = 2442,
+ RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
+ 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+ },
+ {
+ .freq = 2447,
+ RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
+ 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+ },
+ {
+ .freq = 2452,
+ RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
+ 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+ },
+ {
+ .freq = 2457,
+ RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
+ 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+ },
+ {
+ .freq = 2462,
+ RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
+ 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
+ 0x00, 0x00, 0xf0, 0x00),
+ PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+ },
+ {
+ .freq = 5180,
+ RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
+ 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
+ 0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
+ 0x3a, 0x83, 0x00, 0xfc),
+ PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
+ },
+ {
+ .freq = 5200,
+ RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
+ 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
+ 0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
+ 0x4a, 0x83, 0x00, 0xf8),
+ PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
+ },
+ {
+ .freq = 5220,
+ RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
+ 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
+ 0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
+ 0x2a, 0x73, 0x00, 0xf8),
+ PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
+ },
+ {
+ .freq = 5240,
+ RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
+ 0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
+ 0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
+ 0x2b, 0x73, 0x00, 0xf8),
+ PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
+ },
+ {
+ .freq = 5745,
+ RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
+ 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
+ 0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
+ 0x02, 0x03, 0x00, 0x30),
+ PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
+ },
+ {
+ .freq = 5765,
+ RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
+ 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
+ 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x02, 0x03, 0x00, 0x00),
+ PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
+ },
+ {
+ .freq = 5785,
+ RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
+ 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
+ 0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x21, 0x03, 0x00, 0x00),
+ PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
+ },
+ {
+ .freq = 5805,
+ RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
+ 0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
+ 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00),
+ PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
+ },
+ {
+ .freq = 5825,
+ RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
+ 0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
+ 0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x03, 0x00, 0x00),
+ PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
+ },
+};
void r2057_upload_inittabs(struct b43_wldev *dev)
{
@@ -109,33 +540,98 @@ void r2057_upload_inittabs(struct b43_wldev *dev)
u16 *table = NULL;
u16 size, i;
- if (phy->rev == 7) {
+ switch (phy->rev) {
+ case 7:
table = r2057_rev4_init[0];
size = ARRAY_SIZE(r2057_rev4_init);
- } else if (phy->rev == 8 || phy->rev == 9) {
+ break;
+ case 8:
if (phy->radio_rev == 5) {
- if (phy->radio_rev == 8) {
- table = r2057_rev5_init[0];
- size = ARRAY_SIZE(r2057_rev5_init);
- } else {
- table = r2057_rev5a_init[0];
- size = ARRAY_SIZE(r2057_rev5a_init);
- }
+ table = r2057_rev5_init[0];
+ size = ARRAY_SIZE(r2057_rev5_init);
} else if (phy->radio_rev == 7) {
table = r2057_rev7_init[0];
size = ARRAY_SIZE(r2057_rev7_init);
- } else if (phy->radio_rev == 9) {
- table = r2057_rev8_init[0];
- size = ARRAY_SIZE(r2057_rev8_init);
}
+ break;
+ case 9:
+ if (phy->radio_rev == 5) {
+ table = r2057_rev5a_init[0];
+ size = ARRAY_SIZE(r2057_rev5a_init);
+ }
+ break;
+ case 16:
+ if (phy->radio_rev == 9) {
+ table = r2057_rev9_init[0];
+ size = ARRAY_SIZE(r2057_rev9_init);
+ }
+ break;
+ case 17:
+ if (phy->radio_rev == 14) {
+ table = r2057_rev14_init[0];
+ size = ARRAY_SIZE(r2057_rev14_init);
+ }
+ break;
}
+ B43_WARN_ON(!table);
+
if (table) {
- for (i = 0; i < 10; i++) {
- pr_info("radio_write 0x%X ", *table);
- table++;
- pr_info("0x%X\n", *table);
- table++;
+ for (i = 0; i < size; i++, table += 2)
+ b43_radio_write(dev, table[0], table[1]);
+ }
+}
+
+void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
+ const struct b43_nphy_chantabent_rev7 **tabent_r7,
+ const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
+{
+ struct b43_phy *phy = &dev->phy;
+ const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
+ const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
+ unsigned int len, i;
+
+ *tabent_r7 = NULL;
+ *tabent_r7_2g = NULL;
+
+ switch (phy->rev) {
+ case 8:
+ if (phy->radio_rev == 5) {
+ e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
+ len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
+ }
+ break;
+ case 16:
+ if (phy->radio_rev == 9) {
+ e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
+ len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
+ }
+ break;
+ case 17:
+ if (phy->radio_rev == 14) {
+ e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
+ len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (e_r7) {
+ for (i = 0; i < len; i++, e_r7++) {
+ if (e_r7->freq == freq) {
+ *tabent_r7 = e_r7;
+ return;
+ }
+ }
+ } else if (e_r7_2g) {
+ for (i = 0; i < len; i++, e_r7_2g++) {
+ if (e_r7_2g->freq == freq) {
+ *tabent_r7_2g = e_r7_2g;
+ return;
+ }
}
+ } else {
+ B43_WARN_ON(1);
}
}
diff --git a/drivers/net/wireless/b43/radio_2057.h b/drivers/net/wireless/b43/radio_2057.h
index eeebd8fbeb0d..220d080238ff 100644
--- a/drivers/net/wireless/b43/radio_2057.h
+++ b/drivers/net/wireless/b43/radio_2057.h
@@ -84,6 +84,8 @@
#define R2057_CMOSBUF_RX_RCCR 0x04c
#define R2057_LOGEN_SEL_PKDET 0x04d
#define R2057_CMOSBUF_SHAREIQ_PTAT 0x04e
+
+/* MISC core 0 */
#define R2057_RXTXBIAS_CONFIG_CORE0 0x04f
#define R2057_TXGM_TXRF_PUS_CORE0 0x050
#define R2057_TXGM_IDAC_BLEED_CORE0 0x051
@@ -204,6 +206,8 @@
#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0x0d1
#define R2057_LPF_GAIN_CORE0 0x0d2
#define R2057_DACBUF_IDACS_BW_CORE0 0x0d3
+
+/* MISC core 1 */
#define R2057_RXTXBIAS_CONFIG_CORE1 0x0d4
#define R2057_TXGM_TXRF_PUS_CORE1 0x0d5
#define R2057_TXGM_IDAC_BLEED_CORE1 0x0d6
@@ -324,6 +328,7 @@
#define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
#define R2057_LPF_GAIN_CORE1 0x157
#define R2057_DACBUF_IDACS_BW_CORE1 0x158
+
#define R2057_DACBUF_VINCM_CORE1 0x159
#define R2057_RCCAL_START_R1_Q1_P1 0x15a
#define R2057_RCCAL_X1 0x15b
@@ -345,6 +350,8 @@
#define R2057_RCCAL_BCAP_VAL 0x16b
#define R2057_RCCAL_HPC_VAL 0x16c
#define R2057_RCCAL_OVERRIDES 0x16d
+
+/* TX core 0 */
#define R2057_TX0_IQCAL_GAIN_BW 0x170
#define R2057_TX0_LOFT_FINE_I 0x171
#define R2057_TX0_LOFT_FINE_Q 0x172
@@ -362,6 +369,8 @@
#define R2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
#define R2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
#define R2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
+
+/* TX core 1 */
#define R2057_TX1_IQCAL_GAIN_BW 0x190
#define R2057_TX1_LOFT_FINE_I 0x191
#define R2057_TX1_LOFT_FINE_Q 0x192
@@ -379,6 +388,7 @@
#define R2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
#define R2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
#define R2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
+
#define R2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
#define R2057_AFE_SET_VCM_I_CORE0 0x1a2
#define R2057_AFE_SET_VCM_Q_CORE0 0x1a3
@@ -425,6 +435,72 @@
#define R2057_VCM_MASK 0x7
+struct b43_nphy_chantabent_rev7 {
+ /* The channel frequency in MHz */
+ u16 freq;
+ /* Radio regs values on channelswitch */
+ u8 radio_vcocal_countval0;
+ u8 radio_vcocal_countval1;
+ u8 radio_rfpll_refmaster_sparextalsize;
+ u8 radio_rfpll_loopfilter_r1;
+ u8 radio_rfpll_loopfilter_c2;
+ u8 radio_rfpll_loopfilter_c1;
+ u8 radio_cp_kpd_idac;
+ u8 radio_rfpll_mmd0;
+ u8 radio_rfpll_mmd1;
+ u8 radio_vcobuf_tune;
+ u8 radio_logen_mx2g_tune;
+ u8 radio_logen_mx5g_tune;
+ u8 radio_logen_indbuf2g_tune;
+ u8 radio_logen_indbuf5g_tune;
+ u8 radio_txmix2g_tune_boost_pu_core0;
+ u8 radio_pad2g_tune_pus_core0;
+ u8 radio_pga_boost_tune_core0;
+ u8 radio_txmix5g_boost_tune_core0;
+ u8 radio_pad5g_tune_misc_pus_core0;
+ u8 radio_lna2g_tune_core0;
+ u8 radio_lna5g_tune_core0;
+ u8 radio_txmix2g_tune_boost_pu_core1;
+ u8 radio_pad2g_tune_pus_core1;
+ u8 radio_pga_boost_tune_core1;
+ u8 radio_txmix5g_boost_tune_core1;
+ u8 radio_pad5g_tune_misc_pus_core1;
+ u8 radio_lna2g_tune_core1;
+ u8 radio_lna5g_tune_core1;
+ /* PHY res values on channelswitch */
+ struct b43_phy_n_sfo_cfg phy_regs;
+};
+
+struct b43_nphy_chantabent_rev7_2g {
+ /* The channel frequency in MHz */
+ u16 freq;
+ /* Radio regs values on channelswitch */
+ u8 radio_vcocal_countval0;
+ u8 radio_vcocal_countval1;
+ u8 radio_rfpll_refmaster_sparextalsize;
+ u8 radio_rfpll_loopfilter_r1;
+ u8 radio_rfpll_loopfilter_c2;
+ u8 radio_rfpll_loopfilter_c1;
+ u8 radio_cp_kpd_idac;
+ u8 radio_rfpll_mmd0;
+ u8 radio_rfpll_mmd1;
+ u8 radio_vcobuf_tune;
+ u8 radio_logen_mx2g_tune;
+ u8 radio_logen_indbuf2g_tune;
+ u8 radio_txmix2g_tune_boost_pu_core0;
+ u8 radio_pad2g_tune_pus_core0;
+ u8 radio_lna2g_tune_core0;
+ u8 radio_txmix2g_tune_boost_pu_core1;
+ u8 radio_pad2g_tune_pus_core1;
+ u8 radio_lna2g_tune_core1;
+ /* PHY regs values on channelswitch */
+ struct b43_phy_n_sfo_cfg phy_regs;
+};
+
void r2057_upload_inittabs(struct b43_wldev *dev);
+void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
+ const struct b43_nphy_chantabent_rev7 **tabent_r7,
+ const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
+
#endif /* B43_RADIO_2057_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4047c05e3807..4b5885077b01 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4][32] = {
}
};
-/* TX gain tables */
+/* static tables, PHY revision >= 7 */
+
+/* Copied from brcmsmac (5.75.11) */
+static const u32 b43_ntab_tmap_r7[] = {
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
+ 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
+ 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+ 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+ 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
+ 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
+ 0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
+ 0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
+ 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
+ 0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+ 0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
+ 0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
+ 0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
+ 0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
+ 0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
+ 0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+ 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
+ 0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
+ 0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
+ 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+ 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+ 0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
+ 0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
+ 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
+ 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
+ 0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+ 0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
+ 0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
+ 0x22222222, 0x22222222, 0x22f22222, 0x00000222,
+ 0x11000000, 0x1111f111, 0x11111111, 0x11111111,
+ 0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
+ 0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
+ 0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
+ 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+ 0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
+ 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
+ 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
+ 0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
+ 0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
+ 0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
+ 0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
+ 0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
+ 0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
+ 0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
+ 0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
+ 0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
+ 0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
+ 0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
+ 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
+ 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
+ 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
+ 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
+ 0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
+ 0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
+ 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
+ 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
+ 0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
+ 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
+ 0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
+ 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
+ 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+ 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+ 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
+ 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
+ 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+/* Extracted from MMIO dump of 6.30.223.141 */
+static const u32 b43_ntab_noisevar_r7[] = {
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+ 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
+};
+
+/**************************************************
+ * TX gain tables
+ **************************************************/
+
static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
@@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
0x03801442, 0x03801344, 0x03801342, 0x00002b00,
};
-static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
+/* EPA 2 GHz */
+
+static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
@@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
};
-static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
+static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
+ 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
+ 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
+ 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
+ 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
+ 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
+ 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
+ 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
+ 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
+ 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
+ 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
+ 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
+ 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
+ 0x09410044, 0x09410042, 0x09410040, 0x0941003e,
+ 0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
+ 0x08410044, 0x08410042, 0x08410040, 0x0841003e,
+ 0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
+ 0x07410044, 0x07410042, 0x07410040, 0x0741003e,
+ 0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
+ 0x06410044, 0x06410042, 0x06410040, 0x0641003e,
+ 0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
+ 0x05410044, 0x05410042, 0x05410040, 0x0541003e,
+ 0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
+ 0x04410044, 0x04410042, 0x04410040, 0x0441003e,
+ 0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
+ 0x03410044, 0x03410042, 0x03410040, 0x0341003e,
+ 0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
+ 0x02410044, 0x02410042, 0x02410040, 0x0241003e,
+ 0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
+ 0x01410044, 0x01410042, 0x01410040, 0x0141003e,
+ 0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
+ 0x00410044, 0x00410042, 0x00410040, 0x0041003e,
+ 0x0041003c, 0x0041003b, 0x00410039, 0x00410037
+};
+
+/* EPA 5 GHz */
+
+static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
@@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
};
-static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
+static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
@@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
};
-static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
+static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
+ 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
+ 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
+ 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
+ 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
+ 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
+ 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
+ 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
+ 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
+ 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
+ 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
+ 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
+ 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
+ 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
+ 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
+ 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
+ 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
+ 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
+ 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
+ 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
+ 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
+ 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
+ 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
+ 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
+ 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
+ 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
+ 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
+ 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
+ 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
+ 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
+ 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
+ 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
+ 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
+};
+
+static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
@@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
0x0062003b, 0x00620039, 0x00620037, 0x00620035,
};
-static const u32 txpwrctrl_tx_gain_ipa[] = {
+/* IPA 2 GHz */
+
+static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
@@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[] = {
0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
};
-static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
+static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
@@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
};
-static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
+static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
@@ -2427,7 +2692,117 @@ static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
};
-static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
+/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
+static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
+ 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+ 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+ 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+ 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+ 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+ 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+ 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+ 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+ 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+ 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+ 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+ 0x30170028, 0x30170026, 0x30170024, 0x30170022,
+ 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+ 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+ 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+ 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+ 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+ 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+ 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+ 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+};
+
+/* Extracted from MMIO dump of 6.30.223.141 */
+static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
+ 0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
+ 0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
+ 0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
+ 0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
+ 0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
+ 0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
+ 0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
+ 0x60370029, 0x60370027, 0x60370024, 0x602f002a,
+ 0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
+ 0x60270028, 0x60270026, 0x60270024, 0x60270022,
+ 0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
+ 0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
+ 0x60170029, 0x60170027, 0x60170025, 0x60170023,
+ 0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
+ 0x6017001a, 0x60170018, 0x60170018, 0x60170016,
+ 0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
+ 0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
+ 0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
+ 0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
+ 0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+ 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
+};
+
+/* Extracted from MMIO dump of 6.30.223.248 */
+static const u32 b43_ntab_tx_gain_ipa_2057_rev14_2g[] = {
+ 0x50df002e, 0x50cf002d, 0x50bf002c, 0x50b7002b,
+ 0x50af002a, 0x50a70029, 0x509f0029, 0x50970028,
+ 0x508f0027, 0x50870027, 0x507f0027, 0x50770027,
+ 0x506f0027, 0x50670027, 0x505f0028, 0x50570029,
+ 0x504f002b, 0x5047002e, 0x5047002b, 0x50470029,
+ 0x503f002c, 0x503f0029, 0x5037002c, 0x5037002a,
+ 0x50370028, 0x502f002d, 0x502f002b, 0x502f0028,
+ 0x502f0026, 0x5027002d, 0x5027002a, 0x50270028,
+ 0x50270026, 0x50270024, 0x501f002e, 0x501f002b,
+ 0x501f0029, 0x501f0027, 0x501f0024, 0x501f0022,
+ 0x501f0020, 0x501f001f, 0x5017002c, 0x50170029,
+ 0x50170027, 0x50170024, 0x50170022, 0x50170021,
+ 0x5017001f, 0x5017001d, 0x5017001b, 0x5017001a,
+ 0x50170018, 0x50170017, 0x50170015, 0x500f002c,
+ 0x500f002a, 0x500f0027, 0x500f0025, 0x500f0023,
+ 0x500f0022, 0x500f001f, 0x500f001e, 0x500f001c,
+ 0x500f001a, 0x500f0019, 0x500f0018, 0x500f0016,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+ 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
+};
+
+/* IPA 2 5Hz */
+
+static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
@@ -2462,6 +2837,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
};
+/* Extracted from MMIO dump of 6.30.223.141 */
+static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
+ 0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
+ 0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
+ 0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
+ 0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
+ 0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
+ 0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
+ 0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
+ 0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
+ 0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
+ 0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
+ 0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
+ 0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
+ 0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
+ 0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
+ 0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
+ 0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
+ 0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
+ 0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
+ 0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
+ 0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
+ 0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
+ 0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
+ 0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
+ 0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
+ 0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
+ 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
+ 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
+ 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
+ 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+ 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+ 0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
+ 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
+};
+
const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
-114, -108, -98, -91, -84, -78, -70, -62,
-54, -46, -39, -31, -23, -15, -8, 0
@@ -2698,11 +3109,11 @@ static const struct nphy_rf_control_override_rev7
{ 0x0010, 0x07A, 0x07D, 0x0010, 4 },
{ 0x0020, 0x07A, 0x07D, 0x0020, 5 },
{ 0x0040, 0x07A, 0x07D, 0x0040, 6 },
- { 0x0080, 0x0F8, 0x0FA, 0x0080, 7 },
+ { 0x0080, 0x07A, 0x07D, 0x0080, 7 },
{ 0x0400, 0x0F8, 0x0FA, 0x0070, 4 },
{ 0x0800, 0x07B, 0x07E, 0xFFFF, 0 },
{ 0x1000, 0x07C, 0x07F, 0xFFFF, 0 },
- { 0x6000, 0x348, 0x349, 0xFFFF, 0 },
+ { 0x6000, 0x348, 0x349, 0x00FF, 0 },
{ 0x2000, 0x348, 0x349, 0x000F, 0 },
};
@@ -3031,6 +3442,91 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
} while (0)
+static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
+{
+ ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
+ ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
+ ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
+ ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
+ ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
+ ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
+ ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
+ ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
+ ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
+ ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
+}
+
+static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
+{
+ struct ssb_sprom *sprom = dev->dev->bus_sprom;
+ u8 antswlut;
+ int core, offset, i;
+
+ const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
+ const u8 antswlut0_values[][3] = {
+ { 0x2, 0x12, 0x8 }, /* Core 0 */
+ { 0x2, 0x18, 0x2 }, /* Core 1 */
+ };
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+ antswlut = sprom->fem.ghz5.antswlut;
+ else
+ antswlut = sprom->fem.ghz2.antswlut;
+
+ switch (antswlut) {
+ case 0:
+ for (core = 0; core < 2; core++) {
+ for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
+ offset = core ? 0x20 : 0x00;
+ offset += antswlut0_offsets[i];
+ b43_ntab_write(dev, B43_NTAB8(9, offset),
+ antswlut0_values[core][i]);
+ }
+ }
+ break;
+ default:
+ b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
+ break;
+ }
+}
+
+static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
+{
+ /* Static tables */
+ if (dev->phy.do_full_init) {
+ ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
+ b43_nphy_tables_init_shared_lut(dev);
+ }
+
+ /* Volatile tables */
+ b43_nphy_tables_init_rev7_volatile(dev);
+}
+
+static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
+{
+ /* Static tables */
+ if (dev->phy.do_full_init) {
+ ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
+ ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
+ ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
+ ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
+ ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
+ ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
+ ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
+ ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
+ ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
+ ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
+ ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
+ ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
+ ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
+ ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
+ b43_nphy_tables_init_shared_lut(dev);
+ }
+
+ /* Volatile tables */
+ b43_nphy_tables_init_rev7_volatile(dev);
+}
+
static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -3057,16 +3553,7 @@ static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
- ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
- ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
- ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
- ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
- ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
- ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
- ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
- ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
- ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
- ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
+ b43_nphy_tables_init_shared_lut(dev);
}
/* Volatile tables */
@@ -3115,7 +3602,11 @@ static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
void b43_nphy_tables_init(struct b43_wldev *dev)
{
- if (dev->phy.rev >= 3)
+ if (dev->phy.rev >= 16)
+ b43_nphy_tables_init_rev16(dev);
+ else if (dev->phy.rev >= 7)
+ b43_nphy_tables_init_rev7(dev);
+ else if (dev->phy.rev >= 3)
b43_nphy_tables_init_rev3(dev);
else
b43_nphy_tables_init_rev0(dev);
@@ -3124,23 +3615,55 @@ void b43_nphy_tables_init(struct b43_wldev *dev)
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
+
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
- if (dev->phy.rev >= 6) {
- if (dev->dev->chip_id == 47162)
- return txpwrctrl_tx_gain_ipa_rev5;
- return txpwrctrl_tx_gain_ipa_rev6;
- } else if (dev->phy.rev >= 5) {
- return txpwrctrl_tx_gain_ipa_rev5;
- } else {
- return txpwrctrl_tx_gain_ipa;
+ switch (phy->rev) {
+ case 17:
+ if (phy->radio_rev == 14)
+ return b43_ntab_tx_gain_ipa_2057_rev14_2g;
+ break;
+ case 16:
+ if (phy->radio_rev == 9)
+ return b43_ntab_tx_gain_ipa_2057_rev9_2g;
+ break;
+ case 8:
+ if (phy->radio_rev == 5)
+ return b43_ntab_tx_gain_ipa_2057_rev5_2g;
+ break;
+ case 6:
+ if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
+ return b43_ntab_tx_gain_ipa_rev5_2g;
+ return b43_ntab_tx_gain_ipa_rev6_2g;
+ case 5:
+ return b43_ntab_tx_gain_ipa_rev5_2g;
+ case 4:
+ case 3:
+ return b43_ntab_tx_gain_ipa_rev3_2g;
}
+
+ b43err(dev->wl,
+ "No 2GHz IPA gain table available for this device\n");
+ return NULL;
} else {
- return txpwrctrl_tx_gain_ipa_5g;
+ switch (phy->rev) {
+ case 16:
+ if (phy->radio_rev == 9)
+ return b43_ntab_tx_gain_ipa_2057_rev9_5g;
+ break;
+ case 3 ... 6:
+ return b43_ntab_tx_gain_ipa_rev3_5g;
+ }
+
+ b43err(dev->wl,
+ "No 5GHz IPA gain table available for this device\n");
+ return NULL;
}
}
const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
{
+ struct b43_phy *phy = &dev->phy;
enum ieee80211_band band = b43_current_band(dev->wl);
struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -3152,19 +3675,36 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
(dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
return b43_nphy_get_ipa_gain_table(dev);
} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- if (dev->phy.rev == 3)
- return b43_ntab_tx_gain_rev3_5ghz;
- if (dev->phy.rev == 4)
+ switch (phy->rev) {
+ case 6:
+ case 5:
+ return b43_ntab_tx_gain_epa_rev5_5g;
+ case 4:
return sprom->fem.ghz5.extpa_gain == 3 ?
- b43_ntab_tx_gain_rev4_5ghz :
- b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
- else
- return b43_ntab_tx_gain_rev5plus_5ghz;
+ b43_ntab_tx_gain_epa_rev4_5g :
+ b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
+ case 3:
+ return b43_ntab_tx_gain_epa_rev3_5g;
+ default:
+ b43err(dev->wl,
+ "No 5GHz EPA gain table available for this device\n");
+ return NULL;
+ }
} else {
- if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
- return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
- else
- return b43_ntab_tx_gain_rev3plus_2ghz;
+ switch (phy->rev) {
+ case 6:
+ case 5:
+ if (sprom->fem.ghz5.extpa_gain == 3)
+ return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
+ /* fall through */
+ case 4:
+ case 3:
+ return b43_ntab_tx_gain_epa_rev3_2g;
+ default:
+ b43err(dev->wl,
+ "No 2GHz EPA gain table available for this device\n");
+ return NULL;
+ }
}
}
@@ -3191,7 +3731,7 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
/* Some workarounds to the workarounds... */
if (ghz5 && dev->phy.rev >= 6) {
if (dev->phy.radio_rev == 11 &&
- !b43_channel_type_is_40mhz(dev->phy.channel_type))
+ !b43_is_40mhz(dev))
e->cliplo_gain = 0x2d;
} else if (!ghz5 && dev->phy.rev >= 5) {
static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 3a58aee4c4cf..3ce2e6f3a278 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
#define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576)
+/* Static N-PHY tables, PHY revision >= 7 */
+#define B43_NTAB_TMAP_R7 B43_NTAB32(12, 0) /* TM AP */
+#define B43_NTAB_NOISEVAR_R7 B43_NTAB32(16, 0) /* noise variance */
+
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 6e6ef3fc2247..426dc13c44cd 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -80,9 +80,10 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
}
/* Extract the bitrate index out of an OFDM PLCP header. */
-static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
+static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool ghz5)
{
- int base = aphy ? 0 : 4;
+ /* For 2 GHz band first OFDM rate is at index 4, see main.c */
+ int base = ghz5 ? 0 : 4;
switch (plcp->raw[0] & 0xF) {
case 0xB:
@@ -767,7 +768,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
if (phystat0 & B43_RX_PHYST0_OFDM)
rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
- phytype == B43_PHYTYPE_A);
+ !!(chanstat & B43_RX_CHAN_5GHZ));
else
rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
if (unlikely(rate_idx == -1)) {
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index fcfed6b99a62..b8e2561ea645 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -48,6 +48,16 @@ config BRCMFMAC_USB
IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
use the driver for an USB wireless card.
+config BRCMFMAC_PCIE
+ bool "PCIE bus interface support for FullMAC driver"
+ depends on BRCMFMAC
+ depends on PCI
+ select FW_LOADER
+ ---help---
+ This option enables the PCIE bus interface support for Broadcom
+ IEEE802.11ac embedded FullMAC WLAN driver. Say Y if you want to
+ use the driver for an PCIE wireless card.
+
config BRCM_TRACING
bool "Broadcom device tracing"
depends on BRCMSMAC || BRCMFMAC
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 98e67c18f276..c35adf4bc70b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -31,16 +31,25 @@ brcmfmac-objs += \
p2p.o \
proto.o \
bcdc.o \
+ commonring.o \
+ flowring.o \
+ msgbuf.o \
dhd_common.o \
dhd_linux.o \
firmware.o \
- btcoex.o
+ feature.o \
+ btcoex.o \
+ vendor.o
brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
dhd_sdio.o \
bcmsdh.o
brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
usb.o
+brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \
+ pcie.o
brcmfmac-$(CONFIG_BRCMDBG) += \
dhd_dbg.o
brcmfmac-$(CONFIG_BRCM_TRACING) += \
tracepoint.o
+brcmfmac-$(CONFIG_OF) += \
+ of.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
index c229210d50ba..a159ff3427de 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -337,6 +337,23 @@ brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
return brcmf_bus_txdata(drvr->bus_if, pktbuf);
}
+static void
+brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
+ enum proto_addr_mode addr_mode)
+{
+}
+
+static void
+brcmf_proto_bcdc_delete_peer(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+}
+
+static void
+brcmf_proto_bcdc_add_tdls_peer(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+}
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
{
@@ -356,6 +373,9 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
drvr->proto->txdata = brcmf_proto_bcdc_txdata;
+ drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode;
+ drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
+ drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
drvr->proto->pd = bcdc;
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index a16e644e7c08..8dbd5dbb78fd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -25,7 +25,6 @@
#include <linux/mmc/sdio.h>
#include <linux/mmc/core.h>
#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
@@ -39,10 +38,13 @@
#include <brcm_hw_ids.h>
#include <brcmu_utils.h>
#include <brcmu_wifi.h>
+#include <chipcommon.h>
#include <soc.h>
+#include "chip.h"
#include "dhd_bus.h"
#include "dhd_dbg.h"
#include "sdio_host.h"
+#include "of.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
@@ -118,6 +120,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
{
int ret = 0;
u8 data;
+ u32 addr, gpiocontrol;
unsigned long flags;
if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
@@ -147,6 +150,19 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
sdio_claim_host(sdiodev->func[1]);
+ if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
+ /* assign GPIO to SDIO core */
+ addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
+ gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret);
+ gpiocontrol |= 0x2;
+ brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret);
+
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf,
+ &ret);
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
+ }
+
/* must configure SDIO_CCCR_IENx to enable irq */
data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
@@ -979,18 +995,20 @@ out:
return ret;
}
+#define BRCMF_SDIO_DEVICE(dev_id) \
+ {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)}
+
/* devices we support, null terminated */
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM,
- SDIO_DEVICE_ID_BROADCOM_4335_4339)},
- {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)},
- { /* end: all zeroes */ },
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID),
+ BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID),
+ { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
@@ -1043,6 +1061,9 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
sdiodev->dev = &sdiodev->func[1]->dev;
sdiodev->pdata = brcmfmac_sdio_pdata;
+ if (!sdiodev->pdata)
+ brcmf_of_probe(sdiodev);
+
atomic_set(&sdiodev->suspend, false);
init_waitqueue_head(&sdiodev->request_word_wait);
init_waitqueue_head(&sdiodev->request_buffer_wait);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
index 0cb591b050b3..a29ac4977b3a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
@@ -157,7 +157,7 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
*/
/* save current */
- brcmf_dbg(TRACE, "new SCO/eSCO coex algo {save & override}\n");
+ brcmf_dbg(INFO, "new SCO/eSCO coex algo {save & override}\n");
brcmf_btcoex_params_read(ifp, 50, &btci->reg50);
brcmf_btcoex_params_read(ifp, 51, &btci->reg51);
brcmf_btcoex_params_read(ifp, 64, &btci->reg64);
@@ -165,7 +165,7 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
brcmf_btcoex_params_read(ifp, 71, &btci->reg71);
btci->saved_regs_part2 = true;
- brcmf_dbg(TRACE,
+ brcmf_dbg(INFO,
"saved bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
btci->reg50, btci->reg51, btci->reg64,
btci->reg65, btci->reg71);
@@ -179,21 +179,21 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
} else if (btci->saved_regs_part2) {
/* restore previously saved bt params */
- brcmf_dbg(TRACE, "Do new SCO/eSCO coex algo {restore}\n");
+ brcmf_dbg(INFO, "Do new SCO/eSCO coex algo {restore}\n");
brcmf_btcoex_params_write(ifp, 50, btci->reg50);
brcmf_btcoex_params_write(ifp, 51, btci->reg51);
brcmf_btcoex_params_write(ifp, 64, btci->reg64);
brcmf_btcoex_params_write(ifp, 65, btci->reg65);
brcmf_btcoex_params_write(ifp, 71, btci->reg71);
- brcmf_dbg(TRACE,
+ brcmf_dbg(INFO,
"restored bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
btci->reg50, btci->reg51, btci->reg64,
btci->reg65, btci->reg71);
btci->saved_regs_part2 = false;
} else {
- brcmf_err("attempted to restore not saved BTCOEX params\n");
+ brcmf_dbg(INFO, "attempted to restore not saved BTCOEX params\n");
}
}
@@ -219,14 +219,14 @@ static bool brcmf_btcoex_is_sco_active(struct brcmf_if *ifp)
break;
}
- brcmf_dbg(TRACE, "sample[%d], btc_params 27:%x\n", i, param27);
+ brcmf_dbg(INFO, "sample[%d], btc_params 27:%x\n", i, param27);
if ((param27 & 0x6) == 2) { /* count both sco & esco */
sco_id_cnt++;
}
if (sco_id_cnt > 2) {
- brcmf_dbg(TRACE,
+ brcmf_dbg(INFO,
"sco/esco detected, pkt id_cnt:%d samples:%d\n",
sco_id_cnt, i);
res = true;
@@ -250,7 +250,7 @@ static void btcmf_btcoex_save_part1(struct brcmf_btcoex_info *btci)
brcmf_btcoex_params_read(ifp, 41, &btci->reg41);
brcmf_btcoex_params_read(ifp, 68, &btci->reg68);
btci->saved_regs_part1 = true;
- brcmf_dbg(TRACE,
+ brcmf_dbg(INFO,
"saved btc_params regs (66,41,68) 0x%x 0x%x 0x%x\n",
btci->reg66, btci->reg41,
btci->reg68);
@@ -270,7 +270,7 @@ static void brcmf_btcoex_restore_part1(struct brcmf_btcoex_info *btci)
brcmf_btcoex_params_write(ifp, 66, btci->reg66);
brcmf_btcoex_params_write(ifp, 41, btci->reg41);
brcmf_btcoex_params_write(ifp, 68, btci->reg68);
- brcmf_dbg(TRACE,
+ brcmf_dbg(INFO,
"restored btc_params regs {66,41,68} 0x%x 0x%x 0x%x\n",
btci->reg66, btci->reg41,
btci->reg68);
@@ -307,7 +307,7 @@ static void brcmf_btcoex_handler(struct work_struct *work)
/* DHCP started provide OPPORTUNITY window
to get DHCP address
*/
- brcmf_dbg(TRACE, "DHCP started\n");
+ brcmf_dbg(INFO, "DHCP started\n");
btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN;
if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) {
mod_timer(&btci->timer, btci->timer.expires);
@@ -322,12 +322,12 @@ static void brcmf_btcoex_handler(struct work_struct *work)
case BRCMF_BT_DHCP_OPPR_WIN:
if (btci->dhcp_done) {
- brcmf_dbg(TRACE, "DHCP done before T1 expiration\n");
+ brcmf_dbg(INFO, "DHCP done before T1 expiration\n");
goto idle;
}
/* DHCP is not over yet, start lowering BT priority */
- brcmf_dbg(TRACE, "DHCP T1:%d expired\n",
+ brcmf_dbg(INFO, "DHCP T1:%d expired\n",
BRCMF_BTCOEX_OPPR_WIN_TIME);
brcmf_btcoex_boost_wifi(btci, true);
@@ -339,9 +339,9 @@ static void brcmf_btcoex_handler(struct work_struct *work)
case BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT:
if (btci->dhcp_done)
- brcmf_dbg(TRACE, "DHCP done before T2 expiration\n");
+ brcmf_dbg(INFO, "DHCP done before T2 expiration\n");
else
- brcmf_dbg(TRACE, "DHCP T2:%d expired\n",
+ brcmf_dbg(INFO, "DHCP T2:%d expired\n",
BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT);
goto idle;
@@ -440,13 +440,13 @@ static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci)
/* Stop any bt timer because DHCP session is done */
btci->dhcp_done = true;
if (btci->timer_on) {
- brcmf_dbg(TRACE, "disable BT DHCP Timer\n");
+ brcmf_dbg(INFO, "disable BT DHCP Timer\n");
btci->timer_on = false;
del_timer_sync(&btci->timer);
/* schedule worker if transition to IDLE is needed */
if (btci->bt_state != BRCMF_BT_DHCP_IDLE) {
- brcmf_dbg(TRACE, "bt_state:%d\n",
+ brcmf_dbg(INFO, "bt_state:%d\n",
btci->bt_state);
schedule_work(&btci->work);
}
@@ -472,7 +472,7 @@ int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
switch (mode) {
case BRCMF_BTCOEX_DISABLED:
- brcmf_dbg(TRACE, "DHCP session starts\n");
+ brcmf_dbg(INFO, "DHCP session starts\n");
if (btci->bt_state != BRCMF_BT_DHCP_IDLE)
return -EBUSY;
/* Start BT timer only for SCO connection */
@@ -484,14 +484,14 @@ int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
break;
case BRCMF_BTCOEX_ENABLED:
- brcmf_dbg(TRACE, "DHCP session ends\n");
+ brcmf_dbg(INFO, "DHCP session ends\n");
if (btci->bt_state != BRCMF_BT_DHCP_IDLE &&
vif == btci->vif) {
brcmf_btcoex_dhcp_end(btci);
}
break;
default:
- brcmf_dbg(TRACE, "Unknown mode, ignored\n");
+ brcmf_dbg(INFO, "Unknown mode, ignored\n");
}
return 0;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index c7c9f15c0fe0..95efde868db8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -482,33 +482,41 @@ static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
{
switch (ci->pub.chip) {
- case BCM4329_CHIP_ID:
+ case BRCM_CC_4329_CHIP_ID:
ci->pub.ramsize = BCM4329_RAMSIZE;
break;
- case BCM43143_CHIP_ID:
+ case BRCM_CC_43143_CHIP_ID:
ci->pub.ramsize = BCM43143_RAMSIZE;
break;
- case BCM43241_CHIP_ID:
+ case BRCM_CC_43241_CHIP_ID:
ci->pub.ramsize = 0x90000;
break;
- case BCM4330_CHIP_ID:
+ case BRCM_CC_4330_CHIP_ID:
ci->pub.ramsize = 0x48000;
break;
- case BCM4334_CHIP_ID:
+ case BRCM_CC_4334_CHIP_ID:
ci->pub.ramsize = 0x80000;
break;
- case BCM4335_CHIP_ID:
+ case BRCM_CC_4335_CHIP_ID:
ci->pub.ramsize = 0xc0000;
ci->pub.rambase = 0x180000;
break;
- case BCM43362_CHIP_ID:
+ case BRCM_CC_43362_CHIP_ID:
ci->pub.ramsize = 0x3c000;
break;
- case BCM4339_CHIP_ID:
- case BCM4354_CHIP_ID:
+ case BRCM_CC_4339_CHIP_ID:
+ case BRCM_CC_4354_CHIP_ID:
+ case BRCM_CC_4356_CHIP_ID:
+ case BRCM_CC_43567_CHIP_ID:
+ case BRCM_CC_43569_CHIP_ID:
+ case BRCM_CC_43570_CHIP_ID:
ci->pub.ramsize = 0xc0000;
ci->pub.rambase = 0x180000;
break;
+ case BRCM_CC_43602_CHIP_ID:
+ ci->pub.ramsize = 0xf0000;
+ ci->pub.rambase = 0x180000;
+ break;
default:
brcmf_err("unknown chip: %s\n", ci->pub.name);
break;
@@ -682,7 +690,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
ci->pub.chiprev);
if (socitype == SOCI_SB) {
- if (ci->pub.chip != BCM4329_CHIP_ID) {
+ if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) {
brcmf_err("SB chip is not supported\n");
return -ENODEV;
}
@@ -1008,13 +1016,13 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
chip = container_of(pub, struct brcmf_chip_priv, pub);
switch (pub->chip) {
- case BCM4354_CHIP_ID:
+ case BRCM_CC_4354_CHIP_ID:
/* explicitly check SR engine enable bit */
pmu_cc3_mask = BIT(2);
/* fall-through */
- case BCM43241_CHIP_ID:
- case BCM4335_CHIP_ID:
- case BCM4339_CHIP_ID:
+ case BRCM_CC_43241_CHIP_ID:
+ case BRCM_CC_4335_CHIP_ID:
+ case BRCM_CC_4339_CHIP_ID:
/* read PMU chipcontrol register 3 */
addr = CORE_CC_REG(base, chipcontrol_addr);
chip->ops->write32(chip->ctx, addr, 3);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
new file mode 100644
index 000000000000..c6d65b8e1e15
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c
@@ -0,0 +1,273 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+
+#include "dhd.h"
+#include "commonring.h"
+
+
+/* dma flushing needs implementation for mips and arm platforms. Should
+ * be put in util. Note, this is not real flushing. It is virtual non
+ * cached memory. Only write buffers should have to be drained. Though
+ * this may be different depending on platform......
+ * SEE ALSO msgbuf.c
+ */
+#define brcmf_dma_flush(addr, len)
+#define brcmf_dma_invalidate_cache(addr, len)
+
+
+void brcmf_commonring_register_cb(struct brcmf_commonring *commonring,
+ int (*cr_ring_bell)(void *ctx),
+ int (*cr_update_rptr)(void *ctx),
+ int (*cr_update_wptr)(void *ctx),
+ int (*cr_write_rptr)(void *ctx),
+ int (*cr_write_wptr)(void *ctx), void *ctx)
+{
+ commonring->cr_ring_bell = cr_ring_bell;
+ commonring->cr_update_rptr = cr_update_rptr;
+ commonring->cr_update_wptr = cr_update_wptr;
+ commonring->cr_write_rptr = cr_write_rptr;
+ commonring->cr_write_wptr = cr_write_wptr;
+ commonring->cr_ctx = ctx;
+}
+
+
+void brcmf_commonring_config(struct brcmf_commonring *commonring, u16 depth,
+ u16 item_len, void *buf_addr)
+{
+ commonring->depth = depth;
+ commonring->item_len = item_len;
+ commonring->buf_addr = buf_addr;
+ if (!commonring->inited) {
+ spin_lock_init(&commonring->lock);
+ commonring->inited = true;
+ }
+ commonring->r_ptr = 0;
+ if (commonring->cr_write_rptr)
+ commonring->cr_write_rptr(commonring->cr_ctx);
+ commonring->w_ptr = 0;
+ if (commonring->cr_write_wptr)
+ commonring->cr_write_wptr(commonring->cr_ctx);
+ commonring->f_ptr = 0;
+}
+
+
+void brcmf_commonring_lock(struct brcmf_commonring *commonring)
+ __acquires(&commonring->lock)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&commonring->lock, flags);
+ commonring->flags = flags;
+}
+
+
+void brcmf_commonring_unlock(struct brcmf_commonring *commonring)
+ __releases(&commonring->lock)
+{
+ spin_unlock_irqrestore(&commonring->lock, commonring->flags);
+}
+
+
+bool brcmf_commonring_write_available(struct brcmf_commonring *commonring)
+{
+ u16 available;
+ bool retry = true;
+
+again:
+ if (commonring->r_ptr <= commonring->w_ptr)
+ available = commonring->depth - commonring->w_ptr +
+ commonring->r_ptr;
+ else
+ available = commonring->r_ptr - commonring->w_ptr;
+
+ if (available > 1) {
+ if (!commonring->was_full)
+ return true;
+ if (available > commonring->depth / 8) {
+ commonring->was_full = false;
+ return true;
+ }
+ if (retry) {
+ if (commonring->cr_update_rptr)
+ commonring->cr_update_rptr(commonring->cr_ctx);
+ retry = false;
+ goto again;
+ }
+ return false;
+ }
+
+ if (retry) {
+ if (commonring->cr_update_rptr)
+ commonring->cr_update_rptr(commonring->cr_ctx);
+ retry = false;
+ goto again;
+ }
+
+ commonring->was_full = true;
+ return false;
+}
+
+
+void *brcmf_commonring_reserve_for_write(struct brcmf_commonring *commonring)
+{
+ void *ret_ptr;
+ u16 available;
+ bool retry = true;
+
+again:
+ if (commonring->r_ptr <= commonring->w_ptr)
+ available = commonring->depth - commonring->w_ptr +
+ commonring->r_ptr;
+ else
+ available = commonring->r_ptr - commonring->w_ptr;
+
+ if (available > 1) {
+ ret_ptr = commonring->buf_addr +
+ (commonring->w_ptr * commonring->item_len);
+ commonring->w_ptr++;
+ if (commonring->w_ptr == commonring->depth)
+ commonring->w_ptr = 0;
+ return ret_ptr;
+ }
+
+ if (retry) {
+ if (commonring->cr_update_rptr)
+ commonring->cr_update_rptr(commonring->cr_ctx);
+ retry = false;
+ goto again;
+ }
+
+ commonring->was_full = true;
+ return NULL;
+}
+
+
+void *
+brcmf_commonring_reserve_for_write_multiple(struct brcmf_commonring *commonring,
+ u16 n_items, u16 *alloced)
+{
+ void *ret_ptr;
+ u16 available;
+ bool retry = true;
+
+again:
+ if (commonring->r_ptr <= commonring->w_ptr)
+ available = commonring->depth - commonring->w_ptr +
+ commonring->r_ptr;
+ else
+ available = commonring->r_ptr - commonring->w_ptr;
+
+ if (available > 1) {
+ ret_ptr = commonring->buf_addr +
+ (commonring->w_ptr * commonring->item_len);
+ *alloced = min_t(u16, n_items, available - 1);
+ if (*alloced + commonring->w_ptr > commonring->depth)
+ *alloced = commonring->depth - commonring->w_ptr;
+ commonring->w_ptr += *alloced;
+ if (commonring->w_ptr == commonring->depth)
+ commonring->w_ptr = 0;
+ return ret_ptr;
+ }
+
+ if (retry) {
+ if (commonring->cr_update_rptr)
+ commonring->cr_update_rptr(commonring->cr_ctx);
+ retry = false;
+ goto again;
+ }
+
+ commonring->was_full = true;
+ return NULL;
+}
+
+
+int brcmf_commonring_write_complete(struct brcmf_commonring *commonring)
+{
+ void *address;
+
+ address = commonring->buf_addr;
+ address += (commonring->f_ptr * commonring->item_len);
+ if (commonring->f_ptr > commonring->w_ptr) {
+ brcmf_dma_flush(address,
+ (commonring->depth - commonring->f_ptr) *
+ commonring->item_len);
+ address = commonring->buf_addr;
+ commonring->f_ptr = 0;
+ }
+ brcmf_dma_flush(address, (commonring->w_ptr - commonring->f_ptr) *
+ commonring->item_len);
+
+ commonring->f_ptr = commonring->w_ptr;
+
+ if (commonring->cr_write_wptr)
+ commonring->cr_write_wptr(commonring->cr_ctx);
+ if (commonring->cr_ring_bell)
+ return commonring->cr_ring_bell(commonring->cr_ctx);
+
+ return -EIO;
+}
+
+
+void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
+ u16 n_items)
+{
+ if (commonring->w_ptr == 0)
+ commonring->w_ptr = commonring->depth - n_items;
+ else
+ commonring->w_ptr -= n_items;
+}
+
+
+void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
+ u16 *n_items)
+{
+ void *ret_addr;
+
+ if (commonring->cr_update_wptr)
+ commonring->cr_update_wptr(commonring->cr_ctx);
+
+ *n_items = (commonring->w_ptr >= commonring->r_ptr) ?
+ (commonring->w_ptr - commonring->r_ptr) :
+ (commonring->depth - commonring->r_ptr);
+
+ if (*n_items == 0)
+ return NULL;
+
+ ret_addr = commonring->buf_addr +
+ (commonring->r_ptr * commonring->item_len);
+
+ commonring->r_ptr += *n_items;
+ if (commonring->r_ptr == commonring->depth)
+ commonring->r_ptr = 0;
+
+ brcmf_dma_invalidate_cache(ret_addr, *n_ items * commonring->item_len);
+
+ return ret_addr;
+}
+
+
+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring)
+{
+ if (commonring->cr_write_rptr)
+ return commonring->cr_write_rptr(commonring->cr_ctx);
+
+ return -EIO;
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
new file mode 100644
index 000000000000..002336e35764
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef BRCMFMAC_COMMONRING_H
+#define BRCMFMAC_COMMONRING_H
+
+
+struct brcmf_commonring {
+ u16 r_ptr;
+ u16 w_ptr;
+ u16 f_ptr;
+ u16 depth;
+ u16 item_len;
+
+ void *buf_addr;
+
+ int (*cr_ring_bell)(void *ctx);
+ int (*cr_update_rptr)(void *ctx);
+ int (*cr_update_wptr)(void *ctx);
+ int (*cr_write_rptr)(void *ctx);
+ int (*cr_write_wptr)(void *ctx);
+
+ void *cr_ctx;
+
+ spinlock_t lock;
+ unsigned long flags;
+ bool inited;
+ bool was_full;
+};
+
+
+void brcmf_commonring_register_cb(struct brcmf_commonring *commonring,
+ int (*cr_ring_bell)(void *ctx),
+ int (*cr_update_rptr)(void *ctx),
+ int (*cr_update_wptr)(void *ctx),
+ int (*cr_write_rptr)(void *ctx),
+ int (*cr_write_wptr)(void *ctx), void *ctx);
+void brcmf_commonring_config(struct brcmf_commonring *commonring, u16 depth,
+ u16 item_len, void *buf_addr);
+void brcmf_commonring_lock(struct brcmf_commonring *commonring);
+void brcmf_commonring_unlock(struct brcmf_commonring *commonring);
+bool brcmf_commonring_write_available(struct brcmf_commonring *commonring);
+void *brcmf_commonring_reserve_for_write(struct brcmf_commonring *commonring);
+void *
+brcmf_commonring_reserve_for_write_multiple(struct brcmf_commonring *commonring,
+ u16 n_items, u16 *alloced);
+int brcmf_commonring_write_complete(struct brcmf_commonring *commonring);
+void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
+ u16 n_items);
+void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
+ u16 *n_items);
+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring);
+
+#define brcmf_commonring_n_items(commonring) (commonring->depth)
+#define brcmf_commonring_len_item(commonring) (commonring->item_len)
+
+
+#endif /* BRCMFMAC_COMMONRING_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 16f9ab2568a8..5e4317dbc2b0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -49,16 +49,6 @@
*/
#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
-/* Bus independent dongle command */
-struct brcmf_dcmd {
- uint cmd; /* common dongle cmd definition */
- void *buf; /* pointer to user buffer */
- uint len; /* length of user buffer */
- u8 set; /* get or set request (optional) */
- uint used; /* bytes read or written (optional) */
- uint needed; /* bytes needed (optional) */
-};
-
/**
* struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info
*
@@ -113,6 +103,10 @@ struct brcmf_pub {
struct brcmf_ampdu_rx_reorder
*reorder_flows[BRCMF_AMPDU_RX_REORDER_MAXFLOWS];
+
+ u32 feat_flags;
+ u32 chip_quirks;
+
#ifdef DEBUG
struct dentry *dbgfs_dir;
#endif
@@ -127,12 +121,12 @@ struct brcmf_fws_mac_descriptor;
*
* @BRCMF_NETIF_STOP_REASON_FWS_FC:
* netif stopped due to firmware signalling flow control.
- * @BRCMF_NETIF_STOP_REASON_BLOCK_BUS:
- * netif stopped due to bus blocking.
+ * @BRCMF_NETIF_STOP_REASON_FLOW:
+ * netif stopped due to flowring full.
*/
enum brcmf_netif_stop_reason {
BRCMF_NETIF_STOP_REASON_FWS_FC = 1,
- BRCMF_NETIF_STOP_REASON_BLOCK_BUS = 2
+ BRCMF_NETIF_STOP_REASON_FLOW = 2
};
/**
@@ -185,9 +179,9 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
-u32 brcmf_get_chip_info(struct brcmf_if *ifp);
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
bool success);
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
/* Sets dongle media info (drv_version, mac address). */
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 7735328fff21..3122b86050a1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -19,6 +19,18 @@
#include "dhd_dbg.h"
+/* IDs of the 6 default common rings of msgbuf protocol */
+#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1
+#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2
+#define BRCMF_D2H_MSGRING_TX_COMPLETE 3
+#define BRCMF_D2H_MSGRING_RX_COMPLETE 4
+
+#define BRCMF_NROF_H2D_COMMON_MSGRINGS 2
+#define BRCMF_NROF_D2H_COMMON_MSGRINGS 3
+#define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \
+ BRCMF_NROF_D2H_COMMON_MSGRINGS)
+
/* The level of bus communication with the dongle */
enum brcmf_bus_state {
BRCMF_BUS_UNKNOWN, /* Not determined yet */
@@ -70,6 +82,25 @@ struct brcmf_bus_ops {
struct pktq * (*gettxq)(struct device *dev);
};
+
+/**
+ * struct brcmf_bus_msgbuf - bus ringbuf if in case of msgbuf.
+ *
+ * @commonrings: commonrings which are always there.
+ * @flowrings: commonrings which are dynamically created and destroyed for data.
+ * @rx_dataoffset: if set then all rx data has this this offset.
+ * @max_rxbufpost: maximum number of buffers to post for rx.
+ * @nrof_flowrings: number of flowrings.
+ */
+struct brcmf_bus_msgbuf {
+ struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
+ struct brcmf_commonring **flowrings;
+ u32 rx_dataoffset;
+ u32 max_rxbufpost;
+ u32 nrof_flowrings;
+};
+
+
/**
* struct brcmf_bus - interface structure between common and bus layer
*
@@ -89,6 +120,7 @@ struct brcmf_bus {
union {
struct brcmf_sdio_dev *sdio;
struct brcmf_usbdev *usb;
+ struct brcmf_pciedev *pcie;
} bus_priv;
enum brcmf_bus_protocol_type proto_type;
struct device *dev;
@@ -101,6 +133,7 @@ struct brcmf_bus {
bool always_use_fws_queue;
struct brcmf_bus_ops *ops;
+ struct brcmf_bus_msgbuf *msgbuf;
};
/*
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index ed3e32ce8c23..d991f8e3d9ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -282,6 +282,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
ptr = strrchr(buf, ' ') + 1;
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
+ /* set mpc */
+ err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
+ if (err) {
+ brcmf_err("failed setting mpc\n");
+ goto done;
+ }
+
/*
* Setup timeout if Beacons are lost and roam is off to report
* link down
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 03fe8aca4d32..be9f4f829192 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -41,37 +41,12 @@ void brcmf_debugfs_exit(void)
root_folder = NULL;
}
-static
-ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
- size_t count, loff_t *ppos)
+static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
{
- struct brcmf_pub *drvr = f->private_data;
- struct brcmf_bus *bus = drvr->bus_if;
- char buf[40];
- int res;
-
- /* only allow read from start */
- if (*ppos > 0)
- return 0;
-
- res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
- bus->chip, bus->chip, bus->chiprev);
- return simple_read_from_buffer(data, count, ppos, buf, res);
-}
-
-static const struct file_operations brcmf_debugfs_chipinfo_ops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = brcmf_debugfs_chipinfo_read
-};
-
-static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
-{
- struct dentry *dentry = drvr->dbgfs_dir;
+ struct brcmf_bus *bus = dev_get_drvdata(seq->private);
- if (!IS_ERR_OR_NULL(dentry))
- debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
- &brcmf_debugfs_chipinfo_ops);
+ seq_printf(seq, "chip: %x(%u) rev %u\n",
+ bus->chip, bus->chip, bus->chiprev);
return 0;
}
@@ -83,7 +58,8 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
return -ENODEV;
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
- brcmf_debugfs_create_chipinfo(drvr);
+ brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
+
return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
}
@@ -98,148 +74,44 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
return drvr->dbgfs_dir;
}
-static
-ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct brcmf_sdio_count *sdcnt = f->private_data;
- char buf[750];
- int res;
-
- /* only allow read from start */
- if (*ppos > 0)
- return 0;
-
- res = scnprintf(buf, sizeof(buf),
- "intrcount: %u\nlastintrs: %u\n"
- "pollcnt: %u\nregfails: %u\n"
- "tx_sderrs: %u\nfcqueued: %u\n"
- "rxrtx: %u\nrx_toolong: %u\n"
- "rxc_errors: %u\nrx_hdrfail: %u\n"
- "rx_badhdr: %u\nrx_badseq: %u\n"
- "fc_rcvd: %u\nfc_xoff: %u\n"
- "fc_xon: %u\nrxglomfail: %u\n"
- "rxglomframes: %u\nrxglompkts: %u\n"
- "f2rxhdrs: %u\nf2rxdata: %u\n"
- "f2txdata: %u\nf1regdata: %u\n"
- "tickcnt: %u\ntx_ctlerrs: %lu\n"
- "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
- "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
- sdcnt->intrcount, sdcnt->lastintrs,
- sdcnt->pollcnt, sdcnt->regfails,
- sdcnt->tx_sderrs, sdcnt->fcqueued,
- sdcnt->rxrtx, sdcnt->rx_toolong,
- sdcnt->rxc_errors, sdcnt->rx_hdrfail,
- sdcnt->rx_badhdr, sdcnt->rx_badseq,
- sdcnt->fc_rcvd, sdcnt->fc_xoff,
- sdcnt->fc_xon, sdcnt->rxglomfail,
- sdcnt->rxglomframes, sdcnt->rxglompkts,
- sdcnt->f2rxhdrs, sdcnt->f2rxdata,
- sdcnt->f2txdata, sdcnt->f1regdata,
- sdcnt->tickcnt, sdcnt->tx_ctlerrs,
- sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
- sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
-
- return simple_read_from_buffer(data, count, ppos, buf, res);
-}
-
-static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = brcmf_debugfs_sdio_counter_read
+struct brcmf_debugfs_entry {
+ int (*read)(struct seq_file *seq, void *data);
+ struct brcmf_pub *drvr;
};
-void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
- struct brcmf_sdio_count *sdcnt)
+static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
{
- struct dentry *dentry = drvr->dbgfs_dir;
+ struct brcmf_debugfs_entry *entry = inode->i_private;
- if (!IS_ERR_OR_NULL(dentry))
- debugfs_create_file("counters", S_IRUGO, dentry,
- sdcnt, &brcmf_debugfs_sdio_counter_ops);
-}
-
-static
-ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
- size_t count, loff_t *ppos)
-{
- struct brcmf_fws_stats *fwstats = f->private_data;
- char buf[650];
- int res;
-
- /* only allow read from start */
- if (*ppos > 0)
- return 0;
-
- res = scnprintf(buf, sizeof(buf),
- "header_pulls: %u\n"
- "header_only_pkt: %u\n"
- "tlv_parse_failed: %u\n"
- "tlv_invalid_type: %u\n"
- "mac_update_fails: %u\n"
- "ps_update_fails: %u\n"
- "if_update_fails: %u\n"
- "pkt2bus: %u\n"
- "generic_error: %u\n"
- "rollback_success: %u\n"
- "rollback_failed: %u\n"
- "delayq_full: %u\n"
- "supprq_full: %u\n"
- "txs_indicate: %u\n"
- "txs_discard: %u\n"
- "txs_suppr_core: %u\n"
- "txs_suppr_ps: %u\n"
- "txs_tossed: %u\n"
- "txs_host_tossed: %u\n"
- "bus_flow_block: %u\n"
- "fws_flow_block: %u\n"
- "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
- "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
- fwstats->header_pulls,
- fwstats->header_only_pkt,
- fwstats->tlv_parse_failed,
- fwstats->tlv_invalid_type,
- fwstats->mac_update_failed,
- fwstats->mac_ps_update_failed,
- fwstats->if_update_failed,
- fwstats->pkt2bus,
- fwstats->generic_error,
- fwstats->rollback_success,
- fwstats->rollback_failed,
- fwstats->delayq_full_error,
- fwstats->supprq_full_error,
- fwstats->txs_indicate,
- fwstats->txs_discard,
- fwstats->txs_supp_core,
- fwstats->txs_supp_ps,
- fwstats->txs_tossed,
- fwstats->txs_host_tossed,
- fwstats->bus_flow_block,
- fwstats->fws_flow_block,
- fwstats->send_pkts[0], fwstats->send_pkts[1],
- fwstats->send_pkts[2], fwstats->send_pkts[3],
- fwstats->send_pkts[4],
- fwstats->requested_sent[0],
- fwstats->requested_sent[1],
- fwstats->requested_sent[2],
- fwstats->requested_sent[3],
- fwstats->requested_sent[4]);
-
- return simple_read_from_buffer(data, count, ppos, buf, res);
+ return single_open(f, entry->read, entry->drvr->bus_if->dev);
}
-static const struct file_operations brcmf_debugfs_fws_stats_ops = {
+static const struct file_operations brcmf_debugfs_def_ops = {
.owner = THIS_MODULE,
- .open = simple_open,
- .read = brcmf_debugfs_fws_stats_read
+ .open = brcmf_debugfs_entry_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek
};
-void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
- struct brcmf_fws_stats *stats)
+int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
+ int (*read_fn)(struct seq_file *seq, void *data))
{
struct dentry *dentry = drvr->dbgfs_dir;
+ struct brcmf_debugfs_entry *entry;
+
+ if (IS_ERR_OR_NULL(dentry))
+ return -ENOENT;
+
+ entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->read = read_fn;
+ entry->drvr = drvr;
+
+ dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
+ &brcmf_debugfs_def_ops);
- if (!IS_ERR_OR_NULL(dentry))
- debugfs_create_file("fws_stats", S_IRUGO, dentry,
- stats, &brcmf_debugfs_fws_stats_ops);
+ return PTR_ERR_OR_ZERO(dentry);
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index ef52ed7abc69..dec40d316c82 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -18,23 +18,25 @@
#define _BRCMF_DBG_H_
/* message levels */
-#define BRCMF_TRACE_VAL 0x00000002
-#define BRCMF_INFO_VAL 0x00000004
-#define BRCMF_DATA_VAL 0x00000008
-#define BRCMF_CTL_VAL 0x00000010
-#define BRCMF_TIMER_VAL 0x00000020
-#define BRCMF_HDRS_VAL 0x00000040
-#define BRCMF_BYTES_VAL 0x00000080
-#define BRCMF_INTR_VAL 0x00000100
-#define BRCMF_GLOM_VAL 0x00000200
-#define BRCMF_EVENT_VAL 0x00000400
-#define BRCMF_BTA_VAL 0x00000800
-#define BRCMF_FIL_VAL 0x00001000
-#define BRCMF_USB_VAL 0x00002000
-#define BRCMF_SCAN_VAL 0x00004000
-#define BRCMF_CONN_VAL 0x00008000
-#define BRCMF_BCDC_VAL 0x00010000
-#define BRCMF_SDIO_VAL 0x00020000
+#define BRCMF_TRACE_VAL 0x00000002
+#define BRCMF_INFO_VAL 0x00000004
+#define BRCMF_DATA_VAL 0x00000008
+#define BRCMF_CTL_VAL 0x00000010
+#define BRCMF_TIMER_VAL 0x00000020
+#define BRCMF_HDRS_VAL 0x00000040
+#define BRCMF_BYTES_VAL 0x00000080
+#define BRCMF_INTR_VAL 0x00000100
+#define BRCMF_GLOM_VAL 0x00000200
+#define BRCMF_EVENT_VAL 0x00000400
+#define BRCMF_BTA_VAL 0x00000800
+#define BRCMF_FIL_VAL 0x00001000
+#define BRCMF_USB_VAL 0x00002000
+#define BRCMF_SCAN_VAL 0x00004000
+#define BRCMF_CONN_VAL 0x00008000
+#define BRCMF_BCDC_VAL 0x00010000
+#define BRCMF_SDIO_VAL 0x00020000
+#define BRCMF_MSGBUF_VAL 0x00040000
+#define BRCMF_PCIE_VAL 0x00080000
/* set default print format */
#undef pr_fmt
@@ -100,68 +102,6 @@ do { \
extern int brcmf_msg_level;
-/*
- * hold counter variables used in brcmfmac sdio driver.
- */
-struct brcmf_sdio_count {
- uint intrcount; /* Count of device interrupt callbacks */
- uint lastintrs; /* Count as of last watchdog timer */
- uint pollcnt; /* Count of active polls */
- uint regfails; /* Count of R_REG failures */
- uint tx_sderrs; /* Count of tx attempts with sd errors */
- uint fcqueued; /* Tx packets that got queued */
- uint rxrtx; /* Count of rtx requests (NAK to dongle) */
- uint rx_toolong; /* Receive frames too long to receive */
- uint rxc_errors; /* SDIO errors when reading control frames */
- uint rx_hdrfail; /* SDIO errors on header reads */
- uint rx_badhdr; /* Bad received headers (roosync?) */
- uint rx_badseq; /* Mismatched rx sequence number */
- uint fc_rcvd; /* Number of flow-control events received */
- uint fc_xoff; /* Number which turned on flow-control */
- uint fc_xon; /* Number which turned off flow-control */
- uint rxglomfail; /* Failed deglom attempts */
- uint rxglomframes; /* Number of glom frames (superframes) */
- uint rxglompkts; /* Number of packets from glom frames */
- uint f2rxhdrs; /* Number of header reads */
- uint f2rxdata; /* Number of frame data reads */
- uint f2txdata; /* Number of f2 frame writes */
- uint f1regdata; /* Number of f1 register accesses */
- uint tickcnt; /* Number of watchdog been schedule */
- ulong tx_ctlerrs; /* Err of sending ctrl frames */
- ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
- ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
- ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
- ulong rx_readahead_cnt; /* packets where header read-ahead was used */
-};
-
-struct brcmf_fws_stats {
- u32 tlv_parse_failed;
- u32 tlv_invalid_type;
- u32 header_only_pkt;
- u32 header_pulls;
- u32 pkt2bus;
- u32 send_pkts[5];
- u32 requested_sent[5];
- u32 generic_error;
- u32 mac_update_failed;
- u32 mac_ps_update_failed;
- u32 if_update_failed;
- u32 packet_request_failed;
- u32 credit_request_failed;
- u32 rollback_success;
- u32 rollback_failed;
- u32 delayq_full_error;
- u32 supprq_full_error;
- u32 txs_indicate;
- u32 txs_discard;
- u32 txs_supp_core;
- u32 txs_supp_ps;
- u32 txs_tossed;
- u32 txs_host_tossed;
- u32 bus_flow_block;
- u32 fws_flow_block;
-};
-
struct brcmf_pub;
#ifdef DEBUG
void brcmf_debugfs_init(void);
@@ -169,10 +109,8 @@ void brcmf_debugfs_exit(void);
int brcmf_debugfs_attach(struct brcmf_pub *drvr);
void brcmf_debugfs_detach(struct brcmf_pub *drvr);
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
-void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
- struct brcmf_sdio_count *sdcnt);
-void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
- struct brcmf_fws_stats *stats);
+int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
+ int (*read_fn)(struct seq_file *seq, void *data));
#else
static inline void brcmf_debugfs_init(void)
{
@@ -187,9 +125,11 @@ static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
{
}
-static inline void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
- struct brcmf_fws_stats *stats)
+static inline
+int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
+ int (*read_fn)(struct seq_file *seq, void *data))
{
+ return 0;
}
#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 09dd8c13d844..fb1043908a23 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -30,7 +30,9 @@
#include "wl_cfg80211.h"
#include "fwil.h"
#include "fwsignal.h"
+#include "feature.h"
#include "proto.h"
+#include "pcie.h"
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -287,7 +289,7 @@ void brcmf_txflowblock(struct device *dev, bool state)
brcmf_fws_bus_blocked(drvr, state);
}
-static void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{
skb->dev = ifp->ndev;
skb->protocol = eth_type_trans(skb, skb->dev);
@@ -808,7 +810,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
} else {
brcmf_dbg(INFO, "allocate netdev interface\n");
/* Allocate netdev, including space for private structure */
- ndev = alloc_netdev(sizeof(*ifp), name, ether_setup);
+ ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN,
+ ether_setup);
if (!ndev)
return ERR_PTR(-ENOMEM);
@@ -936,6 +939,8 @@ int brcmf_bus_start(struct device *dev)
if (ret < 0)
goto fail;
+ brcmf_feat_attach(drvr);
+
ret = brcmf_fws_init(drvr);
if (ret < 0)
goto fail;
@@ -1073,16 +1078,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
return !err;
}
-/*
- * return chip id and rev of the device encoded in u32.
- */
-u32 brcmf_get_chip_info(struct brcmf_if *ifp)
-{
- struct brcmf_bus *bus = ifp->drvr->bus_if;
-
- return bus->chip << 4 | bus->chiprev;
-}
-
static void brcmf_driver_register(struct work_struct *work)
{
#ifdef CONFIG_BRCMFMAC_SDIO
@@ -1091,6 +1086,9 @@ static void brcmf_driver_register(struct work_struct *work)
#ifdef CONFIG_BRCMFMAC_USB
brcmf_usb_register();
#endif
+#ifdef CONFIG_BRCMFMAC_PCIE
+ brcmf_pcie_register();
+#endif
}
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
@@ -1116,6 +1114,9 @@ static void __exit brcmfmac_module_exit(void)
#ifdef CONFIG_BRCMFMAC_USB
brcmf_usb_exit();
#endif
+#ifdef CONFIG_BRCMFMAC_PCIE
+ brcmf_pcie_exit();
+#endif
brcmf_debugfs_exit();
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 8fa0dbbbda72..f55f625fd06b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -391,6 +391,40 @@ struct brcmf_sdio_hdrinfo {
u16 tail_pad;
};
+/*
+ * hold counter variables
+ */
+struct brcmf_sdio_count {
+ uint intrcount; /* Count of device interrupt callbacks */
+ uint lastintrs; /* Count as of last watchdog timer */
+ uint pollcnt; /* Count of active polls */
+ uint regfails; /* Count of R_REG failures */
+ uint tx_sderrs; /* Count of tx attempts with sd errors */
+ uint fcqueued; /* Tx packets that got queued */
+ uint rxrtx; /* Count of rtx requests (NAK to dongle) */
+ uint rx_toolong; /* Receive frames too long to receive */
+ uint rxc_errors; /* SDIO errors when reading control frames */
+ uint rx_hdrfail; /* SDIO errors on header reads */
+ uint rx_badhdr; /* Bad received headers (roosync?) */
+ uint rx_badseq; /* Mismatched rx sequence number */
+ uint fc_rcvd; /* Number of flow-control events received */
+ uint fc_xoff; /* Number which turned on flow-control */
+ uint fc_xon; /* Number which turned off flow-control */
+ uint rxglomfail; /* Failed deglom attempts */
+ uint rxglomframes; /* Number of glom frames (superframes) */
+ uint rxglompkts; /* Number of packets from glom frames */
+ uint f2rxhdrs; /* Number of header reads */
+ uint f2rxdata; /* Number of frame data reads */
+ uint f2txdata; /* Number of f2 frame writes */
+ uint f1regdata; /* Number of f1 register accesses */
+ uint tickcnt; /* Number of watchdog been schedule */
+ ulong tx_ctlerrs; /* Err of sending ctrl frames */
+ ulong tx_ctlpkts; /* Ctrl frames sent to dongle */
+ ulong rx_ctlerrs; /* Err of processing rx ctrl frames */
+ ulong rx_ctlpkts; /* Ctrl frames processed from dongle */
+ ulong rx_readahead_cnt; /* packets where header read-ahead was used */
+};
+
/* misc chip info needed by some of the routines */
/* Private data for SDIO bus interaction */
struct brcmf_sdio {
@@ -620,40 +654,57 @@ enum brcmf_firmware_type {
name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
static const struct brcmf_firmware_names brcmf_fwname_data[] = {
- { BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
- { BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
- { BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
- { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
- { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
- { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
- { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
- { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
- { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
- { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
+ { BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
+ { BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
+ { BRCM_CC_43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
+ { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
+ { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
+ { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
+ { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
+ { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
+ { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
+ { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
};
-static const char *brcmf_sdio_get_fwname(struct brcmf_chip *ci,
- enum brcmf_firmware_type type)
+static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
+ struct brcmf_sdio_dev *sdiodev)
{
int i;
+ uint fw_len, nv_len;
+ char end;
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
if (brcmf_fwname_data[i].chipid == ci->chip &&
- brcmf_fwname_data[i].revmsk & BIT(ci->chiprev)) {
- switch (type) {
- case BRCMF_FIRMWARE_BIN:
- return brcmf_fwname_data[i].bin;
- case BRCMF_FIRMWARE_NVRAM:
- return brcmf_fwname_data[i].nv;
- default:
- brcmf_err("invalid firmware type (%d)\n", type);
- return NULL;
- }
+ brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(brcmf_fwname_data)) {
+ brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev);
+ return -ENODEV;
+ }
+
+ fw_len = sizeof(sdiodev->fw_name) - 1;
+ nv_len = sizeof(sdiodev->nvram_name) - 1;
+ /* check if firmware path is provided by module parameter */
+ if (brcmf_firmware_path[0] != '\0') {
+ strncpy(sdiodev->fw_name, brcmf_firmware_path, fw_len);
+ strncpy(sdiodev->nvram_name, brcmf_firmware_path, nv_len);
+ fw_len -= strlen(sdiodev->fw_name);
+ nv_len -= strlen(sdiodev->nvram_name);
+
+ end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
+ if (end != '/') {
+ strncat(sdiodev->fw_name, "/", fw_len);
+ strncat(sdiodev->nvram_name, "/", nv_len);
+ fw_len--;
+ nv_len--;
}
}
- brcmf_err("Unknown chipid %d [%d]\n",
- ci->chip, ci->chiprev);
- return NULL;
+ strncat(sdiodev->fw_name, brcmf_fwname_data[i].bin, fw_len);
+ strncat(sdiodev->nvram_name, brcmf_fwname_data[i].nv, nv_len);
+
+ return 0;
}
static void pkt_align(struct sk_buff *p, int len, int align)
@@ -2898,16 +2949,13 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
}
#ifdef DEBUG
-static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
- struct sdpcm_shared *sh, char __user *data,
- size_t count)
+static int brcmf_sdio_dump_console(struct seq_file *seq, struct brcmf_sdio *bus,
+ struct sdpcm_shared *sh)
{
u32 addr, console_ptr, console_size, console_index;
char *conbuf = NULL;
__le32 sh_val;
int rv;
- loff_t pos = 0;
- int nbytes = 0;
/* obtain console information from device memory */
addr = sh->console_addr + offsetof(struct rte_console, log_le);
@@ -2945,33 +2993,24 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
if (rv < 0)
goto done;
- rv = simple_read_from_buffer(data, count, &pos,
- conbuf + console_index,
- console_size - console_index);
+ rv = seq_write(seq, conbuf + console_index,
+ console_size - console_index);
if (rv < 0)
goto done;
- nbytes = rv;
- if (console_index > 0) {
- pos = 0;
- rv = simple_read_from_buffer(data+nbytes, count, &pos,
- conbuf, console_index - 1);
- if (rv < 0)
- goto done;
- rv += nbytes;
- }
+ if (console_index > 0)
+ rv = seq_write(seq, conbuf, console_index - 1);
+
done:
vfree(conbuf);
return rv;
}
-static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
- char __user *data, size_t count)
+static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
+ struct sdpcm_shared *sh)
{
- int error, res;
- char buf[350];
+ int error;
struct brcmf_trap_info tr;
- loff_t pos = 0;
if ((sh->flags & SDPCM_SHARED_TRAP) == 0) {
brcmf_dbg(INFO, "no trap in firmware\n");
@@ -2983,34 +3022,30 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
if (error < 0)
return error;
- res = scnprintf(buf, sizeof(buf),
- "dongle trap info: type 0x%x @ epc 0x%08x\n"
- " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
- " lr 0x%08x pc 0x%08x offset 0x%x\n"
- " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
- " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
- le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
- le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
- le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
- le32_to_cpu(tr.pc), sh->trap_addr,
- le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
- le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
- le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
- le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
-
- return simple_read_from_buffer(data, count, &pos, buf, res);
+ seq_printf(seq,
+ "dongle trap info: type 0x%x @ epc 0x%08x\n"
+ " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
+ " lr 0x%08x pc 0x%08x offset 0x%x\n"
+ " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
+ " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
+ le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
+ le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
+ le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
+ le32_to_cpu(tr.pc), sh->trap_addr,
+ le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
+ le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
+ le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
+ le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
+
+ return 0;
}
-static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
- struct sdpcm_shared *sh, char __user *data,
- size_t count)
+static int brcmf_sdio_assert_info(struct seq_file *seq, struct brcmf_sdio *bus,
+ struct sdpcm_shared *sh)
{
int error = 0;
- char buf[200];
char file[80] = "?";
char expr[80] = "<???>";
- int res;
- loff_t pos = 0;
if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
brcmf_dbg(INFO, "firmware not built with -assert\n");
@@ -3035,10 +3070,9 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
}
sdio_release_host(bus->sdiodev->func[1]);
- res = scnprintf(buf, sizeof(buf),
- "dongle assert: %s:%d: assert(%s)\n",
- file, sh->assert_line, expr);
- return simple_read_from_buffer(data, count, &pos, buf, res);
+ seq_printf(seq, "dongle assert: %s:%d: assert(%s)\n",
+ file, sh->assert_line, expr);
+ return 0;
}
static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
@@ -3062,59 +3096,75 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
return 0;
}
-static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data,
- size_t count, loff_t *ppos)
+static int brcmf_sdio_died_dump(struct seq_file *seq, struct brcmf_sdio *bus)
{
int error = 0;
struct sdpcm_shared sh;
- int nbytes = 0;
- loff_t pos = *ppos;
-
- if (pos != 0)
- return 0;
error = brcmf_sdio_readshared(bus, &sh);
if (error < 0)
goto done;
- error = brcmf_sdio_assert_info(bus, &sh, data, count);
+ error = brcmf_sdio_assert_info(seq, bus, &sh);
if (error < 0)
goto done;
- nbytes = error;
- error = brcmf_sdio_trap_info(bus, &sh, data+nbytes, count);
+ error = brcmf_sdio_trap_info(seq, bus, &sh);
if (error < 0)
goto done;
- nbytes += error;
- error = brcmf_sdio_dump_console(bus, &sh, data+nbytes, count);
- if (error < 0)
- goto done;
- nbytes += error;
+ error = brcmf_sdio_dump_console(seq, bus, &sh);
- error = nbytes;
- *ppos += nbytes;
done:
return error;
}
-static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data,
- size_t count, loff_t *ppos)
+static int brcmf_sdio_forensic_read(struct seq_file *seq, void *data)
{
- struct brcmf_sdio *bus = f->private_data;
- int res;
+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
+ struct brcmf_sdio *bus = bus_if->bus_priv.sdio->bus;
- res = brcmf_sdio_died_dump(bus, data, count, ppos);
- if (res > 0)
- *ppos += res;
- return (ssize_t)res;
+ return brcmf_sdio_died_dump(seq, bus);
}
-static const struct file_operations brcmf_sdio_forensic_ops = {
- .owner = THIS_MODULE,
- .open = simple_open,
- .read = brcmf_sdio_forensic_read
-};
+static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_sdio_count *sdcnt = &sdiodev->bus->sdcnt;
+
+ seq_printf(seq,
+ "intrcount: %u\nlastintrs: %u\n"
+ "pollcnt: %u\nregfails: %u\n"
+ "tx_sderrs: %u\nfcqueued: %u\n"
+ "rxrtx: %u\nrx_toolong: %u\n"
+ "rxc_errors: %u\nrx_hdrfail: %u\n"
+ "rx_badhdr: %u\nrx_badseq: %u\n"
+ "fc_rcvd: %u\nfc_xoff: %u\n"
+ "fc_xon: %u\nrxglomfail: %u\n"
+ "rxglomframes: %u\nrxglompkts: %u\n"
+ "f2rxhdrs: %u\nf2rxdata: %u\n"
+ "f2txdata: %u\nf1regdata: %u\n"
+ "tickcnt: %u\ntx_ctlerrs: %lu\n"
+ "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n"
+ "rx_ctlpkts: %lu\nrx_readahead: %lu\n",
+ sdcnt->intrcount, sdcnt->lastintrs,
+ sdcnt->pollcnt, sdcnt->regfails,
+ sdcnt->tx_sderrs, sdcnt->fcqueued,
+ sdcnt->rxrtx, sdcnt->rx_toolong,
+ sdcnt->rxc_errors, sdcnt->rx_hdrfail,
+ sdcnt->rx_badhdr, sdcnt->rx_badseq,
+ sdcnt->fc_rcvd, sdcnt->fc_xoff,
+ sdcnt->fc_xon, sdcnt->rxglomfail,
+ sdcnt->rxglomframes, sdcnt->rxglompkts,
+ sdcnt->f2rxhdrs, sdcnt->f2rxdata,
+ sdcnt->f2txdata, sdcnt->f1regdata,
+ sdcnt->tickcnt, sdcnt->tx_ctlerrs,
+ sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
+ sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);
+
+ return 0;
+}
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
{
@@ -3124,9 +3174,9 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
if (IS_ERR_OR_NULL(dentry))
return;
- debugfs_create_file("forensics", S_IRUGO, dentry, bus,
- &brcmf_sdio_forensic_ops);
- brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
+ brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
+ brcmf_debugfs_add_entry(drvr, "counters",
+ brcmf_debugfs_sdio_count_read);
debugfs_create_u32("console_interval", 0644, dentry,
&bus->console_interval);
}
@@ -3598,17 +3648,17 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
return;
switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
- case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
+ case SDIOD_DRVSTR_KEY(BRCM_CC_4330_CHIP_ID, 12):
str_tab = sdiod_drvstr_tab1_1v8;
str_mask = 0x00003800;
str_shift = 11;
break;
- case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
+ case SDIOD_DRVSTR_KEY(BRCM_CC_4334_CHIP_ID, 17):
str_tab = sdiod_drvstr_tab6_1v8;
str_mask = 0x00001800;
str_shift = 11;
break;
- case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
+ case SDIOD_DRVSTR_KEY(BRCM_CC_43143_CHIP_ID, 17):
/* note: 43143 does not support tristate */
i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
@@ -3619,7 +3669,7 @@ brcmf_sdio_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
ci->name, drivestrength);
break;
- case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
+ case SDIOD_DRVSTR_KEY(BRCM_CC_43362_CHIP_ID, 13):
str_tab = sdiod_drive_strength_tab5_1v8;
str_mask = 0x00003800;
str_shift = 11;
@@ -3720,12 +3770,12 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
u32 val, rev;
val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
- if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
+ if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID &&
addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
if (rev >= 2) {
val &= ~CID_ID_MASK;
- val |= BCM4339_CHIP_ID;
+ val |= BRCM_CC_4339_CHIP_ID;
}
}
return val;
@@ -4127,11 +4177,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
brcmf_sdio_debugfs_create(bus);
brcmf_dbg(INFO, "completed!!\n");
+ ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev);
+ if (ret)
+ goto fail;
+
ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
- brcmf_sdio_get_fwname(bus->ci,
- BRCMF_FIRMWARE_BIN),
- brcmf_sdio_get_fwname(bus->ci,
- BRCMF_FIRMWARE_NVRAM),
+ sdiodev->fw_name, sdiodev->nvram_name,
brcmf_sdio_firmware_callback);
if (ret != 0) {
brcmf_err("async firmware request failed: %d\n", ret);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
new file mode 100644
index 000000000000..50877e3c5d2f
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/netdevice.h>
+
+#include <brcm_hw_ids.h>
+#include "dhd.h"
+#include "dhd_bus.h"
+#include "dhd_dbg.h"
+#include "fwil.h"
+#include "feature.h"
+
+/*
+ * firmware error code received if iovar is unsupported.
+ */
+#define EBRCMF_FEAT_UNSUPPORTED 23
+
+/*
+ * expand feature list to array of feature strings.
+ */
+#define BRCMF_FEAT_DEF(_f) \
+ #_f,
+static const char *brcmf_feat_names[] = {
+ BRCMF_FEAT_LIST
+};
+#undef BRCMF_FEAT_DEF
+
+#ifdef DEBUG
+/*
+ * expand quirk list to array of quirk strings.
+ */
+#define BRCMF_QUIRK_DEF(_q) \
+ #_q,
+static const char * const brcmf_quirk_names[] = {
+ BRCMF_QUIRK_LIST
+};
+#undef BRCMF_QUIRK_DEF
+
+/**
+ * brcmf_feat_debugfs_read() - expose feature info to debugfs.
+ *
+ * @seq: sequence for debugfs entry.
+ * @data: raw data pointer.
+ */
+static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
+ u32 feats = bus_if->drvr->feat_flags;
+ u32 quirks = bus_if->drvr->chip_quirks;
+ int id;
+
+ seq_printf(seq, "Features: %08x\n", feats);
+ for (id = 0; id < BRCMF_FEAT_LAST; id++)
+ if (feats & BIT(id))
+ seq_printf(seq, "\t%s\n", brcmf_feat_names[id]);
+ seq_printf(seq, "\nQuirks: %08x\n", quirks);
+ for (id = 0; id < BRCMF_FEAT_QUIRK_LAST; id++)
+ if (quirks & BIT(id))
+ seq_printf(seq, "\t%s\n", brcmf_quirk_names[id]);
+ return 0;
+}
+#else
+static int brcmf_feat_debugfs_read(struct seq_file *seq, void *data)
+{
+ return 0;
+}
+#endif /* DEBUG */
+
+/**
+ * brcmf_feat_iovar_int_get() - determine feature through iovar query.
+ *
+ * @ifp: interface to query.
+ * @id: feature id.
+ * @name: iovar name.
+ */
+static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
+ enum brcmf_feat_id id, char *name)
+{
+ u32 data;
+ int err;
+
+ err = brcmf_fil_iovar_int_get(ifp, name, &data);
+ if (err == 0) {
+ brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
+ ifp->drvr->feat_flags |= BIT(id);
+ } else {
+ brcmf_dbg(TRACE, "%s feature check failed: %d\n",
+ brcmf_feat_names[id], err);
+ }
+}
+
+void brcmf_feat_attach(struct brcmf_pub *drvr)
+{
+ struct brcmf_if *ifp = drvr->iflist[0];
+
+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
+
+ /* set chip related quirks */
+ switch (drvr->bus_if->chip) {
+ case BRCM_CC_43236_CHIP_ID:
+ drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_AUTO_AUTH);
+ break;
+ case BRCM_CC_4329_CHIP_ID:
+ drvr->chip_quirks |= BIT(BRCMF_FEAT_QUIRK_NEED_MPC);
+ break;
+ default:
+ /* no quirks */
+ break;
+ }
+
+ brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read);
+}
+
+bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id)
+{
+ return (ifp->drvr->feat_flags & BIT(id));
+}
+
+bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
+ enum brcmf_feat_quirk quirk)
+{
+ return (ifp->drvr->chip_quirks & BIT(quirk));
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
new file mode 100644
index 000000000000..961d175f8afb
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _BRCMF_FEATURE_H
+#define _BRCMF_FEATURE_H
+
+/*
+ * Features:
+ *
+ * MCHAN: multi-channel for concurrent P2P.
+ */
+#define BRCMF_FEAT_LIST \
+ BRCMF_FEAT_DEF(MCHAN)
+/*
+ * Quirks:
+ *
+ * AUTO_AUTH: workaround needed for automatic authentication type.
+ * NEED_MPC: driver needs to disable MPC during scanning operation.
+ */
+#define BRCMF_QUIRK_LIST \
+ BRCMF_QUIRK_DEF(AUTO_AUTH) \
+ BRCMF_QUIRK_DEF(NEED_MPC)
+
+#define BRCMF_FEAT_DEF(_f) \
+ BRCMF_FEAT_ ## _f,
+/*
+ * expand feature list to enumeration.
+ */
+enum brcmf_feat_id {
+ BRCMF_FEAT_LIST
+ BRCMF_FEAT_LAST
+};
+#undef BRCMF_FEAT_DEF
+
+#define BRCMF_QUIRK_DEF(_q) \
+ BRCMF_FEAT_QUIRK_ ## _q,
+/*
+ * expand quirk list to enumeration.
+ */
+enum brcmf_feat_quirk {
+ BRCMF_QUIRK_LIST
+ BRCMF_FEAT_QUIRK_LAST
+};
+#undef BRCMF_QUIRK_DEF
+
+/**
+ * brcmf_feat_attach() - determine features and quirks.
+ *
+ * @drvr: driver instance.
+ */
+void brcmf_feat_attach(struct brcmf_pub *drvr);
+
+/**
+ * brcmf_feat_is_enabled() - query feature.
+ *
+ * @ifp: interface instance.
+ * @id: feature id to check.
+ *
+ * Return: true is feature is enabled; otherwise false.
+ */
+bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id);
+
+/**
+ * brcmf_feat_is_quirk_enabled() - query chip quirk.
+ *
+ * @ifp: interface instance.
+ * @quirk: quirk id to check.
+ *
+ * Return: true is quirk is enabled; otherwise false.
+ */
+bool brcmf_feat_is_quirk_enabled(struct brcmf_if *ifp,
+ enum brcmf_feat_quirk quirk);
+
+#endif /* _BRCMF_FEATURE_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 7b7d237c1ddb..8ea9f283d2b8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -18,10 +18,15 @@
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/firmware.h>
+#include <linux/module.h>
#include "dhd_dbg.h"
#include "firmware.h"
+char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
+module_param_string(firmware_path, brcmf_firmware_path,
+ BRCMF_FW_PATH_LEN, 0440);
+
enum nvram_parser_state {
IDLE,
KEY,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
index 6431bfd7afff..4d3482356b77 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.h
@@ -21,6 +21,11 @@
#define BRCMF_FW_REQ_FLAGS 0x00F0
#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
+#define BRCMF_FW_PATH_LEN 256
+#define BRCMF_FW_NAME_LEN 32
+
+extern char brcmf_firmware_path[];
+
void brcmf_fw_nvram_free(void *nvram);
/*
* Request firmware(s) asynchronously. When the asynchronous request
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
new file mode 100644
index 000000000000..a1016b811284
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -0,0 +1,501 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <brcmu_utils.h>
+
+#include "dhd.h"
+#include "dhd_dbg.h"
+#include "dhd_bus.h"
+#include "proto.h"
+#include "flowring.h"
+#include "msgbuf.h"
+
+
+#define BRCMF_FLOWRING_HIGH 1024
+#define BRCMF_FLOWRING_LOW (BRCMF_FLOWRING_HIGH - 256)
+#define BRCMF_FLOWRING_INVALID_IFIDX 0xff
+
+#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] + fifo + ifidx * 16)
+#define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16)
+
+static const u8 ALLZEROMAC[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+static const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+static const u8 brcmf_flowring_prio2fifo[] = {
+ 1,
+ 0,
+ 0,
+ 1,
+ 2,
+ 2,
+ 3,
+ 3
+};
+
+
+static bool
+brcmf_flowring_is_tdls_mac(struct brcmf_flowring *flow, u8 mac[ETH_ALEN])
+{
+ struct brcmf_flowring_tdls_entry *search;
+
+ search = flow->tdls_entry;
+
+ while (search) {
+ if (memcmp(search->mac, mac, ETH_ALEN) == 0)
+ return true;
+ search = search->next;
+ }
+
+ return false;
+}
+
+
+u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
+ u8 prio, u8 ifidx)
+{
+ struct brcmf_flowring_hash *hash;
+ u8 hash_idx;
+ u32 i;
+ bool found;
+ bool sta;
+ u8 fifo;
+ u8 *mac;
+
+ fifo = brcmf_flowring_prio2fifo[prio];
+ sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT);
+ mac = da;
+ if ((!sta) && (is_multicast_ether_addr(da))) {
+ mac = (u8 *)ALLFFMAC;
+ fifo = 0;
+ }
+ if ((sta) && (flow->tdls_active) &&
+ (brcmf_flowring_is_tdls_mac(flow, da))) {
+ sta = false;
+ }
+ hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
+ BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
+ found = false;
+ hash = flow->hash;
+ for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
+ if ((sta || (memcmp(hash[hash_idx].mac, mac, ETH_ALEN) == 0)) &&
+ (hash[hash_idx].fifo == fifo) &&
+ (hash[hash_idx].ifidx == ifidx)) {
+ found = true;
+ break;
+ }
+ hash_idx++;
+ }
+ if (found)
+ return hash[hash_idx].flowid;
+
+ return BRCMF_FLOWRING_INVALID_ID;
+}
+
+
+u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
+ u8 prio, u8 ifidx)
+{
+ struct brcmf_flowring_ring *ring;
+ struct brcmf_flowring_hash *hash;
+ u8 hash_idx;
+ u32 i;
+ bool found;
+ u8 fifo;
+ bool sta;
+ u8 *mac;
+
+ fifo = brcmf_flowring_prio2fifo[prio];
+ sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT);
+ mac = da;
+ if ((!sta) && (is_multicast_ether_addr(da))) {
+ mac = (u8 *)ALLFFMAC;
+ fifo = 0;
+ }
+ if ((sta) && (flow->tdls_active) &&
+ (brcmf_flowring_is_tdls_mac(flow, da))) {
+ sta = false;
+ }
+ hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
+ BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
+ found = false;
+ hash = flow->hash;
+ for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
+ if ((hash[hash_idx].ifidx == BRCMF_FLOWRING_INVALID_IFIDX) &&
+ (memcmp(hash[hash_idx].mac, ALLZEROMAC, ETH_ALEN) == 0)) {
+ found = true;
+ break;
+ }
+ hash_idx++;
+ }
+ if (found) {
+ for (i = 0; i < flow->nrofrings; i++) {
+ if (flow->rings[i] == NULL)
+ break;
+ }
+ if (i == flow->nrofrings)
+ return -ENOMEM;
+
+ ring = kzalloc(sizeof(*ring), GFP_ATOMIC);
+ if (!ring)
+ return -ENOMEM;
+
+ memcpy(hash[hash_idx].mac, mac, ETH_ALEN);
+ hash[hash_idx].fifo = fifo;
+ hash[hash_idx].ifidx = ifidx;
+ hash[hash_idx].flowid = i;
+
+ ring->hash_id = hash_idx;
+ ring->status = RING_CLOSED;
+ skb_queue_head_init(&ring->skblist);
+ flow->rings[i] = ring;
+
+ return i;
+ }
+ return BRCMF_FLOWRING_INVALID_ID;
+}
+
+
+u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+
+ ring = flow->rings[flowid];
+
+ return flow->hash[ring->hash_id].fifo;
+}
+
+
+static void brcmf_flowring_block(struct brcmf_flowring *flow, u8 flowid,
+ bool blocked)
+{
+ struct brcmf_flowring_ring *ring;
+ struct brcmf_bus *bus_if;
+ struct brcmf_pub *drvr;
+ struct brcmf_if *ifp;
+ bool currently_blocked;
+ int i;
+ u8 ifidx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&flow->block_lock, flags);
+
+ ring = flow->rings[flowid];
+ ifidx = brcmf_flowring_ifidx_get(flow, flowid);
+
+ currently_blocked = false;
+ for (i = 0; i < flow->nrofrings; i++) {
+ if (flow->rings[i]) {
+ ring = flow->rings[i];
+ if ((ring->status == RING_OPEN) &&
+ (brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
+ if (ring->blocked) {
+ currently_blocked = true;
+ break;
+ }
+ }
+ }
+ }
+ ring->blocked = blocked;
+ if (currently_blocked == blocked) {
+ spin_unlock_irqrestore(&flow->block_lock, flags);
+ return;
+ }
+
+ bus_if = dev_get_drvdata(flow->dev);
+ drvr = bus_if->drvr;
+ ifp = drvr->iflist[ifidx];
+ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked);
+
+ spin_unlock_irqrestore(&flow->block_lock, flags);
+}
+
+
+void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+ u8 hash_idx;
+ struct sk_buff *skb;
+
+ ring = flow->rings[flowid];
+ if (!ring)
+ return;
+ brcmf_flowring_block(flow, flowid, false);
+ hash_idx = ring->hash_id;
+ flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
+ memset(flow->hash[hash_idx].mac, 0, ETH_ALEN);
+ flow->rings[flowid] = NULL;
+
+ skb = skb_dequeue(&ring->skblist);
+ while (skb) {
+ brcmu_pkt_buf_free_skb(skb);
+ skb = skb_dequeue(&ring->skblist);
+ }
+
+ kfree(ring);
+}
+
+
+void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
+ struct sk_buff *skb)
+{
+ struct brcmf_flowring_ring *ring;
+
+ ring = flow->rings[flowid];
+
+ skb_queue_tail(&ring->skblist, skb);
+
+ if (!ring->blocked &&
+ (skb_queue_len(&ring->skblist) > BRCMF_FLOWRING_HIGH)) {
+ brcmf_flowring_block(flow, flowid, true);
+ brcmf_dbg(MSGBUF, "Flowcontrol: BLOCK for ring %d\n", flowid);
+ /* To prevent (work around) possible race condition, check
+ * queue len again. It is also possible to use locking to
+ * protect, but that is undesirable for every enqueue and
+ * dequeue. This simple check will solve a possible race
+ * condition if it occurs.
+ */
+ if (skb_queue_len(&ring->skblist) < BRCMF_FLOWRING_LOW)
+ brcmf_flowring_block(flow, flowid, false);
+ }
+}
+
+
+struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+ struct sk_buff *skb;
+
+ ring = flow->rings[flowid];
+ if (ring->status != RING_OPEN)
+ return NULL;
+
+ skb = skb_dequeue(&ring->skblist);
+
+ if (ring->blocked &&
+ (skb_queue_len(&ring->skblist) < BRCMF_FLOWRING_LOW)) {
+ brcmf_flowring_block(flow, flowid, false);
+ brcmf_dbg(MSGBUF, "Flowcontrol: OPEN for ring %d\n", flowid);
+ }
+
+ return skb;
+}
+
+
+void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid,
+ struct sk_buff *skb)
+{
+ struct brcmf_flowring_ring *ring;
+
+ ring = flow->rings[flowid];
+
+ skb_queue_head(&ring->skblist, skb);
+}
+
+
+u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+
+ ring = flow->rings[flowid];
+ if (!ring)
+ return 0;
+
+ if (ring->status != RING_OPEN)
+ return 0;
+
+ return skb_queue_len(&ring->skblist);
+}
+
+
+void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+
+ ring = flow->rings[flowid];
+ if (!ring) {
+ brcmf_err("Ring NULL, for flowid %d\n", flowid);
+ return;
+ }
+
+ ring->status = RING_OPEN;
+}
+
+
+u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid)
+{
+ struct brcmf_flowring_ring *ring;
+ u8 hash_idx;
+
+ ring = flow->rings[flowid];
+ hash_idx = ring->hash_id;
+
+ return flow->hash[hash_idx].ifidx;
+}
+
+
+struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings)
+{
+ struct brcmf_flowring *flow;
+ u32 i;
+
+ flow = kzalloc(sizeof(*flow), GFP_ATOMIC);
+ if (flow) {
+ flow->dev = dev;
+ flow->nrofrings = nrofrings;
+ spin_lock_init(&flow->block_lock);
+ for (i = 0; i < ARRAY_SIZE(flow->addr_mode); i++)
+ flow->addr_mode[i] = ADDR_INDIRECT;
+ for (i = 0; i < ARRAY_SIZE(flow->hash); i++)
+ flow->hash[i].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
+ flow->rings = kcalloc(nrofrings, sizeof(*flow->rings),
+ GFP_ATOMIC);
+ if (!flow->rings) {
+ kfree(flow);
+ flow = NULL;
+ }
+ }
+
+ return flow;
+}
+
+
+void brcmf_flowring_detach(struct brcmf_flowring *flow)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_flowring_tdls_entry *search;
+ struct brcmf_flowring_tdls_entry *remove;
+ u8 flowid;
+
+ for (flowid = 0; flowid < flow->nrofrings; flowid++) {
+ if (flow->rings[flowid])
+ brcmf_msgbuf_delete_flowring(drvr, flowid);
+ }
+
+ search = flow->tdls_entry;
+ while (search) {
+ remove = search;
+ search = search->next;
+ kfree(remove);
+ }
+ kfree(flow->rings);
+ kfree(flow);
+}
+
+
+void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
+ enum proto_addr_mode addr_mode)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ u32 i;
+ u8 flowid;
+
+ if (flow->addr_mode[ifidx] != addr_mode) {
+ for (i = 0; i < ARRAY_SIZE(flow->hash); i++) {
+ if (flow->hash[i].ifidx == ifidx) {
+ flowid = flow->hash[i].flowid;
+ if (flow->rings[flowid]->status != RING_OPEN)
+ continue;
+ flow->rings[flowid]->status = RING_CLOSING;
+ brcmf_msgbuf_delete_flowring(drvr, flowid);
+ }
+ }
+ flow->addr_mode[ifidx] = addr_mode;
+ }
+}
+
+
+void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_flowring_hash *hash;
+ struct brcmf_flowring_tdls_entry *prev;
+ struct brcmf_flowring_tdls_entry *search;
+ u32 i;
+ u8 flowid;
+ bool sta;
+
+ sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT);
+
+ search = flow->tdls_entry;
+ prev = NULL;
+ while (search) {
+ if (memcmp(search->mac, peer, ETH_ALEN) == 0) {
+ sta = false;
+ break;
+ }
+ prev = search;
+ search = search->next;
+ }
+
+ hash = flow->hash;
+ for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
+ if ((sta || (memcmp(hash[i].mac, peer, ETH_ALEN) == 0)) &&
+ (hash[i].ifidx == ifidx)) {
+ flowid = flow->hash[i].flowid;
+ if (flow->rings[flowid]->status == RING_OPEN) {
+ flow->rings[flowid]->status = RING_CLOSING;
+ brcmf_msgbuf_delete_flowring(drvr, flowid);
+ }
+ }
+ }
+
+ if (search) {
+ if (prev)
+ prev->next = search->next;
+ else
+ flow->tdls_entry = search->next;
+ kfree(search);
+ if (flow->tdls_entry == NULL)
+ flow->tdls_active = false;
+ }
+}
+
+
+void brcmf_flowring_add_tdls_peer(struct brcmf_flowring *flow, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+ struct brcmf_flowring_tdls_entry *tdls_entry;
+ struct brcmf_flowring_tdls_entry *search;
+
+ tdls_entry = kzalloc(sizeof(*tdls_entry), GFP_ATOMIC);
+ if (tdls_entry == NULL)
+ return;
+
+ memcpy(tdls_entry->mac, peer, ETH_ALEN);
+ tdls_entry->next = NULL;
+ if (flow->tdls_entry == NULL) {
+ flow->tdls_entry = tdls_entry;
+ } else {
+ search = flow->tdls_entry;
+ if (memcmp(search->mac, peer, ETH_ALEN) == 0)
+ return;
+ while (search->next) {
+ search = search->next;
+ if (memcmp(search->mac, peer, ETH_ALEN) == 0)
+ return;
+ }
+ search->next = tdls_entry;
+ }
+
+ flow->tdls_active = true;
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.h b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
new file mode 100644
index 000000000000..a34cd394c616
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef BRCMFMAC_FLOWRING_H
+#define BRCMFMAC_FLOWRING_H
+
+
+#define BRCMF_FLOWRING_HASHSIZE 256
+#define BRCMF_FLOWRING_INVALID_ID 0xFFFFFFFF
+
+
+struct brcmf_flowring_hash {
+ u8 mac[ETH_ALEN];
+ u8 fifo;
+ u8 ifidx;
+ u8 flowid;
+};
+
+enum ring_status {
+ RING_CLOSED,
+ RING_CLOSING,
+ RING_OPEN
+};
+
+struct brcmf_flowring_ring {
+ u8 hash_id;
+ bool blocked;
+ enum ring_status status;
+ struct sk_buff_head skblist;
+};
+
+struct brcmf_flowring_tdls_entry {
+ u8 mac[ETH_ALEN];
+ struct brcmf_flowring_tdls_entry *next;
+};
+
+struct brcmf_flowring {
+ struct device *dev;
+ struct brcmf_flowring_hash hash[BRCMF_FLOWRING_HASHSIZE];
+ struct brcmf_flowring_ring **rings;
+ spinlock_t block_lock;
+ enum proto_addr_mode addr_mode[BRCMF_MAX_IFS];
+ u16 nrofrings;
+ bool tdls_active;
+ struct brcmf_flowring_tdls_entry *tdls_entry;
+};
+
+
+u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
+ u8 prio, u8 ifidx);
+u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
+ u8 prio, u8 ifidx);
+void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid);
+void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid);
+u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid);
+void brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
+ struct sk_buff *skb);
+struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid);
+void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid,
+ struct sk_buff *skb);
+u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid);
+u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid);
+struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings);
+void brcmf_flowring_detach(struct brcmf_flowring *flow);
+void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
+ enum proto_addr_mode addr_mode);
+void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
+ u8 peer[ETH_ALEN]);
+void brcmf_flowring_add_tdls_peer(struct brcmf_flowring *flow, int ifidx,
+ u8 peer[ETH_ALEN]);
+
+
+#endif /* BRCMFMAC_FLOWRING_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index fad77dd2a3a5..4f1daabc551b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -293,7 +293,11 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
goto event_free;
}
- ifp = drvr->iflist[emsg.bsscfgidx];
+ if ((event->code == BRCMF_E_TDLS_PEER_EVENT) &&
+ (emsg.bsscfgidx == 1))
+ ifp = drvr->iflist[0];
+ else
+ ifp = drvr->iflist[emsg.bsscfgidx];
err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg,
event->data);
if (err) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 51b53a73d074..dd20b1862d44 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -102,6 +102,7 @@ struct brcmf_event;
BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
+ BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
@@ -155,6 +156,10 @@ enum brcmf_fweh_event_code {
#define BRCMF_E_REASON_TSPEC_REJECTED 7
#define BRCMF_E_REASON_BETTER_AP 8
+#define BRCMF_E_REASON_TDLS_PEER_DISCOVERED 0
+#define BRCMF_E_REASON_TDLS_PEER_CONNECTED 1
+#define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED 2
+
/* action field values for brcmf_ifevent */
#define BRCMF_E_IF_ADD 1
#define BRCMF_E_IF_DEL 2
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 59a5af5bf994..ded328f80cd1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -54,7 +54,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
if (err >= 0)
err = 0;
else
- brcmf_err("Failed err=%d\n", err);
+ brcmf_dbg(FIL, "Failed err=%d\n", err);
return err;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 699908de314a..d42f7d04b65f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -454,6 +454,34 @@ struct brcmf_fws_macdesc_table {
struct brcmf_fws_mac_descriptor other;
};
+struct brcmf_fws_stats {
+ u32 tlv_parse_failed;
+ u32 tlv_invalid_type;
+ u32 header_only_pkt;
+ u32 header_pulls;
+ u32 pkt2bus;
+ u32 send_pkts[5];
+ u32 requested_sent[5];
+ u32 generic_error;
+ u32 mac_update_failed;
+ u32 mac_ps_update_failed;
+ u32 if_update_failed;
+ u32 packet_request_failed;
+ u32 credit_request_failed;
+ u32 rollback_success;
+ u32 rollback_failed;
+ u32 delayq_full_error;
+ u32 supprq_full_error;
+ u32 txs_indicate;
+ u32 txs_discard;
+ u32 txs_supp_core;
+ u32 txs_supp_ps;
+ u32 txs_tossed;
+ u32 txs_host_tossed;
+ u32 bus_flow_block;
+ u32 fws_flow_block;
+};
+
struct brcmf_fws_info {
struct brcmf_pub *drvr;
spinlock_t spinlock;
@@ -2017,6 +2045,75 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
brcmf_fws_unlock(fws);
}
+#ifdef DEBUG
+static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
+ struct brcmf_fws_stats *fwstats = &bus_if->drvr->fws->stats;
+
+ seq_printf(seq,
+ "header_pulls: %u\n"
+ "header_only_pkt: %u\n"
+ "tlv_parse_failed: %u\n"
+ "tlv_invalid_type: %u\n"
+ "mac_update_fails: %u\n"
+ "ps_update_fails: %u\n"
+ "if_update_fails: %u\n"
+ "pkt2bus: %u\n"
+ "generic_error: %u\n"
+ "rollback_success: %u\n"
+ "rollback_failed: %u\n"
+ "delayq_full: %u\n"
+ "supprq_full: %u\n"
+ "txs_indicate: %u\n"
+ "txs_discard: %u\n"
+ "txs_suppr_core: %u\n"
+ "txs_suppr_ps: %u\n"
+ "txs_tossed: %u\n"
+ "txs_host_tossed: %u\n"
+ "bus_flow_block: %u\n"
+ "fws_flow_block: %u\n"
+ "send_pkts: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
+ "requested_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
+ fwstats->header_pulls,
+ fwstats->header_only_pkt,
+ fwstats->tlv_parse_failed,
+ fwstats->tlv_invalid_type,
+ fwstats->mac_update_failed,
+ fwstats->mac_ps_update_failed,
+ fwstats->if_update_failed,
+ fwstats->pkt2bus,
+ fwstats->generic_error,
+ fwstats->rollback_success,
+ fwstats->rollback_failed,
+ fwstats->delayq_full_error,
+ fwstats->supprq_full_error,
+ fwstats->txs_indicate,
+ fwstats->txs_discard,
+ fwstats->txs_supp_core,
+ fwstats->txs_supp_ps,
+ fwstats->txs_tossed,
+ fwstats->txs_host_tossed,
+ fwstats->bus_flow_block,
+ fwstats->fws_flow_block,
+ fwstats->send_pkts[0], fwstats->send_pkts[1],
+ fwstats->send_pkts[2], fwstats->send_pkts[3],
+ fwstats->send_pkts[4],
+ fwstats->requested_sent[0],
+ fwstats->requested_sent[1],
+ fwstats->requested_sent[2],
+ fwstats->requested_sent[3],
+ fwstats->requested_sent[4]);
+
+ return 0;
+}
+#else
+static int brcmf_debugfs_fws_stats_read(struct seq_file *seq, void *data)
+{
+ return 0;
+}
+#endif
+
int brcmf_fws_init(struct brcmf_pub *drvr)
{
struct brcmf_fws_info *fws;
@@ -2107,7 +2204,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
BRCMF_FWS_PSQ_LEN);
/* create debugfs file for statistics */
- brcmf_debugfs_create_fws_stats(drvr, &fws->stats);
+ brcmf_debugfs_add_entry(drvr, "fws_stats",
+ brcmf_debugfs_fws_stats_read);
brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n",
fws->fw_signals ? "enabled" : "disabled", tlv);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
new file mode 100644
index 000000000000..535c7eb01b3a
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -0,0 +1,1397 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*******************************************************************************
+ * Communicates with the dongle by using dcmd codes.
+ * For certain dcmd codes, the dongle interprets string data from the host.
+ ******************************************************************************/
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+
+#include "dhd.h"
+#include "dhd_dbg.h"
+#include "proto.h"
+#include "msgbuf.h"
+#include "commonring.h"
+#include "flowring.h"
+#include "dhd_bus.h"
+#include "tracepoint.h"
+
+
+#define MSGBUF_IOCTL_RESP_TIMEOUT 2000
+
+#define MSGBUF_TYPE_GEN_STATUS 0x1
+#define MSGBUF_TYPE_RING_STATUS 0x2
+#define MSGBUF_TYPE_FLOW_RING_CREATE 0x3
+#define MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT 0x4
+#define MSGBUF_TYPE_FLOW_RING_DELETE 0x5
+#define MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT 0x6
+#define MSGBUF_TYPE_FLOW_RING_FLUSH 0x7
+#define MSGBUF_TYPE_FLOW_RING_FLUSH_CMPLT 0x8
+#define MSGBUF_TYPE_IOCTLPTR_REQ 0x9
+#define MSGBUF_TYPE_IOCTLPTR_REQ_ACK 0xA
+#define MSGBUF_TYPE_IOCTLRESP_BUF_POST 0xB
+#define MSGBUF_TYPE_IOCTL_CMPLT 0xC
+#define MSGBUF_TYPE_EVENT_BUF_POST 0xD
+#define MSGBUF_TYPE_WL_EVENT 0xE
+#define MSGBUF_TYPE_TX_POST 0xF
+#define MSGBUF_TYPE_TX_STATUS 0x10
+#define MSGBUF_TYPE_RXBUF_POST 0x11
+#define MSGBUF_TYPE_RX_CMPLT 0x12
+#define MSGBUF_TYPE_LPBK_DMAXFER 0x13
+#define MSGBUF_TYPE_LPBK_DMAXFER_CMPLT 0x14
+
+#define NR_TX_PKTIDS 2048
+#define NR_RX_PKTIDS 1024
+
+#define BRCMF_IOCTL_REQ_PKTID 0xFFFE
+
+#define BRCMF_MSGBUF_MAX_PKT_SIZE 2048
+#define BRCMF_MSGBUF_RXBUFPOST_THRESHOLD 32
+#define BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST 8
+#define BRCMF_MSGBUF_MAX_EVENTBUF_POST 8
+
+#define BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3 0x01
+#define BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT 5
+
+#define BRCMF_MSGBUF_TX_FLUSH_CNT1 32
+#define BRCMF_MSGBUF_TX_FLUSH_CNT2 96
+
+
+struct msgbuf_common_hdr {
+ u8 msgtype;
+ u8 ifidx;
+ u8 flags;
+ u8 rsvd0;
+ __le32 request_id;
+};
+
+struct msgbuf_buf_addr {
+ __le32 low_addr;
+ __le32 high_addr;
+};
+
+struct msgbuf_ioctl_req_hdr {
+ struct msgbuf_common_hdr msg;
+ __le32 cmd;
+ __le16 trans_id;
+ __le16 input_buf_len;
+ __le16 output_buf_len;
+ __le16 rsvd0[3];
+ struct msgbuf_buf_addr req_buf_addr;
+ __le32 rsvd1[2];
+};
+
+struct msgbuf_tx_msghdr {
+ struct msgbuf_common_hdr msg;
+ u8 txhdr[ETH_HLEN];
+ u8 flags;
+ u8 seg_cnt;
+ struct msgbuf_buf_addr metadata_buf_addr;
+ struct msgbuf_buf_addr data_buf_addr;
+ __le16 metadata_buf_len;
+ __le16 data_len;
+ __le32 rsvd0;
+};
+
+struct msgbuf_rx_bufpost {
+ struct msgbuf_common_hdr msg;
+ __le16 metadata_buf_len;
+ __le16 data_buf_len;
+ __le32 rsvd0;
+ struct msgbuf_buf_addr metadata_buf_addr;
+ struct msgbuf_buf_addr data_buf_addr;
+};
+
+struct msgbuf_rx_ioctl_resp_or_event {
+ struct msgbuf_common_hdr msg;
+ __le16 host_buf_len;
+ __le16 rsvd0[3];
+ struct msgbuf_buf_addr host_buf_addr;
+ __le32 rsvd1[4];
+};
+
+struct msgbuf_completion_hdr {
+ __le16 status;
+ __le16 flow_ring_id;
+};
+
+struct msgbuf_rx_event {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le16 event_data_len;
+ __le16 seqnum;
+ __le16 rsvd0[4];
+};
+
+struct msgbuf_ioctl_resp_hdr {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le16 resp_len;
+ __le16 trans_id;
+ __le32 cmd;
+ __le32 rsvd0;
+};
+
+struct msgbuf_tx_status {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le16 metadata_len;
+ __le16 tx_status;
+};
+
+struct msgbuf_rx_complete {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le16 metadata_len;
+ __le16 data_len;
+ __le16 data_offset;
+ __le16 flags;
+ __le32 rx_status_0;
+ __le32 rx_status_1;
+ __le32 rsvd0;
+};
+
+struct msgbuf_tx_flowring_create_req {
+ struct msgbuf_common_hdr msg;
+ u8 da[ETH_ALEN];
+ u8 sa[ETH_ALEN];
+ u8 tid;
+ u8 if_flags;
+ __le16 flow_ring_id;
+ u8 tc;
+ u8 priority;
+ __le16 int_vector;
+ __le16 max_items;
+ __le16 len_item;
+ struct msgbuf_buf_addr flow_ring_addr;
+};
+
+struct msgbuf_tx_flowring_delete_req {
+ struct msgbuf_common_hdr msg;
+ __le16 flow_ring_id;
+ __le16 reason;
+ __le32 rsvd0[7];
+};
+
+struct msgbuf_flowring_create_resp {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le32 rsvd0[3];
+};
+
+struct msgbuf_flowring_delete_resp {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le32 rsvd0[3];
+};
+
+struct msgbuf_flowring_flush_resp {
+ struct msgbuf_common_hdr msg;
+ struct msgbuf_completion_hdr compl_hdr;
+ __le32 rsvd0[3];
+};
+
+struct brcmf_msgbuf {
+ struct brcmf_pub *drvr;
+
+ struct brcmf_commonring **commonrings;
+ struct brcmf_commonring **flowrings;
+ dma_addr_t *flowring_dma_handle;
+ u16 nrof_flowrings;
+
+ u16 rx_dataoffset;
+ u32 max_rxbufpost;
+ u16 rx_metadata_offset;
+ u32 rxbufpost;
+
+ u32 max_ioctlrespbuf;
+ u32 cur_ioctlrespbuf;
+ u32 max_eventbuf;
+ u32 cur_eventbuf;
+
+ void *ioctbuf;
+ dma_addr_t ioctbuf_handle;
+ u32 ioctbuf_phys_hi;
+ u32 ioctbuf_phys_lo;
+ u32 ioctl_resp_status;
+ u32 ioctl_resp_ret_len;
+ u32 ioctl_resp_pktid;
+
+ u16 data_seq_no;
+ u16 ioctl_seq_no;
+ u32 reqid;
+ wait_queue_head_t ioctl_resp_wait;
+ bool ctl_completed;
+
+ struct brcmf_msgbuf_pktids *tx_pktids;
+ struct brcmf_msgbuf_pktids *rx_pktids;
+ struct brcmf_flowring *flow;
+
+ struct workqueue_struct *txflow_wq;
+ struct work_struct txflow_work;
+ unsigned long *flow_map;
+ unsigned long *txstatus_done_map;
+};
+
+struct brcmf_msgbuf_pktid {
+ atomic_t allocated;
+ u16 data_offset;
+ struct sk_buff *skb;
+ dma_addr_t physaddr;
+};
+
+struct brcmf_msgbuf_pktids {
+ u32 array_size;
+ u32 last_allocated_idx;
+ enum dma_data_direction direction;
+ struct brcmf_msgbuf_pktid *array;
+};
+
+
+/* dma flushing needs implementation for mips and arm platforms. Should
+ * be put in util. Note, this is not real flushing. It is virtual non
+ * cached memory. Only write buffers should have to be drained. Though
+ * this may be different depending on platform......
+ */
+#define brcmf_dma_flush(addr, len)
+#define brcmf_dma_invalidate_cache(addr, len)
+
+
+static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf);
+
+
+static struct brcmf_msgbuf_pktids *
+brcmf_msgbuf_init_pktids(u32 nr_array_entries,
+ enum dma_data_direction direction)
+{
+ struct brcmf_msgbuf_pktid *array;
+ struct brcmf_msgbuf_pktids *pktids;
+
+ array = kcalloc(nr_array_entries, sizeof(*array), GFP_ATOMIC);
+ if (!array)
+ return NULL;
+
+ pktids = kzalloc(sizeof(*pktids), GFP_ATOMIC);
+ if (!pktids) {
+ kfree(array);
+ return NULL;
+ }
+ pktids->array = array;
+ pktids->array_size = nr_array_entries;
+
+ return pktids;
+}
+
+
+static int
+brcmf_msgbuf_alloc_pktid(struct device *dev,
+ struct brcmf_msgbuf_pktids *pktids,
+ struct sk_buff *skb, u16 data_offset,
+ dma_addr_t *physaddr, u32 *idx)
+{
+ struct brcmf_msgbuf_pktid *array;
+ u32 count;
+
+ array = pktids->array;
+
+ *physaddr = dma_map_single(dev, skb->data + data_offset,
+ skb->len - data_offset, pktids->direction);
+
+ if (dma_mapping_error(dev, *physaddr)) {
+ brcmf_err("dma_map_single failed !!\n");
+ return -ENOMEM;
+ }
+
+ *idx = pktids->last_allocated_idx;
+
+ count = 0;
+ do {
+ (*idx)++;
+ if (*idx == pktids->array_size)
+ *idx = 0;
+ if (array[*idx].allocated.counter == 0)
+ if (atomic_cmpxchg(&array[*idx].allocated, 0, 1) == 0)
+ break;
+ count++;
+ } while (count < pktids->array_size);
+
+ if (count == pktids->array_size)
+ return -ENOMEM;
+
+ array[*idx].data_offset = data_offset;
+ array[*idx].physaddr = *physaddr;
+ array[*idx].skb = skb;
+
+ pktids->last_allocated_idx = *idx;
+
+ return 0;
+}
+
+
+static struct sk_buff *
+brcmf_msgbuf_get_pktid(struct device *dev, struct brcmf_msgbuf_pktids *pktids,
+ u32 idx)
+{
+ struct brcmf_msgbuf_pktid *pktid;
+ struct sk_buff *skb;
+
+ if (idx >= pktids->array_size) {
+ brcmf_err("Invalid packet id %d (max %d)\n", idx,
+ pktids->array_size);
+ return NULL;
+ }
+ if (pktids->array[idx].allocated.counter) {
+ pktid = &pktids->array[idx];
+ dma_unmap_single(dev, pktid->physaddr,
+ pktid->skb->len - pktid->data_offset,
+ pktids->direction);
+ skb = pktid->skb;
+ pktid->allocated.counter = 0;
+ return skb;
+ } else {
+ brcmf_err("Invalid packet id %d (not in use)\n", idx);
+ }
+
+ return NULL;
+}
+
+
+static void
+brcmf_msgbuf_release_array(struct device *dev,
+ struct brcmf_msgbuf_pktids *pktids)
+{
+ struct brcmf_msgbuf_pktid *array;
+ struct brcmf_msgbuf_pktid *pktid;
+ u32 count;
+
+ array = pktids->array;
+ count = 0;
+ do {
+ if (array[count].allocated.counter) {
+ pktid = &array[count];
+ dma_unmap_single(dev, pktid->physaddr,
+ pktid->skb->len - pktid->data_offset,
+ pktids->direction);
+ brcmu_pkt_buf_free_skb(pktid->skb);
+ }
+ count++;
+ } while (count < pktids->array_size);
+
+ kfree(array);
+ kfree(pktids);
+}
+
+
+static void brcmf_msgbuf_release_pktids(struct brcmf_msgbuf *msgbuf)
+{
+ if (msgbuf->rx_pktids)
+ brcmf_msgbuf_release_array(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids);
+ if (msgbuf->tx_pktids)
+ brcmf_msgbuf_release_array(msgbuf->drvr->bus_if->dev,
+ msgbuf->tx_pktids);
+}
+
+
+static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx,
+ uint cmd, void *buf, uint len)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct brcmf_commonring *commonring;
+ struct msgbuf_ioctl_req_hdr *request;
+ u16 buf_len;
+ void *ret_ptr;
+ int err;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ brcmf_commonring_lock(commonring);
+ ret_ptr = brcmf_commonring_reserve_for_write(commonring);
+ if (!ret_ptr) {
+ brcmf_err("Failed to reserve space in commonring\n");
+ brcmf_commonring_unlock(commonring);
+ return -ENOMEM;
+ }
+
+ msgbuf->reqid++;
+
+ request = (struct msgbuf_ioctl_req_hdr *)ret_ptr;
+ request->msg.msgtype = MSGBUF_TYPE_IOCTLPTR_REQ;
+ request->msg.ifidx = (u8)ifidx;
+ request->msg.flags = 0;
+ request->msg.request_id = cpu_to_le32(BRCMF_IOCTL_REQ_PKTID);
+ request->cmd = cpu_to_le32(cmd);
+ request->output_buf_len = cpu_to_le16(len);
+ request->trans_id = cpu_to_le16(msgbuf->reqid);
+
+ buf_len = min_t(u16, len, BRCMF_TX_IOCTL_MAX_MSG_SIZE);
+ request->input_buf_len = cpu_to_le16(buf_len);
+ request->req_buf_addr.high_addr = cpu_to_le32(msgbuf->ioctbuf_phys_hi);
+ request->req_buf_addr.low_addr = cpu_to_le32(msgbuf->ioctbuf_phys_lo);
+ if (buf)
+ memcpy(msgbuf->ioctbuf, buf, buf_len);
+ else
+ memset(msgbuf->ioctbuf, 0, buf_len);
+ brcmf_dma_flush(ioctl_buf, buf_len);
+
+ err = brcmf_commonring_write_complete(commonring);
+ brcmf_commonring_unlock(commonring);
+
+ return err;
+}
+
+
+static int brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf *msgbuf)
+{
+ return wait_event_timeout(msgbuf->ioctl_resp_wait,
+ msgbuf->ctl_completed,
+ msecs_to_jiffies(MSGBUF_IOCTL_RESP_TIMEOUT));
+}
+
+
+static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
+{
+ if (waitqueue_active(&msgbuf->ioctl_resp_wait)) {
+ msgbuf->ctl_completed = true;
+ wake_up(&msgbuf->ioctl_resp_wait);
+ }
+}
+
+
+static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
+ uint cmd, void *buf, uint len)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct sk_buff *skb = NULL;
+ int timeout;
+ int err;
+
+ brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
+ msgbuf->ctl_completed = false;
+ err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
+ if (err)
+ return err;
+
+ timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);
+ if (!timeout) {
+ brcmf_err("Timeout on response for query command\n");
+ return -EIO;
+ }
+
+ skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids,
+ msgbuf->ioctl_resp_pktid);
+ if (msgbuf->ioctl_resp_ret_len != 0) {
+ if (!skb) {
+ brcmf_err("Invalid packet id idx recv'd %d\n",
+ msgbuf->ioctl_resp_pktid);
+ return -EBADF;
+ }
+ memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ?
+ len : msgbuf->ioctl_resp_ret_len);
+ }
+ if (skb)
+ brcmu_pkt_buf_free_skb(skb);
+
+ return msgbuf->ioctl_resp_status;
+}
+
+
+static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,
+ uint cmd, void *buf, uint len)
+{
+ return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len);
+}
+
+
+static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
+ u8 *ifidx, struct sk_buff *skb)
+{
+ return -ENODEV;
+}
+
+
+static void
+brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid)
+{
+ u32 dma_sz;
+ void *dma_buf;
+
+ brcmf_dbg(MSGBUF, "Removing flowring %d\n", flowid);
+
+ dma_sz = BRCMF_H2D_TXFLOWRING_MAX_ITEM * BRCMF_H2D_TXFLOWRING_ITEMSIZE;
+ dma_buf = msgbuf->flowrings[flowid]->buf_addr;
+ dma_free_coherent(msgbuf->drvr->bus_if->dev, dma_sz, dma_buf,
+ msgbuf->flowring_dma_handle[flowid]);
+
+ brcmf_flowring_delete(msgbuf->flow, flowid);
+}
+
+
+static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx,
+ struct sk_buff *skb)
+{
+ struct msgbuf_tx_flowring_create_req *create;
+ struct ethhdr *eh = (struct ethhdr *)(skb->data);
+ struct brcmf_commonring *commonring;
+ void *ret_ptr;
+ u32 flowid;
+ void *dma_buf;
+ u32 dma_sz;
+ long long address;
+ int err;
+
+ flowid = brcmf_flowring_create(msgbuf->flow, eh->h_dest,
+ skb->priority, ifidx);
+ if (flowid == BRCMF_FLOWRING_INVALID_ID)
+ return flowid;
+
+ dma_sz = BRCMF_H2D_TXFLOWRING_MAX_ITEM * BRCMF_H2D_TXFLOWRING_ITEMSIZE;
+
+ dma_buf = dma_alloc_coherent(msgbuf->drvr->bus_if->dev, dma_sz,
+ &msgbuf->flowring_dma_handle[flowid],
+ GFP_ATOMIC);
+ if (!dma_buf) {
+ brcmf_err("dma_alloc_coherent failed\n");
+ brcmf_flowring_delete(msgbuf->flow, flowid);
+ return BRCMF_FLOWRING_INVALID_ID;
+ }
+
+ brcmf_commonring_config(msgbuf->flowrings[flowid],
+ BRCMF_H2D_TXFLOWRING_MAX_ITEM,
+ BRCMF_H2D_TXFLOWRING_ITEMSIZE, dma_buf);
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ brcmf_commonring_lock(commonring);
+ ret_ptr = brcmf_commonring_reserve_for_write(commonring);
+ if (!ret_ptr) {
+ brcmf_err("Failed to reserve space in commonring\n");
+ brcmf_commonring_unlock(commonring);
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+ return BRCMF_FLOWRING_INVALID_ID;
+ }
+
+ create = (struct msgbuf_tx_flowring_create_req *)ret_ptr;
+ create->msg.msgtype = MSGBUF_TYPE_FLOW_RING_CREATE;
+ create->msg.ifidx = ifidx;
+ create->msg.request_id = 0;
+ create->tid = brcmf_flowring_tid(msgbuf->flow, flowid);
+ create->flow_ring_id = cpu_to_le16(flowid +
+ BRCMF_NROF_H2D_COMMON_MSGRINGS);
+ memcpy(create->sa, eh->h_source, ETH_ALEN);
+ memcpy(create->da, eh->h_dest, ETH_ALEN);
+ address = (long long)(long)msgbuf->flowring_dma_handle[flowid];
+ create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32);
+ create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff);
+ create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM);
+ create->len_item = cpu_to_le16(BRCMF_H2D_TXFLOWRING_ITEMSIZE);
+
+ brcmf_dbg(MSGBUF, "Send Flow Create Req flow ID %d for peer %pM prio %d ifindex %d\n",
+ flowid, eh->h_dest, create->tid, ifidx);
+
+ err = brcmf_commonring_write_complete(commonring);
+ brcmf_commonring_unlock(commonring);
+ if (err) {
+ brcmf_err("Failed to write commonring\n");
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+ return BRCMF_FLOWRING_INVALID_ID;
+ }
+
+ return flowid;
+}
+
+
+static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid)
+{
+ struct brcmf_flowring *flow = msgbuf->flow;
+ struct brcmf_commonring *commonring;
+ void *ret_ptr;
+ u32 count;
+ struct sk_buff *skb;
+ dma_addr_t physaddr;
+ u32 pktid;
+ struct msgbuf_tx_msghdr *tx_msghdr;
+ long long address;
+
+ commonring = msgbuf->flowrings[flowid];
+ if (!brcmf_commonring_write_available(commonring))
+ return;
+
+ brcmf_commonring_lock(commonring);
+
+ count = BRCMF_MSGBUF_TX_FLUSH_CNT2 - BRCMF_MSGBUF_TX_FLUSH_CNT1;
+ while (brcmf_flowring_qlen(flow, flowid)) {
+ skb = brcmf_flowring_dequeue(flow, flowid);
+ if (skb == NULL) {
+ brcmf_err("No SKB, but qlen %d\n",
+ brcmf_flowring_qlen(flow, flowid));
+ break;
+ }
+ skb_orphan(skb);
+ if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->tx_pktids, skb, ETH_HLEN,
+ &physaddr, &pktid)) {
+ brcmf_flowring_reinsert(flow, flowid, skb);
+ brcmf_err("No PKTID available !!\n");
+ break;
+ }
+ ret_ptr = brcmf_commonring_reserve_for_write(commonring);
+ if (!ret_ptr) {
+ brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->tx_pktids, pktid);
+ brcmf_flowring_reinsert(flow, flowid, skb);
+ break;
+ }
+ count++;
+
+ tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr;
+
+ tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST;
+ tx_msghdr->msg.request_id = cpu_to_le32(pktid);
+ tx_msghdr->msg.ifidx = brcmf_flowring_ifidx_get(flow, flowid);
+ tx_msghdr->flags = BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3;
+ tx_msghdr->flags |= (skb->priority & 0x07) <<
+ BRCMF_MSGBUF_PKT_FLAGS_PRIO_SHIFT;
+ tx_msghdr->seg_cnt = 1;
+ memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN);
+ tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN);
+ address = (long long)(long)physaddr;
+ tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32);
+ tx_msghdr->data_buf_addr.low_addr =
+ cpu_to_le32(address & 0xffffffff);
+ tx_msghdr->metadata_buf_len = 0;
+ tx_msghdr->metadata_buf_addr.high_addr = 0;
+ tx_msghdr->metadata_buf_addr.low_addr = 0;
+ if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) {
+ brcmf_commonring_write_complete(commonring);
+ count = 0;
+ }
+ }
+ if (count)
+ brcmf_commonring_write_complete(commonring);
+ brcmf_commonring_unlock(commonring);
+}
+
+
+static void brcmf_msgbuf_txflow_worker(struct work_struct *worker)
+{
+ struct brcmf_msgbuf *msgbuf;
+ u32 flowid;
+
+ msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work);
+ for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->nrof_flowrings) {
+ clear_bit(flowid, msgbuf->flow_map);
+ brcmf_msgbuf_txflow(msgbuf, flowid);
+ }
+}
+
+
+static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid)
+{
+ set_bit(flowid, msgbuf->flow_map);
+ queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
+
+ return 0;
+}
+
+
+static int brcmf_msgbuf_txdata(struct brcmf_pub *drvr, int ifidx,
+ u8 offset, struct sk_buff *skb)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct brcmf_flowring *flow = msgbuf->flow;
+ struct ethhdr *eh = (struct ethhdr *)(skb->data);
+ u32 flowid;
+
+ flowid = brcmf_flowring_lookup(flow, eh->h_dest, skb->priority, ifidx);
+ if (flowid == BRCMF_FLOWRING_INVALID_ID) {
+ flowid = brcmf_msgbuf_flowring_create(msgbuf, ifidx, skb);
+ if (flowid == BRCMF_FLOWRING_INVALID_ID)
+ return -ENOMEM;
+ }
+ brcmf_flowring_enqueue(flow, flowid, skb);
+ brcmf_msgbuf_schedule_txdata(msgbuf, flowid);
+
+ return 0;
+}
+
+
+static void
+brcmf_msgbuf_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
+ enum proto_addr_mode addr_mode)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+
+ brcmf_flowring_configure_addr_mode(msgbuf->flow, ifidx, addr_mode);
+}
+
+
+static void
+brcmf_msgbuf_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+
+ brcmf_flowring_delete_peer(msgbuf->flow, ifidx, peer);
+}
+
+
+static void
+brcmf_msgbuf_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+
+ brcmf_flowring_add_tdls_peer(msgbuf->flow, ifidx, peer);
+}
+
+
+static void
+brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf)
+{
+ struct msgbuf_ioctl_resp_hdr *ioctl_resp;
+
+ ioctl_resp = (struct msgbuf_ioctl_resp_hdr *)buf;
+
+ msgbuf->ioctl_resp_status = le16_to_cpu(ioctl_resp->compl_hdr.status);
+ msgbuf->ioctl_resp_ret_len = le16_to_cpu(ioctl_resp->resp_len);
+ msgbuf->ioctl_resp_pktid = le32_to_cpu(ioctl_resp->msg.request_id);
+
+ brcmf_msgbuf_ioctl_resp_wake(msgbuf);
+
+ if (msgbuf->cur_ioctlrespbuf)
+ msgbuf->cur_ioctlrespbuf--;
+ brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
+}
+
+
+static void
+brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
+{
+ struct msgbuf_tx_status *tx_status;
+ u32 idx;
+ struct sk_buff *skb;
+ u16 flowid;
+
+ tx_status = (struct msgbuf_tx_status *)buf;
+ idx = le32_to_cpu(tx_status->msg.request_id);
+ flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
+ flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->tx_pktids, idx);
+ if (!skb) {
+ brcmf_err("Invalid packet id idx recv'd %d\n", idx);
+ return;
+ }
+
+ set_bit(flowid, msgbuf->txstatus_done_map);
+
+ brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true);
+}
+
+
+static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
+{
+ struct brcmf_commonring *commonring;
+ void *ret_ptr;
+ struct sk_buff *skb;
+ u16 alloced;
+ u32 pktlen;
+ dma_addr_t physaddr;
+ struct msgbuf_rx_bufpost *rx_bufpost;
+ long long address;
+ u32 pktid;
+ u32 i;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
+ ret_ptr = brcmf_commonring_reserve_for_write_multiple(commonring,
+ count,
+ &alloced);
+ if (!ret_ptr) {
+ brcmf_err("Failed to reserve space in commonring\n");
+ return 0;
+ }
+
+ for (i = 0; i < alloced; i++) {
+ rx_bufpost = (struct msgbuf_rx_bufpost *)ret_ptr;
+ memset(rx_bufpost, 0, sizeof(*rx_bufpost));
+
+ skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
+
+ if (skb == NULL) {
+ brcmf_err("Failed to alloc SKB\n");
+ brcmf_commonring_write_cancel(commonring, alloced - i);
+ break;
+ }
+
+ pktlen = skb->len;
+ if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids, skb, 0,
+ &physaddr, &pktid)) {
+ dev_kfree_skb_any(skb);
+ brcmf_err("No PKTID available !!\n");
+ brcmf_commonring_write_cancel(commonring, alloced - i);
+ break;
+ }
+
+ if (msgbuf->rx_metadata_offset) {
+ address = (long long)(long)physaddr;
+ rx_bufpost->metadata_buf_len =
+ cpu_to_le16(msgbuf->rx_metadata_offset);
+ rx_bufpost->metadata_buf_addr.high_addr =
+ cpu_to_le32(address >> 32);
+ rx_bufpost->metadata_buf_addr.low_addr =
+ cpu_to_le32(address & 0xffffffff);
+
+ skb_pull(skb, msgbuf->rx_metadata_offset);
+ pktlen = skb->len;
+ physaddr += msgbuf->rx_metadata_offset;
+ }
+ rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST;
+ rx_bufpost->msg.request_id = cpu_to_le32(pktid);
+
+ address = (long long)(long)physaddr;
+ rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen);
+ rx_bufpost->data_buf_addr.high_addr =
+ cpu_to_le32(address >> 32);
+ rx_bufpost->data_buf_addr.low_addr =
+ cpu_to_le32(address & 0xffffffff);
+
+ ret_ptr += brcmf_commonring_len_item(commonring);
+ }
+
+ if (i)
+ brcmf_commonring_write_complete(commonring);
+
+ return i;
+}
+
+
+static void
+brcmf_msgbuf_rxbuf_data_fill(struct brcmf_msgbuf *msgbuf)
+{
+ u32 fillbufs;
+ u32 retcount;
+
+ fillbufs = msgbuf->max_rxbufpost - msgbuf->rxbufpost;
+
+ while (fillbufs) {
+ retcount = brcmf_msgbuf_rxbuf_data_post(msgbuf, fillbufs);
+ if (!retcount)
+ break;
+ msgbuf->rxbufpost += retcount;
+ fillbufs -= retcount;
+ }
+}
+
+
+static void
+brcmf_msgbuf_update_rxbufpost_count(struct brcmf_msgbuf *msgbuf, u16 rxcnt)
+{
+ msgbuf->rxbufpost -= rxcnt;
+ if (msgbuf->rxbufpost <= (msgbuf->max_rxbufpost -
+ BRCMF_MSGBUF_RXBUFPOST_THRESHOLD))
+ brcmf_msgbuf_rxbuf_data_fill(msgbuf);
+}
+
+
+static u32
+brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
+ u32 count)
+{
+ struct brcmf_commonring *commonring;
+ void *ret_ptr;
+ struct sk_buff *skb;
+ u16 alloced;
+ u32 pktlen;
+ dma_addr_t physaddr;
+ struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost;
+ long long address;
+ u32 pktid;
+ u32 i;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ brcmf_commonring_lock(commonring);
+ ret_ptr = brcmf_commonring_reserve_for_write_multiple(commonring,
+ count,
+ &alloced);
+ if (!ret_ptr) {
+ brcmf_err("Failed to reserve space in commonring\n");
+ brcmf_commonring_unlock(commonring);
+ return 0;
+ }
+
+ for (i = 0; i < alloced; i++) {
+ rx_bufpost = (struct msgbuf_rx_ioctl_resp_or_event *)ret_ptr;
+ memset(rx_bufpost, 0, sizeof(*rx_bufpost));
+
+ skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
+
+ if (skb == NULL) {
+ brcmf_err("Failed to alloc SKB\n");
+ brcmf_commonring_write_cancel(commonring, alloced - i);
+ break;
+ }
+
+ pktlen = skb->len;
+ if (brcmf_msgbuf_alloc_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids, skb, 0,
+ &physaddr, &pktid)) {
+ dev_kfree_skb_any(skb);
+ brcmf_err("No PKTID available !!\n");
+ brcmf_commonring_write_cancel(commonring, alloced - i);
+ break;
+ }
+ if (event_buf)
+ rx_bufpost->msg.msgtype = MSGBUF_TYPE_EVENT_BUF_POST;
+ else
+ rx_bufpost->msg.msgtype =
+ MSGBUF_TYPE_IOCTLRESP_BUF_POST;
+ rx_bufpost->msg.request_id = cpu_to_le32(pktid);
+
+ address = (long long)(long)physaddr;
+ rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen);
+ rx_bufpost->host_buf_addr.high_addr =
+ cpu_to_le32(address >> 32);
+ rx_bufpost->host_buf_addr.low_addr =
+ cpu_to_le32(address & 0xffffffff);
+
+ ret_ptr += brcmf_commonring_len_item(commonring);
+ }
+
+ if (i)
+ brcmf_commonring_write_complete(commonring);
+
+ brcmf_commonring_unlock(commonring);
+
+ return i;
+}
+
+
+static void brcmf_msgbuf_rxbuf_ioctlresp_post(struct brcmf_msgbuf *msgbuf)
+{
+ u32 count;
+
+ count = msgbuf->max_ioctlrespbuf - msgbuf->cur_ioctlrespbuf;
+ count = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, false, count);
+ msgbuf->cur_ioctlrespbuf += count;
+}
+
+
+static void brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf *msgbuf)
+{
+ u32 count;
+
+ count = msgbuf->max_eventbuf - msgbuf->cur_eventbuf;
+ count = brcmf_msgbuf_rxbuf_ctrl_post(msgbuf, true, count);
+ msgbuf->cur_eventbuf += count;
+}
+
+
+static void
+brcmf_msgbuf_rx_skb(struct brcmf_msgbuf *msgbuf, struct sk_buff *skb,
+ u8 ifidx)
+{
+ struct brcmf_if *ifp;
+
+ ifp = msgbuf->drvr->iflist[ifidx];
+ if (!ifp || !ifp->ndev) {
+ brcmu_pkt_buf_free_skb(skb);
+ return;
+ }
+ brcmf_netif_rx(ifp, skb);
+}
+
+
+static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
+{
+ struct msgbuf_rx_event *event;
+ u32 idx;
+ u16 buflen;
+ struct sk_buff *skb;
+
+ event = (struct msgbuf_rx_event *)buf;
+ idx = le32_to_cpu(event->msg.request_id);
+ buflen = le16_to_cpu(event->event_data_len);
+
+ if (msgbuf->cur_eventbuf)
+ msgbuf->cur_eventbuf--;
+ brcmf_msgbuf_rxbuf_event_post(msgbuf);
+
+ skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids, idx);
+ if (!skb)
+ return;
+
+ if (msgbuf->rx_dataoffset)
+ skb_pull(skb, msgbuf->rx_dataoffset);
+
+ skb_trim(skb, buflen);
+
+ brcmf_msgbuf_rx_skb(msgbuf, skb, event->msg.ifidx);
+}
+
+
+static void
+brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
+{
+ struct msgbuf_rx_complete *rx_complete;
+ struct sk_buff *skb;
+ u16 data_offset;
+ u16 buflen;
+ u32 idx;
+
+ brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1);
+
+ rx_complete = (struct msgbuf_rx_complete *)buf;
+ data_offset = le16_to_cpu(rx_complete->data_offset);
+ buflen = le16_to_cpu(rx_complete->data_len);
+ idx = le32_to_cpu(rx_complete->msg.request_id);
+
+ skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ msgbuf->rx_pktids, idx);
+
+ if (data_offset)
+ skb_pull(skb, data_offset);
+ else if (msgbuf->rx_dataoffset)
+ skb_pull(skb, msgbuf->rx_dataoffset);
+
+ skb_trim(skb, buflen);
+
+ brcmf_msgbuf_rx_skb(msgbuf, skb, rx_complete->msg.ifidx);
+}
+
+
+static void
+brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
+ void *buf)
+{
+ struct msgbuf_flowring_create_resp *flowring_create_resp;
+ u16 status;
+ u16 flowid;
+
+ flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
+
+ flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
+ flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
+
+ if (status) {
+ brcmf_err("Flowring creation failed, code %d\n", status);
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+ return;
+ }
+ brcmf_dbg(MSGBUF, "Flowring %d Create response status %d\n", flowid,
+ status);
+
+ brcmf_flowring_open(msgbuf->flow, flowid);
+
+ brcmf_msgbuf_schedule_txdata(msgbuf, flowid);
+}
+
+
+static void
+brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
+ void *buf)
+{
+ struct msgbuf_flowring_delete_resp *flowring_delete_resp;
+ u16 status;
+ u16 flowid;
+
+ flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
+
+ flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
+ flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
+
+ if (status) {
+ brcmf_err("Flowring deletion failed, code %d\n", status);
+ brcmf_flowring_delete(msgbuf->flow, flowid);
+ return;
+ }
+ brcmf_dbg(MSGBUF, "Flowring %d Delete response status %d\n", flowid,
+ status);
+
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+}
+
+
+static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
+{
+ struct msgbuf_common_hdr *msg;
+
+ msg = (struct msgbuf_common_hdr *)buf;
+ switch (msg->msgtype) {
+ case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n");
+ brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);
+ break;
+ case MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_DELETE_CMPLT\n");
+ brcmf_msgbuf_process_flow_ring_delete_response(msgbuf, buf);
+ break;
+ case MSGBUF_TYPE_IOCTLPTR_REQ_ACK:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_IOCTLPTR_REQ_ACK\n");
+ break;
+ case MSGBUF_TYPE_IOCTL_CMPLT:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_IOCTL_CMPLT\n");
+ brcmf_msgbuf_process_ioctl_complete(msgbuf, buf);
+ break;
+ case MSGBUF_TYPE_WL_EVENT:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_WL_EVENT\n");
+ brcmf_msgbuf_process_event(msgbuf, buf);
+ break;
+ case MSGBUF_TYPE_TX_STATUS:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_TX_STATUS\n");
+ brcmf_msgbuf_process_txstatus(msgbuf, buf);
+ break;
+ case MSGBUF_TYPE_RX_CMPLT:
+ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RX_CMPLT\n");
+ brcmf_msgbuf_process_rx_complete(msgbuf, buf);
+ break;
+ default:
+ brcmf_err("Unsupported msgtype %d\n", msg->msgtype);
+ break;
+ }
+}
+
+
+static void brcmf_msgbuf_process_rx(struct brcmf_msgbuf *msgbuf,
+ struct brcmf_commonring *commonring)
+{
+ void *buf;
+ u16 count;
+
+again:
+ buf = brcmf_commonring_get_read_ptr(commonring, &count);
+ if (buf == NULL)
+ return;
+
+ while (count) {
+ brcmf_msgbuf_process_msgtype(msgbuf,
+ buf + msgbuf->rx_dataoffset);
+ buf += brcmf_commonring_len_item(commonring);
+ count--;
+ }
+ brcmf_commonring_read_complete(commonring);
+
+ if (commonring->r_ptr == 0)
+ goto again;
+}
+
+
+int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ void *buf;
+ u32 flowid;
+
+ buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
+ brcmf_msgbuf_process_rx(msgbuf, buf);
+ buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
+ brcmf_msgbuf_process_rx(msgbuf, buf);
+ buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
+ brcmf_msgbuf_process_rx(msgbuf, buf);
+
+ for_each_set_bit(flowid, msgbuf->txstatus_done_map,
+ msgbuf->nrof_flowrings) {
+ clear_bit(flowid, msgbuf->txstatus_done_map);
+ if (brcmf_flowring_qlen(msgbuf->flow, flowid))
+ brcmf_msgbuf_schedule_txdata(msgbuf, flowid);
+ }
+
+ return 0;
+}
+
+
+void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid)
+{
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct msgbuf_tx_flowring_delete_req *delete;
+ struct brcmf_commonring *commonring;
+ void *ret_ptr;
+ u8 ifidx;
+ int err;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ brcmf_commonring_lock(commonring);
+ ret_ptr = brcmf_commonring_reserve_for_write(commonring);
+ if (!ret_ptr) {
+ brcmf_err("FW unaware, flowring will be removed !!\n");
+ brcmf_commonring_unlock(commonring);
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+ return;
+ }
+
+ delete = (struct msgbuf_tx_flowring_delete_req *)ret_ptr;
+
+ ifidx = brcmf_flowring_ifidx_get(msgbuf->flow, flowid);
+
+ delete->msg.msgtype = MSGBUF_TYPE_FLOW_RING_DELETE;
+ delete->msg.ifidx = ifidx;
+ delete->msg.request_id = 0;
+
+ delete->flow_ring_id = cpu_to_le16(flowid +
+ BRCMF_NROF_H2D_COMMON_MSGRINGS);
+ delete->reason = 0;
+
+ brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n",
+ flowid, ifidx);
+
+ err = brcmf_commonring_write_complete(commonring);
+ brcmf_commonring_unlock(commonring);
+ if (err) {
+ brcmf_err("Failed to submit RING_DELETE, flowring will be removed\n");
+ brcmf_msgbuf_remove_flowring(msgbuf, flowid);
+ }
+}
+
+
+int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
+{
+ struct brcmf_bus_msgbuf *if_msgbuf;
+ struct brcmf_msgbuf *msgbuf;
+ long long address;
+ u32 count;
+
+ if_msgbuf = drvr->bus_if->msgbuf;
+ msgbuf = kzalloc(sizeof(*msgbuf), GFP_ATOMIC);
+ if (!msgbuf)
+ goto fail;
+
+ msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow");
+ if (msgbuf->txflow_wq == NULL) {
+ brcmf_err("workqueue creation failed\n");
+ goto fail;
+ }
+ INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);
+ count = BITS_TO_LONGS(if_msgbuf->nrof_flowrings);
+ msgbuf->flow_map = kzalloc(count, GFP_ATOMIC);
+ if (!msgbuf->flow_map)
+ goto fail;
+
+ msgbuf->txstatus_done_map = kzalloc(count, GFP_ATOMIC);
+ if (!msgbuf->txstatus_done_map)
+ goto fail;
+
+ msgbuf->drvr = drvr;
+ msgbuf->ioctbuf = dma_alloc_coherent(drvr->bus_if->dev,
+ BRCMF_TX_IOCTL_MAX_MSG_SIZE,
+ &msgbuf->ioctbuf_handle,
+ GFP_ATOMIC);
+ if (!msgbuf->ioctbuf)
+ goto fail;
+ address = (long long)(long)msgbuf->ioctbuf_handle;
+ msgbuf->ioctbuf_phys_hi = address >> 32;
+ msgbuf->ioctbuf_phys_lo = address & 0xffffffff;
+
+ drvr->proto->hdrpull = brcmf_msgbuf_hdrpull;
+ drvr->proto->query_dcmd = brcmf_msgbuf_query_dcmd;
+ drvr->proto->set_dcmd = brcmf_msgbuf_set_dcmd;
+ drvr->proto->txdata = brcmf_msgbuf_txdata;
+ drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode;
+ drvr->proto->delete_peer = brcmf_msgbuf_delete_peer;
+ drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer;
+ drvr->proto->pd = msgbuf;
+
+ init_waitqueue_head(&msgbuf->ioctl_resp_wait);
+
+ msgbuf->commonrings =
+ (struct brcmf_commonring **)if_msgbuf->commonrings;
+ msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings;
+ msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings;
+ msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings *
+ sizeof(*msgbuf->flowring_dma_handle), GFP_ATOMIC);
+
+ msgbuf->rx_dataoffset = if_msgbuf->rx_dataoffset;
+ msgbuf->max_rxbufpost = if_msgbuf->max_rxbufpost;
+
+ msgbuf->max_ioctlrespbuf = BRCMF_MSGBUF_MAX_IOCTLRESPBUF_POST;
+ msgbuf->max_eventbuf = BRCMF_MSGBUF_MAX_EVENTBUF_POST;
+
+ msgbuf->tx_pktids = brcmf_msgbuf_init_pktids(NR_TX_PKTIDS,
+ DMA_TO_DEVICE);
+ if (!msgbuf->tx_pktids)
+ goto fail;
+ msgbuf->rx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,
+ DMA_FROM_DEVICE);
+ if (!msgbuf->rx_pktids)
+ goto fail;
+
+ msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev,
+ if_msgbuf->nrof_flowrings);
+ if (!msgbuf->flow)
+ goto fail;
+
+
+ brcmf_dbg(MSGBUF, "Feeding buffers, rx data %d, rx event %d, rx ioctl resp %d\n",
+ msgbuf->max_rxbufpost, msgbuf->max_eventbuf,
+ msgbuf->max_ioctlrespbuf);
+ count = 0;
+ do {
+ brcmf_msgbuf_rxbuf_data_fill(msgbuf);
+ if (msgbuf->max_rxbufpost != msgbuf->rxbufpost)
+ msleep(10);
+ else
+ break;
+ count++;
+ } while (count < 10);
+ brcmf_msgbuf_rxbuf_event_post(msgbuf);
+ brcmf_msgbuf_rxbuf_ioctlresp_post(msgbuf);
+
+ return 0;
+
+fail:
+ if (msgbuf) {
+ kfree(msgbuf->flow_map);
+ kfree(msgbuf->txstatus_done_map);
+ brcmf_msgbuf_release_pktids(msgbuf);
+ if (msgbuf->ioctbuf)
+ dma_free_coherent(drvr->bus_if->dev,
+ BRCMF_TX_IOCTL_MAX_MSG_SIZE,
+ msgbuf->ioctbuf,
+ msgbuf->ioctbuf_handle);
+ kfree(msgbuf);
+ }
+ return -ENOMEM;
+}
+
+
+void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr)
+{
+ struct brcmf_msgbuf *msgbuf;
+
+ brcmf_dbg(TRACE, "Enter\n");
+ if (drvr->proto->pd) {
+ msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+
+ kfree(msgbuf->flow_map);
+ kfree(msgbuf->txstatus_done_map);
+ if (msgbuf->txflow_wq)
+ destroy_workqueue(msgbuf->txflow_wq);
+
+ brcmf_flowring_detach(msgbuf->flow);
+ dma_free_coherent(drvr->bus_if->dev,
+ BRCMF_TX_IOCTL_MAX_MSG_SIZE,
+ msgbuf->ioctbuf, msgbuf->ioctbuf_handle);
+ brcmf_msgbuf_release_pktids(msgbuf);
+ kfree(msgbuf);
+ drvr->proto->pd = NULL;
+ }
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
new file mode 100644
index 000000000000..f901ae52bf2b
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef BRCMFMAC_MSGBUF_H
+#define BRCMFMAC_MSGBUF_H
+
+
+#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 20
+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 256
+#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 20
+#define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024
+#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 256
+#define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512
+
+#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40
+#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE 32
+#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE 24
+#define BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE 16
+#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32
+#define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48
+
+
+int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
+int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr);
+void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr);
+void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid);
+
+
+#endif /* BRCMFMAC_MSGBUF_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.c b/drivers/net/wireless/brcm80211/brcmfmac/of.c
new file mode 100644
index 000000000000..f05f5270fec1
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/mmc/card.h>
+#include <linux/platform_data/brcmfmac-sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <defs.h>
+#include "dhd_dbg.h"
+#include "sdio_host.h"
+
+void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
+{
+ struct device *dev = sdiodev->dev;
+ struct device_node *np = dev->of_node;
+ int irq;
+ u32 irqf;
+ u32 val;
+
+ if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
+ return;
+
+ sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL);
+ if (!sdiodev->pdata)
+ return;
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (irq < 0) {
+ brcmf_err("interrupt could not be mapped: err=%d\n", irq);
+ devm_kfree(dev, sdiodev->pdata);
+ return;
+ }
+ irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
+
+ sdiodev->pdata->oob_irq_supported = true;
+ sdiodev->pdata->oob_irq_nr = irq;
+ sdiodev->pdata->oob_irq_flags = irqf;
+
+ if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
+ sdiodev->pdata->drive_strength = val;
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/of.h b/drivers/net/wireless/brcm80211/brcmfmac/of.h
new file mode 100644
index 000000000000..5f7c3550deda
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/of.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifdef CONFIG_OF
+void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev);
+#else
+static void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
+{
+}
+#endif /* CONFIG_OF */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index f3445ac627e4..057b982ea8b3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -708,7 +708,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
active = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS;
else if (num_chans == AF_PEER_SEARCH_CNT)
active = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS;
- else if (wl_get_vif_state_all(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED))
+ else if (brcmf_get_vif_state_any(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED))
active = -1;
else
active = P2PAPI_SCAN_DWELL_TIME_MS;
@@ -2364,7 +2364,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
return 0;
default:
return -ENOTSUPP;
- break;
}
clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
new file mode 100644
index 000000000000..bc972c0ba5f8
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -0,0 +1,1846 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/unaligned/access_ok.h>
+#include <linux/interrupt.h>
+#include <linux/bcma/bcma.h>
+#include <linux/sched.h>
+
+#include <soc.h>
+#include <chipcommon.h>
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+#include <brcm_hw_ids.h>
+
+#include "dhd_dbg.h"
+#include "dhd_bus.h"
+#include "commonring.h"
+#include "msgbuf.h"
+#include "pcie.h"
+#include "firmware.h"
+#include "chip.h"
+
+
+enum brcmf_pcie_state {
+ BRCMFMAC_PCIE_STATE_DOWN,
+ BRCMFMAC_PCIE_STATE_UP
+};
+
+
+#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin"
+#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt"
+#define BRCMF_PCIE_4354_FW_NAME "brcm/brcmfmac4354-pcie.bin"
+#define BRCMF_PCIE_4354_NVRAM_NAME "brcm/brcmfmac4354-pcie.txt"
+#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin"
+#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt"
+#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin"
+#define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt"
+
+#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
+
+#define BRCMF_PCIE_TCM_MAP_SIZE (4096 * 1024)
+#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024)
+
+/* backplane addres space accessed by BAR0 */
+#define BRCMF_PCIE_BAR0_WINDOW 0x80
+#define BRCMF_PCIE_BAR0_REG_SIZE 0x1000
+#define BRCMF_PCIE_BAR0_WRAPPERBASE 0x70
+
+#define BRCMF_PCIE_BAR0_WRAPBASE_DMP_OFFSET 0x1000
+#define BRCMF_PCIE_BARO_PCIE_ENUM_OFFSET 0x2000
+
+#define BRCMF_PCIE_ARMCR4REG_BANKIDX 0x40
+#define BRCMF_PCIE_ARMCR4REG_BANKPDA 0x4C
+
+#define BRCMF_PCIE_REG_INTSTATUS 0x90
+#define BRCMF_PCIE_REG_INTMASK 0x94
+#define BRCMF_PCIE_REG_SBMBX 0x98
+
+#define BRCMF_PCIE_PCIE2REG_INTMASK 0x24
+#define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48
+#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C
+#define BRCMF_PCIE_PCIE2REG_CONFIGADDR 0x120
+#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124
+#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140
+
+#define BRCMF_PCIE_GENREV1 1
+#define BRCMF_PCIE_GENREV2 2
+
+#define BRCMF_PCIE2_INTA 0x01
+#define BRCMF_PCIE2_INTB 0x02
+
+#define BRCMF_PCIE_INT_0 0x01
+#define BRCMF_PCIE_INT_1 0x02
+#define BRCMF_PCIE_INT_DEF (BRCMF_PCIE_INT_0 | \
+ BRCMF_PCIE_INT_1)
+
+#define BRCMF_PCIE_MB_INT_FN0_0 0x0100
+#define BRCMF_PCIE_MB_INT_FN0_1 0x0200
+#define BRCMF_PCIE_MB_INT_D2H0_DB0 0x10000
+#define BRCMF_PCIE_MB_INT_D2H0_DB1 0x20000
+#define BRCMF_PCIE_MB_INT_D2H1_DB0 0x40000
+#define BRCMF_PCIE_MB_INT_D2H1_DB1 0x80000
+#define BRCMF_PCIE_MB_INT_D2H2_DB0 0x100000
+#define BRCMF_PCIE_MB_INT_D2H2_DB1 0x200000
+#define BRCMF_PCIE_MB_INT_D2H3_DB0 0x400000
+#define BRCMF_PCIE_MB_INT_D2H3_DB1 0x800000
+
+#define BRCMF_PCIE_MB_INT_D2H_DB (BRCMF_PCIE_MB_INT_D2H0_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H0_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H1_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H2_DB1 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB0 | \
+ BRCMF_PCIE_MB_INT_D2H3_DB1)
+
+#define BRCMF_PCIE_MIN_SHARED_VERSION 4
+#define BRCMF_PCIE_MAX_SHARED_VERSION 5
+#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
+#define BRCMF_PCIE_SHARED_TXPUSH_SUPPORT 0x4000
+
+#define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000
+#define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000
+
+#define BRCMF_SHARED_MAX_RXBUFPOST_OFFSET 34
+#define BRCMF_SHARED_RING_BASE_OFFSET 52
+#define BRCMF_SHARED_RX_DATAOFFSET_OFFSET 36
+#define BRCMF_SHARED_CONSOLE_ADDR_OFFSET 20
+#define BRCMF_SHARED_HTOD_MB_DATA_ADDR_OFFSET 40
+#define BRCMF_SHARED_DTOH_MB_DATA_ADDR_OFFSET 44
+#define BRCMF_SHARED_RING_INFO_ADDR_OFFSET 48
+#define BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET 52
+#define BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET 56
+#define BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET 64
+#define BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET 68
+
+#define BRCMF_RING_H2D_RING_COUNT_OFFSET 0
+#define BRCMF_RING_D2H_RING_COUNT_OFFSET 1
+#define BRCMF_RING_H2D_RING_MEM_OFFSET 4
+#define BRCMF_RING_H2D_RING_STATE_OFFSET 8
+
+#define BRCMF_RING_MEM_BASE_ADDR_OFFSET 8
+#define BRCMF_RING_MAX_ITEM_OFFSET 4
+#define BRCMF_RING_LEN_ITEMS_OFFSET 6
+#define BRCMF_RING_MEM_SZ 16
+#define BRCMF_RING_STATE_SZ 8
+
+#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET 4
+#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8
+#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12
+#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16
+#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0
+#define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52
+
+#define BRCMF_DEF_MAX_RXBUFPOST 255
+
+#define BRCMF_CONSOLE_BUFADDR_OFFSET 8
+#define BRCMF_CONSOLE_BUFSIZE_OFFSET 12
+#define BRCMF_CONSOLE_WRITEIDX_OFFSET 16
+
+#define BRCMF_DMA_D2H_SCRATCH_BUF_LEN 8
+#define BRCMF_DMA_D2H_RINGUPD_BUF_LEN 1024
+
+#define BRCMF_D2H_DEV_D3_ACK 0x00000001
+#define BRCMF_D2H_DEV_DS_ENTER_REQ 0x00000002
+#define BRCMF_D2H_DEV_DS_EXIT_NOTE 0x00000004
+
+#define BRCMF_H2D_HOST_D3_INFORM 0x00000001
+#define BRCMF_H2D_HOST_DS_ACK 0x00000002
+
+#define BRCMF_PCIE_MBDATA_TIMEOUT 2000
+
+#define BRCMF_PCIE_CFGREG_STATUS_CMD 0x4
+#define BRCMF_PCIE_CFGREG_PM_CSR 0x4C
+#define BRCMF_PCIE_CFGREG_MSI_CAP 0x58
+#define BRCMF_PCIE_CFGREG_MSI_ADDR_L 0x5C
+#define BRCMF_PCIE_CFGREG_MSI_ADDR_H 0x60
+#define BRCMF_PCIE_CFGREG_MSI_DATA 0x64
+#define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL 0xBC
+#define BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2 0xDC
+#define BRCMF_PCIE_CFGREG_RBAR_CTRL 0x228
+#define BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1 0x248
+#define BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG 0x4E0
+#define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 0x4F4
+#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3
+
+
+MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
+MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
+
+
+struct brcmf_pcie_console {
+ u32 base_addr;
+ u32 buf_addr;
+ u32 bufsize;
+ u32 read_idx;
+ u8 log_str[256];
+ u8 log_idx;
+};
+
+struct brcmf_pcie_shared_info {
+ u32 tcm_base_address;
+ u32 flags;
+ struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
+ struct brcmf_pcie_ringbuf *flowrings;
+ u16 max_rxbufpost;
+ u32 nrof_flowrings;
+ u32 rx_dataoffset;
+ u32 htod_mb_data_addr;
+ u32 dtoh_mb_data_addr;
+ u32 ring_info_addr;
+ struct brcmf_pcie_console console;
+ void *scratch;
+ dma_addr_t scratch_dmahandle;
+ void *ringupd;
+ dma_addr_t ringupd_dmahandle;
+};
+
+struct brcmf_pcie_core_info {
+ u32 base;
+ u32 wrapbase;
+};
+
+struct brcmf_pciedev_info {
+ enum brcmf_pcie_state state;
+ bool in_irq;
+ bool irq_requested;
+ struct pci_dev *pdev;
+ char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
+ char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
+ void __iomem *regs;
+ void __iomem *tcm;
+ u32 tcm_size;
+ u32 ram_base;
+ u32 ram_size;
+ struct brcmf_chip *ci;
+ u32 coreid;
+ u32 generic_corerev;
+ struct brcmf_pcie_shared_info shared;
+ void (*ringbell)(struct brcmf_pciedev_info *devinfo);
+ wait_queue_head_t mbdata_resp_wait;
+ bool mbdata_completed;
+ bool irq_allocated;
+};
+
+struct brcmf_pcie_ringbuf {
+ struct brcmf_commonring commonring;
+ dma_addr_t dma_handle;
+ u32 w_idx_addr;
+ u32 r_idx_addr;
+ struct brcmf_pciedev_info *devinfo;
+ u8 id;
+};
+
+
+static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = {
+ BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM,
+ BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM,
+ BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM,
+ BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM,
+ BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM
+};
+
+static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = {
+ BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE,
+ BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE,
+ BRCMF_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE,
+ BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE,
+ BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE
+};
+
+
+/* dma flushing needs implementation for mips and arm platforms. Should
+ * be put in util. Note, this is not real flushing. It is virtual non
+ * cached memory. Only write buffers should have to be drained. Though
+ * this may be different depending on platform......
+ */
+#define brcmf_dma_flush(addr, len)
+#define brcmf_dma_invalidate_cache(addr, len)
+
+
+static u32
+brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
+{
+ void __iomem *address = devinfo->regs + reg_offset;
+
+ return (ioread32(address));
+}
+
+
+static void
+brcmf_pcie_write_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset,
+ u32 value)
+{
+ void __iomem *address = devinfo->regs + reg_offset;
+
+ iowrite32(value, address);
+}
+
+
+static u8
+brcmf_pcie_read_tcm8(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+
+ return (ioread8(address));
+}
+
+
+static u16
+brcmf_pcie_read_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+
+ return (ioread16(address));
+}
+
+
+static void
+brcmf_pcie_write_tcm16(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ u16 value)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+
+ iowrite16(value, address);
+}
+
+
+static u32
+brcmf_pcie_read_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+
+ return (ioread32(address));
+}
+
+
+static void
+brcmf_pcie_write_tcm32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ u32 value)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+
+ iowrite32(value, address);
+}
+
+
+static u32
+brcmf_pcie_read_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset)
+{
+ void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset;
+
+ return (ioread32(addr));
+}
+
+
+static void
+brcmf_pcie_write_ram32(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ u32 value)
+{
+ void __iomem *addr = devinfo->tcm + devinfo->ci->rambase + mem_offset;
+
+ iowrite32(value, addr);
+}
+
+
+static void
+brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
+ void *srcaddr, u32 len)
+{
+ void __iomem *address = devinfo->tcm + mem_offset;
+ __le32 *src32;
+ __le16 *src16;
+ u8 *src8;
+
+ if (((ulong)address & 4) || ((ulong)srcaddr & 4) || (len & 4)) {
+ if (((ulong)address & 2) || ((ulong)srcaddr & 2) || (len & 2)) {
+ src8 = (u8 *)srcaddr;
+ while (len) {
+ iowrite8(*src8, address);
+ address++;
+ src8++;
+ len--;
+ }
+ } else {
+ len = len / 2;
+ src16 = (__le16 *)srcaddr;
+ while (len) {
+ iowrite16(le16_to_cpu(*src16), address);
+ address += 2;
+ src16++;
+ len--;
+ }
+ }
+ } else {
+ len = len / 4;
+ src32 = (__le32 *)srcaddr;
+ while (len) {
+ iowrite32(le32_to_cpu(*src32), address);
+ address += 4;
+ src32++;
+ len--;
+ }
+ }
+}
+
+
+#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
+ CHIPCREGOFFS(reg), value)
+
+
+static void
+brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
+{
+ const struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_core *core;
+ u32 bar0_win;
+
+ core = brcmf_chip_get_core(devinfo->ci, coreid);
+ if (core) {
+ bar0_win = core->base;
+ pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, bar0_win);
+ if (pci_read_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW,
+ &bar0_win) == 0) {
+ if (bar0_win != core->base) {
+ bar0_win = core->base;
+ pci_write_config_dword(pdev,
+ BRCMF_PCIE_BAR0_WINDOW,
+ bar0_win);
+ }
+ }
+ } else {
+ brcmf_err("Unsupported core selected %x\n", coreid);
+ }
+}
+
+
+static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
+{
+ u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD,
+ BRCMF_PCIE_CFGREG_PM_CSR,
+ BRCMF_PCIE_CFGREG_MSI_CAP,
+ BRCMF_PCIE_CFGREG_MSI_ADDR_L,
+ BRCMF_PCIE_CFGREG_MSI_ADDR_H,
+ BRCMF_PCIE_CFGREG_MSI_DATA,
+ BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL2,
+ BRCMF_PCIE_CFGREG_RBAR_CTRL,
+ BRCMF_PCIE_CFGREG_PML1_SUB_CTRL1,
+ BRCMF_PCIE_CFGREG_REG_BAR2_CONFIG,
+ BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG };
+ u32 i;
+ u32 val;
+ u32 lsc;
+
+ if (!devinfo->ci)
+ return;
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
+ BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
+ lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA);
+ val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val);
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON);
+ WRITECC32(devinfo, watchdog, 4);
+ msleep(100);
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
+ BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc);
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
+ cfg_offset[i]);
+ val = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_CONFIGDATA);
+ brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
+ cfg_offset[i], val);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA,
+ val);
+ }
+}
+
+
+static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo)
+{
+ u32 config;
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0)
+ brcmf_pcie_reset_device(devinfo);
+ /* BAR1 window may not be sized properly */
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
+ config = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, config);
+
+ device_wakeup_enable(&devinfo->pdev->dev);
+}
+
+
+static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
+{
+ brcmf_chip_enter_download(devinfo->ci);
+
+ if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX,
+ 5);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKPDA,
+ 0);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX,
+ 7);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKPDA,
+ 0);
+ }
+ return 0;
+}
+
+
+static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
+ u32 resetintr)
+{
+ struct brcmf_core *core;
+
+ if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_INTERNAL_MEM);
+ brcmf_chip_resetcore(core, 0, 0, 0);
+ }
+
+ return !brcmf_chip_exit_download(devinfo->ci, resetintr);
+}
+
+
+static void
+brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data)
+{
+ struct brcmf_pcie_shared_info *shared;
+ u32 addr;
+ u32 cur_htod_mb_data;
+ u32 i;
+
+ shared = &devinfo->shared;
+ addr = shared->htod_mb_data_addr;
+ cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ if (cur_htod_mb_data != 0)
+ brcmf_dbg(PCIE, "MB transaction is already pending 0x%04x\n",
+ cur_htod_mb_data);
+
+ i = 0;
+ while (cur_htod_mb_data != 0) {
+ msleep(10);
+ i++;
+ if (i > 100)
+ break;
+ cur_htod_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+ }
+
+ brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data);
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1);
+}
+
+
+static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
+{
+ struct brcmf_pcie_shared_info *shared;
+ u32 addr;
+ u32 dtoh_mb_data;
+
+ shared = &devinfo->shared;
+ addr = shared->dtoh_mb_data_addr;
+ dtoh_mb_data = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ if (!dtoh_mb_data)
+ return;
+
+ brcmf_pcie_write_tcm32(devinfo, addr, 0);
+
+ brcmf_dbg(PCIE, "D2H_MB_DATA: 0x%04x\n", dtoh_mb_data);
+ if (dtoh_mb_data & BRCMF_D2H_DEV_DS_ENTER_REQ) {
+ brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP REQ\n");
+ brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_DS_ACK);
+ brcmf_dbg(PCIE, "D2H_MB_DATA: sent DEEP SLEEP ACK\n");
+ }
+ if (dtoh_mb_data & BRCMF_D2H_DEV_DS_EXIT_NOTE)
+ brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n");
+ if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK)
+ brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n");
+ if (waitqueue_active(&devinfo->mbdata_resp_wait)) {
+ devinfo->mbdata_completed = true;
+ wake_up(&devinfo->mbdata_resp_wait);
+ }
+}
+
+
+static void brcmf_pcie_bus_console_init(struct brcmf_pciedev_info *devinfo)
+{
+ struct brcmf_pcie_shared_info *shared;
+ struct brcmf_pcie_console *console;
+ u32 addr;
+
+ shared = &devinfo->shared;
+ console = &shared->console;
+ addr = shared->tcm_base_address + BRCMF_SHARED_CONSOLE_ADDR_OFFSET;
+ console->base_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ addr = console->base_addr + BRCMF_CONSOLE_BUFADDR_OFFSET;
+ console->buf_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+ addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET;
+ console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n",
+ console->base_addr, console->buf_addr, console->bufsize);
+}
+
+
+static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo)
+{
+ struct brcmf_pcie_console *console;
+ u32 addr;
+ u8 ch;
+ u32 newidx;
+
+ console = &devinfo->shared.console;
+ addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET;
+ newidx = brcmf_pcie_read_tcm32(devinfo, addr);
+ while (newidx != console->read_idx) {
+ addr = console->buf_addr + console->read_idx;
+ ch = brcmf_pcie_read_tcm8(devinfo, addr);
+ console->read_idx++;
+ if (console->read_idx == console->bufsize)
+ console->read_idx = 0;
+ if (ch == '\r')
+ continue;
+ console->log_str[console->log_idx] = ch;
+ console->log_idx++;
+ if ((ch != '\n') &&
+ (console->log_idx == (sizeof(console->log_str) - 2))) {
+ ch = '\n';
+ console->log_str[console->log_idx] = ch;
+ console->log_idx++;
+ }
+
+ if (ch == '\n') {
+ console->log_str[console->log_idx] = 0;
+ brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str);
+ console->log_idx = 0;
+ }
+ }
+}
+
+
+static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo)
+{
+ u32 reg_value;
+
+ brcmf_dbg(PCIE, "RING !\n");
+ reg_value = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ reg_value |= BRCMF_PCIE2_INTB;
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ reg_value);
+}
+
+
+static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo)
+{
+ brcmf_dbg(PCIE, "RING !\n");
+ /* Any arbitrary value will do, lets use 1 */
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1);
+}
+
+
+static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
+{
+ if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1)
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK,
+ 0);
+ else
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
+ 0);
+}
+
+
+static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
+{
+ if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1)
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK,
+ BRCMF_PCIE_INT_DEF);
+ else
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
+ BRCMF_PCIE_MB_INT_D2H_DB |
+ BRCMF_PCIE_MB_INT_FN0_0 |
+ BRCMF_PCIE_MB_INT_FN0_1);
+}
+
+
+static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
+ u32 status;
+
+ status = 0;
+ pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
+ if (status) {
+ brcmf_pcie_intr_disable(devinfo);
+ brcmf_dbg(PCIE, "Enter\n");
+ return IRQ_WAKE_THREAD;
+ }
+ return IRQ_NONE;
+}
+
+
+static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
+
+ if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT)) {
+ brcmf_pcie_intr_disable(devinfo);
+ brcmf_dbg(PCIE, "Enter\n");
+ return IRQ_WAKE_THREAD;
+ }
+ return IRQ_NONE;
+}
+
+
+static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
+ const struct pci_dev *pdev = devinfo->pdev;
+ u32 status;
+
+ devinfo->in_irq = true;
+ status = 0;
+ pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
+ brcmf_dbg(PCIE, "Enter %x\n", status);
+ if (status) {
+ pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
+ if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
+ brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev);
+ }
+ if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
+ brcmf_pcie_intr_enable(devinfo);
+ devinfo->in_irq = false;
+ return IRQ_HANDLED;
+}
+
+
+static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
+ u32 status;
+
+ devinfo->in_irq = true;
+ status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ brcmf_dbg(PCIE, "Enter %x\n", status);
+ if (status) {
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ status);
+ if (status & (BRCMF_PCIE_MB_INT_FN0_0 |
+ BRCMF_PCIE_MB_INT_FN0_1))
+ brcmf_pcie_handle_mb_data(devinfo);
+ if (status & BRCMF_PCIE_MB_INT_D2H_DB) {
+ if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
+ brcmf_proto_msgbuf_rx_trigger(
+ &devinfo->pdev->dev);
+ }
+ }
+ brcmf_pcie_bus_console_read(devinfo);
+ if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
+ brcmf_pcie_intr_enable(devinfo);
+ devinfo->in_irq = false;
+ return IRQ_HANDLED;
+}
+
+
+static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
+{
+ struct pci_dev *pdev;
+
+ pdev = devinfo->pdev;
+
+ brcmf_pcie_intr_disable(devinfo);
+
+ brcmf_dbg(PCIE, "Enter\n");
+ /* is it a v1 or v2 implementation */
+ devinfo->irq_requested = false;
+ if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) {
+ if (request_threaded_irq(pdev->irq,
+ brcmf_pcie_quick_check_isr_v1,
+ brcmf_pcie_isr_thread_v1,
+ IRQF_SHARED, "brcmf_pcie_intr",
+ devinfo)) {
+ brcmf_err("Failed to request IRQ %d\n", pdev->irq);
+ return -EIO;
+ }
+ } else {
+ if (request_threaded_irq(pdev->irq,
+ brcmf_pcie_quick_check_isr_v2,
+ brcmf_pcie_isr_thread_v2,
+ IRQF_SHARED, "brcmf_pcie_intr",
+ devinfo)) {
+ brcmf_err("Failed to request IRQ %d\n", pdev->irq);
+ return -EIO;
+ }
+ }
+ devinfo->irq_requested = true;
+ devinfo->irq_allocated = true;
+ return 0;
+}
+
+
+static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
+{
+ struct pci_dev *pdev;
+ u32 status;
+ u32 count;
+
+ if (!devinfo->irq_allocated)
+ return;
+
+ pdev = devinfo->pdev;
+
+ brcmf_pcie_intr_disable(devinfo);
+ if (!devinfo->irq_requested)
+ return;
+ devinfo->irq_requested = false;
+ free_irq(pdev->irq, devinfo);
+
+ msleep(50);
+ count = 0;
+ while ((devinfo->in_irq) && (count < 20)) {
+ msleep(50);
+ count++;
+ }
+ if (devinfo->in_irq)
+ brcmf_err("Still in IRQ (processing) !!!\n");
+
+ if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) {
+ status = 0;
+ pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
+ pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
+ } else {
+ status = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ status);
+ }
+ devinfo->irq_allocated = false;
+}
+
+
+static int brcmf_pcie_ring_mb_write_rptr(void *ctx)
+{
+ struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx;
+ struct brcmf_pciedev_info *devinfo = ring->devinfo;
+ struct brcmf_commonring *commonring = &ring->commonring;
+
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
+ return -EIO;
+
+ brcmf_dbg(PCIE, "W r_ptr %d (%d), ring %d\n", commonring->r_ptr,
+ commonring->w_ptr, ring->id);
+
+ brcmf_pcie_write_tcm16(devinfo, ring->r_idx_addr, commonring->r_ptr);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_ring_mb_write_wptr(void *ctx)
+{
+ struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx;
+ struct brcmf_pciedev_info *devinfo = ring->devinfo;
+ struct brcmf_commonring *commonring = &ring->commonring;
+
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
+ return -EIO;
+
+ brcmf_dbg(PCIE, "W w_ptr %d (%d), ring %d\n", commonring->w_ptr,
+ commonring->r_ptr, ring->id);
+
+ brcmf_pcie_write_tcm16(devinfo, ring->w_idx_addr, commonring->w_ptr);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
+{
+ struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx;
+ struct brcmf_pciedev_info *devinfo = ring->devinfo;
+
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
+ return -EIO;
+
+ devinfo->ringbell(devinfo);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_ring_mb_update_rptr(void *ctx)
+{
+ struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx;
+ struct brcmf_pciedev_info *devinfo = ring->devinfo;
+ struct brcmf_commonring *commonring = &ring->commonring;
+
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
+ return -EIO;
+
+ commonring->r_ptr = brcmf_pcie_read_tcm16(devinfo, ring->r_idx_addr);
+
+ brcmf_dbg(PCIE, "R r_ptr %d (%d), ring %d\n", commonring->r_ptr,
+ commonring->w_ptr, ring->id);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_ring_mb_update_wptr(void *ctx)
+{
+ struct brcmf_pcie_ringbuf *ring = (struct brcmf_pcie_ringbuf *)ctx;
+ struct brcmf_pciedev_info *devinfo = ring->devinfo;
+ struct brcmf_commonring *commonring = &ring->commonring;
+
+ if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
+ return -EIO;
+
+ commonring->w_ptr = brcmf_pcie_read_tcm16(devinfo, ring->w_idx_addr);
+
+ brcmf_dbg(PCIE, "R w_ptr %d (%d), ring %d\n", commonring->w_ptr,
+ commonring->r_ptr, ring->id);
+
+ return 0;
+}
+
+
+static void *
+brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
+ u32 size, u32 tcm_dma_phys_addr,
+ dma_addr_t *dma_handle)
+{
+ void *ring;
+ long long address;
+
+ ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
+ GFP_KERNEL);
+ if (!ring)
+ return NULL;
+
+ address = (long long)(long)*dma_handle;
+ brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr,
+ address & 0xffffffff);
+ brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr + 4, address >> 32);
+
+ memset(ring, 0, size);
+
+ return (ring);
+}
+
+
+static struct brcmf_pcie_ringbuf *
+brcmf_pcie_alloc_dma_and_ring(struct brcmf_pciedev_info *devinfo, u32 ring_id,
+ u32 tcm_ring_phys_addr)
+{
+ void *dma_buf;
+ dma_addr_t dma_handle;
+ struct brcmf_pcie_ringbuf *ring;
+ u32 size;
+ u32 addr;
+
+ size = brcmf_ring_max_item[ring_id] * brcmf_ring_itemsize[ring_id];
+ dma_buf = brcmf_pcie_init_dmabuffer_for_device(devinfo, size,
+ tcm_ring_phys_addr + BRCMF_RING_MEM_BASE_ADDR_OFFSET,
+ &dma_handle);
+ if (!dma_buf)
+ return NULL;
+
+ addr = tcm_ring_phys_addr + BRCMF_RING_MAX_ITEM_OFFSET;
+ brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_max_item[ring_id]);
+ addr = tcm_ring_phys_addr + BRCMF_RING_LEN_ITEMS_OFFSET;
+ brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_itemsize[ring_id]);
+
+ ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+ if (!ring) {
+ dma_free_coherent(&devinfo->pdev->dev, size, dma_buf,
+ dma_handle);
+ return NULL;
+ }
+ brcmf_commonring_config(&ring->commonring, brcmf_ring_max_item[ring_id],
+ brcmf_ring_itemsize[ring_id], dma_buf);
+ ring->dma_handle = dma_handle;
+ ring->devinfo = devinfo;
+ brcmf_commonring_register_cb(&ring->commonring,
+ brcmf_pcie_ring_mb_ring_bell,
+ brcmf_pcie_ring_mb_update_rptr,
+ brcmf_pcie_ring_mb_update_wptr,
+ brcmf_pcie_ring_mb_write_rptr,
+ brcmf_pcie_ring_mb_write_wptr, ring);
+
+ return (ring);
+}
+
+
+static void brcmf_pcie_release_ringbuffer(struct device *dev,
+ struct brcmf_pcie_ringbuf *ring)
+{
+ void *dma_buf;
+ u32 size;
+
+ if (!ring)
+ return;
+
+ dma_buf = ring->commonring.buf_addr;
+ if (dma_buf) {
+ size = ring->commonring.depth * ring->commonring.item_len;
+ dma_free_coherent(dev, size, dma_buf, ring->dma_handle);
+ }
+ kfree(ring);
+}
+
+
+static void brcmf_pcie_release_ringbuffers(struct brcmf_pciedev_info *devinfo)
+{
+ u32 i;
+
+ for (i = 0; i < BRCMF_NROF_COMMON_MSGRINGS; i++) {
+ brcmf_pcie_release_ringbuffer(&devinfo->pdev->dev,
+ devinfo->shared.commonrings[i]);
+ devinfo->shared.commonrings[i] = NULL;
+ }
+ kfree(devinfo->shared.flowrings);
+ devinfo->shared.flowrings = NULL;
+}
+
+
+static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
+{
+ struct brcmf_pcie_ringbuf *ring;
+ struct brcmf_pcie_ringbuf *rings;
+ u32 ring_addr;
+ u32 d2h_w_idx_ptr;
+ u32 d2h_r_idx_ptr;
+ u32 h2d_w_idx_ptr;
+ u32 h2d_r_idx_ptr;
+ u32 addr;
+ u32 ring_mem_ptr;
+ u32 i;
+ u16 max_sub_queues;
+
+ ring_addr = devinfo->shared.ring_info_addr;
+ brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr);
+
+ addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
+ d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+ addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
+ d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+ addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
+ h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+ addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
+ h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET;
+ ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) {
+ ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr);
+ if (!ring)
+ goto fail;
+ ring->w_idx_addr = h2d_w_idx_ptr;
+ ring->r_idx_addr = h2d_r_idx_ptr;
+ ring->id = i;
+ devinfo->shared.commonrings[i] = ring;
+
+ h2d_w_idx_ptr += sizeof(u32);
+ h2d_r_idx_ptr += sizeof(u32);
+ ring_mem_ptr += BRCMF_RING_MEM_SZ;
+ }
+
+ for (i = BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ i < BRCMF_NROF_COMMON_MSGRINGS; i++) {
+ ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr);
+ if (!ring)
+ goto fail;
+ ring->w_idx_addr = d2h_w_idx_ptr;
+ ring->r_idx_addr = d2h_r_idx_ptr;
+ ring->id = i;
+ devinfo->shared.commonrings[i] = ring;
+
+ d2h_w_idx_ptr += sizeof(u32);
+ d2h_r_idx_ptr += sizeof(u32);
+ ring_mem_ptr += BRCMF_RING_MEM_SZ;
+ }
+
+ addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
+ max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
+ devinfo->shared.nrof_flowrings =
+ max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring),
+ GFP_KERNEL);
+ if (!rings)
+ goto fail;
+
+ brcmf_dbg(PCIE, "Nr of flowrings is %d\n",
+ devinfo->shared.nrof_flowrings);
+
+ for (i = 0; i < devinfo->shared.nrof_flowrings; i++) {
+ ring = &rings[i];
+ ring->devinfo = devinfo;
+ ring->id = i + BRCMF_NROF_COMMON_MSGRINGS;
+ brcmf_commonring_register_cb(&ring->commonring,
+ brcmf_pcie_ring_mb_ring_bell,
+ brcmf_pcie_ring_mb_update_rptr,
+ brcmf_pcie_ring_mb_update_wptr,
+ brcmf_pcie_ring_mb_write_rptr,
+ brcmf_pcie_ring_mb_write_wptr,
+ ring);
+ ring->w_idx_addr = h2d_w_idx_ptr;
+ ring->r_idx_addr = h2d_r_idx_ptr;
+ h2d_w_idx_ptr += sizeof(u32);
+ h2d_r_idx_ptr += sizeof(u32);
+ }
+ devinfo->shared.flowrings = rings;
+
+ return 0;
+
+fail:
+ brcmf_err("Allocating commonring buffers failed\n");
+ brcmf_pcie_release_ringbuffers(devinfo);
+ return -ENOMEM;
+}
+
+
+static void
+brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo)
+{
+ if (devinfo->shared.scratch)
+ dma_free_coherent(&devinfo->pdev->dev,
+ BRCMF_DMA_D2H_SCRATCH_BUF_LEN,
+ devinfo->shared.scratch,
+ devinfo->shared.scratch_dmahandle);
+ if (devinfo->shared.ringupd)
+ dma_free_coherent(&devinfo->pdev->dev,
+ BRCMF_DMA_D2H_RINGUPD_BUF_LEN,
+ devinfo->shared.ringupd,
+ devinfo->shared.ringupd_dmahandle);
+}
+
+static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
+{
+ long long address;
+ u32 addr;
+
+ devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev,
+ BRCMF_DMA_D2H_SCRATCH_BUF_LEN,
+ &devinfo->shared.scratch_dmahandle, GFP_KERNEL);
+ if (!devinfo->shared.scratch)
+ goto fail;
+
+ memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
+ brcmf_dma_flush(devinfo->shared.scratch, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
+
+ addr = devinfo->shared.tcm_base_address +
+ BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET;
+ address = (long long)(long)devinfo->shared.scratch_dmahandle;
+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
+ addr = devinfo->shared.tcm_base_address +
+ BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET;
+ brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN);
+
+ devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev,
+ BRCMF_DMA_D2H_RINGUPD_BUF_LEN,
+ &devinfo->shared.ringupd_dmahandle, GFP_KERNEL);
+ if (!devinfo->shared.ringupd)
+ goto fail;
+
+ memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
+ brcmf_dma_flush(devinfo->shared.ringupd, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
+
+ addr = devinfo->shared.tcm_base_address +
+ BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET;
+ address = (long long)(long)devinfo->shared.ringupd_dmahandle;
+ brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+ brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
+ addr = devinfo->shared.tcm_base_address +
+ BRCMF_SHARED_DMA_RINGUPD_LEN_OFFSET;
+ brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_RINGUPD_BUF_LEN);
+ return 0;
+
+fail:
+ brcmf_err("Allocating scratch buffers failed\n");
+ brcmf_pcie_release_scratchbuffers(devinfo);
+ return -ENOMEM;
+}
+
+
+static void brcmf_pcie_down(struct device *dev)
+{
+}
+
+
+static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb)
+{
+ return 0;
+}
+
+
+static int brcmf_pcie_tx_ctlpkt(struct device *dev, unsigned char *msg,
+ uint len)
+{
+ return 0;
+}
+
+
+static int brcmf_pcie_rx_ctlpkt(struct device *dev, unsigned char *msg,
+ uint len)
+{
+ return 0;
+}
+
+
+static struct brcmf_bus_ops brcmf_pcie_bus_ops = {
+ .txdata = brcmf_pcie_tx,
+ .stop = brcmf_pcie_down,
+ .txctl = brcmf_pcie_tx_ctlpkt,
+ .rxctl = brcmf_pcie_rx_ctlpkt,
+};
+
+
+static int
+brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
+ u32 sharedram_addr)
+{
+ struct brcmf_pcie_shared_info *shared;
+ u32 addr;
+ u32 version;
+
+ shared = &devinfo->shared;
+ shared->tcm_base_address = sharedram_addr;
+
+ shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr);
+ version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK;
+ brcmf_dbg(PCIE, "PCIe protocol version %d\n", version);
+ if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
+ (version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
+ brcmf_err("Unsupported PCIE version %d\n", version);
+ return -EINVAL;
+ }
+ if (shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT) {
+ brcmf_err("Unsupported legacy TX mode 0x%x\n",
+ shared->flags & BRCMF_PCIE_SHARED_TXPUSH_SUPPORT);
+ return -EINVAL;
+ }
+
+ addr = sharedram_addr + BRCMF_SHARED_MAX_RXBUFPOST_OFFSET;
+ shared->max_rxbufpost = brcmf_pcie_read_tcm16(devinfo, addr);
+ if (shared->max_rxbufpost == 0)
+ shared->max_rxbufpost = BRCMF_DEF_MAX_RXBUFPOST;
+
+ addr = sharedram_addr + BRCMF_SHARED_RX_DATAOFFSET_OFFSET;
+ shared->rx_dataoffset = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ addr = sharedram_addr + BRCMF_SHARED_HTOD_MB_DATA_ADDR_OFFSET;
+ shared->htod_mb_data_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ addr = sharedram_addr + BRCMF_SHARED_DTOH_MB_DATA_ADDR_OFFSET;
+ shared->dtoh_mb_data_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ addr = sharedram_addr + BRCMF_SHARED_RING_INFO_ADDR_OFFSET;
+ shared->ring_info_addr = brcmf_pcie_read_tcm32(devinfo, addr);
+
+ brcmf_dbg(PCIE, "max rx buf post %d, rx dataoffset %d\n",
+ shared->max_rxbufpost, shared->rx_dataoffset);
+
+ brcmf_pcie_bus_console_init(devinfo);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo)
+{
+ char *fw_name;
+ char *nvram_name;
+ uint fw_len, nv_len;
+ char end;
+
+ brcmf_dbg(PCIE, "Enter, chip 0x%04x chiprev %d\n", devinfo->ci->chip,
+ devinfo->ci->chiprev);
+
+ switch (devinfo->ci->chip) {
+ case BRCM_CC_43602_CHIP_ID:
+ fw_name = BRCMF_PCIE_43602_FW_NAME;
+ nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
+ break;
+ case BRCM_CC_4354_CHIP_ID:
+ fw_name = BRCMF_PCIE_4354_FW_NAME;
+ nvram_name = BRCMF_PCIE_4354_NVRAM_NAME;
+ break;
+ case BRCM_CC_4356_CHIP_ID:
+ fw_name = BRCMF_PCIE_4356_FW_NAME;
+ nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
+ break;
+ case BRCM_CC_43567_CHIP_ID:
+ case BRCM_CC_43569_CHIP_ID:
+ case BRCM_CC_43570_CHIP_ID:
+ fw_name = BRCMF_PCIE_43570_FW_NAME;
+ nvram_name = BRCMF_PCIE_43570_NVRAM_NAME;
+ break;
+ default:
+ brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
+ return -ENODEV;
+ }
+
+ fw_len = sizeof(devinfo->fw_name) - 1;
+ nv_len = sizeof(devinfo->nvram_name) - 1;
+ /* check if firmware path is provided by module parameter */
+ if (brcmf_firmware_path[0] != '\0') {
+ strncpy(devinfo->fw_name, brcmf_firmware_path, fw_len);
+ strncpy(devinfo->nvram_name, brcmf_firmware_path, nv_len);
+ fw_len -= strlen(devinfo->fw_name);
+ nv_len -= strlen(devinfo->nvram_name);
+
+ end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
+ if (end != '/') {
+ strncat(devinfo->fw_name, "/", fw_len);
+ strncat(devinfo->nvram_name, "/", nv_len);
+ fw_len--;
+ nv_len--;
+ }
+ }
+ strncat(devinfo->fw_name, fw_name, fw_len);
+ strncat(devinfo->nvram_name, nvram_name, nv_len);
+
+ return 0;
+}
+
+
+static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
+ const struct firmware *fw, void *nvram,
+ u32 nvram_len)
+{
+ u32 sharedram_addr;
+ u32 sharedram_addr_written;
+ u32 loop_counter;
+ int err;
+ u32 address;
+ u32 resetintr;
+
+ devinfo->ringbell = brcmf_pcie_ringbell_v2;
+ devinfo->generic_corerev = BRCMF_PCIE_GENREV2;
+
+ brcmf_dbg(PCIE, "Halt ARM.\n");
+ err = brcmf_pcie_enter_download_state(devinfo);
+ if (err)
+ return err;
+
+ brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name);
+ brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase,
+ (void *)fw->data, fw->size);
+
+ resetintr = get_unaligned_le32(fw->data);
+ release_firmware(fw);
+
+ /* reset last 4 bytes of RAM address. to be used for shared
+ * area. This identifies when FW is running
+ */
+ brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0);
+
+ if (nvram) {
+ brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name);
+ address = devinfo->ci->rambase + devinfo->ci->ramsize -
+ nvram_len;
+ brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len);
+ brcmf_fw_nvram_free(nvram);
+ } else {
+ brcmf_dbg(PCIE, "No matching NVRAM file found %s\n",
+ devinfo->nvram_name);
+ }
+
+ sharedram_addr_written = brcmf_pcie_read_ram32(devinfo,
+ devinfo->ci->ramsize -
+ 4);
+ brcmf_dbg(PCIE, "Bring ARM in running state\n");
+ err = brcmf_pcie_exit_download_state(devinfo, resetintr);
+ if (err)
+ return err;
+
+ brcmf_dbg(PCIE, "Wait for FW init\n");
+ sharedram_addr = sharedram_addr_written;
+ loop_counter = BRCMF_PCIE_FW_UP_TIMEOUT / 50;
+ while ((sharedram_addr == sharedram_addr_written) && (loop_counter)) {
+ msleep(50);
+ sharedram_addr = brcmf_pcie_read_ram32(devinfo,
+ devinfo->ci->ramsize -
+ 4);
+ loop_counter--;
+ }
+ if (sharedram_addr == sharedram_addr_written) {
+ brcmf_err("FW failed to initialize\n");
+ return -ENODEV;
+ }
+ brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr);
+
+ return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr));
+}
+
+
+static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
+{
+ struct pci_dev *pdev;
+ int err;
+ phys_addr_t bar0_addr, bar1_addr;
+ ulong bar1_size;
+
+ pdev = devinfo->pdev;
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ brcmf_err("pci_enable_device failed err=%d\n", err);
+ return err;
+ }
+
+ pci_set_master(pdev);
+
+ /* Bar-0 mapped address */
+ bar0_addr = pci_resource_start(pdev, 0);
+ /* Bar-1 mapped address */
+ bar1_addr = pci_resource_start(pdev, 2);
+ /* read Bar-1 mapped memory range */
+ bar1_size = pci_resource_len(pdev, 2);
+ if ((bar1_size == 0) || (bar1_addr == 0)) {
+ brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n",
+ bar1_size, (unsigned long long)bar1_addr);
+ return -EINVAL;
+ }
+
+ devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE);
+ devinfo->tcm = ioremap_nocache(bar1_addr, BRCMF_PCIE_TCM_MAP_SIZE);
+ devinfo->tcm_size = BRCMF_PCIE_TCM_MAP_SIZE;
+
+ if (!devinfo->regs || !devinfo->tcm) {
+ brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs,
+ devinfo->tcm);
+ return -EINVAL;
+ }
+ brcmf_dbg(PCIE, "Phys addr : reg space = %p base addr %#016llx\n",
+ devinfo->regs, (unsigned long long)bar0_addr);
+ brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx\n",
+ devinfo->tcm, (unsigned long long)bar1_addr);
+
+ return 0;
+}
+
+
+static void brcmf_pcie_release_resource(struct brcmf_pciedev_info *devinfo)
+{
+ if (devinfo->tcm)
+ iounmap(devinfo->tcm);
+ if (devinfo->regs)
+ iounmap(devinfo->regs);
+
+ pci_disable_device(devinfo->pdev);
+}
+
+
+static int brcmf_pcie_attach_bus(struct device *dev)
+{
+ int ret;
+
+ /* Attach to the common driver interface */
+ ret = brcmf_attach(dev);
+ if (ret) {
+ brcmf_err("brcmf_attach failed\n");
+ } else {
+ ret = brcmf_bus_start(dev);
+ if (ret)
+ brcmf_err("dongle is not responding\n");
+ }
+
+ return ret;
+}
+
+
+static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr)
+{
+ u32 ret_addr;
+
+ ret_addr = addr & (BRCMF_PCIE_BAR0_REG_SIZE - 1);
+ addr &= ~(BRCMF_PCIE_BAR0_REG_SIZE - 1);
+ pci_write_config_dword(pdev, BRCMF_PCIE_BAR0_WINDOW, addr);
+
+ return ret_addr;
+}
+
+
+static u32 brcmf_pcie_buscore_read32(void *ctx, u32 addr)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+
+ addr = brcmf_pcie_buscore_prep_addr(devinfo->pdev, addr);
+ return brcmf_pcie_read_reg32(devinfo, addr);
+}
+
+
+static void brcmf_pcie_buscore_write32(void *ctx, u32 addr, u32 value)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+
+ addr = brcmf_pcie_buscore_prep_addr(devinfo->pdev, addr);
+ brcmf_pcie_write_reg32(devinfo, addr, value);
+}
+
+
+static int brcmf_pcie_buscoreprep(void *ctx)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+ int err;
+
+ err = brcmf_pcie_get_resource(devinfo);
+ if (err == 0) {
+ /* Set CC watchdog to reset all the cores on the chip to bring
+ * back dongle to a sane state.
+ */
+ brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE,
+ watchdog), 4);
+ msleep(100);
+ }
+
+ return err;
+}
+
+
+static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
+ u32 rstvec)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+
+ brcmf_pcie_write_tcm32(devinfo, 0, rstvec);
+}
+
+
+static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
+ .prepare = brcmf_pcie_buscoreprep,
+ .exit_dl = brcmf_pcie_buscore_exitdl,
+ .read32 = brcmf_pcie_buscore_read32,
+ .write32 = brcmf_pcie_buscore_write32,
+};
+
+static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
+ void *nvram, u32 nvram_len)
+{
+ struct brcmf_bus *bus = dev_get_drvdata(dev);
+ struct brcmf_pciedev *pcie_bus_dev = bus->bus_priv.pcie;
+ struct brcmf_pciedev_info *devinfo = pcie_bus_dev->devinfo;
+ struct brcmf_commonring **flowrings;
+ int ret;
+ u32 i;
+
+ brcmf_pcie_attach(devinfo);
+
+ ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len);
+ if (ret)
+ goto fail;
+
+ devinfo->state = BRCMFMAC_PCIE_STATE_UP;
+
+ ret = brcmf_pcie_init_ringbuffers(devinfo);
+ if (ret)
+ goto fail;
+
+ ret = brcmf_pcie_init_scratchbuffers(devinfo);
+ if (ret)
+ goto fail;
+
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
+ ret = brcmf_pcie_request_irq(devinfo);
+ if (ret)
+ goto fail;
+
+ /* hook the commonrings in the bus structure. */
+ for (i = 0; i < BRCMF_NROF_COMMON_MSGRINGS; i++)
+ bus->msgbuf->commonrings[i] =
+ &devinfo->shared.commonrings[i]->commonring;
+
+ flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(flowrings),
+ GFP_KERNEL);
+ if (!flowrings)
+ goto fail;
+
+ for (i = 0; i < devinfo->shared.nrof_flowrings; i++)
+ flowrings[i] = &devinfo->shared.flowrings[i].commonring;
+ bus->msgbuf->flowrings = flowrings;
+
+ bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset;
+ bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost;
+ bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings;
+
+ init_waitqueue_head(&devinfo->mbdata_resp_wait);
+
+ brcmf_pcie_intr_enable(devinfo);
+ if (brcmf_pcie_attach_bus(bus->dev) == 0)
+ return;
+
+ brcmf_pcie_bus_console_read(devinfo);
+
+fail:
+ device_release_driver(dev);
+}
+
+static int
+brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int ret;
+ struct brcmf_pciedev_info *devinfo;
+ struct brcmf_pciedev *pcie_bus_dev;
+ struct brcmf_bus *bus;
+
+ brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
+
+ ret = -ENOMEM;
+ devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
+ if (devinfo == NULL)
+ return ret;
+
+ devinfo->pdev = pdev;
+ pcie_bus_dev = NULL;
+ devinfo->ci = brcmf_chip_attach(devinfo, &brcmf_pcie_buscore_ops);
+ if (IS_ERR(devinfo->ci)) {
+ ret = PTR_ERR(devinfo->ci);
+ devinfo->ci = NULL;
+ goto fail;
+ }
+
+ pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL);
+ if (pcie_bus_dev == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+ if (!bus) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ bus->msgbuf = kzalloc(sizeof(*bus->msgbuf), GFP_KERNEL);
+ if (!bus->msgbuf) {
+ ret = -ENOMEM;
+ kfree(bus);
+ goto fail;
+ }
+
+ /* hook it all together. */
+ pcie_bus_dev->devinfo = devinfo;
+ pcie_bus_dev->bus = bus;
+ bus->dev = &pdev->dev;
+ bus->bus_priv.pcie = pcie_bus_dev;
+ bus->ops = &brcmf_pcie_bus_ops;
+ bus->proto_type = BRCMF_PROTO_MSGBUF;
+ bus->chip = devinfo->coreid;
+ dev_set_drvdata(&pdev->dev, bus);
+
+ ret = brcmf_pcie_get_fwnames(devinfo);
+ if (ret)
+ goto fail_bus;
+
+ ret = brcmf_fw_get_firmwares(bus->dev, BRCMF_FW_REQUEST_NVRAM |
+ BRCMF_FW_REQ_NV_OPTIONAL,
+ devinfo->fw_name, devinfo->nvram_name,
+ brcmf_pcie_setup);
+ if (ret == 0)
+ return 0;
+fail_bus:
+ kfree(bus->msgbuf);
+ kfree(bus);
+fail:
+ brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device);
+ brcmf_pcie_release_resource(devinfo);
+ if (devinfo->ci)
+ brcmf_chip_detach(devinfo->ci);
+ kfree(pcie_bus_dev);
+ kfree(devinfo);
+ return ret;
+}
+
+
+static void
+brcmf_pcie_remove(struct pci_dev *pdev)
+{
+ struct brcmf_pciedev_info *devinfo;
+ struct brcmf_bus *bus;
+
+ brcmf_dbg(PCIE, "Enter\n");
+
+ bus = dev_get_drvdata(&pdev->dev);
+ if (bus == NULL)
+ return;
+
+ devinfo = bus->bus_priv.pcie->devinfo;
+
+ devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
+ if (devinfo->ci)
+ brcmf_pcie_intr_disable(devinfo);
+
+ brcmf_detach(&pdev->dev);
+
+ kfree(bus->bus_priv.pcie);
+ kfree(bus->msgbuf->flowrings);
+ kfree(bus->msgbuf);
+ kfree(bus);
+
+ brcmf_pcie_release_irq(devinfo);
+ brcmf_pcie_release_scratchbuffers(devinfo);
+ brcmf_pcie_release_ringbuffers(devinfo);
+ brcmf_pcie_reset_device(devinfo);
+ brcmf_pcie_release_resource(devinfo);
+
+ if (devinfo->ci)
+ brcmf_chip_detach(devinfo->ci);
+
+ kfree(devinfo);
+ dev_set_drvdata(&pdev->dev, NULL);
+}
+
+
+#ifdef CONFIG_PM
+
+
+static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct brcmf_pciedev_info *devinfo;
+ struct brcmf_bus *bus;
+ int err;
+
+ brcmf_dbg(PCIE, "Enter, state=%d, pdev=%p\n", state.event, pdev);
+
+ bus = dev_get_drvdata(&pdev->dev);
+ devinfo = bus->bus_priv.pcie->devinfo;
+
+ brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
+
+ devinfo->mbdata_completed = false;
+ brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D3_INFORM);
+
+ wait_event_timeout(devinfo->mbdata_resp_wait,
+ devinfo->mbdata_completed,
+ msecs_to_jiffies(BRCMF_PCIE_MBDATA_TIMEOUT));
+ if (!devinfo->mbdata_completed) {
+ brcmf_err("Timeout on response for entering D3 substate\n");
+ return -EIO;
+ }
+ brcmf_pcie_release_irq(devinfo);
+
+ err = pci_save_state(pdev);
+ if (err) {
+ brcmf_err("pci_save_state failed, err=%d\n", err);
+ return err;
+ }
+
+ brcmf_chip_detach(devinfo->ci);
+ devinfo->ci = NULL;
+
+ brcmf_pcie_remove(pdev);
+
+ return pci_prepare_to_sleep(pdev);
+}
+
+
+static int brcmf_pcie_resume(struct pci_dev *pdev)
+{
+ int err;
+
+ brcmf_dbg(PCIE, "Enter, pdev=%p\n", pdev);
+
+ err = pci_set_power_state(pdev, PCI_D0);
+ if (err) {
+ brcmf_err("pci_set_power_state failed, err=%d\n", err);
+ return err;
+ }
+ pci_restore_state(pdev);
+
+ err = brcmf_pcie_probe(pdev, NULL);
+ if (err)
+ brcmf_err("probe after resume failed, err=%d\n", err);
+
+ return err;
+}
+
+
+#endif /* CONFIG_PM */
+
+
+#define BRCMF_PCIE_DEVICE(dev_id) { BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 }
+
+static struct pci_device_id brcmf_pcie_devid_table[] = {
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID),
+ { /* end: all zeroes */ }
+};
+
+
+MODULE_DEVICE_TABLE(pci, brcmf_pcie_devid_table);
+
+
+static struct pci_driver brcmf_pciedrvr = {
+ .node = {},
+ .name = KBUILD_MODNAME,
+ .id_table = brcmf_pcie_devid_table,
+ .probe = brcmf_pcie_probe,
+ .remove = brcmf_pcie_remove,
+#ifdef CONFIG_PM
+ .suspend = brcmf_pcie_suspend,
+ .resume = brcmf_pcie_resume
+#endif /* CONFIG_PM */
+};
+
+
+void brcmf_pcie_register(void)
+{
+ int err;
+
+ brcmf_dbg(PCIE, "Enter\n");
+ err = pci_register_driver(&brcmf_pciedrvr);
+ if (err)
+ brcmf_err("PCIE driver registration failed, err=%d\n", err);
+}
+
+
+void brcmf_pcie_exit(void)
+{
+ brcmf_dbg(PCIE, "Enter\n");
+ pci_unregister_driver(&brcmf_pciedrvr);
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.h b/drivers/net/wireless/brcm80211/brcmfmac/pcie.h
new file mode 100644
index 000000000000..6edaaf8ef5ce
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef BRCMFMAC_PCIE_H
+#define BRCMFMAC_PCIE_H
+
+
+struct brcmf_pciedev {
+ struct brcmf_bus *bus;
+ struct brcmf_pciedev_info *devinfo;
+};
+
+
+void brcmf_pcie_exit(void);
+void brcmf_pcie_register(void);
+
+
+#endif /* BRCMFMAC_PCIE_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
index b6b464184946..62b940723339 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -21,26 +21,40 @@
#include <brcmu_wifi.h>
#include "dhd.h"
+#include "dhd_bus.h"
#include "dhd_dbg.h"
#include "proto.h"
#include "bcdc.h"
+#include "msgbuf.h"
int brcmf_proto_attach(struct brcmf_pub *drvr)
{
struct brcmf_proto *proto;
+ brcmf_dbg(TRACE, "Enter\n");
+
proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
if (!proto)
goto fail;
drvr->proto = proto;
- /* BCDC protocol is only protocol supported for the moment */
- if (brcmf_proto_bcdc_attach(drvr))
- goto fail;
+ if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) {
+ if (brcmf_proto_bcdc_attach(drvr))
+ goto fail;
+ } else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) {
+ if (brcmf_proto_msgbuf_attach(drvr))
+ goto fail;
+ } else {
+ brcmf_err("Unsupported proto type %d\n",
+ drvr->bus_if->proto_type);
+ goto fail;
+ }
if ((proto->txdata == NULL) || (proto->hdrpull == NULL) ||
- (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) {
+ (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) ||
+ (proto->configure_addr_mode == NULL) ||
+ (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) {
brcmf_err("Not all proto handlers have been installed\n");
goto fail;
}
@@ -54,8 +68,13 @@ fail:
void brcmf_proto_detach(struct brcmf_pub *drvr)
{
+ brcmf_dbg(TRACE, "Enter\n");
+
if (drvr->proto) {
- brcmf_proto_bcdc_detach(drvr);
+ if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
+ brcmf_proto_bcdc_detach(drvr);
+ else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF)
+ brcmf_proto_msgbuf_detach(drvr);
kfree(drvr->proto);
drvr->proto = NULL;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
index 482fb0ba4a30..971172ff686c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -16,6 +16,13 @@
#ifndef BRCMFMAC_PROTO_H
#define BRCMFMAC_PROTO_H
+
+enum proto_addr_mode {
+ ADDR_INDIRECT = 0,
+ ADDR_DIRECT
+};
+
+
struct brcmf_proto {
int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
struct sk_buff *skb);
@@ -25,6 +32,12 @@ struct brcmf_proto {
uint len);
int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
struct sk_buff *skb);
+ void (*configure_addr_mode)(struct brcmf_pub *drvr, int ifidx,
+ enum proto_addr_mode addr_mode);
+ void (*delete_peer)(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN]);
+ void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN]);
void *pd;
};
@@ -48,10 +61,26 @@ static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
}
static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx,
- u8 offset, struct sk_buff *skb)
+ u8 offset, struct sk_buff *skb)
{
return drvr->proto->txdata(drvr, ifidx, offset, skb);
}
+static inline void
+brcmf_proto_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
+ enum proto_addr_mode addr_mode)
+{
+ drvr->proto->configure_addr_mode(drvr, ifidx, addr_mode);
+}
+static inline void
+brcmf_proto_delete_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
+{
+ drvr->proto->delete_peer(drvr, ifidx, peer);
+}
+static inline void
+brcmf_proto_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN])
+{
+ drvr->proto->add_tdls_peer(drvr, ifidx, peer);
+}
#endif /* BRCMFMAC_PROTO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 3deab7959a0d..f2d06cae366a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -18,6 +18,8 @@
#define _BRCM_SDH_H_
#include <linux/skbuff.h>
+#include <linux/firmware.h>
+#include "firmware.h"
#define SDIO_FUNC_0 0
#define SDIO_FUNC_1 1
@@ -72,12 +74,12 @@
#define SBSDIO_SPROM_DATA_HIGH 0x10003
/* sprom indirect access addr byte 0 */
#define SBSDIO_SPROM_ADDR_LOW 0x10004
-/* sprom indirect access addr byte 0 */
-#define SBSDIO_SPROM_ADDR_HIGH 0x10005
-/* xtal_pu (gpio) output */
-#define SBSDIO_CHIP_CTRL_DATA 0x10006
-/* xtal_pu (gpio) enable */
-#define SBSDIO_CHIP_CTRL_EN 0x10007
+/* gpio select */
+#define SBSDIO_GPIO_SELECT 0x10005
+/* gpio output */
+#define SBSDIO_GPIO_OUT 0x10006
+/* gpio enable */
+#define SBSDIO_GPIO_EN 0x10007
/* rev < 7, watermark for sdio device */
#define SBSDIO_WATERMARK 0x10008
/* control busy signal generation */
@@ -182,6 +184,8 @@ struct brcmf_sdio_dev {
uint max_segment_size;
uint txglomsz;
struct sg_table sgtable;
+ char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
+ char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
};
/* sdio core registers */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 6db51a666f61..dc135915470d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -21,6 +21,7 @@
#include <linux/vmalloc.h>
#include <brcmu_utils.h>
+#include <brcm_hw_ids.h>
#include <brcmu_wifi.h>
#include <dhd_bus.h>
#include <dhd_dbg.h>
@@ -29,32 +30,24 @@
#include "usb_rdl.h"
#include "usb.h"
-#define IOCTL_RESP_TIMEOUT 2000
+#define IOCTL_RESP_TIMEOUT 2000
#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */
#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10
#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle
has boot up */
-#define BRCMF_USB_NRXQ 50
-#define BRCMF_USB_NTXQ 50
+#define BRCMF_USB_NRXQ 50
+#define BRCMF_USB_NTXQ 50
-#define CONFIGDESC(usb) (&((usb)->actconfig)->desc)
-#define IFPTR(usb, idx) ((usb)->actconfig->interface[(idx)])
-#define IFALTS(usb, idx) (IFPTR((usb), (idx))->altsetting[0])
-#define IFDESC(usb, idx) IFALTS((usb), (idx)).desc
-#define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[(ep)]).desc
+#define BRCMF_USB_CBCTL_WRITE 0
+#define BRCMF_USB_CBCTL_READ 1
+#define BRCMF_USB_MAX_PKT_SIZE 1600
-#define CONTROL_IF 0
-#define BULK_IF 0
-
-#define BRCMF_USB_CBCTL_WRITE 0
-#define BRCMF_USB_CBCTL_READ 1
-#define BRCMF_USB_MAX_PKT_SIZE 1600
-
-#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
-#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
-#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
+#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
+#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
+#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
+#define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin"
struct brcmf_usb_image {
struct list_head list;
@@ -70,7 +63,7 @@ struct brcmf_usbdev_info {
struct list_head rx_postq;
struct list_head tx_freeq;
struct list_head tx_postq;
- uint rx_pipe, tx_pipe, rx_pipe2;
+ uint rx_pipe, tx_pipe;
int rx_low_watermark;
int tx_low_watermark;
@@ -97,6 +90,7 @@ struct brcmf_usbdev_info {
int ctl_completed;
wait_queue_head_t ioctl_resp_wait;
ulong ctl_op;
+ u8 ifnum;
struct urb *bulk_urb; /* used for FW download */
};
@@ -576,7 +570,6 @@ fail:
static int brcmf_usb_up(struct device *dev)
{
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
- u16 ifnum;
brcmf_dbg(USB, "Enter\n");
if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
@@ -589,21 +582,19 @@ static int brcmf_usb_up(struct device *dev)
devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
- ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
-
/* CTL Write */
devinfo->ctl_write.bRequestType =
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
devinfo->ctl_write.bRequest = 0;
devinfo->ctl_write.wValue = cpu_to_le16(0);
- devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);
+ devinfo->ctl_write.wIndex = cpu_to_le16(devinfo->ifnum);
/* CTL Read */
devinfo->ctl_read.bRequestType =
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
devinfo->ctl_read.bRequest = 1;
devinfo->ctl_read.wValue = cpu_to_le16(0);
- devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
+ devinfo->ctl_read.wIndex = cpu_to_le16(devinfo->ifnum);
}
brcmf_usb_rx_fill_all(devinfo);
return 0;
@@ -642,19 +633,19 @@ brcmf_usb_sync_complete(struct urb *urb)
brcmf_usb_ioctl_resp_wake(devinfo);
}
-static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
- void *buffer, int buflen)
+static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
+ void *buffer, int buflen)
{
- int ret = 0;
+ int ret;
char *tmpbuf;
u16 size;
if ((!devinfo) || (devinfo->ctl_urb == NULL))
- return false;
+ return -EINVAL;
tmpbuf = kmalloc(buflen, GFP_ATOMIC);
if (!tmpbuf)
- return false;
+ return -ENOMEM;
size = buflen;
devinfo->ctl_urb->transfer_buffer_length = size;
@@ -675,14 +666,16 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
if (ret < 0) {
brcmf_err("usb_submit_urb failed %d\n", ret);
- kfree(tmpbuf);
- return false;
+ goto finalize;
}
- ret = brcmf_usb_ioctl_resp_wait(devinfo);
- memcpy(buffer, tmpbuf, buflen);
- kfree(tmpbuf);
+ if (!brcmf_usb_ioctl_resp_wait(devinfo))
+ ret = -ETIMEDOUT;
+ else
+ memcpy(buffer, tmpbuf, buflen);
+finalize:
+ kfree(tmpbuf);
return ret;
}
@@ -724,6 +717,7 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
{
struct bootrom_id_le id;
u32 loop_cnt;
+ int err;
brcmf_dbg(USB, "Enter\n");
@@ -732,7 +726,9 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT);
loop_cnt++;
id.chip = cpu_to_le32(0xDEAD); /* Get the ID */
- brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id));
+ err = brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id));
+ if ((err) && (err != -ETIMEDOUT))
+ return err;
if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
break;
} while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT);
@@ -794,8 +790,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
}
/* 1) Prepare USB boot loader for runtime image */
- brcmf_usb_dl_cmd(devinfo, DL_START, &state,
- sizeof(struct rdl_state_le));
+ brcmf_usb_dl_cmd(devinfo, DL_START, &state, sizeof(state));
rdlstate = le32_to_cpu(state.state);
rdlbytes = le32_to_cpu(state.bytes);
@@ -839,10 +834,10 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
dlpos += sendlen;
sent += sendlen;
}
- if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
- sizeof(struct rdl_state_le))) {
- brcmf_err("DL_GETSTATE Failed xxxx\n");
- err = -EINVAL;
+ err = brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
+ sizeof(state));
+ if (err) {
+ brcmf_err("DL_GETSTATE Failed\n");
goto fail;
}
@@ -898,13 +893,12 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
return -EINVAL;
/* Check we are runnable */
- brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
- sizeof(struct rdl_state_le));
+ state.state = 0;
+ brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, sizeof(state));
/* Start the image */
if (state.state == cpu_to_le32(DL_RUNNABLE)) {
- if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state,
- sizeof(struct rdl_state_le)))
+ if (brcmf_usb_dl_cmd(devinfo, DL_GO, &state, sizeof(state)))
return -ENODEV;
if (brcmf_usb_resetcfg(devinfo))
return -ENODEV;
@@ -920,13 +914,16 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
static bool brcmf_usb_chip_support(int chipid, int chiprev)
{
switch(chipid) {
- case 43143:
+ case BRCM_CC_43143_CHIP_ID:
return true;
- case 43235:
- case 43236:
- case 43238:
+ case BRCM_CC_43235_CHIP_ID:
+ case BRCM_CC_43236_CHIP_ID:
+ case BRCM_CC_43238_CHIP_ID:
return (chiprev == 3);
- case 43242:
+ case BRCM_CC_43242_CHIP_ID:
+ return true;
+ case BRCM_CC_43566_CHIP_ID:
+ case BRCM_CC_43569_CHIP_ID:
return true;
default:
break;
@@ -1020,14 +1017,17 @@ static int check_file(const u8 *headers)
static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
{
switch (devinfo->bus_pub.devid) {
- case 43143:
+ case BRCM_CC_43143_CHIP_ID:
return BRCMF_USB_43143_FW_NAME;
- case 43235:
- case 43236:
- case 43238:
+ case BRCM_CC_43235_CHIP_ID:
+ case BRCM_CC_43236_CHIP_ID:
+ case BRCM_CC_43238_CHIP_ID:
return BRCMF_USB_43236_FW_NAME;
- case 43242:
+ case BRCM_CC_43242_CHIP_ID:
return BRCMF_USB_43242_FW_NAME;
+ case BRCM_CC_43566_CHIP_ID:
+ case BRCM_CC_43569_CHIP_ID:
+ return BRCMF_USB_43569_FW_NAME;
default:
return NULL;
}
@@ -1184,8 +1184,6 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
bus->bus_priv.usb = bus_pub;
dev_set_drvdata(dev, bus);
bus->ops = &brcmf_usb_bus_ops;
- bus->chip = bus_pub->devid;
- bus->chiprev = bus_pub->chiprev;
bus->proto_type = BRCMF_PROTO_BCDC;
bus->always_use_fws_queue = true;
@@ -1194,6 +1192,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
if (ret)
goto fail;
}
+ bus->chip = bus_pub->devid;
+ bus->chiprev = bus_pub->chiprev;
+
/* request firmware here */
brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
brcmf_usb_probe_phase2);
@@ -1221,15 +1222,15 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
static int
brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- int ep;
- struct usb_endpoint_descriptor *endpoint;
- int ret = 0;
struct usb_device *usb = interface_to_usbdev(intf);
- int num_of_eps;
- u8 endpoint_num;
struct brcmf_usbdev_info *devinfo;
+ struct usb_interface_descriptor *desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int ret = 0;
+ u32 num_of_eps;
+ u8 endpoint_num, ep;
- brcmf_dbg(USB, "Enter\n");
+ brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct);
devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
if (devinfo == NULL)
@@ -1237,92 +1238,71 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->usbdev = usb;
devinfo->dev = &usb->dev;
-
usb_set_intfdata(intf, devinfo);
/* Check that the device supports only one configuration */
if (usb->descriptor.bNumConfigurations != 1) {
- ret = -1;
- goto fail;
- }
-
- if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
- ret = -1;
- goto fail;
- }
-
- /*
- * Only the BDC interface configuration is supported:
- * Device class: USB_CLASS_VENDOR_SPEC
- * if0 class: USB_CLASS_VENDOR_SPEC
- * if0/ep0: control
- * if0/ep1: bulk in
- * if0/ep2: bulk out (ok if swapped with bulk in)
- */
- if (CONFIGDESC(usb)->bNumInterfaces != 1) {
- ret = -1;
+ brcmf_err("Number of configurations: %d not supported\n",
+ usb->descriptor.bNumConfigurations);
+ ret = -ENODEV;
goto fail;
}
- /* Check interface */
- if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
- IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
- IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
- brcmf_err("invalid control interface: class %d, subclass %d, proto %d\n",
- IFDESC(usb, CONTROL_IF).bInterfaceClass,
- IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
- IFDESC(usb, CONTROL_IF).bInterfaceProtocol);
- ret = -1;
+ if ((usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) &&
+ (usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
+ (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS_CONTROLLER)) {
+ brcmf_err("Device class: 0x%x not supported\n",
+ usb->descriptor.bDeviceClass);
+ ret = -ENODEV;
goto fail;
}
- /* Check control endpoint */
- endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- != USB_ENDPOINT_XFER_INT) {
- brcmf_err("invalid control endpoint %d\n",
- endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
- ret = -1;
+ desc = &intf->altsetting[0].desc;
+ if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
+ (desc->bInterfaceSubClass != 2) ||
+ (desc->bInterfaceProtocol != 0xff)) {
+ brcmf_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n",
+ desc->bInterfaceNumber, desc->bInterfaceClass,
+ desc->bInterfaceSubClass, desc->bInterfaceProtocol);
+ ret = -ENODEV;
goto fail;
}
- devinfo->rx_pipe = 0;
- devinfo->rx_pipe2 = 0;
- devinfo->tx_pipe = 0;
- num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
-
- /* Check data endpoints and get pipes */
- for (ep = 1; ep <= num_of_eps; ep++) {
- endpoint = &IFEPDESC(usb, BULK_IF, ep);
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
- USB_ENDPOINT_XFER_BULK) {
- brcmf_err("invalid data endpoint %d\n", ep);
- ret = -1;
- goto fail;
- }
-
- endpoint_num = endpoint->bEndpointAddress &
- USB_ENDPOINT_NUMBER_MASK;
- if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
- == USB_DIR_IN) {
- if (!devinfo->rx_pipe) {
+ num_of_eps = desc->bNumEndpoints;
+ for (ep = 0; ep < num_of_eps; ep++) {
+ endpoint = &intf->altsetting[0].endpoint[ep].desc;
+ endpoint_num = usb_endpoint_num(endpoint);
+ if (!usb_endpoint_xfer_bulk(endpoint))
+ continue;
+ if (usb_endpoint_dir_in(endpoint)) {
+ if (!devinfo->rx_pipe)
devinfo->rx_pipe =
usb_rcvbulkpipe(usb, endpoint_num);
- } else {
- devinfo->rx_pipe2 =
- usb_rcvbulkpipe(usb, endpoint_num);
- }
} else {
- devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num);
+ if (!devinfo->tx_pipe)
+ devinfo->tx_pipe =
+ usb_sndbulkpipe(usb, endpoint_num);
}
}
+ if (devinfo->rx_pipe == 0) {
+ brcmf_err("No RX (in) Bulk EP found\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+ if (devinfo->tx_pipe == 0) {
+ brcmf_err("No TX (out) Bulk EP found\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ devinfo->ifnum = desc->bInterfaceNumber;
if (usb->speed == USB_SPEED_SUPER)
- brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n");
+ brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n");
else if (usb->speed == USB_SPEED_HIGH)
- brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
+ brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n");
else
- brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");
+ brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n");
ret = brcmf_usb_probe_cb(devinfo);
if (ret)
@@ -1332,11 +1312,9 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
return 0;
fail:
- brcmf_err("failed with errno %d\n", ret);
kfree(devinfo);
usb_set_intfdata(intf, NULL);
return ret;
-
}
static void
@@ -1381,6 +1359,7 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
{
struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
+
brcmf_dbg(USB, "Enter\n");
return brcmf_fw_get_firmwares(&usb->dev, 0,
@@ -1388,25 +1367,24 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
brcmf_usb_probe_phase2);
}
-#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
-#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
-#define BRCMF_USB_DEVICE_ID_43236 0xbd17
-#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
-#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
+#define BRCMF_USB_DEVICE(dev_id) \
+ { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) }
static struct usb_device_id brcmf_usb_devid_table[] = {
- { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
- { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
- { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
+ BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
/* special entry for device with firmware loaded and running */
- { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
- { }
+ BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
+ { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
+MODULE_FIRMWARE(BRCMF_USB_43569_FW_NAME);
static struct usb_driver brcmf_usbdrvr = {
.name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
new file mode 100644
index 000000000000..5960d827508c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/vmalloc.h>
+#include <net/cfg80211.h>
+#include <net/netlink.h>
+
+#include <brcmu_wifi.h>
+#include "fwil_types.h"
+#include "dhd.h"
+#include "p2p.h"
+#include "dhd_dbg.h"
+#include "wl_cfg80211.h"
+#include "vendor.h"
+#include "fwil.h"
+
+static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int len)
+{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct net_device *ndev = cfg_to_ndev(cfg);
+ const struct brcmf_vndr_dcmd_hdr *cmdhdr = data;
+ struct sk_buff *reply;
+ int ret, payload, ret_len;
+ void *dcmd_buf = NULL, *wr_pointer;
+ u16 msglen, maxmsglen = PAGE_SIZE - 0x100;
+
+ brcmf_dbg(TRACE, "cmd %x set %d len %d\n", cmdhdr->cmd, cmdhdr->set,
+ cmdhdr->len);
+
+ len -= sizeof(struct brcmf_vndr_dcmd_hdr);
+ ret_len = cmdhdr->len;
+ if (ret_len > 0 || len > 0) {
+ if (len > BRCMF_DCMD_MAXLEN) {
+ brcmf_err("oversize input buffer %d\n", len);
+ len = BRCMF_DCMD_MAXLEN;
+ }
+ if (ret_len > BRCMF_DCMD_MAXLEN) {
+ brcmf_err("oversize return buffer %d\n", ret_len);
+ ret_len = BRCMF_DCMD_MAXLEN;
+ }
+ payload = max(ret_len, len) + 1;
+ dcmd_buf = vzalloc(payload);
+ if (NULL == dcmd_buf)
+ return -ENOMEM;
+
+ memcpy(dcmd_buf, (void *)cmdhdr + cmdhdr->offset, len);
+ *(char *)(dcmd_buf + len) = '\0';
+ }
+
+ if (cmdhdr->set)
+ ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), cmdhdr->cmd,
+ dcmd_buf, ret_len);
+ else
+ ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), cmdhdr->cmd,
+ dcmd_buf, ret_len);
+ if (ret != 0)
+ goto exit;
+
+ wr_pointer = dcmd_buf;
+ while (ret_len > 0) {
+ msglen = ret_len > maxmsglen ? maxmsglen : ret_len;
+ ret_len -= msglen;
+ payload = msglen + sizeof(msglen);
+ reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
+ if (NULL == reply) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ if (nla_put(reply, BRCMF_NLATTR_DATA, msglen, wr_pointer) ||
+ nla_put_u16(reply, BRCMF_NLATTR_LEN, msglen)) {
+ kfree_skb(reply);
+ ret = -ENOBUFS;
+ break;
+ }
+
+ ret = cfg80211_vendor_cmd_reply(reply);
+ if (ret)
+ break;
+
+ wr_pointer += msglen;
+ }
+
+exit:
+ vfree(dcmd_buf);
+
+ return ret;
+}
+
+const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
+ {
+ {
+ .vendor_id = BROADCOM_OUI,
+ .subcmd = BRCMF_VNDR_CMDS_DCMD
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = brcmf_cfg80211_vndr_cmds_dcmd_handler
+ },
+};
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/brcm80211/brcmfmac/vendor.h
new file mode 100644
index 000000000000..061b7bfa2e1c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _vendor_h_
+#define _vendor_h_
+
+#define BROADCOM_OUI 0x001018
+
+enum brcmf_vndr_cmds {
+ BRCMF_VNDR_CMDS_UNSPEC,
+ BRCMF_VNDR_CMDS_DCMD,
+ BRCMF_VNDR_CMDS_LAST
+};
+
+/**
+ * enum brcmf_nlattrs - nl80211 message attributes
+ *
+ * @BRCMF_NLATTR_LEN: message body length
+ * @BRCMF_NLATTR_DATA: message body
+ */
+enum brcmf_nlattrs {
+ BRCMF_NLATTR_UNSPEC,
+
+ BRCMF_NLATTR_LEN,
+ BRCMF_NLATTR_DATA,
+
+ __BRCMF_NLATTR_AFTER_LAST,
+ BRCMF_NLATTR_MAX = __BRCMF_NLATTR_AFTER_LAST - 1
+};
+
+/**
+ * struct brcmf_vndr_dcmd_hdr - message header for cfg80211 vendor command dcmd
+ * support
+ *
+ * @cmd: common dongle cmd definition
+ * @len: length of expecting return buffer
+ * @offset: offset of data buffer
+ * @set: get or set request(optional)
+ * @magic: magic number for verification
+ */
+struct brcmf_vndr_dcmd_hdr {
+ uint cmd;
+ int len;
+ uint offset;
+ uint set;
+ uint magic;
+};
+
+extern const struct wiphy_vendor_command brcmf_vendor_cmds[];
+
+#endif /* _vendor_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index d8fa276e368b..02fe706fc9ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
+#include <linux/vmalloc.h>
#include <net/cfg80211.h>
#include <net/netlink.h>
@@ -32,7 +33,10 @@
#include "p2p.h"
#include "btcoex.h"
#include "wl_cfg80211.h"
+#include "feature.h"
#include "fwil.h"
+#include "proto.h"
+#include "vendor.h"
#define BRCMF_SCAN_IE_LEN_MAX 2048
#define BRCMF_PNO_VERSION 2
@@ -100,24 +104,6 @@ static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
return true;
}
-#define CHAN2G(_channel, _freq, _flags) { \
- .band = IEEE80211_BAND_2GHZ, \
- .center_freq = (_freq), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-#define CHAN5G(_channel, _flags) { \
- .band = IEEE80211_BAND_5GHZ, \
- .center_freq = 5000 + (5 * (_channel)), \
- .hw_value = (_channel), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
#define RATETAB_ENT(_rateid, _flags) \
{ \
@@ -146,58 +132,17 @@ static struct ieee80211_rate __wl_rates[] = {
#define wl_g_rates (__wl_rates + 0)
#define wl_g_rates_size 12
-static struct ieee80211_channel __wl_2ghz_channels[] = {
- CHAN2G(1, 2412, 0),
- CHAN2G(2, 2417, 0),
- CHAN2G(3, 2422, 0),
- CHAN2G(4, 2427, 0),
- CHAN2G(5, 2432, 0),
- CHAN2G(6, 2437, 0),
- CHAN2G(7, 2442, 0),
- CHAN2G(8, 2447, 0),
- CHAN2G(9, 2452, 0),
- CHAN2G(10, 2457, 0),
- CHAN2G(11, 2462, 0),
- CHAN2G(12, 2467, 0),
- CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
-};
-
-static struct ieee80211_channel __wl_5ghz_a_channels[] = {
- CHAN5G(34, 0), CHAN5G(36, 0),
- CHAN5G(38, 0), CHAN5G(40, 0),
- CHAN5G(42, 0), CHAN5G(44, 0),
- CHAN5G(46, 0), CHAN5G(48, 0),
- CHAN5G(52, 0), CHAN5G(56, 0),
- CHAN5G(60, 0), CHAN5G(64, 0),
- CHAN5G(100, 0), CHAN5G(104, 0),
- CHAN5G(108, 0), CHAN5G(112, 0),
- CHAN5G(116, 0), CHAN5G(120, 0),
- CHAN5G(124, 0), CHAN5G(128, 0),
- CHAN5G(132, 0), CHAN5G(136, 0),
- CHAN5G(140, 0), CHAN5G(149, 0),
- CHAN5G(153, 0), CHAN5G(157, 0),
- CHAN5G(161, 0), CHAN5G(165, 0),
- CHAN5G(184, 0), CHAN5G(188, 0),
- CHAN5G(192, 0), CHAN5G(196, 0),
- CHAN5G(200, 0), CHAN5G(204, 0),
- CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0),
-};
-
-static struct ieee80211_supported_band __wl_band_2ghz = {
+/* Band templates duplicated per wiphy. The channel info
+ * is filled in after querying the device.
+ */
+static const struct ieee80211_supported_band __wl_band_2ghz = {
.band = IEEE80211_BAND_2GHZ,
- .channels = __wl_2ghz_channels,
- .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
.bitrates = wl_g_rates,
.n_bitrates = wl_g_rates_size,
- .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
};
-static struct ieee80211_supported_band __wl_band_5ghz_a = {
+static const struct ieee80211_supported_band __wl_band_5ghz_a = {
.band = IEEE80211_BAND_5GHZ,
- .channels = __wl_5ghz_a_channels,
- .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
.bitrates = wl_a_rates,
.n_bitrates = wl_a_rates_size,
};
@@ -549,6 +494,22 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
return err;
}
+static void
+brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
+{
+ struct net_device *ndev = wdev->netdev;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+
+ if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
+ (wdev->iftype == NL80211_IFTYPE_AP) ||
+ (wdev->iftype == NL80211_IFTYPE_P2P_GO))
+ brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
+ ADDR_DIRECT);
+ else
+ brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
+ ADDR_INDIRECT);
+}
+
static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
{
enum nl80211_iftype iftype;
@@ -568,6 +529,8 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
u32 *flags,
struct vif_params *params)
{
+ struct wireless_dev *wdev;
+
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
switch (type) {
case NL80211_IFTYPE_ADHOC:
@@ -581,13 +544,22 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_DEVICE:
- return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
+ wdev = brcmf_p2p_add_vif(wiphy, name, type, flags, params);
+ if (!IS_ERR(wdev))
+ brcmf_cfg80211_update_proto_addr_mode(wdev);
+ return wdev;
case NL80211_IFTYPE_UNSPECIFIED:
default:
return ERR_PTR(-EINVAL);
}
}
+static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
+{
+ if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
+ brcmf_set_mpc(ifp, mpc);
+}
+
void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
{
s32 err = 0;
@@ -641,7 +613,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
brcmf_err("Scan abort failed\n");
}
- brcmf_set_mpc(ifp, 1);
+ brcmf_scan_config_mpc(ifp, 1);
/*
* e-scan can be initiated by scheduled scan
@@ -770,6 +742,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
}
ndev->ieee80211_ptr->iftype = type;
+ brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
+
done:
brcmf_dbg(TRACE, "Exit\n");
@@ -920,7 +894,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
brcmf_err("error (%d)\n", err);
return err;
}
- brcmf_set_mpc(ifp, 0);
+ brcmf_scan_config_mpc(ifp, 0);
results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
results->version = 0;
results->count = 0;
@@ -928,7 +902,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
if (err)
- brcmf_set_mpc(ifp, 1);
+ brcmf_scan_config_mpc(ifp, 1);
return err;
}
@@ -1019,7 +993,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
goto scan_out;
}
- brcmf_set_mpc(ifp, 0);
+ brcmf_scan_config_mpc(ifp, 0);
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
&sr->ssid_le, sizeof(sr->ssid_le));
if (err) {
@@ -1029,7 +1003,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
else
brcmf_err("WLC_SCAN error (%d)\n", err);
- brcmf_set_mpc(ifp, 1);
+ brcmf_scan_config_mpc(ifp, 1);
goto scan_out;
}
}
@@ -1331,7 +1305,6 @@ static s32
brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- s32 err = 0;
brcmf_dbg(TRACE, "Enter\n");
if (!check_vif_up(ifp->vif))
@@ -1341,7 +1314,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
brcmf_dbg(TRACE, "Exit\n");
- return err;
+ return 0;
}
static s32 brcmf_set_wpa_version(struct net_device *ndev,
@@ -1612,17 +1585,10 @@ static
enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
enum nl80211_auth_type type)
{
- u32 ci;
- if (type == NL80211_AUTHTYPE_AUTOMATIC) {
- /* shift to ignore chip revision */
- ci = brcmf_get_chip_info(ifp) >> 4;
- switch (ci) {
- case 43236:
- brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
- return NL80211_AUTHTYPE_OPEN_SYSTEM;
- default:
- break;
- }
+ if (type == NL80211_AUTHTYPE_AUTOMATIC &&
+ brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
+ brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
+ type = NL80211_AUTHTYPE_OPEN_SYSTEM;
}
return type;
}
@@ -2388,7 +2354,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
struct cfg80211_bss *bss;
struct ieee80211_supported_band *band;
struct brcmu_chan ch;
- s32 err = 0;
u16 channel;
u32 freq;
u16 notify_capability;
@@ -2438,7 +2403,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
cfg80211_put_bss(wiphy, bss);
- return err;
+ return 0;
}
static struct brcmf_bss_info_le *
@@ -2690,7 +2655,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
{
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
s32 status;
- s32 err = 0;
struct brcmf_escan_result_le *escan_result_le;
struct brcmf_bss_info_le *bss_info_le;
struct brcmf_bss_info_le *bss = NULL;
@@ -2781,7 +2745,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
status);
}
exit:
- return err;
+ return 0;
}
static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
@@ -3260,35 +3224,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
return 0;
}
-#ifdef CONFIG_NL80211_TESTMODE
-static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- void *data, int len)
-{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct net_device *ndev = cfg_to_ndev(cfg);
- struct brcmf_dcmd *dcmd = data;
- struct sk_buff *reply;
- int ret;
-
- brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
- dcmd->buf, dcmd->len);
-
- if (dcmd->set)
- ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
- dcmd->buf, dcmd->len);
- else
- ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
- dcmd->buf, dcmd->len);
- if (ret == 0) {
- reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
- nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
- ret = cfg80211_testmode_reply(reply);
- }
- return ret;
-}
-#endif
-
static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
{
s32 err;
@@ -3507,7 +3442,6 @@ static s32
brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
struct parsed_vndr_ies *vndr_ies)
{
- s32 err = 0;
struct brcmf_vs_tlv *vndrie;
struct brcmf_tlv *ie;
struct parsed_vndr_ie_info *parsed_info;
@@ -3560,7 +3494,7 @@ next:
ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
TLV_HDR_LEN);
}
- return err;
+ return 0;
}
static u32
@@ -4221,6 +4155,27 @@ static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
}
+static s32
+brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
+{
+ switch (e->reason) {
+ case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
+ brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
+ break;
+ case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
+ brcmf_dbg(TRACE, "TDLS Peer Connected\n");
+ brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+ break;
+ case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
+ brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
+ brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+ break;
+ }
+
+ return 0;
+}
+
static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
{
int ret;
@@ -4307,120 +4262,8 @@ static struct cfg80211_ops wl_cfg80211_ops = {
.crit_proto_start = brcmf_cfg80211_crit_proto_start,
.crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
.tdls_oper = brcmf_cfg80211_tdls_oper,
- CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
};
-static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
-{
- /* scheduled scan settings */
- wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
- wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
- wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
- wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
-}
-
-static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
- {
- .max = 2,
- .types = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP)
- },
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO)
- },
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
- }
-};
-static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
- {
- .max_interfaces = BRCMF_IFACE_MAX_CNT,
- .num_different_channels = 2,
- .n_limits = ARRAY_SIZE(brcmf_iface_limits),
- .limits = brcmf_iface_limits
- }
-};
-
-static const struct ieee80211_txrx_stypes
-brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
- [NL80211_IFTYPE_STATION] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_CLIENT] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_GO] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
- BIT(IEEE80211_STYPE_DISASSOC >> 4) |
- BIT(IEEE80211_STYPE_AUTH >> 4) |
- BIT(IEEE80211_STYPE_DEAUTH >> 4) |
- BIT(IEEE80211_STYPE_ACTION >> 4)
- },
- [NL80211_IFTYPE_P2P_DEVICE] = {
- .tx = 0xffff,
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- }
-};
-
-static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
-{
- struct wiphy *wiphy;
- s32 err = 0;
-
- wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
- if (!wiphy) {
- brcmf_err("Could not allocate wiphy device\n");
- return ERR_PTR(-ENOMEM);
- }
- set_wiphy_dev(wiphy, phydev);
- wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
- wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
- wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_DEVICE);
- wiphy->iface_combinations = brcmf_iface_combos;
- wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
- wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
- wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
- wiphy->cipher_suites = __wl_cipher_suites;
- wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
- wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
- WIPHY_FLAG_OFFCHAN_TX |
- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
- WIPHY_FLAG_SUPPORTS_TDLS;
- if (!brcmf_roamoff)
- wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
- wiphy->mgmt_stypes = brcmf_txrx_stypes;
- wiphy->max_remain_on_channel_duration = 5000;
- brcmf_wiphy_pno_params(wiphy);
- brcmf_dbg(INFO, "Registering custom regulatory\n");
- wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
- wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
- err = wiphy_register(wiphy);
- if (err < 0) {
- brcmf_err("Could not register wiphy device (%d)\n", err);
- wiphy_free(wiphy);
- return ERR_PTR(err);
- }
- return wiphy;
-}
-
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
enum nl80211_iftype type,
bool pm_block)
@@ -4650,7 +4493,6 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
- s32 err = 0;
brcmf_dbg(TRACE, "Enter\n");
@@ -4676,7 +4518,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
completed ? "succeeded" : "failed");
}
brcmf_dbg(TRACE, "Exit\n");
- return err;
+ return 0;
}
static s32
@@ -4728,6 +4570,13 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
struct ieee80211_channel *chan;
s32 err = 0;
+ if ((e->event_code == BRCMF_E_DEAUTH) ||
+ (e->event_code == BRCMF_E_DEAUTH_IND) ||
+ (e->event_code == BRCMF_E_DISASSOC_IND) ||
+ ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
+ brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+ }
+
if (brcmf_is_apmode(ifp->vif)) {
err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
} else if (brcmf_is_linkup(e)) {
@@ -4768,7 +4617,6 @@ brcmf_notify_roaming_status(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- s32 err = 0;
u32 event = e->event_code;
u32 status = e->status;
@@ -4779,7 +4627,7 @@ brcmf_notify_roaming_status(struct brcmf_if *ifp,
brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
}
- return err;
+ return 0;
}
static s32
@@ -4966,135 +4814,6 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
mutex_init(&event->vif_event_lock);
}
-static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
-{
- struct brcmf_fil_bwcap_le band_bwcap;
- u32 val;
- int err;
-
- /* verify support for bw_cap command */
- val = WLC_BAND_5G;
- err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
-
- if (!err) {
- /* only set 2G bandwidth using bw_cap command */
- band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
- band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
- err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
- sizeof(band_bwcap));
- } else {
- brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
- val = WLC_N_BW_40ALL;
- err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
- }
- return err;
-}
-
-struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
- struct device *busdev)
-{
- struct net_device *ndev = drvr->iflist[0]->ndev;
- struct brcmf_cfg80211_info *cfg;
- struct wiphy *wiphy;
- struct brcmf_cfg80211_vif *vif;
- struct brcmf_if *ifp;
- s32 err = 0;
- s32 io_type;
-
- if (!ndev) {
- brcmf_err("ndev is invalid\n");
- return NULL;
- }
-
- ifp = netdev_priv(ndev);
- wiphy = brcmf_setup_wiphy(busdev);
- if (IS_ERR(wiphy))
- return NULL;
-
- cfg = wiphy_priv(wiphy);
- cfg->wiphy = wiphy;
- cfg->pub = drvr;
- init_vif_event(&cfg->vif_event);
- INIT_LIST_HEAD(&cfg->vif_list);
-
- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
- if (IS_ERR(vif)) {
- wiphy_free(wiphy);
- return NULL;
- }
-
- vif->ifp = ifp;
- vif->wdev.netdev = ndev;
- ndev->ieee80211_ptr = &vif->wdev;
- SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
-
- err = wl_init_priv(cfg);
- if (err) {
- brcmf_err("Failed to init iwm_priv (%d)\n", err);
- goto cfg80211_attach_out;
- }
- ifp->vif = vif;
-
- err = brcmf_p2p_attach(cfg);
- if (err) {
- brcmf_err("P2P initilisation failed (%d)\n", err);
- goto cfg80211_p2p_attach_out;
- }
- err = brcmf_btcoex_attach(cfg);
- if (err) {
- brcmf_err("BT-coex initialisation failed (%d)\n", err);
- brcmf_p2p_detach(&cfg->p2p);
- goto cfg80211_p2p_attach_out;
- }
-
- /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
- * setup 40MHz in 2GHz band and enable OBSS scanning.
- */
- if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
- IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
- err = brcmf_enable_bw40_2g(ifp);
- if (!err)
- err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
- BRCMF_OBSS_COEX_AUTO);
- }
-
- err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
- if (err) {
- brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
- wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
- }
-
- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
- &io_type);
- if (err) {
- brcmf_err("Failed to get D11 version (%d)\n", err);
- goto cfg80211_p2p_attach_out;
- }
- cfg->d11inf.io_type = (u8)io_type;
- brcmu_d11_attach(&cfg->d11inf);
-
- return cfg;
-
-cfg80211_p2p_attach_out:
- wl_deinit_priv(cfg);
-
-cfg80211_attach_out:
- brcmf_free_vif(vif);
- return NULL;
-}
-
-void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
-{
- if (!cfg)
- return;
-
- WARN_ON(!list_empty(&cfg->vif_list));
- wiphy_unregister(cfg->wiphy);
- brcmf_btcoex_detach(cfg);
- wl_deinit_priv(cfg);
- wiphy_free(cfg->wiphy);
-}
-
static s32
brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
{
@@ -5187,25 +4906,77 @@ dongle_scantime_out:
return err;
}
+/* Filter the list of channels received from firmware counting only
+ * the 20MHz channels. The wiphy band data only needs those which get
+ * flagged to indicate if they can take part in higher bandwidth.
+ */
+static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg,
+ struct brcmf_chanspec_list *chlist,
+ u32 chcnt[])
+{
+ u32 total = le32_to_cpu(chlist->count);
+ struct brcmu_chan ch;
+ int i;
+
+ for (i = 0; i <= total; i++) {
+ ch.chspec = (u16)le32_to_cpu(chlist->element[i]);
+ cfg->d11inf.decchspec(&ch);
+
+ /* Firmware gives a ordered list. We skip non-20MHz
+ * channels is 2G. For 5G we can abort upon reaching
+ * a non-20MHz channel in the list.
+ */
+ if (ch.bw != BRCMU_CHAN_BW_20) {
+ if (ch.band == BRCMU_CHAN_BAND_5G)
+ break;
+ else
+ continue;
+ }
+
+ if (ch.band == BRCMU_CHAN_BAND_2G)
+ chcnt[0] += 1;
+ else if (ch.band == BRCMU_CHAN_BAND_5G)
+ chcnt[1] += 1;
+ }
+}
+
+static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
+ struct brcmu_chan *ch)
+{
+ u32 ht40_flag;
+
+ ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
+ if (ch->sb == BRCMU_CHAN_SB_U) {
+ if (ht40_flag == IEEE80211_CHAN_NO_HT40)
+ channel->flags &= ~IEEE80211_CHAN_NO_HT40;
+ channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
+ } else {
+ /* It should be one of
+ * IEEE80211_CHAN_NO_HT40 or
+ * IEEE80211_CHAN_NO_HT40PLUS
+ */
+ channel->flags &= ~IEEE80211_CHAN_NO_HT40;
+ if (ht40_flag == IEEE80211_CHAN_NO_HT40)
+ channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
+ }
+}
-static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
- u32 bw_cap[])
+static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
+ u32 bw_cap[])
{
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
- struct ieee80211_channel *band_chan_arr;
+ struct ieee80211_supported_band *band;
+ struct ieee80211_channel *channel;
+ struct wiphy *wiphy;
struct brcmf_chanspec_list *list;
struct brcmu_chan ch;
- s32 err;
+ int err;
u8 *pbuf;
u32 i, j;
u32 total;
- enum ieee80211_band band;
- u32 channel;
- u32 *n_cnt;
+ u32 chaninfo;
+ u32 chcnt[2] = { 0, 0 };
u32 index;
- u32 ht40_flag;
- bool update;
- u32 array_size;
pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
@@ -5218,11 +4989,45 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
BRCMF_DCMD_MEDLEN);
if (err) {
brcmf_err("get chanspecs error (%d)\n", err);
- goto exit;
+ goto fail_pbuf;
}
- __wl_band_2ghz.n_channels = 0;
- __wl_band_5ghz_a.n_channels = 0;
+ brcmf_count_20mhz_channels(cfg, list, chcnt);
+ wiphy = cfg_to_wiphy(cfg);
+ if (chcnt[0]) {
+ band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
+ GFP_KERNEL);
+ if (band == NULL) {
+ err = -ENOMEM;
+ goto fail_pbuf;
+ }
+ band->channels = kcalloc(chcnt[0], sizeof(*channel),
+ GFP_KERNEL);
+ if (band->channels == NULL) {
+ kfree(band);
+ err = -ENOMEM;
+ goto fail_pbuf;
+ }
+ band->n_channels = 0;
+ wiphy->bands[IEEE80211_BAND_2GHZ] = band;
+ }
+ if (chcnt[1]) {
+ band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a),
+ GFP_KERNEL);
+ if (band == NULL) {
+ err = -ENOMEM;
+ goto fail_band2g;
+ }
+ band->channels = kcalloc(chcnt[1], sizeof(*channel),
+ GFP_KERNEL);
+ if (band->channels == NULL) {
+ kfree(band);
+ err = -ENOMEM;
+ goto fail_band2g;
+ }
+ band->n_channels = 0;
+ wiphy->bands[IEEE80211_BAND_5GHZ] = band;
+ }
total = le32_to_cpu(list->count);
for (i = 0; i < total; i++) {
@@ -5230,100 +5035,151 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
cfg->d11inf.decchspec(&ch);
if (ch.band == BRCMU_CHAN_BAND_2G) {
- band_chan_arr = __wl_2ghz_channels;
- array_size = ARRAY_SIZE(__wl_2ghz_channels);
- n_cnt = &__wl_band_2ghz.n_channels;
- band = IEEE80211_BAND_2GHZ;
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
} else if (ch.band == BRCMU_CHAN_BAND_5G) {
- band_chan_arr = __wl_5ghz_a_channels;
- array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
- n_cnt = &__wl_band_5ghz_a.n_channels;
- band = IEEE80211_BAND_5GHZ;
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
} else {
brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
continue;
}
- if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
+ if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
ch.bw == BRCMU_CHAN_BW_40)
continue;
- if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
+ if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
ch.bw == BRCMU_CHAN_BW_80)
continue;
- update = false;
- for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
- if (band_chan_arr[j].hw_value == ch.chnum) {
- update = true;
+
+ channel = band->channels;
+ index = band->n_channels;
+ for (j = 0; j < band->n_channels; j++) {
+ if (channel[j].hw_value == ch.chnum) {
+ index = j;
break;
}
}
- if (update)
- index = j;
- else
- index = *n_cnt;
- if (index < array_size) {
- band_chan_arr[index].center_freq =
- ieee80211_channel_to_frequency(ch.chnum, band);
- band_chan_arr[index].hw_value = ch.chnum;
-
- /* assuming the chanspecs order is HT20,
- * HT40 upper, HT40 lower, and VHT80.
+ channel[index].center_freq =
+ ieee80211_channel_to_frequency(ch.chnum, band->band);
+ channel[index].hw_value = ch.chnum;
+
+ /* assuming the chanspecs order is HT20,
+ * HT40 upper, HT40 lower, and VHT80.
+ */
+ if (ch.bw == BRCMU_CHAN_BW_80) {
+ channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
+ } else if (ch.bw == BRCMU_CHAN_BW_40) {
+ brcmf_update_bw40_channel_flag(&channel[index], &ch);
+ } else {
+ /* disable other bandwidths for now as mentioned
+ * order assure they are enabled for subsequent
+ * chanspecs.
*/
- if (ch.bw == BRCMU_CHAN_BW_80) {
- band_chan_arr[index].flags &=
- ~IEEE80211_CHAN_NO_80MHZ;
- } else if (ch.bw == BRCMU_CHAN_BW_40) {
- ht40_flag = band_chan_arr[index].flags &
- IEEE80211_CHAN_NO_HT40;
- if (ch.sb == BRCMU_CHAN_SB_U) {
- if (ht40_flag == IEEE80211_CHAN_NO_HT40)
- band_chan_arr[index].flags &=
- ~IEEE80211_CHAN_NO_HT40;
- band_chan_arr[index].flags |=
- IEEE80211_CHAN_NO_HT40PLUS;
- } else {
- /* It should be one of
- * IEEE80211_CHAN_NO_HT40 or
- * IEEE80211_CHAN_NO_HT40PLUS
- */
- band_chan_arr[index].flags &=
- ~IEEE80211_CHAN_NO_HT40;
- if (ht40_flag == IEEE80211_CHAN_NO_HT40)
- band_chan_arr[index].flags |=
- IEEE80211_CHAN_NO_HT40MINUS;
- }
- } else {
- /* disable other bandwidths for now as mentioned
- * order assure they are enabled for subsequent
- * chanspecs.
- */
- band_chan_arr[index].flags =
- IEEE80211_CHAN_NO_HT40 |
- IEEE80211_CHAN_NO_80MHZ;
- ch.bw = BRCMU_CHAN_BW_20;
- cfg->d11inf.encchspec(&ch);
- channel = ch.chspec;
- err = brcmf_fil_bsscfg_int_get(ifp,
- "per_chan_info",
- &channel);
- if (!err) {
- if (channel & WL_CHAN_RADAR)
- band_chan_arr[index].flags |=
- (IEEE80211_CHAN_RADAR |
- IEEE80211_CHAN_NO_IR);
- if (channel & WL_CHAN_PASSIVE)
- band_chan_arr[index].flags |=
- IEEE80211_CHAN_NO_IR;
- }
+ channel[index].flags = IEEE80211_CHAN_NO_HT40 |
+ IEEE80211_CHAN_NO_80MHZ;
+ ch.bw = BRCMU_CHAN_BW_20;
+ cfg->d11inf.encchspec(&ch);
+ chaninfo = ch.chspec;
+ err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
+ &chaninfo);
+ if (!err) {
+ if (chaninfo & WL_CHAN_RADAR)
+ channel[index].flags |=
+ (IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IR);
+ if (chaninfo & WL_CHAN_PASSIVE)
+ channel[index].flags |=
+ IEEE80211_CHAN_NO_IR;
}
- if (!update)
- (*n_cnt)++;
}
+ if (index == band->n_channels)
+ band->n_channels++;
}
-exit:
+ kfree(pbuf);
+ return 0;
+
+fail_band2g:
+ kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
+ kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
+ wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+fail_pbuf:
kfree(pbuf);
return err;
}
+static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
+{
+ struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+ struct ieee80211_supported_band *band;
+ struct brcmf_fil_bwcap_le band_bwcap;
+ struct brcmf_chanspec_list *list;
+ u8 *pbuf;
+ u32 val;
+ int err;
+ struct brcmu_chan ch;
+ u32 num_chan;
+ int i, j;
+
+ /* verify support for bw_cap command */
+ val = WLC_BAND_5G;
+ err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
+
+ if (!err) {
+ /* only set 2G bandwidth using bw_cap command */
+ band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
+ band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
+ err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
+ sizeof(band_bwcap));
+ } else {
+ brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
+ val = WLC_N_BW_40ALL;
+ err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
+ }
+
+ if (!err) {
+ /* update channel info in 2G band */
+ pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
+
+ if (pbuf == NULL)
+ return -ENOMEM;
+
+ ch.band = BRCMU_CHAN_BAND_2G;
+ ch.bw = BRCMU_CHAN_BW_40;
+ ch.chnum = 0;
+ cfg->d11inf.encchspec(&ch);
+
+ /* pass encoded chanspec in query */
+ *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
+
+ err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
+ BRCMF_DCMD_MEDLEN);
+ if (err) {
+ brcmf_err("get chanspecs error (%d)\n", err);
+ kfree(pbuf);
+ return err;
+ }
+
+ band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
+ list = (struct brcmf_chanspec_list *)pbuf;
+ num_chan = le32_to_cpu(list->count);
+ for (i = 0; i < num_chan; i++) {
+ ch.chspec = (u16)le32_to_cpu(list->element[i]);
+ cfg->d11inf.decchspec(&ch);
+ if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
+ continue;
+ if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
+ continue;
+ for (j = 0; j < band->n_channels; j++) {
+ if (band->channels[j].hw_value == ch.chnum)
+ break;
+ }
+ if (WARN_ON(j == band->n_channels))
+ continue;
+
+ brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
+ }
+ }
+ return err;
+}
+
static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
{
u32 band, mimo_bwcap;
@@ -5414,44 +5270,19 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
}
-static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
+static int brcmf_setup_wiphybands(struct wiphy *wiphy)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
- struct wiphy *wiphy;
- s32 phy_list;
- u32 band_list[3];
u32 nmode = 0;
u32 vhtmode = 0;
- u32 bw_cap[2] = { 0, 0 };
+ u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
u32 rxchain;
u32 nchain;
- s8 phy;
- s32 err;
- u32 nband;
+ int err;
s32 i;
- struct ieee80211_supported_band *bands[2] = { NULL, NULL };
struct ieee80211_supported_band *band;
- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
- &phy_list, sizeof(phy_list));
- if (err) {
- brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
- return err;
- }
-
- phy = ((char *)&phy_list)[0];
- brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
-
-
- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
- &band_list, sizeof(band_list));
- if (err) {
- brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
- return err;
- }
- brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
- band_list[0], band_list[1], band_list[2]);
-
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
if (err) {
@@ -5473,44 +5304,129 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
}
brcmf_dbg(INFO, "nchain=%d\n", nchain);
- err = brcmf_construct_reginfo(cfg, bw_cap);
+ err = brcmf_construct_chaninfo(cfg, bw_cap);
if (err) {
- brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
+ brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
return err;
}
- nband = band_list[0];
-
- for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
- band = NULL;
- if ((band_list[i] == WLC_BAND_5G) &&
- (__wl_band_5ghz_a.n_channels > 0))
- band = &__wl_band_5ghz_a;
- else if ((band_list[i] == WLC_BAND_2G) &&
- (__wl_band_2ghz.n_channels > 0))
- band = &__wl_band_2ghz;
- else
+ wiphy = cfg_to_wiphy(cfg);
+ for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
+ band = wiphy->bands[i];
+ if (band == NULL)
continue;
if (nmode)
brcmf_update_ht_cap(band, bw_cap, nchain);
if (vhtmode)
brcmf_update_vht_cap(band, bw_cap, nchain);
- bands[band->band] = band;
}
- wiphy = cfg_to_wiphy(cfg);
- wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
- wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
- wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
-
- return err;
+ return 0;
}
+static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
+ {
+ .max = 2,
+ .types = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP)
+ },
+ {
+ .max = 1,
+ .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO)
+ },
+ {
+ .max = 1,
+ .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
+ }
+};
+static struct ieee80211_iface_combination brcmf_iface_combos[] = {
+ {
+ .max_interfaces = BRCMF_IFACE_MAX_CNT,
+ .num_different_channels = 1,
+ .n_limits = ARRAY_SIZE(brcmf_iface_limits),
+ .limits = brcmf_iface_limits
+ }
+};
-static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
+static const struct ieee80211_txrx_stypes
+brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
+ [NL80211_IFTYPE_STATION] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_P2P_CLIENT] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ },
+ [NL80211_IFTYPE_P2P_GO] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_ACTION >> 4)
+ },
+ [NL80211_IFTYPE_P2P_DEVICE] = {
+ .tx = 0xffff,
+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ }
+};
+
+static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
{
- return brcmf_update_wiphybands(cfg);
+ /* scheduled scan settings */
+ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
+ wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
+ wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+}
+
+static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
+{
+ struct ieee80211_iface_combination ifc_combo;
+ wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+ wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
+ wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
+ /* need VSDB firmware feature for concurrent channels */
+ ifc_combo = brcmf_iface_combos[0];
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
+ ifc_combo.num_different_channels = 2;
+ wiphy->iface_combinations = kmemdup(&ifc_combo,
+ sizeof(ifc_combo),
+ GFP_KERNEL);
+ wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ wiphy->cipher_suites = __wl_cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+ wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
+ WIPHY_FLAG_OFFCHAN_TX |
+ WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+ WIPHY_FLAG_SUPPORTS_TDLS;
+ if (!brcmf_roamoff)
+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+ wiphy->mgmt_stypes = brcmf_txrx_stypes;
+ wiphy->max_remain_on_channel_duration = 5000;
+ brcmf_wiphy_pno_params(wiphy);
+
+ /* vendor commands/events support */
+ wiphy->vendor_commands = brcmf_vendor_cmds;
+ wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
+
+ return brcmf_setup_wiphybands(wiphy);
}
static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
@@ -5548,9 +5464,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
NULL, NULL);
if (err)
goto default_conf_out;
- err = brcmf_dongle_probecap(cfg);
- if (err)
- goto default_conf_out;
brcmf_configure_arp_offload(ifp, true);
@@ -5625,16 +5538,15 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
return wdev->iftype;
}
-u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
+bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state)
{
struct brcmf_cfg80211_vif *vif;
- bool result = 0;
list_for_each_entry(vif, &cfg->vif_list, list) {
if (test_bit(state, &vif->sme_state))
- result++;
+ return true;
}
- return result;
+ return false;
}
static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
@@ -5679,3 +5591,153 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
vif_event_equals(event, action), timeout);
}
+static void brcmf_free_wiphy(struct wiphy *wiphy)
+{
+ kfree(wiphy->iface_combinations);
+ if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
+ kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
+ kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
+ }
+ if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
+ kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
+ kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
+ }
+ wiphy_free(wiphy);
+}
+
+struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
+ struct device *busdev)
+{
+ struct net_device *ndev = drvr->iflist[0]->ndev;
+ struct brcmf_cfg80211_info *cfg;
+ struct wiphy *wiphy;
+ struct brcmf_cfg80211_vif *vif;
+ struct brcmf_if *ifp;
+ s32 err = 0;
+ s32 io_type;
+ u16 *cap = NULL;
+
+ if (!ndev) {
+ brcmf_err("ndev is invalid\n");
+ return NULL;
+ }
+
+ ifp = netdev_priv(ndev);
+ wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
+ if (!wiphy) {
+ brcmf_err("Could not allocate wiphy device\n");
+ return NULL;
+ }
+ set_wiphy_dev(wiphy, busdev);
+
+ cfg = wiphy_priv(wiphy);
+ cfg->wiphy = wiphy;
+ cfg->pub = drvr;
+ init_vif_event(&cfg->vif_event);
+ INIT_LIST_HEAD(&cfg->vif_list);
+
+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
+ if (IS_ERR(vif))
+ goto wiphy_out;
+
+ vif->ifp = ifp;
+ vif->wdev.netdev = ndev;
+ ndev->ieee80211_ptr = &vif->wdev;
+ SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
+
+ err = wl_init_priv(cfg);
+ if (err) {
+ brcmf_err("Failed to init iwm_priv (%d)\n", err);
+ brcmf_free_vif(vif);
+ goto wiphy_out;
+ }
+ ifp->vif = vif;
+
+ /* determine d11 io type before wiphy setup */
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
+ if (err) {
+ brcmf_err("Failed to get D11 version (%d)\n", err);
+ goto priv_out;
+ }
+ cfg->d11inf.io_type = (u8)io_type;
+ brcmu_d11_attach(&cfg->d11inf);
+
+ err = brcmf_setup_wiphy(wiphy, ifp);
+ if (err < 0)
+ goto priv_out;
+
+ brcmf_dbg(INFO, "Registering custom regulatory\n");
+ wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
+ wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
+
+ /* firmware defaults to 40MHz disabled in 2G band. We signal
+ * cfg80211 here that we do and have it decide we can enable
+ * it. But first check if device does support 2G operation.
+ */
+ if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
+ cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
+ *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
+ err = wiphy_register(wiphy);
+ if (err < 0) {
+ brcmf_err("Could not register wiphy device (%d)\n", err);
+ goto priv_out;
+ }
+
+ /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
+ * setup 40MHz in 2GHz band and enable OBSS scanning.
+ */
+ if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
+ err = brcmf_enable_bw40_2g(cfg);
+ if (!err)
+ err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
+ BRCMF_OBSS_COEX_AUTO);
+ else
+ *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
+
+ err = brcmf_p2p_attach(cfg);
+ if (err) {
+ brcmf_err("P2P initilisation failed (%d)\n", err);
+ goto wiphy_unreg_out;
+ }
+ err = brcmf_btcoex_attach(cfg);
+ if (err) {
+ brcmf_err("BT-coex initialisation failed (%d)\n", err);
+ brcmf_p2p_detach(&cfg->p2p);
+ goto wiphy_unreg_out;
+ }
+
+ err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
+ if (err) {
+ brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
+ wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
+ } else {
+ brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
+ brcmf_notify_tdls_peer_event);
+ }
+
+ return cfg;
+
+wiphy_unreg_out:
+ wiphy_unregister(cfg->wiphy);
+priv_out:
+ wl_deinit_priv(cfg);
+ brcmf_free_vif(vif);
+wiphy_out:
+ brcmf_free_wiphy(wiphy);
+ return NULL;
+}
+
+void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
+{
+ if (!cfg)
+ return;
+
+ WARN_ON(!list_empty(&cfg->vif_list));
+ wiphy_unregister(cfg->wiphy);
+ brcmf_btcoex_detach(cfg);
+ brcmf_p2p_detach(&cfg->p2p);
+ wl_deinit_priv(cfg);
+ brcmf_free_wiphy(cfg->wiphy);
+}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 283c525a44f7..f9fb10998e79 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -477,7 +477,7 @@ const struct brcmf_tlv *
brcmf_parse_tlvs(const void *buf, int buflen, uint key);
u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
struct ieee80211_channel *ch);
-u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state);
+bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state);
void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
struct brcmf_cfg80211_vif *vif);
bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index af8ba64ace39..1b474828d5b8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4707,41 +4707,6 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
return err;
}
-static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
-{
- uint unit;
- unit = wlc->pub->unit;
-
- if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
- /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
- wlc->band->antgain = 8;
- } else if (wlc->band->antgain == -1) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
- " srom, using 2dB\n", unit, __func__);
- wlc->band->antgain = 8;
- } else {
- s8 gain, fract;
- /* Older sroms specified gain in whole dbm only. In order
- * be able to specify qdbm granularity and remain backward
- * compatible the whole dbms are now encoded in only
- * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
- * 6 bit signed number ranges from -32 - 31.
- *
- * Examples:
- * 0x1 = 1 db,
- * 0xc1 = 1.75 db (1 + 3 quarters),
- * 0x3f = -1 (-1 + 0 quarters),
- * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
- * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
- */
- gain = wlc->band->antgain & 0x3f;
- gain <<= 2; /* Sign extend */
- gain >>= 2;
- fract = (wlc->band->antgain & 0xc0) >> 6;
- wlc->band->antgain = 4 * gain + fract;
- }
-}
-
static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
{
int aa;
@@ -4780,8 +4745,6 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
else
wlc->band->antgain = sprom->antenna_gain.a0;
- brcms_c_attach_antgain_init(wlc);
-
return true;
}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
index b0fd807f2b2b..57ecc05802e9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -1538,11 +1538,7 @@ static s8
wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
u8 rate)
{
- s8 offset = 0;
-
- if (!pi->user_txpwr_at_rfport)
- return offset;
- return offset;
+ return 0;
}
void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 3e9f5b25be63..93869e89aa3d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -22916,7 +22916,6 @@ static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
break;
default:
return;
- break;
}
classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index d816270db3be..af26e0de1e5c 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -17,32 +17,67 @@
#ifndef _BRCM_HW_IDS_H_
#define _BRCM_HW_IDS_H_
-#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
+#include <linux/pci_ids.h>
+#include <linux/mmc/sdio_ids.h>
+
+#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
+#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
+#define BRCM_SDIO_VENDOR_ID_BROADCOM SDIO_VENDOR_ID_BROADCOM
+
+/* Chipcommon Core Chip IDs */
+#define BRCM_CC_43143_CHIP_ID 43143
+#define BRCM_CC_43235_CHIP_ID 43235
+#define BRCM_CC_43236_CHIP_ID 43236
+#define BRCM_CC_43238_CHIP_ID 43238
+#define BRCM_CC_43241_CHIP_ID 0x4324
+#define BRCM_CC_43242_CHIP_ID 43242
+#define BRCM_CC_4329_CHIP_ID 0x4329
+#define BRCM_CC_4330_CHIP_ID 0x4330
+#define BRCM_CC_4334_CHIP_ID 0x4334
+#define BRCM_CC_43362_CHIP_ID 43362
+#define BRCM_CC_4335_CHIP_ID 0x4335
+#define BRCM_CC_4339_CHIP_ID 0x4339
+#define BRCM_CC_4354_CHIP_ID 0x4354
+#define BRCM_CC_4356_CHIP_ID 0x4356
+#define BRCM_CC_43566_CHIP_ID 43566
+#define BRCM_CC_43567_CHIP_ID 43567
+#define BRCM_CC_43569_CHIP_ID 43569
+#define BRCM_CC_43570_CHIP_ID 43570
+#define BRCM_CC_43602_CHIP_ID 43602
+
+/* SDIO Device IDs */
+#define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID
+#define BRCM_SDIO_43241_DEVICE_ID BRCM_CC_43241_CHIP_ID
+#define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID
+#define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID
+#define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID
+#define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID
+#define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID
+#define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID
+
+/* USB Device IDs */
+#define BRCM_USB_43143_DEVICE_ID 0xbd1e
+#define BRCM_USB_43236_DEVICE_ID 0xbd17
+#define BRCM_USB_43242_DEVICE_ID 0xbd1f
+#define BRCM_USB_43569_DEVICE_ID 0xbd27
+#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
+/* PCIE Device IDs */
+#define BRCM_PCIE_4354_DEVICE_ID 0x43df
+#define BRCM_PCIE_4356_DEVICE_ID 0x43ec
+#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
+#define BRCM_PCIE_43570_DEVICE_ID 0x43d9
+#define BRCM_PCIE_43602_DEVICE_ID 0x43ba
+
+/* brcmsmac IDs */
+#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */
#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */
-
#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */
-
#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */
#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */
-/* Chipcommon Core Chip IDs */
#define BCM4313_CHIP_ID 0x4313
-#define BCM43143_CHIP_ID 43143
#define BCM43224_CHIP_ID 43224
-#define BCM43225_CHIP_ID 43225
-#define BCM43235_CHIP_ID 43235
-#define BCM43236_CHIP_ID 43236
-#define BCM43238_CHIP_ID 43238
-#define BCM43241_CHIP_ID 0x4324
-#define BCM4329_CHIP_ID 0x4329
-#define BCM4330_CHIP_ID 0x4330
-#define BCM4331_CHIP_ID 0x4331
-#define BCM4334_CHIP_ID 0x4334
-#define BCM4335_CHIP_ID 0x4335
-#define BCM43362_CHIP_ID 43362
-#define BCM4339_CHIP_ID 0x4339
-#define BCM4354_CHIP_ID 0x4354
#endif /* _BRCM_HW_IDS_H_ */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index e23d67e0bfe6..6f1b9aace8b3 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -290,7 +290,6 @@ static int config_reg_write(struct cw1200_common *priv, u32 val)
case HIF_8601_SILICON:
default:
return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
- break;
}
return 0;
}
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
index 9afcd4ce3368..b2fb6c632092 100644
--- a/drivers/net/wireless/cw1200/scan.c
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -53,9 +53,10 @@ static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
int cw1200_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
struct cw1200_common *priv = hw->priv;
+ struct cfg80211_scan_request *req = &hw_req->req;
struct wsm_template_frame frame = {
.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
};
diff --git a/drivers/net/wireless/cw1200/scan.h b/drivers/net/wireless/cw1200/scan.h
index 5a8296ccfa82..cc75459e5784 100644
--- a/drivers/net/wireless/cw1200/scan.h
+++ b/drivers/net/wireless/cw1200/scan.h
@@ -41,7 +41,7 @@ struct cw1200_scan {
int cw1200_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req);
+ struct ieee80211_scan_request *hw_req);
void cw1200_scan_work(struct work_struct *work);
void cw1200_scan_timeout(struct work_struct *work);
void cw1200_clear_recent_scan_work(struct work_struct *work);
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index cd0cad7f7759..5b84664db13b 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -2289,7 +2289,6 @@ static int cw1200_upload_null(struct cw1200_common *priv)
static int cw1200_upload_qosnull(struct cw1200_common *priv)
{
- int ret = 0;
/* TODO: This needs to be implemented
struct wsm_template_frame frame = {
@@ -2306,7 +2305,7 @@ static int cw1200_upload_qosnull(struct cw1200_common *priv)
dev_kfree_skb(frame.skb);
*/
- return ret;
+ return 0;
}
static int cw1200_enable_beaconing(struct cw1200_common *priv,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 3adb24021a28..5f31b72a4921 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -100,8 +100,7 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
int i;
for (i = 0; i < MAX_NETWORK_COUNT; i++) {
- if (ieee->networks[i]->ibss_dfs)
- kfree(ieee->networks[i]->ibss_dfs);
+ kfree(ieee->networks[i]->ibss_dfs);
kfree(ieee->networks[i]);
}
}
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index ecc674627e6e..2c4fa49686ef 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1572,8 +1572,9 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
int
il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
+ struct cfg80211_scan_request *req = &hw_req->req;
struct il_priv *il = hw->priv;
int ret;
@@ -2979,7 +2980,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
/* Driver ilate data, only for Tx (not command) queues,
* not shared with device. */
if (id != il->cmd_queue) {
- txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *),
+ txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX,
+ sizeof(struct sk_buff *),
GFP_KERNEL);
if (!txq->skbs) {
IL_ERR("Fail to alloc skbs\n");
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index ea5c0f863c4e..5b972798bdff 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1787,7 +1787,7 @@ int il_scan_cancel(struct il_priv *il);
int il_scan_cancel_timeout(struct il_priv *il, unsigned long ms);
void il_force_scan_end(struct il_priv *il);
int il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req);
+ struct ieee80211_scan_request *hw_req);
void il_internal_short_hw_scan(struct il_priv *il);
int il_force_reset(struct il_priv *il, bool external);
u16 il_fill_probe_req(struct il_priv *il, struct ieee80211_mgmt *frame,
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 7fd50428b934..6451d2b6abcf 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -20,16 +20,17 @@ config IWLWIFI
Intel 2000 Series Wi-Fi Adapters
Intel 7260 Wi-Fi Adapter
Intel 3160 Wi-Fi Adapter
+ Intel 7265 Wi-Fi Adapter
This driver uses the kernel's mac80211 subsystem.
- In order to use this driver, you will need a microcode (uCode)
+ In order to use this driver, you will need a firmware
image for it. You can obtain the microcode from:
- <http://intellinuxwireless.org/>.
+ <http://wireless.kernel.org/en/users/Drivers/iwlwifi>.
- The microcode is typically installed in /lib/firmware. You can
+ The firmware is typically installed in /lib/firmware. You can
look in the hotplug script /etc/hotplug/firmware.agent to
determine which directory FIRMWARE_DIR is set to when the script
runs.
@@ -39,9 +40,10 @@ config IWLWIFI
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwlwifi.
+if IWLWIFI
+
config IWLWIFI_LEDS
bool
- depends on IWLWIFI
depends on LEDS_CLASS=y || LEDS_CLASS=IWLWIFI
select LEDS_TRIGGERS
select MAC80211_LEDS
@@ -49,7 +51,7 @@ config IWLWIFI_LEDS
config IWLDVM
tristate "Intel Wireless WiFi DVM Firmware support"
- depends on IWLWIFI
+ depends on m
default IWLWIFI
help
This is the driver that supports the DVM firmware which is
@@ -58,7 +60,7 @@ config IWLDVM
config IWLMVM
tristate "Intel Wireless WiFi MVM Firmware support"
- depends on IWLWIFI
+ depends on m
help
This is the driver that supports the MVM firmware which is
currently only available for 7260 and 3160 devices.
@@ -70,7 +72,7 @@ config IWLWIFI_OPMODE_MODULAR
default y if IWLMVM=m
comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
- depends on IWLWIFI && IWLDVM=n && IWLMVM=n
+ depends on IWLDVM=n && IWLMVM=n
config IWLWIFI_BCAST_FILTERING
bool "Enable broadcast filtering"
@@ -86,11 +88,9 @@ config IWLWIFI_BCAST_FILTERING
expect incoming broadcasts for their normal operations.
menu "Debugging Options"
- depends on IWLWIFI
config IWLWIFI_DEBUG
bool "Enable full debugging output in the iwlwifi driver"
- depends on IWLWIFI
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -115,7 +115,7 @@ config IWLWIFI_DEBUG
config IWLWIFI_DEBUGFS
bool "iwlwifi debugfs support"
- depends on IWLWIFI && MAC80211_DEBUGFS
+ depends on MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
@@ -123,13 +123,12 @@ config IWLWIFI_DEBUGFS
config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
bool "Experimental uCode support"
- depends on IWLWIFI && IWLWIFI_DEBUG
+ depends on IWLWIFI_DEBUG
---help---
Enable use of experimental ucode for testing and debugging.
config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing"
- depends on IWLWIFI
depends on EVENT_TRACING
help
Say Y here to trace all commands, including TX frames and IO
@@ -145,3 +144,5 @@ config IWLWIFI_DEVICE_TRACING
If unsure, say Y so we can help you better when problems
occur.
endmenu
+
+endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 29af7b51e370..afb98f4fdaf3 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1495,9 +1495,10 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+ struct cfg80211_scan_request *req = &hw_req->req;
int ret;
IWL_DEBUG_MAC80211(priv, "enter\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index f2c1439566b5..760c45c34ef3 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -40,6 +40,10 @@
#include "commands.h"
#include "power.h"
+static bool force_cam;
+module_param(force_cam, bool, 0644);
+MODULE_PARM_DESC(force_cam, "force continuously aware mode (no power saving at all)");
+
/*
* Setting power level allows the card to go to sleep when not busy.
*
@@ -288,6 +292,11 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
int dtimper;
+ if (force_cam) {
+ iwl_power_sleep_cam_cmd(priv, cmd);
+ return;
+ }
+
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
if (priv->wowlan)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index ed50de6362ed..6dc5dd3ced44 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1068,13 +1068,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
/* recalculate basic rates */
iwl_calc_basic_rates(priv, ctx);
- /*
- * force CTS-to-self frames protection if RTS-CTS is not preferred
- * one aggregation protection method
- */
- if (!priv->hw_params.use_rts_for_aggregation)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
-
if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -1480,11 +1473,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
else
ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- if (bss_conf->use_cts_prot)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
- else
- ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
-
memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
if (vif->type == NL80211_IFTYPE_AP ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 51c41531d81d..44b19e015102 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -67,7 +67,7 @@
#include "iwl-agn-hw.h"
/* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX 8
+#define IWL8000_UCODE_API_MAX 9
/* Oldest version we won't warn about */
#define IWL8000_UCODE_API_OK 8
@@ -85,6 +85,9 @@
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin"
+/* Max SDIO RX aggregation size of the ADDBA request/response */
+#define MAX_RX_AGG_SIZE_8260_SDIO 28
+
static const struct iwl_base_params iwl8000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000,
.num_of_queues = IWLAGN_NUM_QUEUES,
@@ -119,10 +122,9 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
.ht_params = &iwl8000_ht_params,
.nvm_ver = IWL8000_NVM_VERSION,
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
- .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
};
-const struct iwl_cfg iwl8260_n_cfg = {
+const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
.name = "Intel(R) Dual Band Wireless-AC 8260",
.fw_name_pre = IWL8000_FW_PRE,
IWL_DEVICE_8000,
@@ -130,6 +132,7 @@ const struct iwl_cfg iwl8260_n_cfg = {
.nvm_ver = IWL8000_NVM_VERSION,
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
.default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
+ .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
};
MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index b7047905f41a..8da596db9abe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -240,6 +240,7 @@ struct iwl_pwr_tx_backoff {
* @d0i3: device uses d0i3 instead of d3
* @nvm_hw_section_num: the ID of the HW NVM section
* @pwr_tx_backoffs: translation table between power limits and backoffs
+ * @max_rx_agg_size: max RX aggregation size of the ADDBA request/response
*
* We enable the driver to be backward compatible wrt. hardware features.
* API differences in uCode shouldn't be handled here but through TLVs
@@ -276,6 +277,7 @@ struct iwl_cfg {
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
bool no_power_up_nic_in_init;
const char *default_nvm_file;
+ unsigned int max_rx_agg_size;
};
/*
@@ -337,7 +339,7 @@ extern const struct iwl_cfg iwl7265_2ac_cfg;
extern const struct iwl_cfg iwl7265_2n_cfg;
extern const struct iwl_cfg iwl7265_n_cfg;
extern const struct iwl_cfg iwl8260_2ac_cfg;
-extern const struct iwl_cfg iwl8260_n_cfg;
+extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index f2a5c12269a3..77e3178040b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -155,6 +155,8 @@ static struct iwlwifi_opmode_table {
[MVM_OP_MODE] = { .name = "iwlmvm", .ops = NULL },
};
+#define IWL_DEFAULT_SCAN_CHANNELS 40
+
/*
* struct fw_sec: Just for the image parsing proccess.
* For the fw storage we are using struct fw_desc.
@@ -565,6 +567,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
}
drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
+ memcpy(drv->fw.human_readable, ucode->human_readable,
+ sizeof(drv->fw.human_readable));
build = le32_to_cpu(ucode->build);
if (build)
@@ -819,6 +823,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len))
goto invalid_tlv_len;
break;
+ case IWL_UCODE_TLV_N_SCAN_CHANNELS:
+ if (tlv_len != sizeof(u32))
+ goto invalid_tlv_len;
+ capa->n_scan_channels =
+ le32_to_cpup((__le32 *)tlv_data);
+ break;
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;
@@ -973,6 +983,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
fw->ucode_capa.standard_phy_calibration_size =
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+ fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
if (!api_ok)
api_ok = api_max;
@@ -1394,3 +1405,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
int, S_IRUGO);
MODULE_PARM_DESC(power_level,
"default power save level (range from 1 - 5, default: 1)");
+
+module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO);
+MODULE_PARM_DESC(fw_monitor,
+ "firmware monitor - to debug FW (default: false - needs lots of memory)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index c44cf1149648..07ff7e0028ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -779,7 +779,6 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
if (cfg->ht_params->ht40_bands & BIT(band)) {
ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
- ht_info->mcs.rx_mask[4] = 0x01;
max_bit_rate = MAX_BIT_RATE_40_MHZ;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 2953ffceda38..de5994a776c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -70,16 +70,24 @@
/**
* enum iwl_fw_error_dump_type - types of data in the dump file
* @IWL_FW_ERROR_DUMP_SRAM:
- * @IWL_FW_ERROR_DUMP_REG:
+ * @IWL_FW_ERROR_DUMP_CSR: Control Status Registers - from offset 0
* @IWL_FW_ERROR_DUMP_RXF:
* @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
* &struct iwl_fw_error_dump_txcmd packets
+ * @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info
+ * info on the device / firmware.
+ * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
+ * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several
+ * sections like this in a single file.
*/
enum iwl_fw_error_dump_type {
IWL_FW_ERROR_DUMP_SRAM = 0,
- IWL_FW_ERROR_DUMP_REG = 1,
+ IWL_FW_ERROR_DUMP_CSR = 1,
IWL_FW_ERROR_DUMP_RXF = 2,
IWL_FW_ERROR_DUMP_TXCMD = 3,
+ IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
+ IWL_FW_ERROR_DUMP_FW_MONITOR = 5,
+ IWL_FW_ERROR_DUMP_PRPH = 6,
IWL_FW_ERROR_DUMP_MAX,
};
@@ -87,8 +95,8 @@ enum iwl_fw_error_dump_type {
/**
* struct iwl_fw_error_dump_data - data for one type
* @type: %enum iwl_fw_error_dump_type
- * @len: the length starting from %data - must be a multiplier of 4.
- * @data: the data itself padded to be a multiplier of 4.
+ * @len: the length starting from %data
+ * @data: the data itself
*/
struct iwl_fw_error_dump_data {
__le32 type;
@@ -120,13 +128,60 @@ struct iwl_fw_error_dump_txcmd {
u8 data[];
} __packed;
+enum iwl_fw_error_dump_family {
+ IWL_FW_ERROR_DUMP_FAMILY_7 = 7,
+ IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
+};
+
+/**
+ * struct iwl_fw_error_dump_info - info on the device / firmware
+ * @device_family: the family of the device (7 / 8)
+ * @hw_step: the step of the device
+ * @fw_human_readable: human readable FW version
+ * @dev_human_readable: name of the device
+ * @bus_human_readable: name of the bus used
+ */
+struct iwl_fw_error_dump_info {
+ __le32 device_family;
+ __le32 hw_step;
+ u8 fw_human_readable[FW_VER_HUMAN_READABLE_SZ];
+ u8 dev_human_readable[64];
+ u8 bus_human_readable[8];
+} __packed;
+
+/**
+ * struct iwl_fw_error_dump_fw_mon - FW monitor data
+ * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer
+ * @fw_mon_base_ptr: base pointer of the data
+ * @fw_mon_cycle_cnt: number of wrap arounds
+ * @reserved: for future use
+ * @data: captured data
+ */
+struct iwl_fw_error_dump_fw_mon {
+ __le32 fw_mon_wr_ptr;
+ __le32 fw_mon_base_ptr;
+ __le32 fw_mon_cycle_cnt;
+ __le32 reserved[3];
+ u8 data[];
+} __packed;
+
+/**
+ * struct iwl_fw_error_dump_prph - periphery registers data
+ * @prph_start: address of the first register in this chunk
+ * @data: the content of the registers
+ */
+struct iwl_fw_error_dump_prph {
+ __le32 prph_start;
+ __le32 data[];
+};
+
/**
- * iwl_mvm_fw_error_next_data - advance fw error dump data pointer
+ * iwl_fw_error_next_data - advance fw error dump data pointer
* @data: previous data block
* Returns: next data block
*/
static inline struct iwl_fw_error_dump_data *
-iwl_mvm_fw_error_next_data(struct iwl_fw_error_dump_data *data)
+iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
{
return (void *)(data->data + le32_to_cpu(data->len));
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index b45e576a4b57..929a8063354c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -128,6 +128,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_CSCHEME = 28,
IWL_UCODE_TLV_API_CHANGES_SET = 29,
IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
+ IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
};
struct iwl_ucode_tlv {
@@ -136,7 +137,8 @@ struct iwl_ucode_tlv {
u8 data[0];
};
-#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
+#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
+#define FW_VER_HUMAN_READABLE_SZ 64
struct iwl_tlv_ucode_header {
/*
@@ -147,7 +149,7 @@ struct iwl_tlv_ucode_header {
*/
__le32 zero;
__le32 magic;
- u8 human_readable[64];
+ u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
__le32 ver; /* major/minor/API/serial */
__le32 build;
__le64 ignore;
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 0aa7c0085c9f..1bb5193c5b1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -65,6 +65,8 @@
#include <linux/types.h>
#include <net/mac80211.h>
+#include "iwl-fw-file.h"
+
/**
* enum iwl_ucode_tlv_flag - ucode API flags
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
@@ -88,6 +90,7 @@
* P2P client interfaces simultaneously if they are in different bindings.
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
* P2P client interfaces simultaneously if they are in same bindings.
+ * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
* @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
@@ -117,11 +120,19 @@ enum iwl_ucode_tlv_flag {
/**
* enum iwl_ucode_tlv_api - ucode api
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
+ * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
+ * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
* @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
+ * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
+ * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
*/
enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
+ IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
+ IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
+ IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
+ IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
};
/**
@@ -178,6 +189,7 @@ enum iwl_ucode_sec {
struct iwl_ucode_capabilities {
u32 max_probe_length;
+ u32 n_scan_channels;
u32 standard_phy_calibration_size;
u32 flags;
u32 api[IWL_API_ARRAY_SIZE];
@@ -311,6 +323,7 @@ struct iwl_fw {
bool mvm_fw;
struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
+ u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
};
#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d051857729ab..71507cf490e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -99,10 +99,11 @@ enum iwl_disable_11n {
* @wd_disable: disable stuck queue check, default = 1
* @bt_coex_active: enable bt coex, default = true
* @led_mode: system default, default = 0
- * @power_save: disable power save, default = false
+ * @power_save: enable power save, default = false
* @power_level: power level, default = 1
* @debug_level: levels are IWL_DL_*
* @ant_coupling: antenna coupling in dB, default = 0
+ * @fw_monitor: allow to use firmware monitor
*/
struct iwl_mod_params {
int sw_crypto;
@@ -120,6 +121,7 @@ struct iwl_mod_params {
int ant_coupling;
char *nvm_file;
bool uapsd_disable;
+ bool fw_monitor;
};
#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 85eee79c495c..018af2957d3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -63,6 +63,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/etherdevice.h>
+#include <linux/pci.h>
#include "iwl-drv.h"
#include "iwl-modparams.h"
#include "iwl-nvm-parse.h"
@@ -87,8 +88,10 @@ enum wkp_nvm_offsets {
enum family_8000_nvm_offsets {
/* NVM HW-Section offset (in words) definitions */
- HW_ADDR0_FAMILY_8000 = 0x12,
- HW_ADDR1_FAMILY_8000 = 0x16,
+ HW_ADDR0_WFPM_FAMILY_8000 = 0x12,
+ HW_ADDR1_WFPM_FAMILY_8000 = 0x16,
+ HW_ADDR0_PCIE_FAMILY_8000 = 0x8A,
+ HW_ADDR1_PCIE_FAMILY_8000 = 0x8E,
MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
/* NVM SW-Section offset (in words) definitions */
@@ -174,7 +177,9 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
* @NVM_CHANNEL_IBSS: usable as an IBSS channel
* @NVM_CHANNEL_ACTIVE: active scanning allowed
* @NVM_CHANNEL_RADAR: radar detection required
- * @NVM_CHANNEL_DFS: dynamic freq selection candidate
+ * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
+ * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
+ * on same channel on 2.4 or same UNII band on 5.2
* @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
@@ -185,7 +190,8 @@ enum iwl_nvm_channel_flags {
NVM_CHANNEL_IBSS = BIT(1),
NVM_CHANNEL_ACTIVE = BIT(3),
NVM_CHANNEL_RADAR = BIT(4),
- NVM_CHANNEL_DFS = BIT(7),
+ NVM_CHANNEL_INDOOR_ONLY = BIT(5),
+ NVM_CHANNEL_GO_CONCURRENT = BIT(6),
NVM_CHANNEL_WIDE = BIT(8),
NVM_CHANNEL_40MHZ = BIT(9),
NVM_CHANNEL_80MHZ = BIT(10),
@@ -273,6 +279,16 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
if (ch_flags & NVM_CHANNEL_RADAR)
channel->flags |= IEEE80211_CHAN_RADAR;
+ if (ch_flags & NVM_CHANNEL_INDOOR_ONLY)
+ channel->flags |= IEEE80211_CHAN_INDOOR_ONLY;
+
+ /* Set the GO concurrent flag only in case that NO_IR is set.
+ * Otherwise it is meaningless
+ */
+ if ((ch_flags & NVM_CHANNEL_GO_CONCURRENT) &&
+ (channel->flags & IEEE80211_CHAN_NO_IR))
+ channel->flags |= IEEE80211_CHAN_GO_CONCURRENT;
+
/* Initialize regulatory-based run-time data */
/*
@@ -282,7 +298,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
channel->max_power = DEFAULT_MAX_TX_POWER;
is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
IWL_DEBUG_EEPROM(dev,
- "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
+ "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
channel->hw_value,
is_5ghz ? "5.2" : "2.4",
CHECK_AND_PRINT_I(VALID),
@@ -290,7 +306,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(WIDE),
- CHECK_AND_PRINT_I(DFS),
+ CHECK_AND_PRINT_I(INDOOR_ONLY),
+ CHECK_AND_PRINT_I(GO_CONCURRENT),
ch_flags,
channel->max_power,
((ch_flags & NVM_CHANNEL_IBSS) &&
@@ -462,7 +479,8 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
data->hw_addr[5] = hw_addr[4];
}
-static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
+static void iwl_set_hw_address_family_8000(struct device *dev,
+ const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const __le16 *mac_override,
const __le16 *nvm_hw)
@@ -481,20 +499,64 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
data->hw_addr[4] = hw_addr[5];
data->hw_addr[5] = hw_addr[4];
- if (is_valid_ether_addr(hw_addr))
+ if (is_valid_ether_addr(data->hw_addr))
return;
+
+ IWL_ERR_DEV(dev,
+ "mac address from nvm override section is not valid\n");
}
- /* take the MAC address from the OTP */
- hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000);
- data->hw_addr[0] = hw_addr[3];
- data->hw_addr[1] = hw_addr[2];
- data->hw_addr[2] = hw_addr[1];
- data->hw_addr[3] = hw_addr[0];
+ if (nvm_hw) {
+ /* read the MAC address from OTP */
+ if (!dev_is_pci(dev) || (data->nvm_version < 0xE08)) {
+ /* read the mac address from the WFPM location */
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR0_WFPM_FAMILY_8000);
+ data->hw_addr[0] = hw_addr[3];
+ data->hw_addr[1] = hw_addr[2];
+ data->hw_addr[2] = hw_addr[1];
+ data->hw_addr[3] = hw_addr[0];
+
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR1_WFPM_FAMILY_8000);
+ data->hw_addr[4] = hw_addr[1];
+ data->hw_addr[5] = hw_addr[0];
+ } else if ((data->nvm_version >= 0xE08) &&
+ (data->nvm_version < 0xE0B)) {
+ /* read "reverse order" from the PCIe location */
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR0_PCIE_FAMILY_8000);
+ data->hw_addr[5] = hw_addr[2];
+ data->hw_addr[4] = hw_addr[1];
+ data->hw_addr[3] = hw_addr[0];
+
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR1_PCIE_FAMILY_8000);
+ data->hw_addr[2] = hw_addr[3];
+ data->hw_addr[1] = hw_addr[2];
+ data->hw_addr[0] = hw_addr[1];
+ } else {
+ /* read from the PCIe location */
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR0_PCIE_FAMILY_8000);
+ data->hw_addr[5] = hw_addr[0];
+ data->hw_addr[4] = hw_addr[1];
+ data->hw_addr[3] = hw_addr[2];
+
+ hw_addr = (const u8 *)(nvm_hw +
+ HW_ADDR1_PCIE_FAMILY_8000);
+ data->hw_addr[2] = hw_addr[1];
+ data->hw_addr[1] = hw_addr[2];
+ data->hw_addr[0] = hw_addr[3];
+ }
+ if (!is_valid_ether_addr(data->hw_addr))
+ IWL_ERR_DEV(dev,
+ "mac address from hw section is not valid\n");
+
+ return;
+ }
- hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000);
- data->hw_addr[4] = hw_addr[1];
- data->hw_addr[5] = hw_addr[0];
+ IWL_ERR_DEV(dev, "mac address is not found\n");
}
struct iwl_nvm_data *
@@ -556,7 +618,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
rx_chains);
} else {
/* MAC address in family 8000 */
- iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw);
+ iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
+ nvm_hw);
iwl_init_sbands(dev, cfg, data, regulatory,
sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 4997e27672b3..47033a35a402 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -359,4 +359,10 @@ enum secure_load_status_reg {
#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
+/* FW monitor */
+#define MON_BUFF_BASE_ADDR (0xa03c3c)
+#define MON_BUFF_END_ADDR (0xa03c40)
+#define MON_BUFF_WRPTR (0xa03c44)
+#define MON_BUFF_CYCLE_CNT (0xa03c48)
+
#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 34d49e171fb4..656371a668da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -394,6 +394,11 @@ struct iwl_trans_config {
const char *const *command_names;
};
+struct iwl_trans_dump_data {
+ u32 len;
+ u8 data[];
+};
+
struct iwl_trans;
/**
@@ -461,10 +466,8 @@ struct iwl_trans;
* @unref: release a reference previously taken with @ref. Note that
* initially the reference count is 1, making an initial @unref
* necessary to allow low power states.
- * @dump_data: fill a data dump with debug data, maybe containing last
- * TX'ed commands and similar. When called with a NULL buffer and
- * zero buffer length, provide only the (estimated) required buffer
- * length. Return the used buffer length.
+ * @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last
+ * TX'ed commands and similar. The buffer will be vfree'd by the caller.
* Note that the transport must fill in the proper file headers.
*/
struct iwl_trans_ops {
@@ -518,7 +521,7 @@ struct iwl_trans_ops {
void (*unref)(struct iwl_trans *trans);
#ifdef CONFIG_IWLWIFI_DEBUGFS
- u32 (*dump_data)(struct iwl_trans *trans, void *buf, u32 buflen);
+ struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans);
#endif
};
@@ -685,12 +688,12 @@ static inline void iwl_trans_unref(struct iwl_trans *trans)
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
-static inline u32 iwl_trans_dump_data(struct iwl_trans *trans,
- void *buf, u32 buflen)
+static inline struct iwl_trans_dump_data *
+iwl_trans_dump_data(struct iwl_trans *trans)
{
if (!trans->ops->dump_data)
- return 0;
- return trans->ops->dump_data(trans, buf, buflen);
+ return NULL;
+ return trans->ops->dump_data(trans);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index c30d7f64ec1e..a28235913c2c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
iwlmvm-y += scan.o time-event.o rs.o
-iwlmvm-y += power.o coex.o
+iwlmvm-y += power.o coex.o coex_legacy.o
iwlmvm-y += tt.o offloading.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index c8c3b38228f0..2291bbcaaeab 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -70,57 +70,58 @@
#include "mvm.h"
#include "iwl-debug.h"
-#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
- [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
- ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
-
-static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
- BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
- BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
- BT_COEX_PRIO_TBL_PRIO_LOW, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
- BT_COEX_PRIO_TBL_PRIO_LOW, 1),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
- BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
- BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
- BT_COEX_PRIO_TBL_DISABLED, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
- BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
- BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
- EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
- BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
- 0, 0, 0, 0, 0, 0,
-};
-
-#undef EVENT_PRIO_ANT
-
-#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
-#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
#define BT_ANTENNA_COUPLING_THRESHOLD (30)
-static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
-{
- return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, 0,
- sizeof(struct iwl_bt_coex_prio_tbl_cmd),
- &iwl_bt_prio_tbl);
-}
+const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX] = {
+ [BT_KILL_MSK_DEFAULT] = 0xfffffc00,
+ [BT_KILL_MSK_NEVER] = 0xffffffff,
+ [BT_KILL_MSK_ALWAYS] = 0,
+};
-const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
- [BT_KILL_MSK_DEFAULT] = 0xffff0000,
- [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
- [BT_KILL_MSK_REDUCED_TXPOW] = 0,
+const u8 iwl_bt_cts_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
+ {
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ },
+ {
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_NEVER,
+ },
+ {
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_NEVER,
+ },
+ {
+ BT_KILL_MSK_DEFAULT,
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_DEFAULT,
+ },
};
-const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
- [BT_KILL_MSK_DEFAULT] = 0xffff0000,
- [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
- [BT_KILL_MSK_REDUCED_TXPOW] = 0,
+const u8 iwl_bt_ack_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
+ {
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ },
+ {
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ },
+ {
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_ALWAYS,
+ },
+ {
+ BT_KILL_MSK_DEFAULT,
+ BT_KILL_MSK_ALWAYS,
+ BT_KILL_MSK_DEFAULT,
+ },
};
static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = {
@@ -519,6 +520,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
struct ieee80211_chanctx_conf *chanctx_conf;
enum iwl_bt_coex_lut_type ret;
u16 phy_ctx_id;
+ u32 primary_ch_phy_id, secondary_ch_phy_id;
/*
* Checking that we hold mvm->mutex is a good idea, but the rate
@@ -535,7 +537,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
if (!chanctx_conf ||
chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
rcu_read_unlock();
- return BT_COEX_LOOSE_LUT;
+ return BT_COEX_INVALID_LUT;
}
ret = BT_COEX_TX_DIS_LUT;
@@ -546,10 +548,13 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
}
phy_ctx_id = *((u16 *)chanctx_conf->drv_priv);
+ primary_ch_phy_id = le32_to_cpu(mvm->last_bt_ci_cmd.primary_ch_phy_id);
+ secondary_ch_phy_id =
+ le32_to_cpu(mvm->last_bt_ci_cmd.secondary_ch_phy_id);
- if (mvm->last_bt_ci_cmd.primary_ch_phy_id == phy_ctx_id)
+ if (primary_ch_phy_id == phy_ctx_id)
ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut);
- else if (mvm->last_bt_ci_cmd.secondary_ch_phy_id == phy_ctx_id)
+ else if (secondary_ch_phy_id == phy_ctx_id)
ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut);
/* else - default = TX TX disallowed */
@@ -567,59 +572,63 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
.dataflags = { IWL_HCMD_DFL_NOCOPY, },
};
int ret;
- u32 flags;
+ u32 mode;
- ret = iwl_send_bt_prio_tbl(mvm);
- if (ret)
- return ret;
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_send_bt_init_conf_old(mvm);
bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
if (!bt_cmd)
return -ENOMEM;
cmd.data[0] = bt_cmd;
- bt_cmd->max_kill = 5;
- bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
- bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
- bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
- bt_cmd->bt4_tx_rx_max_freq0 = 15;
- bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
- bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
-
- flags = iwlwifi_mod_params.bt_coex_active ?
- BT_COEX_NW : BT_COEX_DISABLE;
- bt_cmd->flags = cpu_to_le32(flags);
-
- bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE |
- BT_VALID_BT_PRIO_BOOST |
- BT_VALID_MAX_KILL |
- BT_VALID_3W_TMRS |
- BT_VALID_KILL_ACK |
- BT_VALID_KILL_CTS |
- BT_VALID_REDUCED_TX_POWER |
- BT_VALID_LUT |
- BT_VALID_WIFI_RX_SW_PRIO_BOOST |
- BT_VALID_WIFI_TX_SW_PRIO_BOOST |
- BT_VALID_ANT_ISOLATION |
- BT_VALID_ANT_ISOLATION_THRS |
- BT_VALID_TXTX_DELTA_FREQ_THRS |
- BT_VALID_TXRX_MAX_FREQ_0 |
- BT_VALID_SYNC_TO_SCO);
+ lockdep_assert_held(&mvm->mutex);
- if (IWL_MVM_BT_COEX_SYNC2SCO)
- bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) {
+ u32 mode;
- if (IWL_MVM_BT_COEX_CORUNNING) {
- bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
- BT_VALID_CORUN_LUT_40);
- bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
+ switch (mvm->bt_force_ant_mode) {
+ case BT_FORCE_ANT_BT:
+ mode = BT_COEX_BT;
+ break;
+ case BT_FORCE_ANT_WIFI:
+ mode = BT_COEX_WIFI;
+ break;
+ default:
+ WARN_ON(1);
+ mode = 0;
+ }
+
+ bt_cmd->mode = cpu_to_le32(mode);
+ goto send_cmd;
}
+ bt_cmd->max_kill = cpu_to_le32(5);
+ bt_cmd->bt4_antenna_isolation_thr =
+ cpu_to_le32(BT_ANTENNA_COUPLING_THRESHOLD);
+ bt_cmd->bt4_tx_tx_delta_freq_thr = cpu_to_le32(15);
+ bt_cmd->bt4_tx_rx_max_freq0 = cpu_to_le32(15);
+ bt_cmd->override_primary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
+ bt_cmd->override_secondary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
+
+ mode = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE;
+ bt_cmd->mode = cpu_to_le32(mode);
+
+ if (IWL_MVM_BT_COEX_SYNC2SCO)
+ bt_cmd->enabled_modules |=
+ cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
+
+ if (IWL_MVM_BT_COEX_CORUNNING)
+ bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
+
if (IWL_MVM_BT_COEX_MPLUT) {
- bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
- bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
+ bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_MPLUT_ENABLED);
+ bt_cmd->enabled_modules |=
+ cpu_to_le32(BT_COEX_MPLUT_BOOST_ENABLED);
}
+ bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_HIGH_BAND_RET);
+
if (mvm->cfg->bt_shared_single_ant)
memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
sizeof(iwl_single_shared_ant));
@@ -627,21 +636,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
sizeof(iwl_combined_lookup));
- /* Take first Co-running block LUT to get started */
- memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[0].lut20,
- sizeof(bt_cmd->bt4_corun_lut20));
- memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[0].lut20,
- sizeof(bt_cmd->bt4_corun_lut40));
-
- memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
+ memcpy(&bt_cmd->mplut_prio_boost, iwl_bt_prio_boost,
sizeof(iwl_bt_prio_boost));
- memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut,
+ memcpy(&bt_cmd->multiprio_lut, iwl_bt_mprio_lut,
sizeof(iwl_bt_mprio_lut));
- bt_cmd->kill_ack_msk =
- cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
- bt_cmd->kill_cts_msk =
- cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
+send_cmd:
memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
@@ -651,82 +651,54 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
return ret;
}
-static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
- bool reduced_tx_power)
+static int iwl_mvm_bt_udpate_sw_boost(struct iwl_mvm *mvm)
{
- enum iwl_bt_kill_msk bt_kill_msk;
- struct iwl_bt_coex_cmd *bt_cmd;
struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
- struct iwl_host_cmd cmd = {
- .id = BT_CONFIG,
- .data[0] = &bt_cmd,
- .len = { sizeof(*bt_cmd), },
- .dataflags = { IWL_HCMD_DFL_NOCOPY, },
- };
- int ret = 0;
+ u32 primary_lut = le32_to_cpu(notif->primary_ch_lut);
+ u32 secondary_lut = le32_to_cpu(notif->secondary_ch_lut);
+ u32 ag = le32_to_cpu(notif->bt_activity_grading);
+ struct iwl_bt_coex_sw_boost_update_cmd cmd = {};
+ u8 ack_kill_msk[NUM_PHY_CTX] = {};
+ u8 cts_kill_msk[NUM_PHY_CTX] = {};
+ int i;
lockdep_assert_held(&mvm->mutex);
- if (reduced_tx_power) {
- /* Reduced Tx power has precedence on the type of the profile */
- bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW;
- } else {
- /* Low latency BT profile is active: give higher prio to BT */
- if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
- BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
- BT_MBOX_MSG(notif, 3, SNIFF_STATE))
- bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
- else
- bt_kill_msk = BT_KILL_MSK_DEFAULT;
- }
+ ack_kill_msk[0] = iwl_bt_ack_kill_msk[ag][primary_lut];
+ cts_kill_msk[0] = iwl_bt_cts_kill_msk[ag][primary_lut];
- IWL_DEBUG_COEX(mvm,
- "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
- bt_kill_msk,
- BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
- BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
- BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
+ ack_kill_msk[1] = iwl_bt_ack_kill_msk[ag][secondary_lut];
+ cts_kill_msk[1] = iwl_bt_cts_kill_msk[ag][secondary_lut];
/* Don't send HCMD if there is no update */
- if (bt_kill_msk == mvm->bt_kill_msk)
+ if (!memcmp(ack_kill_msk, mvm->bt_ack_kill_msk, sizeof(ack_kill_msk)) ||
+ !memcmp(cts_kill_msk, mvm->bt_cts_kill_msk, sizeof(cts_kill_msk)))
return 0;
- mvm->bt_kill_msk = bt_kill_msk;
-
- bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
- if (!bt_cmd)
- return -ENOMEM;
- cmd.data[0] = bt_cmd;
- bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
-
- bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
- bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
- bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
- BT_VALID_KILL_ACK |
- BT_VALID_KILL_CTS);
+ memcpy(mvm->bt_ack_kill_msk, ack_kill_msk,
+ sizeof(mvm->bt_ack_kill_msk));
+ memcpy(mvm->bt_cts_kill_msk, cts_kill_msk,
+ sizeof(mvm->bt_cts_kill_msk));
- IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n",
- iwl_bt_ack_kill_msk[bt_kill_msk],
- iwl_bt_cts_kill_msk[bt_kill_msk]);
+ BUILD_BUG_ON(ARRAY_SIZE(ack_kill_msk) < ARRAY_SIZE(cmd.boost_values));
- ret = iwl_mvm_send_cmd(mvm, &cmd);
+ for (i = 0; i < ARRAY_SIZE(cmd.boost_values); i++) {
+ cmd.boost_values[i].kill_ack_msk =
+ cpu_to_le32(iwl_bt_ctl_kill_msk[ack_kill_msk[i]]);
+ cmd.boost_values[i].kill_cts_msk =
+ cpu_to_le32(iwl_bt_ctl_kill_msk[cts_kill_msk[i]]);
+ }
- kfree(bt_cmd);
- return ret;
+ return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_SW_BOOST, 0,
+ sizeof(cmd), &cmd);
}
static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
bool enable)
{
- struct iwl_bt_coex_cmd *bt_cmd;
- /* Send ASYNC since this can be sent from an atomic context */
- struct iwl_host_cmd cmd = {
- .id = BT_CONFIG,
- .len = { sizeof(*bt_cmd), },
- .dataflags = { IWL_HCMD_DFL_NOCOPY, },
- .flags = CMD_ASYNC,
- };
+ struct iwl_bt_coex_reduced_txp_update_cmd cmd = {};
struct iwl_mvm_sta *mvmsta;
+ u32 value;
int ret;
mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
@@ -737,35 +709,26 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
if (mvmsta->bt_reduced_txpower == enable)
return 0;
- bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC);
- if (!bt_cmd)
- return -ENOMEM;
- cmd.data[0] = bt_cmd;
- bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
-
- bt_cmd->valid_bit_msk =
- cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER);
- bt_cmd->bt_reduced_tx_power = sta_id;
+ value = mvmsta->sta_id;
if (enable)
- bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
+ value |= BT_REDUCED_TX_POWER_BIT;
IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
enable ? "en" : "dis", sta_id);
+ cmd.reduced_txp = cpu_to_le32(value);
mvmsta->bt_reduced_txpower = enable;
- ret = iwl_mvm_send_cmd(mvm, &cmd);
+ ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_REDUCED_TXP, CMD_ASYNC,
+ sizeof(cmd), &cmd);
- kfree(bt_cmd);
return ret;
}
struct iwl_bt_iterator_data {
struct iwl_bt_coex_profile_notif *notif;
struct iwl_mvm *mvm;
- u32 num_bss_ifaces;
- bool reduced_tx_power;
struct ieee80211_chanctx_conf *primary;
struct ieee80211_chanctx_conf *secondary;
bool primary_ll;
@@ -780,9 +743,9 @@ void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
mvmvif->bf_data.last_bt_coex_event = rssi;
mvmvif->bf_data.bt_coex_max_thold =
- enable ? BT_ENABLE_REDUCED_TXPOWER_THRESHOLD : 0;
+ enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0;
mvmvif->bf_data.bt_coex_min_thold =
- enable ? BT_DISABLE_REDUCED_TXPOWER_THRESHOLD : 0;
+ enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0;
}
/* must be called under rcu_read_lock */
@@ -801,22 +764,12 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
switch (vif->type) {
case NL80211_IFTYPE_STATION:
- /* Count BSSes vifs */
- data->num_bss_ifaces++;
/* default smps_mode for BSS / P2P client is AUTOMATIC */
smps_mode = IEEE80211_SMPS_AUTOMATIC;
break;
case NL80211_IFTYPE_AP:
- /* default smps_mode for AP / GO is OFF */
- smps_mode = IEEE80211_SMPS_OFF;
- if (!mvmvif->ap_ibss_active) {
- iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
- smps_mode);
+ if (!mvmvif->ap_ibss_active)
return;
- }
-
- /* the Ack / Cts kill mask must be default if AP / GO */
- data->reduced_tx_power = false;
break;
default:
return;
@@ -827,11 +780,10 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
/* If channel context is invalid or not on 2.4GHz .. */
if ((!chanctx_conf ||
chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ)) {
- /* ... relax constraints and disable rssi events */
- iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
- smps_mode);
- data->reduced_tx_power = false;
if (vif->type == NL80211_IFTYPE_STATION) {
+ /* ... relax constraints and disable rssi events */
+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
+ smps_mode);
iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
false);
iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
@@ -843,20 +795,23 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
if (bt_activity_grading >= BT_HIGH_TRAFFIC)
smps_mode = IEEE80211_SMPS_STATIC;
else if (bt_activity_grading >= BT_LOW_TRAFFIC)
- smps_mode = vif->type == NL80211_IFTYPE_AP ?
- IEEE80211_SMPS_OFF :
- IEEE80211_SMPS_DYNAMIC;
+ smps_mode = IEEE80211_SMPS_DYNAMIC;
/* relax SMPS contraints for next association */
if (!vif->bss_conf.assoc)
smps_mode = IEEE80211_SMPS_AUTOMATIC;
+ if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
+ mvmvif->phy_ctxt->id))
+ smps_mode = IEEE80211_SMPS_AUTOMATIC;
+
IWL_DEBUG_COEX(data->mvm,
- "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n",
- mvmvif->id, data->notif->bt_status, bt_activity_grading,
- smps_mode);
+ "mac %d: bt_activity_grading %d smps_req %d\n",
+ mvmvif->id, bt_activity_grading, smps_mode);
- iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
+ smps_mode);
/* low latency is always primary */
if (iwl_mvm_vif_low_latency(mvmvif)) {
@@ -906,8 +861,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
*/
if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc ||
- !data->notif->bt_status) {
- data->reduced_tx_power = false;
+ le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) {
iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
return;
@@ -919,26 +873,12 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
/* if the RSSI isn't valid, fake it is very low */
if (!ave_rssi)
ave_rssi = -100;
- if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) {
+ if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
-
- /*
- * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the
- * BSS / P2P clients have rssi above threshold.
- * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before
- * the iteration, if one interface's rssi isn't good enough,
- * bt_kill_msk will be set to default values.
- */
- } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) {
+ } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
-
- /*
- * One interface hasn't rssi above threshold, bt_kill_msk must
- * be set to default values.
- */
- data->reduced_tx_power = false;
}
/* Begin to monitor the RSSI: it may influence the reduced Tx power */
@@ -950,11 +890,14 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
struct iwl_bt_iterator_data data = {
.mvm = mvm,
.notif = &mvm->last_bt_notif,
- .reduced_tx_power = true,
};
struct iwl_bt_coex_ci_cmd cmd = {};
u8 ci_bw_idx;
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return;
+
rcu_read_lock();
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
@@ -969,9 +912,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
if (chan->def.width < NL80211_CHAN_WIDTH_40) {
ci_bw_idx = 0;
- cmd.co_run_bw_primary = 0;
} else {
- cmd.co_run_bw_primary = 1;
if (chan->def.center_freq1 >
chan->def.chan->center_freq)
ci_bw_idx = 2;
@@ -981,7 +922,8 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
cmd.bt_primary_ci =
iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
- cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv);
+ cmd.primary_ch_phy_id =
+ cpu_to_le32(*((u16 *)data.primary->drv_priv));
}
if (data.secondary) {
@@ -993,9 +935,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
if (chan->def.width < NL80211_CHAN_WIDTH_40) {
ci_bw_idx = 0;
- cmd.co_run_bw_secondary = 0;
} else {
- cmd.co_run_bw_secondary = 1;
if (chan->def.center_freq1 >
chan->def.chan->center_freq)
ci_bw_idx = 2;
@@ -1005,7 +945,8 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
cmd.bt_secondary_ci =
iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
- cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv);
+ cmd.secondary_ch_phy_id =
+ cpu_to_le32(*((u16 *)data.secondary->drv_priv));
}
rcu_read_unlock();
@@ -1018,14 +959,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd));
}
- /*
- * If there are no BSS / P2P client interfaces, reduced Tx Power is
- * irrelevant since it is based on the RSSI coming from the beacon.
- * Use BT_KILL_MSK_DEFAULT in that case.
- */
- data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
-
- if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
+ if (iwl_mvm_bt_udpate_sw_boost(mvm))
IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
}
@@ -1036,11 +970,10 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_rx_bt_coex_notif_old(mvm, rxb, dev_cmd);
IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
- IWL_DEBUG_COEX(mvm, "\tBT status: %s\n",
- notif->bt_status ? "ON" : "OFF");
- IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
le32_to_cpu(notif->primary_ch_lut));
@@ -1048,8 +981,6 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
le32_to_cpu(notif->secondary_ch_lut));
IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
le32_to_cpu(notif->bt_activity_grading));
- IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
- notif->bt_agg_traffic_load);
/* remember this notification for future use: rssi fluctuations */
memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
@@ -1097,16 +1028,6 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
return;
mvmsta = iwl_mvm_sta_from_mac80211(sta);
-
- data->num_bss_ifaces++;
-
- /*
- * This interface doesn't support reduced Tx power (because of low
- * RSSI probably), then set bt_kill_msk to default values.
- */
- if (!mvmsta->bt_reduced_txpower)
- data->reduced_tx_power = false;
- /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */
}
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -1115,12 +1036,20 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
struct iwl_bt_iterator_data data = {
.mvm = mvm,
- .reduced_tx_power = true,
};
int ret;
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
+ iwl_mvm_bt_rssi_event_old(mvm, vif, rssi_event);
+ return;
+ }
+
lockdep_assert_held(&mvm->mutex);
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return;
+
/*
* Rssi update while not associated - can happen since the statistics
* are handled asynchronously
@@ -1129,7 +1058,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return;
/* No BT - reports should be disabled */
- if (!mvm->last_bt_notif.bt_status)
+ if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF)
return;
IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
@@ -1153,14 +1082,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_bt_rssi_iterator, &data);
- /*
- * If there are no BSS / P2P client interfaces, reduced Tx Power is
- * irrelevant since it is based on the RSSI coming from the beacon.
- * Use BT_KILL_MSK_DEFAULT in that case.
- */
- data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
-
- if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
+ if (iwl_mvm_bt_udpate_sw_boost(mvm))
IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
}
@@ -1171,15 +1093,23 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct ieee80211_sta *sta)
{
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+ struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
enum iwl_bt_coex_lut_type lut_type;
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_coex_agg_time_limit_old(mvm, sta);
+
+ if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
+ return LINK_QUAL_AGG_TIME_LIMIT_DEF;
+
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
BT_HIGH_TRAFFIC)
return LINK_QUAL_AGG_TIME_LIMIT_DEF;
lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
- if (lut_type == BT_COEX_LOOSE_LUT)
+ if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT)
return LINK_QUAL_AGG_TIME_LIMIT_DEF;
/* tight coex, high bt traffic, reduce AGG time limit */
@@ -1190,18 +1120,37 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct ieee80211_sta *sta)
{
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+ struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
+ enum iwl_bt_coex_lut_type lut_type;
+
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_bt_coex_is_mimo_allowed_old(mvm, sta);
+
+ if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
+ return true;
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
BT_HIGH_TRAFFIC)
return true;
/*
- * In Tight, BT can't Rx while we Tx, so use both antennas since BT is
- * already killed.
- * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we
- * Tx.
+ * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
+ * since BT is already killed.
+ * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
+ * we Tx.
+ * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO.
*/
- return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT;
+ lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
+ return lut_type != BT_COEX_LOOSE_LUT;
+}
+
+bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm)
+{
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm);
+
+ return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF;
}
bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
@@ -1209,6 +1158,9 @@ bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
{
u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_bt_coex_is_tpc_allowed_old(mvm, band);
+
if (band != IEEE80211_BAND_2GHZ)
return false;
@@ -1249,6 +1201,11 @@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
{
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
+ iwl_mvm_bt_coex_vif_change_old(mvm);
+ return;
+ }
+
iwl_mvm_bt_coex_notif_handle(mvm);
}
@@ -1258,22 +1215,22 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u32 ant_isolation = le32_to_cpup((void *)pkt->data);
+ struct iwl_bt_coex_corun_lut_update_cmd cmd = {};
u8 __maybe_unused lower_bound, upper_bound;
- int ret;
u8 lut;
- struct iwl_bt_coex_cmd *bt_cmd;
- struct iwl_host_cmd cmd = {
- .id = BT_CONFIG,
- .len = { sizeof(*bt_cmd), },
- .dataflags = { IWL_HCMD_DFL_NOCOPY, },
- };
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
+ return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd);
if (!IWL_MVM_BT_COEX_CORUNNING)
return 0;
lockdep_assert_held(&mvm->mutex);
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return 0;
+
if (ant_isolation == mvm->last_ant_isol)
return 0;
@@ -1298,25 +1255,13 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
mvm->last_corun_lut = lut;
- bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
- if (!bt_cmd)
- return 0;
- cmd.data[0] = bt_cmd;
-
- bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
- bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
- BT_VALID_CORUN_LUT_20 |
- BT_VALID_CORUN_LUT_40);
-
/* For the moment, use the same LUT for 20GHz and 40GHz */
- memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[lut].lut20,
- sizeof(bt_cmd->bt4_corun_lut20));
+ memcpy(&cmd.corun_lut20, antenna_coupling_ranges[lut].lut20,
+ sizeof(cmd.corun_lut20));
- memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
- sizeof(bt_cmd->bt4_corun_lut40));
+ memcpy(&cmd.corun_lut40, antenna_coupling_ranges[lut].lut20,
+ sizeof(cmd.corun_lut40));
- ret = iwl_mvm_send_cmd(mvm, &cmd);
-
- kfree(bt_cmd);
- return ret;
+ return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_CORUN_LUT, 0,
+ sizeof(cmd), &cmd);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
new file mode 100644
index 000000000000..a3be33359927
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -0,0 +1,1257 @@
+/******************************************************************************
+ *
+ * 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
+ *
+ * Copyright(c) 2013 - 2014 Intel 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.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name 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 <linux/ieee80211.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+
+#include "fw-api-coex.h"
+#include "iwl-modparams.h"
+#include "mvm.h"
+#include "iwl-debug.h"
+
+#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
+ [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
+ ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
+
+static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
+ BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
+ BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
+ BT_COEX_PRIO_TBL_PRIO_LOW, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
+ BT_COEX_PRIO_TBL_PRIO_LOW, 1),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
+ BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
+ BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
+ BT_COEX_PRIO_TBL_DISABLED, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
+ BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
+ BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
+ EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
+ BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
+ 0, 0, 0, 0, 0, 0,
+};
+
+#undef EVENT_PRIO_ANT
+
+#define BT_ANTENNA_COUPLING_THRESHOLD (30)
+
+static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
+{
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return 0;
+
+ return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, 0,
+ sizeof(struct iwl_bt_coex_prio_tbl_cmd),
+ &iwl_bt_prio_tbl);
+}
+
+static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = {
+ cpu_to_le32(0xf0f0f0f0), /* 50% */
+ cpu_to_le32(0xc0c0c0c0), /* 25% */
+ cpu_to_le32(0xfcfcfcfc), /* 75% */
+ cpu_to_le32(0xfefefefe), /* 87.5% */
+};
+
+static const __le32 iwl_single_shared_ant[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
+ {
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ },
+ {
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ },
+ {
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x40000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x44000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ },
+};
+
+static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
+ {
+ /* Tight */
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaeaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xcc00ff28),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xcc00aaaa),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0x00004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0005000),
+ },
+ {
+ /* Loose */
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xcc00ff28),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xcc00aaaa),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0005000),
+ },
+ {
+ /* Tx Tx disabled */
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xeeaaaaaa),
+ cpu_to_le32(0xaaaaaaaa),
+ cpu_to_le32(0xcc00ff28),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xcc00aaaa),
+ cpu_to_le32(0x0000aaaa),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xc0004000),
+ cpu_to_le32(0xf0005000),
+ cpu_to_le32(0xf0005000),
+ },
+};
+
+/* 20MHz / 40MHz below / 40Mhz above*/
+static const __le64 iwl_ci_mask[][3] = {
+ /* dummy entry for channel 0 */
+ {cpu_to_le64(0), cpu_to_le64(0), cpu_to_le64(0)},
+ {
+ cpu_to_le64(0x0000001FFFULL),
+ cpu_to_le64(0x0ULL),
+ cpu_to_le64(0x00007FFFFFULL),
+ },
+ {
+ cpu_to_le64(0x000000FFFFULL),
+ cpu_to_le64(0x0ULL),
+ cpu_to_le64(0x0003FFFFFFULL),
+ },
+ {
+ cpu_to_le64(0x000003FFFCULL),
+ cpu_to_le64(0x0ULL),
+ cpu_to_le64(0x000FFFFFFCULL),
+ },
+ {
+ cpu_to_le64(0x00001FFFE0ULL),
+ cpu_to_le64(0x0ULL),
+ cpu_to_le64(0x007FFFFFE0ULL),
+ },
+ {
+ cpu_to_le64(0x00007FFF80ULL),
+ cpu_to_le64(0x00007FFFFFULL),
+ cpu_to_le64(0x01FFFFFF80ULL),
+ },
+ {
+ cpu_to_le64(0x0003FFFC00ULL),
+ cpu_to_le64(0x0003FFFFFFULL),
+ cpu_to_le64(0x0FFFFFFC00ULL),
+ },
+ {
+ cpu_to_le64(0x000FFFF000ULL),
+ cpu_to_le64(0x000FFFFFFCULL),
+ cpu_to_le64(0x3FFFFFF000ULL),
+ },
+ {
+ cpu_to_le64(0x007FFF8000ULL),
+ cpu_to_le64(0x007FFFFFE0ULL),
+ cpu_to_le64(0xFFFFFF8000ULL),
+ },
+ {
+ cpu_to_le64(0x01FFFE0000ULL),
+ cpu_to_le64(0x01FFFFFF80ULL),
+ cpu_to_le64(0xFFFFFE0000ULL),
+ },
+ {
+ cpu_to_le64(0x0FFFF00000ULL),
+ cpu_to_le64(0x0FFFFFFC00ULL),
+ cpu_to_le64(0x0ULL),
+ },
+ {
+ cpu_to_le64(0x3FFFC00000ULL),
+ cpu_to_le64(0x3FFFFFF000ULL),
+ cpu_to_le64(0x0)
+ },
+ {
+ cpu_to_le64(0xFFFE000000ULL),
+ cpu_to_le64(0xFFFFFF8000ULL),
+ cpu_to_le64(0x0)
+ },
+ {
+ cpu_to_le64(0xFFF8000000ULL),
+ cpu_to_le64(0xFFFFFE0000ULL),
+ cpu_to_le64(0x0)
+ },
+ {
+ cpu_to_le64(0xFFC0000000ULL),
+ cpu_to_le64(0x0ULL),
+ cpu_to_le64(0x0ULL)
+ },
+};
+
+static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
+ cpu_to_le32(0x28412201),
+ cpu_to_le32(0x11118451),
+};
+
+struct corunning_block_luts {
+ u8 range;
+ __le32 lut20[BT_COEX_CORUN_LUT_SIZE];
+};
+
+/*
+ * Ranges for the antenna coupling calibration / co-running block LUT:
+ * LUT0: [ 0, 12[
+ * LUT1: [12, 20[
+ * LUT2: [20, 21[
+ * LUT3: [21, 23[
+ * LUT4: [23, 27[
+ * LUT5: [27, 30[
+ * LUT6: [30, 32[
+ * LUT7: [32, 33[
+ * LUT8: [33, - [
+ */
+static const struct corunning_block_luts antenna_coupling_ranges[] = {
+ {
+ .range = 0,
+ .lut20 = {
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 12,
+ .lut20 = {
+ cpu_to_le32(0x00000001), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 20,
+ .lut20 = {
+ cpu_to_le32(0x00000002), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 21,
+ .lut20 = {
+ cpu_to_le32(0x00000003), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 23,
+ .lut20 = {
+ cpu_to_le32(0x00000004), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 27,
+ .lut20 = {
+ cpu_to_le32(0x00000005), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 30,
+ .lut20 = {
+ cpu_to_le32(0x00000006), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 32,
+ .lut20 = {
+ cpu_to_le32(0x00000007), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+ {
+ .range = 33,
+ .lut20 = {
+ cpu_to_le32(0x00000008), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
+ },
+ },
+};
+
+static enum iwl_bt_coex_lut_type
+iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
+{
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ enum iwl_bt_coex_lut_type ret;
+ u16 phy_ctx_id;
+
+ /*
+ * Checking that we hold mvm->mutex is a good idea, but the rate
+ * control can't acquire the mutex since it runs in Tx path.
+ * So this is racy in that case, but in the worst case, the AMPDU
+ * size limit will be wrong for a short time which is not a big
+ * issue.
+ */
+
+ rcu_read_lock();
+
+ chanctx_conf = rcu_dereference(vif->chanctx_conf);
+
+ if (!chanctx_conf ||
+ chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
+ rcu_read_unlock();
+ return BT_COEX_INVALID_LUT;
+ }
+
+ ret = BT_COEX_TX_DIS_LUT;
+
+ if (mvm->cfg->bt_shared_single_ant) {
+ rcu_read_unlock();
+ return ret;
+ }
+
+ phy_ctx_id = *((u16 *)chanctx_conf->drv_priv);
+
+ if (mvm->last_bt_ci_cmd_old.primary_ch_phy_id == phy_ctx_id)
+ ret = le32_to_cpu(mvm->last_bt_notif_old.primary_ch_lut);
+ else if (mvm->last_bt_ci_cmd_old.secondary_ch_phy_id == phy_ctx_id)
+ ret = le32_to_cpu(mvm->last_bt_notif_old.secondary_ch_lut);
+ /* else - default = TX TX disallowed */
+
+ rcu_read_unlock();
+
+ return ret;
+}
+
+int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
+{
+ struct iwl_bt_coex_cmd_old *bt_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = BT_CONFIG,
+ .len = { sizeof(*bt_cmd), },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ };
+ int ret;
+ u32 flags;
+
+ ret = iwl_send_bt_prio_tbl(mvm);
+ if (ret)
+ return ret;
+
+ bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
+ if (!bt_cmd)
+ return -ENOMEM;
+ cmd.data[0] = bt_cmd;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) {
+ switch (mvm->bt_force_ant_mode) {
+ case BT_FORCE_ANT_AUTO:
+ flags = BT_COEX_AUTO_OLD;
+ break;
+ case BT_FORCE_ANT_BT:
+ flags = BT_COEX_BT_OLD;
+ break;
+ case BT_FORCE_ANT_WIFI:
+ flags = BT_COEX_WIFI_OLD;
+ break;
+ default:
+ WARN_ON(1);
+ flags = 0;
+ }
+
+ bt_cmd->flags = cpu_to_le32(flags);
+ bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE);
+ goto send_cmd;
+ }
+
+ bt_cmd->max_kill = 5;
+ bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
+ bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
+ bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
+ bt_cmd->bt4_tx_rx_max_freq0 = 15;
+ bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
+ bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
+
+ flags = iwlwifi_mod_params.bt_coex_active ?
+ BT_COEX_NW_OLD : BT_COEX_DISABLE_OLD;
+ bt_cmd->flags = cpu_to_le32(flags);
+
+ bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE |
+ BT_VALID_BT_PRIO_BOOST |
+ BT_VALID_MAX_KILL |
+ BT_VALID_3W_TMRS |
+ BT_VALID_KILL_ACK |
+ BT_VALID_KILL_CTS |
+ BT_VALID_REDUCED_TX_POWER |
+ BT_VALID_LUT |
+ BT_VALID_WIFI_RX_SW_PRIO_BOOST |
+ BT_VALID_WIFI_TX_SW_PRIO_BOOST |
+ BT_VALID_ANT_ISOLATION |
+ BT_VALID_ANT_ISOLATION_THRS |
+ BT_VALID_TXTX_DELTA_FREQ_THRS |
+ BT_VALID_TXRX_MAX_FREQ_0 |
+ BT_VALID_SYNC_TO_SCO);
+
+ if (IWL_MVM_BT_COEX_SYNC2SCO)
+ bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
+
+ if (IWL_MVM_BT_COEX_CORUNNING) {
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
+ BT_VALID_CORUN_LUT_40);
+ bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
+ }
+
+ if (IWL_MVM_BT_COEX_MPLUT) {
+ bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
+ }
+
+ if (mvm->cfg->bt_shared_single_ant)
+ memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
+ sizeof(iwl_single_shared_ant));
+ else
+ memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
+ sizeof(iwl_combined_lookup));
+
+ /* Take first Co-running block LUT to get started */
+ memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[0].lut20,
+ sizeof(bt_cmd->bt4_corun_lut20));
+ memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[0].lut20,
+ sizeof(bt_cmd->bt4_corun_lut40));
+
+ memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
+ sizeof(iwl_bt_prio_boost));
+ memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut,
+ sizeof(iwl_bt_mprio_lut));
+
+send_cmd:
+ memset(&mvm->last_bt_notif_old, 0, sizeof(mvm->last_bt_notif_old));
+ memset(&mvm->last_bt_ci_cmd_old, 0, sizeof(mvm->last_bt_ci_cmd_old));
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+
+ kfree(bt_cmd);
+ return ret;
+}
+
+static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm)
+{
+ struct iwl_bt_coex_profile_notif_old *notif = &mvm->last_bt_notif_old;
+ u32 primary_lut = le32_to_cpu(notif->primary_ch_lut);
+ u32 ag = le32_to_cpu(notif->bt_activity_grading);
+ struct iwl_bt_coex_cmd_old *bt_cmd;
+ u8 ack_kill_msk, cts_kill_msk;
+ struct iwl_host_cmd cmd = {
+ .id = BT_CONFIG,
+ .data[0] = &bt_cmd,
+ .len = { sizeof(*bt_cmd), },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ };
+ int ret = 0;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ ack_kill_msk = iwl_bt_ack_kill_msk[ag][primary_lut];
+ cts_kill_msk = iwl_bt_cts_kill_msk[ag][primary_lut];
+
+ if (mvm->bt_ack_kill_msk[0] == ack_kill_msk &&
+ mvm->bt_cts_kill_msk[0] == cts_kill_msk)
+ return 0;
+
+ mvm->bt_ack_kill_msk[0] = ack_kill_msk;
+ mvm->bt_cts_kill_msk[0] = cts_kill_msk;
+
+ bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
+ if (!bt_cmd)
+ return -ENOMEM;
+ cmd.data[0] = bt_cmd;
+ bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
+
+ bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ctl_kill_msk[ack_kill_msk]);
+ bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_ctl_kill_msk[cts_kill_msk]);
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
+ BT_VALID_KILL_ACK |
+ BT_VALID_KILL_CTS);
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+
+ kfree(bt_cmd);
+ return ret;
+}
+
+static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
+ bool enable)
+{
+ struct iwl_bt_coex_cmd_old *bt_cmd;
+ /* Send ASYNC since this can be sent from an atomic context */
+ struct iwl_host_cmd cmd = {
+ .id = BT_CONFIG,
+ .len = { sizeof(*bt_cmd), },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ .flags = CMD_ASYNC,
+ };
+ struct iwl_mvm_sta *mvmsta;
+ int ret;
+
+ mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
+ if (!mvmsta)
+ return 0;
+
+ /* nothing to do */
+ if (mvmsta->bt_reduced_txpower == enable)
+ return 0;
+
+ bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC);
+ if (!bt_cmd)
+ return -ENOMEM;
+ cmd.data[0] = bt_cmd;
+ bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
+
+ bt_cmd->valid_bit_msk =
+ cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER);
+ bt_cmd->bt_reduced_tx_power = sta_id;
+
+ if (enable)
+ bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
+
+ IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
+ enable ? "en" : "dis", sta_id);
+
+ mvmsta->bt_reduced_txpower = enable;
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+
+ kfree(bt_cmd);
+ return ret;
+}
+
+struct iwl_bt_iterator_data {
+ struct iwl_bt_coex_profile_notif_old *notif;
+ struct iwl_mvm *mvm;
+ struct ieee80211_chanctx_conf *primary;
+ struct ieee80211_chanctx_conf *secondary;
+ bool primary_ll;
+};
+
+static inline
+void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ bool enable, int rssi)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ mvmvif->bf_data.last_bt_coex_event = rssi;
+ mvmvif->bf_data.bt_coex_max_thold =
+ enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0;
+ mvmvif->bf_data.bt_coex_min_thold =
+ enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0;
+}
+
+/* must be called under rcu_read_lock */
+static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_bt_iterator_data *data = _data;
+ struct iwl_mvm *mvm = data->mvm;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ enum ieee80211_smps_mode smps_mode;
+ u32 bt_activity_grading;
+ int ave_rssi;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ /* default smps_mode for BSS / P2P client is AUTOMATIC */
+ smps_mode = IEEE80211_SMPS_AUTOMATIC;
+ break;
+ case NL80211_IFTYPE_AP:
+ if (!mvmvif->ap_ibss_active)
+ return;
+ break;
+ default:
+ return;
+ }
+
+ chanctx_conf = rcu_dereference(vif->chanctx_conf);
+
+ /* If channel context is invalid or not on 2.4GHz .. */
+ if ((!chanctx_conf ||
+ chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ)) {
+ if (vif->type == NL80211_IFTYPE_STATION) {
+ /* ... relax constraints and disable rssi events */
+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
+ smps_mode);
+ iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
+ false);
+ iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
+ }
+ return;
+ }
+
+ bt_activity_grading = le32_to_cpu(data->notif->bt_activity_grading);
+ if (bt_activity_grading >= BT_HIGH_TRAFFIC)
+ smps_mode = IEEE80211_SMPS_STATIC;
+ else if (bt_activity_grading >= BT_LOW_TRAFFIC)
+ smps_mode = vif->type == NL80211_IFTYPE_AP ?
+ IEEE80211_SMPS_OFF :
+ IEEE80211_SMPS_DYNAMIC;
+
+ /* relax SMPS contraints for next association */
+ if (!vif->bss_conf.assoc)
+ smps_mode = IEEE80211_SMPS_AUTOMATIC;
+
+ IWL_DEBUG_COEX(data->mvm,
+ "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n",
+ mvmvif->id, data->notif->bt_status, bt_activity_grading,
+ smps_mode);
+
+ if (vif->type == NL80211_IFTYPE_STATION)
+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
+ smps_mode);
+
+ /* low latency is always primary */
+ if (iwl_mvm_vif_low_latency(mvmvif)) {
+ data->primary_ll = true;
+
+ data->secondary = data->primary;
+ data->primary = chanctx_conf;
+ }
+
+ if (vif->type == NL80211_IFTYPE_AP) {
+ if (!mvmvif->ap_ibss_active)
+ return;
+
+ if (chanctx_conf == data->primary)
+ return;
+
+ if (!data->primary_ll) {
+ /*
+ * downgrade the current primary no matter what its
+ * type is.
+ */
+ data->secondary = data->primary;
+ data->primary = chanctx_conf;
+ } else {
+ /* there is low latency vif - we will be secondary */
+ data->secondary = chanctx_conf;
+ }
+ return;
+ }
+
+ /*
+ * STA / P2P Client, try to be primary if first vif. If we are in low
+ * latency mode, we are already in primary and just don't do much
+ */
+ if (!data->primary || data->primary == chanctx_conf)
+ data->primary = chanctx_conf;
+ else if (!data->secondary)
+ /* if secondary is not NULL, it might be a GO */
+ data->secondary = chanctx_conf;
+
+ /*
+ * don't reduce the Tx power if one of these is true:
+ * we are in LOOSE
+ * single share antenna product
+ * BT is active
+ * we are associated
+ */
+ if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
+ mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc ||
+ !data->notif->bt_status) {
+ iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
+ iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
+ return;
+ }
+
+ /* try to get the avg rssi from fw */
+ ave_rssi = mvmvif->bf_data.ave_beacon_signal;
+
+ /* if the RSSI isn't valid, fake it is very low */
+ if (!ave_rssi)
+ ave_rssi = -100;
+ if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
+ if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
+ IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
+ } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
+ if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
+ IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
+ }
+
+ /* Begin to monitor the RSSI: it may influence the reduced Tx power */
+ iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, true, ave_rssi);
+}
+
+static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
+{
+ struct iwl_bt_iterator_data data = {
+ .mvm = mvm,
+ .notif = &mvm->last_bt_notif_old,
+ };
+ struct iwl_bt_coex_ci_cmd_old cmd = {};
+ u8 ci_bw_idx;
+
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return;
+
+ rcu_read_lock();
+ ieee80211_iterate_active_interfaces_atomic(
+ mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+ iwl_mvm_bt_notif_iterator, &data);
+
+ if (data.primary) {
+ struct ieee80211_chanctx_conf *chan = data.primary;
+
+ if (WARN_ON(!chan->def.chan)) {
+ rcu_read_unlock();
+ return;
+ }
+
+ if (chan->def.width < NL80211_CHAN_WIDTH_40) {
+ ci_bw_idx = 0;
+ cmd.co_run_bw_primary = 0;
+ } else {
+ cmd.co_run_bw_primary = 1;
+ if (chan->def.center_freq1 >
+ chan->def.chan->center_freq)
+ ci_bw_idx = 2;
+ else
+ ci_bw_idx = 1;
+ }
+
+ cmd.bt_primary_ci =
+ iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
+ cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv);
+ }
+
+ if (data.secondary) {
+ struct ieee80211_chanctx_conf *chan = data.secondary;
+
+ if (WARN_ON(!data.secondary->def.chan)) {
+ rcu_read_unlock();
+ return;
+ }
+
+ if (chan->def.width < NL80211_CHAN_WIDTH_40) {
+ ci_bw_idx = 0;
+ cmd.co_run_bw_secondary = 0;
+ } else {
+ cmd.co_run_bw_secondary = 1;
+ if (chan->def.center_freq1 >
+ chan->def.chan->center_freq)
+ ci_bw_idx = 2;
+ else
+ ci_bw_idx = 1;
+ }
+
+ cmd.bt_secondary_ci =
+ iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
+ cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv);
+ }
+
+ rcu_read_unlock();
+
+ /* Don't spam the fw with the same command over and over */
+ if (memcmp(&cmd, &mvm->last_bt_ci_cmd_old, sizeof(cmd))) {
+ if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_CI, 0,
+ sizeof(cmd), &cmd))
+ IWL_ERR(mvm, "Failed to send BT_CI cmd\n");
+ memcpy(&mvm->last_bt_ci_cmd_old, &cmd, sizeof(cmd));
+ }
+
+ if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm))
+ IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
+}
+
+int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *dev_cmd)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_bt_coex_profile_notif_old *notif = (void *)pkt->data;
+
+ IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
+ IWL_DEBUG_COEX(mvm, "\tBT status: %s\n",
+ notif->bt_status ? "ON" : "OFF");
+ IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
+ IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
+ IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
+ le32_to_cpu(notif->primary_ch_lut));
+ IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
+ le32_to_cpu(notif->secondary_ch_lut));
+ IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
+ le32_to_cpu(notif->bt_activity_grading));
+ IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
+ notif->bt_agg_traffic_load);
+
+ /* remember this notification for future use: rssi fluctuations */
+ memcpy(&mvm->last_bt_notif_old, notif, sizeof(mvm->last_bt_notif_old));
+
+ iwl_mvm_bt_coex_notif_handle(mvm);
+
+ /*
+ * This is an async handler for a notification, returning anything other
+ * than 0 doesn't make sense even if HCMD failed.
+ */
+ return 0;
+}
+
+static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
+ struct iwl_bt_iterator_data *data = _data;
+ struct iwl_mvm *mvm = data->mvm;
+
+ struct ieee80211_sta *sta;
+ struct iwl_mvm_sta *mvmsta;
+
+ struct ieee80211_chanctx_conf *chanctx_conf;
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(vif->chanctx_conf);
+ /* If channel context is invalid or not on 2.4GHz - don't count it */
+ if (!chanctx_conf ||
+ chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
+ rcu_read_unlock();
+ return;
+ }
+ rcu_read_unlock();
+
+ if (vif->type != NL80211_IFTYPE_STATION ||
+ mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
+ return;
+
+ sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
+ lockdep_is_held(&mvm->mutex));
+
+ /* This can happen if the station has been removed right now */
+ if (IS_ERR_OR_NULL(sta))
+ return;
+
+ mvmsta = iwl_mvm_sta_from_mac80211(sta);
+}
+
+void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum ieee80211_rssi_event rssi_event)
+{
+ struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
+ struct iwl_bt_iterator_data data = {
+ .mvm = mvm,
+ };
+ int ret;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return;
+
+ /*
+ * Rssi update while not associated - can happen since the statistics
+ * are handled asynchronously
+ */
+ if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
+ return;
+
+ /* No BT - reports should be disabled */
+ if (!mvm->last_bt_notif_old.bt_status)
+ return;
+
+ IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
+ rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW");
+
+ /*
+ * Check if rssi is good enough for reduced Tx power, but not in loose
+ * scheme.
+ */
+ if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant ||
+ iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT)
+ ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
+ false);
+ else
+ ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
+
+ if (ret)
+ IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
+
+ ieee80211_iterate_active_interfaces_atomic(
+ mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+ iwl_mvm_bt_rssi_iterator, &data);
+
+ if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm))
+ IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
+}
+
+#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
+#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
+
+u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta)
+{
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ enum iwl_bt_coex_lut_type lut_type;
+
+ if (le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading) <
+ BT_HIGH_TRAFFIC)
+ return LINK_QUAL_AGG_TIME_LIMIT_DEF;
+
+ if (mvm->last_bt_notif_old.ttc_enabled)
+ return LINK_QUAL_AGG_TIME_LIMIT_DEF;
+
+ lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
+
+ if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT)
+ return LINK_QUAL_AGG_TIME_LIMIT_DEF;
+
+ /* tight coex, high bt traffic, reduce AGG time limit */
+ return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT;
+}
+
+bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta)
+{
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ enum iwl_bt_coex_lut_type lut_type;
+
+ if (mvm->last_bt_notif_old.ttc_enabled)
+ return true;
+
+ if (le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading) <
+ BT_HIGH_TRAFFIC)
+ return true;
+
+ /*
+ * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
+ * since BT is already killed.
+ * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
+ * we Tx.
+ * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO.
+ */
+ lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
+ return lut_type != BT_COEX_LOOSE_LUT;
+}
+
+bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm)
+{
+ u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
+ return ag == BT_OFF;
+}
+
+bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
+ enum ieee80211_band band)
+{
+ u32 bt_activity =
+ le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
+
+ if (band != IEEE80211_BAND_2GHZ)
+ return false;
+
+ return bt_activity >= BT_LOW_TRAFFIC;
+}
+
+void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm)
+{
+ iwl_mvm_bt_coex_notif_handle(mvm);
+}
+
+int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *dev_cmd)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ u32 ant_isolation = le32_to_cpup((void *)pkt->data);
+ u8 __maybe_unused lower_bound, upper_bound;
+ int ret;
+ u8 lut;
+
+ struct iwl_bt_coex_cmd_old *bt_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = BT_CONFIG,
+ .len = { sizeof(*bt_cmd), },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ };
+
+ if (!IWL_MVM_BT_COEX_CORUNNING)
+ return 0;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* Ignore updates if we are in force mode */
+ if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
+ return 0;
+
+ if (ant_isolation == mvm->last_ant_isol)
+ return 0;
+
+ for (lut = 0; lut < ARRAY_SIZE(antenna_coupling_ranges) - 1; lut++)
+ if (ant_isolation < antenna_coupling_ranges[lut + 1].range)
+ break;
+
+ lower_bound = antenna_coupling_ranges[lut].range;
+
+ if (lut < ARRAY_SIZE(antenna_coupling_ranges) - 1)
+ upper_bound = antenna_coupling_ranges[lut + 1].range;
+ else
+ upper_bound = antenna_coupling_ranges[lut].range;
+
+ IWL_DEBUG_COEX(mvm, "Antenna isolation=%d in range [%d,%d[, lut=%d\n",
+ ant_isolation, lower_bound, upper_bound, lut);
+
+ mvm->last_ant_isol = ant_isolation;
+
+ if (mvm->last_corun_lut == lut)
+ return 0;
+
+ mvm->last_corun_lut = lut;
+
+ bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
+ if (!bt_cmd)
+ return 0;
+ cmd.data[0] = bt_cmd;
+
+ bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
+ BT_VALID_CORUN_LUT_20 |
+ BT_VALID_CORUN_LUT_40);
+
+ /* For the moment, use the same LUT for 20GHz and 40GHz */
+ memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[lut].lut20,
+ sizeof(bt_cmd->bt4_corun_lut20));
+
+ memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
+ sizeof(bt_cmd->bt4_corun_lut40));
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+
+ kfree(bt_cmd);
+ return ret;
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 51685693af2e..ca79f7160573 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -79,6 +79,8 @@
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
+#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
+#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 1
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 29ca72695eaa..7d18f466fbb3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -146,17 +146,47 @@ static ssize_t iwl_dbgfs_fw_error_dump_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
- struct iwl_fw_error_dump_file *dump_file = file->private_data;
+ struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data;
+ ssize_t bytes_read = 0;
+ ssize_t bytes_read_trans = 0;
+
+ if (*ppos < dump_ptrs->op_mode_len)
+ bytes_read +=
+ simple_read_from_buffer(user_buf, count, ppos,
+ dump_ptrs->op_mode_ptr,
+ dump_ptrs->op_mode_len);
+
+ if (bytes_read < 0 || *ppos < dump_ptrs->op_mode_len)
+ return bytes_read;
+
+ if (dump_ptrs->trans_ptr) {
+ *ppos -= dump_ptrs->op_mode_len;
+ bytes_read_trans =
+ simple_read_from_buffer(user_buf + bytes_read,
+ count - bytes_read, ppos,
+ dump_ptrs->trans_ptr->data,
+ dump_ptrs->trans_ptr->len);
+ *ppos += dump_ptrs->op_mode_len;
+
+ if (bytes_read_trans >= 0)
+ bytes_read += bytes_read_trans;
+ else if (!bytes_read)
+ /* propagate the failure */
+ return bytes_read_trans;
+ }
+
+ return bytes_read;
- return simple_read_from_buffer(user_buf, count, ppos,
- dump_file,
- le32_to_cpu(dump_file->file_len));
}
static int iwl_dbgfs_fw_error_dump_release(struct inode *inode,
struct file *file)
{
- vfree(file->private_data);
+ struct iwl_mvm_dump_ptrs *dump_ptrs = (void *)file->private_data;
+
+ vfree(dump_ptrs->op_mode_ptr);
+ vfree(dump_ptrs->trans_ptr);
+ kfree(dump_ptrs);
return 0;
}
@@ -312,20 +342,69 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
BT_MBOX_MSG(notif, _num, _field), \
true ? "\n" : ", ");
-static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
+static
+int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
+ int pos, int bufsz)
{
- struct iwl_mvm *mvm = file->private_data;
- struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
- char *buf;
- int ret, pos = 0, bufsz = sizeof(char) * 1024;
+ pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
- buf = kmalloc(bufsz, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
+ BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
+ BT_MBOX_PRINT(0, LE_PROF1, false);
+ BT_MBOX_PRINT(0, LE_PROF2, false);
+ BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
+ BT_MBOX_PRINT(0, CHL_SEQ_N, false);
+ BT_MBOX_PRINT(0, INBAND_S, false);
+ BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
+ BT_MBOX_PRINT(0, LE_SCAN, false);
+ BT_MBOX_PRINT(0, LE_ADV, false);
+ BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
+ BT_MBOX_PRINT(0, OPEN_CON_1, true);
- mutex_lock(&mvm->mutex);
+ pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
+
+ BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
+ BT_MBOX_PRINT(1, IP_SR, false);
+ BT_MBOX_PRINT(1, LE_MSTR, false);
+ BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
+ BT_MBOX_PRINT(1, MSG_TYPE, false);
+ BT_MBOX_PRINT(1, SSN, true);
+
+ pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
+
+ BT_MBOX_PRINT(2, SNIFF_ACT, false);
+ BT_MBOX_PRINT(2, PAG, false);
+ BT_MBOX_PRINT(2, INQUIRY, false);
+ BT_MBOX_PRINT(2, CONN, false);
+ BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
+ BT_MBOX_PRINT(2, DISC, false);
+ BT_MBOX_PRINT(2, SCO_TX_ACT, false);
+ BT_MBOX_PRINT(2, SCO_RX_ACT, false);
+ BT_MBOX_PRINT(2, ESCO_RE_TX, false);
+ BT_MBOX_PRINT(2, SCO_DURATION, true);
+
+ pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
+
+ BT_MBOX_PRINT(3, SCO_STATE, false);
+ BT_MBOX_PRINT(3, SNIFF_STATE, false);
+ BT_MBOX_PRINT(3, A2DP_STATE, false);
+ BT_MBOX_PRINT(3, ACL_STATE, false);
+ BT_MBOX_PRINT(3, MSTR_STATE, false);
+ BT_MBOX_PRINT(3, OBX_STATE, false);
+ BT_MBOX_PRINT(3, OPEN_CON_2, false);
+ BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
+ BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
+ BT_MBOX_PRINT(3, INBAND_P, false);
+ BT_MBOX_PRINT(3, MSG_TYPE_2, false);
+ BT_MBOX_PRINT(3, SSN_2, false);
+ BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
+
+ return pos;
+}
+static
+int iwl_mvm_coex_dump_mbox_old(struct iwl_bt_coex_profile_notif_old *notif,
+ char *buf, int pos, int bufsz)
+{
pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
@@ -378,25 +457,59 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
BT_MBOX_PRINT(3, SSN_2, false);
BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
- pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n",
- notif->bt_status);
- pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n",
- notif->bt_open_conn);
- pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n",
- notif->bt_traffic_load);
- pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n",
- notif->bt_agg_traffic_load);
- pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
- notif->bt_ci_compliance);
- pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
- le32_to_cpu(notif->primary_ch_lut));
- pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
- le32_to_cpu(notif->secondary_ch_lut));
- pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n",
- le32_to_cpu(notif->bt_activity_grading));
- pos += scnprintf(buf+pos, bufsz-pos,
- "antenna isolation = %d CORUN LUT index = %d\n",
- mvm->last_ant_isol, mvm->last_corun_lut);
+ return pos;
+}
+
+static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_mvm *mvm = file->private_data;
+ char *buf;
+ int ret, pos = 0, bufsz = sizeof(char) * 1024;
+
+ buf = kmalloc(bufsz, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ mutex_lock(&mvm->mutex);
+
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
+ struct iwl_bt_coex_profile_notif_old *notif =
+ &mvm->last_bt_notif_old;
+
+ pos += iwl_mvm_coex_dump_mbox_old(notif, buf, pos, bufsz);
+
+ pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
+ notif->bt_ci_compliance);
+ pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
+ le32_to_cpu(notif->primary_ch_lut));
+ pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
+ le32_to_cpu(notif->secondary_ch_lut));
+ pos += scnprintf(buf+pos,
+ bufsz-pos, "bt_activity_grading = %d\n",
+ le32_to_cpu(notif->bt_activity_grading));
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "antenna isolation = %d CORUN LUT index = %d\n",
+ mvm->last_ant_isol, mvm->last_corun_lut);
+ } else {
+ struct iwl_bt_coex_profile_notif *notif =
+ &mvm->last_bt_notif;
+
+ pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz);
+
+ pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
+ notif->bt_ci_compliance);
+ pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
+ le32_to_cpu(notif->primary_ch_lut));
+ pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
+ le32_to_cpu(notif->secondary_ch_lut));
+ pos += scnprintf(buf+pos,
+ bufsz-pos, "bt_activity_grading = %d\n",
+ le32_to_cpu(notif->bt_activity_grading));
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "antenna isolation = %d CORUN LUT index = %d\n",
+ mvm->last_ant_isol, mvm->last_corun_lut);
+ }
mutex_unlock(&mvm->mutex);
@@ -411,28 +524,57 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
- struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
char buf[256];
int bufsz = sizeof(buf);
int pos = 0;
mutex_lock(&mvm->mutex);
- pos += scnprintf(buf+pos, bufsz-pos, "Channel inhibition CMD\n");
- pos += scnprintf(buf+pos, bufsz-pos,
- "\tPrimary Channel Bitmap 0x%016llx Fat: %d\n",
- le64_to_cpu(cmd->bt_primary_ci),
- !!cmd->co_run_bw_primary);
- pos += scnprintf(buf+pos, bufsz-pos,
- "\tSecondary Channel Bitmap 0x%016llx Fat: %d\n",
- le64_to_cpu(cmd->bt_secondary_ci),
- !!cmd->co_run_bw_secondary);
-
- pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
- pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
- iwl_bt_ack_kill_msk[mvm->bt_kill_msk]);
- pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
- iwl_bt_cts_kill_msk[mvm->bt_kill_msk]);
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
+ struct iwl_bt_coex_ci_cmd_old *cmd = &mvm->last_bt_ci_cmd_old;
+
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "Channel inhibition CMD\n");
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tPrimary Channel Bitmap 0x%016llx\n",
+ le64_to_cpu(cmd->bt_primary_ci));
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tSecondary Channel Bitmap 0x%016llx\n",
+ le64_to_cpu(cmd->bt_secondary_ci));
+
+ pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
+ pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0]]);
+ pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0]]);
+
+ } else {
+ struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
+
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "Channel inhibition CMD\n");
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tPrimary Channel Bitmap 0x%016llx\n",
+ le64_to_cpu(cmd->bt_primary_ci));
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tSecondary Channel Bitmap 0x%016llx\n",
+ le64_to_cpu(cmd->bt_secondary_ci));
+
+ pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tPrimary: ACK Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0]]);
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tPrimary: CTS Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0]]);
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tSecondary: ACK Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[1]]);
+ pos += scnprintf(buf+pos, bufsz-pos,
+ "\tSecondary: CTS Kill Mask 0x%08x\n",
+ iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[1]]);
+
+ }
mutex_unlock(&mvm->mutex);
@@ -455,6 +597,43 @@ iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
return count;
}
+static ssize_t
+iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
+ size_t count, loff_t *ppos)
+{
+ static const char * const modes_str[BT_FORCE_ANT_MAX] = {
+ [BT_FORCE_ANT_DIS] = "dis",
+ [BT_FORCE_ANT_AUTO] = "auto",
+ [BT_FORCE_ANT_BT] = "bt",
+ [BT_FORCE_ANT_WIFI] = "wifi",
+ };
+ int ret, bt_force_ant_mode;
+
+ for (bt_force_ant_mode = 0;
+ bt_force_ant_mode < ARRAY_SIZE(modes_str);
+ bt_force_ant_mode++) {
+ if (!strcmp(buf, modes_str[bt_force_ant_mode]))
+ break;
+ }
+
+ if (bt_force_ant_mode >= ARRAY_SIZE(modes_str))
+ return -EINVAL;
+
+ ret = 0;
+ mutex_lock(&mvm->mutex);
+ if (mvm->bt_force_ant_mode == bt_force_ant_mode)
+ goto out;
+
+ mvm->bt_force_ant_mode = bt_force_ant_mode;
+ IWL_DEBUG_COEX(mvm, "Force mode: %s\n",
+ modes_str[mvm->bt_force_ant_mode]);
+ ret = iwl_send_bt_init_conf(mvm);
+
+out:
+ mutex_unlock(&mvm->mutex);
+ return ret ?: count;
+}
+
#define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \
@@ -690,8 +869,14 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
{
+ int ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI);
+ if (ret)
+ return ret;
+
iwl_force_nmi(mvm->trans);
+ iwl_mvm_unref(mvm, IWL_MVM_REF_NMI);
+
return count;
}
@@ -975,11 +1160,11 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
}
#endif
-#define PRINT_MVM_REF(ref) do { \
- if (test_bit(ref, mvm->ref_bitmap)) \
- pos += scnprintf(buf + pos, bufsz - pos, \
- "\t(0x%lx) %s\n", \
- BIT(ref), #ref); \
+#define PRINT_MVM_REF(ref) do { \
+ if (mvm->refs[ref]) \
+ pos += scnprintf(buf + pos, bufsz - pos, \
+ "\t(0x%lx): %d %s\n", \
+ BIT(ref), mvm->refs[ref], #ref); \
} while (0)
static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
@@ -987,12 +1172,17 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
- int pos = 0;
+ int i, pos = 0;
char buf[256];
const size_t bufsz = sizeof(buf);
+ u32 refs = 0;
+
+ for (i = 0; i < IWL_MVM_REF_COUNT; i++)
+ if (mvm->refs[i])
+ refs |= BIT(i);
- pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%lx\n",
- mvm->ref_bitmap[0]);
+ pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n",
+ refs);
PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
PRINT_MVM_REF(IWL_MVM_REF_SCAN);
@@ -1018,7 +1208,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
mutex_lock(&mvm->mutex);
- taken = test_bit(IWL_MVM_REF_USER, mvm->ref_bitmap);
+ taken = mvm->refs[IWL_MVM_REF_USER];
if (value == 1 && !taken)
iwl_mvm_ref(mvm, IWL_MVM_REF_USER);
else if (value == 0 && taken)
@@ -1054,14 +1244,21 @@ iwl_dbgfs_prph_reg_read(struct file *file,
int pos = 0;
char buf[32];
const size_t bufsz = sizeof(buf);
+ int ret;
if (!mvm->dbgfs_prph_reg_addr)
return -EINVAL;
+ ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ);
+ if (ret)
+ return ret;
+
pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
mvm->dbgfs_prph_reg_addr,
iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
+ iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ);
+
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -1071,6 +1268,7 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
{
u8 args;
u32 value;
+ int ret;
args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
/* if we only want to set the reg address - nothing more to do */
@@ -1081,7 +1279,13 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
if (args != 2)
return -EINVAL;
+ ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
+ if (ret)
+ return ret;
+
iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
+
+ iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
out:
return count;
}
@@ -1101,6 +1305,7 @@ MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
+MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
@@ -1142,6 +1347,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, S_IWUSR);
+ MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
S_IWUSR | S_IRUSR);
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index 5fe82c29c8ad..69875716dcdb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -72,10 +72,13 @@
* enum iwl_bt_coex_flags - flags for BT_COEX command
* @BT_COEX_MODE_POS:
* @BT_COEX_MODE_MSK:
- * @BT_COEX_DISABLE:
- * @BT_COEX_2W:
- * @BT_COEX_3W:
- * @BT_COEX_NW:
+ * @BT_COEX_DISABLE_OLD:
+ * @BT_COEX_2W_OLD:
+ * @BT_COEX_3W_OLD:
+ * @BT_COEX_NW_OLD:
+ * @BT_COEX_AUTO_OLD:
+ * @BT_COEX_BT_OLD: Antenna is for BT (manufacuring tests)
+ * @BT_COEX_WIFI_OLD: Antenna is for BT (manufacuring tests)
* @BT_COEX_SYNC2SCO:
* @BT_COEX_CORUNNING:
* @BT_COEX_MPLUT:
@@ -85,10 +88,13 @@
enum iwl_bt_coex_flags {
BT_COEX_MODE_POS = 3,
BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,
- BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS,
- BT_COEX_2W = 0x1 << BT_COEX_MODE_POS,
- BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,
- BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
+ BT_COEX_DISABLE_OLD = 0x0 << BT_COEX_MODE_POS,
+ BT_COEX_2W_OLD = 0x1 << BT_COEX_MODE_POS,
+ BT_COEX_3W_OLD = 0x2 << BT_COEX_MODE_POS,
+ BT_COEX_NW_OLD = 0x3 << BT_COEX_MODE_POS,
+ BT_COEX_AUTO_OLD = 0x5 << BT_COEX_MODE_POS,
+ BT_COEX_BT_OLD = 0x6 << BT_COEX_MODE_POS,
+ BT_COEX_WIFI_OLD = 0x7 << BT_COEX_MODE_POS,
BT_COEX_SYNC2SCO = BIT(7),
BT_COEX_CORUNNING = BIT(8),
BT_COEX_MPLUT = BIT(9),
@@ -151,7 +157,7 @@ enum iwl_bt_coex_lut_type {
#define BT_REDUCED_TX_POWER_BIT BIT(7)
/**
- * struct iwl_bt_coex_cmd - bt coex configuration command
+ * struct iwl_bt_coex_cmd_old - bt coex configuration command
* @flags:&enum iwl_bt_coex_flags
* @max_kill:
* @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
@@ -176,7 +182,7 @@ enum iwl_bt_coex_lut_type {
*
* The structure is used for the BT_COEX command.
*/
-struct iwl_bt_coex_cmd {
+struct iwl_bt_coex_cmd_old {
__le32 flags;
u8 max_kill;
u8 bt_reduced_tx_power;
@@ -202,26 +208,117 @@ struct iwl_bt_coex_cmd {
__le32 valid_bit_msk;
} __packed; /* BT_COEX_CMD_API_S_VER_5 */
+enum iwl_bt_coex_mode {
+ BT_COEX_DISABLE = 0x0,
+ BT_COEX_NW = 0x1,
+ BT_COEX_BT = 0x2,
+ BT_COEX_WIFI = 0x3,
+}; /* BT_COEX_MODES_E */
+
+enum iwl_bt_coex_enabled_modules {
+ BT_COEX_MPLUT_ENABLED = BIT(0),
+ BT_COEX_MPLUT_BOOST_ENABLED = BIT(1),
+ BT_COEX_SYNC2SCO_ENABLED = BIT(2),
+ BT_COEX_CORUN_ENABLED = BIT(3),
+ BT_COEX_HIGH_BAND_RET = BIT(4),
+}; /* BT_COEX_MODULES_ENABLE_E_VER_1 */
+
+/**
+ * struct iwl_bt_coex_cmd - bt coex configuration command
+ * @mode: enum %iwl_bt_coex_mode
+ * @enabled_modules: enum %iwl_bt_coex_enabled_modules
+ * @max_kill: max count of Tx retries due to kill from PTA
+ * @override_primary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
+ * should be set by default
+ * @override_secondary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
+ * should be set by default
+ * @bt4_antenna_isolation_thr: antenna threshold value
+ * @bt4_tx_tx_delta_freq_thr: TxTx delta frequency
+ * @bt4_tx_rx_max_freq0: TxRx max frequency
+ * @multiprio_lut: multi priority LUT configuration
+ * @mplut_prio_boost: BT priority boost registers
+ * @decision_lut: PTA decision LUT, per Prio-Ch
+ *
+ * The structure is used for the BT_COEX command.
+ */
+struct iwl_bt_coex_cmd {
+ __le32 mode;
+ __le32 enabled_modules;
+
+ __le32 max_kill;
+ __le32 override_primary_lut;
+ __le32 override_secondary_lut;
+ __le32 bt4_antenna_isolation_thr;
+
+ __le32 bt4_tx_tx_delta_freq_thr;
+ __le32 bt4_tx_rx_max_freq0;
+
+ __le32 multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE];
+ __le32 mplut_prio_boost[BT_COEX_BOOST_SIZE];
+
+ __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE];
+} __packed; /* BT_COEX_CMD_API_S_VER_6 */
+
+/**
+ * struct iwl_bt_coex_corun_lut_update - bt coex update the corun lut
+ * @corun_lut20: co-running 20 MHz LUT configuration
+ * @corun_lut40: co-running 40 MHz LUT configuration
+ *
+ * The structure is used for the BT_COEX_UPDATE_CORUN_LUT command.
+ */
+struct iwl_bt_coex_corun_lut_update_cmd {
+ __le32 corun_lut20[BT_COEX_CORUN_LUT_SIZE];
+ __le32 corun_lut40[BT_COEX_CORUN_LUT_SIZE];
+} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
+
+/**
+ * struct iwl_bt_coex_sw_boost - SW boost values
+ * @wifi_tx_prio_boost: SW boost of wifi tx priority
+ * @wifi_rx_prio_boost: SW boost of wifi rx priority
+ * @kill_ack_msk: kill ACK mask. 1 - Tx ACK, 0 - kill Tx of ACK.
+ * @kill_cts_msk: kill CTS mask. 1 - Tx CTS, 0 - kill Tx of CTS.
+ */
+struct iwl_bt_coex_sw_boost {
+ __le32 wifi_tx_prio_boost;
+ __le32 wifi_rx_prio_boost;
+ __le32 kill_ack_msk;
+ __le32 kill_cts_msk;
+};
+
+/**
+ * struct iwl_bt_coex_sw_boost_update_cmd - command to update the SW boost
+ * @boost_values: check struct %iwl_bt_coex_sw_boost - one for each channel
+ * primary / secondary / low priority
+ */
+struct iwl_bt_coex_sw_boost_update_cmd {
+ struct iwl_bt_coex_sw_boost boost_values[3];
+} __packed; /* BT_COEX_UPDATE_SW_BOOST_S_VER_1 */
+
+/**
+ * struct iwl_bt_coex_reduced_txp_update_cmd
+ * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
+ * bits are the sta_id (value)
+ */
+struct iwl_bt_coex_reduced_txp_update_cmd {
+ __le32 reduced_txp;
+} __packed; /* BT_COEX_UPDATE_REDUCED_TX_POWER_API_S_VER_1 */
+
/**
* struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
* @bt_primary_ci:
- * @bt_secondary_ci:
- * @co_run_bw_primary:
- * @co_run_bw_secondary:
* @primary_ch_phy_id:
+ * @bt_secondary_ci:
* @secondary_ch_phy_id:
*
* Used for BT_COEX_CI command
*/
struct iwl_bt_coex_ci_cmd {
__le64 bt_primary_ci;
- __le64 bt_secondary_ci;
+ __le32 primary_ch_phy_id;
- u8 co_run_bw_primary;
- u8 co_run_bw_secondary;
- u8 primary_ch_phy_id;
- u8 secondary_ch_phy_id;
-} __packed; /* BT_CI_MSG_API_S_VER_1 */
+ __le64 bt_secondary_ci;
+ __le32 secondary_ch_phy_id;
+} __packed; /* BT_CI_MSG_API_S_VER_2 */
#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
@@ -288,35 +385,44 @@ enum iwl_bt_activity_grading {
BT_ON_NO_CONNECTION = 1,
BT_LOW_TRAFFIC = 2,
BT_HIGH_TRAFFIC = 3,
+
+ BT_MAX_AG,
}; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */
+enum iwl_bt_ci_compliance {
+ BT_CI_COMPLIANCE_NONE = 0,
+ BT_CI_COMPLIANCE_PRIMARY = 1,
+ BT_CI_COMPLIANCE_SECONDARY = 2,
+ BT_CI_COMPLIANCE_BOTH = 3,
+}; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */
+
+#define IWL_COEX_IS_TTC_ON(_ttc_rrc_status, _phy_id) \
+ (_ttc_rrc_status & BIT(_phy_id))
+
+#define IWL_COEX_IS_RRC_ON(_ttc_rrc_status, _phy_id) \
+ ((_ttc_rrc_status >> 4) & BIT(_phy_id))
+
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
* @mbox_msg: message from BT to WiFi
* @msg_idx: the index of the message
- * @bt_status: 0 - off, 1 - on
- * @bt_open_conn: number of BT connections open
- * @bt_traffic_load: load of BT traffic
- * @bt_agg_traffic_load: aggregated load of BT traffic
- * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
- * @primary_ch_lut: LUT used for primary channel
- * @secondary_ch_lut: LUT used for secondary channel
+ * @bt_ci_compliance: enum %iwl_bt_ci_compliance
+ * @primary_ch_lut: LUT used for primary channel enum %iwl_bt_coex_lut_type
+ * @secondary_ch_lut: LUT used for secondary channel enume %iwl_bt_coex_lut_type
* @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
+ * @ttc_rrc_status: is TTC or RRC enabled - one bit per PHY
*/
struct iwl_bt_coex_profile_notif {
__le32 mbox_msg[4];
__le32 msg_idx;
- u8 bt_status;
- u8 bt_open_conn;
- u8 bt_traffic_load;
- u8 bt_agg_traffic_load;
- u8 bt_ci_compliance;
- u8 reserved[3];
+ __le32 bt_ci_compliance;
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
-} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */
+ u8 ttc_rrc_status;
+ u8 reserved[3];
+} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_4 */
enum iwl_bt_coex_prio_table_event {
BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
@@ -355,4 +461,54 @@ struct iwl_bt_coex_prio_tbl_cmd {
u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
} __packed;
+/**
+ * struct iwl_bt_coex_ci_cmd_old - bt coex channel inhibition command
+ * @bt_primary_ci:
+ * @bt_secondary_ci:
+ * @co_run_bw_primary:
+ * @co_run_bw_secondary:
+ * @primary_ch_phy_id:
+ * @secondary_ch_phy_id:
+ *
+ * Used for BT_COEX_CI command
+ */
+struct iwl_bt_coex_ci_cmd_old {
+ __le64 bt_primary_ci;
+ __le64 bt_secondary_ci;
+
+ u8 co_run_bw_primary;
+ u8 co_run_bw_secondary;
+ u8 primary_ch_phy_id;
+ u8 secondary_ch_phy_id;
+} __packed; /* BT_CI_MSG_API_S_VER_1 */
+
+/**
+ * struct iwl_bt_coex_profile_notif_old - notification about BT coex
+ * @mbox_msg: message from BT to WiFi
+ * @msg_idx: the index of the message
+ * @bt_status: 0 - off, 1 - on
+ * @bt_open_conn: number of BT connections open
+ * @bt_traffic_load: load of BT traffic
+ * @bt_agg_traffic_load: aggregated load of BT traffic
+ * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
+ * @primary_ch_lut: LUT used for primary channel
+ * @secondary_ch_lut: LUT used for secondary channel
+ * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
+ */
+struct iwl_bt_coex_profile_notif_old {
+ __le32 mbox_msg[4];
+ __le32 msg_idx;
+ u8 bt_status;
+ u8 bt_open_conn;
+ u8 bt_traffic_load;
+ u8 bt_agg_traffic_load;
+ u8 bt_ci_compliance;
+ u8 ttc_enabled;
+ __le16 reserved;
+
+ __le32 primary_ch_lut;
+ __le32 secondary_ch_lut;
+ __le32 bt_activity_grading;
+} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */
+
#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index cbbcd8e284e4..c3a8c86b550d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -336,7 +336,7 @@ struct iwl_beacon_filter_cmd {
#define IWL_BF_DEBUG_FLAG_D0I3 0
#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
-#define IWL_BF_ESCAPE_TIMER_D0I3 1024
+#define IWL_BF_ESCAPE_TIMER_D0I3 0
#define IWL_BF_ESCAPE_TIMER_MAX 1024
#define IWL_BF_ESCAPE_TIMER_MIN 0
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 6959fda3fe09..c02a9e45ec5e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -170,18 +170,12 @@ enum iwl_scan_type {
}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
/**
- * Maximal number of channels to scan
- * it should be equal to:
- * max(IWL_NUM_CHANNELS, IWL_NUM_CHANNELS_FAMILY_8000)
- */
-#define MAX_NUM_SCAN_CHANNELS 50
-
-/**
* struct iwl_scan_cmd - scan request command
* ( SCAN_REQUEST_CMD = 0x80 )
* @len: command length in bytes
* @scan_flags: scan flags from SCAN_FLAGS_*
- * @channel_count: num of channels in channel list (1 - MAX_NUM_SCAN_CHANNELS)
+ * @channel_count: num of channels in channel list
+ * (1 - ucode_capa.n_scan_channels)
* @quiet_time: in msecs, dwell this time for active scan on quiet channels
* @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
* this number of packets were received (typically 1)
@@ -345,7 +339,7 @@ struct iwl_scan_results_notif {
* @last_channel: last channel that was scanned
* @tsf_low: TSF timer (lower half) in usecs
* @tsf_high: TSF timer (higher half) in usecs
- * @results: all scan results, only "scanned_channels" of them are valid
+ * @results: array of scan results, only "scanned_channels" of them are valid
*/
struct iwl_scan_complete_notif {
u8 scanned_channels;
@@ -354,11 +348,10 @@ struct iwl_scan_complete_notif {
u8 last_channel;
__le32 tsf_low;
__le32 tsf_high;
- struct iwl_scan_results_notif results[MAX_NUM_SCAN_CHANNELS];
+ struct iwl_scan_results_notif results[];
} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
/* scan offload */
-#define IWL_MAX_SCAN_CHANNELS 40
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_MAX_PROFILES 11
@@ -423,36 +416,24 @@ enum iwl_scan_offload_channel_flags {
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL = BIT(25),
};
-/**
- * iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S
- * @type: bitmap - see enum iwl_scan_offload_channel_flags.
- * 0: passive (0) or active (1) scan.
- * 1-20: directed scan to i'th ssid.
- * 22: channel width configuation - 1 for narrow.
- * 24: full scan.
- * 25: partial scan.
- * @channel_number: channel number 1-13 etc.
- * @iter_count: repetition count for the channel.
- * @iter_interval: interval between two innteration on one channel.
- * @dwell_time: entry 0 - active scan, entry 1 - passive scan.
+/* channel configuration for struct iwl_scan_offload_cfg. Each channels needs:
+ * __le32 type: bitmap; bits 1-20 are for directed scan to i'th ssid and
+ * see enum iwl_scan_offload_channel_flags.
+ * __le16 channel_number: channel number 1-13 etc.
+ * __le16 iter_count: repetition count for the channel.
+ * __le32 iter_interval: interval between two innteration on one channel.
+ * u8 active_dwell.
+ * u8 passive_dwell.
*/
-struct iwl_scan_channel_cfg {
- __le32 type[IWL_MAX_SCAN_CHANNELS];
- __le16 channel_number[IWL_MAX_SCAN_CHANNELS];
- __le16 iter_count[IWL_MAX_SCAN_CHANNELS];
- __le32 iter_interval[IWL_MAX_SCAN_CHANNELS];
- u8 dwell_time[IWL_MAX_SCAN_CHANNELS][2];
-} __packed;
+#define IWL_SCAN_CHAN_SIZE 14
/**
* iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
* @scan_cmd: scan command fixed part
- * @channel_cfg: scan channel configuration
- * @data: probe request frames (one per band)
+ * @data: scan channel configuration and probe request frames
*/
struct iwl_scan_offload_cfg {
struct iwl_scan_offload_cmd scan_cmd;
- struct iwl_scan_channel_cfg channel_cfg;
u8 data[0];
} __packed;
@@ -528,7 +509,7 @@ struct iwl_scan_offload_profile_cfg {
* @full_scan_mul: number of partial scans before each full scan
*/
struct iwl_scan_offload_schedule {
- u16 delay;
+ __le16 delay;
u8 iterations;
u8 full_scan_mul;
} __packed;
@@ -601,4 +582,211 @@ struct iwl_sched_scan_results {
u8 reserved;
};
+/* Unified LMAC scan API */
+
+#define IWL_MVM_BASIC_PASSIVE_DWELL 110
+
+/**
+ * iwl_scan_req_tx_cmd - SCAN_REQ_TX_CMD_API_S
+ * @tx_flags: combination of TX_CMD_FLG_*
+ * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
+ * cleared. Combination of RATE_MCS_*
+ * @sta_id: index of destination station in FW station table
+ * @reserved: for alignment and future use
+ */
+struct iwl_scan_req_tx_cmd {
+ __le32 tx_flags;
+ __le32 rate_n_flags;
+ u8 sta_id;
+ u8 reserved[3];
+} __packed;
+
+enum iwl_scan_channel_flags_lmac {
+ IWL_UNIFIED_SCAN_CHANNEL_FULL = BIT(27),
+ IWL_UNIFIED_SCAN_CHANNEL_PARTIAL = BIT(28),
+};
+
+/**
+ * iwl_scan_channel_cfg_lmac - SCAN_CHANNEL_CFG_S_VER2
+ * @flags: bits 1-20: directed scan to i'th ssid
+ * other bits &enum iwl_scan_channel_flags_lmac
+ * @channel_number: channel number 1-13 etc
+ * @iter_count: scan iteration on this channel
+ * @iter_interval: interval in seconds between iterations on one channel
+ */
+struct iwl_scan_channel_cfg_lmac {
+ __le32 flags;
+ __le16 channel_num;
+ __le16 iter_count;
+ __le32 iter_interval;
+} __packed;
+
+/*
+ * iwl_scan_probe_segment - PROBE_SEGMENT_API_S_VER_1
+ * @offset: offset in the data block
+ * @len: length of the segment
+ */
+struct iwl_scan_probe_segment {
+ __le16 offset;
+ __le16 len;
+} __packed;
+
+/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_2
+ * @mac_header: first (and common) part of the probe
+ * @band_data: band specific data
+ * @common_data: last (and common) part of the probe
+ * @buf: raw data block
+ */
+struct iwl_scan_probe_req {
+ struct iwl_scan_probe_segment mac_header;
+ struct iwl_scan_probe_segment band_data[2];
+ struct iwl_scan_probe_segment common_data;
+ u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
+} __packed;
+
+enum iwl_scan_channel_flags {
+ IWL_SCAN_CHANNEL_FLAG_EBS = BIT(0),
+ IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE = BIT(1),
+ IWL_SCAN_CHANNEL_FLAG_CACHE_ADD = BIT(2),
+};
+
+/* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
+ * @flags: enum iwl_scan_channel_flgs
+ * @non_ebs_ratio: how many regular scan iteration before EBS
+ */
+struct iwl_scan_channel_opt {
+ __le16 flags;
+ __le16 non_ebs_ratio;
+} __packed;
+
+/**
+ * iwl_mvm_lmac_scan_flags
+ * @IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL: pass all beacons and probe responses
+ * without filtering.
+ * @IWL_MVM_LMAC_SCAN_FLAG_PASSIVE: force passive scan on all channels
+ * @IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION: single channel scan
+ * @IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE: send iteration complete notification
+ * @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS multiple SSID matching
+ * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
+ */
+enum iwl_mvm_lmac_scan_flags {
+ IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0),
+ IWL_MVM_LMAC_SCAN_FLAG_PASSIVE = BIT(1),
+ IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION = BIT(2),
+ IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE = BIT(3),
+ IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4),
+ IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5),
+};
+
+enum iwl_scan_priority {
+ IWL_SCAN_PRIORITY_LOW,
+ IWL_SCAN_PRIORITY_MEDIUM,
+ IWL_SCAN_PRIORITY_HIGH,
+};
+
+/**
+ * iwl_scan_req_unified_lmac - SCAN_REQUEST_CMD_API_S_VER_1
+ * @reserved1: for alignment and future use
+ * @channel_num: num of channels to scan
+ * @active-dwell: dwell time for active channels
+ * @passive-dwell: dwell time for passive channels
+ * @fragmented-dwell: dwell time for fragmented passive scan
+ * @reserved2: for alignment and future use
+ * @rx_chain_selct: PHY_RX_CHAIN_* flags
+ * @scan_flags: &enum iwl_mvm_lmac_scan_flags
+ * @max_out_time: max time (in TU) to be out of associated channel
+ * @suspend_time: pause scan this long (TUs) when returning to service channel
+ * @flags: RXON flags
+ * @filter_flags: RXON filter
+ * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz
+ * @direct_scan: list of SSIDs for directed active scan
+ * @scan_prio: enum iwl_scan_priority
+ * @iter_num: number of scan iterations
+ * @delay: delay in seconds before first iteration
+ * @schedule: two scheduling plans. The first one is finite, the second one can
+ * be infinite.
+ * @channel_opt: channel optimization options, for full and partial scan
+ * @data: channel configuration and probe request packet.
+ */
+struct iwl_scan_req_unified_lmac {
+ /* SCAN_REQUEST_FIXED_PART_API_S_VER_7 */
+ __le32 reserved1;
+ u8 n_channels;
+ u8 active_dwell;
+ u8 passive_dwell;
+ u8 fragmented_dwell;
+ __le16 reserved2;
+ __le16 rx_chain_select;
+ __le32 scan_flags;
+ __le32 max_out_time;
+ __le32 suspend_time;
+ /* RX_ON_FLAGS_API_S_VER_1 */
+ __le32 flags;
+ __le32 filter_flags;
+ struct iwl_scan_req_tx_cmd tx_cmd[2];
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
+ __le32 scan_prio;
+ /* SCAN_REQ_PERIODIC_PARAMS_API_S */
+ __le32 iter_num;
+ __le32 delay;
+ struct iwl_scan_offload_schedule schedule[2];
+ struct iwl_scan_channel_opt channel_opt[2];
+ u8 data[];
+} __packed;
+
+/**
+ * struct iwl_lmac_scan_results_notif - scan results for one channel -
+ * SCAN_RESULT_NTF_API_S_VER_3
+ * @channel: which channel the results are from
+ * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
+ * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
+ * @num_probe_not_sent: # of request that weren't sent due to not enough time
+ * @duration: duration spent in channel, in usecs
+ */
+struct iwl_lmac_scan_results_notif {
+ u8 channel;
+ u8 band;
+ u8 probe_status;
+ u8 num_probe_not_sent;
+ __le32 duration;
+} __packed;
+
+/**
+ * struct iwl_lmac_scan_complete_notif - notifies end of scanning (all channels)
+ * SCAN_COMPLETE_NTF_API_S_VER_3
+ * @scanned_channels: number of channels scanned (and number of valid results)
+ * @status: one of SCAN_COMP_STATUS_*
+ * @bt_status: BT on/off status
+ * @last_channel: last channel that was scanned
+ * @tsf_low: TSF timer (lower half) in usecs
+ * @tsf_high: TSF timer (higher half) in usecs
+ * @results: an array of scan results, only "scanned_channels" of them are valid
+ */
+struct iwl_lmac_scan_complete_notif {
+ u8 scanned_channels;
+ u8 status;
+ u8 bt_status;
+ u8 last_channel;
+ __le32 tsf_low;
+ __le32 tsf_high;
+ struct iwl_scan_results_notif results[];
+} __packed;
+
+/**
+ * iwl_scan_offload_complete - PERIODIC_SCAN_COMPLETE_NTF_API_S_VER_2
+ * @last_schedule_line: last schedule line executed (fast or regular)
+ * @last_schedule_iteration: last scan iteration executed before scan abort
+ * @status: enum iwl_scan_offload_complete_status
+ * @ebs_status: EBS success status &enum iwl_scan_ebs_status
+ * @time_after_last_iter; time in seconds elapsed after last iteration
+ */
+struct iwl_periodic_scan_complete {
+ u8 last_schedule_line;
+ u8 last_schedule_iteration;
+ u8 status;
+ u8 ebs_status;
+ __le32 time_after_last_iter;
+ __le32 reserved;
+} __packed;
+
#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 39cebee8016f..47bd0406355d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -67,7 +67,7 @@
* enum iwl_sta_flags - flags for the ADD_STA host command
* @STA_FLG_REDUCED_TX_PWR_CTRL:
* @STA_FLG_REDUCED_TX_PWR_DATA:
- * @STA_FLG_FLG_ANT_MSK: Antenna selection
+ * @STA_FLG_DISABLE_TX: set if TX should be disabled
* @STA_FLG_PS: set if STA is in Power Save
* @STA_FLG_INVALID: set if STA is invalid
* @STA_FLG_DLP_EN: Direct Link Protocol is enabled
@@ -91,10 +91,7 @@ enum iwl_sta_flags {
STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3),
STA_FLG_REDUCED_TX_PWR_DATA = BIT(6),
- STA_FLG_FLG_ANT_A = (1 << 4),
- STA_FLG_FLG_ANT_B = (2 << 4),
- STA_FLG_FLG_ANT_MSK = (STA_FLG_FLG_ANT_A |
- STA_FLG_FLG_ANT_B),
+ STA_FLG_DISABLE_TX = BIT(4),
STA_FLG_PS = BIT(8),
STA_FLG_DRAIN_FLOW = BIT(12),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 6cc5f52b807f..d6073f67b212 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -69,10 +69,8 @@
* @TX_CMD_FLG_ACK: expect ACK from receiving station
* @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
* Otherwise, use rate_n_flags from the TX command
- * @TX_CMD_FLG_BA: this frame is a block ack
* @TX_CMD_FLG_BAR: this frame is a BA request, immediate BAR is expected
* Must set TX_CMD_FLG_ACK with this flag.
- * @TX_CMD_FLG_TXOP_PROT: protect frame with full TXOP protection
* @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
* @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
* @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
@@ -82,12 +80,10 @@
* @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
* Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
* @TX_CMD_FLG_MORE_FRAG: this frame is non-last MPDU
- * @TX_CMD_FLG_NEXT_FRAME: this frame includes information of the next frame
* @TX_CMD_FLG_TSF: FW should calculate and insert TSF in the frame
* Should be set for beacons and probe responses
* @TX_CMD_FLG_CALIB: activate PA TX power calibrations
* @TX_CMD_FLG_KEEP_SEQ_CTL: if seq_ctl is set, don't increase inner seq count
- * @TX_CMD_FLG_AGG_START: allow this frame to start aggregation
* @TX_CMD_FLG_MH_PAD: driver inserted 2 byte padding after MAC header.
* Should be set for 26/30 length MAC headers
* @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW
@@ -103,7 +99,6 @@ enum iwl_tx_flags {
TX_CMD_FLG_PROT_REQUIRE = BIT(0),
TX_CMD_FLG_ACK = BIT(3),
TX_CMD_FLG_STA_RATE = BIT(4),
- TX_CMD_FLG_BA = BIT(5),
TX_CMD_FLG_BAR = BIT(6),
TX_CMD_FLG_TXOP_PROT = BIT(7),
TX_CMD_FLG_VHT_NDPA = BIT(8),
@@ -113,11 +108,9 @@ enum iwl_tx_flags {
TX_CMD_FLG_BT_DIS = BIT(12),
TX_CMD_FLG_SEQ_CTL = BIT(13),
TX_CMD_FLG_MORE_FRAG = BIT(14),
- TX_CMD_FLG_NEXT_FRAME = BIT(15),
TX_CMD_FLG_TSF = BIT(16),
TX_CMD_FLG_CALIB = BIT(17),
TX_CMD_FLG_KEEP_SEQ_CTL = BIT(18),
- TX_CMD_FLG_AGG_START = BIT(19),
TX_CMD_FLG_MH_PAD = BIT(20),
TX_CMD_FLG_RESP_TO_DRV = BIT(21),
TX_CMD_FLG_CCMP_AGG = BIT(22),
@@ -191,8 +184,6 @@ enum iwl_tx_flags {
* struct iwl_tx_cmd - TX command struct to FW
* ( TX_CMD = 0x1c )
* @len: in bytes of the payload, see below for details
- * @next_frame_len: same as len, but for next frame (0 if not applicable)
- * Used for fragmentation and bursting, but not in 11n aggregation.
* @tx_flags: combination of TX_CMD_FLG_*
* @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
* cleared. Combination of RATE_MCS_*
@@ -210,8 +201,6 @@ enum iwl_tx_flags {
* @data_retry_limit: max attempts to send the data packet
* @tid_spec: TID/tspec
* @pm_frame_timeout: PM TX frame timeout
- * @driver_txop: duration od EDCA TXOP, in 32-usec units. Set this if not
- * specified by HCCA protocol
*
* The byte count (both len and next_frame_len) includes MAC header
* (24/26/30/32 bytes)
@@ -241,8 +230,7 @@ struct iwl_tx_cmd {
u8 initial_rate_index;
u8 reserved2;
u8 key[16];
- __le16 next_frame_flags;
- __le16 reserved3;
+ __le32 reserved3;
__le32 life_time;
__le32 dram_lsb_ptr;
u8 dram_msb_ptr;
@@ -250,7 +238,7 @@ struct iwl_tx_cmd {
u8 data_retry_limit;
u8 tid_tspec;
__le16 pm_frame_timeout;
- __le16 driver_txop;
+ __le16 reserved4;
u8 payload[0];
struct ieee80211_hdr hdr[0];
} __packed; /* TX_CMD_API_S_VER_3 */
@@ -549,6 +537,20 @@ struct iwl_beacon_notif {
} __packed;
/**
+ * struct iwl_extended_beacon_notif - notifies about beacon transmission
+ * @beacon_notify_hdr: tx response command associated with the beacon
+ * @tsf: last beacon tsf
+ * @ibss_mgr_status: whether IBSS is manager
+ * @gp2: last beacon time in gp2
+ */
+struct iwl_extended_beacon_notif {
+ struct iwl_mvm_tx_resp beacon_notify_hdr;
+ __le64 tsf;
+ __le32 ibss_mgr_status;
+ __le32 gp2;
+} __packed; /* BEACON_NTFY_API_S_VER_5 */
+
+/**
* enum iwl_dump_control - dump (flush) control flags
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
* and the TFD queues are empty.
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 309a9b9a94fe..95f5b3274efb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -86,6 +86,8 @@ enum {
#define IWL_MVM_STATION_COUNT 16
+#define IWL_MVM_TDLS_STA_COUNT 4
+
/* commands */
enum {
MVM_ALIVE = 0x1,
@@ -131,10 +133,12 @@ enum {
/* Scan offload */
SCAN_OFFLOAD_REQUEST_CMD = 0x51,
SCAN_OFFLOAD_ABORT_CMD = 0x52,
+ HOT_SPOT_CMD = 0x53,
SCAN_OFFLOAD_COMPLETE = 0x6D,
SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
MATCH_FOUND_NOTIFICATION = 0xd9,
+ SCAN_ITERATION_COMPLETE = 0xe7,
/* Phy */
PHY_CONFIGURATION_CMD = 0x6a,
@@ -163,7 +167,6 @@ enum {
BEACON_NOTIFICATION = 0x90,
BEACON_TEMPLATE_CMD = 0x91,
TX_ANT_CONFIGURATION_CMD = 0x98,
- BT_CONFIG = 0x9b,
STATISTICS_NOTIFICATION = 0x9d,
EOSP_NOTIFICATION = 0x9e,
REDUCE_TX_POWER_CMD = 0x9f,
@@ -185,6 +188,10 @@ enum {
BT_COEX_PRIO_TABLE = 0xcc,
BT_COEX_PROT_ENV = 0xcd,
BT_PROFILE_NOTIFICATION = 0xce,
+ BT_CONFIG = 0x9b,
+ BT_COEX_UPDATE_SW_BOOST = 0x5a,
+ BT_COEX_UPDATE_CORUN_LUT = 0x5b,
+ BT_COEX_UPDATE_REDUCED_TXP = 0x5c,
BT_COEX_CI = 0x5d,
REPLY_SF_CFG_CMD = 0xd1,
@@ -534,6 +541,9 @@ enum iwl_time_event_type {
/* WiDi Sync Events */
TE_WIDI_TX_SYNC,
+ /* Channel Switch NoA */
+ TE_P2P_GO_CSA_NOA,
+
TE_MAX
}; /* MAC_EVENT_TYPE_API_E_VER_1 */
@@ -901,6 +911,72 @@ struct iwl_phy_context_cmd {
__le32 dsp_cfg_flags;
} __packed; /* PHY_CONTEXT_CMD_API_VER_1 */
+/*
+ * Aux ROC command
+ *
+ * Command requests the firmware to create a time event for a certain duration
+ * and remain on the given channel. This is done by using the Aux framework in
+ * the FW.
+ * The command was first used for Hot Spot issues - but can be used regardless
+ * to Hot Spot.
+ *
+ * ( HOT_SPOT_CMD 0x53 )
+ *
+ * @id_and_color: ID and color of the MAC
+ * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @event_unique_id: If the action FW_CTXT_ACTION_REMOVE then the
+ * event_unique_id should be the id of the time event assigned by ucode.
+ * Otherwise ignore the event_unique_id.
+ * @sta_id_and_color: station id and color, resumed during "Remain On Channel"
+ * activity.
+ * @channel_info: channel info
+ * @node_addr: Our MAC Address
+ * @reserved: reserved for alignment
+ * @apply_time: GP2 value to start (should always be the current GP2 value)
+ * @apply_time_max_delay: Maximum apply time delay value in TU. Defines max
+ * time by which start of the event is allowed to be postponed.
+ * @duration: event duration in TU To calculate event duration:
+ * timeEventDuration = min(duration, remainingQuota)
+ */
+struct iwl_hs20_roc_req {
+ /* COMMON_INDEX_HDR_API_S_VER_1 hdr */
+ __le32 id_and_color;
+ __le32 action;
+ __le32 event_unique_id;
+ __le32 sta_id_and_color;
+ struct iwl_fw_channel_info channel_info;
+ u8 node_addr[ETH_ALEN];
+ __le16 reserved;
+ __le32 apply_time;
+ __le32 apply_time_max_delay;
+ __le32 duration;
+} __packed; /* HOT_SPOT_CMD_API_S_VER_1 */
+
+/*
+ * values for AUX ROC result values
+ */
+enum iwl_mvm_hot_spot {
+ HOT_SPOT_RSP_STATUS_OK,
+ HOT_SPOT_RSP_STATUS_TOO_MANY_EVENTS,
+ HOT_SPOT_MAX_NUM_OF_SESSIONS,
+};
+
+/*
+ * Aux ROC command response
+ *
+ * In response to iwl_hs20_roc_req the FW sends this command to notify the
+ * driver the uid of the timevent.
+ *
+ * ( HOT_SPOT_CMD 0x53 )
+ *
+ * @event_unique_id: Unique ID of time event assigned by ucode
+ * @status: Return status 0 is success, all the rest used for specific errors
+ */
+struct iwl_hs20_roc_res {
+ __le32 event_unique_id;
+ __le32 status;
+} __packed; /* HOT_SPOT_RSP_API_S_VER_1 */
+
#define IWL_RX_INFO_PHY_CNT 8
#define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1
#define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 8b5302777632..0e523e28cabf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -67,6 +67,7 @@
#include "iwl-prph.h"
#include "fw-api.h"
#include "mvm.h"
+#include "time-event.h"
const u8 iwl_mvm_ac_to_tx_fifo[] = {
IWL_MVM_TX_FIFO_VO,
@@ -667,10 +668,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
if (vif->bss_conf.qos)
cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
- if (vif->bss_conf.use_cts_prot) {
+ if (vif->bss_conf.use_cts_prot)
cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
- cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
- }
+
IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
vif->bss_conf.use_cts_prot,
vif->bss_conf.ht_operation_mode);
@@ -904,7 +904,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
struct iwl_mac_beacon_cmd beacon_cmd = {};
struct ieee80211_tx_info *info;
u32 beacon_skb_len;
- u32 rate;
+ u32 rate, tx_flags;
if (WARN_ON(!beacon))
return -EINVAL;
@@ -914,14 +914,17 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
/* TODO: for now the beacon template id is set to be the mac context id.
* Might be better to handle it as another resource ... */
beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
+ info = IEEE80211_SKB_CB(beacon);
/* Set up TX command fields */
beacon_cmd.tx.len = cpu_to_le16((u16)beacon_skb_len);
beacon_cmd.tx.sta_id = mvmvif->bcast_sta.sta_id;
beacon_cmd.tx.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
- beacon_cmd.tx.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
- TX_CMD_FLG_BT_DIS |
- TX_CMD_FLG_TSF);
+ tx_flags = TX_CMD_FLG_SEQ_CTL | TX_CMD_FLG_TSF;
+ tx_flags |=
+ iwl_mvm_bt_coex_tx_prio(mvm, (void *)beacon->data, info, 0) <<
+ TX_CMD_FLG_BT_PRIO_POS;
+ beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags);
mvm->mgmt_last_antenna_idx =
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
@@ -931,8 +934,6 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
RATE_MCS_ANT_POS);
- info = IEEE80211_SKB_CB(beacon);
-
if (info->band == IEEE80211_BAND_5GHZ || vif->p2p) {
rate = IWL_FIRST_OFDM_RATE;
} else {
@@ -969,7 +970,7 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
WARN_ON(vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC);
- beacon = ieee80211_beacon_get(mvm->hw, vif);
+ beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
if (!beacon)
return -ENOMEM;
@@ -1073,8 +1074,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
/* Fill the common data for all mac context types */
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
- /* Also enable probe requests to pass */
- cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
+ /*
+ * pass probe requests and beacons from other APs (needed
+ * for ht protection)
+ */
+ cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST |
+ MAC_FILTER_IN_BEACON);
/* Fill the data specific for ap mode */
iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,
@@ -1095,6 +1100,13 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
/* Fill the common data for all mac context types */
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
+ /*
+ * pass probe requests and beacons from other APs (needed
+ * for ht protection)
+ */
+ cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST |
+ MAC_FILTER_IN_BEACON);
+
/* Fill the data specific for GO mode */
iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
action == FW_CTXT_ACTION_ADD);
@@ -1200,31 +1212,94 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
return 0;
}
+static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm,
+ struct ieee80211_vif *csa_vif, u32 gp2)
+{
+ struct iwl_mvm_vif *mvmvif =
+ iwl_mvm_vif_from_mac80211(csa_vif);
+
+ if (!ieee80211_csa_is_complete(csa_vif)) {
+ int c = ieee80211_csa_update_counter(csa_vif);
+
+ iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif);
+ if (csa_vif->p2p &&
+ !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) {
+ u32 rel_time = (c + 1) *
+ csa_vif->bss_conf.beacon_int -
+ IWL_MVM_CHANNEL_SWITCH_TIME;
+ u32 apply_time = gp2 + rel_time * 1024;
+
+ iwl_mvm_schedule_csa_noa(mvm, csa_vif,
+ IWL_MVM_CHANNEL_SWITCH_TIME -
+ IWL_MVM_CHANNEL_SWITCH_MARGIN,
+ apply_time);
+ }
+ } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) {
+ /* we don't have CSA NoA scheduled yet, switch now */
+ ieee80211_csa_finish(csa_vif);
+ RCU_INIT_POINTER(mvm->csa_vif, NULL);
+ }
+}
+
int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_beacon_notif *beacon = (void *)pkt->data;
- u16 status __maybe_unused =
- le16_to_cpu(beacon->beacon_notify_hdr.status.status);
- u32 rate __maybe_unused =
- le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
+ struct iwl_mvm_tx_resp *beacon_notify_hdr;
+ struct ieee80211_vif *csa_vif;
+ struct ieee80211_vif *tx_blocked_vif;
+ u64 tsf;
lockdep_assert_held(&mvm->mutex);
- IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
- status & TX_STATUS_MSK,
- beacon->beacon_notify_hdr.failure_frame,
- le64_to_cpu(beacon->tsf),
- rate);
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) {
+ struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
- if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) {
- if (!ieee80211_csa_is_complete(mvm->csa_vif)) {
- iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm->csa_vif);
- } else {
- ieee80211_csa_finish(mvm->csa_vif);
- mvm->csa_vif = NULL;
+ beacon_notify_hdr = &beacon->beacon_notify_hdr;
+ tsf = le64_to_cpu(beacon->tsf);
+ mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
+ } else {
+ struct iwl_beacon_notif *beacon = (void *)pkt->data;
+
+ beacon_notify_hdr = &beacon->beacon_notify_hdr;
+ tsf = le64_to_cpu(beacon->tsf);
+ }
+
+ IWL_DEBUG_RX(mvm,
+ "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
+ le16_to_cpu(beacon_notify_hdr->status.status) &
+ TX_STATUS_MSK,
+ beacon_notify_hdr->failure_frame, tsf,
+ mvm->ap_last_beacon_gp2,
+ le32_to_cpu(beacon_notify_hdr->initial_rate));
+
+ csa_vif = rcu_dereference_protected(mvm->csa_vif,
+ lockdep_is_held(&mvm->mutex));
+ if (unlikely(csa_vif && csa_vif->csa_active))
+ iwl_mvm_csa_count_down(mvm, csa_vif, mvm->ap_last_beacon_gp2);
+
+ tx_blocked_vif = rcu_dereference_protected(mvm->csa_tx_blocked_vif,
+ lockdep_is_held(&mvm->mutex));
+ if (unlikely(tx_blocked_vif)) {
+ struct iwl_mvm_vif *mvmvif =
+ iwl_mvm_vif_from_mac80211(tx_blocked_vif);
+
+ /*
+ * The channel switch is started and we have blocked the
+ * stations. If this is the first beacon (the timeout wasn't
+ * set), set the unblock timeout, otherwise countdown
+ */
+ if (!mvm->csa_tx_block_bcn_timeout)
+ mvm->csa_tx_block_bcn_timeout =
+ IWL_MVM_CS_UNBLOCK_TX_TIMEOUT;
+ else
+ mvm->csa_tx_block_bcn_timeout--;
+
+ /* Check if the timeout is expired, and unblock tx */
+ if (mvm->csa_tx_block_bcn_timeout == 0) {
+ iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, false);
+ RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
}
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7215f5980186..0d6a8b768a68 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -80,6 +80,8 @@
#include "fw-api-scan.h"
#include "iwl-phy-db.h"
#include "testmode.h"
+#include "iwl-fw-error-dump.h"
+#include "iwl-prph.h"
static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
{
@@ -209,7 +211,9 @@ void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
return;
IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type);
- WARN_ON(test_and_set_bit(ref_type, mvm->ref_bitmap));
+ spin_lock_bh(&mvm->refs_lock);
+ mvm->refs[ref_type]++;
+ spin_unlock_bh(&mvm->refs_lock);
iwl_trans_ref(mvm->trans);
}
@@ -219,26 +223,47 @@ void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
return;
IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type);
- WARN_ON(!test_and_clear_bit(ref_type, mvm->ref_bitmap));
+ spin_lock_bh(&mvm->refs_lock);
+ WARN_ON(!mvm->refs[ref_type]--);
+ spin_unlock_bh(&mvm->refs_lock);
iwl_trans_unref(mvm->trans);
}
-static void
-iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
+static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm,
+ enum iwl_mvm_ref_type except_ref)
{
- int i;
+ int i, j;
if (!iwl_mvm_is_d0i3_supported(mvm))
return;
- for_each_set_bit(i, mvm->ref_bitmap, IWL_MVM_REF_COUNT) {
- if (ref == i)
+ spin_lock_bh(&mvm->refs_lock);
+ for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
+ if (except_ref == i || !mvm->refs[i])
continue;
- IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d\n", i);
- clear_bit(i, mvm->ref_bitmap);
- iwl_trans_unref(mvm->trans);
+ IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d (%d)\n",
+ i, mvm->refs[i]);
+ for (j = 0; j < mvm->refs[i]; j++)
+ iwl_trans_unref(mvm->trans);
+ mvm->refs[i] = 0;
+ }
+ spin_unlock_bh(&mvm->refs_lock);
+}
+
+int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
+{
+ iwl_mvm_ref(mvm, ref_type);
+
+ if (!wait_event_timeout(mvm->d0i3_exit_waitq,
+ !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
+ HZ)) {
+ WARN_ON_ONCE(1);
+ iwl_mvm_unref(mvm, ref_type);
+ return -EIO;
}
+
+ return 0;
}
static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
@@ -276,6 +301,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_TIMING_BEACON_ONLY |
IEEE80211_HW_CONNECTION_MONITOR |
+ IEEE80211_HW_CHANCTX_STA_CSA |
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
@@ -303,6 +329,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
}
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
+
hw->sta_data_size = sizeof(struct iwl_mvm_sta);
hw->vif_data_size = sizeof(struct iwl_mvm_vif);
hw->chanctx_data_size = sizeof(u16);
@@ -374,6 +403,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
+ NL80211_FEATURE_LOW_PRIORITY_SCAN |
NL80211_FEATURE_P2P_GO_OPPPS;
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
@@ -549,9 +579,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
case IEEE80211_AMPDU_TX_OPERATIONAL:
- iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
- tx_agg_ref = true;
-
/*
* for tx start, wait synchronously until D0i3 exit to
* get the correct sequence number for the tid.
@@ -560,12 +587,11 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
* by the trans layer (unlike commands), so wait for
* d0i3 exit in these cases as well.
*/
- if (!wait_event_timeout(mvm->d0i3_exit_waitq,
- !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) {
- WARN_ON_ONCE(1);
- iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
- return -EIO;
- }
+ ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
+ if (ret)
+ return ret;
+
+ tx_agg_ref = true;
break;
default:
break;
@@ -635,7 +661,105 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
spin_unlock_bh(&mvm->time_event_lock);
mvmvif->phy_ctxt = NULL;
+ memset(&mvmvif->bf_data, 0, sizeof(mvmvif->bf_data));
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+{
+ struct iwl_fw_error_dump_file *dump_file;
+ struct iwl_fw_error_dump_data *dump_data;
+ struct iwl_fw_error_dump_info *dump_info;
+ struct iwl_mvm_dump_ptrs *fw_error_dump;
+ const struct fw_img *img;
+ u32 sram_len, sram_ofs;
+ u32 file_len, rxf_len;
+ unsigned long flags;
+ int reg_val;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ if (mvm->fw_error_dump)
+ return;
+
+ fw_error_dump = kzalloc(sizeof(*mvm->fw_error_dump), GFP_KERNEL);
+ if (!fw_error_dump)
+ return;
+
+ img = &mvm->fw->img[mvm->cur_ucode];
+ sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
+ sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
+
+ /* reading buffer size */
+ reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
+ rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
+
+ /* the register holds the value divided by 128 */
+ rxf_len = rxf_len << 7;
+
+ file_len = sizeof(*dump_file) +
+ sizeof(*dump_data) * 3 +
+ sram_len +
+ rxf_len +
+ sizeof(*dump_info);
+
+ dump_file = vzalloc(file_len);
+ if (!dump_file) {
+ kfree(fw_error_dump);
+ return;
+ }
+
+ fw_error_dump->op_mode_ptr = dump_file;
+
+ dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
+ dump_data = (void *)dump_file->data;
+
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
+ dump_data->len = cpu_to_le32(sizeof(*dump_info));
+ dump_info = (void *) dump_data->data;
+ dump_info->device_family =
+ mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
+ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
+ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
+ memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
+ sizeof(dump_info->fw_human_readable));
+ strncpy(dump_info->dev_human_readable, mvm->cfg->name,
+ sizeof(dump_info->dev_human_readable));
+ strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
+ sizeof(dump_info->bus_human_readable));
+
+ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+ dump_data->len = cpu_to_le32(rxf_len);
+
+ if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
+ u32 *rxf = (void *)dump_data->data;
+ int i;
+
+ for (i = 0; i < (rxf_len / sizeof(u32)); i++) {
+ iwl_trans_write_prph(mvm->trans,
+ RXF_LD_FENCE_OFFSET_ADDR,
+ i * sizeof(u32));
+ rxf[i] = iwl_trans_read_prph(mvm->trans,
+ RXF_FIFO_RD_FENCE_ADDR);
+ }
+ iwl_trans_release_nic_access(mvm->trans, &flags);
+ }
+
+ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
+ dump_data->len = cpu_to_le32(sram_len);
+ iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
+ sram_len);
+
+ fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
+ fw_error_dump->op_mode_len = file_len;
+ if (fw_error_dump->trans_ptr)
+ file_len += fw_error_dump->trans_ptr->len;
+ dump_file->file_len = cpu_to_le32(file_len);
+ mvm->fw_error_dump = fw_error_dump;
}
+#endif
static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
{
@@ -665,6 +789,12 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
iwl_mvm_reset_phy_ctxts(mvm);
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
+ memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
+ memset(&mvm->last_bt_notif_old, 0, sizeof(mvm->last_bt_notif_old));
+ memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
+ memset(&mvm->last_bt_ci_cmd_old, 0, sizeof(mvm->last_bt_ci_cmd_old));
+ memset(&mvm->bt_ack_kill_msk, 0, sizeof(mvm->bt_ack_kill_msk));
+ memset(&mvm->bt_cts_kill_msk, 0, sizeof(mvm->bt_cts_kill_msk));
ieee80211_wake_queues(mvm->hw);
@@ -688,6 +818,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
iwl_mvm_restart_cleanup(mvm);
ret = iwl_mvm_up(mvm);
+
+ if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+ /* Something went wrong - we need to finish some cleanup
+ * that normally iwl_mvm_mac_restart_complete() below
+ * would do.
+ */
+ clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
+ iwl_mvm_d0i3_enable_tx(mvm, NULL);
+ }
+
mutex_unlock(&mvm->mutex);
return ret;
@@ -786,6 +926,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
int ret;
/*
+ * make sure D0i3 exit is completed, otherwise a target access
+ * during tx queue configuration could be done when still in
+ * D0i3 state.
+ */
+ ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
+ if (ret)
+ return ret;
+
+ /*
* Not much to do here. The stack will not allow interface
* types or combinations that we didn't advertise, so we
* don't really have to check the types.
@@ -899,6 +1048,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
out_unlock:
mutex_unlock(&mvm->mutex);
+ iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
+
return ret;
}
@@ -1159,8 +1310,12 @@ static void iwl_mvm_bcast_filter_iterator(void *_data, u8 *mac,
bcast_mac = &cmd->macs[mvmvif->id];
- /* enable filtering only for associated stations */
- if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc)
+ /*
+ * enable filtering only for associated stations, but not for P2P
+ * Clients
+ */
+ if (vif->type != NL80211_IFTYPE_STATION || vif->p2p ||
+ !vif->bss_conf.assoc)
return;
bcast_mac->default_discard = 1;
@@ -1237,10 +1392,6 @@ static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING))
return 0;
- /* bcast filtering isn't supported for P2P client */
- if (vif->p2p)
- return 0;
-
if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
return 0;
@@ -1255,6 +1406,28 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
}
#endif
+static void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
+{
+ struct ieee80211_sta *sta;
+ struct iwl_mvm_sta *mvmsta;
+ int i;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
+ sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
+ lockdep_is_held(&mvm->mutex));
+ if (!sta || IS_ERR(sta) || !sta->tdls)
+ continue;
+
+ mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
+ NL80211_TDLS_TEARDOWN,
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
+ GFP_KERNEL);
+ }
+}
+
static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
@@ -1278,7 +1451,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if (changes & BSS_CHANGED_ASSOC) {
if (bss_conf->assoc) {
/* add quota for this interface */
- ret = iwl_mvm_update_quotas(mvm, vif);
+ ret = iwl_mvm_update_quotas(mvm, NULL);
if (ret) {
IWL_ERR(mvm, "failed to update quotas\n");
return;
@@ -1350,14 +1523,18 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
*/
iwl_mvm_remove_time_event(mvm, mvmvif,
&mvmvif->time_event_data);
- iwl_mvm_sf_update(mvm, vif, false);
- WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
} else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
BSS_CHANGED_QOS)) {
ret = iwl_mvm_power_update_mac(mvm);
if (ret)
IWL_ERR(mvm, "failed to update power mode\n");
}
+
+ if (changes & BSS_CHANGED_BEACON_INFO) {
+ iwl_mvm_sf_update(mvm, vif, false);
+ WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
+ }
+
if (changes & BSS_CHANGED_TXPOWER) {
IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
bss_conf->txpower);
@@ -1389,6 +1566,14 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
+ /*
+ * iwl_mvm_mac_ctxt_add() might read directly from the device
+ * (the system time), so make sure it is available.
+ */
+ ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_START_AP);
+ if (ret)
+ return ret;
+
mutex_lock(&mvm->mutex);
/* Send the beacon template */
@@ -1425,7 +1610,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
/* power updated needs to be done before quotas */
iwl_mvm_power_update_mac(mvm);
- ret = iwl_mvm_update_quotas(mvm, vif);
+ ret = iwl_mvm_update_quotas(mvm, NULL);
if (ret)
goto out_quota_failed;
@@ -1437,6 +1622,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
iwl_mvm_bt_coex_vif_change(mvm);
+ /* we don't support TDLS during DCM */
+ if (iwl_mvm_phy_ctx_count(mvm) > 1)
+ iwl_mvm_teardown_tdls_peers(mvm);
+
mutex_unlock(&mvm->mutex);
return 0;
@@ -1450,6 +1639,7 @@ out_remove:
iwl_mvm_mac_ctxt_remove(mvm, vif);
out_unlock:
mutex_unlock(&mvm->mutex);
+ iwl_mvm_unref(mvm, IWL_MVM_REF_START_AP);
return ret;
}
@@ -1463,7 +1653,20 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex);
+ /* Handle AP stop while in CSA */
+ if (rcu_access_pointer(mvm->csa_vif) == vif) {
+ iwl_mvm_remove_time_event(mvm, mvmvif,
+ &mvmvif->time_event_data);
+ RCU_INIT_POINTER(mvm->csa_vif, NULL);
+ }
+
+ if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
+ RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
+ mvm->csa_tx_block_bcn_timeout = 0;
+ }
+
mvmvif->ap_ibss_active = false;
+ mvm->ap_last_beacon_gp2 = 0;
iwl_mvm_bt_coex_vif_change(mvm);
@@ -1514,10 +1717,18 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ /*
+ * iwl_mvm_bss_info_changed_station() might call
+ * iwl_mvm_protect_session(), which reads directly from
+ * the device (the system time), so make sure it is available.
+ */
+ if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_BSS_CHANGED))
+ return;
+
mutex_lock(&mvm->mutex);
if (changes & BSS_CHANGED_IDLE && !bss_conf->idle)
- iwl_mvm_sched_scan_stop(mvm, true);
+ iwl_mvm_scan_offload_stop(mvm, true);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -1533,44 +1744,84 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
}
mutex_unlock(&mvm->mutex);
+ iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
}
+static int iwl_mvm_cancel_scan_wait_notif(struct iwl_mvm *mvm,
+ enum iwl_scan_status scan_type)
+{
+ int ret;
+ bool wait_for_handlers = false;
+
+ mutex_lock(&mvm->mutex);
+
+ if (mvm->scan_status != scan_type) {
+ ret = 0;
+ /* make sure there are no pending notifications */
+ wait_for_handlers = true;
+ goto out;
+ }
+
+ switch (scan_type) {
+ case IWL_MVM_SCAN_SCHED:
+ ret = iwl_mvm_scan_offload_stop(mvm, true);
+ break;
+ case IWL_MVM_SCAN_OS:
+ ret = iwl_mvm_cancel_scan(mvm);
+ break;
+ case IWL_MVM_SCAN_NONE:
+ default:
+ WARN_ON_ONCE(1);
+ ret = -EINVAL;
+ break;
+ }
+ if (ret)
+ goto out;
+
+ wait_for_handlers = true;
+out:
+ mutex_unlock(&mvm->mutex);
+
+ /* make sure we consume the completion notification */
+ if (wait_for_handlers)
+ iwl_mvm_wait_for_async_handlers(mvm);
+
+ return ret;
+}
static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct cfg80211_scan_request *req = &hw_req->req;
int ret;
- if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
+ if (req->n_channels == 0 ||
+ req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
return -EINVAL;
+ ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_SCHED);
+ if (ret)
+ return ret;
+
mutex_lock(&mvm->mutex);
- switch (mvm->scan_status) {
- case IWL_MVM_SCAN_SCHED:
- ret = iwl_mvm_sched_scan_stop(mvm, true);
- if (ret) {
- ret = -EBUSY;
- goto out;
- }
- break;
- case IWL_MVM_SCAN_NONE:
- break;
- default:
+ if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
ret = -EBUSY;
goto out;
}
iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
- ret = iwl_mvm_scan_request(mvm, vif, req);
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
+ else
+ ret = iwl_mvm_scan_request(mvm, vif, req);
+
if (ret)
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
out:
mutex_unlock(&mvm->mutex);
- /* make sure to flush the Rx handler before the next scan arrives */
- iwl_mvm_wait_for_async_handlers(mvm);
return ret;
}
@@ -1680,6 +1931,48 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
mutex_unlock(&mvm->mutex);
}
+int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+{
+ struct ieee80211_sta *sta;
+ struct iwl_mvm_sta *mvmsta;
+ int count = 0;
+ int i;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
+ sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
+ lockdep_is_held(&mvm->mutex));
+ if (!sta || IS_ERR(sta) || !sta->tdls)
+ continue;
+
+ if (vif) {
+ mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ if (mvmsta->vif != vif)
+ continue;
+ }
+
+ count++;
+ }
+
+ return count;
+}
+
+static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ bool sta_added)
+{
+ int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);
+
+ /*
+ * Disable ps when the first TDLS sta is added and re-enable it
+ * when the last TDLS sta is removed
+ */
+ if ((tdls_sta_cnt == 1 && sta_added) ||
+ (tdls_sta_cnt == 0 && !sta_added))
+ iwl_mvm_power_update_mac(mvm);
+}
+
static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -1718,7 +2011,20 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
ret = -EINVAL;
goto out_unlock;
}
+
+ if (sta->tdls &&
+ (vif->p2p ||
+ iwl_mvm_tdls_sta_count(mvm, NULL) ==
+ IWL_MVM_TDLS_STA_COUNT ||
+ iwl_mvm_phy_ctx_count(mvm) > 1)) {
+ IWL_DEBUG_MAC80211(mvm, "refusing TDLS sta\n");
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
ret = iwl_mvm_add_sta(mvm, vif, sta);
+ if (sta->tdls && ret == 0)
+ iwl_mvm_recalc_tdls_state(mvm, vif, true);
} else if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_AUTH) {
/*
@@ -1736,6 +2042,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
true);
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTHORIZED) {
+
+ /* we don't support TDLS during DCM */
+ if (iwl_mvm_phy_ctx_count(mvm) > 1)
+ iwl_mvm_teardown_tdls_peers(mvm);
+
/* enable beacon filtering */
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
ret = 0;
@@ -1753,6 +2064,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
} else if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST) {
ret = iwl_mvm_rm_sta(mvm, vif, sta);
+ if (sta->tdls)
+ iwl_mvm_recalc_tdls_state(mvm, vif, false);
} else {
ret = -EIO;
}
@@ -1818,20 +2131,54 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
if (WARN_ON_ONCE(vif->bss_conf.assoc))
return;
+ /*
+ * iwl_mvm_protect_session() reads directly from the device
+ * (the system time), so make sure it is available.
+ */
+ if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX))
+ return;
+
mutex_lock(&mvm->mutex);
/* Try really hard to protect the session and hear a beacon */
iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
mutex_unlock(&mvm->mutex);
+
+ iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
+}
+
+static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
+
+ /*
+ * iwl_mvm_protect_session() reads directly from the device
+ * (the system time), so make sure it is available.
+ */
+ if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS))
+ return;
+
+ mutex_lock(&mvm->mutex);
+ /* Protect the session to hear the TDLS setup response on the channel */
+ iwl_mvm_protect_session(mvm, vif, duration, duration, 100);
+ mutex_unlock(&mvm->mutex);
+
+ iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
}
static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
+ ret = iwl_mvm_cancel_scan_wait_notif(mvm, IWL_MVM_SCAN_OS);
+ if (ret)
+ return ret;
+
mutex_lock(&mvm->mutex);
if (!iwl_mvm_is_idle(mvm)) {
@@ -1839,49 +2186,34 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
goto out;
}
- switch (mvm->scan_status) {
- case IWL_MVM_SCAN_OS:
- IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
- ret = iwl_mvm_cancel_scan(mvm);
- if (ret) {
- ret = -EBUSY;
- goto out;
- }
-
- /*
- * iwl_mvm_rx_scan_complete() will be called soon but will
- * not reset the scan status as it won't be IWL_MVM_SCAN_OS
- * any more since we queue the next scan immediately (below).
- * We make sure it is called before the next scan starts by
- * flushing the async-handlers work.
- */
- break;
- case IWL_MVM_SCAN_NONE:
- break;
- default:
+ if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
ret = -EBUSY;
goto out;
}
mvm->scan_status = IWL_MVM_SCAN_SCHED;
- ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
- if (ret)
- goto err;
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
+ ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
+ if (ret)
+ goto err;
+ }
ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
if (ret)
goto err;
- ret = iwl_mvm_sched_scan_start(mvm, req);
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
+ else
+ ret = iwl_mvm_sched_scan_start(mvm, req);
+
if (!ret)
goto out;
err:
mvm->scan_status = IWL_MVM_SCAN_NONE;
out:
mutex_unlock(&mvm->mutex);
- /* make sure to flush the Rx handler before the next scan arrives */
- iwl_mvm_wait_for_async_handlers(mvm);
return ret;
}
@@ -1892,7 +2224,7 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
int ret;
mutex_lock(&mvm->mutex);
- ret = iwl_mvm_sched_scan_stop(mvm, false);
+ ret = iwl_mvm_scan_offload_stop(mvm, false);
mutex_unlock(&mvm->mutex);
iwl_mvm_wait_for_async_handlers(mvm);
@@ -2001,6 +2333,119 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
}
+static bool iwl_mvm_rx_aux_roc(struct iwl_notif_wait_data *notif_wait,
+ struct iwl_rx_packet *pkt, void *data)
+{
+ struct iwl_mvm *mvm =
+ container_of(notif_wait, struct iwl_mvm, notif_wait);
+ struct iwl_hs20_roc_res *resp;
+ int resp_len = iwl_rx_packet_payload_len(pkt);
+ struct iwl_mvm_time_event_data *te_data = data;
+
+ if (WARN_ON(pkt->hdr.cmd != HOT_SPOT_CMD))
+ return true;
+
+ if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
+ IWL_ERR(mvm, "Invalid HOT_SPOT_CMD response\n");
+ return true;
+ }
+
+ resp = (void *)pkt->data;
+
+ IWL_DEBUG_TE(mvm,
+ "Aux ROC: Recieved response from ucode: status=%d uid=%d\n",
+ resp->status, resp->event_unique_id);
+
+ te_data->uid = le32_to_cpu(resp->event_unique_id);
+ IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
+ te_data->uid);
+
+ spin_lock_bh(&mvm->time_event_lock);
+ list_add_tail(&te_data->list, &mvm->aux_roc_te_list);
+ spin_unlock_bh(&mvm->time_event_lock);
+
+ return true;
+}
+
+#define AUX_ROC_MAX_DELAY_ON_CHANNEL 5000
+static int iwl_mvm_send_aux_roc_cmd(struct iwl_mvm *mvm,
+ struct ieee80211_channel *channel,
+ struct ieee80211_vif *vif,
+ int duration)
+{
+ int res, time_reg = DEVICE_SYSTEM_TIME_REG;
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_time_event_data *te_data = &mvmvif->hs_time_event_data;
+ static const u8 time_event_response[] = { HOT_SPOT_CMD };
+ struct iwl_notification_wait wait_time_event;
+ struct iwl_hs20_roc_req aux_roc_req = {
+ .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
+ .id_and_color =
+ cpu_to_le32(FW_CMD_ID_AND_COLOR(MAC_INDEX_AUX, 0)),
+ .sta_id_and_color = cpu_to_le32(mvm->aux_sta.sta_id),
+ /* Set the channel info data */
+ .channel_info.band = (channel->band == IEEE80211_BAND_2GHZ) ?
+ PHY_BAND_24 : PHY_BAND_5,
+ .channel_info.channel = channel->hw_value,
+ .channel_info.width = PHY_VHT_CHANNEL_MODE20,
+ /* Set the time and duration */
+ .apply_time = cpu_to_le32(iwl_read_prph(mvm->trans, time_reg)),
+ .apply_time_max_delay =
+ cpu_to_le32(MSEC_TO_TU(AUX_ROC_MAX_DELAY_ON_CHANNEL)),
+ .duration = cpu_to_le32(MSEC_TO_TU(duration)),
+ };
+
+ /* Set the node address */
+ memcpy(aux_roc_req.node_addr, vif->addr, ETH_ALEN);
+
+ te_data->vif = vif;
+ te_data->duration = duration;
+ te_data->id = HOT_SPOT_CMD;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ spin_lock_bh(&mvm->time_event_lock);
+ list_add_tail(&te_data->list, &mvm->time_event_list);
+ spin_unlock_bh(&mvm->time_event_lock);
+
+ /*
+ * Use a notification wait, which really just processes the
+ * command response and doesn't wait for anything, in order
+ * to be able to process the response and get the UID inside
+ * the RX path. Using CMD_WANT_SKB doesn't work because it
+ * stores the buffer and then wakes up this thread, by which
+ * time another notification (that the time event started)
+ * might already be processed unsuccessfully.
+ */
+ iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
+ time_event_response,
+ ARRAY_SIZE(time_event_response),
+ iwl_mvm_rx_aux_roc, te_data);
+
+ res = iwl_mvm_send_cmd_pdu(mvm, HOT_SPOT_CMD, 0, sizeof(aux_roc_req),
+ &aux_roc_req);
+
+ if (res) {
+ IWL_ERR(mvm, "Couldn't send HOT_SPOT_CMD: %d\n", res);
+ iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
+ goto out_clear_te;
+ }
+
+ /* No need to wait for anything, so just pass 1 (0 isn't valid) */
+ res = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1);
+ /* should never fail */
+ WARN_ON_ONCE(res);
+
+ if (res) {
+ out_clear_te:
+ spin_lock_bh(&mvm->time_event_lock);
+ iwl_mvm_te_clear_data(mvm, te_data);
+ spin_unlock_bh(&mvm->time_event_lock);
+ }
+
+ return res;
+}
+
static int iwl_mvm_roc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_channel *channel,
@@ -2016,8 +2461,17 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
duration, type);
- if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
- IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ /* Use aux roc framework (HS20) */
+ ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
+ vif, duration);
+ return ret;
+ case NL80211_IFTYPE_P2P_DEVICE:
+ /* handle below */
+ break;
+ default:
+ IWL_ERR(mvm, "vif isn't P2P_DEVICE: %d\n", vif->type);
return -EINVAL;
}
@@ -2126,17 +2580,17 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
return 0;
}
-static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
- struct ieee80211_chanctx_conf *ctx)
+static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
+ struct ieee80211_chanctx_conf *ctx)
{
- struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
struct iwl_mvm_phy_ctxt *phy_ctxt;
int ret;
+ lockdep_assert_held(&mvm->mutex);
+
IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
- mutex_lock(&mvm->mutex);
phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
if (!phy_ctxt) {
ret = -ENOSPC;
@@ -2154,19 +2608,40 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
*phy_ctxt_id = phy_ctxt->id;
out:
+ return ret;
+}
+
+static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_chanctx_conf *ctx)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ int ret;
+
+ mutex_lock(&mvm->mutex);
+ ret = __iwl_mvm_add_chanctx(mvm, ctx);
mutex_unlock(&mvm->mutex);
+
return ret;
}
+static void __iwl_mvm_remove_chanctx(struct iwl_mvm *mvm,
+ struct ieee80211_chanctx_conf *ctx)
+{
+ u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
+ struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
+
+ lockdep_assert_held(&mvm->mutex);
+
+ iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
+}
+
static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
- struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
mutex_lock(&mvm->mutex);
- iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
+ __iwl_mvm_remove_chanctx(mvm, ctx);
mutex_unlock(&mvm->mutex);
}
@@ -2195,17 +2670,17 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
mutex_unlock(&mvm->mutex);
}
-static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_chanctx_conf *ctx)
+static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *ctx,
+ bool switching_chanctx)
{
- struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
- mutex_lock(&mvm->mutex);
+ lockdep_assert_held(&mvm->mutex);
mvmvif->phy_ctxt = phy_ctxt;
@@ -2222,18 +2697,18 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
* (in bss_info_changed), similarly for IBSS.
*/
ret = 0;
- goto out_unlock;
+ goto out;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
break;
default:
ret = -EINVAL;
- goto out_unlock;
+ goto out;
}
ret = iwl_mvm_binding_add_vif(mvm, vif);
if (ret)
- goto out_unlock;
+ goto out;
/*
* Power state must be updated before quotas,
@@ -2247,67 +2722,168 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
*/
if (vif->type == NL80211_IFTYPE_MONITOR) {
mvmvif->monitor_active = true;
- ret = iwl_mvm_update_quotas(mvm, vif);
+ ret = iwl_mvm_update_quotas(mvm, NULL);
if (ret)
goto out_remove_binding;
}
/* Handle binding during CSA */
- if (vif->type == NL80211_IFTYPE_AP) {
- iwl_mvm_update_quotas(mvm, vif);
+ if ((vif->type == NL80211_IFTYPE_AP) ||
+ (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) {
+ iwl_mvm_update_quotas(mvm, NULL);
iwl_mvm_mac_ctxt_changed(mvm, vif, false);
}
- goto out_unlock;
+ goto out;
- out_remove_binding:
+out_remove_binding:
iwl_mvm_binding_remove_vif(mvm, vif);
iwl_mvm_power_update_mac(mvm);
- out_unlock:
- mutex_unlock(&mvm->mutex);
+out:
if (ret)
mvmvif->phy_ctxt = NULL;
return ret;
}
-
-static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_chanctx_conf *ctx)
+static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *ctx)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ int ret;
mutex_lock(&mvm->mutex);
+ ret = __iwl_mvm_assign_vif_chanctx(mvm, vif, ctx, false);
+ mutex_unlock(&mvm->mutex);
+
+ return ret;
+}
+
+static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *ctx,
+ bool switching_chanctx)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct ieee80211_vif *disabled_vif = NULL;
+
+ lockdep_assert_held(&mvm->mutex);
iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
switch (vif->type) {
case NL80211_IFTYPE_ADHOC:
- goto out_unlock;
+ goto out;
case NL80211_IFTYPE_MONITOR:
mvmvif->monitor_active = false;
- iwl_mvm_update_quotas(mvm, NULL);
break;
case NL80211_IFTYPE_AP:
/* This part is triggered only during CSA */
if (!vif->csa_active || !mvmvif->ap_ibss_active)
- goto out_unlock;
+ goto out;
+
+ /* Set CS bit on all the stations */
+ iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true);
+
+ /* Save blocked iface, the timeout is set on the next beacon */
+ rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif);
mvmvif->ap_ibss_active = false;
- iwl_mvm_update_quotas(mvm, NULL);
- /*TODO: bt_coex notification here? */
+ break;
+ case NL80211_IFTYPE_STATION:
+ if (!switching_chanctx)
+ break;
+
+ disabled_vif = vif;
+
+ iwl_mvm_mac_ctxt_changed(mvm, vif, true);
+ break;
default:
break;
}
+ iwl_mvm_update_quotas(mvm, disabled_vif);
iwl_mvm_binding_remove_vif(mvm, vif);
-out_unlock:
+out:
mvmvif->phy_ctxt = NULL;
iwl_mvm_power_update_mac(mvm);
+}
+
+static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_chanctx_conf *ctx)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+ mutex_lock(&mvm->mutex);
+ __iwl_mvm_unassign_vif_chanctx(mvm, vif, ctx, false);
mutex_unlock(&mvm->mutex);
}
+static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif_chanctx_switch *vifs,
+ int n_vifs,
+ enum ieee80211_chanctx_switch_mode mode)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ int ret;
+
+ /* we only support SWAP_CONTEXTS and with a single-vif right now */
+ if (mode != CHANCTX_SWMODE_SWAP_CONTEXTS || n_vifs > 1)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&mvm->mutex);
+ __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true);
+ __iwl_mvm_remove_chanctx(mvm, vifs[0].old_ctx);
+
+ ret = __iwl_mvm_add_chanctx(mvm, vifs[0].new_ctx);
+ if (ret) {
+ IWL_ERR(mvm, "failed to add new_ctx during channel switch\n");
+ goto out_reassign;
+ }
+
+ ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].new_ctx,
+ true);
+ if (ret) {
+ IWL_ERR(mvm,
+ "failed to assign new_ctx during channel switch\n");
+ goto out_remove;
+ }
+
+ /* we don't support TDLS during DCM - can be caused by channel switch */
+ if (iwl_mvm_phy_ctx_count(mvm) > 1)
+ iwl_mvm_teardown_tdls_peers(mvm);
+
+ goto out;
+
+out_remove:
+ __iwl_mvm_remove_chanctx(mvm, vifs[0].new_ctx);
+
+out_reassign:
+ ret = __iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx);
+ if (ret) {
+ IWL_ERR(mvm, "failed to add old_ctx back after failure.\n");
+ goto out_restart;
+ }
+
+ ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx,
+ true);
+ if (ret) {
+ IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
+ goto out_restart;
+ }
+
+ goto out;
+
+out_restart:
+ /* things keep failing, better restart the hw */
+ iwl_mvm_nic_restart(mvm, false);
+
+out:
+ mutex_unlock(&mvm->mutex);
+ return ret;
+}
+
static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
bool set)
@@ -2395,15 +2971,19 @@ static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw,
struct cfg80211_chan_def *chandef)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct ieee80211_vif *csa_vif;
mutex_lock(&mvm->mutex);
- if (WARN(mvm->csa_vif && mvm->csa_vif->csa_active,
+
+ csa_vif = rcu_dereference_protected(mvm->csa_vif,
+ lockdep_is_held(&mvm->mutex));
+ if (WARN(csa_vif && csa_vif->csa_active,
"Another CSA is already in progress"))
goto out_unlock;
IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n",
chandef->center_freq1);
- mvm->csa_vif = vif;
+ rcu_assign_pointer(mvm->csa_vif, vif);
out_unlock:
mutex_unlock(&mvm->mutex);
@@ -2460,6 +3040,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
.sta_rc_update = iwl_mvm_sta_rc_update,
.conf_tx = iwl_mvm_mac_conf_tx,
.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
+ .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
.flush = iwl_mvm_mac_flush,
.sched_scan_start = iwl_mvm_mac_sched_scan_start,
.sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
@@ -2472,6 +3053,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
.change_chanctx = iwl_mvm_change_chanctx,
.assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
.unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
+ .switch_vif_chanctx = iwl_mvm_switch_vif_chanctx,
.start_ap = iwl_mvm_start_ap_ibss,
.stop_ap = iwl_mvm_stop_ap_ibss,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fcc6c29482d0..2e73d3bd7757 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -82,6 +82,26 @@
/* RSSI offset for WkP */
#define IWL_RSSI_OFFSET 50
#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8
+/* A TimeUnit is 1024 microsecond */
+#define MSEC_TO_TU(_msec) (_msec*1000/1024)
+
+/*
+ * The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0"
+ * TBTT. This value should be big enough to ensure that we switch in time.
+ */
+#define IWL_MVM_CHANNEL_SWITCH_TIME 40
+
+/*
+ * This value (in TUs) is used to fine tune the CSA NoA end time which should
+ * be just before "beacon 0" TBTT.
+ */
+#define IWL_MVM_CHANNEL_SWITCH_MARGIN 4
+
+/*
+ * Number of beacons to transmit on a new channel until we unblock tx to
+ * the stations, even if we didn't identify them on a new channel
+ */
+#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3
enum iwl_mvm_tx_fifo {
IWL_MVM_TX_FIFO_BK = 0,
@@ -108,6 +128,21 @@ struct iwl_mvm_mod_params {
};
extern struct iwl_mvm_mod_params iwlmvm_mod_params;
+/**
+ * struct iwl_mvm_dump_ptrs - set of pointers needed for the fw-error-dump
+ *
+ * @op_mode_ptr: pointer to the buffer coming from the mvm op_mode
+ * @trans_ptr: pointer to struct %iwl_trans_dump_data which contains the
+ * transport's data.
+ * @trans_len: length of the valid data in trans_ptr
+ * @op_mode_len: length of the valid data in op_mode_ptr
+ */
+struct iwl_mvm_dump_ptrs {
+ struct iwl_trans_dump_data *trans_ptr;
+ void *op_mode_ptr;
+ u32 op_mode_len;
+};
+
struct iwl_mvm_phy_ctxt {
u16 id;
u16 color;
@@ -230,11 +265,30 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_USER,
IWL_MVM_REF_TX,
IWL_MVM_REF_TX_AGG,
+ IWL_MVM_REF_ADD_IF,
+ IWL_MVM_REF_START_AP,
+ IWL_MVM_REF_BSS_CHANGED,
+ IWL_MVM_REF_PREPARE_TX,
+ IWL_MVM_REF_PROTECT_TDLS,
+ IWL_MVM_REF_CHECK_CTKILL,
+ IWL_MVM_REF_PRPH_READ,
+ IWL_MVM_REF_PRPH_WRITE,
+ IWL_MVM_REF_NMI,
+ IWL_MVM_REF_TM_CMD,
IWL_MVM_REF_EXIT_WORK,
IWL_MVM_REF_COUNT,
};
+enum iwl_bt_force_ant_mode {
+ BT_FORCE_ANT_DIS = 0,
+ BT_FORCE_ANT_AUTO,
+ BT_FORCE_ANT_BT,
+ BT_FORCE_ANT_WIFI,
+
+ BT_FORCE_ANT_MAX,
+};
+
/**
* struct iwl_mvm_vif_bf_data - beacon filtering related data
* @bf_enabled: indicates if beacon filtering is enabled
@@ -299,6 +353,7 @@ struct iwl_mvm_vif {
*/
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
struct iwl_mvm_time_event_data time_event_data;
+ struct iwl_mvm_time_event_data hs_time_event_data;
struct iwl_mvm_int_sta bcast_sta;
@@ -523,7 +578,7 @@ struct iwl_mvm {
/* Scan status, cmd (pre-allocated) and auxiliary station */
enum iwl_scan_status scan_status;
- struct iwl_scan_cmd *scan_cmd;
+ void *scan_cmd;
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
/* rx chain antennas set through debugfs for the scan command */
@@ -578,18 +633,15 @@ struct iwl_mvm {
*/
unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
- /* A bitmap of reference types taken by the driver. */
- unsigned long ref_bitmap[BITS_TO_LONGS(IWL_MVM_REF_COUNT)];
+ /* references taken by the driver and spinlock protecting them */
+ spinlock_t refs_lock;
+ u8 refs[IWL_MVM_REF_COUNT];
u8 vif_count;
/* -1 for always, 0 for never, >0 for that many times */
s8 restart_fw;
- void *fw_error_dump;
- void *fw_error_sram;
- u32 fw_error_sram_len;
- u32 *fw_error_rxf;
- u32 fw_error_rxf_len;
+ struct iwl_mvm_dump_ptrs *fw_error_dump;
#ifdef CONFIG_IWLWIFI_LEDS
struct led_classdev led;
@@ -623,12 +675,21 @@ struct iwl_mvm {
wait_queue_head_t d0i3_exit_waitq;
/* BT-Coex */
- u8 bt_kill_msk;
+ u8 bt_ack_kill_msk[NUM_PHY_CTX];
+ u8 bt_cts_kill_msk[NUM_PHY_CTX];
+
+ struct iwl_bt_coex_profile_notif_old last_bt_notif_old;
+ struct iwl_bt_coex_ci_cmd_old last_bt_ci_cmd_old;
struct iwl_bt_coex_profile_notif last_bt_notif;
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
+
u32 last_ant_isol;
u8 last_corun_lut;
u8 bt_tx_prio;
+ enum iwl_bt_force_ant_mode bt_force_ant_mode;
+
+ /* Aux ROC */
+ struct list_head aux_roc_te_list;
/* Thermal Throttling and CTkill */
struct iwl_mvm_tt_mgmt thermal_throttle;
@@ -647,7 +708,12 @@ struct iwl_mvm {
/* Indicate if device power save is allowed */
bool ps_disabled;
- struct ieee80211_vif *csa_vif;
+ struct ieee80211_vif __rcu *csa_vif;
+ struct ieee80211_vif __rcu *csa_tx_blocked_vif;
+ u8 csa_tx_block_bcn_timeout;
+
+ /* system time of last beacon (for AP/GO interface) */
+ u32 ap_last_beacon_gp2;
};
/* Extract MVM priv from op_mode and _hw */
@@ -663,6 +729,7 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_ROC_RUNNING,
IWL_MVM_STATUS_IN_HW_RESTART,
IWL_MVM_STATUS_IN_D0I3,
+ IWL_MVM_STATUS_ROC_AUX_RUNNING,
};
static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
@@ -719,11 +786,6 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
struct ieee80211_tx_rate *r);
u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
-void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm);
-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm);
-#endif
u8 first_antenna(u8 mask);
u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
@@ -809,6 +871,7 @@ void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *ctxt);
void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *ctxt);
+int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm);
/* MAC (virtual interface) programming */
int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -835,7 +898,8 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
/* Quota management */
-int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif);
+int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
+ struct ieee80211_vif *disabled_vif);
/* Scanning */
int iwl_mvm_scan_request(struct iwl_mvm *mvm,
@@ -854,15 +918,24 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
struct cfg80211_sched_scan_request *req);
int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
struct cfg80211_sched_scan_request *req);
-int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify);
-int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
- struct iwl_rx_cmd_buffer *rxb,
- struct iwl_device_cmd *cmd);
+int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify);
+int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd);
+
+/* Unified scan */
+int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_scan_request *req);
+int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_scan_ies *ies);
/* MVM debugfs */
#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -948,6 +1021,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
/* D0i3 */
void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
+int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
@@ -963,19 +1037,40 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
+bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm);
bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
enum ieee80211_band band);
u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *info, u8 ac);
+bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm);
+void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm);
+int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm);
+int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd);
+void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ enum ieee80211_rssi_event rssi_event);
+u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta);
+bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta);
+bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
+ enum ieee80211_band band);
+int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd);
+
enum iwl_bt_kill_msk {
BT_KILL_MSK_DEFAULT,
- BT_KILL_MSK_SCO_HID_A2DP,
- BT_KILL_MSK_REDUCED_TXPOW,
+ BT_KILL_MSK_NEVER,
+ BT_KILL_MSK_ALWAYS,
BT_KILL_MSK_MAX,
};
-extern const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX];
-extern const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX];
+
+extern const u8 iwl_bt_ack_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT];
+extern const u8 iwl_bt_cts_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT];
+extern const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX];
/* beacon filtering */
#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -1039,4 +1134,9 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
bool added_vif);
+/* TDLS */
+int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+
+void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
+
#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 808f78f6fbf9..cfdd314fdd5d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -69,7 +69,9 @@
/* Default NVM size to read */
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
-#define IWL_MAX_NVM_SECTION_SIZE 7000
+#define IWL_MAX_NVM_SECTION_SIZE 0x1b58
+#define IWL_MAX_NVM_8000A_SECTION_SIZE 0xffc
+#define IWL_MAX_NVM_8000B_SECTION_SIZE 0x1ffc
#define NVM_WRITE_OPCODE 1
#define NVM_READ_OPCODE 0
@@ -219,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
* without overflowing, so no check is needed.
*/
static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
- u8 *data)
+ u8 *data, u32 size_read)
{
u16 length, offset = 0;
int ret;
@@ -231,6 +233,13 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
/* Read the NVM until exhausted (reading less than requested) */
while (ret == length) {
+ /* Check no memory assumptions fail and cause an overflow */
+ if ((size_read + offset + length) >
+ mvm->cfg->base_params->eeprom_size) {
+ IWL_ERR(mvm, "EEPROM size is too small for NVM\n");
+ return -ENOBUFS;
+ }
+
ret = iwl_nvm_read_chunk(mvm, section, offset, length, data);
if (ret < 0) {
IWL_DEBUG_EEPROM(mvm->trans->dev,
@@ -256,7 +265,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
- IWL_ERR(mvm, "Can't parse empty NVM sections\n");
+ IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n");
return NULL;
}
} else {
@@ -264,7 +273,7 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
!mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
IWL_ERR(mvm,
- "Can't parse empty family 8000 NVM sections\n");
+ "Can't parse empty family 8000 OTP/NVM sections\n");
return NULL;
}
/* MAC_OVERRIDE or at least HW section must exist */
@@ -326,6 +335,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
u8 data[];
} *file_sec;
const u8 *eof, *temp;
+ int max_section_size;
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD2_ID(x) (x >> 12)
@@ -334,6 +344,14 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
+ /* Maximal size depends on HW family and step */
+ if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
+ max_section_size = IWL_MAX_NVM_SECTION_SIZE;
+ else if ((mvm->trans->hw_rev & 0xc) == 0) /* Family 8000 A-step */
+ max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE;
+ else /* Family 8000 B-step */
+ max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE;
+
/*
* Obtain NVM image via request_firmware. Since we already used
* request_firmware_nowait() for the firmware binary load and only
@@ -392,7 +410,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
le16_to_cpu(file_sec->word1));
}
- if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
+ if (section_size > max_section_size) {
IWL_ERR(mvm, "ERROR - section too large (%d)\n",
section_size);
ret = -EINVAL;
@@ -459,6 +477,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
{
int ret, section;
+ u32 size_read = 0;
u8 *nvm_buffer, *temp;
if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
@@ -475,9 +494,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
return -ENOMEM;
for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
/* we override the constness for initial read */
- ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
+ ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
+ size_read);
if (ret < 0)
continue;
+ size_read += ret;
temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
if (!temp) {
ret = -ENOMEM;
@@ -509,6 +530,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
}
#endif
}
+ if (!size_read)
+ IWL_ERR(mvm, "OTP is blank\n");
kfree(nvm_buffer);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index cc2f7de396de..610dbcb0dc27 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -166,8 +166,15 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
WARN_ON((radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE) &
~CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE);
- /* silicon bits */
- reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
+ /*
+ * TODO: Bits 7-8 of CSR in 8000 HW family set the ADC sampling, and
+ * shouldn't be set to any non-zero value. The same is supposed to be
+ * true of the other HW, but unsetting them (such as the 7260) causes
+ * automatic tests to fail on seemingly unrelated errors. Need to
+ * further investigate this, but for now we'll separate cases.
+ */
+ if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
+ reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
@@ -233,7 +240,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
iwl_mvm_rx_scan_offload_complete_notif, true),
- RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
+ RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
false),
RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
@@ -282,8 +289,10 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(MATCH_FOUND_NOTIFICATION),
CMD(SCAN_OFFLOAD_REQUEST_CMD),
CMD(SCAN_OFFLOAD_ABORT_CMD),
+ CMD(HOT_SPOT_CMD),
CMD(SCAN_OFFLOAD_COMPLETE),
CMD(SCAN_OFFLOAD_UPDATE_PROFILES_CMD),
+ CMD(SCAN_ITERATION_COMPLETE),
CMD(POWER_TABLE_CMD),
CMD(WEP_KEY),
CMD(REPLY_RX_PHY_CMD),
@@ -324,6 +333,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(REPLY_THERMAL_MNG_BACKOFF),
CMD(MAC_PM_POWER_TABLE),
CMD(BT_COEX_CI),
+ CMD(BT_COEX_UPDATE_SW_BOOST),
+ CMD(BT_COEX_UPDATE_CORUN_LUT),
+ CMD(BT_COEX_UPDATE_REDUCED_TXP),
CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
CMD(ANTENNA_COUPLING_NOTIFICATION),
};
@@ -380,6 +392,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
if (!hw)
return NULL;
+ if (cfg->max_rx_agg_size)
+ hw->max_rx_aggregation_subframes = cfg->max_rx_agg_size;
+
op_mode = hw->priv;
op_mode->ops = &iwl_mvm_ops;
@@ -405,6 +420,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mutex_init(&mvm->d0i3_suspend_mutex);
spin_lock_init(&mvm->async_handlers_lock);
INIT_LIST_HEAD(&mvm->time_event_list);
+ INIT_LIST_HEAD(&mvm->aux_roc_te_list);
INIT_LIST_HEAD(&mvm->async_handlers_list);
spin_lock_init(&mvm->time_event_lock);
@@ -414,6 +430,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
spin_lock_init(&mvm->d0i3_tx_lock);
+ spin_lock_init(&mvm->refs_lock);
skb_queue_head_init(&mvm->d0i3_tx);
init_waitqueue_head(&mvm->d0i3_exit_waitq);
@@ -502,9 +519,17 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
}
}
- scan_size = sizeof(struct iwl_scan_cmd) +
- mvm->fw->ucode_capa.max_probe_length +
- (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel));
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ scan_size = sizeof(struct iwl_scan_req_unified_lmac) +
+ sizeof(struct iwl_scan_channel_cfg_lmac) *
+ mvm->fw->ucode_capa.n_scan_channels +
+ sizeof(struct iwl_scan_probe_req);
+ else
+ scan_size = sizeof(struct iwl_scan_cmd) +
+ mvm->fw->ucode_capa.max_probe_length +
+ mvm->fw->ucode_capa.n_scan_channels *
+ sizeof(struct iwl_scan_channel);
+
mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL);
if (!mvm->scan_cmd)
goto out_free;
@@ -520,7 +545,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
/* rpm starts with a taken ref. only set the appropriate bit here. */
- set_bit(IWL_MVM_REF_UCODE_DOWN, mvm->ref_bitmap);
+ mvm->refs[IWL_MVM_REF_UCODE_DOWN] = 1;
return op_mode;
@@ -548,9 +573,11 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
ieee80211_unregister_hw(mvm->hw);
kfree(mvm->scan_cmd);
- vfree(mvm->fw_error_dump);
- kfree(mvm->fw_error_sram);
- kfree(mvm->fw_error_rxf);
+ if (mvm->fw_error_dump) {
+ vfree(mvm->fw_error_dump->op_mode_ptr);
+ vfree(mvm->fw_error_dump->trans_ptr);
+ kfree(mvm->fw_error_dump);
+ }
kfree(mvm->mcast_filter_cmd);
mvm->mcast_filter_cmd = NULL;
@@ -754,7 +781,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
module_put(THIS_MODULE);
}
-static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
+void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
{
iwl_abort_notification_waits(&mvm->notif_wait);
@@ -811,93 +838,24 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
reprobe->dev = mvm->trans->dev;
INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
schedule_work(&reprobe->work);
- } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && mvm->restart_fw) {
+ } else if (mvm->cur_ucode == IWL_UCODE_REGULAR &&
+ (!fw_error || mvm->restart_fw)) {
/* don't let the transport/FW power down */
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
- if (mvm->restart_fw > 0)
+ if (fw_error && mvm->restart_fw > 0)
mvm->restart_fw--;
ieee80211_restart_hw(mvm->hw);
}
}
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
-{
- struct iwl_fw_error_dump_file *dump_file;
- struct iwl_fw_error_dump_data *dump_data;
- u32 file_len;
- u32 trans_len;
-
- lockdep_assert_held(&mvm->mutex);
-
- if (mvm->fw_error_dump)
- return;
-
- file_len = mvm->fw_error_sram_len +
- mvm->fw_error_rxf_len +
- sizeof(*dump_file) +
- sizeof(*dump_data) * 2;
-
- trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
- if (trans_len)
- file_len += trans_len;
-
- dump_file = vmalloc(file_len);
- if (!dump_file)
- return;
-
- mvm->fw_error_dump = dump_file;
-
- dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
- dump_file->file_len = cpu_to_le32(file_len);
- dump_data = (void *)dump_file->data;
- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
- dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
- memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
-
- dump_data = iwl_mvm_fw_error_next_data(dump_data);
- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
- dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
-
- /*
- * No need for lock since at the stage the FW isn't loaded. So it
- * can't assert - we are the only one who can possibly be accessing
- * mvm->fw_error_sram right now.
- */
- memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
-
- kfree(mvm->fw_error_rxf);
- mvm->fw_error_rxf = NULL;
- mvm->fw_error_rxf_len = 0;
-
- kfree(mvm->fw_error_sram);
- mvm->fw_error_sram = NULL;
- mvm->fw_error_sram_len = 0;
-
- if (trans_len) {
- void *buf = iwl_mvm_fw_error_next_data(dump_data);
- u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
- trans_len);
- dump_data = (void *)((u8 *)buf + real_trans_len);
- dump_file->file_len =
- cpu_to_le32(file_len - trans_len + real_trans_len);
- }
-}
-#endif
-
static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
iwl_mvm_dump_nic_error_log(mvm);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- iwl_mvm_fw_error_sram_dump(mvm);
- iwl_mvm_fw_error_rxf_dump(mvm);
-#endif
-
- iwl_mvm_nic_restart(mvm);
+ iwl_mvm_nic_restart(mvm, true);
}
static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
@@ -905,7 +863,7 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
WARN_ON(1);
- iwl_mvm_nic_restart(mvm);
+ iwl_mvm_nic_restart(mvm, true);
}
struct iwl_d0i3_iter_data {
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 539f3a942d43..6cc243f7cf60 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -261,3 +261,29 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
ctxt->ref--;
}
+
+static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ unsigned long *data = _data;
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ if (!mvmvif->phy_ctxt)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_STATION ||
+ vif->type == NL80211_IFTYPE_AP)
+ __set_bit(mvmvif->phy_ctxt->id, data);
+}
+
+int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm)
+{
+ unsigned long phy_ctxt_counter = 0;
+
+ ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+ IEEE80211_IFACE_ITER_NORMAL,
+ iwl_mvm_binding_iterator,
+ &phy_ctxt_counter);
+
+ return hweight8(phy_ctxt_counter);
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index c182a8baf685..2b2d10800a55 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -246,30 +246,10 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
}
-static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- unsigned long *data = _data;
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-
- if (!mvmvif->phy_ctxt)
- return;
-
- if (vif->type == NL80211_IFTYPE_STATION ||
- vif->type == NL80211_IFTYPE_AP)
- __set_bit(mvmvif->phy_ctxt->id, data);
-}
-
static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- unsigned long phy_ctxt_counter = 0;
-
- ieee80211_iterate_active_interfaces_atomic(mvm->hw,
- IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_binding_iterator,
- &phy_ctxt_counter);
if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
ETH_ALEN))
@@ -291,7 +271,7 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
* Avoid using uAPSD if client is in DCM -
* low latency issue in Miracast
*/
- if (hweight8(phy_ctxt_counter) >= 2)
+ if (iwl_mvm_phy_ctx_count(mvm) >= 2)
return false;
return true;
@@ -503,6 +483,7 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
}
struct iwl_power_vifs {
+ struct iwl_mvm *mvm;
struct ieee80211_vif *bf_vif;
struct ieee80211_vif *bss_vif;
struct ieee80211_vif *p2p_vif;
@@ -512,6 +493,8 @@ struct iwl_power_vifs {
bool bss_active;
bool ap_active;
bool monitor_active;
+ bool bss_tdls;
+ bool p2p_tdls;
};
static void iwl_mvm_power_iterator(void *_data, u8 *mac,
@@ -548,6 +531,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
/* only a single MAC of the same type */
WARN_ON(power_iterator->p2p_vif);
power_iterator->p2p_vif = vif;
+ power_iterator->p2p_tdls =
+ !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
if (mvmvif->phy_ctxt)
if (mvmvif->phy_ctxt->id < MAX_PHYS)
power_iterator->p2p_active = true;
@@ -557,6 +542,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
/* only a single MAC of the same type */
WARN_ON(power_iterator->bss_vif);
power_iterator->bss_vif = vif;
+ power_iterator->bss_tdls =
+ !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
if (mvmvif->phy_ctxt)
if (mvmvif->phy_ctxt->id < MAX_PHYS)
power_iterator->bss_active = true;
@@ -599,13 +586,15 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
/* enable PM on bss if bss stand alone */
- if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) {
+ if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active &&
+ !vifs->bss_tdls) {
bss_mvmvif->pm_enabled = true;
return;
}
/* enable PM on p2p if p2p stand alone */
- if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) {
+ if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active &&
+ !vifs->p2p_tdls) {
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
p2p_mvmvif->pm_enabled = true;
return;
@@ -831,7 +820,9 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
{
struct iwl_mvm_vif *mvmvif;
- struct iwl_power_vifs vifs = {};
+ struct iwl_power_vifs vifs = {
+ .mvm = mvm,
+ };
bool ba_enable;
int ret;
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index ba68d7b84505..4e20b3ce2b6a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -73,7 +73,7 @@ struct iwl_mvm_quota_iterator_data {
int colors[MAX_BINDINGS];
int low_latency[MAX_BINDINGS];
int n_low_latency_bindings;
- struct ieee80211_vif *new_vif;
+ struct ieee80211_vif *disabled_vif;
};
static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
@@ -83,13 +83,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
u16 id;
- /*
- * We'll account for the new interface (if any) below,
- * skip it here in case we're not called from within
- * the add_interface callback (otherwise it won't show
- * up in iteration)
- */
- if (vif == data->new_vif)
+ /* skip disabled interfaces here immediately */
+ if (vif == data->disabled_vif)
return;
if (!mvmvif->phy_ctxt)
@@ -104,11 +99,6 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
if (WARN_ON_ONCE(id >= MAX_BINDINGS))
return;
- if (data->colors[id] < 0)
- data->colors[id] = mvmvif->phy_ctxt->color;
- else
- WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
-
switch (vif->type) {
case NL80211_IFTYPE_STATION:
if (vif->bss_conf.assoc)
@@ -130,6 +120,11 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
return;
}
+ if (data->colors[id] < 0)
+ data->colors[id] = mvmvif->phy_ctxt->color;
+ else
+ WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
+
data->n_interfaces[id]++;
if (iwl_mvm_vif_low_latency(mvmvif) && !data->low_latency[id]) {
@@ -171,14 +166,15 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
#endif
}
-int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
+int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
+ struct ieee80211_vif *disabled_vif)
{
struct iwl_time_quota_cmd cmd = {};
int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat;
struct iwl_mvm_quota_iterator_data data = {
.n_interfaces = {},
.colors = { -1, -1, -1, -1 },
- .new_vif = newvif,
+ .disabled_vif = disabled_vif,
};
lockdep_assert_held(&mvm->mutex);
@@ -193,10 +189,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_quota_iterator, &data);
- if (newvif) {
- data.new_vif = NULL;
- iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
- }
/*
* The FW's scheduling session consists of
@@ -285,6 +277,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
iwl_mvm_adjust_quota_for_noa(mvm, &cmd);
+ /* check that we have non-zero quota for all valid bindings */
+ for (i = 0; i < MAX_BINDINGS; i++) {
+ if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
+ continue;
+ WARN_ONCE(cmd.quotas[i].quota == 0,
+ "zero quota on binding %d\n", i);
+ }
+
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
sizeof(cmd), &cmd);
if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 306a6caa4868..c70e959bf0e3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -927,7 +927,7 @@ static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
u8 low;
u16 high_low;
u16 rate_mask;
- struct iwl_mvm *mvm = lq_sta->drv;
+ struct iwl_mvm *mvm = lq_sta->pers.drv;
rate_mask = rs_get_supported_rates(lq_sta, rate);
high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask,
@@ -946,7 +946,7 @@ static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
struct rs_rate *rate)
{
- struct iwl_mvm *mvm = lq_sta->drv;
+ struct iwl_mvm *mvm = lq_sta->pers.drv;
if (is_legacy(rate)) {
/* No column to downgrade from Legacy */
@@ -1026,14 +1026,14 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
if (!lq_sta) {
IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
return;
- } else if (!lq_sta->drv) {
+ } else if (!lq_sta->pers.drv) {
IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
return;
}
#ifdef CONFIG_MAC80211_DEBUGFS
/* Disable last tx check if we are debugging with fixed rate */
- if (lq_sta->dbg_fixed_rate) {
+ if (lq_sta->pers.dbg_fixed_rate) {
IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
return;
}
@@ -1405,7 +1405,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
int flush_interval_passed = 0;
struct iwl_mvm *mvm;
- mvm = lq_sta->drv;
+ mvm = lq_sta->pers.drv;
active_tbl = lq_sta->active_tbl;
tbl = &(lq_sta->lq_info[active_tbl]);
@@ -1865,11 +1865,11 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE;
#ifdef CONFIG_MAC80211_DEBUGFS
- if (lq_sta->dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) {
+ if (lq_sta->pers.dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) {
IWL_DEBUG_RATE(mvm, "fixed tpc: %d\n",
- lq_sta->dbg_fixed_txp_reduction);
- lq_sta->lq.reduced_tpc = lq_sta->dbg_fixed_txp_reduction;
- return cur != lq_sta->dbg_fixed_txp_reduction;
+ lq_sta->pers.dbg_fixed_txp_reduction);
+ lq_sta->lq.reduced_tpc = lq_sta->pers.dbg_fixed_txp_reduction;
+ return cur != lq_sta->pers.dbg_fixed_txp_reduction;
}
#endif
@@ -2382,7 +2382,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
}
/* Treat uninitialized rate scaling data same as non-existing. */
- if (lq_sta && !lq_sta->drv) {
+ if (lq_sta && !lq_sta->pers.drv) {
IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
mvm_sta = NULL;
}
@@ -2401,12 +2401,18 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
gfp_t gfp)
{
struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
- struct iwl_op_mode *op_mode __maybe_unused =
- (struct iwl_op_mode *)mvm_rate;
- struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
+ struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+ struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
+ lq_sta->pers.drv = mvm;
+#ifdef CONFIG_MAC80211_DEBUGFS
+ lq_sta->pers.dbg_fixed_rate = 0;
+ lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;
+#endif
+
return &sta_priv->lq_sta;
}
@@ -2552,7 +2558,9 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
lq_sta = &sta_priv->lq_sta;
- memset(lq_sta, 0, sizeof(*lq_sta));
+
+ /* clear all non-persistent lq data */
+ memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
sband = hw->wiphy->bands[band];
@@ -2630,17 +2638,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
/* as default allow aggregation for all tids */
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
- lq_sta->drv = mvm;
/* Set last_txrate_idx to lowest rate */
lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
if (sband->band == IEEE80211_BAND_5GHZ)
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_agg = 0;
-#ifdef CONFIG_MAC80211_DEBUGFS
- lq_sta->dbg_fixed_rate = 0;
- lq_sta->dbg_fixed_txp_reduction = TPC_INVALID;
-#endif
#ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
#endif
@@ -2811,12 +2814,12 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
u8 ant = initial_rate->ant;
#ifdef CONFIG_MAC80211_DEBUGFS
- if (lq_sta->dbg_fixed_rate) {
+ if (lq_sta->pers.dbg_fixed_rate) {
rs_build_rates_table_from_fixed(mvm, lq_cmd,
lq_sta->band,
- lq_sta->dbg_fixed_rate);
+ lq_sta->pers.dbg_fixed_rate);
lq_cmd->reduced_tpc = 0;
- ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
+ ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
RATE_MCS_ANT_POS;
} else
#endif
@@ -2926,14 +2929,14 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
- lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
+ lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate);
- if (lq_sta->dbg_fixed_rate) {
+ if (lq_sta->pers.dbg_fixed_rate) {
struct rs_rate rate;
- rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate,
+ rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate,
lq_sta->band, &rate);
rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
- iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
+ iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false);
}
}
@@ -2946,16 +2949,16 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
size_t buf_size;
u32 parsed_rate;
- mvm = lq_sta->drv;
+ mvm = lq_sta->pers.drv;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x", &parsed_rate) == 1)
- lq_sta->dbg_fixed_rate = parsed_rate;
+ lq_sta->pers.dbg_fixed_rate = parsed_rate;
else
- lq_sta->dbg_fixed_rate = 0;
+ lq_sta->pers.dbg_fixed_rate = 0;
rs_program_fix_rate(mvm, lq_sta);
@@ -2974,7 +2977,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
struct iwl_mvm *mvm;
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
struct rs_rate *rate = &tbl->rate;
- mvm = lq_sta->drv;
+ mvm = lq_sta->pers.drv;
buff = kmalloc(2048, GFP_KERNEL);
if (!buff)
return -ENOMEM;
@@ -2984,7 +2987,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->total_failed, lq_sta->total_success,
lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
- lq_sta->dbg_fixed_rate);
+ lq_sta->pers.dbg_fixed_rate);
desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
(mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "",
(mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "",
@@ -3182,31 +3185,20 @@ static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {
static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
{
struct iwl_lq_sta *lq_sta = mvm_sta;
- lq_sta->rs_sta_dbgfs_scale_table_file =
- debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
- lq_sta, &rs_sta_dbgfs_scale_table_ops);
- lq_sta->rs_sta_dbgfs_stats_table_file =
- debugfs_create_file("rate_stats_table", S_IRUSR, dir,
- lq_sta, &rs_sta_dbgfs_stats_table_ops);
- lq_sta->rs_sta_dbgfs_drv_tx_stats_file =
- debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir,
- lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops);
- lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
- debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
- &lq_sta->tx_agg_tid_en);
- lq_sta->rs_sta_dbgfs_reduced_txp_file =
- debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
- &lq_sta->dbg_fixed_txp_reduction);
+ debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
+ lq_sta, &rs_sta_dbgfs_scale_table_ops);
+ debugfs_create_file("rate_stats_table", S_IRUSR, dir,
+ lq_sta, &rs_sta_dbgfs_stats_table_ops);
+ debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir,
+ lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops);
+ debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
+ &lq_sta->tx_agg_tid_en);
+ debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
+ &lq_sta->pers.dbg_fixed_txp_reduction);
}
static void rs_remove_debugfs(void *mvm, void *mvm_sta)
{
- struct iwl_lq_sta *lq_sta = mvm_sta;
- debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_drv_tx_stats_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_reduced_txp_file);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 374a83d7db25..f27b9d687a25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -349,16 +349,6 @@ struct iwl_lq_sta {
struct iwl_lq_cmd lq;
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
u8 tx_agg_tid_en;
-#ifdef CONFIG_MAC80211_DEBUGFS
- struct dentry *rs_sta_dbgfs_scale_table_file;
- struct dentry *rs_sta_dbgfs_stats_table_file;
- struct dentry *rs_sta_dbgfs_drv_tx_stats_file;
- struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
- struct dentry *rs_sta_dbgfs_reduced_txp_file;
- u32 dbg_fixed_rate;
- u8 dbg_fixed_txp_reduction;
-#endif
- struct iwl_mvm *drv;
/* used to be in sta_info */
int last_txrate_idx;
@@ -369,6 +359,15 @@ struct iwl_lq_sta {
/* tx power reduce for this sta */
int tpc_reduce;
+
+ /* persistent fields - initialized only once - keep last! */
+ struct {
+#ifdef CONFIG_MAC80211_DEBUGFS
+ u32 dbg_fixed_rate;
+ u8 dbg_fixed_txp_reduction;
+#endif
+ struct iwl_mvm *drv;
+ } pers;
};
/* Initialize station's rate scaling information after adding station */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index cf7276967acd..4b98987fc413 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -259,6 +259,23 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
memset(&rx_status, 0, sizeof(rx_status));
/*
+ * We have tx blocked stations (with CS bit). If we heard frames from
+ * a blocked station on a new channel we can TX to it again.
+ */
+ if (unlikely(mvm->csa_tx_block_bcn_timeout)) {
+ struct ieee80211_sta *sta;
+
+ rcu_read_lock();
+
+ sta = ieee80211_find_sta(
+ rcu_dereference(mvm->csa_tx_blocked_vif), hdr->addr2);
+ if (sta)
+ iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);
+
+ rcu_read_unlock();
+ }
+
+ /*
* drop the packet if it has failed being decrypted by HW
*/
if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 4b6c7d4bd199..004b1f5d0314 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -97,10 +97,9 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
return cpu_to_le16(rx_chain);
}
-static inline __le32
-iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req)
+static __le32 iwl_mvm_scan_rxon_flags(enum ieee80211_band band)
{
- if (req->channels[0]->band == IEEE80211_BAND_2GHZ)
+ if (band == IEEE80211_BAND_2GHZ)
return cpu_to_le32(PHY_BAND_24);
else
return cpu_to_le32(PHY_BAND_5);
@@ -130,19 +129,19 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
* request list, is not copied here, but inserted directly to the probe
* request.
*/
-static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
- struct cfg80211_scan_request *req,
- int first)
+static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
+ struct cfg80211_ssid *ssids,
+ int n_ssids, int first)
{
int fw_idx, req_idx;
- for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first;
+ for (req_idx = n_ssids - 1, fw_idx = 0; req_idx >= first;
req_idx--, fw_idx++) {
- cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
- cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
- memcpy(cmd->direct_scan[fw_idx].ssid,
- req->ssids[req_idx].ssid,
- req->ssids[req_idx].ssid_len);
+ cmd_ssid[fw_idx].id = WLAN_EID_SSID;
+ cmd_ssid[fw_idx].len = ssids[req_idx].ssid_len;
+ memcpy(cmd_ssid[fw_idx].ssid,
+ ssids[req_idx].ssid,
+ ssids[req_idx].ssid_len);
}
}
@@ -204,7 +203,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
*/
static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
int n_ssids, const u8 *ssid, int ssid_len,
- const u8 *ie, int ie_len,
+ const u8 *band_ie, int band_ie_len,
+ const u8 *common_ie, int common_ie_len,
int left)
{
int len = 0;
@@ -244,12 +244,19 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
len += ssid_len + 2;
- if (WARN_ON(left < ie_len))
+ if (WARN_ON(left < band_ie_len + common_ie_len))
return len;
- if (ie && ie_len) {
- memcpy(pos, ie, ie_len);
- len += ie_len;
+ if (band_ie && band_ie_len) {
+ memcpy(pos, band_ie, band_ie_len);
+ pos += band_ie_len;
+ len += band_ie_len;
+ }
+
+ if (common_ie && common_ie_len) {
+ memcpy(pos, common_ie, common_ie_len);
+ pos += common_ie_len;
+ len += common_ie_len;
}
return (u16)len;
@@ -267,7 +274,7 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- int n_ssids,
+ int n_ssids, u32 flags,
struct iwl_mvm_scan_params *params)
{
bool global_bound = false;
@@ -289,6 +296,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
params->max_out_time = 250;
}
+ if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
+ params->max_out_time = 200;
+
not_bound:
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
@@ -325,22 +335,20 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
mvm->scan_status = IWL_MVM_SCAN_OS;
- memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
- mvm->fw->ucode_capa.max_probe_length +
- (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
+ memset(cmd, 0, ksize(cmd));
cmd->channel_count = (u8)req->n_channels;
cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
- iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
+ iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
cmd->max_out_time = cpu_to_le32(params.max_out_time);
cmd->suspend_time = cpu_to_le32(params.suspend_time);
if (params.passive_fragmented)
cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
- cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
+ cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
MAC_FILTER_IN_BEACON);
@@ -367,7 +375,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
}
- iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0);
+ iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids,
+ basic_ssid ? 1 : 0);
cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
TX_CMD_FLG_BT_DIS);
@@ -382,7 +391,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
(struct ieee80211_mgmt *)cmd->data,
vif->addr,
req->n_ssids, ssid, ssid_len,
- req->ie, req->ie_len,
+ req->ie, req->ie_len, NULL, 0,
mvm->fw->ucode_capa.max_probe_length));
iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
@@ -441,16 +450,27 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
return 0;
}
-int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
- struct iwl_rx_cmd_buffer *rxb,
- struct iwl_device_cmd *cmd)
+int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_sched_scan_results *notif = (void *)pkt->data;
+ u8 client_bitmap = 0;
- if (notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN) {
- IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
- ieee80211_sched_scan_results(mvm->hw);
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
+ struct iwl_sched_scan_results *notif = (void *)pkt->data;
+
+ client_bitmap = notif->client_bitmap;
+ }
+
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN ||
+ client_bitmap & SCAN_CLIENT_SCHED_SCAN) {
+ if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
+ IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
+ ieee80211_sched_scan_results(mvm->hw);
+ } else {
+ IWL_DEBUG_SCAN(mvm, "Scan results\n");
+ }
}
return 0;
@@ -494,7 +514,7 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
};
}
-int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
+static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
{
struct iwl_notification_wait wait_scan_abort;
static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
@@ -535,33 +555,52 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
struct iwl_device_cmd *cmd)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data;
+ u8 status, ebs_status;
+
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
+ struct iwl_periodic_scan_complete *scan_notif;
+
+ scan_notif = (void *)pkt->data;
+ status = scan_notif->status;
+ ebs_status = scan_notif->ebs_status;
+ } else {
+ struct iwl_scan_offload_complete *scan_notif;
+ scan_notif = (void *)pkt->data;
+ status = scan_notif->status;
+ ebs_status = scan_notif->ebs_status;
+ }
/* scan status must be locked for proper checking */
lockdep_assert_held(&mvm->mutex);
IWL_DEBUG_SCAN(mvm,
- "Scheduled scan completed, status %s EBS status %s:%d\n",
- scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
- "completed" : "aborted", scan_notif->ebs_status ==
- IWL_SCAN_EBS_SUCCESS ? "success" : "failed",
- scan_notif->ebs_status);
+ "%s completed, status %s, EBS status %s\n",
+ mvm->scan_status == IWL_MVM_SCAN_SCHED ?
+ "Scheduled scan" : "Scan",
+ status == IWL_SCAN_OFFLOAD_COMPLETED ?
+ "completed" : "aborted",
+ ebs_status == IWL_SCAN_EBS_SUCCESS ?
+ "success" : "failed");
/* only call mac80211 completion if the stop was initiated by FW */
if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
mvm->scan_status = IWL_MVM_SCAN_NONE;
ieee80211_sched_scan_stopped(mvm->hw);
+ } else if (mvm->scan_status == IWL_MVM_SCAN_OS) {
+ mvm->scan_status = IWL_MVM_SCAN_NONE;
+ ieee80211_scan_completed(mvm->hw,
+ status == IWL_SCAN_OFFLOAD_ABORTED);
}
- mvm->last_ebs_successful = !scan_notif->ebs_status;
+ mvm->last_ebs_successful = !ebs_status;
return 0;
}
static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- struct ieee80211_sched_scan_ies *ies,
+ struct ieee80211_scan_ies *ies,
enum ieee80211_band band,
struct iwl_tx_cmd *cmd,
u8 *data)
@@ -577,7 +616,8 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
vif->addr,
1, NULL, 0,
- ies->ie[band], ies->len[band],
+ ies->ies[band], ies->len[band],
+ ies->common_ies, ies->common_ie_len,
SCAN_OFFLOAD_PROBE_REQ_SIZE);
cmd->len = cpu_to_le16(cmd_len);
}
@@ -588,9 +628,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
struct iwl_scan_offload_cmd *scan,
struct iwl_mvm_scan_params *params)
{
- scan->channel_count =
- mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
- mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
+ scan->channel_count = req->n_channels;
scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
@@ -623,8 +661,8 @@ static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
}
static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
- struct iwl_scan_offload_cmd *scan,
- u32 *ssid_bitmap)
+ struct iwl_ssid_ie *direct_scan,
+ u32 *ssid_bitmap, bool basic_ssid)
{
int i, j;
int index;
@@ -638,10 +676,10 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
/* skip empty SSID matchsets */
if (!req->match_sets[i].ssid.ssid_len)
continue;
- scan->direct_scan[i].id = WLAN_EID_SSID;
- scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
- memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
- scan->direct_scan[i].len);
+ direct_scan[i].id = WLAN_EID_SSID;
+ direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
+ memcpy(direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
+ direct_scan[i].len);
}
/* add SSIDs from scan SSID list */
@@ -649,14 +687,14 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) {
index = iwl_ssid_exist(req->ssids[j].ssid,
req->ssids[j].ssid_len,
- scan->direct_scan);
+ direct_scan);
if (index < 0) {
- if (!req->ssids[j].ssid_len)
+ if (!req->ssids[j].ssid_len && basic_ssid)
continue;
- scan->direct_scan[i].id = WLAN_EID_SSID;
- scan->direct_scan[i].len = req->ssids[j].ssid_len;
- memcpy(scan->direct_scan[i].ssid, req->ssids[j].ssid,
- scan->direct_scan[i].len);
+ direct_scan[i].id = WLAN_EID_SSID;
+ direct_scan[i].len = req->ssids[j].ssid_len;
+ memcpy(direct_scan[i].ssid, req->ssids[j].ssid,
+ direct_scan[i].len);
*ssid_bitmap |= BIT(i + 1);
i++;
} else {
@@ -667,83 +705,67 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
struct cfg80211_sched_scan_request *req,
- struct iwl_scan_channel_cfg *channels,
+ u8 *channels_buffer,
enum ieee80211_band band,
- int *head, int *tail,
+ int *head,
u32 ssid_bitmap,
struct iwl_mvm_scan_params *params)
{
- struct ieee80211_supported_band *s_band;
- int n_channels = req->n_channels;
- int i, j, index = 0;
- bool partial;
+ u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
+ __le32 *type = (__le32 *)channels_buffer;
+ __le16 *channel_number = (__le16 *)(type + n_channels);
+ __le16 *iter_count = channel_number + n_channels;
+ __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
+ u8 *active_dwell = (u8 *)(iter_interval + n_channels);
+ u8 *passive_dwell = active_dwell + n_channels;
+ int i, index = 0;
+
+ for (i = 0; i < req->n_channels; i++) {
+ struct ieee80211_channel *chan = req->channels[i];
+
+ if (chan->band != band)
+ continue;
- /*
- * We have to configure all supported channels, even if we don't want to
- * scan on them, but we have to send channels in the order that we want
- * to scan. So add requested channels to head of the list and others to
- * the end.
- */
- s_band = &mvm->nvm_data->bands[band];
-
- for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
- partial = false;
- for (j = 0; j < n_channels; j++)
- if (s_band->channels[i].center_freq ==
- req->channels[j]->center_freq) {
- index = *head;
- (*head)++;
- /*
- * Channels that came with the request will be
- * in partial scan .
- */
- partial = true;
- break;
- }
- if (!partial) {
- index = *tail;
- (*tail)--;
- }
- channels->channel_number[index] =
- cpu_to_le16(ieee80211_frequency_to_channel(
- s_band->channels[i].center_freq));
- channels->dwell_time[index][0] = params->dwell[band].active;
- channels->dwell_time[index][1] = params->dwell[band].passive;
+ index = *head;
+ (*head)++;
+
+ channel_number[index] = cpu_to_le16(chan->hw_value);
+ active_dwell[index] = params->dwell[band].active;
+ passive_dwell[index] = params->dwell[band].passive;
- channels->iter_count[index] = cpu_to_le16(1);
- channels->iter_interval[index] = 0;
+ iter_count[index] = cpu_to_le16(1);
+ iter_interval[index] = 0;
- if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
- channels->type[index] |=
+ if (!(chan->flags & IEEE80211_CHAN_NO_IR))
+ type[index] |=
cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
- channels->type[index] |=
- cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL);
- if (partial)
- channels->type[index] |=
- cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
+ type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
+ IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
- if (s_band->channels[i].flags & IEEE80211_CHAN_NO_HT40)
- channels->type[index] |=
+ if (chan->flags & IEEE80211_CHAN_NO_HT40)
+ type[index] |=
cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
/* scan for all SSIDs from req->ssids */
- channels->type[index] |= cpu_to_le32(ssid_bitmap);
+ type[index] |= cpu_to_le32(ssid_bitmap);
}
}
int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
int head = 0;
- int tail = band_2ghz + band_5ghz - 1;
u32 ssid_bitmap;
int cmd_len;
int ret;
+ u8 *probes;
+ bool basic_ssid = !(mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
struct iwl_scan_offload_cfg *scan_cfg;
struct iwl_host_cmd cmd = {
@@ -754,35 +776,40 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
cmd_len = sizeof(struct iwl_scan_offload_cfg) +
+ mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
if (!scan_cfg)
return -ENOMEM;
- iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params);
+ probes = scan_cfg->data +
+ mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
+
+ iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
- iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap);
+ iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan,
+ &ssid_bitmap, basic_ssid);
/* build tx frames for supported bands */
if (band_2ghz) {
iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
IEEE80211_BAND_2GHZ,
&scan_cfg->scan_cmd.tx_cmd[0],
- scan_cfg->data);
- iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
- IEEE80211_BAND_2GHZ, &head, &tail,
+ probes);
+ iwl_build_channel_cfg(mvm, req, scan_cfg->data,
+ IEEE80211_BAND_2GHZ, &head,
ssid_bitmap, &params);
}
if (band_5ghz) {
iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
IEEE80211_BAND_5GHZ,
&scan_cfg->scan_cmd.tx_cmd[1],
- scan_cfg->data +
+ probes +
SCAN_OFFLOAD_PROBE_REQ_SIZE);
- iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg,
- IEEE80211_BAND_5GHZ, &head, &tail,
+ iwl_build_channel_cfg(mvm, req, scan_cfg->data,
+ IEEE80211_BAND_5GHZ, &head,
ssid_bitmap, &params);
}
@@ -872,11 +899,11 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
.watchdog = IWL_SCHED_SCAN_WATCHDOG,
.schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
- .schedule_line[0].delay = req->interval / 1000,
+ .schedule_line[0].delay = cpu_to_le16(req->interval / 1000),
.schedule_line[0].full_scan_mul = 1,
.schedule_line[1].iterations = 0xff,
- .schedule_line[1].delay = req->interval / 1000,
+ .schedule_line[1].delay = cpu_to_le16(req->interval / 1000),
.schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
};
@@ -899,7 +926,7 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
sizeof(scan_req), &scan_req);
}
-static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
+static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm)
{
int ret;
struct iwl_host_cmd cmd = {
@@ -910,7 +937,9 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
/* Exit instantly with error when device is not ready
* to receive scan abort command or it does not perform
* scheduled scan currently */
- if (mvm->scan_status != IWL_MVM_SCAN_SCHED)
+ if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
+ (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
+ mvm->scan_status != IWL_MVM_SCAN_OS))
return -EIO;
ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
@@ -932,16 +961,19 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
return ret;
}
-int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify)
+int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
{
int ret;
struct iwl_notification_wait wait_scan_done;
static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, };
+ bool sched = mvm->scan_status == IWL_MVM_SCAN_SCHED;
lockdep_assert_held(&mvm->mutex);
- if (mvm->scan_status != IWL_MVM_SCAN_SCHED) {
- IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n");
+ if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
+ (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
+ mvm->scan_status != IWL_MVM_SCAN_OS)) {
+ IWL_DEBUG_SCAN(mvm, "No scan to stop\n");
return 0;
}
@@ -950,14 +982,16 @@ int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify)
ARRAY_SIZE(scan_done_notif),
NULL, NULL);
- ret = iwl_mvm_send_sched_scan_abort(mvm);
+ ret = iwl_mvm_send_scan_offload_abort(mvm);
if (ret) {
- IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret);
+ IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n",
+ sched ? "offloaded " : "", ret);
iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
return ret;
}
- IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n");
+ IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n",
+ sched ? "offloaded " : "");
ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ);
if (ret)
@@ -970,8 +1004,317 @@ int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify)
*/
mvm->scan_status = IWL_MVM_SCAN_NONE;
- if (notify)
- ieee80211_sched_scan_stopped(mvm->hw);
+ if (notify) {
+ if (sched)
+ ieee80211_sched_scan_stopped(mvm->hw);
+ else
+ ieee80211_scan_completed(mvm->hw, true);
+ }
return 0;
}
+
+static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm,
+ struct iwl_scan_req_tx_cmd *tx_cmd,
+ bool no_cck)
+{
+ tx_cmd[0].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
+ TX_CMD_FLG_BT_DIS);
+ tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
+ IEEE80211_BAND_2GHZ,
+ no_cck);
+ tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
+
+ tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
+ TX_CMD_FLG_BT_DIS);
+ tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
+ IEEE80211_BAND_5GHZ,
+ no_cck);
+ tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
+}
+
+static void
+iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm,
+ struct ieee80211_channel **channels,
+ int n_channels, u32 ssid_bitmap,
+ struct iwl_scan_req_unified_lmac *cmd)
+{
+ struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data;
+ int i;
+
+ for (i = 0; i < n_channels; i++) {
+ channel_cfg[i].channel_num =
+ cpu_to_le16(channels[i]->hw_value);
+ channel_cfg[i].iter_count = cpu_to_le16(1);
+ channel_cfg[i].iter_interval = 0;
+ channel_cfg[i].flags =
+ cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL |
+ ssid_bitmap);
+ }
+}
+
+static void
+iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+ struct ieee80211_scan_ies *ies,
+ struct iwl_scan_req_unified_lmac *cmd)
+{
+ struct iwl_scan_probe_req *preq = (void *)(cmd->data +
+ sizeof(struct iwl_scan_channel_cfg_lmac) *
+ mvm->fw->ucode_capa.n_scan_channels);
+ struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf;
+ u8 *pos;
+
+ frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+ eth_broadcast_addr(frame->da);
+ memcpy(frame->sa, vif->addr, ETH_ALEN);
+ eth_broadcast_addr(frame->bssid);
+ frame->seq_ctrl = 0;
+
+ pos = frame->u.probe_req.variable;
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = 0;
+
+ preq->mac_header.offset = 0;
+ preq->mac_header.len = cpu_to_le16(24 + 2);
+
+ memcpy(pos, ies->ies[IEEE80211_BAND_2GHZ],
+ ies->len[IEEE80211_BAND_2GHZ]);
+ preq->band_data[0].offset = cpu_to_le16(pos - preq->buf);
+ preq->band_data[0].len = cpu_to_le16(ies->len[IEEE80211_BAND_2GHZ]);
+ pos += ies->len[IEEE80211_BAND_2GHZ];
+
+ memcpy(pos, ies->ies[IEEE80211_BAND_5GHZ],
+ ies->len[IEEE80211_BAND_5GHZ]);
+ preq->band_data[1].offset = cpu_to_le16(pos - preq->buf);
+ preq->band_data[1].len = cpu_to_le16(ies->len[IEEE80211_BAND_5GHZ]);
+ pos += ies->len[IEEE80211_BAND_5GHZ];
+
+ memcpy(pos, ies->common_ies, ies->common_ie_len);
+ preq->common_data.offset = cpu_to_le16(pos - preq->buf);
+ preq->common_data.len = cpu_to_le16(ies->common_ie_len);
+}
+
+static void
+iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
+ struct iwl_scan_req_unified_lmac *cmd,
+ struct iwl_mvm_scan_params *params)
+{
+ memset(cmd, 0, ksize(cmd));
+ cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active;
+ cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive;
+ /* TODO: Use params; now fragmented isn't used. */
+ cmd->fragmented_dwell = 0;
+ cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
+ cmd->max_out_time = cpu_to_le32(params->max_out_time);
+ cmd->suspend_time = cpu_to_le32(params->suspend_time);
+ cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
+ cmd->iter_num = cpu_to_le32(1);
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
+ mvm->last_ebs_successful) {
+ cmd->channel_opt[0].flags =
+ cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+ IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+ IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+ cmd->channel_opt[1].flags =
+ cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+ IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+ IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+ }
+}
+
+int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_scan_request *req)
+{
+ struct iwl_host_cmd hcmd = {
+ .id = SCAN_OFFLOAD_REQUEST_CMD,
+ .len = { sizeof(struct iwl_scan_req_unified_lmac) +
+ sizeof(struct iwl_scan_channel_cfg_lmac) *
+ mvm->fw->ucode_capa.n_scan_channels +
+ sizeof(struct iwl_scan_probe_req), },
+ .data = { mvm->scan_cmd, },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ };
+ struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd;
+ struct iwl_mvm_scan_params params = {};
+ u32 flags;
+ int ssid_bitmap = 0;
+ int ret, i;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* we should have failed registration if scan_cmd was NULL */
+ if (WARN_ON(mvm->scan_cmd == NULL))
+ return -ENOMEM;
+
+ if (WARN_ON_ONCE(req->req.n_ssids > PROBE_OPTION_MAX ||
+ req->ies.common_ie_len + req->ies.len[0] +
+ req->ies.len[1] + 24 + 2 >
+ SCAN_OFFLOAD_PROBE_REQ_SIZE ||
+ req->req.n_channels >
+ mvm->fw->ucode_capa.n_scan_channels))
+ return -1;
+
+ mvm->scan_status = IWL_MVM_SCAN_OS;
+
+ iwl_mvm_scan_calc_params(mvm, vif, req->req.n_ssids, req->req.flags,
+ &params);
+
+ iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, &params);
+
+ cmd->n_channels = (u8)req->req.n_channels;
+
+ flags = IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
+
+ if (req->req.n_ssids == 1 && req->req.ssids[0].ssid_len != 0)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
+
+ if (params.passive_fragmented)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
+
+ if (req->req.n_ssids == 0)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
+
+ cmd->scan_flags = cpu_to_le32(flags);
+
+ cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band);
+ cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
+ MAC_FILTER_IN_BEACON);
+ iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, req->req.no_cck);
+ iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->req.ssids,
+ req->req.n_ssids, 0);
+
+ cmd->schedule[0].delay = 0;
+ cmd->schedule[0].iterations = 1;
+ cmd->schedule[0].full_scan_mul = 0;
+ cmd->schedule[1].delay = 0;
+ cmd->schedule[1].iterations = 0;
+ cmd->schedule[1].full_scan_mul = 0;
+
+ for (i = 1; i <= req->req.n_ssids; i++)
+ ssid_bitmap |= BIT(i);
+
+ iwl_mvm_lmac_scan_cfg_channels(mvm, req->req.channels,
+ req->req.n_channels, ssid_bitmap,
+ cmd);
+
+ iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, cmd);
+
+ ret = iwl_mvm_send_cmd(mvm, &hcmd);
+ if (!ret) {
+ IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
+ } else {
+ /*
+ * If the scan failed, it usually means that the FW was unable
+ * to allocate the time events. Warn on it, but maybe we
+ * should try to send the command again with different params.
+ */
+ IWL_ERR(mvm, "Scan failed! ret %d\n", ret);
+ mvm->scan_status = IWL_MVM_SCAN_NONE;
+ ret = -EIO;
+ }
+ return ret;
+}
+
+int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct cfg80211_sched_scan_request *req,
+ struct ieee80211_scan_ies *ies)
+{
+ struct iwl_host_cmd hcmd = {
+ .id = SCAN_OFFLOAD_REQUEST_CMD,
+ .len = { sizeof(struct iwl_scan_req_unified_lmac) +
+ sizeof(struct iwl_scan_channel_cfg_lmac) *
+ mvm->fw->ucode_capa.n_scan_channels +
+ sizeof(struct iwl_scan_probe_req), },
+ .data = { mvm->scan_cmd, },
+ .dataflags = { IWL_HCMD_DFL_NOCOPY, },
+ };
+ struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd;
+ struct iwl_mvm_scan_params params = {};
+ int ret;
+ u32 flags = 0, ssid_bitmap = 0;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* we should have failed registration if scan_cmd was NULL */
+ if (WARN_ON(mvm->scan_cmd == NULL))
+ return -ENOMEM;
+
+ if (WARN_ON_ONCE(req->n_ssids > PROBE_OPTION_MAX ||
+ ies->common_ie_len + ies->len[0] + ies->len[1] + 24 + 2
+ > SCAN_OFFLOAD_PROBE_REQ_SIZE ||
+ req->n_channels > mvm->fw->ucode_capa.n_scan_channels))
+ return -ENOBUFS;
+
+ iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
+
+ iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, &params);
+
+ cmd->n_channels = (u8)req->n_channels;
+
+ if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
+ IWL_DEBUG_SCAN(mvm,
+ "Sending scheduled scan with filtering, n_match_sets %d\n",
+ req->n_match_sets);
+ } else {
+ IWL_DEBUG_SCAN(mvm,
+ "Sending Scheduled scan without filtering\n");
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
+ }
+
+ if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
+
+ if (params.passive_fragmented)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
+
+ if (req->n_ssids == 0)
+ flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
+
+ cmd->scan_flags = cpu_to_le32(flags);
+
+ cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
+ cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
+ MAC_FILTER_IN_BEACON);
+ iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, false);
+ iwl_scan_offload_build_ssid(req, cmd->direct_scan, &ssid_bitmap, false);
+
+ cmd->schedule[0].delay = cpu_to_le16(req->interval / MSEC_PER_SEC);
+ cmd->schedule[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS;
+ cmd->schedule[0].full_scan_mul = 1;
+
+ cmd->schedule[1].delay = cpu_to_le16(req->interval / MSEC_PER_SEC);
+ cmd->schedule[1].iterations = 0xff;
+ cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
+
+ iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
+ ssid_bitmap, cmd);
+
+ iwl_mvm_build_unified_scan_probe(mvm, vif, ies, cmd);
+
+ ret = iwl_mvm_send_cmd(mvm, &hcmd);
+ if (!ret) {
+ IWL_DEBUG_SCAN(mvm,
+ "Sched scan request was sent successfully\n");
+ } else {
+ /*
+ * If the scan failed, it usually means that the FW was unable
+ * to allocate the time events. Warn on it, but maybe we
+ * should try to send the command again with different params.
+ */
+ IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret);
+ mvm->scan_status = IWL_MVM_SCAN_NONE;
+ ret = -EIO;
+ }
+ return ret;
+}
+
+
+int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
+{
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ return iwl_mvm_scan_offload_stop(mvm, true);
+ return iwl_mvm_cancel_regular_scan(mvm);
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 1fb01ea2e704..763548880399 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -98,23 +98,21 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
bool update)
{
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
- struct iwl_mvm_add_sta_cmd add_sta_cmd;
+ struct iwl_mvm_add_sta_cmd add_sta_cmd = {
+ .sta_id = mvm_sta->sta_id,
+ .mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color),
+ .add_modify = update ? 1 : 0,
+ .station_flags_msk = cpu_to_le32(STA_FLG_FAT_EN_MSK |
+ STA_FLG_MIMO_EN_MSK),
+ };
int ret;
u32 status;
u32 agg_size = 0, mpdu_dens = 0;
- memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
-
- add_sta_cmd.sta_id = mvm_sta->sta_id;
- add_sta_cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
if (!update) {
add_sta_cmd.tfd_queue_msk = cpu_to_le32(mvm_sta->tfd_queue_msk);
memcpy(&add_sta_cmd.addr, sta->addr, ETH_ALEN);
}
- add_sta_cmd.add_modify = update ? 1 : 0;
-
- add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
- STA_FLG_MIMO_EN_MSK);
switch (sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
@@ -528,8 +526,12 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex);
- /* Add the aux station, but without any queues */
- ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, 0,
+ /* Map Aux queue to fifo - needs to happen before adding Aux station */
+ iwl_trans_ac_txq_enable(mvm->trans, mvm->aux_queue,
+ IWL_MVM_TX_FIFO_MCAST);
+
+ /* Allocate aux station and assign to it the aux queue */
+ ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue),
NL80211_IFTYPE_UNSPECIFIED);
if (ret)
return ret;
@@ -1448,3 +1450,77 @@ int iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
return 0;
}
+
+void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
+ struct iwl_mvm_sta *mvmsta, bool disable)
+{
+ struct iwl_mvm_add_sta_cmd cmd = {
+ .add_modify = STA_MODE_MODIFY,
+ .sta_id = mvmsta->sta_id,
+ .station_flags = disable ? cpu_to_le32(STA_FLG_DISABLE_TX) : 0,
+ .station_flags_msk = cpu_to_le32(STA_FLG_DISABLE_TX),
+ .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
+ };
+ int ret;
+
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_DISABLE_STA_TX))
+ return;
+
+ ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
+}
+
+void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta,
+ bool disable)
+{
+ struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+
+ spin_lock_bh(&mvm_sta->lock);
+
+ if (mvm_sta->disable_tx == disable) {
+ spin_unlock_bh(&mvm_sta->lock);
+ return;
+ }
+
+ mvm_sta->disable_tx = disable;
+
+ /*
+ * Tell mac80211 to start/stop queueing tx for this station,
+ * but don't stop queueing if there are still pending frames
+ * for this station.
+ */
+ if (disable || !atomic_read(&mvm->pending_frames[mvm_sta->sta_id]))
+ ieee80211_sta_block_awake(mvm->hw, sta, disable);
+
+ iwl_mvm_sta_modify_disable_tx(mvm, mvm_sta, disable);
+
+ spin_unlock_bh(&mvm_sta->lock);
+}
+
+void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
+ struct iwl_mvm_vif *mvmvif,
+ bool disable)
+{
+ struct ieee80211_sta *sta;
+ struct iwl_mvm_sta *mvm_sta;
+ int i;
+
+ lockdep_assert_held(&mvm->mutex);
+
+ /* Block/unblock all the stations of the given mvmvif */
+ for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
+ sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
+ lockdep_is_held(&mvm->mutex));
+ if (IS_ERR_OR_NULL(sta))
+ continue;
+
+ mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+ if (mvm_sta->mac_id_n_color !=
+ FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
+ continue;
+
+ iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, disable);
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index d98e8a2142b8..3b1c8bd6cb54 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -73,6 +73,7 @@
#include "rs.h"
struct iwl_mvm;
+struct iwl_mvm_vif;
/**
* DOC: station table - introduction
@@ -295,6 +296,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data)
* @tid_data: per tid data. Look at %iwl_mvm_tid_data.
* @tx_protection: reference counter for controlling the Tx protection.
* @tt_tx_protection: is thermal throttling enable Tx protection?
+ * @disable_tx: is tx to this STA disabled?
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is placed in that
@@ -317,6 +319,8 @@ struct iwl_mvm_sta {
/* Temporary, until the new TLC will control the Tx protection */
s8 tx_protection;
bool tt_tx_protection;
+
+ bool disable_tx;
};
static inline struct iwl_mvm_sta *
@@ -404,5 +408,13 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
bool agg);
int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
bool drain);
+void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
+ struct iwl_mvm_sta *mvmsta, bool disable);
+void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta,
+ bool disable);
+void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
+ struct iwl_mvm_vif *mvmvif,
+ bool disable);
#endif /* __sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 80100f6cc12a..33e5041f1efc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -72,9 +72,6 @@
#include "iwl-io.h"
#include "iwl-prph.h"
-/* A TimeUnit is 1024 microsecond */
-#define MSEC_TO_TU(_msec) (_msec*1000/1024)
-
/*
* For the high priority TE use a time event type that has similar priority to
* the FW's action scan priority.
@@ -100,6 +97,21 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
void iwl_mvm_roc_done_wk(struct work_struct *wk)
{
struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk);
+ u32 queues = 0;
+
+ /*
+ * Clear the ROC_RUNNING /ROC_AUX_RUNNING status bit.
+ * This will cause the TX path to drop offchannel transmissions.
+ * That would also be done by mac80211, but it is racy, in particular
+ * in the case that the time event actually completed in the firmware
+ * (which is handled in iwl_mvm_te_handle_notif).
+ */
+ if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
+ queues |= BIT(IWL_MVM_OFFCHANNEL_QUEUE);
+ if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
+ queues |= BIT(mvm->aux_queue);
+
+ iwl_mvm_unref(mvm, IWL_MVM_REF_ROC);
synchronize_net();
@@ -113,22 +125,12 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
* issue as it will have to complete before the next command is
* executed, and a new time event means a new command.
*/
- iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false);
+ iwl_mvm_flush_tx_path(mvm, queues, false);
}
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
{
/*
- * First, clear the ROC_RUNNING status bit. This will cause the TX
- * path to drop offchannel transmissions. That would also be done
- * by mac80211, but it is racy, in particular in the case that the
- * time event actually completed in the firmware (which is handled
- * in iwl_mvm_te_handle_notif).
- */
- clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
- iwl_mvm_unref(mvm, IWL_MVM_REF_ROC);
-
- /*
* Of course, our status bit is just as racy as mac80211, so in
* addition, fire off the work struct which will drop all frames
* from the hardware queues that made it through the race. First
@@ -138,6 +140,41 @@ static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
schedule_work(&mvm->roc_done_wk);
}
+static void iwl_mvm_csa_noa_start(struct iwl_mvm *mvm)
+{
+ struct ieee80211_vif *csa_vif;
+
+ rcu_read_lock();
+
+ csa_vif = rcu_dereference(mvm->csa_vif);
+ if (!csa_vif || !csa_vif->csa_active)
+ goto out_unlock;
+
+ IWL_DEBUG_TE(mvm, "CSA NOA started\n");
+
+ /*
+ * CSA NoA is started but we still have beacons to
+ * transmit on the current channel.
+ * So we just do nothing here and the switch
+ * will be performed on the last TBTT.
+ */
+ if (!ieee80211_csa_is_complete(csa_vif)) {
+ IWL_WARN(mvm, "CSA NOA started too early\n");
+ goto out_unlock;
+ }
+
+ ieee80211_csa_finish(csa_vif);
+
+ rcu_read_unlock();
+
+ RCU_INIT_POINTER(mvm->csa_vif, NULL);
+
+ return;
+
+out_unlock:
+ rcu_read_unlock();
+}
+
static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
const char *errmsg)
@@ -213,6 +250,14 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
iwl_mvm_ref(mvm, IWL_MVM_REF_ROC);
ieee80211_ready_on_channel(mvm->hw);
+ } else if (te_data->vif->type == NL80211_IFTYPE_AP) {
+ if (le32_to_cpu(notif->status))
+ iwl_mvm_csa_noa_start(mvm);
+ else
+ IWL_DEBUG_TE(mvm, "CSA NOA failed to start\n");
+
+ /* we don't need it anymore */
+ iwl_mvm_te_clear_data(mvm, te_data);
}
} else {
IWL_WARN(mvm, "Got TE with unknown action\n");
@@ -220,6 +265,60 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
}
/*
+ * Handle A Aux ROC time event
+ */
+static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
+ struct iwl_time_event_notif *notif)
+{
+ struct iwl_mvm_time_event_data *te_data, *tmp;
+ bool aux_roc_te = false;
+
+ list_for_each_entry_safe(te_data, tmp, &mvm->aux_roc_te_list, list) {
+ if (le32_to_cpu(notif->unique_id) == te_data->uid) {
+ aux_roc_te = true;
+ break;
+ }
+ }
+ if (!aux_roc_te) /* Not a Aux ROC time event */
+ return -EINVAL;
+
+ if (!le32_to_cpu(notif->status)) {
+ IWL_DEBUG_TE(mvm,
+ "ERROR: Aux ROC Time Event %s notification failure\n",
+ (le32_to_cpu(notif->action) &
+ TE_V2_NOTIF_HOST_EVENT_START) ? "start" : "end");
+ return -EINVAL;
+ }
+
+ IWL_DEBUG_TE(mvm,
+ "Aux ROC time event notification - UID = 0x%x action %d\n",
+ le32_to_cpu(notif->unique_id),
+ le32_to_cpu(notif->action));
+
+ if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_END) {
+ /* End TE, notify mac80211 */
+ ieee80211_remain_on_channel_expired(mvm->hw);
+ iwl_mvm_roc_finished(mvm); /* flush aux queue */
+ list_del(&te_data->list); /* remove from list */
+ te_data->running = false;
+ te_data->vif = NULL;
+ te_data->uid = 0;
+ } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
+ set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
+ set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
+ te_data->running = true;
+ ieee80211_ready_on_channel(mvm->hw); /* Start TE */
+ } else {
+ IWL_DEBUG_TE(mvm,
+ "ERROR: Unknown Aux ROC Time Event (action = %d)\n",
+ le32_to_cpu(notif->action));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
* The Rx handler for time event notifications
*/
int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
@@ -235,10 +334,15 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
le32_to_cpu(notif->action));
spin_lock_bh(&mvm->time_event_lock);
+ /* This time event is triggered for Aux ROC request */
+ if (!iwl_mvm_aux_roc_te_handle_notif(mvm, notif))
+ goto unlock;
+
list_for_each_entry_safe(te_data, tmp, &mvm->time_event_list, list) {
if (le32_to_cpu(notif->unique_id) == te_data->uid)
iwl_mvm_te_handle_notif(mvm, te_data, notif);
}
+unlock:
spin_unlock_bh(&mvm->time_event_lock);
return 0;
@@ -538,3 +642,33 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
iwl_mvm_roc_finished(mvm);
}
+
+int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ u32 duration, u32 apply_time)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
+ struct iwl_time_event_cmd time_cmd = {};
+
+ lockdep_assert_held(&mvm->mutex);
+
+ if (te_data->running) {
+ IWL_DEBUG_TE(mvm, "CS NOA is already scheduled\n");
+ return -EBUSY;
+ }
+
+ time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
+ time_cmd.id_and_color =
+ cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
+ time_cmd.id = cpu_to_le32(TE_P2P_GO_CSA_NOA);
+ time_cmd.apply_time = cpu_to_le32(apply_time);
+ time_cmd.max_frags = TE_V2_FRAG_NONE;
+ time_cmd.duration = cpu_to_le32(duration);
+ time_cmd.repeat = 1;
+ time_cmd.interval = cpu_to_le32(1);
+ time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
+ TE_V2_ABSENCE);
+
+ return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 4a61c8c02372..2f48a90d4ad3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -214,4 +214,33 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
void iwl_mvm_roc_done_wk(struct work_struct *wk);
+/**
+ * iwl_mvm_schedule_csa_noa - request NoA for channel switch
+ * @mvm: the mvm component
+ * @vif: the virtual interface for which the channel switch is issued
+ * @duration: the duration of the NoA in TU.
+ * @apply_time: NoA start time in GP2.
+ *
+ * This function is used to schedule NoA time event and is used to perform
+ * the channel switch flow.
+ */
+int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ u32 duration, u32 apply_time);
+
+/**
+ * iwl_mvm_te_scheduled - check if the fw received the TE cmd
+ * @te_data: the time event data that corresponds to that time event
+ *
+ * This function returns true iff this TE is added to the fw.
+ */
+static inline bool
+iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
+{
+ if (!te_data)
+ return false;
+
+ return !!te_data->uid;
+}
+
#endif /* __time_event_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 868561512783..0464599c111e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -140,9 +140,9 @@ static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)
/* TODO: move parsing to NVM code */
calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
- ptat = calib[OTP_DTS_DIODE_DEVIATION];
- pa1 = calib[OTP_DTS_DIODE_DEVIATION + 1];
- pa2 = calib[OTP_DTS_DIODE_DEVIATION + 2];
+ ptat = calib[OTP_DTS_DIODE_DEVIATION * 2];
+ pa1 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 1];
+ pa2 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 2];
/* get the median: */
if (ptat > pa1) {
@@ -338,10 +338,16 @@ static void check_exit_ctkill(struct work_struct *work)
duration = tt->params->ct_kill_duration;
+ /* make sure the device is available for direct read/writes */
+ if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL))
+ goto reschedule;
+
iwl_trans_start_hw(mvm->trans);
temp = check_nic_temperature(mvm);
iwl_trans_stop_device(mvm->trans);
+ iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL);
+
if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
goto reschedule;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 3846a6c41eb1..dbc870713882 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -131,7 +131,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
!is_multicast_ether_addr(ieee80211_get_DA(hdr)))
tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
- tx_cmd->driver_txop = 0;
tx_cmd->tx_flags = cpu_to_le32(tx_flags);
/* Total # bytes to be transmitted */
tx_cmd->len = cpu_to_le16((u16)skb->len);
@@ -205,7 +204,13 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
mvm->mgmt_last_antenna_idx =
iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
mvm->mgmt_last_antenna_idx);
- rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
+
+ if (info->band == IEEE80211_BAND_2GHZ &&
+ !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
+ rate_flags = BIT(ANT_A) << RATE_MCS_ANT_POS;
+ else
+ rate_flags =
+ BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
/* Set CCK flag as needed */
if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
@@ -306,6 +311,16 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
return -1;
/*
+ * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
+ * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel
+ * queue. STATION (HS2.0) uses the auxiliary context of the FW,
+ * and hence needs to be sent on the aux queue
+ */
+ if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
+ info->control.vif->type == NL80211_IFTYPE_STATION)
+ IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue;
+
+ /*
* If the interface on which frame is sent is the P2P_DEVICE
* or an AP/GO interface use the broadcast station associated
* with it; otherwise use the AUX station.
@@ -717,18 +732,26 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
/* We can't free more than one frame at once on a shared queue */
WARN_ON(skb_freed > 1);
- /* If we have still frames from this STA nothing to do here */
+ /* If we have still frames for this STA nothing to do here */
if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id]))
goto out;
if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) {
+
/*
- * If there are no pending frames for this STA, notify
- * mac80211 that this station can go to sleep in its
+ * If there are no pending frames for this STA and
+ * the tx to this station is not disabled, notify
+ * mac80211 that this station can now wake up in its
* STA table.
* If mvmsta is not NULL, sta is valid.
*/
- ieee80211_sta_block_awake(mvm->hw, sta, false);
+
+ spin_lock_bh(&mvmsta->lock);
+
+ if (!mvmsta->disable_tx)
+ ieee80211_sta_block_awake(mvm->hw, sta, false);
+
+ spin_unlock_bh(&mvmsta->lock);
}
if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index aa9fc77e8413..ac249da8a22b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -519,71 +519,6 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
iwl_mvm_dump_umac_error_log(mvm);
}
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
-{
- const struct fw_img *img;
- u32 ofs, sram_len;
- void *sram;
-
- if (!mvm->ucode_loaded || mvm->fw_error_sram || mvm->fw_error_dump)
- return;
-
- img = &mvm->fw->img[mvm->cur_ucode];
- ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
- sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
-
- sram = kzalloc(sram_len, GFP_ATOMIC);
- if (!sram)
- return;
-
- iwl_trans_read_mem_bytes(mvm->trans, ofs, sram, sram_len);
- mvm->fw_error_sram = sram;
- mvm->fw_error_sram_len = sram_len;
-}
-
-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
-{
- int i, reg_val;
- unsigned long flags;
-
- if (!mvm->ucode_loaded || mvm->fw_error_rxf || mvm->fw_error_dump)
- return;
-
- /* reading buffer size */
- reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
- mvm->fw_error_rxf_len =
- (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
-
- /* the register holds the value divided by 128 */
- mvm->fw_error_rxf_len = mvm->fw_error_rxf_len << 7;
-
- if (!mvm->fw_error_rxf_len)
- return;
-
- mvm->fw_error_rxf = kzalloc(mvm->fw_error_rxf_len, GFP_ATOMIC);
- if (!mvm->fw_error_rxf) {
- mvm->fw_error_rxf_len = 0;
- return;
- }
-
- if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
- kfree(mvm->fw_error_rxf);
- mvm->fw_error_rxf = NULL;
- mvm->fw_error_rxf_len = 0;
- return;
- }
-
- for (i = 0; i < (mvm->fw_error_rxf_len / sizeof(u32)); i++) {
- iwl_trans_write_prph(mvm->trans, RXF_LD_FENCE_OFFSET_ADDR,
- i * sizeof(u32));
- mvm->fw_error_rxf[i] =
- iwl_trans_read_prph(mvm->trans, RXF_FIFO_RD_FENCE_ADDR);
- }
- iwl_trans_release_nic_access(mvm->trans, &flags);
-}
-#endif
-
/**
* iwl_mvm_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 7091a18d5a72..98950e45c7b0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -367,6 +367,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095A, 0x5510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
@@ -380,7 +381,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095B, 0x9200, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 6c22b23a2845..78f72c34438a 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
* @wd_timeout: queue watchdog timeout (jiffies)
* @reg_lock: protect hw register access
* @cmd_in_flight: true when we have a host command in flight
+ * @fw_mon_phys: physical address of the buffer for the firmware monitor
+ * @fw_mon_page: points to the first page of the buffer for the firmware monitor
+ * @fw_mon_size: size of the buffer for the firmware monitor
*/
struct iwl_trans_pcie {
struct iwl_rxq rxq;
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
/*protect hw register */
spinlock_t reg_lock;
bool cmd_in_flight;
+
+ dma_addr_t fw_mon_phys;
+ struct page *fw_mon_page;
+ u32 fw_mon_size;
};
#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 788085bc65d7..06e04aaf61ee 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -67,6 +67,7 @@
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/gfp.h>
+#include <linux/vmalloc.h>
#include "iwl-drv.h"
#include "iwl-trans.h"
@@ -76,6 +77,68 @@
#include "iwl-fw-error-dump.h"
#include "internal.h"
+static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ if (!trans_pcie->fw_mon_page)
+ return;
+
+ dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys,
+ trans_pcie->fw_mon_size, DMA_FROM_DEVICE);
+ __free_pages(trans_pcie->fw_mon_page,
+ get_order(trans_pcie->fw_mon_size));
+ trans_pcie->fw_mon_page = NULL;
+ trans_pcie->fw_mon_phys = 0;
+ trans_pcie->fw_mon_size = 0;
+}
+
+static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ struct page *page;
+ dma_addr_t phys;
+ u32 size;
+ u8 power;
+
+ if (trans_pcie->fw_mon_page) {
+ dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys,
+ trans_pcie->fw_mon_size,
+ DMA_FROM_DEVICE);
+ return;
+ }
+
+ phys = 0;
+ for (power = 26; power >= 11; power--) {
+ int order;
+
+ size = BIT(power);
+ order = get_order(size);
+ page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO,
+ order);
+ if (!page)
+ continue;
+
+ phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(trans->dev, phys)) {
+ __free_pages(page, order);
+ continue;
+ }
+ IWL_INFO(trans,
+ "Allocated 0x%08x bytes (order %d) for firmware monitor.\n",
+ size, order);
+ break;
+ }
+
+ if (!page)
+ return;
+
+ trans_pcie->fw_mon_page = page;
+ trans_pcie->fw_mon_phys = phys;
+ trans_pcie->fw_mon_size = size;
+}
+
static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg)
{
iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG,
@@ -675,6 +738,7 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
const struct fw_img *image)
{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int ret = 0;
int first_ucode_section;
@@ -733,6 +797,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
return ret;
}
+ /* supported for 7000 only for the moment */
+ if (iwlwifi_mod_params.fw_monitor &&
+ trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ iwl_pcie_alloc_fw_monitor(trans);
+
+ if (trans_pcie->fw_mon_size) {
+ iwl_write_prph(trans, MON_BUFF_BASE_ADDR,
+ trans_pcie->fw_mon_phys >> 4);
+ iwl_write_prph(trans, MON_BUFF_END_ADDR,
+ (trans_pcie->fw_mon_phys +
+ trans_pcie->fw_mon_size) >> 4);
+ }
+ }
+
/* release CPU reset */
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -1126,6 +1204,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
if (trans_pcie->napi.poll)
netif_napi_del(&trans_pcie->napi);
+ iwl_pcie_free_fw_monitor(trans);
+
kfree(trans);
}
@@ -1494,10 +1574,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
txq = &trans_pcie->txq[cnt];
q = &txq->q;
pos += scnprintf(buf + pos, bufsz - pos,
- "hwq %.2d: read=%u write=%u use=%d stop=%d\n",
+ "hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d%s\n",
cnt, q->read_ptr, q->write_ptr,
!!test_bit(cnt, trans_pcie->queue_used),
- !!test_bit(cnt, trans_pcie->queue_stopped));
+ !!test_bit(cnt, trans_pcie->queue_stopped),
+ txq->need_update,
+ (cnt == trans_pcie->cmd_queue ? " HCMD" : ""));
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
@@ -1519,6 +1601,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
rxq->read);
pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
rxq->write);
+ pos += scnprintf(buf + pos, bufsz - pos, "write_actual: %u\n",
+ rxq->write_actual);
+ pos += scnprintf(buf + pos, bufsz - pos, "need_update: %d\n",
+ rxq->need_update);
pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
rxq->free_count);
if (rxq->rb_stts) {
@@ -1688,23 +1774,207 @@ static u32 iwl_trans_pcie_get_cmdlen(struct iwl_tfd *tfd)
return cmdlen;
}
-static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
- void *buf, u32 buflen)
+static const struct {
+ u32 start, end;
+} iwl_prph_dump_addr[] = {
+ { .start = 0x00a00000, .end = 0x00a00000 },
+ { .start = 0x00a0000c, .end = 0x00a00024 },
+ { .start = 0x00a0002c, .end = 0x00a0003c },
+ { .start = 0x00a00410, .end = 0x00a00418 },
+ { .start = 0x00a00420, .end = 0x00a00420 },
+ { .start = 0x00a00428, .end = 0x00a00428 },
+ { .start = 0x00a00430, .end = 0x00a0043c },
+ { .start = 0x00a00444, .end = 0x00a00444 },
+ { .start = 0x00a004c0, .end = 0x00a004cc },
+ { .start = 0x00a004d8, .end = 0x00a004d8 },
+ { .start = 0x00a004e0, .end = 0x00a004f0 },
+ { .start = 0x00a00840, .end = 0x00a00840 },
+ { .start = 0x00a00850, .end = 0x00a00858 },
+ { .start = 0x00a01004, .end = 0x00a01008 },
+ { .start = 0x00a01010, .end = 0x00a01010 },
+ { .start = 0x00a01018, .end = 0x00a01018 },
+ { .start = 0x00a01024, .end = 0x00a01024 },
+ { .start = 0x00a0102c, .end = 0x00a01034 },
+ { .start = 0x00a0103c, .end = 0x00a01040 },
+ { .start = 0x00a01048, .end = 0x00a01094 },
+ { .start = 0x00a01c00, .end = 0x00a01c20 },
+ { .start = 0x00a01c58, .end = 0x00a01c58 },
+ { .start = 0x00a01c7c, .end = 0x00a01c7c },
+ { .start = 0x00a01c28, .end = 0x00a01c54 },
+ { .start = 0x00a01c5c, .end = 0x00a01c5c },
+ { .start = 0x00a01c84, .end = 0x00a01c84 },
+ { .start = 0x00a01ce0, .end = 0x00a01d0c },
+ { .start = 0x00a01d18, .end = 0x00a01d20 },
+ { .start = 0x00a01d2c, .end = 0x00a01d30 },
+ { .start = 0x00a01d40, .end = 0x00a01d5c },
+ { .start = 0x00a01d80, .end = 0x00a01d80 },
+ { .start = 0x00a01d98, .end = 0x00a01d98 },
+ { .start = 0x00a01dc0, .end = 0x00a01dfc },
+ { .start = 0x00a01e00, .end = 0x00a01e2c },
+ { .start = 0x00a01e40, .end = 0x00a01e60 },
+ { .start = 0x00a01e84, .end = 0x00a01e90 },
+ { .start = 0x00a01e9c, .end = 0x00a01ec4 },
+ { .start = 0x00a01ed0, .end = 0x00a01ed0 },
+ { .start = 0x00a01f00, .end = 0x00a01f14 },
+ { .start = 0x00a01f44, .end = 0x00a01f58 },
+ { .start = 0x00a01f80, .end = 0x00a01fa8 },
+ { .start = 0x00a01fb0, .end = 0x00a01fbc },
+ { .start = 0x00a01ff8, .end = 0x00a01ffc },
+ { .start = 0x00a02000, .end = 0x00a02048 },
+ { .start = 0x00a02068, .end = 0x00a020f0 },
+ { .start = 0x00a02100, .end = 0x00a02118 },
+ { .start = 0x00a02140, .end = 0x00a0214c },
+ { .start = 0x00a02168, .end = 0x00a0218c },
+ { .start = 0x00a021c0, .end = 0x00a021c0 },
+ { .start = 0x00a02400, .end = 0x00a02410 },
+ { .start = 0x00a02418, .end = 0x00a02420 },
+ { .start = 0x00a02428, .end = 0x00a0242c },
+ { .start = 0x00a02434, .end = 0x00a02434 },
+ { .start = 0x00a02440, .end = 0x00a02460 },
+ { .start = 0x00a02468, .end = 0x00a024b0 },
+ { .start = 0x00a024c8, .end = 0x00a024cc },
+ { .start = 0x00a02500, .end = 0x00a02504 },
+ { .start = 0x00a0250c, .end = 0x00a02510 },
+ { .start = 0x00a02540, .end = 0x00a02554 },
+ { .start = 0x00a02580, .end = 0x00a025f4 },
+ { .start = 0x00a02600, .end = 0x00a0260c },
+ { .start = 0x00a02648, .end = 0x00a02650 },
+ { .start = 0x00a02680, .end = 0x00a02680 },
+ { .start = 0x00a026c0, .end = 0x00a026d0 },
+ { .start = 0x00a02700, .end = 0x00a0270c },
+ { .start = 0x00a02804, .end = 0x00a02804 },
+ { .start = 0x00a02818, .end = 0x00a0281c },
+ { .start = 0x00a02c00, .end = 0x00a02db4 },
+ { .start = 0x00a02df4, .end = 0x00a02fb0 },
+ { .start = 0x00a03000, .end = 0x00a03014 },
+ { .start = 0x00a0301c, .end = 0x00a0302c },
+ { .start = 0x00a03034, .end = 0x00a03038 },
+ { .start = 0x00a03040, .end = 0x00a03048 },
+ { .start = 0x00a03060, .end = 0x00a03068 },
+ { .start = 0x00a03070, .end = 0x00a03074 },
+ { .start = 0x00a0307c, .end = 0x00a0307c },
+ { .start = 0x00a03080, .end = 0x00a03084 },
+ { .start = 0x00a0308c, .end = 0x00a03090 },
+ { .start = 0x00a03098, .end = 0x00a03098 },
+ { .start = 0x00a030a0, .end = 0x00a030a0 },
+ { .start = 0x00a030a8, .end = 0x00a030b4 },
+ { .start = 0x00a030bc, .end = 0x00a030bc },
+ { .start = 0x00a030c0, .end = 0x00a0312c },
+ { .start = 0x00a03c00, .end = 0x00a03c5c },
+ { .start = 0x00a04400, .end = 0x00a04454 },
+ { .start = 0x00a04460, .end = 0x00a04474 },
+ { .start = 0x00a044c0, .end = 0x00a044ec },
+ { .start = 0x00a04500, .end = 0x00a04504 },
+ { .start = 0x00a04510, .end = 0x00a04538 },
+ { .start = 0x00a04540, .end = 0x00a04548 },
+ { .start = 0x00a04560, .end = 0x00a0457c },
+ { .start = 0x00a04590, .end = 0x00a04598 },
+ { .start = 0x00a045c0, .end = 0x00a045f4 },
+};
+
+static u32 iwl_trans_pcie_dump_prph(struct iwl_trans *trans,
+ struct iwl_fw_error_dump_data **data)
+{
+ struct iwl_fw_error_dump_prph *prph;
+ unsigned long flags;
+ u32 prph_len = 0, i;
+
+ if (!iwl_trans_grab_nic_access(trans, false, &flags))
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
+ /* The range includes both boundaries */
+ int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
+ iwl_prph_dump_addr[i].start + 4;
+ int reg;
+ __le32 *val;
+
+ prph_len += sizeof(*data) + sizeof(*prph) +
+ num_bytes_in_chunk;
+
+ (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
+ (*data)->len = cpu_to_le32(sizeof(*prph) +
+ num_bytes_in_chunk);
+ prph = (void *)(*data)->data;
+ prph->prph_start = cpu_to_le32(iwl_prph_dump_addr[i].start);
+ val = (void *)prph->data;
+
+ for (reg = iwl_prph_dump_addr[i].start;
+ reg <= iwl_prph_dump_addr[i].end;
+ reg += 4)
+ *val++ = cpu_to_le32(iwl_trans_pcie_read_prph(trans,
+ reg));
+ *data = iwl_fw_error_next_data(*data);
+ }
+
+ iwl_trans_release_nic_access(trans, &flags);
+
+ return prph_len;
+}
+
+#define IWL_CSR_TO_DUMP (0x250)
+
+static u32 iwl_trans_pcie_dump_csr(struct iwl_trans *trans,
+ struct iwl_fw_error_dump_data **data)
+{
+ u32 csr_len = sizeof(**data) + IWL_CSR_TO_DUMP;
+ __le32 *val;
+ int i;
+
+ (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR);
+ (*data)->len = cpu_to_le32(IWL_CSR_TO_DUMP);
+ val = (void *)(*data)->data;
+
+ for (i = 0; i < IWL_CSR_TO_DUMP; i += 4)
+ *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
+
+ *data = iwl_fw_error_next_data(*data);
+
+ return csr_len;
+}
+
+static
+struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_fw_error_dump_data *data;
struct iwl_txq *cmdq = &trans_pcie->txq[trans_pcie->cmd_queue];
struct iwl_fw_error_dump_txcmd *txcmd;
+ struct iwl_trans_dump_data *dump_data;
u32 len;
int i, ptr;
- if (!buf)
- return sizeof(*data) +
- cmdq->q.n_window * (sizeof(*txcmd) +
- TFD_MAX_PAYLOAD_SIZE);
+ /* transport dump header */
+ len = sizeof(*dump_data);
+
+ /* host commands */
+ len += sizeof(*data) +
+ cmdq->q.n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
+
+ /* CSR registers */
+ len += sizeof(*data) + IWL_CSR_TO_DUMP;
+
+ /* PRPH registers */
+ for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
+ /* The range includes both boundaries */
+ int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
+ iwl_prph_dump_addr[i].start + 4;
+
+ len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_prph) +
+ num_bytes_in_chunk;
+ }
+
+ /* FW monitor */
+ if (trans_pcie->fw_mon_page)
+ len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
+ trans_pcie->fw_mon_size;
+
+ dump_data = vzalloc(len);
+ if (!dump_data)
+ return NULL;
len = 0;
- data = buf;
+ data = (void *)dump_data->data;
data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXCMD);
txcmd = (void *)data->data;
spin_lock_bh(&cmdq->lock);
@@ -1729,7 +1999,46 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
spin_unlock_bh(&cmdq->lock);
data->len = cpu_to_le32(len);
- return sizeof(*data) + len;
+ len += sizeof(*data);
+ data = iwl_fw_error_next_data(data);
+
+ len += iwl_trans_pcie_dump_prph(trans, &data);
+ len += iwl_trans_pcie_dump_csr(trans, &data);
+ /* data is already pointing to the next section */
+
+ if (trans_pcie->fw_mon_page) {
+ struct iwl_fw_error_dump_fw_mon *fw_mon_data;
+
+ data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
+ data->len = cpu_to_le32(trans_pcie->fw_mon_size +
+ sizeof(*fw_mon_data));
+ fw_mon_data = (void *)data->data;
+ fw_mon_data->fw_mon_wr_ptr =
+ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
+ fw_mon_data->fw_mon_cycle_cnt =
+ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT));
+ fw_mon_data->fw_mon_base_ptr =
+ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR));
+
+ /*
+ * The firmware is now asserted, it won't write anything to
+ * the buffer. CPU can take ownership to fetch the data.
+ * The buffer will be handed back to the device before the
+ * firmware will be restarted.
+ */
+ dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
+ trans_pcie->fw_mon_size,
+ DMA_FROM_DEVICE);
+ memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
+ trans_pcie->fw_mon_size);
+
+ len += sizeof(*data) + sizeof(*fw_mon_data) +
+ trans_pcie->fw_mon_size;
+ }
+
+ dump_data->len = len;
+
+ return dump_data;
}
#else
static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
@@ -1870,6 +2179,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
+ /*
+ * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
+ * changed, and now the revision step also includes bit 0-1 (no more
+ * "dash" value). To keep hw_rev backwards compatible - we'll store it
+ * in the old format.
+ */
+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+ trans->hw_rev = (trans->hw_rev & 0xfff0) |
+ ((trans->hw_rev << 2) & 0xc);
+
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
"PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 038940afbdc5..6acccb19c4f3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1438,6 +1438,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
trans_pcie->cmd_in_flight = false;
+ IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
idx = -EIO;
goto out;
}
diff --git a/drivers/net/wireless/libertas/Kconfig b/drivers/net/wireless/libertas/Kconfig
index 0485c9957575..e6268ceacbf1 100644
--- a/drivers/net/wireless/libertas/Kconfig
+++ b/drivers/net/wireless/libertas/Kconfig
@@ -16,7 +16,7 @@ config LIBERTAS_USB
config LIBERTAS_CS
tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
- depends on LIBERTAS && PCMCIA
+ depends on LIBERTAS && PCMCIA && HAS_IOPORT_MAP
---help---
A driver for Marvell Libertas 8385 CompactFlash devices.
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index aaa297315c47..0387a5b380c8 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1111,6 +1111,7 @@ int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
cmd.action = cpu_to_le16(CMD_ACT_SET);
+ cmd.control = 0;
/* Only v8 and below support setting the preamble */
if (priv->fwrelease < 0x09000000) {
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 0c02f0483d1f..569b64ecc607 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -981,7 +981,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
goto err_wdev;
}
- dev = alloc_netdev(0, "wlan%d", ether_setup);
+ dev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup);
if (!dev) {
dev_err(dmdev, "no memory for network device instance\n");
goto err_adapter;
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index 6fef746345bc..01a67f62696f 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1000,7 +1000,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
goto done;
}
- mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
+ mesh_dev = alloc_netdev(0, "msh%d", NET_NAME_UNKNOWN, ether_setup);
if (!mesh_dev) {
lbs_deb_mesh("init mshX device failed\n");
ret = -ENOMEM;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index a312c653d116..1326f6121835 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -685,11 +685,16 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
struct mac80211_hwsim_data *data = hw->priv;
u64 now = mac80211_hwsim_get_tsf(hw, vif);
u32 bcn_int = data->beacon_int;
- s64 delta = tsf - now;
+ u64 delta = abs64(tsf - now);
- data->tsf_offset += delta;
/* adjust after beaconing with new timestamp at old TBTT */
- data->bcn_delta = do_div(delta, bcn_int);
+ if (tsf > now) {
+ data->tsf_offset += delta;
+ data->bcn_delta = do_div(delta, bcn_int);
+ } else {
+ data->tsf_offset -= delta;
+ data->bcn_delta = -do_div(delta, bcn_int);
+ }
}
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
@@ -781,6 +786,36 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
netif_rx(skb);
}
+struct mac80211_hwsim_addr_match_data {
+ u8 addr[ETH_ALEN];
+ bool ret;
+};
+
+static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct mac80211_hwsim_addr_match_data *md = data;
+
+ if (memcmp(mac, md->addr, ETH_ALEN) == 0)
+ md->ret = true;
+}
+
+static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
+ const u8 *addr)
+{
+ struct mac80211_hwsim_addr_match_data md = {
+ .ret = false,
+ };
+
+ memcpy(md.addr, addr, ETH_ALEN);
+
+ ieee80211_iterate_active_interfaces_atomic(data->hw,
+ IEEE80211_IFACE_ITER_NORMAL,
+ mac80211_hwsim_addr_iter,
+ &md);
+
+ return md.ret;
+}
static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
struct sk_buff *skb)
@@ -798,8 +833,7 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
/* Allow unicast frames to own address if there is a pending
* PS-Poll */
if (data->ps_poll_pending &&
- memcmp(data->hw->wiphy->perm_addr, skb->data + 4,
- ETH_ALEN) == 0) {
+ mac80211_hwsim_addr_match(data, skb->data + 4)) {
data->ps_poll_pending = false;
return true;
}
@@ -809,39 +843,6 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
return true;
}
-
-struct mac80211_hwsim_addr_match_data {
- bool ret;
- const u8 *addr;
-};
-
-static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct mac80211_hwsim_addr_match_data *md = data;
- if (memcmp(mac, md->addr, ETH_ALEN) == 0)
- md->ret = true;
-}
-
-
-static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
- const u8 *addr)
-{
- struct mac80211_hwsim_addr_match_data md;
-
- if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0)
- return true;
-
- md.ret = false;
- md.addr = addr;
- ieee80211_iterate_active_interfaces_atomic(data->hw,
- IEEE80211_IFACE_ITER_NORMAL,
- mac80211_hwsim_addr_iter,
- &md);
-
- return md.ret;
-}
-
static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
struct sk_buff *my_skb,
int dst_portid)
@@ -1740,9 +1741,10 @@ static void hw_scan_work(struct work_struct *work)
static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
struct mac80211_hwsim_data *hwsim = hw->priv;
+ struct cfg80211_scan_request *req = &hw_req->req;
mutex_lock(&hwsim->mutex);
if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
@@ -2679,7 +2681,8 @@ static int __init init_mac80211_hwsim(void)
goto out_free_radios;
}
- hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
+ hwsim_mon = alloc_netdev(0, "hwsim%d", NET_NAME_UNKNOWN,
+ hwsim_mon_setup);
if (hwsim_mon == NULL) {
err = -ENOMEM;
goto out_free_radios;
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index 706831df1fa2..59d23fb2365f 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11ac
*
- * Copyright (C) 2013, Marvell International Ltd.
+ * Copyright (C) 2013-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 0b02cb6cfcb4..1ca92c7a8a4a 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11ac
*
- * Copyright (C) 2013, Marvell International Ltd.
+ * Copyright (C) 2013-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index e76b0db4e3e6..2668e83afbb6 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11h
*
- * Copyright (C) 2013, Marvell International Ltd.
+ * Copyright (C) 2013-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index e1c2f67ae85e..62f5dbe602d3 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -541,7 +541,6 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
{
struct host_cmd_ds_11n_addba_req add_ba_req;
- struct mwifiex_sta_node *sta_ptr;
u32 tx_win_size = priv->add_ba_param.tx_win_size;
static u8 dialog_tok;
int ret;
@@ -553,6 +552,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
priv->adapter->is_hw_11ac_capable &&
memcmp(priv->cfg_bssid, peer_mac, ETH_ALEN)) {
+ struct mwifiex_sta_node *sta_ptr;
+
sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
if (!sta_ptr) {
dev_warn(priv->adapter->dev,
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 0b73fa08f5d4..2ee268b632be 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 5b32106182f8..8720a3d3c755 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n Aggregation
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -185,6 +185,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
+ memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
tx_info_aggr->bss_type = tx_info_src->bss_type;
tx_info_aggr->bss_num = tx_info_src->bss_num;
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h
index 892098d6a696..0cd2a3eb6c17 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.h
+++ b/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n Aggregation
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 0c3571f830b0..06a2c215ef5e 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n RX Re-ordering
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -249,13 +249,22 @@ void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta)
* buffered in Rx reordering table.
*/
static int
-mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
+mwifiex_11n_find_last_seq_num(struct reorder_tmr_cnxt *ctx)
{
+ struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr;
+ struct mwifiex_private *priv = ctx->priv;
+ unsigned long flags;
int i;
- for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
- if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+ spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+ for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) {
+ if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ flags);
return i;
+ }
+ }
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
return -1;
}
@@ -274,7 +283,7 @@ mwifiex_flush_data(unsigned long context)
(struct reorder_tmr_cnxt *) context;
int start_win, seq_num;
- seq_num = mwifiex_11n_find_last_seq_num(ctx->ptr);
+ seq_num = mwifiex_11n_find_last_seq_num(ctx);
if (seq_num < 0)
return;
@@ -729,9 +738,9 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
}
+ INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
- INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
mwifiex_reset_11n_rx_seq_num(priv);
}
@@ -749,10 +758,14 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
priv = adapter->priv[i];
if (!priv)
continue;
- if (list_empty(&priv->rx_reorder_tbl_ptr))
- continue;
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
+ if (list_empty(&priv->rx_reorder_tbl_ptr)) {
+ spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+ lock_flags);
+ continue;
+ }
+
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
tbl->flags = flags;
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 0fc76e4a60f8..3a87bb0e3a62 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: 802.11n RX Re-ordering
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 2aa208ffbe23..9487d728ac20 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2011, Marvell International Ltd.
+# Copyright (C) 2011-2014, Marvell International Ltd.
#
# This software file (the "File") is distributed by Marvell International
# Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3b55ce5690a5..31928caeeed2 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -1,4 +1,4 @@
-# Copyright (C) 2011, Marvell International Ltd.
+# Copyright (C) 2011-2014, Marvell International Ltd.
#
# This software file (the "File") is distributed by Marvell International
# Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -194,6 +194,36 @@ rdeeprom
Example:
echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
+hscfg
+ This command is used to debug/simulate host sleep feature using
+ different configuration parameters.
+
+ Usage:
+ echo "<condition> [GPIO# [gap]]]" > hscfg
+ cat hscfg
+
+ where the parameters are,
+ <condition>: bit 0 = 1 -- broadcast data
+ bit 1 = 1 -- unicast data
+ bit 2 = 1 -- mac event
+ bit 3 = 1 -- multicast data
+ [GPIO#]: pin number of GPIO used to wakeup the host.
+ GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO
+ will be used instead).
+ [gap]: the gap in milliseconds between wakeup signal and
+ wakeup event or 0xff for special setting (host
+ acknowledge required) when GPIO is used to wakeup host.
+
+ Examples:
+ echo "-1" > hscfg : Cancel host sleep mode
+ echo "3" > hscfg : Broadcast and unicast data;
+ Use GPIO and gap set previously
+ echo "2 3" > hscfg : Unicast data and GPIO 3;
+ Use gap set previously
+ echo "2 1 160" > hscfg : Unicast data, GPIO 1 and gap 160 ms
+ echo "2 1 0xff" > hscfg : Unicast data, GPIO 1; Wait for host
+ to ack before sending wakeup event
+
getlog
This command is used to get the statistics available in the station.
Usage:
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e95dec91a561..e2e6bf13c2d8 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: CFG80211
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -42,36 +42,6 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
.beacon_int_infra_match = true,
};
-static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
- .n_reg_rules = 7,
- .alpha2 = "99",
- .reg_rules = {
- /* Channel 1 - 11 */
- REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
- /* Channel 12 - 13 */
- REG_RULE(2467-10, 2472+10, 20, 3, 20,
- NL80211_RRF_NO_IR),
- /* Channel 14 */
- REG_RULE(2484-10, 2484+10, 20, 3, 20,
- NL80211_RRF_NO_IR |
- NL80211_RRF_NO_OFDM),
- /* Channel 36 - 48 */
- REG_RULE(5180-10, 5240+10, 40, 3, 20,
- NL80211_RRF_NO_IR),
- /* Channel 149 - 165 */
- REG_RULE(5745-10, 5825+10, 40, 3, 20,
- NL80211_RRF_NO_IR),
- /* Channel 52 - 64 */
- REG_RULE(5260-10, 5320+10, 40, 3, 30,
- NL80211_RRF_NO_IR |
- NL80211_RRF_DFS),
- /* Channel 100 - 140 */
- REG_RULE(5500-10, 5700+10, 40, 3, 30,
- NL80211_RRF_NO_IR |
- NL80211_RRF_DFS),
- }
-};
-
/*
* This function maps the nl802.11 channel type into driver channel type.
*
@@ -151,7 +121,6 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
u16 pkt_len;
u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
- struct timeval tv;
pkt_len = len + ETH_ALEN;
@@ -173,8 +142,7 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
len - sizeof(struct ieee80211_hdr_3addr));
skb->priority = LOW_PRIO_TID;
- do_gettimeofday(&tv);
- skb->tstamp = timeval_to_ktime(tv);
+ __net_timestamp(skb);
return 0;
}
@@ -220,6 +188,7 @@ mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = pkt_len;
@@ -1635,9 +1604,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
return -EINVAL;
}
- /* disconnect before try to associate */
- mwifiex_deauthenticate(priv, NULL);
-
/* As this is new association, clear locally stored
* keys and security related flags */
priv->sec_info.wpa_enabled = false;
@@ -1775,6 +1741,11 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
return -EINVAL;
}
+ if (priv->wdev && priv->wdev->current_bss) {
+ wiphy_warn(wiphy, "%s: already connected\n", dev->name);
+ return -EALREADY;
+ }
+
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
(char *) sme->ssid, sme->bssid);
@@ -2263,7 +2234,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
}
dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
- ether_setup, IEEE80211_NUM_ACS, 1);
+ NET_NAME_UNKNOWN, ether_setup,
+ IEEE80211_NUM_ACS, 1);
if (!dev) {
wiphy_err(wiphy, "no memory available for netdevice\n");
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -2483,6 +2455,16 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
mef_entry->filter[filt_num].filt_type = TYPE_EQ;
if (filt_num)
mef_entry->filter[filt_num].filt_action = TYPE_OR;
+
+ filt_num++;
+ mef_entry->filter[filt_num].repeat = 16;
+ memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
+ ETH_ALEN);
+ mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
+ ETH_ALEN;
+ mef_entry->filter[filt_num].offset = 56;
+ mef_entry->filter[filt_num].filt_type = TYPE_EQ;
+ mef_entry->filter[filt_num].filt_action = TYPE_OR;
}
if (!mef_cfg.criteria)
@@ -2631,7 +2613,8 @@ static int
mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capability,
- const u8 *extra_ies, size_t extra_ies_len)
+ bool initiator, const u8 *extra_ies,
+ size_t extra_ies_len)
{
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int ret;
@@ -2916,12 +2899,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
- wiphy->regulatory_flags |=
- REGULATORY_CUSTOM_REG |
- REGULATORY_STRICT_REG;
-
- wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
-
#ifdef CONFIG_PM
wiphy->wowlan = &mwifiex_wowlan_support;
#endif
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index c5848934f111..908367857d58 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: CFG80211
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 0ddec3d4b059..b8242eb2be6f 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: Channel, Frequence and Power
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 8dee6c86f4f1..baf0aab63c04 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: commands and events
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -137,7 +137,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
struct host_cmd_ds_command *host_cmd;
uint16_t cmd_code;
uint16_t cmd_size;
- struct timeval tstamp;
unsigned long flags;
__le32 tmp;
@@ -198,10 +197,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
*/
skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
- do_gettimeofday(&tstamp);
- dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
- " seqno %#x\n",
- tstamp.tv_sec, tstamp.tv_usec, cmd_code,
+ dev_dbg(adapter->dev,
+ "cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n", cmd_code,
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
le16_to_cpu(host_cmd->seq_num));
@@ -283,6 +280,13 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
(adapter->seq_num, priv->bss_num,
priv->bss_type)));
+ dev_dbg(adapter->dev,
+ "cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n",
+ le16_to_cpu(sleep_cfm_buf->command),
+ le16_to_cpu(sleep_cfm_buf->action),
+ le16_to_cpu(sleep_cfm_buf->size),
+ le16_to_cpu(sleep_cfm_buf->seq_num));
+
if (adapter->iface_type == MWIFIEX_USB) {
sleep_cfm_tmp =
dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
@@ -433,7 +437,6 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
struct sk_buff *skb = adapter->event_skb;
u32 eventcause = adapter->event_cause;
- struct timeval tstamp;
struct mwifiex_rxinfo *rx_info;
/* Save the last event to debug log */
@@ -453,15 +456,13 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
if (skb) {
rx_info = MWIFIEX_SKB_RXCB(skb);
+ memset(rx_info, 0, sizeof(*rx_info));
rx_info->bss_num = priv->bss_num;
rx_info->bss_type = priv->bss_type;
}
- if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
- do_gettimeofday(&tstamp);
- dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
- tstamp.tv_sec, tstamp.tv_usec, eventcause);
- } else {
+ dev_dbg(adapter->dev, "EVENT: cause: %#x\n", eventcause);
+ if (eventcause == EVENT_PS_SLEEP || eventcause == EVENT_PS_AWAKE) {
/* Handle PS_SLEEP/AWAKE events on STA */
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
if (!priv)
@@ -772,7 +773,6 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
uint16_t orig_cmdresp_no;
uint16_t cmdresp_no;
uint16_t cmdresp_result;
- struct timeval tstamp;
unsigned long flags;
/* Now we got response from FW, cancel the command timer */
@@ -830,11 +830,10 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
orig_cmdresp_no;
- do_gettimeofday(&tstamp);
- dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
- " len %d, seqno 0x%x\n",
- tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
- le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
+ dev_dbg(adapter->dev,
+ "cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
+ orig_cmdresp_no, cmdresp_result,
+ le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
@@ -894,7 +893,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
struct mwifiex_adapter *adapter =
(struct mwifiex_adapter *) function_context;
struct cmd_ctrl_node *cmd_node;
- struct timeval tstamp;
adapter->is_cmd_timedout = 1;
if (!adapter->curr_cmd) {
@@ -907,10 +905,8 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
adapter->dbg.timeout_cmd_act =
adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
- do_gettimeofday(&tstamp);
dev_err(adapter->dev,
- "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n",
- __func__, tstamp.tv_sec, tstamp.tv_usec,
+ "%s: Timeout cmd id = %#x, act = %#x\n", __func__,
adapter->dbg.timeout_cmd_id,
adapter->dbg.timeout_cmd_act);
@@ -960,6 +956,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
mwifiex_init_fw_complete(adapter);
+ if (adapter->if_ops.fw_dump)
+ adapter->if_ops.fw_dump(adapter);
+
if (adapter->if_ops.card_reset)
adapter->if_ops.card_reset(adapter);
}
@@ -1231,6 +1230,10 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
return;
}
+ dev_dbg(adapter->dev,
+ "cmd: CMD_RESP: 0x%x, result %d, len %d, seqno 0x%x\n",
+ command, result, le16_to_cpu(cmd->size), seq_num);
+
/* Get BSS number and corresponding priv */
priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
HostCmd_GET_BSS_TYPE(seq_num));
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 7b419bbcd544..2713f7acd35e 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: debugfs
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -692,6 +692,97 @@ done:
return ret;
}
+/* Proc hscfg file write handler
+ * This function can be used to configure the host sleep parameters.
+ */
+static ssize_t
+mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv = (void *)file->private_data;
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *)addr;
+ size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
+ int ret, arg_num;
+ struct mwifiex_ds_hs_cfg hscfg;
+ int conditions = HS_CFG_COND_DEF;
+ u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, ubuf, buf_size)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
+
+ memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
+
+ if (arg_num > 3) {
+ dev_err(priv->adapter->dev, "Too many arguments\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (arg_num >= 1 && arg_num < 3)
+ mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
+ MWIFIEX_SYNC_CMD, &hscfg);
+
+ if (arg_num) {
+ if (conditions == HS_CFG_CANCEL) {
+ mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
+ ret = count;
+ goto done;
+ }
+ hscfg.conditions = conditions;
+ }
+ if (arg_num >= 2)
+ hscfg.gpio = gpio;
+ if (arg_num == 3)
+ hscfg.gap = gap;
+
+ hscfg.is_invoke_hostcmd = false;
+ mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
+ MWIFIEX_SYNC_CMD, &hscfg);
+
+ mwifiex_enable_hs(priv->adapter);
+ priv->adapter->hs_enabling = false;
+ ret = count;
+done:
+ free_page(addr);
+ return ret;
+}
+
+/* Proc hscfg file read handler
+ * This function can be used to read host sleep configuration
+ * parameters from driver.
+ */
+static ssize_t
+mwifiex_hscfg_read(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct mwifiex_private *priv = (void *)file->private_data;
+ unsigned long addr = get_zeroed_page(GFP_KERNEL);
+ char *buf = (char *)addr;
+ int pos, ret;
+ struct mwifiex_ds_hs_cfg hscfg;
+
+ if (!buf)
+ return -ENOMEM;
+
+ mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
+ MWIFIEX_SYNC_CMD, &hscfg);
+
+ pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
+ hscfg.gpio, hscfg.gap);
+
+ ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+ free_page(addr);
+ return ret;
+}
#define MWIFIEX_DFS_ADD_FILE(name) do { \
if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog);
MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
MWIFIEX_DFS_FILE_OPS(regrdwr);
MWIFIEX_DFS_FILE_OPS(rdeeprom);
+MWIFIEX_DFS_FILE_OPS(hscfg);
/*
* This function creates the debug FS directory structure and the files.
@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
MWIFIEX_DFS_ADD_FILE(regrdwr);
MWIFIEX_DFS_ADD_FILE(rdeeprom);
MWIFIEX_DFS_ADD_FILE(fw_dump);
+ MWIFIEX_DFS_ADD_FILE(hscfg);
}
/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 38da6ff6f416..0e03fe39fc35 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: generic data structures and APIs
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c
index bfb39908b2c6..04e56b5fc535 100644
--- a/drivers/net/wireless/mwifiex/ethtool.c
+++ b/drivers/net/wireless/mwifiex/ethtool.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: ethtool
*
- * Copyright (C) 2013, Marvell International Ltd.
+ * Copyright (C) 2013-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -64,7 +64,90 @@ static int mwifiex_ethtool_set_wol(struct net_device *dev,
return 0;
}
+static int
+mwifiex_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct memory_type_mapping *entry;
+
+ if (!adapter->if_ops.fw_dump)
+ return -ENOTSUPP;
+
+ dump->flag = adapter->curr_mem_idx;
+ dump->version = 1;
+ if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) {
+ entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
+ dump->len = entry->mem_size;
+ } else {
+ dump->len = 0;
+ }
+
+ return 0;
+}
+
+static int
+mwifiex_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
+ void *buffer)
+{
+ u8 *p = buffer;
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_adapter *adapter = priv->adapter;
+ struct memory_type_mapping *entry;
+
+ if (!adapter->if_ops.fw_dump)
+ return -ENOTSUPP;
+
+ if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
+ dev_err(adapter->dev, "firmware dump in progress!!\n");
+ return -EBUSY;
+ }
+
+ entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
+
+ if (!entry->mem_ptr)
+ return -EFAULT;
+
+ memcpy(p, entry->mem_ptr, entry->mem_size);
+
+ entry->mem_size = 0;
+ vfree(entry->mem_ptr);
+ entry->mem_ptr = NULL;
+
+ return 0;
+}
+
+static int mwifiex_set_dump(struct net_device *dev, struct ethtool_dump *val)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_adapter *adapter = priv->adapter;
+
+ if (!adapter->if_ops.fw_dump)
+ return -ENOTSUPP;
+
+ if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
+ dev_err(adapter->dev, "firmware dump in progress!!\n");
+ return -EBUSY;
+ }
+
+ if (val->flag == MWIFIEX_FW_DUMP_IDX) {
+ adapter->curr_mem_idx = val->flag;
+ adapter->if_ops.fw_dump(adapter);
+ return 0;
+ }
+
+ if (val->flag < 0 || val->flag >= adapter->num_mem_types)
+ return -EINVAL;
+
+ adapter->curr_mem_idx = val->flag;
+
+ return 0;
+}
+
const struct ethtool_ops mwifiex_ethtool_ops = {
.get_wol = mwifiex_ethtool_get_wol,
.set_wol = mwifiex_ethtool_set_wol,
+ .get_dump_flag = mwifiex_get_dump_flag,
+ .get_dump_data = mwifiex_get_dump_data,
+ .set_dump = mwifiex_set_dump,
};
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 3175dd04834b..49da2d53d294 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: Firmware specific macros & structures
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -713,7 +713,7 @@ struct mwifiex_ie_types_vendor_param_set {
u8 ie[MWIFIEX_MAX_VSIE_LEN];
};
-#define MWIFIEX_TDLS_IDLE_TIMEOUT 60
+#define MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC 60
struct mwifiex_ie_types_tdls_idle_timeout {
struct mwifiex_ie_types_header header;
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 3bf3d58bbc02..b933794758b7 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -2,7 +2,7 @@
* Marvell Wireless LAN device driver: management IE handling- setting and
* deleting IE.
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 4ecd0b208ac6..269a277d0a2e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: HW/FW Initialization
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -382,6 +382,8 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
static void
mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
{
+ int idx;
+
if (!adapter) {
pr_err("%s: adapter is NULL\n", __func__);
return;
@@ -396,7 +398,16 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
dev_dbg(adapter->dev, "info: free cmd buffer\n");
mwifiex_free_cmd_buffer(adapter);
- dev_dbg(adapter->dev, "info: free scan table\n");
+ for (idx = 0; idx < adapter->num_mem_types; idx++) {
+ struct memory_type_mapping *entry =
+ &adapter->mem_type_mapping_tbl[idx];
+
+ if (entry->mem_ptr) {
+ vfree(entry->mem_ptr);
+ entry->mem_ptr = NULL;
+ }
+ entry->mem_size = 0;
+ }
if (adapter->sleep_cfm)
dev_kfree_skb_any(adapter->sleep_cfm);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 1b576722671d..0847f3e07ab7 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: ioctl data structures & APIs
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 89dc62a467f4..8d6c25908b6d 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: association and ad-hoc start/join
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -949,7 +949,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
chan_tlv->chan_scan_param[0].radio_type |=
(IEEE80211_HT_PARAM_CHA_SEC_ABOVE << 4);
else if (adapter->sec_chan_offset ==
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW)
chan_tlv->chan_scan_param[0].radio_type |=
(IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
}
@@ -1288,8 +1288,6 @@ done:
int mwifiex_associate(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc)
{
- u8 current_bssid[ETH_ALEN];
-
/* Return error if the adapter is not STA role or table entry
* is not marked as infra.
*/
@@ -1304,10 +1302,6 @@ int mwifiex_associate(struct mwifiex_private *priv,
else
mwifiex_set_ba_params(priv);
- memcpy(&current_bssid,
- &priv->curr_bss_params.bss_descriptor.mac_address,
- sizeof(current_bssid));
-
/* Clear any past association response stored for application
retrieval */
priv->assoc_rsp_size = 0;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index cbabc12fbda3..dfa37eadc4db 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: major functions
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -33,6 +33,7 @@ static void scan_delay_timer_fn(unsigned long data)
struct mwifiex_private *priv = (struct mwifiex_private *)data;
struct mwifiex_adapter *adapter = priv->adapter;
struct cmd_ctrl_node *cmd_node, *tmp_node;
+ spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock;
unsigned long flags;
if (adapter->surprise_removed)
@@ -44,13 +45,13 @@ static void scan_delay_timer_fn(unsigned long data)
* Abort scan operation by cancelling all pending scan
* commands
*/
- spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ spin_lock_irqsave(scan_q_lock, flags);
list_for_each_entry_safe(cmd_node, tmp_node,
&adapter->scan_pending_q, list) {
list_del(&cmd_node->list);
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
}
- spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+ spin_unlock_irqrestore(scan_q_lock, flags);
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
adapter->scan_processing = false;
@@ -79,12 +80,17 @@ static void scan_delay_timer_fn(unsigned long data)
*/
adapter->scan_delay_cnt = 0;
adapter->empty_tx_q_cnt = 0;
- spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+ spin_lock_irqsave(scan_q_lock, flags);
+
+ if (list_empty(&adapter->scan_pending_q)) {
+ spin_unlock_irqrestore(scan_q_lock, flags);
+ goto done;
+ }
+
cmd_node = list_first_entry(&adapter->scan_pending_q,
struct cmd_ctrl_node, list);
list_del(&cmd_node->list);
- spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
- flags);
+ spin_unlock_irqrestore(scan_q_lock, flags);
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
true);
@@ -609,7 +615,6 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct sk_buff *new_skb;
struct mwifiex_txinfo *tx_info;
- struct timeval tv;
dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
jiffies, priv->bss_type, priv->bss_num);
@@ -645,6 +650,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = skb->len;
@@ -656,8 +662,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
* firmware for aggregate delay calculation for stats and
* MSDU lifetime expiry.
*/
- do_gettimeofday(&tv);
- skb->tstamp = timeval_to_ktime(tv);
+ __net_timestamp(skb);
mwifiex_queue_tx_pkt(priv, skb);
@@ -881,6 +886,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
goto err_kmalloc;
INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
+ if (adapter->if_ops.iface_work)
+ INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
/* Register the device. Fill up the private data structure with relevant
information from the card. */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1398afa84064..a2733b1e63f9 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: major data structures and prototypes
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -30,6 +30,7 @@
#include <linux/etherdevice.h>
#include <net/sock.h>
#include <net/lib80211.h>
+#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <linux/ctype.h>
#include <linux/of.h>
@@ -410,6 +411,29 @@ struct mwifiex_roc_cfg {
struct ieee80211_channel chan;
};
+#define MWIFIEX_FW_DUMP_IDX 0xff
+#define FW_DUMP_MAX_NAME_LEN 8
+#define FW_DUMP_HOST_READY 0xEE
+#define FW_DUMP_DONE 0xFF
+
+struct memory_type_mapping {
+ u8 mem_name[FW_DUMP_MAX_NAME_LEN];
+ u8 *mem_ptr;
+ u32 mem_size;
+ u8 done_flag;
+};
+
+enum rdwr_status {
+ RDWR_STATUS_SUCCESS = 0,
+ RDWR_STATUS_FAILURE = 1,
+ RDWR_STATUS_DONE = 2
+};
+
+enum mwifiex_iface_work_flags {
+ MWIFIEX_IFACE_WORK_FW_DUMP,
+ MWIFIEX_IFACE_WORK_CARD_RESET,
+};
+
struct mwifiex_adapter;
struct mwifiex_private;
@@ -674,6 +698,7 @@ struct mwifiex_if_ops {
void (*card_reset) (struct mwifiex_adapter *);
void (*fw_dump)(struct mwifiex_adapter *);
int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
+ void (*iface_work)(struct work_struct *work);
};
struct mwifiex_adapter {
@@ -809,6 +834,11 @@ struct mwifiex_adapter {
bool ext_scan;
u8 fw_api_ver;
u8 fw_key_api_major_ver, fw_key_api_minor_ver;
+ struct work_struct iface_work;
+ unsigned long iface_work_flags;
+ struct memory_type_mapping *mem_type_mapping_tbl;
+ u8 num_mem_types;
+ u8 curr_mem_idx;
};
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -890,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
void mwifiex_hs_activated_event(struct mwifiex_private *priv,
u8 activated);
+int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
+ int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg);
int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp);
int mwifiex_process_rx_packet(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 2cc9b6fca490..c16dd2cc8198 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: PCIE specific handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -37,6 +37,13 @@ static struct mwifiex_if_ops pcie_ops;
static struct semaphore add_remove_card_sem;
+static struct memory_type_mapping mem_type_mapping_tbl[] = {
+ {"ITCM", NULL, 0, 0xF0},
+ {"DTCM", NULL, 0, 0xF1},
+ {"SQRAM", NULL, 0, 0xF2},
+ {"IRAM", NULL, 0, 0xF3},
+};
+
static int
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
size_t size, int flags)
@@ -192,6 +199,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
card->pcie.reg = data->reg;
card->pcie.blksz_fw_dl = data->blksz_fw_dl;
card->pcie.tx_buf_size = data->tx_buf_size;
+ card->pcie.supports_fw_dump = data->supports_fw_dump;
}
if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -221,6 +229,8 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
if (!adapter || !adapter->priv_num)
return;
+ cancel_work_sync(&adapter->iface_work);
+
if (user_rmmod) {
#ifdef CONFIG_PM_SLEEP
if (adapter->is_suspended)
@@ -307,6 +317,17 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
return 0;
}
+/* This function reads u8 data from PCIE card register. */
+static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
+ int reg, u8 *data)
+{
+ struct pcie_service_card *card = adapter->card;
+
+ *data = ioread8(card->pci_mmap1 + reg);
+
+ return 0;
+}
+
/*
* This function adds delay loop to ensure FW is awake before proceeding.
*/
@@ -2173,6 +2194,168 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
return 0;
}
+/* This function read/write firmware */
+static enum rdwr_status
+mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
+{
+ int ret, tries;
+ u8 ctrl_data;
+ struct pcie_service_card *card = adapter->card;
+ const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+
+ ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
+ if (ret) {
+ dev_err(adapter->dev, "PCIE write err\n");
+ return RDWR_STATUS_FAILURE;
+ }
+
+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+ mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
+ if (ctrl_data == FW_DUMP_DONE)
+ return RDWR_STATUS_SUCCESS;
+ if (doneflag && ctrl_data == doneflag)
+ return RDWR_STATUS_DONE;
+ if (ctrl_data != FW_DUMP_HOST_READY) {
+ dev_info(adapter->dev,
+ "The ctrl reg was changed, re-try again!\n");
+ mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
+ FW_DUMP_HOST_READY);
+ if (ret) {
+ dev_err(adapter->dev, "PCIE write err\n");
+ return RDWR_STATUS_FAILURE;
+ }
+ }
+ usleep_range(100, 200);
+ }
+
+ dev_err(adapter->dev, "Fail to pull ctrl_data\n");
+ return RDWR_STATUS_FAILURE;
+}
+
+/* This function dump firmware memory to file */
+static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
+{
+ struct pcie_service_card *card = adapter->card;
+ const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
+ unsigned int reg, reg_start, reg_end;
+ u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
+ enum rdwr_status stat;
+ u32 memory_size;
+ static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
+
+ if (!card->pcie.supports_fw_dump)
+ return;
+
+ for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
+ struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
+
+ if (entry->mem_ptr) {
+ vfree(entry->mem_ptr);
+ entry->mem_ptr = NULL;
+ }
+ entry->mem_size = 0;
+ }
+
+ dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
+
+ /* Read the number of the memories which will dump */
+ stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+ if (stat == RDWR_STATUS_FAILURE)
+ goto done;
+
+ reg = creg->fw_dump_start;
+ mwifiex_read_reg_byte(adapter, reg, &dump_num);
+
+ /* Read the length of every memory which will dump */
+ for (idx = 0; idx < dump_num; idx++) {
+ struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
+
+ stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+ if (stat == RDWR_STATUS_FAILURE)
+ goto done;
+
+ memory_size = 0;
+ reg = creg->fw_dump_start;
+ for (i = 0; i < 4; i++) {
+ mwifiex_read_reg_byte(adapter, reg, &read_reg);
+ memory_size |= (read_reg << (i * 8));
+ reg++;
+ }
+
+ if (memory_size == 0) {
+ dev_info(adapter->dev, "Firmware dump Finished!\n");
+ break;
+ }
+
+ dev_info(adapter->dev,
+ "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
+ entry->mem_ptr = vmalloc(memory_size + 1);
+ entry->mem_size = memory_size;
+ if (!entry->mem_ptr) {
+ dev_err(adapter->dev,
+ "Vmalloc %s failed\n", entry->mem_name);
+ goto done;
+ }
+ dbg_ptr = entry->mem_ptr;
+ end_ptr = dbg_ptr + memory_size;
+
+ doneflag = entry->done_flag;
+ dev_info(adapter->dev, "Start %s output, please wait...\n",
+ entry->mem_name);
+
+ do {
+ stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
+ if (RDWR_STATUS_FAILURE == stat)
+ goto done;
+
+ reg_start = creg->fw_dump_start;
+ reg_end = creg->fw_dump_end;
+ for (reg = reg_start; reg <= reg_end; reg++) {
+ mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
+ if (dbg_ptr < end_ptr)
+ dbg_ptr++;
+ else
+ dev_err(adapter->dev,
+ "Allocated buf not enough\n");
+ }
+
+ if (stat != RDWR_STATUS_DONE)
+ continue;
+
+ dev_info(adapter->dev, "%s done: size=0x%tx\n",
+ entry->mem_name, dbg_ptr - entry->mem_ptr);
+ break;
+ } while (true);
+ }
+ dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
+
+ kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
+
+done:
+ adapter->curr_mem_idx = 0;
+}
+
+static void mwifiex_pcie_work(struct work_struct *work)
+{
+ struct mwifiex_adapter *adapter =
+ container_of(work, struct mwifiex_adapter, iface_work);
+
+ if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
+ &adapter->iface_work_flags))
+ mwifiex_pcie_fw_dump_work(adapter);
+}
+
+/* This function dumps FW information */
+static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
+{
+ if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
+ return;
+
+ set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
+
+ schedule_work(&adapter->iface_work);
+}
+
/*
* This function initializes the PCI-E host memory space, WCB rings, etc.
*
@@ -2342,6 +2525,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
adapter->dev = &pdev->dev;
adapter->tx_buf_size = card->pcie.tx_buf_size;
+ adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
+ adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
strcpy(adapter->fw_name, card->pcie.firmware);
return 0;
@@ -2394,6 +2579,8 @@ static struct mwifiex_if_ops pcie_ops = {
.cleanup_mpa_buf = NULL,
.init_fw_port = mwifiex_pcie_init_fw_port,
.clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
+ .fw_dump = mwifiex_pcie_fw_dump,
+ .iface_work = mwifiex_pcie_work,
};
/*
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index e8ec561f8a64..a1a8fd3bc1be 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -3,7 +3,7 @@
* @brief This file contains definitions for PCI-E interface.
* driver.
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -129,6 +129,9 @@ struct mwifiex_pcie_card_reg {
u32 ring_tx_start_ptr;
u8 pfu_enabled;
u8 sleep_cookie;
+ u16 fw_dump_ctrl;
+ u16 fw_dump_start;
+ u16 fw_dump_end;
};
static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = {
@@ -191,6 +194,9 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = {
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
.pfu_enabled = 1,
.sleep_cookie = 0,
+ .fw_dump_ctrl = 0xcf4,
+ .fw_dump_start = 0xcf8,
+ .fw_dump_end = 0xcff
};
struct mwifiex_pcie_device {
@@ -198,6 +204,7 @@ struct mwifiex_pcie_device {
const struct mwifiex_pcie_card_reg *reg;
u16 blksz_fw_dl;
u16 tx_buf_size;
+ bool supports_fw_dump;
};
static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
@@ -205,6 +212,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
.reg = &mwifiex_reg_8766,
.blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
+ .supports_fw_dump = false,
};
static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
@@ -212,6 +220,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
.reg = &mwifiex_reg_8897,
.blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
+ .supports_fw_dump = true,
};
struct mwifiex_evt_buf_desc {
@@ -322,4 +331,5 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
return 0;
}
+
#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 45c5b3450cf5..dee717a19ddb 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: scan ioctl and command handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 4ce3d7b33991..1770fa3fc1e6 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: SDIO specific handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -50,6 +50,24 @@ static struct mwifiex_if_ops sdio_ops;
static struct semaphore add_remove_card_sem;
+static struct memory_type_mapping mem_type_mapping_tbl[] = {
+ {"ITCM", NULL, 0, 0xF0},
+ {"DTCM", NULL, 0, 0xF1},
+ {"SQRAM", NULL, 0, 0xF2},
+ {"APU", NULL, 0, 0xF3},
+ {"CIU", NULL, 0, 0xF4},
+ {"ICU", NULL, 0, 0xF5},
+ {"MAC", NULL, 0, 0xF6},
+ {"EXT7", NULL, 0, 0xF7},
+ {"EXT8", NULL, 0, 0xF8},
+ {"EXT9", NULL, 0, 0xF9},
+ {"EXT10", NULL, 0, 0xFA},
+ {"EXT11", NULL, 0, 0xFB},
+ {"EXT12", NULL, 0, 0xFC},
+ {"EXT13", NULL, 0, 0xFD},
+ {"EXTLAST", NULL, 0, 0xFE},
+};
+
/*
* SDIO probe.
*
@@ -87,6 +105,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
card->tx_buf_size = data->tx_buf_size;
card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
+ card->supports_fw_dump = data->supports_fw_dump;
}
sdio_claim_host(func);
@@ -179,6 +198,8 @@ mwifiex_sdio_remove(struct sdio_func *func)
if (!adapter || !adapter->priv_num)
return;
+ cancel_work_sync(&adapter->iface_work);
+
if (user_rmmod) {
if (adapter->is_suspended)
mwifiex_sdio_resume(adapter->dev);
@@ -1777,6 +1798,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
adapter->dev = &func->dev;
strcpy(adapter->fw_name, card->firmware);
+ adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
+ adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
return 0;
}
@@ -1914,10 +1937,10 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
port, card->mp_data_port_mask);
}
-static struct mmc_host *reset_host;
-static void sdio_card_reset_worker(struct work_struct *work)
+static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
{
- struct mmc_host *target = reset_host;
+ struct sdio_mmc_card *card = adapter->card;
+ struct mmc_host *target = card->func->card->host;
/* The actual reset operation must be run outside of driver thread.
* This is because mmc_remove_host() will cause the device to be
@@ -1931,17 +1954,210 @@ static void sdio_card_reset_worker(struct work_struct *work)
mmc_remove_host(target);
/* 20ms delay is based on experiment with sdhci controller */
mdelay(20);
+ target->rescan_entered = 0; /* rescan non-removable cards */
mmc_add_host(target);
}
-static DECLARE_WORK(card_reset_work, sdio_card_reset_worker);
+
+/* This function read/write firmware */
+static enum
+rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
+ u8 doneflag)
+{
+ struct sdio_mmc_card *card = adapter->card;
+ int ret, tries;
+ u8 ctrl_data = 0;
+
+ sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl,
+ &ret);
+ if (ret) {
+ dev_err(adapter->dev, "SDIO Write ERR\n");
+ return RDWR_STATUS_FAILURE;
+ }
+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+ ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,
+ &ret);
+ if (ret) {
+ dev_err(adapter->dev, "SDIO read err\n");
+ return RDWR_STATUS_FAILURE;
+ }
+ if (ctrl_data == FW_DUMP_DONE)
+ break;
+ if (doneflag && ctrl_data == doneflag)
+ return RDWR_STATUS_DONE;
+ if (ctrl_data != FW_DUMP_HOST_READY) {
+ dev_info(adapter->dev,
+ "The ctrl reg was changed, re-try again!\n");
+ sdio_writeb(card->func, FW_DUMP_HOST_READY,
+ card->reg->fw_dump_ctrl, &ret);
+ if (ret) {
+ dev_err(adapter->dev, "SDIO write err\n");
+ return RDWR_STATUS_FAILURE;
+ }
+ }
+ usleep_range(100, 200);
+ }
+ if (ctrl_data == FW_DUMP_HOST_READY) {
+ dev_err(adapter->dev, "Fail to pull ctrl_data\n");
+ return RDWR_STATUS_FAILURE;
+ }
+
+ return RDWR_STATUS_SUCCESS;
+}
+
+/* This function dump firmware memory to file */
+static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
+{
+ struct mwifiex_adapter *adapter =
+ container_of(work, struct mwifiex_adapter, iface_work);
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+ unsigned int reg, reg_start, reg_end;
+ u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
+ enum rdwr_status stat;
+ u32 memory_size;
+ static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
+
+ if (!card->supports_fw_dump)
+ return;
+
+ for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
+ struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
+
+ if (entry->mem_ptr) {
+ vfree(entry->mem_ptr);
+ entry->mem_ptr = NULL;
+ }
+ entry->mem_size = 0;
+ }
+
+ mwifiex_pm_wakeup_card(adapter);
+ sdio_claim_host(card->func);
+
+ dev_info(adapter->dev, "== mwifiex firmware dump start ==\n");
+
+ stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
+ if (stat == RDWR_STATUS_FAILURE)
+ goto done;
+
+ reg = card->reg->fw_dump_start;
+ /* Read the number of the memories which will dump */
+ dump_num = sdio_readb(card->func, reg, &ret);
+ if (ret) {
+ dev_err(adapter->dev, "SDIO read memory length err\n");
+ goto done;
+ }
+
+ /* Read the length of every memory which will dump */
+ for (idx = 0; idx < dump_num; idx++) {
+ struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
+
+ stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
+ if (stat == RDWR_STATUS_FAILURE)
+ goto done;
+
+ memory_size = 0;
+ reg = card->reg->fw_dump_start;
+ for (i = 0; i < 4; i++) {
+ read_reg = sdio_readb(card->func, reg, &ret);
+ if (ret) {
+ dev_err(adapter->dev, "SDIO read err\n");
+ goto done;
+ }
+ memory_size |= (read_reg << i*8);
+ reg++;
+ }
+
+ if (memory_size == 0) {
+ dev_info(adapter->dev, "Firmware dump Finished!\n");
+ break;
+ }
+
+ dev_info(adapter->dev,
+ "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
+ entry->mem_ptr = vmalloc(memory_size + 1);
+ entry->mem_size = memory_size;
+ if (!entry->mem_ptr) {
+ dev_err(adapter->dev, "Vmalloc %s failed\n",
+ entry->mem_name);
+ goto done;
+ }
+ dbg_ptr = entry->mem_ptr;
+ end_ptr = dbg_ptr + memory_size;
+
+ doneflag = entry->done_flag;
+ dev_info(adapter->dev, "Start %s output, please wait...\n",
+ entry->mem_name);
+
+ do {
+ stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
+ if (stat == RDWR_STATUS_FAILURE)
+ goto done;
+
+ reg_start = card->reg->fw_dump_start;
+ reg_end = card->reg->fw_dump_end;
+ for (reg = reg_start; reg <= reg_end; reg++) {
+ *dbg_ptr = sdio_readb(card->func, reg, &ret);
+ if (ret) {
+ dev_err(adapter->dev,
+ "SDIO read err\n");
+ goto done;
+ }
+ if (dbg_ptr < end_ptr)
+ dbg_ptr++;
+ else
+ dev_err(adapter->dev,
+ "Allocated buf not enough\n");
+ }
+
+ if (stat != RDWR_STATUS_DONE)
+ continue;
+
+ dev_info(adapter->dev, "%s done: size=0x%tx\n",
+ entry->mem_name, dbg_ptr - entry->mem_ptr);
+ break;
+ } while (1);
+ }
+ dev_info(adapter->dev, "== mwifiex firmware dump end ==\n");
+
+ kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
+
+done:
+ sdio_release_host(card->func);
+ adapter->curr_mem_idx = 0;
+}
+
+static void mwifiex_sdio_work(struct work_struct *work)
+{
+ struct mwifiex_adapter *adapter =
+ container_of(work, struct mwifiex_adapter, iface_work);
+
+ if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
+ &adapter->iface_work_flags))
+ mwifiex_sdio_card_reset_work(adapter);
+ if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
+ &adapter->iface_work_flags))
+ mwifiex_sdio_fw_dump_work(work);
+}
/* This function resets the card */
static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
{
- struct sdio_mmc_card *card = adapter->card;
+ if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags))
+ return;
+
+ set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags);
+
+ schedule_work(&adapter->iface_work);
+}
+
+/* This function dumps FW information */
+static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
+{
+ if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
+ return;
- reset_host = card->func->card->host;
- schedule_work(&card_reset_work);
+ set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
+ schedule_work(&adapter->iface_work);
}
static struct mwifiex_if_ops sdio_ops = {
@@ -1964,6 +2180,8 @@ static struct mwifiex_if_ops sdio_ops = {
.cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
.event_complete = mwifiex_sdio_event_complete,
.card_reset = mwifiex_sdio_card_reset,
+ .iface_work = mwifiex_sdio_work,
+ .fw_dump = mwifiex_sdio_fw_dump,
};
/*
@@ -2001,7 +2219,6 @@ mwifiex_sdio_cleanup_module(void)
/* Set the flag as user is removing this module. */
user_rmmod = 1;
- cancel_work_sync(&card_reset_work);
sdio_unregister_driver(&mwifiex_sdio);
}
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 6eea30b43ed7..6b8835ec88f1 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: SDIO specific definitions
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -219,6 +219,9 @@ struct mwifiex_sdio_card_reg {
u8 rd_len_p0_l;
u8 rd_len_p0_u;
u8 card_misc_cfg_reg;
+ u8 fw_dump_ctrl;
+ u8 fw_dump_start;
+ u8 fw_dump_end;
};
struct sdio_mmc_card {
@@ -231,6 +234,7 @@ struct sdio_mmc_card {
u8 mp_agg_pkt_limit;
bool supports_sdio_new_mode;
bool has_control_mask;
+ bool supports_fw_dump;
u16 tx_buf_size;
u32 mp_tx_agg_buf_size;
u32 mp_rx_agg_buf_size;
@@ -257,6 +261,7 @@ struct mwifiex_sdio_device {
u8 mp_agg_pkt_limit;
bool supports_sdio_new_mode;
bool has_control_mask;
+ bool supports_fw_dump;
u16 tx_buf_size;
u32 mp_tx_agg_buf_size;
u32 mp_rx_agg_buf_size;
@@ -307,6 +312,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
.rd_len_p0_l = 0x0c,
.rd_len_p0_u = 0x0d,
.card_misc_cfg_reg = 0xcc,
+ .fw_dump_ctrl = 0xe2,
+ .fw_dump_start = 0xe3,
+ .fw_dump_end = 0xea,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
@@ -319,6 +327,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
.mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
.mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
+ .supports_fw_dump = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -331,6 +340,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
.mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
.mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
+ .supports_fw_dump = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -343,6 +353,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
.mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
.mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
+ .supports_fw_dump = false,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -355,6 +366,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
.mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
.mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
+ .supports_fw_dump = true,
};
/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 88202ce0c139..733de92a4c61 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: station command handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -1647,7 +1647,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
timeout = (void *)(pos + config_len);
timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
timeout->header.len = cpu_to_le16(sizeof(timeout->value));
- timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT);
+ timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT_IN_SEC);
config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout);
break;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 577f2979ed8f..08b78baeb846 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: station command response handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -908,7 +908,7 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
break;
default:
dev_err(priv->adapter->dev,
- "Unknown TDLS command action respnse %d", action);
+ "Unknown TDLS command action response %d", action);
return -1;
}
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index f6395ef11a72..f1c240eca0cd 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: station event handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 536c14aa71f3..caae9738100a 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: functions for station ioctl
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -26,7 +26,7 @@
#include "11n.h"
#include "cfg80211.h"
-static int disconnect_on_suspend = 1;
+static int disconnect_on_suspend;
module_param(disconnect_on_suspend, int, 0644);
/*
@@ -283,10 +283,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
u8 config_bands;
- ret = mwifiex_deauthenticate(priv, NULL);
- if (ret)
- goto done;
-
if (!bss_desc)
return -1;
@@ -345,12 +341,6 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
goto done;
}
- /* Exit Adhoc mode first */
- dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
- ret = mwifiex_deauthenticate(priv, NULL);
- if (ret)
- goto done;
-
priv->adhoc_is_link_sensed = false;
ret = mwifiex_check_network_compatibility(priv, bss_desc);
@@ -389,8 +379,8 @@ done:
* This function prepares the correct firmware command and
* issues it.
*/
-static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
- int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
+int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
+ int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
{
struct mwifiex_adapter *adapter = priv->adapter;
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 8b639d7fe6df..9ceb1dbe34c5 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: station RX data handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 5fce7e78a36e..dab7b33c54be 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: station TX data handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -150,6 +150,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
return -1;
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = data_len - (sizeof(struct txpd) + INTF_HEADER_LEN);
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index e73034fbbde9..4c5fd953893d 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -530,7 +530,6 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
{
struct sk_buff *skb;
struct mwifiex_txinfo *tx_info;
- struct timeval tv;
int ret;
u16 skb_len;
@@ -605,11 +604,11 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
- do_gettimeofday(&tv);
- skb->tstamp = timeval_to_ktime(tv);
+ __net_timestamp(skb);
mwifiex_queue_tx_pkt(priv, skb);
return 0;
@@ -702,7 +701,6 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
{
struct sk_buff *skb;
struct mwifiex_txinfo *tx_info;
- struct timeval tv;
u8 *pos;
u32 pkt_type, tx_control;
u16 pkt_len, skb_len;
@@ -760,6 +758,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
skb->priority = MWIFIEX_PRIO_VI;
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
@@ -767,8 +766,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
sizeof(pkt_len));
- do_gettimeofday(&tv);
- skb->tstamp = timeval_to_ktime(tv);
+ __net_timestamp(skb);
mwifiex_queue_tx_pkt(priv, skb);
return 0;
@@ -783,6 +781,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
struct mwifiex_sta_node *sta_ptr;
u8 *peer, *pos, *end;
u8 i, action, basic;
+ __le16 cap = 0;
int ie_len = 0;
if (len < (sizeof(struct ethhdr) + 3))
@@ -794,18 +793,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
peer = buf + ETH_ALEN;
action = *(buf + sizeof(struct ethhdr) + 2);
-
- /* just handle TDLS setup request/response/confirm */
- if (action > WLAN_TDLS_SETUP_CONFIRM)
- return;
-
dev_dbg(priv->adapter->dev,
"rx:tdls action: peer=%pM, action=%d\n", peer, action);
- sta_ptr = mwifiex_add_sta_entry(priv, peer);
- if (!sta_ptr)
- return;
-
switch (action) {
case WLAN_TDLS_SETUP_REQUEST:
if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
@@ -813,7 +803,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
pos = buf + sizeof(struct ethhdr) + 4;
/* payload 1+ category 1 + action 1 + dialog 1 */
- sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
+ cap = cpu_to_le16(*(u16 *)pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
pos += 2;
break;
@@ -823,7 +813,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
return;
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
pos = buf + sizeof(struct ethhdr) + 6;
- sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
+ cap = cpu_to_le16(*(u16 *)pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
pos += 2;
break;
@@ -835,10 +825,16 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
break;
default:
- dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n");
+ dev_dbg(priv->adapter->dev, "Unknown TDLS frame type.\n");
return;
}
+ sta_ptr = mwifiex_add_sta_entry(priv, peer);
+ if (!sta_ptr)
+ return;
+
+ sta_ptr->tdls_cap.capab = cap;
+
for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
if (pos + 2 + pos[1] > end)
break;
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 37f26afd4314..96a2126cc44b 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: generic TX/RX data handling
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -55,6 +55,7 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
return -1;
}
+ memset(rx_info, 0, sizeof(*rx_info));
rx_info->bss_num = priv->bss_num;
rx_info->bss_type = priv->bss_type;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 32643555dd2a..300bab438011 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: AP specific command handling
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 92e77a398ecf..7c2b97660a03 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: AP event handling
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 9a56bc61cb1d..ec7309d096ab 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: AP TX and RX data handling
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -96,7 +96,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
struct sk_buff *new_skb;
struct mwifiex_txinfo *tx_info;
int hdr_chop;
- struct timeval tv;
struct ethhdr *p_ethhdr;
uap_rx_pd = (struct uap_rxpd *)(skb->data);
@@ -175,6 +174,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT;
@@ -192,8 +192,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
tx_info->pkt_len = skb->len;
}
- do_gettimeofday(&tv);
- skb->tstamp = timeval_to_ktime(tv);
+ __net_timestamp(skb);
mwifiex_wmm_add_buf_txqueue(priv, skb);
atomic_inc(&adapter->tx_pending);
atomic_inc(&adapter->pending_bridged_pkts);
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index a8ce8130cfae..7118a18b91ba 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: USB specific handling
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 15b73d12e998..4c41c2a193c5 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -1,7 +1,7 @@
/*
* This file contains definitions for mwifiex USB interface driver.
*
- * Copyright (C) 2012, Marvell International Ltd.
+ * Copyright (C) 2012-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 6da5abf52e61..cee028321a9a 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: utility functions
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index caadb3737b9e..40296cb4a3f1 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: utility functions
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index d3671d009f6c..94c98a86ebbe 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: WMM
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -878,15 +878,8 @@ u8
mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
const struct sk_buff *skb)
{
+ u32 queue_delay = ktime_to_ms(net_timedelta(skb->tstamp));
u8 ret_val;
- struct timeval out_tstamp, in_tstamp;
- u32 queue_delay;
-
- do_gettimeofday(&out_tstamp);
- in_tstamp = ktime_to_timeval(skb->tstamp);
-
- queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
- queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
/*
* Queue delay is passed as a uint8 in units of 2ms (ms shifted
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index eca56e371a57..569bd73f33c5 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -1,7 +1,7 @@
/*
* Marvell Wireless LAN device driver: WMM
*
- * Copyright (C) 2011, Marvell International Ltd.
+ * Copyright (C) 2011-2014, Marvell International Ltd.
*
* This software file (the "File") is distributed by Marvell International
* Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 3c0a0a86ba12..9a3d4d6724f7 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1633,22 +1633,17 @@ static int mwl8k_tid_queue_mapping(u8 tid)
case 0:
case 3:
return IEEE80211_AC_BE;
- break;
case 1:
case 2:
return IEEE80211_AC_BK;
- break;
case 4:
case 5:
return IEEE80211_AC_VI;
- break;
case 6:
case 7:
return IEEE80211_AC_VO;
- break;
default:
return -1;
- break;
}
}
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index 60819bcf4377..60698b020851 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -107,7 +107,7 @@ config PCI_HERMES
config PCMCIA_HERMES
tristate "Hermes PCMCIA card support"
- depends on PCMCIA && HERMES
+ depends on PCMCIA && HERMES && HAS_IOPORT_MAP
---help---
A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -122,7 +122,7 @@ config PCMCIA_HERMES
config PCMCIA_SPECTRUM
tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
- depends on PCMCIA && HERMES
+ depends on PCMCIA && HERMES && HAS_IOPORT_MAP
---help---
This is a driver for 802.11b cards using RAM-loadable Symbol
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index c90939ced0e4..d3cf7c3ebfd6 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -921,7 +921,6 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv,
retval = -EFAULT;
}
goto exit;
- break;
}
if (ctx->in_rid) {
struct ezusb_packet *ans = ctx->buf;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index de15171e2cd8..63de5eed25cf 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -193,7 +193,7 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
/* allow users to customize their eeprom.
*/
- ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
+ ret = request_firmware_direct(&eeprom, "3826.eeprom", &priv->spi->dev);
if (ret < 0) {
#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
dev_info(&priv->spi->dev, "loading default eeprom...\n");
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 47b34bfe890a..3a8d2dbcfecd 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -793,7 +793,6 @@ mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
switch (isl_oid[n].flags & OID_FLAG_TYPE) {
case OID_TYPE_U32:
return snprintf(str, PRIV_STR_SIZE, "%u\n", r->u);
- break;
case OID_TYPE_BUFFER:{
struct obj_buffer *buff = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index cf61d6e3eaa7..f3d3995d8f6b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -77,6 +77,52 @@ static bool rsi_recalculate_weights(struct rsi_common *common)
}
/**
+ * rsi_get_num_pkts_dequeue() - This function determines the number of
+ * packets to be dequeued based on the number
+ * of bytes calculated using txop.
+ *
+ * @common: Pointer to the driver private structure.
+ * @q_num: the queue from which pkts have to be dequeued
+ *
+ * Return: pkt_num: Number of pkts to be dequeued.
+ */
+static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct sk_buff *skb;
+ u32 pkt_cnt = 0;
+ s16 txop = common->tx_qinfo[q_num].txop * 32;
+ __le16 r_txop;
+ struct ieee80211_rate rate;
+
+ rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */
+ if (q_num == VI_Q)
+ txop = ((txop << 5) / 80);
+
+ if (skb_queue_len(&common->tx_queue[q_num]))
+ skb = skb_peek(&common->tx_queue[q_num]);
+ else
+ return 0;
+
+ do {
+ r_txop = ieee80211_generic_frame_duration(adapter->hw,
+ adapter->vifs[0],
+ common->band,
+ skb->len, &rate);
+ txop -= le16_to_cpu(r_txop);
+ pkt_cnt += 1;
+ /*checking if pkts are still there*/
+ if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt)
+ skb = skb->next;
+ else
+ break;
+
+ } while (txop > 0);
+
+ return pkt_cnt;
+}
+
+/**
* rsi_core_determine_hal_queue() - This function determines the queue from
* which packet has to be dequeued.
* @common: Pointer to the driver private structure.
@@ -88,7 +134,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
bool recontend_queue = false;
u32 q_len = 0;
u8 q_num = INVALID_QUEUE;
- u8 ii = 0, min = 0;
+ u8 ii = 0;
if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
if (!common->mgmt_q_block)
@@ -96,6 +142,9 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
return q_num;
}
+ if (common->hw_data_qs_blocked)
+ return q_num;
+
if (common->pkt_cnt != 0) {
--common->pkt_cnt;
return common->selected_qnum;
@@ -106,14 +155,15 @@ get_queue_num:
q_num = rsi_determine_min_weight_queue(common);
- q_len = skb_queue_len(&common->tx_queue[ii]);
ii = q_num;
/* Selecting the queue with least back off */
for (; ii < NUM_EDCA_QUEUES; ii++) {
+ q_len = skb_queue_len(&common->tx_queue[ii]);
if (((common->tx_qinfo[ii].pkt_contended) &&
- (common->tx_qinfo[ii].weight < min)) && q_len) {
- min = common->tx_qinfo[ii].weight;
+ (common->tx_qinfo[ii].weight < common->min_weight)) &&
+ q_len) {
+ common->min_weight = common->tx_qinfo[ii].weight;
q_num = ii;
}
}
@@ -140,25 +190,9 @@ get_queue_num:
common->selected_qnum = q_num;
q_len = skb_queue_len(&common->tx_queue[q_num]);
- switch (common->selected_qnum) {
- case VO_Q:
- if (q_len > MAX_CONTINUOUS_VO_PKTS)
- common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1);
- else
- common->pkt_cnt = --q_len;
- break;
-
- case VI_Q:
- if (q_len > MAX_CONTINUOUS_VI_PKTS)
- common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1);
- else
- common->pkt_cnt = --q_len;
-
- break;
-
- default:
- common->pkt_cnt = 0;
- break;
+ if (q_num == VO_Q || q_num == VI_Q) {
+ common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num);
+ common->pkt_cnt -= 1;
}
return q_num;
@@ -252,6 +286,7 @@ void rsi_core_qos_processor(struct rsi_common *common)
skb = rsi_core_dequeue_pkt(common, q_num);
if (skb == NULL) {
+ rsi_dbg(ERR_ZONE, "skb null\n");
mutex_unlock(&common->tx_rxlock);
break;
}
@@ -306,7 +341,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
}
if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) ||
- (ieee80211_is_ctl(tmp_hdr->frame_control))) {
+ (ieee80211_is_ctl(tmp_hdr->frame_control)) ||
+ (ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) {
q_num = MGMT_SOFT_Q;
skb->priority = q_num;
} else {
@@ -325,6 +361,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
if ((q_num != MGMT_SOFT_Q) &&
((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
DATA_QUEUE_WATER_MARK)) {
+ rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
rsi_set_event(&common->tx_thread.event);
diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
index c466246a323f..828a042f903f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
+++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
@@ -145,7 +145,7 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
seq_printf(seq, "total_mgmt_pkt_send : %d\n",
common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]);
seq_printf(seq, "total_mgmt_pkt_queued : %d\n",
- skb_queue_len(&common->tx_queue[4]));
+ skb_queue_len(&common->tx_queue[MGMT_SOFT_Q]));
seq_printf(seq, "total_mgmt_pkt_freed : %d\n",
common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]);
@@ -153,25 +153,25 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
seq_printf(seq, "total_data_vo_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[VO_Q]);
seq_printf(seq, "total_data_vo_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[0]));
+ skb_queue_len(&common->tx_queue[VO_Q]));
seq_printf(seq, "total_vo_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[VO_Q]);
seq_printf(seq, "total_data_vi_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[VI_Q]);
seq_printf(seq, "total_data_vi_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[1]));
+ skb_queue_len(&common->tx_queue[VI_Q]));
seq_printf(seq, "total_vi_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[VI_Q]);
seq_printf(seq, "total_data_be_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[BE_Q]);
seq_printf(seq, "total_data_be_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[2]));
+ skb_queue_len(&common->tx_queue[BE_Q]));
seq_printf(seq, "total_be_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[BE_Q]);
seq_printf(seq, "total_data_bk_pkt_send: %8d\t",
common->tx_stats.total_tx_pkt_send[BK_Q]);
seq_printf(seq, "total_data_bk_pkt_queued: %8d\t",
- skb_queue_len(&common->tx_queue[3]));
+ skb_queue_len(&common->tx_queue[BK_Q]));
seq_printf(seq, "total_bk_pkt_freed: %8d\n",
common->tx_stats.total_tx_pkt_freed[BK_Q]);
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 54aaeb09debf..aeaf87bb5518 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -177,7 +177,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40);
- sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
+ sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
sbands->ht_cap.mcs.rx_mask[0] = 0xff;
sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
@@ -185,7 +185,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
}
/**
- * rsi_mac80211_attach() - This function is used to de-initialize the
+ * rsi_mac80211_detach() - This function is used to de-initialize the
* Mac80211 stack.
* @adapter: Pointer to the adapter structure.
*
@@ -341,6 +341,59 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
}
/**
+ * rsi_channel_change() - This function is a performs the checks
+ * required for changing a channel and sets
+ * the channel accordingly.
+ * @hw: Pointer to the ieee80211_hw structure.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int rsi_channel_change(struct ieee80211_hw *hw)
+{
+ struct rsi_hw *adapter = hw->priv;
+ struct rsi_common *common = adapter->priv;
+ int status = -EOPNOTSUPP;
+ struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+ u16 channel = curchan->hw_value;
+ struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
+
+ rsi_dbg(INFO_ZONE,
+ "%s: Set channel: %d MHz type: %d channel_no %d\n",
+ __func__, curchan->center_freq,
+ curchan->flags, channel);
+
+ if (bss->assoc) {
+ if (!common->hw_data_qs_blocked &&
+ (rsi_get_connected_channel(adapter) != channel)) {
+ rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
+ if (!rsi_send_block_unblock_frame(common, true))
+ common->hw_data_qs_blocked = true;
+ }
+ }
+
+ status = rsi_band_check(common);
+ if (!status)
+ status = rsi_set_channel(adapter->priv, channel);
+
+ if (bss->assoc) {
+ if (common->hw_data_qs_blocked &&
+ (rsi_get_connected_channel(adapter) == channel)) {
+ rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
+ if (!rsi_send_block_unblock_frame(common, false))
+ common->hw_data_qs_blocked = false;
+ }
+ } else {
+ if (common->hw_data_qs_blocked) {
+ rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
+ if (!rsi_send_block_unblock_frame(common, false))
+ common->hw_data_qs_blocked = false;
+ }
+ }
+
+ return status;
+}
+
+/**
* rsi_mac80211_config() - This function is a handler for configuration
* requests. The stack calls this function to
* change hardware configuration, e.g., channel.
@@ -357,17 +410,10 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
int status = -EOPNOTSUPP;
mutex_lock(&common->mutex);
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- struct ieee80211_channel *curchan = hw->conf.chandef.chan;
- u16 channel = curchan->hw_value;
-
- rsi_dbg(INFO_ZONE,
- "%s: Set channel: %d MHz type: %d channel_no %d\n",
- __func__, curchan->center_freq,
- curchan->flags, channel);
- common->band = curchan->band;
- status = rsi_set_channel(adapter->priv, channel);
- }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+ status = rsi_channel_change(hw);
+
mutex_unlock(&common->mutex);
return status;
@@ -421,6 +467,15 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->qos,
bss_conf->aid);
}
+
+ if (changed & BSS_CHANGED_CQM) {
+ common->cqm_info.last_cqm_event_rssi = 0;
+ common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
+ common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
+ rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
+ common->cqm_info.rssi_thold,
+ common->cqm_info.rssi_hyst);
+ }
mutex_unlock(&common->mutex);
}
@@ -723,17 +778,17 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
{
struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv;
+ enum ieee80211_band band = hw->conf.chandef.chan->band;
mutex_lock(&common->mutex);
+ common->fixedrate_mask[band] = 0;
- common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 0;
-
- if (mask->control[IEEE80211_BAND_2GHZ].legacy == 0xfff) {
- common->fixedrate_mask[IEEE80211_BAND_2GHZ] =
- (mask->control[IEEE80211_BAND_2GHZ].ht_mcs[0] << 12);
+ if (mask->control[band].legacy == 0xfff) {
+ common->fixedrate_mask[band] =
+ (mask->control[band].ht_mcs[0] << 12);
} else {
- common->fixedrate_mask[IEEE80211_BAND_2GHZ] =
- mask->control[IEEE80211_BAND_2GHZ].legacy;
+ common->fixedrate_mask[band] =
+ mask->control[band].legacy;
}
mutex_unlock(&common->mutex);
@@ -741,6 +796,37 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
}
/**
+ * rsi_perform_cqm() - This function performs cqm.
+ * @common: Pointer to the driver private structure.
+ * @bssid: pointer to the bssid.
+ * @rssi: RSSI value.
+ */
+static void rsi_perform_cqm(struct rsi_common *common,
+ u8 *bssid,
+ s8 rssi)
+{
+ struct rsi_hw *adapter = common->priv;
+ s8 last_event = common->cqm_info.last_cqm_event_rssi;
+ int thold = common->cqm_info.rssi_thold;
+ u32 hyst = common->cqm_info.rssi_hyst;
+ enum nl80211_cqm_rssi_threshold_event event;
+
+ if (rssi < thold && (last_event == 0 || rssi < (last_event - hyst)))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
+ else if (rssi > thold &&
+ (last_event == 0 || rssi > (last_event + hyst)))
+ event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+ else
+ return;
+
+ common->cqm_info.last_cqm_event_rssi = rssi;
+ rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
+ ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL);
+
+ return;
+}
+
+/**
* rsi_fill_rx_status() - This function fills rx status in
* ieee80211_rx_status structure.
* @hw: Pointer to the ieee80211_hw structure.
@@ -755,6 +841,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
struct rsi_common *common,
struct ieee80211_rx_status *rxs)
{
+ struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct skb_info *rx_params = (struct skb_info *)info->driver_data;
struct ieee80211_hdr *hdr;
@@ -770,10 +857,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
rxs->signal = -(rssi);
- if (channel <= 14)
- rxs->band = IEEE80211_BAND_2GHZ;
- else
- rxs->band = IEEE80211_BAND_5GHZ;
+ rxs->band = common->band;
freq = ieee80211_channel_to_frequency(channel, rxs->band);
@@ -792,6 +876,14 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
rxs->flag |= RX_FLAG_DECRYPTED;
rxs->flag |= RX_FLAG_IV_STRIPPED;
}
+
+ /* CQM only for connected AP beacons, the RSSI is a weighted avg */
+ if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) {
+ if (ieee80211_is_beacon(hdr->frame_control))
+ rsi_perform_cqm(common, hdr->addr2, rxs->signal);
+ }
+
+ return;
}
/**
@@ -983,6 +1075,7 @@ int rsi_mac80211_attach(struct rsi_common *common)
hw->max_tx_aggregation_subframes = 6;
rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ);
+ rsi_register_rates_channels(adapter, IEEE80211_BAND_5GHZ);
hw->rate_control_algorithm = "AARF";
SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
@@ -1000,6 +1093,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
wiphy->available_antennas_tx = 1;
wiphy->bands[IEEE80211_BAND_2GHZ] =
&adapter->sbands[IEEE80211_BAND_2GHZ];
+ wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &adapter->sbands[IEEE80211_BAND_5GHZ];
status = ieee80211_register_hw(hw);
if (status)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 2eefbf159bc0..8d110fd9eba1 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -217,6 +217,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
common->min_rate = 0xffff;
common->fsm_state = FSM_CARD_NOT_READY;
common->iface_down = true;
+ common->endpoint = EP_2GHZ_20MHZ;
}
/**
@@ -276,7 +277,6 @@ static int rsi_load_radio_caps(struct rsi_common *common)
{
struct rsi_radio_caps *radio_caps;
struct rsi_hw *adapter = common->priv;
- struct ieee80211_hw *hw = adapter->hw;
u16 inx = 0;
u8 ii;
u8 radio_id = 0;
@@ -285,7 +285,6 @@ static int rsi_load_radio_caps(struct rsi_common *common)
0xf0, 0xf0, 0xf0, 0xf0,
0xf0, 0xf0, 0xf0, 0xf0,
0xf0, 0xf0, 0xf0, 0xf0};
- struct ieee80211_conf *conf = &hw->conf;
struct sk_buff *skb;
rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__);
@@ -307,29 +306,36 @@ static int rsi_load_radio_caps(struct rsi_common *common)
if (common->channel_width == BW_40MHZ) {
radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ);
radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ);
- if (common->channel_width) {
- radio_caps->desc_word[5] =
- cpu_to_le16(common->channel_width << 12);
- radio_caps->desc_word[5] |= cpu_to_le16(FULL40M_ENABLE);
- }
- if (conf_is_ht40_minus(conf)) {
- radio_caps->desc_word[5] = 0;
- radio_caps->desc_word[5] |=
- cpu_to_le16(LOWER_20_ENABLE);
- radio_caps->desc_word[5] |=
- cpu_to_le16(LOWER_20_ENABLE >> 12);
- }
-
- if (conf_is_ht40_plus(conf)) {
- radio_caps->desc_word[5] = 0;
- radio_caps->desc_word[5] |=
- cpu_to_le16(UPPER_20_ENABLE);
- radio_caps->desc_word[5] |=
- cpu_to_le16(UPPER_20_ENABLE >> 12);
+ if (common->fsm_state == FSM_MAC_INIT_DONE) {
+ struct ieee80211_hw *hw = adapter->hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ if (conf_is_ht40_plus(conf)) {
+ radio_caps->desc_word[5] =
+ cpu_to_le16(LOWER_20_ENABLE);
+ radio_caps->desc_word[5] |=
+ cpu_to_le16(LOWER_20_ENABLE >> 12);
+ } else if (conf_is_ht40_minus(conf)) {
+ radio_caps->desc_word[5] =
+ cpu_to_le16(UPPER_20_ENABLE);
+ radio_caps->desc_word[5] |=
+ cpu_to_le16(UPPER_20_ENABLE >> 12);
+ } else {
+ radio_caps->desc_word[5] =
+ cpu_to_le16(BW_40MHZ << 12);
+ radio_caps->desc_word[5] |=
+ cpu_to_le16(FULL40M_ENABLE);
+ }
}
}
+ radio_caps->sifs_tx_11n = cpu_to_le16(SIFS_TX_11N_VALUE);
+ radio_caps->sifs_tx_11b = cpu_to_le16(SIFS_TX_11B_VALUE);
+ radio_caps->slot_rx_11n = cpu_to_le16(SHORT_SLOT_VALUE);
+ radio_caps->ofdm_ack_tout = cpu_to_le16(OFDM_ACK_TOUT_VALUE);
+ radio_caps->cck_ack_tout = cpu_to_le16(CCK_ACK_TOUT_VALUE);
+ radio_caps->preamble_type = cpu_to_le16(LONG_PREAMBLE);
+
radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8);
for (ii = 0; ii < MAX_HW_QUEUES; ii++) {
@@ -588,7 +594,7 @@ static int rsi_program_bb_rf(struct rsi_common *common)
mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA);
- mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint << 8);
+ mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint);
if (common->rf_reset) {
mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE);
@@ -615,6 +621,9 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode)
{
struct sk_buff *skb = NULL;
struct rsi_vap_caps *vap_caps;
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_hw *hw = adapter->hw;
+ struct ieee80211_conf *conf = &hw->conf;
u16 vap_id = 0;
rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__);
@@ -644,13 +653,24 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode)
vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD);
vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold);
- vap_caps->default_mgmt_rate = 0;
- if (conf_is_ht40(&common->priv->hw->conf)) {
- vap_caps->default_ctrl_rate =
- cpu_to_le32(RSI_RATE_6 | FULL40M_ENABLE << 16);
- } else {
+ vap_caps->default_mgmt_rate = cpu_to_le32(RSI_RATE_6);
+
+ if (common->band == IEEE80211_BAND_5GHZ) {
vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6);
+ if (conf_is_ht40(&common->priv->hw->conf)) {
+ vap_caps->default_ctrl_rate |=
+ cpu_to_le32(FULL40M_ENABLE << 16);
+ }
+ } else {
+ vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_1);
+ if (conf_is_ht40_minus(conf))
+ vap_caps->default_ctrl_rate |=
+ cpu_to_le32(UPPER_20_ENABLE << 16);
+ else if (conf_is_ht40_plus(conf))
+ vap_caps->default_ctrl_rate |=
+ cpu_to_le32(LOWER_20_ENABLE << 16);
}
+
vap_caps->default_data_rate = 0;
vap_caps->beacon_interval = cpu_to_le16(200);
vap_caps->dtim_period = cpu_to_le16(4);
@@ -827,6 +847,63 @@ static int rsi_send_reset_mac(struct rsi_common *common)
}
/**
+ * rsi_band_check() - This function programs the band
+ * @common: Pointer to the driver private structure.
+ *
+ * Return: 0 on success, corresponding error code on failure.
+ */
+int rsi_band_check(struct rsi_common *common)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_hw *hw = adapter->hw;
+ u8 prev_bw = common->channel_width;
+ u8 prev_ep = common->endpoint;
+ struct ieee80211_channel *curchan = hw->conf.chandef.chan;
+ int status = 0;
+
+ if (common->band != curchan->band) {
+ common->rf_reset = 1;
+ common->band = curchan->band;
+ }
+
+ if ((hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
+ (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20))
+ common->channel_width = BW_20MHZ;
+ else
+ common->channel_width = BW_40MHZ;
+
+ if (common->band == IEEE80211_BAND_2GHZ) {
+ if (common->channel_width)
+ common->endpoint = EP_2GHZ_40MHZ;
+ else
+ common->endpoint = EP_2GHZ_20MHZ;
+ } else {
+ if (common->channel_width)
+ common->endpoint = EP_5GHZ_40MHZ;
+ else
+ common->endpoint = EP_5GHZ_20MHZ;
+ }
+
+ if (common->endpoint != prev_ep) {
+ status = rsi_program_bb_rf(common);
+ if (status)
+ return status;
+ }
+
+ if (common->channel_width != prev_bw) {
+ status = rsi_load_bootup_params(common);
+ if (status)
+ return status;
+
+ status = rsi_load_radio_caps(common);
+ if (status)
+ return status;
+ }
+
+ return status;
+}
+
+/**
* rsi_set_channel() - This function programs the channel.
* @common: Pointer to the driver private structure.
* @channel: Channel value to be set.
@@ -841,23 +918,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
rsi_dbg(MGMT_TX_ZONE,
"%s: Sending scan req frame\n", __func__);
- if (common->band == IEEE80211_BAND_5GHZ) {
- if ((channel >= 36) && (channel <= 64))
- channel = ((channel - 32) / 4);
- else if ((channel > 64) && (channel <= 140))
- channel = ((channel - 102) / 4) + 8;
- else if (channel >= 149)
- channel = ((channel - 151) / 4) + 18;
- else
- return -EINVAL;
- } else {
- if (channel > 14) {
- rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n",
- __func__, channel, common->band);
- return -EINVAL;
- }
- }
-
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
@@ -877,6 +937,7 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
(RSI_RF_TYPE << 4));
mgmt_frame->desc_word[5] = cpu_to_le16(0x01);
+ mgmt_frame->desc_word[6] = cpu_to_le16(0x12);
if (common->channel_width == BW_40MHZ)
mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
@@ -950,7 +1011,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
struct ieee80211_hw *hw = common->priv->hw;
u8 band = hw->conf.chandef.chan->band;
u8 num_supported_rates = 0;
- u8 rate_offset = 0;
+ u8 rate_table_offset, rate_offset = 0;
u32 rate_bitmap = common->bitrate_mask[band];
u16 *selected_rates, min_rate;
@@ -986,14 +1047,19 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
if (common->channel_width == BW_40MHZ)
auto_rate->desc_word[7] |= cpu_to_le16(1);
- if (band == IEEE80211_BAND_2GHZ)
- min_rate = STD_RATE_01;
- else
- min_rate = STD_RATE_06;
+ if (band == IEEE80211_BAND_2GHZ) {
+ min_rate = RSI_RATE_1;
+ rate_table_offset = 0;
+ } else {
+ min_rate = RSI_RATE_6;
+ rate_table_offset = 4;
+ }
- for (ii = 0, jj = 0; ii < ARRAY_SIZE(rsi_rates); ii++) {
+ for (ii = 0, jj = 0;
+ ii < (ARRAY_SIZE(rsi_rates) - rate_table_offset); ii++) {
if (rate_bitmap & BIT(ii)) {
- selected_rates[jj++] = (rsi_rates[ii].bitrate / 5);
+ selected_rates[jj++] =
+ (rsi_rates[ii + rate_table_offset].bitrate / 5);
rate_offset++;
}
}
@@ -1006,13 +1072,6 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
rate_offset += ARRAY_SIZE(mcs);
}
- if (rate_offset < (RSI_TBL_SZ / 2) - 1) {
- for (ii = jj; ii < (RSI_TBL_SZ / 2); ii++) {
- selected_rates[jj++] = min_rate;
- rate_offset++;
- }
- }
-
sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL);
/* mapping the rates to RSI rates */
@@ -1028,25 +1087,25 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
/* loading HT rates in the bottom half of the auto rate table */
if (common->vif_info[0].is_ht) {
- if (common->vif_info[0].sgi)
- auto_rate->supported_rates[rate_offset++] =
- cpu_to_le16(RSI_RATE_MCS7_SG);
-
for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
- if (common->vif_info[0].sgi)
+ if (common->vif_info[0].sgi ||
+ conf_is_ht40(&common->priv->hw->conf))
auto_rate->supported_rates[ii++] =
cpu_to_le16(rsi_mcsrates[kk] | BIT(9));
auto_rate->supported_rates[ii] =
cpu_to_le16(rsi_mcsrates[kk--]);
}
- for (; ii < RSI_TBL_SZ; ii++) {
+ for (; ii < (RSI_TBL_SZ - 1); ii++) {
auto_rate->supported_rates[ii] =
cpu_to_le16(rsi_mcsrates[0]);
}
}
+ for (; ii < RSI_TBL_SZ; ii++)
+ auto_rate->supported_rates[ii] = cpu_to_le16(min_rate);
+
auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2);
auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2);
auto_rate->desc_word[7] |= cpu_to_le16(0 << 8);
@@ -1141,6 +1200,49 @@ static int rsi_eeprom_read(struct rsi_common *common)
}
/**
+ * This function sends a frame to block/unblock
+ * data queues in the firmware
+ *
+ * @param common Pointer to the driver private structure.
+ * @param block event - block if true, unblock if false
+ * @return 0 on success, -1 on failure.
+ */
+int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
+{
+ struct rsi_mac_frame *mgmt_frame;
+ struct sk_buff *skb;
+
+ rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
+
+ skb = dev_alloc_skb(FRAME_DESC_SZ);
+ if (!skb) {
+ rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ memset(skb->data, 0, FRAME_DESC_SZ);
+ mgmt_frame = (struct rsi_mac_frame *)skb->data;
+
+ mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
+ mgmt_frame->desc_word[1] = cpu_to_le16(BLOCK_HW_QUEUE);
+
+ if (block_event == true) {
+ rsi_dbg(INFO_ZONE, "blocking the data qs\n");
+ mgmt_frame->desc_word[4] = cpu_to_le16(0xf);
+ } else {
+ rsi_dbg(INFO_ZONE, "unblocking the data qs\n");
+ mgmt_frame->desc_word[5] = cpu_to_le16(0xf);
+ }
+
+ skb_put(skb, FRAME_DESC_SZ);
+
+ return rsi_send_internal_mgmt_frame(common, skb);
+
+}
+
+
+/**
* rsi_handle_ta_confirm_type() - This function handles the confirm frames.
* @common: Pointer to the driver private structure.
* @msg: Pointer to received packet.
@@ -1164,7 +1266,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
}
} else {
- rsi_dbg(ERR_ZONE,
+ rsi_dbg(INFO_ZONE,
"%s: Received bootup params cfm in %d state\n",
__func__, common->fsm_state);
return 0;
@@ -1227,7 +1329,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
__func__);
}
} else {
- rsi_dbg(ERR_ZONE,
+ rsi_dbg(INFO_ZONE,
"%s: Received radio caps cfm in %d state\n",
__func__, common->fsm_state);
return 0;
@@ -1245,7 +1347,10 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
return rsi_mac80211_attach(common);
}
} else {
- goto out;
+ rsi_dbg(INFO_ZONE,
+ "%s: Received bbb_rf cfm in %d state\n",
+ __func__, common->fsm_state);
+ return 0;
}
break;
diff --git a/drivers/net/wireless/rsi/rsi_91x_pkt.c b/drivers/net/wireless/rsi/rsi_91x_pkt.c
index 8e48e72bae20..702593f19997 100644
--- a/drivers/net/wireless/rsi/rsi_91x_pkt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_pkt.c
@@ -81,6 +81,16 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
/* Send fixed rate */
frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
frame_desc[4] = cpu_to_le16(common->min_rate);
+
+ if (conf_is_ht40(&common->priv->hw->conf))
+ frame_desc[5] = cpu_to_le16(FULL40M_ENABLE);
+
+ if (common->vif_info[0].sgi) {
+ if (common->min_rate & 0x100) /* Only MCS rates */
+ frame_desc[4] |=
+ cpu_to_le16(ENABLE_SHORTGI_RATE);
+ }
+
}
frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
@@ -116,6 +126,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
struct ieee80211_hdr *wh = NULL;
struct ieee80211_tx_info *info;
struct ieee80211_bss_conf *bss = NULL;
+ struct ieee80211_hw *hw = adapter->hw;
+ struct ieee80211_conf *conf = &hw->conf;
struct skb_info *tx_params;
int status = -E2BIG;
__le16 *msg = NULL;
@@ -175,6 +187,11 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
else
msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
+ if (conf_is_ht40(conf)) {
+ msg[4] = cpu_to_le16(0xB | RSI_11G_MODE);
+ msg[5] = cpu_to_le16(0x6);
+ }
+
/* Indicate to firmware to give cfm */
if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
msg[1] |= cpu_to_le16(BIT(10));
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 46e7af446f01..8428858204a6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -820,9 +820,11 @@ static struct sdio_driver rsi_driver = {
*/
static int rsi_module_init(void)
{
- sdio_register_driver(&rsi_driver);
+ int ret;
+
+ ret = sdio_register_driver(&rsi_driver);
rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
- return 0;
+ return ret;
}
/**
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 20d11ccfffe3..4834a9abc171 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -401,14 +401,16 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
case BUFFER_AVAILABLE:
dev->rx_info.watch_bufferfull_count = 0;
dev->rx_info.buffer_full = false;
+ dev->rx_info.semi_buffer_full = false;
dev->rx_info.mgmt_buffer_full = false;
rsi_sdio_ack_intr(common->priv,
(1 << PKT_BUFF_AVAILABLE));
- rsi_set_event((&common->tx_thread.event));
+ rsi_set_event(&common->tx_thread.event);
+
rsi_dbg(ISR_ZONE,
- "%s: ==> BUFFER_AVILABLE <==\n",
+ "%s: ==> BUFFER_AVAILABLE <==\n",
__func__);
- dev->rx_info.buf_avilable_counter++;
+ dev->rx_info.buf_available_counter++;
break;
case FIRMWARE_ASSERT_IND:
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 4c46e5631e2f..ef5d394f185b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -25,7 +25,7 @@
* @len: Length to be written.
* @endpoint: Type of endpoint.
*
- * Return: status: 0 on success, -1 on failure.
+ * Return: status: 0 on success, a negative error code on failure.
*/
static int rsi_usb_card_write(struct rsi_hw *adapter,
void *buf,
@@ -60,7 +60,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
* @data: Pointer to the data that has to be written.
* @count: Number of multiple bytes to be written.
*
- * Return: 0 on success, -1 on failure.
+ * Return: 0 on success, a negative error code on failure.
*/
static int rsi_write_multiple(struct rsi_hw *adapter,
u8 endpoint,
@@ -147,7 +147,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface,
* @value: Value to be read.
* @len: length of data to be read.
*
- * Return: status: 0 on success, -1 on failure.
+ * Return: status: 0 on success, a negative error code on failure.
*/
static int rsi_usb_reg_read(struct usb_device *usbdev,
u32 reg,
@@ -189,7 +189,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev,
* @value: Value to write.
* @len: Length of data to be written.
*
- * Return: status: 0 on success, -1 on failure.
+ * Return: status: 0 on success, a negative error code on failure.
*/
static int rsi_usb_reg_write(struct usb_device *usbdev,
u32 reg,
@@ -249,7 +249,7 @@ static void rsi_rx_done_handler(struct urb *urb)
* rsi_rx_urb_submit() - This function submits the given URB to the USB stack.
* @adapter: Pointer to the adapter structure.
*
- * Return: 0 on success, -1 on failure.
+ * Return: 0 on success, a negative error code on failure.
*/
static int rsi_rx_urb_submit(struct rsi_hw *adapter)
{
@@ -281,7 +281,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter)
* @data: Pointer to the data that has to be written.
* @count: Number of multiple bytes to be written on to the registers.
*
- * Return: status: 0 on success, -1 on failure.
+ * Return: status: 0 on success, a negative error code on failure.
*/
int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
u32 addr,
@@ -331,7 +331,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
* @pkt: Pointer to the data to be written on to the card.
* @len: Length of the data to be written on to the card.
*
- * Return: 0 on success, -1 on failure.
+ * Return: 0 on success, a negative error code on failure.
*/
static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u8 *pkt,
@@ -359,6 +359,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
rsi_kill_thread(&dev->rx_thread);
+ usb_free_urb(dev->rx_usb_urb[0]);
kfree(adapter->priv->rx_data_pkt);
kfree(dev->tx_buffer);
}
@@ -368,7 +369,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
* @adapter: Pointer to the adapter structure.
* @pfunction: Pointer to USB interface structure.
*
- * Return: 0 on success, -1 on failure.
+ * Return: 0 on success, a negative error code on failure.
*/
static int rsi_init_usb_interface(struct rsi_hw *adapter,
struct usb_interface *pfunction)
@@ -397,8 +398,16 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
return -ENOMEM;
}
- rsi_dev->tx_buffer = kmalloc(2048, GFP_ATOMIC);
+ rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL);
+ if (!rsi_dev->tx_buffer) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL);
+ if (!rsi_dev->rx_usb_urb[0]) {
+ status = -ENOMEM;
+ goto fail_rx;
+ }
rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt;
rsi_dev->tx_blk_size = 252;
@@ -413,7 +422,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
rsi_usb_rx_thread, "RX-Thread");
if (status) {
rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
- goto fail;
+ goto fail_thread;
}
#ifdef CONFIG_RSI_DEBUGFS
@@ -424,8 +433,11 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
return 0;
-fail:
+fail_thread:
+ usb_free_urb(rsi_dev->rx_usb_urb[0]);
+fail_rx:
kfree(rsi_dev->tx_buffer);
+fail_tx:
kfree(common->rx_data_pkt);
return status;
}
@@ -437,7 +449,7 @@ fail:
* @pfunction: Pointer to the USB interface structure.
* @id: Pointer to the usb_device_id structure.
*
- * Return: 0 on success, -1 on failure.
+ * Return: 0 on success, a negative error code on failure.
*/
static int rsi_probe(struct usb_interface *pfunction,
const struct usb_device_id *id)
@@ -445,6 +457,7 @@ static int rsi_probe(struct usb_interface *pfunction,
struct rsi_hw *adapter;
struct rsi_91x_usbdev *dev;
u16 fw_status;
+ int status;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
@@ -452,10 +465,11 @@ static int rsi_probe(struct usb_interface *pfunction,
if (!adapter) {
rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
__func__);
- return 1;
+ return -ENOMEM;
}
- if (rsi_init_usb_interface(adapter, pfunction)) {
+ status = rsi_init_usb_interface(adapter, pfunction);
+ if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
__func__);
goto err;
@@ -465,26 +479,30 @@ static int rsi_probe(struct usb_interface *pfunction,
dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
- if (rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2) < 0)
+ status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2);
+ if (status)
goto err1;
else
fw_status &= 1;
if (!fw_status) {
- if (rsi_usb_device_init(adapter->priv)) {
+ status = rsi_usb_device_init(adapter->priv);
+ if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
__func__);
goto err1;
}
- if (rsi_usb_reg_write(dev->usbdev,
- USB_INTERNAL_REG_1,
- RSI_USB_READY_MAGIC_NUM, 1) < 0)
+ status = rsi_usb_reg_write(dev->usbdev,
+ USB_INTERNAL_REG_1,
+ RSI_USB_READY_MAGIC_NUM, 1);
+ if (status)
goto err1;
rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__);
}
- if (rsi_rx_urb_submit(adapter))
+ status = rsi_rx_urb_submit(adapter);
+ if (status)
goto err1;
return 0;
@@ -493,7 +511,7 @@ err1:
err:
rsi_91x_deinit(adapter);
rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
- return 1;
+ return status;
}
/**
@@ -550,33 +568,7 @@ static struct usb_driver rsi_driver = {
#endif
};
-/**
- * rsi_module_init() - This function registers the client driver.
- * @void: Void.
- *
- * Return: 0 on success.
- */
-static int rsi_module_init(void)
-{
- usb_register(&rsi_driver);
- rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
- return 0;
-}
-
-/**
- * rsi_module_exit() - This function unregisters the client driver.
- * @void: Void.
- *
- * Return: None.
- */
-static void rsi_module_exit(void)
-{
- usb_deregister(&rsi_driver);
- rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
-}
-
-module_init(rsi_module_init);
-module_exit(rsi_module_exit);
+module_usb_driver(rsi_driver);
MODULE_AUTHOR("Redpine Signals Inc");
MODULE_DESCRIPTION("Common USB layer for RSI drivers");
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 2cb73e7edb98..5baed945f60e 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -115,6 +115,7 @@ struct wmm_qinfo {
s32 weight;
s32 wme_params;
s32 pkt_contended;
+ s32 txop;
};
struct transmit_q_stats {
@@ -141,6 +142,12 @@ struct rsi_thread {
atomic_t thread_done;
};
+struct cqm_info {
+ s8 last_cqm_event_rssi;
+ int rssi_thold;
+ u32 rssi_hyst;
+};
+
struct rsi_hw;
struct rsi_common {
@@ -192,6 +199,11 @@ struct rsi_common {
u8 selected_qnum;
u32 pkt_cnt;
u8 min_weight;
+
+ /* bgscan related */
+ struct cqm_info cqm_info;
+
+ bool hw_data_qs_blocked;
};
struct rsi_hw {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 225215a3b8bb..3741173fd3ac 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -69,6 +69,7 @@
#define RSI_LMAC_CLOCK_80MHZ 0x1
#define RSI_ENABLE_40MHZ (0x1 << 3)
+#define ENABLE_SHORTGI_RATE BIT(9)
#define RX_BA_INDICATION 1
#define RSI_TBL_SZ 40
@@ -123,6 +124,20 @@
#define BW_20MHZ 0
#define BW_40MHZ 1
+#define EP_2GHZ_20MHZ 0
+#define EP_2GHZ_40MHZ 1
+#define EP_5GHZ_20MHZ 2
+#define EP_5GHZ_40MHZ 3
+
+#define SIFS_TX_11N_VALUE 580
+#define SIFS_TX_11B_VALUE 346
+#define SHORT_SLOT_VALUE 360
+#define LONG_SLOT_VALUE 640
+#define OFDM_ACK_TOUT_VALUE 2720
+#define CCK_ACK_TOUT_VALUE 9440
+#define LONG_PREAMBLE 0x0000
+#define SHORT_PREAMBLE 0x0001
+
#define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\
FIF_BCN_PRBRESP_PROMISC)
enum opmode {
@@ -153,7 +168,7 @@ enum cmd_frame_type {
SCAN_REQUEST,
TSF_UPDATE,
PEER_NOTIFY,
- BLOCK_UNBLOCK,
+ BLOCK_HW_QUEUE,
SET_KEY_REQ,
AUTO_RATE_IND,
BOOTUP_PARAMS_REQUEST,
@@ -238,6 +253,12 @@ struct rsi_radio_caps {
u8 num_11n_rates;
u8 num_11ac_rates;
__le16 gcpd_per_rate[20];
+ __le16 sifs_tx_11n;
+ __le16 sifs_tx_11b;
+ __le16 slot_rx_11n;
+ __le16 ofdm_ack_tout;
+ __le16 cck_ack_tout;
+ __le16 preamble_type;
} __packed;
static inline u32 rsi_get_queueno(u8 *addr, u16 offset)
@@ -272,6 +293,7 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid,
int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
u8 key_type, u8 key_id, u32 cipher);
int rsi_set_channel(struct rsi_common *common, u16 chno);
+int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
void rsi_inform_bss_status(struct rsi_common *common, u8 status,
const u8 *bssid, u8 qos_enable, u16 aid);
void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
@@ -283,4 +305,5 @@ void rsi_core_qos_processor(struct rsi_common *common);
void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
+int rsi_band_check(struct rsi_common *common);
#endif
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index df4b5e20e05f..c7e8f2be7901 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -30,7 +30,7 @@
enum sdio_interrupt_type {
BUFFER_FULL = 0x0,
- BUFFER_AVAILABLE = 0x1,
+ BUFFER_AVAILABLE = 0x2,
FIRMWARE_ASSERT_IND = 0x3,
MSDU_PACKET_PENDING = 0x4,
UNKNOWN_INT = 0XE
@@ -42,7 +42,7 @@ enum sdio_interrupt_type {
#define PKT_MGMT_BUFF_FULL 2
#define MSDU_PKT_PENDING 3
/* Interrupt Bit Related Macros */
-#define PKT_BUFF_AVAILABLE 0
+#define PKT_BUFF_AVAILABLE 1
#define FW_ASSERT_IND 2
#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3
@@ -84,7 +84,7 @@ enum sdio_interrupt_type {
#define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF)
#define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF)
#define TA_BASE_ADDR 0x2200
-#define MISC_CFG_BASE_ADDR 0x4150
+#define MISC_CFG_BASE_ADDR 0x4105
struct receive_info {
bool buffer_full;
@@ -98,7 +98,7 @@ struct receive_info {
u32 total_sdio_msdu_pending_intr;
u32 total_sdio_unknown_intr;
u32 buf_full_counter;
- u32 buf_avilable_counter;
+ u32 buf_available_counter;
};
struct rsi_91x_sdiodev {
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c17fcf272728..893c9d5f3d6f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
}
+static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue = rt2x00dev->bcn;
+ struct queue_entry *entry;
+ int i, bcn_num = 0;
+ u64 off, reg = 0;
+ u32 bssid_dw1;
+
+ /*
+ * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
+ */
+ for (i = 0; i < queue->limit; i++) {
+ entry = &queue->entries[i];
+ if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
+ continue;
+ off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
+ reg |= off << (8 * bcn_num);
+ bcn_num++;
+ }
+
+ WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
+
+ rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
+ rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
+
+ /*
+ * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
+ */
+ rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
+ rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
+ bcn_num > 0 ? bcn_num - 1 : 0);
+ rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
+}
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
entry->skb->len + padding_len);
+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
+
+ /*
+ * Change global beacons settings.
+ */
+ rt2800_update_beacons_setup(rt2x00dev);
/*
* Restore beaconing state.
@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_entry *entry)
* Clear beacon.
*/
rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
+ __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
/*
+ * Change global beacons settings.
+ */
+ rt2800_update_beacons_setup(rt2x00dev);
+ /*
* Restore beaconing state.
*/
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
@@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
reg = le32_to_cpu(conf->bssid[1]);
rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
- rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
+ rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
conf->bssid[1] = cpu_to_le32(reg);
}
@@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
if (ret)
return ret;
- rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
- rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
- rt2800_get_beacon_offset(rt2x00dev, 0));
- rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
- rt2800_get_beacon_offset(rt2x00dev, 1));
- rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
- rt2800_get_beacon_offset(rt2x00dev, 2));
- rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
- rt2800_get_beacon_offset(rt2x00dev, 3));
- rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
-
- rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
- rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
- rt2800_get_beacon_offset(rt2x00dev, 4));
- rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
- rt2800_get_beacon_offset(rt2x00dev, 5));
- rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
- rt2800_get_beacon_offset(rt2x00dev, 6));
- rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
- rt2800_get_beacon_offset(rt2x00dev, 7));
- rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
-
rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index e11dab2216c6..573897b8e878 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -231,9 +231,12 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
*/
static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
{
- __le32 reg;
+ __le32 *reg;
u32 fw_mode;
+ reg = kmalloc(sizeof(*reg), GFP_KERNEL);
+ if (reg == NULL)
+ return -ENOMEM;
/* cannot use rt2x00usb_register_read here as it uses different
* mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
* magic value USB_MODE_AUTORUN (0x11) to the device, thus the
@@ -241,8 +244,9 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
*/
rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN,
- &reg, sizeof(reg), REGISTER_TIMEOUT_FIRMWARE);
- fw_mode = le32_to_cpu(reg);
+ reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE);
+ fw_mode = le32_to_cpu(*reg);
+ kfree(reg);
if ((fw_mode & 0x00000003) == 2)
return 1;
@@ -261,6 +265,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
int status;
u32 offset;
u32 length;
+ int retval;
/*
* Check which section of the firmware we need.
@@ -278,7 +283,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
- if (rt2800usb_autorun_detect(rt2x00dev)) {
+ retval = rt2800usb_autorun_detect(rt2x00dev);
+ if (retval < 0)
+ return retval;
+ if (retval) {
rt2x00_info(rt2x00dev,
"Firmware loading not required - NIC in AutoRun mode\n");
} else {
@@ -763,7 +771,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
*/
static int rt2800usb_efuse_detect(struct rt2x00_dev *rt2x00dev)
{
- if (rt2800usb_autorun_detect(rt2x00dev))
+ int retval;
+
+ retval = rt2800usb_autorun_detect(rt2x00dev);
+ if (retval < 0)
+ return retval;
+ if (retval)
return 1;
return rt2800_efuse_detect(rt2x00dev);
}
@@ -772,7 +785,10 @@ static int rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
{
int retval;
- if (rt2800usb_efuse_detect(rt2x00dev))
+ retval = rt2800usb_efuse_detect(rt2x00dev);
+ if (retval < 0)
+ return retval;
+ if (retval)
retval = rt2800_read_eeprom_efuse(rt2x00dev);
else
retval = rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
@@ -1268,6 +1284,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
/* Arcadyan */
{ USB_DEVICE(0x043e, 0x7a12) },
{ USB_DEVICE(0x043e, 0x7a32) },
+ /* ASUS */
+ { USB_DEVICE(0x0b05, 0x17e8) },
/* Azurewave */
{ USB_DEVICE(0x13d3, 0x3329) },
{ USB_DEVICE(0x13d3, 0x3365) },
@@ -1304,6 +1322,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x057c, 0x8501) },
/* Buffalo */
{ USB_DEVICE(0x0411, 0x0241) },
+ { USB_DEVICE(0x0411, 0x0253) },
/* D-Link */
{ USB_DEVICE(0x2001, 0x3c1a) },
{ USB_DEVICE(0x2001, 0x3c21) },
@@ -1394,6 +1413,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x0053) },
{ USB_DEVICE(0x0df6, 0x0069) },
{ USB_DEVICE(0x0df6, 0x006f) },
+ { USB_DEVICE(0x0df6, 0x0078) },
/* SMC */
{ USB_DEVICE(0x083a, 0xa512) },
{ USB_DEVICE(0x083a, 0xc522) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 4fa43a2eeb73..9967a1d9f0ec 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
return;
- if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
+ if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
+ mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_update_beacon(rt2x00dev, vif);
+ mutex_unlock(&intf->beacon_skb_mutex);
+ }
}
static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
* never be called for USB devices.
*/
WARN_ON(rt2x00_is_usb(rt2x00dev));
- rt2x00queue_update_beacon_locked(rt2x00dev, vif);
+ rt2x00queue_update_beacon(rt2x00dev, vif);
}
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
@@ -1470,8 +1473,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
/*
* Free the driver data.
*/
- if (rt2x00dev->drv_data)
- kfree(rt2x00dev->drv_data);
+ kfree(rt2x00dev->drv_data);
}
EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 004dff9b962d..ad6e5a8d1e10 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -626,25 +626,24 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* Start/stop beaconing.
*/
if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ mutex_lock(&intf->beacon_skb_mutex);
if (!bss_conf->enable_beacon && intf->enable_beacon) {
rt2x00dev->intf_beaconing--;
intf->enable_beacon = false;
- /*
- * Clear beacon in the H/W for this vif. This is needed
- * to disable beaconing on this particular interface
- * and keep it running on other interfaces.
- */
- rt2x00queue_clear_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 0) {
/*
* Last beaconing interface disabled
* -> stop beacon queue.
*/
- mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_stop_queue(rt2x00dev->bcn);
- mutex_unlock(&intf->beacon_skb_mutex);
}
+ /*
+ * Clear beacon in the H/W for this vif. This is needed
+ * to disable beaconing on this particular interface
+ * and keep it running on other interfaces.
+ */
+ rt2x00queue_clear_beacon(rt2x00dev, vif);
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
rt2x00dev->intf_beaconing++;
intf->enable_beacon = true;
@@ -660,11 +659,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* First beaconing interface enabled
* -> start beacon queue.
*/
- mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_start_queue(rt2x00dev->bcn);
- mutex_unlock(&intf->beacon_skb_mutex);
}
}
+ mutex_unlock(&intf->beacon_skb_mutex);
}
/*
@@ -801,6 +799,8 @@ int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
setup.tx = tx_ant;
setup.rx = rx_ant;
+ setup.rx_chain_num = 0;
+ setup.tx_chain_num = 0;
rt2x00lib_config_antenna(rt2x00dev, setup);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
index 6f236ea180aa..f0178fd4fe5f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -119,14 +119,12 @@ static int rt2x00mmio_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
/*
* Allocate DMA memory for descriptor and buffer.
*/
- addr = dma_alloc_coherent(rt2x00dev->dev,
- queue->limit * queue->desc_size,
- &dma, GFP_KERNEL);
+ addr = dma_zalloc_coherent(rt2x00dev->dev,
+ queue->limit * queue->desc_size, &dma,
+ GFP_KERNEL);
if (!addr)
return -ENOMEM;
- memset(addr, 0, queue->limit * queue->desc_size);
-
/*
* Initialize all queue entries to contain valid addresses.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 5642ccceca7c..8e68f87ab13c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
if (unlikely(!intf->beacon))
return -ENOBUFS;
- mutex_lock(&intf->beacon_skb_mutex);
-
/*
* Clean up the beacon skb.
*/
@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->ops->lib->clear_beacon)
rt2x00dev->ops->lib->clear_beacon(intf->beacon);
- mutex_unlock(&intf->beacon_skb_mutex);
-
return 0;
}
-int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif)
{
struct rt2x00_intf *intf = vif_to_intf(vif);
struct skb_frame_desc *skbdesc;
@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
}
-int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
-{
- struct rt2x00_intf *intf = vif_to_intf(vif);
- int ret;
-
- mutex_lock(&intf->beacon_skb_mutex);
- ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
- mutex_unlock(&intf->beacon_skb_mutex);
-
- return ret;
-}
-
bool rt2x00queue_for_each_entry(struct data_queue *queue,
enum queue_index start,
enum queue_index end,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index c48125be0e34..2233b911a1d7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -353,6 +353,7 @@ struct txentry_desc {
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
+ ENTRY_BCN_ENABLED,
ENTRY_OWNER_DEVICE_DATA,
ENTRY_DATA_PENDING,
ENTRY_DATA_IO_FAILED,
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 2c1c02bafa10..4b904f708184 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -16,6 +16,7 @@
*
* based also on:
* - portions of rtl8187se Linux staging driver, Copyright Realtek corp.
+ * (available in drivers/staging/rtl8187se directory of Linux 3.14)
* - other GPL, unpublished (until now), Linux driver code,
* Copyright Larry Finger <Larry.Finger@lwfinger.net>
*
@@ -209,7 +210,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
struct rtl8180_priv *priv = dev->priv;
struct rtl818x_rx_cmd_desc *cmd_desc;
unsigned int count = 32;
- u8 signal, agc, sq;
+ u8 agc, sq, signal = 1;
dma_addr_t mapping;
while (count--) {
@@ -222,12 +223,20 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
struct rtl8187se_rx_desc *desc = entry;
flags = le32_to_cpu(desc->flags);
+ /* if ownership flag is set, then we can trust the
+ * HW has written other fields. We must not trust
+ * other descriptor data read before we checked (read)
+ * the ownership flag
+ */
+ rmb();
flags2 = le32_to_cpu(desc->flags2);
tsft = le64_to_cpu(desc->tsft);
} else {
struct rtl8180_rx_desc *desc = entry;
flags = le32_to_cpu(desc->flags);
+ /* same as above */
+ rmb();
flags2 = le32_to_cpu(desc->flags2);
tsft = le64_to_cpu(desc->tsft);
}
@@ -266,18 +275,21 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.rate_idx = (flags >> 20) & 0xF;
agc = (flags2 >> 17) & 0x7F;
- if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) {
+ switch (priv->chip_family) {
+ case RTL818X_CHIP_FAMILY_RTL8185:
if (rx_status.rate_idx > 3)
- signal = 90 - clamp_t(u8, agc, 25, 90);
+ signal = -clamp_t(u8, agc, 25, 90) - 9;
else
- signal = 95 - clamp_t(u8, agc, 30, 95);
- } else if (priv->chip_family ==
- RTL818X_CHIP_FAMILY_RTL8180) {
+ signal = -clamp_t(u8, agc, 30, 95);
+ break;
+ case RTL818X_CHIP_FAMILY_RTL8180:
sq = flags2 & 0xff;
signal = priv->rf->calc_rssi(agc, sq);
- } else {
+ break;
+ case RTL818X_CHIP_FAMILY_RTL8187SE:
/* TODO: rtl8187se rssi */
signal = 10;
+ break;
}
rx_status.signal = signal;
rx_status.freq = dev->conf.chandef.chan->center_freq;
@@ -336,7 +348,6 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
info->flags |= IEEE80211_TX_STAT_ACK;
info->status.rates[0].count = (flags & 0xFF) + 1;
- info->status.rates[1].idx = -1;
ieee80211_tx_status_irqsafe(dev, skb);
if (ring->entries - skb_queue_len(&ring->queue) == 2)
@@ -528,9 +539,7 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
entry->plcp_len = cpu_to_le16(plcp_len);
entry->tx_buf = cpu_to_le32(mapping);
- entry->flags2 = info->control.rates[1].idx >= 0 ?
- ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
- entry->retry_limit = info->control.rates[0].count;
+ entry->retry_limit = info->control.rates[0].count - 1;
/* We must be sure that tx_flags is written last because the HW
* looks at it to check if the rest of data is valid or not
@@ -852,7 +861,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
- rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+ rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
} else {
rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
@@ -868,6 +877,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ /* fix eccessive IFS after CTS-to-self */
+ if (priv->map_pio) {
+ u8 reg;
+
+ reg = rtl818x_ioread8(priv, &priv->map->PGSELECT);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
+ rtl818x_iowrite8(priv, REG_ADDR1(0xff), 0x35);
+ rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+ } else
+ rtl818x_iowrite8(priv, REG_ADDR1(0x1ff), 0x35);
}
if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
@@ -1450,9 +1469,10 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
if (changed & BSS_CHANGED_BSSID) {
- for (i = 0; i < ETH_ALEN; i++)
- rtl818x_iowrite8(priv, &priv->map->BSSID[i],
- info->bssid[i]);
+ rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->BSSID[0],
+ le16_to_cpu(*(__le16 *)info->bssid));
+ rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->BSSID[2],
+ le32_to_cpu(*(__le32 *)(info->bssid + 2)));
if (is_valid_ether_addr(info->bssid)) {
if (vif->type == NL80211_IFTYPE_ADHOC)
@@ -1723,17 +1743,20 @@ static int rtl8180_probe(struct pci_dev *pdev,
priv = dev->priv;
priv->pdev = pdev;
- dev->max_rates = 2;
+ dev->max_rates = 1;
SET_IEEE80211_DEV(dev, &pdev->dev);
pci_set_drvdata(pdev, dev);
+ priv->map_pio = false;
priv->map = pci_iomap(pdev, 1, mem_len);
- if (!priv->map)
+ if (!priv->map) {
priv->map = pci_iomap(pdev, 0, io_len);
+ priv->map_pio = true;
+ }
if (!priv->map) {
- printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot map device memory/PIO\n");
+ err = -ENOMEM;
goto err_free_dev;
}
@@ -1751,8 +1774,7 @@ static int rtl8180_probe(struct pci_dev *pdev,
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_UNSPEC;
+ IEEE80211_HW_RX_INCLUDES_FCS;
dev->vif_data_size = sizeof(struct rtl8180_vif);
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
@@ -1783,12 +1805,19 @@ static int rtl8180_probe(struct pci_dev *pdev,
case RTL818X_TX_CONF_RTL8187SE:
chip_name = "RTL8187SE";
+ if (priv->map_pio) {
+ dev_err(&pdev->dev,
+ "MMIO failed. PIO not supported on RTL8187SE\n");
+ err = -ENOMEM;
+ goto err_iounmap;
+ }
priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE;
break;
default:
printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
pci_name(pdev), reg >> 25);
+ err = -ENODEV;
goto err_iounmap;
}
@@ -1809,6 +1838,11 @@ static int rtl8180_probe(struct pci_dev *pdev,
pci_try_set_mwi(pdev);
}
+ if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185)
+ dev->flags |= IEEE80211_HW_SIGNAL_DBM;
+ else
+ dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
+
rtl8180_eeprom_read(priv);
switch (priv->rf_type) {
@@ -1834,12 +1868,14 @@ static int rtl8180_probe(struct pci_dev *pdev,
default:
printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
pci_name(pdev), priv->rf_type);
+ err = -ENODEV;
goto err_iounmap;
}
if (!priv->rf) {
printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
pci_name(pdev), rf_name);
+ err = -ENODEV;
goto err_iounmap;
}
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
index 291a55970d1a..e8243a44d6b6 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
@@ -107,6 +107,7 @@ struct rtl8180_priv {
struct ieee80211_vif *vif;
/* rtl8180 driver specific */
+ bool map_pio;
spinlock_t lock;
void *rx_ring;
u8 rx_ring_sz;
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
index 871fc3c6d559..049f4c8d98a8 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -114,7 +114,7 @@ extern u32 btc_dbg_type[];
#define CL_SPRINTF snprintf
-#define CL_PRINTF printk
+#define CL_PRINTF(buf) printk("%s", buf)
#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
do { \
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index b1ed6d0796f6..56e218e0469c 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1064,7 +1064,6 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
"IEEE80211_AMPDU_TX_START: TID:%d\n", tid);
return rtl_tx_agg_start(hw, sta, tid, ssn);
- break;
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index b14cf5a10f44..d840ad7bdf65 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -1231,7 +1231,7 @@ static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0xfc) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c
index a9cfa13be3a8..0f9314205526 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c
@@ -125,7 +125,6 @@ bool rtl88_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
"rtl88_hal_pwrseqcmdparsing(): PWR_CMD_END\n");
return true;
- break;
default:
RT_ASSERT(false,
"rtl88_hal_pwrseqcmdparsing(): Unknown CMD!!\n");
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
index 7af85cfa8f87..cd7e7a527133 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
@@ -411,6 +411,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index cdecb0fd4d8e..df98a5e4729a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -1200,13 +1200,12 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Network type %d not supported!\n", type);
return 1;
- break;
}
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0xfc) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index ed703a1b3b7c..dc8460c0b32f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -375,6 +375,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index a903c2671b4d..270cbffcac70 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1360,7 +1360,7 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
}
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0xfc) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 2b08671004a0..280c3da42993 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1128,7 +1128,7 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
}
rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0xfc) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 3d1f0dd4e52d..592125a5f19c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -203,11 +203,12 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u32 returnvalue, originalvalue, bitshift;
- u8 dbi_direct;
RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
regaddr, bitmask);
if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
+ u8 dbi_direct = 0;
+
/* mac1 use phy0 read radio_b. */
/* mac0 use phy1 read radio_b. */
if (rtlhal->during_mac1init_radioa)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
index 7f29b8d765b3..315a298bab06 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
@@ -369,6 +369,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */
/* ----------------------------------------------------- */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
index 380e7d4b1ccf..331b1584a1a2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -112,13 +112,10 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
switch (rtlphy->rf_type) {
case RF_1T1R:
return 0x11;
- break;
case RF_1T2R:
return 0x12;
- break;
case RF_2T2R:
return 0x22;
- break;
default:
RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n",
rtlphy->rf_type);
@@ -438,7 +435,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Unexpected Download step!!\n");
goto fail;
- break;
}
/* <2> Download image file */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 1c7101bcd790..00e067044c08 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -1198,7 +1198,6 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Network type %d not supported!\n", type);
return 1;
- break;
}
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index 87f69166a7ed..662a079f76f3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -1103,13 +1103,12 @@ static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,
"Network type %d not supported!\n",
type);
return 1;
- break;
}
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0x03) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
index 64376b38708b..ce2c66fd9eee 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
@@ -361,6 +361,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
index 3d555495b453..3cd286930fe0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -1197,7 +1197,7 @@ static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
}
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & 0x03) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
index e4a507a756fb..4573310c707f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c
@@ -124,7 +124,6 @@ bool rtlbe_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version,
"rtlbe_hal_pwrseqcmdparsing(): "
"PWR_CMD_END\n");
return true;
- break;
default:
RT_ASSERT(false,
"rtlbe_hal_pwrseqcmdparsing(): "
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
index 4c653fab8795..3006849ed439 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
@@ -412,6 +412,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 4e782f18ae34..38234851457e 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -991,8 +991,9 @@ out:
static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
+ struct cfg80211_scan_request *req = &hw_req->req;
struct wl1251 *wl = hw->priv;
struct sk_buff *skb;
size_t ssid_len = 0;
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index d50dfac91631..0bccf123831e 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1668,7 +1668,7 @@ static bool wl12xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
{
u8 thold;
- if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map))
+ if (test_bit(hlid, &wl->fw_fast_lnk_map))
thold = wl->conf.tx.fast_link_thold;
else
thold = wl->conf.tx.slow_link_thold;
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index 7541bd1a4a4b..0c0d5cd98514 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -156,7 +156,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
cmd->params.role_id, band,
wl->scan.ssid, wl->scan.ssid_len,
wl->scan.req->ie,
- wl->scan.req->ie_len, false);
+ wl->scan.req->ie_len, NULL, 0, false);
if (ret < 0) {
wl1271_error("PROBE request template failed");
goto out;
@@ -317,7 +317,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
int wl1271_scan_sched_scan_config(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
struct wl1271_cmd_sched_scan_config *cfg = NULL;
struct wlcore_scan_channels *cfg_channels = NULL;
@@ -378,8 +378,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
wlvif->role_id, band,
req->ssids[0].ssid,
req->ssids[0].ssid_len,
- ies->ie[band],
- ies->len[band], true);
+ ies->ies[band],
+ ies->len[band],
+ ies->common_ies,
+ ies->common_ie_len,
+ true);
if (ret < 0) {
wl1271_error("2.4GHz PROBE request template failed");
goto out;
@@ -392,8 +395,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
wlvif->role_id, band,
req->ssids[0].ssid,
req->ssids[0].ssid_len,
- ies->ie[band],
- ies->len[band], true);
+ ies->ies[band],
+ ies->len[band],
+ ies->common_ies,
+ ies->common_ie_len,
+ true);
if (ret < 0) {
wl1271_error("5GHz PROBE request template failed");
goto out;
@@ -449,7 +455,7 @@ out_free:
int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
int ret;
diff --git a/drivers/net/wireless/ti/wl12xx/scan.h b/drivers/net/wireless/ti/wl12xx/scan.h
index 264af7ac2785..427f9af85a00 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.h
+++ b/drivers/net/wireless/ti/wl12xx/scan.h
@@ -135,6 +135,6 @@ int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
#endif
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c
index 7649c75cd68d..44f0b205b065 100644
--- a/drivers/net/wireless/ti/wl18xx/cmd.c
+++ b/drivers/net/wireless/ti/wl18xx/cmd.c
@@ -78,3 +78,92 @@ out_free:
out:
return ret;
}
+
+int wl18xx_cmd_smart_config_start(struct wl1271 *wl, u32 group_bitmap)
+{
+ struct wl18xx_cmd_smart_config_start *cmd;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd smart config start group_bitmap=0x%x",
+ group_bitmap);
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ cmd->group_id_bitmask = cpu_to_le32(group_bitmap);
+
+ ret = wl1271_cmd_send(wl, CMD_SMART_CONFIG_START, cmd, sizeof(*cmd), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send smart config start command");
+ goto out_free;
+ }
+
+out_free:
+ kfree(cmd);
+out:
+ return ret;
+}
+
+int wl18xx_cmd_smart_config_stop(struct wl1271 *wl)
+{
+ struct wl1271_cmd_header *cmd;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd smart config stop");
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = wl1271_cmd_send(wl, CMD_SMART_CONFIG_STOP, cmd, sizeof(*cmd), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send smart config stop command");
+ goto out_free;
+ }
+
+out_free:
+ kfree(cmd);
+out:
+ return ret;
+}
+
+int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
+ u8 key_len, u8 *key)
+{
+ struct wl18xx_cmd_smart_config_set_group_key *cmd;
+ int ret = 0;
+
+ wl1271_debug(DEBUG_CMD, "cmd smart config set group key id=0x%x",
+ group_id);
+
+ if (key_len != sizeof(cmd->key)) {
+ wl1271_error("invalid group key size: %d", key_len);
+ return -E2BIG;
+ }
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (!cmd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ cmd->group_id = cpu_to_le32(group_id);
+ memcpy(cmd->key, key, key_len);
+
+ ret = wl1271_cmd_send(wl, CMD_SMART_CONFIG_SET_GROUP_KEY, cmd,
+ sizeof(*cmd), 0);
+ if (ret < 0) {
+ wl1271_error("failed to send smart config set group key cmd");
+ goto out_free;
+ }
+
+out_free:
+ kfree(cmd);
+out:
+ return ret;
+}
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.h b/drivers/net/wireless/ti/wl18xx/cmd.h
index 6687d10899ac..92499e2dfa83 100644
--- a/drivers/net/wireless/ti/wl18xx/cmd.h
+++ b/drivers/net/wireless/ti/wl18xx/cmd.h
@@ -45,8 +45,25 @@ struct wl18xx_cmd_channel_switch {
u8 padding[2];
} __packed;
+struct wl18xx_cmd_smart_config_start {
+ struct wl1271_cmd_header header;
+
+ __le32 group_id_bitmask;
+} __packed;
+
+struct wl18xx_cmd_smart_config_set_group_key {
+ struct wl1271_cmd_header header;
+
+ __le32 group_id;
+
+ u8 key[16];
+} __packed;
+
int wl18xx_cmd_channel_switch(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct ieee80211_channel_switch *ch_switch);
-
+int wl18xx_cmd_smart_config_start(struct wl1271 *wl, u32 group_bitmap);
+int wl18xx_cmd_smart_config_stop(struct wl1271 *wl);
+int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
+ u8 key_len, u8 *key);
#endif
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
index c9199d7804c6..eb1848e08424 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -19,10 +19,12 @@
*
*/
+#include <net/genetlink.h>
#include "event.h"
#include "scan.h"
#include "../wlcore/cmd.h"
#include "../wlcore/debug.h"
+#include "../wlcore/vendor_cmd.h"
int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
bool *timeout)
@@ -45,6 +47,58 @@ int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
return wlcore_cmd_wait_for_event_or_timeout(wl, local_event, timeout);
}
+static int wlcore_smart_config_sync_event(struct wl1271 *wl, u8 sync_channel,
+ u8 sync_band)
+{
+ struct sk_buff *skb;
+ enum ieee80211_band band;
+ int freq;
+
+ if (sync_band == WLCORE_BAND_5GHZ)
+ band = IEEE80211_BAND_5GHZ;
+ else
+ band = IEEE80211_BAND_2GHZ;
+
+ freq = ieee80211_channel_to_frequency(sync_channel, band);
+
+ wl1271_debug(DEBUG_EVENT,
+ "SMART_CONFIG_SYNC_EVENT_ID, freq: %d (chan: %d band %d)",
+ freq, sync_channel, sync_band);
+ skb = cfg80211_vendor_event_alloc(wl->hw->wiphy, 20,
+ WLCORE_VENDOR_EVENT_SC_SYNC,
+ GFP_KERNEL);
+
+ if (nla_put_u32(skb, WLCORE_VENDOR_ATTR_FREQ, freq)) {
+ kfree_skb(skb);
+ return -EMSGSIZE;
+ }
+ cfg80211_vendor_event(skb, GFP_KERNEL);
+ return 0;
+}
+
+static int wlcore_smart_config_decode_event(struct wl1271 *wl,
+ u8 ssid_len, u8 *ssid,
+ u8 pwd_len, u8 *pwd)
+{
+ struct sk_buff *skb;
+
+ wl1271_debug(DEBUG_EVENT, "SMART_CONFIG_DECODE_EVENT_ID");
+ wl1271_dump_ascii(DEBUG_EVENT, "SSID:", ssid, ssid_len);
+
+ skb = cfg80211_vendor_event_alloc(wl->hw->wiphy,
+ ssid_len + pwd_len + 20,
+ WLCORE_VENDOR_EVENT_SC_DECODE,
+ GFP_KERNEL);
+
+ if (nla_put(skb, WLCORE_VENDOR_ATTR_SSID, ssid_len, ssid) ||
+ nla_put(skb, WLCORE_VENDOR_ATTR_PSK, pwd_len, pwd)) {
+ kfree_skb(skb);
+ return -EMSGSIZE;
+ }
+ cfg80211_vendor_event(skb, GFP_KERNEL);
+ return 0;
+}
+
int wl18xx_process_mailbox_events(struct wl1271 *wl)
{
struct wl18xx_event_mailbox *mbox = wl->mbox;
@@ -107,5 +161,16 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
if (vector & REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID)
wlcore_event_roc_complete(wl);
+ if (vector & SMART_CONFIG_SYNC_EVENT_ID)
+ wlcore_smart_config_sync_event(wl, mbox->sc_sync_channel,
+ mbox->sc_sync_band);
+
+ if (vector & SMART_CONFIG_DECODE_EVENT_ID)
+ wlcore_smart_config_decode_event(wl,
+ mbox->sc_ssid_len,
+ mbox->sc_ssid,
+ mbox->sc_pwd_len,
+ mbox->sc_pwd);
+
return 0;
}
diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h
index a76e98eb8372..0680312d4943 100644
--- a/drivers/net/wireless/ti/wl18xx/event.h
+++ b/drivers/net/wireless/ti/wl18xx/event.h
@@ -38,6 +38,8 @@ enum {
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18),
DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19),
PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20),
+ SMART_CONFIG_SYNC_EVENT_ID = BIT(22),
+ SMART_CONFIG_DECODE_EVENT_ID = BIT(23),
};
struct wl18xx_event_mailbox {
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index de5b4fa5d166..7af1936719eb 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -992,7 +992,10 @@ static int wl18xx_boot(struct wl1271 *wl)
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
INACTIVE_STA_EVENT_ID |
CHANNEL_SWITCH_COMPLETE_EVENT_ID |
- DFS_CHANNELS_CONFIG_COMPLETE_EVENT;
+ DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
+ SMART_CONFIG_SYNC_EVENT_ID |
+ SMART_CONFIG_DECODE_EVENT_ID;
+;
wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
@@ -1606,15 +1609,20 @@ static bool wl18xx_lnk_high_prio(struct wl1271 *wl, u8 hlid,
u8 thold;
struct wl18xx_fw_status_priv *status_priv =
(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
- u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
+ unsigned long suspend_bitmap;
+
+ /* if we don't have the link map yet, assume they all low prio */
+ if (!status_priv)
+ return false;
/* suspended links are never high priority */
- if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
+ suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
+ if (test_bit(hlid, &suspend_bitmap))
return false;
/* the priority thresholds are taken from FW */
- if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
- !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
+ if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
+ !test_bit(hlid, &wl->ap_fw_ps_map))
thold = status_priv->tx_fast_link_prio_threshold;
else
thold = status_priv->tx_slow_link_prio_threshold;
@@ -1628,12 +1636,17 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
u8 thold;
struct wl18xx_fw_status_priv *status_priv =
(struct wl18xx_fw_status_priv *)wl->fw_status->priv;
- u32 suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
+ unsigned long suspend_bitmap;
+
+ /* if we don't have the link map yet, assume they all low prio */
+ if (!status_priv)
+ return true;
- if (test_bit(hlid, (unsigned long *)&suspend_bitmap))
+ suspend_bitmap = le32_to_cpu(status_priv->link_suspend_bitmap);
+ if (test_bit(hlid, &suspend_bitmap))
thold = status_priv->tx_suspend_threshold;
- else if (test_bit(hlid, (unsigned long *)&wl->fw_fast_lnk_map) &&
- !test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map))
+ else if (test_bit(hlid, &wl->fw_fast_lnk_map) &&
+ !test_bit(hlid, &wl->ap_fw_ps_map))
thold = status_priv->tx_fast_stop_threshold;
else
thold = status_priv->tx_slow_stop_threshold;
@@ -1687,6 +1700,9 @@ static struct wlcore_ops wl18xx_ops = {
.convert_hwaddr = wl18xx_convert_hwaddr,
.lnk_high_prio = wl18xx_lnk_high_prio,
.lnk_low_prio = wl18xx_lnk_low_prio,
+ .smart_config_start = wl18xx_cmd_smart_config_start,
+ .smart_config_stop = wl18xx_cmd_smart_config_stop,
+ .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key,
};
/* HT cap appropriate for wide channels in 2Ghz */
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c
index 2b642f8c9266..98666f235a12 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.c
+++ b/drivers/net/wireless/ti/wl18xx/scan.c
@@ -113,6 +113,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
req->ssids ? req->ssids[0].ssid_len : 0,
req->ie,
req->ie_len,
+ NULL,
+ 0,
false);
if (ret < 0) {
wl1271_error("2.4GHz PROBE request template failed");
@@ -128,6 +130,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
req->ssids ? req->ssids[0].ssid_len : 0,
req->ie,
req->ie_len,
+ NULL,
+ 0,
false);
if (ret < 0) {
wl1271_error("5GHz PROBE request template failed");
@@ -161,7 +165,7 @@ static
int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
struct wl18xx_cmd_scan_params *cmd;
struct wlcore_scan_channels *cmd_channels = NULL;
@@ -237,8 +241,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
cmd->role_id, band,
req->ssids ? req->ssids[0].ssid : NULL,
req->ssids ? req->ssids[0].ssid_len : 0,
- ies->ie[band],
+ ies->ies[band],
ies->len[band],
+ ies->common_ies,
+ ies->common_ie_len,
true);
if (ret < 0) {
wl1271_error("2.4GHz PROBE request template failed");
@@ -252,8 +258,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
cmd->role_id, band,
req->ssids ? req->ssids[0].ssid : NULL,
req->ssids ? req->ssids[0].ssid_len : 0,
- ies->ie[band],
+ ies->ies[band],
ies->len[band],
+ ies->common_ies,
+ ies->common_ie_len,
true);
if (ret < 0) {
wl1271_error("5GHz PROBE request template failed");
@@ -277,7 +285,7 @@ out:
int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies);
}
diff --git a/drivers/net/wireless/ti/wl18xx/scan.h b/drivers/net/wireless/ti/wl18xx/scan.h
index eadee42689d1..2e636aa5dba9 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.h
+++ b/drivers/net/wireless/ti/wl18xx/scan.h
@@ -122,6 +122,6 @@ int wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
#endif
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c
index be1ebd55ac88..3406ffb53325 100644
--- a/drivers/net/wireless/ti/wl18xx/tx.c
+++ b/drivers/net/wireless/ti/wl18xx/tx.c
@@ -30,7 +30,7 @@
static
void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
- struct ieee80211_tx_rate *rate)
+ u8 band, struct ieee80211_tx_rate *rate)
{
u8 fw_rate = wl->fw_status->counters.tx_last_rate;
@@ -43,6 +43,8 @@ void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
if (fw_rate <= CONF_HW_RATE_INDEX_54MBPS) {
rate->idx = fw_rate;
+ if (band == IEEE80211_BAND_5GHZ)
+ rate->idx -= CONF_HW_RATE_INDEX_6MBPS;
rate->flags = 0;
} else {
rate->flags = IEEE80211_TX_RC_MCS;
@@ -102,7 +104,8 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
* first pass info->control.vif while it's valid, and then fill out
* the info->status structures
*/
- wl18xx_get_last_tx_rate(wl, info->control.vif, &info->status.rates[0]);
+ wl18xx_get_last_tx_rate(wl, info->control.vif,
+ info->band, &info->status.rates[0]);
info->status.rates[0].count = 1; /* no data about retries */
info->status.ack_signal = -1;
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index eb7cfe817010..6a2b88030c1d 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -38,7 +38,7 @@
#define WL18XX_NUM_TX_DESCRIPTORS 32
#define WL18XX_NUM_RX_DESCRIPTORS 32
-#define WL18XX_NUM_MAC_ADDRESSES 3
+#define WL18XX_NUM_MAC_ADDRESSES 2
#define WL18XX_RX_BA_MAX_SESSIONS 13
diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile
index 4f23931d7bd5..0a69c1373643 100644
--- a/drivers/net/wireless/ti/wlcore/Makefile
+++ b/drivers/net/wireless/ti/wlcore/Makefile
@@ -1,5 +1,5 @@
wlcore-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
- boot.o init.o debugfs.o scan.o sysfs.o
+ boot.o init.o debugfs.o scan.o sysfs.o vendor_cmd.o
wlcore_spi-objs = spi.o
wlcore_sdio-objs = sdio.o
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 40dc30f4faaa..05604ee31224 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -372,9 +372,9 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
wl1271_tx_reset_link_queues(wl, *hlid);
wl->links[*hlid].wlvif = NULL;
- if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
- (wlvif->bss_type == BSS_TYPE_AP_BSS &&
- *hlid == wlvif->ap.bcast_hlid)) {
+ if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
+ *hlid == wlvif->ap.bcast_hlid) {
+ u32 sqn_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING;
/*
* save the total freed packets in the wlvif, in case this is
* recovery or suspend
@@ -385,9 +385,11 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
* increment the initial seq number on recovery to account for
* transmitted packets that we haven't yet got in the FW status
*/
+ if (wlvif->encryption_type == KEY_GEM)
+ sqn_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING_GEM;
+
if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
- wlvif->total_freed_pkts +=
- WL1271_TX_SQN_POST_RECOVERY_PADDING;
+ wlvif->total_freed_pkts += sqn_padding;
}
wl->links[*hlid].total_freed_pkts = 0;
@@ -1124,7 +1126,8 @@ out:
int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 role_id, u8 band,
const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len, bool sched_scan)
+ const u8 *ie0, size_t ie0_len, const u8 *ie1,
+ size_t ie1_len, bool sched_scan)
{
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
struct sk_buff *skb;
@@ -1136,13 +1139,15 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);
skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
- ie_len);
+ ie0_len + ie1_len);
if (!skb) {
ret = -ENOMEM;
goto out;
}
- if (ie_len)
- memcpy(skb_put(skb, ie_len), ie, ie_len);
+ if (ie0_len)
+ memcpy(skb_put(skb, ie0_len), ie0, ie0_len);
+ if (ie1_len)
+ memcpy(skb_put(skb, ie1_len), ie1, ie1_len);
if (sched_scan &&
(wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index b084830a61cf..ca6a28b03f8f 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -64,7 +64,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u8 role_id, u8 band,
const u8 *ssid, size_t ssid_len,
- const u8 *ie, size_t ie_len, bool sched_scan);
+ const u8 *ie, size_t ie_len, const u8 *common_ie,
+ size_t common_ie_len, bool sched_scan);
struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct sk_buff *skb);
@@ -169,6 +170,9 @@ enum wl1271_commands {
/* start of 18xx specific commands */
CMD_DFS_CHANNEL_CONFIG = 60,
+ CMD_SMART_CONFIG_START = 61,
+ CMD_SMART_CONFIG_STOP = 62,
+ CMD_SMART_CONFIG_SET_GROUP_KEY = 63,
MAX_COMMAND_ID = 0xFFFF,
};
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index 89893c717025..0be21f62fcb0 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -496,7 +496,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
DRIVER_STATE_PRINT_INT(sg_enabled);
DRIVER_STATE_PRINT_INT(enable_11a);
DRIVER_STATE_PRINT_INT(noise);
- DRIVER_STATE_PRINT_HEX(ap_fw_ps_map);
+ DRIVER_STATE_PRINT_LHEX(ap_fw_ps_map);
DRIVER_STATE_PRINT_LHEX(ap_ps_map);
DRIVER_STATE_PRINT_HEX(quirks);
DRIVER_STATE_PRINT_HEX(irq);
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 1555ff970050..aa9f82c72296 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -260,4 +260,31 @@ wlcore_hw_lnk_low_prio(struct wl1271 *wl, u8 hlid,
return wl->ops->lnk_low_prio(wl, hlid, lnk);
}
+static inline int
+wlcore_smart_config_start(struct wl1271 *wl, u32 group_bitmap)
+{
+ if (!wl->ops->smart_config_start)
+ return -EINVAL;
+
+ return wl->ops->smart_config_start(wl, group_bitmap);
+}
+
+static inline int
+wlcore_smart_config_stop(struct wl1271 *wl)
+{
+ if (!wl->ops->smart_config_stop)
+ return -EINVAL;
+
+ return wl->ops->smart_config_stop(wl);
+}
+
+static inline int
+wlcore_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
+ u8 key_len, u8 *key)
+{
+ if (!wl->ops->smart_config_set_group_key)
+ return -EINVAL;
+
+ return wl->ops->smart_config_set_group_key(wl, group_id, key_len, key);
+}
#endif
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 3d6028e62750..575c8f6d4009 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -37,6 +37,7 @@
#include "init.h"
#include "debugfs.h"
#include "testmode.h"
+#include "vendor_cmd.h"
#include "scan.h"
#include "hw_ops.h"
#include "sysfs.h"
@@ -332,7 +333,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
{
bool fw_ps;
- fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
+ fw_ps = test_bit(hlid, &wl->ap_fw_ps_map);
/*
* Wake up from high level PS if the STA is asleep with too little
@@ -359,13 +360,13 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct wl_fw_status *status)
{
- u32 cur_fw_ps_map;
+ unsigned long cur_fw_ps_map;
u8 hlid;
cur_fw_ps_map = status->link_ps_bitmap;
if (wl->ap_fw_ps_map != cur_fw_ps_map) {
wl1271_debug(DEBUG_PSM,
- "link ps prev 0x%x cur 0x%x changed 0x%x",
+ "link ps prev 0x%lx cur 0x%lx changed 0x%lx",
wl->ap_fw_ps_map, cur_fw_ps_map,
wl->ap_fw_ps_map ^ cur_fw_ps_map);
@@ -898,6 +899,44 @@ out:
wlcore_set_partition(wl, &old_part);
}
+static void wlcore_save_freed_pkts(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 hlid, struct ieee80211_sta *sta)
+{
+ struct wl1271_station *wl_sta;
+ u32 sqn_recovery_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING;
+
+ wl_sta = (void *)sta->drv_priv;
+ wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
+
+ /*
+ * increment the initial seq number on recovery to account for
+ * transmitted packets that we haven't yet got in the FW status
+ */
+ if (wlvif->encryption_type == KEY_GEM)
+ sqn_recovery_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING_GEM;
+
+ if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
+ wl_sta->total_freed_pkts += sqn_recovery_padding;
+}
+
+static void wlcore_save_freed_pkts_addr(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif,
+ u8 hlid, const u8 *addr)
+{
+ struct ieee80211_sta *sta;
+ struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
+
+ if (WARN_ON(hlid == WL12XX_INVALID_LINK_ID ||
+ is_zero_ether_addr(addr)))
+ return;
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta(vif, addr);
+ if (sta)
+ wlcore_save_freed_pkts(wl, wlvif, hlid, sta);
+ rcu_read_unlock();
+}
+
static void wlcore_print_recovery(struct wl1271 *wl)
{
u32 pc = 0;
@@ -961,6 +1000,13 @@ static void wl1271_recovery_work(struct work_struct *work)
wlvif = list_first_entry(&wl->wlvif_list,
struct wl12xx_vif, list);
vif = wl12xx_wlvif_to_vif(wlvif);
+
+ if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
+ test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
+ wlcore_save_freed_pkts_addr(wl, wlvif, wlvif->sta.hlid,
+ vif->bss_conf.bssid);
+ }
+
__wl1271_op_remove_interface(wl, vif, false);
}
@@ -3540,8 +3586,9 @@ out:
static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req)
+ struct ieee80211_scan_request *hw_req)
{
+ struct cfg80211_scan_request *req = &hw_req->req;
struct wl1271 *wl = hw->priv;
int ret;
u8 *ssid = NULL;
@@ -3636,7 +3683,7 @@ out:
static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies)
+ struct ieee80211_scan_ies *ies)
{
struct wl1271 *wl = hw->priv;
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
@@ -4702,36 +4749,18 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
{
- struct wl1271_station *wl_sta;
- struct ieee80211_sta *sta;
- struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
-
if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
return;
clear_bit(hlid, wlvif->ap.sta_hlid_map);
__clear_bit(hlid, &wl->ap_ps_map);
- __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
+ __clear_bit(hlid, &wl->ap_fw_ps_map);
/*
* save the last used PN in the private part of iee80211_sta,
* in case of recovery/suspend
*/
- rcu_read_lock();
- sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
- if (sta) {
- wl_sta = (void *)sta->drv_priv;
- wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;
-
- /*
- * increment the initial seq number on recovery to account for
- * transmitted packets that we haven't yet got in the FW status
- */
- if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
- wl_sta->total_freed_pkts +=
- WL1271_TX_SQN_POST_RECOVERY_PADDING;
- }
- rcu_read_unlock();
+ wlcore_save_freed_pkts_addr(wl, wlvif, hlid, wl->links[hlid].addr);
wl12xx_free_link(wl, wlvif, &hlid);
wl->active_sta_count--;
@@ -4914,6 +4943,21 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
}
+ /* save seq number on disassoc (suspend) */
+ if (is_sta &&
+ old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTH) {
+ wlcore_save_freed_pkts(wl, wlvif, wlvif->sta.hlid, sta);
+ wlvif->total_freed_pkts = 0;
+ }
+
+ /* restore seq number on assoc (resume) */
+ if (is_sta &&
+ old_state == IEEE80211_STA_AUTH &&
+ new_state == IEEE80211_STA_ASSOC) {
+ wlvif->total_freed_pkts = wl_sta->total_freed_pkts;
+ }
+
/* clear ROCs on failure or authorization */
if (is_sta &&
(new_state == IEEE80211_STA_AUTHORIZED ||
@@ -5148,6 +5192,10 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
if (unlikely(wl->state == WLCORE_STATE_OFF)) {
wl12xx_for_each_wlvif_sta(wl, wlvif) {
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
+
+ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+ continue;
+
ieee80211_chswitch_done(vif, false);
}
goto out;
@@ -5163,6 +5211,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
wl12xx_for_each_wlvif_sta(wl, wlvif) {
unsigned long delay_usec;
+ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+ continue;
+
ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
if (ret)
goto out_sleep;
@@ -5618,7 +5669,7 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
memcpy(&wl->addresses[idx], &wl->addresses[0],
sizeof(wl->addresses[0]));
/* LAA bit */
- wl->addresses[idx].addr[2] |= BIT(1);
+ wl->addresses[idx].addr[0] |= BIT(1);
}
wl->hw->wiphy->n_addresses = WLCORE_NUM_MAC_ADDRESSES;
@@ -5763,7 +5814,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
sizeof(struct ieee80211_header);
- wl->hw->wiphy->max_remain_on_channel_duration = 5000;
+ wl->hw->wiphy->max_remain_on_channel_duration = 30000;
wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
@@ -5832,6 +5883,9 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
wl->hw->wiphy->iface_combinations = wl->iface_combinations;
wl->hw->wiphy->n_iface_combinations = wl->n_iface_combinations;
+ /* register vendor commands */
+ wlcore_set_vendor_commands(wl->hw->wiphy);
+
SET_IEEE80211_DEV(wl->hw, wl->dev);
wl->hw->sta_data_size = sizeof(struct wl1271_station);
diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index a6ab24b5c0f9..4dadd0c62cde 100644
--- a/drivers/net/wireless/ti/wlcore/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -37,7 +37,7 @@ void wl1271_scan_complete_work(struct work_struct *work);
int wl1271_scan_sched_scan_config(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif);
void wlcore_scan_sched_scan_results(struct wl1271 *wl);
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 40b43115f835..f0ac36139bcc 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -126,7 +126,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl,
if (WARN_ON(!test_bit(hlid, wlvif->links_map)))
return;
- fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
+ fw_ps = test_bit(hlid, &wl->ap_fw_ps_map);
tx_pkts = wl->links[hlid].allocated_pkts;
/*
diff --git a/drivers/net/wireless/ti/wlcore/vendor_cmd.c b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
new file mode 100644
index 000000000000..ad86a48dcfcb
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
@@ -0,0 +1,197 @@
+/*
+ * This file is part of wlcore
+ *
+ * Copyright (C) 2014 Texas Instruments. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <net/mac80211.h>
+#include <net/netlink.h>
+
+#include "wlcore.h"
+#include "debug.h"
+#include "ps.h"
+#include "hw_ops.h"
+#include "vendor_cmd.h"
+
+static const
+struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = {
+ [WLCORE_VENDOR_ATTR_FREQ] = { .type = NLA_U32 },
+ [WLCORE_VENDOR_ATTR_GROUP_ID] = { .type = NLA_U32 },
+ [WLCORE_VENDOR_ATTR_GROUP_KEY] = { .type = NLA_U32,
+ .len = WLAN_MAX_KEY_LEN },
+};
+
+static int
+wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct wl1271 *wl = hw->priv;
+ struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
+ int ret;
+
+ wl1271_debug(DEBUG_CMD, "vendor cmd smart config start");
+
+ if (!data)
+ return -EINVAL;
+
+ ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
+ wlcore_vendor_attr_policy);
+ if (ret)
+ return ret;
+
+ if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID])
+ return -EINVAL;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state != WLCORE_STATE_ON)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wlcore_smart_config_start(wl,
+ nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]));
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+
+ return 0;
+}
+
+static int
+wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct wl1271 *wl = hw->priv;
+ int ret;
+
+ wl1271_debug(DEBUG_CMD, "testmode cmd smart config stop");
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state != WLCORE_STATE_ON)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wlcore_smart_config_stop(wl);
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static int
+wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct wl1271 *wl = hw->priv;
+ struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
+ int ret;
+
+ wl1271_debug(DEBUG_CMD, "testmode cmd smart config set group key");
+
+ if (!data)
+ return -EINVAL;
+
+ ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
+ wlcore_vendor_attr_policy);
+ if (ret)
+ return ret;
+
+ if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID] ||
+ !tb[WLCORE_VENDOR_ATTR_GROUP_KEY])
+ return -EINVAL;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state != WLCORE_STATE_ON)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ ret = wlcore_smart_config_set_group_key(wl,
+ nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]),
+ nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]),
+ nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]));
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+
+ return ret;
+}
+
+static const struct wiphy_vendor_command wlcore_vendor_commands[] = {
+ {
+ .info = {
+ .vendor_id = TI_OUI,
+ .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_START,
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlcore_vendor_cmd_smart_config_start,
+ },
+ {
+ .info = {
+ .vendor_id = TI_OUI,
+ .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_STOP,
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlcore_vendor_cmd_smart_config_stop,
+ },
+ {
+ .info = {
+ .vendor_id = TI_OUI,
+ .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY,
+ },
+ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlcore_vendor_cmd_smart_config_set_group_key,
+ },
+};
+
+static const struct nl80211_vendor_cmd_info wlcore_vendor_events[] = {
+ {
+ .vendor_id = TI_OUI,
+ .subcmd = WLCORE_VENDOR_EVENT_SC_SYNC,
+ },
+ {
+ .vendor_id = TI_OUI,
+ .subcmd = WLCORE_VENDOR_EVENT_SC_DECODE,
+ },
+};
+
+void wlcore_set_vendor_commands(struct wiphy *wiphy)
+{
+ wiphy->vendor_commands = wlcore_vendor_commands;
+ wiphy->n_vendor_commands = ARRAY_SIZE(wlcore_vendor_commands);
+ wiphy->vendor_events = wlcore_vendor_events;
+ wiphy->n_vendor_events = ARRAY_SIZE(wlcore_vendor_events);
+}
diff --git a/drivers/net/wireless/ti/wlcore/vendor_cmd.h b/drivers/net/wireless/ti/wlcore/vendor_cmd.h
new file mode 100644
index 000000000000..6e0c15e30f03
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/vendor_cmd.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of wlcore
+ *
+ * Copyright (C) 2014 Texas Instruments. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef __WLCORE_VENDOR_H__
+#define __WLCORE_VENDOR_H__
+
+#ifdef __KERNEL__
+void wlcore_set_vendor_commands(struct wiphy *wiphy);
+#endif
+
+#define TI_OUI 0x080028
+
+enum wlcore_vendor_commands {
+ WLCORE_VENDOR_CMD_SMART_CONFIG_START,
+ WLCORE_VENDOR_CMD_SMART_CONFIG_STOP,
+ WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY,
+
+ NUM_WLCORE_VENDOR_CMD,
+ MAX_WLCORE_VENDOR_CMD = NUM_WLCORE_VENDOR_CMD - 1
+};
+
+enum wlcore_vendor_attributes {
+ WLCORE_VENDOR_ATTR_FREQ,
+ WLCORE_VENDOR_ATTR_PSK,
+ WLCORE_VENDOR_ATTR_SSID,
+ WLCORE_VENDOR_ATTR_GROUP_ID,
+ WLCORE_VENDOR_ATTR_GROUP_KEY,
+
+ NUM_WLCORE_VENDOR_ATTR,
+ MAX_WLCORE_VENDOR_ATTR = NUM_WLCORE_VENDOR_ATTR - 1
+};
+
+enum wlcore_vendor_events {
+ WLCORE_VENDOR_EVENT_SC_SYNC,
+ WLCORE_VENDOR_EVENT_SC_DECODE,
+};
+
+#endif /* __WLCORE_VENDOR_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 95a54504f0cc..df78cf12ef15 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -95,7 +95,7 @@ struct wlcore_ops {
int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem);
int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd,
@@ -117,6 +117,10 @@ struct wlcore_ops {
struct wl1271_link *lnk);
bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid,
struct wl1271_link *lnk);
+ int (*smart_config_start)(struct wl1271 *wl, u32 group_bitmap);
+ int (*smart_config_stop)(struct wl1271 *wl);
+ int (*smart_config_set_group_key)(struct wl1271 *wl, u16 group_id,
+ u8 key_len, u8 *key);
};
enum wlcore_partitions {
@@ -384,10 +388,10 @@ struct wl1271 {
int active_link_count;
/* Fast/slow links bitmap according to FW */
- u32 fw_fast_lnk_map;
+ unsigned long fw_fast_lnk_map;
/* AP-mode - a bitmap of links currently in PS mode according to FW */
- u32 ap_fw_ps_map;
+ unsigned long ap_fw_ps_map;
/* AP-mode - a bitmap of links currently in PS mode in mac80211 */
unsigned long ap_ps_map;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index c2c34a84ff3d..0e52556044d9 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -45,6 +45,9 @@
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
#define WL1271_TX_SQN_POST_RECOVERY_PADDING 0xff
+/* Use smaller padding for GEM, as some APs have issues when it's too big */
+#define WL1271_TX_SQN_POST_RECOVERY_PADDING_GEM 0x20
+
#define WL1271_CIPHER_SUITE_GEM 0x00147201
@@ -324,6 +327,7 @@ struct wl1271_station {
* total freed FW packets on the link to the STA - used for tracking the
* AES/TKIP PN across recoveries. Re-initialized each time from the
* wl1271_station structure.
+ * Used in both AP and STA mode.
*/
u64 total_freed_pkts;
};
@@ -460,21 +464,19 @@ struct wl12xx_vif {
struct delayed_work pending_auth_complete_work;
/*
+ * total freed FW packets on the link.
+ * For STA this holds the PN of the link to the AP.
+ * For AP this holds the PN of the broadcast link.
+ */
+ u64 total_freed_pkts;
+
+ /*
* This struct must be last!
* data that has to be saved acrossed reconfigs (e.g. recovery)
* should be declared in this struct.
*/
struct {
u8 persistent[0];
-
- /*
- * total freed FW packets on the link - used for
- * storing the AES/TKIP PN during recovery, as this
- * structure is not zeroed out.
- * For STA this holds the PN of the link to the AP.
- * For AP this holds the PN of the broadcast link.
- */
- u64 total_freed_pkts;
};
};
diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig
index 96c8e1de0879..95920581860a 100644
--- a/drivers/net/wireless/zd1211rw/Kconfig
+++ b/drivers/net/wireless/zd1211rw/Kconfig
@@ -3,11 +3,11 @@ config ZD1211RW
depends on USB && MAC80211
select FW_LOADER
---help---
- This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless
+ This is a driver for the ZyDAS ZD1211/ZD1211B wireless
chip, present in many USB-wireless adapters.
Device firmware is required alongside this driver. You can download
- the firmware distribution from http://zd1211.ath.cx/get-firmware
+ the firmware distribution from http://sf.net/projects/zd1211/files/
config ZD1211RW_DEBUG
bool "ZyDAS ZD1211 debugging"
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 2532ce85d718..ef3026f46a37 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -44,6 +44,7 @@
#include <xen/interface/grant_table.h>
#include <xen/grant_table.h>
#include <xen/xenbus.h>
+#include <linux/debugfs.h>
typedef unsigned int pending_ring_idx_t;
#define INVALID_PENDING_RING_IDX (~0U)
@@ -175,9 +176,9 @@ struct xenvif_queue { /* Per-queue data for xenvif */
struct xen_netif_rx_back_ring rx;
struct sk_buff_head rx_queue;
RING_IDX rx_last_skb_slots;
- bool rx_queue_purge;
+ unsigned long status;
- struct timer_list wake_queue;
+ struct timer_list rx_stalled;
struct gnttab_copy grant_copy_op[MAX_GRANT_COPY_OPS];
@@ -197,6 +198,20 @@ struct xenvif_queue { /* Per-queue data for xenvif */
struct xenvif_stats stats;
};
+enum state_bit_shift {
+ /* This bit marks that the vif is connected */
+ VIF_STATUS_CONNECTED,
+ /* This bit signals the RX thread that queuing was stopped (in
+ * start_xmit), and either the timer fired or an RX interrupt came
+ */
+ QUEUE_STATUS_RX_PURGE_EVENT,
+ /* This bit tells the interrupt handler that this queue was the reason
+ * for the carrier off, so it should kick the thread. Only queues which
+ * brought it down can turn on the carrier.
+ */
+ QUEUE_STATUS_RX_STALLED
+};
+
struct xenvif {
/* Unique identifier for this interface. */
domid_t domid;
@@ -219,11 +234,16 @@ struct xenvif {
* frontend is rogue.
*/
bool disabled;
+ unsigned long status;
/* Queues */
struct xenvif_queue *queues;
unsigned int num_queues; /* active queues, resource allocated */
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *xenvif_dbg_root;
+#endif
+
/* Miscellaneous private stuff. */
struct net_device *dev;
};
@@ -297,10 +317,16 @@ static inline pending_ring_idx_t nr_pending_reqs(struct xenvif_queue *queue)
/* Callback from stack when TX packet can be released */
void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success);
+irqreturn_t xenvif_interrupt(int irq, void *dev_id);
+
extern bool separate_tx_rx_irq;
extern unsigned int rx_drain_timeout_msecs;
extern unsigned int rx_drain_timeout_jiffies;
extern unsigned int xenvif_max_queues;
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *xen_netback_dbg_root;
+#endif
+
#endif /* __XEN_NETBACK__COMMON_H__ */
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 9e97c7ca0ddd..48a55cda979b 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -55,7 +55,8 @@ static inline void xenvif_stop_queue(struct xenvif_queue *queue)
int xenvif_schedulable(struct xenvif *vif)
{
- return netif_running(vif->dev) && netif_carrier_ok(vif->dev);
+ return netif_running(vif->dev) &&
+ test_bit(VIF_STATUS_CONNECTED, &vif->status);
}
static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
@@ -77,8 +78,12 @@ int xenvif_poll(struct napi_struct *napi, int budget)
/* This vif is rogue, we pretend we've there is nothing to do
* for this vif to deschedule it from NAPI. But this interface
* will be turned off in thread context later.
+ * Also, if a guest doesn't post enough slots to receive data on one of
+ * its queues, the carrier goes down and NAPI is descheduled here so
+ * the guest can't send more packets until it's ready to receive.
*/
- if (unlikely(queue->vif->disabled)) {
+ if (unlikely(queue->vif->disabled ||
+ !netif_carrier_ok(queue->vif->dev))) {
napi_complete(napi);
return 0;
}
@@ -96,13 +101,22 @@ int xenvif_poll(struct napi_struct *napi, int budget)
static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
{
struct xenvif_queue *queue = dev_id;
+ struct netdev_queue *net_queue =
+ netdev_get_tx_queue(queue->vif->dev, queue->id);
+ /* QUEUE_STATUS_RX_PURGE_EVENT is only set if either QDisc was off OR
+ * the carrier went down and this queue was previously blocked
+ */
+ if (unlikely(netif_tx_queue_stopped(net_queue) ||
+ (!netif_carrier_ok(queue->vif->dev) &&
+ test_bit(QUEUE_STATUS_RX_STALLED, &queue->status))))
+ set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status);
xenvif_kick_thread(queue);
return IRQ_HANDLED;
}
-static irqreturn_t xenvif_interrupt(int irq, void *dev_id)
+irqreturn_t xenvif_interrupt(int irq, void *dev_id)
{
xenvif_tx_interrupt(irq, dev_id);
xenvif_rx_interrupt(irq, dev_id);
@@ -124,16 +138,14 @@ void xenvif_wake_queue(struct xenvif_queue *queue)
netif_tx_wake_queue(netdev_get_tx_queue(dev, id));
}
-/* Callback to wake the queue and drain it on timeout */
-static void xenvif_wake_queue_callback(unsigned long data)
+/* Callback to wake the queue's thread and turn the carrier off on timeout */
+static void xenvif_rx_stalled(unsigned long data)
{
struct xenvif_queue *queue = (struct xenvif_queue *)data;
if (xenvif_queue_stopped(queue)) {
- netdev_err(queue->vif->dev, "draining TX queue\n");
- queue->rx_queue_purge = true;
+ set_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status);
xenvif_kick_thread(queue);
- xenvif_wake_queue(queue);
}
}
@@ -182,11 +194,11 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
* drain.
*/
if (!xenvif_rx_ring_slots_available(queue, min_slots_needed)) {
- queue->wake_queue.function = xenvif_wake_queue_callback;
- queue->wake_queue.data = (unsigned long)queue;
+ queue->rx_stalled.function = xenvif_rx_stalled;
+ queue->rx_stalled.data = (unsigned long)queue;
xenvif_stop_queue(queue);
- mod_timer(&queue->wake_queue,
- jiffies + rx_drain_timeout_jiffies);
+ mod_timer(&queue->rx_stalled,
+ jiffies + rx_drain_timeout_jiffies);
}
skb_queue_tail(&queue->rx_queue, skb);
@@ -267,7 +279,7 @@ static void xenvif_down(struct xenvif *vif)
static int xenvif_open(struct net_device *dev)
{
struct xenvif *vif = netdev_priv(dev);
- if (netif_carrier_ok(dev))
+ if (test_bit(VIF_STATUS_CONNECTED, &vif->status))
xenvif_up(vif);
netif_tx_start_all_queues(dev);
return 0;
@@ -276,7 +288,7 @@ static int xenvif_open(struct net_device *dev)
static int xenvif_close(struct net_device *dev)
{
struct xenvif *vif = netdev_priv(dev);
- if (netif_carrier_ok(dev))
+ if (test_bit(VIF_STATUS_CONNECTED, &vif->status))
xenvif_down(vif);
netif_tx_stop_all_queues(dev);
return 0;
@@ -418,8 +430,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
* When the guest selects the desired number, it will be updated
* via netif_set_real_num_*_queues().
*/
- dev = alloc_netdev_mq(sizeof(struct xenvif), name, ether_setup,
- xenvif_max_queues);
+ dev = alloc_netdev_mq(sizeof(struct xenvif), name, NET_NAME_UNKNOWN,
+ ether_setup, xenvif_max_queues);
if (dev == NULL) {
pr_warn("Could not allocate netdev for %s\n", name);
return ERR_PTR(-ENOMEM);
@@ -514,7 +526,7 @@ int xenvif_init_queue(struct xenvif_queue *queue)
queue->grant_tx_handle[i] = NETBACK_INVALID_HANDLE;
}
- init_timer(&queue->wake_queue);
+ init_timer(&queue->rx_stalled);
netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll,
XENVIF_NAPI_WEIGHT);
@@ -528,6 +540,7 @@ void xenvif_carrier_on(struct xenvif *vif)
if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN)
dev_set_mtu(vif->dev, ETH_DATA_LEN);
netdev_update_features(vif->dev);
+ set_bit(VIF_STATUS_CONNECTED, &vif->status);
netif_carrier_on(vif->dev);
if (netif_running(vif->dev))
xenvif_up(vif);
@@ -625,9 +638,11 @@ void xenvif_carrier_off(struct xenvif *vif)
struct net_device *dev = vif->dev;
rtnl_lock();
- netif_carrier_off(dev); /* discard queued packets */
- if (netif_running(dev))
- xenvif_down(vif);
+ if (test_and_clear_bit(VIF_STATUS_CONNECTED, &vif->status)) {
+ netif_carrier_off(dev); /* discard queued packets */
+ if (netif_running(dev))
+ xenvif_down(vif);
+ }
rtnl_unlock();
}
@@ -656,14 +671,13 @@ void xenvif_disconnect(struct xenvif *vif)
unsigned int num_queues = vif->num_queues;
unsigned int queue_index;
- if (netif_carrier_ok(vif->dev))
- xenvif_carrier_off(vif);
+ xenvif_carrier_off(vif);
for (queue_index = 0; queue_index < num_queues; ++queue_index) {
queue = &vif->queues[queue_index];
if (queue->task) {
- del_timer_sync(&queue->wake_queue);
+ del_timer_sync(&queue->rx_stalled);
kthread_stop(queue->task);
queue->task = NULL;
}
@@ -705,16 +719,12 @@ void xenvif_free(struct xenvif *vif)
/* Here we want to avoid timeout messages if an skb can be legitimately
* stuck somewhere else. Realistically this could be an another vif's
* internal or QDisc queue. That another vif also has this
- * rx_drain_timeout_msecs timeout, but the timer only ditches the
- * internal queue. After that, the QDisc queue can put in worst case
- * XEN_NETIF_RX_RING_SIZE / MAX_SKB_FRAGS skbs into that another vif's
- * internal queue, so we need several rounds of such timeouts until we
- * can be sure that no another vif should have skb's from us. We are
- * not sending more skb's, so newly stuck packets are not interesting
- * for us here.
+ * rx_drain_timeout_msecs timeout, so give it time to drain out.
+ * Although if that other guest wakes up just before its timeout happens
+ * and takes only one skb from QDisc, it can hold onto other skbs for a
+ * longer period.
*/
- unsigned int worst_case_skb_lifetime = (rx_drain_timeout_msecs/1000) *
- DIV_ROUND_UP(XENVIF_QUEUE_LENGTH, (XEN_NETIF_RX_RING_SIZE / MAX_SKB_FRAGS));
+ unsigned int worst_case_skb_lifetime = (rx_drain_timeout_msecs/1000);
unregister_netdev(vif->dev);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 1844a47636b6..aa2093325be1 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1030,14 +1030,21 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
{
struct gnttab_map_grant_ref *gop_map = *gopp_map;
u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
+ /* This always points to the shinfo of the skb being checked, which
+ * could be either the first or the one on the frag_list
+ */
struct skb_shared_info *shinfo = skb_shinfo(skb);
+ /* If this is non-NULL, we are currently checking the frag_list skb, and
+ * this points to the shinfo of the first one
+ */
+ struct skb_shared_info *first_shinfo = NULL;
int nr_frags = shinfo->nr_frags;
+ const bool sharedslot = nr_frags &&
+ frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
int i, err;
- struct sk_buff *first_skb = NULL;
/* Check status of header. */
err = (*gopp_copy)->status;
- (*gopp_copy)++;
if (unlikely(err)) {
if (net_ratelimit())
netdev_dbg(queue->vif->dev,
@@ -1045,8 +1052,12 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
(*gopp_copy)->status,
pending_idx,
(*gopp_copy)->source.u.ref);
- xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
+ /* The first frag might still have this slot mapped */
+ if (!sharedslot)
+ xenvif_idx_release(queue, pending_idx,
+ XEN_NETIF_RSP_ERROR);
}
+ (*gopp_copy)++;
check_frags:
for (i = 0; i < nr_frags; i++, gop_map++) {
@@ -1062,8 +1073,19 @@ check_frags:
pending_idx,
gop_map->handle);
/* Had a previous error? Invalidate this fragment. */
- if (unlikely(err))
+ if (unlikely(err)) {
xenvif_idx_unmap(queue, pending_idx);
+ /* If the mapping of the first frag was OK, but
+ * the header's copy failed, and they are
+ * sharing a slot, send an error
+ */
+ if (i == 0 && sharedslot)
+ xenvif_idx_release(queue, pending_idx,
+ XEN_NETIF_RSP_ERROR);
+ else
+ xenvif_idx_release(queue, pending_idx,
+ XEN_NETIF_RSP_OKAY);
+ }
continue;
}
@@ -1075,42 +1097,53 @@ check_frags:
gop_map->status,
pending_idx,
gop_map->ref);
+
xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR);
/* Not the first error? Preceding frags already invalidated. */
if (err)
continue;
- /* First error: invalidate preceding fragments. */
+
+ /* First error: if the header haven't shared a slot with the
+ * first frag, release it as well.
+ */
+ if (!sharedslot)
+ xenvif_idx_release(queue,
+ XENVIF_TX_CB(skb)->pending_idx,
+ XEN_NETIF_RSP_OKAY);
+
+ /* Invalidate preceding fragments of this skb. */
for (j = 0; j < i; j++) {
pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
xenvif_idx_unmap(queue, pending_idx);
+ xenvif_idx_release(queue, pending_idx,
+ XEN_NETIF_RSP_OKAY);
+ }
+
+ /* And if we found the error while checking the frag_list, unmap
+ * the first skb's frags
+ */
+ if (first_shinfo) {
+ for (j = 0; j < first_shinfo->nr_frags; j++) {
+ pending_idx = frag_get_pending_idx(&first_shinfo->frags[j]);
+ xenvif_idx_unmap(queue, pending_idx);
+ xenvif_idx_release(queue, pending_idx,
+ XEN_NETIF_RSP_OKAY);
+ }
}
/* Remember the error: invalidate all subsequent fragments. */
err = newerr;
}
- if (skb_has_frag_list(skb)) {
- first_skb = skb;
- skb = shinfo->frag_list;
- shinfo = skb_shinfo(skb);
+ if (skb_has_frag_list(skb) && !first_shinfo) {
+ first_shinfo = skb_shinfo(skb);
+ shinfo = skb_shinfo(skb_shinfo(skb)->frag_list);
nr_frags = shinfo->nr_frags;
goto check_frags;
}
- /* There was a mapping error in the frag_list skb. We have to unmap
- * the first skb's frags
- */
- if (first_skb && err) {
- int j;
- shinfo = skb_shinfo(first_skb);
- for (j = 0; j < shinfo->nr_frags; j++) {
- pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
- xenvif_idx_unmap(queue, pending_idx);
- }
- }
-
*gopp_map = gop_map;
return err;
}
@@ -1518,7 +1551,16 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
/* Check the remap error code. */
if (unlikely(xenvif_tx_check_gop(queue, skb, &gop_map, &gop_copy))) {
+ /* If there was an error, xenvif_tx_check_gop is
+ * expected to release all the frags which were mapped,
+ * so kfree_skb shouldn't do it again
+ */
skb_shinfo(skb)->nr_frags = 0;
+ if (skb_has_frag_list(skb)) {
+ struct sk_buff *nskb =
+ skb_shinfo(skb)->frag_list;
+ skb_shinfo(nskb)->nr_frags = 0;
+ }
kfree_skb(skb);
continue;
}
@@ -1822,15 +1864,12 @@ void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx)
tx_unmap_op.status);
BUG();
}
-
- xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_OKAY);
}
static inline int rx_work_todo(struct xenvif_queue *queue)
{
return (!skb_queue_empty(&queue->rx_queue) &&
- xenvif_rx_ring_slots_available(queue, queue->rx_last_skb_slots)) ||
- queue->rx_queue_purge;
+ xenvif_rx_ring_slots_available(queue, queue->rx_last_skb_slots));
}
static inline int tx_work_todo(struct xenvif_queue *queue)
@@ -1895,6 +1934,75 @@ static void xenvif_start_queue(struct xenvif_queue *queue)
xenvif_wake_queue(queue);
}
+/* Only called from the queue's thread, it handles the situation when the guest
+ * doesn't post enough requests on the receiving ring.
+ * First xenvif_start_xmit disables QDisc and start a timer, and then either the
+ * timer fires, or the guest send an interrupt after posting new request. If it
+ * is the timer, the carrier is turned off here.
+ * */
+static void xenvif_rx_purge_event(struct xenvif_queue *queue)
+{
+ /* Either the last unsuccesful skb or at least 1 slot should fit */
+ int needed = queue->rx_last_skb_slots ?
+ queue->rx_last_skb_slots : 1;
+
+ /* It is assumed that if the guest post new slots after this, the RX
+ * interrupt will set the QUEUE_STATUS_RX_PURGE_EVENT bit and wake up
+ * the thread again
+ */
+ set_bit(QUEUE_STATUS_RX_STALLED, &queue->status);
+ if (!xenvif_rx_ring_slots_available(queue, needed)) {
+ rtnl_lock();
+ if (netif_carrier_ok(queue->vif->dev)) {
+ /* Timer fired and there are still no slots. Turn off
+ * everything except the interrupts
+ */
+ netif_carrier_off(queue->vif->dev);
+ skb_queue_purge(&queue->rx_queue);
+ queue->rx_last_skb_slots = 0;
+ if (net_ratelimit())
+ netdev_err(queue->vif->dev, "Carrier off due to lack of guest response on queue %d\n", queue->id);
+ } else {
+ /* Probably an another queue already turned the carrier
+ * off, make sure nothing is stucked in the internal
+ * queue of this queue
+ */
+ skb_queue_purge(&queue->rx_queue);
+ queue->rx_last_skb_slots = 0;
+ }
+ rtnl_unlock();
+ } else if (!netif_carrier_ok(queue->vif->dev)) {
+ unsigned int num_queues = queue->vif->num_queues;
+ unsigned int i;
+ /* The carrier was down, but an interrupt kicked
+ * the thread again after new requests were
+ * posted
+ */
+ clear_bit(QUEUE_STATUS_RX_STALLED,
+ &queue->status);
+ rtnl_lock();
+ netif_carrier_on(queue->vif->dev);
+ netif_tx_wake_all_queues(queue->vif->dev);
+ rtnl_unlock();
+
+ for (i = 0; i < num_queues; i++) {
+ struct xenvif_queue *temp = &queue->vif->queues[i];
+
+ xenvif_napi_schedule_or_enable_events(temp);
+ }
+ if (net_ratelimit())
+ netdev_err(queue->vif->dev, "Carrier on again\n");
+ } else {
+ /* Queuing were stopped, but the guest posted
+ * new requests and sent an interrupt
+ */
+ clear_bit(QUEUE_STATUS_RX_STALLED,
+ &queue->status);
+ del_timer_sync(&queue->rx_stalled);
+ xenvif_start_queue(queue);
+ }
+}
+
int xenvif_kthread_guest_rx(void *data)
{
struct xenvif_queue *queue = data;
@@ -1904,8 +2012,12 @@ int xenvif_kthread_guest_rx(void *data)
wait_event_interruptible(queue->wq,
rx_work_todo(queue) ||
queue->vif->disabled ||
+ test_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status) ||
kthread_should_stop());
+ if (kthread_should_stop())
+ break;
+
/* This frontend is found to be rogue, disable it in
* kthread context. Currently this is only set when
* netback finds out frontend sends malformed packet,
@@ -1913,26 +2025,23 @@ int xenvif_kthread_guest_rx(void *data)
* context so we defer it here, if this thread is
* associated with queue 0.
*/
- if (unlikely(queue->vif->disabled && netif_carrier_ok(queue->vif->dev) && queue->id == 0))
+ if (unlikely(queue->vif->disabled && queue->id == 0))
xenvif_carrier_off(queue->vif);
-
- if (kthread_should_stop())
- break;
-
- if (queue->rx_queue_purge) {
+ else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT,
+ &queue->status))) {
+ xenvif_rx_purge_event(queue);
+ } else if (!netif_carrier_ok(queue->vif->dev)) {
+ /* Another queue stalled and turned the carrier off, so
+ * purge the internal queue of queues which were not
+ * blocked
+ */
skb_queue_purge(&queue->rx_queue);
- queue->rx_queue_purge = false;
+ queue->rx_last_skb_slots = 0;
}
if (!skb_queue_empty(&queue->rx_queue))
xenvif_rx_action(queue);
- if (skb_queue_empty(&queue->rx_queue) &&
- xenvif_queue_stopped(queue)) {
- del_timer_sync(&queue->wake_queue);
- xenvif_start_queue(queue);
- }
-
cond_resched();
}
@@ -1987,6 +2096,13 @@ static int __init netback_init(void)
rx_drain_timeout_jiffies = msecs_to_jiffies(rx_drain_timeout_msecs);
+#ifdef CONFIG_DEBUG_FS
+ xen_netback_dbg_root = debugfs_create_dir("xen-netback", NULL);
+ if (IS_ERR_OR_NULL(xen_netback_dbg_root))
+ pr_warn("Init of debugfs returned %ld!\n",
+ PTR_ERR(xen_netback_dbg_root));
+#endif /* CONFIG_DEBUG_FS */
+
return 0;
failed_init:
@@ -1997,6 +2113,10 @@ module_init(netback_init);
static void __exit netback_fini(void)
{
+#ifdef CONFIG_DEBUG_FS
+ if (!IS_ERR_OR_NULL(xen_netback_dbg_root))
+ debugfs_remove_recursive(xen_netback_dbg_root);
+#endif /* CONFIG_DEBUG_FS */
xenvif_xenbus_fini();
}
module_exit(netback_fini);
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index 3d85acd84bad..580517d857bf 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -44,6 +44,175 @@ static void unregister_hotplug_status_watch(struct backend_info *be);
static void set_backend_state(struct backend_info *be,
enum xenbus_state state);
+#ifdef CONFIG_DEBUG_FS
+struct dentry *xen_netback_dbg_root = NULL;
+
+static int xenvif_read_io_ring(struct seq_file *m, void *v)
+{
+ struct xenvif_queue *queue = m->private;
+ struct xen_netif_tx_back_ring *tx_ring = &queue->tx;
+ struct xen_netif_rx_back_ring *rx_ring = &queue->rx;
+
+ if (tx_ring->sring) {
+ struct xen_netif_tx_sring *sring = tx_ring->sring;
+
+ seq_printf(m, "Queue %d\nTX: nr_ents %u\n", queue->id,
+ tx_ring->nr_ents);
+ seq_printf(m, "req prod %u (%d) cons %u (%d) event %u (%d)\n",
+ sring->req_prod,
+ sring->req_prod - sring->rsp_prod,
+ tx_ring->req_cons,
+ tx_ring->req_cons - sring->rsp_prod,
+ sring->req_event,
+ sring->req_event - sring->rsp_prod);
+ seq_printf(m, "rsp prod %u (base) pvt %u (%d) event %u (%d)\n",
+ sring->rsp_prod,
+ tx_ring->rsp_prod_pvt,
+ tx_ring->rsp_prod_pvt - sring->rsp_prod,
+ sring->rsp_event,
+ sring->rsp_event - sring->rsp_prod);
+ seq_printf(m, "pending prod %u pending cons %u nr_pending_reqs %u\n",
+ queue->pending_prod,
+ queue->pending_cons,
+ nr_pending_reqs(queue));
+ seq_printf(m, "dealloc prod %u dealloc cons %u dealloc_queue %u\n\n",
+ queue->dealloc_prod,
+ queue->dealloc_cons,
+ queue->dealloc_prod - queue->dealloc_cons);
+ }
+
+ if (rx_ring->sring) {
+ struct xen_netif_rx_sring *sring = rx_ring->sring;
+
+ seq_printf(m, "RX: nr_ents %u\n", rx_ring->nr_ents);
+ seq_printf(m, "req prod %u (%d) cons %u (%d) event %u (%d)\n",
+ sring->req_prod,
+ sring->req_prod - sring->rsp_prod,
+ rx_ring->req_cons,
+ rx_ring->req_cons - sring->rsp_prod,
+ sring->req_event,
+ sring->req_event - sring->rsp_prod);
+ seq_printf(m, "rsp prod %u (base) pvt %u (%d) event %u (%d)\n\n",
+ sring->rsp_prod,
+ rx_ring->rsp_prod_pvt,
+ rx_ring->rsp_prod_pvt - sring->rsp_prod,
+ sring->rsp_event,
+ sring->rsp_event - sring->rsp_prod);
+ }
+
+ seq_printf(m, "NAPI state: %lx NAPI weight: %d TX queue len %u\n"
+ "Credit timer_pending: %d, credit: %lu, usec: %lu\n"
+ "remaining: %lu, expires: %lu, now: %lu\n",
+ queue->napi.state, queue->napi.weight,
+ skb_queue_len(&queue->tx_queue),
+ timer_pending(&queue->credit_timeout),
+ queue->credit_bytes,
+ queue->credit_usec,
+ queue->remaining_credit,
+ queue->credit_timeout.expires,
+ jiffies);
+
+ return 0;
+}
+
+#define XENVIF_KICK_STR "kick"
+
+static ssize_t
+xenvif_write_io_ring(struct file *filp, const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct xenvif_queue *queue =
+ ((struct seq_file *)filp->private_data)->private;
+ int len;
+ char write[sizeof(XENVIF_KICK_STR)];
+
+ /* don't allow partial writes and check the length */
+ if (*ppos != 0)
+ return 0;
+ if (count < sizeof(XENVIF_KICK_STR) - 1)
+ return -ENOSPC;
+
+ len = simple_write_to_buffer(write,
+ sizeof(write),
+ ppos,
+ buf,
+ count);
+ if (len < 0)
+ return len;
+
+ if (!strncmp(write, XENVIF_KICK_STR, sizeof(XENVIF_KICK_STR) - 1))
+ xenvif_interrupt(0, (void *)queue);
+ else {
+ pr_warn("Unknown command to io_ring_q%d. Available: kick\n",
+ queue->id);
+ count = -EINVAL;
+ }
+ return count;
+}
+
+static int xenvif_dump_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+ void *queue = NULL;
+
+ if (inode->i_private)
+ queue = inode->i_private;
+ ret = single_open(filp, xenvif_read_io_ring, queue);
+ filp->f_mode |= FMODE_PWRITE;
+ return ret;
+}
+
+static const struct file_operations xenvif_dbg_io_ring_ops_fops = {
+ .owner = THIS_MODULE,
+ .open = xenvif_dump_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = xenvif_write_io_ring,
+};
+
+static void xenvif_debugfs_addif(struct xenvif_queue *queue)
+{
+ struct dentry *pfile;
+ struct xenvif *vif = queue->vif;
+ int i;
+
+ if (IS_ERR_OR_NULL(xen_netback_dbg_root))
+ return;
+
+ vif->xenvif_dbg_root = debugfs_create_dir(vif->dev->name,
+ xen_netback_dbg_root);
+ if (!IS_ERR_OR_NULL(vif->xenvif_dbg_root)) {
+ for (i = 0; i < vif->num_queues; ++i) {
+ char filename[sizeof("io_ring_q") + 4];
+
+ snprintf(filename, sizeof(filename), "io_ring_q%d", i);
+ pfile = debugfs_create_file(filename,
+ S_IRUSR | S_IWUSR,
+ vif->xenvif_dbg_root,
+ &vif->queues[i],
+ &xenvif_dbg_io_ring_ops_fops);
+ if (IS_ERR_OR_NULL(pfile))
+ pr_warn("Creation of io_ring file returned %ld!\n",
+ PTR_ERR(pfile));
+ }
+ } else
+ netdev_warn(vif->dev,
+ "Creation of vif debugfs dir returned %ld!\n",
+ PTR_ERR(vif->xenvif_dbg_root));
+}
+
+static void xenvif_debugfs_delif(struct xenvif *vif)
+{
+ if (IS_ERR_OR_NULL(xen_netback_dbg_root))
+ return;
+
+ if (!IS_ERR_OR_NULL(vif->xenvif_dbg_root))
+ debugfs_remove_recursive(vif->xenvif_dbg_root);
+ vif->xenvif_dbg_root = NULL;
+}
+#endif /* CONFIG_DEBUG_FS */
+
static int netback_remove(struct xenbus_device *dev)
{
struct backend_info *be = dev_get_drvdata(&dev->dev);
@@ -246,8 +415,12 @@ static void backend_create_xenvif(struct backend_info *be)
static void backend_disconnect(struct backend_info *be)
{
- if (be->vif)
+ if (be->vif) {
+#ifdef CONFIG_DEBUG_FS
+ xenvif_debugfs_delif(be->vif);
+#endif /* CONFIG_DEBUG_FS */
xenvif_disconnect(be->vif);
+ }
}
static void backend_connect(struct backend_info *be)
@@ -560,6 +733,9 @@ static void connect(struct backend_info *be)
be->vif->num_queues = queue_index;
goto err;
}
+#ifdef CONFIG_DEBUG_FS
+ xenvif_debugfs_addif(queue);
+#endif /* CONFIG_DEBUG_FS */
}
/* Initialisation completed, tell core driver the number of
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 2ccb4a02368b..28204bc4f369 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1196,22 +1196,6 @@ static void xennet_release_rx_bufs(struct netfront_queue *queue)
spin_unlock_bh(&queue->rx_lock);
}
-static void xennet_uninit(struct net_device *dev)
-{
- struct netfront_info *np = netdev_priv(dev);
- unsigned int num_queues = dev->real_num_tx_queues;
- struct netfront_queue *queue;
- unsigned int i;
-
- for (i = 0; i < num_queues; ++i) {
- queue = &np->queues[i];
- xennet_release_tx_bufs(queue);
- xennet_release_rx_bufs(queue);
- gnttab_free_grant_references(queue->gref_tx_head);
- gnttab_free_grant_references(queue->gref_rx_head);
- }
-}
-
static netdev_features_t xennet_fix_features(struct net_device *dev,
netdev_features_t features)
{
@@ -1313,7 +1297,6 @@ static void xennet_poll_controller(struct net_device *dev)
static const struct net_device_ops xennet_netdev_ops = {
.ndo_open = xennet_open,
- .ndo_uninit = xennet_uninit,
.ndo_stop = xennet_close,
.ndo_start_xmit = xennet_start_xmit,
.ndo_change_mtu = xennet_change_mtu,
@@ -1439,16 +1422,11 @@ static void xennet_disconnect_backend(struct netfront_info *info)
unsigned int i = 0;
unsigned int num_queues = info->netdev->real_num_tx_queues;
+ netif_carrier_off(info->netdev);
+
for (i = 0; i < num_queues; ++i) {
struct netfront_queue *queue = &info->queues[i];
- /* Stop old i/f to prevent errors whilst we rebuild the state. */
- spin_lock_bh(&queue->rx_lock);
- spin_lock_irq(&queue->tx_lock);
- netif_carrier_off(queue->info->netdev);
- spin_unlock_irq(&queue->tx_lock);
- spin_unlock_bh(&queue->rx_lock);
-
if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
unbind_from_irqhandler(queue->tx_irq, queue);
if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
@@ -1458,6 +1436,13 @@ static void xennet_disconnect_backend(struct netfront_info *info)
queue->tx_evtchn = queue->rx_evtchn = 0;
queue->tx_irq = queue->rx_irq = 0;
+ napi_synchronize(&queue->napi);
+
+ xennet_release_tx_bufs(queue);
+ xennet_release_rx_bufs(queue);
+ gnttab_free_grant_references(queue->gref_tx_head);
+ gnttab_free_grant_references(queue->gref_rx_head);
+
/* End access and free the pages */
xennet_end_access(queue->tx_ring_ref, queue->tx.sring);
xennet_end_access(queue->rx_ring_ref, queue->rx.sring);
@@ -1830,8 +1815,8 @@ static int xennet_create_queues(struct netfront_info *info,
ret = xennet_init_queue(queue);
if (ret < 0) {
- dev_warn(&info->netdev->dev, "only created %d queues\n",
- num_queues);
+ dev_warn(&info->netdev->dev,
+ "only created %d queues\n", i);
num_queues = i;
break;
}
@@ -2004,7 +1989,7 @@ abort_transaction_no_dev_fatal:
info->queues = NULL;
rtnl_lock();
netif_set_real_num_tx_queues(info->netdev, 0);
- rtnl_lock();
+ rtnl_unlock();
out:
return err;
}
@@ -2013,10 +1998,7 @@ static int xennet_connect(struct net_device *dev)
{
struct netfront_info *np = netdev_priv(dev);
unsigned int num_queues = 0;
- int i, requeue_idx, err;
- struct sk_buff *skb;
- grant_ref_t ref;
- struct xen_netif_rx_request *req;
+ int err;
unsigned int feature_rx_copy;
unsigned int j = 0;
struct netfront_queue *queue = NULL;
@@ -2043,43 +2025,8 @@ static int xennet_connect(struct net_device *dev)
netdev_update_features(dev);
rtnl_unlock();
- /* By now, the queue structures have been set up */
- for (j = 0; j < num_queues; ++j) {
- queue = &np->queues[j];
- spin_lock_bh(&queue->rx_lock);
- spin_lock_irq(&queue->tx_lock);
-
- /* Step 1: Discard all pending TX packet fragments. */
- xennet_release_tx_bufs(queue);
-
- /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
- for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
- skb_frag_t *frag;
- const struct page *page;
- if (!queue->rx_skbs[i])
- continue;
-
- skb = queue->rx_skbs[requeue_idx] = xennet_get_rx_skb(queue, i);
- ref = queue->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(queue, i);
- req = RING_GET_REQUEST(&queue->rx, requeue_idx);
-
- frag = &skb_shinfo(skb)->frags[0];
- page = skb_frag_page(frag);
- gnttab_grant_foreign_access_ref(
- ref, queue->info->xbdev->otherend_id,
- pfn_to_mfn(page_to_pfn(page)),
- 0);
- req->gref = ref;
- req->id = requeue_idx;
-
- requeue_idx++;
- }
-
- queue->rx.req_prod_pvt = requeue_idx;
- }
-
/*
- * Step 3: All public and private state should now be sane. Get
+ * All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
* packets.
@@ -2087,13 +2034,17 @@ static int xennet_connect(struct net_device *dev)
netif_carrier_on(np->netdev);
for (j = 0; j < num_queues; ++j) {
queue = &np->queues[j];
+
notify_remote_via_irq(queue->tx_irq);
if (queue->tx_irq != queue->rx_irq)
notify_remote_via_irq(queue->rx_irq);
- xennet_tx_buf_gc(queue);
- xennet_alloc_rx_buffers(queue);
+ spin_lock_irq(&queue->tx_lock);
+ xennet_tx_buf_gc(queue);
spin_unlock_irq(&queue->tx_lock);
+
+ spin_lock_bh(&queue->rx_lock);
+ xennet_alloc_rx_buffers(queue);
spin_unlock_bh(&queue->rx_lock);
}
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 26c66a126551..7929fac13e1c 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -72,5 +72,5 @@ source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/microread/Kconfig"
source "drivers/nfc/nfcmrvl/Kconfig"
source "drivers/nfc/st21nfca/Kconfig"
-
+source "drivers/nfc/st21nfcb/Kconfig"
endmenu
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 23225b0287fd..6b23a2c6e34a 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o
obj-$(CONFIG_NFC_MRVL) += nfcmrvl/
obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o
-obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/
+obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/
+obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/
ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/st21nfca/Makefile b/drivers/nfc/st21nfca/Makefile
index 038ed093a119..db7a38ae05f7 100644
--- a/drivers/nfc/st21nfca/Makefile
+++ b/drivers/nfc/st21nfca/Makefile
@@ -4,5 +4,5 @@
st21nfca_i2c-objs = i2c.o
-obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o
+obj-$(CONFIG_NFC_ST21NFCA) += st21nfca.o st21nfca_dep.o
obj-$(CONFIG_NFC_ST21NFCA_I2C) += st21nfca_i2c.o
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
index 3f954ed86d98..ff31939978ae 100644
--- a/drivers/nfc/st21nfca/i2c.c
+++ b/drivers/nfc/st21nfca/i2c.c
@@ -93,7 +93,7 @@ struct st21nfca_i2c_phy {
int hard_fault;
struct mutex phy_lock;
};
-static u8 len_seq[] = { 13, 24, 15, 29 };
+static u8 len_seq[] = { 16, 24, 12, 29 };
static u16 wait_tab[] = { 2, 3, 5, 15, 20, 40};
#define I2C_DUMP_SKB(info, skb) \
@@ -397,12 +397,11 @@ static int st21nfca_hci_i2c_read(struct st21nfca_i2c_phy *phy,
* The first read sequence does not start with SOF.
* Data is corrupeted so we drop it.
*/
- if (!phy->current_read_len && buf[0] != ST21NFCA_SOF_EOF) {
+ if (!phy->current_read_len && !IS_START_OF_FRAME(buf)) {
skb_trim(skb, 0);
phy->current_read_len = 0;
return -EIO;
- } else if (phy->current_read_len &&
- IS_START_OF_FRAME(buf)) {
+ } else if (phy->current_read_len && IS_START_OF_FRAME(buf)) {
/*
* Previous frame transmission was interrupted and
* the frame got repeated.
@@ -487,6 +486,8 @@ static irqreturn_t st21nfca_hci_irq_thread_fn(int irq, void *phy_id)
*/
nfc_hci_recv_frame(phy->hdev, phy->pending_skb);
phy->crc_trials = 0;
+ } else {
+ kfree_skb(phy->pending_skb);
}
phy->pending_skb = alloc_skb(ST21NFCA_HCI_LLC_MAX_SIZE * 2, GFP_KERNEL);
diff --git a/drivers/nfc/st21nfca/st21nfca.c b/drivers/nfc/st21nfca/st21nfca.c
index 51e0f00b3a4f..a902b0551c86 100644
--- a/drivers/nfc/st21nfca/st21nfca.c
+++ b/drivers/nfc/st21nfca/st21nfca.c
@@ -22,6 +22,7 @@
#include <net/nfc/llc.h>
#include "st21nfca.h"
+#include "st21nfca_dep.h"
#define DRIVER_DESC "HCI NFC driver for ST21NFCA"
@@ -53,6 +54,7 @@
#define ST21NFCA_DM_PIPE_CREATED 0x02
#define ST21NFCA_DM_PIPE_OPEN 0x04
#define ST21NFCA_DM_RF_ACTIVE 0x80
+#define ST21NFCA_DM_DISCONNECT 0x30
#define ST21NFCA_DM_IS_PIPE_OPEN(p) \
((p & 0x0f) == (ST21NFCA_DM_PIPE_CREATED | ST21NFCA_DM_PIPE_OPEN))
@@ -72,6 +74,7 @@ static struct nfc_hci_gate st21nfca_gates[] = {
{ST21NFCA_RF_READER_F_GATE, NFC_HCI_INVALID_PIPE},
{ST21NFCA_RF_READER_14443_3_A_GATE, NFC_HCI_INVALID_PIPE},
{ST21NFCA_RF_READER_ISO15693_GATE, NFC_HCI_INVALID_PIPE},
+ {ST21NFCA_RF_CARD_F_GATE, NFC_HCI_INVALID_PIPE},
};
struct st21nfca_pipe_info {
@@ -299,6 +302,9 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
u32 im_protocols, u32 tm_protocols)
{
int r;
+ u32 pol_req;
+ u8 param[19];
+ struct sk_buff *datarate_skb;
pr_info(DRIVER_DESC ": %s protocols 0x%x 0x%x\n",
__func__, im_protocols, tm_protocols);
@@ -331,6 +337,31 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
ST21NFCA_RF_READER_F_GATE);
if (r < 0)
return r;
+ } else {
+ hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
+ &hdev->gb_len);
+
+ if (hdev->gb == NULL || hdev->gb_len == 0) {
+ im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
+ tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
+ }
+
+ param[0] = ST21NFCA_RF_READER_F_DATARATE_106 |
+ ST21NFCA_RF_READER_F_DATARATE_212 |
+ ST21NFCA_RF_READER_F_DATARATE_424;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_RF_READER_F_DATARATE,
+ param, 1);
+ if (r < 0)
+ return r;
+
+ pol_req =
+ be32_to_cpu(ST21NFCA_RF_READER_F_POL_REQ_DEFAULT);
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_RF_READER_F_POL_REQ,
+ (u8 *) &pol_req, 4);
+ if (r < 0)
+ return r;
}
if ((ST21NFCA_RF_READER_14443_3_A_GATE & im_protocols) == 0) {
@@ -353,9 +384,104 @@ static int st21nfca_hci_start_poll(struct nfc_hci_dev *hdev,
nfc_hci_send_event(hdev, NFC_HCI_RF_READER_A_GATE,
NFC_HCI_EVT_END_OPERATION, NULL, 0);
}
+
+ if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
+ r = nfc_hci_get_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_DATARATE,
+ &datarate_skb);
+ if (r < 0)
+ return r;
+
+ /* Configure the maximum supported datarate to 424Kbps */
+ if (datarate_skb->len > 0 &&
+ datarate_skb->data[0] !=
+ ST21NFCA_RF_CARD_F_DATARATE_212_424) {
+ param[0] = ST21NFCA_RF_CARD_F_DATARATE_212_424;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_DATARATE,
+ param, 1);
+ if (r < 0)
+ return r;
+ }
+
+ /*
+ * Configure sens_res
+ *
+ * NFC Forum Digital Spec Table 7:
+ * NFCID1 size: triple (10 bytes)
+ */
+ param[0] = 0x00;
+ param[1] = 0x08;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_SENS_RES, param, 2);
+ if (r < 0)
+ return r;
+
+ /*
+ * Configure sel_res
+ *
+ * NFC Forum Digistal Spec Table 17:
+ * b3 set to 0b (value b7-b6):
+ * - 10b: Configured for NFC-DEP Protocol
+ */
+ param[0] = 0x40;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_SEL_RES, param, 1);
+ if (r < 0)
+ return r;
+
+ /* Configure NFCID1 Random uid */
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_NFCID1, NULL, 0);
+ if (r < 0)
+ return r;
+
+ /* Configure NFCID2_LIST */
+ /* System Code */
+ param[0] = 0x00;
+ param[1] = 0x00;
+ /* NFCID2 */
+ param[2] = 0x01;
+ param[3] = 0xfe;
+ param[4] = 'S';
+ param[5] = 'T';
+ param[6] = 'M';
+ param[7] = 'i';
+ param[8] = 'c';
+ param[9] = 'r';
+ /* 8 byte Pad bytes used for polling respone frame */
+
+ /*
+ * Configuration byte:
+ * - bit 0: define the default NFCID2 entry used when the
+ * system code is equal to 'FFFF'
+ * - bit 1: use a random value for lowest 6 bytes of
+ * NFCID2 value
+ * - bit 2: ignore polling request frame if request code
+ * is equal to '01'
+ * - Other bits are RFU
+ */
+ param[18] = 0x01;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_NFCID2_LIST, param,
+ 19);
+ if (r < 0)
+ return r;
+
+ param[0] = 0x02;
+ r = nfc_hci_set_param(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_RF_CARD_F_MODE, param, 1);
+ }
+
return r;
}
+static void st21nfca_hci_stop_poll(struct nfc_hci_dev *hdev)
+{
+ nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
+ ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
+}
+
static int st21nfca_get_iso14443_3_atqa(struct nfc_hci_dev *hdev, u16 *atqa)
{
int r;
@@ -451,6 +577,26 @@ exit:
return r;
}
+static int st21nfca_hci_dep_link_up(struct nfc_hci_dev *hdev,
+ struct nfc_target *target, u8 comm_mode,
+ u8 *gb, size_t gb_len)
+{
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ info->dep_info.idx = target->idx;
+ return st21nfca_im_send_atr_req(hdev, gb, gb_len);
+}
+
+static int st21nfca_hci_dep_link_down(struct nfc_hci_dev *hdev)
+{
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ info->state = ST21NFCA_ST_READY;
+
+ return nfc_hci_send_cmd(hdev, ST21NFCA_DEVICE_MGNT_GATE,
+ ST21NFCA_DM_DISCONNECT, NULL, 0, NULL);
+}
+
static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
struct nfc_target *target)
{
@@ -505,6 +651,69 @@ static int st21nfca_hci_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
return 0;
}
+static int st21nfca_hci_complete_target_discovered(struct nfc_hci_dev *hdev,
+ u8 gate,
+ struct nfc_target *target)
+{
+ int r;
+ struct sk_buff *nfcid2_skb = NULL, *nfcid1_skb;
+
+ if (gate == ST21NFCA_RF_READER_F_GATE) {
+ r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_RF_READER_F_NFCID2, &nfcid2_skb);
+ if (r < 0)
+ goto exit;
+
+ if (nfcid2_skb->len > NFC_SENSF_RES_MAXSIZE) {
+ r = -EPROTO;
+ goto exit;
+ }
+
+ /*
+ * - After the recepton of polling response for type F frame
+ * at 212 or 424 Kbit/s, NFCID2 registry parameters will be
+ * updated.
+ * - After the reception of SEL_RES with NFCIP-1 compliant bit
+ * set for type A frame NFCID1 will be updated
+ */
+ if (nfcid2_skb->len > 0) {
+ /* P2P in type F */
+ memcpy(target->sensf_res, nfcid2_skb->data,
+ nfcid2_skb->len);
+ target->sensf_res_len = nfcid2_skb->len;
+ /* NFC Forum Digital Protocol Table 44 */
+ if (target->sensf_res[0] == 0x01 &&
+ target->sensf_res[1] == 0xfe)
+ target->supported_protocols =
+ NFC_PROTO_NFC_DEP_MASK;
+ else
+ target->supported_protocols =
+ NFC_PROTO_FELICA_MASK;
+ } else {
+ /* P2P in type A */
+ r = nfc_hci_get_param(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_RF_READER_F_NFCID1,
+ &nfcid1_skb);
+ if (r < 0)
+ goto exit;
+
+ if (nfcid1_skb->len > NFC_NFCID1_MAXSIZE) {
+ r = -EPROTO;
+ goto exit;
+ }
+ memcpy(target->sensf_res, nfcid1_skb->data,
+ nfcid1_skb->len);
+ target->sensf_res_len = nfcid1_skb->len;
+ target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+ }
+ target->hci_reader_gate = ST21NFCA_RF_READER_F_GATE;
+ }
+ r = 1;
+exit:
+ kfree_skb(nfcid2_skb);
+ return r;
+}
+
#define ST21NFCA_CB_TYPE_READER_ISO15693 1
static void st21nfca_hci_data_exchange_cb(void *context, struct sk_buff *skb,
int err)
@@ -541,6 +750,9 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
switch (target->hci_reader_gate) {
case ST21NFCA_RF_READER_F_GATE:
+ if (target->supported_protocols == NFC_PROTO_NFC_DEP_MASK)
+ return st21nfca_im_send_dep_req(hdev, skb);
+
*skb_push(skb, 1) = 0x1a;
return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
ST21NFCA_WR_XCHG_DATA, skb->data,
@@ -569,6 +781,11 @@ static int st21nfca_hci_im_transceive(struct nfc_hci_dev *hdev,
}
}
+static int st21nfca_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
+{
+ return st21nfca_tm_send_dep_res(hdev, skb);
+}
+
static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target)
{
@@ -594,6 +811,50 @@ static int st21nfca_hci_check_presence(struct nfc_hci_dev *hdev,
}
}
+/*
+ * Returns:
+ * <= 0: driver handled the event, skb consumed
+ * 1: driver does not handle the event, please do standard processing
+ */
+static int st21nfca_hci_event_received(struct nfc_hci_dev *hdev, u8 gate,
+ u8 event, struct sk_buff *skb)
+{
+ int r;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ pr_debug("hci event: %d\n", event);
+
+ switch (event) {
+ case ST21NFCA_EVT_CARD_ACTIVATED:
+ if (gate == ST21NFCA_RF_CARD_F_GATE)
+ info->dep_info.curr_nfc_dep_pni = 0;
+ break;
+ case ST21NFCA_EVT_CARD_DEACTIVATED:
+ break;
+ case ST21NFCA_EVT_FIELD_ON:
+ break;
+ case ST21NFCA_EVT_FIELD_OFF:
+ break;
+ case ST21NFCA_EVT_SEND_DATA:
+ if (gate == ST21NFCA_RF_CARD_F_GATE) {
+ r = st21nfca_tm_event_send_data(hdev, skb, gate);
+ if (r < 0)
+ goto exit;
+ return 0;
+ } else {
+ info->dep_info.curr_nfc_dep_pni = 0;
+ return 1;
+ }
+ break;
+ default:
+ return 1;
+ }
+ kfree_skb(skb);
+ return 0;
+exit:
+ return r;
+}
+
static struct nfc_hci_ops st21nfca_hci_ops = {
.open = st21nfca_hci_open,
.close = st21nfca_hci_close,
@@ -601,9 +862,15 @@ static struct nfc_hci_ops st21nfca_hci_ops = {
.hci_ready = st21nfca_hci_ready,
.xmit = st21nfca_hci_xmit,
.start_poll = st21nfca_hci_start_poll,
+ .stop_poll = st21nfca_hci_stop_poll,
+ .dep_link_up = st21nfca_hci_dep_link_up,
+ .dep_link_down = st21nfca_hci_dep_link_down,
.target_from_gate = st21nfca_hci_target_from_gate,
+ .complete_target_discovered = st21nfca_hci_complete_target_discovered,
.im_transceive = st21nfca_hci_im_transceive,
+ .tm_send = st21nfca_hci_tm_send,
.check_presence = st21nfca_hci_check_presence,
+ .event_received = st21nfca_hci_event_received,
};
int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
@@ -648,7 +915,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
NFC_PROTO_FELICA_MASK |
NFC_PROTO_ISO14443_MASK |
NFC_PROTO_ISO14443_B_MASK |
- NFC_PROTO_ISO15693_MASK;
+ NFC_PROTO_ISO15693_MASK |
+ NFC_PROTO_NFC_DEP_MASK;
set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);
@@ -671,6 +939,7 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
goto err_regdev;
*hdev = info->hdev;
+ st21nfca_dep_init(info->hdev);
return 0;
@@ -688,6 +957,7 @@ void st21nfca_hci_remove(struct nfc_hci_dev *hdev)
{
struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+ st21nfca_dep_deinit(hdev);
nfc_hci_unregister_device(hdev);
nfc_hci_free_device(hdev);
kfree(info);
diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h
index 334cd90bcc8c..96fe5a62dc0d 100644
--- a/drivers/nfc/st21nfca/st21nfca.h
+++ b/drivers/nfc/st21nfca/st21nfca.h
@@ -19,6 +19,8 @@
#include <net/nfc/hci.h>
+#include "st21nfca_dep.h"
+
#define HCI_MODE 0
/* framing in HCI mode */
@@ -73,7 +75,8 @@ struct st21nfca_hci_info {
data_exchange_cb_t async_cb;
void *async_cb_context;
-} __packed;
+ struct st21nfca_dep_info dep_info;
+};
/* Reader RF commands */
#define ST21NFCA_WR_XCHG_DATA 0x10
@@ -83,5 +86,26 @@ struct st21nfca_hci_info {
#define ST21NFCA_RF_READER_F_DATARATE_106 0x01
#define ST21NFCA_RF_READER_F_DATARATE_212 0x02
#define ST21NFCA_RF_READER_F_DATARATE_424 0x04
+#define ST21NFCA_RF_READER_F_POL_REQ 0x02
+#define ST21NFCA_RF_READER_F_POL_REQ_DEFAULT 0xffff0000
+#define ST21NFCA_RF_READER_F_NFCID2 0x03
+#define ST21NFCA_RF_READER_F_NFCID1 0x04
+#define ST21NFCA_RF_READER_F_SENS_RES 0x05
+
+#define ST21NFCA_RF_CARD_F_GATE 0x24
+#define ST21NFCA_RF_CARD_F_MODE 0x01
+#define ST21NFCA_RF_CARD_F_NFCID2_LIST 0x04
+#define ST21NFCA_RF_CARD_F_NFCID1 0x05
+#define ST21NFCA_RF_CARD_F_SENS_RES 0x06
+#define ST21NFCA_RF_CARD_F_SEL_RES 0x07
+#define ST21NFCA_RF_CARD_F_DATARATE 0x08
+#define ST21NFCA_RF_CARD_F_DATARATE_106 0x00
+#define ST21NFCA_RF_CARD_F_DATARATE_212_424 0x01
+
+#define ST21NFCA_EVT_SEND_DATA 0x10
+#define ST21NFCA_EVT_FIELD_ON 0x11
+#define ST21NFCA_EVT_CARD_DEACTIVATED 0x12
+#define ST21NFCA_EVT_CARD_ACTIVATED 0x13
+#define ST21NFCA_EVT_FIELD_OFF 0x14
#endif /* __LOCAL_ST21NFCA_H_ */
diff --git a/drivers/nfc/st21nfca/st21nfca_dep.c b/drivers/nfc/st21nfca/st21nfca_dep.c
new file mode 100644
index 000000000000..b2d9957b57f8
--- /dev/null
+++ b/drivers/nfc/st21nfca/st21nfca_dep.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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 <net/nfc/hci.h>
+
+#include "st21nfca.h"
+#include "st21nfca_dep.h"
+
+#define ST21NFCA_NFCIP1_INITIATOR 0x00
+#define ST21NFCA_NFCIP1_REQ 0xd4
+#define ST21NFCA_NFCIP1_RES 0xd5
+#define ST21NFCA_NFCIP1_ATR_REQ 0x00
+#define ST21NFCA_NFCIP1_ATR_RES 0x01
+#define ST21NFCA_NFCIP1_PSL_REQ 0x04
+#define ST21NFCA_NFCIP1_PSL_RES 0x05
+#define ST21NFCA_NFCIP1_DEP_REQ 0x06
+#define ST21NFCA_NFCIP1_DEP_RES 0x07
+
+#define ST21NFCA_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03)
+#define ST21NFCA_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
+#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
+ ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
+#define ST21NFCA_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
+#define ST21NFCA_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
+#define ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT 0x10
+
+#define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
+ ((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
+
+#define ST21NFCA_NFC_DEP_PFB_I_PDU 0x00
+#define ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU 0x40
+#define ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
+
+#define ST21NFCA_ATR_REQ_MIN_SIZE 17
+#define ST21NFCA_ATR_REQ_MAX_SIZE 65
+#define ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B 0x30
+#define ST21NFCA_GB_BIT 0x02
+
+#define ST21NFCA_EVT_CARD_F_BITRATE 0x16
+#define ST21NFCA_EVT_READER_F_BITRATE 0x13
+#define ST21NFCA_PSL_REQ_SEND_SPEED(brs) (brs & 0x38)
+#define ST21NFCA_PSL_REQ_RECV_SPEED(brs) (brs & 0x07)
+#define ST21NFCA_PP2LRI(pp) ((pp & 0x30) >> 4)
+#define ST21NFCA_CARD_BITRATE_212 0x01
+#define ST21NFCA_CARD_BITRATE_424 0x02
+
+#define ST21NFCA_DEFAULT_TIMEOUT 0x0a
+
+
+#define PROTOCOL_ERR(req) pr_err("%d: ST21NFCA Protocol error: %s\n", \
+ __LINE__, req)
+
+struct st21nfca_atr_req {
+ u8 length;
+ u8 cmd0;
+ u8 cmd1;
+ u8 nfcid3[NFC_NFCID3_MAXSIZE];
+ u8 did;
+ u8 bsi;
+ u8 bri;
+ u8 ppi;
+ u8 gbi[0];
+} __packed;
+
+struct st21nfca_atr_res {
+ u8 length;
+ u8 cmd0;
+ u8 cmd1;
+ u8 nfcid3[NFC_NFCID3_MAXSIZE];
+ u8 did;
+ u8 bsi;
+ u8 bri;
+ u8 to;
+ u8 ppi;
+ u8 gbi[0];
+} __packed;
+
+struct st21nfca_psl_req {
+ u8 length;
+ u8 cmd0;
+ u8 cmd1;
+ u8 did;
+ u8 brs;
+ u8 fsl;
+} __packed;
+
+struct st21nfca_psl_res {
+ u8 length;
+ u8 cmd0;
+ u8 cmd1;
+ u8 did;
+} __packed;
+
+struct st21nfca_dep_req_res {
+ u8 length;
+ u8 cmd0;
+ u8 cmd1;
+ u8 pfb;
+ u8 did;
+ u8 nad;
+} __packed;
+
+static void st21nfca_tx_work(struct work_struct *work)
+{
+ struct st21nfca_hci_info *info = container_of(work,
+ struct st21nfca_hci_info,
+ dep_info.tx_work);
+
+ struct nfc_dev *dev;
+ struct sk_buff *skb;
+ if (info) {
+ dev = info->hdev->ndev;
+ skb = info->dep_info.tx_pending;
+
+ device_lock(&dev->dev);
+
+ nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_WR_XCHG_DATA,
+ skb->data, skb->len,
+ info->async_cb, info);
+ device_unlock(&dev->dev);
+ kfree_skb(skb);
+ }
+}
+
+static void st21nfca_im_send_pdu(struct st21nfca_hci_info *info,
+ struct sk_buff *skb)
+{
+ info->dep_info.tx_pending = skb;
+ schedule_work(&info->dep_info.tx_work);
+}
+
+static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
+ struct st21nfca_atr_req *atr_req)
+{
+ struct st21nfca_atr_res *atr_res;
+ struct sk_buff *skb;
+ size_t gb_len;
+ int r;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
+ skb = alloc_skb(atr_req->length + 1, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, sizeof(struct st21nfca_atr_res));
+
+ atr_res = (struct st21nfca_atr_res *)skb->data;
+ memset(atr_res, 0, sizeof(struct st21nfca_atr_res));
+
+ atr_res->length = atr_req->length + 1;
+ atr_res->cmd0 = ST21NFCA_NFCIP1_RES;
+ atr_res->cmd1 = ST21NFCA_NFCIP1_ATR_RES;
+
+ memcpy(atr_res->nfcid3, atr_req->nfcid3, 6);
+ atr_res->bsi = 0x00;
+ atr_res->bri = 0x00;
+ atr_res->to = ST21NFCA_DEFAULT_TIMEOUT;
+ atr_res->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
+
+ if (gb_len) {
+ skb_put(skb, gb_len);
+
+ atr_res->ppi |= ST21NFCA_GB_BIT;
+ memcpy(atr_res->gbi, atr_req->gbi, gb_len);
+ r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
+ gb_len);
+ if (r < 0)
+ return r;
+ }
+
+ info->dep_info.curr_nfc_dep_pni = 0;
+
+ return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+}
+
+static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct st21nfca_atr_req *atr_req;
+ size_t gb_len;
+ int r;
+
+ skb_trim(skb, skb->len - 1);
+ if (IS_ERR(skb)) {
+ r = PTR_ERR(skb);
+ goto exit;
+ }
+
+ if (!skb->len) {
+ r = -EIO;
+ goto exit;
+ }
+
+ if (skb->len < ST21NFCA_ATR_REQ_MIN_SIZE) {
+ r = -EPROTO;
+ goto exit;
+ }
+
+ atr_req = (struct st21nfca_atr_req *)skb->data;
+
+ r = st21nfca_tm_send_atr_res(hdev, atr_req);
+ if (r)
+ goto exit;
+
+ gb_len = skb->len - sizeof(struct st21nfca_atr_req);
+
+ r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
+ NFC_COMM_PASSIVE, atr_req->gbi, gb_len);
+ if (r)
+ goto exit;
+
+ r = 0;
+
+exit:
+ return r;
+}
+
+static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
+ struct st21nfca_psl_req *psl_req)
+{
+ struct st21nfca_psl_res *psl_res;
+ struct sk_buff *skb;
+ u8 bitrate[2] = {0, 0};
+
+ int r;
+
+ skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+ skb_put(skb, sizeof(struct st21nfca_psl_res));
+
+ psl_res = (struct st21nfca_psl_res *)skb->data;
+
+ psl_res->length = sizeof(struct st21nfca_psl_res);
+ psl_res->cmd0 = ST21NFCA_NFCIP1_RES;
+ psl_res->cmd1 = ST21NFCA_NFCIP1_PSL_RES;
+ psl_res->did = psl_req->did;
+
+ r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+
+ /*
+ * ST21NFCA only support P2P passive.
+ * PSL_REQ BRS value != 0 has only a meaning to
+ * change technology to type F.
+ * We change to BITRATE 424Kbits.
+ * In other case switch to BITRATE 106Kbits.
+ */
+ if (ST21NFCA_PSL_REQ_SEND_SPEED(psl_req->brs) &&
+ ST21NFCA_PSL_REQ_RECV_SPEED(psl_req->brs)) {
+ bitrate[0] = ST21NFCA_CARD_BITRATE_424;
+ bitrate[1] = ST21NFCA_CARD_BITRATE_424;
+ }
+
+ /* Send an event to change bitrate change event to card f */
+ return nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
+}
+
+static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct st21nfca_psl_req *psl_req;
+ int r;
+
+ skb_trim(skb, skb->len - 1);
+ if (IS_ERR(skb)) {
+ r = PTR_ERR(skb);
+ skb = NULL;
+ goto exit;
+ }
+
+ if (!skb->len) {
+ r = -EIO;
+ goto exit;
+ }
+
+ psl_req = (struct st21nfca_psl_req *)skb->data;
+
+ if (skb->len < sizeof(struct st21nfca_psl_req)) {
+ r = -EIO;
+ goto exit;
+ }
+
+ r = st21nfca_tm_send_psl_res(hdev, psl_req);
+exit:
+ return r;
+}
+
+int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
+{
+ int r;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_RES;
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_RES;
+ *skb_push(skb, 1) = skb->len;
+
+ r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
+ ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
+ kfree_skb(skb);
+
+ return r;
+}
+EXPORT_SYMBOL(st21nfca_tm_send_dep_res);
+
+static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct st21nfca_dep_req_res *dep_req;
+ u8 size;
+ int r;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ skb_trim(skb, skb->len - 1);
+ if (IS_ERR(skb)) {
+ r = PTR_ERR(skb);
+ skb = NULL;
+ goto exit;
+ }
+
+ size = 4;
+
+ dep_req = (struct st21nfca_dep_req_res *)skb->data;
+ if (skb->len < size) {
+ r = -EIO;
+ goto exit;
+ }
+
+ if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_req->pfb))
+ size++;
+ if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_req->pfb))
+ size++;
+
+ if (skb->len < size) {
+ r = -EIO;
+ goto exit;
+ }
+
+ /* Receiving DEP_REQ - Decoding */
+ switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
+ case ST21NFCA_NFC_DEP_PFB_I_PDU:
+ info->dep_info.curr_nfc_dep_pni =
+ ST21NFCA_NFC_DEP_PFB_PNI(dep_req->pfb);
+ break;
+ case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
+ pr_err("Received a ACK/NACK PDU\n");
+ break;
+ case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
+ pr_err("Received a SUPERVISOR PDU\n");
+ break;
+ }
+
+ if (IS_ERR(skb)) {
+ r = PTR_ERR(skb);
+ skb = NULL;
+ goto exit;
+ }
+
+ skb_pull(skb, size);
+
+ return nfc_tm_data_received(hdev->ndev, skb);
+exit:
+ return r;
+}
+
+int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev, struct sk_buff *skb,
+ u8 gate)
+{
+ u8 cmd0, cmd1;
+ int r;
+
+ cmd0 = skb->data[1];
+ switch (cmd0) {
+ case ST21NFCA_NFCIP1_REQ:
+ cmd1 = skb->data[2];
+ switch (cmd1) {
+ case ST21NFCA_NFCIP1_ATR_REQ:
+ r = st21nfca_tm_recv_atr_req(hdev, skb);
+ break;
+ case ST21NFCA_NFCIP1_PSL_REQ:
+ r = st21nfca_tm_recv_psl_req(hdev, skb);
+ break;
+ case ST21NFCA_NFCIP1_DEP_REQ:
+ r = st21nfca_tm_recv_dep_req(hdev, skb);
+ break;
+ default:
+ return 1;
+ }
+ default:
+ return 1;
+ }
+ return r;
+}
+EXPORT_SYMBOL(st21nfca_tm_event_send_data);
+
+static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
+ u8 bri, u8 lri)
+{
+ struct sk_buff *skb;
+ struct st21nfca_psl_req *psl_req;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ skb =
+ alloc_skb(sizeof(struct st21nfca_psl_req) + 1, GFP_KERNEL);
+ if (!skb)
+ return;
+ skb_reserve(skb, 1);
+
+ skb_put(skb, sizeof(struct st21nfca_psl_req));
+ psl_req = (struct st21nfca_psl_req *) skb->data;
+
+ psl_req->length = sizeof(struct st21nfca_psl_req);
+ psl_req->cmd0 = ST21NFCA_NFCIP1_REQ;
+ psl_req->cmd1 = ST21NFCA_NFCIP1_PSL_REQ;
+ psl_req->did = did;
+ psl_req->brs = (0x30 & bsi << 4) | (bri & 0x03);
+ psl_req->fsl = lri;
+
+ *skb_push(skb, 1) = info->dep_info.to | 0x10;
+
+ st21nfca_im_send_pdu(info, skb);
+
+ kfree_skb(skb);
+}
+
+#define ST21NFCA_CB_TYPE_READER_F 1
+static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
+ int err)
+{
+ struct st21nfca_hci_info *info = context;
+ struct st21nfca_atr_res *atr_res;
+ int r;
+
+ if (err != 0)
+ return;
+
+ if (IS_ERR(skb))
+ return;
+
+ switch (info->async_cb_type) {
+ case ST21NFCA_CB_TYPE_READER_F:
+ skb_trim(skb, skb->len - 1);
+ atr_res = (struct st21nfca_atr_res *)skb->data;
+ r = nfc_set_remote_general_bytes(info->hdev->ndev,
+ atr_res->gbi,
+ skb->len - sizeof(struct st21nfca_atr_res));
+ if (r < 0)
+ return;
+
+ if (atr_res->to >= 0x0e)
+ info->dep_info.to = 0x0e;
+ else
+ info->dep_info.to = atr_res->to + 1;
+
+ info->dep_info.to |= 0x10;
+
+ r = nfc_dep_link_is_up(info->hdev->ndev, info->dep_info.idx,
+ NFC_COMM_PASSIVE, NFC_RF_INITIATOR);
+ if (r < 0)
+ return;
+
+ info->dep_info.curr_nfc_dep_pni = 0;
+ if (ST21NFCA_PP2LRI(atr_res->ppi) != info->dep_info.lri)
+ st21nfca_im_send_psl_req(info->hdev, atr_res->did,
+ atr_res->bsi, atr_res->bri,
+ ST21NFCA_PP2LRI(atr_res->ppi));
+ break;
+ default:
+ if (err == 0)
+ kfree_skb(skb);
+ break;
+ }
+}
+
+int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
+{
+ struct sk_buff *skb;
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+ struct st21nfca_atr_req *atr_req;
+ struct nfc_target *target;
+ uint size;
+
+ info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
+ size = ST21NFCA_ATR_REQ_MIN_SIZE + gb_len;
+ if (size > ST21NFCA_ATR_REQ_MAX_SIZE) {
+ PROTOCOL_ERR("14.6.1.1");
+ return -EINVAL;
+ }
+
+ skb =
+ alloc_skb(sizeof(struct st21nfca_atr_req) + gb_len + 1, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reserve(skb, 1);
+
+ skb_put(skb, sizeof(struct st21nfca_atr_req));
+
+ atr_req = (struct st21nfca_atr_req *)skb->data;
+ memset(atr_req, 0, sizeof(struct st21nfca_atr_req));
+
+ atr_req->cmd0 = ST21NFCA_NFCIP1_REQ;
+ atr_req->cmd1 = ST21NFCA_NFCIP1_ATR_REQ;
+ memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
+ target = hdev->ndev->targets;
+
+ if (target->sensf_res)
+ memcpy(atr_req->nfcid3, target->sensf_res,
+ target->sensf_res_len);
+ else
+ get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
+
+ atr_req->did = 0x0;
+
+ atr_req->bsi = 0x00;
+ atr_req->bri = 0x00;
+ atr_req->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
+ if (gb_len) {
+ atr_req->ppi |= ST21NFCA_GB_BIT;
+ memcpy(skb_put(skb, gb_len), gb, gb_len);
+ }
+ atr_req->length = sizeof(struct st21nfca_atr_req) + hdev->gb_len;
+
+ *skb_push(skb, 1) = info->dep_info.to | 0x10; /* timeout */
+
+ info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
+ info->async_cb_context = info;
+ info->async_cb = st21nfca_im_recv_atr_res_cb;
+ info->dep_info.bri = atr_req->bri;
+ info->dep_info.bsi = atr_req->bsi;
+ info->dep_info.lri = ST21NFCA_PP2LRI(atr_req->ppi);
+
+ return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_WR_XCHG_DATA, skb->data,
+ skb->len, info->async_cb, info);
+}
+EXPORT_SYMBOL(st21nfca_im_send_atr_req);
+
+static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
+ int err)
+{
+ struct st21nfca_hci_info *info = context;
+ struct st21nfca_dep_req_res *dep_res;
+
+ int size;
+
+ if (err != 0)
+ return;
+
+ if (IS_ERR(skb))
+ return;
+
+ switch (info->async_cb_type) {
+ case ST21NFCA_CB_TYPE_READER_F:
+ dep_res = (struct st21nfca_dep_req_res *)skb->data;
+
+ size = 3;
+ if (skb->len < size)
+ goto exit;
+
+ if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_res->pfb))
+ size++;
+ if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_res->pfb))
+ size++;
+
+ if (skb->len < size)
+ goto exit;
+
+ skb_trim(skb, skb->len - 1);
+
+ /* Receiving DEP_REQ - Decoding */
+ switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_res->pfb)) {
+ case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
+ pr_err("Received a ACK/NACK PDU\n");
+ case ST21NFCA_NFC_DEP_PFB_I_PDU:
+ info->dep_info.curr_nfc_dep_pni =
+ ST21NFCA_NFC_DEP_PFB_PNI(dep_res->pfb + 1);
+ size++;
+ skb_pull(skb, size);
+ nfc_tm_data_received(info->hdev->ndev, skb);
+ break;
+ case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
+ pr_err("Received a SUPERVISOR PDU\n");
+ skb_pull(skb, size);
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
+ *skb_push(skb, 1) = skb->len;
+ *skb_push(skb, 1) = info->dep_info.to | 0x10;
+
+ st21nfca_im_send_pdu(info, skb);
+ break;
+ }
+
+ return;
+ default:
+ break;
+ }
+
+exit:
+ if (err == 0)
+ kfree_skb(skb);
+}
+
+int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)
+{
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
+ info->async_cb_context = info;
+ info->async_cb = st21nfca_im_recv_dep_res_cb;
+
+ *skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
+ *skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
+ *skb_push(skb, 1) = skb->len;
+
+ *skb_push(skb, 1) = info->dep_info.to | 0x10;
+
+ return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
+ ST21NFCA_WR_XCHG_DATA,
+ skb->data, skb->len,
+ info->async_cb, info);
+}
+EXPORT_SYMBOL(st21nfca_im_send_dep_req);
+
+void st21nfca_dep_init(struct nfc_hci_dev *hdev)
+{
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ INIT_WORK(&info->dep_info.tx_work, st21nfca_tx_work);
+ info->dep_info.curr_nfc_dep_pni = 0;
+ info->dep_info.idx = 0;
+ info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
+}
+EXPORT_SYMBOL(st21nfca_dep_init);
+
+void st21nfca_dep_deinit(struct nfc_hci_dev *hdev)
+{
+ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
+
+ cancel_work_sync(&info->dep_info.tx_work);
+}
+EXPORT_SYMBOL(st21nfca_dep_deinit);
diff --git a/drivers/nfc/st21nfca/st21nfca_dep.h b/drivers/nfc/st21nfca/st21nfca_dep.h
new file mode 100644
index 000000000000..ca213dee9c6e
--- /dev/null
+++ b/drivers/nfc/st21nfca/st21nfca_dep.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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 __ST21NFCA_DEP_H
+#define __ST21NFCA_DEP_H
+
+#include <linux/skbuff.h>
+#include <linux/workqueue.h>
+
+struct st21nfca_dep_info {
+ struct sk_buff *tx_pending;
+ struct work_struct tx_work;
+ u8 curr_nfc_dep_pni;
+ u32 idx;
+ u8 to;
+ u8 did;
+ u8 bsi;
+ u8 bri;
+ u8 lri;
+} __packed;
+
+int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev, struct sk_buff *skb,
+ u8 gate);
+int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb);
+
+int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len);
+int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb);
+void st21nfca_dep_init(struct nfc_hci_dev *hdev);
+void st21nfca_dep_deinit(struct nfc_hci_dev *hdev);
+#endif /* __ST21NFCA_DEP_H */
diff --git a/drivers/nfc/st21nfcb/Kconfig b/drivers/nfc/st21nfcb/Kconfig
new file mode 100644
index 000000000000..e0322dd03a70
--- /dev/null
+++ b/drivers/nfc/st21nfcb/Kconfig
@@ -0,0 +1,22 @@
+config NFC_ST21NFCB
+ tristate "STMicroelectronics ST21NFCB NFC driver"
+ depends on NFC_NCI
+ default n
+ ---help---
+ STMicroelectronics ST21NFCB core driver. It implements the chipset
+ NCI logic and hooks into the NFC kernel APIs. Physical layers will
+ register against it.
+
+ To compile this driver as a module, choose m here. The module will
+ be called st21nfcb.
+ Say N if unsure.
+
+config NFC_ST21NFCB_I2C
+ tristate "NFC ST21NFCB i2c support"
+ depends on NFC_ST21NFCB && I2C
+ ---help---
+ This module adds support for the STMicroelectronics st21nfcb i2c interface.
+ Select this if your platform is using the i2c bus.
+
+ If you choose to build a module, it'll be called st21nfcb_i2c.
+ Say N if unsure.
diff --git a/drivers/nfc/st21nfcb/Makefile b/drivers/nfc/st21nfcb/Makefile
new file mode 100644
index 000000000000..13d9f03b2fea
--- /dev/null
+++ b/drivers/nfc/st21nfcb/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for ST21NFCB NCI based NFC driver
+#
+
+st21nfcb_i2c-objs = i2c.o
+
+obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb.o ndlc.o
+obj-$(CONFIG_NFC_ST21NFCB_I2C) += st21nfcb_i2c.o
diff --git a/drivers/nfc/st21nfcb/i2c.c b/drivers/nfc/st21nfcb/i2c.c
new file mode 100644
index 000000000000..8af880ead5db
--- /dev/null
+++ b/drivers/nfc/st21nfcb/i2c.c
@@ -0,0 +1,462 @@
+/*
+ * I2C Link Layer for ST21NFCB NCI based Driver
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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/>.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/crc-ccitt.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/nfc.h>
+#include <linux/firmware.h>
+#include <linux/unaligned/access_ok.h>
+#include <linux/platform_data/st21nfcb.h>
+
+#include <net/nfc/nci.h>
+#include <net/nfc/llc.h>
+#include <net/nfc/nfc.h>
+
+#include "ndlc.h"
+
+#define DRIVER_DESC "NCI NFC driver for ST21NFCB"
+
+/* ndlc header */
+#define ST21NFCB_FRAME_HEADROOM 1
+#define ST21NFCB_FRAME_TAILROOM 0
+
+#define ST21NFCB_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */
+#define ST21NFCB_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */
+
+#define ST21NFCB_NCI_I2C_DRIVER_NAME "st21nfcb_nci_i2c"
+
+static struct i2c_device_id st21nfcb_nci_i2c_id_table[] = {
+ {ST21NFCB_NCI_DRIVER_NAME, 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, st21nfcb_nci_i2c_id_table);
+
+struct st21nfcb_i2c_phy {
+ struct i2c_client *i2c_dev;
+ struct llt_ndlc *ndlc;
+
+ unsigned int gpio_irq;
+ unsigned int gpio_reset;
+ unsigned int irq_polarity;
+
+ int powered;
+
+ /*
+ * < 0 if hardware error occured (e.g. i2c err)
+ * and prevents normal operation.
+ */
+ int hard_fault;
+};
+
+#define I2C_DUMP_SKB(info, skb) \
+do { \
+ pr_debug("%s:\n", info); \
+ print_hex_dump(KERN_DEBUG, "i2c: ", DUMP_PREFIX_OFFSET, \
+ 16, 1, (skb)->data, (skb)->len, 0); \
+} while (0)
+
+static int st21nfcb_nci_i2c_enable(void *phy_id)
+{
+ struct st21nfcb_i2c_phy *phy = phy_id;
+
+ gpio_set_value(phy->gpio_reset, 0);
+ usleep_range(10000, 15000);
+ gpio_set_value(phy->gpio_reset, 1);
+ phy->powered = 1;
+ usleep_range(80000, 85000);
+
+ return 0;
+}
+
+static void st21nfcb_nci_i2c_disable(void *phy_id)
+{
+ struct st21nfcb_i2c_phy *phy = phy_id;
+
+ pr_info("\n");
+
+ phy->powered = 0;
+ /* reset chip in order to flush clf */
+ gpio_set_value(phy->gpio_reset, 0);
+ usleep_range(10000, 15000);
+ gpio_set_value(phy->gpio_reset, 1);
+}
+
+static void st21nfcb_nci_remove_header(struct sk_buff *skb)
+{
+ skb_pull(skb, ST21NFCB_FRAME_HEADROOM);
+}
+
+/*
+ * Writing a frame must not return the number of written bytes.
+ * It must return either zero for success, or <0 for error.
+ * In addition, it must not alter the skb
+ */
+static int st21nfcb_nci_i2c_write(void *phy_id, struct sk_buff *skb)
+{
+ int r = -1;
+ struct st21nfcb_i2c_phy *phy = phy_id;
+ struct i2c_client *client = phy->i2c_dev;
+
+ I2C_DUMP_SKB("st21nfcb_nci_i2c_write", skb);
+
+ if (phy->hard_fault != 0)
+ return phy->hard_fault;
+
+ r = i2c_master_send(client, skb->data, skb->len);
+ if (r == -EREMOTEIO) { /* Retry, chip was in standby */
+ usleep_range(1000, 4000);
+ r = i2c_master_send(client, skb->data, skb->len);
+ }
+
+ if (r >= 0) {
+ if (r != skb->len)
+ r = -EREMOTEIO;
+ else
+ r = 0;
+ }
+
+ st21nfcb_nci_remove_header(skb);
+
+ return r;
+}
+
+/*
+ * Reads an ndlc frame and returns it in a newly allocated sk_buff.
+ * returns:
+ * frame size : if received frame is complete (find ST21NFCB_SOF_EOF at
+ * end of read)
+ * -EAGAIN : if received frame is incomplete (not find ST21NFCB_SOF_EOF
+ * at end of read)
+ * -EREMOTEIO : i2c read error (fatal)
+ * -EBADMSG : frame was incorrect and discarded
+ * (value returned from st21nfcb_nci_i2c_repack)
+ * -EIO : if no ST21NFCB_SOF_EOF is found after reaching
+ * the read length end sequence
+ */
+static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy,
+ struct sk_buff **skb)
+{
+ int r;
+ u8 len;
+ u8 buf[ST21NFCB_NCI_I2C_MAX_SIZE];
+ struct i2c_client *client = phy->i2c_dev;
+
+ r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE);
+ if (r == -EREMOTEIO) { /* Retry, chip was in standby */
+ usleep_range(1000, 4000);
+ r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE);
+ } else if (r != ST21NFCB_NCI_I2C_MIN_SIZE) {
+ nfc_err(&client->dev, "cannot read ndlc & nci header\n");
+ return -EREMOTEIO;
+ }
+
+ len = be16_to_cpu(*(__be16 *) (buf + 2));
+ if (len > ST21NFCB_NCI_I2C_MAX_SIZE) {
+ nfc_err(&client->dev, "invalid frame len\n");
+ return -EBADMSG;
+ }
+
+ *skb = alloc_skb(ST21NFCB_NCI_I2C_MIN_SIZE + len, GFP_KERNEL);
+ if (*skb == NULL)
+ return -ENOMEM;
+
+ skb_reserve(*skb, ST21NFCB_NCI_I2C_MIN_SIZE);
+ skb_put(*skb, ST21NFCB_NCI_I2C_MIN_SIZE);
+ memcpy((*skb)->data, buf, ST21NFCB_NCI_I2C_MIN_SIZE);
+
+ if (!len)
+ return 0;
+
+ r = i2c_master_recv(client, buf, len);
+ if (r != len) {
+ kfree_skb(*skb);
+ return -EREMOTEIO;
+ }
+
+ skb_put(*skb, len);
+ memcpy((*skb)->data + ST21NFCB_NCI_I2C_MIN_SIZE, buf, len);
+
+ I2C_DUMP_SKB("i2c frame read", *skb);
+
+ return 0;
+}
+
+/*
+ * Reads an ndlc frame from the chip.
+ *
+ * On ST21NFCB, IRQ goes in idle state when read starts.
+ */
+static irqreturn_t st21nfcb_nci_irq_thread_fn(int irq, void *phy_id)
+{
+ struct st21nfcb_i2c_phy *phy = phy_id;
+ struct i2c_client *client;
+ struct sk_buff *skb = NULL;
+ int r;
+
+ if (!phy || irq != phy->i2c_dev->irq) {
+ WARN_ON_ONCE(1);
+ return IRQ_NONE;
+ }
+
+ client = phy->i2c_dev;
+ dev_dbg(&client->dev, "IRQ\n");
+
+ if (phy->hard_fault)
+ return IRQ_HANDLED;
+
+ if (!phy->powered) {
+ st21nfcb_nci_i2c_disable(phy);
+ return IRQ_HANDLED;
+ }
+
+ r = st21nfcb_nci_i2c_read(phy, &skb);
+ if (r == -EREMOTEIO) {
+ phy->hard_fault = r;
+ ndlc_recv(phy->ndlc, NULL);
+ return IRQ_HANDLED;
+ } else if (r == -ENOMEM || r == -EBADMSG) {
+ return IRQ_HANDLED;
+ }
+
+ ndlc_recv(phy->ndlc, skb);
+
+ return IRQ_HANDLED;
+}
+
+static struct nfc_phy_ops i2c_phy_ops = {
+ .write = st21nfcb_nci_i2c_write,
+ .enable = st21nfcb_nci_i2c_enable,
+ .disable = st21nfcb_nci_i2c_disable,
+};
+
+#ifdef CONFIG_OF
+static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client)
+{
+ struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client);
+ struct device_node *pp;
+ int gpio;
+ int r;
+
+ pp = client->dev.of_node;
+ if (!pp)
+ return -ENODEV;
+
+ /* Get GPIO from device tree */
+ gpio = of_get_named_gpio(pp, "reset-gpios", 0);
+ if (gpio < 0) {
+ nfc_err(&client->dev,
+ "Failed to retrieve reset-gpios from device tree\n");
+ return gpio;
+ }
+
+ /* GPIO request and configuration */
+ r = devm_gpio_request(&client->dev, gpio, "clf_reset");
+ if (r) {
+ nfc_err(&client->dev, "Failed to request reset pin\n");
+ return -ENODEV;
+ }
+
+ r = gpio_direction_output(gpio, 1);
+ if (r) {
+ nfc_err(&client->dev,
+ "Failed to set reset pin direction as output\n");
+ return -ENODEV;
+ }
+ phy->gpio_reset = gpio;
+
+ /* IRQ */
+ r = irq_of_parse_and_map(pp, 0);
+ if (r < 0) {
+ nfc_err(&client->dev,
+ "Unable to get irq, error: %d\n", r);
+ return r;
+ }
+
+ phy->irq_polarity = irq_get_trigger_type(r);
+ client->irq = r;
+
+ return 0;
+}
+#else
+static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client)
+{
+ return -ENODEV;
+}
+#endif
+
+static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client)
+{
+ struct st21nfcb_nfc_platform_data *pdata;
+ struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client);
+ int r;
+ int irq;
+
+ pdata = client->dev.platform_data;
+ if (pdata == NULL) {
+ nfc_err(&client->dev, "No platform data\n");
+ return -EINVAL;
+ }
+
+ /* store for later use */
+ phy->gpio_irq = pdata->gpio_irq;
+ phy->gpio_reset = pdata->gpio_reset;
+ phy->irq_polarity = pdata->irq_polarity;
+
+ r = devm_gpio_request(&client->dev, phy->gpio_irq, "wake_up");
+ if (r) {
+ pr_err("%s : gpio_request failed\n", __FILE__);
+ return -ENODEV;
+ }
+
+ r = gpio_direction_input(phy->gpio_irq);
+ if (r) {
+ pr_err("%s : gpio_direction_input failed\n", __FILE__);
+ return -ENODEV;
+ }
+
+ r = devm_gpio_request(&client->dev,
+ phy->gpio_reset, "clf_reset");
+ if (r) {
+ pr_err("%s : reset gpio_request failed\n", __FILE__);
+ return -ENODEV;
+ }
+
+ r = gpio_direction_output(phy->gpio_reset, 1);
+ if (r) {
+ pr_err("%s : reset gpio_direction_output failed\n",
+ __FILE__);
+ return -ENODEV;
+ }
+
+ /* IRQ */
+ irq = gpio_to_irq(phy->gpio_irq);
+ if (irq < 0) {
+ nfc_err(&client->dev,
+ "Unable to get irq number for GPIO %d error %d\n",
+ phy->gpio_irq, r);
+ return -ENODEV;
+ }
+ client->irq = irq;
+
+ return 0;
+}
+
+static int st21nfcb_nci_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct st21nfcb_i2c_phy *phy;
+ struct st21nfcb_nfc_platform_data *pdata;
+ int r;
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+ dev_dbg(&client->dev, "IRQ: %d\n", client->irq);
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
+ return -ENODEV;
+ }
+
+ phy = devm_kzalloc(&client->dev, sizeof(struct st21nfcb_i2c_phy),
+ GFP_KERNEL);
+ if (!phy) {
+ nfc_err(&client->dev,
+ "Cannot allocate memory for st21nfcb i2c phy.\n");
+ return -ENOMEM;
+ }
+
+ phy->i2c_dev = client;
+
+ i2c_set_clientdata(client, phy);
+
+ pdata = client->dev.platform_data;
+ if (!pdata && client->dev.of_node) {
+ r = st21nfcb_nci_i2c_of_request_resources(client);
+ if (r) {
+ nfc_err(&client->dev, "No platform data\n");
+ return r;
+ }
+ } else if (pdata) {
+ r = st21nfcb_nci_i2c_request_resources(client);
+ if (r) {
+ nfc_err(&client->dev,
+ "Cannot get platform resources\n");
+ return r;
+ }
+ } else {
+ nfc_err(&client->dev,
+ "st21nfcb platform resources not available\n");
+ return -ENODEV;
+ }
+
+ r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ st21nfcb_nci_irq_thread_fn,
+ phy->irq_polarity | IRQF_ONESHOT,
+ ST21NFCB_NCI_DRIVER_NAME, phy);
+ if (r < 0) {
+ nfc_err(&client->dev, "Unable to register IRQ handler\n");
+ return r;
+ }
+
+ return ndlc_probe(phy, &i2c_phy_ops, &client->dev,
+ ST21NFCB_FRAME_HEADROOM, ST21NFCB_FRAME_TAILROOM,
+ &phy->ndlc);
+}
+
+static int st21nfcb_nci_i2c_remove(struct i2c_client *client)
+{
+ struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client);
+
+ dev_dbg(&client->dev, "%s\n", __func__);
+
+ ndlc_remove(phy->ndlc);
+
+ if (phy->powered)
+ st21nfcb_nci_i2c_disable(phy);
+
+ return 0;
+}
+
+static const struct of_device_id of_st21nfcb_i2c_match[] = {
+ { .compatible = "st,st21nfcb_i2c", },
+ {}
+};
+
+static struct i2c_driver st21nfcb_nci_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = ST21NFCB_NCI_I2C_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(of_st21nfcb_i2c_match),
+ },
+ .probe = st21nfcb_nci_i2c_probe,
+ .id_table = st21nfcb_nci_i2c_id_table,
+ .remove = st21nfcb_nci_i2c_remove,
+};
+
+module_i2c_driver(st21nfcb_nci_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/nfc/st21nfcb/ndlc.c b/drivers/nfc/st21nfcb/ndlc.c
new file mode 100644
index 000000000000..83c97c36112b
--- /dev/null
+++ b/drivers/nfc/st21nfcb/ndlc.c
@@ -0,0 +1,298 @@
+/*
+ * Low Level Transport (NDLC) Driver for STMicroelectronics NFC Chip
+ *
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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/sched.h>
+#include <net/nfc/nci_core.h>
+
+#include "ndlc.h"
+#include "st21nfcb.h"
+
+#define NDLC_TIMER_T1 100
+#define NDLC_TIMER_T1_WAIT 400
+#define NDLC_TIMER_T2 1200
+
+#define PCB_TYPE_DATAFRAME 0x80
+#define PCB_TYPE_SUPERVISOR 0xc0
+#define PCB_TYPE_MASK PCB_TYPE_SUPERVISOR
+
+#define PCB_SYNC_ACK 0x20
+#define PCB_SYNC_NACK 0x10
+#define PCB_SYNC_WAIT 0x30
+#define PCB_SYNC_NOINFO 0x00
+#define PCB_SYNC_MASK PCB_SYNC_WAIT
+
+#define PCB_DATAFRAME_RETRANSMIT_YES 0x00
+#define PCB_DATAFRAME_RETRANSMIT_NO 0x04
+#define PCB_DATAFRAME_RETRANSMIT_MASK PCB_DATAFRAME_RETRANSMIT_NO
+
+#define PCB_SUPERVISOR_RETRANSMIT_YES 0x00
+#define PCB_SUPERVISOR_RETRANSMIT_NO 0x02
+#define PCB_SUPERVISOR_RETRANSMIT_MASK PCB_SUPERVISOR_RETRANSMIT_NO
+
+#define PCB_FRAME_CRC_INFO_PRESENT 0x08
+#define PCB_FRAME_CRC_INFO_NOTPRESENT 0x00
+#define PCB_FRAME_CRC_INFO_MASK PCB_FRAME_CRC_INFO_PRESENT
+
+#define NDLC_DUMP_SKB(info, skb) \
+do { \
+ pr_debug("%s:\n", info); \
+ print_hex_dump(KERN_DEBUG, "ndlc: ", DUMP_PREFIX_OFFSET, \
+ 16, 1, skb->data, skb->len, 0); \
+} while (0)
+
+int ndlc_open(struct llt_ndlc *ndlc)
+{
+ /* toggle reset pin */
+ ndlc->ops->enable(ndlc->phy_id);
+ return 0;
+}
+EXPORT_SYMBOL(ndlc_open);
+
+void ndlc_close(struct llt_ndlc *ndlc)
+{
+ /* toggle reset pin */
+ ndlc->ops->disable(ndlc->phy_id);
+}
+EXPORT_SYMBOL(ndlc_close);
+
+int ndlc_send(struct llt_ndlc *ndlc, struct sk_buff *skb)
+{
+ /* add ndlc header */
+ u8 pcb = PCB_TYPE_DATAFRAME | PCB_DATAFRAME_RETRANSMIT_NO |
+ PCB_FRAME_CRC_INFO_NOTPRESENT;
+
+ *skb_push(skb, 1) = pcb;
+ skb_queue_tail(&ndlc->send_q, skb);
+
+ schedule_work(&ndlc->sm_work);
+
+ return 0;
+}
+EXPORT_SYMBOL(ndlc_send);
+
+static void llt_ndlc_send_queue(struct llt_ndlc *ndlc)
+{
+ struct sk_buff *skb;
+ int r;
+ unsigned long time_sent;
+
+ if (ndlc->send_q.qlen)
+ pr_debug("sendQlen=%d unackQlen=%d\n",
+ ndlc->send_q.qlen, ndlc->ack_pending_q.qlen);
+
+ while (ndlc->send_q.qlen) {
+ skb = skb_dequeue(&ndlc->send_q);
+ NDLC_DUMP_SKB("ndlc frame written", skb);
+ r = ndlc->ops->write(ndlc->phy_id, skb);
+ if (r < 0) {
+ ndlc->hard_fault = r;
+ break;
+ }
+ time_sent = jiffies;
+ *(unsigned long *)skb->cb = time_sent;
+
+ skb_queue_tail(&ndlc->ack_pending_q, skb);
+
+ /* start timer t1 for ndlc aknowledge */
+ ndlc->t1_active = true;
+ mod_timer(&ndlc->t1_timer, time_sent +
+ msecs_to_jiffies(NDLC_TIMER_T1));
+ }
+}
+
+static void llt_ndlc_requeue_data_pending(struct llt_ndlc *ndlc)
+{
+ struct sk_buff *skb;
+ u8 pcb;
+
+ while ((skb = skb_dequeue_tail(&ndlc->ack_pending_q))) {
+ pcb = skb->data[0];
+ switch (pcb & PCB_TYPE_MASK) {
+ case PCB_TYPE_SUPERVISOR:
+ skb->data[0] = (pcb & ~PCB_SUPERVISOR_RETRANSMIT_MASK) |
+ PCB_SUPERVISOR_RETRANSMIT_YES;
+ break;
+ case PCB_TYPE_DATAFRAME:
+ skb->data[0] = (pcb & ~PCB_DATAFRAME_RETRANSMIT_MASK) |
+ PCB_DATAFRAME_RETRANSMIT_YES;
+ break;
+ default:
+ pr_err("UNKNOWN Packet Control Byte=%d\n", pcb);
+ kfree_skb(skb);
+ break;
+ }
+ skb_queue_head(&ndlc->send_q, skb);
+ }
+}
+
+static void llt_ndlc_rcv_queue(struct llt_ndlc *ndlc)
+{
+ struct sk_buff *skb;
+ u8 pcb;
+ unsigned long time_sent;
+
+ if (ndlc->rcv_q.qlen)
+ pr_debug("rcvQlen=%d\n", ndlc->rcv_q.qlen);
+
+ while ((skb = skb_dequeue(&ndlc->rcv_q)) != NULL) {
+ pcb = skb->data[0];
+ skb_pull(skb, 1);
+ if ((pcb & PCB_TYPE_MASK) == PCB_TYPE_SUPERVISOR) {
+ switch (pcb & PCB_SYNC_MASK) {
+ case PCB_SYNC_ACK:
+ del_timer_sync(&ndlc->t1_timer);
+ del_timer_sync(&ndlc->t2_timer);
+ ndlc->t2_active = false;
+ ndlc->t1_active = false;
+ break;
+ case PCB_SYNC_NACK:
+ llt_ndlc_requeue_data_pending(ndlc);
+ llt_ndlc_send_queue(ndlc);
+ /* start timer t1 for ndlc aknowledge */
+ time_sent = jiffies;
+ ndlc->t1_active = true;
+ mod_timer(&ndlc->t1_timer, time_sent +
+ msecs_to_jiffies(NDLC_TIMER_T1));
+ break;
+ case PCB_SYNC_WAIT:
+ time_sent = jiffies;
+ ndlc->t1_active = true;
+ mod_timer(&ndlc->t1_timer, time_sent +
+ msecs_to_jiffies(NDLC_TIMER_T1_WAIT));
+ break;
+ default:
+ pr_err("UNKNOWN Packet Control Byte=%d\n", pcb);
+ kfree_skb(skb);
+ break;
+ }
+ } else {
+ nci_recv_frame(ndlc->ndev, skb);
+ }
+ }
+}
+
+static void llt_ndlc_sm_work(struct work_struct *work)
+{
+ struct llt_ndlc *ndlc = container_of(work, struct llt_ndlc, sm_work);
+
+ llt_ndlc_send_queue(ndlc);
+ llt_ndlc_rcv_queue(ndlc);
+
+ if (ndlc->t1_active && timer_pending(&ndlc->t1_timer) == 0) {
+ pr_debug
+ ("Handle T1(recv SUPERVISOR) elapsed (T1 now inactive)\n");
+ ndlc->t1_active = false;
+
+ llt_ndlc_requeue_data_pending(ndlc);
+ llt_ndlc_send_queue(ndlc);
+ }
+
+ if (ndlc->t2_active && timer_pending(&ndlc->t2_timer) == 0) {
+ pr_debug("Handle T2(recv DATA) elapsed (T2 now inactive)\n");
+ ndlc->t2_active = false;
+ ndlc->t1_active = false;
+ del_timer_sync(&ndlc->t1_timer);
+
+ ndlc_close(ndlc);
+ ndlc->hard_fault = -EREMOTEIO;
+ }
+}
+
+void ndlc_recv(struct llt_ndlc *ndlc, struct sk_buff *skb)
+{
+ if (skb == NULL) {
+ pr_err("NULL Frame -> link is dead\n");
+ ndlc->hard_fault = -EREMOTEIO;
+ ndlc_close(ndlc);
+ } else {
+ NDLC_DUMP_SKB("incoming frame", skb);
+ skb_queue_tail(&ndlc->rcv_q, skb);
+ }
+
+ schedule_work(&ndlc->sm_work);
+}
+EXPORT_SYMBOL(ndlc_recv);
+
+static void ndlc_t1_timeout(unsigned long data)
+{
+ struct llt_ndlc *ndlc = (struct llt_ndlc *)data;
+
+ pr_debug("\n");
+
+ schedule_work(&ndlc->sm_work);
+}
+
+static void ndlc_t2_timeout(unsigned long data)
+{
+ struct llt_ndlc *ndlc = (struct llt_ndlc *)data;
+
+ pr_debug("\n");
+
+ schedule_work(&ndlc->sm_work);
+}
+
+int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev,
+ int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id)
+{
+ struct llt_ndlc *ndlc;
+
+ ndlc = devm_kzalloc(dev, sizeof(struct llt_ndlc), GFP_KERNEL);
+ if (!ndlc) {
+ nfc_err(dev, "Cannot allocate memory for ndlc.\n");
+ return -ENOMEM;
+ }
+ ndlc->ops = phy_ops;
+ ndlc->phy_id = phy_id;
+ ndlc->dev = dev;
+
+ *ndlc_id = ndlc;
+
+ /* start timers */
+ init_timer(&ndlc->t1_timer);
+ ndlc->t1_timer.data = (unsigned long)ndlc;
+ ndlc->t1_timer.function = ndlc_t1_timeout;
+
+ init_timer(&ndlc->t2_timer);
+ ndlc->t2_timer.data = (unsigned long)ndlc;
+ ndlc->t2_timer.function = ndlc_t2_timeout;
+
+ skb_queue_head_init(&ndlc->rcv_q);
+ skb_queue_head_init(&ndlc->send_q);
+ skb_queue_head_init(&ndlc->ack_pending_q);
+
+ INIT_WORK(&ndlc->sm_work, llt_ndlc_sm_work);
+
+ return st21nfcb_nci_probe(ndlc, phy_headroom, phy_tailroom);
+}
+EXPORT_SYMBOL(ndlc_probe);
+
+void ndlc_remove(struct llt_ndlc *ndlc)
+{
+ /* cancel timers */
+ del_timer_sync(&ndlc->t1_timer);
+ del_timer_sync(&ndlc->t2_timer);
+ ndlc->t2_active = false;
+ ndlc->t1_active = false;
+
+ skb_queue_purge(&ndlc->rcv_q);
+ skb_queue_purge(&ndlc->send_q);
+
+ st21nfcb_nci_remove(ndlc->ndev);
+ kfree(ndlc);
+}
+EXPORT_SYMBOL(ndlc_remove);
diff --git a/drivers/nfc/st21nfcb/ndlc.h b/drivers/nfc/st21nfcb/ndlc.h
new file mode 100644
index 000000000000..c30a2f0faa5f
--- /dev/null
+++ b/drivers/nfc/st21nfcb/ndlc.h
@@ -0,0 +1,55 @@
+/*
+ * NCI based Driver for STMicroelectronics NFC Chip
+ *
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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 __LOCAL_NDLC_H_
+#define __LOCAL_NDLC_H_
+
+#include <linux/skbuff.h>
+#include <net/nfc/nfc.h>
+
+/* Low Level Transport description */
+struct llt_ndlc {
+ struct nci_dev *ndev;
+ struct nfc_phy_ops *ops;
+ void *phy_id;
+
+ struct timer_list t1_timer;
+ bool t1_active;
+
+ struct timer_list t2_timer;
+ bool t2_active;
+
+ struct sk_buff_head rcv_q;
+ struct sk_buff_head send_q;
+ struct sk_buff_head ack_pending_q;
+
+ struct work_struct sm_work;
+
+ struct device *dev;
+
+ int hard_fault;
+};
+
+int ndlc_open(struct llt_ndlc *ndlc);
+void ndlc_close(struct llt_ndlc *ndlc);
+int ndlc_send(struct llt_ndlc *ndlc, struct sk_buff *skb);
+void ndlc_recv(struct llt_ndlc *ndlc, struct sk_buff *skb);
+int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev,
+ int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id);
+void ndlc_remove(struct llt_ndlc *ndlc);
+#endif /* __LOCAL_NDLC_H__ */
diff --git a/drivers/nfc/st21nfcb/st21nfcb.c b/drivers/nfc/st21nfcb/st21nfcb.c
new file mode 100644
index 000000000000..4d95863e3063
--- /dev/null
+++ b/drivers/nfc/st21nfcb/st21nfcb.c
@@ -0,0 +1,129 @@
+/*
+ * NCI based Driver for STMicroelectronics NFC Chip
+ *
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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/module.h>
+#include <linux/nfc.h>
+#include <net/nfc/nci.h>
+#include <net/nfc/nci_core.h>
+
+#include "st21nfcb.h"
+#include "ndlc.h"
+
+#define DRIVER_DESC "NCI NFC driver for ST21NFCB"
+
+static int st21nfcb_nci_open(struct nci_dev *ndev)
+{
+ struct st21nfcb_nci_info *info = nci_get_drvdata(ndev);
+ int r;
+
+ if (test_and_set_bit(ST21NFCB_NCI_RUNNING, &info->flags))
+ return 0;
+
+ r = ndlc_open(info->ndlc);
+ if (r)
+ clear_bit(ST21NFCB_NCI_RUNNING, &info->flags);
+
+ return r;
+}
+
+static int st21nfcb_nci_close(struct nci_dev *ndev)
+{
+ struct st21nfcb_nci_info *info = nci_get_drvdata(ndev);
+
+ if (!test_and_clear_bit(ST21NFCB_NCI_RUNNING, &info->flags))
+ return 0;
+
+ ndlc_close(info->ndlc);
+
+ return 0;
+}
+
+static int st21nfcb_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+{
+ struct st21nfcb_nci_info *info = nci_get_drvdata(ndev);
+
+ skb->dev = (void *)ndev;
+
+ if (!test_bit(ST21NFCB_NCI_RUNNING, &info->flags))
+ return -EBUSY;
+
+ return ndlc_send(info->ndlc, skb);
+}
+
+static struct nci_ops st21nfcb_nci_ops = {
+ .open = st21nfcb_nci_open,
+ .close = st21nfcb_nci_close,
+ .send = st21nfcb_nci_send,
+};
+
+int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
+ int phy_tailroom)
+{
+ struct st21nfcb_nci_info *info;
+ int r;
+ u32 protocols;
+
+ info = devm_kzalloc(ndlc->dev,
+ sizeof(struct st21nfcb_nci_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ protocols = NFC_PROTO_JEWEL_MASK
+ | NFC_PROTO_MIFARE_MASK
+ | NFC_PROTO_FELICA_MASK
+ | NFC_PROTO_ISO14443_MASK
+ | NFC_PROTO_ISO14443_B_MASK
+ | NFC_PROTO_NFC_DEP_MASK;
+
+ ndlc->ndev = nci_allocate_device(&st21nfcb_nci_ops, protocols,
+ phy_headroom, phy_tailroom);
+ if (!ndlc->ndev) {
+ pr_err("Cannot allocate nfc ndev\n");
+ r = -ENOMEM;
+ goto err_alloc_ndev;
+ }
+ info->ndlc = ndlc;
+
+ nci_set_drvdata(ndlc->ndev, info);
+
+ r = nci_register_device(ndlc->ndev);
+ if (r)
+ goto err_regdev;
+
+ return r;
+err_regdev:
+ nci_free_device(ndlc->ndev);
+
+err_alloc_ndev:
+ kfree(info);
+ return r;
+}
+EXPORT_SYMBOL_GPL(st21nfcb_nci_probe);
+
+void st21nfcb_nci_remove(struct nci_dev *ndev)
+{
+ struct st21nfcb_nci_info *info = nci_get_drvdata(ndev);
+
+ nci_unregister_device(ndev);
+ nci_free_device(ndev);
+ kfree(info);
+}
+EXPORT_SYMBOL_GPL(st21nfcb_nci_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/nfc/st21nfcb/st21nfcb.h b/drivers/nfc/st21nfcb/st21nfcb.h
new file mode 100644
index 000000000000..4bbbebb9f34d
--- /dev/null
+++ b/drivers/nfc/st21nfcb/st21nfcb.h
@@ -0,0 +1,38 @@
+/*
+ * NCI based Driver for STMicroelectronics NFC Chip
+ *
+ * Copyright (C) 2014 STMicroelectronics SAS. 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. 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 __LOCAL_ST21NFCB_H_
+#define __LOCAL_ST21NFCB_H_
+
+#include <net/nfc/nci_core.h>
+
+#include "ndlc.h"
+
+/* Define private flags: */
+#define ST21NFCB_NCI_RUNNING 1
+
+struct st21nfcb_nci_info {
+ struct llt_ndlc *ndlc;
+ unsigned long flags;
+};
+
+void st21nfcb_nci_remove(struct nci_dev *ndev);
+int st21nfcb_nci_probe(struct llt_ndlc *ndlc, int phy_headroom,
+ int phy_tailroom);
+
+#endif /* __LOCAL_ST21NFCB_H_ */
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 5edfcb0da37d..e3718250d66e 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -702,6 +702,42 @@ void __iomem *of_iomap(struct device_node *np, int index)
}
EXPORT_SYMBOL(of_iomap);
+/*
+ * of_io_request_and_map - Requests a resource and maps the memory mapped IO
+ * for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ * @name: name of the resource
+ *
+ * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded
+ * error code on failure. Usage example:
+ *
+ * base = of_io_request_and_map(node, 0, "foo");
+ * if (IS_ERR(base))
+ * return PTR_ERR(base);
+ */
+void __iomem *of_io_request_and_map(struct device_node *np, int index,
+ char *name)
+{
+ struct resource res;
+ void __iomem *mem;
+
+ if (of_address_to_resource(np, index, &res))
+ return IOMEM_ERR_PTR(-EINVAL);
+
+ if (!request_mem_region(res.start, resource_size(&res), name))
+ return IOMEM_ERR_PTR(-EBUSY);
+
+ mem = ioremap(res.start, resource_size(&res));
+ if (!mem) {
+ release_mem_region(res.start, resource_size(&res));
+ return IOMEM_ERR_PTR(-ENOMEM);
+ }
+
+ return mem;
+}
+EXPORT_SYMBOL(of_io_request_and_map);
+
/**
* of_dma_get_range - Get DMA range info
* @np: device node to get DMA range info
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index c4cddf0cd96d..9aa012e6ea0a 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -26,6 +26,54 @@
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include <asm/page.h>
+/*
+ * of_fdt_limit_memory - limit the number of regions in the /memory node
+ * @limit: maximum entries
+ *
+ * Adjust the flattened device tree to have at most 'limit' number of
+ * memory entries in the /memory node. This function may be called
+ * any time after initial_boot_param is set.
+ */
+void of_fdt_limit_memory(int limit)
+{
+ int memory;
+ int len;
+ const void *val;
+ int nr_address_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+ int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+ const uint32_t *addr_prop;
+ const uint32_t *size_prop;
+ int root_offset;
+ int cell_size;
+
+ root_offset = fdt_path_offset(initial_boot_params, "/");
+ if (root_offset < 0)
+ return;
+
+ addr_prop = fdt_getprop(initial_boot_params, root_offset,
+ "#address-cells", NULL);
+ if (addr_prop)
+ nr_address_cells = fdt32_to_cpu(*addr_prop);
+
+ size_prop = fdt_getprop(initial_boot_params, root_offset,
+ "#size-cells", NULL);
+ if (size_prop)
+ nr_size_cells = fdt32_to_cpu(*size_prop);
+
+ cell_size = sizeof(uint32_t)*(nr_address_cells + nr_size_cells);
+
+ memory = fdt_path_offset(initial_boot_params, "/memory");
+ if (memory > 0) {
+ val = fdt_getprop(initial_boot_params, memory, "reg", &len);
+ if (len > limit*cell_size) {
+ len = limit*cell_size;
+ pr_debug("Limiting number of entries to %d\n", limit);
+ fdt_setprop(initial_boot_params, memory, "reg", val,
+ len);
+ }
+ }
+}
+
/**
* of_fdt_is_compatible - Return true if given node from the given blob has
* compat in its compatible list
@@ -880,6 +928,21 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
const u64 phys_offset = __pa(PAGE_OFFSET);
base &= PAGE_MASK;
size &= PAGE_MASK;
+
+ if (sizeof(phys_addr_t) < sizeof(u64)) {
+ if (base > ULONG_MAX) {
+ pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
+ base, base + size);
+ return;
+ }
+
+ if (base + size > ULONG_MAX) {
+ pr_warning("Ignoring memory range 0x%lx - 0x%llx\n",
+ ULONG_MAX, base + size);
+ size = ULONG_MAX - base;
+ }
+ }
+
if (base + size < phys_offset) {
pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
base, base + size);
@@ -922,7 +985,7 @@ int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
}
#endif
-bool __init early_init_dt_scan(void *params)
+bool __init early_init_dt_verify(void *params)
{
if (!params)
return false;
@@ -936,6 +999,12 @@ bool __init early_init_dt_scan(void *params)
return false;
}
+ return true;
+}
+
+
+void __init early_init_dt_scan_nodes(void)
+{
/* Retrieve various information from the /chosen node */
of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
@@ -944,7 +1013,17 @@ bool __init early_init_dt_scan(void *params)
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+}
+
+bool __init early_init_dt_scan(void *params)
+{
+ bool status;
+
+ status = early_init_dt_verify(params);
+ if (!status)
+ return false;
+ early_init_dt_scan_nodes();
return true;
}
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index a3bf2122a8d5..401b2453da45 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -182,40 +182,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
}
EXPORT_SYMBOL(of_mdiobus_register);
-/**
- * of_mdiobus_link_phydev - Find a device node for a phy
- * @mdio: pointer to mii_bus structure
- * @phydev: phydev for which the of_node pointer should be set
- *
- * Walk the list of subnodes of a mdio bus and look for a node that matches the
- * phy's address with its 'reg' property. If found, set the of_node pointer for
- * the phy. This allows auto-probed pyh devices to be supplied with information
- * passed in via DT.
- */
-void of_mdiobus_link_phydev(struct mii_bus *mdio,
- struct phy_device *phydev)
-{
- struct device *dev = &phydev->dev;
- struct device_node *child;
-
- if (dev->of_node || !mdio->dev.of_node)
- return;
-
- for_each_available_child_of_node(mdio->dev.of_node, child) {
- int addr;
-
- addr = of_mdio_parse_addr(&mdio->dev, child);
- if (addr < 0)
- continue;
-
- if (addr == phydev->addr) {
- dev->of_node = child;
- return;
- }
- }
-}
-EXPORT_SYMBOL(of_mdiobus_link_phydev);
-
/* Helper function for of_phy_find_device */
static int of_phy_match(struct device *dev, void *phy_np)
{
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 2872ece81f35..44333bd8f908 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -5,6 +5,12 @@
# Parport configuration.
#
+config ARCH_MIGHT_HAVE_PC_PARPORT
+ bool
+ help
+ Select this config option from the architecture Kconfig if
+ the architecture might have PC parallel port hardware.
+
menuconfig PARPORT
tristate "Parallel port support"
depends on HAS_IOMEM
@@ -31,12 +37,6 @@ menuconfig PARPORT
If unsure, say Y.
-config ARCH_MIGHT_HAVE_PC_PARPORT
- bool
- help
- Select this config option from the architecture Kconfig if
- the architecture might have PC parallel port hardware.
-
if PARPORT
config PARPORT_PC
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 44fe6aa6a43f..3d2076f59911 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -385,4 +385,4 @@ module_platform_driver(gen_pci_driver);
MODULE_DESCRIPTION("Generic PCI host driver");
MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index ce23e0f076b6..a8c6f1a92e0f 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -1094,4 +1094,4 @@ module_platform_driver(mvebu_pcie_driver);
MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
MODULE_DESCRIPTION("Marvell EBU PCIe driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index d697587dbb7c..abd65784618d 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -41,11 +41,12 @@
#include <linux/reset.h>
#include <linux/sizes.h>
#include <linux/slab.h>
-#include <linux/tegra-cpuidle.h>
-#include <linux/tegra-powergate.h>
#include <linux/vmalloc.h>
#include <linux/regulator/consumer.h>
+#include <soc/tegra/cpuidle.h>
+#include <soc/tegra/pmc.h>
+
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
@@ -1816,4 +1817,4 @@ module_platform_driver(tegra_pcie_driver);
MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra PCIe driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index f7d3de32c9a0..4884ee5e07d4 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -105,7 +105,7 @@
#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 19)
#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 16)
-#define PCI_MAX_RESOURCES 4
+#define RCAR_PCI_MAX_RESOURCES 4
#define MAX_NR_INBOUND_MAPS 6
struct rcar_msi {
@@ -127,7 +127,7 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_chip *chip)
struct rcar_pcie {
struct device *dev;
void __iomem *base;
- struct resource res[PCI_MAX_RESOURCES];
+ struct resource res[RCAR_PCI_MAX_RESOURCES];
struct resource busn;
int root_bus_nr;
struct clk *clk;
@@ -140,36 +140,37 @@ static inline struct rcar_pcie *sys_to_pcie(struct pci_sys_data *sys)
return sys->private_data;
}
-static void pci_write_reg(struct rcar_pcie *pcie, unsigned long val,
- unsigned long reg)
+static void rcar_pci_write_reg(struct rcar_pcie *pcie, unsigned long val,
+ unsigned long reg)
{
writel(val, pcie->base + reg);
}
-static unsigned long pci_read_reg(struct rcar_pcie *pcie, unsigned long reg)
+static unsigned long rcar_pci_read_reg(struct rcar_pcie *pcie,
+ unsigned long reg)
{
return readl(pcie->base + reg);
}
enum {
- PCI_ACCESS_READ,
- PCI_ACCESS_WRITE,
+ RCAR_PCI_ACCESS_READ,
+ RCAR_PCI_ACCESS_WRITE,
};
static void rcar_rmw32(struct rcar_pcie *pcie, int where, u32 mask, u32 data)
{
int shift = 8 * (where & 3);
- u32 val = pci_read_reg(pcie, where & ~3);
+ u32 val = rcar_pci_read_reg(pcie, where & ~3);
val &= ~(mask << shift);
val |= data << shift;
- pci_write_reg(pcie, val, where & ~3);
+ rcar_pci_write_reg(pcie, val, where & ~3);
}
static u32 rcar_read_conf(struct rcar_pcie *pcie, int where)
{
int shift = 8 * (where & 3);
- u32 val = pci_read_reg(pcie, where & ~3);
+ u32 val = rcar_pci_read_reg(pcie, where & ~3);
return val >> shift;
}
@@ -205,14 +206,14 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
if (dev != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
- if (access_type == PCI_ACCESS_READ) {
- *data = pci_read_reg(pcie, PCICONF(index));
+ if (access_type == RCAR_PCI_ACCESS_READ) {
+ *data = rcar_pci_read_reg(pcie, PCICONF(index));
} else {
/* Keep an eye out for changes to the root bus number */
if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS))
pcie->root_bus_nr = *data & 0xff;
- pci_write_reg(pcie, *data, PCICONF(index));
+ rcar_pci_write_reg(pcie, *data, PCICONF(index));
}
return PCIBIOS_SUCCESSFUL;
@@ -222,20 +223,20 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
return PCIBIOS_DEVICE_NOT_FOUND;
/* Clear errors */
- pci_write_reg(pcie, pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
+ rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
/* Set the PIO address */
- pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) | PCIE_CONF_DEV(dev) |
- PCIE_CONF_FUNC(func) | reg, PCIECAR);
+ rcar_pci_write_reg(pcie, PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
/* Enable the configuration access */
if (bus->parent->number == pcie->root_bus_nr)
- pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
+ rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
else
- pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
+ rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
/* Check for errors */
- if (pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
+ if (rcar_pci_read_reg(pcie, PCIEERRFR) & UNSUPPORTED_REQUEST)
return PCIBIOS_DEVICE_NOT_FOUND;
/* Check for master and target aborts */
@@ -243,13 +244,13 @@ static int rcar_pcie_config_access(struct rcar_pcie *pcie,
(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT))
return PCIBIOS_DEVICE_NOT_FOUND;
- if (access_type == PCI_ACCESS_READ)
- *data = pci_read_reg(pcie, PCIECDR);
+ if (access_type == RCAR_PCI_ACCESS_READ)
+ *data = rcar_pci_read_reg(pcie, PCIECDR);
else
- pci_write_reg(pcie, *data, PCIECDR);
+ rcar_pci_write_reg(pcie, *data, PCIECDR);
/* Disable the configuration access */
- pci_write_reg(pcie, 0, PCIECCTLR);
+ rcar_pci_write_reg(pcie, 0, PCIECCTLR);
return PCIBIOS_SUCCESSFUL;
}
@@ -260,12 +261,7 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
struct rcar_pcie *pcie = sys_to_pcie(bus->sysdata);
int ret;
- if ((size == 2) && (where & 1))
- return PCIBIOS_BAD_REGISTER_NUMBER;
- else if ((size == 4) && (where & 3))
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- ret = rcar_pcie_config_access(pcie, PCI_ACCESS_READ,
+ ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ,
bus, devfn, where, val);
if (ret != PCIBIOS_SUCCESSFUL) {
*val = 0xffffffff;
@@ -291,12 +287,7 @@ static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
int shift, ret;
u32 data;
- if ((size == 2) && (where & 1))
- return PCIBIOS_BAD_REGISTER_NUMBER;
- else if ((size == 4) && (where & 3))
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- ret = rcar_pcie_config_access(pcie, PCI_ACCESS_READ,
+ ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ,
bus, devfn, where, &data);
if (ret != PCIBIOS_SUCCESSFUL)
return ret;
@@ -315,7 +306,7 @@ static int rcar_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
} else
data = val;
- ret = rcar_pcie_config_access(pcie, PCI_ACCESS_WRITE,
+ ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_WRITE,
bus, devfn, where, &data);
return ret;
@@ -326,14 +317,15 @@ static struct pci_ops rcar_pcie_ops = {
.write = rcar_pcie_write_conf,
};
-static void rcar_pcie_setup_window(int win, struct resource *res,
- struct rcar_pcie *pcie)
+static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie)
{
+ struct resource *res = &pcie->res[win];
+
/* Setup PCIe address space mappings for each resource */
resource_size_t size;
u32 mask;
- pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
+ rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win));
/*
* The PAMR mask is calculated in units of 128Bytes, which
@@ -341,17 +333,17 @@ static void rcar_pcie_setup_window(int win, struct resource *res,
*/
size = resource_size(res);
mask = (roundup_pow_of_two(size) / SZ_128) - 1;
- pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
+ rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win));
- pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
- pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
+ rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win));
+ rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win));
/* First resource is for IO */
mask = PAR_ENABLE;
if (res->flags & IORESOURCE_IO)
mask |= IO_SPACE;
- pci_write_reg(pcie, mask, PCIEPTCTLR(win));
+ rcar_pci_write_reg(pcie, mask, PCIEPTCTLR(win));
}
static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
@@ -363,13 +355,13 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
pcie->root_bus_nr = -1;
/* Setup PCI resources */
- for (i = 0; i < PCI_MAX_RESOURCES; i++) {
+ for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
res = &pcie->res[i];
if (!res->flags)
continue;
- rcar_pcie_setup_window(i, res, pcie);
+ rcar_pcie_setup_window(i, pcie);
if (res->flags & IORESOURCE_IO)
pci_ioremap_io(nr * SZ_64K, res->start);
@@ -415,7 +407,7 @@ static int phy_wait_for_ack(struct rcar_pcie *pcie)
unsigned int timeout = 100;
while (timeout--) {
- if (pci_read_reg(pcie, H1_PCIEPHYADRR) & PHY_ACK)
+ if (rcar_pci_read_reg(pcie, H1_PCIEPHYADRR) & PHY_ACK)
return 0;
udelay(100);
@@ -438,15 +430,15 @@ static void phy_write_reg(struct rcar_pcie *pcie,
((addr & 0xff) << ADR_POS);
/* Set write data */
- pci_write_reg(pcie, data, H1_PCIEPHYDOUTR);
- pci_write_reg(pcie, phyaddr, H1_PCIEPHYADRR);
+ rcar_pci_write_reg(pcie, data, H1_PCIEPHYDOUTR);
+ rcar_pci_write_reg(pcie, phyaddr, H1_PCIEPHYADRR);
/* Ignore errors as they will be dealt with if the data link is down */
phy_wait_for_ack(pcie);
/* Clear command */
- pci_write_reg(pcie, 0, H1_PCIEPHYDOUTR);
- pci_write_reg(pcie, 0, H1_PCIEPHYADRR);
+ rcar_pci_write_reg(pcie, 0, H1_PCIEPHYDOUTR);
+ rcar_pci_write_reg(pcie, 0, H1_PCIEPHYADRR);
/* Ignore errors as they will be dealt with if the data link is down */
phy_wait_for_ack(pcie);
@@ -457,7 +449,7 @@ static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie)
unsigned int timeout = 10;
while (timeout--) {
- if ((pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE))
+ if ((rcar_pci_read_reg(pcie, PCIETSTR) & DATA_LINK_ACTIVE))
return 0;
msleep(5);
@@ -471,17 +463,17 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
int err;
/* Begin initialization */
- pci_write_reg(pcie, 0, PCIETCTLR);
+ rcar_pci_write_reg(pcie, 0, PCIETCTLR);
/* Set mode */
- pci_write_reg(pcie, 1, PCIEMSR);
+ rcar_pci_write_reg(pcie, 1, PCIEMSR);
/*
* Initial header for port config space is type 1, set the device
* class to match. Hardware takes care of propagating the IDSETR
* settings, so there is no need to bother with a quirk.
*/
- pci_write_reg(pcie, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
+ rcar_pci_write_reg(pcie, PCI_CLASS_BRIDGE_PCI << 16, IDSETR1);
/*
* Setup Secondary Bus Number & Subordinate Bus Number, even though
@@ -491,33 +483,31 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
rcar_rmw32(pcie, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);
/* Initialize default capabilities. */
- rcar_rmw32(pcie, REXPCAP(0), 0, PCI_CAP_ID_EXP);
+ rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
PCI_HEADER_TYPE_BRIDGE);
/* Enable data link layer active state reporting */
- rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP), 0, PCI_EXP_LNKCAP_DLLLARC);
+ rcar_rmw32(pcie, REXPCAP(PCI_EXP_LNKCAP), PCI_EXP_LNKCAP_DLLLARC,
+ PCI_EXP_LNKCAP_DLLLARC);
/* Write out the physical slot number = 0 */
rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);
/* Set the completion timer timeout to the maximum 50ms. */
- rcar_rmw32(pcie, TLCTLR+1, 0x3f, 50);
+ rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);
/* Terminate list of capabilities (Next Capability Offset=0) */
- rcar_rmw32(pcie, RVCCAP(0), 0xfff0, 0);
-
- /* Enable MAC data scrambling. */
- rcar_rmw32(pcie, MACCTLR, SCRAMBLE_DISABLE, 0);
+ rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);
/* Enable MSI */
if (IS_ENABLED(CONFIG_PCI_MSI))
- pci_write_reg(pcie, 0x101f0000, PCIEMSITXR);
+ rcar_pci_write_reg(pcie, 0x101f0000, PCIEMSITXR);
/* Finish initialization - establish a PCI Express link */
- pci_write_reg(pcie, CFINIT, PCIETCTLR);
+ rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR);
/* This will timeout if we don't have a link. */
err = rcar_pcie_wait_for_dl(pcie);
@@ -527,11 +517,6 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
/* Enable INTx interrupts */
rcar_rmw32(pcie, PCIEINTXR, 0, 0xF << 8);
- /* Enable slave Bus Mastering */
- rcar_rmw32(pcie, RCONF(PCI_STATUS), PCI_STATUS_DEVSEL_MASK,
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST);
-
wmb();
return 0;
@@ -560,7 +545,7 @@ static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie)
phy_write_reg(pcie, 0, 0x66, 0x1, 0x00008000);
while (timeout--) {
- if (pci_read_reg(pcie, H1_PCIEPHYSR))
+ if (rcar_pci_read_reg(pcie, H1_PCIEPHYSR))
return rcar_pcie_hw_init(pcie);
msleep(5);
@@ -599,7 +584,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
struct rcar_msi *msi = &pcie->msi;
unsigned long reg;
- reg = pci_read_reg(pcie, PCIEMSIFR);
+ reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
/* MSI & INTx share an interrupt - we only handle MSI here */
if (!reg)
@@ -610,7 +595,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
unsigned int irq;
/* clear the interrupt */
- pci_write_reg(pcie, 1 << index, PCIEMSIFR);
+ rcar_pci_write_reg(pcie, 1 << index, PCIEMSIFR);
irq = irq_find_mapping(msi->domain, index);
if (irq) {
@@ -624,7 +609,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
}
/* see if there's any more pending in this vector */
- reg = pci_read_reg(pcie, PCIEMSIFR);
+ reg = rcar_pci_read_reg(pcie, PCIEMSIFR);
}
return IRQ_HANDLED;
@@ -651,8 +636,8 @@ static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
irq_set_msi_desc(irq, desc);
- msg.address_lo = pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
- msg.address_hi = pci_read_reg(pcie, PCIEMSIAUR);
+ msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
+ msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
msg.data = hwirq;
write_msi_msg(irq, &msg);
@@ -729,11 +714,11 @@ static int rcar_pcie_enable_msi(struct rcar_pcie *pcie)
msi->pages = __get_free_pages(GFP_KERNEL, 0);
base = virt_to_phys((void *)msi->pages);
- pci_write_reg(pcie, base | MSIFE, PCIEMSIALR);
- pci_write_reg(pcie, 0, PCIEMSIAUR);
+ rcar_pci_write_reg(pcie, base | MSIFE, PCIEMSIALR);
+ rcar_pci_write_reg(pcie, 0, PCIEMSIAUR);
/* enable all MSI interrupts */
- pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
+ rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
return 0;
@@ -826,6 +811,7 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
if (cpu_addr > 0) {
unsigned long nr_zeros = __ffs64(cpu_addr);
u64 alignment = 1ULL << nr_zeros;
+
size = min(range->size, alignment);
} else {
size = range->size;
@@ -841,13 +827,13 @@ static int rcar_pcie_inbound_ranges(struct rcar_pcie *pcie,
* Set up 64-bit inbound regions as the range parser doesn't
* distinguish between 32 and 64-bit types.
*/
- pci_write_reg(pcie, lower_32_bits(pci_addr), PCIEPRAR(idx));
- pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
- pci_write_reg(pcie, lower_32_bits(mask) | flags, PCIELAMR(idx));
+ rcar_pci_write_reg(pcie, lower_32_bits(pci_addr), PCIEPRAR(idx));
+ rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
+ rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags, PCIELAMR(idx));
- pci_write_reg(pcie, upper_32_bits(pci_addr), PCIEPRAR(idx+1));
- pci_write_reg(pcie, upper_32_bits(cpu_addr), PCIELAR(idx+1));
- pci_write_reg(pcie, 0, PCIELAMR(idx+1));
+ rcar_pci_write_reg(pcie, upper_32_bits(pci_addr), PCIEPRAR(idx+1));
+ rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr), PCIELAR(idx+1));
+ rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
pci_addr += size;
cpu_addr += size;
@@ -952,7 +938,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
of_pci_range_to_resource(&range, pdev->dev.of_node,
&pcie->res[win++]);
- if (win > PCI_MAX_RESOURCES)
+ if (win > RCAR_PCI_MAX_RESOURCES)
break;
}
@@ -982,7 +968,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
return 0;
}
- data = pci_read_reg(pcie, MACSR);
+ data = rcar_pci_read_reg(pcie, MACSR);
dev_info(&pdev->dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f);
rcar_pcie_enable(pcie);
@@ -1003,4 +989,4 @@ module_platform_driver(rcar_pcie_driver);
MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>");
MODULE_DESCRIPTION("Renesas R-Car PCIe driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 602d153c7055..70741c8c46a0 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -80,8 +80,9 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
return NULL;
context->refcount = 1;
- acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL,
- acpiphp_post_dock_fixup);
+ context->hp.notify = acpiphp_hotplug_notify;
+ context->hp.fixup = acpiphp_post_dock_fixup;
+ acpi_set_hp_context(adev, &context->hp);
return context;
}
@@ -369,20 +370,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
return AE_OK;
}
-static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev)
-{
- struct acpiphp_bridge *bridge = NULL;
-
- acpi_lock_hp_context();
- if (adev->hp) {
- bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
- if (bridge)
- get_bridge(bridge);
- }
- acpi_unlock_hp_context();
- return bridge;
-}
-
static void cleanup_bridge(struct acpiphp_bridge *bridge)
{
struct acpiphp_slot *slot;
@@ -753,9 +740,15 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
void acpiphp_check_host_bridge(struct acpi_device *adev)
{
- struct acpiphp_bridge *bridge;
+ struct acpiphp_bridge *bridge = NULL;
- bridge = acpiphp_dev_to_bridge(adev);
+ acpi_lock_hp_context();
+ if (adev->hp) {
+ bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
+ if (bridge)
+ get_bridge(bridge);
+ }
+ acpi_unlock_hp_context();
if (bridge) {
pci_lock_rescan_remove();
@@ -884,7 +877,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
goto err;
root_context->root_bridge = bridge;
- acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL);
+ acpi_set_hp_context(adev, &root_context->hp);
} else {
struct acpiphp_context *context;
@@ -927,7 +920,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
kfree(bridge);
}
-void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
+static void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
{
if (pci_is_root_bus(bridge->pci_bus)) {
struct acpiphp_root_context *root_context;
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 4a392c44e3d3..d81648f71425 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -216,8 +216,7 @@ void cpqhp_create_debugfs_files(struct controller *ctrl)
void cpqhp_remove_debugfs_files(struct controller *ctrl)
{
- if (ctrl->dentry)
- debugfs_remove(ctrl->dentry);
+ debugfs_remove(ctrl->dentry);
ctrl->dentry = NULL;
}
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 8e9012dca450..9e5a9fbb93d7 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -92,9 +92,10 @@ struct controller {
struct slot *slot;
wait_queue_head_t queue; /* sleep & wake process */
u32 slot_cap;
+ u32 slot_ctrl;
struct timer_list poll_timer;
+ unsigned long cmd_started; /* jiffies */
unsigned int cmd_busy:1;
- unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
unsigned int notification_enabled:1;
unsigned int power_fault_detected;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index a2297db80813..07aa722bb12c 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -255,6 +255,13 @@ static int pciehp_probe(struct pcie_device *dev)
else if (pciehp_acpi_slot_detection_check(dev->port))
goto err_out_none;
+ if (!dev->port->subordinate) {
+ /* Can happen if we run out of bus numbers during probe */
+ dev_err(&dev->device,
+ "Hotplug bridge without secondary bus, ignoring\n");
+ goto err_out_none;
+ }
+
ctrl = pcie_init(dev);
if (!ctrl) {
dev_err(&dev->device, "Controller initialization failed\n");
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 42914e04d110..9da84b8b27d8 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -104,11 +104,10 @@ static inline void pciehp_free_irq(struct controller *ctrl)
free_irq(ctrl->pcie->irq, ctrl);
}
-static int pcie_poll_cmd(struct controller *ctrl)
+static int pcie_poll_cmd(struct controller *ctrl, int timeout)
{
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_status;
- int timeout = 1000;
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
if (slot_status & PCI_EXP_SLTSTA_CC) {
@@ -129,18 +128,52 @@ static int pcie_poll_cmd(struct controller *ctrl)
return 0; /* timeout */
}
-static void pcie_wait_cmd(struct controller *ctrl, int poll)
+static void pcie_wait_cmd(struct controller *ctrl)
{
unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
- unsigned long timeout = msecs_to_jiffies(msecs);
+ unsigned long duration = msecs_to_jiffies(msecs);
+ unsigned long cmd_timeout = ctrl->cmd_started + duration;
+ unsigned long now, timeout;
int rc;
- if (poll)
- rc = pcie_poll_cmd(ctrl);
+ /*
+ * If the controller does not generate notifications for command
+ * completions, we never need to wait between writes.
+ */
+ if (NO_CMD_CMPL(ctrl))
+ return;
+
+ if (!ctrl->cmd_busy)
+ return;
+
+ /*
+ * Even if the command has already timed out, we want to call
+ * pcie_poll_cmd() so it can clear PCI_EXP_SLTSTA_CC.
+ */
+ now = jiffies;
+ if (time_before_eq(cmd_timeout, now))
+ timeout = 1;
else
+ timeout = cmd_timeout - now;
+
+ if (ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE &&
+ ctrl->slot_ctrl & PCI_EXP_SLTCTL_CCIE)
rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
+ else
+ rc = pcie_poll_cmd(ctrl, timeout);
+
+ /*
+ * Controllers with errata like Intel CF118 don't generate
+ * completion notifications unless the power/indicator/interlock
+ * control bits are changed. On such controllers, we'll emit this
+ * timeout message when we wait for completion of commands that
+ * don't change those bits, e.g., commands that merely enable
+ * interrupts.
+ */
if (!rc)
- ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
+ ctrl_info(ctrl, "Timeout on hotplug command %#010x (issued %u msec ago)\n",
+ ctrl->slot_ctrl,
+ jiffies_to_msecs(now - ctrl->cmd_started));
}
/**
@@ -152,34 +185,12 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll)
static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
{
struct pci_dev *pdev = ctrl_dev(ctrl);
- u16 slot_status;
u16 slot_ctrl;
mutex_lock(&ctrl->ctrl_lock);
- pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
- if (slot_status & PCI_EXP_SLTSTA_CC) {
- pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
- PCI_EXP_SLTSTA_CC);
- if (!ctrl->no_cmd_complete) {
- /*
- * After 1 sec and CMD_COMPLETED still not set, just
- * proceed forward to issue the next command according
- * to spec. Just print out the error message.
- */
- ctrl_dbg(ctrl, "CMD_COMPLETED not clear after 1 sec\n");
- } else if (!NO_CMD_CMPL(ctrl)) {
- /*
- * This controller seems to notify of command completed
- * event even though it supports none of power
- * controller, attention led, power led and EMI.
- */
- ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Need to wait for command completed event\n");
- ctrl->no_cmd_complete = 0;
- } else {
- ctrl_dbg(ctrl, "Unexpected CMD_COMPLETED. Maybe the controller is broken\n");
- }
- }
+ /* Wait for any previous command that might still be in progress */
+ pcie_wait_cmd(ctrl);
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
slot_ctrl &= ~mask;
@@ -187,22 +198,9 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
ctrl->cmd_busy = 1;
smp_mb();
pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
+ ctrl->cmd_started = jiffies;
+ ctrl->slot_ctrl = slot_ctrl;
- /*
- * Wait for command completion.
- */
- if (!ctrl->no_cmd_complete) {
- int poll = 0;
- /*
- * if hotplug interrupt is not enabled or command
- * completed interrupt is not enabled, we need to poll
- * command completed event.
- */
- if (!(slot_ctrl & PCI_EXP_SLTCTL_HPIE) ||
- !(slot_ctrl & PCI_EXP_SLTCTL_CCIE))
- poll = 1;
- pcie_wait_cmd(ctrl, poll);
- }
mutex_unlock(&ctrl->ctrl_lock);
}
@@ -773,15 +771,6 @@ struct controller *pcie_init(struct pcie_device *dev)
mutex_init(&ctrl->ctrl_lock);
init_waitqueue_head(&ctrl->queue);
dbg_ctrl(ctrl);
- /*
- * Controller doesn't notify of command completion if the "No
- * Command Completed Support" bit is set in Slot Capability
- * register or the controller supports none of power
- * controller, attention led, power led and EMI.
- */
- if (NO_CMD_CMPL(ctrl) ||
- !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl)))
- ctrl->no_cmd_complete = 1;
/* Check if Data Link Layer Link Active Reporting is implemented */
pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap);
@@ -794,7 +783,7 @@ struct controller *pcie_init(struct pcie_device *dev)
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
- PCI_EXP_SLTSTA_CC);
+ PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);
/* Disable software notification */
pcie_disable_notification(ctrl);
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index d1332d2f8730..d77e46bca54c 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -7,8 +7,8 @@
* Jan Glauber <jang@linux.vnet.ibm.com>
*/
-#define COMPONENT "zPCI hpc"
-#define pr_fmt(fmt) COMPONENT ": " fmt
+#define KMSG_COMPONENT "zpci"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 13f3d3037272..5a40516444f3 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -149,15 +149,14 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
}
-static void msix_set_enable(struct pci_dev *dev, int enable)
+static void msix_clear_and_set_ctrl(struct pci_dev *dev, u16 clear, u16 set)
{
- u16 control;
+ u16 ctrl;
- pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
- control &= ~PCI_MSIX_FLAGS_ENABLE;
- if (enable)
- control |= PCI_MSIX_FLAGS_ENABLE;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &ctrl);
+ ctrl &= ~clear;
+ ctrl |= set;
+ pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, ctrl);
}
static inline __attribute_const__ u32 msi_mask(unsigned x)
@@ -168,16 +167,6 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
return (1 << (1 << x)) - 1;
}
-static inline __attribute_const__ u32 msi_capable_mask(u16 control)
-{
- return msi_mask((control >> 1) & 7);
-}
-
-static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
-{
- return msi_mask((control >> 4) & 7);
-}
-
/*
* PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to
* mask all MSI interrupts by clearing the MSI enable bit does not work
@@ -246,7 +235,7 @@ static void msi_set_mask_bit(struct irq_data *data, u32 flag)
msix_mask_irq(desc, flag);
readl(desc->mask_base); /* Flush write to device */
} else {
- unsigned offset = data->irq - desc->dev->irq;
+ unsigned offset = data->irq - desc->irq;
msi_mask_irq(desc, 1 << offset, flag << offset);
}
}
@@ -460,7 +449,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
arch_restore_msi_irqs(dev);
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
- msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
+ msi_mask_irq(entry, msi_mask(entry->msi_attrib.multi_cap),
+ entry->masked);
control &= ~PCI_MSI_FLAGS_QSIZE;
control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE;
pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
@@ -469,26 +459,22 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
static void __pci_restore_msix_state(struct pci_dev *dev)
{
struct msi_desc *entry;
- u16 control;
if (!dev->msix_enabled)
return;
BUG_ON(list_empty(&dev->msi_list));
- entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
- pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
/* route the table */
pci_intx_for_msi(dev, 0);
- control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ msix_clear_and_set_ctrl(dev, 0,
+ PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);
arch_restore_msi_irqs(dev);
list_for_each_entry(entry, &dev->msi_list, list) {
msix_mask_irq(entry, entry->masked);
}
- control &= ~PCI_MSIX_FLAGS_MASKALL;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
}
void pci_restore_msi_state(struct pci_dev *dev)
@@ -501,7 +487,6 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state);
static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *entry;
unsigned long irq;
int retval;
@@ -510,12 +495,11 @@ static ssize_t msi_mode_show(struct device *dev, struct device_attribute *attr,
if (retval)
return retval;
- list_for_each_entry(entry, &pdev->msi_list, list) {
- if (entry->irq == irq) {
- return sprintf(buf, "%s\n",
- entry->msi_attrib.is_msix ? "msix" : "msi");
- }
- }
+ entry = irq_get_msi_desc(irq);
+ if (entry)
+ return sprintf(buf, "%s\n",
+ entry->msi_attrib.is_msix ? "msix" : "msi");
+
return -ENODEV;
}
@@ -594,6 +578,38 @@ error_attrs:
return ret;
}
+static struct msi_desc *msi_setup_entry(struct pci_dev *dev)
+{
+ u16 control;
+ struct msi_desc *entry;
+
+ /* MSI Entry Initialization */
+ entry = alloc_msi_entry(dev);
+ if (!entry)
+ return NULL;
+
+ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
+
+ entry->msi_attrib.is_msix = 0;
+ entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT);
+ entry->msi_attrib.entry_nr = 0;
+ entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT);
+ entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
+ entry->msi_attrib.pos = dev->msi_cap;
+ entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1;
+
+ if (control & PCI_MSI_FLAGS_64BIT)
+ entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64;
+ else
+ entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_32;
+
+ /* Save the initial mask status */
+ if (entry->msi_attrib.maskbit)
+ pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
+
+ return entry;
+}
+
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
@@ -609,32 +625,16 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
{
struct msi_desc *entry;
int ret;
- u16 control;
unsigned mask;
msi_set_enable(dev, 0); /* Disable MSI during set up */
- pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
- /* MSI Entry Initialization */
- entry = alloc_msi_entry(dev);
+ entry = msi_setup_entry(dev);
if (!entry)
return -ENOMEM;
- entry->msi_attrib.is_msix = 0;
- entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT);
- entry->msi_attrib.entry_nr = 0;
- entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT);
- entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
- entry->msi_attrib.pos = dev->msi_cap;
-
- if (control & PCI_MSI_FLAGS_64BIT)
- entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_64;
- else
- entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_32;
/* All MSIs are unmasked by default, Mask them all */
- if (entry->msi_attrib.maskbit)
- pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
- mask = msi_capable_mask(control);
+ mask = msi_mask(entry->msi_attrib.multi_cap);
msi_mask_irq(entry, mask, mask);
list_add_tail(&entry->list, &dev->msi_list);
@@ -743,12 +743,10 @@ static int msix_capability_init(struct pci_dev *dev,
u16 control;
void __iomem *base;
- pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
-
/* Ensure MSI-X is disabled while it is set up */
- control &= ~PCI_MSIX_FLAGS_ENABLE;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
+ pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
/* Request & Map MSI-X table region */
base = msix_map_region(dev, msix_table_size(control));
if (!base)
@@ -767,8 +765,8 @@ static int msix_capability_init(struct pci_dev *dev,
* MSI-X registers. We need to mask all the vectors to prevent
* interrupts coming in before they're fully set up.
*/
- control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ msix_clear_and_set_ctrl(dev, 0,
+ PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE);
msix_program_entries(dev, entries);
@@ -780,8 +778,7 @@ static int msix_capability_init(struct pci_dev *dev,
pci_intx_for_msi(dev, 0);
dev->msix_enabled = 1;
- control &= ~PCI_MSIX_FLAGS_MASKALL;
- pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control);
+ msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
return 0;
@@ -882,7 +879,6 @@ void pci_msi_shutdown(struct pci_dev *dev)
{
struct msi_desc *desc;
u32 mask;
- u16 ctrl;
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;
@@ -895,8 +891,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
dev->msi_enabled = 0;
/* Return the device with MSI unmasked as initial states */
- pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl);
- mask = msi_capable_mask(ctrl);
+ mask = msi_mask(desc->msi_attrib.multi_cap);
/* Keep cached state to be restored */
arch_msi_mask_irq(desc, mask, ~mask);
@@ -1001,7 +996,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
arch_msix_mask_irq(entry, 1);
}
- msix_set_enable(dev, 0);
+ msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
pci_intx_for_msi(dev, 1);
dev->msix_enabled = 0;
}
@@ -1016,24 +1011,6 @@ void pci_disable_msix(struct pci_dev *dev)
}
EXPORT_SYMBOL(pci_disable_msix);
-/**
- * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state
- * @dev: pointer to the pci_dev data structure of MSI(X) device function
- *
- * Being called during hotplug remove, from which the device function
- * is hot-removed. All previous assigned MSI/MSI-X irqs, if
- * allocated for this device function, are reclaimed to unused state,
- * which may be used later on.
- **/
-void msi_remove_pci_irq_vectors(struct pci_dev *dev)
-{
- if (!pci_msi_enable || !dev)
- return;
-
- if (dev->msi_enabled || dev->msix_enabled)
- free_msi_irqs(dev);
-}
-
void pci_no_msi(void)
{
pci_msi_enable = 0;
@@ -1065,7 +1042,7 @@ void pci_msi_init_pci_dev(struct pci_dev *dev)
dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX);
if (dev->msix_cap)
- msix_set_enable(dev, 0);
+ msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
}
/**
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index ca4927ba8433..37263b0ebfe3 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -18,31 +18,31 @@
#include "pci.h"
/**
- * pci_acpi_wake_bus - Wake-up notification handler for root buses.
- * @handle: ACPI handle of a device the notification is for.
- * @event: Type of the signaled event.
- * @context: PCI root bus to wake up devices on.
+ * pci_acpi_wake_bus - Root bus wakeup notification fork function.
+ * @work: Work item to handle.
*/
-static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context)
+static void pci_acpi_wake_bus(struct work_struct *work)
{
- struct pci_bus *pci_bus = context;
+ struct acpi_device *adev;
+ struct acpi_pci_root *root;
- if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus)
- pci_pme_wakeup_bus(pci_bus);
+ adev = container_of(work, struct acpi_device, wakeup.context.work);
+ root = acpi_driver_data(adev);
+ pci_pme_wakeup_bus(root->bus);
}
/**
- * pci_acpi_wake_dev - Wake-up notification handler for PCI devices.
+ * pci_acpi_wake_dev - PCI device wakeup notification work function.
* @handle: ACPI handle of a device the notification is for.
- * @event: Type of the signaled event.
- * @context: PCI device object to wake up.
+ * @work: Work item to handle.
*/
-static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
+static void pci_acpi_wake_dev(struct work_struct *work)
{
- struct pci_dev *pci_dev = context;
+ struct acpi_device_wakeup_context *context;
+ struct pci_dev *pci_dev;
- if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev)
- return;
+ context = container_of(work, struct acpi_device_wakeup_context, work);
+ pci_dev = to_pci_dev(context->dev);
if (pci_dev->pme_poll)
pci_dev->pme_poll = false;
@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
}
/**
- * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus.
- * @dev: ACPI device to add the notifier for.
- * @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
- */
-acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
- struct pci_bus *pci_bus)
-{
- return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
-}
-
-/**
- * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier.
- * @dev: ACPI device to remove the notifier from.
+ * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus.
+ * @dev: PCI root bridge ACPI device.
*/
-acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
+acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev)
{
- return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus);
+ return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus);
}
/**
@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
struct pci_dev *pci_dev)
{
- return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
-}
-
-/**
- * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier.
- * @dev: ACPI device to remove the notifier from.
- */
-acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
-{
- return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev);
+ return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev);
}
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
@@ -170,14 +150,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
static bool acpi_pci_power_manageable(struct pci_dev *dev)
{
- acpi_handle handle = ACPI_HANDLE(&dev->dev);
-
- return handle ? acpi_bus_power_manageable(handle) : false;
+ struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+ return adev ? acpi_device_power_manageable(adev) : false;
}
static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
- acpi_handle handle = ACPI_HANDLE(&dev->dev);
+ struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
static const u8 state_conv[] = {
[PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1,
@@ -188,7 +167,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
int error = -EINVAL;
/* If the ACPI device has _EJ0, ignore the device */
- if (!handle || acpi_has_method(handle, "_EJ0"))
+ if (!adev || acpi_has_method(adev->handle, "_EJ0"))
return -ENODEV;
switch (state) {
@@ -202,7 +181,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
case PCI_D1:
case PCI_D2:
case PCI_D3hot:
- error = acpi_bus_set_power(handle, state_conv[state]);
+ error = acpi_device_set_power(adev, state_conv[state]);
}
if (!error)
@@ -214,9 +193,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
static bool acpi_pci_can_wakeup(struct pci_dev *dev)
{
- acpi_handle handle = ACPI_HANDLE(&dev->dev);
-
- return handle ? acpi_bus_can_wakeup(handle) : false;
+ struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+ return adev ? acpi_device_can_wakeup(adev) : false;
}
static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3f8e3dbcaa7c..d04c5adafc16 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -582,7 +582,7 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: Device state not saved by %pF\n",
drv->suspend_late);
- return 0;
+ goto Fixup;
}
}
@@ -591,6 +591,9 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
pci_pm_set_unknown_state(pci_dev);
+Fixup:
+ pci_fixup_device(pci_fixup_suspend_late, pci_dev);
+
return 0;
}
@@ -734,7 +737,7 @@ static int pci_pm_suspend_noirq(struct device *dev)
if (!pm) {
pci_save_state(pci_dev);
- return 0;
+ goto Fixup;
}
if (pm->suspend_noirq) {
@@ -751,7 +754,7 @@ static int pci_pm_suspend_noirq(struct device *dev)
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: State of device not saved by %pF\n",
pm->suspend_noirq);
- return 0;
+ goto Fixup;
}
}
@@ -775,6 +778,9 @@ static int pci_pm_suspend_noirq(struct device *dev)
if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
pci_write_config_word(pci_dev, PCI_COMMAND, 0);
+Fixup:
+ pci_fixup_device(pci_fixup_suspend_late, pci_dev);
+
return 0;
}
@@ -999,8 +1005,10 @@ static int pci_pm_poweroff_noirq(struct device *dev)
if (pci_has_legacy_pm_support(to_pci_dev(dev)))
return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
- if (!drv || !drv->pm)
+ if (!drv || !drv->pm) {
+ pci_fixup_device(pci_fixup_suspend_late, pci_dev);
return 0;
+ }
if (drv->pm->poweroff_noirq) {
int error;
@@ -1021,6 +1029,8 @@ static int pci_pm_poweroff_noirq(struct device *dev)
if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
pci_write_config_word(pci_dev, PCI_COMMAND, 0);
+ pci_fixup_device(pci_fixup_suspend_late, pci_dev);
+
if (pcibios_pm_ops.poweroff_noirq)
return pcibios_pm_ops.poweroff_noirq(dev);
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
index a3fbe2012ea3..2ab1b47c7651 100644
--- a/drivers/pci/pci-label.c
+++ b/drivers/pci/pci-label.c
@@ -161,8 +161,8 @@ enum acpi_attr_enum {
static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
{
int len;
- len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer,
- obj->string.length,
+ len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer,
+ obj->buffer.length,
UTF16_LITTLE_ENDIAN,
buf, PAGE_SIZE);
buf[len] = '\n';
@@ -187,16 +187,22 @@ static int dsm_get_label(struct device *dev, char *buf,
tmp = obj->package.elements;
if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 &&
tmp[0].type == ACPI_TYPE_INTEGER &&
- tmp[1].type == ACPI_TYPE_STRING) {
+ (tmp[1].type == ACPI_TYPE_STRING ||
+ tmp[1].type == ACPI_TYPE_BUFFER)) {
/*
* The second string element is optional even when
* this _DSM is implemented; when not implemented,
* this entry must return a null string.
*/
- if (attr == ACPI_ATTR_INDEX_SHOW)
+ if (attr == ACPI_ATTR_INDEX_SHOW) {
scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value);
- else if (attr == ACPI_ATTR_LABEL_SHOW)
- dsm_label_utf16s_to_utf8s(tmp + 1, buf);
+ } else if (attr == ACPI_ATTR_LABEL_SHOW) {
+ if (tmp[1].type == ACPI_TYPE_STRING)
+ scnprintf(buf, PAGE_SIZE, "%s\n",
+ tmp[1].string.pointer);
+ else if (tmp[1].type == ACPI_TYPE_BUFFER)
+ dsm_label_utf16s_to_utf8s(tmp + 1, buf);
+ }
len = strlen(buf) > 0 ? strlen(buf) : -1;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 63a54a340863..2c9ac70254e2 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -839,12 +839,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (!__pci_complete_power_transition(dev, state))
error = 0;
- /*
- * When aspm_policy is "powersave" this call ensures
- * that ASPM is configured.
- */
- if (!error && dev->bus->self)
- pcie_aspm_powersave_config_link(dev->bus->self);
return error;
}
@@ -1195,12 +1189,18 @@ int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
static int do_pci_enable_device(struct pci_dev *dev, int bars)
{
int err;
+ struct pci_dev *bridge;
u16 cmd;
u8 pin;
err = pci_set_power_state(dev, PCI_D0);
if (err < 0 && err != -EIO)
return err;
+
+ bridge = pci_upstream_bridge(dev);
+ if (bridge)
+ pcie_aspm_powersave_config_link(bridge);
+
err = pcibios_enable_device(dev, bars);
if (err < 0)
return err;
@@ -3135,8 +3135,13 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
if (probe)
return 0;
- /* Wait for Transaction Pending bit clean */
- if (pci_wait_for_pending(dev, pos + PCI_AF_STATUS, PCI_AF_STATUS_TP))
+ /*
+ * Wait for Transaction Pending bit to clear. A word-aligned test
+ * is used, so we use the conrol offset rather than status and shift
+ * the test bit to match.
+ */
+ if (pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
+ PCI_AF_STATUS_TP << 8))
goto clear;
dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
@@ -3193,7 +3198,7 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
return 0;
}
-void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
+void pci_reset_secondary_bus(struct pci_dev *dev)
{
u16 ctrl;
@@ -3219,6 +3224,11 @@ void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
ssleep(1);
}
+void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
+{
+ pci_reset_secondary_bus(dev);
+}
+
/**
* pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge.
* @dev: Bridge device
diff --git a/drivers/pci/pcie/aer/Kconfig b/drivers/pci/pcie/aer/Kconfig
index 50e94e02378a..389440228c1d 100644
--- a/drivers/pci/pcie/aer/Kconfig
+++ b/drivers/pci/pcie/aer/Kconfig
@@ -5,6 +5,7 @@
config PCIEAER
boolean "Root Port Advanced Error Reporting support"
depends on PCIEPORTBUS
+ select RAS
default y
help
This enables PCI Express Root Port Advanced Error Reporting
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 36ed31b52198..35d06e177917 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -22,9 +22,7 @@
#include <linux/cper.h>
#include "aerdrv.h"
-
-#define CREATE_TRACE_POINTS
-#include <trace/events/ras.h>
+#include <ras/ras_event.h>
#define AER_AGENT_RECEIVER 0
#define AER_AGENT_REQUESTER 1
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 80887eaa0668..2ccc9b926ea7 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -203,10 +203,6 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
(pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
return -ENODEV;
- if (!dev->irq && dev->pin) {
- dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; check vendor BIOS\n",
- dev->vendor, dev->device);
- }
status = pcie_port_device_register(dev);
if (status)
return status;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d0f69269eb6c..80c2d014283d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2986,6 +2986,103 @@ DECLARE_PCI_FIXUP_HEADER(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169,
quirk_broken_intx_masking);
+#ifdef CONFIG_ACPI
+/*
+ * Apple: Shutdown Cactus Ridge Thunderbolt controller.
+ *
+ * On Apple hardware the Cactus Ridge Thunderbolt controller needs to be
+ * shutdown before suspend. Otherwise the native host interface (NHI) will not
+ * be present after resume if a device was plugged in before suspend.
+ *
+ * The thunderbolt controller consists of a pcie switch with downstream
+ * bridges leading to the NHI and to the tunnel pci bridges.
+ *
+ * This quirk cuts power to the whole chip. Therefore we have to apply it
+ * during suspend_noirq of the upstream bridge.
+ *
+ * Power is automagically restored before resume. No action is needed.
+ */
+static void quirk_apple_poweroff_thunderbolt(struct pci_dev *dev)
+{
+ acpi_handle bridge, SXIO, SXFP, SXLV;
+
+ if (!dmi_match(DMI_BOARD_VENDOR, "Apple Inc."))
+ return;
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM)
+ return;
+ bridge = ACPI_HANDLE(&dev->dev);
+ if (!bridge)
+ return;
+ /*
+ * SXIO and SXLV are present only on machines requiring this quirk.
+ * TB bridges in external devices might have the same device id as those
+ * on the host, but they will not have the associated ACPI methods. This
+ * implicitly checks that we are at the right bridge.
+ */
+ if (ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXIO", &SXIO))
+ || ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXFP", &SXFP))
+ || ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXLV", &SXLV)))
+ return;
+ dev_info(&dev->dev, "quirk: cutting power to thunderbolt controller...\n");
+
+ /* magic sequence */
+ acpi_execute_simple_method(SXIO, NULL, 1);
+ acpi_execute_simple_method(SXFP, NULL, 0);
+ msleep(300);
+ acpi_execute_simple_method(SXLV, NULL, 0);
+ acpi_execute_simple_method(SXIO, NULL, 0);
+ acpi_execute_simple_method(SXLV, NULL, 0);
+}
+DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL, 0x1547,
+ quirk_apple_poweroff_thunderbolt);
+
+/*
+ * Apple: Wait for the thunderbolt controller to reestablish pci tunnels.
+ *
+ * During suspend the thunderbolt controller is reset and all pci
+ * tunnels are lost. The NHI driver will try to reestablish all tunnels
+ * during resume. We have to manually wait for the NHI since there is
+ * no parent child relationship between the NHI and the tunneled
+ * bridges.
+ */
+static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev)
+{
+ struct pci_dev *sibling = NULL;
+ struct pci_dev *nhi = NULL;
+
+ if (!dmi_match(DMI_BOARD_VENDOR, "Apple Inc."))
+ return;
+ if (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)
+ return;
+ /*
+ * Find the NHI and confirm that we are a bridge on the tb host
+ * controller and not on a tb endpoint.
+ */
+ sibling = pci_get_slot(dev->bus, 0x0);
+ if (sibling == dev)
+ goto out; /* we are the downstream bridge to the NHI */
+ if (!sibling || !sibling->subordinate)
+ goto out;
+ nhi = pci_get_slot(sibling->subordinate, 0x0);
+ if (!nhi)
+ goto out;
+ if (nhi->vendor != PCI_VENDOR_ID_INTEL
+ || (nhi->device != 0x1547 && nhi->device != 0x156c)
+ || nhi->subsystem_vendor != 0x2222
+ || nhi->subsystem_device != 0x1111)
+ goto out;
+ dev_info(&dev->dev, "quirk: wating for thunderbolt to reestablish pci tunnels...\n");
+ device_pm_wait_for_dev(&dev->dev, &nhi->dev);
+out:
+ pci_dev_put(nhi);
+ pci_dev_put(sibling);
+}
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x1547,
+ quirk_apple_wait_for_thunderbolt);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, 0x156d,
+ quirk_apple_wait_for_thunderbolt);
+#endif
+
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
struct pci_fixup *end)
{
@@ -3018,6 +3115,8 @@ extern struct pci_fixup __start_pci_fixups_resume_early[];
extern struct pci_fixup __end_pci_fixups_resume_early[];
extern struct pci_fixup __start_pci_fixups_suspend[];
extern struct pci_fixup __end_pci_fixups_suspend[];
+extern struct pci_fixup __start_pci_fixups_suspend_late[];
+extern struct pci_fixup __end_pci_fixups_suspend_late[];
static bool pci_apply_fixup_final_quirks;
@@ -3063,6 +3162,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
end = __end_pci_fixups_suspend;
break;
+ case pci_fixup_suspend_late:
+ start = __start_pci_fixups_suspend_late;
+ end = __end_pci_fixups_suspend_late;
+ break;
+
default:
/* stupid compiler warning, you would think with an enum... */
return;
@@ -3405,6 +3509,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ASMEDIA, 0x1080,
DECLARE_PCI_FIXUP_HEADER(0x10e3, 0x8113, quirk_use_pcie_bridge_dma_alias);
/* ITE 8892, https://bugzilla.kernel.org/show_bug.cgi?id=73551 */
DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias);
+/* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */
+DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias);
static struct pci_dev *pci_func_0_dma_source(struct pci_dev *dev)
{
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index a5a63ecfb628..6373985ad3f7 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -925,7 +925,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
{
struct pci_dev *dev;
resource_size_t min_align, align, size, size0, size1;
- resource_size_t aligns[14]; /* Alignments from 1Mb to 8Gb */
+ resource_size_t aligns[18]; /* Alignments from 1Mb to 128Gb */
int order, max_order;
struct resource *b_res = find_free_bus_resource(bus,
mask | IORESOURCE_PREFETCH, type);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index caed1ce6facd..b7c3a5ea1fca 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -166,11 +166,10 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
{
struct resource *root, *conflict;
resource_size_t fw_addr, start, end;
- int ret = 0;
fw_addr = pcibios_retrieve_fw_addr(dev, resno);
if (!fw_addr)
- return 1;
+ return -ENOMEM;
start = res->start;
end = res->end;
@@ -189,14 +188,13 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
resno, res);
conflict = request_resource_conflict(root, res);
if (conflict) {
- dev_info(&dev->dev,
- "BAR %d: %pR conflicts with %s %pR\n", resno,
- res, conflict->name, conflict);
+ dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n",
+ resno, res, conflict->name, conflict);
res->start = start;
res->end = end;
- ret = 1;
+ return -EBUSY;
}
- return ret;
+ return 0;
}
static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
@@ -250,10 +248,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
static int _pci_assign_resource(struct pci_dev *dev, int resno,
resource_size_t size, resource_size_t min_align)
{
- struct resource *res = dev->resource + resno;
struct pci_bus *bus;
int ret;
- char *type;
bus = dev->bus;
while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
@@ -262,21 +258,6 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
bus = bus->parent;
}
- if (ret) {
- if (res->flags & IORESOURCE_MEM)
- if (res->flags & IORESOURCE_PREFETCH)
- type = "mem pref";
- else
- type = "mem";
- else if (res->flags & IORESOURCE_IO)
- type = "io";
- else
- type = "unknown";
- dev_info(&dev->dev,
- "BAR %d: can't assign %s (size %#llx)\n",
- resno, type, (unsigned long long) resource_size(res));
- }
-
return ret;
}
@@ -302,17 +283,24 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
* where firmware left it. That at least has a chance of
* working, which is better than just leaving it disabled.
*/
- if (ret < 0)
+ if (ret < 0) {
+ dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res);
ret = pci_revert_fw_address(res, dev, resno, size);
+ }
- if (!ret) {
- res->flags &= ~IORESOURCE_UNSET;
- res->flags &= ~IORESOURCE_STARTALIGN;
- dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
- if (resno < PCI_BRIDGE_RESOURCES)
- pci_update_resource(dev, resno);
+ if (ret < 0) {
+ dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno,
+ res);
+ return ret;
}
- return ret;
+
+ res->flags &= ~IORESOURCE_UNSET;
+ res->flags &= ~IORESOURCE_STARTALIGN;
+ dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
+ if (resno < PCI_BRIDGE_RESOURCES)
+ pci_update_resource(dev, resno);
+
+ return 0;
}
EXPORT_SYMBOL(pci_assign_resource);
@@ -320,9 +308,11 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
resource_size_t min_align)
{
struct resource *res = dev->resource + resno;
+ unsigned long flags;
resource_size_t new_size;
int ret;
+ flags = res->flags;
res->flags |= IORESOURCE_UNSET;
if (!res->parent) {
dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n",
@@ -333,14 +323,21 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
/* already aligned with min_align */
new_size = resource_size(res) + addsize;
ret = _pci_assign_resource(dev, resno, new_size, min_align);
- if (!ret) {
- res->flags &= ~IORESOURCE_UNSET;
- res->flags &= ~IORESOURCE_STARTALIGN;
- dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
- if (resno < PCI_BRIDGE_RESOURCES)
- pci_update_resource(dev, resno);
+ if (ret) {
+ res->flags = flags;
+ dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n",
+ resno, res, (unsigned long long) addsize);
+ return ret;
}
- return ret;
+
+ res->flags &= ~IORESOURCE_UNSET;
+ res->flags &= ~IORESOURCE_STARTALIGN;
+ dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
+ resno, res, (unsigned long long) addsize);
+ if (resno < PCI_BRIDGE_RESOURCES)
+ pci_update_resource(dev, resno);
+
+ return 0;
}
int pci_enable_resources(struct pci_dev *dev, int mask)
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 0c657d6af03d..b0ce7cdee0c2 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -144,16 +144,6 @@ config TCIC
"Bridge" is the name used for the hardware inside your computer that
PCMCIA cards are plugged into. If unsure, say N.
-config PCMCIA_M8XX
- tristate "MPC8xx PCMCIA support"
- depends on PCCARD && PPC && 8xx
- select PCCARD_IODYN if PCMCIA != n
- help
- Say Y here to include support for PowerPC 8xx series PCMCIA
- controller.
-
- This driver is also available as a module called m8xx_pcmcia.
-
config PCMCIA_ALCHEMY_DEVBOARD
tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
depends on MIPS_ALCHEMY && PCMCIA
@@ -202,6 +192,7 @@ config PCMCIA_SA1111
depends on ARM && SA1111 && PCMCIA
select PCMCIA_SOC_COMMON
select PCMCIA_SA11XX_BASE if ARCH_SA1100
+ select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
help
Say Y here to include support for SA1111-based PCMCIA or CF
sockets, found on the Jornada 720, Graphicsmaster and other
@@ -217,7 +208,6 @@ config PCMCIA_PXA2XX
|| ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
|| MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
|| MACH_COLIBRI320 || MACH_H4700)
- select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
select PCMCIA_SOC_COMMON
help
Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 7745b512a87c..27e94b30cf96 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -23,7 +23,6 @@ obj-$(CONFIG_PD6729) += pd6729.o
obj-$(CONFIG_I82365) += i82365.o
obj-$(CONFIG_I82092) += i82092.o
obj-$(CONFIG_TCIC) += tcic.o
-obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o
obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
@@ -49,6 +48,7 @@ sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
+sa1100_cs-$(CONFIG_SA1100_H3100) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c
index 0c6aac1232fc..0802e0bc7d0c 100644
--- a/drivers/pcmcia/bcm63xx_pcmcia.c
+++ b/drivers/pcmcia/bcm63xx_pcmcia.c
@@ -475,7 +475,7 @@ static void bcm63xx_cb_exit(struct pci_dev *dev)
bcm63xx_cb_dev = NULL;
}
-static DEFINE_PCI_DEVICE_TABLE(bcm63xx_cb_table) = {
+static const struct pci_device_id bcm63xx_cb_table[] = {
{
.vendor = PCI_VENDOR_ID_BROADCOM,
.device = BCM6348_CPU_ID,
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 7d47456429a1..aae7e6df99cd 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -25,7 +25,7 @@
MODULE_LICENSE("GPL");
/* PCI core routines */
-static DEFINE_PCI_DEVICE_TABLE(i82092aa_pci_ids) = {
+static const struct pci_device_id i82092aa_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82092AA_0) },
{ }
};
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
deleted file mode 100644
index 182034d2ef58..000000000000
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
- *
- * (C) 1999-2000 Magnus Damm <damm@opensource.se>
- * (C) 2001-2002 Montavista Software, Inc.
- * <mlocke@mvista.com>
- *
- * Support for two slots by Cyclades Corporation
- * <oliver.kurth@cyclades.de>
- * Further fixes, v2.6 kernel port
- * <marcelo.tosatti@cyclades.com>
- *
- * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
- * <vbordug@ru.mvista.com>
- *
- * "The ExCA standard specifies that socket controllers should provide
- * two IO and five memory windows per socket, which can be independently
- * configured and positioned in the host address space and mapped to
- * arbitrary segments of card address space. " - David A Hinds. 1999
- *
- * This controller does _not_ meet the ExCA standard.
- *
- * m8xx pcmcia controller brief info:
- * + 8 windows (attrib, mem, i/o)
- * + up to two slots (SLOT_A and SLOT_B)
- * + inputpins, outputpins, event and mask registers.
- * - no offset register. sigh.
- *
- * Because of the lacking offset register we must map the whole card.
- * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
- * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
- * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
- * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
- * They are maximum 64KByte each...
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fsl_devices.h>
-#include <linux/bitops.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-
-#include <asm/io.h>
-#include <asm/time.h>
-#include <asm/mpc8xx.h>
-#include <asm/8xx_immap.h>
-#include <asm/irq.h>
-#include <asm/fs_pd.h>
-
-#include <pcmcia/ss.h>
-
-#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
-#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
-
-static const char *version = "Version 0.06, Aug 2005";
-MODULE_LICENSE("Dual MPL/GPL");
-
-#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
-
-/* The ADS board use SLOT_A */
-#ifdef CONFIG_ADS
-#define CONFIG_PCMCIA_SLOT_A
-#define CONFIG_BD_IS_MHZ
-#endif
-
-/* The FADS series are a mess */
-#ifdef CONFIG_FADS
-#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
-#define CONFIG_PCMCIA_SLOT_A
-#else
-#define CONFIG_PCMCIA_SLOT_B
-#endif
-#endif
-
-#if defined(CONFIG_MPC885ADS)
-#define CONFIG_PCMCIA_SLOT_A
-#define PCMCIA_GLITCHY_CD
-#endif
-
-/* Cyclades ACS uses both slots */
-#ifdef CONFIG_PRxK
-#define CONFIG_PCMCIA_SLOT_A
-#define CONFIG_PCMCIA_SLOT_B
-#endif
-
-#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
-
-#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
-
-#define PCMCIA_SOCKETS_NO 2
-/* We have only 8 windows, dualsocket support will be limited. */
-#define PCMCIA_MEM_WIN_NO 2
-#define PCMCIA_IO_WIN_NO 2
-#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
-
-#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
-
-#define PCMCIA_SOCKETS_NO 1
-/* full support for one slot */
-#define PCMCIA_MEM_WIN_NO 5
-#define PCMCIA_IO_WIN_NO 2
-
-/* define _slot_ to be able to optimize macros */
-
-#ifdef CONFIG_PCMCIA_SLOT_A
-#define _slot_ 0
-#define PCMCIA_SLOT_MSG "SLOT_A"
-#else
-#define _slot_ 1
-#define PCMCIA_SLOT_MSG "SLOT_B"
-#endif
-
-#else
-#error m8xx_pcmcia: Bad configuration!
-#endif
-
-/* ------------------------------------------------------------------------- */
-
-#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
-#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
-#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
-/* ------------------------------------------------------------------------- */
-
-static int pcmcia_schlvl;
-
-static DEFINE_SPINLOCK(events_lock);
-
-#define PCMCIA_SOCKET_KEY_5V 1
-#define PCMCIA_SOCKET_KEY_LV 2
-
-/* look up table for pgcrx registers */
-static u32 *m8xx_pgcrx[2];
-
-/*
- * This structure is used to address each window in the PCMCIA controller.
- *
- * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
- * after pcmcia_win[n]...
- */
-
-struct pcmcia_win {
- u32 br;
- u32 or;
-};
-
-/*
- * For some reason the hardware guys decided to make both slots share
- * some registers.
- *
- * Could someone invent object oriented hardware ?
- *
- * The macros are used to get the right bit from the registers.
- * SLOT_A : slot = 0
- * SLOT_B : slot = 1
- */
-
-#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
-#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
-#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
-#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
-
-#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
-#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
-#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
-#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
-#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
-#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
-#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
-#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
-#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
-#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
-#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
-
-#define M8XX_PCMCIA_POR_VALID 0x00000001
-#define M8XX_PCMCIA_POR_WRPROT 0x00000002
-#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010
-#define M8XX_PCMCIA_POR_IO 0x00000018
-#define M8XX_PCMCIA_POR_16BIT 0x00000040
-
-#define M8XX_PGCRX(slot) m8xx_pgcrx[slot]
-
-#define M8XX_PGCRX_CXOE 0x00000080
-#define M8XX_PGCRX_CXRESET 0x00000040
-
-/* we keep one lookup table per socket to check flags */
-
-#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
-
-struct event_table {
- u32 regbit;
- u32 eventbit;
-};
-
-static const char driver_name[] = "m8xx-pcmcia";
-
-struct socket_info {
- void (*handler) (void *info, u32 events);
- void *info;
-
- u32 slot;
- pcmconf8xx_t *pcmcia;
- u32 bus_freq;
- int hwirq;
-
- socket_state_t state;
- struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
- struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
- struct event_table events[PCMCIA_EVENTS_MAX];
- struct pcmcia_socket socket;
-};
-
-static struct socket_info socket[PCMCIA_SOCKETS_NO];
-
-/*
- * Search this table to see if the windowsize is
- * supported...
- */
-
-#define M8XX_SIZES_NO 32
-
-static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = {
- 0x00000001, 0x00000002, 0x00000008, 0x00000004,
- 0x00000080, 0x00000040, 0x00000010, 0x00000020,
- 0x00008000, 0x00004000, 0x00001000, 0x00002000,
- 0x00000100, 0x00000200, 0x00000800, 0x00000400,
-
- 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
- 0x00010000, 0x00020000, 0x00080000, 0x00040000,
- 0x00800000, 0x00400000, 0x00100000, 0x00200000
-};
-
-/* ------------------------------------------------------------------------- */
-
-static irqreturn_t m8xx_interrupt(int irq, void *dev);
-
-#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
-
-/* FADS Boards from Motorola */
-
-#if defined(CONFIG_FADS)
-
-#define PCMCIA_BOARD_MSG "FADS"
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- u32 reg = 0;
-
- switch (vcc) {
- case 0:
- break;
- case 33:
- reg |= BCSR1_PCCVCC0;
- break;
- case 50:
- reg |= BCSR1_PCCVCC1;
- break;
- default:
- return 1;
- }
-
- switch (vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if (vcc == vpp)
- reg |= BCSR1_PCCVPP1;
- else
- return 1;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= BCSR1_PCCVPP0;
- else
- return 1;
- default:
- return 1;
- }
-
- /* first, turn off all power */
- out_be32((u32 *) BCSR1,
- in_be32((u32 *) BCSR1) & ~(BCSR1_PCCVCC_MASK |
- BCSR1_PCCVPP_MASK));
-
- /* enable new powersettings */
- out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | reg);
-
- return 0;
-}
-
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-
-static void hardware_enable(int slot)
-{
- out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~BCSR1_PCCEN);
-}
-
-static void hardware_disable(int slot)
-{
- out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | BCSR1_PCCEN);
-}
-
-#endif
-
-/* MPC885ADS Boards */
-
-#if defined(CONFIG_MPC885ADS)
-
-#define PCMCIA_BOARD_MSG "MPC885ADS"
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
-
-static inline void hardware_enable(int slot)
-{
- m8xx_pcmcia_ops.hw_ctrl(slot, 1);
-}
-
-static inline void hardware_disable(int slot)
-{
- m8xx_pcmcia_ops.hw_ctrl(slot, 0);
-}
-
-static inline int voltage_set(int slot, int vcc, int vpp)
-{
- return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
-}
-
-#endif
-
-#if defined(CONFIG_PRxK)
-#include <asm/cpld.h>
-extern volatile fpga_pc_regs *fpga_pc;
-
-#define PCMCIA_BOARD_MSG "MPC855T"
-
-static int voltage_set(int slot, int vcc, int vpp)
-{
- u8 reg = 0;
- u8 regread;
- cpld_regs *ccpld = get_cpld();
-
- switch (vcc) {
- case 0:
- break;
- case 33:
- reg |= PCMCIA_VCC_33;
- break;
- case 50:
- reg |= PCMCIA_VCC_50;
- break;
- default:
- return 1;
- }
-
- switch (vpp) {
- case 0:
- break;
- case 33:
- case 50:
- if (vcc == vpp)
- reg |= PCMCIA_VPP_VCC;
- else
- return 1;
- break;
- case 120:
- if ((vcc == 33) || (vcc == 50))
- reg |= PCMCIA_VPP_12;
- else
- return 1;
- default:
- return 1;
- }
-
- reg = reg >> (slot << 2);
- regread = in_8(&ccpld->fpga_pc_ctl);
- if (reg !=
- (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
- /* enable new powersettings */
- regread =
- regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >>
- (slot << 2));
- out_8(&ccpld->fpga_pc_ctl, reg | regread);
- msleep(100);
- }
-
- return 0;
-}
-
-#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
-#define hardware_enable(_slot_) /* No hardware to enable */
-#define hardware_disable(_slot_) /* No hardware to disable */
-
-#endif /* CONFIG_PRxK */
-
-static u32 pending_events[PCMCIA_SOCKETS_NO];
-static DEFINE_SPINLOCK(pending_event_lock);
-
-static irqreturn_t m8xx_interrupt(int irq, void *dev)
-{
- struct socket_info *s;
- struct event_table *e;
- unsigned int i, events, pscr, pipr, per;
- pcmconf8xx_t *pcmcia = socket[0].pcmcia;
-
- pr_debug("m8xx_pcmcia: Interrupt!\n");
- /* get interrupt sources */
-
- pscr = in_be32(&pcmcia->pcmc_pscr);
- pipr = in_be32(&pcmcia->pcmc_pipr);
- per = in_be32(&pcmcia->pcmc_per);
-
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- s = &socket[i];
- e = &s->events[0];
- events = 0;
-
- while (e->regbit) {
- if (pscr & e->regbit)
- events |= e->eventbit;
-
- e++;
- }
-
- /*
- * report only if both card detect signals are the same
- * not too nice done,
- * we depend on that CD2 is the bit to the left of CD1...
- */
- if (events & SS_DETECT)
- if (((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
- (pipr & M8XX_PCMCIA_CD1(i))) {
- events &= ~SS_DETECT;
- }
-#ifdef PCMCIA_GLITCHY_CD
- /*
- * I've experienced CD problems with my ADS board.
- * We make an extra check to see if there was a
- * real change of Card detection.
- */
-
- if ((events & SS_DETECT) &&
- ((pipr &
- (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
- (s->state.Vcc | s->state.Vpp)) {
- events &= ~SS_DETECT;
- /*printk( "CD glitch workaround - CD = 0x%08x!\n",
- (pipr & (M8XX_PCMCIA_CD2(i)
- | M8XX_PCMCIA_CD1(i)))); */
- }
-#endif
-
- /* call the handler */
-
- pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
- "pipr = 0x%08x\n", i, events, pscr, pipr);
-
- if (events) {
- spin_lock(&pending_event_lock);
- pending_events[i] |= events;
- spin_unlock(&pending_event_lock);
- /*
- * Turn off RDY_L bits in the PER mask on
- * CD interrupt receival.
- *
- * They can generate bad interrupts on the
- * ACS4,8,16,32. - marcelo
- */
- per &= ~M8XX_PCMCIA_RDY_L(0);
- per &= ~M8XX_PCMCIA_RDY_L(1);
-
- out_be32(&pcmcia->pcmc_per, per);
-
- if (events)
- pcmcia_parse_events(&socket[i].socket, events);
- }
- }
-
- /* clear the interrupt sources */
- out_be32(&pcmcia->pcmc_pscr, pscr);
-
- pr_debug("m8xx_pcmcia: Interrupt done.\n");
-
- return IRQ_HANDLED;
-}
-
-static u32 m8xx_get_graycode(u32 size)
-{
- u32 k;
-
- for (k = 0; k < M8XX_SIZES_NO; k++)
- if (m8xx_size_to_gray[k] == size)
- break;
-
- if ((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
- k = -1;
-
- return k;
-}
-
-static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
-{
- u32 reg, clocks, psst, psl, psht;
-
- if (!ns) {
-
- /*
- * We get called with IO maps setup to 0ns
- * if not specified by the user.
- * They should be 255ns.
- */
-
- if (is_io)
- ns = 255;
- else
- ns = 100; /* fast memory if 0 */
- }
-
- /*
- * In PSST, PSL, PSHT fields we tell the controller
- * timing parameters in CLKOUT clock cycles.
- * CLKOUT is the same as GCLK2_50.
- */
-
-/* how we want to adjust the timing - in percent */
-
-#define ADJ 180 /* 80 % longer accesstime - to be sure */
-
- clocks = ((bus_freq / 1000) * ns) / 1000;
- clocks = (clocks * ADJ) / (100 * 1000);
- if (clocks >= PCMCIA_BMT_LIMIT) {
- printk("Max access time limit reached\n");
- clocks = PCMCIA_BMT_LIMIT - 1;
- }
-
- psst = clocks / 7; /* setup time */
- psht = clocks / 7; /* hold time */
- psl = (clocks * 5) / 7; /* strobe length */
-
- psst += clocks - (psst + psht + psl);
-
- reg = psst << 12;
- reg |= psl << 7;
- reg |= psht << 16;
-
- return reg;
-}
-
-static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
-{
- int lsock = container_of(sock, struct socket_info, socket)->slot;
- struct socket_info *s = &socket[lsock];
- unsigned int pipr, reg;
- pcmconf8xx_t *pcmcia = s->pcmcia;
-
- pipr = in_be32(&pcmcia->pcmc_pipr);
-
- *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
- | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
- *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
-
- if (s->state.flags & SS_IOCARD)
- *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
- else {
- *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
- *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
- *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
- }
-
- if (s->state.Vcc | s->state.Vpp)
- *value |= SS_POWERON;
-
- /*
- * Voltage detection:
- * This driver only supports 16-Bit pc-cards.
- * Cardbus is not handled here.
- *
- * To determine what voltage to use we must read the VS1 and VS2 pin.
- * Depending on what socket type is present,
- * different combinations mean different things.
- *
- * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse
- *
- * 5V 5V, LV* NC NC 5V only 5V (if available)
- *
- * 5V 5V, LV* GND NC 5 or 3.3V as low as possible
- *
- * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible
- *
- * LV* 5V - - shall not fit into socket
- *
- * LV* LV* GND NC 3.3V only 3.3V
- *
- * LV* LV* NC GND x.xV x.xV (if avail.)
- *
- * LV* LV* GND GND 3.3 or x.xV as low as possible
- *
- * *LV means Low Voltage
- *
- *
- * That gives us the following table:
- *
- * Socket VS1 VS2 Voltage
- *
- * 5V NC NC 5V
- * 5V NC GND none (should not be possible)
- * 5V GND NC >= 3.3V
- * 5V GND GND >= x.xV
- *
- * LV NC NC 5V (if available)
- * LV NC GND x.xV (if available)
- * LV GND NC 3.3V
- * LV GND GND >= x.xV
- *
- * So, how do I determine if I have a 5V or a LV
- * socket on my board? Look at the socket!
- *
- *
- * Socket with 5V key:
- * ++--------------------------------------------+
- * || |
- * || ||
- * || ||
- * | |
- * +---------------------------------------------+
- *
- * Socket with LV key:
- * ++--------------------------------------------+
- * || |
- * | ||
- * | ||
- * | |
- * +---------------------------------------------+
- *
- *
- * With other words - LV only cards does not fit
- * into the 5V socket!
- */
-
- /* read out VS1 and VS2 */
-
- reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
- >> M8XX_PCMCIA_VS_SHIFT(lsock);
-
- if (socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
- switch (reg) {
- case 1:
- *value |= SS_3VCARD;
- break; /* GND, NC - 3.3V only */
- case 2:
- *value |= SS_XVCARD;
- break; /* NC. GND - x.xV only */
- };
- }
-
- pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
- return 0;
-}
-
-static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
-{
- int lsock = container_of(sock, struct socket_info, socket)->slot;
- struct socket_info *s = &socket[lsock];
- struct event_table *e;
- unsigned int reg;
- unsigned long flags;
- pcmconf8xx_t *pcmcia = socket[0].pcmcia;
-
- pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
- "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
- state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-
- /* First, set voltage - bail out if invalid */
- if (voltage_set(lsock, state->Vcc, state->Vpp))
- return -EINVAL;
-
- /* Take care of reset... */
- if (state->flags & SS_RESET)
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
- else
- out_be32(M8XX_PGCRX(lsock),
- in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
-
- /* ... and output enable. */
-
- /* The CxOE signal is connected to a 74541 on the ADS.
- I guess most other boards used the ADS as a reference.
- I tried to control the CxOE signal with SS_OUTPUT_ENA,
- but the reset signal seems connected via the 541.
- If the CxOE is left high are some signals tristated and
- no pullups are present -> the cards act weird.
- So right now the buffers are enabled if the power is on. */
-
- if (state->Vcc || state->Vpp)
- out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
- else
- out_be32(M8XX_PGCRX(lsock),
- in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
-
- /*
- * We'd better turn off interrupts before
- * we mess with the events-table..
- */
-
- spin_lock_irqsave(&events_lock, flags);
-
- /*
- * Play around with the interrupt mask to be able to
- * give the events the generic pcmcia driver wants us to.
- */
-
- e = &s->events[0];
- reg = 0;
-
- if (state->csc_mask & SS_DETECT) {
- e->eventbit = SS_DETECT;
- reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
- | M8XX_PCMCIA_CD1(lsock));
- e++;
- }
- if (state->flags & SS_IOCARD) {
- /*
- * I/O card
- */
- if (state->csc_mask & SS_STSCHG) {
- e->eventbit = SS_STSCHG;
- reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
- e++;
- }
- /*
- * If io_irq is non-zero we should enable irq.
- */
- if (state->io_irq) {
- out_be32(M8XX_PGCRX(lsock),
- in_be32(M8XX_PGCRX(lsock)) |
- mk_int_int_mask(s->hwirq) << 24);
- /*
- * Strange thing here:
- * The manual does not tell us which interrupt
- * the sources generate.
- * Anyhow, I found out that RDY_L generates IREQLVL.
- *
- * We use level triggerd interrupts, and they don't
- * have to be cleared in PSCR in the interrupt handler.
- */
- reg |= M8XX_PCMCIA_RDY_L(lsock);
- } else
- out_be32(M8XX_PGCRX(lsock),
- in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
- } else {
- /*
- * Memory card
- */
- if (state->csc_mask & SS_BATDEAD) {
- e->eventbit = SS_BATDEAD;
- reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
- e++;
- }
- if (state->csc_mask & SS_BATWARN) {
- e->eventbit = SS_BATWARN;
- reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
- e++;
- }
- /* What should I trigger on - low/high,raise,fall? */
- if (state->csc_mask & SS_READY) {
- e->eventbit = SS_READY;
- reg |= e->regbit = 0; //??
- e++;
- }
- }
-
- e->regbit = 0; /* terminate list */
-
- /*
- * Clear the status changed .
- * Port A and Port B share the same port.
- * Writing ones will clear the bits.
- */
-
- out_be32(&pcmcia->pcmc_pscr, reg);
-
- /*
- * Write the mask.
- * Port A and Port B share the same port.
- * Need for read-modify-write.
- * Ones will enable the interrupt.
- */
-
- reg |=
- in_be32(&pcmcia->
- pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
- out_be32(&pcmcia->pcmc_per, reg);
-
- spin_unlock_irqrestore(&events_lock, flags);
-
- /* copy the struct and modify the copy */
-
- s->state = *state;
-
- return 0;
-}
-
-static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
-{
- int lsock = container_of(sock, struct socket_info, socket)->slot;
-
- struct socket_info *s = &socket[lsock];
- struct pcmcia_win *w;
- unsigned int reg, winnr;
- pcmconf8xx_t *pcmcia = s->pcmcia;
-
-#define M8XX_SIZE (io->stop - io->start + 1)
-#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
-
- pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
- io->speed, (unsigned long long)io->start,
- (unsigned long long)io->stop);
-
- if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
- || (io->stop > 0xffff) || (io->stop < io->start))
- return -EINVAL;
-
- if ((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
- return -EINVAL;
-
- if (io->flags & MAP_ACTIVE) {
-
- pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
-
- winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
- + (lsock * PCMCIA_IO_WIN_NO) + io->map;
-
- /* setup registers */
-
- w = (void *)&pcmcia->pcmc_pbr0;
- w += winnr;
-
- out_be32(&w->or, 0); /* turn off window first */
- out_be32(&w->br, M8XX_BASE);
-
- reg <<= 27;
- reg |= M8XX_PCMCIA_POR_IO | (lsock << 2);
-
- reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
-
- if (io->flags & MAP_WRPROT)
- reg |= M8XX_PCMCIA_POR_WRPROT;
-
- /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) */
- if (io->flags & MAP_16BIT)
- reg |= M8XX_PCMCIA_POR_16BIT;
-
- if (io->flags & MAP_ACTIVE)
- reg |= M8XX_PCMCIA_POR_VALID;
-
- out_be32(&w->or, reg);
-
- pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
- "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
- } else {
- /* shutdown IO window */
- winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
- + (lsock * PCMCIA_IO_WIN_NO) + io->map;
-
- /* setup registers */
-
- w = (void *)&pcmcia->pcmc_pbr0;
- w += winnr;
-
- out_be32(&w->or, 0); /* turn off window */
- out_be32(&w->br, 0); /* turn off base address */
-
- pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
- "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
- }
-
- /* copy the struct and modify the copy */
- s->io_win[io->map] = *io;
- s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
- pr_debug("m8xx_pcmcia: SetIOMap exit\n");
-
- return 0;
-}
-
-static int m8xx_set_mem_map(struct pcmcia_socket *sock,
- struct pccard_mem_map *mem)
-{
- int lsock = container_of(sock, struct socket_info, socket)->slot;
- struct socket_info *s = &socket[lsock];
- struct pcmcia_win *w;
- struct pccard_mem_map *old;
- unsigned int reg, winnr;
- pcmconf8xx_t *pcmcia = s->pcmcia;
-
- pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, (unsigned long long)mem->static_start,
- mem->card_start);
-
- if ((mem->map >= PCMCIA_MEM_WIN_NO)
-// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
- || (mem->card_start >= 0x04000000)
- || (mem->static_start & 0xfff) /* 4KByte resolution */
- ||(mem->card_start & 0xfff))
- return -EINVAL;
-
- if ((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
- printk("Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
- return -EINVAL;
- }
- reg <<= 27;
-
- winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
-
- /* Setup the window in the pcmcia controller */
-
- w = (void *)&pcmcia->pcmc_pbr0;
- w += winnr;
-
- reg |= lsock << 2;
-
- reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
-
- if (mem->flags & MAP_ATTRIB)
- reg |= M8XX_PCMCIA_POR_ATTRMEM;
-
- if (mem->flags & MAP_WRPROT)
- reg |= M8XX_PCMCIA_POR_WRPROT;
-
- if (mem->flags & MAP_16BIT)
- reg |= M8XX_PCMCIA_POR_16BIT;
-
- if (mem->flags & MAP_ACTIVE)
- reg |= M8XX_PCMCIA_POR_VALID;
-
- out_be32(&w->or, reg);
-
- pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
- "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
-
- if (mem->flags & MAP_ACTIVE) {
- /* get the new base address */
- mem->static_start = PCMCIA_MEM_WIN_BASE +
- (PCMCIA_MEM_WIN_SIZE * winnr)
- + mem->card_start;
- }
-
- pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
- "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
- mem->speed, (unsigned long long)mem->static_start,
- mem->card_start);
-
- /* copy the struct and modify the copy */
-
- old = &s->mem_win[mem->map];
-
- *old = *mem;
- old->flags &= (MAP_ATTRIB | MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
-
- return 0;
-}
-
-static int m8xx_sock_init(struct pcmcia_socket *sock)
-{
- int i;
- pccard_io_map io = { 0, 0, 0, 0, 1 };
- pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
-
- pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
-
- m8xx_set_socket(sock, &dead_socket);
- for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
- io.map = i;
- m8xx_set_io_map(sock, &io);
- }
- for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
- mem.map = i;
- m8xx_set_mem_map(sock, &mem);
- }
-
- return 0;
-
-}
-
-static int m8xx_sock_suspend(struct pcmcia_socket *sock)
-{
- return m8xx_set_socket(sock, &dead_socket);
-}
-
-static struct pccard_operations m8xx_services = {
- .init = m8xx_sock_init,
- .suspend = m8xx_sock_suspend,
- .get_status = m8xx_get_status,
- .set_socket = m8xx_set_socket,
- .set_io_map = m8xx_set_io_map,
- .set_mem_map = m8xx_set_mem_map,
-};
-
-static int __init m8xx_probe(struct platform_device *ofdev)
-{
- struct pcmcia_win *w;
- unsigned int i, m, hwirq;
- pcmconf8xx_t *pcmcia;
- int status;
- struct device_node *np = ofdev->dev.of_node;
-
- pcmcia_info("%s\n", version);
-
- pcmcia = of_iomap(np, 0);
- if (pcmcia == NULL)
- return -EINVAL;
-
- pcmcia_schlvl = irq_of_parse_and_map(np, 0);
- hwirq = irq_map[pcmcia_schlvl].hwirq;
- if (pcmcia_schlvl < 0) {
- iounmap(pcmcia);
- return -EINVAL;
- }
-
- m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
- m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
-
- pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
- " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
-
- /* Configure Status change interrupt */
-
- if (request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
- driver_name, socket)) {
- pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
- pcmcia_schlvl);
- iounmap(pcmcia);
- return -1;
- }
-
- w = (void *)&pcmcia->pcmc_pbr0;
-
- out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
- clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
-
- /* connect interrupt and disable CxOE */
-
- out_be32(M8XX_PGCRX(0),
- M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
- out_be32(M8XX_PGCRX(1),
- M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
-
- /* initialize the fixed memory windows */
-
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
- out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
- (PCMCIA_MEM_WIN_SIZE
- * (m + i * PCMCIA_MEM_WIN_NO)));
-
- out_be32(&w->or, 0); /* set to not valid */
-
- w++;
- }
- }
-
- /* turn off voltage */
- voltage_set(0, 0, 0);
- voltage_set(1, 0, 0);
-
- /* Enable external hardware */
- hardware_enable(0);
- hardware_enable(1);
-
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- socket[i].slot = i;
- socket[i].socket.owner = THIS_MODULE;
- socket[i].socket.features =
- SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
- socket[i].socket.irq_mask = 0x000;
- socket[i].socket.map_size = 0x1000;
- socket[i].socket.io_offset = 0;
- socket[i].socket.pci_irq = pcmcia_schlvl;
- socket[i].socket.ops = &m8xx_services;
- socket[i].socket.resource_ops = &pccard_iodyn_ops;
- socket[i].socket.cb_dev = NULL;
- socket[i].socket.dev.parent = &ofdev->dev;
- socket[i].pcmcia = pcmcia;
- socket[i].bus_freq = ppc_proc_freq;
- socket[i].hwirq = hwirq;
-
- }
-
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- status = pcmcia_register_socket(&socket[i].socket);
- if (status < 0)
- pcmcia_error("Socket register failed\n");
- }
-
- return 0;
-}
-
-static int m8xx_remove(struct platform_device *ofdev)
-{
- u32 m, i;
- struct pcmcia_win *w;
- pcmconf8xx_t *pcmcia = socket[0].pcmcia;
-
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
- w = (void *)&pcmcia->pcmc_pbr0;
-
- out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
- out_be32(&pcmcia->pcmc_per,
- in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
-
- /* turn off interrupt and disable CxOE */
- out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
-
- /* turn off memory windows */
- for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
- out_be32(&w->or, 0); /* set to not valid */
- w++;
- }
-
- /* turn off voltage */
- voltage_set(i, 0, 0);
-
- /* disable external hardware */
- hardware_disable(i);
- }
- for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
- pcmcia_unregister_socket(&socket[i].socket);
- iounmap(pcmcia);
-
- free_irq(pcmcia_schlvl, NULL);
-
- return 0;
-}
-
-static const struct of_device_id m8xx_pcmcia_match[] = {
- {
- .type = "pcmcia",
- .compatible = "fsl,pq-pcmcia",
- },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
-
-static struct platform_driver m8xx_pcmcia_driver = {
- .driver = {
- .name = driver_name,
- .owner = THIS_MODULE,
- .of_match_table = m8xx_pcmcia_match,
- },
- .probe = m8xx_probe,
- .remove = m8xx_remove,
-};
-
-module_platform_driver(m8xx_pcmcia_driver);
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 622dd6fe7347..34ace4854dc2 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -764,7 +764,7 @@ static void pd6729_pci_remove(struct pci_dev *dev)
kfree(socket);
}
-static DEFINE_PCI_DEVICE_TABLE(pd6729_pci_ids) = {
+static const struct pci_device_id pd6729_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6729) },
{ }
};
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 3baa3ef09682..40e040314503 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/hardware/sa1111.h>
@@ -94,6 +95,7 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
int pcmcia_jornada720_init(struct device *dev)
{
int ret = -ENODEV;
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
if (machine_is_jornada720()) {
unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
@@ -101,12 +103,12 @@ int pcmcia_jornada720_init(struct device *dev)
GRER |= 0x00000002;
/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
- sa1111_set_io_dir(dev, pin, 0, 0);
- sa1111_set_io(dev, pin, 0);
- sa1111_set_sleep_io(dev, pin, 0);
+ sa1111_set_io_dir(sadev, pin, 0, 0);
+ sa1111_set_io(sadev, pin, 0);
+ sa1111_set_sleep_io(sadev, pin, 0);
sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
- ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+ ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
sa11xx_drv_pcmcia_add_one);
}
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index d92692056e24..9fb0c3addfd4 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -563,7 +563,7 @@ static int vrc4173_cardu_setup(char *options)
__setup("vrc4173_cardu=", vrc4173_cardu_setup);
-static DEFINE_PCI_DEVICE_TABLE(vrc4173_cardu_id_table) = {
+static const struct pci_device_id vrc4173_cardu_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NAPCCARD) },
{0, }
};
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 946f90ef6020..8a23ccb41213 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1352,7 +1352,7 @@ static const struct dev_pm_ops yenta_pm_ops = {
.driver_data = CARDBUS_TYPE_##type, \
}
-static DEFINE_PCI_DEVICE_TABLE(yenta_table) = {
+static const struct pci_device_id yenta_table[] = {
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1031, TI),
/*
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index e8f8a2d165d1..0dd742719154 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -15,6 +15,13 @@ config GENERIC_PHY
phy users can obtain reference to the PHY. All the users of this
framework should select this config.
+config PHY_BERLIN_SATA
+ tristate "Marvell Berlin SATA PHY driver"
+ depends on ARCH_BERLIN && HAS_IOMEM && OF
+ select GENERIC_PHY
+ help
+ Enable this to support the SATA PHY on Marvell Berlin SoCs.
+
config PHY_EXYNOS_MIPI_VIDEO
tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
depends on HAS_IOMEM
@@ -27,10 +34,20 @@ config PHY_EXYNOS_MIPI_VIDEO
config PHY_MVEBU_SATA
def_bool y
- depends on ARCH_KIRKWOOD || ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
+ depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
depends on OF
select GENERIC_PHY
+config PHY_MIPHY365X
+ tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
+ depends on ARCH_STI
+ depends on GENERIC_PHY
+ depends on HAS_IOMEM
+ depends on OF
+ help
+ Enable this to support the miphy transceiver (for SATA/PCIE)
+ that is part of STMicroelectronics STiH41x SoC series.
+
config OMAP_CONTROL_PHY
tristate "OMAP CONTROL PHY Driver"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
@@ -109,9 +126,18 @@ config PHY_EXYNOS5250_SATA
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
port to accept one SATA device.
+config PHY_HIX5HD2_SATA
+ tristate "HIX5HD2 SATA PHY Driver"
+ depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
+ select GENERIC_PHY
+ select MFD_SYSCON
+ help
+ Support for SATA PHY on Hisilicon hix5hd2 Soc.
+
config PHY_SUN4I_USB
tristate "Allwinner sunxi SoC USB PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
+ depends on RESET_CONTROLLER
select GENERIC_PHY
help
Enable this to support the transceiver that is part of Allwinner
@@ -122,61 +148,68 @@ config PHY_SUN4I_USB
config PHY_SAMSUNG_USB2
tristate "Samsung USB 2.0 PHY driver"
+ depends on HAS_IOMEM
+ depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
select GENERIC_PHY
select MFD_SYSCON
+ default ARCH_EXYNOS
help
Enable this to support the Samsung USB 2.0 PHY driver for Samsung
- SoCs. This driver provides the interface for USB 2.0 PHY. Support for
- particular SoCs has to be enabled in addition to this driver. Number
- and type of supported phys depends on the SoC.
+ SoCs. This driver provides the interface for USB 2.0 PHY. Support
+ for particular PHYs will be enabled based on the SoC type in addition
+ to this driver.
-config PHY_EXYNOS4210_USB2
- bool "Support for Exynos 4210"
+config PHY_S5PV210_USB2
+ bool "Support for S5PV210"
depends on PHY_SAMSUNG_USB2
- depends on CPU_EXYNOS4210
+ depends on ARCH_S5PV210
help
- Enable USB PHY support for Exynos 4210. This option requires that
- Samsung USB 2.0 PHY driver is enabled and means that support for this
- particular SoC is compiled in the driver. In case of Exynos 4210 four
- phys are available - device, host, HSIC0 and HSIC1.
+ Enable USB PHY support for S5PV210. This option requires that Samsung
+ USB 2.0 PHY driver is enabled and means that support for this
+ particular SoC is compiled in the driver. In case of S5PV210 two phys
+ are available - device and host.
+
+config PHY_EXYNOS4210_USB2
+ bool
+ depends on PHY_SAMSUNG_USB2
+ default CPU_EXYNOS4210
config PHY_EXYNOS4X12_USB2
- bool "Support for Exynos 4x12"
+ bool
depends on PHY_SAMSUNG_USB2
- depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
- help
- Enable USB PHY support for Exynos 4x12. This option requires that
- Samsung USB 2.0 PHY driver is enabled and means that support for this
- particular SoC is compiled in the driver. In case of Exynos 4x12 four
- phys are available - device, host, HSIC0 and HSIC1.
+ default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
config PHY_EXYNOS5250_USB2
- bool "Support for Exynos 5250"
+ bool
depends on PHY_SAMSUNG_USB2
- depends on SOC_EXYNOS5250
- help
- Enable USB PHY support for Exynos 5250. This option requires that
- Samsung USB 2.0 PHY driver is enabled and means that support for this
- particular SoC is compiled in the driver. In case of Exynos 5250 four
- phys are available - device, host, HSIC0 and HSIC.
+ default SOC_EXYNOS5250 || SOC_EXYNOS5420
config PHY_EXYNOS5_USBDRD
tristate "Exynos5 SoC series USB DRD PHY driver"
depends on ARCH_EXYNOS5 && OF
depends on HAS_IOMEM
+ depends on USB_DWC3_EXYNOS
select GENERIC_PHY
select MFD_SYSCON
+ default y
help
Enable USB DRD PHY support for Exynos 5 SoC series.
This driver provides PHY interface for USB 3.0 DRD controller
present on Exynos5 SoC series.
-config PHY_XGENE
- tristate "APM X-Gene 15Gbps PHY support"
- depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
+config PHY_QCOM_APQ8064_SATA
+ tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
+ depends on ARCH_QCOM
+ depends on HAS_IOMEM
+ depends on OF
+ select GENERIC_PHY
+
+config PHY_QCOM_IPQ806X_SATA
+ tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
+ depends on ARCH_QCOM
+ depends on HAS_IOMEM
+ depends on OF
select GENERIC_PHY
- help
- This option enables support for APM X-Gene SoC multi-purpose PHY.
config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
@@ -190,4 +223,11 @@ config PHY_ST_SPEAR1340_MIPHY
help
Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
+config PHY_XGENE
+ tristate "APM X-Gene 15Gbps PHY support"
+ depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ This option enables support for APM X-Gene SoC multi-purpose PHY.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d39609bb38de..95c69ed5ed45 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -3,22 +3,28 @@
#
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
+obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
+obj-$(CONFIG_PHY_MIPHY365X) += phy-miphy365x.o
obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
+obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
phy-exynos-usb2-y += phy-samsung-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
+phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
-obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
+obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
+obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
+obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
diff --git a/drivers/phy/phy-bcm-kona-usb2.c b/drivers/phy/phy-bcm-kona-usb2.c
index e94f5a6a5645..894fe74c1e44 100644
--- a/drivers/phy/phy-bcm-kona-usb2.c
+++ b/drivers/phy/phy-bcm-kona-usb2.c
@@ -117,7 +117,7 @@ static int bcm_kona_usb2_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy);
- gphy = devm_phy_create(dev, &ops, NULL);
+ gphy = devm_phy_create(dev, NULL, &ops, NULL);
if (IS_ERR(gphy))
return PTR_ERR(gphy);
diff --git a/drivers/phy/phy-berlin-sata.c b/drivers/phy/phy-berlin-sata.c
new file mode 100644
index 000000000000..5c3a0424aeb4
--- /dev/null
+++ b/drivers/phy/phy-berlin-sata.c
@@ -0,0 +1,284 @@
+/*
+ * Marvell Berlin SATA PHY driver
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <antoine.tenart@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#define HOST_VSA_ADDR 0x0
+#define HOST_VSA_DATA 0x4
+#define PORT_SCR_CTL 0x2c
+#define PORT_VSR_ADDR 0x78
+#define PORT_VSR_DATA 0x7c
+
+#define CONTROL_REGISTER 0x0
+#define MBUS_SIZE_CONTROL 0x4
+
+#define POWER_DOWN_PHY0 BIT(6)
+#define POWER_DOWN_PHY1 BIT(14)
+#define MBUS_WRITE_REQUEST_SIZE_128 (BIT(2) << 16)
+#define MBUS_READ_REQUEST_SIZE_128 (BIT(2) << 19)
+
+#define PHY_BASE 0x200
+
+/* register 0x01 */
+#define REF_FREF_SEL_25 BIT(0)
+#define PHY_MODE_SATA (0x0 << 5)
+
+/* register 0x02 */
+#define USE_MAX_PLL_RATE BIT(12)
+
+/* register 0x23 */
+#define DATA_BIT_WIDTH_10 (0x0 << 10)
+#define DATA_BIT_WIDTH_20 (0x1 << 10)
+#define DATA_BIT_WIDTH_40 (0x2 << 10)
+
+/* register 0x25 */
+#define PHY_GEN_MAX_1_5 (0x0 << 10)
+#define PHY_GEN_MAX_3_0 (0x1 << 10)
+#define PHY_GEN_MAX_6_0 (0x2 << 10)
+
+struct phy_berlin_desc {
+ struct phy *phy;
+ u32 power_bit;
+ unsigned index;
+};
+
+struct phy_berlin_priv {
+ void __iomem *base;
+ spinlock_t lock;
+ struct clk *clk;
+ struct phy_berlin_desc **phys;
+ unsigned nphys;
+};
+
+static inline void phy_berlin_sata_reg_setbits(void __iomem *ctrl_reg, u32 reg,
+ u32 mask, u32 val)
+{
+ u32 regval;
+
+ /* select register */
+ writel(PHY_BASE + reg, ctrl_reg + PORT_VSR_ADDR);
+
+ /* set bits */
+ regval = readl(ctrl_reg + PORT_VSR_DATA);
+ regval &= ~mask;
+ regval |= val;
+ writel(regval, ctrl_reg + PORT_VSR_DATA);
+}
+
+static int phy_berlin_sata_power_on(struct phy *phy)
+{
+ struct phy_berlin_desc *desc = phy_get_drvdata(phy);
+ struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
+ void __iomem *ctrl_reg = priv->base + 0x60 + (desc->index * 0x80);
+ int ret = 0;
+ u32 regval;
+
+ clk_prepare_enable(priv->clk);
+
+ spin_lock(&priv->lock);
+
+ /* Power on PHY */
+ writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
+ regval = readl(priv->base + HOST_VSA_DATA);
+ regval &= ~desc->power_bit;
+ writel(regval, priv->base + HOST_VSA_DATA);
+
+ /* Configure MBus */
+ writel(MBUS_SIZE_CONTROL, priv->base + HOST_VSA_ADDR);
+ regval = readl(priv->base + HOST_VSA_DATA);
+ regval |= MBUS_WRITE_REQUEST_SIZE_128 | MBUS_READ_REQUEST_SIZE_128;
+ writel(regval, priv->base + HOST_VSA_DATA);
+
+ /* set PHY mode and ref freq to 25 MHz */
+ phy_berlin_sata_reg_setbits(ctrl_reg, 0x1, 0xff,
+ REF_FREF_SEL_25 | PHY_MODE_SATA);
+
+ /* set PHY up to 6 Gbps */
+ phy_berlin_sata_reg_setbits(ctrl_reg, 0x25, 0xc00, PHY_GEN_MAX_6_0);
+
+ /* set 40 bits width */
+ phy_berlin_sata_reg_setbits(ctrl_reg, 0x23, 0xc00, DATA_BIT_WIDTH_40);
+
+ /* use max pll rate */
+ phy_berlin_sata_reg_setbits(ctrl_reg, 0x2, 0x0, USE_MAX_PLL_RATE);
+
+ /* set Gen3 controller speed */
+ regval = readl(ctrl_reg + PORT_SCR_CTL);
+ regval &= ~GENMASK(7, 4);
+ regval |= 0x30;
+ writel(regval, ctrl_reg + PORT_SCR_CTL);
+
+ spin_unlock(&priv->lock);
+
+ clk_disable_unprepare(priv->clk);
+
+ return ret;
+}
+
+static int phy_berlin_sata_power_off(struct phy *phy)
+{
+ struct phy_berlin_desc *desc = phy_get_drvdata(phy);
+ struct phy_berlin_priv *priv = dev_get_drvdata(phy->dev.parent);
+ u32 regval;
+
+ clk_prepare_enable(priv->clk);
+
+ spin_lock(&priv->lock);
+
+ /* Power down PHY */
+ writel(CONTROL_REGISTER, priv->base + HOST_VSA_ADDR);
+ regval = readl(priv->base + HOST_VSA_DATA);
+ regval |= desc->power_bit;
+ writel(regval, priv->base + HOST_VSA_DATA);
+
+ spin_unlock(&priv->lock);
+
+ clk_disable_unprepare(priv->clk);
+
+ return 0;
+}
+
+static struct phy *phy_berlin_sata_phy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct phy_berlin_priv *priv = dev_get_drvdata(dev);
+ int i;
+
+ if (WARN_ON(args->args[0] >= priv->nphys))
+ return ERR_PTR(-ENODEV);
+
+ for (i = 0; i < priv->nphys; i++) {
+ if (priv->phys[i]->index == args->args[0])
+ break;
+ }
+
+ if (i == priv->nphys)
+ return ERR_PTR(-ENODEV);
+
+ return priv->phys[i]->phy;
+}
+
+static struct phy_ops phy_berlin_sata_ops = {
+ .power_on = phy_berlin_sata_power_on,
+ .power_off = phy_berlin_sata_power_off,
+ .owner = THIS_MODULE,
+};
+
+static u32 phy_berlin_power_down_bits[] = {
+ POWER_DOWN_PHY0,
+ POWER_DOWN_PHY1,
+};
+
+static int phy_berlin_sata_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *child;
+ struct phy *phy;
+ struct phy_provider *phy_provider;
+ struct phy_berlin_priv *priv;
+ struct resource *res;
+ int i = 0;
+ u32 phy_id;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
+ priv->base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!priv->base)
+ return -ENOMEM;
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ priv->nphys = of_get_child_count(dev->of_node);
+ if (priv->nphys == 0)
+ return -ENODEV;
+
+ priv->phys = devm_kzalloc(dev, priv->nphys * sizeof(*priv->phys),
+ GFP_KERNEL);
+ if (!priv->phys)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, priv);
+ spin_lock_init(&priv->lock);
+
+ for_each_available_child_of_node(dev->of_node, child) {
+ struct phy_berlin_desc *phy_desc;
+
+ if (of_property_read_u32(child, "reg", &phy_id)) {
+ dev_err(dev, "missing reg property in node %s\n",
+ child->name);
+ return -EINVAL;
+ }
+
+ if (phy_id >= ARRAY_SIZE(phy_berlin_power_down_bits)) {
+ dev_err(dev, "invalid reg in node %s\n", child->name);
+ return -EINVAL;
+ }
+
+ phy_desc = devm_kzalloc(dev, sizeof(*phy_desc), GFP_KERNEL);
+ if (!phy_desc)
+ return -ENOMEM;
+
+ phy = devm_phy_create(dev, NULL, &phy_berlin_sata_ops, NULL);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "failed to create PHY %d\n", phy_id);
+ return PTR_ERR(phy);
+ }
+
+ phy_desc->phy = phy;
+ phy_desc->power_bit = phy_berlin_power_down_bits[phy_id];
+ phy_desc->index = phy_id;
+ phy_set_drvdata(phy, phy_desc);
+
+ priv->phys[i++] = phy_desc;
+
+ /* Make sure the PHY is off */
+ phy_berlin_sata_power_off(phy);
+ }
+
+ phy_provider =
+ devm_of_phy_provider_register(dev, phy_berlin_sata_phy_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ return 0;
+}
+
+static const struct of_device_id phy_berlin_sata_of_match[] = {
+ { .compatible = "marvell,berlin2q-sata-phy" },
+ { },
+};
+
+static struct platform_driver phy_berlin_sata_driver = {
+ .probe = phy_berlin_sata_probe,
+ .driver = {
+ .name = "phy-berlin-sata",
+ .owner = THIS_MODULE,
+ .of_match_table = phy_berlin_sata_of_match,
+ },
+};
+module_platform_driver(phy_berlin_sata_driver);
+
+MODULE_DESCRIPTION("Marvell Berlin SATA PHY driver");
+MODULE_AUTHOR("Antoine Ténart <antoine.tenart@free-electrons.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index c64a2f3b2d62..ff5eec5af817 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -21,6 +21,7 @@
#include <linux/phy/phy.h>
#include <linux/idr.h>
#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
static struct class *phy_class;
static DEFINE_MUTEX(phy_provider_mutex);
@@ -86,10 +87,15 @@ static struct phy *phy_lookup(struct device *device, const char *port)
static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
{
struct phy_provider *phy_provider;
+ struct device_node *child;
list_for_each_entry(phy_provider, &phy_provider_list, list) {
if (phy_provider->dev->of_node == node)
return phy_provider;
+
+ for_each_child_of_node(phy_provider->dev->of_node, child)
+ if (child == node)
+ return phy_provider;
}
return ERR_PTR(-EPROBE_DEFER);
@@ -226,6 +232,12 @@ int phy_power_on(struct phy *phy)
if (!phy)
return 0;
+ if (phy->pwr) {
+ ret = regulator_enable(phy->pwr);
+ if (ret)
+ return ret;
+ }
+
ret = phy_pm_runtime_get_sync(phy);
if (ret < 0 && ret != -ENOTSUPP)
return ret;
@@ -247,6 +259,8 @@ int phy_power_on(struct phy *phy)
out:
mutex_unlock(&phy->mutex);
phy_pm_runtime_put_sync(phy);
+ if (phy->pwr)
+ regulator_disable(phy->pwr);
return ret;
}
@@ -272,6 +286,9 @@ int phy_power_off(struct phy *phy)
mutex_unlock(&phy->mutex);
phy_pm_runtime_put(phy);
+ if (phy->pwr)
+ regulator_disable(phy->pwr);
+
return 0;
}
EXPORT_SYMBOL_GPL(phy_power_off);
@@ -398,13 +415,20 @@ struct phy *of_phy_simple_xlate(struct device *dev, struct of_phandle_args
struct phy *phy;
struct class_dev_iter iter;
struct device_node *node = dev->of_node;
+ struct device_node *child;
class_dev_iter_init(&iter, phy_class, NULL, NULL);
while ((dev = class_dev_iter_next(&iter))) {
phy = to_phy(dev);
- if (node != phy->dev.of_node)
+ if (node != phy->dev.of_node) {
+ for_each_child_of_node(node, child) {
+ if (child == phy->dev.of_node)
+ goto phy_found;
+ }
continue;
+ }
+phy_found:
class_dev_iter_exit(&iter);
return phy;
}
@@ -562,13 +586,15 @@ EXPORT_SYMBOL_GPL(devm_of_phy_get);
/**
* phy_create() - create a new phy
* @dev: device that is creating the new phy
+ * @node: device node of the phy
* @ops: function pointers for performing phy operations
* @init_data: contains the list of PHY consumers or NULL
*
* Called to create a phy using phy framework.
*/
-struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
- struct phy_init_data *init_data)
+struct phy *phy_create(struct device *dev, struct device_node *node,
+ const struct phy_ops *ops,
+ struct phy_init_data *init_data)
{
int ret;
int id;
@@ -588,12 +614,22 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
goto free_phy;
}
+ /* phy-supply */
+ phy->pwr = regulator_get_optional(dev, "phy");
+ if (IS_ERR(phy->pwr)) {
+ if (PTR_ERR(phy->pwr) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto free_ida;
+ }
+ phy->pwr = NULL;
+ }
+
device_initialize(&phy->dev);
mutex_init(&phy->mutex);
phy->dev.class = phy_class;
phy->dev.parent = dev;
- phy->dev.of_node = dev->of_node;
+ phy->dev.of_node = node ?: dev->of_node;
phy->id = id;
phy->ops = ops;
phy->init_data = init_data;
@@ -614,8 +650,12 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
return phy;
put_dev:
- put_device(&phy->dev);
- ida_remove(&phy_ida, phy->id);
+ put_device(&phy->dev); /* calls phy_release() which frees resources */
+ return ERR_PTR(ret);
+
+free_ida:
+ ida_simple_remove(&phy_ida, phy->id);
+
free_phy:
kfree(phy);
return ERR_PTR(ret);
@@ -625,6 +665,7 @@ EXPORT_SYMBOL_GPL(phy_create);
/**
* devm_phy_create() - create a new phy
* @dev: device that is creating the new phy
+ * @node: device node of the phy
* @ops: function pointers for performing phy operations
* @init_data: contains the list of PHY consumers or NULL
*
@@ -633,8 +674,9 @@ EXPORT_SYMBOL_GPL(phy_create);
* On driver detach, release function is invoked on the devres data,
* then, devres data is freed.
*/
-struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
- struct phy_init_data *init_data)
+struct phy *devm_phy_create(struct device *dev, struct device_node *node,
+ const struct phy_ops *ops,
+ struct phy_init_data *init_data)
{
struct phy **ptr, *phy;
@@ -642,7 +684,7 @@ struct phy *devm_phy_create(struct device *dev, const struct phy_ops *ops,
if (!ptr)
return ERR_PTR(-ENOMEM);
- phy = phy_create(dev, ops, init_data);
+ phy = phy_create(dev, node, ops, init_data);
if (!IS_ERR(phy)) {
*ptr = phy;
devres_add(dev, ptr);
@@ -799,7 +841,8 @@ static void phy_release(struct device *dev)
phy = to_phy(dev);
dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
- ida_remove(&phy_ida, phy->id);
+ regulator_put(phy->pwr);
+ ida_simple_remove(&phy_ida, phy->id);
kfree(phy);
}
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c
index 0786fef842e7..8b3026e2af7f 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -76,7 +77,7 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
if (IS_ERR(state->regs))
return PTR_ERR(state->regs);
- phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL);
+ phy = devm_phy_create(dev, NULL, &exynos_dp_video_phy_ops, NULL);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create Display Port PHY\n");
return PTR_ERR(phy);
@@ -84,10 +85,8 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev)
phy_set_drvdata(phy, state);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- if (IS_ERR(phy_provider))
- return PTR_ERR(phy_provider);
- return 0;
+ return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id exynos_dp_video_phy_of_match[] = {
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
index ff026689358c..b55a92e12496 100644
--- a/drivers/phy/phy-exynos-mipi-video.c
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -135,7 +136,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
spin_lock_init(&state->slock);
for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
- struct phy *phy = devm_phy_create(dev,
+ struct phy *phy = devm_phy_create(dev, NULL,
&exynos_mipi_video_phy_ops, NULL);
if (IS_ERR(phy)) {
dev_err(dev, "failed to create PHY %d\n", i);
@@ -149,10 +150,8 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
phy_provider = devm_of_phy_provider_register(dev,
exynos_mipi_video_phy_xlate);
- if (IS_ERR(phy_provider))
- return PTR_ERR(phy_provider);
- return 0;
+ return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c
index d92a7cc5698a..0b9de88579b1 100644
--- a/drivers/phy/phy-exynos4x12-usb2.c
+++ b/drivers/phy/phy-exynos4x12-usb2.c
@@ -67,6 +67,8 @@
#define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0)
#define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0)
+#define EXYNOS_3250_UPHYCLK_REFCLKSEL (0x2 << 8)
+
#define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3)
#define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4)
#define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7)
@@ -86,13 +88,23 @@
#define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1)
#define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2)
#define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3)
+/* The following bit defines are presented in the
+ * order taken from the Exynos4412 reference manual.
+ *
+ * During experiments with the hardware and debugging
+ * it was determined that the hardware behaves contrary
+ * to the manual.
+ *
+ * The following bit values were chaned accordingly to the
+ * results of real hardware experiments.
+ */
#define EXYNOS_4x12_URSTCON_PHY1 BIT(4)
-#define EXYNOS_4x12_URSTCON_HSIC0 BIT(5)
-#define EXYNOS_4x12_URSTCON_HSIC1 BIT(6)
+#define EXYNOS_4x12_URSTCON_HSIC0 BIT(6)
+#define EXYNOS_4x12_URSTCON_HSIC1 BIT(5)
#define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7)
-#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8)
+#define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(10)
#define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9)
-#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(10)
+#define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(8)
/* Isolation, configured in the power management unit */
#define EXYNOS_4x12_USB_ISOL_OFFSET 0x704
@@ -187,7 +199,12 @@ static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst)
clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK);
clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK;
+
+ if (drv->cfg->has_refclk_sel)
+ clk = EXYNOS_3250_UPHYCLK_REFCLKSEL;
+
clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET;
+ clk |= EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON;
writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK);
}
@@ -198,27 +215,22 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
u32 phypwr = 0;
u32 rst;
u32 pwr;
- u32 mode = 0;
- u32 switch_mode = 0;
switch (inst->cfg->id) {
case EXYNOS4x12_DEVICE:
phypwr = EXYNOS_4x12_UPHYPWR_PHY0;
rstbits = EXYNOS_4x12_URSTCON_PHY0;
- mode = EXYNOS_4x12_MODE_SWITCH_DEVICE;
- switch_mode = 1;
break;
case EXYNOS4x12_HOST:
phypwr = EXYNOS_4x12_UPHYPWR_PHY1;
- rstbits = EXYNOS_4x12_URSTCON_HOST_PHY;
- mode = EXYNOS_4x12_MODE_SWITCH_HOST;
- switch_mode = 1;
+ rstbits = EXYNOS_4x12_URSTCON_HOST_PHY |
+ EXYNOS_4x12_URSTCON_PHY1 |
+ EXYNOS_4x12_URSTCON_HOST_LINK_P0;
break;
case EXYNOS4x12_HSIC0:
phypwr = EXYNOS_4x12_UPHYPWR_HSIC0;
- rstbits = EXYNOS_4x12_URSTCON_HSIC1 |
- EXYNOS_4x12_URSTCON_HOST_LINK_P0 |
- EXYNOS_4x12_URSTCON_HOST_PHY;
+ rstbits = EXYNOS_4x12_URSTCON_HSIC0 |
+ EXYNOS_4x12_URSTCON_HOST_LINK_P1;
break;
case EXYNOS4x12_HSIC1:
phypwr = EXYNOS_4x12_UPHYPWR_HSIC1;
@@ -228,11 +240,6 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
};
if (on) {
- if (switch_mode)
- regmap_update_bits(drv->reg_sys,
- EXYNOS_4x12_MODE_SWITCH_OFFSET,
- EXYNOS_4x12_MODE_SWITCH_MASK, mode);
-
pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR);
pwr &= ~phypwr;
writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR);
@@ -253,41 +260,78 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
}
}
-static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
+static void exynos4x12_power_on_int(struct samsung_usb2_phy_instance *inst)
{
- struct samsung_usb2_phy_driver *drv = inst->drv;
+ if (inst->int_cnt++ > 0)
+ return;
- inst->enabled = 1;
exynos4x12_setup_clk(inst);
- exynos4x12_phy_pwr(inst, 1);
exynos4x12_isol(inst, 0);
+ exynos4x12_phy_pwr(inst, 1);
+}
+
+static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
+{
+ struct samsung_usb2_phy_driver *drv = inst->drv;
+
+ if (inst->ext_cnt++ > 0)
+ return 0;
- /* Power on the device, as it is necessary for HSIC to work */
- if (inst->cfg->id == EXYNOS4x12_HSIC0) {
- struct samsung_usb2_phy_instance *device =
- &drv->instances[EXYNOS4x12_DEVICE];
- exynos4x12_phy_pwr(device, 1);
- exynos4x12_isol(device, 0);
+ if (inst->cfg->id == EXYNOS4x12_HOST) {
+ regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+ EXYNOS_4x12_MODE_SWITCH_MASK,
+ EXYNOS_4x12_MODE_SWITCH_HOST);
+ exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
}
+ if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch)
+ regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+ EXYNOS_4x12_MODE_SWITCH_MASK,
+ EXYNOS_4x12_MODE_SWITCH_DEVICE);
+
+ if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+ inst->cfg->id == EXYNOS4x12_HSIC1) {
+ exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
+ exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_HOST]);
+ }
+
+ exynos4x12_power_on_int(inst);
+
return 0;
}
-static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst)
+static void exynos4x12_power_off_int(struct samsung_usb2_phy_instance *inst)
{
- struct samsung_usb2_phy_driver *drv = inst->drv;
- struct samsung_usb2_phy_instance *device =
- &drv->instances[EXYNOS4x12_DEVICE];
+ if (inst->int_cnt-- > 1)
+ return;
- inst->enabled = 0;
exynos4x12_isol(inst, 1);
exynos4x12_phy_pwr(inst, 0);
+}
+
+static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst)
+{
+ struct samsung_usb2_phy_driver *drv = inst->drv;
+
+ if (inst->ext_cnt-- > 1)
+ return 0;
+
+ if (inst->cfg->id == EXYNOS4x12_DEVICE && drv->cfg->has_mode_switch)
+ regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+ EXYNOS_4x12_MODE_SWITCH_MASK,
+ EXYNOS_4x12_MODE_SWITCH_HOST);
+
+ if (inst->cfg->id == EXYNOS4x12_HOST)
+ exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
- if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) {
- exynos4x12_isol(device, 1);
- exynos4x12_phy_pwr(device, 0);
+ if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+ inst->cfg->id == EXYNOS4x12_HSIC1) {
+ exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
+ exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_HOST]);
}
+ exynos4x12_power_off_int(inst);
+
return 0;
}
@@ -320,6 +364,13 @@ static const struct samsung_usb2_common_phy exynos4x12_phys[] = {
{},
};
+const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = {
+ .has_refclk_sel = 1,
+ .num_phys = 1,
+ .phys = exynos4x12_phys,
+ .rate_to_clk = exynos4x12_rate_to_clk,
+};
+
const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config = {
.has_mode_switch = 1,
.num_phys = EXYNOS4x12_NUM_PHYS,
diff --git a/drivers/phy/phy-exynos5-usbdrd.c b/drivers/phy/phy-exynos5-usbdrd.c
index 76d862b2202f..b05302b09c9f 100644
--- a/drivers/phy/phy-exynos5-usbdrd.c
+++ b/drivers/phy/phy-exynos5-usbdrd.c
@@ -506,7 +506,7 @@ static struct phy_ops exynos5_usbdrd_phy_ops = {
.owner = THIS_MODULE,
};
-const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
+static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
{
.id = EXYNOS5_DRDPHY_UTMI,
.phy_isol = exynos5_usbdrd_phy_isol,
@@ -521,13 +521,13 @@ const struct exynos5_usbdrd_phy_config phy_cfg_exynos5[] = {
},
};
-const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
+static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy = {
.phy_cfg = phy_cfg_exynos5,
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
.pmu_offset_usbdrd1_phy = EXYNOS5420_USBDRD1_PHY_CONTROL,
};
-const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = {
+static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy = {
.phy_cfg = phy_cfg_exynos5,
.pmu_offset_usbdrd0_phy = EXYNOS5_USBDRD_PHY_CONTROL,
};
@@ -635,7 +635,8 @@ static int exynos5_usbdrd_phy_probe(struct platform_device *pdev)
dev_vdbg(dev, "Creating usbdrd_phy phy\n");
for (i = 0; i < EXYNOS5_DRDPHYS_NUM; i++) {
- struct phy *phy = devm_phy_create(dev, &exynos5_usbdrd_phy_ops,
+ struct phy *phy = devm_phy_create(dev, NULL,
+ &exynos5_usbdrd_phy_ops,
NULL);
if (IS_ERR(phy)) {
dev_err(dev, "Failed to create usbdrd_phy phy\n");
diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c
index 05689450f93b..19a679aca4ac 100644
--- a/drivers/phy/phy-exynos5250-sata.c
+++ b/drivers/phy/phy-exynos5250-sata.c
@@ -210,7 +210,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
return ret;
}
- sata_phy->phy = devm_phy_create(dev, &exynos_sata_phy_ops, NULL);
+ sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops, NULL);
if (IS_ERR(sata_phy->phy)) {
clk_disable_unprepare(sata_phy->phyclk);
dev_err(dev, "failed to create PHY\n");
diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c
index 94179afda951..1c139aa0d074 100644
--- a/drivers/phy/phy-exynos5250-usb2.c
+++ b/drivers/phy/phy-exynos5250-usb2.c
@@ -318,7 +318,6 @@ static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst)
break;
}
- inst->enabled = 1;
exynos5250_isol(inst, 0);
return 0;
@@ -331,7 +330,6 @@ static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst)
u32 otg;
u32 hsic;
- inst->enabled = 0;
exynos5250_isol(inst, 1);
switch (inst->cfg->id) {
diff --git a/drivers/phy/phy-hix5hd2-sata.c b/drivers/phy/phy-hix5hd2-sata.c
new file mode 100644
index 000000000000..6a08fa5f81eb
--- /dev/null
+++ b/drivers/phy/phy-hix5hd2-sata.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2014 Linaro Ltd.
+ * Copyright (c) 2014 Hisilicon Limited.
+ *
+ * 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/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define SATA_PHY0_CTLL 0xa0
+#define MPLL_MULTIPLIER_SHIFT 1
+#define MPLL_MULTIPLIER_MASK 0xfe
+#define MPLL_MULTIPLIER_50M 0x3c
+#define MPLL_MULTIPLIER_100M 0x1e
+#define PHY_RESET BIT(0)
+#define REF_SSP_EN BIT(9)
+#define SSC_EN BIT(10)
+#define REF_USE_PAD BIT(23)
+
+#define SATA_PORT_PHYCTL 0x174
+#define SPEED_MODE_MASK 0x6f0000
+#define HALF_RATE_SHIFT 16
+#define PHY_CONFIG_SHIFT 18
+#define GEN2_EN_SHIFT 21
+#define SPEED_CTRL BIT(20)
+
+#define SATA_PORT_PHYCTL1 0x148
+#define AMPLITUDE_MASK 0x3ffffe
+#define AMPLITUDE_GEN3 0x68
+#define AMPLITUDE_GEN3_SHIFT 15
+#define AMPLITUDE_GEN2 0x56
+#define AMPLITUDE_GEN2_SHIFT 8
+#define AMPLITUDE_GEN1 0x56
+#define AMPLITUDE_GEN1_SHIFT 1
+
+#define SATA_PORT_PHYCTL2 0x14c
+#define PREEMPH_MASK 0x3ffff
+#define PREEMPH_GEN3 0x20
+#define PREEMPH_GEN3_SHIFT 12
+#define PREEMPH_GEN2 0x15
+#define PREEMPH_GEN2_SHIFT 6
+#define PREEMPH_GEN1 0x5
+#define PREEMPH_GEN1_SHIFT 0
+
+struct hix5hd2_priv {
+ void __iomem *base;
+ struct regmap *peri_ctrl;
+};
+
+enum phy_speed_mode {
+ SPEED_MODE_GEN1 = 0,
+ SPEED_MODE_GEN2 = 1,
+ SPEED_MODE_GEN3 = 2,
+};
+
+static int hix5hd2_sata_phy_init(struct phy *phy)
+{
+ struct hix5hd2_priv *priv = phy_get_drvdata(phy);
+ u32 val, data[2];
+ int ret;
+
+ if (priv->peri_ctrl) {
+ ret = of_property_read_u32_array(phy->dev.of_node,
+ "hisilicon,power-reg",
+ &data[0], 2);
+ if (ret) {
+ dev_err(&phy->dev, "Fail read hisilicon,power-reg\n");
+ return ret;
+ }
+
+ regmap_update_bits(priv->peri_ctrl, data[0],
+ BIT(data[1]), BIT(data[1]));
+ }
+
+ /* reset phy */
+ val = readl_relaxed(priv->base + SATA_PHY0_CTLL);
+ val &= ~(MPLL_MULTIPLIER_MASK | REF_USE_PAD);
+ val |= MPLL_MULTIPLIER_50M << MPLL_MULTIPLIER_SHIFT |
+ REF_SSP_EN | PHY_RESET;
+ writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
+ msleep(20);
+ val &= ~PHY_RESET;
+ writel_relaxed(val, priv->base + SATA_PHY0_CTLL);
+
+ val = readl_relaxed(priv->base + SATA_PORT_PHYCTL1);
+ val &= ~AMPLITUDE_MASK;
+ val |= AMPLITUDE_GEN3 << AMPLITUDE_GEN3_SHIFT |
+ AMPLITUDE_GEN2 << AMPLITUDE_GEN2_SHIFT |
+ AMPLITUDE_GEN1 << AMPLITUDE_GEN1_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL1);
+
+ val = readl_relaxed(priv->base + SATA_PORT_PHYCTL2);
+ val &= ~PREEMPH_MASK;
+ val |= PREEMPH_GEN3 << PREEMPH_GEN3_SHIFT |
+ PREEMPH_GEN2 << PREEMPH_GEN2_SHIFT |
+ PREEMPH_GEN1 << PREEMPH_GEN1_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL2);
+
+ /* ensure PHYCTRL setting takes effect */
+ val = readl_relaxed(priv->base + SATA_PORT_PHYCTL);
+ val &= ~SPEED_MODE_MASK;
+ val |= SPEED_MODE_GEN1 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN1 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN1 << GEN2_EN_SHIFT | SPEED_CTRL;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
+
+ msleep(20);
+ val &= ~SPEED_MODE_MASK;
+ val |= SPEED_MODE_GEN3 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN3 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN3 << GEN2_EN_SHIFT | SPEED_CTRL;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
+
+ val &= ~(SPEED_MODE_MASK | SPEED_CTRL);
+ val |= SPEED_MODE_GEN2 << HALF_RATE_SHIFT |
+ SPEED_MODE_GEN2 << PHY_CONFIG_SHIFT |
+ SPEED_MODE_GEN2 << GEN2_EN_SHIFT;
+ writel_relaxed(val, priv->base + SATA_PORT_PHYCTL);
+
+ return 0;
+}
+
+static struct phy_ops hix5hd2_sata_phy_ops = {
+ .init = hix5hd2_sata_phy_init,
+ .owner = THIS_MODULE,
+};
+
+static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct phy *phy;
+ struct hix5hd2_priv *priv;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!priv->base)
+ return -ENOMEM;
+
+ priv->peri_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "hisilicon,peripheral-syscon");
+ if (IS_ERR(priv->peri_ctrl))
+ priv->peri_ctrl = NULL;
+
+ phy = devm_phy_create(dev, NULL, &hix5hd2_sata_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ dev_err(dev, "failed to create PHY\n");
+ return PTR_ERR(phy);
+ }
+
+ phy_set_drvdata(phy, priv);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider))
+ return PTR_ERR(phy_provider);
+
+ return 0;
+}
+
+static const struct of_device_id hix5hd2_sata_phy_of_match[] = {
+ {.compatible = "hisilicon,hix5hd2-sata-phy",},
+ { },
+};
+MODULE_DEVICE_TABLE(of, hix5hd2_sata_phy_of_match);
+
+static struct platform_driver hix5hd2_sata_phy_driver = {
+ .probe = hix5hd2_sata_phy_probe,
+ .driver = {
+ .name = "hix5hd2-sata-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = hix5hd2_sata_phy_of_match,
+ }
+};
+module_platform_driver(hix5hd2_sata_phy_driver);
+
+MODULE_AUTHOR("Jiancheng Xue <xuejiancheng@huawei.com>");
+MODULE_DESCRIPTION("HISILICON HIX5HD2 SATA PHY driver");
+MODULE_ALIAS("platform:hix5hd2-sata-phy");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
new file mode 100644
index 000000000000..e111baf187ce
--- /dev/null
+++ b/drivers/phy/phy-miphy365x.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics – All Rights Reserved
+ *
+ * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416).
+ *
+ * Authors: Alexandre Torgue <alexandre.torgue@st.com>
+ * Lee Jones <lee.jones@linaro.org>
+ *
+ * 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/phy/phy-miphy365x.h>
+
+#define HFC_TIMEOUT 100
+
+#define SYSCFG_SELECT_SATA_MASK BIT(1)
+#define SYSCFG_SELECT_SATA_POS 1
+
+/* MiPHY365x register definitions */
+#define RESET_REG 0x00
+#define RST_PLL BIT(1)
+#define RST_PLL_CAL BIT(2)
+#define RST_RX BIT(4)
+#define RST_MACRO BIT(7)
+
+#define STATUS_REG 0x01
+#define IDLL_RDY BIT(0)
+#define PLL_RDY BIT(1)
+#define DES_BIT_LOCK BIT(2)
+#define DES_SYMBOL_LOCK BIT(3)
+
+#define CTRL_REG 0x02
+#define TERM_EN BIT(0)
+#define PCI_EN BIT(2)
+#define DES_BIT_LOCK_EN BIT(3)
+#define TX_POL BIT(5)
+
+#define INT_CTRL_REG 0x03
+
+#define BOUNDARY1_REG 0x10
+#define SPDSEL_SEL BIT(0)
+
+#define BOUNDARY3_REG 0x12
+#define TX_SPDSEL_GEN1_VAL 0
+#define TX_SPDSEL_GEN2_VAL 0x01
+#define TX_SPDSEL_GEN3_VAL 0x02
+#define RX_SPDSEL_GEN1_VAL 0
+#define RX_SPDSEL_GEN2_VAL (0x01 << 3)
+#define RX_SPDSEL_GEN3_VAL (0x02 << 3)
+
+#define PCIE_REG 0x16
+
+#define BUF_SEL_REG 0x20
+#define CONF_GEN_SEL_GEN3 0x02
+#define CONF_GEN_SEL_GEN2 0x01
+#define PD_VDDTFILTER BIT(4)
+
+#define TXBUF1_REG 0x21
+#define SWING_VAL 0x04
+#define SWING_VAL_GEN1 0x03
+#define PREEMPH_VAL (0x3 << 5)
+
+#define TXBUF2_REG 0x22
+#define TXSLEW_VAL 0x2
+#define TXSLEW_VAL_GEN1 0x4
+
+#define RXBUF_OFFSET_CTRL_REG 0x23
+
+#define RXBUF_REG 0x25
+#define SDTHRES_VAL 0x01
+#define EQ_ON3 (0x03 << 4)
+#define EQ_ON1 (0x01 << 4)
+
+#define COMP_CTRL1_REG 0x40
+#define START_COMSR BIT(0)
+#define START_COMZC BIT(1)
+#define COMSR_DONE BIT(2)
+#define COMZC_DONE BIT(3)
+#define COMP_AUTO_LOAD BIT(4)
+
+#define COMP_CTRL2_REG 0x41
+#define COMP_2MHZ_RAT_GEN1 0x1e
+#define COMP_2MHZ_RAT 0xf
+
+#define COMP_CTRL3_REG 0x42
+#define COMSR_COMP_REF 0x33
+
+#define COMP_IDLL_REG 0x47
+#define COMZC_IDLL 0x2a
+
+#define PLL_CTRL1_REG 0x50
+#define PLL_START_CAL BIT(0)
+#define BUF_EN BIT(2)
+#define SYNCHRO_TX BIT(3)
+#define SSC_EN BIT(6)
+#define CONFIG_PLL BIT(7)
+
+#define PLL_CTRL2_REG 0x51
+#define BYPASS_PLL_CAL BIT(1)
+
+#define PLL_RAT_REG 0x52
+
+#define PLL_SSC_STEP_MSB_REG 0x56
+#define PLL_SSC_STEP_MSB_VAL 0x03
+
+#define PLL_SSC_STEP_LSB_REG 0x57
+#define PLL_SSC_STEP_LSB_VAL 0x63
+
+#define PLL_SSC_PER_MSB_REG 0x58
+#define PLL_SSC_PER_MSB_VAL 0
+
+#define PLL_SSC_PER_LSB_REG 0x59
+#define PLL_SSC_PER_LSB_VAL 0xf1
+
+#define IDLL_TEST_REG 0x72
+#define START_CLK_HF BIT(6)
+
+#define DES_BITLOCK_REG 0x86
+#define BIT_LOCK_LEVEL 0x01
+#define BIT_LOCK_CNT_512 (0x03 << 5)
+
+struct miphy365x_phy {
+ struct phy *phy;
+ void __iomem *base;
+ bool pcie_tx_pol_inv;
+ bool sata_tx_pol_inv;
+ u32 sata_gen;
+ u64 ctrlreg;
+ u8 type;
+};
+
+struct miphy365x_dev {
+ struct device *dev;
+ struct regmap *regmap;
+ struct mutex miphy_mutex;
+ struct miphy365x_phy **phys;
+};
+
+/*
+ * These values are represented in Device tree. They are considered to be ABI
+ * and although they can be extended any existing values must not change.
+ */
+enum miphy_sata_gen {
+ SATA_GEN1 = 1,
+ SATA_GEN2,
+ SATA_GEN3
+};
+
+static u8 rx_tx_spd[] = {
+ TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL,
+ TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL,
+ TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL
+};
+
+/*
+ * This function selects the system configuration,
+ * either two SATA, one SATA and one PCIe, or two PCIe lanes.
+ */
+static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ bool sata = (miphy_phy->type == MIPHY_TYPE_SATA);
+
+ return regmap_update_bits(miphy_dev->regmap,
+ (unsigned int)miphy_phy->ctrlreg,
+ SYSCFG_SELECT_SATA_MASK,
+ sata << SYSCFG_SELECT_SATA_POS);
+}
+
+static int miphy365x_init_pcie_port(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ u8 val;
+
+ if (miphy_phy->pcie_tx_pol_inv) {
+ /* Invert Tx polarity and clear pci_txdetect_pol bit */
+ val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL;
+ writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+ writeb_relaxed(0x00, miphy_phy->base + PCIE_REG);
+ }
+
+ return 0;
+}
+
+static inline int miphy365x_hfc_not_rdy(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT);
+ u8 mask = IDLL_RDY | PLL_RDY;
+ u8 regval;
+
+ do {
+ regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+ if (!(regval & mask))
+ return 0;
+
+ usleep_range(2000, 2500);
+ } while (time_before(jiffies, timeout));
+
+ dev_err(miphy_dev->dev, "HFC ready timeout!\n");
+ return -EBUSY;
+}
+
+static inline int miphy365x_rdy(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(HFC_TIMEOUT);
+ u8 mask = IDLL_RDY | PLL_RDY;
+ u8 regval;
+
+ do {
+ regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+ if ((regval & mask) == mask)
+ return 0;
+
+ usleep_range(2000, 2500);
+ } while (time_before(jiffies, timeout));
+
+ dev_err(miphy_dev->dev, "PHY not ready timeout!\n");
+ return -EBUSY;
+}
+
+static inline void miphy365x_set_comp(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ u8 val, mask;
+
+ if (miphy_phy->sata_gen == SATA_GEN1)
+ writeb_relaxed(COMP_2MHZ_RAT_GEN1,
+ miphy_phy->base + COMP_CTRL2_REG);
+ else
+ writeb_relaxed(COMP_2MHZ_RAT,
+ miphy_phy->base + COMP_CTRL2_REG);
+
+ if (miphy_phy->sata_gen != SATA_GEN3) {
+ writeb_relaxed(COMSR_COMP_REF,
+ miphy_phy->base + COMP_CTRL3_REG);
+ /*
+ * Force VCO current to value defined by address 0x5A
+ * and disable PCIe100Mref bit
+ * Enable auto load compensation for pll_i_bias
+ */
+ writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG);
+ writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG);
+ }
+
+ /*
+ * Force restart compensation and enable auto load
+ * for Comzc_Tx, Comzc_Rx and Comsr on macro
+ */
+ val = START_COMSR | START_COMZC | COMP_AUTO_LOAD;
+ writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG);
+
+ mask = COMSR_DONE | COMZC_DONE;
+ while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask) != mask)
+ cpu_relax();
+}
+
+static inline void miphy365x_set_ssc(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ u8 val;
+
+ /*
+ * SSC Settings. SSC will be enabled through Link
+ * SSC Ampl. = 0.4%
+ * SSC Freq = 31KHz
+ */
+ writeb_relaxed(PLL_SSC_STEP_MSB_VAL,
+ miphy_phy->base + PLL_SSC_STEP_MSB_REG);
+ writeb_relaxed(PLL_SSC_STEP_LSB_VAL,
+ miphy_phy->base + PLL_SSC_STEP_LSB_REG);
+ writeb_relaxed(PLL_SSC_PER_MSB_VAL,
+ miphy_phy->base + PLL_SSC_PER_MSB_REG);
+ writeb_relaxed(PLL_SSC_PER_LSB_VAL,
+ miphy_phy->base + PLL_SSC_PER_LSB_REG);
+
+ /* SSC Settings complete */
+ if (miphy_phy->sata_gen == SATA_GEN1) {
+ val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+ writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+ } else {
+ val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+ writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+ }
+}
+
+static int miphy365x_init_sata_port(struct miphy365x_phy *miphy_phy,
+ struct miphy365x_dev *miphy_dev)
+{
+ int ret;
+ u8 val;
+
+ /*
+ * Force PHY macro reset, PLL calibration reset, PLL reset
+ * and assert Deserializer Reset
+ */
+ val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO;
+ writeb_relaxed(val, miphy_phy->base + RESET_REG);
+
+ if (miphy_phy->sata_tx_pol_inv)
+ writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG);
+
+ /*
+ * Force macro1 to use rx_lspd, tx_lspd
+ * Force Rx_Clock on first I-DLL phase
+ * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3
+ */
+ writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG);
+ writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG);
+ val = rx_tx_spd[miphy_phy->sata_gen];
+ writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG);
+
+ /* Wait for HFC_READY = 0 */
+ ret = miphy365x_hfc_not_rdy(miphy_phy, miphy_dev);
+ if (ret)
+ return ret;
+
+ /* Compensation Recalibration */
+ miphy365x_set_comp(miphy_phy, miphy_dev);
+
+ switch (miphy_phy->sata_gen) {
+ case SATA_GEN3:
+ /*
+ * TX Swing target 550-600mv peak to peak diff
+ * Tx Slew target 90-110ps rising/falling time
+ * Rx Eq ON3, Sigdet threshold SDTH1
+ */
+ val = PD_VDDTFILTER | CONF_GEN_SEL_GEN3;
+ writeb_relaxed(val, miphy_phy->base + BUF_SEL_REG);
+ val = SWING_VAL | PREEMPH_VAL;
+ writeb_relaxed(val, miphy_phy->base + TXBUF1_REG);
+ writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+ writeb_relaxed(0x00, miphy_phy->base + RXBUF_OFFSET_CTRL_REG);
+ val = SDTHRES_VAL | EQ_ON3;
+ writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+ break;
+ case SATA_GEN2:
+ /*
+ * conf gen sel=0x1 to program Gen2 banked registers
+ * VDDT filter ON
+ * Tx Swing target 550-600mV peak-to-peak diff
+ * Tx Slew target 90-110 ps rising/falling time
+ * RX Equalization ON1, Sigdet threshold SDTH1
+ */
+ writeb_relaxed(CONF_GEN_SEL_GEN2,
+ miphy_phy->base + BUF_SEL_REG);
+ writeb_relaxed(SWING_VAL, miphy_phy->base + TXBUF1_REG);
+ writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+ val = SDTHRES_VAL | EQ_ON1;
+ writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+ break;
+ case SATA_GEN1:
+ /*
+ * conf gen sel = 00b to program Gen1 banked registers
+ * VDDT filter ON
+ * Tx Swing target 500-550mV peak-to-peak diff
+ * Tx Slew target120-140 ps rising/falling time
+ */
+ writeb_relaxed(PD_VDDTFILTER, miphy_phy->base + BUF_SEL_REG);
+ writeb_relaxed(SWING_VAL_GEN1, miphy_phy->base + TXBUF1_REG);
+ writeb_relaxed(TXSLEW_VAL_GEN1, miphy_phy->base + TXBUF2_REG);
+ break;
+ default:
+ break;
+ }
+
+ /* Force Macro1 in partial mode & release pll cal reset */
+ writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+ usleep_range(100, 150);
+
+ miphy365x_set_ssc(miphy_phy, miphy_dev);
+
+ /* Wait for phy_ready */
+ ret = miphy365x_rdy(miphy_phy, miphy_dev);
+ if (ret)
+ return ret;
+
+ /*
+ * Enable macro1 to use rx_lspd & tx_lspd
+ * Release Rx_Clock on first I-DLL phase on macro1
+ * Assert deserializer reset
+ * des_bit_lock_en is set
+ * bit lock detection strength
+ * Deassert deserializer reset
+ */
+ writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG);
+ writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG);
+ writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+ val = miphy_phy->sata_tx_pol_inv ?
+ (TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN;
+ writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+
+ val = BIT_LOCK_CNT_512 | BIT_LOCK_LEVEL;
+ writeb_relaxed(val, miphy_phy->base + DES_BITLOCK_REG);
+ writeb_relaxed(0x00, miphy_phy->base + RESET_REG);
+
+ return 0;
+}
+
+static int miphy365x_init(struct phy *phy)
+{
+ struct miphy365x_phy *miphy_phy = phy_get_drvdata(phy);
+ struct miphy365x_dev *miphy_dev = dev_get_drvdata(phy->dev.parent);
+ int ret = 0;
+
+ mutex_lock(&miphy_dev->miphy_mutex);
+
+ ret = miphy365x_set_path(miphy_phy, miphy_dev);
+ if (ret) {
+ mutex_unlock(&miphy_dev->miphy_mutex);
+ return ret;
+ }
+
+ /* Initialise Miphy for PCIe or SATA */
+ if (miphy_phy->type == MIPHY_TYPE_PCIE)
+ ret = miphy365x_init_pcie_port(miphy_phy, miphy_dev);
+ else
+ ret = miphy365x_init_sata_port(miphy_phy, miphy_dev);
+
+ mutex_unlock(&miphy_dev->miphy_mutex);
+
+ return ret;
+}
+
+int miphy365x_get_addr(struct device *dev, struct miphy365x_phy *miphy_phy,
+ int index)
+{
+ struct device_node *phynode = miphy_phy->phy->dev.of_node;
+ const char *name;
+ const __be32 *taddr;
+ int type = miphy_phy->type;
+ int ret;
+
+ ret = of_property_read_string_index(phynode, "reg-names", index, &name);
+ if (ret) {
+ dev_err(dev, "no reg-names property not found\n");
+ return ret;
+ }
+
+ if (!strncmp(name, "syscfg", 6)) {
+ taddr = of_get_address(phynode, index, NULL, NULL);
+ if (!taddr) {
+ dev_err(dev, "failed to fetch syscfg address\n");
+ return -EINVAL;
+ }
+
+ miphy_phy->ctrlreg = of_translate_address(phynode, taddr);
+ if (miphy_phy->ctrlreg == OF_BAD_ADDR) {
+ dev_err(dev, "failed to translate syscfg address\n");
+ return -EINVAL;
+ }
+
+ return 0;
+ }
+
+ if (!((!strncmp(name, "sata", 4) && type == MIPHY_TYPE_SATA) ||
+ (!strncmp(name, "pcie", 4) && type == MIPHY_TYPE_PCIE)))
+ return 0;
+
+ miphy_phy->base = of_iomap(phynode, index);
+ if (!miphy_phy->base) {
+ dev_err(dev, "Failed to map %s\n", phynode->full_name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct phy *miphy365x_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct miphy365x_dev *miphy_dev = dev_get_drvdata(dev);
+ struct miphy365x_phy *miphy_phy = NULL;
+ struct device_node *phynode = args->np;
+ int ret, index;
+
+ if (!of_device_is_available(phynode)) {
+ dev_warn(dev, "Requested PHY is disabled\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (args->args_count != 1) {
+ dev_err(dev, "Invalid number of cells in 'phy' property\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (index = 0; index < of_get_child_count(dev->of_node); index++)
+ if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
+ miphy_phy = miphy_dev->phys[index];
+ break;
+ }
+
+ if (!miphy_phy) {
+ dev_err(dev, "Failed to find appropriate phy\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ miphy_phy->type = args->args[0];
+
+ if (!(miphy_phy->type == MIPHY_TYPE_SATA ||
+ miphy_phy->type == MIPHY_TYPE_PCIE)) {
+ dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type);
+ return ERR_PTR(-EINVAL);
+ }
+
+ /* Each port handles SATA and PCIE - third entry is always sysconf. */
+ for (index = 0; index < 3; index++) {
+ ret = miphy365x_get_addr(dev, miphy_phy, index);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ }
+
+ return miphy_phy->phy;
+}
+
+static struct phy_ops miphy365x_ops = {
+ .init = miphy365x_init,
+ .owner = THIS_MODULE,
+};
+
+static int miphy365x_of_probe(struct device_node *phynode,
+ struct miphy365x_phy *miphy_phy)
+{
+ of_property_read_u32(phynode, "st,sata-gen", &miphy_phy->sata_gen);
+ if (!miphy_phy->sata_gen)
+ miphy_phy->sata_gen = SATA_GEN1;
+
+ miphy_phy->pcie_tx_pol_inv =
+ of_property_read_bool(phynode, "st,pcie-tx-pol-inv");
+
+ miphy_phy->sata_tx_pol_inv =
+ of_property_read_bool(phynode, "st,sata-tx-pol-inv");
+
+ return 0;
+}
+
+static int miphy365x_probe(struct platform_device *pdev)
+{
+ struct device_node *child, *np = pdev->dev.of_node;
+ struct miphy365x_dev *miphy_dev;
+ struct phy_provider *provider;
+ struct phy *phy;
+ int chancount, port = 0;
+ int ret;
+
+ miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
+ if (!miphy_dev)
+ return -ENOMEM;
+
+ chancount = of_get_child_count(np);
+ miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
+ GFP_KERNEL);
+ if (!miphy_dev->phys)
+ return -ENOMEM;
+
+ miphy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+ if (IS_ERR(miphy_dev->regmap)) {
+ dev_err(miphy_dev->dev, "No syscfg phandle specified\n");
+ return PTR_ERR(miphy_dev->regmap);
+ }
+
+ miphy_dev->dev = &pdev->dev;
+
+ dev_set_drvdata(&pdev->dev, miphy_dev);
+
+ mutex_init(&miphy_dev->miphy_mutex);
+
+ for_each_child_of_node(np, child) {
+ struct miphy365x_phy *miphy_phy;
+
+ miphy_phy = devm_kzalloc(&pdev->dev, sizeof(*miphy_phy),
+ GFP_KERNEL);
+ if (!miphy_phy)
+ return -ENOMEM;
+
+ miphy_dev->phys[port] = miphy_phy;
+
+ phy = devm_phy_create(&pdev->dev, child, &miphy365x_ops, NULL);
+ if (IS_ERR(phy)) {
+ dev_err(&pdev->dev, "failed to create PHY\n");
+ return PTR_ERR(phy);
+ }
+
+ miphy_dev->phys[port]->phy = phy;
+
+ ret = miphy365x_of_probe(child, miphy_phy);
+ if (ret)
+ return ret;
+
+ phy_set_drvdata(phy, miphy_dev->phys[port]);
+ port++;
+ }
+
+ provider = devm_of_phy_provider_register(&pdev->dev, miphy365x_xlate);
+ if (IS_ERR(provider))
+ return PTR_ERR(provider);
+
+ return 0;
+}
+
+static const struct of_device_id miphy365x_of_match[] = {
+ { .compatible = "st,miphy365x-phy", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, miphy365x_of_match);
+
+static struct platform_driver miphy365x_driver = {
+ .probe = miphy365x_probe,
+ .driver = {
+ .name = "miphy365x-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = miphy365x_of_match,
+ }
+};
+module_platform_driver(miphy365x_driver);
+
+MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics miphy365x driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c
index d70ecd6a1b3f..cc3c0e166daf 100644
--- a/drivers/phy/phy-mvebu-sata.c
+++ b/drivers/phy/phy-mvebu-sata.c
@@ -99,7 +99,7 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev)
if (IS_ERR(priv->clk))
return PTR_ERR(priv->clk);
- phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL);
+ phy = devm_phy_create(&pdev->dev, NULL, &phy_mvebu_sata_ops, NULL);
if (IS_ERR(phy))
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c
index 311b4f9a5132..9487bf112267 100644
--- a/drivers/phy/phy-omap-control.c
+++ b/drivers/phy/phy-omap-control.c
@@ -27,6 +27,41 @@
#include <linux/phy/omap_control_phy.h>
/**
+ * omap_control_pcie_pcs - set the PCS delay count
+ * @dev: the control module device
+ * @id: index of the pcie PHY (should be 1 or 2)
+ * @delay: 8 bit delay value
+ */
+void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay)
+{
+ u32 val;
+ struct omap_control_phy *control_phy;
+
+ if (IS_ERR(dev) || !dev) {
+ pr_err("%s: invalid device\n", __func__);
+ return;
+ }
+
+ control_phy = dev_get_drvdata(dev);
+ if (!control_phy) {
+ dev_err(dev, "%s: invalid control phy device\n", __func__);
+ return;
+ }
+
+ if (control_phy->type != OMAP_CTRL_TYPE_PCIE) {
+ dev_err(dev, "%s: unsupported operation\n", __func__);
+ return;
+ }
+
+ val = readl(control_phy->pcie_pcs);
+ val &= ~(OMAP_CTRL_PCIE_PCS_MASK <<
+ (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT));
+ val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT);
+ writel(val, control_phy->pcie_pcs);
+}
+EXPORT_SYMBOL_GPL(omap_control_pcie_pcs);
+
+/**
* omap_control_phy_power - power on/off the phy using control module reg
* @dev: the control module device
* @on: 0 or 1, based on powering on or off the PHY
@@ -61,6 +96,7 @@ void omap_control_phy_power(struct device *dev, int on)
val |= OMAP_CTRL_DEV_PHY_PD;
break;
+ case OMAP_CTRL_TYPE_PCIE:
case OMAP_CTRL_TYPE_PIPE3:
rate = clk_get_rate(control_phy->sys_clk);
rate = rate/1000000;
@@ -211,6 +247,7 @@ EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
static const enum omap_control_phy_type otghs_data = OMAP_CTRL_TYPE_OTGHS;
static const enum omap_control_phy_type usb2_data = OMAP_CTRL_TYPE_USB2;
static const enum omap_control_phy_type pipe3_data = OMAP_CTRL_TYPE_PIPE3;
+static const enum omap_control_phy_type pcie_data = OMAP_CTRL_TYPE_PCIE;
static const enum omap_control_phy_type dra7usb2_data = OMAP_CTRL_TYPE_DRA7USB2;
static const enum omap_control_phy_type am437usb2_data = OMAP_CTRL_TYPE_AM437USB2;
@@ -228,6 +265,10 @@ static const struct of_device_id omap_control_phy_id_table[] = {
.data = &pipe3_data,
},
{
+ .compatible = "ti,control-phy-pcie",
+ .data = &pcie_data,
+ },
+ {
.compatible = "ti,control-phy-usb2-dra7",
.data = &dra7usb2_data,
},
@@ -279,7 +320,8 @@ static int omap_control_phy_probe(struct platform_device *pdev)
}
}
- if (control_phy->type == OMAP_CTRL_TYPE_PIPE3) {
+ if (control_phy->type == OMAP_CTRL_TYPE_PIPE3 ||
+ control_phy->type == OMAP_CTRL_TYPE_PCIE) {
control_phy->sys_clk = devm_clk_get(control_phy->dev,
"sys_clkin");
if (IS_ERR(control_phy->sys_clk)) {
@@ -288,6 +330,14 @@ static int omap_control_phy_probe(struct platform_device *pdev)
}
}
+ if (control_phy->type == OMAP_CTRL_TYPE_PCIE) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "pcie_pcs");
+ control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(control_phy->pcie_pcs))
+ return PTR_ERR(control_phy->pcie_pcs);
+ }
+
dev_set_drvdata(control_phy->dev, control_phy);
return 0;
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 7007c11fe07d..93d78359246c 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -233,8 +233,8 @@ static int omap_usb2_probe(struct platform_device *pdev)
if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
- if (!phy->phy_base)
- return -ENOMEM;
+ if (IS_ERR(phy->phy_base))
+ return PTR_ERR(phy->phy_base);
phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT;
}
@@ -262,18 +262,20 @@ static int omap_usb2_probe(struct platform_device *pdev)
otg->phy = &phy->phy;
platform_set_drvdata(pdev, phy);
- pm_runtime_enable(phy->dev);
- generic_phy = devm_phy_create(phy->dev, &ops, NULL);
+ generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
if (IS_ERR(generic_phy))
return PTR_ERR(generic_phy);
phy_set_drvdata(generic_phy, phy);
+ pm_runtime_enable(phy->dev);
phy_provider = devm_of_phy_provider_register(phy->dev,
of_phy_simple_xlate);
- if (IS_ERR(phy_provider))
+ if (IS_ERR(phy_provider)) {
+ pm_runtime_disable(phy->dev);
return PTR_ERR(phy_provider);
+ }
phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
if (IS_ERR(phy->wkupclk)) {
@@ -317,6 +319,7 @@ static int omap_usb2_remove(struct platform_device *pdev)
if (!IS_ERR(phy->optclk))
clk_unprepare(phy->optclk);
usb_remove_phy(&phy->phy);
+ pm_runtime_disable(phy->dev);
return 0;
}
diff --git a/drivers/phy/phy-qcom-apq8064-sata.c b/drivers/phy/phy-qcom-apq8064-sata.c
new file mode 100644
index 000000000000..b3ef7d805765
--- /dev/null
+++ b/drivers/phy/phy-qcom-apq8064-sata.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+/* PHY registers */
+#define UNIPHY_PLL_REFCLK_CFG 0x000
+#define UNIPHY_PLL_PWRGEN_CFG 0x014
+#define UNIPHY_PLL_GLB_CFG 0x020
+#define UNIPHY_PLL_SDM_CFG0 0x038
+#define UNIPHY_PLL_SDM_CFG1 0x03C
+#define UNIPHY_PLL_SDM_CFG2 0x040
+#define UNIPHY_PLL_SDM_CFG3 0x044
+#define UNIPHY_PLL_SDM_CFG4 0x048
+#define UNIPHY_PLL_SSC_CFG0 0x04C
+#define UNIPHY_PLL_SSC_CFG1 0x050
+#define UNIPHY_PLL_SSC_CFG2 0x054
+#define UNIPHY_PLL_SSC_CFG3 0x058
+#define UNIPHY_PLL_LKDET_CFG0 0x05C
+#define UNIPHY_PLL_LKDET_CFG1 0x060
+#define UNIPHY_PLL_LKDET_CFG2 0x064
+#define UNIPHY_PLL_CAL_CFG0 0x06C
+#define UNIPHY_PLL_CAL_CFG8 0x08C
+#define UNIPHY_PLL_CAL_CFG9 0x090
+#define UNIPHY_PLL_CAL_CFG10 0x094
+#define UNIPHY_PLL_CAL_CFG11 0x098
+#define UNIPHY_PLL_STATUS 0x0C0
+
+#define SATA_PHY_SER_CTRL 0x100
+#define SATA_PHY_TX_DRIV_CTRL0 0x104
+#define SATA_PHY_TX_DRIV_CTRL1 0x108
+#define SATA_PHY_TX_IMCAL0 0x11C
+#define SATA_PHY_TX_IMCAL2 0x124
+#define SATA_PHY_RX_IMCAL0 0x128
+#define SATA_PHY_EQUAL 0x13C
+#define SATA_PHY_OOB_TERM 0x144
+#define SATA_PHY_CDR_CTRL0 0x148
+#define SATA_PHY_CDR_CTRL1 0x14C
+#define SATA_PHY_CDR_CTRL2 0x150
+#define SATA_PHY_CDR_CTRL3 0x154
+#define SATA_PHY_PI_CTRL0 0x168
+#define SATA_PHY_POW_DWN_CTRL0 0x180
+#define SATA_PHY_POW_DWN_CTRL1 0x184
+#define SATA_PHY_TX_DATA_CTRL 0x188
+#define SATA_PHY_ALIGNP 0x1A4
+#define SATA_PHY_TX_IMCAL_STAT 0x1E4
+#define SATA_PHY_RX_IMCAL_STAT 0x1E8
+
+#define UNIPHY_PLL_LOCK BIT(0)
+#define SATA_PHY_TX_CAL BIT(0)
+#define SATA_PHY_RX_CAL BIT(0)
+
+/* default timeout set to 1 sec */
+#define TIMEOUT_MS 10000
+#define DELAY_INTERVAL_US 100
+
+struct qcom_apq8064_sata_phy {
+ void __iomem *mmio;
+ struct clk *cfg_clk;
+ struct device *dev;
+};
+
+/* Helper function to do poll and timeout */
+static int read_poll_timeout(void __iomem *addr, u32 mask)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
+
+ do {
+ if (readl_relaxed(addr) & mask)
+ return 0;
+
+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
+ } while (!time_after(jiffies, timeout));
+
+ return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT;
+}
+
+static int qcom_apq8064_sata_phy_init(struct phy *generic_phy)
+{
+ struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy);
+ void __iomem *base = phy->mmio;
+ int ret = 0;
+
+ /* SATA phy initialization */
+ writel_relaxed(0x01, base + SATA_PHY_SER_CTRL);
+ writel_relaxed(0xB1, base + SATA_PHY_POW_DWN_CTRL0);
+ /* Make sure the power down happens before power up */
+ mb();
+ usleep_range(10, 60);
+
+ writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0);
+ writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1);
+ writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0);
+ writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0);
+ writel_relaxed(0x02, base + SATA_PHY_TX_IMCAL2);
+
+ /* Write UNIPHYPLL registers to configure PLL */
+ writel_relaxed(0x04, base + UNIPHY_PLL_REFCLK_CFG);
+ writel_relaxed(0x00, base + UNIPHY_PLL_PWRGEN_CFG);
+
+ writel_relaxed(0x0A, base + UNIPHY_PLL_CAL_CFG0);
+ writel_relaxed(0xF3, base + UNIPHY_PLL_CAL_CFG8);
+ writel_relaxed(0x01, base + UNIPHY_PLL_CAL_CFG9);
+ writel_relaxed(0xED, base + UNIPHY_PLL_CAL_CFG10);
+ writel_relaxed(0x02, base + UNIPHY_PLL_CAL_CFG11);
+
+ writel_relaxed(0x36, base + UNIPHY_PLL_SDM_CFG0);
+ writel_relaxed(0x0D, base + UNIPHY_PLL_SDM_CFG1);
+ writel_relaxed(0xA3, base + UNIPHY_PLL_SDM_CFG2);
+ writel_relaxed(0xF0, base + UNIPHY_PLL_SDM_CFG3);
+ writel_relaxed(0x00, base + UNIPHY_PLL_SDM_CFG4);
+
+ writel_relaxed(0x19, base + UNIPHY_PLL_SSC_CFG0);
+ writel_relaxed(0xE1, base + UNIPHY_PLL_SSC_CFG1);
+ writel_relaxed(0x00, base + UNIPHY_PLL_SSC_CFG2);
+ writel_relaxed(0x11, base + UNIPHY_PLL_SSC_CFG3);
+
+ writel_relaxed(0x04, base + UNIPHY_PLL_LKDET_CFG0);
+ writel_relaxed(0xFF, base + UNIPHY_PLL_LKDET_CFG1);
+
+ writel_relaxed(0x02, base + UNIPHY_PLL_GLB_CFG);
+ /* make sure global config LDO power down happens before power up */
+ mb();
+
+ writel_relaxed(0x03, base + UNIPHY_PLL_GLB_CFG);
+ writel_relaxed(0x05, base + UNIPHY_PLL_LKDET_CFG2);
+
+ /* PLL Lock wait */
+ ret = read_poll_timeout(base + UNIPHY_PLL_STATUS, UNIPHY_PLL_LOCK);
+ if (ret) {
+ dev_err(phy->dev, "poll timeout UNIPHY_PLL_STATUS\n");
+ return ret;
+ }
+
+ /* TX Calibration */
+ ret = read_poll_timeout(base + SATA_PHY_TX_IMCAL_STAT, SATA_PHY_TX_CAL);
+ if (ret) {
+ dev_err(phy->dev, "poll timeout SATA_PHY_TX_IMCAL_STAT\n");
+ return ret;
+ }
+
+ /* RX Calibration */
+ ret = read_poll_timeout(base + SATA_PHY_RX_IMCAL_STAT, SATA_PHY_RX_CAL);
+ if (ret) {
+ dev_err(phy->dev, "poll timeout SATA_PHY_RX_IMCAL_STAT\n");
+ return ret;
+ }
+
+ /* SATA phy calibrated succesfully, power up to functional mode */
+ writel_relaxed(0x3E, base + SATA_PHY_POW_DWN_CTRL1);
+ writel_relaxed(0x01, base + SATA_PHY_RX_IMCAL0);
+ writel_relaxed(0x01, base + SATA_PHY_TX_IMCAL0);
+
+ writel_relaxed(0x00, base + SATA_PHY_POW_DWN_CTRL1);
+ writel_relaxed(0x59, base + SATA_PHY_CDR_CTRL0);
+ writel_relaxed(0x04, base + SATA_PHY_CDR_CTRL1);
+ writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL2);
+ writel_relaxed(0x00, base + SATA_PHY_PI_CTRL0);
+ writel_relaxed(0x00, base + SATA_PHY_CDR_CTRL3);
+ writel_relaxed(0x01, base + SATA_PHY_POW_DWN_CTRL0);
+
+ writel_relaxed(0x11, base + SATA_PHY_TX_DATA_CTRL);
+ writel_relaxed(0x43, base + SATA_PHY_ALIGNP);
+ writel_relaxed(0x04, base + SATA_PHY_OOB_TERM);
+
+ writel_relaxed(0x01, base + SATA_PHY_EQUAL);
+ writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL0);
+ writel_relaxed(0x09, base + SATA_PHY_TX_DRIV_CTRL1);
+
+ return 0;
+}
+
+static int qcom_apq8064_sata_phy_exit(struct phy *generic_phy)
+{
+ struct qcom_apq8064_sata_phy *phy = phy_get_drvdata(generic_phy);
+ void __iomem *base = phy->mmio;
+
+ /* Power down PHY */
+ writel_relaxed(0xF8, base + SATA_PHY_POW_DWN_CTRL0);
+ writel_relaxed(0xFE, base + SATA_PHY_POW_DWN_CTRL1);
+
+ /* Power down PLL block */
+ writel_relaxed(0x00, base + UNIPHY_PLL_GLB_CFG);
+
+ return 0;
+}
+
+static struct phy_ops qcom_apq8064_sata_phy_ops = {
+ .init = qcom_apq8064_sata_phy_init,
+ .exit = qcom_apq8064_sata_phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev)
+{
+ struct qcom_apq8064_sata_phy *phy;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct phy_provider *phy_provider;
+ struct phy *generic_phy;
+ int ret;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ phy->mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(phy->mmio))
+ return PTR_ERR(phy->mmio);
+
+ generic_phy = devm_phy_create(dev, NULL, &qcom_apq8064_sata_phy_ops,
+ NULL);
+ if (IS_ERR(generic_phy)) {
+ dev_err(dev, "%s: failed to create phy\n", __func__);
+ return PTR_ERR(generic_phy);
+ }
+
+ phy->dev = dev;
+ phy_set_drvdata(generic_phy, phy);
+ platform_set_drvdata(pdev, phy);
+
+ phy->cfg_clk = devm_clk_get(dev, "cfg");
+ if (IS_ERR(phy->cfg_clk)) {
+ dev_err(dev, "Failed to get sata cfg clock\n");
+ return PTR_ERR(phy->cfg_clk);
+ }
+
+ ret = clk_prepare_enable(phy->cfg_clk);
+ if (ret)
+ return ret;
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider)) {
+ clk_disable_unprepare(phy->cfg_clk);
+ dev_err(dev, "%s: failed to register phy\n", __func__);
+ return PTR_ERR(phy_provider);
+ }
+
+ return 0;
+}
+
+static int qcom_apq8064_sata_phy_remove(struct platform_device *pdev)
+{
+ struct qcom_apq8064_sata_phy *phy = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(phy->cfg_clk);
+
+ return 0;
+}
+
+static const struct of_device_id qcom_apq8064_sata_phy_of_match[] = {
+ { .compatible = "qcom,apq8064-sata-phy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qcom_apq8064_sata_phy_of_match);
+
+static struct platform_driver qcom_apq8064_sata_phy_driver = {
+ .probe = qcom_apq8064_sata_phy_probe,
+ .remove = qcom_apq8064_sata_phy_remove,
+ .driver = {
+ .name = "qcom-apq8064-sata-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = qcom_apq8064_sata_phy_of_match,
+ }
+};
+module_platform_driver(qcom_apq8064_sata_phy_driver);
+
+MODULE_DESCRIPTION("QCOM apq8064 SATA PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-qcom-ipq806x-sata.c b/drivers/phy/phy-qcom-ipq806x-sata.c
new file mode 100644
index 000000000000..909b5a87fc6a
--- /dev/null
+++ b/drivers/phy/phy-qcom-ipq806x-sata.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+
+struct qcom_ipq806x_sata_phy {
+ void __iomem *mmio;
+ struct clk *cfg_clk;
+ struct device *dev;
+};
+
+#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b))
+
+#define SATA_PHY_P0_PARAM0 0x200
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(x) __set(x, 17, 12)
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK GENMASK(17, 12)
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2(x) __set(x, 11, 6)
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK GENMASK(11, 6)
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1(x) __set(x, 5, 0)
+#define SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK GENMASK(5, 0)
+
+#define SATA_PHY_P0_PARAM1 0x204
+#define SATA_PHY_P0_PARAM1_RESERVED_BITS31_21(x) __set(x, 31, 21)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(x) __set(x, 20, 14)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK GENMASK(20, 14)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(x) __set(x, 13, 7)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK GENMASK(13, 7)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(x) __set(x, 6, 0)
+#define SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0)
+
+#define SATA_PHY_P0_PARAM2 0x208
+#define SATA_PHY_P0_PARAM2_RX_EQ(x) __set(x, 20, 18)
+#define SATA_PHY_P0_PARAM2_RX_EQ_MASK GENMASK(20, 18)
+
+#define SATA_PHY_P0_PARAM3 0x20C
+#define SATA_PHY_SSC_EN 0x8
+#define SATA_PHY_P0_PARAM4 0x210
+#define SATA_PHY_REF_SSP_EN 0x2
+#define SATA_PHY_RESET 0x1
+
+static int qcom_ipq806x_sata_phy_init(struct phy *generic_phy)
+{
+ struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
+ u32 reg;
+
+ /* Setting SSC_EN to 1 */
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM3);
+ reg = reg | SATA_PHY_SSC_EN;
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM3);
+
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM0) &
+ ~(SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3_MASK |
+ SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN2_MASK |
+ SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN1_MASK);
+ reg |= SATA_PHY_P0_PARAM0_P0_TX_PREEMPH_GEN3(0xf);
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM0);
+
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM1) &
+ ~(SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3_MASK |
+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2_MASK |
+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1_MASK);
+ reg |= SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN3(0x55) |
+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN2(0x55) |
+ SATA_PHY_P0_PARAM1_P0_TX_AMPLITUDE_GEN1(0x55);
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM1);
+
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM2) &
+ ~SATA_PHY_P0_PARAM2_RX_EQ_MASK;
+ reg |= SATA_PHY_P0_PARAM2_RX_EQ(0x3);
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM2);
+
+ /* Setting PHY_RESET to 1 */
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
+ reg = reg | SATA_PHY_RESET;
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
+
+ /* Setting REF_SSP_EN to 1 */
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
+ reg = reg | SATA_PHY_REF_SSP_EN | SATA_PHY_RESET;
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
+
+ /* make sure all changes complete before we let the PHY out of reset */
+ mb();
+
+ /* sleep for max. 50us more to combine processor wakeups */
+ usleep_range(20, 20 + 50);
+
+ /* Clearing PHY_RESET to 0 */
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
+ reg = reg & ~SATA_PHY_RESET;
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
+
+ return 0;
+}
+
+static int qcom_ipq806x_sata_phy_exit(struct phy *generic_phy)
+{
+ struct qcom_ipq806x_sata_phy *phy = phy_get_drvdata(generic_phy);
+ u32 reg;
+
+ /* Setting PHY_RESET to 1 */
+ reg = readl_relaxed(phy->mmio + SATA_PHY_P0_PARAM4);
+ reg = reg | SATA_PHY_RESET;
+ writel_relaxed(reg, phy->mmio + SATA_PHY_P0_PARAM4);
+
+ return 0;
+}
+
+static struct phy_ops qcom_ipq806x_sata_phy_ops = {
+ .init = qcom_ipq806x_sata_phy_init,
+ .exit = qcom_ipq806x_sata_phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev)
+{
+ struct qcom_ipq806x_sata_phy *phy;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct phy_provider *phy_provider;
+ struct phy *generic_phy;
+ int ret;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ phy->mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(phy->mmio))
+ return PTR_ERR(phy->mmio);
+
+ generic_phy = devm_phy_create(dev, NULL, &qcom_ipq806x_sata_phy_ops,
+ NULL);
+ if (IS_ERR(generic_phy)) {
+ dev_err(dev, "%s: failed to create phy\n", __func__);
+ return PTR_ERR(generic_phy);
+ }
+
+ phy->dev = dev;
+ phy_set_drvdata(generic_phy, phy);
+ platform_set_drvdata(pdev, phy);
+
+ phy->cfg_clk = devm_clk_get(dev, "cfg");
+ if (IS_ERR(phy->cfg_clk)) {
+ dev_err(dev, "Failed to get sata cfg clock\n");
+ return PTR_ERR(phy->cfg_clk);
+ }
+
+ ret = clk_prepare_enable(phy->cfg_clk);
+ if (ret)
+ return ret;
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ if (IS_ERR(phy_provider)) {
+ clk_disable_unprepare(phy->cfg_clk);
+ dev_err(dev, "%s: failed to register phy\n", __func__);
+ return PTR_ERR(phy_provider);
+ }
+
+ return 0;
+}
+
+static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev)
+{
+ struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(phy->cfg_clk);
+
+ return 0;
+}
+
+static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = {
+ { .compatible = "qcom,ipq806x-sata-phy" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match);
+
+static struct platform_driver qcom_ipq806x_sata_phy_driver = {
+ .probe = qcom_ipq806x_sata_phy_probe,
+ .remove = qcom_ipq806x_sata_phy_remove,
+ .driver = {
+ .name = "qcom-ipq806x-sata-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = qcom_ipq806x_sata_phy_of_match,
+ }
+};
+module_platform_driver(qcom_ipq806x_sata_phy_driver);
+
+MODULE_DESCRIPTION("QCOM IPQ806x SATA PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-s5pv210-usb2.c b/drivers/phy/phy-s5pv210-usb2.c
new file mode 100644
index 000000000000..004d320767e4
--- /dev/null
+++ b/drivers/phy/phy-s5pv210-usb2.c
@@ -0,0 +1,187 @@
+/*
+ * Samsung SoC USB 1.1/2.0 PHY driver - S5PV210 support
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Authors: Kamil Debski <k.debski@samsung.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.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/phy/phy.h>
+#include "phy-samsung-usb2.h"
+
+/* Exynos USB PHY registers */
+
+/* PHY power control */
+#define S5PV210_UPHYPWR 0x0
+
+#define S5PV210_UPHYPWR_PHY0_SUSPEND BIT(0)
+#define S5PV210_UPHYPWR_PHY0_PWR BIT(3)
+#define S5PV210_UPHYPWR_PHY0_OTG_PWR BIT(4)
+#define S5PV210_UPHYPWR_PHY0 ( \
+ S5PV210_UPHYPWR_PHY0_SUSPEND | \
+ S5PV210_UPHYPWR_PHY0_PWR | \
+ S5PV210_UPHYPWR_PHY0_OTG_PWR)
+
+#define S5PV210_UPHYPWR_PHY1_SUSPEND BIT(6)
+#define S5PV210_UPHYPWR_PHY1_PWR BIT(7)
+#define S5PV210_UPHYPWR_PHY1 ( \
+ S5PV210_UPHYPWR_PHY1_SUSPEND | \
+ S5PV210_UPHYPWR_PHY1_PWR)
+
+/* PHY clock control */
+#define S5PV210_UPHYCLK 0x4
+
+#define S5PV210_UPHYCLK_PHYFSEL_MASK (0x3 << 0)
+#define S5PV210_UPHYCLK_PHYFSEL_48MHZ (0x0 << 0)
+#define S5PV210_UPHYCLK_PHYFSEL_24MHZ (0x3 << 0)
+#define S5PV210_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0)
+
+#define S5PV210_UPHYCLK_PHY0_ID_PULLUP BIT(2)
+#define S5PV210_UPHYCLK_PHY0_COMMON_ON BIT(4)
+#define S5PV210_UPHYCLK_PHY1_COMMON_ON BIT(7)
+
+/* PHY reset control */
+#define S5PV210_UPHYRST 0x8
+
+#define S5PV210_URSTCON_PHY0 BIT(0)
+#define S5PV210_URSTCON_OTG_HLINK BIT(1)
+#define S5PV210_URSTCON_OTG_PHYLINK BIT(2)
+#define S5PV210_URSTCON_PHY1_ALL BIT(3)
+#define S5PV210_URSTCON_HOST_LINK_ALL BIT(4)
+
+/* Isolation, configured in the power management unit */
+#define S5PV210_USB_ISOL_OFFSET 0x680c
+#define S5PV210_USB_ISOL_DEVICE BIT(0)
+#define S5PV210_USB_ISOL_HOST BIT(1)
+
+
+enum s5pv210_phy_id {
+ S5PV210_DEVICE,
+ S5PV210_HOST,
+ S5PV210_NUM_PHYS,
+};
+
+/*
+ * s5pv210_rate_to_clk() converts the supplied clock rate to the value that
+ * can be written to the phy register.
+ */
+static int s5pv210_rate_to_clk(unsigned long rate, u32 *reg)
+{
+ switch (rate) {
+ case 12 * MHZ:
+ *reg = S5PV210_UPHYCLK_PHYFSEL_12MHZ;
+ break;
+ case 24 * MHZ:
+ *reg = S5PV210_UPHYCLK_PHYFSEL_24MHZ;
+ break;
+ case 48 * MHZ:
+ *reg = S5PV210_UPHYCLK_PHYFSEL_48MHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void s5pv210_isol(struct samsung_usb2_phy_instance *inst, bool on)
+{
+ struct samsung_usb2_phy_driver *drv = inst->drv;
+ u32 mask;
+
+ switch (inst->cfg->id) {
+ case S5PV210_DEVICE:
+ mask = S5PV210_USB_ISOL_DEVICE;
+ break;
+ case S5PV210_HOST:
+ mask = S5PV210_USB_ISOL_HOST;
+ break;
+ default:
+ return;
+ };
+
+ regmap_update_bits(drv->reg_pmu, S5PV210_USB_ISOL_OFFSET,
+ mask, on ? 0 : mask);
+}
+
+static void s5pv210_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
+{
+ struct samsung_usb2_phy_driver *drv = inst->drv;
+ u32 rstbits = 0;
+ u32 phypwr = 0;
+ u32 rst;
+ u32 pwr;
+
+ switch (inst->cfg->id) {
+ case S5PV210_DEVICE:
+ phypwr = S5PV210_UPHYPWR_PHY0;
+ rstbits = S5PV210_URSTCON_PHY0;
+ break;
+ case S5PV210_HOST:
+ phypwr = S5PV210_UPHYPWR_PHY1;
+ rstbits = S5PV210_URSTCON_PHY1_ALL |
+ S5PV210_URSTCON_HOST_LINK_ALL;
+ break;
+ };
+
+ if (on) {
+ writel(drv->ref_reg_val, drv->reg_phy + S5PV210_UPHYCLK);
+
+ pwr = readl(drv->reg_phy + S5PV210_UPHYPWR);
+ pwr &= ~phypwr;
+ writel(pwr, drv->reg_phy + S5PV210_UPHYPWR);
+
+ rst = readl(drv->reg_phy + S5PV210_UPHYRST);
+ rst |= rstbits;
+ writel(rst, drv->reg_phy + S5PV210_UPHYRST);
+ udelay(10);
+ rst &= ~rstbits;
+ writel(rst, drv->reg_phy + S5PV210_UPHYRST);
+ } else {
+ pwr = readl(drv->reg_phy + S5PV210_UPHYPWR);
+ pwr |= phypwr;
+ writel(pwr, drv->reg_phy + S5PV210_UPHYPWR);
+ }
+}
+
+static int s5pv210_power_on(struct samsung_usb2_phy_instance *inst)
+{
+ s5pv210_isol(inst, 0);
+ s5pv210_phy_pwr(inst, 1);
+
+ return 0;
+}
+
+static int s5pv210_power_off(struct samsung_usb2_phy_instance *inst)
+{
+ s5pv210_phy_pwr(inst, 0);
+ s5pv210_isol(inst, 1);
+
+ return 0;
+}
+
+static const struct samsung_usb2_common_phy s5pv210_phys[S5PV210_NUM_PHYS] = {
+ [S5PV210_DEVICE] = {
+ .label = "device",
+ .id = S5PV210_DEVICE,
+ .power_on = s5pv210_power_on,
+ .power_off = s5pv210_power_off,
+ },
+ [S5PV210_HOST] = {
+ .label = "host",
+ .id = S5PV210_HOST,
+ .power_on = s5pv210_power_on,
+ .power_off = s5pv210_power_off,
+ },
+};
+
+const struct samsung_usb2_phy_config s5pv210_usb2_phy_config = {
+ .num_phys = ARRAY_SIZE(s5pv210_phys),
+ .phys = s5pv210_phys,
+ .rate_to_clk = s5pv210_rate_to_clk,
+};
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c
index 8a8c6bc8709a..3732ca25e09f 100644
--- a/drivers/phy/phy-samsung-usb2.c
+++ b/drivers/phy/phy-samsung-usb2.c
@@ -87,6 +87,12 @@ static struct phy *samsung_usb2_phy_xlate(struct device *dev,
}
static const struct of_device_id samsung_usb2_phy_of_match[] = {
+#ifdef CONFIG_PHY_EXYNOS4X12_USB2
+ {
+ .compatible = "samsung,exynos3250-usb2-phy",
+ .data = &exynos3250_usb2_phy_config,
+ },
+#endif
#ifdef CONFIG_PHY_EXYNOS4210_USB2
{
.compatible = "samsung,exynos4210-usb2-phy",
@@ -105,8 +111,15 @@ static const struct of_device_id samsung_usb2_phy_of_match[] = {
.data = &exynos5250_usb2_phy_config,
},
#endif
+#ifdef CONFIG_PHY_S5PV210_USB2
+ {
+ .compatible = "samsung,s5pv210-usb2-phy",
+ .data = &s5pv210_usb2_phy_config,
+ },
+#endif
{ },
};
+MODULE_DEVICE_TABLE(of, samsung_usb2_phy_of_match);
static int samsung_usb2_phy_probe(struct platform_device *pdev)
{
@@ -189,7 +202,8 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
struct samsung_usb2_phy_instance *p = &drv->instances[i];
dev_dbg(dev, "Creating phy \"%s\"\n", label);
- p->phy = devm_phy_create(dev, &samsung_usb2_phy_ops, NULL);
+ p->phy = devm_phy_create(dev, NULL, &samsung_usb2_phy_ops,
+ NULL);
if (IS_ERR(p->phy)) {
dev_err(drv->dev, "Failed to create usb2_phy \"%s\"\n",
label);
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h
index 45b3170652bd..44bead9b8f34 100644
--- a/drivers/phy/phy-samsung-usb2.h
+++ b/drivers/phy/phy-samsung-usb2.h
@@ -29,7 +29,8 @@ struct samsung_usb2_phy_instance {
const struct samsung_usb2_common_phy *cfg;
struct phy *phy;
struct samsung_usb2_phy_driver *drv;
- bool enabled;
+ int int_cnt;
+ int ext_cnt;
};
struct samsung_usb2_phy_driver {
@@ -59,9 +60,12 @@ struct samsung_usb2_phy_config {
int (*rate_to_clk)(unsigned long, u32 *);
unsigned int num_phys;
bool has_mode_switch;
+ bool has_refclk_sel;
};
+extern const struct samsung_usb2_phy_config exynos3250_usb2_phy_config;
extern const struct samsung_usb2_phy_config exynos4210_usb2_phy_config;
extern const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config;
extern const struct samsung_usb2_phy_config exynos5250_usb2_phy_config;
+extern const struct samsung_usb2_phy_config s5pv210_usb2_phy_config;
#endif
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c
index c58c869d57e0..6dcbfcddb372 100644
--- a/drivers/phy/phy-spear1310-miphy.c
+++ b/drivers/phy/phy-spear1310-miphy.c
@@ -229,7 +229,7 @@ static int spear1310_miphy_probe(struct platform_device *pdev)
return -EINVAL;
}
- priv->phy = devm_phy_create(dev, &spear1310_miphy_ops, NULL);
+ priv->phy = devm_phy_create(dev, NULL, &spear1310_miphy_ops, NULL);
if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create SATA PCIe PHY\n");
return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c
index 8de98adf21c3..7135ba2603b6 100644
--- a/drivers/phy/phy-spear1340-miphy.c
+++ b/drivers/phy/phy-spear1340-miphy.c
@@ -261,7 +261,7 @@ static int spear1340_miphy_probe(struct platform_device *pdev)
return PTR_ERR(priv->misc);
}
- priv->phy = devm_phy_create(dev, &spear1340_miphy_ops, NULL);
+ priv->phy = devm_phy_create(dev, NULL, &spear1340_miphy_ops, NULL);
if (IS_ERR(priv->phy)) {
dev_err(dev, "failed to create SATA PCIe PHY\n");
return PTR_ERR(priv->phy);
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 115d8d5190d5..61ebea49709b 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -22,6 +22,7 @@
*/
#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -294,7 +295,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy->pmu);
}
- phy->phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL);
+ phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops, NULL);
if (IS_ERR(phy->phy)) {
dev_err(dev, "failed to create PHY %d\n", i);
return PTR_ERR(phy->phy);
@@ -306,10 +307,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
dev_set_drvdata(dev, data);
phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
- if (IS_ERR(phy_provider))
- return PTR_ERR(phy_provider);
- return 0;
+ return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id sun4i_usb_phy_of_match[] = {
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index 591367654613..b964aa967b46 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -80,7 +80,9 @@ struct ti_pipe3 {
struct clk *wkupclk;
struct clk *sys_clk;
struct clk *refclk;
+ struct clk *div_clk;
struct pipe3_dpll_map *dpll_map;
+ u8 id;
};
static struct pipe3_dpll_map dpll_map_usb[] = {
@@ -215,6 +217,11 @@ static int ti_pipe3_init(struct phy *x)
u32 val;
int ret = 0;
+ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) {
+ omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1);
+ return 0;
+ }
+
/* Bring it out of IDLE if it is IDLE */
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
if (val & PLL_IDLE) {
@@ -238,8 +245,11 @@ static int ti_pipe3_exit(struct phy *x)
u32 val;
unsigned long timeout;
- /* SATA DPLL can't be powered down due to Errata i783 */
- if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata"))
+ /* SATA DPLL can't be powered down due to Errata i783 and PCIe
+ * does not have internal DPLL
+ */
+ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") ||
+ of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie"))
return 0;
/* Put DPLL in IDLE mode */
@@ -286,32 +296,41 @@ static int ti_pipe3_probe(struct platform_device *pdev)
struct device_node *control_node;
struct platform_device *control_pdev;
const struct of_device_id *match;
-
- match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
- if (!match)
- return -EINVAL;
+ struct clk *clk;
phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
if (!phy) {
dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n");
return -ENOMEM;
}
+ phy->dev = &pdev->dev;
- phy->dpll_map = (struct pipe3_dpll_map *)match->data;
- if (!phy->dpll_map) {
- dev_err(&pdev->dev, "no DPLL data\n");
- return -EINVAL;
- }
+ if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
+ match = of_match_device(of_match_ptr(ti_pipe3_id_table),
+ &pdev->dev);
+ if (!match)
+ return -EINVAL;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
- phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(phy->pll_ctrl_base))
- return PTR_ERR(phy->pll_ctrl_base);
+ phy->dpll_map = (struct pipe3_dpll_map *)match->data;
+ if (!phy->dpll_map) {
+ dev_err(&pdev->dev, "no DPLL data\n");
+ return -EINVAL;
+ }
- phy->dev = &pdev->dev;
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "pll_ctrl");
+ phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(phy->pll_ctrl_base))
+ return PTR_ERR(phy->pll_ctrl_base);
- if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
+ phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
+ if (IS_ERR(phy->sys_clk)) {
+ dev_err(&pdev->dev, "unable to get sysclk\n");
+ return -EINVAL;
+ }
+ }
+ if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
if (IS_ERR(phy->wkupclk)) {
dev_err(&pdev->dev, "unable to get wkupclk\n");
@@ -328,10 +347,38 @@ static int ti_pipe3_probe(struct platform_device *pdev)
phy->refclk = ERR_PTR(-ENODEV);
}
- phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
- if (IS_ERR(phy->sys_clk)) {
- dev_err(&pdev->dev, "unable to get sysclk\n");
- return -EINVAL;
+ if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
+ if (of_property_read_u8(node, "id", &phy->id) < 0)
+ phy->id = 1;
+
+ clk = devm_clk_get(phy->dev, "dpll_ref");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "unable to get dpll ref clk\n");
+ return PTR_ERR(clk);
+ }
+ clk_set_rate(clk, 1500000000);
+
+ clk = devm_clk_get(phy->dev, "dpll_ref_m2");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n");
+ return PTR_ERR(clk);
+ }
+ clk_set_rate(clk, 100000000);
+
+ clk = devm_clk_get(phy->dev, "phy-div");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "unable to get phy-div clk\n");
+ return PTR_ERR(clk);
+ }
+ clk_set_rate(clk, 100000000);
+
+ phy->div_clk = devm_clk_get(phy->dev, "div-clk");
+ if (IS_ERR(phy->div_clk)) {
+ dev_err(&pdev->dev, "unable to get div-clk\n");
+ return PTR_ERR(phy->div_clk);
+ }
+ } else {
+ phy->div_clk = ERR_PTR(-ENODEV);
}
control_node = of_parse_phandle(node, "ctrl-module", 0);
@@ -353,7 +400,7 @@ static int ti_pipe3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, phy);
pm_runtime_enable(phy->dev);
- generic_phy = devm_phy_create(phy->dev, &ops, NULL);
+ generic_phy = devm_phy_create(phy->dev, NULL, &ops, NULL);
if (IS_ERR(generic_phy))
return PTR_ERR(generic_phy);
@@ -387,6 +434,8 @@ static int ti_pipe3_runtime_suspend(struct device *dev)
clk_disable_unprepare(phy->wkupclk);
if (!IS_ERR(phy->refclk))
clk_disable_unprepare(phy->refclk);
+ if (!IS_ERR(phy->div_clk))
+ clk_disable_unprepare(phy->div_clk);
return 0;
}
@@ -412,8 +461,19 @@ static int ti_pipe3_runtime_resume(struct device *dev)
}
}
+ if (!IS_ERR(phy->div_clk)) {
+ ret = clk_prepare_enable(phy->div_clk);
+ if (ret) {
+ dev_err(phy->dev, "Failed to enable div_clk %d\n", ret);
+ goto err3;
+ }
+ }
return 0;
+err3:
+ if (!IS_ERR(phy->wkupclk))
+ clk_disable_unprepare(phy->wkupclk);
+
err2:
if (!IS_ERR(phy->refclk))
clk_disable_unprepare(phy->refclk);
@@ -446,6 +506,9 @@ static const struct of_device_id ti_pipe3_id_table[] = {
.compatible = "ti,phy-pipe3-sata",
.data = dpll_map_sata,
},
+ {
+ .compatible = "ti,phy-pipe3-pcie",
+ },
{}
};
MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 2e0e9b3774c8..e1a6623d4696 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -695,7 +695,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
otg->set_host = twl4030_set_host;
otg->set_peripheral = twl4030_set_peripheral;
- phy = devm_phy_create(twl->dev, &ops, init_data);
+ phy = devm_phy_create(twl->dev, NULL, &ops, init_data);
if (IS_ERR(phy)) {
dev_dbg(&pdev->dev, "Failed to create PHY\n");
return PTR_ERR(phy);
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c
index 4aa1ccd1511f..db809b97219e 100644
--- a/drivers/phy/phy-xgene.c
+++ b/drivers/phy/phy-xgene.c
@@ -1707,7 +1707,7 @@ static int xgene_phy_probe(struct platform_device *pdev)
ctx->dev = &pdev->dev;
platform_set_drvdata(pdev, ctx);
- ctx->phy = devm_phy_create(ctx->dev, &xgene_phy_ops, NULL);
+ ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops, NULL);
if (IS_ERR(ctx->phy)) {
dev_dbg(&pdev->dev, "Failed to create PHY\n");
rc = PTR_ERR(ctx->phy);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0042ccb46b9a..bfd2c2e9f6cd 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -11,10 +11,10 @@ menu "Pin controllers"
depends on PINCTRL
config PINMUX
- bool "Support pin multiplexing controllers"
+ bool "Support pin multiplexing controllers" if COMPILE_TEST
config PINCONF
- bool "Support pin configuration controllers"
+ bool "Support pin configuration controllers" if COMPILE_TEST
config GENERIC_PINCONF
bool
@@ -26,29 +26,6 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
-config PINCTRL_ABX500
- bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
- depends on AB8500_CORE
- select GENERIC_PINCONF
- help
- Select this to enable the ABx500 family IC GPIO driver
-
-config PINCTRL_AB8500
- bool "AB8500 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8540
- bool "AB8540 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB9540
- bool "AB9540 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
-config PINCTRL_AB8505
- bool "AB8505 pin controller driver"
- depends on PINCTRL_ABX500 && ARCH_U8500
-
config PINCTRL_ADI2
bool "ADI pin controller driver"
depends on BLACKFIN
@@ -93,7 +70,7 @@ config PINCTRL_AT91
config PINCTRL_BAYTRAIL
bool "Intel Baytrail GPIO pin control"
depends on GPIOLIB && ACPI && X86
- select IRQ_DOMAIN
+ select GPIOLIB_IRQCHIP
help
driver for memory mapped GPIO functionality on Intel Baytrail
platforms. Supports 3 banks with 102, 28 and 44 gpios.
@@ -130,6 +107,13 @@ config PINCTRL_IMX1_CORE
select PINMUX
select PINCONF
+config PINCTRL_IMX1
+ bool "IMX1 pinctrl driver"
+ depends on SOC_IMX1
+ select PINCTRL_IMX1_CORE
+ help
+ Say Y here to enable the imx1 pinctrl driver
+
config PINCTRL_IMX27
bool "IMX27 pinctrl driver"
depends on SOC_IMX27
@@ -226,58 +210,6 @@ config PINCTRL_IMX28
bool
select PINCTRL_MXS
-config PINCTRL_MSM
- bool
- select PINMUX
- select PINCONF
- select GENERIC_PINCONF
- select GPIOLIB_IRQCHIP
-
-config PINCTRL_APQ8064
- tristate "Qualcomm APQ8064 pin controller driver"
- depends on GPIOLIB && OF
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
-
-config PINCTRL_IPQ8064
- tristate "Qualcomm IPQ8064 pin controller driver"
- depends on GPIOLIB && OF
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
-
-config PINCTRL_MSM8X74
- tristate "Qualcomm 8x74 pin controller driver"
- depends on GPIOLIB && OF && (ARCH_QCOM || COMPILE_TEST)
- select PINCTRL_MSM
- help
- This is the pinctrl, pinmux, pinconf and gpiolib driver for the
- Qualcomm TLMM block found in the Qualcomm 8974 platform.
-
-config PINCTRL_NOMADIK
- bool "Nomadik pin controller driver"
- depends on ARCH_U8500 || ARCH_NOMADIK
- select PINMUX
- select PINCONF
- select GPIOLIB
- select OF_GPIO
- select GPIOLIB_IRQCHIP
-
-config PINCTRL_STN8815
- bool "STN8815 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_NOMADIK
-
-config PINCTRL_DB8500
- bool "DB8500 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_U8500
-
-config PINCTRL_DB8540
- bool "DB8540 pin controller driver"
- depends on PINCTRL_NOMADIK && ARCH_U8500
-
config PINCTRL_ROCKCHIP
bool
select PINMUX
@@ -328,6 +260,12 @@ config PINCTRL_TEGRA124
bool
select PINCTRL_TEGRA
+config PINCTRL_TEGRA_XUSB
+ def_bool y if ARCH_TEGRA
+ select GENERIC_PHY
+ select PINCONF
+ select PINMUX
+
config PINCTRL_TZ1090
bool "Toumaz Xenif TZ1090 pin control driver"
depends on SOC_TZ1090
@@ -356,22 +294,6 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
-config PINCTRL_SAMSUNG
- bool
- select PINMUX
- select PINCONF
-
-config PINCTRL_EXYNOS
- bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
- depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
- select PINCTRL_SAMSUNG
-
-config PINCTRL_EXYNOS5440
- bool "Samsung EXYNOS5440 SoC pinctrl driver"
- depends on SOC_EXYNOS5440
- select PINMUX
- select PINCONF
-
config PINCTRL_PALMAS
bool "Pinctrl driver for the PALMAS Series MFD devices"
depends on OF && MFD_PALMAS
@@ -383,18 +305,11 @@ config PINCTRL_PALMAS
open drain configuration for the Palmas series devices like
TPS65913, TPS80036 etc.
-config PINCTRL_S3C24XX
- bool "Samsung S3C24XX SoC pinctrl driver"
- depends on ARCH_S3C24XX
- select PINCTRL_SAMSUNG
-
-config PINCTRL_S3C64XX
- bool "Samsung S3C64XX SoC pinctrl driver"
- depends on ARCH_S3C64XX
- select PINCTRL_SAMSUNG
-
source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
+source "drivers/pinctrl/nomadik/Kconfig"
+source "drivers/pinctrl/qcom/Kconfig"
+source "drivers/pinctrl/samsung/Kconfig"
source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
source "drivers/pinctrl/sunxi/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c4b5d405b8f5..05d227508c95 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,11 +9,6 @@ ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_PINCTRL) += devicetree.o
endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
-obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
-obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
-obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
-obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
-obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
@@ -24,6 +19,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o
+obj-$(CONFIG_PINCTRL_IMX1) += pinctrl-imx1.o
obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o
obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o
obj-$(CONFIG_PINCTRL_IMX50) += pinctrl-imx50.o
@@ -38,14 +34,6 @@ obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX25) += pinctrl-imx25.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
-obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
-obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
-obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
-obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
-obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
-obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
-obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
-obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
@@ -55,15 +43,11 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_TEGRA114) += pinctrl-tegra114.o
obj-$(CONFIG_PINCTRL_TEGRA124) += pinctrl-tegra124.o
+obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o
obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
-obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
-obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
-obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
-obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
-obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
@@ -72,8 +56,11 @@ obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_PLAT_ORION) += mvebu/
+obj-y += nomadik/
+obj-$(CONFIG_ARCH_QCOM) += qcom/
+obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
obj-$(CONFIG_SUPERH) += sh-pfc/
obj-$(CONFIG_PLAT_SPEAR) += spear/
-obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+obj-$(CONFIG_ARCH_VT8500) += vt8500/
diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c
index edf5d2fd2b22..86db2235ab00 100644
--- a/drivers/pinctrl/berlin/berlin.c
+++ b/drivers/pinctrl/berlin/berlin.c
@@ -320,7 +320,7 @@ int berlin_pinctrl_probe(struct platform_device *pdev,
regmap = dev_get_regmap(&pdev->dev, NULL);
if (!regmap)
- return PTR_ERR(regmap);
+ return -ENODEV;
pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
if (!pctrl)
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index e09474ecde23..e4f65510c87e 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -992,29 +992,15 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
if (p->state) {
/*
- * The set of groups with a mux configuration in the old state
- * may not be identical to the set of groups with a mux setting
- * in the new state. While this might be unusual, it's entirely
- * possible for the "user"-supplied mapping table to be written
- * that way. For each group that was configured in the old state
- * but not in the new state, this code puts that group into a
- * safe/disabled state.
+ * For each pinmux setting in the old state, forget SW's record
+ * of mux owner for that pingroup. Any pingroups which are
+ * still owned by the new state will be re-acquired by the call
+ * to pinmux_enable_setting() in the loop below.
*/
list_for_each_entry(setting, &p->state->settings, node) {
- bool found = false;
if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
continue;
- list_for_each_entry(setting2, &state->settings, node) {
- if (setting2->type != PIN_MAP_TYPE_MUX_GROUP)
- continue;
- if (setting2->data.mux.group ==
- setting->data.mux.group) {
- found = true;
- break;
- }
- }
- if (!found)
- pinmux_disable_setting(setting);
+ pinmux_disable_setting(setting);
}
}
diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
new file mode 100644
index 000000000000..d48a5aa24a29
--- /dev/null
+++ b/drivers/pinctrl/nomadik/Kconfig
@@ -0,0 +1,51 @@
+if ARCH_U8500
+
+config PINCTRL_ABX500
+ bool "ST-Ericsson ABx500 family Mixed Signal Circuit gpio functions"
+ depends on AB8500_CORE
+ select GENERIC_PINCONF
+ help
+ Select this to enable the ABx500 family IC GPIO driver
+
+config PINCTRL_AB8500
+ bool "AB8500 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8540
+ bool "AB8540 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB9540
+ bool "AB9540 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+config PINCTRL_AB8505
+ bool "AB8505 pin controller driver"
+ depends on PINCTRL_ABX500 && ARCH_U8500
+
+endif
+
+if (ARCH_U8500 || ARCH_NOMADIK)
+
+config PINCTRL_NOMADIK
+ bool "Nomadik pin controller driver"
+ depends on ARCH_U8500 || ARCH_NOMADIK
+ select PINMUX
+ select PINCONF
+ select GPIOLIB
+ select OF_GPIO
+ select GPIOLIB_IRQCHIP
+
+config PINCTRL_STN8815
+ bool "STN8815 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_NOMADIK
+
+config PINCTRL_DB8500
+ bool "DB8500 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_U8500
+
+config PINCTRL_DB8540
+ bool "DB8540 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_U8500
+
+endif
diff --git a/drivers/pinctrl/nomadik/Makefile b/drivers/pinctrl/nomadik/Makefile
new file mode 100644
index 000000000000..30b27f18cd52
--- /dev/null
+++ b/drivers/pinctrl/nomadik/Makefile
@@ -0,0 +1,10 @@
+# Nomadik family pin control drivers
+obj-$(CONFIG_PINCTRL_ABX500) += pinctrl-abx500.o
+obj-$(CONFIG_PINCTRL_AB8500) += pinctrl-ab8500.o
+obj-$(CONFIG_PINCTRL_AB8540) += pinctrl-ab8540.o
+obj-$(CONFIG_PINCTRL_AB9540) += pinctrl-ab9540.o
+obj-$(CONFIG_PINCTRL_AB8505) += pinctrl-ab8505.o
+obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
+obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
+obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
+obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
diff --git a/drivers/pinctrl/pinctrl-ab8500.c b/drivers/pinctrl/nomadik/pinctrl-ab8500.c
index 2ac2d0ad3025..2ac2d0ad3025 100644
--- a/drivers/pinctrl/pinctrl-ab8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8500.c
diff --git a/drivers/pinctrl/pinctrl-ab8505.c b/drivers/pinctrl/nomadik/pinctrl-ab8505.c
index bf0ef4ac376f..bf0ef4ac376f 100644
--- a/drivers/pinctrl/pinctrl-ab8505.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8505.c
diff --git a/drivers/pinctrl/pinctrl-ab8540.c b/drivers/pinctrl/nomadik/pinctrl-ab8540.c
index 9867535d49c1..9867535d49c1 100644
--- a/drivers/pinctrl/pinctrl-ab8540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab8540.c
diff --git a/drivers/pinctrl/pinctrl-ab9540.c b/drivers/pinctrl/nomadik/pinctrl-ab9540.c
index 1a281ca95dac..1a281ca95dac 100644
--- a/drivers/pinctrl/pinctrl-ab9540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-ab9540.c
diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c
index 163da9c3ea0e..a53a689a2bfa 100644
--- a/drivers/pinctrl/pinctrl-abx500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c
@@ -32,8 +32,8 @@
#include <linux/pinctrl/machine.h>
#include "pinctrl-abx500.h"
-#include "core.h"
-#include "pinconf.h"
+#include "../core.h"
+#include "../pinconf.h"
/*
* The AB9540 and AB8540 GPIO support are extended versions
@@ -737,20 +737,6 @@ static int abx500_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
return ret;
}
-static void abx500_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
- const struct abx500_pingroup *g;
-
- g = &pct->soc->groups[group];
- if (g->altsetting < 0)
- return;
-
- /* FIXME: poke out the mux, set the pin to some default state? */
- dev_dbg(pct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
static int abx500_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -799,7 +785,6 @@ static const struct pinmux_ops abx500_pinmux_ops = {
.get_function_name = abx500_pmx_get_func_name,
.get_function_groups = abx500_pmx_get_func_groups,
.enable = abx500_pmx_enable,
- .disable = abx500_pmx_disable,
.gpio_request_enable = abx500_gpio_request_enable,
.gpio_disable_free = abx500_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-abx500.h b/drivers/pinctrl/nomadik/pinctrl-abx500.h
index 2beef3bfe9ca..2beef3bfe9ca 100644
--- a/drivers/pinctrl/pinctrl-abx500.h
+++ b/drivers/pinctrl/nomadik/pinctrl-abx500.h
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
index c74840729648..c74840729648 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
index d7ba5443bae0..d7ba5443bae0 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8540.c
diff --git a/drivers/pinctrl/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
index ed39dcafd4f8..ed39dcafd4f8 100644
--- a/drivers/pinctrl/pinctrl-nomadik-stn8815.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 8f6f16ef73f3..e7cab07eef47 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -31,7 +31,7 @@
/* Since we request GPIOs from ourself */
#include <linux/pinctrl/consumer.h>
#include "pinctrl-nomadik.h"
-#include "core.h"
+#include "../core.h"
/*
* The GPIO module in the Nomadik family of Systems-on-Chip is an
@@ -1765,21 +1765,6 @@ out_glitch:
return ret;
}
-static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
- const struct nmk_pingroup *g;
-
- g = &npct->soc->groups[group];
-
- if (g->altsetting < 0)
- return;
-
- /* Poke out the mux, set the pin to some default state? */
- dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
-}
-
static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -1826,7 +1811,6 @@ static const struct pinmux_ops nmk_pinmux_ops = {
.get_function_name = nmk_pmx_get_func_name,
.get_function_groups = nmk_pmx_get_func_groups,
.enable = nmk_pmx_enable,
- .disable = nmk_pmx_disable,
.gpio_request_enable = nmk_gpio_request_enable,
.gpio_disable_free = nmk_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
index d8215f1e70c7..d8215f1e70c7 100644
--- a/drivers/pinctrl/pinctrl-nomadik.h
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
index 5c44feb54ebb..b092b93c67a1 100644
--- a/drivers/pinctrl/pinctrl-adi2.c
+++ b/drivers/pinctrl/pinctrl-adi2.c
@@ -401,7 +401,7 @@ static int adi_gpio_irq_type(struct irq_data *d, unsigned int type)
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
- snprintf(buf, 16, "gpio-irq%d", irq);
+ snprintf(buf, 16, "gpio-irq%u", irq);
port_setup(port, d->hwirq, true);
} else
goto out;
@@ -652,35 +652,6 @@ static int adi_pinmux_enable(struct pinctrl_dev *pctldev, unsigned func_id,
return 0;
}
-static void adi_pinmux_disable(struct pinctrl_dev *pctldev, unsigned func_id,
- unsigned group_id)
-{
- struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
- struct gpio_port *port;
- struct pinctrl_gpio_range *range;
- unsigned long flags;
- unsigned short *mux, pin;
-
- mux = (unsigned short *)pinctrl->soc->groups[group_id].mux;
-
- while (*mux) {
- pin = P_IDENT(*mux);
-
- range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
- if (range == NULL) /* should not happen */
- return;
-
- port = container_of(range->gc, struct gpio_port, chip);
-
- spin_lock_irqsave(&port->lock, flags);
-
- port_setup(port, pin_to_offset(range, pin), true);
- mux++;
-
- spin_unlock_irqrestore(&port->lock, flags);
- }
-}
-
static int adi_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct adi_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -728,7 +699,6 @@ static int adi_pinmux_request_gpio(struct pinctrl_dev *pctldev,
static struct pinmux_ops adi_pinmux_ops = {
.enable = adi_pinmux_enable,
- .disable = adi_pinmux_disable,
.get_functions_count = adi_pinmux_get_funcs_count,
.get_function_name = adi_pinmux_get_func_name,
.get_function_groups = adi_pinmux_get_groups,
@@ -979,7 +949,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
struct gpio_port *port;
char pinctrl_devname[DEVNAME_SIZE];
static int gpio;
- int ret = 0, ret1;
+ int ret = 0;
pdata = dev->platform_data;
if (!pdata)
@@ -1057,7 +1027,7 @@ static int adi_gpio_probe(struct platform_device *pdev)
return 0;
out_remove_gpiochip:
- ret1 = gpiochip_remove(&port->chip);
+ gpiochip_remove(&port->chip);
out_remove_domain:
if (port->pint)
irq_domain_remove(port->domain);
@@ -1068,12 +1038,11 @@ out_remove_domain:
static int adi_gpio_remove(struct platform_device *pdev)
{
struct gpio_port *port = platform_get_drvdata(pdev);
- int ret;
u8 offset;
list_del(&port->node);
gpiochip_remove_pin_ranges(&port->chip);
- ret = gpiochip_remove(&port->chip);
+ gpiochip_remove(&port->chip);
if (port->pint) {
for (offset = 0; offset < port->width; offset++)
irq_dispose_mapping(irq_find_mapping(port->domain,
@@ -1081,7 +1050,7 @@ static int adi_gpio_remove(struct platform_device *pdev)
irq_domain_remove(port->domain);
}
- return ret;
+ return 0;
}
static int adi_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c
index c862f9c0e9ce..0e4ec91f4d49 100644
--- a/drivers/pinctrl/pinctrl-as3722.c
+++ b/drivers/pinctrl/pinctrl-as3722.c
@@ -565,7 +565,6 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
{
struct as3722_pctrl_info *as_pci;
int ret;
- int tret;
as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
if (!as_pci)
@@ -611,10 +610,7 @@ static int as3722_pinctrl_probe(struct platform_device *pdev)
return 0;
fail_range_add:
- tret = gpiochip_remove(&as_pci->gpio_chip);
- if (tret < 0)
- dev_warn(&pdev->dev, "Couldn't remove gpio chip, %d\n", tret);
-
+ gpiochip_remove(&as_pci->gpio_chip);
fail_chip_add:
pinctrl_unregister(as_pci->pctl);
return ret;
@@ -623,11 +619,8 @@ fail_chip_add:
static int as3722_pinctrl_remove(struct platform_device *pdev)
{
struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
- int ret;
- ret = gpiochip_remove(&as_pci->gpio_chip);
- if (ret < 0)
- return ret;
+ gpiochip_remove(&as_pci->gpio_chip);
pinctrl_unregister(as_pci->pctl);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index 421493cb490c..af1ba4fc150d 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -611,26 +611,6 @@ static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf;
- const struct at91_pmx_pin *pin;
- uint32_t npins = info->groups[group].npins;
- int i;
- unsigned mask;
- void __iomem *pio;
-
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- at91_pin_dbg(info->dev, pin);
- pio = pin_to_controller(info, pin->bank);
- mask = pin_to_mask(pin->pin);
- at91_mux_gpio_enable(pio, mask, 1);
- }
-}
-
static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
@@ -705,7 +685,6 @@ static const struct pinmux_ops at91_pmx_ops = {
.get_function_name = at91_pmx_get_func_name,
.get_function_groups = at91_pmx_get_groups,
.enable = at91_pmx_enable,
- .disable = at91_pmx_disable,
.gpio_request_enable = at91_gpio_request_enable,
.gpio_disable_free = at91_gpio_disable_free,
};
@@ -793,9 +772,9 @@ static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin_id)
{
unsigned long config;
- int ret, val, num_conf = 0;
+ int val, num_conf = 0;
- ret = at91_pinconf_get(pctldev, pin_id, &config);
+ at91_pinconf_get(pctldev, pin_id, &config);
DBG_SHOW_FLAG(MULTI_DRIVE);
DBG_SHOW_FLAG(PULL_UP);
@@ -945,7 +924,7 @@ static int at91_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
+ if (func->ngroups == 0) {
dev_err(info->dev, "no groups defined\n");
return -EINVAL;
}
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c
index 975572e2f260..9ca59a018743 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -25,9 +25,7 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/irqdomain.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
@@ -44,6 +42,7 @@
/* BYT_CONF0_REG register bits */
#define BYT_IODEN BIT(31)
+#define BYT_DIRECT_IRQ_EN BIT(27)
#define BYT_TRIG_NEG BIT(26)
#define BYT_TRIG_POS BIT(25)
#define BYT_TRIG_LVL BIT(24)
@@ -137,7 +136,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
struct byt_gpio {
struct gpio_chip chip;
- struct irq_domain *domain;
struct platform_device *pdev;
spinlock_t lock;
void __iomem *reg_base;
@@ -217,7 +215,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
static int byt_irq_type(struct irq_data *d, unsigned type)
{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+ struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
u32 offset = irqd_to_hwirq(d);
u32 value;
unsigned long flags;
@@ -303,12 +301,22 @@ static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int value)
{
struct byt_gpio *vg = to_byt_gpio(chip);
+ void __iomem *conf_reg = byt_gpio_reg(chip, gpio, BYT_CONF0_REG);
void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
unsigned long flags;
u32 reg_val;
spin_lock_irqsave(&vg->lock, flags);
+ /*
+ * Before making any direction modifications, do a check if gpio
+ * is set for direct IRQ. On baytrail, setting GPIO to output does
+ * not make sense, so let's at least warn the caller before they shoot
+ * themselves in the foot.
+ */
+ WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
+ "Potential Error: Setting GPIO with direct_irq_en to output");
+
reg_val = readl(reg) | BYT_DIR_MASK;
reg_val &= ~BYT_OUTPUT_EN;
@@ -393,16 +401,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
spin_unlock_irqrestore(&vg->lock, flags);
}
-static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct byt_gpio *vg = to_byt_gpio(chip);
- return irq_create_mapping(vg->domain, offset);
-}
-
static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct irq_data *data = irq_desc_get_irq_data(desc);
- struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
+ struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, pin, mask;
void __iomem *reg;
@@ -421,7 +423,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
/* Clear before handling so we can't lose an edge */
writel(mask, reg);
- virq = irq_find_mapping(vg->domain, base + pin);
+ virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
generic_handle_irq(virq);
/* In case bios or user sets triggering incorretly a pin
@@ -454,33 +456,11 @@ static void byt_irq_mask(struct irq_data *d)
{
}
-static int byt_irq_reqres(struct irq_data *d)
-{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
- if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) {
- dev_err(vg->chip.dev,
- "unable to lock HW IRQ %lu for IRQ\n",
- irqd_to_hwirq(d));
- return -EINVAL;
- }
- return 0;
-}
-
-static void byt_irq_relres(struct irq_data *d)
-{
- struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
- gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
-}
-
static struct irq_chip byt_irqchip = {
.name = "BYT-GPIO",
.irq_mask = byt_irq_mask,
.irq_unmask = byt_irq_unmask,
.irq_set_type = byt_irq_type,
- .irq_request_resources = byt_irq_reqres,
- .irq_release_resources = byt_irq_relres,
};
static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
@@ -501,23 +481,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
}
}
-static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct byt_gpio *vg = d->host_data;
-
- irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
- "demux");
- irq_set_chip_data(virq, vg);
- irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static const struct irq_domain_ops byt_gpio_irq_ops = {
- .map = byt_gpio_irq_map,
-};
-
static int byt_gpio_probe(struct platform_device *pdev)
{
struct byt_gpio *vg;
@@ -527,7 +490,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
struct acpi_device *acpi_dev;
struct pinctrl_gpio_range *range;
acpi_handle handle = ACPI_HANDLE(dev);
- unsigned hwirq;
int ret;
if (acpi_bus_get_device(handle, &acpi_dev))
@@ -574,27 +536,27 @@ static int byt_gpio_probe(struct platform_device *pdev)
gc->can_sleep = false;
gc->dev = dev;
+ ret = gpiochip_add(gc);
+ if (ret) {
+ dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
+ return ret;
+ }
+
/* set up interrupts */
irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_rc && irq_rc->start) {
- hwirq = irq_rc->start;
- gc->to_irq = byt_gpio_to_irq;
-
- vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
- &byt_gpio_irq_ops, vg);
- if (!vg->domain)
- return -ENXIO;
-
byt_gpio_irq_init_hw(vg);
+ ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
+ handle_simple_irq, IRQ_TYPE_NONE);
+ if (ret) {
+ dev_err(dev, "failed to add irqchip\n");
+ gpiochip_remove(gc);
+ return ret;
+ }
- irq_set_handler_data(hwirq, vg);
- irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
- }
-
- ret = gpiochip_add(gc);
- if (ret) {
- dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
- return ret;
+ gpiochip_set_chained_irqchip(gc, &byt_irqchip,
+ (unsigned)irq_rc->start,
+ byt_gpio_irq_handler);
}
pm_runtime_enable(dev);
@@ -627,12 +589,9 @@ MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
static int byt_gpio_remove(struct platform_device *pdev)
{
struct byt_gpio *vg = platform_get_drvdata(pdev);
- int err;
pm_runtime_disable(&pdev->dev);
- err = gpiochip_remove(&vg->chip);
- if (err)
- dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
+ gpiochip_remove(&vg->chip);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c
index 3bed792b2c03..c5ca9e633fff 100644
--- a/drivers/pinctrl/pinctrl-bcm281xx.c
+++ b/drivers/pinctrl/pinctrl-bcm281xx.c
@@ -1396,7 +1396,7 @@ static struct pinctrl_desc bcm281xx_pinctrl_desc = {
.owner = THIS_MODULE,
};
-int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+static int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
{
struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
struct resource *res;
diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index 3d907de9bc91..5bcfd7ace0cd 100644
--- a/drivers/pinctrl/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -841,16 +841,6 @@ static int bcm2835_pmx_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void bcm2835_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- unsigned group_selector)
-{
- struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
-
- /* disable by setting to GPIO_IN */
- bcm2835_pinctrl_fsel_set(pc, group_selector, BCM2835_FSEL_GPIO_IN);
-}
-
static void bcm2835_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -880,7 +870,6 @@ static const struct pinmux_ops bcm2835_pmx_ops = {
.get_function_name = bcm2835_pmx_get_function_name,
.get_function_groups = bcm2835_pmx_get_function_groups,
.enable = bcm2835_pmx_enable,
- .disable = bcm2835_pmx_disable,
.gpio_disable_free = bcm2835_pmx_gpio_disable_free,
.gpio_set_direction = bcm2835_pmx_gpio_set_direction,
};
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index d182fdd2e715..29cbbab8c3a6 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -756,8 +756,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
err_no_range:
err_no_irqchip:
- if (gpiochip_remove(&gpio->chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&gpio->chip);
err_no_chip:
clk_disable_unprepare(gpio->clk);
dev_err(&pdev->dev, "module ERROR:%d\n", err);
@@ -767,16 +766,11 @@ err_no_chip:
static int __exit u300_gpio_remove(struct platform_device *pdev)
{
struct u300_gpio *gpio = platform_get_drvdata(pdev);
- int err;
/* Turn off the GPIO block */
writel(0x00000000U, gpio->base + U300_GPIO_CR);
- err = gpiochip_remove(&gpio->chip);
- if (err < 0) {
- dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err);
- return err;
- }
+ gpiochip_remove(&gpio->chip);
clk_disable_unprepare(gpio->clk);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c
index a24448e5d399..946d594a64dd 100644
--- a/drivers/pinctrl/pinctrl-imx.c
+++ b/drivers/pinctrl/pinctrl-imx.c
@@ -515,7 +515,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->num_groups = of_get_child_count(np);
- if (func->num_groups <= 0) {
+ if (func->num_groups == 0) {
dev_err(info->dev, "no groups defined in %s\n", np->full_name);
return -EINVAL;
}
diff --git a/drivers/pinctrl/pinctrl-imx1-core.c b/drivers/pinctrl/pinctrl-imx1-core.c
index 815384b377b5..483420757c9f 100644
--- a/drivers/pinctrl/pinctrl-imx1-core.c
+++ b/drivers/pinctrl/pinctrl-imx1-core.c
@@ -526,7 +526,7 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
/* Initialise function */
func->name = np->name;
func->num_groups = of_get_child_count(np);
- if (func->num_groups <= 0)
+ if (func->num_groups == 0)
return -EINVAL;
func->groups = devm_kzalloc(info->dev,
diff --git a/drivers/pinctrl/pinctrl-imx1.c b/drivers/pinctrl/pinctrl-imx1.c
new file mode 100644
index 000000000000..533a6e519648
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-imx1.c
@@ -0,0 +1,279 @@
+/*
+ * i.MX1 pinctrl driver based on imx pinmux core
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * 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/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx1.h"
+
+#define PAD_ID(port, pin) ((port) * 32 + (pin))
+#define PA 0
+#define PB 1
+#define PC 2
+#define PD 3
+
+enum imx1_pads {
+ MX1_PAD_A24 = PAD_ID(PA, 0),
+ MX1_PAD_TIN = PAD_ID(PA, 1),
+ MX1_PAD_PWMO = PAD_ID(PA, 2),
+ MX1_PAD_CSI_MCLK = PAD_ID(PA, 3),
+ MX1_PAD_CSI_D0 = PAD_ID(PA, 4),
+ MX1_PAD_CSI_D1 = PAD_ID(PA, 5),
+ MX1_PAD_CSI_D2 = PAD_ID(PA, 6),
+ MX1_PAD_CSI_D3 = PAD_ID(PA, 7),
+ MX1_PAD_CSI_D4 = PAD_ID(PA, 8),
+ MX1_PAD_CSI_D5 = PAD_ID(PA, 9),
+ MX1_PAD_CSI_D6 = PAD_ID(PA, 10),
+ MX1_PAD_CSI_D7 = PAD_ID(PA, 11),
+ MX1_PAD_CSI_VSYNC = PAD_ID(PA, 12),
+ MX1_PAD_CSI_HSYNC = PAD_ID(PA, 13),
+ MX1_PAD_CSI_PIXCLK = PAD_ID(PA, 14),
+ MX1_PAD_I2C_SDA = PAD_ID(PA, 15),
+ MX1_PAD_I2C_SCL = PAD_ID(PA, 16),
+ MX1_PAD_DTACK = PAD_ID(PA, 17),
+ MX1_PAD_BCLK = PAD_ID(PA, 18),
+ MX1_PAD_LBA = PAD_ID(PA, 19),
+ MX1_PAD_ECB = PAD_ID(PA, 20),
+ MX1_PAD_A0 = PAD_ID(PA, 21),
+ MX1_PAD_CS4 = PAD_ID(PA, 22),
+ MX1_PAD_CS5 = PAD_ID(PA, 23),
+ MX1_PAD_A16 = PAD_ID(PA, 24),
+ MX1_PAD_A17 = PAD_ID(PA, 25),
+ MX1_PAD_A18 = PAD_ID(PA, 26),
+ MX1_PAD_A19 = PAD_ID(PA, 27),
+ MX1_PAD_A20 = PAD_ID(PA, 28),
+ MX1_PAD_A21 = PAD_ID(PA, 29),
+ MX1_PAD_A22 = PAD_ID(PA, 30),
+ MX1_PAD_A23 = PAD_ID(PA, 31),
+ MX1_PAD_SD_DAT0 = PAD_ID(PB, 8),
+ MX1_PAD_SD_DAT1 = PAD_ID(PB, 9),
+ MX1_PAD_SD_DAT2 = PAD_ID(PB, 10),
+ MX1_PAD_SD_DAT3 = PAD_ID(PB, 11),
+ MX1_PAD_SD_SCLK = PAD_ID(PB, 12),
+ MX1_PAD_SD_CMD = PAD_ID(PB, 13),
+ MX1_PAD_SIM_SVEN = PAD_ID(PB, 14),
+ MX1_PAD_SIM_PD = PAD_ID(PB, 15),
+ MX1_PAD_SIM_TX = PAD_ID(PB, 16),
+ MX1_PAD_SIM_RX = PAD_ID(PB, 17),
+ MX1_PAD_SIM_RST = PAD_ID(PB, 18),
+ MX1_PAD_SIM_CLK = PAD_ID(PB, 19),
+ MX1_PAD_USBD_AFE = PAD_ID(PB, 20),
+ MX1_PAD_USBD_OE = PAD_ID(PB, 21),
+ MX1_PAD_USBD_RCV = PAD_ID(PB, 22),
+ MX1_PAD_USBD_SUSPND = PAD_ID(PB, 23),
+ MX1_PAD_USBD_VP = PAD_ID(PB, 24),
+ MX1_PAD_USBD_VM = PAD_ID(PB, 25),
+ MX1_PAD_USBD_VPO = PAD_ID(PB, 26),
+ MX1_PAD_USBD_VMO = PAD_ID(PB, 27),
+ MX1_PAD_UART2_CTS = PAD_ID(PB, 28),
+ MX1_PAD_UART2_RTS = PAD_ID(PB, 29),
+ MX1_PAD_UART2_TXD = PAD_ID(PB, 30),
+ MX1_PAD_UART2_RXD = PAD_ID(PB, 31),
+ MX1_PAD_SSI_RXFS = PAD_ID(PC, 3),
+ MX1_PAD_SSI_RXCLK = PAD_ID(PC, 4),
+ MX1_PAD_SSI_RXDAT = PAD_ID(PC, 5),
+ MX1_PAD_SSI_TXDAT = PAD_ID(PC, 6),
+ MX1_PAD_SSI_TXFS = PAD_ID(PC, 7),
+ MX1_PAD_SSI_TXCLK = PAD_ID(PC, 8),
+ MX1_PAD_UART1_CTS = PAD_ID(PC, 9),
+ MX1_PAD_UART1_RTS = PAD_ID(PC, 10),
+ MX1_PAD_UART1_TXD = PAD_ID(PC, 11),
+ MX1_PAD_UART1_RXD = PAD_ID(PC, 12),
+ MX1_PAD_SPI1_RDY = PAD_ID(PC, 13),
+ MX1_PAD_SPI1_SCLK = PAD_ID(PC, 14),
+ MX1_PAD_SPI1_SS = PAD_ID(PC, 15),
+ MX1_PAD_SPI1_MISO = PAD_ID(PC, 16),
+ MX1_PAD_SPI1_MOSI = PAD_ID(PC, 17),
+ MX1_PAD_BT13 = PAD_ID(PC, 19),
+ MX1_PAD_BT12 = PAD_ID(PC, 20),
+ MX1_PAD_BT11 = PAD_ID(PC, 21),
+ MX1_PAD_BT10 = PAD_ID(PC, 22),
+ MX1_PAD_BT9 = PAD_ID(PC, 23),
+ MX1_PAD_BT8 = PAD_ID(PC, 24),
+ MX1_PAD_BT7 = PAD_ID(PC, 25),
+ MX1_PAD_BT6 = PAD_ID(PC, 26),
+ MX1_PAD_BT5 = PAD_ID(PC, 27),
+ MX1_PAD_BT4 = PAD_ID(PC, 28),
+ MX1_PAD_BT3 = PAD_ID(PC, 29),
+ MX1_PAD_BT2 = PAD_ID(PC, 30),
+ MX1_PAD_BT1 = PAD_ID(PC, 31),
+ MX1_PAD_LSCLK = PAD_ID(PD, 6),
+ MX1_PAD_REV = PAD_ID(PD, 7),
+ MX1_PAD_CLS = PAD_ID(PD, 8),
+ MX1_PAD_PS = PAD_ID(PD, 9),
+ MX1_PAD_SPL_SPR = PAD_ID(PD, 10),
+ MX1_PAD_CONTRAST = PAD_ID(PD, 11),
+ MX1_PAD_ACD_OE = PAD_ID(PD, 12),
+ MX1_PAD_LP_HSYNC = PAD_ID(PD, 13),
+ MX1_PAD_FLM_VSYNC = PAD_ID(PD, 14),
+ MX1_PAD_LD0 = PAD_ID(PD, 15),
+ MX1_PAD_LD1 = PAD_ID(PD, 16),
+ MX1_PAD_LD2 = PAD_ID(PD, 17),
+ MX1_PAD_LD3 = PAD_ID(PD, 18),
+ MX1_PAD_LD4 = PAD_ID(PD, 19),
+ MX1_PAD_LD5 = PAD_ID(PD, 20),
+ MX1_PAD_LD6 = PAD_ID(PD, 21),
+ MX1_PAD_LD7 = PAD_ID(PD, 22),
+ MX1_PAD_LD8 = PAD_ID(PD, 23),
+ MX1_PAD_LD9 = PAD_ID(PD, 24),
+ MX1_PAD_LD10 = PAD_ID(PD, 25),
+ MX1_PAD_LD11 = PAD_ID(PD, 26),
+ MX1_PAD_LD12 = PAD_ID(PD, 27),
+ MX1_PAD_LD13 = PAD_ID(PD, 28),
+ MX1_PAD_LD14 = PAD_ID(PD, 29),
+ MX1_PAD_LD15 = PAD_ID(PD, 30),
+ MX1_PAD_TMR2OUT = PAD_ID(PD, 31),
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx1_pinctrl_pads[] = {
+ IMX_PINCTRL_PIN(MX1_PAD_A24),
+ IMX_PINCTRL_PIN(MX1_PAD_TIN),
+ IMX_PINCTRL_PIN(MX1_PAD_PWMO),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_MCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D0),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D1),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D2),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D3),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D4),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D5),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D6),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_D7),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_VSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_HSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_CSI_PIXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_I2C_SDA),
+ IMX_PINCTRL_PIN(MX1_PAD_I2C_SCL),
+ IMX_PINCTRL_PIN(MX1_PAD_DTACK),
+ IMX_PINCTRL_PIN(MX1_PAD_BCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_LBA),
+ IMX_PINCTRL_PIN(MX1_PAD_ECB),
+ IMX_PINCTRL_PIN(MX1_PAD_A0),
+ IMX_PINCTRL_PIN(MX1_PAD_CS4),
+ IMX_PINCTRL_PIN(MX1_PAD_CS5),
+ IMX_PINCTRL_PIN(MX1_PAD_A16),
+ IMX_PINCTRL_PIN(MX1_PAD_A17),
+ IMX_PINCTRL_PIN(MX1_PAD_A18),
+ IMX_PINCTRL_PIN(MX1_PAD_A19),
+ IMX_PINCTRL_PIN(MX1_PAD_A20),
+ IMX_PINCTRL_PIN(MX1_PAD_A21),
+ IMX_PINCTRL_PIN(MX1_PAD_A22),
+ IMX_PINCTRL_PIN(MX1_PAD_A23),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT0),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT1),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT2),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_DAT3),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_SCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SD_CMD),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_SVEN),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_PD),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_TX),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_RX),
+ IMX_PINCTRL_PIN(MX1_PAD_SIM_CLK),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_AFE),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_OE),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_RCV),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_SUSPND),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VP),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VM),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VPO),
+ IMX_PINCTRL_PIN(MX1_PAD_USBD_VMO),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_CTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_RTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_TXD),
+ IMX_PINCTRL_PIN(MX1_PAD_UART2_RXD),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXFS),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_RXDAT),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXDAT),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXFS),
+ IMX_PINCTRL_PIN(MX1_PAD_SSI_TXCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_CTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_RTS),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_TXD),
+ IMX_PINCTRL_PIN(MX1_PAD_UART1_RXD),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_RDY),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_SCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_SS),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_MISO),
+ IMX_PINCTRL_PIN(MX1_PAD_SPI1_MOSI),
+ IMX_PINCTRL_PIN(MX1_PAD_BT13),
+ IMX_PINCTRL_PIN(MX1_PAD_BT12),
+ IMX_PINCTRL_PIN(MX1_PAD_BT11),
+ IMX_PINCTRL_PIN(MX1_PAD_BT10),
+ IMX_PINCTRL_PIN(MX1_PAD_BT9),
+ IMX_PINCTRL_PIN(MX1_PAD_BT8),
+ IMX_PINCTRL_PIN(MX1_PAD_BT7),
+ IMX_PINCTRL_PIN(MX1_PAD_BT6),
+ IMX_PINCTRL_PIN(MX1_PAD_BT5),
+ IMX_PINCTRL_PIN(MX1_PAD_BT4),
+ IMX_PINCTRL_PIN(MX1_PAD_BT3),
+ IMX_PINCTRL_PIN(MX1_PAD_BT2),
+ IMX_PINCTRL_PIN(MX1_PAD_BT1),
+ IMX_PINCTRL_PIN(MX1_PAD_LSCLK),
+ IMX_PINCTRL_PIN(MX1_PAD_REV),
+ IMX_PINCTRL_PIN(MX1_PAD_CLS),
+ IMX_PINCTRL_PIN(MX1_PAD_PS),
+ IMX_PINCTRL_PIN(MX1_PAD_SPL_SPR),
+ IMX_PINCTRL_PIN(MX1_PAD_CONTRAST),
+ IMX_PINCTRL_PIN(MX1_PAD_ACD_OE),
+ IMX_PINCTRL_PIN(MX1_PAD_LP_HSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_FLM_VSYNC),
+ IMX_PINCTRL_PIN(MX1_PAD_LD0),
+ IMX_PINCTRL_PIN(MX1_PAD_LD1),
+ IMX_PINCTRL_PIN(MX1_PAD_LD2),
+ IMX_PINCTRL_PIN(MX1_PAD_LD3),
+ IMX_PINCTRL_PIN(MX1_PAD_LD4),
+ IMX_PINCTRL_PIN(MX1_PAD_LD5),
+ IMX_PINCTRL_PIN(MX1_PAD_LD6),
+ IMX_PINCTRL_PIN(MX1_PAD_LD7),
+ IMX_PINCTRL_PIN(MX1_PAD_LD8),
+ IMX_PINCTRL_PIN(MX1_PAD_LD9),
+ IMX_PINCTRL_PIN(MX1_PAD_LD10),
+ IMX_PINCTRL_PIN(MX1_PAD_LD11),
+ IMX_PINCTRL_PIN(MX1_PAD_LD12),
+ IMX_PINCTRL_PIN(MX1_PAD_LD13),
+ IMX_PINCTRL_PIN(MX1_PAD_LD14),
+ IMX_PINCTRL_PIN(MX1_PAD_LD15),
+ IMX_PINCTRL_PIN(MX1_PAD_TMR2OUT),
+};
+
+static struct imx1_pinctrl_soc_info imx1_pinctrl_info = {
+ .pins = imx1_pinctrl_pads,
+ .npins = ARRAY_SIZE(imx1_pinctrl_pads),
+};
+
+static int __init imx1_pinctrl_probe(struct platform_device *pdev)
+{
+ return imx1_pinctrl_core_probe(pdev, &imx1_pinctrl_info);
+}
+
+static const struct of_device_id imx1_pinctrl_of_match[] = {
+ { .compatible = "fsl,imx1-iomuxc", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match);
+
+static struct platform_driver imx1_pinctrl_driver = {
+ .driver = {
+ .name = "imx1-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = imx1_pinctrl_of_match,
+ },
+ .remove = imx1_pinctrl_core_remove,
+};
+module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-imx27.c b/drivers/pinctrl/pinctrl-imx27.c
index 417c99205bc2..f8dfefb69968 100644
--- a/drivers/pinctrl/pinctrl-imx27.c
+++ b/drivers/pinctrl/pinctrl-imx27.c
@@ -63,10 +63,6 @@ enum imx27_pads {
MX27_PAD_CONTRAST = PAD_ID(PA, 30),
MX27_PAD_OE_ACD = PAD_ID(PA, 31),
- MX27_PAD_UNUSED0 = PAD_ID(PB, 0),
- MX27_PAD_UNUSED1 = PAD_ID(PB, 1),
- MX27_PAD_UNUSED2 = PAD_ID(PB, 2),
- MX27_PAD_UNUSED3 = PAD_ID(PB, 3),
MX27_PAD_SD2_D0 = PAD_ID(PB, 4),
MX27_PAD_SD2_D1 = PAD_ID(PB, 5),
MX27_PAD_SD2_D2 = PAD_ID(PB, 6),
@@ -96,11 +92,6 @@ enum imx27_pads {
MX27_PAD_USBH1_RXDM = PAD_ID(PB, 30),
MX27_PAD_USBH1_RXDP = PAD_ID(PB, 31),
- MX27_PAD_UNUSED4 = PAD_ID(PC, 0),
- MX27_PAD_UNUSED5 = PAD_ID(PC, 1),
- MX27_PAD_UNUSED6 = PAD_ID(PC, 2),
- MX27_PAD_UNUSED7 = PAD_ID(PC, 3),
- MX27_PAD_UNUSED8 = PAD_ID(PC, 4),
MX27_PAD_I2C2_SDA = PAD_ID(PC, 5),
MX27_PAD_I2C2_SCL = PAD_ID(PC, 6),
MX27_PAD_USBOTG_DATA5 = PAD_ID(PC, 7),
@@ -188,12 +179,6 @@ enum imx27_pads {
MX27_PAD_SD1_CLK = PAD_ID(PE, 23),
MX27_PAD_USBOTG_CLK = PAD_ID(PE, 24),
MX27_PAD_USBOTG_DATA7 = PAD_ID(PE, 25),
- MX27_PAD_UNUSED9 = PAD_ID(PE, 26),
- MX27_PAD_UNUSED10 = PAD_ID(PE, 27),
- MX27_PAD_UNUSED11 = PAD_ID(PE, 28),
- MX27_PAD_UNUSED12 = PAD_ID(PE, 29),
- MX27_PAD_UNUSED13 = PAD_ID(PE, 30),
- MX27_PAD_UNUSED14 = PAD_ID(PE, 31),
MX27_PAD_NFRB = PAD_ID(PF, 0),
MX27_PAD_NFCLE = PAD_ID(PF, 1),
@@ -219,14 +204,6 @@ enum imx27_pads {
MX27_PAD_CS4_B = PAD_ID(PF, 21),
MX27_PAD_CS5_B = PAD_ID(PF, 22),
MX27_PAD_ATA_DATA15 = PAD_ID(PF, 23),
- MX27_PAD_UNUSED15 = PAD_ID(PF, 24),
- MX27_PAD_UNUSED16 = PAD_ID(PF, 25),
- MX27_PAD_UNUSED17 = PAD_ID(PF, 26),
- MX27_PAD_UNUSED18 = PAD_ID(PF, 27),
- MX27_PAD_UNUSED19 = PAD_ID(PF, 28),
- MX27_PAD_UNUSED20 = PAD_ID(PF, 29),
- MX27_PAD_UNUSED21 = PAD_ID(PF, 30),
- MX27_PAD_UNUSED22 = PAD_ID(PF, 31),
};
/* Pad names for the pinmux subsystem */
@@ -264,10 +241,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_CONTRAST),
IMX_PINCTRL_PIN(MX27_PAD_OE_ACD),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED0),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED1),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED2),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED3),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D0),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D1),
IMX_PINCTRL_PIN(MX27_PAD_SD2_D2),
@@ -297,11 +270,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDM),
IMX_PINCTRL_PIN(MX27_PAD_USBH1_RXDP),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED4),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED5),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED6),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED7),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED8),
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SDA),
IMX_PINCTRL_PIN(MX27_PAD_I2C2_SCL),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA5),
@@ -389,12 +357,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_SD1_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_CLK),
IMX_PINCTRL_PIN(MX27_PAD_USBOTG_DATA7),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED9),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED10),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED11),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED12),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED13),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED14),
IMX_PINCTRL_PIN(MX27_PAD_NFRB),
IMX_PINCTRL_PIN(MX27_PAD_NFCLE),
@@ -420,14 +382,6 @@ static const struct pinctrl_pin_desc imx27_pinctrl_pads[] = {
IMX_PINCTRL_PIN(MX27_PAD_CS4_B),
IMX_PINCTRL_PIN(MX27_PAD_CS5_B),
IMX_PINCTRL_PIN(MX27_PAD_ATA_DATA15),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED15),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED16),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED17),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED18),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED19),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED20),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED21),
- IMX_PINCTRL_PIN(MX27_PAD_UNUSED22),
};
static struct imx1_pinctrl_soc_info imx27_pinctrl_info = {
@@ -440,12 +394,6 @@ static struct of_device_id imx27_pinctrl_of_match[] = {
{ /* sentinel */ }
};
-struct imx27_pinctrl_private {
- int num_gpio_childs;
- struct platform_device **gpio_dev;
- struct mxc_gpio_platform_data *gpio_pdata;
-};
-
static int imx27_pinctrl_probe(struct platform_device *pdev)
{
return imx1_pinctrl_core_probe(pdev, &imx27_pinctrl_info);
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index bb805d5e9ff0..5e8b2e04cd7a 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -62,11 +62,26 @@ enum rockchip_pinctrl_type {
RK2928,
RK3066B,
RK3188,
+ RK3288,
};
-enum rockchip_pin_bank_type {
- COMMON_BANK,
- RK3188_BANK0,
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY BIT(0)
+#define IOMUX_WIDTH_4BIT BIT(1)
+#define IOMUX_SOURCE_PMU BIT(2)
+#define IOMUX_UNROUTED BIT(3)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ * an initial offset value the relevant source offset can be reset
+ * to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+ int type;
+ int offset;
};
/**
@@ -78,6 +93,7 @@ enum rockchip_pin_bank_type {
* @nr_pins: number of pins in this bank
* @name: name of the bank
* @bank_num: number of the bank, to account for holes
+ * @iomux: array describing the 4 iomux sources of the bank
* @valid: are all necessary informations present
* @of_node: dt node of this bank
* @drvdata: common pinctrl basedata
@@ -95,7 +111,7 @@ struct rockchip_pin_bank {
u8 nr_pins;
char *name;
u8 bank_num;
- enum rockchip_pin_bank_type bank_type;
+ struct rockchip_iomux iomux[4];
bool valid;
struct device_node *of_node;
struct rockchip_pinctrl *drvdata;
@@ -111,6 +127,25 @@ struct rockchip_pin_bank {
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
+ .iomux = { \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ }, \
+ }
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
}
/**
@@ -121,7 +156,8 @@ struct rockchip_pin_ctrl {
u32 nr_pins;
char *label;
enum rockchip_pinctrl_type type;
- int mux_offset;
+ int grf_mux_offset;
+ int pmu_mux_offset;
void (*pull_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit);
@@ -343,24 +379,42 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
unsigned int val;
- int reg, ret;
+ int reg, ret, mask;
u8 bit;
- if (bank->bank_type == RK3188_BANK0 && pin < 16)
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+ dev_err(info->dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
return RK_FUNC_GPIO;
+ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->regmap_pmu : info->regmap_base;
+
/* get basic quadrupel of mux registers and the correct reg inside */
- reg = info->ctrl->mux_offset;
- reg += bank->bank_num * 0x10;
- reg += (pin / 8) * 4;
- bit = (pin % 8) * 2;
+ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+ reg = bank->iomux[iomux_num].offset;
+ if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ } else {
+ bit = (pin % 8) * 2;
+ }
- ret = regmap_read(info->regmap_base, reg, &val);
+ ret = regmap_read(regmap, reg, &val);
if (ret)
return ret;
- return ((val >> bit) & 3);
+ return ((val >> bit) & mask);
}
/*
@@ -379,16 +433,22 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
- int reg, ret;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
+ int reg, ret, mask;
unsigned long flags;
u8 bit;
u32 data;
- /*
- * The first 16 pins of rk3188_bank0 are always gpios and do not have
- * a mux register at all.
- */
- if (bank->bank_type == RK3188_BANK0 && pin < 16) {
+ if (iomux_num > 3)
+ return -EINVAL;
+
+ if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
+ dev_err(info->dev, "pin %d is unrouted\n", pin);
+ return -EINVAL;
+ }
+
+ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
if (mux != RK_FUNC_GPIO) {
dev_err(info->dev,
"pin %d only supports a gpio mux\n", pin);
@@ -401,17 +461,25 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
+ regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->regmap_pmu : info->regmap_base;
+
/* get basic quadrupel of mux registers and the correct reg inside */
- reg = info->ctrl->mux_offset;
- reg += bank->bank_num * 0x10;
- reg += (pin / 8) * 4;
- bit = (pin % 8) * 2;
+ mask = (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) ? 0xf : 0x3;
+ reg = bank->iomux[iomux_num].offset;
+ if (bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ } else {
+ bit = (pin % 8) * 2;
+ }
spin_lock_irqsave(&bank->slock, flags);
- data = (3 << (bit + 16));
- data |= (mux & 3) << bit;
- ret = regmap_write(info->regmap_base, reg, data);
+ data = (mask << (bit + 16));
+ data |= (mux & mask) << bit;
+ ret = regmap_write(regmap, reg, data);
spin_unlock_irqrestore(&bank->slock, flags);
@@ -449,7 +517,7 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
struct rockchip_pinctrl *info = bank->drvdata;
/* The first 12 pins of the first bank are located elsewhere */
- if (bank->bank_type == RK3188_BANK0 && pin_num < 12) {
+ if (bank->bank_num == 0 && pin_num < 12) {
*regmap = info->regmap_pmu ? info->regmap_pmu
: bank->regmap_pull;
*reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0;
@@ -476,6 +544,127 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
}
}
+#define RK3288_PULL_OFFSET 0x140
+static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ *regmap = info->regmap_pmu;
+ *reg = RK3188_PULL_PMU_OFFSET;
+
+ *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+ *bit = pin_num % RK3188_PULL_PINS_PER_REG;
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ } else {
+ *regmap = info->regmap_base;
+ *reg = RK3288_PULL_OFFSET;
+
+ /* correct the offset, as we're starting with the 2nd bank */
+ *reg -= 0x10;
+ *reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
+ *reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3188_PULL_PINS_PER_REG);
+ *bit *= RK3188_PULL_BITS_PER_PIN;
+ }
+}
+
+#define RK3288_DRV_PMU_OFFSET 0x70
+#define RK3288_DRV_GRF_OFFSET 0x1c0
+#define RK3288_DRV_BITS_PER_PIN 2
+#define RK3288_DRV_PINS_PER_REG 8
+#define RK3288_DRV_BANK_STRIDE 16
+static int rk3288_drv_list[] = { 2, 4, 8, 12 };
+
+static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ *regmap = info->regmap_pmu;
+ *reg = RK3288_DRV_PMU_OFFSET;
+
+ *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RK3288_DRV_PINS_PER_REG;
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ } else {
+ *regmap = info->regmap_base;
+ *reg = RK3288_DRV_GRF_OFFSET;
+
+ /* correct the offset, as we're starting with the 2nd bank */
+ *reg -= 0x10;
+ *reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
+ *reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3288_DRV_PINS_PER_REG);
+ *bit *= RK3288_DRV_BITS_PER_PIN;
+ }
+}
+
+static int rk3288_get_drive(struct rockchip_pin_bank *bank, int pin_num)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data;
+ u8 bit;
+
+ rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+ ret = regmap_read(regmap, reg, &data);
+ if (ret)
+ return ret;
+
+ data >>= bit;
+ data &= (1 << RK3288_DRV_BITS_PER_PIN) - 1;
+
+ return rk3288_drv_list[data];
+}
+
+static int rk3288_set_drive(struct rockchip_pin_bank *bank, int pin_num,
+ int strength)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct regmap *regmap;
+ unsigned long flags;
+ int reg, ret, i;
+ u32 data;
+ u8 bit;
+
+ rk3288_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+ ret = -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(rk3288_drv_list); i++) {
+ if (rk3288_drv_list[i] == strength) {
+ ret = i;
+ break;
+ }
+ }
+
+ if (ret < 0) {
+ dev_err(info->dev, "unsupported driver strength %d\n",
+ strength);
+ return ret;
+ }
+
+ spin_lock_irqsave(&bank->slock, flags);
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << RK3288_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+ data |= (ret << bit);
+
+ ret = regmap_write(regmap, reg, data);
+ spin_unlock_irqrestore(&bank->slock, flags);
+
+ return ret;
+}
+
static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
{
struct rockchip_pinctrl *info = bank->drvdata;
@@ -501,6 +690,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
: PIN_CONFIG_BIAS_DISABLE;
case RK3188:
+ case RK3288:
data >>= bit;
data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
@@ -555,6 +745,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
spin_unlock_irqrestore(&bank->slock, flags);
break;
case RK3188:
+ case RK3288:
spin_lock_irqsave(&bank->slock, flags);
/* enable the write to the equivalent lower bits */
@@ -657,23 +848,6 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const unsigned int *pins = info->groups[group].pins;
- struct rockchip_pin_bank *bank;
- int cnt;
-
- dev_dbg(info->dev, "disable function %s group %s\n",
- info->functions[selector].name, info->groups[group].name);
-
- for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
- bank = pin_to_bank(info, pins[cnt]);
- rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
- }
-}
-
/*
* The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -716,7 +890,6 @@ static const struct pinmux_ops rockchip_pmx_ops = {
.get_function_name = rockchip_pmx_get_func_name,
.get_function_groups = rockchip_pmx_get_groups,
.enable = rockchip_pmx_enable,
- .disable = rockchip_pmx_disable,
.gpio_set_direction = rockchip_pmx_gpio_set_direction,
};
@@ -734,6 +907,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
case RK3066B:
return pull ? false : true;
case RK3188:
+ case RK3288:
return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
}
@@ -788,6 +962,15 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc)
return rc;
break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* rk3288 is the first with per-pin drive-strength */
+ if (info->ctrl->type != RK3288)
+ return -ENOTSUPP;
+
+ rc = rk3288_set_drive(bank, pin - bank->pin_base, arg);
+ if (rc < 0)
+ return rc;
+ break;
default:
return -ENOTSUPP;
break;
@@ -837,6 +1020,17 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
arg = rc ? 1 : 0;
break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* rk3288 is the first with per-pin drive-strength */
+ if (info->ctrl->type != RK3288)
+ return -ENOTSUPP;
+
+ rc = rk3288_get_drive(bank, pin - bank->pin_base);
+ if (rc < 0)
+ return rc;
+
+ arg = rc;
+ break;
default:
return -ENOTSUPP;
break;
@@ -850,6 +1044,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
static const struct pinconf_ops rockchip_pinconf_ops = {
.pin_config_get = rockchip_pinconf_get,
.pin_config_set = rockchip_pinconf_set,
+ .is_generic = true,
};
static const struct of_device_id rockchip_bank_match[] = {
@@ -1414,10 +1609,7 @@ fail:
for (--i, --bank; i >= 0; --i, --bank) {
if (!bank->valid)
continue;
-
- if (gpiochip_remove(&bank->gpio_chip))
- dev_err(&pdev->dev, "gpio chip %s remove failed\n",
- bank->gpio_chip.label);
+ gpiochip_remove(&bank->gpio_chip);
}
return ret;
}
@@ -1427,20 +1619,15 @@ static int rockchip_gpiolib_unregister(struct platform_device *pdev,
{
struct rockchip_pin_ctrl *ctrl = info->ctrl;
struct rockchip_pin_bank *bank = ctrl->pin_banks;
- int ret = 0;
int i;
- for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) {
+ for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
if (!bank->valid)
continue;
-
- ret = gpiochip_remove(&bank->gpio_chip);
+ gpiochip_remove(&bank->gpio_chip);
}
- if (ret)
- dev_err(&pdev->dev, "gpio chip remove failed\n");
-
- return ret;
+ return 0;
}
static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
@@ -1466,8 +1653,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
"rockchip,rk3188-gpio-bank0")) {
struct device_node *node;
- bank->bank_type = RK3188_BANK0;
-
node = of_parse_phandle(bank->of_node->parent,
"rockchip,pmu", 0);
if (!node) {
@@ -1487,9 +1672,6 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
base,
&rockchip_regmap_config);
}
-
- } else {
- bank->bank_type = COMMON_BANK;
}
bank->irq = irq_of_parse_and_map(bank->of_node, 0);
@@ -1513,7 +1695,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
struct device_node *np;
struct rockchip_pin_ctrl *ctrl;
struct rockchip_pin_bank *bank;
- int i;
+ int grf_offs, pmu_offs, i, j;
match = of_match_node(rockchip_pinctrl_dt_match, node);
ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -1535,12 +1717,51 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
}
}
+ grf_offs = ctrl->grf_mux_offset;
+ pmu_offs = ctrl->pmu_mux_offset;
bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+ int bank_pins = 0;
+
spin_lock_init(&bank->slock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
+
+ /* calculate iomux offsets */
+ for (j = 0; j < 4; j++) {
+ struct rockchip_iomux *iom = &bank->iomux[j];
+ int inc;
+
+ if (bank_pins >= bank->nr_pins)
+ break;
+
+ /* preset offset value, set new start value */
+ if (iom->offset >= 0) {
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs = iom->offset;
+ else
+ grf_offs = iom->offset;
+ } else { /* set current offset */
+ iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+ pmu_offs : grf_offs;
+ }
+
+ dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n",
+ i, j, iom->offset);
+
+ /*
+ * Increase offset according to iomux width.
+ * 4bit iomux'es are spread over two registers.
+ */
+ inc = (iom->type & IOMUX_WIDTH_4BIT) ? 8 : 4;
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs += inc;
+ else
+ grf_offs += inc;
+
+ bank_pins += 8;
+ }
}
return ctrl;
@@ -1644,7 +1865,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk2928_pin_banks),
.label = "RK2928-GPIO",
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -1662,7 +1883,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
.label = "RK3066a-GPIO",
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -1678,11 +1899,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
.label = "RK3066b-GPIO",
.type = RK3066B,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
};
static struct rockchip_pin_bank rk3188_pin_banks[] = {
- PIN_BANK(0, 32, "gpio0"),
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
PIN_BANK(1, 32, "gpio1"),
PIN_BANK(2, 32, "gpio2"),
PIN_BANK(3, 32, "gpio3"),
@@ -1693,10 +1914,52 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.label = "RK3188-GPIO",
.type = RK3188,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
};
+static struct rockchip_pin_bank rk3288_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
+ IOMUX_SOURCE_PMU,
+ IOMUX_SOURCE_PMU,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
+ IOMUX_UNROUTED,
+ IOMUX_UNROUTED,
+ 0
+ ),
+ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
+ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0,
+ 0
+ ),
+ PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
+ 0,
+ 0,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
+ PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
+ 0,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_UNROUTED
+ ),
+ PIN_BANK(8, 16, "gpio8"),
+};
+
+static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
+ .pin_banks = rk3288_pin_banks,
+ .nr_banks = ARRAY_SIZE(rk3288_pin_banks),
+ .label = "RK3288-GPIO",
+ .type = RK3288,
+ .grf_mux_offset = 0x0,
+ .pmu_mux_offset = 0x84,
+ .pull_calc_reg = rk3288_calc_pull_reg_and_bit,
+};
+
static const struct of_device_id rockchip_pinctrl_dt_match[] = {
{ .compatible = "rockchip,rk2928-pinctrl",
.data = (void *)&rk2928_pin_ctrl },
@@ -1706,6 +1969,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
.data = (void *)&rk3066b_pin_ctrl },
{ .compatible = "rockchip,rk3188-pinctrl",
.data = (void *)&rk3188_pin_ctrl },
+ { .compatible = "rockchip,rk3288-pinctrl",
+ .data = (void *)&rk3288_pin_ctrl },
{},
};
MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 2960557bfed9..95dd9cf55cb3 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -488,61 +488,6 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0;
}
-static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
- unsigned group)
-{
- struct pcs_device *pcs;
- struct pcs_function *func;
- int i;
-
- pcs = pinctrl_dev_get_drvdata(pctldev);
- /* If function mask is null, needn't disable it. */
- if (!pcs->fmask)
- return;
-
- func = radix_tree_lookup(&pcs->ftree, fselector);
- if (!func) {
- dev_err(pcs->dev, "%s could not find function%i\n",
- __func__, fselector);
- return;
- }
-
- /*
- * Ignore disable if function-off is not specified. Some hardware
- * does not have clearly defined disable function. For pin specific
- * off modes, you can use alternate named states as described in
- * pinctrl-bindings.txt.
- */
- if (pcs->foff == PCS_OFF_DISABLED) {
- dev_dbg(pcs->dev, "ignoring disable for %s function%i\n",
- func->name, fselector);
- return;
- }
-
- dev_dbg(pcs->dev, "disabling function%i %s\n",
- fselector, func->name);
-
- for (i = 0; i < func->nvals; i++) {
- struct pcs_func_vals *vals;
- unsigned long flags;
- unsigned val, mask;
-
- vals = &func->vals[i];
- raw_spin_lock_irqsave(&pcs->lock, flags);
- val = pcs->read(vals->reg);
-
- if (pcs->bits_per_mux)
- mask = vals->mask;
- else
- mask = pcs->fmask;
-
- val &= ~mask;
- val |= pcs->foff << pcs->fshift;
- pcs->write(val, vals->reg);
- raw_spin_unlock_irqrestore(&pcs->lock, flags);
- }
-}
-
static int pcs_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned pin)
{
@@ -575,7 +520,6 @@ static const struct pinmux_ops pcs_pinmux_ops = {
.get_function_name = pcs_get_function_name,
.get_function_groups = pcs_get_function_groups,
.enable = pcs_enable,
- .disable = pcs_disable,
.gpio_request_enable = pcs_request_gpio,
};
@@ -836,7 +780,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
pin = &pcs->pins.pa[i];
pn = &pcs->names[i];
- sprintf(pn->name, "%lx.%d",
+ sprintf(pn->name, "%lx.%u",
(unsigned long)pcs->res->start + offset, pin_pos);
pin->name = pn->name;
pin->number = i;
@@ -1739,11 +1683,10 @@ static void pcs_irq_chain_handler(unsigned int irq, struct irq_desc *desc)
{
struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc);
struct irq_chip *chip;
- int res;
chip = irq_get_chip(irq);
chained_irq_enter(chip, desc);
- res = pcs_irq_handle(pcs_soc);
+ pcs_irq_handle(pcs_soc);
/* REVISIT: export and add handle_bad_irq(irq, desc)? */
chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index 1bd6363bc95e..5475374d803f 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -930,11 +930,6 @@ static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
return 0;
}
-static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
-}
-
static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned gpio,
bool input)
@@ -957,7 +952,6 @@ static struct pinmux_ops st_pmxops = {
.get_function_name = st_pmx_get_fname,
.get_function_groups = st_pmx_get_groups,
.enable = st_pmx_enable,
- .disable = st_pmx_disable,
.gpio_set_direction = st_pmx_set_gpio_direction,
};
@@ -1178,9 +1172,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
const __be32 *list;
struct property *pp;
struct st_pinconf *conf;
- phandle phandle;
struct device_node *pins;
- u32 pin;
int i = 0, npins = 0, nr_props;
pins = of_get_child_by_name(np, "st,pins");
@@ -1218,8 +1210,8 @@ static int st_pctl_dt_parse_groups(struct device_node *np,
conf = &grp->pin_conf[i];
/* bank & offset */
- phandle = be32_to_cpup(list++);
- pin = be32_to_cpup(list++);
+ be32_to_cpup(list++);
+ be32_to_cpup(list++);
conf->pin = of_get_named_gpio(pins, pp->name, 0);
conf->name = pp->name;
grp->pins[i] = conf->pin;
@@ -1256,7 +1248,7 @@ static int st_pctl_parse_functions(struct device_node *np,
func = &info->functions[index];
func->name = np->name;
func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
+ if (func->ngroups == 0) {
dev_err(info->dev, "No groups defined\n");
return -EINVAL;
}
@@ -1431,7 +1423,7 @@ static void st_gpio_irqmux_handler(unsigned irq, struct irq_desc *desc)
status = readl(info->irqmux_base);
- for_each_set_bit(n, &status, ST_GPIO_PINS_PER_BANK)
+ for_each_set_bit(n, &status, info->nbanks)
__gpio_irq_handler(&info->banks[n]);
chained_irq_exit(chip, desc);
@@ -1454,6 +1446,7 @@ static struct irq_chip st_gpio_irqchip = {
.irq_mask = st_gpio_irq_mask,
.irq_unmask = st_gpio_irq_unmask,
.irq_set_type = st_gpio_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
};
static int st_gpiolib_register_bank(struct st_pinctrl *info,
diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c
index 26ca6855f478..71c5d4f0c538 100644
--- a/drivers/pinctrl/pinctrl-tb10x.c
+++ b/drivers/pinctrl/pinctrl-tb10x.c
@@ -738,22 +738,6 @@ static int tb10x_pctl_enable(struct pinctrl_dev *pctl,
return 0;
}
-static void tb10x_pctl_disable(struct pinctrl_dev *pctl,
- unsigned func_selector, unsigned group_selector)
-{
- struct tb10x_pinctrl *state = pinctrl_dev_get_drvdata(pctl);
- const struct tb10x_pinfuncgrp *grp = &state->pingroups[group_selector];
-
- if (grp->port < 0)
- return;
-
- mutex_lock(&state->mutex);
-
- state->ports[grp->port].count--;
-
- mutex_unlock(&state->mutex);
-}
-
static struct pinmux_ops tb10x_pinmux_ops = {
.get_functions_count = tb10x_get_functions_count,
.get_function_name = tb10x_get_function_name,
@@ -761,7 +745,6 @@ static struct pinmux_ops tb10x_pinmux_ops = {
.gpio_request_enable = tb10x_gpio_request_enable,
.gpio_disable_free = tb10x_gpio_disable_free,
.enable = tb10x_pctl_enable,
- .disable = tb10x_pctl_disable,
};
static struct pinctrl_desc tb10x_pindesc = {
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
new file mode 100644
index 000000000000..a06620474845
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -0,0 +1,973 @@
+/*
+ * Copyright (c) 2014, NVIDIA 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 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/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+
+#include "core.h"
+#include "pinctrl-utils.h"
+
+#define XUSB_PADCTL_ELPG_PROGRAM 0x01c
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
+
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
+
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
+
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
+
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
+
+struct tegra_xusb_padctl_function {
+ const char *name;
+ const char * const *groups;
+ unsigned int num_groups;
+};
+
+struct tegra_xusb_padctl_group {
+ const unsigned int *funcs;
+ unsigned int num_funcs;
+};
+
+struct tegra_xusb_padctl_soc {
+ const struct pinctrl_pin_desc *pins;
+ unsigned int num_pins;
+
+ const struct tegra_xusb_padctl_function *functions;
+ unsigned int num_functions;
+
+ const struct tegra_xusb_padctl_lane *lanes;
+ unsigned int num_lanes;
+};
+
+struct tegra_xusb_padctl_lane {
+ const char *name;
+
+ unsigned int offset;
+ unsigned int shift;
+ unsigned int mask;
+ unsigned int iddq;
+
+ const unsigned int *funcs;
+ unsigned int num_funcs;
+};
+
+struct tegra_xusb_padctl {
+ struct device *dev;
+ void __iomem *regs;
+ struct mutex lock;
+ struct reset_control *rst;
+
+ const struct tegra_xusb_padctl_soc *soc;
+ struct pinctrl_dev *pinctrl;
+ struct pinctrl_desc desc;
+
+ struct phy_provider *provider;
+ struct phy *phys[2];
+
+ unsigned int enable;
+};
+
+static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,
+ unsigned long offset)
+{
+ writel(value, padctl->regs + offset);
+}
+
+static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
+ unsigned long offset)
+{
+ return readl(padctl->regs + offset);
+}
+
+static int tegra_xusb_padctl_get_groups_count(struct pinctrl_dev *pinctrl)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+
+ return padctl->soc->num_pins;
+}
+
+static const char *tegra_xusb_padctl_get_group_name(struct pinctrl_dev *pinctrl,
+ unsigned int group)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+
+ return padctl->soc->pins[group].name;
+}
+
+enum tegra_xusb_padctl_param {
+ TEGRA_XUSB_PADCTL_IDDQ,
+};
+
+static const struct tegra_xusb_padctl_property {
+ const char *name;
+ enum tegra_xusb_padctl_param param;
+} properties[] = {
+ { "nvidia,iddq", TEGRA_XUSB_PADCTL_IDDQ },
+};
+
+#define TEGRA_XUSB_PADCTL_PACK(param, value) ((param) << 16 | (value))
+#define TEGRA_XUSB_PADCTL_UNPACK_PARAM(config) ((config) >> 16)
+#define TEGRA_XUSB_PADCTL_UNPACK_VALUE(config) ((config) & 0xffff)
+
+static int tegra_xusb_padctl_parse_subnode(struct tegra_xusb_padctl *padctl,
+ struct device_node *np,
+ struct pinctrl_map **maps,
+ unsigned int *reserved_maps,
+ unsigned int *num_maps)
+{
+ unsigned int i, reserve = 0, num_configs = 0;
+ unsigned long config, *configs = NULL;
+ const char *function, *group;
+ struct property *prop;
+ int err = 0;
+ u32 value;
+
+ err = of_property_read_string(np, "nvidia,function", &function);
+ if (err < 0) {
+ if (err != -EINVAL)
+ return err;
+
+ function = NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(properties); i++) {
+ err = of_property_read_u32(np, properties[i].name, &value);
+ if (err < 0) {
+ if (err == -EINVAL)
+ continue;
+
+ return err;
+ }
+
+ config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, value);
+
+ err = pinctrl_utils_add_config(padctl->pinctrl, &configs,
+ &num_configs, config);
+ if (err < 0)
+ return err;
+ }
+
+ if (function)
+ reserve++;
+
+ if (num_configs)
+ reserve++;
+
+ err = of_property_count_strings(np, "nvidia,lanes");
+ if (err < 0)
+ return err;
+
+ reserve *= err;
+
+ err = pinctrl_utils_reserve_map(padctl->pinctrl, maps, reserved_maps,
+ num_maps, reserve);
+ if (err < 0)
+ return err;
+
+ of_property_for_each_string(np, "nvidia,lanes", prop, group) {
+ if (function) {
+ err = pinctrl_utils_add_map_mux(padctl->pinctrl, maps,
+ reserved_maps, num_maps, group,
+ function);
+ if (err < 0)
+ return err;
+ }
+
+ if (num_configs) {
+ err = pinctrl_utils_add_map_configs(padctl->pinctrl,
+ maps, reserved_maps, num_maps, group,
+ configs, num_configs,
+ PIN_MAP_TYPE_CONFIGS_GROUP);
+ if (err < 0)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static int tegra_xusb_padctl_dt_node_to_map(struct pinctrl_dev *pinctrl,
+ struct device_node *parent,
+ struct pinctrl_map **maps,
+ unsigned int *num_maps)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+ unsigned int reserved_maps = 0;
+ struct device_node *np;
+ int err;
+
+ *num_maps = 0;
+ *maps = NULL;
+
+ for_each_child_of_node(parent, np) {
+ err = tegra_xusb_padctl_parse_subnode(padctl, np, maps,
+ &reserved_maps,
+ num_maps);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct pinctrl_ops tegra_xusb_padctl_pinctrl_ops = {
+ .get_groups_count = tegra_xusb_padctl_get_groups_count,
+ .get_group_name = tegra_xusb_padctl_get_group_name,
+ .dt_node_to_map = tegra_xusb_padctl_dt_node_to_map,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int tegra_xusb_padctl_get_functions_count(struct pinctrl_dev *pinctrl)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+
+ return padctl->soc->num_functions;
+}
+
+static const char *
+tegra_xusb_padctl_get_function_name(struct pinctrl_dev *pinctrl,
+ unsigned int function)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+
+ return padctl->soc->functions[function].name;
+}
+
+static int tegra_xusb_padctl_get_function_groups(struct pinctrl_dev *pinctrl,
+ unsigned int function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+
+ *num_groups = padctl->soc->functions[function].num_groups;
+ *groups = padctl->soc->functions[function].groups;
+
+ return 0;
+}
+
+static int tegra_xusb_padctl_pinmux_enable(struct pinctrl_dev *pinctrl,
+ unsigned int function,
+ unsigned int group)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+ const struct tegra_xusb_padctl_lane *lane;
+ unsigned int i;
+ u32 value;
+
+ lane = &padctl->soc->lanes[group];
+
+ for (i = 0; i < lane->num_funcs; i++)
+ if (lane->funcs[i] == function)
+ break;
+
+ if (i >= lane->num_funcs)
+ return -EINVAL;
+
+ value = padctl_readl(padctl, lane->offset);
+ value &= ~(lane->mask << lane->shift);
+ value |= i << lane->shift;
+ padctl_writel(padctl, value, lane->offset);
+
+ return 0;
+}
+
+static const struct pinmux_ops tegra_xusb_padctl_pinmux_ops = {
+ .get_functions_count = tegra_xusb_padctl_get_functions_count,
+ .get_function_name = tegra_xusb_padctl_get_function_name,
+ .get_function_groups = tegra_xusb_padctl_get_function_groups,
+ .enable = tegra_xusb_padctl_pinmux_enable,
+};
+
+static int tegra_xusb_padctl_pinconf_group_get(struct pinctrl_dev *pinctrl,
+ unsigned int group,
+ unsigned long *config)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+ const struct tegra_xusb_padctl_lane *lane;
+ enum tegra_xusb_padctl_param param;
+ u32 value;
+
+ param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(*config);
+ lane = &padctl->soc->lanes[group];
+
+ switch (param) {
+ case TEGRA_XUSB_PADCTL_IDDQ:
+ /* lanes with iddq == 0 don't support this parameter */
+ if (lane->iddq == 0)
+ return -EINVAL;
+
+ value = padctl_readl(padctl, lane->offset);
+
+ if (value & BIT(lane->iddq))
+ value = 0;
+ else
+ value = 1;
+
+ *config = TEGRA_XUSB_PADCTL_PACK(param, value);
+ break;
+
+ default:
+ dev_err(padctl->dev, "invalid configuration parameter: %04x\n",
+ param);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int tegra_xusb_padctl_pinconf_group_set(struct pinctrl_dev *pinctrl,
+ unsigned int group,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct tegra_xusb_padctl *padctl = pinctrl_dev_get_drvdata(pinctrl);
+ const struct tegra_xusb_padctl_lane *lane;
+ enum tegra_xusb_padctl_param param;
+ unsigned long value;
+ unsigned int i;
+ u32 regval;
+
+ lane = &padctl->soc->lanes[group];
+
+ for (i = 0; i < num_configs; i++) {
+ param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(configs[i]);
+ value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(configs[i]);
+
+ switch (param) {
+ case TEGRA_XUSB_PADCTL_IDDQ:
+ /* lanes with iddq == 0 don't support this parameter */
+ if (lane->iddq == 0)
+ return -EINVAL;
+
+ regval = padctl_readl(padctl, lane->offset);
+
+ if (value)
+ regval &= ~BIT(lane->iddq);
+ else
+ regval |= BIT(lane->iddq);
+
+ padctl_writel(padctl, regval, lane->offset);
+ break;
+
+ default:
+ dev_err(padctl->dev,
+ "invalid configuration parameter: %04x\n",
+ param);
+ return -ENOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const char *strip_prefix(const char *s)
+{
+ const char *comma = strchr(s, ',');
+ if (!comma)
+ return s;
+
+ return comma + 1;
+}
+
+static void
+tegra_xusb_padctl_pinconf_group_dbg_show(struct pinctrl_dev *pinctrl,
+ struct seq_file *s,
+ unsigned int group)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(properties); i++) {
+ unsigned long config, value;
+ int err;
+
+ config = TEGRA_XUSB_PADCTL_PACK(properties[i].param, 0);
+
+ err = tegra_xusb_padctl_pinconf_group_get(pinctrl, group,
+ &config);
+ if (err < 0)
+ continue;
+
+ value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
+
+ seq_printf(s, "\n\t%s=%lu\n", strip_prefix(properties[i].name),
+ value);
+ }
+}
+
+static void
+tegra_xusb_padctl_pinconf_config_dbg_show(struct pinctrl_dev *pinctrl,
+ struct seq_file *s,
+ unsigned long config)
+{
+ enum tegra_xusb_padctl_param param;
+ const char *name = "unknown";
+ unsigned long value;
+ unsigned int i;
+
+ param = TEGRA_XUSB_PADCTL_UNPACK_PARAM(config);
+ value = TEGRA_XUSB_PADCTL_UNPACK_VALUE(config);
+
+ for (i = 0; i < ARRAY_SIZE(properties); i++) {
+ if (properties[i].param == param) {
+ name = properties[i].name;
+ break;
+ }
+ }
+
+ seq_printf(s, "%s=%lu", strip_prefix(name), value);
+}
+#endif
+
+static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = {
+ .pin_config_group_get = tegra_xusb_padctl_pinconf_group_get,
+ .pin_config_group_set = tegra_xusb_padctl_pinconf_group_set,
+#ifdef CONFIG_DEBUG_FS
+ .pin_config_group_dbg_show = tegra_xusb_padctl_pinconf_group_dbg_show,
+ .pin_config_config_dbg_show = tegra_xusb_padctl_pinconf_config_dbg_show,
+#endif
+};
+
+static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ mutex_lock(&padctl->lock);
+
+ if (padctl->enable++ > 0)
+ goto out;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ usleep_range(100, 200);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ usleep_range(100, 200);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+out:
+ mutex_unlock(&padctl->lock);
+ return 0;
+}
+
+static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ mutex_lock(&padctl->lock);
+
+ if (WARN_ON(padctl->enable == 0))
+ goto out;
+
+ if (--padctl->enable > 0)
+ goto out;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ usleep_range(100, 200);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ usleep_range(100, 200);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+out:
+ mutex_unlock(&padctl->lock);
+ return 0;
+}
+
+static int tegra_xusb_phy_init(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+
+ return tegra_xusb_padctl_enable(padctl);
+}
+
+static int tegra_xusb_phy_exit(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+
+ return tegra_xusb_padctl_disable(padctl);
+}
+
+static int pcie_phy_power_on(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ unsigned long timeout;
+ int err = -ETIMEDOUT;
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
+ value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |
+ XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |
+ XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ timeout = jiffies + msecs_to_jiffies(50);
+
+ while (time_before(jiffies, timeout)) {
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) {
+ err = 0;
+ break;
+ }
+
+ usleep_range(100, 200);
+ }
+
+ return err;
+}
+
+static int pcie_phy_power_off(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ return 0;
+}
+
+static const struct phy_ops pcie_phy_ops = {
+ .init = tegra_xusb_phy_init,
+ .exit = tegra_xusb_phy_exit,
+ .power_on = pcie_phy_power_on,
+ .power_off = pcie_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int sata_phy_power_on(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ unsigned long timeout;
+ int err = -ETIMEDOUT;
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
+ value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ timeout = jiffies + msecs_to_jiffies(50);
+
+ while (time_before(jiffies, timeout)) {
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) {
+ err = 0;
+ break;
+ }
+
+ usleep_range(100, 200);
+ }
+
+ return err;
+}
+
+static int sata_phy_power_off(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+ value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
+ value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+
+ return 0;
+}
+
+static const struct phy_ops sata_phy_ops = {
+ .init = tegra_xusb_phy_init,
+ .exit = tegra_xusb_phy_exit,
+ .power_on = sata_phy_power_on,
+ .power_off = sata_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static struct phy *tegra_xusb_padctl_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev);
+ unsigned int index = args->args[0];
+
+ if (args->args_count <= 0)
+ return ERR_PTR(-EINVAL);
+
+ if (index > ARRAY_SIZE(padctl->phys))
+ return ERR_PTR(-EINVAL);
+
+ return padctl->phys[index];
+}
+
+#define PIN_OTG_0 0
+#define PIN_OTG_1 1
+#define PIN_OTG_2 2
+#define PIN_ULPI_0 3
+#define PIN_HSIC_0 4
+#define PIN_HSIC_1 5
+#define PIN_PCIE_0 6
+#define PIN_PCIE_1 7
+#define PIN_PCIE_2 8
+#define PIN_PCIE_3 9
+#define PIN_PCIE_4 10
+#define PIN_SATA_0 11
+
+static const struct pinctrl_pin_desc tegra124_pins[] = {
+ PINCTRL_PIN(PIN_OTG_0, "otg-0"),
+ PINCTRL_PIN(PIN_OTG_1, "otg-1"),
+ PINCTRL_PIN(PIN_OTG_2, "otg-2"),
+ PINCTRL_PIN(PIN_ULPI_0, "ulpi-0"),
+ PINCTRL_PIN(PIN_HSIC_0, "hsic-0"),
+ PINCTRL_PIN(PIN_HSIC_1, "hsic-1"),
+ PINCTRL_PIN(PIN_PCIE_0, "pcie-0"),
+ PINCTRL_PIN(PIN_PCIE_1, "pcie-1"),
+ PINCTRL_PIN(PIN_PCIE_2, "pcie-2"),
+ PINCTRL_PIN(PIN_PCIE_3, "pcie-3"),
+ PINCTRL_PIN(PIN_PCIE_4, "pcie-4"),
+ PINCTRL_PIN(PIN_SATA_0, "sata-0"),
+};
+
+static const char * const tegra124_snps_groups[] = {
+ "otg-0",
+ "otg-1",
+ "otg-2",
+ "ulpi-0",
+ "hsic-0",
+ "hsic-1",
+};
+
+static const char * const tegra124_xusb_groups[] = {
+ "otg-0",
+ "otg-1",
+ "otg-2",
+ "ulpi-0",
+ "hsic-0",
+ "hsic-1",
+};
+
+static const char * const tegra124_uart_groups[] = {
+ "otg-0",
+ "otg-1",
+ "otg-2",
+};
+
+static const char * const tegra124_pcie_groups[] = {
+ "pcie-0",
+ "pcie-1",
+ "pcie-2",
+ "pcie-3",
+ "pcie-4",
+ "sata-0",
+};
+
+static const char * const tegra124_usb3_groups[] = {
+ "pcie-0",
+ "pcie-1",
+ "pcie-2",
+ "pcie-3",
+ "pcie-4",
+ "sata-0",
+};
+
+static const char * const tegra124_sata_groups[] = {
+ "pcie-0",
+ "pcie-1",
+ "pcie-2",
+ "pcie-3",
+ "pcie-4",
+ "sata-0",
+};
+
+static const char * const tegra124_rsvd_groups[] = {
+ "otg-0",
+ "otg-1",
+ "otg-2",
+ "pcie-0",
+ "pcie-1",
+ "pcie-2",
+ "pcie-3",
+ "pcie-4",
+ "sata-0",
+};
+
+#define TEGRA124_FUNCTION(_name) \
+ { \
+ .name = #_name, \
+ .num_groups = ARRAY_SIZE(tegra124_##_name##_groups), \
+ .groups = tegra124_##_name##_groups, \
+ }
+
+static struct tegra_xusb_padctl_function tegra124_functions[] = {
+ TEGRA124_FUNCTION(snps),
+ TEGRA124_FUNCTION(xusb),
+ TEGRA124_FUNCTION(uart),
+ TEGRA124_FUNCTION(pcie),
+ TEGRA124_FUNCTION(usb3),
+ TEGRA124_FUNCTION(sata),
+ TEGRA124_FUNCTION(rsvd),
+};
+
+enum tegra124_function {
+ TEGRA124_FUNC_SNPS,
+ TEGRA124_FUNC_XUSB,
+ TEGRA124_FUNC_UART,
+ TEGRA124_FUNC_PCIE,
+ TEGRA124_FUNC_USB3,
+ TEGRA124_FUNC_SATA,
+ TEGRA124_FUNC_RSVD,
+};
+
+static const unsigned int tegra124_otg_functions[] = {
+ TEGRA124_FUNC_SNPS,
+ TEGRA124_FUNC_XUSB,
+ TEGRA124_FUNC_UART,
+ TEGRA124_FUNC_RSVD,
+};
+
+static const unsigned int tegra124_usb_functions[] = {
+ TEGRA124_FUNC_SNPS,
+ TEGRA124_FUNC_XUSB,
+};
+
+static const unsigned int tegra124_pci_functions[] = {
+ TEGRA124_FUNC_PCIE,
+ TEGRA124_FUNC_USB3,
+ TEGRA124_FUNC_SATA,
+ TEGRA124_FUNC_RSVD,
+};
+
+#define TEGRA124_LANE(_name, _offset, _shift, _mask, _iddq, _funcs) \
+ { \
+ .name = _name, \
+ .offset = _offset, \
+ .shift = _shift, \
+ .mask = _mask, \
+ .iddq = _iddq, \
+ .num_funcs = ARRAY_SIZE(tegra124_##_funcs##_functions), \
+ .funcs = tegra124_##_funcs##_functions, \
+ }
+
+static const struct tegra_xusb_padctl_lane tegra124_lanes[] = {
+ TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg),
+ TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg),
+ TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg),
+ TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb),
+ TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb),
+ TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb),
+ TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci),
+ TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci),
+ TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci),
+ TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci),
+ TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci),
+ TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci),
+};
+
+static const struct tegra_xusb_padctl_soc tegra124_soc = {
+ .num_pins = ARRAY_SIZE(tegra124_pins),
+ .pins = tegra124_pins,
+ .num_functions = ARRAY_SIZE(tegra124_functions),
+ .functions = tegra124_functions,
+ .num_lanes = ARRAY_SIZE(tegra124_lanes),
+ .lanes = tegra124_lanes,
+};
+
+static const struct of_device_id tegra_xusb_padctl_of_match[] = {
+ { .compatible = "nvidia,tegra124-xusb-padctl", .data = &tegra124_soc },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
+
+static int tegra_xusb_padctl_probe(struct platform_device *pdev)
+{
+ struct tegra_xusb_padctl *padctl;
+ const struct of_device_id *match;
+ struct resource *res;
+ struct phy *phy;
+ int err;
+
+ padctl = devm_kzalloc(&pdev->dev, sizeof(*padctl), GFP_KERNEL);
+ if (!padctl)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, padctl);
+ mutex_init(&padctl->lock);
+ padctl->dev = &pdev->dev;
+
+ match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node);
+ padctl->soc = match->data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ padctl->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(padctl->regs))
+ return PTR_ERR(padctl->regs);
+
+ padctl->rst = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(padctl->rst))
+ return PTR_ERR(padctl->rst);
+
+ err = reset_control_deassert(padctl->rst);
+ if (err < 0)
+ return err;
+
+ memset(&padctl->desc, 0, sizeof(padctl->desc));
+ padctl->desc.name = dev_name(padctl->dev);
+ padctl->desc.pctlops = &tegra_xusb_padctl_pinctrl_ops;
+ padctl->desc.pmxops = &tegra_xusb_padctl_pinmux_ops;
+ padctl->desc.confops = &tegra_xusb_padctl_pinconf_ops;
+ padctl->desc.owner = THIS_MODULE;
+
+ padctl->pinctrl = pinctrl_register(&padctl->desc, &pdev->dev, padctl);
+ if (!padctl->pinctrl) {
+ dev_err(&pdev->dev, "failed to register pincontrol\n");
+ err = -ENODEV;
+ goto reset;
+ }
+
+ phy = devm_phy_create(&pdev->dev, NULL, &pcie_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ err = PTR_ERR(phy);
+ goto unregister;
+ }
+
+ padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
+ phy_set_drvdata(phy, padctl);
+
+ phy = devm_phy_create(&pdev->dev, NULL, &sata_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ err = PTR_ERR(phy);
+ goto unregister;
+ }
+
+ padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy;
+ phy_set_drvdata(phy, padctl);
+
+ padctl->provider = devm_of_phy_provider_register(&pdev->dev,
+ tegra_xusb_padctl_xlate);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register PHYs: %d\n", err);
+ goto unregister;
+ }
+
+ return 0;
+
+unregister:
+ pinctrl_unregister(padctl->pinctrl);
+reset:
+ reset_control_assert(padctl->rst);
+ return err;
+}
+
+static int tegra_xusb_padctl_remove(struct platform_device *pdev)
+{
+ struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev);
+ int err;
+
+ pinctrl_unregister(padctl->pinctrl);
+
+ err = reset_control_assert(padctl->rst);
+ if (err < 0)
+ dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
+
+ return err;
+}
+
+static struct platform_driver tegra_xusb_padctl_driver = {
+ .driver = {
+ .name = "tegra-xusb-padctl",
+ .of_match_table = tegra_xusb_padctl_of_match,
+ },
+ .probe = tegra_xusb_padctl_probe,
+ .remove = tegra_xusb_padctl_remove,
+};
+module_platform_driver(tegra_xusb_padctl_driver);
+
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_DESCRIPTION("Tegra 124 XUSB Pad Control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 2d43bff74f59..150af5503c09 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -290,24 +290,11 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return 0;
}
-static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- const struct tegra_pingroup *g;
-
- g = &pmx->soc->groups[group];
-
- if (WARN_ON(g->mux_reg < 0))
- return;
-}
-
static const struct pinmux_ops tegra_pinmux_ops = {
.get_functions_count = tegra_pinctrl_get_funcs_count,
.get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups,
.enable = tegra_pinctrl_enable,
- .disable = tegra_pinctrl_disable,
};
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
diff --git a/drivers/pinctrl/pinctrl-tz1090-pdc.c b/drivers/pinctrl/pinctrl-tz1090-pdc.c
index 5bf01c28925e..41e81a35cabb 100644
--- a/drivers/pinctrl/pinctrl-tz1090-pdc.c
+++ b/drivers/pinctrl/pinctrl-tz1090-pdc.c
@@ -574,33 +574,6 @@ static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned int function,
- unsigned int group)
-{
- struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
-
- dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
- __func__,
- function, tz1090_pdc_functions[function].name,
- group, tz1090_pdc_groups[group].name);
-
- /* is it even a mux? */
- if (grp->drv)
- return;
-
- /* does this group even control the function? */
- if (function != grp->func)
- return;
-
- /* record the pin being unmuxed and update mux bit */
- spin_lock(&pmx->lock);
- pmx->mux_en &= ~BIT(grp->pins[0]);
- tz1090_pdc_pinctrl_mux(pmx, grp);
- spin_unlock(&pmx->lock);
-}
-
static const struct tz1090_pdc_pingroup *find_mux_group(
struct tz1090_pdc_pmx *pmx,
unsigned int pin)
@@ -662,7 +635,6 @@ static struct pinmux_ops tz1090_pdc_pinmux_ops = {
.get_function_name = tz1090_pdc_pinctrl_get_func_name,
.get_function_groups = tz1090_pdc_pinctrl_get_func_groups,
.enable = tz1090_pdc_pinctrl_enable,
- .disable = tz1090_pdc_pinctrl_disable,
.gpio_request_enable = tz1090_pdc_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pdc_pinctrl_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-tz1090.c b/drivers/pinctrl/pinctrl-tz1090.c
index bc9cd7a7602e..24082216842e 100644
--- a/drivers/pinctrl/pinctrl-tz1090.c
+++ b/drivers/pinctrl/pinctrl-tz1090.c
@@ -1479,63 +1479,6 @@ mux_pins:
}
/**
- * tz1090_pinctrl_disable() - Disable a function on a pin group.
- * @pctldev: Pin control data
- * @function: Function index to disable
- * @group: Group index to disable
- *
- * Disable a particular function on a group of pins. The per GPIO pin pseudo pin
- * groups can be used (in which case the pin will be taken out of peripheral
- * mode. Some convenience pin groups can also be used in which case the effect
- * is the same as enabling the function on each individual pin in the group.
- */
-static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned int function, unsigned int group)
-{
- struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
- struct tz1090_pingroup *grp;
- unsigned int pin_num, mux_group, i, npins;
- const unsigned int *pins;
-
- /* group of pins? */
- if (group < ARRAY_SIZE(tz1090_groups)) {
- grp = &tz1090_groups[group];
- npins = grp->npins;
- pins = grp->pins;
- /*
- * All pins in the group must belong to the same mux group,
- * which allows us to just use the mux group of the first pin.
- * By explicitly listing permitted pingroups for each function
- * the pinmux core should ensure this is always the case.
- */
- } else {
- pin_num = group - ARRAY_SIZE(tz1090_groups);
- npins = 1;
- pins = &pin_num;
- }
- mux_group = tz1090_mux_pins[*pins];
-
- /* no mux group, but can still be individually muxed to peripheral */
- if (mux_group >= TZ1090_MUX_GROUP_MAX) {
- if (function == TZ1090_MUX_PERIP)
- goto unmux_pins;
- return;
- }
-
- /* mux group already set to a different function? */
- grp = &tz1090_mux_groups[mux_group];
- dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n",
- __func__, npins, grp->name, tz1090_functions[function].name);
-
- /* subtract pins from ref count and unmux individually */
- WARN_ON(grp->func_count < npins);
- grp->func_count -= npins;
-unmux_pins:
- for (i = 0; i < npins; ++i)
- tz1090_pinctrl_perip_select(pmx, pins[i], false);
-}
-
-/**
* tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
* @pctldev: Pin control data
* @range: GPIO range
@@ -1575,7 +1518,6 @@ static struct pinmux_ops tz1090_pinmux_ops = {
.get_function_name = tz1090_pinctrl_get_func_name,
.get_function_groups = tz1090_pinctrl_get_func_groups,
.enable = tz1090_pinctrl_enable,
- .disable = tz1090_pinctrl_disable,
.gpio_request_enable = tz1090_pinctrl_gpio_request_enable,
.gpio_disable_free = tz1090_pinctrl_gpio_disable_free,
};
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index 209a01b8bd3b..0959bb36450f 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -970,19 +970,6 @@ static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
return 0;
}
-static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct u300_pmx *upmx;
-
- /* There is nothing to do with the power pins */
- if (selector == 0)
- return;
-
- upmx = pinctrl_dev_get_drvdata(pctldev);
- u300_pmx_endisable(upmx, selector, false);
-}
-
static int u300_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
{
return ARRAY_SIZE(u300_pmx_functions);
@@ -1008,7 +995,6 @@ static const struct pinmux_ops u300_pmx_ops = {
.get_function_name = u300_pmx_get_func_name,
.get_function_groups = u300_pmx_get_groups,
.enable = u300_pmx_enable,
- .disable = u300_pmx_disable,
};
static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 051e8592990e..c055daf9a80f 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -471,7 +471,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- const struct pinmux_ops *ops = pctldev->desc->pmxops;
int ret = 0;
const unsigned *pins = NULL;
unsigned num_pins = 0;
@@ -518,9 +517,6 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
pins[i], desc->name, gname);
}
}
-
- if (ops->disable)
- ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
}
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
new file mode 100644
index 000000000000..d160a710d704
--- /dev/null
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -0,0 +1,42 @@
+if (ARCH_QCOM || COMPILE_TEST)
+
+config PINCTRL_MSM
+ bool
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
+ select GPIOLIB_IRQCHIP
+
+config PINCTRL_APQ8064
+ tristate "Qualcomm APQ8064 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm APQ8064 platform.
+
+config PINCTRL_IPQ8064
+ tristate "Qualcomm IPQ8064 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm IPQ8064 platform.
+
+config PINCTRL_MSM8960
+ tristate "Qualcomm 8960 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm 8960 platform.
+
+config PINCTRL_MSM8X74
+ tristate "Qualcomm 8x74 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm TLMM block found in the Qualcomm 8974 platform.
+
+endif
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
new file mode 100644
index 000000000000..2a02602d715c
--- /dev/null
+++ b/drivers/pinctrl/qcom/Makefile
@@ -0,0 +1,6 @@
+# Qualcomm pin control drivers
+obj-$(CONFIG_PINCTRL_MSM) += pinctrl-msm.o
+obj-$(CONFIG_PINCTRL_APQ8064) += pinctrl-apq8064.o
+obj-$(CONFIG_PINCTRL_IPQ8064) += pinctrl-ipq8064.o
+obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o
+obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o
diff --git a/drivers/pinctrl/pinctrl-apq8064.c b/drivers/pinctrl/qcom/pinctrl-apq8064.c
index 519f7886b0f1..feb6f152f9b7 100644
--- a/drivers/pinctrl/pinctrl-apq8064.c
+++ b/drivers/pinctrl/qcom/pinctrl-apq8064.c
@@ -230,7 +230,7 @@ static const unsigned int sdc3_data_pins[] = { 95 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- APQ_MUX_NA, /* gpio mode */ \
+ APQ_MUX_gpio, \
APQ_MUX_##f1, \
APQ_MUX_##f2, \
APQ_MUX_##f3, \
@@ -293,6 +293,7 @@ enum apq8064_functions {
APQ_MUX_cam_mclk,
APQ_MUX_codec_mic_i2s,
APQ_MUX_codec_spkr_i2s,
+ APQ_MUX_gpio,
APQ_MUX_gsbi1,
APQ_MUX_gsbi2,
APQ_MUX_gsbi3,
@@ -335,6 +336,21 @@ static const char * const codec_mic_i2s_groups[] = {
static const char * const codec_spkr_i2s_groups[] = {
"gpio39", "gpio40", "gpio41", "gpio42"
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89"
+};
static const char * const gsbi1_groups[] = {
"gpio18", "gpio19", "gpio20", "gpio21"
};
@@ -430,6 +446,7 @@ static const struct msm_function apq8064_functions[] = {
FUNCTION(cam_mclk),
FUNCTION(codec_mic_i2s),
FUNCTION(codec_spkr_i2s),
+ FUNCTION(gpio),
FUNCTION(gsbi1),
FUNCTION(gsbi2),
FUNCTION(gsbi3),
diff --git a/drivers/pinctrl/pinctrl-ipq8064.c b/drivers/pinctrl/qcom/pinctrl-ipq8064.c
index acafea4c3a33..767cf1120b20 100644
--- a/drivers/pinctrl/pinctrl-ipq8064.c
+++ b/drivers/pinctrl/qcom/pinctrl-ipq8064.c
@@ -183,7 +183,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- IPQ_MUX_NA, /* gpio mode */ \
+ IPQ_MUX_gpio, \
IPQ_MUX_##f1, \
IPQ_MUX_##f2, \
IPQ_MUX_##f3, \
@@ -243,6 +243,7 @@ static const unsigned int sdc3_data_pins[] = { 71 };
}
enum ipq8064_functions {
+ IPQ_MUX_gpio,
IPQ_MUX_mdio,
IPQ_MUX_mi2s,
IPQ_MUX_pdm,
@@ -291,6 +292,19 @@ enum ipq8064_functions {
IPQ_MUX_NA,
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"
+};
+
static const char * const mdio_groups[] = {
"gpio0", "gpio1", "gpio10", "gpio11",
};
@@ -481,6 +495,7 @@ static const char * const ps_hold_groups[] = {
};
static const struct msm_function ipq8064_functions[] = {
+ FUNCTION(gpio),
FUNCTION(mdio),
FUNCTION(ssbi),
FUNCTION(spmi),
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index df6dda4ce803..2738108caff2 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -27,10 +27,10 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include "core.h"
-#include "pinconf.h"
+#include "../core.h"
+#include "../pinconf.h"
#include "pinctrl-msm.h"
-#include "pinctrl-utils.h"
+#include "../pinctrl-utils.h"
#define MAX_NR_GPIO 300
@@ -142,9 +142,6 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
g = &pctrl->soc->groups[group];
- if (WARN_ON(g->mux_bit < 0))
- return -EINVAL;
-
for (i = 0; i < g->nfuncs; i++) {
if (g->funcs[i] == function)
break;
@@ -165,36 +162,11 @@ static int msm_pinmux_enable(struct pinctrl_dev *pctldev,
return 0;
}
-static void msm_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned function,
- unsigned group)
-{
- struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
- const struct msm_pingroup *g;
- unsigned long flags;
- u32 val;
-
- g = &pctrl->soc->groups[group];
-
- if (WARN_ON(g->mux_bit < 0))
- return;
-
- spin_lock_irqsave(&pctrl->lock, flags);
-
- /* Clear the mux bits to select gpio mode */
- val = readl(pctrl->regs + g->ctl_reg);
- val &= ~(0x7 << g->mux_bit);
- writel(val, pctrl->regs + g->ctl_reg);
-
- spin_unlock_irqrestore(&pctrl->lock, flags);
-}
-
static const struct pinmux_ops msm_pinmux_ops = {
.get_functions_count = msm_get_functions_count,
.get_function_name = msm_get_function_name,
.get_function_groups = msm_get_function_groups,
.enable = msm_pinmux_enable,
- .disable = msm_pinmux_disable,
};
static int msm_config_reg(struct msm_pinctrl *pctrl,
@@ -206,6 +178,7 @@ static int msm_config_reg(struct msm_pinctrl *pctrl,
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_BUS_HOLD:
case PIN_CONFIG_BIAS_PULL_UP:
*bit = g->pull_bit;
*mask = 3;
@@ -243,6 +216,7 @@ static int msm_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
#define MSM_NO_PULL 0
#define MSM_PULL_DOWN 1
+#define MSM_KEEPER 2
#define MSM_PULL_UP 3
static unsigned msm_regval_to_drive(u32 val)
@@ -280,6 +254,9 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = arg == MSM_PULL_DOWN;
break;
+ case PIN_CONFIG_BIAS_BUS_HOLD:
+ arg = arg == MSM_KEEPER;
+ break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = arg == MSM_PULL_UP;
break;
@@ -339,6 +316,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev,
case PIN_CONFIG_BIAS_PULL_DOWN:
arg = MSM_PULL_DOWN;
break;
+ case PIN_CONFIG_BIAS_BUS_HOLD:
+ arg = MSM_KEEPER;
+ break;
case PIN_CONFIG_BIAS_PULL_UP:
arg = MSM_PULL_UP;
break;
diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
index 7b2a227a590a..7b2a227a590a 100644
--- a/drivers/pinctrl/pinctrl-msm.h
+++ b/drivers/pinctrl/qcom/pinctrl-msm.h
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8960.c b/drivers/pinctrl/qcom/pinctrl-msm8960.c
new file mode 100644
index 000000000000..35047036a053
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-msm8960.c
@@ -0,0 +1,1282 @@
+/*
+ * Copyright (c) 2014, Sony Mobile Communications AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-msm.h"
+
+static const struct pinctrl_pin_desc msm8960_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "GPIO_100"),
+ PINCTRL_PIN(101, "GPIO_101"),
+ PINCTRL_PIN(102, "GPIO_102"),
+ PINCTRL_PIN(103, "GPIO_103"),
+ PINCTRL_PIN(104, "GPIO_104"),
+ PINCTRL_PIN(105, "GPIO_105"),
+ PINCTRL_PIN(106, "GPIO_106"),
+ PINCTRL_PIN(107, "GPIO_107"),
+ PINCTRL_PIN(108, "GPIO_108"),
+ PINCTRL_PIN(109, "GPIO_109"),
+ PINCTRL_PIN(110, "GPIO_110"),
+ PINCTRL_PIN(111, "GPIO_111"),
+ PINCTRL_PIN(112, "GPIO_112"),
+ PINCTRL_PIN(113, "GPIO_113"),
+ PINCTRL_PIN(114, "GPIO_114"),
+ PINCTRL_PIN(115, "GPIO_115"),
+ PINCTRL_PIN(116, "GPIO_116"),
+ PINCTRL_PIN(117, "GPIO_117"),
+ PINCTRL_PIN(118, "GPIO_118"),
+ PINCTRL_PIN(119, "GPIO_119"),
+ PINCTRL_PIN(120, "GPIO_120"),
+ PINCTRL_PIN(121, "GPIO_121"),
+ PINCTRL_PIN(122, "GPIO_122"),
+ PINCTRL_PIN(123, "GPIO_123"),
+ PINCTRL_PIN(124, "GPIO_124"),
+ PINCTRL_PIN(125, "GPIO_125"),
+ PINCTRL_PIN(126, "GPIO_126"),
+ PINCTRL_PIN(127, "GPIO_127"),
+ PINCTRL_PIN(128, "GPIO_128"),
+ PINCTRL_PIN(129, "GPIO_129"),
+ PINCTRL_PIN(130, "GPIO_130"),
+ PINCTRL_PIN(131, "GPIO_131"),
+ PINCTRL_PIN(132, "GPIO_132"),
+ PINCTRL_PIN(133, "GPIO_133"),
+ PINCTRL_PIN(134, "GPIO_134"),
+ PINCTRL_PIN(135, "GPIO_135"),
+ PINCTRL_PIN(136, "GPIO_136"),
+ PINCTRL_PIN(137, "GPIO_137"),
+ PINCTRL_PIN(138, "GPIO_138"),
+ PINCTRL_PIN(139, "GPIO_139"),
+ PINCTRL_PIN(140, "GPIO_140"),
+ PINCTRL_PIN(141, "GPIO_141"),
+ PINCTRL_PIN(142, "GPIO_142"),
+ PINCTRL_PIN(143, "GPIO_143"),
+ PINCTRL_PIN(144, "GPIO_144"),
+ PINCTRL_PIN(145, "GPIO_145"),
+ PINCTRL_PIN(146, "GPIO_146"),
+ PINCTRL_PIN(147, "GPIO_147"),
+ PINCTRL_PIN(148, "GPIO_148"),
+ PINCTRL_PIN(149, "GPIO_149"),
+ PINCTRL_PIN(150, "GPIO_150"),
+ PINCTRL_PIN(151, "GPIO_151"),
+
+ PINCTRL_PIN(152, "SDC1_CLK"),
+ PINCTRL_PIN(153, "SDC1_CMD"),
+ PINCTRL_PIN(154, "SDC1_DATA"),
+ PINCTRL_PIN(155, "SDC3_CLK"),
+ PINCTRL_PIN(156, "SDC3_CMD"),
+ PINCTRL_PIN(157, "SDC3_DATA"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+DECLARE_MSM_GPIO_PINS(142);
+DECLARE_MSM_GPIO_PINS(143);
+DECLARE_MSM_GPIO_PINS(144);
+DECLARE_MSM_GPIO_PINS(145);
+DECLARE_MSM_GPIO_PINS(146);
+DECLARE_MSM_GPIO_PINS(147);
+DECLARE_MSM_GPIO_PINS(148);
+DECLARE_MSM_GPIO_PINS(149);
+DECLARE_MSM_GPIO_PINS(150);
+DECLARE_MSM_GPIO_PINS(151);
+
+static const unsigned int sdc1_clk_pins[] = { 152 };
+static const unsigned int sdc1_cmd_pins[] = { 153 };
+static const unsigned int sdc1_data_pins[] = { 154 };
+static const unsigned int sdc3_clk_pins[] = { 155 };
+static const unsigned int sdc3_cmd_pins[] = { 156 };
+static const unsigned int sdc3_data_pins[] = { 157 };
+
+#define FUNCTION(fname) \
+ [MSM_MUX_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = (int[]){ \
+ MSM_MUX_gpio, \
+ MSM_MUX_##f1, \
+ MSM_MUX_##f2, \
+ MSM_MUX_##f3, \
+ MSM_MUX_##f4, \
+ MSM_MUX_##f5, \
+ MSM_MUX_##f6, \
+ MSM_MUX_##f7, \
+ MSM_MUX_##f8, \
+ MSM_MUX_##f9, \
+ MSM_MUX_##f10, \
+ MSM_MUX_##f11 \
+ }, \
+ .nfuncs = 12, \
+ .ctl_reg = 0x1000 + 0x10 * id, \
+ .io_reg = 0x1004 + 0x10 * id, \
+ .intr_cfg_reg = 0x1008 + 0x10 * id, \
+ .intr_status_reg = 0x100c + 0x10 * id, \
+ .intr_target_reg = 0x400 + 0x4 * id, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_ack_high = 1, \
+ .intr_target_bit = 0, \
+ .intr_raw_status_bit = 3, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 1, \
+ }
+
+#define SDC_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+
+enum msm8960_functions {
+ MSM_MUX_audio_pcm,
+ MSM_MUX_bt,
+ MSM_MUX_cam_mclk0,
+ MSM_MUX_cam_mclk1,
+ MSM_MUX_cam_mclk2,
+ MSM_MUX_codec_mic_i2s,
+ MSM_MUX_codec_spkr_i2s,
+ MSM_MUX_ext_gps,
+ MSM_MUX_fm,
+ MSM_MUX_gps_blanking,
+ MSM_MUX_gps_pps_in,
+ MSM_MUX_gps_pps_out,
+ MSM_MUX_gp_clk_0a,
+ MSM_MUX_gp_clk_0b,
+ MSM_MUX_gp_clk_1a,
+ MSM_MUX_gp_clk_1b,
+ MSM_MUX_gp_clk_2a,
+ MSM_MUX_gp_clk_2b,
+ MSM_MUX_gp_mn,
+ MSM_MUX_gp_pdm_0a,
+ MSM_MUX_gp_pdm_0b,
+ MSM_MUX_gp_pdm_1a,
+ MSM_MUX_gp_pdm_1b,
+ MSM_MUX_gp_pdm_2a,
+ MSM_MUX_gp_pdm_2b,
+ MSM_MUX_gpio,
+ MSM_MUX_gsbi1,
+ MSM_MUX_gsbi1_spi_cs1_n,
+ MSM_MUX_gsbi1_spi_cs2a_n,
+ MSM_MUX_gsbi1_spi_cs2b_n,
+ MSM_MUX_gsbi1_spi_cs3_n,
+ MSM_MUX_gsbi2,
+ MSM_MUX_gsbi2_spi_cs1_n,
+ MSM_MUX_gsbi2_spi_cs2_n,
+ MSM_MUX_gsbi2_spi_cs3_n,
+ MSM_MUX_gsbi3,
+ MSM_MUX_gsbi4,
+ MSM_MUX_gsbi4_3d_cam_i2c_l,
+ MSM_MUX_gsbi4_3d_cam_i2c_r,
+ MSM_MUX_gsbi5,
+ MSM_MUX_gsbi5_3d_cam_i2c_l,
+ MSM_MUX_gsbi5_3d_cam_i2c_r,
+ MSM_MUX_gsbi6,
+ MSM_MUX_gsbi7,
+ MSM_MUX_gsbi8,
+ MSM_MUX_gsbi9,
+ MSM_MUX_gsbi10,
+ MSM_MUX_gsbi11,
+ MSM_MUX_gsbi11_spi_cs1a_n,
+ MSM_MUX_gsbi11_spi_cs1b_n,
+ MSM_MUX_gsbi11_spi_cs2a_n,
+ MSM_MUX_gsbi11_spi_cs2b_n,
+ MSM_MUX_gsbi11_spi_cs3_n,
+ MSM_MUX_gsbi12,
+ MSM_MUX_hdmi_cec,
+ MSM_MUX_hdmi_ddc_clock,
+ MSM_MUX_hdmi_ddc_data,
+ MSM_MUX_hdmi_hot_plug_detect,
+ MSM_MUX_hsic,
+ MSM_MUX_mdp_vsync,
+ MSM_MUX_mi2s,
+ MSM_MUX_mic_i2s,
+ MSM_MUX_pmb_clk,
+ MSM_MUX_pmb_ext_ctrl,
+ MSM_MUX_ps_hold,
+ MSM_MUX_rpm_wdog,
+ MSM_MUX_sdc2,
+ MSM_MUX_sdc4,
+ MSM_MUX_sdc5,
+ MSM_MUX_slimbus1,
+ MSM_MUX_slimbus2,
+ MSM_MUX_spkr_i2s,
+ MSM_MUX_ssbi1,
+ MSM_MUX_ssbi2,
+ MSM_MUX_ssbi_ext_gps,
+ MSM_MUX_ssbi_pmic2,
+ MSM_MUX_ssbi_qpa1,
+ MSM_MUX_ssbi_ts,
+ MSM_MUX_tsif1,
+ MSM_MUX_tsif2,
+ MSM_MUX_ts_eoc,
+ MSM_MUX_usb_fs1,
+ MSM_MUX_usb_fs1_oe,
+ MSM_MUX_usb_fs1_oe_n,
+ MSM_MUX_usb_fs2,
+ MSM_MUX_usb_fs2_oe,
+ MSM_MUX_usb_fs2_oe_n,
+ MSM_MUX_vfe_camif_timer1_a,
+ MSM_MUX_vfe_camif_timer1_b,
+ MSM_MUX_vfe_camif_timer2,
+ MSM_MUX_vfe_camif_timer3_a,
+ MSM_MUX_vfe_camif_timer3_b,
+ MSM_MUX_vfe_camif_timer4_a,
+ MSM_MUX_vfe_camif_timer4_b,
+ MSM_MUX_vfe_camif_timer4_c,
+ MSM_MUX_vfe_camif_timer5_a,
+ MSM_MUX_vfe_camif_timer5_b,
+ MSM_MUX_vfe_camif_timer6_a,
+ MSM_MUX_vfe_camif_timer6_b,
+ MSM_MUX_vfe_camif_timer6_c,
+ MSM_MUX_vfe_camif_timer7_a,
+ MSM_MUX_vfe_camif_timer7_b,
+ MSM_MUX_vfe_camif_timer7_c,
+ MSM_MUX_wlan,
+ MSM_MUX_NA,
+};
+
+static const char * const audio_pcm_groups[] = {
+ "gpio63", "gpio64", "gpio65", "gpio66"
+};
+
+static const char * const bt_groups[] = {
+ "gpio28", "gpio29", "gpio83"
+};
+
+static const char * const cam_mclk0_groups[] = {
+ "gpio5"
+};
+
+static const char * const cam_mclk1_groups[] = {
+ "gpio4"
+};
+
+static const char * const cam_mclk2_groups[] = {
+ "gpio2"
+};
+
+static const char * const codec_mic_i2s_groups[] = {
+ "gpio54", "gpio55", "gpio56", "gpio57", "gpio58"
+};
+
+static const char * const codec_spkr_i2s_groups[] = {
+ "gpio59", "gpio60", "gpio61", "gpio62"
+};
+
+static const char * const ext_gps_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const fm_groups[] = {
+ "gpio26", "gpio27"
+};
+
+static const char * const gps_blanking_groups[] = {
+ "gpio137"
+};
+
+static const char * const gps_pps_in_groups[] = {
+ "gpio37"
+};
+
+static const char * const gps_pps_out_groups[] = {
+ "gpio37"
+};
+
+static const char * const gp_clk_0a_groups[] = {
+ "gpio3"
+};
+
+static const char * const gp_clk_0b_groups[] = {
+ "gpio54"
+};
+
+static const char * const gp_clk_1a_groups[] = {
+ "gpio4"
+};
+
+static const char * const gp_clk_1b_groups[] = {
+ "gpio70"
+};
+
+static const char * const gp_clk_2a_groups[] = {
+ "gpio52"
+};
+
+static const char * const gp_clk_2b_groups[] = {
+ "gpio37"
+};
+
+static const char * const gp_mn_groups[] = {
+ "gpio2"
+};
+
+static const char * const gp_pdm_0a_groups[] = {
+ "gpio58"
+};
+
+static const char * const gp_pdm_0b_groups[] = {
+ "gpio39"
+};
+
+static const char * const gp_pdm_1a_groups[] = {
+ "gpio94"
+};
+
+static const char * const gp_pdm_1b_groups[] = {
+ "gpio64"
+};
+
+static const char * const gp_pdm_2a_groups[] = {
+ "gpio69"
+};
+
+static const char * const gp_pdm_2b_groups[] = {
+ "gpio53"
+};
+
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "gpio146",
+ "gpio147", "gpio148", "gpio149", "gpio150", "gpio151"
+};
+
+static const char * const gsbi1_groups[] = {
+ "gpio6", "gpio7", "gpio8", "gpio9"
+};
+
+static const char * const gsbi1_spi_cs1_n_groups[] = {
+ "gpio14"
+};
+
+static const char * const gsbi1_spi_cs2a_n_groups[] = {
+ "gpio15"
+};
+
+static const char * const gsbi1_spi_cs2b_n_groups[] = {
+ "gpio17"
+};
+
+static const char * const gsbi1_spi_cs3_n_groups[] = {
+ "gpio16"
+};
+
+static const char * const gsbi2_groups[] = {
+ "gpio10", "gpio11", "gpio12", "gpio13"
+};
+
+static const char * const gsbi2_spi_cs1_n_groups[] = {
+ "gpio52"
+};
+
+static const char * const gsbi2_spi_cs2_n_groups[] = {
+ "gpio68"
+};
+
+static const char * const gsbi2_spi_cs3_n_groups[] = {
+ "gpio56"
+};
+
+static const char * const gsbi3_groups[] = {
+ "gpio14", "gpio15", "gpio16", "gpio17"
+};
+
+static const char * const gsbi4_groups[] = {
+ "gpio18", "gpio19", "gpio20", "gpio21"
+};
+
+static const char * const gsbi4_3d_cam_i2c_l_groups[] = {
+ "gpio18", "gpio19"
+};
+
+static const char * const gsbi4_3d_cam_i2c_r_groups[] = {
+ "gpio20", "gpio21"
+};
+
+static const char * const gsbi5_groups[] = {
+ "gpio22", "gpio23", "gpio24", "gpio25"
+};
+
+static const char * const gsbi5_3d_cam_i2c_l_groups[] = {
+ "gpio22", "gpio23"
+};
+
+static const char * const gsbi5_3d_cam_i2c_r_groups[] = {
+ "gpio24", "gpio25"
+};
+
+static const char * const gsbi6_groups[] = {
+ "gpio26", "gpio27", "gpio28", "gpio29"
+};
+
+static const char * const gsbi7_groups[] = {
+ "gpio30", "gpio31", "gpio32", "gpio33"
+};
+
+static const char * const gsbi8_groups[] = {
+ "gpio34", "gpio35", "gpio36", "gpio37"
+};
+
+static const char * const gsbi9_groups[] = {
+ "gpio93", "gpio94", "gpio95", "gpio96"
+};
+
+static const char * const gsbi10_groups[] = {
+ "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const gsbi11_groups[] = {
+ "gpio38", "gpio39", "gpio40", "gpio41"
+};
+
+static const char * const gsbi11_spi_cs1a_n_groups[] = {
+ "gpio36"
+};
+
+static const char * const gsbi11_spi_cs1b_n_groups[] = {
+ "gpio18"
+};
+
+static const char * const gsbi11_spi_cs2a_n_groups[] = {
+ "gpio37"
+};
+
+static const char * const gsbi11_spi_cs2b_n_groups[] = {
+ "gpio19"
+};
+
+static const char * const gsbi11_spi_cs3_n_groups[] = {
+ "gpio76"
+};
+
+static const char * const gsbi12_groups[] = {
+ "gpio42", "gpio43", "gpio44", "gpio45"
+};
+
+static const char * const hdmi_cec_groups[] = {
+ "gpio99"
+};
+
+static const char * const hdmi_ddc_clock_groups[] = {
+ "gpio100"
+};
+
+static const char * const hdmi_ddc_data_groups[] = {
+ "gpio101"
+};
+
+static const char * const hdmi_hot_plug_detect_groups[] = {
+ "gpio102"
+};
+
+static const char * const hsic_groups[] = {
+ "gpio150", "gpio151"
+};
+
+static const char * const mdp_vsync_groups[] = {
+ "gpio0", "gpio1", "gpio19"
+};
+
+static const char * const mi2s_groups[] = {
+ "gpio47", "gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53"
+};
+
+static const char * const mic_i2s_groups[] = {
+ "gpio71", "gpio72", "gpio73", "gpio74"
+};
+
+static const char * const pmb_clk_groups[] = {
+ "gpio21", "gpio86", "gpio112"
+};
+
+static const char * const pmb_ext_ctrl_groups[] = {
+ "gpio4", "gpio5"
+};
+
+static const char * const ps_hold_groups[] = {
+ "gpio108"
+};
+
+static const char * const rpm_wdog_groups[] = {
+ "gpio12"
+};
+
+static const char * const sdc2_groups[] = {
+ "gpio89", "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95",
+ "gpio96", "gpio97", "gpio98"
+};
+
+static const char * const sdc4_groups[] = {
+ "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const char * const sdc5_groups[] = {
+ "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82"
+};
+
+static const char * const slimbus1_groups[] = {
+ "gpio50", "gpio51", "gpio60", "gpio61"
+};
+
+static const char * const slimbus2_groups[] = {
+ "gpio42", "gpio43"
+};
+
+static const char * const spkr_i2s_groups[] = {
+ "gpio67", "gpio68", "gpio69", "gpio70"
+};
+
+static const char * const ssbi1_groups[] = {
+ "gpio141", "gpio143"
+};
+
+static const char * const ssbi2_groups[] = {
+ "gpio140", "gpio142"
+};
+
+static const char * const ssbi_ext_gps_groups[] = {
+ "gpio23"
+};
+
+static const char * const ssbi_pmic2_groups[] = {
+ "gpio149"
+};
+
+static const char * const ssbi_qpa1_groups[] = {
+ "gpio131"
+};
+
+static const char * const ssbi_ts_groups[] = {
+ "gpio10"
+};
+
+static const char * const tsif1_groups[] = {
+ "gpio75", "gpio76", "gpio77", "gpio82"
+};
+
+static const char * const tsif2_groups[] = {
+ "gpio78", "gpio79", "gpio80", "gpio81"
+};
+
+static const char * const ts_eoc_groups[] = {
+ "gpio11"
+};
+
+static const char * const usb_fs1_groups[] = {
+ "gpio32", "gpio33"
+};
+
+static const char * const usb_fs1_oe_groups[] = {
+ "gpio31"
+};
+
+static const char * const usb_fs1_oe_n_groups[] = {
+ "gpio31"
+};
+
+static const char * const usb_fs2_groups[] = {
+ "gpio34", "gpio35"
+};
+
+static const char * const usb_fs2_oe_groups[] = {
+ "gpio36"
+};
+
+static const char * const usb_fs2_oe_n_groups[] = {
+ "gpio36"
+};
+
+static const char * const vfe_camif_timer1_a_groups[] = {
+ "gpio2"
+};
+
+static const char * const vfe_camif_timer1_b_groups[] = {
+ "gpio38"
+};
+
+static const char * const vfe_camif_timer2_groups[] = {
+ "gpio3"
+};
+
+static const char * const vfe_camif_timer3_a_groups[] = {
+ "gpio4"
+};
+
+static const char * const vfe_camif_timer3_b_groups[] = {
+ "gpio151"
+};
+
+static const char * const vfe_camif_timer4_a_groups[] = {
+ "gpio65"
+};
+
+static const char * const vfe_camif_timer4_b_groups[] = {
+ "gpio150"
+};
+
+static const char * const vfe_camif_timer4_c_groups[] = {
+ "gpio10"
+};
+
+static const char * const vfe_camif_timer5_a_groups[] = {
+ "gpio66"
+};
+
+static const char * const vfe_camif_timer5_b_groups[] = {
+ "gpio39"
+};
+
+static const char * const vfe_camif_timer6_a_groups[] = {
+ "gpio71"
+};
+
+static const char * const vfe_camif_timer6_b_groups[] = {
+ "gpio0"
+};
+
+static const char * const vfe_camif_timer6_c_groups[] = {
+ "gpio18"
+};
+
+static const char * const vfe_camif_timer7_a_groups[] = {
+ "gpio67"
+};
+
+static const char * const vfe_camif_timer7_b_groups[] = {
+ "gpio1"
+};
+
+static const char * const vfe_camif_timer7_c_groups[] = {
+ "gpio19"
+};
+
+static const char * const wlan_groups[] = {
+ "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"
+};
+
+static const struct msm_function msm8960_functions[] = {
+ FUNCTION(audio_pcm),
+ FUNCTION(bt),
+ FUNCTION(cam_mclk0),
+ FUNCTION(cam_mclk1),
+ FUNCTION(cam_mclk2),
+ FUNCTION(codec_mic_i2s),
+ FUNCTION(codec_spkr_i2s),
+ FUNCTION(ext_gps),
+ FUNCTION(fm),
+ FUNCTION(gps_blanking),
+ FUNCTION(gps_pps_in),
+ FUNCTION(gps_pps_out),
+ FUNCTION(gp_clk_0a),
+ FUNCTION(gp_clk_0b),
+ FUNCTION(gp_clk_1a),
+ FUNCTION(gp_clk_1b),
+ FUNCTION(gp_clk_2a),
+ FUNCTION(gp_clk_2b),
+ FUNCTION(gp_mn),
+ FUNCTION(gp_pdm_0a),
+ FUNCTION(gp_pdm_0b),
+ FUNCTION(gp_pdm_1a),
+ FUNCTION(gp_pdm_1b),
+ FUNCTION(gp_pdm_2a),
+ FUNCTION(gp_pdm_2b),
+ FUNCTION(gpio),
+ FUNCTION(gsbi1),
+ FUNCTION(gsbi1_spi_cs1_n),
+ FUNCTION(gsbi1_spi_cs2a_n),
+ FUNCTION(gsbi1_spi_cs2b_n),
+ FUNCTION(gsbi1_spi_cs3_n),
+ FUNCTION(gsbi2),
+ FUNCTION(gsbi2_spi_cs1_n),
+ FUNCTION(gsbi2_spi_cs2_n),
+ FUNCTION(gsbi2_spi_cs3_n),
+ FUNCTION(gsbi3),
+ FUNCTION(gsbi4),
+ FUNCTION(gsbi4_3d_cam_i2c_l),
+ FUNCTION(gsbi4_3d_cam_i2c_r),
+ FUNCTION(gsbi5),
+ FUNCTION(gsbi5_3d_cam_i2c_l),
+ FUNCTION(gsbi5_3d_cam_i2c_r),
+ FUNCTION(gsbi6),
+ FUNCTION(gsbi7),
+ FUNCTION(gsbi8),
+ FUNCTION(gsbi9),
+ FUNCTION(gsbi10),
+ FUNCTION(gsbi11),
+ FUNCTION(gsbi11_spi_cs1a_n),
+ FUNCTION(gsbi11_spi_cs1b_n),
+ FUNCTION(gsbi11_spi_cs2a_n),
+ FUNCTION(gsbi11_spi_cs2b_n),
+ FUNCTION(gsbi11_spi_cs3_n),
+ FUNCTION(gsbi12),
+ FUNCTION(hdmi_cec),
+ FUNCTION(hdmi_ddc_clock),
+ FUNCTION(hdmi_ddc_data),
+ FUNCTION(hdmi_hot_plug_detect),
+ FUNCTION(hsic),
+ FUNCTION(mdp_vsync),
+ FUNCTION(mi2s),
+ FUNCTION(mic_i2s),
+ FUNCTION(pmb_clk),
+ FUNCTION(pmb_ext_ctrl),
+ FUNCTION(ps_hold),
+ FUNCTION(rpm_wdog),
+ FUNCTION(sdc2),
+ FUNCTION(sdc4),
+ FUNCTION(sdc5),
+ FUNCTION(slimbus1),
+ FUNCTION(slimbus2),
+ FUNCTION(spkr_i2s),
+ FUNCTION(ssbi1),
+ FUNCTION(ssbi2),
+ FUNCTION(ssbi_ext_gps),
+ FUNCTION(ssbi_pmic2),
+ FUNCTION(ssbi_qpa1),
+ FUNCTION(ssbi_ts),
+ FUNCTION(tsif1),
+ FUNCTION(tsif2),
+ FUNCTION(ts_eoc),
+ FUNCTION(usb_fs1),
+ FUNCTION(usb_fs1_oe),
+ FUNCTION(usb_fs1_oe_n),
+ FUNCTION(usb_fs2),
+ FUNCTION(usb_fs2_oe),
+ FUNCTION(usb_fs2_oe_n),
+ FUNCTION(vfe_camif_timer1_a),
+ FUNCTION(vfe_camif_timer1_b),
+ FUNCTION(vfe_camif_timer2),
+ FUNCTION(vfe_camif_timer3_a),
+ FUNCTION(vfe_camif_timer3_b),
+ FUNCTION(vfe_camif_timer4_a),
+ FUNCTION(vfe_camif_timer4_b),
+ FUNCTION(vfe_camif_timer4_c),
+ FUNCTION(vfe_camif_timer5_a),
+ FUNCTION(vfe_camif_timer5_b),
+ FUNCTION(vfe_camif_timer6_a),
+ FUNCTION(vfe_camif_timer6_b),
+ FUNCTION(vfe_camif_timer6_c),
+ FUNCTION(vfe_camif_timer7_a),
+ FUNCTION(vfe_camif_timer7_b),
+ FUNCTION(vfe_camif_timer7_c),
+ FUNCTION(wlan),
+};
+
+static const struct msm_pingroup msm8960_groups[] = {
+ PINGROUP(0, mdp_vsync, vfe_camif_timer6_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(1, mdp_vsync, vfe_camif_timer7_b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(2, vfe_camif_timer1_a, gp_mn, NA, cam_mclk2, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(3, vfe_camif_timer2, gp_clk_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(4, vfe_camif_timer3_a, cam_mclk1, gp_clk_1a, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(5, cam_mclk0, pmb_ext_ctrl, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(6, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(7, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(8, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(9, gsbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(10, gsbi2, ssbi_ts, NA, vfe_camif_timer4_c, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(11, gsbi2, ts_eoc, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(12, gsbi2, rpm_wdog, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(13, gsbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(14, gsbi3, gsbi1_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(15, gsbi3, gsbi1_spi_cs2a_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(16, gsbi3, gsbi1_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(17, gsbi3, gsbi1_spi_cs2b_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(18, gsbi4, gsbi11_spi_cs1b_n, NA, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer6_c, NA, NA, NA, NA, NA),
+ PINGROUP(19, gsbi4, gsbi11_spi_cs2b_n, NA, mdp_vsync, NA, gsbi4_3d_cam_i2c_l, vfe_camif_timer7_c, NA, NA, NA, NA),
+ PINGROUP(20, gsbi4, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(21, gsbi4, pmb_clk, gsbi4_3d_cam_i2c_r, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(22, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+ PINGROUP(23, gsbi5, ssbi_ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_l, NA),
+ PINGROUP(24, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+ PINGROUP(25, gsbi5, ext_gps, NA, NA, NA, NA, NA, NA, NA, gsbi5_3d_cam_i2c_r, NA),
+ PINGROUP(26, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(27, fm, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(28, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(29, bt, gsbi6, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(30, gsbi7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(31, gsbi7, usb_fs1_oe, usb_fs1_oe_n, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(32, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(33, gsbi7, usb_fs1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(34, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(35, gsbi8, usb_fs2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(36, gsbi8, usb_fs2_oe, usb_fs2_oe_n, gsbi11_spi_cs1a_n, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(37, gsbi8, gps_pps_out, gps_pps_in, gsbi11_spi_cs2a_n, gp_clk_2b, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer1_b, NA),
+ PINGROUP(39, gsbi11, gp_pdm_0b, NA, NA, NA, NA, NA, NA, NA, NA, vfe_camif_timer5_b),
+ PINGROUP(40, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(41, gsbi11, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(42, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(43, gsbi12, slimbus2, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(44, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(45, gsbi12, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(47, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(48, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(49, mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(51, mi2s, slimbus1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, mi2s, gp_clk_2a, gsbi2_spi_cs1_n, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, mi2s, gp_pdm_2b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, codec_mic_i2s, gp_clk_0b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, codec_mic_i2s, gsbi2_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, codec_mic_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, codec_mic_i2s, gp_pdm_0a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(61, slimbus1, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(62, codec_spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(63, audio_pcm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, audio_pcm, gp_pdm_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(65, audio_pcm, vfe_camif_timer4_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(66, audio_pcm, vfe_camif_timer5_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(67, spkr_i2s, vfe_camif_timer7_a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(68, spkr_i2s, gsbi2_spi_cs2_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(69, spkr_i2s, gp_pdm_2a, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(70, spkr_i2s, gp_clk_1b, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(71, mic_i2s, gsbi10, vfe_camif_timer6_a, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(72, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, mic_i2s, gsbi10, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(76, tsif1, gsbi11_spi_cs3_n, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, tsif2, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, tsif1, sdc5, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, bt, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(84, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(85, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, wlan, sdc4, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(88, wlan, sdc4, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(89, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(92, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(93, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, sdc2, gsbi9, gp_pdm_1a, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, sdc2, gsbi9, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, sdc2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(100, hdmi_ddc_clock, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(101, hdmi_ddc_data, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(102, hdmi_hot_plug_detect, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(108, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(110, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(112, NA, pmb_clk, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(113, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(115, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(117, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(118, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(119, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(120, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(121, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(122, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(123, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(126, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(127, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(128, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(129, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(130, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(131, NA, ssbi_qpa1, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(132, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(133, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(134, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(135, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(136, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(137, gps_blanking, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(138, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(139, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(140, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(141, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(142, ssbi2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(143, ssbi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(146, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(147, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(148, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(149, ssbi_pmic2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(150, hsic, NA, vfe_camif_timer4_b, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(151, hsic, NA, vfe_camif_timer3_b, NA, NA, NA, NA, NA, NA, NA, NA),
+
+ SDC_PINGROUP(sdc1_clk, 0x20a0, 13, 6),
+ SDC_PINGROUP(sdc1_cmd, 0x20a0, 11, 3),
+ SDC_PINGROUP(sdc1_data, 0x20a0, 9, 0),
+
+ SDC_PINGROUP(sdc3_clk, 0x20a4, 14, 6),
+ SDC_PINGROUP(sdc3_cmd, 0x20a4, 11, 3),
+ SDC_PINGROUP(sdc3_data, 0x20a4, 9, 0),
+};
+
+#define NUM_GPIO_PINGROUPS 152
+
+static const struct msm_pinctrl_soc_data msm8960_pinctrl = {
+ .pins = msm8960_pins,
+ .npins = ARRAY_SIZE(msm8960_pins),
+ .functions = msm8960_functions,
+ .nfunctions = ARRAY_SIZE(msm8960_functions),
+ .groups = msm8960_groups,
+ .ngroups = ARRAY_SIZE(msm8960_groups),
+ .ngpios = NUM_GPIO_PINGROUPS,
+};
+
+static int msm8960_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &msm8960_pinctrl);
+}
+
+static const struct of_device_id msm8960_pinctrl_of_match[] = {
+ { .compatible = "qcom,msm8960-pinctrl", },
+ { },
+};
+
+static struct platform_driver msm8960_pinctrl_driver = {
+ .driver = {
+ .name = "msm8960-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = msm8960_pinctrl_of_match,
+ },
+ .probe = msm8960_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8960_pinctrl_init(void)
+{
+ return platform_driver_register(&msm8960_pinctrl_driver);
+}
+arch_initcall(msm8960_pinctrl_init);
+
+static void __exit msm8960_pinctrl_exit(void)
+{
+ platform_driver_unregister(&msm8960_pinctrl_driver);
+}
+module_exit(msm8960_pinctrl_exit);
+
+MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
+MODULE_DESCRIPTION("Qualcomm MSM8960 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8960_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c
index 418306911a6f..8c9720154d1e 100644
--- a/drivers/pinctrl/pinctrl-msm8x74.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c
@@ -342,7 +342,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
.pins = gpio##id##_pins, \
.npins = ARRAY_SIZE(gpio##id##_pins), \
.funcs = (int[]){ \
- MSM_MUX_NA, /* gpio mode */ \
+ MSM_MUX_gpio, \
MSM_MUX_##f1, \
MSM_MUX_##f2, \
MSM_MUX_##f3, \
@@ -402,6 +402,7 @@ static const unsigned int sdc2_data_pins[] = { 151 };
* the pingroup table below.
*/
enum msm8x74_functions {
+ MSM_MUX_gpio,
MSM_MUX_cci_i2c0,
MSM_MUX_cci_i2c1,
MSM_MUX_blsp_i2c1,
@@ -509,6 +510,31 @@ enum msm8x74_functions {
MSM_MUX_NA,
};
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141", "gpio142", "gpio143", "gpio144", "gpio145"
+};
+
static const char * const blsp_uart1_groups[] = {
"gpio0", "gpio1", "gpio2", "gpio3"
};
@@ -728,6 +754,7 @@ static const char * const wlan_groups[] = {
static const char * const slimbus_groups[] = { "gpio70", "gpio71" };
static const struct msm_function msm8x74_functions[] = {
+ FUNCTION(gpio),
FUNCTION(cci_i2c0),
FUNCTION(cci_i2c1),
FUNCTION(uim1),
diff --git a/drivers/pinctrl/samsung/Kconfig b/drivers/pinctrl/samsung/Kconfig
new file mode 100644
index 000000000000..d0461cd5d707
--- /dev/null
+++ b/drivers/pinctrl/samsung/Kconfig
@@ -0,0 +1,28 @@
+#
+# Samsung Pin control drivers
+#
+config PINCTRL_SAMSUNG
+ bool
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_EXYNOS
+ bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
+ depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
+ select PINCTRL_SAMSUNG
+
+config PINCTRL_EXYNOS5440
+ bool "Samsung EXYNOS5440 SoC pinctrl driver"
+ depends on SOC_EXYNOS5440
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_S3C24XX
+ bool "Samsung S3C24XX SoC pinctrl driver"
+ depends on ARCH_S3C24XX
+ select PINCTRL_SAMSUNG
+
+config PINCTRL_S3C64XX
+ bool "Samsung S3C64XX SoC pinctrl driver"
+ depends on ARCH_S3C64XX
+ select PINCTRL_SAMSUNG
diff --git a/drivers/pinctrl/samsung/Makefile b/drivers/pinctrl/samsung/Makefile
new file mode 100644
index 000000000000..70160c059edd
--- /dev/null
+++ b/drivers/pinctrl/samsung/Makefile
@@ -0,0 +1,7 @@
+# Samsung pin control drivers
+
+obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
+obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
+obj-$(CONFIG_PINCTRL_S3C24XX) += pinctrl-s3c24xx.o
+obj-$(CONFIG_PINCTRL_S3C64XX) += pinctrl-s3c64xx.o
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 9609c23834ce..003bfd874a61 100644
--- a/drivers/pinctrl/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -33,6 +33,18 @@
#include "pinctrl-samsung.h"
#include "pinctrl-exynos.h"
+struct exynos_irq_chip {
+ struct irq_chip chip;
+
+ u32 eint_con;
+ u32 eint_mask;
+ u32 eint_pend;
+};
+
+static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
+{
+ return container_of(chip, struct exynos_irq_chip, chip);
+}
static struct samsung_pin_bank_type bank_type_off = {
.fld_width = { 4, 1, 2, 2, 2, 2, },
@@ -50,11 +62,13 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
{ }
};
-static void exynos_gpio_irq_mask(struct irq_data *irqd)
+static void exynos_irq_mask(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+ unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
@@ -67,20 +81,24 @@ static void exynos_gpio_irq_mask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags);
}
-static void exynos_gpio_irq_ack(struct irq_data *irqd)
+static void exynos_irq_ack(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
+ unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
writel(1 << irqd->hwirq, d->virt_base + reg_pend);
}
-static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+static void exynos_irq_unmask(struct irq_data *irqd)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+ unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
unsigned long mask;
unsigned long flags;
@@ -93,7 +111,7 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
* masked.
*/
if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
- exynos_gpio_irq_ack(irqd);
+ exynos_irq_ack(irqd);
spin_lock_irqsave(&bank->slock, flags);
@@ -104,16 +122,17 @@ static void exynos_gpio_irq_unmask(struct irq_data *irqd)
spin_unlock_irqrestore(&bank->slock, flags);
}
-static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
+static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
{
+ struct irq_chip *chip = irq_data_get_irq_chip(irqd);
+ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
struct samsung_pin_bank_type *bank_type = bank->type;
struct samsung_pinctrl_drv_data *d = bank->drvdata;
- struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned int pin = irqd->hwirq;
unsigned int shift = EXYNOS_EINT_CON_LEN * pin;
unsigned int con, trig_type;
- unsigned long reg_con = ctrl->geint_con + bank->eint_offset;
+ unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
unsigned long flags;
unsigned int mask;
@@ -167,12 +186,17 @@ static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
/*
* irq_chip for gpio interrupts.
*/
-static struct irq_chip exynos_gpio_irq_chip = {
- .name = "exynos_gpio_irq_chip",
- .irq_unmask = exynos_gpio_irq_unmask,
- .irq_mask = exynos_gpio_irq_mask,
- .irq_ack = exynos_gpio_irq_ack,
- .irq_set_type = exynos_gpio_irq_set_type,
+static struct exynos_irq_chip exynos_gpio_irq_chip = {
+ .chip = {
+ .name = "exynos_gpio_irq_chip",
+ .irq_unmask = exynos_irq_unmask,
+ .irq_mask = exynos_irq_mask,
+ .irq_ack = exynos_irq_ack,
+ .irq_set_type = exynos_irq_set_type,
+ },
+ .eint_con = EXYNOS_GPIO_ECON_OFFSET,
+ .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
+ .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
};
static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
@@ -181,7 +205,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
struct samsung_pin_bank *b = h->host_data;
irq_set_chip_data(virq, b);
- irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
+ irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
handle_level_irq);
set_irq_flags(virq, IRQF_VALID);
return 0;
@@ -202,7 +226,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
struct samsung_pin_bank *bank = ctrl->pin_banks;
unsigned int svc, group, pin, virq;
- svc = readl(d->virt_base + ctrl->svc);
+ svc = readl(d->virt_base + EXYNOS_SVC_OFFSET);
group = EXYNOS_SVC_GROUP(svc);
pin = svc & EXYNOS_SVC_NUM_MASK;
@@ -279,119 +303,6 @@ err_domains:
return ret;
}
-static void exynos_wkup_irq_mask(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
- unsigned long mask;
- unsigned long flags;
-
- spin_lock_irqsave(&b->slock, flags);
-
- mask = readl(d->virt_base + reg_mask);
- mask |= 1 << irqd->hwirq;
- writel(mask, d->virt_base + reg_mask);
-
- spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static void exynos_wkup_irq_ack(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
-
- writel(1 << irqd->hwirq, d->virt_base + pend);
-}
-
-static void exynos_wkup_irq_unmask(struct irq_data *irqd)
-{
- struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
- struct samsung_pinctrl_drv_data *d = b->drvdata;
- unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
- unsigned long mask;
- unsigned long flags;
-
- /*
- * Ack level interrupts right before unmask
- *
- * If we don't do this we'll get a double-interrupt. Level triggered
- * interrupts must not fire an interrupt if the level is not
- * _currently_ active, even if it was active while the interrupt was
- * masked.
- */
- if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
- exynos_wkup_irq_ack(irqd);
-
- spin_lock_irqsave(&b->slock, flags);
-
- mask = readl(d->virt_base + reg_mask);
- mask &= ~(1 << irqd->hwirq);
- writel(mask, d->virt_base + reg_mask);
-
- spin_unlock_irqrestore(&b->slock, flags);
-}
-
-static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
-{
- struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
- struct samsung_pin_bank_type *bank_type = bank->type;
- struct samsung_pinctrl_drv_data *d = bank->drvdata;
- unsigned int pin = irqd->hwirq;
- unsigned long reg_con = d->ctrl->weint_con + bank->eint_offset;
- unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
- unsigned long con, trig_type;
- unsigned long flags;
- unsigned int mask;
-
- switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- trig_type = EXYNOS_EINT_EDGE_RISING;
- break;
- case IRQ_TYPE_EDGE_FALLING:
- trig_type = EXYNOS_EINT_EDGE_FALLING;
- break;
- case IRQ_TYPE_EDGE_BOTH:
- trig_type = EXYNOS_EINT_EDGE_BOTH;
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- trig_type = EXYNOS_EINT_LEVEL_HIGH;
- break;
- case IRQ_TYPE_LEVEL_LOW:
- trig_type = EXYNOS_EINT_LEVEL_LOW;
- break;
- default:
- pr_err("unsupported external interrupt type\n");
- return -EINVAL;
- }
-
- if (type & IRQ_TYPE_EDGE_BOTH)
- __irq_set_handler_locked(irqd->irq, handle_edge_irq);
- else
- __irq_set_handler_locked(irqd->irq, handle_level_irq);
-
- con = readl(d->virt_base + reg_con);
- con &= ~(EXYNOS_EINT_CON_MASK << shift);
- con |= trig_type << shift;
- writel(con, d->virt_base + reg_con);
-
- reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
- shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
- mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
-
- spin_lock_irqsave(&bank->slock, flags);
-
- con = readl(d->virt_base + reg_con);
- con &= ~(mask << shift);
- con |= EXYNOS_EINT_FUNC << shift;
- writel(con, d->virt_base + reg_con);
-
- spin_unlock_irqrestore(&bank->slock, flags);
-
- return 0;
-}
-
static u32 exynos_eint_wake_mask = 0xffffffff;
u32 exynos_get_eint_wake_mask(void)
@@ -417,13 +328,18 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
/*
* irq_chip for wakeup interrupts
*/
-static struct irq_chip exynos_wkup_irq_chip = {
- .name = "exynos_wkup_irq_chip",
- .irq_unmask = exynos_wkup_irq_unmask,
- .irq_mask = exynos_wkup_irq_mask,
- .irq_ack = exynos_wkup_irq_ack,
- .irq_set_type = exynos_wkup_irq_set_type,
- .irq_set_wake = exynos_wkup_irq_set_wake,
+static struct exynos_irq_chip exynos_wkup_irq_chip = {
+ .chip = {
+ .name = "exynos_wkup_irq_chip",
+ .irq_unmask = exynos_irq_unmask,
+ .irq_mask = exynos_irq_mask,
+ .irq_ack = exynos_irq_ack,
+ .irq_set_type = exynos_irq_set_type,
+ .irq_set_wake = exynos_wkup_irq_set_wake,
+ },
+ .eint_con = EXYNOS_WKUP_ECON_OFFSET,
+ .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
+ .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
};
/* interrupt handler for wakeup interrupts 0..15 */
@@ -464,7 +380,6 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
struct irq_chip *chip = irq_get_chip(irq);
struct exynos_muxed_weint_data *eintd = irq_get_handler_data(irq);
struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata;
- struct samsung_pin_ctrl *ctrl = d->ctrl;
unsigned long pend;
unsigned long mask;
int i;
@@ -473,8 +388,10 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
- pend = readl(d->virt_base + ctrl->weint_pend + b->eint_offset);
- mask = readl(d->virt_base + ctrl->weint_mask + b->eint_offset);
+ pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
+ + b->eint_offset);
+ mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
+ + b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
@@ -484,7 +401,8 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
- irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
+ handle_level_irq);
irq_set_chip_data(virq, h->host_data);
set_irq_flags(virq, IRQF_VALID);
return 0;
@@ -703,13 +621,6 @@ struct samsung_pin_ctrl s5pv210_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = s5pv210_pin_bank,
.nr_banks = ARRAY_SIZE(s5pv210_pin_bank),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -758,10 +669,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos3250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -770,13 +677,6 @@ struct samsung_pin_ctrl exynos3250_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos3250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos3250_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -843,10 +743,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos4210_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -855,13 +751,6 @@ struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos4210_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -942,10 +831,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos4x12_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -954,13 +839,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos4x12_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -970,10 +848,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 2 data */
.pin_banks = exynos4x12_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -982,10 +856,6 @@ struct samsung_pin_ctrl exynos4x12_pin_ctrl[] = {
/* pin-controller instance 3 data */
.pin_banks = exynos4x12_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos4x12_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1058,13 +928,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5250_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.suspend = exynos_pinctrl_suspend,
@@ -1074,10 +937,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5250_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1086,10 +945,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 2 data */
.pin_banks = exynos5250_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1098,10 +953,6 @@ struct samsung_pin_ctrl exynos5250_pin_ctrl[] = {
/* pin-controller instance 3 data */
.pin_banks = exynos5250_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5250_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.suspend = exynos_pinctrl_suspend,
.resume = exynos_pinctrl_resume,
@@ -1158,13 +1009,6 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5260_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5260-gpio-ctrl0",
@@ -1172,20 +1016,12 @@ struct samsung_pin_ctrl exynos5260_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5260_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5260_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5260_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5260-gpio-ctrl2",
},
@@ -1256,13 +1092,6 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 0 data */
.pin_banks = exynos5420_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks0),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .weint_con = EXYNOS_WKUP_ECON_OFFSET,
- .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
- .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.eint_wkup_init = exynos_eint_wkup_init,
.label = "exynos5420-gpio-ctrl0",
@@ -1270,40 +1099,24 @@ struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
/* pin-controller instance 1 data */
.pin_banks = exynos5420_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks1),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl1",
}, {
/* pin-controller instance 2 data */
.pin_banks = exynos5420_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks2),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl2",
}, {
/* pin-controller instance 3 data */
.pin_banks = exynos5420_pin_banks3,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks3),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl3",
}, {
/* pin-controller instance 4 data */
.pin_banks = exynos5420_pin_banks4,
.nr_banks = ARRAY_SIZE(exynos5420_pin_banks4),
- .geint_con = EXYNOS_GPIO_ECON_OFFSET,
- .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
- .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
- .svc = EXYNOS_SVC_OFFSET,
.eint_gpio_init = exynos_eint_gpio_init,
.label = "exynos5420-gpio-ctrl4",
},
diff --git a/drivers/pinctrl/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index 3c91c357792f..3c91c357792f 100644
--- a/drivers/pinctrl/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
index 8fe2ab0a7698..603da2f9dd95 100644
--- a/drivers/pinctrl/pinctrl-exynos5440.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
@@ -23,7 +23,7 @@
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/of_irq.h>
-#include "core.h"
+#include "../core.h"
/* EXYNOS5440 GPIO and Pinctrl register offsets */
#define GPIO_MUX 0x00
@@ -371,13 +371,6 @@ static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned select
return 0;
}
-/* disable a specified pinmux by writing to registers */
-static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- exynos5440_pinmux_setup(pctldev, selector, group, false);
-}
-
/*
* The calls to gpio_direction_output() and gpio_direction_input()
* leads to this function call (via the pinctrl_gpio_direction_{input|output}()
@@ -395,7 +388,6 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
.get_function_name = exynos5440_pinmux_get_fname,
.get_function_groups = exynos5440_pinmux_get_groups,
.enable = exynos5440_pinmux_enable,
- .disable = exynos5440_pinmux_disable,
.gpio_set_direction = exynos5440_pinmux_gpio_set_direction,
};
diff --git a/drivers/pinctrl/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index ad3eaad17001..ad3eaad17001 100644
--- a/drivers/pinctrl/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
diff --git a/drivers/pinctrl/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 89143c903000..89143c903000 100644
--- a/drivers/pinctrl/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 3e61d0f8f146..b07406da333c 100644
--- a/drivers/pinctrl/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -30,7 +30,7 @@
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
-#include "core.h"
+#include "../core.h"
#include "pinctrl-samsung.h"
#define GROUP_SUFFIX "-grp"
@@ -40,13 +40,14 @@
/* list of all possible config options supported */
static struct pin_config {
- char *prop_cfg;
- unsigned int cfg_type;
-} pcfgs[] = {
+ const char *property;
+ enum pincfg_type param;
+} cfg_params[] = {
{ "samsung,pin-pud", PINCFG_TYPE_PUD },
{ "samsung,pin-drv", PINCFG_TYPE_DRV },
{ "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
{ "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
+ { "samsung,pin-val", PINCFG_TYPE_DAT },
};
/* Global list of devices (struct samsung_pinctrl_drv_data) */
@@ -59,163 +60,242 @@ static inline struct samsung_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
return container_of(gc, struct samsung_pin_bank, gpio_chip);
}
-/* check if the selector is a valid pin group selector */
static int samsung_get_group_count(struct pinctrl_dev *pctldev)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- return drvdata->nr_groups;
+ return pmx->nr_groups;
}
-/* return the name of the group selected by the group selector */
static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
- unsigned selector)
+ unsigned group)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- return drvdata->pin_groups[selector].name;
+ return pmx->pin_groups[group].name;
}
-/* return the pin numbers associated with the specified group */
static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned selector, const unsigned **pins, unsigned *num_pins)
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
{
- struct samsung_pinctrl_drv_data *drvdata;
+ struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = pmx->pin_groups[group].pins;
+ *num_pins = pmx->pin_groups[group].num_pins;
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- *pins = drvdata->pin_groups[selector].pins;
- *num_pins = drvdata->pin_groups[selector].num_pins;
return 0;
}
-/* create pinctrl_map entries by parsing device tree nodes */
-static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np, struct pinctrl_map **maps,
- unsigned *nmaps)
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ unsigned reserve)
{
- struct device *dev = pctldev->dev;
- struct pinctrl_map *map;
- unsigned long *cfg = NULL;
- char *gname, *fname;
- int cfg_cnt = 0, map_cnt = 0, idx = 0;
-
- /* count the number of config options specfied in the node */
- for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
- if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
- cfg_cnt++;
- }
+ unsigned old_num = *reserved_maps;
+ unsigned new_num = *num_maps + reserve;
+ struct pinctrl_map *new_map;
- /*
- * Find out the number of map entries to create. All the config options
- * can be accomadated into a single config map entry.
- */
- if (cfg_cnt)
- map_cnt = 1;
- if (of_find_property(np, "samsung,pin-function", NULL))
- map_cnt++;
- if (!map_cnt) {
- dev_err(dev, "node %s does not have either config or function "
- "configurations\n", np->name);
- return -EINVAL;
- }
+ if (old_num >= new_num)
+ return 0;
- /* Allocate memory for pin-map entries */
- map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
- if (!map) {
- dev_err(dev, "could not alloc memory for pin-maps\n");
+ new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+ if (!new_map) {
+ dev_err(dev, "krealloc(map) failed\n");
return -ENOMEM;
}
- *nmaps = 0;
- /*
- * Allocate memory for pin group name. The pin group name is derived
- * from the node name from which these map entries are be created.
- */
- gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
- if (!gname) {
- dev_err(dev, "failed to alloc memory for group name\n");
- goto free_map;
+ memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+ *map = new_map;
+ *reserved_maps = new_num;
+
+ return 0;
+}
+
+static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
+ unsigned *num_maps, const char *group,
+ const char *function)
+{
+ if (WARN_ON(*num_maps == *reserved_maps))
+ return -ENOSPC;
+
+ (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+ (*map)[*num_maps].data.mux.group = group;
+ (*map)[*num_maps].data.mux.function = function;
+ (*num_maps)++;
+
+ return 0;
+}
+
+static int add_map_configs(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ const char *group, unsigned long *configs,
+ unsigned num_configs)
+{
+ unsigned long *dup_configs;
+
+ if (WARN_ON(*num_maps == *reserved_maps))
+ return -ENOSPC;
+
+ dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+ GFP_KERNEL);
+ if (!dup_configs) {
+ dev_err(dev, "kmemdup(configs) failed\n");
+ return -ENOMEM;
}
- sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
- /*
- * don't have config options? then skip over to creating function
- * map entries.
- */
- if (!cfg_cnt)
- goto skip_cfgs;
-
- /* Allocate memory for config entries */
- cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
- if (!cfg) {
- dev_err(dev, "failed to alloc memory for configs\n");
- goto free_gname;
+ (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+ (*map)[*num_maps].data.configs.group_or_pin = group;
+ (*map)[*num_maps].data.configs.configs = dup_configs;
+ (*map)[*num_maps].data.configs.num_configs = num_configs;
+ (*num_maps)++;
+
+ return 0;
+}
+
+static int add_config(struct device *dev, unsigned long **configs,
+ unsigned *num_configs, unsigned long config)
+{
+ unsigned old_num = *num_configs;
+ unsigned new_num = old_num + 1;
+ unsigned long *new_configs;
+
+ new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
+ GFP_KERNEL);
+ if (!new_configs) {
+ dev_err(dev, "krealloc(configs) failed\n");
+ return -ENOMEM;
}
- /* Prepare a list of config settings */
- for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
- u32 value;
- if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
- cfg[cfg_cnt++] =
- PINCFG_PACK(pcfgs[idx].cfg_type, value);
+ new_configs[old_num] = config;
+
+ *configs = new_configs;
+ *num_configs = new_num;
+
+ return 0;
+}
+
+static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map,
+ unsigned num_maps)
+{
+ int i;
+
+ for (i = 0; i < num_maps; i++)
+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
+ kfree(map[i].data.configs.configs);
+
+ kfree(map);
+}
+
+static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,
+ struct device *dev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned *reserved_maps,
+ unsigned *num_maps)
+{
+ int ret, i;
+ u32 val;
+ unsigned long config;
+ unsigned long *configs = NULL;
+ unsigned num_configs = 0;
+ unsigned reserve;
+ struct property *prop;
+ const char *group;
+ bool has_func = false;
+
+ ret = of_property_read_u32(np, "samsung,pin-function", &val);
+ if (!ret)
+ has_func = true;
+
+ for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
+ ret = of_property_read_u32(np, cfg_params[i].property, &val);
+ if (!ret) {
+ config = PINCFG_PACK(cfg_params[i].param, val);
+ ret = add_config(dev, &configs, &num_configs, config);
+ if (ret < 0)
+ goto exit;
+ /* EINVAL=missing, which is fine since it's optional */
+ } else if (ret != -EINVAL) {
+ dev_err(dev, "could not parse property %s\n",
+ cfg_params[i].property);
+ }
}
- /* create the config map entry */
- map[*nmaps].data.configs.group_or_pin = gname;
- map[*nmaps].data.configs.configs = cfg;
- map[*nmaps].data.configs.num_configs = cfg_cnt;
- map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
- *nmaps += 1;
-
-skip_cfgs:
- /* create the function map entry */
- if (of_find_property(np, "samsung,pin-function", NULL)) {
- fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
- if (!fname) {
- dev_err(dev, "failed to alloc memory for func name\n");
- goto free_cfg;
+ reserve = 0;
+ if (has_func)
+ reserve++;
+ if (num_configs)
+ reserve++;
+ ret = of_property_count_strings(np, "samsung,pins");
+ if (ret < 0) {
+ dev_err(dev, "could not parse property samsung,pins\n");
+ goto exit;
+ }
+ reserve *= ret;
+
+ ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
+ if (ret < 0)
+ goto exit;
+
+ of_property_for_each_string(np, "samsung,pins", prop, group) {
+ if (has_func) {
+ ret = add_map_mux(map, reserved_maps,
+ num_maps, group, np->full_name);
+ if (ret < 0)
+ goto exit;
}
- sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
- map[*nmaps].data.mux.group = gname;
- map[*nmaps].data.mux.function = fname;
- map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
- *nmaps += 1;
+ if (num_configs) {
+ ret = add_map_configs(dev, map, reserved_maps,
+ num_maps, group, configs,
+ num_configs);
+ if (ret < 0)
+ goto exit;
+ }
}
- *maps = map;
- return 0;
+ ret = 0;
-free_cfg:
- kfree(cfg);
-free_gname:
- kfree(gname);
-free_map:
- kfree(map);
- return -ENOMEM;
+exit:
+ kfree(configs);
+ return ret;
}
-/* free the memory allocated to hold the pin-map table */
-static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
+static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
{
- int idx;
-
- for (idx = 0; idx < num_maps; idx++) {
- if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
- kfree(map[idx].data.mux.function);
- if (!idx)
- kfree(map[idx].data.mux.group);
- } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
- kfree(map[idx].data.configs.configs);
- if (!idx)
- kfree(map[idx].data.configs.group_or_pin);
+ struct samsung_pinctrl_drv_data *drvdata;
+ unsigned reserved_maps;
+ struct device_node *np;
+ int ret;
+
+ drvdata = pinctrl_dev_get_drvdata(pctldev);
+
+ reserved_maps = 0;
+ *map = NULL;
+ *num_maps = 0;
+
+ if (!of_get_child_count(np_config))
+ return samsung_dt_subnode_to_map(drvdata, pctldev->dev,
+ np_config, map,
+ &reserved_maps,
+ num_maps);
+
+ for_each_child_of_node(np_config, np) {
+ ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map,
+ &reserved_maps, num_maps);
+ if (ret < 0) {
+ samsung_dt_free_map(pctldev, *map, *num_maps);
+ return ret;
}
- };
+ }
- kfree(map);
+ return 0;
}
/* list of pinctrl callbacks for the pinctrl core */
@@ -286,83 +366,21 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group, bool enable)
{
struct samsung_pinctrl_drv_data *drvdata;
- const unsigned int *pins;
- struct samsung_pin_bank *bank;
- void __iomem *reg;
- u32 mask, shift, data, pin_offset, cnt;
- unsigned long flags;
-
- drvdata = pinctrl_dev_get_drvdata(pctldev);
- pins = drvdata->pin_groups[group].pins;
-
- /*
- * for each pin in the pin group selected, program the correspoding pin
- * pin function number in the config register.
- */
- for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
- struct samsung_pin_bank_type *type;
-
- pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base,
- &reg, &pin_offset, &bank);
- type = bank->type;
- mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
- shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
- if (shift >= 32) {
- /* Some banks have two config registers */
- shift -= 32;
- reg += 4;
- }
-
- spin_lock_irqsave(&bank->slock, flags);
-
- data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
- data &= ~(mask << shift);
- if (enable)
- data |= drvdata->pin_groups[group].func << shift;
- writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
-
- spin_unlock_irqrestore(&bank->slock, flags);
- }
-}
-
-/* enable a specified pinmux by writing to registers */
-static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- samsung_pinmux_setup(pctldev, selector, group, true);
- return 0;
-}
-
-/* disable a specified pinmux by writing to registers */
-static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
- unsigned selector, unsigned group)
-{
- samsung_pinmux_setup(pctldev, selector, group, false);
-}
-
-/*
- * The calls to gpio_direction_output() and gpio_direction_input()
- * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
- * function called from the gpiolib interface).
- */
-static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range, unsigned offset, bool input)
-{
struct samsung_pin_bank_type *type;
struct samsung_pin_bank *bank;
- struct samsung_pinctrl_drv_data *drvdata;
void __iomem *reg;
- u32 data, pin_offset, mask, shift;
+ u32 mask, shift, data, pin_offset;
unsigned long flags;
+ const struct samsung_pmx_func *func;
+ const struct samsung_pin_group *grp;
- bank = gc_to_pin_bank(range->gc);
- type = bank->type;
drvdata = pinctrl_dev_get_drvdata(pctldev);
+ func = &drvdata->pmx_functions[selector];
+ grp = &drvdata->pin_groups[group];
- pin_offset = offset - bank->pin_base;
- reg = drvdata->virt_base + bank->pctl_offset +
- type->reg_offset[PINCFG_TYPE_FUNC];
-
+ pin_to_reg_bank(drvdata, grp->pins[0] - drvdata->ctrl->base,
+ &reg, &pin_offset, &bank);
+ type = bank->type;
mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];
if (shift >= 32) {
@@ -373,14 +391,20 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
spin_lock_irqsave(&bank->slock, flags);
- data = readl(reg);
+ data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);
data &= ~(mask << shift);
- if (!input)
- data |= FUNC_OUTPUT << shift;
- writel(data, reg);
+ if (enable)
+ data |= func->val << shift;
+ writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);
spin_unlock_irqrestore(&bank->slock, flags);
+}
+/* enable a specified pinmux by writing to registers */
+static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
+ unsigned group)
+{
+ samsung_pinmux_setup(pctldev, selector, group, true);
return 0;
}
@@ -390,8 +414,6 @@ static const struct pinmux_ops samsung_pinmux_ops = {
.get_function_name = samsung_pinmux_get_fname,
.get_function_groups = samsung_pinmux_get_groups,
.enable = samsung_pinmux_enable,
- .disable = samsung_pinmux_disable,
- .gpio_set_direction = samsung_pinmux_gpio_set_direction,
};
/* set or get the pin config settings for a specified pin */
@@ -540,25 +562,59 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
}
/*
- * gpiolib gpio_direction_input callback function. The setting of the pin
- * mux function as 'gpio input' will be handled by the pinctrl susbsystem
- * interface.
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call.
*/
+static int samsung_gpio_set_direction(struct gpio_chip *gc,
+ unsigned offset, bool input)
+{
+ struct samsung_pin_bank_type *type;
+ struct samsung_pin_bank *bank;
+ struct samsung_pinctrl_drv_data *drvdata;
+ void __iomem *reg;
+ u32 data, mask, shift;
+ unsigned long flags;
+
+ bank = gc_to_pin_bank(gc);
+ type = bank->type;
+ drvdata = bank->drvdata;
+
+ reg = drvdata->virt_base + bank->pctl_offset +
+ type->reg_offset[PINCFG_TYPE_FUNC];
+
+ mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+ shift = offset * type->fld_width[PINCFG_TYPE_FUNC];
+ if (shift >= 32) {
+ /* Some banks have two config registers */
+ shift -= 32;
+ reg += 4;
+ }
+
+ spin_lock_irqsave(&bank->slock, flags);
+
+ data = readl(reg);
+ data &= ~(mask << shift);
+ if (!input)
+ data |= FUNC_OUTPUT << shift;
+ writel(data, reg);
+
+ spin_unlock_irqrestore(&bank->slock, flags);
+
+ return 0;
+}
+
+/* gpiolib gpio_direction_input callback function. */
static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
{
- return pinctrl_gpio_direction_input(gc->base + offset);
+ return samsung_gpio_set_direction(gc, offset, true);
}
-/*
- * gpiolib gpio_direction_output callback function. The setting of the pin
- * mux function as 'gpio output' will be handled by the pinctrl susbsystem
- * interface.
- */
+/* gpiolib gpio_direction_output callback function. */
static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
int value)
{
samsung_gpio_set(gc, offset, value);
- return pinctrl_gpio_direction_output(gc->base + offset);
+ return samsung_gpio_set_direction(gc, offset, false);
}
/*
@@ -578,87 +634,115 @@ static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
return (virq) ? : -ENXIO;
}
-/*
- * Parse the pin names listed in the 'samsung,pins' property and convert it
- * into a list of gpio numbers are create a pin group from it.
- */
-static int samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
- struct device_node *cfg_np,
- struct pinctrl_desc *pctl,
- unsigned int **pin_list,
- unsigned int *npins)
+static struct samsung_pin_group *samsung_pinctrl_create_groups(
+ struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ unsigned int *cnt)
{
- struct device *dev = &pdev->dev;
- struct property *prop;
- struct pinctrl_pin_desc const *pdesc = pctl->pins;
- unsigned int idx = 0, cnt;
- const char *pin_name;
+ struct pinctrl_desc *ctrldesc = &drvdata->pctl;
+ struct samsung_pin_group *groups, *grp;
+ const struct pinctrl_pin_desc *pdesc;
+ int i;
- *npins = of_property_count_strings(cfg_np, "samsung,pins");
- if (IS_ERR_VALUE(*npins)) {
- dev_err(dev, "invalid pin list in %s node", cfg_np->name);
+ groups = devm_kzalloc(dev, ctrldesc->npins * sizeof(*groups),
+ GFP_KERNEL);
+ if (!groups)
+ return ERR_PTR(-EINVAL);
+ grp = groups;
+
+ pdesc = ctrldesc->pins;
+ for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) {
+ grp->name = pdesc->name;
+ grp->pins = &pdesc->number;
+ grp->num_pins = 1;
+ }
+
+ *cnt = ctrldesc->npins;
+ return groups;
+}
+
+static int samsung_pinctrl_create_function(struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ struct device_node *func_np,
+ struct samsung_pmx_func *func)
+{
+ int npins;
+ int ret;
+ int i;
+
+ if (of_property_read_u32(func_np, "samsung,pin-function", &func->val))
+ return 0;
+
+ npins = of_property_count_strings(func_np, "samsung,pins");
+ if (npins < 1) {
+ dev_err(dev, "invalid pin list in %s node", func_np->name);
return -EINVAL;
}
- *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
- if (!*pin_list) {
- dev_err(dev, "failed to allocate memory for pin list\n");
+ func->name = func_np->full_name;
+
+ func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
+ if (!func->groups)
return -ENOMEM;
- }
- of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
- for (cnt = 0; cnt < pctl->npins; cnt++) {
- if (pdesc[cnt].name) {
- if (!strcmp(pin_name, pdesc[cnt].name)) {
- (*pin_list)[idx++] = pdesc[cnt].number;
- break;
- }
- }
- }
- if (cnt == pctl->npins) {
- dev_err(dev, "pin %s not valid in %s node\n",
- pin_name, cfg_np->name);
- devm_kfree(dev, *pin_list);
- return -EINVAL;
+ for (i = 0; i < npins; ++i) {
+ const char *gname;
+
+ ret = of_property_read_string_index(func_np, "samsung,pins",
+ i, &gname);
+ if (ret) {
+ dev_err(dev,
+ "failed to read pin name %d from %s node\n",
+ i, func_np->name);
+ return ret;
}
+
+ func->groups[i] = gname;
}
- return 0;
+ func->num_groups = npins;
+ return 1;
}
-/*
- * Parse the information about all the available pin groups and pin functions
- * from device node of the pin-controller. A pin group is formed with all
- * the pins listed in the "samsung,pins" property.
- */
-static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
- struct samsung_pinctrl_drv_data *drvdata)
+static struct samsung_pmx_func *samsung_pinctrl_create_functions(
+ struct device *dev,
+ struct samsung_pinctrl_drv_data *drvdata,
+ unsigned int *cnt)
{
- struct device *dev = &pdev->dev;
+ struct samsung_pmx_func *functions, *func;
struct device_node *dev_np = dev->of_node;
struct device_node *cfg_np;
- struct samsung_pin_group *groups, *grp;
- struct samsung_pmx_func *functions, *func;
- unsigned *pin_list;
- unsigned int npins, grp_cnt, func_idx = 0;
- char *gname, *fname;
+ unsigned int func_cnt = 0;
int ret;
- grp_cnt = of_get_child_count(dev_np);
- if (!grp_cnt)
- return -EINVAL;
+ /*
+ * Iterate over all the child nodes of the pin controller node
+ * and create pin groups and pin function lists.
+ */
+ for_each_child_of_node(dev_np, cfg_np) {
+ struct device_node *func_np;
- groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
- if (!groups) {
- dev_err(dev, "failed allocate memory for ping group list\n");
- return -EINVAL;
+ if (!of_get_child_count(cfg_np)) {
+ if (!of_find_property(cfg_np,
+ "samsung,pin-function", NULL))
+ continue;
+ ++func_cnt;
+ continue;
+ }
+
+ for_each_child_of_node(cfg_np, func_np) {
+ if (!of_find_property(func_np,
+ "samsung,pin-function", NULL))
+ continue;
+ ++func_cnt;
+ }
}
- grp = groups;
- functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
+ functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
+ GFP_KERNEL);
if (!functions) {
dev_err(dev, "failed to allocate memory for function list\n");
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
func = functions;
@@ -666,61 +750,68 @@ static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
* Iterate over all the child nodes of the pin controller node
* and create pin groups and pin function lists.
*/
+ func_cnt = 0;
for_each_child_of_node(dev_np, cfg_np) {
- u32 function;
- if (!of_find_property(cfg_np, "samsung,pins", NULL))
+ struct device_node *func_np;
+
+ if (!of_get_child_count(cfg_np)) {
+ ret = samsung_pinctrl_create_function(dev, drvdata,
+ cfg_np, func);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0) {
+ ++func;
+ ++func_cnt;
+ }
continue;
+ }
- ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
- &drvdata->pctl, &pin_list, &npins);
- if (ret)
- return ret;
-
- /* derive pin group name from the node name */
- gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
- GFP_KERNEL);
- if (!gname) {
- dev_err(dev, "failed to alloc memory for group name\n");
- return -ENOMEM;
+ for_each_child_of_node(cfg_np, func_np) {
+ ret = samsung_pinctrl_create_function(dev, drvdata,
+ func_np, func);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ if (ret > 0) {
+ ++func;
+ ++func_cnt;
+ }
}
- sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
+ }
- grp->name = gname;
- grp->pins = pin_list;
- grp->num_pins = npins;
- of_property_read_u32(cfg_np, "samsung,pin-function", &function);
- grp->func = function;
- grp++;
+ *cnt = func_cnt;
+ return functions;
+}
- if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
- continue;
+/*
+ * Parse the information about all the available pin groups and pin functions
+ * from device node of the pin-controller. A pin group is formed with all
+ * the pins listed in the "samsung,pins" property.
+ */
- /* derive function name from the node name */
- fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
- GFP_KERNEL);
- if (!fname) {
- dev_err(dev, "failed to alloc memory for func name\n");
- return -ENOMEM;
- }
- sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
-
- func->name = fname;
- func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
- if (!func->groups) {
- dev_err(dev, "failed to alloc memory for group list "
- "in pin function");
- return -ENOMEM;
- }
- func->groups[0] = gname;
- func->num_groups = 1;
- func++;
- func_idx++;
+static int samsung_pinctrl_parse_dt(struct platform_device *pdev,
+ struct samsung_pinctrl_drv_data *drvdata)
+{
+ struct device *dev = &pdev->dev;
+ struct samsung_pin_group *groups;
+ struct samsung_pmx_func *functions;
+ unsigned int grp_cnt = 0, func_cnt = 0;
+
+ groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt);
+ if (IS_ERR(groups)) {
+ dev_err(dev, "failed to parse pin groups\n");
+ return PTR_ERR(groups);
+ }
+
+ functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);
+ if (IS_ERR(functions)) {
+ dev_err(dev, "failed to parse pin functions\n");
+ return PTR_ERR(groups);
}
drvdata->pin_groups = groups;
drvdata->nr_groups = grp_cnt;
drvdata->pmx_functions = functions;
- drvdata->nr_functions = func_idx;
+ drvdata->nr_functions = func_cnt;
return 0;
}
@@ -790,7 +881,8 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
pin_bank = &drvdata->ctrl->pin_banks[bank];
pin_bank->grange.name = pin_bank->name;
pin_bank->grange.id = bank;
- pin_bank->grange.pin_base = pin_bank->pin_base;
+ pin_bank->grange.pin_base = drvdata->ctrl->base
+ + pin_bank->pin_base;
pin_bank->grange.base = pin_bank->gpio_chip.base;
pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
pin_bank->grange.gc = &pin_bank->gpio_chip;
@@ -800,7 +892,19 @@ static int samsung_pinctrl_register(struct platform_device *pdev,
return 0;
}
+static int samsung_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void samsung_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ pinctrl_free_gpio(chip->base + offset);
+}
+
static const struct gpio_chip samsung_gpiolib_chip = {
+ .request = samsung_gpio_request,
+ .free = samsung_gpio_free,
.set = samsung_gpio_set,
.get = samsung_gpio_get,
.direction_input = samsung_gpio_direction_input,
diff --git a/drivers/pinctrl/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index b3e41fa5798b..2b882320e8e9 100644
--- a/drivers/pinctrl/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -156,13 +156,6 @@ struct samsung_pin_bank {
* @nr_banks: number of pin banks.
* @base: starting system wide pin number.
* @nr_pins: number of pins supported by the controller.
- * @geint_con: offset of the ext-gpio controller registers.
- * @geint_mask: offset of the ext-gpio interrupt mask registers.
- * @geint_pend: offset of the ext-gpio interrupt pending registers.
- * @weint_con: offset of the ext-wakeup controller registers.
- * @weint_mask: offset of the ext-wakeup interrupt mask registers.
- * @weint_pend: offset of the ext-wakeup interrupt pending registers.
- * @svc: offset of the interrupt service register.
* @eint_gpio_init: platform specific callback to setup the external gpio
* interrupts for the controller.
* @eint_wkup_init: platform specific callback to setup the external wakeup
@@ -176,16 +169,6 @@ struct samsung_pin_ctrl {
u32 base;
u32 nr_pins;
- u32 geint_con;
- u32 geint_mask;
- u32 geint_pend;
-
- u32 weint_con;
- u32 weint_mask;
- u32 weint_pend;
-
- u32 svc;
-
int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *);
int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *);
void (*suspend)(struct samsung_pinctrl_drv_data *);
@@ -248,6 +231,7 @@ struct samsung_pmx_func {
const char *name;
const char **groups;
u8 num_groups;
+ u32 val;
};
/* list of all exported SoC specific data */
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index a9288ab01f7b..80f641ee4dea 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -409,11 +409,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
{
- int err;
- int ret;
-
- ret = gpiochip_remove(&pfc->gpio->gpio_chip);
- err = gpiochip_remove(&pfc->func->gpio_chip);
+ gpiochip_remove(&pfc->gpio->gpio_chip);
+ gpiochip_remove(&pfc->func->gpio_chip);
- return ret < 0 ? ret : err;
+ return 0;
}
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
index 2e688dc4a3c8..576d41b459e9 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c
@@ -1726,6 +1726,133 @@ static const unsigned int audio_clkout_mux[] = {
AUDIO_CLKOUT_MARK,
};
+/* - CAN -------------------------------------------------------------------- */
+
+static const unsigned int can0_data_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 29),
+};
+
+static const unsigned int can0_data_mux[] = {
+ CAN0_TX_MARK, CAN0_RX_MARK,
+};
+
+static const unsigned int can0_data_b_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 3),
+};
+
+static const unsigned int can0_data_b_mux[] = {
+ CAN0_TX_B_MARK, CAN0_RX_B_MARK,
+};
+
+static const unsigned int can0_data_c_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 18),
+};
+
+static const unsigned int can0_data_c_mux[] = {
+ CAN0_TX_C_MARK, CAN0_RX_C_MARK,
+};
+
+static const unsigned int can0_data_d_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27),
+};
+
+static const unsigned int can0_data_d_mux[] = {
+ CAN0_TX_D_MARK, CAN0_RX_D_MARK,
+};
+
+static const unsigned int can0_data_e_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 28),
+};
+
+static const unsigned int can0_data_e_mux[] = {
+ CAN0_TX_E_MARK, CAN0_RX_E_MARK,
+};
+
+static const unsigned int can0_data_f_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6),
+};
+
+static const unsigned int can0_data_f_mux[] = {
+ CAN0_TX_F_MARK, CAN0_RX_F_MARK,
+};
+
+static const unsigned int can1_data_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 20),
+};
+
+static const unsigned int can1_data_mux[] = {
+ CAN1_TX_MARK, CAN1_RX_MARK,
+};
+
+static const unsigned int can1_data_b_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(7, 8), RCAR_GP_PIN(7, 9),
+};
+
+static const unsigned int can1_data_b_mux[] = {
+ CAN1_TX_B_MARK, CAN1_RX_B_MARK,
+};
+
+static const unsigned int can1_data_c_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(5, 20), RCAR_GP_PIN(5, 19),
+};
+
+static const unsigned int can1_data_c_mux[] = {
+ CAN1_TX_C_MARK, CAN1_RX_C_MARK,
+};
+
+static const unsigned int can1_data_d_pins[] = {
+ /* TX, RX */
+ RCAR_GP_PIN(4, 29), RCAR_GP_PIN(4, 31),
+};
+
+static const unsigned int can1_data_d_mux[] = {
+ CAN1_TX_D_MARK, CAN1_RX_D_MARK,
+};
+
+static const unsigned int can_clk_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(7, 2),
+};
+
+static const unsigned int can_clk_mux[] = {
+ CAN_CLK_MARK,
+};
+
+static const unsigned int can_clk_b_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(5, 21),
+};
+
+static const unsigned int can_clk_b_mux[] = {
+ CAN_CLK_B_MARK,
+};
+
+static const unsigned int can_clk_c_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(4, 30),
+};
+
+static const unsigned int can_clk_c_mux[] = {
+ CAN_CLK_C_MARK,
+};
+
+static const unsigned int can_clk_d_pins[] = {
+ /* CLK */
+ RCAR_GP_PIN(7, 19),
+};
+
+static const unsigned int can_clk_d_mux[] = {
+ CAN_CLK_D_MARK,
+};
/* - DU --------------------------------------------------------------------- */
static const unsigned int du_rgb666_pins[] = {
@@ -1867,6 +1994,192 @@ static const unsigned int eth_rmii_mux[] = {
ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK,
ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK,
};
+
+/* - HSCIF0 ----------------------------------------------------------------- */
+static const unsigned int hscif0_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4),
+};
+static const unsigned int hscif0_data_mux[] = {
+ HRX0_MARK, HTX0_MARK,
+};
+static const unsigned int hscif0_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 2),
+};
+static const unsigned int hscif0_clk_mux[] = {
+ HSCK0_MARK,
+};
+static const unsigned int hscif0_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0),
+};
+static const unsigned int hscif0_ctrl_mux[] = {
+ HRTS0_N_MARK, HCTS0_N_MARK,
+};
+static const unsigned int hscif0_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 15),
+};
+static const unsigned int hscif0_data_b_mux[] = {
+ HRX0_B_MARK, HTX0_B_MARK,
+};
+static const unsigned int hscif0_ctrl_b_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13),
+};
+static const unsigned int hscif0_ctrl_b_mux[] = {
+ HRTS0_N_B_MARK, HCTS0_N_B_MARK,
+};
+static const unsigned int hscif0_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif0_data_c_mux[] = {
+ HRX0_C_MARK, HTX0_C_MARK,
+};
+static const unsigned int hscif0_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif0_clk_c_mux[] = {
+ HSCK0_C_MARK,
+};
+/* - HSCIF1 ----------------------------------------------------------------- */
+static const unsigned int hscif1_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6),
+};
+static const unsigned int hscif1_data_mux[] = {
+ HRX1_MARK, HTX1_MARK,
+};
+static const unsigned int hscif1_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 7),
+};
+static const unsigned int hscif1_clk_mux[] = {
+ HSCK1_MARK,
+};
+static const unsigned int hscif1_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8),
+};
+static const unsigned int hscif1_ctrl_mux[] = {
+ HRTS1_N_MARK, HCTS1_N_MARK,
+};
+static const unsigned int hscif1_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18),
+};
+static const unsigned int hscif1_data_b_mux[] = {
+ HRX1_B_MARK, HTX1_B_MARK,
+};
+static const unsigned int hscif1_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_c_mux[] = {
+ HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(7, 16),
+};
+static const unsigned int hscif1_clk_c_mux[] = {
+ HSCK1_C_MARK,
+};
+static const unsigned int hscif1_ctrl_c_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(7, 18), RCAR_GP_PIN(7, 17),
+};
+static const unsigned int hscif1_ctrl_c_mux[] = {
+ HRTS1_N_C_MARK, HCTS1_N_C_MARK,
+};
+static const unsigned int hscif1_data_d_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18),
+};
+static const unsigned int hscif1_data_d_mux[] = {
+ HRX1_D_MARK, HTX1_D_MARK,
+};
+static const unsigned int hscif1_data_e_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(7, 14), RCAR_GP_PIN(7, 15),
+};
+static const unsigned int hscif1_data_e_mux[] = {
+ HRX1_C_MARK, HTX1_C_MARK,
+};
+static const unsigned int hscif1_clk_e_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(2, 6),
+};
+static const unsigned int hscif1_clk_e_mux[] = {
+ HSCK1_E_MARK,
+};
+static const unsigned int hscif1_ctrl_e_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 7),
+};
+static const unsigned int hscif1_ctrl_e_mux[] = {
+ HRTS1_N_E_MARK, HCTS1_N_E_MARK,
+};
+/* - HSCIF2 ----------------------------------------------------------------- */
+static const unsigned int hscif2_data_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17),
+};
+static const unsigned int hscif2_data_mux[] = {
+ HRX2_MARK, HTX2_MARK,
+};
+static const unsigned int hscif2_clk_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(4, 15),
+};
+static const unsigned int hscif2_clk_mux[] = {
+ HSCK2_MARK,
+};
+static const unsigned int hscif2_ctrl_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13),
+};
+static const unsigned int hscif2_ctrl_mux[] = {
+ HRTS2_N_MARK, HCTS2_N_MARK,
+};
+static const unsigned int hscif2_data_b_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 22),
+};
+static const unsigned int hscif2_data_b_mux[] = {
+ HRX2_B_MARK, HTX2_B_MARK,
+};
+static const unsigned int hscif2_ctrl_b_pins[] = {
+ /* RTS, CTS */
+ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 21),
+};
+static const unsigned int hscif2_ctrl_b_mux[] = {
+ HRTS2_N_B_MARK, HCTS2_N_B_MARK,
+};
+static const unsigned int hscif2_data_c_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1),
+};
+static const unsigned int hscif2_data_c_mux[] = {
+ HRX2_C_MARK, HTX2_C_MARK,
+};
+static const unsigned int hscif2_clk_c_pins[] = {
+ /* SCK */
+ RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_clk_c_mux[] = {
+ HSCK2_C_MARK,
+};
+static const unsigned int hscif2_data_d_pins[] = {
+ /* RX, TX */
+ RCAR_GP_PIN(1, 20), RCAR_GP_PIN(5, 31),
+};
+static const unsigned int hscif2_data_d_mux[] = {
+ HRX2_B_MARK, HTX2_D_MARK,
+};
/* - I2C0 ------------------------------------------------------------------- */
static const unsigned int i2c0_pins[] = {
/* SCL, SDA */
@@ -3869,6 +4182,20 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(audio_clk_b_b),
SH_PFC_PIN_GROUP(audio_clk_c),
SH_PFC_PIN_GROUP(audio_clkout),
+ SH_PFC_PIN_GROUP(can0_data),
+ SH_PFC_PIN_GROUP(can0_data_b),
+ SH_PFC_PIN_GROUP(can0_data_c),
+ SH_PFC_PIN_GROUP(can0_data_d),
+ SH_PFC_PIN_GROUP(can0_data_e),
+ SH_PFC_PIN_GROUP(can0_data_f),
+ SH_PFC_PIN_GROUP(can1_data),
+ SH_PFC_PIN_GROUP(can1_data_b),
+ SH_PFC_PIN_GROUP(can1_data_c),
+ SH_PFC_PIN_GROUP(can1_data_d),
+ SH_PFC_PIN_GROUP(can_clk),
+ SH_PFC_PIN_GROUP(can_clk_b),
+ SH_PFC_PIN_GROUP(can_clk_c),
+ SH_PFC_PIN_GROUP(can_clk_d),
SH_PFC_PIN_GROUP(du_rgb666),
SH_PFC_PIN_GROUP(du_rgb888),
SH_PFC_PIN_GROUP(du_clk_out_0),
@@ -3885,6 +4212,32 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
SH_PFC_PIN_GROUP(eth_magic),
SH_PFC_PIN_GROUP(eth_mdio),
SH_PFC_PIN_GROUP(eth_rmii),
+ SH_PFC_PIN_GROUP(hscif0_data),
+ SH_PFC_PIN_GROUP(hscif0_clk),
+ SH_PFC_PIN_GROUP(hscif0_ctrl),
+ SH_PFC_PIN_GROUP(hscif0_data_b),
+ SH_PFC_PIN_GROUP(hscif0_ctrl_b),
+ SH_PFC_PIN_GROUP(hscif0_data_c),
+ SH_PFC_PIN_GROUP(hscif0_clk_c),
+ SH_PFC_PIN_GROUP(hscif1_data),
+ SH_PFC_PIN_GROUP(hscif1_clk),
+ SH_PFC_PIN_GROUP(hscif1_ctrl),
+ SH_PFC_PIN_GROUP(hscif1_data_b),
+ SH_PFC_PIN_GROUP(hscif1_data_c),
+ SH_PFC_PIN_GROUP(hscif1_clk_c),
+ SH_PFC_PIN_GROUP(hscif1_ctrl_c),
+ SH_PFC_PIN_GROUP(hscif1_data_d),
+ SH_PFC_PIN_GROUP(hscif1_data_e),
+ SH_PFC_PIN_GROUP(hscif1_clk_e),
+ SH_PFC_PIN_GROUP(hscif1_ctrl_e),
+ SH_PFC_PIN_GROUP(hscif2_data),
+ SH_PFC_PIN_GROUP(hscif2_clk),
+ SH_PFC_PIN_GROUP(hscif2_ctrl),
+ SH_PFC_PIN_GROUP(hscif2_data_b),
+ SH_PFC_PIN_GROUP(hscif2_ctrl_b),
+ SH_PFC_PIN_GROUP(hscif2_data_c),
+ SH_PFC_PIN_GROUP(hscif2_clk_c),
+ SH_PFC_PIN_GROUP(hscif2_data_d),
SH_PFC_PIN_GROUP(i2c0),
SH_PFC_PIN_GROUP(i2c0_b),
SH_PFC_PIN_GROUP(i2c0_c),
@@ -4155,6 +4508,30 @@ static const char * const audio_clk_groups[] = {
"audio_clkout",
};
+static const char * const can0_groups[] = {
+ "can0_data_a",
+ "can0_data_b",
+ "can0_data_c",
+ "can0_data_d",
+ "can0_data_e",
+ "can0_data_f",
+ "can_clk_a",
+ "can_clk_b",
+ "can_clk_c",
+ "can_clk_d",
+};
+
+static const char * const can1_groups[] = {
+ "can1_data_a",
+ "can1_data_b",
+ "can1_data_c",
+ "can1_data_d",
+ "can_clk_a",
+ "can_clk_b",
+ "can_clk_c",
+ "can_clk_d",
+};
+
static const char * const du_groups[] = {
"du_rgb666",
"du_rgb888",
@@ -4183,6 +4560,41 @@ static const char * const eth_groups[] = {
"eth_rmii",
};
+static const char * const hscif0_groups[] = {
+ "hscif0_data",
+ "hscif0_clk",
+ "hscif0_ctrl",
+ "hscif0_data_b",
+ "hscif0_ctrl_b",
+ "hscif0_data_c",
+ "hscif0_clk_c",
+};
+
+static const char * const hscif1_groups[] = {
+ "hscif1_data",
+ "hscif1_clk",
+ "hscif1_ctrl",
+ "hscif1_data_b",
+ "hscif1_data_c",
+ "hscif1_clk_c",
+ "hscif1_ctrl_c",
+ "hscif1_data_d",
+ "hscif1_data_e",
+ "hscif1_clk_e",
+ "hscif1_ctrl_e",
+};
+
+static const char * const hscif2_groups[] = {
+ "hscif2_data",
+ "hscif2_clk",
+ "hscif2_ctrl",
+ "hscif2_data_b",
+ "hscif2_ctrl_b",
+ "hscif2_data_c",
+ "hscif2_clk_c",
+ "hscif2_data_d",
+};
+
static const char * const i2c0_groups[] = {
"i2c0",
"i2c0_b",
@@ -4543,10 +4955,15 @@ static const char * const vin2_groups[] = {
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
+ SH_PFC_FUNCTION(can0),
+ SH_PFC_FUNCTION(can1),
SH_PFC_FUNCTION(du),
SH_PFC_FUNCTION(du0),
SH_PFC_FUNCTION(du1),
SH_PFC_FUNCTION(eth),
+ SH_PFC_FUNCTION(hscif0),
+ SH_PFC_FUNCTION(hscif1),
+ SH_PFC_FUNCTION(hscif2),
SH_PFC_FUNCTION(i2c0),
SH_PFC_FUNCTION(i2c1),
SH_PFC_FUNCTION(i2c2),
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
index ee370de4609a..0bd8f4401b42 100644
--- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
+++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
@@ -3842,7 +3842,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
cfg.init_data = &sh73a0_vccq_mc0_init_data;
cfg.driver_data = pfc;
- data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
+ data->vccq_mc0 = devm_regulator_register(pfc->dev,
+ &sh73a0_vccq_mc0_desc, &cfg);
if (IS_ERR(data->vccq_mc0)) {
ret = PTR_ERR(data->vccq_mc0);
dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
@@ -3855,16 +3856,8 @@ static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
return 0;
}
-static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc)
-{
- struct sh73a0_pinmux_data *data = pfc->soc_data;
-
- regulator_unregister(data->vccq_mc0);
-}
-
static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
.init = sh73a0_pinmux_soc_init,
- .exit = sh73a0_pinmux_soc_exit,
.get_bias = sh73a0_pinmux_get_bias,
.set_bias = sh73a0_pinmux_set_bias,
};
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
index e758af95c209..11db3ee39d40 100644
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -345,27 +345,6 @@ done:
return ret;
}
-static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
- struct sh_pfc *pfc = pmx->pfc;
- const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
- unsigned long flags;
- unsigned int i;
-
- spin_lock_irqsave(&pfc->lock, flags);
-
- for (i = 0; i < grp->nr_pins; ++i) {
- int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]);
- struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
-
- cfg->type = PINMUX_TYPE_NONE;
- }
-
- spin_unlock_irqrestore(&pfc->lock, flags);
-}
-
static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -464,7 +443,6 @@ static const struct pinmux_ops sh_pfc_pinmux_ops = {
.get_function_name = sh_pfc_get_function_name,
.get_function_groups = sh_pfc_get_function_groups,
.enable = sh_pfc_func_enable,
- .disable = sh_pfc_func_disable,
.gpio_request_enable = sh_pfc_gpio_request_enable,
.gpio_disable_free = sh_pfc_gpio_disable_free,
.gpio_set_direction = sh_pfc_gpio_set_direction,
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c
index 014f5b1fee55..4c1d7c68666d 100644
--- a/drivers/pinctrl/sirf/pinctrl-sirf.c
+++ b/drivers/pinctrl/sirf/pinctrl-sirf.c
@@ -186,15 +186,6 @@ static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
return 0;
}
-static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
- unsigned group)
-{
- struct sirfsoc_pmx *spmx;
-
- spmx = pinctrl_dev_get_drvdata(pmxdev);
- sirfsoc_pinmux_endisable(spmx, selector, false);
-}
-
static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
{
return sirfsoc_pmxfunc_cnt;
@@ -240,7 +231,6 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
static struct pinmux_ops sirfsoc_pinmux_ops = {
.enable = sirfsoc_pinmux_enable,
- .disable = sirfsoc_pinmux_disable,
.get_functions_count = sirfsoc_pinmux_get_funcs_count,
.get_function_name = sirfsoc_pinmux_get_func_name,
.get_function_groups = sirfsoc_pinmux_get_groups,
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
index 04d93e602674..9ef18eb958e1 100644
--- a/drivers/pinctrl/spear/Kconfig
+++ b/drivers/pinctrl/spear/Kconfig
@@ -48,6 +48,7 @@ config PINCTRL_SPEAR1340
config PINCTRL_SPEAR_PLGPIO
bool "SPEAr SoC PLGPIO Controller"
depends on GPIOLIB && PINCTRL_SPEAR
+ select GPIOLIB_IRQCHIP
help
Say yes here to support PLGPIO controller on ST Microelectronics SPEAr
SoCs.
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
index ff2940e9f2a7..bddb79105d67 100644
--- a/drivers/pinctrl/spear/pinctrl-plgpio.c
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -11,12 +11,11 @@
#include <linux/clk.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@@ -54,7 +53,6 @@ struct plgpio_regs {
*
* lock: lock for guarding gpio registers
* base: base address of plgpio block
- * irq_base: irq number of plgpio0
* chip: gpio framework specific chip information structure
* p2o: function ptr for pin to offset conversion. This is required only for
* machines where mapping b/w pin and offset is not 1-to-1.
@@ -68,8 +66,6 @@ struct plgpio {
spinlock_t lock;
void __iomem *base;
struct clk *clk;
- unsigned irq_base;
- struct irq_domain *irq_domain;
struct gpio_chip chip;
int (*p2o)(int pin); /* pin_to_offset */
int (*o2p)(int offset); /* offset_to_pin */
@@ -280,21 +276,12 @@ disable_clk:
pinctrl_free_gpio(gpio);
}
-static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct plgpio *plgpio = container_of(chip, struct plgpio, chip);
-
- if (IS_ERR_VALUE(plgpio->irq_base))
- return -EINVAL;
-
- return irq_find_mapping(plgpio->irq_domain, offset);
-}
-
/* PLGPIO IRQ */
static void plgpio_irq_disable(struct irq_data *d)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
unsigned long flags;
/* get correct offset for "offset" pin */
@@ -311,8 +298,9 @@ static void plgpio_irq_disable(struct irq_data *d)
static void plgpio_irq_enable(struct irq_data *d)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
unsigned long flags;
/* get correct offset for "offset" pin */
@@ -329,8 +317,9 @@ static void plgpio_irq_enable(struct irq_data *d)
static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger)
{
- struct plgpio *plgpio = irq_data_get_irq_chip_data(d);
- int offset = d->irq - plgpio->irq_base;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
+ int offset = d->hwirq;
void __iomem *reg_off;
unsigned int supported_type = 0, val;
@@ -369,7 +358,8 @@ static struct irq_chip plgpio_irqchip = {
static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct plgpio *plgpio = irq_get_handler_data(irq);
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct plgpio *plgpio = container_of(gc, struct plgpio, chip);
struct irq_chip *irqchip = irq_desc_get_chip(desc);
int regs_count, count, pin, offset, i = 0;
unsigned long pending;
@@ -410,7 +400,8 @@ static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc)
/* get correct irq line number */
pin = i * MAX_GPIO_PER_REG + pin;
- generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin));
+ generic_handle_irq(
+ irq_find_mapping(gc->irqdomain, pin));
}
}
chained_irq_exit(irqchip, desc);
@@ -523,10 +514,9 @@ end:
}
static int plgpio_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
struct plgpio *plgpio;
struct resource *res;
- int ret, irq, i;
+ int ret, irq;
plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
if (!plgpio) {
@@ -563,7 +553,6 @@ static int plgpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, plgpio);
spin_lock_init(&plgpio->lock);
- plgpio->irq_base = -1;
plgpio->chip.base = -1;
plgpio->chip.request = plgpio_request;
plgpio->chip.free = plgpio_free;
@@ -571,10 +560,10 @@ static int plgpio_probe(struct platform_device *pdev)
plgpio->chip.direction_output = plgpio_direction_output;
plgpio->chip.get = plgpio_get_value;
plgpio->chip.set = plgpio_set_value;
- plgpio->chip.to_irq = plgpio_to_irq;
plgpio->chip.label = dev_name(&pdev->dev);
plgpio->chip.dev = &pdev->dev;
plgpio->chip.owner = THIS_MODULE;
+ plgpio->chip.of_node = pdev->dev.of_node;
if (!IS_ERR(plgpio->clk)) {
ret = clk_prepare(plgpio->clk);
@@ -592,43 +581,32 @@ static int plgpio_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_info(&pdev->dev, "irqs not supported\n");
- return 0;
- }
-
- plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0);
- if (IS_ERR_VALUE(plgpio->irq_base)) {
- /* we would not support irq for gpio */
- dev_warn(&pdev->dev, "couldn't allocate irq base\n");
+ dev_info(&pdev->dev, "PLGPIO registered without IRQs\n");
return 0;
}
- plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio,
- plgpio->irq_base, 0, &irq_domain_simple_ops, NULL);
- if (WARN_ON(!plgpio->irq_domain)) {
- dev_err(&pdev->dev, "irq domain init failed\n");
- irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio);
- ret = -ENXIO;
+ ret = gpiochip_irqchip_add(&plgpio->chip,
+ &plgpio_irqchip,
+ 0,
+ handle_simple_irq,
+ IRQ_TYPE_NONE);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to add irqchip to gpiochip\n");
goto remove_gpiochip;
}
- irq_set_chained_handler(irq, plgpio_irq_handler);
- for (i = 0; i < plgpio->chip.ngpio; i++) {
- irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip,
- handle_simple_irq);
- set_irq_flags(i + plgpio->irq_base, IRQF_VALID);
- irq_set_chip_data(i + plgpio->irq_base, plgpio);
- }
+ gpiochip_set_chained_irqchip(&plgpio->chip,
+ &plgpio_irqchip,
+ irq,
+ plgpio_irq_handler);
- irq_set_handler_data(irq, plgpio);
dev_info(&pdev->dev, "PLGPIO registered with IRQs\n");
return 0;
remove_gpiochip:
dev_info(&pdev->dev, "Remove gpiochip\n");
- if (gpiochip_remove(&plgpio->chip))
- dev_err(&pdev->dev, "unable to remove gpiochip\n");
+ gpiochip_remove(&plgpio->chip);
unprepare_clk:
if (!IS_ERR(plgpio->clk))
clk_unprepare(plgpio->clk);
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index 58bf6867aa17..f72cc4e192bd 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -274,12 +274,6 @@ static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
return spear_pinctrl_endisable(pctldev, function, group, true);
}
-static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
- unsigned function, unsigned group)
-{
- spear_pinctrl_endisable(pctldev, function, group, false);
-}
-
/* gpio with pinmux */
static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx,
unsigned pin)
@@ -345,7 +339,6 @@ static const struct pinmux_ops spear_pinmux_ops = {
.get_function_name = spear_pinctrl_get_func_name,
.get_function_groups = spear_pinctrl_get_func_groups,
.enable = spear_pinctrl_enable,
- .disable = spear_pinctrl_disable,
.gpio_request_enable = gpio_request_enable,
.gpio_disable_free = gpio_disable_free,
};
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 73e0a305ea13..a5e10f777ed2 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -1,36 +1,42 @@
if ARCH_SUNXI
-config PINCTRL_SUNXI
- bool
-
config PINCTRL_SUNXI_COMMON
bool
select PINMUX
select GENERIC_PINCONF
config PINCTRL_SUN4I_A10
- def_bool PINCTRL_SUNXI || MACH_SUN4I
+ def_bool MACH_SUN4I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A10S
- def_bool PINCTRL_SUNXI || MACH_SUN5I
+ def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN5I_A13
- def_bool PINCTRL_SUNXI || MACH_SUN5I
+ def_bool MACH_SUN5I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31
- def_bool PINCTRL_SUNXI || MACH_SUN6I
+ def_bool MACH_SUN6I
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN6I_A31_R
- def_bool PINCTRL_SUNXI || MACH_SUN6I
+ def_bool MACH_SUN6I
depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON
config PINCTRL_SUN7I_A20
- def_bool PINCTRL_SUNXI || MACH_SUN7I
+ def_bool MACH_SUN7I
+ select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23
+ def_bool MACH_SUN8I
+ select PINCTRL_SUNXI_COMMON
+
+config PINCTRL_SUN8I_A23_R
+ def_bool MACH_SUN8I
+ depends on RESET_CONTROLLER
select PINCTRL_SUNXI_COMMON
endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index 0f4461cbe11d..e797efb02901 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_PINCTRL_SUN5I_A13) += pinctrl-sun5i-a13.o
obj-$(CONFIG_PINCTRL_SUN6I_A31) += pinctrl-sun6i-a31.o
obj-$(CONFIG_PINCTRL_SUN6I_A31_R) += pinctrl-sun6i-a31-r.o
obj-$(CONFIG_PINCTRL_SUN7I_A20) += pinctrl-sun7i-a20.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o
+obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index fa1ff7c7e357..86b608bedca6 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -1010,6 +1010,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
.pins = sun4i_a10_pins,
.npins = ARRAY_SIZE(sun4i_a10_pins),
+ .irq_banks = 1,
};
static int sun4i_a10_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
index 164d743f526c..2fa7430cabaf 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c
@@ -661,6 +661,7 @@ static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
.pins = sun5i_a10s_pins,
.npins = ARRAY_SIZE(sun5i_a10s_pins),
+ .irq_banks = 1,
};
static int sun5i_a10s_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
index 1188a2b7b988..e47c33dbae3a 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c
@@ -330,15 +330,12 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 0)), /* EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 1)), /* EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
- SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION_IRQ(0x6, 2)), /* EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -382,6 +379,7 @@ static const struct sunxi_desc_pin sun5i_a13_pins[] = {
static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
.pins = sun5i_a13_pins,
.npins = ARRAY_SIZE(sun5i_a13_pins),
+ .irq_banks = 1,
};
static int sun5i_a13_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
index 8fcba48e0a42..9a2517b65113 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c
@@ -93,6 +93,7 @@ static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = {
.pins = sun6i_a31_r_pins,
.npins = ARRAY_SIZE(sun6i_a31_r_pins),
.pin_base = PL_BASE,
+ .irq_banks = 2,
};
static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
index 8dea5856458b..a2b4b85c5ad5 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c
@@ -24,208 +24,244 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D0 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DTR */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DTR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PA_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D1 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DSR */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DSR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PA_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D2 */
- SUNXI_FUNCTION(0x4, "uart1")), /* DCD */
+ SUNXI_FUNCTION(0x4, "uart1"), /* DCD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PA_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D3 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RING */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RING */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PA_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD4 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D4 */
- SUNXI_FUNCTION(0x4, "uart1")), /* TX */
+ SUNXI_FUNCTION(0x4, "uart1"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PA_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD5 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D5 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RX */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PA_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD6 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D6 */
- SUNXI_FUNCTION(0x4, "uart1")), /* RTS */
+ SUNXI_FUNCTION(0x4, "uart1"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXD7 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D7 */
- SUNXI_FUNCTION(0x4, "uart1")), /* CTS */
+ SUNXI_FUNCTION(0x4, "uart1"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PA_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXCLK */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D8 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D8 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PA_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXEN */
SUNXI_FUNCTION(0x3, "lcd1"), /* D9 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CMD */
- SUNXI_FUNCTION(0x5, "mmc2")), /* CMD */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PA_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* GTXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D10 */
SUNXI_FUNCTION(0x4, "mmc3"), /* CLK */
- SUNXI_FUNCTION(0x5, "mmc2")), /* CLK */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PA_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD0 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D11 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D0 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D0 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PA_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD1 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D12 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D1 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D1 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PA_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD2 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D13 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D2 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D2 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 13)), /* PA_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD3 */
SUNXI_FUNCTION(0x3, "lcd1"), /* D14 */
SUNXI_FUNCTION(0x4, "mmc3"), /* D3 */
- SUNXI_FUNCTION(0x5, "mmc2")), /* D3 */
+ SUNXI_FUNCTION(0x5, "mmc2"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), /* PA_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD4 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D15 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D15 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 15)), /* PA_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD5 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D16 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D16 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 16)), /* PA_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD6 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D17 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D17 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 17)), /* PA_EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXD7 */
- SUNXI_FUNCTION(0x3, "lcd1")), /* D18 */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* D18 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 18)), /* PA_EINT18 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 19),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXDV */
SUNXI_FUNCTION(0x3, "lcd1"), /* D19 */
- SUNXI_FUNCTION(0x4, "pwm3")), /* Positive */
+ SUNXI_FUNCTION(0x4, "pwm3"), /* Positive */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 19)), /* PA_EINT19 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 20),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXCLK */
SUNXI_FUNCTION(0x3, "lcd1"), /* D20 */
- SUNXI_FUNCTION(0x4, "pwm3")), /* Negative */
+ SUNXI_FUNCTION(0x4, "pwm3"), /* Negative */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 20)), /* PA_EINT20 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 21),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* TXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D21 */
- SUNXI_FUNCTION(0x4, "spi3")), /* CS0 */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CS0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 21)), /* PA_EINT21 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 22),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* RXERR */
SUNXI_FUNCTION(0x3, "lcd1"), /* D22 */
- SUNXI_FUNCTION(0x4, "spi3")), /* CLK */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 22)), /* PA_EINT22 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 23),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* COL */
SUNXI_FUNCTION(0x3, "lcd1"), /* D23 */
- SUNXI_FUNCTION(0x4, "spi3")), /* MOSI */
+ SUNXI_FUNCTION(0x4, "spi3"), /* MOSI */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 23)), /* PA_EINT23 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 24),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CRS */
SUNXI_FUNCTION(0x3, "lcd1"), /* CLK */
- SUNXI_FUNCTION(0x4, "spi3")), /* MISO */
+ SUNXI_FUNCTION(0x4, "spi3"), /* MISO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 24)), /* PA_EINT24 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 25),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* CLKIN */
SUNXI_FUNCTION(0x3, "lcd1"), /* DE */
- SUNXI_FUNCTION(0x4, "spi3")), /* CS1 */
+ SUNXI_FUNCTION(0x4, "spi3"), /* CS1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 25)), /* PA_EINT25 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 26),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDC */
- SUNXI_FUNCTION(0x3, "lcd1")), /* HSYNC */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* HSYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 26)), /* PA_EINT26 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 27),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "gmac"), /* MDIO */
- SUNXI_FUNCTION(0x3, "lcd1")), /* VSYNC */
+ SUNXI_FUNCTION(0x3, "lcd1"), /* VSYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 27)), /* PA_EINT27 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* MCLK */
SUNXI_FUNCTION(0x3, "uart3"), /* CTS */
- SUNXI_FUNCTION(0x4, "csi")), /* MCLK1 */
+ SUNXI_FUNCTION(0x4, "csi"), /* MCLK1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PB_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* BCLK */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* BCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PB_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* LRCK */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* LRCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PB_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "i2s0")), /* DO0 */
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DO0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PB_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO1 */
- SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
+ SUNXI_FUNCTION(0x3, "uart3"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PB_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO2 */
SUNXI_FUNCTION(0x3, "uart3"), /* TX */
- SUNXI_FUNCTION(0x4, "i2c3")), /* SCK */
+ SUNXI_FUNCTION(0x4, "i2c3"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PB_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2s0"), /* DO3 */
SUNXI_FUNCTION(0x3, "uart3"), /* RX */
- SUNXI_FUNCTION(0x4, "i2c3")), /* SDA */
+ SUNXI_FUNCTION(0x4, "i2c3"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PB_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x3, "i2s0")), /* DI */
+ SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PB_EINT7 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -510,86 +546,103 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* PCLK */
- SUNXI_FUNCTION(0x3, "ts")), /* CLK */
+ SUNXI_FUNCTION(0x3, "ts"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PE_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* MCLK */
- SUNXI_FUNCTION(0x3, "ts")), /* ERR */
+ SUNXI_FUNCTION(0x3, "ts"), /* ERR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PE_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* HSYNC */
- SUNXI_FUNCTION(0x3, "ts")), /* SYNC */
+ SUNXI_FUNCTION(0x3, "ts"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PE_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* VSYNC */
- SUNXI_FUNCTION(0x3, "ts")), /* DVLD */
+ SUNXI_FUNCTION(0x3, "ts"), /* DVLD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PE_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D0 */
- SUNXI_FUNCTION(0x3, "uart5")), /* TX */
+ SUNXI_FUNCTION(0x3, "uart5"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PE_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D1 */
- SUNXI_FUNCTION(0x3, "uart5")), /* RX */
+ SUNXI_FUNCTION(0x3, "uart5"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PE_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D2 */
- SUNXI_FUNCTION(0x3, "uart5")), /* RTS */
+ SUNXI_FUNCTION(0x3, "uart5"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PE_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D3 */
- SUNXI_FUNCTION(0x3, "uart5")), /* CTS */
+ SUNXI_FUNCTION(0x3, "uart5"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PE_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D4 */
- SUNXI_FUNCTION(0x3, "ts")), /* D0 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PE_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D5 */
- SUNXI_FUNCTION(0x3, "ts")), /* D1 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PE_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D6 */
- SUNXI_FUNCTION(0x3, "ts")), /* D2 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PE_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D7 */
- SUNXI_FUNCTION(0x3, "ts")), /* D3 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PE_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D8 */
- SUNXI_FUNCTION(0x3, "ts")), /* D4 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D4 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PE_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D9 */
- SUNXI_FUNCTION(0x3, "ts")), /* D5 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D5 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PE_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D10 */
- SUNXI_FUNCTION(0x3, "ts")), /* D6 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D6 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PE_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "csi"), /* D11 */
- SUNXI_FUNCTION(0x3, "ts")), /* D7 */
+ SUNXI_FUNCTION(0x3, "ts"), /* D7 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PE_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "csi")), /* MIPI CSI MCLK */
+ SUNXI_FUNCTION(0x2, "csi"), /* MIPI CSI MCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PE_EINT16 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -625,86 +678,105 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* CLK */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PG_EINT0 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* CMD */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PG_EINT1 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D0 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PG_EINT2 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D1 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PG_EINT3 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D2 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PG_EINT4 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "mmc1")), /* D3 */
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PG_EINT5 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* TX */
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PG_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* RX */
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PG_EINT7 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* RTS */
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PG_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart2")), /* CTS */
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PG_EINT9 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SCK */
- SUNXI_FUNCTION(0x3, "usb")), /* DP3 */
+ SUNXI_FUNCTION(0x3, "usb"), /* DP3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 10)), /* PG_EINT10 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c3"), /* SDA */
- SUNXI_FUNCTION(0x3, "usb")), /* DM3 */
+ SUNXI_FUNCTION(0x3, "usb"), /* DM3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 11)), /* PG_EINT11 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS1 */
- SUNXI_FUNCTION(0x3, "i2s1")), /* MCLK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* MCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 12)), /* PG_EINT12 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CS0 */
- SUNXI_FUNCTION(0x3, "i2s1")), /* BCLK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 13)), /* PG_EINT13 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
- SUNXI_FUNCTION(0x3, "i2s1")), /* LRCK */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* LRCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 14)), /* PG_EINT14 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 15),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
- SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 15)), /* PG_EINT15 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 16),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
- SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 16)), /* PG_EINT16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 17),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart4")), /* TX */
+ SUNXI_FUNCTION(0x2, "uart4"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 17)), /* PG_EINT17 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 18),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
- SUNXI_FUNCTION(0x2, "uart4")), /* RX */
+ SUNXI_FUNCTION(0x2, "uart4"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 18)), /* PG_EINT18 */
/* Hole */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
SUNXI_FUNCTION(0x0, "gpio_in"),
@@ -836,6 +908,7 @@ static const struct sunxi_desc_pin sun6i_a31_pins[] = {
static const struct sunxi_pinctrl_desc sun6i_a31_pinctrl_data = {
.pins = sun6i_a31_pins,
.npins = ARRAY_SIZE(sun6i_a31_pins),
+ .irq_banks = 4,
};
static int sun6i_a31_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
index d8577ce5f1a4..dac99e02bfdb 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c
@@ -1036,6 +1036,7 @@ static const struct sunxi_desc_pin sun7i_a20_pins[] = {
static const struct sunxi_pinctrl_desc sun7i_a20_pinctrl_data = {
.pins = sun7i_a20_pins,
.npins = ARRAY_SIZE(sun7i_a20_pins),
+ .irq_banks = 1,
};
static int sun7i_a20_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
new file mode 100644
index 000000000000..90f3b3a7c51e
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c
@@ -0,0 +1,142 @@
+/*
+ * Allwinner A23 SoCs special pins pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Boris Brezillon
+ * Boris Brezillon <boris.brezillon@free-electrons.com>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_r_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */
+ SUNXI_FUNCTION(0x3, "s_twi"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PL_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */
+ SUNXI_FUNCTION(0x3, "s_twi"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PL_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PL_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PL_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* MS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PL_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* CK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PL_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PL_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PL_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_twi"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 8)), /* PL_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_twi"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 9)), /* PL_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_pwm"),
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 10)), /* PL_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 11)), /* PL_EINT11 */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_r_pinctrl_data = {
+ .pins = sun8i_a23_r_pins,
+ .npins = ARRAY_SIZE(sun8i_a23_r_pins),
+ .pin_base = PL_BASE,
+ .irq_banks = 1,
+};
+
+static int sun8i_a23_r_pinctrl_probe(struct platform_device *pdev)
+{
+ struct reset_control *rstc;
+ int ret;
+
+ rstc = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(rstc)) {
+ dev_err(&pdev->dev, "Reset controller missing\n");
+ return PTR_ERR(rstc);
+ }
+
+ ret = reset_control_deassert(rstc);
+ if (ret)
+ return ret;
+
+ ret = sunxi_pinctrl_init(pdev,
+ &sun8i_a23_r_pinctrl_data);
+
+ if (ret)
+ reset_control_assert(rstc);
+
+ return ret;
+}
+
+static struct of_device_id sun8i_a23_r_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-a23-r-pinctrl", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match);
+
+static struct platform_driver sun8i_a23_r_pinctrl_driver = {
+ .probe = sun8i_a23_r_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-a23-r-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = sun8i_a23_r_pinctrl_match,
+ },
+};
+module_platform_driver(sun8i_a23_r_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 R_PIO pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
new file mode 100644
index 000000000000..ac71e8c5901b
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c
@@ -0,0 +1,593 @@
+/*
+ * Allwinner A23 SoCs pinctrl driver.
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * Copyright (C) 2014 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun8i_a23_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CS */
+ SUNXI_FUNCTION(0x3, "jtag"), /* MS0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 0)), /* PA_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* CLK */
+ SUNXI_FUNCTION(0x3, "jtag"), /* CKO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 1)), /* PA_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MOSI */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DOO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 2)), /* PA_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi1"), /* MISO */
+ SUNXI_FUNCTION(0x3, "jtag"), /* DIO */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 3)), /* PA_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 4)), /* PA_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 5)), /* PA_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 6)), /* PA_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart4"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 0, 7)), /* PA_EINT7 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 0)), /* PB_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 1)), /* PB_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 2)), /* PB_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 3)), /* PB_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 4)), /* PB_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 5)), /* PB_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s0"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 6)), /* PB_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "i2s0"), /* DI */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 1, 7)), /* PB_EINT7 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* WE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MOSI */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* MISO */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CE1 */
+ SUNXI_FUNCTION(0x3, "spi0")), /* CS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RE */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* CMD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* RB1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ2 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ3 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ4 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ5 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQS */
+ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D2 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D3 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* CMD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D4 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D5 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D6 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D7 */
+ SUNXI_FUNCTION(0x3, "mmc1")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D8 */
+ SUNXI_FUNCTION(0x3, "uart3")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D9 */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D10 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D11 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D12 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* RTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D13 */
+ SUNXI_FUNCTION(0x3, "uart1")), /* CTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D14 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* SYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D15 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D16 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* DOUT */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D17 */
+ SUNXI_FUNCTION(0x3, "i2s1")), /* DIN */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D18 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D19 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D20 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D21 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D22 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* D23 */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VPC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 25),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* DE */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 26),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* HSYNC */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VP3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 27),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "lcd0"), /* VSYNC */
+ SUNXI_FUNCTION(0x3, "lvds0")), /* VN3 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* PCLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* MCLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* HSYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* VSYNC */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi")), /* D7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SCK */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "csi"), /* SDA */
+ SUNXI_FUNCTION(0x3, "i2c2")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out")),
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D1 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* MS1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D0 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DI1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart0")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* CMD */
+ SUNXI_FUNCTION(0x3, "jtag")), /* DO1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D3 */
+ SUNXI_FUNCTION(0x3, "uart0")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc0"), /* D2 */
+ SUNXI_FUNCTION(0x3, "jtag")), /* CK1 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 0)), /* PG_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 1)), /* PG_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 2)), /* PG_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 3)), /* PG_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 4)), /* PG_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 5)), /* PG_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 6)), /* PG_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 7)), /* PG_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 8)), /* PG_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 9)), /* PG_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* SYNC */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 10)), /* PG_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 11)), /* PG_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 12)), /* PG_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2s1"), /* DIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x4, 2, 13)), /* PG_EINT13 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "pwm0")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "pwm1")),
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1")), /* SCK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1")), /* SDA */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* CS */
+ SUNXI_FUNCTION(0x3, "uart3")), /* TX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* CLK */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RX */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* DOUT */
+ SUNXI_FUNCTION(0x3, "uart3")), /* RTS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "spi0"), /* DIN */
+ SUNXI_FUNCTION(0x3, "uart3")), /* CTS */
+};
+
+static const struct sunxi_pinctrl_desc sun8i_a23_pinctrl_data = {
+ .pins = sun8i_a23_pins,
+ .npins = ARRAY_SIZE(sun8i_a23_pins),
+ .irq_banks = 3,
+};
+
+static int sun8i_a23_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_init(pdev,
+ &sun8i_a23_pinctrl_data);
+}
+
+static struct of_device_id sun8i_a23_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-a23-pinctrl", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match);
+
+static struct platform_driver sun8i_a23_pinctrl_driver = {
+ .probe = sun8i_a23_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-a23-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = sun8i_a23_pinctrl_match,
+ },
+};
+module_platform_driver(sun8i_a23_pinctrl_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
+MODULE_DESCRIPTION("Allwinner A23 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index f1ca75e6d7b1..3df66e366c87 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -31,6 +31,9 @@
#include "../core.h"
#include "pinctrl-sunxi.h"
+static struct irq_chip sunxi_pinctrl_edge_irq_chip;
+static struct irq_chip sunxi_pinctrl_level_irq_chip;
+
static struct sunxi_pinctrl_group *
sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
{
@@ -211,6 +214,10 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
configlen++;
pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
+ if (!pinconfig) {
+ kfree(*map);
+ return -ENOMEM;
+ }
if (!of_property_read_u32(node, "allwinner,drive", &val)) {
u16 strength = (val + 1) * 10;
@@ -504,7 +511,7 @@ static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
base = PINS_PER_BANK * gpiospec->args[0];
pin = base + gpiospec->args[1];
- if (pin > (gc->base + gc->ngpio))
+ if (pin > gc->ngpio)
return -EINVAL;
if (flags)
@@ -517,25 +524,61 @@ static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
struct sunxi_desc_function *desc;
+ unsigned pinnum = pctl->desc->pin_base + offset;
+ unsigned irqnum;
if (offset >= chip->ngpio)
return -ENXIO;
- desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
+ desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq");
if (!desc)
return -EINVAL;
+ irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
+
dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
- chip->label, offset + chip->base, desc->irqnum);
+ chip->label, offset + chip->base, irqnum);
- return irq_find_mapping(pctl->domain, desc->irqnum);
+ return irq_find_mapping(pctl->domain, irqnum);
}
+static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
+{
+ struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+ struct sunxi_desc_function *func;
+ int ret;
+
+ func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
+ pctl->irq_array[d->hwirq], "irq");
+ if (!func)
+ return -EINVAL;
+
+ ret = gpio_lock_as_irq(pctl->chip,
+ pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+ if (ret) {
+ dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
+ irqd_to_hwirq(d));
+ return ret;
+ }
+
+ /* Change muxing to INT mode */
+ sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
-static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
- unsigned int type)
+ return 0;
+}
+
+static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
+{
+ struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+
+ gpio_unlock_as_irq(pctl->chip,
+ pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
+}
+
+static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+ struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
u32 reg = sunxi_irq_cfg_reg(d->hwirq);
u8 index = sunxi_irq_cfg_offset(d->hwirq);
unsigned long flags;
@@ -562,6 +605,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return -EINVAL;
}
+ if (type & IRQ_TYPE_LEVEL_MASK) {
+ d->chip = &sunxi_pinctrl_level_irq_chip;
+ desc->handle_irq = handle_fasteoi_irq;
+ } else {
+ d->chip = &sunxi_pinctrl_edge_irq_chip;
+ desc->handle_irq = handle_edge_irq;
+ }
+
spin_lock_irqsave(&pctl->lock, flags);
regval = readl(pctl->membase + reg);
@@ -573,26 +624,14 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
return 0;
}
-static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
+static void sunxi_pinctrl_irq_ack(struct irq_data *d)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
- u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
u32 status_reg = sunxi_irq_status_reg(d->hwirq);
u8 status_idx = sunxi_irq_status_offset(d->hwirq);
- unsigned long flags;
- u32 val;
-
- spin_lock_irqsave(&pctl->lock, flags);
-
- /* Mask the IRQ */
- val = readl(pctl->membase + ctrl_reg);
- writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
/* Clear the IRQ */
writel(1 << status_idx, pctl->membase + status_reg);
-
- spin_unlock_irqrestore(&pctl->lock, flags);
}
static void sunxi_pinctrl_irq_mask(struct irq_data *d)
@@ -615,19 +654,11 @@ static void sunxi_pinctrl_irq_mask(struct irq_data *d)
static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
- struct sunxi_desc_function *func;
u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
unsigned long flags;
u32 val;
- func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
- pctl->irq_array[d->hwirq],
- "irq");
-
- /* Change muxing to INT mode */
- sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
-
spin_lock_irqsave(&pctl->lock, flags);
/* Unmask the IRQ */
@@ -637,28 +668,60 @@ static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
spin_unlock_irqrestore(&pctl->lock, flags);
}
-static struct irq_chip sunxi_pinctrl_irq_chip = {
+static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
+{
+ sunxi_pinctrl_irq_ack(d);
+ sunxi_pinctrl_irq_unmask(d);
+}
+
+static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
+ .irq_ack = sunxi_pinctrl_irq_ack,
.irq_mask = sunxi_pinctrl_irq_mask,
- .irq_mask_ack = sunxi_pinctrl_irq_mask_ack,
.irq_unmask = sunxi_pinctrl_irq_unmask,
+ .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+ .irq_release_resources = sunxi_pinctrl_irq_release_resources,
.irq_set_type = sunxi_pinctrl_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
+};
+
+static struct irq_chip sunxi_pinctrl_level_irq_chip = {
+ .irq_eoi = sunxi_pinctrl_irq_ack,
+ .irq_mask = sunxi_pinctrl_irq_mask,
+ .irq_unmask = sunxi_pinctrl_irq_unmask,
+ /* Define irq_enable / disable to avoid spurious irqs for drivers
+ * using these to suppress irqs while they clear the irq source */
+ .irq_enable = sunxi_pinctrl_irq_ack_unmask,
+ .irq_disable = sunxi_pinctrl_irq_mask,
+ .irq_request_resources = sunxi_pinctrl_irq_request_resources,
+ .irq_release_resources = sunxi_pinctrl_irq_release_resources,
+ .irq_set_type = sunxi_pinctrl_irq_set_type,
+ .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_EOI_THREADED |
+ IRQCHIP_EOI_IF_HANDLED,
};
static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
- const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
+ unsigned long bank, reg, val;
+
+ for (bank = 0; bank < pctl->desc->irq_banks; bank++)
+ if (irq == pctl->irq[bank])
+ break;
+
+ if (bank == pctl->desc->irq_banks)
+ return;
- /* Clear all interrupts */
- writel(reg, pctl->membase + IRQ_STATUS_REG);
+ reg = sunxi_irq_status_reg_from_bank(bank);
+ val = readl(pctl->membase + reg);
- if (reg) {
+ if (val) {
int irqoffset;
chained_irq_enter(chip, desc);
- for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
- int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
+ for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
+ int pin_irq = irq_find_mapping(pctl->domain,
+ bank * IRQ_PER_BANK + irqoffset);
generic_handle_irq(pin_irq);
}
chained_irq_exit(chip, desc);
@@ -726,8 +789,11 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev)
while (func->name) {
/* Create interrupt mapping while we're at it */
- if (!strcmp(func->name, "irq"))
- pctl->irq_array[func->irqnum] = pin->pin.number;
+ if (!strcmp(func->name, "irq")) {
+ int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
+ pctl->irq_array[irqnum] = pin->pin.number;
+ }
+
sunxi_pinctrl_add_function(pctl, func->name);
func++;
}
@@ -797,6 +863,13 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
pctl->dev = &pdev->dev;
pctl->desc = desc;
+ pctl->irq_array = devm_kcalloc(&pdev->dev,
+ IRQ_PER_BANK * pctl->desc->irq_banks,
+ sizeof(*pctl->irq_array),
+ GFP_KERNEL);
+ if (!pctl->irq_array)
+ return -ENOMEM;
+
ret = sunxi_pinctrl_build_state(pdev);
if (ret) {
dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -865,7 +938,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
- pin->pin.number,
+ pin->pin.number - pctl->desc->pin_base,
pin->pin.number, 1);
if (ret)
goto gpiochip_error;
@@ -881,30 +954,51 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
if (ret)
goto gpiochip_error;
- pctl->irq = irq_of_parse_and_map(node, 0);
+ pctl->irq = devm_kcalloc(&pdev->dev,
+ pctl->desc->irq_banks,
+ sizeof(*pctl->irq),
+ GFP_KERNEL);
if (!pctl->irq) {
- ret = -EINVAL;
+ ret = -ENOMEM;
goto clk_error;
}
- pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
- &irq_domain_simple_ops, NULL);
+ for (i = 0; i < pctl->desc->irq_banks; i++) {
+ pctl->irq[i] = platform_get_irq(pdev, i);
+ if (pctl->irq[i] < 0) {
+ ret = pctl->irq[i];
+ goto clk_error;
+ }
+ }
+
+ pctl->domain = irq_domain_add_linear(node,
+ pctl->desc->irq_banks * IRQ_PER_BANK,
+ &irq_domain_simple_ops,
+ NULL);
if (!pctl->domain) {
dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
ret = -ENOMEM;
goto clk_error;
}
- for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
+ for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
int irqno = irq_create_mapping(pctl->domain, i);
- irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
- handle_simple_irq);
+ irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
+ handle_edge_irq);
irq_set_chip_data(irqno, pctl);
};
- irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
- irq_set_handler_data(pctl->irq, pctl);
+ for (i = 0; i < pctl->desc->irq_banks; i++) {
+ /* Mask and clear all IRQs before registering a handler */
+ writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(i));
+ writel(0xffffffff,
+ pctl->membase + sunxi_irq_status_reg_from_bank(i));
+
+ irq_set_chained_handler(pctl->irq[i],
+ sunxi_pinctrl_irq_handler);
+ irq_set_handler_data(pctl->irq[i], pctl);
+ }
dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
@@ -913,8 +1007,7 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
clk_error:
clk_disable_unprepare(clk);
gpiochip_error:
- if (gpiochip_remove(pctl->chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(pctl->chip);
pinctrl_error:
pinctrl_unregister(pctl->pctl_dev);
return ret;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 8169ba598876..4245b96c7996 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -53,7 +53,7 @@
#define PULL_PINS_BITS 2
#define PULL_PINS_MASK 0x03
-#define SUNXI_IRQ_NUMBER 32
+#define IRQ_PER_BANK 32
#define IRQ_CFG_REG 0x200
#define IRQ_CFG_IRQ_PER_REG 8
@@ -68,6 +68,8 @@
#define IRQ_STATUS_IRQ_BITS 1
#define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1)
+#define IRQ_MEM_SIZE 0x20
+
#define IRQ_EDGE_RISING 0x00
#define IRQ_EDGE_FALLING 0x01
#define IRQ_LEVEL_HIGH 0x02
@@ -77,6 +79,7 @@
struct sunxi_desc_function {
const char *name;
u8 muxval;
+ u8 irqbank;
u8 irqnum;
};
@@ -89,6 +92,7 @@ struct sunxi_pinctrl_desc {
const struct sunxi_desc_pin *pins;
int npins;
unsigned pin_base;
+ unsigned irq_banks;
};
struct sunxi_pinctrl_function {
@@ -113,8 +117,8 @@ struct sunxi_pinctrl {
unsigned nfunctions;
struct sunxi_pinctrl_group *groups;
unsigned ngroups;
- int irq;
- int irq_array[SUNXI_IRQ_NUMBER];
+ int *irq;
+ unsigned *irq_array;
spinlock_t lock;
struct pinctrl_dev *pctl_dev;
};
@@ -139,6 +143,14 @@ struct sunxi_pinctrl {
.irqnum = _irq, \
}
+#define SUNXI_FUNCTION_IRQ_BANK(_val, _bank, _irq) \
+ { \
+ .name = "irq", \
+ .muxval = _val, \
+ .irqbank = _bank, \
+ .irqnum = _irq, \
+ }
+
/*
* The sunXi PIO registers are organized as is:
* 0x00 - 0x0c Muxing values.
@@ -218,8 +230,10 @@ static inline u32 sunxi_pull_offset(u16 pin)
static inline u32 sunxi_irq_cfg_reg(u16 irq)
{
- u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04;
- return reg + IRQ_CFG_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+ u8 reg = (irq % IRQ_PER_BANK) / IRQ_CFG_IRQ_PER_REG * 0x04;
+
+ return IRQ_CFG_REG + bank * IRQ_MEM_SIZE + reg;
}
static inline u32 sunxi_irq_cfg_offset(u16 irq)
@@ -228,10 +242,16 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq)
return irq_num * IRQ_CFG_IRQ_BITS;
}
+static inline u32 sunxi_irq_ctrl_reg_from_bank(u8 bank)
+{
+ return IRQ_CTRL_REG + bank * IRQ_MEM_SIZE;
+}
+
static inline u32 sunxi_irq_ctrl_reg(u16 irq)
{
- u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04;
- return reg + IRQ_CTRL_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+
+ return sunxi_irq_ctrl_reg_from_bank(bank);
}
static inline u32 sunxi_irq_ctrl_offset(u16 irq)
@@ -240,10 +260,16 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq)
return irq_num * IRQ_CTRL_IRQ_BITS;
}
+static inline u32 sunxi_irq_status_reg_from_bank(u8 bank)
+{
+ return IRQ_STATUS_REG + bank * IRQ_MEM_SIZE;
+}
+
static inline u32 sunxi_irq_status_reg(u16 irq)
{
- u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04;
- return reg + IRQ_STATUS_REG;
+ u8 bank = irq / IRQ_PER_BANK;
+
+ return sunxi_irq_status_reg_from_bank(bank);
}
static inline u32 sunxi_irq_status_offset(u16 irq)
diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c
index 2c61281bebd7..8cea355f9a81 100644
--- a/drivers/pinctrl/vt8500/pinctrl-wmt.c
+++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c
@@ -141,17 +141,6 @@ static int wmt_pmx_enable(struct pinctrl_dev *pctldev,
return wmt_set_pinmux(data, func_selector, pinnum);
}
-static void wmt_pmx_disable(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- unsigned group_selector)
-{
- struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
- u32 pinnum = data->pins[group_selector].number;
-
- /* disable by setting GPIO_IN */
- wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, pinnum);
-}
-
static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned offset)
@@ -180,7 +169,6 @@ static struct pinmux_ops wmt_pinmux_ops = {
.get_function_name = wmt_pmx_get_function_name,
.get_function_groups = wmt_pmx_get_function_groups,
.enable = wmt_pmx_enable,
- .disable = wmt_pmx_disable,
.gpio_disable_free = wmt_pmx_gpio_disable_free,
.gpio_set_direction = wmt_pmx_gpio_set_direction,
};
@@ -627,8 +615,7 @@ int wmt_pinctrl_probe(struct platform_device *pdev,
return 0;
fail_range:
- if (gpiochip_remove(&data->gpio_chip))
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&data->gpio_chip);
fail_gpio:
pinctrl_unregister(data->pctl_dev);
return err;
@@ -637,12 +624,8 @@ fail_gpio:
int wmt_pinctrl_remove(struct platform_device *pdev)
{
struct wmt_pinctrl_data *data = platform_get_drvdata(pdev);
- int err;
-
- err = gpiochip_remove(&data->gpio_chip);
- if (err)
- dev_err(&pdev->dev, "failed to remove gpio chip\n");
+ gpiochip_remove(&data->gpio_chip);
pinctrl_unregister(data->pctl_dev);
return 0;
diff --git a/drivers/platform/x86/samsung-q10.c b/drivers/platform/x86/samsung-q10.c
index 5413f62d2e61..28d12bda3ac1 100644
--- a/drivers/platform/x86/samsung-q10.c
+++ b/drivers/platform/x86/samsung-q10.c
@@ -46,13 +46,7 @@ static int samsungq10_bl_set_intensity(struct backlight_device *bd)
return 0;
}
-static int samsungq10_bl_get_intensity(struct backlight_device *bd)
-{
- return bd->props.brightness;
-}
-
static const struct backlight_ops samsungq10_bl_ops = {
- .get_brightness = samsungq10_bl_get_intensity,
.update_status = samsungq10_bl_set_intensity,
};
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index b81448b2c75d..d2b780aade89 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -67,8 +67,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
pnp_dbg(&dev->dev, "set resources\n");
- handle = ACPI_HANDLE(&dev->dev);
- if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+ acpi_dev = ACPI_COMPANION(&dev->dev);
+ if (!acpi_dev) {
dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
return -ENODEV;
}
@@ -76,6 +76,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
if (WARN_ON_ONCE(acpi_dev != dev->data))
dev->data = acpi_dev;
+ handle = acpi_dev->handle;
if (acpi_has_method(handle, METHOD_NAME__SRS)) {
struct acpi_buffer buffer;
@@ -93,8 +94,8 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
}
kfree(buffer.pointer);
}
- if (!ret && acpi_bus_power_manageable(handle))
- ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
+ if (!ret && acpi_device_power_manageable(acpi_dev))
+ ret = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);
return ret;
}
@@ -102,23 +103,22 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
struct acpi_device *acpi_dev;
- acpi_handle handle;
acpi_status status;
dev_dbg(&dev->dev, "disable resources\n");
- handle = ACPI_HANDLE(&dev->dev);
- if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+ acpi_dev = ACPI_COMPANION(&dev->dev);
+ if (!acpi_dev) {
dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
return 0;
}
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- if (acpi_bus_power_manageable(handle))
- acpi_bus_set_power(handle, ACPI_STATE_D3_COLD);
+ if (acpi_device_power_manageable(acpi_dev))
+ acpi_device_set_power(acpi_dev, ACPI_STATE_D3_COLD);
- /* continue even if acpi_bus_set_power() fails */
- status = acpi_evaluate_object(handle, "_DIS", NULL, NULL);
+ /* continue even if acpi_device_set_power() fails */
+ status = acpi_evaluate_object(acpi_dev->handle, "_DIS", NULL, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
return -ENODEV;
@@ -128,26 +128,22 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
#ifdef CONFIG_ACPI_SLEEP
static bool pnpacpi_can_wakeup(struct pnp_dev *dev)
{
- struct acpi_device *acpi_dev;
- acpi_handle handle;
+ struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
- handle = ACPI_HANDLE(&dev->dev);
- if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+ if (!acpi_dev) {
dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
return false;
}
- return acpi_bus_can_wakeup(handle);
+ return acpi_bus_can_wakeup(acpi_dev->handle);
}
static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
- struct acpi_device *acpi_dev;
- acpi_handle handle;
+ struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
int error = 0;
- handle = ACPI_HANDLE(&dev->dev);
- if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+ if (!acpi_dev) {
dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
return 0;
}
@@ -159,7 +155,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
return error;
}
- if (acpi_bus_power_manageable(handle)) {
+ if (acpi_device_power_manageable(acpi_dev)) {
int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL,
ACPI_STATE_D3_COLD);
if (power_state < 0)
@@ -167,12 +163,12 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
ACPI_STATE_D0 : ACPI_STATE_D3_COLD;
/*
- * acpi_bus_set_power() often fails (keyboard port can't be
+ * acpi_device_set_power() can fail (keyboard port can't be
* powered-down?), and in any case, our return value is ignored
* by pnp_bus_suspend(). Hence we don't revert the wakeup
* setting if the set_power fails.
*/
- error = acpi_bus_set_power(handle, power_state);
+ error = acpi_device_set_power(acpi_dev, power_state);
}
return error;
@@ -180,11 +176,10 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
static int pnpacpi_resume(struct pnp_dev *dev)
{
- struct acpi_device *acpi_dev;
- acpi_handle handle = ACPI_HANDLE(&dev->dev);
+ struct acpi_device *acpi_dev = ACPI_COMPANION(&dev->dev);
int error = 0;
- if (!handle || acpi_bus_get_device(handle, &acpi_dev)) {
+ if (!acpi_dev) {
dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__);
return -ENODEV;
}
@@ -192,8 +187,8 @@ static int pnpacpi_resume(struct pnp_dev *dev)
if (device_may_wakeup(&dev->dev))
acpi_pm_device_sleep_wake(&dev->dev, false);
- if (acpi_bus_power_manageable(handle))
- error = acpi_bus_set_power(handle, ACPI_STATE_D0);
+ if (acpi_device_power_manageable(acpi_dev))
+ error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);
return error;
}
@@ -295,9 +290,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
return error;
}
+ error = acpi_bind_one(&dev->dev, device);
+
num++;
- return 0;
+ return error;
}
static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
@@ -313,41 +310,6 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
return AE_OK;
}
-static int __init acpi_pnp_match(struct device *dev, void *_pnp)
-{
- struct acpi_device *acpi = to_acpi_device(dev);
- struct pnp_dev *pnp = _pnp;
-
- /* true means it matched */
- return !acpi->physical_node_count
- && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
-}
-
-static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev)
-{
- dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev),
- acpi_pnp_match);
- if (!dev)
- return NULL;
-
- put_device(dev);
- return to_acpi_device(dev);
-}
-
-/* complete initialization of a PNPACPI device includes having
- * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
- */
-static bool acpi_pnp_bus_match(struct device *dev)
-{
- return dev->bus == &pnp_bus_type;
-}
-
-static struct acpi_bus_type __initdata acpi_pnp_bus = {
- .name = "PNP",
- .match = acpi_pnp_bus_match,
- .find_companion = acpi_pnp_find_companion,
-};
-
int pnpacpi_disabled __initdata;
static int __init pnpacpi_init(void)
{
@@ -357,10 +319,8 @@ static int __init pnpacpi_init(void)
}
printk(KERN_INFO "pnp: PnP ACPI init\n");
pnp_register_protocol(&pnpacpi_protocol);
- register_acpi_bus_type(&acpi_pnp_bus);
acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num);
- unregister_acpi_bus_type(&acpi_pnp_bus);
pnp_platform_devices = 1;
return 0;
}
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index ba6975123071..73cfcdf28a36 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -137,6 +137,13 @@ config BATTERY_COLLIE
Say Y to enable support for the battery on the Sharp Zaurus
SL-5500 (collie) models.
+config BATTERY_IPAQ_MICRO
+ tristate "iPAQ Atmel Micro ASIC battery driver"
+ depends on MFD_IPAQ_MICRO
+ help
+ Choose this option if you want to monitor battery status on
+ Compaq/HP iPAQ h3100 and h3600.
+
config BATTERY_WM97XX
bool "WM97xx generic battery driver"
depends on TOUCHSCREEN_WM97XX=y
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index ee54a3e4c90a..dfa894273926 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
+obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 79a37f6d3307..e384844a1ae1 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -840,8 +840,7 @@ static int bq2415x_notifier_call(struct notifier_block *nb,
if (bq->automode < 1)
return NOTIFY_OK;
- sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
- bq2415x_set_mode(bq, bq->reported_mode);
+ schedule_delayed_work(&bq->work, 0);
return NOTIFY_OK;
}
@@ -892,6 +891,11 @@ static void bq2415x_timer_work(struct work_struct *work)
int error;
int boost;
+ if (bq->automode > 0 && (bq->reported_mode != bq->mode)) {
+ sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
+ bq2415x_set_mode(bq, bq->reported_mode);
+ }
+
if (!bq->autotimer)
return;
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index b309713b63bc..e10763e3a1d5 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -25,6 +25,7 @@
* http://www.ti.com/product/bq27425-g1
*/
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/param.h>
#include <linux/jiffies.h>
@@ -415,6 +416,9 @@ static void bq27x00_update(struct bq27x00_device_info *di)
bool is_bq27425 = di->chip == BQ27425;
cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500);
+ if ((cache.flags & 0xff) == 0xff)
+ /* read error */
+ cache.flags = -1;
if (cache.flags >= 0) {
if (!is_bq27500 && !is_bq27425
&& (cache.flags & BQ27000_FLAG_CI)) {
@@ -804,7 +808,7 @@ static int bq27x00_battery_probe(struct i2c_client *client,
goto batt_failed_1;
}
- di = kzalloc(sizeof(*di), GFP_KERNEL);
+ di = devm_kzalloc(&client->dev, sizeof(*di), GFP_KERNEL);
if (!di) {
dev_err(&client->dev, "failed to allocate device info data\n");
retval = -ENOMEM;
@@ -819,14 +823,12 @@ static int bq27x00_battery_probe(struct i2c_client *client,
retval = bq27x00_powersupply_init(di);
if (retval)
- goto batt_failed_3;
+ goto batt_failed_2;
i2c_set_clientdata(client, di);
return 0;
-batt_failed_3:
- kfree(di);
batt_failed_2:
kfree(name);
batt_failed_1:
@@ -849,8 +851,6 @@ static int bq27x00_battery_remove(struct i2c_client *client)
idr_remove(&battery_id, di->id);
mutex_unlock(&battery_mutex);
- kfree(di);
-
return 0;
}
@@ -933,7 +933,6 @@ static int bq27000_battery_probe(struct platform_device *pdev)
{
struct bq27x00_device_info *di;
struct bq27000_platform_data *pdata = pdev->dev.platform_data;
- int ret;
if (!pdata) {
dev_err(&pdev->dev, "no platform_data supplied\n");
@@ -945,7 +944,7 @@ static int bq27000_battery_probe(struct platform_device *pdev)
return -EINVAL;
}
- di = kzalloc(sizeof(*di), GFP_KERNEL);
+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
if (!di) {
dev_err(&pdev->dev, "failed to allocate device info data\n");
return -ENOMEM;
@@ -959,16 +958,7 @@ static int bq27000_battery_probe(struct platform_device *pdev)
di->bat.name = pdata->name ?: dev_name(&pdev->dev);
di->bus.read = &bq27000_read_platform;
- ret = bq27x00_powersupply_init(di);
- if (ret)
- goto err_free;
-
- return 0;
-
-err_free:
- kfree(di);
-
- return ret;
+ return bq27x00_powersupply_init(di);
}
static int bq27000_battery_remove(struct platform_device *pdev)
@@ -977,8 +967,6 @@ static int bq27000_battery_remove(struct platform_device *pdev)
bq27x00_powersupply_unregister(di);
- kfree(di);
-
return 0;
}
diff --git a/drivers/power/ipaq_micro_battery.c b/drivers/power/ipaq_micro_battery.c
new file mode 100644
index 000000000000..9d694605cdb7
--- /dev/null
+++ b/drivers/power/ipaq_micro_battery.c
@@ -0,0 +1,290 @@
+/*
+ * 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.
+ *
+ * h3xxx atmel micro companion support, battery subdevice
+ * based on previous kernel 2.4 version
+ * Author : Alessandro Gardich <gremlin@gremlin.it>
+ * Author : Linus Walleij <linus.walleij@linaro.org>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ipaq-micro.h>
+#include <linux/power_supply.h>
+#include <linux/workqueue.h>
+
+#define BATT_PERIOD 100000 /* 100 seconds in milliseconds */
+
+#define MICRO_BATT_CHEM_ALKALINE 0x01
+#define MICRO_BATT_CHEM_NICD 0x02
+#define MICRO_BATT_CHEM_NIMH 0x03
+#define MICRO_BATT_CHEM_LION 0x04
+#define MICRO_BATT_CHEM_LIPOLY 0x05
+#define MICRO_BATT_CHEM_NOT_INSTALLED 0x06
+#define MICRO_BATT_CHEM_UNKNOWN 0xff
+
+#define MICRO_BATT_STATUS_HIGH 0x01
+#define MICRO_BATT_STATUS_LOW 0x02
+#define MICRO_BATT_STATUS_CRITICAL 0x04
+#define MICRO_BATT_STATUS_CHARGING 0x08
+#define MICRO_BATT_STATUS_CHARGEMAIN 0x10
+#define MICRO_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
+#define MICRO_BATT_STATUS_NOTINSTALLED 0x20 /* For expansion pack batteries */
+#define MICRO_BATT_STATUS_FULL 0x40 /* Battery fully charged */
+#define MICRO_BATT_STATUS_NOBATTERY 0x80
+#define MICRO_BATT_STATUS_UNKNOWN 0xff
+
+struct micro_battery {
+ struct ipaq_micro *micro;
+ struct workqueue_struct *wq;
+ struct delayed_work update;
+ u8 ac;
+ u8 chemistry;
+ unsigned int voltage;
+ u16 temperature;
+ u8 flag;
+};
+
+static void micro_battery_work(struct work_struct *work)
+{
+ struct micro_battery *mb = container_of(work,
+ struct micro_battery, update.work);
+ struct ipaq_micro_msg msg_battery = {
+ .id = MSG_BATTERY,
+ };
+ struct ipaq_micro_msg msg_sensor = {
+ .id = MSG_THERMAL_SENSOR,
+ };
+
+ /* First send battery message */
+ ipaq_micro_tx_msg_sync(mb->micro, &msg_battery);
+ if (msg_battery.rx_len < 4)
+ pr_info("ERROR");
+
+ /*
+ * Returned message format:
+ * byte 0: 0x00 = Not plugged in
+ * 0x01 = AC adapter plugged in
+ * byte 1: chemistry
+ * byte 2: voltage LSB
+ * byte 3: voltage MSB
+ * byte 4: flags
+ * byte 5-9: same for battery 2
+ */
+ mb->ac = msg_battery.rx_data[0];
+ mb->chemistry = msg_battery.rx_data[1];
+ mb->voltage = ((((unsigned short)msg_battery.rx_data[3] << 8) +
+ msg_battery.rx_data[2]) * 5000L) * 1000 / 1024;
+ mb->flag = msg_battery.rx_data[4];
+
+ if (msg_battery.rx_len == 9)
+ pr_debug("second battery ignored\n");
+
+ /* Then read the sensor */
+ ipaq_micro_tx_msg_sync(mb->micro, &msg_sensor);
+ mb->temperature = msg_sensor.rx_data[1] << 8 | msg_sensor.rx_data[0];
+
+ queue_delayed_work(mb->wq, &mb->update, msecs_to_jiffies(BATT_PERIOD));
+}
+
+static int get_capacity(struct power_supply *b)
+{
+ struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+
+ switch (mb->flag & 0x07) {
+ case MICRO_BATT_STATUS_HIGH:
+ return 100;
+ break;
+ case MICRO_BATT_STATUS_LOW:
+ return 50;
+ break;
+ case MICRO_BATT_STATUS_CRITICAL:
+ return 5;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int get_status(struct power_supply *b)
+{
+ struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+
+ if (mb->flag == MICRO_BATT_STATUS_UNKNOWN)
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+
+ if (mb->flag & MICRO_BATT_STATUS_FULL)
+ return POWER_SUPPLY_STATUS_FULL;
+
+ if ((mb->flag & MICRO_BATT_STATUS_CHARGING) ||
+ (mb->flag & MICRO_BATT_STATUS_CHARGEMAIN))
+ return POWER_SUPPLY_STATUS_CHARGING;
+
+ return POWER_SUPPLY_STATUS_DISCHARGING;
+}
+
+static int micro_batt_get_property(struct power_supply *b,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ switch (mb->chemistry) {
+ case MICRO_BATT_CHEM_NICD:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd;
+ break;
+ case MICRO_BATT_CHEM_NIMH:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
+ break;
+ case MICRO_BATT_CHEM_LION:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+ case MICRO_BATT_CHEM_LIPOLY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
+ break;
+ default:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+ break;
+ };
+ break;
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = get_status(b);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ val->intval = 4700000;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = get_capacity(b);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = mb->temperature;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = mb->voltage;
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static int micro_ac_get_property(struct power_supply *b,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct micro_battery *mb = dev_get_drvdata(b->dev->parent);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = mb->ac;
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static enum power_supply_property micro_batt_power_props[] = {
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static struct power_supply micro_batt_power = {
+ .name = "main-battery",
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = micro_batt_power_props,
+ .num_properties = ARRAY_SIZE(micro_batt_power_props),
+ .get_property = micro_batt_get_property,
+ .use_for_apm = 1,
+};
+
+static enum power_supply_property micro_ac_power_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static struct power_supply micro_ac_power = {
+ .name = "ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .properties = micro_ac_power_props,
+ .num_properties = ARRAY_SIZE(micro_ac_power_props),
+ .get_property = micro_ac_get_property,
+};
+
+static int micro_batt_probe(struct platform_device *pdev)
+{
+ struct micro_battery *mb;
+
+ mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL);
+ if (!mb)
+ return -ENOMEM;
+
+ mb->micro = dev_get_drvdata(pdev->dev.parent);
+ mb->wq = create_singlethread_workqueue("ipaq-battery-wq");
+ INIT_DELAYED_WORK(&mb->update, micro_battery_work);
+ platform_set_drvdata(pdev, mb);
+ queue_delayed_work(mb->wq, &mb->update, 1);
+ power_supply_register(&pdev->dev, &micro_batt_power);
+ power_supply_register(&pdev->dev, &micro_ac_power);
+
+ dev_info(&pdev->dev, "iPAQ micro battery driver\n");
+ return 0;
+}
+
+static int micro_batt_remove(struct platform_device *pdev)
+
+{
+ struct micro_battery *mb = platform_get_drvdata(pdev);
+
+ power_supply_unregister(&micro_ac_power);
+ power_supply_unregister(&micro_batt_power);
+ cancel_delayed_work_sync(&mb->update);
+
+ return 0;
+}
+
+static int micro_batt_suspend(struct device *dev)
+{
+ struct micro_battery *mb = dev_get_drvdata(dev);
+
+ cancel_delayed_work_sync(&mb->update);
+ return 0;
+}
+
+static int micro_batt_resume(struct device *dev)
+{
+ struct micro_battery *mb = dev_get_drvdata(dev);
+
+ queue_delayed_work(mb->wq, &mb->update, msecs_to_jiffies(BATT_PERIOD));
+ return 0;
+}
+
+static const struct dev_pm_ops micro_batt_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(micro_batt_suspend, micro_batt_resume)
+};
+
+static struct platform_driver micro_batt_device_driver = {
+ .driver = {
+ .name = "ipaq-micro-battery",
+ .pm = &micro_batt_dev_pm_ops,
+ },
+ .probe = micro_batt_probe,
+ .remove = micro_batt_remove,
+};
+module_platform_driver(micro_batt_device_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("driver for iPAQ Atmel micro battery");
+MODULE_ALIAS("platform:battery-ipaq-micro");
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 5a5a24e7d43c..078afd61490d 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -537,7 +537,8 @@ static void psy_unregister_cooler(struct power_supply *psy)
}
#endif
-int __power_supply_register(struct device *parent, struct power_supply *psy, bool ws)
+static int __power_supply_register(struct device *parent,
+ struct power_supply *psy, bool ws)
{
struct device *dev;
int rc;
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 44420d1e9094..750a20275664 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -167,6 +167,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(constant_charge_voltage_max),
POWER_SUPPLY_ATTR(charge_control_limit),
POWER_SUPPLY_ATTR(charge_control_limit_max),
+ POWER_SUPPLY_ATTR(input_current_limit),
POWER_SUPPLY_ATTR(energy_full_design),
POWER_SUPPLY_ATTR(energy_empty_design),
POWER_SUPPLY_ATTR(energy_full),
@@ -178,6 +179,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(capacity_alert_max),
POWER_SUPPLY_ATTR(capacity_level),
POWER_SUPPLY_ATTR(temp),
+ POWER_SUPPLY_ATTR(temp_max),
+ POWER_SUPPLY_ATTR(temp_min),
POWER_SUPPLY_ATTR(temp_alert_min),
POWER_SUPPLY_ATTR(temp_alert_max),
POWER_SUPPLY_ATTR(temp_ambient),
@@ -189,6 +192,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(time_to_full_avg),
POWER_SUPPLY_ATTR(type),
POWER_SUPPLY_ATTR(scope),
+ POWER_SUPPLY_ATTR(charge_term_current),
/* Properties of type `const char *' */
POWER_SUPPLY_ATTR(model_name),
POWER_SUPPLY_ATTR(manufacturer),
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index bdcf5173e377..ca41523bbebf 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -20,6 +20,17 @@ config POWER_RESET_AXXIA
Say Y if you have an Axxia family SoC.
+config POWER_RESET_BRCMSTB
+ bool "Broadcom STB reset driver" if COMPILE_TEST
+ depends on POWER_RESET && ARM
+ default ARCH_BRCMSTB
+ help
+ This driver provides restart support for ARM-based Broadcom STB
+ boards.
+
+ Say Y here if you have an ARM-based Broadcom STB board and you wish
+ to have restart support.
+
config POWER_RESET_GPIO
bool "GPIO power-off driver"
depends on OF_GPIO && POWER_RESET
@@ -28,6 +39,12 @@ config POWER_RESET_GPIO
If your board needs a GPIO high/low to power down, say Y and
create a binding in your devicetree.
+config POWER_RESET_HISI
+ bool "Hisilicon power-off driver"
+ depends on POWER_RESET && ARCH_HISI
+ help
+ Reboot support for Hisilicon boards.
+
config POWER_RESET_MSM
bool "Qualcomm MSM power-off driver"
depends on POWER_RESET && ARCH_QCOM
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index dde2e8bbac53..a42e70edd037 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -1,6 +1,8 @@
obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o
obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o
+obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
+obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
diff --git a/drivers/power/reset/brcmstb-reboot.c b/drivers/power/reset/brcmstb-reboot.c
new file mode 100644
index 000000000000..3f236924742a
--- /dev/null
+++ b/drivers/power/reset/brcmstb-reboot.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013 Broadcom 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+#include <linux/smp.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/system_misc.h>
+
+#define RESET_SOURCE_ENABLE_REG 1
+#define SW_MASTER_RESET_REG 2
+
+static struct regmap *regmap;
+static u32 rst_src_en;
+static u32 sw_mstr_rst;
+
+static void brcmstb_reboot(enum reboot_mode mode, const char *cmd)
+{
+ int rc;
+ u32 tmp;
+
+ rc = regmap_write(regmap, rst_src_en, 1);
+ if (rc) {
+ pr_err("failed to write rst_src_en (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_read(regmap, rst_src_en, &tmp);
+ if (rc) {
+ pr_err("failed to read rst_src_en (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_write(regmap, sw_mstr_rst, 1);
+ if (rc) {
+ pr_err("failed to write sw_mstr_rst (%d)\n", rc);
+ return;
+ }
+
+ rc = regmap_read(regmap, sw_mstr_rst, &tmp);
+ if (rc) {
+ pr_err("failed to read sw_mstr_rst (%d)\n", rc);
+ return;
+ }
+
+ while (1)
+ ;
+}
+
+static int brcmstb_reboot_probe(struct platform_device *pdev)
+{
+ int rc;
+ struct device_node *np = pdev->dev.of_node;
+
+ regmap = syscon_regmap_lookup_by_phandle(np, "syscon");
+ if (IS_ERR(regmap)) {
+ pr_err("failed to get syscon phandle\n");
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_index(np, "syscon", RESET_SOURCE_ENABLE_REG,
+ &rst_src_en);
+ if (rc) {
+ pr_err("can't get rst_src_en offset (%d)\n", rc);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32_index(np, "syscon", SW_MASTER_RESET_REG,
+ &sw_mstr_rst);
+ if (rc) {
+ pr_err("can't get sw_mstr_rst offset (%d)\n", rc);
+ return -EINVAL;
+ }
+
+ arm_pm_restart = brcmstb_reboot;
+
+ return 0;
+}
+
+static const struct of_device_id of_match[] = {
+ { .compatible = "brcm,brcmstb-reboot", },
+ {},
+};
+
+static struct platform_driver brcmstb_reboot_driver = {
+ .probe = brcmstb_reboot_probe,
+ .driver = {
+ .name = "brcmstb-reboot",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match,
+ },
+};
+
+static int __init brcmstb_reboot_init(void)
+{
+ return platform_driver_probe(&brcmstb_reboot_driver,
+ brcmstb_reboot_probe);
+}
+subsys_initcall(brcmstb_reboot_init);
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
index e290d48ddd99..ce849bc9b269 100644
--- a/drivers/power/reset/gpio-poweroff.c
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -15,31 +15,29 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/of_platform.h>
-#include <linux/of_gpio.h>
#include <linux/module.h>
/*
* Hold configuration here, cannot be more than one instance of the driver
* since pm_power_off itself is global.
*/
-static int gpio_num = -1;
-static int gpio_active_low;
+static struct gpio_desc *reset_gpio;
static void gpio_poweroff_do_poweroff(void)
{
- BUG_ON(!gpio_is_valid(gpio_num));
+ BUG_ON(!reset_gpio);
/* drive it active, also inactive->active edge */
- gpio_direction_output(gpio_num, !gpio_active_low);
+ gpiod_direction_output(reset_gpio, 1);
mdelay(100);
/* drive inactive, also active->inactive edge */
- gpio_set_value(gpio_num, gpio_active_low);
+ gpiod_set_value(reset_gpio, 0);
mdelay(100);
/* drive it active, also inactive->active edge */
- gpio_set_value(gpio_num, !gpio_active_low);
+ gpiod_set_value(reset_gpio, 1);
/* give it some time */
mdelay(3000);
@@ -49,54 +47,42 @@ static void gpio_poweroff_do_poweroff(void)
static int gpio_poweroff_probe(struct platform_device *pdev)
{
- enum of_gpio_flags flags;
bool input = false;
- int ret;
/* If a pm_power_off function has already been added, leave it alone */
if (pm_power_off != NULL) {
- pr_err("%s: pm_power_off function already registered",
+ dev_err(&pdev->dev,
+ "%s: pm_power_off function already registered",
__func__);
return -EBUSY;
}
- gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
- if (!gpio_is_valid(gpio_num))
- return gpio_num;
-
- gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
+ reset_gpio = devm_gpiod_get(&pdev->dev, NULL);
+ if (IS_ERR(reset_gpio))
+ return PTR_ERR(reset_gpio);
input = of_property_read_bool(pdev->dev.of_node, "input");
- ret = gpio_request(gpio_num, "poweroff-gpio");
- if (ret) {
- pr_err("%s: Could not get GPIO %d", __func__, gpio_num);
- return ret;
- }
if (input) {
- if (gpio_direction_input(gpio_num)) {
- pr_err("Could not set direction of GPIO %d to input",
- gpio_num);
- goto err;
+ if (gpiod_direction_input(reset_gpio)) {
+ dev_err(&pdev->dev,
+ "Could not set direction of reset GPIO to input\n");
+ return -ENODEV;
}
} else {
- if (gpio_direction_output(gpio_num, gpio_active_low)) {
- pr_err("Could not set direction of GPIO %d", gpio_num);
- goto err;
+ if (gpiod_direction_output(reset_gpio, 0)) {
+ dev_err(&pdev->dev,
+ "Could not set direction of reset GPIO\n");
+ return -ENODEV;
}
}
pm_power_off = &gpio_poweroff_do_poweroff;
return 0;
-
-err:
- gpio_free(gpio_num);
- return -ENODEV;
}
static int gpio_poweroff_remove(struct platform_device *pdev)
{
- gpio_free(gpio_num);
if (pm_power_off == &gpio_poweroff_do_poweroff)
pm_power_off = NULL;
diff --git a/drivers/power/reset/hisi-reboot.c b/drivers/power/reset/hisi-reboot.c
new file mode 100644
index 000000000000..0c91d0231d36
--- /dev/null
+++ b/drivers/power/reset/hisi-reboot.c
@@ -0,0 +1,67 @@
+/*
+ * Hisilicon SoC reset code
+ *
+ * Copyright (c) 2014 Hisilicon Ltd.
+ * Copyright (c) 2014 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system_misc.h>
+
+static void __iomem *base;
+static u32 reboot_offset;
+
+static void hisi_restart(enum reboot_mode mode, const char *cmd)
+{
+ writel_relaxed(0xdeadbeef, base + reboot_offset);
+
+ while (1)
+ cpu_do_idle();
+}
+
+static int hisi_reboot_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ WARN(1, "failed to map base address");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) {
+ pr_err("failed to find reboot-offset property\n");
+ return -EINVAL;
+ }
+
+ arm_pm_restart = hisi_restart;
+
+ return 0;
+}
+
+static struct of_device_id hisi_reboot_of_match[] = {
+ { .compatible = "hisilicon,sysctrl" },
+ {}
+};
+
+static struct platform_driver hisi_reboot_driver = {
+ .probe = hisi_reboot_probe,
+ .driver = {
+ .name = "hisi-reboot",
+ .of_match_table = hisi_reboot_of_match,
+ },
+};
+module_platform_driver(hisi_reboot_driver);
diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index 5758033e0c16..3e51f8d29bfe 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -62,5 +62,5 @@ module_platform_driver(restart_poweroff_driver);
MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch");
MODULE_DESCRIPTION("restart poweroff driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:poweroff-restart");
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c
index 1bc5857b8bd5..d5a2acfb8821 100644
--- a/drivers/power/rx51_battery.c
+++ b/drivers/power/rx51_battery.c
@@ -24,34 +24,27 @@
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/i2c/twl4030-madc.h>
-
-/* RX51 specific channels */
-#define TWL4030_MADC_BTEMP_RX51 TWL4030_MADC_ADCIN0
-#define TWL4030_MADC_BCI_RX51 TWL4030_MADC_ADCIN4
+#include <linux/iio/consumer.h>
+#include <linux/of.h>
struct rx51_device_info {
struct device *dev;
struct power_supply bat;
+ struct iio_channel *channel_temp;
+ struct iio_channel *channel_bsi;
+ struct iio_channel *channel_vbat;
};
/*
* Read ADCIN channel value, code copied from maemo kernel
*/
-static int rx51_battery_read_adc(int channel)
+static int rx51_battery_read_adc(struct iio_channel *channel)
{
- struct twl4030_madc_request req;
-
- req.channels = channel;
- req.do_avg = 1;
- req.method = TWL4030_MADC_SW1;
- req.func_cb = NULL;
- req.type = TWL4030_MADC_WAIT;
- req.raw = true;
-
- if (twl4030_madc_conversion(&req) <= 0)
- return -ENODATA;
-
- return req.rbuf[ffs(channel) - 1];
+ int val, err;
+ err = iio_read_channel_average_raw(channel, &val);
+ if (err < 0)
+ return err;
+ return val;
}
/*
@@ -60,10 +53,12 @@ static int rx51_battery_read_adc(int channel)
*/
static int rx51_battery_read_voltage(struct rx51_device_info *di)
{
- int voltage = rx51_battery_read_adc(TWL4030_MADC_VBAT);
+ int voltage = rx51_battery_read_adc(di->channel_vbat);
- if (voltage < 0)
+ if (voltage < 0) {
+ dev_err(di->dev, "Could not read ADC: %d\n", voltage);
return voltage;
+ }
return 1000 * (10000 * voltage / 1705);
}
@@ -112,7 +107,10 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di)
{
int min = 0;
int max = ARRAY_SIZE(rx51_temp_table2) - 1;
- int raw = rx51_battery_read_adc(TWL4030_MADC_BTEMP_RX51);
+ int raw = rx51_battery_read_adc(di->channel_temp);
+
+ if (raw < 0)
+ dev_err(di->dev, "Could not read ADC: %d\n", raw);
/* Zero and negative values are undefined */
if (raw <= 0)
@@ -146,10 +144,12 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di)
*/
static int rx51_battery_read_capacity(struct rx51_device_info *di)
{
- int capacity = rx51_battery_read_adc(TWL4030_MADC_BCI_RX51);
+ int capacity = rx51_battery_read_adc(di->channel_bsi);
- if (capacity < 0)
+ if (capacity < 0) {
+ dev_err(di->dev, "Could not read ADC: %d\n", capacity);
return capacity;
+ }
return 1280 * (1200 * capacity)/(1024 - capacity);
}
@@ -213,17 +213,46 @@ static int rx51_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, di);
+ di->dev = &pdev->dev;
di->bat.name = dev_name(&pdev->dev);
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat.properties = rx51_battery_props;
di->bat.num_properties = ARRAY_SIZE(rx51_battery_props);
di->bat.get_property = rx51_battery_get_property;
+ di->channel_temp = iio_channel_get(di->dev, "temp");
+ if (IS_ERR(di->channel_temp)) {
+ ret = PTR_ERR(di->channel_temp);
+ goto error;
+ }
+
+ di->channel_bsi = iio_channel_get(di->dev, "bsi");
+ if (IS_ERR(di->channel_bsi)) {
+ ret = PTR_ERR(di->channel_bsi);
+ goto error_channel_temp;
+ }
+
+ di->channel_vbat = iio_channel_get(di->dev, "vbat");
+ if (IS_ERR(di->channel_vbat)) {
+ ret = PTR_ERR(di->channel_vbat);
+ goto error_channel_bsi;
+ }
+
ret = power_supply_register(di->dev, &di->bat);
if (ret)
- return ret;
+ goto error_channel_vbat;
return 0;
+
+error_channel_vbat:
+ iio_channel_release(di->channel_vbat);
+error_channel_bsi:
+ iio_channel_release(di->channel_bsi);
+error_channel_temp:
+ iio_channel_release(di->channel_temp);
+error:
+
+ return ret;
}
static int rx51_battery_remove(struct platform_device *pdev)
@@ -232,15 +261,28 @@ static int rx51_battery_remove(struct platform_device *pdev)
power_supply_unregister(&di->bat);
+ iio_channel_release(di->channel_vbat);
+ iio_channel_release(di->channel_bsi);
+ iio_channel_release(di->channel_temp);
+
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id n900_battery_of_match[] = {
+ {.compatible = "nokia,n900-battery", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, n900_battery_of_match);
+#endif
+
static struct platform_driver rx51_battery_driver = {
.probe = rx51_battery_probe,
.remove = rx51_battery_remove,
.driver = {
.name = "rx51-battery",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(n900_battery_of_match),
},
};
module_platform_driver(rx51_battery_driver);
diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c
index 1685f63b9e5d..3e8ba97c8169 100644
--- a/drivers/power/tps65090-charger.c
+++ b/drivers/power/tps65090-charger.c
@@ -17,9 +17,11 @@
*/
#include <linux/delay.h>
#include <linux/err.h>
+#include <linux/freezer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -32,11 +34,15 @@
#define TPS65090_VACG BIT(1)
#define TPS65090_NOITERM BIT(5)
+#define POLL_INTERVAL (HZ * 2) /* Used when no irq */
+
struct tps65090_charger {
struct device *dev;
int ac_online;
int prev_ac_online;
int irq;
+ struct task_struct *poll_task;
+ bool passive_mode;
struct power_supply ac;
struct tps65090_platform_data *pdata;
};
@@ -49,6 +55,9 @@ static int tps65090_low_chrg_current(struct tps65090_charger *charger)
{
int ret;
+ if (charger->passive_mode)
+ return 0;
+
ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL5,
TPS65090_NOITERM);
if (ret < 0) {
@@ -64,6 +73,9 @@ static int tps65090_enable_charging(struct tps65090_charger *charger)
int ret;
uint8_t ctrl0 = 0;
+ if (charger->passive_mode)
+ return 0;
+
ret = tps65090_read(charger->dev->parent, TPS65090_REG_CG_CTRL0,
&ctrl0);
if (ret < 0) {
@@ -87,6 +99,9 @@ static int tps65090_config_charger(struct tps65090_charger *charger)
uint8_t intrmask = 0;
int ret;
+ if (charger->passive_mode)
+ return 0;
+
if (charger->pdata->enable_low_current_chrg) {
ret = tps65090_low_chrg_current(charger);
if (ret < 0) {
@@ -164,10 +179,14 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id)
}
/* Clear interrupts. */
- ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_STS, 0x00);
- if (ret < 0) {
- dev_err(charger->dev, "%s(): Error in writing reg 0x%x\n",
+ if (!charger->passive_mode) {
+ ret = tps65090_write(charger->dev->parent,
+ TPS65090_REG_INTR_STS, 0x00);
+ if (ret < 0) {
+ dev_err(charger->dev,
+ "%s(): Error in writing reg 0x%x\n",
__func__, TPS65090_REG_INTR_STS);
+ }
}
if (charger->prev_ac_online != charger->ac_online)
@@ -198,6 +217,18 @@ static struct tps65090_platform_data *
}
+static int tps65090_charger_poll_task(void *data)
+{
+ set_freezable();
+
+ while (!kthread_should_stop()) {
+ schedule_timeout_interruptible(POLL_INTERVAL);
+ try_to_freeze();
+ tps65090_charger_isr(-1, data);
+ }
+ return 0;
+}
+
static int tps65090_charger_probe(struct platform_device *pdev)
{
struct tps65090_charger *cdata;
@@ -244,22 +275,10 @@ static int tps65090_charger_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
- dev_warn(&pdev->dev, "Unable to get charger irq = %d\n", irq);
- ret = irq;
- goto fail_unregister_supply;
- }
-
+ if (irq < 0)
+ irq = -ENXIO;
cdata->irq = irq;
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
- tps65090_charger_isr, 0, "tps65090-charger", cdata);
- if (ret) {
- dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq,
- ret);
- goto fail_unregister_supply;
- }
-
ret = tps65090_config_charger(cdata);
if (ret < 0) {
dev_err(&pdev->dev, "charger config failed, err %d\n", ret);
@@ -285,6 +304,27 @@ static int tps65090_charger_probe(struct platform_device *pdev)
power_supply_changed(&cdata->ac);
}
+ if (irq != -ENXIO) {
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ tps65090_charger_isr, 0, "tps65090-charger", cdata);
+ if (ret) {
+ dev_err(cdata->dev,
+ "Unable to register irq %d err %d\n", irq,
+ ret);
+ goto fail_unregister_supply;
+ }
+ } else {
+ cdata->poll_task = kthread_run(tps65090_charger_poll_task,
+ cdata, "ktps65090charger");
+ cdata->passive_mode = true;
+ if (IS_ERR(cdata->poll_task)) {
+ ret = PTR_ERR(cdata->poll_task);
+ dev_err(cdata->dev,
+ "Unable to run kthread err %d\n", ret);
+ goto fail_unregister_supply;
+ }
+ }
+
return 0;
fail_unregister_supply:
@@ -297,6 +337,8 @@ static int tps65090_charger_remove(struct platform_device *pdev)
{
struct tps65090_charger *cdata = platform_get_drvdata(pdev);
+ if (cdata->irq == -ENXIO)
+ kthread_stop(cdata->poll_task);
power_supply_unregister(&cdata->ac);
return 0;
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index f14108844e1a..2598c588006e 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -28,10 +28,13 @@
#define TWL4030_BCIICHG 0x08
#define TWL4030_BCIVAC 0x0a
#define TWL4030_BCIVBUS 0x0c
+#define TWL4030_BCIMFSTS3 0x0F
#define TWL4030_BCIMFSTS4 0x10
#define TWL4030_BCICTL1 0x23
#define TWL4030_BB_CFG 0x12
+#define TWL4030_BCIMFSTS1 0x01
+
#define TWL4030_BCIAUTOWEN BIT(5)
#define TWL4030_CONFIG_DONE BIT(4)
#define TWL4030_BCIAUTOUSB BIT(1)
@@ -52,6 +55,9 @@
#define TWL4030_BBISEL_500uA 0x02
#define TWL4030_BBISEL_1000uA 0x03
+#define TWL4030_BATSTSPCHG BIT(2)
+#define TWL4030_BATSTSMCHG BIT(6)
+
/* BCI interrupts */
#define TWL4030_WOVF BIT(0) /* Watchdog overflow */
#define TWL4030_TMOVF BIT(1) /* Timer overflow */
@@ -145,6 +151,35 @@ static int twl4030bci_read_adc_val(u8 reg)
}
/*
+ * Check if Battery Pack was present
+ */
+static int twl4030_is_battery_present(struct twl4030_bci *bci)
+{
+ int ret;
+ u8 val = 0;
+
+ /* Battery presence in Main charge? */
+ ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, TWL4030_BCIMFSTS3);
+ if (ret)
+ return ret;
+ if (val & TWL4030_BATSTSMCHG)
+ return 0;
+
+ /*
+ * OK, It could be that bootloader did not enable main charger,
+ * pre-charge is h/w auto. So, Battery presence in Pre-charge?
+ */
+ ret = twl_i2c_read_u8(TWL4030_MODULE_PRECHARGE, &val,
+ TWL4030_BCIMFSTS1);
+ if (ret)
+ return ret;
+ if (val & TWL4030_BATSTSPCHG)
+ return 0;
+
+ return -ENODEV;
+}
+
+/*
* Check if VBUS power is present
*/
static int twl4030_bci_have_vbus(struct twl4030_bci *bci)
@@ -541,8 +576,14 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
bci->irq_chg = platform_get_irq(pdev, 0);
bci->irq_bci = platform_get_irq(pdev, 1);
- platform_set_drvdata(pdev, bci);
+ /* Only proceed further *IF* battery is physically present */
+ ret = twl4030_is_battery_present(bci);
+ if (ret) {
+ dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret);
+ goto fail_no_battery;
+ }
+ platform_set_drvdata(pdev, bci);
bci->ac.name = "twl4030_ac";
bci->ac.type = POWER_SUPPLY_TYPE_MAINS;
bci->ac.properties = twl4030_charger_props;
@@ -633,6 +674,7 @@ fail_chg_irq:
fail_register_usb:
power_supply_unregister(&bci->ac);
fail_register_ac:
+fail_no_battery:
kfree(bci);
return ret;
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 419056d7887e..f8a76090cbca 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -86,17 +86,12 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
return -EINVAL;
break;
case PTP_PF_PHYSYNC:
- pr_err("sorry, cannot reassign the calibration pin\n");
- return -EINVAL;
+ if (chan != 0)
+ return -EINVAL;
default:
return -EINVAL;
}
- if (pin2->func == PTP_PF_PHYSYNC) {
- pr_err("sorry, cannot reprogram the calibration pin\n");
- return -EINVAL;
- }
-
if (info->verify(info, pin, func, chan)) {
pr_err("driver cannot use function %u on pin %u\n", func, chan);
return -EOPNOTSUPP;
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index 9b60b1f3261c..44341dc5b148 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -287,6 +287,12 @@ struct tsi721_tx_desc *tsi721_desc_get(struct tsi721_bdma_chan *bdma_chan)
"desc %p not ACKed\n", tx_desc);
}
+ if (ret == NULL) {
+ dev_dbg(bdma_chan->dchan.device->dev,
+ "%s: unable to obtain tx descriptor\n", __func__);
+ goto err_out;
+ }
+
i = bdma_chan->wr_count_next % bdma_chan->bd_num;
if (i == bdma_chan->bd_num - 1) {
i = 0;
@@ -297,7 +303,7 @@ struct tsi721_tx_desc *tsi721_desc_get(struct tsi721_bdma_chan *bdma_chan)
tx_desc->txd.phys = bdma_chan->bd_phys +
i * sizeof(struct tsi721_dma_desc);
tx_desc->hw_desc = &((struct tsi721_dma_desc *)bdma_chan->bd_base)[i];
-
+err_out:
spin_unlock_bh(&bdma_chan->lock);
return ret;
diff --git a/drivers/ras/Kconfig b/drivers/ras/Kconfig
new file mode 100644
index 000000000000..f9da613052c2
--- /dev/null
+++ b/drivers/ras/Kconfig
@@ -0,0 +1,2 @@
+config RAS
+ bool
diff --git a/drivers/ras/Makefile b/drivers/ras/Makefile
new file mode 100644
index 000000000000..d7f73341ced3
--- /dev/null
+++ b/drivers/ras/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RAS) += ras.o debugfs.o
diff --git a/drivers/ras/debugfs.c b/drivers/ras/debugfs.c
new file mode 100644
index 000000000000..0322acf67ea5
--- /dev/null
+++ b/drivers/ras/debugfs.c
@@ -0,0 +1,56 @@
+#include <linux/debugfs.h>
+
+static struct dentry *ras_debugfs_dir;
+
+static atomic_t trace_count = ATOMIC_INIT(0);
+
+int ras_userspace_consumers(void)
+{
+ return atomic_read(&trace_count);
+}
+EXPORT_SYMBOL_GPL(ras_userspace_consumers);
+
+static int trace_show(struct seq_file *m, void *v)
+{
+ return atomic_read(&trace_count);
+}
+
+static int trace_open(struct inode *inode, struct file *file)
+{
+ atomic_inc(&trace_count);
+ return single_open(file, trace_show, NULL);
+}
+
+static int trace_release(struct inode *inode, struct file *file)
+{
+ atomic_dec(&trace_count);
+ return single_release(inode, file);
+}
+
+static const struct file_operations trace_fops = {
+ .open = trace_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = trace_release,
+};
+
+int __init ras_add_daemon_trace(void)
+{
+ struct dentry *fentry;
+
+ if (!ras_debugfs_dir)
+ return -ENOENT;
+
+ fentry = debugfs_create_file("daemon_active", S_IRUSR, ras_debugfs_dir,
+ NULL, &trace_fops);
+ if (!fentry)
+ return -ENODEV;
+
+ return 0;
+
+}
+
+void __init ras_debugfs_init(void)
+{
+ ras_debugfs_dir = debugfs_create_dir("ras", NULL);
+}
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
new file mode 100644
index 000000000000..b67dd362b7b6
--- /dev/null
+++ b/drivers/ras/ras.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Authors:
+ * Chen, Gong <gong.chen@linux.intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/ras.h>
+
+#define CREATE_TRACE_POINTS
+#define TRACE_INCLUDE_PATH ../../include/ras
+#include <ras/ras_event.h>
+
+static int __init ras_init(void)
+{
+ int rc = 0;
+
+ ras_debugfs_init();
+ rc = ras_add_daemon_trace();
+
+ return rc;
+}
+subsys_initcall(ras_init);
+
+#if defined(CONFIG_ACPI_EXTLOG) || defined(CONFIG_ACPI_EXTLOG_MODULE)
+EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
+#endif
+EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 7a721d67e6ac..4e6c8c611905 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -52,7 +52,6 @@
#define PM800_BUCK1_3 (0x3F)
#define PM800_BUCK2 (0x40)
#define PM800_BUCK3 (0x41)
-#define PM800_BUCK3 (0x41)
#define PM800_BUCK4 (0x42)
#define PM800_BUCK4_1 (0x43)
#define PM800_BUCK4_2 (0x44)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 789eb46090e3..2dc8289e5dba 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -198,6 +198,16 @@ config REGULATOR_DA9210
converter 12A DC-DC Buck controlled through an I2C
interface.
+config REGULATOR_DA9211
+ tristate "Dialog Semiconductor DA9211/DA9212 regulator"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say y here to support for the Dialog Semiconductor DA9211/DA9212.
+ The DA9211/DA9212 is a multi-phase synchronous step down
+ converter 12A DC-DC Buck controlled through an I2C
+ interface.
+
config REGULATOR_DBX500_PRCMU
bool
@@ -457,10 +467,10 @@ config REGULATOR_S2MPA01
via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
config REGULATOR_S2MPS11
- tristate "Samsung S2MPS11/S2MPS14 voltage regulator"
+ tristate "Samsung S2MPS11/S2MPS14/S2MPU02 voltage regulator"
depends on MFD_SEC_CORE
help
- This driver supports a Samsung S2MPS11/S2MPS14 voltage output
+ This driver supports a Samsung S2MPS11/S2MPS14/S2MPU02 voltage output
regulator via I2C bus. The chip is comprised of high efficient Buck
converters including Dual-Phase Buck converter, Buck-Boost converter,
various LDOs.
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d461110f4463..aa4a6aa7b558 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
obj-$(CONFIG_REGULATOR_DA9063) += da9063-regulator.o
obj-$(CONFIG_REGULATOR_DA9210) += da9210-regulator.o
+obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index c625468c7f2c..1fda14e12ea8 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -3037,28 +3037,12 @@ static int ab8500_regulator_register(struct platform_device *pdev,
return 0;
}
-static int
-ab8500_regulator_of_probe(struct platform_device *pdev,
- struct device_node *np)
-{
- struct of_regulator_match *match = abx500_regulator.match;
- int err, i;
-
- for (i = 0; i < abx500_regulator.info_size; i++) {
- err = ab8500_regulator_register(
- pdev, match[i].init_data, i, match[i].of_node);
- if (err)
- return err;
- }
-
- return 0;
-}
-
static int ab8500_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct device_node *np = pdev->dev.of_node;
- int err;
+ struct of_regulator_match *match;
+ int err, i;
if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n");
@@ -3075,24 +3059,20 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
"Error parsing regulator init data: %d\n", err);
return err;
}
- return ab8500_regulator_of_probe(pdev, np);
-}
-
-static int ab8500_regulator_remove(struct platform_device *pdev)
-{
- int err;
- /* remove regulator debug */
- err = ab8500_regulator_debug_exit(pdev);
- if (err)
- return err;
+ match = abx500_regulator.match;
+ for (i = 0; i < abx500_regulator.info_size; i++) {
+ err = ab8500_regulator_register(pdev, match[i].init_data, i,
+ match[i].of_node);
+ if (err)
+ return err;
+ }
return 0;
}
static struct platform_driver ab8500_regulator_driver = {
.probe = ab8500_regulator_probe,
- .remove = ab8500_regulator_remove,
.driver = {
.name = "ab8500-regulator",
.owner = THIS_MODULE,
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c
index b92d7dd01a18..afd06f92dfdf 100644
--- a/drivers/regulator/act8865-regulator.c
+++ b/drivers/regulator/act8865-regulator.c
@@ -1,6 +1,7 @@
/*
- * act8865-regulator.c - Voltage regulation for the active-semi ACT8865
- * http://www.active-semi.com/sheets/ACT8865_Datasheet.pdf
+ * act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs
+ *
+ * http://www.active-semi.com/products/power-management-units/act88xx/
*
* Copyright (C) 2013 Atmel Corporation
*
@@ -28,6 +29,40 @@
#include <linux/regmap.h>
/*
+ * ACT8846 Global Register Map.
+ */
+#define ACT8846_SYS0 0x00
+#define ACT8846_SYS1 0x01
+#define ACT8846_REG1_VSET 0x10
+#define ACT8846_REG1_CTRL 0x12
+#define ACT8846_REG2_VSET0 0x20
+#define ACT8846_REG2_VSET1 0x21
+#define ACT8846_REG2_CTRL 0x22
+#define ACT8846_REG3_VSET0 0x30
+#define ACT8846_REG3_VSET1 0x31
+#define ACT8846_REG3_CTRL 0x32
+#define ACT8846_REG4_VSET0 0x40
+#define ACT8846_REG4_VSET1 0x41
+#define ACT8846_REG4_CTRL 0x42
+#define ACT8846_REG5_VSET 0x50
+#define ACT8846_REG5_CTRL 0x51
+#define ACT8846_REG6_VSET 0x58
+#define ACT8846_REG6_CTRL 0x59
+#define ACT8846_REG7_VSET 0x60
+#define ACT8846_REG7_CTRL 0x61
+#define ACT8846_REG8_VSET 0x68
+#define ACT8846_REG8_CTRL 0x69
+#define ACT8846_REG9_VSET 0x70
+#define ACT8846_REG9_CTRL 0x71
+#define ACT8846_REG10_VSET 0x80
+#define ACT8846_REG10_CTRL 0x81
+#define ACT8846_REG11_VSET 0x90
+#define ACT8846_REG11_CTRL 0x91
+#define ACT8846_REG12_VSET 0xa0
+#define ACT8846_REG12_CTRL 0xa1
+#define ACT8846_REG13_CTRL 0xb1
+
+/*
* ACT8865 Global Register Map.
*/
#define ACT8865_SYS_MODE 0x00
@@ -70,7 +105,7 @@ static const struct regmap_config act8865_regmap_config = {
.val_bits = 8,
};
-static const struct regulator_linear_range act8865_volatge_ranges[] = {
+static const struct regulator_linear_range act8865_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
@@ -86,114 +121,70 @@ static struct regulator_ops act8865_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
-static const struct regulator_desc act8865_reg[] = {
- {
- .name = "DCDC_REG1",
- .id = ACT8865_ID_DCDC1,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_DCDC1_VSET1,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_DCDC1_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC_REG2",
- .id = ACT8865_ID_DCDC2,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_DCDC2_VSET1,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_DCDC2_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "DCDC_REG3",
- .id = ACT8865_ID_DCDC3,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_DCDC3_VSET1,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_DCDC3_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO_REG1",
- .id = ACT8865_ID_LDO1,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_LDO1_VSET,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_LDO1_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO_REG2",
- .id = ACT8865_ID_LDO2,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_LDO2_VSET,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_LDO2_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO_REG3",
- .id = ACT8865_ID_LDO3,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_LDO3_VSET,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_LDO3_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
- {
- .name = "LDO_REG4",
- .id = ACT8865_ID_LDO4,
- .ops = &act8865_ops,
- .type = REGULATOR_VOLTAGE,
- .n_voltages = ACT8865_VOLTAGE_NUM,
- .linear_ranges = act8865_volatge_ranges,
- .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
- .vsel_reg = ACT8865_LDO4_VSET,
- .vsel_mask = ACT8865_VSEL_MASK,
- .enable_reg = ACT8865_LDO4_CTRL,
- .enable_mask = ACT8865_ENA,
- .owner = THIS_MODULE,
- },
+#define ACT88xx_REG(_name, _family, _id, _vsel_reg) \
+ [_family##_ID_##_id] = { \
+ .name = _name, \
+ .id = _family##_ID_##_id, \
+ .type = REGULATOR_VOLTAGE, \
+ .ops = &act8865_ops, \
+ .n_voltages = ACT8865_VOLTAGE_NUM, \
+ .linear_ranges = act8865_voltage_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(act8865_voltage_ranges), \
+ .vsel_reg = _family##_##_id##_##_vsel_reg, \
+ .vsel_mask = ACT8865_VSEL_MASK, \
+ .enable_reg = _family##_##_id##_CTRL, \
+ .enable_mask = ACT8865_ENA, \
+ .owner = THIS_MODULE, \
+ }
+
+static const struct regulator_desc act8846_regulators[] = {
+ ACT88xx_REG("REG1", ACT8846, REG1, VSET),
+ ACT88xx_REG("REG2", ACT8846, REG2, VSET0),
+ ACT88xx_REG("REG3", ACT8846, REG3, VSET0),
+ ACT88xx_REG("REG4", ACT8846, REG4, VSET0),
+ ACT88xx_REG("REG5", ACT8846, REG5, VSET),
+ ACT88xx_REG("REG6", ACT8846, REG6, VSET),
+ ACT88xx_REG("REG7", ACT8846, REG7, VSET),
+ ACT88xx_REG("REG8", ACT8846, REG8, VSET),
+ ACT88xx_REG("REG9", ACT8846, REG9, VSET),
+ ACT88xx_REG("REG10", ACT8846, REG10, VSET),
+ ACT88xx_REG("REG11", ACT8846, REG11, VSET),
+ ACT88xx_REG("REG12", ACT8846, REG12, VSET),
+};
+
+static const struct regulator_desc act8865_regulators[] = {
+ ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1),
+ ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1),
+ ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1),
+ ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET),
+ ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET),
+ ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET),
+ ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET),
};
#ifdef CONFIG_OF
static const struct of_device_id act8865_dt_ids[] = {
- { .compatible = "active-semi,act8865" },
+ { .compatible = "active-semi,act8846", .data = (void *)ACT8846 },
+ { .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
{ }
};
MODULE_DEVICE_TABLE(of, act8865_dt_ids);
+static struct of_regulator_match act8846_matches[] = {
+ [ACT8846_ID_REG1] = { .name = "REG1" },
+ [ACT8846_ID_REG2] = { .name = "REG2" },
+ [ACT8846_ID_REG3] = { .name = "REG3" },
+ [ACT8846_ID_REG4] = { .name = "REG4" },
+ [ACT8846_ID_REG5] = { .name = "REG5" },
+ [ACT8846_ID_REG6] = { .name = "REG6" },
+ [ACT8846_ID_REG7] = { .name = "REG7" },
+ [ACT8846_ID_REG8] = { .name = "REG8" },
+ [ACT8846_ID_REG9] = { .name = "REG9" },
+ [ACT8846_ID_REG10] = { .name = "REG10" },
+ [ACT8846_ID_REG11] = { .name = "REG11" },
+ [ACT8846_ID_REG12] = { .name = "REG12" },
+};
+
static struct of_regulator_match act8865_matches[] = {
[ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"},
[ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"},
@@ -206,11 +197,13 @@ static struct of_regulator_match act8865_matches[] = {
static int act8865_pdata_from_dt(struct device *dev,
struct device_node **of_node,
- struct act8865_platform_data *pdata)
+ struct act8865_platform_data *pdata,
+ unsigned long type)
{
- int matched, i;
+ int matched, i, num_matches;
struct device_node *np;
struct act8865_regulator_data *regulator;
+ struct of_regulator_match *matches;
np = of_get_child_by_name(dev->of_node, "regulators");
if (!np) {
@@ -218,26 +211,39 @@ static int act8865_pdata_from_dt(struct device *dev,
return -EINVAL;
}
- matched = of_regulator_match(dev, np,
- act8865_matches, ARRAY_SIZE(act8865_matches));
+ switch (type) {
+ case ACT8846:
+ matches = act8846_matches;
+ num_matches = ARRAY_SIZE(act8846_matches);
+ break;
+ case ACT8865:
+ matches = act8865_matches;
+ num_matches = ARRAY_SIZE(act8865_matches);
+ break;
+ default:
+ dev_err(dev, "invalid device id %lu\n", type);
+ return -EINVAL;
+ }
+
+ matched = of_regulator_match(dev, np, matches, num_matches);
of_node_put(np);
if (matched <= 0)
return matched;
pdata->regulators = devm_kzalloc(dev,
- sizeof(struct act8865_regulator_data) *
- ARRAY_SIZE(act8865_matches), GFP_KERNEL);
+ sizeof(struct act8865_regulator_data) *
+ num_matches, GFP_KERNEL);
if (!pdata->regulators)
return -ENOMEM;
- pdata->num_regulators = matched;
+ pdata->num_regulators = num_matches;
regulator = pdata->regulators;
- for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) {
+ for (i = 0; i < num_matches; i++) {
regulator->id = i;
- regulator->name = act8865_matches[i].name;
- regulator->platform_data = act8865_matches[i].init_data;
- of_node[i] = act8865_matches[i].of_node;
+ regulator->name = matches[i].name;
+ regulator->platform_data = matches[i].init_data;
+ of_node[i] = matches[i].of_node;
regulator++;
}
@@ -246,42 +252,84 @@ static int act8865_pdata_from_dt(struct device *dev,
#else
static inline int act8865_pdata_from_dt(struct device *dev,
struct device_node **of_node,
- struct act8865_platform_data *pdata)
+ struct act8865_platform_data *pdata,
+ unsigned long type)
{
return 0;
}
#endif
+static struct regulator_init_data
+*act8865_get_init_data(int id, struct act8865_platform_data *pdata)
+{
+ int i;
+
+ if (!pdata)
+ return NULL;
+
+ for (i = 0; i < pdata->num_regulators; i++) {
+ if (pdata->regulators[i].id == id)
+ return pdata->regulators[i].platform_data;
+ }
+
+ return NULL;
+}
+
static int act8865_pmic_probe(struct i2c_client *client,
- const struct i2c_device_id *i2c_id)
+ const struct i2c_device_id *i2c_id)
{
- struct regulator_dev *rdev;
+ static const struct regulator_desc *regulators;
+ struct act8865_platform_data pdata_of, *pdata;
struct device *dev = &client->dev;
- struct act8865_platform_data *pdata = dev_get_platdata(dev);
- struct regulator_config config = { };
+ struct device_node **of_node;
+ int i, ret, num_regulators;
struct act8865 *act8865;
- struct device_node *of_node[ACT8865_REG_NUM];
- int i, id;
- int ret = -EINVAL;
- int error;
+ unsigned long type;
+
+ pdata = dev_get_platdata(dev);
if (dev->of_node && !pdata) {
const struct of_device_id *id;
- struct act8865_platform_data pdata_of;
id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
if (!id)
return -ENODEV;
- ret = act8865_pdata_from_dt(dev, of_node, &pdata_of);
+ type = (unsigned long) id->data;
+ } else {
+ type = i2c_id->driver_data;
+ }
+
+ switch (type) {
+ case ACT8846:
+ regulators = act8846_regulators;
+ num_regulators = ARRAY_SIZE(act8846_regulators);
+ break;
+ case ACT8865:
+ regulators = act8865_regulators;
+ num_regulators = ARRAY_SIZE(act8865_regulators);
+ break;
+ default:
+ dev_err(dev, "invalid device id %lu\n", type);
+ return -EINVAL;
+ }
+
+ of_node = devm_kzalloc(dev, sizeof(struct device_node *) *
+ num_regulators, GFP_KERNEL);
+ if (!of_node)
+ return -ENOMEM;
+
+ if (dev->of_node && !pdata) {
+ ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, type);
if (ret < 0)
return ret;
pdata = &pdata_of;
}
- if (pdata->num_regulators > ACT8865_REG_NUM) {
- dev_err(dev, "Too many regulators found!\n");
+ if (pdata->num_regulators > num_regulators) {
+ dev_err(dev, "too many regulators: %d\n",
+ pdata->num_regulators);
return -EINVAL;
}
@@ -291,39 +339,40 @@ static int act8865_pmic_probe(struct i2c_client *client,
act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config);
if (IS_ERR(act8865->regmap)) {
- error = PTR_ERR(act8865->regmap);
+ ret = PTR_ERR(act8865->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n",
- error);
- return error;
+ ret);
+ return ret;
}
/* Finally register devices */
- for (i = 0; i < ACT8865_REG_NUM; i++) {
-
- id = pdata->regulators[i].id;
+ for (i = 0; i < num_regulators; i++) {
+ const struct regulator_desc *desc = &regulators[i];
+ struct regulator_config config = { };
+ struct regulator_dev *rdev;
config.dev = dev;
- config.init_data = pdata->regulators[i].platform_data;
+ config.init_data = act8865_get_init_data(desc->id, pdata);
config.of_node = of_node[i];
config.driver_data = act8865;
config.regmap = act8865->regmap;
- rdev = devm_regulator_register(&client->dev, &act8865_reg[i],
- &config);
+ rdev = devm_regulator_register(&client->dev, desc, &config);
if (IS_ERR(rdev)) {
- dev_err(dev, "failed to register %s\n",
- act8865_reg[id].name);
+ dev_err(dev, "failed to register %s\n", desc->name);
return PTR_ERR(rdev);
}
}
i2c_set_clientdata(client, act8865);
+ devm_kfree(dev, of_node);
return 0;
}
static const struct i2c_device_id act8865_ids[] = {
- { "act8865", 0 },
+ { .name = "act8846", .driver_data = ACT8846 },
+ { .name = "act8865", .driver_data = ACT8865 },
{ },
};
MODULE_DEVICE_TABLE(i2c, act8865_ids);
@@ -339,6 +388,6 @@ static struct i2c_driver act8865_pmic_driver = {
module_i2c_driver(act8865_pmic_driver);
-MODULE_DESCRIPTION("active-semi act8865 voltage regulator driver");
+MODULE_DESCRIPTION("active-semi act88xx voltage regulator driver");
MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 04f262a836b2..4c9db589f6c1 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -143,8 +143,6 @@ static struct regulator_ops arizona_ldo1_ops = {
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_bypass = regulator_get_bypass_regmap,
- .set_bypass = regulator_set_bypass_regmap,
};
static const struct regulator_desc arizona_ldo1 = {
diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c
index ad9e0c9b7daf..b68f05f38537 100644
--- a/drivers/regulator/as3722-regulator.c
+++ b/drivers/regulator/as3722-regulator.c
@@ -219,7 +219,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
{
.regulator_id = AS3722_REGULATOR_ID_LDO3,
.name = "as3722-ldo3",
- .name = "vin-ldo3-4",
+ .sname = "vin-ldo3-4",
.vsel_reg = AS3722_LDO3_VOLTAGE_REG,
.vsel_mask = AS3722_LDO3_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
@@ -231,7 +231,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
{
.regulator_id = AS3722_REGULATOR_ID_LDO4,
.name = "as3722-ldo4",
- .name = "vin-ldo3-4",
+ .sname = "vin-ldo3-4",
.vsel_reg = AS3722_LDO4_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c
index 58ece59367ae..5d1fd6f3d10a 100644
--- a/drivers/regulator/bcm590xx-regulator.c
+++ b/drivers/regulator/bcm590xx-regulator.c
@@ -331,10 +331,8 @@ static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- if (!data) {
- dev_err(&pdev->dev, "failed to allocate regulator board data\n");
+ if (!data)
return NULL;
- }
np = of_node_get(np);
regulators = of_get_child_by_name(np, "regulators");
@@ -379,10 +377,8 @@ static int bcm590xx_probe(struct platform_device *pdev)
&bcm590xx_reg_matches);
pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
- if (!pmu) {
- dev_err(&pdev->dev, "Memory allocation failed for pmu\n");
+ if (!pmu)
return -ENOMEM;
- }
pmu->mfd = bcm590xx;
@@ -390,17 +386,13 @@ static int bcm590xx_probe(struct platform_device *pdev)
pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS *
sizeof(struct regulator_desc), GFP_KERNEL);
- if (!pmu->desc) {
- dev_err(&pdev->dev, "Memory alloc fails for desc\n");
+ if (!pmu->desc)
return -ENOMEM;
- }
pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS *
sizeof(struct bcm590xx_info *), GFP_KERNEL);
- if (!pmu->info) {
- dev_err(&pdev->dev, "Memory alloc fails for info\n");
+ if (!pmu->info)
return -ENOMEM;
- }
info = bcm590xx_regs;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 4c1f999041dd..a3c3785901f5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -24,6 +24,7 @@
#include <linux/suspend.h>
#include <linux/delay.h>
#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
@@ -77,7 +78,7 @@ struct regulator_map {
*/
struct regulator_enable_gpio {
struct list_head list;
- int gpio;
+ struct gpio_desc *gpiod;
u32 enable_count; /* a number of enabled shared GPIO */
u32 request_count; /* a number of requested shared GPIO */
unsigned int ena_gpio_invert:1;
@@ -846,7 +847,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
rdev->constraints->min_uV == rdev->constraints->max_uV) {
int current_uV = _regulator_get_voltage(rdev);
if (current_uV < 0) {
- rdev_err(rdev, "failed to get the current voltage\n");
+ rdev_err(rdev,
+ "failed to get the current voltage(%d)\n",
+ current_uV);
return current_uV;
}
if (current_uV < rdev->constraints->min_uV ||
@@ -856,8 +859,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
rdev->constraints->max_uV);
if (ret < 0) {
rdev_err(rdev,
- "failed to apply %duV constraint\n",
- rdev->constraints->min_uV);
+ "failed to apply %duV constraint(%d)\n",
+ rdev->constraints->min_uV, ret);
return ret;
}
}
@@ -1660,10 +1663,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
const struct regulator_config *config)
{
struct regulator_enable_gpio *pin;
+ struct gpio_desc *gpiod;
int ret;
+ gpiod = gpio_to_desc(config->ena_gpio);
+
list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
- if (pin->gpio == config->ena_gpio) {
+ if (pin->gpiod == gpiod) {
rdev_dbg(rdev, "GPIO %d is already used\n",
config->ena_gpio);
goto update_ena_gpio_to_rdev;
@@ -1682,7 +1688,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
return -ENOMEM;
}
- pin->gpio = config->ena_gpio;
+ pin->gpiod = gpiod;
pin->ena_gpio_invert = config->ena_gpio_invert;
list_add(&pin->list, &regulator_ena_gpio_list);
@@ -1701,10 +1707,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
/* Free the GPIO only in case of no use */
list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
- if (pin->gpio == rdev->ena_pin->gpio) {
+ if (pin->gpiod == rdev->ena_pin->gpiod) {
if (pin->request_count <= 1) {
pin->request_count = 0;
- gpio_free(pin->gpio);
+ gpiod_put(pin->gpiod);
list_del(&pin->list);
kfree(pin);
} else {
@@ -1732,8 +1738,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
if (enable) {
/* Enable GPIO at initial use */
if (pin->enable_count == 0)
- gpio_set_value_cansleep(pin->gpio,
- !pin->ena_gpio_invert);
+ gpiod_set_value_cansleep(pin->gpiod,
+ !pin->ena_gpio_invert);
pin->enable_count++;
} else {
@@ -1744,8 +1750,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
/* Disable GPIO if not used */
if (pin->enable_count <= 1) {
- gpio_set_value_cansleep(pin->gpio,
- pin->ena_gpio_invert);
+ gpiod_set_value_cansleep(pin->gpiod,
+ pin->ena_gpio_invert);
pin->enable_count = 0;
}
}
@@ -2180,7 +2186,13 @@ int regulator_count_voltages(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;
- return rdev->desc->n_voltages ? : -EINVAL;
+ if (rdev->desc->n_voltages)
+ return rdev->desc->n_voltages;
+
+ if (!rdev->supply)
+ return -EINVAL;
+
+ return regulator_count_voltages(rdev->supply);
}
EXPORT_SYMBOL_GPL(regulator_count_voltages);
@@ -2203,12 +2215,17 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)
return rdev->desc->fixed_uV;
- if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+ if (ops->list_voltage) {
+ if (selector >= rdev->desc->n_voltages)
+ return -EINVAL;
+ mutex_lock(&rdev->mutex);
+ ret = ops->list_voltage(rdev, selector);
+ mutex_unlock(&rdev->mutex);
+ } else if (rdev->supply) {
+ ret = regulator_list_voltage(rdev->supply, selector);
+ } else {
return -EINVAL;
-
- mutex_lock(&rdev->mutex);
- ret = ops->list_voltage(rdev, selector);
- mutex_unlock(&rdev->mutex);
+ }
if (ret > 0) {
if (ret < rdev->constraints->min_uV)
@@ -2222,6 +2239,77 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
EXPORT_SYMBOL_GPL(regulator_list_voltage);
/**
+ * regulator_get_regmap - get the regulator's register map
+ * @regulator: regulator source
+ *
+ * Returns the register map for the given regulator, or an ERR_PTR value
+ * if the regulator doesn't use regmap.
+ */
+struct regmap *regulator_get_regmap(struct regulator *regulator)
+{
+ struct regmap *map = regulator->rdev->regmap;
+
+ return map ? map : ERR_PTR(-EOPNOTSUPP);
+}
+
+/**
+ * regulator_get_hardware_vsel_register - get the HW voltage selector register
+ * @regulator: regulator source
+ * @vsel_reg: voltage selector register, output parameter
+ * @vsel_mask: mask for voltage selector bitfield, output parameter
+ *
+ * Returns the hardware register offset and bitmask used for setting the
+ * regulator voltage. This might be useful when configuring voltage-scaling
+ * hardware or firmware that can make I2C requests behind the kernel's back,
+ * for example.
+ *
+ * On success, the output parameters @vsel_reg and @vsel_mask are filled in
+ * and 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+ unsigned *vsel_reg,
+ unsigned *vsel_mask)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+
+ if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+ return -EOPNOTSUPP;
+
+ *vsel_reg = rdev->desc->vsel_reg;
+ *vsel_mask = rdev->desc->vsel_mask;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
+
+/**
+ * regulator_list_hardware_vsel - get the HW-specific register value for a selector
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ *
+ * Converts the selector to a hardware-specific voltage selector that can be
+ * directly written to the regulator registers. The address of the voltage
+ * register can be determined by calling @regulator_get_hardware_vsel_register.
+ *
+ * On error a negative errno is returned.
+ */
+int regulator_list_hardware_vsel(struct regulator *regulator,
+ unsigned selector)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+
+ if (selector >= rdev->desc->n_voltages)
+ return -EINVAL;
+ if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+ return -EOPNOTSUPP;
+
+ return selector;
+}
+EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
+
+/**
* regulator_get_linear_step - return the voltage step size between VSEL values
* @regulator: regulator source
*
@@ -2618,6 +2706,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
ret = rdev->desc->ops->list_voltage(rdev, 0);
} else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) {
ret = rdev->desc->fixed_uV;
+ } else if (rdev->supply) {
+ ret = regulator_get_voltage(rdev->supply);
} else {
return -EINVAL;
}
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
new file mode 100644
index 000000000000..1482adafa1ad
--- /dev/null
+++ b/drivers/regulator/da9211-regulator.c
@@ -0,0 +1,368 @@
+/*
+ * da9211-regulator.c - Regulator device driver for DA9211
+ * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/da9211.h>
+#include "da9211-regulator.h"
+
+#define DA9211_BUCK_MODE_SLEEP 1
+#define DA9211_BUCK_MODE_SYNC 2
+#define DA9211_BUCK_MODE_AUTO 3
+
+/* DA9211 REGULATOR IDs */
+#define DA9211_ID_BUCKA 0
+#define DA9211_ID_BUCKB 1
+
+struct da9211 {
+ struct device *dev;
+ struct regmap *regmap;
+ struct da9211_pdata *pdata;
+ struct regulator_dev *rdev[DA9211_MAX_REGULATORS];
+ int num_regulator;
+ int chip_irq;
+};
+
+static const struct regmap_range_cfg da9211_regmap_range[] = {
+ {
+ .selector_reg = DA9211_REG_PAGE_CON,
+ .selector_mask = DA9211_REG_PAGE_MASK,
+ .selector_shift = DA9211_REG_PAGE_SHIFT,
+ .window_start = 0,
+ .window_len = 256,
+ .range_min = 0,
+ .range_max = 2*256,
+ },
+};
+
+static const struct regmap_config da9211_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 2 * 256,
+ .ranges = da9211_regmap_range,
+ .num_ranges = ARRAY_SIZE(da9211_regmap_range),
+};
+
+/* Default limits measured in millivolts and milliamps */
+#define DA9211_MIN_MV 300
+#define DA9211_MAX_MV 1570
+#define DA9211_STEP_MV 10
+
+/* Current limits for buck (uA) indices corresponds with register values */
+static const int da9211_current_limits[] = {
+ 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000,
+ 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000
+};
+
+static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev)
+{
+ int id = rdev_get_id(rdev);
+ struct da9211 *chip = rdev_get_drvdata(rdev);
+ unsigned int data;
+ int ret, mode = 0;
+
+ ret = regmap_read(chip->regmap, DA9211_REG_BUCKA_CONF+id, &data);
+ if (ret < 0)
+ return ret;
+
+ switch (data & 0x03) {
+ case DA9211_BUCK_MODE_SYNC:
+ mode = REGULATOR_MODE_FAST;
+ break;
+ case DA9211_BUCK_MODE_AUTO:
+ mode = REGULATOR_MODE_NORMAL;
+ break;
+ case DA9211_BUCK_MODE_SLEEP:
+ mode = REGULATOR_MODE_STANDBY;
+ break;
+ }
+
+ return mode;
+}
+
+static int da9211_buck_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+{
+ int id = rdev_get_id(rdev);
+ struct da9211 *chip = rdev_get_drvdata(rdev);
+ int val = 0;
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = DA9211_BUCK_MODE_SYNC;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = DA9211_BUCK_MODE_AUTO;
+ break;
+ case REGULATOR_MODE_STANDBY:
+ val = DA9211_BUCK_MODE_SLEEP;
+ break;
+ }
+
+ return regmap_update_bits(chip->regmap, DA9211_REG_BUCKA_CONF+id,
+ 0x03, val);
+}
+
+static int da9211_set_current_limit(struct regulator_dev *rdev, int min,
+ int max)
+{
+ int id = rdev_get_id(rdev);
+ struct da9211 *chip = rdev_get_drvdata(rdev);
+ int i;
+
+ /* search for closest to maximum */
+ for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) {
+ if (min <= da9211_current_limits[i] &&
+ max >= da9211_current_limits[i]) {
+ return regmap_update_bits(chip->regmap,
+ DA9211_REG_BUCK_ILIM,
+ (0x0F << id*4), (i << id*4));
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int da9211_get_current_limit(struct regulator_dev *rdev)
+{
+ int id = rdev_get_id(rdev);
+ struct da9211 *chip = rdev_get_drvdata(rdev);
+ unsigned int data;
+ int ret;
+
+ ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data);
+ if (ret < 0)
+ return ret;
+
+ /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */
+ data = (data >> id*4) & 0x0F;
+ return da9211_current_limits[data];
+}
+
+static struct regulator_ops da9211_buck_ops = {
+ .get_mode = da9211_buck_get_mode,
+ .set_mode = da9211_buck_set_mode,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .set_current_limit = da9211_set_current_limit,
+ .get_current_limit = da9211_get_current_limit,
+};
+
+#define DA9211_BUCK(_id) \
+{\
+ .name = #_id,\
+ .ops = &da9211_buck_ops,\
+ .type = REGULATOR_VOLTAGE,\
+ .id = DA9211_ID_##_id,\
+ .n_voltages = (DA9211_MAX_MV - DA9211_MIN_MV) / DA9211_STEP_MV + 1,\
+ .min_uV = (DA9211_MIN_MV * 1000),\
+ .uV_step = (DA9211_STEP_MV * 1000),\
+ .enable_reg = DA9211_REG_BUCKA_CONT + DA9211_ID_##_id,\
+ .enable_mask = DA9211_BUCKA_EN,\
+ .vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\
+ .vsel_mask = DA9211_VBUCK_MASK,\
+ .owner = THIS_MODULE,\
+}
+
+static struct regulator_desc da9211_regulators[] = {
+ DA9211_BUCK(BUCKA),
+ DA9211_BUCK(BUCKB),
+};
+
+static irqreturn_t da9211_irq_handler(int irq, void *data)
+{
+ struct da9211 *chip = data;
+ int reg_val, err, ret = IRQ_NONE;
+
+ err = regmap_read(chip->regmap, DA9211_REG_EVENT_B, &reg_val);
+ if (err < 0)
+ goto error_i2c;
+
+ if (reg_val & DA9211_E_OV_CURR_A) {
+ regulator_notifier_call_chain(chip->rdev[0],
+ REGULATOR_EVENT_OVER_CURRENT,
+ rdev_get_drvdata(chip->rdev[0]));
+
+ err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
+ DA9211_E_OV_CURR_A);
+ if (err < 0)
+ goto error_i2c;
+
+ ret = IRQ_HANDLED;
+ }
+
+ if (reg_val & DA9211_E_OV_CURR_B) {
+ regulator_notifier_call_chain(chip->rdev[1],
+ REGULATOR_EVENT_OVER_CURRENT,
+ rdev_get_drvdata(chip->rdev[1]));
+
+ err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
+ DA9211_E_OV_CURR_B);
+ if (err < 0)
+ goto error_i2c;
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+
+error_i2c:
+ dev_err(chip->dev, "I2C error : %d\n", err);
+ return IRQ_NONE;
+}
+
+static int da9211_regulator_init(struct da9211 *chip)
+{
+ struct regulator_config config = { };
+ int i, ret;
+ unsigned int data;
+
+ ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data);
+ if (ret < 0) {
+ dev_err(chip->dev, "Failed to read CONTROL_E reg: %d\n", ret);
+ return ret;
+ }
+
+ data &= DA9211_SLAVE_SEL;
+ /* If configuration for 1/2 bucks is different between platform data
+ * and the register, driver should exit.
+ */
+ if ((chip->pdata->num_buck == 2 && data == 0x40)
+ || (chip->pdata->num_buck == 1 && data == 0x00)) {
+ if (data == 0)
+ chip->num_regulator = 1;
+ else
+ chip->num_regulator = 2;
+ } else {
+ dev_err(chip->dev, "Configuration is mismatched\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < chip->num_regulator; i++) {
+ if (chip->pdata)
+ config.init_data =
+ &(chip->pdata->init_data[i]);
+
+ config.dev = chip->dev;
+ config.driver_data = chip;
+ config.regmap = chip->regmap;
+
+ chip->rdev[i] = devm_regulator_register(chip->dev,
+ &da9211_regulators[i], &config);
+ if (IS_ERR(chip->rdev[i])) {
+ dev_err(chip->dev,
+ "Failed to register DA9211 regulator\n");
+ return PTR_ERR(chip->rdev[i]);
+ }
+
+ if (chip->chip_irq != 0) {
+ ret = regmap_update_bits(chip->regmap,
+ DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 1);
+ if (ret < 0) {
+ dev_err(chip->dev,
+ "Failed to update mask reg: %d\n", ret);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+/*
+ * I2C driver interface functions
+ */
+static int da9211_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct da9211 *chip;
+ int error, ret;
+
+ chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL);
+
+ chip->dev = &i2c->dev;
+ chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config);
+ if (IS_ERR(chip->regmap)) {
+ error = PTR_ERR(chip->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ error);
+ return error;
+ }
+
+ i2c_set_clientdata(i2c, chip);
+
+ chip->pdata = i2c->dev.platform_data;
+ if (!chip->pdata) {
+ dev_err(&i2c->dev, "No platform init data supplied\n");
+ return -ENODEV;
+ }
+
+ chip->chip_irq = i2c->irq;
+
+ if (chip->chip_irq != 0) {
+ ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL,
+ da9211_irq_handler,
+ IRQF_TRIGGER_LOW|IRQF_ONESHOT,
+ "da9211", chip);
+ if (ret != 0) {
+ dev_err(chip->dev, "Failed to request IRQ: %d\n",
+ chip->chip_irq);
+ return ret;
+ }
+ } else {
+ dev_warn(chip->dev, "No IRQ configured\n");
+ }
+
+ ret = da9211_regulator_init(chip);
+
+ if (ret < 0)
+ dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret);
+
+ return ret;
+}
+
+static const struct i2c_device_id da9211_i2c_id[] = {
+ {"da9211", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
+
+static struct i2c_driver da9211_regulator_driver = {
+ .driver = {
+ .name = "da9211",
+ .owner = THIS_MODULE,
+ },
+ .probe = da9211_i2c_probe,
+ .id_table = da9211_i2c_id,
+};
+
+module_i2c_driver(da9211_regulator_driver);
+
+MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
+MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h
new file mode 100644
index 000000000000..88b1769e8058
--- /dev/null
+++ b/drivers/regulator/da9211-regulator.h
@@ -0,0 +1,271 @@
+/*
+ * da9211-regulator.h - Regulator definitions for DA9211
+ * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ */
+
+#ifndef __DA9211_REGISTERS_H__
+#define __DA9211_REGISTERS_H__
+
+/* Page selection */
+#define DA9211_REG_PAGE_CON 0x00
+
+/* System Control and Event Registers */
+#define DA9211_REG_STATUS_A 0x50
+#define DA9211_REG_STATUS_B 0x51
+#define DA9211_REG_EVENT_A 0x52
+#define DA9211_REG_EVENT_B 0x53
+#define DA9211_REG_MASK_A 0x54
+#define DA9211_REG_MASK_B 0x55
+#define DA9211_REG_CONTROL_A 0x56
+
+/* GPIO Control Registers */
+#define DA9211_REG_GPIO_0_1 0x58
+#define DA9211_REG_GPIO_2_3 0x59
+#define DA9211_REG_GPIO_4 0x5A
+
+/* Regulator Registers */
+#define DA9211_REG_BUCKA_CONT 0x5D
+#define DA9211_REG_BUCKB_CONT 0x5E
+#define DA9211_REG_BUCK_ILIM 0xD0
+#define DA9211_REG_BUCKA_CONF 0xD1
+#define DA9211_REG_BUCKB_CONF 0xD2
+#define DA9211_REG_BUCK_CONF 0xD3
+#define DA9211_REG_VBACKA_MAX 0xD5
+#define DA9211_REG_VBACKB_MAX 0xD6
+#define DA9211_REG_VBUCKA_A 0xD7
+#define DA9211_REG_VBUCKA_B 0xD8
+#define DA9211_REG_VBUCKB_A 0xD9
+#define DA9211_REG_VBUCKB_B 0xDA
+
+/* I2C Interface Settings */
+#define DA9211_REG_INTERFACE 0x105
+
+/* BUCK Phase Selection*/
+#define DA9211_REG_CONFIG_E 0x147
+
+/*
+ * Registers bits
+ */
+/* DA9211_REG_PAGE_CON (addr=0x00) */
+#define DA9211_REG_PAGE_SHIFT 1
+#define DA9211_REG_PAGE_MASK 0x02
+/* On I2C registers 0x00 - 0xFF */
+#define DA9211_REG_PAGE0 0
+/* On I2C registers 0x100 - 0x1FF */
+#define DA9211_REG_PAGE2 2
+#define DA9211_PAGE_WRITE_MODE 0x00
+#define DA9211_REPEAT_WRITE_MODE 0x40
+#define DA9211_PAGE_REVERT 0x80
+
+/* DA9211_REG_STATUS_A (addr=0x50) */
+#define DA9211_GPI0 0x01
+#define DA9211_GPI1 0x02
+#define DA9211_GPI2 0x04
+#define DA9211_GPI3 0x08
+#define DA9211_GPI4 0x10
+
+/* DA9211_REG_EVENT_A (addr=0x52) */
+#define DA9211_E_GPI0 0x01
+#define DA9211_E_GPI1 0x02
+#define DA9211_E_GPI2 0x04
+#define DA9211_E_GPI3 0x08
+#define DA9211_E_GPI4 0x10
+#define DA9211_E_UVLO_IO 0x40
+
+/* DA9211_REG_EVENT_B (addr=0x53) */
+#define DA9211_E_PWRGOOD_A 0x01
+#define DA9211_E_PWRGOOD_B 0x02
+#define DA9211_E_TEMP_WARN 0x04
+#define DA9211_E_TEMP_CRIT 0x08
+#define DA9211_E_OV_CURR_A 0x10
+#define DA9211_E_OV_CURR_B 0x20
+
+/* DA9211_REG_MASK_A (addr=0x54) */
+#define DA9211_M_GPI0 0x01
+#define DA9211_M_GPI1 0x02
+#define DA9211_M_GPI2 0x04
+#define DA9211_M_GPI3 0x08
+#define DA9211_M_GPI4 0x10
+#define DA9211_M_UVLO_IO 0x40
+
+/* DA9211_REG_MASK_B (addr=0x55) */
+#define DA9211_M_PWRGOOD_A 0x01
+#define DA9211_M_PWRGOOD_B 0x02
+#define DA9211_M_TEMP_WARN 0x04
+#define DA9211_M_TEMP_CRIT 0x08
+#define DA9211_M_OV_CURR_A 0x10
+#define DA9211_M_OV_CURR_B 0x20
+
+/* DA9211_REG_CONTROL_A (addr=0x56) */
+#define DA9211_DEBOUNCING_SHIFT 0
+#define DA9211_DEBOUNCING_MASK 0x07
+#define DA9211_SLEW_RATE_SHIFT 3
+#define DA9211_SLEW_RATE_A_MASK 0x18
+#define DA9211_SLEW_RATE_B_SHIFT 5
+#define DA9211_SLEW_RATE_B_MASK 0x60
+#define DA9211_V_LOCK 0x80
+
+/* DA9211_REG_GPIO_0_1 (addr=0x58) */
+#define DA9211_GPIO0_PIN_SHIFT 0
+#define DA9211_GPIO0_PIN_MASK 0x03
+#define DA9211_GPIO0_PIN_GPI 0x00
+#define DA9211_GPIO0_PIN_GPO_OD 0x02
+#define DA9211_GPIO0_PIN_GPO 0x03
+#define DA9211_GPIO0_TYPE 0x04
+#define DA9211_GPIO0_TYPE_GPI 0x00
+#define DA9211_GPIO0_TYPE_GPO 0x04
+#define DA9211_GPIO0_MODE 0x08
+#define DA9211_GPIO1_PIN_SHIFT 4
+#define DA9211_GPIO1_PIN_MASK 0x30
+#define DA9211_GPIO1_PIN_GPI 0x00
+#define DA9211_GPIO1_PIN_VERROR 0x10
+#define DA9211_GPIO1_PIN_GPO_OD 0x20
+#define DA9211_GPIO1_PIN_GPO 0x30
+#define DA9211_GPIO1_TYPE_SHIFT 0x40
+#define DA9211_GPIO1_TYPE_GPI 0x00
+#define DA9211_GPIO1_TYPE_GPO 0x40
+#define DA9211_GPIO1_MODE 0x80
+
+/* DA9211_REG_GPIO_2_3 (addr=0x59) */
+#define DA9211_GPIO2_PIN_SHIFT 0
+#define DA9211_GPIO2_PIN_MASK 0x03
+#define DA9211_GPIO2_PIN_GPI 0x00
+#define DA9211_GPIO5_PIN_BUCK_CLK 0x10
+#define DA9211_GPIO2_PIN_GPO_OD 0x02
+#define DA9211_GPIO2_PIN_GPO 0x03
+#define DA9211_GPIO2_TYPE 0x04
+#define DA9211_GPIO2_TYPE_GPI 0x00
+#define DA9211_GPIO2_TYPE_GPO 0x04
+#define DA9211_GPIO2_MODE 0x08
+#define DA9211_GPIO3_PIN_SHIFT 4
+#define DA9211_GPIO3_PIN_MASK 0x30
+#define DA9211_GPIO3_PIN_GPI 0x00
+#define DA9211_GPIO3_PIN_IERROR 0x10
+#define DA9211_GPIO3_PIN_GPO_OD 0x20
+#define DA9211_GPIO3_PIN_GPO 0x30
+#define DA9211_GPIO3_TYPE_SHIFT 0x40
+#define DA9211_GPIO3_TYPE_GPI 0x00
+#define DA9211_GPIO3_TYPE_GPO 0x40
+#define DA9211_GPIO3_MODE 0x80
+
+/* DA9211_REG_GPIO_4 (addr=0x5A) */
+#define DA9211_GPIO4_PIN_SHIFT 0
+#define DA9211_GPIO4_PIN_MASK 0x03
+#define DA9211_GPIO4_PIN_GPI 0x00
+#define DA9211_GPIO4_PIN_GPO_OD 0x02
+#define DA9211_GPIO4_PIN_GPO 0x03
+#define DA9211_GPIO4_TYPE 0x04
+#define DA9211_GPIO4_TYPE_GPI 0x00
+#define DA9211_GPIO4_TYPE_GPO 0x04
+#define DA9211_GPIO4_MODE 0x08
+
+/* DA9211_REG_BUCKA_CONT (addr=0x5D) */
+#define DA9211_BUCKA_EN 0x01
+#define DA9211_BUCKA_GPI_SHIFT 1
+#define DA9211_BUCKA_GPI_MASK 0x06
+#define DA9211_BUCKA_GPI_OFF 0x00
+#define DA9211_BUCKA_GPI_GPIO0 0x02
+#define DA9211_BUCKA_GPI_GPIO1 0x04
+#define DA9211_BUCKA_GPI_GPIO3 0x06
+#define DA9211_BUCKA_PD_DIS 0x08
+#define DA9211_VBUCKA_SEL 0x10
+#define DA9211_VBUCKA_SEL_A 0x00
+#define DA9211_VBUCKA_SEL_B 0x10
+#define DA9211_VBUCKA_GPI_SHIFT 5
+#define DA9211_VBUCKA_GPI_MASK 0x60
+#define DA9211_VBUCKA_GPI_OFF 0x00
+#define DA9211_VBUCKA_GPI_GPIO1 0x20
+#define DA9211_VBUCKA_GPI_GPIO2 0x40
+#define DA9211_VBUCKA_GPI_GPIO4 0x60
+
+/* DA9211_REG_BUCKB_CONT (addr=0x5E) */
+#define DA9211_BUCKB_EN 0x01
+#define DA9211_BUCKB_GPI_SHIFT 1
+#define DA9211_BUCKB_GPI_MASK 0x06
+#define DA9211_BUCKB_GPI_OFF 0x00
+#define DA9211_BUCKB_GPI_GPIO0 0x02
+#define DA9211_BUCKB_GPI_GPIO1 0x04
+#define DA9211_BUCKB_GPI_GPIO3 0x06
+#define DA9211_BUCKB_PD_DIS 0x08
+#define DA9211_VBUCKB_SEL 0x10
+#define DA9211_VBUCKB_SEL_A 0x00
+#define DA9211_VBUCKB_SEL_B 0x10
+#define DA9211_VBUCKB_GPI_SHIFT 5
+#define DA9211_VBUCKB_GPI_MASK 0x60
+#define DA9211_VBUCKB_GPI_OFF 0x00
+#define DA9211_VBUCKB_GPI_GPIO1 0x20
+#define DA9211_VBUCKB_GPI_GPIO2 0x40
+#define DA9211_VBUCKB_GPI_GPIO4 0x60
+
+/* DA9211_REG_BUCK_ILIM (addr=0xD0) */
+#define DA9211_BUCKA_ILIM_SHIFT 0
+#define DA9211_BUCKA_ILIM_MASK 0x0F
+#define DA9211_BUCKB_ILIM_SHIFT 4
+#define DA9211_BUCKB_ILIM_MASK 0xF0
+
+/* DA9211_REG_BUCKA_CONF (addr=0xD1) */
+#define DA9211_BUCKA_MODE_SHIFT 0
+#define DA9211_BUCKA_MODE_MASK 0x03
+#define DA9211_BUCKA_MODE_MANUAL 0x00
+#define DA9211_BUCKA_MODE_SLEEP 0x01
+#define DA9211_BUCKA_MODE_SYNC 0x02
+#define DA9211_BUCKA_MODE_AUTO 0x03
+#define DA9211_BUCKA_UP_CTRL_SHIFT 2
+#define DA9211_BUCKA_UP_CTRL_MASK 0x1C
+#define DA9211_BUCKA_DOWN_CTRL_SHIFT 5
+#define DA9211_BUCKA_DOWN_CTRL_MASK 0xE0
+
+/* DA9211_REG_BUCKB_CONF (addr=0xD2) */
+#define DA9211_BUCKB_MODE_SHIFT 0
+#define DA9211_BUCKB_MODE_MASK 0x03
+#define DA9211_BUCKB_MODE_MANUAL 0x00
+#define DA9211_BUCKB_MODE_SLEEP 0x01
+#define DA9211_BUCKB_MODE_SYNC 0x02
+#define DA9211_BUCKB_MODE_AUTO 0x03
+#define DA9211_BUCKB_UP_CTRL_SHIFT 2
+#define DA9211_BUCKB_UP_CTRL_MASK 0x1C
+#define DA9211_BUCKB_DOWN_CTRL_SHIFT 5
+#define DA9211_BUCKB_DOWN_CTRL_MASK 0xE0
+
+/* DA9211_REG_BUCK_CONF (addr=0xD3) */
+#define DA9211_PHASE_SEL_A_SHIFT 0
+#define DA9211_PHASE_SEL_A_MASK 0x03
+#define DA9211_PHASE_SEL_B_SHIFT 2
+#define DA9211_PHASE_SEL_B_MASK 0x04
+#define DA9211_PH_SH_EN_A_SHIFT 3
+#define DA9211_PH_SH_EN_A_MASK 0x08
+#define DA9211_PH_SH_EN_B_SHIFT 4
+#define DA9211_PH_SH_EN_B_MASK 0x10
+
+/* DA9211_REG_VBUCKA_MAX (addr=0xD5) */
+#define DA9211_VBUCKA_BASE_SHIFT 0
+#define DA9211_VBUCKA_BASE_MASK 0x7F
+
+/* DA9211_REG_VBUCKB_MAX (addr=0xD6) */
+#define DA9211_VBUCKB_BASE_SHIFT 0
+#define DA9211_VBUCKB_BASE_MASK 0x7F
+
+/* DA9211_REG_VBUCKA/B_A/B (addr=0xD7/0xD8/0xD9/0xDA) */
+#define DA9211_VBUCK_SHIFT 0
+#define DA9211_VBUCK_MASK 0x7F
+#define DA9211_VBUCK_BIAS 0
+#define DA9211_BUCK_SL 0x80
+
+/* DA9211_REG_INTERFACE (addr=0x105) */
+#define DA9211_IF_BASE_ADDR_SHIFT 4
+#define DA9211_IF_BASE_ADDR_MASK 0xF0
+
+/* DA9211_REG_CONFIG_E (addr=0x147) */
+#define DA9211_SLAVE_SEL 0x40
+
+#endif /* __DA9211_REGISTERS_H__ */
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 2e022aabd951..021d64d856bb 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -845,7 +845,6 @@ static struct lp872x_platform_data
struct device_node *np = dev->of_node;
struct lp872x_platform_data *pdata;
struct of_regulator_match *match;
- struct regulator_init_data *d;
int num_matches;
int count;
int i;
@@ -892,14 +891,6 @@ static struct lp872x_platform_data
pdata->regulator_data[i].id =
(enum lp872x_regulator_id)match[i].driver_data;
pdata->regulator_data[i].init_data = match[i].init_data;
-
- /* Operation mode configuration for buck/buck1/buck2 */
- if (strncmp(match[i].name, "buck", 4))
- continue;
-
- d = pdata->regulator_data[i].init_data;
- d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE;
- d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
}
out:
return pdata;
diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c
index 785a25e9a437..4a415d4ee463 100644
--- a/drivers/regulator/lp8755.c
+++ b/drivers/regulator/lp8755.c
@@ -339,22 +339,18 @@ static int lp8755_regulator_init(struct lp8755_chip *pchip)
rconfig.init_data = pdata->buck_data[buck_num];
rconfig.of_node = pchip->dev->of_node;
pchip->rdev[buck_num] =
- regulator_register(&lp8755_regulators[buck_num], &rconfig);
+ devm_regulator_register(pchip->dev,
+ &lp8755_regulators[buck_num], &rconfig);
if (IS_ERR(pchip->rdev[buck_num])) {
ret = PTR_ERR(pchip->rdev[buck_num]);
pchip->rdev[buck_num] = NULL;
dev_err(pchip->dev, "regulator init failed: buck %d\n",
buck_num);
- goto err_buck;
+ return ret;
}
}
return 0;
-
-err_buck:
- for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
- regulator_unregister(pchip->rdev[icnt]);
- return ret;
}
static irqreturn_t lp8755_irq_handler(int irq, void *data)
@@ -490,23 +486,19 @@ static int lp8755_probe(struct i2c_client *client,
ret = lp8755_regulator_init(pchip);
if (ret < 0) {
dev_err(&client->dev, "fail to initialize regulators\n");
- goto err_regulator;
+ goto err;
}
pchip->irq = client->irq;
ret = lp8755_int_config(pchip);
if (ret < 0) {
dev_err(&client->dev, "fail to irq config\n");
- goto err_irq;
+ goto err;
}
return ret;
-err_irq:
- for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++)
- regulator_unregister(pchip->rdev[icnt]);
-
-err_regulator:
+err:
/* output disable */
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
lp8755_write(pchip, icnt, 0x00);
@@ -519,9 +511,6 @@ static int lp8755_remove(struct i2c_client *client)
int icnt;
struct lp8755_chip *pchip = i2c_get_clientdata(client);
- for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++)
- regulator_unregister(pchip->rdev[icnt]);
-
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
lp8755_write(pchip, icnt, 0x00);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index c8105182b8b8..c756955bfcc5 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -377,7 +377,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
-struct reg_default ltc3589_reg_defaults[] = {
+static struct reg_default ltc3589_reg_defaults[] = {
{ LTC3589_SCR1, 0x00 },
{ LTC3589_OVEN, 0x00 },
{ LTC3589_SCR2, 0x00 },
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index 653a58b49cdf..c67ff05fc1dd 100644
--- a/drivers/regulator/max77693.c
+++ b/drivers/regulator/max77693.c
@@ -31,6 +31,7 @@
#include <linux/mfd/max77693.h>
#include <linux/mfd/max77693-private.h>
#include <linux/regulator/of_regulator.h>
+#include <linux/regmap.h>
#define CHGIN_ILIM_STEP_20mA 20000
@@ -39,9 +40,9 @@
static int max77693_chg_is_enabled(struct regulator_dev *rdev)
{
int ret;
- u8 val;
+ unsigned int val;
- ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val);
+ ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret)
return ret;
@@ -57,12 +58,11 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
{
unsigned int chg_min_uA = rdev->constraints->min_uA;
unsigned int chg_max_uA = rdev->constraints->max_uA;
- u8 reg, sel;
+ unsigned int reg, sel;
unsigned int val;
int ret;
- ret = max77693_read_reg(rdev->regmap,
- MAX77693_CHG_REG_CHG_CNFG_09, &reg);
+ ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, &reg);
if (ret < 0)
return ret;
@@ -96,7 +96,7 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
/* the first four codes for charger current are all 60mA */
sel += 3;
- return max77693_write_reg(rdev->regmap,
+ return regmap_write(rdev->regmap,
MAX77693_CHG_REG_CHG_CNFG_09, sel);
}
/* end of CHARGER regulator ops */
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index c2792f0271ab..f7f9efcfedb7 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -229,7 +229,6 @@ static int max8952_pmic_probe(struct i2c_client *client,
config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
rdev = devm_regulator_register(&client->dev, &regulator, &config);
-
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&client->dev, "regulator init failed (%d)\n", ret);
@@ -241,21 +240,19 @@ static int max8952_pmic_probe(struct i2c_client *client,
if (gpio_is_valid(pdata->gpio_vid0) &&
gpio_is_valid(pdata->gpio_vid1)) {
- if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
- gpio_direction_output(pdata->gpio_vid0,
- (pdata->default_mode) & 0x1);
- else
+ unsigned long gpio_flags;
+
+ gpio_flags = max8952->vid0 ?
+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ if (devm_gpio_request_one(&client->dev, pdata->gpio_vid0,
+ gpio_flags, "MAX8952 VID0"))
err = 1;
- if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
- gpio_direction_output(pdata->gpio_vid1,
- (pdata->default_mode >> 1) & 0x1);
- else {
- if (!err)
- gpio_free(pdata->gpio_vid0);
+ gpio_flags = max8952->vid1 ?
+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ if (devm_gpio_request_one(&client->dev, pdata->gpio_vid1,
+ gpio_flags, "MAX8952 VID1"))
err = 2;
- }
-
} else
err = 3;
@@ -314,16 +311,6 @@ static int max8952_pmic_probe(struct i2c_client *client,
return 0;
}
-static int max8952_pmic_remove(struct i2c_client *client)
-{
- struct max8952_data *max8952 = i2c_get_clientdata(client);
- struct max8952_platform_data *pdata = max8952->pdata;
-
- gpio_free(pdata->gpio_vid0);
- gpio_free(pdata->gpio_vid1);
- return 0;
-}
-
static const struct i2c_device_id max8952_ids[] = {
{ "max8952", 0 },
{ },
@@ -332,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, max8952_ids);
static struct i2c_driver max8952_pmic_driver = {
.probe = max8952_pmic_probe,
- .remove = max8952_pmic_remove,
.driver = {
.name = "max8952",
.of_match_table = of_match_ptr(max8952_dt_match),
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index 05b971726ffa..afba024953e1 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -33,17 +33,12 @@ static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
int id = rdev_get_id(rdev);
- int ret;
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
- mc13xxx_lock(priv->mc13xxx);
- ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
- mc13xxx_regulators[id].enable_bit,
- mc13xxx_regulators[id].enable_bit);
- mc13xxx_unlock(priv->mc13xxx);
-
- return ret;
+ return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
+ mc13xxx_regulators[id].enable_bit,
+ mc13xxx_regulators[id].enable_bit);
}
static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
@@ -51,16 +46,11 @@ static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
int id = rdev_get_id(rdev);
- int ret;
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
- mc13xxx_lock(priv->mc13xxx);
- ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
- mc13xxx_regulators[id].enable_bit, 0);
- mc13xxx_unlock(priv->mc13xxx);
-
- return ret;
+ return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
+ mc13xxx_regulators[id].enable_bit, 0);
}
static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
@@ -70,10 +60,7 @@ static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
int ret, id = rdev_get_id(rdev);
unsigned int val;
- mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
- mc13xxx_unlock(priv->mc13xxx);
-
if (ret)
return ret;
@@ -86,15 +73,10 @@ static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
int id = rdev_get_id(rdev);
- int ret;
- mc13xxx_lock(priv->mc13xxx);
- ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
- mc13xxx_regulators[id].vsel_mask,
- selector << mc13xxx_regulators[id].vsel_shift);
- mc13xxx_unlock(priv->mc13xxx);
-
- return ret;
+ return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
+ mc13xxx_regulators[id].vsel_mask,
+ selector << mc13xxx_regulators[id].vsel_shift);
}
static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
@@ -106,11 +88,8 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
- mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_read(priv->mc13xxx,
mc13xxx_regulators[id].vsel_reg, &val);
- mc13xxx_unlock(priv->mc13xxx);
-
if (ret)
return ret;
diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h
index 06c8903f182a..2ab9bfd93b4e 100644
--- a/drivers/regulator/mc13xxx.h
+++ b/drivers/regulator/mc13xxx.h
@@ -21,7 +21,6 @@ struct mc13xxx_regulator {
int vsel_reg;
int vsel_shift;
int vsel_mask;
- int hi_bit;
};
struct mc13xxx_regulator_priv {
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 93b4ad842901..a7ce34d1b5f2 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -27,15 +27,6 @@
#include <linux/of_platform.h>
#include <linux/regulator/of_regulator.h>
-struct regs_info {
- char *name;
- char *sname;
- u8 vsel_addr;
- u8 ctrl_addr;
- u8 tstep_addr;
- int sleep_id;
-};
-
static const struct regulator_linear_range smps_low_ranges[] = {
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0),
@@ -50,7 +41,7 @@ static const struct regulator_linear_range smps_high_ranges[] = {
REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0),
};
-static const struct regs_info palmas_regs_info[] = {
+static struct palmas_regs_info palmas_generic_regs_info[] = {
{
.name = "SMPS12",
.sname = "smps1-in",
@@ -236,6 +227,153 @@ static const struct regs_info palmas_regs_info[] = {
},
};
+static struct palmas_regs_info tps65917_regs_info[] = {
+ {
+ .name = "SMPS1",
+ .sname = "smps1-in",
+ .vsel_addr = TPS65917_SMPS1_VOLTAGE,
+ .ctrl_addr = TPS65917_SMPS1_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS1,
+ },
+ {
+ .name = "SMPS2",
+ .sname = "smps2-in",
+ .vsel_addr = TPS65917_SMPS2_VOLTAGE,
+ .ctrl_addr = TPS65917_SMPS2_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS2,
+ },
+ {
+ .name = "SMPS3",
+ .sname = "smps3-in",
+ .vsel_addr = TPS65917_SMPS3_VOLTAGE,
+ .ctrl_addr = TPS65917_SMPS3_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS3,
+ },
+ {
+ .name = "SMPS4",
+ .sname = "smps4-in",
+ .vsel_addr = TPS65917_SMPS4_VOLTAGE,
+ .ctrl_addr = TPS65917_SMPS4_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS4,
+ },
+ {
+ .name = "SMPS5",
+ .sname = "smps5-in",
+ .vsel_addr = TPS65917_SMPS5_VOLTAGE,
+ .ctrl_addr = TPS65917_SMPS5_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS5,
+ },
+ {
+ .name = "LDO1",
+ .sname = "ldo1-in",
+ .vsel_addr = TPS65917_LDO1_VOLTAGE,
+ .ctrl_addr = TPS65917_LDO1_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO1,
+ },
+ {
+ .name = "LDO2",
+ .sname = "ldo2-in",
+ .vsel_addr = TPS65917_LDO2_VOLTAGE,
+ .ctrl_addr = TPS65917_LDO2_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO2,
+ },
+ {
+ .name = "LDO3",
+ .sname = "ldo3-in",
+ .vsel_addr = TPS65917_LDO3_VOLTAGE,
+ .ctrl_addr = TPS65917_LDO3_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO3,
+ },
+ {
+ .name = "LDO4",
+ .sname = "ldo4-in",
+ .vsel_addr = TPS65917_LDO4_VOLTAGE,
+ .ctrl_addr = TPS65917_LDO4_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO4,
+ },
+ {
+ .name = "LDO5",
+ .sname = "ldo5-in",
+ .vsel_addr = TPS65917_LDO5_VOLTAGE,
+ .ctrl_addr = TPS65917_LDO5_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO5,
+ },
+ {
+ .name = "REGEN1",
+ .ctrl_addr = TPS65917_REGEN1_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN1,
+ },
+ {
+ .name = "REGEN2",
+ .ctrl_addr = TPS65917_REGEN2_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN2,
+ },
+ {
+ .name = "REGEN3",
+ .ctrl_addr = TPS65917_REGEN3_CTRL,
+ .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN3,
+ },
+};
+
+#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \
+ [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \
+ .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \
+ .reg_offset = _offset, \
+ .bit_pos = _pos, \
+ }
+
+static struct palmas_sleep_requestor_info palma_sleep_req_info[] = {
+ EXTERNAL_REQUESTOR(REGEN1, 0, 0),
+ EXTERNAL_REQUESTOR(REGEN2, 0, 1),
+ EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
+ EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
+ EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
+ EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
+ EXTERNAL_REQUESTOR(REGEN3, 0, 6),
+ EXTERNAL_REQUESTOR(SMPS12, 1, 0),
+ EXTERNAL_REQUESTOR(SMPS3, 1, 1),
+ EXTERNAL_REQUESTOR(SMPS45, 1, 2),
+ EXTERNAL_REQUESTOR(SMPS6, 1, 3),
+ EXTERNAL_REQUESTOR(SMPS7, 1, 4),
+ EXTERNAL_REQUESTOR(SMPS8, 1, 5),
+ EXTERNAL_REQUESTOR(SMPS9, 1, 6),
+ EXTERNAL_REQUESTOR(SMPS10, 1, 7),
+ EXTERNAL_REQUESTOR(LDO1, 2, 0),
+ EXTERNAL_REQUESTOR(LDO2, 2, 1),
+ EXTERNAL_REQUESTOR(LDO3, 2, 2),
+ EXTERNAL_REQUESTOR(LDO4, 2, 3),
+ EXTERNAL_REQUESTOR(LDO5, 2, 4),
+ EXTERNAL_REQUESTOR(LDO6, 2, 5),
+ EXTERNAL_REQUESTOR(LDO7, 2, 6),
+ EXTERNAL_REQUESTOR(LDO8, 2, 7),
+ EXTERNAL_REQUESTOR(LDO9, 3, 0),
+ EXTERNAL_REQUESTOR(LDOLN, 3, 1),
+ EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
+};
+
+#define EXTERNAL_REQUESTOR_TPS65917(_id, _offset, _pos) \
+ [TPS65917_EXTERNAL_REQSTR_ID_##_id] = { \
+ .id = TPS65917_EXTERNAL_REQSTR_ID_##_id, \
+ .reg_offset = _offset, \
+ .bit_pos = _pos, \
+ }
+
+static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = {
+ EXTERNAL_REQUESTOR_TPS65917(REGEN1, 0, 0),
+ EXTERNAL_REQUESTOR_TPS65917(REGEN2, 0, 1),
+ EXTERNAL_REQUESTOR_TPS65917(REGEN3, 0, 6),
+ EXTERNAL_REQUESTOR_TPS65917(SMPS1, 1, 0),
+ EXTERNAL_REQUESTOR_TPS65917(SMPS2, 1, 1),
+ EXTERNAL_REQUESTOR_TPS65917(SMPS3, 1, 2),
+ EXTERNAL_REQUESTOR_TPS65917(SMPS4, 1, 3),
+ EXTERNAL_REQUESTOR_TPS65917(SMPS5, 1, 4),
+ EXTERNAL_REQUESTOR_TPS65917(LDO1, 2, 0),
+ EXTERNAL_REQUESTOR_TPS65917(LDO2, 2, 1),
+ EXTERNAL_REQUESTOR_TPS65917(LDO3, 2, 2),
+ EXTERNAL_REQUESTOR_TPS65917(LDO4, 2, 3),
+ EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4),
+};
+
static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
#define SMPS_CTRL_MODE_OFF 0x00
@@ -296,12 +434,15 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg,
static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
{
- struct palmas_pmic *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev);
+ struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+ struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
unsigned int reg;
bool rail_enable = true;
- palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
+ palmas_smps_read(pmic->palmas, rinfo->ctrl_addr, &reg);
+
reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
if (reg == SMPS_CTRL_MODE_OFF)
@@ -323,8 +464,7 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
if (rail_enable)
- palmas_smps_write(pmic->palmas,
- palmas_regs_info[id].ctrl_addr, reg);
+ palmas_smps_write(pmic->palmas, rinfo->ctrl_addr, reg);
/* Switch the enable value to ensure this is used for enable */
pmic->desc[id].enable_val = pmic->current_reg_mode[id];
@@ -355,10 +495,11 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
- struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
+ struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
+ struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
unsigned int reg = 0;
- unsigned int addr = palmas_regs_info[id].tstep_addr;
int ret;
/* SMPS3 and SMPS7 do not have tstep_addr setting */
@@ -377,7 +518,7 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
else
reg = 1;
- ret = palmas_smps_write(pmic->palmas, addr, reg);
+ ret = palmas_smps_write(pmic->palmas, rinfo->tstep_addr, reg);
if (ret < 0) {
dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret);
return ret;
@@ -424,13 +565,37 @@ static struct regulator_ops palmas_ops_smps10 = {
.get_bypass = regulator_get_bypass_regmap,
};
+static struct regulator_ops tps65917_ops_smps = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .set_mode = palmas_set_mode_smps,
+ .get_mode = palmas_get_mode_smps,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops tps65917_ops_ext_control_smps = {
+ .set_mode = palmas_set_mode_smps,
+ .get_mode = palmas_get_mode_smps,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+};
+
static int palmas_is_enabled_ldo(struct regulator_dev *dev)
{
- struct palmas_pmic *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev);
+ struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+ struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
unsigned int reg;
- palmas_ldo_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
+ palmas_ldo_read(pmic->palmas, rinfo->ctrl_addr, &reg);
reg &= PALMAS_LDO1_CTRL_STATUS;
@@ -463,14 +628,26 @@ static struct regulator_ops palmas_ops_extreg = {
static struct regulator_ops palmas_ops_ext_control_extreg = {
};
+static struct regulator_ops tps65917_ops_ldo = {
+ .is_enabled = palmas_is_enabled_ldo,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
static int palmas_regulator_config_external(struct palmas *palmas, int id,
struct palmas_reg_init *reg_init)
{
- int sleep_id = palmas_regs_info[id].sleep_id;
+ struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
int ret;
- ret = palmas_ext_control_req_config(palmas, sleep_id,
- reg_init->roof_floor, true);
+ ret = palmas_ext_control_req_config(palmas, rinfo->sleep_id,
+ reg_init->roof_floor, true);
if (ret < 0)
dev_err(palmas->dev,
"Ext control config for regulator %d failed %d\n",
@@ -488,10 +665,10 @@ static int palmas_smps_init(struct palmas *palmas, int id,
struct palmas_reg_init *reg_init)
{
unsigned int reg;
- unsigned int addr;
int ret;
-
- addr = palmas_regs_info[id].ctrl_addr;
+ struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
+ unsigned int addr = rinfo->ctrl_addr;
ret = palmas_smps_read(palmas, addr, &reg);
if (ret)
@@ -526,12 +703,11 @@ static int palmas_smps_init(struct palmas *palmas, int id,
if (ret)
return ret;
- if (palmas_regs_info[id].vsel_addr && reg_init->vsel) {
- addr = palmas_regs_info[id].vsel_addr;
+ if (rinfo->vsel_addr && reg_init->vsel) {
reg = reg_init->vsel;
- ret = palmas_smps_write(palmas, addr, reg);
+ ret = palmas_smps_write(palmas, rinfo->vsel_addr, reg);
if (ret)
return ret;
}
@@ -539,7 +715,6 @@ static int palmas_smps_init(struct palmas *palmas, int id,
if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) &&
(id != PALMAS_REG_SMPS10_OUT2)) {
/* Enable externally controlled regulator */
- addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_smps_read(palmas, addr, &reg);
if (ret < 0)
return ret;
@@ -561,8 +736,10 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
unsigned int reg;
unsigned int addr;
int ret;
+ struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
- addr = palmas_regs_info[id].ctrl_addr;
+ addr = rinfo->ctrl_addr;
ret = palmas_ldo_read(palmas, addr, &reg);
if (ret)
@@ -584,7 +761,6 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
if (reg_init->roof_floor) {
/* Enable externally controlled regulator */
- addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_update_bits(palmas, PALMAS_LDO_BASE,
addr, PALMAS_LDO1_CTRL_MODE_ACTIVE,
PALMAS_LDO1_CTRL_MODE_ACTIVE);
@@ -605,8 +781,10 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
unsigned int addr;
int ret;
unsigned int val = 0;
+ struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
- addr = palmas_regs_info[id].ctrl_addr;
+ addr = rinfo->ctrl_addr;
if (reg_init->mode_sleep)
val = PALMAS_REGEN1_CTRL_MODE_SLEEP;
@@ -621,7 +799,6 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
if (reg_init->roof_floor) {
/* Enable externally controlled regulator */
- addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE,
PALMAS_REGEN1_CTRL_MODE_ACTIVE);
@@ -641,8 +818,11 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
unsigned int reg;
unsigned int addr;
int ret;
+ struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+ struct palmas_regs_info *rinfo;
- addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr;
+ rinfo = &ddata->palmas_regs_info[PALMAS_REG_LDO8];
+ addr = rinfo->ctrl_addr;
ret = palmas_ldo_read(palmas, addr, &reg);
if (ret) {
@@ -661,7 +841,7 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
* output is defined by the LDO8_VOLTAGE.VSEL register divided by two,
* and can be set from 0.45 to 1.65 V.
*/
- addr = palmas_regs_info[PALMAS_REG_LDO8].vsel_addr;
+ addr = rinfo->vsel_addr;
ret = palmas_ldo_read(palmas, addr, &reg);
if (ret) {
dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n");
@@ -676,169 +856,230 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
return;
}
-static struct of_regulator_match palmas_matches[] = {
- { .name = "smps12", },
- { .name = "smps123", },
- { .name = "smps3", },
- { .name = "smps45", },
- { .name = "smps457", },
- { .name = "smps6", },
- { .name = "smps7", },
- { .name = "smps8", },
- { .name = "smps9", },
- { .name = "smps10_out2", },
- { .name = "smps10_out1", },
- { .name = "ldo1", },
- { .name = "ldo2", },
- { .name = "ldo3", },
- { .name = "ldo4", },
- { .name = "ldo5", },
- { .name = "ldo6", },
- { .name = "ldo7", },
- { .name = "ldo8", },
- { .name = "ldo9", },
- { .name = "ldoln", },
- { .name = "ldousb", },
- { .name = "regen1", },
- { .name = "regen2", },
- { .name = "regen3", },
- { .name = "sysen1", },
- { .name = "sysen2", },
-};
-
-static void palmas_dt_to_pdata(struct device *dev,
- struct device_node *node,
- struct palmas_pmic_platform_data *pdata)
+static int palmas_ldo_registration(struct palmas_pmic *pmic,
+ struct palmas_pmic_driver_data *ddata,
+ struct palmas_pmic_platform_data *pdata,
+ const char *pdev_name,
+ struct regulator_config config)
{
- struct device_node *regulators;
- u32 prop;
- int idx, ret;
+ int id, ret;
+ struct regulator_dev *rdev;
+ struct palmas_reg_init *reg_init;
+ struct palmas_regs_info *rinfo;
+ struct regulator_desc *desc;
- node = of_node_get(node);
- regulators = of_get_child_by_name(node, "regulators");
- if (!regulators) {
- dev_info(dev, "regulator node not found\n");
- return;
- }
+ for (id = ddata->ldo_begin; id < ddata->max_reg; id++) {
+ if (pdata && pdata->reg_init[id])
+ reg_init = pdata->reg_init[id];
+ else
+ reg_init = NULL;
- ret = of_regulator_match(dev, regulators, palmas_matches,
- PALMAS_NUM_REGS);
- of_node_put(regulators);
- if (ret < 0) {
- dev_err(dev, "Error parsing regulator init data: %d\n", ret);
- return;
- }
+ rinfo = &ddata->palmas_regs_info[id];
+ /* Miss out regulators which are not available due
+ * to alternate functions.
+ */
- for (idx = 0; idx < PALMAS_NUM_REGS; idx++) {
- if (!palmas_matches[idx].init_data ||
- !palmas_matches[idx].of_node)
- continue;
+ /* Register the regulators */
+ desc = &pmic->desc[id];
+ desc->name = rinfo->name;
+ desc->id = id;
+ desc->type = REGULATOR_VOLTAGE;
+ desc->owner = THIS_MODULE;
- pdata->reg_data[idx] = palmas_matches[idx].init_data;
+ if (id < PALMAS_REG_REGEN1) {
+ desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+ if (reg_init && reg_init->roof_floor)
+ desc->ops = &palmas_ops_ext_control_ldo;
+ else
+ desc->ops = &palmas_ops_ldo;
+ desc->min_uV = 900000;
+ desc->uV_step = 50000;
+ desc->linear_min_sel = 1;
+ desc->enable_time = 500;
+ desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+ rinfo->vsel_addr);
+ desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
+ desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
- pdata->reg_init[idx] = devm_kzalloc(dev,
- sizeof(struct palmas_reg_init), GFP_KERNEL);
+ /* Check if LDO8 is in tracking mode or not */
+ if (pdata && (id == PALMAS_REG_LDO8) &&
+ pdata->enable_ldo8_tracking) {
+ palmas_enable_ldo8_track(pmic->palmas);
+ desc->min_uV = 450000;
+ desc->uV_step = 25000;
+ }
- pdata->reg_init[idx]->warm_reset =
- of_property_read_bool(palmas_matches[idx].of_node,
- "ti,warm-reset");
+ /* LOD6 in vibrator mode will have enable time 2000us */
+ if (pdata && pdata->ldo6_vibrator &&
+ (id == PALMAS_REG_LDO6))
+ desc->enable_time = 2000;
+ } else {
+ desc->n_voltages = 1;
+ if (reg_init && reg_init->roof_floor)
+ desc->ops = &palmas_ops_ext_control_extreg;
+ else
+ desc->ops = &palmas_ops_extreg;
+ desc->enable_reg =
+ PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+ }
- ret = of_property_read_u32(palmas_matches[idx].of_node,
- "ti,roof-floor", &prop);
- /* EINVAL: Property not found */
- if (ret != -EINVAL) {
- int econtrol;
+ if (pdata)
+ config.init_data = pdata->reg_data[id];
+ else
+ config.init_data = NULL;
- /* use default value, when no value is specified */
- econtrol = PALMAS_EXT_CONTROL_NSLEEP;
- if (!ret) {
- switch (prop) {
- case 1:
- econtrol = PALMAS_EXT_CONTROL_ENABLE1;
- break;
- case 2:
- econtrol = PALMAS_EXT_CONTROL_ENABLE2;
- break;
- case 3:
- econtrol = PALMAS_EXT_CONTROL_NSLEEP;
- break;
- default:
- WARN_ON(1);
- dev_warn(dev,
- "%s: Invalid roof-floor option: %u\n",
- palmas_matches[idx].name, prop);
- break;
- }
- }
- pdata->reg_init[idx]->roof_floor = econtrol;
- }
+ desc->supply_name = rinfo->sname;
+ config.of_node = ddata->palmas_matches[id].of_node;
- ret = of_property_read_u32(palmas_matches[idx].of_node,
- "ti,mode-sleep", &prop);
- if (!ret)
- pdata->reg_init[idx]->mode_sleep = prop;
+ rdev = devm_regulator_register(pmic->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(pmic->dev,
+ "failed to register %s regulator\n",
+ pdev_name);
+ return PTR_ERR(rdev);
+ }
- ret = of_property_read_bool(palmas_matches[idx].of_node,
- "ti,smps-range");
- if (ret)
- pdata->reg_init[idx]->vsel =
- PALMAS_SMPS12_VOLTAGE_RANGE;
+ /* Save regulator for cleanup */
+ pmic->rdev[id] = rdev;
- if (idx == PALMAS_REG_LDO8)
- pdata->enable_ldo8_tracking = of_property_read_bool(
- palmas_matches[idx].of_node,
- "ti,enable-ldo8-tracking");
+ /* Initialise sleep/init values from platform data */
+ if (pdata) {
+ reg_init = pdata->reg_init[id];
+ if (reg_init) {
+ if (id <= ddata->ldo_end)
+ ret = palmas_ldo_init(pmic->palmas, id,
+ reg_init);
+ else
+ ret = palmas_extreg_init(pmic->palmas,
+ id, reg_init);
+ if (ret)
+ return ret;
+ }
+ }
}
- pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
+ return 0;
}
-
-static int palmas_regulators_probe(struct platform_device *pdev)
+static int tps65917_ldo_registration(struct palmas_pmic *pmic,
+ struct palmas_pmic_driver_data *ddata,
+ struct palmas_pmic_platform_data *pdata,
+ const char *pdev_name,
+ struct regulator_config config)
{
- struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
- struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct device_node *node = pdev->dev.of_node;
+ int id, ret;
struct regulator_dev *rdev;
- struct regulator_config config = { };
- struct palmas_pmic *pmic;
struct palmas_reg_init *reg_init;
- int id = 0, ret;
- unsigned int addr, reg;
+ struct palmas_regs_info *rinfo;
+ struct regulator_desc *desc;
- if (node && !pdata) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ for (id = ddata->ldo_begin; id < ddata->max_reg; id++) {
+ if (pdata && pdata->reg_init[id])
+ reg_init = pdata->reg_init[id];
+ else
+ reg_init = NULL;
- if (!pdata)
- return -ENOMEM;
+ /* Miss out regulators which are not available due
+ * to alternate functions.
+ */
+ rinfo = &ddata->palmas_regs_info[id];
- palmas_dt_to_pdata(&pdev->dev, node, pdata);
- }
+ /* Register the regulators */
+ desc = &pmic->desc[id];
+ desc->name = rinfo->name;
+ desc->id = id;
+ desc->type = REGULATOR_VOLTAGE;
+ desc->owner = THIS_MODULE;
+
+ if (id < TPS65917_REG_REGEN1) {
+ desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+ if (reg_init && reg_init->roof_floor)
+ desc->ops = &palmas_ops_ext_control_ldo;
+ else
+ desc->ops = &tps65917_ops_ldo;
+ desc->min_uV = 900000;
+ desc->uV_step = 50000;
+ desc->linear_min_sel = 1;
+ desc->enable_time = 500;
+ desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+ rinfo->vsel_addr);
+ desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
+ desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
+ /*
+ * To be confirmed. Discussion on going with PMIC Team.
+ * It is of the order of ~60mV/uS.
+ */
+ desc->ramp_delay = 2500;
+ } else {
+ desc->n_voltages = 1;
+ if (reg_init && reg_init->roof_floor)
+ desc->ops = &palmas_ops_ext_control_extreg;
+ else
+ desc->ops = &palmas_ops_extreg;
+ desc->enable_reg =
+ PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+ }
- pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
- if (!pmic)
- return -ENOMEM;
+ if (pdata)
+ config.init_data = pdata->reg_data[id];
+ else
+ config.init_data = NULL;
- pmic->dev = &pdev->dev;
- pmic->palmas = palmas;
- palmas->pmic = pmic;
- platform_set_drvdata(pdev, pmic);
+ desc->supply_name = rinfo->sname;
+ config.of_node = ddata->palmas_matches[id].of_node;
- ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
- if (ret)
- return ret;
+ rdev = devm_regulator_register(pmic->dev, desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(pmic->dev,
+ "failed to register %s regulator\n",
+ pdev_name);
+ return PTR_ERR(rdev);
+ }
- if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
- pmic->smps123 = 1;
+ /* Save regulator for cleanup */
+ pmic->rdev[id] = rdev;
- if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN)
- pmic->smps457 = 1;
+ /* Initialise sleep/init values from platform data */
+ if (pdata) {
+ reg_init = pdata->reg_init[id];
+ if (reg_init) {
+ if (id < TPS65917_REG_REGEN1)
+ ret = palmas_ldo_init(pmic->palmas,
+ id, reg_init);
+ else
+ ret = palmas_extreg_init(pmic->palmas,
+ id, reg_init);
+ if (ret)
+ return ret;
+ }
+ }
+ }
- config.regmap = palmas->regmap[REGULATOR_SLAVE];
- config.dev = &pdev->dev;
- config.driver_data = pmic;
+ return 0;
+}
+
+static int palmas_smps_registration(struct palmas_pmic *pmic,
+ struct palmas_pmic_driver_data *ddata,
+ struct palmas_pmic_platform_data *pdata,
+ const char *pdev_name,
+ struct regulator_config config)
+{
+ int id, ret;
+ unsigned int addr, reg;
+ struct regulator_dev *rdev;
+ struct palmas_reg_init *reg_init;
+ struct palmas_regs_info *rinfo;
+ struct regulator_desc *desc;
- for (id = 0; id < PALMAS_REG_LDO1; id++) {
+ for (id = ddata->smps_start; id <= ddata->smps_end; id++) {
bool ramp_delay_support = false;
/*
@@ -872,30 +1113,31 @@ static int palmas_regulators_probe(struct platform_device *pdev)
break;
case PALMAS_REG_SMPS10_OUT1:
case PALMAS_REG_SMPS10_OUT2:
- if (!PALMAS_PMIC_HAS(palmas, SMPS10_BOOST))
+ if (!PALMAS_PMIC_HAS(pmic->palmas, SMPS10_BOOST))
continue;
}
+ rinfo = &ddata->palmas_regs_info[id];
+ desc = &pmic->desc[id];
if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8))
ramp_delay_support = true;
if (ramp_delay_support) {
- addr = palmas_regs_info[id].tstep_addr;
+ addr = rinfo->tstep_addr;
ret = palmas_smps_read(pmic->palmas, addr, &reg);
if (ret < 0) {
- dev_err(&pdev->dev,
+ dev_err(pmic->dev,
"reading TSTEP reg failed: %d\n", ret);
return ret;
}
- pmic->desc[id].ramp_delay =
- palmas_smps_ramp_delay[reg & 0x3];
- pmic->ramp_delay[id] = pmic->desc[id].ramp_delay;
+ desc->ramp_delay = palmas_smps_ramp_delay[reg & 0x3];
+ pmic->ramp_delay[id] = desc->ramp_delay;
}
/* Initialise sleep/init values from platform data */
if (pdata && pdata->reg_init[id]) {
reg_init = pdata->reg_init[id];
- ret = palmas_smps_init(palmas, id, reg_init);
+ ret = palmas_smps_init(pmic->palmas, id, reg_init);
if (ret)
return ret;
} else {
@@ -903,31 +1145,28 @@ static int palmas_regulators_probe(struct platform_device *pdev)
}
/* Register the regulators */
- pmic->desc[id].name = palmas_regs_info[id].name;
- pmic->desc[id].id = id;
+ desc->name = rinfo->name;
+ desc->id = id;
switch (id) {
case PALMAS_REG_SMPS10_OUT1:
case PALMAS_REG_SMPS10_OUT2:
- pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
- pmic->desc[id].ops = &palmas_ops_smps10;
- pmic->desc[id].vsel_reg =
- PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
- PALMAS_SMPS10_CTRL);
- pmic->desc[id].vsel_mask = SMPS10_VSEL;
- pmic->desc[id].enable_reg =
- PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
- PALMAS_SMPS10_CTRL);
+ desc->n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
+ desc->ops = &palmas_ops_smps10;
+ desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ PALMAS_SMPS10_CTRL);
+ desc->vsel_mask = SMPS10_VSEL;
+ desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ PALMAS_SMPS10_CTRL);
if (id == PALMAS_REG_SMPS10_OUT1)
- pmic->desc[id].enable_mask = SMPS10_SWITCH_EN;
+ desc->enable_mask = SMPS10_SWITCH_EN;
else
- pmic->desc[id].enable_mask = SMPS10_BOOST_EN;
- pmic->desc[id].bypass_reg =
- PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
- PALMAS_SMPS10_CTRL);
- pmic->desc[id].bypass_mask = SMPS10_BYPASS_EN;
- pmic->desc[id].min_uV = 3750000;
- pmic->desc[id].uV_step = 1250000;
+ desc->enable_mask = SMPS10_BOOST_EN;
+ desc->bypass_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ PALMAS_SMPS10_CTRL);
+ desc->bypass_mask = SMPS10_BYPASS_EN;
+ desc->min_uV = 3750000;
+ desc->uV_step = 1250000;
break;
default:
/*
@@ -936,8 +1175,8 @@ static int palmas_regulators_probe(struct platform_device *pdev)
* otherwise we error in probe with unsupportable
* ranges. Read the current smps mode for later use.
*/
- addr = palmas_regs_info[id].vsel_addr;
- pmic->desc[id].n_linear_ranges = 3;
+ addr = rinfo->vsel_addr;
+ desc->n_linear_ranges = 3;
ret = palmas_smps_read(pmic->palmas, addr, &reg);
if (ret)
@@ -945,56 +1184,50 @@ static int palmas_regulators_probe(struct platform_device *pdev)
if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
pmic->range[id] = 1;
if (pmic->range[id])
- pmic->desc[id].linear_ranges = smps_high_ranges;
+ desc->linear_ranges = smps_high_ranges;
else
- pmic->desc[id].linear_ranges = smps_low_ranges;
+ desc->linear_ranges = smps_low_ranges;
if (reg_init && reg_init->roof_floor)
- pmic->desc[id].ops =
- &palmas_ops_ext_control_smps;
+ desc->ops = &palmas_ops_ext_control_smps;
else
- pmic->desc[id].ops = &palmas_ops_smps;
- pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
- pmic->desc[id].vsel_reg =
- PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
- palmas_regs_info[id].vsel_addr);
- pmic->desc[id].vsel_mask =
- PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
+ desc->ops = &palmas_ops_smps;
+ desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
+ desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ rinfo->vsel_addr);
+ desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
/* Read the smps mode for later use. */
- addr = palmas_regs_info[id].ctrl_addr;
+ addr = rinfo->ctrl_addr;
ret = palmas_smps_read(pmic->palmas, addr, &reg);
if (ret)
return ret;
pmic->current_reg_mode[id] = reg &
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
- pmic->desc[id].enable_reg =
- PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
- palmas_regs_info[id].ctrl_addr);
- pmic->desc[id].enable_mask =
- PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+ desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
/* set_mode overrides this value */
- pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON;
+ desc->enable_val = SMPS_CTRL_MODE_ON;
}
- pmic->desc[id].type = REGULATOR_VOLTAGE;
- pmic->desc[id].owner = THIS_MODULE;
+ desc->type = REGULATOR_VOLTAGE;
+ desc->owner = THIS_MODULE;
if (pdata)
config.init_data = pdata->reg_data[id];
else
config.init_data = NULL;
- pmic->desc[id].supply_name = palmas_regs_info[id].sname;
- config.of_node = palmas_matches[id].of_node;
+ desc->supply_name = rinfo->sname;
+ config.of_node = ddata->palmas_matches[id].of_node;
- rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
- &config);
+ rdev = devm_regulator_register(pmic->dev, desc, &config);
if (IS_ERR(rdev)) {
- dev_err(&pdev->dev,
+ dev_err(pmic->dev,
"failed to register %s regulator\n",
- pdev->name);
+ pdev_name);
return PTR_ERR(rdev);
}
@@ -1002,123 +1235,378 @@ static int palmas_regulators_probe(struct platform_device *pdev)
pmic->rdev[id] = rdev;
}
- /* Start this loop from the id left from previous loop */
- for (; id < PALMAS_NUM_REGS; id++) {
- if (pdata && pdata->reg_init[id])
+ return 0;
+}
+
+static int tps65917_smps_registration(struct palmas_pmic *pmic,
+ struct palmas_pmic_driver_data *ddata,
+ struct palmas_pmic_platform_data *pdata,
+ const char *pdev_name,
+ struct regulator_config config)
+{
+ int id, ret;
+ unsigned int addr, reg;
+ struct regulator_dev *rdev;
+ struct palmas_reg_init *reg_init;
+ struct palmas_regs_info *rinfo;
+ struct regulator_desc *desc;
+
+ for (id = ddata->smps_start; id <= ddata->smps_end; id++) {
+ /*
+ * Miss out regulators which are not available due
+ * to slaving configurations.
+ */
+ desc = &pmic->desc[id];
+ desc->n_linear_ranges = 3;
+ if ((id == TPS65917_REG_SMPS2) && pmic->smps12)
+ continue;
+
+ /* Initialise sleep/init values from platform data */
+ if (pdata && pdata->reg_init[id]) {
reg_init = pdata->reg_init[id];
- else
+ ret = palmas_smps_init(pmic->palmas, id, reg_init);
+ if (ret)
+ return ret;
+ } else {
reg_init = NULL;
+ }
+ rinfo = &ddata->palmas_regs_info[id];
- /* Miss out regulators which are not available due
- * to alternate functions.
+ /* Register the regulators */
+ desc->name = rinfo->name;
+ desc->id = id;
+
+ /*
+ * Read and store the RANGE bit for later use
+ * This must be done before regulator is probed,
+ * otherwise we error in probe with unsupportable
+ * ranges. Read the current smps mode for later use.
*/
+ addr = rinfo->vsel_addr;
- /* Register the regulators */
- pmic->desc[id].name = palmas_regs_info[id].name;
- pmic->desc[id].id = id;
- pmic->desc[id].type = REGULATOR_VOLTAGE;
- pmic->desc[id].owner = THIS_MODULE;
+ ret = palmas_smps_read(pmic->palmas, addr, &reg);
+ if (ret)
+ return ret;
+ if (reg & TPS65917_SMPS1_VOLTAGE_RANGE)
+ pmic->range[id] = 1;
- if (id < PALMAS_REG_REGEN1) {
- pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
- if (reg_init && reg_init->roof_floor)
- pmic->desc[id].ops =
- &palmas_ops_ext_control_ldo;
- else
- pmic->desc[id].ops = &palmas_ops_ldo;
- pmic->desc[id].min_uV = 900000;
- pmic->desc[id].uV_step = 50000;
- pmic->desc[id].linear_min_sel = 1;
- pmic->desc[id].enable_time = 500;
- pmic->desc[id].vsel_reg =
- PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
- palmas_regs_info[id].vsel_addr);
- pmic->desc[id].vsel_mask =
- PALMAS_LDO1_VOLTAGE_VSEL_MASK;
- pmic->desc[id].enable_reg =
- PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
- palmas_regs_info[id].ctrl_addr);
- pmic->desc[id].enable_mask =
- PALMAS_LDO1_CTRL_MODE_ACTIVE;
+ if (pmic->range[id])
+ desc->linear_ranges = smps_high_ranges;
+ else
+ desc->linear_ranges = smps_low_ranges;
- /* Check if LDO8 is in tracking mode or not */
- if (pdata && (id == PALMAS_REG_LDO8) &&
- pdata->enable_ldo8_tracking) {
- palmas_enable_ldo8_track(palmas);
- pmic->desc[id].min_uV = 450000;
- pmic->desc[id].uV_step = 25000;
- }
+ if (reg_init && reg_init->roof_floor)
+ desc->ops = &tps65917_ops_ext_control_smps;
+ else
+ desc->ops = &tps65917_ops_smps;
+ desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
+ desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ rinfo->vsel_addr);
+ desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
+ desc->ramp_delay = 2500;
+
+ /* Read the smps mode for later use. */
+ addr = rinfo->ctrl_addr;
+ ret = palmas_smps_read(pmic->palmas, addr, &reg);
+ if (ret)
+ return ret;
+ pmic->current_reg_mode[id] = reg &
+ PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+ desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+ rinfo->ctrl_addr);
+ desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+ /* set_mode overrides this value */
+ desc->enable_val = SMPS_CTRL_MODE_ON;
- /* LOD6 in vibrator mode will have enable time 2000us */
- if (pdata && pdata->ldo6_vibrator &&
- (id == PALMAS_REG_LDO6))
- pmic->desc[id].enable_time = 2000;
- } else {
- pmic->desc[id].n_voltages = 1;
- if (reg_init && reg_init->roof_floor)
- pmic->desc[id].ops =
- &palmas_ops_ext_control_extreg;
- else
- pmic->desc[id].ops = &palmas_ops_extreg;
- pmic->desc[id].enable_reg =
- PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
- palmas_regs_info[id].ctrl_addr);
- pmic->desc[id].enable_mask =
- PALMAS_REGEN1_CTRL_MODE_ACTIVE;
- }
+ desc->type = REGULATOR_VOLTAGE;
+ desc->owner = THIS_MODULE;
if (pdata)
config.init_data = pdata->reg_data[id];
else
config.init_data = NULL;
- pmic->desc[id].supply_name = palmas_regs_info[id].sname;
- config.of_node = palmas_matches[id].of_node;
+ desc->supply_name = rinfo->sname;
+ config.of_node = ddata->palmas_matches[id].of_node;
- rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
- &config);
+ rdev = devm_regulator_register(pmic->dev, desc, &config);
if (IS_ERR(rdev)) {
- dev_err(&pdev->dev,
+ dev_err(pmic->dev,
"failed to register %s regulator\n",
- pdev->name);
+ pdev_name);
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[id] = rdev;
+ }
- /* Initialise sleep/init values from platform data */
- if (pdata) {
- reg_init = pdata->reg_init[id];
- if (reg_init) {
- if (id < PALMAS_REG_REGEN1)
- ret = palmas_ldo_init(palmas,
- id, reg_init);
- else
- ret = palmas_extreg_init(palmas,
- id, reg_init);
- if (ret)
- return ret;
+ return 0;
+}
+
+static struct of_regulator_match palmas_matches[] = {
+ { .name = "smps12", },
+ { .name = "smps123", },
+ { .name = "smps3", },
+ { .name = "smps45", },
+ { .name = "smps457", },
+ { .name = "smps6", },
+ { .name = "smps7", },
+ { .name = "smps8", },
+ { .name = "smps9", },
+ { .name = "smps10_out2", },
+ { .name = "smps10_out1", },
+ { .name = "ldo1", },
+ { .name = "ldo2", },
+ { .name = "ldo3", },
+ { .name = "ldo4", },
+ { .name = "ldo5", },
+ { .name = "ldo6", },
+ { .name = "ldo7", },
+ { .name = "ldo8", },
+ { .name = "ldo9", },
+ { .name = "ldoln", },
+ { .name = "ldousb", },
+ { .name = "regen1", },
+ { .name = "regen2", },
+ { .name = "regen3", },
+ { .name = "sysen1", },
+ { .name = "sysen2", },
+};
+
+static struct of_regulator_match tps65917_matches[] = {
+ { .name = "smps1", },
+ { .name = "smps2", },
+ { .name = "smps3", },
+ { .name = "smps4", },
+ { .name = "smps5", },
+ { .name = "ldo1", },
+ { .name = "ldo2", },
+ { .name = "ldo3", },
+ { .name = "ldo4", },
+ { .name = "ldo5", },
+ { .name = "regen1", },
+ { .name = "regen2", },
+ { .name = "regen3", },
+ { .name = "sysen1", },
+ { .name = "sysen2", },
+};
+
+static struct palmas_pmic_driver_data palmas_ddata = {
+ .smps_start = PALMAS_REG_SMPS12,
+ .smps_end = PALMAS_REG_SMPS10_OUT1,
+ .ldo_begin = PALMAS_REG_LDO1,
+ .ldo_end = PALMAS_REG_LDOUSB,
+ .max_reg = PALMAS_NUM_REGS,
+ .palmas_regs_info = palmas_generic_regs_info,
+ .palmas_matches = palmas_matches,
+ .sleep_req_info = palma_sleep_req_info,
+ .smps_register = palmas_smps_registration,
+ .ldo_register = palmas_ldo_registration,
+};
+
+static struct palmas_pmic_driver_data tps65917_ddata = {
+ .smps_start = TPS65917_REG_SMPS1,
+ .smps_end = TPS65917_REG_SMPS5,
+ .ldo_begin = TPS65917_REG_LDO1,
+ .ldo_end = TPS65917_REG_LDO5,
+ .max_reg = TPS65917_NUM_REGS,
+ .palmas_regs_info = tps65917_regs_info,
+ .palmas_matches = tps65917_matches,
+ .sleep_req_info = tps65917_sleep_req_info,
+ .smps_register = tps65917_smps_registration,
+ .ldo_register = tps65917_ldo_registration,
+};
+
+static void palmas_dt_to_pdata(struct device *dev,
+ struct device_node *node,
+ struct palmas_pmic_platform_data *pdata,
+ struct palmas_pmic_driver_data *ddata)
+{
+ struct device_node *regulators;
+ u32 prop;
+ int idx, ret;
+
+ node = of_node_get(node);
+ regulators = of_get_child_by_name(node, "regulators");
+ if (!regulators) {
+ dev_info(dev, "regulator node not found\n");
+ return;
+ }
+
+ ret = of_regulator_match(dev, regulators, ddata->palmas_matches,
+ ddata->max_reg);
+ of_node_put(regulators);
+ if (ret < 0) {
+ dev_err(dev, "Error parsing regulator init data: %d\n", ret);
+ return;
+ }
+
+ for (idx = 0; idx < ddata->max_reg; idx++) {
+ if (!ddata->palmas_matches[idx].init_data ||
+ !ddata->palmas_matches[idx].of_node)
+ continue;
+
+ pdata->reg_data[idx] = ddata->palmas_matches[idx].init_data;
+
+ pdata->reg_init[idx] = devm_kzalloc(dev,
+ sizeof(struct palmas_reg_init), GFP_KERNEL);
+
+ pdata->reg_init[idx]->warm_reset =
+ of_property_read_bool(ddata->palmas_matches[idx].of_node,
+ "ti,warm-reset");
+
+ ret = of_property_read_u32(ddata->palmas_matches[idx].of_node,
+ "ti,roof-floor", &prop);
+ /* EINVAL: Property not found */
+ if (ret != -EINVAL) {
+ int econtrol;
+
+ /* use default value, when no value is specified */
+ econtrol = PALMAS_EXT_CONTROL_NSLEEP;
+ if (!ret) {
+ switch (prop) {
+ case 1:
+ econtrol = PALMAS_EXT_CONTROL_ENABLE1;
+ break;
+ case 2:
+ econtrol = PALMAS_EXT_CONTROL_ENABLE2;
+ break;
+ case 3:
+ econtrol = PALMAS_EXT_CONTROL_NSLEEP;
+ break;
+ default:
+ WARN_ON(1);
+ dev_warn(dev,
+ "%s: Invalid roof-floor option: %u\n",
+ palmas_matches[idx].name, prop);
+ break;
+ }
}
+ pdata->reg_init[idx]->roof_floor = econtrol;
}
- }
+ ret = of_property_read_u32(ddata->palmas_matches[idx].of_node,
+ "ti,mode-sleep", &prop);
+ if (!ret)
+ pdata->reg_init[idx]->mode_sleep = prop;
+
+ ret = of_property_read_bool(ddata->palmas_matches[idx].of_node,
+ "ti,smps-range");
+ if (ret)
+ pdata->reg_init[idx]->vsel =
+ PALMAS_SMPS12_VOLTAGE_RANGE;
- return 0;
+ if (idx == PALMAS_REG_LDO8)
+ pdata->enable_ldo8_tracking = of_property_read_bool(
+ ddata->palmas_matches[idx].of_node,
+ "ti,enable-ldo8-tracking");
+ }
+
+ pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
}
-static const struct of_device_id of_palmas_match_tbl[] = {
- { .compatible = "ti,palmas-pmic", },
- { .compatible = "ti,twl6035-pmic", },
- { .compatible = "ti,twl6036-pmic", },
- { .compatible = "ti,twl6037-pmic", },
- { .compatible = "ti,tps65913-pmic", },
- { .compatible = "ti,tps65914-pmic", },
- { .compatible = "ti,tps80036-pmic", },
- { .compatible = "ti,tps659038-pmic", },
+static struct of_device_id of_palmas_match_tbl[] = {
+ {
+ .compatible = "ti,palmas-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,twl6035-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,twl6036-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,twl6037-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,tps65913-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,tps65914-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,tps80036-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,tps659038-pmic",
+ .data = &palmas_ddata,
+ },
+ {
+ .compatible = "ti,tps65917-pmic",
+ .data = &tps65917_ddata,
+ },
{ /* end */ }
};
+static int palmas_regulators_probe(struct platform_device *pdev)
+{
+ struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
+ struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct device_node *node = pdev->dev.of_node;
+ struct palmas_pmic_driver_data *driver_data;
+ struct regulator_config config = { };
+ struct palmas_pmic *pmic;
+ const char *pdev_name;
+ const struct of_device_id *match;
+ int ret = 0;
+ unsigned int reg;
+
+ match = of_match_device(of_match_ptr(of_palmas_match_tbl), &pdev->dev);
+
+ if (!match)
+ return -ENODATA;
+
+ driver_data = (struct palmas_pmic_driver_data *)match->data;
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
+ if (!pmic)
+ return -ENOMEM;
+
+ pmic->dev = &pdev->dev;
+ pmic->palmas = palmas;
+ palmas->pmic = pmic;
+ platform_set_drvdata(pdev, pmic);
+ pmic->palmas->pmic_ddata = driver_data;
+
+ palmas_dt_to_pdata(&pdev->dev, node, pdata, driver_data);
+
+ ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
+ if (ret)
+ return ret;
+
+ if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
+ pmic->smps123 = 1;
+
+ if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN)
+ pmic->smps457 = 1;
+
+ config.regmap = palmas->regmap[REGULATOR_SLAVE];
+ config.dev = &pdev->dev;
+ config.driver_data = pmic;
+ pdev_name = pdev->name;
+
+ ret = driver_data->smps_register(pmic, driver_data, pdata, pdev_name,
+ config);
+ if (ret)
+ return ret;
+
+ ret = driver_data->ldo_register(pmic, driver_data, pdata, pdev_name,
+ config);
+
+ return ret;
+}
+
static struct platform_driver palmas_driver = {
.driver = {
.name = "palmas-pmic",
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index 02e2fb2fca66..b16c53a8272f 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -31,6 +31,7 @@
#include <linux/mfd/samsung/core.h>
#include <linux/mfd/samsung/s2mps11.h>
#include <linux/mfd/samsung/s2mps14.h>
+#include <linux/mfd/samsung/s2mpu02.h>
struct s2mps11_info {
unsigned int rdev_num;
@@ -40,11 +41,15 @@ struct s2mps11_info {
int ramp_delay16;
int ramp_delay7810;
int ramp_delay9;
+
+ enum sec_device_type dev_type;
+
/*
- * One bit for each S2MPS14 regulator whether the suspend mode
+ * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode
* was enabled.
*/
- unsigned int s2mps14_suspend_state:30;
+ unsigned long long s2mps14_suspend_state:35;
+
/* Array of size rdev_num with GPIO-s for external sleep control */
int *ext_control_gpio;
};
@@ -415,12 +420,24 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
unsigned int val;
- if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
- val = S2MPS14_ENABLE_SUSPEND;
- else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
- val = S2MPS14_ENABLE_EXT_CONTROL;
- else
- val = rdev->desc->enable_mask;
+ switch (s2mps11->dev_type) {
+ case S2MPS14X:
+ if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ val = S2MPS14_ENABLE_SUSPEND;
+ else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
+ val = S2MPS14_ENABLE_EXT_CONTROL;
+ else
+ val = rdev->desc->enable_mask;
+ break;
+ case S2MPU02:
+ if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ val = S2MPU02_ENABLE_SUSPEND;
+ else
+ val = rdev->desc->enable_mask;
+ break;
+ default:
+ return -EINVAL;
+ };
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val);
@@ -429,12 +446,38 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
{
int ret;
- unsigned int val;
+ unsigned int val, state;
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
+ int rdev_id = rdev_get_id(rdev);
- /* LDO3 should be always on and does not support suspend mode */
- if (rdev_get_id(rdev) == S2MPS14_LDO3)
- return 0;
+ /* Below LDO should be always on or does not support suspend mode. */
+ switch (s2mps11->dev_type) {
+ case S2MPS14X:
+ switch (rdev_id) {
+ case S2MPS14_LDO3:
+ return 0;
+ default:
+ state = S2MPS14_ENABLE_SUSPEND;
+ break;
+ };
+ break;
+ case S2MPU02:
+ switch (rdev_id) {
+ case S2MPU02_LDO13:
+ case S2MPU02_LDO14:
+ case S2MPU02_LDO15:
+ case S2MPU02_LDO17:
+ case S2MPU02_BUCK7:
+ state = S2MPU02_DISABLE_SUSPEND;
+ break;
+ default:
+ state = S2MPU02_ENABLE_SUSPEND;
+ break;
+ };
+ break;
+ default:
+ return -EINVAL;
+ };
ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
if (ret < 0)
@@ -452,7 +495,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
return 0;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
- rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND);
+ rdev->desc->enable_mask, state);
}
static struct regulator_ops s2mps14_reg_ops = {
@@ -605,8 +648,7 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev,
}
static int s2mps11_pmic_dt_parse(struct platform_device *pdev,
- struct of_regulator_match *rdata, struct s2mps11_info *s2mps11,
- enum sec_device_type dev_type)
+ struct of_regulator_match *rdata, struct s2mps11_info *s2mps11)
{
struct device_node *reg_np;
@@ -617,7 +659,7 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev,
}
of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num);
- if (dev_type == S2MPS14X)
+ if (s2mps11->dev_type == S2MPS14X)
s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11);
of_node_put(reg_np);
@@ -625,6 +667,238 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev,
return 0;
}
+static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
+{
+ unsigned int ramp_val, ramp_shift, ramp_reg;
+
+ switch (rdev_get_id(rdev)) {
+ case S2MPU02_BUCK1:
+ ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT;
+ break;
+ case S2MPU02_BUCK2:
+ ramp_shift = S2MPU02_BUCK2_RAMP_SHIFT;
+ break;
+ case S2MPU02_BUCK3:
+ ramp_shift = S2MPU02_BUCK3_RAMP_SHIFT;
+ break;
+ case S2MPU02_BUCK4:
+ ramp_shift = S2MPU02_BUCK4_RAMP_SHIFT;
+ break;
+ default:
+ return 0;
+ }
+ ramp_reg = S2MPU02_REG_RAMP1;
+ ramp_val = get_ramp_delay(ramp_delay);
+
+ return regmap_update_bits(rdev->regmap, ramp_reg,
+ S2MPU02_BUCK1234_RAMP_MASK << ramp_shift,
+ ramp_val << ramp_shift);
+}
+
+static struct regulator_ops s2mpu02_ldo_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = s2mps14_regulator_enable,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_suspend_disable = s2mps14_regulator_set_suspend_disable,
+};
+
+static struct regulator_ops s2mpu02_buck_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = s2mps14_regulator_enable,
+ .disable = regulator_disable_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .set_suspend_disable = s2mps14_regulator_set_suspend_disable,
+ .set_ramp_delay = s2mpu02_set_ramp_delay,
+};
+
+#define regulator_desc_s2mpu02_ldo1(num) { \
+ .name = "LDO"#num, \
+ .id = S2MPU02_LDO##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_LDO_MIN_900MV, \
+ .uV_step = S2MPU02_LDO_STEP_12_5MV, \
+ .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \
+ .n_voltages = S2MPU02_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPU02_REG_L1CTRL, \
+ .vsel_mask = S2MPU02_LDO_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_L1CTRL, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_ldo2(num) { \
+ .name = "LDO"#num, \
+ .id = S2MPU02_LDO##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_LDO_MIN_1050MV, \
+ .uV_step = S2MPU02_LDO_STEP_25MV, \
+ .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \
+ .n_voltages = S2MPU02_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPU02_REG_L2CTRL1, \
+ .vsel_mask = S2MPU02_LDO_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_L2CTRL1, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_ldo3(num) { \
+ .name = "LDO"#num, \
+ .id = S2MPU02_LDO##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_LDO_MIN_900MV, \
+ .uV_step = S2MPU02_LDO_STEP_12_5MV, \
+ .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \
+ .n_voltages = S2MPU02_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .vsel_mask = S2MPU02_LDO_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_ldo4(num) { \
+ .name = "LDO"#num, \
+ .id = S2MPU02_LDO##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_LDO_MIN_1050MV, \
+ .uV_step = S2MPU02_LDO_STEP_25MV, \
+ .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \
+ .n_voltages = S2MPU02_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .vsel_mask = S2MPU02_LDO_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_ldo5(num) { \
+ .name = "LDO"#num, \
+ .id = S2MPU02_LDO##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_LDO_MIN_1600MV, \
+ .uV_step = S2MPU02_LDO_STEP_50MV, \
+ .linear_min_sel = S2MPU02_LDO_GROUP3_START_SEL, \
+ .n_voltages = S2MPU02_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .vsel_mask = S2MPU02_LDO_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+
+#define regulator_desc_s2mpu02_buck1234(num) { \
+ .name = "BUCK"#num, \
+ .id = S2MPU02_BUCK##num, \
+ .ops = &s2mpu02_buck_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_BUCK1234_MIN_600MV, \
+ .uV_step = S2MPU02_BUCK1234_STEP_6_25MV, \
+ .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \
+ .linear_min_sel = S2MPU02_BUCK1234_START_SEL, \
+ .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPU02_REG_B1CTRL2 + (num - 1) * 2, \
+ .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_B1CTRL1 + (num - 1) * 2, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_buck5(num) { \
+ .name = "BUCK"#num, \
+ .id = S2MPU02_BUCK##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_BUCK5_MIN_1081_25MV, \
+ .uV_step = S2MPU02_BUCK5_STEP_6_25MV, \
+ .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \
+ .linear_min_sel = S2MPU02_BUCK5_START_SEL, \
+ .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPU02_REG_B5CTRL2, \
+ .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_B5CTRL1, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_buck6(num) { \
+ .name = "BUCK"#num, \
+ .id = S2MPU02_BUCK##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_BUCK6_MIN_1700MV, \
+ .uV_step = S2MPU02_BUCK6_STEP_2_50MV, \
+ .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \
+ .linear_min_sel = S2MPU02_BUCK6_START_SEL, \
+ .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPU02_REG_B6CTRL2, \
+ .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_B6CTRL1, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+#define regulator_desc_s2mpu02_buck7(num) { \
+ .name = "BUCK"#num, \
+ .id = S2MPU02_BUCK##num, \
+ .ops = &s2mpu02_ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = S2MPU02_BUCK7_MIN_900MV, \
+ .uV_step = S2MPU02_BUCK7_STEP_6_25MV, \
+ .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \
+ .linear_min_sel = S2MPU02_BUCK7_START_SEL, \
+ .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPU02_REG_B7CTRL2, \
+ .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPU02_REG_B7CTRL1, \
+ .enable_mask = S2MPU02_ENABLE_MASK \
+}
+
+static const struct regulator_desc s2mpu02_regulators[] = {
+ regulator_desc_s2mpu02_ldo1(1),
+ regulator_desc_s2mpu02_ldo2(2),
+ regulator_desc_s2mpu02_ldo4(3),
+ regulator_desc_s2mpu02_ldo5(4),
+ regulator_desc_s2mpu02_ldo4(5),
+ regulator_desc_s2mpu02_ldo3(6),
+ regulator_desc_s2mpu02_ldo3(7),
+ regulator_desc_s2mpu02_ldo4(8),
+ regulator_desc_s2mpu02_ldo5(9),
+ regulator_desc_s2mpu02_ldo3(10),
+ regulator_desc_s2mpu02_ldo4(11),
+ regulator_desc_s2mpu02_ldo5(12),
+ regulator_desc_s2mpu02_ldo5(13),
+ regulator_desc_s2mpu02_ldo5(14),
+ regulator_desc_s2mpu02_ldo5(15),
+ regulator_desc_s2mpu02_ldo5(16),
+ regulator_desc_s2mpu02_ldo4(17),
+ regulator_desc_s2mpu02_ldo5(18),
+ regulator_desc_s2mpu02_ldo3(19),
+ regulator_desc_s2mpu02_ldo4(20),
+ regulator_desc_s2mpu02_ldo5(21),
+ regulator_desc_s2mpu02_ldo5(22),
+ regulator_desc_s2mpu02_ldo5(23),
+ regulator_desc_s2mpu02_ldo4(24),
+ regulator_desc_s2mpu02_ldo5(25),
+ regulator_desc_s2mpu02_ldo4(26),
+ regulator_desc_s2mpu02_ldo5(27),
+ regulator_desc_s2mpu02_ldo5(28),
+ regulator_desc_s2mpu02_buck1234(1),
+ regulator_desc_s2mpu02_buck1234(2),
+ regulator_desc_s2mpu02_buck1234(3),
+ regulator_desc_s2mpu02_buck1234(4),
+ regulator_desc_s2mpu02_buck5(5),
+ regulator_desc_s2mpu02_buck6(6),
+ regulator_desc_s2mpu02_buck7(7),
+};
+
static int s2mps11_pmic_probe(struct platform_device *pdev)
{
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
@@ -634,15 +908,14 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
struct s2mps11_info *s2mps11;
int i, ret = 0;
const struct regulator_desc *regulators;
- enum sec_device_type dev_type;
s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info),
GFP_KERNEL);
if (!s2mps11)
return -ENOMEM;
- dev_type = platform_get_device_id(pdev)->driver_data;
- switch (dev_type) {
+ s2mps11->dev_type = platform_get_device_id(pdev)->driver_data;
+ switch (s2mps11->dev_type) {
case S2MPS11X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators);
regulators = s2mps11_regulators;
@@ -651,8 +924,13 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators);
regulators = s2mps14_regulators;
break;
+ case S2MPU02:
+ s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators);
+ regulators = s2mpu02_regulators;
+ break;
default:
- dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type);
+ dev_err(&pdev->dev, "Invalid device type: %u\n",
+ s2mps11->dev_type);
return -EINVAL;
};
@@ -686,7 +964,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
for (i = 0; i < s2mps11->rdev_num; i++)
rdata[i].name = regulators[i].name;
- ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type);
+ ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11);
if (ret)
goto out;
@@ -739,6 +1017,7 @@ out:
static const struct platform_device_id s2mps11_pmic_id[] = {
{ "s2mps11-pmic", S2MPS11X},
{ "s2mps14-pmic", S2MPS14X},
+ { "s2mpu02-pmic", S2MPU02},
{ },
};
MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
@@ -766,5 +1045,5 @@ module_exit(s2mps11_pmic_exit);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver");
+MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPU02 Regulator Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index c79af943a5c0..0ab5cbeeb797 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -686,7 +686,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
struct sec_platform_data *pdata = iodev->pdata;
struct regulator_config config = { };
struct s5m8767_info *s5m8767;
- int i, ret, size, buck_init;
+ int i, ret, buck_init;
if (!pdata) {
dev_err(pdev->dev.parent, "Platform data not supplied\n");
@@ -725,8 +725,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
if (!s5m8767)
return -ENOMEM;
- size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2);
-
s5m8767->dev = &pdev->dev;
s5m8767->iodev = iodev;
s5m8767->num_regulators = pdata->num_regulators;
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
index 2064b3fd45f7..d5df1e9ad1da 100644
--- a/drivers/regulator/tps65090-regulator.c
+++ b/drivers/regulator/tps65090-regulator.c
@@ -192,12 +192,14 @@ static struct regulator_ops tps65090_fet_control_ops = {
static struct regulator_ops tps65090_ldo_ops = {
};
-#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops) \
+#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \
{ \
.name = "TPS65090_RAILS"#_id, \
.supply_name = _sname, \
.id = TPS65090_REGULATOR_##_id, \
+ .n_voltages = _nvolt, \
.ops = &_ops, \
+ .fixed_uV = _volt, \
.enable_reg = _en_reg, \
.enable_val = _en_bits, \
.enable_mask = _en_bits, \
@@ -205,40 +207,46 @@ static struct regulator_ops tps65090_ldo_ops = {
.owner = THIS_MODULE, \
}
+#define tps65090_REG_FIXEDV(_id, _sname, en_reg, _en_bits, _volt, _ops) \
+ tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 1, _volt, _ops)
+
+#define tps65090_REG_SWITCH(_id, _sname, en_reg, _en_bits, _ops) \
+ tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 0, 0, _ops)
+
static struct regulator_desc tps65090_regulator_desc[] = {
- tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT),
- tps65090_reg_control_ops),
- tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT),
- tps65090_reg_control_ops),
- tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT),
- tps65090_reg_control_ops),
-
- tps65090_REG_DESC(FET1, "infet1", 0x0F,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET2, "infet2", 0x10,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET3, "infet3", 0x11,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET4, "infet4", 0x12,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET5, "infet5", 0x13,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET6, "infet6", 0x14,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
- tps65090_REG_DESC(FET7, "infet7", 0x15,
- BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
- tps65090_fet_control_ops),
-
- tps65090_REG_DESC(LDO1, "vsys-l1", 0, 0,
- tps65090_ldo_ops),
- tps65090_REG_DESC(LDO2, "vsys-l2", 0, 0,
- tps65090_ldo_ops),
+ tps65090_REG_FIXEDV(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), 5000000,
+ tps65090_reg_control_ops),
+ tps65090_REG_FIXEDV(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), 3300000,
+ tps65090_reg_control_ops),
+ tps65090_REG_SWITCH(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT),
+ tps65090_reg_control_ops),
+
+ tps65090_REG_SWITCH(FET1, "infet1", 0x0F,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET2, "infet2", 0x10,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET3, "infet3", 0x11,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET4, "infet4", 0x12,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET5, "infet5", 0x13,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET6, "infet6", 0x14,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+ tps65090_REG_SWITCH(FET7, "infet7", 0x15,
+ BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+ tps65090_fet_control_ops),
+
+ tps65090_REG_FIXEDV(LDO1, "vsys-l1", 0, 0, 5000000,
+ tps65090_ldo_ops),
+ tps65090_REG_FIXEDV(LDO2, "vsys-l2", 0, 0, 3300000,
+ tps65090_ldo_ops),
};
static inline bool is_dcdc(int id)
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c
index f7ed20a5a8b9..d58db72a63b0 100644
--- a/drivers/regulator/tps65217-regulator.c
+++ b/drivers/regulator/tps65217-regulator.c
@@ -68,7 +68,7 @@ static const struct regulator_linear_range tps65217_uv2_ranges[] = {
static int tps65217_pmic_enable(struct regulator_dev *dev)
{
struct tps65217 *tps = rdev_get_drvdata(dev);
- unsigned int rid = rdev_get_id(dev);
+ int rid = rdev_get_id(dev);
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
return -EINVAL;
@@ -82,7 +82,7 @@ static int tps65217_pmic_enable(struct regulator_dev *dev)
static int tps65217_pmic_disable(struct regulator_dev *dev)
{
struct tps65217 *tps = rdev_get_drvdata(dev);
- unsigned int rid = rdev_get_id(dev);
+ int rid = rdev_get_id(dev);
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
return -EINVAL;
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c
index 9effe48c605e..f0a40281b9c1 100644
--- a/drivers/regulator/tps65218-regulator.c
+++ b/drivers/regulator/tps65218-regulator.c
@@ -29,8 +29,8 @@
enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 };
-#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \
- _lr, _nlr, _delay) \
+#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \
+ _lr, _nlr, _delay, _fuv) \
{ \
.name = _name, \
.id = _id, \
@@ -42,14 +42,15 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 };
.vsel_mask = _vm, \
.enable_reg = _er, \
.enable_mask = _em, \
- .volt_table = _t, \
+ .volt_table = NULL, \
.linear_ranges = _lr, \
.n_linear_ranges = _nlr, \
.ramp_delay = _delay, \
+ .fixed_uV = _fuv \
} \
#define TPS65218_INFO(_id, _nm, _min, _max) \
- { \
+ [_id] = { \
.id = _id, \
.name = _nm, \
.min_uV = _min, \
@@ -68,17 +69,17 @@ static const struct regulator_linear_range ldo1_dcdc3_ranges[] = {
static const struct regulator_linear_range dcdc4_ranges[] = {
REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000),
- REGULATOR_LINEAR_RANGE(1550000, 0x10, 0x34, 50000),
+ REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000),
};
static struct tps_info tps65218_pmic_regs[] = {
- TPS65218_INFO(0, "DCDC1", 850000, 167500),
- TPS65218_INFO(1, "DCDC2", 850000, 1675000),
- TPS65218_INFO(2, "DCDC3", 900000, 3400000),
- TPS65218_INFO(3, "DCDC4", 1175000, 3400000),
- TPS65218_INFO(4, "DCDC5", 1000000, 1000000),
- TPS65218_INFO(5, "DCDC6", 1800000, 1800000),
- TPS65218_INFO(6, "LDO1", 900000, 3400000),
+ TPS65218_INFO(DCDC1, "DCDC1", 850000, 167500),
+ TPS65218_INFO(DCDC2, "DCDC2", 850000, 1675000),
+ TPS65218_INFO(DCDC3, "DCDC3", 900000, 3400000),
+ TPS65218_INFO(DCDC4, "DCDC4", 1175000, 3400000),
+ TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000),
+ TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000),
+ TPS65218_INFO(LDO1, "LDO1", 900000, 3400000),
};
#define TPS65218_OF_MATCH(comp, label) \
@@ -127,7 +128,7 @@ static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev,
static int tps65218_pmic_enable(struct regulator_dev *dev)
{
struct tps65218 *tps = rdev_get_drvdata(dev);
- unsigned int rid = rdev_get_id(dev);
+ int rid = rdev_get_id(dev);
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
return -EINVAL;
@@ -141,7 +142,7 @@ static int tps65218_pmic_enable(struct regulator_dev *dev)
static int tps65218_pmic_disable(struct regulator_dev *dev)
{
struct tps65218 *tps = rdev_get_drvdata(dev);
- unsigned int rid = rdev_get_id(dev);
+ int rid = rdev_get_id(dev);
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
return -EINVAL;
@@ -185,34 +186,33 @@ static const struct regulator_desc regulators[] = {
TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64,
TPS65218_REG_CONTROL_DCDC1,
TPS65218_CONTROL_DCDC1_MASK,
- TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL,
- dcdc1_dcdc2_ranges, 2, 4000),
+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN,
+ dcdc1_dcdc2_ranges, 2, 4000, 0),
TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64,
TPS65218_REG_CONTROL_DCDC2,
TPS65218_CONTROL_DCDC2_MASK,
- TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL,
- dcdc1_dcdc2_ranges, 2, 4000),
+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN,
+ dcdc1_dcdc2_ranges, 2, 4000, 0),
TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops,
64, TPS65218_REG_CONTROL_DCDC3,
TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
- TPS65218_ENABLE1_DC3_EN, NULL,
- ldo1_dcdc3_ranges, 2, 0),
+ TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0, 0),
TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops,
53, TPS65218_REG_CONTROL_DCDC4,
TPS65218_CONTROL_DCDC4_MASK,
- TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL,
- dcdc4_ranges, 2, 0),
+ TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN,
+ dcdc4_ranges, 2, 0, 0),
TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops,
1, -1, -1, TPS65218_REG_ENABLE1,
- TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0),
+ TPS65218_ENABLE1_DC5_EN, NULL, 0, 0, 1000000),
TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops,
1, -1, -1, TPS65218_REG_ENABLE1,
- TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0),
+ TPS65218_ENABLE1_DC6_EN, NULL, 0, 0, 1800000),
TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REG_CONTROL_LDO1,
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
- TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges,
- 2, 0),
+ TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges,
+ 2, 0, 0),
};
static int tps65218_regulator_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index 0a3bb3aecd97..ccbb9f150b4e 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -74,6 +74,16 @@ static struct regulator_ops tps6586x_rw_regulator_ops = {
.disable = regulator_disable_regmap,
};
+static struct regulator_ops tps6586x_rw_linear_regulator_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+};
+
static struct regulator_ops tps6586x_ro_regulator_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
@@ -91,48 +101,11 @@ static const unsigned int tps6586x_ldo0_voltages[] = {
1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
};
-static const unsigned int tps6586x_ldo4_voltages[] = {
- 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
- 1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000,
- 2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000,
- 2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000,
-};
-
-#define tps658623_sm2_voltages tps6586x_ldo4_voltages
-
static const unsigned int tps6586x_ldo_voltages[] = {
1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
};
-static const unsigned int tps6586x_sm2_voltages[] = {
- 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000,
- 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000,
- 3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000,
- 4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000,
-};
-
-static int tps658640_sm2_voltages[] = {
- 2150000, 2200000, 2250000, 2300000, 2350000, 2400000, 2450000, 2500000,
- 2550000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, 2900000,
- 2950000, 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000,
- 3350000, 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000,
-};
-
-static const unsigned int tps658643_sm2_voltages[] = {
- 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000,
- 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000,
- 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000, 1600000,
- 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, 1800000,
-};
-
-static const unsigned int tps6586x_dvm_voltages[] = {
- 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000,
- 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000,
- 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
- 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
-};
-
-static int tps658640_rtc_voltages[] = {
+static const unsigned int tps658640_rtc_voltages[] = {
2500000, 2850000, 3100000, 3300000,
};
@@ -159,6 +132,31 @@ static int tps658640_rtc_voltages[] = {
.enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
.enable_bit[1] = (ebit1),
+#define TPS6586X_REGULATOR_LINEAR(_id, _ops, _pin_name, n_volt, min_uv, \
+ uv_step, vreg, shift, nbits, ereg0, \
+ ebit0, ereg1, ebit1, goreg, gobit) \
+ .desc = { \
+ .supply_name = _pin_name, \
+ .name = "REG-" #_id, \
+ .ops = &tps6586x_## _ops ## _regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = TPS6586X_ID_##_id, \
+ .n_voltages = n_volt, \
+ .min_uV = min_uv, \
+ .uV_step = uv_step, \
+ .owner = THIS_MODULE, \
+ .enable_reg = TPS6586X_SUPPLY##ereg0, \
+ .enable_mask = 1 << (ebit0), \
+ .vsel_reg = TPS6586X_##vreg, \
+ .vsel_mask = ((1 << (nbits)) - 1) << (shift), \
+ .apply_reg = (goreg), \
+ .apply_bit = (gobit), \
+ }, \
+ .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \
+ .enable_bit[0] = (ebit0), \
+ .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \
+ .enable_bit[1] = (ebit1),
+
#define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
{ \
@@ -166,6 +164,14 @@ static int tps658640_rtc_voltages[] = {
ereg0, ebit0, ereg1, ebit1, 0, 0) \
}
+#define TPS6586X_LDO_LINEAR(_id, _pname, n_volt, min_uv, uv_step, vreg, \
+ shift, nbits, ereg0, ebit0, ereg1, ebit1) \
+{ \
+ TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt, \
+ min_uv, uv_step, vreg, shift, nbits, \
+ ereg0, ebit0, ereg1, ebit1, 0, 0) \
+}
+
#define TPS6586X_FIXED_LDO(_id, _pname, vdata, vreg, shift, nbits, \
ereg0, ebit0, ereg1, ebit1) \
{ \
@@ -173,11 +179,13 @@ static int tps658640_rtc_voltages[] = {
ereg0, ebit0, ereg1, ebit1, 0, 0) \
}
-#define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
+#define TPS6586X_DVM(_id, _pname, n_volt, min_uv, uv_step, vreg, shift, \
+ nbits, ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
{ \
- TPS6586X_REGULATOR(_id, rw, _pname, vdata, vreg, shift, nbits, \
- ereg0, ebit0, ereg1, ebit1, goreg, gobit) \
+ TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt, \
+ min_uv, uv_step, vreg, shift, nbits, \
+ ereg0, ebit0, ereg1, ebit1, goreg, \
+ gobit) \
}
#define TPS6586X_SYS_REGULATOR() \
@@ -210,24 +218,23 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
ENE, 7),
TPS6586X_LDO(LDO_RTC, "REG-SYS", tps6586x_ldo, SUPPLYV4, 3, 3, V4, 7,
V4, 7),
- TPS6586X_LDO(LDO_1, "vinldo01", tps6586x_dvm, SUPPLYV1, 0, 5, ENC, 1,
- END, 1),
- TPS6586X_LDO(SM_2, "vin-sm2", tps6586x_sm2, SUPPLYV2, 0, 5, ENC, 7,
- END, 7),
-
- TPS6586X_DVM(LDO_2, "vinldo23", tps6586x_dvm, LDO2BV1, 0, 5, ENA, 3,
- ENB, 3, TPS6586X_VCC2, BIT(6)),
- TPS6586X_DVM(LDO_4, "vinldo4", tps6586x_ldo4, LDO4V1, 0, 5, ENC, 3,
- END, 3, TPS6586X_VCC1, BIT(6)),
- TPS6586X_DVM(SM_0, "vin-sm0", tps6586x_dvm, SM0V1, 0, 5, ENA, 1,
- ENB, 1, TPS6586X_VCC1, BIT(2)),
- TPS6586X_DVM(SM_1, "vin-sm1", tps6586x_dvm, SM1V1, 0, 5, ENA, 0,
- ENB, 0, TPS6586X_VCC1, BIT(0)),
+ TPS6586X_LDO_LINEAR(LDO_1, "vinldo01", 32, 725000, 25000, SUPPLYV1,
+ 0, 5, ENC, 1, END, 1),
+ TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 3000000, 50000, SUPPLYV2,
+ 0, 5, ENC, 7, END, 7),
+ TPS6586X_DVM(LDO_2, "vinldo23", 32, 725000, 25000, LDO2BV1, 0, 5,
+ ENA, 3, ENB, 3, TPS6586X_VCC2, BIT(6)),
+ TPS6586X_DVM(LDO_4, "vinldo4", 32, 1700000, 25000, LDO4V1, 0, 5,
+ ENC, 3, END, 3, TPS6586X_VCC1, BIT(6)),
+ TPS6586X_DVM(SM_0, "vin-sm0", 32, 725000, 25000, SM0V1, 0, 5,
+ ENA, 1, ENB, 1, TPS6586X_VCC1, BIT(2)),
+ TPS6586X_DVM(SM_1, "vin-sm1", 32, 725000, 25000, SM1V1, 0, 5,
+ ENA, 0, ENB, 0, TPS6586X_VCC1, BIT(0)),
};
static struct tps6586x_regulator tps658623_regulator[] = {
- TPS6586X_LDO(SM_2, "vin-sm2", tps658623_sm2, SUPPLYV2, 0, 5, ENC, 7,
- END, 7),
+ TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1700000, 25000, SUPPLYV2,
+ 0, 5, ENC, 7, END, 7),
};
static struct tps6586x_regulator tps658640_regulator[] = {
@@ -243,16 +250,16 @@ static struct tps6586x_regulator tps658640_regulator[] = {
ENC, 6, END, 6),
TPS6586X_LDO(LDO_9, "vinldo9", tps6586x_ldo0, SUPPLYV6, 3, 3,
ENE, 7, ENE, 7),
- TPS6586X_LDO(SM_2, "vin-sm2", tps658640_sm2, SUPPLYV2, 0, 5,
- ENC, 7, END, 7),
+ TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 2150000, 50000, SUPPLYV2,
+ 0, 5, ENC, 7, END, 7),
TPS6586X_FIXED_LDO(LDO_RTC, "REG-SYS", tps658640_rtc, SUPPLYV4, 3, 2,
V4, 7, V4, 7),
};
static struct tps6586x_regulator tps658643_regulator[] = {
- TPS6586X_LDO(SM_2, "vin-sm2", tps658643_sm2, SUPPLYV2, 0, 5, ENC, 7,
- END, 7),
+ TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1025000, 25000, SUPPLYV2,
+ 0, 5, ENC, 7, END, 7),
};
/*
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index fed28abef419..0b4f8660fdb4 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1128,7 +1128,7 @@ static int twlreg_probe(struct platform_device *pdev)
if (!initdata)
return -EINVAL;
- info = kmemdup(template, sizeof(*info), GFP_KERNEL);
+ info = devm_kmemdup(&pdev->dev, template, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -1192,7 +1192,6 @@ static int twlreg_probe(struct platform_device *pdev)
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register %s, %ld\n",
info->desc.name, PTR_ERR(rdev));
- kfree(info);
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
@@ -1212,20 +1211,10 @@ static int twlreg_probe(struct platform_device *pdev)
return 0;
}
-static int twlreg_remove(struct platform_device *pdev)
-{
- struct regulator_dev *rdev = platform_get_drvdata(pdev);
- struct twlreg_info *info = rdev->reg_data;
-
- kfree(info);
- return 0;
-}
-
MODULE_ALIAS("platform:twl_reg");
static struct platform_driver twlreg_driver = {
.probe = twlreg_probe,
- .remove = twlreg_remove,
/* NOTE: short name, to work around driver model truncation of
* "twl_regulator.12" (and friends) to "twl_regulator.1".
*/
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c
index ed526a192ce0..fd25e2374d4e 100644
--- a/drivers/rtc/rtc-au1xxx.c
+++ b/drivers/rtc/rtc-au1xxx.c
@@ -32,7 +32,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
unsigned long t;
- t = au_readl(SYS_TOYREAD);
+ t = alchemy_rdsys(AU1000_SYS_TOYREAD);
rtc_time_to_tm(t, tm);
@@ -45,13 +45,12 @@ static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_tm_to_time(tm, &t);
- au_writel(t, SYS_TOYWRITE);
- au_sync();
+ alchemy_wrsys(t, AU1000_SYS_TOYWRITE);
/* wait for the pending register write to succeed. This can
* take up to 6 seconds...
*/
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S)
+ while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S)
msleep(1);
return 0;
@@ -68,7 +67,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev)
unsigned long t;
int ret;
- t = au_readl(SYS_COUNTER_CNTRL);
+ t = alchemy_rdsys(AU1000_SYS_CNTRCTRL);
if (!(t & CNTR_OK)) {
dev_err(&pdev->dev, "counters not working; aborting.\n");
ret = -ENODEV;
@@ -78,10 +77,10 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev)
ret = -ETIMEDOUT;
/* set counter0 tickrate to 1Hz if necessary */
- if (au_readl(SYS_TOYTRIM) != 32767) {
+ if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) {
/* wait until hardware gives access to TRIM register */
t = 0x00100000;
- while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t)
+ while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T0S) && --t)
msleep(1);
if (!t) {
@@ -93,12 +92,11 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev)
}
/* set 1Hz TOY tick rate */
- au_writel(32767, SYS_TOYTRIM);
- au_sync();
+ alchemy_wrsys(32767, AU1000_SYS_TOYTRIM);
}
/* wait until the hardware allows writes to the counter reg */
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S)
+ while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S)
msleep(1);
rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx",
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
index 595393098b09..731ed1a97f59 100644
--- a/drivers/rtc/rtc-da9063.c
+++ b/drivers/rtc/rtc-da9063.c
@@ -29,6 +29,8 @@
#define YEARS_FROM_DA9063(year) ((year) + 100)
#define MONTHS_FROM_DA9063(month) ((month) - 1)
+#define RTC_ALARM_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1)
+
#define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1)
#define RTC_SEC 0
#define RTC_MIN 1
@@ -42,6 +44,10 @@ struct da9063_rtc {
struct da9063 *hw;
struct rtc_time alarm_time;
bool rtc_sync;
+ int alarm_year;
+ int alarm_start;
+ int alarm_len;
+ int data_start;
};
static void da9063_data_to_tm(u8 *data, struct rtc_time *tm)
@@ -83,7 +89,7 @@ static int da9063_rtc_stop_alarm(struct device *dev)
{
struct da9063_rtc *rtc = dev_get_drvdata(dev);
- return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
+ return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year,
DA9063_ALARM_ON, 0);
}
@@ -91,7 +97,7 @@ static int da9063_rtc_start_alarm(struct device *dev)
{
struct da9063_rtc *rtc = dev_get_drvdata(dev);
- return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
+ return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year,
DA9063_ALARM_ON, DA9063_ALARM_ON);
}
@@ -151,8 +157,9 @@ static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
int ret;
unsigned int val;
- ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_ALARM_S,
- &data[RTC_SEC], RTC_DATA_LEN);
+ data[RTC_SEC] = 0;
+ ret = regmap_bulk_read(rtc->hw->regmap, rtc->alarm_start,
+ &data[rtc->data_start], rtc->alarm_len);
if (ret < 0)
return ret;
@@ -186,14 +193,14 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
- ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_ALARM_S,
- data, RTC_DATA_LEN);
+ ret = regmap_bulk_write(rtc->hw->regmap, rtc->alarm_start,
+ &data[rtc->data_start], rtc->alarm_len);
if (ret < 0) {
dev_err(dev, "Failed to write alarm: %d\n", ret);
return ret;
}
- rtc->alarm_time = alrm->time;
+ da9063_data_to_tm(data, &rtc->alarm_time);
if (alrm->enabled) {
ret = da9063_rtc_start_alarm(dev);
@@ -218,7 +225,7 @@ static irqreturn_t da9063_alarm_event(int irq, void *data)
{
struct da9063_rtc *rtc = data;
- regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y,
+ regmap_update_bits(rtc->hw->regmap, rtc->alarm_year,
DA9063_ALARM_ON, 0);
rtc->rtc_sync = true;
@@ -257,7 +264,23 @@ static int da9063_rtc_probe(struct platform_device *pdev)
goto err;
}
- ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S,
+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ if (da9063->variant_code == PMIC_DA9063_AD) {
+ rtc->alarm_year = DA9063_AD_REG_ALARM_Y;
+ rtc->alarm_start = DA9063_AD_REG_ALARM_MI;
+ rtc->alarm_len = RTC_ALARM_DATA_LEN;
+ rtc->data_start = RTC_MIN;
+ } else {
+ rtc->alarm_year = DA9063_BB_REG_ALARM_Y;
+ rtc->alarm_start = DA9063_BB_REG_ALARM_S;
+ rtc->alarm_len = RTC_DATA_LEN;
+ rtc->data_start = RTC_SEC;
+ }
+
+ ret = regmap_update_bits(da9063->regmap, rtc->alarm_start,
DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM,
0);
if (ret < 0) {
@@ -265,7 +288,7 @@ static int da9063_rtc_probe(struct platform_device *pdev)
goto err;
}
- ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S,
+ ret = regmap_update_bits(da9063->regmap, rtc->alarm_start,
DA9063_ALARM_STATUS_ALARM,
DA9063_ALARM_STATUS_ALARM);
if (ret < 0) {
@@ -273,25 +296,22 @@ static int da9063_rtc_probe(struct platform_device *pdev)
goto err;
}
- ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_Y,
+ ret = regmap_update_bits(da9063->regmap, rtc->alarm_year,
DA9063_TICK_ON, 0);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to disable TICKs\n");
goto err;
}
- ret = regmap_bulk_read(da9063->regmap, DA9063_REG_ALARM_S,
- data, RTC_DATA_LEN);
+ data[RTC_SEC] = 0;
+ ret = regmap_bulk_read(da9063->regmap, rtc->alarm_start,
+ &data[rtc->data_start], rtc->alarm_len);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n",
ret);
goto err;
}
- rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
- if (!rtc)
- return -ENOMEM;
-
platform_set_drvdata(pdev, rtc);
irq_alarm = platform_get_irq_byname(pdev, "ALARM");
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 9efe118a28ba..d20a7f0786eb 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -492,16 +492,11 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
return ret;
}
-static struct regmap_config max77686_rtc_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-};
-
static int max77686_rtc_probe(struct platform_device *pdev)
{
struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent);
struct max77686_rtc_info *info;
- int ret, virq;
+ int ret;
dev_info(&pdev->dev, "%s\n", __func__);
@@ -514,14 +509,7 @@ static int max77686_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev;
info->max77686 = max77686;
info->rtc = max77686->rtc;
- info->max77686->rtc_regmap = devm_regmap_init_i2c(info->max77686->rtc,
- &max77686_rtc_regmap_config);
- if (IS_ERR(info->max77686->rtc_regmap)) {
- ret = PTR_ERR(info->max77686->rtc_regmap);
- dev_err(info->max77686->dev, "Failed to allocate register map: %d\n",
- ret);
- return ret;
- }
+
platform_set_drvdata(pdev, info);
ret = max77686_rtc_init_reg(info);
@@ -550,15 +538,16 @@ static int max77686_rtc_probe(struct platform_device *pdev)
ret = -EINVAL;
goto err_rtc;
}
- virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1);
- if (!virq) {
+
+ info->virq = regmap_irq_get_virq(max77686->rtc_irq_data,
+ MAX77686_RTCIRQ_RTCA1);
+ if (!info->virq) {
ret = -ENXIO;
goto err_rtc;
}
- info->virq = virq;
- ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
- max77686_rtc_alarm_irq, 0, "rtc-alarm0", info);
+ ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL,
+ max77686_rtc_alarm_irq, 0, "rtc-alarm1", info);
if (ret < 0)
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->virq, ret);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 1eef0f586950..5df05f26b7d9 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -42,8 +42,10 @@
* SECTION: exported variables of dasd.c
*/
debug_info_t *dasd_debug_area;
+EXPORT_SYMBOL(dasd_debug_area);
static struct dentry *dasd_debugfs_root_entry;
struct dasd_discipline *dasd_diag_discipline_pointer;
+EXPORT_SYMBOL(dasd_diag_discipline_pointer);
void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
MODULE_AUTHOR("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
@@ -164,6 +166,7 @@ struct dasd_block *dasd_alloc_block(void)
return block;
}
+EXPORT_SYMBOL_GPL(dasd_alloc_block);
/*
* Free memory of a device structure.
@@ -172,6 +175,7 @@ void dasd_free_block(struct dasd_block *block)
{
kfree(block);
}
+EXPORT_SYMBOL_GPL(dasd_free_block);
/*
* Make a new device known to the system.
@@ -281,10 +285,15 @@ static int dasd_state_basic_to_known(struct dasd_device *device)
{
int rc;
+ if (device->discipline->basic_to_known) {
+ rc = device->discipline->basic_to_known(device);
+ if (rc)
+ return rc;
+ }
+
if (device->block) {
dasd_profile_exit(&device->block->profile);
- if (device->block->debugfs_dentry)
- debugfs_remove(device->block->debugfs_dentry);
+ debugfs_remove(device->block->debugfs_dentry);
dasd_gendisk_free(device->block);
dasd_block_clear_timer(device->block);
}
@@ -293,9 +302,7 @@ static int dasd_state_basic_to_known(struct dasd_device *device)
return rc;
dasd_device_clear_timer(device);
dasd_profile_exit(&device->profile);
- if (device->debugfs_dentry)
- debugfs_remove(device->debugfs_dentry);
-
+ debugfs_remove(device->debugfs_dentry);
DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device);
if (device->debug_area != NULL) {
debug_unregister(device->debug_area);
@@ -374,11 +381,6 @@ static int dasd_state_ready_to_basic(struct dasd_device *device)
{
int rc;
- if (device->discipline->ready_to_basic) {
- rc = device->discipline->ready_to_basic(device);
- if (rc)
- return rc;
- }
device->state = DASD_STATE_BASIC;
if (device->block) {
struct dasd_block *block = device->block;
@@ -579,6 +581,7 @@ void dasd_kick_device(struct dasd_device *device)
/* queue call to dasd_kick_device to the kernel event daemon. */
schedule_work(&device->kick_work);
}
+EXPORT_SYMBOL(dasd_kick_device);
/*
* dasd_reload_device will schedule a call do do_reload_device to the kernel
@@ -639,6 +642,7 @@ void dasd_set_target_state(struct dasd_device *device, int target)
mutex_unlock(&device->state_mutex);
dasd_put_device(device);
}
+EXPORT_SYMBOL(dasd_set_target_state);
/*
* Enable devices with device numbers in [from..to].
@@ -661,6 +665,7 @@ void dasd_enable_device(struct dasd_device *device)
if (device->discipline->kick_validate)
device->discipline->kick_validate(device);
}
+EXPORT_SYMBOL(dasd_enable_device);
/*
* SECTION: device operation (interrupt handler, start i/o, term i/o ...)
@@ -972,37 +977,37 @@ 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, "histogram_sectors ");
+ seq_puts(m, "histogram_sectors ");
dasd_stats_array(m, data->dasd_io_secs);
- seq_printf(m, "histogram_io_times ");
+ seq_puts(m, "histogram_io_times ");
dasd_stats_array(m, data->dasd_io_times);
- seq_printf(m, "histogram_io_times_weighted ");
+ seq_puts(m, "histogram_io_times_weighted ");
dasd_stats_array(m, data->dasd_io_timps);
- seq_printf(m, "histogram_time_build_to_ssch ");
+ seq_puts(m, "histogram_time_build_to_ssch ");
dasd_stats_array(m, data->dasd_io_time1);
- seq_printf(m, "histogram_time_ssch_to_irq ");
+ seq_puts(m, "histogram_time_ssch_to_irq ");
dasd_stats_array(m, data->dasd_io_time2);
- seq_printf(m, "histogram_time_ssch_to_irq_weighted ");
+ seq_puts(m, "histogram_time_ssch_to_irq_weighted ");
dasd_stats_array(m, data->dasd_io_time2ps);
- seq_printf(m, "histogram_time_irq_to_end ");
+ seq_puts(m, "histogram_time_irq_to_end ");
dasd_stats_array(m, data->dasd_io_time3);
- seq_printf(m, "histogram_ccw_queue_length ");
+ seq_puts(m, "histogram_ccw_queue_length ");
dasd_stats_array(m, data->dasd_io_nr_req);
seq_printf(m, "total_read_requests %u\n", data->dasd_read_reqs);
seq_printf(m, "total_read_sectors %u\n", data->dasd_read_sects);
seq_printf(m, "total_read_pav %u\n", data->dasd_read_alias);
seq_printf(m, "total_read_hpf %u\n", data->dasd_read_tpm);
- seq_printf(m, "histogram_read_sectors ");
+ seq_puts(m, "histogram_read_sectors ");
dasd_stats_array(m, data->dasd_read_secs);
- seq_printf(m, "histogram_read_times ");
+ seq_puts(m, "histogram_read_times ");
dasd_stats_array(m, data->dasd_read_times);
- seq_printf(m, "histogram_read_time_build_to_ssch ");
+ seq_puts(m, "histogram_read_time_build_to_ssch ");
dasd_stats_array(m, data->dasd_read_time1);
- seq_printf(m, "histogram_read_time_ssch_to_irq ");
+ seq_puts(m, "histogram_read_time_ssch_to_irq ");
dasd_stats_array(m, data->dasd_read_time2);
- seq_printf(m, "histogram_read_time_irq_to_end ");
+ seq_puts(m, "histogram_read_time_irq_to_end ");
dasd_stats_array(m, data->dasd_read_time3);
- seq_printf(m, "histogram_read_ccw_queue_length ");
+ seq_puts(m, "histogram_read_ccw_queue_length ");
dasd_stats_array(m, data->dasd_read_nr_req);
}
@@ -1016,7 +1021,7 @@ static int dasd_stats_show(struct seq_file *m, void *v)
data = profile->data;
if (!data) {
spin_unlock_bh(&profile->lock);
- seq_printf(m, "disabled\n");
+ seq_puts(m, "disabled\n");
return 0;
}
dasd_stats_seq_print(m, data);
@@ -1069,7 +1074,7 @@ static ssize_t dasd_stats_global_write(struct file *file,
static int dasd_stats_global_show(struct seq_file *m, void *v)
{
if (!dasd_global_profile_level) {
- seq_printf(m, "disabled\n");
+ seq_puts(m, "disabled\n");
return 0;
}
dasd_stats_seq_print(m, &dasd_global_profile_data);
@@ -1111,23 +1116,17 @@ static void dasd_profile_init(struct dasd_profile *profile,
static void dasd_profile_exit(struct dasd_profile *profile)
{
dasd_profile_off(profile);
- if (profile->dentry) {
- debugfs_remove(profile->dentry);
- profile->dentry = NULL;
- }
+ debugfs_remove(profile->dentry);
+ profile->dentry = NULL;
}
static void dasd_statistics_removeroot(void)
{
dasd_global_profile_level = DASD_PROFILE_OFF;
- if (dasd_global_profile_dentry) {
- debugfs_remove(dasd_global_profile_dentry);
- dasd_global_profile_dentry = NULL;
- }
- if (dasd_debugfs_global_entry)
- debugfs_remove(dasd_debugfs_global_entry);
- if (dasd_debugfs_root_entry)
- debugfs_remove(dasd_debugfs_root_entry);
+ debugfs_remove(dasd_global_profile_dentry);
+ dasd_global_profile_dentry = NULL;
+ debugfs_remove(dasd_debugfs_global_entry);
+ debugfs_remove(dasd_debugfs_root_entry);
}
static void dasd_statistics_createroot(void)
@@ -1178,7 +1177,7 @@ static void dasd_statistics_removeroot(void)
int dasd_stats_generic_show(struct seq_file *m, void *v)
{
- seq_printf(m, "Statistics are not activated in this kernel\n");
+ seq_puts(m, "Statistics are not activated in this kernel\n");
return 0;
}
@@ -1243,6 +1242,7 @@ struct dasd_ccw_req *dasd_kmalloc_request(int magic, int cplength,
dasd_get_device(device);
return cqr;
}
+EXPORT_SYMBOL(dasd_kmalloc_request);
struct dasd_ccw_req *dasd_smalloc_request(int magic, int cplength,
int datasize,
@@ -1282,6 +1282,7 @@ struct dasd_ccw_req *dasd_smalloc_request(int magic, int cplength,
dasd_get_device(device);
return cqr;
}
+EXPORT_SYMBOL(dasd_smalloc_request);
/*
* Free memory of a channel program. This function needs to free all the
@@ -1304,6 +1305,7 @@ void dasd_kfree_request(struct dasd_ccw_req *cqr, struct dasd_device *device)
kfree(cqr);
dasd_put_device(device);
}
+EXPORT_SYMBOL(dasd_kfree_request);
void dasd_sfree_request(struct dasd_ccw_req *cqr, struct dasd_device *device)
{
@@ -1314,6 +1316,7 @@ void dasd_sfree_request(struct dasd_ccw_req *cqr, struct dasd_device *device)
spin_unlock_irqrestore(&device->mem_lock, flags);
dasd_put_device(device);
}
+EXPORT_SYMBOL(dasd_sfree_request);
/*
* Check discipline magic in cqr.
@@ -1391,6 +1394,7 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
dasd_schedule_device_bh(device);
return rc;
}
+EXPORT_SYMBOL(dasd_term_IO);
/*
* Start the i/o. This start_IO can fail if the channel is really busy.
@@ -1509,6 +1513,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr->intrc = rc;
return rc;
}
+EXPORT_SYMBOL(dasd_start_IO);
/*
* Timeout function for dasd devices. This is used for different purposes
@@ -1541,6 +1546,7 @@ void dasd_device_set_timer(struct dasd_device *device, int expires)
else
mod_timer(&device->timer, jiffies + expires);
}
+EXPORT_SYMBOL(dasd_device_set_timer);
/*
* Clear timeout for a device.
@@ -1549,6 +1555,7 @@ void dasd_device_clear_timer(struct dasd_device *device)
{
del_timer(&device->timer);
}
+EXPORT_SYMBOL(dasd_device_clear_timer);
static void dasd_handle_killed_request(struct ccw_device *cdev,
unsigned long intparm)
@@ -1601,6 +1608,7 @@ void dasd_generic_handle_state_change(struct dasd_device *device)
if (device->block)
dasd_schedule_block_bh(device->block);
}
+EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change);
/*
* Interrupt handler for "normal" ssch-io based dasd devices.
@@ -1667,8 +1675,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_CLEARED;
+ if (cqr->callback_data == DASD_SLEEPON_START_TAG)
+ cqr->callback_data = DASD_SLEEPON_END_TAG;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
+ wake_up(&generic_waitq);
dasd_schedule_device_bh(device);
return;
}
@@ -1722,6 +1733,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
dasd_device_clear_timer(device);
dasd_schedule_device_bh(device);
}
+EXPORT_SYMBOL(dasd_int_handler);
enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb)
{
@@ -1995,6 +2007,7 @@ finished:
__dasd_device_process_final_queue(device, &flush_queue);
return rc;
}
+EXPORT_SYMBOL_GPL(dasd_flush_device_queue);
/*
* Acquire the device lock and process queues for the device.
@@ -2034,6 +2047,7 @@ void dasd_schedule_device_bh(struct dasd_device *device)
dasd_get_device(device);
tasklet_hi_schedule(&device->tasklet);
}
+EXPORT_SYMBOL(dasd_schedule_device_bh);
void dasd_device_set_stop_bits(struct dasd_device *device, int bits)
{
@@ -2066,6 +2080,7 @@ void dasd_add_request_head(struct dasd_ccw_req *cqr)
dasd_schedule_device_bh(device);
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
}
+EXPORT_SYMBOL(dasd_add_request_head);
/*
* Queue a request to the tail of the device ccw_queue.
@@ -2084,6 +2099,7 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
dasd_schedule_device_bh(device);
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
}
+EXPORT_SYMBOL(dasd_add_request_tail);
/*
* Wakeup helper for the 'sleep_on' functions.
@@ -2291,13 +2307,27 @@ retry:
rc = 0;
list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) {
- if (__dasd_sleep_on_erp(cqr))
- rc = 1;
+ /*
+ * for alias devices simplify error recovery and
+ * return to upper layer
+ */
+ if (cqr->startdev != cqr->basedev &&
+ (cqr->status == DASD_CQR_TERMINATED ||
+ cqr->status == DASD_CQR_NEED_ERP))
+ return -EAGAIN;
+ else {
+ /* normal recovery for basedev IO */
+ if (__dasd_sleep_on_erp(cqr)) {
+ if (!cqr->status == DASD_CQR_TERMINATED &&
+ !cqr->status == DASD_CQR_NEED_ERP)
+ break;
+ rc = 1;
+ }
+ }
}
if (rc)
goto retry;
-
return 0;
}
@@ -2309,6 +2339,7 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr)
{
return _dasd_sleep_on(cqr, 0);
}
+EXPORT_SYMBOL(dasd_sleep_on);
/*
* Start requests from a ccw_queue and wait for their completion.
@@ -2327,6 +2358,7 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
{
return _dasd_sleep_on(cqr, 1);
}
+EXPORT_SYMBOL(dasd_sleep_on_interruptible);
/*
* Whoa nelly now it gets really hairy. For some functions (e.g. steal lock
@@ -2401,6 +2433,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
return rc;
}
+EXPORT_SYMBOL(dasd_sleep_on_immediatly);
/*
* Cancels a request that was started with dasd_sleep_on_req.
@@ -2423,6 +2456,8 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
case DASD_CQR_QUEUED:
/* request was not started - just set to cleared */
cqr->status = DASD_CQR_CLEARED;
+ if (cqr->callback_data == DASD_SLEEPON_START_TAG)
+ cqr->callback_data = DASD_SLEEPON_END_TAG;
break;
case DASD_CQR_IN_IO:
/* request in IO - terminate IO and release again */
@@ -2442,6 +2477,7 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
dasd_schedule_device_bh(device);
return rc;
}
+EXPORT_SYMBOL(dasd_cancel_req);
/*
* SECTION: Operations of the dasd_block layer.
@@ -2475,6 +2511,7 @@ void dasd_block_set_timer(struct dasd_block *block, int expires)
else
mod_timer(&block->timer, jiffies + expires);
}
+EXPORT_SYMBOL(dasd_block_set_timer);
/*
* Clear timeout for a dasd_block.
@@ -2483,6 +2520,7 @@ void dasd_block_clear_timer(struct dasd_block *block)
{
del_timer(&block->timer);
}
+EXPORT_SYMBOL(dasd_block_clear_timer);
/*
* Process finished error recovery ccw.
@@ -2864,6 +2902,7 @@ void dasd_schedule_block_bh(struct dasd_block *block)
dasd_get_device(block->base);
tasklet_hi_schedule(&block->tasklet);
}
+EXPORT_SYMBOL(dasd_schedule_block_bh);
/*
@@ -3202,8 +3241,8 @@ static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
ret = ccw_device_set_online(cdev);
if (ret)
- pr_warning("%s: Setting the DASD online failed with rc=%d\n",
- dev_name(&cdev->dev), ret);
+ pr_warn("%s: Setting the DASD online failed with rc=%d\n",
+ dev_name(&cdev->dev), ret);
}
/*
@@ -3234,6 +3273,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
async_schedule(dasd_generic_auto_online, cdev);
return 0;
}
+EXPORT_SYMBOL_GPL(dasd_generic_probe);
/*
* This will one day be called from a global not_oper handler.
@@ -3276,6 +3316,7 @@ void dasd_generic_remove(struct ccw_device *cdev)
dasd_remove_sysfs_files(cdev);
}
+EXPORT_SYMBOL_GPL(dasd_generic_remove);
/*
* Activate a device. This is called from dasd_{eckd,fba}_probe() when either
@@ -3298,9 +3339,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
discipline = base_discipline;
if (device->features & DASD_FEATURE_USEDIAG) {
if (!dasd_diag_discipline_pointer) {
- pr_warning("%s Setting the DASD online failed because "
- "of missing DIAG discipline\n",
- dev_name(&cdev->dev));
+ pr_warn("%s Setting the DASD online failed because of missing DIAG discipline\n",
+ dev_name(&cdev->dev));
dasd_delete_device(device);
return -ENODEV;
}
@@ -3321,9 +3361,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
/* check_device will allocate block device if necessary */
rc = discipline->check_device(device);
if (rc) {
- pr_warning("%s Setting the DASD online with discipline %s "
- "failed with rc=%i\n",
- dev_name(&cdev->dev), discipline->name, rc);
+ pr_warn("%s Setting the DASD online with discipline %s failed with rc=%i\n",
+ dev_name(&cdev->dev), discipline->name, rc);
module_put(discipline->owner);
module_put(base_discipline->owner);
dasd_delete_device(device);
@@ -3332,8 +3371,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_set_target_state(device, DASD_STATE_ONLINE);
if (device->state <= DASD_STATE_KNOWN) {
- pr_warning("%s Setting the DASD online failed because of a "
- "missing discipline\n", dev_name(&cdev->dev));
+ pr_warn("%s Setting the DASD online failed because of a missing discipline\n",
+ dev_name(&cdev->dev));
rc = -ENODEV;
dasd_set_target_state(device, DASD_STATE_NEW);
if (device->block)
@@ -3348,6 +3387,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_put_device(device);
return rc;
}
+EXPORT_SYMBOL_GPL(dasd_generic_set_online);
int dasd_generic_set_offline(struct ccw_device *cdev)
{
@@ -3371,13 +3411,11 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
open_count = atomic_read(&device->block->open_count);
if (open_count > max_count) {
if (open_count > 0)
- pr_warning("%s: The DASD cannot be set offline "
- "with open count %i\n",
- dev_name(&cdev->dev), open_count);
+ pr_warn("%s: The DASD cannot be set offline with open count %i\n",
+ dev_name(&cdev->dev), open_count);
else
- pr_warning("%s: The DASD cannot be set offline "
- "while it is in use\n",
- dev_name(&cdev->dev));
+ pr_warn("%s: The DASD cannot be set offline while it is in use\n",
+ dev_name(&cdev->dev));
clear_bit(DASD_FLAG_OFFLINE, &device->flags);
dasd_put_device(device);
return -EBUSY;
@@ -3451,6 +3489,7 @@ interrupted:
dasd_put_device(device);
return rc;
}
+EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
int dasd_generic_last_path_gone(struct dasd_device *device)
{
@@ -3492,6 +3531,10 @@ int dasd_generic_path_operational(struct dasd_device *device)
dasd_schedule_device_bh(device);
if (device->block)
dasd_schedule_block_bh(device->block);
+
+ if (!device->stopped)
+ wake_up(&generic_waitq);
+
return 1;
}
EXPORT_SYMBOL_GPL(dasd_generic_path_operational);
@@ -3523,6 +3566,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
dasd_put_device(device);
return ret;
}
+EXPORT_SYMBOL_GPL(dasd_generic_notify);
void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
{
@@ -3872,39 +3916,3 @@ failed:
module_init(dasd_init);
module_exit(dasd_exit);
-
-EXPORT_SYMBOL(dasd_debug_area);
-EXPORT_SYMBOL(dasd_diag_discipline_pointer);
-
-EXPORT_SYMBOL(dasd_add_request_head);
-EXPORT_SYMBOL(dasd_add_request_tail);
-EXPORT_SYMBOL(dasd_cancel_req);
-EXPORT_SYMBOL(dasd_device_clear_timer);
-EXPORT_SYMBOL(dasd_block_clear_timer);
-EXPORT_SYMBOL(dasd_enable_device);
-EXPORT_SYMBOL(dasd_int_handler);
-EXPORT_SYMBOL(dasd_kfree_request);
-EXPORT_SYMBOL(dasd_kick_device);
-EXPORT_SYMBOL(dasd_kmalloc_request);
-EXPORT_SYMBOL(dasd_schedule_device_bh);
-EXPORT_SYMBOL(dasd_schedule_block_bh);
-EXPORT_SYMBOL(dasd_set_target_state);
-EXPORT_SYMBOL(dasd_device_set_timer);
-EXPORT_SYMBOL(dasd_block_set_timer);
-EXPORT_SYMBOL(dasd_sfree_request);
-EXPORT_SYMBOL(dasd_sleep_on);
-EXPORT_SYMBOL(dasd_sleep_on_immediatly);
-EXPORT_SYMBOL(dasd_sleep_on_interruptible);
-EXPORT_SYMBOL(dasd_smalloc_request);
-EXPORT_SYMBOL(dasd_start_IO);
-EXPORT_SYMBOL(dasd_term_IO);
-
-EXPORT_SYMBOL_GPL(dasd_generic_probe);
-EXPORT_SYMBOL_GPL(dasd_generic_remove);
-EXPORT_SYMBOL_GPL(dasd_generic_notify);
-EXPORT_SYMBOL_GPL(dasd_generic_set_online);
-EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
-EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change);
-EXPORT_SYMBOL_GPL(dasd_flush_device_queue);
-EXPORT_SYMBOL_GPL(dasd_alloc_block);
-EXPORT_SYMBOL_GPL(dasd_free_block);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 2e8e0755070b..51dea7baf02c 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2039,7 +2039,7 @@ static int dasd_eckd_online_to_ready(struct dasd_device *device)
return 0;
};
-static int dasd_eckd_ready_to_basic(struct dasd_device *device)
+static int dasd_eckd_basic_to_known(struct dasd_device *device)
{
return dasd_alias_remove_device(device);
};
@@ -2061,11 +2061,12 @@ dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo)
static struct dasd_ccw_req *
dasd_eckd_build_format(struct dasd_device *base,
- struct format_data_t *fdata)
+ struct format_data_t *fdata,
+ int enable_pav)
{
struct dasd_eckd_private *base_priv;
struct dasd_eckd_private *start_priv;
- struct dasd_device *startdev;
+ struct dasd_device *startdev = NULL;
struct dasd_ccw_req *fcp;
struct eckd_count *ect;
struct ch_t address;
@@ -2079,7 +2080,9 @@ dasd_eckd_build_format(struct dasd_device *base,
int nr_tracks;
int use_prefix;
- startdev = dasd_alias_get_start_dev(base);
+ if (enable_pav)
+ startdev = dasd_alias_get_start_dev(base);
+
if (!startdev)
startdev = base;
@@ -2309,6 +2312,7 @@ dasd_eckd_build_format(struct dasd_device *base,
fcp->startdev = startdev;
fcp->memdev = startdev;
+ fcp->basedev = base;
fcp->retries = 256;
fcp->expires = startdev->default_expires * HZ;
fcp->buildclk = get_tod_clock();
@@ -2319,7 +2323,8 @@ dasd_eckd_build_format(struct dasd_device *base,
static int
dasd_eckd_format_device(struct dasd_device *base,
- struct format_data_t *fdata)
+ struct format_data_t *fdata,
+ int enable_pav)
{
struct dasd_ccw_req *cqr, *n;
struct dasd_block *block;
@@ -2327,7 +2332,7 @@ dasd_eckd_format_device(struct dasd_device *base,
struct list_head format_queue;
struct dasd_device *device;
int old_stop, format_step;
- int step, rc = 0;
+ int step, rc = 0, sleep_rc;
block = base->block;
private = (struct dasd_eckd_private *) base->private;
@@ -2361,11 +2366,11 @@ dasd_eckd_format_device(struct dasd_device *base,
}
INIT_LIST_HEAD(&format_queue);
- old_stop = fdata->stop_unit;
+ old_stop = fdata->stop_unit;
while (fdata->start_unit <= 1) {
fdata->stop_unit = fdata->start_unit;
- cqr = dasd_eckd_build_format(base, fdata);
+ cqr = dasd_eckd_build_format(base, fdata, enable_pav);
list_add(&cqr->blocklist, &format_queue);
fdata->stop_unit = old_stop;
@@ -2383,7 +2388,7 @@ retry:
if (step > format_step)
fdata->stop_unit = fdata->start_unit + format_step - 1;
- cqr = dasd_eckd_build_format(base, fdata);
+ cqr = dasd_eckd_build_format(base, fdata, enable_pav);
if (IS_ERR(cqr)) {
if (PTR_ERR(cqr) == -ENOMEM) {
/*
@@ -2403,7 +2408,7 @@ retry:
}
sleep:
- dasd_sleep_on_queue(&format_queue);
+ sleep_rc = dasd_sleep_on_queue(&format_queue);
list_for_each_entry_safe(cqr, n, &format_queue, blocklist) {
device = cqr->startdev;
@@ -2415,6 +2420,9 @@ sleep:
private->count--;
}
+ if (sleep_rc)
+ return sleep_rc;
+
/*
* in case of ENOMEM we need to retry after
* first requests are finished
@@ -4511,7 +4519,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.verify_path = dasd_eckd_verify_path,
.basic_to_ready = dasd_eckd_basic_to_ready,
.online_to_ready = dasd_eckd_online_to_ready,
- .ready_to_basic = dasd_eckd_ready_to_basic,
+ .basic_to_known = dasd_eckd_basic_to_known,
.fill_geometry = dasd_eckd_fill_geometry,
.start_IO = dasd_start_IO,
.term_IO = dasd_term_IO,
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 690001af0d09..c20170166909 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -175,6 +175,7 @@ struct dasd_ccw_req {
struct dasd_block *block; /* the originating block device */
struct dasd_device *memdev; /* the device used to allocate this */
struct dasd_device *startdev; /* device the request is started on */
+ struct dasd_device *basedev; /* base device if no block->base */
void *cpaddr; /* address of ccw or tcw */
unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */
char status; /* status of this request */
@@ -304,7 +305,7 @@ struct dasd_discipline {
*/
int (*basic_to_ready) (struct dasd_device *);
int (*online_to_ready) (struct dasd_device *);
- int (*ready_to_basic) (struct dasd_device *);
+ int (*basic_to_known)(struct dasd_device *);
/* (struct dasd_device *);
* Device operation functions. build_cp creates a ccw chain for
@@ -321,7 +322,7 @@ struct dasd_discipline {
int (*term_IO) (struct dasd_ccw_req *);
void (*handle_terminated_request) (struct dasd_ccw_req *);
int (*format_device) (struct dasd_device *,
- struct format_data_t *);
+ struct format_data_t *, int enable_pav);
int (*free_cp) (struct dasd_ccw_req *, struct request *);
/*
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 25a0f2f8b0b9..02837d0ad942 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -203,7 +203,9 @@ static int
dasd_format(struct dasd_block *block, struct format_data_t *fdata)
{
struct dasd_device *base;
- int rc;
+ int enable_pav = 1;
+ int rc, retries;
+ int start, stop;
base = block->base;
if (base->discipline->format_device == NULL)
@@ -231,11 +233,30 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata)
bdput(bdev);
}
- rc = base->discipline->format_device(base, fdata);
- if (rc)
- return rc;
-
- return 0;
+ retries = 255;
+ /* backup start- and endtrack for retries */
+ start = fdata->start_unit;
+ stop = fdata->stop_unit;
+ do {
+ rc = base->discipline->format_device(base, fdata, enable_pav);
+ if (rc) {
+ if (rc == -EAGAIN) {
+ retries--;
+ /* disable PAV in case of errors */
+ enable_pav = 0;
+ fdata->start_unit = start;
+ fdata->stop_unit = stop;
+ } else
+ return rc;
+ } else
+ /* success */
+ break;
+ } while (retries);
+
+ if (!retries)
+ return -EIO;
+ else
+ return 0;
}
/*
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 5af7f0bd6125..a6d47e5eee9e 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data)
unsigned long flags;
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
- if (raw->flags & RAW3215_TIMER_RUNS) {
- del_timer(&raw->timer);
- raw->flags &= ~RAW3215_TIMER_RUNS;
- if (!(raw->port.flags & ASYNC_SUSPENDED)) {
- raw3215_mk_write_req(raw);
- raw3215_start_io(raw);
+ raw->flags &= ~RAW3215_TIMER_RUNS;
+ if (!(raw->port.flags & ASYNC_SUSPENDED)) {
+ raw3215_mk_write_req(raw);
+ raw3215_start_io(raw);
+ if ((raw->queued_read || raw->queued_write) &&
+ !(raw->flags & RAW3215_WORKING) &&
+ !(raw->flags & RAW3215_TIMER_RUNS)) {
+ raw->timer.expires = RAW3215_TIMEOUT + jiffies;
+ add_timer(&raw->timer);
+ raw->flags |= RAW3215_TIMER_RUNS;
}
}
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
(raw->flags & RAW3215_FLUSHING)) {
/* execute write requests bigger than minimum size */
raw3215_start_io(raw);
- if (raw->flags & RAW3215_TIMER_RUNS) {
- del_timer(&raw->timer);
- raw->flags &= ~RAW3215_TIMER_RUNS;
- }
- } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
- /* delay small writes */
- raw->timer.expires = RAW3215_TIMEOUT + jiffies;
- add_timer(&raw->timer);
- raw->flags |= RAW3215_TIMER_RUNS;
}
}
+ if ((raw->queued_read || raw->queued_write) &&
+ !(raw->flags & RAW3215_WORKING) &&
+ !(raw->flags & RAW3215_TIMER_RUNS)) {
+ raw->timer.expires = RAW3215_TIMEOUT + jiffies;
+ add_timer(&raw->timer);
+ raw->flags |= RAW3215_TIMER_RUNS;
+ }
}
/*
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 15b3459f8656..220acb4cbee5 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -633,7 +633,6 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
} else
raw3270_writesf_readpart(rp);
memset(&rp->init_reset, 0, sizeof(rp->init_reset));
- memset(&rp->init_data, 0, sizeof(rp->init_data));
}
static int
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index f5f4a91fab44..f76bff68d1de 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -17,6 +17,8 @@
#include "qdio.h"
#include "qdio_debug.h"
+#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
+
static struct kmem_cache *qdio_q_cache;
static struct kmem_cache *qdio_aob_cache;
@@ -32,6 +34,57 @@ void qdio_release_aob(struct qaob *aob)
}
EXPORT_SYMBOL_GPL(qdio_release_aob);
+/**
+ * qdio_free_buffers() - free qdio buffers
+ * @buf: array of pointers to qdio buffers
+ * @count: number of qdio buffers to free
+ */
+void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count)
+{
+ int pos;
+
+ for (pos = 0; pos < count; pos += QBUFF_PER_PAGE)
+ free_page((unsigned long) buf[pos]);
+}
+EXPORT_SYMBOL_GPL(qdio_free_buffers);
+
+/**
+ * qdio_alloc_buffers() - allocate qdio buffers
+ * @buf: array of pointers to qdio buffers
+ * @count: number of qdio buffers to allocate
+ */
+int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count)
+{
+ int pos;
+
+ for (pos = 0; pos < count; pos += QBUFF_PER_PAGE) {
+ buf[pos] = (void *) get_zeroed_page(GFP_KERNEL);
+ if (!buf[pos]) {
+ qdio_free_buffers(buf, count);
+ return -ENOMEM;
+ }
+ }
+ for (pos = 0; pos < count; pos++)
+ if (pos % QBUFF_PER_PAGE)
+ buf[pos] = buf[pos - 1] + 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qdio_alloc_buffers);
+
+/**
+ * qdio_reset_buffers() - reset qdio buffers
+ * @buf: array of pointers to qdio buffers
+ * @count: number of qdio buffers that will be zeroed
+ */
+void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count)
+{
+ int pos;
+
+ for (pos = 0; pos < count; pos++)
+ memset(buf[pos], 0, sizeof(struct qdio_buffer));
+}
+EXPORT_SYMBOL_GPL(qdio_reset_buffers);
+
/*
* qebsm is only available under 64bit but the adapter sets the feature
* flag anyway, so we manually override it.
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 69ef4f8cfac8..4038437ff033 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -901,10 +901,15 @@ static int ap_device_probe(struct device *dev)
int rc;
ap_dev->drv = ap_drv;
+
+ spin_lock_bh(&ap_device_list_lock);
+ list_add(&ap_dev->list, &ap_device_list);
+ spin_unlock_bh(&ap_device_list_lock);
+
rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
- if (!rc) {
+ if (rc) {
spin_lock_bh(&ap_device_list_lock);
- list_add(&ap_dev->list, &ap_device_list);
+ list_del_init(&ap_dev->list);
spin_unlock_bh(&ap_device_list_lock);
}
return rc;
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index d837c3c5330f..fbc6701bef30 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -2915,7 +2915,7 @@ claw_new_device(struct ccwgroup_device *cgdev)
"failed with error code %d\n", ret);
goto out;
}
- dev = alloc_netdev(0,"claw%d",claw_init_netdevice);
+ dev = alloc_netdev(0, "claw%d", NET_NAME_UNKNOWN, claw_init_netdevice);
if (!dev) {
dev_warn(&cgdev->dev,
"Activating the CLAW device failed\n");
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 03b6ad035577..e056dd4fe44d 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1137,9 +1137,11 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
return NULL;
if (IS_MPC(priv))
- dev = alloc_netdev(0, MPC_DEVICE_GENE, ctcm_dev_setup);
+ dev = alloc_netdev(0, MPC_DEVICE_GENE, NET_NAME_UNKNOWN,
+ ctcm_dev_setup);
else
- dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup);
+ dev = alloc_netdev(0, CTC_DEVICE_GENE, NET_NAME_UNKNOWN,
+ ctcm_dev_setup);
if (!dev) {
CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index ce16d1bdb20a..0a87809c8af7 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -2015,7 +2015,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
struct net_device *dev;
dev = alloc_netdev(sizeof(struct netiucv_priv), "iucv%d",
- netiucv_setup_netdevice);
+ NET_NAME_UNKNOWN, netiucv_setup_netdevice);
if (!dev)
return NULL;
rtnl_lock();
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index a2088af51cc5..97ef37b51068 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -439,10 +439,10 @@ struct qeth_qdio_buffer {
};
struct qeth_qdio_q {
- struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
+ struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
int next_buf_to_init;
-} __attribute__ ((aligned(256)));
+};
struct qeth_qdio_out_buffer {
struct qdio_buffer *buffer;
@@ -465,7 +465,7 @@ enum qeth_out_q_states {
};
struct qeth_qdio_out_q {
- struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
+ struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q];
struct qdio_outbuf_state *bufstates; /* convenience pointer */
int queue_no;
@@ -483,7 +483,7 @@ struct qeth_qdio_out_q {
atomic_t used_buffers;
/* indicates whether PCI flag must be set (or if one is outstanding) */
atomic_t set_pci_flags_count;
-} __attribute__ ((aligned(256)));
+};
struct qeth_qdio_info {
atomic_t state;
@@ -766,6 +766,11 @@ struct carrier_info {
__u32 port_speed;
};
+struct qeth_switch_info {
+ __u32 capabilities;
+ __u32 settings;
+};
+
#define QETH_NAPI_WEIGHT NAPI_POLL_WEIGHT
struct qeth_card {
@@ -946,6 +951,8 @@ struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
int qeth_mdio_read(struct net_device *, int, int);
int qeth_snmp_command(struct qeth_card *, char __user *);
int qeth_query_oat_command(struct qeth_card *, char __user *);
+int qeth_query_switch_attributes(struct qeth_card *card,
+ struct qeth_switch_info *sw_info);
int qeth_query_card_info(struct qeth_card *card,
struct carrier_info *carrier_info);
int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index f54bec54d677..c0d6ba8655c7 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -292,14 +292,43 @@ int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
}
EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool);
+static void qeth_free_qdio_queue(struct qeth_qdio_q *q)
+{
+ if (!q)
+ return;
+
+ qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
+ kfree(q);
+}
+
+static struct qeth_qdio_q *qeth_alloc_qdio_queue(void)
+{
+ struct qeth_qdio_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
+ int i;
+
+ if (!q)
+ return NULL;
+
+ if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
+ kfree(q);
+ return NULL;
+ }
+
+ for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
+ q->bufs[i].buffer = q->qdio_bufs[i];
+
+ QETH_DBF_HEX(SETUP, 2, &q, sizeof(void *));
+ return q;
+}
+
static inline int qeth_cq_init(struct qeth_card *card)
{
int rc;
if (card->options.cq == QETH_CQ_ENABLED) {
QETH_DBF_TEXT(SETUP, 2, "cqinit");
- memset(card->qdio.c_q->qdio_bufs, 0,
- QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
+ qdio_reset_buffers(card->qdio.c_q->qdio_bufs,
+ QDIO_MAX_BUFFERS_PER_Q);
card->qdio.c_q->next_buf_to_init = 127;
rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT,
card->qdio.no_in_queues - 1, 0,
@@ -323,21 +352,12 @@ static inline int qeth_alloc_cq(struct qeth_card *card)
struct qdio_outbuf_state *outbuf_states;
QETH_DBF_TEXT(SETUP, 2, "cqon");
- card->qdio.c_q = kzalloc(sizeof(struct qeth_qdio_q),
- GFP_KERNEL);
+ card->qdio.c_q = qeth_alloc_qdio_queue();
if (!card->qdio.c_q) {
rc = -1;
goto kmsg_out;
}
- QETH_DBF_HEX(SETUP, 2, &card->qdio.c_q, sizeof(void *));
-
- for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
- card->qdio.c_q->bufs[i].buffer =
- &card->qdio.c_q->qdio_bufs[i];
- }
-
card->qdio.no_in_queues = 2;
-
card->qdio.out_bufstates =
kzalloc(card->qdio.no_out_queues *
QDIO_MAX_BUFFERS_PER_Q *
@@ -361,7 +381,7 @@ static inline int qeth_alloc_cq(struct qeth_card *card)
out:
return rc;
free_cq_out:
- kfree(card->qdio.c_q);
+ qeth_free_qdio_queue(card->qdio.c_q);
card->qdio.c_q = NULL;
kmsg_out:
dev_err(&card->gdev->dev, "Failed to create completion queue\n");
@@ -372,7 +392,7 @@ static inline void qeth_free_cq(struct qeth_card *card)
{
if (card->qdio.c_q) {
--card->qdio.no_in_queues;
- kfree(card->qdio.c_q);
+ qeth_free_qdio_queue(card->qdio.c_q);
card->qdio.c_q = NULL;
}
kfree(card->qdio.out_bufstates);
@@ -1282,35 +1302,6 @@ static void qeth_free_buffer_pool(struct qeth_card *card)
}
}
-static void qeth_free_qdio_buffers(struct qeth_card *card)
-{
- int i, j;
-
- if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
- QETH_QDIO_UNINITIALIZED)
- return;
-
- qeth_free_cq(card);
- cancel_delayed_work_sync(&card->buffer_reclaim_work);
- for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
- if (card->qdio.in_q->bufs[j].rx_skb)
- dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
- }
- kfree(card->qdio.in_q);
- card->qdio.in_q = NULL;
- /* inbound buffer pool */
- qeth_free_buffer_pool(card);
- /* free outbound qdio_qs */
- if (card->qdio.out_qs) {
- for (i = 0; i < card->qdio.no_out_queues; ++i) {
- qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
- kfree(card->qdio.out_qs[i]);
- }
- kfree(card->qdio.out_qs);
- card->qdio.out_qs = NULL;
- }
-}
-
static void qeth_clean_channel(struct qeth_channel *channel)
{
int cnt;
@@ -2392,7 +2383,7 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
rc = -ENOMEM;
goto out;
}
- newbuf->buffer = &q->qdio_bufs[bidx];
+ newbuf->buffer = q->qdio_bufs[bidx];
skb_queue_head_init(&newbuf->skb_list);
lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key);
newbuf->q = q;
@@ -2411,6 +2402,28 @@ out:
return rc;
}
+static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q)
+{
+ if (!q)
+ return;
+
+ qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
+ kfree(q);
+}
+
+static struct qeth_qdio_out_q *qeth_alloc_qdio_out_buf(void)
+{
+ struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL);
+
+ if (!q)
+ return NULL;
+
+ if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) {
+ kfree(q);
+ return NULL;
+ }
+ return q;
+}
static int qeth_alloc_qdio_buffers(struct qeth_card *card)
{
@@ -2422,19 +2435,11 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
return 0;
- card->qdio.in_q = kzalloc(sizeof(struct qeth_qdio_q),
- GFP_KERNEL);
+ QETH_DBF_TEXT(SETUP, 2, "inq");
+ card->qdio.in_q = qeth_alloc_qdio_queue();
if (!card->qdio.in_q)
goto out_nomem;
- QETH_DBF_TEXT(SETUP, 2, "inq");
- QETH_DBF_HEX(SETUP, 2, &card->qdio.in_q, sizeof(void *));
- memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
- /* give inbound qeth_qdio_buffers their qdio_buffers */
- for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) {
- card->qdio.in_q->bufs[i].buffer =
- &card->qdio.in_q->qdio_bufs[i];
- card->qdio.in_q->bufs[i].rx_skb = NULL;
- }
+
/* inbound buffer pool */
if (qeth_alloc_buffer_pool(card))
goto out_freeinq;
@@ -2446,8 +2451,7 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
if (!card->qdio.out_qs)
goto out_freepool;
for (i = 0; i < card->qdio.no_out_queues; ++i) {
- card->qdio.out_qs[i] = kzalloc(sizeof(struct qeth_qdio_out_q),
- GFP_KERNEL);
+ card->qdio.out_qs[i] = qeth_alloc_qdio_out_buf();
if (!card->qdio.out_qs[i])
goto out_freeoutq;
QETH_DBF_TEXT_(SETUP, 2, "outq %i", i);
@@ -2476,7 +2480,7 @@ out_freeoutqbufs:
}
out_freeoutq:
while (i > 0) {
- kfree(card->qdio.out_qs[--i]);
+ qeth_free_qdio_out_buf(card->qdio.out_qs[--i]);
qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
}
kfree(card->qdio.out_qs);
@@ -2484,13 +2488,42 @@ out_freeoutq:
out_freepool:
qeth_free_buffer_pool(card);
out_freeinq:
- kfree(card->qdio.in_q);
+ qeth_free_qdio_queue(card->qdio.in_q);
card->qdio.in_q = NULL;
out_nomem:
atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
return -ENOMEM;
}
+static void qeth_free_qdio_buffers(struct qeth_card *card)
+{
+ int i, j;
+
+ if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
+ QETH_QDIO_UNINITIALIZED)
+ return;
+
+ qeth_free_cq(card);
+ cancel_delayed_work_sync(&card->buffer_reclaim_work);
+ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
+ if (card->qdio.in_q->bufs[j].rx_skb)
+ dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
+ }
+ qeth_free_qdio_queue(card->qdio.in_q);
+ card->qdio.in_q = NULL;
+ /* inbound buffer pool */
+ qeth_free_buffer_pool(card);
+ /* free outbound qdio_qs */
+ if (card->qdio.out_qs) {
+ for (i = 0; i < card->qdio.no_out_queues; ++i) {
+ qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
+ qeth_free_qdio_out_buf(card->qdio.out_qs[i]);
+ }
+ kfree(card->qdio.out_qs);
+ card->qdio.out_qs = NULL;
+ }
+}
+
static void qeth_create_qib_param_field(struct qeth_card *card,
char *param_field)
{
@@ -2788,8 +2821,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
QETH_DBF_TEXT(SETUP, 2, "initqdqs");
/* inbound queue */
- memset(card->qdio.in_q->qdio_bufs, 0,
- QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
+ qdio_reset_buffers(card->qdio.in_q->qdio_bufs,
+ QDIO_MAX_BUFFERS_PER_Q);
qeth_initialize_working_pool_list(card);
/*give only as many buffers to hardware as we have buffer pool entries*/
for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
@@ -2811,8 +2844,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
/* outbound queue */
for (i = 0; i < card->qdio.no_out_queues; ++i) {
- memset(card->qdio.out_qs[i]->qdio_bufs, 0,
- QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
+ qdio_reset_buffers(card->qdio.out_qs[i]->qdio_bufs,
+ QDIO_MAX_BUFFERS_PER_Q);
for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
qeth_clear_output_buffer(card->qdio.out_qs[i],
card->qdio.out_qs[i]->bufs[j],
@@ -3037,6 +3070,45 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
}
EXPORT_SYMBOL_GPL(qeth_query_ipassists);
+static int qeth_query_switch_attributes_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+ struct qeth_switch_info *sw_info;
+ struct qeth_query_switch_attributes *attrs;
+
+ QETH_CARD_TEXT(card, 2, "qswiatcb");
+ cmd = (struct qeth_ipa_cmd *) data;
+ sw_info = (struct qeth_switch_info *)reply->param;
+ if (cmd->data.setadapterparms.hdr.return_code == 0) {
+ attrs = &cmd->data.setadapterparms.data.query_switch_attributes;
+ sw_info->capabilities = attrs->capabilities;
+ sw_info->settings = attrs->settings;
+ QETH_CARD_TEXT_(card, 2, "%04x%04x", sw_info->capabilities,
+ sw_info->settings);
+ }
+ qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
+
+ return 0;
+}
+
+int qeth_query_switch_attributes(struct qeth_card *card,
+ struct qeth_switch_info *sw_info)
+{
+ struct qeth_cmd_buffer *iob;
+
+ QETH_CARD_TEXT(card, 2, "qswiattr");
+ if (!qeth_adp_supported(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES))
+ return -EOPNOTSUPP;
+ if (!netif_carrier_ok(card->dev))
+ return -ENOMEDIUM;
+ iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES,
+ sizeof(struct qeth_ipacmd_setadpparms_hdr));
+ return qeth_send_ipa_cmd(card, iob,
+ qeth_query_switch_attributes_cb, sw_info);
+}
+EXPORT_SYMBOL_GPL(qeth_query_switch_attributes);
+
static int qeth_query_setdiagass_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long data)
{
@@ -3530,7 +3602,7 @@ static void qeth_qdio_cq_handler(struct qeth_card *card,
for (i = first_element; i < first_element + count; ++i) {
int bidx = i % QDIO_MAX_BUFFERS_PER_Q;
- struct qdio_buffer *buffer = &cq->qdio_bufs[bidx];
+ struct qdio_buffer *buffer = cq->qdio_bufs[bidx];
int e;
e = 0;
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index cf6a90ed42ae..1558be1af72d 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -242,6 +242,7 @@ enum qeth_ipa_setadp_cmd {
IPA_SETADP_SET_DIAG_ASSIST = 0x00002000L,
IPA_SETADP_SET_ACCESS_CONTROL = 0x00010000L,
IPA_SETADP_QUERY_OAT = 0x00080000L,
+ IPA_SETADP_QUERY_SWITCH_ATTRIBUTES = 0x00100000L,
};
enum qeth_ipa_mac_ops {
CHANGE_ADDR_READ_MAC = 0,
@@ -431,6 +432,21 @@ struct qeth_query_card_info {
__u32 reserved2;
};
+#define QETH_SWITCH_FORW_802_1 0x00000001
+#define QETH_SWITCH_FORW_REFL_RELAY 0x00000002
+#define QETH_SWITCH_CAP_RTE 0x00000004
+#define QETH_SWITCH_CAP_ECP 0x00000008
+#define QETH_SWITCH_CAP_VDP 0x00000010
+
+struct qeth_query_switch_attributes {
+ __u8 version;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 capabilities;
+ __u32 settings;
+ __u8 reserved3[8];
+};
+
struct qeth_ipacmd_setadpparms_hdr {
__u32 supp_hw_cmds;
__u32 reserved1;
@@ -452,6 +468,7 @@ struct qeth_ipacmd_setadpparms {
struct qeth_set_access_ctrl set_access_ctrl;
struct qeth_query_oat query_oat;
struct qeth_query_card_info card_info;
+ struct qeth_query_switch_attributes query_switch_attributes;
__u32 mode;
} data;
} __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 8a25a2be9890..15523f0e4c03 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -543,7 +543,42 @@ out:
}
static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
- qeth_dev_isolation_store);
+ qeth_dev_isolation_store);
+
+static ssize_t qeth_dev_switch_attrs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct qeth_card *card = dev_get_drvdata(dev);
+ struct qeth_switch_info sw_info;
+ int rc = 0;
+
+ if (!card)
+ return -EINVAL;
+
+ if (card->state != CARD_STATE_SOFTSETUP && card->state != CARD_STATE_UP)
+ return sprintf(buf, "n/a\n");
+
+ rc = qeth_query_switch_attributes(card, &sw_info);
+ if (rc)
+ return rc;
+
+ if (!sw_info.capabilities)
+ rc = sprintf(buf, "unknown");
+
+ if (sw_info.capabilities & QETH_SWITCH_FORW_802_1)
+ rc = sprintf(buf, (sw_info.settings & QETH_SWITCH_FORW_802_1 ?
+ "[802.1]" : "802.1"));
+ if (sw_info.capabilities & QETH_SWITCH_FORW_REFL_RELAY)
+ rc += sprintf(buf + rc,
+ (sw_info.settings & QETH_SWITCH_FORW_REFL_RELAY ?
+ " [rr]" : " rr"));
+ rc += sprintf(buf + rc, "\n");
+
+ return rc;
+}
+
+static DEVICE_ATTR(switch_attrs, 0444,
+ qeth_dev_switch_attrs_show, NULL);
static ssize_t qeth_hw_trap_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -728,6 +763,7 @@ static struct attribute *qeth_device_attrs[] = {
&dev_attr_layer2.attr,
&dev_attr_isolation.attr,
&dev_attr_hw_trap.attr,
+ &dev_attr_switch_attrs.attr,
NULL,
};
static struct attribute_group qeth_device_attr_group = {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 5ef5b4f45758..c2679bfe7f66 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -952,10 +952,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
{
switch (card->info.type) {
case QETH_CARD_TYPE_IQD:
- card->dev = alloc_netdev(0, "hsi%d", ether_setup);
+ card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN,
+ ether_setup);
break;
case QETH_CARD_TYPE_OSN:
- card->dev = alloc_netdev(0, "osn%d", ether_setup);
+ card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN,
+ ether_setup);
card->dev->flags |= IFF_NOARP;
break;
default:
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 14e0b5810e8c..f8427a2c4840 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3287,7 +3287,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
}
}
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
- card->dev = alloc_netdev(0, "hsi%d", ether_setup);
+ card->dev = alloc_netdev(0, "hsi%d", NET_NAME_UNKNOWN,
+ ether_setup);
if (!card->dev)
return -ENODEV;
card->dev->flags |= IFF_NOARP;
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 0ca64484cfa3..5d7fbe4e907e 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -418,7 +418,8 @@ void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
rec->scsi_retries = sc->retries;
rec->scsi_allowed = sc->allowed;
rec->scsi_id = sc->device->id;
- rec->scsi_lun = sc->device->lun;
+ /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */
+ rec->scsi_lun = (u32)sc->device->lun;
rec->host_scribble = (unsigned long)sc->host_scribble;
memcpy(rec->scsi_opcode, sc->cmnd,
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 06025cdaa4ad..495e1cb3afa6 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -14,27 +14,10 @@
#include "zfcp_ext.h"
#include "zfcp_qdio.h"
-#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
-
static bool enable_multibuffer = 1;
module_param_named(datarouter, enable_multibuffer, bool, 0400);
MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)");
-static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
-{
- int pos;
-
- for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) {
- sbal[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL);
- if (!sbal[pos])
- return -ENOMEM;
- }
- for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++)
- if (pos % QBUFF_PER_PAGE)
- sbal[pos] = sbal[pos - 1] + 1;
- return 0;
-}
-
static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
unsigned int qdio_err)
{
@@ -326,15 +309,30 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
{
struct qdio_initialize init_data;
+ int ret;
- if (zfcp_qdio_buffers_enqueue(qdio->req_q) ||
- zfcp_qdio_buffers_enqueue(qdio->res_q))
+ ret = qdio_alloc_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
+ if (ret)
return -ENOMEM;
+ ret = qdio_alloc_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
+ if (ret)
+ goto free_req_q;
+
zfcp_qdio_setup_init_data(&init_data, qdio);
init_waitqueue_head(&qdio->req_q_wq);
- return qdio_allocate(&init_data);
+ ret = qdio_allocate(&init_data);
+ if (ret)
+ goto free_res_q;
+
+ return 0;
+
+free_res_q:
+ qdio_free_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
+free_req_q:
+ qdio_free_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
+ return ret;
}
/**
@@ -448,19 +446,14 @@ failed_establish:
void zfcp_qdio_destroy(struct zfcp_qdio *qdio)
{
- int p;
-
if (!qdio)
return;
if (qdio->adapter->ccw_device)
qdio_free(qdio->adapter->ccw_device);
- for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) {
- free_page((unsigned long) qdio->req_q[p]);
- free_page((unsigned long) qdio->res_q[p]);
- }
-
+ qdio_free_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
+ qdio_free_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
kfree(qdio);
}
@@ -475,7 +468,7 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter)
qdio->adapter = adapter;
if (zfcp_qdio_allocate(qdio)) {
- zfcp_qdio_destroy(qdio);
+ kfree(qdio);
return -ENOMEM;
}
diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c
index 39f5446f7216..157d3d203ba1 100644
--- a/drivers/s390/scsi/zfcp_unit.c
+++ b/drivers/s390/scsi/zfcp_unit.c
@@ -21,7 +21,7 @@
void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
{
struct fc_rport *rport = unit->port->rport;
- unsigned int lun;
+ u64 lun;
lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
@@ -188,7 +188,7 @@ struct scsi_device *zfcp_unit_sdev(struct zfcp_unit *unit)
{
struct Scsi_Host *shost;
struct zfcp_port *port;
- unsigned int lun;
+ u64 lun;
lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
port = unit->port;
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index 160e7510aca6..0787b9756165 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -452,6 +452,9 @@ static void attach_one_temp(struct bbc_i2c_bus *bp, struct platform_device *op,
if (!tp)
return;
+ INIT_LIST_HEAD(&tp->bp_list);
+ INIT_LIST_HEAD(&tp->glob_list);
+
tp->client = bbc_i2c_attach(bp, op);
if (!tp->client) {
kfree(tp);
@@ -497,6 +500,9 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct platform_device *op,
if (!fp)
return;
+ INIT_LIST_HEAD(&fp->bp_list);
+ INIT_LIST_HEAD(&fp->glob_list);
+
fp->client = bbc_i2c_attach(bp, op);
if (!fp->client) {
kfree(fp);
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index c7763e482eb2..812b5f0361b6 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -300,13 +300,18 @@ static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index
if (!bp)
return NULL;
+ INIT_LIST_HEAD(&bp->temps);
+ INIT_LIST_HEAD(&bp->fans);
+
bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs");
if (!bp->i2c_control_regs)
goto fail;
- bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
- if (!bp->i2c_bussel_reg)
- goto fail;
+ if (op->num_resources == 2) {
+ bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel");
+ if (!bp->i2c_bussel_reg)
+ goto fail;
+ }
bp->waiting = 0;
init_waitqueue_head(&bp->wq);
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 7c71e7b4febf..2b0ce7c350ee 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -4,6 +4,7 @@
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
*/
+#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
@@ -143,10 +144,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case D7SIOCTM:
/* toggle device mode-- flip display orientation */
- if (regs & D7S_FLIP)
- regs &= ~D7S_FLIP;
- else
- regs |= D7S_FLIP;
+ regs ^= D7S_FLIP;
writeb(regs, p->regs);
break;
}
@@ -180,7 +178,7 @@ static int d7s_probe(struct platform_device *op)
if (d7s_device)
goto out;
- p = kzalloc(sizeof(*p), GFP_KERNEL);
+ p = devm_kzalloc(&op->dev, sizeof(*p), GFP_KERNEL);
err = -ENOMEM;
if (!p)
goto out;
@@ -231,7 +229,6 @@ out_iounmap:
of_iounmap(&op->resource[0], p->regs, sizeof(u8));
out_free:
- kfree(p);
goto out;
}
@@ -251,7 +248,6 @@ static int d7s_remove(struct platform_device *op)
misc_deregister(&d7s_miscdev);
of_iounmap(&op->resource[0], p->regs, sizeof(u8));
- kfree(p);
return 0;
}
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 49dcf03c631a..29b0b84ed69e 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -392,6 +392,8 @@ typedef struct TAG_TW_Passthru
unsigned char padding[12];
} TW_Passthru;
+#pragma pack()
+
typedef struct TAG_TW_Device_Extension {
u32 base_addr;
unsigned long *alignment_virtual_address[TW_Q_LENGTH];
@@ -430,6 +432,4 @@ typedef struct TAG_TW_Device_Extension {
wait_queue_head_t ioctl_wqueue;
} TW_Device_Extension;
-#pragma pack()
-
#endif /* _3W_XXXX_H */
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index a3adfb4357f5..fabd4be2c985 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -1005,7 +1005,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
DMA_TO_DEVICE);
cmnd[0] = REQUEST_SENSE;
- cmnd[1] = (SCp->device->lun & 0x7) << 5;
+ cmnd[1] = (lun & 0x7) << 5;
cmnd[2] = 0;
cmnd[3] = 0;
cmnd[4] = SCSI_SENSE_BUFFERSIZE;
@@ -1396,7 +1396,8 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
struct NCR_700_Host_Parameters *hostdata =
(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
__u16 count = 1; /* for IDENTIFY message */
-
+ u8 lun = SCp->device->lun;
+
if(hostdata->state != NCR_700_HOST_FREE) {
/* keep this inside the lock to close the race window where
* the running command finishes on another CPU while we don't
@@ -1415,7 +1416,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE &&
slot->flags != NCR_700_FLAG_AUTOSENSE),
- SCp->device->lun);
+ lun);
/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
* if the negotiated transfer parameters still hold, so
* always renegotiate them */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index baca5897039f..18a3358eb1d4 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -40,13 +40,6 @@ config SCSI_DMA
bool
default n
-config SCSI_TGT
- tristate "SCSI target support"
- depends on SCSI
- ---help---
- If you want to use SCSI target mode drivers enable this option.
- If you choose M, the module will be called scsi_tgt.
-
config SCSI_NETLINK
bool
default n
@@ -197,20 +190,6 @@ config SCSI_ENCLOSURE
it has an enclosure device. Selecting this option will just allow
certain enclosure conditions to be reported and is not required.
-config SCSI_MULTI_LUN
- bool "Probe all LUNs on each SCSI device"
- depends on SCSI
- help
- Some devices support more than one LUN (Logical Unit Number) in order
- to allow access to several media, e.g. CD jukebox, USB card reader,
- mobile phone in mass storage mode. This option forces the kernel to
- probe for all LUNs by default. This setting can be overridden by
- max_luns boot/module parameter. Note that this option does not affect
- devices conforming to SCSI-3 or higher as they can explicitly report
- their number of LUNs. It is safe to say Y here unless you have one of
- those rare devices which reacts in an unexpected way when probed for
- multiple LUNs.
-
config SCSI_CONSTANTS
bool "Verbose SCSI error reporting (kernel size +=12K)"
depends on SCSI
@@ -285,13 +264,6 @@ config SCSI_FC_ATTRS
each attached FiberChannel device to sysfs, say Y.
Otherwise, say N.
-config SCSI_FC_TGT_ATTRS
- bool "SCSI target support for FiberChannel Transport Attributes"
- depends on SCSI_FC_ATTRS
- depends on SCSI_TGT = y || SCSI_TGT = SCSI_FC_ATTRS
- help
- If you want to use SCSI target mode drivers enable this option.
-
config SCSI_ISCSI_ATTRS
tristate "iSCSI Transport Attributes"
depends on SCSI && NET
@@ -318,13 +290,6 @@ config SCSI_SRP_ATTRS
If you wish to export transport-specific information about
each attached SRP device to sysfs, say Y.
-config SCSI_SRP_TGT_ATTRS
- bool "SCSI target support for SRP Transport Attributes"
- depends on SCSI_SRP_ATTRS
- depends on SCSI_TGT = y || SCSI_TGT = SCSI_SRP_ATTRS
- help
- If you want to use SCSI target mode drivers enable this option.
-
endmenu
menuconfig SCSI_LOWLEVEL
@@ -528,7 +493,7 @@ config SCSI_DPT_I2O
config SCSI_ADVANSYS
tristate "AdvanSys SCSI support"
- depends on SCSI && VIRT_TO_BUS
+ depends on SCSI && VIRT_TO_BUS && !ARM
depends on ISA || EISA || PCI
help
This is a driver for all SCSI host adapters manufactured by
@@ -848,20 +813,6 @@ config SCSI_IBMVSCSI
To compile this driver as a module, choose M here: the
module will be called ibmvscsi.
-config SCSI_IBMVSCSIS
- tristate "IBM Virtual SCSI Server support"
- depends on PPC_PSERIES && SCSI_SRP && SCSI_SRP_TGT_ATTRS
- help
- This is the SRP target driver for IBM pSeries virtual environments.
-
- The userspace component needed to initialize the driver and
- documentation can be found:
-
- http://stgt.berlios.de/
-
- To compile this driver as a module, choose M here: the
- module will be called ibmvstgt.
-
config SCSI_IBMVFC
tristate "IBM Virtual FC support"
depends on PPC_PSERIES && SCSI
@@ -1750,16 +1701,6 @@ config SCSI_PM8001
This driver supports PMC-Sierra PCIE SAS/SATA 8x6G SPC 8001 chip
based host adapters.
-config SCSI_SRP
- tristate "SCSI RDMA Protocol helper library"
- depends on SCSI && PCI
- select SCSI_TGT
- help
- If you wish to use SRP target drivers, say Y.
-
- To compile this driver as a module, choose M here: the
- module will be called libsrp.
-
config SCSI_BFA_FC
tristate "Brocade BFA Fibre Channel Support"
depends on PCI && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index e172d4f8e02f..5f0d299b0093 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -20,7 +20,6 @@ CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
obj-$(CONFIG_PCMCIA) += pcmcia/
obj-$(CONFIG_SCSI) += scsi_mod.o
-obj-$(CONFIG_SCSI_TGT) += scsi_tgt.o
obj-$(CONFIG_RAID_ATTRS) += raid_class.o
@@ -127,9 +126,7 @@ obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o
-obj-$(CONFIG_SCSI_SRP) += libsrp.o
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
-obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
obj-$(CONFIG_SCSI_IBMVFC) += ibmvscsi/
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o
@@ -173,8 +170,6 @@ scsi_mod-$(CONFIG_PM) += scsi_pm.o
hv_storvsc-y := storvsc_drv.o
-scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
-
sd_mod-objs := sd.o
sd_mod-$(CONFIG_BLK_DEV_INTEGRITY) += sd_dif.o
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 93d13fc9a293..45da3c823322 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -762,7 +762,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m,
static void lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, struct seq_file *m)
{
- SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
+ SPRINTF("scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun);
SPRINTF(" command = ");
lprint_command(cmd->cmnd, m);
}
@@ -1039,9 +1039,10 @@ static void NCR5380_main(struct work_struct *work)
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
{
if (prev != tmp)
- dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
+ dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
/* When we find one, remove it from the issue queue. */
- if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
+ if (!(hostdata->busy[tmp->device->id] &
+ (1 << (u8)(tmp->device->lun & 0xff)))) {
if (prev) {
REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
prev->host_scribble = tmp->host_scribble;
@@ -1057,7 +1058,7 @@ static void NCR5380_main(struct work_struct *work)
* On failure, we must add the command back to the
* issue queue so we can keep trying.
*/
- dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %d removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
+ dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
/*
* A successful selection is defined as one that
@@ -1524,7 +1525,7 @@ part2:
dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
/* XXX need to handle errors here */
hostdata->connected = cmd;
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
initialize_SCp(cmd);
@@ -2210,14 +2211,14 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
case LINKED_FLG_CMD_COMPLETE:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
/*
* Sanity check : A linked command should only terminate with
* one of these messages if there are more linked commands
* available.
*/
if (!cmd->next_link) {
- printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
+ printk("scsi%d : target %d lun %llu linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);
sink = 1;
do_abort(instance);
return;
@@ -2226,7 +2227,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
/* The next command is still part of this process */
cmd->next_link->tag = cmd->tag;
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
cmd = hostdata->connected;
@@ -2238,8 +2239,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
hostdata->connected = NULL;
- dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
/*
* I'm not sure what the correct thing to do here is :
@@ -2304,7 +2305,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
case ORDERED_QUEUE_TAG:
case SIMPLE_QUEUE_TAG:
cmd->device->simple_tags = 0;
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
break;
default:
break;
@@ -2318,7 +2319,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
hostdata->disconnected_queue;
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
- dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
/*
* Restore phase bits to 0 so an interrupted selection,
* arbitration can resume.
@@ -2426,7 +2427,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) {
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
collect_stats(hostdata, cmd);
@@ -2562,7 +2563,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
- if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
+ if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)
) {
if (prev) {
REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble);
@@ -2588,7 +2589,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
do_abort(instance);
} else {
hostdata->connected = tmp;
- dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %d, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+ dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
}
}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index c91888a0a23c..42c7161474f7 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -595,7 +595,7 @@ static int NCR53c406a_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
-#ifdef USE_DMA
+#if USE_DMA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
#endif
@@ -698,7 +698,7 @@ static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
int i;
VDEB(printk("NCR53c406a_queue called\n"));
- DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->target, SCpnt->lun, scsi_bufflen(SCpnt)));
+ DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->target, (u8)SCpnt->device->lun, scsi_bufflen(SCpnt)));
#if 0
VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 0163457c12bb..522570d297ca 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -891,7 +891,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc
printk("max cdb length= %x\b", cmd->cmd_len);
scb->cdb_len = IMAX_CDB;
}
- scb->ident = cmd->device->lun | DISC_ALLOW;
+ scb->ident = (u8)(cmd->device->lun & 0xff) | DISC_ALLOW;
if (cmd->device->tagged_supported) { /* Tag Support */
scb->tag_msg = SIMPLE_QUEUE_TAG; /* Do simple tag only */
} else {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 4921ed19a027..63f576c9300a 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -551,7 +551,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
int count;
int ret = FAILED;
- printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%d)\n",
+ printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%llu)\n",
AAC_DRIVERNAME,
host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun);
switch (cmd->cmnd[0]) {
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index d8145888e66a..43761c1c46f0 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2512,7 +2512,7 @@ static void asc_prt_scsi_host(struct Scsi_Host *s)
printk("Scsi_Host at addr 0x%p, device %s\n", s, dev_name(boardp->dev));
printk(" host_busy %u, host_no %d,\n",
- s->host_busy, s->host_no);
+ atomic_read(&s->host_busy), s->host_no);
printk(" base 0x%lx, io_port 0x%lx, irq %d,\n",
(ulong)s->base, (ulong)s->io_port, boardp->irq);
@@ -3345,8 +3345,8 @@ static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost)
shost->host_no);
seq_printf(m,
- " host_busy %u, max_id %u, max_lun %u, max_channel %u\n",
- shost->host_busy, shost->max_id,
+ " host_busy %u, max_id %u, max_lun %llu, max_channel %u\n",
+ atomic_read(&shost->host_busy), shost->max_id,
shost->max_lun, shost->max_channel);
seq_printf(m,
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index e86eb6a921fc..e77b72f78006 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -321,7 +321,7 @@ static LIST_HEAD(aha152x_host_list);
#define CMDINFO(cmd) \
(cmd) ? ((cmd)->device->host->host_no) : -1, \
(cmd) ? ((cmd)->device->id & 0x0f) : -1, \
- (cmd) ? ((cmd)->device->lun & 0x07) : -1
+ (cmd) ? ((u8)(cmd)->device->lun & 0x07) : -1
static inline void
CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
@@ -1602,7 +1602,7 @@ static void busfree_run(struct Scsi_Host *shpnt)
#if defined(AHA152X_DEBUG)
int hostno=DONE_SC->device->host->host_no;
int id=DONE_SC->device->id & 0xf;
- int lun=DONE_SC->device->lun & 0x7;
+ int lun=((u8)DONE_SC->device->lun) & 0x7;
#endif
Scsi_Cmnd *ptr = DONE_SC;
DONE_SC=NULL;
@@ -2984,7 +2984,7 @@ static void get_command(struct seq_file *m, Scsi_Cmnd * ptr)
int i;
SPRINTF("%p: target=%d; lun=%d; cmnd=( ",
- ptr, ptr->device->id, ptr->device->lun);
+ ptr, ptr->device->id, (u8)ptr->device->lun);
for (i = 0; i < COMMAND_SIZE(ptr->cmnd[0]); i++)
SPRINTF("0x%02x ", ptr->cmnd[i]);
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
index 0cb8ef64b5ce..3d401d02c019 100644
--- a/drivers/scsi/aic7xxx/aic7770_osm.c
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -85,10 +85,9 @@ aic7770_probe(struct device *dev)
int error;
sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
- name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
+ name = kstrdup(buf, GFP_ATOMIC);
if (name == NULL)
return (ENOMEM);
- strcpy(name, buf);
ahc = ahc_alloc(&aic7xxx_driver_template, name);
if (ahc == NULL)
return (ENOMEM);
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index 113874c1284b..df2e0e5367d2 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -115,7 +115,7 @@ struct scb_platform_data;
#endif
#define AHD_BUILD_COL_IDX(target, lun) \
- (((lun) << 4) | target)
+ ((((u8)lun) << 4) | target)
#define AHD_GET_SCB_COL_IDX(ahd, scb) \
((SCB_GET_LUN(scb) << 4) | SCB_GET_TARGET(ahd, scb))
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 69d5c43a65e5..ed333669a7dc 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -2137,7 +2137,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
if (do_fallback) {
printk("%s: device overrun (status %x) on %d:%d:%d\n",
ahd_name(ahd), status, cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ cmd->device->id, (u8)cmd->device->lun);
}
ahd_cmd_set_transaction_status(cmd, new_status);
@@ -2253,13 +2253,13 @@ ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
disconnected = TRUE;
if (ahd_search_qinfifo(ahd, cmd->device->id,
cmd->device->channel + 'A',
- cmd->device->lun,
+ cmd->device->lun,
pending_scb->hscb->tag,
ROLE_INITIATOR, CAM_REQ_ABORTED,
SEARCH_COMPLETE) > 0) {
printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
ahd_name(ahd), cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ cmd->device->id, (u8)cmd->device->lun);
retval = SUCCESS;
goto done;
}
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 3c85873b14b9..8466aa784ec1 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -178,10 +178,9 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahd_get_pci_bus(pci),
ahd_get_pci_slot(pci),
ahd_get_pci_function(pci));
- name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
+ name = kstrdup(buf, GFP_ATOMIC);
if (name == NULL)
return (-ENOMEM);
- strcpy(name, buf);
ahd = ahd_alloc(NULL, name);
if (ahd == NULL)
return (-ENOMEM);
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c
index e9778b4f7e32..27dbfccea774 100644
--- a/drivers/scsi/aic7xxx/aic79xx_proc.c
+++ b/drivers/scsi/aic7xxx/aic79xx_proc.c
@@ -197,7 +197,7 @@ ahd_dump_device_state(struct seq_file *m, struct scsi_device *sdev)
seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n",
sdev->sdev_target->channel + 'A',
- sdev->sdev_target->id, sdev->lun);
+ sdev->sdev_target->id, (u8)sdev->lun);
seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued);
seq_printf(m, "\t\tCommands Active %d\n", dev->active);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 114ff0c6e311..d2c9bf39033d 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -2110,7 +2110,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
*/
printk("%s:%d:%d:%d: Is not an active device\n",
ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ (u8)cmd->device->lun);
retval = SUCCESS;
goto no_cmd;
}
@@ -2118,11 +2118,11 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
&& ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
cmd->device->channel + 'A',
- cmd->device->lun,
+ (u8)cmd->device->lun,
CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
printk("%s:%d:%d:%d: Command found on untagged queue\n",
ahc_name(ahc), cmd->device->channel, cmd->device->id,
- cmd->device->lun);
+ (u8)cmd->device->lun);
retval = SUCCESS;
goto done;
}
@@ -2188,13 +2188,14 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
SEARCH_COMPLETE) > 0) {
printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
ahc_name(ahc), cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ cmd->device->id, (u8)cmd->device->lun);
retval = SUCCESS;
goto done;
}
} else if (ahc_search_qinfifo(ahc, cmd->device->id,
cmd->device->channel + 'A',
- cmd->device->lun, pending_scb->hscb->tag,
+ cmd->device->lun,
+ pending_scb->hscb->tag,
ROLE_INITIATOR, /*status*/0,
SEARCH_COUNT) > 0) {
disconnected = FALSE;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index ee05e8410754..0fc14dac7070 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -225,10 +225,9 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahc_get_pci_bus(pci),
ahc_get_pci_slot(pci),
ahc_get_pci_function(pci));
- name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
+ name = kstrdup(buf, GFP_ATOMIC);
if (name == NULL)
return (-ENOMEM);
- strcpy(name, buf);
ahc = ahc_alloc(NULL, name);
if (ahc == NULL)
return (-ENOMEM);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
index 383a3d11652d..64eec6c07a83 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -175,7 +175,7 @@ ahc_dump_device_state(struct seq_file *m, struct scsi_device *sdev)
seq_printf(m, "\tChannel %c Target %d Lun %d Settings\n",
sdev->sdev_target->channel + 'A',
- sdev->sdev_target->id, sdev->lun);
+ sdev->sdev_target->id, (u8)sdev->lun);
seq_printf(m, "\t\tCommands Queued %ld\n", dev->commands_issued);
seq_printf(m, "\t\tCommands Active %d\n", dev->active);
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 652b41b4ddbd..b13764ca23fd 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -2335,7 +2335,7 @@ static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
" poll command abort successfully \n"
, acb->host->host_no
, ccb->pcmd->device->id
- , ccb->pcmd->device->lun
+ , (u32)ccb->pcmd->device->lun
, ccb);
ccb->pcmd->result = DID_ABORT << 16;
arcmsr_ccb_complete(ccb);
@@ -2399,7 +2399,7 @@ static int arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb,
" poll command abort successfully \n"
,acb->host->host_no
,ccb->pcmd->device->id
- ,ccb->pcmd->device->lun
+ ,(u32)ccb->pcmd->device->lun
,ccb);
ccb->pcmd->result = DID_ABORT << 16;
arcmsr_ccb_complete(ccb);
@@ -2456,7 +2456,7 @@ polling_hbc_ccb_retry:
" poll command abort successfully \n"
, acb->host->host_no
, pCCB->pcmd->device->id
- , pCCB->pcmd->device->lun
+ , (u32)pCCB->pcmd->device->lun
, pCCB);
pCCB->pcmd->result = DID_ABORT << 16;
arcmsr_ccb_complete(pCCB);
@@ -3058,7 +3058,7 @@ static int arcmsr_abort(struct scsi_cmnd *cmd)
int rtn = FAILED;
printk(KERN_NOTICE
"arcmsr%d: abort device command of scsi id = %d lun = %d \n",
- acb->host->host_no, cmd->device->id, cmd->device->lun);
+ acb->host->host_no, cmd->device->id, (u32)cmd->device->lun);
acb->acb_flags |= ACB_F_ABORT;
acb->num_aborts++;
/*
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 2e797a367608..d89b9b4deb3c 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -760,7 +760,8 @@ intr_ret_t acornscsi_kick(AS_Host *host)
SCpnt->tag = SCpnt->device->current_tag;
} else
#endif
- set_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
+ set_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x07), host->busyluns);
host->stats.removes += 1;
@@ -863,7 +864,8 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
if (!SCpnt->scsi_done)
panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no);
- clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
+ clear_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x7), host->busyluns);
SCpnt->scsi_done(SCpnt);
} else
@@ -1576,7 +1578,8 @@ void acornscsi_message(AS_Host *host)
printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n",
host->host->host_no, acornscsi_target(host));
host->SCpnt->device->simple_tags = 0;
- set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns);
+ set_bit(host->SCpnt->device->id * 8 +
+ (u8)(host->SCpnt->device->lun & 0x7), host->busyluns);
break;
#endif
case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8):
@@ -2671,7 +2674,8 @@ int acornscsi_abort(struct scsi_cmnd *SCpnt)
//#if (DEBUG & DEBUG_ABORT)
printk("clear ");
//#endif
- clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns);
+ clear_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x7), host->busyluns);
/*
* We found the command, and cleared it out. Either
@@ -2853,7 +2857,7 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
shost_for_each_device(scd, instance) {
seq_printf(m, "Device/Lun TaggedQ Sync\n");
- seq_printf(m, " %d/%d ", scd->id, scd->lun);
+ seq_printf(m, " %d/%llu ", scd->id, scd->lun);
if (scd->tagged_supported)
seq_printf(m, "%3sabled(%3d) ",
scd->simple_tags ? "en" : "dis",
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index b46a6f6c0eb3..71cfb1e504c4 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -1821,7 +1821,8 @@ static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
SCpnt->tag = SCpnt->device->current_tag;
} else
#endif
- set_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
+ set_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x7), info->busyluns);
info->stats.removes += 1;
switch (SCpnt->cmnd[0]) {
@@ -2171,7 +2172,8 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
* status.
*/
info->device[SCpnt->device->id].parity_check = 0;
- clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
+ clear_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x7), info->busyluns);
fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
fn(info, SCpnt, result);
@@ -2398,7 +2400,8 @@ static enum res_find fas216_find_command(FAS216_Info *info,
* been set.
*/
info->origSCpnt = NULL;
- clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
+ clear_bit(SCpnt->device->id * 8 +
+ (u8)(SCpnt->device->lun & 0x7), info->busyluns);
printk("waiting for execution ");
res = res_success;
} else
@@ -3000,7 +3003,7 @@ void fas216_print_devices(FAS216_Info *info, struct seq_file *m)
shost_for_each_device(scd, info->host) {
dev = &info->device[scd->id];
- seq_printf(m, " %d/%d ", scd->id, scd->lun);
+ seq_printf(m, " %d/%llu ", scd->id, scd->lun);
if (scd->tagged_supported)
seq_printf(m, "%3sabled(%3d) ",
scd->simple_tags ? "en" : "dis",
diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c
index cb11ccef54e5..3441ce3ebabf 100644
--- a/drivers/scsi/arm/queue.c
+++ b/drivers/scsi/arm/queue.c
@@ -167,7 +167,8 @@ struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
spin_lock_irqsave(&queue->queue_lock, flags);
list_for_each(l, &queue->head) {
QE_t *q = list_entry(l, QE_t, list);
- if (!test_bit(q->SCpnt->device->id * 8 + q->SCpnt->device->lun, exclude)) {
+ if (!test_bit(q->SCpnt->device->id * 8 +
+ (u8)(q->SCpnt->device->lun & 0x7), exclude)) {
SCpnt = __queue_remove(queue, l);
break;
}
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 1814aa20b724..79e6f045c2a9 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -361,17 +361,18 @@ static void __init init_tags(void)
static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
- if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))
+ if (hostdata->busy[cmd->device->id] & (1 << lun))
return 1;
if (!should_be_tagged ||
!setup_use_tagged_queuing || !cmd->device->tagged_supported)
return 0;
- if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
- TagAlloc[cmd->device->id][cmd->device->lun].queue_size) {
+ if (TagAlloc[cmd->device->id][lun].nr_allocated >=
+ TagAlloc[cmd->device->id][lun].queue_size) {
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
- H_NO(cmd), cmd->device->id, cmd->device->lun);
+ H_NO(cmd), cmd->device->id, lun);
return 1;
}
return 0;
@@ -385,6 +386,7 @@ static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged)
static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
/* If we or the target don't support tagged queuing, allocate the LUN for
@@ -393,11 +395,11 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
if (!should_be_tagged ||
!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
cmd->tag = TAG_NONE;
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= (1 << lun);
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
- "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun);
+ "command\n", H_NO(cmd), cmd->device->id, lun);
} else {
- TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
+ TAG_ALLOC *ta = &TagAlloc[cmd->device->id][lun];
cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
set_bit(cmd->tag, ta->allocated);
@@ -405,7 +407,7 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
"(now %d tags in use)\n",
H_NO(cmd), cmd->tag, cmd->device->id,
- cmd->device->lun, ta->nr_allocated);
+ lun, ta->nr_allocated);
}
}
@@ -416,21 +418,22 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
static void cmd_free_tag(Scsi_Cmnd *cmd)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
if (cmd->tag == TAG_NONE) {
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << lun);
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
- H_NO(cmd), cmd->device->id, cmd->device->lun);
+ H_NO(cmd), cmd->device->id, lun);
} else if (cmd->tag >= MAX_TAGS) {
printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
H_NO(cmd), cmd->tag);
} else {
- TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
+ TAG_ALLOC *ta = &TagAlloc[cmd->device->id][lun];
clear_bit(cmd->tag, ta->allocated);
ta->nr_allocated--;
dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
- H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun);
+ H_NO(cmd), cmd->tag, cmd->device->id, lun);
}
}
@@ -713,7 +716,7 @@ static void lprint_Scsi_Cmnd(Scsi_Cmnd *cmd)
{
int i, s;
unsigned char *command;
- printk("scsi%d: destination target %d, lun %d\n",
+ printk("scsi%d: destination target %d, lun %llu\n",
H_NO(cmd), cmd->device->id, cmd->device->lun);
printk(KERN_CONT " command = ");
command = cmd->cmnd;
@@ -759,7 +762,7 @@ static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m)
{
int i, s;
unsigned char *command;
- seq_printf(m, "scsi%d: destination target %d, lun %d\n",
+ seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
H_NO(cmd), cmd->device->id, cmd->device->lun);
seq_printf(m, " command = ");
command = cmd->cmnd;
@@ -1060,12 +1063,13 @@ static void NCR5380_main(struct work_struct *work)
#endif
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
+ u8 lun = tmp->device->lun;
#if (NDEBUG & NDEBUG_LISTS)
if (prev != tmp)
- printk("MAIN tmp=%p target=%d busy=%d lun=%d\n",
+ printk("MAIN tmp=%p target=%d busy=%d lun=%llu\n",
tmp, tmp->device->id, hostdata->busy[tmp->device->id],
- tmp->device->lun);
+ lun);
#endif
/* When we find one, remove it from the issue queue. */
/* ++guenther: possible race with Falcon locking */
@@ -1073,7 +1077,7 @@ static void NCR5380_main(struct work_struct *work)
#ifdef SUPPORT_TAGS
!is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
#else
- !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
+ !(hostdata->busy[tmp->device->id] & (1 << lun))
#endif
) {
/* ++guenther: just to be sure, this must be atomic */
@@ -1099,7 +1103,7 @@ static void NCR5380_main(struct work_struct *work)
*/
dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
"lun %d removed from issue_queue\n",
- HOSTNO, tmp->device->id, tmp->device->lun);
+ HOSTNO, tmp->device->id, lun);
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
@@ -2061,7 +2065,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
* accesses to this device will use the
* polled-IO. */
printk(KERN_NOTICE "scsi%d: switching target %d "
- "lun %d to slow handshake\n", HOSTNO,
+ "lun %llu to slow handshake\n", HOSTNO,
cmd->device->id, cmd->device->lun);
cmd->device->borken = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
@@ -2113,7 +2117,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked command "
+ dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command "
"complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
/* Enable reselect interrupts */
@@ -2125,7 +2129,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
*/
if (!cmd->next_link) {
- printk(KERN_NOTICE "scsi%d: target %d lun %d "
+ printk(KERN_NOTICE "scsi%d: target %d lun %llu "
"linked command complete, no next_link\n",
HOSTNO, cmd->device->id, cmd->device->lun);
sink = 1;
@@ -2138,7 +2142,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
* and don't free it! */
cmd->next_link->tag = cmd->tag;
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked request "
+ dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request "
"done, calling scsi_done().\n",
HOSTNO, cmd->device->id, cmd->device->lun);
#ifdef NCR5380_STATS
@@ -2155,7 +2159,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* ++guenther: possible race with Falcon locking */
falcon_dont_release++;
hostdata->connected = NULL;
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %d "
+ dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
@@ -2169,7 +2173,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* ++Andreas: the mid level code knows about
QUEUE_FULL now. */
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d returned "
+ dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
"QUEUE_FULL after %d commands\n",
HOSTNO, cmd->device->id, cmd->device->lun,
ta->nr_allocated);
@@ -2267,7 +2271,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
cmd->device->tagged_supported = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
cmd->tag = TAG_NONE;
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d rejected "
+ dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
"QUEUE_TAG message; tagged queuing "
"disabled\n",
HOSTNO, cmd->device->id, cmd->device->lun);
@@ -2284,7 +2288,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
local_irq_restore(flags);
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %d was "
+ dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
"moved from connected to the "
"disconnected_queue\n", HOSTNO,
cmd->device->id, cmd->device->lun);
@@ -2385,12 +2389,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
printk("\n");
} else if (tmp != EXTENDED_MESSAGE)
printk(KERN_DEBUG "scsi%d: rejecting unknown "
- "message %02x from target %d, lun %d\n",
+ "message %02x from target %d, lun %llu\n",
HOSTNO, tmp, cmd->device->id, cmd->device->lun);
else
printk(KERN_DEBUG "scsi%d: rejecting unknown "
"extended message "
- "code %02x, length %d from target %d, lun %d\n",
+ "code %02x, length %d from target %d, lun %llu\n",
HOSTNO, extended_msg[1], extended_msg[0],
cmd->device->id, cmd->device->lun);
@@ -2588,7 +2592,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
hostdata->connected = tmp;
- dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
+ dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
falcon_dont_release--;
}
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index fd284ff36ecf..86162811812d 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -914,7 +914,7 @@ void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
stats->r2t_pdus = conn->r2t_pdus_cnt;
stats->digest_err = 0;
stats->timeout_err = 0;
- stats->custom_length = 0;
+ stats->custom_length = 1;
strcpy(stats->custom[0].desc, "eh_abort_cnt");
stats->custom[0].value = conn->eh_abort_cnt;
}
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 554349029628..56467df3d6de 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4198,6 +4198,8 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
kfree(phba->ep_array);
phba->ep_array = NULL;
ret = -ENOMEM;
+
+ goto free_memory;
}
for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 6045aa78986a..a3e56487616c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1008,16 +1008,14 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
BE2_IPV6 : BE2_IPV4 ;
rc = mgmt_get_if_info(phba, ip_type, &if_info);
- if (rc) {
- kfree(if_info);
+ if (rc)
return rc;
- }
if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
if (if_info->dhcp_state) {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
"BG_%d : DHCP Already Enabled\n");
- return 0;
+ goto exit;
}
/* The ip_param->len is 1 in DHCP case. Setting
proper IP len as this it is used while
@@ -1035,7 +1033,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
sizeof(*reldhcp));
if (rc)
- return rc;
+ goto exit;
reldhcp = nonemb_cmd.va;
reldhcp->interface_hndl = phba->interface_handle;
@@ -1046,7 +1044,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
beiscsi_log(phba, KERN_WARNING,
BEISCSI_LOG_CONFIG,
"BG_%d : Failed to Delete existing dhcp\n");
- return rc;
+ goto exit;
}
}
}
@@ -1056,7 +1054,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
IP_ACTION_DEL);
if (rc)
- return rc;
+ goto exit;
}
/* Delete the Gateway settings if mode change is to DHCP */
@@ -1066,7 +1064,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
if (rc) {
beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
"BG_%d : Failed to Get Gateway Addr\n");
- return rc;
+ goto exit;
}
if (gtway_addr_set.ip_addr.addr[0]) {
@@ -1078,7 +1076,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
beiscsi_log(phba, KERN_WARNING,
BEISCSI_LOG_CONFIG,
"BG_%d : Failed to clear Gateway Addr Set\n");
- return rc;
+ goto exit;
}
}
}
@@ -1089,7 +1087,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
sizeof(*dhcpreq));
if (rc)
- return rc;
+ goto exit;
dhcpreq = nonemb_cmd.va;
dhcpreq->flags = BLOCKING;
@@ -1097,12 +1095,14 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
dhcpreq->interface_hndl = phba->interface_handle;
dhcpreq->ip_type = BE2_DHCP_V4;
- return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
+ rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
} else {
- return mgmt_static_ip_modify(phba, if_info, ip_param,
+ rc = mgmt_static_ip_modify(phba, if_info, ip_param,
subnet_param, IP_ACTION_ADD);
}
+exit:
+ kfree(if_info);
return rc;
}
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index a3ab5cce4208..0f19455951ec 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -81,7 +81,7 @@ bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
bfa->fcs = BFA_TRUE;
fcbuild_init();
- for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
mod = &fcs_modules[i];
if (mod->attach)
mod->attach(fcs);
@@ -97,7 +97,7 @@ bfa_fcs_init(struct bfa_fcs_s *fcs)
int i;
struct bfa_fcs_mod_s *mod;
- for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(fcs_modules); i++) {
mod = &fcs_modules[i];
if (mod->modinit)
mod->modinit(fcs);
@@ -184,7 +184,7 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs)
bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
- nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
+ nmods = ARRAY_SIZE(fcs_modules);
for (i = 0; i < nmods; i++) {
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 2e28392c2fb6..a38aafa030b3 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -72,7 +72,7 @@ struct bfa_sge_s {
} while (0)
#define bfa_swap_words(_x) ( \
- ((_x) << 32) | ((_x) >> 32))
+ ((u64)(_x) << 32) | ((u64)(_x) >> 32))
#ifdef __BIG_ENDIAN
#define bfa_sge_to_be(_x)
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 7593b7c1d336..e90a3742f09d 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -1219,7 +1219,7 @@ bfad_install_msix_handler(struct bfad_s *bfad)
int
bfad_setup_intr(struct bfad_s *bfad)
{
- int error = 0;
+ int error;
u32 mask = 0, i, num_bit = 0, max_bit = 0;
struct msix_entry msix_entries[MAX_MSIX_ENTRY];
struct pci_dev *pdev = bfad->pcidev;
@@ -1234,34 +1234,24 @@ bfad_setup_intr(struct bfad_s *bfad)
if ((bfa_asic_id_ctc(pdev->device) && !msix_disable_ct) ||
(bfa_asic_id_cb(pdev->device) && !msix_disable_cb)) {
- error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
- if (error) {
- /* In CT1 & CT2, try to allocate just one vector */
- if (bfa_asic_id_ctc(pdev->device)) {
- printk(KERN_WARNING "bfa %s: trying one msix "
- "vector failed to allocate %d[%d]\n",
- bfad->pci_name, bfad->nvec, error);
- bfad->nvec = 1;
- error = pci_enable_msix(bfad->pcidev,
- msix_entries, bfad->nvec);
- }
+ error = pci_enable_msix_exact(bfad->pcidev,
+ msix_entries, bfad->nvec);
+ /* In CT1 & CT2, try to allocate just one vector */
+ if (error == -ENOSPC && bfa_asic_id_ctc(pdev->device)) {
+ printk(KERN_WARNING "bfa %s: trying one msix "
+ "vector failed to allocate %d[%d]\n",
+ bfad->pci_name, bfad->nvec, error);
+ bfad->nvec = 1;
+ error = pci_enable_msix_exact(bfad->pcidev,
+ msix_entries, 1);
+ }
- /*
- * Only error number of vector is available.
- * We don't have a mechanism to map multiple
- * interrupts into one vector, so even if we
- * can try to request less vectors, we don't
- * know how to associate interrupt events to
- * vectors. Linux doesn't duplicate vectors
- * in the MSIX table for this case.
- */
- if (error) {
- printk(KERN_WARNING "bfad%d: "
- "pci_enable_msix failed (%d), "
- "use line based.\n",
- bfad->inst_no, error);
- goto line_based;
- }
+ if (error) {
+ printk(KERN_WARNING "bfad%d: "
+ "pci_enable_msix_exact failed (%d), "
+ "use line based.\n",
+ bfad->inst_no, error);
+ goto line_based;
}
/* Disable INTX in MSI-X mode */
@@ -1281,20 +1271,18 @@ bfad_setup_intr(struct bfad_s *bfad)
bfad->bfad_flags |= BFAD_MSIX_ON;
- return error;
+ return 0;
}
line_based:
- error = 0;
- if (request_irq
- (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS,
- BFAD_DRIVER_NAME, bfad) != 0) {
- /* Enable interrupt handler failed */
- return 1;
- }
+ error = request_irq(bfad->pcidev->irq, (irq_handler_t)bfad_intx,
+ BFAD_IRQ_FLAGS, BFAD_DRIVER_NAME, bfad);
+ if (error)
+ return error;
+
bfad->bfad_flags |= BFAD_INTX_ON;
- return error;
+ return 0;
}
void
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 8994fb857ee9..023b9d42ad9a 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -26,7 +26,6 @@ int
bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
- int rc = 0;
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
@@ -34,7 +33,7 @@ bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
- return rc;
+ return 0;
}
init_completion(&bfad->enable_comp);
@@ -43,21 +42,20 @@ bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
wait_for_completion(&bfad->enable_comp);
- return rc;
+ return 0;
}
int
bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
- int rc = 0;
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
if (bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
- return rc;
+ return 0;
}
if (bfad->disable_active) {
@@ -74,7 +72,7 @@ bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
bfad->disable_active = BFA_FALSE;
iocmd->status = BFA_STATUS_OK;
- return rc;
+ return 0;
}
static int
@@ -3270,13 +3268,13 @@ bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf,
/* Allocate dma coherent memory */
buf_info = buf_base;
buf_info->size = payload_len;
- buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, buf_info->size,
- &buf_info->phys, GFP_KERNEL);
+ buf_info->virt = dma_zalloc_coherent(&bfad->pcidev->dev,
+ buf_info->size, &buf_info->phys,
+ GFP_KERNEL);
if (!buf_info->virt)
goto out_free_mem;
/* copy the linear bsg buffer to buf_info */
- memset(buf_info->virt, 0, buf_info->size);
memcpy(buf_info->virt, payload_kbuf, buf_info->size);
/*
diff --git a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h
index e1f1e3448f98..fe2106c91c08 100644
--- a/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h
+++ b/drivers/scsi/bnx2fc/57xx_hsi_bnx2fc.h
@@ -1,3 +1,16 @@
+/* 57xx_hsi_bnx2fc.h: QLogic NetXtreme II Linux FCoE offload driver.
+ * Handles operations such as session offload/upload etc, and manages
+ * session resources such as connection id and qp resources.
+ *
+ * Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
+ *
+ */
+
#ifndef __57XX_FCOE_HSI_LINUX_LE__
#define __57XX_FCOE_HSI_LINUX_LE__
diff --git a/drivers/scsi/bnx2fc/Kconfig b/drivers/scsi/bnx2fc/Kconfig
index cfcad8bde7cf..f245d543d7b1 100644
--- a/drivers/scsi/bnx2fc/Kconfig
+++ b/drivers/scsi/bnx2fc/Kconfig
@@ -1,5 +1,5 @@
config SCSI_BNX2X_FCOE
- tristate "Broadcom NetXtreme II FCoE support"
+ tristate "QLogic NetXtreme II FCoE support"
depends on PCI
select NETDEVICES
select ETHERNET
@@ -8,5 +8,5 @@ config SCSI_BNX2X_FCOE
select LIBFCOE
select CNIC
---help---
- This driver supports FCoE offload for the Broadcom NetXtreme II
+ This driver supports FCoE offload for the QLogic NetXtreme II
devices.
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 6a976657b475..1346e052e03c 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -1,8 +1,7 @@
-#ifndef _BNX2FC_H_
-#define _BNX2FC_H_
-/* bnx2fc.h: Broadcom NetXtreme II Linux FCoE offload driver.
+/* bnx2fc.h: QLogic NetXtreme II Linux FCoE offload driver.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
@@ -11,6 +10,8 @@
* Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
*/
+#ifndef _BNX2FC_H_
+#define _BNX2FC_H_
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
diff --git a/drivers/scsi/bnx2fc/bnx2fc_constants.h b/drivers/scsi/bnx2fc/bnx2fc_constants.h
index dad9924abbbb..e147cc7ee36c 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_constants.h
+++ b/drivers/scsi/bnx2fc/bnx2fc_constants.h
@@ -1,3 +1,16 @@
+/* bnx2fc_constants.h: QLogic NetXtreme II Linux FCoE offload driver.
+ * Handles operations such as session offload/upload etc, and manages
+ * session resources such as connection id and qp resources.
+ *
+ * Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
+ *
+ */
+
#ifndef __BNX2FC_CONSTANTS_H_
#define __BNX2FC_CONSTANTS_H_
diff --git a/drivers/scsi/bnx2fc/bnx2fc_debug.c b/drivers/scsi/bnx2fc/bnx2fc_debug.c
index 0cbee1b23ee2..d055df01faa5 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_debug.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_debug.c
@@ -1,3 +1,16 @@
+/* bnx2fc_debug.c: QLogic NetXtreme II Linux FCoE offload driver.
+ * Handles operations such as session offload/upload etc, and manages
+ * session resources such as connection id and qp resources.
+ *
+ * Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
+ *
+ */
+
#include "bnx2fc.h"
void BNX2FC_IO_DBG(const struct bnx2fc_cmd *io_req, const char *fmt, ...)
diff --git a/drivers/scsi/bnx2fc/bnx2fc_debug.h b/drivers/scsi/bnx2fc/bnx2fc_debug.h
index 4808ff99621f..2b9006774f37 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_debug.h
+++ b/drivers/scsi/bnx2fc/bnx2fc_debug.h
@@ -1,3 +1,16 @@
+/* bnx2fc_debug.h: QLogic NetXtreme II Linux FCoE offload driver.
+ * Handles operations such as session offload/upload etc, and manages
+ * session resources such as connection id and qp resources.
+ *
+ * Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
+ *
+ */
+
#ifndef __BNX2FC_DEBUG__
#define __BNX2FC_DEBUG__
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c
index b1c9a4f8caee..ca75c7ca2559 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -1,9 +1,10 @@
/*
- * bnx2fc_els.c: Broadcom NetXtreme II Linux FCoE offload driver.
+ * bnx2fc_els.c: QLogic NetXtreme II Linux FCoE offload driver.
* This file contains helper routines that handle ELS requests
* and responses.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index f54843023466..79e5c94107a9 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -1,9 +1,10 @@
-/* bnx2fc_fcoe.c: Broadcom NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_fcoe.c: QLogic NetXtreme II Linux FCoE offload driver.
* This file contains the code that interacts with libfc, libfcoe,
* cnic modules to create FCoE instances, send/receive non-offloaded
* FIP/FCoE packets, listen to link events etc.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
@@ -26,12 +27,12 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
static char version[] =
- "Broadcom NetXtreme II FCoE Driver " DRV_MODULE_NAME \
+ "QLogic NetXtreme II FCoE Driver " DRV_MODULE_NAME \
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Bhanu Prakash Gollapudi <bprakash@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 FCoE Driver");
+MODULE_DESCRIPTION("QLogic NetXtreme II BCM57710 FCoE Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -516,23 +517,17 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
skb_pull(skb, sizeof(struct fcoe_hdr));
fr_len = skb->len - sizeof(struct fcoe_crc_eof);
- stats = per_cpu_ptr(lport->stats, get_cpu());
- stats->RxFrames++;
- stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
-
fp = (struct fc_frame *)skb;
fc_frame_init(fp);
fr_dev(fp) = lport;
fr_sof(fp) = hp->fcoe_sof;
if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
- put_cpu();
kfree_skb(skb);
return;
}
fr_eof(fp) = crc_eof.fcoe_eof;
fr_crc(fp) = crc_eof.fcoe_crc32;
if (pskb_trim(skb, fr_len)) {
- put_cpu();
kfree_skb(skb);
return;
}
@@ -544,7 +539,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
port = lport_priv(vn_port);
if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
- put_cpu();
kfree_skb(skb);
return;
}
@@ -552,7 +546,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
fh->fh_type == FC_TYPE_FCP) {
/* Drop FCP data. We dont this in L2 path */
- put_cpu();
kfree_skb(skb);
return;
}
@@ -562,7 +555,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
case ELS_LOGO:
if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
/* drop non-FIP LOGO */
- put_cpu();
kfree_skb(skb);
return;
}
@@ -572,22 +564,23 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) {
/* Drop incoming ABTS */
- put_cpu();
kfree_skb(skb);
return;
}
+ stats = per_cpu_ptr(lport->stats, smp_processor_id());
+ stats->RxFrames++;
+ stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
if (le32_to_cpu(fr_crc(fp)) !=
~crc32(~0, skb->data, fr_len)) {
if (stats->InvalidCRCCount < 5)
printk(KERN_WARNING PFX "dropping frame with "
"CRC error\n");
stats->InvalidCRCCount++;
- put_cpu();
kfree_skb(skb);
return;
}
- put_cpu();
fc_exch_recv(lport, fp);
}
@@ -700,7 +693,7 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
if (!lport->vport)
fc_host_max_npiv_vports(lport->host) = USHRT_MAX;
snprintf(fc_host_symbolic_name(lport->host), 256,
- "%s (Broadcom %s) v%s over %s",
+ "%s (QLogic %s) v%s over %s",
BNX2FC_NAME, hba->chip_num, BNX2FC_VERSION,
interface->netdev->name);
@@ -2783,7 +2776,7 @@ static struct fc_function_template bnx2fc_vport_xport_function = {
*/
static struct scsi_host_template bnx2fc_shost_template = {
.module = THIS_MODULE,
- .name = "Broadcom Offload FCoE Initiator",
+ .name = "QLogic Offload FCoE Initiator",
.queuecommand = bnx2fc_queuecommand,
.eh_abort_handler = bnx2fc_eh_abort, /* abts */
.eh_device_reset_handler = bnx2fc_eh_device_reset, /* lun reset */
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 512aed3ae4f1..c6688d72a846 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -1,8 +1,9 @@
-/* bnx2fc_hwi.c: Broadcom NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_hwi.c: QLogic NetXtreme II Linux FCoE offload driver.
* This file contains the code that low level functions that interact
* with 57712 FCoE firmware.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 32a5e0a2a669..4c5891e66038 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1,7 +1,8 @@
-/* bnx2fc_io.c: Broadcom NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_io.c: QLogic NetXtreme II Linux FCoE offload driver.
* IO manager and SCSI IO processing.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
@@ -282,6 +283,8 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba)
arr_sz, GFP_KERNEL);
if (!cmgr->free_list_lock) {
printk(KERN_ERR PFX "failed to alloc free_list_lock\n");
+ kfree(cmgr->free_list);
+ cmgr->free_list = NULL;
goto mem_err;
}
@@ -1448,9 +1451,9 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
struct bnx2fc_rport *tgt = io_req->tgt;
struct bnx2fc_cmd *cmd, *tmp;
- int tm_lun = sc_cmd->device->lun;
+ u64 tm_lun = sc_cmd->device->lun;
+ u64 lun;
int rc = 0;
- int lun;
/* called with tgt_lock held */
BNX2FC_IO_DBG(io_req, "Entered bnx2fc_lun_reset_cmpl\n");
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
index 6870cf6781d9..c66c708412a6 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
@@ -1,8 +1,9 @@
-/* bnx2fc_tgt.c: Broadcom NetXtreme II Linux FCoE offload driver.
+/* bnx2fc_tgt.c: QLogic NetXtreme II Linux FCoE offload driver.
* Handles operations such as session offload/upload etc, and manages
* session resources such as connection id and qp resources.
*
* Copyright (c) 2008 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
index 3d33767f2f2c..917534109a50 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h
@@ -1,13 +1,15 @@
-/* 57xx_iscsi_constants.h: Broadcom NetXtreme II iSCSI HSI
+/* 57xx_iscsi_constants.h: QLogic NetXtreme II iSCSI HSI
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#ifndef __57XX_ISCSI_CONSTANTS_H_
#define __57XX_ISCSI_CONSTANTS_H_
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
index 7052a839b0ea..19b3a97dbacd 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
@@ -1,13 +1,15 @@
-/* 57xx_iscsi_hsi.h: Broadcom NetXtreme II iSCSI HSI.
+/* 57xx_iscsi_hsi.h: QLogic NetXtreme II iSCSI HSI.
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#ifndef __57XX_ISCSI_HSI_LINUX_LE__
#define __57XX_ISCSI_HSI_LINUX_LE__
diff --git a/drivers/scsi/bnx2i/Kconfig b/drivers/scsi/bnx2i/Kconfig
index 01cff1894b6d..44ce54e536e5 100644
--- a/drivers/scsi/bnx2i/Kconfig
+++ b/drivers/scsi/bnx2i/Kconfig
@@ -1,5 +1,5 @@
config SCSI_BNX2_ISCSI
- tristate "Broadcom NetXtreme II iSCSI support"
+ tristate "QLogic NetXtreme II iSCSI support"
depends on NET
depends on PCI
select SCSI_ISCSI_ATTRS
@@ -8,5 +8,5 @@ config SCSI_BNX2_ISCSI
select NET_VENDOR_BROADCOM
select CNIC
---help---
- This driver supports iSCSI offload for the Broadcom NetXtreme II
+ This driver supports iSCSI offload for the QLogic NetXtreme II
devices.
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index c73bbcb63c02..ed7f3228e234 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -1,15 +1,17 @@
-/* bnx2i.h: Broadcom NetXtreme II iSCSI driver.
+/* bnx2i.h: QLogic NetXtreme II iSCSI driver.
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#ifndef _BNX2I_H_
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index d6d491c2f004..fb072cc5e9fd 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1,15 +1,17 @@
-/* bnx2i_hwi.c: Broadcom NetXtreme II iSCSI driver.
+/* bnx2i_hwi.c: QLogic NetXtreme II iSCSI driver.
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#include <linux/gfp.h>
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 80c03b452d61..c8b410c24cf0 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -1,15 +1,17 @@
-/* bnx2i.c: Broadcom NetXtreme II iSCSI driver.
+/* bnx2i.c: QLogic NetXtreme II iSCSI driver.
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#include "bnx2i.h"
@@ -18,18 +20,18 @@ static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
static u32 adapter_count;
#define DRV_MODULE_NAME "bnx2i"
-#define DRV_MODULE_VERSION "2.7.6.2"
-#define DRV_MODULE_RELDATE "Jun 06, 2013"
+#define DRV_MODULE_VERSION "2.7.10.1"
+#define DRV_MODULE_RELDATE "Jul 16, 2014"
static char version[] =
- "Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
+ "QLogic NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com> and "
"Eddie Wai <eddie.wai@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/57710/57711/57712"
+MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/57710/57711/57712"
"/57800/57810/57840 iSCSI Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 166543f7ef55..40e22497d249 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1,16 +1,18 @@
/*
- * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver.
+ * bnx2i_iscsi.c: QLogic NetXtreme II iSCSI driver.
*
* Copyright (c) 2006 - 2013 Broadcom Corporation
* Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved.
* Copyright (c) 2007, 2008 Mike Christie
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#include <linux/slab.h>
@@ -1643,12 +1645,11 @@ static void bnx2i_conn_get_stats(struct iscsi_cls_conn *cls_conn,
stats->r2t_pdus = conn->r2t_pdus_cnt;
stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
- stats->custom_length = 3;
- strcpy(stats->custom[2].desc, "eh_abort_cnt");
- stats->custom[2].value = conn->eh_abort_cnt;
stats->digest_err = 0;
stats->timeout_err = 0;
- stats->custom_length = 0;
+ strcpy(stats->custom[0].desc, "eh_abort_cnt");
+ stats->custom[0].value = conn->eh_abort_cnt;
+ stats->custom_length = 1;
}
@@ -2249,7 +2250,7 @@ static umode_t bnx2i_attr_is_visible(int param_type, int param)
*/
static struct scsi_host_template bnx2i_host_template = {
.module = THIS_MODULE,
- .name = "Broadcom Offload iSCSI Initiator",
+ .name = "QLogic Offload iSCSI Initiator",
.proc_name = "bnx2i",
.queuecommand = iscsi_queuecommand,
.eh_abort_handler = iscsi_eh_abort,
diff --git a/drivers/scsi/bnx2i/bnx2i_sysfs.c b/drivers/scsi/bnx2i/bnx2i_sysfs.c
index a0a3d9fe61fe..6d56fd60cb2b 100644
--- a/drivers/scsi/bnx2i/bnx2i_sysfs.c
+++ b/drivers/scsi/bnx2i/bnx2i_sysfs.c
@@ -1,13 +1,15 @@
-/* bnx2i_sysfs.c: Broadcom NetXtreme II iSCSI driver.
+/* bnx2i_sysfs.c: QLogic NetXtreme II iSCSI driver.
*
* Copyright (c) 2004 - 2013 Broadcom Corporation
+ * Copyright (c) 2014, QLogic 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.
*
* Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
- * Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
+ * Maintained by: QLogic-Storage-Upstream@qlogic.com
*/
#include "bnx2i.h"
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 2a323742ce04..ef5ae0d03616 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -84,15 +84,19 @@ static const char * vendor_labels[CH_TYPES-4] = {
};
// module_param_string_array(vendor_labels, NULL, 0444);
+#define ch_printk(prefix, ch, fmt, a...) \
+ sdev_printk(prefix, (ch)->device, "[%s] " fmt, \
+ (ch)->name, ##a)
+
#define DPRINTK(fmt, arg...) \
do { \
if (debug) \
- printk(KERN_DEBUG "%s: " fmt, ch->name, ##arg); \
+ ch_printk(KERN_DEBUG, ch, fmt, ##arg); \
} while (0)
#define VPRINTK(level, fmt, arg...) \
do { \
if (verbose) \
- printk(level "%s: " fmt, ch->name, ##arg); \
+ ch_printk(level, ch, fmt, ##arg); \
} while (0)
/* ------------------------------------------------------------------- */
@@ -196,7 +200,7 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd,
__scsi_print_command(cmd);
}
- result = scsi_execute_req(ch->device, cmd, direction, buffer,
+ result = scsi_execute_req(ch->device, cmd, direction, buffer,
buflength, &sshdr, timeout * HZ,
MAX_RETRIES, NULL);
@@ -247,7 +251,7 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
retry:
memset(cmd,0,sizeof(cmd));
cmd[0] = READ_ELEMENT_STATUS;
- cmd[1] = (ch->device->lun << 5) |
+ cmd[1] = ((ch->device->lun & 0x7) << 5) |
(ch->voltags ? 0x10 : 0) |
ch_elem_to_typecode(ch,elem);
cmd[2] = (elem >> 8) & 0xff;
@@ -283,7 +287,7 @@ ch_init_elem(scsi_changer *ch)
VPRINTK(KERN_INFO, "INITIALIZE ELEMENT STATUS, may take some time ...\n");
memset(cmd,0,sizeof(cmd));
cmd[0] = INITIALIZE_ELEMENT_STATUS;
- cmd[1] = ch->device->lun << 5;
+ cmd[1] = (ch->device->lun & 0x7) << 5;
err = ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE);
VPRINTK(KERN_INFO, "... finished\n");
return err;
@@ -303,7 +307,7 @@ ch_readconfig(scsi_changer *ch)
memset(cmd,0,sizeof(cmd));
cmd[0] = MODE_SENSE;
- cmd[1] = ch->device->lun << 5;
+ cmd[1] = (ch->device->lun & 0x7) << 5;
cmd[2] = 0x1d;
cmd[4] = 255;
result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE);
@@ -428,7 +432,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
trans = ch->firsts[CHET_MT];
memset(cmd,0,sizeof(cmd));
cmd[0] = POSITION_TO_ELEMENT;
- cmd[1] = ch->device->lun << 5;
+ cmd[1] = (ch->device->lun & 0x7) << 5;
cmd[2] = (trans >> 8) & 0xff;
cmd[3] = trans & 0xff;
cmd[4] = (elem >> 8) & 0xff;
@@ -447,7 +451,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
trans = ch->firsts[CHET_MT];
memset(cmd,0,sizeof(cmd));
cmd[0] = MOVE_MEDIUM;
- cmd[1] = ch->device->lun << 5;
+ cmd[1] = (ch->device->lun & 0x7) << 5;
cmd[2] = (trans >> 8) & 0xff;
cmd[3] = trans & 0xff;
cmd[4] = (src >> 8) & 0xff;
@@ -470,7 +474,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src,
trans = ch->firsts[CHET_MT];
memset(cmd,0,sizeof(cmd));
cmd[0] = EXCHANGE_MEDIUM;
- cmd[1] = ch->device->lun << 5;
+ cmd[1] = (ch->device->lun & 0x7) << 5;
cmd[2] = (trans >> 8) & 0xff;
cmd[3] = trans & 0xff;
cmd[4] = (src >> 8) & 0xff;
@@ -518,7 +522,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
elem, tag);
memset(cmd,0,sizeof(cmd));
cmd[0] = SEND_VOLUME_TAG;
- cmd[1] = (ch->device->lun << 5) |
+ cmd[1] = ((ch->device->lun & 0x7) << 5) |
ch_elem_to_typecode(ch,elem);
cmd[2] = (elem >> 8) & 0xff;
cmd[3] = elem & 0xff;
@@ -754,7 +758,7 @@ static long ch_ioctl(struct file *file,
voltag_retry:
memset(ch_cmd, 0, sizeof(ch_cmd));
ch_cmd[0] = READ_ELEMENT_STATUS;
- ch_cmd[1] = (ch->device->lun << 5) |
+ ch_cmd[1] = ((ch->device->lun & 0x7) << 5) |
(ch->voltags ? 0x10 : 0) |
ch_elem_to_typecode(ch,elem);
ch_cmd[2] = (elem >> 8) & 0xff;
@@ -924,8 +928,8 @@ static int ch_probe(struct device *dev)
MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
"s%s", ch->name);
if (IS_ERR(class_dev)) {
- printk(KERN_WARNING "ch%d: device_create failed\n",
- ch->minor);
+ sdev_printk(KERN_WARNING, sd, "ch%d: device_create failed\n",
+ ch->minor);
ret = PTR_ERR(class_dev);
goto remove_idr;
}
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index 7494e4bc69cc..86103c8475d8 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1657,7 +1657,7 @@ csio_scsi_err_handler(struct csio_hw *hw, struct csio_ioreq *req)
case FW_SCSI_UNDER_FLOW_ERR:
csio_warn(hw,
"Under-flow error,cmnd:0x%x expected"
- " len:0x%x resid:0x%x lun:0x%x ssn:0x%x\n",
+ " len:0x%x resid:0x%x lun:0x%llx ssn:0x%x\n",
cmnd->cmnd[0], scsi_bufflen(cmnd),
scsi_get_resid(cmnd), cmnd->device->lun,
rn->flowid);
@@ -1957,7 +1957,7 @@ csio_eh_abort_handler(struct scsi_cmnd *cmnd)
csio_dbg(hw,
"Request to abort ioreq:%p cmd:%p cdb:%08llx"
- " ssni:0x%x lun:%d iq:0x%x\n",
+ " ssni:0x%x lun:%llu iq:0x%x\n",
ioreq, cmnd, *((uint64_t *)cmnd->cmnd), rn->flowid,
cmnd->device->lun, csio_q_physiqid(hw, ioreq->iq_idx));
@@ -2015,13 +2015,13 @@ inval_scmnd:
/* FW successfully aborted the request */
if (host_byte(cmnd->result) == DID_REQUEUE) {
csio_info(hw,
- "Aborted SCSI command to (%d:%d) serial#:0x%lx\n",
+ "Aborted SCSI command to (%d:%llu) serial#:0x%lx\n",
cmnd->device->id, cmnd->device->lun,
cmnd->serial_number);
return SUCCESS;
} else {
csio_info(hw,
- "Failed to abort SCSI command, (%d:%d) serial#:0x%lx\n",
+ "Failed to abort SCSI command, (%d:%llu) serial#:0x%lx\n",
cmnd->device->id, cmnd->device->lun,
cmnd->serial_number);
return FAILED;
@@ -2100,13 +2100,13 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
if (!rn)
goto fail;
- csio_dbg(hw, "Request to reset LUN:%d (ssni:0x%x tgtid:%d)\n",
+ csio_dbg(hw, "Request to reset LUN:%llu (ssni:0x%x tgtid:%d)\n",
cmnd->device->lun, rn->flowid, rn->scsi_id);
if (!csio_is_lnode_ready(ln)) {
csio_err(hw,
"LUN reset cannot be issued on non-ready"
- " local node vnpi:0x%x (LUN:%d)\n",
+ " local node vnpi:0x%x (LUN:%llu)\n",
ln->vnp_flowid, cmnd->device->lun);
goto fail;
}
@@ -2126,7 +2126,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
if (fc_remote_port_chkready(rn->rport)) {
csio_err(hw,
"LUN reset cannot be issued on non-ready"
- " remote node ssni:0x%x (LUN:%d)\n",
+ " remote node ssni:0x%x (LUN:%llu)\n",
rn->flowid, cmnd->device->lun);
goto fail;
}
@@ -2168,7 +2168,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
sld.level = CSIO_LEV_LUN;
sld.lnode = ioreq->lnode;
sld.rnode = ioreq->rnode;
- sld.oslun = (uint64_t)cmnd->device->lun;
+ sld.oslun = cmnd->device->lun;
spin_lock_irqsave(&hw->lock, flags);
/* Kick off TM SM on the ioreq */
@@ -2190,7 +2190,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
/* LUN reset timed-out */
if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd) {
- csio_err(hw, "LUN reset (%d:%d) timed out\n",
+ csio_err(hw, "LUN reset (%d:%llu) timed out\n",
cmnd->device->id, cmnd->device->lun);
spin_lock_irq(&hw->lock);
@@ -2203,7 +2203,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
/* LUN reset returned, check cached status */
if (cmnd->SCp.Status != FW_SUCCESS) {
- csio_err(hw, "LUN reset failed (%d:%d), status: %d\n",
+ csio_err(hw, "LUN reset failed (%d:%llu), status: %d\n",
cmnd->device->id, cmnd->device->lun, cmnd->SCp.Status);
goto fail;
}
@@ -2223,7 +2223,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
/* Aborts may have timed out */
if (retval != 0) {
csio_err(hw,
- "Attempt to abort I/Os during LUN reset of %d"
+ "Attempt to abort I/Os during LUN reset of %llu"
" returned %d\n", cmnd->device->lun, retval);
/* Return I/Os back to active_q */
spin_lock_irq(&hw->lock);
@@ -2234,7 +2234,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
CSIO_INC_STATS(rn, n_lun_rst);
- csio_info(hw, "LUN reset occurred (%d:%d)\n",
+ csio_info(hw, "LUN reset occurred (%d:%llu)\n",
cmnd->device->id, cmnd->device->lun);
return SUCCESS;
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index e8ee5e5fe0ef..79788a12712d 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -19,6 +19,7 @@
#include <net/tcp.h>
#include <net/dst.h>
#include <linux/netdevice.h>
+#include <net/addrconf.h>
#include "t4_regs.h"
#include "t4_msg.h"
@@ -150,6 +151,7 @@ static struct scsi_transport_template *cxgb4i_stt;
* The section below implments CPLs that related to iscsi tcp connection
* open/close/abort and data send/receive.
*/
+
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define RCV_BUFSIZ_MASK 0x3FFU
#define MAX_IMM_TX_PKT_LEN 128
@@ -179,6 +181,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
struct l2t_entry *e)
{
struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
+ int t4 = is_t4(lldi->adapter_type);
int wscale = cxgbi_sock_compute_wscale(csk->mss_idx);
unsigned long long opt0;
unsigned int opt2;
@@ -248,6 +251,97 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
}
set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id);
+
+ pr_info_ipaddr("t%d csk 0x%p,%u,0x%lx,%u, rss_qid %u.\n",
+ (&csk->saddr), (&csk->daddr), t4 ? 4 : 5, csk,
+ csk->state, csk->flags, csk->atid, csk->rss_qid);
+
+ cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
+}
+
+static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb,
+ struct l2t_entry *e)
+{
+ struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
+ int t4 = is_t4(lldi->adapter_type);
+ int wscale = cxgbi_sock_compute_wscale(csk->mss_idx);
+ unsigned long long opt0;
+ unsigned int opt2;
+ unsigned int qid_atid = ((unsigned int)csk->atid) |
+ (((unsigned int)csk->rss_qid) << 14);
+
+ opt0 = KEEP_ALIVE(1) |
+ WND_SCALE(wscale) |
+ MSS_IDX(csk->mss_idx) |
+ L2T_IDX(((struct l2t_entry *)csk->l2t)->idx) |
+ TX_CHAN(csk->tx_chan) |
+ SMAC_SEL(csk->smac_idx) |
+ ULP_MODE(ULP_MODE_ISCSI) |
+ RCV_BUFSIZ(cxgb4i_rcv_win >> 10);
+
+ opt2 = RX_CHANNEL(0) |
+ RSS_QUEUE_VALID |
+ RX_FC_DISABLE |
+ RSS_QUEUE(csk->rss_qid);
+
+ if (t4) {
+ struct cpl_act_open_req6 *req =
+ (struct cpl_act_open_req6 *)skb->head;
+
+ INIT_TP_WR(req, 0);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
+ qid_atid));
+ req->local_port = csk->saddr6.sin6_port;
+ req->peer_port = csk->daddr6.sin6_port;
+
+ req->local_ip_hi = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr);
+ req->local_ip_lo = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr +
+ 8);
+ req->peer_ip_hi = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr);
+ req->peer_ip_lo = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr +
+ 8);
+
+ req->opt0 = cpu_to_be64(opt0);
+
+ opt2 |= RX_FC_VALID;
+ req->opt2 = cpu_to_be32(opt2);
+
+ req->params = cpu_to_be32(cxgb4_select_ntuple(
+ csk->cdev->ports[csk->port_id],
+ csk->l2t));
+ } else {
+ struct cpl_t5_act_open_req6 *req =
+ (struct cpl_t5_act_open_req6 *)skb->head;
+
+ INIT_TP_WR(req, 0);
+ OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
+ qid_atid));
+ req->local_port = csk->saddr6.sin6_port;
+ req->peer_port = csk->daddr6.sin6_port;
+ req->local_ip_hi = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr);
+ req->local_ip_lo = *(__be64 *)(csk->saddr6.sin6_addr.s6_addr +
+ 8);
+ req->peer_ip_hi = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr);
+ req->peer_ip_lo = *(__be64 *)(csk->daddr6.sin6_addr.s6_addr +
+ 8);
+ req->opt0 = cpu_to_be64(opt0);
+
+ opt2 |= T5_OPT_2_VALID;
+ req->opt2 = cpu_to_be32(opt2);
+
+ req->params = cpu_to_be64(V_FILTER_TUPLE(cxgb4_select_ntuple(
+ csk->cdev->ports[csk->port_id],
+ csk->l2t)));
+ }
+
+ set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id);
+
+ pr_info("t%d csk 0x%p,%u,0x%lx,%u, [%pI6]:%u-[%pI6]:%u, rss_qid %u.\n",
+ t4 ? 4 : 5, csk, csk->state, csk->flags, csk->atid,
+ &csk->saddr6.sin6_addr, ntohs(csk->saddr.sin_port),
+ &csk->daddr6.sin6_addr, ntohs(csk->daddr.sin_port),
+ csk->rss_qid);
+
cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
}
@@ -586,9 +680,11 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
goto rel_skb;
}
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,%u,0x%lx, tid %u, atid %u, rseq %u.\n",
- csk, csk->state, csk->flags, tid, atid, rcv_isn);
+ pr_info_ipaddr("atid 0x%x, tid 0x%x, csk 0x%p,%u,0x%lx, isn %u.\n",
+ (&csk->saddr), (&csk->daddr),
+ atid, tid, csk, csk->state, csk->flags, rcv_isn);
+
+ module_put(THIS_MODULE);
cxgbi_sock_get(csk);
csk->tid = tid;
@@ -663,6 +759,9 @@ static void csk_act_open_retry_timer(unsigned long data)
struct sk_buff *skb;
struct cxgbi_sock *csk = (struct cxgbi_sock *)data;
struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
+ void (*send_act_open_func)(struct cxgbi_sock *, struct sk_buff *,
+ struct l2t_entry *);
+ int t4 = is_t4(lldi->adapter_type), size, size6;
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p,%u,0x%lx,%u.\n",
@@ -670,20 +769,35 @@ static void csk_act_open_retry_timer(unsigned long data)
cxgbi_sock_get(csk);
spin_lock_bh(&csk->lock);
- skb = alloc_wr(is_t4(lldi->adapter_type) ?
- sizeof(struct cpl_act_open_req) :
- sizeof(struct cpl_t5_act_open_req),
- 0, GFP_ATOMIC);
+
+ if (t4) {
+ size = sizeof(struct cpl_act_open_req);
+ size6 = sizeof(struct cpl_act_open_req6);
+ } else {
+ size = sizeof(struct cpl_t5_act_open_req);
+ size6 = sizeof(struct cpl_t5_act_open_req6);
+ }
+
+ if (csk->csk_family == AF_INET) {
+ send_act_open_func = send_act_open_req;
+ skb = alloc_wr(size, 0, GFP_ATOMIC);
+ } else {
+ send_act_open_func = send_act_open_req6;
+ skb = alloc_wr(size6, 0, GFP_ATOMIC);
+ }
+
if (!skb)
cxgbi_sock_fail_act_open(csk, -ENOMEM);
else {
skb->sk = (struct sock *)csk;
t4_set_arp_err_handler(skb, csk,
- cxgbi_sock_act_open_req_arp_failure);
- send_act_open_req(csk, skb, csk->l2t);
+ cxgbi_sock_act_open_req_arp_failure);
+ send_act_open_func(csk, skb, csk->l2t);
}
+
spin_unlock_bh(&csk->lock);
cxgbi_sock_put(csk);
+
}
static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
@@ -703,10 +817,9 @@ static void do_act_open_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
goto rel_skb;
}
- pr_info("%pI4:%u-%pI4:%u, atid %u,%u, status %u, csk 0x%p,%u,0x%lx.\n",
- &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port),
- &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port),
- atid, tid, status, csk, csk->state, csk->flags);
+ pr_info_ipaddr("tid %u/%u, status %u.\n"
+ "csk 0x%p,%u,0x%lx. ", (&csk->saddr), (&csk->daddr),
+ atid, tid, status, csk, csk->state, csk->flags);
if (status == CPL_ERR_RTX_NEG_ADVICE)
goto rel_skb;
@@ -746,9 +859,9 @@ static void do_peer_close(struct cxgbi_device *cdev, struct sk_buff *skb)
pr_err("can't find connection for tid %u.\n", tid);
goto rel_skb;
}
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,%u,0x%lx,%u.\n",
- csk, csk->state, csk->flags, csk->tid);
+ pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u.\n",
+ (&csk->saddr), (&csk->daddr),
+ csk, csk->state, csk->flags, csk->tid);
cxgbi_sock_rcv_peer_close(csk);
rel_skb:
__kfree_skb(skb);
@@ -767,9 +880,9 @@ static void do_close_con_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
pr_err("can't find connection for tid %u.\n", tid);
goto rel_skb;
}
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,%u,0x%lx,%u.\n",
- csk, csk->state, csk->flags, csk->tid);
+ pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u.\n",
+ (&csk->saddr), (&csk->daddr),
+ csk, csk->state, csk->flags, csk->tid);
cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt));
rel_skb:
__kfree_skb(skb);
@@ -808,9 +921,9 @@ static void do_abort_req_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
goto rel_skb;
}
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,%u,0x%lx, tid %u, status 0x%x.\n",
- csk, csk->state, csk->flags, csk->tid, req->status);
+ pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n",
+ (&csk->saddr), (&csk->daddr),
+ csk, csk->state, csk->flags, csk->tid, req->status);
if (req->status == CPL_ERR_RTX_NEG_ADVICE ||
req->status == CPL_ERR_PERSIST_NEG_ADVICE)
@@ -851,10 +964,10 @@ static void do_abort_rpl_rss(struct cxgbi_device *cdev, struct sk_buff *skb)
if (!csk)
goto rel_skb;
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "status 0x%x, csk 0x%p, s %u, 0x%lx.\n",
- rpl->status, csk, csk ? csk->state : 0,
- csk ? csk->flags : 0UL);
+ if (csk)
+ pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n",
+ (&csk->saddr), (&csk->daddr), csk,
+ csk->state, csk->flags, csk->tid, rpl->status);
if (rpl->status == CPL_ERR_ABORT_FAILED)
goto rel_skb;
@@ -1163,15 +1276,35 @@ static int init_act_open(struct cxgbi_sock *csk)
struct cxgbi_device *cdev = csk->cdev;
struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
struct net_device *ndev = cdev->ports[csk->port_id];
- struct port_info *pi = netdev_priv(ndev);
struct sk_buff *skb = NULL;
- struct neighbour *n;
+ struct neighbour *n = NULL;
+ void *daddr;
unsigned int step;
+ unsigned int size, size6;
+ int t4 = is_t4(lldi->adapter_type);
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p,%u,0x%lx,%u.\n",
csk, csk->state, csk->flags, csk->tid);
+ if (csk->csk_family == AF_INET)
+ daddr = &csk->daddr.sin_addr.s_addr;
+#if IS_ENABLED(CONFIG_IPV6)
+ else if (csk->csk_family == AF_INET6)
+ daddr = &csk->daddr6.sin6_addr;
+#endif
+ else {
+ pr_err("address family 0x%x not supported\n", csk->csk_family);
+ goto rel_resource;
+ }
+
+ n = dst_neigh_lookup(csk->dst, daddr);
+
+ if (!n) {
+ pr_err("%s, can't get neighbour of csk->dst.\n", ndev->name);
+ goto rel_resource;
+ }
+
csk->atid = cxgb4_alloc_atid(lldi->tids, csk);
if (csk->atid < 0) {
pr_err("%s, NO atid available.\n", ndev->name);
@@ -1192,10 +1325,19 @@ static int init_act_open(struct cxgbi_sock *csk)
}
cxgbi_sock_get(csk);
- skb = alloc_wr(is_t4(lldi->adapter_type) ?
- sizeof(struct cpl_act_open_req) :
- sizeof(struct cpl_t5_act_open_req),
- 0, GFP_ATOMIC);
+ if (t4) {
+ size = sizeof(struct cpl_act_open_req);
+ size6 = sizeof(struct cpl_act_open_req6);
+ } else {
+ size = sizeof(struct cpl_t5_act_open_req);
+ size6 = sizeof(struct cpl_t5_act_open_req6);
+ }
+
+ if (csk->csk_family == AF_INET)
+ skb = alloc_wr(size, 0, GFP_NOIO);
+ else
+ skb = alloc_wr(size6, 0, GFP_NOIO);
+
if (!skb)
goto rel_resource;
skb->sk = (struct sock *)csk;
@@ -1211,19 +1353,27 @@ static int init_act_open(struct cxgbi_sock *csk)
csk->txq_idx = cxgb4_port_idx(ndev) * step;
step = lldi->nrxq / lldi->nchan;
csk->rss_qid = lldi->rxq_ids[cxgb4_port_idx(ndev) * step];
- csk->wr_max_cred = csk->wr_cred = lldi->wr_cred;
+ csk->wr_cred = lldi->wr_cred -
+ DIV_ROUND_UP(sizeof(struct cpl_abort_req), 16);
+ csk->wr_max_cred = csk->wr_cred;
csk->wr_una_cred = 0;
cxgbi_sock_reset_wr_list(csk);
csk->err = 0;
- log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
- "csk 0x%p,p%d,%s, %u,%u,%u, mss %u,%u, smac %u.\n",
- csk, pi->port_id, ndev->name, csk->tx_chan,
- csk->txq_idx, csk->rss_qid, csk->mtu, csk->mss_idx,
- csk->smac_idx);
+ pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u,%u,%u, mtu %u,%u, smac %u.\n",
+ (&csk->saddr), (&csk->daddr), csk, csk->state,
+ csk->flags, csk->tx_chan, csk->txq_idx, csk->rss_qid,
+ csk->mtu, csk->mss_idx, csk->smac_idx);
+
+ /* must wait for either a act_open_rpl or act_open_establish */
+ try_module_get(THIS_MODULE);
cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN);
- send_act_open_req(csk, skb, csk->l2t);
+ if (csk->csk_family == AF_INET)
+ send_act_open_req(csk, skb, csk->l2t);
+ else
+ send_act_open_req6(csk, skb, csk->l2t);
neigh_release(n);
+
return 0;
rel_resource:
@@ -1234,8 +1384,6 @@ rel_resource:
return -EINVAL;
}
-#define CPL_ISCSI_DATA 0xB2
-#define CPL_RX_ISCSI_DDP 0x49
cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = {
[CPL_ACT_ESTABLISH] = do_act_establish,
[CPL_ACT_OPEN_RPL] = do_act_open_rpl,
@@ -1487,6 +1635,129 @@ static int cxgb4i_ddp_init(struct cxgbi_device *cdev)
return 0;
}
+#if IS_ENABLED(CONFIG_IPV6)
+static int cxgbi_inet6addr_handler(struct notifier_block *this,
+ unsigned long event, void *data)
+{
+ struct inet6_ifaddr *ifa = data;
+ struct net_device *event_dev = ifa->idev->dev;
+ struct cxgbi_device *cdev;
+ int ret = NOTIFY_DONE;
+
+ if (event_dev->priv_flags & IFF_802_1Q_VLAN)
+ event_dev = vlan_dev_real_dev(event_dev);
+
+ cdev = cxgbi_device_find_by_netdev(event_dev, NULL);
+
+ if (!cdev)
+ return ret;
+
+ switch (event) {
+ case NETDEV_UP:
+ ret = cxgb4_clip_get(event_dev,
+ (const struct in6_addr *)
+ ((ifa)->addr.s6_addr));
+ if (ret < 0)
+ return ret;
+
+ ret = NOTIFY_OK;
+ break;
+
+ case NETDEV_DOWN:
+ cxgb4_clip_release(event_dev,
+ (const struct in6_addr *)
+ ((ifa)->addr.s6_addr));
+ ret = NOTIFY_OK;
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static struct notifier_block cxgbi_inet6addr_notifier = {
+ .notifier_call = cxgbi_inet6addr_handler
+};
+
+/* Retrieve IPv6 addresses from a root device (bond, vlan) associated with
+ * a physical device.
+ * The physical device reference is needed to send the actual CLIP command.
+ */
+static int update_dev_clip(struct net_device *root_dev, struct net_device *dev)
+{
+ struct inet6_dev *idev = NULL;
+ struct inet6_ifaddr *ifa;
+ int ret = 0;
+
+ idev = __in6_dev_get(root_dev);
+ if (!idev)
+ return ret;
+
+ read_lock_bh(&idev->lock);
+ list_for_each_entry(ifa, &idev->addr_list, if_list) {
+ pr_info("updating the clip for addr %pI6\n",
+ ifa->addr.s6_addr);
+ ret = cxgb4_clip_get(dev, (const struct in6_addr *)
+ ifa->addr.s6_addr);
+ if (ret < 0)
+ break;
+ }
+
+ read_unlock_bh(&idev->lock);
+ return ret;
+}
+
+static int update_root_dev_clip(struct net_device *dev)
+{
+ struct net_device *root_dev = NULL;
+ int i, ret = 0;
+
+ /* First populate the real net device's IPv6 address */
+ ret = update_dev_clip(dev, dev);
+ if (ret)
+ return ret;
+
+ /* Parse all bond and vlan devices layered on top of the physical dev */
+ root_dev = netdev_master_upper_dev_get(dev);
+ if (root_dev) {
+ ret = update_dev_clip(root_dev, dev);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < VLAN_N_VID; i++) {
+ root_dev = __vlan_find_dev_deep_rcu(dev, htons(ETH_P_8021Q), i);
+ if (!root_dev)
+ continue;
+
+ ret = update_dev_clip(root_dev, dev);
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
+static void cxgbi_update_clip(struct cxgbi_device *cdev)
+{
+ int i;
+
+ rcu_read_lock();
+
+ for (i = 0; i < cdev->nports; i++) {
+ struct net_device *dev = cdev->ports[i];
+ int ret = 0;
+
+ if (dev)
+ ret = update_root_dev_clip(dev);
+ if (ret < 0)
+ break;
+ }
+ rcu_read_unlock();
+}
+#endif /* IS_ENABLED(CONFIG_IPV6) */
+
static void *t4_uld_add(const struct cxgb4_lld_info *lldi)
{
struct cxgbi_device *cdev;
@@ -1605,6 +1876,9 @@ static int t4_uld_state_change(void *handle, enum cxgb4_state state)
switch (state) {
case CXGB4_STATE_UP:
pr_info("cdev 0x%p, UP.\n", cdev);
+#if IS_ENABLED(CONFIG_IPV6)
+ cxgbi_update_clip(cdev);
+#endif
/* re-initialize */
break;
case CXGB4_STATE_START_RECOVERY:
@@ -1635,11 +1909,18 @@ static int __init cxgb4i_init_module(void)
if (rc < 0)
return rc;
cxgb4_register_uld(CXGB4_ULD_ISCSI, &cxgb4i_uld_info);
+
+#if IS_ENABLED(CONFIG_IPV6)
+ register_inet6addr_notifier(&cxgbi_inet6addr_notifier);
+#endif
return 0;
}
static void __exit cxgb4i_exit_module(void)
{
+#if IS_ENABLED(CONFIG_IPV6)
+ unregister_inet6addr_notifier(&cxgbi_inet6addr_notifier);
+#endif
cxgb4_unregister_uld(CXGB4_ULD_ISCSI);
cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T4);
cxgbi_iscsi_cleanup(&cxgb4i_iscsi_transport, &cxgb4i_stt);
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index b44c1cff3114..d65df6dc106f 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -24,6 +24,10 @@
#include <linux/inet.h>
#include <net/dst.h>
#include <net/route.h>
+#include <net/ipv6.h>
+#include <net/ip6_route.h>
+#include <net/addrconf.h>
+
#include <linux/inetdevice.h> /* ip_dev_find */
#include <linux/module.h>
#include <net/tcp.h>
@@ -193,8 +197,8 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev)
}
EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev);
-static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
- int *port)
+struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
+ int *port)
{
struct net_device *vdev = NULL;
struct cxgbi_device *cdev, *tmp;
@@ -224,6 +228,40 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev,
"ndev 0x%p, %s, NO match found.\n", ndev, ndev->name);
return NULL;
}
+EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev);
+
+static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev,
+ int *port)
+{
+ struct net_device *vdev = NULL;
+ struct cxgbi_device *cdev, *tmp;
+ int i;
+
+ if (ndev->priv_flags & IFF_802_1Q_VLAN) {
+ vdev = ndev;
+ ndev = vlan_dev_real_dev(ndev);
+ pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name);
+ }
+
+ mutex_lock(&cdev_mutex);
+ list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) {
+ for (i = 0; i < cdev->nports; i++) {
+ if (!memcmp(ndev->dev_addr, cdev->ports[i]->dev_addr,
+ MAX_ADDR_LEN)) {
+ cdev->hbas[i]->vdev = vdev;
+ mutex_unlock(&cdev_mutex);
+ if (port)
+ *port = i;
+ return cdev;
+ }
+ }
+ }
+ mutex_unlock(&cdev_mutex);
+ log_debug(1 << CXGBI_DBG_DEV,
+ "ndev 0x%p, %s, NO match mac found.\n",
+ ndev, ndev->name);
+ return NULL;
+}
void cxgbi_hbas_remove(struct cxgbi_device *cdev)
{
@@ -245,7 +283,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev)
}
EXPORT_SYMBOL_GPL(cxgbi_hbas_remove);
-int cxgbi_hbas_add(struct cxgbi_device *cdev, unsigned int max_lun,
+int cxgbi_hbas_add(struct cxgbi_device *cdev, u64 max_lun,
unsigned int max_id, struct scsi_host_template *sht,
struct scsi_transport_template *stt)
{
@@ -320,6 +358,7 @@ static int sock_get_port(struct cxgbi_sock *csk)
struct cxgbi_ports_map *pmap = &cdev->pmap;
unsigned int start;
int idx;
+ __be16 *port;
if (!pmap->max_connect) {
pr_err("cdev 0x%p, p#%u %s, NO port map.\n",
@@ -327,9 +366,14 @@ static int sock_get_port(struct cxgbi_sock *csk)
return -EADDRNOTAVAIL;
}
- if (csk->saddr.sin_port) {
+ if (csk->csk_family == AF_INET)
+ port = &csk->saddr.sin_port;
+ else /* ipv6 */
+ port = &csk->saddr6.sin6_port;
+
+ if (*port) {
pr_err("source port NON-ZERO %u.\n",
- ntohs(csk->saddr.sin_port));
+ ntohs(*port));
return -EADDRINUSE;
}
@@ -347,8 +391,7 @@ static int sock_get_port(struct cxgbi_sock *csk)
idx = 0;
if (!pmap->port_csk[idx]) {
pmap->used++;
- csk->saddr.sin_port =
- htons(pmap->sport_base + idx);
+ *port = htons(pmap->sport_base + idx);
pmap->next = idx;
pmap->port_csk[idx] = csk;
spin_unlock_bh(&pmap->lock);
@@ -374,16 +417,22 @@ static void sock_put_port(struct cxgbi_sock *csk)
{
struct cxgbi_device *cdev = csk->cdev;
struct cxgbi_ports_map *pmap = &cdev->pmap;
+ __be16 *port;
- if (csk->saddr.sin_port) {
- int idx = ntohs(csk->saddr.sin_port) - pmap->sport_base;
+ if (csk->csk_family == AF_INET)
+ port = &csk->saddr.sin_port;
+ else /* ipv6 */
+ port = &csk->saddr6.sin6_port;
- csk->saddr.sin_port = 0;
+ if (*port) {
+ int idx = ntohs(*port) - pmap->sport_base;
+
+ *port = 0;
if (idx < 0 || idx >= pmap->max_connect) {
pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n",
cdev, csk->port_id,
cdev->ports[csk->port_id]->name,
- ntohs(csk->saddr.sin_port));
+ ntohs(*port));
return;
}
@@ -479,17 +528,11 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
int port = 0xFFFF;
int err = 0;
- if (daddr->sin_family != AF_INET) {
- pr_info("address family 0x%x NOT supported.\n",
- daddr->sin_family);
- err = -EAFNOSUPPORT;
- goto err_out;
- }
-
rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
if (!rt) {
pr_info("no route to ipv4 0x%x, port %u.\n",
- daddr->sin_addr.s_addr, daddr->sin_port);
+ be32_to_cpu(daddr->sin_addr.s_addr),
+ be16_to_cpu(daddr->sin_port));
err = -ENETUNREACH;
goto err_out;
}
@@ -537,9 +580,12 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
csk->port_id = port;
csk->mtu = mtu;
csk->dst = dst;
+
+ csk->csk_family = AF_INET;
csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
csk->daddr.sin_port = daddr->sin_port;
csk->daddr.sin_family = daddr->sin_family;
+ csk->saddr.sin_family = daddr->sin_family;
csk->saddr.sin_addr.s_addr = fl4.saddr;
neigh_release(n);
@@ -556,6 +602,123 @@ err_out:
return ERR_PTR(err);
}
+#if IS_ENABLED(CONFIG_IPV6)
+static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr,
+ const struct in6_addr *daddr)
+{
+ struct flowi6 fl;
+
+ if (saddr)
+ memcpy(&fl.saddr, saddr, sizeof(struct in6_addr));
+ if (daddr)
+ memcpy(&fl.daddr, daddr, sizeof(struct in6_addr));
+ return (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
+}
+
+static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr)
+{
+ struct sockaddr_in6 *daddr6 = (struct sockaddr_in6 *)dst_addr;
+ struct dst_entry *dst;
+ struct net_device *ndev;
+ struct cxgbi_device *cdev;
+ struct rt6_info *rt = NULL;
+ struct neighbour *n;
+ struct in6_addr pref_saddr;
+ struct cxgbi_sock *csk = NULL;
+ unsigned int mtu = 0;
+ int port = 0xFFFF;
+ int err = 0;
+
+ rt = find_route_ipv6(NULL, &daddr6->sin6_addr);
+
+ if (!rt) {
+ pr_info("no route to ipv6 %pI6 port %u\n",
+ daddr6->sin6_addr.s6_addr,
+ be16_to_cpu(daddr6->sin6_port));
+ err = -ENETUNREACH;
+ goto err_out;
+ }
+
+ dst = &rt->dst;
+
+ n = dst_neigh_lookup(dst, &daddr6->sin6_addr);
+
+ if (!n) {
+ pr_info("%pI6, port %u, dst no neighbour.\n",
+ daddr6->sin6_addr.s6_addr,
+ be16_to_cpu(daddr6->sin6_port));
+ err = -ENETUNREACH;
+ goto rel_rt;
+ }
+ ndev = n->dev;
+
+ if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
+ pr_info("multi-cast route %pI6 port %u, dev %s.\n",
+ daddr6->sin6_addr.s6_addr,
+ ntohs(daddr6->sin6_port), ndev->name);
+ err = -ENETUNREACH;
+ goto rel_rt;
+ }
+
+ cdev = cxgbi_device_find_by_netdev(ndev, &port);
+ if (!cdev)
+ cdev = cxgbi_device_find_by_mac(ndev, &port);
+ if (!cdev) {
+ pr_info("dst %pI6 %s, NOT cxgbi device.\n",
+ daddr6->sin6_addr.s6_addr, ndev->name);
+ err = -ENETUNREACH;
+ goto rel_rt;
+ }
+ log_debug(1 << CXGBI_DBG_SOCK,
+ "route to %pI6 :%u, ndev p#%d,%s, cdev 0x%p.\n",
+ daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), port,
+ ndev->name, cdev);
+
+ csk = cxgbi_sock_create(cdev);
+ if (!csk) {
+ err = -ENOMEM;
+ goto rel_rt;
+ }
+ csk->cdev = cdev;
+ csk->port_id = port;
+ csk->mtu = mtu;
+ csk->dst = dst;
+
+ if (ipv6_addr_any(&rt->rt6i_prefsrc.addr)) {
+ struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
+
+ err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL,
+ &daddr6->sin6_addr, 0, &pref_saddr);
+ if (err) {
+ pr_info("failed to get source address to reach %pI6\n",
+ &daddr6->sin6_addr);
+ goto rel_rt;
+ }
+ } else {
+ pref_saddr = rt->rt6i_prefsrc.addr;
+ }
+
+ csk->csk_family = AF_INET6;
+ csk->daddr6.sin6_addr = daddr6->sin6_addr;
+ csk->daddr6.sin6_port = daddr6->sin6_port;
+ csk->daddr6.sin6_family = daddr6->sin6_family;
+ csk->saddr6.sin6_addr = pref_saddr;
+
+ neigh_release(n);
+ return csk;
+
+rel_rt:
+ if (n)
+ neigh_release(n);
+
+ ip6_rt_put(rt);
+ if (csk)
+ cxgbi_sock_closed(csk);
+err_out:
+ return ERR_PTR(err);
+}
+#endif /* IS_ENABLED(CONFIG_IPV6) */
+
void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn,
unsigned int opt)
{
@@ -2194,6 +2357,34 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn,
}
EXPORT_SYMBOL_GPL(cxgbi_set_conn_param);
+static inline int csk_print_port(struct cxgbi_sock *csk, char *buf)
+{
+ int len;
+
+ cxgbi_sock_get(csk);
+ len = sprintf(buf, "%hu\n", ntohs(csk->daddr.sin_port));
+ cxgbi_sock_put(csk);
+
+ return len;
+}
+
+static inline int csk_print_ip(struct cxgbi_sock *csk, char *buf)
+{
+ int len;
+
+ cxgbi_sock_get(csk);
+ if (csk->csk_family == AF_INET)
+ len = sprintf(buf, "%pI4",
+ &csk->daddr.sin_addr.s_addr);
+ else
+ len = sprintf(buf, "%pI6",
+ &csk->daddr6.sin6_addr);
+
+ cxgbi_sock_put(csk);
+
+ return len;
+}
+
int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param,
char *buf)
{
@@ -2447,7 +2638,19 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost,
}
}
- csk = cxgbi_check_route(dst_addr);
+ if (dst_addr->sa_family == AF_INET) {
+ csk = cxgbi_check_route(dst_addr);
+#if IS_ENABLED(CONFIG_IPV6)
+ } else if (dst_addr->sa_family == AF_INET6) {
+ csk = cxgbi_check_route6(dst_addr);
+#endif
+ } else {
+ pr_info("address family 0x%x NOT supported.\n",
+ dst_addr->sa_family);
+ err = -EAFNOSUPPORT;
+ return (struct iscsi_endpoint *)ERR_PTR(err);
+ }
+
if (IS_ERR(csk))
return (struct iscsi_endpoint *)csk;
cxgbi_sock_get(csk);
diff --git a/drivers/scsi/cxgbi/libcxgbi.h b/drivers/scsi/cxgbi/libcxgbi.h
index 8135f04671af..b3e6e7541cc5 100644
--- a/drivers/scsi/cxgbi/libcxgbi.h
+++ b/drivers/scsi/cxgbi/libcxgbi.h
@@ -44,6 +44,15 @@ enum cxgbi_dbg_flag {
pr_info(fmt, ##__VA_ARGS__); \
} while (0)
+#define pr_info_ipaddr(fmt_trail, \
+ addr1, addr2, args_trail...) \
+do { \
+ if (!((1 << CXGBI_DBG_SOCK) & dbg_level)) \
+ break; \
+ pr_info("%pISpc - %pISpc, " fmt_trail, \
+ addr1, addr2, args_trail); \
+} while (0)
+
/* max. connections per adapter */
#define CXGBI_MAX_CONN 16384
@@ -202,8 +211,15 @@ struct cxgbi_sock {
spinlock_t lock;
struct kref refcnt;
unsigned int state;
- struct sockaddr_in saddr;
- struct sockaddr_in daddr;
+ unsigned int csk_family;
+ union {
+ struct sockaddr_in saddr;
+ struct sockaddr_in6 saddr6;
+ };
+ union {
+ struct sockaddr_in daddr;
+ struct sockaddr_in6 daddr6;
+ };
struct dst_entry *dst;
struct sk_buff_head receive_queue;
struct sk_buff_head write_queue;
@@ -692,7 +708,8 @@ struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int);
void cxgbi_device_unregister(struct cxgbi_device *);
void cxgbi_device_unregister_all(unsigned int flag);
struct cxgbi_device *cxgbi_device_find_by_lldev(void *);
-int cxgbi_hbas_add(struct cxgbi_device *, unsigned int, unsigned int,
+struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *);
+int cxgbi_hbas_add(struct cxgbi_device *, u64, unsigned int,
struct scsi_host_template *,
struct scsi_transport_template *);
void cxgbi_hbas_remove(struct cxgbi_device *);
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 83d9bf6fa6ca..0c6be0a17f53 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -519,9 +519,7 @@ static struct ParameterData cfg_data[] = {
CFG_PARAM_UNSET,
0,
0x2f,
-#ifdef CONFIG_SCSI_MULTI_LUN
- NAC_SCANLUN |
-#endif
+ NAC_SCANLUN |
NAC_GT2DRIVES | NAC_GREATER_1G | NAC_POWERON_SCSI_RESET
/*| NAC_ACTIVE_NEG*/,
NAC_GT2DRIVES | NAC_GREATER_1G | NAC_POWERON_SCSI_RESET | 0x08
@@ -1089,7 +1087,7 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s
struct AdapterCtlBlk *acb =
(struct AdapterCtlBlk *)cmd->device->host->hostdata;
dprintkdbg(DBG_0, "queue_command: (0x%p) <%02i-%i> cmnd=0x%02x\n",
- cmd, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+ cmd, cmd->device->id, (u8)cmd->device->lun, cmd->cmnd[0]);
/* Assume BAD_TARGET; will be cleared later */
cmd->result = DID_BAD_TARGET << 16;
@@ -1104,7 +1102,7 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s
/* does the specified lun on the specified device exist */
if (!(acb->dcb_map[cmd->device->id] & (1 << cmd->device->lun))) {
dprintkl(KERN_INFO, "queue_command: Ignore target <%02i-%i>\n",
- cmd->device->id, cmd->device->lun);
+ cmd->device->id, (u8)cmd->device->lun);
goto complete;
}
@@ -1113,7 +1111,7 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s
if (!dcb) {
/* should never happen */
dprintkl(KERN_ERR, "queue_command: No such device <%02i-%i>",
- cmd->device->id, cmd->device->lun);
+ cmd->device->id, (u8)cmd->device->lun);
goto complete;
}
@@ -1209,7 +1207,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb,
"cmnd=0x%02x <%02i-%i>\n",
srb, srb->cmd,
srb->cmd->cmnd[0], srb->cmd->device->id,
- srb->cmd->device->lun);
+ (u8)srb->cmd->device->lun);
printk(" sglist=%p cnt=%i idx=%i len=%zu\n",
srb->segment_x, srb->sg_count, srb->sg_index,
srb->total_xfer_length);
@@ -1304,7 +1302,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
(struct AdapterCtlBlk *)cmd->device->host->hostdata;
dprintkl(KERN_INFO,
"eh_bus_reset: (0%p) target=<%02i-%i> cmd=%p\n",
- cmd, cmd->device->id, cmd->device->lun, cmd);
+ cmd, cmd->device->id, (u8)cmd->device->lun, cmd);
if (timer_pending(&acb->waiting_timer))
del_timer(&acb->waiting_timer);
@@ -1371,7 +1369,7 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd)
struct DeviceCtlBlk *dcb;
struct ScsiReqBlk *srb;
dprintkl(KERN_INFO, "eh_abort: (0x%p) target=<%02i-%i> cmd=%p\n",
- cmd, cmd->device->id, cmd->device->lun, cmd);
+ cmd, cmd->device->id, (u8)cmd->device->lun, cmd);
dcb = find_dcb(acb, cmd->device->id, cmd->device->lun);
if (!dcb) {
@@ -1607,7 +1605,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
dprintkl(KERN_WARNING, "start_scsi: (0x%p) "
"Out of tags target=<%02i-%i>)\n",
srb->cmd, srb->cmd->device->id,
- srb->cmd->device->lun);
+ (u8)srb->cmd->device->lun);
srb->state = SRB_READY;
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL,
DO_HWRESELECT);
@@ -1625,7 +1623,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
/*polling:*/
/* Send CDB ..command block ......... */
dprintkdbg(DBG_KG, "start_scsi: (0x%p) <%02i-%i> cmnd=0x%02x tag=%i\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun,
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun,
srb->cmd->cmnd[0], srb->tag_number);
if (srb->flag & AUTO_REQSENSE) {
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE);
@@ -2043,7 +2041,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 scsi_status = *pscsi_status;
u32 d_left_counter = 0;
dprintkdbg(DBG_0, "data_out_phase0: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
/*
* KG: We need to drain the buffers before we draw any conclusions!
@@ -2173,7 +2171,7 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status)
{
dprintkdbg(DBG_0, "data_out_phase1: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
clear_fifo(acb, "data_out_phase1");
/* do prepare before transfer when data out phase */
data_io_transfer(acb, srb, XFERDATAOUT);
@@ -2185,7 +2183,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 scsi_status = *pscsi_status;
dprintkdbg(DBG_0, "data_in_phase0: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
/*
* KG: DataIn is much more tricky than DataOut. When the device is finished
@@ -2396,7 +2394,7 @@ static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status)
{
dprintkdbg(DBG_0, "data_in_phase1: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
data_io_transfer(acb, srb, XFERDATAIN);
}
@@ -2408,7 +2406,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb,
u8 bval;
dprintkdbg(DBG_0,
"data_io_transfer: (0x%p) <%02i-%i> %c len=%i, sg=(%i/%i)\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun,
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun,
((io_dir & DMACMD_DIR) ? 'r' : 'w'),
srb->total_xfer_length, srb->sg_index, srb->sg_count);
if (srb == acb->tmp_srb)
@@ -2581,7 +2579,7 @@ static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status)
{
dprintkdbg(DBG_0, "status_phase0: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */
srb->state = SRB_COMPLETED;
@@ -2595,7 +2593,7 @@ static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status)
{
dprintkdbg(DBG_0, "status_phase1: (0x%p) <%02i-%i>\n",
- srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd, srb->cmd->device->id, (u8)srb->cmd->device->lun);
srb->state = SRB_STATUS;
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
@@ -3320,7 +3318,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
int ckc_only = 1;
dprintkdbg(DBG_1, "srb_done: (0x%p) <%02i-%i>\n", srb->cmd,
- srb->cmd->device->id, srb->cmd->device->lun);
+ srb->cmd->device->id, (u8)srb->cmd->device->lun);
dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n",
srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count,
scsi_sgtalbe(cmd));
@@ -3500,7 +3498,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (srb->total_xfer_length)
dprintkdbg(DBG_KG, "srb_done: (0x%p) <%02i-%i> "
"cmnd=0x%02x Missed %i bytes\n",
- cmd, cmd->device->id, cmd->device->lun,
+ cmd, cmd->device->id, (u8)cmd->device->lun,
cmd->cmnd[0], srb->total_xfer_length);
}
@@ -3540,7 +3538,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
dir = p->sc_data_direction;
result = MK_RES(0, did_flag, 0, 0);
printk("G:%p(%02i-%i) ", p,
- p->device->id, p->device->lun);
+ p->device->id, (u8)p->device->lun);
srb_going_remove(dcb, srb);
free_tag(dcb, srb);
srb_free_insert(acb, srb);
@@ -3570,7 +3568,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
result = MK_RES(0, did_flag, 0, 0);
printk("W:%p<%02i-%i>", p, p->device->id,
- p->device->lun);
+ (u8)p->device->lun);
srb_waiting_remove(dcb, srb);
srb_free_insert(acb, srb);
p->result = result;
@@ -3679,7 +3677,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
{
struct scsi_cmnd *cmd = srb->cmd;
dprintkdbg(DBG_1, "request_sense: (0x%p) <%02i-%i>\n",
- cmd, cmd->device->id, cmd->device->lun);
+ cmd, cmd->device->id, (u8)cmd->device->lun);
srb->flag |= AUTO_REQSENSE;
srb->adapter_status = 0;
@@ -4434,15 +4432,10 @@ static void adapter_init_scsi_host(struct Scsi_Host *host)
if (host->max_id - 1 == eeprom->scsi_id)
host->max_id--;
-#ifdef CONFIG_SCSI_MULTI_LUN
if (eeprom->channel_cfg & NAC_SCANLUN)
host->max_lun = 8;
else
host->max_lun = 1;
-#else
- host->max_lun = 1;
-#endif
-
}
@@ -4645,7 +4638,7 @@ static int dc395x_show_info(struct seq_file *m, struct Scsi_Host *host)
SPRINTF("irq_level 0x%04x, ", acb->irq_level);
SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000);
- SPRINTF("MaxID %i, MaxLUN %i, ", host->max_id, host->max_lun);
+ SPRINTF("MaxID %i, MaxLUN %llu, ", host->max_id, host->max_lun);
SPRINTF("AdapterID %i\n", host->this_id);
SPRINTF("tag_max_num %i", acb->tag_max_num);
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index c0ae8fa57a3b..67283ef418ac 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -459,7 +459,7 @@ static int adpt_queue_lck(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
* to the device structure. This should be a TEST_UNIT_READY
* command from scan_scsis_single.
*/
- if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun)) == NULL) {
+ if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun)) == NULL) {
// TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response
// with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
cmd->result = (DID_NO_CONNECT << 16);
@@ -579,8 +579,8 @@ static int adpt_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_printf(m," Rev: %-8.8s\n", d->pScsi_dev->rev);
unit = d->pI2o_dev->lct_data.tid;
- seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n",
- unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
+ seq_printf(m, "\tTID=%d, (Channel=%d, Target=%d, Lun=%llu) (%s)\n\n",
+ unit, (int)d->scsi_channel, (int)d->scsi_id, d->scsi_lun,
scsi_device_online(d->pScsi_dev)? "online":"offline");
d = d->next_lun;
}
@@ -1162,7 +1162,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
}
}
-static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u64 lun)
{
struct adpt_device* d;
@@ -1462,7 +1462,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
i2o_lct *lct = pHba->lct;
u8 bus_no = 0;
s16 scsi_id;
- s16 scsi_lun;
+ u64 scsi_lun;
u32 buf[10]; // larger than 7, or 8 ...
struct adpt_device* pDev;
@@ -1496,7 +1496,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
}
bus_no = buf[0]>>16;
scsi_id = buf[1];
- scsi_lun = (buf[2]>>8 )&0xff;
+ scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
continue;
@@ -1571,7 +1571,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
bus_no = buf[0]>>16;
scsi_id = buf[1];
- scsi_lun = (buf[2]>>8 )&0xff;
+ scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
continue;
}
@@ -2407,8 +2407,8 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
case I2O_SCSI_DSC_COMMAND_TIMEOUT:
case I2O_SCSI_DSC_NO_ADAPTER:
case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
- printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
- pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]);
+ printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%llu) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
+ pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]);
cmd->result = (DID_TIME_OUT << 16);
break;
case I2O_SCSI_DSC_ADAPTER_BUSY:
@@ -2447,8 +2447,8 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
case I2O_SCSI_DSC_QUEUE_FROZEN:
case I2O_SCSI_DSC_REQUEST_INVALID:
default:
- printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
- pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
+ printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%llu) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+ pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
hba_status, dev_status, cmd->cmnd[0]);
cmd->result = (DID_ERROR << 16);
break;
@@ -2464,8 +2464,8 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
cmd->sense_buffer[2] == DATA_PROTECT ){
/* This is to handle an array failed */
cmd->result = (DID_TIME_OUT << 16);
- printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
- pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
+ printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%llu) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+ pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
hba_status, dev_status, cmd->cmnd[0]);
}
@@ -2476,8 +2476,8 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
* for a limitted number of retries.
*/
cmd->result = (DID_TIME_OUT << 16);
- printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
- pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
+ printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%llu) tid=%d, cmd=0x%x\n",
+ pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, cmd->device->lun,
((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
}
@@ -2517,7 +2517,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
i2o_lct *lct = pHba->lct;
u8 bus_no = 0;
s16 scsi_id;
- s16 scsi_lun;
+ u64 scsi_lun;
u32 buf[10]; // at least 8 u32's
struct adpt_device* pDev = NULL;
struct i2o_device* pI2o_dev = NULL;
@@ -2564,7 +2564,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
}
scsi_id = buf[1];
- scsi_lun = (buf[2]>>8 )&0xff;
+ scsi_lun = scsilun_to_int((struct scsi_lun *)&buf[2]);
pDev = pHba->channel[bus_no].device[scsi_id];
/* da lun */
while(pDev) {
@@ -2633,7 +2633,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
while(pDev) {
if(pDev->scsi_lun == scsi_lun) {
if(!scsi_device_online(pDev->pScsi_dev)) {
- printk(KERN_WARNING"%s: Setting device (%d,%d,%d) back online\n",
+ printk(KERN_WARNING"%s: Setting device (%d,%d,%llu) back online\n",
pHba->name,bus_no,scsi_id,scsi_lun);
if (pDev->pScsi_dev) {
scsi_device_set_state(pDev->pScsi_dev, SDEV_RUNNING);
@@ -2665,7 +2665,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
// in the LCT table
if (pDev->state & DPTI_DEV_UNSCANNED){
pDev->state = DPTI_DEV_OFFLINE;
- printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
+ printk(KERN_WARNING"%s: Device (%d,%d,%llu) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
if (pDev->pScsi_dev) {
scsi_device_set_state(pDev->pScsi_dev, SDEV_OFFLINE);
}
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index aeb046186c84..1fa345ab8ecb 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -184,7 +184,7 @@ struct adpt_device {
u32 block_size;
u8 scsi_channel;
u8 scsi_id;
- u8 scsi_lun;
+ u64 scsi_lun;
u8 state;
u16 tid;
struct i2o_device* pI2o_dev;
@@ -231,7 +231,7 @@ typedef struct _adpt_hba {
u32 sg_tablesize; // Scatter/Gather List Size.
u8 top_scsi_channel;
u8 top_scsi_id;
- u8 top_scsi_lun;
+ u64 top_scsi_lun;
u8 dma64;
i2o_status_block* status_block;
@@ -300,7 +300,7 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m);
static void adpt_i2o_delete_hba(adpt_hba* pHba);
static void adpt_inquiry(adpt_hba* pHba);
static void adpt_fail_posted_scbs(adpt_hba* pHba);
-static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u64 lun);
static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
static int adpt_i2o_online_hba(adpt_hba* pHba);
static void adpt_i2o_post_wait_complete(u32, int);
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index ebf57364df91..03372cff38f3 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1399,7 +1399,7 @@ static int port_detect(unsigned long port_base, unsigned int j,
if (shost->max_id > 8 || shost->max_lun > 8)
printk
- ("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+ ("%s: wide SCSI support enabled, max_id %u, max_lun %llu.\n",
ha->board_name, shost->max_id, shost->max_lun);
for (i = 0; i <= shost->max_channel; i++)
@@ -2449,7 +2449,7 @@ static irqreturn_t ihdlr(struct Scsi_Host *shost)
"target_status 0x%x, sense key 0x%x.\n",
ha->board_name,
SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun,
+ (u8)SCpnt->device->lun,
spp->target_status, SCpnt->sense_buffer[2]);
ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c
index 7d9b54ae7f62..a0dd1b67a467 100644
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -257,8 +257,8 @@ int fnic_set_intr_mode(struct fnic *fnic)
fnic->raw_wq_count >= m &&
fnic->wq_copy_count >= o &&
fnic->cq_count >= n + m + o) {
- if (!pci_enable_msix(fnic->pdev, fnic->msix_entry,
- n + m + o + 1)) {
+ if (!pci_enable_msix_exact(fnic->pdev, fnic->msix_entry,
+ n + m + o + 1)) {
fnic->rq_count = n;
fnic->raw_wq_count = m;
fnic->wq_copy_count = o;
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index ea28b5ca4c73..961bdf5d31cd 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -1753,7 +1753,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
tag = sc->request->tag;
FNIC_SCSI_DBG(KERN_DEBUG,
fnic->lport->host,
- "Abort Cmd called FCID 0x%x, LUN 0x%x TAG %x flags %x\n",
+ "Abort Cmd called FCID 0x%x, LUN 0x%llx TAG %x flags %x\n",
rport->port_id, sc->device->lun, tag, CMD_FLAGS(sc));
CMD_FLAGS(sc) = FNIC_NO_FLAGS;
@@ -2207,7 +2207,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
rport = starget_to_rport(scsi_target(sc->device));
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
- "Device reset called FCID 0x%x, LUN 0x%x sc 0x%p\n",
+ "Device reset called FCID 0x%x, LUN 0x%llx sc 0x%p\n",
rport->port_id, sc->device->lun, sc);
if (lp->state != LPORT_ST_READY || !(lp->link_up))
@@ -2224,6 +2224,22 @@ int fnic_device_reset(struct scsi_cmnd *sc)
tag = sc->request->tag;
if (unlikely(tag < 0)) {
+ /*
+ * XXX(hch): current the midlayer fakes up a struct
+ * request for the explicit reset ioctls, and those
+ * don't have a tag allocated to them. The below
+ * code pokes into midlayer structures to paper over
+ * this design issue, but that won't work for blk-mq.
+ *
+ * Either someone who can actually test the hardware
+ * will have to come up with a similar hack for the
+ * blk-mq case, or we'll have to bite the bullet and
+ * fix the way the EH ioctls work for real, but until
+ * that happens we fail these explicit requests here.
+ */
+ if (shost_use_blk_mq(sc->device->host))
+ goto fnic_device_reset_end;
+
tag = fnic_scsi_host_start_tag(fnic, sc);
if (unlikely(tag == SCSI_NO_TAG))
goto fnic_device_reset_end;
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index a1bc8ca958e1..b331272e93bc 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -768,7 +768,7 @@ static void sprint_command(struct seq_file *m, unsigned char *command)
static void sprint_Scsi_Cmnd(struct seq_file *m, Scsi_Cmnd * cmd)
{
- PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun);
+ PRINTP("host number %d destination target %d, lun %llu\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun);
PRINTP(" command = ");
sprint_command(m, cmd->cmnd);
}
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 3cbb57a8b846..6de80e352871 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -204,18 +204,33 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
struct scsi_host_template *sht = shost->hostt;
int error = -EINVAL;
- printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
+ shost_printk(KERN_INFO, shost, "%s\n",
sht->info ? sht->info(shost) : sht->name);
if (!shost->can_queue) {
- printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
- sht->name);
+ shost_printk(KERN_ERR, shost,
+ "can_queue = 0 no longer supported\n");
goto fail;
}
+ if (shost_use_blk_mq(shost)) {
+ error = scsi_mq_setup_tags(shost);
+ if (error)
+ goto fail;
+ }
+
+ /*
+ * Note that we allocate the freelist even for the MQ case for now,
+ * as we need a command set aside for scsi_reset_provider. Having
+ * the full host freelist and one command available for that is a
+ * little heavy-handed, but avoids introducing a special allocator
+ * just for this. Eventually the structure of scsi_reset_provider
+ * will need a major overhaul.
+ */
error = scsi_setup_command_freelist(shost);
if (error)
- goto fail;
+ goto out_destroy_tags;
+
if (!shost->shost_gendev.parent)
shost->shost_gendev.parent = dev ? dev : &platform_bus;
@@ -226,7 +241,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
error = device_add(&shost->shost_gendev);
if (error)
- goto out;
+ goto out_destroy_freelist;
pm_runtime_set_active(&shost->shost_gendev);
pm_runtime_enable(&shost->shost_gendev);
@@ -279,8 +294,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
device_del(&shost->shost_dev);
out_del_gendev:
device_del(&shost->shost_gendev);
- out:
+ out_destroy_freelist:
scsi_destroy_command_freelist(shost);
+ out_destroy_tags:
+ if (shost_use_blk_mq(shost))
+ scsi_mq_destroy_tags(shost);
fail:
return error;
}
@@ -309,8 +327,13 @@ static void scsi_host_dev_release(struct device *dev)
}
scsi_destroy_command_freelist(shost);
- if (shost->bqt)
- blk_free_tags(shost->bqt);
+ if (shost_use_blk_mq(shost)) {
+ if (shost->tag_set.tags)
+ scsi_mq_destroy_tags(shost);
+ } else {
+ if (shost->bqt)
+ blk_free_tags(shost->bqt);
+ }
kfree(shost->shost_data);
@@ -436,6 +459,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
else
shost->dma_boundary = 0xffffffff;
+ shost->use_blk_mq = scsi_use_blk_mq && !shost->hostt->disable_blk_mq;
+
device_initialize(&shost->shost_gendev);
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
shost->shost_gendev.bus = &scsi_bus_type;
@@ -450,8 +475,9 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->ehandler = kthread_run(scsi_error_handler, shost,
"scsi_eh_%d", shost->host_no);
if (IS_ERR(shost->ehandler)) {
- printk(KERN_WARNING "scsi%d: error handler thread failed to spawn, error = %ld\n",
- shost->host_no, PTR_ERR(shost->ehandler));
+ shost_printk(KERN_WARNING, shost,
+ "error handler thread failed to spawn, error = %ld\n",
+ PTR_ERR(shost->ehandler));
goto fail_kfree;
}
@@ -584,7 +610,7 @@ EXPORT_SYMBOL(scsi_is_host_device);
int scsi_queue_work(struct Scsi_Host *shost, struct work_struct *work)
{
if (unlikely(!shost->work_q)) {
- printk(KERN_ERR
+ shost_printk(KERN_ERR, shost,
"ERROR: Scsi host '%s' attempted to queue scsi-work, "
"when no workqueue created.\n", shost->hostt->name);
dump_stack();
@@ -603,7 +629,7 @@ EXPORT_SYMBOL_GPL(scsi_queue_work);
void scsi_flush_work(struct Scsi_Host *shost)
{
if (!shost->work_q) {
- printk(KERN_ERR
+ shost_printk(KERN_ERR, shost,
"ERROR: Scsi host '%s' attempted to flush scsi-work, "
"when no workqueue created.\n", shost->hostt->name);
dump_stack();
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 31184b35370f..8545d1826725 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1708,7 +1708,14 @@ static void complete_scsi_command(struct CommandList *cp)
cmd->result |= ei->ScsiStatus;
- /* copy the sense data whether we need to or not. */
+ scsi_set_resid(cmd, ei->ResidualCnt);
+ if (ei->CommandStatus == 0) {
+ cmd_free(h, cp);
+ cmd->scsi_done(cmd);
+ return;
+ }
+
+ /* copy the sense data */
if (SCSI_SENSE_BUFFERSIZE < sizeof(ei->SenseInfo))
sense_data_size = SCSI_SENSE_BUFFERSIZE;
else
@@ -1717,13 +1724,6 @@ static void complete_scsi_command(struct CommandList *cp)
sense_data_size = ei->SenseLen;
memcpy(cmd->sense_buffer, ei->SenseInfo, sense_data_size);
- scsi_set_resid(cmd, ei->ResidualCnt);
-
- if (ei->CommandStatus == 0) {
- cmd_free(h, cp);
- cmd->scsi_done(cmd);
- return;
- }
/* For I/O accelerator commands, copy over some fields to the normal
* CISS header used below for error handling.
@@ -3686,6 +3686,8 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
(((u64) cmd->cmnd[2]) << 8) |
cmd->cmnd[3];
block_cnt = cmd->cmnd[4];
+ if (block_cnt == 0)
+ block_cnt = 256;
break;
case WRITE_10:
is_write = 1;
@@ -3734,7 +3736,6 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
default:
return IO_ACCEL_INELIGIBLE; /* process via normal I/O path */
}
- BUG_ON(block_cnt == 0);
last_block = first_block + block_cnt - 1;
/* check for write to non-RAID-0 */
@@ -4590,7 +4591,7 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
return FAILED;
memset(msg, 0, sizeof(msg));
- ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%d ",
+ ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%llu ",
h->scsi_host->host_no, sc->device->channel,
sc->device->id, sc->device->lun);
@@ -5092,7 +5093,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
}
if (ioc->Request.Type.Direction & XFER_WRITE) {
if (copy_from_user(buff[sg_used], data_ptr, sz)) {
- status = -ENOMEM;
+ status = -EFAULT;
goto cleanup1;
}
} else
@@ -6365,9 +6366,9 @@ static inline void hpsa_set_driver_support_bits(struct ctlr_info *h)
{
u32 driver_support;
-#ifdef CONFIG_X86
- /* Need to enable prefetch in the SCSI core for 6400 in x86 */
driver_support = readl(&(h->cfgtable->driver_support));
+ /* Need to enable prefetch in the SCSI core for 6400 in x86 */
+#ifdef CONFIG_X86
driver_support |= ENABLE_SCSI_PREFETCH;
#endif
driver_support |= ENABLE_UNIT_ATTN;
@@ -6913,8 +6914,12 @@ static int hpsa_offline_devices_ready(struct ctlr_info *h)
d = list_entry(this, struct offline_device_entry,
offline_list);
spin_unlock_irqrestore(&h->offline_device_lock, flags);
- if (!hpsa_volume_offline(h, d->scsi3addr))
+ if (!hpsa_volume_offline(h, d->scsi3addr)) {
+ spin_lock_irqsave(&h->offline_device_lock, flags);
+ list_del(&d->offline_list);
+ spin_unlock_irqrestore(&h->offline_device_lock, flags);
return 1;
+ }
spin_lock_irqsave(&h->offline_device_lock, flags);
}
spin_unlock_irqrestore(&h->offline_device_lock, flags);
@@ -6995,8 +7000,10 @@ reinit_after_soft_reset:
/* Allocate and clear per-cpu variable lockup_detected */
h->lockup_detected = alloc_percpu(u32);
- if (!h->lockup_detected)
+ if (!h->lockup_detected) {
+ rc = -ENOMEM;
goto clean1;
+ }
set_lockup_detected_for_all_cpus(h, 0);
rc = hpsa_pci_init(h);
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index ee196b363d81..dedb62c21b29 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1024,7 +1024,7 @@ static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
_req->scp = scp;
- dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%08x-%08x-%08x-%08x) "
+ dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%llu cdb=(%08x-%08x-%08x-%08x) "
"req_index=%d, req=%p\n",
scp,
host->host_no, scp->device->channel,
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index cb150d1e5850..3840c64f2966 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -1,3 +1,2 @@
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi.o
-obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
obj-$(CONFIG_SCSI_IBMVFC) += ibmvfc.o
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 8dd47689d584..598c42cba5a8 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -46,7 +46,7 @@
static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT;
static unsigned int default_timeout = IBMVFC_DEFAULT_TIMEOUT;
-static unsigned int max_lun = IBMVFC_MAX_LUN;
+static u64 max_lun = IBMVFC_MAX_LUN;
static unsigned int max_targets = IBMVFC_MAX_TARGETS;
static unsigned int max_requests = IBMVFC_MAX_REQUESTS_DEFAULT;
static unsigned int disc_threads = IBMVFC_MAX_DISC_THREADS;
@@ -71,7 +71,7 @@ MODULE_PARM_DESC(default_timeout,
module_param_named(max_requests, max_requests, uint, S_IRUGO);
MODULE_PARM_DESC(max_requests, "Maximum requests for this adapter. "
"[Default=" __stringify(IBMVFC_MAX_REQUESTS_DEFAULT) "]");
-module_param_named(max_lun, max_lun, uint, S_IRUGO);
+module_param_named(max_lun, max_lun, ullong, S_IRUGO);
MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. "
"[Default=" __stringify(IBMVFC_MAX_LUN) "]");
module_param_named(max_targets, max_targets, uint, S_IRUGO);
@@ -166,13 +166,13 @@ static void ibmvfc_trc_start(struct ibmvfc_event *evt)
switch (entry->fmt) {
case IBMVFC_CMD_FORMAT:
entry->op_code = vfc_cmd->iu.cdb[0];
- entry->scsi_id = vfc_cmd->tgt_scsi_id;
+ entry->scsi_id = be64_to_cpu(vfc_cmd->tgt_scsi_id);
entry->lun = scsilun_to_int(&vfc_cmd->iu.lun);
entry->tmf_flags = vfc_cmd->iu.tmf_flags;
- entry->u.start.xfer_len = vfc_cmd->iu.xfer_len;
+ entry->u.start.xfer_len = be32_to_cpu(vfc_cmd->iu.xfer_len);
break;
case IBMVFC_MAD_FORMAT:
- entry->op_code = mad->opcode;
+ entry->op_code = be32_to_cpu(mad->opcode);
break;
default:
break;
@@ -199,18 +199,18 @@ static void ibmvfc_trc_end(struct ibmvfc_event *evt)
switch (entry->fmt) {
case IBMVFC_CMD_FORMAT:
entry->op_code = vfc_cmd->iu.cdb[0];
- entry->scsi_id = vfc_cmd->tgt_scsi_id;
+ entry->scsi_id = be64_to_cpu(vfc_cmd->tgt_scsi_id);
entry->lun = scsilun_to_int(&vfc_cmd->iu.lun);
entry->tmf_flags = vfc_cmd->iu.tmf_flags;
- entry->u.end.status = vfc_cmd->status;
- entry->u.end.error = vfc_cmd->error;
+ entry->u.end.status = be16_to_cpu(vfc_cmd->status);
+ entry->u.end.error = be16_to_cpu(vfc_cmd->error);
entry->u.end.fcp_rsp_flags = vfc_cmd->rsp.flags;
entry->u.end.rsp_code = vfc_cmd->rsp.data.info.rsp_code;
entry->u.end.scsi_status = vfc_cmd->rsp.scsi_status;
break;
case IBMVFC_MAD_FORMAT:
- entry->op_code = mad->opcode;
- entry->u.end.status = mad->status;
+ entry->op_code = be32_to_cpu(mad->opcode);
+ entry->u.end.status = be16_to_cpu(mad->status);
break;
default:
break;
@@ -270,14 +270,14 @@ static int ibmvfc_get_err_result(struct ibmvfc_cmd *vfc_cmd)
{
int err;
struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
- int fc_rsp_len = rsp->fcp_rsp_len;
+ int fc_rsp_len = be32_to_cpu(rsp->fcp_rsp_len);
if ((rsp->flags & FCP_RSP_LEN_VALID) &&
((fc_rsp_len && fc_rsp_len != 4 && fc_rsp_len != 8) ||
rsp->data.info.rsp_code))
return DID_ERROR << 16;
- err = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error);
+ err = ibmvfc_get_err_index(be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error));
if (err >= 0)
return rsp->scsi_status | (cmd_status[err].result << 16);
return rsp->scsi_status | (DID_ERROR << 16);
@@ -807,7 +807,7 @@ static void ibmvfc_fail_request(struct ibmvfc_event *evt, int error_code)
evt->cmnd->result = (error_code << 16);
evt->done = ibmvfc_scsi_eh_done;
} else
- evt->xfer_iu->mad_common.status = IBMVFC_MAD_DRIVER_FAILED;
+ evt->xfer_iu->mad_common.status = cpu_to_be16(IBMVFC_MAD_DRIVER_FAILED);
list_del(&evt->queue);
del_timer(&evt->timer);
@@ -955,7 +955,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost)
spin_lock_irqsave(shost->host_lock, flags);
if (vhost->state == IBMVFC_ACTIVE) {
- switch (vhost->login_buf->resp.link_speed / 100) {
+ switch (be64_to_cpu(vhost->login_buf->resp.link_speed) / 100) {
case 1:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
break;
@@ -976,7 +976,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost)
break;
default:
ibmvfc_log(vhost, 3, "Unknown port speed: %lld Gbit\n",
- vhost->login_buf->resp.link_speed / 100);
+ be64_to_cpu(vhost->login_buf->resp.link_speed) / 100);
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
}
@@ -1171,21 +1171,21 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost)
memset(login_info, 0, sizeof(*login_info));
- login_info->ostype = IBMVFC_OS_LINUX;
- login_info->max_dma_len = IBMVFC_MAX_SECTORS << 9;
- login_info->max_payload = sizeof(struct ibmvfc_fcp_cmd_iu);
- login_info->max_response = sizeof(struct ibmvfc_fcp_rsp);
- login_info->partition_num = vhost->partition_number;
- login_info->vfc_frame_version = 1;
- login_info->fcp_version = 3;
- login_info->flags = IBMVFC_FLUSH_ON_HALT;
+ login_info->ostype = cpu_to_be32(IBMVFC_OS_LINUX);
+ login_info->max_dma_len = cpu_to_be64(IBMVFC_MAX_SECTORS << 9);
+ login_info->max_payload = cpu_to_be32(sizeof(struct ibmvfc_fcp_cmd_iu));
+ login_info->max_response = cpu_to_be32(sizeof(struct ibmvfc_fcp_rsp));
+ login_info->partition_num = cpu_to_be32(vhost->partition_number);
+ login_info->vfc_frame_version = cpu_to_be32(1);
+ login_info->fcp_version = cpu_to_be16(3);
+ login_info->flags = cpu_to_be16(IBMVFC_FLUSH_ON_HALT);
if (vhost->client_migrated)
- login_info->flags |= IBMVFC_CLIENT_MIGRATED;
+ login_info->flags |= cpu_to_be16(IBMVFC_CLIENT_MIGRATED);
- login_info->max_cmds = max_requests + IBMVFC_NUM_INTERNAL_REQ;
- login_info->capabilities = IBMVFC_CAN_MIGRATE;
- login_info->async.va = vhost->async_crq.msg_token;
- login_info->async.len = vhost->async_crq.size * sizeof(*vhost->async_crq.msgs);
+ login_info->max_cmds = cpu_to_be32(max_requests + IBMVFC_NUM_INTERNAL_REQ);
+ login_info->capabilities = cpu_to_be64(IBMVFC_CAN_MIGRATE);
+ login_info->async.va = cpu_to_be64(vhost->async_crq.msg_token);
+ login_info->async.len = cpu_to_be32(vhost->async_crq.size * sizeof(*vhost->async_crq.msgs));
strncpy(login_info->partition_name, vhost->partition_name, IBMVFC_MAX_NAME);
strncpy(login_info->device_name,
dev_name(&vhost->host->shost_gendev), IBMVFC_MAX_NAME);
@@ -1225,7 +1225,7 @@ static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost)
struct ibmvfc_event *evt = &pool->events[i];
atomic_set(&evt->free, 1);
evt->crq.valid = 0x80;
- evt->crq.ioba = pool->iu_token + (sizeof(*evt->xfer_iu) * i);
+ evt->crq.ioba = cpu_to_be64(pool->iu_token + (sizeof(*evt->xfer_iu) * i));
evt->xfer_iu = pool->iu_storage + i;
evt->vhost = vhost;
evt->ext_list = NULL;
@@ -1310,8 +1310,8 @@ static void ibmvfc_map_sg_list(struct scsi_cmnd *scmd, int nseg,
struct scatterlist *sg;
scsi_for_each_sg(scmd, sg, nseg, i) {
- md[i].va = sg_dma_address(sg);
- md[i].len = sg_dma_len(sg);
+ md[i].va = cpu_to_be64(sg_dma_address(sg));
+ md[i].len = cpu_to_be32(sg_dma_len(sg));
md[i].key = 0;
}
}
@@ -1337,7 +1337,7 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
sg_mapped = scsi_dma_map(scmd);
if (!sg_mapped) {
- vfc_cmd->flags |= IBMVFC_NO_MEM_DESC;
+ vfc_cmd->flags |= cpu_to_be16(IBMVFC_NO_MEM_DESC);
return 0;
} else if (unlikely(sg_mapped < 0)) {
if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
@@ -1346,10 +1346,10 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
}
if (scmd->sc_data_direction == DMA_TO_DEVICE) {
- vfc_cmd->flags |= IBMVFC_WRITE;
+ vfc_cmd->flags |= cpu_to_be16(IBMVFC_WRITE);
vfc_cmd->iu.add_cdb_len |= IBMVFC_WRDATA;
} else {
- vfc_cmd->flags |= IBMVFC_READ;
+ vfc_cmd->flags |= cpu_to_be16(IBMVFC_READ);
vfc_cmd->iu.add_cdb_len |= IBMVFC_RDDATA;
}
@@ -1358,7 +1358,7 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
return 0;
}
- vfc_cmd->flags |= IBMVFC_SCATTERLIST;
+ vfc_cmd->flags |= cpu_to_be16(IBMVFC_SCATTERLIST);
if (!evt->ext_list) {
evt->ext_list = dma_pool_alloc(vhost->sg_pool, GFP_ATOMIC,
@@ -1374,8 +1374,8 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd,
ibmvfc_map_sg_list(scmd, sg_mapped, evt->ext_list);
- data->va = evt->ext_list_token;
- data->len = sg_mapped * sizeof(struct srp_direct_buf);
+ data->va = cpu_to_be64(evt->ext_list_token);
+ data->len = cpu_to_be32(sg_mapped * sizeof(struct srp_direct_buf));
data->key = 0;
return 0;
}
@@ -1404,15 +1404,15 @@ static void ibmvfc_timeout(struct ibmvfc_event *evt)
static int ibmvfc_send_event(struct ibmvfc_event *evt,
struct ibmvfc_host *vhost, unsigned long timeout)
{
- u64 *crq_as_u64 = (u64 *) &evt->crq;
+ __be64 *crq_as_u64 = (__be64 *) &evt->crq;
int rc;
/* Copy the IU into the transfer area */
*evt->xfer_iu = evt->iu;
if (evt->crq.format == IBMVFC_CMD_FORMAT)
- evt->xfer_iu->cmd.tag = (u64)evt;
+ evt->xfer_iu->cmd.tag = cpu_to_be64((u64)evt);
else if (evt->crq.format == IBMVFC_MAD_FORMAT)
- evt->xfer_iu->mad_common.tag = (u64)evt;
+ evt->xfer_iu->mad_common.tag = cpu_to_be64((u64)evt);
else
BUG();
@@ -1428,7 +1428,8 @@ static int ibmvfc_send_event(struct ibmvfc_event *evt,
mb();
- if ((rc = ibmvfc_send_crq(vhost, crq_as_u64[0], crq_as_u64[1]))) {
+ if ((rc = ibmvfc_send_crq(vhost, be64_to_cpu(crq_as_u64[0]),
+ be64_to_cpu(crq_as_u64[1])))) {
list_del(&evt->queue);
del_timer(&evt->timer);
@@ -1451,7 +1452,7 @@ static int ibmvfc_send_event(struct ibmvfc_event *evt,
evt->cmnd->result = DID_ERROR << 16;
evt->done = ibmvfc_scsi_eh_done;
} else
- evt->xfer_iu->mad_common.status = IBMVFC_MAD_CRQ_ERROR;
+ evt->xfer_iu->mad_common.status = cpu_to_be16(IBMVFC_MAD_CRQ_ERROR);
evt->done(evt);
} else
@@ -1472,7 +1473,7 @@ static void ibmvfc_log_error(struct ibmvfc_event *evt)
struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
struct scsi_cmnd *cmnd = evt->cmnd;
const char *err = unknown_error;
- int index = ibmvfc_get_err_index(vfc_cmd->status, vfc_cmd->error);
+ int index = ibmvfc_get_err_index(be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error));
int logerr = 0;
int rsp_code = 0;
@@ -1526,13 +1527,13 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
struct scsi_cmnd *cmnd = evt->cmnd;
u32 rsp_len = 0;
- u32 sense_len = rsp->fcp_sense_len;
+ u32 sense_len = be32_to_cpu(rsp->fcp_sense_len);
if (cmnd) {
- if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID)
- scsi_set_resid(cmnd, vfc_cmd->adapter_resid);
+ if (be16_to_cpu(vfc_cmd->response_flags) & IBMVFC_ADAPTER_RESID_VALID)
+ scsi_set_resid(cmnd, be32_to_cpu(vfc_cmd->adapter_resid));
else if (rsp->flags & FCP_RESID_UNDER)
- scsi_set_resid(cmnd, rsp->fcp_resid);
+ scsi_set_resid(cmnd, be32_to_cpu(rsp->fcp_resid));
else
scsi_set_resid(cmnd, 0);
@@ -1540,12 +1541,13 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
cmnd->result = ibmvfc_get_err_result(vfc_cmd);
if (rsp->flags & FCP_RSP_LEN_VALID)
- rsp_len = rsp->fcp_rsp_len;
+ rsp_len = be32_to_cpu(rsp->fcp_rsp_len);
if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE)
sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len;
if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len && rsp_len <= 8)
memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len);
- if ((vfc_cmd->status & IBMVFC_VIOS_FAILURE) && (vfc_cmd->error == IBMVFC_PLOGI_REQUIRED))
+ if ((be16_to_cpu(vfc_cmd->status) & IBMVFC_VIOS_FAILURE) &&
+ (be16_to_cpu(vfc_cmd->error) == IBMVFC_PLOGI_REQUIRED))
ibmvfc_relogin(cmnd->device);
if (!cmnd->result && (!scsi_get_resid(cmnd) || (rsp->flags & FCP_RESID_OVER)))
@@ -1630,19 +1632,19 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
cmnd->scsi_done = done;
vfc_cmd = &evt->iu.cmd;
memset(vfc_cmd, 0, sizeof(*vfc_cmd));
- vfc_cmd->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
- vfc_cmd->resp.len = sizeof(vfc_cmd->rsp);
- vfc_cmd->frame_type = IBMVFC_SCSI_FCP_TYPE;
- vfc_cmd->payload_len = sizeof(vfc_cmd->iu);
- vfc_cmd->resp_len = sizeof(vfc_cmd->rsp);
- vfc_cmd->cancel_key = (unsigned long)cmnd->device->hostdata;
- vfc_cmd->tgt_scsi_id = rport->port_id;
- vfc_cmd->iu.xfer_len = scsi_bufflen(cmnd);
+ vfc_cmd->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offsetof(struct ibmvfc_cmd, rsp));
+ vfc_cmd->resp.len = cpu_to_be32(sizeof(vfc_cmd->rsp));
+ vfc_cmd->frame_type = cpu_to_be32(IBMVFC_SCSI_FCP_TYPE);
+ vfc_cmd->payload_len = cpu_to_be32(sizeof(vfc_cmd->iu));
+ vfc_cmd->resp_len = cpu_to_be32(sizeof(vfc_cmd->rsp));
+ vfc_cmd->cancel_key = cpu_to_be32((unsigned long)cmnd->device->hostdata);
+ vfc_cmd->tgt_scsi_id = cpu_to_be64(rport->port_id);
+ vfc_cmd->iu.xfer_len = cpu_to_be32(scsi_bufflen(cmnd));
int_to_scsilun(cmnd->device->lun, &vfc_cmd->iu.lun);
memcpy(vfc_cmd->iu.cdb, cmnd->cmnd, cmnd->cmd_len);
if (scsi_populate_tag_msg(cmnd, tag)) {
- vfc_cmd->task_tag = tag[1];
+ vfc_cmd->task_tag = cpu_to_be64(tag[1]);
switch (tag[0]) {
case MSG_SIMPLE_TAG:
vfc_cmd->iu.pri_task_attr = IBMVFC_SIMPLE_TASK;
@@ -1732,12 +1734,12 @@ static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
tmf = &evt->iu.tmf;
memset(tmf, 0, sizeof(*tmf));
- tmf->common.version = 1;
- tmf->common.opcode = IBMVFC_TMF_MAD;
- tmf->common.length = sizeof(*tmf);
- tmf->scsi_id = port_id;
- tmf->cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
- tmf->my_cancel_key = IBMVFC_INTERNAL_CANCEL_KEY;
+ tmf->common.version = cpu_to_be32(1);
+ tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
+ tmf->common.length = cpu_to_be16(sizeof(*tmf));
+ tmf->scsi_id = cpu_to_be64(port_id);
+ tmf->cancel_key = cpu_to_be32(IBMVFC_PASSTHRU_CANCEL_KEY);
+ tmf->my_cancel_key = cpu_to_be32(IBMVFC_INTERNAL_CANCEL_KEY);
rc = ibmvfc_send_event(evt, vhost, default_timeout);
if (rc != 0) {
@@ -1789,10 +1791,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id)
ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
plogi = &evt->iu.plogi;
memset(plogi, 0, sizeof(*plogi));
- plogi->common.version = 1;
- plogi->common.opcode = IBMVFC_PORT_LOGIN;
- plogi->common.length = sizeof(*plogi);
- plogi->scsi_id = port_id;
+ plogi->common.version = cpu_to_be32(1);
+ plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN);
+ plogi->common.length = cpu_to_be16(sizeof(*plogi));
+ plogi->scsi_id = cpu_to_be64(port_id);
evt->sync_iu = &rsp_iu;
init_completion(&evt->comp);
@@ -1904,26 +1906,26 @@ static int ibmvfc_bsg_request(struct fc_bsg_job *job)
mad = &evt->iu.passthru;
memset(mad, 0, sizeof(*mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_PASSTHRU;
- mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu);
-
- mad->cmd_ioba.va = (u64)evt->crq.ioba +
- offsetof(struct ibmvfc_passthru_mad, iu);
- mad->cmd_ioba.len = sizeof(mad->iu);
-
- mad->iu.cmd_len = job->request_payload.payload_len;
- mad->iu.rsp_len = job->reply_payload.payload_len;
- mad->iu.flags = fc_flags;
- mad->iu.cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
-
- mad->iu.cmd.va = sg_dma_address(job->request_payload.sg_list);
- mad->iu.cmd.len = sg_dma_len(job->request_payload.sg_list);
- mad->iu.rsp.va = sg_dma_address(job->reply_payload.sg_list);
- mad->iu.rsp.len = sg_dma_len(job->reply_payload.sg_list);
- mad->iu.scsi_id = port_id;
- mad->iu.tag = (u64)evt;
- rsp_len = mad->iu.rsp.len;
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_PASSTHRU);
+ mad->common.length = cpu_to_be16(sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu));
+
+ mad->cmd_ioba.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) +
+ offsetof(struct ibmvfc_passthru_mad, iu));
+ mad->cmd_ioba.len = cpu_to_be32(sizeof(mad->iu));
+
+ mad->iu.cmd_len = cpu_to_be32(job->request_payload.payload_len);
+ mad->iu.rsp_len = cpu_to_be32(job->reply_payload.payload_len);
+ mad->iu.flags = cpu_to_be32(fc_flags);
+ mad->iu.cancel_key = cpu_to_be32(IBMVFC_PASSTHRU_CANCEL_KEY);
+
+ mad->iu.cmd.va = cpu_to_be64(sg_dma_address(job->request_payload.sg_list));
+ mad->iu.cmd.len = cpu_to_be32(sg_dma_len(job->request_payload.sg_list));
+ mad->iu.rsp.va = cpu_to_be64(sg_dma_address(job->reply_payload.sg_list));
+ mad->iu.rsp.len = cpu_to_be32(sg_dma_len(job->reply_payload.sg_list));
+ mad->iu.scsi_id = cpu_to_be64(port_id);
+ mad->iu.tag = cpu_to_be64((u64)evt);
+ rsp_len = be32_to_cpu(mad->iu.rsp.len);
evt->sync_iu = &rsp_iu;
init_completion(&evt->comp);
@@ -1986,15 +1988,15 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
tmf = &evt->iu.cmd;
memset(tmf, 0, sizeof(*tmf));
- tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
- tmf->resp.len = sizeof(tmf->rsp);
- tmf->frame_type = IBMVFC_SCSI_FCP_TYPE;
- tmf->payload_len = sizeof(tmf->iu);
- tmf->resp_len = sizeof(tmf->rsp);
- tmf->cancel_key = (unsigned long)sdev->hostdata;
- tmf->tgt_scsi_id = rport->port_id;
+ tmf->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offsetof(struct ibmvfc_cmd, rsp));
+ tmf->resp.len = cpu_to_be32(sizeof(tmf->rsp));
+ tmf->frame_type = cpu_to_be32(IBMVFC_SCSI_FCP_TYPE);
+ tmf->payload_len = cpu_to_be32(sizeof(tmf->iu));
+ tmf->resp_len = cpu_to_be32(sizeof(tmf->rsp));
+ tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
+ tmf->tgt_scsi_id = cpu_to_be64(rport->port_id);
int_to_scsilun(sdev->lun, &tmf->iu.lun);
- tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF);
+ tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
tmf->iu.tmf_flags = type;
evt->sync_iu = &rsp_iu;
@@ -2020,8 +2022,8 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
rsp_code = fc_rsp->data.info.rsp_code;
sdev_printk(KERN_ERR, sdev, "%s reset failed: %s (%x:%x) "
- "flags: %x fcp_rsp: %x, scsi_status: %x\n",
- desc, ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error),
+ "flags: %x fcp_rsp: %x, scsi_status: %x\n", desc,
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
fc_rsp->scsi_status);
rsp_rc = -EIO;
@@ -2185,19 +2187,19 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
tmf = &evt->iu.tmf;
memset(tmf, 0, sizeof(*tmf));
- tmf->common.version = 1;
- tmf->common.opcode = IBMVFC_TMF_MAD;
- tmf->common.length = sizeof(*tmf);
- tmf->scsi_id = rport->port_id;
+ tmf->common.version = cpu_to_be32(1);
+ tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
+ tmf->common.length = cpu_to_be16(sizeof(*tmf));
+ tmf->scsi_id = cpu_to_be64(rport->port_id);
int_to_scsilun(sdev->lun, &tmf->lun);
- if (!(vhost->login_buf->resp.capabilities & IBMVFC_CAN_SUPPRESS_ABTS))
+ if (!(be64_to_cpu(vhost->login_buf->resp.capabilities) & IBMVFC_CAN_SUPPRESS_ABTS))
type &= ~IBMVFC_TMF_SUPPRESS_ABTS;
if (vhost->state == IBMVFC_ACTIVE)
- tmf->flags = (type | IBMVFC_TMF_LUA_VALID);
+ tmf->flags = cpu_to_be32((type | IBMVFC_TMF_LUA_VALID));
else
- tmf->flags = ((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID);
- tmf->cancel_key = (unsigned long)sdev->hostdata;
- tmf->my_cancel_key = (unsigned long)starget->hostdata;
+ tmf->flags = cpu_to_be32(((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID));
+ tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
+ tmf->my_cancel_key = cpu_to_be32((unsigned long)starget->hostdata);
evt->sync_iu = &rsp;
init_completion(&evt->comp);
@@ -2217,7 +2219,7 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
sdev_printk(KERN_INFO, sdev, "Cancelling outstanding commands.\n");
wait_for_completion(&evt->comp);
- status = rsp.mad_common.status;
+ status = be16_to_cpu(rsp.mad_common.status);
spin_lock_irqsave(vhost->host->host_lock, flags);
ibmvfc_free_event(evt);
spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -2252,7 +2254,7 @@ static int ibmvfc_match_key(struct ibmvfc_event *evt, void *key)
unsigned long cancel_key = (unsigned long)key;
if (evt->crq.format == IBMVFC_CMD_FORMAT &&
- evt->iu.cmd.cancel_key == cancel_key)
+ be32_to_cpu(evt->iu.cmd.cancel_key) == cancel_key)
return 1;
return 0;
}
@@ -2316,15 +2318,15 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
tmf = &evt->iu.cmd;
memset(tmf, 0, sizeof(*tmf));
- tmf->resp.va = (u64)evt->crq.ioba + offsetof(struct ibmvfc_cmd, rsp);
- tmf->resp.len = sizeof(tmf->rsp);
- tmf->frame_type = IBMVFC_SCSI_FCP_TYPE;
- tmf->payload_len = sizeof(tmf->iu);
- tmf->resp_len = sizeof(tmf->rsp);
- tmf->cancel_key = (unsigned long)sdev->hostdata;
- tmf->tgt_scsi_id = rport->port_id;
+ tmf->resp.va = cpu_to_be64(be64_to_cpu(evt->crq.ioba) + offsetof(struct ibmvfc_cmd, rsp));
+ tmf->resp.len = cpu_to_be32(sizeof(tmf->rsp));
+ tmf->frame_type = cpu_to_be32(IBMVFC_SCSI_FCP_TYPE);
+ tmf->payload_len = cpu_to_be32(sizeof(tmf->iu));
+ tmf->resp_len = cpu_to_be32(sizeof(tmf->rsp));
+ tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
+ tmf->tgt_scsi_id = cpu_to_be64(rport->port_id);
int_to_scsilun(sdev->lun, &tmf->iu.lun);
- tmf->flags = (IBMVFC_NO_MEM_DESC | IBMVFC_TMF);
+ tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
tmf->iu.tmf_flags = IBMVFC_ABORT_TASK_SET;
evt->sync_iu = &rsp_iu;
@@ -2380,7 +2382,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
sdev_printk(KERN_ERR, sdev, "Abort failed: %s (%x:%x) "
"flags: %x fcp_rsp: %x, scsi_status: %x\n",
- ibmvfc_get_cmd_error(rsp_iu.cmd.status, rsp_iu.cmd.error),
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
fc_rsp->scsi_status);
rsp_rc = -EIO;
@@ -2641,14 +2643,14 @@ static const char *ibmvfc_get_link_state(enum ibmvfc_ae_link_state state)
static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
struct ibmvfc_host *vhost)
{
- const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(crq->event);
+ const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event));
struct ibmvfc_target *tgt;
ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx,"
" node_name: %llx%s\n", desc->desc, crq->scsi_id, crq->wwpn, crq->node_name,
ibmvfc_get_link_state(crq->link_state));
- switch (crq->event) {
+ switch (be64_to_cpu(crq->event)) {
case IBMVFC_AE_RESUME:
switch (crq->link_state) {
case IBMVFC_AE_LS_LINK_DOWN:
@@ -2691,15 +2693,15 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
list_for_each_entry(tgt, &vhost->targets, queue) {
if (!crq->scsi_id && !crq->wwpn && !crq->node_name)
break;
- if (crq->scsi_id && tgt->scsi_id != crq->scsi_id)
+ if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id)
continue;
- if (crq->wwpn && tgt->ids.port_name != crq->wwpn)
+ if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn)
continue;
- if (crq->node_name && tgt->ids.node_name != crq->node_name)
+ if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name)
continue;
- if (tgt->need_login && crq->event == IBMVFC_AE_ELS_LOGO)
+ if (tgt->need_login && be64_to_cpu(crq->event) == IBMVFC_AE_ELS_LOGO)
tgt->logo_rcvd = 1;
- if (!tgt->need_login || crq->event == IBMVFC_AE_ELS_PLOGI) {
+ if (!tgt->need_login || be64_to_cpu(crq->event) == IBMVFC_AE_ELS_PLOGI) {
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
ibmvfc_reinit_host(vhost);
}
@@ -2730,7 +2732,7 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
{
long rc;
- struct ibmvfc_event *evt = (struct ibmvfc_event *)crq->ioba;
+ struct ibmvfc_event *evt = (struct ibmvfc_event *)be64_to_cpu(crq->ioba);
switch (crq->valid) {
case IBMVFC_CRQ_INIT_RSP:
@@ -3336,7 +3338,7 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_process_login *rsp = &evt->xfer_iu->prli;
struct ibmvfc_prli_svc_parms *parms = &rsp->parms;
- u32 status = rsp->common.status;
+ u32 status = be16_to_cpu(rsp->common.status);
int index, level = IBMVFC_DEFAULT_LOG_LEVEL;
vhost->discovery_threads--;
@@ -3347,14 +3349,14 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
parms->type, parms->flags, parms->service_parms);
if (parms->type == IBMVFC_SCSI_FCP_TYPE) {
- index = ibmvfc_get_prli_rsp(parms->flags);
+ index = ibmvfc_get_prli_rsp(be16_to_cpu(parms->flags));
if (prli_rsp[index].logged_in) {
- if (parms->flags & IBMVFC_PRLI_EST_IMG_PAIR) {
+ if (be16_to_cpu(parms->flags) & IBMVFC_PRLI_EST_IMG_PAIR) {
tgt->need_login = 0;
tgt->ids.roles = 0;
- if (parms->service_parms & IBMVFC_PRLI_TARGET_FUNC)
+ if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_TARGET_FUNC)
tgt->ids.roles |= FC_PORT_ROLE_FCP_TARGET;
- if (parms->service_parms & IBMVFC_PRLI_INITIATOR_FUNC)
+ if (be32_to_cpu(parms->service_parms) & IBMVFC_PRLI_INITIATOR_FUNC)
tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
tgt->add_rport = 1;
} else
@@ -3373,17 +3375,18 @@ static void ibmvfc_tgt_prli_done(struct ibmvfc_event *evt)
break;
case IBMVFC_MAD_FAILED:
default:
- if ((rsp->status & IBMVFC_VIOS_FAILURE) && rsp->error == IBMVFC_PLOGI_REQUIRED)
+ if ((be16_to_cpu(rsp->status) & IBMVFC_VIOS_FAILURE) &&
+ be16_to_cpu(rsp->error) == IBMVFC_PLOGI_REQUIRED)
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
else if (tgt->logo_rcvd)
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
- else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+ else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
else
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
tgt_log(tgt, level, "Process Login failed: %s (%x:%x) rc=0x%02X\n",
- ibmvfc_get_cmd_error(rsp->status, rsp->error),
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
rsp->status, rsp->error, status);
break;
};
@@ -3414,14 +3417,14 @@ static void ibmvfc_tgt_send_prli(struct ibmvfc_target *tgt)
evt->tgt = tgt;
prli = &evt->iu.prli;
memset(prli, 0, sizeof(*prli));
- prli->common.version = 1;
- prli->common.opcode = IBMVFC_PROCESS_LOGIN;
- prli->common.length = sizeof(*prli);
- prli->scsi_id = tgt->scsi_id;
+ prli->common.version = cpu_to_be32(1);
+ prli->common.opcode = cpu_to_be32(IBMVFC_PROCESS_LOGIN);
+ prli->common.length = cpu_to_be16(sizeof(*prli));
+ prli->scsi_id = cpu_to_be64(tgt->scsi_id);
prli->parms.type = IBMVFC_SCSI_FCP_TYPE;
- prli->parms.flags = IBMVFC_PRLI_EST_IMG_PAIR;
- prli->parms.service_parms = IBMVFC_PRLI_INITIATOR_FUNC;
+ prli->parms.flags = cpu_to_be16(IBMVFC_PRLI_EST_IMG_PAIR);
+ prli->parms.service_parms = cpu_to_be32(IBMVFC_PRLI_INITIATOR_FUNC);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
@@ -3442,7 +3445,7 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
struct ibmvfc_target *tgt = evt->tgt;
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_port_login *rsp = &evt->xfer_iu->plogi;
- u32 status = rsp->common.status;
+ u32 status = be16_to_cpu(rsp->common.status);
int level = IBMVFC_DEFAULT_LOG_LEVEL;
vhost->discovery_threads--;
@@ -3472,15 +3475,15 @@ static void ibmvfc_tgt_plogi_done(struct ibmvfc_event *evt)
break;
case IBMVFC_MAD_FAILED:
default:
- if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+ if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
else
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
tgt_log(tgt, level, "Port Login failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
- ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error,
- ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type,
- ibmvfc_get_ls_explain(rsp->fc_explain), rsp->fc_explain, status);
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), rsp->status, rsp->error,
+ ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), rsp->fc_type,
+ ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), rsp->fc_explain, status);
break;
};
@@ -3512,10 +3515,10 @@ static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *tgt)
evt->tgt = tgt;
plogi = &evt->iu.plogi;
memset(plogi, 0, sizeof(*plogi));
- plogi->common.version = 1;
- plogi->common.opcode = IBMVFC_PORT_LOGIN;
- plogi->common.length = sizeof(*plogi);
- plogi->scsi_id = tgt->scsi_id;
+ plogi->common.version = cpu_to_be32(1);
+ plogi->common.opcode = cpu_to_be32(IBMVFC_PORT_LOGIN);
+ plogi->common.length = cpu_to_be16(sizeof(*plogi));
+ plogi->scsi_id = cpu_to_be64(tgt->scsi_id);
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
vhost->discovery_threads--;
@@ -3535,7 +3538,7 @@ static void ibmvfc_tgt_implicit_logout_done(struct ibmvfc_event *evt)
struct ibmvfc_target *tgt = evt->tgt;
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_implicit_logout *rsp = &evt->xfer_iu->implicit_logout;
- u32 status = rsp->common.status;
+ u32 status = be16_to_cpu(rsp->common.status);
vhost->discovery_threads--;
ibmvfc_free_event(evt);
@@ -3585,10 +3588,10 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
evt->tgt = tgt;
mad = &evt->iu.implicit_logout;
memset(mad, 0, sizeof(*mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_IMPLICIT_LOGOUT;
- mad->common.length = sizeof(*mad);
- mad->old_scsi_id = tgt->scsi_id;
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_IMPLICIT_LOGOUT);
+ mad->common.length = cpu_to_be16(sizeof(*mad));
+ mad->old_scsi_id = cpu_to_be64(tgt->scsi_id);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
@@ -3616,7 +3619,7 @@ static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad,
if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name,
sizeof(tgt->ids.node_name)))
return 1;
- if (mad->fc_iu.response[6] != tgt->scsi_id)
+ if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id)
return 1;
return 0;
}
@@ -3631,7 +3634,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
struct ibmvfc_target *tgt = evt->tgt;
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru;
- u32 status = mad->common.status;
+ u32 status = be16_to_cpu(mad->common.status);
u8 fc_reason, fc_explain;
vhost->discovery_threads--;
@@ -3649,10 +3652,10 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
case IBMVFC_MAD_FAILED:
default:
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
- fc_reason = (mad->fc_iu.response[1] & 0x00ff0000) >> 16;
- fc_explain = (mad->fc_iu.response[1] & 0x0000ff00) >> 8;
+ fc_reason = (be32_to_cpu(mad->fc_iu.response[1]) & 0x00ff0000) >> 16;
+ fc_explain = (be32_to_cpu(mad->fc_iu.response[1]) & 0x0000ff00) >> 8;
tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
- ibmvfc_get_cmd_error(mad->iu.status, mad->iu.error),
+ ibmvfc_get_cmd_error(be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error)),
mad->iu.status, mad->iu.error,
ibmvfc_get_fc_type(fc_reason), fc_reason,
ibmvfc_get_ls_explain(fc_explain), fc_explain, status);
@@ -3674,22 +3677,22 @@ static void ibmvfc_init_passthru(struct ibmvfc_event *evt)
struct ibmvfc_passthru_mad *mad = &evt->iu.passthru;
memset(mad, 0, sizeof(*mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_PASSTHRU;
- mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu);
- mad->cmd_ioba.va = (u64)evt->crq.ioba +
- offsetof(struct ibmvfc_passthru_mad, iu);
- mad->cmd_ioba.len = sizeof(mad->iu);
- mad->iu.cmd_len = sizeof(mad->fc_iu.payload);
- mad->iu.rsp_len = sizeof(mad->fc_iu.response);
- mad->iu.cmd.va = (u64)evt->crq.ioba +
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_PASSTHRU);
+ mad->common.length = cpu_to_be16(sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu));
+ mad->cmd_ioba.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) +
+ offsetof(struct ibmvfc_passthru_mad, iu));
+ mad->cmd_ioba.len = cpu_to_be32(sizeof(mad->iu));
+ mad->iu.cmd_len = cpu_to_be32(sizeof(mad->fc_iu.payload));
+ mad->iu.rsp_len = cpu_to_be32(sizeof(mad->fc_iu.response));
+ mad->iu.cmd.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) +
offsetof(struct ibmvfc_passthru_mad, fc_iu) +
- offsetof(struct ibmvfc_passthru_fc_iu, payload);
- mad->iu.cmd.len = sizeof(mad->fc_iu.payload);
- mad->iu.rsp.va = (u64)evt->crq.ioba +
+ offsetof(struct ibmvfc_passthru_fc_iu, payload));
+ mad->iu.cmd.len = cpu_to_be32(sizeof(mad->fc_iu.payload));
+ mad->iu.rsp.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) +
offsetof(struct ibmvfc_passthru_mad, fc_iu) +
- offsetof(struct ibmvfc_passthru_fc_iu, response);
- mad->iu.rsp.len = sizeof(mad->fc_iu.response);
+ offsetof(struct ibmvfc_passthru_fc_iu, response));
+ mad->iu.rsp.len = cpu_to_be32(sizeof(mad->fc_iu.response));
}
/**
@@ -3748,11 +3751,11 @@ static void ibmvfc_adisc_timeout(struct ibmvfc_target *tgt)
evt->tgt = tgt;
tmf = &evt->iu.tmf;
memset(tmf, 0, sizeof(*tmf));
- tmf->common.version = 1;
- tmf->common.opcode = IBMVFC_TMF_MAD;
- tmf->common.length = sizeof(*tmf);
- tmf->scsi_id = tgt->scsi_id;
- tmf->cancel_key = tgt->cancel_key;
+ tmf->common.version = cpu_to_be32(1);
+ tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
+ tmf->common.length = cpu_to_be16(sizeof(*tmf));
+ tmf->scsi_id = cpu_to_be64(tgt->scsi_id);
+ tmf->cancel_key = cpu_to_be32(tgt->cancel_key);
rc = ibmvfc_send_event(evt, vhost, default_timeout);
@@ -3794,16 +3797,16 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
ibmvfc_init_passthru(evt);
mad = &evt->iu.passthru;
- mad->iu.flags = IBMVFC_FC_ELS;
- mad->iu.scsi_id = tgt->scsi_id;
- mad->iu.cancel_key = tgt->cancel_key;
+ mad->iu.flags = cpu_to_be32(IBMVFC_FC_ELS);
+ mad->iu.scsi_id = cpu_to_be64(tgt->scsi_id);
+ mad->iu.cancel_key = cpu_to_be32(tgt->cancel_key);
- mad->fc_iu.payload[0] = IBMVFC_ADISC;
+ mad->fc_iu.payload[0] = cpu_to_be32(IBMVFC_ADISC);
memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name,
sizeof(vhost->login_buf->resp.port_name));
memcpy(&mad->fc_iu.payload[4], &vhost->login_buf->resp.node_name,
sizeof(vhost->login_buf->resp.node_name));
- mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff;
+ mad->fc_iu.payload[6] = cpu_to_be32(be64_to_cpu(vhost->login_buf->resp.scsi_id) & 0x00ffffff);
if (timer_pending(&tgt->timer))
mod_timer(&tgt->timer, jiffies + (IBMVFC_ADISC_TIMEOUT * HZ));
@@ -3834,7 +3837,7 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
struct ibmvfc_target *tgt = evt->tgt;
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_query_tgt *rsp = &evt->xfer_iu->query_tgt;
- u32 status = rsp->common.status;
+ u32 status = be16_to_cpu(rsp->common.status);
int level = IBMVFC_DEFAULT_LOG_LEVEL;
vhost->discovery_threads--;
@@ -3842,8 +3845,8 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
switch (status) {
case IBMVFC_MAD_SUCCESS:
tgt_dbg(tgt, "Query Target succeeded\n");
- tgt->new_scsi_id = rsp->scsi_id;
- if (rsp->scsi_id != tgt->scsi_id)
+ tgt->new_scsi_id = be64_to_cpu(rsp->scsi_id);
+ if (be64_to_cpu(rsp->scsi_id) != tgt->scsi_id)
ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
else
ibmvfc_init_tgt(tgt, ibmvfc_tgt_adisc);
@@ -3855,19 +3858,20 @@ static void ibmvfc_tgt_query_target_done(struct ibmvfc_event *evt)
break;
case IBMVFC_MAD_FAILED:
default:
- if ((rsp->status & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED &&
- rsp->error == IBMVFC_UNABLE_TO_PERFORM_REQ &&
- rsp->fc_explain == IBMVFC_PORT_NAME_NOT_REG)
+ if ((be16_to_cpu(rsp->status) & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED &&
+ be16_to_cpu(rsp->error) == IBMVFC_UNABLE_TO_PERFORM_REQ &&
+ be16_to_cpu(rsp->fc_explain) == IBMVFC_PORT_NAME_NOT_REG)
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
- else if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+ else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target);
else
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
tgt_log(tgt, level, "Query Target failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
- ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error,
- ibmvfc_get_fc_type(rsp->fc_type), rsp->fc_type,
- ibmvfc_get_gs_explain(rsp->fc_explain), rsp->fc_explain, status);
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
+ rsp->status, rsp->error, ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)),
+ rsp->fc_type, ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)),
+ rsp->fc_explain, status);
break;
};
@@ -3897,10 +3901,10 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt)
ibmvfc_init_event(evt, ibmvfc_tgt_query_target_done, IBMVFC_MAD_FORMAT);
query_tgt = &evt->iu.query_tgt;
memset(query_tgt, 0, sizeof(*query_tgt));
- query_tgt->common.version = 1;
- query_tgt->common.opcode = IBMVFC_QUERY_TARGET;
- query_tgt->common.length = sizeof(*query_tgt);
- query_tgt->wwpn = tgt->ids.port_name;
+ query_tgt->common.version = cpu_to_be32(1);
+ query_tgt->common.opcode = cpu_to_be32(IBMVFC_QUERY_TARGET);
+ query_tgt->common.length = cpu_to_be16(sizeof(*query_tgt));
+ query_tgt->wwpn = cpu_to_be64(tgt->ids.port_name);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
if (ibmvfc_send_event(evt, vhost, default_timeout)) {
@@ -3971,7 +3975,8 @@ static int ibmvfc_alloc_targets(struct ibmvfc_host *vhost)
for (i = 0, rc = 0; !rc && i < vhost->num_targets; i++)
rc = ibmvfc_alloc_target(vhost,
- vhost->disc_buf->scsi_id[i] & IBMVFC_DISC_TGT_SCSI_ID_MASK);
+ be32_to_cpu(vhost->disc_buf->scsi_id[i]) &
+ IBMVFC_DISC_TGT_SCSI_ID_MASK);
return rc;
}
@@ -3985,19 +3990,20 @@ static void ibmvfc_discover_targets_done(struct ibmvfc_event *evt)
{
struct ibmvfc_host *vhost = evt->vhost;
struct ibmvfc_discover_targets *rsp = &evt->xfer_iu->discover_targets;
- u32 mad_status = rsp->common.status;
+ u32 mad_status = be16_to_cpu(rsp->common.status);
int level = IBMVFC_DEFAULT_LOG_LEVEL;
switch (mad_status) {
case IBMVFC_MAD_SUCCESS:
ibmvfc_dbg(vhost, "Discover Targets succeeded\n");
- vhost->num_targets = rsp->num_written;
+ vhost->num_targets = be32_to_cpu(rsp->num_written);
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_ALLOC_TGTS);
break;
case IBMVFC_MAD_FAILED:
level += ibmvfc_retry_host_init(vhost);
ibmvfc_log(vhost, level, "Discover Targets failed: %s (%x:%x)\n",
- ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error);
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
+ rsp->status, rsp->error);
break;
case IBMVFC_MAD_DRIVER_FAILED:
break;
@@ -4024,12 +4030,12 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost)
ibmvfc_init_event(evt, ibmvfc_discover_targets_done, IBMVFC_MAD_FORMAT);
mad = &evt->iu.discover_targets;
memset(mad, 0, sizeof(*mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_DISC_TARGETS;
- mad->common.length = sizeof(*mad);
- mad->bufflen = vhost->disc_buf_sz;
- mad->buffer.va = vhost->disc_buf_dma;
- mad->buffer.len = vhost->disc_buf_sz;
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_DISC_TARGETS);
+ mad->common.length = cpu_to_be16(sizeof(*mad));
+ mad->bufflen = cpu_to_be32(vhost->disc_buf_sz);
+ mad->buffer.va = cpu_to_be64(vhost->disc_buf_dma);
+ mad->buffer.len = cpu_to_be32(vhost->disc_buf_sz);
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
if (!ibmvfc_send_event(evt, vhost, default_timeout))
@@ -4046,7 +4052,7 @@ static void ibmvfc_discover_targets(struct ibmvfc_host *vhost)
static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
{
struct ibmvfc_host *vhost = evt->vhost;
- u32 mad_status = evt->xfer_iu->npiv_login.common.status;
+ u32 mad_status = be16_to_cpu(evt->xfer_iu->npiv_login.common.status);
struct ibmvfc_npiv_login_resp *rsp = &vhost->login_buf->resp;
unsigned int npiv_max_sectors;
int level = IBMVFC_DEFAULT_LOG_LEVEL;
@@ -4056,12 +4062,13 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
ibmvfc_free_event(evt);
break;
case IBMVFC_MAD_FAILED:
- if (ibmvfc_retry_cmd(rsp->status, rsp->error))
+ if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
level += ibmvfc_retry_host_init(vhost);
else
ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
ibmvfc_log(vhost, level, "NPIV Login failed: %s (%x:%x)\n",
- ibmvfc_get_cmd_error(rsp->status, rsp->error), rsp->status, rsp->error);
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
+ rsp->status, rsp->error);
ibmvfc_free_event(evt);
return;
case IBMVFC_MAD_CRQ_ERROR:
@@ -4078,7 +4085,7 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
vhost->client_migrated = 0;
- if (!(rsp->flags & IBMVFC_NATIVE_FC)) {
+ if (!(be32_to_cpu(rsp->flags) & IBMVFC_NATIVE_FC)) {
dev_err(vhost->dev, "Virtual adapter does not support FC. %x\n",
rsp->flags);
ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
@@ -4086,7 +4093,7 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
return;
}
- if (rsp->max_cmds <= IBMVFC_NUM_INTERNAL_REQ) {
+ if (be32_to_cpu(rsp->max_cmds) <= IBMVFC_NUM_INTERNAL_REQ) {
dev_err(vhost->dev, "Virtual adapter supported queue depth too small: %d\n",
rsp->max_cmds);
ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
@@ -4095,27 +4102,27 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
}
vhost->logged_in = 1;
- npiv_max_sectors = min((uint)(rsp->max_dma_len >> 9), IBMVFC_MAX_SECTORS);
+ npiv_max_sectors = min((uint)(be64_to_cpu(rsp->max_dma_len) >> 9), IBMVFC_MAX_SECTORS);
dev_info(vhost->dev, "Host partition: %s, device: %s %s %s max sectors %u\n",
rsp->partition_name, rsp->device_name, rsp->port_loc_code,
rsp->drc_name, npiv_max_sectors);
- fc_host_fabric_name(vhost->host) = rsp->node_name;
- fc_host_node_name(vhost->host) = rsp->node_name;
- fc_host_port_name(vhost->host) = rsp->port_name;
- fc_host_port_id(vhost->host) = rsp->scsi_id;
+ fc_host_fabric_name(vhost->host) = be64_to_cpu(rsp->node_name);
+ fc_host_node_name(vhost->host) = be64_to_cpu(rsp->node_name);
+ fc_host_port_name(vhost->host) = be64_to_cpu(rsp->port_name);
+ fc_host_port_id(vhost->host) = be64_to_cpu(rsp->scsi_id);
fc_host_port_type(vhost->host) = FC_PORTTYPE_NPIV;
fc_host_supported_classes(vhost->host) = 0;
- if (rsp->service_parms.class1_parms[0] & 0x80000000)
+ if (be32_to_cpu(rsp->service_parms.class1_parms[0]) & 0x80000000)
fc_host_supported_classes(vhost->host) |= FC_COS_CLASS1;
- if (rsp->service_parms.class2_parms[0] & 0x80000000)
+ if (be32_to_cpu(rsp->service_parms.class2_parms[0]) & 0x80000000)
fc_host_supported_classes(vhost->host) |= FC_COS_CLASS2;
- if (rsp->service_parms.class3_parms[0] & 0x80000000)
+ if (be32_to_cpu(rsp->service_parms.class3_parms[0]) & 0x80000000)
fc_host_supported_classes(vhost->host) |= FC_COS_CLASS3;
fc_host_maxframe_size(vhost->host) =
- rsp->service_parms.common.bb_rcv_sz & 0x0fff;
+ be16_to_cpu(rsp->service_parms.common.bb_rcv_sz) & 0x0fff;
- vhost->host->can_queue = rsp->max_cmds - IBMVFC_NUM_INTERNAL_REQ;
+ vhost->host->can_queue = be32_to_cpu(rsp->max_cmds) - IBMVFC_NUM_INTERNAL_REQ;
vhost->host->max_sectors = npiv_max_sectors;
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
wake_up(&vhost->work_wait_q);
@@ -4138,11 +4145,11 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost)
memcpy(vhost->login_buf, &vhost->login_info, sizeof(vhost->login_info));
mad = &evt->iu.npiv_login;
memset(mad, 0, sizeof(struct ibmvfc_npiv_login_mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_NPIV_LOGIN;
- mad->common.length = sizeof(struct ibmvfc_npiv_login_mad);
- mad->buffer.va = vhost->login_buf_dma;
- mad->buffer.len = sizeof(*vhost->login_buf);
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_NPIV_LOGIN);
+ mad->common.length = cpu_to_be16(sizeof(struct ibmvfc_npiv_login_mad));
+ mad->buffer.va = cpu_to_be64(vhost->login_buf_dma);
+ mad->buffer.len = cpu_to_be32(sizeof(*vhost->login_buf));
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
@@ -4160,7 +4167,7 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost)
static void ibmvfc_npiv_logout_done(struct ibmvfc_event *evt)
{
struct ibmvfc_host *vhost = evt->vhost;
- u32 mad_status = evt->xfer_iu->npiv_logout.common.status;
+ u32 mad_status = be16_to_cpu(evt->xfer_iu->npiv_logout.common.status);
ibmvfc_free_event(evt);
@@ -4199,9 +4206,9 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *vhost)
mad = &evt->iu.npiv_logout;
memset(mad, 0, sizeof(*mad));
- mad->common.version = 1;
- mad->common.opcode = IBMVFC_NPIV_LOGOUT;
- mad->common.length = sizeof(struct ibmvfc_npiv_logout_mad);
+ mad->common.version = cpu_to_be32(1);
+ mad->common.opcode = cpu_to_be32(IBMVFC_NPIV_LOGOUT);
+ mad->common.length = cpu_to_be16(sizeof(struct ibmvfc_npiv_logout_mad));
ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_LOGO_WAIT);
@@ -4343,14 +4350,14 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
if (rport) {
tgt_dbg(tgt, "rport add succeeded\n");
tgt->rport = rport;
- rport->maxframe_size = tgt->service_parms.common.bb_rcv_sz & 0x0fff;
+ rport->maxframe_size = be16_to_cpu(tgt->service_parms.common.bb_rcv_sz) & 0x0fff;
rport->supported_classes = 0;
tgt->target_id = rport->scsi_target_id;
- if (tgt->service_parms.class1_parms[0] & 0x80000000)
+ if (be32_to_cpu(tgt->service_parms.class1_parms[0]) & 0x80000000)
rport->supported_classes |= FC_COS_CLASS1;
- if (tgt->service_parms.class2_parms[0] & 0x80000000)
+ if (be32_to_cpu(tgt->service_parms.class2_parms[0]) & 0x80000000)
rport->supported_classes |= FC_COS_CLASS2;
- if (tgt->service_parms.class3_parms[0] & 0x80000000)
+ if (be32_to_cpu(tgt->service_parms.class3_parms[0]) & 0x80000000)
rport->supported_classes |= FC_COS_CLASS3;
if (rport->rqst_q)
blk_queue_max_segments(rport->rqst_q, 1);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 017a5290e8c1..8fae03215a85 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -135,12 +135,12 @@ enum ibmvfc_mad_types {
};
struct ibmvfc_mad_common {
- u32 version;
- u32 reserved;
- u32 opcode;
- u16 status;
- u16 length;
- u64 tag;
+ __be32 version;
+ __be32 reserved;
+ __be32 opcode;
+ __be16 status;
+ __be16 length;
+ __be64 tag;
}__attribute__((packed, aligned (8)));
struct ibmvfc_npiv_login_mad {
@@ -155,76 +155,76 @@ struct ibmvfc_npiv_logout_mad {
#define IBMVFC_MAX_NAME 256
struct ibmvfc_npiv_login {
- u32 ostype;
+ __be32 ostype;
#define IBMVFC_OS_LINUX 0x02
- u32 pad;
- u64 max_dma_len;
- u32 max_payload;
- u32 max_response;
- u32 partition_num;
- u32 vfc_frame_version;
- u16 fcp_version;
- u16 flags;
+ __be32 pad;
+ __be64 max_dma_len;
+ __be32 max_payload;
+ __be32 max_response;
+ __be32 partition_num;
+ __be32 vfc_frame_version;
+ __be16 fcp_version;
+ __be16 flags;
#define IBMVFC_CLIENT_MIGRATED 0x01
#define IBMVFC_FLUSH_ON_HALT 0x02
- u32 max_cmds;
- u64 capabilities;
+ __be32 max_cmds;
+ __be64 capabilities;
#define IBMVFC_CAN_MIGRATE 0x01
- u64 node_name;
+ __be64 node_name;
struct srp_direct_buf async;
u8 partition_name[IBMVFC_MAX_NAME];
u8 device_name[IBMVFC_MAX_NAME];
u8 drc_name[IBMVFC_MAX_NAME];
- u64 reserved2[2];
+ __be64 reserved2[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_common_svc_parms {
- u16 fcph_version;
- u16 b2b_credit;
- u16 features;
- u16 bb_rcv_sz; /* upper nibble is BB_SC_N */
- u32 ratov;
- u32 edtov;
+ __be16 fcph_version;
+ __be16 b2b_credit;
+ __be16 features;
+ __be16 bb_rcv_sz; /* upper nibble is BB_SC_N */
+ __be32 ratov;
+ __be32 edtov;
}__attribute__((packed, aligned (4)));
struct ibmvfc_service_parms {
struct ibmvfc_common_svc_parms common;
u8 port_name[8];
u8 node_name[8];
- u32 class1_parms[4];
- u32 class2_parms[4];
- u32 class3_parms[4];
- u32 obsolete[4];
- u32 vendor_version[4];
- u32 services_avail[2];
- u32 ext_len;
- u32 reserved[30];
- u32 clk_sync_qos[2];
+ __be32 class1_parms[4];
+ __be32 class2_parms[4];
+ __be32 class3_parms[4];
+ __be32 obsolete[4];
+ __be32 vendor_version[4];
+ __be32 services_avail[2];
+ __be32 ext_len;
+ __be32 reserved[30];
+ __be32 clk_sync_qos[2];
}__attribute__((packed, aligned (4)));
struct ibmvfc_npiv_login_resp {
- u32 version;
- u16 status;
- u16 error;
- u32 flags;
+ __be32 version;
+ __be16 status;
+ __be16 error;
+ __be32 flags;
#define IBMVFC_NATIVE_FC 0x01
- u32 reserved;
- u64 capabilities;
+ __be32 reserved;
+ __be64 capabilities;
#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
#define IBMVFC_CAN_SUPPRESS_ABTS 0x10
- u32 max_cmds;
- u32 scsi_id_sz;
- u64 max_dma_len;
- u64 scsi_id;
- u64 port_name;
- u64 node_name;
- u64 link_speed;
+ __be32 max_cmds;
+ __be32 scsi_id_sz;
+ __be64 max_dma_len;
+ __be64 scsi_id;
+ __be64 port_name;
+ __be64 node_name;
+ __be64 link_speed;
u8 partition_name[IBMVFC_MAX_NAME];
u8 device_name[IBMVFC_MAX_NAME];
u8 port_loc_code[IBMVFC_MAX_NAME];
u8 drc_name[IBMVFC_MAX_NAME];
struct ibmvfc_service_parms service_parms;
- u64 reserved2;
+ __be64 reserved2;
}__attribute__((packed, aligned (8)));
union ibmvfc_npiv_login_data {
@@ -233,20 +233,20 @@ union ibmvfc_npiv_login_data {
}__attribute__((packed, aligned (8)));
struct ibmvfc_discover_targets_buf {
- u32 scsi_id[1];
+ __be32 scsi_id[1];
#define IBMVFC_DISC_TGT_SCSI_ID_MASK 0x00ffffff
};
struct ibmvfc_discover_targets {
struct ibmvfc_mad_common common;
struct srp_direct_buf buffer;
- u32 flags;
- u16 status;
- u16 error;
- u32 bufflen;
- u32 num_avail;
- u32 num_written;
- u64 reserved[2];
+ __be32 flags;
+ __be16 status;
+ __be16 error;
+ __be32 bufflen;
+ __be32 num_avail;
+ __be32 num_written;
+ __be64 reserved[2];
}__attribute__((packed, aligned (8)));
enum ibmvfc_fc_reason {
@@ -278,32 +278,32 @@ enum ibmvfc_gs_explain {
struct ibmvfc_port_login {
struct ibmvfc_mad_common common;
- u64 scsi_id;
- u16 reserved;
- u16 fc_service_class;
- u32 blksz;
- u32 hdr_per_blk;
- u16 status;
- u16 error; /* also fc_reason */
- u16 fc_explain;
- u16 fc_type;
- u32 reserved2;
+ __be64 scsi_id;
+ __be16 reserved;
+ __be16 fc_service_class;
+ __be32 blksz;
+ __be32 hdr_per_blk;
+ __be16 status;
+ __be16 error; /* also fc_reason */
+ __be16 fc_explain;
+ __be16 fc_type;
+ __be32 reserved2;
struct ibmvfc_service_parms service_parms;
struct ibmvfc_service_parms service_parms_change;
- u64 reserved3[2];
+ __be64 reserved3[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_prli_svc_parms {
u8 type;
#define IBMVFC_SCSI_FCP_TYPE 0x08
u8 type_ext;
- u16 flags;
+ __be16 flags;
#define IBMVFC_PRLI_ORIG_PA_VALID 0x8000
#define IBMVFC_PRLI_RESP_PA_VALID 0x4000
#define IBMVFC_PRLI_EST_IMG_PAIR 0x2000
- u32 orig_pa;
- u32 resp_pa;
- u32 service_parms;
+ __be32 orig_pa;
+ __be32 resp_pa;
+ __be32 service_parms;
#define IBMVFC_PRLI_TASK_RETRY 0x00000200
#define IBMVFC_PRLI_RETRY 0x00000100
#define IBMVFC_PRLI_DATA_OVERLAY 0x00000040
@@ -315,47 +315,47 @@ struct ibmvfc_prli_svc_parms {
struct ibmvfc_process_login {
struct ibmvfc_mad_common common;
- u64 scsi_id;
+ __be64 scsi_id;
struct ibmvfc_prli_svc_parms parms;
u8 reserved[48];
- u16 status;
- u16 error; /* also fc_reason */
- u32 reserved2;
- u64 reserved3[2];
+ __be16 status;
+ __be16 error; /* also fc_reason */
+ __be32 reserved2;
+ __be64 reserved3[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_query_tgt {
struct ibmvfc_mad_common common;
- u64 wwpn;
- u64 scsi_id;
- u16 status;
- u16 error;
- u16 fc_explain;
- u16 fc_type;
- u64 reserved[2];
+ __be64 wwpn;
+ __be64 scsi_id;
+ __be16 status;
+ __be16 error;
+ __be16 fc_explain;
+ __be16 fc_type;
+ __be64 reserved[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_implicit_logout {
struct ibmvfc_mad_common common;
- u64 old_scsi_id;
- u64 reserved[2];
+ __be64 old_scsi_id;
+ __be64 reserved[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_tmf {
struct ibmvfc_mad_common common;
- u64 scsi_id;
+ __be64 scsi_id;
struct scsi_lun lun;
- u32 flags;
+ __be32 flags;
#define IBMVFC_TMF_ABORT_TASK 0x02
#define IBMVFC_TMF_ABORT_TASK_SET 0x04
#define IBMVFC_TMF_LUN_RESET 0x10
#define IBMVFC_TMF_TGT_RESET 0x20
#define IBMVFC_TMF_LUA_VALID 0x40
#define IBMVFC_TMF_SUPPRESS_ABTS 0x80
- u32 cancel_key;
- u32 my_cancel_key;
- u32 pad;
- u64 reserved[2];
+ __be32 cancel_key;
+ __be32 my_cancel_key;
+ __be32 pad;
+ __be64 reserved[2];
}__attribute__((packed, aligned (8)));
enum ibmvfc_fcp_rsp_info_codes {
@@ -366,7 +366,7 @@ enum ibmvfc_fcp_rsp_info_codes {
};
struct ibmvfc_fcp_rsp_info {
- u16 reserved;
+ __be16 reserved;
u8 rsp_code;
u8 reserved2[4];
}__attribute__((packed, aligned (2)));
@@ -388,13 +388,13 @@ union ibmvfc_fcp_rsp_data {
}__attribute__((packed, aligned (8)));
struct ibmvfc_fcp_rsp {
- u64 reserved;
- u16 retry_delay_timer;
+ __be64 reserved;
+ __be16 retry_delay_timer;
u8 flags;
u8 scsi_status;
- u32 fcp_resid;
- u32 fcp_sense_len;
- u32 fcp_rsp_len;
+ __be32 fcp_resid;
+ __be32 fcp_sense_len;
+ __be32 fcp_rsp_len;
union ibmvfc_fcp_rsp_data data;
}__attribute__((packed, aligned (8)));
@@ -429,58 +429,58 @@ struct ibmvfc_fcp_cmd_iu {
#define IBMVFC_RDDATA 0x02
#define IBMVFC_WRDATA 0x01
u8 cdb[IBMVFC_MAX_CDB_LEN];
- u32 xfer_len;
+ __be32 xfer_len;
}__attribute__((packed, aligned (4)));
struct ibmvfc_cmd {
- u64 task_tag;
- u32 frame_type;
- u32 payload_len;
- u32 resp_len;
- u32 adapter_resid;
- u16 status;
- u16 error;
- u16 flags;
- u16 response_flags;
+ __be64 task_tag;
+ __be32 frame_type;
+ __be32 payload_len;
+ __be32 resp_len;
+ __be32 adapter_resid;
+ __be16 status;
+ __be16 error;
+ __be16 flags;
+ __be16 response_flags;
#define IBMVFC_ADAPTER_RESID_VALID 0x01
- u32 cancel_key;
- u32 exchange_id;
+ __be32 cancel_key;
+ __be32 exchange_id;
struct srp_direct_buf ext_func;
struct srp_direct_buf ioba;
struct srp_direct_buf resp;
- u64 correlation;
- u64 tgt_scsi_id;
- u64 tag;
- u64 reserved3[2];
+ __be64 correlation;
+ __be64 tgt_scsi_id;
+ __be64 tag;
+ __be64 reserved3[2];
struct ibmvfc_fcp_cmd_iu iu;
struct ibmvfc_fcp_rsp rsp;
}__attribute__((packed, aligned (8)));
struct ibmvfc_passthru_fc_iu {
- u32 payload[7];
+ __be32 payload[7];
#define IBMVFC_ADISC 0x52000000
- u32 response[7];
+ __be32 response[7];
};
struct ibmvfc_passthru_iu {
- u64 task_tag;
- u32 cmd_len;
- u32 rsp_len;
- u16 status;
- u16 error;
- u32 flags;
+ __be64 task_tag;
+ __be32 cmd_len;
+ __be32 rsp_len;
+ __be16 status;
+ __be16 error;
+ __be32 flags;
#define IBMVFC_FC_ELS 0x01
#define IBMVFC_FC_CT_IU 0x02
- u32 cancel_key;
+ __be32 cancel_key;
#define IBMVFC_PASSTHRU_CANCEL_KEY 0x80000000
#define IBMVFC_INTERNAL_CANCEL_KEY 0x80000001
- u32 reserved;
+ __be32 reserved;
struct srp_direct_buf cmd;
struct srp_direct_buf rsp;
- u64 correlation;
- u64 scsi_id;
- u64 tag;
- u64 reserved2[2];
+ __be64 correlation;
+ __be64 scsi_id;
+ __be64 tag;
+ __be64 reserved2[2];
}__attribute__((packed, aligned (8)));
struct ibmvfc_passthru_mad {
@@ -552,7 +552,7 @@ struct ibmvfc_crq {
volatile u8 valid;
volatile u8 format;
u8 reserved[6];
- volatile u64 ioba;
+ volatile __be64 ioba;
}__attribute__((packed, aligned (8)));
struct ibmvfc_crq_queue {
@@ -572,12 +572,12 @@ struct ibmvfc_async_crq {
volatile u8 valid;
u8 link_state;
u8 pad[2];
- u32 pad2;
- volatile u64 event;
- volatile u64 scsi_id;
- volatile u64 wwpn;
- volatile u64 node_name;
- u64 reserved;
+ __be32 pad2;
+ volatile __be64 event;
+ volatile __be64 scsi_id;
+ volatile __be64 wwpn;
+ volatile __be64 node_name;
+ __be64 reserved;
}__attribute__((packed, aligned (8)));
struct ibmvfc_async_crq_queue {
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 2ebfb2bb0f42..7b23f21f22f1 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -185,6 +185,11 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
if (crq->valid & 0x80) {
if (++queue->cur == queue->size)
queue->cur = 0;
+
+ /* Ensure the read of the valid bit occurs before reading any
+ * other bits of the CRQ entry
+ */
+ rmb();
} else
crq = NULL;
spin_unlock_irqrestore(&queue->lock, flags);
@@ -203,6 +208,11 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
{
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
+ /*
+ * Ensure the command buffer is flushed to memory before handing it
+ * over to the VIOS to prevent it from fetching any stale data.
+ */
+ mb();
return plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2);
}
@@ -797,7 +807,8 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code)
evt->hostdata->dev);
if (evt->cmnd_done)
evt->cmnd_done(evt->cmnd);
- } else if (evt->done)
+ } else if (evt->done && evt->crq.format != VIOSRP_MAD_FORMAT &&
+ evt->iu.srp.login_req.opcode != SRP_LOGIN_REQ)
evt->done(evt);
free_event_struct(&evt->hostdata->pool, evt);
spin_lock_irqsave(hostdata->host->host_lock, flags);
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
deleted file mode 100644
index 56f8a861ed72..000000000000
--- a/drivers/scsi/ibmvscsi/ibmvstgt.c
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- * IBM eServer i/pSeries Virtual SCSI Target Driver
- * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.
- * Santiago Leon (santil@us.ibm.com) IBM Corp.
- * Linda Xie (lxie@us.ibm.com) IBM Corp.
- *
- * Copyright (C) 2005-2006 FUJITA Tomonori <tomof@acm.org>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_transport_srp.h>
-#include <scsi/scsi_tgt.h>
-#include <scsi/libsrp.h>
-#include <asm/hvcall.h>
-#include <asm/iommu.h>
-#include <asm/prom.h>
-#include <asm/vio.h>
-
-#include "ibmvscsi.h"
-
-#define INITIAL_SRP_LIMIT 16
-#define DEFAULT_MAX_SECTORS 256
-
-#define TGT_NAME "ibmvstgt"
-
-/*
- * Hypervisor calls.
- */
-#define h_copy_rdma(l, sa, sb, da, db) \
- plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
-#define h_send_crq(ua, l, h) \
- plpar_hcall_norets(H_SEND_CRQ, ua, l, h)
-#define h_reg_crq(ua, tok, sz)\
- plpar_hcall_norets(H_REG_CRQ, ua, tok, sz);
-#define h_free_crq(ua) \
- plpar_hcall_norets(H_FREE_CRQ, ua);
-
-/* tmp - will replace with SCSI logging stuff */
-#define eprintk(fmt, args...) \
-do { \
- printk("%s(%d) " fmt, __func__, __LINE__, ##args); \
-} while (0)
-/* #define dprintk eprintk */
-#define dprintk(fmt, args...)
-
-struct vio_port {
- struct vio_dev *dma_dev;
-
- struct crq_queue crq_queue;
- struct work_struct crq_work;
-
- unsigned long liobn;
- unsigned long riobn;
- struct srp_target *target;
-
- struct srp_rport *rport;
-};
-
-static struct workqueue_struct *vtgtd;
-static struct scsi_transport_template *ibmvstgt_transport_template;
-
-/*
- * These are fixed for the system and come from the Open Firmware device tree.
- * We just store them here to save getting them every time.
- */
-static char system_id[64] = "";
-static char partition_name[97] = "UNKNOWN";
-static unsigned int partition_number = -1;
-
-static struct vio_port *target_to_port(struct srp_target *target)
-{
- return (struct vio_port *) target->ldata;
-}
-
-static inline union viosrp_iu *vio_iu(struct iu_entry *iue)
-{
- return (union viosrp_iu *) (iue->sbuf->buf);
-}
-
-static int send_iu(struct iu_entry *iue, uint64_t length, uint8_t format)
-{
- struct srp_target *target = iue->target;
- struct vio_port *vport = target_to_port(target);
- long rc, rc1;
- union {
- struct viosrp_crq cooked;
- uint64_t raw[2];
- } crq;
-
- /* First copy the SRP */
- rc = h_copy_rdma(length, vport->liobn, iue->sbuf->dma,
- vport->riobn, iue->remote_token);
-
- if (rc)
- eprintk("Error %ld transferring data\n", rc);
-
- crq.cooked.valid = 0x80;
- crq.cooked.format = format;
- crq.cooked.reserved = 0x00;
- crq.cooked.timeout = 0x00;
- crq.cooked.IU_length = length;
- crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag;
-
- if (rc == 0)
- crq.cooked.status = 0x99; /* Just needs to be non-zero */
- else
- crq.cooked.status = 0x00;
-
- rc1 = h_send_crq(vport->dma_dev->unit_address, crq.raw[0], crq.raw[1]);
-
- if (rc1) {
- eprintk("%ld sending response\n", rc1);
- return rc1;
- }
-
- return rc;
-}
-
-#define SRP_RSP_SENSE_DATA_LEN 18
-
-static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc,
- unsigned char status, unsigned char asc)
-{
- union viosrp_iu *iu = vio_iu(iue);
- uint64_t tag = iu->srp.rsp.tag;
-
- /* If the linked bit is on and status is good */
- if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE))
- status = 0x10;
-
- memset(iu, 0, sizeof(struct srp_rsp));
- iu->srp.rsp.opcode = SRP_RSP;
- iu->srp.rsp.req_lim_delta = 1;
- iu->srp.rsp.tag = tag;
-
- if (test_bit(V_DIOVER, &iue->flags))
- iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER;
-
- iu->srp.rsp.data_in_res_cnt = 0;
- iu->srp.rsp.data_out_res_cnt = 0;
-
- iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID;
-
- iu->srp.rsp.resp_data_len = 0;
- iu->srp.rsp.status = status;
- if (status) {
- uint8_t *sense = iu->srp.rsp.data;
-
- if (sc) {
- iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
- iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE;
- memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE);
- } else {
- iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION;
- iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID;
- iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN;
-
- /* Valid bit and 'current errors' */
- sense[0] = (0x1 << 7 | 0x70);
- /* Sense key */
- sense[2] = status;
- /* Additional sense length */
- sense[7] = 0xa; /* 10 bytes */
- /* Additional sense code */
- sense[12] = asc;
- }
- }
-
- send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN,
- VIOSRP_SRP_FORMAT);
-
- return 0;
-}
-
-static void handle_cmd_queue(struct srp_target *target)
-{
- struct Scsi_Host *shost = target->shost;
- struct srp_rport *rport = target_to_port(target)->rport;
- struct iu_entry *iue;
- struct srp_cmd *cmd;
- unsigned long flags;
- int err;
-
-retry:
- spin_lock_irqsave(&target->lock, flags);
-
- list_for_each_entry(iue, &target->cmd_queue, ilist) {
- if (!test_and_set_bit(V_FLYING, &iue->flags)) {
- spin_unlock_irqrestore(&target->lock, flags);
- cmd = iue->sbuf->buf;
- err = srp_cmd_queue(shost, cmd, iue,
- (unsigned long)rport, 0);
- if (err) {
- eprintk("cannot queue cmd %p %d\n", cmd, err);
- srp_iu_put(iue);
- }
- goto retry;
- }
- }
-
- spin_unlock_irqrestore(&target->lock, flags);
-}
-
-static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg,
- struct srp_direct_buf *md, int nmd,
- enum dma_data_direction dir, unsigned int rest)
-{
- struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
- struct srp_target *target = iue->target;
- struct vio_port *vport = target_to_port(target);
- dma_addr_t token;
- long err;
- unsigned int done = 0;
- int i, sidx, soff;
-
- sidx = soff = 0;
- token = sg_dma_address(sg + sidx);
-
- for (i = 0; i < nmd && rest; i++) {
- unsigned int mdone, mlen;
-
- mlen = min(rest, md[i].len);
- for (mdone = 0; mlen;) {
- int slen = min(sg_dma_len(sg + sidx) - soff, mlen);
-
- if (dir == DMA_TO_DEVICE)
- err = h_copy_rdma(slen,
- vport->riobn,
- md[i].va + mdone,
- vport->liobn,
- token + soff);
- else
- err = h_copy_rdma(slen,
- vport->liobn,
- token + soff,
- vport->riobn,
- md[i].va + mdone);
-
- if (err != H_SUCCESS) {
- eprintk("rdma error %d %d %ld\n", dir, slen, err);
- return -EIO;
- }
-
- mlen -= slen;
- mdone += slen;
- soff += slen;
- done += slen;
-
- if (soff == sg_dma_len(sg + sidx)) {
- sidx++;
- soff = 0;
- token = sg_dma_address(sg + sidx);
-
- if (sidx > nsg) {
- eprintk("out of sg %p %d %d\n",
- iue, sidx, nsg);
- return -EIO;
- }
- }
- };
-
- rest -= mlen;
- }
- return 0;
-}
-
-static int ibmvstgt_cmd_done(struct scsi_cmnd *sc,
- void (*done)(struct scsi_cmnd *))
-{
- unsigned long flags;
- struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
- struct srp_target *target = iue->target;
- int err = 0;
-
- dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0],
- scsi_sg_count(sc));
-
- if (scsi_sg_count(sc))
- err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1);
-
- spin_lock_irqsave(&target->lock, flags);
- list_del(&iue->ilist);
- spin_unlock_irqrestore(&target->lock, flags);
-
- if (err|| sc->result != SAM_STAT_GOOD) {
- eprintk("operation failed %p %d %x\n",
- iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]);
- send_rsp(iue, sc, HARDWARE_ERROR, 0x00);
- } else
- send_rsp(iue, sc, NO_SENSE, 0x00);
-
- done(sc);
- srp_iu_put(iue);
- return 0;
-}
-
-int send_adapter_info(struct iu_entry *iue,
- dma_addr_t remote_buffer, uint16_t length)
-{
- struct srp_target *target = iue->target;
- struct vio_port *vport = target_to_port(target);
- struct Scsi_Host *shost = target->shost;
- dma_addr_t data_token;
- struct mad_adapter_info_data *info;
- int err;
-
- info = dma_alloc_coherent(target->dev, sizeof(*info), &data_token,
- GFP_KERNEL);
- if (!info) {
- eprintk("bad dma_alloc_coherent %p\n", target);
- return 1;
- }
-
- /* Get remote info */
- err = h_copy_rdma(sizeof(*info), vport->riobn, remote_buffer,
- vport->liobn, data_token);
- if (err == H_SUCCESS) {
- dprintk("Client connect: %s (%d)\n",
- info->partition_name, info->partition_number);
- }
-
- memset(info, 0, sizeof(*info));
-
- strcpy(info->srp_version, "16.a");
- strncpy(info->partition_name, partition_name,
- sizeof(info->partition_name));
- info->partition_number = partition_number;
- info->mad_version = 1;
- info->os_type = 2;
- info->port_max_txu[0] = shost->hostt->max_sectors << 9;
-
- /* Send our info to remote */
- err = h_copy_rdma(sizeof(*info), vport->liobn, data_token,
- vport->riobn, remote_buffer);
-
- dma_free_coherent(target->dev, sizeof(*info), info, data_token);
-
- if (err != H_SUCCESS) {
- eprintk("Error sending adapter info %d\n", err);
- return 1;
- }
-
- return 0;
-}
-
-static void process_login(struct iu_entry *iue)
-{
- union viosrp_iu *iu = vio_iu(iue);
- struct srp_login_rsp *rsp = &iu->srp.login_rsp;
- uint64_t tag = iu->srp.rsp.tag;
- struct Scsi_Host *shost = iue->target->shost;
- struct srp_target *target = host_to_srp_target(shost);
- struct vio_port *vport = target_to_port(target);
- struct srp_rport_identifiers ids;
-
- memset(&ids, 0, sizeof(ids));
- sprintf(ids.port_id, "%x", vport->dma_dev->unit_address);
- ids.roles = SRP_RPORT_ROLE_INITIATOR;
- if (!vport->rport)
- vport->rport = srp_rport_add(shost, &ids);
-
- /* TODO handle case that requested size is wrong and
- * buffer format is wrong
- */
- memset(iu, 0, sizeof(struct srp_login_rsp));
- rsp->opcode = SRP_LOGIN_RSP;
- rsp->req_lim_delta = INITIAL_SRP_LIMIT;
- rsp->tag = tag;
- rsp->max_it_iu_len = sizeof(union srp_iu);
- rsp->max_ti_iu_len = sizeof(union srp_iu);
- /* direct and indirect */
- rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT;
-
- send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT);
-}
-
-static inline void queue_cmd(struct iu_entry *iue)
-{
- struct srp_target *target = iue->target;
- unsigned long flags;
-
- spin_lock_irqsave(&target->lock, flags);
- list_add_tail(&iue->ilist, &target->cmd_queue);
- spin_unlock_irqrestore(&target->lock, flags);
-}
-
-static int process_tsk_mgmt(struct iu_entry *iue)
-{
- union viosrp_iu *iu = vio_iu(iue);
- int fn;
-
- dprintk("%p %u\n", iue, iu->srp.tsk_mgmt.tsk_mgmt_func);
-
- switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
- case SRP_TSK_ABORT_TASK:
- fn = ABORT_TASK;
- break;
- case SRP_TSK_ABORT_TASK_SET:
- fn = ABORT_TASK_SET;
- break;
- case SRP_TSK_CLEAR_TASK_SET:
- fn = CLEAR_TASK_SET;
- break;
- case SRP_TSK_LUN_RESET:
- fn = LOGICAL_UNIT_RESET;
- break;
- case SRP_TSK_CLEAR_ACA:
- fn = CLEAR_ACA;
- break;
- default:
- fn = 0;
- }
- if (fn)
- scsi_tgt_tsk_mgmt_request(iue->target->shost,
- (unsigned long)iue->target->shost,
- fn,
- iu->srp.tsk_mgmt.task_tag,
- (struct scsi_lun *) &iu->srp.tsk_mgmt.lun,
- iue);
- else
- send_rsp(iue, NULL, ILLEGAL_REQUEST, 0x20);
-
- return !fn;
-}
-
-static int process_mad_iu(struct iu_entry *iue)
-{
- union viosrp_iu *iu = vio_iu(iue);
- struct viosrp_adapter_info *info;
- struct viosrp_host_config *conf;
-
- switch (iu->mad.empty_iu.common.type) {
- case VIOSRP_EMPTY_IU_TYPE:
- eprintk("%s\n", "Unsupported EMPTY MAD IU");
- break;
- case VIOSRP_ERROR_LOG_TYPE:
- eprintk("%s\n", "Unsupported ERROR LOG MAD IU");
- iu->mad.error_log.common.status = 1;
- send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT);
- break;
- case VIOSRP_ADAPTER_INFO_TYPE:
- info = &iu->mad.adapter_info;
- info->common.status = send_adapter_info(iue, info->buffer,
- info->common.length);
- send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT);
- break;
- case VIOSRP_HOST_CONFIG_TYPE:
- conf = &iu->mad.host_config;
- conf->common.status = 1;
- send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT);
- break;
- default:
- eprintk("Unknown type %u\n", iu->srp.rsp.opcode);
- }
-
- return 1;
-}
-
-static int process_srp_iu(struct iu_entry *iue)
-{
- union viosrp_iu *iu = vio_iu(iue);
- int done = 1;
- u8 opcode = iu->srp.rsp.opcode;
-
- switch (opcode) {
- case SRP_LOGIN_REQ:
- process_login(iue);
- break;
- case SRP_TSK_MGMT:
- done = process_tsk_mgmt(iue);
- break;
- case SRP_CMD:
- queue_cmd(iue);
- done = 0;
- break;
- case SRP_LOGIN_RSP:
- case SRP_I_LOGOUT:
- case SRP_T_LOGOUT:
- case SRP_RSP:
- case SRP_CRED_REQ:
- case SRP_CRED_RSP:
- case SRP_AER_REQ:
- case SRP_AER_RSP:
- eprintk("Unsupported type %u\n", opcode);
- break;
- default:
- eprintk("Unknown type %u\n", opcode);
- }
-
- return done;
-}
-
-static void process_iu(struct viosrp_crq *crq, struct srp_target *target)
-{
- struct vio_port *vport = target_to_port(target);
- struct iu_entry *iue;
- long err;
- int done = 1;
-
- iue = srp_iu_get(target);
- if (!iue) {
- eprintk("Error getting IU from pool, %p\n", target);
- return;
- }
-
- iue->remote_token = crq->IU_data_ptr;
-
- err = h_copy_rdma(crq->IU_length, vport->riobn,
- iue->remote_token, vport->liobn, iue->sbuf->dma);
-
- if (err != H_SUCCESS) {
- eprintk("%ld transferring data error %p\n", err, iue);
- goto out;
- }
-
- if (crq->format == VIOSRP_MAD_FORMAT)
- done = process_mad_iu(iue);
- else
- done = process_srp_iu(iue);
-out:
- if (done)
- srp_iu_put(iue);
-}
-
-static irqreturn_t ibmvstgt_interrupt(int dummy, void *data)
-{
- struct srp_target *target = data;
- struct vio_port *vport = target_to_port(target);
-
- vio_disable_interrupts(vport->dma_dev);
- queue_work(vtgtd, &vport->crq_work);
-
- return IRQ_HANDLED;
-}
-
-static int crq_queue_create(struct crq_queue *queue, struct srp_target *target)
-{
- int err;
- struct vio_port *vport = target_to_port(target);
-
- queue->msgs = (struct viosrp_crq *) get_zeroed_page(GFP_KERNEL);
- if (!queue->msgs)
- goto malloc_failed;
- queue->size = PAGE_SIZE / sizeof(*queue->msgs);
-
- queue->msg_token = dma_map_single(target->dev, queue->msgs,
- queue->size * sizeof(*queue->msgs),
- DMA_BIDIRECTIONAL);
-
- if (dma_mapping_error(target->dev, queue->msg_token))
- goto map_failed;
-
- err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token,
- PAGE_SIZE);
-
- /* If the adapter was left active for some reason (like kexec)
- * try freeing and re-registering
- */
- if (err == H_RESOURCE) {
- do {
- err = h_free_crq(vport->dma_dev->unit_address);
- } while (err == H_BUSY || H_IS_LONG_BUSY(err));
-
- err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token,
- PAGE_SIZE);
- }
-
- if (err != H_SUCCESS && err != 2) {
- eprintk("Error 0x%x opening virtual adapter\n", err);
- goto reg_crq_failed;
- }
-
- err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt,
- 0, "ibmvstgt", target);
- if (err)
- goto req_irq_failed;
-
- vio_enable_interrupts(vport->dma_dev);
-
- h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0);
-
- queue->cur = 0;
- spin_lock_init(&queue->lock);
-
- return 0;
-
-req_irq_failed:
- do {
- err = h_free_crq(vport->dma_dev->unit_address);
- } while (err == H_BUSY || H_IS_LONG_BUSY(err));
-
-reg_crq_failed:
- dma_unmap_single(target->dev, queue->msg_token,
- queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
-map_failed:
- free_page((unsigned long) queue->msgs);
-
-malloc_failed:
- return -ENOMEM;
-}
-
-static void crq_queue_destroy(struct srp_target *target)
-{
- struct vio_port *vport = target_to_port(target);
- struct crq_queue *queue = &vport->crq_queue;
- int err;
-
- free_irq(vport->dma_dev->irq, target);
- do {
- err = h_free_crq(vport->dma_dev->unit_address);
- } while (err == H_BUSY || H_IS_LONG_BUSY(err));
-
- dma_unmap_single(target->dev, queue->msg_token,
- queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
-
- free_page((unsigned long) queue->msgs);
-}
-
-static void process_crq(struct viosrp_crq *crq, struct srp_target *target)
-{
- struct vio_port *vport = target_to_port(target);
- dprintk("%x %x\n", crq->valid, crq->format);
-
- switch (crq->valid) {
- case 0xC0:
- /* initialization */
- switch (crq->format) {
- case 0x01:
- h_send_crq(vport->dma_dev->unit_address,
- 0xC002000000000000, 0);
- break;
- case 0x02:
- break;
- default:
- eprintk("Unknown format %u\n", crq->format);
- }
- break;
- case 0xFF:
- /* transport event */
- break;
- case 0x80:
- /* real payload */
- switch (crq->format) {
- case VIOSRP_SRP_FORMAT:
- case VIOSRP_MAD_FORMAT:
- process_iu(crq, target);
- break;
- case VIOSRP_OS400_FORMAT:
- case VIOSRP_AIX_FORMAT:
- case VIOSRP_LINUX_FORMAT:
- case VIOSRP_INLINE_FORMAT:
- eprintk("Unsupported format %u\n", crq->format);
- break;
- default:
- eprintk("Unknown format %u\n", crq->format);
- }
- break;
- default:
- eprintk("unknown message type 0x%02x!?\n", crq->valid);
- }
-}
-
-static inline struct viosrp_crq *next_crq(struct crq_queue *queue)
-{
- struct viosrp_crq *crq;
- unsigned long flags;
-
- spin_lock_irqsave(&queue->lock, flags);
- crq = &queue->msgs[queue->cur];
- if (crq->valid & 0x80) {
- if (++queue->cur == queue->size)
- queue->cur = 0;
- } else
- crq = NULL;
- spin_unlock_irqrestore(&queue->lock, flags);
-
- return crq;
-}
-
-static void handle_crq(struct work_struct *work)
-{
- struct vio_port *vport = container_of(work, struct vio_port, crq_work);
- struct srp_target *target = vport->target;
- struct viosrp_crq *crq;
- int done = 0;
-
- while (!done) {
- while ((crq = next_crq(&vport->crq_queue)) != NULL) {
- process_crq(crq, target);
- crq->valid = 0x00;
- }
-
- vio_enable_interrupts(vport->dma_dev);
-
- crq = next_crq(&vport->crq_queue);
- if (crq) {
- vio_disable_interrupts(vport->dma_dev);
- process_crq(crq, target);
- crq->valid = 0x00;
- } else
- done = 1;
- }
-
- handle_cmd_queue(target);
-}
-
-
-static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc)
-{
- unsigned long flags;
- struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr;
- struct srp_target *target = iue->target;
-
- dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]);
-
- spin_lock_irqsave(&target->lock, flags);
- list_del(&iue->ilist);
- spin_unlock_irqrestore(&target->lock, flags);
-
- srp_iu_put(iue);
-
- return 0;
-}
-
-static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost,
- u64 itn_id, u64 mid, int result)
-{
- struct iu_entry *iue = (struct iu_entry *) ((void *) mid);
- union viosrp_iu *iu = vio_iu(iue);
- unsigned char status, asc;
-
- eprintk("%p %d\n", iue, result);
- status = NO_SENSE;
- asc = 0;
-
- switch (iu->srp.tsk_mgmt.tsk_mgmt_func) {
- case SRP_TSK_ABORT_TASK:
- asc = 0x14;
- if (result)
- status = ABORTED_COMMAND;
- break;
- default:
- break;
- }
-
- send_rsp(iue, NULL, status, asc);
- srp_iu_put(iue);
-
- return 0;
-}
-
-static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id,
- int result)
-{
- struct srp_target *target = host_to_srp_target(shost);
- struct vio_port *vport = target_to_port(target);
-
- if (result) {
- eprintk("%p %d\n", shost, result);
- srp_rport_del(vport->rport);
- vport->rport = NULL;
- }
- return 0;
-}
-
-static ssize_t system_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n", system_id);
-}
-
-static ssize_t partition_number_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%x\n", partition_number);
-}
-
-static ssize_t unit_address_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct Scsi_Host *shost = class_to_shost(dev);
- struct srp_target *target = host_to_srp_target(shost);
- struct vio_port *vport = target_to_port(target);
- return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address);
-}
-
-static DEVICE_ATTR(system_id, S_IRUGO, system_id_show, NULL);
-static DEVICE_ATTR(partition_number, S_IRUGO, partition_number_show, NULL);
-static DEVICE_ATTR(unit_address, S_IRUGO, unit_address_show, NULL);
-
-static struct device_attribute *ibmvstgt_attrs[] = {
- &dev_attr_system_id,
- &dev_attr_partition_number,
- &dev_attr_unit_address,
- NULL,
-};
-
-static struct scsi_host_template ibmvstgt_sht = {
- .name = TGT_NAME,
- .module = THIS_MODULE,
- .can_queue = INITIAL_SRP_LIMIT,
- .sg_tablesize = SG_ALL,
- .use_clustering = DISABLE_CLUSTERING,
- .max_sectors = DEFAULT_MAX_SECTORS,
- .transfer_response = ibmvstgt_cmd_done,
- .eh_abort_handler = ibmvstgt_eh_abort_handler,
- .shost_attrs = ibmvstgt_attrs,
- .proc_name = TGT_NAME,
- .supported_mode = MODE_TARGET,
-};
-
-static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
-{
- struct Scsi_Host *shost;
- struct srp_target *target;
- struct vio_port *vport;
- unsigned int *dma, dma_size;
- int err = -ENOMEM;
-
- vport = kzalloc(sizeof(struct vio_port), GFP_KERNEL);
- if (!vport)
- return err;
- shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target));
- if (!shost)
- goto free_vport;
- shost->transportt = ibmvstgt_transport_template;
-
- target = host_to_srp_target(shost);
- target->shost = shost;
- vport->dma_dev = dev;
- target->ldata = vport;
- vport->target = target;
- err = srp_target_alloc(target, &dev->dev, INITIAL_SRP_LIMIT,
- SRP_MAX_IU_LEN);
- if (err)
- goto put_host;
-
- dma = (unsigned int *) vio_get_attribute(dev, "ibm,my-dma-window",
- &dma_size);
- if (!dma || dma_size != 40) {
- eprintk("Couldn't get window property %d\n", dma_size);
- err = -EIO;
- goto free_srp_target;
- }
- vport->liobn = dma[0];
- vport->riobn = dma[5];
-
- INIT_WORK(&vport->crq_work, handle_crq);
-
- err = scsi_add_host(shost, target->dev);
- if (err)
- goto free_srp_target;
-
- err = scsi_tgt_alloc_queue(shost);
- if (err)
- goto remove_host;
-
- err = crq_queue_create(&vport->crq_queue, target);
- if (err)
- goto free_queue;
-
- return 0;
-free_queue:
- scsi_tgt_free_queue(shost);
-remove_host:
- scsi_remove_host(shost);
-free_srp_target:
- srp_target_free(target);
-put_host:
- scsi_host_put(shost);
-free_vport:
- kfree(vport);
- return err;
-}
-
-static int ibmvstgt_remove(struct vio_dev *dev)
-{
- struct srp_target *target = dev_get_drvdata(&dev->dev);
- struct Scsi_Host *shost = target->shost;
- struct vio_port *vport = target->ldata;
-
- crq_queue_destroy(target);
- srp_remove_host(shost);
- scsi_remove_host(shost);
- scsi_tgt_free_queue(shost);
- srp_target_free(target);
- kfree(vport);
- scsi_host_put(shost);
- return 0;
-}
-
-static struct vio_device_id ibmvstgt_device_table[] = {
- {"v-scsi-host", "IBM,v-scsi-host"},
- {"",""}
-};
-
-MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table);
-
-static struct vio_driver ibmvstgt_driver = {
- .id_table = ibmvstgt_device_table,
- .probe = ibmvstgt_probe,
- .remove = ibmvstgt_remove,
- .name = "ibmvscsis",
-};
-
-static int get_system_info(void)
-{
- struct device_node *rootdn;
- const char *id, *model, *name;
- const unsigned int *num;
-
- rootdn = of_find_node_by_path("/");
- if (!rootdn)
- return -ENOENT;
-
- model = of_get_property(rootdn, "model", NULL);
- id = of_get_property(rootdn, "system-id", NULL);
- if (model && id)
- snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
-
- name = of_get_property(rootdn, "ibm,partition-name", NULL);
- if (name)
- strncpy(partition_name, name, sizeof(partition_name));
-
- num = of_get_property(rootdn, "ibm,partition-no", NULL);
- if (num)
- partition_number = *num;
-
- of_node_put(rootdn);
- return 0;
-}
-
-static struct srp_function_template ibmvstgt_transport_functions = {
- .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response,
- .it_nexus_response = ibmvstgt_it_nexus_response,
-};
-
-static int __init ibmvstgt_init(void)
-{
- int err = -ENOMEM;
-
- printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n");
-
- ibmvstgt_transport_template =
- srp_attach_transport(&ibmvstgt_transport_functions);
- if (!ibmvstgt_transport_template)
- return err;
-
- vtgtd = create_workqueue("ibmvtgtd");
- if (!vtgtd)
- goto release_transport;
-
- err = get_system_info();
- if (err)
- goto destroy_wq;
-
- err = vio_register_driver(&ibmvstgt_driver);
- if (err)
- goto destroy_wq;
-
- return 0;
-destroy_wq:
- destroy_workqueue(vtgtd);
-release_transport:
- srp_release_transport(ibmvstgt_transport_template);
- return err;
-}
-
-static void __exit ibmvstgt_exit(void)
-{
- printk("Unregister IBM virtual SCSI driver\n");
-
- destroy_workqueue(vtgtd);
- vio_unregister_driver(&ibmvstgt_driver);
- srp_release_transport(ibmvstgt_transport_template);
-}
-
-MODULE_DESCRIPTION("IBM Virtual SCSI Target");
-MODULE_AUTHOR("Santiago Leon");
-MODULE_LICENSE("GPL");
-
-module_init(ibmvstgt_init);
-module_exit(ibmvstgt_exit);
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index b1c4d831137d..ddf0694d87f0 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -2251,14 +2251,14 @@ static int in2000_show_info(struct seq_file *m, struct Scsi_Host *instance)
seq_printf(m, "\nconnected: ");
if (hd->connected) {
cmd = (Scsi_Cmnd *) hd->connected;
- seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+ seq_printf(m, " %d:%llu(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
}
}
if (hd->proc & PR_INPUTQ) {
seq_printf(m, "\ninput_Q: ");
cmd = (Scsi_Cmnd *) hd->input_Q;
while (cmd) {
- seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+ seq_printf(m, " %d:%llu(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
}
@@ -2266,7 +2266,7 @@ static int in2000_show_info(struct seq_file *m, struct Scsi_Host *instance)
seq_printf(m, "\ndisconnected_Q:");
cmd = (Scsi_Cmnd *) hd->disconnected_Q;
while (cmd) {
- seq_printf(m, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+ seq_printf(m, " %d:%llu(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
cmd = (Scsi_Cmnd *) cmd->host_scribble;
}
}
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 695b34e9154e..4198e45ea941 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -356,7 +356,7 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
for (i = 0; i < num_msix; i++)
pci_info->msix_entries[i].entry = i;
- err = pci_enable_msix(pdev, pci_info->msix_entries, num_msix);
+ err = pci_enable_msix_exact(pdev, pci_info->msix_entries, num_msix);
if (err)
goto intx;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 3d1bc67bac9d..f9f3a1224dfa 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -260,7 +260,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
{
struct iscsi_conn *conn = task->conn;
struct iscsi_tm *tmf = &conn->tmhdr;
- unsigned int hdr_lun;
+ u64 hdr_lun;
if (conn->tmf_state == TMF_INITIAL)
return 0;
@@ -1859,8 +1859,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
* Fail commands. session lock held and recv side suspended and xmit
* thread flushed
*/
-static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun,
- int error)
+static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
{
struct iscsi_task *task;
int i;
@@ -2279,7 +2278,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data;
- ISCSI_DBG_EH(session, "LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
+ ISCSI_DBG_EH(session, "LU Reset [sc %p lun %llu]\n", sc,
+ sc->device->lun);
mutex_lock(&session->eh_mutex);
spin_lock_bh(&session->frwd_lock);
@@ -2971,7 +2971,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
*/
for (;;) {
spin_lock_irqsave(session->host->host_lock, flags);
- if (!session->host->host_busy) { /* OK for ERL == 0 */
+ if (!atomic_read(&session->host->host_busy)) { /* OK for ERL == 0 */
spin_unlock_irqrestore(session->host->host_lock, flags);
break;
}
@@ -2979,7 +2979,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
msleep_interruptible(500);
iscsi_conn_printk(KERN_INFO, conn, "iscsi conn_destroy(): "
"host_busy %d host_failed %d\n",
- session->host->host_busy,
+ atomic_read(&session->host->host_busy),
session->host->host_failed);
/*
* force eh_abort() to unblock
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 25d0f127424d..24e477d2ea70 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -404,7 +404,7 @@ static int sas_recover_lu(struct domain_device *dev, struct scsi_cmnd *cmd)
int_to_scsilun(cmd->device->lun, &lun);
- SAS_DPRINTK("eh: device %llx LUN %x has the task\n",
+ SAS_DPRINTK("eh: device %llx LUN %llx has the task\n",
SAS_ADDR(dev->sas_addr),
cmd->device->lun);
@@ -490,7 +490,8 @@ static void sas_wait_eh(struct domain_device *dev)
}
EXPORT_SYMBOL(sas_wait_eh);
-static int sas_queue_reset(struct domain_device *dev, int reset_type, int lun, int wait)
+static int sas_queue_reset(struct domain_device *dev, int reset_type,
+ u64 lun, int wait)
{
struct sas_ha_struct *ha = dev->port->ha;
int scheduled = 0, tries = 100;
@@ -689,7 +690,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
reset:
tmf_resp = sas_recover_lu(task->dev, cmd);
if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
- SAS_DPRINTK("dev %016llx LU %x is "
+ SAS_DPRINTK("dev %016llx LU %llx is "
"recovered\n",
SAS_ADDR(task->dev),
cmd->device->lun);
@@ -742,7 +743,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *
* of effort could recover from errors. Quite
* possibly the HA just disappeared.
*/
- SAS_DPRINTK("error from device %llx, LUN %x "
+ SAS_DPRINTK("error from device %llx, LUN %llx "
"couldn't be recovered in any way\n",
SAS_ADDR(task->dev->sas_addr),
cmd->device->lun);
@@ -812,7 +813,7 @@ retry:
spin_unlock_irq(shost->host_lock);
SAS_DPRINTK("Enter %s busy: %d failed: %d\n",
- __func__, shost->host_busy, shost->host_failed);
+ __func__, atomic_read(&shost->host_busy), shost->host_failed);
/*
* Deal with commands that still have SAS tasks (i.e. they didn't
* complete via the normal sas_task completion mechanism),
@@ -857,7 +858,8 @@ out:
goto retry;
SAS_DPRINTK("--- Exit %s: busy: %d failed: %d tries: %d\n",
- __func__, shost->host_busy, shost->host_failed, tries);
+ __func__, atomic_read(&shost->host_busy),
+ shost->host_failed, tries);
}
enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
@@ -941,7 +943,7 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
scsi_set_tag_type(scsi_dev, MSG_SIMPLE_TAG);
scsi_activate_tcq(scsi_dev, SAS_DEF_QD);
} else {
- SAS_DPRINTK("device %llx, LUN %x doesn't support "
+ SAS_DPRINTK("device %llx, LUN %llx doesn't support "
"TCQ\n", SAS_ADDR(dev->sas_addr),
scsi_dev->lun);
scsi_dev->tagged_supported = 0;
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
deleted file mode 100644
index 0707ecdbaa32..000000000000
--- a/drivers/scsi/libsrp.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * SCSI RDMA Protocol lib functions
- *
- * Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org>
- *
- * 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/err.h>
-#include <linux/slab.h>
-#include <linux/kfifo.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_tgt.h>
-#include <scsi/srp.h>
-#include <scsi/libsrp.h>
-
-enum srp_task_attributes {
- SRP_SIMPLE_TASK = 0,
- SRP_HEAD_TASK = 1,
- SRP_ORDERED_TASK = 2,
- SRP_ACA_TASK = 4
-};
-
-/* tmp - will replace with SCSI logging stuff */
-#define eprintk(fmt, args...) \
-do { \
- printk("%s(%d) " fmt, __func__, __LINE__, ##args); \
-} while (0)
-/* #define dprintk eprintk */
-#define dprintk(fmt, args...)
-
-static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
- struct srp_buf **ring)
-{
- int i;
- struct iu_entry *iue;
-
- q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL);
- if (!q->pool)
- return -ENOMEM;
- q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL);
- if (!q->items)
- goto free_pool;
-
- spin_lock_init(&q->lock);
- kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
-
- for (i = 0, iue = q->items; i < max; i++) {
- kfifo_in(&q->queue, (void *) &iue, sizeof(void *));
- iue->sbuf = ring[i];
- iue++;
- }
- return 0;
-
- kfree(q->items);
-free_pool:
- kfree(q->pool);
- return -ENOMEM;
-}
-
-static void srp_iu_pool_free(struct srp_queue *q)
-{
- kfree(q->items);
- kfree(q->pool);
-}
-
-static struct srp_buf **srp_ring_alloc(struct device *dev,
- size_t max, size_t size)
-{
- int i;
- struct srp_buf **ring;
-
- ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL);
- if (!ring)
- return NULL;
-
- for (i = 0; i < max; i++) {
- ring[i] = kzalloc(sizeof(struct srp_buf), GFP_KERNEL);
- if (!ring[i])
- goto out;
- ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma,
- GFP_KERNEL);
- if (!ring[i]->buf)
- goto out;
- }
- return ring;
-
-out:
- for (i = 0; i < max && ring[i]; i++) {
- if (ring[i]->buf)
- dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
- kfree(ring[i]);
- }
- kfree(ring);
-
- return NULL;
-}
-
-static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
- size_t size)
-{
- int i;
-
- for (i = 0; i < max; i++) {
- dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
- kfree(ring[i]);
- }
- kfree(ring);
-}
-
-int srp_target_alloc(struct srp_target *target, struct device *dev,
- size_t nr, size_t iu_size)
-{
- int err;
-
- spin_lock_init(&target->lock);
- INIT_LIST_HEAD(&target->cmd_queue);
-
- target->dev = dev;
- dev_set_drvdata(target->dev, target);
-
- target->srp_iu_size = iu_size;
- target->rx_ring_size = nr;
- target->rx_ring = srp_ring_alloc(target->dev, nr, iu_size);
- if (!target->rx_ring)
- return -ENOMEM;
- err = srp_iu_pool_alloc(&target->iu_queue, nr, target->rx_ring);
- if (err)
- goto free_ring;
-
- return 0;
-
-free_ring:
- srp_ring_free(target->dev, target->rx_ring, nr, iu_size);
- return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(srp_target_alloc);
-
-void srp_target_free(struct srp_target *target)
-{
- srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size,
- target->srp_iu_size);
- srp_iu_pool_free(&target->iu_queue);
-}
-EXPORT_SYMBOL_GPL(srp_target_free);
-
-struct iu_entry *srp_iu_get(struct srp_target *target)
-{
- struct iu_entry *iue = NULL;
-
- if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue,
- sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) {
- WARN_ONCE(1, "unexpected fifo state");
- return NULL;
- }
- if (!iue)
- return iue;
- iue->target = target;
- INIT_LIST_HEAD(&iue->ilist);
- iue->flags = 0;
- return iue;
-}
-EXPORT_SYMBOL_GPL(srp_iu_get);
-
-void srp_iu_put(struct iu_entry *iue)
-{
- kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue,
- sizeof(void *), &iue->target->iu_queue.lock);
-}
-EXPORT_SYMBOL_GPL(srp_iu_put);
-
-static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md,
- enum dma_data_direction dir, srp_rdma_t rdma_io,
- int dma_map, int ext_desc)
-{
- struct iu_entry *iue = NULL;
- struct scatterlist *sg = NULL;
- int err, nsg = 0, len;
-
- if (dma_map) {
- iue = (struct iu_entry *) sc->SCp.ptr;
- sg = scsi_sglist(sc);
-
- dprintk("%p %u %u %d\n", iue, scsi_bufflen(sc),
- md->len, scsi_sg_count(sc));
-
- nsg = dma_map_sg(iue->target->dev, sg, scsi_sg_count(sc),
- DMA_BIDIRECTIONAL);
- if (!nsg) {
- printk("fail to map %p %d\n", iue, scsi_sg_count(sc));
- return 0;
- }
- len = min(scsi_bufflen(sc), md->len);
- } else
- len = md->len;
-
- err = rdma_io(sc, sg, nsg, md, 1, dir, len);
-
- if (dma_map)
- dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
-
- return err;
-}
-
-static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
- struct srp_indirect_buf *id,
- enum dma_data_direction dir, srp_rdma_t rdma_io,
- int dma_map, int ext_desc)
-{
- struct iu_entry *iue = NULL;
- struct srp_direct_buf *md = NULL;
- struct scatterlist dummy, *sg = NULL;
- dma_addr_t token = 0;
- int err = 0;
- int nmd, nsg = 0, len;
-
- if (dma_map || ext_desc) {
- iue = (struct iu_entry *) sc->SCp.ptr;
- sg = scsi_sglist(sc);
-
- dprintk("%p %u %u %d %d\n",
- iue, scsi_bufflen(sc), id->len,
- cmd->data_in_desc_cnt, cmd->data_out_desc_cnt);
- }
-
- nmd = id->table_desc.len / sizeof(struct srp_direct_buf);
-
- if ((dir == DMA_FROM_DEVICE && nmd == cmd->data_in_desc_cnt) ||
- (dir == DMA_TO_DEVICE && nmd == cmd->data_out_desc_cnt)) {
- md = &id->desc_list[0];
- goto rdma;
- }
-
- if (ext_desc && dma_map) {
- md = dma_alloc_coherent(iue->target->dev, id->table_desc.len,
- &token, GFP_KERNEL);
- if (!md) {
- eprintk("Can't get dma memory %u\n", id->table_desc.len);
- return -ENOMEM;
- }
-
- sg_init_one(&dummy, md, id->table_desc.len);
- sg_dma_address(&dummy) = token;
- sg_dma_len(&dummy) = id->table_desc.len;
- err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
- id->table_desc.len);
- if (err) {
- eprintk("Error copying indirect table %d\n", err);
- goto free_mem;
- }
- } else {
- eprintk("This command uses external indirect buffer\n");
- return -EINVAL;
- }
-
-rdma:
- if (dma_map) {
- nsg = dma_map_sg(iue->target->dev, sg, scsi_sg_count(sc),
- DMA_BIDIRECTIONAL);
- if (!nsg) {
- eprintk("fail to map %p %d\n", iue, scsi_sg_count(sc));
- err = -EIO;
- goto free_mem;
- }
- len = min(scsi_bufflen(sc), id->len);
- } else
- len = id->len;
-
- err = rdma_io(sc, sg, nsg, md, nmd, dir, len);
-
- if (dma_map)
- dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
-
-free_mem:
- if (token && dma_map)
- dma_free_coherent(iue->target->dev, id->table_desc.len, md, token);
-
- return err;
-}
-
-static int data_out_desc_size(struct srp_cmd *cmd)
-{
- int size = 0;
- u8 fmt = cmd->buf_fmt >> 4;
-
- switch (fmt) {
- case SRP_NO_DATA_DESC:
- break;
- case SRP_DATA_DESC_DIRECT:
- size = sizeof(struct srp_direct_buf);
- break;
- case SRP_DATA_DESC_INDIRECT:
- size = sizeof(struct srp_indirect_buf) +
- sizeof(struct srp_direct_buf) * cmd->data_out_desc_cnt;
- break;
- default:
- eprintk("client error. Invalid data_out_format %x\n", fmt);
- break;
- }
- return size;
-}
-
-/*
- * TODO: this can be called multiple times for a single command if it
- * has very long data.
- */
-int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd,
- srp_rdma_t rdma_io, int dma_map, int ext_desc)
-{
- struct srp_direct_buf *md;
- struct srp_indirect_buf *id;
- enum dma_data_direction dir;
- int offset, err = 0;
- u8 format;
-
- offset = cmd->add_cdb_len & ~3;
-
- dir = srp_cmd_direction(cmd);
- if (dir == DMA_FROM_DEVICE)
- offset += data_out_desc_size(cmd);
-
- if (dir == DMA_TO_DEVICE)
- format = cmd->buf_fmt >> 4;
- else
- format = cmd->buf_fmt & ((1U << 4) - 1);
-
- switch (format) {
- case SRP_NO_DATA_DESC:
- break;
- case SRP_DATA_DESC_DIRECT:
- md = (struct srp_direct_buf *)
- (cmd->add_data + offset);
- err = srp_direct_data(sc, md, dir, rdma_io, dma_map, ext_desc);
- break;
- case SRP_DATA_DESC_INDIRECT:
- id = (struct srp_indirect_buf *)
- (cmd->add_data + offset);
- err = srp_indirect_data(sc, cmd, id, dir, rdma_io, dma_map,
- ext_desc);
- break;
- default:
- eprintk("Unknown format %d %x\n", dir, format);
- err = -EINVAL;
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(srp_transfer_data);
-
-static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
-{
- struct srp_direct_buf *md;
- struct srp_indirect_buf *id;
- int len = 0, offset = cmd->add_cdb_len & ~3;
- u8 fmt;
-
- if (dir == DMA_TO_DEVICE)
- fmt = cmd->buf_fmt >> 4;
- else {
- fmt = cmd->buf_fmt & ((1U << 4) - 1);
- offset += data_out_desc_size(cmd);
- }
-
- switch (fmt) {
- case SRP_NO_DATA_DESC:
- break;
- case SRP_DATA_DESC_DIRECT:
- md = (struct srp_direct_buf *) (cmd->add_data + offset);
- len = md->len;
- break;
- case SRP_DATA_DESC_INDIRECT:
- id = (struct srp_indirect_buf *) (cmd->add_data + offset);
- len = id->len;
- break;
- default:
- eprintk("invalid data format %x\n", fmt);
- break;
- }
- return len;
-}
-
-int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
- u64 itn_id, u64 addr)
-{
- enum dma_data_direction dir;
- struct scsi_cmnd *sc;
- int tag, len, err;
-
- switch (cmd->task_attr) {
- case SRP_SIMPLE_TASK:
- tag = MSG_SIMPLE_TAG;
- break;
- case SRP_ORDERED_TASK:
- tag = MSG_ORDERED_TAG;
- break;
- case SRP_HEAD_TASK:
- tag = MSG_HEAD_TAG;
- break;
- default:
- eprintk("Task attribute %d not supported\n", cmd->task_attr);
- tag = MSG_ORDERED_TAG;
- }
-
- dir = srp_cmd_direction(cmd);
- len = vscsis_data_length(cmd, dir);
-
- dprintk("%p %x %lx %d %d %d %llx\n", info, cmd->cdb[0],
- cmd->lun, dir, len, tag, (unsigned long long) cmd->tag);
-
- sc = scsi_host_get_command(shost, dir, GFP_KERNEL);
- if (!sc)
- return -ENOMEM;
-
- sc->SCp.ptr = info;
- memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE);
- sc->sdb.length = len;
- sc->sdb.table.sgl = (void *) (unsigned long) addr;
- sc->tag = tag;
- err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun,
- cmd->tag);
- if (err)
- scsi_host_put_command(shost, sc);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(srp_cmd_queue);
-
-MODULE_DESCRIPTION("SCSI RDMA Protocol lib functions");
-MODULE_AUTHOR("FUJITA Tomonori");
-MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 1d7a5c34ee8c..6eed9e76a166 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1998,6 +1998,14 @@ lpfc_vport_param_show(name)\
lpfc_vport_param_init(name, defval, minval, maxval)\
static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+#define LPFC_VPORT_ULL_ATTR_R(name, defval, minval, maxval, desc) \
+static uint64_t lpfc_##name = defval;\
+module_param(lpfc_##name, ullong, S_IRUGO);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_show(name)\
+lpfc_vport_param_init(name, defval, minval, maxval)\
+static DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
#define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \
static uint lpfc_##name = defval;\
module_param(lpfc_##name, uint, S_IRUGO);\
@@ -4596,7 +4604,7 @@ LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
# Value range is [0,65535]. Default value is 255.
# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
*/
-LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
+LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
/*
# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 06f9a5b79e66..a5769a9960ac 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8242,7 +8242,7 @@ lpfc_sli_enable_msix(struct lpfc_hba *phba)
if (rc) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"0420 PCI enable MSI-X failed (%d)\n", rc);
- goto msi_fail_out;
+ goto vec_fail_out;
}
for (i = 0; i < LPFC_MSIX_VECTORS; i++)
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
@@ -8320,6 +8320,8 @@ irq_fail_out:
msi_fail_out:
/* Unconfigure MSI-X capability structure */
pci_disable_msix(phba->pcidev);
+
+vec_fail_out:
return rc;
}
@@ -8812,7 +8814,7 @@ enable_msix_vectors:
} else if (rc) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"0484 PCI enable MSI-X failed (%d)\n", rc);
- goto msi_fail_out;
+ goto vec_fail_out;
}
/* Log MSI-X vector assignment */
@@ -8875,9 +8877,10 @@ cfg_fail_out:
&phba->sli4_hba.fcp_eq_hdl[index]);
}
-msi_fail_out:
/* Unconfigure MSI-X capability structure */
pci_disable_msix(phba->pcidev);
+
+vec_fail_out:
return rc;
}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 2df11daad85b..7862c5540861 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -258,7 +258,7 @@ static void
lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba,
struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp,
- uint32_t lun,
+ uint64_t lun,
uint32_t old_val,
uint32_t new_val)
{
@@ -3823,7 +3823,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"2719 Invalid response length: "
- "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
+ "tgt x%x lun x%llx cmnd x%x rsplen x%x\n",
cmnd->device->id,
cmnd->device->lun, cmnd->cmnd[0],
rsplen);
@@ -3834,7 +3834,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"2757 Protocol failure detected during "
"processing of FCP I/O op: "
- "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
+ "tgt x%x lun x%llx cmnd x%x rspInfo3 x%x\n",
cmnd->device->id,
cmnd->device->lun, cmnd->cmnd[0],
fcprsp->rspInfo3);
@@ -4045,7 +4045,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
else
logit = LOG_FCP | LOG_FCP_UNDER;
lpfc_printf_vlog(vport, KERN_WARNING, logit,
- "9030 FCP cmd x%x failed <%d/%d> "
+ "9030 FCP cmd x%x failed <%d/%lld> "
"status: x%x result: x%x "
"sid: x%x did: x%x oxid: x%x "
"Data: x%x x%x\n",
@@ -4157,7 +4157,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
uint32_t *lp = (uint32_t *)cmd->sense_buffer;
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
- "0710 Iodone <%d/%d> cmd %p, error "
+ "0710 Iodone <%d/%llu> cmd %p, error "
"x%x SNS x%x x%x Data: x%x x%x\n",
cmd->device->id, cmd->device->lun, cmd,
cmd->result, *lp, *(lp + 3), cmd->retries,
@@ -4390,7 +4390,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
static int
lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
struct lpfc_scsi_buf *lpfc_cmd,
- unsigned int lun,
+ uint64_t lun,
uint8_t task_mgmt_cmd)
{
struct lpfc_iocbq *piocbq;
@@ -4719,12 +4719,12 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
atomic_dec(&ndlp->cmd_pending);
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
"3376 FCP could not issue IOCB err %x"
- "FCP cmd x%x <%d/%d> "
+ "FCP cmd x%x <%d/%llu> "
"sid: x%x did: x%x oxid: x%x "
"Data: x%x x%x x%x x%x\n",
err, cmnd->cmnd[0],
cmnd->device ? cmnd->device->id : 0xffff,
- cmnd->device ? cmnd->device->lun : 0xffff,
+ cmnd->device ? cmnd->device->lun : (u64) -1,
vport->fc_myDID, ndlp->nlp_DID,
phba->sli_rev == LPFC_SLI_REV4 ?
lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff,
@@ -4807,7 +4807,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
spin_unlock_irqrestore(&phba->hbalock, flags);
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"2873 SCSI Layer I/O Abort Request IO CMPL Status "
- "x%x ID %d LUN %d\n",
+ "x%x ID %d LUN %llu\n",
SUCCESS, cmnd->device->id, cmnd->device->lun);
return SUCCESS;
}
@@ -4924,7 +4924,7 @@ wait_for_cmpl:
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"0748 abort handler timed out waiting "
"for abortng I/O (xri:x%x) to complete: "
- "ret %#x, ID %d, LUN %d\n",
+ "ret %#x, ID %d, LUN %llu\n",
iocb->sli4_xritag, ret,
cmnd->device->id, cmnd->device->lun);
}
@@ -4935,7 +4935,7 @@ out_unlock:
out:
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"0749 SCSI Layer I/O Abort Request Status x%x ID %d "
- "LUN %d\n", ret, cmnd->device->id,
+ "LUN %llu\n", ret, cmnd->device->id,
cmnd->device->lun);
return ret;
}
@@ -5047,7 +5047,7 @@ lpfc_check_fcp_rsp(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd)
**/
static int
lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
- unsigned tgt_id, unsigned int lun_id,
+ unsigned tgt_id, uint64_t lun_id,
uint8_t task_mgmt_cmd)
{
struct lpfc_hba *phba = vport->phba;
@@ -5083,7 +5083,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
- "0702 Issue %s to TGT %d LUN %d "
+ "0702 Issue %s to TGT %d LUN %llu "
"rpi x%x nlp_flag x%x Data: x%x x%x\n",
lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag,
@@ -5094,7 +5094,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
if ((status != IOCB_SUCCESS) ||
(iocbqrsp->iocb.ulpStatus != IOSTAT_SUCCESS)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
- "0727 TMF %s to TGT %d LUN %d failed (%d, %d) "
+ "0727 TMF %s to TGT %d LUN %llu failed (%d, %d) "
"iocb_flag x%x\n",
lpfc_taskmgmt_name(task_mgmt_cmd),
tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
@@ -5238,7 +5238,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
struct lpfc_rport_data *rdata;
struct lpfc_nodelist *pnode;
unsigned tgt_id = cmnd->device->id;
- unsigned int lun_id = cmnd->device->lun;
+ uint64_t lun_id = cmnd->device->lun;
struct lpfc_scsi_event_header scsi_event;
int status;
@@ -5273,7 +5273,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
FCP_LUN_RESET);
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
- "0713 SCSI layer issued Device Reset (%d, %d) "
+ "0713 SCSI layer issued Device Reset (%d, %llu) "
"return x%x\n", tgt_id, lun_id, status);
/*
@@ -5308,7 +5308,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
struct lpfc_rport_data *rdata;
struct lpfc_nodelist *pnode;
unsigned tgt_id = cmnd->device->id;
- unsigned int lun_id = cmnd->device->lun;
+ uint64_t lun_id = cmnd->device->lun;
struct lpfc_scsi_event_header scsi_event;
int status;
@@ -5343,7 +5343,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
FCP_TARGET_RESET);
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
- "0723 SCSI layer issued Target Reset (%d, %d) "
+ "0723 SCSI layer issued Target Reset (%d, %llu) "
"return x%x\n", tgt_id, lun_id, status);
/*
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index b7770516f4c2..ac5d94cfd52f 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -1860,7 +1860,7 @@ megaraid_info(struct Scsi_Host *host)
"LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
adapter->fw_version, adapter->product_info.max_commands,
adapter->host->max_id, adapter->host->max_channel,
- adapter->host->max_lun);
+ (u32)adapter->host->max_lun);
return buffer;
}
@@ -1941,8 +1941,8 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
printk(KERN_WARNING "megaraid: %s cmd=%x <c=%d t=%d l=%d>\n",
(aor == SCB_ABORT)? "ABORTING":"RESET",
- cmd->cmnd[0], cmd->device->channel,
- cmd->device->id, cmd->device->lun);
+ cmd->cmnd[0], cmd->device->channel,
+ cmd->device->id, (u32)cmd->device->lun);
if(list_empty(&adapter->pending_list))
return FALSE;
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 5ead1283a844..1d037ed52c33 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -204,7 +204,7 @@ typedef struct {
#define SCP2HOSTDATA(scp) SCP2HOST(scp)->hostdata // to soft state
#define SCP2CHANNEL(scp) (scp)->device->channel // to channel
#define SCP2TARGET(scp) (scp)->device->id // to target
-#define SCP2LUN(scp) (scp)->device->lun // to LUN
+#define SCP2LUN(scp) (u32)(scp)->device->lun // to LUN
// generic macro to convert scsi command and host to controller's soft state
#define SCSIHOST2ADAP(host) (((caddr_t *)(host->hostdata))[0])
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 22600419ae9f..3ed03dfab76c 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1690,7 +1690,7 @@ NonFastPath:
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
}
io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id);
- io_request->LUN[1] = scmd->device->lun;
+ int_to_scsilun(scmd->device->lun, (struct scsi_lun *)io_request->LUN);
}
/**
@@ -1713,7 +1713,7 @@ megasas_build_io_fusion(struct megasas_instance *instance,
device_id = MEGASAS_DEV_INDEX(instance, scp);
/* Zero out some fields so they don't get reused */
- io_request->LUN[1] = 0;
+ memset(io_request->LUN, 0x0, 8);
io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0;
io_request->EEDPFlags = 0;
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index e8a04ae3276a..7a6160f172ce 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1230,7 +1230,7 @@ static void handle_msgin(struct mesh_state *ms)
ms->msgphase = msg_out;
} else if (code != cmd->device->lun + IDENTIFY_BASE) {
printk(KERN_WARNING "mesh: lun mismatch "
- "(%d != %d) on reselection from "
+ "(%d != %llu) on reselection from "
"target %d\n", code - IDENTIFY_BASE,
cmd->device->lun, ms->conn_tgt);
}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 8b88118e20e6..2f262be890c5 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -277,7 +277,7 @@ mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
ioc->fault_reset_work_q = NULL;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
if (wq) {
- if (!cancel_delayed_work(&ioc->fault_reset_work))
+ if (!cancel_delayed_work_sync(&ioc->fault_reset_work))
flush_workqueue(wq);
destroy_workqueue(wq);
}
@@ -1332,53 +1332,35 @@ _base_request_irq(struct MPT2SAS_ADAPTER *ioc, u8 index, u32 vector)
static void
_base_assign_reply_queues(struct MPT2SAS_ADAPTER *ioc)
{
- struct adapter_reply_queue *reply_q;
- int cpu_id;
- int cpu_grouping, loop, grouping, grouping_mod;
+ unsigned int cpu, nr_cpus, nr_msix, index = 0;
if (!_base_is_controller_msix_enabled(ioc))
return;
memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz);
- /* when there are more cpus than available msix vectors,
- * then group cpus togeather on same irq
- */
- if (ioc->cpu_count > ioc->msix_vector_count) {
- grouping = ioc->cpu_count / ioc->msix_vector_count;
- grouping_mod = ioc->cpu_count % ioc->msix_vector_count;
- if (grouping < 2 || (grouping == 2 && !grouping_mod))
- cpu_grouping = 2;
- else if (grouping < 4 || (grouping == 4 && !grouping_mod))
- cpu_grouping = 4;
- else if (grouping < 8 || (grouping == 8 && !grouping_mod))
- cpu_grouping = 8;
- else
- cpu_grouping = 16;
- } else
- cpu_grouping = 0;
-
- loop = 0;
- reply_q = list_entry(ioc->reply_queue_list.next,
- struct adapter_reply_queue, list);
- for_each_online_cpu(cpu_id) {
- if (!cpu_grouping) {
- ioc->cpu_msix_table[cpu_id] = reply_q->msix_index;
- reply_q = list_entry(reply_q->list.next,
- struct adapter_reply_queue, list);
- } else {
- if (loop < cpu_grouping) {
- ioc->cpu_msix_table[cpu_id] =
- reply_q->msix_index;
- loop++;
- } else {
- reply_q = list_entry(reply_q->list.next,
- struct adapter_reply_queue, list);
- ioc->cpu_msix_table[cpu_id] =
- reply_q->msix_index;
- loop = 1;
- }
+
+ nr_cpus = num_online_cpus();
+ nr_msix = ioc->reply_queue_count = min(ioc->reply_queue_count,
+ ioc->facts.MaxMSIxVectors);
+ if (!nr_msix)
+ return;
+
+ cpu = cpumask_first(cpu_online_mask);
+
+ do {
+ unsigned int i, group = nr_cpus / nr_msix;
+
+ if (index < nr_cpus % nr_msix)
+ group++;
+
+ for (i = 0 ; i < group ; i++) {
+ ioc->cpu_msix_table[cpu] = index;
+ cpu = cpumask_next(cpu, cpu_online_mask);
}
- }
+
+ index++;
+
+ } while (cpu < nr_cpus);
}
/**
@@ -4295,12 +4277,13 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
goto out_free_resources;
if (ioc->is_warpdrive) {
- ioc->reply_post_host_index[0] =
- (resource_size_t *)&ioc->chip->ReplyPostHostIndex;
+ ioc->reply_post_host_index[0] = (resource_size_t __iomem *)
+ &ioc->chip->ReplyPostHostIndex;
for (i = 1; i < ioc->cpu_msix_table_sz; i++)
- ioc->reply_post_host_index[i] = (resource_size_t *)
- ((u8 *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
+ ioc->reply_post_host_index[i] =
+ (resource_size_t __iomem *)
+ ((u8 __iomem *)&ioc->chip->Doorbell + (0x4000 + ((i - 1)
* 4)));
}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index fd3b998c75b1..0ac5815a7f91 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -837,7 +837,7 @@ struct MPT2SAS_ADAPTER {
u8 msix_enable;
u16 msix_vector_count;
u8 *cpu_msix_table;
- resource_size_t **reply_post_host_index;
+ resource_size_t __iomem **reply_post_host_index;
u16 cpu_msix_table_sz;
u32 ioc_reset_count;
MPT2SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 5055f925d2cd..dd461015813f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -173,7 +173,7 @@ struct fw_event_work {
u8 VP_ID;
u8 ignore;
u16 event;
- void *event_data;
+ char event_data[0] __aligned(4);
};
/* raid transport support */
@@ -1292,7 +1292,8 @@ _scsih_target_alloc(struct scsi_target *starget)
unsigned long flags;
struct sas_rphy *rphy;
- sas_target_priv_data = kzalloc(sizeof(struct scsi_target), GFP_KERNEL);
+ sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data),
+ GFP_KERNEL);
if (!sas_target_priv_data)
return -ENOMEM;
@@ -1406,7 +1407,8 @@ _scsih_slave_alloc(struct scsi_device *sdev)
struct _sas_device *sas_device;
unsigned long flags;
- sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
+ sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data),
+ GFP_KERNEL);
if (!sas_device_priv_data)
return -ENOMEM;
@@ -2832,7 +2834,6 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
spin_lock_irqsave(&ioc->fw_event_lock, flags);
list_del(&fw_event->list);
- kfree(fw_event->event_data);
kfree(fw_event);
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
}
@@ -2899,11 +2900,10 @@ _scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)
return;
list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
- if (cancel_delayed_work(&fw_event->delayed_work)) {
+ if (cancel_delayed_work_sync(&fw_event->delayed_work)) {
_scsih_fw_event_free(ioc, fw_event);
continue;
}
- fw_event->cancel_pending_work = 1;
}
}
@@ -3518,7 +3518,8 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
fw_event->ignore)
continue;
- local_event_data = fw_event->event_data;
+ local_event_data = (Mpi2EventDataSasTopologyChangeList_t *)
+ fw_event->event_data;
if (local_event_data->ExpStatus ==
MPI2_EVENT_SAS_TOPO_ES_ADDED ||
local_event_data->ExpStatus ==
@@ -5502,7 +5503,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
u64 sas_address;
unsigned long flags;
u8 link_rate, prev_link_rate;
- Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasTopologyChangeList_t *event_data =
+ (Mpi2EventDataSasTopologyChangeList_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -5697,7 +5700,8 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
u64 sas_address;
unsigned long flags;
Mpi2EventDataSasDeviceStatusChange_t *event_data =
- fw_event->event_data;
+ (Mpi2EventDataSasDeviceStatusChange_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -5792,6 +5796,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
_scsih_sas_enclosure_dev_status_change_event_debug(ioc,
+ (Mpi2EventDataSasEnclDevStatusChange_t *)
fw_event->event_data);
#endif
}
@@ -5816,7 +5821,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT2SAS_ADAPTER *ioc,
u32 termination_count;
u32 query_count;
Mpi2SCSITaskManagementReply_t *mpi_reply;
- Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasBroadcastPrimitive_t *event_data =
+ (Mpi2EventDataSasBroadcastPrimitive_t *)
+ fw_event->event_data;
u16 ioc_status;
unsigned long flags;
int r;
@@ -5967,7 +5974,9 @@ static void
_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
struct fw_event_work *fw_event)
{
- Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasDiscovery_t *event_data =
+ (Mpi2EventDataSasDiscovery_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
@@ -6355,7 +6364,9 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
Mpi2EventIrConfigElement_t *element;
int i;
u8 foreign_config;
- Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrConfigChangeList_t *event_data =
+ (Mpi2EventDataIrConfigChangeList_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -6423,7 +6434,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
u16 handle;
u32 state;
int rc;
- Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrVolume_t *event_data =
+ (Mpi2EventDataIrVolume_t *)
+ fw_event->event_data;
if (ioc->shost_recovery)
return;
@@ -6507,7 +6520,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
u32 ioc_status;
- Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrPhysicalDisk_t *event_data =
+ (Mpi2EventDataIrPhysicalDisk_t *)
+ fw_event->event_data;
u64 sas_address;
if (ioc->shost_recovery)
@@ -6630,7 +6645,9 @@ static void
_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
struct fw_event_work *fw_event)
{
- Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrOperationStatus_t *event_data =
+ (Mpi2EventDataIrOperationStatus_t *)
+ fw_event->event_data;
static struct _raid_device *raid_device;
unsigned long flags;
u16 handle;
@@ -7401,7 +7418,7 @@ _firmware_event_work(struct work_struct *work)
struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
/* the queue is being flushed so ignore this event */
- if (ioc->remove_host || fw_event->cancel_pending_work ||
+ if (ioc->remove_host ||
ioc->pci_error_recovery) {
_scsih_fw_event_free(ioc, fw_event);
return;
@@ -7590,23 +7607,15 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
return;
}
- fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
- if (!fw_event) {
- printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
- ioc->name, __FILE__, __LINE__, __func__);
- return;
- }
sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
- fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
- if (!fw_event->event_data) {
+ fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC);
+ if (!fw_event) {
printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
- kfree(fw_event);
return;
}
- memcpy(fw_event->event_data, mpi_reply->EventData,
- sz);
+ memcpy(fw_event->event_data, mpi_reply->EventData, sz);
fw_event->ioc = ioc;
fw_event->VF_ID = mpi_reply->VF_ID;
fw_event->VP_ID = mpi_reply->VP_ID;
@@ -7857,9 +7866,9 @@ _scsih_remove(struct pci_dev *pdev)
}
sas_remove_host(shost);
+ scsi_remove_host(shost);
mpt2sas_base_detach(ioc);
list_del(&ioc->list);
- scsi_remove_host(shost);
scsi_host_put(shost);
}
@@ -8200,13 +8209,6 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
}
- if ((scsi_add_host(shost, &pdev->dev))) {
- printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
- ioc->name, __FILE__, __LINE__, __func__);
- list_del(&ioc->list);
- goto out_add_shost_fail;
- }
-
/* register EEDP capabilities with SCSI layer */
if (prot_mask)
scsi_host_set_prot(shost, prot_mask);
@@ -8248,16 +8250,23 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
} else
ioc->hide_drives = 0;
+
+ if ((scsi_add_host(shost, &pdev->dev))) {
+ printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ goto out_add_shost_fail;
+ }
+
scsi_scan_host(shost);
return 0;
+ out_add_shost_fail:
+ mpt2sas_base_detach(ioc);
out_attach_fail:
destroy_workqueue(ioc->firmware_event_thread);
out_thread_fail:
list_del(&ioc->list);
- scsi_remove_host(shost);
- out_add_shost_fail:
scsi_host_put(shost);
return -ENODEV;
}
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 0cf4f7000f94..93ce2b2baa41 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -266,7 +266,7 @@ mpt3sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc)
ioc->fault_reset_work_q = NULL;
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
if (wq) {
- if (!cancel_delayed_work(&ioc->fault_reset_work))
+ if (!cancel_delayed_work_sync(&ioc->fault_reset_work))
flush_workqueue(wq);
destroy_workqueue(wq);
}
@@ -1624,66 +1624,35 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector)
static void
_base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
{
- struct adapter_reply_queue *reply_q;
- int cpu_id;
- int cpu_grouping, loop, grouping, grouping_mod;
- int reply_queue;
+ unsigned int cpu, nr_cpus, nr_msix, index = 0;
if (!_base_is_controller_msix_enabled(ioc))
return;
memset(ioc->cpu_msix_table, 0, ioc->cpu_msix_table_sz);
- /* NUMA Hardware bug workaround - drop to less reply queues */
- if (ioc->reply_queue_count > ioc->facts.MaxMSIxVectors) {
- ioc->reply_queue_count = ioc->facts.MaxMSIxVectors;
- reply_queue = 0;
- list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
- reply_q->msix_index = reply_queue;
- if (++reply_queue == ioc->reply_queue_count)
- reply_queue = 0;
- }
- }
+ nr_cpus = num_online_cpus();
+ nr_msix = ioc->reply_queue_count = min(ioc->reply_queue_count,
+ ioc->facts.MaxMSIxVectors);
+ if (!nr_msix)
+ return;
- /* when there are more cpus than available msix vectors,
- * then group cpus togeather on same irq
- */
- if (ioc->cpu_count > ioc->msix_vector_count) {
- grouping = ioc->cpu_count / ioc->msix_vector_count;
- grouping_mod = ioc->cpu_count % ioc->msix_vector_count;
- if (grouping < 2 || (grouping == 2 && !grouping_mod))
- cpu_grouping = 2;
- else if (grouping < 4 || (grouping == 4 && !grouping_mod))
- cpu_grouping = 4;
- else if (grouping < 8 || (grouping == 8 && !grouping_mod))
- cpu_grouping = 8;
- else
- cpu_grouping = 16;
- } else
- cpu_grouping = 0;
-
- loop = 0;
- reply_q = list_entry(ioc->reply_queue_list.next,
- struct adapter_reply_queue, list);
- for_each_online_cpu(cpu_id) {
- if (!cpu_grouping) {
- ioc->cpu_msix_table[cpu_id] = reply_q->msix_index;
- reply_q = list_entry(reply_q->list.next,
- struct adapter_reply_queue, list);
- } else {
- if (loop < cpu_grouping) {
- ioc->cpu_msix_table[cpu_id] =
- reply_q->msix_index;
- loop++;
- } else {
- reply_q = list_entry(reply_q->list.next,
- struct adapter_reply_queue, list);
- ioc->cpu_msix_table[cpu_id] =
- reply_q->msix_index;
- loop = 1;
- }
+ cpu = cpumask_first(cpu_online_mask);
+
+ do {
+ unsigned int i, group = nr_cpus / nr_msix;
+
+ if (index < nr_cpus % nr_msix)
+ group++;
+
+ for (i = 0 ; i < group ; i++) {
+ ioc->cpu_msix_table[cpu] = index;
+ cpu = cpumask_next(cpu, cpu_online_mask);
}
- }
+
+ index++;
+
+ } while (cpu < nr_cpus);
}
/**
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 18e713db1d32..7cf48c5c15a7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -112,8 +112,8 @@ MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
#define MPT3SAS_MAX_LUN (16895)
-static int max_lun = MPT3SAS_MAX_LUN;
-module_param(max_lun, int, 0);
+static u64 max_lun = MPT3SAS_MAX_LUN;
+module_param(max_lun, ullong, 0);
MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
@@ -190,7 +190,7 @@ struct fw_event_work {
u8 VP_ID;
u8 ignore;
u16 event;
- void *event_data;
+ char event_data[0] __aligned(4);
};
/* raid transport support */
@@ -1163,7 +1163,8 @@ _scsih_target_alloc(struct scsi_target *starget)
unsigned long flags;
struct sas_rphy *rphy;
- sas_target_priv_data = kzalloc(sizeof(struct scsi_target), GFP_KERNEL);
+ sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data),
+ GFP_KERNEL);
if (!sas_target_priv_data)
return -ENOMEM;
@@ -1277,7 +1278,8 @@ _scsih_slave_alloc(struct scsi_device *sdev)
struct _sas_device *sas_device;
unsigned long flags;
- sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
+ sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data),
+ GFP_KERNEL);
if (!sas_device_priv_data)
return -ENOMEM;
@@ -2490,7 +2492,6 @@ _scsih_fw_event_free(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work
spin_lock_irqsave(&ioc->fw_event_lock, flags);
list_del(&fw_event->list);
- kfree(fw_event->event_data);
kfree(fw_event);
spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
}
@@ -2511,12 +2512,10 @@ mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc,
if (ioc->is_driver_loading)
return;
- fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+ fw_event = kzalloc(sizeof(*fw_event) + sizeof(*event_data),
+ GFP_ATOMIC);
if (!fw_event)
return;
- fw_event->event_data = kzalloc(sizeof(*event_data), GFP_ATOMIC);
- if (!fw_event->event_data)
- return;
fw_event->event = MPT3SAS_PROCESS_TRIGGER_DIAG;
fw_event->ioc = ioc;
memcpy(fw_event->event_data, event_data, sizeof(*event_data));
@@ -2582,11 +2581,10 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc)
return;
list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
- if (cancel_delayed_work(&fw_event->delayed_work)) {
+ if (cancel_delayed_work_sync(&fw_event->delayed_work)) {
_scsih_fw_event_free(ioc, fw_event);
continue;
}
- fw_event->cancel_pending_work = 1;
}
}
@@ -3211,7 +3209,8 @@ _scsih_check_topo_delete_events(struct MPT3SAS_ADAPTER *ioc,
if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||
fw_event->ignore)
continue;
- local_event_data = fw_event->event_data;
+ local_event_data = (Mpi2EventDataSasTopologyChangeList_t *)
+ fw_event->event_data;
if (local_event_data->ExpStatus ==
MPI2_EVENT_SAS_TOPO_ES_ADDED ||
local_event_data->ExpStatus ==
@@ -5043,7 +5042,9 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
u64 sas_address;
unsigned long flags;
u8 link_rate, prev_link_rate;
- Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasTopologyChangeList_t *event_data =
+ (Mpi2EventDataSasTopologyChangeList_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -5241,7 +5242,8 @@ _scsih_sas_device_status_change_event(struct MPT3SAS_ADAPTER *ioc,
u64 sas_address;
unsigned long flags;
Mpi2EventDataSasDeviceStatusChange_t *event_data =
- fw_event->event_data;
+ (Mpi2EventDataSasDeviceStatusChange_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -5337,6 +5339,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc,
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
_scsih_sas_enclosure_dev_status_change_event_debug(ioc,
+ (Mpi2EventDataSasEnclDevStatusChange_t *)
fw_event->event_data);
#endif
}
@@ -5361,7 +5364,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
u32 termination_count;
u32 query_count;
Mpi2SCSITaskManagementReply_t *mpi_reply;
- Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasBroadcastPrimitive_t *event_data =
+ (Mpi2EventDataSasBroadcastPrimitive_t *)
+ fw_event->event_data;
u16 ioc_status;
unsigned long flags;
int r;
@@ -5513,7 +5518,8 @@ static void
_scsih_sas_discovery_event(struct MPT3SAS_ADAPTER *ioc,
struct fw_event_work *fw_event)
{
- Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data;
+ Mpi2EventDataSasDiscovery_t *event_data =
+ (Mpi2EventDataSasDiscovery_t *) fw_event->event_data;
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
@@ -5999,7 +6005,9 @@ _scsih_sas_ir_config_change_event(struct MPT3SAS_ADAPTER *ioc,
Mpi2EventIrConfigElement_t *element;
int i;
u8 foreign_config;
- Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrConfigChangeList_t *event_data =
+ (Mpi2EventDataIrConfigChangeList_t *)
+ fw_event->event_data;
#ifdef CONFIG_SCSI_MPT3SAS_LOGGING
if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -6069,7 +6077,8 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc,
u16 handle;
u32 state;
int rc;
- Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrVolume_t *event_data =
+ (Mpi2EventDataIrVolume_t *) fw_event->event_data;
if (ioc->shost_recovery)
return;
@@ -6152,7 +6161,8 @@ _scsih_sas_ir_physical_disk_event(struct MPT3SAS_ADAPTER *ioc,
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
u32 ioc_status;
- Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrPhysicalDisk_t *event_data =
+ (Mpi2EventDataIrPhysicalDisk_t *) fw_event->event_data;
u64 sas_address;
if (ioc->shost_recovery)
@@ -6272,7 +6282,9 @@ static void
_scsih_sas_ir_operation_status_event(struct MPT3SAS_ADAPTER *ioc,
struct fw_event_work *fw_event)
{
- Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data;
+ Mpi2EventDataIrOperationStatus_t *event_data =
+ (Mpi2EventDataIrOperationStatus_t *)
+ fw_event->event_data;
static struct _raid_device *raid_device;
unsigned long flags;
u16 handle;
@@ -7026,7 +7038,7 @@ static void
_mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
{
/* the queue is being flushed so ignore this event */
- if (ioc->remove_host || fw_event->cancel_pending_work ||
+ if (ioc->remove_host ||
ioc->pci_error_recovery) {
_scsih_fw_event_free(ioc, fw_event);
return;
@@ -7034,7 +7046,9 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event)
switch (fw_event->event) {
case MPT3SAS_PROCESS_TRIGGER_DIAG:
- mpt3sas_process_trigger_data(ioc, fw_event->event_data);
+ mpt3sas_process_trigger_data(ioc,
+ (struct SL_WH_TRIGGERS_EVENT_DATA_T *)
+ fw_event->event_data);
break;
case MPT3SAS_REMOVE_UNRESPONDING_DEVICES:
while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery)
@@ -7192,18 +7206,11 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
return 1;
}
- fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
- if (!fw_event) {
- pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
- ioc->name, __FILE__, __LINE__, __func__);
- return 1;
- }
sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
- fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
- if (!fw_event->event_data) {
+ fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC);
+ if (!fw_event) {
pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
ioc->name, __FILE__, __LINE__, __func__);
- kfree(fw_event);
return 1;
}
@@ -7431,9 +7438,9 @@ static void _scsih_remove(struct pci_dev *pdev)
}
sas_remove_host(shost);
+ scsi_remove_host(shost);
mpt3sas_base_detach(ioc);
list_del(&ioc->list);
- scsi_remove_host(shost);
scsi_host_put(shost);
}
@@ -7801,13 +7808,6 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
}
- if ((scsi_add_host(shost, &pdev->dev))) {
- pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
- ioc->name, __FILE__, __LINE__, __func__);
- list_del(&ioc->list);
- goto out_add_shost_fail;
- }
-
/* register EEDP capabilities with SCSI layer */
if (prot_mask > 0)
scsi_host_set_prot(shost, prot_mask);
@@ -7835,15 +7835,21 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->name, __FILE__, __LINE__, __func__);
goto out_attach_fail;
}
+ if ((scsi_add_host(shost, &pdev->dev))) {
+ pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n",
+ ioc->name, __FILE__, __LINE__, __func__);
+ list_del(&ioc->list);
+ goto out_add_shost_fail;
+ }
+
scsi_scan_host(shost);
return 0;
-
+out_add_shost_fail:
+ mpt3sas_base_detach(ioc);
out_attach_fail:
destroy_workqueue(ioc->firmware_event_thread);
out_thread_fail:
list_del(&ioc->list);
- scsi_remove_host(shost);
- out_add_shost_fail:
scsi_host_put(shost);
return -ENODEV;
}
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 6c1f223a8e1d..ac52f7c99513 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1344,19 +1344,23 @@ void mvs_dev_gone_notify(struct domain_device *dev)
{
unsigned long flags = 0;
struct mvs_device *mvi_dev = dev->lldd_dev;
- struct mvs_info *mvi = mvi_dev->mvi_info;
-
- spin_lock_irqsave(&mvi->lock, flags);
+ struct mvs_info *mvi;
- if (mvi_dev) {
- mv_dprintk("found dev[%d:%x] is gone.\n",
- mvi_dev->device_id, mvi_dev->dev_type);
- mvs_release_task(mvi, dev);
- mvs_free_reg_set(mvi, mvi_dev);
- mvs_free_dev(mvi_dev);
- } else {
+ if (!mvi_dev) {
mv_dprintk("found dev has gone.\n");
+ return;
}
+
+ mvi = mvi_dev->mvi_info;
+
+ spin_lock_irqsave(&mvi->lock, flags);
+
+ mv_dprintk("found dev[%d:%x] is gone.\n",
+ mvi_dev->device_id, mvi_dev->dev_type);
+ mvs_release_task(mvi, dev);
+ mvs_free_reg_set(mvi, mvi_dev);
+ mvs_free_dev(mvi_dev);
+
dev->lldd_dev = NULL;
mvi_dev->sas_device = NULL;
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 7d014b11df62..a7305ffc359d 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -6633,7 +6633,7 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
** patch requested size into sense command
*/
cp->sensecmd[0] = 0x03;
- cp->sensecmd[1] = cmd->device->lun << 5;
+ cp->sensecmd[1] = (cmd->device->lun & 0x7) << 5;
cp->sensecmd[4] = sizeof(cp->sense_buf);
/*
diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
index 0e008dacf679..02901c54b08b 100644
--- a/drivers/scsi/ncr53c8xx.h
+++ b/drivers/scsi/ncr53c8xx.h
@@ -264,11 +264,7 @@
#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER)
#define SCSI_NCR_TIMER_INTERVAL (HZ)
-#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
#define SCSI_NCR_MAX_LUN (16)
-#else
-#define SCSI_NCR_MAX_LUN (1)
-#endif
/*
* IO functions definition for big/little endian CPU support.
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 0665f9cfdb02..50b086aef178 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -915,7 +915,7 @@ static int nsp32_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct s
int ret;
nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND,
- "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x "
+ "enter. target: 0x%x LUN: 0x%llu cmnd: 0x%x cmndlen: 0x%x "
"use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x",
SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
scsi_sg_count(SCpnt), scsi_sglist(SCpnt), scsi_bufflen(SCpnt));
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index 0d78a4d5576c..80bacb5dc1d4 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -607,8 +607,6 @@ static int pas16_release(struct Scsi_Host *shost)
if (shost->irq)
free_irq(shost->irq, shost);
NCR5380_exit(shost);
- if (shost->dma_channel != 0xff)
- free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 987fbb1b244e..340ceff03823 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -195,7 +195,7 @@ static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
- "SCpnt=0x%p target=%d lun=%d sglist=0x%p bufflen=%d sg_count=%d",
+ "SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index f5b52731abd9..155f9573021f 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -558,7 +558,7 @@ SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->id,
- SCpnt->device->lun, scsi_bufflen(SCpnt)));
+ (u8)SCpnt->device->lun, scsi_bufflen(SCpnt)));
VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i]));
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index a368d77b8d41..d3a08aea0948 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -397,7 +397,10 @@ static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
payload.func_specific = kzalloc(4096, GFP_KERNEL);
if (!payload.func_specific)
return -ENOMEM;
- PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
+ if (PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload)) {
+ kfree(payload.func_specific);
+ return -ENOMEM;
+ }
wait_for_completion(&completion);
virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
for (bios_index = BIOSOFFSET; bios_index < BIOS_OFFSET_LIMIT;
@@ -614,11 +617,11 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
pm8001_ha->nvmd_completion = &completion;
ret = PM8001_CHIP_DISP->fw_flash_update_req(pm8001_ha, payload);
+ if (ret)
+ break;
wait_for_completion(&completion);
- if (ret || (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS)) {
+ if (fwControl->retcode > FLASH_UPDATE_IN_PROGRESS) {
ret = fwControl->retcode;
- kfree(ioctlbuffer);
- ioctlbuffer = NULL;
break;
}
}
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index a97be015e52e..173831016f5f 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -1346,7 +1346,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
&pMessage) < 0) {
PM8001_IO_DBG(pm8001_ha,
pm8001_printk("No free mpi buffer\n"));
- return -1;
+ return -ENOMEM;
}
BUG_ON(!payload);
/*Copy to the payload*/
@@ -1751,6 +1751,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
task_abort.tag = cpu_to_le32(ccb_tag);
ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0);
+ if (ret)
+ pm8001_tag_free(pm8001_ha, ccb_tag);
}
@@ -1778,6 +1780,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
if (res) {
+ sas_free_task(task);
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("cannot allocate tag !!!\n"));
return;
@@ -1788,14 +1791,14 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
*/
dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
if (!dev) {
+ sas_free_task(task);
+ pm8001_tag_free(pm8001_ha, ccb_tag);
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Domain device cannot be allocated\n"));
- sas_free_task(task);
return;
- } else {
- task->dev = dev;
- task->dev->lldd_dev = pm8001_ha_dev;
}
+ task->dev = dev;
+ task->dev->lldd_dev = pm8001_ha_dev;
ccb = &pm8001_ha->ccb_info[ccb_tag];
ccb->device = pm8001_ha_dev;
@@ -1821,7 +1824,11 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0);
-
+ if (res) {
+ sas_free_task(task);
+ pm8001_tag_free(pm8001_ha, ccb_tag);
+ kfree(dev);
+ }
}
/**
@@ -3100,7 +3107,7 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha,
complete(pm8001_dev->setds_completion);
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
- pm8001_ccb_free(pm8001_ha, tag);
+ pm8001_tag_free(pm8001_ha, tag);
}
void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -3119,13 +3126,12 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
}
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
- pm8001_ccb_free(pm8001_ha, tag);
+ pm8001_tag_free(pm8001_ha, tag);
}
void
pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
- struct fw_control_ex *fw_control_context;
struct get_nvm_data_resp *pPayload =
(struct get_nvm_data_resp *)(piomb + 4);
u32 tag = le32_to_cpu(pPayload->tag);
@@ -3134,7 +3140,6 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
u32 ir_tds_bn_dps_das_nvm =
le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm);
void *virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
- fw_control_context = ccb->fw_control_context;
PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Get nvm data complete!\n"));
if ((dlen_status & NVMD_STAT) != 0) {
@@ -3175,13 +3180,11 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
pm8001_printk("Get NVMD success, IR=0, dataLen=%d\n",
(dlen_status & NVMD_LEN) >> 24));
}
- memcpy(fw_control_context->usrAddr,
- pm8001_ha->memoryMap.region[NVMD].virt_ptr,
- fw_control_context->len);
- complete(pm8001_ha->nvmd_completion);
+ kfree(ccb->fw_control_context);
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
- pm8001_ccb_free(pm8001_ha, tag);
+ pm8001_tag_free(pm8001_ha, tag);
+ complete(pm8001_ha->nvmd_completion);
}
int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -3588,7 +3591,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
complete(pm8001_dev->dcompletion);
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
- pm8001_ccb_free(pm8001_ha, htag);
+ pm8001_tag_free(pm8001_ha, htag);
return 0;
}
@@ -3617,15 +3620,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
u32 status;
- struct fw_control_ex fw_control_context;
struct fw_flash_Update_resp *ppayload =
(struct fw_flash_Update_resp *)(piomb + 4);
u32 tag = le32_to_cpu(ppayload->tag);
struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
status = le32_to_cpu(ppayload->status);
- memcpy(&fw_control_context,
- ccb->fw_control_context,
- sizeof(fw_control_context));
switch (status) {
case FLASH_UPDATE_COMPLETE_PENDING_REBOOT:
PM8001_MSG_DBG(pm8001_ha,
@@ -3668,11 +3667,11 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
pm8001_printk("No matched status = %d\n", status));
break;
}
- ccb->fw_control_context->fw_control->retcode = status;
- complete(pm8001_ha->nvmd_completion);
+ kfree(ccb->fw_control_context);
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
- pm8001_ccb_free(pm8001_ha, tag);
+ pm8001_tag_free(pm8001_ha, tag);
+ complete(pm8001_ha->nvmd_completion);
return 0;
}
@@ -4257,7 +4256,11 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
smp_cmd.long_smp_req.long_resp_size =
cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4);
build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd);
- pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0);
+ rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
+ (u32 *)&smp_cmd, 0);
+ if (rc)
+ goto err_out_2;
+
return 0;
err_out_2:
@@ -4398,7 +4401,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha,
/* Check for read log for failed drive and return */
if (sata_cmd.sata_fis.command == 0x2f) {
- if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) ||
+ if (((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) ||
(pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) ||
(pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) {
struct task_status_struct *ts;
@@ -4789,6 +4792,10 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
break;
}
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0);
+ if (rc) {
+ kfree(fw_control_context);
+ pm8001_tag_free(pm8001_ha, tag);
+ }
return rc;
}
@@ -4869,6 +4876,10 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
break;
}
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0);
+ if (rc) {
+ kfree(fw_control_context);
+ pm8001_tag_free(pm8001_ha, tag);
+ }
return rc;
}
@@ -5061,7 +5072,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
memset(&payload, 0, sizeof(payload));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
if (rc)
- return -1;
+ return -ENOMEM;
ccb = &pm8001_ha->ccb_info[tag];
ccb->ccb_tag = tag;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
@@ -5070,6 +5081,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
payload.sata_hol_tmo = cpu_to_le32(80);
payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff);
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
return rc;
}
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index c4f31b21feb8..e49623a897a7 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -246,6 +246,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
{
int i;
spin_lock_init(&pm8001_ha->lock);
+ spin_lock_init(&pm8001_ha->bitmap_lock);
PM8001_INIT_DBG(pm8001_ha,
pm8001_printk("pm8001_alloc: PHY:%x\n",
pm8001_ha->chip->n_phy));
@@ -621,6 +622,8 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;
u16 deviceid;
+ int rc;
+
pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
pm8001_ha->nvmd_completion = &completion;
@@ -638,7 +641,16 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
}
payload.offset = 0;
payload.func_specific = kzalloc(payload.length, GFP_KERNEL);
- PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
+ if (!payload.func_specific) {
+ PM8001_INIT_DBG(pm8001_ha, pm8001_printk("mem alloc fail\n"));
+ return;
+ }
+ rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
+ if (rc) {
+ kfree(payload.func_specific);
+ PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n"));
+ return;
+ }
wait_for_completion(&completion);
for (i = 0, j = 0; i <= 7; i++, j++) {
@@ -661,6 +673,7 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
pm8001_printk("phy %d sas_addr = %016llx\n", i,
pm8001_ha->phy[i].dev_sas_addr));
}
+ kfree(payload.func_specific);
#else
for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL;
@@ -677,13 +690,14 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
* pm8001_get_phy_settings_info : Read phy setting values.
* @pm8001_ha : our hba.
*/
-void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
+static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
{
#ifdef PM8001_READ_VPD
/*OPTION ROM FLASH read for the SPC cards */
DECLARE_COMPLETION_ONSTACK(completion);
struct pm8001_ioctl_payload payload;
+ int rc;
pm8001_ha->nvmd_completion = &completion;
/* SAS ADDRESS read from flash / EEPROM */
@@ -691,11 +705,20 @@ void pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
payload.offset = 0;
payload.length = 4096;
payload.func_specific = kzalloc(4096, GFP_KERNEL);
+ if (!payload.func_specific)
+ return -ENOMEM;
/* Read phy setting values from flash */
- PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
+ rc = PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
+ if (rc) {
+ kfree(payload.func_specific);
+ PM8001_INIT_DBG(pm8001_ha, pm8001_printk("nvmd failed\n"));
+ return -ENOMEM;
+ }
wait_for_completion(&completion);
pm8001_set_phy_profile(pm8001_ha, sizeof(u8), payload.func_specific);
+ kfree(payload.func_specific);
#endif
+ return 0;
}
#ifdef PM8001_USE_MSIX
@@ -740,9 +763,10 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
pm8001_ha->irq_vector[i].irq_id = i;
pm8001_ha->irq_vector[i].drv_inst = pm8001_ha;
- if (request_irq(pm8001_ha->msix_entries[i].vector,
+ rc = request_irq(pm8001_ha->msix_entries[i].vector,
pm8001_interrupt_handler_msix, flag,
- intr_drvname[i], &(pm8001_ha->irq_vector[i]))) {
+ intr_drvname[i], &(pm8001_ha->irq_vector[i]));
+ if (rc) {
for (j = 0; j < i; j++)
free_irq(
pm8001_ha->msix_entries[j].vector,
@@ -879,8 +903,11 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
pm8001_init_sas_add(pm8001_ha);
/* phy setting support for motherboard controller */
if (pdev->subsystem_vendor != PCI_VENDOR_ID_ADAPTEC2 &&
- pdev->subsystem_vendor != 0)
- pm8001_get_phy_settings_info(pm8001_ha);
+ pdev->subsystem_vendor != 0) {
+ rc = pm8001_get_phy_settings_info(pm8001_ha);
+ if (rc)
+ goto err_out_shost;
+ }
pm8001_post_sas_ha_init(shost, chip);
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
if (rc)
@@ -957,6 +984,7 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)
int i, j;
u32 device_state;
pm8001_ha = sha->lldd_ha;
+ sas_suspend_ha(sha);
flush_workqueue(pm8001_wq);
scsi_block_requests(pm8001_ha->shost);
if (!pdev->pm_cap) {
@@ -1006,6 +1034,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
int rc;
u8 i = 0, j;
u32 device_state;
+ DECLARE_COMPLETION_ONSTACK(completion);
pm8001_ha = sha->lldd_ha;
device_state = pdev->current_state;
@@ -1026,7 +1055,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
rc = pci_go_44(pdev);
if (rc)
goto err_out_disable;
-
+ sas_prep_resume_ha(sha);
/* chip soft rst only for spc */
if (pm8001_ha->chip_id == chip_8001) {
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
@@ -1058,7 +1087,13 @@ static int pm8001_pci_resume(struct pci_dev *pdev)
for (i = 1; i < pm8001_ha->number_of_intr; i++)
PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i);
}
- scsi_unblock_requests(pm8001_ha->shost);
+ pm8001_ha->flags = PM8001F_RUN_TIME;
+ for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+ pm8001_ha->phy[i].enable_completion = &completion;
+ PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i);
+ wait_for_completion(&completion);
+ }
+ sas_resume_ha(sha);
return 0;
err_out_disable:
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 8a44bc92bc78..34cea8291772 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -58,25 +58,14 @@ static int pm8001_find_tag(struct sas_task *task, u32 *tag)
}
/**
- * pm8001_tag_clear - clear the tags bitmap
+ * pm8001_tag_free - free the no more needed tag
* @pm8001_ha: our hba struct
* @tag: the found tag associated with the task
*/
-static void pm8001_tag_clear(struct pm8001_hba_info *pm8001_ha, u32 tag)
-{
- void *bitmap = pm8001_ha->tags;
- clear_bit(tag, bitmap);
-}
-
void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag)
{
- pm8001_tag_clear(pm8001_ha, tag);
-}
-
-static void pm8001_tag_set(struct pm8001_hba_info *pm8001_ha, u32 tag)
-{
void *bitmap = pm8001_ha->tags;
- set_bit(tag, bitmap);
+ clear_bit(tag, bitmap);
}
/**
@@ -86,14 +75,18 @@ static void pm8001_tag_set(struct pm8001_hba_info *pm8001_ha, u32 tag)
*/
inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out)
{
- unsigned int index, tag;
+ unsigned int tag;
void *bitmap = pm8001_ha->tags;
+ unsigned long flags;
- index = find_first_zero_bit(bitmap, pm8001_ha->tags_num);
- tag = index;
- if (tag >= pm8001_ha->tags_num)
+ spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags);
+ tag = find_first_zero_bit(bitmap, pm8001_ha->tags_num);
+ if (tag >= pm8001_ha->tags_num) {
+ spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
return -SAS_QUEUE_FULL;
- pm8001_tag_set(pm8001_ha, tag);
+ }
+ set_bit(tag, bitmap);
+ spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags);
*tag_out = tag;
return 0;
}
@@ -102,7 +95,7 @@ void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha)
{
int i;
for (i = 0; i < pm8001_ha->tags_num; ++i)
- pm8001_tag_clear(pm8001_ha, i);
+ pm8001_tag_free(pm8001_ha, i);
}
/**
@@ -501,11 +494,6 @@ int pm8001_queue_command(struct sas_task *task, const int num,
return pm8001_task_exec(task, num, gfp_flags, 0, NULL);
}
-void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha, u32 ccb_idx)
-{
- pm8001_tag_clear(pm8001_ha, ccb_idx);
-}
-
/**
* pm8001_ccb_task_free - free the sg for ssp and smp command, free the ccb.
* @pm8001_ha: our hba card information
@@ -542,7 +530,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
ccb->open_retry = 0;
- pm8001_ccb_free(pm8001_ha, ccb_idx);
+ pm8001_tag_free(pm8001_ha, ccb_idx);
}
/**
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 1ee06f21803b..f6b2ac59dae4 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -475,6 +475,7 @@ struct pm8001_hba_info {
struct list_head list;
unsigned long flags;
spinlock_t lock;/* host-wide lock */
+ spinlock_t bitmap_lock;
struct pci_dev *pdev;/* our device */
struct device *dev;
struct pm8001_hba_memspace io_mem[6];
@@ -616,7 +617,6 @@ extern struct workqueue_struct *pm8001_wq;
int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out);
void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha);
u32 pm8001_get_ncq_tag(struct sas_task *task, u32 *tag);
-void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha, u32 ccb_idx);
void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
struct sas_task *task, struct pm8001_ccb_info *ccb, u32 ccb_idx);
int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index d70587f96184..b06443a0db2d 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -856,6 +856,8 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)
payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8);
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
return rc;
}
@@ -936,6 +938,8 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)
sizeof(SASProtocolTimerConfig_t));
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
return rc;
}
@@ -948,7 +952,7 @@ static int
pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
{
u32 scratch3_value;
- int ret;
+ int ret = -1;
/* Read encryption status from SCRATCH PAD 3 */
scratch3_value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
@@ -982,7 +986,7 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
pm8001_ha->encrypt_info.status = 0xFFFFFFFF;
pm8001_ha->encrypt_info.cipher_mode = 0;
pm8001_ha->encrypt_info.sec_mode = 0;
- return 0;
+ ret = 0;
} else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
SCRATCH_PAD3_ENC_DIS_ERR) {
pm8001_ha->encrypt_info.status =
@@ -1004,7 +1008,6 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
scratch3_value, pm8001_ha->encrypt_info.cipher_mode,
pm8001_ha->encrypt_info.sec_mode,
pm8001_ha->encrypt_info.status));
- ret = -1;
} else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) ==
SCRATCH_PAD3_ENC_ENA_ERR) {
@@ -1028,7 +1031,6 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
scratch3_value, pm8001_ha->encrypt_info.cipher_mode,
pm8001_ha->encrypt_info.sec_mode,
pm8001_ha->encrypt_info.status));
- ret = -1;
}
return ret;
}
@@ -1059,6 +1061,8 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
KEK_MGMT_SUBOP_KEYCARDUPDATE);
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
return rc;
}
@@ -1383,8 +1387,10 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
task->task_done = pm8001_task_done;
res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
- if (res)
+ if (res) {
+ sas_free_task(task);
return;
+ }
ccb = &pm8001_ha->ccb_info[ccb_tag];
ccb->device = pm8001_ha_dev;
@@ -1399,7 +1405,10 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
task_abort.tag = cpu_to_le32(ccb_tag);
ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0);
-
+ if (ret) {
+ sas_free_task(task);
+ pm8001_tag_free(pm8001_ha, ccb_tag);
+ }
}
static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
@@ -1426,6 +1435,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
if (res) {
+ sas_free_task(task);
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("cannot allocate tag !!!\n"));
return;
@@ -1436,15 +1446,16 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
*/
dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
if (!dev) {
+ sas_free_task(task);
+ pm8001_tag_free(pm8001_ha, ccb_tag);
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Domain device cannot be allocated\n"));
- sas_free_task(task);
return;
- } else {
- task->dev = dev;
- task->dev->lldd_dev = pm8001_ha_dev;
}
+ task->dev = dev;
+ task->dev->lldd_dev = pm8001_ha_dev;
+
ccb = &pm8001_ha->ccb_info[ccb_tag];
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
@@ -1469,7 +1480,11 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0);
-
+ if (res) {
+ sas_free_task(task);
+ pm8001_tag_free(pm8001_ha, ccb_tag);
+ kfree(dev);
+ }
}
/**
@@ -3815,7 +3830,10 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag,
&smp_cmd, pm8001_ha->smp_exp_mode, length);
- pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0);
+ rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc,
+ (u32 *)&smp_cmd, 0);
+ if (rc)
+ goto err_out_2;
return 0;
err_out_2:
@@ -4406,6 +4424,8 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
SAS_ADDR_SIZE);
rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
return rc;
}
@@ -4484,7 +4504,9 @@ void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
payload.reserved[j] = cpu_to_le32(*((u32 *)buf + i));
j++;
}
- pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
+ if (rc)
+ pm8001_tag_free(pm8001_ha, tag);
}
void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index be8ce54f99b2..017f8b9554e5 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -237,7 +237,7 @@ static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
scsi_dev->host->unique_id,
scsi_dev->channel,
scsi_dev->id,
- scsi_dev->lun);
+ (u8)scsi_dev->lun);
if (RES_IS_GSCSI(res->cfg_entry)) {
scsi_dev->allow_restart = 1;
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index e6e2a30493e6..ef23fabe3924 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -78,7 +78,7 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
struct ps3rom_private *priv = shost_priv(scsi_dev->host);
struct ps3_storage_device *dev = priv->dev;
- dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %u, channel %u\n", __func__,
+ dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %llu, channel %u\n", __func__,
__LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel);
/*
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index de5d0ae19d83..b64399153135 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -320,8 +320,8 @@ struct srb_iocb {
* defined in tsk_mgmt_entry struct
* for control_flags field in qla_fw.h.
*/
+ uint64_t lun;
uint32_t flags;
- uint32_t lun;
uint32_t data;
struct completion comp;
__le16 comp_status;
@@ -2529,8 +2529,8 @@ struct isp_operations {
void (*disable_intrs) (struct qla_hw_data *);
int (*abort_command) (srb_t *);
- int (*target_reset) (struct fc_port *, unsigned int, int);
- int (*lun_reset) (struct fc_port *, unsigned int, int);
+ int (*target_reset) (struct fc_port *, uint64_t, int);
+ int (*lun_reset) (struct fc_port *, uint64_t, int);
int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
uint8_t, uint8_t, uint16_t *, uint8_t);
int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index d48dea8fab1b..d646540db3ac 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -113,7 +113,7 @@ extern int ql2xenabledif;
extern int ql2xenablehba_err_chk;
extern int ql2xtargetreset;
extern int ql2xdontresethba;
-extern unsigned int ql2xmaxlun;
+extern uint64_t ql2xmaxlun;
extern int ql2xmdcapmask;
extern int ql2xmdenable;
@@ -212,7 +212,7 @@ extern void qla2x00_build_scsi_iocbs_64(srb_t *, cmd_entry_t *, uint16_t);
extern int qla2x00_start_scsi(srb_t *sp);
extern int qla24xx_start_scsi(srb_t *sp);
int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
- uint16_t, uint16_t, uint8_t);
+ uint16_t, uint64_t, uint8_t);
extern int qla2x00_start_sp(srb_t *);
extern int qla24xx_dif_start_scsi(srb_t *);
extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t);
@@ -262,10 +262,10 @@ extern int
qla2x00_abort_command(srb_t *);
extern int
-qla2x00_abort_target(struct fc_port *, unsigned int, int);
+qla2x00_abort_target(struct fc_port *, uint64_t, int);
extern int
-qla2x00_lun_reset(struct fc_port *, unsigned int, int);
+qla2x00_lun_reset(struct fc_port *, uint64_t, int);
extern int
qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
@@ -339,12 +339,12 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
extern int qla24xx_abort_command(srb_t *);
extern int qla24xx_async_abort_command(srb_t *);
extern int
-qla24xx_abort_target(struct fc_port *, unsigned int, int);
+qla24xx_abort_target(struct fc_port *, uint64_t, int);
extern int
-qla24xx_lun_reset(struct fc_port *, unsigned int, int);
+qla24xx_lun_reset(struct fc_port *, uint64_t, int);
extern int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *, unsigned int,
- unsigned int, enum nexus_wait_type);
+ uint64_t, enum nexus_wait_type);
extern int
qla2x00_system_error(scsi_qla_host_t *);
@@ -617,8 +617,8 @@ extern char *qlafx00_fw_version_str(struct scsi_qla_host *, char *);
extern irqreturn_t qlafx00_intr_handler(int, void *);
extern void qlafx00_enable_intrs(struct qla_hw_data *);
extern void qlafx00_disable_intrs(struct qla_hw_data *);
-extern int qlafx00_abort_target(fc_port_t *, unsigned int, int);
-extern int qlafx00_lun_reset(fc_port_t *, unsigned int, int);
+extern int qlafx00_abort_target(fc_port_t *, uint64_t, int);
+extern int qlafx00_lun_reset(fc_port_t *, uint64_t, int);
extern int qlafx00_start_scsi(srb_t *);
extern int qlafx00_abort_isp(scsi_qla_host_t *);
extern int qlafx00_iospace_config(struct qla_hw_data *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index e2184412617d..46990f4ceb40 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1526,8 +1526,8 @@ try_fce:
FCE_SIZE, ha->fce, ha->fce_dma);
/* Allocate memory for Fibre Channel Event Buffer. */
- tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
- GFP_KERNEL);
+ tc = dma_zalloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
+ GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00be,
"Unable to allocate (%d KB) for FCE.\n",
@@ -1535,7 +1535,6 @@ try_fce:
goto try_eft;
}
- memset(tc, 0, FCE_SIZE);
rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
ha->fce_mb, &ha->fce_bufs);
if (rval) {
@@ -1560,8 +1559,8 @@ try_eft:
EFT_SIZE, ha->eft, ha->eft_dma);
/* Allocate memory for Extended Trace Buffer. */
- tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
- GFP_KERNEL);
+ tc = dma_zalloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
+ GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
@@ -1569,7 +1568,6 @@ try_eft:
goto cont_alloc;
}
- memset(tc, 0, EFT_SIZE);
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
if (rval) {
ql_log(ql_log_warn, vha, 0x00c2,
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 760931529592..150529d98db4 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -520,7 +520,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
static int
__qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
struct rsp_que *rsp, uint16_t loop_id,
- uint16_t lun, uint8_t type)
+ uint64_t lun, uint8_t type)
{
mrk_entry_t *mrk;
struct mrk_entry_24xx *mrk24 = NULL;
@@ -543,14 +543,13 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
if (IS_FWI2_CAPABLE(ha)) {
mrk24 = (struct mrk_entry_24xx *) mrk;
mrk24->nport_handle = cpu_to_le16(loop_id);
- mrk24->lun[1] = LSB(lun);
- mrk24->lun[2] = MSB(lun);
+ int_to_scsilun(lun, (struct scsi_lun *)&mrk24->lun);
host_to_fcp_swap(mrk24->lun, sizeof(mrk24->lun));
mrk24->vp_index = vha->vp_idx;
mrk24->handle = MAKE_HANDLE(req->id, mrk24->handle);
} else {
SET_TARGET_ID(ha, mrk->target, loop_id);
- mrk->lun = cpu_to_le16(lun);
+ mrk->lun = cpu_to_le16((uint16_t)lun);
}
}
wmb();
@@ -562,7 +561,7 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
int
qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
- struct rsp_que *rsp, uint16_t loop_id, uint16_t lun,
+ struct rsp_que *rsp, uint16_t loop_id, uint64_t lun,
uint8_t type)
{
int ret;
@@ -2047,7 +2046,7 @@ static void
qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
{
uint32_t flags;
- unsigned int lun;
+ uint64_t lun;
struct fc_port *fcport = sp->fcport;
scsi_qla_host_t *vha = fcport->vha;
struct qla_hw_data *ha = vha->hw;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a56825c73c31..550a4a31f51a 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1659,7 +1659,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
if (sense_len) {
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c,
- "Check condition Sense data, nexus%ld:%d:%d cmd=%p.\n",
+ "Check condition Sense data, nexus%ld:%d:%llu cmd=%p.\n",
sp->fcport->vha->host_no, cp->device->id, cp->device->lun,
cp);
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302b,
@@ -2281,7 +2281,7 @@ check_scsi_status:
out:
if (logit)
ql_dbg(ql_dbg_io, fcport->vha, 0x3022,
- "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%d "
+ "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu "
"portid=%02x%02x%02x oxid=0x%x cdb=%10phN len=0x%x "
"rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n",
comp_status, scsi_status, res, vha->host_no,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 1c33a77db5c2..d9aafc003be2 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -947,7 +947,7 @@ qla2x00_abort_command(srb_t *sp)
}
int
-qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
+qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
{
int rval, rval2;
mbx_cmd_t mc;
@@ -1000,7 +1000,7 @@ qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
}
int
-qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
+qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
{
int rval, rval2;
mbx_cmd_t mc;
@@ -1022,7 +1022,7 @@ qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
mcp->mb[1] = fcport->loop_id;
else
mcp->mb[1] = fcport->loop_id << 8;
- mcp->mb[2] = l;
+ mcp->mb[2] = (u32)l;
mcp->mb[3] = 0;
mcp->mb[9] = vha->vp_idx;
@@ -2666,7 +2666,7 @@ struct tsk_mgmt_cmd {
static int
__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
- unsigned int l, int tag)
+ uint64_t l, int tag)
{
int rval, rval2;
struct tsk_mgmt_cmd *tsk;
@@ -2760,7 +2760,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
}
int
-qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
+qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
{
struct qla_hw_data *ha = fcport->vha->hw;
@@ -2771,7 +2771,7 @@ qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
}
int
-qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
+qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
{
struct qla_hw_data *ha = fcport->vha->hw;
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c
index abeb3901498b..4775baa8b6a0 100644
--- a/drivers/scsi/qla2xxx/qla_mr.c
+++ b/drivers/scsi/qla2xxx/qla_mr.c
@@ -726,13 +726,13 @@ qlafx00_disable_intrs(struct qla_hw_data *ha)
}
int
-qlafx00_abort_target(fc_port_t *fcport, unsigned int l, int tag)
+qlafx00_abort_target(fc_port_t *fcport, uint64_t l, int tag)
{
return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
}
int
-qlafx00_lun_reset(fc_port_t *fcport, unsigned int l, int tag)
+qlafx00_lun_reset(fc_port_t *fcport, uint64_t l, int tag)
{
return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
}
@@ -2159,7 +2159,7 @@ qlafx00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
if (sense_len) {
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3039,
- "Check condition Sense data, nexus%ld:%d:%d cmd=%p.\n",
+ "Check condition Sense data, nexus%ld:%d:%llu cmd=%p.\n",
sp->fcport->vha->host_no, cp->device->id, cp->device->lun,
cp);
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x3049,
@@ -2524,7 +2524,7 @@ check_scsi_status:
if (logit)
ql_dbg(ql_dbg_io, fcport->vha, 0x3058,
- "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%d "
+ "FCP command status: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu "
"tgt_id: 0x%x lscsi_status: 0x%x cdb=%10phN len=0x%x "
"rsp_info=0x%x resid=0x%x fw_resid=0x%x sense_len=0x%x, "
"par_sense_len=0x%x, rsp_info_len=0x%x\n",
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d96bfb55e57b..be9698d920c2 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -202,8 +202,8 @@ MODULE_PARM_DESC(ql2xdontresethba,
" 0 (Default) -- Reset on failure.\n"
" 1 -- Do not reset on failure.\n");
-uint ql2xmaxlun = MAX_LUNS;
-module_param(ql2xmaxlun, uint, S_IRUGO);
+uint64_t ql2xmaxlun = MAX_LUNS;
+module_param(ql2xmaxlun, ullong, S_IRUGO);
MODULE_PARM_DESC(ql2xmaxlun,
"Defines the maximum LU number to register with the SCSI "
"midlayer. Default is 65535.");
@@ -920,7 +920,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
srb_t *sp;
int ret;
- unsigned int id, lun;
+ unsigned int id;
+ uint64_t lun;
unsigned long flags;
int rval, wait = 0;
struct qla_hw_data *ha = vha->hw;
@@ -944,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
}
ql_dbg(ql_dbg_taskm, vha, 0x8002,
- "Aborting from RISC nexus=%ld:%d:%d sp=%p cmd=%p\n",
+ "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p\n",
vha->host_no, id, lun, sp, cmd);
/* Get a reference to the sp and drop the lock.*/
@@ -995,7 +996,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
}
ql_log(ql_log_info, vha, 0x801c,
- "Abort command issued nexus=%ld:%d:%d -- %d %x.\n",
+ "Abort command issued nexus=%ld:%d:%llu -- %d %x.\n",
vha->host_no, id, lun, wait, ret);
return ret;
@@ -1003,7 +1004,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
- unsigned int l, enum nexus_wait_type type)
+ uint64_t l, enum nexus_wait_type type)
{
int cnt, match, status;
unsigned long flags;
@@ -1060,7 +1061,7 @@ static char *reset_errors[] = {
static int
__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
- struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int, int))
+ struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, uint64_t, int))
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -1075,7 +1076,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
return err;
ql_log(ql_log_info, vha, 0x8009,
- "%s RESET ISSUED nexus=%ld:%d:%d cmd=%p.\n", name, vha->host_no,
+ "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no,
cmd->device->id, cmd->device->lun, cmd);
err = 0;
@@ -1100,14 +1101,14 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
}
ql_log(ql_log_info, vha, 0x800e,
- "%s RESET SUCCEEDED nexus:%ld:%d:%d cmd=%p.\n", name,
+ "%s RESET SUCCEEDED nexus:%ld:%d:%llu cmd=%p.\n", name,
vha->host_no, cmd->device->id, cmd->device->lun, cmd);
return SUCCESS;
eh_reset_failed:
ql_log(ql_log_info, vha, 0x800f,
- "%s RESET FAILED: %s nexus=%ld:%d:%d cmd=%p.\n", name,
+ "%s RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.\n", name,
reset_errors[err], vha->host_no, cmd->device->id, cmd->device->lun,
cmd);
return FAILED;
@@ -1154,7 +1155,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
int ret = FAILED;
- unsigned int id, lun;
+ unsigned int id;
+ uint64_t lun;
id = cmd->device->id;
lun = cmd->device->lun;
@@ -1169,7 +1171,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
ret = FAILED;
ql_log(ql_log_info, vha, 0x8012,
- "BUS RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
+ "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
ql_log(ql_log_fatal, vha, 0x8013,
@@ -1193,7 +1195,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
eh_bus_reset_done:
ql_log(ql_log_warn, vha, 0x802b,
- "BUS RESET %s nexus=%ld:%d:%d.\n",
+ "BUS RESET %s nexus=%ld:%d:%llu.\n",
(ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
return ret;
@@ -1220,14 +1222,15 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
struct qla_hw_data *ha = vha->hw;
int ret = FAILED;
- unsigned int id, lun;
+ unsigned int id;
+ uint64_t lun;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
id = cmd->device->id;
lun = cmd->device->lun;
ql_log(ql_log_info, vha, 0x8018,
- "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
+ "ADAPTER RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
/*
* No point in issuing another reset if one is active. Also do not
@@ -1273,7 +1276,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
eh_host_reset_lock:
ql_log(ql_log_info, vha, 0x8017,
- "ADAPTER RESET %s nexus=%ld:%d:%d.\n",
+ "ADAPTER RESET %s nexus=%ld:%d:%llu.\n",
(ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
return ret;
@@ -1409,7 +1412,7 @@ static void qla2x00_handle_queue_full(struct scsi_device *sdev, int qdepth)
return;
ql_dbg(ql_dbg_io, fcport->vha, 0x3029,
- "Queue depth adjusted-down to %d for nexus=%ld:%d:%d.\n",
+ "Queue depth adjusted-down to %d for nexus=%ld:%d:%llu.\n",
sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
}
@@ -1432,7 +1435,7 @@ static void qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, int qdepth)
scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, qdepth);
ql_dbg(ql_dbg_io, vha, 0x302a,
- "Queue depth adjusted-up to %d for nexus=%ld:%d:%d.\n",
+ "Queue depth adjusted-up to %d for nexus=%ld:%d:%llu.\n",
sdev->queue_depth, fcport->vha->host_no, sdev->id, sdev->lun);
}
@@ -2661,14 +2664,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
else
host->max_cmd_len = MAX_CMDSZ;
host->max_channel = MAX_BUSES - 1;
- host->max_lun = ql2xmaxlun;
+ /* Older HBAs support only 16-bit LUNs */
+ if (!IS_QLAFX00(ha) && !IS_FWI2_CAPABLE(ha) &&
+ ql2xmaxlun > 0xffff)
+ host->max_lun = 0xffff;
+ else
+ host->max_lun = ql2xmaxlun;
host->transportt = qla2xxx_transport_template;
sht->vendor_id = (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC);
ql_dbg(ql_dbg_init, base_vha, 0x0033,
"max_id=%d this_id=%d "
"cmd_per_len=%d unique_id=%d max_cmd_len=%d max_channel=%d "
- "max_lun=%d transportt=%p, vendor_id=%llu.\n", host->max_id,
+ "max_lun=%llu transportt=%p, vendor_id=%llu.\n", host->max_id,
host->this_id, host->cmd_per_lun, host->unique_id,
host->max_cmd_len, host->max_channel, host->max_lun,
host->transportt, sht->vendor_id);
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 4b188b0164e9..e632e14180cf 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1128,7 +1128,7 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
ctio->u.status1.flags =
__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
CTIO7_FLAGS_TERMINATE);
- ctio->u.status1.ox_id = entry->fcp_hdr_le.ox_id;
+ ctio->u.status1.ox_id = cpu_to_le16(entry->fcp_hdr_le.ox_id);
qla2x00_start_iocbs(vha, vha->req);
@@ -1262,6 +1262,7 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
{
struct atio_from_isp *atio = &mcmd->orig_iocb.atio;
struct ctio7_to_24xx *ctio;
+ uint16_t temp;
ql_dbg(ql_dbg_tgt, ha, 0xe008,
"Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n",
@@ -1292,7 +1293,8 @@ static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha,
ctio->u.status1.flags = (atio->u.isp24.attr << 9) |
__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
CTIO7_FLAGS_SEND_STATUS);
- ctio->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
+ temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
+ ctio->u.status1.ox_id = cpu_to_le16(temp);
ctio->u.status1.scsi_status =
__constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID);
ctio->u.status1.response_len = __constant_cpu_to_le16(8);
@@ -1513,6 +1515,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
struct ctio7_to_24xx *pkt;
struct qla_hw_data *ha = vha->hw;
struct atio_from_isp *atio = &prm->cmd->atio;
+ uint16_t temp;
pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr;
prm->pkt = pkt;
@@ -1541,13 +1544,13 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm,
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
pkt->exchange_addr = atio->u.isp24.exchange_addr;
pkt->u.status0.flags |= (atio->u.isp24.attr << 9);
- pkt->u.status0.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
+ temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
+ pkt->u.status0.ox_id = cpu_to_le16(temp);
pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset);
ql_dbg(ql_dbg_tgt, vha, 0xe00c,
"qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n",
- vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT,
- le16_to_cpu(pkt->u.status0.ox_id));
+ vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, temp);
return 0;
}
@@ -2619,6 +2622,7 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw;
request_t *pkt;
int ret = 0;
+ uint16_t temp;
ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha);
@@ -2655,7 +2659,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
ctio24->u.status1.flags = (atio->u.isp24.attr << 9) |
__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 |
CTIO7_FLAGS_TERMINATE);
- ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
+ temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id);
+ ctio24->u.status1.ox_id = cpu_to_le16(temp);
/* Most likely, it isn't needed */
ctio24->u.status1.residual = get_unaligned((uint32_t *)
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index e0a58fd13f66..d1d24fb0160a 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -443,7 +443,7 @@ struct ctio7_to_24xx {
uint16_t reserved1;
__le16 flags;
uint32_t residual;
- uint16_t ox_id;
+ __le16 ox_id;
uint16_t scsi_status;
uint32_t relative_offset;
uint32_t reserved2;
@@ -458,7 +458,7 @@ struct ctio7_to_24xx {
uint16_t sense_length;
uint16_t flags;
uint32_t residual;
- uint16_t ox_id;
+ __le16 ox_id;
uint16_t scsi_status;
uint16_t response_len;
uint16_t reserved;
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 5f58b451327e..2559144f5475 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -23,7 +23,7 @@ void qla4xxx_process_aen(struct scsi_qla_host *ha, uint8_t process_aen);
int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host *ha);
int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb);
int qla4xxx_reset_lun(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry,
- int lun);
+ uint64_t lun);
int qla4xxx_reset_target(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry);
int qla4xxx_get_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
@@ -76,7 +76,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
uint32_t state, uint32_t conn_error);
void qla4xxx_dump_buffer(void *b, uint32_t size);
int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
- struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod);
+ struct ddb_entry *ddb_entry, uint64_t lun, uint16_t mrkr_mod);
int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
uint32_t offset, uint32_t length, uint32_t options);
int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index e5697ab144d2..08ab6dac226d 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -83,7 +83,7 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
* This routine issues a marker IOCB.
**/
int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
- struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod)
+ struct ddb_entry *ddb_entry, uint64_t lun, uint16_t mrkr_mod)
{
struct qla4_marker_entry *marker_entry;
unsigned long flags = 0;
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 081b6b78d2c6..4f9c0f2be89d 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -26,7 +26,7 @@ static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
if (sense_len == 0) {
- DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d:%d: %s:"
+ DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d:%llu: %s:"
" sense len 0\n", ha->host_no,
cmd->device->channel, cmd->device->id,
cmd->device->lun, __func__));
@@ -43,7 +43,7 @@ static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN);
memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len);
- DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: %s: sense key = %x, "
+ DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: %s: sense key = %x, "
"ASL= %02x, ASC/ASCQ = %02x/%02x\n", ha->host_no,
cmd->device->channel, cmd->device->id,
cmd->device->lun, __func__,
@@ -169,7 +169,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
cmd->result = DID_ERROR << 16;
- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
+ DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: "
"Mid-layer Data underrun0, "
"xferlen = 0x%x, "
"residual = 0x%x\n", ha->host_no,
@@ -197,7 +197,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
break;
case SCS_RESET_OCCURRED:
- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n",
+ DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: Device RESET occurred\n",
ha->host_no, cmd->device->channel,
cmd->device->id, cmd->device->lun, __func__));
@@ -205,7 +205,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
break;
case SCS_ABORTED:
- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n",
+ DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: Abort occurred\n",
ha->host_no, cmd->device->channel,
cmd->device->id, cmd->device->lun, __func__));
@@ -213,7 +213,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
break;
case SCS_TIMEOUT:
- DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n",
+ DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: Timeout\n",
ha->host_no, cmd->device->channel,
cmd->device->id, cmd->device->lun));
@@ -232,7 +232,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
case SCS_DATA_OVERRUN:
if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) ||
(sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
- DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun\n",
+ DEBUG2(printk("scsi%ld:%d:%d:%llu: %s: " "Data overrun\n",
ha->host_no,
cmd->device->channel, cmd->device->id,
cmd->device->lun, __func__));
@@ -259,7 +259,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
if (!scsi_status && (scsi_bufflen(cmd) - residual) <
cmd->underflow) {
DEBUG2(ql4_printk(KERN_INFO, ha,
- "scsi%ld:%d:%d:%d: %s: Mid-layer Data underrun, xferlen = 0x%x,residual = 0x%x\n",
+ "scsi%ld:%d:%d:%llu: %s: Mid-layer Data underrun, xferlen = 0x%x,residual = 0x%x\n",
ha->host_no,
cmd->device->channel,
cmd->device->id,
@@ -291,7 +291,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
*/
DEBUG2(ql4_printk(KERN_INFO, ha,
- "scsi%ld:%d:%d:%d: %s: Dropped frame(s) detected (0x%x of 0x%x bytes).\n",
+ "scsi%ld:%d:%d:%llu: %s: Dropped frame(s) detected (0x%x of 0x%x bytes).\n",
ha->host_no,
cmd->device->channel,
cmd->device->id,
@@ -313,7 +313,7 @@ check_scsi_status:
case SCS_DEVICE_LOGGED_OUT:
case SCS_DEVICE_UNAVAILABLE:
- DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: SCS_DEVICE "
+ DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%llu: SCS_DEVICE "
"state: 0x%x\n", ha->host_no,
cmd->device->channel, cmd->device->id,
cmd->device->lun, sts_entry->completionStatus));
@@ -333,7 +333,7 @@ check_scsi_status:
* SCSI Mid-Layer handles device queue full
*/
cmd->result = DID_OK << 16 | sts_entry->scsiStatus;
- DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected "
+ DEBUG2(printk("scsi%ld:%d:%llu: %s: QUEUE FULL detected "
"compl=%02x, scsi=%02x, state=%02x, iFlags=%02x,"
" iResp=%02x\n", ha->host_no, cmd->device->id,
cmd->device->lun, __func__,
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 0a3312c6dd6d..fdfae79924ac 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1205,7 +1205,7 @@ int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {
status = QLA_ERROR;
- DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: "
+ DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%llu: abort task FAILED: "
"mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",
ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],
mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));
@@ -1225,14 +1225,14 @@ int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
* are valid before calling this routine.
**/
int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
- int lun)
+ uint64_t lun)
{
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
uint32_t scsi_lun[2];
int status = QLA_SUCCESS;
- DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
+ DEBUG2(printk("scsi%ld:%d:%llu: lun reset issued\n", ha->host_no,
ddb_entry->fw_ddb_index, lun));
/*
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 320206376206..c5d9564d455c 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -9223,20 +9223,20 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
{
struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
unsigned int id = cmd->device->id;
- unsigned int lun = cmd->device->lun;
+ uint64_t lun = cmd->device->lun;
unsigned long flags;
struct srb *srb = NULL;
int ret = SUCCESS;
int wait = 0;
- ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d: Abort command issued cmd=%p, cdb=0x%x\n",
+ ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n",
ha->host_no, id, lun, cmd, cmd->cmnd[0]);
spin_lock_irqsave(&ha->hardware_lock, flags);
srb = (struct srb *) CMD_SP(cmd);
if (!srb) {
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d: Specified command has already completed.\n",
+ ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n",
ha->host_no, id, lun);
return SUCCESS;
}
@@ -9244,11 +9244,11 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (qla4xxx_abort_task(ha, srb) != QLA_SUCCESS) {
- DEBUG3(printk("scsi%ld:%d:%d: Abort_task mbx failed.\n",
+ DEBUG3(printk("scsi%ld:%d:%llu: Abort_task mbx failed.\n",
ha->host_no, id, lun));
ret = FAILED;
} else {
- DEBUG3(printk("scsi%ld:%d:%d: Abort_task mbx success.\n",
+ DEBUG3(printk("scsi%ld:%d:%llu: Abort_task mbx success.\n",
ha->host_no, id, lun));
wait = 1;
}
@@ -9258,14 +9258,14 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
/* Wait for command to complete */
if (wait) {
if (!qla4xxx_eh_wait_on_command(ha, cmd)) {
- DEBUG2(printk("scsi%ld:%d:%d: Abort handler timed out\n",
+ DEBUG2(printk("scsi%ld:%d:%llu: Abort handler timed out\n",
ha->host_no, id, lun));
ret = FAILED;
}
}
ql4_printk(KERN_INFO, ha,
- "scsi%ld:%d:%d: Abort command - %s\n",
+ "scsi%ld:%d:%llu: Abort command - %s\n",
ha->host_no, id, lun, (ret == SUCCESS) ? "succeeded" : "failed");
return ret;
@@ -9293,7 +9293,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
ret = FAILED;
ql4_printk(KERN_INFO, ha,
- "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no,
+ "scsi%ld:%d:%d:%llu: DEVICE RESET ISSUED.\n", ha->host_no,
cmd->device->channel, cmd->device->id, cmd->device->lun);
DEBUG2(printk(KERN_INFO
@@ -9323,7 +9323,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
goto eh_dev_reset_done;
ql4_printk(KERN_INFO, ha,
- "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n",
+ "scsi(%ld:%d:%d:%llu): DEVICE RESET SUCCEEDED.\n",
ha->host_no, cmd->device->channel, cmd->device->id,
cmd->device->lun);
@@ -9440,7 +9440,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
}
ql4_printk(KERN_INFO, ha,
- "scsi(%ld:%d:%d:%d): HOST RESET ISSUED.\n", ha->host_no,
+ "scsi(%ld:%d:%d:%llu): HOST RESET ISSUED.\n", ha->host_no,
cmd->device->channel, cmd->device->id, cmd->device->lun);
if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) {
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
index 13d628b56ff7..a22bb1b40ce2 100644
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -171,8 +171,6 @@ static int qlogicfas_release(struct Scsi_Host *shost)
qlogicfas408_disable_ints(priv);
free_irq(shost->irq, shost);
}
- if (shost->dma_channel != 0xff)
- free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_host_put(shost);
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 6d48d30bed05..740ae495aa77 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -959,7 +959,7 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int
/* Temporary workaround until bug is found and fixed (one bug has been found
already, but fixing it makes things even worse) -jj */
int num_free = QLOGICPTI_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr) - 64;
- host->can_queue = host->host_busy + num_free;
+ host->can_queue = atomic_read(&host->host_busy) + num_free;
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
}
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 88d46fe6bf98..df3306019a7e 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -72,8 +72,6 @@
#define CREATE_TRACE_POINTS
#include <trace/events/scsi.h>
-static void scsi_done(struct scsi_cmnd *cmd);
-
/*
* Definitions and constants.
*/
@@ -124,6 +122,8 @@ static const char *const scsi_device_types[] = {
"Bridge controller",
"Object storage ",
"Automation/Drive ",
+ "Security Manager ",
+ "Direct-Access-ZBC",
};
/**
@@ -235,7 +235,8 @@ fail:
* Description: allocate a struct scsi_cmd from host's slab, recycling from the
* host's free_list if necessary.
*/
-struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
+static struct scsi_cmnd *
+__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask);
@@ -265,7 +266,6 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
return cmd;
}
-EXPORT_SYMBOL_GPL(__scsi_get_command);
/**
* scsi_get_command - Allocate and setup a scsi command block
@@ -291,14 +291,13 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
cmd->jiffies_at_alloc = jiffies;
return cmd;
}
-EXPORT_SYMBOL(scsi_get_command);
/**
* __scsi_put_command - Free a struct scsi_cmnd
* @shost: dev->host
* @cmd: Command to free
*/
-void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+static void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
unsigned long flags;
@@ -314,7 +313,6 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
if (likely(cmd != NULL))
scsi_host_free_command(shost, cmd);
}
-EXPORT_SYMBOL(__scsi_put_command);
/**
* scsi_put_command - Free a scsi command block
@@ -334,11 +332,10 @@ void scsi_put_command(struct scsi_cmnd *cmd)
list_del_init(&cmd->list);
spin_unlock_irqrestore(&cmd->device->list_lock, flags);
- cancel_delayed_work(&cmd->abort_work);
+ BUG_ON(delayed_work_pending(&cmd->abort_work));
__scsi_put_command(cmd->device->host, cmd);
}
-EXPORT_SYMBOL(scsi_put_command);
static struct scsi_host_cmd_pool *
scsi_find_host_cmd_pool(struct Scsi_Host *shost)
@@ -368,8 +365,8 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost)
if (!pool)
return NULL;
- pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->name);
- pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->name);
+ pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->proc_name);
+ pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->proc_name);
if (!pool->cmd_name || !pool->sense_name) {
scsi_free_host_cmd_pool(pool);
return NULL;
@@ -605,7 +602,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
if (level > 3)
scmd_printk(KERN_INFO, cmd,
"scsi host busy %d failed %d\n",
- cmd->device->host->host_busy,
+ atomic_read(&cmd->device->host->host_busy),
cmd->device->host->host_failed);
}
}
@@ -648,33 +645,24 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
* returns an immediate error upwards, and signals
* that the device is no longer present */
cmd->result = DID_NO_CONNECT << 16;
- scsi_done(cmd);
- /* return 0 (because the command has been processed) */
- goto out;
+ goto done;
}
/* Check to see if the scsi lld made this device blocked. */
if (unlikely(scsi_device_blocked(cmd->device))) {
- /*
+ /*
* in blocked state, the command is just put back on
* the device queue. The suspend state has already
* blocked the queue so future requests should not
* occur until the device transitions out of the
* suspend state.
*/
-
- scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
-
- SCSI_LOG_MLQUEUE(3, printk("queuecommand : device blocked \n"));
-
- /*
- * NOTE: rtn is still zero here because we don't need the
- * queue to be plugged on return (it's already stopped)
- */
- goto out;
+ SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
+ "queuecommand : device blocked\n"));
+ return SCSI_MLQUEUE_DEVICE_BUSY;
}
- /*
+ /*
* If SCSI-2 or lower, store the LUN value in cmnd.
*/
if (cmd->device->scsi_level <= SCSI_2 &&
@@ -690,57 +678,36 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
* length exceeds what the host adapter can handle.
*/
if (cmd->cmd_len > cmd->device->host->max_cmd_len) {
- SCSI_LOG_MLQUEUE(3,
- printk("queuecommand : command too long. "
+ SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
+ "queuecommand : command too long. "
"cdb_size=%d host->max_cmd_len=%d\n",
cmd->cmd_len, cmd->device->host->max_cmd_len));
cmd->result = (DID_ABORT << 16);
-
- scsi_done(cmd);
- goto out;
+ goto done;
}
if (unlikely(host->shost_state == SHOST_DEL)) {
cmd->result = (DID_NO_CONNECT << 16);
- scsi_done(cmd);
- } else {
- trace_scsi_dispatch_cmd_start(cmd);
- cmd->scsi_done = scsi_done;
- rtn = host->hostt->queuecommand(host, cmd);
+ goto done;
+
}
+ trace_scsi_dispatch_cmd_start(cmd);
+ rtn = host->hostt->queuecommand(host, cmd);
if (rtn) {
trace_scsi_dispatch_cmd_error(cmd, rtn);
if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
rtn != SCSI_MLQUEUE_TARGET_BUSY)
rtn = SCSI_MLQUEUE_HOST_BUSY;
- scsi_queue_insert(cmd, rtn);
-
- SCSI_LOG_MLQUEUE(3,
- printk("queuecommand : request rejected\n"));
+ SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd,
+ "queuecommand : request rejected\n"));
}
- out:
- SCSI_LOG_MLQUEUE(3, printk("leaving scsi_dispatch_cmnd()\n"));
return rtn;
-}
-
-/**
- * scsi_done - Invoke completion on finished SCSI command.
- * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
- * ownership back to SCSI Core -- i.e. the LLDD has finished with it.
- *
- * Description: This function is the mid-level's (SCSI Core) interrupt routine,
- * which regains ownership of the SCSI command (de facto) from a LLDD, and
- * calls blk_complete_request() for further processing.
- *
- * This function is interrupt context safe.
- */
-static void scsi_done(struct scsi_cmnd *cmd)
-{
- trace_scsi_dispatch_cmd_done(cmd);
- blk_complete_request(cmd->request);
+ done:
+ cmd->scsi_done(cmd);
+ return 0;
}
/**
@@ -761,17 +728,16 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
scsi_device_unbusy(sdev);
- /*
- * Clear the flags which say that the device/host is no longer
- * capable of accepting new commands. These are set in scsi_queue.c
- * for both the queue full condition on a device, and for a
- * host full condition on the host.
- *
- * XXX(hch): What about locking?
- */
- shost->host_blocked = 0;
- starget->target_blocked = 0;
- sdev->device_blocked = 0;
+ /*
+ * Clear the flags that say that the device/target/host is no longer
+ * capable of accepting new commands.
+ */
+ if (atomic_read(&shost->host_blocked))
+ atomic_set(&shost->host_blocked, 0);
+ if (atomic_read(&starget->target_blocked))
+ atomic_set(&starget->target_blocked, 0);
+ if (atomic_read(&sdev->device_blocked))
+ atomic_set(&sdev->device_blocked, 0);
/*
* If we have valid sense information, then some kind of recovery
@@ -801,7 +767,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
}
scsi_io_completion(cmd, good_bytes);
}
-EXPORT_SYMBOL(scsi_finish_command);
/**
* scsi_adjust_queue_depth - Let low level drivers change a device's queue depth
@@ -842,7 +807,7 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
* is more IO than the LLD's can_queue (so there are not enuogh
* tags) request_fn's host queue ready check will handle it.
*/
- if (!sdev->host->bqt) {
+ if (!shost_use_blk_mq(sdev->host) && !sdev->host->bqt) {
if (blk_queue_tagged(sdev->request_queue) &&
blk_queue_resize_tags(sdev->request_queue, tags) != 0)
goto out;
@@ -850,6 +815,10 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
sdev->queue_depth = tags;
switch (tagged) {
+ case 0:
+ sdev->ordered_tags = 0;
+ sdev->simple_tags = 0;
+ break;
case MSG_ORDERED_TAG:
sdev->ordered_tags = 1;
sdev->simple_tags = 1;
@@ -859,13 +828,11 @@ void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
sdev->simple_tags = 1;
break;
default:
+ sdev->ordered_tags = 0;
+ sdev->simple_tags = 0;
sdev_printk(KERN_WARNING, sdev,
"scsi_adjust_queue_depth, bad queue type, "
"disabled\n");
- case 0:
- sdev->ordered_tags = sdev->simple_tags = 0;
- sdev->queue_depth = tags;
- break;
}
out:
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
@@ -1291,7 +1258,7 @@ EXPORT_SYMBOL(__starget_for_each_device);
* really want to use scsi_device_lookup_by_target instead.
**/
struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *starget,
- uint lun)
+ u64 lun)
{
struct scsi_device *sdev;
@@ -1316,7 +1283,7 @@ EXPORT_SYMBOL(__scsi_device_lookup_by_target);
* needs to be released with scsi_device_put once you're done with it.
**/
struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget,
- uint lun)
+ u64 lun)
{
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -1349,7 +1316,7 @@ EXPORT_SYMBOL(scsi_device_lookup_by_target);
* really want to use scsi_device_lookup instead.
**/
struct scsi_device *__scsi_device_lookup(struct Scsi_Host *shost,
- uint channel, uint id, uint lun)
+ uint channel, uint id, u64 lun)
{
struct scsi_device *sdev;
@@ -1375,7 +1342,7 @@ EXPORT_SYMBOL(__scsi_device_lookup);
* needs to be released with scsi_device_put once you're done with it.
**/
struct scsi_device *scsi_device_lookup(struct Scsi_Host *shost,
- uint channel, uint id, uint lun)
+ uint channel, uint id, u64 lun)
{
struct scsi_device *sdev;
unsigned long flags;
@@ -1396,6 +1363,9 @@ MODULE_LICENSE("GPL");
module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
+bool scsi_use_blk_mq = false;
+module_param_named(use_blk_mq, scsi_use_blk_mq, bool, S_IWUSR | S_IRUGO);
+
static int __init init_scsi(void)
{
int error;
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1328a2621070..d19c0e3c7f48 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -42,6 +42,10 @@
#include <linux/scatterlist.h>
#include <linux/blkdev.h>
#include <linux/crc-t10dif.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/atomic.h>
+#include <linux/hrtimer.h>
#include <net/checksum.h>
@@ -53,13 +57,16 @@
#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
#include <scsi/scsi_eh.h>
+#include <scsi/scsi_tcq.h>
#include <scsi/scsi_dbg.h>
#include "sd.h"
#include "scsi_logging.h"
-#define SCSI_DEBUG_VERSION "1.82"
-static const char * scsi_debug_version_date = "20100324";
+#define SCSI_DEBUG_VERSION "1.84"
+static const char *scsi_debug_version_date = "20140706";
+
+#define MY_NAME "scsi_debug"
/* Additional Sense Code (ASC) */
#define NO_ADDITIONAL_SENSE 0x0
@@ -72,7 +79,11 @@ static const char * scsi_debug_version_date = "20100324";
#define INVALID_COMMAND_OPCODE 0x20
#define INVALID_FIELD_IN_CDB 0x24
#define INVALID_FIELD_IN_PARAM_LIST 0x26
-#define POWERON_RESET 0x29
+#define UA_RESET_ASC 0x29
+#define UA_CHANGED_ASC 0x2a
+#define POWER_ON_RESET_ASCQ 0x0
+#define BUS_RESET_ASCQ 0x2 /* scsi bus reset occurred */
+#define MODE_CHANGED_ASCQ 0x1 /* mode parameters changed */
#define SAVING_PARAMS_UNSUP 0x39
#define TRANSPORT_PROBLEM 0x4b
#define THRESHOLD_EXCEEDED 0x5d
@@ -81,7 +92,6 @@ static const char * scsi_debug_version_date = "20100324";
/* Additional Sense Code Qualifier (ASCQ) */
#define ACK_NAK_TO 0x3
-#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
/* Default values for driver parameters */
#define DEF_NUM_HOST 1
@@ -91,7 +101,7 @@ static const char * scsi_debug_version_date = "20100324";
* (id 0) containing 1 logical unit (lun 0). That is 1 device.
*/
#define DEF_ATO 1
-#define DEF_DELAY 1
+#define DEF_DELAY 1 /* if > 0 unit is a jiffy */
#define DEF_DEV_SIZE_MB 8
#define DEF_DIF 0
#define DEF_DIX 0
@@ -99,11 +109,13 @@ static const char * scsi_debug_version_date = "20100324";
#define DEF_EVERY_NTH 0
#define DEF_FAKE_RW 0
#define DEF_GUARD 0
+#define DEF_HOST_LOCK 0
#define DEF_LBPU 0
#define DEF_LBPWS 0
#define DEF_LBPWS10 0
#define DEF_LBPRZ 1
#define DEF_LOWEST_ALIGNED 0
+#define DEF_NDELAY 0 /* if > 0 unit is a nanosecond */
#define DEF_NO_LUN_0 0
#define DEF_NUM_PARTS 0
#define DEF_OPTS 0
@@ -113,6 +125,7 @@ static const char * scsi_debug_version_date = "20100324";
#define DEF_REMOVABLE false
#define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */
#define DEF_SECTOR_SIZE 512
+#define DEF_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
#define DEF_UNMAP_ALIGNMENT 0
#define DEF_UNMAP_GRANULARITY 1
#define DEF_UNMAP_MAX_BLOCKS 0xFFFFFFFF
@@ -120,6 +133,7 @@ static const char * scsi_debug_version_date = "20100324";
#define DEF_VIRTUAL_GB 0
#define DEF_VPD_USE_HOSTNO 1
#define DEF_WRITESAME_LENGTH 0xFFFF
+#define DELAY_OVERRIDDEN -9999
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
@@ -130,7 +144,14 @@ static const char * scsi_debug_version_date = "20100324";
#define SCSI_DEBUG_OPT_DIF_ERR 32
#define SCSI_DEBUG_OPT_DIX_ERR 64
#define SCSI_DEBUG_OPT_MAC_TIMEOUT 128
-#define SCSI_DEBUG_OPT_SHORT_TRANSFER 256
+#define SCSI_DEBUG_OPT_SHORT_TRANSFER 0x100
+#define SCSI_DEBUG_OPT_Q_NOISE 0x200
+#define SCSI_DEBUG_OPT_ALL_TSF 0x400
+#define SCSI_DEBUG_OPT_RARE_TSF 0x800
+#define SCSI_DEBUG_OPT_N_WCE 0x1000
+#define SCSI_DEBUG_OPT_RESET_NOISE 0x2000
+#define SCSI_DEBUG_OPT_NO_CDB_NOISE 0x4000
+#define SCSI_DEBUG_OPT_ALL_NOISE (0x1 | 0x200 | 0x2000)
/* When "every_nth" > 0 then modulo "every_nth" commands:
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
* - a RECOVERED_ERROR is simulated on successful read and write
@@ -148,6 +169,19 @@ static const char * scsi_debug_version_date = "20100324";
* writing a new value (other than -1 or 1) to every_nth via sysfs).
*/
+/* As indicated in SAM-5 and SPC-4 Unit Attentions (UAs)are returned in
+ * priority order. In the subset implemented here lower numbers have higher
+ * priority. The UA numbers should be a sequence starting from 0 with
+ * SDEBUG_NUM_UAS being 1 higher than the highest numbered UA. */
+#define SDEBUG_UA_POR 0 /* Power on, reset, or bus device reset */
+#define SDEBUG_UA_BUS_RESET 1
+#define SDEBUG_UA_MODE_CHANGED 2
+#define SDEBUG_NUM_UAS 3
+
+/* for check_readiness() */
+#define UAS_ONLY 1
+#define UAS_TUR 0
+
/* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
* sector on read commands: */
#define OPT_MEDIUM_ERR_ADDR 0x1234 /* that's sector 4660 in decimal */
@@ -158,9 +192,19 @@ static const char * scsi_debug_version_date = "20100324";
#define SAM2_LUN_ADDRESS_METHOD 0
#define SAM2_WLUN_REPORT_LUNS 0xc101
-/* Can queue up to this number of commands. Typically commands that
- * that have a non-zero delay are queued. */
-#define SCSI_DEBUG_CANQUEUE 255
+/* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued
+ * (for response) at one time. Can be reduced by max_queue option. Command
+ * responses are not queued when delay=0 and ndelay=0. The per-device
+ * DEF_CMD_PER_LUN can be changed via sysfs:
+ * /sys/class/scsi_device/<h:c:t:l>/device/queue_depth but cannot exceed
+ * SCSI_DEBUG_CANQUEUE. */
+#define SCSI_DEBUG_CANQUEUE_WORDS 9 /* a WORD is bits in a long */
+#define SCSI_DEBUG_CANQUEUE (SCSI_DEBUG_CANQUEUE_WORDS * BITS_PER_LONG)
+#define DEF_CMD_PER_LUN 255
+
+#if DEF_CMD_PER_LUN > SCSI_DEBUG_CANQUEUE
+#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
+#endif
static int scsi_debug_add_host = DEF_NUM_HOST;
static int scsi_debug_ato = DEF_ATO;
@@ -175,6 +219,8 @@ static unsigned int scsi_debug_guard = DEF_GUARD;
static int scsi_debug_lowest_aligned = DEF_LOWEST_ALIGNED;
static int scsi_debug_max_luns = DEF_MAX_LUNS;
static int scsi_debug_max_queue = SCSI_DEBUG_CANQUEUE;
+static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */
+static int scsi_debug_ndelay = DEF_NDELAY;
static int scsi_debug_no_lun_0 = DEF_NO_LUN_0;
static int scsi_debug_no_uld = 0;
static int scsi_debug_num_parts = DEF_NUM_PARTS;
@@ -198,8 +244,11 @@ static unsigned int scsi_debug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
static bool scsi_debug_removable = DEF_REMOVABLE;
static bool scsi_debug_clustering;
+static bool scsi_debug_host_lock = DEF_HOST_LOCK;
-static int scsi_debug_cmnd_count = 0;
+static atomic_t sdebug_cmnd_count;
+static atomic_t sdebug_completions;
+static atomic_t sdebug_a_tsf; /* counter of 'almost' TSFs */
#define DEV_READONLY(TGT) (0)
@@ -214,24 +263,23 @@ static int sdebug_sectors_per; /* sectors per cylinder */
#define SDEBUG_MAX_PARTS 4
-#define SDEBUG_SENSE_LEN 32
-
#define SCSI_DEBUG_MAX_CMD_LEN 32
static unsigned int scsi_debug_lbp(void)
{
- return scsi_debug_lbpu | scsi_debug_lbpws | scsi_debug_lbpws10;
+ return ((0 == scsi_debug_fake_rw) &&
+ (scsi_debug_lbpu | scsi_debug_lbpws | scsi_debug_lbpws10));
}
struct sdebug_dev_info {
struct list_head dev_list;
- unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */
unsigned int channel;
unsigned int target;
- unsigned int lun;
+ u64 lun;
struct sdebug_host_info *sdbg_host;
- unsigned int wlun;
- char reset;
+ u64 wlun;
+ unsigned long uas_bm[1];
+ atomic_t num_in_q;
char stopped;
char used;
};
@@ -249,26 +297,33 @@ struct sdebug_host_info {
static LIST_HEAD(sdebug_host_list);
static DEFINE_SPINLOCK(sdebug_host_list_lock);
-typedef void (* done_funct_t) (struct scsi_cmnd *);
+
+struct sdebug_hrtimer { /* ... is derived from hrtimer */
+ struct hrtimer hrt; /* must be first element */
+ int qa_indx;
+};
struct sdebug_queued_cmd {
- int in_use;
- struct timer_list cmnd_timer;
- done_funct_t done_funct;
+ /* in_use flagged by a bit in queued_in_use_bm[] */
+ struct timer_list *cmnd_timerp;
+ struct tasklet_struct *tletp;
+ struct sdebug_hrtimer *sd_hrtp;
struct scsi_cmnd * a_cmnd;
- int scsi_result;
};
static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
+static unsigned long queued_in_use_bm[SCSI_DEBUG_CANQUEUE_WORDS];
+
static unsigned char * fake_storep; /* ramdisk storage */
static struct sd_dif_tuple *dif_storep; /* protection info */
static void *map_storep; /* provisioning map */
static unsigned long map_size;
-static int num_aborts = 0;
-static int num_dev_resets = 0;
-static int num_bus_resets = 0;
-static int num_host_resets = 0;
+static int num_aborts;
+static int num_dev_resets;
+static int num_target_resets;
+static int num_bus_resets;
+static int num_host_resets;
static int dix_writes;
static int dix_reads;
static int dif_errors;
@@ -276,7 +331,8 @@ static int dif_errors;
static DEFINE_SPINLOCK(queued_arr_lock);
static DEFINE_RWLOCK(atomic_rw);
-static char sdebug_proc_name[] = "scsi_debug";
+static char sdebug_proc_name[] = MY_NAME;
+static const char *my_name = MY_NAME;
static struct bus_type pseudo_lld_bus;
@@ -291,6 +347,12 @@ static const int check_condition_result =
static const int illegal_condition_result =
(DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
+static const int device_qfull_result =
+ (DID_OK << 16) | (COMMAND_COMPLETE << 8) | SAM_STAT_TASK_SET_FULL;
+
+static unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
+ 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0,
+ 0, 0, 0, 0};
static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
0, 0, 0x2, 0x4b};
static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
@@ -332,19 +394,24 @@ static void sdebug_max_tgts_luns(void)
spin_unlock(&sdebug_host_list_lock);
}
-static void mk_sense_buffer(struct sdebug_dev_info *devip, int key,
- int asc, int asq)
+static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq)
{
unsigned char *sbuff;
- sbuff = devip->sense_buff;
- memset(sbuff, 0, SDEBUG_SENSE_LEN);
+ sbuff = scp->sense_buffer;
+ if (!sbuff) {
+ sdev_printk(KERN_ERR, scp->device,
+ "%s: sense_buffer is NULL\n", __func__);
+ return;
+ }
+ memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE);
scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq);
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: "
- "[0x%x,0x%x,0x%x]\n", key, asc, asq);
+ sdev_printk(KERN_INFO, scp->device,
+ "%s: [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n",
+ my_name, key, asc, asq);
}
static void get_data_transfer_info(unsigned char *cmd,
@@ -409,29 +476,71 @@ static void get_data_transfer_info(unsigned char *cmd,
static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
{
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
- printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd);
+ if (0x1261 == cmd)
+ sdev_printk(KERN_INFO, dev,
+ "%s: BLKFLSBUF [0x1261]\n", __func__);
+ else if (0x5331 == cmd)
+ sdev_printk(KERN_INFO, dev,
+ "%s: CDROM_GET_CAPABILITY [0x5331]\n",
+ __func__);
+ else
+ sdev_printk(KERN_INFO, dev, "%s: cmd=0x%x\n",
+ __func__, cmd);
}
return -EINVAL;
/* return -ENOTTY; // correct return but upsets fdisk */
}
-static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only,
+static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
struct sdebug_dev_info * devip)
{
- if (devip->reset) {
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Reporting Unit "
- "attention: power on reset\n");
- devip->reset = 0;
- mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0);
+ int k;
+ bool debug = !!(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts);
+
+ k = find_first_bit(devip->uas_bm, SDEBUG_NUM_UAS);
+ if (k != SDEBUG_NUM_UAS) {
+ const char *cp = NULL;
+
+ switch (k) {
+ case SDEBUG_UA_POR:
+ mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+ UA_RESET_ASC, POWER_ON_RESET_ASCQ);
+ if (debug)
+ cp = "power on reset";
+ break;
+ case SDEBUG_UA_BUS_RESET:
+ mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+ UA_RESET_ASC, BUS_RESET_ASCQ);
+ if (debug)
+ cp = "bus reset";
+ break;
+ case SDEBUG_UA_MODE_CHANGED:
+ mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+ UA_CHANGED_ASC, MODE_CHANGED_ASCQ);
+ if (debug)
+ cp = "mode parameters changed";
+ break;
+ default:
+ pr_warn("%s: unexpected unit attention code=%d\n",
+ __func__, k);
+ if (debug)
+ cp = "unknown";
+ break;
+ }
+ clear_bit(k, devip->uas_bm);
+ if (debug)
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s reports: Unit attention: %s\n",
+ my_name, cp);
return check_condition_result;
}
- if ((0 == reset_only) && devip->stopped) {
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Reporting Not "
- "ready: initializing command required\n");
- mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY,
+ if ((UAS_TUR == uas_only) && devip->stopped) {
+ mk_sense_buffer(SCpnt, NOT_READY, LOGICAL_UNIT_NOT_READY,
0x2);
+ if (debug)
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s reports: Not ready: %s\n", my_name,
+ "initializing command required");
return check_condition_result;
}
return 0;
@@ -471,8 +580,9 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr,
static const char * inq_vendor_id = "Linux ";
static const char * inq_product_id = "scsi_debug ";
-static const char * inq_product_rev = "0004";
+static const char *inq_product_rev = "0184"; /* version less '.' */
+/* Device identification VPD page. Returns number of bytes placed in arr */
static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
int target_dev_id, int dev_id_num,
const char * dev_id_str,
@@ -573,12 +683,14 @@ static unsigned char vpd84_data[] = {
0x22,0x22,0x22,0x0,0xbb,0x2,
};
+/* Software interface identification VPD page */
static int inquiry_evpd_84(unsigned char * arr)
{
memcpy(arr, vpd84_data, sizeof(vpd84_data));
return sizeof(vpd84_data);
}
+/* Management network addresses VPD page */
static int inquiry_evpd_85(unsigned char * arr)
{
int num = 0;
@@ -713,6 +825,7 @@ static unsigned char vpd89_data[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51,
};
+/* ATA Information VPD page */
static int inquiry_evpd_89(unsigned char * arr)
{
memcpy(arr, vpd89_data, sizeof(vpd89_data));
@@ -720,7 +833,6 @@ static int inquiry_evpd_89(unsigned char * arr)
}
-/* Block limits VPD page (SBC-3) */
static unsigned char vpdb0_data[] = {
/* from 4th byte */ 0,0,0,4, 0,0,0x4,0, 0,0,0,64,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -728,6 +840,7 @@ static unsigned char vpdb0_data[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
+/* Block limits VPD page (SBC-3) */
static int inquiry_evpd_b0(unsigned char * arr)
{
unsigned int gran;
@@ -811,7 +924,7 @@ static int inquiry_evpd_b2(unsigned char *arr)
#define SDEBUG_LONG_INQ_SZ 96
#define SDEBUG_MAX_INQ_ARR_SZ 584
-static int resp_inquiry(struct scsi_cmnd * scp, int target,
+static int resp_inquiry(struct scsi_cmnd *scp, int target,
struct sdebug_dev_info * devip)
{
unsigned char pq_pdt;
@@ -831,7 +944,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
pq_pdt = (scsi_debug_ptype & 0x1f);
arr[0] = pq_pdt;
if (0x2 & cmd[1]) { /* CMDDT bit set */
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
kfree(arr);
return check_condition_result;
@@ -917,7 +1030,7 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
arr[3] = inquiry_evpd_b2(&arr[4]);
} else {
/* Illegal request, invalid field in cdb */
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
kfree(arr);
return check_condition_result;
@@ -963,15 +1076,13 @@ static int resp_requests(struct scsi_cmnd * scp,
{
unsigned char * sbuff;
unsigned char *cmd = (unsigned char *)scp->cmnd;
- unsigned char arr[SDEBUG_SENSE_LEN];
+ unsigned char arr[SCSI_SENSE_BUFFERSIZE];
int want_dsense;
int len = 18;
memset(arr, 0, sizeof(arr));
- if (devip->reset == 1)
- mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0);
want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense;
- sbuff = devip->sense_buff;
+ sbuff = scp->sense_buffer;
if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) {
if (want_dsense) {
arr[0] = 0x72;
@@ -986,7 +1097,7 @@ static int resp_requests(struct scsi_cmnd * scp,
arr[13] = 0xff; /* TEST set and MRIE==6 */
}
} else {
- memcpy(arr, sbuff, SDEBUG_SENSE_LEN);
+ memcpy(arr, sbuff, SCSI_SENSE_BUFFERSIZE);
if ((cmd[1] & 1) && (! scsi_debug_dsense)) {
/* DESC bit set and sense_buff in fixed format */
memset(arr, 0, sizeof(arr));
@@ -997,7 +1108,7 @@ static int resp_requests(struct scsi_cmnd * scp,
len = 8;
}
}
- mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0);
+ mk_sense_buffer(scp, 0, NO_ADDITIONAL_SENSE, 0);
return fill_from_dev_buffer(scp, arr, len);
}
@@ -1007,11 +1118,12 @@ static int resp_start_stop(struct scsi_cmnd * scp,
unsigned char *cmd = (unsigned char *)scp->cmnd;
int power_cond, errsts, start;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
power_cond = (cmd[4] & 0xf0) >> 4;
if (power_cond) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
return check_condition_result;
}
@@ -1038,7 +1150,8 @@ static int resp_readcap(struct scsi_cmnd * scp,
unsigned int capac;
int errsts;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
/* following just in case virtual_gb changed */
sdebug_capacity = get_sdebug_capacity();
@@ -1069,7 +1182,8 @@ static int resp_readcap16(struct scsi_cmnd * scp,
unsigned long long capac;
int errsts, k, alloc_len;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8)
+ cmd[13]);
@@ -1230,12 +1344,18 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target)
static int resp_caching_pg(unsigned char * p, int pcontrol, int target)
{ /* Caching page for mode_sense */
- unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
+ unsigned char ch_caching_pg[] = {/* 0x8, 18, */ 0x4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char d_caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0,
0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0};
+ if (SCSI_DEBUG_OPT_N_WCE & scsi_debug_opts)
+ caching_pg[2] &= ~0x4; /* set WCE=0 (default WCE=1) */
memcpy(p, caching_pg, sizeof(caching_pg));
if (1 == pcontrol)
- memset(p + 2, 0, sizeof(caching_pg) - 2);
+ memcpy(p + 2, ch_caching_pg, sizeof(ch_caching_pg));
+ else if (2 == pcontrol)
+ memcpy(p, d_caching_pg, sizeof(d_caching_pg));
return sizeof(caching_pg);
}
@@ -1350,7 +1470,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
unsigned char *cmd = (unsigned char *)scp->cmnd;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
dbd = !!(cmd[1] & 0x8);
pcontrol = (cmd[2] & 0xc0) >> 6;
@@ -1365,8 +1486,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
if (0x3 == pcontrol) { /* Saving values not supported */
- mk_sense_buffer(devip, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP,
- 0);
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP, 0);
return check_condition_result;
}
target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) +
@@ -1422,7 +1542,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) {
/* TODO: Control Extension page */
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
return check_condition_result;
}
@@ -1449,7 +1569,7 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
break;
case 0x19: /* if spc==1 then sas phy, control+discover */
if ((subpcode > 0x2) && (subpcode < 0xff)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
@@ -1482,14 +1602,14 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target,
}
len += resp_iec_m_pg(ap + len, pcontrol, target);
} else {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
offset += len;
break;
default:
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
return check_condition_result;
}
@@ -1512,14 +1632,15 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
unsigned char arr[SDEBUG_MAX_MSELECT_SZ];
unsigned char *cmd = (unsigned char *)scp->cmnd;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
memset(arr, 0, sizeof(arr));
pf = cmd[1] & 0x10;
sp = cmd[1] & 0x1;
param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]);
if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
@@ -1528,12 +1649,13 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
return (DID_ERROR << 16);
else if ((res < param_len) &&
(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
- printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, "
- " IO sent=%d bytes\n", param_len, res);
+ sdev_printk(KERN_INFO, scp->device,
+ "%s: cdb indicated=%d, IO sent=%d bytes\n",
+ __func__, param_len, res);
md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2);
bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]);
if (md_len > 2) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_PARAM_LIST, 0);
return check_condition_result;
}
@@ -1541,7 +1663,7 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
mpage = arr[off] & 0x3f;
ps = !!(arr[off] & 0x80);
if (ps) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_PARAM_LIST, 0);
return check_condition_result;
}
@@ -1549,32 +1671,42 @@ static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) :
(arr[off + 1] + 2);
if ((pg_len + off) > param_len) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
PARAMETER_LIST_LENGTH_ERR, 0);
return check_condition_result;
}
switch (mpage) {
+ case 0x8: /* Caching Mode page */
+ if (caching_pg[1] == arr[off + 1]) {
+ memcpy(caching_pg + 2, arr + off + 2,
+ sizeof(caching_pg) - 2);
+ goto set_mode_changed_ua;
+ }
+ break;
case 0xa: /* Control Mode page */
if (ctrl_m_pg[1] == arr[off + 1]) {
memcpy(ctrl_m_pg + 2, arr + off + 2,
sizeof(ctrl_m_pg) - 2);
scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4);
- return 0;
+ goto set_mode_changed_ua;
}
break;
case 0x1c: /* Informational Exceptions Mode page */
if (iec_m_pg[1] == arr[off + 1]) {
memcpy(iec_m_pg + 2, arr + off + 2,
sizeof(iec_m_pg) - 2);
- return 0;
+ goto set_mode_changed_ua;
}
break;
default:
break;
}
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_PARAM_LIST, 0);
return check_condition_result;
+set_mode_changed_ua:
+ set_bit(SDEBUG_UA_MODE_CHANGED, devip->uas_bm);
+ return 0;
}
static int resp_temp_l_pg(unsigned char * arr)
@@ -1609,13 +1741,14 @@ static int resp_log_sense(struct scsi_cmnd * scp,
unsigned char arr[SDEBUG_MAX_LSENSE_SZ];
unsigned char *cmd = (unsigned char *)scp->cmnd;
- if ((errsts = check_readiness(scp, 1, devip)))
+ errsts = check_readiness(scp, UAS_ONLY, devip);
+ if (errsts)
return errsts;
memset(arr, 0, sizeof(arr));
ppc = cmd[1] & 0x2;
sp = cmd[1] & 0x1;
if (ppc || sp) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
@@ -1640,7 +1773,7 @@ static int resp_log_sense(struct scsi_cmnd * scp,
arr[3] = resp_ie_l_pg(arr + 4);
break;
default:
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
@@ -1673,12 +1806,12 @@ static int resp_log_sense(struct scsi_cmnd * scp,
arr[3] = n - 4;
break;
default:
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
} else {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
@@ -1687,16 +1820,16 @@ static int resp_log_sense(struct scsi_cmnd * scp,
min(len, SDEBUG_MAX_INQ_ARR_SZ));
}
-static int check_device_access_params(struct sdebug_dev_info *devi,
+static int check_device_access_params(struct scsi_cmnd *scp,
unsigned long long lba, unsigned int num)
{
if (lba + num > sdebug_capacity) {
- mk_sense_buffer(devi, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0);
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0);
return check_condition_result;
}
/* transfer length excessive (tie in to block limits VPD page) */
if (num > sdebug_store_sectors) {
- mk_sense_buffer(devi, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
return check_condition_result;
}
return 0;
@@ -1704,7 +1837,6 @@ static int check_device_access_params(struct sdebug_dev_info *devi,
/* Returns number of bytes copied or -1 if error. */
static int do_device_access(struct scsi_cmnd *scmd,
- struct sdebug_dev_info *devi,
unsigned long long lba, unsigned int num, int write)
{
int ret;
@@ -1861,13 +1993,12 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
}
static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip,
- u32 ei_lba)
+ unsigned int num, u32 ei_lba)
{
unsigned long iflags;
int ret;
- ret = check_device_access_params(devip, lba, num);
+ ret = check_device_access_params(SCpnt, lba, num);
if (ret)
return ret;
@@ -1875,16 +2006,16 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
(lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) &&
((lba + num) > OPT_MEDIUM_ERR_ADDR)) {
/* claim unrecoverable read error */
- mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
+ mk_sense_buffer(SCpnt, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0);
/* set info field and valid bit for fixed descriptor */
- if (0x70 == (devip->sense_buff[0] & 0x7f)) {
- devip->sense_buff[0] |= 0x80; /* Valid bit */
+ if (0x70 == (SCpnt->sense_buffer[0] & 0x7f)) {
+ SCpnt->sense_buffer[0] |= 0x80; /* Valid bit */
ret = (lba < OPT_MEDIUM_ERR_ADDR)
? OPT_MEDIUM_ERR_ADDR : (int)lba;
- devip->sense_buff[3] = (ret >> 24) & 0xff;
- devip->sense_buff[4] = (ret >> 16) & 0xff;
- devip->sense_buff[5] = (ret >> 8) & 0xff;
- devip->sense_buff[6] = ret & 0xff;
+ SCpnt->sense_buffer[3] = (ret >> 24) & 0xff;
+ SCpnt->sense_buffer[4] = (ret >> 16) & 0xff;
+ SCpnt->sense_buffer[5] = (ret >> 8) & 0xff;
+ SCpnt->sense_buffer[6] = ret & 0xff;
}
scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
return check_condition_result;
@@ -1898,12 +2029,12 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
if (prot_ret) {
read_unlock_irqrestore(&atomic_rw, iflags);
- mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret);
+ mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, prot_ret);
return illegal_condition_result;
}
}
- ret = do_device_access(SCpnt, devip, lba, num, 0);
+ ret = do_device_access(SCpnt, lba, num, 0);
read_unlock_irqrestore(&atomic_rw, iflags);
if (ret == -1)
return DID_ERROR << 16;
@@ -1915,22 +2046,23 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
void dump_sector(unsigned char *buf, int len)
{
- int i, j;
-
- printk(KERN_ERR ">>> Sector Dump <<<\n");
+ int i, j, n;
+ pr_err(">>> Sector Dump <<<\n");
for (i = 0 ; i < len ; i += 16) {
- printk(KERN_ERR "%04d: ", i);
+ char b[128];
- for (j = 0 ; j < 16 ; j++) {
+ for (j = 0, n = 0; j < 16; j++) {
unsigned char c = buf[i+j];
+
if (c >= 0x20 && c < 0x7e)
- printk(" %c ", buf[i+j]);
+ n += scnprintf(b + n, sizeof(b) - n,
+ " %c ", buf[i+j]);
else
- printk("%02x ", buf[i+j]);
+ n += scnprintf(b + n, sizeof(b) - n,
+ "%02x ", buf[i+j]);
}
-
- printk("\n");
+ pr_err("%04d: %s\n", i, b);
}
}
@@ -2092,13 +2224,12 @@ static void unmap_region(sector_t lba, unsigned int len)
}
static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip,
- u32 ei_lba)
+ unsigned int num, u32 ei_lba)
{
unsigned long iflags;
int ret;
- ret = check_device_access_params(devip, lba, num);
+ ret = check_device_access_params(SCpnt, lba, num);
if (ret)
return ret;
@@ -2110,12 +2241,13 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
if (prot_ret) {
write_unlock_irqrestore(&atomic_rw, iflags);
- mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret);
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10,
+ prot_ret);
return illegal_condition_result;
}
}
- ret = do_device_access(SCpnt, devip, lba, num, 1);
+ ret = do_device_access(SCpnt, lba, num, 1);
if (scsi_debug_lbp())
map_region(lba, num);
write_unlock_irqrestore(&atomic_rw, iflags);
@@ -2123,26 +2255,26 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
return (DID_ERROR << 16);
else if ((ret < (num * scsi_debug_sector_size)) &&
(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
- printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, "
- " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret);
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s: write: cdb indicated=%u, IO sent=%d bytes\n",
+ my_name, num * scsi_debug_sector_size, ret);
return 0;
}
static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba,
- unsigned int num, struct sdebug_dev_info *devip,
- u32 ei_lba, unsigned int unmap)
+ unsigned int num, u32 ei_lba, unsigned int unmap)
{
unsigned long iflags;
unsigned long long i;
int ret;
- ret = check_device_access_params(devip, lba, num);
+ ret = check_device_access_params(scmd, lba, num);
if (ret)
return ret;
if (num > scsi_debug_write_same_length) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scmd, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
return check_condition_result;
}
@@ -2164,8 +2296,10 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba,
return (DID_ERROR << 16);
} else if ((ret < (num * scsi_debug_sector_size)) &&
(SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
- printk(KERN_INFO "scsi_debug: write same: cdb indicated=%u, "
- " IO sent=%d bytes\n", num * scsi_debug_sector_size, ret);
+ sdev_printk(KERN_INFO, scmd->device,
+ "%s: %s: cdb indicated=%u, IO sent=%d bytes\n",
+ my_name, "write same",
+ num * scsi_debug_sector_size, ret);
/* Copy first sector to remaining blocks */
for (i = 1 ; i < num ; i++)
@@ -2195,7 +2329,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
int ret;
unsigned long iflags;
- ret = check_readiness(scmd, 1, devip);
+ ret = check_readiness(scmd, UAS_ONLY, devip);
if (ret)
return ret;
@@ -2221,7 +2355,7 @@ static int resp_unmap(struct scsi_cmnd * scmd, struct sdebug_dev_info * devip)
unsigned long long lba = get_unaligned_be64(&desc[i].lba);
unsigned int num = get_unaligned_be32(&desc[i].blocks);
- ret = check_device_access_params(devip, lba, num);
+ ret = check_device_access_params(scmd, lba, num);
if (ret)
goto out;
@@ -2247,7 +2381,7 @@ static int resp_get_lba_status(struct scsi_cmnd * scmd,
unsigned char arr[SDEBUG_GET_LBA_STATUS_LEN];
int ret;
- ret = check_readiness(scmd, 1, devip);
+ ret = check_readiness(scmd, UAS_ONLY, devip);
if (ret)
return ret;
@@ -2257,7 +2391,7 @@ static int resp_get_lba_status(struct scsi_cmnd * scmd,
if (alloc_len < 24)
return 0;
- ret = check_device_access_params(devip, lba, 1);
+ ret = check_device_access_params(scmd, lba, 1);
if (ret)
return ret;
@@ -2278,7 +2412,8 @@ static int resp_report_luns(struct scsi_cmnd * scp,
struct sdebug_dev_info * devip)
{
unsigned int alloc_len;
- int lun_cnt, i, upper, num, n, wlun, lun;
+ int lun_cnt, i, upper, num, n;
+ u64 wlun, lun;
unsigned char *cmd = (unsigned char *)scp->cmnd;
int select_report = (int)cmd[2];
struct scsi_lun *one_lun;
@@ -2287,7 +2422,7 @@ static int resp_report_luns(struct scsi_cmnd * scp,
alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
if ((alloc_len < 4) || (select_report > 2)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
+ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
0);
return check_condition_result;
}
@@ -2341,7 +2476,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
/* better not to use temporary buffer. */
buf = kmalloc(scsi_bufflen(scp), GFP_ATOMIC);
if (!buf) {
- mk_sense_buffer(devip, NOT_READY,
+ mk_sense_buffer(scp, NOT_READY,
LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
return check_condition_result;
}
@@ -2365,34 +2500,125 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
return 0;
}
-/* When timer goes off this function is called. */
-static void timer_intr_handler(unsigned long indx)
+/* When timer or tasklet goes off this function is called. */
+static void sdebug_q_cmd_complete(unsigned long indx)
{
- struct sdebug_queued_cmd * sqcp;
+ int qa_indx;
+ int retiring = 0;
unsigned long iflags;
+ struct sdebug_queued_cmd *sqcp;
+ struct scsi_cmnd *scp;
+ struct sdebug_dev_info *devip;
- if (indx >= scsi_debug_max_queue) {
- printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too "
- "large\n");
+ atomic_inc(&sdebug_completions);
+ qa_indx = indx;
+ if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) {
+ pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx);
return;
}
spin_lock_irqsave(&queued_arr_lock, iflags);
- sqcp = &queued_arr[(int)indx];
- if (! sqcp->in_use) {
- printk(KERN_ERR "scsi_debug:timer_intr_handler: Unexpected "
- "interrupt\n");
+ sqcp = &queued_arr[qa_indx];
+ scp = sqcp->a_cmnd;
+ if (NULL == scp) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: scp is NULL\n", __func__);
+ return;
+ }
+ devip = (struct sdebug_dev_info *)scp->device->hostdata;
+ if (devip)
+ atomic_dec(&devip->num_in_q);
+ else
+ pr_err("%s: devip=NULL\n", __func__);
+ if (atomic_read(&retired_max_queue) > 0)
+ retiring = 1;
+
+ sqcp->a_cmnd = NULL;
+ if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) {
spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: Unexpected completion\n", __func__);
return;
}
- sqcp->in_use = 0;
- if (sqcp->done_funct) {
- sqcp->a_cmnd->result = sqcp->scsi_result;
- sqcp->done_funct(sqcp->a_cmnd); /* callback to mid level */
+
+ if (unlikely(retiring)) { /* user has reduced max_queue */
+ int k, retval;
+
+ retval = atomic_read(&retired_max_queue);
+ if (qa_indx >= retval) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: index %d too large\n", __func__, retval);
+ return;
+ }
+ k = find_last_bit(queued_in_use_bm, retval);
+ if ((k < scsi_debug_max_queue) || (k == retval))
+ atomic_set(&retired_max_queue, 0);
+ else
+ atomic_set(&retired_max_queue, k + 1);
}
- sqcp->done_funct = NULL;
spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ scp->scsi_done(scp); /* callback to mid level */
}
+/* When high resolution timer goes off this function is called. */
+static enum hrtimer_restart
+sdebug_q_cmd_hrt_complete(struct hrtimer *timer)
+{
+ int qa_indx;
+ int retiring = 0;
+ unsigned long iflags;
+ struct sdebug_hrtimer *sd_hrtp = (struct sdebug_hrtimer *)timer;
+ struct sdebug_queued_cmd *sqcp;
+ struct scsi_cmnd *scp;
+ struct sdebug_dev_info *devip;
+
+ atomic_inc(&sdebug_completions);
+ qa_indx = sd_hrtp->qa_indx;
+ if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) {
+ pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx);
+ goto the_end;
+ }
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ sqcp = &queued_arr[qa_indx];
+ scp = sqcp->a_cmnd;
+ if (NULL == scp) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: scp is NULL\n", __func__);
+ goto the_end;
+ }
+ devip = (struct sdebug_dev_info *)scp->device->hostdata;
+ if (devip)
+ atomic_dec(&devip->num_in_q);
+ else
+ pr_err("%s: devip=NULL\n", __func__);
+ if (atomic_read(&retired_max_queue) > 0)
+ retiring = 1;
+
+ sqcp->a_cmnd = NULL;
+ if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: Unexpected completion\n", __func__);
+ goto the_end;
+ }
+
+ if (unlikely(retiring)) { /* user has reduced max_queue */
+ int k, retval;
+
+ retval = atomic_read(&retired_max_queue);
+ if (qa_indx >= retval) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ pr_err("%s: index %d too large\n", __func__, retval);
+ goto the_end;
+ }
+ k = find_last_bit(queued_in_use_bm, retval);
+ if ((k < scsi_debug_max_queue) || (k == retval))
+ atomic_set(&retired_max_queue, 0);
+ else
+ atomic_set(&retired_max_queue, k + 1);
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ scp->scsi_done(scp); /* callback to mid level */
+the_end:
+ return HRTIMER_NORESTART;
+}
static struct sdebug_dev_info *
sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags)
@@ -2418,7 +2644,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
return devip;
sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host);
if (!sdbg_host) {
- printk(KERN_ERR "Host info NULL\n");
+ pr_err("%s: Host info NULL\n", __func__);
return NULL;
}
list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) {
@@ -2444,15 +2670,9 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
open_devip->target = sdev->id;
open_devip->lun = sdev->lun;
open_devip->sdbg_host = sdbg_host;
- open_devip->reset = 1;
+ atomic_set(&open_devip->num_in_q, 0);
+ set_bit(SDEBUG_UA_POR, open_devip->uas_bm);
open_devip->used = 1;
- memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
- if (scsi_debug_dsense)
- open_devip->sense_buff[0] = 0x72;
- else {
- open_devip->sense_buff[0] = 0x70;
- open_devip->sense_buff[7] = 0xa;
- }
if (sdev->lun == SAM2_WLUN_REPORT_LUNS)
open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff;
@@ -2462,7 +2682,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
static int scsi_debug_slave_alloc(struct scsi_device *sdp)
{
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n",
+ printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %llu>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue);
return 0;
@@ -2473,7 +2693,7 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp)
struct sdebug_dev_info *devip;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n",
+ printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %llu>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
@@ -2481,10 +2701,11 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp)
if (NULL == devip)
return 1; /* no resources, will be marked offline */
sdp->hostdata = devip;
+ sdp->tagged_supported = 1;
if (sdp->host->cmd_per_lun)
- scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
- sdp->host->cmd_per_lun);
- blk_queue_max_segment_size(sdp->request_queue, 256 * 1024);
+ scsi_adjust_queue_depth(sdp, DEF_TAGGED_QUEUING,
+ DEF_CMD_PER_LUN);
+ blk_queue_max_segment_size(sdp->request_queue, -1U);
if (scsi_debug_no_uld)
sdp->no_uld_attach = 1;
return 0;
@@ -2496,7 +2717,7 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp)
(struct sdebug_dev_info *)sdp->hostdata;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n",
+ printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %llu>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
if (devip) {
/* make this slot available for re-use */
@@ -2505,150 +2726,230 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp)
}
}
-/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */
+/* Returns 1 if cmnd found (deletes its timer or tasklet), else returns 0 */
static int stop_queued_cmnd(struct scsi_cmnd *cmnd)
{
unsigned long iflags;
- int k;
+ int k, qmax, r_qmax;
struct sdebug_queued_cmd *sqcp;
+ struct sdebug_dev_info *devip;
spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < scsi_debug_max_queue; ++k) {
- sqcp = &queued_arr[k];
- if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) {
- del_timer_sync(&sqcp->cmnd_timer);
- sqcp->in_use = 0;
- sqcp->a_cmnd = NULL;
- break;
+ qmax = scsi_debug_max_queue;
+ r_qmax = atomic_read(&retired_max_queue);
+ if (r_qmax > qmax)
+ qmax = r_qmax;
+ for (k = 0; k < qmax; ++k) {
+ if (test_bit(k, queued_in_use_bm)) {
+ sqcp = &queued_arr[k];
+ if (cmnd == sqcp->a_cmnd) {
+ if (scsi_debug_ndelay > 0) {
+ if (sqcp->sd_hrtp)
+ hrtimer_cancel(
+ &sqcp->sd_hrtp->hrt);
+ } else if (scsi_debug_delay > 0) {
+ if (sqcp->cmnd_timerp)
+ del_timer_sync(
+ sqcp->cmnd_timerp);
+ } else if (scsi_debug_delay < 0) {
+ if (sqcp->tletp)
+ tasklet_kill(sqcp->tletp);
+ }
+ __clear_bit(k, queued_in_use_bm);
+ devip = (struct sdebug_dev_info *)
+ cmnd->device->hostdata;
+ if (devip)
+ atomic_dec(&devip->num_in_q);
+ sqcp->a_cmnd = NULL;
+ break;
+ }
}
}
spin_unlock_irqrestore(&queued_arr_lock, iflags);
- return (k < scsi_debug_max_queue) ? 1 : 0;
+ return (k < qmax) ? 1 : 0;
}
-/* Deletes (stops) timers of all queued commands */
+/* Deletes (stops) timers or tasklets of all queued commands */
static void stop_all_queued(void)
{
unsigned long iflags;
int k;
struct sdebug_queued_cmd *sqcp;
+ struct sdebug_dev_info *devip;
spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < scsi_debug_max_queue; ++k) {
- sqcp = &queued_arr[k];
- if (sqcp->in_use && sqcp->a_cmnd) {
- del_timer_sync(&sqcp->cmnd_timer);
- sqcp->in_use = 0;
- sqcp->a_cmnd = NULL;
+ for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
+ if (test_bit(k, queued_in_use_bm)) {
+ sqcp = &queued_arr[k];
+ if (sqcp->a_cmnd) {
+ if (scsi_debug_ndelay > 0) {
+ if (sqcp->sd_hrtp)
+ hrtimer_cancel(
+ &sqcp->sd_hrtp->hrt);
+ } else if (scsi_debug_delay > 0) {
+ if (sqcp->cmnd_timerp)
+ del_timer_sync(
+ sqcp->cmnd_timerp);
+ } else if (scsi_debug_delay < 0) {
+ if (sqcp->tletp)
+ tasklet_kill(sqcp->tletp);
+ }
+ __clear_bit(k, queued_in_use_bm);
+ devip = (struct sdebug_dev_info *)
+ sqcp->a_cmnd->device->hostdata;
+ if (devip)
+ atomic_dec(&devip->num_in_q);
+ sqcp->a_cmnd = NULL;
+ }
}
}
spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
-static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
+/* Free queued command memory on heap */
+static void free_all_queued(void)
{
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: abort\n");
- ++num_aborts;
- stop_queued_cmnd(SCpnt);
- return SUCCESS;
+ unsigned long iflags;
+ int k;
+ struct sdebug_queued_cmd *sqcp;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) {
+ sqcp = &queued_arr[k];
+ kfree(sqcp->cmnd_timerp);
+ sqcp->cmnd_timerp = NULL;
+ kfree(sqcp->tletp);
+ sqcp->tletp = NULL;
+ kfree(sqcp->sd_hrtp);
+ sqcp->sd_hrtp = NULL;
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
-static int scsi_debug_biosparam(struct scsi_device *sdev,
- struct block_device * bdev, sector_t capacity, int *info)
+static int scsi_debug_abort(struct scsi_cmnd *SCpnt)
{
- int res;
- unsigned char *buf;
-
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: biosparam\n");
- buf = scsi_bios_ptable(bdev);
- if (buf) {
- res = scsi_partsize(buf, capacity,
- &info[2], &info[0], &info[1]);
- kfree(buf);
- if (! res)
- return res;
- }
- info[0] = sdebug_heads;
- info[1] = sdebug_sectors_per;
- info[2] = sdebug_cylinders_per;
- return 0;
+ ++num_aborts;
+ if (SCpnt) {
+ if (SCpnt->device &&
+ (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts))
+ sdev_printk(KERN_INFO, SCpnt->device, "%s\n",
+ __func__);
+ stop_queued_cmnd(SCpnt);
+ }
+ return SUCCESS;
}
static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
{
struct sdebug_dev_info * devip;
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: device_reset\n");
++num_dev_resets;
- if (SCpnt) {
- devip = devInfoReg(SCpnt->device);
+ if (SCpnt && SCpnt->device) {
+ struct scsi_device *sdp = SCpnt->device;
+
+ if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
+ devip = devInfoReg(sdp);
if (devip)
- devip->reset = 1;
+ set_bit(SDEBUG_UA_POR, devip->uas_bm);
+ }
+ return SUCCESS;
+}
+
+static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
+{
+ struct sdebug_host_info *sdbg_host;
+ struct sdebug_dev_info *devip;
+ struct scsi_device *sdp;
+ struct Scsi_Host *hp;
+ int k = 0;
+
+ ++num_target_resets;
+ if (!SCpnt)
+ goto lie;
+ sdp = SCpnt->device;
+ if (!sdp)
+ goto lie;
+ if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
+ hp = sdp->host;
+ if (!hp)
+ goto lie;
+ sdbg_host = *(struct sdebug_host_info **)shost_priv(hp);
+ if (sdbg_host) {
+ list_for_each_entry(devip,
+ &sdbg_host->dev_info_list,
+ dev_list)
+ if (devip->target == sdp->id) {
+ set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
+ ++k;
+ }
}
+ if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp,
+ "%s: %d device(s) found in target\n", __func__, k);
+lie:
return SUCCESS;
}
static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
{
struct sdebug_host_info *sdbg_host;
- struct sdebug_dev_info * dev_info;
+ struct sdebug_dev_info *devip;
struct scsi_device * sdp;
struct Scsi_Host * hp;
+ int k = 0;
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: bus_reset\n");
++num_bus_resets;
- if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) {
+ if (!(SCpnt && SCpnt->device))
+ goto lie;
+ sdp = SCpnt->device;
+ if (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
+ hp = sdp->host;
+ if (hp) {
sdbg_host = *(struct sdebug_host_info **)shost_priv(hp);
if (sdbg_host) {
- list_for_each_entry(dev_info,
+ list_for_each_entry(devip,
&sdbg_host->dev_info_list,
- dev_list)
- dev_info->reset = 1;
+ dev_list) {
+ set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
+ ++k;
+ }
}
}
+ if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp,
+ "%s: %d device(s) found in host\n", __func__, k);
+lie:
return SUCCESS;
}
static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
{
struct sdebug_host_info * sdbg_host;
- struct sdebug_dev_info * dev_info;
+ struct sdebug_dev_info *devip;
+ int k = 0;
- if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: host_reset\n");
++num_host_resets;
+ if ((SCpnt->device) && (SCSI_DEBUG_OPT_ALL_NOISE & scsi_debug_opts))
+ sdev_printk(KERN_INFO, SCpnt->device, "%s\n", __func__);
spin_lock(&sdebug_host_list_lock);
list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
- list_for_each_entry(dev_info, &sdbg_host->dev_info_list,
- dev_list)
- dev_info->reset = 1;
+ list_for_each_entry(devip, &sdbg_host->dev_info_list,
+ dev_list) {
+ set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
+ ++k;
+ }
}
spin_unlock(&sdebug_host_list_lock);
stop_all_queued();
+ if (SCSI_DEBUG_OPT_RESET_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s: %d device(s) found\n", __func__, k);
return SUCCESS;
}
-/* Initializes timers in queued array */
-static void __init init_all_queued(void)
-{
- unsigned long iflags;
- int k;
- struct sdebug_queued_cmd * sqcp;
-
- spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < scsi_debug_max_queue; ++k) {
- sqcp = &queued_arr[k];
- init_timer(&sqcp->cmnd_timer);
- sqcp->in_use = 0;
- sqcp->a_cmnd = NULL;
- }
- spin_unlock_irqrestore(&queued_arr_lock, iflags);
-}
-
static void __init sdebug_build_parts(unsigned char *ramp,
unsigned long store_size)
{
@@ -2662,8 +2963,8 @@ static void __init sdebug_build_parts(unsigned char *ramp,
return;
if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) {
scsi_debug_num_parts = SDEBUG_MAX_PARTS;
- printk(KERN_WARNING "scsi_debug:build_parts: reducing "
- "partitions to %d\n", SDEBUG_MAX_PARTS);
+ pr_warn("%s: reducing partitions to %d\n", __func__,
+ SDEBUG_MAX_PARTS);
}
num_sectors = (int)sdebug_store_sectors;
sectors_per_part = (num_sectors - sdebug_sectors_per)
@@ -2700,62 +3001,130 @@ static void __init sdebug_build_parts(unsigned char *ramp,
}
}
-static int schedule_resp(struct scsi_cmnd * cmnd,
- struct sdebug_dev_info * devip,
- done_funct_t done, int scsi_result, int delta_jiff)
+static int
+schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
+ int scsi_result, int delta_jiff)
{
- if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmnd) {
- if (scsi_result) {
- struct scsi_device * sdp = cmnd->device;
+ unsigned long iflags;
+ int k, num_in_q, tsf, qdepth, inject;
+ struct sdebug_queued_cmd *sqcp = NULL;
+ struct scsi_device *sdp = cmnd->device;
+
+ if (NULL == cmnd || NULL == devip) {
+ pr_warn("%s: called with NULL cmnd or devip pointer\n",
+ __func__);
+ /* no particularly good error to report back */
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+ if ((scsi_result) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
+ sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
+ __func__, scsi_result);
+ if (delta_jiff == 0) {
+ /* using same thread to call back mid-layer */
+ cmnd->result = scsi_result;
+ cmnd->scsi_done(cmnd);
+ return 0;
+ }
- printk(KERN_INFO "scsi_debug: <%u %u %u %u> "
- "non-zero result=0x%x\n", sdp->host->host_no,
- sdp->channel, sdp->id, sdp->lun, scsi_result);
+ /* deferred response cases */
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ num_in_q = atomic_read(&devip->num_in_q);
+ qdepth = cmnd->device->queue_depth;
+ k = find_first_zero_bit(queued_in_use_bm, scsi_debug_max_queue);
+ tsf = 0;
+ inject = 0;
+ if ((qdepth > 0) && (num_in_q >= qdepth))
+ tsf = 1;
+ else if ((scsi_debug_every_nth != 0) &&
+ (SCSI_DEBUG_OPT_RARE_TSF & scsi_debug_opts)) {
+ if ((num_in_q == (qdepth - 1)) &&
+ (atomic_inc_return(&sdebug_a_tsf) >=
+ abs(scsi_debug_every_nth))) {
+ atomic_set(&sdebug_a_tsf, 0);
+ inject = 1;
+ tsf = 1;
}
}
- if (cmnd && devip) {
- /* simulate autosense by this driver */
- if (SAM_STAT_CHECK_CONDITION == (scsi_result & 0xff))
- memcpy(cmnd->sense_buffer, devip->sense_buff,
- (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ?
- SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE);
- }
- if (delta_jiff <= 0) {
- if (cmnd)
- cmnd->result = scsi_result;
- if (done)
- done(cmnd);
- return 0;
- } else {
- unsigned long iflags;
- int k;
- struct sdebug_queued_cmd * sqcp = NULL;
- spin_lock_irqsave(&queued_arr_lock, iflags);
- for (k = 0; k < scsi_debug_max_queue; ++k) {
- sqcp = &queued_arr[k];
- if (! sqcp->in_use)
- break;
+ /* if (tsf) simulate device reporting SCSI status of TASK SET FULL.
+ * Might override existing CHECK CONDITION. */
+ if (tsf)
+ scsi_result = device_qfull_result;
+ if (k >= scsi_debug_max_queue) {
+ if (SCSI_DEBUG_OPT_ALL_TSF & scsi_debug_opts)
+ tsf = 1;
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, sdp,
+ "%s: num_in_q=%d, bypass q, %s%s\n",
+ __func__, num_in_q,
+ (inject ? "<inject> " : ""),
+ (tsf ? "status: TASK SET FULL" :
+ "report: host busy"));
+ if (tsf) {
+ /* queued_arr full so respond in same thread */
+ cmnd->result = scsi_result;
+ cmnd->scsi_done(cmnd);
+ /* As scsi_done() is called "inline" must return 0 */
+ return 0;
+ } else
+ return SCSI_MLQUEUE_HOST_BUSY;
+ }
+ __set_bit(k, queued_in_use_bm);
+ atomic_inc(&devip->num_in_q);
+ sqcp = &queued_arr[k];
+ sqcp->a_cmnd = cmnd;
+ cmnd->result = scsi_result;
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ if (delta_jiff > 0) {
+ if (NULL == sqcp->cmnd_timerp) {
+ sqcp->cmnd_timerp = kmalloc(sizeof(struct timer_list),
+ GFP_ATOMIC);
+ if (NULL == sqcp->cmnd_timerp)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ init_timer(sqcp->cmnd_timerp);
}
- if (k >= scsi_debug_max_queue) {
- spin_unlock_irqrestore(&queued_arr_lock, iflags);
- printk(KERN_WARNING "scsi_debug: can_queue exceeded\n");
- return 1; /* report busy to mid level */
+ sqcp->cmnd_timerp->function = sdebug_q_cmd_complete;
+ sqcp->cmnd_timerp->data = k;
+ sqcp->cmnd_timerp->expires = get_jiffies_64() + delta_jiff;
+ add_timer(sqcp->cmnd_timerp);
+ } else if (scsi_debug_ndelay > 0) {
+ ktime_t kt = ktime_set(0, scsi_debug_ndelay);
+ struct sdebug_hrtimer *sd_hp = sqcp->sd_hrtp;
+
+ if (NULL == sd_hp) {
+ sd_hp = kmalloc(sizeof(*sd_hp), GFP_ATOMIC);
+ if (NULL == sd_hp)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ sqcp->sd_hrtp = sd_hp;
+ hrtimer_init(&sd_hp->hrt, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ sd_hp->hrt.function = sdebug_q_cmd_hrt_complete;
+ sd_hp->qa_indx = k;
}
- sqcp->in_use = 1;
- sqcp->a_cmnd = cmnd;
- sqcp->scsi_result = scsi_result;
- sqcp->done_funct = done;
- sqcp->cmnd_timer.function = timer_intr_handler;
- sqcp->cmnd_timer.data = k;
- sqcp->cmnd_timer.expires = jiffies + delta_jiff;
- add_timer(&sqcp->cmnd_timer);
- spin_unlock_irqrestore(&queued_arr_lock, iflags);
- if (cmnd)
- cmnd->result = 0;
- return 0;
+ hrtimer_start(&sd_hp->hrt, kt, HRTIMER_MODE_REL);
+ } else { /* delay < 0 */
+ if (NULL == sqcp->tletp) {
+ sqcp->tletp = kmalloc(sizeof(*sqcp->tletp),
+ GFP_ATOMIC);
+ if (NULL == sqcp->tletp)
+ return SCSI_MLQUEUE_HOST_BUSY;
+ tasklet_init(sqcp->tletp,
+ sdebug_q_cmd_complete, k);
+ }
+ if (-1 == delta_jiff)
+ tasklet_hi_schedule(sqcp->tletp);
+ else
+ tasklet_schedule(sqcp->tletp);
}
+ if (tsf && (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts))
+ sdev_printk(KERN_INFO, sdp,
+ "%s: num_in_q=%d +1, %s%s\n", __func__,
+ num_in_q, (inject ? "<inject> " : ""),
+ "status: TASK SET FULL");
+ return 0;
}
+
/* Note: The following macros create attribute files in the
/sys/module/scsi_debug/parameters directory. Unfortunately this
driver is unaware of a change and cannot trigger auxiliary actions
@@ -2773,6 +3142,7 @@ module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR);
module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR);
module_param_named(fake_rw, scsi_debug_fake_rw, int, S_IRUGO | S_IWUSR);
module_param_named(guard, scsi_debug_guard, uint, S_IRUGO);
+module_param_named(host_lock, scsi_debug_host_lock, bool, S_IRUGO | S_IWUSR);
module_param_named(lbpu, scsi_debug_lbpu, int, S_IRUGO);
module_param_named(lbpws, scsi_debug_lbpws, int, S_IRUGO);
module_param_named(lbpws10, scsi_debug_lbpws10, int, S_IRUGO);
@@ -2780,6 +3150,7 @@ module_param_named(lbprz, scsi_debug_lbprz, int, S_IRUGO);
module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO);
module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR);
module_param_named(max_queue, scsi_debug_max_queue, int, S_IRUGO | S_IWUSR);
+module_param_named(ndelay, scsi_debug_ndelay, int, S_IRUGO | S_IWUSR);
module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR);
module_param_named(no_uld, scsi_debug_no_uld, int, S_IRUGO);
module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO);
@@ -2809,7 +3180,7 @@ MODULE_VERSION(SCSI_DEBUG_VERSION);
MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)");
MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)");
MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=0)");
-MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)");
+MODULE_PARM_DESC(delay, "response delay (def=1 jiffy); 0:imm, -1,-2:tiny");
MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)");
MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)");
MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)");
@@ -2817,13 +3188,15 @@ MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)");
MODULE_PARM_DESC(every_nth, "timeout every nth command(def=0)");
MODULE_PARM_DESC(fake_rw, "fake reads/writes instead of copying (def=0)");
MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)");
+MODULE_PARM_DESC(host_lock, "use host_lock around all commands (def=0)");
MODULE_PARM_DESC(lbpu, "enable LBP, support UNMAP command (def=0)");
MODULE_PARM_DESC(lbpws, "enable LBP, support WRITE SAME(16) with UNMAP bit (def=0)");
MODULE_PARM_DESC(lbpws10, "enable LBP, support WRITE SAME(10) with UNMAP bit (def=0)");
MODULE_PARM_DESC(lbprz, "unmapped blocks return 0 on read (def=1)");
MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)");
MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
-MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to 255(def))");
+MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to max(def))");
+MODULE_PARM_DESC(ndelay, "response delay in nanoseconds (def=0 -> ignore)");
MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))");
MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
@@ -2854,9 +3227,7 @@ static const char * scsi_debug_info(struct Scsi_Host * shp)
return sdebug_info;
}
-/* scsi_debug_proc_info
- * Used if the driver currently has no own support for /proc/scsi
- */
+/* 'echo <val> > /proc/scsi/scsi_debug/<host_id>' writes to opts */
static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int length)
{
char arr[16];
@@ -2871,27 +3242,49 @@ static int scsi_debug_write_info(struct Scsi_Host *host, char *buffer, int lengt
return -EINVAL;
scsi_debug_opts = opts;
if (scsi_debug_every_nth != 0)
- scsi_debug_cmnd_count = 0;
+ atomic_set(&sdebug_cmnd_count, 0);
return length;
}
+/* Output seen with 'cat /proc/scsi/scsi_debug/<host_id>'. It will be the
+ * same for each scsi_debug host (if more than one). Some of the counters
+ * output are not atomics so might be inaccurate in a busy system. */
static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host)
{
- seq_printf(m, "scsi_debug adapter driver, version "
- "%s [%s]\n"
- "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
- "every_nth=%d(curr:%d)\n"
- "delay=%d, max_luns=%d, scsi_level=%d\n"
- "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
- "number of aborts=%d, device_reset=%d, bus_resets=%d, "
- "host_resets=%d\ndix_reads=%d dix_writes=%d dif_errors=%d\n",
- SCSI_DEBUG_VERSION, scsi_debug_version_date, scsi_debug_num_tgts,
- scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
- scsi_debug_cmnd_count, scsi_debug_delay,
- scsi_debug_max_luns, scsi_debug_scsi_level,
- scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads,
- sdebug_sectors_per, num_aborts, num_dev_resets, num_bus_resets,
- num_host_resets, dix_reads, dix_writes, dif_errors);
+ int f, l;
+ char b[32];
+
+ if (scsi_debug_every_nth > 0)
+ snprintf(b, sizeof(b), " (curr:%d)",
+ ((SCSI_DEBUG_OPT_RARE_TSF & scsi_debug_opts) ?
+ atomic_read(&sdebug_a_tsf) :
+ atomic_read(&sdebug_cmnd_count)));
+ else
+ b[0] = '\0';
+
+ seq_printf(m, "scsi_debug adapter driver, version %s [%s]\n"
+ "num_tgts=%d, shared (ram) size=%d MB, opts=0x%x, "
+ "every_nth=%d%s\n"
+ "delay=%d, ndelay=%d, max_luns=%d, q_completions=%d\n"
+ "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d\n"
+ "command aborts=%d; RESETs: device=%d, target=%d, bus=%d, "
+ "host=%d\ndix_reads=%d dix_writes=%d dif_errors=%d "
+ "usec_in_jiffy=%lu\n",
+ SCSI_DEBUG_VERSION, scsi_debug_version_date,
+ scsi_debug_num_tgts, scsi_debug_dev_size_mb, scsi_debug_opts,
+ scsi_debug_every_nth, b, scsi_debug_delay, scsi_debug_ndelay,
+ scsi_debug_max_luns, atomic_read(&sdebug_completions),
+ scsi_debug_sector_size, sdebug_cylinders_per, sdebug_heads,
+ sdebug_sectors_per, num_aborts, num_dev_resets,
+ num_target_resets, num_bus_resets, num_host_resets,
+ dix_reads, dix_writes, dif_errors, TICK_NSEC / 1000);
+
+ f = find_first_bit(queued_in_use_bm, scsi_debug_max_queue);
+ if (f != scsi_debug_max_queue) {
+ l = find_last_bit(queued_in_use_bm, scsi_debug_max_queue);
+ seq_printf(m, " %s BUSY: first,last bits set: %d,%d\n",
+ "queued_in_use_bm", f, l);
+ }
return 0;
}
@@ -2899,23 +3292,69 @@ static ssize_t delay_show(struct device_driver *ddp, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_delay);
}
-
+/* Returns -EBUSY if delay is being changed and commands are queued */
static ssize_t delay_store(struct device_driver *ddp, const char *buf,
size_t count)
{
- int delay;
- char work[20];
-
- if (1 == sscanf(buf, "%10s", work)) {
- if ((1 == sscanf(work, "%d", &delay)) && (delay >= 0)) {
- scsi_debug_delay = delay;
- return count;
+ int delay, res;
+
+ if ((count > 0) && (1 == sscanf(buf, "%d", &delay))) {
+ res = count;
+ if (scsi_debug_delay != delay) {
+ unsigned long iflags;
+ int k;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ k = find_first_bit(queued_in_use_bm,
+ scsi_debug_max_queue);
+ if (k != scsi_debug_max_queue)
+ res = -EBUSY; /* have queued commands */
+ else {
+ scsi_debug_delay = delay;
+ scsi_debug_ndelay = 0;
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
}
+ return res;
}
return -EINVAL;
}
static DRIVER_ATTR_RW(delay);
+static ssize_t ndelay_show(struct device_driver *ddp, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_ndelay);
+}
+/* Returns -EBUSY if ndelay is being changed and commands are queued */
+/* If > 0 and accepted then scsi_debug_delay is set to DELAY_OVERRIDDEN */
+static ssize_t ndelay_store(struct device_driver *ddp, const char *buf,
+ size_t count)
+{
+ unsigned long iflags;
+ int ndelay, res, k;
+
+ if ((count > 0) && (1 == sscanf(buf, "%d", &ndelay)) &&
+ (ndelay >= 0) && (ndelay < 1000000000)) {
+ res = count;
+ if (scsi_debug_ndelay != ndelay) {
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ k = find_first_bit(queued_in_use_bm,
+ scsi_debug_max_queue);
+ if (k != scsi_debug_max_queue)
+ res = -EBUSY; /* have queued commands */
+ else {
+ scsi_debug_ndelay = ndelay;
+ scsi_debug_delay = ndelay ? DELAY_OVERRIDDEN
+ : DEF_DELAY;
+ }
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ }
+ return res;
+ }
+ return -EINVAL;
+}
+static DRIVER_ATTR_RW(ndelay);
+
static ssize_t opts_show(struct device_driver *ddp, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "0x%x\n", scsi_debug_opts);
@@ -2939,7 +3378,8 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf,
return -EINVAL;
opts_done:
scsi_debug_opts = opts;
- scsi_debug_cmnd_count = 0;
+ atomic_set(&sdebug_cmnd_count, 0);
+ atomic_set(&sdebug_a_tsf, 0);
return count;
}
static DRIVER_ATTR_RW(opts);
@@ -2988,7 +3428,24 @@ static ssize_t fake_rw_store(struct device_driver *ddp, const char *buf,
int n;
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
- scsi_debug_fake_rw = n;
+ n = (n > 0);
+ scsi_debug_fake_rw = (scsi_debug_fake_rw > 0);
+ if (scsi_debug_fake_rw != n) {
+ if ((0 == n) && (NULL == fake_storep)) {
+ unsigned long sz =
+ (unsigned long)scsi_debug_dev_size_mb *
+ 1048576;
+
+ fake_storep = vmalloc(sz);
+ if (NULL == fake_storep) {
+ pr_err("%s: out of memory, 9\n",
+ __func__);
+ return -ENOMEM;
+ }
+ memset(fake_storep, 0, sz);
+ }
+ scsi_debug_fake_rw = n;
+ }
return count;
}
return -EINVAL;
@@ -3053,7 +3510,7 @@ static ssize_t every_nth_store(struct device_driver *ddp, const char *buf,
if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) {
scsi_debug_every_nth = nth;
- scsi_debug_cmnd_count = 0;
+ atomic_set(&sdebug_cmnd_count, 0);
return count;
}
return -EINVAL;
@@ -3082,14 +3539,26 @@ static ssize_t max_queue_show(struct device_driver *ddp, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_max_queue);
}
+/* N.B. max_queue can be changed while there are queued commands. In flight
+ * commands beyond the new max_queue will be completed. */
static ssize_t max_queue_store(struct device_driver *ddp, const char *buf,
size_t count)
{
- int n;
+ unsigned long iflags;
+ int n, k;
if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n > 0) &&
(n <= SCSI_DEBUG_CANQUEUE)) {
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ k = find_last_bit(queued_in_use_bm, SCSI_DEBUG_CANQUEUE);
scsi_debug_max_queue = n;
+ if (SCSI_DEBUG_CANQUEUE == k)
+ atomic_set(&retired_max_queue, 0);
+ else if (k >= n)
+ atomic_set(&retired_max_queue, k + 1);
+ else
+ atomic_set(&retired_max_queue, 0);
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
return count;
}
return -EINVAL;
@@ -3234,6 +3703,40 @@ static ssize_t removable_store(struct device_driver *ddp, const char *buf,
}
static DRIVER_ATTR_RW(removable);
+static ssize_t host_lock_show(struct device_driver *ddp, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n", !!scsi_debug_host_lock);
+}
+/* Returns -EBUSY if host_lock is being changed and commands are queued */
+static ssize_t host_lock_store(struct device_driver *ddp, const char *buf,
+ size_t count)
+{
+ int n, res;
+
+ if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
+ bool new_host_lock = (n > 0);
+
+ res = count;
+ if (new_host_lock != scsi_debug_host_lock) {
+ unsigned long iflags;
+ int k;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ k = find_first_bit(queued_in_use_bm,
+ scsi_debug_max_queue);
+ if (k != scsi_debug_max_queue)
+ res = -EBUSY; /* have queued commands */
+ else
+ scsi_debug_host_lock = new_host_lock;
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ }
+ return res;
+ }
+ return -EINVAL;
+}
+static DRIVER_ATTR_RW(host_lock);
+
+
/* Note: The following array creates attribute files in the
/sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
files (over those found in the /sys/module/scsi_debug/parameters
@@ -3266,6 +3769,8 @@ static struct attribute *sdebug_drv_attrs[] = {
&driver_attr_ato.attr,
&driver_attr_map.attr,
&driver_attr_removable.attr,
+ &driver_attr_host_lock.attr,
+ &driver_attr_ndelay.attr,
NULL,
};
ATTRIBUTE_GROUPS(sdebug_drv);
@@ -3279,6 +3784,17 @@ static int __init scsi_debug_init(void)
int k;
int ret;
+ atomic_set(&sdebug_cmnd_count, 0);
+ atomic_set(&sdebug_completions, 0);
+ atomic_set(&retired_max_queue, 0);
+
+ if (scsi_debug_ndelay >= 1000000000) {
+ pr_warn("%s: ndelay must be less than 1 second, ignored\n",
+ __func__);
+ scsi_debug_ndelay = 0;
+ } else if (scsi_debug_ndelay > 0)
+ scsi_debug_delay = DELAY_OVERRIDDEN;
+
switch (scsi_debug_sector_size) {
case 512:
case 1024:
@@ -3286,7 +3802,7 @@ static int __init scsi_debug_init(void)
case 4096:
break;
default:
- printk(KERN_ERR "scsi_debug_init: invalid sector_size %d\n",
+ pr_err("%s: invalid sector_size %d\n", __func__,
scsi_debug_sector_size);
return -EINVAL;
}
@@ -3300,28 +3816,28 @@ static int __init scsi_debug_init(void)
break;
default:
- printk(KERN_ERR "scsi_debug_init: dif must be 0, 1, 2 or 3\n");
+ pr_err("%s: dif must be 0, 1, 2 or 3\n", __func__);
return -EINVAL;
}
if (scsi_debug_guard > 1) {
- printk(KERN_ERR "scsi_debug_init: guard must be 0 or 1\n");
+ pr_err("%s: guard must be 0 or 1\n", __func__);
return -EINVAL;
}
if (scsi_debug_ato > 1) {
- printk(KERN_ERR "scsi_debug_init: ato must be 0 or 1\n");
+ pr_err("%s: ato must be 0 or 1\n", __func__);
return -EINVAL;
}
if (scsi_debug_physblk_exp > 15) {
- printk(KERN_ERR "scsi_debug_init: invalid physblk_exp %u\n",
+ pr_err("%s: invalid physblk_exp %u\n", __func__,
scsi_debug_physblk_exp);
return -EINVAL;
}
if (scsi_debug_lowest_aligned > 0x3fff) {
- printk(KERN_ERR "scsi_debug_init: lowest_aligned too big: %u\n",
+ pr_err("%s: lowest_aligned too big: %u\n", __func__,
scsi_debug_lowest_aligned);
return -EINVAL;
}
@@ -3349,14 +3865,16 @@ static int __init scsi_debug_init(void)
(sdebug_sectors_per * sdebug_heads);
}
- fake_storep = vmalloc(sz);
- if (NULL == fake_storep) {
- printk(KERN_ERR "scsi_debug_init: out of memory, 1\n");
- return -ENOMEM;
+ if (0 == scsi_debug_fake_rw) {
+ fake_storep = vmalloc(sz);
+ if (NULL == fake_storep) {
+ pr_err("%s: out of memory, 1\n", __func__);
+ return -ENOMEM;
+ }
+ memset(fake_storep, 0, sz);
+ if (scsi_debug_num_parts > 0)
+ sdebug_build_parts(fake_storep, sz);
}
- memset(fake_storep, 0, sz);
- if (scsi_debug_num_parts > 0)
- sdebug_build_parts(fake_storep, sz);
if (scsi_debug_dix) {
int dif_size;
@@ -3364,11 +3882,11 @@ static int __init scsi_debug_init(void)
dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);
dif_storep = vmalloc(dif_size);
- printk(KERN_ERR "scsi_debug_init: dif_storep %u bytes @ %p\n",
- dif_size, dif_storep);
+ pr_err("%s: dif_storep %u bytes @ %p\n", __func__, dif_size,
+ dif_storep);
if (dif_storep == NULL) {
- printk(KERN_ERR "scsi_debug_init: out of mem. (DIX)\n");
+ pr_err("%s: out of mem. (DIX)\n", __func__);
ret = -ENOMEM;
goto free_vm;
}
@@ -3390,8 +3908,7 @@ static int __init scsi_debug_init(void)
if (scsi_debug_unmap_alignment &&
scsi_debug_unmap_granularity <=
scsi_debug_unmap_alignment) {
- printk(KERN_ERR
- "%s: ERR: unmap_granularity <= unmap_alignment\n",
+ pr_err("%s: ERR: unmap_granularity <= unmap_alignment\n",
__func__);
return -EINVAL;
}
@@ -3399,11 +3916,10 @@ static int __init scsi_debug_init(void)
map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1;
map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long));
- printk(KERN_INFO "scsi_debug_init: %lu provisioning blocks\n",
- map_size);
+ pr_info("%s: %lu provisioning blocks\n", __func__, map_size);
if (map_storep == NULL) {
- printk(KERN_ERR "scsi_debug_init: out of mem. (MAP)\n");
+ pr_err("%s: out of mem. (MAP)\n", __func__);
ret = -ENOMEM;
goto free_vm;
}
@@ -3417,39 +3933,35 @@ static int __init scsi_debug_init(void)
pseudo_primary = root_device_register("pseudo_0");
if (IS_ERR(pseudo_primary)) {
- printk(KERN_WARNING "scsi_debug: root_device_register() error\n");
+ pr_warn("%s: root_device_register() error\n", __func__);
ret = PTR_ERR(pseudo_primary);
goto free_vm;
}
ret = bus_register(&pseudo_lld_bus);
if (ret < 0) {
- printk(KERN_WARNING "scsi_debug: bus_register error: %d\n",
- ret);
+ pr_warn("%s: bus_register error: %d\n", __func__, ret);
goto dev_unreg;
}
ret = driver_register(&sdebug_driverfs_driver);
if (ret < 0) {
- printk(KERN_WARNING "scsi_debug: driver_register error: %d\n",
- ret);
+ pr_warn("%s: driver_register error: %d\n", __func__, ret);
goto bus_unreg;
}
- init_all_queued();
-
host_to_add = scsi_debug_add_host;
scsi_debug_add_host = 0;
for (k = 0; k < host_to_add; k++) {
if (sdebug_add_adapter()) {
- printk(KERN_ERR "scsi_debug_init: "
- "sdebug_add_adapter failed k=%d\n", k);
+ pr_err("%s: sdebug_add_adapter failed k=%d\n",
+ __func__, k);
break;
}
}
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
- printk(KERN_INFO "scsi_debug_init: built %d host(s)\n",
- scsi_debug_add_host);
+ pr_info("%s: built %d host(s)\n", __func__,
+ scsi_debug_add_host);
}
return 0;
@@ -3472,6 +3984,7 @@ static void __exit scsi_debug_exit(void)
int k = scsi_debug_add_host;
stop_all_queued();
+ free_all_queued();
for (; k; k--)
sdebug_remove_adapter();
driver_unregister(&sdebug_driverfs_driver);
@@ -3569,8 +4082,8 @@ static void sdebug_remove_adapter(void)
--scsi_debug_add_host;
}
-static
-int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
+static int
+scsi_debug_queuecommand(struct scsi_cmnd *SCpnt)
{
unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
int len, k;
@@ -3589,32 +4102,34 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
int unmap = 0;
scsi_set_resid(SCpnt, 0);
- if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
- printk(KERN_INFO "scsi_debug: cmd ");
- for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
- printk("%02x ", (int)cmd[k]);
- printk("\n");
- }
-
- if (target == SCpnt->device->host->hostt->this_id) {
- printk(KERN_INFO "scsi_debug: initiator's id used as "
- "target!\n");
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
+ if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) &&
+ !(SCSI_DEBUG_OPT_NO_CDB_NOISE & scsi_debug_opts) && cmd) {
+ char b[120];
+ int n;
+
+ len = SCpnt->cmd_len;
+ if (len > 32)
+ strcpy(b, "too long, over 32 bytes");
+ else {
+ for (k = 0, n = 0; k < len; ++k)
+ n += scnprintf(b + n, sizeof(b) - n, "%02x ",
+ (unsigned int)cmd[k]);
+ }
+ sdev_printk(KERN_INFO, SCpnt->device, "%s: cmd %s\n", my_name,
+ b);
}
if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
(SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
+ return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0);
devip = devInfoReg(SCpnt->device);
if (NULL == devip)
- return schedule_resp(SCpnt, NULL, done,
- DID_NO_CONNECT << 16, 0);
+ return schedule_resp(SCpnt, NULL, DID_NO_CONNECT << 16, 0);
if ((scsi_debug_every_nth != 0) &&
- (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
- scsi_debug_cmnd_count = 0;
+ (atomic_inc_return(&sdebug_cmnd_count) >=
+ abs(scsi_debug_every_nth))) {
+ atomic_set(&sdebug_cmnd_count, 0);
if (scsi_debug_every_nth < -1)
scsi_debug_every_nth = -1;
if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
@@ -3645,11 +4160,10 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
"not supported for wlun\n", *cmd);
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_OPCODE, 0);
errsts = check_condition_result;
- return schedule_resp(SCpnt, devip, done, errsts,
- 0);
+ return schedule_resp(SCpnt, devip, errsts, 0);
}
}
@@ -3667,7 +4181,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
errsts = resp_start_stop(SCpnt, devip);
break;
case ALLOW_MEDIUM_REMOVAL:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
if (errsts)
break;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
@@ -3675,23 +4189,23 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
cmd[4] ? "inhibited" : "enabled");
break;
case SEND_DIAGNOSTIC: /* mandatory */
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case TEST_UNIT_READY: /* mandatory */
- delay_override = 1;
- errsts = check_readiness(SCpnt, 0, devip);
+ /* delay_override = 1; */
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
break;
case RESERVE:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case RESERVE_10:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case RELEASE:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case RELEASE_10:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case READ_CAPACITY:
errsts = resp_readcap(SCpnt, devip);
@@ -3702,20 +4216,20 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
else if (cmd[1] == SAI_GET_LBA_STATUS) {
if (scsi_debug_lbp() == 0) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
} else
errsts = resp_get_lba_status(SCpnt, devip);
} else {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_OPCODE, 0);
errsts = check_condition_result;
}
break;
case MAINTENANCE_IN:
if (MI_REPORT_TARGET_PGS != cmd[1]) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_OPCODE, 0);
errsts = check_condition_result;
break;
@@ -3728,7 +4242,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
/* READ{10,12,16} and DIF Type 2 are natural enemies */
if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
cmd[1] & 0xe0) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
break;
@@ -3742,7 +4256,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
/* fall through */
case READ_6:
read:
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
if (errsts)
break;
if (scsi_debug_fake_rw)
@@ -3752,20 +4266,21 @@ read:
if (inj_short)
num /= 2;
- errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
+ errsts = resp_read(SCpnt, lba, num, ei_lba);
if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
+ mk_sense_buffer(SCpnt, RECOVERED_ERROR,
THRESHOLD_EXCEEDED, 0);
errsts = check_condition_result;
} else if (inj_transport && (0 == errsts)) {
- mk_sense_buffer(devip, ABORTED_COMMAND,
+ mk_sense_buffer(SCpnt, ABORTED_COMMAND,
TRANSPORT_PROBLEM, ACK_NAK_TO);
errsts = check_condition_result;
} else if (inj_dif && (0 == errsts)) {
- mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1);
+ /* Logical block guard check failed */
+ mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1);
errsts = illegal_condition_result;
} else if (inj_dix && (0 == errsts)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1);
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1);
errsts = illegal_condition_result;
}
break;
@@ -3774,7 +4289,7 @@ read:
errsts = resp_report_luns(SCpnt, devip);
break;
case VERIFY: /* 10 byte SBC-2 command */
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
break;
case WRITE_16:
case WRITE_12:
@@ -3782,7 +4297,7 @@ read:
/* WRITE{10,12,16} and DIF Type 2 are natural enemies */
if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
cmd[1] & 0xe0) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
break;
@@ -3796,22 +4311,22 @@ read:
/* fall through */
case WRITE_6:
write:
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
if (errsts)
break;
if (scsi_debug_fake_rw)
break;
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
- errsts = resp_write(SCpnt, lba, num, devip, ei_lba);
+ errsts = resp_write(SCpnt, lba, num, ei_lba);
if (inj_recovered && (0 == errsts)) {
- mk_sense_buffer(devip, RECOVERED_ERROR,
+ mk_sense_buffer(SCpnt, RECOVERED_ERROR,
THRESHOLD_EXCEEDED, 0);
errsts = check_condition_result;
} else if (inj_dif && (0 == errsts)) {
- mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, 1);
+ mk_sense_buffer(SCpnt, ABORTED_COMMAND, 0x10, 1);
errsts = illegal_condition_result;
} else if (inj_dix && (0 == errsts)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, 1);
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, 0x10, 1);
errsts = illegal_condition_result;
}
break;
@@ -3820,7 +4335,7 @@ write:
if (cmd[1] & 0x8) {
if ((*cmd == WRITE_SAME_16 && scsi_debug_lbpws == 0) ||
(*cmd == WRITE_SAME && scsi_debug_lbpws10 == 0)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
errsts = check_condition_result;
} else
@@ -3828,19 +4343,23 @@ write:
}
if (errsts)
break;
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
if (errsts)
break;
+ if (scsi_debug_fake_rw)
+ break;
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
- errsts = resp_write_same(SCpnt, lba, num, devip, ei_lba, unmap);
+ errsts = resp_write_same(SCpnt, lba, num, ei_lba, unmap);
break;
case UNMAP:
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
if (errsts)
break;
+ if (scsi_debug_fake_rw)
+ break;
if (scsi_debug_unmap_max_desc == 0 || scsi_debug_lbpu == 0) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_COMMAND_OPCODE, 0);
errsts = check_condition_result;
} else
@@ -3861,29 +4380,29 @@ write:
break;
case SYNCHRONIZE_CACHE:
delay_override = 1;
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
break;
case WRITE_BUFFER:
- errsts = check_readiness(SCpnt, 1, devip);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
break;
case XDWRITEREAD_10:
if (!scsi_bidi_cmnd(SCpnt)) {
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
errsts = check_condition_result;
break;
}
- errsts = check_readiness(SCpnt, 0, devip);
+ errsts = check_readiness(SCpnt, UAS_TUR, devip);
if (errsts)
break;
if (scsi_debug_fake_rw)
break;
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
- errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
+ errsts = resp_read(SCpnt, lba, num, ei_lba);
if (errsts)
break;
- errsts = resp_write(SCpnt, lba, num, devip, ei_lba);
+ errsts = resp_write(SCpnt, lba, num, ei_lba);
if (errsts)
break;
errsts = resp_xdwriteread(SCpnt, lba, num, devip);
@@ -3906,27 +4425,138 @@ write:
}
}
- mk_sense_buffer(devip, ILLEGAL_REQUEST,
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
INVALID_FIELD_IN_CDB, 0);
errsts = check_condition_result;
break;
-
+ case 0x85:
+ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s: ATA PASS-THROUGH(16) not supported\n", my_name);
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST,
+ INVALID_OPCODE, 0);
+ errsts = check_condition_result;
+ break;
default:
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
- printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
- "supported\n", *cmd);
- errsts = check_readiness(SCpnt, 1, devip);
+ sdev_printk(KERN_INFO, SCpnt->device,
+ "%s: Opcode: 0x%x not supported\n",
+ my_name, *cmd);
+ errsts = check_readiness(SCpnt, UAS_ONLY, devip);
if (errsts)
break; /* Unit attention takes precedence */
- mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
+ mk_sense_buffer(SCpnt, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
errsts = check_condition_result;
break;
}
- return schedule_resp(SCpnt, devip, done, errsts,
+ return schedule_resp(SCpnt, devip, errsts,
(delay_override ? 0 : scsi_debug_delay));
}
-static DEF_SCSI_QCMD(scsi_debug_queuecommand)
+static int
+sdebug_queuecommand_lock_or_not(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+{
+ if (scsi_debug_host_lock) {
+ unsigned long iflags;
+ int rc;
+
+ spin_lock_irqsave(shost->host_lock, iflags);
+ rc = scsi_debug_queuecommand(cmd);
+ spin_unlock_irqrestore(shost->host_lock, iflags);
+ return rc;
+ } else
+ return scsi_debug_queuecommand(cmd);
+}
+
+static int
+sdebug_change_qdepth(struct scsi_device *sdev, int qdepth, int reason)
+{
+ int num_in_q = 0;
+ int bad = 0;
+ unsigned long iflags;
+ struct sdebug_dev_info *devip;
+
+ spin_lock_irqsave(&queued_arr_lock, iflags);
+ devip = (struct sdebug_dev_info *)sdev->hostdata;
+ if (NULL == devip) {
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ return -ENODEV;
+ }
+ num_in_q = atomic_read(&devip->num_in_q);
+ spin_unlock_irqrestore(&queued_arr_lock, iflags);
+ if (reason == SCSI_QDEPTH_DEFAULT || reason == SCSI_QDEPTH_RAMP_UP) {
+ if (qdepth < 1)
+ qdepth = 1;
+ /* allow to exceed max host queued_arr elements for testing */
+ if (qdepth > SCSI_DEBUG_CANQUEUE + 10)
+ qdepth = SCSI_DEBUG_CANQUEUE + 10;
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+ } else if (reason == SCSI_QDEPTH_QFULL)
+ scsi_track_queue_full(sdev, qdepth);
+ else
+ bad = 1;
+ if (bad)
+ sdev_printk(KERN_WARNING, sdev,
+ "%s: unknown reason=0x%x\n", __func__, reason);
+ if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) {
+ if (SCSI_QDEPTH_QFULL == reason)
+ sdev_printk(KERN_INFO, sdev,
+ "%s: -> %d, num_in_q=%d, reason: queue full\n",
+ __func__, qdepth, num_in_q);
+ else {
+ const char *cp;
+
+ switch (reason) {
+ case SCSI_QDEPTH_DEFAULT:
+ cp = "default (sysfs ?)";
+ break;
+ case SCSI_QDEPTH_RAMP_UP:
+ cp = "ramp up";
+ break;
+ default:
+ cp = "unknown";
+ break;
+ }
+ sdev_printk(KERN_INFO, sdev,
+ "%s: qdepth=%d, num_in_q=%d, reason: %s\n",
+ __func__, qdepth, num_in_q, cp);
+ }
+ }
+ return sdev->queue_depth;
+}
+
+static int
+sdebug_change_qtype(struct scsi_device *sdev, int qtype)
+{
+ if (sdev->tagged_supported) {
+ scsi_set_tag_type(sdev, qtype);
+ if (qtype)
+ scsi_activate_tcq(sdev, sdev->queue_depth);
+ else
+ scsi_deactivate_tcq(sdev, sdev->queue_depth);
+ } else
+ qtype = 0;
+ if (SCSI_DEBUG_OPT_Q_NOISE & scsi_debug_opts) {
+ const char *cp;
+
+ switch (qtype) {
+ case 0:
+ cp = "untagged";
+ break;
+ case MSG_SIMPLE_TAG:
+ cp = "simple tags";
+ break;
+ case MSG_ORDERED_TAG:
+ cp = "ordered tags";
+ break;
+ default:
+ cp = "unknown";
+ break;
+ }
+ sdev_printk(KERN_INFO, sdev, "%s: to %s\n", __func__, cp);
+ }
+ return qtype;
+}
static struct scsi_host_template sdebug_driver_template = {
.show_info = scsi_debug_show_info,
@@ -3938,17 +4568,19 @@ static struct scsi_host_template sdebug_driver_template = {
.slave_configure = scsi_debug_slave_configure,
.slave_destroy = scsi_debug_slave_destroy,
.ioctl = scsi_debug_ioctl,
- .queuecommand = scsi_debug_queuecommand,
+ .queuecommand = sdebug_queuecommand_lock_or_not,
+ .change_queue_depth = sdebug_change_qdepth,
+ .change_queue_type = sdebug_change_qtype,
.eh_abort_handler = scsi_debug_abort,
- .eh_bus_reset_handler = scsi_debug_bus_reset,
.eh_device_reset_handler = scsi_debug_device_reset,
+ .eh_target_reset_handler = scsi_debug_target_reset,
+ .eh_bus_reset_handler = scsi_debug_bus_reset,
.eh_host_reset_handler = scsi_debug_host_reset,
- .bios_param = scsi_debug_biosparam,
.can_queue = SCSI_DEBUG_CANQUEUE,
.this_id = 7,
- .sg_tablesize = 256,
- .cmd_per_lun = 16,
- .max_sectors = 0xffff,
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .cmd_per_lun = DEF_CMD_PER_LUN,
+ .max_sectors = -1U,
.use_clustering = DISABLE_CLUSTERING,
.module = THIS_MODULE,
};
@@ -4032,8 +4664,7 @@ static int sdebug_driver_probe(struct device * dev)
} else
scsi_scan_host(hpnt);
-
- return error;
+ return error;
}
static int sdebug_driver_remove(struct device * dev)
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index f969aca0b54e..49014a143c6a 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -222,6 +222,7 @@ static struct {
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
{"Promise", "", NULL, BLIST_SPARSELUN},
{"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index cbe38e5e7955..5db8454474ee 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -59,11 +59,11 @@ static int scsi_try_to_abort_cmd(struct scsi_host_template *,
/* called with shost->host_lock held */
void scsi_eh_wakeup(struct Scsi_Host *shost)
{
- if (shost->host_busy == shost->host_failed) {
+ if (atomic_read(&shost->host_busy) == shost->host_failed) {
trace_scsi_eh_wakeup(shost);
wake_up_process(shost->ehandler);
- SCSI_LOG_ERROR_RECOVERY(5,
- printk("Waking error handler thread\n"));
+ SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost,
+ "Waking error handler thread\n"));
}
}
@@ -131,7 +131,7 @@ scmd_eh_abort_handler(struct work_struct *work)
"aborting command %p\n", scmd));
rtn = scsi_try_to_abort_cmd(sdev->host->hostt, scmd);
if (rtn == SUCCESS) {
- scmd->result |= DID_TIME_OUT << 16;
+ set_host_byte(scmd, DID_TIME_OUT);
if (scsi_host_eh_past_deadline(sdev->host)) {
SCSI_LOG_ERROR_RECOVERY(3,
scmd_printk(KERN_INFO, scmd,
@@ -167,7 +167,7 @@ scmd_eh_abort_handler(struct work_struct *work)
scmd_printk(KERN_WARNING, scmd,
"scmd %p terminate "
"aborted command\n", scmd));
- scmd->result |= DID_TIME_OUT << 16;
+ set_host_byte(scmd, DID_TIME_OUT);
scsi_finish_command(scmd);
}
}
@@ -193,7 +193,7 @@ scsi_abort_command(struct scsi_cmnd *scmd)
SCSI_LOG_ERROR_RECOVERY(3,
scmd_printk(KERN_INFO, scmd,
"scmd %p previous abort failed\n", scmd));
- cancel_delayed_work(&scmd->abort_work);
+ BUG_ON(delayed_work_pending(&scmd->abort_work));
return FAILED;
}
@@ -287,15 +287,15 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
else if (host->hostt->eh_timed_out)
rtn = host->hostt->eh_timed_out(scmd);
- if (rtn == BLK_EH_NOT_HANDLED && !host->hostt->no_async_abort)
- if (scsi_abort_command(scmd) == SUCCESS)
+ if (rtn == BLK_EH_NOT_HANDLED) {
+ if (!host->hostt->no_async_abort &&
+ scsi_abort_command(scmd) == SUCCESS)
return BLK_EH_NOT_HANDLED;
- scmd->result |= DID_TIME_OUT << 16;
-
- if (unlikely(rtn == BLK_EH_NOT_HANDLED &&
- !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)))
- rtn = BLK_EH_HANDLED;
+ set_host_byte(scmd, DID_TIME_OUT);
+ if (!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))
+ rtn = BLK_EH_HANDLED;
+ }
return rtn;
}
@@ -319,8 +319,8 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
online = scsi_device_online(sdev);
- SCSI_LOG_ERROR_RECOVERY(5, printk("%s: rtn: %d\n", __func__,
- online));
+ SCSI_LOG_ERROR_RECOVERY(5, sdev_printk(KERN_INFO, sdev,
+ "%s: rtn: %d\n", __func__, online));
return online;
}
@@ -365,8 +365,9 @@ static inline void scsi_eh_prt_fail_stats(struct Scsi_Host *shost,
}
}
- SCSI_LOG_ERROR_RECOVERY(2, printk("Total of %d commands on %d"
- " devices require eh work\n",
+ SCSI_LOG_ERROR_RECOVERY(2, shost_printk(KERN_INFO, shost,
+ "Total of %d commands on %d"
+ " devices require eh work\n",
total_failures, devices_failed));
}
#endif
@@ -738,8 +739,8 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
{
struct completion *eh_action;
- SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s scmd: %p result: %x\n",
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "%s scmd: %p result: %x\n",
__func__, scmd, scmd->result));
eh_action = scmd->device->host->eh_action;
@@ -758,8 +759,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
struct Scsi_Host *host = scmd->device->host;
struct scsi_host_template *hostt = host->hostt;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
- __func__));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, host, "Snd Host RST\n"));
if (!hostt->eh_host_reset_handler)
return FAILED;
@@ -788,8 +789,8 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
struct Scsi_Host *host = scmd->device->host;
struct scsi_host_template *hostt = host->hostt;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
- __func__));
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "%s: Snd Bus RST\n", __func__));
if (!hostt->eh_bus_reset_handler)
return FAILED;
@@ -1036,8 +1037,8 @@ retry:
scsi_log_completion(scmd, rtn);
- SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s: scmd: %p, timeleft: %ld\n",
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "%s: scmd: %p, timeleft: %ld\n",
__func__, scmd, timeleft));
/*
@@ -1051,9 +1052,8 @@ retry:
*/
if (timeleft) {
rtn = scsi_eh_completed_normally(scmd);
- SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s: scsi_eh_completed_normally %x\n",
- __func__, rtn));
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "%s: scsi_eh_completed_normally %x\n", __func__, rtn));
switch (rtn) {
case SUCCESS:
@@ -1177,9 +1177,9 @@ int scsi_eh_get_sense(struct list_head *work_q,
if (rtn != SUCCESS)
continue;
- SCSI_LOG_ERROR_RECOVERY(3, printk("sense requested for %p"
- " result %x\n", scmd,
- scmd->result));
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "sense requested for %p result %x\n",
+ scmd, scmd->result));
SCSI_LOG_ERROR_RECOVERY(3, scsi_print_sense("bh", scmd));
rtn = scsi_decide_disposition(scmd);
@@ -1220,8 +1220,8 @@ retry_tur:
rtn = scsi_send_eh_cmnd(scmd, tur_command, 6,
scmd->device->eh_timeout, 0);
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
- __func__, scmd, rtn));
+ SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+ "%s: scmd %p rtn %x\n", __func__, scmd, rtn));
switch (rtn) {
case NEEDS_RETRY:
@@ -1323,16 +1323,16 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
__func__));
return list_empty(work_q);
}
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting cmd:"
- "0x%p\n", current->comm,
- scmd));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: aborting cmd: 0x%p\n",
+ current->comm, scmd));
rtn = scsi_try_to_abort_cmd(shost->hostt, scmd);
if (rtn == FAILED) {
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting"
- " cmd failed:"
- "0x%p\n",
- current->comm,
- scmd));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: aborting cmd failed: 0x%p\n",
+ current->comm, scmd));
list_splice_init(&check_list, work_q);
return list_empty(work_q);
}
@@ -1406,8 +1406,10 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
if (!stu_scmd)
continue;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending START_UNIT to sdev:"
- " 0x%p\n", current->comm, sdev));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Sending START_UNIT to sdev: 0x%p\n",
+ current->comm, sdev));
if (!scsi_eh_try_stu(stu_scmd)) {
if (!scsi_device_online(sdev) ||
@@ -1421,8 +1423,9 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
}
} else {
SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s: START_UNIT failed to sdev:"
- " 0x%p\n", current->comm, sdev));
+ shost_printk(KERN_INFO, shost,
+ "%s: START_UNIT failed to sdev:"
+ " 0x%p\n", current->comm, sdev));
}
}
@@ -1468,9 +1471,10 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
if (!bdr_scmd)
continue;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending BDR sdev:"
- " 0x%p\n", current->comm,
- sdev));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Sending BDR sdev: 0x%p\n",
+ current->comm, sdev));
rtn = scsi_try_bus_device_reset(bdr_scmd);
if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
if (!scsi_device_online(sdev) ||
@@ -1485,11 +1489,10 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
}
}
} else {
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: BDR"
- " failed sdev:"
- "0x%p\n",
- current->comm,
- sdev));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: BDR failed sdev: 0x%p\n",
+ current->comm, sdev));
}
}
@@ -1533,15 +1536,17 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
scmd = list_entry(tmp_list.next, struct scsi_cmnd, eh_entry);
id = scmd_id(scmd);
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
- "to target %d\n",
- current->comm, id));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Sending target reset to target %d\n",
+ current->comm, id));
rtn = scsi_try_target_reset(scmd);
if (rtn != SUCCESS && rtn != FAST_IO_FAIL)
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset"
- " failed target: "
- "%d\n",
- current->comm, id));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Target reset failed"
+ " target: %d\n",
+ current->comm, id));
list_for_each_entry_safe(scmd, next, &tmp_list, eh_entry) {
if (scmd_id(scmd) != id)
continue;
@@ -1605,9 +1610,10 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
if (!chan_scmd)
continue;
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending BRST chan:"
- " %d\n", current->comm,
- channel));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Sending BRST chan: %d\n",
+ current->comm, channel));
rtn = scsi_try_bus_reset(chan_scmd);
if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
@@ -1621,10 +1627,10 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
}
}
} else {
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: BRST"
- " failed chan: %d\n",
- current->comm,
- channel));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: BRST failed chan: %d\n",
+ current->comm, channel));
}
}
return scsi_eh_test_devices(&check_list, work_q, done_q, 0);
@@ -1635,7 +1641,8 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
* @work_q: list_head for processed commands.
* @done_q: list_head for processed commands.
*/
-static int scsi_eh_host_reset(struct list_head *work_q,
+static int scsi_eh_host_reset(struct Scsi_Host *shost,
+ struct list_head *work_q,
struct list_head *done_q)
{
struct scsi_cmnd *scmd, *next;
@@ -1646,8 +1653,10 @@ static int scsi_eh_host_reset(struct list_head *work_q,
scmd = list_entry(work_q->next,
struct scsi_cmnd, eh_entry);
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending HRST\n"
- , current->comm));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: Sending HRST\n",
+ current->comm));
rtn = scsi_try_host_reset(scmd);
if (rtn == SUCCESS) {
@@ -1657,9 +1666,10 @@ static int scsi_eh_host_reset(struct list_head *work_q,
scsi_eh_finish_cmd(scmd, done_q);
}
} else {
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: HRST"
- " failed\n",
- current->comm));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ shost_printk(KERN_INFO, shost,
+ "%s: HRST failed\n",
+ current->comm));
}
}
return scsi_eh_test_devices(&check_list, work_q, done_q, 1);
@@ -1751,9 +1761,8 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
* up to the top level.
*/
if (!scsi_device_online(scmd->device)) {
- SCSI_LOG_ERROR_RECOVERY(5, printk("%s: device offline - report"
- " as SUCCESS\n",
- __func__));
+ SCSI_LOG_ERROR_RECOVERY(5, scmd_printk(KERN_INFO, scmd,
+ "%s: device offline - report as SUCCESS\n", __func__));
return SUCCESS;
}
@@ -1777,7 +1786,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
break;
case DID_ABORT:
if (scmd->eh_eflags & SCSI_EH_ABORT_SCHEDULED) {
- scmd->result |= DID_TIME_OUT << 16;
+ set_host_byte(scmd, DID_TIME_OUT);
return SUCCESS;
}
case DID_NO_CONNECT:
@@ -1999,8 +2008,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
* ioctls to queued block devices.
*/
SCSI_LOG_ERROR_RECOVERY(3,
- printk("scsi_eh_%d waking up host to restart\n",
- shost->host_no));
+ shost_printk(KERN_INFO, shost, "waking up host to restart\n"));
spin_lock_irqsave(shost->host_lock, flags);
if (scsi_host_set_state(shost, SHOST_RUNNING))
@@ -2047,7 +2055,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost,
if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
if (!scsi_eh_target_reset(shost, work_q, done_q))
if (!scsi_eh_bus_reset(shost, work_q, done_q))
- if (!scsi_eh_host_reset(work_q, done_q))
+ if (!scsi_eh_host_reset(shost, work_q, done_q))
scsi_eh_offline_sdevs(work_q,
done_q);
}
@@ -2066,10 +2074,10 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
if (scsi_device_online(scmd->device) &&
!scsi_noretry_cmd(scmd) &&
(++scmd->retries <= scmd->allowed)) {
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush"
- " retry cmd: %p\n",
- current->comm,
- scmd));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ scmd_printk(KERN_INFO, scmd,
+ "%s: flush retry cmd: %p\n",
+ current->comm, scmd));
scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
} else {
/*
@@ -2079,9 +2087,10 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
*/
if (!scmd->result)
scmd->result |= (DRIVER_TIMEOUT << 24);
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
- " cmd: %p\n",
- current->comm, scmd));
+ SCSI_LOG_ERROR_RECOVERY(3,
+ scmd_printk(KERN_INFO, scmd,
+ "%s: flush finish cmd: %p\n",
+ current->comm, scmd));
scsi_finish_command(scmd);
}
}
@@ -2155,19 +2164,22 @@ int scsi_error_handler(void *data)
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) ||
- shost->host_failed != shost->host_busy) {
+ shost->host_failed != atomic_read(&shost->host_busy)) {
SCSI_LOG_ERROR_RECOVERY(1,
- printk("scsi_eh_%d: sleeping\n",
- shost->host_no));
+ shost_printk(KERN_INFO, shost,
+ "scsi_eh_%d: sleeping\n",
+ shost->host_no));
schedule();
continue;
}
__set_current_state(TASK_RUNNING);
SCSI_LOG_ERROR_RECOVERY(1,
- printk("scsi_eh_%d: waking up %d/%d/%d\n",
- shost->host_no, shost->host_eh_scheduled,
- shost->host_failed, shost->host_busy));
+ shost_printk(KERN_INFO, shost,
+ "scsi_eh_%d: waking up %d/%d/%d\n",
+ shost->host_no, shost->host_eh_scheduled,
+ shost->host_failed,
+ atomic_read(&shost->host_busy)));
/*
* We have a host that is failing for some reason. Figure out
@@ -2201,7 +2213,9 @@ int scsi_error_handler(void *data)
__set_current_state(TASK_RUNNING);
SCSI_LOG_ERROR_RECOVERY(1,
- printk("Error handler scsi_eh_%d exiting\n", shost->host_no));
+ shost_printk(KERN_INFO, shost,
+ "Error handler scsi_eh_%d exiting\n",
+ shost->host_no));
shost->ehandler = NULL;
return 0;
}
@@ -2362,8 +2376,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
* suspended while we performed the TMF.
*/
SCSI_LOG_ERROR_RECOVERY(3,
- printk("%s: waking up host to restart after TMF\n",
- __func__));
+ shost_printk(KERN_INFO, shost,
+ "waking up host to restart after TMF\n"));
wake_up(&shost->host_wait);
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index d9564fb04f62..1aaaf43c6803 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -91,12 +91,14 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
int result;
struct scsi_sense_hdr sshdr;
- SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
+ SCSI_LOG_IOCTL(1, sdev_printk(KERN_INFO, sdev,
+ "Trying ioctl with scsi command %d\n", *cmd));
result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0,
&sshdr, timeout, retries, NULL);
- SCSI_LOG_IOCTL(2, printk("Ioctl returned 0x%x\n", result));
+ SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
+ "Ioctl returned 0x%x\n", result));
if ((driver_byte(result) & DRIVER_SENSE) &&
(scsi_sense_valid(&sshdr))) {
@@ -105,9 +107,11 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
sdev->lockable = 0;
else
- printk(KERN_INFO "ioctl_internal_command: "
- "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
- sshdr.asc, sshdr.ascq);
+ sdev_printk(KERN_INFO, sdev,
+ "ioctl_internal_command: "
+ "ILLEGAL REQUEST "
+ "asc=0x%x ascq=0x%x\n",
+ sshdr.asc, sshdr.ascq);
break;
case NOT_READY: /* This happens if there is no disc in drive */
if (sdev->removable)
@@ -127,7 +131,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
}
}
- SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
+ SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
+ "IOCTL Releasing command\n"));
return result;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f7e316368c99..9c44392b748f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1,5 +1,6 @@
/*
- * scsi_lib.c Copyright (C) 1999 Eric Youngdale
+ * Copyright (C) 1999 Eric Youngdale
+ * Copyright (C) 2014 Christoph Hellwig
*
* SCSI queueing library.
* Initial versions: Eric Youngdale (eric@andante.org).
@@ -20,6 +21,7 @@
#include <linux/delay.h>
#include <linux/hardirq.h>
#include <linux/scatterlist.h>
+#include <linux/blk-mq.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -29,6 +31,8 @@
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
+#include <trace/events/scsi.h>
+
#include "scsi_priv.h"
#include "scsi_logging.h"
@@ -75,28 +79,12 @@ struct kmem_cache *scsi_sdb_cache;
*/
#define SCSI_QUEUE_DELAY 3
-/**
- * __scsi_queue_insert - private queue insertion
- * @cmd: The SCSI command being requeued
- * @reason: The reason for the requeue
- * @unbusy: Whether the queue should be unbusied
- *
- * This is a private queue insertion. The public interface
- * scsi_queue_insert() always assumes the queue should be unbusied
- * because it's always called before the completion. This function is
- * for a requeue after completion, which should only occur in this
- * file.
- */
-static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
+static void
+scsi_set_blocked(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
struct scsi_target *starget = scsi_target(device);
- struct request_queue *q = device->request_queue;
- unsigned long flags;
-
- SCSI_LOG_MLQUEUE(1,
- printk("Inserting command %p into mlqueue\n", cmd));
/*
* Set the appropriate busy bit for the device/host.
@@ -113,16 +101,52 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
*/
switch (reason) {
case SCSI_MLQUEUE_HOST_BUSY:
- host->host_blocked = host->max_host_blocked;
+ atomic_set(&host->host_blocked, host->max_host_blocked);
break;
case SCSI_MLQUEUE_DEVICE_BUSY:
case SCSI_MLQUEUE_EH_RETRY:
- device->device_blocked = device->max_device_blocked;
+ atomic_set(&device->device_blocked,
+ device->max_device_blocked);
break;
case SCSI_MLQUEUE_TARGET_BUSY:
- starget->target_blocked = starget->max_target_blocked;
+ atomic_set(&starget->target_blocked,
+ starget->max_target_blocked);
break;
}
+}
+
+static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd)
+{
+ struct scsi_device *sdev = cmd->device;
+ struct request_queue *q = cmd->request->q;
+
+ blk_mq_requeue_request(cmd->request);
+ blk_mq_kick_requeue_list(q);
+ put_device(&sdev->sdev_gendev);
+}
+
+/**
+ * __scsi_queue_insert - private queue insertion
+ * @cmd: The SCSI command being requeued
+ * @reason: The reason for the requeue
+ * @unbusy: Whether the queue should be unbusied
+ *
+ * This is a private queue insertion. The public interface
+ * scsi_queue_insert() always assumes the queue should be unbusied
+ * because it's always called before the completion. This function is
+ * for a requeue after completion, which should only occur in this
+ * file.
+ */
+static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
+{
+ struct scsi_device *device = cmd->device;
+ struct request_queue *q = device->request_queue;
+ unsigned long flags;
+
+ SCSI_LOG_MLQUEUE(1, scmd_printk(KERN_INFO, cmd,
+ "Inserting command %p into mlqueue\n", cmd));
+
+ scsi_set_blocked(cmd, reason);
/*
* Decrement the counters, since these commands are no longer
@@ -138,6 +162,10 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
* before blk_cleanup_queue() finishes.
*/
cmd->result = 0;
+ if (q->mq_ops) {
+ scsi_mq_requeue_cmd(cmd);
+ return;
+ }
spin_lock_irqsave(q->queue_lock, flags);
blk_requeue_request(q, cmd->request);
kblockd_schedule_work(&device->requeue_work);
@@ -282,16 +310,26 @@ void scsi_device_unbusy(struct scsi_device *sdev)
struct scsi_target *starget = scsi_target(sdev);
unsigned long flags;
- spin_lock_irqsave(shost->host_lock, flags);
- shost->host_busy--;
- starget->target_busy--;
+ atomic_dec(&shost->host_busy);
+ if (starget->can_queue > 0)
+ atomic_dec(&starget->target_busy);
+
if (unlikely(scsi_host_in_recovery(shost) &&
- (shost->host_failed || shost->host_eh_scheduled)))
+ (shost->host_failed || shost->host_eh_scheduled))) {
+ spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_wakeup(shost);
- spin_unlock(shost->host_lock);
- spin_lock(sdev->request_queue->queue_lock);
- sdev->device_busy--;
- spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ }
+
+ atomic_dec(&sdev->device_busy);
+}
+
+static void scsi_kick_queue(struct request_queue *q)
+{
+ if (q->mq_ops)
+ blk_mq_start_hw_queues(q);
+ else
+ blk_run_queue(q);
}
/*
@@ -318,7 +356,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
* but in most cases, we will be first. Ideally, each LU on the
* target would get some limited time or requests on the target.
*/
- blk_run_queue(current_sdev->request_queue);
+ scsi_kick_queue(current_sdev->request_queue);
spin_lock_irqsave(shost->host_lock, flags);
if (starget->starget_sdev_user)
@@ -331,7 +369,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
- blk_run_queue(sdev->request_queue);
+ scsi_kick_queue(sdev->request_queue);
spin_lock_irqsave(shost->host_lock, flags);
scsi_device_put(sdev);
@@ -340,28 +378,36 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
spin_unlock_irqrestore(shost->host_lock, flags);
}
-static inline int scsi_device_is_busy(struct scsi_device *sdev)
+static inline bool scsi_device_is_busy(struct scsi_device *sdev)
{
- if (sdev->device_busy >= sdev->queue_depth || sdev->device_blocked)
- return 1;
-
- return 0;
+ if (atomic_read(&sdev->device_busy) >= sdev->queue_depth)
+ return true;
+ if (atomic_read(&sdev->device_blocked) > 0)
+ return true;
+ return false;
}
-static inline int scsi_target_is_busy(struct scsi_target *starget)
+static inline bool scsi_target_is_busy(struct scsi_target *starget)
{
- return ((starget->can_queue > 0 &&
- starget->target_busy >= starget->can_queue) ||
- starget->target_blocked);
+ if (starget->can_queue > 0) {
+ if (atomic_read(&starget->target_busy) >= starget->can_queue)
+ return true;
+ if (atomic_read(&starget->target_blocked) > 0)
+ return true;
+ }
+ return false;
}
-static inline int scsi_host_is_busy(struct Scsi_Host *shost)
+static inline bool scsi_host_is_busy(struct Scsi_Host *shost)
{
- if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
- shost->host_blocked || shost->host_self_blocked)
- return 1;
-
- return 0;
+ if (shost->can_queue > 0 &&
+ atomic_read(&shost->host_busy) >= shost->can_queue)
+ return true;
+ if (atomic_read(&shost->host_blocked) > 0)
+ return true;
+ if (shost->host_self_blocked)
+ return true;
+ return false;
}
static void scsi_starved_list_run(struct Scsi_Host *shost)
@@ -413,7 +459,7 @@ static void scsi_starved_list_run(struct Scsi_Host *shost)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
- blk_run_queue(slq);
+ scsi_kick_queue(slq);
blk_put_queue(slq);
spin_lock_irqsave(shost->host_lock, flags);
@@ -444,7 +490,10 @@ static void scsi_run_queue(struct request_queue *q)
if (!list_empty(&sdev->host->starved_list))
scsi_starved_list_run(sdev->host);
- blk_run_queue(q);
+ if (q->mq_ops)
+ blk_mq_start_stopped_hw_queues(q, false);
+ else
+ blk_run_queue(q);
}
void scsi_requeue_run_queue(struct work_struct *work)
@@ -542,25 +591,70 @@ static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
return mempool_alloc(sgp->pool, gfp_mask);
}
+static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq)
+{
+ if (mq && sdb->table.nents <= SCSI_MAX_SG_SEGMENTS)
+ return;
+ __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free);
+}
+
static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents,
- gfp_t gfp_mask)
+ gfp_t gfp_mask, bool mq)
{
+ struct scatterlist *first_chunk = NULL;
int ret;
BUG_ON(!nents);
+ if (mq) {
+ if (nents <= SCSI_MAX_SG_SEGMENTS) {
+ sdb->table.nents = nents;
+ sg_init_table(sdb->table.sgl, sdb->table.nents);
+ return 0;
+ }
+ first_chunk = sdb->table.sgl;
+ }
+
ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS,
- gfp_mask, scsi_sg_alloc);
+ first_chunk, gfp_mask, scsi_sg_alloc);
if (unlikely(ret))
- __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS,
- scsi_sg_free);
-
+ scsi_free_sgtable(sdb, mq);
return ret;
}
-static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
+static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
+{
+ if (cmd->request->cmd_type == REQ_TYPE_FS) {
+ struct scsi_driver *drv = scsi_cmd_to_driver(cmd);
+
+ if (drv->uninit_command)
+ drv->uninit_command(cmd);
+ }
+}
+
+static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
{
- __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
+ if (cmd->sdb.table.nents)
+ scsi_free_sgtable(&cmd->sdb, true);
+ if (cmd->request->next_rq && cmd->request->next_rq->special)
+ scsi_free_sgtable(cmd->request->next_rq->special, true);
+ if (scsi_prot_sg_count(cmd))
+ scsi_free_sgtable(cmd->prot_sdb, true);
+}
+
+static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
+{
+ struct scsi_device *sdev = cmd->device;
+ unsigned long flags;
+
+ BUG_ON(list_empty(&cmd->list));
+
+ scsi_mq_free_sgtables(cmd);
+ scsi_uninit_cmd(cmd);
+
+ spin_lock_irqsave(&sdev->list_lock, flags);
+ list_del_init(&cmd->list);
+ spin_unlock_irqrestore(&sdev->list_lock, flags);
}
/*
@@ -579,27 +673,79 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
* the __init_io() function. Primarily this would involve
* the scatter-gather table.
*/
-void scsi_release_buffers(struct scsi_cmnd *cmd)
+static void scsi_release_buffers(struct scsi_cmnd *cmd)
{
if (cmd->sdb.table.nents)
- scsi_free_sgtable(&cmd->sdb);
+ scsi_free_sgtable(&cmd->sdb, false);
memset(&cmd->sdb, 0, sizeof(cmd->sdb));
if (scsi_prot_sg_count(cmd))
- scsi_free_sgtable(cmd->prot_sdb);
+ scsi_free_sgtable(cmd->prot_sdb, false);
}
-EXPORT_SYMBOL(scsi_release_buffers);
static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd)
{
struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special;
- scsi_free_sgtable(bidi_sdb);
+ scsi_free_sgtable(bidi_sdb, false);
kmem_cache_free(scsi_sdb_cache, bidi_sdb);
cmd->request->next_rq->special = NULL;
}
+static bool scsi_end_request(struct request *req, int error,
+ unsigned int bytes, unsigned int bidi_bytes)
+{
+ struct scsi_cmnd *cmd = req->special;
+ struct scsi_device *sdev = cmd->device;
+ struct request_queue *q = sdev->request_queue;
+
+ if (blk_update_request(req, error, bytes))
+ return true;
+
+ /* Bidi request must be completed as a whole */
+ if (unlikely(bidi_bytes) &&
+ blk_update_request(req->next_rq, error, bidi_bytes))
+ return true;
+
+ if (blk_queue_add_random(q))
+ add_disk_randomness(req->rq_disk);
+
+ if (req->mq_ctx) {
+ /*
+ * In the MQ case the command gets freed by __blk_mq_end_io,
+ * so we have to do all cleanup that depends on it earlier.
+ *
+ * We also can't kick the queues from irq context, so we
+ * will have to defer it to a workqueue.
+ */
+ scsi_mq_uninit_cmd(cmd);
+
+ __blk_mq_end_io(req, error);
+
+ if (scsi_target(sdev)->single_lun ||
+ !list_empty(&sdev->host->starved_list))
+ kblockd_schedule_work(&sdev->requeue_work);
+ else
+ blk_mq_start_stopped_hw_queues(q, true);
+
+ put_device(&sdev->sdev_gendev);
+ } else {
+ unsigned long flags;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_finish_request(req, error);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ if (bidi_bytes)
+ scsi_release_bidi_buffers(cmd);
+ scsi_release_buffers(cmd);
+ scsi_next_command(cmd);
+ }
+
+ return false;
+}
+
/**
* __scsi_error_from_host_byte - translate SCSI error code into errno
* @cmd: SCSI command (unused)
@@ -672,7 +818,7 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
* be put back on the queue and retried using the same
* command as before, possibly after a delay.
*
- * c) We can call blk_end_request() with -EIO to fail
+ * c) We can call scsi_end_request() with -EIO to fail
* the remainder of the request.
*/
void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
@@ -686,7 +832,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
int sense_deferred = 0;
enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY,
ACTION_DELAYED_RETRY} action;
- char *description = NULL;
unsigned long wait_for = (cmd->allowed + 1) * req->timeout;
if (result) {
@@ -724,15 +869,19 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* both sides at once.
*/
req->next_rq->resid_len = scsi_in(cmd)->resid;
-
- scsi_release_buffers(cmd);
- scsi_release_bidi_buffers(cmd);
-
- blk_end_request_all(req, 0);
-
- scsi_next_command(cmd);
+ if (scsi_end_request(req, 0, blk_rq_bytes(req),
+ blk_rq_bytes(req->next_rq)))
+ BUG();
return;
}
+ } else if (blk_rq_bytes(req) == 0 && result && !sense_deferred) {
+ /*
+ * Certain non BLOCK_PC requests are commands that don't
+ * actually transfer anything (FLUSH), so cannot use
+ * good_bytes != blk_rq_bytes(req) as the signal for an error.
+ * This sets the error explicitly for the problem case.
+ */
+ error = __scsi_error_from_host_byte(cmd, result);
}
/* no bidi support for !REQ_TYPE_BLOCK_PC yet */
@@ -742,9 +891,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* Next deal with any sectors which we were able to correctly
* handle.
*/
- SCSI_LOG_HLCOMPLETE(1, printk("%u sectors total, "
- "%d bytes done.\n",
- blk_rq_sectors(req), good_bytes));
+ SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, cmd,
+ "%u sectors total, %d bytes done.\n",
+ blk_rq_sectors(req), good_bytes));
/*
* Recovered errors need reporting, but they're always treated
@@ -769,15 +918,16 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
/*
* If we finished all bytes in the request we are done now.
*/
- if (!blk_end_request(req, error, good_bytes))
- goto next_command;
+ if (!scsi_end_request(req, error, good_bytes, 0))
+ return;
/*
* Kill remainder if no retrys.
*/
if (error && scsi_noretry_cmd(cmd)) {
- blk_end_request_all(req, error);
- goto next_command;
+ if (scsi_end_request(req, error, blk_rq_bytes(req), 0))
+ BUG();
+ return;
}
/*
@@ -803,7 +953,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
* and quietly refuse further access.
*/
cmd->device->changed = 1;
- description = "Media Changed";
action = ACTION_FAIL;
} else {
/* Must have been a power glitch, or a
@@ -831,27 +980,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
cmd->device->use_10_for_rw = 0;
action = ACTION_REPREP;
} else if (sshdr.asc == 0x10) /* DIX */ {
- description = "Host Data Integrity Failure";
action = ACTION_FAIL;
error = -EILSEQ;
/* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */
} else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) {
- switch (cmd->cmnd[0]) {
- case UNMAP:
- description = "Discard failure";
- break;
- case WRITE_SAME:
- case WRITE_SAME_16:
- if (cmd->cmnd[1] & 0x8)
- description = "Discard failure";
- else
- description =
- "Write same failure";
- break;
- default:
- description = "Invalid command failure";
- break;
- }
action = ACTION_FAIL;
error = -EREMOTEIO;
} else
@@ -859,10 +991,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
break;
case ABORTED_COMMAND:
action = ACTION_FAIL;
- if (sshdr.asc == 0x10) { /* DIF */
- description = "Target Data Integrity Failure";
+ if (sshdr.asc == 0x10) /* DIF */
error = -EILSEQ;
- }
break;
case NOT_READY:
/* If the device is in the process of becoming
@@ -881,57 +1011,52 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
action = ACTION_DELAYED_RETRY;
break;
default:
- description = "Device not ready";
action = ACTION_FAIL;
break;
}
- } else {
- description = "Device not ready";
+ } else
action = ACTION_FAIL;
- }
break;
case VOLUME_OVERFLOW:
/* See SSC3rXX or current. */
action = ACTION_FAIL;
break;
default:
- description = "Unhandled sense code";
action = ACTION_FAIL;
break;
}
- } else {
- description = "Unhandled error code";
+ } else
action = ACTION_FAIL;
- }
if (action != ACTION_FAIL &&
- time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
+ time_before(cmd->jiffies_at_alloc + wait_for, jiffies))
action = ACTION_FAIL;
- description = "Command timed out";
- }
switch (action) {
case ACTION_FAIL:
/* Give up and fail the remainder of the request */
if (!(req->cmd_flags & REQ_QUIET)) {
- if (description)
- scmd_printk(KERN_INFO, cmd, "%s\n",
- description);
scsi_print_result(cmd);
if (driver_byte(result) & DRIVER_SENSE)
scsi_print_sense("", cmd);
scsi_print_command(cmd);
}
- if (!blk_end_request_err(req, error))
- goto next_command;
+ if (!scsi_end_request(req, error, blk_rq_err_bytes(req), 0))
+ return;
/*FALLTHRU*/
case ACTION_REPREP:
requeue:
/* Unprep the request and put it back at the head of the queue.
* A new command will be prepared and issued.
*/
- scsi_release_buffers(cmd);
- scsi_requeue_command(q, cmd);
+ if (q->mq_ops) {
+ cmd->request->cmd_flags &= ~REQ_DONTPREP;
+ scsi_mq_uninit_cmd(cmd);
+ scsi_mq_requeue_cmd(cmd);
+ } else {
+ scsi_release_buffers(cmd);
+ scsi_requeue_command(q, cmd);
+ }
break;
case ACTION_RETRY:
/* Retry the same command immediately */
@@ -942,11 +1067,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
break;
}
- return;
-
-next_command:
- scsi_release_buffers(cmd);
- scsi_next_command(cmd);
}
static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
@@ -958,9 +1078,8 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
* If sg table allocation fails, requeue request later.
*/
if (unlikely(scsi_alloc_sgtable(sdb, req->nr_phys_segments,
- gfp_mask))) {
+ gfp_mask, req->mq_ctx != NULL)))
return BLKPREP_DEFER;
- }
/*
* Next, walk the list, and fill in the addresses and sizes of
@@ -988,21 +1107,29 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
struct scsi_device *sdev = cmd->device;
struct request *rq = cmd->request;
+ bool is_mq = (rq->mq_ctx != NULL);
+ int error;
+
+ BUG_ON(!rq->nr_phys_segments);
- int error = scsi_init_sgtable(rq, &cmd->sdb, gfp_mask);
+ error = scsi_init_sgtable(rq, &cmd->sdb, gfp_mask);
if (error)
goto err_exit;
if (blk_bidi_rq(rq)) {
- struct scsi_data_buffer *bidi_sdb = kmem_cache_zalloc(
- scsi_sdb_cache, GFP_ATOMIC);
- if (!bidi_sdb) {
- error = BLKPREP_DEFER;
- goto err_exit;
+ if (!rq->q->mq_ops) {
+ struct scsi_data_buffer *bidi_sdb =
+ kmem_cache_zalloc(scsi_sdb_cache, GFP_ATOMIC);
+ if (!bidi_sdb) {
+ error = BLKPREP_DEFER;
+ goto err_exit;
+ }
+
+ rq->next_rq->special = bidi_sdb;
}
- rq->next_rq->special = bidi_sdb;
- error = scsi_init_sgtable(rq->next_rq, bidi_sdb, GFP_ATOMIC);
+ error = scsi_init_sgtable(rq->next_rq, rq->next_rq->special,
+ GFP_ATOMIC);
if (error)
goto err_exit;
}
@@ -1014,7 +1141,7 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
BUG_ON(prot_sdb == NULL);
ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
- if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask)) {
+ if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask, is_mq)) {
error = BLKPREP_DEFER;
goto err_exit;
}
@@ -1028,13 +1155,16 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
cmd->prot_sdb->table.nents = count;
}
- return BLKPREP_OK ;
-
+ return BLKPREP_OK;
err_exit:
- scsi_release_buffers(cmd);
- cmd->request->special = NULL;
- scsi_put_command(cmd);
- put_device(&sdev->sdev_gendev);
+ if (is_mq) {
+ scsi_mq_free_sgtables(cmd);
+ } else {
+ scsi_release_buffers(cmd);
+ cmd->request->special = NULL;
+ scsi_put_command(cmd);
+ put_device(&sdev->sdev_gendev);
+ }
return error;
}
EXPORT_SYMBOL(scsi_init_io);
@@ -1069,7 +1199,7 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
return cmd;
}
-int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
+static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
{
struct scsi_cmnd *cmd = req->special;
@@ -1080,11 +1210,7 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
* submit a request without an attached bio.
*/
if (req->bio) {
- int ret;
-
- BUG_ON(!req->nr_phys_segments);
-
- ret = scsi_init_io(cmd, GFP_ATOMIC);
+ int ret = scsi_init_io(cmd, GFP_ATOMIC);
if (unlikely(ret))
return ret;
} else {
@@ -1094,25 +1220,16 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
}
cmd->cmd_len = req->cmd_len;
- if (!blk_rq_bytes(req))
- cmd->sc_data_direction = DMA_NONE;
- else if (rq_data_dir(req) == WRITE)
- cmd->sc_data_direction = DMA_TO_DEVICE;
- else
- cmd->sc_data_direction = DMA_FROM_DEVICE;
-
cmd->transfersize = blk_rq_bytes(req);
cmd->allowed = req->retries;
return BLKPREP_OK;
}
-EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
/*
- * Setup a REQ_TYPE_FS command. These are simple read/write request
- * from filesystems that still need to be translated to SCSI CDBs from
- * the ULD.
+ * Setup a REQ_TYPE_FS command. These are simple request from filesystems
+ * that still need to be translated to SCSI CDBs from the ULD.
*/
-int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
+static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
{
struct scsi_cmnd *cmd = req->special;
@@ -1123,15 +1240,30 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
return ret;
}
- /*
- * Filesystem requests must transfer data.
- */
- BUG_ON(!req->nr_phys_segments);
-
memset(cmd->cmnd, 0, BLK_MAX_CDB);
- return scsi_init_io(cmd, GFP_ATOMIC);
+ return scsi_cmd_to_driver(cmd)->init_command(cmd);
+}
+
+static int scsi_setup_cmnd(struct scsi_device *sdev, struct request *req)
+{
+ struct scsi_cmnd *cmd = req->special;
+
+ if (!blk_rq_bytes(req))
+ cmd->sc_data_direction = DMA_NONE;
+ else if (rq_data_dir(req) == WRITE)
+ cmd->sc_data_direction = DMA_TO_DEVICE;
+ else
+ cmd->sc_data_direction = DMA_FROM_DEVICE;
+
+ switch (req->cmd_type) {
+ case REQ_TYPE_FS:
+ return scsi_setup_fs_cmnd(sdev, req);
+ case REQ_TYPE_BLOCK_PC:
+ return scsi_setup_blk_pc_cmnd(sdev, req);
+ default:
+ return BLKPREP_KILL;
+ }
}
-EXPORT_SYMBOL(scsi_setup_fs_cmnd);
static int
scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
@@ -1210,7 +1342,7 @@ scsi_prep_return(struct request_queue *q, struct request *req, int ret)
* queue must be restarted, so we schedule a callback to happen
* shortly.
*/
- if (sdev->device_busy == 0)
+ if (atomic_read(&sdev->device_busy) == 0)
blk_delay_queue(q, SCSI_QUEUE_DELAY);
break;
default:
@@ -1236,26 +1368,14 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
goto out;
}
- if (req->cmd_type == REQ_TYPE_FS)
- ret = scsi_cmd_to_driver(cmd)->init_command(cmd);
- else if (req->cmd_type == REQ_TYPE_BLOCK_PC)
- ret = scsi_setup_blk_pc_cmnd(sdev, req);
- else
- ret = BLKPREP_KILL;
-
+ ret = scsi_setup_cmnd(sdev, req);
out:
return scsi_prep_return(q, req, ret);
}
static void scsi_unprep_fn(struct request_queue *q, struct request *req)
{
- if (req->cmd_type == REQ_TYPE_FS) {
- struct scsi_cmnd *cmd = req->special;
- struct scsi_driver *drv = scsi_cmd_to_driver(cmd);
-
- if (drv->uninit_command)
- drv->uninit_command(cmd);
- }
+ scsi_uninit_cmd(req->special);
}
/*
@@ -1267,99 +1387,144 @@ static void scsi_unprep_fn(struct request_queue *q, struct request *req)
static inline int scsi_dev_queue_ready(struct request_queue *q,
struct scsi_device *sdev)
{
- if (sdev->device_busy == 0 && sdev->device_blocked) {
+ unsigned int busy;
+
+ busy = atomic_inc_return(&sdev->device_busy) - 1;
+ if (atomic_read(&sdev->device_blocked)) {
+ if (busy)
+ goto out_dec;
+
/*
* unblock after device_blocked iterates to zero
*/
- if (--sdev->device_blocked == 0) {
- SCSI_LOG_MLQUEUE(3,
- sdev_printk(KERN_INFO, sdev,
- "unblocking device at zero depth\n"));
- } else {
- blk_delay_queue(q, SCSI_QUEUE_DELAY);
- return 0;
+ if (atomic_dec_return(&sdev->device_blocked) > 0) {
+ /*
+ * For the MQ case we take care of this in the caller.
+ */
+ if (!q->mq_ops)
+ blk_delay_queue(q, SCSI_QUEUE_DELAY);
+ goto out_dec;
}
+ SCSI_LOG_MLQUEUE(3, sdev_printk(KERN_INFO, sdev,
+ "unblocking device at zero depth\n"));
}
- if (scsi_device_is_busy(sdev))
- return 0;
+
+ if (busy >= sdev->queue_depth)
+ goto out_dec;
return 1;
+out_dec:
+ atomic_dec(&sdev->device_busy);
+ return 0;
}
-
/*
* scsi_target_queue_ready: checks if there we can send commands to target
* @sdev: scsi device on starget to check.
- *
- * Called with the host lock held.
*/
static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
struct scsi_device *sdev)
{
struct scsi_target *starget = scsi_target(sdev);
+ unsigned int busy;
if (starget->single_lun) {
+ spin_lock_irq(shost->host_lock);
if (starget->starget_sdev_user &&
- starget->starget_sdev_user != sdev)
+ starget->starget_sdev_user != sdev) {
+ spin_unlock_irq(shost->host_lock);
return 0;
+ }
starget->starget_sdev_user = sdev;
+ spin_unlock_irq(shost->host_lock);
}
- if (starget->target_busy == 0 && starget->target_blocked) {
+ if (starget->can_queue <= 0)
+ return 1;
+
+ busy = atomic_inc_return(&starget->target_busy) - 1;
+ if (atomic_read(&starget->target_blocked) > 0) {
+ if (busy)
+ goto starved;
+
/*
* unblock after target_blocked iterates to zero
*/
- if (--starget->target_blocked == 0) {
- SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
- "unblocking target at zero depth\n"));
- } else
- return 0;
- }
+ if (atomic_dec_return(&starget->target_blocked) > 0)
+ goto out_dec;
- if (scsi_target_is_busy(starget)) {
- list_move_tail(&sdev->starved_entry, &shost->starved_list);
- return 0;
+ SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
+ "unblocking target at zero depth\n"));
}
+ if (busy >= starget->can_queue)
+ goto starved;
+
return 1;
+
+starved:
+ spin_lock_irq(shost->host_lock);
+ list_move_tail(&sdev->starved_entry, &shost->starved_list);
+ spin_unlock_irq(shost->host_lock);
+out_dec:
+ if (starget->can_queue > 0)
+ atomic_dec(&starget->target_busy);
+ return 0;
}
/*
* scsi_host_queue_ready: if we can send requests to shost, return 1 else
* return 0. We must end up running the queue again whenever 0 is
* returned, else IO can hang.
- *
- * Called with host_lock held.
*/
static inline int scsi_host_queue_ready(struct request_queue *q,
struct Scsi_Host *shost,
struct scsi_device *sdev)
{
+ unsigned int busy;
+
if (scsi_host_in_recovery(shost))
return 0;
- if (shost->host_busy == 0 && shost->host_blocked) {
+
+ busy = atomic_inc_return(&shost->host_busy) - 1;
+ if (atomic_read(&shost->host_blocked) > 0) {
+ if (busy)
+ goto starved;
+
/*
* unblock after host_blocked iterates to zero
*/
- if (--shost->host_blocked == 0) {
- SCSI_LOG_MLQUEUE(3,
- printk("scsi%d unblocking host at zero depth\n",
- shost->host_no));
- } else {
- return 0;
- }
- }
- if (scsi_host_is_busy(shost)) {
- if (list_empty(&sdev->starved_entry))
- list_add_tail(&sdev->starved_entry, &shost->starved_list);
- return 0;
+ if (atomic_dec_return(&shost->host_blocked) > 0)
+ goto out_dec;
+
+ SCSI_LOG_MLQUEUE(3,
+ shost_printk(KERN_INFO, shost,
+ "unblocking host at zero depth\n"));
}
+ if (shost->can_queue > 0 && busy >= shost->can_queue)
+ goto starved;
+ if (shost->host_self_blocked)
+ goto starved;
+
/* We're OK to process the command, so we can't be starved */
- if (!list_empty(&sdev->starved_entry))
- list_del_init(&sdev->starved_entry);
+ if (!list_empty(&sdev->starved_entry)) {
+ spin_lock_irq(shost->host_lock);
+ if (!list_empty(&sdev->starved_entry))
+ list_del_init(&sdev->starved_entry);
+ spin_unlock_irq(shost->host_lock);
+ }
return 1;
+
+starved:
+ spin_lock_irq(shost->host_lock);
+ if (list_empty(&sdev->starved_entry))
+ list_add_tail(&sdev->starved_entry, &shost->starved_list);
+ spin_unlock_irq(shost->host_lock);
+out_dec:
+ atomic_dec(&shost->host_busy);
+ return 0;
}
/*
@@ -1422,13 +1587,10 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
* bump busy counts. To bump the counters, we need to dance
* with the locks as normal issue path does.
*/
- sdev->device_busy++;
- spin_unlock(sdev->request_queue->queue_lock);
- spin_lock(shost->host_lock);
- shost->host_busy++;
- starget->target_busy++;
- spin_unlock(shost->host_lock);
- spin_lock(sdev->request_queue->queue_lock);
+ atomic_inc(&sdev->device_busy);
+ atomic_inc(&shost->host_busy);
+ if (starget->can_queue > 0)
+ atomic_inc(&starget->target_busy);
blk_complete_request(req);
}
@@ -1453,7 +1615,7 @@ static void scsi_softirq_done(struct request *rq)
wait_for/HZ);
disposition = SUCCESS;
}
-
+
scsi_log_completion(cmd, disposition);
switch (disposition) {
@@ -1472,6 +1634,23 @@ static void scsi_softirq_done(struct request *rq)
}
}
+/**
+ * scsi_done - Invoke completion on finished SCSI command.
+ * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives
+ * ownership back to SCSI Core -- i.e. the LLDD has finished with it.
+ *
+ * Description: This function is the mid-level's (SCSI Core) interrupt routine,
+ * which regains ownership of the SCSI command (de facto) from a LLDD, and
+ * calls blk_complete_request() for further processing.
+ *
+ * This function is interrupt context safe.
+ */
+static void scsi_done(struct scsi_cmnd *cmd)
+{
+ trace_scsi_dispatch_cmd_done(cmd);
+ blk_complete_request(cmd->request);
+}
+
/*
* Function: scsi_request_fn()
*
@@ -1501,11 +1680,11 @@ static void scsi_request_fn(struct request_queue *q)
int rtn;
/*
* get next queueable request. We do this early to make sure
- * that the request is fully prepared even if we cannot
+ * that the request is fully prepared even if we cannot
* accept it.
*/
req = blk_peek_request(q);
- if (!req || !scsi_dev_queue_ready(q, sdev))
+ if (!req)
break;
if (unlikely(!scsi_device_online(sdev))) {
@@ -1515,15 +1694,16 @@ static void scsi_request_fn(struct request_queue *q)
continue;
}
+ if (!scsi_dev_queue_ready(q, sdev))
+ break;
/*
* Remove the request from the request list.
*/
if (!(blk_queue_tagged(q) && !blk_queue_start_tag(q, req)))
blk_start_request(req);
- sdev->device_busy++;
- spin_unlock(q->queue_lock);
+ spin_unlock_irq(q->queue_lock);
cmd = req->special;
if (unlikely(cmd == NULL)) {
printk(KERN_CRIT "impossible request in %s.\n"
@@ -1533,7 +1713,6 @@ static void scsi_request_fn(struct request_queue *q)
blk_dump_rq_flags(req, "foo");
BUG();
}
- spin_lock(shost->host_lock);
/*
* We hit this when the driver is using a host wide
@@ -1544,9 +1723,11 @@ static void scsi_request_fn(struct request_queue *q)
* a run when a tag is freed.
*/
if (blk_queue_tagged(q) && !blk_rq_tagged(req)) {
+ spin_lock_irq(shost->host_lock);
if (list_empty(&sdev->starved_entry))
list_add_tail(&sdev->starved_entry,
&shost->starved_list);
+ spin_unlock_irq(shost->host_lock);
goto not_ready;
}
@@ -1554,16 +1735,7 @@ static void scsi_request_fn(struct request_queue *q)
goto not_ready;
if (!scsi_host_queue_ready(q, shost, sdev))
- goto not_ready;
-
- scsi_target(sdev)->target_busy++;
- shost->host_busy++;
-
- /*
- * XXX(hch): This is rather suboptimal, scsi_dispatch_cmd will
- * take the lock again.
- */
- spin_unlock_irq(shost->host_lock);
+ goto host_not_ready;
/*
* Finally, initialize any error handling parameters, and set up
@@ -1574,17 +1746,22 @@ static void scsi_request_fn(struct request_queue *q)
/*
* Dispatch the command to the low-level driver.
*/
+ cmd->scsi_done = scsi_done;
rtn = scsi_dispatch_cmd(cmd);
- spin_lock_irq(q->queue_lock);
- if (rtn)
+ if (rtn) {
+ scsi_queue_insert(cmd, rtn);
+ spin_lock_irq(q->queue_lock);
goto out_delay;
+ }
+ spin_lock_irq(q->queue_lock);
}
return;
+ host_not_ready:
+ if (scsi_target(sdev)->can_queue > 0)
+ atomic_dec(&scsi_target(sdev)->target_busy);
not_ready:
- spin_unlock_irq(shost->host_lock);
-
/*
* lock q, handle tag, requeue req, and decrement device_busy. We
* must return with queue_lock held.
@@ -1595,13 +1772,187 @@ static void scsi_request_fn(struct request_queue *q)
*/
spin_lock_irq(q->queue_lock);
blk_requeue_request(q, req);
- sdev->device_busy--;
+ atomic_dec(&sdev->device_busy);
out_delay:
- if (sdev->device_busy == 0)
+ if (atomic_read(&sdev->device_busy) && !scsi_device_blocked(sdev))
blk_delay_queue(q, SCSI_QUEUE_DELAY);
}
-u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
+static inline int prep_to_mq(int ret)
+{
+ switch (ret) {
+ case BLKPREP_OK:
+ return 0;
+ case BLKPREP_DEFER:
+ return BLK_MQ_RQ_QUEUE_BUSY;
+ default:
+ return BLK_MQ_RQ_QUEUE_ERROR;
+ }
+}
+
+static int scsi_mq_prep_fn(struct request *req)
+{
+ struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
+ struct scsi_device *sdev = req->q->queuedata;
+ struct Scsi_Host *shost = sdev->host;
+ unsigned char *sense_buf = cmd->sense_buffer;
+ struct scatterlist *sg;
+
+ memset(cmd, 0, sizeof(struct scsi_cmnd));
+
+ req->special = cmd;
+
+ cmd->request = req;
+ cmd->device = sdev;
+ cmd->sense_buffer = sense_buf;
+
+ cmd->tag = req->tag;
+
+ req->cmd = req->__cmd;
+ cmd->cmnd = req->cmd;
+ cmd->prot_op = SCSI_PROT_NORMAL;
+
+ INIT_LIST_HEAD(&cmd->list);
+ INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
+ cmd->jiffies_at_alloc = jiffies;
+
+ /*
+ * XXX: cmd_list lookups are only used by two drivers, try to get
+ * rid of this list in common code.
+ */
+ spin_lock_irq(&sdev->list_lock);
+ list_add_tail(&cmd->list, &sdev->cmd_list);
+ spin_unlock_irq(&sdev->list_lock);
+
+ sg = (void *)cmd + sizeof(struct scsi_cmnd) + shost->hostt->cmd_size;
+ cmd->sdb.table.sgl = sg;
+
+ if (scsi_host_get_prot(shost)) {
+ cmd->prot_sdb = (void *)sg +
+ shost->sg_tablesize * sizeof(struct scatterlist);
+ memset(cmd->prot_sdb, 0, sizeof(struct scsi_data_buffer));
+
+ cmd->prot_sdb->table.sgl =
+ (struct scatterlist *)(cmd->prot_sdb + 1);
+ }
+
+ if (blk_bidi_rq(req)) {
+ struct request *next_rq = req->next_rq;
+ struct scsi_data_buffer *bidi_sdb = blk_mq_rq_to_pdu(next_rq);
+
+ memset(bidi_sdb, 0, sizeof(struct scsi_data_buffer));
+ bidi_sdb->table.sgl =
+ (struct scatterlist *)(bidi_sdb + 1);
+
+ next_rq->special = bidi_sdb;
+ }
+
+ return scsi_setup_cmnd(sdev, req);
+}
+
+static void scsi_mq_done(struct scsi_cmnd *cmd)
+{
+ trace_scsi_dispatch_cmd_done(cmd);
+ blk_mq_complete_request(cmd->request);
+}
+
+static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req)
+{
+ struct request_queue *q = req->q;
+ struct scsi_device *sdev = q->queuedata;
+ struct Scsi_Host *shost = sdev->host;
+ struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
+ int ret;
+ int reason;
+
+ ret = prep_to_mq(scsi_prep_state_check(sdev, req));
+ if (ret)
+ goto out;
+
+ ret = BLK_MQ_RQ_QUEUE_BUSY;
+ if (!get_device(&sdev->sdev_gendev))
+ goto out;
+
+ if (!scsi_dev_queue_ready(q, sdev))
+ goto out_put_device;
+ if (!scsi_target_queue_ready(shost, sdev))
+ goto out_dec_device_busy;
+ if (!scsi_host_queue_ready(q, shost, sdev))
+ goto out_dec_target_busy;
+
+ if (!(req->cmd_flags & REQ_DONTPREP)) {
+ ret = prep_to_mq(scsi_mq_prep_fn(req));
+ if (ret)
+ goto out_dec_host_busy;
+ req->cmd_flags |= REQ_DONTPREP;
+ }
+
+ scsi_init_cmd_errh(cmd);
+ cmd->scsi_done = scsi_mq_done;
+
+ reason = scsi_dispatch_cmd(cmd);
+ if (reason) {
+ scsi_set_blocked(cmd, reason);
+ ret = BLK_MQ_RQ_QUEUE_BUSY;
+ goto out_dec_host_busy;
+ }
+
+ return BLK_MQ_RQ_QUEUE_OK;
+
+out_dec_host_busy:
+ atomic_dec(&shost->host_busy);
+out_dec_target_busy:
+ if (scsi_target(sdev)->can_queue > 0)
+ atomic_dec(&scsi_target(sdev)->target_busy);
+out_dec_device_busy:
+ atomic_dec(&sdev->device_busy);
+out_put_device:
+ put_device(&sdev->sdev_gendev);
+out:
+ switch (ret) {
+ case BLK_MQ_RQ_QUEUE_BUSY:
+ blk_mq_stop_hw_queue(hctx);
+ if (atomic_read(&sdev->device_busy) == 0 &&
+ !scsi_device_blocked(sdev))
+ blk_mq_delay_queue(hctx, SCSI_QUEUE_DELAY);
+ break;
+ case BLK_MQ_RQ_QUEUE_ERROR:
+ /*
+ * Make sure to release all allocated ressources when
+ * we hit an error, as we will never see this command
+ * again.
+ */
+ if (req->cmd_flags & REQ_DONTPREP)
+ scsi_mq_uninit_cmd(cmd);
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+static int scsi_init_request(void *data, struct request *rq,
+ unsigned int hctx_idx, unsigned int request_idx,
+ unsigned int numa_node)
+{
+ struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
+
+ cmd->sense_buffer = kzalloc_node(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL,
+ numa_node);
+ if (!cmd->sense_buffer)
+ return -ENOMEM;
+ return 0;
+}
+
+static void scsi_exit_request(void *data, struct request *rq,
+ unsigned int hctx_idx, unsigned int request_idx)
+{
+ struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq);
+
+ kfree(cmd->sense_buffer);
+}
+
+static u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
{
struct device *host_dev;
u64 bounce_limit = 0xffffffff;
@@ -1621,18 +1972,11 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
return bounce_limit;
}
-EXPORT_SYMBOL(scsi_calculate_bounce_limit);
-struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
- request_fn_proc *request_fn)
+static void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
{
- struct request_queue *q;
struct device *dev = shost->dma_dev;
- q = blk_init_queue(request_fn, NULL);
- if (!q)
- return NULL;
-
/*
* this limit is imposed by hardware restrictions
*/
@@ -1663,7 +2007,17 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
* blk_queue_update_dma_alignment() later.
*/
blk_queue_dma_alignment(q, 0x03);
+}
+
+struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
+ request_fn_proc *request_fn)
+{
+ struct request_queue *q;
+ q = blk_init_queue(request_fn, NULL);
+ if (!q)
+ return NULL;
+ __scsi_init_queue(shost, q);
return q;
}
EXPORT_SYMBOL(__scsi_alloc_queue);
@@ -1684,6 +2038,55 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
return q;
}
+static struct blk_mq_ops scsi_mq_ops = {
+ .map_queue = blk_mq_map_queue,
+ .queue_rq = scsi_queue_rq,
+ .complete = scsi_softirq_done,
+ .timeout = scsi_times_out,
+ .init_request = scsi_init_request,
+ .exit_request = scsi_exit_request,
+};
+
+struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev)
+{
+ sdev->request_queue = blk_mq_init_queue(&sdev->host->tag_set);
+ if (IS_ERR(sdev->request_queue))
+ return NULL;
+
+ sdev->request_queue->queuedata = sdev;
+ __scsi_init_queue(sdev->host, sdev->request_queue);
+ return sdev->request_queue;
+}
+
+int scsi_mq_setup_tags(struct Scsi_Host *shost)
+{
+ unsigned int cmd_size, sgl_size, tbl_size;
+
+ tbl_size = shost->sg_tablesize;
+ if (tbl_size > SCSI_MAX_SG_SEGMENTS)
+ tbl_size = SCSI_MAX_SG_SEGMENTS;
+ sgl_size = tbl_size * sizeof(struct scatterlist);
+ cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size + sgl_size;
+ if (scsi_host_get_prot(shost))
+ cmd_size += sizeof(struct scsi_data_buffer) + sgl_size;
+
+ memset(&shost->tag_set, 0, sizeof(shost->tag_set));
+ shost->tag_set.ops = &scsi_mq_ops;
+ shost->tag_set.nr_hw_queues = 1;
+ shost->tag_set.queue_depth = shost->can_queue;
+ shost->tag_set.cmd_size = cmd_size;
+ shost->tag_set.numa_node = NUMA_NO_NODE;
+ shost->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE;
+ shost->tag_set.driver_data = shost;
+
+ return blk_mq_alloc_tag_set(&shost->tag_set);
+}
+
+void scsi_mq_destroy_tags(struct Scsi_Host *shost)
+{
+ blk_mq_free_tag_set(&shost->tag_set);
+}
+
/*
* Function: scsi_block_requests()
*
@@ -2139,9 +2542,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
return 0;
illegal:
- SCSI_LOG_ERROR_RECOVERY(1,
+ SCSI_LOG_ERROR_RECOVERY(1,
sdev_printk(KERN_ERR, sdev,
- "Illegal state transition %s->%s\n",
+ "Illegal state transition %s->%s",
scsi_device_state_name(oldstate),
scsi_device_state_name(state))
);
@@ -2337,7 +2740,7 @@ scsi_device_quiesce(struct scsi_device *sdev)
return err;
scsi_run_queue(sdev->request_queue);
- while (sdev->device_busy) {
+ while (atomic_read(&sdev->device_busy)) {
msleep_interruptible(200);
scsi_run_queue(sdev->request_queue);
}
@@ -2429,9 +2832,13 @@ scsi_internal_device_block(struct scsi_device *sdev)
* block layer from calling the midlayer with this device's
* request queue.
*/
- spin_lock_irqsave(q->queue_lock, flags);
- blk_stop_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
+ if (q->mq_ops) {
+ blk_mq_stop_hw_queues(q);
+ } else {
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_stop_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+ }
return 0;
}
@@ -2477,9 +2884,13 @@ scsi_internal_device_unblock(struct scsi_device *sdev,
sdev->sdev_state != SDEV_OFFLINE)
return -EINVAL;
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
+ if (q->mq_ops) {
+ blk_mq_start_stopped_hw_queues(q, false);
+ } else {
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_start_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+ }
return 0;
}
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 48e5b657e79f..12b8e1bee7f0 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -88,6 +88,9 @@ extern void scsi_next_command(struct scsi_cmnd *cmd);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
extern void scsi_run_host_queues(struct Scsi_Host *shost);
extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev);
+extern struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev);
+extern int scsi_mq_setup_tags(struct Scsi_Host *shost);
+extern void scsi_mq_destroy_tags(struct Scsi_Host *shost);
extern int scsi_init_queue(void);
extern void scsi_exit_queue(void);
struct request_queue;
@@ -115,7 +118,7 @@ extern void scsi_exit_procfs(void);
extern char scsi_scan_type[];
extern int scsi_complete_async_scans(void);
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
- unsigned int, unsigned int, int);
+ unsigned int, u64, int);
extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_rescan_device(struct device *);
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 86f0c5d5c116..6fcefa2da503 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -185,7 +185,7 @@ static int proc_print_scsidevice(struct device *dev, void *data)
sdev = to_scsi_device(dev);
seq_printf(s,
- "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
+ "Host: scsi%d Channel: %02d Id: %02d Lun: %02llu\n Vendor: ",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
for (i = 0; i < 8; i++) {
if (sdev->vendor[i] >= 0x20)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index e02b3aab56ce..56675dbbf681 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -81,15 +81,11 @@ static const char *scsi_null_device_strs = "nullnullnullnull";
#define MAX_SCSI_LUNS 512
-#ifdef CONFIG_SCSI_MULTI_LUN
-static unsigned int max_scsi_luns = MAX_SCSI_LUNS;
-#else
-static unsigned int max_scsi_luns = 1;
-#endif
+static u64 max_scsi_luns = MAX_SCSI_LUNS;
-module_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR);
+module_param_named(max_luns, max_scsi_luns, ullong, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(max_luns,
- "last scsi LUN (should be between 1 and 2^32-1)");
+ "last scsi LUN (should be between 1 and 2^64-1)");
#ifdef CONFIG_SCSI_SCAN_ASYNC
#define SCSI_SCAN_TYPE_DEFAULT "async"
@@ -198,7 +194,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
{
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
- printk(KERN_NOTICE "scsi: unlocking floptical drive\n");
+ sdev_printk(KERN_NOTICE, sdev, "unlocking floptical drive\n");
scsi_cmd[0] = MODE_SENSE;
scsi_cmd[1] = 0;
scsi_cmd[2] = 0x2e;
@@ -224,7 +220,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
* scsi_Device pointer, or NULL on failure.
**/
static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
- unsigned int lun, void *hostdata)
+ u64 lun, void *hostdata)
{
struct scsi_device *sdev;
int display_failure_msg = 1, ret;
@@ -277,7 +273,10 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
*/
sdev->borken = 1;
- sdev->request_queue = scsi_alloc_queue(sdev);
+ if (shost_use_blk_mq(shost))
+ sdev->request_queue = scsi_mq_alloc_queue(sdev);
+ else
+ sdev->request_queue = scsi_alloc_queue(sdev);
if (!sdev->request_queue) {
/* release fn is set up in scsi_sysfs_device_initialise, so
* have to free and put manually here */
@@ -600,8 +599,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
HZ / 2 + HZ * scsi_inq_timeout, 3,
&resid);
- SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
- "with code 0x%x\n",
+ SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
+ "scsi scan: INQUIRY %s with code 0x%x\n",
result ? "failed" : "successful", result));
if (result) {
@@ -671,9 +670,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
}
} else if (pass == 2) {
- printk(KERN_INFO "scsi scan: %d byte inquiry failed. "
- "Consider BLIST_INQUIRY_36 for this device\n",
- try_inquiry_len);
+ sdev_printk(KERN_INFO, sdev,
+ "scsi scan: %d byte inquiry failed. "
+ "Consider BLIST_INQUIRY_36 for this device\n",
+ try_inquiry_len);
/* If this pass failed, the third pass goes back and transfers
* the same amount as we successfully got in the first pass. */
@@ -706,8 +706,9 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
* strings.
*/
if (sdev->inquiry_len < 36) {
- printk(KERN_INFO "scsi scan: INQUIRY result too short (%d),"
- " using 36\n", sdev->inquiry_len);
+ sdev_printk(KERN_INFO, sdev,
+ "scsi scan: INQUIRY result too short (%d),"
+ " using 36\n", sdev->inquiry_len);
sdev->inquiry_len = 36;
}
@@ -806,29 +807,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
sdev->removable = (inq_result[1] & 0x80) >> 7;
}
- switch (sdev->type) {
- case TYPE_RBC:
- case TYPE_TAPE:
- case TYPE_DISK:
- case TYPE_PRINTER:
- case TYPE_MOD:
- case TYPE_PROCESSOR:
- case TYPE_SCANNER:
- case TYPE_MEDIUM_CHANGER:
- case TYPE_ENCLOSURE:
- case TYPE_COMM:
- case TYPE_RAID:
- case TYPE_OSD:
- sdev->writeable = 1;
- break;
- case TYPE_ROM:
- case TYPE_WORM:
- sdev->writeable = 0;
- break;
- default:
- printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type);
- }
-
if (sdev->type == TYPE_RBC || sdev->type == TYPE_ROM) {
/* RBC and MMC devices can return SCSI-3 compliance and yet
* still not support REPORT LUNS, so make them act as
@@ -922,6 +900,12 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
if (*bflags & BLIST_USE_10_BYTE_MS)
sdev->use_10_for_ms = 1;
+ /* some devices don't like REPORT SUPPORTED OPERATION CODES
+ * and will simply timeout causing sd_mod init to take a very
+ * very long time */
+ if (*bflags & BLIST_NO_RSOC)
+ sdev->no_report_opcodes = 1;
+
/* set the device running here so that slave configure
* may do I/O */
ret = scsi_device_set_state(sdev, SDEV_RUNNING);
@@ -950,7 +934,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
- if (*bflags & BLIST_SKIP_VPD_PAGES)
+ if (*bflags & BLIST_TRY_VPD_PAGES)
+ sdev->try_vpd_pages = 1;
+ else if (*bflags & BLIST_SKIP_VPD_PAGES)
sdev->skip_vpd_pages = 1;
transport_configure_device(&sdev->sdev_gendev);
@@ -1032,7 +1018,7 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
* SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
**/
static int scsi_probe_and_add_lun(struct scsi_target *starget,
- uint lun, int *bflagsp,
+ u64 lun, int *bflagsp,
struct scsi_device **sdevp, int rescan,
void *hostdata)
{
@@ -1048,7 +1034,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
sdev = scsi_device_lookup_by_target(starget, lun);
if (sdev) {
if (rescan || !scsi_device_created(sdev)) {
- SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+ SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
"scsi scan: device exists on %s\n",
dev_name(&sdev->sdev_gendev)));
if (sdevp)
@@ -1135,7 +1121,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
(result[0] & 0x1f) == 0x1f &&
!scsi_is_wlun(lun)) {
- SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+ SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
"scsi scan: peripheral device type"
" of 31, no device added\n"));
res = SCSI_SCAN_TARGET_PRESENT;
@@ -1185,11 +1171,12 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
static void scsi_sequential_lun_scan(struct scsi_target *starget,
int bflags, int scsi_level, int rescan)
{
- unsigned int sparse_lun, lun, max_dev_lun;
+ uint max_dev_lun;
+ u64 sparse_lun, lun;
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
- SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of"
- "%s\n", dev_name(&starget->dev)));
+ SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
+ "scsi scan: Sequential scan\n"));
max_dev_lun = min(max_scsi_luns, shost->max_lun);
/*
@@ -1239,6 +1226,12 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
max_dev_lun = min(8U, max_dev_lun);
/*
+ * Stop scanning at 255 unless BLIST_SCSI3LUN
+ */
+ if (!(bflags & BLIST_SCSI3LUN))
+ max_dev_lun = min(256U, max_dev_lun);
+
+ /*
* We have already scanned LUN 0, so start at LUN 1. Keep scanning
* until we reach the max, or no LUN is found and we are not
* sparse_lun.
@@ -1260,24 +1253,25 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
* truncation before using this function.
*
* Notes:
- * The struct scsi_lun is assumed to be four levels, with each level
- * effectively containing a SCSI byte-ordered (big endian) short; the
- * addressing bits of each level are ignored (the highest two bits).
* For a description of the LUN format, post SCSI-3 see the SCSI
* Architecture Model, for SCSI-3 see the SCSI Controller Commands.
*
- * Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns
- * the integer: 0x0b030a04
+ * Given a struct scsi_lun of: d2 04 0b 03 00 00 00 00, this function
+ * returns the integer: 0x0b03d204
+ *
+ * This encoding will return a standard integer LUN for LUNs smaller
+ * than 256, which typically use a single level LUN structure with
+ * addressing method 0.
**/
-int scsilun_to_int(struct scsi_lun *scsilun)
+u64 scsilun_to_int(struct scsi_lun *scsilun)
{
int i;
- unsigned int lun;
+ u64 lun;
lun = 0;
for (i = 0; i < sizeof(lun); i += 2)
- lun = lun | (((scsilun->scsi_lun[i] << 8) |
- scsilun->scsi_lun[i + 1]) << (i * 8));
+ lun = lun | (((u64)scsilun->scsi_lun[i] << ((i + 1) * 8)) |
+ ((u64)scsilun->scsi_lun[i + 1] << (i * 8)));
return lun;
}
EXPORT_SYMBOL(scsilun_to_int);
@@ -1291,16 +1285,13 @@ EXPORT_SYMBOL(scsilun_to_int);
* Reverts the functionality of the scsilun_to_int, which packed
* an 8-byte lun value into an int. This routine unpacks the int
* back into the lun value.
- * Note: the scsilun_to_int() routine does not truly handle all
- * 8bytes of the lun value. This functions restores only as much
- * as was set by the routine.
*
* Notes:
- * Given an integer : 0x0b030a04, this function returns a
- * scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00
+ * Given an integer : 0x0b03d204, this function returns a
+ * struct scsi_lun of: d2 04 0b 03 00 00 00 00
*
**/
-void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun)
+void int_to_scsilun(u64 lun, struct scsi_lun *scsilun)
{
int i;
@@ -1340,7 +1331,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
char devname[64];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
unsigned int length;
- unsigned int lun;
+ u64 lun;
unsigned int num_luns;
unsigned int retries;
int result;
@@ -1430,17 +1421,19 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
* a retry.
*/
for (retries = 0; retries < 3; retries++) {
- SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
- " REPORT LUNS to %s (try %d)\n", devname,
+ SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+ "scsi scan: Sending REPORT LUNS to (try %d)\n",
retries));
result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
lun_data, length, &sshdr,
SCSI_TIMEOUT + 4 * HZ, 3, NULL);
- SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
- " %s (try %d) result 0x%x\n", result
- ? "failed" : "successful", retries, result));
+ SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev,
+ "scsi scan: REPORT LUNS"
+ " %s (try %d) result 0x%x\n",
+ result ? "failed" : "successful",
+ retries, result));
if (result == 0)
break;
else if (scsi_sense_valid(&sshdr)) {
@@ -1466,10 +1459,11 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
num_luns = (length / sizeof(struct scsi_lun));
if (num_luns > max_scsi_report_luns) {
- printk(KERN_WARNING "scsi: On %s only %d (max_scsi_report_luns)"
- " of %d luns reported, try increasing"
- " max_scsi_report_luns.\n", devname,
- max_scsi_report_luns, num_luns);
+ sdev_printk(KERN_WARNING, sdev,
+ "Only %d (max_scsi_report_luns)"
+ " of %d luns reported, try increasing"
+ " max_scsi_report_luns.\n",
+ max_scsi_report_luns, num_luns);
num_luns = max_scsi_report_luns;
}
@@ -1483,27 +1477,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) {
lun = scsilun_to_int(lunp);
- /*
- * Check if the unused part of lunp is non-zero, and so
- * does not fit in lun.
- */
- if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4)) {
- int i;
-
- /*
- * Output an error displaying the LUN in byte order,
- * this differs from what linux would print for the
- * integer LUN value.
- */
- printk(KERN_WARNING "scsi: %s lun 0x", devname);
- data = (char *)lunp->scsi_lun;
- for (i = 0; i < sizeof(struct scsi_lun); i++)
- printk("%02x", data[i]);
- printk(" has a LUN larger than currently supported.\n");
- } else if (lun > sdev->host->max_lun) {
- printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
- " than allowed by the host adapter\n",
- devname, lun);
+ if (lun > sdev->host->max_lun) {
+ sdev_printk(KERN_WARNING, sdev,
+ "lun%llu has a LUN larger than"
+ " allowed by the host adapter\n", lun);
} else {
int res;
@@ -1515,8 +1492,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
*/
sdev_printk(KERN_ERR, sdev,
"Unexpected response"
- " from lun %d while scanning, scan"
- " aborted\n", lun);
+ " from lun %llu while scanning, scan"
+ " aborted\n", (unsigned long long)lun);
break;
}
}
@@ -1535,7 +1512,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
}
struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
- uint id, uint lun, void *hostdata)
+ uint id, u64 lun, void *hostdata)
{
struct scsi_device *sdev = ERR_PTR(-ENODEV);
struct device *parent = &shost->shost_gendev;
@@ -1571,7 +1548,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
EXPORT_SYMBOL(__scsi_add_device);
int scsi_add_device(struct Scsi_Host *host, uint channel,
- uint target, uint lun)
+ uint target, u64 lun)
{
struct scsi_device *sdev =
__scsi_add_device(host, channel, target, lun, NULL);
@@ -1600,7 +1577,7 @@ void scsi_rescan_device(struct device *dev)
EXPORT_SYMBOL(scsi_rescan_device);
static void __scsi_scan_target(struct device *parent, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+ unsigned int id, u64 lun, int rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
int bflags = 0;
@@ -1668,7 +1645,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
* sequential scan of LUNs on the target id.
**/
void scsi_scan_target(struct device *parent, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+ unsigned int id, u64 lun, int rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
@@ -1688,7 +1665,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
EXPORT_SYMBOL(scsi_scan_target);
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+ unsigned int id, u64 lun, int rescan)
{
uint order_id;
@@ -1719,10 +1696,10 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
}
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+ unsigned int id, u64 lun, int rescan)
{
SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
- "%s: <%u:%u:%u>\n",
+ "%s: <%u:%u:%llu>\n",
__func__, channel, id, lun));
if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
@@ -1781,8 +1758,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
return NULL;
if (shost->async_scan) {
- printk("%s called twice for host %d", __func__,
- shost->host_no);
+ shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
dump_stack();
return NULL;
}
@@ -1835,8 +1811,7 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
mutex_lock(&shost->scan_mutex);
if (!shost->async_scan) {
- printk("%s called twice for host %d", __func__,
- shost->host_no);
+ shost_printk(KERN_INFO, shost, "%s called twice\n", __func__);
dump_stack();
mutex_unlock(&shost->scan_mutex);
return;
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 074e8cc30955..406b3038bbad 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -80,7 +80,7 @@ const char *scsi_host_state_name(enum scsi_host_state state)
return name;
}
-static int check_set(unsigned int *val, char *src)
+static int check_set(unsigned long long *val, char *src)
{
char *last;
@@ -90,7 +90,7 @@ static int check_set(unsigned int *val, char *src)
/*
* Doesn't check for int overflow
*/
- *val = simple_strtoul(src, &last, 0);
+ *val = simple_strtoull(src, &last, 0);
if (*last != '\0')
return 1;
}
@@ -99,11 +99,11 @@ static int check_set(unsigned int *val, char *src)
static int scsi_scan(struct Scsi_Host *shost, const char *str)
{
- char s1[15], s2[15], s3[15], junk;
- unsigned int channel, id, lun;
+ char s1[15], s2[15], s3[17], junk;
+ unsigned long long channel, id, lun;
int res;
- res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk);
+ res = sscanf(str, "%10s %10s %16s %c", s1, s2, s3, &junk);
if (res != 3)
return -EINVAL;
if (check_set(&channel, s1))
@@ -333,8 +333,8 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline);
+shost_rd_attr(use_blk_mq, "%d\n");
shost_rd_attr(unique_id, "%u\n");
-shost_rd_attr(host_busy, "%hu\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
shost_rd_attr(can_queue, "%hd\n");
shost_rd_attr(sg_tablesize, "%hu\n");
@@ -344,7 +344,16 @@ shost_rd_attr(prot_capabilities, "%u\n");
shost_rd_attr(prot_guard_type, "%hd\n");
shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
+static ssize_t
+show_host_busy(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ return snprintf(buf, 20, "%d\n", atomic_read(&shost->host_busy));
+}
+static DEVICE_ATTR(host_busy, S_IRUGO, show_host_busy, NULL);
+
static struct attribute *scsi_sysfs_shost_attrs[] = {
+ &dev_attr_use_blk_mq.attr,
&dev_attr_unique_id.attr,
&dev_attr_host_busy.attr,
&dev_attr_cmd_per_lun.attr,
@@ -577,14 +586,30 @@ static int scsi_sdev_check_buf_bit(const char *buf)
/*
* Create the actual show/store functions and data structures.
*/
-sdev_rd_attr (device_blocked, "%d\n");
-sdev_rd_attr (device_busy, "%d\n");
sdev_rd_attr (type, "%d\n");
sdev_rd_attr (scsi_level, "%d\n");
sdev_rd_attr (vendor, "%.8s\n");
sdev_rd_attr (model, "%.16s\n");
sdev_rd_attr (rev, "%.4s\n");
+static ssize_t
+sdev_show_device_busy(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_busy));
+}
+static DEVICE_ATTR(device_busy, S_IRUGO, sdev_show_device_busy, NULL);
+
+static ssize_t
+sdev_show_device_blocked(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_blocked));
+}
+static DEVICE_ATTR(device_blocked, S_IRUGO, sdev_show_device_blocked, NULL);
+
/*
* TODO: can we make these symlinks to the block layer ones?
*/
@@ -1230,13 +1255,13 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
device_initialize(&sdev->sdev_gendev);
sdev->sdev_gendev.bus = &scsi_bus_type;
sdev->sdev_gendev.type = &scsi_dev_type;
- dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%d",
+ dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
device_initialize(&sdev->sdev_dev);
sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev);
sdev->sdev_dev.class = &sdev_class;
- dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d",
+ dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%llu",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->scsi_level = starget->scsi_level;
transport_setup_device(&sdev->sdev_gendev);
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
deleted file mode 100644
index 6209110f295d..000000000000
--- a/drivers/scsi/scsi_tgt_if.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * SCSI target kernel/user interface functions
- *
- * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
- * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
- *
- * 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/miscdevice.h>
-#include <linux/gfp.h>
-#include <linux/file.h>
-#include <linux/export.h>
-#include <net/tcp.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_tgt.h>
-#include <scsi/scsi_tgt_if.h>
-
-#include <asm/cacheflush.h>
-
-#include "scsi_tgt_priv.h"
-
-#if TGT_RING_SIZE < PAGE_SIZE
-# define TGT_RING_SIZE PAGE_SIZE
-#endif
-
-#define TGT_RING_PAGES (TGT_RING_SIZE >> PAGE_SHIFT)
-#define TGT_EVENT_PER_PAGE (PAGE_SIZE / sizeof(struct tgt_event))
-#define TGT_MAX_EVENTS (TGT_EVENT_PER_PAGE * TGT_RING_PAGES)
-
-struct tgt_ring {
- u32 tr_idx;
- unsigned long tr_pages[TGT_RING_PAGES];
- spinlock_t tr_lock;
-};
-
-/* tx_ring : kernel->user, rx_ring : user->kernel */
-static struct tgt_ring tx_ring, rx_ring;
-static DECLARE_WAIT_QUEUE_HEAD(tgt_poll_wait);
-
-static inline void tgt_ring_idx_inc(struct tgt_ring *ring)
-{
- if (ring->tr_idx == TGT_MAX_EVENTS - 1)
- ring->tr_idx = 0;
- else
- ring->tr_idx++;
-}
-
-static struct tgt_event *tgt_head_event(struct tgt_ring *ring, u32 idx)
-{
- u32 pidx, off;
-
- pidx = idx / TGT_EVENT_PER_PAGE;
- off = idx % TGT_EVENT_PER_PAGE;
-
- return (struct tgt_event *)
- (ring->tr_pages[pidx] + sizeof(struct tgt_event) * off);
-}
-
-static int tgt_uspace_send_event(u32 type, struct tgt_event *p)
-{
- struct tgt_event *ev;
- struct tgt_ring *ring = &tx_ring;
- unsigned long flags;
- int err = 0;
-
- spin_lock_irqsave(&ring->tr_lock, flags);
-
- ev = tgt_head_event(ring, ring->tr_idx);
- if (!ev->hdr.status)
- tgt_ring_idx_inc(ring);
- else
- err = -BUSY;
-
- spin_unlock_irqrestore(&ring->tr_lock, flags);
-
- if (err)
- return err;
-
- memcpy(ev, p, sizeof(*ev));
- ev->hdr.type = type;
- mb();
- ev->hdr.status = 1;
-
- flush_dcache_page(virt_to_page(ev));
-
- wake_up_interruptible(&tgt_poll_wait);
-
- return 0;
-}
-
-int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 itn_id,
- struct scsi_lun *lun, u64 tag)
-{
- struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
- struct tgt_event ev;
- int err;
-
- memset(&ev, 0, sizeof(ev));
- ev.p.cmd_req.host_no = shost->host_no;
- ev.p.cmd_req.itn_id = itn_id;
- ev.p.cmd_req.data_len = scsi_bufflen(cmd);
- memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb));
- memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun));
- ev.p.cmd_req.attribute = cmd->tag;
- ev.p.cmd_req.tag = tag;
-
- dprintk("%p %d %u %x %llx\n", cmd, shost->host_no,
- ev.p.cmd_req.data_len, cmd->tag,
- (unsigned long long) ev.p.cmd_req.tag);
-
- err = tgt_uspace_send_event(TGT_KEVENT_CMD_REQ, &ev);
- if (err)
- eprintk("tx buf is full, could not send\n");
-
- return err;
-}
-
-int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 itn_id, u64 tag)
-{
- struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
- struct tgt_event ev;
- int err;
-
- memset(&ev, 0, sizeof(ev));
- ev.p.cmd_done.host_no = shost->host_no;
- ev.p.cmd_done.itn_id = itn_id;
- ev.p.cmd_done.tag = tag;
- ev.p.cmd_done.result = cmd->result;
-
- dprintk("%p %d %llu %u %x\n", cmd, shost->host_no,
- (unsigned long long) ev.p.cmd_req.tag,
- ev.p.cmd_req.data_len, cmd->tag);
-
- err = tgt_uspace_send_event(TGT_KEVENT_CMD_DONE, &ev);
- if (err)
- eprintk("tx buf is full, could not send\n");
-
- return err;
-}
-
-int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 itn_id, int function,
- u64 tag, struct scsi_lun *scsilun, void *data)
-{
- struct tgt_event ev;
- int err;
-
- memset(&ev, 0, sizeof(ev));
- ev.p.tsk_mgmt_req.host_no = host_no;
- ev.p.tsk_mgmt_req.itn_id = itn_id;
- ev.p.tsk_mgmt_req.function = function;
- ev.p.tsk_mgmt_req.tag = tag;
- memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun));
- ev.p.tsk_mgmt_req.mid = (u64) (unsigned long) data;
-
- dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag,
- (unsigned long long) ev.p.tsk_mgmt_req.mid);
-
- err = tgt_uspace_send_event(TGT_KEVENT_TSK_MGMT_REQ, &ev);
- if (err)
- eprintk("tx buf is full, could not send\n");
-
- return err;
-}
-
-int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 itn_id,
- int function, char *initiator_id)
-{
- struct tgt_event ev;
- int err;
-
- memset(&ev, 0, sizeof(ev));
- ev.p.it_nexus_req.host_no = host_no;
- ev.p.it_nexus_req.function = function;
- ev.p.it_nexus_req.itn_id = itn_id;
- if (initiator_id)
- strncpy(ev.p.it_nexus_req.initiator_id, initiator_id,
- sizeof(ev.p.it_nexus_req.initiator_id));
-
- dprintk("%d %x %llx\n", host_no, function, (unsigned long long)itn_id);
-
- err = tgt_uspace_send_event(TGT_KEVENT_IT_NEXUS_REQ, &ev);
- if (err)
- eprintk("tx buf is full, could not send\n");
-
- return err;
-}
-
-static int event_recv_msg(struct tgt_event *ev)
-{
- int err = 0;
-
- switch (ev->hdr.type) {
- case TGT_UEVENT_CMD_RSP:
- err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no,
- ev->p.cmd_rsp.itn_id,
- ev->p.cmd_rsp.result,
- ev->p.cmd_rsp.tag,
- ev->p.cmd_rsp.uaddr,
- ev->p.cmd_rsp.len,
- ev->p.cmd_rsp.sense_uaddr,
- ev->p.cmd_rsp.sense_len,
- ev->p.cmd_rsp.rw);
- break;
- case TGT_UEVENT_TSK_MGMT_RSP:
- err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no,
- ev->p.tsk_mgmt_rsp.itn_id,
- ev->p.tsk_mgmt_rsp.mid,
- ev->p.tsk_mgmt_rsp.result);
- break;
- case TGT_UEVENT_IT_NEXUS_RSP:
- err = scsi_tgt_kspace_it_nexus_rsp(ev->p.it_nexus_rsp.host_no,
- ev->p.it_nexus_rsp.itn_id,
- ev->p.it_nexus_rsp.result);
- break;
- default:
- eprintk("unknown type %d\n", ev->hdr.type);
- err = -EINVAL;
- }
-
- return err;
-}
-
-static ssize_t tgt_write(struct file *file, const char __user * buffer,
- size_t count, loff_t * ppos)
-{
- struct tgt_event *ev;
- struct tgt_ring *ring = &rx_ring;
-
- while (1) {
- ev = tgt_head_event(ring, ring->tr_idx);
- /* do we need this? */
- flush_dcache_page(virt_to_page(ev));
-
- if (!ev->hdr.status)
- break;
-
- tgt_ring_idx_inc(ring);
- event_recv_msg(ev);
- ev->hdr.status = 0;
- };
-
- return count;
-}
-
-static unsigned int tgt_poll(struct file * file, struct poll_table_struct *wait)
-{
- struct tgt_event *ev;
- struct tgt_ring *ring = &tx_ring;
- unsigned long flags;
- unsigned int mask = 0;
- u32 idx;
-
- poll_wait(file, &tgt_poll_wait, wait);
-
- spin_lock_irqsave(&ring->tr_lock, flags);
-
- idx = ring->tr_idx ? ring->tr_idx - 1 : TGT_MAX_EVENTS - 1;
- ev = tgt_head_event(ring, idx);
- if (ev->hdr.status)
- mask |= POLLIN | POLLRDNORM;
-
- spin_unlock_irqrestore(&ring->tr_lock, flags);
-
- return mask;
-}
-
-static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr,
- struct tgt_ring *ring)
-{
- int i, err;
-
- for (i = 0; i < TGT_RING_PAGES; i++) {
- struct page *page = virt_to_page(ring->tr_pages[i]);
- err = vm_insert_page(vma, addr, page);
- if (err)
- return err;
- addr += PAGE_SIZE;
- }
-
- return 0;
-}
-
-static int tgt_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long addr;
- int err;
-
- if (vma->vm_pgoff)
- return -EINVAL;
-
- if (vma->vm_end - vma->vm_start != TGT_RING_SIZE * 2) {
- eprintk("mmap size must be %lu, not %lu \n",
- TGT_RING_SIZE * 2, vma->vm_end - vma->vm_start);
- return -EINVAL;
- }
-
- addr = vma->vm_start;
- err = uspace_ring_map(vma, addr, &tx_ring);
- if (err)
- return err;
- err = uspace_ring_map(vma, addr + TGT_RING_SIZE, &rx_ring);
-
- return err;
-}
-
-static int tgt_open(struct inode *inode, struct file *file)
-{
- tx_ring.tr_idx = rx_ring.tr_idx = 0;
-
- return 0;
-}
-
-static const struct file_operations tgt_fops = {
- .owner = THIS_MODULE,
- .open = tgt_open,
- .poll = tgt_poll,
- .write = tgt_write,
- .mmap = tgt_mmap,
- .llseek = noop_llseek,
-};
-
-static struct miscdevice tgt_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "tgt",
- .fops = &tgt_fops,
-};
-
-static void tgt_ring_exit(struct tgt_ring *ring)
-{
- int i;
-
- for (i = 0; i < TGT_RING_PAGES; i++)
- free_page(ring->tr_pages[i]);
-}
-
-static int tgt_ring_init(struct tgt_ring *ring)
-{
- int i;
-
- spin_lock_init(&ring->tr_lock);
-
- for (i = 0; i < TGT_RING_PAGES; i++) {
- ring->tr_pages[i] = get_zeroed_page(GFP_KERNEL);
- if (!ring->tr_pages[i]) {
- eprintk("out of memory\n");
- return -ENOMEM;
- }
- }
-
- return 0;
-}
-
-void scsi_tgt_if_exit(void)
-{
- tgt_ring_exit(&tx_ring);
- tgt_ring_exit(&rx_ring);
- misc_deregister(&tgt_miscdev);
-}
-
-int scsi_tgt_if_init(void)
-{
- int err;
-
- err = tgt_ring_init(&tx_ring);
- if (err)
- return err;
-
- err = tgt_ring_init(&rx_ring);
- if (err)
- goto free_tx_ring;
-
- err = misc_register(&tgt_miscdev);
- if (err)
- goto free_rx_ring;
-
- return 0;
-free_rx_ring:
- tgt_ring_exit(&rx_ring);
-free_tx_ring:
- tgt_ring_exit(&tx_ring);
-
- return err;
-}
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
deleted file mode 100644
index e51add05fb8d..000000000000
--- a/drivers/scsi/scsi_tgt_lib.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- * SCSI target lib functions
- *
- * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu>
- * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
- *
- * 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/blkdev.h>
-#include <linux/hash.h>
-#include <linux/module.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_tgt.h>
-
-#include "scsi_tgt_priv.h"
-
-static struct workqueue_struct *scsi_tgtd;
-static struct kmem_cache *scsi_tgt_cmd_cache;
-
-/*
- * TODO: this struct will be killed when the block layer supports large bios
- * and James's work struct code is in
- */
-struct scsi_tgt_cmd {
- /* TODO replace work with James b's code */
- struct work_struct work;
- /* TODO fix limits of some drivers */
- struct bio *bio;
-
- struct list_head hash_list;
- struct request *rq;
- u64 itn_id;
- u64 tag;
-};
-
-#define TGT_HASH_ORDER 4
-#define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER)
-
-struct scsi_tgt_queuedata {
- struct Scsi_Host *shost;
- struct list_head cmd_hash[1 << TGT_HASH_ORDER];
- spinlock_t cmd_hash_lock;
-};
-
-/*
- * Function: scsi_host_get_command()
- *
- * Purpose: Allocate and setup a scsi command block and blk request
- *
- * Arguments: shost - scsi host
- * data_dir - dma data dir
- * gfp_mask- allocator flags
- *
- * Returns: The allocated scsi command structure.
- *
- * This should be called by target LLDs to get a command.
- */
-struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost,
- enum dma_data_direction data_dir,
- gfp_t gfp_mask)
-{
- int write = (data_dir == DMA_TO_DEVICE);
- struct request *rq;
- struct scsi_cmnd *cmd;
- struct scsi_tgt_cmd *tcmd;
-
- /* Bail if we can't get a reference to the device */
- if (!get_device(&shost->shost_gendev))
- return NULL;
-
- tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC);
- if (!tcmd)
- goto put_dev;
-
- /*
- * The blk helpers are used to the READ/WRITE requests
- * transferring data from a initiator point of view. Since
- * we are in target mode we want the opposite.
- */
- rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask);
- if (!rq)
- goto free_tcmd;
-
- cmd = __scsi_get_command(shost, gfp_mask);
- if (!cmd)
- goto release_rq;
-
- cmd->sc_data_direction = data_dir;
- cmd->jiffies_at_alloc = jiffies;
- cmd->request = rq;
-
- cmd->cmnd = rq->cmd;
-
- rq->special = cmd;
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_TYPE_BLOCK_PC;
- rq->end_io_data = tcmd;
-
- tcmd->rq = rq;
-
- return cmd;
-
-release_rq:
- blk_put_request(rq);
-free_tcmd:
- kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
-put_dev:
- put_device(&shost->shost_gendev);
- return NULL;
-
-}
-EXPORT_SYMBOL_GPL(scsi_host_get_command);
-
-/*
- * Function: scsi_host_put_command()
- *
- * Purpose: Free a scsi command block
- *
- * Arguments: shost - scsi host
- * cmd - command block to free
- *
- * Returns: Nothing.
- *
- * Notes: The command must not belong to any lists.
- */
-void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
-{
- struct request_queue *q = shost->uspace_req_q;
- struct request *rq = cmd->request;
- struct scsi_tgt_cmd *tcmd = rq->end_io_data;
- unsigned long flags;
-
- kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
-
- spin_lock_irqsave(q->queue_lock, flags);
- __blk_put_request(q, rq);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- __scsi_put_command(shost, cmd);
- put_device(&shost->shost_gendev);
-}
-EXPORT_SYMBOL_GPL(scsi_host_put_command);
-
-static void cmd_hashlist_del(struct scsi_cmnd *cmd)
-{
- struct request_queue *q = cmd->request->q;
- struct scsi_tgt_queuedata *qdata = q->queuedata;
- unsigned long flags;
- struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
-
- spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
- list_del(&tcmd->hash_list);
- spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
-}
-
-static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd)
-{
- blk_rq_unmap_user(tcmd->bio);
-}
-
-static void scsi_tgt_cmd_destroy(struct work_struct *work)
-{
- struct scsi_tgt_cmd *tcmd =
- container_of(work, struct scsi_tgt_cmd, work);
- struct scsi_cmnd *cmd = tcmd->rq->special;
-
- dprintk("cmd %p %d %u\n", cmd, cmd->sc_data_direction,
- rq_data_dir(cmd->request));
- scsi_unmap_user_pages(tcmd);
- tcmd->rq->bio = NULL;
- scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd);
-}
-
-static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd,
- u64 itn_id, u64 tag)
-{
- struct scsi_tgt_queuedata *qdata = rq->q->queuedata;
- unsigned long flags;
- struct list_head *head;
-
- tcmd->itn_id = itn_id;
- tcmd->tag = tag;
- tcmd->bio = NULL;
- INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy);
- spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
- head = &qdata->cmd_hash[cmd_hashfn(tag)];
- list_add(&tcmd->hash_list, head);
- spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
-}
-
-/*
- * scsi_tgt_alloc_queue - setup queue used for message passing
- * shost: scsi host
- *
- * This should be called by the LLD after host allocation.
- * And will be released when the host is released.
- */
-int scsi_tgt_alloc_queue(struct Scsi_Host *shost)
-{
- struct scsi_tgt_queuedata *queuedata;
- struct request_queue *q;
- int err, i;
-
- /*
- * Do we need to send a netlink event or should uspace
- * just respond to the hotplug event?
- */
- q = __scsi_alloc_queue(shost, NULL);
- if (!q)
- return -ENOMEM;
-
- queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL);
- if (!queuedata) {
- err = -ENOMEM;
- goto cleanup_queue;
- }
- queuedata->shost = shost;
- q->queuedata = queuedata;
-
- /*
- * this is a silly hack. We should probably just queue as many
- * command as is recvd to userspace. uspace can then make
- * sure we do not overload the HBA
- */
- q->nr_requests = shost->can_queue;
- /*
- * We currently only support software LLDs so this does
- * not matter for now. Do we need this for the cards we support?
- * If so we should make it a host template value.
- */
- blk_queue_dma_alignment(q, 0);
- shost->uspace_req_q = q;
-
- for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++)
- INIT_LIST_HEAD(&queuedata->cmd_hash[i]);
- spin_lock_init(&queuedata->cmd_hash_lock);
-
- return 0;
-
-cleanup_queue:
- blk_cleanup_queue(q);
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue);
-
-void scsi_tgt_free_queue(struct Scsi_Host *shost)
-{
- int i;
- unsigned long flags;
- struct request_queue *q = shost->uspace_req_q;
- struct scsi_cmnd *cmd;
- struct scsi_tgt_queuedata *qdata = q->queuedata;
- struct scsi_tgt_cmd *tcmd, *n;
- LIST_HEAD(cmds);
-
- spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
-
- for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) {
- list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i],
- hash_list)
- list_move(&tcmd->hash_list, &cmds);
- }
-
- spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
-
- while (!list_empty(&cmds)) {
- tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list);
- list_del(&tcmd->hash_list);
- cmd = tcmd->rq->special;
-
- shost->hostt->eh_abort_handler(cmd);
- scsi_tgt_cmd_destroy(&tcmd->work);
- }
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_free_queue);
-
-struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd)
-{
- struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata;
- return queue->shost;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host);
-
-/*
- * scsi_tgt_queue_command - queue command for userspace processing
- * @cmd: scsi command
- * @scsilun: scsi lun
- * @tag: unique value to identify this command for tmf
- */
-int scsi_tgt_queue_command(struct scsi_cmnd *cmd, u64 itn_id,
- struct scsi_lun *scsilun, u64 tag)
-{
- struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
- int err;
-
- init_scsi_tgt_cmd(cmd->request, tcmd, itn_id, tag);
- err = scsi_tgt_uspace_send_cmd(cmd, itn_id, scsilun, tag);
- if (err)
- cmd_hashlist_del(cmd);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_queue_command);
-
-/*
- * This is run from a interrupt handler normally and the unmap
- * needs process context so we must queue
- */
-static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
-{
- struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
-
- dprintk("cmd %p %u\n", cmd, rq_data_dir(cmd->request));
-
- scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
-
- scsi_release_buffers(cmd);
-
- queue_work(scsi_tgtd, &tcmd->work);
-}
-
-static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd)
-{
- struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd);
- int err;
-
- dprintk("cmd %p %u\n", cmd, rq_data_dir(cmd->request));
-
- err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done);
- switch (err) {
- case SCSI_MLQUEUE_HOST_BUSY:
- case SCSI_MLQUEUE_DEVICE_BUSY:
- return -EAGAIN;
- }
- return 0;
-}
-
-/* TODO: test this crap and replace bio_map_user with new interface maybe */
-static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd,
- unsigned long uaddr, unsigned int len, int rw)
-{
- struct request_queue *q = cmd->request->q;
- struct request *rq = cmd->request;
- int err;
-
- dprintk("%lx %u\n", uaddr, len);
- err = blk_rq_map_user(q, rq, NULL, (void *)uaddr, len, GFP_KERNEL);
- if (err) {
- /*
- * TODO: need to fixup sg_tablesize, max_segment_size,
- * max_sectors, etc for modern HW and software drivers
- * where this value is bogus.
- *
- * TODO2: we can alloc a reserve buffer of max size
- * we can handle and do the slow copy path for really large
- * IO.
- */
- eprintk("Could not handle request of size %u.\n", len);
- return err;
- }
-
- tcmd->bio = rq->bio;
- err = scsi_init_io(cmd, GFP_KERNEL);
- if (err) {
- scsi_release_buffers(cmd);
- goto unmap_rq;
- }
- /*
- * we use REQ_TYPE_BLOCK_PC so scsi_init_io doesn't set the
- * length for us.
- */
- cmd->sdb.length = blk_rq_bytes(rq);
-
- return 0;
-
-unmap_rq:
- scsi_unmap_user_pages(tcmd);
- return err;
-}
-
-static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr,
- unsigned len)
-{
- char __user *p = (char __user *) uaddr;
-
- if (copy_from_user(cmd->sense_buffer, p,
- min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) {
- printk(KERN_ERR "Could not copy the sense buffer\n");
- return -EIO;
- }
- return 0;
-}
-
-static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
-{
- struct scsi_tgt_cmd *tcmd;
- int err;
-
- err = shost->hostt->eh_abort_handler(cmd);
- if (err)
- eprintk("fail to abort %p\n", cmd);
-
- tcmd = cmd->request->end_io_data;
- scsi_tgt_cmd_destroy(&tcmd->work);
- return err;
-}
-
-static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag)
-{
- struct scsi_tgt_queuedata *qdata = q->queuedata;
- struct request *rq = NULL;
- struct list_head *head;
- struct scsi_tgt_cmd *tcmd;
- unsigned long flags;
-
- head = &qdata->cmd_hash[cmd_hashfn(tag)];
- spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
- list_for_each_entry(tcmd, head, hash_list) {
- if (tcmd->tag == tag) {
- rq = tcmd->rq;
- list_del(&tcmd->hash_list);
- break;
- }
- }
- spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
-
- return rq;
-}
-
-int scsi_tgt_kspace_exec(int host_no, u64 itn_id, int result, u64 tag,
- unsigned long uaddr, u32 len, unsigned long sense_uaddr,
- u32 sense_len, u8 rw)
-{
- struct Scsi_Host *shost;
- struct scsi_cmnd *cmd;
- struct request *rq;
- struct scsi_tgt_cmd *tcmd;
- int err = 0;
-
- dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag,
- result, len, uaddr, rw);
-
- /* TODO: replace with a O(1) alg */
- shost = scsi_host_lookup(host_no);
- if (!shost) {
- printk(KERN_ERR "Could not find host no %d\n", host_no);
- return -EINVAL;
- }
-
- if (!shost->uspace_req_q) {
- printk(KERN_ERR "Not target scsi host %d\n", host_no);
- goto done;
- }
-
- rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag);
- if (!rq) {
- printk(KERN_ERR "Could not find tag %llu\n",
- (unsigned long long) tag);
- err = -EINVAL;
- goto done;
- }
- cmd = rq->special;
-
- dprintk("cmd %p scb %x result %d len %d bufflen %u %u %x\n",
- cmd, cmd->cmnd[0], result, len, scsi_bufflen(cmd),
- rq_data_dir(rq), cmd->cmnd[0]);
-
- if (result == TASK_ABORTED) {
- scsi_tgt_abort_cmd(shost, cmd);
- goto done;
- }
- /*
- * store the userspace values here, the working values are
- * in the request_* values
- */
- tcmd = cmd->request->end_io_data;
- cmd->result = result;
-
- if (cmd->result == SAM_STAT_CHECK_CONDITION)
- scsi_tgt_copy_sense(cmd, sense_uaddr, sense_len);
-
- if (len) {
- err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw);
- if (err) {
- /*
- * user-space daemon bugs or OOM
- * TODO: we can do better for OOM.
- */
- struct scsi_tgt_queuedata *qdata;
- struct list_head *head;
- unsigned long flags;
-
- eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n",
- cmd, err, uaddr, len, rw);
-
- qdata = shost->uspace_req_q->queuedata;
- head = &qdata->cmd_hash[cmd_hashfn(tcmd->tag)];
-
- spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
- list_add(&tcmd->hash_list, head);
- spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
-
- goto done;
- }
- }
- err = scsi_tgt_transfer_response(cmd);
-done:
- scsi_host_put(shost);
- return err;
-}
-
-int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, u64 itn_id,
- int function, u64 tag, struct scsi_lun *scsilun,
- void *data)
-{
- int err;
-
- /* TODO: need to retry if this fails. */
- err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, itn_id,
- function, tag, scsilun, data);
- if (err < 0)
- eprintk("The task management request lost!\n");
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request);
-
-int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result)
-{
- struct Scsi_Host *shost;
- int err = -EINVAL;
-
- dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid);
-
- shost = scsi_host_lookup(host_no);
- if (!shost) {
- printk(KERN_ERR "Could not find host no %d\n", host_no);
- return err;
- }
-
- if (!shost->uspace_req_q) {
- printk(KERN_ERR "Not target scsi host %d\n", host_no);
- goto done;
- }
-
- err = shost->transportt->tsk_mgmt_response(shost, itn_id, mid, result);
-done:
- scsi_host_put(shost);
- return err;
-}
-
-int scsi_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
- char *initiator)
-{
- int err;
-
- /* TODO: need to retry if this fails. */
- err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, itn_id, 0,
- initiator);
- if (err < 0)
- eprintk("The i_t_neuxs request lost, %d %llx!\n",
- shost->host_no, (unsigned long long)itn_id);
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_create);
-
-int scsi_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
-{
- int err;
-
- /* TODO: need to retry if this fails. */
- err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no,
- itn_id, 1, NULL);
- if (err < 0)
- eprintk("The i_t_neuxs request lost, %d %llx!\n",
- shost->host_no, (unsigned long long)itn_id);
- return err;
-}
-EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_destroy);
-
-int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 itn_id, int result)
-{
- struct Scsi_Host *shost;
- int err = -EINVAL;
-
- dprintk("%d %d%llx\n", host_no, result, (unsigned long long)itn_id);
-
- shost = scsi_host_lookup(host_no);
- if (!shost) {
- printk(KERN_ERR "Could not find host no %d\n", host_no);
- return err;
- }
-
- if (!shost->uspace_req_q) {
- printk(KERN_ERR "Not target scsi host %d\n", host_no);
- goto done;
- }
-
- err = shost->transportt->it_nexus_response(shost, itn_id, result);
-done:
- scsi_host_put(shost);
- return err;
-}
-
-static int __init scsi_tgt_init(void)
-{
- int err;
-
- scsi_tgt_cmd_cache = KMEM_CACHE(scsi_tgt_cmd, 0);
- if (!scsi_tgt_cmd_cache)
- return -ENOMEM;
-
- scsi_tgtd = alloc_workqueue("scsi_tgtd", 0, 1);
- if (!scsi_tgtd) {
- err = -ENOMEM;
- goto free_kmemcache;
- }
-
- err = scsi_tgt_if_init();
- if (err)
- goto destroy_wq;
-
- return 0;
-
-destroy_wq:
- destroy_workqueue(scsi_tgtd);
-free_kmemcache:
- kmem_cache_destroy(scsi_tgt_cmd_cache);
- return err;
-}
-
-static void __exit scsi_tgt_exit(void)
-{
- destroy_workqueue(scsi_tgtd);
- scsi_tgt_if_exit();
- kmem_cache_destroy(scsi_tgt_cmd_cache);
-}
-
-module_init(scsi_tgt_init);
-module_exit(scsi_tgt_exit);
-
-MODULE_DESCRIPTION("SCSI target core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h
deleted file mode 100644
index fe4c62177f78..000000000000
--- a/drivers/scsi/scsi_tgt_priv.h
+++ /dev/null
@@ -1,32 +0,0 @@
-struct scsi_cmnd;
-struct scsi_lun;
-struct Scsi_Host;
-struct task_struct;
-
-/* tmp - will replace with SCSI logging stuff */
-#define eprintk(fmt, args...) \
-do { \
- printk("%s(%d) " fmt, __func__, __LINE__, ##args); \
-} while (0)
-
-#define dprintk(fmt, args...)
-/* #define dprintk eprintk */
-
-extern void scsi_tgt_if_exit(void);
-extern int scsi_tgt_if_init(void);
-
-extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 it_nexus_id,
- struct scsi_lun *lun, u64 tag);
-extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 it_nexus_id,
- u64 tag);
-extern int scsi_tgt_kspace_exec(int host_no, u64 it_nexus_id, int result, u64 tag,
- unsigned long uaddr, u32 len,
- unsigned long sense_uaddr, u32 sense_len, u8 rw);
-extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 it_nexus_id,
- int function, u64 tag,
- struct scsi_lun *scsilun, void *data);
-extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 it_nexus_id,
- u64 mid, int result);
-extern int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 it_nexus_id,
- int function, char *initiator);
-extern int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 it_nexus_id, int result);
diff --git a/drivers/scsi/scsi_trace.c b/drivers/scsi/scsi_trace.c
index 2bea4f0b684a..503594e5f76d 100644
--- a/drivers/scsi/scsi_trace.c
+++ b/drivers/scsi/scsi_trace.c
@@ -28,7 +28,7 @@ scsi_trace_misc(struct trace_seq *, unsigned char *, int);
static const char *
scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0;
lba |= ((cdb[1] & 0x1F) << 16);
@@ -46,7 +46,7 @@ scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0;
lba |= (cdb[2] << 24);
@@ -71,7 +71,7 @@ scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0;
lba |= (cdb[2] << 24);
@@ -94,7 +94,7 @@ scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0;
lba |= ((u64)cdb[2] << 56);
@@ -125,7 +125,7 @@ scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len, *cmd;
+ const char *ret = trace_seq_buffer_ptr(p), *cmd;
sector_t lba = 0, txlen = 0;
u32 ei_lbrt = 0;
@@ -180,7 +180,7 @@ out:
static const char *
scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
unsigned int regions = cdb[7] << 8 | cdb[8];
trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
@@ -192,7 +192,7 @@ scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len, *cmd;
+ const char *ret = trace_seq_buffer_ptr(p), *cmd;
sector_t lba = 0;
u32 alloc_len = 0;
@@ -247,7 +247,7 @@ scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
static const char *
scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
{
- const char *ret = p->buffer + p->len;
+ const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "-");
trace_seq_putc(p, 0);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index f80908f74ca9..5d6f348eb3d8 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -39,7 +39,6 @@
#include <scsi/scsi_netlink_fc.h>
#include <scsi/scsi_bsg_fc.h>
#include "scsi_priv.h"
-#include "scsi_transport_fc_internal.h"
static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
static void fc_vport_sched_delete(struct work_struct *work);
@@ -262,6 +261,10 @@ static const struct {
{ FC_PORTSPEED_8GBIT, "8 Gbit" },
{ FC_PORTSPEED_16GBIT, "16 Gbit" },
{ FC_PORTSPEED_32GBIT, "32 Gbit" },
+ { FC_PORTSPEED_20GBIT, "20 Gbit" },
+ { FC_PORTSPEED_40GBIT, "40 Gbit" },
+ { FC_PORTSPEED_50GBIT, "50 Gbit" },
+ { FC_PORTSPEED_100GBIT, "100 Gbit" },
{ FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" },
};
fc_bitfield_name_search(port_speed, fc_port_speed_names)
@@ -2089,7 +2092,7 @@ fc_timed_out(struct scsi_cmnd *scmd)
* on the rport.
*/
static void
-fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
+fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
{
struct fc_rport *rport;
unsigned long flags;
@@ -2121,7 +2124,7 @@ fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
* object as the parent.
*/
static int
-fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun)
+fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
{
uint chlo, chhi;
uint tgtlo, tgthi;
@@ -2549,6 +2552,7 @@ fc_rport_final_delete(struct work_struct *work)
fc_flush_devloss(shost);
if (!cancel_delayed_work(&rport->dev_loss_work))
fc_flush_devloss(shost);
+ cancel_work_sync(&rport->scan_work);
spin_lock_irqsave(shost->host_lock, flags);
rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
}
@@ -3007,10 +3011,6 @@ fc_remote_port_delete(struct fc_rport *rport)
spin_unlock_irqrestore(shost->host_lock, flags);
- if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR &&
- shost->active_mode & MODE_TARGET)
- fc_tgt_it_nexus_destroy(shost, (unsigned long)rport);
-
scsi_target_block(&rport->dev);
/* see if we need to kill io faster than waiting for device loss */
@@ -3051,7 +3051,6 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
unsigned long flags;
int create = 0;
- int ret;
spin_lock_irqsave(shost->host_lock, flags);
if (roles & FC_PORT_ROLE_FCP_TARGET) {
@@ -3060,12 +3059,6 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
create = 1;
} else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
create = 1;
- } else if (shost->active_mode & MODE_TARGET) {
- ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport,
- (char *)&rport->node_name);
- if (ret)
- printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n",
- ret);
}
rport->roles = roles;
diff --git a/drivers/scsi/scsi_transport_fc_internal.h b/drivers/scsi/scsi_transport_fc_internal.h
deleted file mode 100644
index e7bfbe751c1f..000000000000
--- a/drivers/scsi/scsi_transport_fc_internal.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <scsi/scsi_tgt.h>
-
-#ifdef CONFIG_SCSI_FC_TGT_ATTRS
-static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
- char *initiator)
-{
- return scsi_tgt_it_nexus_create(shost, itn_id, initiator);
-}
-
-static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
-{
- return scsi_tgt_it_nexus_destroy(shost, itn_id);
-}
-#else
-static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
- char *initiator)
-{
- return 0;
-}
-
-static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
-{
- return 0;
-}
-
-#endif
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 0102a2d70dd8..b481e62a12cc 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1780,7 +1780,7 @@ EXPORT_SYMBOL_GPL(iscsi_scan_finished);
struct iscsi_scan_data {
unsigned int channel;
unsigned int id;
- unsigned int lun;
+ u64 lun;
};
static int iscsi_user_scan_session(struct device *dev, void *data)
@@ -1827,7 +1827,7 @@ user_scan_exit:
}
static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
- uint id, uint lun)
+ uint id, u64 lun)
{
struct iscsi_scan_data scan_data;
@@ -3059,7 +3059,7 @@ iscsi_get_chap(struct iscsi_transport *transport, struct nlmsghdr *nlh)
evchap->u.get_chap.host_no = ev->u.get_chap.host_no;
evchap->u.get_chap.chap_tbl_idx = ev->u.get_chap.chap_tbl_idx;
evchap->u.get_chap.num_entries = ev->u.get_chap.num_entries;
- buf = (char *) ((char *)evchap + sizeof(*evchap));
+ buf = (char *)evchap + sizeof(*evchap);
memset(buf, 0, chap_buf_size);
err = transport->get_chap(shost, ev->u.get_chap.chap_tbl_idx,
@@ -3463,7 +3463,7 @@ iscsi_get_host_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
evhost_stats->type = nlh->nlmsg_type;
evhost_stats->u.get_host_stats.host_no =
ev->u.get_host_stats.host_no;
- buf = (char *)((char *)evhost_stats + sizeof(*evhost_stats));
+ buf = (char *)evhost_stats + sizeof(*evhost_stats);
memset(buf, 0, host_stats_size);
err = transport->get_host_stats(shost, buf, host_stats_size);
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index c341f855fadc..9a058194b9bd 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -1705,7 +1705,7 @@ EXPORT_SYMBOL(scsi_is_sas_rphy);
*/
static int sas_user_scan(struct Scsi_Host *shost, uint channel,
- uint id, uint lun)
+ uint id, u64 lun)
{
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
struct sas_rphy *rphy;
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index 13e898332e45..43fea2219f83 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -33,7 +33,6 @@
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_srp.h>
#include "scsi_priv.h"
-#include "scsi_transport_srp_internal.h"
struct srp_host_attrs {
atomic_t next_port_id;
@@ -746,18 +745,6 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost,
return ERR_PTR(ret);
}
- if (shost->active_mode & MODE_TARGET &&
- ids->roles == SRP_RPORT_ROLE_INITIATOR) {
- ret = srp_tgt_it_nexus_create(shost, (unsigned long)rport,
- rport->port_id);
- if (ret) {
- device_del(&rport->dev);
- transport_destroy_device(&rport->dev);
- put_device(&rport->dev);
- return ERR_PTR(ret);
- }
- }
-
transport_add_device(&rport->dev);
transport_configure_device(&rport->dev);
@@ -774,11 +761,6 @@ EXPORT_SYMBOL_GPL(srp_rport_add);
void srp_rport_del(struct srp_rport *rport)
{
struct device *dev = &rport->dev;
- struct Scsi_Host *shost = dev_to_shost(dev->parent);
-
- if (shost->active_mode & MODE_TARGET &&
- rport->roles == SRP_RPORT_ROLE_INITIATOR)
- srp_tgt_it_nexus_destroy(shost, (unsigned long)rport);
transport_remove_device(dev);
device_del(dev);
diff --git a/drivers/scsi/scsi_transport_srp_internal.h b/drivers/scsi/scsi_transport_srp_internal.h
deleted file mode 100644
index 8a79747f9f3d..000000000000
--- a/drivers/scsi/scsi_transport_srp_internal.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <scsi/scsi_tgt.h>
-
-#ifdef CONFIG_SCSI_SRP_TGT_ATTRS
-static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
- char *initiator)
-{
- return scsi_tgt_it_nexus_create(shost, itn_id, initiator);
-}
-
-static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
-{
- return scsi_tgt_it_nexus_destroy(shost, itn_id);
-}
-
-#else
-static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
- char *initiator)
-{
- return 0;
-}
-static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
-{
- return 0;
-}
-#endif
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e9689d57ccb6..2c2041ca4b70 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -134,6 +134,19 @@ static const char *sd_cache_types[] = {
"write back, no read (daft)"
};
+static void sd_set_flush_flag(struct scsi_disk *sdkp)
+{
+ unsigned flush = 0;
+
+ if (sdkp->WCE) {
+ flush |= REQ_FLUSH;
+ if (sdkp->DPOFUA)
+ flush |= REQ_FUA;
+ }
+
+ blk_queue_flush(sdkp->disk->queue, flush);
+}
+
static ssize_t
cache_type_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -177,6 +190,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
if (sdkp->cache_override) {
sdkp->WCE = wce;
sdkp->RCD = rcd;
+ sd_set_flush_flag(sdkp);
return count;
}
@@ -677,8 +691,10 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
* Will issue either UNMAP or WRITE SAME(16) depending on preference
* indicated by target device.
**/
-static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
{
+ struct request *rq = cmd->request;
+ struct scsi_device *sdp = cmd->device;
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
sector_t sector = blk_rq_pos(rq);
unsigned int nr_sectors = blk_rq_sectors(rq);
@@ -690,9 +706,6 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
sector >>= ilog2(sdp->sector_size) - 9;
nr_sectors >>= ilog2(sdp->sector_size) - 9;
- rq->timeout = SD_TIMEOUT;
-
- memset(rq->cmd, 0, rq->cmd_len);
page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
if (!page)
@@ -702,9 +715,9 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
case SD_LBP_UNMAP:
buf = page_address(page);
- rq->cmd_len = 10;
- rq->cmd[0] = UNMAP;
- rq->cmd[8] = 24;
+ cmd->cmd_len = 10;
+ cmd->cmnd[0] = UNMAP;
+ cmd->cmnd[8] = 24;
put_unaligned_be16(6 + 16, &buf[0]);
put_unaligned_be16(16, &buf[2]);
@@ -715,23 +728,23 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
break;
case SD_LBP_WS16:
- rq->cmd_len = 16;
- rq->cmd[0] = WRITE_SAME_16;
- rq->cmd[1] = 0x8; /* UNMAP */
- put_unaligned_be64(sector, &rq->cmd[2]);
- put_unaligned_be32(nr_sectors, &rq->cmd[10]);
+ cmd->cmd_len = 16;
+ cmd->cmnd[0] = WRITE_SAME_16;
+ cmd->cmnd[1] = 0x8; /* UNMAP */
+ put_unaligned_be64(sector, &cmd->cmnd[2]);
+ put_unaligned_be32(nr_sectors, &cmd->cmnd[10]);
len = sdkp->device->sector_size;
break;
case SD_LBP_WS10:
case SD_LBP_ZERO:
- rq->cmd_len = 10;
- rq->cmd[0] = WRITE_SAME;
+ cmd->cmd_len = 10;
+ cmd->cmnd[0] = WRITE_SAME;
if (sdkp->provisioning_mode == SD_LBP_WS10)
- rq->cmd[1] = 0x8; /* UNMAP */
- put_unaligned_be32(sector, &rq->cmd[2]);
- put_unaligned_be16(nr_sectors, &rq->cmd[7]);
+ cmd->cmnd[1] = 0x8; /* UNMAP */
+ put_unaligned_be32(sector, &cmd->cmnd[2]);
+ put_unaligned_be16(nr_sectors, &cmd->cmnd[7]);
len = sdkp->device->sector_size;
break;
@@ -742,8 +755,21 @@ static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
}
rq->completion_data = page;
+ rq->timeout = SD_TIMEOUT;
+
+ cmd->transfersize = len;
+ cmd->allowed = SD_MAX_RETRIES;
+
+ /*
+ * Initially __data_len is set to the amount of data that needs to be
+ * transferred to the target. This amount depends on whether WRITE SAME
+ * or UNMAP is being used. After the scatterlist has been mapped by
+ * scsi_init_io() we set __data_len to the size of the area to be
+ * discarded on disk. This allows us to report completion on the full
+ * amount of blocks described by the request.
+ */
blk_add_request_payload(rq, page, len);
- ret = scsi_setup_blk_pc_cmnd(sdp, rq);
+ ret = scsi_init_io(cmd, GFP_ATOMIC);
rq->__data_len = nr_bytes;
out:
@@ -785,14 +811,15 @@ out:
/**
* sd_setup_write_same_cmnd - write the same data to multiple blocks
- * @sdp: scsi device to operate one
- * @rq: Request to prepare
+ * @cmd: command to prepare
*
* Will issue either WRITE SAME(10) or WRITE SAME(16) depending on
* preference indicated by target device.
**/
-static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
{
+ struct request *rq = cmd->request;
+ struct scsi_device *sdp = cmd->device;
struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
struct bio *bio = rq->bio;
sector_t sector = blk_rq_pos(rq);
@@ -808,53 +835,56 @@ static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq)
sector >>= ilog2(sdp->sector_size) - 9;
nr_sectors >>= ilog2(sdp->sector_size) - 9;
- rq->__data_len = sdp->sector_size;
rq->timeout = SD_WRITE_SAME_TIMEOUT;
- memset(rq->cmd, 0, rq->cmd_len);
if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) {
- rq->cmd_len = 16;
- rq->cmd[0] = WRITE_SAME_16;
- put_unaligned_be64(sector, &rq->cmd[2]);
- put_unaligned_be32(nr_sectors, &rq->cmd[10]);
+ cmd->cmd_len = 16;
+ cmd->cmnd[0] = WRITE_SAME_16;
+ put_unaligned_be64(sector, &cmd->cmnd[2]);
+ put_unaligned_be32(nr_sectors, &cmd->cmnd[10]);
} else {
- rq->cmd_len = 10;
- rq->cmd[0] = WRITE_SAME;
- put_unaligned_be32(sector, &rq->cmd[2]);
- put_unaligned_be16(nr_sectors, &rq->cmd[7]);
+ cmd->cmd_len = 10;
+ cmd->cmnd[0] = WRITE_SAME;
+ put_unaligned_be32(sector, &cmd->cmnd[2]);
+ put_unaligned_be16(nr_sectors, &cmd->cmnd[7]);
}
- ret = scsi_setup_blk_pc_cmnd(sdp, rq);
- rq->__data_len = nr_bytes;
+ cmd->transfersize = sdp->sector_size;
+ cmd->allowed = SD_MAX_RETRIES;
+ /*
+ * For WRITE_SAME the data transferred in the DATA IN buffer is
+ * different from the amount of data actually written to the target.
+ *
+ * We set up __data_len to the amount of data transferred from the
+ * DATA IN buffer so that blk_rq_map_sg set up the proper S/G list
+ * to transfer a single sector of data first, but then reset it to
+ * the amount of data to be written right after so that the I/O path
+ * knows how much to actually write.
+ */
+ rq->__data_len = sdp->sector_size;
+ ret = scsi_init_io(cmd, GFP_ATOMIC);
+ rq->__data_len = nr_bytes;
return ret;
}
-static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
+static int sd_setup_flush_cmnd(struct scsi_cmnd *cmd)
{
- rq->timeout *= SD_FLUSH_TIMEOUT_MULTIPLIER;
- rq->retries = SD_MAX_RETRIES;
- rq->cmd[0] = SYNCHRONIZE_CACHE;
- rq->cmd_len = 10;
+ struct request *rq = cmd->request;
- return scsi_setup_blk_pc_cmnd(sdp, rq);
-}
-
-static void sd_uninit_command(struct scsi_cmnd *SCpnt)
-{
- struct request *rq = SCpnt->request;
+ /* flush requests don't perform I/O, zero the S/G table */
+ memset(&cmd->sdb, 0, sizeof(cmd->sdb));
- if (rq->cmd_flags & REQ_DISCARD)
- __free_page(rq->completion_data);
+ cmd->cmnd[0] = SYNCHRONIZE_CACHE;
+ cmd->cmd_len = 10;
+ cmd->transfersize = 0;
+ cmd->allowed = SD_MAX_RETRIES;
- if (SCpnt->cmnd != rq->cmd) {
- mempool_free(SCpnt->cmnd, sd_cdb_pool);
- SCpnt->cmnd = NULL;
- SCpnt->cmd_len = 0;
- }
+ rq->timeout = rq->q->rq_timeout * SD_FLUSH_TIMEOUT_MULTIPLIER;
+ return BLKPREP_OK;
}
-static int sd_init_command(struct scsi_cmnd *SCpnt)
+static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
{
struct request *rq = SCpnt->request;
struct scsi_device *sdp = SCpnt->device;
@@ -866,21 +896,7 @@ static int sd_init_command(struct scsi_cmnd *SCpnt)
int ret, host_dif;
unsigned char protect;
- /*
- * Discard request come in as REQ_TYPE_FS but we turn them into
- * block PC requests to make life easier.
- */
- if (rq->cmd_flags & REQ_DISCARD) {
- ret = sd_setup_discard_cmnd(sdp, rq);
- goto out;
- } else if (rq->cmd_flags & REQ_WRITE_SAME) {
- ret = sd_setup_write_same_cmnd(sdp, rq);
- goto out;
- } else if (rq->cmd_flags & REQ_FLUSH) {
- ret = scsi_setup_flush_cmnd(sdp, rq);
- goto out;
- }
- ret = scsi_setup_fs_cmnd(sdp, rq);
+ ret = scsi_init_io(SCpnt, GFP_ATOMIC);
if (ret != BLKPREP_OK)
goto out;
SCpnt = rq->special;
@@ -976,18 +992,13 @@ static int sd_init_command(struct scsi_cmnd *SCpnt)
}
}
if (rq_data_dir(rq) == WRITE) {
- if (!sdp->writeable) {
- goto out;
- }
SCpnt->cmnd[0] = WRITE_6;
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
if (blk_integrity_rq(rq))
sd_dif_prepare(rq, block, sdp->sector_size);
} else if (rq_data_dir(rq) == READ) {
SCpnt->cmnd[0] = READ_6;
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
scmd_printk(KERN_ERR, SCpnt, "Unknown command %llx\n", (unsigned long long) rq->cmd_flags);
goto out;
@@ -1042,7 +1053,7 @@ static int sd_init_command(struct scsi_cmnd *SCpnt)
SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff;
SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff;
SCpnt->cmnd[31] = (unsigned char) this_count & 0xff;
- } else if (sdp->use_16_for_rw) {
+ } else if (sdp->use_16_for_rw || (this_count > 0xffff)) {
SCpnt->cmnd[0] += READ_16 - READ_6;
SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0);
SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
@@ -1061,9 +1072,6 @@ static int sd_init_command(struct scsi_cmnd *SCpnt)
} else if ((this_count > 0xff) || (block > 0x1fffff) ||
scsi_device_protection(SCpnt->device) ||
SCpnt->device->use_10_for_rw) {
- if (this_count > 0xffff)
- this_count = 0xffff;
-
SCpnt->cmnd[0] += READ_10 - READ_6;
SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0);
SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
@@ -1116,6 +1124,34 @@ static int sd_init_command(struct scsi_cmnd *SCpnt)
return ret;
}
+static int sd_init_command(struct scsi_cmnd *cmd)
+{
+ struct request *rq = cmd->request;
+
+ if (rq->cmd_flags & REQ_DISCARD)
+ return sd_setup_discard_cmnd(cmd);
+ else if (rq->cmd_flags & REQ_WRITE_SAME)
+ return sd_setup_write_same_cmnd(cmd);
+ else if (rq->cmd_flags & REQ_FLUSH)
+ return sd_setup_flush_cmnd(cmd);
+ else
+ return sd_setup_read_write_cmnd(cmd);
+}
+
+static void sd_uninit_command(struct scsi_cmnd *SCpnt)
+{
+ struct request *rq = SCpnt->request;
+
+ if (rq->cmd_flags & REQ_DISCARD)
+ __free_page(rq->completion_data);
+
+ if (SCpnt->cmnd != rq->cmd) {
+ mempool_free(SCpnt->cmnd, sd_cdb_pool);
+ SCpnt->cmnd = NULL;
+ SCpnt->cmd_len = 0;
+ }
+}
+
/**
* sd_open - open a scsi disk device
* @inode: only i_rdev member may be used
@@ -2225,7 +2261,11 @@ got_data:
}
}
- sdp->use_16_for_rw = (sdkp->capacity > 0xffffffff);
+ if (sdkp->capacity > 0xffffffff) {
+ sdp->use_16_for_rw = 1;
+ sdkp->max_xfer_blocks = SD_MAX_XFER_BLOCKS;
+ } else
+ sdkp->max_xfer_blocks = SD_DEF_XFER_BLOCKS;
/* Rescale capacity to 512-byte units */
if (sector_size == 4096)
@@ -2441,7 +2481,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
}
sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
- if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
+ if (sdp->broken_fua) {
+ sd_first_printk(KERN_NOTICE, sdkp, "Disabling FUA\n");
+ sdkp->DPOFUA = 0;
+ } else if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
sd_first_printk(KERN_NOTICE, sdkp,
"Uses READ/WRITE(6), disabling FUA\n");
sdkp->DPOFUA = 0;
@@ -2537,6 +2580,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
{
unsigned int sector_sz = sdkp->device->sector_size;
const int vpd_len = 64;
+ u32 max_xfer_length;
unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
if (!buffer ||
@@ -2544,6 +2588,10 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len))
goto out;
+ max_xfer_length = get_unaligned_be32(&buffer[8]);
+ if (max_xfer_length)
+ sdkp->max_xfer_blocks = max_xfer_length;
+
blk_queue_io_min(sdkp->disk->queue,
get_unaligned_be16(&buffer[6]) * sector_sz);
blk_queue_io_opt(sdkp->disk->queue,
@@ -2678,6 +2726,11 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
static int sd_try_extended_inquiry(struct scsi_device *sdp)
{
+ /* Attempt VPD inquiry if the device blacklist explicitly calls
+ * for it.
+ */
+ if (sdp->try_vpd_pages)
+ return 1;
/*
* Although VPD inquiries can go to SCSI-2 type devices,
* some USB ones crash on receiving them, and the pages
@@ -2698,7 +2751,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdp = sdkp->device;
unsigned char *buffer;
- unsigned flush = 0;
+ unsigned int max_xfer;
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
"sd_revalidate_disk\n"));
@@ -2744,14 +2797,12 @@ static int sd_revalidate_disk(struct gendisk *disk)
* We now have all cache related info, determine how we deal
* with flush requests.
*/
- if (sdkp->WCE) {
- flush |= REQ_FLUSH;
- if (sdkp->DPOFUA)
- flush |= REQ_FUA;
- }
-
- blk_queue_flush(sdkp->disk->queue, flush);
+ sd_set_flush_flag(sdkp);
+ max_xfer = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue),
+ sdkp->max_xfer_blocks);
+ max_xfer <<= ilog2(sdp->sector_size) - 9;
+ blk_queue_max_hw_sectors(sdkp->disk->queue, max_xfer);
set_capacity(disk, sdkp->capacity);
sd_config_write_same(sdkp);
kfree(buffer);
@@ -3205,12 +3256,14 @@ static int __init init_sd(void)
0, 0, NULL);
if (!sd_cdb_cache) {
printk(KERN_ERR "sd: can't init extended cdb cache\n");
+ err = -ENOMEM;
goto err_out_class;
}
sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache);
if (!sd_cdb_pool) {
printk(KERN_ERR "sd: can't init extended cdb pool\n");
+ err = -ENOMEM;
goto err_out_cache;
}
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 620871efbf0a..4c3ab8377fd3 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -44,6 +44,8 @@ enum {
};
enum {
+ SD_DEF_XFER_BLOCKS = 0xffff,
+ SD_MAX_XFER_BLOCKS = 0xffffffff,
SD_MAX_WS10_BLOCKS = 0xffff,
SD_MAX_WS16_BLOCKS = 0x7fffff,
};
@@ -64,6 +66,7 @@ struct scsi_disk {
struct gendisk *disk;
atomic_t openers;
sector_t capacity; /* size in 512-byte sectors */
+ u32 max_xfer_blocks;
u32 max_ws_blocks;
u32 max_unmap_blocks;
u32 unmap_granularity;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 53268aaba559..01cf88888797 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -7,9 +7,7 @@
* Original driver (sg.c):
* Copyright (C) 1992 Lawrence Foard
* Version 2 and 3 extensions to driver:
- * Copyright (C) 1998 - 2005 Douglas Gilbert
- *
- * Modified 19-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
+ * Copyright (C) 1998 - 2014 Douglas Gilbert
*
* 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
@@ -18,11 +16,11 @@
*
*/
-static int sg_version_num = 30534; /* 2 digits for each component */
-#define SG_VERSION_STR "3.5.34"
+static int sg_version_num = 30536; /* 2 digits for each component */
+#define SG_VERSION_STR "3.5.36"
/*
- * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
+ * D. P. Gilbert (dgilbert@interlog.com), notes:
* - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
* the kernel/module needs to be built with CONFIG_SCSI_LOGGING
* (otherwise the macros compile to empty statements).
@@ -51,6 +49,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/delay.h>
#include <linux/blktrace_api.h>
#include <linux/mutex.h>
+#include <linux/atomic.h>
#include <linux/ratelimit.h>
#include "scsi.h"
@@ -64,7 +63,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
-static char *sg_version_date = "20061027";
+static char *sg_version_date = "20140603";
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
@@ -74,6 +73,12 @@ static void sg_proc_cleanup(void);
#define SG_MAX_DEVS 32768
+/* SG_MAX_CDB_SIZE should be 260 (spc4r37 section 3.1.30) however the type
+ * of sg_io_hdr::cmd_len can only represent 255. All SCSI commands greater
+ * than 16 bytes are "variable length" whose length is a multiple of 4
+ */
+#define SG_MAX_CDB_SIZE 252
+
/*
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
* Then when using 32 bit integers x * m may overflow during the calculation.
@@ -102,18 +107,16 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ;
#define SG_SECTOR_SZ 512
-static int sg_add(struct device *, struct class_interface *);
-static void sg_remove(struct device *, struct class_interface *);
-
-static DEFINE_SPINLOCK(sg_open_exclusive_lock);
+static int sg_add_device(struct device *, struct class_interface *);
+static void sg_remove_device(struct device *, struct class_interface *);
static DEFINE_IDR(sg_index_idr);
static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock
file descriptor list for device */
static struct class_interface sg_interface = {
- .add_dev = sg_add,
- .remove_dev = sg_remove,
+ .add_dev = sg_add_device,
+ .remove_dev = sg_remove_device,
};
typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
@@ -146,8 +149,7 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
} Sg_request;
typedef struct sg_fd { /* holds the state of a file descriptor */
- /* sfd_siblings is protected by sg_index_lock */
- struct list_head sfd_siblings;
+ struct list_head sfd_siblings; /* protected by device's sfd_lock */
struct sg_device *parentdp; /* owning device */
wait_queue_head_t read_wait; /* queue read until command done */
rwlock_t rq_list_lock; /* protect access to list in req_arr */
@@ -161,7 +163,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
char low_dma; /* as in parent but possibly overridden to 1 */
char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
- char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
+ unsigned char next_cmd_len; /* 0: automatic, >0: use on next write() */
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
char mmap_called; /* 0 -> mmap() never called on this fd */
struct kref f_ref;
@@ -170,14 +172,15 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
typedef struct sg_device { /* holds the state of each scsi generic device */
struct scsi_device *device;
- wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */
+ wait_queue_head_t open_wait; /* queue open() when O_EXCL present */
+ struct mutex open_rel_lock; /* held when in open() or release() */
int sg_tablesize; /* adapter's max scatter-gather table size */
u32 index; /* device index number */
- /* sfds is protected by sg_index_lock */
struct list_head sfds;
- volatile char detached; /* 0->attached, 1->detached pending removal */
- /* exclude protected by sg_open_exclusive_lock */
- char exclude; /* opened for exclusive access */
+ rwlock_t sfd_lock; /* protect access to sfd list */
+ atomic_t detaching; /* 0->device usable, 1->device detaching */
+ bool exclude; /* 1->open(O_EXCL) succeeded and is active */
+ int open_cnt; /* count of opens (perhaps < num(sfds) ) */
char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
struct gendisk *disk;
struct cdev * cdev; /* char_dev [sysfs: /sys/cdev/major/sg<n>] */
@@ -197,24 +200,28 @@ static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
unsigned char *cmnd, int timeout, int blocking);
static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
-static void sg_remove_scat(Sg_scatter_hold * schp);
+static void sg_remove_scat(Sg_fd * sfp, Sg_scatter_hold * schp);
static void sg_build_reserve(Sg_fd * sfp, int req_size);
static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
+static Sg_fd *sg_add_sfp(Sg_device * sdp);
static void sg_remove_sfp(struct kref *);
static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
static Sg_request *sg_add_request(Sg_fd * sfp);
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
static int sg_res_in_use(Sg_fd * sfp);
static Sg_device *sg_get_dev(int dev);
-static void sg_put_dev(Sg_device *sdp);
+static void sg_device_destroy(struct kref *kref);
#define SZ_SG_HEADER sizeof(struct sg_header)
#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t)
#define SZ_SG_IOVEC sizeof(sg_iovec_t)
#define SZ_SG_REQ_INFO sizeof(sg_req_info_t)
+#define sg_printk(prefix, sdp, fmt, a...) \
+ sdev_printk(prefix, (sdp)->device, "[%s] " fmt, \
+ (sdp)->disk->disk_name, ##a)
+
static int sg_allow_access(struct file *filp, unsigned char *cmd)
{
struct sg_fd *sfp = filp->private_data;
@@ -225,38 +232,43 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd)
return blk_verify_command(cmd, filp->f_mode & FMODE_WRITE);
}
-static int get_exclude(Sg_device *sdp)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&sg_open_exclusive_lock, flags);
- ret = sdp->exclude;
- spin_unlock_irqrestore(&sg_open_exclusive_lock, flags);
- return ret;
-}
-
-static int set_exclude(Sg_device *sdp, char val)
+static int
+open_wait(Sg_device *sdp, int flags)
{
- unsigned long flags;
-
- spin_lock_irqsave(&sg_open_exclusive_lock, flags);
- sdp->exclude = val;
- spin_unlock_irqrestore(&sg_open_exclusive_lock, flags);
- return val;
-}
+ int retval = 0;
-static int sfds_list_empty(Sg_device *sdp)
-{
- unsigned long flags;
- int ret;
+ if (flags & O_EXCL) {
+ while (sdp->open_cnt > 0) {
+ mutex_unlock(&sdp->open_rel_lock);
+ retval = wait_event_interruptible(sdp->open_wait,
+ (atomic_read(&sdp->detaching) ||
+ !sdp->open_cnt));
+ mutex_lock(&sdp->open_rel_lock);
+
+ if (retval) /* -ERESTARTSYS */
+ return retval;
+ if (atomic_read(&sdp->detaching))
+ return -ENODEV;
+ }
+ } else {
+ while (sdp->exclude) {
+ mutex_unlock(&sdp->open_rel_lock);
+ retval = wait_event_interruptible(sdp->open_wait,
+ (atomic_read(&sdp->detaching) ||
+ !sdp->exclude));
+ mutex_lock(&sdp->open_rel_lock);
+
+ if (retval) /* -ERESTARTSYS */
+ return retval;
+ if (atomic_read(&sdp->detaching))
+ return -ENODEV;
+ }
+ }
- read_lock_irqsave(&sg_index_lock, flags);
- ret = list_empty(&sdp->sfds);
- read_unlock_irqrestore(&sg_index_lock, flags);
- return ret;
+ return retval;
}
+/* Returns 0 on success, else a negated errno value */
static int
sg_open(struct inode *inode, struct file *filp)
{
@@ -265,17 +277,17 @@ sg_open(struct inode *inode, struct file *filp)
struct request_queue *q;
Sg_device *sdp;
Sg_fd *sfp;
- int res;
int retval;
nonseekable_open(inode, filp);
- SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
+ if ((flags & O_EXCL) && (O_RDONLY == (flags & O_ACCMODE)))
+ return -EPERM; /* Can't lock it with read only access */
sdp = sg_get_dev(dev);
- if (IS_ERR(sdp)) {
- retval = PTR_ERR(sdp);
- sdp = NULL;
- goto sg_put;
- }
+ if (IS_ERR(sdp))
+ return PTR_ERR(sdp);
+
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_open: flags=0x%x\n", flags));
/* This driver's module count bumped by fops_get in <linux/fs.h> */
/* Prevent the device driver from vanishing while we sleep */
@@ -287,6 +299,9 @@ sg_open(struct inode *inode, struct file *filp)
if (retval)
goto sdp_put;
+ /* scsi_block_when_processing_errors() may block so bypass
+ * check if O_NONBLOCK. Permits SCSI commands to be issued
+ * during error recovery. Tread carefully. */
if (!((flags & O_NONBLOCK) ||
scsi_block_when_processing_errors(sdp->device))) {
retval = -ENXIO;
@@ -294,65 +309,65 @@ sg_open(struct inode *inode, struct file *filp)
goto error_out;
}
- if (flags & O_EXCL) {
- if (O_RDONLY == (flags & O_ACCMODE)) {
- retval = -EPERM; /* Can't lock it with read only access */
- goto error_out;
- }
- if (!sfds_list_empty(sdp) && (flags & O_NONBLOCK)) {
- retval = -EBUSY;
- goto error_out;
- }
- res = wait_event_interruptible(sdp->o_excl_wait,
- ((!sfds_list_empty(sdp) || get_exclude(sdp)) ? 0 : set_exclude(sdp, 1)));
- if (res) {
- retval = res; /* -ERESTARTSYS because signal hit process */
- goto error_out;
- }
- } else if (get_exclude(sdp)) { /* some other fd has an exclusive lock on dev */
- if (flags & O_NONBLOCK) {
- retval = -EBUSY;
- goto error_out;
- }
- res = wait_event_interruptible(sdp->o_excl_wait, !get_exclude(sdp));
- if (res) {
- retval = res; /* -ERESTARTSYS because signal hit process */
- goto error_out;
+ mutex_lock(&sdp->open_rel_lock);
+ if (flags & O_NONBLOCK) {
+ if (flags & O_EXCL) {
+ if (sdp->open_cnt > 0) {
+ retval = -EBUSY;
+ goto error_mutex_locked;
+ }
+ } else {
+ if (sdp->exclude) {
+ retval = -EBUSY;
+ goto error_mutex_locked;
+ }
}
+ } else {
+ retval = open_wait(sdp, flags);
+ if (retval) /* -ERESTARTSYS or -ENODEV */
+ goto error_mutex_locked;
}
- if (sdp->detached) {
- retval = -ENODEV;
- goto error_out;
- }
- if (sfds_list_empty(sdp)) { /* no existing opens on this device */
+
+ /* N.B. at this point we are holding the open_rel_lock */
+ if (flags & O_EXCL)
+ sdp->exclude = true;
+
+ if (sdp->open_cnt < 1) { /* no existing opens */
sdp->sgdebug = 0;
q = sdp->device->request_queue;
sdp->sg_tablesize = queue_max_segments(q);
}
- if ((sfp = sg_add_sfp(sdp, dev)))
- filp->private_data = sfp;
- else {
- if (flags & O_EXCL) {
- set_exclude(sdp, 0); /* undo if error */
- wake_up_interruptible(&sdp->o_excl_wait);
- }
- retval = -ENOMEM;
- goto error_out;
+ sfp = sg_add_sfp(sdp);
+ if (IS_ERR(sfp)) {
+ retval = PTR_ERR(sfp);
+ goto out_undo;
}
+
+ filp->private_data = sfp;
+ sdp->open_cnt++;
+ mutex_unlock(&sdp->open_rel_lock);
+
retval = 0;
-error_out:
- if (retval) {
- scsi_autopm_put_device(sdp->device);
-sdp_put:
- scsi_device_put(sdp->device);
- }
sg_put:
- if (sdp)
- sg_put_dev(sdp);
+ kref_put(&sdp->d_ref, sg_device_destroy);
return retval;
+
+out_undo:
+ if (flags & O_EXCL) {
+ sdp->exclude = false; /* undo if error */
+ wake_up_interruptible(&sdp->open_wait);
+ }
+error_mutex_locked:
+ mutex_unlock(&sdp->open_rel_lock);
+error_out:
+ scsi_autopm_put_device(sdp->device);
+sdp_put:
+ scsi_device_put(sdp->device);
+ goto sg_put;
}
-/* Following function was formerly called 'sg_close' */
+/* Release resources associated with a successful sg_open()
+ * Returns 0 on success, else a negated errno value */
static int
sg_release(struct inode *inode, struct file *filp)
{
@@ -361,13 +376,22 @@ sg_release(struct inode *inode, struct file *filp)
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name));
-
- set_exclude(sdp, 0);
- wake_up_interruptible(&sdp->o_excl_wait);
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, "sg_release\n"));
+ mutex_lock(&sdp->open_rel_lock);
scsi_autopm_put_device(sdp->device);
kref_put(&sfp->f_ref, sg_remove_sfp);
+ sdp->open_cnt--;
+
+ /* possibly many open()s waiting on exlude clearing, start many;
+ * only open(O_EXCL)s wait on 0==open_cnt so only start one */
+ if (sdp->exclude) {
+ sdp->exclude = false;
+ wake_up_interruptible_all(&sdp->open_wait);
+ } else if (0 == sdp->open_cnt) {
+ wake_up_interruptible(&sdp->open_wait);
+ }
+ mutex_unlock(&sdp->open_rel_lock);
return 0;
}
@@ -384,8 +408,8 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
- sdp->disk->disk_name, (int) count));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_read: count=%d\n", (int) count));
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
@@ -419,7 +443,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
}
srp = sg_get_rq_mark(sfp, req_pack_id);
if (!srp) { /* now wait on packet to arrive */
- if (sdp->detached) {
+ if (atomic_read(&sdp->detaching)) {
retval = -ENODEV;
goto free_old_hdr;
}
@@ -428,9 +452,9 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
goto free_old_hdr;
}
retval = wait_event_interruptible(sfp->read_wait,
- (sdp->detached ||
+ (atomic_read(&sdp->detaching) ||
(srp = sg_get_rq_mark(sfp, req_pack_id))));
- if (sdp->detached) {
+ if (atomic_read(&sdp->detaching)) {
retval = -ENODEV;
goto free_old_hdr;
}
@@ -566,13 +590,13 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
Sg_request *srp;
struct sg_header old_hdr;
sg_io_hdr_t *hp;
- unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_write: %s, count=%d\n",
- sdp->disk->disk_name, (int) count));
- if (sdp->detached)
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_write: count=%d\n", (int) count));
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
if (!((filp->f_flags & O_NONBLOCK) ||
scsi_block_when_processing_errors(sdp->device)))
@@ -592,18 +616,13 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
return -EIO; /* The minimum scsi command length is 6 bytes. */
if (!(srp = sg_add_request(sfp))) {
- SCSI_LOG_TIMEOUT(1, printk("sg_write: queue full\n"));
+ SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sdp,
+ "sg_write: queue full\n"));
return -EDOM;
}
buf += SZ_SG_HEADER;
__get_user(opcode, buf);
if (sfp->next_cmd_len > 0) {
- if (sfp->next_cmd_len > MAX_COMMAND_SIZE) {
- SCSI_LOG_TIMEOUT(1, printk("sg_write: command length too long\n"));
- sfp->next_cmd_len = 0;
- sg_remove_request(sfp, srp);
- return -EIO;
- }
cmd_size = sfp->next_cmd_len;
sfp->next_cmd_len = 0; /* reset so only this write() effected */
} else {
@@ -611,7 +630,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
if ((opcode >= 0xc0) && old_hdr.twelve_byte)
cmd_size = 12;
}
- SCSI_LOG_TIMEOUT(4, printk(
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp,
"sg_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) opcode, cmd_size));
/* Determine buffer size. */
input_size = count - cmd_size;
@@ -675,7 +694,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
int k;
Sg_request *srp;
sg_io_hdr_t *hp;
- unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
int timeout;
unsigned long ul_timeout;
@@ -686,7 +705,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
sfp->cmd_q = 1; /* when sg_io_hdr seen, set command queuing on */
if (!(srp = sg_add_request(sfp))) {
- SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n"));
+ SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_new_write: queue full\n"));
return -EDOM;
}
srp->sg_io_owned = sg_io_owned;
@@ -743,7 +763,7 @@ static int
sg_common_write(Sg_fd * sfp, Sg_request * srp,
unsigned char *cmnd, int timeout, int blocking)
{
- int k, data_dir;
+ int k, data_dir, at_head;
Sg_device *sdp = sfp->parentdp;
sg_io_hdr_t *hp = &srp->header;
@@ -755,16 +775,18 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
hp->host_status = 0;
hp->driver_status = 0;
hp->resid = 0;
- SCSI_LOG_TIMEOUT(4, printk("sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n",
- (int) cmnd[0], (int) hp->cmd_len));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n",
+ (int) cmnd[0], (int) hp->cmd_len));
k = sg_start_req(srp, cmnd);
if (k) {
- SCSI_LOG_TIMEOUT(1, printk("sg_common_write: start_req err=%d\n", k));
+ SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_common_write: start_req err=%d\n", k));
sg_finish_rem_req(srp);
return k; /* probably out of space --> ENOMEM */
}
- if (sdp->detached) {
+ if (atomic_read(&sdp->detaching)) {
if (srp->bio)
blk_end_request_all(srp->rq, -EIO);
sg_finish_rem_req(srp);
@@ -787,11 +809,16 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
break;
}
hp->duration = jiffies_to_msecs(jiffies);
+ if (hp->interface_id != '\0' && /* v3 (or later) interface */
+ (SG_FLAG_Q_AT_TAIL & hp->flags))
+ at_head = 0;
+ else
+ at_head = 1;
srp->rq->timeout = timeout;
kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
- srp->rq, 1, sg_rq_end_io);
+ srp->rq, at_head, sg_rq_end_io);
return 0;
}
@@ -806,6 +833,15 @@ static int srp_done(Sg_fd *sfp, Sg_request *srp)
return ret;
}
+static int max_sectors_bytes(struct request_queue *q)
+{
+ unsigned int max_sectors = queue_max_sectors(q);
+
+ max_sectors = min_t(unsigned int, max_sectors, INT_MAX >> 9);
+
+ return max_sectors << 9;
+}
+
static long
sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
@@ -820,13 +856,13 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: %s, cmd=0x%x\n",
- sdp->disk->disk_name, (int) cmd_in));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_ioctl: cmd=0x%x\n", (int) cmd_in));
read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
switch (cmd_in) {
case SG_IO:
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
if (!scsi_block_when_processing_errors(sdp->device))
return -ENXIO;
@@ -837,8 +873,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
if (result < 0)
return result;
result = wait_event_interruptible(sfp->read_wait,
- (srp_done(sfp, srp) || sdp->detached));
- if (sdp->detached)
+ (srp_done(sfp, srp) || atomic_read(&sdp->detaching)));
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
write_lock_irq(&sfp->rq_list_lock);
if (srp->done) {
@@ -873,11 +909,11 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
sfp->low_dma = 1;
if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
val = (int) sfp->reserve.bufflen;
- sg_remove_scat(&sfp->reserve);
+ sg_remove_scat(sfp, &sfp->reserve);
sg_build_reserve(sfp, val);
}
} else {
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
sfp->low_dma = sdp->device->host->unchecked_isa_dma;
}
@@ -890,7 +926,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
else {
sg_scsi_id_t __user *sg_idp = p;
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
__put_user((int) sdp->device->host->host_no,
&sg_idp->host_no);
@@ -945,17 +981,17 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
if (val < 0)
return -EINVAL;
val = min_t(int, val,
- queue_max_sectors(sdp->device->request_queue) * 512);
+ max_sectors_bytes(sdp->device->request_queue));
if (val != sfp->reserve.bufflen) {
if (sg_res_in_use(sfp) || sfp->mmap_called)
return -EBUSY;
- sg_remove_scat(&sfp->reserve);
+ sg_remove_scat(sfp, &sfp->reserve);
sg_build_reserve(sfp, val);
}
return 0;
case SG_GET_RESERVED_SIZE:
val = min_t(int, sfp->reserve.bufflen,
- queue_max_sectors(sdp->device->request_queue) * 512);
+ max_sectors_bytes(sdp->device->request_queue));
return put_user(val, ip);
case SG_SET_COMMAND_Q:
result = get_user(val, ip);
@@ -1032,11 +1068,11 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
return result;
}
case SG_EMULATED_HOST:
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
return put_user(sdp->device->host->hostt->emulated, ip);
case SG_SCSI_RESET:
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
if (filp->f_flags & O_NONBLOCK) {
if (scsi_host_in_recovery(sdp->device->host))
@@ -1069,7 +1105,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
return (scsi_reset_provider(sdp->device, val) ==
SUCCESS) ? 0 : -EIO;
case SCSI_IOCTL_SEND_COMMAND:
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
if (read_only) {
unsigned char opcode = WRITE_6;
@@ -1091,11 +1127,11 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
case SCSI_IOCTL_GET_BUS_NUMBER:
case SCSI_IOCTL_PROBE_HOST:
case SG_GET_TRANSFORM:
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
return -ENODEV;
return scsi_ioctl(sdp->device, cmd_in, p);
case BLKSECTGET:
- return put_user(queue_max_sectors(sdp->device->request_queue) * 512,
+ return put_user(max_sectors_bytes(sdp->device->request_queue),
ip);
case BLKTRACESETUP:
return blk_trace_setup(sdp->device->request_queue,
@@ -1165,15 +1201,15 @@ sg_poll(struct file *filp, poll_table * wait)
}
read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
- if (sdp->detached)
+ if (atomic_read(&sdp->detaching))
res |= POLLHUP;
else if (!sfp->cmd_q) {
if (0 == count)
res |= POLLOUT | POLLWRNORM;
} else if (count < SG_MAX_QUEUE)
res |= POLLOUT | POLLWRNORM;
- SCSI_LOG_TIMEOUT(3, printk("sg_poll: %s, res=0x%x\n",
- sdp->disk->disk_name, (int) res));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_poll: res=0x%x\n", (int) res));
return res;
}
@@ -1185,8 +1221,8 @@ sg_fasync(int fd, struct file *filp, int mode)
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
- SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n",
- sdp->disk->disk_name, mode));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_fasync: mode=%d\n", mode));
return fasync_helper(fd, filp, mode, &sfp->async_qp);
}
@@ -1205,8 +1241,9 @@ sg_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
offset = vmf->pgoff << PAGE_SHIFT;
if (offset >= rsv_schp->bufflen)
return VM_FAULT_SIGBUS;
- SCSI_LOG_TIMEOUT(3, printk("sg_vma_fault: offset=%lu, scatg=%d\n",
- offset, rsv_schp->k_use_sg));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_vma_fault: offset=%lu, scatg=%d\n",
+ offset, rsv_schp->k_use_sg));
sa = vma->vm_start;
length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
for (k = 0; k < rsv_schp->k_use_sg && sa < vma->vm_end; k++) {
@@ -1241,8 +1278,9 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
return -ENXIO;
req_sz = vma->vm_end - vma->vm_start;
- SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n",
- (void *) vma->vm_start, (int) req_sz));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_mmap starting, vm_start=%p, len=%d\n",
+ (void *) vma->vm_start, (int) req_sz));
if (vma->vm_pgoff)
return -EINVAL; /* want no offset */
rsv_schp = &sfp->reserve;
@@ -1264,7 +1302,8 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-static void sg_rq_end_io_usercontext(struct work_struct *work)
+static void
+sg_rq_end_io_usercontext(struct work_struct *work)
{
struct sg_request *srp = container_of(work, struct sg_request, ew.work);
struct sg_fd *sfp = srp->parentfp;
@@ -1277,7 +1316,8 @@ static void sg_rq_end_io_usercontext(struct work_struct *work)
* This function is a "bottom half" handler that is called by the mid
* level when a command is completed (or has failed).
*/
-static void sg_rq_end_io(struct request *rq, int uptodate)
+static void
+sg_rq_end_io(struct request *rq, int uptodate)
{
struct sg_request *srp = rq->end_io_data;
Sg_device *sdp;
@@ -1295,15 +1335,16 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
return;
sdp = sfp->parentdp;
- if (unlikely(sdp->detached))
- printk(KERN_INFO "sg_rq_end_io: device detached\n");
+ if (unlikely(atomic_read(&sdp->detaching)))
+ pr_info("%s: device detaching\n", __func__);
sense = rq->sense;
result = rq->errors;
resid = rq->resid_len;
- SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
- sdp->disk->disk_name, srp->header.pack_id, result));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sdp,
+ "sg_cmd_done: pack_id=%d, res=0x%x\n",
+ srp->header.pack_id, result));
srp->header.resid = resid;
ms = jiffies_to_msecs(jiffies);
srp->header.duration = (ms > srp->header.duration) ?
@@ -1319,7 +1360,7 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
if ((sdp->sgdebug > 0) &&
((CHECK_CONDITION == srp->header.masked_status) ||
(COMMAND_TERMINATED == srp->header.masked_status)))
- __scsi_print_sense("sg_cmd_done", sense,
+ __scsi_print_sense(__func__, sense,
SCSI_SENSE_BUFFERSIZE);
/* Following if statement is a patch supplied by Eric Youngdale */
@@ -1378,7 +1419,8 @@ static struct class *sg_sysfs_class;
static int sg_sysfs_valid = 0;
-static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
+static Sg_device *
+sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
{
struct request_queue *q = scsidp->request_queue;
Sg_device *sdp;
@@ -1388,7 +1430,8 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL);
if (!sdp) {
- printk(KERN_WARNING "kmalloc Sg_device failure\n");
+ sdev_printk(KERN_WARNING, scsidp, "%s: kmalloc Sg_device "
+ "failure\n", __func__);
return ERR_PTR(-ENOMEM);
}
@@ -1403,20 +1446,25 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
scsidp->type, SG_MAX_DEVS - 1);
error = -ENODEV;
} else {
- printk(KERN_WARNING
- "idr allocation Sg_device failure: %d\n", error);
+ sdev_printk(KERN_WARNING, scsidp, "%s: idr "
+ "allocation Sg_device failure: %d\n",
+ __func__, error);
}
goto out_unlock;
}
k = error;
- SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k));
+ SCSI_LOG_TIMEOUT(3, sdev_printk(KERN_INFO, scsidp,
+ "sg_alloc: dev=%d \n", k));
sprintf(disk->disk_name, "sg%d", k);
disk->first_minor = k;
sdp->disk = disk;
sdp->device = scsidp;
+ mutex_init(&sdp->open_rel_lock);
INIT_LIST_HEAD(&sdp->sfds);
- init_waitqueue_head(&sdp->o_excl_wait);
+ init_waitqueue_head(&sdp->open_wait);
+ atomic_set(&sdp->detaching, 0);
+ rwlock_init(&sdp->sfd_lock);
sdp->sg_tablesize = queue_max_segments(q);
sdp->index = k;
kref_init(&sdp->d_ref);
@@ -1434,7 +1482,7 @@ out_unlock:
}
static int
-sg_add(struct device *cl_dev, struct class_interface *cl_intf)
+sg_add_device(struct device *cl_dev, struct class_interface *cl_intf)
{
struct scsi_device *scsidp = to_scsi_device(cl_dev->parent);
struct gendisk *disk;
@@ -1445,7 +1493,7 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
disk = alloc_disk(1);
if (!disk) {
- printk(KERN_WARNING "alloc_disk failed\n");
+ pr_warn("%s: alloc_disk failed\n", __func__);
return -ENOMEM;
}
disk->major = SCSI_GENERIC_MAJOR;
@@ -1453,7 +1501,7 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
error = -ENOMEM;
cdev = cdev_alloc();
if (!cdev) {
- printk(KERN_WARNING "cdev_alloc failed\n");
+ pr_warn("%s: cdev_alloc failed\n", __func__);
goto out;
}
cdev->owner = THIS_MODULE;
@@ -1461,7 +1509,7 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
sdp = sg_alloc(disk, scsidp);
if (IS_ERR(sdp)) {
- printk(KERN_WARNING "sg_alloc failed\n");
+ pr_warn("%s: sg_alloc failed\n", __func__);
error = PTR_ERR(sdp);
goto out;
}
@@ -1479,22 +1527,20 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
sdp->index),
sdp, "%s", disk->disk_name);
if (IS_ERR(sg_class_member)) {
- printk(KERN_ERR "sg_add: "
- "device_create failed\n");
+ pr_err("%s: device_create failed\n", __func__);
error = PTR_ERR(sg_class_member);
goto cdev_add_err;
}
error = sysfs_create_link(&scsidp->sdev_gendev.kobj,
&sg_class_member->kobj, "generic");
if (error)
- printk(KERN_ERR "sg_add: unable to make symlink "
- "'generic' back to sg%d\n", sdp->index);
+ pr_err("%s: unable to make symlink 'generic' back "
+ "to sg%d\n", __func__, sdp->index);
} else
- printk(KERN_WARNING "sg_add: sg_sys Invalid\n");
+ pr_warn("%s: sg_sys Invalid\n", __func__);
- sdev_printk(KERN_NOTICE, scsidp,
- "Attached scsi generic sg%d type %d\n", sdp->index,
- scsidp->type);
+ sdev_printk(KERN_NOTICE, scsidp, "Attached scsi generic sg%d "
+ "type %d\n", sdp->index, scsidp->type);
dev_set_drvdata(cl_dev, sdp);
@@ -1513,7 +1559,8 @@ out:
return error;
}
-static void sg_device_destroy(struct kref *kref)
+static void
+sg_device_destroy(struct kref *kref)
{
struct sg_device *sdp = container_of(kref, struct sg_device, d_ref);
unsigned long flags;
@@ -1528,40 +1575,45 @@ static void sg_device_destroy(struct kref *kref)
write_unlock_irqrestore(&sg_index_lock, flags);
SCSI_LOG_TIMEOUT(3,
- printk("sg_device_destroy: %s\n",
- sdp->disk->disk_name));
+ sg_printk(KERN_INFO, sdp, "sg_device_destroy\n"));
put_disk(sdp->disk);
kfree(sdp);
}
-static void sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
+static void
+sg_remove_device(struct device *cl_dev, struct class_interface *cl_intf)
{
struct scsi_device *scsidp = to_scsi_device(cl_dev->parent);
Sg_device *sdp = dev_get_drvdata(cl_dev);
unsigned long iflags;
Sg_fd *sfp;
+ int val;
- if (!sdp || sdp->detached)
+ if (!sdp)
return;
+ /* want sdp->detaching non-zero as soon as possible */
+ val = atomic_inc_return(&sdp->detaching);
+ if (val > 1)
+ return; /* only want to do following once per device */
- SCSI_LOG_TIMEOUT(3, printk("sg_remove: %s\n", sdp->disk->disk_name));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "%s\n", __func__));
- /* Need a write lock to set sdp->detached. */
- write_lock_irqsave(&sg_index_lock, iflags);
- sdp->detached = 1;
+ read_lock_irqsave(&sdp->sfd_lock, iflags);
list_for_each_entry(sfp, &sdp->sfds, sfd_siblings) {
- wake_up_interruptible(&sfp->read_wait);
+ wake_up_interruptible_all(&sfp->read_wait);
kill_fasync(&sfp->async_qp, SIGPOLL, POLL_HUP);
}
- write_unlock_irqrestore(&sg_index_lock, iflags);
+ wake_up_interruptible_all(&sdp->open_wait);
+ read_unlock_irqrestore(&sdp->sfd_lock, iflags);
sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic");
device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index));
cdev_del(sdp->cdev);
sdp->cdev = NULL;
- sg_put_dev(sdp);
+ kref_put(&sdp->d_ref, sg_device_destroy);
}
module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
@@ -1631,7 +1683,8 @@ exit_sg(void)
idr_destroy(&sg_index_idr);
}
-static int sg_start_req(Sg_request *srp, unsigned char *cmd)
+static int
+sg_start_req(Sg_request *srp, unsigned char *cmd)
{
int res;
struct request *rq;
@@ -1645,15 +1698,28 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
struct request_queue *q = sfp->parentdp->device->request_queue;
struct rq_map_data *md, map_data;
int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
+ unsigned char *long_cmdp = NULL;
- SCSI_LOG_TIMEOUT(4, printk(KERN_INFO "sg_start_req: dxfer_len=%d\n",
- dxfer_len));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_start_req: dxfer_len=%d\n",
+ dxfer_len));
+
+ if (hp->cmd_len > BLK_MAX_CDB) {
+ long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL);
+ if (!long_cmdp)
+ return -ENOMEM;
+ }
rq = blk_get_request(q, rw, GFP_ATOMIC);
- if (!rq)
+ if (!rq) {
+ kfree(long_cmdp);
return -ENOMEM;
+ }
blk_rq_set_block_pc(rq);
+
+ if (hp->cmd_len > BLK_MAX_CDB)
+ rq->cmd = long_cmdp;
memcpy(rq->cmd, cmd, hp->cmd_len);
rq->cmd_len = hp->cmd_len;
@@ -1726,25 +1792,30 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
return res;
}
-static int sg_finish_rem_req(Sg_request * srp)
+static int
+sg_finish_rem_req(Sg_request *srp)
{
int ret = 0;
Sg_fd *sfp = srp->parentfp;
Sg_scatter_hold *req_schp = &srp->data;
- SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_finish_rem_req: res_used=%d\n",
+ (int) srp->res_used));
if (srp->rq) {
if (srp->bio)
ret = blk_rq_unmap_user(srp->bio);
+ if (srp->rq->cmd != srp->rq->__cmd)
+ kfree(srp->rq->cmd);
blk_put_request(srp->rq);
}
if (srp->res_used)
sg_unlink_reserve(sfp, srp);
else
- sg_remove_scat(req_schp);
+ sg_remove_scat(sfp, req_schp);
sg_remove_request(sfp, srp);
@@ -1778,8 +1849,9 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
++blk_size; /* don't know why */
/* round request up to next highest SG_SECTOR_SZ byte boundary */
blk_size = ALIGN(blk_size, SG_SECTOR_SZ);
- SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
- buff_size, blk_size));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_build_indirect: buff_size=%d, blk_size=%d\n",
+ buff_size, blk_size));
/* N.B. ret_sz carried into this block ... */
mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
@@ -1822,14 +1894,16 @@ retry:
}
}
- SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
- "ret_sz=%d\n", k, num, ret_sz));
+ SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_build_indirect: k=%d, num=%d, ret_sz=%d\n",
+ k, num, ret_sz));
} /* end of for loop */
schp->page_order = order;
schp->k_use_sg = k;
- SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, "
- "rem_sz=%d\n", k, rem_sz));
+ SCSI_LOG_TIMEOUT(5, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_build_indirect: k_use_sg=%d, rem_sz=%d\n",
+ k, rem_sz));
schp->bufflen = blk_size;
if (rem_sz > 0) /* must have failed */
@@ -1846,17 +1920,19 @@ out:
}
static void
-sg_remove_scat(Sg_scatter_hold * schp)
+sg_remove_scat(Sg_fd * sfp, Sg_scatter_hold * schp)
{
- SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
if (schp->pages && schp->sglist_len > 0) {
if (!schp->dio_in_use) {
int k;
for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) {
- SCSI_LOG_TIMEOUT(5, printk(
- "sg_remove_scat: k=%d, pg=0x%p\n",
- k, schp->pages[k]));
+ SCSI_LOG_TIMEOUT(5,
+ sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_remove_scat: k=%d, pg=0x%p\n",
+ k, schp->pages[k]));
__free_pages(schp->pages[k], schp->page_order);
}
@@ -1872,8 +1948,9 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
Sg_scatter_hold *schp = &srp->data;
int k, num;
- SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
- num_read_xfer));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp,
+ "sg_read_oxfer: num_read_xfer=%d\n",
+ num_read_xfer));
if ((!outp) || (num_read_xfer <= 0))
return 0;
@@ -1903,14 +1980,15 @@ sg_build_reserve(Sg_fd * sfp, int req_size)
{
Sg_scatter_hold *schp = &sfp->reserve;
- SCSI_LOG_TIMEOUT(4, printk("sg_build_reserve: req_size=%d\n", req_size));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_build_reserve: req_size=%d\n", req_size));
do {
if (req_size < PAGE_SIZE)
req_size = PAGE_SIZE;
if (0 == sg_build_indirect(schp, sfp, req_size))
return;
else
- sg_remove_scat(schp);
+ sg_remove_scat(sfp, schp);
req_size >>= 1; /* divide by 2 */
} while (req_size > (PAGE_SIZE / 2));
}
@@ -1923,7 +2001,8 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
int k, num, rem;
srp->res_used = 1;
- SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_link_reserve: size=%d\n", size));
rem = size;
num = 1 << (PAGE_SHIFT + rsv_schp->page_order);
@@ -1941,7 +2020,8 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
}
if (k >= rsv_schp->k_use_sg)
- SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
+ SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sfp->parentdp,
+ "sg_link_reserve: BAD size\n"));
}
static void
@@ -1949,8 +2029,9 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
{
Sg_scatter_hold *req_schp = &srp->data;
- SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
- (int) req_schp->k_use_sg));
+ SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, srp->parentfp->parentdp,
+ "sg_unlink_reserve: req->k_use_sg=%d\n",
+ (int) req_schp->k_use_sg));
req_schp->k_use_sg = 0;
req_schp->bufflen = 0;
req_schp->pages = NULL;
@@ -2055,7 +2136,7 @@ sg_remove_request(Sg_fd * sfp, Sg_request * srp)
}
static Sg_fd *
-sg_add_sfp(Sg_device * sdp, int dev)
+sg_add_sfp(Sg_device * sdp)
{
Sg_fd *sfp;
unsigned long iflags;
@@ -2063,7 +2144,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN);
if (!sfp)
- return NULL;
+ return ERR_PTR(-ENOMEM);
init_waitqueue_head(&sfp->read_wait);
rwlock_init(&sfp->rq_list_lock);
@@ -2077,25 +2158,33 @@ sg_add_sfp(Sg_device * sdp, int dev)
sfp->cmd_q = SG_DEF_COMMAND_Q;
sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
sfp->parentdp = sdp;
- write_lock_irqsave(&sg_index_lock, iflags);
+ write_lock_irqsave(&sdp->sfd_lock, iflags);
+ if (atomic_read(&sdp->detaching)) {
+ write_unlock_irqrestore(&sdp->sfd_lock, iflags);
+ return ERR_PTR(-ENODEV);
+ }
list_add_tail(&sfp->sfd_siblings, &sdp->sfds);
- write_unlock_irqrestore(&sg_index_lock, iflags);
- SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
+ write_unlock_irqrestore(&sdp->sfd_lock, iflags);
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_add_sfp: sfp=0x%p\n", sfp));
if (unlikely(sg_big_buff != def_reserved_size))
sg_big_buff = def_reserved_size;
bufflen = min_t(int, sg_big_buff,
- queue_max_sectors(sdp->device->request_queue) * 512);
+ max_sectors_bytes(sdp->device->request_queue));
sg_build_reserve(sfp, bufflen);
- SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n",
- sfp->reserve.bufflen, sfp->reserve.k_use_sg));
+ SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+ "sg_add_sfp: bufflen=%d, k_use_sg=%d\n",
+ sfp->reserve.bufflen,
+ sfp->reserve.k_use_sg));
kref_get(&sdp->d_ref);
__module_get(THIS_MODULE);
return sfp;
}
-static void sg_remove_sfp_usercontext(struct work_struct *work)
+static void
+sg_remove_sfp_usercontext(struct work_struct *work)
{
struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
struct sg_device *sdp = sfp->parentdp;
@@ -2105,34 +2194,32 @@ static void sg_remove_sfp_usercontext(struct work_struct *work)
sg_finish_rem_req(sfp->headrp);
if (sfp->reserve.bufflen > 0) {
- SCSI_LOG_TIMEOUT(6,
- printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
+ SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
+ "sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
(int) sfp->reserve.bufflen,
(int) sfp->reserve.k_use_sg));
- sg_remove_scat(&sfp->reserve);
+ sg_remove_scat(sfp, &sfp->reserve);
}
- SCSI_LOG_TIMEOUT(6,
- printk("sg_remove_sfp: %s, sfp=0x%p\n",
- sdp->disk->disk_name,
- sfp));
+ SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
+ "sg_remove_sfp: sfp=0x%p\n", sfp));
kfree(sfp);
scsi_device_put(sdp->device);
- sg_put_dev(sdp);
+ kref_put(&sdp->d_ref, sg_device_destroy);
module_put(THIS_MODULE);
}
-static void sg_remove_sfp(struct kref *kref)
+static void
+sg_remove_sfp(struct kref *kref)
{
struct sg_fd *sfp = container_of(kref, struct sg_fd, f_ref);
struct sg_device *sdp = sfp->parentdp;
unsigned long iflags;
- write_lock_irqsave(&sg_index_lock, iflags);
+ write_lock_irqsave(&sdp->sfd_lock, iflags);
list_del(&sfp->sfd_siblings);
- write_unlock_irqrestore(&sg_index_lock, iflags);
- wake_up_interruptible(&sdp->o_excl_wait);
+ write_unlock_irqrestore(&sdp->sfd_lock, iflags);
INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext);
schedule_work(&sfp->ew.work);
@@ -2183,7 +2270,8 @@ static Sg_device *sg_lookup_dev(int dev)
return idr_find(&sg_index_idr, dev);
}
-static Sg_device *sg_get_dev(int dev)
+static Sg_device *
+sg_get_dev(int dev)
{
struct sg_device *sdp;
unsigned long flags;
@@ -2192,8 +2280,8 @@ static Sg_device *sg_get_dev(int dev)
sdp = sg_lookup_dev(dev);
if (!sdp)
sdp = ERR_PTR(-ENXIO);
- else if (sdp->detached) {
- /* If sdp->detached, then the refcount may already be 0, in
+ else if (atomic_read(&sdp->detaching)) {
+ /* If sdp->detaching, then the refcount may already be 0, in
* which case it would be a bug to do kref_get().
*/
sdp = ERR_PTR(-ENODEV);
@@ -2204,11 +2292,6 @@ static Sg_device *sg_get_dev(int dev)
return sdp;
}
-static void sg_put_dev(struct sg_device *sdp)
-{
- kref_put(&sdp->d_ref, sg_device_destroy);
-}
-
#ifdef CONFIG_SCSI_PROC_FS
static struct proc_dir_entry *sg_proc_sgp = NULL;
@@ -2425,8 +2508,7 @@ static int sg_proc_single_open_version(struct inode *inode, struct file *file)
static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v)
{
- seq_printf(s, "host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\t"
- "online\n");
+ seq_puts(s, "host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n");
return 0;
}
@@ -2482,16 +2564,19 @@ static int sg_proc_seq_show_dev(struct seq_file *s, void *v)
read_lock_irqsave(&sg_index_lock, iflags);
sdp = it ? sg_lookup_dev(it->index) : NULL;
- if (sdp && (scsidp = sdp->device) && (!sdp->detached))
- seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
+ if ((NULL == sdp) || (NULL == sdp->device) ||
+ (atomic_read(&sdp->detaching)))
+ seq_puts(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
+ else {
+ scsidp = sdp->device;
+ seq_printf(s, "%d\t%d\t%d\t%llu\t%d\t%d\t%d\t%d\t%d\n",
scsidp->host->host_no, scsidp->channel,
scsidp->id, scsidp->lun, (int) scsidp->type,
1,
(int) scsidp->queue_depth,
- (int) scsidp->device_busy,
+ (int) atomic_read(&scsidp->device_busy),
(int) scsi_device_online(scsidp));
- else
- seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
+ }
read_unlock_irqrestore(&sg_index_lock, iflags);
return 0;
}
@@ -2510,11 +2595,12 @@ static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v)
read_lock_irqsave(&sg_index_lock, iflags);
sdp = it ? sg_lookup_dev(it->index) : NULL;
- if (sdp && (scsidp = sdp->device) && (!sdp->detached))
+ scsidp = sdp ? sdp->device : NULL;
+ if (sdp && scsidp && (!atomic_read(&sdp->detaching)))
seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n",
scsidp->vendor, scsidp->model, scsidp->rev);
else
- seq_printf(s, "<no active device>\n");
+ seq_puts(s, "<no active device>\n");
read_unlock_irqrestore(&sg_index_lock, iflags);
return 0;
}
@@ -2559,12 +2645,12 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
else
cp = " ";
}
- seq_printf(s, cp);
+ seq_puts(s, cp);
blen = srp->data.bufflen;
usg = srp->data.k_use_sg;
- seq_printf(s, srp->done ?
- ((1 == srp->done) ? "rcv:" : "fin:")
- : "act:");
+ seq_puts(s, srp->done ?
+ ((1 == srp->done) ? "rcv:" : "fin:")
+ : "act:");
seq_printf(s, " id=%d blen=%d",
srp->header.pack_id, blen);
if (srp->done)
@@ -2580,7 +2666,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
(int) srp->data.cmd_opcode);
}
if (0 == m)
- seq_printf(s, " No requests active\n");
+ seq_puts(s, " No requests active\n");
read_unlock(&fp->rq_list_lock);
}
}
@@ -2596,31 +2682,34 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v)
Sg_device *sdp;
unsigned long iflags;
- if (it && (0 == it->index)) {
- seq_printf(s, "max_active_device=%d(origin 1)\n",
- (int)it->max);
- seq_printf(s, " def_reserved_size=%d\n", sg_big_buff);
- }
+ if (it && (0 == it->index))
+ seq_printf(s, "max_active_device=%d def_reserved_size=%d\n",
+ (int)it->max, sg_big_buff);
read_lock_irqsave(&sg_index_lock, iflags);
sdp = it ? sg_lookup_dev(it->index) : NULL;
- if (sdp && !list_empty(&sdp->sfds)) {
- struct scsi_device *scsidp = sdp->device;
-
+ if (NULL == sdp)
+ goto skip;
+ read_lock(&sdp->sfd_lock);
+ if (!list_empty(&sdp->sfds)) {
seq_printf(s, " >>> device=%s ", sdp->disk->disk_name);
- if (sdp->detached)
- seq_printf(s, "detached pending close ");
- else
- seq_printf
- (s, "scsi%d chan=%d id=%d lun=%d em=%d",
- scsidp->host->host_no,
- scsidp->channel, scsidp->id,
- scsidp->lun,
- scsidp->host->hostt->emulated);
- seq_printf(s, " sg_tablesize=%d excl=%d\n",
- sdp->sg_tablesize, get_exclude(sdp));
+ if (atomic_read(&sdp->detaching))
+ seq_puts(s, "detaching pending close ");
+ else if (sdp->device) {
+ struct scsi_device *scsidp = sdp->device;
+
+ seq_printf(s, "%d:%d:%d:%llu em=%d",
+ scsidp->host->host_no,
+ scsidp->channel, scsidp->id,
+ scsidp->lun,
+ scsidp->host->hostt->emulated);
+ }
+ seq_printf(s, " sg_tablesize=%d excl=%d open_cnt=%d\n",
+ sdp->sg_tablesize, sdp->exclude, sdp->open_cnt);
sg_proc_debug_helper(s, sdp);
}
+ read_unlock(&sdp->sfd_lock);
+skip:
read_unlock_irqrestore(&sg_index_lock, iflags);
return 0;
}
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 93cbd36c990b..7eeb93627beb 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -292,8 +292,8 @@ do_tur:
if (!cd->tur_changed) {
if (cd->get_event_changed) {
if (cd->tur_mismatch++ > 8) {
- sdev_printk(KERN_WARNING, cd->device,
- "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n");
+ sr_printk(KERN_WARNING, cd,
+ "GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n");
cd->ignore_get_event = true;
}
} else {
@@ -322,7 +322,7 @@ static int sr_done(struct scsi_cmnd *SCpnt)
struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
#ifdef DEBUG
- printk("sr.c done: %x\n", result);
+ scmd_printk(KERN_INFO, SCpnt, "done: %x\n", result);
#endif
/*
@@ -385,10 +385,9 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
int block = 0, this_count, s_size;
struct scsi_cd *cd;
struct request *rq = SCpnt->request;
- struct scsi_device *sdp = SCpnt->device;
int ret;
- ret = scsi_setup_fs_cmnd(sdp, rq);
+ ret = scsi_init_io(SCpnt, GFP_ATOMIC);
if (ret != BLKPREP_OK)
goto out;
SCpnt = rq->special;
@@ -398,13 +397,14 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
* is used for a killable error condition */
ret = BLKPREP_KILL;
- SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
- cd->disk->disk_name, block));
+ SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
+ "Doing sr request, block = %d\n", block));
if (!cd->device || !scsi_device_online(cd->device)) {
- SCSI_LOG_HLQUEUE(2, printk("Finishing %u sectors\n",
- blk_rq_sectors(rq)));
- SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
+ SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
+ "Finishing %u sectors\n", blk_rq_sectors(rq)));
+ SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
+ "Retry with 0x%p\n", SCpnt));
goto out;
}
@@ -425,7 +425,8 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
if (!in_interrupt())
sr_set_blocklength(cd, 2048);
else
- printk("sr: can't switch blocksize: in interrupt\n");
+ scmd_printk(KERN_INFO, SCpnt,
+ "can't switch blocksize: in interrupt\n");
}
if (s_size != 512 && s_size != 1024 && s_size != 2048) {
@@ -434,14 +435,12 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
}
if (rq_data_dir(rq) == WRITE) {
- if (!cd->device->writeable)
+ if (!cd->writeable)
goto out;
SCpnt->cmnd[0] = WRITE_10;
- SCpnt->sc_data_direction = DMA_TO_DEVICE;
- cd->cdi.media_written = 1;
+ cd->cdi.media_written = 1;
} else if (rq_data_dir(rq) == READ) {
SCpnt->cmnd[0] = READ_10;
- SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
blk_dump_rq_flags(rq, "Unknown sr command");
goto out;
@@ -475,11 +474,11 @@ static int sr_init_command(struct scsi_cmnd *SCpnt)
this_count = (scsi_bufflen(SCpnt) >> 9) / (s_size >> 9);
- SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%u 512 byte blocks.\n",
- cd->cdi.name,
- (rq_data_dir(rq) == WRITE) ?
+ SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
+ "%s %d/%u 512 byte blocks.\n",
+ (rq_data_dir(rq) == WRITE) ?
"writing" : "reading",
- this_count, blk_rq_sectors(rq)));
+ this_count, blk_rq_sectors(rq)));
SCpnt->cmnd[1] = 0;
block = (unsigned int)blk_rq_pos(rq) / (s_size >> 9);
@@ -810,8 +809,8 @@ static void get_sectorsize(struct scsi_cd *cd)
case 512:
break;
default:
- printk("%s: unsupported sector size %d.\n",
- cd->cdi.name, sector_size);
+ sr_printk(KERN_INFO, cd,
+ "unsupported sector size %d.", sector_size);
cd->capacity = 0;
}
@@ -853,7 +852,7 @@ static void get_capabilities(struct scsi_cd *cd)
/* allocate transfer buffer */
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
if (!buffer) {
- printk(KERN_ERR "sr: out of memory.\n");
+ sr_printk(KERN_ERR, cd, "out of memory.\n");
return;
}
@@ -872,7 +871,7 @@ static void get_capabilities(struct scsi_cd *cd)
CDC_SELECT_DISC | CDC_SELECT_SPEED |
CDC_MRW | CDC_MRW_W | CDC_RAM);
kfree(buffer);
- printk("%s: scsi-1 drive\n", cd->cdi.name);
+ sr_printk(KERN_INFO, cd, "scsi-1 drive");
return;
}
@@ -881,22 +880,23 @@ static void get_capabilities(struct scsi_cd *cd)
cd->readcd_known = 1;
cd->readcd_cdda = buffer[n + 5] & 0x01;
/* print some capability bits */
- printk("%s: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", cd->cdi.name,
- ((buffer[n + 14] << 8) + buffer[n + 15]) / 176,
- cd->cdi.speed,
- buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */
- buffer[n + 3] & 0x20 ? "dvd-ram " : "",
- buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */
- buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */
- buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */
- loadmech[buffer[n + 6] >> 5]);
+ sr_printk(KERN_INFO, cd,
+ "scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n",
+ ((buffer[n + 14] << 8) + buffer[n + 15]) / 176,
+ cd->cdi.speed,
+ buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */
+ buffer[n + 3] & 0x20 ? "dvd-ram " : "",
+ buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */
+ buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */
+ buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */
+ loadmech[buffer[n + 6] >> 5]);
if ((buffer[n + 6] >> 5) == 0)
/* caddy drives can't close tray... */
cd->cdi.mask |= CDC_CLOSE_TRAY;
if ((buffer[n + 2] & 0x8) == 0)
/* not a DVD drive */
cd->cdi.mask |= CDC_DVD;
- if ((buffer[n + 3] & 0x20) == 0)
+ if ((buffer[n + 3] & 0x20) == 0)
/* can't write DVD-RAM media */
cd->cdi.mask |= CDC_DVD_RAM;
if ((buffer[n + 3] & 0x10) == 0)
@@ -927,7 +927,7 @@ static void get_capabilities(struct scsi_cd *cd)
*/
if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) !=
(CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) {
- cd->device->writeable = 1;
+ cd->writeable = 1;
}
kfree(buffer);
@@ -935,7 +935,7 @@ static void get_capabilities(struct scsi_cd *cd)
/*
* sr_packet() is the entry point for the generic commands generated
- * by the Uniform CD-ROM layer.
+ * by the Uniform CD-ROM layer.
*/
static int sr_packet(struct cdrom_device_info *cdi,
struct packet_command *cgc)
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index 37c8f6b17510..1d1f6f416c59 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -36,6 +36,7 @@ typedef struct scsi_cd {
struct scsi_device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
unsigned long ms_offset; /* for reading multisession-CD's */
+ unsigned writeable : 1;
unsigned use:1; /* is this device still supportable */
unsigned xa_flag:1; /* CD has XA sectors ? */
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
@@ -55,6 +56,10 @@ typedef struct scsi_cd {
struct gendisk *disk;
} Scsi_CD;
+#define sr_printk(prefix, cd, fmt, a...) \
+ sdev_printk(prefix, (cd)->device, "[%s] " fmt, \
+ (cd)->cdi.name, ##a)
+
int sr_do_ioctl(Scsi_CD *, struct packet_command *);
int sr_lock_door(struct cdrom_device_info *, int);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index a3911c39ea50..6389fcff12ec 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -36,7 +36,6 @@ module_param(xa_test, int, S_IRUGO | S_IWUSR);
* the status of the unchecked_isa_dma flag in the host structure */
#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)
-
static int sr_read_tochdr(struct cdrom_device_info *cdi,
struct cdrom_tochdr *tochdr)
{
@@ -219,7 +218,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
case UNIT_ATTENTION:
SDev->changed = 1;
if (!cgc->quiet)
- printk(KERN_INFO "%s: disc change detected.\n", cd->cdi.name);
+ sr_printk(KERN_INFO, cd,
+ "disc change detected.\n");
if (retries++ < 10)
goto retry;
err = -ENOMEDIUM;
@@ -229,7 +229,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
sshdr.ascq == 0x01) {
/* sense: Logical unit is in process of becoming ready */
if (!cgc->quiet)
- printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
+ sr_printk(KERN_INFO, cd,
+ "CDROM not ready yet.\n");
if (retries++ < 10) {
/* sleep 2 sec and try again */
ssleep(2);
@@ -241,7 +242,9 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
}
}
if (!cgc->quiet)
- printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name);
+ sr_printk(KERN_INFO, cd,
+ "CDROM not ready. Make sure there "
+ "is a disc in the drive.\n");
#ifdef DEBUG
scsi_print_sense_hdr("sr", &sshdr);
#endif
@@ -259,7 +262,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
#endif
break;
default:
- printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
+ sr_printk(KERN_ERR, cd,
+ "CDROM (ioctl) error, command: ");
__scsi_print_command(cgc->cmd);
scsi_print_sense_hdr("sr", &sshdr);
err = -EIO;
@@ -491,8 +495,8 @@ static int sr_read_cd(Scsi_CD *cd, unsigned char *dest, int lba, int format, int
struct packet_command cgc;
#ifdef DEBUG
- printk("%s: sr_read_cd lba=%d format=%d blksize=%d\n",
- cd->cdi.name, lba, format, blksize);
+ sr_printk(KERN_INFO, cd, "sr_read_cd lba=%d format=%d blksize=%d\n",
+ lba, format, blksize);
#endif
memset(&cgc, 0, sizeof(struct packet_command));
@@ -539,7 +543,8 @@ static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest
if (-EDRIVE_CANT_DO_THIS != rc)
return rc;
cd->readcd_known = 0;
- printk("CDROM does'nt support READ CD (0xbe) command\n");
+ sr_printk(KERN_INFO, cd,
+ "CDROM does'nt support READ CD (0xbe) command\n");
/* fall & retry the other way */
}
/* ... if this fails, we switch the blocksize using MODE SELECT */
@@ -548,7 +553,8 @@ static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest
return rc;
}
#ifdef DEBUG
- printk("%s: sr_read_sector lba=%d blksize=%d\n", cd->cdi.name, lba, blksize);
+ sr_printk(KERN_INFO, cd, "sr_read_sector lba=%d blksize=%d\n",
+ lba, blksize);
#endif
memset(&cgc, 0, sizeof(struct packet_command));
@@ -592,7 +598,7 @@ int sr_is_xa(Scsi_CD *cd)
}
kfree(raw_sector);
#ifdef DEBUG
- printk("%s: sr_is_xa: %d\n", cd->cdi.name, is_xa);
+ sr_printk(KERN_INFO, cd, "sr_is_xa: %d\n", is_xa);
#endif
return is_xa;
}
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 92cc2efb25d7..11a238cb2222 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -123,7 +123,7 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength)
return -ENOMEM;
#ifdef DEBUG
- printk("%s: MODE SELECT 0x%x/%d\n", cd->cdi.name, density, blocklength);
+ sr_printk(KERN_INFO, cd, "MODE SELECT 0x%x/%d\n", density, blocklength);
#endif
memset(&cgc, 0, sizeof(struct packet_command));
cgc.cmd[0] = MODE_SELECT;
@@ -144,8 +144,9 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength)
}
#ifdef DEBUG
else
- printk("%s: switching blocklength to %d bytes failed\n",
- cd->cdi.name, blocklength);
+ sr_printk(KERN_INFO, cd,
+ "switching blocklength to %d bytes failed\n",
+ blocklength);
#endif
kfree(buffer);
return rc;
@@ -190,8 +191,8 @@ int sr_cd_check(struct cdrom_device_info *cdi)
if (rc != 0)
break;
if ((buffer[0] << 8) + buffer[1] < 0x0a) {
- printk(KERN_INFO "%s: Hmm, seems the drive "
- "doesn't support multisession CD's\n", cd->cdi.name);
+ sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
+ "doesn't support multisession CD's\n");
no_multi = 1;
break;
}
@@ -218,9 +219,9 @@ int sr_cd_check(struct cdrom_device_info *cdi)
if (rc != 0)
break;
if (buffer[14] != 0 && buffer[14] != 0xb0) {
- printk(KERN_INFO "%s: Hmm, seems the cdrom "
- "doesn't support multisession CD's\n",
- cd->cdi.name);
+ sr_printk(KERN_INFO, cd, "Hmm, seems the cdrom "
+ "doesn't support multisession CD's\n");
+
no_multi = 1;
break;
}
@@ -245,9 +246,8 @@ int sr_cd_check(struct cdrom_device_info *cdi)
cgc.timeout = VENDOR_TIMEOUT;
rc = sr_do_ioctl(cd, &cgc);
if (rc == -EINVAL) {
- printk(KERN_INFO "%s: Hmm, seems the drive "
- "doesn't support multisession CD's\n",
- cd->cdi.name);
+ sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
+ "doesn't support multisession CD's\n");
no_multi = 1;
break;
}
@@ -277,8 +277,8 @@ int sr_cd_check(struct cdrom_device_info *cdi)
break;
}
if ((rc = buffer[2]) == 0) {
- printk(KERN_WARNING
- "%s: No finished session\n", cd->cdi.name);
+ sr_printk(KERN_WARNING, cd,
+ "No finished session\n");
break;
}
cgc.cmd[0] = READ_TOC; /* Read TOC */
@@ -301,9 +301,9 @@ int sr_cd_check(struct cdrom_device_info *cdi)
default:
/* should not happen */
- printk(KERN_WARNING
- "%s: unknown vendor code (%i), not initialized ?\n",
- cd->cdi.name, cd->vendor);
+ sr_printk(KERN_WARNING, cd,
+ "unknown vendor code (%i), not initialized ?\n",
+ cd->vendor);
sector = 0;
no_multi = 1;
break;
@@ -321,8 +321,8 @@ int sr_cd_check(struct cdrom_device_info *cdi)
#ifdef DEBUG
if (sector)
- printk(KERN_DEBUG "%s: multisession offset=%lu\n",
- cd->cdi.name, sector);
+ sr_printk(KERN_DEBUG, cd, "multisession offset=%lu\n",
+ sector);
#endif
kfree(buffer);
return rc;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 14eb4b256a03..aff9689de0f7 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -58,11 +58,11 @@ static const char *verstr = "20101219";
is defined and non-zero. */
#define DEBUG 0
+#define ST_DEB_MSG KERN_NOTICE
#if DEBUG
/* The message level for the debug messages is currently set to KERN_NOTICE
so that people can easily see the messages. Later when the debugging messages
in the drivers are more widely classified, this may be changed to KERN_DEBUG. */
-#define ST_DEB_MSG KERN_NOTICE
#define DEB(a) a
#define DEBC(a) if (debugging) { a ; }
#else
@@ -305,6 +305,15 @@ static inline char *tape_name(struct scsi_tape *tape)
return tape->disk->disk_name;
}
+#define st_printk(prefix, t, fmt, a...) \
+ sdev_printk(prefix, (t)->device, "%s: " fmt, \
+ tape_name(t), ##a)
+#ifdef DEBUG
+#define DEBC_printk(t, fmt, a...) \
+ if (debugging) { st_printk(ST_DEB_MSG, t, fmt, ##a ); }
+#else
+#define DEBC_printk(t, fmt, a...)
+#endif
static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
{
@@ -358,21 +367,20 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
else
scode = 0;
- DEB(
- if (debugging) {
- printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
- name, result,
- SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
- SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
+ DEB(
+ if (debugging) {
+ st_printk(ST_DEB_MSG, STp,
+ "Error: %x, cmd: %x %x %x %x %x %x\n", result,
+ SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
+ SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
if (cmdstatp->have_sense)
__scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
} ) /* end DEB */
if (!debugging) { /* Abnormal conditions for tape */
if (!cmdstatp->have_sense)
- printk(KERN_WARNING
- "%s: Error %x (driver bt 0x%x, host bt 0x%x).\n",
- name, result, driver_byte(result),
- host_byte(result));
+ st_printk(KERN_WARNING, STp,
+ "Error %x (driver bt 0x%x, host bt 0x%x).\n",
+ result, driver_byte(result), host_byte(result));
else if (cmdstatp->have_sense &&
scode != NO_SENSE &&
scode != RECOVERED_ERROR &&
@@ -411,7 +419,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
STp->recover_count++;
STp->recover_reg++;
- DEB(
+ DEB(
if (debugging) {
if (SRpnt->cmd[0] == READ_6)
stp = "read";
@@ -419,8 +427,9 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
stp = "write";
else
stp = "ioctl";
- printk(ST_DEB_MSG "%s: Recovered %s error (%d).\n", name, stp,
- STp->recover_count);
+ st_printk(ST_DEB_MSG, STp,
+ "Recovered %s error (%d).\n",
+ stp, STp->recover_count);
} ) /* end DEB */
if (cmdstatp->flags == 0)
@@ -437,8 +446,8 @@ static struct st_request *st_allocate_request(struct scsi_tape *stp)
if (streq)
streq->stp = stp;
else {
- DEBC(printk(KERN_ERR "%s: Can't get SCSI request.\n",
- tape_name(stp)););
+ st_printk(KERN_ERR, stp,
+ "Can't get SCSI request.\n");
if (signal_pending(current))
stp->buffer->syscall_result = -EINTR;
else
@@ -525,8 +534,8 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd
/* if async, make sure there's no command outstanding */
if (!do_wait && ((STp->buffer)->last_SRpnt)) {
- printk(KERN_ERR "%s: Async command already active.\n",
- tape_name(STp));
+ st_printk(KERN_ERR, STp,
+ "Async command already active.\n");
if (signal_pending(current))
(STp->buffer)->syscall_result = (-EINTR);
else
@@ -597,12 +606,12 @@ static int write_behind_check(struct scsi_tape * STp)
if (!STbuffer->writing)
return 0;
- DEB(
+ DEB(
if (STp->write_pending)
STp->nbr_waits++;
else
STp->nbr_finished++;
- ) /* end DEB */
+ ) /* end DEB */
wait_for_completion(&(STp->wait));
SRpnt = STbuffer->last_SRpnt;
@@ -639,8 +648,9 @@ static int write_behind_check(struct scsi_tape * STp)
STbuffer->writing = 0;
DEB(if (debugging && retval)
- printk(ST_DEB_MSG "%s: Async write error %x, return value %d.\n",
- tape_name(STp), STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
+ st_printk(ST_DEB_MSG, STp,
+ "Async write error %x, return value %d.\n",
+ STbuffer->cmdstat.midlevel_result, retval);) /* end DEB */
return retval;
}
@@ -662,8 +672,8 @@ static int cross_eof(struct scsi_tape * STp, int forward)
cmd[2] = cmd[3] = cmd[4] = 0xff; /* -1 filemarks */
cmd[5] = 0;
- DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n",
- tape_name(STp), forward ? "forward" : "backward"));
+ DEBC_printk(STp, "Stepping over filemark %s.\n",
+ forward ? "forward" : "backward");
SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
STp->device->request_queue->rq_timeout,
@@ -675,8 +685,9 @@ static int cross_eof(struct scsi_tape * STp, int forward)
SRpnt = NULL;
if ((STp->buffer)->cmdstat.midlevel_result != 0)
- printk(KERN_ERR "%s: Stepping over filemark %s failed.\n",
- tape_name(STp), forward ? "forward" : "backward");
+ st_printk(KERN_ERR, STp,
+ "Stepping over filemark %s failed.\n",
+ forward ? "forward" : "backward");
return (STp->buffer)->syscall_result;
}
@@ -699,8 +710,7 @@ static int st_flush_write_buffer(struct scsi_tape * STp)
if (STp->dirty == 1) {
transfer = STp->buffer->buffer_bytes;
- DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
- tape_name(STp), transfer));
+ DEBC_printk(STp, "Flushing %d bytes.\n", transfer);
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = WRITE_6;
@@ -732,8 +742,7 @@ static int st_flush_write_buffer(struct scsi_tape * STp)
STps->drv_block += blks;
result = (-ENOSPC);
} else {
- printk(KERN_ERR "%s: Error on flush.\n",
- tape_name(STp));
+ st_printk(KERN_ERR, STp, "Error on flush.\n");
STps->drv_block = (-1);
result = (-EIO);
}
@@ -811,7 +820,6 @@ static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
{
int set_it = 0;
unsigned long arg;
- char *name = tape_name(STp);
if (!STp->density_changed &&
STm->default_density >= 0 &&
@@ -830,9 +838,10 @@ static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
arg |= STp->block_size;
if (set_it &&
st_int_ioctl(STp, SET_DENS_AND_BLK, arg)) {
- printk(KERN_WARNING
- "%s: Can't set default block size to %d bytes and density %x.\n",
- name, STm->default_blksize, STm->default_density);
+ st_printk(KERN_WARNING, STp,
+ "Can't set default block size to %d bytes "
+ "and density %x.\n",
+ STm->default_blksize, STm->default_density);
if (modes_defined)
return (-EINVAL);
}
@@ -844,12 +853,9 @@ static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm)
static int do_door_lock(struct scsi_tape * STp, int do_lock)
{
int retval, cmd;
- DEB(char *name = tape_name(STp);)
-
cmd = do_lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK;
- DEBC(printk(ST_DEB_MSG "%s: %socking drive door.\n", name,
- do_lock ? "L" : "Unl"));
+ DEBC_printk(STp, "%socking drive door.\n", do_lock ? "L" : "Unl");
retval = scsi_ioctl(STp->device, cmd, NULL);
if (!retval) {
STp->door_locked = do_lock ? ST_LOCKED_EXPLICIT : ST_UNLOCKED;
@@ -976,15 +982,14 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
struct st_request *SRpnt = NULL;
struct st_modedef *STm;
struct st_partstat *STps;
- char *name = tape_name(STp);
struct inode *inode = file_inode(filp);
int mode = TAPE_MODE(inode);
STp->ready = ST_READY;
if (mode != STp->current_mode) {
- DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n",
- name, STp->current_mode, mode));
+ DEBC_printk(STp, "Mode change from %d to %d.\n",
+ STp->current_mode, mode);
new_session = 1;
STp->current_mode = mode;
}
@@ -1055,13 +1060,12 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
STp->min_block = ((STp->buffer)->b_data[4] << 8) |
(STp->buffer)->b_data[5];
if ( DEB( debugging || ) !STp->inited)
- printk(KERN_INFO
- "%s: Block limits %d - %d bytes.\n", name,
- STp->min_block, STp->max_block);
+ st_printk(KERN_INFO, STp,
+ "Block limits %d - %d bytes.\n",
+ STp->min_block, STp->max_block);
} else {
STp->min_block = STp->max_block = (-1);
- DEBC(printk(ST_DEB_MSG "%s: Can't read block limits.\n",
- name));
+ DEBC_printk(STp, "Can't read block limits.\n");
}
}
@@ -1078,56 +1082,58 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
}
if ((STp->buffer)->syscall_result != 0) {
- DEBC(printk(ST_DEB_MSG "%s: No Mode Sense.\n", name));
+ DEBC_printk(STp, "No Mode Sense.\n");
STp->block_size = ST_DEFAULT_BLOCK; /* Educated guess (?) */
(STp->buffer)->syscall_result = 0; /* Prevent error propagation */
STp->drv_write_prot = 0;
} else {
- DEBC(printk(ST_DEB_MSG
- "%s: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n",
- name,
- (STp->buffer)->b_data[0], (STp->buffer)->b_data[1],
- (STp->buffer)->b_data[2], (STp->buffer)->b_data[3]));
+ DEBC_printk(STp,"Mode sense. Length %d, "
+ "medium %x, WBS %x, BLL %d\n",
+ (STp->buffer)->b_data[0],
+ (STp->buffer)->b_data[1],
+ (STp->buffer)->b_data[2],
+ (STp->buffer)->b_data[3]);
if ((STp->buffer)->b_data[3] >= 8) {
STp->drv_buffer = ((STp->buffer)->b_data[2] >> 4) & 7;
STp->density = (STp->buffer)->b_data[4];
STp->block_size = (STp->buffer)->b_data[9] * 65536 +
(STp->buffer)->b_data[10] * 256 + (STp->buffer)->b_data[11];
- DEBC(printk(ST_DEB_MSG
- "%s: Density %x, tape length: %x, drv buffer: %d\n",
- name, STp->density, (STp->buffer)->b_data[5] * 65536 +
- (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],
- STp->drv_buffer));
+ DEBC_printk(STp, "Density %x, tape length: %x, "
+ "drv buffer: %d\n",
+ STp->density,
+ (STp->buffer)->b_data[5] * 65536 +
+ (STp->buffer)->b_data[6] * 256 +
+ (STp->buffer)->b_data[7],
+ STp->drv_buffer);
}
STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
if (!STp->drv_buffer && STp->immediate_filemark) {
- printk(KERN_WARNING
- "%s: non-buffered tape: disabling writing immediate filemarks\n",
- name);
+ st_printk(KERN_WARNING, STp,
+ "non-buffered tape: disabling "
+ "writing immediate filemarks\n");
STp->immediate_filemark = 0;
}
}
st_release_request(SRpnt);
SRpnt = NULL;
- STp->inited = 1;
+ STp->inited = 1;
if (STp->block_size > 0)
(STp->buffer)->buffer_blocks =
- (STp->buffer)->buffer_size / STp->block_size;
+ (STp->buffer)->buffer_size / STp->block_size;
else
(STp->buffer)->buffer_blocks = 1;
(STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;
- DEBC(printk(ST_DEB_MSG
- "%s: Block size: %d, buffer size: %d (%d blocks).\n", name,
- STp->block_size, (STp->buffer)->buffer_size,
- (STp->buffer)->buffer_blocks));
+ DEBC_printk(STp, "Block size: %d, buffer size: %d (%d blocks).\n",
+ STp->block_size, (STp->buffer)->buffer_size,
+ (STp->buffer)->buffer_blocks);
if (STp->drv_write_prot) {
STp->write_prot = 1;
- DEBC(printk(ST_DEB_MSG "%s: Write protected\n", name));
+ DEBC_printk(STp, "Write protected\n");
if (do_wait &&
((st_flags & O_ACCMODE) == O_WRONLY ||
@@ -1141,8 +1147,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
/* This code is reached when the device is opened for the first time
after the driver has been initialized with tape in the drive and the
partition support has been enabled. */
- DEBC(printk(ST_DEB_MSG
- "%s: Updating partition number in status.\n", name));
+ DEBC_printk(STp, "Updating partition number in status.\n");
if ((STp->partition = find_partition(STp)) < 0) {
retval = STp->partition;
goto err_out;
@@ -1160,9 +1165,10 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
if (STp->default_drvbuffer != 0xff) {
if (st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer))
- printk(KERN_WARNING
- "%s: Can't set default drive buffering to %d.\n",
- name, STp->default_drvbuffer);
+ st_printk(KERN_WARNING, STp,
+ "Can't set default drive "
+ "buffering to %d.\n",
+ STp->default_drvbuffer);
}
}
@@ -1182,7 +1188,6 @@ static int st_open(struct inode *inode, struct file *filp)
struct scsi_tape *STp;
struct st_partstat *STps;
int dev = TAPE_NR(inode);
- char *name;
/*
* We really want to do nonseekable_open(inode, filp); here, but some
@@ -1196,13 +1201,12 @@ static int st_open(struct inode *inode, struct file *filp)
}
filp->private_data = STp;
- name = tape_name(STp);
spin_lock(&st_use_lock);
if (STp->in_use) {
spin_unlock(&st_use_lock);
scsi_tape_put(STp);
- DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
+ DEBC_printk(STp, "Device already in use.\n");
return (-EBUSY);
}
@@ -1222,8 +1226,8 @@ static int st_open(struct inode *inode, struct file *filp)
/* See that we have at least a one page buffer available */
if (!enlarge_buffer(STp->buffer, PAGE_SIZE, STp->restr_dma)) {
- printk(KERN_WARNING "%s: Can't allocate one page tape buffer.\n",
- name);
+ st_printk(KERN_WARNING, STp,
+ "Can't allocate one page tape buffer.\n");
retval = (-EOVERFLOW);
goto err_out;
}
@@ -1279,7 +1283,6 @@ static int st_flush(struct file *filp, fl_owner_t id)
struct scsi_tape *STp = filp->private_data;
struct st_modedef *STm = &(STp->modes[STp->current_mode]);
struct st_partstat *STps = &(STp->ps[STp->partition]);
- char *name = tape_name(STp);
if (file_count(filp) > 1)
return 0;
@@ -1292,24 +1295,25 @@ static int st_flush(struct file *filp, fl_owner_t id)
if (STp->can_partitions &&
(result2 = switch_partition(STp)) < 0) {
- DEBC(printk(ST_DEB_MSG
- "%s: switch_partition at close failed.\n", name));
+ DEBC_printk(STp, "switch_partition at close failed.\n");
if (result == 0)
result = result2;
goto out;
}
DEBC( if (STp->nbr_requests)
- printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
- name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
+ st_printk(KERN_DEBUG, STp,
+ "Number of r/w requests %d, dio used in %d, "
+ "pages %d.\n", STp->nbr_requests, STp->nbr_dio,
+ STp->nbr_pages));
if (STps->rw == ST_WRITING && !STp->pos_unknown) {
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
- DEBC(printk(ST_DEB_MSG "%s: Async write waits %d, finished %d.\n",
- name, STp->nbr_waits, STp->nbr_finished);
- )
-
+#if DEBUG
+ DEBC_printk(STp, "Async write waits %d, finished %d.\n",
+ STp->nbr_waits, STp->nbr_finished);
+#endif
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = WRITE_FILEMARKS;
if (STp->immediate_filemark)
@@ -1343,13 +1347,13 @@ static int st_flush(struct file *filp, fl_owner_t id)
else { /* Write error */
st_release_request(SRpnt);
SRpnt = NULL;
- printk(KERN_ERR "%s: Error on write filemark.\n", name);
+ st_printk(KERN_ERR, STp,
+ "Error on write filemark.\n");
if (result == 0)
result = (-EIO);
}
- DEBC(printk(ST_DEB_MSG "%s: Buffer flushed, %d EOF(s) written\n",
- name, cmd[4]));
+ DEBC_printk(STp, "Buffer flushed, %d EOF(s) written\n", cmd[4]);
} else if (!STp->rew_at_close) {
STps = &(STp->ps[STp->partition]);
if (!STm->sysv || STps->rw != ST_READING) {
@@ -1447,9 +1451,10 @@ static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
if (count == 0)
goto out;
- DEB(
+ DEB(
if (!STp->in_use) {
- printk(ST_DEB_MSG "%s: Incorrect device.\n", tape_name(STp));
+ st_printk(ST_DEB_MSG, STp,
+ "Incorrect device.\n");
retval = (-EIO);
goto out;
} ) /* end DEB */
@@ -1519,8 +1524,9 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
if (bufsize > STbp->buffer_size &&
!enlarge_buffer(STbp, bufsize, STp->restr_dma)) {
- printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n",
- tape_name(STp), bufsize);
+ st_printk(KERN_WARNING, STp,
+ "Can't allocate %d byte tape buffer.\n",
+ bufsize);
retval = (-EOVERFLOW);
goto out;
}
@@ -1563,7 +1569,6 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
struct st_modedef *STm;
struct st_partstat *STps;
struct st_buffer *STbp;
- char *name = tape_name(STp);
if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
@@ -1574,8 +1579,8 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
/* Write must be integral number of blocks */
if (STp->block_size != 0 && (count % STp->block_size) != 0) {
- printk(KERN_WARNING "%s: Write not multiple of tape block size.\n",
- name);
+ st_printk(KERN_WARNING, STp,
+ "Write not multiple of tape block size.\n");
retval = (-EINVAL);
goto out;
}
@@ -1601,8 +1606,8 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
if (STm->default_compression != ST_DONT_TOUCH &&
!(STp->compression_changed)) {
if (st_compression(STp, (STm->default_compression == ST_YES))) {
- printk(KERN_WARNING "%s: Can't set default compression.\n",
- name);
+ st_printk(KERN_WARNING, STp,
+ "Can't set default compression.\n");
if (modes_defined) {
retval = (-EINVAL);
goto out;
@@ -1723,7 +1728,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
if (STbp->syscall_result != 0) {
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
- DEBC(printk(ST_DEB_MSG "%s: Error on write:\n", name));
+ DEBC_printk(STp, "Error on write:\n");
if (cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) {
scode = cmdstatp->sense_hdr.sense_key;
if (cmdstatp->remainder_valid)
@@ -1750,9 +1755,9 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
if (STp->block_size == 0 ||
undone > 0 || count == 0)
retval = (-ENOSPC); /* EOM within current request */
- DEBC(printk(ST_DEB_MSG
- "%s: EOM with %d bytes unwritten.\n",
- name, (int)count));
+ DEBC_printk(STp, "EOM with %d "
+ "bytes unwritten.\n",
+ (int)count);
} else {
/* EOT within data buffered earlier (possible only
in fixed block mode without direct i/o) */
@@ -1765,9 +1770,10 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
STp->block_size;
}
STps->eof = ST_EOM_OK;
- DEBC(printk(ST_DEB_MSG
- "%s: Retry write of %d bytes at EOM.\n",
- name, STp->buffer->buffer_bytes));
+ DEBC_printk(STp, "Retry "
+ "write of %d "
+ "bytes at EOM.\n",
+ STp->buffer->buffer_bytes);
goto retry_write;
}
else {
@@ -1778,9 +1784,8 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
STps->eof = ST_EOM_ERROR;
STps->drv_block = (-1); /* Too cautious? */
retval = (-EIO); /* EOM for old data */
- DEBC(printk(ST_DEB_MSG
- "%s: EOM with lost data.\n",
- name));
+ DEBC_printk(STp, "EOM with "
+ "lost data.\n");
}
}
} else {
@@ -1839,7 +1844,6 @@ static long read_tape(struct scsi_tape *STp, long count,
struct st_partstat *STps;
struct st_buffer *STbp;
int retval = 0;
- char *name = tape_name(STp);
if (count == 0)
return 0;
@@ -1891,12 +1895,12 @@ static long read_tape(struct scsi_tape *STp, long count,
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
retval = 1;
- DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
- name,
- SRpnt->sense[0], SRpnt->sense[1],
- SRpnt->sense[2], SRpnt->sense[3],
- SRpnt->sense[4], SRpnt->sense[5],
- SRpnt->sense[6], SRpnt->sense[7]));
+ DEBC_printk(STp,
+ "Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
+ SRpnt->sense[0], SRpnt->sense[1],
+ SRpnt->sense[2], SRpnt->sense[3],
+ SRpnt->sense[4], SRpnt->sense[5],
+ SRpnt->sense[6], SRpnt->sense[7]);
if (cmdstatp->have_sense) {
if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
@@ -1913,23 +1917,27 @@ static long read_tape(struct scsi_tape *STp, long count,
transfer = bytes;
if (cmdstatp->flags & SENSE_ILI) { /* ILI */
- if (STp->block_size == 0) {
- if (transfer <= 0) {
- if (transfer < 0)
- printk(KERN_NOTICE
- "%s: Failed to read %d byte block with %d byte transfer.\n",
- name, bytes - transfer, bytes);
- if (STps->drv_block >= 0)
- STps->drv_block += 1;
- STbp->buffer_bytes = 0;
- return (-ENOMEM);
- }
+ if (STp->block_size == 0 &&
+ transfer < 0) {
+ st_printk(KERN_NOTICE, STp,
+ "Failed to read %d "
+ "byte block with %d "
+ "byte transfer.\n",
+ bytes - transfer,
+ bytes);
+ if (STps->drv_block >= 0)
+ STps->drv_block += 1;
+ STbp->buffer_bytes = 0;
+ return (-ENOMEM);
+ } else if (STp->block_size == 0) {
STbp->buffer_bytes = bytes - transfer;
} else {
st_release_request(SRpnt);
SRpnt = *aSRpnt = NULL;
if (transfer == blks) { /* We did not get anything, error */
- printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
+ st_printk(KERN_NOTICE, STp,
+ "Incorrect "
+ "block size.\n");
if (STps->drv_block >= 0)
STps->drv_block += blks - transfer + 1;
st_int_ioctl(STp, MTBSR, 1);
@@ -1938,9 +1946,11 @@ static long read_tape(struct scsi_tape *STp, long count,
/* We have some data, deliver it */
STbp->buffer_bytes = (blks - transfer) *
STp->block_size;
- DEBC(printk(ST_DEB_MSG
- "%s: ILI but enough data received %ld %d.\n",
- name, count, STbp->buffer_bytes));
+ DEBC_printk(STp, "ILI but "
+ "enough data "
+ "received %ld "
+ "%d.\n", count,
+ STbp->buffer_bytes);
if (STps->drv_block >= 0)
STps->drv_block += 1;
if (st_int_ioctl(STp, MTBSR, 1))
@@ -1956,9 +1966,9 @@ static long read_tape(struct scsi_tape *STp, long count,
else
STbp->buffer_bytes =
bytes - transfer * STp->block_size;
- DEBC(printk(ST_DEB_MSG
- "%s: EOF detected (%d bytes read).\n",
- name, STbp->buffer_bytes));
+ DEBC_printk(STp, "EOF detected (%d "
+ "bytes read).\n",
+ STbp->buffer_bytes);
} else if (cmdstatp->flags & SENSE_EOM) {
if (STps->eof == ST_FM)
STps->eof = ST_EOD_1;
@@ -1970,20 +1980,20 @@ static long read_tape(struct scsi_tape *STp, long count,
STbp->buffer_bytes =
bytes - transfer * STp->block_size;
- DEBC(printk(ST_DEB_MSG "%s: EOM detected (%d bytes read).\n",
- name, STbp->buffer_bytes));
+ DEBC_printk(STp, "EOM detected (%d "
+ "bytes read).\n",
+ STbp->buffer_bytes);
}
}
- /* end of EOF, EOM, ILI test */
+ /* end of EOF, EOM, ILI test */
else { /* nonzero sense key */
- DEBC(printk(ST_DEB_MSG
- "%s: Tape error while reading.\n", name));
+ DEBC_printk(STp, "Tape error while reading.\n");
STps->drv_block = (-1);
if (STps->eof == ST_FM &&
cmdstatp->sense_hdr.sense_key == BLANK_CHECK) {
- DEBC(printk(ST_DEB_MSG
- "%s: Zero returned for first BLANK CHECK after EOF.\n",
- name));
+ DEBC_printk(STp, "Zero returned for "
+ "first BLANK CHECK "
+ "after EOF.\n");
STps->eof = ST_EOD_2; /* First BLANK_CHECK after FM */
} else /* Some other extended sense code */
retval = (-EIO);
@@ -1992,13 +2002,13 @@ static long read_tape(struct scsi_tape *STp, long count,
if (STbp->buffer_bytes < 0) /* Caused by bogus sense data */
STbp->buffer_bytes = 0;
}
- /* End of extended sense test */
+ /* End of extended sense test */
else { /* Non-extended sense */
retval = STbp->syscall_result;
}
}
- /* End of error handling */
+ /* End of error handling */
else { /* Read successful */
STbp->buffer_bytes = bytes;
if (STp->sili) /* In fixed block mode residual is always zero here */
@@ -2028,7 +2038,6 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
struct st_modedef *STm;
struct st_partstat *STps;
struct st_buffer *STbp = STp->buffer;
- DEB( char *name = tape_name(STp); )
if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
@@ -2053,11 +2062,12 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
goto out;
STps->rw = ST_READING;
}
- DEB(
+ DEB(
if (debugging && STps->eof != ST_NOEOF)
- printk(ST_DEB_MSG "%s: EOF/EOM flag up (%d). Bytes %d\n", name,
- STps->eof, STbp->buffer_bytes);
- ) /* end DEB */
+ st_printk(ST_DEB_MSG, STp,
+ "EOF/EOM flag up (%d). Bytes %d\n",
+ STps->eof, STbp->buffer_bytes);
+ ) /* end DEB */
retval = setup_buffering(STp, buf, count, 1);
if (retval)
@@ -2104,13 +2114,13 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
/* Move the data from driver buffer to user buffer */
if (STbp->buffer_bytes > 0) {
- DEB(
+ DEB(
if (debugging && STps->eof != ST_NOEOF)
- printk(ST_DEB_MSG
- "%s: EOF up (%d). Left %d, needed %d.\n", name,
- STps->eof, STbp->buffer_bytes,
- (int)(count - total));
- ) /* end DEB */
+ st_printk(ST_DEB_MSG, STp,
+ "EOF up (%d). Left %d, needed %d.\n",
+ STps->eof, STbp->buffer_bytes,
+ (int)(count - total));
+ ) /* end DEB */
transfer = STbp->buffer_bytes < count - total ?
STbp->buffer_bytes : count - total;
if (!do_dio) {
@@ -2166,26 +2176,30 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
DEB(
/* Set the driver options */
-static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char *name)
+static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm)
{
if (debugging) {
- printk(KERN_INFO
- "%s: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
- name, STp->current_mode, STm->do_buffer_writes, STm->do_async_writes,
- STm->do_read_ahead);
- printk(KERN_INFO
- "%s: can bsr: %d, two FMs: %d, fast mteom: %d, auto lock: %d,\n",
- name, STp->can_bsr, STp->two_fm, STp->fast_mteom, STp->do_auto_lock);
- printk(KERN_INFO
- "%s: defs for wr: %d, no block limits: %d, partitions: %d, s2 log: %d\n",
- name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions,
- STp->scsi2_logical);
- printk(KERN_INFO
- "%s: sysv: %d nowait: %d sili: %d nowait_filemark: %d\n",
- name, STm->sysv, STp->immediate, STp->sili,
- STp->immediate_filemark);
- printk(KERN_INFO "%s: debugging: %d\n",
- name, debugging);
+ st_printk(KERN_INFO, STp,
+ "Mode %d options: buffer writes: %d, "
+ "async writes: %d, read ahead: %d\n",
+ STp->current_mode, STm->do_buffer_writes,
+ STm->do_async_writes, STm->do_read_ahead);
+ st_printk(KERN_INFO, STp,
+ " can bsr: %d, two FMs: %d, "
+ "fast mteom: %d, auto lock: %d,\n",
+ STp->can_bsr, STp->two_fm, STp->fast_mteom,
+ STp->do_auto_lock);
+ st_printk(KERN_INFO, STp,
+ " defs for wr: %d, no block limits: %d, "
+ "partitions: %d, s2 log: %d\n",
+ STm->defaults_for_writes, STp->omit_blklims,
+ STp->can_partitions, STp->scsi2_logical);
+ st_printk(KERN_INFO, STp,
+ " sysv: %d nowait: %d sili: %d "
+ "nowait_filemark: %d\n",
+ STm->sysv, STp->immediate, STp->sili,
+ STp->immediate_filemark);
+ st_printk(KERN_INFO, STp, " debugging: %d\n", debugging);
}
}
)
@@ -2196,7 +2210,6 @@ static int st_set_options(struct scsi_tape *STp, long options)
int value;
long code;
struct st_modedef *STm;
- char *name = tape_name(STp);
struct cdev *cd0, *cd1;
struct device *d0, *d1;
@@ -2212,9 +2225,8 @@ static int st_set_options(struct scsi_tape *STp, long options)
STm->devs[0] = d0;
STm->devs[1] = d1;
modes_defined = 1;
- DEBC(printk(ST_DEB_MSG
- "%s: Initialized mode %d definition from mode 0\n",
- name, STp->current_mode));
+ DEBC_printk(STp, "Initialized mode %d definition from mode 0\n",
+ STp->current_mode);
}
code = options & MT_ST_OPTIONS;
@@ -2236,7 +2248,7 @@ static int st_set_options(struct scsi_tape *STp, long options)
STm->sysv = (options & MT_ST_SYSV) != 0;
STp->sili = (options & MT_ST_SILI) != 0;
DEB( debugging = (options & MT_ST_DEBUGGING) != 0;
- st_log_options(STp, STm, name); )
+ st_log_options(STp, STm); )
} else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) {
value = (code == MT_ST_SETBOOLEANS);
if ((options & MT_ST_BUFFER_WRITES) != 0)
@@ -2270,21 +2282,21 @@ static int st_set_options(struct scsi_tape *STp, long options)
STm->sysv = value;
if ((options & MT_ST_SILI) != 0)
STp->sili = value;
- DEB(
+ DEB(
if ((options & MT_ST_DEBUGGING) != 0)
debugging = value;
- st_log_options(STp, STm, name); )
+ st_log_options(STp, STm); )
} else if (code == MT_ST_WRITE_THRESHOLD) {
/* Retained for compatibility */
} else if (code == MT_ST_DEF_BLKSIZE) {
value = (options & ~MT_ST_OPTIONS);
if (value == ~MT_ST_OPTIONS) {
STm->default_blksize = (-1);
- DEBC( printk(KERN_INFO "%s: Default block size disabled.\n", name));
+ DEBC_printk(STp, "Default block size disabled.\n");
} else {
STm->default_blksize = value;
- DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n",
- name, STm->default_blksize));
+ DEBC_printk(STp,"Default block size set to "
+ "%d bytes.\n", STm->default_blksize);
if (STp->ready == ST_READY) {
STp->blksize_changed = 0;
set_mode_densblk(STp, STm);
@@ -2294,13 +2306,13 @@ static int st_set_options(struct scsi_tape *STp, long options)
value = (options & ~MT_ST_OPTIONS);
if ((value & MT_ST_SET_LONG_TIMEOUT) != 0) {
STp->long_timeout = (value & ~MT_ST_SET_LONG_TIMEOUT) * HZ;
- DEBC( printk(KERN_INFO "%s: Long timeout set to %d seconds.\n", name,
- (value & ~MT_ST_SET_LONG_TIMEOUT)));
+ DEBC_printk(STp, "Long timeout set to %d seconds.\n",
+ (value & ~MT_ST_SET_LONG_TIMEOUT));
} else {
blk_queue_rq_timeout(STp->device->request_queue,
value * HZ);
- DEBC( printk(KERN_INFO "%s: Normal timeout set to %d seconds.\n",
- name, value) );
+ DEBC_printk(STp, "Normal timeout set to %d seconds.\n",
+ value);
}
} else if (code == MT_ST_SET_CLN) {
value = (options & ~MT_ST_OPTIONS) & 0xff;
@@ -2311,21 +2323,21 @@ static int st_set_options(struct scsi_tape *STp, long options)
STp->cln_mode = value;
STp->cln_sense_mask = (options >> 8) & 0xff;
STp->cln_sense_value = (options >> 16) & 0xff;
- printk(KERN_INFO
- "%s: Cleaning request mode %d, mask %02x, value %02x\n",
- name, value, STp->cln_sense_mask, STp->cln_sense_value);
+ st_printk(KERN_INFO, STp,
+ "Cleaning request mode %d, mask %02x, value %02x\n",
+ value, STp->cln_sense_mask, STp->cln_sense_value);
} else if (code == MT_ST_DEF_OPTIONS) {
code = (options & ~MT_ST_CLEAR_DEFAULT);
value = (options & MT_ST_CLEAR_DEFAULT);
if (code == MT_ST_DEF_DENSITY) {
if (value == MT_ST_CLEAR_DEFAULT) {
STm->default_density = (-1);
- DEBC( printk(KERN_INFO "%s: Density default disabled.\n",
- name));
+ DEBC_printk(STp,
+ "Density default disabled.\n");
} else {
STm->default_density = value & 0xff;
- DEBC( printk(KERN_INFO "%s: Density default set to %x\n",
- name, STm->default_density));
+ DEBC_printk(STp, "Density default set to %x\n",
+ STm->default_density);
if (STp->ready == ST_READY) {
STp->density_changed = 0;
set_mode_densblk(STp, STm);
@@ -2334,31 +2346,33 @@ static int st_set_options(struct scsi_tape *STp, long options)
} else if (code == MT_ST_DEF_DRVBUFFER) {
if (value == MT_ST_CLEAR_DEFAULT) {
STp->default_drvbuffer = 0xff;
- DEBC( printk(KERN_INFO
- "%s: Drive buffer default disabled.\n", name));
+ DEBC_printk(STp,
+ "Drive buffer default disabled.\n");
} else {
STp->default_drvbuffer = value & 7;
- DEBC( printk(KERN_INFO
- "%s: Drive buffer default set to %x\n",
- name, STp->default_drvbuffer));
+ DEBC_printk(STp,
+ "Drive buffer default set to %x\n",
+ STp->default_drvbuffer);
if (STp->ready == ST_READY)
st_int_ioctl(STp, MTSETDRVBUFFER, STp->default_drvbuffer);
}
} else if (code == MT_ST_DEF_COMPRESSION) {
if (value == MT_ST_CLEAR_DEFAULT) {
STm->default_compression = ST_DONT_TOUCH;
- DEBC( printk(KERN_INFO
- "%s: Compression default disabled.\n", name));
+ DEBC_printk(STp,
+ "Compression default disabled.\n");
} else {
if ((value & 0xff00) != 0) {
STp->c_algo = (value & 0xff00) >> 8;
- DEBC( printk(KERN_INFO "%s: Compression algorithm set to 0x%x.\n",
- name, STp->c_algo));
+ DEBC_printk(STp, "Compression "
+ "algorithm set to 0x%x.\n",
+ STp->c_algo);
}
if ((value & 0xff) != 0xff) {
STm->default_compression = (value & 1 ? ST_YES : ST_NO);
- DEBC( printk(KERN_INFO "%s: Compression default set to %x\n",
- name, (value & 1)));
+ DEBC_printk(STp, "Compression default "
+ "set to %x\n",
+ (value & 1));
if (STp->ready == ST_READY) {
STp->compression_changed = 0;
st_compression(STp, (STm->default_compression == ST_YES));
@@ -2473,7 +2487,6 @@ static int st_compression(struct scsi_tape * STp, int state)
int retval;
int mpoffs; /* Offset to mode page start */
unsigned char *b_data = (STp->buffer)->b_data;
- DEB( char *name = tape_name(STp); )
if (STp->ready != ST_READY)
return (-EIO);
@@ -2481,18 +2494,17 @@ static int st_compression(struct scsi_tape * STp, int state)
/* Read the current page contents */
retval = read_mode_page(STp, COMPRESSION_PAGE, 0);
if (retval) {
- DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n",
- name));
+ DEBC_printk(STp, "Compression mode page not supported.\n");
return (-EIO);
}
mpoffs = MODE_HEADER_LENGTH + b_data[MH_OFF_BDESCS_LENGTH];
- DEBC(printk(ST_DEB_MSG "%s: Compression state is %d.\n", name,
- (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0)));
+ DEBC_printk(STp, "Compression state is %d.\n",
+ (b_data[mpoffs + CP_OFF_DCE_DCC] & DCE_MASK ? 1 : 0));
/* Check if compression can be changed */
if ((b_data[mpoffs + CP_OFF_DCE_DCC] & DCC_MASK) == 0) {
- DEBC(printk(ST_DEB_MSG "%s: Compression not supported.\n", name));
+ DEBC_printk(STp, "Compression not supported.\n");
return (-EIO);
}
@@ -2510,11 +2522,10 @@ static int st_compression(struct scsi_tape * STp, int state)
retval = write_mode_page(STp, COMPRESSION_PAGE, 0);
if (retval) {
- DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name));
+ DEBC_printk(STp, "Compression change failed.\n");
return (-EIO);
}
- DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n",
- name, state));
+ DEBC_printk(STp, "Compression state changed to %d.\n", state);
STp->compression_changed = 1;
return 0;
@@ -2525,7 +2536,6 @@ static int st_compression(struct scsi_tape * STp, int state)
static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_code)
{
int retval = (-EIO), timeout;
- DEB( char *name = tape_name(STp); )
unsigned char cmd[MAX_COMMAND_SIZE];
struct st_partstat *STps;
struct st_request *SRpnt;
@@ -2546,9 +2556,9 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod
*/
if (load_code >= 1 + MT_ST_HPLOADER_OFFSET
&& load_code <= 6 + MT_ST_HPLOADER_OFFSET) {
- DEBC(printk(ST_DEB_MSG "%s: Enhanced %sload slot %2d.\n",
- name, (cmd[4]) ? "" : "un",
- load_code - MT_ST_HPLOADER_OFFSET));
+ DEBC_printk(STp, " Enhanced %sload slot %2d.\n",
+ (cmd[4]) ? "" : "un",
+ load_code - MT_ST_HPLOADER_OFFSET);
cmd[3] = load_code - MT_ST_HPLOADER_OFFSET; /* MediaID field of C1553A */
}
if (STp->immediate) {
@@ -2560,9 +2570,9 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod
DEBC(
if (!load_code)
- printk(ST_DEB_MSG "%s: Unloading tape.\n", name);
+ st_printk(ST_DEB_MSG, STp, "Unloading tape.\n");
else
- printk(ST_DEB_MSG "%s: Loading tape.\n", name);
+ st_printk(ST_DEB_MSG, STp, "Loading tape.\n");
);
SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
@@ -2597,17 +2607,24 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod
#if DEBUG
#define ST_DEB_FORWARD 0
#define ST_DEB_BACKWARD 1
-static void deb_space_print(char *name, int direction, char *units, unsigned char *cmd)
+static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd)
{
s32 sc;
+ if (!debugging)
+ return;
+
sc = cmd[2] & 0x80 ? 0xff000000 : 0;
sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
if (direction)
sc = -sc;
- printk(ST_DEB_MSG "%s: Spacing tape %s over %d %s.\n", name,
- direction ? "backward" : "forward", sc, units);
+ st_printk(ST_DEB_MSG, STp, "Spacing tape %s over %d %s.\n",
+ direction ? "backward" : "forward", sc, units);
}
+#else
+#define ST_DEB_FORWARD 0
+#define ST_DEB_BACKWARD 1
+static void deb_space_print(struct scsi_tape *STp, int direction, char *units, unsigned char *cmd) {}
#endif
@@ -2623,7 +2640,6 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
struct st_partstat *STps;
int fileno, blkno, at_sm, undone;
int datalen = 0, direction = DMA_NONE;
- char *name = tape_name(STp);
WARN_ON(STp->buffer->do_dio != 0);
if (STp->ready != ST_READY) {
@@ -2648,7 +2664,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (arg >> 16);
cmd[3] = (arg >> 8);
cmd[4] = arg;
- DEBC(deb_space_print(name, ST_DEB_FORWARD, "filemarks", cmd);)
+ deb_space_print(STp, ST_DEB_FORWARD, "filemarks", cmd);
if (fileno >= 0)
fileno += arg;
blkno = 0;
@@ -2663,7 +2679,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (ltmp >> 16);
cmd[3] = (ltmp >> 8);
cmd[4] = ltmp;
- DEBC(deb_space_print(name, ST_DEB_BACKWARD, "filemarks", cmd);)
+ deb_space_print(STp, ST_DEB_BACKWARD, "filemarks", cmd);
if (fileno >= 0)
fileno -= arg;
blkno = (-1); /* We can't know the block number */
@@ -2675,7 +2691,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (arg >> 16);
cmd[3] = (arg >> 8);
cmd[4] = arg;
- DEBC(deb_space_print(name, ST_DEB_FORWARD, "blocks", cmd);)
+ deb_space_print(STp, ST_DEB_FORWARD, "blocks", cmd);
if (blkno >= 0)
blkno += arg;
at_sm &= (arg == 0);
@@ -2687,7 +2703,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (ltmp >> 16);
cmd[3] = (ltmp >> 8);
cmd[4] = ltmp;
- DEBC(deb_space_print(name, ST_DEB_BACKWARD, "blocks", cmd);)
+ deb_space_print(STp, ST_DEB_BACKWARD, "blocks", cmd);
if (blkno >= 0)
blkno -= arg;
at_sm &= (arg == 0);
@@ -2698,7 +2714,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (arg >> 16);
cmd[3] = (arg >> 8);
cmd[4] = arg;
- DEBC(deb_space_print(name, ST_DEB_FORWARD, "setmarks", cmd);)
+ deb_space_print(STp, ST_DEB_FORWARD, "setmarks", cmd);
if (arg != 0) {
blkno = fileno = (-1);
at_sm = 1;
@@ -2711,7 +2727,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[2] = (ltmp >> 16);
cmd[3] = (ltmp >> 8);
cmd[4] = ltmp;
- DEBC(deb_space_print(name, ST_DEB_BACKWARD, "setmarks", cmd);)
+ deb_space_print(STp, ST_DEB_BACKWARD, "setmarks", cmd);
if (arg != 0) {
blkno = fileno = (-1);
at_sm = 1;
@@ -2732,13 +2748,19 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[3] = (arg >> 8);
cmd[4] = arg;
timeout = STp->device->request_queue->rq_timeout;
- DEBC(
- if (cmd_in != MTWSM)
- printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name,
- cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
- else
- printk(ST_DEB_MSG "%s: Writing %d setmarks.\n", name,
- cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
+ DEBC(
+ if (cmd_in != MTWSM)
+ st_printk(ST_DEB_MSG, STp,
+ "Writing %d filemarks.\n",
+ cmd[2] * 65536 +
+ cmd[3] * 256 +
+ cmd[4]);
+ else
+ st_printk(ST_DEB_MSG, STp,
+ "Writing %d setmarks.\n",
+ cmd[2] * 65536 +
+ cmd[3] * 256 +
+ cmd[4]);
)
if (fileno >= 0)
fileno += arg;
@@ -2751,11 +2773,11 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
cmd[1] = 1; /* Don't wait for completion */
timeout = STp->device->request_queue->rq_timeout;
}
- DEBC(printk(ST_DEB_MSG "%s: Rewinding tape.\n", name));
+ DEBC_printk(STp, "Rewinding tape.\n");
fileno = blkno = at_sm = 0;
break;
case MTNOP:
- DEBC(printk(ST_DEB_MSG "%s: No op on tape.\n", name));
+ DEBC_printk(STp, "No op on tape.\n");
return 0; /* Should do something ? */
break;
case MTRETEN:
@@ -2765,7 +2787,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
timeout = STp->device->request_queue->rq_timeout;
}
cmd[4] = 3;
- DEBC(printk(ST_DEB_MSG "%s: Retensioning tape.\n", name));
+ DEBC_printk(STp, "Retensioning tape.\n");
fileno = blkno = at_sm = 0;
break;
case MTEOM:
@@ -2783,8 +2805,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
fileno = (-1);
cmd[0] = SPACE;
cmd[1] = 3;
- DEBC(printk(ST_DEB_MSG "%s: Spacing to end of recorded medium.\n",
- name));
+ DEBC_printk(STp, "Spacing to end of recorded medium.\n");
blkno = -1;
at_sm = 0;
break;
@@ -2800,7 +2821,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
else
timeout = STp->long_timeout * 8;
- DEBC(printk(ST_DEB_MSG "%s: Erasing tape.\n", name));
+ DEBC_printk(STp, "Erasing tape.\n");
fileno = blkno = at_sm = 0;
break;
case MTSETBLK: /* Set block length */
@@ -2815,7 +2836,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
STp->max_block > 0 &&
((arg & MT_ST_BLKSIZE_MASK) < STp->min_block ||
(arg & MT_ST_BLKSIZE_MASK) > STp->max_block)) {
- printk(KERN_WARNING "%s: Illegal block size.\n", name);
+ st_printk(KERN_WARNING, STp, "Illegal block size.\n");
return (-EINVAL);
}
cmd[0] = MODE_SELECT;
@@ -2848,21 +2869,21 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
(STp->buffer)->b_data[10] = (ltmp >> 8);
(STp->buffer)->b_data[11] = ltmp;
timeout = STp->device->request_queue->rq_timeout;
- DEBC(
+ DEBC(
if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK)
- printk(ST_DEB_MSG
- "%s: Setting block size to %d bytes.\n", name,
- (STp->buffer)->b_data[9] * 65536 +
- (STp->buffer)->b_data[10] * 256 +
- (STp->buffer)->b_data[11]);
+ st_printk(ST_DEB_MSG, STp,
+ "Setting block size to %d bytes.\n",
+ (STp->buffer)->b_data[9] * 65536 +
+ (STp->buffer)->b_data[10] * 256 +
+ (STp->buffer)->b_data[11]);
if (cmd_in == MTSETDENSITY || cmd_in == SET_DENS_AND_BLK)
- printk(ST_DEB_MSG
- "%s: Setting density code to %x.\n", name,
- (STp->buffer)->b_data[4]);
+ st_printk(ST_DEB_MSG, STp,
+ "Setting density code to %x.\n",
+ (STp->buffer)->b_data[4]);
if (cmd_in == MTSETDRVBUFFER)
- printk(ST_DEB_MSG
- "%s: Setting drive buffer code to %d.\n", name,
- ((STp->buffer)->b_data[2] >> 4) & 7);
+ st_printk(ST_DEB_MSG, STp,
+ "Setting drive buffer code to %d.\n",
+ ((STp->buffer)->b_data[2] >> 4) & 7);
)
break;
default:
@@ -3019,7 +3040,6 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti
int result;
unsigned char scmd[MAX_COMMAND_SIZE];
struct st_request *SRpnt;
- DEB( char *name = tape_name(STp); )
if (STp->ready != ST_READY)
return (-EIO);
@@ -3043,7 +3063,7 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti
(STp->device->scsi_level >= SCSI_2 &&
((STp->buffer)->b_data[0] & 4) != 0)) {
*block = *partition = 0;
- DEBC(printk(ST_DEB_MSG "%s: Can't read tape position.\n", name));
+ DEBC_printk(STp, " Can't read tape position.\n");
result = (-EIO);
} else {
result = 0;
@@ -3062,8 +3082,8 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti
(STp->buffer)->b_data[1] == 0) /* BOP of partition 0 */
STp->ps[0].drv_block = STp->ps[0].drv_file = 0;
}
- DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
- *block, *partition));
+ DEBC_printk(STp, "Got tape pos. blk %d part %d.\n",
+ *block, *partition);
}
st_release_request(SRpnt);
SRpnt = NULL;
@@ -3083,15 +3103,14 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition
int timeout;
unsigned char scmd[MAX_COMMAND_SIZE];
struct st_request *SRpnt;
- DEB( char *name = tape_name(STp); )
if (STp->ready != ST_READY)
return (-EIO);
timeout = STp->long_timeout;
STps = &(STp->ps[STp->partition]);
- DEBC(printk(ST_DEB_MSG "%s: Setting block to %d and partition to %d.\n",
- name, block, partition));
+ DEBC_printk(STp, "Setting block to %d and partition to %d.\n",
+ block, partition);
DEB(if (partition < 0)
return (-EIO); )
@@ -3105,9 +3124,9 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition
else {
STps->last_block_valid = 1;
STps->last_block_visited = blk;
- DEBC(printk(ST_DEB_MSG
- "%s: Visited block %d for partition %d saved.\n",
- name, blk, STp->partition));
+ DEBC_printk(STp, "Visited block %d for "
+ "partition %d saved.\n",
+ blk, STp->partition);
}
}
@@ -3129,9 +3148,9 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition
if (STp->partition != partition) {
scmd[1] |= 2;
scmd[8] = partition;
- DEBC(printk(ST_DEB_MSG
- "%s: Trying to change partition from %d to %d\n",
- name, STp->partition, partition));
+ DEBC_printk(STp, "Trying to change partition "
+ "from %d to %d\n", STp->partition,
+ partition);
}
}
if (STp->immediate) {
@@ -3222,7 +3241,6 @@ static int switch_partition(struct scsi_tape *STp)
static int nbr_partitions(struct scsi_tape *STp)
{
int result;
- DEB( char *name = tape_name(STp); )
if (STp->ready != ST_READY)
return (-EIO);
@@ -3230,13 +3248,12 @@ static int nbr_partitions(struct scsi_tape *STp)
result = read_mode_page(STp, PART_PAGE, 1);
if (result) {
- DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n",
- name));
+ DEBC_printk(STp, "Can't read medium partition page.\n");
result = (-EIO);
} else {
result = (STp->buffer)->b_data[MODE_HEADER_LENGTH +
PP_OFF_NBR_ADD_PARTS] + 1;
- DEBC(printk(ST_DEB_MSG "%s: Number of partitions %d.\n", name, result));
+ DEBC_printk(STp, "Number of partitions %d.\n", result);
}
return result;
@@ -3264,21 +3281,20 @@ static int nbr_partitions(struct scsi_tape *STp)
*/
static int partition_tape(struct scsi_tape *STp, int size)
{
- char *name = tape_name(STp);
int result;
int pgo, psd_cnt, psdo;
unsigned char *bp;
result = read_mode_page(STp, PART_PAGE, 0);
if (result) {
- DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name));
+ DEBC_printk(STp, "Can't read partition mode page.\n");
return result;
}
/* The mode page is in the buffer. Let's modify it and write it. */
bp = (STp->buffer)->b_data;
pgo = MODE_HEADER_LENGTH + bp[MH_OFF_BDESCS_LENGTH];
- DEBC(printk(ST_DEB_MSG "%s: Partition page length is %d bytes.\n",
- name, bp[pgo + MP_OFF_PAGE_LENGTH] + 2));
+ DEBC_printk(STp, "Partition page length is %d bytes.\n",
+ bp[pgo + MP_OFF_PAGE_LENGTH] + 2);
psd_cnt = (bp[pgo + MP_OFF_PAGE_LENGTH] + 2 - PART_PAGE_FIXED_LENGTH) / 2;
psdo = pgo + PART_PAGE_FIXED_LENGTH;
@@ -3288,25 +3304,23 @@ static int partition_tape(struct scsi_tape *STp, int size)
}
memset(bp + psdo, 0, bp[pgo + PP_OFF_NBR_ADD_PARTS] * 2);
- DEBC(printk("%s: psd_cnt %d, max.parts %d, nbr_parts %d\n", name,
+ DEBC_printk(STp, "psd_cnt %d, max.parts %d, nbr_parts %d\n",
psd_cnt, bp[pgo + PP_OFF_MAX_ADD_PARTS],
- bp[pgo + PP_OFF_NBR_ADD_PARTS]));
+ bp[pgo + PP_OFF_NBR_ADD_PARTS]);
if (size <= 0) {
bp[pgo + PP_OFF_NBR_ADD_PARTS] = 0;
if (psd_cnt <= bp[pgo + PP_OFF_MAX_ADD_PARTS])
bp[pgo + MP_OFF_PAGE_LENGTH] = 6;
- DEBC(printk(ST_DEB_MSG "%s: Formatting tape with one partition.\n",
- name));
+ DEBC_printk(STp, "Formatting tape with one partition.\n");
} else {
bp[psdo] = (size >> 8) & 0xff;
bp[psdo + 1] = size & 0xff;
bp[pgo + 3] = 1;
if (bp[pgo + MP_OFF_PAGE_LENGTH] < 8)
bp[pgo + MP_OFF_PAGE_LENGTH] = 8;
- DEBC(printk(ST_DEB_MSG
- "%s: Formatting tape with two partitions (1 = %d MB).\n",
- name, size));
+ DEBC_printk(STp, "Formatting tape with two partitions "
+ "(1 = %d MB).\n", size);
}
bp[pgo + PP_OFF_PART_UNITS] = 0;
bp[pgo + PP_OFF_RESERVED] = 0;
@@ -3314,7 +3328,7 @@ static int partition_tape(struct scsi_tape *STp, int size)
result = write_mode_page(STp, PART_PAGE, 1);
if (result) {
- printk(KERN_INFO "%s: Partitioning of tape failed.\n", name);
+ st_printk(KERN_INFO, STp, "Partitioning of tape failed.\n");
result = (-EIO);
}
@@ -3332,15 +3346,14 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
struct scsi_tape *STp = file->private_data;
struct st_modedef *STm;
struct st_partstat *STps;
- char *name = tape_name(STp);
void __user *p = (void __user *)arg;
if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
- DEB(
+ DEB(
if (debugging && !STp->in_use) {
- printk(ST_DEB_MSG "%s: Incorrect device.\n", name);
+ st_printk(ST_DEB_MSG, STp, "Incorrect device.\n");
retval = (-EIO);
goto out;
} ) /* end DEB */
@@ -3378,8 +3391,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
}
if (mtc.mt_op == MTSETDRVBUFFER && !capable(CAP_SYS_ADMIN)) {
- printk(KERN_WARNING
- "%s: MTSETDRVBUFFER only allowed for root.\n", name);
+ st_printk(KERN_WARNING, STp,
+ "MTSETDRVBUFFER only allowed for root.\n");
retval = (-EPERM);
goto out;
}
@@ -4087,7 +4100,8 @@ static int st_probe(struct device *dev)
return -ENODEV;
if ((stp = st_incompatible(SDp))) {
sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
- printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
+ sdev_printk(KERN_INFO, SDp,
+ "st: The suggested driver is %s.\n", stp);
return -ENODEV;
}
@@ -4096,20 +4110,23 @@ static int st_probe(struct device *dev)
i = st_max_sg_segs;
buffer = new_tape_buffer((SDp->host)->unchecked_isa_dma, i);
if (buffer == NULL) {
- printk(KERN_ERR
- "st: Can't allocate new tape buffer. Device not attached.\n");
+ sdev_printk(KERN_ERR, SDp,
+ "st: Can't allocate new tape buffer. "
+ "Device not attached.\n");
goto out;
}
disk = alloc_disk(1);
if (!disk) {
- printk(KERN_ERR "st: out of memory. Device not attached.\n");
+ sdev_printk(KERN_ERR, SDp,
+ "st: out of memory. Device not attached.\n");
goto out_buffer_free;
}
tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
if (tpnt == NULL) {
- printk(KERN_ERR "st: Can't allocate device descriptor.\n");
+ sdev_printk(KERN_ERR, SDp,
+ "st: Can't allocate device descriptor.\n");
goto out_put_disk;
}
kref_init(&tpnt->kref);
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 9969fa1ef7c4..fecac5d03fdd 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -33,6 +33,7 @@
#include <linux/device.h>
#include <linux/hyperv.h>
#include <linux/mempool.h>
+#include <linux/blkdev.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -326,21 +327,23 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
*/
static int storvsc_timeout = 180;
+static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
+
#define STORVSC_MAX_IO_REQUESTS 200
static void storvsc_on_channel_callback(void *context);
-/*
- * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
- * reality, the path/target is not used (ie always set to 0) so our
- * scsi host adapter essentially has 1 bus with 1 target that contains
- * up to 256 luns.
- */
-#define STORVSC_MAX_LUNS_PER_TARGET 64
-#define STORVSC_MAX_TARGETS 1
-#define STORVSC_MAX_CHANNELS 1
+#define STORVSC_MAX_LUNS_PER_TARGET 255
+#define STORVSC_MAX_TARGETS 2
+#define STORVSC_MAX_CHANNELS 8
+#define STORVSC_FC_MAX_LUNS_PER_TARGET 255
+#define STORVSC_FC_MAX_TARGETS 128
+#define STORVSC_FC_MAX_CHANNELS 8
+#define STORVSC_IDE_MAX_LUNS_PER_TARGET 64
+#define STORVSC_IDE_MAX_TARGETS 1
+#define STORVSC_IDE_MAX_CHANNELS 1
struct storvsc_cmd_request {
struct list_head entry;
@@ -1017,6 +1020,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
case ATA_12:
set_host_byte(scmnd, DID_PASSTHROUGH);
break;
+ /*
+ * On Some Windows hosts TEST_UNIT_READY command can return
+ * SRB_STATUS_ERROR, let the upper level code deal with it
+ * based on the sense information.
+ */
+ case TEST_UNIT_READY:
+ break;
default:
set_host_byte(scmnd, DID_TARGET_FAILURE);
}
@@ -1441,6 +1451,14 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
sdevice->no_write_same = 1;
+ /*
+ * Add blist flags to permit the reading of the VPD pages even when
+ * the target may claim SPC-2 compliance. MSFT targets currently
+ * claim SPC-2 compliance while they implement post SPC-2 features.
+ * With this patch we can correctly handle WRITE_SAME_16 issues.
+ */
+ sdevice->sdev_bflags |= msft_blist_flags;
+
return 0;
}
@@ -1518,6 +1536,16 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
return SUCCESS;
}
+/*
+ * The host guarantees to respond to each command, although I/O latencies might
+ * be unbounded on Azure. Reset the timer unconditionally to give the host a
+ * chance to perform EH.
+ */
+static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
+{
+ return BLK_EH_RESET_TIMER;
+}
+
static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd)
{
bool allowed = true;
@@ -1553,9 +1581,19 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
struct vmscsi_request *vm_srb;
struct stor_mem_pools *memp = scmnd->device->hostdata;
- if (!storvsc_scsi_cmd_ok(scmnd)) {
- scmnd->scsi_done(scmnd);
- return 0;
+ if (vmstor_current_major <= VMSTOR_WIN8_MAJOR) {
+ /*
+ * On legacy hosts filter unimplemented commands.
+ * Future hosts are expected to correctly handle
+ * unsupported commands. Furthermore, it is
+ * possible that some of the currently
+ * unsupported commands maybe supported in
+ * future versions of the host.
+ */
+ if (!storvsc_scsi_cmd_ok(scmnd)) {
+ scmnd->scsi_done(scmnd);
+ return 0;
+ }
}
request_size = sizeof(struct storvsc_cmd_request);
@@ -1580,26 +1618,24 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
vm_srb = &cmd_request->vstor_packet.vm_srb;
vm_srb->win8_extension.time_out_value = 60;
+ vm_srb->win8_extension.srb_flags |=
+ (SRB_FLAGS_QUEUE_ACTION_ENABLE |
+ SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
/* Build the SRB */
switch (scmnd->sc_data_direction) {
case DMA_TO_DEVICE:
vm_srb->data_in = WRITE_TYPE;
vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT;
- vm_srb->win8_extension.srb_flags |=
- (SRB_FLAGS_QUEUE_ACTION_ENABLE |
- SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
break;
case DMA_FROM_DEVICE:
vm_srb->data_in = READ_TYPE;
vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN;
- vm_srb->win8_extension.srb_flags |=
- (SRB_FLAGS_QUEUE_ACTION_ENABLE |
- SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
break;
default:
vm_srb->data_in = UNKNOWN_TYPE;
- vm_srb->win8_extension.srb_flags = 0;
+ vm_srb->win8_extension.srb_flags |= (SRB_FLAGS_DATA_IN |
+ SRB_FLAGS_DATA_OUT);
break;
}
@@ -1687,11 +1723,11 @@ static struct scsi_host_template scsi_driver = {
.bios_param = storvsc_get_chs,
.queuecommand = storvsc_queuecommand,
.eh_host_reset_handler = storvsc_host_reset_handler,
+ .eh_timed_out = storvsc_eh_timed_out,
.slave_alloc = storvsc_device_alloc,
.slave_destroy = storvsc_device_destroy,
.slave_configure = storvsc_device_configure,
- .cmd_per_lun = 1,
- /* 64 max_queue * 1 target */
+ .cmd_per_lun = 255,
.can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id = -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
@@ -1743,19 +1779,25 @@ static int storvsc_probe(struct hv_device *device,
* set state to properly communicate with the host.
*/
- if (vmbus_proto_version == VERSION_WIN8) {
- sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
- vmscsi_size_delta = 0;
- vmstor_current_major = VMSTOR_WIN8_MAJOR;
- vmstor_current_minor = VMSTOR_WIN8_MINOR;
- } else {
+ switch (vmbus_proto_version) {
+ case VERSION_WS2008:
+ case VERSION_WIN7:
sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
vmstor_current_major = VMSTOR_WIN7_MAJOR;
vmstor_current_minor = VMSTOR_WIN7_MINOR;
+ break;
+ default:
+ sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
+ vmscsi_size_delta = 0;
+ vmstor_current_major = VMSTOR_WIN8_MAJOR;
+ vmstor_current_minor = VMSTOR_WIN8_MINOR;
+ break;
}
-
+ if (dev_id->driver_data == SFC_GUID)
+ scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
+ STORVSC_FC_MAX_TARGETS);
host = scsi_host_alloc(&scsi_driver,
sizeof(struct hv_host_device));
if (!host)
@@ -1789,12 +1831,25 @@ static int storvsc_probe(struct hv_device *device,
host_dev->path = stor_device->path_id;
host_dev->target = stor_device->target_id;
- /* max # of devices per target */
- host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
- /* max # of targets per channel */
- host->max_id = STORVSC_MAX_TARGETS;
- /* max # of channels */
- host->max_channel = STORVSC_MAX_CHANNELS - 1;
+ switch (dev_id->driver_data) {
+ case SFC_GUID:
+ host->max_lun = STORVSC_FC_MAX_LUNS_PER_TARGET;
+ host->max_id = STORVSC_FC_MAX_TARGETS;
+ host->max_channel = STORVSC_FC_MAX_CHANNELS - 1;
+ break;
+
+ case SCSI_GUID:
+ host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
+ host->max_id = STORVSC_MAX_TARGETS;
+ host->max_channel = STORVSC_MAX_CHANNELS - 1;
+ break;
+
+ default:
+ host->max_lun = STORVSC_IDE_MAX_LUNS_PER_TARGET;
+ host->max_id = STORVSC_IDE_MAX_TARGETS;
+ host->max_channel = STORVSC_IDE_MAX_CHANNELS - 1;
+ break;
+ }
/* max cmd length */
host->max_cmd_len = STORVSC_MAX_CMD_LEN;
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 88220794cc98..1a2367a1b1f2 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -355,17 +355,18 @@ static void __init init_tags( void )
static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
- if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))
+ if (hostdata->busy[cmd->device->id] & (1 << lun))
return( 1 );
if (!should_be_tagged ||
!setup_use_tagged_queuing || !cmd->device->tagged_supported)
return( 0 );
- if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
- TagAlloc[cmd->device->id][cmd->device->lun].queue_size ) {
+ if (TagAlloc[cmd->device->id][lun].nr_allocated >=
+ TagAlloc[cmd->device->id][lun].queue_size ) {
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
- H_NO(cmd), cmd->device->id, cmd->device->lun );
+ H_NO(cmd), cmd->device->id, lun );
return( 1 );
}
return( 0 );
@@ -379,6 +380,7 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
/* If we or the target don't support tagged queuing, allocate the LUN for
@@ -387,19 +389,19 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
if (!should_be_tagged ||
!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
cmd->tag = TAG_NONE;
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= (1 << lun);
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
- "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun );
+ "command\n", H_NO(cmd), cmd->device->id, lun );
}
else {
- TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
+ TAG_ALLOC *ta = &TagAlloc[cmd->device->id][lun];
cmd->tag = find_first_zero_bit( &ta->allocated, MAX_TAGS );
set_bit( cmd->tag, &ta->allocated );
ta->nr_allocated++;
dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
"(now %d tags in use)\n",
- H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun,
+ H_NO(cmd), cmd->tag, cmd->device->id, lun,
ta->nr_allocated );
}
}
@@ -411,23 +413,24 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
static void cmd_free_tag(struct scsi_cmnd *cmd)
{
+ u8 lun = cmd->device->lun;
SETUP_HOSTDATA(cmd->device->host);
if (cmd->tag == TAG_NONE) {
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << lun);
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
- H_NO(cmd), cmd->device->id, cmd->device->lun );
+ H_NO(cmd), cmd->device->id, lun );
}
else if (cmd->tag >= MAX_TAGS) {
printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
H_NO(cmd), cmd->tag );
}
else {
- TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
+ TAG_ALLOC *ta = &TagAlloc[cmd->device->id][lun];
clear_bit( cmd->tag, &ta->allocated );
ta->nr_allocated--;
dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
- H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun );
+ H_NO(cmd), cmd->tag, cmd->device->id, lun );
}
}
@@ -659,7 +662,7 @@ static void lprint_Scsi_Cmnd(Scsi_Cmnd *cmd)
{
int i, s;
unsigned char *command;
- printk("scsi%d: destination target %d, lun %d\n",
+ printk("scsi%d: destination target %d, lun %llu\n",
H_NO(cmd), cmd->device->id, cmd->device->lun);
printk(KERN_CONT " command = ");
command = cmd->cmnd;
@@ -705,7 +708,7 @@ static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m)
{
int i, s;
unsigned char *command;
- seq_printf(m, "scsi%d: destination target %d, lun %d\n",
+ seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
H_NO(cmd), cmd->device->id, cmd->device->lun);
seq_printf(m, " command = ");
command = cmd->cmnd;
@@ -1007,7 +1010,7 @@ static void NCR5380_main (struct work_struct *bl)
prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) {
if (prev != tmp)
- dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
+ dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
/* When we find one, remove it from the issue queue. */
/* ++guenther: possible race with Falcon locking */
if (
@@ -1038,7 +1041,7 @@ static void NCR5380_main (struct work_struct *bl)
* issue queue so we can keep trying.
*/
dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
- "lun %d removed from issue_queue\n",
+ "lun %llu removed from issue_queue\n",
HOSTNO, tmp->device->id, tmp->device->lun);
/*
* REQUEST SENSE commands are issued without tagged
@@ -2020,7 +2023,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
* accesses to this device will use the
* polled-IO. */
printk(KERN_NOTICE "scsi%d: switching target %d "
- "lun %d to slow handshake\n", HOSTNO,
+ "lun %llu to slow handshake\n", HOSTNO,
cmd->device->id, cmd->device->lun);
cmd->device->borken = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
@@ -2078,7 +2081,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked command "
+ dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command "
"complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
/* Enable reselect interrupts */
@@ -2090,7 +2093,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
*/
if (!cmd->next_link) {
- printk(KERN_NOTICE "scsi%d: target %d lun %d "
+ printk(KERN_NOTICE "scsi%d: target %d lun %llu "
"linked command complete, no next_link\n",
HOSTNO, cmd->device->id, cmd->device->lun);
sink = 1;
@@ -2103,7 +2106,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
* and don't free it! */
cmd->next_link->tag = cmd->tag;
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked request "
+ dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request "
"done, calling scsi_done().\n",
HOSTNO, cmd->device->id, cmd->device->lun);
#ifdef NCR5380_STATS
@@ -2118,7 +2121,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
hostdata->connected = NULL;
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %d "
+ dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
#ifdef SUPPORT_TAGS
cmd_free_tag( cmd );
@@ -2132,7 +2135,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
/* ++Andreas: the mid level code knows about
QUEUE_FULL now. */
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d returned "
+ dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
"QUEUE_FULL after %d commands\n",
HOSTNO, cmd->device->id, cmd->device->lun,
ta->nr_allocated);
@@ -2228,7 +2231,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
cmd->device->tagged_supported = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
cmd->tag = TAG_NONE;
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d rejected "
+ dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
"QUEUE_TAG message; tagged queuing "
"disabled\n",
HOSTNO, cmd->device->id, cmd->device->lun);
@@ -2245,7 +2248,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
local_irq_restore(flags);
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %d was "
+ dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
"moved from connected to the "
"disconnected_queue\n", HOSTNO,
cmd->device->id, cmd->device->lun);
@@ -2349,12 +2352,12 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
printk("\n");
} else if (tmp != EXTENDED_MESSAGE)
printk(KERN_DEBUG "scsi%d: rejecting unknown "
- "message %02x from target %d, lun %d\n",
+ "message %02x from target %d, lun %llu\n",
HOSTNO, tmp, cmd->device->id, cmd->device->lun);
else
printk(KERN_DEBUG "scsi%d: rejecting unknown "
"extended message "
- "code %02x, length %d from target %d, lun %d\n",
+ "code %02x, length %d from target %d, lun %llu\n",
HOSTNO, extended_msg[1], extended_msg[0],
cmd->device->id, cmd->device->lun);
@@ -2576,7 +2579,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
#endif
hostdata->connected = tmp;
- dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
+ dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 6d3ee1ab6362..e59e6f96b725 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -851,7 +851,7 @@ static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
* so let's try to stop all on-going I/O.
*/
starget_printk(KERN_WARNING, tp->starget,
- "Removing busy LCB (%d)\n", sdev->lun);
+ "Removing busy LCB (%d)\n", (u8)sdev->lun);
sym_reset_scsi_bus(np, 1);
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 5a80cbac3f92..a141b1758033 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -581,7 +581,7 @@ struct sym_pmc {
#define sym_lp(tp, lun) (!lun) ? (tp)->lun0p : NULL
#else
#define sym_lp(tp, lun) \
- (!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[(lun)] : NULL
+ (!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[((u8)lun)] : NULL
#endif
/*
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index b006cf789ba1..764575726c85 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -621,7 +621,7 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr
{
dc390_freetag (pDCB, pSRB);
DEBUG0(printk ("DC390: Interrupt during Start SCSI (target %02i-%02i)\n",
- scmd->device->id, scmd->device->lun));
+ scmd->device->id, (u8)scmd->device->lun));
pSRB->SRBState = SRB_READY;
//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
pACB->SelLost++;
@@ -1726,7 +1726,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb*
} else {
SET_RES_DRV(pcmd->result, DRIVER_SENSE);
//pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8);
- DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+ DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, (u8)pcmd->device->lun));
pSRB->TotalXferredLen = 0;
SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
}
@@ -1746,7 +1746,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb*
else if (status == SAM_STAT_TASK_SET_FULL)
{
scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1);
- DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+ DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, (u8)pcmd->device->lun));
pSRB->TotalXferredLen = 0;
SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
}
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 5a03bb3bcfef..4e76fe863fc4 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1285,14 +1285,14 @@ static int u14_34f_queuecommand_lck(struct scsi_cmnd *SCpnt, void (*done)(struct
cpp->cpp_index = i;
SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
- if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d.\n",
+ if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%llu.\n",
BN(j), i, SCpnt->device->channel, SCpnt->device->id,
- SCpnt->device->lun);
+ (u8)SCpnt->device->lun);
cpp->opcode = OP_SCSI;
cpp->channel = SCpnt->device->channel;
cpp->target = SCpnt->device->id;
- cpp->lun = SCpnt->device->lun;
+ cpp->lun = (u8)SCpnt->device->lun;
cpp->SCpnt = SCpnt;
cpp->cdb_len = SCpnt->cmd_len;
memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
@@ -1663,10 +1663,10 @@ static int reorder(unsigned int j, unsigned long cursec,
if (link_statistics && (overlap || !(flushcount % link_statistics)))
for (n = 0; n < n_ready; n++) {
k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
- printk("%s %d.%d:%d mb %d fc %d nr %d sec %ld ns %u"\
+ printk("%s %d.%d:%llu mb %d fc %d nr %d sec %ld ns %u"\
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
- SCpnt->lun, k, flushcount, n_ready,
+ (u8)SCpnt->lun, k, flushcount, n_ready,
blk_rq_pos(SCpnt->request), blk_rq_sectors(SCpnt->request),
cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
YESNO(overlap), cpp->xdir);
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index f42d1cee652a..fafcf5e354c6 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -41,7 +41,8 @@
#define MAX_CDB_SIZE 16
#define GENERAL_UPIU_REQUEST_SIZE 32
-#define QUERY_DESC_MAX_SIZE 256
+#define QUERY_DESC_MAX_SIZE 255
+#define QUERY_DESC_MIN_SIZE 2
#define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \
(sizeof(struct utp_upiu_header)))
@@ -117,6 +118,41 @@ enum attr_idn {
QUERY_ATTR_IDN_EE_STATUS = 0x0E,
};
+/* Descriptor idn for Query requests */
+enum desc_idn {
+ QUERY_DESC_IDN_DEVICE = 0x0,
+ QUERY_DESC_IDN_CONFIGURAION = 0x1,
+ QUERY_DESC_IDN_UNIT = 0x2,
+ QUERY_DESC_IDN_RFU_0 = 0x3,
+ QUERY_DESC_IDN_INTERCONNECT = 0x4,
+ QUERY_DESC_IDN_STRING = 0x5,
+ QUERY_DESC_IDN_RFU_1 = 0x6,
+ QUERY_DESC_IDN_GEOMETRY = 0x7,
+ QUERY_DESC_IDN_POWER = 0x8,
+ QUERY_DESC_IDN_RFU_2 = 0x9,
+};
+
+#define UNIT_DESC_MAX_SIZE 0x22
+/* Unit descriptor parameters offsets in bytes*/
+enum unit_desc_param {
+ UNIT_DESC_PARAM_LEN = 0x0,
+ UNIT_DESC_PARAM_TYPE = 0x1,
+ UNIT_DESC_PARAM_UNIT_INDEX = 0x2,
+ UNIT_DESC_PARAM_LU_ENABLE = 0x3,
+ UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4,
+ UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5,
+ UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6,
+ UNIT_DESC_PARAM_MEM_TYPE = 0x8,
+ UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9,
+ UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA,
+ UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB,
+ UNIT_DESC_PARAM_ERASE_BLK_SIZE = 0x13,
+ UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17,
+ UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18,
+ UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20,
+ UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22,
+};
+
/* Exception event mask values */
enum {
MASK_EE_STATUS = 0xFFFF,
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
index 8b9531204c2b..c007a7a69c28 100644
--- a/drivers/scsi/ufs/ufshcd-pci.c
+++ b/drivers/scsi/ufs/ufshcd-pci.c
@@ -135,26 +135,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev)
}
/**
- * ufshcd_set_dma_mask - Set dma mask based on the controller
- * addressing capability
- * @pdev: PCI device structure
- *
- * Returns 0 for success, non-zero for failure
- */
-static int ufshcd_set_dma_mask(struct pci_dev *pdev)
-{
- int err;
-
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
- && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
- return 0;
- err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
- return err;
-}
-
-/**
* ufshcd_pci_probe - probe routine of the driver
* @pdev: pointer to PCI device handle
* @id: PCI device id
@@ -184,12 +164,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mmio_base = pcim_iomap_table(pdev)[0];
- err = ufshcd_set_dma_mask(pdev);
- if (err) {
- dev_err(&pdev->dev, "set dma mask failed\n");
- return err;
- }
-
err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
if (err) {
dev_err(&pdev->dev, "Initialization failed\n");
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 0c2877251251..ba27215b8034 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -110,6 +110,8 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba);
static void ufshcd_async_scan(void *data, async_cookie_t cookie);
static int ufshcd_reset_and_restore(struct ufs_hba *hba);
static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag);
+static int ufshcd_read_sdev_qdepth(struct ufs_hba *hba,
+ struct scsi_device *sdev);
/*
* ufshcd_wait_for_register - wait for register value to change
@@ -446,30 +448,35 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp)
* @lrb - pointer to local reference block
*/
static
-void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
{
struct ufs_query_res *query_res = &hba->dev_cmd.query.response;
- /* Get the UPIU response */
- query_res->response = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr) >>
- UPIU_RSP_CODE_OFFSET;
-
memcpy(&query_res->upiu_res, &lrbp->ucd_rsp_ptr->qr, QUERY_OSF_SIZE);
-
/* Get the descriptor */
if (lrbp->ucd_rsp_ptr->qr.opcode == UPIU_QUERY_OPCODE_READ_DESC) {
- u8 *descp = (u8 *)&lrbp->ucd_rsp_ptr +
+ u8 *descp = (u8 *)lrbp->ucd_rsp_ptr +
GENERAL_UPIU_REQUEST_SIZE;
- u16 len;
+ u16 resp_len;
+ u16 buf_len;
/* data segment length */
- len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) &
+ resp_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) &
MASK_QUERY_DATA_SEG_LEN;
-
- memcpy(hba->dev_cmd.query.descriptor, descp,
- min_t(u16, len, QUERY_DESC_MAX_SIZE));
+ buf_len = be16_to_cpu(
+ hba->dev_cmd.query.request.upiu_req.length);
+ if (likely(buf_len >= resp_len)) {
+ memcpy(hba->dev_cmd.query.descriptor, descp, resp_len);
+ } else {
+ dev_warn(hba->dev,
+ "%s: Response size is bigger than buffer",
+ __func__);
+ return -EINVAL;
+ }
}
+
+ return 0;
}
/**
@@ -797,11 +804,9 @@ static void ufshcd_prepare_utp_query_req_upiu(struct ufs_hba *hba,
QUERY_OSF_SIZE);
/* Copy the Descriptor */
- if ((len > 0) && (query->request.upiu_req.opcode ==
- UPIU_QUERY_OPCODE_WRITE_DESC)) {
- memcpy(descp, query->descriptor,
- min_t(u16, len, QUERY_DESC_MAX_SIZE));
- }
+ if (query->request.upiu_req.opcode == UPIU_QUERY_OPCODE_WRITE_DESC)
+ memcpy(descp, query->descriptor, len);
+
}
static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp)
@@ -980,6 +985,17 @@ ufshcd_clear_cmd(struct ufs_hba *hba, int tag)
return err;
}
+static int
+ufshcd_check_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
+{
+ struct ufs_query_res *query_res = &hba->dev_cmd.query.response;
+
+ /* Get the UPIU response */
+ query_res->response = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr) >>
+ UPIU_RSP_CODE_OFFSET;
+ return query_res->response;
+}
+
/**
* ufshcd_dev_cmd_completion() - handles device management command responses
* @hba: per adapter instance
@@ -1002,7 +1018,9 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
}
break;
case UPIU_TRANSACTION_QUERY_RSP:
- ufshcd_copy_query_response(hba, lrbp);
+ err = ufshcd_check_query_response(hba, lrbp);
+ if (!err)
+ err = ufshcd_copy_query_response(hba, lrbp);
break;
case UPIU_TRANSACTION_REJECT_UPIU:
/* TODO: handle Reject UPIU Response */
@@ -1134,6 +1152,30 @@ out_put_tag:
}
/**
+ * ufshcd_init_query() - init the query response and request parameters
+ * @hba: per-adapter instance
+ * @request: address of the request pointer to be initialized
+ * @response: address of the response pointer to be initialized
+ * @opcode: operation to perform
+ * @idn: flag idn to access
+ * @index: LU number to access
+ * @selector: query/flag/descriptor further identification
+ */
+static inline void ufshcd_init_query(struct ufs_hba *hba,
+ struct ufs_query_req **request, struct ufs_query_res **response,
+ enum query_opcode opcode, u8 idn, u8 index, u8 selector)
+{
+ *request = &hba->dev_cmd.query.request;
+ *response = &hba->dev_cmd.query.response;
+ memset(*request, 0, sizeof(struct ufs_query_req));
+ memset(*response, 0, sizeof(struct ufs_query_res));
+ (*request)->upiu_req.opcode = opcode;
+ (*request)->upiu_req.idn = idn;
+ (*request)->upiu_req.index = index;
+ (*request)->upiu_req.selector = selector;
+}
+
+/**
* ufshcd_query_flag() - API function for sending flag query requests
* hba: per-adapter instance
* query_opcode: flag query to perform
@@ -1145,17 +1187,15 @@ out_put_tag:
static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
enum flag_idn idn, bool *flag_res)
{
- struct ufs_query_req *request;
- struct ufs_query_res *response;
- int err;
+ struct ufs_query_req *request = NULL;
+ struct ufs_query_res *response = NULL;
+ int err, index = 0, selector = 0;
BUG_ON(!hba);
mutex_lock(&hba->dev_cmd.lock);
- request = &hba->dev_cmd.query.request;
- response = &hba->dev_cmd.query.response;
- memset(request, 0, sizeof(struct ufs_query_req));
- memset(response, 0, sizeof(struct ufs_query_res));
+ ufshcd_init_query(hba, &request, &response, opcode, idn, index,
+ selector);
switch (opcode) {
case UPIU_QUERY_OPCODE_SET_FLAG:
@@ -1180,12 +1220,8 @@ static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
err = -EINVAL;
goto out_unlock;
}
- request->upiu_req.opcode = opcode;
- request->upiu_req.idn = idn;
- /* Send query request */
- err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY,
- QUERY_REQ_TIMEOUT);
+ err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT);
if (err) {
dev_err(hba->dev,
@@ -1217,8 +1253,8 @@ out_unlock:
static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
{
- struct ufs_query_req *request;
- struct ufs_query_res *response;
+ struct ufs_query_req *request = NULL;
+ struct ufs_query_res *response = NULL;
int err;
BUG_ON(!hba);
@@ -1231,10 +1267,8 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
}
mutex_lock(&hba->dev_cmd.lock);
- request = &hba->dev_cmd.query.request;
- response = &hba->dev_cmd.query.response;
- memset(request, 0, sizeof(struct ufs_query_req));
- memset(response, 0, sizeof(struct ufs_query_res));
+ ufshcd_init_query(hba, &request, &response, opcode, idn, index,
+ selector);
switch (opcode) {
case UPIU_QUERY_OPCODE_WRITE_ATTR:
@@ -1251,14 +1285,7 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
goto out_unlock;
}
- request->upiu_req.opcode = opcode;
- request->upiu_req.idn = idn;
- request->upiu_req.index = index;
- request->upiu_req.selector = selector;
-
- /* Send query request */
- err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY,
- QUERY_REQ_TIMEOUT);
+ err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT);
if (err) {
dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, err = %d\n",
@@ -1275,6 +1302,82 @@ out:
}
/**
+ * ufshcd_query_descriptor - API function for sending descriptor requests
+ * hba: per-adapter instance
+ * opcode: attribute opcode
+ * idn: attribute idn to access
+ * index: index field
+ * selector: selector field
+ * desc_buf: the buffer that contains the descriptor
+ * buf_len: length parameter passed to the device
+ *
+ * Returns 0 for success, non-zero in case of failure.
+ * The buf_len parameter will contain, on return, the length parameter
+ * received on the response.
+ */
+static int ufshcd_query_descriptor(struct ufs_hba *hba,
+ enum query_opcode opcode, enum desc_idn idn, u8 index,
+ u8 selector, u8 *desc_buf, int *buf_len)
+{
+ struct ufs_query_req *request = NULL;
+ struct ufs_query_res *response = NULL;
+ int err;
+
+ BUG_ON(!hba);
+
+ if (!desc_buf) {
+ dev_err(hba->dev, "%s: descriptor buffer required for opcode 0x%x\n",
+ __func__, opcode);
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (*buf_len <= QUERY_DESC_MIN_SIZE || *buf_len > QUERY_DESC_MAX_SIZE) {
+ dev_err(hba->dev, "%s: descriptor buffer size (%d) is out of range\n",
+ __func__, *buf_len);
+ err = -EINVAL;
+ goto out;
+ }
+
+ mutex_lock(&hba->dev_cmd.lock);
+ ufshcd_init_query(hba, &request, &response, opcode, idn, index,
+ selector);
+ hba->dev_cmd.query.descriptor = desc_buf;
+ request->upiu_req.length = cpu_to_be16(*buf_len);
+
+ switch (opcode) {
+ case UPIU_QUERY_OPCODE_WRITE_DESC:
+ request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST;
+ break;
+ case UPIU_QUERY_OPCODE_READ_DESC:
+ request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
+ break;
+ default:
+ dev_err(hba->dev,
+ "%s: Expected query descriptor opcode but got = 0x%.2x\n",
+ __func__, opcode);
+ err = -EINVAL;
+ goto out_unlock;
+ }
+
+ err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, QUERY_REQ_TIMEOUT);
+
+ if (err) {
+ dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, err = %d\n",
+ __func__, opcode, idn, err);
+ goto out_unlock;
+ }
+
+ hba->dev_cmd.query.descriptor = NULL;
+ *buf_len = be16_to_cpu(response->upiu_res.length);
+
+out_unlock:
+ mutex_unlock(&hba->dev_cmd.lock);
+out:
+ return err;
+}
+
+/**
* ufshcd_memory_alloc - allocate memory for host memory space data structures
* @hba: per adapter instance
*
@@ -1878,6 +1981,7 @@ static int ufshcd_verify_dev_init(struct ufs_hba *hba)
static int ufshcd_slave_alloc(struct scsi_device *sdev)
{
struct ufs_hba *hba;
+ int lun_qdepth;
hba = shost_priv(sdev->host);
sdev->tagged_supported = 1;
@@ -1889,14 +1993,68 @@ static int ufshcd_slave_alloc(struct scsi_device *sdev)
/* allow SCSI layer to restart the device in case of errors */
sdev->allow_restart = 1;
- /*
- * Inform SCSI Midlayer that the LUN queue depth is same as the
- * controller queue depth. If a LUN queue depth is less than the
- * controller queue depth and if the LUN reports
- * SAM_STAT_TASK_SET_FULL, the LUN queue depth will be adjusted
- * with scsi_adjust_queue_depth.
- */
- scsi_activate_tcq(sdev, hba->nutrs);
+ /* REPORT SUPPORTED OPERATION CODES is not supported */
+ sdev->no_report_opcodes = 1;
+
+ lun_qdepth = ufshcd_read_sdev_qdepth(hba, sdev);
+ if (lun_qdepth <= 0)
+ /* eventually, we can figure out the real queue depth */
+ lun_qdepth = hba->nutrs;
+ else
+ lun_qdepth = min_t(int, lun_qdepth, hba->nutrs);
+
+ dev_dbg(hba->dev, "%s: activate tcq with queue depth %d\n",
+ __func__, lun_qdepth);
+ scsi_activate_tcq(sdev, lun_qdepth);
+
+ return 0;
+}
+
+/**
+ * ufshcd_change_queue_depth - change queue depth
+ * @sdev: pointer to SCSI device
+ * @depth: required depth to set
+ * @reason: reason for changing the depth
+ *
+ * Change queue depth according to the reason and make sure
+ * the max. limits are not crossed.
+ */
+static int ufshcd_change_queue_depth(struct scsi_device *sdev,
+ int depth, int reason)
+{
+ struct ufs_hba *hba = shost_priv(sdev->host);
+
+ if (depth > hba->nutrs)
+ depth = hba->nutrs;
+
+ switch (reason) {
+ case SCSI_QDEPTH_DEFAULT:
+ case SCSI_QDEPTH_RAMP_UP:
+ if (!sdev->tagged_supported)
+ depth = 1;
+ scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+ break;
+ case SCSI_QDEPTH_QFULL:
+ scsi_track_queue_full(sdev, depth);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return depth;
+}
+
+/**
+ * ufshcd_slave_configure - adjust SCSI device configurations
+ * @sdev: pointer to SCSI device
+ */
+static int ufshcd_slave_configure(struct scsi_device *sdev)
+{
+ struct request_queue *q = sdev->request_queue;
+
+ blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
+ blk_queue_max_segment_size(q, PRDT_DATA_BYTE_COUNT_MAX);
+
return 0;
}
@@ -1953,42 +2111,6 @@ static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index, u8 *resp)
}
/**
- * ufshcd_adjust_lun_qdepth - Update LUN queue depth if device responds with
- * SAM_STAT_TASK_SET_FULL SCSI command status.
- * @cmd: pointer to SCSI command
- */
-static void ufshcd_adjust_lun_qdepth(struct scsi_cmnd *cmd)
-{
- struct ufs_hba *hba;
- int i;
- int lun_qdepth = 0;
-
- hba = shost_priv(cmd->device->host);
-
- /*
- * LUN queue depth can be obtained by counting outstanding commands
- * on the LUN.
- */
- for (i = 0; i < hba->nutrs; i++) {
- if (test_bit(i, &hba->outstanding_reqs)) {
-
- /*
- * Check if the outstanding command belongs
- * to the LUN which reported SAM_STAT_TASK_SET_FULL.
- */
- if (cmd->device->lun == hba->lrb[i].lun)
- lun_qdepth++;
- }
- }
-
- /*
- * LUN queue depth will be total outstanding commands, except the
- * command for which the LUN reported SAM_STAT_TASK_SET_FULL.
- */
- scsi_adjust_queue_depth(cmd->device, MSG_SIMPLE_TAG, lun_qdepth - 1);
-}
-
-/**
* ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status
* @lrb: pointer to local reference block of completed command
* @scsi_status: SCSI command status
@@ -2009,12 +2131,6 @@ ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status)
scsi_status;
break;
case SAM_STAT_TASK_SET_FULL:
- /*
- * If a LUN reports SAM_STAT_TASK_SET_FULL, then the LUN queue
- * depth needs to be adjusted to the exact number of
- * outstanding commands the LUN can handle at any given time.
- */
- ufshcd_adjust_lun_qdepth(lrbp->cmd);
case SAM_STAT_BUSY:
case SAM_STAT_TASK_ABORTED:
ufshcd_copy_sense_data(lrbp);
@@ -2134,47 +2250,42 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
u32 tr_doorbell;
int result;
int index;
- bool int_aggr_reset = false;
+
+ /* Resetting interrupt aggregation counters first and reading the
+ * DOOR_BELL afterward allows us to handle all the completed requests.
+ * In order to prevent other interrupts starvation the DB is read once
+ * after reset. The down side of this solution is the possibility of
+ * false interrupt if device completes another request after resetting
+ * aggregation and before reading the DB.
+ */
+ ufshcd_reset_intr_aggr(hba);
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
completed_reqs = tr_doorbell ^ hba->outstanding_reqs;
- for (index = 0; index < hba->nutrs; index++) {
- if (test_bit(index, &completed_reqs)) {
- lrbp = &hba->lrb[index];
- cmd = lrbp->cmd;
- /*
- * Don't skip resetting interrupt aggregation counters
- * if a regular command is present.
- */
- int_aggr_reset |= !lrbp->intr_cmd;
-
- if (cmd) {
- result = ufshcd_transfer_rsp_status(hba, lrbp);
- scsi_dma_unmap(cmd);
- cmd->result = result;
- /* Mark completed command as NULL in LRB */
- lrbp->cmd = NULL;
- clear_bit_unlock(index, &hba->lrb_in_use);
- /* Do not touch lrbp after scsi done */
- cmd->scsi_done(cmd);
- } else if (lrbp->command_type ==
- UTP_CMD_TYPE_DEV_MANAGE) {
- if (hba->dev_cmd.complete)
- complete(hba->dev_cmd.complete);
- }
- } /* end of if */
- } /* end of for */
+ for_each_set_bit(index, &completed_reqs, hba->nutrs) {
+ lrbp = &hba->lrb[index];
+ cmd = lrbp->cmd;
+ if (cmd) {
+ result = ufshcd_transfer_rsp_status(hba, lrbp);
+ scsi_dma_unmap(cmd);
+ cmd->result = result;
+ /* Mark completed command as NULL in LRB */
+ lrbp->cmd = NULL;
+ clear_bit_unlock(index, &hba->lrb_in_use);
+ /* Do not touch lrbp after scsi done */
+ cmd->scsi_done(cmd);
+ } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE) {
+ if (hba->dev_cmd.complete)
+ complete(hba->dev_cmd.complete);
+ }
+ }
/* clear corresponding bits of completed commands */
hba->outstanding_reqs ^= completed_reqs;
/* we might have free'd some tags above */
wake_up(&hba->dev_cmd.tag_wq);
-
- /* Reset interrupt aggregation counters */
- if (int_aggr_reset)
- ufshcd_reset_intr_aggr(hba);
}
/**
@@ -2779,6 +2890,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
int poll_cnt;
u8 resp = 0xF;
struct ufshcd_lrb *lrbp;
+ u32 reg;
host = cmd->device->host;
hba = shost_priv(host);
@@ -2788,6 +2900,13 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
if (!(test_bit(tag, &hba->outstanding_reqs)))
goto out;
+ reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
+ if (!(reg & (1 << tag))) {
+ dev_err(hba->dev,
+ "%s: cmd was completed, but without a notifying intr, tag = %d",
+ __func__, tag);
+ }
+
lrbp = &hba->lrb[tag];
for (poll_cnt = 100; poll_cnt; poll_cnt--) {
err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
@@ -2796,8 +2915,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
/* cmd pending in the device */
break;
} else if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
- u32 reg;
-
/*
* cmd not pending in the device, check if it is
* in transition.
@@ -2971,6 +3088,38 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
}
/**
+ * ufshcd_read_sdev_qdepth - read the lun command queue depth
+ * @hba: Pointer to adapter instance
+ * @sdev: pointer to SCSI device
+ *
+ * Return in case of success the lun's queue depth else error.
+ */
+static int ufshcd_read_sdev_qdepth(struct ufs_hba *hba,
+ struct scsi_device *sdev)
+{
+ int ret;
+ int buff_len = UNIT_DESC_MAX_SIZE;
+ u8 desc_buf[UNIT_DESC_MAX_SIZE];
+
+ ret = ufshcd_query_descriptor(hba, UPIU_QUERY_OPCODE_READ_DESC,
+ QUERY_DESC_IDN_UNIT, sdev->lun, 0, desc_buf, &buff_len);
+
+ if (ret || (buff_len < UNIT_DESC_PARAM_LU_Q_DEPTH)) {
+ dev_err(hba->dev,
+ "%s:Failed reading unit descriptor. len = %d ret = %d"
+ , __func__, buff_len, ret);
+ if (!ret)
+ ret = -EINVAL;
+
+ goto out;
+ }
+
+ ret = desc_buf[UNIT_DESC_PARAM_LU_Q_DEPTH] & 0xFF;
+out:
+ return ret;
+}
+
+/**
* ufshcd_async_scan - asynchronous execution for link startup
* @data: data pointer to pass to this function
* @cookie: cookie data
@@ -3012,7 +3161,9 @@ static struct scsi_host_template ufshcd_driver_template = {
.proc_name = UFSHCD,
.queuecommand = ufshcd_queuecommand,
.slave_alloc = ufshcd_slave_alloc,
+ .slave_configure = ufshcd_slave_configure,
.slave_destroy = ufshcd_slave_destroy,
+ .change_queue_depth = ufshcd_change_queue_depth,
.eh_abort_handler = ufshcd_abort,
.eh_device_reset_handler = ufshcd_eh_device_reset_handler,
.eh_host_reset_handler = ufshcd_eh_host_reset_handler,
@@ -3110,6 +3261,22 @@ void ufshcd_remove(struct ufs_hba *hba)
EXPORT_SYMBOL_GPL(ufshcd_remove);
/**
+ * ufshcd_set_dma_mask - Set dma mask based on the controller
+ * addressing capability
+ * @hba: per adapter instance
+ *
+ * Returns 0 for success, non-zero for failure
+ */
+static int ufshcd_set_dma_mask(struct ufs_hba *hba)
+{
+ if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) {
+ if (!dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(64)))
+ return 0;
+ }
+ return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
+}
+
+/**
* ufshcd_init - Driver initialization routine
* @dev: pointer to device handle
* @hba_handle: driver private handle
@@ -3160,6 +3327,12 @@ int ufshcd_init(struct device *dev, struct ufs_hba **hba_handle,
/* Get Interrupt bit mask per version */
hba->intr_mask = ufshcd_get_intr_mask(hba);
+ err = ufshcd_set_dma_mask(hba);
+ if (err) {
+ dev_err(hba->dev, "set dma mask failed\n");
+ goto out_disable;
+ }
+
/* Allocate memory for host memory space */
err = ufshcd_memory_alloc(hba);
if (err) {
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index 9abc7e32b43d..e1b844bc9460 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -296,6 +296,11 @@ enum {
MASK_OCS = 0x0F,
};
+/* The maximum length of the data byte count field in the PRDT is 256KB */
+#define PRDT_DATA_BYTE_COUNT_MAX (256 * 1024)
+/* The granularity of the data byte count field in the PRDT is 32-bit */
+#define PRDT_DATA_BYTE_COUNT_PAD 4
+
/**
* struct ufshcd_sg_entry - UFSHCI PRD Entry
* @base_addr: Lower 32bit physical address DW-0
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 89ee5929eb6d..eee1bc0b506e 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -27,6 +27,8 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include <linux/seqlock.h>
#define VIRTIO_SCSI_MEMPOOL_SZ 64
#define VIRTIO_SCSI_EVENT_LEN 8
@@ -75,18 +77,16 @@ struct virtio_scsi_vq {
* queue, and also lets the driver optimize the IRQ affinity for the virtqueues
* (each virtqueue's affinity is set to the CPU that "owns" the queue).
*
- * tgt_lock is held to serialize reading and writing req_vq. Reading req_vq
- * could be done locklessly, but we do not do it yet.
+ * tgt_seq is held to serialize reading and writing req_vq.
*
* Decrements of reqs are never concurrent with writes of req_vq: before the
* decrement reqs will be != 0; after the decrement the virtqueue completion
* routine will not use the req_vq so it can be changed by a new request.
- * Thus they can happen outside the tgt_lock, provided of course we make reqs
+ * Thus they can happen outside the tgt_seq, provided of course we make reqs
* an atomic_t.
*/
struct virtio_scsi_target_state {
- /* This spinlock never held at the same time as vq_lock. */
- spinlock_t tgt_lock;
+ seqcount_t tgt_seq;
/* Count of outstanding requests. */
atomic_t reqs;
@@ -237,6 +237,16 @@ static void virtscsi_req_done(struct virtqueue *vq)
virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd);
};
+static void virtscsi_poll_requests(struct virtio_scsi *vscsi)
+{
+ int i, num_vqs;
+
+ num_vqs = vscsi->num_queues;
+ for (i = 0; i < num_vqs; i++)
+ virtscsi_vq_done(vscsi, &vscsi->req_vqs[i],
+ virtscsi_complete_cmd);
+}
+
static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf)
{
struct virtio_scsi_cmd *cmd = buf;
@@ -253,6 +263,8 @@ static void virtscsi_ctrl_done(struct virtqueue *vq)
virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free);
};
+static void virtscsi_handle_event(struct work_struct *work);
+
static int virtscsi_kick_event(struct virtio_scsi *vscsi,
struct virtio_scsi_event_node *event_node)
{
@@ -260,6 +272,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi,
struct scatterlist sg;
unsigned long flags;
+ INIT_WORK(&event_node->work, virtscsi_handle_event);
sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event));
spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags);
@@ -377,7 +390,6 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf)
{
struct virtio_scsi_event_node *event_node = buf;
- INIT_WORK(&event_node->work, virtscsi_handle_event);
schedule_work(&event_node->work);
}
@@ -547,19 +559,33 @@ static struct virtio_scsi_vq *virtscsi_pick_vq(struct virtio_scsi *vscsi,
unsigned long flags;
u32 queue_num;
- spin_lock_irqsave(&tgt->tgt_lock, flags);
+ local_irq_save(flags);
+ if (atomic_inc_return(&tgt->reqs) > 1) {
+ unsigned long seq;
+
+ do {
+ seq = read_seqcount_begin(&tgt->tgt_seq);
+ vq = tgt->req_vq;
+ } while (read_seqcount_retry(&tgt->tgt_seq, seq));
+ } else {
+ /* no writes can be concurrent because of atomic_t */
+ write_seqcount_begin(&tgt->tgt_seq);
+
+ /* keep previous req_vq if a reader just arrived */
+ if (unlikely(atomic_read(&tgt->reqs) > 1)) {
+ vq = tgt->req_vq;
+ goto unlock;
+ }
- if (atomic_inc_return(&tgt->reqs) > 1)
- vq = tgt->req_vq;
- else {
queue_num = smp_processor_id();
while (unlikely(queue_num >= vscsi->num_queues))
queue_num -= vscsi->num_queues;
-
tgt->req_vq = vq = &vscsi->req_vqs[queue_num];
+ unlock:
+ write_seqcount_end(&tgt->tgt_seq);
}
+ local_irq_restore(flags);
- spin_unlock_irqrestore(&tgt->tgt_lock, flags);
return vq;
}
@@ -589,6 +615,18 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED)
ret = SUCCESS;
+ /*
+ * The spec guarantees that all requests related to the TMF have
+ * been completed, but the callback might not have run yet if
+ * we're using independent interrupts (e.g. MSI). Poll the
+ * virtqueues once.
+ *
+ * In the abort case, sc->scsi_done will do nothing, because
+ * the block layer must have detected a timeout and as a result
+ * REQ_ATOM_COMPLETE has been set.
+ */
+ virtscsi_poll_requests(vscsi);
+
out:
mempool_free(cmd, virtscsi_cmd_pool);
return ret;
@@ -617,6 +655,36 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc)
return virtscsi_tmf(vscsi, cmd);
}
+/**
+ * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth
+ * @sdev: Virtscsi target whose queue depth to change
+ * @qdepth: New queue depth
+ * @reason: Reason for the queue depth change.
+ */
+static int virtscsi_change_queue_depth(struct scsi_device *sdev,
+ int qdepth,
+ int reason)
+{
+ struct Scsi_Host *shost = sdev->host;
+ int max_depth = shost->cmd_per_lun;
+
+ switch (reason) {
+ case SCSI_QDEPTH_QFULL: /* Drop qdepth in response to BUSY state */
+ scsi_track_queue_full(sdev, qdepth);
+ break;
+ case SCSI_QDEPTH_RAMP_UP: /* Raise qdepth after BUSY state resolved */
+ case SCSI_QDEPTH_DEFAULT: /* Manual change via sysfs */
+ scsi_adjust_queue_depth(sdev,
+ scsi_get_tag_type(sdev),
+ min(max_depth, qdepth));
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return sdev->queue_depth;
+}
+
static int virtscsi_abort(struct scsi_cmnd *sc)
{
struct virtio_scsi *vscsi = shost_priv(sc->device->host);
@@ -643,14 +711,17 @@ static int virtscsi_abort(struct scsi_cmnd *sc)
static int virtscsi_target_alloc(struct scsi_target *starget)
{
+ struct Scsi_Host *sh = dev_to_shost(starget->dev.parent);
+ struct virtio_scsi *vscsi = shost_priv(sh);
+
struct virtio_scsi_target_state *tgt =
kmalloc(sizeof(*tgt), GFP_KERNEL);
if (!tgt)
return -ENOMEM;
- spin_lock_init(&tgt->tgt_lock);
+ seqcount_init(&tgt->tgt_seq);
atomic_set(&tgt->reqs, 0);
- tgt->req_vq = NULL;
+ tgt->req_vq = &vscsi->req_vqs[0];
starget->hostdata = tgt;
return 0;
@@ -669,6 +740,7 @@ static struct scsi_host_template virtscsi_host_template_single = {
.this_id = -1,
.cmd_size = sizeof(struct virtio_scsi_cmd),
.queuecommand = virtscsi_queuecommand_single,
+ .change_queue_depth = virtscsi_change_queue_depth,
.eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset,
@@ -686,6 +758,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
.this_id = -1,
.cmd_size = sizeof(struct virtio_scsi_cmd),
.queuecommand = virtscsi_queuecommand_multi,
+ .change_queue_depth = virtscsi_change_queue_depth,
.eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset,
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index c88e1468aad7..598f65efaaec 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -1194,7 +1194,7 @@ static int pvscsi_setup_msix(const struct pvscsi_adapter *adapter,
struct msix_entry entry = { 0, PVSCSI_VECTOR_COMPLETION };
int ret;
- ret = pci_enable_msix(adapter->dev, &entry, 1);
+ ret = pci_enable_msix_exact(adapter->dev, &entry, 1);
if (ret)
return ret;
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 41883a87931d..c0506de4f3b6 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -502,7 +502,8 @@ wd33c93_execute(struct Scsi_Host *instance)
cmd = (struct scsi_cmnd *) hostdata->input_Q;
prev = NULL;
while (cmd) {
- if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)))
+ if (!(hostdata->busy[cmd->device->id] &
+ (1 << (cmd->device->lun & 0xff))))
break;
prev = cmd;
cmd = (struct scsi_cmnd *) cmd->host_scribble;
@@ -593,10 +594,10 @@ wd33c93_execute(struct Scsi_Host *instance)
write_wd33c93(regs, WD_SOURCE_ID, ((cmd->SCp.phase) ? SRCID_ER : 0));
- write_wd33c93(regs, WD_TARGET_LUN, cmd->device->lun);
+ write_wd33c93(regs, WD_TARGET_LUN, (u8)cmd->device->lun);
write_wd33c93(regs, WD_SYNCHRONOUS_TRANSFER,
hostdata->sync_xfer[cmd->device->id]);
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
if ((hostdata->level2 == L2_NONE) ||
(hostdata->sync_stat[cmd->device->id] == SS_UNSET)) {
@@ -862,7 +863,7 @@ wd33c93_intr(struct Scsi_Host *instance)
}
cmd->result = DID_NO_CONNECT << 16;
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED;
cmd->scsi_done(cmd);
@@ -895,7 +896,7 @@ wd33c93_intr(struct Scsi_Host *instance)
/* construct an IDENTIFY message with correct disconnect bit */
- hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->device->lun);
+ hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun);
if (cmd->SCp.phase)
hostdata->outgoing_msg[0] |= 0x40;
@@ -1179,7 +1180,7 @@ wd33c93_intr(struct Scsi_Host *instance)
lun = read_wd33c93(regs, WD_TARGET_LUN);
DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
hostdata->connected = NULL;
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED;
if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
cmd->SCp.Status = lun;
@@ -1268,7 +1269,7 @@ wd33c93_intr(struct Scsi_Host *instance)
}
DB(DB_INTR, printk("UNEXP_DISC"))
hostdata->connected = NULL;
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED;
if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD)
cmd->result =
@@ -1300,7 +1301,7 @@ wd33c93_intr(struct Scsi_Host *instance)
switch (hostdata->state) {
case S_PRE_CMP_DISC:
hostdata->connected = NULL;
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED;
DB(DB_INTR, printk(":%d", cmd->SCp.Status))
if (cmd->cmnd[0] == REQUEST_SENSE
@@ -1353,7 +1354,7 @@ wd33c93_intr(struct Scsi_Host *instance)
if (hostdata->selecting) {
cmd = (struct scsi_cmnd *) hostdata->selecting;
hostdata->selecting = NULL;
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
cmd->host_scribble =
(uchar *) hostdata->input_Q;
hostdata->input_Q = cmd;
@@ -1365,7 +1366,7 @@ wd33c93_intr(struct Scsi_Host *instance)
if (cmd) {
if (phs == 0x00) {
hostdata->busy[cmd->device->id] &=
- ~(1 << cmd->device->lun);
+ ~(1 << (cmd->device->lun & 0xff));
cmd->host_scribble =
(uchar *) hostdata->input_Q;
hostdata->input_Q = cmd;
@@ -1448,7 +1449,7 @@ wd33c93_intr(struct Scsi_Host *instance)
cmd = (struct scsi_cmnd *) hostdata->disconnected_Q;
patch = NULL;
while (cmd) {
- if (id == cmd->device->id && lun == cmd->device->lun)
+ if (id == cmd->device->id && lun == (u8)cmd->device->lun)
break;
patch = cmd;
cmd = (struct scsi_cmnd *) cmd->host_scribble;
@@ -1459,7 +1460,7 @@ wd33c93_intr(struct Scsi_Host *instance)
if (!cmd) {
printk
("---TROUBLE: target %d.%d not in disconnect queue---",
- id, lun);
+ id, (u8)lun);
spin_unlock_irqrestore(&hostdata->lock, flags);
return;
}
@@ -1705,7 +1706,7 @@ wd33c93_abort(struct scsi_cmnd * cmd)
sr = read_wd33c93(regs, WD_SCSI_STATUS);
printk("asr=%02x, sr=%02x.", asr, sr);
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->connected = NULL;
hostdata->state = S_UNCONNECTED;
cmd->result = DID_ABORT << 16;
@@ -2169,7 +2170,7 @@ wd33c93_show_info(struct seq_file *m, struct Scsi_Host *instance)
seq_printf(m, "\nconnected: ");
if (hd->connected) {
cmd = (struct scsi_cmnd *) hd->connected;
- seq_printf(m, " %d:%d(%02x)",
+ seq_printf(m, " %d:%llu(%02x)",
cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
}
}
@@ -2177,7 +2178,7 @@ wd33c93_show_info(struct seq_file *m, struct Scsi_Host *instance)
seq_printf(m, "\ninput_Q: ");
cmd = (struct scsi_cmnd *) hd->input_Q;
while (cmd) {
- seq_printf(m, " %d:%d(%02x)",
+ seq_printf(m, " %d:%llu(%02x)",
cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
cmd = (struct scsi_cmnd *) cmd->host_scribble;
}
@@ -2186,7 +2187,7 @@ wd33c93_show_info(struct seq_file *m, struct Scsi_Host *instance)
seq_printf(m, "\ndisconnected_Q:");
cmd = (struct scsi_cmnd *) hd->disconnected_Q;
while (cmd) {
- seq_printf(m, " %d:%d(%02x)",
+ seq_printf(m, " %d:%llu(%02x)",
cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
cmd = (struct scsi_cmnd *) cmd->host_scribble;
}
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 0f7c44793b29..3b1b95d932d1 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_ARCH_QCOM) += qcom/
+obj-$(CONFIG_ARCH_TEGRA) += tegra/
diff --git a/drivers/soc/tegra/Makefile b/drivers/soc/tegra/Makefile
new file mode 100644
index 000000000000..cdaad9d53a05
--- /dev/null
+++ b/drivers/soc/tegra/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_ARCH_TEGRA) += fuse/
+
+obj-$(CONFIG_ARCH_TEGRA) += common.o
+obj-$(CONFIG_ARCH_TEGRA) += pmc.o
diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
new file mode 100644
index 000000000000..a71cb74f3674
--- /dev/null
+++ b/drivers/soc/tegra/common.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 NVIDIA 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/of.h>
+
+#include <soc/tegra/common.h>
+
+static const struct of_device_id tegra_machine_match[] = {
+ { .compatible = "nvidia,tegra20", },
+ { .compatible = "nvidia,tegra30", },
+ { .compatible = "nvidia,tegra114", },
+ { .compatible = "nvidia,tegra124", },
+ { }
+};
+
+bool soc_is_tegra(void)
+{
+ struct device_node *root;
+
+ root = of_find_node_by_path("/");
+ if (!root)
+ return false;
+
+ return of_match_node(tegra_machine_match, root) != NULL;
+}
diff --git a/drivers/soc/tegra/fuse/Makefile b/drivers/soc/tegra/fuse/Makefile
new file mode 100644
index 000000000000..3af357da91f3
--- /dev/null
+++ b/drivers/soc/tegra/fuse/Makefile
@@ -0,0 +1,8 @@
+obj-y += fuse-tegra.o
+obj-y += fuse-tegra30.o
+obj-y += tegra-apbmisc.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += fuse-tegra20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += speedo-tegra20.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += speedo-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC) += speedo-tegra114.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC) += speedo-tegra124.o
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
new file mode 100644
index 000000000000..11a5043959dc
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA 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 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/device.h>
+#include <linux/kobject.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include <soc/tegra/common.h>
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+static u32 (*fuse_readl)(const unsigned int offset);
+static int fuse_size;
+struct tegra_sku_info tegra_sku_info;
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+ [TEGRA_REVISION_UNKNOWN] = "unknown",
+ [TEGRA_REVISION_A01] = "A01",
+ [TEGRA_REVISION_A02] = "A02",
+ [TEGRA_REVISION_A03] = "A03",
+ [TEGRA_REVISION_A03p] = "A03 prime",
+ [TEGRA_REVISION_A04] = "A04",
+};
+
+static u8 fuse_readb(const unsigned int offset)
+{
+ u32 val;
+
+ val = fuse_readl(round_down(offset, 4));
+ val >>= (offset % 4) * 8;
+ val &= 0xff;
+
+ return val;
+}
+
+static ssize_t fuse_read(struct file *fd, struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t pos, size_t size)
+{
+ int i;
+
+ if (pos < 0 || pos >= fuse_size)
+ return 0;
+
+ if (size > fuse_size - pos)
+ size = fuse_size - pos;
+
+ for (i = 0; i < size; i++)
+ buf[i] = fuse_readb(pos + i);
+
+ return i;
+}
+
+static struct bin_attribute fuse_bin_attr = {
+ .attr = { .name = "fuse", .mode = S_IRUGO, },
+ .read = fuse_read,
+};
+
+static const struct of_device_id car_match[] __initconst = {
+ { .compatible = "nvidia,tegra20-car", },
+ { .compatible = "nvidia,tegra30-car", },
+ { .compatible = "nvidia,tegra114-car", },
+ { .compatible = "nvidia,tegra124-car", },
+ {},
+};
+
+static void tegra_enable_fuse_clk(void __iomem *base)
+{
+ u32 reg;
+
+ reg = readl_relaxed(base + 0x48);
+ reg |= 1 << 28;
+ writel(reg, base + 0x48);
+
+ /*
+ * Enable FUSE clock. This needs to be hardcoded because the clock
+ * subsystem is not active during early boot.
+ */
+ reg = readl(base + 0x14);
+ reg |= 1 << 7;
+ writel(reg, base + 0x14);
+}
+
+int tegra_fuse_readl(unsigned long offset, u32 *value)
+{
+ if (!fuse_readl)
+ return -EPROBE_DEFER;
+
+ *value = fuse_readl(offset);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_fuse_readl);
+
+int tegra_fuse_create_sysfs(struct device *dev, int size,
+ u32 (*readl)(const unsigned int offset))
+{
+ if (fuse_size)
+ return -ENODEV;
+
+ fuse_bin_attr.size = size;
+ fuse_bin_attr.read = fuse_read;
+
+ fuse_size = size;
+ fuse_readl = readl;
+
+ return device_create_bin_file(dev, &fuse_bin_attr);
+}
+
+static int __init tegra_init_fuse(void)
+{
+ struct device_node *np;
+ void __iomem *car_base;
+
+ if (!soc_is_tegra())
+ return 0;
+
+ tegra_init_apbmisc();
+
+ np = of_find_matching_node(NULL, car_match);
+ car_base = of_iomap(np, 0);
+ if (car_base) {
+ tegra_enable_fuse_clk(car_base);
+ iounmap(car_base);
+ } else {
+ pr_err("Could not enable fuse clk. ioremap tegra car failed.\n");
+ return -ENXIO;
+ }
+
+ if (tegra_get_chip_id() == TEGRA20)
+ tegra20_init_fuse_early();
+ else
+ tegra30_init_fuse_early();
+
+ pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_revision_name[tegra_sku_info.revision],
+ tegra_sku_info.sku_id, tegra_sku_info.cpu_process_id,
+ tegra_sku_info.core_process_id);
+ pr_debug("Tegra CPU Speedo ID %d, Soc Speedo ID %d\n",
+ tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
+
+ return 0;
+}
+early_initcall(tegra_init_fuse);
diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c
new file mode 100644
index 000000000000..7cb63ab6aac2
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra20.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA 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 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/>.
+ *
+ * Based on drivers/misc/eeprom/sunxi_sid.c
+ */
+
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/kobject.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define FUSE_BEGIN 0x100
+#define FUSE_SIZE 0x1f8
+#define FUSE_UID_LOW 0x08
+#define FUSE_UID_HIGH 0x0c
+
+static phys_addr_t fuse_phys;
+static struct clk *fuse_clk;
+static void __iomem __initdata *fuse_base;
+
+static DEFINE_MUTEX(apb_dma_lock);
+static DECLARE_COMPLETION(apb_dma_wait);
+static struct dma_chan *apb_dma_chan;
+static struct dma_slave_config dma_sconfig;
+static u32 *apb_buffer;
+static dma_addr_t apb_buffer_phys;
+
+static void apb_dma_complete(void *args)
+{
+ complete(&apb_dma_wait);
+}
+
+static u32 tegra20_fuse_readl(const unsigned int offset)
+{
+ int ret;
+ u32 val = 0;
+ struct dma_async_tx_descriptor *dma_desc;
+
+ mutex_lock(&apb_dma_lock);
+
+ dma_sconfig.src_addr = fuse_phys + FUSE_BEGIN + offset;
+ ret = dmaengine_slave_config(apb_dma_chan, &dma_sconfig);
+ if (ret)
+ goto out;
+
+ dma_desc = dmaengine_prep_slave_single(apb_dma_chan, apb_buffer_phys,
+ sizeof(u32), DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!dma_desc)
+ goto out;
+
+ dma_desc->callback = apb_dma_complete;
+ dma_desc->callback_param = NULL;
+
+ reinit_completion(&apb_dma_wait);
+
+ clk_prepare_enable(fuse_clk);
+
+ dmaengine_submit(dma_desc);
+ dma_async_issue_pending(apb_dma_chan);
+ ret = wait_for_completion_timeout(&apb_dma_wait, msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb read dma timed out"))
+ dmaengine_terminate_all(apb_dma_chan);
+ else
+ val = *apb_buffer;
+
+ clk_disable_unprepare(fuse_clk);
+out:
+ mutex_unlock(&apb_dma_lock);
+
+ return val;
+}
+
+static const struct of_device_id tegra20_fuse_of_match[] = {
+ { .compatible = "nvidia,tegra20-efuse" },
+ {},
+};
+
+static int apb_dma_init(void)
+{
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ apb_dma_chan = dma_request_channel(mask, NULL, NULL);
+ if (!apb_dma_chan)
+ return -EPROBE_DEFER;
+
+ apb_buffer = dma_alloc_coherent(NULL, sizeof(u32), &apb_buffer_phys,
+ GFP_KERNEL);
+ if (!apb_buffer) {
+ dma_release_channel(apb_dma_chan);
+ return -ENOMEM;
+ }
+
+ dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_sconfig.src_maxburst = 1;
+ dma_sconfig.dst_maxburst = 1;
+
+ return 0;
+}
+
+static int tegra20_fuse_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int err;
+
+ fuse_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fuse_clk)) {
+ dev_err(&pdev->dev, "missing clock");
+ return PTR_ERR(fuse_clk);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+ fuse_phys = res->start;
+
+ err = apb_dma_init();
+ if (err)
+ return err;
+
+ if (tegra_fuse_create_sysfs(&pdev->dev, FUSE_SIZE, tegra20_fuse_readl))
+ return -ENODEV;
+
+ dev_dbg(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static struct platform_driver tegra20_fuse_driver = {
+ .probe = tegra20_fuse_probe,
+ .driver = {
+ .name = "tegra20_fuse",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra20_fuse_of_match,
+ }
+};
+
+static int __init tegra20_fuse_init(void)
+{
+ return platform_driver_register(&tegra20_fuse_driver);
+}
+postcore_initcall(tegra20_fuse_init);
+
+/* Early boot code. This code is called before the devices are created */
+
+u32 __init tegra20_fuse_early(const unsigned int offset)
+{
+ return readl_relaxed(fuse_base + FUSE_BEGIN + offset);
+}
+
+bool __init tegra20_spare_fuse_early(int spare_bit)
+{
+ u32 offset = spare_bit * 4;
+ bool value;
+
+ value = tegra20_fuse_early(offset + 0x100);
+
+ return value;
+}
+
+static void __init tegra20_fuse_add_randomness(void)
+{
+ u32 randomness[7];
+
+ randomness[0] = tegra_sku_info.sku_id;
+ randomness[1] = tegra_read_straps();
+ randomness[2] = tegra_read_chipid();
+ randomness[3] = tegra_sku_info.cpu_process_id << 16;
+ randomness[3] |= tegra_sku_info.core_process_id;
+ randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
+ randomness[4] |= tegra_sku_info.soc_speedo_id;
+ randomness[5] = tegra20_fuse_early(FUSE_UID_LOW);
+ randomness[6] = tegra20_fuse_early(FUSE_UID_HIGH);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+void __init tegra20_init_fuse_early(void)
+{
+ fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);
+
+ tegra_init_revision();
+ tegra20_init_speedo_data(&tegra_sku_info);
+ tegra20_fuse_add_randomness();
+
+ iounmap(fuse_base);
+}
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c
new file mode 100644
index 000000000000..5999cf34ab70
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA 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 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/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define FUSE_BEGIN 0x100
+
+/* Tegra30 and later */
+#define FUSE_VENDOR_CODE 0x100
+#define FUSE_FAB_CODE 0x104
+#define FUSE_LOT_CODE_0 0x108
+#define FUSE_LOT_CODE_1 0x10c
+#define FUSE_WAFER_ID 0x110
+#define FUSE_X_COORDINATE 0x114
+#define FUSE_Y_COORDINATE 0x118
+
+#define FUSE_HAS_REVISION_INFO BIT(0)
+
+enum speedo_idx {
+ SPEEDO_TEGRA30 = 0,
+ SPEEDO_TEGRA114,
+ SPEEDO_TEGRA124,
+};
+
+struct tegra_fuse_info {
+ int size;
+ int spare_bit;
+ enum speedo_idx speedo_idx;
+};
+
+static void __iomem *fuse_base;
+static struct clk *fuse_clk;
+static struct tegra_fuse_info *fuse_info;
+
+u32 tegra30_fuse_readl(const unsigned int offset)
+{
+ u32 val;
+
+ /*
+ * early in the boot, the fuse clock will be enabled by
+ * tegra_init_fuse()
+ */
+
+ if (fuse_clk)
+ clk_prepare_enable(fuse_clk);
+
+ val = readl_relaxed(fuse_base + FUSE_BEGIN + offset);
+
+ if (fuse_clk)
+ clk_disable_unprepare(fuse_clk);
+
+ return val;
+}
+
+static struct tegra_fuse_info tegra30_info = {
+ .size = 0x2a4,
+ .spare_bit = 0x144,
+ .speedo_idx = SPEEDO_TEGRA30,
+};
+
+static struct tegra_fuse_info tegra114_info = {
+ .size = 0x2a0,
+ .speedo_idx = SPEEDO_TEGRA114,
+};
+
+static struct tegra_fuse_info tegra124_info = {
+ .size = 0x300,
+ .speedo_idx = SPEEDO_TEGRA124,
+};
+
+static const struct of_device_id tegra30_fuse_of_match[] = {
+ { .compatible = "nvidia,tegra30-efuse", .data = &tegra30_info },
+ { .compatible = "nvidia,tegra114-efuse", .data = &tegra114_info },
+ { .compatible = "nvidia,tegra124-efuse", .data = &tegra124_info },
+ {},
+};
+
+static int tegra30_fuse_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_dev_id;
+
+ of_dev_id = of_match_device(tegra30_fuse_of_match, &pdev->dev);
+ if (!of_dev_id)
+ return -ENODEV;
+
+ fuse_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(fuse_clk)) {
+ dev_err(&pdev->dev, "missing clock");
+ return PTR_ERR(fuse_clk);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (tegra_fuse_create_sysfs(&pdev->dev, fuse_info->size,
+ tegra30_fuse_readl))
+ return -ENODEV;
+
+ dev_dbg(&pdev->dev, "loaded\n");
+
+ return 0;
+}
+
+static struct platform_driver tegra30_fuse_driver = {
+ .probe = tegra30_fuse_probe,
+ .driver = {
+ .name = "tegra_fuse",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra30_fuse_of_match,
+ }
+};
+
+static int __init tegra30_fuse_init(void)
+{
+ return platform_driver_register(&tegra30_fuse_driver);
+}
+postcore_initcall(tegra30_fuse_init);
+
+/* Early boot code. This code is called before the devices are created */
+
+typedef void (*speedo_f)(struct tegra_sku_info *sku_info);
+
+static speedo_f __initdata speedo_tbl[] = {
+ [SPEEDO_TEGRA30] = tegra30_init_speedo_data,
+ [SPEEDO_TEGRA114] = tegra114_init_speedo_data,
+ [SPEEDO_TEGRA124] = tegra124_init_speedo_data,
+};
+
+static void __init tegra30_fuse_add_randomness(void)
+{
+ u32 randomness[12];
+
+ randomness[0] = tegra_sku_info.sku_id;
+ randomness[1] = tegra_read_straps();
+ randomness[2] = tegra_read_chipid();
+ randomness[3] = tegra_sku_info.cpu_process_id << 16;
+ randomness[3] |= tegra_sku_info.core_process_id;
+ randomness[4] = tegra_sku_info.cpu_speedo_id << 16;
+ randomness[4] |= tegra_sku_info.soc_speedo_id;
+ randomness[5] = tegra30_fuse_readl(FUSE_VENDOR_CODE);
+ randomness[6] = tegra30_fuse_readl(FUSE_FAB_CODE);
+ randomness[7] = tegra30_fuse_readl(FUSE_LOT_CODE_0);
+ randomness[8] = tegra30_fuse_readl(FUSE_LOT_CODE_1);
+ randomness[9] = tegra30_fuse_readl(FUSE_WAFER_ID);
+ randomness[10] = tegra30_fuse_readl(FUSE_X_COORDINATE);
+ randomness[11] = tegra30_fuse_readl(FUSE_Y_COORDINATE);
+
+ add_device_randomness(randomness, sizeof(randomness));
+}
+
+static void __init legacy_fuse_init(void)
+{
+ switch (tegra_get_chip_id()) {
+ case TEGRA30:
+ fuse_info = &tegra30_info;
+ break;
+ case TEGRA114:
+ fuse_info = &tegra114_info;
+ break;
+ case TEGRA124:
+ fuse_info = &tegra124_info;
+ break;
+ default:
+ return;
+ }
+
+ fuse_base = ioremap(TEGRA_FUSE_BASE, TEGRA_FUSE_SIZE);
+}
+
+bool __init tegra30_spare_fuse(int spare_bit)
+{
+ u32 offset = fuse_info->spare_bit + spare_bit * 4;
+
+ return tegra30_fuse_readl(offset) & 1;
+}
+
+void __init tegra30_init_fuse_early(void)
+{
+ struct device_node *np;
+ const struct of_device_id *of_match;
+
+ np = of_find_matching_node_and_match(NULL, tegra30_fuse_of_match,
+ &of_match);
+ if (np) {
+ fuse_base = of_iomap(np, 0);
+ fuse_info = (struct tegra_fuse_info *)of_match->data;
+ } else
+ legacy_fuse_init();
+
+ if (!fuse_base) {
+ pr_warn("fuse DT node missing and unknown chip id: 0x%02x\n",
+ tegra_get_chip_id());
+ return;
+ }
+
+ tegra_init_revision();
+ speedo_tbl[fuse_info->speedo_idx](&tegra_sku_info);
+ tegra30_fuse_add_randomness();
+}
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
new file mode 100644
index 000000000000..3a398bf3572c
--- /dev/null
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_MISC_TEGRA_FUSE_H
+#define __DRIVERS_MISC_TEGRA_FUSE_H
+
+#define TEGRA_FUSE_BASE 0x7000f800
+#define TEGRA_FUSE_SIZE 0x400
+
+int tegra_fuse_create_sysfs(struct device *dev, int size,
+ u32 (*readl)(const unsigned int offset));
+
+bool tegra30_spare_fuse(int bit);
+u32 tegra30_fuse_readl(const unsigned int offset);
+void tegra30_init_fuse_early(void);
+void tegra_init_revision(void);
+void tegra_init_apbmisc(void);
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra20_init_speedo_data(struct tegra_sku_info *sku_info);
+bool tegra20_spare_fuse_early(int spare_bit);
+void tegra20_init_fuse_early(void);
+u32 tegra20_fuse_early(const unsigned int offset);
+#else
+static inline void tegra20_init_speedo_data(struct tegra_sku_info *sku_info) {}
+static inline bool tegra20_spare_fuse_early(int spare_bit)
+{
+ return false;
+}
+static inline void tegra20_init_fuse_early(void) {}
+static inline u32 tegra20_fuse_early(const unsigned int offset)
+{
+ return 0;
+}
+#endif
+
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+void tegra30_init_speedo_data(struct tegra_sku_info *sku_info);
+#else
+static inline void tegra30_init_speedo_data(struct tegra_sku_info *sku_info) {}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_init_speedo_data(struct tegra_sku_info *sku_info);
+#else
+static inline void tegra114_init_speedo_data(struct tegra_sku_info *sku_info) {}
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_124_SOC
+void tegra124_init_speedo_data(struct tegra_sku_info *sku_info);
+#else
+static inline void tegra124_init_speedo_data(struct tegra_sku_info *sku_info) {}
+#endif
+
+#endif
diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c
new file mode 100644
index 000000000000..2a6ca036f09f
--- /dev/null
+++ b/drivers/soc/tegra/fuse/speedo-tegra114.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA 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 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/bug.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS 2
+#define CPU_PROCESS_CORNERS 2
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
+ {1123, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
+ {1695, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
+ int *threshold)
+{
+ u32 tmp;
+ u32 sku = sku_info->sku_id;
+ enum tegra_revision rev = sku_info->revision;
+
+ switch (sku) {
+ case 0x00:
+ case 0x10:
+ case 0x05:
+ case 0x06:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+
+ case 0x03:
+ case 0x04:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+
+ default:
+ pr_err("Tegra Unknown SKU %d\n", sku);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+ }
+
+ if (rev == TEGRA_REVISION_A01) {
+ tmp = tegra30_fuse_readl(0x270) << 1;
+ tmp |= tegra30_fuse_readl(0x26c);
+ if (!tmp)
+ sku_info->cpu_speedo_id = 0;
+ }
+}
+
+void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
+{
+ u32 cpu_speedo_val;
+ u32 core_speedo_val;
+ int threshold;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ rev_sku_to_speedo_ids(sku_info, &threshold);
+
+ cpu_speedo_val = tegra30_fuse_readl(0x12c) + 1024;
+ core_speedo_val = tegra30_fuse_readl(0x134);
+
+ for (i = 0; i < CPU_PROCESS_CORNERS; i++)
+ if (cpu_speedo_val < cpu_process_speedos[threshold][i])
+ break;
+ sku_info->cpu_process_id = i;
+
+ for (i = 0; i < CORE_PROCESS_CORNERS; i++)
+ if (core_speedo_val < core_process_speedos[threshold][i])
+ break;
+ sku_info->core_process_id = i;
+}
diff --git a/drivers/soc/tegra/fuse/speedo-tegra124.c b/drivers/soc/tegra/fuse/speedo-tegra124.c
new file mode 100644
index 000000000000..46362387d974
--- /dev/null
+++ b/drivers/soc/tegra/fuse/speedo-tegra124.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA 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 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/device.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define CPU_PROCESS_CORNERS 2
+#define GPU_PROCESS_CORNERS 2
+#define CORE_PROCESS_CORNERS 2
+
+#define FUSE_CPU_SPEEDO_0 0x14
+#define FUSE_CPU_SPEEDO_1 0x2c
+#define FUSE_CPU_SPEEDO_2 0x30
+#define FUSE_SOC_SPEEDO_0 0x34
+#define FUSE_SOC_SPEEDO_1 0x38
+#define FUSE_SOC_SPEEDO_2 0x3c
+#define FUSE_CPU_IDDQ 0x18
+#define FUSE_SOC_IDDQ 0x40
+#define FUSE_GPU_IDDQ 0x128
+#define FUSE_FT_REV 0x28
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
+ {2190, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
+ {1965, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
+ {2101, UINT_MAX},
+ {0, UINT_MAX},
+};
+
+static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
+ int *threshold)
+{
+ int sku = sku_info->sku_id;
+
+ /* Assign to default */
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ sku_info->gpu_speedo_id = 0;
+ *threshold = THRESHOLD_INDEX_0;
+
+ switch (sku) {
+ case 0x00: /* Eng sku */
+ case 0x0F:
+ case 0x23:
+ /* Using the default */
+ break;
+ case 0x83:
+ sku_info->cpu_speedo_id = 2;
+ break;
+
+ case 0x1F:
+ case 0x87:
+ case 0x27:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 0;
+ sku_info->gpu_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_0;
+ break;
+ case 0x81:
+ case 0x21:
+ case 0x07:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ sku_info->gpu_speedo_id = 1;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+ case 0x49:
+ case 0x4A:
+ case 0x48:
+ sku_info->cpu_speedo_id = 4;
+ sku_info->soc_speedo_id = 2;
+ sku_info->gpu_speedo_id = 3;
+ *threshold = THRESHOLD_INDEX_1;
+ break;
+ default:
+ pr_err("Tegra Unknown SKU %d\n", sku);
+ /* Using the default for the error case */
+ break;
+ }
+}
+
+void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
+{
+ int i, threshold, cpu_speedo_0_value, soc_speedo_0_value;
+ int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+ cpu_speedo_0_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_0);
+
+ /* GPU Speedo is stored in CPU_SPEEDO_2 */
+ sku_info->gpu_speedo_value = tegra30_fuse_readl(FUSE_CPU_SPEEDO_2);
+
+ soc_speedo_0_value = tegra30_fuse_readl(FUSE_SOC_SPEEDO_0);
+
+ cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
+ soc_iddq_value = tegra30_fuse_readl(FUSE_SOC_IDDQ);
+ gpu_iddq_value = tegra30_fuse_readl(FUSE_GPU_IDDQ);
+
+ sku_info->cpu_speedo_value = cpu_speedo_0_value;
+
+ if (sku_info->cpu_speedo_value == 0) {
+ pr_warn("Tegra Warning: Speedo value not fused.\n");
+ WARN_ON(1);
+ return;
+ }
+
+ rev_sku_to_speedo_ids(sku_info, &threshold);
+
+ sku_info->cpu_iddq_value = tegra30_fuse_readl(FUSE_CPU_IDDQ);
+
+ for (i = 0; i < GPU_PROCESS_CORNERS; i++)
+ if (sku_info->gpu_speedo_value <
+ gpu_process_speedos[threshold][i])
+ break;
+ sku_info->gpu_process_id = i;
+
+ for (i = 0; i < CPU_PROCESS_CORNERS; i++)
+ if (sku_info->cpu_speedo_value <
+ cpu_process_speedos[threshold][i])
+ break;
+ sku_info->cpu_process_id = i;
+
+ for (i = 0; i < CORE_PROCESS_CORNERS; i++)
+ if (soc_speedo_0_value <
+ core_process_speedos[threshold][i])
+ break;
+ sku_info->core_process_id = i;
+
+ pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
+ sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
+}
diff --git a/drivers/soc/tegra/fuse/speedo-tegra20.c b/drivers/soc/tegra/fuse/speedo-tegra20.c
new file mode 100644
index 000000000000..eff1b63f330d
--- /dev/null
+++ b/drivers/soc/tegra/fuse/speedo-tegra20.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012-2014, NVIDIA 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 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/bug.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define CPU_SPEEDO_LSBIT 20
+#define CPU_SPEEDO_MSBIT 29
+#define CPU_SPEEDO_REDUND_LSBIT 30
+#define CPU_SPEEDO_REDUND_MSBIT 39
+#define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
+
+#define CORE_SPEEDO_LSBIT 40
+#define CORE_SPEEDO_MSBIT 47
+#define CORE_SPEEDO_REDUND_LSBIT 48
+#define CORE_SPEEDO_REDUND_MSBIT 55
+#define CORE_SPEEDO_REDUND_OFFS (CORE_SPEEDO_REDUND_MSBIT - CORE_SPEEDO_MSBIT)
+
+#define SPEEDO_MULT 4
+
+#define PROCESS_CORNERS_NUM 4
+
+#define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
+#define SPEEDO_ID_SELECT_1(sku) \
+ (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
+ ((sku) != 27) && ((sku) != 28))
+
+enum {
+ SPEEDO_ID_0,
+ SPEEDO_ID_1,
+ SPEEDO_ID_2,
+ SPEEDO_ID_COUNT,
+};
+
+static const u32 __initconst cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
+ {315, 366, 420, UINT_MAX},
+ {303, 368, 419, UINT_MAX},
+ {316, 331, 383, UINT_MAX},
+};
+
+static const u32 __initconst core_process_speedos[][PROCESS_CORNERS_NUM] = {
+ {165, 195, 224, UINT_MAX},
+ {165, 195, 224, UINT_MAX},
+ {165, 195, 224, UINT_MAX},
+};
+
+void __init tegra20_init_speedo_data(struct tegra_sku_info *sku_info)
+{
+ u32 reg;
+ u32 val;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
+
+ if (SPEEDO_ID_SELECT_0(sku_info->revision))
+ sku_info->soc_speedo_id = SPEEDO_ID_0;
+ else if (SPEEDO_ID_SELECT_1(sku_info->sku_id))
+ sku_info->soc_speedo_id = SPEEDO_ID_1;
+ else
+ sku_info->soc_speedo_id = SPEEDO_ID_2;
+
+ val = 0;
+ for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
+ reg = tegra20_spare_fuse_early(i) |
+ tegra20_spare_fuse_early(i + CPU_SPEEDO_REDUND_OFFS);
+ val = (val << 1) | (reg & 0x1);
+ }
+ val = val * SPEEDO_MULT;
+ pr_debug("Tegra CPU speedo value %u\n", val);
+
+ for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+ if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i])
+ break;
+ }
+ sku_info->cpu_process_id = i;
+
+ val = 0;
+ for (i = CORE_SPEEDO_MSBIT; i >= CORE_SPEEDO_LSBIT; i--) {
+ reg = tegra20_spare_fuse_early(i) |
+ tegra20_spare_fuse_early(i + CORE_SPEEDO_REDUND_OFFS);
+ val = (val << 1) | (reg & 0x1);
+ }
+ val = val * SPEEDO_MULT;
+ pr_debug("Core speedo value %u\n", val);
+
+ for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
+ if (val <= core_process_speedos[sku_info->soc_speedo_id][i])
+ break;
+ }
+ sku_info->core_process_id = i;
+}
diff --git a/drivers/soc/tegra/fuse/speedo-tegra30.c b/drivers/soc/tegra/fuse/speedo-tegra30.c
new file mode 100644
index 000000000000..b17f0dcdfebe
--- /dev/null
+++ b/drivers/soc/tegra/fuse/speedo-tegra30.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2012-2014, NVIDIA 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 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/bug.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS 1
+#define CPU_PROCESS_CORNERS 6
+
+#define FUSE_SPEEDO_CALIB_0 0x14
+#define FUSE_PACKAGE_INFO 0XFC
+#define FUSE_TEST_PROG_VER 0X28
+
+#define G_SPEEDO_BIT_MINUS1 58
+#define G_SPEEDO_BIT_MINUS1_R 59
+#define G_SPEEDO_BIT_MINUS2 60
+#define G_SPEEDO_BIT_MINUS2_R 61
+#define LP_SPEEDO_BIT_MINUS1 62
+#define LP_SPEEDO_BIT_MINUS1_R 63
+#define LP_SPEEDO_BIT_MINUS2 64
+#define LP_SPEEDO_BIT_MINUS2_R 65
+
+enum {
+ THRESHOLD_INDEX_0,
+ THRESHOLD_INDEX_1,
+ THRESHOLD_INDEX_2,
+ THRESHOLD_INDEX_3,
+ THRESHOLD_INDEX_4,
+ THRESHOLD_INDEX_5,
+ THRESHOLD_INDEX_6,
+ THRESHOLD_INDEX_7,
+ THRESHOLD_INDEX_8,
+ THRESHOLD_INDEX_9,
+ THRESHOLD_INDEX_10,
+ THRESHOLD_INDEX_11,
+ THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 __initconst core_process_speedos[][CORE_PROCESS_CORNERS] = {
+ {180},
+ {170},
+ {195},
+ {180},
+ {168},
+ {192},
+ {180},
+ {170},
+ {195},
+ {180},
+ {180},
+ {180},
+};
+
+static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
+ {306, 338, 360, 376, UINT_MAX},
+ {295, 336, 358, 375, UINT_MAX},
+ {325, 325, 358, 375, UINT_MAX},
+ {325, 325, 358, 375, UINT_MAX},
+ {292, 324, 348, 364, UINT_MAX},
+ {324, 324, 348, 364, UINT_MAX},
+ {324, 324, 348, 364, UINT_MAX},
+ {295, 336, 358, 375, UINT_MAX},
+ {358, 358, 358, 358, 397, UINT_MAX},
+ {364, 364, 364, 364, 397, UINT_MAX},
+ {295, 336, 358, 375, 391, UINT_MAX},
+ {295, 336, 358, 375, 391, UINT_MAX},
+};
+
+static int threshold_index __initdata;
+
+static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
+{
+ u32 reg;
+ int ate_ver;
+ int bit_minus1;
+ int bit_minus2;
+
+ reg = tegra30_fuse_readl(FUSE_SPEEDO_CALIB_0);
+
+ *speedo_lp = (reg & 0xFFFF) * 4;
+ *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
+
+ ate_ver = tegra30_fuse_readl(FUSE_TEST_PROG_VER);
+ pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
+
+ if (ate_ver >= 26) {
+ bit_minus1 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1);
+ bit_minus1 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS1_R);
+ bit_minus2 = tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2);
+ bit_minus2 |= tegra30_spare_fuse(LP_SPEEDO_BIT_MINUS2_R);
+ *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
+
+ bit_minus1 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1);
+ bit_minus1 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS1_R);
+ bit_minus2 = tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2);
+ bit_minus2 |= tegra30_spare_fuse(G_SPEEDO_BIT_MINUS2_R);
+ *speedo_g |= (bit_minus1 << 1) | bit_minus2;
+ } else {
+ *speedo_lp |= 0x3;
+ *speedo_g |= 0x3;
+ }
+}
+
+static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
+{
+ int package_id = tegra30_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
+
+ switch (sku_info->revision) {
+ case TEGRA_REVISION_A01:
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ case TEGRA_REVISION_A02:
+ case TEGRA_REVISION_A03:
+ switch (sku_info->sku_id) {
+ case 0x87:
+ case 0x82:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_1;
+ break;
+ case 0x81:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_2;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 4;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_7;
+ break;
+ default:
+ pr_err("Tegra Unknown pkg %d\n", package_id);
+ break;
+ }
+ break;
+ case 0x80:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 5;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_8;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 6;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_9;
+ break;
+ default:
+ pr_err("Tegra Unknown pkg %d\n", package_id);
+ break;
+ }
+ break;
+ case 0x83:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 7;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_10;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_3;
+ break;
+ default:
+ pr_err("Tegra Unknown pkg %d\n", package_id);
+ break;
+ }
+ break;
+ case 0x8F:
+ sku_info->cpu_speedo_id = 8;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_11;
+ break;
+ case 0x08:
+ sku_info->cpu_speedo_id = 1;
+ sku_info->soc_speedo_id = 1;
+ threshold_index = THRESHOLD_INDEX_4;
+ break;
+ case 0x02:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_5;
+ break;
+ case 0x04:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_6;
+ break;
+ case 0:
+ switch (package_id) {
+ case 1:
+ sku_info->cpu_speedo_id = 2;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_2;
+ break;
+ case 2:
+ sku_info->cpu_speedo_id = 3;
+ sku_info->soc_speedo_id = 2;
+ threshold_index = THRESHOLD_INDEX_3;
+ break;
+ default:
+ pr_err("Tegra Unknown pkg %d\n", package_id);
+ break;
+ }
+ break;
+ default:
+ pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ }
+ break;
+ default:
+ pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
+ sku_info->cpu_speedo_id = 0;
+ sku_info->soc_speedo_id = 0;
+ threshold_index = THRESHOLD_INDEX_0;
+ break;
+ }
+}
+
+void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
+{
+ u32 cpu_speedo_val;
+ u32 core_speedo_val;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+ THRESHOLD_INDEX_COUNT);
+
+
+ rev_sku_to_speedo_ids(sku_info);
+ fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);
+ pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
+ pr_debug("Tegra Core speedo value %u\n", core_speedo_val);
+
+ for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
+ if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
+ break;
+ }
+ sku_info->cpu_process_id = i - 1;
+
+ if (sku_info->cpu_process_id == -1) {
+ pr_warn("Tegra CPU speedo value %3d out of range",
+ cpu_speedo_val);
+ sku_info->cpu_process_id = 0;
+ sku_info->cpu_speedo_id = 1;
+ }
+
+ for (i = 0; i < CORE_PROCESS_CORNERS; i++) {
+ if (core_speedo_val < core_process_speedos[threshold_index][i])
+ break;
+ }
+ sku_info->core_process_id = i - 1;
+
+ if (sku_info->core_process_id == -1) {
+ pr_warn("Tegra CORE speedo value %3d out of range",
+ core_speedo_val);
+ sku_info->core_process_id = 0;
+ sku_info->soc_speedo_id = 1;
+ }
+}
diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
new file mode 100644
index 000000000000..3bf5aba4caaa
--- /dev/null
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, NVIDIA 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 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/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include <soc/tegra/fuse.h>
+
+#include "fuse.h"
+
+#define APBMISC_BASE 0x70000800
+#define APBMISC_SIZE 0x64
+#define FUSE_SKU_INFO 0x10
+
+static void __iomem *apbmisc_base;
+static void __iomem *strapping_base;
+
+u32 tegra_read_chipid(void)
+{
+ return readl_relaxed(apbmisc_base + 4);
+}
+
+u8 tegra_get_chip_id(void)
+{
+ if (!apbmisc_base) {
+ WARN(1, "Tegra Chip ID not yet available\n");
+ return 0;
+ }
+
+ return (tegra_read_chipid() >> 8) & 0xff;
+}
+
+u32 tegra_read_straps(void)
+{
+ if (strapping_base)
+ return readl_relaxed(strapping_base);
+ else
+ return 0;
+}
+
+static const struct of_device_id apbmisc_match[] __initconst = {
+ { .compatible = "nvidia,tegra20-apbmisc", },
+ {},
+};
+
+void __init tegra_init_revision(void)
+{
+ u32 id, chip_id, minor_rev;
+ int rev;
+
+ id = tegra_read_chipid();
+ chip_id = (id >> 8) & 0xff;
+ minor_rev = (id >> 16) & 0xf;
+
+ switch (minor_rev) {
+ case 1:
+ rev = TEGRA_REVISION_A01;
+ break;
+ case 2:
+ rev = TEGRA_REVISION_A02;
+ break;
+ case 3:
+ if (chip_id == TEGRA20 && (tegra20_spare_fuse_early(18) ||
+ tegra20_spare_fuse_early(19)))
+ rev = TEGRA_REVISION_A03p;
+ else
+ rev = TEGRA_REVISION_A03;
+ break;
+ case 4:
+ rev = TEGRA_REVISION_A04;
+ break;
+ default:
+ rev = TEGRA_REVISION_UNKNOWN;
+ }
+
+ tegra_sku_info.revision = rev;
+
+ if (chip_id == TEGRA20)
+ tegra_sku_info.sku_id = tegra20_fuse_early(FUSE_SKU_INFO);
+ else
+ tegra_sku_info.sku_id = tegra30_fuse_readl(FUSE_SKU_INFO);
+}
+
+void __init tegra_init_apbmisc(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, apbmisc_match);
+ apbmisc_base = of_iomap(np, 0);
+ if (!apbmisc_base) {
+ pr_warn("ioremap tegra apbmisc failed. using %08x instead\n",
+ APBMISC_BASE);
+ apbmisc_base = ioremap(APBMISC_BASE, APBMISC_SIZE);
+ }
+
+ strapping_base = of_iomap(np, 1);
+ if (!strapping_base)
+ pr_err("ioremap tegra strapping_base failed\n");
+}
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
new file mode 100644
index 000000000000..a2c0ceb95f8f
--- /dev/null
+++ b/drivers/soc/tegra/pmc.c
@@ -0,0 +1,957 @@
+/*
+ * drivers/soc/tegra/pmc.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clk/tegra.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reset.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+
+#include <soc/tegra/common.h>
+#include <soc/tegra/fuse.h>
+#include <soc/tegra/pmc.h>
+
+#define PMC_CNTRL 0x0
+#define PMC_CNTRL_SYSCLK_POLARITY (1 << 10) /* sys clk polarity */
+#define PMC_CNTRL_SYSCLK_OE (1 << 11) /* system clock enable */
+#define PMC_CNTRL_SIDE_EFFECT_LP0 (1 << 14) /* LP0 when CPU pwr gated */
+#define PMC_CNTRL_CPU_PWRREQ_POLARITY (1 << 15) /* CPU pwr req polarity */
+#define PMC_CNTRL_CPU_PWRREQ_OE (1 << 16) /* CPU pwr req enable */
+#define PMC_CNTRL_INTR_POLARITY (1 << 17) /* inverts INTR polarity */
+
+#define DPD_SAMPLE 0x020
+#define DPD_SAMPLE_ENABLE (1 << 0)
+#define DPD_SAMPLE_DISABLE (0 << 0)
+
+#define PWRGATE_TOGGLE 0x30
+#define PWRGATE_TOGGLE_START (1 << 8)
+
+#define REMOVE_CLAMPING 0x34
+
+#define PWRGATE_STATUS 0x38
+
+#define PMC_SCRATCH0 0x50
+#define PMC_SCRATCH0_MODE_RECOVERY (1 << 31)
+#define PMC_SCRATCH0_MODE_BOOTLOADER (1 << 30)
+#define PMC_SCRATCH0_MODE_RCM (1 << 1)
+#define PMC_SCRATCH0_MODE_MASK (PMC_SCRATCH0_MODE_RECOVERY | \
+ PMC_SCRATCH0_MODE_BOOTLOADER | \
+ PMC_SCRATCH0_MODE_RCM)
+
+#define PMC_CPUPWRGOOD_TIMER 0xc8
+#define PMC_CPUPWROFF_TIMER 0xcc
+
+#define PMC_SCRATCH41 0x140
+
+#define IO_DPD_REQ 0x1b8
+#define IO_DPD_REQ_CODE_IDLE (0 << 30)
+#define IO_DPD_REQ_CODE_OFF (1 << 30)
+#define IO_DPD_REQ_CODE_ON (2 << 30)
+#define IO_DPD_REQ_CODE_MASK (3 << 30)
+
+#define IO_DPD_STATUS 0x1bc
+#define IO_DPD2_REQ 0x1c0
+#define IO_DPD2_STATUS 0x1c4
+#define SEL_DPD_TIM 0x1c8
+
+#define GPU_RG_CNTRL 0x2d4
+
+struct tegra_pmc_soc {
+ unsigned int num_powergates;
+ const char *const *powergates;
+ unsigned int num_cpu_powergates;
+ const u8 *cpu_powergates;
+};
+
+/**
+ * struct tegra_pmc - NVIDIA Tegra PMC
+ * @base: pointer to I/O remapped register region
+ * @clk: pointer to pclk clock
+ * @rate: currently configured rate of pclk
+ * @suspend_mode: lowest suspend mode available
+ * @cpu_good_time: CPU power good time (in microseconds)
+ * @cpu_off_time: CPU power off time (in microsecends)
+ * @core_osc_time: core power good OSC time (in microseconds)
+ * @core_pmu_time: core power good PMU time (in microseconds)
+ * @core_off_time: core power off time (in microseconds)
+ * @corereq_high: core power request is active-high
+ * @sysclkreq_high: system clock request is active-high
+ * @combined_req: combined power request for CPU & core
+ * @cpu_pwr_good_en: CPU power good signal is enabled
+ * @lp0_vec_phys: physical base address of the LP0 warm boot code
+ * @lp0_vec_size: size of the LP0 warm boot code
+ * @powergates_lock: mutex for power gate register access
+ */
+struct tegra_pmc {
+ void __iomem *base;
+ struct clk *clk;
+
+ const struct tegra_pmc_soc *soc;
+
+ unsigned long rate;
+
+ enum tegra_suspend_mode suspend_mode;
+ u32 cpu_good_time;
+ u32 cpu_off_time;
+ u32 core_osc_time;
+ u32 core_pmu_time;
+ u32 core_off_time;
+ bool corereq_high;
+ bool sysclkreq_high;
+ bool combined_req;
+ bool cpu_pwr_good_en;
+ u32 lp0_vec_phys;
+ u32 lp0_vec_size;
+
+ struct mutex powergates_lock;
+};
+
+static struct tegra_pmc *pmc = &(struct tegra_pmc) {
+ .base = NULL,
+ .suspend_mode = TEGRA_SUSPEND_NONE,
+};
+
+static u32 tegra_pmc_readl(unsigned long offset)
+{
+ return readl(pmc->base + offset);
+}
+
+static void tegra_pmc_writel(u32 value, unsigned long offset)
+{
+ writel(value, pmc->base + offset);
+}
+
+/**
+ * tegra_powergate_set() - set the state of a partition
+ * @id: partition ID
+ * @new_state: new state of the partition
+ */
+static int tegra_powergate_set(int id, bool new_state)
+{
+ bool status;
+
+ mutex_lock(&pmc->powergates_lock);
+
+ status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
+
+ if (status == new_state) {
+ mutex_unlock(&pmc->powergates_lock);
+ return 0;
+ }
+
+ tegra_pmc_writel(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+
+ mutex_unlock(&pmc->powergates_lock);
+
+ return 0;
+}
+
+/**
+ * tegra_powergate_power_on() - power on partition
+ * @id: partition ID
+ */
+int tegra_powergate_power_on(int id)
+{
+ if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, true);
+}
+
+/**
+ * tegra_powergate_power_off() - power off partition
+ * @id: partition ID
+ */
+int tegra_powergate_power_off(int id)
+{
+ if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, false);
+}
+EXPORT_SYMBOL(tegra_powergate_power_off);
+
+/**
+ * tegra_powergate_is_powered() - check if partition is powered
+ * @id: partition ID
+ */
+int tegra_powergate_is_powered(int id)
+{
+ u32 status;
+
+ if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+ return -EINVAL;
+
+ status = tegra_pmc_readl(PWRGATE_STATUS) & (1 << id);
+ return !!status;
+}
+
+/**
+ * tegra_powergate_remove_clamping() - remove power clamps for partition
+ * @id: partition ID
+ */
+int tegra_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ if (!pmc->soc || id < 0 || id >= pmc->soc->num_powergates)
+ return -EINVAL;
+
+ /*
+ * The Tegra124 GPU has a separate register (with different semantics)
+ * to remove clamps.
+ */
+ if (tegra_get_chip_id() == TEGRA124) {
+ if (id == TEGRA_POWERGATE_3D) {
+ tegra_pmc_writel(0, GPU_RG_CNTRL);
+ return 0;
+ }
+ }
+
+ /*
+ * Tegra 2 has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ tegra_pmc_writel(mask, REMOVE_CLAMPING);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_powergate_remove_clamping);
+
+/**
+ * tegra_powergate_sequence_power_up() - power up partition
+ * @id: partition ID
+ * @clk: clock for partition
+ * @rst: reset for partition
+ *
+ * Must be called with clk disabled, and returns with clk enabled.
+ */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+ struct reset_control *rst)
+{
+ int ret;
+
+ reset_control_assert(rst);
+
+ ret = tegra_powergate_power_on(id);
+ if (ret)
+ goto err_power;
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto err_clk;
+
+ usleep_range(10, 20);
+
+ ret = tegra_powergate_remove_clamping(id);
+ if (ret)
+ goto err_clamp;
+
+ usleep_range(10, 20);
+ reset_control_deassert(rst);
+
+ return 0;
+
+err_clamp:
+ clk_disable_unprepare(clk);
+err_clk:
+ tegra_powergate_power_off(id);
+err_power:
+ return ret;
+}
+EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
+
+#ifdef CONFIG_SMP
+/**
+ * tegra_get_cpu_powergate_id() - convert from CPU ID to partition ID
+ * @cpuid: CPU partition ID
+ *
+ * Returns the partition ID corresponding to the CPU partition ID or a
+ * negative error code on failure.
+ */
+static int tegra_get_cpu_powergate_id(int cpuid)
+{
+ if (pmc->soc && cpuid > 0 && cpuid < pmc->soc->num_cpu_powergates)
+ return pmc->soc->cpu_powergates[cpuid];
+
+ return -EINVAL;
+}
+
+/**
+ * tegra_pmc_cpu_is_powered() - check if CPU partition is powered
+ * @cpuid: CPU partition ID
+ */
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+ int id;
+
+ id = tegra_get_cpu_powergate_id(cpuid);
+ if (id < 0)
+ return false;
+
+ return tegra_powergate_is_powered(id);
+}
+
+/**
+ * tegra_pmc_cpu_power_on() - power on CPU partition
+ * @cpuid: CPU partition ID
+ */
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+ int id;
+
+ id = tegra_get_cpu_powergate_id(cpuid);
+ if (id < 0)
+ return id;
+
+ return tegra_powergate_set(id, true);
+}
+
+/**
+ * tegra_pmc_cpu_remove_clamping() - remove power clamps for CPU partition
+ * @cpuid: CPU partition ID
+ */
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+ int id;
+
+ id = tegra_get_cpu_powergate_id(cpuid);
+ if (id < 0)
+ return id;
+
+ return tegra_powergate_remove_clamping(id);
+}
+#endif /* CONFIG_SMP */
+
+/**
+ * tegra_pmc_restart() - reboot the system
+ * @mode: which mode to reboot in
+ * @cmd: reboot command
+ */
+void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
+{
+ u32 value;
+
+ value = tegra_pmc_readl(PMC_SCRATCH0);
+ value &= ~PMC_SCRATCH0_MODE_MASK;
+
+ if (cmd) {
+ if (strcmp(cmd, "recovery") == 0)
+ value |= PMC_SCRATCH0_MODE_RECOVERY;
+
+ if (strcmp(cmd, "bootloader") == 0)
+ value |= PMC_SCRATCH0_MODE_BOOTLOADER;
+
+ if (strcmp(cmd, "forced-recovery") == 0)
+ value |= PMC_SCRATCH0_MODE_RCM;
+ }
+
+ tegra_pmc_writel(value, PMC_SCRATCH0);
+
+ value = tegra_pmc_readl(0);
+ value |= 0x10;
+ tegra_pmc_writel(value, 0);
+}
+
+static int powergate_show(struct seq_file *s, void *data)
+{
+ unsigned int i;
+
+ seq_printf(s, " powergate powered\n");
+ seq_printf(s, "------------------\n");
+
+ for (i = 0; i < pmc->soc->num_powergates; i++) {
+ if (!pmc->soc->powergates[i])
+ continue;
+
+ seq_printf(s, " %9s %7s\n", pmc->soc->powergates[i],
+ tegra_powergate_is_powered(i) ? "yes" : "no");
+ }
+
+ return 0;
+}
+
+static int powergate_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, powergate_show, inode->i_private);
+}
+
+static const struct file_operations powergate_fops = {
+ .open = powergate_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int tegra_powergate_debugfs_init(void)
+{
+ struct dentry *d;
+
+ d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
+ &powergate_fops);
+ if (!d)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int tegra_io_rail_prepare(int id, unsigned long *request,
+ unsigned long *status, unsigned int *bit)
+{
+ unsigned long rate, value;
+ struct clk *clk;
+
+ *bit = id % 32;
+
+ /*
+ * There are two sets of 30 bits to select IO rails, but bits 30 and
+ * 31 are control bits rather than IO rail selection bits.
+ */
+ if (id > 63 || *bit == 30 || *bit == 31)
+ return -EINVAL;
+
+ if (id < 32) {
+ *status = IO_DPD_STATUS;
+ *request = IO_DPD_REQ;
+ } else {
+ *status = IO_DPD2_STATUS;
+ *request = IO_DPD2_REQ;
+ }
+
+ clk = clk_get_sys(NULL, "pclk");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ rate = clk_get_rate(clk);
+ clk_put(clk);
+
+ tegra_pmc_writel(DPD_SAMPLE_ENABLE, DPD_SAMPLE);
+
+ /* must be at least 200 ns, in APB (PCLK) clock cycles */
+ value = DIV_ROUND_UP(1000000000, rate);
+ value = DIV_ROUND_UP(200, value);
+ tegra_pmc_writel(value, SEL_DPD_TIM);
+
+ return 0;
+}
+
+static int tegra_io_rail_poll(unsigned long offset, unsigned long mask,
+ unsigned long val, unsigned long timeout)
+{
+ unsigned long value;
+
+ timeout = jiffies + msecs_to_jiffies(timeout);
+
+ while (time_after(timeout, jiffies)) {
+ value = tegra_pmc_readl(offset);
+ if ((value & mask) == val)
+ return 0;
+
+ usleep_range(250, 1000);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void tegra_io_rail_unprepare(void)
+{
+ tegra_pmc_writel(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
+}
+
+int tegra_io_rail_power_on(int id)
+{
+ unsigned long request, status, value;
+ unsigned int bit, mask;
+ int err;
+
+ err = tegra_io_rail_prepare(id, &request, &status, &bit);
+ if (err < 0)
+ return err;
+
+ mask = 1 << bit;
+
+ value = tegra_pmc_readl(request);
+ value |= mask;
+ value &= ~IO_DPD_REQ_CODE_MASK;
+ value |= IO_DPD_REQ_CODE_OFF;
+ tegra_pmc_writel(value, request);
+
+ err = tegra_io_rail_poll(status, mask, 0, 250);
+ if (err < 0)
+ return err;
+
+ tegra_io_rail_unprepare();
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_io_rail_power_on);
+
+int tegra_io_rail_power_off(int id)
+{
+ unsigned long request, status, value;
+ unsigned int bit, mask;
+ int err;
+
+ err = tegra_io_rail_prepare(id, &request, &status, &bit);
+ if (err < 0)
+ return err;
+
+ mask = 1 << bit;
+
+ value = tegra_pmc_readl(request);
+ value |= mask;
+ value &= ~IO_DPD_REQ_CODE_MASK;
+ value |= IO_DPD_REQ_CODE_ON;
+ tegra_pmc_writel(value, request);
+
+ err = tegra_io_rail_poll(status, mask, mask, 250);
+ if (err < 0)
+ return err;
+
+ tegra_io_rail_unprepare();
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_io_rail_power_off);
+
+#ifdef CONFIG_PM_SLEEP
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
+{
+ return pmc->suspend_mode;
+}
+
+void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
+{
+ if (mode < TEGRA_SUSPEND_NONE || mode >= TEGRA_MAX_SUSPEND_MODE)
+ return;
+
+ pmc->suspend_mode = mode;
+}
+
+void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
+{
+ unsigned long long rate = 0;
+ u32 value;
+
+ switch (mode) {
+ case TEGRA_SUSPEND_LP1:
+ rate = 32768;
+ break;
+
+ case TEGRA_SUSPEND_LP2:
+ rate = clk_get_rate(pmc->clk);
+ break;
+
+ default:
+ break;
+ }
+
+ if (WARN_ON_ONCE(rate == 0))
+ rate = 100000000;
+
+ if (rate != pmc->rate) {
+ u64 ticks;
+
+ ticks = pmc->cpu_good_time * rate + USEC_PER_SEC - 1;
+ do_div(ticks, USEC_PER_SEC);
+ tegra_pmc_writel(ticks, PMC_CPUPWRGOOD_TIMER);
+
+ ticks = pmc->cpu_off_time * rate + USEC_PER_SEC - 1;
+ do_div(ticks, USEC_PER_SEC);
+ tegra_pmc_writel(ticks, PMC_CPUPWROFF_TIMER);
+
+ wmb();
+
+ pmc->rate = rate;
+ }
+
+ value = tegra_pmc_readl(PMC_CNTRL);
+ value &= ~PMC_CNTRL_SIDE_EFFECT_LP0;
+ value |= PMC_CNTRL_CPU_PWRREQ_OE;
+ tegra_pmc_writel(value, PMC_CNTRL);
+}
+#endif
+
+static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np)
+{
+ u32 value, values[2];
+
+ if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
+ } else {
+ switch (value) {
+ case 0:
+ pmc->suspend_mode = TEGRA_SUSPEND_LP0;
+ break;
+
+ case 1:
+ pmc->suspend_mode = TEGRA_SUSPEND_LP1;
+ break;
+
+ case 2:
+ pmc->suspend_mode = TEGRA_SUSPEND_LP2;
+ break;
+
+ default:
+ pmc->suspend_mode = TEGRA_SUSPEND_NONE;
+ break;
+ }
+ }
+
+ pmc->suspend_mode = tegra_pm_validate_suspend_mode(pmc->suspend_mode);
+
+ if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &value))
+ pmc->suspend_mode = TEGRA_SUSPEND_NONE;
+
+ pmc->cpu_good_time = value;
+
+ if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &value))
+ pmc->suspend_mode = TEGRA_SUSPEND_NONE;
+
+ pmc->cpu_off_time = value;
+
+ if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time",
+ values, ARRAY_SIZE(values)))
+ pmc->suspend_mode = TEGRA_SUSPEND_NONE;
+
+ pmc->core_osc_time = values[0];
+ pmc->core_pmu_time = values[1];
+
+ if (of_property_read_u32(np, "nvidia,core-pwr-off-time", &value))
+ pmc->suspend_mode = TEGRA_SUSPEND_NONE;
+
+ pmc->core_off_time = value;
+
+ pmc->corereq_high = of_property_read_bool(np,
+ "nvidia,core-power-req-active-high");
+
+ pmc->sysclkreq_high = of_property_read_bool(np,
+ "nvidia,sys-clock-req-active-high");
+
+ pmc->combined_req = of_property_read_bool(np,
+ "nvidia,combined-power-req");
+
+ pmc->cpu_pwr_good_en = of_property_read_bool(np,
+ "nvidia,cpu-pwr-good-en");
+
+ if (of_property_read_u32_array(np, "nvidia,lp0-vec", values,
+ ARRAY_SIZE(values)))
+ if (pmc->suspend_mode == TEGRA_SUSPEND_LP0)
+ pmc->suspend_mode = TEGRA_SUSPEND_LP1;
+
+ pmc->lp0_vec_phys = values[0];
+ pmc->lp0_vec_size = values[1];
+
+ return 0;
+}
+
+static void tegra_pmc_init(struct tegra_pmc *pmc)
+{
+ u32 value;
+
+ /* Always enable CPU power request */
+ value = tegra_pmc_readl(PMC_CNTRL);
+ value |= PMC_CNTRL_CPU_PWRREQ_OE;
+ tegra_pmc_writel(value, PMC_CNTRL);
+
+ value = tegra_pmc_readl(PMC_CNTRL);
+
+ if (pmc->sysclkreq_high)
+ value &= ~PMC_CNTRL_SYSCLK_POLARITY;
+ else
+ value |= PMC_CNTRL_SYSCLK_POLARITY;
+
+ /* configure the output polarity while the request is tristated */
+ tegra_pmc_writel(value, PMC_CNTRL);
+
+ /* now enable the request */
+ value = tegra_pmc_readl(PMC_CNTRL);
+ value |= PMC_CNTRL_SYSCLK_OE;
+ tegra_pmc_writel(value, PMC_CNTRL);
+}
+
+static int tegra_pmc_probe(struct platform_device *pdev)
+{
+ void __iomem *base = pmc->base;
+ struct resource *res;
+ int err;
+
+ err = tegra_pmc_parse_dt(pmc, pdev->dev.of_node);
+ if (err < 0)
+ return err;
+
+ /* take over the memory region from the early initialization */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pmc->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pmc->base))
+ return PTR_ERR(pmc->base);
+
+ iounmap(base);
+
+ pmc->clk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(pmc->clk)) {
+ err = PTR_ERR(pmc->clk);
+ dev_err(&pdev->dev, "failed to get pclk: %d\n", err);
+ return err;
+ }
+
+ tegra_pmc_init(pmc);
+
+ if (IS_ENABLED(CONFIG_DEBUG_FS)) {
+ err = tegra_powergate_debugfs_init();
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra_pmc_suspend(struct device *dev)
+{
+ tegra_pmc_writel(virt_to_phys(tegra_resume), PMC_SCRATCH41);
+
+ return 0;
+}
+
+static int tegra_pmc_resume(struct device *dev)
+{
+ tegra_pmc_writel(0x0, PMC_SCRATCH41);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tegra_pmc_pm_ops, tegra_pmc_suspend, tegra_pmc_resume);
+
+static const char * const tegra20_powergates[] = {
+ [TEGRA_POWERGATE_CPU] = "cpu",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_L2] = "l2",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+};
+
+static const struct tegra_pmc_soc tegra20_pmc_soc = {
+ .num_powergates = ARRAY_SIZE(tegra20_powergates),
+ .powergates = tegra20_powergates,
+ .num_cpu_powergates = 0,
+ .cpu_powergates = NULL,
+};
+
+static const char * const tegra30_powergates[] = {
+ [TEGRA_POWERGATE_CPU] = "cpu0",
+ [TEGRA_POWERGATE_3D] = "3d0",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_L2] = "l2",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_HEG] = "heg",
+ [TEGRA_POWERGATE_SATA] = "sata",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CELP] = "celp",
+ [TEGRA_POWERGATE_3D1] = "3d1",
+};
+
+static const u8 tegra30_cpu_powergates[] = {
+ TEGRA_POWERGATE_CPU,
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+
+static const struct tegra_pmc_soc tegra30_pmc_soc = {
+ .num_powergates = ARRAY_SIZE(tegra30_powergates),
+ .powergates = tegra30_powergates,
+ .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
+ .cpu_powergates = tegra30_cpu_powergates,
+};
+
+static const char * const tegra114_powergates[] = {
+ [TEGRA_POWERGATE_CPU] = "crail",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_HEG] = "heg",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CELP] = "celp",
+ [TEGRA_POWERGATE_CPU0] = "cpu0",
+ [TEGRA_POWERGATE_C0NC] = "c0nc",
+ [TEGRA_POWERGATE_C1NC] = "c1nc",
+ [TEGRA_POWERGATE_DIS] = "dis",
+ [TEGRA_POWERGATE_DISB] = "disb",
+ [TEGRA_POWERGATE_XUSBA] = "xusba",
+ [TEGRA_POWERGATE_XUSBB] = "xusbb",
+ [TEGRA_POWERGATE_XUSBC] = "xusbc",
+};
+
+static const u8 tegra114_cpu_powergates[] = {
+ TEGRA_POWERGATE_CPU0,
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+
+static const struct tegra_pmc_soc tegra114_pmc_soc = {
+ .num_powergates = ARRAY_SIZE(tegra114_powergates),
+ .powergates = tegra114_powergates,
+ .num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
+ .cpu_powergates = tegra114_cpu_powergates,
+};
+
+static const char * const tegra124_powergates[] = {
+ [TEGRA_POWERGATE_CPU] = "crail",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_L2] = "l2",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+ [TEGRA_POWERGATE_HEG] = "heg",
+ [TEGRA_POWERGATE_SATA] = "sata",
+ [TEGRA_POWERGATE_CPU1] = "cpu1",
+ [TEGRA_POWERGATE_CPU2] = "cpu2",
+ [TEGRA_POWERGATE_CPU3] = "cpu3",
+ [TEGRA_POWERGATE_CELP] = "celp",
+ [TEGRA_POWERGATE_CPU0] = "cpu0",
+ [TEGRA_POWERGATE_C0NC] = "c0nc",
+ [TEGRA_POWERGATE_C1NC] = "c1nc",
+ [TEGRA_POWERGATE_SOR] = "sor",
+ [TEGRA_POWERGATE_DIS] = "dis",
+ [TEGRA_POWERGATE_DISB] = "disb",
+ [TEGRA_POWERGATE_XUSBA] = "xusba",
+ [TEGRA_POWERGATE_XUSBB] = "xusbb",
+ [TEGRA_POWERGATE_XUSBC] = "xusbc",
+ [TEGRA_POWERGATE_VIC] = "vic",
+ [TEGRA_POWERGATE_IRAM] = "iram",
+};
+
+static const u8 tegra124_cpu_powergates[] = {
+ TEGRA_POWERGATE_CPU0,
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+
+static const struct tegra_pmc_soc tegra124_pmc_soc = {
+ .num_powergates = ARRAY_SIZE(tegra124_powergates),
+ .powergates = tegra124_powergates,
+ .num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
+ .cpu_powergates = tegra124_cpu_powergates,
+};
+
+static const struct of_device_id tegra_pmc_match[] = {
+ { .compatible = "nvidia,tegra124-pmc", .data = &tegra124_pmc_soc },
+ { .compatible = "nvidia,tegra114-pmc", .data = &tegra114_pmc_soc },
+ { .compatible = "nvidia,tegra30-pmc", .data = &tegra30_pmc_soc },
+ { .compatible = "nvidia,tegra20-pmc", .data = &tegra20_pmc_soc },
+ { }
+};
+
+static struct platform_driver tegra_pmc_driver = {
+ .driver = {
+ .name = "tegra-pmc",
+ .suppress_bind_attrs = true,
+ .of_match_table = tegra_pmc_match,
+ .pm = &tegra_pmc_pm_ops,
+ },
+ .probe = tegra_pmc_probe,
+};
+module_platform_driver(tegra_pmc_driver);
+
+/*
+ * Early initialization to allow access to registers in the very early boot
+ * process.
+ */
+static int __init tegra_pmc_early_init(void)
+{
+ const struct of_device_id *match;
+ struct device_node *np;
+ struct resource regs;
+ bool invert;
+ u32 value;
+
+ if (!soc_is_tegra())
+ return 0;
+
+ np = of_find_matching_node_and_match(NULL, tegra_pmc_match, &match);
+ if (!np) {
+ pr_warn("PMC device node not found, disabling powergating\n");
+
+ regs.start = 0x7000e400;
+ regs.end = 0x7000e7ff;
+ regs.flags = IORESOURCE_MEM;
+
+ pr_warn("Using memory region %pR\n", &regs);
+ } else {
+ pmc->soc = match->data;
+ }
+
+ if (of_address_to_resource(np, 0, &regs) < 0) {
+ pr_err("failed to get PMC registers\n");
+ return -ENXIO;
+ }
+
+ pmc->base = ioremap_nocache(regs.start, resource_size(&regs));
+ if (!pmc->base) {
+ pr_err("failed to map PMC registers\n");
+ return -ENXIO;
+ }
+
+ mutex_init(&pmc->powergates_lock);
+
+ invert = of_property_read_bool(np, "nvidia,invert-interrupt");
+
+ value = tegra_pmc_readl(PMC_CNTRL);
+
+ if (invert)
+ value |= PMC_CNTRL_INTR_POLARITY;
+ else
+ value &= ~PMC_CNTRL_INTR_POLARITY;
+
+ tegra_pmc_writel(value, PMC_CNTRL);
+
+ return 0;
+}
+early_initcall(tegra_pmc_early_init);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 213b5cbb9dcc..62e2242ad7e0 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -382,9 +382,21 @@ config SPI_PXA2XX
config SPI_PXA2XX_PCI
def_tristate SPI_PXA2XX && PCI
+config SPI_ROCKCHIP
+ tristate "Rockchip SPI controller driver"
+ depends on ARM || ARM64 || AVR32 || HEXAGON || MIPS || SUPERH
+ help
+ This selects a driver for Rockchip SPI controller.
+
+ If you say yes to this option, support will be included for
+ RK3066, RK3188 and RK3288 families of SPI controller.
+ Rockchip SPI controller support DMA transport and PIO mode.
+ The main usecase of this controller is to use spi flash as boot
+ device.
+
config SPI_RSPI
tristate "Renesas RSPI/QSPI controller"
- depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE
+ depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
help
SPI driver for Renesas RSPI and QSPI blocks.
@@ -434,7 +446,7 @@ config SPI_SC18IS602
config SPI_SH_MSIOF
tristate "SuperH MSIOF SPI controller"
- depends on HAVE_CLK
+ depends on HAVE_CLK && HAS_DMA
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
help
SPI driver for SuperH and SH Mobile MSIOF blocks.
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 929c9f5eac01..762da0741148 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -61,6 +61,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_QUP) += spi-qup.o
+obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
spi-s3c24xx-hw-y := spi-s3c24xx.o
diff --git a/drivers/spi/spi-adi-v3.c b/drivers/spi/spi-adi-v3.c
index dcb2287c7f8a..19ea8fb78cc7 100644
--- a/drivers/spi/spi-adi-v3.c
+++ b/drivers/spi/spi-adi-v3.c
@@ -660,10 +660,9 @@ static int adi_spi_setup(struct spi_device *spi)
struct adi_spi3_chip *chip_info = spi->controller_data;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- dev_err(&spi->dev, "can not allocate chip data\n");
+ if (!chip)
return -ENOMEM;
- }
+
if (chip_info) {
if (chip_info->control & ~ctl_reg) {
dev_err(&spi->dev,
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 92a6f0d93233..113c83f44b5c 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -597,21 +597,15 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_master *master,
goto err_exit;
/* Send both scatterlists */
- rxdesc = rxchan->device->device_prep_slave_sg(rxchan,
- &as->dma.sgrx,
- 1,
- DMA_FROM_DEVICE,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
- NULL);
+ rxdesc = dmaengine_prep_slave_sg(rxchan, &as->dma.sgrx, 1,
+ DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!rxdesc)
goto err_dma;
- txdesc = txchan->device->device_prep_slave_sg(txchan,
- &as->dma.sgtx,
- 1,
- DMA_TO_DEVICE,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
- NULL);
+ txdesc = dmaengine_prep_slave_sg(txchan, &as->dma.sgtx, 1,
+ DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!txdesc)
goto err_dma;
@@ -1018,7 +1012,7 @@ static int atmel_spi_setup(struct spi_device *spi)
csr |= SPI_BF(DLYBCT, 0);
/* chipselect must have been muxed as GPIO (e.g. in board setup) */
- npcs_pin = (unsigned int)spi->controller_data;
+ npcs_pin = (unsigned long)spi->controller_data;
if (gpio_is_valid(spi->cs_gpio))
npcs_pin = spi->cs_gpio;
@@ -1253,7 +1247,7 @@ msg_done:
static void atmel_spi_cleanup(struct spi_device *spi)
{
struct atmel_spi_device *asd = spi->controller_state;
- unsigned gpio = (unsigned) spi->controller_data;
+ unsigned gpio = (unsigned long) spi->controller_data;
if (!asd)
return;
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c
index 67375a11d4bd..40c3d43c9292 100644
--- a/drivers/spi/spi-au1550.c
+++ b/drivers/spi/spi-au1550.c
@@ -141,13 +141,13 @@ static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw)
PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
| PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
| PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_spievent =
PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
| PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
| PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
- au_sync();
+ wmb(); /* drain writebuffer */
}
static void au1550_spi_reset_fifos(struct au1550_spi *hw)
@@ -155,10 +155,10 @@ static void au1550_spi_reset_fifos(struct au1550_spi *hw)
u32 pcr;
hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
- au_sync();
+ wmb(); /* drain writebuffer */
do {
pcr = hw->regs->psc_spipcr;
- au_sync();
+ wmb(); /* drain writebuffer */
} while (pcr != 0);
}
@@ -188,9 +188,9 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value)
au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
cfg = hw->regs->psc_spicfg;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
if (spi->mode & SPI_CPOL)
cfg |= PSC_SPICFG_BI;
@@ -218,10 +218,10 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value)
cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
do {
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
} while ((stat & PSC_SPISTAT_DR) == 0);
if (hw->pdata->activate_cs)
@@ -252,9 +252,9 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
cfg = hw->regs->psc_spicfg;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
if (hw->usedma && bpw <= 8)
cfg &= ~PSC_SPICFG_DD_DISABLE;
@@ -268,12 +268,12 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
cfg |= au1550_spi_baudcfg(hw, hz);
hw->regs->psc_spicfg = cfg;
- au_sync();
+ wmb(); /* drain writebuffer */
if (cfg & PSC_SPICFG_DE_ENABLE) {
do {
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
} while ((stat & PSC_SPISTAT_DR) == 0);
}
@@ -396,11 +396,11 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
/* by default enable nearly all events interrupt */
hw->regs->psc_spimsk = PSC_SPIMSK_SD;
- au_sync();
+ wmb(); /* drain writebuffer */
/* start the transfer */
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
- au_sync();
+ wmb(); /* drain writebuffer */
wait_for_completion(&hw->master_done);
@@ -429,7 +429,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
stat = hw->regs->psc_spistat;
evnt = hw->regs->psc_spievent;
- au_sync();
+ wmb(); /* drain writebuffer */
if ((stat & PSC_SPISTAT_DI) == 0) {
dev_err(hw->dev, "Unexpected IRQ!\n");
return IRQ_NONE;
@@ -484,7 +484,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \
{ \
u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \
- au_sync(); \
+ wmb(); /* drain writebuffer */ \
if (hw->rx) { \
*(u##size *)hw->rx = (u##size)fifoword; \
hw->rx += (size) / 8; \
@@ -504,7 +504,7 @@ static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \
if (hw->tx_count >= hw->len) \
fifoword |= PSC_SPITXRX_LC; \
hw->regs->psc_spitxrx = fifoword; \
- au_sync(); \
+ wmb(); /* drain writebuffer */ \
}
AU1550_SPI_RX_WORD(8,0xff)
@@ -539,18 +539,18 @@ static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
}
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
if (stat & PSC_SPISTAT_TF)
break;
}
/* enable event interrupts */
hw->regs->psc_spimsk = mask;
- au_sync();
+ wmb(); /* drain writebuffer */
/* start the transfer */
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
- au_sync();
+ wmb(); /* drain writebuffer */
wait_for_completion(&hw->master_done);
@@ -564,7 +564,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
stat = hw->regs->psc_spistat;
evnt = hw->regs->psc_spievent;
- au_sync();
+ wmb(); /* drain writebuffer */
if ((stat & PSC_SPISTAT_DI) == 0) {
dev_err(hw->dev, "Unexpected IRQ!\n");
return IRQ_NONE;
@@ -594,7 +594,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
do {
busy = 0;
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
/*
* Take care to not let the Rx FIFO overflow.
@@ -615,7 +615,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
} while (busy);
hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR;
- au_sync();
+ wmb(); /* drain writebuffer */
/*
* Restart the SPI transmission in case of a transmit underflow.
@@ -634,9 +634,9 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
*/
if (evnt & PSC_SPIEVNT_TU) {
hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_spipcr = PSC_SPIPCR_MS;
- au_sync();
+ wmb(); /* drain writebuffer */
}
if (hw->rx_count >= hw->len) {
@@ -690,19 +690,19 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
/* set up the PSC for SPI mode */
hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_spicfg = 0;
- au_sync();
+ wmb(); /* drain writebuffer */
hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
do {
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
} while ((stat & PSC_SPISTAT_SR) == 0);
@@ -717,16 +717,16 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
#endif
hw->regs->psc_spicfg = cfg;
- au_sync();
+ wmb(); /* drain writebuffer */
au1550_spi_mask_ack_all(hw);
hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
- au_sync();
+ wmb(); /* drain writebuffer */
do {
stat = hw->regs->psc_spistat;
- au_sync();
+ wmb(); /* drain writebuffer */
} while ((stat & PSC_SPISTAT_DR) == 0);
au1550_spi_reset_fifos(hw);
@@ -925,8 +925,7 @@ err_no_txdma:
iounmap((void __iomem *)hw->regs);
err_ioremap:
- release_resource(hw->ioarea);
- kfree(hw->ioarea);
+ release_mem_region(r->start, sizeof(psc_spi_t));
err_no_iores:
err_no_pdata:
@@ -946,8 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
spi_bitbang_stop(&hw->bitbang);
free_irq(hw->irq, hw);
iounmap((void __iomem *)hw->regs);
- release_resource(hw->ioarea);
- kfree(hw->ioarea);
+ release_mem_region(r->start, sizeof(psc_spi_t));
if (hw->usedma) {
au1550_spi_dma_rxtmp_free(hw);
diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index bb758978465d..562ff83debd9 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
static void cdns_spi_config_clock_mode(struct spi_device *spi)
{
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
- u32 ctrl_reg;
+ u32 ctrl_reg, new_ctrl_reg;
- ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
+ new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
/* Set the SPI clock phase and clock polarity */
- ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
+ new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
if (spi->mode & SPI_CPHA)
- ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
+ new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
if (spi->mode & SPI_CPOL)
- ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
-
- cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg);
+ new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
+
+ if (new_ctrl_reg != ctrl_reg) {
+ /*
+ * Just writing the CR register does not seem to apply the clock
+ * setting changes. This is problematic when changing the clock
+ * polarity as it will cause the SPI slave to see spurious clock
+ * transitions. To workaround the issue toggle the ER register.
+ */
+ cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
+ CDNS_SPI_ER_DISABLE_MASK);
+ cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg);
+ cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
+ CDNS_SPI_ER_ENABLE_MASK);
+ }
}
/**
@@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
return status;
}
+static int cdns_prepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ cdns_spi_config_clock_mode(msg->spi);
+ return 0;
+}
/**
* cdns_transfer_one - Initiates the SPI transfer
@@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
{
struct cdns_spi *xspi = spi_master_get_devdata(master);
- cdns_spi_config_clock_mode(master->cur_msg->spi);
-
cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_ENABLE_MASK);
@@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
xspi->is_decoded_cs = 0;
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
+ master->prepare_message = cdns_prepare_message;
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;
@@ -647,7 +664,7 @@ static int __maybe_unused cdns_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
cdns_spi_resume);
-static struct of_device_id cdns_spi_of_match[] = {
+static const struct of_device_id cdns_spi_of_match[] = {
{ .compatible = "xlnx,zynq-spi-r1p6" },
{ .compatible = "cdns,spi-r1p6" },
{ /* end of table */ }
diff --git a/drivers/spi/spi-clps711x.c b/drivers/spi/spi-clps711x.c
index 4cd62f636547..ce538dad526b 100644
--- a/drivers/spi/spi-clps711x.c
+++ b/drivers/spi/spi-clps711x.c
@@ -184,8 +184,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
}
master->max_speed_hz = clk_get_rate(hw->spi_clk);
- platform_set_drvdata(pdev, master);
-
hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3");
if (IS_ERR(hw->syscon)) {
ret = PTR_ERR(hw->syscon);
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 50f750989258..276a3884fb3c 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -30,6 +30,7 @@
#include <linux/edma.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/slab.h>
@@ -38,8 +39,6 @@
#define SPI_NO_RESOURCE ((resource_size_t)-1)
-#define SPI_MAX_CHIPSELECT 2
-
#define CS_DEFAULT 0xFF
#define SPIFMT_PHASE_MASK BIT(16)
@@ -142,7 +141,7 @@ struct davinci_spi {
void (*get_rx)(u32 rx_data, struct davinci_spi *);
u32 (*get_tx)(struct davinci_spi *);
- u8 bytes_per_word[SPI_MAX_CHIPSELECT];
+ u8 *bytes_per_word;
};
static struct davinci_spi_config davinci_spi_default_cfg;
@@ -213,13 +212,16 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
u8 chip_sel = spi->chip_select;
u16 spidat1 = CS_DEFAULT;
bool gpio_chipsel = false;
+ int gpio;
dspi = spi_master_get_devdata(spi->master);
pdata = &dspi->pdata;
- if (pdata->chip_sel && chip_sel < pdata->num_chipselect &&
- pdata->chip_sel[chip_sel] != SPI_INTERN_CS)
+ if (spi->cs_gpio >= 0) {
+ /* SPI core parse and update master->cs_gpio */
gpio_chipsel = true;
+ gpio = spi->cs_gpio;
+ }
/*
* Board specific chip select logic decides the polarity and cs
@@ -227,9 +229,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
*/
if (gpio_chipsel) {
if (value == BITBANG_CS_ACTIVE)
- gpio_set_value(pdata->chip_sel[chip_sel], 0);
+ gpio_set_value(gpio, spi->mode & SPI_CS_HIGH);
else
- gpio_set_value(pdata->chip_sel[chip_sel], 1);
+ gpio_set_value(gpio, !(spi->mode & SPI_CS_HIGH));
} else {
if (value == BITBANG_CS_ACTIVE) {
spidat1 |= SPIDAT1_CSHOLD_MASK;
@@ -392,17 +394,40 @@ static int davinci_spi_setup(struct spi_device *spi)
int retval = 0;
struct davinci_spi *dspi;
struct davinci_spi_platform_data *pdata;
+ struct spi_master *master = spi->master;
+ struct device_node *np = spi->dev.of_node;
+ bool internal_cs = true;
+ unsigned long flags = GPIOF_DIR_OUT;
dspi = spi_master_get_devdata(spi->master);
pdata = &dspi->pdata;
+ flags |= (spi->mode & SPI_CS_HIGH) ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH;
+
if (!(spi->mode & SPI_NO_CS)) {
- if ((pdata->chip_sel == NULL) ||
- (pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS))
- set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
+ if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) {
+ retval = gpio_request_one(spi->cs_gpio,
+ flags, dev_name(&spi->dev));
+ internal_cs = false;
+ } else if (pdata->chip_sel &&
+ spi->chip_select < pdata->num_chipselect &&
+ pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) {
+ spi->cs_gpio = pdata->chip_sel[spi->chip_select];
+ retval = gpio_request_one(spi->cs_gpio,
+ flags, dev_name(&spi->dev));
+ internal_cs = false;
+ }
+ }
+ if (retval) {
+ dev_err(&spi->dev, "GPIO %d setup failed (%d)\n",
+ spi->cs_gpio, retval);
+ return retval;
}
+ if (internal_cs)
+ set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select);
+
if (spi->mode & SPI_READY)
set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK);
@@ -414,6 +439,12 @@ static int davinci_spi_setup(struct spi_device *spi)
return retval;
}
+static void davinci_spi_cleanup(struct spi_device *spi)
+{
+ if (spi->cs_gpio >= 0)
+ gpio_free(spi->cs_gpio);
+}
+
static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
{
struct device *sdev = dspi->bitbang.master->dev.parent;
@@ -812,6 +843,8 @@ static int spi_davinci_get_pdata(struct platform_device *pdev,
/*
* default num_cs is 1 and all chipsel are internal to the chip
+ * indicated by chip_sel being NULL or cs_gpios being NULL or
+ * set to -ENOENT. num-cs includes internal as well as gpios.
* indicated by chip_sel being NULL. GPIO based CS is not
* supported yet in DT bindings.
*/
@@ -850,7 +883,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
struct resource *r;
resource_size_t dma_rx_chan = SPI_NO_RESOURCE;
resource_size_t dma_tx_chan = SPI_NO_RESOURCE;
- int i = 0, ret = 0;
+ int ret = 0;
u32 spipc0;
master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi));
@@ -876,6 +909,14 @@ static int davinci_spi_probe(struct platform_device *pdev)
/* pdata in dspi is now updated and point pdata to that */
pdata = &dspi->pdata;
+ dspi->bytes_per_word = devm_kzalloc(&pdev->dev,
+ sizeof(*dspi->bytes_per_word) *
+ pdata->num_chipselect, GFP_KERNEL);
+ if (dspi->bytes_per_word == NULL) {
+ ret = -ENOMEM;
+ goto free_master;
+ }
+
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
ret = -ENOENT;
@@ -915,6 +956,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
master->num_chipselect = pdata->num_chipselect;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
master->setup = davinci_spi_setup;
+ master->cleanup = davinci_spi_cleanup;
dspi->bitbang.chipselect = davinci_spi_chipselect;
dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;
@@ -962,14 +1004,6 @@ static int davinci_spi_probe(struct platform_device *pdev)
spipc0 = SPIPC0_DIFUN_MASK | SPIPC0_DOFUN_MASK | SPIPC0_CLKFUN_MASK;
iowrite32(spipc0, dspi->base + SPIPC0);
- /* initialize chip selects */
- if (pdata->chip_sel) {
- for (i = 0; i < pdata->num_chipselect; i++) {
- if (pdata->chip_sel[i] != SPI_INTERN_CS)
- gpio_direction_output(pdata->chip_sel[i], 1);
- }
- }
-
if (pdata->intr_line)
iowrite32(SPI_INTLVL_1, dspi->base + SPILVL);
else
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
index a5cba14ac3d2..21ce0e36fa00 100644
--- a/drivers/spi/spi-dw-mmio.c
+++ b/drivers/spi/spi-dw-mmio.c
@@ -16,7 +16,9 @@
#include <linux/spi/spi.h>
#include <linux/scatterlist.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
#include "spi-dw.h"
@@ -33,6 +35,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
struct dw_spi *dws;
struct resource *mem;
int ret;
+ int num_cs;
dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
GFP_KERNEL);
@@ -68,9 +71,16 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
return ret;
dws->bus_num = pdev->id;
- dws->num_cs = 4;
+
dws->max_freq = clk_get_rate(dwsmmio->clk);
+ num_cs = 4;
+
+ if (pdev->dev.of_node)
+ of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
+
+ dws->num_cs = num_cs;
+
if (pdev->dev.of_node) {
int i;
@@ -114,12 +124,19 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id dw_spi_mmio_of_match[] = {
+ { .compatible = "snps,dw-apb-ssi", },
+ { /* end of table */}
+};
+MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
+
static struct platform_driver dw_spi_mmio_driver = {
.probe = dw_spi_mmio_probe,
.remove = dw_spi_mmio_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = dw_spi_mmio_of_match,
},
};
module_platform_driver(dw_spi_mmio_driver);
diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c
index be44a3eeb5e8..6caeb1cac0f3 100644
--- a/drivers/spi/spi-efm32.c
+++ b/drivers/spi/spi-efm32.c
@@ -294,10 +294,16 @@ static void efm32_spi_probe_dt(struct platform_device *pdev,
u32 location;
int ret;
- ret = of_property_read_u32(np, "efm32,location", &location);
+ ret = of_property_read_u32(np, "energymicro,location", &location);
+
+ if (ret)
+ /* fall back to wrongly namespaced property */
+ ret = of_property_read_u32(np, "efm32,location", &location);
+
if (ret)
/* fall back to old and (wrongly) generic property "location" */
ret = of_property_read_u32(np, "location", &location);
+
if (!ret) {
dev_dbg(&pdev->dev, "using location %u\n", location);
} else {
diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c
index ba441ad9a007..f73b3004d6d3 100644
--- a/drivers/spi/spi-falcon.c
+++ b/drivers/spi/spi-falcon.c
@@ -425,8 +425,6 @@ static int falcon_sflash_probe(struct platform_device *pdev)
master->unprepare_transfer_hardware = falcon_sflash_unprepare_xfer;
master->dev.of_node = pdev->dev.of_node;
- platform_set_drvdata(pdev, priv);
-
ret = devm_spi_register_master(&pdev->dev, master);
if (ret)
spi_master_put(master);
diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c
index 95212ea96c8d..e0b773fc29cb 100644
--- a/drivers/spi/spi-fsl-lib.c
+++ b/drivers/spi/spi-fsl-lib.c
@@ -196,7 +196,7 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)
pinfo = devm_kzalloc(&ofdev->dev, sizeof(*pinfo), GFP_KERNEL);
if (!pinfo)
- return -ENOMEM;
+ return ret;
pdata = &pinfo->pdata;
dev->platform_data = pdata;
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 98ccd231bf00..9452f6740997 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -58,7 +58,7 @@ static struct fsl_spi_match_data of_fsl_spi_grlib_config = {
.type = TYPE_GRLIB,
};
-static struct of_device_id of_fsl_spi_match[] = {
+static const struct of_device_id of_fsl_spi_match[] = {
{
.compatible = "fsl,spi",
.data = &of_fsl_spi_fsl_config,
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index e7ffcded4e14..5e91858f6f01 100644
--- a/drivers/spi/spi-omap-100k.c
+++ b/drivers/spi/spi-omap-100k.c
@@ -420,8 +420,6 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
master->min_speed_hz = OMAP1_SPI100K_MAX_FREQ/(1<<16);
master->max_speed_hz = OMAP1_SPI100K_MAX_FREQ;
- platform_set_drvdata(pdev, master);
-
spi100k = spi_master_get_devdata(master);
/*
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c
index 0f5a0aa3b871..8bca90a19dd1 100644
--- a/drivers/spi/spi-omap-uwire.c
+++ b/drivers/spi/spi-omap-uwire.c
@@ -41,14 +41,15 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/slab.h>
+#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/module.h>
+#include <linux/io.h>
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/mach-types.h>
#include <mach/mux.h>
@@ -447,7 +448,6 @@ static void uwire_off(struct uwire_spi *uwire)
{
uwire_write_reg(UWIRE_SR3, 0);
clk_disable(uwire->ck);
- clk_put(uwire->ck);
spi_master_put(uwire->bitbang.master);
}
@@ -463,7 +463,7 @@ static int uwire_probe(struct platform_device *pdev)
uwire = spi_master_get_devdata(master);
- uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
+ uwire_base = devm_ioremap(&pdev->dev, UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
if (!uwire_base) {
dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");
spi_master_put(master);
@@ -472,12 +472,11 @@ static int uwire_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, uwire);
- uwire->ck = clk_get(&pdev->dev, "fck");
+ uwire->ck = devm_clk_get(&pdev->dev, "fck");
if (IS_ERR(uwire->ck)) {
status = PTR_ERR(uwire->ck);
dev_dbg(&pdev->dev, "no functional clock?\n");
spi_master_put(master);
- iounmap(uwire_base);
return status;
}
clk_enable(uwire->ck);
@@ -507,7 +506,6 @@ static int uwire_probe(struct platform_device *pdev)
status = spi_bitbang_start(&uwire->bitbang);
if (status < 0) {
uwire_off(uwire);
- iounmap(uwire_base);
}
return status;
}
@@ -520,7 +518,6 @@ static int uwire_remove(struct platform_device *pdev)
spi_bitbang_stop(&uwire->bitbang);
uwire_off(uwire);
- iounmap(uwire_base);
return 0;
}
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 4dc77df38864..68441fa448de 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -149,6 +149,7 @@ struct omap2_mcspi_cs {
void __iomem *base;
unsigned long phys;
int word_len;
+ u16 mode;
struct list_head node;
/* Context save and restore shadow register */
u32 chconf0, chctrl0;
@@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
mcspi_write_chconf0(spi, l);
+ cs->mode = spi->mode;
+
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
speed_hz,
(spi->mode & SPI_CPHA) ? "trailing" : "leading",
@@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14;
cs->phys = mcspi->phys + spi->chip_select * 0x14;
+ cs->mode = 0;
cs->chconf0 = 0;
cs->chctrl0 = 0;
spi->controller_state = cs;
@@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
cs = spi->controller_state;
cd = spi->controller_data;
+ /*
+ * The slave driver could have changed spi->mode in which case
+ * it will be different from cs->mode (the current hardware setup).
+ * If so, set par_override (even though its not a parity issue) so
+ * omap2_mcspi_setup_transfer will be called to configure the hardware
+ * with the correct mode on the first iteration of the loop below.
+ */
+ if (spi->mode != cs->mode)
+ par_override = 1;
+
omap2_mcspi_set_enable(spi, 0);
list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index d018a4aac3a1..c4675fa8b645 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -16,6 +16,7 @@
#include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/sizes.h>
@@ -23,6 +24,9 @@
#define DRIVER_NAME "orion_spi"
+/* Runtime PM autosuspend timeout: PM is fairly light on this driver */
+#define SPI_AUTOSUSPEND_TIMEOUT 200
+
#define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/
#define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */
@@ -277,7 +281,6 @@ out:
return xfer->len - count;
}
-
static int orion_spi_transfer_one_message(struct spi_master *master,
struct spi_message *m)
{
@@ -346,8 +349,6 @@ static int orion_spi_probe(struct platform_device *pdev)
struct resource *r;
unsigned long tclk_hz;
int status = 0;
- const u32 *iprop;
- int size;
master = spi_alloc_master(&pdev->dev, sizeof(*spi));
if (master == NULL) {
@@ -358,10 +359,10 @@ static int orion_spi_probe(struct platform_device *pdev)
if (pdev->id != -1)
master->bus_num = pdev->id;
if (pdev->dev.of_node) {
- iprop = of_get_property(pdev->dev.of_node, "cell-index",
- &size);
- if (iprop && size == sizeof(*iprop))
- master->bus_num = *iprop;
+ u32 cell_index;
+ if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
+ &cell_index))
+ master->bus_num = cell_index;
}
/* we support only mode 0, and no options */
@@ -370,6 +371,7 @@ static int orion_spi_probe(struct platform_device *pdev)
master->transfer_one_message = orion_spi_transfer_one_message;
master->num_chipselect = ORION_NUM_CHIPSELECTS;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+ master->auto_runtime_pm = true;
platform_set_drvdata(pdev, master);
@@ -382,8 +384,10 @@ static int orion_spi_probe(struct platform_device *pdev)
goto out;
}
- clk_prepare(spi->clk);
- clk_enable(spi->clk);
+ status = clk_prepare_enable(spi->clk);
+ if (status)
+ goto out;
+
tclk_hz = clk_get_rate(spi->clk);
master->max_speed_hz = DIV_ROUND_UP(tclk_hz, 4);
master->min_speed_hz = DIV_ROUND_UP(tclk_hz, 30);
@@ -395,16 +399,27 @@ static int orion_spi_probe(struct platform_device *pdev)
goto out_rel_clk;
}
- if (orion_spi_reset(spi) < 0)
- goto out_rel_clk;
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
+ pm_runtime_enable(&pdev->dev);
+
+ status = orion_spi_reset(spi);
+ if (status < 0)
+ goto out_rel_pm;
+
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_put_autosuspend(&pdev->dev);
master->dev.of_node = pdev->dev.of_node;
- status = devm_spi_register_master(&pdev->dev, master);
+ status = spi_register_master(master);
if (status < 0)
- goto out_rel_clk;
+ goto out_rel_pm;
return status;
+out_rel_pm:
+ pm_runtime_disable(&pdev->dev);
out_rel_clk:
clk_disable_unprepare(spi->clk);
out:
@@ -415,19 +430,45 @@ out:
static int orion_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master;
- struct orion_spi *spi;
-
- master = platform_get_drvdata(pdev);
- spi = spi_master_get_devdata(master);
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct orion_spi *spi = spi_master_get_devdata(master);
+ pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(spi->clk);
+ spi_unregister_master(master);
+ pm_runtime_disable(&pdev->dev);
+
return 0;
}
MODULE_ALIAS("platform:" DRIVER_NAME);
+#ifdef CONFIG_PM_RUNTIME
+static int orion_spi_runtime_suspend(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct orion_spi *spi = spi_master_get_devdata(master);
+
+ clk_disable_unprepare(spi->clk);
+ return 0;
+}
+
+static int orion_spi_runtime_resume(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct orion_spi *spi = spi_master_get_devdata(master);
+
+ return clk_prepare_enable(spi->clk);
+}
+#endif
+
+static const struct dev_pm_ops orion_spi_pm_ops = {
+ SET_RUNTIME_PM_OPS(orion_spi_runtime_suspend,
+ orion_spi_runtime_resume,
+ NULL)
+};
+
static const struct of_device_id orion_spi_of_match_table[] = {
{ .compatible = "marvell,orion-spi", },
{}
@@ -438,6 +479,7 @@ static struct platform_driver orion_spi_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .pm = &orion_spi_pm_ops,
.of_match_table = of_match_ptr(orion_spi_of_match_table),
},
.probe = orion_spi_probe,
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 66d2ae21e78e..1189cfd96477 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1417,7 +1417,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022)
* Default is to enable all interrupts except RX -
* this will be enabled once TX is complete
*/
- u32 irqflags = ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM;
+ u32 irqflags = (u32)(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM);
/* Enable target chip, if not already active */
if (!pl022->next_msg_cs_active)
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index c08da380cb23..9f83d2950748 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -142,6 +142,7 @@ struct spi_qup {
int w_size; /* bytes per SPI word */
int tx_bytes;
int rx_bytes;
+ int qup_v1;
};
@@ -420,7 +421,9 @@ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
config |= QUP_CONFIG_SPI_MODE;
writel_relaxed(config, controller->base + QUP_CONFIG);
- writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
+ /* only write to OPERATIONAL_MASK when register is present */
+ if (!controller->qup_v1)
+ writel_relaxed(0, controller->base + QUP_OPERATIONAL_MASK);
return 0;
}
@@ -486,7 +489,7 @@ static int spi_qup_probe(struct platform_device *pdev)
struct resource *res;
struct device *dev;
void __iomem *base;
- u32 data, max_freq, iomode;
+ u32 max_freq, iomode;
int ret, irq, size;
dev = &pdev->dev;
@@ -529,15 +532,6 @@ static int spi_qup_probe(struct platform_device *pdev)
return ret;
}
- data = readl_relaxed(base + QUP_HW_VERSION);
-
- if (data < QUP_HW_VERSION_2_1_1) {
- clk_disable_unprepare(cclk);
- clk_disable_unprepare(iclk);
- dev_err(dev, "v.%08x is not supported\n", data);
- return -ENXIO;
- }
-
master = spi_alloc_master(dev, sizeof(struct spi_qup));
if (!master) {
clk_disable_unprepare(cclk);
@@ -570,6 +564,10 @@ static int spi_qup_probe(struct platform_device *pdev)
controller->cclk = cclk;
controller->irq = irq;
+ /* set v1 flag if device is version 1 */
+ if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
+ controller->qup_v1 = 1;
+
spin_lock_init(&controller->lock);
init_completion(&controller->done);
@@ -593,8 +591,8 @@ static int spi_qup_probe(struct platform_device *pdev)
size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
controller->in_fifo_sz = controller->in_blk_sz * (2 << size);
- dev_info(dev, "v.%08x IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
- data, controller->in_blk_sz, controller->in_fifo_sz,
+ dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
+ controller->in_blk_sz, controller->in_fifo_sz,
controller->out_blk_sz, controller->out_fifo_sz);
writel_relaxed(1, base + QUP_SW_RESET);
@@ -607,10 +605,19 @@ static int spi_qup_probe(struct platform_device *pdev)
writel_relaxed(0, base + QUP_OPERATIONAL);
writel_relaxed(0, base + QUP_IO_M_MODES);
- writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
+
+ if (!controller->qup_v1)
+ writel_relaxed(0, base + QUP_OPERATIONAL_MASK);
+
writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
base + SPI_ERROR_FLAGS_EN);
+ /* if earlier version of the QUP, disable INPUT_OVERRUN */
+ if (controller->qup_v1)
+ writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
+ QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
+ base + QUP_ERROR_FLAGS_EN);
+
writel_relaxed(0, base + SPI_CONFIG);
writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
@@ -732,6 +739,7 @@ static int spi_qup_remove(struct platform_device *pdev)
}
static const struct of_device_id spi_qup_dt_match[] = {
+ { .compatible = "qcom,spi-qup-v1.1.1", },
{ .compatible = "qcom,spi-qup-v2.1.1", },
{ .compatible = "qcom,spi-qup-v2.2.1", },
{ }
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
new file mode 100644
index 000000000000..c0743604b906
--- /dev/null
+++ b/drivers/spi/spi-rockchip.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Addy Ke <addy.ke@rock-chips.com>
+ *
+ * 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 it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/scatterlist.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/dmaengine.h>
+
+#define DRIVER_NAME "rockchip-spi"
+
+/* SPI register offsets */
+#define ROCKCHIP_SPI_CTRLR0 0x0000
+#define ROCKCHIP_SPI_CTRLR1 0x0004
+#define ROCKCHIP_SPI_SSIENR 0x0008
+#define ROCKCHIP_SPI_SER 0x000c
+#define ROCKCHIP_SPI_BAUDR 0x0010
+#define ROCKCHIP_SPI_TXFTLR 0x0014
+#define ROCKCHIP_SPI_RXFTLR 0x0018
+#define ROCKCHIP_SPI_TXFLR 0x001c
+#define ROCKCHIP_SPI_RXFLR 0x0020
+#define ROCKCHIP_SPI_SR 0x0024
+#define ROCKCHIP_SPI_IPR 0x0028
+#define ROCKCHIP_SPI_IMR 0x002c
+#define ROCKCHIP_SPI_ISR 0x0030
+#define ROCKCHIP_SPI_RISR 0x0034
+#define ROCKCHIP_SPI_ICR 0x0038
+#define ROCKCHIP_SPI_DMACR 0x003c
+#define ROCKCHIP_SPI_DMATDLR 0x0040
+#define ROCKCHIP_SPI_DMARDLR 0x0044
+#define ROCKCHIP_SPI_TXDR 0x0400
+#define ROCKCHIP_SPI_RXDR 0x0800
+
+/* Bit fields in CTRLR0 */
+#define CR0_DFS_OFFSET 0
+
+#define CR0_CFS_OFFSET 2
+
+#define CR0_SCPH_OFFSET 6
+
+#define CR0_SCPOL_OFFSET 7
+
+#define CR0_CSM_OFFSET 8
+#define CR0_CSM_KEEP 0x0
+/* ss_n be high for half sclk_out cycles */
+#define CR0_CSM_HALF 0X1
+/* ss_n be high for one sclk_out cycle */
+#define CR0_CSM_ONE 0x2
+
+/* ss_n to sclk_out delay */
+#define CR0_SSD_OFFSET 10
+/*
+ * The period between ss_n active and
+ * sclk_out active is half sclk_out cycles
+ */
+#define CR0_SSD_HALF 0x0
+/*
+ * The period between ss_n active and
+ * sclk_out active is one sclk_out cycle
+ */
+#define CR0_SSD_ONE 0x1
+
+#define CR0_EM_OFFSET 11
+#define CR0_EM_LITTLE 0x0
+#define CR0_EM_BIG 0x1
+
+#define CR0_FBM_OFFSET 12
+#define CR0_FBM_MSB 0x0
+#define CR0_FBM_LSB 0x1
+
+#define CR0_BHT_OFFSET 13
+#define CR0_BHT_16BIT 0x0
+#define CR0_BHT_8BIT 0x1
+
+#define CR0_RSD_OFFSET 14
+
+#define CR0_FRF_OFFSET 16
+#define CR0_FRF_SPI 0x0
+#define CR0_FRF_SSP 0x1
+#define CR0_FRF_MICROWIRE 0x2
+
+#define CR0_XFM_OFFSET 18
+#define CR0_XFM_MASK (0x03 << SPI_XFM_OFFSET)
+#define CR0_XFM_TR 0x0
+#define CR0_XFM_TO 0x1
+#define CR0_XFM_RO 0x2
+
+#define CR0_OPM_OFFSET 20
+#define CR0_OPM_MASTER 0x0
+#define CR0_OPM_SLAVE 0x1
+
+#define CR0_MTM_OFFSET 0x21
+
+/* Bit fields in SER, 2bit */
+#define SER_MASK 0x3
+
+/* Bit fields in SR, 5bit */
+#define SR_MASK 0x1f
+#define SR_BUSY (1 << 0)
+#define SR_TF_FULL (1 << 1)
+#define SR_TF_EMPTY (1 << 2)
+#define SR_RF_EMPTY (1 << 3)
+#define SR_RF_FULL (1 << 4)
+
+/* Bit fields in ISR, IMR, ISR, RISR, 5bit */
+#define INT_MASK 0x1f
+#define INT_TF_EMPTY (1 << 0)
+#define INT_TF_OVERFLOW (1 << 1)
+#define INT_RF_UNDERFLOW (1 << 2)
+#define INT_RF_OVERFLOW (1 << 3)
+#define INT_RF_FULL (1 << 4)
+
+/* Bit fields in ICR, 4bit */
+#define ICR_MASK 0x0f
+#define ICR_ALL (1 << 0)
+#define ICR_RF_UNDERFLOW (1 << 1)
+#define ICR_RF_OVERFLOW (1 << 2)
+#define ICR_TF_OVERFLOW (1 << 3)
+
+/* Bit fields in DMACR */
+#define RF_DMA_EN (1 << 0)
+#define TF_DMA_EN (1 << 1)
+
+#define RXBUSY (1 << 0)
+#define TXBUSY (1 << 1)
+
+enum rockchip_ssi_type {
+ SSI_MOTO_SPI = 0,
+ SSI_TI_SSP,
+ SSI_NS_MICROWIRE,
+};
+
+struct rockchip_spi_dma_data {
+ struct dma_chan *ch;
+ enum dma_transfer_direction direction;
+ dma_addr_t addr;
+};
+
+struct rockchip_spi {
+ struct device *dev;
+ struct spi_master *master;
+
+ struct clk *spiclk;
+ struct clk *apb_pclk;
+
+ void __iomem *regs;
+ /*depth of the FIFO buffer */
+ u32 fifo_len;
+ /* max bus freq supported */
+ u32 max_freq;
+ /* supported slave numbers */
+ enum rockchip_ssi_type type;
+
+ u16 mode;
+ u8 tmode;
+ u8 bpw;
+ u8 n_bytes;
+ unsigned len;
+ u32 speed;
+
+ const void *tx;
+ const void *tx_end;
+ void *rx;
+ void *rx_end;
+
+ u32 state;
+ /* protect state */
+ spinlock_t lock;
+
+ struct completion xfer_completion;
+
+ u32 use_dma;
+ struct sg_table tx_sg;
+ struct sg_table rx_sg;
+ struct rockchip_spi_dma_data dma_rx;
+ struct rockchip_spi_dma_data dma_tx;
+};
+
+static inline void spi_enable_chip(struct rockchip_spi *rs, int enable)
+{
+ writel_relaxed((enable ? 1 : 0), rs->regs + ROCKCHIP_SPI_SSIENR);
+}
+
+static inline void spi_set_clk(struct rockchip_spi *rs, u16 div)
+{
+ writel_relaxed(div, rs->regs + ROCKCHIP_SPI_BAUDR);
+}
+
+static inline void flush_fifo(struct rockchip_spi *rs)
+{
+ while (readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR))
+ readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
+}
+
+static inline void wait_for_idle(struct rockchip_spi *rs)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(5);
+
+ do {
+ if (!(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY))
+ return;
+ } while (time_before(jiffies, timeout));
+
+ dev_warn(rs->dev, "spi controller is in busy state!\n");
+}
+
+static u32 get_fifo_len(struct rockchip_spi *rs)
+{
+ u32 fifo;
+
+ for (fifo = 2; fifo < 32; fifo++) {
+ writel_relaxed(fifo, rs->regs + ROCKCHIP_SPI_TXFTLR);
+ if (fifo != readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFTLR))
+ break;
+ }
+
+ writel_relaxed(0, rs->regs + ROCKCHIP_SPI_TXFTLR);
+
+ return (fifo == 31) ? 0 : fifo;
+}
+
+static inline u32 tx_max(struct rockchip_spi *rs)
+{
+ u32 tx_left, tx_room;
+
+ tx_left = (rs->tx_end - rs->tx) / rs->n_bytes;
+ tx_room = rs->fifo_len - readl_relaxed(rs->regs + ROCKCHIP_SPI_TXFLR);
+
+ return min(tx_left, tx_room);
+}
+
+static inline u32 rx_max(struct rockchip_spi *rs)
+{
+ u32 rx_left = (rs->rx_end - rs->rx) / rs->n_bytes;
+ u32 rx_room = (u32)readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR);
+
+ return min(rx_left, rx_room);
+}
+
+static void rockchip_spi_set_cs(struct spi_device *spi, bool enable)
+{
+ u32 ser;
+ struct rockchip_spi *rs = spi_master_get_devdata(spi->master);
+
+ ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK;
+
+ /*
+ * drivers/spi/spi.c:
+ * static void spi_set_cs(struct spi_device *spi, bool enable)
+ * {
+ * if (spi->mode & SPI_CS_HIGH)
+ * enable = !enable;
+ *
+ * if (spi->cs_gpio >= 0)
+ * gpio_set_value(spi->cs_gpio, !enable);
+ * else if (spi->master->set_cs)
+ * spi->master->set_cs(spi, !enable);
+ * }
+ *
+ * Note: enable(rockchip_spi_set_cs) = !enable(spi_set_cs)
+ */
+ if (!enable)
+ ser |= 1 << spi->chip_select;
+ else
+ ser &= ~(1 << spi->chip_select);
+
+ writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER);
+}
+
+static int rockchip_spi_prepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+ struct spi_device *spi = msg->spi;
+
+ rs->mode = spi->mode;
+
+ return 0;
+}
+
+static int rockchip_spi_unprepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ unsigned long flags;
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ spin_lock_irqsave(&rs->lock, flags);
+
+ /*
+ * For DMA mode, we need terminate DMA channel and flush
+ * fifo for the next transfer if DMA thansfer timeout.
+ * unprepare_message() was called by core if transfer complete
+ * or timeout. Maybe it is reasonable for error handling here.
+ */
+ if (rs->use_dma) {
+ if (rs->state & RXBUSY) {
+ dmaengine_terminate_all(rs->dma_rx.ch);
+ flush_fifo(rs);
+ }
+
+ if (rs->state & TXBUSY)
+ dmaengine_terminate_all(rs->dma_tx.ch);
+ }
+
+ spin_unlock_irqrestore(&rs->lock, flags);
+
+ return 0;
+}
+
+static void rockchip_spi_pio_writer(struct rockchip_spi *rs)
+{
+ u32 max = tx_max(rs);
+ u32 txw = 0;
+
+ while (max--) {
+ if (rs->n_bytes == 1)
+ txw = *(u8 *)(rs->tx);
+ else
+ txw = *(u16 *)(rs->tx);
+
+ writel_relaxed(txw, rs->regs + ROCKCHIP_SPI_TXDR);
+ rs->tx += rs->n_bytes;
+ }
+}
+
+static void rockchip_spi_pio_reader(struct rockchip_spi *rs)
+{
+ u32 max = rx_max(rs);
+ u32 rxw;
+
+ while (max--) {
+ rxw = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXDR);
+ if (rs->n_bytes == 1)
+ *(u8 *)(rs->rx) = (u8)rxw;
+ else
+ *(u16 *)(rs->rx) = (u16)rxw;
+ rs->rx += rs->n_bytes;
+ }
+}
+
+static int rockchip_spi_pio_transfer(struct rockchip_spi *rs)
+{
+ int remain = 0;
+
+ do {
+ if (rs->tx) {
+ remain = rs->tx_end - rs->tx;
+ rockchip_spi_pio_writer(rs);
+ }
+
+ if (rs->rx) {
+ remain = rs->rx_end - rs->rx;
+ rockchip_spi_pio_reader(rs);
+ }
+
+ cpu_relax();
+ } while (remain);
+
+ /* If tx, wait until the FIFO data completely. */
+ if (rs->tx)
+ wait_for_idle(rs);
+
+ return 0;
+}
+
+static void rockchip_spi_dma_rxcb(void *data)
+{
+ unsigned long flags;
+ struct rockchip_spi *rs = data;
+
+ spin_lock_irqsave(&rs->lock, flags);
+
+ rs->state &= ~RXBUSY;
+ if (!(rs->state & TXBUSY))
+ spi_finalize_current_transfer(rs->master);
+
+ spin_unlock_irqrestore(&rs->lock, flags);
+}
+
+static void rockchip_spi_dma_txcb(void *data)
+{
+ unsigned long flags;
+ struct rockchip_spi *rs = data;
+
+ /* Wait until the FIFO data completely. */
+ wait_for_idle(rs);
+
+ spin_lock_irqsave(&rs->lock, flags);
+
+ rs->state &= ~TXBUSY;
+ if (!(rs->state & RXBUSY))
+ spi_finalize_current_transfer(rs->master);
+
+ spin_unlock_irqrestore(&rs->lock, flags);
+}
+
+static int rockchip_spi_dma_transfer(struct rockchip_spi *rs)
+{
+ unsigned long flags;
+ struct dma_slave_config rxconf, txconf;
+ struct dma_async_tx_descriptor *rxdesc, *txdesc;
+
+ spin_lock_irqsave(&rs->lock, flags);
+ rs->state &= ~RXBUSY;
+ rs->state &= ~TXBUSY;
+ spin_unlock_irqrestore(&rs->lock, flags);
+
+ if (rs->rx) {
+ rxconf.direction = rs->dma_rx.direction;
+ rxconf.src_addr = rs->dma_rx.addr;
+ rxconf.src_addr_width = rs->n_bytes;
+ rxconf.src_maxburst = rs->n_bytes;
+ dmaengine_slave_config(rs->dma_rx.ch, &rxconf);
+
+ rxdesc = dmaengine_prep_slave_sg(
+ rs->dma_rx.ch,
+ rs->rx_sg.sgl, rs->rx_sg.nents,
+ rs->dma_rx.direction, DMA_PREP_INTERRUPT);
+
+ rxdesc->callback = rockchip_spi_dma_rxcb;
+ rxdesc->callback_param = rs;
+ }
+
+ if (rs->tx) {
+ txconf.direction = rs->dma_tx.direction;
+ txconf.dst_addr = rs->dma_tx.addr;
+ txconf.dst_addr_width = rs->n_bytes;
+ txconf.dst_maxburst = rs->n_bytes;
+ dmaengine_slave_config(rs->dma_tx.ch, &txconf);
+
+ txdesc = dmaengine_prep_slave_sg(
+ rs->dma_tx.ch,
+ rs->tx_sg.sgl, rs->tx_sg.nents,
+ rs->dma_tx.direction, DMA_PREP_INTERRUPT);
+
+ txdesc->callback = rockchip_spi_dma_txcb;
+ txdesc->callback_param = rs;
+ }
+
+ /* rx must be started before tx due to spi instinct */
+ if (rs->rx) {
+ spin_lock_irqsave(&rs->lock, flags);
+ rs->state |= RXBUSY;
+ spin_unlock_irqrestore(&rs->lock, flags);
+ dmaengine_submit(rxdesc);
+ dma_async_issue_pending(rs->dma_rx.ch);
+ }
+
+ if (rs->tx) {
+ spin_lock_irqsave(&rs->lock, flags);
+ rs->state |= TXBUSY;
+ spin_unlock_irqrestore(&rs->lock, flags);
+ dmaengine_submit(txdesc);
+ dma_async_issue_pending(rs->dma_tx.ch);
+ }
+
+ return 1;
+}
+
+static void rockchip_spi_config(struct rockchip_spi *rs)
+{
+ u32 div = 0;
+ u32 dmacr = 0;
+
+ u32 cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET)
+ | (CR0_SSD_ONE << CR0_SSD_OFFSET);
+
+ cr0 |= (rs->n_bytes << CR0_DFS_OFFSET);
+ cr0 |= ((rs->mode & 0x3) << CR0_SCPH_OFFSET);
+ cr0 |= (rs->tmode << CR0_XFM_OFFSET);
+ cr0 |= (rs->type << CR0_FRF_OFFSET);
+
+ if (rs->use_dma) {
+ if (rs->tx)
+ dmacr |= TF_DMA_EN;
+ if (rs->rx)
+ dmacr |= RF_DMA_EN;
+ }
+
+ /* div doesn't support odd number */
+ div = rs->max_freq / rs->speed;
+ div = (div + 1) & 0xfffe;
+
+ spi_enable_chip(rs, 0);
+
+ writel_relaxed(cr0, rs->regs + ROCKCHIP_SPI_CTRLR0);
+
+ writel_relaxed(rs->len - 1, rs->regs + ROCKCHIP_SPI_CTRLR1);
+ writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_TXFTLR);
+ writel_relaxed(rs->fifo_len / 2 - 1, rs->regs + ROCKCHIP_SPI_RXFTLR);
+
+ writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMATDLR);
+ writel_relaxed(0, rs->regs + ROCKCHIP_SPI_DMARDLR);
+ writel_relaxed(dmacr, rs->regs + ROCKCHIP_SPI_DMACR);
+
+ spi_set_clk(rs, div);
+
+ dev_dbg(rs->dev, "cr0 0x%x, div %d\n", cr0, div);
+
+ spi_enable_chip(rs, 1);
+}
+
+static int rockchip_spi_transfer_one(
+ struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *xfer)
+{
+ int ret = 0;
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ WARN_ON((readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
+
+ if (!xfer->tx_buf && !xfer->rx_buf) {
+ dev_err(rs->dev, "No buffer for transfer\n");
+ return -EINVAL;
+ }
+
+ rs->speed = xfer->speed_hz;
+ rs->bpw = xfer->bits_per_word;
+ rs->n_bytes = rs->bpw >> 3;
+
+ rs->tx = xfer->tx_buf;
+ rs->tx_end = rs->tx + xfer->len;
+ rs->rx = xfer->rx_buf;
+ rs->rx_end = rs->rx + xfer->len;
+ rs->len = xfer->len;
+
+ rs->tx_sg = xfer->tx_sg;
+ rs->rx_sg = xfer->rx_sg;
+
+ if (rs->tx && rs->rx)
+ rs->tmode = CR0_XFM_TR;
+ else if (rs->tx)
+ rs->tmode = CR0_XFM_TO;
+ else if (rs->rx)
+ rs->tmode = CR0_XFM_RO;
+
+ if (master->can_dma && master->can_dma(master, spi, xfer))
+ rs->use_dma = 1;
+ else
+ rs->use_dma = 0;
+
+ rockchip_spi_config(rs);
+
+ if (rs->use_dma)
+ ret = rockchip_spi_dma_transfer(rs);
+ else
+ ret = rockchip_spi_pio_transfer(rs);
+
+ return ret;
+}
+
+static bool rockchip_spi_can_dma(struct spi_master *master,
+ struct spi_device *spi,
+ struct spi_transfer *xfer)
+{
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ return (xfer->len > rs->fifo_len);
+}
+
+static int rockchip_spi_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct rockchip_spi *rs;
+ struct spi_master *master;
+ struct resource *mem;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct rockchip_spi));
+ if (!master)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, master);
+
+ rs = spi_master_get_devdata(master);
+ memset(rs, 0, sizeof(struct rockchip_spi));
+
+ /* Get basic io resource and map it */
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rs->regs = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(rs->regs)) {
+ ret = PTR_ERR(rs->regs);
+ goto err_ioremap_resource;
+ }
+
+ rs->apb_pclk = devm_clk_get(&pdev->dev, "apb_pclk");
+ if (IS_ERR(rs->apb_pclk)) {
+ dev_err(&pdev->dev, "Failed to get apb_pclk\n");
+ ret = PTR_ERR(rs->apb_pclk);
+ goto err_ioremap_resource;
+ }
+
+ rs->spiclk = devm_clk_get(&pdev->dev, "spiclk");
+ if (IS_ERR(rs->spiclk)) {
+ dev_err(&pdev->dev, "Failed to get spi_pclk\n");
+ ret = PTR_ERR(rs->spiclk);
+ goto err_ioremap_resource;
+ }
+
+ ret = clk_prepare_enable(rs->apb_pclk);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable apb_pclk\n");
+ goto err_ioremap_resource;
+ }
+
+ ret = clk_prepare_enable(rs->spiclk);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable spi_clk\n");
+ goto err_spiclk_enable;
+ }
+
+ spi_enable_chip(rs, 0);
+
+ rs->type = SSI_MOTO_SPI;
+ rs->master = master;
+ rs->dev = &pdev->dev;
+ rs->max_freq = clk_get_rate(rs->spiclk);
+
+ rs->fifo_len = get_fifo_len(rs);
+ if (!rs->fifo_len) {
+ dev_err(&pdev->dev, "Failed to get fifo length\n");
+ ret = -EINVAL;
+ goto err_get_fifo_len;
+ }
+
+ spin_lock_init(&rs->lock);
+
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
+ master->auto_runtime_pm = true;
+ master->bus_num = pdev->id;
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
+ master->num_chipselect = 2;
+ master->dev.of_node = pdev->dev.of_node;
+ master->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
+
+ master->set_cs = rockchip_spi_set_cs;
+ master->prepare_message = rockchip_spi_prepare_message;
+ master->unprepare_message = rockchip_spi_unprepare_message;
+ master->transfer_one = rockchip_spi_transfer_one;
+
+ rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx");
+ if (!rs->dma_tx.ch)
+ dev_warn(rs->dev, "Failed to request TX DMA channel\n");
+
+ rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx");
+ if (!rs->dma_rx.ch) {
+ if (rs->dma_tx.ch) {
+ dma_release_channel(rs->dma_tx.ch);
+ rs->dma_tx.ch = NULL;
+ }
+ dev_warn(rs->dev, "Failed to request RX DMA channel\n");
+ }
+
+ if (rs->dma_tx.ch && rs->dma_rx.ch) {
+ rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR);
+ rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR);
+ rs->dma_tx.direction = DMA_MEM_TO_DEV;
+ rs->dma_tx.direction = DMA_DEV_TO_MEM;
+
+ master->can_dma = rockchip_spi_can_dma;
+ master->dma_tx = rs->dma_tx.ch;
+ master->dma_rx = rs->dma_rx.ch;
+ }
+
+ ret = devm_spi_register_master(&pdev->dev, master);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register master\n");
+ goto err_register_master;
+ }
+
+ return 0;
+
+err_register_master:
+ if (rs->dma_tx.ch)
+ dma_release_channel(rs->dma_tx.ch);
+ if (rs->dma_rx.ch)
+ dma_release_channel(rs->dma_rx.ch);
+err_get_fifo_len:
+ clk_disable_unprepare(rs->spiclk);
+err_spiclk_enable:
+ clk_disable_unprepare(rs->apb_pclk);
+err_ioremap_resource:
+ spi_master_put(master);
+
+ return ret;
+}
+
+static int rockchip_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ pm_runtime_disable(&pdev->dev);
+
+ clk_disable_unprepare(rs->spiclk);
+ clk_disable_unprepare(rs->apb_pclk);
+
+ if (rs->dma_tx.ch)
+ dma_release_channel(rs->dma_tx.ch);
+ if (rs->dma_rx.ch)
+ dma_release_channel(rs->dma_rx.ch);
+
+ spi_master_put(master);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_spi_suspend(struct device *dev)
+{
+ int ret = 0;
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ ret = spi_master_suspend(rs->master);
+ if (ret)
+ return ret;
+
+ if (!pm_runtime_suspended(dev)) {
+ clk_disable_unprepare(rs->spiclk);
+ clk_disable_unprepare(rs->apb_pclk);
+ }
+
+ return ret;
+}
+
+static int rockchip_spi_resume(struct device *dev)
+{
+ int ret = 0;
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ if (!pm_runtime_suspended(dev)) {
+ ret = clk_prepare_enable(rs->apb_pclk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_prepare_enable(rs->spiclk);
+ if (ret < 0) {
+ clk_disable_unprepare(rs->apb_pclk);
+ return ret;
+ }
+ }
+
+ ret = spi_master_resume(rs->master);
+ if (ret < 0) {
+ clk_disable_unprepare(rs->spiclk);
+ clk_disable_unprepare(rs->apb_pclk);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_RUNTIME
+static int rockchip_spi_runtime_suspend(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ clk_disable_unprepare(rs->spiclk);
+ clk_disable_unprepare(rs->apb_pclk);
+
+ return 0;
+}
+
+static int rockchip_spi_runtime_resume(struct device *dev)
+{
+ int ret;
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct rockchip_spi *rs = spi_master_get_devdata(master);
+
+ ret = clk_prepare_enable(rs->apb_pclk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(rs->spiclk);
+ if (ret)
+ clk_disable_unprepare(rs->apb_pclk);
+
+ return ret;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops rockchip_spi_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume)
+ SET_RUNTIME_PM_OPS(rockchip_spi_runtime_suspend,
+ rockchip_spi_runtime_resume, NULL)
+};
+
+static const struct of_device_id rockchip_spi_dt_match[] = {
+ { .compatible = "rockchip,rk3066-spi", },
+ { .compatible = "rockchip,rk3188-spi", },
+ { .compatible = "rockchip,rk3288-spi", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
+
+static struct platform_driver rockchip_spi_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .pm = &rockchip_spi_pm,
+ .of_match_table = of_match_ptr(rockchip_spi_dt_match),
+ },
+ .probe = rockchip_spi_probe,
+ .remove = rockchip_spi_remove,
+};
+
+module_platform_driver(rockchip_spi_driver);
+
+MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>");
+MODULE_DESCRIPTION("ROCKCHIP SPI Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 10112745bb17..c850dfdfa9e3 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -477,7 +477,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
tx->sgl, tx->nents, DMA_TO_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx)
- return -EIO;
+ goto no_dma;
irq_mask |= SPCR_SPTIE;
}
@@ -486,7 +486,7 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
rx->sgl, rx->nents, DMA_FROM_DEVICE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx)
- return -EIO;
+ goto no_dma;
irq_mask |= SPCR_SPRIE;
}
@@ -540,6 +540,12 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
enable_irq(rspi->rx_irq);
return ret;
+
+no_dma:
+ pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
+ dev_driver_string(&rspi->master->dev),
+ dev_name(&rspi->master->dev));
+ return -EAGAIN;
}
static void rspi_receive_init(const struct rspi_data *rspi)
@@ -593,8 +599,10 @@ static int rspi_common_transfer(struct rspi_data *rspi,
if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
- return rspi_dma_transfer(rspi, &xfer->tx_sg,
- xfer->rx_buf ? &xfer->rx_sg : NULL);
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg,
+ xfer->rx_buf ? &xfer->rx_sg : NULL);
+ if (ret != -EAGAIN)
+ return ret;
}
ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
@@ -630,7 +638,6 @@ static int rspi_rz_transfer_one(struct spi_master *master,
struct spi_transfer *xfer)
{
struct rspi_data *rspi = spi_master_get_devdata(master);
- int ret;
rspi_rz_receive_init(rspi);
@@ -649,8 +656,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
{
int ret;
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
- return rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
+ ret = rspi_dma_transfer(rspi, &xfer->tx_sg, NULL);
+ if (ret != -EAGAIN)
+ return ret;
+ }
ret = rspi_pio_transfer(rspi, xfer->tx_buf, NULL, xfer->len);
if (ret < 0)
@@ -664,8 +674,11 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
{
- if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer))
- return rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
+ if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
+ int ret = rspi_dma_transfer(rspi, NULL, &xfer->rx_sg);
+ if (ret != -EAGAIN)
+ return ret;
+ }
return rspi_pio_transfer(rspi, NULL, xfer->rx_buf, xfer->len);
}
@@ -927,19 +940,19 @@ static int rspi_request_dma(struct device *dev, struct spi_master *master,
return 0;
}
-static void rspi_release_dma(struct rspi_data *rspi)
+static void rspi_release_dma(struct spi_master *master)
{
- if (rspi->master->dma_tx)
- dma_release_channel(rspi->master->dma_tx);
- if (rspi->master->dma_rx)
- dma_release_channel(rspi->master->dma_rx);
+ if (master->dma_tx)
+ dma_release_channel(master->dma_tx);
+ if (master->dma_rx)
+ dma_release_channel(master->dma_rx);
}
static int rspi_remove(struct platform_device *pdev)
{
struct rspi_data *rspi = platform_get_drvdata(pdev);
- rspi_release_dma(rspi);
+ rspi_release_dma(rspi->master);
pm_runtime_disable(&pdev->dev);
return 0;
@@ -1141,7 +1154,7 @@ static int rspi_probe(struct platform_device *pdev)
return 0;
error3:
- rspi_release_dma(rspi);
+ rspi_release_dma(master);
error2:
pm_runtime_disable(&pdev->dev);
error1:
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 75a56968b14c..480133ee1eb3 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -197,7 +197,6 @@ struct s3c64xx_spi_driver_data {
struct s3c64xx_spi_dma_data tx_dma;
struct s3c64xx_spi_port_config *port_conf;
unsigned int port_id;
- bool cs_gpio;
};
static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -754,10 +753,8 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
{
struct s3c64xx_spi_csinfo *cs;
struct device_node *slave_np, *data_np = NULL;
- struct s3c64xx_spi_driver_data *sdd;
u32 fb_delay = 0;
- sdd = spi_master_get_devdata(spi->master);
slave_np = spi->dev.of_node;
if (!slave_np) {
dev_err(&spi->dev, "device node not found\n");
@@ -776,17 +773,6 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
return ERR_PTR(-ENOMEM);
}
- /* The CS line is asserted/deasserted by the gpio pin */
- if (sdd->cs_gpio)
- cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
-
- if (!gpio_is_valid(cs->line)) {
- dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
- kfree(cs);
- of_node_put(data_np);
- return ERR_PTR(-EINVAL);
- }
-
of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
cs->fb_delay = fb_delay;
of_node_put(data_np);
@@ -807,9 +793,16 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
int err;
sdd = spi_master_get_devdata(spi->master);
- if (!cs && spi->dev.of_node) {
+ if (spi->dev.of_node) {
cs = s3c64xx_get_slave_ctrldata(spi);
spi->controller_data = cs;
+ } else if (cs) {
+ /* On non-DT platforms the SPI core will set spi->cs_gpio
+ * to -ENOENT. The GPIO pin used to drive the chip select
+ * is defined by using platform data so spi->cs_gpio value
+ * has to be override to have the proper GPIO pin number.
+ */
+ spi->cs_gpio = cs->line;
}
if (IS_ERR_OR_NULL(cs)) {
@@ -818,18 +811,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
}
if (!spi_get_ctldata(spi)) {
- /* Request gpio only if cs line is asserted by gpio pins */
- if (sdd->cs_gpio) {
- err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH,
- dev_name(&spi->dev));
+ if (gpio_is_valid(spi->cs_gpio)) {
+ err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH,
+ dev_name(&spi->dev));
if (err) {
dev_err(&spi->dev,
"Failed to get /CS gpio [%d]: %d\n",
- cs->line, err);
+ spi->cs_gpio, err);
goto err_gpio_req;
}
-
- spi->cs_gpio = cs->line;
}
spi_set_ctldata(spi, cs);
@@ -884,7 +874,8 @@ setup_exit:
/* setup() returns with device de-selected */
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
- gpio_free(cs->line);
+ if (gpio_is_valid(spi->cs_gpio))
+ gpio_free(spi->cs_gpio);
spi_set_ctldata(spi, NULL);
err_gpio_req:
@@ -897,14 +888,21 @@ err_gpio_req:
static void s3c64xx_spi_cleanup(struct spi_device *spi)
{
struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
- struct s3c64xx_spi_driver_data *sdd;
- sdd = spi_master_get_devdata(spi->master);
- if (spi->cs_gpio) {
+ if (gpio_is_valid(spi->cs_gpio)) {
gpio_free(spi->cs_gpio);
if (spi->dev.of_node)
kfree(cs);
+ else {
+ /* On non-DT platforms, the SPI core sets
+ * spi->cs_gpio to -ENOENT and .setup()
+ * overrides it with the GPIO pin value
+ * passed using platform data.
+ */
+ spi->cs_gpio = -ENOENT;
+ }
}
+
spi_set_ctldata(spi, NULL);
}
@@ -1075,11 +1073,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
sdd->cntrlr_info = sci;
sdd->pdev = pdev;
sdd->sfr_start = mem_res->start;
- sdd->cs_gpio = true;
if (pdev->dev.of_node) {
- if (!of_find_property(pdev->dev.of_node, "cs-gpio", NULL))
- sdd->cs_gpio = false;
-
ret = of_alias_get_id(pdev->dev.of_node, "spi");
if (ret < 0) {
dev_err(&pdev->dev, "failed to get alias id, errno %d\n",
@@ -1323,19 +1317,6 @@ static struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
.tx_st_done = 21,
};
-static struct s3c64xx_spi_port_config s5p64x0_spi_port_config = {
- .fifo_lvl_mask = { 0x1ff, 0x7F },
- .rx_lvl_offset = 15,
- .tx_st_done = 25,
-};
-
-static struct s3c64xx_spi_port_config s5pc100_spi_port_config = {
- .fifo_lvl_mask = { 0x7f, 0x7F },
- .rx_lvl_offset = 13,
- .tx_st_done = 21,
- .high_speed = true,
-};
-
static struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
.fifo_lvl_mask = { 0x1ff, 0x7F },
.rx_lvl_offset = 15,
@@ -1368,12 +1349,6 @@ static struct platform_device_id s3c64xx_spi_driver_ids[] = {
.name = "s3c6410-spi",
.driver_data = (kernel_ulong_t)&s3c6410_spi_port_config,
}, {
- .name = "s5p64x0-spi",
- .driver_data = (kernel_ulong_t)&s5p64x0_spi_port_config,
- }, {
- .name = "s5pc100-spi",
- .driver_data = (kernel_ulong_t)&s5pc100_spi_port_config,
- }, {
.name = "s5pv210-spi",
.driver_data = (kernel_ulong_t)&s5pv210_spi_port_config,
}, {
@@ -1390,9 +1365,6 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
{ .compatible = "samsung,s3c6410-spi",
.data = (void *)&s3c6410_spi_port_config,
},
- { .compatible = "samsung,s5pc100-spi",
- .data = (void *)&s5pc100_spi_port_config,
- },
{ .compatible = "samsung,s5pv210-spi",
.data = (void *)&s5pv210_spi_port_config,
},
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index c8e795ef2e13..94b5faed21e2 100644
--- a/drivers/spi/spi-sh-hspi.c
+++ b/drivers/spi/spi-sh-hspi.c
@@ -304,7 +304,7 @@ static int hspi_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id hspi_of_match[] = {
+static const struct of_device_id hspi_of_match[] = {
{ .compatible = "renesas,hspi", },
{ /* sentinel */ }
};
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 45b09142afe2..2a4354dcd661 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -2,6 +2,7 @@
* SuperH MSIOF SPI Master Interface
*
* Copyright (c) 2009 Magnus Damm
+ * Copyright (C) 2014 Glider bvba
*
* 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
@@ -13,6 +14,8 @@
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
@@ -23,6 +26,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/sh_dma.h>
#include <linux/spi/sh_msiof.h>
#include <linux/spi/spi.h>
@@ -37,6 +41,7 @@ struct sh_msiof_chipdata {
};
struct sh_msiof_spi_priv {
+ struct spi_master *master;
void __iomem *mapbase;
struct clk *clk;
struct platform_device *pdev;
@@ -45,6 +50,10 @@ struct sh_msiof_spi_priv {
struct completion done;
int tx_fifo_size;
int rx_fifo_size;
+ void *tx_dma_page;
+ void *rx_dma_page;
+ dma_addr_t tx_dma_addr;
+ dma_addr_t rx_dma_addr;
};
#define TMDR1 0x00 /* Transmit Mode Register 1 */
@@ -84,6 +93,8 @@ struct sh_msiof_spi_priv {
#define MDR2_WDLEN1(i) (((i) - 1) << 16) /* Word Count (1-64/256 (SH, A1))) */
#define MDR2_GRPMASK1 0x00000001 /* Group Output Mask 1 (SH, A1) */
+#define MAX_WDLEN 256U
+
/* TSCR and RSCR */
#define SCR_BRPS_MASK 0x1f00 /* Prescaler Setting (1-32) */
#define SCR_BRPS(i) (((i) - 1) << 8)
@@ -113,9 +124,61 @@ struct sh_msiof_spi_priv {
#define CTR_TXE 0x00000200 /* Transmit Enable */
#define CTR_RXE 0x00000100 /* Receive Enable */
-/* STR and IER */
+/* FCTR */
+#define FCTR_TFWM_MASK 0xe0000000 /* Transmit FIFO Watermark */
+#define FCTR_TFWM_64 0x00000000 /* Transfer Request when 64 empty stages */
+#define FCTR_TFWM_32 0x20000000 /* Transfer Request when 32 empty stages */
+#define FCTR_TFWM_24 0x40000000 /* Transfer Request when 24 empty stages */
+#define FCTR_TFWM_16 0x60000000 /* Transfer Request when 16 empty stages */
+#define FCTR_TFWM_12 0x80000000 /* Transfer Request when 12 empty stages */
+#define FCTR_TFWM_8 0xa0000000 /* Transfer Request when 8 empty stages */
+#define FCTR_TFWM_4 0xc0000000 /* Transfer Request when 4 empty stages */
+#define FCTR_TFWM_1 0xe0000000 /* Transfer Request when 1 empty stage */
+#define FCTR_TFUA_MASK 0x07f00000 /* Transmit FIFO Usable Area */
+#define FCTR_TFUA_SHIFT 20
+#define FCTR_TFUA(i) ((i) << FCTR_TFUA_SHIFT)
+#define FCTR_RFWM_MASK 0x0000e000 /* Receive FIFO Watermark */
+#define FCTR_RFWM_1 0x00000000 /* Transfer Request when 1 valid stages */
+#define FCTR_RFWM_4 0x00002000 /* Transfer Request when 4 valid stages */
+#define FCTR_RFWM_8 0x00004000 /* Transfer Request when 8 valid stages */
+#define FCTR_RFWM_16 0x00006000 /* Transfer Request when 16 valid stages */
+#define FCTR_RFWM_32 0x00008000 /* Transfer Request when 32 valid stages */
+#define FCTR_RFWM_64 0x0000a000 /* Transfer Request when 64 valid stages */
+#define FCTR_RFWM_128 0x0000c000 /* Transfer Request when 128 valid stages */
+#define FCTR_RFWM_256 0x0000e000 /* Transfer Request when 256 valid stages */
+#define FCTR_RFUA_MASK 0x00001ff0 /* Receive FIFO Usable Area (0x40 = full) */
+#define FCTR_RFUA_SHIFT 4
+#define FCTR_RFUA(i) ((i) << FCTR_RFUA_SHIFT)
+
+/* STR */
+#define STR_TFEMP 0x20000000 /* Transmit FIFO Empty */
+#define STR_TDREQ 0x10000000 /* Transmit Data Transfer Request */
#define STR_TEOF 0x00800000 /* Frame Transmission End */
+#define STR_TFSERR 0x00200000 /* Transmit Frame Synchronization Error */
+#define STR_TFOVF 0x00100000 /* Transmit FIFO Overflow */
+#define STR_TFUDF 0x00080000 /* Transmit FIFO Underflow */
+#define STR_RFFUL 0x00002000 /* Receive FIFO Full */
+#define STR_RDREQ 0x00001000 /* Receive Data Transfer Request */
#define STR_REOF 0x00000080 /* Frame Reception End */
+#define STR_RFSERR 0x00000020 /* Receive Frame Synchronization Error */
+#define STR_RFUDF 0x00000010 /* Receive FIFO Underflow */
+#define STR_RFOVF 0x00000008 /* Receive FIFO Overflow */
+
+/* IER */
+#define IER_TDMAE 0x80000000 /* Transmit Data DMA Transfer Req. Enable */
+#define IER_TFEMPE 0x20000000 /* Transmit FIFO Empty Enable */
+#define IER_TDREQE 0x10000000 /* Transmit Data Transfer Request Enable */
+#define IER_TEOFE 0x00800000 /* Frame Transmission End Enable */
+#define IER_TFSERRE 0x00200000 /* Transmit Frame Sync Error Enable */
+#define IER_TFOVFE 0x00100000 /* Transmit FIFO Overflow Enable */
+#define IER_TFUDFE 0x00080000 /* Transmit FIFO Underflow Enable */
+#define IER_RDMAE 0x00008000 /* Receive Data DMA Transfer Req. Enable */
+#define IER_RFFULE 0x00002000 /* Receive FIFO Full Enable */
+#define IER_RDREQE 0x00001000 /* Receive Data Transfer Request Enable */
+#define IER_REOFE 0x00000080 /* Frame Reception End Enable */
+#define IER_RFSERRE 0x00000020 /* Receive Frame Sync Error Enable */
+#define IER_RFUDFE 0x00000010 /* Receive FIFO Underflow Enable */
+#define IER_RFOVFE 0x00000008 /* Receive FIFO Overflow Enable */
static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
@@ -230,8 +293,6 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
* 1 0 11 11 0 0
* 1 1 11 11 1 1
*/
- sh_msiof_write(p, FCTR, 0);
-
tmp = MDR1_SYNCMD_SPI | 1 << MDR1_FLD_SHIFT | MDR1_XXSTP;
tmp |= !cs_high << MDR1_SYNCAC_SHIFT;
tmp |= lsb_first << MDR1_BITLSB_SHIFT;
@@ -267,8 +328,6 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
if (rx_buf)
sh_msiof_write(p, RMDR2, dr2);
-
- sh_msiof_write(p, IER, STR_TEOF | STR_REOF);
}
static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
@@ -457,6 +516,40 @@ static int sh_msiof_prepare_message(struct spi_master *master,
return 0;
}
+static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
+{
+ int ret;
+
+ /* setup clock and rx/tx signals */
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
+ if (rx_buf && !ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
+
+ /* start by setting frame bit */
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
+
+ return ret;
+}
+
+static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
+{
+ int ret;
+
+ /* shut down frame, rx/tx and clock signals */
+ ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
+ if (rx_buf && !ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
+ if (!ret)
+ ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
+
+ return ret;
+}
+
static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
void (*tx_fifo)(struct sh_msiof_spi_priv *,
const void *, int, int),
@@ -477,29 +570,32 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
/* the fifo contents need shifting */
fifo_shift = 32 - bits;
+ /* default FIFO watermarks for PIO */
+ sh_msiof_write(p, FCTR, 0);
+
/* setup msiof transfer mode registers */
sh_msiof_spi_set_mode_regs(p, tx_buf, rx_buf, bits, words);
+ sh_msiof_write(p, IER, IER_TEOFE | IER_REOFE);
/* write tx fifo */
if (tx_buf)
tx_fifo(p, tx_buf, words, fifo_shift);
- /* setup clock and rx/tx signals */
- ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
- if (rx_buf)
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
-
- /* start by setting frame bit */
reinit_completion(&p->done);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
+
+ ret = sh_msiof_spi_start(p, rx_buf);
if (ret) {
dev_err(&p->pdev->dev, "failed to start hardware\n");
- goto err;
+ goto stop_ier;
}
/* wait for tx fifo to be emptied / rx fifo to be filled */
- wait_for_completion(&p->done);
+ ret = wait_for_completion_timeout(&p->done, HZ);
+ if (!ret) {
+ dev_err(&p->pdev->dev, "PIO timeout\n");
+ ret = -ETIMEDOUT;
+ goto stop_reset;
+ }
/* read rx fifo */
if (rx_buf)
@@ -508,41 +604,248 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
/* clear status bits */
sh_msiof_reset_str(p);
- /* shut down frame, rx/tx and clock signals */
- ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
- if (rx_buf)
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
- ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
+ ret = sh_msiof_spi_stop(p, rx_buf);
if (ret) {
dev_err(&p->pdev->dev, "failed to shut down hardware\n");
- goto err;
+ return ret;
}
return words;
- err:
+stop_reset:
+ sh_msiof_reset_str(p);
+ sh_msiof_spi_stop(p, rx_buf);
+stop_ier:
+ sh_msiof_write(p, IER, 0);
+ return ret;
+}
+
+static void sh_msiof_dma_complete(void *arg)
+{
+ struct sh_msiof_spi_priv *p = arg;
+
+ sh_msiof_write(p, IER, 0);
+ complete(&p->done);
+}
+
+static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
+ void *rx, unsigned int len)
+{
+ u32 ier_bits = 0;
+ struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
+ dma_cookie_t cookie;
+ int ret;
+
+ if (tx) {
+ ier_bits |= IER_TDREQE | IER_TDMAE;
+ dma_sync_single_for_device(p->master->dma_tx->device->dev,
+ p->tx_dma_addr, len, DMA_TO_DEVICE);
+ desc_tx = dmaengine_prep_slave_single(p->master->dma_tx,
+ p->tx_dma_addr, len, DMA_TO_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_tx)
+ return -EAGAIN;
+ }
+
+ if (rx) {
+ ier_bits |= IER_RDREQE | IER_RDMAE;
+ desc_rx = dmaengine_prep_slave_single(p->master->dma_rx,
+ p->rx_dma_addr, len, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_rx)
+ return -EAGAIN;
+ }
+
+ /* 1 stage FIFO watermarks for DMA */
+ sh_msiof_write(p, FCTR, FCTR_TFWM_1 | FCTR_RFWM_1);
+
+ /* setup msiof transfer mode registers (32-bit words) */
+ sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4);
+
+ sh_msiof_write(p, IER, ier_bits);
+
+ reinit_completion(&p->done);
+
+ if (rx) {
+ desc_rx->callback = sh_msiof_dma_complete;
+ desc_rx->callback_param = p;
+ cookie = dmaengine_submit(desc_rx);
+ if (dma_submit_error(cookie)) {
+ ret = cookie;
+ goto stop_ier;
+ }
+ dma_async_issue_pending(p->master->dma_rx);
+ }
+
+ if (tx) {
+ if (rx) {
+ /* No callback */
+ desc_tx->callback = NULL;
+ } else {
+ desc_tx->callback = sh_msiof_dma_complete;
+ desc_tx->callback_param = p;
+ }
+ cookie = dmaengine_submit(desc_tx);
+ if (dma_submit_error(cookie)) {
+ ret = cookie;
+ goto stop_rx;
+ }
+ dma_async_issue_pending(p->master->dma_tx);
+ }
+
+ ret = sh_msiof_spi_start(p, rx);
+ if (ret) {
+ dev_err(&p->pdev->dev, "failed to start hardware\n");
+ goto stop_tx;
+ }
+
+ /* wait for tx fifo to be emptied / rx fifo to be filled */
+ ret = wait_for_completion_timeout(&p->done, HZ);
+ if (!ret) {
+ dev_err(&p->pdev->dev, "DMA timeout\n");
+ ret = -ETIMEDOUT;
+ goto stop_reset;
+ }
+
+ /* clear status bits */
+ sh_msiof_reset_str(p);
+
+ ret = sh_msiof_spi_stop(p, rx);
+ if (ret) {
+ dev_err(&p->pdev->dev, "failed to shut down hardware\n");
+ return ret;
+ }
+
+ if (rx)
+ dma_sync_single_for_cpu(p->master->dma_rx->device->dev,
+ p->rx_dma_addr, len,
+ DMA_FROM_DEVICE);
+
+ return 0;
+
+stop_reset:
+ sh_msiof_reset_str(p);
+ sh_msiof_spi_stop(p, rx);
+stop_tx:
+ if (tx)
+ dmaengine_terminate_all(p->master->dma_tx);
+stop_rx:
+ if (rx)
+ dmaengine_terminate_all(p->master->dma_rx);
+stop_ier:
sh_msiof_write(p, IER, 0);
return ret;
}
+static void copy_bswap32(u32 *dst, const u32 *src, unsigned int words)
+{
+ /* src or dst can be unaligned, but not both */
+ if ((unsigned long)src & 3) {
+ while (words--) {
+ *dst++ = swab32(get_unaligned(src));
+ src++;
+ }
+ } else if ((unsigned long)dst & 3) {
+ while (words--) {
+ put_unaligned(swab32(*src++), dst);
+ dst++;
+ }
+ } else {
+ while (words--)
+ *dst++ = swab32(*src++);
+ }
+}
+
+static void copy_wswap32(u32 *dst, const u32 *src, unsigned int words)
+{
+ /* src or dst can be unaligned, but not both */
+ if ((unsigned long)src & 3) {
+ while (words--) {
+ *dst++ = swahw32(get_unaligned(src));
+ src++;
+ }
+ } else if ((unsigned long)dst & 3) {
+ while (words--) {
+ put_unaligned(swahw32(*src++), dst);
+ dst++;
+ }
+ } else {
+ while (words--)
+ *dst++ = swahw32(*src++);
+ }
+}
+
+static void copy_plain32(u32 *dst, const u32 *src, unsigned int words)
+{
+ memcpy(dst, src, words * 4);
+}
+
static int sh_msiof_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *t)
{
struct sh_msiof_spi_priv *p = spi_master_get_devdata(master);
+ void (*copy32)(u32 *, const u32 *, unsigned int);
void (*tx_fifo)(struct sh_msiof_spi_priv *, const void *, int, int);
void (*rx_fifo)(struct sh_msiof_spi_priv *, void *, int, int);
- int bits;
- int bytes_per_word;
- int bytes_done;
- int words;
+ const void *tx_buf = t->tx_buf;
+ void *rx_buf = t->rx_buf;
+ unsigned int len = t->len;
+ unsigned int bits = t->bits_per_word;
+ unsigned int bytes_per_word;
+ unsigned int words;
int n;
bool swab;
+ int ret;
- bits = t->bits_per_word;
+ /* setup clocks (clock already enabled in chipselect()) */
+ sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);
- if (bits <= 8 && t->len > 15 && !(t->len & 3)) {
+ while (master->dma_tx && len > 15) {
+ /*
+ * DMA supports 32-bit words only, hence pack 8-bit and 16-bit
+ * words, with byte resp. word swapping.
+ */
+ unsigned int l = min(len, MAX_WDLEN * 4);
+
+ if (bits <= 8) {
+ if (l & 3)
+ break;
+ copy32 = copy_bswap32;
+ } else if (bits <= 16) {
+ if (l & 1)
+ break;
+ copy32 = copy_wswap32;
+ } else {
+ copy32 = copy_plain32;
+ }
+
+ if (tx_buf)
+ copy32(p->tx_dma_page, tx_buf, l / 4);
+
+ ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l);
+ if (ret == -EAGAIN) {
+ pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
+ dev_driver_string(&p->pdev->dev),
+ dev_name(&p->pdev->dev));
+ break;
+ }
+ if (ret)
+ return ret;
+
+ if (rx_buf) {
+ copy32(rx_buf, p->rx_dma_page, l / 4);
+ rx_buf += l;
+ }
+ if (tx_buf)
+ tx_buf += l;
+
+ len -= l;
+ if (!len)
+ return 0;
+ }
+
+ if (bits <= 8 && len > 15 && !(len & 3)) {
bits = 32;
swab = true;
} else {
@@ -556,57 +859,52 @@ static int sh_msiof_transfer_one(struct spi_master *master,
rx_fifo = sh_msiof_spi_read_fifo_8;
} else if (bits <= 16) {
bytes_per_word = 2;
- if ((unsigned long)t->tx_buf & 0x01)
+ if ((unsigned long)tx_buf & 0x01)
tx_fifo = sh_msiof_spi_write_fifo_16u;
else
tx_fifo = sh_msiof_spi_write_fifo_16;
- if ((unsigned long)t->rx_buf & 0x01)
+ if ((unsigned long)rx_buf & 0x01)
rx_fifo = sh_msiof_spi_read_fifo_16u;
else
rx_fifo = sh_msiof_spi_read_fifo_16;
} else if (swab) {
bytes_per_word = 4;
- if ((unsigned long)t->tx_buf & 0x03)
+ if ((unsigned long)tx_buf & 0x03)
tx_fifo = sh_msiof_spi_write_fifo_s32u;
else
tx_fifo = sh_msiof_spi_write_fifo_s32;
- if ((unsigned long)t->rx_buf & 0x03)
+ if ((unsigned long)rx_buf & 0x03)
rx_fifo = sh_msiof_spi_read_fifo_s32u;
else
rx_fifo = sh_msiof_spi_read_fifo_s32;
} else {
bytes_per_word = 4;
- if ((unsigned long)t->tx_buf & 0x03)
+ if ((unsigned long)tx_buf & 0x03)
tx_fifo = sh_msiof_spi_write_fifo_32u;
else
tx_fifo = sh_msiof_spi_write_fifo_32;
- if ((unsigned long)t->rx_buf & 0x03)
+ if ((unsigned long)rx_buf & 0x03)
rx_fifo = sh_msiof_spi_read_fifo_32u;
else
rx_fifo = sh_msiof_spi_read_fifo_32;
}
- /* setup clocks (clock already enabled in chipselect()) */
- sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);
-
/* transfer in fifo sized chunks */
- words = t->len / bytes_per_word;
- bytes_done = 0;
-
- while (bytes_done < t->len) {
- void *rx_buf = t->rx_buf ? t->rx_buf + bytes_done : NULL;
- const void *tx_buf = t->tx_buf ? t->tx_buf + bytes_done : NULL;
- n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo,
- tx_buf,
- rx_buf,
+ words = len / bytes_per_word;
+
+ while (words > 0) {
+ n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo, tx_buf, rx_buf,
words, bits);
if (n < 0)
- break;
+ return n;
- bytes_done += n * bytes_per_word;
+ if (tx_buf)
+ tx_buf += n * bytes_per_word;
+ if (rx_buf)
+ rx_buf += n * bytes_per_word;
words -= n;
}
@@ -663,6 +961,128 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
}
#endif
+static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev,
+ enum dma_transfer_direction dir, unsigned int id, dma_addr_t port_addr)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct dma_slave_config cfg;
+ int ret;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_channel(mask, shdma_chan_filter,
+ (void *)(unsigned long)id);
+ if (!chan) {
+ dev_warn(dev, "dma_request_channel failed\n");
+ return NULL;
+ }
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.slave_id = id;
+ cfg.direction = dir;
+ if (dir == DMA_MEM_TO_DEV)
+ cfg.dst_addr = port_addr;
+ else
+ cfg.src_addr = port_addr;
+
+ ret = dmaengine_slave_config(chan, &cfg);
+ if (ret) {
+ dev_warn(dev, "dmaengine_slave_config failed %d\n", ret);
+ dma_release_channel(chan);
+ return NULL;
+ }
+
+ return chan;
+}
+
+static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p)
+{
+ struct platform_device *pdev = p->pdev;
+ struct device *dev = &pdev->dev;
+ const struct sh_msiof_spi_info *info = dev_get_platdata(dev);
+ const struct resource *res;
+ struct spi_master *master;
+ struct device *tx_dev, *rx_dev;
+
+ if (!info || !info->dma_tx_id || !info->dma_rx_id)
+ return 0; /* The driver assumes no error */
+
+ /* The DMA engine uses the second register set, if present */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ master = p->master;
+ master->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV,
+ info->dma_tx_id,
+ res->start + TFDR);
+ if (!master->dma_tx)
+ return -ENODEV;
+
+ master->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM,
+ info->dma_rx_id,
+ res->start + RFDR);
+ if (!master->dma_rx)
+ goto free_tx_chan;
+
+ p->tx_dma_page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!p->tx_dma_page)
+ goto free_rx_chan;
+
+ p->rx_dma_page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!p->rx_dma_page)
+ goto free_tx_page;
+
+ tx_dev = master->dma_tx->device->dev;
+ p->tx_dma_addr = dma_map_single(tx_dev, p->tx_dma_page, PAGE_SIZE,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(tx_dev, p->tx_dma_addr))
+ goto free_rx_page;
+
+ rx_dev = master->dma_rx->device->dev;
+ p->rx_dma_addr = dma_map_single(rx_dev, p->rx_dma_page, PAGE_SIZE,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(rx_dev, p->rx_dma_addr))
+ goto unmap_tx_page;
+
+ dev_info(dev, "DMA available");
+ return 0;
+
+unmap_tx_page:
+ dma_unmap_single(tx_dev, p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE);
+free_rx_page:
+ free_page((unsigned long)p->rx_dma_page);
+free_tx_page:
+ free_page((unsigned long)p->tx_dma_page);
+free_rx_chan:
+ dma_release_channel(master->dma_rx);
+free_tx_chan:
+ dma_release_channel(master->dma_tx);
+ master->dma_tx = NULL;
+ return -ENODEV;
+}
+
+static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p)
+{
+ struct spi_master *master = p->master;
+ struct device *dev;
+
+ if (!master->dma_tx)
+ return;
+
+ dev = &p->pdev->dev;
+ dma_unmap_single(master->dma_rx->device->dev, p->rx_dma_addr,
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ dma_unmap_single(master->dma_tx->device->dev, p->tx_dma_addr,
+ PAGE_SIZE, DMA_TO_DEVICE);
+ free_page((unsigned long)p->rx_dma_page);
+ free_page((unsigned long)p->tx_dma_page);
+ dma_release_channel(master->dma_rx);
+ dma_release_channel(master->dma_tx);
+}
+
static int sh_msiof_spi_probe(struct platform_device *pdev)
{
struct resource *r;
@@ -681,6 +1101,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
p = spi_master_get_devdata(master);
platform_set_drvdata(pdev, p);
+ p->master = master;
of_id = of_match_device(sh_msiof_match, &pdev->dev);
if (of_id) {
@@ -751,6 +1172,10 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
master->auto_runtime_pm = true;
master->transfer_one = sh_msiof_transfer_one;
+ ret = sh_msiof_request_dma(p);
+ if (ret < 0)
+ dev_warn(&pdev->dev, "DMA not available, using PIO\n");
+
ret = devm_spi_register_master(&pdev->dev, master);
if (ret < 0) {
dev_err(&pdev->dev, "spi_register_master error.\n");
@@ -760,6 +1185,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
return 0;
err2:
+ sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
err1:
spi_master_put(master);
@@ -768,6 +1194,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
static int sh_msiof_spi_remove(struct platform_device *pdev)
{
+ struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
+
+ sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
return 0;
}
diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c
index 03edf5ed0e9f..8e171a76049f 100644
--- a/drivers/spi/spi-sh.c
+++ b/drivers/spi/spi-sh.c
@@ -432,7 +432,6 @@ static int spi_sh_remove(struct platform_device *pdev)
spi_unregister_master(ss->master);
destroy_workqueue(ss->workqueue);
free_irq(ss->irq, ss);
- iounmap(ss->addr);
return 0;
}
@@ -480,7 +479,7 @@ static int spi_sh_probe(struct platform_device *pdev)
}
ss->irq = irq;
ss->master = master;
- ss->addr = ioremap(res->start, resource_size(res));
+ ss->addr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (ss->addr == NULL) {
dev_err(&pdev->dev, "ioremap error.\n");
ret = -ENOMEM;
@@ -495,13 +494,13 @@ static int spi_sh_probe(struct platform_device *pdev)
if (ss->workqueue == NULL) {
dev_err(&pdev->dev, "create workqueue error\n");
ret = -EBUSY;
- goto error2;
+ goto error1;
}
ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss);
if (ret < 0) {
dev_err(&pdev->dev, "request_irq error\n");
- goto error3;
+ goto error2;
}
master->num_chipselect = 2;
@@ -513,17 +512,15 @@ static int spi_sh_probe(struct platform_device *pdev)
ret = spi_register_master(master);
if (ret < 0) {
printk(KERN_ERR "spi_register_master error.\n");
- goto error4;
+ goto error3;
}
return 0;
- error4:
- free_irq(irq, ss);
error3:
- destroy_workqueue(ss->workqueue);
+ free_irq(irq, ss);
error2:
- iounmap(ss->addr);
+ destroy_workqueue(ss->workqueue);
error1:
spi_master_put(master);
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index f05abf89c067..0a87ec39f619 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -874,8 +874,8 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
dma_cap_set(DMA_SLAVE, mask);
/* Get DMA's dev information */
- dma_dev = pci_get_bus_and_slot(data->board_dat->pdev->bus->number,
- PCI_DEVFN(12, 0));
+ dma_dev = pci_get_slot(data->board_dat->pdev->bus,
+ PCI_DEVFN(PCI_SLOT(data->board_dat->pdev->devfn), 0));
/* Set Tx DMA */
param = &dma->param_tx;
@@ -1047,8 +1047,8 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
num, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_rx) {
- dev_err(&data->master->dev, "%s:device_prep_slave_sg Failed\n",
- __func__);
+ dev_err(&data->master->dev,
+ "%s:dmaengine_prep_slave_sg Failed\n", __func__);
return;
}
dma_sync_sg_for_device(&data->master->dev, sg, num, DMA_FROM_DEVICE);
@@ -1106,8 +1106,8 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
sg, num, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc_tx) {
- dev_err(&data->master->dev, "%s:device_prep_slave_sg Failed\n",
- __func__);
+ dev_err(&data->master->dev,
+ "%s:dmaengine_prep_slave_sg Failed\n", __func__);
return;
}
dma_sync_sg_for_device(&data->master->dev, sg, num, DMA_TO_DEVICE);
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index a3b0b9944bf0..4d8efb16573d 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -369,7 +369,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
goto put_master;
}
- master->bus_num = pdev->dev.id;
+ master->bus_num = pdev->id;
master->num_chipselect = num_cs;
master->dev.of_node = pdev->dev.of_node;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d4f9670b51bc..e0531baf2782 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -29,6 +29,7 @@
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/clk/clk-conf.h>
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
@@ -259,6 +260,10 @@ static int spi_drv_probe(struct device *dev)
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
int ret;
+ ret = of_clk_set_defaults(dev->of_node, false);
+ if (ret)
+ return ret;
+
acpi_dev_pm_attach(dev, true);
ret = sdrv->probe(to_spi_device(dev));
if (ret)
@@ -345,14 +350,12 @@ static DEFINE_MUTEX(board_lock);
struct spi_device *spi_alloc_device(struct spi_master *master)
{
struct spi_device *spi;
- struct device *dev = master->dev.parent;
if (!spi_master_get(master))
return NULL;
spi = kzalloc(sizeof(*spi), GFP_KERNEL);
if (!spi) {
- dev_err(dev, "cannot alloc spi_device\n");
spi_master_put(master);
return NULL;
}
@@ -619,6 +622,8 @@ static int spi_map_buf(struct spi_master *master, struct device *dev,
}
ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
+ if (!ret)
+ ret = -ENOMEM;
if (ret < 0) {
sg_free_table(sgt);
return ret;
@@ -647,8 +652,8 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg)
if (!master->can_dma)
return 0;
- tx_dev = &master->dma_tx->dev->device;
- rx_dev = &master->dma_rx->dev->device;
+ tx_dev = master->dma_tx->device->dev;
+ rx_dev = master->dma_rx->device->dev;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer))
@@ -687,8 +692,8 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
if (!master->cur_msg_mapped || !master->can_dma)
return 0;
- tx_dev = &master->dma_tx->dev->device;
- rx_dev = &master->dma_rx->dev->device;
+ tx_dev = master->dma_tx->device->dev;
+ rx_dev = master->dma_rx->device->dev;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (!master->can_dma(master, msg->spi, xfer))
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 3b5780710d50..1d92f5103ebf 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -18,7 +18,6 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/spmi.h>
-#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <dt-bindings/spmi/spmi.h>
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index a8dc95ebf2d6..0f28c08fcb3c 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -326,13 +326,13 @@ err_ctlreg:
return err;
}
-static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
- u16 mask, u16 shift)
+static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset,
+ u16 mask, u16 shift)
{
u16 v;
u8 gain;
- v = in[SPOFF(SSB_SPROM1_AGAIN)];
+ v = in[SPOFF(offset)];
gain = (v & mask) >> shift;
if (gain == 0xFF)
gain = 2; /* If unset use 2dBm */
@@ -416,12 +416,14 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
/* Extract the antenna gain values. */
- out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
- SSB_SPROM1_AGAIN_BG,
- SSB_SPROM1_AGAIN_BG_SHIFT);
- out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
- SSB_SPROM1_AGAIN_A,
- SSB_SPROM1_AGAIN_A_SHIFT);
+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN,
+ SSB_SPROM1_AGAIN_BG,
+ SSB_SPROM1_AGAIN_BG_SHIFT);
+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN,
+ SSB_SPROM1_AGAIN_A,
+ SSB_SPROM1_AGAIN_A_SHIFT);
if (out->revision >= 2)
sprom_extract_r23(out, in);
}
@@ -468,7 +470,15 @@ static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
{
+ static const u16 pwr_info_offset[] = {
+ SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1,
+ SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3
+ };
u16 il0mac_offset;
+ int i;
+
+ BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+ ARRAY_SIZE(out->core_pwr_info));
if (out->revision == 4)
il0mac_offset = SSB_SPROM4_IL0MAC;
@@ -524,14 +534,59 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
}
/* Extract the antenna gain values. */
- SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
- SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
- SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
- SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
- SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
- SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
- SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
- SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM4_AGAIN01,
+ SSB_SPROM4_AGAIN0,
+ SSB_SPROM4_AGAIN0_SHIFT);
+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM4_AGAIN01,
+ SSB_SPROM4_AGAIN1,
+ SSB_SPROM4_AGAIN1_SHIFT);
+ out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM4_AGAIN23,
+ SSB_SPROM4_AGAIN2,
+ SSB_SPROM4_AGAIN2_SHIFT);
+ out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM4_AGAIN23,
+ SSB_SPROM4_AGAIN3,
+ SSB_SPROM4_AGAIN3_SHIFT);
+
+ /* Extract cores power info info */
+ for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
+ u16 o = pwr_info_offset[i];
+
+ SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
+ SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT);
+ SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
+ SSB_SPROM4_2G_MAXP, 0);
+
+ SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0);
+ SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0);
+ SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0);
+ SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0);
+
+ SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
+ SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT);
+ SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
+ SSB_SPROM4_5G_MAXP, 0);
+ SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP,
+ SSB_SPROM4_5GH_MAXP, 0);
+ SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP,
+ SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT);
+
+ SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0);
+ SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0);
+ }
sprom_extract_r458(out, in);
@@ -621,14 +676,22 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
/* Extract the antenna gain values. */
- SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
- SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
- SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
- SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
+ out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN0,
+ SSB_SPROM8_AGAIN0_SHIFT);
+ out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN1,
+ SSB_SPROM8_AGAIN1_SHIFT);
+ out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN2,
+ SSB_SPROM8_AGAIN2_SHIFT);
+ out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN3,
+ SSB_SPROM8_AGAIN3_SHIFT);
/* Extract cores power info info */
for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4f38fc000a37..2c486ea6236b 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -30,8 +30,6 @@ source "drivers/staging/slicoss/Kconfig"
source "drivers/staging/usbip/Kconfig"
-source "drivers/staging/winbond/Kconfig"
-
source "drivers/staging/wlan-ng/Kconfig"
source "drivers/staging/comedi/Kconfig"
@@ -56,41 +54,21 @@ source "drivers/staging/rtl8821ae/Kconfig"
source "drivers/staging/rts5208/Kconfig"
-source "drivers/staging/frontier/Kconfig"
-
-source "drivers/staging/phison/Kconfig"
-
source "drivers/staging/line6/Kconfig"
source "drivers/staging/octeon/Kconfig"
source "drivers/staging/octeon-usb/Kconfig"
-source "drivers/staging/serqt_usb2/Kconfig"
-
source "drivers/staging/vt6655/Kconfig"
source "drivers/staging/vt6656/Kconfig"
-source "drivers/staging/sep/Kconfig"
-
source "drivers/staging/iio/Kconfig"
-source "drivers/staging/wlags49_h2/Kconfig"
-
-source "drivers/staging/wlags49_h25/Kconfig"
-
-source "drivers/staging/crystalhd/Kconfig"
-
-source "drivers/staging/cxt1e1/Kconfig"
-
source "drivers/staging/xgifb/Kconfig"
-source "drivers/staging/tidspbridge/Kconfig"
-
-source "drivers/staging/quickstart/Kconfig"
-
-source "drivers/staging/keucr/Kconfig"
+source "drivers/staging/emxx_udc/Kconfig"
source "drivers/staging/bcm/Kconfig"
@@ -108,20 +86,16 @@ source "drivers/staging/media/Kconfig"
source "drivers/staging/android/Kconfig"
+source "drivers/staging/board/Kconfig"
+
source "drivers/staging/ozwpan/Kconfig"
source "drivers/staging/gdm72xx/Kconfig"
source "drivers/staging/gdm724x/Kconfig"
-source "drivers/staging/silicom/Kconfig"
-
-source "drivers/staging/ced1401/Kconfig"
-
source "drivers/staging/imx-drm/Kconfig"
-source "drivers/staging/dgrp/Kconfig"
-
source "drivers/staging/fwserial/Kconfig"
source "drivers/staging/goldfish/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 1e97ad2177de..1e1a3a10faf7 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -7,7 +7,6 @@ obj-y += media/
obj-$(CONFIG_ET131X) += et131x/
obj-$(CONFIG_SLICOSS) += slicoss/
obj-$(CONFIG_USBIP_CORE) += usbip/
-obj-$(CONFIG_W35UND) += winbond/
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
@@ -20,26 +19,16 @@ obj-$(CONFIG_R8192EE) += rtl8192ee/
obj-$(CONFIG_R8723AU) += rtl8723au/
obj-$(CONFIG_R8821AE) += rtl8821ae/
obj-$(CONFIG_RTS5208) += rts5208/
-obj-$(CONFIG_TRANZPORT) += frontier/
-obj-$(CONFIG_IDE_PHISON) += phison/
obj-$(CONFIG_LINE6_USB) += line6/
obj-$(CONFIG_NETLOGIC_XLR_NET) += netlogic/
-obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_OCTEON_USB) += octeon-usb/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_VME_BUS) += vme/
-obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
-obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
-obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
-obj-$(CONFIG_CRYSTALHD) += crystalhd/
-obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_FB_XGI) += xgifb/
-obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
-obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
-obj-$(CONFIG_USB_ENESTORAGE) += keucr/
+obj-$(CONFIG_USB_EMXX) += emxx_udc/
obj-$(CONFIG_BCM_WIMAX) += bcm/
obj-$(CONFIG_FT1000) += ft1000/
obj-$(CONFIG_SPEAKUP) += speakup/
@@ -47,13 +36,11 @@ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_ANDROID) += android/
+obj-$(CONFIG_STAGING_BOARD) += board/
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
obj-$(CONFIG_LTE_GDM724X) += gdm724x/
-obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
-obj-$(CONFIG_CED1401) += ced1401/
obj-$(CONFIG_DRM_IMX) += imx-drm/
-obj-$(CONFIG_DGRP) += dgrp/
obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
obj-$(CONFIG_GOLDFISH) += goldfish/
obj-$(CONFIG_LUSTRE_FS) += lustre/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 99e484f845f2..7a0e28852965 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -76,7 +76,7 @@ config ANDROID_LOW_MEMORY_KILLER
Registers processes to be killed when memory is low
config ANDROID_INTF_ALARM_DEV
- bool "Android alarm driver"
+ tristate "Android alarm driver"
depends on RTC_CLASS
default n
---help---
@@ -88,6 +88,7 @@ config SYNC
bool "Synchronization framework"
default n
select ANON_INODES
+ select DMA_SHARED_BUFFER
---help---
This option enables the framework for synchronization between multiple
drivers. Sync implementations can take advantage of hardware
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 0a01e1914905..517ad5ffa429 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -9,5 +9,5 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
-obj-$(CONFIG_SYNC) += sync.o
+obj-$(CONFIG_SYNC) += sync.o sync_debug.o
obj-$(CONFIG_SW_SYNC) += sw_sync.o
diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c
index f200e8a84325..ff4b3e8758a7 100644
--- a/drivers/staging/android/alarm-dev.c
+++ b/drivers/staging/android/alarm-dev.c
@@ -443,4 +443,4 @@ static void __exit alarm_dev_exit(void)
module_init(alarm_dev_init);
module_exit(alarm_dev_exit);
-
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index a741da77828a..4f34dc0095b5 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -454,9 +454,8 @@ static size_t binder_buffer_size(struct binder_proc *proc,
{
if (list_is_last(&buffer->entry, &proc->buffers))
return proc->buffer + proc->buffer_size - (void *)buffer->data;
- else
- return (size_t)list_entry(buffer->entry.next,
- struct binder_buffer, entry) - (size_t)buffer->data;
+ return (size_t)list_entry(buffer->entry.next,
+ struct binder_buffer, entry) - (size_t)buffer->data;
}
static void binder_insert_free_buffer(struct binder_proc *proc,
@@ -586,7 +585,6 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) {
int ret;
- struct page **page_array_ptr;
page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];
@@ -599,8 +597,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
}
tmp_area.addr = page_addr;
tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;
- page_array_ptr = page;
- ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
+ ret = map_vm_area(&tmp_area, PAGE_KERNEL, page);
if (ret) {
pr_err("%d: binder_alloc_buf failed to map page at %p in kernel\n",
proc->pid, page_addr);
@@ -1186,6 +1183,7 @@ static void binder_send_failed_reply(struct binder_transaction *t,
uint32_t error_code)
{
struct binder_thread *target_thread;
+ struct binder_transaction *next;
BUG_ON(t->flags & TF_ONE_WAY);
while (1) {
@@ -1213,24 +1211,23 @@ static void binder_send_failed_reply(struct binder_transaction *t,
target_thread->return_error);
}
return;
- } else {
- struct binder_transaction *next = t->from_parent;
+ }
+ next = t->from_parent;
- binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
- "send failed reply for transaction %d, target dead\n",
- t->debug_id);
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+ "send failed reply for transaction %d, target dead\n",
+ t->debug_id);
- binder_pop_transaction(target_thread, t);
- if (next == NULL) {
- binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "reply failed, no target thread at root\n");
- return;
- }
- t = next;
+ binder_pop_transaction(target_thread, t);
+ if (next == NULL) {
binder_debug(BINDER_DEBUG_DEAD_BINDER,
- "reply failed, no target thread -- retry %d\n",
- t->debug_id);
+ "reply failed, no target thread at root\n");
+ return;
}
+ t = next;
+ binder_debug(BINDER_DEBUG_DEAD_BINDER,
+ "reply failed, no target thread -- retry %d\n",
+ t->debug_id);
}
}
@@ -2594,6 +2591,106 @@ static unsigned int binder_poll(struct file *filp,
return 0;
}
+static int binder_ioctl_write_read(struct file *filp,
+ unsigned int cmd, unsigned long arg,
+ struct binder_thread *thread)
+{
+ int ret = 0;
+ struct binder_proc *proc = filp->private_data;
+ unsigned int size = _IOC_SIZE(cmd);
+ void __user *ubuf = (void __user *)arg;
+ struct binder_write_read bwr;
+
+ if (size != sizeof(struct binder_write_read)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
+ ret = -EFAULT;
+ goto out;
+ }
+ binder_debug(BINDER_DEBUG_READ_WRITE,
+ "%d:%d write %lld at %016llx, read %lld at %016llx\n",
+ proc->pid, thread->pid,
+ (u64)bwr.write_size, (u64)bwr.write_buffer,
+ (u64)bwr.read_size, (u64)bwr.read_buffer);
+
+ if (bwr.write_size > 0) {
+ ret = binder_thread_write(proc, thread,
+ bwr.write_buffer,
+ bwr.write_size,
+ &bwr.write_consumed);
+ trace_binder_write_done(ret);
+ if (ret < 0) {
+ bwr.read_consumed = 0;
+ if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+ if (bwr.read_size > 0) {
+ ret = binder_thread_read(proc, thread, bwr.read_buffer,
+ bwr.read_size,
+ &bwr.read_consumed,
+ filp->f_flags & O_NONBLOCK);
+ trace_binder_read_done(ret);
+ if (!list_empty(&proc->todo))
+ wake_up_interruptible(&proc->wait);
+ if (ret < 0) {
+ if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+ binder_debug(BINDER_DEBUG_READ_WRITE,
+ "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
+ proc->pid, thread->pid,
+ (u64)bwr.write_consumed, (u64)bwr.write_size,
+ (u64)bwr.read_consumed, (u64)bwr.read_size);
+ if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
+ ret = -EFAULT;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+static int binder_ioctl_set_ctx_mgr(struct file *filp)
+{
+ int ret = 0;
+ struct binder_proc *proc = filp->private_data;
+ kuid_t curr_euid = current_euid();
+
+ if (binder_context_mgr_node != NULL) {
+ pr_err("BINDER_SET_CONTEXT_MGR already set\n");
+ ret = -EBUSY;
+ goto out;
+ }
+ if (uid_valid(binder_context_mgr_uid)) {
+ if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
+ pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
+ from_kuid(&init_user_ns, curr_euid),
+ from_kuid(&init_user_ns,
+ binder_context_mgr_uid));
+ ret = -EPERM;
+ goto out;
+ }
+ } else {
+ binder_context_mgr_uid = curr_euid;
+ }
+ binder_context_mgr_node = binder_new_node(proc, 0, 0);
+ if (binder_context_mgr_node == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ binder_context_mgr_node->local_weak_refs++;
+ binder_context_mgr_node->local_strong_refs++;
+ binder_context_mgr_node->has_strong_ref = 1;
+ binder_context_mgr_node->has_weak_ref = 1;
+out:
+ return ret;
+}
+
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
@@ -2601,9 +2698,9 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct binder_thread *thread;
unsigned int size = _IOC_SIZE(cmd);
void __user *ubuf = (void __user *)arg;
- kuid_t curr_euid = current_euid();
- /*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+ /*pr_info("binder_ioctl: %d:%d %x %lx\n",
+ proc->pid, current->pid, cmd, arg);*/
trace_binder_ioctl(cmd, arg);
@@ -2619,61 +2716,11 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
switch (cmd) {
- case BINDER_WRITE_READ: {
- struct binder_write_read bwr;
-
- if (size != sizeof(struct binder_write_read)) {
- ret = -EINVAL;
- goto err;
- }
- if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
- ret = -EFAULT;
- goto err;
- }
- binder_debug(BINDER_DEBUG_READ_WRITE,
- "%d:%d write %lld at %016llx, read %lld at %016llx\n",
- proc->pid, thread->pid,
- (u64)bwr.write_size, (u64)bwr.write_buffer,
- (u64)bwr.read_size, (u64)bwr.read_buffer);
-
- if (bwr.write_size > 0) {
- ret = binder_thread_write(proc, thread,
- bwr.write_buffer,
- bwr.write_size,
- &bwr.write_consumed);
- trace_binder_write_done(ret);
- if (ret < 0) {
- bwr.read_consumed = 0;
- if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
- ret = -EFAULT;
- goto err;
- }
- }
- if (bwr.read_size > 0) {
- ret = binder_thread_read(proc, thread, bwr.read_buffer,
- bwr.read_size,
- &bwr.read_consumed,
- filp->f_flags & O_NONBLOCK);
- trace_binder_read_done(ret);
- if (!list_empty(&proc->todo))
- wake_up_interruptible(&proc->wait);
- if (ret < 0) {
- if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
- ret = -EFAULT;
- goto err;
- }
- }
- binder_debug(BINDER_DEBUG_READ_WRITE,
- "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
- proc->pid, thread->pid,
- (u64)bwr.write_consumed, (u64)bwr.write_size,
- (u64)bwr.read_consumed, (u64)bwr.read_size);
- if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
- ret = -EFAULT;
+ case BINDER_WRITE_READ:
+ ret = binder_ioctl_write_read(filp, cmd, arg, thread);
+ if (ret)
goto err;
- }
break;
- }
case BINDER_SET_MAX_THREADS:
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret = -EINVAL;
@@ -2681,31 +2728,9 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
case BINDER_SET_CONTEXT_MGR:
- if (binder_context_mgr_node != NULL) {
- pr_err("BINDER_SET_CONTEXT_MGR already set\n");
- ret = -EBUSY;
+ ret = binder_ioctl_set_ctx_mgr(filp);
+ if (ret)
goto err;
- }
- if (uid_valid(binder_context_mgr_uid)) {
- if (!uid_eq(binder_context_mgr_uid, curr_euid)) {
- pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
- from_kuid(&init_user_ns, curr_euid),
- from_kuid(&init_user_ns, binder_context_mgr_uid));
- ret = -EPERM;
- goto err;
- }
- } else {
- binder_context_mgr_uid = curr_euid;
- }
- binder_context_mgr_node = binder_new_node(proc, 0, 0);
- if (binder_context_mgr_node == NULL) {
- ret = -ENOMEM;
- goto err;
- }
- binder_context_mgr_node->local_weak_refs++;
- binder_context_mgr_node->local_strong_refs++;
- binder_context_mgr_node->has_strong_ref = 1;
- binder_context_mgr_node->has_weak_ref = 1;
break;
case BINDER_THREAD_EXIT:
binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n",
@@ -2769,9 +2794,15 @@ static void binder_vma_close(struct vm_area_struct *vma)
binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
}
+static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return VM_FAULT_SIGBUS;
+}
+
static struct vm_operations_struct binder_vm_ops = {
.open = binder_vma_open,
.close = binder_vma_close,
+ .fault = binder_vm_fault,
};
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
index 0f8fec1f84e5..345234624492 100644
--- a/drivers/staging/android/ion/Kconfig
+++ b/drivers/staging/android/ion/Kconfig
@@ -1,6 +1,6 @@
menuconfig ION
bool "Ion Memory Manager"
- depends on HAVE_MEMBLOCK
+ depends on HAVE_MEMBLOCK && HAS_DMA && MMU
select GENERIC_ALLOCATOR
select DMA_SHARED_BUFFER
---help---
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 389b8f67a2ec..270360912b2c 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1120,7 +1120,8 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client,
ion_buffer_get(buffer);
mutex_unlock(&client->lock);
- dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR);
+ dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR,
+ NULL);
if (IS_ERR(dmabuf)) {
ion_buffer_put(buffer);
return dmabuf;
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index dcd2a0cdb192..d305bb7e9a74 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -84,7 +84,6 @@ void ion_reserve(struct ion_platform_data *data);
/**
* ion_client_create() - allocate a client and returns it
* @dev: the global ion device
- * @heap_type_mask: mask of heaps this client can allocate from
* @name: used for debugging
*/
struct ion_client *ion_client_create(struct ion_device *dev,
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 3f2c12ba4d14..9c3e49aa204b 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -106,7 +106,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
if (ion_buffer_cached(buffer))
dma_sync_sg_for_device(NULL, table->sgl, table->nents,
- DMA_BIDIRECTIONAL);
+ DMA_BIDIRECTIONAL);
for_each_sg(table->sgl, sg, table->nents, i) {
gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index ce68ecfed31f..f8cabcbc39e5 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -76,10 +76,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
return -EINVAL;
info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL);
- if (!info) {
- dev_err(dev, "Can't allocate buffer info\n");
+ if (!info)
return ION_CMA_ALLOCATE_FAILED;
- }
info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle),
GFP_HIGHUSER | __GFP_ZERO);
@@ -90,10 +88,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
}
info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
- if (!info->table) {
- dev_err(dev, "Fail to allocate sg table\n");
+ if (!info->table)
goto free_mem;
- }
if (ion_cma_get_sgtable
(dev, info->table, info->cpu_addr, info->handle, len))
@@ -155,7 +151,6 @@ static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap,
static void ion_cma_heap_unmap_dma(struct ion_heap *heap,
struct ion_buffer *buffer)
{
- return;
}
static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer,
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index cb7ae08a5e24..6b77c5195b4d 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -49,13 +49,7 @@ static inline unsigned int order_to_size(int order)
struct ion_system_heap {
struct ion_heap heap;
- struct ion_page_pool **pools;
-};
-
-struct page_info {
- struct page *page;
- unsigned int order;
- struct list_head list;
+ struct ion_page_pool *pools[0];
};
static struct page *alloc_buffer_page(struct ion_system_heap *heap,
@@ -84,9 +78,9 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap,
}
static void free_buffer_page(struct ion_system_heap *heap,
- struct ion_buffer *buffer, struct page *page,
- unsigned int order)
+ struct ion_buffer *buffer, struct page *page)
{
+ unsigned int order = compound_order(page);
bool cached = ion_buffer_cached(buffer);
if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) {
@@ -99,19 +93,14 @@ static void free_buffer_page(struct ion_system_heap *heap,
}
-static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
- struct ion_buffer *buffer,
- unsigned long size,
- unsigned int max_order)
+static struct page *alloc_largest_available(struct ion_system_heap *heap,
+ struct ion_buffer *buffer,
+ unsigned long size,
+ unsigned int max_order)
{
struct page *page;
- struct page_info *info;
int i;
- info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
- if (!info)
- return NULL;
-
for (i = 0; i < num_orders; i++) {
if (size < order_to_size(orders[i]))
continue;
@@ -122,11 +111,8 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
if (!page)
continue;
- info->page = page;
- info->order = orders[i];
- return info;
+ return page;
}
- kfree(info);
return NULL;
}
@@ -142,7 +128,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
struct sg_table *table;
struct scatterlist *sg;
struct list_head pages;
- struct page_info *info, *tmp_info;
+ struct page *page, *tmp_page;
int i = 0;
unsigned long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = orders[0];
@@ -155,13 +141,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
INIT_LIST_HEAD(&pages);
while (size_remaining > 0) {
- info = alloc_largest_available(sys_heap, buffer, size_remaining,
+ page = alloc_largest_available(sys_heap, buffer, size_remaining,
max_order);
- if (!info)
+ if (!page)
goto free_pages;
- list_add_tail(&info->list, &pages);
- size_remaining -= PAGE_SIZE << info->order;
- max_order = info->order;
+ list_add_tail(&page->lru, &pages);
+ size_remaining -= PAGE_SIZE << compound_order(page);
+ max_order = compound_order(page);
i++;
}
table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
@@ -172,12 +158,10 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
goto free_table;
sg = table->sgl;
- list_for_each_entry_safe(info, tmp_info, &pages, list) {
- struct page *page = info->page;
- sg_set_page(sg, page, PAGE_SIZE << info->order, 0);
+ list_for_each_entry_safe(page, tmp_page, &pages, lru) {
+ sg_set_page(sg, page, PAGE_SIZE << compound_order(page), 0);
sg = sg_next(sg);
- list_del(&info->list);
- kfree(info);
+ list_del(&page->lru);
}
buffer->priv_virt = table;
@@ -186,10 +170,8 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
free_table:
kfree(table);
free_pages:
- list_for_each_entry_safe(info, tmp_info, &pages, list) {
- free_buffer_page(sys_heap, buffer, info->page, info->order);
- kfree(info);
- }
+ list_for_each_entry_safe(page, tmp_page, &pages, lru)
+ free_buffer_page(sys_heap, buffer, page);
return -ENOMEM;
}
@@ -209,8 +191,7 @@ static void ion_system_heap_free(struct ion_buffer *buffer)
ion_heap_buffer_zero(buffer);
for_each_sg(table->sgl, sg, table->nents, i)
- free_buffer_page(sys_heap, buffer, sg_page(sg),
- get_order(sg->length));
+ free_buffer_page(sys_heap, buffer, sg_page(sg));
sg_free_table(table);
kfree(table);
}
@@ -283,16 +264,15 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
struct ion_system_heap *heap;
int i;
- heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL);
+ heap = kzalloc(sizeof(struct ion_system_heap) +
+ sizeof(struct ion_page_pool *) * num_orders,
+ GFP_KERNEL);
if (!heap)
return ERR_PTR(-ENOMEM);
heap->heap.ops = &system_heap_ops;
heap->heap.type = ION_HEAP_TYPE_SYSTEM;
heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
- heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders,
- GFP_KERNEL);
- if (!heap->pools)
- goto free_heap;
+
for (i = 0; i < num_orders; i++) {
struct ion_page_pool *pool;
gfp_t gfp_flags = low_order_gfp_flags;
@@ -311,8 +291,6 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
destroy_pools:
while (i--)
ion_page_pool_destroy(heap->pools[i]);
- kfree(heap->pools);
-free_heap:
kfree(heap);
return ERR_PTR(-ENOMEM);
}
@@ -326,7 +304,6 @@ void ion_system_heap_destroy(struct ion_heap *heap)
for (i = 0; i < num_orders; i++)
ion_page_pool_destroy(sys_heap->pools[i]);
- kfree(sys_heap->pools);
kfree(sys_heap);
}
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index 2772e01b37f5..9b47e66599a3 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -110,8 +110,8 @@ static inline struct logger_log *file_get_log(struct file *file)
struct logger_reader *reader = file->private_data;
return reader->log;
- } else
- return file->private_data;
+ }
+ return file->private_data;
}
/*
@@ -159,8 +159,7 @@ static size_t get_user_hdr_len(int ver)
{
if (ver < 2)
return sizeof(struct user_logger_entry_compat);
- else
- return sizeof(struct logger_entry);
+ return sizeof(struct logger_entry);
}
static ssize_t copy_header_to_user(int ver, struct logger_entry *entry,
diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c
index 12a136ec1cec..a76db3ff87cb 100644
--- a/drivers/staging/android/sw_sync.c
+++ b/drivers/staging/android/sw_sync.c
@@ -50,7 +50,7 @@ static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt)
{
struct sw_sync_pt *pt = (struct sw_sync_pt *) sync_pt;
struct sw_sync_timeline *obj =
- (struct sw_sync_timeline *)sync_pt->parent;
+ (struct sw_sync_timeline *)sync_pt_parent(sync_pt);
return (struct sync_pt *) sw_sync_pt_create(obj, pt->value);
}
@@ -59,7 +59,7 @@ static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt)
{
struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
struct sw_sync_timeline *obj =
- (struct sw_sync_timeline *)sync_pt->parent;
+ (struct sw_sync_timeline *)sync_pt_parent(sync_pt);
return sw_sync_cmp(obj->value, pt->value) >= 0;
}
@@ -97,7 +97,6 @@ static void sw_sync_pt_value_str(struct sync_pt *sync_pt,
char *str, int size)
{
struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
-
snprintf(str, size, "%d", pt->value);
}
@@ -157,7 +156,6 @@ static int sw_sync_open(struct inode *inode, struct file *file)
static int sw_sync_release(struct inode *inode, struct file *file)
{
struct sw_sync_timeline *obj = file->private_data;
-
sync_timeline_destroy(&obj->obj);
return 0;
}
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c
index 18174f7c871c..e7b2e0234196 100644
--- a/drivers/staging/android/sync.c
+++ b/drivers/staging/android/sync.c
@@ -31,22 +31,13 @@
#define CREATE_TRACE_POINTS
#include "trace/sync.h"
-static void sync_fence_signal_pt(struct sync_pt *pt);
-static int _sync_pt_has_signaled(struct sync_pt *pt);
-static void sync_fence_free(struct kref *kref);
-static void sync_dump(void);
-
-static LIST_HEAD(sync_timeline_list_head);
-static DEFINE_SPINLOCK(sync_timeline_list_lock);
-
-static LIST_HEAD(sync_fence_list_head);
-static DEFINE_SPINLOCK(sync_fence_list_lock);
+static const struct fence_ops android_fence_ops;
+static const struct file_operations sync_fence_fops;
struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
int size, const char *name)
{
struct sync_timeline *obj;
- unsigned long flags;
if (size < sizeof(struct sync_timeline))
return NULL;
@@ -57,17 +48,14 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
kref_init(&obj->kref);
obj->ops = ops;
+ obj->context = fence_context_alloc(1);
strlcpy(obj->name, name, sizeof(obj->name));
INIT_LIST_HEAD(&obj->child_list_head);
- spin_lock_init(&obj->child_list_lock);
-
INIT_LIST_HEAD(&obj->active_list_head);
- spin_lock_init(&obj->active_list_lock);
+ spin_lock_init(&obj->child_list_lock);
- spin_lock_irqsave(&sync_timeline_list_lock, flags);
- list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head);
- spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+ sync_timeline_debug_add(obj);
return obj;
}
@@ -77,11 +65,8 @@ static void sync_timeline_free(struct kref *kref)
{
struct sync_timeline *obj =
container_of(kref, struct sync_timeline, kref);
- unsigned long flags;
- spin_lock_irqsave(&sync_timeline_list_lock, flags);
- list_del(&obj->sync_timeline_list);
- spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+ sync_timeline_debug_remove(obj);
if (obj->ops->release_obj)
obj->ops->release_obj(obj);
@@ -89,6 +74,16 @@ static void sync_timeline_free(struct kref *kref)
kfree(obj);
}
+static void sync_timeline_get(struct sync_timeline *obj)
+{
+ kref_get(&obj->kref);
+}
+
+static void sync_timeline_put(struct sync_timeline *obj)
+{
+ kref_put(&obj->kref, sync_timeline_free);
+}
+
void sync_timeline_destroy(struct sync_timeline *obj)
{
obj->destroyed = true;
@@ -102,75 +97,33 @@ void sync_timeline_destroy(struct sync_timeline *obj)
* signal any children that their parent is going away.
*/
sync_timeline_signal(obj);
-
- kref_put(&obj->kref, sync_timeline_free);
+ sync_timeline_put(obj);
}
EXPORT_SYMBOL(sync_timeline_destroy);
-static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt)
-{
- unsigned long flags;
-
- pt->parent = obj;
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
- list_add_tail(&pt->child_list, &obj->child_list_head);
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-
-static void sync_timeline_remove_pt(struct sync_pt *pt)
-{
- struct sync_timeline *obj = pt->parent;
- unsigned long flags;
-
- spin_lock_irqsave(&obj->active_list_lock, flags);
- if (!list_empty(&pt->active_list))
- list_del_init(&pt->active_list);
- spin_unlock_irqrestore(&obj->active_list_lock, flags);
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
- if (!list_empty(&pt->child_list))
- list_del_init(&pt->child_list);
-
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-
void sync_timeline_signal(struct sync_timeline *obj)
{
unsigned long flags;
LIST_HEAD(signaled_pts);
- struct list_head *pos, *n;
+ struct sync_pt *pt, *next;
trace_sync_timeline(obj);
- spin_lock_irqsave(&obj->active_list_lock, flags);
-
- list_for_each_safe(pos, n, &obj->active_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, active_list);
+ spin_lock_irqsave(&obj->child_list_lock, flags);
- if (_sync_pt_has_signaled(pt)) {
- list_del_init(pos);
- list_add(&pt->signaled_list, &signaled_pts);
- kref_get(&pt->fence->kref);
- }
+ list_for_each_entry_safe(pt, next, &obj->active_list_head,
+ active_list) {
+ if (fence_is_signaled_locked(&pt->base))
+ list_del(&pt->active_list);
}
- spin_unlock_irqrestore(&obj->active_list_lock, flags);
-
- list_for_each_safe(pos, n, &signaled_pts) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, signaled_list);
-
- list_del_init(pos);
- sync_fence_signal_pt(pt);
- kref_put(&pt->fence->kref, sync_fence_free);
- }
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
}
EXPORT_SYMBOL(sync_timeline_signal);
-struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
+struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size)
{
+ unsigned long flags;
struct sync_pt *pt;
if (size < sizeof(struct sync_pt))
@@ -180,87 +133,28 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
if (pt == NULL)
return NULL;
+ spin_lock_irqsave(&obj->child_list_lock, flags);
+ sync_timeline_get(obj);
+ fence_init(&pt->base, &android_fence_ops, &obj->child_list_lock,
+ obj->context, ++obj->value);
+ list_add_tail(&pt->child_list, &obj->child_list_head);
INIT_LIST_HEAD(&pt->active_list);
- kref_get(&parent->kref);
- sync_timeline_add_pt(parent, pt);
-
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
return pt;
}
EXPORT_SYMBOL(sync_pt_create);
void sync_pt_free(struct sync_pt *pt)
{
- if (pt->parent->ops->free_pt)
- pt->parent->ops->free_pt(pt);
-
- sync_timeline_remove_pt(pt);
-
- kref_put(&pt->parent->kref, sync_timeline_free);
-
- kfree(pt);
+ fence_put(&pt->base);
}
EXPORT_SYMBOL(sync_pt_free);
-/* call with pt->parent->active_list_lock held */
-static int _sync_pt_has_signaled(struct sync_pt *pt)
-{
- int old_status = pt->status;
-
- if (!pt->status)
- pt->status = pt->parent->ops->has_signaled(pt);
-
- if (!pt->status && pt->parent->destroyed)
- pt->status = -ENOENT;
-
- if (pt->status != old_status)
- pt->timestamp = ktime_get();
-
- return pt->status;
-}
-
-static struct sync_pt *sync_pt_dup(struct sync_pt *pt)
-{
- return pt->parent->ops->dup(pt);
-}
-
-/* Adds a sync pt to the active queue. Called when added to a fence */
-static void sync_pt_activate(struct sync_pt *pt)
-{
- struct sync_timeline *obj = pt->parent;
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&obj->active_list_lock, flags);
-
- err = _sync_pt_has_signaled(pt);
- if (err != 0)
- goto out;
-
- list_add_tail(&pt->active_list, &obj->active_list_head);
-
-out:
- spin_unlock_irqrestore(&obj->active_list_lock, flags);
-}
-
-static int sync_fence_release(struct inode *inode, struct file *file);
-static unsigned int sync_fence_poll(struct file *file, poll_table *wait);
-static long sync_fence_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-
-
-static const struct file_operations sync_fence_fops = {
- .release = sync_fence_release,
- .poll = sync_fence_poll,
- .unlocked_ioctl = sync_fence_ioctl,
- .compat_ioctl = sync_fence_ioctl,
-};
-
-static struct sync_fence *sync_fence_alloc(const char *name)
+static struct sync_fence *sync_fence_alloc(int size, const char *name)
{
struct sync_fence *fence;
- unsigned long flags;
- fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL);
+ fence = kzalloc(size, GFP_KERNEL);
if (fence == NULL)
return NULL;
@@ -272,16 +166,8 @@ static struct sync_fence *sync_fence_alloc(const char *name)
kref_init(&fence->kref);
strlcpy(fence->name, name, sizeof(fence->name));
- INIT_LIST_HEAD(&fence->pt_list_head);
- INIT_LIST_HEAD(&fence->waiter_list_head);
- spin_lock_init(&fence->waiter_list_lock);
-
init_waitqueue_head(&fence->wq);
- spin_lock_irqsave(&sync_fence_list_lock, flags);
- list_add_tail(&fence->sync_fence_list, &sync_fence_list_head);
- spin_unlock_irqrestore(&sync_fence_list_lock, flags);
-
return fence;
err:
@@ -289,120 +175,42 @@ err:
return NULL;
}
-/* TODO: implement a create which takes more that one sync_pt */
-struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
+static void fence_check_cb_func(struct fence *f, struct fence_cb *cb)
{
+ struct sync_fence_cb *check;
struct sync_fence *fence;
- if (pt->fence)
- return NULL;
-
- fence = sync_fence_alloc(name);
- if (fence == NULL)
- return NULL;
-
- pt->fence = fence;
- list_add(&pt->pt_list, &fence->pt_list_head);
- sync_pt_activate(pt);
+ check = container_of(cb, struct sync_fence_cb, cb);
+ fence = check->fence;
- /*
- * signal the fence in case pt was activated before
- * sync_pt_activate(pt) was called
- */
- sync_fence_signal_pt(pt);
-
- return fence;
+ if (atomic_dec_and_test(&fence->status))
+ wake_up_all(&fence->wq);
}
-EXPORT_SYMBOL(sync_fence_create);
-static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src)
-{
- struct list_head *pos;
-
- list_for_each(pos, &src->pt_list_head) {
- struct sync_pt *orig_pt =
- container_of(pos, struct sync_pt, pt_list);
- struct sync_pt *new_pt = sync_pt_dup(orig_pt);
-
- if (new_pt == NULL)
- return -ENOMEM;
-
- new_pt->fence = dst;
- list_add(&new_pt->pt_list, &dst->pt_list_head);
- }
-
- return 0;
-}
-
-static int sync_fence_merge_pts(struct sync_fence *dst, struct sync_fence *src)
-{
- struct list_head *src_pos, *dst_pos, *n;
-
- list_for_each(src_pos, &src->pt_list_head) {
- struct sync_pt *src_pt =
- container_of(src_pos, struct sync_pt, pt_list);
- bool collapsed = false;
-
- list_for_each_safe(dst_pos, n, &dst->pt_list_head) {
- struct sync_pt *dst_pt =
- container_of(dst_pos, struct sync_pt, pt_list);
- /* collapse two sync_pts on the same timeline
- * to a single sync_pt that will signal at
- * the later of the two
- */
- if (dst_pt->parent == src_pt->parent) {
- if (dst_pt->parent->ops->compare(dst_pt, src_pt)
- == -1) {
- struct sync_pt *new_pt =
- sync_pt_dup(src_pt);
- if (new_pt == NULL)
- return -ENOMEM;
-
- new_pt->fence = dst;
- list_replace(&dst_pt->pt_list,
- &new_pt->pt_list);
- sync_pt_free(dst_pt);
- }
- collapsed = true;
- break;
- }
- }
-
- if (!collapsed) {
- struct sync_pt *new_pt = sync_pt_dup(src_pt);
-
- if (new_pt == NULL)
- return -ENOMEM;
-
- new_pt->fence = dst;
- list_add(&new_pt->pt_list, &dst->pt_list_head);
- }
- }
-
- return 0;
-}
-
-static void sync_fence_detach_pts(struct sync_fence *fence)
+/* TODO: implement a create which takes more that one sync_pt */
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
{
- struct list_head *pos, *n;
+ struct sync_fence *fence;
- list_for_each_safe(pos, n, &fence->pt_list_head) {
- struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+ fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name);
+ if (fence == NULL)
+ return NULL;
- sync_timeline_remove_pt(pt);
- }
-}
+ fence->num_fences = 1;
+ atomic_set(&fence->status, 1);
-static void sync_fence_free_pts(struct sync_fence *fence)
-{
- struct list_head *pos, *n;
+ fence_get(&pt->base);
+ fence->cbs[0].sync_pt = &pt->base;
+ fence->cbs[0].fence = fence;
+ if (fence_add_callback(&pt->base, &fence->cbs[0].cb,
+ fence_check_cb_func))
+ atomic_dec(&fence->status);
- list_for_each_safe(pos, n, &fence->pt_list_head) {
- struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+ sync_fence_debug_add(fence);
- sync_pt_free(pt);
- }
+ return fence;
}
+EXPORT_SYMBOL(sync_fence_create);
struct sync_fence *sync_fence_fdget(int fd)
{
@@ -434,197 +242,155 @@ void sync_fence_install(struct sync_fence *fence, int fd)
}
EXPORT_SYMBOL(sync_fence_install);
-static int sync_fence_get_status(struct sync_fence *fence)
+static void sync_fence_add_pt(struct sync_fence *fence,
+ int *i, struct fence *pt)
{
- struct list_head *pos;
- int status = 1;
-
- list_for_each(pos, &fence->pt_list_head) {
- struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
- int pt_status = pt->status;
-
- if (pt_status < 0) {
- status = pt_status;
- break;
- } else if (status == 1) {
- status = pt_status;
- }
- }
+ fence->cbs[*i].sync_pt = pt;
+ fence->cbs[*i].fence = fence;
- return status;
+ if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) {
+ fence_get(pt);
+ (*i)++;
+ }
}
struct sync_fence *sync_fence_merge(const char *name,
struct sync_fence *a, struct sync_fence *b)
{
+ int num_fences = a->num_fences + b->num_fences;
struct sync_fence *fence;
- struct list_head *pos;
- int err;
+ int i, i_a, i_b;
+ unsigned long size = offsetof(struct sync_fence, cbs[num_fences]);
- fence = sync_fence_alloc(name);
+ fence = sync_fence_alloc(size, name);
if (fence == NULL)
return NULL;
- err = sync_fence_copy_pts(fence, a);
- if (err < 0)
- goto err;
+ atomic_set(&fence->status, num_fences);
- err = sync_fence_merge_pts(fence, b);
- if (err < 0)
- goto err;
+ /*
+ * Assume sync_fence a and b are both ordered and have no
+ * duplicates with the same context.
+ *
+ * If a sync_fence can only be created with sync_fence_merge
+ * and sync_fence_create, this is a reasonable assumption.
+ */
+ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) {
+ struct fence *pt_a = a->cbs[i_a].sync_pt;
+ struct fence *pt_b = b->cbs[i_b].sync_pt;
+
+ if (pt_a->context < pt_b->context) {
+ sync_fence_add_pt(fence, &i, pt_a);
+
+ i_a++;
+ } else if (pt_a->context > pt_b->context) {
+ sync_fence_add_pt(fence, &i, pt_b);
+
+ i_b++;
+ } else {
+ if (pt_a->seqno - pt_b->seqno <= INT_MAX)
+ sync_fence_add_pt(fence, &i, pt_a);
+ else
+ sync_fence_add_pt(fence, &i, pt_b);
- list_for_each(pos, &fence->pt_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, pt_list);
- sync_pt_activate(pt);
+ i_a++;
+ i_b++;
+ }
}
- /*
- * signal the fence in case one of it's pts were activated before
- * they were activated
- */
- sync_fence_signal_pt(list_first_entry(&fence->pt_list_head,
- struct sync_pt,
- pt_list));
+ for (; i_a < a->num_fences; i_a++)
+ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt);
+
+ for (; i_b < b->num_fences; i_b++)
+ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt);
+
+ if (num_fences > i)
+ atomic_sub(num_fences - i, &fence->status);
+ fence->num_fences = i;
+ sync_fence_debug_add(fence);
return fence;
-err:
- sync_fence_free_pts(fence);
- kfree(fence);
- return NULL;
}
EXPORT_SYMBOL(sync_fence_merge);
-static void sync_fence_signal_pt(struct sync_pt *pt)
+int sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode,
+ int wake_flags, void *key)
{
- LIST_HEAD(signaled_waiters);
- struct sync_fence *fence = pt->fence;
- struct list_head *pos;
- struct list_head *n;
- unsigned long flags;
- int status;
-
- status = sync_fence_get_status(fence);
-
- spin_lock_irqsave(&fence->waiter_list_lock, flags);
- /*
- * this should protect against two threads racing on the signaled
- * false -> true transition
- */
- if (status && !fence->status) {
- list_for_each_safe(pos, n, &fence->waiter_list_head)
- list_move(pos, &signaled_waiters);
-
- fence->status = status;
- } else {
- status = 0;
- }
- spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ struct sync_fence_waiter *wait;
- if (status) {
- list_for_each_safe(pos, n, &signaled_waiters) {
- struct sync_fence_waiter *waiter =
- container_of(pos, struct sync_fence_waiter,
- waiter_list);
+ wait = container_of(curr, struct sync_fence_waiter, work);
+ list_del_init(&wait->work.task_list);
- list_del(pos);
- waiter->callback(fence, waiter);
- }
- wake_up(&fence->wq);
- }
+ wait->callback(wait->work.private, wait);
+ return 1;
}
int sync_fence_wait_async(struct sync_fence *fence,
struct sync_fence_waiter *waiter)
{
+ int err = atomic_read(&fence->status);
unsigned long flags;
- int err = 0;
- spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ if (err < 0)
+ return err;
+
+ if (!err)
+ return 1;
- if (fence->status) {
- err = fence->status;
- goto out;
- }
+ init_waitqueue_func_entry(&waiter->work, sync_fence_wake_up_wq);
+ waiter->work.private = fence;
- list_add_tail(&waiter->waiter_list, &fence->waiter_list_head);
-out:
- spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ spin_lock_irqsave(&fence->wq.lock, flags);
+ err = atomic_read(&fence->status);
+ if (err > 0)
+ __add_wait_queue_tail(&fence->wq, &waiter->work);
+ spin_unlock_irqrestore(&fence->wq.lock, flags);
- return err;
+ if (err < 0)
+ return err;
+
+ return !err;
}
EXPORT_SYMBOL(sync_fence_wait_async);
int sync_fence_cancel_async(struct sync_fence *fence,
struct sync_fence_waiter *waiter)
{
- struct list_head *pos;
- struct list_head *n;
unsigned long flags;
- int ret = -ENOENT;
+ int ret = 0;
- spin_lock_irqsave(&fence->waiter_list_lock, flags);
- /*
- * Make sure waiter is still in waiter_list because it is possible for
- * the waiter to be removed from the list while the callback is still
- * pending.
- */
- list_for_each_safe(pos, n, &fence->waiter_list_head) {
- struct sync_fence_waiter *list_waiter =
- container_of(pos, struct sync_fence_waiter,
- waiter_list);
- if (list_waiter == waiter) {
- list_del(pos);
- ret = 0;
- break;
- }
- }
- spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ spin_lock_irqsave(&fence->wq.lock, flags);
+ if (!list_empty(&waiter->work.task_list))
+ list_del_init(&waiter->work.task_list);
+ else
+ ret = -ENOENT;
+ spin_unlock_irqrestore(&fence->wq.lock, flags);
return ret;
}
EXPORT_SYMBOL(sync_fence_cancel_async);
-static bool sync_fence_check(struct sync_fence *fence)
-{
- /*
- * Make sure that reads to fence->status are ordered with the
- * wait queue event triggering
- */
- smp_rmb();
- return fence->status != 0;
-}
-
int sync_fence_wait(struct sync_fence *fence, long timeout)
{
- int err = 0;
- struct sync_pt *pt;
-
- trace_sync_wait(fence, 1);
- list_for_each_entry(pt, &fence->pt_list_head, pt_list)
- trace_sync_pt(pt);
+ long ret;
+ int i;
- if (timeout > 0) {
+ if (timeout < 0)
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ else
timeout = msecs_to_jiffies(timeout);
- err = wait_event_interruptible_timeout(fence->wq,
- sync_fence_check(fence),
- timeout);
- } else if (timeout < 0) {
- err = wait_event_interruptible(fence->wq,
- sync_fence_check(fence));
- }
- trace_sync_wait(fence, 0);
- if (err < 0)
- return err;
-
- if (fence->status < 0) {
- pr_info("fence error %d on [%p]\n", fence->status, fence);
- sync_dump();
- return fence->status;
- }
+ trace_sync_wait(fence, 1);
+ for (i = 0; i < fence->num_fences; ++i)
+ trace_sync_pt(fence->cbs[i].sync_pt);
+ ret = wait_event_interruptible_timeout(fence->wq,
+ atomic_read(&fence->status) <= 0,
+ timeout);
+ trace_sync_wait(fence, 0);
- if (fence->status == 0) {
- if (timeout > 0) {
+ if (ret < 0)
+ return ret;
+ else if (ret == 0) {
+ if (timeout) {
pr_info("fence timeout on [%p] after %dms\n", fence,
jiffies_to_msecs(timeout));
sync_dump();
@@ -632,15 +398,136 @@ int sync_fence_wait(struct sync_fence *fence, long timeout)
return -ETIME;
}
- return 0;
+ ret = atomic_read(&fence->status);
+ if (ret) {
+ pr_info("fence error %ld on [%p]\n", ret, fence);
+ sync_dump();
+ }
+ return ret;
}
EXPORT_SYMBOL(sync_fence_wait);
+static const char *android_fence_get_driver_name(struct fence *fence)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ return parent->ops->driver_name;
+}
+
+static const char *android_fence_get_timeline_name(struct fence *fence)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ return parent->name;
+}
+
+static void android_fence_release(struct fence *fence)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+ unsigned long flags;
+
+ spin_lock_irqsave(fence->lock, flags);
+ list_del(&pt->child_list);
+ if (WARN_ON_ONCE(!list_empty(&pt->active_list)))
+ list_del(&pt->active_list);
+ spin_unlock_irqrestore(fence->lock, flags);
+
+ if (parent->ops->free_pt)
+ parent->ops->free_pt(pt);
+
+ sync_timeline_put(parent);
+ fence_free(&pt->base);
+}
+
+static bool android_fence_signaled(struct fence *fence)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+ int ret;
+
+ ret = parent->ops->has_signaled(pt);
+ if (ret < 0)
+ fence->status = ret;
+ return ret;
+}
+
+static bool android_fence_enable_signaling(struct fence *fence)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ if (android_fence_signaled(fence))
+ return false;
+
+ list_add_tail(&pt->active_list, &parent->active_list_head);
+ return true;
+}
+
+static int android_fence_fill_driver_data(struct fence *fence,
+ void *data, int size)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ if (!parent->ops->fill_driver_data)
+ return 0;
+ return parent->ops->fill_driver_data(pt, data, size);
+}
+
+static void android_fence_value_str(struct fence *fence,
+ char *str, int size)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ if (!parent->ops->pt_value_str) {
+ if (size)
+ *str = 0;
+ return;
+ }
+ parent->ops->pt_value_str(pt, str, size);
+}
+
+static void android_fence_timeline_value_str(struct fence *fence,
+ char *str, int size)
+{
+ struct sync_pt *pt = container_of(fence, struct sync_pt, base);
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ if (!parent->ops->timeline_value_str) {
+ if (size)
+ *str = 0;
+ return;
+ }
+ parent->ops->timeline_value_str(parent, str, size);
+}
+
+static const struct fence_ops android_fence_ops = {
+ .get_driver_name = android_fence_get_driver_name,
+ .get_timeline_name = android_fence_get_timeline_name,
+ .enable_signaling = android_fence_enable_signaling,
+ .signaled = android_fence_signaled,
+ .wait = fence_default_wait,
+ .release = android_fence_release,
+ .fill_driver_data = android_fence_fill_driver_data,
+ .fence_value_str = android_fence_value_str,
+ .timeline_value_str = android_fence_timeline_value_str,
+};
+
static void sync_fence_free(struct kref *kref)
{
struct sync_fence *fence = container_of(kref, struct sync_fence, kref);
+ int i, status = atomic_read(&fence->status);
- sync_fence_free_pts(fence);
+ for (i = 0; i < fence->num_fences; ++i) {
+ if (status)
+ fence_remove_callback(fence->cbs[i].sync_pt,
+ &fence->cbs[i].cb);
+ fence_put(fence->cbs[i].sync_pt);
+ }
kfree(fence);
}
@@ -648,47 +535,27 @@ static void sync_fence_free(struct kref *kref)
static int sync_fence_release(struct inode *inode, struct file *file)
{
struct sync_fence *fence = file->private_data;
- unsigned long flags;
-
- /*
- * We need to remove all ways to access this fence before droping
- * our ref.
- *
- * start with its membership in the global fence list
- */
- spin_lock_irqsave(&sync_fence_list_lock, flags);
- list_del(&fence->sync_fence_list);
- spin_unlock_irqrestore(&sync_fence_list_lock, flags);
- /*
- * remove its pts from their parents so that sync_timeline_signal()
- * can't reference the fence.
- */
- sync_fence_detach_pts(fence);
+ sync_fence_debug_remove(fence);
kref_put(&fence->kref, sync_fence_free);
-
return 0;
}
static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
{
struct sync_fence *fence = file->private_data;
+ int status;
poll_wait(file, &fence->wq, wait);
- /*
- * Make sure that reads to fence->status are ordered with the
- * wait queue event triggering
- */
- smp_rmb();
+ status = atomic_read(&fence->status);
- if (fence->status == 1)
+ if (!status)
return POLLIN;
- else if (fence->status < 0)
+ else if (status < 0)
return POLLERR;
- else
- return 0;
+ return 0;
}
static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg)
@@ -750,7 +617,7 @@ err_put_fd:
return err;
}
-static int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
+static int sync_fill_pt_info(struct fence *fence, void *data, int size)
{
struct sync_pt_info *info = data;
int ret;
@@ -760,20 +627,24 @@ static int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
info->len = sizeof(struct sync_pt_info);
- if (pt->parent->ops->fill_driver_data) {
- ret = pt->parent->ops->fill_driver_data(pt, info->driver_data,
- size - sizeof(*info));
+ if (fence->ops->fill_driver_data) {
+ ret = fence->ops->fill_driver_data(fence, info->driver_data,
+ size - sizeof(*info));
if (ret < 0)
return ret;
info->len += ret;
}
- strlcpy(info->obj_name, pt->parent->name, sizeof(info->obj_name));
- strlcpy(info->driver_name, pt->parent->ops->driver_name,
+ strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
+ sizeof(info->obj_name));
+ strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
sizeof(info->driver_name));
- info->status = pt->status;
- info->timestamp_ns = ktime_to_ns(pt->timestamp);
+ if (fence_is_signaled(fence))
+ info->status = fence->status >= 0 ? 1 : fence->status;
+ else
+ info->status = 0;
+ info->timestamp_ns = ktime_to_ns(fence->timestamp);
return info->len;
}
@@ -782,10 +653,9 @@ static long sync_fence_ioctl_fence_info(struct sync_fence *fence,
unsigned long arg)
{
struct sync_fence_info_data *data;
- struct list_head *pos;
__u32 size;
__u32 len = 0;
- int ret;
+ int ret, i;
if (copy_from_user(&size, (void __user *)arg, sizeof(size)))
return -EFAULT;
@@ -801,12 +671,14 @@ static long sync_fence_ioctl_fence_info(struct sync_fence *fence,
return -ENOMEM;
strlcpy(data->name, fence->name, sizeof(data->name));
- data->status = fence->status;
+ data->status = atomic_read(&fence->status);
+ if (data->status >= 0)
+ data->status = !data->status;
+
len = sizeof(struct sync_fence_info_data);
- list_for_each(pos, &fence->pt_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, pt_list);
+ for (i = 0; i < fence->num_fences; ++i) {
+ struct fence *pt = fence->cbs[i].sync_pt;
ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len);
@@ -833,7 +705,6 @@ static long sync_fence_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
struct sync_fence *fence = file->private_data;
-
switch (cmd) {
case SYNC_IOC_WAIT:
return sync_fence_ioctl_wait(fence, arg);
@@ -849,181 +720,10 @@ static long sync_fence_ioctl(struct file *file, unsigned int cmd,
}
}
-#ifdef CONFIG_DEBUG_FS
-static const char *sync_status_str(int status)
-{
- if (status > 0)
- return "signaled";
- else if (status == 0)
- return "active";
- else
- return "error";
-}
-
-static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
-{
- int status = pt->status;
-
- seq_printf(s, " %s%spt %s",
- fence ? pt->parent->name : "",
- fence ? "_" : "",
- sync_status_str(status));
- if (pt->status) {
- struct timeval tv = ktime_to_timeval(pt->timestamp);
-
- seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
- }
-
- if (pt->parent->ops->timeline_value_str &&
- pt->parent->ops->pt_value_str) {
- char value[64];
-
- pt->parent->ops->pt_value_str(pt, value, sizeof(value));
- seq_printf(s, ": %s", value);
- if (fence) {
- pt->parent->ops->timeline_value_str(pt->parent, value,
- sizeof(value));
- seq_printf(s, " / %s", value);
- }
- } else if (pt->parent->ops->print_pt) {
- seq_puts(s, ": ");
- pt->parent->ops->print_pt(s, pt);
- }
-
- seq_puts(s, "\n");
-}
-
-static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
-{
- struct list_head *pos;
- unsigned long flags;
-
- seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
-
- if (obj->ops->timeline_value_str) {
- char value[64];
-
- obj->ops->timeline_value_str(obj, value, sizeof(value));
- seq_printf(s, ": %s", value);
- } else if (obj->ops->print_obj) {
- seq_puts(s, ": ");
- obj->ops->print_obj(s, obj);
- }
-
- seq_puts(s, "\n");
-
- 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);
- sync_print_pt(s, pt, false);
- }
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-
-static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
-{
- struct list_head *pos;
- unsigned long flags;
-
- seq_printf(s, "[%p] %s: %s\n", fence, fence->name,
- sync_status_str(fence->status));
-
- list_for_each(pos, &fence->pt_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, pt_list);
- sync_print_pt(s, pt, true);
- }
-
- spin_lock_irqsave(&fence->waiter_list_lock, flags);
- list_for_each(pos, &fence->waiter_list_head) {
- struct sync_fence_waiter *waiter =
- container_of(pos, struct sync_fence_waiter,
- waiter_list);
-
- seq_printf(s, "waiter %pF\n", waiter->callback);
- }
- spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
-}
-
-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);
- list_for_each(pos, &sync_timeline_list_head) {
- struct sync_timeline *obj =
- container_of(pos, struct sync_timeline,
- sync_timeline_list);
-
- sync_print_obj(s, obj);
- seq_puts(s, "\n");
- }
- spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
-
- seq_puts(s, "fences:\n--------------\n");
-
- spin_lock_irqsave(&sync_fence_list_lock, flags);
- list_for_each(pos, &sync_fence_list_head) {
- struct sync_fence *fence =
- container_of(pos, struct sync_fence, sync_fence_list);
-
- sync_print_fence(s, fence);
- seq_puts(s, "\n");
- }
- spin_unlock_irqrestore(&sync_fence_list_lock, flags);
- return 0;
-}
-
-static int sync_debugfs_open(struct inode *inode, struct file *file)
-{
- return single_open(file, sync_debugfs_show, inode->i_private);
-}
-
-static const struct file_operations sync_debugfs_fops = {
- .open = sync_debugfs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+static const struct file_operations sync_fence_fops = {
+ .release = sync_fence_release,
+ .poll = sync_fence_poll,
+ .unlocked_ioctl = sync_fence_ioctl,
+ .compat_ioctl = sync_fence_ioctl,
};
-static __init int sync_debugfs_init(void)
-{
- debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops);
- return 0;
-}
-late_initcall(sync_debugfs_init);
-
-#define DUMP_CHUNK 256
-static char sync_dump_buf[64 * 1024];
-static void sync_dump(void)
-{
- struct seq_file s = {
- .buf = sync_dump_buf,
- .size = sizeof(sync_dump_buf) - 1,
- };
- int i;
-
- sync_debugfs_show(&s, NULL);
-
- for (i = 0; i < s.count; i += DUMP_CHUNK) {
- if ((s.count - i) > DUMP_CHUNK) {
- char c = s.buf[i + DUMP_CHUNK];
-
- s.buf[i + DUMP_CHUNK] = 0;
- pr_cont("%s", s.buf + i);
- s.buf[i + DUMP_CHUNK] = c;
- } else {
- s.buf[s.count] = 0;
- pr_cont("%s", s.buf + i);
- }
- }
-}
-#else
-static void sync_dump(void)
-{
-}
-#endif
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index eaf57cccf626..66b0f431f63e 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <linux/fence.h>
#include "uapi/sync.h"
@@ -40,8 +41,6 @@ struct sync_fence;
* -1 if a will signal before b
* @free_pt: called before sync_pt is freed
* @release_obj: called before sync_timeline is freed
- * @print_obj: deprecated
- * @print_pt: deprecated
* @fill_driver_data: write implementation specific driver data to data.
* should return an error if there is not enough room
* as specified by size. This information is returned
@@ -67,13 +66,6 @@ struct sync_timeline_ops {
/* optional */
void (*release_obj)(struct sync_timeline *sync_timeline);
- /* deprecated */
- void (*print_obj)(struct seq_file *s,
- struct sync_timeline *sync_timeline);
-
- /* deprecated */
- void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
-
/* optional */
int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
@@ -104,19 +96,21 @@ struct sync_timeline {
/* protected by child_list_lock */
bool destroyed;
+ int context, value;
struct list_head child_list_head;
spinlock_t child_list_lock;
struct list_head active_list_head;
- spinlock_t active_list_lock;
+#ifdef CONFIG_DEBUG_FS
struct list_head sync_timeline_list;
+#endif
};
/**
* struct sync_pt - sync point
- * @parent: sync_timeline to which this sync_pt belongs
+ * @fence: base fence class
* @child_list: membership in sync_timeline.child_list_head
* @active_list: membership in sync_timeline.active_list_head
* @signaled_list: membership in temporary signaled_list on stack
@@ -127,19 +121,22 @@ struct sync_timeline {
* signaled or error.
*/
struct sync_pt {
- struct sync_timeline *parent;
- struct list_head child_list;
+ struct fence base;
+ struct list_head child_list;
struct list_head active_list;
- struct list_head signaled_list;
-
- struct sync_fence *fence;
- struct list_head pt_list;
+};
- /* protected by parent->active_list_lock */
- int status;
+static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt)
+{
+ return container_of(pt->base.lock, struct sync_timeline,
+ child_list_lock);
+}
- ktime_t timestamp;
+struct sync_fence_cb {
+ struct fence_cb cb;
+ struct fence *sync_pt;
+ struct sync_fence *fence;
};
/**
@@ -149,9 +146,7 @@ struct sync_pt {
* @name: name of sync_fence. Useful for debugging
* @pt_list_head: list of sync_pts in the fence. immutable once fence
* is created
- * @waiter_list_head: list of asynchronous waiters on this fence
- * @waiter_list_lock: lock protecting @waiter_list_head and @status
- * @status: 1: signaled, 0:active, <0: error
+ * @status: 0: signaled, >0:active, <0: error
*
* @wq: wait queue for fence signaling
* @sync_fence_list: membership in global fence list
@@ -160,17 +155,15 @@ struct sync_fence {
struct file *file;
struct kref kref;
char name[32];
-
- /* this list is immutable once the fence is created */
- struct list_head pt_list_head;
-
- struct list_head waiter_list_head;
- spinlock_t waiter_list_lock; /* also protects status */
- int status;
+#ifdef CONFIG_DEBUG_FS
+ struct list_head sync_fence_list;
+#endif
+ int num_fences;
wait_queue_head_t wq;
+ atomic_t status;
- struct list_head sync_fence_list;
+ struct sync_fence_cb cbs[];
};
struct sync_fence_waiter;
@@ -184,14 +177,14 @@ typedef void (*sync_callback_t)(struct sync_fence *fence,
* @callback_data: pointer to pass to @callback
*/
struct sync_fence_waiter {
- struct list_head waiter_list;
-
- sync_callback_t callback;
+ wait_queue_t work;
+ sync_callback_t callback;
};
static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter,
sync_callback_t callback)
{
+ INIT_LIST_HEAD(&waiter->work.task_list);
waiter->callback = callback;
}
@@ -341,4 +334,22 @@ int sync_fence_cancel_async(struct sync_fence *fence,
*/
int sync_fence_wait(struct sync_fence *fence, long timeout);
+#ifdef CONFIG_DEBUG_FS
+
+extern void sync_timeline_debug_add(struct sync_timeline *obj);
+extern void sync_timeline_debug_remove(struct sync_timeline *obj);
+extern void sync_fence_debug_add(struct sync_fence *fence);
+extern void sync_fence_debug_remove(struct sync_fence *fence);
+extern void sync_dump(void);
+
+#else
+# define sync_timeline_debug_add(obj)
+# define sync_timeline_debug_remove(obj)
+# define sync_fence_debug_add(fence)
+# define sync_fence_debug_remove(fence)
+# define sync_dump()
+#endif
+int sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode,
+ int wake_flags, void *key);
+
#endif /* _LINUX_SYNC_H */
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
new file mode 100644
index 000000000000..257fc91bf02b
--- /dev/null
+++ b/drivers/staging/android/sync_debug.c
@@ -0,0 +1,252 @@
+/*
+ * drivers/base/sync.c
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/export.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/anon_inodes.h>
+#include "sync.h"
+
+#ifdef CONFIG_DEBUG_FS
+
+static LIST_HEAD(sync_timeline_list_head);
+static DEFINE_SPINLOCK(sync_timeline_list_lock);
+static LIST_HEAD(sync_fence_list_head);
+static DEFINE_SPINLOCK(sync_fence_list_lock);
+
+void sync_timeline_debug_add(struct sync_timeline *obj)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head);
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+}
+
+void sync_timeline_debug_remove(struct sync_timeline *obj)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ list_del(&obj->sync_timeline_list);
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+}
+
+void sync_fence_debug_add(struct sync_fence *fence)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_add_tail(&fence->sync_fence_list, &sync_fence_list_head);
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+}
+
+void sync_fence_debug_remove(struct sync_fence *fence)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_del(&fence->sync_fence_list);
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+}
+
+static const char *sync_status_str(int status)
+{
+ if (status == 0)
+ return "signaled";
+
+ if (status > 0)
+ return "active";
+
+ return "error";
+}
+
+static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
+{
+ int status = 1;
+ struct sync_timeline *parent = sync_pt_parent(pt);
+
+ if (fence_is_signaled_locked(&pt->base))
+ status = pt->base.status;
+
+ seq_printf(s, " %s%spt %s",
+ fence ? parent->name : "",
+ fence ? "_" : "",
+ sync_status_str(status));
+
+ if (status <= 0) {
+ struct timeval tv = ktime_to_timeval(pt->base.timestamp);
+
+ seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
+ }
+
+ if (parent->ops->timeline_value_str &&
+ parent->ops->pt_value_str) {
+ char value[64];
+
+ parent->ops->pt_value_str(pt, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ if (fence) {
+ parent->ops->timeline_value_str(parent, value,
+ sizeof(value));
+ seq_printf(s, " / %s", value);
+ }
+ }
+
+ seq_puts(s, "\n");
+}
+
+static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
+{
+ struct list_head *pos;
+ unsigned long flags;
+
+ seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
+
+ if (obj->ops->timeline_value_str) {
+ char value[64];
+
+ obj->ops->timeline_value_str(obj, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ }
+
+ seq_puts(s, "\n");
+
+ 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);
+ sync_print_pt(s, pt, false);
+ }
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
+}
+
+static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
+{
+ wait_queue_t *pos;
+ unsigned long flags;
+ int i;
+
+ seq_printf(s, "[%p] %s: %s\n", fence, fence->name,
+ sync_status_str(atomic_read(&fence->status)));
+
+ for (i = 0; i < fence->num_fences; ++i) {
+ struct sync_pt *pt =
+ container_of(fence->cbs[i].sync_pt,
+ struct sync_pt, base);
+
+ sync_print_pt(s, pt, true);
+ }
+
+ spin_lock_irqsave(&fence->wq.lock, flags);
+ list_for_each_entry(pos, &fence->wq.task_list, task_list) {
+ struct sync_fence_waiter *waiter;
+
+ if (pos->func != &sync_fence_wake_up_wq)
+ continue;
+
+ waiter = container_of(pos, struct sync_fence_waiter, work);
+
+ seq_printf(s, "waiter %pF\n", waiter->callback);
+ }
+ spin_unlock_irqrestore(&fence->wq.lock, flags);
+}
+
+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);
+ list_for_each(pos, &sync_timeline_list_head) {
+ struct sync_timeline *obj =
+ container_of(pos, struct sync_timeline,
+ sync_timeline_list);
+
+ sync_print_obj(s, obj);
+ seq_puts(s, "\n");
+ }
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+
+ seq_puts(s, "fences:\n--------------\n");
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_for_each(pos, &sync_fence_list_head) {
+ struct sync_fence *fence =
+ container_of(pos, struct sync_fence, sync_fence_list);
+
+ sync_print_fence(s, fence);
+ seq_puts(s, "\n");
+ }
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+ return 0;
+}
+
+static int sync_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sync_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations sync_debugfs_fops = {
+ .open = sync_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static __init int sync_debugfs_init(void)
+{
+ debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops);
+ return 0;
+}
+late_initcall(sync_debugfs_init);
+
+#define DUMP_CHUNK 256
+static char sync_dump_buf[64 * 1024];
+void sync_dump(void)
+{
+ struct seq_file s = {
+ .buf = sync_dump_buf,
+ .size = sizeof(sync_dump_buf) - 1,
+ };
+ int i;
+
+ sync_debugfs_show(&s, NULL);
+
+ for (i = 0; i < s.count; i += DUMP_CHUNK) {
+ if ((s.count - i) > DUMP_CHUNK) {
+ char c = s.buf[i + DUMP_CHUNK];
+
+ s.buf[i + DUMP_CHUNK] = 0;
+ pr_cont("%s", s.buf + i);
+ s.buf[i + DUMP_CHUNK] = c;
+ } else {
+ s.buf[s.count] = 0;
+ pr_cont("%s", s.buf + i);
+ }
+ }
+}
+
+#endif
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index 180c209a009e..8fa4758517c0 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -45,16 +45,17 @@ static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
static int gpio_get_time(struct timed_output_dev *dev)
{
- struct timed_gpio_data *data =
- container_of(dev, struct timed_gpio_data, dev);
+ struct timed_gpio_data *data;
+ struct timeval t;
- if (hrtimer_active(&data->timer)) {
- ktime_t r = hrtimer_get_remaining(&data->timer);
- struct timeval t = ktime_to_timeval(r);
+ data = container_of(dev, struct timed_gpio_data, dev);
- return t.tv_sec * 1000 + t.tv_usec / 1000;
- } else
+ if (!hrtimer_active(&data->timer))
return 0;
+
+ t = ktime_to_timeval(hrtimer_get_remaining(&data->timer));
+
+ return t.tv_sec * 1000 + t.tv_usec / 1000;
}
static void gpio_enable(struct timed_output_dev *dev, int value)
diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c
index c341ac11c5a3..b41429f379fe 100644
--- a/drivers/staging/android/timed_output.c
+++ b/drivers/staging/android/timed_output.c
@@ -41,8 +41,10 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
{
struct timed_output_dev *tdev = dev_get_drvdata(dev);
int value;
+ int rc;
- if (sscanf(buf, "%d", &value) != 1)
+ rc = kstrtoint(buf, 0, &value);
+ if (rc != 0)
return -EINVAL;
tdev->enable(tdev, value);
diff --git a/drivers/staging/android/trace/sync.h b/drivers/staging/android/trace/sync.h
index 95462359ba57..77edb977a7bf 100644
--- a/drivers/staging/android/trace/sync.h
+++ b/drivers/staging/android/trace/sync.h
@@ -45,7 +45,7 @@ TRACE_EVENT(sync_wait,
TP_fast_assign(
__assign_str(name, fence->name);
- __entry->status = fence->status;
+ __entry->status = atomic_read(&fence->status);
__entry->begin = begin;
),
@@ -54,19 +54,19 @@ TRACE_EVENT(sync_wait,
);
TRACE_EVENT(sync_pt,
- TP_PROTO(struct sync_pt *pt),
+ TP_PROTO(struct fence *pt),
TP_ARGS(pt),
TP_STRUCT__entry(
- __string(timeline, pt->parent->name)
+ __string(timeline, pt->ops->get_timeline_name(pt))
__array(char, value, 32)
),
TP_fast_assign(
- __assign_str(timeline, pt->parent->name);
- if (pt->parent->ops->pt_value_str) {
- pt->parent->ops->pt_value_str(pt, __entry->value,
+ __assign_str(timeline, pt->ops->get_timeline_name(pt));
+ if (pt->ops->fence_value_str) {
+ pt->ops->fence_value_str(pt, __entry->value,
sizeof(__entry->value));
} else {
__entry->value[0] = '\0';
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 606d5f5e9216..c1e01f7d64ba 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -1648,7 +1648,7 @@ static int bcm_char_ioctl_flash2x_section_read(void __user *argp,
ReadOffset = sFlash2xRead.offset;
OutPutBuff = IoBuffer.OutputBuffer;
- pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
+ pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
if (pReadBuff == NULL) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
index fb1d932c5d79..adca0ce4d05f 100644
--- a/drivers/staging/bcm/CmHost.c
+++ b/drivers/staging/bcm/CmHost.c
@@ -972,6 +972,7 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
pstAddIndication->sfAuthorizedSet.bValid = 1;
for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
struct bcm_convergence_types *psfCSType = NULL;
+
psfCSType = &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex];
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType);
@@ -1418,7 +1419,7 @@ static inline ULONG RestoreSFParam(struct bcm_mini_adapter *Adapter,
ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
/* Read out the SF Param Set At the indicated Location */
- if (rdm(Adapter, ulAddrSFParamSet,(PUCHAR)pucDestBuffer, nBytesToRead) < 0)
+ if (rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
return STATUS_FAILURE;
return 1;
diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c
index f1d7cb82fd7e..4226c931cd45 100644
--- a/drivers/staging/bcm/DDRInit.c
+++ b/drivers/staging/bcm/DDRInit.c
@@ -7,7 +7,8 @@
/* DDR INIT-133Mhz */
#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = {
+ /* DPLL Clock Setting */
{0x0F000800, 0x00007212},
{0x0f000820, 0x07F13FFF},
{0x0f000810, 0x00000F95},
@@ -65,7 +66,8 @@ static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = { /* DPLL Clock Setting
};
/* 80Mhz */
#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00000F95},
{0x0f000820, 0x07f1ffff},
{0x0f000860, 0x00000000},
@@ -117,7 +119,8 @@ static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = { /* DPLL Clock Setting
};
/* 100Mhz */
#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = {
+ /* DPLL Clock Setting */
{0x0F000800, 0x00007008},
{0x0f000810, 0x00000F95},
{0x0f000820, 0x07F13E3F},
@@ -189,7 +192,8 @@ static struct bcm_ddr_setting asDPLL_266MHZ[] = {
};
#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00000F95},
{0x0f000810, 0x00000F95},
{0x0f000810, 0x00000F95},
@@ -247,7 +251,8 @@ static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = { /* DPLL Clock Settin
};
#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00000F95},
{0x0f000820, 0x07F13FFF},
{0x0f000840, 0x0FFF1F00},
@@ -301,7 +306,8 @@ static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = { /* DPLL Clock Setting
/* 100Mhz */
#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00000F95},
{0x0f000820, 0x07F1369B},
{0x0f000840, 0x0FFF0800},
@@ -356,7 +362,8 @@ static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = { /* DPLL Clock Settin
#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000820, 0x03F1365B},
{0x0f000810, 0x00002F95},
{0x0f000880, 0x000003DD},
@@ -416,7 +423,8 @@ static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = { /* DPLL Clock Setti
};
#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00002F95},
{0x0f000820, 0x03F1369B},
{0x0f000840, 0x0fff0000},
@@ -476,7 +484,8 @@ static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = { /* DPLL Clock Setti
};
#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000820, 0x07F13FFF},
{0x0f000810, 0x00002F95},
{0x0f000860, 0x00000000},
@@ -536,7 +545,8 @@ static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = { /* DPLL Clock Settin
/* T3 LP-B (UMA-B) */
#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000820, 0x03F137DB},
{0x0f000810, 0x01842795},
{0x0f000860, 0x00000000},
@@ -544,7 +554,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { /* DPLL Clock Sett
{0x0f000840, 0x0FFF0400},
{0x0F00a044, 0x1fffffff},
{0x0F00a040, 0x1f000000},
- {0x0f003050, 0x00000021}, /* this is flash/eeprom clock divisor which set the flash clock to 20 MHz */
+ {0x0f003050, 0x00000021}, /* this is flash/eeprom clock divisor which
+ * set the flash clock to 20 MHz */
{0x0F00a084, 0x1Cffffff}, /* Now dump from her in internal memory */
{0x0F00a080, 0x1C000000},
{0x0F00A000, 0x00000016},
@@ -593,7 +604,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { /* DPLL Clock Sett
#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000820, 0x03F1365B},
{0x0f000810, 0x00002F95},
{0x0f000880, 0x000003DD},
@@ -602,7 +614,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { /* DPLL Clock Sett
{0x0f000860, 0x00000000},
{0x0F00a044, 0x1fffffff},
{0x0F00a040, 0x1f000000},
- {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */
+ {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which
+ * set the flash clock to 20 MHz */
{0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */
{0x0F00a080, 0x1C000000},
{0x0F00A000, 0x00000016},
@@ -654,7 +667,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { /* DPLL Clock Sett
};
#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000810, 0x00002F95},
{0x0f000820, 0x03F1369B},
{0x0f000840, 0x0fff0000},
@@ -664,7 +678,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { /* DPLL Clock Sett
{0x0f000840, 0x0FFF0000},
{0x0F00a044, 0x1fffffff},
{0x0F00a040, 0x1f000000},
- {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */
+ {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which
+ * set the flash clock to 20 MHz */
{0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */
{0x0F00a080, 0x1C000000},
/* Memcontroller Default values */
@@ -715,7 +730,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { /* DPLL Clock Sett
};
#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 /* index for 0x0F007000 */
-static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = { /* DPLL Clock Setting */
+static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = {
+ /* DPLL Clock Setting */
{0x0f000820, 0x07F13FFF},
{0x0f000810, 0x00002F95},
{0x0f000860, 0x00000000},
@@ -723,7 +739,8 @@ static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = { /* DPLL Clock Setti
{0x0f000840, 0x0FFF1F00},
{0x0F00a044, 0x1fffffff},
{0x0F00a040, 0x1f000000},
- {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */
+ {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor
+ * which set the flash clock to 20 MHz */
{0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */
{0x0F00a080, 0x1C000000},
{0x0F00A000, 0x00000016},
@@ -776,7 +793,7 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
struct bcm_ddr_setting *psDDRSetting = NULL;
ULONG RegCount = 0;
UINT value = 0;
- UINT uiResetValue = 0;
+ UINT uiResetValue = 0;
UINT uiClockSetting = 0;
int retval = STATUS_SUCCESS;
@@ -785,18 +802,18 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
switch (Adapter->DDRSetting) {
case DDR_80_MHZ:
psDDRSetting = asT3LP_DDRSetting80MHz;
- RegCount = (sizeof(asT3LP_DDRSetting80MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3LP_DDRSetting80MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_100_MHZ:
psDDRSetting = asT3LP_DDRSetting100MHz;
- RegCount = (sizeof(asT3LP_DDRSetting100MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3LP_DDRSetting100MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_133_MHZ:
psDDRSetting = asT3LP_DDRSetting133MHz;
- RegCount = (sizeof(asT3LP_DDRSetting133MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3LP_DDRSetting133MHz) /
+ sizeof(struct bcm_ddr_setting));
if (Adapter->bMipsConfig == MIPS_200_MHZ)
uiClockSetting = 0x03F13652;
else
@@ -818,15 +835,21 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
if ((Adapter->chip_id != BCS220_2) &&
(Adapter->chip_id != BCS220_2BC) &&
(Adapter->chip_id != BCS220_3)) {
- retval = rdmalt(Adapter, (UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000830, &uiResetValue,
+ sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__, __LINE__);
return retval;
}
uiResetValue |= 0x44;
- retval = wrmalt(Adapter, (UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0f000830, &uiResetValue,
+ sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__, __LINE__);
return retval;
}
}
@@ -836,18 +859,18 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
case DDR_80_MHZ:
psDDRSetting = asT3LPB_DDRSetting80MHz;
- RegCount = (sizeof(asT3B_DDRSetting80MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting80MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_100_MHZ:
psDDRSetting = asT3LPB_DDRSetting100MHz;
- RegCount = (sizeof(asT3B_DDRSetting100MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting100MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_133_MHZ:
psDDRSetting = asT3LPB_DDRSetting133MHz;
- RegCount = (sizeof(asT3B_DDRSetting133MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting133MHz) /
+ sizeof(struct bcm_ddr_setting));
if (Adapter->bMipsConfig == MIPS_200_MHZ)
uiClockSetting = 0x03F13652;
@@ -857,7 +880,8 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
case DDR_160_MHZ:
psDDRSetting = asT3LPB_DDRSetting160MHz;
- RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting);
+ RegCount = sizeof(asT3LPB_DDRSetting160MHz) /
+ sizeof(struct bcm_ddr_setting);
if (Adapter->bMipsConfig == MIPS_200_MHZ)
uiClockSetting = 0x03F137D2;
@@ -871,22 +895,23 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
case 0xbece0121:
case 0xbece0130:
case 0xbece0300:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
+ "DDR Setting: %x\n", Adapter->DDRSetting);
switch (Adapter->DDRSetting) {
case DDR_80_MHZ:
psDDRSetting = asT3_DDRSetting80MHz;
- RegCount = (sizeof(asT3_DDRSetting80MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3_DDRSetting80MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_100_MHZ:
psDDRSetting = asT3_DDRSetting100MHz;
- RegCount = (sizeof(asT3_DDRSetting100MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3_DDRSetting100MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_133_MHZ:
psDDRSetting = asT3_DDRSetting133MHz;
- RegCount = (sizeof(asT3_DDRSetting133MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3_DDRSetting133MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
default:
return -EINVAL;
@@ -896,26 +921,27 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
switch (Adapter->DDRSetting) {
case DDR_80_MHZ:
psDDRSetting = asT3B_DDRSetting80MHz;
- RegCount = (sizeof(asT3B_DDRSetting80MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting80MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_100_MHZ:
psDDRSetting = asT3B_DDRSetting100MHz;
- RegCount = (sizeof(asT3B_DDRSetting100MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting100MHz) /
+ sizeof(struct bcm_ddr_setting));
break;
case DDR_133_MHZ:
- if (Adapter->bDPLLConfig == PLL_266_MHZ) { /* 266Mhz PLL selected. */
+ /* 266Mhz PLL selected. */
+ if (Adapter->bDPLLConfig == PLL_266_MHZ) {
memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ,
- sizeof(asDPLL_266MHZ));
+ sizeof(asDPLL_266MHZ));
psDDRSetting = asT3B_DDRSetting133MHz;
- RegCount = (sizeof(asT3B_DDRSetting133MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting133MHz) /
+ sizeof(struct bcm_ddr_setting));
} else {
psDDRSetting = asT3B_DDRSetting133MHz;
- RegCount = (sizeof(asT3B_DDRSetting133MHz)/
- sizeof(struct bcm_ddr_setting));
+ RegCount = (sizeof(asT3B_DDRSetting133MHz) /
+ sizeof(struct bcm_ddr_setting));
if (Adapter->bMipsConfig == MIPS_200_MHZ)
uiClockSetting = 0x07F13652;
else
@@ -933,15 +959,19 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
}
value = 0;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
+ "Register Count is =%lu\n", RegCount);
while (RegCount && !retval) {
- if (uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
+ if (uiClockSetting
+ && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG)
value = uiClockSetting;
else
value = psDDRSetting->ulRegValue;
- retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value));
+ retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value,
+ sizeof(value));
if (STATUS_SUCCESS != retval) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+ "%s:%d\n", __func__, __LINE__);
break;
}
@@ -957,27 +987,47 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
(Adapter->chip_id != BCS220_3)) {
/* drive MDDR to half in case of UMA-B: */
uiResetValue = 0x01010001;
- retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0F007018,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x00040020;
- retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0F007094,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x01020101;
- retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0F00701c,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x01010000;
- retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0F007018,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
}
@@ -986,74 +1036,135 @@ int ddr_init(struct bcm_mini_adapter *Adapter)
/* DC/DC standby change...
* This is to be done only for Hybrid PMU mode.
* with the current h/w there is no way to detect this.
- * and since we dont have internal PMU lets do it under UMA-B chip id.
- * we will change this when we will have internal PMU.
+ * and since we dont have internal PMU lets do it under
+ * UMA-B chip id. we will change this when we will have
+ * internal PMU.
*/
if (Adapter->PmuMode == HYBRID_MODE_7C) {
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x1322a8;
- retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0f000d1c,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x132296;
- retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0f000d14,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
} else if (Adapter->PmuMode == HYBRID_MODE_6) {
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x6003229a;
- retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0f000d14,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
- retval = rdmalt(Adapter, (UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue));
+ retval = rdmalt(Adapter, (UINT)0x0f000c00,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
uiResetValue = 0x1322a8;
- retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue));
+ retval = wrmalt(Adapter, (UINT)0x0f000d1c,
+ &uiResetValue, sizeof(uiResetValue));
if (retval < 0) {
- BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, CMHOST, RDM,
+ DBG_LVL_ALL,
+ "%s:%d RDM failed\n",
+ __func__,
+ __LINE__);
return retval;
}
}
@@ -1067,8 +1178,9 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
{
struct bcm_ddr_setting *psDDRSetting = NULL;
ULONG RegCount = 0;
- unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY;
- UINT value = 0;
+ unsigned long ul_ddr_setting_load_addr =
+ DDR_DUMP_INTERNAL_DEVICE_MEMORY;
+ UINT value = 0;
int retval = STATUS_SUCCESS;
bool bOverrideSelfRefresh = false;
@@ -1191,18 +1303,22 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
}
/* total number of Register that has to be dumped */
value = RegCount;
- retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value,
+ sizeof(value));
if (retval) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+ "%s:%d\n", __func__, __LINE__);
return retval;
}
ul_ddr_setting_load_addr += sizeof(ULONG);
/* signature */
value = (0x1d1e0dd0);
- retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value,
+ sizeof(value));
if (retval) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+ "%s:%d\n", __func__, __LINE__);
return retval;
}
@@ -1211,29 +1327,29 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter)
while (RegCount && !retval) {
value = psDDRSetting->ulRegAddress;
- retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value));
+ retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value,
+ sizeof(value));
ul_ddr_setting_load_addr += sizeof(ULONG);
if (!retval) {
- if (bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) {
+ if (bOverrideSelfRefresh
+ && (psDDRSetting->ulRegAddress
+ == 0x0F007018))
value = (psDDRSetting->ulRegValue | (1<<8));
- if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr,
- &value, sizeof(value))) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
- break;
- }
- } else {
- value = psDDRSetting->ulRegValue;
+ else
+ value = psDDRSetting->ulRegValue;
- if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr ,
- &value, sizeof(value))) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__);
- break;
- }
+ if (STATUS_SUCCESS != wrmalt(Adapter,
+ ul_ddr_setting_load_addr,
+ &value,
+ sizeof(value))) {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+ "%s:%d\n", __func__, __LINE__);
+ break;
}
}
ul_ddr_setting_load_addr += sizeof(ULONG);
RegCount--;
psDDRSetting++;
}
- return retval;
+ return retval;
}
diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c
index 495fe3dc5148..54552214bf6f 100644
--- a/drivers/staging/bcm/HandleControlPacket.c
+++ b/drivers/staging/bcm/HandleControlPacket.c
@@ -11,7 +11,8 @@
* Enqueue the control packet for Application.
* @return None
*/
-static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
+static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter,
+ struct sk_buff *skb)
{
struct bcm_tarang_data *pTarang = NULL;
bool HighPriorityMessage = false;
@@ -22,7 +23,7 @@ static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk
if (netif_msg_pktdata(Adapter))
print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
- 16, 1, skb->data, skb->len, 0);
+ 16, 1, skb->data, skb->len, 0);
switch (usStatus) {
case CM_RESPONSES: /* 0xA0 */
@@ -106,30 +107,32 @@ static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk
* the sum of all types of dropped pkt by that
* tarang only.
*/
+ struct bcm_mibs_dropped_cntrl_msg *msg =
+ &pTarang->stDroppedAppCntrlMsgs;
switch (*(PUSHORT)skb->data) {
case CM_RESPONSES:
- pTarang->stDroppedAppCntrlMsgs.cm_responses++;
+ msg->cm_responses++;
break;
case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
- pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
+ msg->cm_control_newdsx_multiclassifier_resp++;
break;
case LINK_CONTROL_RESP:
- pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
+ msg->link_control_resp++;
break;
case STATUS_RSP:
- pTarang->stDroppedAppCntrlMsgs.status_rsp++;
+ msg->status_rsp++;
break;
case STATS_POINTER_RESP:
- pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
+ msg->stats_pointer_resp++;
break;
case IDLE_MODE_STATUS:
- pTarang->stDroppedAppCntrlMsgs.idle_mode_status++;
+ msg->idle_mode_status++;
break;
case AUTH_SS_HOST_MSG:
- pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++;
+ msg->auth_ss_host_msg++;
break;
default:
- pTarang->stDroppedAppCntrlMsgs.low_priority_message++;
+ msg->low_priority_message++;
break;
}
@@ -216,6 +219,7 @@ INT flushAllAppQ(void)
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
struct bcm_tarang_data *pTarang = NULL;
struct sk_buff *PacketToDrop = NULL;
+
for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
while (pTarang->RxAppControlHead != NULL) {
PacketToDrop = pTarang->RxAppControlHead;
diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c
index cd160670e028..27f3f416f184 100644
--- a/drivers/staging/bcm/IPv6Protocol.c
+++ b/drivers/staging/bcm/IPv6Protocol.c
@@ -11,7 +11,7 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
{
UCHAR *pucRetHeaderPtr = NULL;
UCHAR *pucPayloadPtr = NULL;
- USHORT usNextHeaderOffset = 0 ;
+ USHORT usNextHeaderOffset = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
if ((ppucPayload == NULL) || (*pusPayloadLength == 0) ||
@@ -34,94 +34,89 @@ static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload,
switch (*pucNextHeader) {
case IPV6HDR_TYPE_HOPBYHOP:
- {
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 HopByHop Header");
- usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr);
- }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL, "\nIPv6 HopByHop Header");
+ usNextHeaderOffset += sizeof(struct bcm_ipv6_options_hdr);
break;
case IPV6HDR_TYPE_ROUTING:
{
struct bcm_ipv6_routing_hdr *pstIpv6RoutingHeader;
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
DBG_LVL_ALL, "\nIPv6 Routing Header");
- pstIpv6RoutingHeader = (struct bcm_ipv6_routing_hdr *)pucPayloadPtr;
+ pstIpv6RoutingHeader =
+ (struct bcm_ipv6_routing_hdr *)pucPayloadPtr;
usNextHeaderOffset += sizeof(struct bcm_ipv6_routing_hdr);
- usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES;
-
+ usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses *
+ IPV6_ADDRESS_SIZEINBYTES;
}
break;
- case IPV6HDR_TYPE_FRAGMENTATION:
- {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Fragmentation Header");
- usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr);
- }
+ case IPV6HDR_TYPE_FRAGMENTATION:
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL,
+ "\nIPv6 Fragmentation Header");
+ usNextHeaderOffset += sizeof(struct bcm_ipv6_fragment_hdr);
break;
+
case IPV6HDR_TYPE_DESTOPTS:
{
- struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr = (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr;
+ struct bcm_ipv6_dest_options_hdr *pstIpv6DestOptsHdr =
+ (struct bcm_ipv6_dest_options_hdr *)pucPayloadPtr;
int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen;
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
DBG_LVL_ALL,
"\nIPv6 DestOpts Header Header");
usNextHeaderOffset += sizeof(struct bcm_ipv6_dest_options_hdr);
- usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ;
-
+ usNextHeaderOffset += nTotalOptions *
+ IPV6_DESTOPTS_HDR_OPTIONSIZE;
}
break;
+
+
case IPV6HDR_TYPE_AUTHENTICATION:
{
- struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr = (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr;
+ struct bcm_ipv6_authentication_hdr *pstIpv6AuthHdr =
+ (struct bcm_ipv6_authentication_hdr *)pucPayloadPtr;
int nHdrLen = pstIpv6AuthHdr->ucLength;
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
DBG_LVL_ALL,
"\nIPv6 Authentication Header");
usNextHeaderOffset += nHdrLen * 4;
}
break;
- case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
- {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL,
- "\nIPv6 Encrypted Security Payload Header");
- *bParseDone = TRUE;
- }
+ case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD:
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL,
+ "\nIPv6 Encrypted Security Payload Header");
+ *bParseDone = TRUE;
break;
+
case IPV6_ICMP_HDR_TYPE:
- {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nICMP Header");
- *bParseDone = TRUE;
- }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL, "\nICMP Header");
+ *bParseDone = TRUE;
break;
+
case TCP_HEADER_TYPE:
- {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nTCP Header");
- *bParseDone = TRUE;
- }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL, "\nTCP Header");
+ *bParseDone = TRUE;
break;
+
case UDP_HEADER_TYPE:
- {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nUDP Header");
- *bParseDone = TRUE;
- }
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
+ DBG_LVL_ALL, "\nUDP Header");
+ *bParseDone = TRUE;
break;
- default:
- {
- *bParseDone = TRUE;
- }
+ default:
+ *bParseDone = TRUE;
break;
-
-
}
if (*bParseDone == false) {
@@ -156,7 +151,9 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
ucHeaderType = ucNextHeader;
while (!bDone) {
pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,
- &ucHeaderType, &bDone, &usPayloadLength);
+ &ucHeaderType,
+ &bDone,
+ &usPayloadLength);
if (bDone) {
if ((ucHeaderType == TCP_HEADER_TYPE) ||
(ucHeaderType == UDP_HEADER_TYPE)) {
@@ -177,11 +174,12 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort,
/*
- * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver contorl structure
+ * Arg 1 struct bcm_mini_adapter *Adapter is a pointer ot the driver control
+ * structure
* Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet
*/
USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
- struct bcm_classifier_rule *pstClassifierRule)
+ struct bcm_classifier_rule *pstClassifierRule)
{
USHORT ushDestPort = 0;
USHORT ushSrcPort = 0;
@@ -200,11 +198,12 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
* Try to get the next higher layer protocol
* and the Ports Nos if TCP or UDP
*/
- ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(struct bcm_ipv6_hdr)),
- &ushSrcPort,
- &ushDestPort,
- pstIpv6Header->usPayloadLength,
- pstIpv6Header->ucNextHeader);
+ ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader +
+ sizeof(struct bcm_ipv6_hdr)),
+ &ushSrcPort,
+ &ushDestPort,
+ pstIpv6Header->usPayloadLength,
+ pstIpv6Header->ucNextHeader);
do {
if (pstClassifierRule->ucDirection == 0) {
@@ -224,12 +223,12 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
}
bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule,
- pstIpv6Header);
+ pstIpv6Header);
if (!bClassificationSucceed)
break;
bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule,
- pstIpv6Header);
+ pstIpv6Header);
if (!bClassificationSucceed)
break;
@@ -239,7 +238,7 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
* Chain of IPv6 prot headers
*/
bClassificationSucceed = MatchProtocol(pstClassifierRule,
- ucNextProtocolAboveIP);
+ ucNextProtocolAboveIP);
if (!bClassificationSucceed)
break;
@@ -253,7 +252,7 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",
ntohs(ushSrcPort));
bClassificationSucceed = MatchSrcPort(pstClassifierRule,
- ntohs(ushSrcPort));
+ ntohs(ushSrcPort));
if (!bClassificationSucceed)
break;
@@ -262,26 +261,27 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
/* Match Dest Port */
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",
+ DBG_LVL_ALL,
+ "\nIPv6 Destination Port:%x\n",
ntohs(ushDestPort));
bClassificationSucceed = MatchDestPort(pstClassifierRule,
- ntohs(ushDestPort));
+ ntohs(ushDestPort));
if (!bClassificationSucceed)
break;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG,
- DBG_LVL_ALL, "\nIPv6 Dest Port Matched");
+ DBG_LVL_ALL,
+ "\nIPv6 Dest Port Matched");
}
} while (0);
if (bClassificationSucceed == TRUE) {
INT iMatchedSFQueueIndex = 0;
- iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
- if (iMatchedSFQueueIndex >= NO_OF_QUEUES) {
+
+ iMatchedSFQueueIndex = SearchSfid(Adapter,
+ pstClassifierRule->ulSFID);
+ if ((iMatchedSFQueueIndex >= NO_OF_QUEUES) ||
+ (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false))
bClassificationSucceed = false;
- } else {
- if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == false)
- bClassificationSucceed = false;
- }
}
return bClassificationSucceed;
@@ -289,18 +289,21 @@ USHORT IpVersion6(struct bcm_mini_adapter *Adapter, PVOID pcIpHeader,
static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header)
+ struct bcm_ipv6_hdr *pstIpv6Header)
{
UINT uiLoopIndex = 0;
UINT uiIpv6AddIndex = 0;
UINT uiIpv6AddrNoLongWords = 4;
ULONG aulSrcIP[4];
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ union u_ip_address *src_addr = &pstClassifierRule->stSrcIpAddress;
+
/*
* This is the no. of Src Addresses ie Range of IP Addresses contained
* in the classifier rule for which we need to match
*/
- UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength;
+ UINT uiCountIPSrcAddresses =
+ (UINT)pstClassifierRule->ucIPSourceAddressLength;
if (uiCountIPSrcAddresses == 0)
@@ -308,23 +311,31 @@ static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
/* First Convert the Ip Address in the packet to Host Endian order */
- for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++)
- aulSrcIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
-
- for (uiLoopIndex = 0; uiLoopIndex < uiCountIPSrcAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) {
+ for (uiIpv6AddIndex = 0;
+ uiIpv6AddIndex < uiIpv6AddrNoLongWords;
+ uiIpv6AddIndex++)
+ aulSrcIP[uiIpv6AddIndex] =
+ ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]);
+
+ for (uiLoopIndex = 0;
+ uiLoopIndex < uiCountIPSrcAddresses;
+ uiLoopIndex += uiIpv6AddrNoLongWords) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Src Ipv6 Address In Received Packet :\n ");
DumpIpv6Address(aulSrcIP);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Src Ipv6 Mask In Classifier Rule:\n");
- DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]);
+ DumpIpv6Address(&src_addr->ulIpv6Mask[uiLoopIndex]);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Src Ipv6 Address In Classifier Rule :\n");
- DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]);
-
- for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
- if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex])
- != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
+ DumpIpv6Address(&src_addr->ulIpv6Addr[uiLoopIndex]);
+
+ for (uiIpv6AddIndex = 0;
+ uiIpv6AddIndex < uiIpv6AddrNoLongWords;
+ uiIpv6AddIndex++) {
+ if ((src_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] &
+ aulSrcIP[uiIpv6AddIndex]) !=
+ src_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
/*
* Match failed for current Ipv6 Address
* Try next Ipv6 Address
@@ -345,43 +356,53 @@ static bool MatchSrcIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
}
static bool MatchDestIpv6Address(struct bcm_classifier_rule *pstClassifierRule,
- struct bcm_ipv6_hdr *pstIpv6Header)
+ struct bcm_ipv6_hdr *pstIpv6Header)
{
UINT uiLoopIndex = 0;
UINT uiIpv6AddIndex = 0;
UINT uiIpv6AddrNoLongWords = 4;
ULONG aulDestIP[4];
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress;
+
/*
* This is the no. of Destination Addresses
* ie Range of IP Addresses contained in the classifier rule
* for which we need to match
*/
- UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength;
-
+ UINT uiCountIPDestinationAddresses =
+ (UINT)pstClassifierRule->ucIPDestinationAddressLength;
if (uiCountIPDestinationAddresses == 0)
return TRUE;
/* First Convert the Ip Address in the packet to Host Endian order */
- for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++)
- aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
-
- for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) {
+ for (uiIpv6AddIndex = 0;
+ uiIpv6AddIndex < uiIpv6AddrNoLongWords;
+ uiIpv6AddIndex++)
+ aulDestIP[uiIpv6AddIndex] =
+ ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]);
+
+ for (uiLoopIndex = 0;
+ uiLoopIndex < uiCountIPDestinationAddresses;
+ uiLoopIndex += uiIpv6AddrNoLongWords) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Destination Ipv6 Address In Received Packet :\n ");
DumpIpv6Address(aulDestIP);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Destination Ipv6 Mask In Classifier Rule :\n");
- DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]);
+ DumpIpv6Address(&dest_addr->ulIpv6Mask[uiLoopIndex]);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"\n Destination Ipv6 Address In Classifier Rule :\n");
- DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]);
-
- for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
- if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex])
- != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
+ DumpIpv6Address(&dest_addr->ulIpv6Addr[uiLoopIndex]);
+
+ for (uiIpv6AddIndex = 0;
+ uiIpv6AddIndex < uiIpv6AddrNoLongWords;
+ uiIpv6AddIndex++) {
+ if ((dest_addr->ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] &
+ aulDestIP[uiIpv6AddIndex]) !=
+ dest_addr->ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) {
/*
* Match failed for current Ipv6 Address.
* Try next Ipv6 Address
@@ -407,7 +428,10 @@ VOID DumpIpv6Address(ULONG *puIpv6Address)
UINT uiIpv6AddrNoLongWords = 4;
UINT uiIpv6AddIndex = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) {
+
+ for (uiIpv6AddIndex = 0;
+ uiIpv6AddIndex < uiIpv6AddrNoLongWords;
+ uiIpv6AddIndex++) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
":%lx", puIpv6Address[uiIpv6AddIndex]);
}
@@ -419,6 +443,7 @@ static VOID DumpIpv6Header(struct bcm_ipv6_hdr *pstIpv6Header)
UCHAR ucVersion;
UCHAR ucPrio;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL,
"----Ipv6 Header---");
ucVersion = pstIpv6Header->ucVersionPrio & 0xf0;
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
index e1925bdc127c..abc7a7ab782a 100644
--- a/drivers/staging/bcm/InterfaceDld.c
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -244,6 +244,7 @@ static INT buffDnld(struct bcm_mini_adapter *Adapter,
{
unsigned int len = 0;
int retval = STATUS_SUCCESS;
+
len = u32FirmwareLength;
while (u32FirmwareLength) {
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c
index 7c04c73e3bc8..bb61d34886b3 100644
--- a/drivers/staging/bcm/InterfaceInit.c
+++ b/drivers/staging/bcm/InterfaceInit.c
@@ -28,28 +28,28 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter);
static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
{
int i = 0;
+ struct bcm_mini_adapter *ps_ad = psIntfAdapter->psAdapter;
/* Wake up the wait_queue... */
- if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running &
+ if (ps_ad->LEDInfo.led_thread_running &
BCM_LED_THREAD_RUNNING_ACTIVELY) {
- psIntfAdapter->psAdapter->DriverState = DRIVER_HALT;
- wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event);
+ ps_ad->DriverState = DRIVER_HALT;
+ wake_up(&ps_ad->LEDInfo.notify_led_event);
}
- reset_card_proc(psIntfAdapter->psAdapter);
+ reset_card_proc(ps_ad);
/*
* worst case time taken by the RDM/WRM will be 5 sec. will check after
* every 100 ms to accertain the device is not being accessed. After
* this No RDM/WRM should be made.
*/
- while (psIntfAdapter->psAdapter->DeviceAccess) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT,
- DRV_ENTRY, DBG_LVL_ALL,
- "Device is being accessed.\n");
+ while (ps_ad->DeviceAccess) {
+ BCM_DEBUG_PRINT(ps_ad, DBG_TYPE_INITEXIT, DRV_ENTRY,
+ DBG_LVL_ALL, "Device is being accessed.\n");
msleep(100);
}
/* Free interrupt URB */
- /* psIntfAdapter->psAdapter->device_removed = TRUE; */
+ /* ps_ad->device_removed = TRUE; */
usb_free_urb(psIntfAdapter->psInterruptUrb);
/* Free transmit URBs */
@@ -67,10 +67,11 @@ static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter)
psIntfAdapter->asUsbRcb[i].urb = NULL;
}
}
- AdapterFree(psIntfAdapter->psAdapter);
+ AdapterFree(ps_ad);
}
-static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter)
+static void ConfigureEndPointTypesThroughEEPROM(
+ struct bcm_mini_adapter *Adapter)
{
u32 ulReg;
int bytes;
@@ -129,7 +130,10 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter
ulReg &= 0x0101FFFF;
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE);
- /* Update length field if required. Also make the string NULL terminated. */
+ /*
+ * Update length field if required.
+ * Also make the string NULL terminated.
+ */
ReadBeceemEEPROM(Adapter, 0xA8, &ulReg);
if ((ulReg&0x00FF0000)>>16 > 0x30) {
@@ -147,7 +151,8 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter
BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE);
}
-static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int usbbcm_device_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
int retval;
@@ -338,16 +343,16 @@ static int device_run(struct bcm_interface_adapter *psIntfAdapter)
{
int value = 0;
UINT status = STATUS_SUCCESS;
+ struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter;
- status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter);
+ status = InitCardAndDownloadFirmware(psAd);
if (status != STATUS_SUCCESS) {
pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n");
return status;
}
- if (psIntfAdapter->psAdapter->fw_download_done) {
+ if (psAd->fw_download_done) {
if (StartInterruptUrb(psIntfAdapter)) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT, DRV_ENTRY,
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY,
DBG_LVL_ALL,
"Cannot send interrupt in URB\n");
}
@@ -356,17 +361,15 @@ static int device_run(struct bcm_interface_adapter *psIntfAdapter)
* now register the cntrl interface. after downloading the f/w
* waiting for 5 sec to get the mailbox interrupt.
*/
- psIntfAdapter->psAdapter->waiting_to_fw_download_done = false;
- value = wait_event_timeout(
- psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue,
- psIntfAdapter->psAdapter->waiting_to_fw_download_done,
- 5 * HZ);
+ psAd->waiting_to_fw_download_done = false;
+ value = wait_event_timeout(psAd->ioctl_fw_dnld_wait_queue,
+ psAd->waiting_to_fw_download_done,
+ 5 * HZ);
if (value == 0)
pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n");
- if (register_control_device_interface(
- psIntfAdapter->psAdapter) < 0) {
+ if (register_control_device_interface(psAd) < 0) {
pr_err(DRV_NAME ": Register Control Device failed.\n");
return -EIO;
}
@@ -374,6 +377,110 @@ static int device_run(struct bcm_interface_adapter *psIntfAdapter)
return 0;
}
+static int select_alternate_setting_for_highspeed_modem(
+ struct bcm_interface_adapter *psIntfAdapter,
+ struct usb_endpoint_descriptor **endpoint,
+ const struct usb_host_interface *iface_desc,
+ int *usedIntOutForBulkTransfer)
+{
+ int retval = 0;
+ struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter;
+
+ /* selecting alternate setting one as a default setting
+ * for High Speed modem. */
+ if (psIntfAdapter->bHighSpeedDevice)
+ retval = usb_set_interface(psIntfAdapter->udev,
+ DEFAULT_SETTING_0,
+ ALTERNATE_SETTING_1);
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
+ "BCM16 is applicable on this dongle\n");
+ if (retval || !psIntfAdapter->bHighSpeedDevice) {
+ *usedIntOutForBulkTransfer = EP2;
+ *endpoint = &iface_desc->endpoint[EP2].desc;
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
+ "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
+ /*
+ * If Modem is high speed device EP2 should be
+ * INT OUT End point
+ *
+ * If Mode is FS then EP2 should be bulk end
+ * point
+ */
+ if ((psIntfAdapter->bHighSpeedDevice &&
+ !usb_endpoint_is_int_out(*endpoint)) ||
+ (!psIntfAdapter->bHighSpeedDevice &&
+ !usb_endpoint_is_bulk_out(*endpoint))) {
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY,
+ DBG_LVL_ALL,
+ "Configuring the EEPROM\n");
+ /* change the EP2, EP4 to INT OUT end point */
+ ConfigureEndPointTypesThroughEEPROM(
+ psAd);
+
+ /*
+ * It resets the device and if any thing
+ * gets changed in USB descriptor it
+ * will show fail and re-enumerate the
+ * device
+ */
+ retval = usb_reset_device(psIntfAdapter->udev);
+ if (retval) {
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT,
+ DRV_ENTRY, DBG_LVL_ALL,
+ "reset failed. Re-enumerating the device.\n");
+ return retval;
+ }
+
+ }
+ if (!psIntfAdapter->bHighSpeedDevice &&
+ usb_endpoint_is_bulk_out(*endpoint)) {
+ /*
+ * Once BULK is selected in FS mode.
+ * Revert it back to INT.
+ * Else USB_IF will fail.
+ */
+ UINT _uiData = ntohl(EP2_CFG_INT);
+
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY,
+ DBG_LVL_ALL,
+ "Reverting Bulk to INT as it is in Full Speed mode.\n");
+ BeceemEEPROMBulkWrite(psAd, (PUCHAR) & _uiData, 0x136,
+ 4, TRUE);
+ }
+ } else {
+ *usedIntOutForBulkTransfer = EP4;
+ *endpoint = &iface_desc->endpoint[EP4].desc;
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,
+ "Choosing AltSetting as a default setting.\n");
+ if (!usb_endpoint_is_int_out(*endpoint)) {
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT, DRV_ENTRY,
+ DBG_LVL_ALL,
+ "Dongle does not have BCM16 Fix.\n");
+ /*
+ * change the EP2, EP4 to INT OUT end point and use EP4
+ * in altsetting
+ */
+ ConfigureEndPointTypesThroughEEPROM(psAd);
+
+ /*
+ * It resets the device and if any thing
+ * gets changed in USB descriptor it
+ * will show fail and re-enumerate the
+ * device
+ */
+ retval = usb_reset_device(psIntfAdapter->udev);
+ if (retval) {
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_INITEXIT,
+ DRV_ENTRY, DBG_LVL_ALL,
+ "reset failed. Re-enumerating the device.\n");
+ return retval;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
{
struct usb_host_interface *iface_desc;
@@ -385,6 +492,7 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
bool bBcm16 = false;
UINT uiData = 0;
int bytes;
+ struct bcm_mini_adapter *psAd = psIntfAdapter->psAdapter;
/* Store the usb dev into interface adapter */
psIntfAdapter->udev =
@@ -392,141 +500,43 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
psIntfAdapter->bHighSpeedDevice =
(psIntfAdapter->udev->speed == USB_SPEED_HIGH);
- psIntfAdapter->psAdapter->interface_rdm = BcmRDM;
- psIntfAdapter->psAdapter->interface_wrm = BcmWRM;
+ psAd->interface_rdm = BcmRDM;
+ psAd->interface_wrm = BcmWRM;
- bytes = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG,
- (u32 *) &(psIntfAdapter->psAdapter->chip_id),
- sizeof(u32));
+ bytes = rdmalt(psAd, CHIP_ID_REG, (u32 *) &(psAd->chip_id),
+ sizeof(u32));
if (bytes < 0) {
retval = bytes;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0,
"CHIP ID Read Failed\n");
return retval;
}
- if (0xbece3200 == (psIntfAdapter->psAdapter->chip_id & ~(0xF0)))
- psIntfAdapter->psAdapter->chip_id &= ~0xF0;
+ if (0xbece3200 == (psAd->chip_id & ~(0xF0)))
+ psAd->chip_id &= ~0xF0;
dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n",
- psIntfAdapter->psAdapter->chip_id);
+ psAd->chip_id);
iface_desc = psIntfAdapter->interface->cur_altsetting;
- if (psIntfAdapter->psAdapter->chip_id == T3B) {
+ if (psAd->chip_id == T3B) {
/* T3B device will have EEPROM, check if EEPROM is proper and
* BCM16 can be done or not. */
- BeceemEEPROMBulkRead(psIntfAdapter->psAdapter, &uiData, 0x0, 4);
+ BeceemEEPROMBulkRead(psAd, &uiData, 0x0, 4);
if (uiData == BECM)
bBcm16 = TRUE;
dev_info(&psIntfAdapter->udev->dev,
- "number of alternate setting %d\n",
- psIntfAdapter->interface->num_altsetting);
+ "number of alternate setting %d\n",
+ psIntfAdapter->interface->num_altsetting);
if (bBcm16 == TRUE) {
- /* selecting alternate setting one as a default setting
- * for High Speed modem. */
- if (psIntfAdapter->bHighSpeedDevice)
- retval = usb_set_interface(psIntfAdapter->udev,
- DEFAULT_SETTING_0,
- ALTERNATE_SETTING_1);
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT, DRV_ENTRY,
- DBG_LVL_ALL,
- "BCM16 is applicable on this dongle\n");
- if (retval || !psIntfAdapter->bHighSpeedDevice) {
- usedIntOutForBulkTransfer = EP2;
- endpoint = &iface_desc->endpoint[EP2].desc;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT, DRV_ENTRY,
- DBG_LVL_ALL,
- "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n");
- /*
- * If Modem is high speed device EP2 should be
- * INT OUT End point
- *
- * If Mode is FS then EP2 should be bulk end
- * point
- */
- if ((psIntfAdapter->bHighSpeedDevice &&
- !usb_endpoint_is_int_out(endpoint)) ||
- (!psIntfAdapter->bHighSpeedDevice &&
- !usb_endpoint_is_bulk_out(endpoint))) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT,
- DRV_ENTRY, DBG_LVL_ALL,
- "Configuring the EEPROM\n");
- /* change the EP2, EP4 to INT OUT end point */
- ConfigureEndPointTypesThroughEEPROM(
- psIntfAdapter->psAdapter);
-
- /*
- * It resets the device and if any thing
- * gets changed in USB descriptor it
- * will show fail and re-enumerate the
- * device
- */
- retval = usb_reset_device(
- psIntfAdapter->udev);
- if (retval) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT,
- DRV_ENTRY,
- DBG_LVL_ALL,
- "reset failed. Re-enumerating the device.\n");
- return retval;
- }
-
- }
- if (!psIntfAdapter->bHighSpeedDevice &&
- usb_endpoint_is_bulk_out(endpoint)) {
- /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */
- UINT _uiData = ntohl(EP2_CFG_INT);
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT,
- DRV_ENTRY, DBG_LVL_ALL,
- "Reverting Bulk to INT as it is in Full Speed mode.\n");
- BeceemEEPROMBulkWrite(
- psIntfAdapter->psAdapter,
- (PUCHAR) & _uiData,
- 0x136, 4, TRUE);
- }
- } else {
- usedIntOutForBulkTransfer = EP4;
- endpoint = &iface_desc->endpoint[EP4].desc;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT, DRV_ENTRY,
- DBG_LVL_ALL,
- "Choosing AltSetting as a default setting.\n");
- if (!usb_endpoint_is_int_out(endpoint)) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT,
- DRV_ENTRY, DBG_LVL_ALL,
- "Dongle does not have BCM16 Fix.\n");
- /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */
- ConfigureEndPointTypesThroughEEPROM(
- psIntfAdapter->psAdapter);
-
- /*
- * It resets the device and if any thing
- * gets changed in USB descriptor it
- * will show fail and re-enumerate the
- * device
- */
- retval = usb_reset_device(
- psIntfAdapter->udev);
- if (retval) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
- DBG_TYPE_INITEXIT,
- DRV_ENTRY,
- DBG_LVL_ALL,
- "reset failed. Re-enumerating the device.\n");
- return retval;
- }
-
- }
- }
+ retval = select_alternate_setting_for_highspeed_modem(
+ psIntfAdapter, &endpoint, iface_desc,
+ &usedIntOutForBulkTransfer);
+ if (retval)
+ return retval;
}
}
@@ -572,9 +582,12 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
if (!psIntfAdapter->sIntrOut.int_out_endpointAddr &&
usb_endpoint_is_int_out(endpoint)) {
if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr &&
- (psIntfAdapter->psAdapter->chip_id == T3B) &&
+ (psAd->chip_id == T3B) &&
(value == usedIntOutForBulkTransfer)) {
- /* use first intout end point as a bulk out end point */
+ /*
+ * use first intout end point as a bulk out end
+ * point
+ */
buffer_size =
le16_to_cpu(endpoint->wMaxPacketSize);
psIntfAdapter->sBulkOut.bulk_out_size =
@@ -606,15 +619,14 @@ static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter)
usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter);
- psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload;
- psIntfAdapter->psAdapter->bcm_file_readback_from_chip =
- InterfaceFileReadbackFromChip;
- psIntfAdapter->psAdapter->interface_transmit = InterfaceTransmitPacket;
+ psAd->bcm_file_download = InterfaceFileDownload;
+ psAd->bcm_file_readback_from_chip = InterfaceFileReadbackFromChip;
+ psAd->interface_transmit = InterfaceTransmitPacket;
retval = CreateInterruptUrb(psIntfAdapter);
if (retval) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+ BCM_DEBUG_PRINT(psAd, DBG_TYPE_PRINTK, 0, 0,
"Cannot create interrupt urb\n");
return retval;
}
diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c
index 4173fd7d671c..e5bcfec2a6cf 100644
--- a/drivers/staging/bcm/InterfaceMisc.c
+++ b/drivers/staging/bcm/InterfaceMisc.c
@@ -1,29 +1,46 @@
#include "headers.h"
+static int adapter_err_occurred(const struct bcm_interface_adapter *ad)
+{
+ if (ad->psAdapter->device_removed == TRUE) {
+ BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+ "Device got removed");
+ return -ENODEV;
+ }
+
+ if ((ad->psAdapter->StopAllXaction == TRUE) &&
+ (ad->psAdapter->chip_id >= T3LPB)) {
+ BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM,
+ DBG_LVL_ALL,
+ "Currently Xaction is not allowed on the bus");
+ return -EACCES;
+ }
+
+ if (ad->bSuspended == TRUE || ad->bPreparingForBusSuspend == TRUE) {
+ BCM_DEBUG_PRINT(ad->psAdapter, DBG_TYPE_OTHERS, RDM,
+ DBG_LVL_ALL,
+ "Bus is in suspended states hence RDM not allowed..");
+ return -EACCES;
+ }
+
+ return 0;
+}
+
int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
unsigned int addr,
void *buff,
int len)
{
int bytes;
+ int err = 0;
if (!psIntfAdapter)
return -EINVAL;
- if (psIntfAdapter->psAdapter->device_removed == TRUE) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
- return -ENODEV;
- }
-
- if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus");
- return -EACCES;
- }
+ err = adapter_err_occurred(psIntfAdapter);
+ if (err)
+ return err;
- if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
- return -EACCES;
- }
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
bytes = usb_control_msg(psIntfAdapter->udev,
@@ -40,9 +57,11 @@ int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter,
psIntfAdapter->psAdapter->device_removed = TRUE;
if (bytes < 0)
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d", bytes);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM,
+ DBG_LVL_ALL, "RDM failed status :%d", bytes);
else
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM,
+ DBG_LVL_ALL, "RDM sent %d", bytes);
psIntfAdapter->psAdapter->DeviceAccess = false;
return bytes;
@@ -54,24 +73,14 @@ int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
int len)
{
int retval = 0;
+ int err = 0;
if (!psIntfAdapter)
return -EINVAL;
- if (psIntfAdapter->psAdapter->device_removed == TRUE) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed");
- return -ENODEV;
- }
-
- if ((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Currently Xaction is not allowed on the bus...");
- return -EACCES;
- }
-
- if (psIntfAdapter->bSuspended == TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "Bus is in suspended states hence RDM not allowed..");
- return -EACCES;
- }
+ err = adapter_err_occurred(psIntfAdapter);
+ if (err)
+ return err;
psIntfAdapter->psAdapter->DeviceAccess = TRUE;
@@ -89,12 +98,14 @@ int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter,
psIntfAdapter->psAdapter->device_removed = TRUE;
if (retval < 0) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM,
+ DBG_LVL_ALL, "WRM failed status :%d", retval);
psIntfAdapter->psAdapter->DeviceAccess = false;
return retval;
} else {
psIntfAdapter->psAdapter->DeviceAccess = false;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM,
+ DBG_LVL_ALL, "WRM sent %d", retval);
return STATUS_SUCCESS;
}
}
@@ -104,7 +115,8 @@ int BcmRDM(void *arg,
void *buff,
int len)
{
- return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff, len);
+ return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff,
+ len);
}
int BcmWRM(void *arg,
@@ -112,12 +124,14 @@ int BcmWRM(void *arg,
void *buff,
int len)
{
- return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, len);
+ return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff,
+ len);
}
int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
{
- struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
+ struct bcm_interface_adapter *psIntfAdapter =
+ (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter);
int status = STATUS_SUCCESS;
/*
@@ -126,12 +140,14 @@ int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
* @pipe: endpoint "pipe" being cleared
* @ Context: !in_interrupt ()
*
- * usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
- * This is used to clear halt conditions for bulk and interrupt endpoints only.
+ * usb_clear_halt is the synchrnous call and returns 0 on success else
+ * returns with error code.
+ * This is used to clear halt conditions for bulk and interrupt
+ * endpoints only.
* Control and isochronous endpoints never halts.
*
- * Any URBs queued for such an endpoint should normally be unlinked by the driver
- * before clearing the halt condition.
+ * Any URBs queued for such an endpoint should normally be unlinked by
+ * the driver before clearing the halt condition.
*
*/
@@ -139,17 +155,29 @@ int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter)
Bcm_kill_all_URBs(psIntfAdapter);
/* clear the halted/stalled state for every end point */
- status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sIntrIn.int_in_pipe);
+ status = usb_clear_halt(psIntfAdapter->udev,
+ psIntfAdapter->sIntrIn.int_in_pipe);
if (status != STATUS_SUCCESS)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+ DBG_LVL_ALL,
+ "Unable to Clear Halt of Interrupt IN end point. :%d ",
+ status);
- status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_pipe);
+ status = usb_clear_halt(psIntfAdapter->udev,
+ psIntfAdapter->sBulkIn.bulk_in_pipe);
if (status != STATUS_SUCCESS)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+ DBG_LVL_ALL,
+ "Unable to Clear Halt of Bulk IN end point. :%d ",
+ status);
- status = usb_clear_halt(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe);
+ status = usb_clear_halt(psIntfAdapter->udev,
+ psIntfAdapter->sBulkOut.bulk_out_pipe);
if (status != STATUS_SUCCESS)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, INTF_INIT,
+ DBG_LVL_ALL,
+ "Unable to Clear Halt of Bulk OUT end point. :%d ",
+ status);
return status;
}
@@ -168,9 +196,9 @@ void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter)
* upon return all completion handlers will have finished and the URB
* will be totally idle and available for reuse
*
- * This routine may not be used in an interrupt context (such as a bottom
- * half or a completion handler), or when holding a spinlock, or in other
- * situations where the caller can't schedule().
+ * This routine may not be used in an interrupt context (such as a
+ * bottom half or a completion handler), or when holding a spinlock, or
+ * in other situations where the caller can't schedule().
*
*/
@@ -208,7 +236,9 @@ void putUsbSuspend(struct work_struct *work)
{
struct bcm_interface_adapter *psIntfAdapter = NULL;
struct usb_interface *intf = NULL;
- psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork);
+
+ psIntfAdapter = container_of(work, struct bcm_interface_adapter,
+ usbSuspendWork);
intf = psIntfAdapter->interface;
if (psIntfAdapter->bSuspended == false)
diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c
index 11008173f915..0f179b9382d3 100644
--- a/drivers/staging/bcm/InterfaceRx.c
+++ b/drivers/staging/bcm/InterfaceRx.c
@@ -1,5 +1,92 @@
#include "headers.h"
+static void handle_control_packet(struct bcm_interface_adapter *interface,
+ struct bcm_mini_adapter *ad,
+ struct bcm_leader *leader,
+ struct sk_buff *skb,
+ struct urb *urb)
+{
+ BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL,
+ "Received control pkt...");
+ *(PUSHORT)skb->data = leader->Status;
+ memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
+ (sizeof(struct bcm_leader)), leader->PLength);
+ skb->len = leader->PLength + sizeof(USHORT);
+
+ spin_lock(&ad->control_queue_lock);
+ ENQUEUEPACKET(ad->RxControlHead, ad->RxControlTail, skb);
+ spin_unlock(&ad->control_queue_lock);
+
+ atomic_inc(&ad->cntrlpktCnt);
+ wake_up(&ad->process_rx_cntrlpkt);
+}
+
+static void format_eth_hdr_to_stack(struct bcm_interface_adapter *interface,
+ struct bcm_mini_adapter *ad,
+ struct bcm_leader *p_leader,
+ struct sk_buff *skb,
+ struct urb *urb,
+ UINT ui_index,
+ int queue_index,
+ bool b_header_supression_endabled)
+{
+ /*
+ * Data Packet, Format a proper Ethernet Header
+ * and give it to the stack
+ */
+ BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA,
+ DBG_LVL_ALL, "Received Data pkt...");
+ skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
+ memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer +
+ sizeof(struct bcm_leader), p_leader->PLength);
+ skb->dev = ad->dev;
+
+ /* currently skb->len has extra ETH_HLEN bytes in the beginning */
+ skb_put(skb, p_leader->PLength + ETH_HLEN);
+ ad->PackInfo[queue_index].uiTotalRxBytes += p_leader->PLength;
+ ad->PackInfo[queue_index].uiThisPeriodRxBytes += p_leader->PLength;
+ BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX, RX_DATA,
+ DBG_LVL_ALL, "Received Data pkt of len :0x%X",
+ p_leader->PLength);
+
+ if (netif_running(ad->dev)) {
+ /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
+ skb_pull(skb, ETH_HLEN);
+ PHSReceive(ad, p_leader->Vcid, skb, &skb->len,
+ NULL, b_header_supression_endabled);
+
+ if (!ad->PackInfo[queue_index].bEthCSSupport) {
+ skb_push(skb, ETH_HLEN);
+
+ memcpy(skb->data, skb->dev->dev_addr, 6);
+ memcpy(skb->data+6, skb->dev->dev_addr, 6);
+ (*(skb->data+11))++;
+ *(skb->data+12) = 0x08;
+ *(skb->data+13) = 0x00;
+ p_leader->PLength += ETH_HLEN;
+ }
+
+ skb->protocol = eth_type_trans(skb, ad->dev);
+ netif_rx(skb);
+ } else {
+ BCM_DEBUG_PRINT(interface->psAdapter, DBG_TYPE_RX,
+ RX_DATA, DBG_LVL_ALL,
+ "i/f not up hance freeing SKB...");
+ dev_kfree_skb(skb);
+ }
+
+ ++ad->dev->stats.rx_packets;
+ ad->dev->stats.rx_bytes += p_leader->PLength;
+
+ for (ui_index = 0; ui_index < MIBS_MAX_HIST_ENTRIES; ui_index++) {
+ if ((p_leader->PLength <=
+ MIBS_PKTSIZEHIST_RANGE*(ui_index+1)) &&
+ (p_leader->PLength > MIBS_PKTSIZEHIST_RANGE*(ui_index)))
+
+ ad->aRxPktSizeHist[ui_index]++;
+ }
+}
+
static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid)
{
int iIndex = 0;
@@ -24,8 +111,9 @@ GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter)
pRcb = &psIntfAdapter->asUsbRcb[index];
pRcb->bUsed = TRUE;
pRcb->psIntfAdapter = psIntfAdapter;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d",
- index, atomic_read(&psIntfAdapter->uNumRcbUsed));
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC,
+ DBG_LVL_ALL, "Got Rx desc %d used %d", index,
+ atomic_read(&psIntfAdapter->uNumRcbUsed));
index = (index + 1) % MAXIMUM_USB_RCB;
atomic_set(&psIntfAdapter->uCurrRcb, index);
atomic_inc(&psIntfAdapter->uNumRcbUsed);
@@ -40,7 +128,6 @@ static void read_bulk_callback(struct urb *urb)
bool bHeaderSupressionEnabled = false;
int QueueIndex = NO_OF_QUEUES + 1;
UINT uiIndex = 0;
- int process_done = 1;
struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context;
struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter;
struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter;
@@ -63,7 +150,10 @@ static void read_bulk_callback(struct urb *urb)
Adapter->bEndPointHalted = TRUE;
wake_up(&Adapter->tx_packet_wait_queue);
} else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Rx URB has got cancelled. status :%d", urb->status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC,
+ DBG_LVL_ALL,
+ "Rx URB has got cancelled. status :%d",
+ urb->status);
}
pRcb->bUsed = false;
atomic_dec(&psIntfAdapter->uNumRcbUsed);
@@ -72,17 +162,22 @@ static void read_bulk_callback(struct urb *urb)
}
if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "device is going in low power mode while PMU option selected..hence rx packet should not be process");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
+ "device is going in low power mode while PMU option selected..hence rx packet should not be process");
return;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
+ "Read back done len %d\n", pLeader->PLength);
if (!pLeader->PLength) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
+ "Leader Length 0");
atomic_dec(&psIntfAdapter->uNumRcbUsed);
return;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status, pLeader->PLength, pLeader->Vcid);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,
+ "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX",
+ pLeader->Status, pLeader->PLength, pLeader->Vcid);
if (MAX_CNTL_PKT_SIZE < pLeader->PLength) {
if (netif_msg_rx_err(Adapter))
pr_info(PFX "%s: corrupted leader length...%d\n",
@@ -100,95 +195,52 @@ static void read_bulk_callback(struct urb *urb)
bHeaderSupressionEnabled & Adapter->bPHSEnabled;
}
- skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);
+ skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES +
+ SKB_RESERVE_ETHERNET_HEADER);
if (!skb) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
+ "NO SKBUFF!!! Dropping the Packet");
atomic_dec(&psIntfAdapter->uNumRcbUsed);
return;
}
/* If it is a control Packet, then call handle_bcm_packet ()*/
if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) ||
(!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt...");
- *(PUSHORT)skb->data = pLeader->Status;
- memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer +
- (sizeof(struct bcm_leader)), pLeader->PLength);
- skb->len = pLeader->PLength + sizeof(USHORT);
-
- spin_lock(&Adapter->control_queue_lock);
- ENQUEUEPACKET(Adapter->RxControlHead, Adapter->RxControlTail, skb);
- spin_unlock(&Adapter->control_queue_lock);
-
- atomic_inc(&Adapter->cntrlpktCnt);
- wake_up(&Adapter->process_rx_cntrlpkt);
+ handle_control_packet(psIntfAdapter, Adapter, pLeader, skb,
+ urb);
} else {
- /*
- * Data Packet, Format a proper Ethernet Header
- * and give it to the stack
- */
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt...");
- skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES);
- memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(struct bcm_leader), pLeader->PLength);
- skb->dev = Adapter->dev;
-
- /* currently skb->len has extra ETH_HLEN bytes in the beginning */
- skb_put(skb, pLeader->PLength + ETH_HLEN);
- Adapter->PackInfo[QueueIndex].uiTotalRxBytes += pLeader->PLength;
- Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes += pLeader->PLength;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength);
-
- if (netif_running(Adapter->dev)) {
- /* Moving ahead by ETH_HLEN to the data ptr as received from FW */
- skb_pull(skb, ETH_HLEN);
- PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len,
- NULL, bHeaderSupressionEnabled);
-
- if (!Adapter->PackInfo[QueueIndex].bEthCSSupport) {
- skb_push(skb, ETH_HLEN);
-
- memcpy(skb->data, skb->dev->dev_addr, 6);
- memcpy(skb->data+6, skb->dev->dev_addr, 6);
- (*(skb->data+11))++;
- *(skb->data+12) = 0x08;
- *(skb->data+13) = 0x00;
- pLeader->PLength += ETH_HLEN;
- }
-
- skb->protocol = eth_type_trans(skb, Adapter->dev);
- process_done = netif_rx(skb);
- } else {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB...");
- dev_kfree_skb(skb);
- }
-
- ++Adapter->dev->stats.rx_packets;
- Adapter->dev->stats.rx_bytes += pLeader->PLength;
-
- for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) {
- if ((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) &&
- (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
- Adapter->aRxPktSizeHist[uiIndex]++;
- }
+ format_eth_hdr_to_stack(psIntfAdapter, Adapter, pLeader, skb,
+ urb, uiIndex, QueueIndex,
+ bHeaderSupressionEnabled);
}
Adapter->PrevNumRecvDescs++;
pRcb->bUsed = false;
atomic_dec(&psIntfAdapter->uNumRcbUsed);
}
-static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_rcb *pRcb)
+static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter,
+ struct bcm_usb_rcb *pRcb)
{
struct urb *urb = pRcb->urb;
int retval = 0;
- usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
- urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback, pRcb);
+ usb_fill_bulk_urb(urb, psIntfAdapter->udev,
+ usb_rcvbulkpipe(psIntfAdapter->udev,
+ psIntfAdapter->sBulkIn.bulk_in_endpointAddr),
+ urb->transfer_buffer,
+ BCM_USB_MAX_READ_LENGTH,
+ read_bulk_callback, pRcb);
+
if (false == psIntfAdapter->psAdapter->device_removed &&
false == psIntfAdapter->psAdapter->bEndPointHalted &&
false == psIntfAdapter->bSuspended &&
false == psIntfAdapter->bPreparingForBusSuspend) {
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX,
+ RX_DPC, DBG_LVL_ALL,
+ "failed submitting read urb, error %d",
+ retval);
/* if this return value is because of pipe halt. need to clear this. */
if (retval == -EPIPE) {
psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
@@ -216,13 +268,17 @@ Return: TRUE - If Rx was successful.
bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter)
{
- USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed);
+ USHORT RxDescCount = NUM_RX_DESC -
+ atomic_read(&psIntfAdapter->uNumRcbUsed);
+
struct bcm_usb_rcb *pRcb = NULL;
while (RxDescCount) {
pRcb = GetBulkInRcb(psIntfAdapter);
if (pRcb == NULL) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer");
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
+ DBG_TYPE_PRINTK, 0, 0,
+ "Unable to get Rcb pointer");
return false;
}
ReceiveRcb(psIntfAdapter, pRcb);
diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c
index ea7707b8e60e..9b3f64b821ed 100644
--- a/drivers/staging/bcm/InterfaceTx.c
+++ b/drivers/staging/bcm/InterfaceTx.c
@@ -1,93 +1,122 @@
#include "headers.h"
+static void prepare_low_power_mode(struct urb *urb,
+ struct bcm_interface_adapter *interface,
+ struct bcm_mini_adapter *ps_adapter,
+ struct bcm_mini_adapter *ad,
+ struct bcm_link_request *p_control_msg,
+ bool *b_power_down_msg)
+{
+ if (((p_control_msg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
+ (p_control_msg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) {
+
+ *b_power_down_msg = TRUE;
+ /*
+ * This covers the bus err while Idle Request msg
+ * sent down.
+ */
+ if (urb->status != STATUS_SUCCESS) {
+ ps_adapter->bPreparingForLowPowerMode = false;
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "Idle Mode Request msg failed to reach to Modem");
+ /* Signalling the cntrl pkt path in Ioctl */
+ wake_up(&ps_adapter->lowpower_mode_wait_queue);
+ StartInterruptUrb(interface);
+ return;
+ }
+
+ if (ps_adapter->bDoSuspend == false) {
+ ps_adapter->IdleMode = TRUE;
+ /* since going in Idle mode completed hence making this var false */
+ ps_adapter->bPreparingForLowPowerMode = false;
+
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "Host Entered in Idle Mode State...");
+ /* Signalling the cntrl pkt path in Ioctl*/
+ wake_up(&ps_adapter->lowpower_mode_wait_queue);
+ }
+
+ } else if ((p_control_msg->Leader.Status == LINK_UP_CONTROL_REQ) &&
+ (p_control_msg->szData[0] == LINK_UP_ACK) &&
+ (p_control_msg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) &&
+ (p_control_msg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) {
+ /*
+ * This covers the bus err while shutdown Request
+ * msg sent down.
+ */
+ if (urb->status != STATUS_SUCCESS) {
+ ps_adapter->bPreparingForLowPowerMode = false;
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "Shutdown Request Msg failed to reach to Modem");
+ /* Signalling the cntrl pkt path in Ioctl */
+ wake_up(&ps_adapter->lowpower_mode_wait_queue);
+ StartInterruptUrb(interface);
+ return;
+ }
+
+ *b_power_down_msg = TRUE;
+ if (ps_adapter->bDoSuspend == false) {
+ ps_adapter->bShutStatus = TRUE;
+ /*
+ * since going in shutdown mode completed hence
+ * making this var false
+ */
+ ps_adapter->bPreparingForLowPowerMode = false;
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "Host Entered in shutdown Mode State...");
+ /* Signalling the cntrl pkt path in Ioctl */
+ wake_up(&ps_adapter->lowpower_mode_wait_queue);
+ }
+ }
+
+ if (ps_adapter->bDoSuspend && *b_power_down_msg) {
+ /* issuing bus suspend request */
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
+ "Issuing the Bus suspend request to USB stack");
+ interface->bPreparingForBusSuspend = TRUE;
+ schedule_work(&interface->usbSuspendWork);
+ }
+}
+
/*this is transmit call-back(BULK OUT)*/
static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/)
{
struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context;
struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter;
- struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer;
+ struct bcm_link_request *pControlMsg =
+ (struct bcm_link_request *)urb->transfer_buffer;
struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter;
bool bpowerDownMsg = false;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
if (unlikely(netif_msg_tx_done(Adapter)))
- pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status);
+ pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name,
+ urb->status);
if (urb->status != STATUS_SUCCESS) {
if (urb->status == -EPIPE) {
psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
} else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx URB has got cancelled. status :%d", urb->status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "Tx URB has got cancelled. status :%d",
+ urb->status);
}
}
pTcb->bUsed = false;
atomic_dec(&psIntfAdapter->uNumTcbUsed);
-
-
if (TRUE == psAdapter->bPreparingForLowPowerMode) {
-
- if (((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) &&
- (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) {
- bpowerDownMsg = TRUE;
- /* This covers the bus err while Idle Request msg sent down. */
- if (urb->status != STATUS_SUCCESS) {
- psAdapter->bPreparingForLowPowerMode = false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Request msg failed to reach to Modem");
- /* Signalling the cntrl pkt path in Ioctl */
- wake_up(&psAdapter->lowpower_mode_wait_queue);
- StartInterruptUrb(psIntfAdapter);
- goto err_exit;
- }
-
- if (psAdapter->bDoSuspend == false) {
- psAdapter->IdleMode = TRUE;
- /* since going in Idle mode completed hence making this var false */
- psAdapter->bPreparingForLowPowerMode = false;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State...");
- /* Signalling the cntrl pkt path in Ioctl*/
- wake_up(&psAdapter->lowpower_mode_wait_queue);
- }
-
- } else if ((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) &&
- (pControlMsg->szData[0] == LINK_UP_ACK) &&
- (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) &&
- (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) {
- /* This covers the bus err while shutdown Request msg sent down. */
- if (urb->status != STATUS_SUCCESS) {
- psAdapter->bPreparingForLowPowerMode = false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Shutdown Request Msg failed to reach to Modem");
- /* Signalling the cntrl pkt path in Ioctl */
- wake_up(&psAdapter->lowpower_mode_wait_queue);
- StartInterruptUrb(psIntfAdapter);
- goto err_exit;
- }
-
- bpowerDownMsg = TRUE;
- if (psAdapter->bDoSuspend == false) {
- psAdapter->bShutStatus = TRUE;
- /* since going in shutdown mode completed hence making this var false */
- psAdapter->bPreparingForLowPowerMode = false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in shutdown Mode State...");
- /* Signalling the cntrl pkt path in Ioctl */
- wake_up(&psAdapter->lowpower_mode_wait_queue);
- }
- }
-
- if (psAdapter->bDoSuspend && bpowerDownMsg) {
- /* issuing bus suspend request */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Issuing the Bus suspend request to USB stack");
- psIntfAdapter->bPreparingForBusSuspend = TRUE;
- schedule_work(&psIntfAdapter->usbSuspendWork);
-
- }
-
+ prepare_low_power_mode(urb, psIntfAdapter, psAdapter, Adapter,
+ pControlMsg, &bpowerDownMsg);
}
-err_exit:
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
}
@@ -104,8 +133,11 @@ static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAda
pTcb = &psIntfAdapter->asUsbTcb[index];
pTcb->bUsed = TRUE;
pTcb->psIntfAdapter = psIntfAdapter;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d",
- index, atomic_read(&psIntfAdapter->uNumTcbUsed));
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX,
+ NEXT_SEND, DBG_LVL_ALL,
+ "Got Tx desc %d used %d",
+ index,
+ atomic_read(&psIntfAdapter->uNumTcbUsed));
index = (index + 1) % MAXIMUM_USB_TCB;
atomic_set(&psIntfAdapter->uCurrTcb, index);
atomic_inc(&psIntfAdapter->uNumTcbUsed);
@@ -113,7 +145,8 @@ static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAda
return pTcb;
}
-static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_tcb *pTcb, PVOID data, int len)
+static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter,
+ struct bcm_usb_tcb *pTcb, PVOID data, int len)
{
struct urb *urb = pTcb->urb;
@@ -122,15 +155,18 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u
urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len,
GFP_ATOMIC, &urb->transfer_dma);
if (!urb->transfer_buffer) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n");
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+ "Error allocating memory\n");
return -ENOMEM;
}
memcpy(urb->transfer_buffer, data, len);
urb->transfer_buffer_length = len;
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n");
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL, "Sending Bulk out packet\n");
/* For T3B,INT OUT end point will be used as bulk out end point */
- if ((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) {
+ if ((psIntfAdapter->psAdapter->chip_id == T3B) &&
+ (psIntfAdapter->bHighSpeedDevice == TRUE)) {
usb_fill_int_urb(urb, psIntfAdapter->udev,
psIntfAdapter->sBulkOut.bulk_out_pipe,
urb->transfer_buffer, len, write_bulk_callback, pTcb,
@@ -148,7 +184,10 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u
false == psIntfAdapter->bPreparingForBusSuspend) {
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval);
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX,
+ NEXT_SEND, DBG_LVL_ALL,
+ "failed submitting write urb, error %d",
+ retval);
if (retval == -EPIPE) {
psIntfAdapter->psAdapter->bEndPointHalted = TRUE;
wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue);
@@ -161,14 +200,14 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u
int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len)
{
struct bcm_usb_tcb *pTcb = NULL;
-
struct bcm_interface_adapter *psIntfAdapter = arg;
+
pTcb = GetBulkOutTcb(psIntfAdapter);
if (pTcb == NULL) {
- BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet");
+ BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0,
+ "No URB to transmit packet, dropping packet");
return -EFAULT;
}
return TransmitTcb(psIntfAdapter, pTcb, data, len);
}
-
diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c
index f95b06713a28..8c4030dfa7d5 100644
--- a/drivers/staging/bcm/LeakyBucket.c
+++ b/drivers/staging/bcm/LeakyBucket.c
@@ -20,6 +20,7 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
ULONG liCurrentTime;
INT i = 0;
struct timeval tv;
+ struct bcm_packet_info *curr_pi;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
"=====>\n");
@@ -31,30 +32,30 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
do_gettimeofday(&tv);
for (i = 0; i < NO_OF_QUEUES; i++) {
- if (TRUE == Adapter->PackInfo[i].bValid &&
- (1 == Adapter->PackInfo[i].ucDirection)) {
- liCurrentTime = ((tv.tv_sec-
- Adapter->PackInfo[i].stLastUpdateTokenAt.tv_sec)*1000 +
- (tv.tv_usec-Adapter->PackInfo[i].stLastUpdateTokenAt.tv_usec)/
+ curr_pi = &Adapter->PackInfo[i];
+
+ if (TRUE == curr_pi->bValid && (1 == curr_pi->ucDirection)) {
+ liCurrentTime = ((tv.tv_sec -
+ curr_pi->stLastUpdateTokenAt.tv_sec)*1000 +
+ (tv.tv_usec - curr_pi->stLastUpdateTokenAt.tv_usec) /
1000);
if (0 != liCurrentTime) {
- Adapter->PackInfo[i].uiCurrentTokenCount += (ULONG)
- ((Adapter->PackInfo[i].uiMaxAllowedRate) *
+ curr_pi->uiCurrentTokenCount += (ULONG)
+ ((curr_pi->uiMaxAllowedRate) *
((ULONG)((liCurrentTime)))/1000);
- memcpy(&Adapter->PackInfo[i].stLastUpdateTokenAt,
- &tv, sizeof(struct timeval));
- Adapter->PackInfo[i].liLastUpdateTokenAt = liCurrentTime;
- if (Adapter->PackInfo[i].uiCurrentTokenCount >=
- Adapter->PackInfo[i].uiMaxBucketSize) {
- Adapter->PackInfo[i].uiCurrentTokenCount =
- Adapter->PackInfo[i].uiMaxBucketSize;
+ memcpy(&curr_pi->stLastUpdateTokenAt, &tv,
+ sizeof(struct timeval));
+ curr_pi->liLastUpdateTokenAt = liCurrentTime;
+ if (curr_pi->uiCurrentTokenCount >=
+ curr_pi->uiMaxBucketSize) {
+ curr_pi->uiCurrentTokenCount =
+ curr_pi->uiMaxBucketSize;
}
}
}
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n");
- return;
-
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "<=====\n");
}
@@ -74,26 +75,35 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
***********************************************************************/
static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF)
{
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "IsPacketAllowedForFlow ===>");
+
/* Validate the parameters */
if (NULL == Adapter || (psSF < Adapter->PackInfo &&
(uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo));
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n",
+ Adapter, (psSF-Adapter->PackInfo));
return 0;
}
if (false != psSF->bValid && psSF->ucDirection) {
if (0 != psSF->uiCurrentTokenCount) {
- return psSF->uiCurrentTokenCount;
+ return psSF->uiCurrentTokenCount;
} else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n",
- psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
+ DBG_LVL_ALL,
+ "Not enough tokens in queue %zd Available %u\n",
+ psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
psSF->uiPendedLast = 1;
}
} else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "IPAFF: Queue %zd not valid\n",
+ psSF-Adapter->PackInfo);
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
+ "IsPacketAllowedForFlow <===");
return 0;
}
@@ -103,15 +113,17 @@ This function despatches packet from the specified queue.
@return Zero(success) or Negative value(failure)
*/
static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/
- struct bcm_packet_info *psSF, /**<Queue identifier*/
+ struct bcm_packet_info *psSF, /**<Queue identifier*/
struct sk_buff *Packet) /**<Pointer to the packet to be sent*/
{
INT Status = STATUS_FAILURE;
UINT uiIndex = 0, PktLen = 0;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
+ "=====>");
if (!Adapter || !Packet || !psSF) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
+ "Got NULL Adapter or Packet");
return -EINVAL;
}
@@ -122,118 +134,155 @@ static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adap
Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value);
if (Status == 0) {
for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) {
- if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
+ if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) &&
+ (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
Adapter->aTxPktSizeHist[uiIndex]++;
}
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<=====");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
+ "<=====");
return Status;
}
-/************************************************************************
-* Function - CheckAndSendPacketFromIndex()
-*
-* Description - This function dequeues the data/control packet from the
-* specified queue for transmission.
-*
-* Parameters - Adapter : Pointer to the driver control structure.
-* - iQIndex : The queue Identifier.
-*
-* Returns - None.
-*
-****************************************************************************/
-static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF)
+static void get_data_packet(struct bcm_mini_adapter *ad,
+ struct bcm_packet_info *ps_sf)
{
- struct sk_buff *QueuePacket = NULL;
- char *pControlPacket = NULL;
- INT Status = 0;
- int iPacketLen = 0;
-
+ int packet_len;
+ struct sk_buff *qpacket;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo));
- if ((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */
- if (!psSF->ucDirection)
- return;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
- if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
- return; /* in idle mode */
+ if (!ps_sf->ucDirection)
+ return;
- /* Check for Free Descriptors */
- if (atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..", atomic_read(&Adapter->CurrNumFreeTxDesc));
- return;
- }
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "UpdateTokenCount ");
+ if (ad->IdleMode || ad->bPreparingForLowPowerMode)
+ return; /* in idle mode */
+
+ /* Check for Free Descriptors */
+ if (atomic_read(&ad->CurrNumFreeTxDesc) <=
+ MINIMUM_PENDING_DESCRIPTORS) {
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ " No Free Tx Descriptor(%d) is available for Data pkt..",
+ atomic_read(&ad->CurrNumFreeTxDesc));
+ return;
+ }
- spin_lock_bh(&psSF->SFQueueLock);
- QueuePacket = psSF->FirstTxQueue;
+ spin_lock_bh(&ps_sf->SFQueueLock);
+ qpacket = ps_sf->FirstTxQueue;
- if (QueuePacket) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet");
+ if (qpacket) {
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "Dequeuing Data Packet");
- if (psSF->bEthCSSupport)
- iPacketLen = QueuePacket->len;
- else
- iPacketLen = QueuePacket->len-ETH_HLEN;
+ if (ps_sf->bEthCSSupport)
+ packet_len = qpacket->len;
+ else
+ packet_len = qpacket->len - ETH_HLEN;
- iPacketLen <<= 3;
- if (iPacketLen <= GetSFTokenCount(Adapter, psSF)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d",
- (iPacketLen >> 3));
+ packet_len <<= 3;
+ if (packet_len <= GetSFTokenCount(ad, ps_sf)) {
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL, "Allowed bytes %d",
+ (packet_len >> 3));
- DEQUEUEPACKET(psSF->FirstTxQueue, psSF->LastTxQueue);
- psSF->uiCurrentBytesOnHost -= (QueuePacket->len);
- psSF->uiCurrentPacketsOnHost--;
- atomic_dec(&Adapter->TotalPacketCount);
- spin_unlock_bh(&psSF->SFQueueLock);
+ DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue);
+ ps_sf->uiCurrentBytesOnHost -= (qpacket->len);
+ ps_sf->uiCurrentPacketsOnHost--;
+ atomic_dec(&ad->TotalPacketCount);
+ spin_unlock_bh(&ps_sf->SFQueueLock);
- Status = SendPacketFromQueue(Adapter, psSF, QueuePacket);
- psSF->uiPendedLast = false;
- } else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
- psSF->uiCurrentTokenCount, iPacketLen);
- /*
- this part indicates that because of non-availability of the tokens
- pkt has not been send out hence setting the pending flag indicating the host to send it out
- first next iteration.
- */
- psSF->uiPendedLast = TRUE;
- spin_unlock_bh(&psSF->SFQueueLock);
- }
+ SendPacketFromQueue(ad, ps_sf, qpacket);
+ ps_sf->uiPendedLast = false;
} else {
- spin_unlock_bh(&psSF->SFQueueLock);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL, "For Queue: %zd\n",
+ ps_sf - ad->PackInfo);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL,
+ "\nAvailable Tokens = %d required = %d\n",
+ ps_sf->uiCurrentTokenCount,
+ packet_len);
+ /*
+ this part indicates that because of
+ non-availability of the tokens
+ pkt has not been send out hence setting the
+ pending flag indicating the host to send it out
+ first next iteration.
+ */
+ ps_sf->uiPendedLast = TRUE;
+ spin_unlock_bh(&ps_sf->SFQueueLock);
}
} else {
+ spin_unlock_bh(&ps_sf->SFQueueLock);
+ }
+}
- if ((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0) &&
- (atomic_read(&Adapter->index_rd_txcntrlpkt) !=
- atomic_read(&Adapter->index_wr_txcntrlpkt))) {
- pControlPacket = Adapter->txctlpacket
- [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
- if (pControlPacket) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet");
- Status = SendControlPacket(Adapter, pControlPacket);
- if (STATUS_SUCCESS == Status) {
- spin_lock_bh(&psSF->SFQueueLock);
- psSF->NumOfPacketsSent++;
- psSF->uiSentBytes += ((struct bcm_leader *)pControlPacket)->PLength;
- psSF->uiSentPackets++;
- atomic_dec(&Adapter->TotalPacketCount);
- psSF->uiCurrentBytesOnHost -= ((struct bcm_leader *)pControlPacket)->PLength;
- psSF->uiCurrentPacketsOnHost--;
- atomic_inc(&Adapter->index_rd_txcntrlpkt);
- spin_unlock_bh(&psSF->SFQueueLock);
- } else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n");
- }
+static void send_control_packet(struct bcm_mini_adapter *ad,
+ struct bcm_packet_info *ps_sf)
+{
+ char *ctrl_packet = NULL;
+ INT status = 0;
+
+ if ((atomic_read(&ad->CurrNumFreeTxDesc) > 0) &&
+ (atomic_read(&ad->index_rd_txcntrlpkt) !=
+ atomic_read(&ad->index_wr_txcntrlpkt))) {
+ ctrl_packet = ad->txctlpacket
+ [(atomic_read(&ad->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
+ if (ctrl_packet) {
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL,
+ "Sending Control packet");
+ status = SendControlPacket(ad, ctrl_packet);
+ if (STATUS_SUCCESS == status) {
+ spin_lock_bh(&ps_sf->SFQueueLock);
+ ps_sf->NumOfPacketsSent++;
+ ps_sf->uiSentBytes += ((struct bcm_leader *)ctrl_packet)->PLength;
+ ps_sf->uiSentPackets++;
+ atomic_dec(&ad->TotalPacketCount);
+ ps_sf->uiCurrentBytesOnHost -= ((struct bcm_leader *)ctrl_packet)->PLength;
+ ps_sf->uiCurrentPacketsOnHost--;
+ atomic_inc(&ad->index_rd_txcntrlpkt);
+ spin_unlock_bh(&ps_sf->SFQueueLock);
} else {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong....");
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL,
+ "SendControlPacket Failed\n");
}
+ } else {
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL,
+ " Control Pkt is not available, Indexing is wrong....");
}
}
}
+/************************************************************************
+* Function - CheckAndSendPacketFromIndex()
+*
+* Description - This function dequeues the data/control packet from the
+* specified queue for transmission.
+*
+* Parameters - Adapter : Pointer to the driver control structure.
+* - iQIndex : The queue Identifier.
+*
+* Returns - None.
+*
+****************************************************************************/
+static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter,
+ struct bcm_packet_info *psSF)
+{
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "%zd ====>", (psSF-Adapter->PackInfo));
+ if ((psSF != &Adapter->PackInfo[HiPriority]) &&
+ Adapter->LinkUpStatus &&
+ atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */
+
+ get_data_packet(Adapter, psSF);
+ } else {
+ send_control_packet(Adapter, psSF);
+ }
+}
+
/*******************************************************************
* Function - transmit_packets()
@@ -252,22 +301,27 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
bool exit_flag = TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "=====>");
if (NULL == Adapter) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "Got NULL Adapter");
return;
}
if (Adapter->device_removed == TRUE) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "Device removed");
return;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "\nUpdateTokenCount ====>\n");
UpdateTokenCount(Adapter);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "\nPruneQueueAllSF ====>\n");
PruneQueueAllSF(Adapter);
@@ -280,8 +334,11 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
if (Adapter->PackInfo[iIndex].bValid &&
Adapter->PackInfo[iIndex].uiPendedLast &&
Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
- CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL,
+ "Calling CheckAndSendPacketFromIndex..");
+ CheckAndSendPacketFromIndex(Adapter,
+ &Adapter->PackInfo[iIndex]);
uiPrevTotalCount--;
}
}
@@ -290,13 +347,16 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
exit_flag = TRUE;
/* second iteration to parse non-pending queues */
for (iIndex = HiPriority; iIndex >= 0; iIndex--) {
- if (!uiPrevTotalCount || (TRUE == Adapter->device_removed))
+ if (!uiPrevTotalCount ||
+ (TRUE == Adapter->device_removed))
break;
if (Adapter->PackInfo[iIndex].bValid &&
Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
!Adapter->PackInfo[iIndex].uiPendedLast) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX,
+ TX_PACKETS, DBG_LVL_ALL,
+ "Calling CheckAndSendPacketFromIndex..");
CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
uiPrevTotalCount--;
exit_flag = false;
@@ -304,7 +364,8 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
}
if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS,
+ DBG_LVL_ALL, "In Idle Mode\n");
break;
}
if (exit_flag == TRUE)
@@ -313,5 +374,6 @@ VOID transmit_packets(struct bcm_mini_adapter *Adapter)
update_per_cid_rx(Adapter);
Adapter->txtransmit_running = 0;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
+ "<======");
}
diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c
index 7b2fa0f4a2e4..883f7394dee6 100644
--- a/drivers/staging/bcm/Misc.c
+++ b/drivers/staging/bcm/Misc.c
@@ -21,13 +21,13 @@ static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter)
Adapter->LinkStatus = SYNC_UP_REQUEST;
Adapter->TransferMode = IP_PACKET_ONLY_MODE;
Adapter->usBestEffortQueueIndex = -1;
- return;
}
int InitAdapter(struct bcm_mini_adapter *psAdapter)
{
int i = 0;
int Status = STATUS_SUCCESS;
+
BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter);
if (psAdapter == NULL) {
@@ -96,6 +96,7 @@ int InitAdapter(struct bcm_mini_adapter *psAdapter)
void AdapterFree(struct bcm_mini_adapter *Adapter)
{
int count;
+
beceem_protocol_reset(Adapter);
vendorextnExit(Adapter);
@@ -158,6 +159,7 @@ static int create_worker_threads(struct bcm_mini_adapter *psAdapter)
static struct file *open_firmware_file(struct bcm_mini_adapter *Adapter, const char *path)
{
struct file *flp = filp_open(path, O_RDONLY, S_IRWXU);
+
if (IS_ERR(flp)) {
pr_err(DRV_NAME "Unable To Open File %s, err %ld", path, PTR_ERR(flp));
flp = NULL;
@@ -281,7 +283,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) {
if ((pLeader->Status == LINK_UP_CONTROL_REQ) && (pLinkReq->szData[0] == LINK_DOWN_REQ_PAYLOAD)) {
- if ((pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE)) {
+ if (pLinkReq->szData[1] == LINK_SYNC_DOWN_SUBTYPE) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Link Down Sent in Idle Mode\n");
Adapter->usIdleModePattern = ABORT_IDLE_SYNCDOWN; /* LINK DOWN sent in Idle Mode */
} else {
@@ -402,6 +404,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer)
void LinkMessage(struct bcm_mini_adapter *Adapter)
{
struct bcm_link_request *pstLinkRequest = NULL;
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>");
if (Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) {
pstLinkRequest = kzalloc(sizeof(struct bcm_link_request), GFP_ATOMIC);
@@ -456,7 +459,6 @@ void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer)
Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__);
- return;
}
/**********************************************************************
@@ -534,13 +536,13 @@ void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff
}
} else if (SET_MAC_ADDRESS_RESPONSE == *pucBuffer) {
PUCHAR puMacAddr = (pucBuffer + 1);
+
Adapter->LinkStatus = SYNC_UP_REQUEST;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "MAC address response, sending SYNC_UP");
LinkMessage(Adapter);
memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "%s <=====", __func__);
- return;
}
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
@@ -548,6 +550,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0;
struct timeval tv;
struct bcm_link_request stIdleResponse = {{0} };
+
memset(&tv, 0, sizeof(tv));
stIdleResponse.Leader.Status = IDLE_MESSAGE;
stIdleResponse.Leader.PLength = IDLE_MODE_PAYLOAD_LENGTH;
@@ -624,7 +627,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter)
}
status = CopyBufferToControlPacket(Adapter, &stIdleResponse);
- if ((status != STATUS_SUCCESS)) {
+ if (status != STATUS_SUCCESS) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n");
Adapter->bPreparingForLowPowerMode = false;
StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
@@ -770,8 +773,6 @@ void DumpPackInfo(struct bcm_mini_adapter *Adapter)
for (uiLoopIndex = 0; uiLoopIndex < MIBS_MAX_HIST_ENTRIES; uiLoopIndex++)
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Adapter->aTxPktSizeHist[%x] = %x\n", uiLoopIndex, Adapter->aTxPktSizeHist[uiLoopIndex]);
-
- return;
}
int reset_card_proc(struct bcm_mini_adapter *ps_adapter)
@@ -1153,7 +1154,7 @@ static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter)
reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02;
psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1);
- if (reporting_mode == TRUE) {
+ if (reporting_mode) {
BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "can't do suspen/resume as reporting mode is enable");
psAdapter->bDoSuspend = false;
}
@@ -1224,6 +1225,7 @@ int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned in
int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize)
{
int status = STATUS_SUCCESS;
+
down(&Adapter->rdmwrmsync);
if ((Adapter->IdleMode == TRUE) ||
@@ -1282,6 +1284,7 @@ exit:
static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter)
{
int clear_abort_pattern = 0, Status = 0;
+
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n");
/* target has woken up From Shut Down */
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n");
@@ -1385,7 +1388,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter)
}
Status = CopyBufferToControlPacket(Adapter, &stShutdownResponse);
- if ((Status != STATUS_SUCCESS)) {
+ if (Status != STATUS_SUCCESS) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n");
Adapter->bPreparingForLowPowerMode = false;
StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
@@ -1418,7 +1421,6 @@ static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR p
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n");
- return;
}
void ResetCounters(struct bcm_mini_adapter *Adapter)
@@ -1440,6 +1442,7 @@ void ResetCounters(struct bcm_mini_adapter *Adapter)
struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP)
{
unsigned int uiIndex = 0;
+
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@@ -1454,6 +1457,7 @@ struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter,
void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo)
{
unsigned int uiIndex = 0;
+
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) {
memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info));
@@ -1465,6 +1469,7 @@ void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_p
void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp)
{
unsigned int uiIndex = 0;
+
for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) {
if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) &&
(Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) &&
@@ -1528,6 +1533,7 @@ void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
{
struct sk_buff *PacketToDrop = NULL;
struct net_device_stats *netstats = &Adapter->dev->stats;
+
spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
while (Adapter->PackInfo[iQIndex].FirstTxQueue && atomic_read(&Adapter->TotalPacketCount)) {
@@ -1551,6 +1557,7 @@ void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex)
static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter)
{
int i;
+
if (netif_msg_link(Adapter))
pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name);
diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c
index 07c5a0bae1ed..5f4e503d54ec 100644
--- a/drivers/staging/bcm/PHSModule.c
+++ b/drivers/staging/bcm/PHSModule.c
@@ -1,46 +1,80 @@
#include "headers.h"
-static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_table *psServiceFlowTable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
-
-static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid, B_UINT16 uiClsId, struct bcm_phs_entry *pstServiceFlowEntry, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
-
-static UINT CreateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, enum bcm_phs_classifier_context eClsContext, B_UINT8 u8AssociatedPHSI);
-
-static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId, struct bcm_phs_classifier_entry *pstClassifierEntry, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *psPhsRule, B_UINT8 u8AssociatedPHSI);
-
-static bool ValidatePHSRuleComplete(struct bcm_phs_rule *psPhsRule);
-
-static bool DerefPhsRule(B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule);
-
-static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_classifier_entry **ppstClassifierEntry);
-
-static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable, B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext, struct bcm_phs_rule **ppstPhsRule);
+static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,
+ B_UINT16 uiClsId,
+ struct bcm_phs_table *psServiceFlowTable,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI);
+
+static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,
+ B_UINT16 uiClsId,
+ struct bcm_phs_entry *pstServiceFlowEntry,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI);
+
+static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *psPhsRule,
+ enum bcm_phs_classifier_context eClsContext,
+ B_UINT8 u8AssociatedPHSI);
+
+static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,
+ struct bcm_phs_classifier_entry *pstClassifierEntry,
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI);
+
+static bool ValidatePHSRuleComplete(const struct bcm_phs_rule *psPhsRule);
+
+static bool DerefPhsRule(B_UINT16 uiClsId,
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *pstPhsRule);
+
+static UINT GetClassifierEntry(struct bcm_phs_classifier_table *pstClassifierTable,
+ B_UINT32 uiClsid,
+ enum bcm_phs_classifier_context eClsContext,
+ struct bcm_phs_classifier_entry **ppstClassifierEntry);
+
+static UINT GetPhsRuleEntry(struct bcm_phs_classifier_table *pstClassifierTable,
+ B_UINT32 uiPHSI,
+ enum bcm_phs_classifier_context eClsContext,
+ struct bcm_phs_rule **ppstPhsRule);
static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesTable);
-static int phs_compress(struct bcm_phs_rule *phs_members, unsigned char *in_buf,
- unsigned char *out_buf, unsigned int *header_size, UINT *new_header_size);
+static int phs_compress(struct bcm_phs_rule *phs_members,
+ unsigned char *in_buf,
+ unsigned char *out_buf,
+ unsigned int *header_size,
+ UINT *new_header_size);
-static int verify_suppress_phsf(unsigned char *in_buffer, unsigned char *out_buffer,
- unsigned char *phsf, unsigned char *phsm, unsigned int phss, unsigned int phsv, UINT *new_header_size);
+static int verify_suppress_phsf(unsigned char *in_buffer,
+ unsigned char *out_buffer,
+ unsigned char *phsf,
+ unsigned char *phsm,
+ unsigned int phss,
+ unsigned int phsv,
+ UINT *new_header_size);
-static int phs_decompress(unsigned char *in_buf, unsigned char *out_buf,
- struct bcm_phs_rule *phs_rules, UINT *header_size);
+static int phs_decompress(unsigned char *in_buf,
+ unsigned char *out_buf,
+ struct bcm_phs_rule *phs_rules,
+ UINT *header_size);
static ULONG PhsCompress(void *pvContext,
- B_UINT16 uiVcid,
- B_UINT16 uiClsId,
- void *pvInputBuffer,
- void *pvOutputBuffer,
- UINT *pOldHeaderSize,
- UINT *pNewHeaderSize);
+ B_UINT16 uiVcid,
+ B_UINT16 uiClsId,
+ void *pvInputBuffer,
+ void *pvOutputBuffer,
+ UINT *pOldHeaderSize,
+ UINT *pNewHeaderSize);
static ULONG PhsDeCompress(void *pvContext,
- B_UINT16 uiVcid,
- void *pvInputBuffer,
- void *pvOutputBuffer,
- UINT *pInHeaderSize,
- UINT *pOutHeaderSize);
+ B_UINT16 uiVcid,
+ void *pvInputBuffer,
+ void *pvOutputBuffer,
+ UINT *pInHeaderSize,
+ UINT *pOutHeaderSize);
#define IN
#define OUT
@@ -76,9 +110,11 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
UINT unPhsOldHdrSize = 0;
UINT unPHSNewPktHeaderLen = 0;
/* Pointer to PHS IN Hdr Buffer */
- PUCHAR pucPHSPktHdrInBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
+ PUCHAR pucPHSPktHdrInBuf =
+ Adapter->stPhsTxContextInfo.ucaHdrSuppressionInBuf;
/* Pointer to PHS OUT Hdr Buffer */
- PUCHAR pucPHSPktHdrOutBuf = Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
+ PUCHAR pucPHSPktHdrOutBuf =
+ Adapter->stPhsTxContextInfo.ucaHdrSuppressionOutBuf;
UINT usPacketType;
UINT BytesToRemove = 0;
bool bPHSI = 0;
@@ -87,7 +123,8 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
struct sk_buff *newPacket = NULL;
struct sk_buff *Packet = *pPacket;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "In PHSTransmit");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "In PHSTransmit");
if (!bEthCSSupport)
BytesToRemove = ETH_HLEN;
@@ -109,23 +146,31 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
(unPHSPktHdrBytesCopied <= MAX_PHS_LENGTHS)) {
/*
- * Step 2 Suppress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf.
- * Suppress only if IP Header and PHS Enabled For the Service Flow
+ * Step 2 Suppress Header using PHS and fill into intermediate
+ * ucaPHSPktHdrOutBuf.
+ * Suppress only if IP Header and PHS Enabled For the
+ * Service Flow
*/
if (((usPacketType == ETHERNET_FRAMETYPE_IPV4) ||
(usPacketType == ETHERNET_FRAMETYPE_IPV6)) &&
(bHeaderSuppressionEnabled)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nTrying to PHS Compress Using Classifier rule 0x%X", uiClassifierRuleID);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND,
+ DBG_LVL_ALL,
+ "\nTrying to PHS Compress Using Classifier rule 0x%X",
+ uiClassifierRuleID);
unPHSNewPktHeaderLen = unPHSPktHdrBytesCopied;
ulPhsStatus = PhsCompress(&Adapter->stBCMPhsContext,
- Vcid,
- uiClassifierRuleID,
- pucPHSPktHdrInBuf,
- pucPHSPktHdrOutBuf,
- &unPhsOldHdrSize,
- &unPHSNewPktHeaderLen);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nPHS Old header Size : %d New Header Size %d\n", unPhsOldHdrSize, unPHSNewPktHeaderLen);
+ Vcid,
+ uiClassifierRuleID,
+ pucPHSPktHdrInBuf,
+ pucPHSPktHdrOutBuf,
+ &unPhsOldHdrSize,
+ &unPHSNewPktHeaderLen);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND,
+ DBG_LVL_ALL,
+ "\nPHS Old header Size : %d New Header Size %d\n",
+ unPhsOldHdrSize, unPHSNewPktHeaderLen);
if (unPHSNewPktHeaderLen == unPhsOldHdrSize) {
@@ -137,32 +182,45 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
if (ulPhsStatus == STATUS_PHS_COMPRESSED) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "PHS Sending packet Compressed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+ PHS_SEND, DBG_LVL_ALL,
+ "PHS Sending packet Compressed");
if (skb_cloned(Packet)) {
- newPacket = skb_copy(Packet, GFP_ATOMIC);
+ newPacket =
+ skb_copy(Packet, GFP_ATOMIC);
if (newPacket == NULL)
return STATUS_FAILURE;
dev_kfree_skb(Packet);
*pPacket = Packet = newPacket;
- pucPHSPktHdrInBuf = Packet->data + BytesToRemove;
+ pucPHSPktHdrInBuf =
+ Packet->data + BytesToRemove;
}
- numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen + PHSI_LEN);
+ numBytesCompressed = unPhsOldHdrSize -
+ (unPHSNewPktHeaderLen + PHSI_LEN);
- memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN);
- memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove);
+ memcpy(pucPHSPktHdrInBuf + numBytesCompressed,
+ pucPHSPktHdrOutBuf,
+ unPHSNewPktHeaderLen + PHSI_LEN);
+ memcpy(Packet->data + numBytesCompressed,
+ Packet->data, BytesToRemove);
skb_pull(Packet, numBytesCompressed);
return STATUS_SUCCESS;
} else {
- /* if one byte headroom is not available, increase it through skb_cow */
+ /* if one byte headroom is not available,
+ * increase it through skb_cow
+ */
if (!(skb_headroom(Packet) > 0)) {
if (skb_cow(Packet, 1)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SKB Cow Failed\n");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_PRINTK,
+ 0, 0,
+ "SKB Cow Failed\n");
return STATUS_FAILURE;
}
}
@@ -179,22 +237,25 @@ int PHSTransmit(struct bcm_mini_adapter *Adapter,
} else {
if (!bHeaderSuppressionEnabled)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nHeader Suppression Disabled For SF: No PHS\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
+ PHS_SEND, DBG_LVL_ALL,
+ "\nHeader Suppression Disabled For SF: No PHS\n");
return STATUS_SUCCESS;
}
}
- /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"PHSTransmit : Dumping data packet After PHS"); */
+ /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ * "PHSTransmit : Dumping data packet After PHS"); */
return STATUS_SUCCESS;
}
int PHSReceive(struct bcm_mini_adapter *Adapter,
- USHORT usVcid,
- struct sk_buff *packet,
- UINT *punPacketLen,
- UCHAR *pucEthernetHdr,
- UINT bHeaderSuppressionEnabled)
+ USHORT usVcid,
+ struct sk_buff *packet,
+ UINT *punPacketLen,
+ UCHAR *pucEthernetHdr,
+ UINT bHeaderSuppressionEnabled)
{
u32 nStandardPktHdrLen = 0;
u32 nTotalsuppressedPktHdrBytes = 0;
@@ -203,7 +264,9 @@ int PHSReceive(struct bcm_mini_adapter *Adapter,
UINT TotalBytesAdded = 0;
if (!bHeaderSuppressionEnabled) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nPhs Disabled for incoming packet");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
+ DBG_LVL_ALL,
+ "\nPhs Disabled for incoming packet");
return ulPhsStatus;
}
@@ -212,27 +275,31 @@ int PHSReceive(struct bcm_mini_adapter *Adapter,
/* Restore PHS suppressed header */
nStandardPktHdrLen = packet->len;
ulPhsStatus = PhsDeCompress(&Adapter->stBCMPhsContext,
- usVcid,
- pucInBuff,
- Adapter->ucaPHSPktRestoreBuf,
- &nTotalsuppressedPktHdrBytes,
- &nStandardPktHdrLen);
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
+ usVcid,
+ pucInBuff,
+ Adapter->ucaPHSPktRestoreBuf,
+ &nTotalsuppressedPktHdrBytes,
+ &nStandardPktHdrLen);
+
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
+ "\nSuppressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x",
nTotalsuppressedPktHdrBytes, nStandardPktHdrLen);
if (ulPhsStatus != STATUS_PHS_COMPRESSED) {
skb_pull(packet, 1);
return STATUS_SUCCESS;
} else {
- TotalBytesAdded = nStandardPktHdrLen - nTotalsuppressedPktHdrBytes - PHSI_LEN;
+ TotalBytesAdded = nStandardPktHdrLen -
+ nTotalsuppressedPktHdrBytes - PHSI_LEN;
if (TotalBytesAdded) {
if (skb_headroom(packet) >= (SKB_RESERVE_ETHERNET_HEADER + TotalBytesAdded))
skb_push(packet, TotalBytesAdded);
else {
if (skb_cow(packet, skb_headroom(packet) + TotalBytesAdded)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "cow failed in receive\n");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_PRINTK, 0, 0,
+ "cow failed in receive\n");
return STATUS_FAILURE;
}
@@ -240,7 +307,8 @@ int PHSReceive(struct bcm_mini_adapter *Adapter,
}
}
- memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen);
+ memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf,
+ nStandardPktHdrLen);
}
return STATUS_SUCCESS;
@@ -250,46 +318,58 @@ void DumpFullPacket(UCHAR *pBuf, UINT nPktLen)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dumping Data Packet");
- BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, pBuf, nPktLen);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,
+ "Dumping Data Packet");
+ BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL,
+ pBuf, nPktLen);
}
/*
* Procedure: phs_init
*
- * Description: This routine is responsible for allocating memory for classifier and
- * PHS rules.
+ * Description: This routine is responsible for allocating memory for classifier
+ * and PHS rules.
*
* Arguments:
- * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules and PHS Rules , RX, TX buffer etc
+ * pPhsdeviceExtension - ptr to Device extension containing PHS Classifier rules
+ * and PHS Rules , RX, TX buffer etc
*
* Returns:
* TRUE(1) -If allocation of memory was successful.
* FALSE -If allocation of memory fails.
*/
-int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adapter *Adapter)
+int phs_init(struct bcm_phs_extension *pPhsdeviceExtension,
+ struct bcm_mini_adapter *Adapter)
{
int i;
struct bcm_phs_table *pstServiceFlowTable;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nPHS:phs_init function");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "\nPHS:phs_init function");
if (pPhsdeviceExtension->pstServiceFlowPhsRulesTable)
return -EINVAL;
- pPhsdeviceExtension->pstServiceFlowPhsRulesTable = kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
+ pPhsdeviceExtension->pstServiceFlowPhsRulesTable =
+ kzalloc(sizeof(struct bcm_phs_table), GFP_KERNEL);
if (!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL,
+ "\nAllocation ServiceFlowPhsRulesTable failed");
return -ENOMEM;
}
pstServiceFlowTable = pPhsdeviceExtension->pstServiceFlowPhsRulesTable;
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
- struct bcm_phs_entry sServiceFlow = pstServiceFlowTable->stSFList[i];
- sServiceFlow.pstClassifierTable = kzalloc(sizeof(struct bcm_phs_classifier_table), GFP_KERNEL);
+ struct bcm_phs_entry sServiceFlow =
+ pstServiceFlowTable->stSFList[i];
+ sServiceFlow.pstClassifierTable =
+ kzalloc(sizeof(struct bcm_phs_classifier_table),
+ GFP_KERNEL);
if (!sServiceFlow.pstClassifierTable) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "\nAllocation failed");
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
return -ENOMEM;
@@ -298,22 +378,26 @@ int phs_init(struct bcm_phs_extension *pPhsdeviceExtension, struct bcm_mini_adap
pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
if (pPhsdeviceExtension->CompressedTxBuffer == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "\nAllocation failed");
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
return -ENOMEM;
}
- pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
+ pPhsdeviceExtension->UnCompressedRxBuffer =
+ kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL);
if (pPhsdeviceExtension->UnCompressedRxBuffer == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "\nAllocation failed");
kfree(pPhsdeviceExtension->CompressedTxBuffer);
free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable);
pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL;
return -ENOMEM;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n phs_init Successful");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "\n phs_init Successful");
return STATUS_SUCCESS;
}
@@ -352,21 +436,24 @@ int PhsCleanup(IN struct bcm_phs_extension *pPHSDeviceExt)
* >0 Error.
*/
ULONG PhsUpdateClassifierRule(IN void *pvContext,
- IN B_UINT16 uiVcid ,
- IN B_UINT16 uiClsId ,
- IN struct bcm_phs_rule *psPhsRule,
- IN B_UINT8 u8AssociatedPHSI)
+ IN B_UINT16 uiVcid ,
+ IN B_UINT16 uiClsId ,
+ IN struct bcm_phs_rule *psPhsRule,
+ IN B_UINT8 u8AssociatedPHSI)
{
ULONG lStatus = 0;
UINT nSFIndex = 0;
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_extension *pDeviceExtension =
+ (struct bcm_phs_extension *)pvContext;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS With Corr2 Changes\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "PHS With Corr2 Changes\n");
if (pDeviceExtension == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Invalid Device Extension\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "Invalid Device Extension\n");
return ERR_PHS_INVALID_DEVICE_EXETENSION;
}
@@ -375,18 +462,22 @@ ULONG PhsUpdateClassifierRule(IN void *pvContext,
/* Retrieve the SFID Entry Index for requested Service Flow */
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
- uiVcid, &pstServiceFlowEntry);
+ uiVcid, &pstServiceFlowEntry);
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
/* This is a new SF. Create a mapping entry for this */
lStatus = CreateSFToClassifierRuleMapping(uiVcid, uiClsId,
- pDeviceExtension->pstServiceFlowPhsRulesTable, psPhsRule, u8AssociatedPHSI);
+ pDeviceExtension->pstServiceFlowPhsRulesTable,
+ psPhsRule,
+ u8AssociatedPHSI);
return lStatus;
}
/* SF already Exists Add PHS Rule to existing SF */
lStatus = CreateClassiferToPHSRuleMapping(uiVcid, uiClsId,
- pstServiceFlowEntry, psPhsRule, u8AssociatedPHSI);
+ pstServiceFlowEntry,
+ psPhsRule,
+ u8AssociatedPHSI);
return lStatus;
}
@@ -407,40 +498,48 @@ ULONG PhsUpdateClassifierRule(IN void *pvContext,
* 0 if successful,
* >0 Error.
*/
-ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI)
+ULONG PhsDeletePHSRule(IN void *pvContext,
+ IN B_UINT16 uiVcid,
+ IN B_UINT8 u8PHSI)
{
UINT nSFIndex = 0, nClsidIndex = 0;
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_classifier_entry *curr_entry;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "======>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "======>\n");
if (pDeviceExtension) {
/* Retrieve the SFID Entry Index for requested Service Flow */
- nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid, &pstServiceFlowEntry);
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "SFID Match Failed\n");
return ERR_SF_MATCH_FAIL;
}
pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
if (pstClassifierRulesTable) {
for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
- if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) {
- if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) {
+ curr_entry = &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
+ if (curr_entry->bUsed &&
+ curr_entry->pstPhsRule &&
+ (curr_entry->pstPhsRule->u8PHSI == u8PHSI)) {
- if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
+ if (curr_entry->pstPhsRule->u8RefCnt)
+ curr_entry->pstPhsRule->u8RefCnt--;
- if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
+ if (0 == curr_entry->pstPhsRule->u8RefCnt)
+ kfree(curr_entry->pstPhsRule);
- memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0,
- sizeof(struct bcm_phs_classifier_entry));
- }
+ memset(curr_entry,
+ 0,
+ sizeof(struct bcm_phs_classifier_entry));
}
}
}
@@ -464,44 +563,62 @@ ULONG PhsDeletePHSRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT8 u8PHSI
* 0 if successful,
* >0 Error.
*/
-ULONG PhsDeleteClassifierRule(IN void *pvContext, IN B_UINT16 uiVcid, IN B_UINT16 uiClsId)
+ULONG PhsDeleteClassifierRule(IN void *pvContext,
+ IN B_UINT16 uiVcid,
+ IN B_UINT16 uiClsId)
{
UINT nSFIndex = 0, nClsidIndex = 0;
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_extension *pDeviceExtension =
+ (struct bcm_phs_extension *)pvContext;
- if (pDeviceExtension) {
- /* Retrieve the SFID Entry Index for requested Service Flow */
- nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable, uiVcid, &pstServiceFlowEntry);
- if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
- return ERR_SF_MATCH_FAIL;
- }
+ if (!pDeviceExtension)
+ goto out;
- nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
- uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
-
- if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) {
- if (pstClassifierEntry->pstPhsRule) {
- if (pstClassifierEntry->pstPhsRule->u8RefCnt)
- pstClassifierEntry->pstPhsRule->u8RefCnt--;
+ /* Retrieve the SFID Entry Index for requested Service Flow */
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid, &pstServiceFlowEntry);
+ if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "SFID Match Failed\n");
+ return ERR_SF_MATCH_FAIL;
+ }
- if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
- kfree(pstClassifierEntry->pstPhsRule);
- }
- memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
- }
+ nClsidIndex =
+ GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
+ uiClsId,
+ eActiveClassifierRuleContext,
+ &pstClassifierEntry);
- nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
- uiClsId, eOldClassifierRuleContext, &pstClassifierEntry);
+ if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
+ (!pstClassifierEntry->bUnclassifiedPHSRule)) {
+ if (pstClassifierEntry->pstPhsRule) {
+ if (pstClassifierEntry->pstPhsRule->u8RefCnt)
+ pstClassifierEntry->pstPhsRule->u8RefCnt--;
- if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) {
- kfree(pstClassifierEntry->pstPhsRule);
- memset(pstClassifierEntry, 0, sizeof(struct bcm_phs_classifier_entry));
+ if (0 == pstClassifierEntry->pstPhsRule->u8RefCnt)
+ kfree(pstClassifierEntry->pstPhsRule);
}
+ memset(pstClassifierEntry, 0,
+ sizeof(struct bcm_phs_classifier_entry));
+ }
+
+ nClsidIndex =
+ GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
+ uiClsId,
+ eOldClassifierRuleContext,
+ &pstClassifierEntry);
+
+ if ((nClsidIndex != PHS_INVALID_TABLE_INDEX) &&
+ (!pstClassifierEntry->bUnclassifiedPHSRule)) {
+ kfree(pstClassifierEntry->pstPhsRule);
+ memset(pstClassifierEntry, 0,
+ sizeof(struct bcm_phs_classifier_entry));
}
+
+out:
return 0;
}
@@ -526,50 +643,65 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_phs_classifier_table *pstClassifierRulesTable = NULL;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_extension *pDeviceExtension =
+ (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_classifier_entry *curr_clsf_entry;
+ struct bcm_phs_classifier_entry *curr_rules_list;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "====>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "====>\n");
- if (pDeviceExtension) {
- /* Retrieve the SFID Entry Index for requested Service Flow */
- nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
- uiVcid, &pstServiceFlowEntry);
- if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "SFID Match Failed\n");
- return ERR_SF_MATCH_FAIL;
- }
+ if (!pDeviceExtension)
+ goto out;
- pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
- if (pstClassifierRulesTable) {
- for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
- if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) {
+ /* Retrieve the SFID Entry Index for requested Service Flow */
+ nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
+ uiVcid, &pstServiceFlowEntry);
+ if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "SFID Match Failed\n");
+ return ERR_SF_MATCH_FAIL;
+ }
- if (pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
+ pstClassifierRulesTable = pstServiceFlowEntry->pstClassifierTable;
+ if (pstClassifierRulesTable) {
+ for (nClsidIndex = 0; nClsidIndex < MAX_PHSRULE_PER_SF; nClsidIndex++) {
+ curr_clsf_entry =
+ &pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex];
- if (0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule);
+ curr_rules_list =
+ &pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex];
- pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule = NULL;
- }
- memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
- if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) {
+ if (curr_clsf_entry->pstPhsRule) {
- if (pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--;
+ if (curr_clsf_entry->pstPhsRule->u8RefCnt)
+ curr_clsf_entry->pstPhsRule->u8RefCnt--;
- if (0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt)
- kfree(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule);
+ if (0 == curr_clsf_entry->pstPhsRule->u8RefCnt)
+ kfree(curr_clsf_entry->pstPhsRule);
- pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule = NULL;
- }
- memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(struct bcm_phs_classifier_entry));
+ curr_clsf_entry->pstPhsRule = NULL;
}
+ memset(curr_clsf_entry, 0,
+ sizeof(struct bcm_phs_classifier_entry));
+ if (curr_rules_list->pstPhsRule) {
+
+ if (curr_rules_list->pstPhsRule->u8RefCnt)
+ curr_rules_list->pstPhsRule->u8RefCnt--;
+
+ if (0 == curr_rules_list->pstPhsRule->u8RefCnt)
+ kfree(curr_rules_list->pstPhsRule);
+
+ curr_rules_list->pstPhsRule = NULL;
+ }
+ memset(curr_rules_list, 0,
+ sizeof(struct bcm_phs_classifier_entry));
}
- pstServiceFlowEntry->bUsed = false;
- pstServiceFlowEntry->uiVcid = 0;
}
+ pstServiceFlowEntry->bUsed = false;
+ pstServiceFlowEntry->uiVcid = 0;
+out:
return 0;
}
@@ -580,13 +712,18 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
* Exported function to compress the data using PHS.
*
* Arguments:
- * IN void* pvContext - PHS Driver Specific Context.
- * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header compression applies.
- * IN UINT uiClsId - The Classifier ID to which current packet header compression applies.
- * IN void *pvInputBuffer - The Input buffer containg packet header data
- * IN void *pvOutputBuffer - The output buffer returned by this function after PHS
- * IN UINT *pOldHeaderSize - The actual size of the header before PHS
- * IN UINT *pNewHeaderSize - The new size of the header after applying PHS
+ * IN void* pvContext - PHS Driver Specific Context.
+ * IN B_UINT16 uiVcid - The Service Flow ID to which current
+ * packet header compression applies.
+ * IN UINT uiClsId - The Classifier ID to which current packet
+ * header compression applies.
+ * IN void *pvInputBuffer - The Input buffer containg packet header
+ * data
+ * IN void *pvOutputBuffer - The output buffer returned by this
+ * function after PHS
+ * IN UINT *pOldHeaderSize - The actual size of the header before PHS
+ * IN UINT *pNewHeaderSize - The new size of the header after applying
+ * PHS
*
* Return Value:
*
@@ -594,12 +731,12 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
* >0 Error.
*/
static ULONG PhsCompress(IN void *pvContext,
- IN B_UINT16 uiVcid,
- IN B_UINT16 uiClsId,
- IN void *pvInputBuffer,
- OUT void *pvOutputBuffer,
- OUT UINT *pOldHeaderSize,
- OUT UINT *pNewHeaderSize)
+ IN B_UINT16 uiVcid,
+ IN B_UINT16 uiClsId,
+ IN void *pvInputBuffer,
+ OUT void *pvOutputBuffer,
+ OUT UINT *pOldHeaderSize,
+ OUT UINT *pNewHeaderSize)
{
UINT nSFIndex = 0, nClsidIndex = 0;
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
@@ -607,30 +744,36 @@ static ULONG PhsCompress(IN void *pvContext,
struct bcm_phs_rule *pstPhsRule = NULL;
ULONG lStatus = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_extension *pDeviceExtension =
+ (struct bcm_phs_extension *)pvContext;
if (pDeviceExtension == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Invalid Device Extension\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "Invalid Device Extension\n");
lStatus = STATUS_PHS_NOCOMPRESSION;
return lStatus;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "Suppressing header\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "Suppressing header\n");
/* Retrieve the SFID Entry Index for requested Service Flow */
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
- uiVcid, &pstServiceFlowEntry);
+ uiVcid, &pstServiceFlowEntry);
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "SFID Match Failed\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "SFID Match Failed\n");
lStatus = STATUS_PHS_NOCOMPRESSION;
return lStatus;
}
nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable,
- uiClsId, eActiveClassifierRuleContext, &pstClassifierEntry);
+ uiClsId, eActiveClassifierRuleContext,
+ &pstClassifierEntry);
if (nClsidIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "No PHS Rule Defined For Classifier\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "No PHS Rule Defined For Classifier\n");
lStatus = STATUS_PHS_NOCOMPRESSION;
return lStatus;
}
@@ -638,20 +781,26 @@ static ULONG PhsCompress(IN void *pvContext,
/* get rule from SF id,Cls ID pair and proceed */
pstPhsRule = pstClassifierEntry->pstPhsRule;
if (!ValidatePHSRuleComplete(pstPhsRule)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "PHS Rule Defined For Classifier But Not Complete\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "PHS Rule Defined For Classifier But Not Complete\n");
lStatus = STATUS_PHS_NOCOMPRESSION;
return lStatus;
}
/* Compress Packet */
- lStatus = phs_compress(pstPhsRule, (PUCHAR)pvInputBuffer,
- (PUCHAR)pvOutputBuffer, pOldHeaderSize, pNewHeaderSize);
+ lStatus = phs_compress(pstPhsRule,
+ (PUCHAR)pvInputBuffer,
+ (PUCHAR)pvOutputBuffer,
+ pOldHeaderSize,
+ pNewHeaderSize);
if (lStatus == STATUS_PHS_COMPRESSED) {
- pstPhsRule->PHSModifiedBytes += *pOldHeaderSize - *pNewHeaderSize - 1;
+ pstPhsRule->PHSModifiedBytes +=
+ *pOldHeaderSize - *pNewHeaderSize - 1;
pstPhsRule->PHSModifiedNumPackets++;
- } else
+ } else {
pstPhsRule->PHSErrorNumPackets++;
+ }
return lStatus;
}
@@ -663,11 +812,15 @@ static ULONG PhsCompress(IN void *pvContext,
* Exported function to restore the packet header in Rx path.
*
* Arguments:
- * IN void* pvContext - PHS Driver Specific Context.
- * IN B_UINT16 uiVcid - The Service Flow ID to which current packet header restoration applies.
- * IN void *pvInputBuffer - The Input buffer containg suppressed packet header data
- * OUT void *pvOutputBuffer - The output buffer returned by this function after restoration
- * OUT UINT *pHeaderSize - The packet header size after restoration is returned in this parameter.
+ * IN void* pvContext - PHS Driver Specific Context.
+ * IN B_UINT16 uiVcid - The Service Flow ID to which current
+ * packet header restoration applies.
+ * IN void *pvInputBuffer - The Input buffer containg suppressed
+ * packet header data
+ * OUT void *pvOutputBuffer - The output buffer returned by this
+ * function after restoration
+ * OUT UINT *pHeaderSize - The packet header size after restoration
+ * is returned in this parameter.
*
* Return Value:
*
@@ -675,52 +828,65 @@ static ULONG PhsCompress(IN void *pvContext,
* >0 Error.
*/
static ULONG PhsDeCompress(IN void *pvContext,
- IN B_UINT16 uiVcid,
- IN void *pvInputBuffer,
- OUT void *pvOutputBuffer,
- OUT UINT *pInHeaderSize,
- OUT UINT *pOutHeaderSize)
+ IN B_UINT16 uiVcid,
+ IN void *pvInputBuffer,
+ OUT void *pvOutputBuffer,
+ OUT UINT *pInHeaderSize,
+ OUT UINT *pOutHeaderSize)
{
UINT nSFIndex = 0, nPhsRuleIndex = 0;
struct bcm_phs_entry *pstServiceFlowEntry = NULL;
struct bcm_phs_rule *pstPhsRule = NULL;
UINT phsi;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- struct bcm_phs_extension *pDeviceExtension = (struct bcm_phs_extension *)pvContext;
+ struct bcm_phs_extension *pDeviceExtension =
+ (struct bcm_phs_extension *)pvContext;
*pInHeaderSize = 0;
if (pDeviceExtension == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Invalid Device Extension\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
+ DBG_LVL_ALL, "Invalid Device Extension\n");
return ERR_PHS_INVALID_DEVICE_EXETENSION;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "Restoring header\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
+ "Restoring header\n");
phsi = *((unsigned char *)(pvInputBuffer));
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "PHSI To Be Used For restore : %x\n", phsi);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
+ "PHSI To Be Used For restore : %x\n", phsi);
if (phsi == UNCOMPRESSED_PACKET)
return STATUS_PHS_NOCOMPRESSION;
/* Retrieve the SFID Entry Index for requested Service Flow */
nSFIndex = GetServiceFlowEntry(pDeviceExtension->pstServiceFlowPhsRulesTable,
- uiVcid, &pstServiceFlowEntry);
+ uiVcid, &pstServiceFlowEntry);
if (nSFIndex == PHS_INVALID_TABLE_INDEX) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "SFID Match Failed During Lookup\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
+ DBG_LVL_ALL,
+ "SFID Match Failed During Lookup\n");
return ERR_SF_MATCH_FAIL;
}
- nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable, phsi,
- eActiveClassifierRuleContext, &pstPhsRule);
+ nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
+ phsi,
+ eActiveClassifierRuleContext,
+ &pstPhsRule);
if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX) {
- /* Phs Rule does not exist in active rules table. Lets try in the old rules table. */
+ /* Phs Rule does not exist in active rules table. Lets try
+ * in the old rules table. */
nPhsRuleIndex = GetPhsRuleEntry(pstServiceFlowEntry->pstClassifierTable,
- phsi, eOldClassifierRuleContext, &pstPhsRule);
+ phsi,
+ eOldClassifierRuleContext,
+ &pstPhsRule);
if (nPhsRuleIndex == PHS_INVALID_TABLE_INDEX)
return ERR_PHSRULE_MATCH_FAIL;
}
*pInHeaderSize = phs_decompress((PUCHAR)pvInputBuffer,
- (PUCHAR)pvOutputBuffer, pstPhsRule, pOutHeaderSize);
+ (PUCHAR)pvOutputBuffer,
+ pstPhsRule,
+ pOutHeaderSize);
pstPhsRule->PHSModifiedBytes += *pOutHeaderSize - *pInHeaderSize - 1;
@@ -731,7 +897,8 @@ static ULONG PhsDeCompress(IN void *pvContext,
/*
* Procedure: free_phs_serviceflow_rules
*
- * Description: This routine is responsible for freeing memory allocated for PHS rules.
+ * Description: This routine is responsible for freeing memory allocated for
+ * PHS rules.
*
* Arguments:
* rules - ptr to S_SERVICEFLOW_TABLE structure.
@@ -743,82 +910,83 @@ static void free_phs_serviceflow_rules(struct bcm_phs_table *psServiceFlowRulesT
{
int i, j;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ struct bcm_phs_classifier_entry *curr_act_rules_list;
+ struct bcm_phs_classifier_entry *curr_old_rules_list;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "=======>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "=======>\n");
- if (psServiceFlowRulesTable) {
- for (i = 0; i < MAX_SERVICEFLOWS; i++) {
- struct bcm_phs_entry stServiceFlowEntry = psServiceFlowRulesTable->stSFList[i];
- struct bcm_phs_classifier_table *pstClassifierRulesTable = stServiceFlowEntry.pstClassifierTable;
+ if (!psServiceFlowRulesTable)
+ goto out;
- if (pstClassifierRulesTable) {
- for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
- if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule) {
+ for (i = 0; i < MAX_SERVICEFLOWS; i++) {
+ struct bcm_phs_entry stServiceFlowEntry =
+ psServiceFlowRulesTable->stSFList[i];
+ struct bcm_phs_classifier_table *pstClassifierRulesTable =
+ stServiceFlowEntry.pstClassifierTable;
- if (pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
- pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt--;
+ if (pstClassifierRulesTable) {
+ for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
+ curr_act_rules_list =
+ &pstClassifierRulesTable->stActivePhsRulesList[j];
- if (0 == pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule->u8RefCnt)
- kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule);
+ curr_old_rules_list =
+ &pstClassifierRulesTable->stOldPhsRulesList[j];
- pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL;
- }
+ if (curr_act_rules_list->pstPhsRule) {
- if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) {
+ if (curr_act_rules_list->pstPhsRule->u8RefCnt)
+ curr_act_rules_list->pstPhsRule->u8RefCnt--;
- if (pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
- pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt--;
+ if (0 == curr_act_rules_list->pstPhsRule->u8RefCnt)
+ kfree(curr_act_rules_list->pstPhsRule);
- if (0 == pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule->u8RefCnt)
- kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule);
+ curr_act_rules_list->pstPhsRule = NULL;
+ }
- pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL;
- }
+ if (curr_old_rules_list->pstPhsRule) {
+
+ if (curr_old_rules_list->pstPhsRule->u8RefCnt)
+ curr_old_rules_list->pstPhsRule->u8RefCnt--;
+
+ if (0 == curr_old_rules_list->pstPhsRule->u8RefCnt)
+ kfree(curr_old_rules_list->pstPhsRule);
+
+ curr_old_rules_list->pstPhsRule = NULL;
}
- kfree(pstClassifierRulesTable);
- stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL;
}
+ kfree(pstClassifierRulesTable);
+ stServiceFlowEntry.pstClassifierTable =
+ pstClassifierRulesTable = NULL;
}
}
+out:
+
kfree(psServiceFlowRulesTable);
psServiceFlowRulesTable = NULL;
}
-static bool ValidatePHSRuleComplete(IN struct bcm_phs_rule *psPhsRule)
+static bool ValidatePHSRuleComplete(IN const struct bcm_phs_rule *psPhsRule)
{
- if (psPhsRule) {
- if (!psPhsRule->u8PHSI) {
- /* PHSI is not valid */
- return false;
- }
-
- if (!psPhsRule->u8PHSS) {
- /* PHSS Is Undefined */
- return false;
- }
-
- /* Check if PHSF is defines for the PHS Rule */
- if (!psPhsRule->u8PHSFLength) /* If any part of PHSF is valid then Rule contains valid PHSF */
- return false;
-
- return TRUE;
- } else
- return false;
+ return (psPhsRule &&
+ psPhsRule->u8PHSI &&
+ psPhsRule->u8PHSS &&
+ psPhsRule->u8PHSFLength);
}
UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
- IN B_UINT16 uiVcid,
- struct bcm_phs_entry **ppstServiceFlowEntry)
+ IN B_UINT16 uiVcid,
+ struct bcm_phs_entry **ppstServiceFlowEntry)
{
int i;
+ struct bcm_phs_entry *curr_sf_list;
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
- if (psServiceFlowTable->stSFList[i].bUsed) {
- if (psServiceFlowTable->stSFList[i].uiVcid == uiVcid) {
- *ppstServiceFlowEntry = &psServiceFlowTable->stSFList[i];
- return i;
- }
+ curr_sf_list = &psServiceFlowTable->stSFList[i];
+ if (curr_sf_list->bUsed && (curr_sf_list->uiVcid == uiVcid)) {
+ *ppstServiceFlowEntry = curr_sf_list;
+ return i;
}
}
@@ -827,8 +995,9 @@ UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
}
static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
- IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext,
- OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
+ IN B_UINT32 uiClsid,
+ enum bcm_phs_classifier_context eClsContext,
+ OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
{
int i;
struct bcm_phs_classifier_entry *psClassifierRules = NULL;
@@ -836,15 +1005,16 @@ static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifier
for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
if (eClsContext == eActiveClassifierRuleContext)
- psClassifierRules = &pstClassifierTable->stActivePhsRulesList[i];
+ psClassifierRules =
+ &pstClassifierTable->stActivePhsRulesList[i];
else
- psClassifierRules = &pstClassifierTable->stOldPhsRulesList[i];
+ psClassifierRules =
+ &pstClassifierTable->stOldPhsRulesList[i];
- if (psClassifierRules->bUsed) {
- if (psClassifierRules->uiClassifierRuleId == uiClsid) {
- *ppstClassifierEntry = psClassifierRules;
- return i;
- }
+ if (psClassifierRules->bUsed &&
+ (psClassifierRules->uiClassifierRuleId == uiClsid)) {
+ *ppstClassifierEntry = psClassifierRules;
+ return i;
}
}
@@ -853,23 +1023,25 @@ static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifier
}
static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
- IN B_UINT32 uiPHSI, enum bcm_phs_classifier_context eClsContext,
- OUT struct bcm_phs_rule **ppstPhsRule)
+ IN B_UINT32 uiPHSI,
+ enum bcm_phs_classifier_context eClsContext,
+ OUT struct bcm_phs_rule **ppstPhsRule)
{
int i;
struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
for (i = 0; i < MAX_PHSRULE_PER_SF; i++) {
if (eClsContext == eActiveClassifierRuleContext)
- pstClassifierRule = &pstClassifierTable->stActivePhsRulesList[i];
+ pstClassifierRule =
+ &pstClassifierTable->stActivePhsRulesList[i];
else
- pstClassifierRule = &pstClassifierTable->stOldPhsRulesList[i];
+ pstClassifierRule =
+ &pstClassifierTable->stOldPhsRulesList[i];
- if (pstClassifierRule->bUsed) {
- if (pstClassifierRule->u8PHSI == uiPHSI) {
- *ppstPhsRule = pstClassifierRule->pstPhsRule;
- return i;
- }
+ if (pstClassifierRule->bUsed &&
+ (pstClassifierRule->u8PHSI == uiPHSI)) {
+ *ppstPhsRule = pstClassifierRule->pstPhsRule;
+ return i;
}
}
@@ -877,19 +1049,22 @@ static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTab
return PHS_INVALID_TABLE_INDEX;
}
-static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiClsId,
- IN struct bcm_phs_table *psServiceFlowTable,
- struct bcm_phs_rule *psPhsRule,
- B_UINT8 u8AssociatedPHSI)
+static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid,
+ IN B_UINT16 uiClsId,
+ IN struct bcm_phs_table *psServiceFlowTable,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI)
{
struct bcm_phs_classifier_table *psaClassifiertable = NULL;
UINT uiStatus = 0;
int iSfIndex;
bool bFreeEntryFound = false;
+ struct bcm_phs_entry *curr_list;
/* Check for a free entry in SFID table */
for (iSfIndex = 0; iSfIndex < MAX_SERVICEFLOWS; iSfIndex++) {
- if (!psServiceFlowTable->stSFList[iSfIndex].bUsed) {
+ curr_list = &psServiceFlowTable->stSFList[iSfIndex];
+ if (!curr_list->bUsed) {
bFreeEntryFound = TRUE;
break;
}
@@ -898,23 +1073,26 @@ static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16 uiC
if (!bFreeEntryFound)
return ERR_SFTABLE_FULL;
- psaClassifiertable = psServiceFlowTable->stSFList[iSfIndex].pstClassifierTable;
- uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable, psPhsRule,
- eActiveClassifierRuleContext, u8AssociatedPHSI);
+ psaClassifiertable = curr_list->pstClassifierTable;
+ uiStatus = CreateClassifierPHSRule(uiClsId,
+ psaClassifiertable,
+ psPhsRule,
+ eActiveClassifierRuleContext,
+ u8AssociatedPHSI);
if (uiStatus == PHS_SUCCESS) {
/* Add entry at free index to the SF */
- psServiceFlowTable->stSFList[iSfIndex].bUsed = TRUE;
- psServiceFlowTable->stSFList[iSfIndex].uiVcid = uiVcid;
+ curr_list->bUsed = TRUE;
+ curr_list->uiVcid = uiVcid;
}
return uiStatus;
}
static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
- IN B_UINT16 uiClsId,
- IN struct bcm_phs_entry *pstServiceFlowEntry,
- struct bcm_phs_rule *psPhsRule,
- B_UINT8 u8AssociatedPHSI)
+ IN B_UINT16 uiClsId,
+ IN struct bcm_phs_entry *pstServiceFlowEntry,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI)
{
struct bcm_phs_classifier_entry *pstClassifierEntry = NULL;
UINT uiStatus = PHS_SUCCESS;
@@ -924,7 +1102,8 @@ static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
psaClassifiertable = pstServiceFlowEntry->pstClassifierTable;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "==>");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "==>");
/* Check if the supplied Classifier already exists */
nClassifierIndex = GetClassifierEntry(
@@ -935,14 +1114,15 @@ static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
if (nClassifierIndex == PHS_INVALID_TABLE_INDEX) {
/*
- * The Classifier doesn't exist. So its a new classifier being added.
+ * The Classifier doesn't exist. So its a new classifier being
+ * added.
* Add new entry to associate PHS Rule to the Classifier
*/
uiStatus = CreateClassifierPHSRule(uiClsId, psaClassifiertable,
- psPhsRule,
- eActiveClassifierRuleContext,
- u8AssociatedPHSI);
+ psPhsRule,
+ eActiveClassifierRuleContext,
+ u8AssociatedPHSI);
return uiStatus;
}
@@ -956,25 +1136,28 @@ static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
return ERR_PHS_INVALID_PHS_RULE;
/*
- * This rule already exists if any fields are changed for this PHS
- * rule update them.
+ * This rule already exists if any fields are changed for this
+ * PHS rule update them.
*/
/* If any part of PHSF is valid then we update PHSF */
if (psPhsRule->u8PHSFLength) {
/* update PHSF */
memcpy(pstClassifierEntry->pstPhsRule->u8PHSF,
- psPhsRule->u8PHSF, MAX_PHS_LENGTHS);
+ psPhsRule->u8PHSF,
+ MAX_PHS_LENGTHS);
}
if (psPhsRule->u8PHSFLength) {
/* update PHSFLen */
- pstClassifierEntry->pstPhsRule->u8PHSFLength = psPhsRule->u8PHSFLength;
+ pstClassifierEntry->pstPhsRule->u8PHSFLength =
+ psPhsRule->u8PHSFLength;
}
if (psPhsRule->u8PHSMLength) {
/* update PHSM */
memcpy(pstClassifierEntry->pstPhsRule->u8PHSM,
- psPhsRule->u8PHSM, MAX_PHS_LENGTHS);
+ psPhsRule->u8PHSM,
+ MAX_PHS_LENGTHS);
}
if (psPhsRule->u8PHSMLength) {
@@ -985,25 +1168,29 @@ static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
if (psPhsRule->u8PHSS) {
/* update PHSS */
- pstClassifierEntry->pstPhsRule->u8PHSS = psPhsRule->u8PHSS;
+ pstClassifierEntry->pstPhsRule->u8PHSS =
+ psPhsRule->u8PHSS;
}
/* update PHSV */
pstClassifierEntry->pstPhsRule->u8PHSV = psPhsRule->u8PHSV;
} else {
/* A new rule is being set for this classifier. */
- uiStatus = UpdateClassifierPHSRule(uiClsId, pstClassifierEntry,
- psaClassifiertable, psPhsRule, u8AssociatedPHSI);
+ uiStatus = UpdateClassifierPHSRule(uiClsId,
+ pstClassifierEntry,
+ psaClassifiertable,
+ psPhsRule,
+ u8AssociatedPHSI);
}
return uiStatus;
}
static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
- struct bcm_phs_classifier_table *psaClassifiertable,
- struct bcm_phs_rule *psPhsRule,
- enum bcm_phs_classifier_context eClsContext,
- B_UINT8 u8AssociatedPHSI)
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *psPhsRule,
+ enum bcm_phs_classifier_context eClsContext,
+ B_UINT8 u8AssociatedPHSI)
{
UINT iClassifierIndex = 0;
bool bFreeEntryFound = false;
@@ -1011,7 +1198,8 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
UINT nStatus = PHS_SUCCESS;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "Inside CreateClassifierPHSRule");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL,
+ "Inside CreateClassifierPHSRule");
if (psaClassifiertable == NULL)
return ERR_INVALID_CLASSIFIERTABLE_FOR_SF;
@@ -1022,9 +1210,10 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
* old rules table replace it.
*/
- iClassifierIndex =
- GetClassifierEntry(psaClassifiertable, uiClsId,
- eClsContext, &psClassifierRules);
+ iClassifierIndex = GetClassifierEntry(psaClassifiertable,
+ uiClsId,
+ eClsContext,
+ &psClassifierRules);
if (iClassifierIndex != PHS_INVALID_TABLE_INDEX) {
/*
@@ -1056,12 +1245,15 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
if (eClsContext == eActiveClassifierRuleContext)
return ERR_CLSASSIFIER_TABLE_FULL;
else {
- /* Lets replace the oldest rule if we are looking in old Rule table */
+ /* Lets replace the oldest rule if we are looking in
+ * old Rule table */
if (psaClassifiertable->uiOldestPhsRuleIndex >= MAX_PHSRULE_PER_SF)
psaClassifiertable->uiOldestPhsRuleIndex = 0;
- iClassifierIndex = psaClassifiertable->uiOldestPhsRuleIndex;
- psClassifierRules = &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
+ iClassifierIndex =
+ psaClassifiertable->uiOldestPhsRuleIndex;
+ psClassifierRules =
+ &psaClassifiertable->stOldPhsRulesList[iClassifierIndex];
(psaClassifiertable->uiOldestPhsRuleIndex)++;
}
@@ -1071,7 +1263,9 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
if (psClassifierRules->pstPhsRule == NULL) {
- psClassifierRules->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
+ psClassifierRules->pstPhsRule =
+ kmalloc(sizeof(struct bcm_phs_rule),
+ GFP_KERNEL);
if (NULL == psClassifierRules->pstPhsRule)
return ERR_PHSRULE_MEMALLOC_FAIL;
@@ -1080,22 +1274,27 @@ static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId,
psClassifierRules->bUsed = TRUE;
psClassifierRules->uiClassifierRuleId = uiClsId;
psClassifierRules->u8PHSI = psPhsRule->u8PHSI;
- psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule;
+ psClassifierRules->bUnclassifiedPHSRule =
+ psPhsRule->bUnclassifiedPHSRule;
/* Update The PHS rule */
- memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
+ memcpy(psClassifierRules->pstPhsRule, psPhsRule,
+ sizeof(struct bcm_phs_rule));
} else
- nStatus = UpdateClassifierPHSRule(uiClsId, psClassifierRules,
- psaClassifiertable, psPhsRule, u8AssociatedPHSI);
+ nStatus = UpdateClassifierPHSRule(uiClsId,
+ psClassifierRules,
+ psaClassifiertable,
+ psPhsRule,
+ u8AssociatedPHSI);
return nStatus;
}
static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
- IN struct bcm_phs_classifier_entry *pstClassifierEntry,
- struct bcm_phs_classifier_table *psaClassifiertable,
- struct bcm_phs_rule *psPhsRule,
- B_UINT8 u8AssociatedPHSI)
+ IN struct bcm_phs_classifier_entry *pstClassifierEntry,
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI)
{
struct bcm_phs_rule *pstAddPhsRule = NULL;
UINT nPhsRuleIndex = 0;
@@ -1108,29 +1307,41 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
bPHSRuleOrphaned = DerefPhsRule(uiClsId, psaClassifiertable,
pstClassifierEntry->pstPhsRule);
- /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in Classifier table for this SF */
+ /* Step 2 Search if there is a PHS Rule with u8AssociatedPHSI in
+ * Classifier table for this SF */
nPhsRuleIndex = GetPhsRuleEntry(psaClassifiertable, u8AssociatedPHSI,
- eActiveClassifierRuleContext, &pstAddPhsRule);
+ eActiveClassifierRuleContext,
+ &pstAddPhsRule);
if (PHS_INVALID_TABLE_INDEX == nPhsRuleIndex) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAdding New PHSRuleEntry For Classifier");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL,
+ "\nAdding New PHSRuleEntry For Classifier");
if (psPhsRule->u8PHSI == 0) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nError PHSI is Zero\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL, "\nError PHSI is Zero\n");
return ERR_PHS_INVALID_PHS_RULE;
}
- /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId */
+ /* Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for
+ * uiClsId */
if (false == bPHSRuleOrphaned) {
- pstClassifierEntry->pstPhsRule = kmalloc(sizeof(struct bcm_phs_rule), GFP_KERNEL);
+ pstClassifierEntry->pstPhsRule =
+ kmalloc(sizeof(struct bcm_phs_rule),
+ GFP_KERNEL);
if (NULL == pstClassifierEntry->pstPhsRule)
return ERR_PHSRULE_MEMALLOC_FAIL;
}
- memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(struct bcm_phs_rule));
+ memcpy(pstClassifierEntry->pstPhsRule, psPhsRule,
+ sizeof(struct bcm_phs_rule));
} else {
- /* Step 2.b PHS Rule Exists Tie uiClsId with the existing PHS Rule */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule");
+ /* Step 2.b PHS Rule Exists Tie uiClsId with the existing
+ * PHS Rule */
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_DISPATCH,
+ DBG_LVL_ALL,
+ "\nTying Classifier to Existing PHS Rule");
if (bPHSRuleOrphaned) {
kfree(pstClassifierEntry->pstPhsRule);
pstClassifierEntry->pstPhsRule = NULL;
@@ -1142,12 +1353,15 @@ static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId,
pstClassifierEntry->u8PHSI = pstClassifierEntry->pstPhsRule->u8PHSI;
pstClassifierEntry->uiClassifierRuleId = uiClsId;
pstClassifierEntry->pstPhsRule->u8RefCnt++;
- pstClassifierEntry->bUnclassifiedPHSRule = pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
+ pstClassifierEntry->bUnclassifiedPHSRule =
+ pstClassifierEntry->pstPhsRule->bUnclassifiedPHSRule;
return PHS_SUCCESS;
}
-static bool DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_table *psaClassifiertable, struct bcm_phs_rule *pstPhsRule)
+static bool DerefPhsRule(IN B_UINT16 uiClsId,
+ struct bcm_phs_classifier_table *psaClassifiertable,
+ struct bcm_phs_rule *pstPhsRule)
{
if (pstPhsRule == NULL)
return false;
@@ -1155,68 +1369,89 @@ static bool DerefPhsRule(IN B_UINT16 uiClsId, struct bcm_phs_classifier_table *
if (pstPhsRule->u8RefCnt)
pstPhsRule->u8RefCnt--;
- if (0 == pstPhsRule->u8RefCnt) {
- /*
- * if(pstPhsRule->u8PHSI)
- * Store the currently active rule into the old rules list
- * CreateClassifierPHSRule(uiClsId,psaClassifiertable,pstPhsRule,eOldClassifierRuleContext,pstPhsRule->u8PHSI);
- */
- return TRUE;
- } else
- return false;
+ return (0 == pstPhsRule->u8RefCnt);
+}
+
+static void dbg_print_st_cls_entry(struct bcm_mini_adapter *ad,
+ struct bcm_phs_entry *st_serv_flow_entry,
+ struct bcm_phs_classifier_entry *st_cls_entry)
+{
+ int k;
+
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", st_serv_flow_entry->uiVcid);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", st_cls_entry->uiClassifierRuleId);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", st_cls_entry->u8PHSI);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", st_cls_entry->pstPhsRule->u8PHSI);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", st_cls_entry->pstPhsRule->u8PHSFLength);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
+
+ for (k = 0 ; k < st_cls_entry->pstPhsRule->u8PHSFLength; k++)
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSF[k]);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", st_cls_entry->pstPhsRule->u8PHSMLength);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
+
+ for (k = 0; k < st_cls_entry->pstPhsRule->u8PHSMLength; k++)
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", st_cls_entry->pstPhsRule->u8PHSM[k]);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", st_cls_entry->pstPhsRule->u8PHSS);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", st_cls_entry->pstPhsRule->u8PHSV);
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
+}
+
+static void phsrules_per_sf_dbg_print(struct bcm_mini_adapter *ad,
+ struct bcm_phs_entry *st_serv_flow_entry)
+{
+ int j, l;
+ struct bcm_phs_classifier_entry st_cls_entry;
+
+ for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
+
+ for (l = 0; l < 2; l++) {
+
+ if (l == 0) {
+ st_cls_entry = st_serv_flow_entry->pstClassifierTable->stActivePhsRulesList[j];
+ if (st_cls_entry.bUsed)
+ BCM_DEBUG_PRINT(ad,
+ DBG_TYPE_OTHERS,
+ DUMP_INFO,
+ (DBG_LVL_ALL | DBG_NO_FUNC_PRINT),
+ "\n Active PHS Rule :\n");
+ } else {
+ st_cls_entry = st_serv_flow_entry->pstClassifierTable->stOldPhsRulesList[j];
+ if (st_cls_entry.bUsed)
+ BCM_DEBUG_PRINT(ad,
+ DBG_TYPE_OTHERS,
+ DUMP_INFO,
+ (DBG_LVL_ALL | DBG_NO_FUNC_PRINT),
+ "\n Old PHS Rule :\n");
+ }
+
+ if (st_cls_entry.bUsed) {
+ dbg_print_st_cls_entry(ad,
+ st_serv_flow_entry,
+ &st_cls_entry);
+ }
+ }
+ }
}
void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
{
- int i, j, k, l;
+ int i;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n Dumping PHS Rules :\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL,
+ "\n Dumping PHS Rules :\n");
for (i = 0; i < MAX_SERVICEFLOWS; i++) {
struct bcm_phs_entry stServFlowEntry =
pDeviceExtension->pstServiceFlowPhsRulesTable->stSFList[i];
- if (stServFlowEntry.bUsed) {
- for (j = 0; j < MAX_PHSRULE_PER_SF; j++) {
+ if (!stServFlowEntry.bUsed)
+ continue;
- for (l = 0; l < 2; l++) {
- struct bcm_phs_classifier_entry stClsEntry;
-
- if (l == 0) {
- stClsEntry = stServFlowEntry.pstClassifierTable->stActivePhsRulesList[j];
- if (stClsEntry.bUsed)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Active PHS Rule :\n");
- } else {
- stClsEntry = stServFlowEntry.pstClassifierTable->stOldPhsRulesList[j];
- if (stClsEntry.bUsed)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n Old PHS Rule :\n");
- }
-
- if (stClsEntry.bUsed) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n VCID : %#X", stServFlowEntry.uiVcid);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n ClassifierID : %#X", stClsEntry.uiClassifierRuleId);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSRuleID : %#X", stClsEntry.u8PHSI);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n****************PHS Rule********************\n");
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSI : %#X", stClsEntry.pstPhsRule->u8PHSI);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSFLength : %#X ", stClsEntry.pstPhsRule->u8PHSFLength);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSF : ");
-
- for (k = 0 ; k < stClsEntry.pstPhsRule->u8PHSFLength; k++)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSF[k]);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSMLength : %#X", stClsEntry.pstPhsRule->u8PHSMLength);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSM :");
-
- for (k = 0; k < stClsEntry.pstPhsRule->u8PHSMLength; k++)
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "%#X ", stClsEntry.pstPhsRule->u8PHSM[k]);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSS : %#X ", stClsEntry.pstPhsRule->u8PHSS);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, (DBG_LVL_ALL|DBG_NO_FUNC_PRINT), "\n PHSV : %#X", stClsEntry.pstPhsRule->u8PHSV);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "\n********************************************\n");
- }
- }
- }
- }
+ phsrules_per_sf_dbg_print(Adapter, &stServFlowEntry);
}
}
@@ -1227,19 +1462,22 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
*
* Arguments:
* in_buf - ptr to incoming packet buffer.
- * out_buf - ptr to output buffer where the suppressed header is copied.
- * decomp_phs_rules - ptr to PHS rule.
- * header_size - ptr to field which holds the phss or phsf_length.
+ * out_buf - ptr to output buffer where the suppressed
+ * header is copied.
+ * decomp_phs_rules - ptr to PHS rule.
+ * header_size - ptr to field which holds the phss or
+ * phsf_length.
*
* Returns:
- * size -The number of bytes of dynamic fields present with in the incoming packet
- * header.
- * 0 -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
+ * size - The number of bytes of dynamic fields present with in the
+ * incoming packet header.
+ * 0 - If PHS rule is NULL.If PHSI is 0 indicateing packet as
+ * uncompressed.
*/
static int phs_decompress(unsigned char *in_buf,
- unsigned char *out_buf,
- struct bcm_phs_rule *decomp_phs_rules,
- UINT *header_size)
+ unsigned char *out_buf,
+ struct bcm_phs_rule *decomp_phs_rules,
+ UINT *header_size)
{
int phss, size = 0;
struct bcm_phs_rule *tmp_memb;
@@ -1250,15 +1488,17 @@ static int phs_decompress(unsigned char *in_buf,
in_buf++;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "====>\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL,
+ "====>\n");
*header_size = 0;
- if ((decomp_phs_rules == NULL))
+ if (decomp_phs_rules == NULL)
return 0;
tmp_memb = decomp_phs_rules;
/*
- * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
+ * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
+ * "\nDECOMP:In phs_decompress PHSI 1 %d",phsi));
* header_size = tmp_memb->u8PHSFLength;
*/
phss = tmp_memb->u8PHSS;
@@ -1269,7 +1509,8 @@ static int phs_decompress(unsigned char *in_buf,
phss = MAX_PHS_LENGTHS;
/*
- * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:
+ * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,
+ * "\nDECOMP:
* In phs_decompress PHSI %d phss %d index %d",phsi,phss,index));
*/
while ((phss > 0) && (size < in_buf_len)) {
@@ -1277,11 +1518,15 @@ static int phs_decompress(unsigned char *in_buf,
if (bit == SUPPRESS) {
*out_buf = *phsf;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d phsf %d output %d",
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
+ DBG_LVL_ALL,
+ "\nDECOMP:In phss %d phsf %d output %d",
phss, *phsf, *out_buf);
} else {
*out_buf = *in_buf;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d input %d output %d",
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE,
+ DBG_LVL_ALL,
+ "\nDECOMP:In phss %d input %d output %d",
phss, *in_buf, *out_buf);
in_buf++;
size++;
@@ -1304,22 +1549,25 @@ static int phs_decompress(unsigned char *in_buf,
/*
* Procedure: phs_compress
*
- * Description: This routine suppresses the static fields within the packet.Before
- * that it will verify the fields to be suppressed with the corresponding fields in the
- * phsf. For verification it checks the phsv field of PHS rule. If set and verification
- * succeeds it suppresses the field.If any one static field is found different none of
- * the static fields are suppressed then the packet is sent as uncompressed packet with
- * phsi=0.
+ * Description: This routine suppresses the static fields within the packet.
+ * Before that it will verify the fields to be suppressed with the corresponding
+ * fields in the phsf. For verification it checks the phsv field of PHS rule.
+ * If set and verification succeeds it suppresses the field.If any one static
+ * field is found different none of the static fields are suppressed then the
+ * packet is sent as uncompressed packet with phsi=0.
*
* Arguments:
* phs_rule - ptr to PHS rule.
* in_buf - ptr to incoming packet buffer.
- * out_buf - ptr to output buffer where the suppressed header is copied.
+ * out_buf - ptr to output buffer where the suppressed header is
+ * copied.
* header_size - ptr to field which holds the phss.
*
* Returns:
- * size-The number of bytes copied into the output buffer i.e dynamic fields
- * 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails.
+ * size - The number of bytes copied into the output buffer i.e
+ * dynamic fields
+ * 0 - If PHS rule is NULL.If PHSV field is not set. If the
+ * verification fails.
*/
static int phs_compress(struct bcm_phs_rule *phs_rule,
unsigned char *in_buf,
@@ -1332,7 +1580,8 @@ static int phs_compress(struct bcm_phs_rule *phs_rule,
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
if (phs_rule == NULL) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nphs_compress(): phs_rule null!");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "\nphs_compress(): phs_rule null!");
*out_buf = ZERO_PHSI;
return STATUS_PHS_NOCOMPRESSION;
}
@@ -1350,10 +1599,13 @@ static int phs_compress(struct bcm_phs_rule *phs_rule,
if (suppress == STATUS_PHS_COMPRESSED) {
*old_addr = (unsigned char)phs_rule->u8PHSI;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress phsi %d", phs_rule->u8PHSI);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "\nCOMP:In phs_compress phsi %d",
+ phs_rule->u8PHSI);
} else {
*old_addr = ZERO_PHSI;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In phs_compress PHSV Verification failed");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "\nCOMP:In phs_compress PHSV Verification failed");
}
return suppress;
@@ -1370,13 +1622,14 @@ static int phs_compress(struct bcm_phs_rule *phs_rule,
* rules_set - ptr to classifier_rules.
* in_buffer - ptr to incoming packet buffer.
* out_buffer - ptr to output buffer where the suppressed header is copied.
- * phsf - ptr to phsf.
- * phsm - ptr to phsm.
- * phss - variable holding phss.
+ * phsf - ptr to phsf.
+ * phsm - ptr to phsm.
+ * phss - variable holding phss.
*
* Returns:
- * size-The number of bytes copied into the output buffer i.e dynamic fields.
- * 0 -Packet has failed the verification.
+ * size - The number of bytes copied into the output buffer i.e dynamic
+ * fields.
+ * 0 - Packet has failed the verification.
*/
static int verify_suppress_phsf(unsigned char *in_buffer,
unsigned char *out_buffer,
@@ -1390,7 +1643,8 @@ static int verify_suppress_phsf(unsigned char *in_buffer,
int bit, i = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "\nCOMP:In verify_phsf PHSM - 0x%X", *phsm);
if (phss > (*new_header_size))
phss = *new_header_size;
@@ -1442,7 +1696,8 @@ static int verify_suppress_phsf(unsigned char *in_buffer,
phsm++;
}
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL, "\nCOMP:In verify_phsf success");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,
+ "\nCOMP:In verify_phsf success");
*new_header_size = size;
return STATUS_PHS_COMPRESSED;
}
diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h
index d697f9c860cf..d84d60ba48f9 100644
--- a/drivers/staging/bcm/PHSModule.h
+++ b/drivers/staging/bcm/PHSModule.h
@@ -20,28 +20,37 @@ int PHSReceive(struct bcm_mini_adapter *Adapter,
void DumpDataPacketHeader(PUCHAR pPkt);
-void DumpFullPacket(UCHAR *pBuf,UINT nPktLen);
+void DumpFullPacket(UCHAR *pBuf, UINT nPktLen);
void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension);
-int phs_init(struct bcm_phs_extension *pPhsdeviceExtension,struct bcm_mini_adapter *Adapter);
+int phs_init(struct bcm_phs_extension *pPhsdeviceExtension,
+ struct bcm_mini_adapter *Adapter);
int PhsCleanup(struct bcm_phs_extension *pPHSDeviceExt);
-//Utility Functions
-ULONG PhsUpdateClassifierRule(void* pvContext,B_UINT16 uiVcid,B_UINT16 uiClsId, struct bcm_phs_rule *psPhsRule,B_UINT8 u8AssociatedPHSI );
+/* Utility Functions */
+ULONG PhsUpdateClassifierRule(void *pvContext,
+ B_UINT16 uiVcid,
+ B_UINT16 uiClsId,
+ struct bcm_phs_rule *psPhsRule,
+ B_UINT8 u8AssociatedPHSI);
-ULONG PhsDeletePHSRule(void* pvContext,B_UINT16 uiVcid,B_UINT8 u8PHSI);
+ULONG PhsDeletePHSRule(void *pvContext, B_UINT16 uiVcid, B_UINT8 u8PHSI);
-ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsId);
+ULONG PhsDeleteClassifierRule(void *pvContext,
+ B_UINT16 uiVcid,
+ B_UINT16 uiClsId);
-ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ;
+ULONG PhsDeleteSFRules(void *pvContext, B_UINT16 uiVcid);
bool ValidatePHSRule(struct bcm_phs_rule *psPhsRule);
-UINT GetServiceFlowEntry(struct bcm_phs_table *psServiceFlowTable,B_UINT16 uiVcid, struct bcm_phs_entry **ppstServiceFlowEntry);
+UINT GetServiceFlowEntry(struct bcm_phs_table *psServiceFlowTable,
+ B_UINT16 uiVcid,
+ struct bcm_phs_entry **ppstServiceFlowEntry);
void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension);
diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h
index fb53a00591eb..1ddc8b2539f6 100644
--- a/drivers/staging/bcm/Prototypes.h
+++ b/drivers/staging/bcm/Prototypes.h
@@ -3,13 +3,13 @@
VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer);
-VOID StatisticsResponse(struct bcm_mini_adapter *Adapter,PVOID pvBuffer);
+VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer);
-VOID IdleModeResponse(struct bcm_mini_adapter *Adapter,PUINT puiBuffer);
+VOID IdleModeResponse(struct bcm_mini_adapter *Adapter, PUINT puiBuffer);
-int control_packet_handler (struct bcm_mini_adapter *Adapter);
+int control_packet_handler(struct bcm_mini_adapter *Adapter);
-VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter,UINT uiSearchRuleIndex);
+VOID DeleteAllClassifiersForSF(struct bcm_mini_adapter *Adapter, UINT uiSearchRuleIndex);
VOID flush_all_queues(struct bcm_mini_adapter *Adapter);
@@ -29,18 +29,19 @@ VOID flush_all_queues(struct bcm_mini_adapter *Adapter);
VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter);
-INT SearchSfid(struct bcm_mini_adapter *Adapter,UINT uiSfid);
+INT SearchSfid(struct bcm_mini_adapter *Adapter, UINT uiSfid);
-USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter,struct sk_buff* skb);
+USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb);
-bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrcPort);
-bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,USHORT ushSrcPort);
-bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,UCHAR ucProtocol);
+bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPort);
+bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPort);
+
+bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucProtocol);
INT SetupNextSend(struct bcm_mini_adapter *Adapter, /**<Logical Adapter*/
struct sk_buff *Packet, /**<data buffer*/
- USHORT Vcid) ;
+ USHORT Vcid);
VOID LinkMessage(struct bcm_mini_adapter *Adapter);
@@ -50,8 +51,8 @@ INT SendControlPacket(struct bcm_mini_adapter *Adapter, /**<Logical Adapter*/
char *pControlPacket/**<Control Packet*/
);
-
int register_networkdev(struct bcm_mini_adapter *Adapter);
+
void unregister_networkdev(struct bcm_mini_adapter *Adapter);
INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
@@ -62,13 +63,12 @@ INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter);
int tx_pkt_handler(struct bcm_mini_adapter *Adapter);
-int reset_card_proc(struct bcm_mini_adapter *Adapter );
+int reset_card_proc(struct bcm_mini_adapter *Adapter);
-int run_card_proc(struct bcm_mini_adapter *Adapter );
+int run_card_proc(struct bcm_mini_adapter *Adapter);
int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter);
-
INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter);
int register_control_device_interface(struct bcm_mini_adapter *ps_adapter);
@@ -79,17 +79,18 @@ int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t
int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
-int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
+int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
-int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
+int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
-int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user * user_buffer);
+int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user *user_buffer);
void SendIdleModeResponse(struct bcm_mini_adapter *Adapter);
+int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *buf);
-int ProcessGetHostMibs(struct bcm_mini_adapter *Adapter, struct bcm_host_stats_mibs *buf);
void GetDroppedAppCntrlPktMibs(struct bcm_host_stats_mibs *ioBuffer, struct bcm_tarang_data *pTarang);
+
void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter);
int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo);
@@ -101,38 +102,32 @@ VOID ResetCounters(struct bcm_mini_adapter *Adapter);
int InitLedSettings(struct bcm_mini_adapter *Adapter);
-struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter,USHORT usIpIdentification,ULONG SrcIP);
+struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP);
void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo);
-void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter,USHORT usIpIdentification,ULONG SrcIp);
-
-void update_per_cid_rx (struct bcm_mini_adapter *Adapter);
+void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp);
-void update_per_sf_desc_cnts( struct bcm_mini_adapter *Adapter);
+void update_per_cid_rx(struct bcm_mini_adapter *Adapter);
-void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter,B_UINT16 TID,bool bFreeAll);
+void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter);
+void ClearTargetDSXBuffer(struct bcm_mini_adapter *Adapter, B_UINT16 TID, bool bFreeAll);
void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex);
-
INT flushAllAppQ(VOID);
-
INT BeceemEEPROMBulkRead(
struct bcm_mini_adapter *Adapter,
PUINT pBuffer,
UINT uiOffset,
UINT uiNumBytes);
-
-
-INT WriteBeceemEEPROM(struct bcm_mini_adapter *Adapter,UINT uiEEPROMOffset, UINT uiData);
+INT WriteBeceemEEPROM(struct bcm_mini_adapter *Adapter, UINT uiEEPROMOffset, UINT uiData);
INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter);
-
INT BeceemEEPROMBulkWrite(
struct bcm_mini_adapter *Adapter,
PUCHAR pBuffer,
@@ -140,9 +135,7 @@ INT BeceemEEPROMBulkWrite(
UINT uiNumBytes,
bool bVerify);
-
-INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,UINT dwAddress, UINT *pdwData);
-
+INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData);
INT BeceemNVMRead(
struct bcm_mini_adapter *Adapter,
@@ -157,10 +150,10 @@ INT BeceemNVMWrite(
UINT uiNumBytes,
bool bVerify);
-
INT BcmInitNVM(struct bcm_mini_adapter *Adapter);
-INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter,UINT uiSectorSize);
+INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize);
+
bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap);
@@ -183,40 +176,42 @@ INT BcmFlash2xBulkRead(
INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal);
+
INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
+
INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter);
INT BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut);
+
INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
+
INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal);
-INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite);
+
+INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite);
+
INT IsFlash2x(struct bcm_mini_adapter *Adapter);
-INT BcmCopySection(struct bcm_mini_adapter *Adapter,
+
+INT BcmCopySection(struct bcm_mini_adapter *Adapter,
enum bcm_flash2x_section_val SrcSection,
enum bcm_flash2x_section_val DstSection,
UINT offset,
UINT numOfBytes);
-
bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter);
+VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer);
-VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter,PUINT puiBuffer);
+int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
-int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
-int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
+int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize);
int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size);
+
INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
unsigned long u32StartingAddress);
-
VOID putUsbSuspend(struct work_struct *work);
-bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios);
+bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios);
#endif
-
-
-
-
diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c
index 0c742da8c6b5..b3ac614cd35f 100644
--- a/drivers/staging/bcm/Qos.c
+++ b/drivers/staging/bcm/Qos.c
@@ -1,6 +1,6 @@
/**
-@file Qos.C
-This file contains the routines related to Quality of Service.
+ * @file Qos.C
+ * This file contains the routines related to Quality of Service.
*/
#include "headers.h"
@@ -31,22 +31,40 @@ static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex);
*
* Returns - TRUE(If address matches) else FAIL .
*********************************************************************/
-static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSrcIP)
+static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule,
+ ULONG ulSrcIP)
{
UCHAR ucLoopIndex = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ union u_ip_address *src_addr;
ulSrcIP = ntohl(ulSrcIP);
if (0 == pstClassifierRule->ucIPSourceAddressLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength); ucLoopIndex++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x", (UINT)pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)ulSrcIP, (UINT)pstClassifierRule->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]);
- if ((pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
- (pstClassifierRule->stSrcIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]))
+ for (ucLoopIndex = 0;
+ ucLoopIndex < (pstClassifierRule->ucIPSourceAddressLength);
+ ucLoopIndex++) {
+ src_addr = &pstClassifierRule->stSrcIpAddress;
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Src Ip Address Mask:0x%x PacketIp:0x%x and Classification:0x%x",
+ (UINT)src_addr->ulIpv4Mask[ucLoopIndex],
+ (UINT)ulSrcIP,
+ (UINT)src_addr->ulIpv6Addr[ucLoopIndex]);
+
+ if ((src_addr->ulIpv4Mask[ucLoopIndex] & ulSrcIP) ==
+ (src_addr->ulIpv4Addr[ucLoopIndex] &
+ src_addr->ulIpv4Mask[ucLoopIndex]))
return TRUE;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Ip Address Not Matched");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Src Ip Address Not Matched");
return false;
}
@@ -66,18 +84,33 @@ static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, UL
{
UCHAR ucLoopIndex = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ union u_ip_address *dest_addr = &pstClassifierRule->stDestIpAddress;
ulDestIP = ntohl(ulDestIP);
if (0 == pstClassifierRule->ucIPDestinationAddressLength)
return TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address 0x%x 0x%x 0x%x ", (UINT)ulDestIP, (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex], (UINT)pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex]);
-
- for (ucLoopIndex = 0; ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength); ucLoopIndex++) {
- if ((pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
- (pstClassifierRule->stDestIpAddress.ulIpv4Addr[ucLoopIndex] & pstClassifierRule->stDestIpAddress.ulIpv4Mask[ucLoopIndex]))
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Destination Ip Address 0x%x 0x%x 0x%x ",
+ (UINT)ulDestIP,
+ (UINT)dest_addr->ulIpv4Mask[ucLoopIndex],
+ (UINT)dest_addr->ulIpv4Addr[ucLoopIndex]);
+
+ for (ucLoopIndex = 0;
+ ucLoopIndex < (pstClassifierRule->ucIPDestinationAddressLength);
+ ucLoopIndex++) {
+ if ((dest_addr->ulIpv4Mask[ucLoopIndex] & ulDestIP) ==
+ (dest_addr->ulIpv4Addr[ucLoopIndex] &
+ dest_addr->ulIpv4Mask[ucLoopIndex]))
return TRUE;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Ip Address Not Matched");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Destination Ip Address Not Matched");
return false;
}
@@ -92,17 +125,25 @@ static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, UL
*
* Returns - TRUE(If address matches) else FAIL.
**************************************************************************/
-static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfService)
+static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule,
+ UCHAR ucTypeOfService)
{
-
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
if (3 != pstClassifierRule->ucIPTypeOfServiceLength)
return TRUE;
- if (((pstClassifierRule->ucTosMask & ucTypeOfService) <= pstClassifierRule->ucTosHigh) && ((pstClassifierRule->ucTosMask & ucTypeOfService) >= pstClassifierRule->ucTosLow))
+ if (((pstClassifierRule->ucTosMask & ucTypeOfService) <=
+ pstClassifierRule->ucTosHigh) &&
+ ((pstClassifierRule->ucTosMask & ucTypeOfService) >=
+ pstClassifierRule->ucTosLow))
return TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Type Of Service Not Matched");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Type Of Service Not Matched");
return false;
}
@@ -117,18 +158,32 @@ static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucType
*
* Returns - TRUE(If address matches) else FAIL.
****************************************************************************/
-bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucProtocol)
+bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule,
+ UCHAR ucProtocol)
{
UCHAR ucLoopIndex = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
if (0 == pstClassifierRule->ucProtocolLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucProtocolLength; ucLoopIndex++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol:0x%X Classification Protocol:0x%X", ucProtocol, pstClassifierRule->ucProtocol[ucLoopIndex]);
+ for (ucLoopIndex = 0;
+ ucLoopIndex < pstClassifierRule->ucProtocolLength;
+ ucLoopIndex++) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Protocol:0x%X Classification Protocol:0x%X",
+ ucProtocol,
+ pstClassifierRule->ucProtocol[ucLoopIndex]);
if (pstClassifierRule->ucProtocol[ucLoopIndex] == ucProtocol)
return TRUE;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Not Matched");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Protocol Not Matched");
return false;
}
@@ -143,7 +198,8 @@ bool MatchProtocol(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucProtoc
*
* Returns - TRUE(If address matches) else FAIL.
***************************************************************************/
-bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPort)
+bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule,
+ USHORT ushSrcPort)
{
UCHAR ucLoopIndex = 0;
@@ -152,12 +208,19 @@ bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPo
if (0 == pstClassifierRule->ucSrcPortRangeLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength; ucLoopIndex++) {
+ for (ucLoopIndex = 0;
+ ucLoopIndex < pstClassifierRule->ucSrcPortRangeLength;
+ ucLoopIndex++) {
if (ushSrcPort <= pstClassifierRule->usSrcPortRangeHi[ucLoopIndex] &&
ushSrcPort >= pstClassifierRule->usSrcPortRangeLo[ucLoopIndex])
return TRUE;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port: %x Not Matched ", ushSrcPort);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Src Port: %x Not Matched ",
+ ushSrcPort);
return false;
}
@@ -172,7 +235,8 @@ bool MatchSrcPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushSrcPo
*
* Returns - TRUE(If address matches) else FAIL.
***************************************************************************/
-bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushDestPort)
+bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule,
+ USHORT ushDestPort)
{
UCHAR ucLoopIndex = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
@@ -180,20 +244,34 @@ bool MatchDestPort(struct bcm_classifier_rule *pstClassifierRule, USHORT ushDest
if (0 == pstClassifierRule->ucDestPortRangeLength)
return TRUE;
- for (ucLoopIndex = 0; ucLoopIndex < pstClassifierRule->ucDestPortRangeLength; ucLoopIndex++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Matching Port:0x%X 0x%X 0x%X", ushDestPort, pstClassifierRule->usDestPortRangeLo[ucLoopIndex], pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
+ for (ucLoopIndex = 0;
+ ucLoopIndex < pstClassifierRule->ucDestPortRangeLength;
+ ucLoopIndex++) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Matching Port:0x%X 0x%X 0x%X",
+ ushDestPort,
+ pstClassifierRule->usDestPortRangeLo[ucLoopIndex],
+ pstClassifierRule->usDestPortRangeHi[ucLoopIndex]);
if (ushDestPort <= pstClassifierRule->usDestPortRangeHi[ucLoopIndex] &&
ushDestPort >= pstClassifierRule->usDestPortRangeLo[ucLoopIndex])
return TRUE;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dest Port: %x Not Matched", ushDestPort);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Dest Port: %x Not Matched",
+ ushDestPort);
return false;
}
/**
-@ingroup tx_functions
-Compares IPV4 Ip address and port number
-@return Queue Index.
+ * @ingroup tx_functions
+ * Compares IPV4 Ip address and port number
+ * @return Queue Index.
*/
static USHORT IpVersion4(struct bcm_mini_adapter *Adapter,
struct iphdr *iphd,
@@ -202,78 +280,136 @@ static USHORT IpVersion4(struct bcm_mini_adapter *Adapter,
struct bcm_transport_header *xprt_hdr = NULL;
bool bClassificationSucceed = false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "========>");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "========>");
xprt_hdr = (struct bcm_transport_header *)((PUCHAR)iphd + sizeof(struct iphdr));
- do {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to see Direction = %d %d",
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Trying to see Direction = %d %d",
pstClassifierRule->ucDirection,
pstClassifierRule->usVCID_Value);
- //Checking classifier validity
- if (!pstClassifierRule->bUsed || pstClassifierRule->ucDirection == DOWNLINK_DIR)
- break;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "is IPv6 check!");
- if (pstClassifierRule->bIpv6Protocol)
- break;
-
- //**************Checking IP header parameter**************************//
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Trying to match Source IP Address");
- if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source IP Address Matched");
-
- if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination IP Address Matched");
-
- if (!MatchTos(pstClassifierRule, iphd->tos)) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Match failed\n");
- break;
- }
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "TOS Matched");
-
- if (!MatchProtocol(pstClassifierRule, iphd->protocol))
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Protocol Matched");
-
- //if protocol is not TCP or UDP then no need of comparing source port and destination port
- if (iphd->protocol != TCP && iphd->protocol != UDP) {
- bClassificationSucceed = TRUE;
- break;
- }
- //******************Checking Transport Layer Header field if present *****************//
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x",
+ /* Checking classifier validity */
+ if (!pstClassifierRule->bUsed ||
+ pstClassifierRule->ucDirection == DOWNLINK_DIR)
+ goto out;
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "is IPv6 check!");
+ if (pstClassifierRule->bIpv6Protocol)
+ goto out;
+
+ /* Checking IP header parameter */
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Trying to match Source IP Address");
+ if (!MatchSrcIpAddress(pstClassifierRule, iphd->saddr))
+ goto out;
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Source IP Address Matched");
+
+ if (!MatchDestIpAddress(pstClassifierRule, iphd->daddr))
+ goto out;
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Destination IP Address Matched");
+
+ if (!MatchTos(pstClassifierRule, iphd->tos)) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "TOS Match failed\n");
+ goto out;
+ }
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "TOS Matched");
+
+ if (!MatchProtocol(pstClassifierRule, iphd->protocol))
+ goto out;
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Protocol Matched");
+
+ /*
+ * if protocol is not TCP or UDP then no
+ * need of comparing source port and destination port
+ */
+ if (iphd->protocol != TCP && iphd->protocol != UDP) {
+ bClassificationSucceed = TRUE;
+ goto out;
+ }
+ /* Checking Transport Layer Header field if present */
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Source Port %04x",
(iphd->protocol == UDP) ? xprt_hdr->uhdr.source : xprt_hdr->thdr.source);
- if (!MatchSrcPort(pstClassifierRule,
- ntohs((iphd->protocol == UDP) ?
- xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
- break;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Src Port Matched");
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Destination Port %04x",
+ if (!MatchSrcPort(pstClassifierRule,
+ ntohs((iphd->protocol == UDP) ?
+ xprt_hdr->uhdr.source : xprt_hdr->thdr.source)))
+ goto out;
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Src Port Matched");
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Destination Port %04x",
(iphd->protocol == UDP) ? xprt_hdr->uhdr.dest :
- xprt_hdr->thdr.dest);
- if (!MatchDestPort(pstClassifierRule,
- ntohs((iphd->protocol == UDP) ?
- xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
- break;
- bClassificationSucceed = TRUE;
- } while (0);
+ xprt_hdr->thdr.dest);
+
+ if (!MatchDestPort(pstClassifierRule,
+ ntohs((iphd->protocol == UDP) ?
+ xprt_hdr->uhdr.dest : xprt_hdr->thdr.dest)))
+ goto out;
+ bClassificationSucceed = TRUE;
+out:
if (TRUE == bClassificationSucceed) {
INT iMatchedSFQueueIndex = 0;
- iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
+
+ iMatchedSFQueueIndex =
+ SearchSfid(Adapter, pstClassifierRule->ulSFID);
if (iMatchedSFQueueIndex >= NO_OF_QUEUES)
bClassificationSucceed = false;
else if (false == Adapter->PackInfo[iMatchedSFQueueIndex].bActive)
bClassificationSucceed = false;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "IpVersion4 <==========");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "IpVersion4 <==========");
return bClassificationSucceed;
}
@@ -292,18 +428,24 @@ VOID PruneQueueAllSF(struct bcm_mini_adapter *Adapter)
/**
-@ingroup tx_functions
-This function checks if the max queue size for a queue
-is less than number of bytes in the queue. If so -
-drops packets from the Head till the number of bytes is
-less than or equal to max queue size for the queue.
-*/
+ * @ingroup tx_functions
+ * This function checks if the max queue size for a queue
+ * is less than number of bytes in the queue. If so -
+ * drops packets from the Head till the number of bytes is
+ * less than or equal to max queue size for the queue.
+ */
static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
{
- struct sk_buff* PacketToDrop = NULL;
+ struct sk_buff *PacketToDrop = NULL;
struct net_device_stats *netstats;
+ struct bcm_packet_info *curr_pack_info = &Adapter->PackInfo[iIndex];
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "=====> Index %d", iIndex);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ PRUNE_QUEUE,
+ DBG_LVL_ALL,
+ "=====> Index %d",
+ iIndex);
if (iIndex == HiPriority)
return;
@@ -314,22 +456,29 @@ static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
/* To Store the netdevice statistic */
netstats = &Adapter->dev->stats;
- spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
+ spin_lock_bh(&curr_pack_info->SFQueueLock);
while (1) {
-// while((UINT)Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost >
-// SF_MAX_ALLOWED_PACKETS_TO_BACKUP) {
+/* while((UINT)curr_pack_info->uiCurrentPacketsOnHost >
+ SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
- Adapter->PackInfo[iIndex].uiCurrentBytesOnHost,
- Adapter->PackInfo[iIndex].uiMaxBucketSize);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ PRUNE_QUEUE,
+ DBG_LVL_ALL,
+ "uiCurrentBytesOnHost:%x uiMaxBucketSize :%x",
+ curr_pack_info->uiCurrentBytesOnHost,
+ curr_pack_info->uiMaxBucketSize);
- PacketToDrop = Adapter->PackInfo[iIndex].FirstTxQueue;
+ PacketToDrop = curr_pack_info->FirstTxQueue;
if (PacketToDrop == NULL)
break;
- if ((Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost < SF_MAX_ALLOWED_PACKETS_TO_BACKUP) &&
- ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb)+SKB_CB_LATENCY_OFFSET))/HZ) <= Adapter->PackInfo[iIndex].uiMaxLatency))
+ if ((curr_pack_info->uiCurrentPacketsOnHost <
+ SF_MAX_ALLOWED_PACKETS_TO_BACKUP) &&
+ ((1000*(jiffies - *((B_UINT32 *)(PacketToDrop->cb) +
+ SKB_CB_LATENCY_OFFSET))/HZ) <=
+ curr_pack_info->uiMaxLatency))
break;
if (PacketToDrop) {
@@ -339,120 +488,168 @@ static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex)
netstats->tx_dropped++;
- DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue,
- Adapter->PackInfo[iIndex].LastTxQueue);
- /// update current bytes and packets count
- Adapter->PackInfo[iIndex].uiCurrentBytesOnHost -=
+ DEQUEUEPACKET(curr_pack_info->FirstTxQueue,
+ curr_pack_info->LastTxQueue);
+ /* update current bytes and packets count */
+ curr_pack_info->uiCurrentBytesOnHost -=
PacketToDrop->len;
- Adapter->PackInfo[iIndex].uiCurrentPacketsOnHost--;
- /// update dropped bytes and packets counts
- Adapter->PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len;
- Adapter->PackInfo[iIndex].uiDroppedCountPackets++;
+ curr_pack_info->uiCurrentPacketsOnHost--;
+ /* update dropped bytes and packets counts */
+ curr_pack_info->uiDroppedCountBytes += PacketToDrop->len;
+ curr_pack_info->uiDroppedCountPackets++;
dev_kfree_skb(PacketToDrop);
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x",
- Adapter->PackInfo[iIndex].uiDroppedCountBytes,
- Adapter->PackInfo[iIndex].uiDroppedCountPackets);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ PRUNE_QUEUE,
+ DBG_LVL_ALL,
+ "Dropped Bytes:%x Dropped Packets:%x",
+ curr_pack_info->uiDroppedCountBytes,
+ curr_pack_info->uiDroppedCountPackets);
atomic_dec(&Adapter->TotalPacketCount);
}
- spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock);
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "TotalPacketCount:%x",
- atomic_read(&Adapter->TotalPacketCount));
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, PRUNE_QUEUE, DBG_LVL_ALL, "<=====");
+ spin_unlock_bh(&curr_pack_info->SFQueueLock);
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ PRUNE_QUEUE,
+ DBG_LVL_ALL,
+ "TotalPacketCount:%x",
+ atomic_read(&Adapter->TotalPacketCount));
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ PRUNE_QUEUE,
+ DBG_LVL_ALL,
+ "<=====");
}
VOID flush_all_queues(struct bcm_mini_adapter *Adapter)
{
- INT iQIndex;
- UINT uiTotalPacketLength;
- struct sk_buff* PacketToDrop = NULL;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>");
-
-// down(&Adapter->data_packet_queue_lock);
+ INT iQIndex;
+ UINT uiTotalPacketLength;
+ struct sk_buff *PacketToDrop = NULL;
+ struct bcm_packet_info *curr_packet_info;
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_OTHERS,
+ DUMP_INFO,
+ DBG_LVL_ALL,
+ "=====>");
+
+ /* down(&Adapter->data_packet_queue_lock); */
for (iQIndex = LowPriority; iQIndex < HiPriority; iQIndex++) {
struct net_device_stats *netstats = &Adapter->dev->stats;
- spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
- while (Adapter->PackInfo[iQIndex].FirstTxQueue) {
- PacketToDrop = Adapter->PackInfo[iQIndex].FirstTxQueue;
+ curr_packet_info = &Adapter->PackInfo[iQIndex];
+
+ spin_lock_bh(&curr_packet_info->SFQueueLock);
+ while (curr_packet_info->FirstTxQueue) {
+ PacketToDrop = curr_packet_info->FirstTxQueue;
if (PacketToDrop) {
uiTotalPacketLength = PacketToDrop->len;
netstats->tx_dropped++;
} else
uiTotalPacketLength = 0;
- DEQUEUEPACKET(Adapter->PackInfo[iQIndex].FirstTxQueue,
- Adapter->PackInfo[iQIndex].LastTxQueue);
+ DEQUEUEPACKET(curr_packet_info->FirstTxQueue,
+ curr_packet_info->LastTxQueue);
/* Free the skb */
dev_kfree_skb(PacketToDrop);
- /// update current bytes and packets count
- Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength;
- Adapter->PackInfo[iQIndex].uiCurrentPacketsOnHost--;
-
- /// update dropped bytes and packets counts
- Adapter->PackInfo[iQIndex].uiDroppedCountBytes += uiTotalPacketLength;
- Adapter->PackInfo[iQIndex].uiDroppedCountPackets++;
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Dropped Bytes:%x Dropped Packets:%x",
- Adapter->PackInfo[iQIndex].uiDroppedCountBytes,
- Adapter->PackInfo[iQIndex].uiDroppedCountPackets);
+ /* update current bytes and packets count */
+ curr_packet_info->uiCurrentBytesOnHost -= uiTotalPacketLength;
+ curr_packet_info->uiCurrentPacketsOnHost--;
+
+ /* update dropped bytes and packets counts */
+ curr_packet_info->uiDroppedCountBytes += uiTotalPacketLength;
+ curr_packet_info->uiDroppedCountPackets++;
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_OTHERS,
+ DUMP_INFO,
+ DBG_LVL_ALL,
+ "Dropped Bytes:%x Dropped Packets:%x",
+ curr_packet_info->uiDroppedCountBytes,
+ curr_packet_info->uiDroppedCountPackets);
atomic_dec(&Adapter->TotalPacketCount);
}
- spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock);
+ spin_unlock_bh(&curr_packet_info->SFQueueLock);
}
-// up(&Adapter->data_packet_queue_lock);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "<=====");
+ /* up(&Adapter->data_packet_queue_lock); */
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_OTHERS,
+ DUMP_INFO,
+ DBG_LVL_ALL,
+ "<=====");
}
-USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
+USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
{
- INT uiLoopIndex = 0;
+ INT uiLoopIndex = 0;
struct bcm_classifier_rule *pstClassifierRule = NULL;
struct bcm_eth_packet_info stEthCsPktInfo;
PVOID pvEThPayload = NULL;
struct iphdr *pIpHeader = NULL;
- INT uiSfIndex = 0;
- USHORT usIndex = Adapter->usBestEffortQueueIndex;
- bool bFragmentedPkt = false, bClassificationSucceed = false;
- USHORT usCurrFragment = 0;
+ INT uiSfIndex = 0;
+ USHORT usIndex = Adapter->usBestEffortQueueIndex;
+ bool bFragmentedPkt = false, bClassificationSucceed = false;
+ USHORT usCurrFragment = 0;
struct bcm_tcp_header *pTcpHeader;
UCHAR IpHeaderLength;
UCHAR TcpHeaderLength;
pvEThPayload = skb->data;
- *((UINT32*) (skb->cb) +SKB_CB_TCPACK_OFFSET) = 0;
+ *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) = 0;
EThCSGetPktInfo(Adapter, pvEThPayload, &stEthCsPktInfo);
switch (stEthCsPktInfo.eNwpktEthFrameType) {
- case eEth802LLCFrame:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLCFrame\n");
- pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
- break;
- case eEth802LLCSNAPFrame:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802LLC SNAP Frame\n");
- pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_snap_frame);
- break;
- case eEth802QVLANFrame:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : 802.1Q VLANFrame\n");
- pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
- break;
- case eEthOtherFrame:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : ETH Other Frame\n");
- pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
- break;
- default:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Unrecognized ETH Frame\n");
- pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
- break;
+ case eEth802LLCFrame:
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : 802LLCFrame\n");
+ pIpHeader = pvEThPayload + sizeof(struct bcm_eth_llc_frame);
+ break;
+ case eEth802LLCSNAPFrame:
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : 802LLC SNAP Frame\n");
+ pIpHeader = pvEThPayload +
+ sizeof(struct bcm_eth_llc_snap_frame);
+ break;
+ case eEth802QVLANFrame:
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : 802.1Q VLANFrame\n");
+ pIpHeader = pvEThPayload + sizeof(struct bcm_eth_q_frame);
+ break;
+ case eEthOtherFrame:
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : ETH Other Frame\n");
+ pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
+ break;
+ default:
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : Unrecognized ETH Frame\n");
+ pIpHeader = pvEThPayload + sizeof(struct bcm_ethernet2_frame);
+ break;
}
if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet) {
@@ -461,16 +658,28 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
bFragmentedPkt = TRUE;
if (bFragmentedPkt) {
- //Fragmented Packet. Get Frag Classifier Entry.
- pstClassifierRule = GetFragIPClsEntry(Adapter, pIpHeader->id, pIpHeader->saddr);
+ /* Fragmented Packet. Get Frag Classifier Entry. */
+ pstClassifierRule = GetFragIPClsEntry(Adapter,
+ pIpHeader->id,
+ pIpHeader->saddr);
if (pstClassifierRule) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "It is next Fragmented pkt");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "It is next Fragmented pkt");
bClassificationSucceed = TRUE;
}
if (!(ntohs(pIpHeader->frag_off) & IP_MF)) {
- //Fragmented Last packet . Remove Frag Classifier Entry
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "This is the last fragmented Pkt");
- DelFragIPClsEntry(Adapter, pIpHeader->id, pIpHeader->saddr);
+ /* Fragmented Last packet . Remove Frag Classifier Entry */
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "This is the last fragmented Pkt");
+ DelFragIPClsEntry(Adapter,
+ pIpHeader->id,
+ pIpHeader->saddr);
}
}
}
@@ -478,100 +687,173 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
for (uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) {
if (bClassificationSucceed)
break;
- //Iterate through all classifiers which are already in order of priority
- //to classify the packet until match found
- do {
- if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
- bClassificationSucceed = false;
- break;
- }
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Adapter->PackInfo[%d].bvalid=True\n", uiLoopIndex);
-
- if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
- bClassificationSucceed = false;//cannot be processed for classification.
- break; // it is a down link connection
- }
-
- pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
+ /*
+ * Iterate through all classifiers which are already in order of priority
+ * to classify the packet until match found
+ */
+ if (false == Adapter->astClassifierTable[uiLoopIndex].bUsed) {
+ bClassificationSucceed = false;
+ continue;
+ }
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Adapter->PackInfo[%d].bvalid=True\n",
+ uiLoopIndex);
+
+ if (0 == Adapter->astClassifierTable[uiLoopIndex].ucDirection) {
+ bClassificationSucceed = false; /* cannot be processed for classification. */
+ continue; /* it is a down link connection */
+ }
- uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
- if (uiSfIndex >= NO_OF_QUEUES) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Queue Not Valid. SearchSfid for this classifier Failed\n");
- break;
- }
+ pstClassifierRule = &Adapter->astClassifierTable[uiLoopIndex];
- if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
+ uiSfIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
+ if (uiSfIndex >= NO_OF_QUEUES) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Queue Not Valid. SearchSfid for this classifier Failed\n");
+ continue;
+ }
- if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
- bClassificationSucceed = false;
- break;
- }
+ if (Adapter->PackInfo[uiSfIndex].bEthCSSupport) {
+ if (eEthUnsupportedFrame == stEthCsPktInfo.eNwpktEthFrameType) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ " ClassifyPacket : Packet Not a Valid Supported Ethernet Frame\n");
+ bClassificationSucceed = false;
+ continue;
+ }
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n", pstClassifierRule->uiClassifierRuleIndex, Adapter->PackInfo[uiSfIndex].ulSFID);
- bClassificationSucceed = EThCSClassifyPkt(Adapter, skb, &stEthCsPktInfo, pstClassifierRule, Adapter->PackInfo[uiSfIndex].bEthCSSupport);
- if (!bClassificationSucceed) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ClassifyPacket : Ethernet CS Classification Failed\n");
- break;
- }
- } else { // No ETH Supported on this SF
- if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
- bClassificationSucceed = false;
- break;
- }
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Performing ETH CS Classification on Classifier Rule ID : %x Service Flow ID : %lx\n",
+ pstClassifierRule->uiClassifierRuleIndex,
+ Adapter->PackInfo[uiSfIndex].ulSFID);
+ bClassificationSucceed = EThCSClassifyPkt(Adapter,
+ skb,
+ &stEthCsPktInfo,
+ pstClassifierRule,
+ Adapter->PackInfo[uiSfIndex].bEthCSSupport);
+
+ if (!bClassificationSucceed) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ClassifyPacket : Ethernet CS Classification Failed\n");
+ continue;
}
+ } else { /* No ETH Supported on this SF */
+ if (eEthOtherFrame != stEthCsPktInfo.eNwpktEthFrameType) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ " ClassifyPacket : Packet Not a 802.3 Ethernet Frame... hence not allowed over non-ETH CS SF\n");
+ bClassificationSucceed = false;
+ continue;
+ }
+ }
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Proceeding to IP CS Clasification");
-
- if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Proceeding to IP CS Clasification");
- if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, " ClassifyPacket : Packet is Not an IP Packet\n");
- bClassificationSucceed = false;
- break;
- }
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Dump IP Header :\n");
- DumpFullPacket((PUCHAR)pIpHeader, 20);
+ if (Adapter->PackInfo[uiSfIndex].bIPCSSupport) {
- if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
- bClassificationSucceed = IpVersion4(Adapter, pIpHeader, pstClassifierRule);
- else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
- bClassificationSucceed = IpVersion6(Adapter, pIpHeader, pstClassifierRule);
+ if (stEthCsPktInfo.eNwpktIPFrameType == eNonIPPacket) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ " ClassifyPacket : Packet is Not an IP Packet\n");
+ bClassificationSucceed = false;
+ continue;
}
-
- } while (0);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "Dump IP Header :\n");
+ DumpFullPacket((PUCHAR)pIpHeader, 20);
+
+ if (stEthCsPktInfo.eNwpktIPFrameType == eIPv4Packet)
+ bClassificationSucceed = IpVersion4(Adapter,
+ pIpHeader,
+ pstClassifierRule);
+ else if (stEthCsPktInfo.eNwpktIPFrameType == eIPv6Packet)
+ bClassificationSucceed = IpVersion6(Adapter,
+ pIpHeader,
+ pstClassifierRule);
+ }
}
if (bClassificationSucceed == TRUE) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "CF id : %d, SF ID is =%lu", pstClassifierRule->uiClassifierRuleIndex, pstClassifierRule->ulSFID);
-
- //Store The matched Classifier in SKB
- *((UINT32*)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) = pstClassifierRule->uiClassifierRuleIndex;
- if ((TCP == pIpHeader->protocol) && !bFragmentedPkt && (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <= skb->len)) {
- IpHeaderLength = pIpHeader->ihl;
- pTcpHeader = (struct bcm_tcp_header *)(((PUCHAR)pIpHeader)+(IpHeaderLength*4));
- TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "CF id : %d, SF ID is =%lu",
+ pstClassifierRule->uiClassifierRuleIndex,
+ pstClassifierRule->ulSFID);
+
+ /* Store The matched Classifier in SKB */
+ *((UINT32 *)(skb->cb)+SKB_CB_CLASSIFICATION_OFFSET) =
+ pstClassifierRule->uiClassifierRuleIndex;
+ if ((TCP == pIpHeader->protocol) && !bFragmentedPkt &&
+ (ETH_AND_IP_HEADER_LEN + TCP_HEADER_LEN <=
+ skb->len)) {
+ IpHeaderLength = pIpHeader->ihl;
+ pTcpHeader =
+ (struct bcm_tcp_header *)(((PUCHAR)pIpHeader) +
+ (IpHeaderLength*4));
+ TcpHeaderLength = GET_TCP_HEADER_LEN(pTcpHeader->HeaderLength);
if ((pTcpHeader->ucFlags & TCP_ACK) &&
- (ntohs(pIpHeader->tot_len) == (IpHeaderLength*4)+(TcpHeaderLength*4)))
- *((UINT32*) (skb->cb) + SKB_CB_TCPACK_OFFSET) = TCP_ACK;
+ (ntohs(pIpHeader->tot_len) ==
+ (IpHeaderLength*4)+(TcpHeaderLength*4)))
+ *((UINT32 *) (skb->cb) + SKB_CB_TCPACK_OFFSET) =
+ TCP_ACK;
}
usIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "index is =%d", usIndex);
-
- //If this is the first fragment of a Fragmented pkt, add this CF. Only This CF should be used for all other fragment of this Pkt.
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "index is =%d",
+ usIndex);
+
+ /*
+ * If this is the first fragment of a Fragmented pkt,
+ * add this CF. Only This CF should be used for all other
+ * fragment of this Pkt.
+ */
if (bFragmentedPkt && (usCurrFragment == 0)) {
- //First Fragment of Fragmented Packet. Create Frag CLS Entry
+ /*
+ * First Fragment of Fragmented Packet.
+ * Create Frag CLS Entry
+ */
struct bcm_fragmented_packet_info stFragPktInfo;
+
stFragPktInfo.bUsed = TRUE;
stFragPktInfo.ulSrcIpAddress = pIpHeader->saddr;
stFragPktInfo.usIpIdentification = pIpHeader->id;
- stFragPktInfo.pstMatchedClassifierEntry = pstClassifierRule;
+ stFragPktInfo.pstMatchedClassifierEntry =
+ pstClassifierRule;
stFragPktInfo.bOutOfOrderFragment = false;
AddFragIPClsEntry(Adapter, &stFragPktInfo);
}
@@ -579,56 +861,103 @@ USHORT ClassifyPacket(struct bcm_mini_adapter *Adapter, struct sk_buff* skb)
}
- if (bClassificationSucceed)
- return usIndex;
- else
- return INVALID_QUEUE_INDEX;
+ return bClassificationSucceed ? usIndex : INVALID_QUEUE_INDEX;
}
-static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
+static bool EthCSMatchSrcMACAddress(struct bcm_classifier_rule *pstClassifierRule,
+ PUCHAR Mac)
{
UINT i = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
if (pstClassifierRule->ucEthCSSrcMACLen == 0)
return TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s\n", __func__);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s\n", __func__);
for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSSrcMAC[i], pstClassifierRule->au8EThCSSrcMACMask[i]);
- if ((pstClassifierRule->au8EThCSSrcMAC[i] & pstClassifierRule->au8EThCSSrcMACMask[i]) !=
- (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
+ i,
+ Mac[i],
+ pstClassifierRule->au8EThCSSrcMAC[i],
+ pstClassifierRule->au8EThCSSrcMACMask[i]);
+ if ((pstClassifierRule->au8EThCSSrcMAC[i] &
+ pstClassifierRule->au8EThCSSrcMACMask[i]) !=
+ (Mac[i] & pstClassifierRule->au8EThCSSrcMACMask[i]))
return false;
}
return TRUE;
}
-static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule, PUCHAR Mac)
+static bool EthCSMatchDestMACAddress(struct bcm_classifier_rule *pstClassifierRule,
+ PUCHAR Mac)
{
UINT i = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
if (pstClassifierRule->ucEthCSDestMACLen == 0)
return TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s\n", __func__);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s\n",
+ __func__);
for (i = 0; i < MAC_ADDRESS_SIZE; i++) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n", i, Mac[i], pstClassifierRule->au8EThCSDestMAC[i], pstClassifierRule->au8EThCSDestMACMask[i]);
- if ((pstClassifierRule->au8EThCSDestMAC[i] & pstClassifierRule->au8EThCSDestMACMask[i]) !=
- (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "SRC MAC[%x] = %x ClassifierRuleSrcMAC = %x Mask : %x\n",
+ i,
+ Mac[i],
+ pstClassifierRule->au8EThCSDestMAC[i],
+ pstClassifierRule->au8EThCSDestMACMask[i]);
+ if ((pstClassifierRule->au8EThCSDestMAC[i] &
+ pstClassifierRule->au8EThCSDestMACMask[i]) !=
+ (Mac[i] & pstClassifierRule->au8EThCSDestMACMask[i]))
return false;
}
return TRUE;
}
-static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
+static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
+ struct sk_buff *skb,
+ struct bcm_eth_packet_info *pstEthCsPktInfo)
{
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
+
if ((pstClassifierRule->ucEtherTypeLen == 0) ||
(pstClassifierRule->au8EthCSEtherType[0] == 0))
return TRUE;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s SrcEtherType:%x CLS EtherType[0]:%x\n", __func__, pstEthCsPktInfo->usEtherType, pstClassifierRule->au8EthCSEtherType[0]);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s SrcEtherType:%x CLS EtherType[0]:%x\n",
+ __func__,
+ pstEthCsPktInfo->usEtherType,
+ pstClassifierRule->au8EthCSEtherType[0]);
if (pstClassifierRule->au8EthCSEtherType[0] == 1) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS EtherType[1]:%x EtherType[2]:%x\n", __func__, pstClassifierRule->au8EthCSEtherType[1], pstClassifierRule->au8EthCSEtherType[2]);
-
- if (memcmp(&pstEthCsPktInfo->usEtherType, &pstClassifierRule->au8EthCSEtherType[1], 2) == 0)
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s CLS EtherType[1]:%x EtherType[2]:%x\n",
+ __func__,
+ pstClassifierRule->au8EthCSEtherType[1],
+ pstClassifierRule->au8EthCSEtherType[2]);
+
+ if (memcmp(&pstEthCsPktInfo->usEtherType,
+ &pstClassifierRule->au8EthCSEtherType[1],
+ 2) == 0)
return TRUE;
else
return false;
@@ -638,8 +967,16 @@ static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
if (eEth802LLCFrame != pstEthCsPktInfo->eNwpktEthFrameType)
return false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s EthCS DSAP:%x EtherType[2]:%x\n", __func__, pstEthCsPktInfo->ucDSAP, pstClassifierRule->au8EthCSEtherType[2]);
- if (pstEthCsPktInfo->ucDSAP == pstClassifierRule->au8EthCSEtherType[2])
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s EthCS DSAP:%x EtherType[2]:%x\n",
+ __func__,
+ pstEthCsPktInfo->ucDSAP,
+ pstClassifierRule->au8EthCSEtherType[2]);
+ if (pstEthCsPktInfo->ucDSAP ==
+ pstClassifierRule->au8EthCSEtherType[2])
return TRUE;
else
return false;
@@ -650,40 +987,70 @@ static bool EthCSMatchEThTypeSAP(struct bcm_classifier_rule *pstClassifierRule,
}
-static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, struct sk_buff* skb, struct bcm_eth_packet_info *pstEthCsPktInfo)
+static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule,
+ struct sk_buff *skb,
+ struct bcm_eth_packet_info *pstEthCsPktInfo)
{
bool bClassificationSucceed = false;
USHORT usVLANID;
B_UINT8 uPriority = 0;
struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s CLS UserPrio:%x CLS VLANID:%x\n", __func__, ntohs(*((USHORT *)pstClassifierRule->usUserPriority)), pstClassifierRule->usVLANID);
-
- /* In case FW didn't receive the TLV, the priority field should be ignored */
- if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s CLS UserPrio:%x CLS VLANID:%x\n",
+ __func__,
+ ntohs(*((USHORT *)pstClassifierRule->usUserPriority)),
+ pstClassifierRule->usVLANID);
+
+ /*
+ * In case FW didn't receive the TLV,
+ * the priority field should be ignored
+ */
+ if (pstClassifierRule->usValidityBitMap &
+ (1<<PKT_CLASSIFICATION_USER_PRIORITY_VALID)) {
if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
return false;
- uPriority = (ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xF000) >> 13;
+ uPriority = (ntohs(*(USHORT *)(skb->data +
+ sizeof(struct bcm_eth_header))) &
+ 0xF000) >> 13;
- if ((uPriority >= pstClassifierRule->usUserPriority[0]) && (uPriority <= pstClassifierRule->usUserPriority[1]))
- bClassificationSucceed = TRUE;
+ if ((uPriority >= pstClassifierRule->usUserPriority[0]) &&
+ (uPriority <=
+ pstClassifierRule->usUserPriority[1]))
+ bClassificationSucceed = TRUE;
if (!bClassificationSucceed)
return false;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 D User Priority Rule Matched\n");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS 802.1 D User Priority Rule Matched\n");
bClassificationSucceed = false;
- if (pstClassifierRule->usValidityBitMap & (1<<PKT_CLASSIFICATION_VLANID_VALID)) {
+ if (pstClassifierRule->usValidityBitMap &
+ (1<<PKT_CLASSIFICATION_VLANID_VALID)) {
if (pstEthCsPktInfo->eNwpktEthFrameType != eEth802QVLANFrame)
return false;
- usVLANID = ntohs(*(USHORT *)(skb->data + sizeof(struct bcm_eth_header))) & 0xFFF;
+ usVLANID = ntohs(*(USHORT *)(skb->data +
+ sizeof(struct bcm_eth_header))) & 0xFFF;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "%s Pkt VLANID %x Priority: %d\n", __func__, usVLANID, uPriority);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "%s Pkt VLANID %x Priority: %d\n",
+ __func__,
+ usVLANID,
+ uPriority);
if (usVLANID == ((pstClassifierRule->usVLANID & 0xFFF0) >> 4))
bClassificationSucceed = TRUE;
@@ -692,70 +1059,113 @@ static bool EthCSMatchVLANRules(struct bcm_classifier_rule *pstClassifierRule, s
return false;
}
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 Q VLAN ID Rule Matched\n");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS 802.1 Q VLAN ID Rule Matched\n");
return TRUE;
}
-static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter, struct sk_buff* skb,
- struct bcm_eth_packet_info *pstEthCsPktInfo,
- struct bcm_classifier_rule *pstClassifierRule,
- B_UINT8 EthCSCupport)
+static bool EThCSClassifyPkt(struct bcm_mini_adapter *Adapter,
+ struct sk_buff *skb,
+ struct bcm_eth_packet_info *pstEthCsPktInfo,
+ struct bcm_classifier_rule *pstClassifierRule,
+ B_UINT8 EthCSCupport)
{
bool bClassificationSucceed = false;
- bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule, ((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
+
+ bClassificationSucceed = EthCSMatchSrcMACAddress(pstClassifierRule,
+ ((struct bcm_eth_header *)(skb->data))->au8SourceAddress);
if (!bClassificationSucceed)
return false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS SrcMAC Matched\n");
-
- bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule, ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS SrcMAC Matched\n");
+
+ bClassificationSucceed = EthCSMatchDestMACAddress(pstClassifierRule,
+ ((struct bcm_eth_header *)(skb->data))->au8DestinationAddress);
if (!bClassificationSucceed)
return false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS DestMAC Matched\n");
-
- //classify on ETHType/802.2SAP TLV
- bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule, skb, pstEthCsPktInfo);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS DestMAC Matched\n");
+
+ /* classify on ETHType/802.2SAP TLV */
+ bClassificationSucceed = EthCSMatchEThTypeSAP(pstClassifierRule,
+ skb,
+ pstEthCsPktInfo);
if (!bClassificationSucceed)
return false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS EthType/802.2SAP Matched\n");
-
- //classify on 802.1VLAN Header Parameters
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS EthType/802.2SAP Matched\n");
- bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule, skb, pstEthCsPktInfo);
+ /* classify on 802.1VLAN Header Parameters */
+ bClassificationSucceed = EthCSMatchVLANRules(pstClassifierRule,
+ skb,
+ pstEthCsPktInfo);
if (!bClassificationSucceed)
return false;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "ETH CS 802.1 VLAN Rules Matched\n");
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "ETH CS 802.1 VLAN Rules Matched\n");
return bClassificationSucceed;
}
-static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, PVOID pvEthPayload,
+static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter,
+ PVOID pvEthPayload,
struct bcm_eth_packet_info *pstEthCsPktInfo)
{
- USHORT u16Etype = ntohs(((struct bcm_eth_header *)pvEthPayload)->u16Etype);
-
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n", u16Etype);
+ USHORT u16Etype = ntohs(
+ ((struct bcm_eth_header *)pvEthPayload)->u16Etype);
+
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "EthCSGetPktInfo : Eth Hdr Type : %X\n",
+ u16Etype);
if (u16Etype > 0x5dc) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : ETH2 Frame\n");
- //ETH2 Frame
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "EthCSGetPktInfo : ETH2 Frame\n");
+ /* ETH2 Frame */
if (u16Etype == ETHERNET_FRAMETYPE_802QVLAN) {
- //802.1Q VLAN Header
+ /* 802.1Q VLAN Header */
pstEthCsPktInfo->eNwpktEthFrameType = eEth802QVLANFrame;
u16Etype = ((struct bcm_eth_q_frame *)pvEthPayload)->EthType;
- //((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority
+ /* ((ETH_CS_802_Q_FRAME*)pvEthPayload)->UserPriority */
} else {
pstEthCsPktInfo->eNwpktEthFrameType = eEthOtherFrame;
u16Etype = ntohs(u16Etype);
}
} else {
- //802.2 LLC
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "802.2 LLC Frame\n");
+ /* 802.2 LLC */
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "802.2 LLC Frame\n");
pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCFrame;
- pstEthCsPktInfo->ucDSAP = ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP;
+ pstEthCsPktInfo->ucDSAP =
+ ((struct bcm_eth_llc_frame *)pvEthPayload)->DSAP;
if (pstEthCsPktInfo->ucDSAP == 0xAA && ((struct bcm_eth_llc_frame *)pvEthPayload)->SSAP == 0xAA) {
- //SNAP Frame
+ /* SNAP Frame */
pstEthCsPktInfo->eNwpktEthFrameType = eEth802LLCSNAPFrame;
u16Etype = ((struct bcm_eth_llc_snap_frame *)pvEthPayload)->usEtherType;
}
@@ -768,10 +1178,23 @@ static void EThCSGetPktInfo(struct bcm_mini_adapter *Adapter, PVOID pvEthPayload
pstEthCsPktInfo->eNwpktIPFrameType = eNonIPPacket;
pstEthCsPktInfo->usEtherType = ((struct bcm_eth_header *)pvEthPayload)->u16Etype;
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktIPFrameType : %x\n", pstEthCsPktInfo->eNwpktIPFrameType);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->eNwpktEthFrameType : %x\n", pstEthCsPktInfo->eNwpktEthFrameType);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCsPktInfo->usEtherType : %x\n", pstEthCsPktInfo->usEtherType);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "EthCsPktInfo->eNwpktIPFrameType : %x\n",
+ pstEthCsPktInfo->eNwpktIPFrameType);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "EthCsPktInfo->eNwpktEthFrameType : %x\n",
+ pstEthCsPktInfo->eNwpktEthFrameType);
+ BCM_DEBUG_PRINT(Adapter,
+ DBG_TYPE_TX,
+ IPV4_DBG,
+ DBG_LVL_ALL,
+ "EthCsPktInfo->usEtherType : %x\n",
+ pstEthCsPktInfo->usEtherType);
}
-
-
diff --git a/drivers/staging/bcm/Queue.h b/drivers/staging/bcm/Queue.h
index e1f1da2bb6d4..460c0aee67f6 100644
--- a/drivers/staging/bcm/Queue.h
+++ b/drivers/staging/bcm/Queue.h
@@ -1,31 +1,29 @@
/*************************************
-* Queue.h
+* Queue.h
**************************************/
#ifndef __QUEUE_H__
#define __QUEUE_H__
-#define ENQUEUEPACKET(_Head, _Tail,_Packet) \
-do \
-{ \
- if (!_Head) { \
- _Head = _Packet; \
- } \
- else { \
- (_Tail)->next = _Packet; \
- } \
- (_Packet)->next = NULL; \
- _Tail = _Packet; \
-}while(0)
-#define DEQUEUEPACKET(Head, Tail ) \
-do \
-{ if(Head) \
- { \
- if (!Head->next) { \
- Tail = NULL; \
- } \
- Head = Head->next; \
- } \
-}while(0)
-#endif //__QUEUE_H__
+#define ENQUEUEPACKET(_Head, _Tail, _Packet) \
+do { \
+ if (!_Head) { \
+ _Head = _Packet; \
+ } \
+ else { \
+ (_Tail)->next = _Packet; \
+ } \
+ (_Packet)->next = NULL; \
+ _Tail = _Packet; \
+} while (0)
+#define DEQUEUEPACKET(Head, Tail) \
+do { \
+ if (Head) { \
+ if (!Head->next) { \
+ Tail = NULL; \
+ } \
+ Head = Head->next; \
+ } \
+} while (0)
+#endif /* __QUEUE_H__ */
diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO
index cd3e9f2ed87a..8467f45d08a6 100644
--- a/drivers/staging/bcm/TODO
+++ b/drivers/staging/bcm/TODO
@@ -1,5 +1,9 @@
This driver is barely functional in its current state.
+Kevin McKinney(klmckinney1@gmail.com) and Matthias Beyer(mail@beyermatthias.de)
+are currently maintaining/cleaning up this driver. Please copy us on all
+patches. More maintainers are aways welcomed.
+
BIG:
- existing API is (/dev/tarang) should be replaced
Is it possible to use same API as Intel Wimax stack and
diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c
index 49767468ac23..622a482e9826 100644
--- a/drivers/staging/bcm/Transmit.c
+++ b/drivers/staging/bcm/Transmit.c
@@ -59,21 +59,27 @@ int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)
/* Update the netdevice statistics */
/* Dump Packet */
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Status: %x", PLeader->Status);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader VCID: %x", PLeader->Vcid);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x", PLeader->PLength);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
+ "Leader Status: %x", PLeader->Status);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
+ "Leader VCID: %x", PLeader->Vcid);
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
+ "Leader Length: %x", PLeader->PLength);
if (Adapter->device_removed)
return 0;
if (netif_msg_pktdata(Adapter))
print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE,
- 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0);
+ 16, 1, pControlPacket,
+ PLeader->PLength + LEADER_SIZE, 0);
Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
- pControlPacket, (PLeader->PLength + LEADER_SIZE));
+ pControlPacket,
+ (PLeader->PLength + LEADER_SIZE));
atomic_dec(&Adapter->CurrNumFreeTxDesc);
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<=========");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL,
+ "<=========");
return STATUS_SUCCESS;
}
@@ -83,12 +89,15 @@ int SendControlPacket(struct bcm_mini_adapter *Adapter, char *pControlPacket)
* to the target via the host h/w interface.
* @return zero(success) or -ve value(failure)
*/
-int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USHORT Vcid)
+int SetupNextSend(struct bcm_mini_adapter *Adapter,
+ struct sk_buff *Packet, USHORT Vcid)
{
int status = 0;
bool bHeaderSupressionEnabled = false;
B_UINT16 uiClassifierRuleID;
u16 QueueIndex = skb_get_queue_mapping(Packet);
+ struct bcm_packet_info *curr_packet_info =
+ &Adapter->PackInfo[QueueIndex];
struct bcm_leader Leader = {0};
if (Packet->len > MAX_DEVICE_DESC_SIZE) {
@@ -97,18 +106,21 @@ int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH
}
/* Get the Classifier Rule ID */
- uiClassifierRuleID = *((UINT32 *) (Packet->cb) + SKB_CB_CLASSIFICATION_OFFSET);
+ uiClassifierRuleID = *((UINT32 *) (Packet->cb) +
+ SKB_CB_CLASSIFICATION_OFFSET);
- bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled
- & Adapter->bPHSEnabled;
+ bHeaderSupressionEnabled = curr_packet_info->bHeaderSuppressionEnabled &
+ Adapter->bPHSEnabled;
if (Adapter->device_removed) {
status = STATUS_FAILURE;
goto errExit;
}
- status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID, bHeaderSupressionEnabled,
- (UINT *)&Packet->len, Adapter->PackInfo[QueueIndex].bEthCSSupport);
+ status = PHSTransmit(Adapter, &Packet, Vcid, uiClassifierRuleID,
+ bHeaderSupressionEnabled,
+ (UINT *)&Packet->len,
+ curr_packet_info->bEthCSSupport);
if (status != STATUS_SUCCESS) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,
@@ -123,12 +135,14 @@ int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH
else
Leader.Status = LEADER_STATUS;
- if (Adapter->PackInfo[QueueIndex].bEthCSSupport) {
+ if (curr_packet_info->bEthCSSupport) {
Leader.PLength = Packet->len;
if (skb_headroom(Packet) < LEADER_SIZE) {
status = skb_cow(Packet, LEADER_SIZE);
if (status) {
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit : Failed To Increase headRoom\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND,
+ DBG_LVL_ALL,
+ "bcm_transmit : Failed To Increase headRoom\n");
goto errExit;
}
}
@@ -136,30 +150,36 @@ int SetupNextSend(struct bcm_mini_adapter *Adapter, struct sk_buff *Packet, USH
memcpy(Packet->data, &Leader, LEADER_SIZE);
} else {
Leader.PLength = Packet->len - ETH_HLEN;
- memcpy((struct bcm_leader *)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE);
+ memcpy((struct bcm_leader *)skb_pull(Packet,
+ (ETH_HLEN - LEADER_SIZE)),
+ &Leader,
+ LEADER_SIZE);
}
status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter,
- Packet->data, (Leader.PLength + LEADER_SIZE));
+ Packet->data,
+ (Leader.PLength + LEADER_SIZE));
if (status) {
++Adapter->dev->stats.tx_errors;
if (netif_msg_tx_err(Adapter))
- pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name,
+ pr_info(PFX "%s: transmit error %d\n",
+ Adapter->dev->name,
status);
} else {
struct net_device_stats *netstats = &Adapter->dev->stats;
- Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength;
+
+ curr_packet_info->uiTotalTxBytes += Leader.PLength;
netstats->tx_bytes += Leader.PLength;
++netstats->tx_packets;
- Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3;
- Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len);
- Adapter->PackInfo[QueueIndex].uiSentPackets++;
- Adapter->PackInfo[QueueIndex].NumOfPacketsSent++;
+ curr_packet_info->uiCurrentTokenCount -= Leader.PLength << 3;
+ curr_packet_info->uiSentBytes += (Packet->len);
+ curr_packet_info->uiSentPackets++;
+ curr_packet_info->NumOfPacketsSent++;
- atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount);
- Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength;
+ atomic_dec(&curr_packet_info->uiPerSFTxResourceCount);
+ curr_packet_info->uiThisPeriodSentBytes += Leader.PLength;
}
atomic_dec(&Adapter->CurrNumFreeTxDesc);
@@ -172,7 +192,8 @@ errExit:
static int tx_pending(struct bcm_mini_adapter *Adapter)
{
return (atomic_read(&Adapter->TxPktAvail)
- && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc))
+ && MINIMUM_PENDING_DESCRIPTORS <
+ atomic_read(&Adapter->CurrNumFreeTxDesc))
|| Adapter->device_removed || (1 == Adapter->downloadDDR);
}
@@ -180,18 +201,21 @@ static int tx_pending(struct bcm_mini_adapter *Adapter)
* @ingroup tx_functions
* Transmit thread
*/
-int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter object*/)
+int tx_pkt_handler(struct bcm_mini_adapter *Adapter)
{
int status = 0;
while (!kthread_should_stop()) {
- /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */
+ /* FIXME - the timeout looks like workaround
+ * for racey usage of TxPktAvail
+ */
if (Adapter->LinkUpStatus)
wait_event_timeout(Adapter->tx_packet_wait_queue,
- tx_pending(Adapter), msecs_to_jiffies(10));
+ tx_pending(Adapter),
+ msecs_to_jiffies(10));
else
wait_event_interruptible(Adapter->tx_packet_wait_queue,
- tx_pending(Adapter));
+ tx_pending(Adapter));
if (Adapter->device_removed)
break;
@@ -208,7 +232,8 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje
if (Adapter->bEndPointHalted == TRUE) {
Bcm_clear_halt_of_endpoints(Adapter);
Adapter->bEndPointHalted = false;
- StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter));
+ StartInterruptUrb((struct bcm_interface_adapter *)
+ (Adapter->pvInterfaceAdapter));
}
if (Adapter->LinkUpStatus && !Adapter->IdleMode) {
@@ -225,7 +250,8 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje
LinkMessage(Adapter);
}
- if ((Adapter->IdleMode || Adapter->bShutStatus) && atomic_read(&Adapter->TotalPacketCount)) {
+ if ((Adapter->IdleMode || Adapter->bShutStatus) &&
+ atomic_read(&Adapter->TotalPacketCount)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX,
TX_PACKETS, DBG_LVL_ALL,
"Device in Low Power mode...waking up");
diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c
index 42d9004e357d..f9b08a5d8ce8 100644
--- a/drivers/staging/bcm/hostmibs.c
+++ b/drivers/staging/bcm/hostmibs.c
@@ -17,6 +17,7 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter,
struct bcm_phs_classifier_table *pstClassifierTable = NULL;
struct bcm_phs_classifier_entry *pstClassifierRule = NULL;
struct bcm_phs_extension *pDeviceExtension = &Adapter->stBCMPhsContext;
+ struct bcm_mibs_host_info *host_info;
UINT nClassifierIndex = 0;
UINT nPhsTableIndex = 0;
UINT nSfIndex = 0;
@@ -83,18 +84,18 @@ INT ProcessGetHostMibs(struct bcm_mini_adapter *Adapter,
}
/* Copy other Host Statistics parameters */
- pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets;
- pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets;
- pstHostMibs->stHostInfo.CurrNumFreeDesc =
- atomic_read(&Adapter->CurrNumFreeTxDesc);
- pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize;
- pstHostMibs->stHostInfo.rtPSBucketSize = Adapter->rtPSBucketSize;
- pstHostMibs->stHostInfo.TimerActive = Adapter->TimerActive;
- pstHostMibs->stHostInfo.u32TotalDSD = Adapter->u32TotalDSD;
-
- memcpy(pstHostMibs->stHostInfo.aTxPktSizeHist, Adapter->aTxPktSizeHist,
+ host_info = &pstHostMibs->stHostInfo;
+ host_info->GoodTransmits = Adapter->dev->stats.tx_packets;
+ host_info->GoodReceives = Adapter->dev->stats.rx_packets;
+ host_info->CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc);
+ host_info->BEBucketSize = Adapter->BEBucketSize;
+ host_info->rtPSBucketSize = Adapter->rtPSBucketSize;
+ host_info->TimerActive = Adapter->TimerActive;
+ host_info->u32TotalDSD = Adapter->u32TotalDSD;
+
+ memcpy(host_info->aTxPktSizeHist, Adapter->aTxPktSizeHist,
sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
- memcpy(pstHostMibs->stHostInfo.aRxPktSizeHist, Adapter->aRxPktSizeHist,
+ memcpy(host_info->aRxPktSizeHist, Adapter->aRxPktSizeHist,
sizeof(UINT32) * MIBS_MAX_HIST_ENTRIES);
return STATUS_SUCCESS;
@@ -112,32 +113,45 @@ VOID CopyMIBSExtendedSFParameters(struct bcm_mini_adapter *Adapter,
struct bcm_connect_mgr_params *psfLocalSet,
UINT uiSearchRuleIndex)
{
- struct bcm_mibs_parameters *t = &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
+ struct bcm_mibs_parameters *t =
+ &Adapter->PackInfo[uiSearchRuleIndex].stMibsExtServiceFlowTable;
t->wmanIfSfid = psfLocalSet->u32SFID;
- t->wmanIfCmnCpsMaxSustainedRate = psfLocalSet->u32MaxSustainedTrafficRate;
+ t->wmanIfCmnCpsMaxSustainedRate =
+ psfLocalSet->u32MaxSustainedTrafficRate;
t->wmanIfCmnCpsMaxTrafficBurst = psfLocalSet->u32MaxTrafficBurst;
t->wmanIfCmnCpsMinReservedRate = psfLocalSet->u32MinReservedTrafficRate;
t->wmanIfCmnCpsToleratedJitter = psfLocalSet->u32ToleratedJitter;
t->wmanIfCmnCpsMaxLatency = psfLocalSet->u32MaximumLatency;
- t->wmanIfCmnCpsFixedVsVariableSduInd = psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator;
- t->wmanIfCmnCpsFixedVsVariableSduInd = ntohl(t->wmanIfCmnCpsFixedVsVariableSduInd);
+ t->wmanIfCmnCpsFixedVsVariableSduInd =
+ psfLocalSet->u8FixedLengthVSVariableLengthSDUIndicator;
+ t->wmanIfCmnCpsFixedVsVariableSduInd =
+ ntohl(t->wmanIfCmnCpsFixedVsVariableSduInd);
t->wmanIfCmnCpsSduSize = psfLocalSet->u8SDUSize;
t->wmanIfCmnCpsSduSize = ntohl(t->wmanIfCmnCpsSduSize);
- t->wmanIfCmnCpsSfSchedulingType = psfLocalSet->u8ServiceFlowSchedulingType;
- t->wmanIfCmnCpsSfSchedulingType = ntohl(t->wmanIfCmnCpsSfSchedulingType);
+ t->wmanIfCmnCpsSfSchedulingType =
+ psfLocalSet->u8ServiceFlowSchedulingType;
+ t->wmanIfCmnCpsSfSchedulingType =
+ ntohl(t->wmanIfCmnCpsSfSchedulingType);
t->wmanIfCmnCpsArqEnable = psfLocalSet->u8ARQEnable;
t->wmanIfCmnCpsArqEnable = ntohl(t->wmanIfCmnCpsArqEnable);
t->wmanIfCmnCpsArqWindowSize = ntohs(psfLocalSet->u16ARQWindowSize);
t->wmanIfCmnCpsArqWindowSize = ntohl(t->wmanIfCmnCpsArqWindowSize);
- t->wmanIfCmnCpsArqBlockLifetime = ntohs(psfLocalSet->u16ARQBlockLifeTime);
- t->wmanIfCmnCpsArqBlockLifetime = ntohl(t->wmanIfCmnCpsArqBlockLifetime);
- t->wmanIfCmnCpsArqSyncLossTimeout = ntohs(psfLocalSet->u16ARQSyncLossTimeOut);
- t->wmanIfCmnCpsArqSyncLossTimeout = ntohl(t->wmanIfCmnCpsArqSyncLossTimeout);
+ t->wmanIfCmnCpsArqBlockLifetime =
+ ntohs(psfLocalSet->u16ARQBlockLifeTime);
+ t->wmanIfCmnCpsArqBlockLifetime =
+ ntohl(t->wmanIfCmnCpsArqBlockLifetime);
+ t->wmanIfCmnCpsArqSyncLossTimeout =
+ ntohs(psfLocalSet->u16ARQSyncLossTimeOut);
+ t->wmanIfCmnCpsArqSyncLossTimeout =
+ ntohl(t->wmanIfCmnCpsArqSyncLossTimeout);
t->wmanIfCmnCpsArqDeliverInOrder = psfLocalSet->u8ARQDeliverInOrder;
- t->wmanIfCmnCpsArqDeliverInOrder = ntohl(t->wmanIfCmnCpsArqDeliverInOrder);
- t->wmanIfCmnCpsArqRxPurgeTimeout = ntohs(psfLocalSet->u16ARQRxPurgeTimeOut);
- t->wmanIfCmnCpsArqRxPurgeTimeout = ntohl(t->wmanIfCmnCpsArqRxPurgeTimeout);
+ t->wmanIfCmnCpsArqDeliverInOrder =
+ ntohl(t->wmanIfCmnCpsArqDeliverInOrder);
+ t->wmanIfCmnCpsArqRxPurgeTimeout =
+ ntohs(psfLocalSet->u16ARQRxPurgeTimeOut);
+ t->wmanIfCmnCpsArqRxPurgeTimeout =
+ ntohl(t->wmanIfCmnCpsArqRxPurgeTimeout);
t->wmanIfCmnCpsArqBlockSize = ntohs(psfLocalSet->u16ARQBlockSize);
t->wmanIfCmnCpsArqBlockSize = ntohl(t->wmanIfCmnCpsArqBlockSize);
t->wmanIfCmnCpsReqTxPolicy = psfLocalSet->u8RequesttransmissionPolicy;
diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c
index eee4f4795a71..074fc39ed678 100644
--- a/drivers/staging/bcm/led_control.c
+++ b/drivers/staging/bcm/led_control.c
@@ -6,6 +6,7 @@
static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
{
B_UINT16 u16CheckSum = 0;
+
while (u32Size--) {
u16CheckSum += (B_UINT8)~(*pu8Buffer);
pu8Buffer++;
@@ -16,6 +17,7 @@ static B_UINT16 CFG_CalculateChecksum(B_UINT8 *pu8Buffer, B_UINT32 u32Size)
bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
{
INT Status;
+
Status = (Adapter->gpioBitMap & gpios) ^ gpios;
if (Status)
return false;
@@ -23,8 +25,12 @@ bool IsReqGpioIsLedInNVM(struct bcm_mini_adapter *Adapter, UINT gpios)
return TRUE;
}
-static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLedIndex,
- ULONG timeout, INT num_of_time, enum bcm_led_events currdriverstate)
+static INT LED_Blink(struct bcm_mini_adapter *Adapter,
+ UINT GPIO_Num,
+ UCHAR uiLedIndex,
+ ULONG timeout,
+ INT num_of_time,
+ enum bcm_led_events currdriverstate)
{
int Status = STATUS_SUCCESS;
bool bInfinite = false;
@@ -36,7 +42,7 @@ static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLe
}
while (num_of_time) {
if (currdriverstate == Adapter->DriverState)
- TURN_ON_LED(GPIO_Num, uiLedIndex);
+ TURN_ON_LED(Adapter, GPIO_Num, uiLedIndex);
/* Wait for timeout after setting on the LED */
Status = wait_event_interruptible_timeout(
@@ -51,17 +57,17 @@ static INT LED_Blink(struct bcm_mini_adapter *Adapter, UINT GPIO_Num, UCHAR uiLe
"Led thread got signal to exit..hence exiting");
Adapter->LEDInfo.led_thread_running =
BCM_LED_THREAD_DISABLED;
- TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Status = EVENT_SIGNALED;
break;
}
if (Status) {
- TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Status = EVENT_SIGNALED;
break;
}
- TURN_OFF_LED(GPIO_Num, uiLedIndex);
+ TURN_OFF_LED(Adapter, GPIO_Num, uiLedIndex);
Status = wait_event_interruptible_timeout(
Adapter->LEDInfo.notify_led_event,
currdriverstate != Adapter->DriverState ||
@@ -93,11 +99,59 @@ static INT ScaleRateofTransfer(ULONG rate)
return MAX_NUM_OF_BLINKS;
}
+static INT blink_in_normal_bandwidth(struct bcm_mini_adapter *ad,
+ INT *time,
+ INT *time_tx,
+ INT *time_rx,
+ UCHAR GPIO_Num_tx,
+ UCHAR uiTxLedIndex,
+ UCHAR GPIO_Num_rx,
+ UCHAR uiRxLedIndex,
+ enum bcm_led_events currdriverstate,
+ ulong *timeout)
+{
+ /*
+ * Assign minimum number of blinks of
+ * either Tx or Rx.
+ */
+ *time = (*time_tx > *time_rx ? *time_rx : *time_tx);
+
+ if (*time > 0) {
+ /* Blink both Tx and Rx LEDs */
+ if ((LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
+ *time, currdriverstate) == EVENT_SIGNALED) ||
+ (LED_Blink(ad, 1 << GPIO_Num_rx, uiRxLedIndex, *timeout,
+ *time, currdriverstate) == EVENT_SIGNALED))
+ return EVENT_SIGNALED;
+ }
+
+ if (*time == *time_tx) {
+ /* Blink pending rate of Rx */
+ if (LED_Blink(ad, (1 << GPIO_Num_rx), uiRxLedIndex, *timeout,
+ *time_rx - *time,
+ currdriverstate) == EVENT_SIGNALED)
+ return EVENT_SIGNALED;
+ *time = *time_rx;
+ } else {
+ /* Blink pending rate of Tx */
+ if (LED_Blink(ad, 1 << GPIO_Num_tx, uiTxLedIndex, *timeout,
+ *time_tx - *time,
+ currdriverstate) == EVENT_SIGNALED)
+ return EVENT_SIGNALED;
+
+ *time = *time_tx;
+ }
-static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_Num_tx,
- UCHAR uiTxLedIndex, UCHAR GPIO_Num_rx, UCHAR uiRxLedIndex,
- enum bcm_led_events currdriverstate)
+ return 0;
+}
+
+static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter,
+ UCHAR GPIO_Num_tx,
+ UCHAR uiTxLedIndex,
+ UCHAR GPIO_Num_rx,
+ UCHAR uiRxLedIndex,
+ enum bcm_led_events currdriverstate)
{
/* Initial values of TX and RX packets */
ULONG64 Initial_num_of_packts_tx = 0, Initial_num_of_packts_rx = 0;
@@ -108,7 +162,6 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
int Status = STATUS_SUCCESS;
INT num_of_time = 0, num_of_time_tx = 0, num_of_time_rx = 0;
UINT remDelay = 0;
- bool bBlinkBothLED = TRUE;
/* UINT GPIO_num = DISABLE_GPIO_NUM; */
ulong timeout = 0;
@@ -122,73 +175,19 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
while ((Adapter->device_removed == false)) {
timeout = 50;
- /*
- * Blink Tx and Rx LED when both Tx and Rx is
- * in normal bandwidth
- */
- if (bBlinkBothLED) {
- /*
- * Assign minimum number of blinks of
- * either Tx or Rx.
- */
- if (num_of_time_tx > num_of_time_rx)
- num_of_time = num_of_time_rx;
- else
- num_of_time = num_of_time_tx;
- if (num_of_time > 0) {
- /* Blink both Tx and Rx LEDs */
- if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
- uiTxLedIndex, timeout,
- num_of_time, currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
-
- if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
- uiRxLedIndex, timeout,
- num_of_time, currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
- }
+ if (EVENT_SIGNALED == blink_in_normal_bandwidth(Adapter,
+ &num_of_time,
+ &num_of_time_tx,
+ &num_of_time_rx,
+ GPIO_Num_tx,
+ uiTxLedIndex,
+ GPIO_Num_rx,
+ uiRxLedIndex,
+ currdriverstate,
+ &timeout))
+ return EVENT_SIGNALED;
- if (num_of_time == num_of_time_tx) {
- /* Blink pending rate of Rx */
- if (LED_Blink(Adapter, (1 << GPIO_Num_rx),
- uiRxLedIndex, timeout,
- num_of_time_rx-num_of_time,
- currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
-
- num_of_time = num_of_time_rx;
- } else {
- /* Blink pending rate of Tx */
- if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
- uiTxLedIndex, timeout,
- num_of_time_tx-num_of_time,
- currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
-
- num_of_time = num_of_time_tx;
- }
- } else {
- if (num_of_time == num_of_time_tx) {
- /* Blink pending rate of Rx */
- if (LED_Blink(Adapter, 1 << GPIO_Num_tx,
- uiTxLedIndex, timeout,
- num_of_time, currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
- } else {
- /* Blink pending rate of Tx */
- if (LED_Blink(Adapter, 1 << GPIO_Num_rx,
- uiRxLedIndex, timeout,
- num_of_time, currdriverstate)
- == EVENT_SIGNALED)
- return EVENT_SIGNALED;
- }
- }
/*
* If Tx/Rx rate is less than maximum blinks per second,
@@ -216,8 +215,8 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
}
/* Turn off both Tx and Rx LEDs before next second */
- TURN_OFF_LED(1 << GPIO_Num_tx, uiTxLedIndex);
- TURN_OFF_LED(1 << GPIO_Num_rx, uiTxLedIndex);
+ TURN_OFF_LED(Adapter, 1 << GPIO_Num_tx, uiTxLedIndex);
+ TURN_OFF_LED(Adapter, 1 << GPIO_Num_rx, uiTxLedIndex);
/*
* Read the Tx & Rx packets transmission after 1 second and
@@ -261,8 +260,9 @@ static INT LED_Proportional_Blink(struct bcm_mini_adapter *Adapter, UCHAR GPIO_N
* <OSAL_STATUS_CODE>
* -----------------------------------------------------------------------------
*/
-static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, ULONG ulParamOffset,
- USHORT usParamLen)
+static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter,
+ ULONG ulParamOffset,
+ USHORT usParamLen)
{
INT Status = STATUS_SUCCESS;
PUCHAR puBuffer = NULL;
@@ -270,24 +270,24 @@ static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, ULONG ulP
USHORT usChecksumCalculated = 0;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
- ulParamOffset, usParamLen);
+ "LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",
+ ulParamOffset, usParamLen);
puBuffer = kmalloc(usParamLen, GFP_KERNEL);
if (!puBuffer) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "LED Thread: ValidateDSDParamsChecksum Allocation failed");
+ DBG_LVL_ALL,
+ "LED Thread: ValidateDSDParamsChecksum Allocation failed");
return -ENOMEM;
}
/* Read the DSD data from the parameter offset. */
if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)puBuffer,
- ulParamOffset, usParamLen)) {
+ ulParamOffset, usParamLen)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+ DBG_LVL_ALL,
+ "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
goto exit;
}
@@ -295,24 +295,24 @@ static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, ULONG ulP
/* Calculate the checksum of the data read from the DSD parameter. */
usChecksumCalculated = CFG_CalculateChecksum(puBuffer, usParamLen);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread: usCheckSumCalculated = 0x%x\n",
- usChecksumCalculated);
+ "LED Thread: usCheckSumCalculated = 0x%x\n",
+ usChecksumCalculated);
/*
* End of the DSD parameter will have a TWO bytes checksum stored in it.
* Read it and compare with the calculated Checksum.
*/
if (STATUS_SUCCESS != BeceemNVMRead(Adapter, (PUINT)&usChksmOrg,
- ulParamOffset+usParamLen, 2)) {
+ ulParamOffset+usParamLen, 2)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
+ DBG_LVL_ALL,
+ "LED Thread: ValidateDSDParamsChecksum BeceemNVMRead failed");
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
goto exit;
}
usChksmOrg = ntohs(usChksmOrg);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
+ "LED Thread: usChksmOrg = 0x%x", usChksmOrg);
/*
* Compare the checksum calculated with the checksum read
@@ -320,8 +320,8 @@ static INT ValidateDSDParamsChecksum(struct bcm_mini_adapter *Adapter, ULONG ulP
*/
if (usChecksumCalculated ^ usChksmOrg) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
+ DBG_LVL_ALL,
+ "LED Thread: ValidateDSDParamsChecksum: Checksums don't match");
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
goto exit;
}
@@ -347,7 +347,8 @@ exit:
* <OSAL_STATUS_CODE>
* -----------------------------------------------------------------------------
*/
-static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, ULONG ulHwParamOffset)
+static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter,
+ ULONG ulHwParamOffset)
{
INT Status = STATUS_SUCCESS;
@@ -365,9 +366,9 @@ static INT ValidateHWParmStructure(struct bcm_mini_adapter *Adapter, ULONG ulHwP
return STATUS_IMAGE_CHECKSUM_MISMATCH;
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread:HwParamLen = 0x%x", HwParamLen);
+ "LED Thread:HwParamLen = 0x%x", HwParamLen);
Status = ValidateDSDParamsChecksum(Adapter, ulHwParamOffset,
- HwParamLen);
+ HwParamLen);
return Status;
} /* ValidateHWParmStructure() */
@@ -383,16 +384,17 @@ static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
UCHAR ucGPIOInfo[32] = {0};
BeceemNVMRead(Adapter, (PUINT)&usEEPROMVersion,
- EEPROM_VERSION_OFFSET, 2);
+ EEPROM_VERSION_OFFSET, 2);
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "usEEPROMVersion: Minor:0x%X Major:0x%x",
- usEEPROMVersion&0xFF, ((usEEPROMVersion>>8)&0xFF));
+ "usEEPROMVersion: Minor:0x%X Major:0x%x",
+ usEEPROMVersion & 0xFF,
+ ((usEEPROMVersion >> 8) & 0xFF));
if (((usEEPROMVersion>>8)&0xFF) < EEPROM_MAP5_MAJORVERSION) {
BeceemNVMRead(Adapter, (PUINT)&usHwParamData,
- EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
+ EEPROM_HW_PARAM_POINTER_ADDRESS, 2);
usHwParamData = ntohs(usHwParamData);
dwReadValue = usHwParamData;
} else {
@@ -401,21 +403,21 @@ static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
* if compatibility section is valid.
*/
Status = ValidateDSDParamsChecksum(Adapter,
- DSD_START_OFFSET,
- COMPATIBILITY_SECTION_LENGTH_MAP5);
+ DSD_START_OFFSET,
+ COMPATIBILITY_SECTION_LENGTH_MAP5);
if (Status != STATUS_SUCCESS)
return Status;
BeceemNVMRead(Adapter, (PUINT)&dwReadValue,
- EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
+ EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5, 4);
dwReadValue = ntohl(dwReadValue);
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread: Start address of HW_PARAM structure = 0x%lx",
- dwReadValue);
+ "LED Thread: Start address of HW_PARAM structure = 0x%lx",
+ dwReadValue);
/*
* Validate if the address read out is within the DSD.
@@ -437,8 +439,8 @@ static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
* To read GPIO section, add GPIO offset further.
*/
- dwReadValue +=
- DSD_START_OFFSET; /* = start address of hw param section. */
+ dwReadValue += DSD_START_OFFSET;
+ /* = start address of hw param section. */
dwReadValue += GPIO_SECTION_START_OFFSET;
/* = GPIO start offset within HW Param section. */
@@ -472,13 +474,14 @@ static int ReadLEDInformationFromEEPROM(struct bcm_mini_adapter *Adapter,
}
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "GPIO's bit map correspond to LED :0x%X", Adapter->gpioBitMap);
+ "GPIO's bit map correspond to LED :0x%X",
+ Adapter->gpioBitMap);
return Status;
}
static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
- bool *bEnableThread)
+ bool *bEnableThread)
{
int Status = STATUS_SUCCESS;
/* Array to store GPIO numbers from EEPROM */
@@ -487,11 +490,13 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
UINT uiNum_of_LED_Type = 0;
PUCHAR puCFGData = NULL;
UCHAR bData = 0;
+ struct bcm_led_state_info *curr_led_state;
+
memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1);
if (!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) {
- BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL, "Target Params not Avail.\n");
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+ DBG_LVL_ALL, "Target Params not Avail.\n");
return -ENOENT;
}
@@ -511,7 +516,7 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
* uiFileNameBufferSize
*/
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,
- "LED Thread: Config file read successfully\n");
+ "LED Thread: Config file read successfully\n");
puCFGData = (PUCHAR) &Adapter->pstargetparams->HostDrvrConfig1;
/*
@@ -522,31 +527,30 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
bData = *puCFGData;
+ curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
/*
* Check Bit 8 for polarity. If it is set,
* polarity is reverse polarity
*/
if (bData & 0x80) {
- Adapter->LEDInfo.LEDState[uiIndex].BitPolarity = 0;
+ curr_led_state->BitPolarity = 0;
/* unset the bit 8 */
bData = bData & 0x7f;
}
- Adapter->LEDInfo.LEDState[uiIndex].LED_Type = bData;
+ curr_led_state->LED_Type = bData;
if (bData <= NUM_OF_LEDS)
- Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
- GPIO_Array[bData];
+ curr_led_state->GPIO_Num = GPIO_Array[bData];
else
- Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num =
- DISABLE_GPIO_NUM;
+ curr_led_state->GPIO_Num = DISABLE_GPIO_NUM;
puCFGData++;
bData = *puCFGData;
- Adapter->LEDInfo.LEDState[uiIndex].LED_On_State = bData;
+ curr_led_state->LED_On_State = bData;
puCFGData++;
bData = *puCFGData;
- Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State = bData;
+ curr_led_state->LED_Blink_State = bData;
puCFGData++;
}
@@ -555,9 +559,11 @@ static int ReadConfigFileStructure(struct bcm_mini_adapter *Adapter,
* dont launch the LED control thread.
*/
for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
- if ((Adapter->LEDInfo.LEDState[uiIndex].LED_Type == DISABLE_GPIO_NUM) ||
- (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0x7f) ||
- (Adapter->LEDInfo.LEDState[uiIndex].LED_Type == 0))
+ curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
+
+ if ((curr_led_state->LED_Type == DISABLE_GPIO_NUM) ||
+ (curr_led_state->LED_Type == 0x7f) ||
+ (curr_led_state->LED_Type == 0))
uiNum_of_LED_Type++;
}
if (uiNum_of_LED_Type >= NUM_OF_LEDS)
@@ -584,67 +590,237 @@ static VOID LedGpioInit(struct bcm_mini_adapter *Adapter)
{
UINT uiResetValue = 0;
UINT uiIndex = 0;
+ struct bcm_led_state_info *curr_led_state;
/* Set all LED GPIO Mode to output mode */
if (rdmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
- sizeof(uiResetValue)) < 0)
+ sizeof(uiResetValue)) < 0)
BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
DBG_LVL_ALL, "LED Thread: RDM Failed\n");
for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num !=
- DISABLE_GPIO_NUM)
- uiResetValue |= (1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num);
- TURN_OFF_LED(1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num,
- uiIndex);
+ curr_led_state = &Adapter->LEDInfo.LEDState[uiIndex];
+
+ if (curr_led_state->GPIO_Num != DISABLE_GPIO_NUM)
+ uiResetValue |= (1 << curr_led_state->GPIO_Num);
+
+ TURN_OFF_LED(Adapter, 1 << curr_led_state->GPIO_Num, uiIndex);
+
}
if (wrmalt(Adapter, GPIO_MODE_REGISTER, &uiResetValue,
- sizeof(uiResetValue)) < 0)
- BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL, "LED Thread: WRM Failed\n");
+ sizeof(uiResetValue)) < 0)
+ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+ DBG_LVL_ALL, "LED Thread: WRM Failed\n");
Adapter->LEDInfo.bIdle_led_off = false;
}
-static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter, UCHAR *GPIO_num_tx,
- UCHAR *GPIO_num_rx, UCHAR *uiLedTxIndex, UCHAR *uiLedRxIndex,
- enum bcm_led_events currdriverstate)
+static INT BcmGetGPIOPinInfo(struct bcm_mini_adapter *Adapter,
+ UCHAR *GPIO_num_tx,
+ UCHAR *GPIO_num_rx,
+ UCHAR *uiLedTxIndex,
+ UCHAR *uiLedRxIndex,
+ enum bcm_led_events currdriverstate)
{
UINT uiIndex = 0;
+ struct bcm_led_state_info *led_state_info;
*GPIO_num_tx = DISABLE_GPIO_NUM;
*GPIO_num_rx = DISABLE_GPIO_NUM;
for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
-
- if ((currdriverstate == NORMAL_OPERATION) ||
- (currdriverstate == IDLEMODE_EXIT) ||
- (currdriverstate == FW_DOWNLOAD)) {
- if (Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State &
- currdriverstate) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
- != DISABLE_GPIO_NUM) {
- if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
- *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
- *uiLedTxIndex = uiIndex;
- } else {
- *GPIO_num_rx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
- *uiLedRxIndex = uiIndex;
- }
- }
+ led_state_info = &Adapter->LEDInfo.LEDState[uiIndex];
+
+ if (((currdriverstate == NORMAL_OPERATION) ||
+ (currdriverstate == IDLEMODE_EXIT) ||
+ (currdriverstate == FW_DOWNLOAD)) &&
+ (led_state_info->LED_Blink_State & currdriverstate) &&
+ (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
+ if (*GPIO_num_tx == DISABLE_GPIO_NUM) {
+ *GPIO_num_tx = led_state_info->GPIO_Num;
+ *uiLedTxIndex = uiIndex;
+ } else {
+ *GPIO_num_rx = led_state_info->GPIO_Num;
+ *uiLedRxIndex = uiIndex;
}
} else {
- if (Adapter->LEDInfo.LEDState[uiIndex].LED_On_State
- & currdriverstate) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
- != DISABLE_GPIO_NUM) {
- *GPIO_num_tx = Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num;
- *uiLedTxIndex = uiIndex;
- }
+ if ((led_state_info->LED_On_State & currdriverstate) &&
+ (led_state_info->GPIO_Num != DISABLE_GPIO_NUM)) {
+ *GPIO_num_tx = led_state_info->GPIO_Num;
+ *uiLedTxIndex = uiIndex;
}
}
}
return STATUS_SUCCESS;
}
+
+static void handle_adapter_driver_state(struct bcm_mini_adapter *ad,
+ enum bcm_led_events currdriverstate,
+ UCHAR GPIO_num,
+ UCHAR dummyGPIONum,
+ UCHAR uiLedIndex,
+ UCHAR dummyIndex,
+ ulong timeout,
+ UINT uiResetValue,
+ UINT uiIndex)
+{
+ switch (ad->DriverState) {
+ case DRIVER_INIT:
+ currdriverstate = DRIVER_INIT;
+ /* ad->DriverState; */
+ BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
+ &uiLedIndex, &dummyIndex,
+ currdriverstate);
+
+ if (GPIO_num != DISABLE_GPIO_NUM)
+ TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
+
+ break;
+ case FW_DOWNLOAD:
+ /*
+ * BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
+ * LED_DUMP_INFO, DBG_LVL_ALL,
+ * "LED Thread: FW_DN_DONE called\n");
+ */
+ currdriverstate = FW_DOWNLOAD;
+ BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
+ &uiLedIndex, &dummyIndex,
+ currdriverstate);
+
+ if (GPIO_num != DISABLE_GPIO_NUM) {
+ timeout = 50;
+ LED_Blink(ad, 1 << GPIO_num, uiLedIndex, timeout,
+ -1, currdriverstate);
+ }
+ break;
+ case FW_DOWNLOAD_DONE:
+ currdriverstate = FW_DOWNLOAD_DONE;
+ BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
+ &uiLedIndex, &dummyIndex, currdriverstate);
+ if (GPIO_num != DISABLE_GPIO_NUM)
+ TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
+ break;
+
+ case SHUTDOWN_EXIT:
+ /*
+ * no break, continue to NO_NETWORK_ENTRY
+ * state as well.
+ */
+ case NO_NETWORK_ENTRY:
+ currdriverstate = NO_NETWORK_ENTRY;
+ BcmGetGPIOPinInfo(ad, &GPIO_num, &dummyGPIONum,
+ &uiLedIndex, &dummyGPIONum, currdriverstate);
+ if (GPIO_num != DISABLE_GPIO_NUM)
+ TURN_ON_LED(ad, 1 << GPIO_num, uiLedIndex);
+ break;
+ case NORMAL_OPERATION:
+ {
+ UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
+ UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
+ UCHAR uiLEDTx = 0;
+ UCHAR uiLEDRx = 0;
+
+ currdriverstate = NORMAL_OPERATION;
+ ad->LEDInfo.bIdle_led_off = false;
+
+ BcmGetGPIOPinInfo(ad, &GPIO_num_tx, &GPIO_num_rx,
+ &uiLEDTx, &uiLEDRx, currdriverstate);
+ if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
+ (GPIO_num_rx == DISABLE_GPIO_NUM)) {
+ GPIO_num = DISABLE_GPIO_NUM;
+ } else {
+ /*
+ * If single LED is selected, use same
+ * for both Tx and Rx
+ */
+ if (GPIO_num_tx == DISABLE_GPIO_NUM) {
+ GPIO_num_tx = GPIO_num_rx;
+ uiLEDTx = uiLEDRx;
+ } else if (GPIO_num_rx == DISABLE_GPIO_NUM) {
+ GPIO_num_rx = GPIO_num_tx;
+ uiLEDRx = uiLEDTx;
+ }
+ /*
+ * Blink the LED in proportionate
+ * to Tx and Rx transmissions.
+ */
+ LED_Proportional_Blink(ad,
+ GPIO_num_tx, uiLEDTx,
+ GPIO_num_rx, uiLEDRx,
+ currdriverstate);
+ }
+ }
+ break;
+ case LOWPOWER_MODE_ENTER:
+ currdriverstate = LOWPOWER_MODE_ENTER;
+ if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
+ ad->ulPowerSaveMode) {
+ /* Turn OFF all the LED */
+ uiResetValue = 0;
+ for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+ if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
+ TURN_OFF_LED(ad,
+ (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
+ uiIndex);
+ }
+
+ }
+ /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
+ ad->LEDInfo.bLedInitDone = false;
+ ad->LEDInfo.bIdle_led_off = TRUE;
+ wake_up(&ad->LEDInfo.idleModeSyncEvent);
+ GPIO_num = DISABLE_GPIO_NUM;
+ break;
+ case IDLEMODE_CONTINUE:
+ currdriverstate = IDLEMODE_CONTINUE;
+ GPIO_num = DISABLE_GPIO_NUM;
+ break;
+ case IDLEMODE_EXIT:
+ break;
+ case DRIVER_HALT:
+ currdriverstate = DRIVER_HALT;
+ GPIO_num = DISABLE_GPIO_NUM;
+ for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+ if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
+ DISABLE_GPIO_NUM)
+ TURN_OFF_LED(ad,
+ (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
+ uiIndex);
+ }
+ /* ad->DriverState = DRIVER_INIT; */
+ break;
+ case LED_THREAD_INACTIVE:
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+ DBG_LVL_ALL, "InActivating LED thread...");
+ currdriverstate = LED_THREAD_INACTIVE;
+ ad->LEDInfo.led_thread_running =
+ BCM_LED_THREAD_RUNNING_INACTIVELY;
+ ad->LEDInfo.bLedInitDone = false;
+ /* disable ALL LED */
+ for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
+ if (ad->LEDInfo.LEDState[uiIndex].GPIO_Num !=
+ DISABLE_GPIO_NUM)
+ TURN_OFF_LED(ad,
+ (1 << ad->LEDInfo.LEDState[uiIndex].GPIO_Num),
+ uiIndex);
+ }
+ break;
+ case LED_THREAD_ACTIVE:
+ BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, LED_DUMP_INFO,
+ DBG_LVL_ALL, "Activating LED thread again...");
+ if (ad->LinkUpStatus == false)
+ ad->DriverState = NO_NETWORK_ENTRY;
+ else
+ ad->DriverState = NORMAL_OPERATION;
+
+ ad->LEDInfo.led_thread_running =
+ BCM_LED_THREAD_RUNNING_ACTIVELY;
+ break;
+ /* return; */
+ default:
+ break;
+ }
+}
+
static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
{
UINT uiIndex = 0;
@@ -691,168 +867,28 @@ static VOID LEDControlThread(struct bcm_mini_adapter *Adapter)
"Led thread got signal to exit..hence exiting");
Adapter->LEDInfo.led_thread_running =
BCM_LED_THREAD_DISABLED;
- TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
+ TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
return; /* STATUS_FAILURE; */
}
if (GPIO_num != DISABLE_GPIO_NUM)
- TURN_OFF_LED(1 << GPIO_num, uiLedIndex);
+ TURN_OFF_LED(Adapter, 1 << GPIO_num, uiLedIndex);
if (Adapter->LEDInfo.bLedInitDone == false) {
LedGpioInit(Adapter);
Adapter->LEDInfo.bLedInitDone = TRUE;
}
- switch (Adapter->DriverState) {
- case DRIVER_INIT:
- currdriverstate = DRIVER_INIT;
- /* Adapter->DriverState; */
- BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
- &uiLedIndex, &dummyIndex, currdriverstate);
-
- if (GPIO_num != DISABLE_GPIO_NUM)
- TURN_ON_LED(1 << GPIO_num, uiLedIndex);
-
- break;
- case FW_DOWNLOAD:
- /*
- * BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
- * LED_DUMP_INFO, DBG_LVL_ALL,
- * "LED Thread: FW_DN_DONE called\n");
- */
- currdriverstate = FW_DOWNLOAD;
- BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
- &uiLedIndex, &dummyIndex, currdriverstate);
-
- if (GPIO_num != DISABLE_GPIO_NUM) {
- timeout = 50;
- LED_Blink(Adapter, 1 << GPIO_num, uiLedIndex,
- timeout, -1, currdriverstate);
- }
- break;
- case FW_DOWNLOAD_DONE:
- currdriverstate = FW_DOWNLOAD_DONE;
- BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
- &uiLedIndex, &dummyIndex, currdriverstate);
- if (GPIO_num != DISABLE_GPIO_NUM)
- TURN_ON_LED(1 << GPIO_num, uiLedIndex);
- break;
-
- case SHUTDOWN_EXIT:
- /*
- * no break, continue to NO_NETWORK_ENTRY
- * state as well.
- */
- case NO_NETWORK_ENTRY:
- currdriverstate = NO_NETWORK_ENTRY;
- BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum,
- &uiLedIndex, &dummyGPIONum, currdriverstate);
- if (GPIO_num != DISABLE_GPIO_NUM)
- TURN_ON_LED(1 << GPIO_num, uiLedIndex);
- break;
- case NORMAL_OPERATION:
- {
- UCHAR GPIO_num_tx = DISABLE_GPIO_NUM;
- UCHAR GPIO_num_rx = DISABLE_GPIO_NUM;
- UCHAR uiLEDTx = 0;
- UCHAR uiLEDRx = 0;
- currdriverstate = NORMAL_OPERATION;
- Adapter->LEDInfo.bIdle_led_off = false;
-
- BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx,
- &GPIO_num_rx, &uiLEDTx, &uiLEDRx,
- currdriverstate);
- if ((GPIO_num_tx == DISABLE_GPIO_NUM) &&
- (GPIO_num_rx ==
- DISABLE_GPIO_NUM)) {
- GPIO_num = DISABLE_GPIO_NUM;
- } else {
- /*
- * If single LED is selected, use same
- * for both Tx and Rx
- */
- if (GPIO_num_tx == DISABLE_GPIO_NUM) {
- GPIO_num_tx = GPIO_num_rx;
- uiLEDTx = uiLEDRx;
- } else if (GPIO_num_rx ==
- DISABLE_GPIO_NUM) {
- GPIO_num_rx = GPIO_num_tx;
- uiLEDRx = uiLEDTx;
- }
- /*
- * Blink the LED in proportionate
- * to Tx and Rx transmissions.
- */
- LED_Proportional_Blink(Adapter,
- GPIO_num_tx, uiLEDTx,
- GPIO_num_rx, uiLEDRx,
- currdriverstate);
- }
- }
- break;
- case LOWPOWER_MODE_ENTER:
- currdriverstate = LOWPOWER_MODE_ENTER;
- if (DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING ==
- Adapter->ulPowerSaveMode) {
- /* Turn OFF all the LED */
- uiResetValue = 0;
- for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num != DISABLE_GPIO_NUM)
- TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
- }
-
- }
- /* Turn off LED And WAKE-UP for Sendinf IDLE mode ACK */
- Adapter->LEDInfo.bLedInitDone = false;
- Adapter->LEDInfo.bIdle_led_off = TRUE;
- wake_up(&Adapter->LEDInfo.idleModeSyncEvent);
- GPIO_num = DISABLE_GPIO_NUM;
- break;
- case IDLEMODE_CONTINUE:
- currdriverstate = IDLEMODE_CONTINUE;
- GPIO_num = DISABLE_GPIO_NUM;
- break;
- case IDLEMODE_EXIT:
- break;
- case DRIVER_HALT:
- currdriverstate = DRIVER_HALT;
- GPIO_num = DISABLE_GPIO_NUM;
- for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
- != DISABLE_GPIO_NUM)
- TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
- }
- /* Adapter->DriverState = DRIVER_INIT; */
- break;
- case LED_THREAD_INACTIVE:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL, "InActivating LED thread...");
- currdriverstate = LED_THREAD_INACTIVE;
- Adapter->LEDInfo.led_thread_running =
- BCM_LED_THREAD_RUNNING_INACTIVELY;
- Adapter->LEDInfo.bLedInitDone = false;
- /* disable ALL LED */
- for (uiIndex = 0; uiIndex < NUM_OF_LEDS; uiIndex++) {
- if (Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num
- != DISABLE_GPIO_NUM)
- TURN_OFF_LED((1 << Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num), uiIndex);
- }
- break;
- case LED_THREAD_ACTIVE:
- BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL, "Activating LED thread again...");
- if (Adapter->LinkUpStatus == false)
- Adapter->DriverState = NO_NETWORK_ENTRY;
- else
- Adapter->DriverState = NORMAL_OPERATION;
-
- Adapter->LEDInfo.led_thread_running =
- BCM_LED_THREAD_RUNNING_ACTIVELY;
- break;
- /* return; */
- default:
- break;
- }
+ handle_adapter_driver_state(Adapter,
+ currdriverstate,
+ GPIO_num,
+ dummyGPIONum,
+ uiLedIndex,
+ dummyIndex,
+ timeout,
+ uiResetValue,
+ uiIndex
+ );
}
Adapter->LEDInfo.led_thread_running = BCM_LED_THREAD_DISABLED;
}
@@ -878,8 +914,8 @@ int InitLedSettings(struct bcm_mini_adapter *Adapter)
Status = ReadConfigFileStructure(Adapter, &bEnableThread);
if (STATUS_SUCCESS != Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "LED Thread: FAILED in ReadConfigFileStructure\n");
+ DBG_LVL_ALL,
+ "LED Thread: FAILED in ReadConfigFileStructure\n");
return Status;
}
@@ -902,11 +938,11 @@ int InitLedSettings(struct bcm_mini_adapter *Adapter)
Adapter->LEDInfo.bIdle_led_off = false;
Adapter->LEDInfo.led_cntrl_threadid =
kthread_run((int (*)(void *)) LEDControlThread,
- Adapter, "led_control_thread");
+ Adapter, "led_control_thread");
if (IS_ERR(Adapter->LEDInfo.led_cntrl_threadid)) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LED_DUMP_INFO,
- DBG_LVL_ALL,
- "Not able to spawn Kernel Thread\n");
+ DBG_LVL_ALL,
+ "Not able to spawn Kernel Thread\n");
Adapter->LEDInfo.led_thread_running =
BCM_LED_THREAD_DISABLED;
return PTR_ERR(Adapter->LEDInfo.led_cntrl_threadid);
diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h
index bae40e22e11b..1b24bf4658af 100644
--- a/drivers/staging/bcm/led_control.h
+++ b/drivers/staging/bcm/led_control.h
@@ -17,18 +17,18 @@
#define EVENT_SIGNALED 1
#define MAX_FILE_NAME_BUFFER_SIZE 100
-#define TURN_ON_LED(GPIO, index) do { \
+#define TURN_ON_LED(ad, GPIO, index) do { \
unsigned int gpio_val = GPIO; \
- (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
- wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \
- wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
+ (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \
+ wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \
+ wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
} while (0)
-#define TURN_OFF_LED(GPIO, index) do { \
+#define TURN_OFF_LED(ad, GPIO, index) do { \
unsigned int gpio_val = GPIO; \
- (Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
- wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \
- wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \
+ (ad->LEDInfo.LEDState[index].BitPolarity == 1) ? \
+ wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \
+ wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \
} while (0)
enum bcm_led_colors {
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
index 63be3be62ebd..ce09473fbb1f 100644
--- a/drivers/staging/bcm/nvm.c
+++ b/drivers/staging/bcm/nvm.c
@@ -2,35 +2,52 @@
#define DWORD unsigned int
-static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset);
+static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter,
+ unsigned int offset);
static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
-static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize);
+static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter,
+ unsigned int FlashSectorSizeSig,
+ unsigned int FlashSectorSize);
static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter);
-static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
-
-static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset);
-static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section);
-static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
-
-static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
-static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
-static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
-static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
-
-static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
-static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
-static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr);
-static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
- enum bcm_flash2x_section_val eFlash2xSectionVal,
- unsigned int uiOffset, unsigned int uiNumBytes);
+static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val eFlash2xSectionVal);
+
+static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter,
+ unsigned int uiOffset);
+static int IsSectionWritable(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val Section);
+static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val section);
+
+static int ReadDSDPriority(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val dsd);
+static int ReadDSDSignature(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val dsd);
+static int ReadISOPriority(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val iso);
+static int ReadISOSignature(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val iso);
+
+static int CorruptDSDSig(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val eFlash2xSectionVal);
+static int CorruptISOSig(struct bcm_mini_adapter *Adapter,
+ enum bcm_flash2x_section_val eFlash2xSectionVal);
+static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter,
+ PUCHAR pBuff,
+ unsigned int uiSectAlignAddr);
+static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
+ PUINT pBuff,
+ enum bcm_flash2x_section_val eFlash2xSectionVal,
+ unsigned int uiOffset,
+ unsigned int uiNumBytes);
static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
@@ -361,6 +378,7 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
} else {
/* Handle the reads less than 4 bytes... */
PUCHAR pCharBuff = (PUCHAR)pBuffer;
+
pCharBuff += uiIndex;
if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */
@@ -914,6 +932,7 @@ static int flashWriteStatus(struct bcm_mini_adapter *Adapter,
static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
{
unsigned int value;
+
value = (FLASH_CMD_WRITE_ENABLE << 24);
wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
@@ -1014,6 +1033,45 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned i
return ulStatus;
}
+static int bulk_read_complete_sector(struct bcm_mini_adapter *ad,
+ UCHAR read_bk[],
+ PCHAR tmpbuff,
+ unsigned int offset,
+ unsigned int partoff)
+{
+ unsigned int i;
+ int j;
+ int bulk_read_stat;
+ FP_FLASH_WRITE_STATUS writef =
+ ad->fpFlashWriteWithStatusCheck;
+
+ for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) {
+ bulk_read_stat = BeceemFlashBulkRead(ad,
+ (PUINT)read_bk,
+ offset + i,
+ MAX_RW_SIZE);
+
+ if (bulk_read_stat != STATUS_SUCCESS)
+ continue;
+
+ if (ad->ulFlashWriteSize == 1) {
+ for (j = 0; j < 16; j++) {
+ if ((read_bk[j] != tmpbuff[i + j]) &&
+ (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) {
+ return STATUS_FAILURE;
+ }
+ }
+ } else {
+ if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) &&
+ (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) {
+ return STATUS_FAILURE;
+ }
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
/*
* Procedure: BeceemFlashBulkWrite
*
@@ -1150,28 +1208,16 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
/* do_gettimeofday(&tw);
* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000));
*/
- for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) {
- if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) {
- if (Adapter->ulFlashWriteSize == 1) {
- unsigned int uiReadIndex = 0;
- for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) {
- if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) {
- if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) {
- Status = STATUS_FAILURE;
- goto BeceemFlashBulkWrite_EXIT;
- }
- }
- }
- } else {
- if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
- if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) {
- Status = STATUS_FAILURE;
- goto BeceemFlashBulkWrite_EXIT;
- }
- }
- }
- }
+
+ if (STATUS_FAILURE == bulk_read_complete_sector(Adapter,
+ ucReadBk,
+ pTempBuff,
+ uiOffsetFromSectStart,
+ uiPartOffset)) {
+ Status = STATUS_FAILURE;
+ goto BeceemFlashBulkWrite_EXIT;
}
+
/* do_gettimeofday(&twv);
* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000));
*/
@@ -1868,6 +1914,7 @@ int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
ULONG ulBytesTobeSkipped = 0;
PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */
+
uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
uiOffset += (EEPROM_CALPARAM_START - uiOffset);
@@ -2455,6 +2502,7 @@ static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
#endif
unsigned int uiFlashLayoutMajorVersion;
+
Adapter->uiFlashLayoutMinorVersion = 0;
Adapter->uiFlashLayoutMajorVersion = 0;
Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
@@ -3321,7 +3369,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti
SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
- if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) {
+ if ((SectImagePriority == 0) && IsSectionWritable(Adapter, HighestPriISO)) {
/* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
* We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
* by user
@@ -3381,7 +3429,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti
}
SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
- if (SectImagePriority <= 0) {
+ if (SectImagePriority == 0) {
/* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
* We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
* by user
@@ -3487,11 +3535,10 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
return STATUS_FAILURE;
}
- Status = BcmFlash2xBulkRead(Adapter,
- &ISOLength,
- sCopySectStrut.SrcSection,
- 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
- 4);
+ Status = BcmFlash2xBulkRead(Adapter, &ISOLength,
+ sCopySectStrut.SrcSection,
+ 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
+ 4);
if (Status) {
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
return Status;
@@ -3591,7 +3638,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
if (IsThisHeaderSector == TRUE) {
/* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
- memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+ memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
for (i = 0; i < MAX_RW_SIZE; i++)
*(Buff + sigOffset + i) = 0xFF;
@@ -3704,7 +3751,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section
if (IsThisHeaderSector == TRUE) {
/* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
- memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+ memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
for (i = 0; i < MAX_RW_SIZE; i++)
*(Buff + sigOffset + i) = 0xFF;
@@ -4319,6 +4366,7 @@ static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_s
static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
unsigned int ISOPri = STATUS_FAILURE;
+
if (IsSectionWritable(Adapter, iso)) {
if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
BcmFlash2xBulkRead(Adapter,
diff --git a/drivers/staging/board/Kconfig b/drivers/staging/board/Kconfig
new file mode 100644
index 000000000000..7eda0b8b7aab
--- /dev/null
+++ b/drivers/staging/board/Kconfig
@@ -0,0 +1,9 @@
+config STAGING_BOARD
+ boolean "Staging Board Support"
+ depends on OF_ADDRESS
+ depends on BROKEN
+ help
+ Select to enable per-board staging support code.
+
+ If in doubt, say N here.
+
diff --git a/drivers/staging/board/Makefile b/drivers/staging/board/Makefile
new file mode 100644
index 000000000000..65d39ecfad63
--- /dev/null
+++ b/drivers/staging/board/Makefile
@@ -0,0 +1,2 @@
+obj-y := board.o
+obj-$(CONFIG_ARCH_EMEV2) += kzm9d.o
diff --git a/drivers/staging/board/TODO b/drivers/staging/board/TODO
new file mode 100644
index 000000000000..8db70e10aa67
--- /dev/null
+++ b/drivers/staging/board/TODO
@@ -0,0 +1,2 @@
+* replace platform device code with DT nodes once the driver supports DT
+* remove staging board code when no more platform devices are needed
diff --git a/drivers/staging/board/board.c b/drivers/staging/board/board.c
new file mode 100644
index 000000000000..6050fbdfd31f
--- /dev/null
+++ b/drivers/staging/board/board.c
@@ -0,0 +1,41 @@
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include "board.h"
+
+static bool find_by_address(u64 base_address)
+{
+ struct device_node *dn = of_find_all_nodes(NULL);
+ struct resource res;
+
+ while (dn) {
+ if (of_can_translate_address(dn)
+ && !of_address_to_resource(dn, 0, &res)) {
+ if (res.start == base_address) {
+ of_node_put(dn);
+ return true;
+ }
+ }
+ dn = of_find_all_nodes(dn);
+ }
+
+ return false;
+}
+
+bool __init board_staging_dt_node_available(const struct resource *resource,
+ unsigned int num_resources)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_resources; i++) {
+ const struct resource *r = resource + i;
+
+ if (resource_type(r) == IORESOURCE_MEM)
+ if (find_by_address(r->start))
+ return true; /* DT node available */
+ }
+
+ return false; /* Nothing found */
+}
diff --git a/drivers/staging/board/board.h b/drivers/staging/board/board.h
new file mode 100644
index 000000000000..2390ed6c31a4
--- /dev/null
+++ b/drivers/staging/board/board.h
@@ -0,0 +1,20 @@
+#ifndef __BOARD_H__
+#define __BOARD_H__
+#include <linux/init.h>
+#include <linux/of.h>
+
+bool board_staging_dt_node_available(const struct resource *resource,
+ unsigned int num_resources);
+
+#define board_staging(str, fn) \
+static int __init runtime_board_check(void) \
+{ \
+ if (of_machine_is_compatible(str)) \
+ fn(); \
+ \
+ return 0; \
+} \
+ \
+late_initcall(runtime_board_check)
+
+#endif /* __BOARD_H__ */
diff --git a/drivers/staging/board/kzm9d.c b/drivers/staging/board/kzm9d.c
new file mode 100644
index 000000000000..533f3026e17a
--- /dev/null
+++ b/drivers/staging/board/kzm9d.c
@@ -0,0 +1,19 @@
+/* Staging board support for KZM9D. Enable not-yet-DT-capable devices here. */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include "board.h"
+
+static const struct resource usbs1_res[] __initconst = {
+ DEFINE_RES_MEM(0xe2800000, 0x2000),
+ DEFINE_RES_IRQ(159),
+};
+
+static void __init kzm9d_init(void)
+{
+ if (!board_staging_dt_node_available(usbs1_res, ARRAY_SIZE(usbs1_res)))
+ platform_device_register_simple("emxx_udc", -1, usbs1_res,
+ ARRAY_SIZE(usbs1_res));
+}
+
+board_staging("renesas,kzm9d", kzm9d_init);
diff --git a/drivers/staging/ced1401/Kconfig b/drivers/staging/ced1401/Kconfig
deleted file mode 100644
index ae36d1b2ba99..000000000000
--- a/drivers/staging/ced1401/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config CED1401
- tristate "Cambridge Electronic Design 1401 USB support"
- depends on USB
- help
- This driver supports the Cambridge Electronic Design 1401 USB device
- (whatever that is.)
diff --git a/drivers/staging/ced1401/Makefile b/drivers/staging/ced1401/Makefile
deleted file mode 100644
index f0c114b2b4b9..000000000000
--- a/drivers/staging/ced1401/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-
-obj-$(CONFIG_CED1401) := cedusb.o
-cedusb-objs := usb1401.o ced_ioc.o
diff --git a/drivers/staging/ced1401/TODO b/drivers/staging/ced1401/TODO
deleted file mode 100644
index 9fd5630bdf4d..000000000000
--- a/drivers/staging/ced1401/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO:
- - coding syle fixes
- - build warning fixups
- - ioctl auditing
- - usb api auditing
- - proper USB minor number (it's stomping on an existing one right now.)
-
-Please send patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org> and Cc:
-Alois Schlögl <alois.schloegl@ist.ac.at>
-
diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c
deleted file mode 100644
index ebbc5090f219..000000000000
--- a/drivers/staging/ced1401/ced_ioc.c
+++ /dev/null
@@ -1,1494 +0,0 @@
-/* ced_ioc.c
- ioctl part of the 1401 usb device driver for linux.
- Copyright (C) 2010 Cambridge Electronic Design Ltd
- Author Greg P Smith (greg@ced.co.uk)
-
- 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-#include <linux/page-flags.h>
-#include <linux/pagemap.h>
-#include <linux/jiffies.h>
-
-#include "usb1401.h"
-
-/****************************************************************************
-** FlushOutBuff
-**
-** Empties the Output buffer and sets int lines. Used from user level only
-****************************************************************************/
-static void FlushOutBuff(DEVICE_EXTENSION *pdx)
-{
- dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n",
- __func__, pdx->sCurrentState);
- if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
- return;
- /* Kill off any pending I/O */
- /* CharSend_Cancel(pdx); */
- spin_lock_irq(&pdx->charOutLock);
- pdx->dwNumOutput = 0;
- pdx->dwOutBuffGet = 0;
- pdx->dwOutBuffPut = 0;
- spin_unlock_irq(&pdx->charOutLock);
-}
-
-/****************************************************************************
-**
-** FlushInBuff
-**
-** Empties the input buffer and sets int lines
-****************************************************************************/
-static void FlushInBuff(DEVICE_EXTENSION *pdx)
-{
- dev_dbg(&pdx->interface->dev, "%s: currentState=%d\n",
- __func__, pdx->sCurrentState);
- if (pdx->sCurrentState == U14ERR_TIME) /* Do nothing if hardware in trouble */
- return;
- /* Kill off any pending I/O */
- /* CharRead_Cancel(pDevObject); */
- spin_lock_irq(&pdx->charInLock);
- pdx->dwNumInput = 0;
- pdx->dwInBuffGet = 0;
- pdx->dwInBuffPut = 0;
- spin_unlock_irq(&pdx->charInLock);
-}
-
-/****************************************************************************
-** PutChars
-**
-** Utility routine to copy chars into the output buffer and fire them off.
-** called from user mode, holds charOutLock.
-****************************************************************************/
-static int PutChars(DEVICE_EXTENSION *pdx, const char *pCh,
- unsigned int uCount)
-{
- int iReturn;
- spin_lock_irq(&pdx->charOutLock); /* get the output spin lock */
- if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) {
- unsigned int u;
- for (u = 0; u < uCount; u++) {
- pdx->outputBuffer[pdx->dwOutBuffPut++] = pCh[u];
- if (pdx->dwOutBuffPut >= OUTBUF_SZ)
- pdx->dwOutBuffPut = 0;
- }
- pdx->dwNumOutput += uCount;
- spin_unlock_irq(&pdx->charOutLock);
- iReturn = SendChars(pdx); /* ...give a chance to transmit data */
- } else {
- iReturn = U14ERR_NOOUT; /* no room at the out (ha-ha) */
- spin_unlock_irq(&pdx->charOutLock);
- }
- return iReturn;
-}
-
-/*****************************************************************************
-** Add the data in pData (local pointer) of length n to the output buffer, and
-** trigger an output transfer if this is appropriate. User mode.
-** Holds the io_mutex
-*****************************************************************************/
-int SendString(DEVICE_EXTENSION *pdx, const char __user *pData,
- unsigned int n)
-{
- int iReturn = U14ERR_NOERROR; /* assume all will be well */
- char buffer[OUTBUF_SZ + 1]; /* space in our address space for characters */
- if (n > OUTBUF_SZ) /* check space in local buffer... */
- return U14ERR_NOOUT; /* ...too many characters */
- if (copy_from_user(buffer, pData, n))
- return -EFAULT;
- buffer[n] = 0; /* terminate for debug purposes */
-
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- if (n > 0) { /* do nothing if nowt to do! */
- dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n",
- __func__, n, buffer);
- iReturn = PutChars(pdx, buffer, n);
- }
-
- Allowi(pdx); /* make sure we have input int */
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** SendChar
-**
-** Sends a single character to the 1401. User mode, holds io_mutex.
-****************************************************************************/
-int SendChar(DEVICE_EXTENSION *pdx, char c)
-{
- int iReturn;
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- iReturn = PutChars(pdx, &c, 1);
- dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)\n", c, c);
- Allowi(pdx); /* Make sure char reads are running */
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/***************************************************************************
-**
-** Get1401State
-**
-** Retrieves state information from the 1401, adjusts the 1401 state held
-** in the device extension to indicate the current 1401 type.
-**
-** *state is updated with information about the 1401 state as returned by the
-** 1401. The low byte is a code for what 1401 is doing:
-**
-** 0 normal 1401 operation
-** 1 sending chars to host
-** 2 sending block data to host
-** 3 reading block data from host
-** 4 sending an escape sequence to the host
-** 0x80 1401 is executing self-test, in which case the upper word
-** is the last error code seen (or zero for no new error).
-**
-** *error is updated with error information if a self-test error code
-** is returned in the upper word of state.
-**
-** both state and error are set to -1 if there are comms problems, and
-** to zero if there is a simple failure.
-**
-** return error code (U14ERR_NOERROR for OK)
-*/
-int Get1401State(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error)
-{
- int nGot;
- dev_dbg(&pdx->interface->dev, "%s: entry\n", __func__);
-
- *state = 0xFFFFFFFF; /* Start off with invalid state */
- nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
- GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0,
- pdx->statBuf, sizeof(pdx->statBuf), HZ);
- if (nGot != sizeof(pdx->statBuf)) {
- dev_err(&pdx->interface->dev,
- "%s: FAILED, return code %d\n", __func__, nGot);
- pdx->sCurrentState = U14ERR_TIME; /* Indicate that things are very wrong indeed */
- *state = 0; /* Force status values to a known state */
- *error = 0;
- } else {
- int nDevice;
- dev_dbg(&pdx->interface->dev,
- "%s: Success, state: 0x%x, 0x%x\n",
- __func__, pdx->statBuf[0], pdx->statBuf[1]);
-
- *state = pdx->statBuf[0]; /* Return the state values to the calling code */
- *error = pdx->statBuf[1];
-
- nDevice = pdx->udev->descriptor.bcdDevice >> 8; /* 1401 type code value */
- switch (nDevice) { /* so we can clean up current state */
- case 0:
- pdx->sCurrentState = U14ERR_U1401;
- break;
-
- default: /* allow lots of device codes for future 1401s */
- if ((nDevice >= 1) && (nDevice <= 23))
- pdx->sCurrentState = (short)(nDevice + 6);
- else
- pdx->sCurrentState = U14ERR_ILL;
- break;
- }
- }
-
- return pdx->sCurrentState >= 0 ? U14ERR_NOERROR : pdx->sCurrentState;
-}
-
-/****************************************************************************
-** ReadWrite_Cancel
-**
-** Kills off staged read\write request from the USB if one is pending.
-****************************************************************************/
-int ReadWrite_Cancel(DEVICE_EXTENSION *pdx)
-{
- dev_dbg(&pdx->interface->dev, "%s: entry %d\n",
- __func__, pdx->bStagedUrbPending);
-#ifdef NOT_WRITTEN_YET
- int ntStatus = STATUS_SUCCESS;
- bool bResult = false;
- unsigned int i;
- /* We can fill this in when we know how we will implement the staged transfer stuff */
- spin_lock_irq(&pdx->stagedLock);
-
- if (pdx->bStagedUrbPending) { /* anything to be cancelled? May need more... */
- dev_info(&pdx->interface - dev,
- "ReadWrite_Cancel about to cancel Urb\n");
- /* Clear the staging done flag */
- /* KeClearEvent(&pdx->StagingDoneEvent); */
- USB_ASSERT(pdx->pStagedIrp != NULL);
-
- /* Release the spinlock first otherwise the completion routine may hang */
- /* on the spinlock while this function hands waiting for the event. */
- spin_unlock_irq(&pdx->stagedLock);
- bResult = IoCancelIrp(pdx->pStagedIrp); /* Actually do the cancel */
- if (bResult) {
- LARGE_INTEGER timeout;
- timeout.QuadPart = -10000000; /* Use a timeout of 1 second */
- dev_info(&pdx->interface - dev,
- "%s: about to wait till done\n", __func__);
- ntStatus =
- KeWaitForSingleObject(&pdx->StagingDoneEvent,
- Executive, KernelMode, FALSE,
- &timeout);
- } else {
- dev_info(&pdx->interface - dev,
- "%s: cancellation failed\n", __func__);
- ntStatus = U14ERR_FAIL;
- }
- USB_KdPrint(DBGLVL_DEFAULT,
- ("ReadWrite_Cancel ntStatus = 0x%x decimal %d\n",
- ntStatus, ntStatus));
- } else
- spin_unlock_irq(&pdx->stagedLock);
-
- dev_info(&pdx->interface - dev, "%s: done\n", __func__);
- return ntStatus;
-#else
- return U14ERR_NOERROR;
-#endif
-
-}
-
-/***************************************************************************
-** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or
-** a -ve error code if we failed for some reason.
-***************************************************************************/
-static int InSelfTest(DEVICE_EXTENSION *pdx, unsigned int *pState)
-{
- unsigned int state, error;
- int iReturn = Get1401State(pdx, &state, &error); /* see if in self-test */
- if (iReturn == U14ERR_NOERROR) /* if all still OK */
- iReturn = (state == (unsigned int)-1) || /* TX problem or... */
- ((state & 0xff) == 0x80); /* ...self test */
- *pState = state; /* return actual state */
- return iReturn;
-}
-
-/***************************************************************************
-** Is1401 - ALWAYS CALLED HOLDING THE io_mutex
-**
-** Tests for the current state of the 1401. Sets sCurrentState:
-**
-** U14ERR_NOIF 1401 i/f card not installed (not done here)
-** U14ERR_OFF 1401 apparently not switched on
-** U14ERR_NC 1401 appears to be not connected
-** U14ERR_ILL 1401 if it is there its not very well at all
-** U14ERR_TIME 1401 appears OK, but doesn't communicate - very bad
-** U14ERR_STD 1401 OK and ready for use
-** U14ERR_PLUS 1401+ OK and ready for use
-** U14ERR_U1401 Micro1401 OK and ready for use
-** U14ERR_POWER Power1401 OK and ready for use
-** U14ERR_U14012 Micro1401 mkII OK and ready for use
-**
-** Returns TRUE if a 1401 detected and OK, else FALSE
-****************************************************************************/
-bool Is1401(DEVICE_EXTENSION *pdx)
-{
- int iReturn;
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- ced_draw_down(pdx); /* wait for, then kill outstanding Urbs */
- FlushInBuff(pdx); /* Clear out input buffer & pipe */
- FlushOutBuff(pdx); /* Clear output buffer & pipe */
-
- /* The next call returns 0 if OK, but has returned 1 in the past, meaning that */
- /* usb_unlock_device() is needed... now it always is */
- iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface);
-
- /* release the io_mutex because if we don't, we will deadlock due to system */
- /* calls back into the driver. */
- mutex_unlock(&pdx->io_mutex); /* locked, so we will not get system calls */
- if (iReturn >= 0) { /* if we failed */
- iReturn = usb_reset_device(pdx->udev); /* try to do the reset */
- usb_unlock_device(pdx->udev); /* undo the lock */
- }
-
- mutex_lock(&pdx->io_mutex); /* hold stuff off while we wait */
- pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flag regardless! */
- if (iReturn == 0) { /* if all is OK still */
- unsigned int state;
- iReturn = InSelfTest(pdx, &state); /* see if likely in self test */
- if (iReturn > 0) { /* do we need to wait for self-test? */
- unsigned long ulTimeOut = jiffies + 30 * HZ; /* when to give up */
- while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
- schedule(); /* let other stuff run */
- iReturn = InSelfTest(pdx, &state); /* see if done yet */
- }
- }
-
- if (iReturn == 0) /* if all is OK... */
- iReturn = state == 0; /* then success is that the state is 0 */
- } else
- iReturn = 0; /* we failed */
- pdx->bForceReset = false; /* Clear forced reset flag now */
-
- return iReturn > 0;
-}
-
-/****************************************************************************
-** QuickCheck - ALWAYS CALLED HOLDING THE io_mutex
-** This is used to test for a 1401. It will try to do a quick check if all is
-** OK, that is the 1401 was OK the last time it was asked, and there is no DMA
-** in progress, and if the bTestBuff flag is set, the character buffers must be
-** empty too. If the quick check shows that the state is still the same, then
-** all is OK.
-**
-** If any of the above conditions are not met, or if the state or type of the
-** 1401 has changed since the previous test, the full Is1401 test is done, but
-** only if bCanReset is also TRUE.
-**
-** The return value is TRUE if a useable 1401 is found, FALSE if not
-*/
-bool QuickCheck(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanReset)
-{
- bool bRet = false; /* assume it will fail and we will reset */
- bool bShortTest;
-
- bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) && /* no DMA running */
- (!pdx->bForceReset) && /* Not had a real reset forced */
- (pdx->sCurrentState >= U14ERR_STD)); /* No 1401 errors stored */
-
- dev_dbg(&pdx->interface->dev,
- "%s: DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d\n",
- __func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset,
- bTestBuff, bShortTest);
-
- if ((bTestBuff) && /* Buffer check requested, and... */
- (pdx->dwNumInput || pdx->dwNumOutput)) { /* ...characters were in the buffer? */
- bShortTest = false; /* Then do the full test */
- dev_dbg(&pdx->interface->dev,
- "%s: will reset as buffers not empty\n", __func__);
- }
-
- if (bShortTest || !bCanReset) { /* Still OK to try the short test? */
- /* Always test if no reset - we want state update */
- unsigned int state, error;
- dev_dbg(&pdx->interface->dev, "%s: Get1401State\n", __func__);
- if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) { /* Check on the 1401 state */
- if ((state & 0xFF) == 0) /* If call worked, check the status value */
- bRet = true; /* If that was zero, all is OK, no reset needed */
- }
- }
-
- if (!bRet && bCanReset) { /* If all not OK, then */
- dev_info(&pdx->interface->dev, "%s: Is1401 %d %d %d %d\n",
- __func__, bShortTest, pdx->sCurrentState, bTestBuff,
- pdx->bForceReset);
- bRet = Is1401(pdx); /* do full test */
- }
-
- return bRet;
-}
-
-/****************************************************************************
-** Reset1401
-**
-** Resets the 1401 and empties the i/o buffers
-*****************************************************************************/
-int Reset1401(DEVICE_EXTENSION *pdx)
-{
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- dev_dbg(&pdx->interface->dev, "%s: About to call QuickCheck\n",
- __func__);
- QuickCheck(pdx, true, true); /* Check 1401, reset if not OK */
- mutex_unlock(&pdx->io_mutex);
- return U14ERR_NOERROR;
-}
-
-/****************************************************************************
-** GetChar
-**
-** Gets a single character from the 1401
-****************************************************************************/
-int GetChar(DEVICE_EXTENSION *pdx)
-{
- int iReturn = U14ERR_NOIN; /* assume we will get nothing */
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
-
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- Allowi(pdx); /* Make sure char reads are running */
- SendChars(pdx); /* and send any buffered chars */
-
- spin_lock_irq(&pdx->charInLock);
- if (pdx->dwNumInput > 0) { /* worth looking */
- iReturn = pdx->inputBuffer[pdx->dwInBuffGet++];
- if (pdx->dwInBuffGet >= INBUF_SZ)
- pdx->dwInBuffGet = 0;
- pdx->dwNumInput--;
- } else
- iReturn = U14ERR_NOIN; /* no input data to read */
- spin_unlock_irq(&pdx->charInLock);
-
- Allowi(pdx); /* Make sure char reads are running */
-
- mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- return iReturn;
-}
-
-/****************************************************************************
-** GetString
-**
-** Gets a string from the 1401. Returns chars up to the next CR or when
-** there are no more to read or nowhere to put them. CR is translated to
-** 0 and counted as a character. If the string does not end in a 0, we will
-** add one, if there is room, but it is not counted as a character.
-**
-** returns the count of characters (including the terminator, or 0 if none
-** or a negative error code.
-****************************************************************************/
-int GetString(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
-{
- int nAvailable; /* character in the buffer */
- int iReturn = U14ERR_NOIN;
- if (n <= 0)
- return -ENOMEM;
-
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- Allowi(pdx); /* Make sure char reads are running */
- SendChars(pdx); /* and send any buffered chars */
-
- spin_lock_irq(&pdx->charInLock);
- nAvailable = pdx->dwNumInput; /* characters available now */
- if (nAvailable > n) /* read max of space in pUser... */
- nAvailable = n; /* ...or input characters */
-
- if (nAvailable > 0) { /* worth looking? */
- char buffer[INBUF_SZ + 1]; /* space for a linear copy of data */
- int nGot = 0;
- int nCopyToUser; /* number to copy to user */
- char cData;
- do {
- cData = pdx->inputBuffer[pdx->dwInBuffGet++];
- if (cData == CR_CHAR) /* replace CR with zero */
- cData = (char)0;
-
- if (pdx->dwInBuffGet >= INBUF_SZ)
- pdx->dwInBuffGet = 0; /* wrap buffer pointer */
-
- buffer[nGot++] = cData; /* save the output */
- } while ((nGot < nAvailable) && cData);
-
- nCopyToUser = nGot; /* what to copy... */
- if (cData) { /* do we need null */
- buffer[nGot] = (char)0; /* make it tidy */
- if (nGot < n) /* if space in user buffer... */
- ++nCopyToUser; /* ...copy the 0 as well. */
- }
-
- pdx->dwNumInput -= nGot;
- spin_unlock_irq(&pdx->charInLock);
-
- dev_dbg(&pdx->interface->dev, "%s: read %d characters >%s<\n",
- __func__, nGot, buffer);
- if (copy_to_user(pUser, buffer, nCopyToUser))
- iReturn = -EFAULT;
- else
- iReturn = nGot; /* report characters read */
- } else
- spin_unlock_irq(&pdx->charInLock);
-
- Allowi(pdx); /* Make sure char reads are running */
- mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
-
- return iReturn;
-}
-
-/*******************************************************************************
-** Get count of characters in the inout buffer.
-*******************************************************************************/
-int Stat1401(DEVICE_EXTENSION *pdx)
-{
- int iReturn;
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- Allowi(pdx); /* make sure we allow pending chars */
- SendChars(pdx); /* in both directions */
- iReturn = pdx->dwNumInput; /* no lock as single read */
- mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- return iReturn;
-}
-
-/****************************************************************************
-** LineCount
-**
-** Returns the number of newline chars in the buffer. There is no need for
-** any fancy interlocks as we only read the interrupt routine data, and the
-** system is arranged so nothing can be destroyed.
-****************************************************************************/
-int LineCount(DEVICE_EXTENSION *pdx)
-{
- int iReturn = 0; /* will be count of line ends */
-
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- Allowi(pdx); /* Make sure char reads are running */
- SendChars(pdx); /* and send any buffered chars */
- spin_lock_irq(&pdx->charInLock); /* Get protection */
-
- if (pdx->dwNumInput > 0) { /* worth looking? */
- unsigned int dwIndex = pdx->dwInBuffGet; /* start at first available */
- unsigned int dwEnd = pdx->dwInBuffPut; /* Position for search end */
- do {
- if (pdx->inputBuffer[dwIndex++] == CR_CHAR)
- ++iReturn; /* inc count if CR */
-
- if (dwIndex >= INBUF_SZ) /* see if we fall off buff */
- dwIndex = 0;
- } while (dwIndex != dwEnd); /* go to last available */
- }
-
- spin_unlock_irq(&pdx->charInLock);
- dev_dbg(&pdx->interface->dev, "%s: returned %d\n", __func__, iReturn);
- mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- return iReturn;
-}
-
-/****************************************************************************
-** GetOutBufSpace
-**
-** Gets the space in the output buffer. Called from user code.
-*****************************************************************************/
-int GetOutBufSpace(DEVICE_EXTENSION *pdx)
-{
- int iReturn;
- mutex_lock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- SendChars(pdx); /* send any buffered chars */
- iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput); /* no lock needed for single read */
- dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn);
- mutex_unlock(&pdx->io_mutex); /* Protect disconnect from new i/o */
- return iReturn;
-}
-
-/****************************************************************************
-**
-** ClearArea
-**
-** Clears up a transfer area. This is always called in the context of a user
-** request, never from a call-back.
-****************************************************************************/
-int ClearArea(DEVICE_EXTENSION *pdx, int nArea)
-{
- int iReturn = U14ERR_NOERROR;
-
- if ((nArea < 0) || (nArea >= MAX_TRANSAREAS)) {
- iReturn = U14ERR_BADAREA;
- dev_err(&pdx->interface->dev, "%s: Attempt to clear area %d\n",
- __func__, nArea);
- } else {
- TRANSAREA *pTA = &pdx->rTransDef[nArea]; /* to save typing */
- if (!pTA->bUsed) /* if not used... */
- iReturn = U14ERR_NOTSET; /* ...nothing to be done */
- else {
- /* We must save the memory we return as we shouldn't mess with memory while */
- /* holding a spin lock. */
- struct page **pPages = NULL; /*save page address list*/
- int nPages = 0; /* and number of pages */
- int np;
-
- dev_dbg(&pdx->interface->dev, "%s: area %d\n",
- __func__, nArea);
- spin_lock_irq(&pdx->stagedLock);
- if ((pdx->StagedId == nArea)
- && (pdx->dwDMAFlag > MODE_CHAR)) {
- iReturn = U14ERR_UNLOCKFAIL; /* cannot delete as in use */
- dev_err(&pdx->interface->dev,
- "%s: call on area %d while active\n",
- __func__, nArea);
- } else {
- pPages = pTA->pPages; /* save page address list */
- nPages = pTA->nPages; /* and page count */
- if (pTA->dwEventSz) /* if events flagging in use */
- wake_up_interruptible(&pTA->wqEvent); /* release anything that was waiting */
-
- if (pdx->bXFerWaiting
- && (pdx->rDMAInfo.wIdent == nArea))
- pdx->bXFerWaiting = false; /* Cannot have pending xfer if area cleared */
-
- /* Clean out the TRANSAREA except for the wait queue, which is at the end */
- /* This sets bUsed to false and dwEventSz to 0 to say area not used and no events. */
- memset(pTA, 0,
- sizeof(TRANSAREA) -
- sizeof(wait_queue_head_t));
- }
- spin_unlock_irq(&pdx->stagedLock);
-
- if (pPages) { /* if we decided to release the memory */
- /* Now we must undo the pinning down of the pages. We will assume the worst and mark */
- /* all the pages as dirty. Don't be tempted to move this up above as you must not be */
- /* holding a spin lock to do this stuff as it is not atomic. */
- dev_dbg(&pdx->interface->dev, "%s: nPages=%d\n",
- __func__, nPages);
-
- for (np = 0; np < nPages; ++np) {
- if (pPages[np]) {
- SetPageDirty(pPages[np]);
- page_cache_release(pPages[np]);
- }
- }
-
- kfree(pPages);
- dev_dbg(&pdx->interface->dev,
- "%s: kfree(pPages) done\n", __func__);
- }
- }
- }
-
- return iReturn;
-}
-
-/****************************************************************************
-** SetArea
-**
-** Sets up a transfer area - the functional part. Called by both
-** SetTransfer and SetCircular.
-****************************************************************************/
-static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
- unsigned int dwLength, bool bCircular, bool bCircToHost)
-{
- /* Start by working out the page aligned start of the area and the size */
- /* of the area in pages, allowing for the start not being aligned and the */
- /* end needing to be rounded up to a page boundary. */
- unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK;
- unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
- int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
- TRANSAREA *pTA = &pdx->rTransDef[nArea]; /* to save typing */
- struct page **pPages = NULL; /* space for page tables */
- int nPages = 0; /* and number of pages */
-
- int iReturn = ClearArea(pdx, nArea); /* see if OK to use this area */
- if ((iReturn != U14ERR_NOTSET) && /* if not area unused and... */
- (iReturn != U14ERR_NOERROR)) /* ...not all OK, then... */
- return iReturn; /* ...we cannot use this area */
-
- if (!access_ok(VERIFY_WRITE, puBuf, dwLength)) /* if we cannot access the memory... */
- return -EFAULT; /* ...then we are done */
-
- /* Now allocate space to hold the page pointer and virtual address pointer tables */
- pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL);
- if (!pPages) {
- iReturn = U14ERR_NOMEMORY;
- goto error;
- }
- dev_dbg(&pdx->interface->dev, "%s: %p, length=%06x, circular %d\n",
- __func__, puBuf, dwLength, bCircular);
-
- /* To pin down user pages we must first acquire the mapping semaphore. */
- nPages = get_user_pages_fast(ulStart, len, 1, pPages);
- dev_dbg(&pdx->interface->dev, "%s: nPages = %d\n", __func__, nPages);
-
- if (nPages > 0) { /* if we succeeded */
- /* If you are tempted to use page_address (form LDD3), forget it. You MUST use */
- /* kmap() or kmap_atomic() to get a virtual address. page_address will give you */
- /* (null) or at least it does in this context with an x86 machine. */
- spin_lock_irq(&pdx->stagedLock);
- pTA->lpvBuff = puBuf; /* keep start of region (user address) */
- pTA->dwBaseOffset = ulOffset; /* save offset in first page to start of xfer */
- pTA->dwLength = dwLength; /* Size if the region in bytes */
- pTA->pPages = pPages; /* list of pages that are used by buffer */
- pTA->nPages = nPages; /* number of pages */
-
- pTA->bCircular = bCircular;
- pTA->bCircToHost = bCircToHost;
-
- pTA->aBlocks[0].dwOffset = 0;
- pTA->aBlocks[0].dwSize = 0;
- pTA->aBlocks[1].dwOffset = 0;
- pTA->aBlocks[1].dwSize = 0;
- pTA->bUsed = true; /* This is now a used block */
-
- spin_unlock_irq(&pdx->stagedLock);
- iReturn = U14ERR_NOERROR; /* say all was well */
- } else {
- iReturn = U14ERR_LOCKFAIL;
- goto error;
- }
-
- return iReturn;
-
-error:
- kfree(pPages);
- return iReturn;
-}
-
-/****************************************************************************
-** SetTransfer
-**
-** Sets up a transfer area record. If the area is already set, we attempt to
-** unset it. Unsetting will fail if the area is booked, and a transfer to that
-** area is in progress. Otherwise, we will release the area and re-assign it.
-****************************************************************************/
-int SetTransfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD)
-{
- int iReturn;
- struct transfer_area_desc td;
-
- if (copy_from_user(&td, pTD, sizeof(td)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n",
- __func__, td.wAreaNum, td.dwLength);
- /* The strange cast is done so that we don't get warnings in 32-bit linux about the size of the */
- /* pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
- /* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
- iReturn =
- SetArea(pdx, td.wAreaNum,
- (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
- false, false);
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/****************************************************************************
-** UnSetTransfer
-** Erases a transfer area record
-****************************************************************************/
-int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea)
-{
- int iReturn;
- mutex_lock(&pdx->io_mutex);
- iReturn = ClearArea(pdx, nArea);
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/****************************************************************************
-** SetEvent
-** Creates an event that we can test for based on a transfer to/from an area.
-** The area must be setup for a transfer. We attempt to simulate the Windows
-** driver behavior for events (as we don't actually use them), which is to
-** pretend that whatever the user asked for was achieved, so we return 1 if
-** try to create one, and 0 if they ask to remove (assuming all else was OK).
-****************************************************************************/
-int SetEvent(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE)
-{
- int iReturn = U14ERR_NOERROR;
- struct transfer_event te;
-
- /* get a local copy of the data */
- if (copy_from_user(&te, pTE, sizeof(te)))
- return -EFAULT;
-
- if (te.wAreaNum >= MAX_TRANSAREAS) /* the area must exist */
- return U14ERR_BADAREA;
- else {
- TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum];
- mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
- spin_lock_irq(&pdx->stagedLock);
- if (pTA->bUsed) { /* area must be in use */
- pTA->dwEventSt = te.dwStart; /* set area regions */
- pTA->dwEventSz = te.dwLength; /* set size (0 cancels it) */
- pTA->bEventToHost = te.wFlags & 1; /* set the direction */
- pTA->iWakeUp = 0; /* zero the wake up count */
- } else
- iReturn = U14ERR_NOTSET;
- spin_unlock_irq(&pdx->stagedLock);
- mutex_unlock(&pdx->io_mutex);
- }
- return iReturn ==
- U14ERR_NOERROR ? (te.iSetEvent ? 1 : U14ERR_NOERROR) : iReturn;
-}
-
-/****************************************************************************
-** WaitEvent
-** Sleep the process with a timeout waiting for an event. Returns the number
-** of times that a block met the event condition since we last cleared it or
-** 0 if timed out, or -ve error (bad area or not set, or signal).
-****************************************************************************/
-int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
-{
- int iReturn;
- if ((unsigned)nArea >= MAX_TRANSAREAS)
- return U14ERR_BADAREA;
- else {
- int iWait;
- TRANSAREA *pTA = &pdx->rTransDef[nArea];
- msTimeOut = (msTimeOut * HZ + 999) / 1000; /* convert timeout to jiffies */
-
- /* We cannot wait holding the mutex, but we check the flags while holding */
- /* it. This may well be pointless as another thread could get in between */
- /* releasing it and the wait call. However, this would have to clear the */
- /* iWakeUp flag. However, the !pTA-bUsed may help us in this case. */
- mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
- if (!pTA->bUsed || !pTA->dwEventSz) /* check something to wait for... */
- return U14ERR_NOTSET; /* ...else we do nothing */
- mutex_unlock(&pdx->io_mutex);
-
- if (msTimeOut)
- iWait =
- wait_event_interruptible_timeout(pTA->wqEvent,
- pTA->iWakeUp
- || !pTA->bUsed,
- msTimeOut);
- else
- iWait =
- wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp
- || !pTA->bUsed);
- if (iWait)
- iReturn = -ERESTARTSYS; /* oops - we have had a SIGNAL */
- else
- iReturn = pTA->iWakeUp; /* else the wakeup count */
-
- spin_lock_irq(&pdx->stagedLock);
- pTA->iWakeUp = 0; /* clear the flag */
- spin_unlock_irq(&pdx->stagedLock);
- }
- return iReturn;
-}
-
-/****************************************************************************
-** TestEvent
-** Test the event to see if a WaitEvent would return immediately. Returns the
-** number of times a block completed since the last call, or 0 if none or a
-** negative error.
-****************************************************************************/
-int TestEvent(DEVICE_EXTENSION *pdx, int nArea)
-{
- int iReturn;
- if ((unsigned)nArea >= MAX_TRANSAREAS)
- iReturn = U14ERR_BADAREA;
- else {
- TRANSAREA *pTA = &pdx->rTransDef[nArea];
- mutex_lock(&pdx->io_mutex); /* make sure we have no competitor */
- spin_lock_irq(&pdx->stagedLock);
- iReturn = pTA->iWakeUp; /* get wakeup count since last call */
- pTA->iWakeUp = 0; /* clear the count */
- spin_unlock_irq(&pdx->stagedLock);
- mutex_unlock(&pdx->io_mutex);
- }
- return iReturn;
-}
-
-/****************************************************************************
-** GetTransferInfo
-** Puts the current state of the 1401 in a TGET_TX_BLOCK.
-*****************************************************************************/
-int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
-{
- int iReturn = U14ERR_NOERROR;
- unsigned int dwIdent;
-
- mutex_lock(&pdx->io_mutex);
- dwIdent = pdx->StagedId; /* area ident for last xfer */
- if (dwIdent >= MAX_TRANSAREAS)
- iReturn = U14ERR_BADAREA;
- else {
- /* Return the best information we have - we don't have physical addresses */
- TGET_TX_BLOCK *tx;
-
- tx = kzalloc(sizeof(*tx), GFP_KERNEL);
- if (!tx) {
- mutex_unlock(&pdx->io_mutex);
- return -ENOMEM;
- }
- tx->size = pdx->rTransDef[dwIdent].dwLength;
- tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
- tx->avail = GET_TX_MAXENTRIES; /* how many blocks we could return */
- tx->used = 1; /* number we actually return */
- tx->entries[0].physical =
- (long long)(tx->linear + pdx->StagedOffset);
- tx->entries[0].size = tx->size;
-
- if (copy_to_user(pTX, tx, sizeof(*tx)))
- iReturn = -EFAULT;
- kfree(tx);
- }
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/****************************************************************************
-** KillIO1401
-**
-** Empties the host i/o buffers
-****************************************************************************/
-int KillIO1401(DEVICE_EXTENSION *pdx)
-{
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
- mutex_lock(&pdx->io_mutex);
- FlushOutBuff(pdx);
- FlushInBuff(pdx);
- mutex_unlock(&pdx->io_mutex);
- return U14ERR_NOERROR;
-}
-
-/****************************************************************************
-** BlkTransState
-** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex
-** for this as it only does one read.
-*****************************************************************************/
-int BlkTransState(DEVICE_EXTENSION *pdx)
-{
- int iReturn = pdx->dwDMAFlag != MODE_CHAR;
- dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn);
- return iReturn;
-}
-
-/****************************************************************************
-** StateOf1401
-**
-** Puts the current state of the 1401 in the Irp return buffer.
-*****************************************************************************/
-int StateOf1401(DEVICE_EXTENSION *pdx)
-{
- int iReturn;
- mutex_lock(&pdx->io_mutex);
-
- QuickCheck(pdx, false, false); /* get state up to date, no reset */
- iReturn = pdx->sCurrentState;
-
- mutex_unlock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: %d\n", __func__, iReturn);
-
- return iReturn;
-}
-
-/****************************************************************************
-** StartSelfTest
-**
-** Initiates a self-test cycle. The assumption is that we have no interrupts
-** active, so we should make sure that this is the case.
-*****************************************************************************/
-int StartSelfTest(DEVICE_EXTENSION *pdx)
-{
- int nGot;
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- ced_draw_down(pdx); /* wait for, then kill outstanding Urbs */
- FlushInBuff(pdx); /* Clear out input buffer & pipe */
- FlushOutBuff(pdx); /* Clear output buffer & pipe */
- /* so things stay tidy */
- /* ReadWrite_Cancel(pDeviceObject); */
- pdx->dwDMAFlag = MODE_CHAR; /* Clear DMA mode flags here */
-
- nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
- DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ),
- 0, 0, NULL, 0, HZ); /* allow 1 second timeout */
- pdx->ulSelfTestTime = jiffies + HZ * 30; /* 30 seconds into the future */
-
- mutex_unlock(&pdx->io_mutex);
- if (nGot < 0)
- dev_err(&pdx->interface->dev, "%s: err=%d\n", __func__, nGot);
- return nGot < 0 ? U14ERR_FAIL : U14ERR_NOERROR;
-}
-
-/****************************************************************************
-** CheckSelfTest
-**
-** Check progress of a self-test cycle
-****************************************************************************/
-int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST)
-{
- unsigned int state, error;
- int iReturn;
- TGET_SELFTEST gst; /* local work space */
- memset(&gst, 0, sizeof(gst)); /* clear out the space (sets code 0) */
-
- mutex_lock(&pdx->io_mutex);
-
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
- iReturn = Get1401State(pdx, &state, &error);
- if (iReturn == U14ERR_NOERROR) /* Only accept zero if it happens twice */
- iReturn = Get1401State(pdx, &state, &error);
-
- if (iReturn != U14ERR_NOERROR) { /* Self-test can cause comms errors */
- /* so we assume still testing */
- dev_err(&pdx->interface->dev,
- "%s: Get1401State=%d, assuming still testing\n",
- __func__, iReturn);
- state = 0x80; /* Force still-testing, no error */
- error = 0;
- iReturn = U14ERR_NOERROR;
- }
-
- if ((state == -1) && (error == -1)) { /* If Get1401State had problems */
- dev_err(&pdx->interface->dev,
- "%s: Get1401State failed, assuming still testing\n",
- __func__);
- state = 0x80; /* Force still-testing, no error */
- error = 0;
- }
-
- if ((state & 0xFF) == 0x80) { /* If we are still in self-test */
- if (state & 0x00FF0000) { /* Have we got an error? */
- gst.code = (state & 0x00FF0000) >> 16; /* read the error code */
- gst.x = error & 0x0000FFFF; /* Error data X */
- gst.y = (error & 0xFFFF0000) >> 16; /* and data Y */
- dev_dbg(&pdx->interface->dev,
- "Self-test error code %d\n", gst.code);
- } else { /* No error, check for timeout */
- unsigned long ulNow = jiffies; /* get current time */
- if (time_after(ulNow, pdx->ulSelfTestTime)) {
- gst.code = -2; /* Flag the timeout */
- dev_dbg(&pdx->interface->dev,
- "Self-test timed-out\n");
- } else
- dev_dbg(&pdx->interface->dev,
- "Self-test on-going\n");
- }
- } else {
- gst.code = -1; /* Flag the test is done */
- dev_dbg(&pdx->interface->dev, "Self-test done\n");
- }
-
- if (gst.code < 0) { /* If we have a problem or finished */
- /* If using the 2890 we should reset properly */
- if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER))
- Is1401(pdx); /* Get 1401 reset and OK */
- else
- QuickCheck(pdx, true, true); /* Otherwise check without reset unless problems */
- }
- mutex_unlock(&pdx->io_mutex);
-
- if (copy_to_user(pGST, &gst, sizeof(gst)))
- return -EFAULT;
-
- return iReturn;
-}
-
-/****************************************************************************
-** TypeOf1401
-**
-** Returns code for standard, plus, micro1401, power1401 or none
-****************************************************************************/
-int TypeOf1401(DEVICE_EXTENSION *pdx)
-{
- int iReturn = TYPEUNKNOWN;
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- switch (pdx->s1401Type) {
- case TYPE1401:
- iReturn = U14ERR_STD;
- break; /* Handle these types directly */
- case TYPEPLUS:
- iReturn = U14ERR_PLUS;
- break;
- case TYPEU1401:
- iReturn = U14ERR_U1401;
- break;
- default:
- if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25))
- iReturn = pdx->s1401Type + 4; /* We can calculate types */
- else /* for up-coming 1401 designs */
- iReturn = TYPEUNKNOWN; /* Don't know or not there */
- }
- dev_dbg(&pdx->interface->dev, "%s %d\n", __func__, iReturn);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** TransferFlags
-**
-** Returns flags on block transfer abilities
-****************************************************************************/
-int TransferFlags(DEVICE_EXTENSION *pdx)
-{
- int iReturn = U14TF_MULTIA | U14TF_DIAG | /* we always have multiple DMA area */
- U14TF_NOTIFY | U14TF_CIRCTH; /* diagnostics, notify and circular */
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
- mutex_lock(&pdx->io_mutex);
- if (pdx->bIsUSB2) /* Set flag for USB2 if appropriate */
- iReturn |= U14TF_USB2;
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/***************************************************************************
-** DbgCmd1401
-** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum
-** This is a utility command used for dbg operations.
-*/
-static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd,
- unsigned int data)
-{
- int iReturn;
- dev_dbg(&pdx->interface->dev, "%s: entry\n", __func__);
- iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd,
- (H_TO_D | VENDOR | DEVREQ),
- (unsigned short)data,
- (unsigned short)(data >> 16), NULL, 0, HZ);
- /* allow 1 second timeout */
- if (iReturn < 0)
- dev_err(&pdx->interface->dev, "%s: fail code=%d\n",
- __func__, iReturn);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgPeek
-**
-** Execute the diagnostic peek operation. Uses address, width and repeats.
-****************************************************************************/
-int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
-{
- int iReturn;
- TDBGBLOCK db;
-
- if (copy_from_user(&db, pDB, sizeof(db)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
-
- iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_PEEK, 0);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgPoke
-**
-** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct
-** in order address, size, repeats and value to poke.
-****************************************************************************/
-int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
-{
- int iReturn;
- TDBGBLOCK db;
-
- if (copy_from_user(&db, pDB, sizeof(db)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
-
- iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_POKE, db.iData);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgRampData
-**
-** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct
-** in order address, default, enable mask, size and repeats.
-****************************************************************************/
-int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
-{
- int iReturn;
- TDBGBLOCK db;
-
- if (copy_from_user(&db, pDB, sizeof(db)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: @ %08x\n", __func__, db.iAddr);
-
- iReturn = DbgCmd1401(pdx, DB_SETADD, db.iAddr);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_RAMPD, 0);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgRampAddr
-**
-** Execute the diagnostic ramp address operation
-****************************************************************************/
-int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
-{
- int iReturn;
- TDBGBLOCK db;
-
- if (copy_from_user(&db, pDB, sizeof(db)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- iReturn = DbgCmd1401(pdx, DB_SETDEF, db.iDefault);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_SETMASK, db.iMask);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_WIDTH, db.iWidth);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_REPEATS, db.iRepeats);
- if (iReturn == U14ERR_NOERROR)
- iReturn = DbgCmd1401(pdx, DB_RAMPA, 0);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgGetData
-**
-** Retrieve the data resulting from the last debug Peek operation
-****************************************************************************/
-int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
-{
- int iReturn;
- TDBGBLOCK db;
- memset(&db, 0, sizeof(db)); /* fill returned block with 0s */
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- /* Read back the last peeked value from the 1401. */
- iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
- DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0,
- &db.iData, sizeof(db.iData), HZ);
- if (iReturn == sizeof(db.iData)) {
- if (copy_to_user(pDB, &db, sizeof(db)))
- iReturn = -EFAULT;
- else
- iReturn = U14ERR_NOERROR;
- } else
- dev_err(&pdx->interface->dev, "%s: failed, code %d\n",
- __func__, iReturn);
-
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** DbgStopLoop
-**
-** Stop any never-ending debug loop, we just call Get1401State for USB
-**
-****************************************************************************/
-int DbgStopLoop(DEVICE_EXTENSION *pdx)
-{
- int iReturn;
- unsigned int uState, uErr;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
- iReturn = Get1401State(pdx, &uState, &uErr);
- mutex_unlock(&pdx->io_mutex);
-
- return iReturn;
-}
-
-/****************************************************************************
-** SetCircular
-**
-** Sets up a transfer area record for circular transfers. If the area is
-** already set, we attempt to unset it. Unsetting will fail if the area is
-** booked and a transfer to that area is in progress. Otherwise, we will
-** release the area and re-assign it.
-****************************************************************************/
-int SetCircular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD)
-{
- int iReturn;
- bool bToHost;
- struct transfer_area_desc td;
-
- if (copy_from_user(&td, pTD, sizeof(td)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: area:%d, size:%08x\n",
- __func__, td.wAreaNum, td.dwLength);
- bToHost = td.eSize != 0; /* this is used as the tohost flag */
-
- /* The strange cast is done so that we don't get warnings in 32-bit linux about the size of the */
- /* pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
- /* a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
- iReturn =
- SetArea(pdx, td.wAreaNum,
- (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
- true, bToHost);
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/****************************************************************************
-** GetCircBlock
-**
-** Return the next available block of circularly-transferred data.
-****************************************************************************/
-int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
-{
- int iReturn = U14ERR_NOERROR;
- unsigned int nArea;
- TCIRCBLOCK cb;
-
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- if (copy_from_user(&cb, pCB, sizeof(cb)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
-
- nArea = cb.nArea; /* Retrieve parameters first */
- cb.dwOffset = 0; /* set default result (nothing) */
- cb.dwSize = 0;
-
- if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */
- TRANSAREA *pArea = &pdx->rTransDef[nArea]; /* Pointer to relevant info */
- spin_lock_irq(&pdx->stagedLock); /* Lock others out */
-
- if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
- (pArea->bCircToHost)) { /* For now at least must be to host */
- if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
- cb.dwOffset = pArea->aBlocks[0].dwOffset;
- cb.dwSize = pArea->aBlocks[0].dwSize;
- dev_dbg(&pdx->interface->dev,
- "%s: return block 0: %d bytes at %d\n",
- __func__, cb.dwSize, cb.dwOffset);
- }
- } else
- iReturn = U14ERR_NOTSET;
-
- spin_unlock_irq(&pdx->stagedLock);
- } else
- iReturn = U14ERR_BADAREA;
-
- if (copy_to_user(pCB, &cb, sizeof(cb)))
- iReturn = -EFAULT;
-
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
-
-/****************************************************************************
-** FreeCircBlock
-**
-** Frees a block of circularly-transferred data and returns the next one.
-****************************************************************************/
-int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
-{
- int iReturn = U14ERR_NOERROR;
- unsigned int nArea, uStart, uSize;
- TCIRCBLOCK cb;
-
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- if (copy_from_user(&cb, pCB, sizeof(cb)))
- return -EFAULT;
-
- mutex_lock(&pdx->io_mutex);
-
- nArea = cb.nArea; /* Retrieve parameters first */
- uStart = cb.dwOffset;
- uSize = cb.dwSize;
- cb.dwOffset = 0; /* then set default result (nothing) */
- cb.dwSize = 0;
-
- if (nArea < MAX_TRANSAREAS) { /* The area number must be OK */
- TRANSAREA *pArea = &pdx->rTransDef[nArea]; /* Pointer to relevant info */
- spin_lock_irq(&pdx->stagedLock); /* Lock others out */
-
- if ((pArea->bUsed) && (pArea->bCircular) && /* Must be circular area */
- (pArea->bCircToHost)) { /* For now at least must be to host */
- bool bWaiting = false;
-
- if ((pArea->aBlocks[0].dwSize >= uSize) && /* Got anything? */
- (pArea->aBlocks[0].dwOffset == uStart)) { /* Must be legal data */
- pArea->aBlocks[0].dwSize -= uSize;
- pArea->aBlocks[0].dwOffset += uSize;
- if (pArea->aBlocks[0].dwSize == 0) { /* Have we emptied this block? */
- if (pArea->aBlocks[1].dwSize) { /* Is there a second block? */
- pArea->aBlocks[0] = pArea->aBlocks[1]; /* Copy down block 2 data */
- pArea->aBlocks[1].dwSize = 0; /* and mark the second block as unused */
- pArea->aBlocks[1].dwOffset = 0;
- } else
- pArea->aBlocks[0].dwOffset = 0;
- }
-
- dev_dbg(&pdx->interface->dev,
- "%s: free %d bytes at %d, return %d bytes at %d, wait=%d\n",
- __func__, uSize, uStart,
- pArea->aBlocks[0].dwSize,
- pArea->aBlocks[0].dwOffset,
- pdx->bXFerWaiting);
-
- /* Return the next available block of memory as well */
- if (pArea->aBlocks[0].dwSize > 0) { /* Got anything? */
- cb.dwOffset =
- pArea->aBlocks[0].dwOffset;
- cb.dwSize = pArea->aBlocks[0].dwSize;
- }
-
- bWaiting = pdx->bXFerWaiting;
- if (bWaiting && pdx->bStagedUrbPending) {
- dev_err(&pdx->interface->dev,
- "%s: ERROR: waiting xfer and staged Urb pending!\n",
- __func__);
- bWaiting = false;
- }
- } else {
- dev_err(&pdx->interface->dev,
- "%s: ERROR: freeing %d bytes at %d, block 0 is %d bytes at %d\n",
- __func__, uSize, uStart,
- pArea->aBlocks[0].dwSize,
- pArea->aBlocks[0].dwOffset);
- iReturn = U14ERR_NOMEMORY;
- }
-
- /* If we have one, kick off pending transfer */
- if (bWaiting) { /* Got a block xfer waiting? */
- int RWMStat =
- ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
- pdx->rDMAInfo.wIdent,
- pdx->rDMAInfo.dwOffset,
- pdx->rDMAInfo.dwSize);
- if (RWMStat != U14ERR_NOERROR)
- dev_err(&pdx->interface->dev,
- "%s: rw setup failed %d\n",
- __func__, RWMStat);
- }
- } else
- iReturn = U14ERR_NOTSET;
-
- spin_unlock_irq(&pdx->stagedLock);
- } else
- iReturn = U14ERR_BADAREA;
-
- if (copy_to_user(pCB, &cb, sizeof(cb)))
- iReturn = -EFAULT;
-
- mutex_unlock(&pdx->io_mutex);
- return iReturn;
-}
diff --git a/drivers/staging/ced1401/ced_ioctl.h b/drivers/staging/ced1401/ced_ioctl.h
deleted file mode 100644
index 4b6c9dedb21e..000000000000
--- a/drivers/staging/ced1401/ced_ioctl.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * IOCTL calls for the CED1401 driver
- * Copyright (C) 2010 Cambridge Electronic Design Ltd
- * Author Greg P Smith (greg@ced.co.uk)
- *
- * 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 __CED_IOCTL_H__
-#define __CED_IOCTL_H__
-
-#include <linux/ioctl.h>
-
-/* dma modes, only MODE_CHAR and MODE_LINEAR are used in this driver */
-#define MODE_CHAR 0
-#define MODE_LINEAR 1
-
-/****************************************************************************
-** TypeDefs
-*****************************************************************************/
-
-struct transfer_area_desc {
- long long lpvBuff; /* address of transfer area (for 64 or 32 bit) */
- unsigned int dwLength; /* length of the area */
- unsigned short wAreaNum; /* number of transfer area to set up */
- short eSize; /* element size - is tohost flag for circular */
-};
-
-
-struct transfer_event {
- unsigned int dwStart; /* offset into the area */
- unsigned int dwLength; /* length of the region */
- unsigned short wAreaNum; /* the area number */
- unsigned short wFlags; /* bit 0 set for toHost */
- int iSetEvent; /* could be dummy in LINUX */
-};
-
-#define MAX_TRANSFER_SIZE 0x4000 /* Maximum data bytes per IRP */
-#define MAX_AREA_LENGTH 0x100000 /* Maximum size of transfer area */
-#define MAX_TRANSAREAS 8 /* definitions for dma set up */
-
-typedef struct TGetSelfTest {
- int code; /* self-test error code */
- int x, y; /* additional information */
-} TGET_SELFTEST;
-
-/* Debug block used for several commands. Not all fields are used for all commands. */
-typedef struct TDbgBlock {
- int iAddr; /* the address in the 1401 */
- int iRepeats; /* number of repeats */
- int iWidth; /* width in bytes 1, 2, 4 */
- int iDefault; /* default value */
- int iMask; /* mask to apply */
- int iData; /* data for poke, result for peek */
-} TDBGBLOCK;
-
-/* Used to collect information about a circular block from the device driver */
-typedef struct TCircBlock {
- unsigned int nArea; /* the area to collect information from */
- unsigned int dwOffset; /* offset into the area to the available block */
- unsigned int dwSize; /* size of the area */
-} TCIRCBLOCK;
-
-/* Used to clollect the 1401 status */
-typedef struct TCSBlock {
- unsigned int uiState;
- unsigned int uiError;
-} TCSBLOCK;
-
-/*
- * As seen by the user, an ioctl call looks like: int ioctl(int fd, unsigned
- * long cmd, char* argp); We will then have all sorts of variants on this that
- * can be used to pass stuff to our driver. We will generate macros for each
- * type of call so as to provide some sort of type safety in the calling:
- */
-#define CED_MAGIC_IOC 0xce
-
-#define IOCTL_CED_SENDSTRING(n) _IOC(_IOC_WRITE, CED_MAGIC_IOC, 2, n)
-
-#define IOCTL_CED_RESET1401 _IO(CED_MAGIC_IOC, 3)
-#define IOCTL_CED_GETCHAR _IO(CED_MAGIC_IOC, 4)
-#define IOCTL_CED_SENDCHAR _IO(CED_MAGIC_IOC, 5)
-#define IOCTL_CED_STAT1401 _IO(CED_MAGIC_IOC, 6)
-#define IOCTL_CED_LINECOUNT _IO(CED_MAGIC_IOC, 7)
-#define IOCTL_CED_GETSTRING(nMax) _IOC(_IOC_READ, CED_MAGIC_IOC, 8, nMax)
-
-#define IOCTL_CED_SETTRANSFER _IOW(CED_MAGIC_IOC, 11, struct transfer_area_desc)
-#define IOCTL_CED_UNSETTRANSFER _IO(CED_MAGIC_IOC, 12)
-#define IOCTL_CED_SETEVENT _IOW(CED_MAGIC_IOC, 13, struct transfer_event)
-#define IOCTL_CED_GETOUTBUFSPACE _IO(CED_MAGIC_IOC, 14)
-#define IOCTL_CED_GETBASEADDRESS _IO(CED_MAGIC_IOC, 15)
-#define IOCTL_CED_GETDRIVERREVISION _IO(CED_MAGIC_IOC, 16)
-
-#define IOCTL_CED_GETTRANSFER _IOR(CED_MAGIC_IOC, 17, TGET_TX_BLOCK)
-#define IOCTL_CED_KILLIO1401 _IO(CED_MAGIC_IOC, 18)
-#define IOCTL_CED_BLKTRANSSTATE _IO(CED_MAGIC_IOC, 19)
-
-#define IOCTL_CED_STATEOF1401 _IO(CED_MAGIC_IOC, 23)
-#define IOCTL_CED_GRAB1401 _IO(CED_MAGIC_IOC, 25)
-#define IOCTL_CED_FREE1401 _IO(CED_MAGIC_IOC, 26)
-#define IOCTL_CED_STARTSELFTEST _IO(CED_MAGIC_IOC, 31)
-#define IOCTL_CED_CHECKSELFTEST _IOR(CED_MAGIC_IOC, 32, TGET_SELFTEST)
-#define IOCTL_CED_TYPEOF1401 _IO(CED_MAGIC_IOC, 33)
-#define IOCTL_CED_TRANSFERFLAGS _IO(CED_MAGIC_IOC, 34)
-
-#define IOCTL_CED_DBGPEEK _IOW(CED_MAGIC_IOC, 35, TDBGBLOCK)
-#define IOCTL_CED_DBGPOKE _IOW(CED_MAGIC_IOC, 36, TDBGBLOCK)
-#define IOCTL_CED_DBGRAMPDATA _IOW(CED_MAGIC_IOC, 37, TDBGBLOCK)
-#define IOCTL_CED_DBGRAMPADDR _IOW(CED_MAGIC_IOC, 38, TDBGBLOCK)
-#define IOCTL_CED_DBGGETDATA _IOR(CED_MAGIC_IOC, 39, TDBGBLOCK)
-#define IOCTL_CED_DBGSTOPLOOP _IO(CED_MAGIC_IOC, 40)
-#define IOCTL_CED_FULLRESET _IO(CED_MAGIC_IOC, 41)
-#define IOCTL_CED_SETCIRCULAR _IOW(CED_MAGIC_IOC, 42, struct transfer_area_desc)
-#define IOCTL_CED_GETCIRCBLOCK _IOWR(CED_MAGIC_IOC, 43, TCIRCBLOCK)
-#define IOCTL_CED_FREECIRCBLOCK _IOWR(CED_MAGIC_IOC, 44, TCIRCBLOCK)
-#define IOCTL_CED_WAITEVENT _IO(CED_MAGIC_IOC, 45)
-#define IOCTL_CED_TESTEVENT _IO(CED_MAGIC_IOC, 46)
-
-#ifndef __KERNEL__
-/*
- * If nothing said about return value, it is a U14ERR_... error code
- * (U14ERR_NOERROR for none)
- */
-inline int CED_SendString(int fh, const char *szText, int n)
-{
- return ioctl(fh, IOCTL_CED_SENDSTRING(n), szText);
-}
-
-inline int CED_Reset1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_RESET1401);
-}
-
-/* Return the singe character or a -ve error code. */
-inline int CED_GetChar(int fh)
-{
- return ioctl(fh, IOCTL_CED_GETCHAR);
-}
-
-/* Return character count in input buffer */
-inline int CED_Stat1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_STAT1401);
-}
-
-inline int CED_SendChar(int fh, char c)
-{
- return ioctl(fh, IOCTL_CED_SENDCHAR, c);
-}
-
-inline int CED_LineCount(int fh)
-{
- return ioctl(fh, IOCTL_CED_LINECOUNT);
-}
-
-/*
- * return the count of characters returned. If the string was terminated by CR
- * or 0, then the 0 is part of the count. Otherwise, we will add a zero if
- * there is room, but it is not included in the count. The return value is 0
- * if there was nothing to read.
- */
-inline int CED_GetString(int fh, char *szText, int nMax)
-{
- return ioctl(fh, IOCTL_CED_GETSTRING(nMax), szText);
-}
-
-/* returns space in the output buffer. */
-inline int CED_GetOutBufSpace(int fh)
-{
- return ioctl(fh, IOCTL_CED_GETOUTBUFSPACE);
-}
-
-/* This always returns -1 as not implemented. */
-inline int CED_GetBaseAddress(int fh)
-{
- return ioctl(fh, IOCTL_CED_GETBASEADDRESS);
-}
-
-/* returns the major revision <<16 | minor revision. */
-inline int CED_GetDriverRevision(int fh)
-{
- return ioctl(fh, IOCTL_CED_GETDRIVERREVISION);
-}
-
-inline int CED_SetTransfer(int fh, struct transfer_area_desc *pTD)
-{
- return ioctl(fh, IOCTL_CED_SETTRANSFER, pTD);
-}
-
-inline int CED_UnsetTransfer(int fh, int nArea)
-{
- return ioctl(fh, IOCTL_CED_UNSETTRANSFER, nArea);
-}
-
-inline int CED_SetEvent(int fh, struct transfer_event *pTE)
-{
- return ioctl(fh, IOCTL_CED_SETEVENT, pTE);
-}
-
-inline int CED_GetTransfer(int fh, TGET_TX_BLOCK *pTX)
-{
- return ioctl(fh, IOCTL_CED_GETTRANSFER, pTX);
-}
-
-inline int CED_KillIO1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_KILLIO1401);
-}
-
-/* returns 0 if no active DMA, 1 if active */
-inline int CED_BlkTransState(int fh)
-{
- return ioctl(fh, IOCTL_CED_BLKTRANSSTATE);
-}
-
-inline int CED_StateOf1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_STATEOF1401);
-}
-
-inline int CED_Grab1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_GRAB1401);
-}
-
-inline int CED_Free1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_FREE1401);
-}
-
-inline int CED_StartSelfTest(int fh)
-{
- return ioctl(fh, IOCTL_CED_STARTSELFTEST);
-}
-
-inline int CED_CheckSelfTest(int fh, TGET_SELFTEST *pGST)
-{
- return ioctl(fh, IOCTL_CED_CHECKSELFTEST, pGST);
-}
-
-inline int CED_TypeOf1401(int fh)
-{
- return ioctl(fh, IOCTL_CED_TYPEOF1401);
-}
-
-inline int CED_TransferFlags(int fh)
-{
- return ioctl(fh, IOCTL_CED_TRANSFERFLAGS);
-}
-
-inline int CED_DbgPeek(int fh, TDBGBLOCK *pDB)
-{
- return ioctl(fh, IOCTL_CED_DBGPEEK, pDB);
-}
-
-inline int CED_DbgPoke(int fh, TDBGBLOCK *pDB)
-{
- return ioctl(fh, IOCTL_CED_DBGPOKE, pDB);
-}
-
-inline int CED_DbgRampData(int fh, TDBGBLOCK *pDB)
-{
- return ioctl(fh, IOCTL_CED_DBGRAMPDATA, pDB);
-}
-
-inline int CED_DbgRampAddr(int fh, TDBGBLOCK *pDB)
-{
- return ioctl(fh, IOCTL_CED_DBGRAMPADDR, pDB);
-}
-
-inline int CED_DbgGetData(int fh, TDBGBLOCK *pDB)
-{
- return ioctl(fh, IOCTL_CED_DBGGETDATA, pDB);
-}
-
-inline int CED_DbgStopLoop(int fh)
-{
- return ioctl(fh, IOCTL_CED_DBGSTOPLOOP);
-}
-
-inline int CED_FullReset(int fh)
-{
- return ioctl(fh, IOCTL_CED_FULLRESET);
-}
-
-inline int CED_SetCircular(int fh, struct transfer_area_desc *pTD)
-{
- return ioctl(fh, IOCTL_CED_SETCIRCULAR, pTD);
-}
-
-inline int CED_GetCircBlock(int fh, TCIRCBLOCK *pCB)
-{
- return ioctl(fh, IOCTL_CED_GETCIRCBLOCK, pCB);
-}
-
-inline int CED_FreeCircBlock(int fh, TCIRCBLOCK *pCB)
-{
- return ioctl(fh, IOCTL_CED_FREECIRCBLOCK, pCB);
-}
-
-inline int CED_WaitEvent(int fh, int nArea, int msTimeOut)
-{
- return ioctl(fh, IOCTL_CED_WAITEVENT, (nArea & 0xff)|(msTimeOut << 8));
-}
-
-inline int CED_TestEvent(int fh, int nArea)
-{
- return ioctl(fh, IOCTL_CED_TESTEVENT, nArea);
-}
-#endif
-
-#ifdef NOTWANTEDYET
-#define IOCTL_CED_REGCALLBACK _IO(CED_MAGIC_IOC, 9) /* Not used */
-#define IOCTL_CED_GETMONITORBUF _IO(CED_MAGIC_IOC, 10) /* Not used */
-
-#define IOCTL_CED_BYTECOUNT _IO(CED_MAGIC_IOC, 20) /* Not used */
-#define IOCTL_CED_ZEROBLOCKCOUNT _IO(CED_MAGIC_IOC, 21) /* Not used */
-#define IOCTL_CED_STOPCIRCULAR _IO(CED_MAGIC_IOC, 22) /* Not used */
-
-#define IOCTL_CED_REGISTERS1401 _IO(CED_MAGIC_IOC, 24) /* Not used */
-#define IOCTL_CED_STEP1401 _IO(CED_MAGIC_IOC, 27) /* Not used */
-#define IOCTL_CED_SET1401REGISTERS _IO(CED_MAGIC_IOC, 28) /* Not used */
-#define IOCTL_CED_STEPTILL1401 _IO(CED_MAGIC_IOC, 29) /* Not used */
-#define IOCTL_CED_SETORIN _IO(CED_MAGIC_IOC, 30) /* Not used */
-
-#endif
-
-/* __CED_IOCTL_H__ */
-#endif
diff --git a/drivers/staging/ced1401/machine.h b/drivers/staging/ced1401/machine.h
deleted file mode 100644
index dbd4036d9bdd..000000000000
--- a/drivers/staging/ced1401/machine.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*****************************************************************************
-**
-** machine.h
-**
-** Copyright (c) Cambridge Electronic Design Limited 1991,1992,2010
-**
-** 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**
-** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road
-** Cambridge, CB6 0FE.
-** www.ced.co.uk
-** greg@ced.co.uk
-**
-** This file is included at the start of 'C' or 'C++' source file to define
-** things for cross-platform/compiler interoperability. This used to deal with
-** MSDOS/16-bit stuff, but this was all removed in Decemeber 2010. There are
-** three things to consider: Windows, LINUX, mac OSX (BSD Unix) and 32 vs 64
-** bit. At the time of writing (DEC 2010) there is a consensus on the following
-** and their unsigned equivalents:
-**
-** type bits
-** char 8
-** short 16
-** int 32
-** long long 64
-**
-** long is a problem as it is always 64 bits on linux/unix and is always 32 bits
-** on windows.
-** On windows, we define _IS_WINDOWS_ and one of WIN32 or WIN64.
-** On linux we define LINUX
-** On Max OSX we define MACOSX
-**
-*/
-
-#ifndef __MACHINE_H__
-#define __MACHINE_H__
-#ifndef __KERNEL__
-#include <float.h>
-#include <limits.h>
-#endif
-
-/*
-** The initial section is to identify the operating system
-*/
-#if (defined(__linux__) || defined(_linux) || defined(__linux)) && !defined(LINUX)
-#define LINUX 1
-#endif
-
-#if (defined(__WIN32__) || defined(_WIN32)) && !defined(WIN32)
-#define WIN32 1
-#endif
-
-#if defined(__APPLE__)
-#define MACOSX
-#endif
-
-#if defined(_WIN64)
-#undef WIN32
-#undef WIN64
-#define WIN64 1
-#endif
-
-#if defined(WIN32) || defined(WIN64)
-#define _IS_WINDOWS_ 1
-#endif
-
-#if defined(LINUX) || defined(MAXOSX)
- #define FAR
-
- typedef int BOOL; /* To match Windows */
- typedef unsigned char BYTE;
- #define __packed __attribute__((packed))
- #define HIWORD(x) (unsigned short)(((x)>>16) & 0xffff)
- #define LOWORD(x) (unsigned short)((x) & 0xffff)
-#endif
-
-#ifdef _IS_WINDOWS_
-#include <windows.h>
-#define __packed
-#endif
-
-/*
-** Sort out the DllExport and DllImport macros. The GCC compiler has its own
-** syntax for this, though it also supports the MS specific __declspec() as
-** a synonym.
-*/
-#ifdef GNUC
- #define DllExport __attribute__((dllexport))
- #define DllImport __attribute__((dllimport))
-#endif
-
-#ifndef DllExport
-#ifdef _IS_WINDOWS_
- #define DllExport __declspec(dllexport)
- #define DllImport __declspec(dllimport)
-#else
- #define DllExport
- #define DllImport
-#endif
-#endif /* _IS_WINDOWS_ */
-
-#ifndef TRUE
- #define TRUE 1
- #define FALSE 0
-#endif
-
-#endif
diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c
deleted file mode 100644
index 284abc08922c..000000000000
--- a/drivers/staging/ced1401/usb1401.c
+++ /dev/null
@@ -1,1582 +0,0 @@
-/***********************************************************************************
- CED1401 usb driver. This basic loading is based on the usb-skeleton.c code that is:
- Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- Copyright (C) 2012 Alois Schloegl <alois.schloegl@ist.ac.at>
- There is not a great deal of the skeleton left.
-
- All the remainder dealing specifically with the CED1401 is based on drivers written
- by CED for other systems (mainly Windows) and is:
- Copyright (C) 2010 Cambridge Electronic Design Ltd
- Author Greg P Smith (greg@ced.co.uk)
-
- 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-Endpoints
-*********
-There are 4 endpoints plus the control endpoint in the standard interface
-provided by most 1401s. The control endpoint is used for standard USB requests,
-plus various CED-specific transactions such as start self test, debug and get
-the 1401 status. The other endpoints are:
-
- 1 Characters to the 1401
- 2 Characters from the 1401
- 3 Block data to the 1401
- 4 Block data to the host.
-
-inside the driver these are indexed as an array from 0 to 3, transactions
-over the control endpoint are carried out using a separate mechanism. The
-use of the endpoints is mostly straightforward, with the driver issuing
-IO request packets (IRPs) as required to transfer data to and from the 1401.
-The handling of endpoint 2 is different because it is used for characters
-from the 1401, which can appear spontaneously and without any other driver
-activity - for example to repeatedly request DMA transfers in Spike2. The
-desired effect is achieved by using an interrupt endpoint which can be
-polled to see if it has data available, and writing the driver so that it
-always maintains a pending read IRP from that endpoint which will read the
-character data and terminate as soon as the 1401 makes data available. This
-works very well, some care is taken with when you kick off this character
-read IRP to avoid it being active when it is not wanted but generally it
-is running all the time.
-
-In the 2270, there are only three endpoints plus the control endpoint. In
-addition to the transactions mentioned above, the control endpoint is used
-to transfer character data to the 1401. The other endpoints are used as:
-
- 1 Characters from the 1401
- 2 Block data to the 1401
- 3 Block data to the host.
-
-The type of interface available is specified by the interface subclass field
-in the interface descriptor provided by the 1401. See the USB_INT_ constants
-for the values that this field can hold.
-
-****************************************************************************
-Linux implementation
-
-Although Linux Device Drivers (3rd Edition) was a major source of information,
-it is very out of date. A lot of information was gleaned from the latest
-usb_skeleton.c code (you need to download the kernel sources to get this).
-
-To match the Windows version, everything is done using ioctl calls. All the
-device state is held in the DEVICE_EXTENSION (named to match Windows use).
-Block transfers are done by using get_user_pages() to pin down a list of
-pages that we hold a pointer to in the device driver. We also allocate a
-coherent transfer buffer of size STAGED_SZ (this must be a multiple of the
-bulk endpoint size so that the 1401 does not realise that we break large
-transfers down into smaller pieces). We use kmap_atomic() to get a kernel
-va for each page, as it is required, for copying; see CopyUserSpace().
-
-All character and data transfers are done using asynchronous IO. All Urbs are
-tracked by anchoring them. Status and debug ioctls are implemented with the
-synchronous non-Urb based transfers.
-*/
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kref.h>
-#include <linux/uaccess.h>
-
-#include "usb1401.h"
-
-/* Define these values to match your devices */
-#define USB_CED_VENDOR_ID 0x0525
-#define USB_CED_PRODUCT_ID 0xa0f0
-
-/* table of devices that work with this driver */
-static const struct usb_device_id ced_table[] = {
- {USB_DEVICE(USB_CED_VENDOR_ID, USB_CED_PRODUCT_ID)},
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, ced_table);
-
-/* Get a minor range for your devices from the usb maintainer */
-#define USB_CED_MINOR_BASE 192
-
-/* our private defines. if this grows any larger, use your own .h file */
-#define MAX_TRANSFER (PAGE_SIZE - 512)
-/* MAX_TRANSFER is chosen so that the VM is not stressed by
- allocations > PAGE_SIZE and the number of packets in a page
- is an integer 512 is the largest possible packet on EHCI */
-#define WRITES_IN_FLIGHT 8
-/* arbitrarily chosen */
-
-static struct usb_driver ced_driver;
-
-static void ced_delete(struct kref *kref)
-{
- DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref);
-
- /* Free up the output buffer, then free the output urb. Note that the interface member */
- /* of pdx will probably be NULL, so cannot be used to get to dev. */
- usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut,
- pdx->pUrbCharOut->transfer_dma);
- usb_free_urb(pdx->pUrbCharOut);
-
- /* Do the same for chan input */
- usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn,
- pdx->pUrbCharIn->transfer_dma);
- usb_free_urb(pdx->pUrbCharIn);
-
- /* Do the same for the block transfers */
- usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO,
- pdx->pStagedUrb->transfer_dma);
- usb_free_urb(pdx->pStagedUrb);
-
- usb_put_dev(pdx->udev);
- kfree(pdx);
-}
-
-/* This is the driver end of the open() call from user space. */
-static int ced_open(struct inode *inode, struct file *file)
-{
- DEVICE_EXTENSION *pdx;
- int retval = 0;
- int subminor = iminor(inode);
- struct usb_interface *interface =
- usb_find_interface(&ced_driver, subminor);
- if (!interface) {
- pr_err("%s - error, can't find device for minor %d", __func__,
- subminor);
- retval = -ENODEV;
- goto exit;
- }
-
- pdx = usb_get_intfdata(interface);
- if (!pdx) {
- retval = -ENODEV;
- goto exit;
- }
-
- dev_dbg(&interface->dev, "%s: got pdx\n", __func__);
-
- /* increment our usage count for the device */
- kref_get(&pdx->kref);
-
- /* lock the device to allow correctly handling errors
- * in resumption */
- mutex_lock(&pdx->io_mutex);
-
- if (!pdx->open_count++) {
- retval = usb_autopm_get_interface(interface);
- if (retval) {
- pdx->open_count--;
- mutex_unlock(&pdx->io_mutex);
- kref_put(&pdx->kref, ced_delete);
- goto exit;
- }
- } else { /* uncomment this block if you want exclusive open */
- dev_err(&interface->dev, "%s: fail: already open\n", __func__);
- retval = -EBUSY;
- pdx->open_count--;
- mutex_unlock(&pdx->io_mutex);
- kref_put(&pdx->kref, ced_delete);
- goto exit;
- }
- /* prevent the device from being autosuspended */
-
- /* save our object in the file's private structure */
- file->private_data = pdx;
- mutex_unlock(&pdx->io_mutex);
-
-exit:
- return retval;
-}
-
-static int ced_release(struct inode *inode, struct file *file)
-{
- DEVICE_EXTENSION *pdx = file->private_data;
- if (pdx == NULL)
- return -ENODEV;
-
- dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
- mutex_lock(&pdx->io_mutex);
- if (!--pdx->open_count && pdx->interface) /* Allow autosuspend */
- usb_autopm_put_interface(pdx->interface);
- mutex_unlock(&pdx->io_mutex);
-
- kref_put(&pdx->kref, ced_delete); /* decrement the count on our device */
- return 0;
-}
-
-static int ced_flush(struct file *file, fl_owner_t id)
-{
- int res;
- DEVICE_EXTENSION *pdx = file->private_data;
- if (pdx == NULL)
- return -ENODEV;
-
- dev_dbg(&pdx->interface->dev, "%s: char in pend=%d\n",
- __func__, pdx->bReadCharsPending);
-
- /* wait for io to stop */
- mutex_lock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: got io_mutex\n", __func__);
- ced_draw_down(pdx);
-
- /* read out errors, leave subsequent opens a clean slate */
- spin_lock_irq(&pdx->err_lock);
- res = pdx->errors ? (pdx->errors == -EPIPE ? -EPIPE : -EIO) : 0;
- pdx->errors = 0;
- spin_unlock_irq(&pdx->err_lock);
-
- mutex_unlock(&pdx->io_mutex);
- dev_dbg(&pdx->interface->dev, "%s: exit reached\n", __func__);
-
- return res;
-}
-
-/***************************************************************************
-** CanAcceptIoRequests
-** If the device is removed, interface is set NULL. We also clear our pointer
-** from the interface, so we should make sure that pdx is not NULL. This will
-** not help with a device extension held by a file.
-** return true if can accept new io requests, else false
-*/
-static bool CanAcceptIoRequests(DEVICE_EXTENSION *pdx)
-{
- return pdx && pdx->interface; /* Can we accept IO requests */
-}
-
-/****************************************************************************
-** Callback routine to complete writes. This may need to fire off another
-** urb to complete the transfer.
-****************************************************************************/
-static void ced_writechar_callback(struct urb *pUrb)
-{
- DEVICE_EXTENSION *pdx = pUrb->context;
- int nGot = pUrb->actual_length; /* what we transferred */
-
- if (pUrb->status) { /* sync/async unlink faults aren't errors */
- if (!
- (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
- || pUrb->status == -ESHUTDOWN)) {
- dev_err(&pdx->interface->dev,
- "%s: nonzero write bulk status received: %d\n",
- __func__, pUrb->status);
- }
-
- spin_lock(&pdx->err_lock);
- pdx->errors = pUrb->status;
- spin_unlock(&pdx->err_lock);
- nGot = 0; /* and tidy up again if so */
-
- spin_lock(&pdx->charOutLock); /* already at irq level */
- pdx->dwOutBuffGet = 0; /* Reset the output buffer */
- pdx->dwOutBuffPut = 0;
- pdx->dwNumOutput = 0; /* Clear the char count */
- pdx->bPipeError[0] = 1; /* Flag an error for later */
- pdx->bSendCharsPending = false; /* Allow other threads again */
- spin_unlock(&pdx->charOutLock); /* already at irq level */
- dev_dbg(&pdx->interface->dev,
- "%s: char out done, 0 chars sent\n", __func__);
- } else {
- dev_dbg(&pdx->interface->dev,
- "%s: char out done, %d chars sent\n", __func__, nGot);
- spin_lock(&pdx->charOutLock); /* already at irq level */
- pdx->dwNumOutput -= nGot; /* Now adjust the char send buffer */
- pdx->dwOutBuffGet += nGot; /* to match what we did */
- if (pdx->dwOutBuffGet >= OUTBUF_SZ) /* Can't do this any earlier as data could be overwritten */
- pdx->dwOutBuffGet = 0;
-
- if (pdx->dwNumOutput > 0) { /* if more to be done... */
- int nPipe = 0; /* The pipe number to use */
- int iReturn;
- char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
- unsigned int dwCount = pdx->dwNumOutput; /* maximum to send */
- if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
- dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
- spin_unlock(&pdx->charOutLock); /* we are done with stuff that changes */
- memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
- usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
- usb_sndbulkpipe(pdx->udev,
- pdx->epAddr[0]),
- pdx->pCoherCharOut, dwCount,
- ced_writechar_callback, pdx);
- pdx->pUrbCharOut->transfer_flags |=
- URB_NO_TRANSFER_DMA_MAP;
- usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted); /* in case we need to kill it */
- iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC);
- dev_dbg(&pdx->interface->dev, "%s: n=%d>%s<\n",
- __func__, dwCount, pDat);
- spin_lock(&pdx->charOutLock); /* grab lock for errors */
- if (iReturn) {
- pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
- pdx->bSendCharsPending = false; /* Allow other threads again */
- usb_unanchor_urb(pdx->pUrbCharOut);
- dev_err(&pdx->interface->dev,
- "%s: usb_submit_urb() returned %d\n",
- __func__, iReturn);
- }
- } else
- pdx->bSendCharsPending = false; /* Allow other threads again */
- spin_unlock(&pdx->charOutLock); /* already at irq level */
- }
-}
-
-/****************************************************************************
-** SendChars
-** Transmit the characters in the output buffer to the 1401. This may need
-** breaking down into multiple transfers.
-****************************************************************************/
-int SendChars(DEVICE_EXTENSION *pdx)
-{
- int iReturn = U14ERR_NOERROR;
-
- spin_lock_irq(&pdx->charOutLock); /* Protect ourselves */
-
- if ((!pdx->bSendCharsPending) && /* Not currently sending */
- (pdx->dwNumOutput > 0) && /* has characters to output */
- (CanAcceptIoRequests(pdx))) { /* and current activity is OK */
- unsigned int dwCount = pdx->dwNumOutput; /* Get a copy of the character count */
- pdx->bSendCharsPending = true; /* Set flag to lock out other threads */
-
- dev_dbg(&pdx->interface->dev,
- "Send %d chars to 1401, EP0 flag %d\n",
- dwCount, pdx->nPipes == 3);
- /* If we have only 3 end points we must send the characters to the 1401 using EP0. */
- if (pdx->nPipes == 3) {
- /* For EP0 character transmissions to the 1401, we have to hang about until they */
- /* are gone, as otherwise without more character IO activity they will never go. */
- unsigned int count = dwCount; /* Local char counter */
- unsigned int index = 0; /* The index into the char buffer */
-
- spin_unlock_irq(&pdx->charOutLock); /* Free spinlock as we call USBD */
-
- while ((count > 0) && (iReturn == U14ERR_NOERROR)) {
- /* We have to break the transfer up into 64-byte chunks because of a 2270 problem */
- int n = count > 64 ? 64 : count; /* Chars for this xfer, max of 64 */
- int nSent = usb_control_msg(pdx->udev,
- usb_sndctrlpipe(pdx->udev, 0), /* use end point 0 */
- DB_CHARS, /* bRequest */
- (H_TO_D | VENDOR | DEVREQ), /* to the device, vendor request to the device */
- 0, 0, /* value and index are both 0 */
- &pdx->outputBuffer[index], /* where to send from */
- n, /* how much to send */
- 1000); /* timeout in jiffies */
- if (nSent <= 0) {
- iReturn = nSent ? nSent : -ETIMEDOUT; /* if 0 chars says we timed out */
- dev_err(&pdx->interface->dev,
- "Send %d chars by EP0 failed: %d\n",
- n, iReturn);
- } else {
- dev_dbg(&pdx->interface->dev,
- "Sent %d chars by EP0\n", n);
- count -= nSent;
- index += nSent;
- }
- }
-
- spin_lock_irq(&pdx->charOutLock); /* Protect pdx changes, released by general code */
- pdx->dwOutBuffGet = 0; /* so reset the output buffer */
- pdx->dwOutBuffPut = 0;
- pdx->dwNumOutput = 0; /* and clear the buffer count */
- pdx->bSendCharsPending = false; /* Allow other threads again */
- } else { /* Here for sending chars normally - we hold the spin lock */
- int nPipe = 0; /* The pipe number to use */
- char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
-
- if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ) /* does it cross buffer end? */
- dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
- spin_unlock_irq(&pdx->charOutLock); /* we are done with stuff that changes */
- memcpy(pdx->pCoherCharOut, pDat, dwCount); /* copy output data to the buffer */
- usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
- usb_sndbulkpipe(pdx->udev,
- pdx->epAddr[0]),
- pdx->pCoherCharOut, dwCount,
- ced_writechar_callback, pdx);
- pdx->pUrbCharOut->transfer_flags |=
- URB_NO_TRANSFER_DMA_MAP;
- usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);
- iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL);
- spin_lock_irq(&pdx->charOutLock); /* grab lock for errors */
- if (iReturn) {
- pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
- pdx->bSendCharsPending = false; /* Allow other threads again */
- usb_unanchor_urb(pdx->pUrbCharOut); /* remove from list of active urbs */
- }
- }
- } else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0))
- dev_dbg(&pdx->interface->dev,
- "%s: bSendCharsPending:true\n", __func__);
-
- dev_dbg(&pdx->interface->dev, "%s: exit code: %d\n", __func__, iReturn);
- spin_unlock_irq(&pdx->charOutLock); /* Now let go of the spinlock */
- return iReturn;
-}
-
-/***************************************************************************
-** CopyUserSpace
-** This moves memory between pinned down user space and the pCoherStagedIO
-** memory buffer we use for transfers. Copy n bytes in the directions that
-** is defined by pdx->StagedRead. The user space is determined by the area
-** in pdx->StagedId and the offset in pdx->StagedDone. The user
-** area may well not start on a page boundary, so allow for that.
-**
-** We have a table of physical pages that describe the area, so we can use
-** this to get a virtual address that the kernel can use.
-**
-** pdx Is our device extension which holds all we know about the transfer.
-** n The number of bytes to move one way or the other.
-***************************************************************************/
-static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n)
-{
- unsigned int nArea = pdx->StagedId;
- if (nArea < MAX_TRANSAREAS) {
- TRANSAREA *pArea = &pdx->rTransDef[nArea]; /* area to be used */
- unsigned int dwOffset =
- pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset;
- char *pCoherBuf = pdx->pCoherStagedIO; /* coherent buffer */
- if (!pArea->bUsed) {
- dev_err(&pdx->interface->dev, "%s: area %d unused\n",
- __func__, nArea);
- return;
- }
-
- while (n) {
- int nPage = dwOffset >> PAGE_SHIFT; /* page number in table */
- if (nPage < pArea->nPages) {
- char *pvAddress =
- (char *)kmap_atomic(pArea->pPages[nPage]);
- if (pvAddress) {
- unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1); /* offset into the page */
- size_t uiXfer = PAGE_SIZE - uiPageOff; /* max to transfer on this page */
- if (uiXfer > n) /* limit byte count if too much */
- uiXfer = n; /* for the page */
- if (pdx->StagedRead)
- memcpy(pvAddress + uiPageOff,
- pCoherBuf, uiXfer);
- else
- memcpy(pCoherBuf,
- pvAddress + uiPageOff,
- uiXfer);
- kunmap_atomic(pvAddress);
- dwOffset += uiXfer;
- pCoherBuf += uiXfer;
- n -= uiXfer;
- } else {
- dev_err(&pdx->interface->dev,
- "%s: did not map page %d\n",
- __func__, nPage);
- return;
- }
-
- } else {
- dev_err(&pdx->interface->dev,
- "%s: exceeded pages %d\n",
- __func__, nPage);
- return;
- }
- }
- } else
- dev_err(&pdx->interface->dev, "%s: bad area %d\n",
- __func__, nArea);
-}
-
-/* Forward declarations for stuff used circularly */
-static int StageChunk(DEVICE_EXTENSION *pdx);
-/***************************************************************************
-** ReadWrite_Complete
-**
-** Completion routine for our staged read/write Irps
-*/
-static void staged_callback(struct urb *pUrb)
-{
- DEVICE_EXTENSION *pdx = pUrb->context;
- unsigned int nGot = pUrb->actual_length; /* what we transferred */
- bool bCancel = false;
- bool bRestartCharInput; /* used at the end */
-
- spin_lock(&pdx->stagedLock); /* stop ReadWriteMem() action while this routine is running */
- pdx->bStagedUrbPending = false; /* clear the flag for staged IRP pending */
-
- if (pUrb->status) { /* sync/async unlink faults aren't errors */
- if (!
- (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
- || pUrb->status == -ESHUTDOWN)) {
- dev_err(&pdx->interface->dev,
- "%s: nonzero write bulk status received: %d\n",
- __func__, pUrb->status);
- } else
- dev_info(&pdx->interface->dev,
- "%s: staged xfer cancelled\n", __func__);
-
- spin_lock(&pdx->err_lock);
- pdx->errors = pUrb->status;
- spin_unlock(&pdx->err_lock);
- nGot = 0; /* and tidy up again if so */
- bCancel = true;
- } else {
- dev_dbg(&pdx->interface->dev, "%s: %d chars xferred\n",
- __func__, nGot);
- if (pdx->StagedRead) /* if reading, save to user space */
- CopyUserSpace(pdx, nGot); /* copy from buffer to user */
- if (nGot == 0)
- dev_dbg(&pdx->interface->dev, "%s: ZLP\n", __func__);
- }
-
- /* Update the transfer length based on the TransferBufferLength value in the URB */
- pdx->StagedDone += nGot;
-
- dev_dbg(&pdx->interface->dev, "%s: done %d bytes of %d\n",
- __func__, pdx->StagedDone, pdx->StagedLength);
-
- if ((pdx->StagedDone == pdx->StagedLength) || /* If no more to do */
- (bCancel)) { /* or this IRP was cancelled */
- TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId]; /* Transfer area info */
- dev_dbg(&pdx->interface->dev,
- "%s: transfer done, bytes %d, cancel %d\n",
- __func__, pdx->StagedDone, bCancel);
-
- /* Here is where we sort out what to do with this transfer if using a circular buffer. We have */
- /* a completed transfer that can be assumed to fit into the transfer area. We should be able to */
- /* add this to the end of a growing block or to use it to start a new block unless the code */
- /* that calculates the offset to use (in ReadWriteMem) is totally duff. */
- if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) && /* Time to sort out circular buffer info? */
- (pdx->StagedRead)) { /* Only for tohost transfers for now */
- if (pArea->aBlocks[1].dwSize > 0) { /* If block 1 is in use we must append to it */
- if (pdx->StagedOffset ==
- (pArea->aBlocks[1].dwOffset +
- pArea->aBlocks[1].dwSize)) {
- pArea->aBlocks[1].dwSize +=
- pdx->StagedLength;
- dev_dbg(&pdx->interface->dev,
- "RWM_Complete, circ block 1 now %d bytes at %d\n",
- pArea->aBlocks[1].dwSize,
- pArea->aBlocks[1].dwOffset);
- } else {
- /* Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */
- pArea->aBlocks[1].dwOffset =
- pdx->StagedOffset;
- pArea->aBlocks[1].dwSize =
- pdx->StagedLength;
- dev_err(&pdx->interface->dev,
- "%s: ERROR, circ block 1 re-started %d bytes at %d\n",
- __func__,
- pArea->aBlocks[1].dwSize,
- pArea->aBlocks[1].dwOffset);
- }
- } else { /* If block 1 is not used, we try to add to block 0 */
- if (pArea->aBlocks[0].dwSize > 0) { /* Got stored block 0 information? */
- /* Must append onto the existing block 0 */
- if (pdx->StagedOffset ==
- (pArea->aBlocks[0].dwOffset +
- pArea->aBlocks[0].dwSize)) {
- pArea->aBlocks[0].dwSize += pdx->StagedLength; /* Just add this transfer in */
- dev_dbg(&pdx->interface->dev,
- "RWM_Complete, circ block 0 now %d bytes at %d\n",
- pArea->aBlocks[0].
- dwSize,
- pArea->aBlocks[0].
- dwOffset);
- } else { /* If it doesn't append, put into new block 1 */
- pArea->aBlocks[1].dwOffset =
- pdx->StagedOffset;
- pArea->aBlocks[1].dwSize =
- pdx->StagedLength;
- dev_dbg(&pdx->interface->dev,
- "RWM_Complete, circ block 1 started %d bytes at %d\n",
- pArea->aBlocks[1].
- dwSize,
- pArea->aBlocks[1].
- dwOffset);
- }
- } else { /* No info stored yet, just save in block 0 */
- pArea->aBlocks[0].dwOffset =
- pdx->StagedOffset;
- pArea->aBlocks[0].dwSize =
- pdx->StagedLength;
- dev_dbg(&pdx->interface->dev,
- "RWM_Complete, circ block 0 started %d bytes at %d\n",
- pArea->aBlocks[0].dwSize,
- pArea->aBlocks[0].dwOffset);
- }
- }
- }
-
- if (!bCancel) { /* Don't generate an event if cancelled */
- dev_dbg(&pdx->interface->dev,
- "RWM_Complete, bCircular %d, bToHost %d, eStart %d, eSize %d\n",
- pArea->bCircular, pArea->bEventToHost,
- pArea->dwEventSt, pArea->dwEventSz);
- if ((pArea->dwEventSz) && /* Set a user-mode event... */
- (pdx->StagedRead == pArea->bEventToHost)) { /* ...on transfers in this direction? */
- int iWakeUp = 0; /* assume */
- /* If we have completed the right sort of DMA transfer then set the event to notify */
- /* the user code to wake up anyone that is waiting. */
- if ((pArea->bCircular) && /* Circular areas use a simpler test */
- (pArea->bCircToHost)) { /* only in supported direction */
- /* Is total data waiting up to size limit? */
- unsigned int dwTotal =
- pArea->aBlocks[0].dwSize +
- pArea->aBlocks[1].dwSize;
- iWakeUp = (dwTotal >= pArea->dwEventSz);
- } else {
- unsigned int transEnd =
- pdx->StagedOffset +
- pdx->StagedLength;
- unsigned int eventEnd =
- pArea->dwEventSt + pArea->dwEventSz;
- iWakeUp = (pdx->StagedOffset < eventEnd)
- && (transEnd > pArea->dwEventSt);
- }
-
- if (iWakeUp) {
- dev_dbg(&pdx->interface->dev,
- "About to set event to notify app\n");
- wake_up_interruptible(&pArea->wqEvent); /* wake up waiting processes */
- ++pArea->iWakeUp; /* increment wakeup count */
- }
- }
- }
-
- pdx->dwDMAFlag = MODE_CHAR; /* Switch back to char mode before ReadWriteMem call */
-
- if (!bCancel) { /* Don't look for waiting transfer if cancelled */
- /* If we have a transfer waiting, kick it off */
- if (pdx->bXFerWaiting) { /* Got a block xfer waiting? */
- int iReturn;
- dev_info(&pdx->interface->dev,
- "*** RWM_Complete *** pending transfer will now be set up!!!\n");
- iReturn =
- ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
- pdx->rDMAInfo.wIdent,
- pdx->rDMAInfo.dwOffset,
- pdx->rDMAInfo.dwSize);
-
- if (iReturn)
- dev_err(&pdx->interface->dev,
- "RWM_Complete rw setup failed %d\n",
- iReturn);
- }
- }
-
- } else /* Here for more to do */
- StageChunk(pdx); /* fire off the next bit */
-
- /* While we hold the stagedLock, see if we should reallow character input ints */
- /* Don't allow if cancelled, or if a new block has started or if there is a waiting block. */
- /* This feels wrong as we should ask which spin lock protects dwDMAFlag. */
- bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR)
- && !pdx->bXFerWaiting;
-
- spin_unlock(&pdx->stagedLock); /* Finally release the lock again */
-
- /* This is not correct as dwDMAFlag is protected by the staged lock, but it is treated */
- /* in Allowi as if it were protected by the char lock. In any case, most systems will */
- /* not be upset by char input during DMA... sigh. Needs sorting out. */
- if (bRestartCharInput) /* may be out of date, but... */
- Allowi(pdx); /* ...Allowi tests a lock too. */
- dev_dbg(&pdx->interface->dev, "%s: done\n", __func__);
-}
-
-/****************************************************************************
-** StageChunk
-**
-** Generates the next chunk of data making up a staged transfer.
-**
-** The calling code must have acquired the staging spinlock before calling
-** this function, and is responsible for releasing it. We are at callback level.
-****************************************************************************/
-static int StageChunk(DEVICE_EXTENSION *pdx)
-{
- int iReturn = U14ERR_NOERROR;
- unsigned int ChunkSize;
- int nPipe = pdx->StagedRead ? 3 : 2; /* The pipe number to use for reads or writes */
- if (pdx->nPipes == 3)
- nPipe--; /* Adjust for the 3-pipe case */
- if (nPipe < 0) /* and trap case that should never happen */
- return U14ERR_FAIL;
-
- if (!CanAcceptIoRequests(pdx)) { /* got sudden remove? */
- dev_info(&pdx->interface->dev, "%s: sudden remove, giving up\n",
- __func__);
- return U14ERR_FAIL; /* could do with a better error */
- }
-
- ChunkSize = (pdx->StagedLength - pdx->StagedDone); /* transfer length remaining */
- if (ChunkSize > STAGED_SZ) /* make sure to keep legal */
- ChunkSize = STAGED_SZ; /* limit to max allowed */
-
- if (!pdx->StagedRead) /* if writing... */
- CopyUserSpace(pdx, ChunkSize); /* ...copy data into the buffer */
-
- usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev,
- pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev,
- pdx->
- epAddr[nPipe]) :
- usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]),
- pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx);
- pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted); /* in case we need to kill it */
- iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC);
- if (iReturn) {
- usb_unanchor_urb(pdx->pStagedUrb); /* kill it */
- pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
- dev_err(&pdx->interface->dev, "%s: submit urb failed, code %d\n",
- __func__, iReturn);
- } else
- pdx->bStagedUrbPending = true; /* Set the flag for staged URB pending */
- dev_dbg(&pdx->interface->dev, "%s: done so far:%d, this size:%d\n",
- __func__, pdx->StagedDone, ChunkSize);
-
- return iReturn;
-}
-
-/***************************************************************************
-** ReadWriteMem
-**
-** This routine is used generally for block read and write operations.
-** Breaks up a read or write in to specified sized chunks, as specified by pipe
-** information on maximum transfer size.
-**
-** Any code that calls this must be holding the stagedLock
-**
-** Arguments:
-** DeviceObject - pointer to our FDO (Functional Device Object)
-** Read - TRUE for read, FALSE for write. This is from POV of the driver
-** wIdent - the transfer area number - defines memory area and more.
-** dwOffs - the start offset within the transfer area of the start of this
-** transfer.
-** dwLen - the number of bytes to transfer.
-*/
-int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
- unsigned int dwOffs, unsigned int dwLen)
-{
- TRANSAREA *pArea = &pdx->rTransDef[wIdent]; /* Transfer area info */
-
- if (!CanAcceptIoRequests(pdx)) { /* Are we in a state to accept new requests? */
- dev_err(&pdx->interface->dev, "%s: can't accept requests\n",
- __func__);
- return U14ERR_FAIL;
- }
-
- dev_dbg(&pdx->interface->dev,
- "%s: xfer %d bytes to %s, offset %d, area %d\n",
- __func__, dwLen, Read ? "host" : "1401", dwOffs, wIdent);
-
- /* Amazingly, we can get an escape sequence back before the current staged Urb is done, so we */
- /* have to check for this situation and, if so, wait until all is OK. */
- if (pdx->bStagedUrbPending) {
- pdx->bXFerWaiting = true; /* Flag we are waiting */
- dev_info(&pdx->interface->dev,
- "%s: xfer is waiting, as previous staged pending\n",
- __func__);
- return U14ERR_NOERROR;
- }
-
- if (dwLen == 0) { /* allow 0-len read or write; just return success */
- dev_dbg(&pdx->interface->dev,
- "%s: OK; zero-len read/write request\n", __func__);
- return U14ERR_NOERROR;
- }
-
- if ((pArea->bCircular) && /* Circular transfer? */
- (pArea->bCircToHost) && (Read)) { /* In a supported direction */
- /* If so, we sort out offset ourself */
- bool bWait = false; /* Flag for transfer having to wait */
-
- dev_dbg(&pdx->interface->dev,
- "Circular buffers are %d at %d and %d at %d\n",
- pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset,
- pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset);
- if (pArea->aBlocks[1].dwSize > 0) { /* Using the second block already? */
- dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize; /* take offset from that */
- bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; /* Wait if will overwrite block 0? */
- bWait |= (dwOffs + dwLen) > pArea->dwLength; /* or if it overflows the buffer */
- } else { /* Area 1 not in use, try to use area 0 */
- if (pArea->aBlocks[0].dwSize == 0) /* Reset block 0 if not in use */
- pArea->aBlocks[0].dwOffset = 0;
- dwOffs =
- pArea->aBlocks[0].dwOffset +
- pArea->aBlocks[0].dwSize;
- if ((dwOffs + dwLen) > pArea->dwLength) { /* Off the end of the buffer? */
- pArea->aBlocks[1].dwOffset = 0; /* Set up to use second block */
- dwOffs = 0;
- bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset; /* Wait if will overwrite block 0? */
- bWait |= (dwOffs + dwLen) > pArea->dwLength; /* or if it overflows the buffer */
- }
- }
-
- if (bWait) { /* This transfer will have to wait? */
- pdx->bXFerWaiting = true; /* Flag we are waiting */
- dev_dbg(&pdx->interface->dev,
- "%s: xfer waiting for circular buffer space\n",
- __func__);
- return U14ERR_NOERROR;
- }
-
- dev_dbg(&pdx->interface->dev,
- "%s: circular xfer, %d bytes starting at %d\n",
- __func__, dwLen, dwOffs);
- }
- /* Save the parameters for the read\write transfer */
- pdx->StagedRead = Read; /* Save the parameters for this read */
- pdx->StagedId = wIdent; /* ID allows us to get transfer area info */
- pdx->StagedOffset = dwOffs; /* The area within the transfer area */
- pdx->StagedLength = dwLen;
- pdx->StagedDone = 0; /* Initialise the byte count */
- pdx->dwDMAFlag = MODE_LINEAR; /* Set DMA mode flag at this point */
- pdx->bXFerWaiting = false; /* Clearly not a transfer waiting now */
-
-/* KeClearEvent(&pdx->StagingDoneEvent); // Clear the transfer done event */
- StageChunk(pdx); /* fire off the first chunk */
-
- return U14ERR_NOERROR;
-}
-
-/****************************************************************************
-**
-** ReadChar
-**
-** Reads a character a buffer. If there is no more
-** data we return FALSE. Used as part of decoding a DMA request.
-**
-****************************************************************************/
-static bool ReadChar(unsigned char *pChar, char *pBuf, unsigned int *pdDone,
- unsigned int dGot)
-{
- bool bRead = false;
- unsigned int dDone = *pdDone;
-
- if (dDone < dGot) { /* If there is more data */
- *pChar = (unsigned char)pBuf[dDone]; /* Extract the next char */
- dDone++; /* Increment the done count */
- *pdDone = dDone;
- bRead = true; /* and flag success */
- }
-
- return bRead;
-}
-
-#ifdef NOTUSED
-/****************************************************************************
-**
-** ReadWord
-**
-** Reads a word from the 1401, just uses ReadChar twice; passes on any error
-**
-*****************************************************************************/
-static bool ReadWord(unsigned short *pWord, char *pBuf, unsigned int *pdDone,
- unsigned int dGot)
-{
- if (ReadChar((unsigned char *)pWord, pBuf, pdDone, dGot))
- return ReadChar(((unsigned char *)pWord) + 1, pBuf, pdDone,
- dGot);
- else
- return false;
-}
-#endif
-
-/****************************************************************************
-** ReadHuff
-**
-** Reads a coded number in and returns it, Code is:
-** If data is in range 0..127 we receive 1 byte. If data in range 128-16383
-** we receive two bytes, top bit of first indicates another on its way. If
-** data in range 16384-4194303 we get three bytes, top two bits of first set
-** to indicate three byte total.
-**
-*****************************************************************************/
-static bool ReadHuff(volatile unsigned int *pDWord, char *pBuf,
- unsigned int *pdDone, unsigned int dGot)
-{
- unsigned char ucData; /* for each read to ReadChar */
- bool bReturn = true; /* assume we will succeed */
- unsigned int dwData = 0; /* Accumulator for the data */
-
- if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
- dwData = ucData; /* copy the data */
- if ((dwData & 0x00000080) != 0) { /* Bit set for more data ? */
- dwData &= 0x0000007F; /* Clear the relevant bit */
- if (ReadChar(&ucData, pBuf, pdDone, dGot)) {
- dwData = (dwData << 8) | ucData;
- if ((dwData & 0x00004000) != 0) { /* three byte sequence ? */
- dwData &= 0x00003FFF; /* Clear the relevant bit */
- if (ReadChar
- (&ucData, pBuf, pdDone, dGot))
- dwData = (dwData << 8) | ucData;
- else
- bReturn = false;
- }
- } else
- bReturn = false; /* couldn't read data */
- }
- } else
- bReturn = false;
-
- *pDWord = dwData; /* return the data */
- return bReturn;
-}
-
-/***************************************************************************
-**
-** ReadDMAInfo
-**
-** Tries to read info about the dma request from the 1401 and decode it into
-** the dma descriptor block. We have at this point had the escape character
-** from the 1401 and now we must read in the rest of the information about
-** the transfer request. Returns FALSE if 1401 fails to respond or obselete
-** code from 1401 or bad parameters.
-**
-** The pBuf char pointer does not include the initial escape character, so
-** we start handling the data at offset zero.
-**
-*****************************************************************************/
-static bool ReadDMAInfo(volatile DMADESC *pDmaDesc, DEVICE_EXTENSION *pdx,
- char *pBuf, unsigned int dwCount)
-{
- bool bResult = false; /* assume we won't succeed */
- unsigned char ucData;
- unsigned int dDone = 0; /* We haven't parsed anything so far */
-
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- if (ReadChar(&ucData, pBuf, &dDone, dwCount)) {
- unsigned char ucTransCode = (ucData & 0x0F); /* get code for transfer type */
- unsigned short wIdent = ((ucData >> 4) & 0x07); /* and area identifier */
-
- /* fill in the structure we were given */
- pDmaDesc->wTransType = ucTransCode; /* type of transfer */
- pDmaDesc->wIdent = wIdent; /* area to use */
- pDmaDesc->dwSize = 0; /* initialise other bits */
- pDmaDesc->dwOffset = 0;
-
- dev_dbg(&pdx->interface->dev, "%s: type: %d ident: %d\n",
- __func__, pDmaDesc->wTransType, pDmaDesc->wIdent);
-
- pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST); /* set transfer direction */
-
- switch (ucTransCode) {
- case TM_EXTTOHOST: /* Extended linear transfer modes (the only ones!) */
- case TM_EXTTO1401:
- {
- bResult =
- ReadHuff(&(pDmaDesc->dwOffset), pBuf,
- &dDone, dwCount)
- && ReadHuff(&(pDmaDesc->dwSize), pBuf,
- &dDone, dwCount);
- if (bResult) {
- dev_dbg(&pdx->interface->dev,
- "%s: xfer offset & size %d %d\n",
- __func__, pDmaDesc->dwOffset,
- pDmaDesc->dwSize);
-
- if ((wIdent >= MAX_TRANSAREAS) || /* Illegal area number, or... */
- (!pdx->rTransDef[wIdent].bUsed) || /* area not set up, or... */
- (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) || /* range/size */
- ((pDmaDesc->dwOffset +
- pDmaDesc->dwSize) >
- (pdx->rTransDef[wIdent].
- dwLength))) {
- bResult = false; /* bad parameter(s) */
- dev_dbg(&pdx->interface->dev,
- "%s: bad param - id %d, bUsed %d, offset %d, size %d, area length %d\n",
- __func__, wIdent,
- pdx->rTransDef[wIdent].
- bUsed,
- pDmaDesc->dwOffset,
- pDmaDesc->dwSize,
- pdx->rTransDef[wIdent].
- dwLength);
- }
- }
- break;
- }
- default:
- break;
- }
- } else
- bResult = false;
-
- if (!bResult) /* now check parameters for validity */
- dev_err(&pdx->interface->dev, "%s: error reading Esc sequence\n",
- __func__);
-
- return bResult;
-}
-
-/****************************************************************************
-**
-** Handle1401Esc
-**
-** Deals with an escape sequence coming from the 1401. This can either be
-** a DMA transfer request of various types or a response to an escape sequence
-** sent to the 1401. This is called from a callback.
-**
-** Parameters are
-**
-** dwCount - the number of characters in the device extension char in buffer,
-** this is known to be at least 2 or we will not be called.
-**
-****************************************************************************/
-static int Handle1401Esc(DEVICE_EXTENSION *pdx, char *pCh,
- unsigned int dwCount)
-{
- int iReturn = U14ERR_FAIL;
-
- /* I have no idea what this next test is about. '?' is 0x3f, which is area 3, code */
- /* 15. At the moment, this is not used, so it does no harm, but unless someone can */
- /* tell me what this is for, it should be removed from this and the Windows driver. */
- if (pCh[0] == '?') { /* Is this an information response */
- /* Parse and save the information */
- } else {
- spin_lock(&pdx->stagedLock); /* Lock others out */
-
- if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) { /* Get DMA parameters */
- unsigned short wTransType = pdx->rDMAInfo.wTransType; /* check transfer type */
-
- dev_dbg(&pdx->interface->dev,
- "%s: xfer to %s, offset %d, length %d\n",
- __func__,
- pdx->rDMAInfo.bOutWard ? "1401" : "host",
- pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize);
-
- if (pdx->bXFerWaiting) { /* Check here for badly out of kilter... */
- /* This can never happen, really */
- dev_err(&pdx->interface->dev,
- "ERROR: DMA setup while transfer still waiting\n");
- } else {
- if ((wTransType == TM_EXTTOHOST)
- || (wTransType == TM_EXTTO1401)) {
- iReturn =
- ReadWriteMem(pdx,
- !pdx->rDMAInfo.
- bOutWard,
- pdx->rDMAInfo.wIdent,
- pdx->rDMAInfo.dwOffset,
- pdx->rDMAInfo.dwSize);
- if (iReturn != U14ERR_NOERROR)
- dev_err(&pdx->interface->dev,
- "%s: ReadWriteMem() failed %d\n",
- __func__, iReturn);
- } else /* This covers non-linear transfer setup */
- dev_err(&pdx->interface->dev,
- "%s: Unknown block xfer type %d\n",
- __func__, wTransType);
- }
- } else /* Failed to read parameters */
- dev_err(&pdx->interface->dev, "%s: ReadDMAInfo() fail\n",
- __func__);
-
- spin_unlock(&pdx->stagedLock); /* OK here */
- }
-
- dev_dbg(&pdx->interface->dev, "%s: returns %d\n", __func__, iReturn);
-
- return iReturn;
-}
-
-/****************************************************************************
-** Callback for the character read complete or error
-****************************************************************************/
-static void ced_readchar_callback(struct urb *pUrb)
-{
- DEVICE_EXTENSION *pdx = pUrb->context;
- int nGot = pUrb->actual_length; /* what we transferred */
-
- if (pUrb->status) { /* Do we have a problem to handle? */
- int nPipe = pdx->nPipes == 4 ? 1 : 0; /* The pipe number to use for error */
- /* sync/async unlink faults aren't errors... just saying device removed or stopped */
- if (!
- (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
- || pUrb->status == -ESHUTDOWN)) {
- dev_err(&pdx->interface->dev,
- "%s: nonzero write bulk status received: %d\n",
- __func__, pUrb->status);
- } else
- dev_dbg(&pdx->interface->dev,
- "%s: 0 chars pUrb->status=%d (shutdown?)\n",
- __func__, pUrb->status);
-
- spin_lock(&pdx->err_lock);
- pdx->errors = pUrb->status;
- spin_unlock(&pdx->err_lock);
- nGot = 0; /* and tidy up again if so */
-
- spin_lock(&pdx->charInLock); /* already at irq level */
- pdx->bPipeError[nPipe] = 1; /* Flag an error for later */
- } else {
- if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) { /* Esc sequence? */
- Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1); /* handle it */
- spin_lock(&pdx->charInLock); /* already at irq level */
- } else {
- spin_lock(&pdx->charInLock); /* already at irq level */
- if (nGot > 0) {
- unsigned int i;
- if (nGot < INBUF_SZ) {
- pdx->pCoherCharIn[nGot] = 0; /* tidy the string */
- dev_dbg(&pdx->interface->dev,
- "%s: got %d chars >%s<\n",
- __func__, nGot,
- pdx->pCoherCharIn);
- }
- /* We know that whatever we read must fit in the input buffer */
- for (i = 0; i < nGot; i++) {
- pdx->inputBuffer[pdx->dwInBuffPut++] =
- pdx->pCoherCharIn[i] & 0x7F;
- if (pdx->dwInBuffPut >= INBUF_SZ)
- pdx->dwInBuffPut = 0;
- }
-
- if ((pdx->dwNumInput + nGot) <= INBUF_SZ)
- pdx->dwNumInput += nGot; /* Adjust the buffer count accordingly */
- } else
- dev_dbg(&pdx->interface->dev, "%s: read ZLP\n",
- __func__);
- }
- }
-
- pdx->bReadCharsPending = false; /* No longer have a pending read */
- spin_unlock(&pdx->charInLock); /* already at irq level */
-
- Allowi(pdx); /* see if we can do the next one */
-}
-
-/****************************************************************************
-** Allowi
-**
-** This is used to make sure that there is always a pending input transfer so
-** we can pick up any inward transfers. This can be called in multiple contexts
-** so we use the irqsave version of the spinlock.
-****************************************************************************/
-int Allowi(DEVICE_EXTENSION *pdx)
-{
- int iReturn = U14ERR_NOERROR;
- unsigned long flags;
- spin_lock_irqsave(&pdx->charInLock, flags); /* can be called in multiple contexts */
-
- /* We don't want char input running while DMA is in progress as we know that this */
- /* can cause sequencing problems for the 2270. So don't. It will also allow the */
- /* ERR response to get back to the host code too early on some PCs, even if there */
- /* is no actual driver failure, so we don't allow this at all. */
- if (!pdx->bInDrawDown && /* stop input if */
- !pdx->bReadCharsPending && /* If no read request outstanding */
- (pdx->dwNumInput < (INBUF_SZ / 2)) && /* and there is some space */
- (pdx->dwDMAFlag == MODE_CHAR) && /* not doing any DMA */
- (!pdx->bXFerWaiting) && /* no xfer waiting to start */
- (CanAcceptIoRequests(pdx))) { /* and activity is generally OK */
- /* then off we go */
- unsigned int nMax = INBUF_SZ - pdx->dwNumInput; /* max we could read */
- int nPipe = pdx->nPipes == 4 ? 1 : 0; /* The pipe number to use */
-
- dev_dbg(&pdx->interface->dev, "%s: %d chars in input buffer\n",
- __func__, pdx->dwNumInput);
-
- usb_fill_int_urb(pdx->pUrbCharIn, pdx->udev,
- usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]),
- pdx->pCoherCharIn, nMax, ced_readchar_callback,
- pdx, pdx->bInterval);
- pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* short xfers are OK by default */
- usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted); /* in case we need to kill it */
- iReturn = usb_submit_urb(pdx->pUrbCharIn, GFP_ATOMIC);
- if (iReturn) {
- usb_unanchor_urb(pdx->pUrbCharIn); /* remove from list of active Urbs */
- pdx->bPipeError[nPipe] = 1; /* Flag an error to be handled later */
- dev_err(&pdx->interface->dev,
- "%s: submit urb failed: %d\n",
- __func__, iReturn);
- } else
- pdx->bReadCharsPending = true; /* Flag that we are active here */
- }
-
- spin_unlock_irqrestore(&pdx->charInLock, flags);
-
- return iReturn;
-
-}
-
-/*****************************************************************************
-** The ioctl entry point to the driver that is used by us to talk to it.
-** inode The device node (no longer in 3.0.0 kernels)
-** file The file that is open, which holds our pdx pointer
-** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big
-** enough for a 64-bit pointer.
-*****************************************************************************/
-static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg)
-{
- int err = 0;
- DEVICE_EXTENSION *pdx = file->private_data;
- if (!CanAcceptIoRequests(pdx)) /* check we still exist */
- return -ENODEV;
-
- /* Check that access is allowed, where is is needed. Anything that would have an indeterminate */
- /* size will be checked by the specific command. */
- if (_IOC_DIR(cmd) & _IOC_READ) /* read from point of view of user... */
- err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd)); /* is kernel write */
- else if (_IOC_DIR(cmd) & _IOC_WRITE) /* and write from point of view of user... */
- err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd)); /* is kernel read */
- if (err)
- return -EFAULT;
-
- switch (_IOC_NR(cmd)) {
- case _IOC_NR(IOCTL_CED_SENDSTRING(0)):
- return SendString(pdx, (const char __user *)ulArg,
- _IOC_SIZE(cmd));
-
- case _IOC_NR(IOCTL_CED_RESET1401):
- return Reset1401(pdx);
-
- case _IOC_NR(IOCTL_CED_GETCHAR):
- return GetChar(pdx);
-
- case _IOC_NR(IOCTL_CED_SENDCHAR):
- return SendChar(pdx, (char)ulArg);
-
- case _IOC_NR(IOCTL_CED_STAT1401):
- return Stat1401(pdx);
-
- case _IOC_NR(IOCTL_CED_LINECOUNT):
- return LineCount(pdx);
-
- case _IOC_NR(IOCTL_CED_GETSTRING(0)):
- return GetString(pdx, (char __user *)ulArg, _IOC_SIZE(cmd));
-
- case _IOC_NR(IOCTL_CED_SETTRANSFER):
- return SetTransfer(pdx, (struct transfer_area_desc __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_UNSETTRANSFER):
- return UnsetTransfer(pdx, (int)ulArg);
-
- case _IOC_NR(IOCTL_CED_SETEVENT):
- return SetEvent(pdx, (struct transfer_event __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_GETOUTBUFSPACE):
- return GetOutBufSpace(pdx);
-
- case _IOC_NR(IOCTL_CED_GETBASEADDRESS):
- return -1;
-
- case _IOC_NR(IOCTL_CED_GETDRIVERREVISION):
- return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV; /* USB | MAJOR | MINOR */
-
- case _IOC_NR(IOCTL_CED_GETTRANSFER):
- return GetTransfer(pdx, (TGET_TX_BLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_KILLIO1401):
- return KillIO1401(pdx);
-
- case _IOC_NR(IOCTL_CED_STATEOF1401):
- return StateOf1401(pdx);
-
- case _IOC_NR(IOCTL_CED_GRAB1401):
- case _IOC_NR(IOCTL_CED_FREE1401):
- return U14ERR_NOERROR;
-
- case _IOC_NR(IOCTL_CED_STARTSELFTEST):
- return StartSelfTest(pdx);
-
- case _IOC_NR(IOCTL_CED_CHECKSELFTEST):
- return CheckSelfTest(pdx, (TGET_SELFTEST __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_TYPEOF1401):
- return TypeOf1401(pdx);
-
- case _IOC_NR(IOCTL_CED_TRANSFERFLAGS):
- return TransferFlags(pdx);
-
- case _IOC_NR(IOCTL_CED_DBGPEEK):
- return DbgPeek(pdx, (TDBGBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_DBGPOKE):
- return DbgPoke(pdx, (TDBGBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_DBGRAMPDATA):
- return DbgRampData(pdx, (TDBGBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_DBGRAMPADDR):
- return DbgRampAddr(pdx, (TDBGBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_DBGGETDATA):
- return DbgGetData(pdx, (TDBGBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_DBGSTOPLOOP):
- return DbgStopLoop(pdx);
-
- case _IOC_NR(IOCTL_CED_FULLRESET):
- pdx->bForceReset = true; /* Set a flag for a full reset */
- break;
-
- case _IOC_NR(IOCTL_CED_SETCIRCULAR):
- return SetCircular(pdx, (struct transfer_area_desc __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_GETCIRCBLOCK):
- return GetCircBlock(pdx, (TCIRCBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_FREECIRCBLOCK):
- return FreeCircBlock(pdx, (TCIRCBLOCK __user *) ulArg);
-
- case _IOC_NR(IOCTL_CED_WAITEVENT):
- return WaitEvent(pdx, (int)(ulArg & 0xff), (int)(ulArg >> 8));
-
- case _IOC_NR(IOCTL_CED_TESTEVENT):
- return TestEvent(pdx, (int)ulArg);
-
- default:
- return U14ERR_NO_SUCH_FN;
- }
- return U14ERR_NOERROR;
-}
-
-static const struct file_operations ced_fops = {
- .owner = THIS_MODULE,
- .open = ced_open,
- .release = ced_release,
- .flush = ced_flush,
- .llseek = noop_llseek,
- .unlocked_ioctl = ced_ioctl,
-};
-
-/*
- * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with the driver core
- */
-static struct usb_class_driver ced_class = {
- .name = "cedusb%d",
- .fops = &ced_fops,
- .minor_base = USB_CED_MINOR_BASE,
-};
-
-/* Check that the device that matches a 1401 vendor and product ID is OK to use and */
-/* initialise our DEVICE_EXTENSION. */
-static int ced_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- DEVICE_EXTENSION *pdx;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int i, bcdDevice;
- int retval = -ENOMEM;
-
- /* allocate memory for our device extension and initialize it */
- pdx = kzalloc(sizeof(*pdx), GFP_KERNEL);
- if (!pdx)
- goto error;
-
- for (i = 0; i < MAX_TRANSAREAS; ++i) { /* Initialise the wait queues */
- init_waitqueue_head(&pdx->rTransDef[i].wqEvent);
- }
-
- /* Put initialises for our stuff here. Note that all of *pdx is zero, so */
- /* no need to explicitly zero it. */
- spin_lock_init(&pdx->charOutLock);
- spin_lock_init(&pdx->charInLock);
- spin_lock_init(&pdx->stagedLock);
-
- /* Initialises from the skeleton stuff */
- kref_init(&pdx->kref);
- mutex_init(&pdx->io_mutex);
- spin_lock_init(&pdx->err_lock);
- init_usb_anchor(&pdx->submitted);
-
- pdx->udev = usb_get_dev(interface_to_usbdev(interface));
- pdx->interface = interface;
-
- /* Attempt to identify the device */
- bcdDevice = pdx->udev->descriptor.bcdDevice;
- i = (bcdDevice >> 8);
- if (i == 0)
- pdx->s1401Type = TYPEU1401;
- else if ((i >= 1) && (i <= 23))
- pdx->s1401Type = i + 2;
- else {
- dev_err(&interface->dev, "%s: Unknown device. bcdDevice = %d\n",
- __func__, bcdDevice);
- goto error;
- }
- /* set up the endpoint information. We only care about the number of EP as */
- /* we know that we are dealing with a 1401 device. */
- iface_desc = interface->cur_altsetting;
- pdx->nPipes = iface_desc->desc.bNumEndpoints;
- dev_info(&interface->dev, "1401Type=%d with %d End Points\n",
- pdx->s1401Type, pdx->nPipes);
- if ((pdx->nPipes < 3) || (pdx->nPipes > 4))
- goto error;
-
- /* Allocate the URBs we hold for performing transfers */
- pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL); /* character output URB */
- pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL); /* character input URB */
- pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL); /* block transfer URB */
- if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) {
- dev_err(&interface->dev, "%s: URB alloc failed\n", __func__);
- goto error;
- }
-
- pdx->pCoherStagedIO =
- usb_alloc_coherent(pdx->udev, STAGED_SZ, GFP_KERNEL,
- &pdx->pStagedUrb->transfer_dma);
- pdx->pCoherCharOut =
- usb_alloc_coherent(pdx->udev, OUTBUF_SZ, GFP_KERNEL,
- &pdx->pUrbCharOut->transfer_dma);
- pdx->pCoherCharIn =
- usb_alloc_coherent(pdx->udev, INBUF_SZ, GFP_KERNEL,
- &pdx->pUrbCharIn->transfer_dma);
- if (!pdx->pCoherCharOut || !pdx->pCoherCharIn || !pdx->pCoherStagedIO) {
- dev_err(&interface->dev, "%s: Coherent buffer alloc failed\n",
- __func__);
- goto error;
- }
-
- for (i = 0; i < pdx->nPipes; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
- pdx->epAddr[i] = endpoint->bEndpointAddress;
- dev_info(&interface->dev, "Pipe %d, ep address %02x\n",
- i, pdx->epAddr[i]);
- if (((pdx->nPipes == 3) && (i == 0)) || /* if char input end point */
- ((pdx->nPipes == 4) && (i == 1))) {
- pdx->bInterval = endpoint->bInterval; /* save the endpoint interrupt interval */
- dev_info(&interface->dev, "Pipe %d, bInterval = %d\n",
- i, pdx->bInterval);
- }
- /* Detect USB2 by checking last ep size (64 if USB1) */
- if (i == pdx->nPipes - 1) { /* if this is the last ep (bulk) */
- pdx->bIsUSB2 =
- le16_to_cpu(endpoint->wMaxPacketSize) > 64;
- dev_info(&pdx->interface->dev, "USB%d\n",
- pdx->bIsUSB2 + 1);
- }
- }
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, pdx);
-
- /* we can register the device now, as it is ready */
- retval = usb_register_dev(interface, &ced_class);
- if (retval) {
- /* something prevented us from registering this driver */
- dev_err(&interface->dev,
- "Not able to get a minor for this device\n");
- usb_set_intfdata(interface, NULL);
- goto error;
- }
-
- /* let the user know what node this device is now attached to */
- dev_info(&interface->dev,
- "USB CEDUSB device now attached to cedusb #%d\n",
- interface->minor);
- return 0;
-
-error:
- if (pdx)
- kref_put(&pdx->kref, ced_delete); /* frees allocated memory */
- return retval;
-}
-
-static void ced_disconnect(struct usb_interface *interface)
-{
- DEVICE_EXTENSION *pdx = usb_get_intfdata(interface);
- int minor = interface->minor;
- int i;
-
- usb_set_intfdata(interface, NULL); /* remove the pdx from the interface */
- usb_deregister_dev(interface, &ced_class); /* give back our minor device number */
-
- mutex_lock(&pdx->io_mutex); /* stop more I/O starting while... */
- ced_draw_down(pdx); /* ...wait for then kill any io */
- for (i = 0; i < MAX_TRANSAREAS; ++i) {
- int iErr = ClearArea(pdx, i); /* ...release any used memory */
- if (iErr == U14ERR_UNLOCKFAIL)
- dev_err(&pdx->interface->dev, "%s: Area %d was in used\n",
- __func__, i);
- }
- pdx->interface = NULL; /* ...we kill off link to interface */
- mutex_unlock(&pdx->io_mutex);
-
- usb_kill_anchored_urbs(&pdx->submitted);
-
- kref_put(&pdx->kref, ced_delete); /* decrement our usage count */
-
- dev_info(&interface->dev, "USB cedusb #%d now disconnected\n", minor);
-}
-
-/* Wait for all the urbs we know of to be done with, then kill off any that */
-/* are left. NBNB we will need to have a mechanism to stop circular xfers */
-/* from trying to fire off more urbs. We will wait up to 3 seconds for Urbs */
-/* to be done. */
-void ced_draw_down(DEVICE_EXTENSION *pdx)
-{
- int time;
- dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
-
- pdx->bInDrawDown = true;
- time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
- if (!time) { /* if we timed out we kill the urbs */
- usb_kill_anchored_urbs(&pdx->submitted);
- dev_err(&pdx->interface->dev, "%s: timed out\n", __func__);
- }
- pdx->bInDrawDown = false;
-}
-
-static int ced_suspend(struct usb_interface *intf, pm_message_t message)
-{
- DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
- if (!pdx)
- return 0;
- ced_draw_down(pdx);
-
- dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
- return 0;
-}
-
-static int ced_resume(struct usb_interface *intf)
-{
- DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
- if (!pdx)
- return 0;
- dev_dbg(&pdx->interface->dev, "%s: called\n", __func__);
- return 0;
-}
-
-static int ced_pre_reset(struct usb_interface *intf)
-{
- DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
- mutex_lock(&pdx->io_mutex);
- ced_draw_down(pdx);
- return 0;
-}
-
-static int ced_post_reset(struct usb_interface *intf)
-{
- DEVICE_EXTENSION *pdx = usb_get_intfdata(intf);
- dev_dbg(&pdx->interface->dev, "%s\n", __func__);
-
- /* we are sure no URBs are active - no locking needed */
- pdx->errors = -EPIPE;
- mutex_unlock(&pdx->io_mutex);
-
- return 0;
-}
-
-static struct usb_driver ced_driver = {
- .name = "cedusb",
- .probe = ced_probe,
- .disconnect = ced_disconnect,
- .suspend = ced_suspend,
- .resume = ced_resume,
- .pre_reset = ced_pre_reset,
- .post_reset = ced_post_reset,
- .id_table = ced_table,
- .supports_autosuspend = 1,
-};
-
-module_usb_driver(ced_driver);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ced1401/usb1401.h b/drivers/staging/ced1401/usb1401.h
deleted file mode 100644
index ea0fe6398a01..000000000000
--- a/drivers/staging/ced1401/usb1401.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/* usb1401.h
- Header file for the CED 1401 USB device driver for Linux
- Copyright (C) 2010 Cambridge Electronic Design Ltd
- Author Greg P Smith (greg@ced.co.uk)
-
- 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-#ifndef __USB1401_H__
-#define __USB1401_H__
-#include "use1401.h"
-#include "ced_ioctl.h"
-
-#ifndef UINT
-#define UINT unsigned int
-#endif
-
-/** Device type codes, but these don't need to be extended - a succession is assumed
-** These are set for usb from the bcdDevice field (suitably mangled). Future devices
-** will be added in order of device creation to the list, so the names here are just
-** to help use remember which device is which. The U14ERR_... values follow the same
-** pattern for modern devices.a
-**/
-#define TYPEUNKNOWN -1 /* dont know */
-#define TYPE1401 0 /* standard 1401 */
-#define TYPEPLUS 1 /* 1401 plus */
-#define TYPEU1401 2 /* u1401 */
-#define TYPEPOWER 3 /* Power1401 */
-#define TYPEU14012 4 /* u1401 mkII */
-#define TYPEPOWER2 5 /* Power1401 mk II */
-#define TYPEMICRO3 6 /* Micro1401-3 */
-#define TYPEPOWER3 7 /* Power1401-3 */
-
-/* Some useful defines of constants. DONT FORGET to change the version in the */
-/* resources whenever you change it here!. */
-#define DRIVERMAJREV 2 /* driver revision level major (match windows) */
-#define DRIVERMINREV 0 /* driver revision level minor */
-
-/* Definitions of the various block transfer command codes */
-#define TM_EXTTOHOST 8 /* extended tohost */
-#define TM_EXTTO1401 9 /* extended to1401 */
-
-/* Definitions of values in usbReqtype. Used in sorting out setup actions */
-#define H_TO_D 0x00
-#define D_TO_H 0x80
-#define VENDOR 0x40
-#define DEVREQ 0x00
-#define INTREQ 0x01
-#define ENDREQ 0x02
-
-/* Definition of values in usbRequest, again used to sort out setup */
-#define GET_STATUS 0x00
-#define CLEAR_FEATURE 0x01
-#define SET_FEATURE 0x03
-#define SET_ADDRESS 0x05
-#define GET_DESC 0x06
-#define SET_DESC 0x07
-#define GET_CONF 0x08
-#define SET_CONF 0x09
-#define GET_INTERFACE 0x0a
-#define SET_INTERFACE 0x0b
-#define SYNCH_FRAME 0x0c
-
-/* Definitions of the various debug command codes understood by the 1401. These */
-/* are used in various vendor-specific commands to achieve the desired effect */
-#define DB_GRAB 0x50 /* Grab is a NOP for USB */
-#define DB_FREE 0x51 /* Free is a NOP for the USB */
-#define DB_SETADD 0x52 /* Set debug address (double) */
-#define DB_SELFTEST 0x53 /* Start self test */
-#define DB_SETMASK 0x54 /* Set enable mask (double) */
-#define DB_SETDEF 0x55 /* Set default mask (double) */
-#define DB_PEEK 0x56 /* Peek address, save result */
-#define DB_POKE 0x57 /* Poke address with data (double) */
-#define DB_RAMPD 0x58 /* Ramp data at debug address */
-#define DB_RAMPA 0x59 /* Ramp address bus */
-#define DB_REPEATS 0x5A /* Set repeats for operations (double) */
-#define DB_WIDTH 0x5B /* Set width for operations (byte) */
-#define DB_DATA 0x5C /* Get 4-byte data read by PEEK */
-#define DB_CHARS 0x5D /* Send chars via EP0 control write */
-
-#define CR_CHAR 0x0D /* The carriage return character */
-#define CR_CHAR_80 0x8d /* and with bit 7 set */
-
-/* A structure holding information about a block of memory for use in circular transfers */
-typedef struct circBlk {
- volatile UINT dwOffset; /* Offset within area of block start */
- volatile UINT dwSize; /* Size of the block, in bytes (0 = unused) */
-} CIRCBLK;
-
-/* A structure holding all of the information about a transfer area - an area of */
-/* memory set up for use either as a source or destination in DMA transfers. */
-typedef struct transarea {
- void *lpvBuff; /* User address of xfer area saved for completeness */
- UINT dwBaseOffset; /* offset to start of xfer area in first page */
- UINT dwLength; /* Length of xfer area, in bytes */
- struct page **pPages; /* Points at array of locked down pages */
- int nPages; /* number of pages that are locked down */
- bool bUsed; /* Is this structure in use? */
- bool bCircular; /* Is this area for circular transfers? */
- bool bCircToHost; /* Flag for direction of circular transfer */
- bool bEventToHost; /* Set event on transfer to host? */
- int iWakeUp; /* Set 1 on event, cleared by TestEvent() */
- UINT dwEventSt; /* Defines section within xfer area for... */
- UINT dwEventSz; /* ...notification by the event SZ is 0 if unset */
- CIRCBLK aBlocks[2]; /* Info on a pair of circular blocks */
- wait_queue_head_t wqEvent; /* The wait queue for events in this area MUST BE LAST */
-} TRANSAREA;
-
-/* The DMADESC structure is used to hold information on the transfer in progress. It */
-/* is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence. */
-typedef struct dmadesc {
- unsigned short wTransType; /* transfer type as TM_xxx above */
- unsigned short wIdent; /* identifier word */
- unsigned int dwSize; /* bytes to transfer */
- unsigned int dwOffset; /* offset into transfer area for trans */
- bool bOutWard; /* true when data is going TO 1401 */
-} DMADESC;
-
-#define INBUF_SZ 256 /* input buffer size */
-#define OUTBUF_SZ 256 /* output buffer size */
-#define STAGED_SZ 0x10000 /* size of coherent buffer for staged transfers */
-
-/* Structure to hold all of our device specific stuff. We are making this as similar as we */
-/* can to the Windows driver to help in our understanding of what is going on. */
-typedef struct _DEVICE_EXTENSION {
- char inputBuffer[INBUF_SZ]; /* The two buffers */
- char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */
- volatile unsigned int dwNumInput; /* num of chars in input buffer */
- volatile unsigned int dwInBuffGet; /* where to get from input buffer */
- volatile unsigned int dwInBuffPut; /* where to put into input buffer */
- volatile unsigned int dwNumOutput; /* num of chars in output buffer */
- volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/
- volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/
-
- volatile bool bSendCharsPending; /* Flag to indicate sendchar active */
- volatile bool bReadCharsPending; /* Flag to indicate a read is primed */
- char *pCoherCharOut; /* special aligned buffer for chars to 1401 */
- struct urb *pUrbCharOut; /* urb used for chars to 1401 */
- char *pCoherCharIn; /* special aligned buffer for chars to host */
- struct urb *pUrbCharIn; /* urb used for chars to host */
-
- spinlock_t charOutLock; /* to protect the outputBuffer and outputting */
- spinlock_t charInLock; /* to protect the inputBuffer and char reads */
- __u8 bInterval; /* Interrupt end point interval */
-
- volatile unsigned int dwDMAFlag; /* state of DMA */
- TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */
- volatile DMADESC rDMAInfo; /* info on current DMA transfer */
- volatile bool bXFerWaiting; /* Flag set if DMA transfer stalled */
- volatile bool bInDrawDown; /* Flag that we want to halt transfers */
-
- /* Parameters relating to a block read\write that is in progress. Some of these values */
- /* are equivalent to values in rDMAInfo. The values here are those in use, while those */
- /* in rDMAInfo are those received from the 1401 via an escape sequence. If another */
- /* escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these */
- /* are used to finish off the current transfer. */
- volatile short StagedId; /* The transfer area id for this transfer */
- volatile bool StagedRead; /* Flag TRUE for read from 1401, FALSE for write */
- volatile unsigned int StagedLength; /* Total length of this transfer */
- volatile unsigned int StagedOffset; /* Offset within memory area for transfer start */
- volatile unsigned int StagedDone; /* Bytes transferred so far */
- volatile bool bStagedUrbPending; /* Flag to indicate active */
- char *pCoherStagedIO; /* buffer used for block transfers */
- struct urb *pStagedUrb; /* The URB to use */
- spinlock_t stagedLock; /* protects ReadWriteMem() and circular buffer stuff */
-
- short s1401Type; /* type of 1401 attached */
- short sCurrentState; /* current error state */
- bool bIsUSB2; /* type of the interface we connect to */
- bool bForceReset; /* Flag to make sure we get a real reset */
- __u32 statBuf[2]; /* buffer for 1401 state info */
-
- unsigned long ulSelfTestTime; /* used to timeout self test */
-
- int nPipes; /* Should be 3 or 4 depending on 1401 usb chip */
- int bPipeError[4]; /* set non-zero if an error on one of the pipe */
- __u8 epAddr[4]; /* addresses of the 3/4 end points */
-
- struct usb_device *udev; /* the usb device for this device */
- struct usb_interface *interface; /* the interface for this device, NULL if removed */
- struct usb_anchor submitted; /* in case we need to retract our submissions */
- struct mutex io_mutex; /* synchronize I/O with disconnect, one user-mode caller at a time */
-
- int errors; /* the last request tanked */
- int open_count; /* count the number of openers */
- spinlock_t err_lock; /* lock for errors */
- struct kref kref;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-#define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref)
-
-/* Definitions of routimes used between compilation object files */
-/* in usb1401.c */
-extern int Allowi(DEVICE_EXTENSION *pdx);
-extern int SendChars(DEVICE_EXTENSION *pdx);
-extern void ced_draw_down(DEVICE_EXTENSION *pdx);
-extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
- unsigned int dwOffs, unsigned int dwLen);
-
-/* in ced_ioc.c */
-extern int ClearArea(DEVICE_EXTENSION *pdx, int nArea);
-extern int SendString(DEVICE_EXTENSION *pdx, const char __user *pData, unsigned int n);
-extern int SendChar(DEVICE_EXTENSION *pdx, char c);
-extern int Get1401State(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error);
-extern int ReadWrite_Cancel(DEVICE_EXTENSION *pdx);
-extern bool Is1401(DEVICE_EXTENSION *pdx);
-extern bool QuickCheck(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanReset);
-extern int Reset1401(DEVICE_EXTENSION *pdx);
-extern int GetChar(DEVICE_EXTENSION *pdx);
-extern int GetString(DEVICE_EXTENSION *pdx, char __user *pUser, int n);
-extern int SetTransfer(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD);
-extern int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea);
-extern int SetEvent(DEVICE_EXTENSION *pdx, struct transfer_event __user *pTE);
-extern int Stat1401(DEVICE_EXTENSION *pdx);
-extern int LineCount(DEVICE_EXTENSION *pdx);
-extern int GetOutBufSpace(DEVICE_EXTENSION *pdx);
-extern int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB);
-extern int KillIO1401(DEVICE_EXTENSION *pdx);
-extern int BlkTransState(DEVICE_EXTENSION *pdx);
-extern int StateOf1401(DEVICE_EXTENSION *pdx);
-extern int StartSelfTest(DEVICE_EXTENSION *pdx);
-extern int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST);
-extern int TypeOf1401(DEVICE_EXTENSION *pdx);
-extern int TransferFlags(DEVICE_EXTENSION *pdx);
-extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
-extern int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
-extern int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
-extern int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
-extern int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
-extern int DbgStopLoop(DEVICE_EXTENSION *pdx);
-extern int SetCircular(DEVICE_EXTENSION *pdx, struct transfer_area_desc __user *pTD);
-extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
-extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
-extern int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut);
-extern int TestEvent(DEVICE_EXTENSION *pdx, int nArea);
-#endif
diff --git a/drivers/staging/ced1401/use1401.h b/drivers/staging/ced1401/use1401.h
deleted file mode 100644
index b7997c9835c2..000000000000
--- a/drivers/staging/ced1401/use1401.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/****************************************************************************
-** use1401.h
-** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010
-** Authors: Paul Cox, Tim Bergel, Greg Smith
-** See CVS for revisions.
-**
-** Because the size of a long is different between 32-bit and 64-bit on some
-** systems, we avoid this in this interface.
-****************************************************************************/
-#ifndef __USE1401_H__
-#define __USE1401_H__
-#include "machine.h"
-
-/* Some definitions to make things compatible. If you want to use Use1401 directly */
-/* from a Windows program you should define U14_NOT_DLL, in which case you also */
-/* MUST make sure that your application startup code calls U14InitLib(). */
-/* DLL_USE1401 is defined when you are building the Use1401 dll, not otherwise. */
-#ifdef _IS_WINDOWS_
-#ifndef U14_NOT_DLL
-#ifdef DLL_USE1401
-#define U14API(retType) (retType DllExport __stdcall)
-#else
-#define U14API(retType) (retType DllImport __stdcall)
-#endif
-#endif
-
-#define U14ERRBASE -500
-#define U14LONG long
-#endif
-
-#ifdef LINUX
-#define U14ERRBASE -1000
-#define U14LONG int
-#endif
-
-#ifdef _QT
-#ifndef U14_NOT_DLL
-#undef U14API
-#define U14API(retType) (retType __declspec(dllimport) __stdcall)
-#endif
-#undef U14LONG
-#define U14LONG int
-#endif
-
-#ifndef U14API
-#define U14API(retType) retType
-#endif
-
-#ifndef U14LONG
-#define U14LONG long
-#endif
-
-/* Error codes: We need them here as user space can see them. */
-#define U14ERR_NOERROR 0 /* no problems */
-
-/* Device error codes, but these don't need to be extended - a succession is assumed */
-#define U14ERR_STD 4 /* standard 1401 connected */
-#define U14ERR_U1401 5 /* u1401 connected */
-#define U14ERR_PLUS 6 /* 1401 plus connected */
-#define U14ERR_POWER 7 /* Power1401 connected */
-#define U14ERR_U14012 8 /* u1401 mkII connected */
-#define U14ERR_POWER2 9
-#define U14ERR_U14013 10
-#define U14ERR_POWER3 11
-
-/* NBNB Error numbers need shifting as some linux error codes start at 512 */
-#define U14ERR(n) (n+U14ERRBASE)
-#define U14ERR_OFF U14ERR(0) /* 1401 there but switched off */
-#define U14ERR_NC U14ERR(-1) /* 1401 not connected */
-#define U14ERR_ILL U14ERR(-2) /* if present it is ill */
-#define U14ERR_NOIF U14ERR(-3) /* I/F card missing */
-#define U14ERR_TIME U14ERR(-4) /* 1401 failed to come ready */
-#define U14ERR_BADSW U14ERR(-5) /* I/F card bad switches */
-#define U14ERR_PTIME U14ERR(-6) /* 1401plus failed to come ready */
-#define U14ERR_NOINT U14ERR(-7) /* couldn't grab the int vector */
-#define U14ERR_INUSE U14ERR(-8) /* 1401 is already in use */
-#define U14ERR_NODMA U14ERR(-9) /* couldn't get DMA channel */
-#define U14ERR_BADHAND U14ERR(-10) /* handle provided was bad */
-#define U14ERR_BAD1401NUM U14ERR(-11) /* 1401 number provided was bad */
-
-#define U14ERR_NO_SUCH_FN U14ERR(-20) /* no such function */
-#define U14ERR_NO_SUCH_SUBFN U14ERR(-21) /* no such sub function */
-#define U14ERR_NOOUT U14ERR(-22) /* no room in output buffer */
-#define U14ERR_NOIN U14ERR(-23) /* no input in buffer */
-#define U14ERR_STRLEN U14ERR(-24) /* string longer than buffer */
-#define U14ERR_ERR_STRLEN U14ERR(-24) /* string longer than buffer */
-#define U14ERR_LOCKFAIL U14ERR(-25) /* failed to lock memory */
-#define U14ERR_UNLOCKFAIL U14ERR(-26) /* failed to unlock memory */
-#define U14ERR_ALREADYSET U14ERR(-27) /* area already set up */
-#define U14ERR_NOTSET U14ERR(-28) /* area not set up */
-#define U14ERR_BADAREA U14ERR(-29) /* illegal area number */
-#define U14ERR_FAIL U14ERR(-30) /* we failed for some other reason*/
-
-#define U14ERR_NOFILE U14ERR(-40) /* command file not found */
-#define U14ERR_READERR U14ERR(-41) /* error reading command file */
-#define U14ERR_UNKNOWN U14ERR(-42) /* unknown command */
-#define U14ERR_HOSTSPACE U14ERR(-43) /* not enough host space to load */
-#define U14ERR_LOCKERR U14ERR(-44) /* could not lock resource/command*/
-#define U14ERR_CLOADERR U14ERR(-45) /* CLOAD command failed */
-
-#define U14ERR_TOXXXERR U14ERR(-60) /* tohost/1401 failed */
-#define U14ERR_NO386ENH U14ERR(-80) /* not 386 enhanced mode */
-#define U14ERR_NO1401DRIV U14ERR(-81) /* no device driver */
-#define U14ERR_DRIVTOOOLD U14ERR(-82) /* device driver too old */
-
-#define U14ERR_TIMEOUT U14ERR(-90) /* timeout occurred */
-
-#define U14ERR_BUFF_SMALL U14ERR(-100) /* buffer for getstring too small */
-#define U14ERR_CBALREADY U14ERR(-101) /* there is already a callback */
-#define U14ERR_BADDEREG U14ERR(-102) /* bad parameter to deregcallback */
-#define U14ERR_NOMEMORY U14ERR(-103) /* no memory for allocation */
-
-#define U14ERR_DRIVCOMMS U14ERR(-110) /* failed talking to driver */
-#define U14ERR_OUTOFMEMORY U14ERR(-111) /* needed memory and couldnt get it*/
-
-/* / 1401 type codes. */
-#define U14TYPE1401 0 /* standard 1401 */
-#define U14TYPEPLUS 1 /* 1401 plus */
-#define U14TYPEU1401 2 /* u1401 */
-#define U14TYPEPOWER 3 /* power1401 */
-#define U14TYPEU14012 4 /* u1401 mk II */
-#define U14TYPEPOWER2 5 /* power1401 mk II */
-#define U14TYPEU14013 6 /* u1401-3 */
-#define U14TYPEPOWER3 7 /* power1401-3 */
-#define U14TYPEUNKNOWN -1 /* dont know */
-
-/* Transfer flags to allow driver capabilities to be interrogated */
-
-/* Constants for transfer flags */
-#define U14TF_USEDMA 1 /* Transfer flag for use DMA */
-#define U14TF_MULTIA 2 /* Transfer flag for multi areas */
-#define U14TF_FIFO 4 /* for FIFO interface card */
-#define U14TF_USB2 8 /* for USB2 interface and 1401 */
-#define U14TF_NOTIFY 16 /* for event notifications */
-#define U14TF_SHORT 32 /* for PCI can short cycle */
-#define U14TF_PCI2 64 /* for new PCI card 1401-70 */
-#define U14TF_CIRCTH 128 /* Circular-mode to host */
-#define U14TF_DIAG 256 /* Diagnostics/debug functions */
-#define U14TF_CIRC14 512 /* Circular-mode to 1401 */
-
-/* Definitions of element sizes for DMA transfers - to allow byte-swapping */
-#define ESZBYTES 0 /* BYTE element size value */
-#define ESZWORDS 1 /* unsigned short element size value */
-#define ESZLONGS 2 /* long element size value */
-#define ESZUNKNOWN 0 /* unknown element size value */
-
-/* These define required access types for the debug/diagnostics function */
-#define BYTE_SIZE 1 /* 8-bit access */
-#define WORD_SIZE 2 /* 16-bit access */
-#define LONG_SIZE 3 /* 32-bit access */
-
-/* Stuff used by U14_GetTransfer */
-#define GET_TX_MAXENTRIES 257 /* (max length / page size + 1) */
-
-#ifdef _IS_WINDOWS_
-#pragma pack(1)
-
-typedef struct /* used for U14_GetTransfer results */
-{ /* Info on a single mapped block */
- U14LONG physical;
- U14LONG size;
-} TXENTRY;
-
-typedef struct TGetTxBlock /* used for U14_GetTransfer results */
-{ /* matches structure in VXD */
- U14LONG size;
- U14LONG linear;
- short seg;
- short reserved;
- short avail; /* number of available entries */
- short used; /* number of used entries */
- TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
-} TGET_TX_BLOCK;
-
-typedef TGET_TX_BLOCK *LPGET_TX_BLOCK;
-
-#pragma pack()
-#endif
-
-#ifdef LINUX
-typedef struct /* used for U14_GetTransfer results */
-{ /* Info on a single mapped block */
- long long physical;
- long size;
-} TXENTRY;
-
-typedef struct TGetTxBlock /* used for U14_GetTransfer results */
-{ /* matches structure in VXD */
- long long linear; /* linear address */
- long size; /* total size of the mapped area, holds id when called */
- short seg; /* segment of the address for Win16 */
- short reserved;
- short avail; /* number of available entries */
- short used; /* number of used entries */
- TXENTRY entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
-} TGET_TX_BLOCK;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-U14API(int) U14WhenToTimeOut(short hand); /* when to timeout in ms */
-U14API(short) U14PassedTime(int iTime); /* non-zero if iTime passed */
-
-U14API(short) U14LastErrCode(short hand);
-
-U14API(short) U14Open1401(short n1401);
-U14API(short) U14Close1401(short hand);
-U14API(short) U14Reset1401(short hand);
-U14API(short) U14ForceReset(short hand);
-U14API(short) U14TypeOf1401(short hand);
-U14API(short) U14NameOf1401(short hand, char *pBuf, unsigned short wMax);
-
-U14API(short) U14Stat1401(short hand);
-U14API(short) U14CharCount(short hand);
-U14API(short) U14LineCount(short hand);
-
-U14API(short) U14SendString(short hand, const char *pString);
-U14API(short) U14GetString(short hand, char *pBuffer, unsigned short wMaxLen);
-U14API(short) U14SendChar(short hand, char cChar);
-U14API(short) U14GetChar(short hand, char *pcChar);
-
-U14API(short) U14LdCmd(short hand, const char *command);
-U14API(unsigned int) U14Ld(short hand, const char *vl, const char *str);
-
-U14API(short) U14SetTransArea(short hand, unsigned short wArea, void *pvBuff,
- unsigned int dwLength, short eSz);
-U14API(short) U14UnSetTransfer(short hand, unsigned short wArea);
-U14API(short) U14SetTransferEvent(short hand, unsigned short wArea, BOOL bEvent,
- BOOL bToHost, unsigned int dwStart, unsigned int dwLength);
-U14API(int) U14TestTransferEvent(short hand, unsigned short wArea);
-U14API(int) U14WaitTransferEvent(short hand, unsigned short wArea, int msTimeOut);
-U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock);
-
-U14API(short) U14ToHost(short hand, char *pAddrHost, unsigned int dwSize, unsigned int dw1401,
- short eSz);
-U14API(short) U14To1401(short hand, const char *pAddrHost, unsigned int dwSize, unsigned int dw1401,
- short eSz);
-
-U14API(short) U14SetCircular(short hand, unsigned short wArea, BOOL bToHost, void *pvBuff,
- unsigned int dwLength);
-
-U14API(int) U14GetCircBlk(short hand, unsigned short wArea, unsigned int *pdwOffs);
-U14API(int) U14FreeCircBlk(short hand, unsigned short wArea, unsigned int dwOffs, unsigned int dwSize,
- unsigned int *pdwOffs);
-
-U14API(short) U14StrToLongs(const char *pszBuff, U14LONG *palNums, short sMaxLongs);
-U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs);
-
-U14API(void) U14SetTimeout(short hand, int lTimeout);
-U14API(int) U14GetTimeout(short hand);
-U14API(short) U14OutBufSpace(short hand);
-U14API(int) U14BaseAddr1401(short hand);
-U14API(int) U14DriverVersion(short hand);
-U14API(int) U14DriverType(short hand);
-U14API(short) U14DriverName(short hand, char *pBuf, unsigned short wMax);
-U14API(short) U14GetUserMemorySize(short hand, unsigned int *pMemorySize);
-U14API(short) U14KillIO1401(short hand);
-
-U14API(short) U14BlkTransState(short hand);
-U14API(short) U14StateOf1401(short hand);
-
-U14API(short) U14Grab1401(short hand);
-U14API(short) U14Free1401(short hand);
-U14API(short) U14Peek1401(short hand, unsigned int dwAddr, int nSize, int nRepeats);
-U14API(short) U14Poke1401(short hand, unsigned int dwAddr, unsigned int dwValue, int nSize, int nRepeats);
-U14API(short) U14Ramp1401(short hand, unsigned int dwAddr, unsigned int dwDef, unsigned int dwEnable, int nSize, int nRepeats);
-U14API(short) U14RampAddr(short hand, unsigned int dwDef, unsigned int dwEnable, int nSize, int nRepeats);
-U14API(short) U14StopDebugLoop(short hand);
-U14API(short) U14GetDebugData(short hand, U14LONG *plValue);
-
-U14API(short) U14StartSelfTest(short hand);
-U14API(short) U14CheckSelfTest(short hand, U14LONG *pData);
-U14API(short) U14TransferFlags(short hand);
-U14API(void) U14GetErrorString(short nErr, char *pStr, unsigned short wMax);
-U14API(int) U14MonitorRev(short hand);
-U14API(void) U14CloseAll(void);
-
-U14API(short) U14WorkingSet(unsigned int dwMinKb, unsigned int dwMaxKb);
-U14API(int) U14InitLib(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* End of ifndef __USE1401_H__ */
-
diff --git a/drivers/staging/ced1401/use14_ioc.h b/drivers/staging/ced1401/use14_ioc.h
deleted file mode 100644
index 42d2e4e6e9a9..000000000000
--- a/drivers/staging/ced1401/use14_ioc.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* use14_ioc.h
-** definitions of use1401 module stuff that is shared between use1401 and the driver.
-** Copyright (C) Cambridge Electronic Design Limited 2010
-** Author Greg P Smith
-************************************************************************************/
-#ifndef __USE14_IOC_H__
-#define __USE14_IOC_H__
-
-#define MAX_TRANSAREAS 8 /* The number of transfer areas supported by driver */
-
-#define i386
-#include "winioctl.h" /* needed so we can access driver */
-
-/*
-** Defines for IOCTL functions to ask driver to perform. These must be matched
-** in both use1401 and in the driver. The IOCTL code contains a command
-** identifier, plus other information about the device, the type of access
-** with which the file must have been opened, and the type of buffering.
-** The IOCTL function codes from 0x80 to 0xFF are for developer use.
-*/
-#define FILE_DEVICE_CED1401 0x8001
- FNNUMBASE 0x800
-
-#define U14_OPEN1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_CLOSE1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+1, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SENDSTRING CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+2, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_RESET1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+3, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETCHAR CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+4, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SENDCHAR CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+5, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STAT1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+6, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_LINECOUNT CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+7, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETSTRING CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+8, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_REGCALLBACK CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+9, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETMONITORBUF CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+10, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SETTRANSFER CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+11, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_UNSETTRANSFER CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+12, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SETTRANSEVENT CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+13, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETOUTBUFSPACE CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+14, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETBASEADDRESS CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+15, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETDRIVERREVISION CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+16, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETTRANSFER CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+17, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_KILLIO1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+18, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_BLKTRANSSTATE CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+19, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_BYTECOUNT CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+20, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_ZEROBLOCKCOUNT CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+21, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STOPCIRCULAR CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+22, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STATEOF1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+23, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_REGISTERS1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+24, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GRAB1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+25, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_FREE1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+26, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STEP1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+27, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SET1401REGISTERS CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+28, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STEPTILL1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+29, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SETORIN CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+30, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_STARTSELFTEST CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+31, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_CHECKSELFTEST CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+32, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_TYPEOF1401 CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+33, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_TRANSFERFLAGS CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+34, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGPEEK CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+35, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGPOKE CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+36, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGRAMPDATA CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+37, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGRAMPADDR CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+38, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGGETDATA CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+39, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_DBGSTOPLOOP CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+40, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_FULLRESET CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+41, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_SETCIRCULAR CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+42, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_GETCIRCBLK CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+43, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define U14_FREECIRCBLK CTL_CODE(FILE_DEVICE_CED1401, \
- FNNUMBASE+44, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-/*--------------- Structures that are shared with the driver ------------- */
-#pragma pack(1)
-
-typedef struct /* used for get/set standard 1401 registers */
-{
- short sPC;
- char A;
- char X;
- char Y;
- char stat;
- char rubbish;
-} T1401REGISTERS;
-
-typedef union /* to communicate with 1401 driver status & control funcs */
-{
- char chrs[22];
- short ints[11];
- long longs[5];
- T1401REGISTERS registers;
-} TCSBLOCK;
-
-typedef TCSBLOCK* LPTCSBLOCK;
-
-typedef struct paramBlk {
- short sState;
- TCSBLOCK csBlock;
-} PARAMBLK;
-
-typedef PARAMBLK* PPARAMBLK;
-
-struct transfer_area_desc /* Structure and type for SetTransArea */
-{
- unsigned short wArea; /* number of transfer area to set up */
- void FAR *lpvBuff; /* address of transfer area */
- unsigned int dwLength; /* length of area to set up */
- short eSize; /* size to move (for swapping on MAC) */
-};
-
-
-/* This is the structure used to set up a transfer area */
-typedef struct VXTransferDesc /* use1401.c and use1432x.x use only */
-{
- unsigned short wArea; /* number of transfer area to set up */
- unsigned short wAddrSel; /* 16 bit selector for area */
- unsigned int dwAddrOfs; /* 32 bit offset for area start */
- unsigned int dwLength; /* length of area to set up */
-} VXTRANSFERDESC;
-
-#pragma pack()
-
-#endif
diff --git a/drivers/staging/ced1401/userspace/use1401.c b/drivers/staging/ced1401/userspace/use1401.c
deleted file mode 100644
index 7b8a2227fe5b..000000000000
--- a/drivers/staging/ced1401/userspace/use1401.c
+++ /dev/null
@@ -1,3035 +0,0 @@
-/****************************************************************************
-** use1401.c
-** Copyright (C) Cambridge Electronic Design Ltd, 1992-2010
-**
-** 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-**
-** Contact CED: Cambridge Electronic Design Limited, Science Park, Milton Road
-** Cambridge, CB6 0FE.
-** www.ced.co.uk
-** greg@ced.co.uk
-**
-** Title: USE1401.C
-** Version: 4.00
-** Author: Paul Cox, Tim Bergel, Greg Smith
-**
-** The code was vigorously pruned in DEC 2010 to remove the macintosh options
-** and to get rid of the 16-bit support. It has also been aligned with the
-** Linux version. See CVS for revisions. This will work for Win 9x onwards.
-****************************************************************************
-**
-** Notes on Windows interface to driver
-** ************************************
-**
-** Under Windows 9x and NT, Use1401 uses DeviceIoControl to get access to
-** the 1401 driver. This has parameters for the device handle, the function
-** code, an input pointer and byte count, an output pointer and byte count
-** and a pointer to a unsigned int to hold the output byte count. Note that input
-** and output are from the point-of-view of the driver, so the output stuff
-** is used to read values from the 1401, not send to the 1401. The use of
-** these parameters varies with the function in use and the operating
-** system; there are five separate DIOC calls SendString, GetString and
-** SetTransferArea all have their own specialised calls, the rest use the
-** Status1401 or Control1401 functions.
-**
-** There are two basic styles of DIOC call used, one for Win9x VxD drivers
-** and one for NT Kernel-mode and WDM drivers (see below for tables showing
-** the different parameters used. The array bUseNTDIOC[] selects between
-** these two calling styles.
-**
-** Function codes
-** In Win3.x, simple function codes from 0 to 40 were used, shifted left 8
-** bits with a sub-function code in the lower 8 bits. These were also used
-** in the Windows 95 driver, though we had to add 1 to the code value to
-** avoid problems (Open from CreateFile is zero), and the sub-function code
-** is now unused. We found that this gave some problems with Windows 98
-** as the function code values are reserved by microsoft, so we switched to
-** using the NT function codes instead. The NT codes are generated using the
-** CTL_CODE macro, essentially this gives 0x80012000 | (func << 2), where
-** func is the original 0 to 34 value. The driver will handle both types of
-** code and Use1432 only uses the NT codes if it knows the driver is new
-** enough. The array bUseNTCodes[] holds flags on the type of codes required.
-** GPS/TDB Dec 2010: we removed the bUseNTCodes array as this is always true
-** as we no longer support ancient versions.
-**
-** The CreateFile and CloseFile function calls are also handled
-** by DIOC, using the special function codes 0 and -1 respectively.
-**
-** Input pointer and buffer size
-** These are intended for data sent to the device driver. In nearly all cases
-** they are unused in calls to the Win95 driver, the NT driver uses them
-** for all information sent to the driver. The table below shows the pointer
-** and byte count used for the various calls:
-**
-** Win 95 Win NT
-** SendString NULL, 0 pStr, nStr
-** GetString NULL, 0 NULL, 0
-** SetTransferArea pBuf, nBuf (unused?) pDesc, nDesc
-** GetTransfer NULL, 0 NULL, 0
-** Status1401 NULL, 0 NULL, 0
-** Control1401 NULL, 0 pBlk, nBlk
-**
-** pStr and nStr are pointers to a char buffer and the buffer length for
-** string I/O, note that these are temporary buffers owned by the DLL, not
-** application memory, pBuf and nBuf are the transfer area buffer (I think
-** these are unused), pDesc and nDesc are the TRANSFERDESC structure, pBlk
-** and nBlk are the TCSBLOCK structure.
-**
-**
-** Output pointer and buffer size
-** These are intended for data read from the device driver. These are used
-** for almost all information sent to the Win95 driver, the NT driver uses
-** them for information read from the driver, chiefly the error code. The
-** table below shows the pointer and byte count used for the various calls:
-**
-** Win 95 Win NT
-** SendString pStr, nStr pPar, nPar
-** GetString pStr, nStr+2 pStr, nStr+2
-** SetTransferArea pDesc, nDesc pPar, nPar
-** GetTransfer pGet, nGet pGet, nGet
-** Status1401 pBlk, nBlk pPar, nPar
-** Control1401 pBlk, nBlk pPar, nPar
-**
-** pStr and nStr are pointers to a char buffer and the buffer length for
-** string I/O, the +2 for GetString refers to two spare bytes at the start
-** used to hold the string length and returning an error code for NT. Note
-** again that these are (and must be) DLL-owned temporary buffers. pPar
-** and nPar are a PARAM structure used in NT (it holds an error code and a
-** TCSBLOCK structure). pDesc and nDesc are the VXTRANSFERDESC structure,
-** pBlk and nBlk are the TCSBLOCK structure. pGet and nGet indicate the
-** TGET_TX_BLOCK structure used for GetTransfer.
-**
-**
-** The output byte count
-** Both drivers return the output buffer size here, regardless of the actual
-** bytes output. This is used to check that we did get through to the driver.
-**
-** Multiple 1401s
-** **************
-**
-** We have code that tries to support the use of multiple 1401s, but there
-** are problems: The lDriverVersion and lDriverType variables are global, not
-** per-1401 (a particular problem as the U14 functions that use them don't
-** have a hand parameter). In addition, the mechansim for finding a free
-** 1401 depends upon the 1401 device driver open operation failing if it's
-** already in use, which doesn't always happen, particularly with the VxDs.
-** The code in TryToOpen tries to fix this by relying on TYPEOF1401 to detect
-** the 1401-in-use state - the VxDs contain special code to help this. This is
-** working OK but multiple 1401 support works better with the Win2000 drivers.
-**
-** USB driver
-** **********
-**
-** The USB driver, which runs on both Win98 and NT2000, uses the NT-style
-** calling convention, both for the DIOC codes and the DIOC parameters. The
-** TryToOpen function has been altered to look for an NT driver first in
-** the appropriate circumstances, and to set the driver DIOC flags up in
-** the correct state.
-**
-** Adding a new 1401 type - now almost nothing to do
-** *************************************************
-**
-** The 1401 types are defined by a set of U14TYPExxxx codes in USE1401.H.
-** You should add a new one of these to keep things tidy for applications.
-**
-** DRIVERET_MAX (below) specifies the maximum allowed type code from the
-** 1401 driver; I have set this high to accommodate as yet undesigned 1401
-** types. Similarly, as long as the command file names follow the ARM,
-** ARN, ARO sequence, these are calculated by the ExtForType function, so
-** you don't need to do anything here either.
-**
-** Version number
-** **************
-** The new U14InitLib() function returns 0 if the OS is incapable of use,
-** otherwise is returns the version of the USE1401 library. This is done
-** in three parts: Major(31-24).Minor(23-16).Revision.(15-0) (brackets are
-** the bits used). The Major number starts at 2 for the first revision with
-** the U14InitLib() function. Changes to the Major version means that we
-** have broken backwards compatibility. Minor number changes mean that we
-** have added new functionality that does not break backwards compatibility.
-** we starts at 0. Revision changes mean we have fixed something. Each index
-** returns to 0 when a higher one changes.
-*/
-#define U14LIB_MAJOR 4
-#define U14LIB_MINOR 0
-#define U14LIB_REVISION 0
-#define U14LIB_VERSION ((U14LIB_MAJOR<<24) | (U14LIB_MINOR<<16) | U14LIB_REVISION)
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "USE1401.H"
-
-#ifdef _IS_WINDOWS_
-#include <io.h>
-#include <windows.h>
-#pragma warning(disable: 4100) /* Disable "Unused formal parameter" warning */
-#include <assert.h>
-#include "process.h"
-
-
-#define sprintf wsprintf
-#define PATHSEP '\\'
-#define PATHSEPSTR "\\"
-#define DEFCMDPATH "\\1401\\" // default command path if all else fails
-#define MINDRIVERMAJREV 1 // minimum driver revision level we need
-#define __packed // does nothing in Windows
-
-#include "use14_ioc.h" // links to device driver stuff
-#endif
-
-#ifdef LINUX
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sched.h>
-#include <libgen.h>
-#define PATHSEP '/'
-#define PATHSEPSTR "/"
-#define DEFCMDPATH "/var/1401/" // default command path if all else fails
-#define MINDRIVERMAJREV 2 // minimum driver revision level we need
-
-#include "ced_ioctl.h" // links to device driver stuff
-#endif
-
-#define MAX1401 8 // The number of 1401s that can be supported
-
-/*
-** These are the 1401 type codes returned by the driver, they are a slightly
-** odd sequence & start for reasons of compatibility with the DOS driver.
-** The maximum code value is the upper limit of 1401 device types.
-*/
-#define DRIVRET_STD 4 // Codes for 1401 types matching driver values
-#define DRIVRET_U1401 5 // This table does not need extending, as
-#define DRIVRET_PLUS 6 // we can calculate values now.
-#define DRIVRET_POWER 7 // but we need all of these values still
-#define DRIVRET_MAX 26 // Maximum tolerated code - future designs
-
-/*
-** These variables store data that will be used to generate the last
-** error string. For now, a string will hold the 1401 command file name.
-*/
-static char szLastName[20]; // additional text information
-
-/*
-** Information stored per handle. NBNB, driverType and DriverVersion used to be
-** only stored once for all handles... i.e. nonsensical. This change means that
-** three U14...() calls now include handles that were previously void. We have
-** set a constructor and a destructor call for the library (see the end) to
-** initialise important structures, or call use1401_load().
-*/
-static short asDriverType[MAX1401] = {0};
-static int lLastDriverVersion = U14ERR_NO1401DRIV;
-static int lLastDriverType = U14TYPEUNKNOWN;
-static int alDriverVersion[MAX1401]; // version/type of each driver
-static int alTimeOutPeriod[MAX1401]; // timeout time in milliseconds
-static short asLastRetCode[MAX1401]; // last code from a fn call
-static short asType1401[MAX1401] = {0}; // The type of the 1401
-static BOOL abGrabbed[MAX1401] = {0}; // Flag for grabbed, set true by grab1401
-static int iAttached = 0; // counts process attaches so can let go
-
-#ifdef _IS_WINDOWS_
-/****************************************************************************
-** Windows NT Specific Variables and internal types
-****************************************************************************/
-static HANDLE aHand1401[MAX1401] = {0}; // handles for 1401s
-static HANDLE aXferEvent[MAX1401] = {0}; // transfer events for the 1401s
-static LPVOID apAreas[MAX1401][MAX_TRANSAREAS]; // Locked areas
-static unsigned int auAreas[MAX1401][MAX_TRANSAREAS]; // Size of locked areas
-static BOOL bWindows9x = FALSE; // if we are Windows 95 or better
-#ifdef _WIN64
-#define USE_NT_DIOC(ind) TRUE
-#else
-static BOOL abUseNTDIOC[MAX1401]; // Use NT-style DIOC parameters */
-#define USE_NT_DIOC(ind) abUseNTDIOC[ind]
-#endif
-
-#endif
-
-#ifdef LINUX
-static int aHand1401[MAX1401] = {0}; // handles for 1401s
-#define INVALID_HANDLE_VALUE 0 // to avoid code differences
-#endif
-
-
-/*
-** The CmdHead relates to backwards compatibility with ancient Microsoft (and Sperry!)
-** versions of BASIC, where this header was needed so we could load a command into
-** memory.
-*/
-#pragma pack(1) // pack our structure
-typedef struct CmdHead // defines header block on command
-{ // for PC commands
- char acBasic[5]; // BASIC information - needed to align things
- unsigned short wBasicSz; // size as seen by BASIC
- unsigned short wCmdSize; // size of the following info
-} __packed CMDHEAD;
-#pragma pack() // back to normal
-
-/*
-** The rest of the header looks like this...
-** int iRelPnt; relocation pointer... actual start
-** char acName[8]; string holding the command name
-** BYTE bMonRev; monitor revision level
-** BYTE bCmdRev; command revision level
-*/
-
-typedef CMDHEAD *LPCMDHEAD; // pointer to a command header
-
-#define MAXSTRLEN 255 // maximum string length we use
-#define TOHOST FALSE
-#define TO1401 TRUE
-
-static short CheckHandle(short h)
-{
- if ((h < 0) || (h >= MAX1401)) // must be legal range...
- return U14ERR_BADHAND;
- if (aHand1401[h] <= 0) // must be open
- return U14ERR_BADHAND;
- return U14ERR_NOERROR;
-}
-
-#ifdef _IS_WINDOWS_
-/****************************************************************************
-** U14Status1401 Used for functions which do not pass any data in but
-** get data back
-****************************************************************************/
-static short U14Status1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
-{
- unsigned int dwBytes = 0;
-
- if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */
- return U14ERR_BADHAND;
-#ifndef _WIN64
- if (!USE_NT_DIOC(sHand))
- { /* Windows 9x DIOC methods? */
- if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk,sizeof(TCSBLOCK),&dwBytes,NULL))
- return (short)((dwBytes>=sizeof(TCSBLOCK)) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS);
- else
- return (short)GetLastError();
- }
- else
-#endif
- { /* Windows NT or USB driver */
- PARAMBLK rWork;
- rWork.sState = U14ERR_DRIVCOMMS;
- if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, &rWork,sizeof(PARAMBLK),&dwBytes,NULL) &&
- (dwBytes >= sizeof(PARAMBLK)))
- {
- *pBlk = rWork.csBlock;
- return rWork.sState;
- }
- }
-
- return U14ERR_DRIVCOMMS;
-}
-
-/****************************************************************************
-** U14Control1401 Used for functions which pass data in and only expect
-** an error code back
-****************************************************************************/
-static short U14Control1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
-{
- unsigned int dwBytes = 0;
-
- if ((sHand < 0) || (sHand >= MAX1401)) /* Check parameters */
- return U14ERR_BADHAND;
-
-#ifndef _WIN64
- if (!USE_NT_DIOC(sHand))
- { /* Windows 9x DIOC methods */
- if (DeviceIoControl(aHand1401[sHand], lCode, NULL, 0, pBlk, sizeof(TCSBLOCK), &dwBytes, NULL))
- return (short)(dwBytes >= sizeof(TCSBLOCK) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS);
- else
- return (short)GetLastError();
- }
- else
-#endif
- { /* Windows NT or later */
- PARAMBLK rWork;
- rWork.sState = U14ERR_DRIVCOMMS;
- if (DeviceIoControl(aHand1401[sHand], lCode, pBlk, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
- (dwBytes >= sizeof(PARAMBLK)))
- return rWork.sState;
- }
-
- return U14ERR_DRIVCOMMS;
-}
-#endif
-
-/****************************************************************************
-** SafeTickCount
-** Gets time in approximately units of a millisecond.
-*****************************************************************************/
-static long SafeTickCount()
-{
-#ifdef _IS_WINDOWS_
- return GetTickCount();
-#endif
-#ifdef LINUX
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (tv.tv_sec*1000 + tv.tv_usec/1000);
-#endif
-}
-
-/****************************************************************************
-** A utility routine to get the command file extension for a given type
-** of 1401. We assume the type code is vaguely legal.
-****************************************************************************/
-static int ExtForType(short sType, char* szExt)
-{
- szExt[0] = 0; /* Default return is a blank string */
- switch (sType)
- {
- case U14TYPE1401: strcpy(szExt, ".CMD"); break; // Standard 1401
- case U14TYPEPLUS: strcpy(szExt, ".GXC"); break; // 1401 plus
- default: // All others are in a predictable sequence
- strcpy(szExt, ".ARM");
- szExt[3] = (char)('M' + sType - U14TYPEU1401);
- if (szExt[3] > 'Z') // Wrap round to ARA after ARZ
- szExt[3] = (char)(szExt[3] - 26);
- }
- return 0;
-}
-
-/****************************************************************************
-** U14WhenToTimeOut
-** Returns the time to time out in time units suitable for the machine
-** we are running on ie millsecs for pc/linux, or Mac/
-****************************************************************************/
-U14API(int) U14WhenToTimeOut(short hand)
-{
- int iNow = SafeTickCount();
- if ((hand >= 0) && (hand < MAX1401))
- iNow += alTimeOutPeriod[hand];
- return iNow;
-}
-
-/****************************************************************************
-** U14PassedTime
-** Returns non zero if the timed passed in has been passed 0 if not
-****************************************************************************/
-U14API(short) U14PassedTime(int lCheckTime)
-{
- return (short)((SafeTickCount()-lCheckTime) > 0);
-}
-
-/****************************************************************************
-** TranslateString
-** Tidies up string that U14GetString returns. Converts all the commas in a
-** string to spaces. Removes terminating CR character. May do more in future.
-****************************************************************************/
-static void TranslateString(char* pStr)
-{
- int i = 0;
- while (pStr[i])
- {
- if (pStr[i] == ',')
- pStr[i] = ' '; /* convert comma to space */
- ++i;
- }
-
- if ((i > 0) && (pStr[i-1] == '\n')) /* kill terminating LF */
- pStr[i-1] = (char)0;
-}
-
-/****************************************************************************
-** U14StrToLongs
-** Converts a string to an array of longs and returns the number of values
-****************************************************************************/
-U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs)
-{
- unsigned short wChInd = 0; // index into source
- short sLgInd = 0; // index into result longs
-
- while (pszBuff[wChInd] && // until we get to end of string...
- (sLgInd < sMaxLongs)) // ...or filled the buffer
- {
- // Why not use a C Library converter?
- switch (pszBuff[wChInd])
- {
- case '-':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- {
- BOOL bDone = FALSE; // true at end of number
- int iSign = 1; // sign of number
- long lValue = 0;
-
- while ((!bDone) && pszBuff[wChInd])
- {
- switch (pszBuff[wChInd])
- {
- case '-':
- iSign = -1; // swap sign
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- lValue *= 10; // move to next digit base 10
- lValue += ((int)pszBuff[wChInd]-(int)'0');
- break;
-
- default: // end of number
- bDone = TRUE;
- break;
- }
- wChInd++; // move onto next character
- }
- palNums[sLgInd] = lValue * iSign;
- sLgInd++;
- }
- break;
-
- default:
- wChInd++; // look at next char
- break;
- }
- }
- return (sLgInd);
-}
-
-
-/****************************************************************************
-** U14LongsFrom1401
-** Gets the next waiting line from the 1401 and converts it longs
-** Returns the number of numbers read or an error.
-****************************************************************************/
-U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs)
-{
- char szWork[MAXSTRLEN];
- short sResult = U14GetString(hand, szWork, MAXSTRLEN);/* get reply from 1401 */
- if (sResult == U14ERR_NOERROR) /* if no error convert */
- sResult = U14StrToLongs(szWork, palBuff, sMaxLongs);
- return sResult;
-}
-
-/****************************************************************************
-** U14CheckErr
-** Sends the ERR command to the 1401 and gets the result. Returns 0, a
-** negative error code, or the first error value.
-****************************************************************************/
-U14API(short) U14CheckErr(short hand)
-{
- short sResult = U14SendString(hand, ";ERR;");
- if (sResult == U14ERR_NOERROR)
- {
- U14LONG er[3];
- sResult = U14LongsFrom1401(hand, er, 3);
- if (sResult > 0)
- {
- sResult = (short)er[0]; /* Either zero or an error value */
-#ifdef _DEBUG
- if (er[0] != 0)
- {
- char szMsg[50];
- sprintf(szMsg, "U14CheckErr returned %d,%d\n", er[0], er[1]);
- OutputDebugString(szMsg);
- }
-#endif
- }
- else
- {
- if (sResult == 0)
- sResult = U14ERR_TIMEOUT; /* No numbers equals timeout */
- }
- }
-
- return sResult;
-}
-
-/****************************************************************************
-** U14LastErrCode
-** Returns the last code from the driver. This is for Windows where all calls
-** go through the Control and Status routines, so we can save any error.
-****************************************************************************/
-U14API(short) U14LastErrCode(short hand)
-{
- if ((hand < 0) || (hand >= MAX1401))
- return U14ERR_BADHAND;
- return asLastRetCode[hand];
-}
-
-/****************************************************************************
-** U14SetTimeout
-** Set the timeout period for 1401 comms in milliseconds
-****************************************************************************/
-U14API(void) U14SetTimeout(short hand, int lTimeOut)
-{
- if ((hand < 0) || (hand >= MAX1401))
- return;
- alTimeOutPeriod[hand] = lTimeOut;
-}
-
-/****************************************************************************
-** U14GetTimeout
-** Get the timeout period for 1401 comms in milliseconds
-****************************************************************************/
-U14API(int) U14GetTimeout(short hand)
-{
- if ((hand < 0) || (hand >= MAX1401))
- return U14ERR_BADHAND;
- return alTimeOutPeriod[hand];
-}
-
-/****************************************************************************
-** U14OutBufSpace
-** Return the space in the output buffer, or an error.
-****************************************************************************/
-U14API(short) U14OutBufSpace(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_GETOUTBUFSPACE,&csBlock);
- if (sErr == U14ERR_NOERROR)
- sErr = csBlock.ints[0];
- return sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_GetOutBufSpace(aHand1401[hand]) : sErr;
-#endif
-}
-
-
-/****************************************************************************
-** U14BaseAddr1401
-** Returns the 1401 base address or an error code. Meaningless nowadays
-****************************************************************************/
-U14API(int) U14BaseAddr1401(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- int iError = U14Status1401(hand, U14_GETBASEADDRESS,&csBlock);
- if (iError == U14ERR_NOERROR)
- iError = csBlock.longs[0];
- return iError;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_GetBaseAddress(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14StateOf1401
-** Return error state, either NOERROR or a negative code.
-****************************************************************************/
-U14API(short) U14StateOf1401(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_STATEOF1401, &csBlock);
- if (sErr == U14ERR_NOERROR)
- {
- sErr = csBlock.ints[0]; // returned 1401 state
- if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX))
- sErr = U14ERR_NOERROR;
- }
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- sErr = (short)CED_StateOf1401(aHand1401[hand]);
- if ((sErr >= DRIVRET_STD) && (sErr <= DRIVRET_MAX))
- sErr = U14ERR_NOERROR;
- }
-#endif
- return sErr;
-}
-
-/****************************************************************************
-** U14DriverVersion
-** Returns the driver version. Hi word is major revision, low word is minor.
-** If you pass in a silly handle (like -1), we return the version of the last
-** driver we know of (to cope with PCI and no 1401 attached).
-****************************************************************************/
-U14API(int) U14DriverVersion(short hand)
-{
- return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverVersion : alDriverVersion[hand];
-}
-
-/****************************************************************************
-** U14DriverType
-** Returns the driver type. The type, 0=ISA/NU-Bus, 1=PCI, 2=USB, 3=HSS
-** If you pass in a silly handle (like -1), we return the type of the last
-** driver we know of (to cope with PCI and no 1401 attached).
-****************************************************************************/
-U14API(int) U14DriverType(short hand)
-{
- return CheckHandle(hand) != U14ERR_NOERROR ? lLastDriverType : asDriverType[hand];
-}
-
-/****************************************************************************
-** U14DriverName
-** Returns the driver type as 3 character (ISA, PCI, USB or HSS))
-****************************************************************************/
-U14API(short) U14DriverName(short hand, char* pBuf, unsigned short wMax)
-{
- char* pName;
- *pBuf = 0; // Start off with a blank string
- switch (U14DriverType(hand)) // Results according to type
- {
- case 0: pName = "ISA"; break;
- case 1: pName = "PCI"; break;
- case 2: pName = "USB"; break;
- case 3: pName = "HSS"; break;
- default: pName = "???"; break;
- }
- strncpy(pBuf, pName, wMax); // Copy the correct name to return
-
- return U14ERR_NOERROR;
-}
-
-/****************************************************************************
-** U14BlkTransState
-** Returns 0 no transfer in progress, 1 transfer in progress or an error code
-****************************************************************************/
-U14API(short) U14BlkTransState(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_BLKTRANSSTATE, &csBlock);
- if (sErr == U14ERR_NOERROR)
- sErr = csBlock.ints[0];
- return sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_BlkTransState(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14Grab1401
-** Take control of the 1401 for diagnostics purposes. USB does nothing.
-****************************************************************************/
-U14API(short) U14Grab1401(short hand)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
-#ifdef _IS_WINDOWS_
- if (abGrabbed[hand]) // 1401 should not have been grabbed
- sErr = U14ERR_ALREADYSET; // Error code defined for this
- else
- {
- TCSBLOCK csBlock;
- sErr = U14Control1401(hand, U14_GRAB1401, &csBlock);
- }
-#endif
-#ifdef LINUX
- // 1401 should not have been grabbed
- sErr = abGrabbed[hand] ? U14ERR_ALREADYSET : CED_Grab1401(aHand1401[hand]);
-#endif
- if (sErr == U14ERR_NOERROR)
- abGrabbed[hand] = TRUE;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14Free1401
-****************************************************************************/
-U14API(short) U14Free1401(short hand)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
-#ifdef _IS_WINDOWS_
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
- TCSBLOCK csBlock;
- sErr = U14Control1401(hand, U14_FREE1401, &csBlock);
- }
- else
- sErr = U14ERR_NOTSET;
-#endif
-#ifdef LINUX
- // 1401 should not have been grabbed
- sErr = abGrabbed[hand] ? CED_Free1401(aHand1401[hand]) : U14ERR_NOTSET;
-#endif
- if (sErr == U14ERR_NOERROR)
- abGrabbed[hand] = FALSE;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14Peek1401
-** DESCRIPTION Cause the 1401 to do one or more peek operations.
-** If lRepeats is zero, the loop will continue until U14StopDebugLoop
-** is called. After the peek is done, use U14GetDebugData to retrieve
-** the results of the peek.
-****************************************************************************/
-U14API(short) U14Peek1401(short hand, unsigned int dwAddr, int nSize, int nRepeats)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- csBlock.longs[0] = (long)dwAddr;
- csBlock.longs[1] = nSize;
- csBlock.longs[2] = nRepeats;
- sErr = U14Control1401(hand, U14_DBGPEEK, &csBlock);
-#endif
-#ifdef LINUX
- TDBGBLOCK dbb;
- dbb.iAddr = (int)dwAddr;
- dbb.iWidth = nSize;
- dbb.iRepeats = nRepeats;
- sErr = CED_DbgPeek(aHand1401[hand], &dbb);
-#endif
- }
- else
- sErr = U14ERR_NOTSET;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14Poke1401
-** DESCRIPTION Cause the 1401 to do one or more poke operations.
-** If lRepeats is zero, the loop will continue until U14StopDebugLoop
-** is called.
-****************************************************************************/
-U14API(short) U14Poke1401(short hand, unsigned int dwAddr, unsigned int dwValue,
- int nSize, int nRepeats)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- csBlock.longs[0] = (long)dwAddr;
- csBlock.longs[1] = nSize;
- csBlock.longs[2] = nRepeats;
- csBlock.longs[3] = (long)dwValue;
- sErr = U14Control1401(hand, U14_DBGPOKE, &csBlock);
-#endif
-#ifdef LINUX
- TDBGBLOCK dbb;
- dbb.iAddr = (int)dwAddr;
- dbb.iWidth = nSize;
- dbb.iRepeats= nRepeats;
- dbb.iData = (int)dwValue;
- sErr = CED_DbgPoke(aHand1401[hand], &dbb);
-#endif
- }
- else
- sErr = U14ERR_NOTSET;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14Ramp1401
-** DESCRIPTION Cause the 1401 to loop, writing a ramp to a location.
-** If lRepeats is zero, the loop will continue until U14StopDebugLoop.
-****************************************************************************/
-U14API(short) U14Ramp1401(short hand, unsigned int dwAddr, unsigned int dwDef, unsigned int dwEnable,
- int nSize, int nRepeats)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- csBlock.longs[0] = (long)dwAddr;
- csBlock.longs[1] = (long)dwDef;
- csBlock.longs[2] = (long)dwEnable;
- csBlock.longs[3] = nSize;
- csBlock.longs[4] = nRepeats;
- sErr = U14Control1401(hand, U14_DBGRAMPDATA, &csBlock);
-#endif
-#ifdef LINUX
- TDBGBLOCK dbb;
- dbb.iAddr = (int)dwAddr;
- dbb.iDefault = (int)dwDef;
- dbb.iMask = (int)dwEnable;
- dbb.iWidth = nSize;
- dbb.iRepeats = nRepeats;
- sErr = CED_DbgRampAddr(aHand1401[hand], &dbb);
-#endif
- }
- else
- sErr = U14ERR_NOTSET;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14RampAddr
-** DESCRIPTION Cause the 1401 to loop, reading from a ramping location.
-** If lRepeats is zero, the loop will continue until U14StopDebugLoop
-****************************************************************************/
-U14API(short) U14RampAddr(short hand, unsigned int dwDef, unsigned int dwEnable,
- int nSize, int nRepeats)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- csBlock.longs[0] = (long)dwDef;
- csBlock.longs[1] = (long)dwEnable;
- csBlock.longs[2] = nSize;
- csBlock.longs[3] = nRepeats;
- sErr = U14Control1401(hand, U14_DBGRAMPADDR, &csBlock);
-#endif
-#ifdef LINUX
- TDBGBLOCK dbb;
- dbb.iDefault = (int)dwDef;
- dbb.iMask = (int)dwEnable;
- dbb.iWidth = nSize;
- dbb.iRepeats = nRepeats;
- sErr = CED_DbgRampAddr(aHand1401[hand], &dbb);
-#endif
- }
- else
- sErr = U14ERR_NOTSET;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14StopDebugLoop
-** DESCRIPTION Stops a peek\poke\ramp that, with repeats set to zero,
-** will otherwise continue forever.
-****************************************************************************/
-U14API(short) U14StopDebugLoop(short hand)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
-#ifdef _IS_WINDOWS_
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
- TCSBLOCK csBlock;
- sErr = U14Control1401(hand, U14_DBGSTOPLOOP, &csBlock);
- }
- else
- sErr = U14ERR_NOTSET;
- }
-#endif
-#ifdef LINUX
- sErr = abGrabbed[hand] ? CED_DbgStopLoop(aHand1401[hand]) : U14ERR_NOTSET;
-#endif
- return sErr;
-}
-
-/****************************************************************************
-** U14GetDebugData
-** DESCRIPTION Returns the result from a previous peek operation.
-****************************************************************************/
-U14API(short) U14GetDebugData(short hand, U14LONG* plValue)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- if (abGrabbed[hand]) // 1401 should have been grabbed
- {
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- sErr = U14Status1401(hand, U14_DBGGETDATA, &csBlock);
- if (sErr == U14ERR_NOERROR)
- *plValue = csBlock.longs[0]; // Return the data
-#endif
-#ifdef LINUX
- TDBGBLOCK dbb;
- sErr = CED_DbgGetData(aHand1401[hand], &dbb);
- if (sErr == U14ERR_NOERROR)
- *plValue = dbb.iData; /* Return the data */
-#endif
- }
- else
- sErr = U14ERR_NOTSET;
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14StartSelfTest
-****************************************************************************/
-U14API(short) U14StartSelfTest(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- return U14Control1401(hand, U14_STARTSELFTEST, &csBlock);
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_StartSelfTest(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14CheckSelfTest
-****************************************************************************/
-U14API(short) U14CheckSelfTest(short hand, U14LONG *pData)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_CHECKSELFTEST, &csBlock);
- if (sErr == U14ERR_NOERROR)
- {
- pData[0] = csBlock.longs[0]; /* Return the results to user */
- pData[1] = csBlock.longs[1];
- pData[2] = csBlock.longs[2];
- }
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR) /* Check parameters */
- {
- TGET_SELFTEST gst;
- sErr = CED_CheckSelfTest(aHand1401[hand], &gst);
- if (sErr == U14ERR_NOERROR)
- {
- pData[0] = gst.code; /* Return the results to user */
- pData[1] = gst.x;
- pData[2] = gst.y;
- }
- }
-#endif
- return sErr;
-}
-
-/****************************************************************************
-** U14GetUserMemorySize
-****************************************************************************/
-U14API(short) U14GetUserMemorySize(short hand, unsigned int *pMemorySize)
-{
- // The original 1401 used a different command for getting the size
- short sErr = U14SendString(hand, (asType1401[hand] == U14TYPE1401) ? "MEMTOP;" : "MEMTOP,?;");
- *pMemorySize = 0; /* if we get error then leave size set at 0 */
- if (sErr == U14ERR_NOERROR)
- {
- U14LONG alLimits[4];
- sErr = U14LongsFrom1401(hand, alLimits, 4);
- if (sErr > 0) /* +ve sErr is the number of values read */
- {
- sErr = U14ERR_NOERROR; /* All OK, flag success */
- if (asType1401[hand] == U14TYPE1401) /* result for standard */
- *pMemorySize = alLimits[0] - alLimits[1]; /* memtop-membot */
- else
- *pMemorySize = alLimits[0]; /* result for plus or u1401 */
- }
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14TypeOf1401
-** Returns the type of the 1401, maybe unknown
-****************************************************************************/
-U14API(short) U14TypeOf1401(short hand)
-{
- if ((hand < 0) || (hand >= MAX1401)) /* Check parameters */
- return U14ERR_BADHAND;
- else
- return asType1401[hand];
-}
-
-/****************************************************************************
-** U14NameOf1401
-** Returns the type of the 1401 as a string, blank if unknown
-****************************************************************************/
-U14API(short) U14NameOf1401(short hand, char* pBuf, unsigned short wMax)
-{
- short sErr = CheckHandle(hand);
- if (sErr == U14ERR_NOERROR)
- {
- char* pName;
- switch (asType1401[hand]) // Results according to type
- {
- case U14TYPE1401: pName = "Std 1401"; break;
- case U14TYPEPLUS: pName = "1401plus"; break;
- case U14TYPEU1401: pName = "micro1401"; break;
- case U14TYPEPOWER: pName = "Power1401"; break;
- case U14TYPEU14012:pName = "Micro1401 mk II"; break;
- case U14TYPEPOWER2:pName = "Power1401 mk II"; break;
- case U14TYPEU14013:pName = "Micro1401-3"; break;
- case U14TYPEPOWER3:pName = "Power1401-3"; break;
- default: pName = "Unknown";
- }
- strncpy(pBuf, pName, wMax);
- }
- return sErr;
-}
-
-/****************************************************************************
-** U14TransferFlags
-** Returns the driver block transfer flags.
-** Bits can be set - see U14TF_ constants in use1401.h
-*****************************************************************************/
-U14API(short) U14TransferFlags(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_TRANSFERFLAGS, &csBlock);
- return (sErr == U14ERR_NOERROR) ? (short)csBlock.ints[0] : sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_TransferFlags(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** GetDriverVersion
-** Actually reads driver version from the device driver.
-** Hi word is major revision, low word is minor revision.
-** Assumes that hand has been checked. Also codes driver type in bits 24 up.
-*****************************************************************************/
-static int GetDriverVersion(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- int iErr = U14Status1401(hand, U14_GETDRIVERREVISION, &csBlock);
- if (iErr == U14ERR_NOERROR)
- iErr = csBlock.longs[0];
- return iErr;
-#endif
-#ifdef LINUX
- return CED_GetDriverRevision(aHand1401[hand]);
-#endif
-}
-
-/****************************************************************************
-** U14MonitorRev
-** Returns the 1401 monitor revision number.
-** The number returned is the minor revision - the part after the
-** decimal point - plus the major revision times 1000.
-*****************************************************************************/
-U14API(int) U14MonitorRev(short hand)
-{
- int iRev = 0;
- int iErr = CheckHandle(hand);
- if (iErr != U14ERR_NOERROR) // Check open and in use
- return iErr;
-
- if (asType1401[hand] >= U14TYPEPOWER2) // The Power2 onwards can give us the monitor
- { // revision directly for all versions
- iErr = U14SendString(hand, "INFO,S,28;");
- if (iErr == U14ERR_NOERROR)
- {
- U14LONG lVals[2]; // Read a single number being the revision
- iErr = U14LongsFrom1401(hand, lVals, 1);
- if (iErr > 0)
- {
- iErr = U14ERR_NOERROR;
- iRev = lVals[0]; // This is the minor part of the revision
- iRev += asType1401[hand] * 10000;
- }
- }
- }
- else
- { /* Do it the hard way for older hardware */
- iErr = U14SendString(hand, ";CLIST;"); /* ask for command levels */
- if (iErr == U14ERR_NOERROR)
- {
- while (iErr == U14ERR_NOERROR)
- {
- char wstr[50];
- iErr = U14GetString(hand, wstr, 45);
- if (iErr == U14ERR_NOERROR)
- {
- char *pstr = strstr(wstr,"RESET"); /* Is this the RESET command? */
- if ((pstr == wstr) && (wstr[5] == ' '))
- {
- char *pstr2;
- size_t l;
- pstr += 6; /* Move past RESET and followinmg char */
- l = strlen(pstr); /* The length of text remaining */
- while (((pstr[l-1] == ' ') || (pstr[l-1] == 13)) && (l > 0))
- {
- pstr[l-1] = 0; /* Tidy up string at the end */
- l--; /* by removing spaces and CRs */
- }
- pstr2 = strchr(pstr, '.'); /* Find the decimal point */
- if (pstr2 != NULL) /* If we found the DP */
- {
- *pstr2 = 0; /* End pstr string at DP */
- pstr2++; /* Now past the decimal point */
- iRev = atoi(pstr2); /* Get the number after point */
- }
- iRev += (atoi(pstr) * 1000); /* Add first bit * 1000 */
- }
- if ((strlen(wstr) < 3) && (wstr[0] == ' '))
- break; /* Spot the last line of results */
- }
- }
- }
- }
- if (iErr == U14ERR_NOERROR) /* Return revision if no error */
- iErr = iRev;
-
- return iErr;
-}
-
-/****************************************************************************
-** U14TryToOpen Tries to open the 1401 number passed
-** Note : This will succeed with NT driver even if no I/F card or
-** 1401 switched off, so we check state and close the driver
-** if the state is unsatisfactory in U14Open1401.
-****************************************************************************/
-#ifdef _IS_WINDOWS_
-#define U14NAMEOLD "\\\\.\\CED_140%d"
-#define U14NAMENEW "\\\\.\\CED%d"
-static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle)
-{
- short sErr = U14ERR_NOERROR;
- HANDLE hDevice = INVALID_HANDLE_VALUE;
- unsigned int dwErr = 0;
- int nFirst, nLast, nDev = 0; /* Used for the search for a 1401 */
- BOOL bOldName = FALSE; /* start by looking for a modern driver */
-
- if (n1401 == 0) /* If we need to look for a 1401 */
- {
- nFirst = 1; /* Set the search range */
- nLast = MAX1401; /* through all the possible 1401s */
- }
- else
- nFirst = nLast = n1401; /* Otherwise just one 1401 */
-
- while (hDevice == INVALID_HANDLE_VALUE) /* Loop to try for a 1401 */
- {
- for (nDev = nFirst; nDev <= nLast; nDev++)
- {
- char szDevName[40]; /* name of the device to open */
- sprintf(szDevName, bOldName ? U14NAMEOLD : U14NAMENEW, nDev);
- hDevice = CreateFile(szDevName, GENERIC_WRITE | GENERIC_READ,
- 0, 0, /* Unshared mode does nothing as this is a device */
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (hDevice != INVALID_HANDLE_VALUE)/* Check 1401 if opened */
- {
- TCSBLOCK csBlock;
- assert(aHand1401[nDev-1] == INVALID_HANDLE_VALUE); // assert if already open
- aHand1401[nDev-1] = hDevice; /* Save handle for now */
-
-#ifndef _WIN64
- // Use DIOC method if not windows 9x or if using new device name
- abUseNTDIOC[nDev-1] = (BOOL)(!bWindows9x || !bOldName);
-#endif
- sErr = U14Status1401((short)(nDev-1), U14_TYPEOF1401, &csBlock);
- if (sErr == U14ERR_NOERROR)
- {
- *plRetVal = csBlock.ints[0];
- if (csBlock.ints[0] == U14ERR_INUSE)/* Prevent multi opens */
- {
- CloseHandle(hDevice); /* treat as open failure */
- hDevice = INVALID_HANDLE_VALUE;
- aHand1401[nDev-1] = INVALID_HANDLE_VALUE;
- sErr = U14ERR_INUSE;
- }
- else
- break; /* Exit from for loop on success */
- }
- else
- {
- CloseHandle(hDevice); /* Give up if func fails */
- hDevice = INVALID_HANDLE_VALUE;
- aHand1401[nDev-1] = INVALID_HANDLE_VALUE;
- }
- }
- else
- {
- unsigned int dwe = GetLastError(); /* Get error code otherwise */
- if ((dwe != ERROR_FILE_NOT_FOUND) || (dwErr == 0))
- dwErr = dwe; /* Ignore repeats of 'not found' */
- }
- }
-
- if ((hDevice == INVALID_HANDLE_VALUE) &&/* No device found, and... */
- (bWindows9x) && /* ...old names are allowed, and... */
- (bOldName == FALSE)) /* ...not tried old names yet */
- bOldName = TRUE; /* Set flag and go round again */
- else
- break; /* otherwise that's all folks */
- }
-
- if (hDevice != INVALID_HANDLE_VALUE) /* If we got our device open */
- *psHandle = (short)(nDev-1); /* return 1401 number opened */
- else
- {
- if (dwErr == ERROR_FILE_NOT_FOUND) /* Sort out the error codes */
- sErr = U14ERR_NO1401DRIV; /* if file not found */
- else if (dwErr == ERROR_NOT_SUPPORTED)
- sErr = U14ERR_DRIVTOOOLD; /* if DIOC not supported */
- else if (dwErr == ERROR_ACCESS_DENIED)
- sErr = U14ERR_INUSE;
- else
- sErr = U14ERR_DRIVCOMMS; /* otherwise assume comms problem */
- }
- return sErr;
-}
-#endif
-#ifdef LINUX
-static short U14TryToOpen(int n1401, long* plRetVal, short* psHandle)
-{
- short sErr = U14ERR_NOERROR;
- int fh = 0; // will be 1401 handle
- int iErr = 0;
- int nFirst, nLast, nDev = 0; // Used for the search for a 1401
-
- if (n1401 == 0) // If we need to look for a 1401
- {
- nFirst = 1; /* Set the search range */
- nLast = MAX1401; /* through all the possible 1401s */
- }
- else
- nFirst = nLast = n1401; /* Otherwise just one 1401 */
-
- for (nDev = nFirst; nDev <= nLast; nDev++)
- {
- char szDevName[40]; // name of the device to open
- sprintf(szDevName,"/dev/cedusb/%d", nDev-1);
- fh = open(szDevName, O_RDWR); // can only be opened once at a time
- if (fh > 0) // Check 1401 if opened
- {
- int iType1401 = CED_TypeOf1401(fh); // get 1401 type
- aHand1401[nDev-1] = fh; // Save handle for now
- if (iType1401 >= 0)
- {
- *plRetVal = iType1401;
- break; // Exit from for loop on success
- }
- else
- {
- close(fh); // Give up if func fails
- fh = 0;
- aHand1401[nDev-1] = 0;
- }
- }
- else
- {
- if (((errno != ENODEV) && (errno != ENOENT)) || (iErr == 0))
- iErr = errno; // Ignore repeats of 'not found'
- }
- }
-
-
- if (fh) // If we got our device open
- *psHandle = (short)(nDev-1); // return 1401 number opened
- else
- {
- if ((iErr == ENODEV) || (iErr == ENOENT)) // Sort out the error codes
- sErr = U14ERR_NO1401DRIV; // if file not found
- else if (iErr == EBUSY)
- sErr = U14ERR_INUSE;
- else
- sErr = U14ERR_DRIVCOMMS; // otherwise assume comms problem
- }
-
- return sErr;
-}
-#endif
-/****************************************************************************
-** U14Open1401
-** Tries to get the 1401 for use by this application
-*****************************************************************************/
-U14API(short) U14Open1401(short n1401)
-{
- long lRetVal = -1;
- short sErr;
- short hand = 0;
-
- if ((n1401 < 0) || (n1401 > MAX1401)) // must check the 1401 number
- return U14ERR_BAD1401NUM;
-
- szLastName[0] = 0; /* initialise the error info string */
-
- sErr = U14TryToOpen(n1401, &lRetVal, &hand);
- if (sErr == U14ERR_NOERROR)
- {
- long lDriverVersion = GetDriverVersion(hand); /* get driver revision */
- long lDriverRev = -1;
- if (lDriverVersion >= 0) /* can use it if all OK */
- {
- lLastDriverType = (lDriverVersion >> 24) & 0x000000FF;
- asDriverType[hand] = (short)lLastDriverType; /* Drv type */
- lLastDriverVersion = lDriverVersion & 0x00FFFFFF;
- alDriverVersion[hand] = lLastDriverVersion; /* Actual version */
- lDriverRev = ((lDriverVersion>>16) & 0x00FF); /* use hi word */
- }
- else
- {
- U14Close1401(hand); /* If there is a problem we should close */
- return (short)lDriverVersion; /* and return the error code */
- }
-
- if (lDriverRev < MINDRIVERMAJREV) /* late enough version? */
- {
- U14Close1401(hand); /* If there is a problem we should close */
- return U14ERR_DRIVTOOOLD; /* too old */
- }
-
- asLastRetCode[hand] = U14ERR_NOERROR; /* Initialise this 1401s info */
- abGrabbed[hand] = FALSE; /* we are not in single step mode */
- U14SetTimeout(hand, 3000); /* set 3 seconds as default timeout */
-
- switch (lRetVal)
- {
- case DRIVRET_STD: asType1401[hand] = U14TYPE1401; break; /* Some we do by hand */
- case DRIVRET_U1401:asType1401[hand] = U14TYPEU1401; break;
- case DRIVRET_PLUS: asType1401[hand] = U14TYPEPLUS; break;
- default: // For the power upwards, we can calculate the codes
- if ((lRetVal >= DRIVRET_POWER) && (lRetVal <= DRIVRET_MAX))
- asType1401[hand] = (short)(lRetVal - (DRIVRET_POWER - U14TYPEPOWER));
- else
- asType1401[hand] = U14TYPEUNKNOWN;
- break;
- }
- U14KillIO1401(hand); /* resets the 1401 buffers */
-
- if (asType1401[hand] != U14TYPEUNKNOWN) /* If all seems OK so far */
- {
- sErr = U14CheckErr(hand); /* we can check 1401 comms now */
- if (sErr != 0) /* If this failed to go OK */
- U14Reset1401(hand); /* Reset the 1401 to try to sort it out */
- }
-
- sErr = U14StateOf1401(hand);/* Get the state of the 1401 for return */
- if (sErr == U14ERR_NOERROR)
- sErr = hand; /* return the handle if no problem */
- else
- U14Close1401(hand); /* If there is a problem we should close */
- }
-
- return sErr;
-}
-
-
-/****************************************************************************
-** U14Close1401
-** Closes the 1401 so someone else can use it.
-****************************************************************************/
-U14API(short) U14Close1401(short hand)
-{
- int j;
- int iAreaMask = 0; // Mask for active areas
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR) // Check open and in use
- return sErr;
-
- for (j = 0; j<MAX_TRANSAREAS; ++j)
- {
- TGET_TX_BLOCK gtb;
- int iReturn = U14GetTransfer(hand, &gtb); // get area information
- if (iReturn == U14ERR_NOERROR) // ignore if any problem
- if (gtb.used)
- iAreaMask |= (1 << j); // set a bit for each used area
- }
-
- if (iAreaMask) // if any areas are in use
- {
- U14Reset1401(hand); // in case an active transfer running
- for (j = 0; j < MAX_TRANSAREAS; ++j) // Locate locked areas
- if (iAreaMask & (1 << j)) // And kill off any transfers
- U14UnSetTransfer(hand, (unsigned short)j);
- }
-
-#ifdef _IS_WINDOWS_
- if (aXferEvent[hand]) // if this 1401 has an open event handle
- {
- CloseHandle(aXferEvent[hand]); // close down the handle
- aXferEvent[hand] = NULL; // and mark it as gone
- }
-
- if (CloseHandle(aHand1401[hand]))
-#endif
-#ifdef LINUX
- if (close(aHand1401[hand]) == 0) // make sure that close works
-#endif
- {
- aHand1401[hand] = INVALID_HANDLE_VALUE;
- asType1401[hand] = U14TYPEUNKNOWN;
- return U14ERR_NOERROR;
- }
- else
- return U14ERR_BADHAND; /* BUGBUG GetLastError() ? */
-}
-
-/**************************************************************************
-**
-** Look for open 1401s and attempt to close them down. 32-bit windows only.
-**************************************************************************/
-U14API(void) U14CloseAll(void)
-{
- int i;
- for (i = 0; i < MAX1401; i++) // Tidy up and make safe
- if (aHand1401[i] != INVALID_HANDLE_VALUE)
- U14Close1401((short)i); // Last ditch close 1401
-}
-
-/****************************************************************************
-** U14Reset1401
-** Resets the 1401
-****************************************************************************/
-U14API(short) U14Reset1401(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- return U14Control1401(hand, U14_RESET1401, &csBlock);
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_Reset1401(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14ForceReset
-** Sets the 1401 full reset flag, so that next call to Reset1401 will
-** always cause a genuine reset.
-*****************************************************************************/
-U14API(short) U14ForceReset(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- return U14Control1401(hand, U14_FULLRESET, &csBlock);
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_FullReset(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14KillIO1401
-** Removes any pending IO from the buffers.
-*****************************************************************************/
-U14API(short) U14KillIO1401(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- return U14Control1401(hand, U14_KILLIO1401, &csBlock);
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_KillIO1401(aHand1401[hand]) : sErr;
-#endif
-}
-
-
-/****************************************************************************
-** U14SendString
-** Send characters to the 1401
-*****************************************************************************/
-U14API(short) U14SendString(short hand, const char* pString)
-{
- int nChars; // length we are sending
- long lTimeOutTicks; // when to time out
- BOOL bSpaceToSend; // space to send yet
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
-
- nChars = (int)strlen(pString); // get string length we want to send
- if (nChars > MAXSTRLEN)
- return U14ERR_STRLEN; // String too long
-
-#ifdef _IS_WINDOWS_
- // To get here we must wait for the buffer to have some space
- lTimeOutTicks = U14WhenToTimeOut(hand);
- do
- {
- bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
- }
- while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks));
-
- if (!bSpaceToSend) /* Last-ditch attempt to avoid timeout */
- { /* This can happen with anti-virus or network activity! */
- int i;
- for (i = 0; (i < 4) && (!bSpaceToSend); ++i)
- {
- Sleep(25); /* Give other threads a chance for a while */
- bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
- }
- }
-
- if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */
- {
- if (bSpaceToSend)
- {
- PARAMBLK rData;
- unsigned int dwBytes;
- char tstr[MAXSTRLEN+5]; /* Buffer for chars */
-
- if ((hand < 0) || (hand >= MAX1401))
- sErr = U14ERR_BADHAND;
- else
- {
- strcpy(tstr, pString); /* Into local buf */
-#ifndef _WIN64
- if (!USE_NT_DIOC(hand)) /* Using WIN 95 driver access? */
- {
- int iOK = DeviceIoControl(aHand1401[hand], (unsigned int)U14_SENDSTRING,
- NULL, 0, tstr, nChars,
- &dwBytes, NULL);
- if (iOK)
- sErr = (dwBytes >= (unsigned int)nChars) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS;
- else
- sErr = (short)GetLastError();
- }
- else
-#endif
- {
- int iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_SENDSTRING,
- tstr, nChars,
- &rData,sizeof(PARAMBLK),&dwBytes,NULL);
- if (iOK && (dwBytes >= sizeof(PARAMBLK)))
- sErr = rData.sState;
- else
- sErr = U14ERR_DRIVCOMMS;
- }
-
- if (sErr != U14ERR_NOERROR) // If we have had a comms error
- U14ForceReset(hand); // make sure we get real reset
- }
-
- return sErr;
-
- }
- else
- {
- U14ForceReset(hand); // make sure we get real reset
- return U14ERR_TIMEOUT;
- }
- }
- else
- return asLastRetCode[hand];
-#endif
-#ifdef LINUX
- // Just try to send it and see what happens!
- sErr = CED_SendString(aHand1401[hand], pString, nChars);
- if (sErr != U14ERR_NOOUT) // if any result except "no room in output"...
- {
- if (sErr != U14ERR_NOERROR) // if a problem...
- U14ForceReset(hand); // ...make sure we get real reset next time
- return sErr; // ... we are done as nothing we can do
- }
-
- // To get here we must wait for the buffer to have some space
- lTimeOutTicks = U14WhenToTimeOut(hand);
- do
- {
- bSpaceToSend = (BOOL)((long)U14OutBufSpace(hand) >= nChars);
- if (!bSpaceToSend)
- sched_yield(); // let others have fun while we wait
- }
- while (!bSpaceToSend && !U14PassedTime(lTimeOutTicks));
-
- if (asLastRetCode[hand] == U14ERR_NOERROR) /* no errors? */
- {
- if (bSpaceToSend)
- {
- sErr = CED_SendString(aHand1401[hand], pString, nChars);
- if (sErr != U14ERR_NOERROR) // If we have had a comms error
- U14ForceReset(hand); // make sure we get real reset
- return sErr;
- }
- else
- {
- U14ForceReset(hand); // make sure we get real reset
- return U14ERR_TIMEOUT;
- }
- }
- else
- return asLastRetCode[hand];
-#endif
-}
-
-/****************************************************************************
-** U14SendChar
-** Send character to the 1401
-*****************************************************************************/
-U14API(short) U14SendChar(short hand, char cChar)
-{
-#ifdef _IS_WINDOWS_
- char sz[2]=" "; // convert to a string and send
- sz[0] = cChar;
- sz[1] = 0;
- return(U14SendString(hand, sz)); // String routines are better
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_SendChar(aHand1401[hand], cChar) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14GetString
-** Get a string from the 1401. Returns a null terminated string.
-** The string is all the characters up to the next CR in the buffer
-** or the end of the buffer if that comes first. This only returns text
-** if there is a CR in the buffer. The terminating CR character is removed.
-** wMaxLen Is the size of the buffer and must be at least 2 or an error.
-** Returns U14ERR_NOERR if OK with the result in the string or a negative
-** error code. Any error from the device causes us to set up for
-** a full reset.
-****************************************************************************/
-U14API(short) U14GetString(short hand, char* pBuffer, unsigned short wMaxLen)
-{
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR) // If an error...
- return sErr; // ...bail out!
-
-#ifdef _IS_WINDOWS_
- if (wMaxLen>1) // we need space for terminating 0
- {
- BOOL bLineToGet; // true when a line to get
- long lTimeOutTicks = U14WhenToTimeOut(hand);
- do
- bLineToGet = (BOOL)(U14LineCount(hand) != 0);
- while (!bLineToGet && !U14PassedTime(lTimeOutTicks));
-
- if (!bLineToGet) /* Last-ditch attempt to avoid timeout */
- { /* This can happen with anti-virus or network activity! */
- int i;
- for (i = 0; (i < 4) && (!bLineToGet); ++i)
- {
- Sleep(25); /* Give other threads a chance for a while */
- bLineToGet = (BOOL)(U14LineCount(hand) != 0);
- }
- }
-
- if (bLineToGet)
- {
- if (asLastRetCode[hand] == U14ERR_NOERROR) /* all ok so far */
- {
- unsigned int dwBytes = 0;
- *((unsigned short *)pBuffer) = wMaxLen; /* set up length */
-#ifndef _WIN64
- if (!USE_NT_DIOC(hand)) /* Win 95 DIOC here ? */
- {
- char tstr[MAXSTRLEN+5]; /* Buffer for Win95 chars */
- int iOK;
-
- if (wMaxLen > MAXSTRLEN) /* Truncate length */
- wMaxLen = MAXSTRLEN;
-
- *((unsigned short *)tstr) = wMaxLen; /* set len */
-
- iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_GETSTRING,
- NULL, 0, tstr, wMaxLen+sizeof(short),
- &dwBytes, NULL);
- if (iOK) /* Device IO control OK ? */
- {
- if (dwBytes >= 0) /* If driver OK */
- {
- strcpy(pBuffer, tstr);
- sErr = U14ERR_NOERROR;
- }
- else
- sErr = U14ERR_DRIVCOMMS;
- }
- else
- {
- sErr = (short)GetLastError();
- if (sErr > 0) /* Errors are -ve */
- sErr = (short)-sErr;
- }
- }
- else
-#endif
- { /* Here for NT, the DLL must own the buffer */
- HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE,wMaxLen+sizeof(short));
- if (hMem)
- {
- char* pMem = (char*)GlobalLock(hMem);
- if (pMem)
- {
- int iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_GETSTRING,
- NULL, 0, pMem, wMaxLen+sizeof(short),
- &dwBytes, NULL);
- if (iOK) /* Device IO control OK ? */
- {
- if (dwBytes >= wMaxLen)
- {
- strcpy(pBuffer, pMem+sizeof(short));
- sErr = *((SHORT*)pMem);
- }
- else
- sErr = U14ERR_DRIVCOMMS;
- }
- else
- sErr = U14ERR_DRIVCOMMS;
-
- GlobalUnlock(hMem);
- }
- else
- sErr = U14ERR_OUTOFMEMORY;
-
- GlobalFree(hMem);
- }
- else
- sErr = U14ERR_OUTOFMEMORY;
- }
-
- if (sErr == U14ERR_NOERROR) // If all OK...
- TranslateString(pBuffer); // ...convert any commas to spaces
- else // If we have had a comms error...
- U14ForceReset(hand); // ...make sure we get real reset
-
- }
- else
- sErr = asLastRetCode[hand];
- }
- else
- {
- sErr = U14ERR_TIMEOUT;
- U14ForceReset(hand); // make sure we get real reset
- }
- }
- else
- sErr = U14ERR_BUFF_SMALL;
- return sErr;
-#endif
-#ifdef LINUX
- if (wMaxLen>1) // we need space for terminating 0
- {
- BOOL bLineToGet; // true when a line to get
- long lTimeOutTicks = U14WhenToTimeOut(hand);
- do
- {
- bLineToGet = (BOOL)(U14LineCount(hand) != 0);
- if (!bLineToGet)
- sched_yield();
-
- }
- while (!bLineToGet && !U14PassedTime(lTimeOutTicks));
-
- if (bLineToGet)
- {
- sErr = CED_GetString(aHand1401[hand], pBuffer, wMaxLen-1); // space for terminator
- if (sErr >=0) // if we were OK...
- {
- if (sErr >= wMaxLen) // this should NOT happen unless
- sErr = U14ERR_DRIVCOMMS; // ...driver Comms are very bad
- else
- {
- pBuffer[sErr] = 0; // OK, so terminate the string...
- TranslateString(pBuffer); // ...and convert commas to spaces.
- }
- }
-
- if (sErr < U14ERR_NOERROR) // If we have had a comms error
- U14ForceReset(hand); // make sure we get real reset
- }
- else
- {
- sErr = U14ERR_TIMEOUT;
- U14ForceReset(hand); // make sure we get real reset
- }
- }
- else
- sErr = U14ERR_BUFF_SMALL;
-
- return sErr >= U14ERR_NOERROR ? U14ERR_NOERROR : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14GetChar
-** Get a character from the 1401. CR returned as CR.
-*****************************************************************************/
-U14API(short) U14GetChar(short hand, char* pcChar)
-{
-#ifdef _IS_WINDOWS_
- char sz[2]; // read a very short string
- short sErr = U14GetString(hand, sz, 2); // read one char and nul terminate it
- *pcChar = sz[0]; // copy to result, NB char translate done by GetString
- if (sErr == U14ERR_NOERROR)
- { // undo translate of CR to zero
- if (*pcChar == '\0') // by converting back
- *pcChar = '\n'; // What a nasty thing to have to do
- }
- return sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR) // Check parameters
- return sErr;
- sErr = CED_GetChar(aHand1401[hand]); // get one char, if available
- if (sErr >= 0)
- {
- *pcChar = (char)sErr; // return if it we have one
- return U14ERR_NOERROR; // say all OK
- }
- else
- return sErr;
-#endif
-}
-
-/****************************************************************************
-** U14Stat1401
-** Returns 0 for no lines or error or non zero for something waiting
-****************************************************************************/
-U14API(short) U14Stat1401(short hand)
-{
- return ((short)(U14LineCount(hand) > 0));
-}
-
-/****************************************************************************
-** U14CharCount
-** Returns the number of characters in the input buffer
-*****************************************************************************/
-U14API(short) U14CharCount(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_STAT1401, &csBlock);
- if (sErr == U14ERR_NOERROR)
- sErr = csBlock.ints[0];
- return sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_Stat1401(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14LineCount
-** Returns the number of CR characters in the input buffer
-*****************************************************************************/
-U14API(short) U14LineCount(short hand)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14Status1401(hand, U14_LINECOUNT, &csBlock);
- if (sErr == U14ERR_NOERROR)
- sErr = csBlock.ints[0];
- return sErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_LineCount(aHand1401[hand]) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14GetErrorString
-** Converts error code supplied to a decent descriptive string.
-** NOTE: This function may use some extra information stored
-** internally in the DLL. This information is stored on a
-** per-process basis, but it might be altered if you call
-** other functions after getting an error and before using
-** this function.
-****************************************************************************/
-U14API(void) U14GetErrorString(short nErr, char* pStr, unsigned short wMax)
-{
- char wstr[150];
-
- switch (nErr) /* Basically, we do this with a switch block */
- {
- case U14ERR_OFF:
- sprintf(wstr, "The 1401 is apparently switched off (code %d)", nErr);
- break;
-
- case U14ERR_NC:
- sprintf(wstr, "The 1401 is not connected to the interface card (code %d)", nErr);
- break;
-
- case U14ERR_ILL:
- sprintf(wstr, "The 1401 is not working correctly (code %d)", nErr);
- break;
-
- case U14ERR_NOIF:
- sprintf(wstr, "The 1401 interface card was not detected (code %d)", nErr);
- break;
-
- case U14ERR_TIME:
- sprintf(wstr, "The 1401 fails to become ready for use (code %d)", nErr);
- break;
-
- case U14ERR_BADSW:
- sprintf(wstr, "The 1401 interface card jumpers are incorrect (code %d)", nErr);
- break;
-
- case U14ERR_NOINT:
- sprintf(wstr, "The 1401 interrupt is not available for use (code %d)", nErr);
- break;
-
- case U14ERR_INUSE:
- sprintf(wstr, "The 1401 is already in use by another program (code %d)", nErr);
- break;
-
- case U14ERR_NODMA:
- sprintf(wstr, "The 1401 DMA channel is not available for use (code %d)", nErr);
- break;
-
- case U14ERR_BADHAND:
- sprintf(wstr, "The application supplied an incorrect 1401 handle (code %d)", nErr);
- break;
-
- case U14ERR_BAD1401NUM:
- sprintf(wstr, "The application used an incorrect 1401 number (code %d)", nErr);
- break;
-
- case U14ERR_NO_SUCH_FN:
- sprintf(wstr, "The code passed to the 1401 driver is invalid (code %d)", nErr);
- break;
-
- case U14ERR_NO_SUCH_SUBFN:
- sprintf(wstr, "The sub-code passed to the 1401 driver is invalid (code %d)", nErr);
- break;
-
- case U14ERR_NOOUT:
- sprintf(wstr, "No room in buffer for characters for the 1401 (code %d)", nErr);
- break;
-
- case U14ERR_NOIN:
- sprintf(wstr, "No characters from the 1401 are available (code %d)", nErr);
- break;
-
- case U14ERR_STRLEN:
- sprintf(wstr, "A string sent to or read from the 1401 was too long (code %d)", nErr);
- break;
-
- case U14ERR_LOCKFAIL:
- sprintf(wstr, "Failed to lock host memory for data transfer (code %d)", nErr);
- break;
-
- case U14ERR_UNLOCKFAIL:
- sprintf(wstr, "Failed to unlock host memory after data transfer (code %d)", nErr);
- break;
-
- case U14ERR_ALREADYSET:
- sprintf(wstr, "The transfer area used is already set up (code %d)", nErr);
- break;
-
- case U14ERR_NOTSET:
- sprintf(wstr, "The transfer area used has not been set up (code %d)", nErr);
- break;
-
- case U14ERR_BADAREA:
- sprintf(wstr, "The transfer area number is incorrect (code %d)", nErr);
- break;
-
- case U14ERR_NOFILE:
- sprintf(wstr, "The command file %s could not be opened (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_READERR:
- sprintf(wstr, "The command file %s could not be read (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_UNKNOWN:
- sprintf(wstr, "The %s command resource could not be found (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_HOSTSPACE:
- sprintf(wstr, "Unable to allocate memory for loading command %s (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_LOCKERR:
- sprintf(wstr, "Unable to lock memory for loading command %s (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_CLOADERR:
- sprintf(wstr, "Error in loading command %s, bad command format (code %d)", szLastName, nErr);
- break;
-
- case U14ERR_TOXXXERR:
- sprintf(wstr, "Error detected after data transfer to or from the 1401 (code %d)", nErr);
- break;
-
- case U14ERR_NO386ENH:
- sprintf(wstr, "Windows 3.1 is not running in 386 enhanced mode (code %d)", nErr);
- break;
-
- case U14ERR_NO1401DRIV:
- sprintf(wstr, "The 1401 device driver cannot be found (code %d)\nUSB: check plugged in and powered\nOther: not installed?", nErr);
- break;
-
- case U14ERR_DRIVTOOOLD:
- sprintf(wstr, "The 1401 device driver is too old for use (code %d)", nErr);
- break;
-
- case U14ERR_TIMEOUT:
- sprintf(wstr, "Character transmissions to the 1401 timed-out (code %d)", nErr);
- break;
-
- case U14ERR_BUFF_SMALL:
- sprintf(wstr, "Buffer for text from the 1401 was too small (code %d)", nErr);
- break;
-
- case U14ERR_CBALREADY:
- sprintf(wstr, "1401 monitor callback already set up (code %d)", nErr);
- break;
-
- case U14ERR_BADDEREG:
- sprintf(wstr, "1401 monitor callback deregister invalid (code %d)", nErr);
- break;
-
- case U14ERR_DRIVCOMMS:
- sprintf(wstr, "1401 device driver communications failed (code %d)", nErr);
- break;
-
- case U14ERR_OUTOFMEMORY:
- sprintf(wstr, "Failed to allocate or lock memory for text from the 1401 (code %d)", nErr);
- break;
-
- default:
- sprintf(wstr, "1401 error code %d returned; this code is unknown", nErr);
- break;
-
- }
- if ((unsigned short)strlen(wstr) >= wMax-1) /* Check for string being too long */
- wstr[wMax-1] = 0; /* and truncate it if so */
- strcpy(pStr, wstr); /* Return the error string */
-}
-
-/***************************************************************************
-** U14GetTransfer
-** Get a TGET_TX_BLOCK describing a transfer area (held in the block)
-***************************************************************************/
-U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock)
-{
- short sErr = CheckHandle(hand);
-#ifdef _IS_WINDOWS_
- if (sErr == U14ERR_NOERROR)
- {
- unsigned int dwBytes = 0;
- BOOL bOK = DeviceIoControl(aHand1401[hand], (unsigned int)U14_GETTRANSFER, NULL, 0, pTransBlock,
- sizeof(TGET_TX_BLOCK), &dwBytes, NULL);
-
- if (bOK && (dwBytes >= sizeof(TGET_TX_BLOCK)))
- sErr = U14ERR_NOERROR;
- else
- sErr = U14ERR_DRIVCOMMS;
- }
- return sErr;
-#endif
-#ifdef LINUX
- return (sErr == U14ERR_NOERROR) ? CED_GetTransfer(aHand1401[hand], pTransBlock) : sErr;
-#endif
-}
-/////////////////////////////////////////////////////////////////////////////
-// U14WorkingSet
-// For Win32 only, adjusts process working set so that minimum is at least
-// dwMinKb and maximum is at least dwMaxKb.
-// Return value is zero if all went OK, or a code from 1 to 3 indicating the
-// cause of the failure:
-//
-// 1 unable to access process (insufficient rights?)
-// 2 unable to read process working set
-// 3 unable to set process working set - bad parameters?
-U14API(short) U14WorkingSet(unsigned int dwMinKb, unsigned int dwMaxKb)
-{
-#ifdef _IS_WINDOWS_
- short sRetVal = 0; // 0 means all is OK
- HANDLE hProcess;
- unsigned int dwVer = GetVersion();
- if (dwVer & 0x80000000) // is this not NT?
- return 0; // then give up right now
-
- // Now attempt to get information on working set size
- hProcess = OpenProcess(STANDARD_RIGHTS_REQUIRED |
- PROCESS_QUERY_INFORMATION |
- PROCESS_SET_QUOTA,
- FALSE, _getpid());
- if (hProcess)
- {
- SIZE_T dwMinSize,dwMaxSize;
- if (GetProcessWorkingSetSize(hProcess, &dwMinSize, &dwMaxSize))
- {
- unsigned int dwMin = dwMinKb << 10; // convert from kb to bytes
- unsigned int dwMax = dwMaxKb << 10;
-
- // if we get here, we have managed to read the current size
- if (dwMin > dwMinSize) // need to change sizes?
- dwMinSize = dwMin;
-
- if (dwMax > dwMaxSize)
- dwMaxSize = dwMax;
-
- if (!SetProcessWorkingSetSize(hProcess, dwMinSize, dwMaxSize))
- sRetVal = 3; // failed to change size
- }
- else
- sRetVal = 2; // failed to read original size
-
- CloseHandle(hProcess);
- }
- else
- sRetVal = 1; // failed to get handle
-
- return sRetVal;
-#endif
-#ifdef LINUX
- if (dwMinKb | dwMaxKb)
- {
- // to stop compiler moaning
- }
- return U14ERR_NOERROR;
-#endif
-}
-
-/****************************************************************************
-** U14UnSetTransfer Cancels a transfer area
-** wArea The index of a block previously used in by SetTransfer
-*****************************************************************************/
-U14API(short) U14UnSetTransfer(short hand, unsigned short wArea)
-{
- short sErr = CheckHandle(hand);
-#ifdef _IS_WINDOWS_
- if (sErr == U14ERR_NOERROR)
- {
- TCSBLOCK csBlock;
- csBlock.ints[0] = (short)wArea; /* Area number into control block */
- sErr = U14Control1401(hand, U14_UNSETTRANSFER, &csBlock); /* Free area */
-
- VirtualUnlock(apAreas[hand][wArea], auAreas[hand][wArea]);/* Unlock */
- apAreas[hand][wArea] = NULL; /* Clear locations */
- auAreas[hand][wArea] = 0;
- }
- return sErr;
-#endif
-#ifdef LINUX
- return (sErr == U14ERR_NOERROR) ? CED_UnsetTransfer(aHand1401[hand], wArea) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14SetTransArea Sets an area up to be used for transfers
-** unsigned short wArea The area number to set up
-** void *pvBuff The address of the buffer for the data.
-** unsigned int dwLength The length of the buffer for the data
-** short eSz The element size (used for byte swapping on the Mac)
-****************************************************************************/
-U14API(short) U14SetTransArea(short hand, unsigned short wArea, void *pvBuff,
- unsigned int dwLength, short eSz)
-{
- struct transfer_area_desc td;
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
- if (wArea >= MAX_TRANSAREAS) // Is this a valid area number
- return U14ERR_BADAREA;
-
-#ifdef _IS_WINDOWS_
- assert(apAreas[hand][wArea] == NULL);
- assert(auAreas[hand][wArea] == 0);
-
- apAreas[hand][wArea] = pvBuff; /* Save data for later */
- auAreas[hand][wArea] = dwLength;
-
- if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */
- {
- apAreas[hand][wArea] = NULL; /* Clear locations */
- auAreas[hand][wArea] = 0;
- return U14ERR_LOCKERR; /* VirtualLock failed */
- }
-#ifndef _WIN64
- if (!USE_NT_DIOC(hand)) /* Use Win 9x DIOC? */
- {
- unsigned int dwBytes;
- VXTRANSFERDESC vxDesc; /* Structure to pass to VXD */
- vxDesc.wArea = wArea; /* Copy across simple params */
- vxDesc.dwLength = dwLength;
-
- // Check we are not asking an old driver for more than area 0
- if ((wArea != 0) && (U14DriverVersion(hand) < 0x00010002L))
- sErr = U14ERR_DRIVTOOOLD;
- else
- {
- vxDesc.dwAddrOfs = (unsigned int)pvBuff; /* 32 bit offset */
- vxDesc.wAddrSel = 0;
-
- if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_SETTRANSFER,
- pvBuff,dwLength, /* Will translate pointer */
- &vxDesc,sizeof(VXTRANSFERDESC),
- &dwBytes,NULL))
- {
- if (dwBytes >= sizeof(VXTRANSFERDESC)) /* Driver OK ? */
- sErr = U14ERR_NOERROR;
- else
- sErr = U14ERR_DRIVCOMMS; /* Else never got there */
- }
- else
- sErr = (short)GetLastError();
- }
- }
- else
-#endif
- {
- PARAMBLK rWork;
- unsigned int dwBytes;
- td.wArea = wArea; /* Pure NT - put data into struct */
- td.lpvBuff = pvBuff;
- td.dwLength = dwLength;
- td.eSize = 0; // Dummy element size
-
- if (DeviceIoControl(aHand1401[hand],(unsigned int)U14_SETTRANSFER,
- &td,sizeof(struct transfer_area_desc),
- &rWork,sizeof(PARAMBLK),&dwBytes,NULL))
- {
- if (dwBytes >= sizeof(PARAMBLK)) // maybe error from driver?
- sErr = rWork.sState; // will report any error
- else
- sErr = U14ERR_DRIVCOMMS; // Else never got there
- }
- else
- sErr = U14ERR_DRIVCOMMS;
- }
-
- if (sErr != U14ERR_NOERROR)
- {
- if (sErr != U14ERR_LOCKERR) // unless lock failed...
- VirtualUnlock(pvBuff, dwLength); // ...release the lock
- apAreas[hand][wArea] = NULL; // Clear locations
- auAreas[hand][wArea] = 0;
- }
-
- return sErr;
-#endif
-#ifdef LINUX
- // The strange cast is so that it works in 64 and 32-bit linux as long is 64-bits
- // in the 64 bit version.
- td.lpvBuff = (long long)((unsigned long)pvBuff);
- td.wAreaNum = wArea;
- td.dwLength = dwLength;
- td.eSize = eSz; // Dummy element size
- return CED_SetTransfer(aHand1401[hand], &td);
-#endif
-}
-
-/****************************************************************************
-** U14SetTransferEvent Sets an event for notification of application
-** wArea The transfer area index, from 0 to MAXAREAS-1
-** bEvent True to create an event, false to remove it
-** bToHost Set 0 for notification on to1401 tranfers, 1 for
-** notification of transfers to the host PC
-** dwStart The offset of the sub-area of interest
-** dwLength The size of the sub-area of interest
-**
-** The device driver will set the event supplied to the signalled state
-** whenever a DMA transfer to/from the specified area is completed. The
-** transfer has to be in the direction specified by bToHost, and overlap
-** that part of the whole transfer area specified by dwStart and dwLength.
-** It is important that this function is called with bEvent false to release
-** the event once 1401 activity is finished.
-**
-** Returns 1 if an event handle exists, 0 if all OK and no event handle or
-** a negative code for an error.
-****************************************************************************/
-U14API(short) U14SetTransferEvent(short hand, unsigned short wArea, BOOL bEvent,
- BOOL bToHost, unsigned int dwStart, unsigned int dwLength)
-{
-#ifdef _IS_WINDOWS_
- TCSBLOCK csBlock;
- short sErr = U14TransferFlags(hand); // see if we can handle events
- if (sErr >= U14ERR_NOERROR) // check handle is OK
- {
- bEvent = bEvent && ((sErr & U14TF_NOTIFY) != 0); // remove request if we cannot do events
- if (wArea >= MAX_TRANSAREAS) // Check a valid area...
- return U14ERR_BADAREA; // ...and bail of not
-
- // We can hold an event for each area, so see if we need to change the
- // state of the event.
- if ((bEvent != 0) != (aXferEvent[hand] != 0)) // change of event state?
- {
- if (bEvent) // want one and none present
- aXferEvent[hand] = CreateEvent(NULL, FALSE, FALSE, NULL);
- else
- {
- CloseHandle(aXferEvent[hand]); // clear the existing event
- aXferEvent[hand] = NULL; // and clear handle
- }
- }
-
- // We have to store the parameters differently for 64-bit operations
- // because a handle is 64 bits long. The drivers know of this and
- // handle the information appropriately.
-#ifdef _WIN64
- csBlock.longs[0] = wArea; // Pass paramaters into the driver...
- if (bToHost != 0) // The direction flag is held in the
- csBlock.longs[0] |= 0x10000; // upper word of the transfer area value
- *((HANDLE*)&csBlock.longs[1]) = aXferEvent[hand]; // The event handle is 64-bits
- csBlock.longs[3] = dwStart; // Thankfully these two remain
- csBlock.longs[4] = dwLength; // as unsigned 32-bit values
-#else
- csBlock.longs[0] = wArea; // pass paramaters into the driver...
- csBlock.longs[1] = (long)aXferEvent[hand]; // ...especially the event handle
- csBlock.longs[2] = bToHost;
- csBlock.longs[3] = dwStart;
- csBlock.longs[4] = dwLength;
-#endif
- sErr = U14Control1401(hand, U14_SETTRANSEVENT, &csBlock);
- if (sErr == U14ERR_NOERROR)
- sErr = (short)(aXferEvent[hand] != NULL); // report if we have a flag
- }
-
- return sErr;
-#endif
-#ifdef LINUX
- TRANSFEREVENT te;
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
-
- if (wArea >= MAX_TRANSAREAS) // Is this a valid area number
- return U14ERR_BADAREA;
-
- te.wAreaNum = wArea; // copy parameters to the control block
- te.wFlags = bToHost ? 1 : 0; // bit 0 sets the direction
- te.dwStart = dwStart; // start offset of the event area
- te.dwLength = dwLength; // size of the event area
- te.iSetEvent = bEvent; // in Windows, this creates/destroys the event
- return CED_SetEvent(aHand1401[hand], &te);
-#endif
-}
-
-/****************************************************************************
-** U14TestTransferEvent
-** Would a U14WaitTransferEvent() call return immediately? return 1 if so,
-** 0 if not or a negative code if a problem.
-****************************************************************************/
-U14API(int) U14TestTransferEvent(short hand, unsigned short wArea)
-{
-#ifdef _IS_WINDOWS_
- int iErr = CheckHandle(hand);
- if (iErr == U14ERR_NOERROR)
- {
- if (aXferEvent[hand]) // if a handle is set...
- iErr = WaitForSingleObject(aXferEvent[hand], 0) == WAIT_OBJECT_0;
- }
- return iErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_TestEvent(aHand1401[hand], wArea) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14WaitTransferEvent
-** Wait for a transfer event with a timeout.
-** msTimeOut is 0 for an infinite wait, else it is the maximum time to wait
-** in milliseconds in range 0-0x00ffffff.
-** Returns If no event handle then return immediately. Else return 1 if
-** timed out or 0=event, and a negative code if a problem.
-****************************************************************************/
-U14API(int) U14WaitTransferEvent(short hand, unsigned short wArea, int msTimeOut)
-{
-#ifdef _IS_WINDOWS_
- int iErr = CheckHandle(hand);
- if (iErr == U14ERR_NOERROR)
- {
- if (aXferEvent[hand])
- {
- if (msTimeOut == 0)
- msTimeOut = INFINITE;
- iErr = WaitForSingleObject(aXferEvent[hand], msTimeOut) != WAIT_OBJECT_0;
- }
- else
- iErr = TRUE; // say we timed out if no event
- }
- return iErr;
-#endif
-#ifdef LINUX
- short sErr = CheckHandle(hand);
- return (sErr == U14ERR_NOERROR) ? CED_WaitEvent(aHand1401[hand], wArea, msTimeOut) : sErr;
-#endif
-}
-
-/****************************************************************************
-** U14SetCircular Sets an area up for circular DMA transfers
-** unsigned short wArea The area number to set up
-** BOOL bToHost Sets the direction of data transfer
-** void *pvBuff The address of the buffer for the data
-** unsigned int dwLength The length of the buffer for the data
-****************************************************************************/
-U14API(short) U14SetCircular(short hand, unsigned short wArea, BOOL bToHost,
- void *pvBuff, unsigned int dwLength)
-{
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
-
- if (wArea >= MAX_TRANSAREAS) /* Is this a valid area number */
- return U14ERR_BADAREA;
-
- if (!bToHost) /* For now, support tohost transfers only */
- return U14ERR_BADAREA; /* best error code I can find */
-#ifdef _IS_WINDOWS_
- assert(apAreas[hand][wArea] == NULL);
- assert(auAreas[hand][wArea] == 0);
-
- apAreas[hand][wArea] = pvBuff; /* Save data for later */
- auAreas[hand][wArea] = dwLength;
-
- if (!VirtualLock(pvBuff, dwLength)) /* Lock using WIN32 calls */
- sErr = U14ERR_LOCKERR; /* VirtualLock failed */
- else
- {
- PARAMBLK rWork;
- unsigned int dwBytes;
- struct transfer_area_desc txDesc;
- txDesc.wArea = wArea; /* Pure NT - put data into struct */
- txDesc.lpvBuff = pvBuff;
- txDesc.dwLength = dwLength;
- txDesc.eSize = (short)bToHost; /* Use this for direction flag */
-
- if (DeviceIoControl(aHand1401[hand],(unsigned int)U14_SETCIRCULAR,
- &txDesc, sizeof(struct transfer_area_desc),
- &rWork, sizeof(PARAMBLK),&dwBytes,NULL))
- {
- if (dwBytes >= sizeof(PARAMBLK)) /* error from driver? */
- sErr = rWork.sState; /* No, just return driver data */
- else
- sErr = U14ERR_DRIVCOMMS; /* Else never got there */
- }
- else
- sErr = U14ERR_DRIVCOMMS;
- }
-
- if (sErr != U14ERR_NOERROR)
- {
- if (sErr != U14ERR_LOCKERR)
- VirtualUnlock(pvBuff, dwLength); /* Release NT lock */
- apAreas[hand][wArea] = NULL; /* Clear locations */
- auAreas[hand][wArea] = 0;
- }
-
- return sErr;
-#endif
-#ifdef LINUX
- else
- {
- struct transfer_area_desc td;
- td.lpvBuff = (long long)((unsigned long)pvBuff);
- td.wAreaNum = wArea;
- td.dwLength = dwLength;
- td.eSize = (short)bToHost; /* Use this for direction flag */
- return CED_SetCircular(aHand1401[hand], &td);
- }
-#endif
-}
-
-/****************************************************************************
-** Function GetCircBlk returns the size (& start offset) of the next
-** available block of circular data.
-****************************************************************************/
-U14API(int) U14GetCircBlk(short hand, unsigned short wArea, unsigned int *pdwOffs)
-{
- int lErr = CheckHandle(hand);
- if (lErr != U14ERR_NOERROR)
- return lErr;
-
- if (wArea >= MAX_TRANSAREAS) // Is this a valid area number?
- return U14ERR_BADAREA;
- else
- {
-#ifdef _IS_WINDOWS_
- PARAMBLK rWork;
- TCSBLOCK csBlock;
- unsigned int dwBytes;
- csBlock.longs[0] = wArea; // Area number into control block
- rWork.sState = U14ERR_DRIVCOMMS;
- if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_GETCIRCBLK, &csBlock, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
- (dwBytes >= sizeof(PARAMBLK)))
- lErr = rWork.sState;
- else
- lErr = U14ERR_DRIVCOMMS;
-
- if (lErr == U14ERR_NOERROR) // Did everything go OK?
- { // Yes, we can pass the results back
- lErr = rWork.csBlock.longs[1]; // Return the block information
- *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array
- }
-#endif
-#ifdef LINUX
- TCIRCBLOCK cb;
- cb.nArea = wArea; // Area number into control block
- cb.dwOffset = 0;
- cb.dwSize = 0;
- lErr = CED_GetCircBlock(aHand1401[hand], &cb);
- if (lErr == U14ERR_NOERROR) // Did everything go OK?
- { // Yes, we can pass the results back
- lErr = cb.dwSize; // return the size
- *pdwOffs = cb.dwOffset; // and the offset
- }
-#endif
- }
- return lErr;
-}
-
-/****************************************************************************
-** Function FreeCircBlk marks the specified area of memory as free for
-** resuse for circular transfers and returns the size (& start
-** offset) of the next available block of circular data.
-****************************************************************************/
-U14API(int) U14FreeCircBlk(short hand, unsigned short wArea, unsigned int dwOffs, unsigned int dwSize,
- unsigned int *pdwOffs)
-{
- int lErr = CheckHandle(hand);
- if (lErr != U14ERR_NOERROR)
- return lErr;
-
- if (wArea < MAX_TRANSAREAS) // Is this a valid area number
- {
-#ifdef _IS_WINDOWS_
- PARAMBLK rWork;
- TCSBLOCK csBlock;
- unsigned int dwBytes;
- csBlock.longs[0] = wArea; // Area number into control block
- csBlock.longs[1] = dwOffs;
- csBlock.longs[2] = dwSize;
- rWork.sState = U14ERR_DRIVCOMMS;
- if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_FREECIRCBLK, &csBlock, sizeof(TCSBLOCK),
- &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
- (dwBytes >= sizeof(PARAMBLK)))
- lErr = rWork.sState;
- else
- lErr = U14ERR_DRIVCOMMS;
- if (lErr == U14ERR_NOERROR) // Did everything work OK?
- { // Yes, we can pass the results back
- lErr = rWork.csBlock.longs[1]; // Return the block information
- *pdwOffs = rWork.csBlock.longs[0]; // Offset is first in array
- }
-#endif
-#ifdef LINUX
- TCIRCBLOCK cb;
- cb.nArea = wArea; // Area number into control block
- cb.dwOffset = dwOffs;
- cb.dwSize = dwSize;
-
- lErr = CED_FreeCircBlock(aHand1401[hand], &cb);
- if (lErr == U14ERR_NOERROR) // Did everything work OK?
- { // Yes, we can pass the results back
- lErr = cb.dwSize; // Return the block information
- *pdwOffs = cb.dwOffset; // Offset is first in array
- }
-#endif
- }
- else
- lErr = U14ERR_BADAREA;
-
- return lErr;
-}
-
-/****************************************************************************
-** Transfer
-** Transfer moves data to 1401 or to host
-** Assumes memory is allocated and locked,
-** which it should be to get a pointer
-*****************************************************************************/
-static short Transfer(short hand, BOOL bTo1401, char* pData,
- unsigned int dwSize, unsigned int dw1401, short eSz)
-{
- char strcopy[MAXSTRLEN+1]; // to hold copy of work string
- short sResult = U14SetTransArea(hand, 0, (void *)pData, dwSize, eSz);
- if (sResult == U14ERR_NOERROR) // no error
- {
- sprintf(strcopy, // data offset is always 0
- "TO%s,$%X,$%X,0;", bTo1401 ? "1401" : "HOST", dw1401, dwSize);
-
- U14SendString(hand, strcopy); // send transfer string
-
- sResult = U14CheckErr(hand); // Use ERR command to check for done
- if (sResult > 0)
- sResult = U14ERR_TOXXXERR; // If a 1401 error, use this code
-
- U14UnSetTransfer(hand, 0);
- }
- return sResult;
-}
-
-/****************************************************************************
-** Function ToHost transfers data into the host from the 1401
-****************************************************************************/
-U14API(short) U14ToHost(short hand, char* pAddrHost, unsigned int dwSize,
- unsigned int dw1401, short eSz)
-{
- short sErr = CheckHandle(hand);
- if ((sErr == U14ERR_NOERROR) && dwSize) // TOHOST is a constant
- sErr = Transfer(hand, TOHOST, pAddrHost, dwSize, dw1401, eSz);
- return sErr;
-}
-
-/****************************************************************************
-** Function To1401 transfers data into the 1401 from the host
-****************************************************************************/
-U14API(short) U14To1401(short hand, const char* pAddrHost,unsigned int dwSize,
- unsigned int dw1401, short eSz)
-{
- short sErr = CheckHandle(hand);
- if ((sErr == U14ERR_NOERROR) && dwSize) // TO1401 is a constant
- sErr = Transfer(hand, TO1401, (char*)pAddrHost, dwSize, dw1401, eSz);
- return sErr;
-}
-
-/****************************************************************************
-** Function LdCmd Loads a command from a full path or just a file
-*****************************************************************************/
-#ifdef _IS_WINDOWS_
-#define file_exist(name) (_access(name, 0) != -1)
-#define file_open(name) _lopen(name, OF_READ)
-#define file_close(h) _lclose(h)
-#define file_seek(h, pos) _llseek(h, pos, FILE_BEGIN)
-#define file_read(h, buffer, size) (_lread(h, buffer, size) == size)
-#endif
-#ifdef LINUX
-#define file_exist(name) (access(name, F_OK) != -1)
-#define file_open(name) open(name, O_RDONLY)
-#define file_close(h) close(h)
-#define file_seek(h, pos) lseek(h, pos, SEEK_SET)
-#define file_read(h, buffer, size) (read(h, buffer, size) == (ssize_t)size)
-static unsigned int GetModuleFileName(void* dummy, char* buffer, int max)
-{
- // The following works for Linux systems with a /proc file system.
- char szProcPath[32];
- sprintf(szProcPath, "/proc/%d/exe", getpid()); // attempt to read link
- if (readlink(szProcPath, buffer, max) != -1)
- {
- dirname (buffer);
- strcat (buffer, "/");
- return strlen(buffer);
- }
- return 0;
-}
-#endif
-
-U14API(short) U14LdCmd(short hand, const char* command)
-{
- char strcopy[MAXSTRLEN+1]; // to hold copy of work string
- BOOL bGotIt = FALSE; // have we found the command file?
- int iFHandle; // file handle of command
-#define FNSZ 260
- char filnam[FNSZ]; // space to build name in
- char szCmd[25]; // just the command name with extension
-
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
-
- if (strchr(command, '.') != NULL) // see if we have full name
- {
- if (file_exist(command)) // If the file exists
- {
- strcpy(filnam, command); // use name as is
- bGotIt = TRUE; // Flag no more searching
- }
- else // not found, get file name for search
- {
- char* pStr = strrchr(command, PATHSEP); // Point to last separator
- if (pStr != NULL) // Check we got it
- {
- pStr++; // move past the backslash
- strcpy(szCmd, pStr); // copy file name as is
- }
- else
- strcpy(szCmd, command); // use as is
- }
- }
- else // File extension not supplied, so build the command file name
- {
- char szExt[8];
- strcpy(szCmd, command); // Build command file name
- ExtForType(asType1401[hand], szExt);// File extension string
- strcat(szCmd, szExt); // add it to the end
- }
-
- // Next place to look is in the 1401 folder in the same place as the
- // application was run from.
- if (!bGotIt) // Still not got it?
- {
- unsigned int dwLen = GetModuleFileName(NULL, filnam, FNSZ); // Get app path
- if (dwLen > 0) // and use it as path if found
- {
- char* pStr = strrchr(filnam, PATHSEP); // Point to last separator
- if (pStr != NULL)
- {
- *(++pStr) = 0; // Terminate string there
- if (strlen(filnam) < FNSZ-6) // make sure we have space
- {
- strcat(filnam, "1401" PATHSEPSTR); // add in 1401 subdir
- strcat(filnam,szCmd);
- bGotIt = (BOOL)file_exist(filnam); // See if file exists
- }
- }
- }
- }
-
- // Next place to look is in whatever path is set by the 1401DIR environment
- // variable, if it exists.
- if (!bGotIt) // Need to do more searches?/
- {
- char* pStr = getenv("1401DIR"); // Try to find environment var
- if (pStr != NULL) // and use it as path if found
- {
- strcpy(filnam, pStr); // Use path in environment
- if (filnam[strlen(filnam)-1] != PATHSEP)// We need separator
- strcat(filnam, PATHSEPSTR);
- strcat(filnam, szCmd);
- bGotIt = (BOOL)file_exist(filnam); // Got this one?
- }
- }
-
- // Last place to look is the default location.
- if (!bGotIt) // Need to do more searches?
- {
- strcpy(filnam, DEFCMDPATH); // Use default path
- strcat(filnam, szCmd);
- bGotIt = file_exist(filnam); // Got this one?
- }
-
- iFHandle = file_open(filnam);
- if (iFHandle == -1)
- sErr = U14ERR_NOFILE;
- else
- { // first read in the header block
- CMDHEAD rCmdHead; // to hold the command header
- if (file_read(iFHandle, &rCmdHead, sizeof(CMDHEAD)))
- {
- size_t nComSize = rCmdHead.wCmdSize;
- char* pMem = malloc(nComSize);
- if (pMem != NULL)
- {
- file_seek(iFHandle, sizeof(CMDHEAD));
- if (file_read(iFHandle, pMem, (UINT)nComSize))
- {
- sErr = U14SetTransArea(hand, 0, (void *)pMem, (unsigned int)nComSize, ESZBYTES);
- if (sErr == U14ERR_NOERROR)
- {
- sprintf(strcopy, "CLOAD,0,$%X;", (int)nComSize);
- sErr = U14SendString(hand, strcopy);
- if (sErr == U14ERR_NOERROR)
- {
- sErr = U14CheckErr(hand); // Use ERR to check for done
- if (sErr > 0)
- sErr = U14ERR_CLOADERR; // If an error, this code
- }
- U14UnSetTransfer(hand, 0); // release transfer area
- }
- }
- else
- sErr = U14ERR_READERR;
- free(pMem);
- }
- else
- sErr = U14ERR_HOSTSPACE; // memory allocate failed
- }
- else
- sErr = U14ERR_READERR;
-
- file_close(iFHandle); // close the file
- }
-
- return sErr;
-}
-
-
-/****************************************************************************
-** Ld
-** Loads a command into the 1401
-** Returns NOERROR code or a long with error in lo word and index of
-** command that failed in high word
-****************************************************************************/
-U14API(unsigned int) U14Ld(short hand, const char* vl, const char* str)
-{
- unsigned int dwIndex = 0; // index to current command
- long lErr = U14ERR_NOERROR; // what the error was that went wrong
- char strcopy[MAXSTRLEN+1]; // stores unmodified str parameter
- char szFExt[8]; // The command file extension
- short sErr = CheckHandle(hand);
- if (sErr != U14ERR_NOERROR)
- return sErr;
-
- ExtForType(asType1401[hand], szFExt); // File extension string
- strcpy(strcopy, str); // to avoid changing original
-
- // now break out one command at a time and see if loaded
- if (*str) // if anything there
- {
- BOOL bDone = FALSE; // true when finished all commands
- int iLoop1 = 0; // Point at start of string for command name
- int iLoop2 = 0; // and at start of str parameter
- do // repeat until end of str
- {
- char filnam[MAXSTRLEN+1]; // filename to use
- char szFName[MAXSTRLEN+1]; // filename work string
-
- if (!strcopy[iLoop1]) // at the end of the string?
- bDone = TRUE; // set the finish flag
-
- if (bDone || (strcopy[iLoop1] == ',')) // end of cmd?
- {
- U14LONG er[5]; // Used to read back error results
- ++dwIndex; // Keep count of command number, first is 1
- szFName[iLoop2]=(char)0; // null terminate name of command
-
- strncpy(szLastName, szFName, sizeof(szLastName)); // Save for error info
- szLastName[sizeof(szLastName)-1] = 0;
- strncat(szLastName, szFExt, sizeof(szLastName)); // with extension included
- szLastName[sizeof(szLastName)-1] = 0;
-
- U14SendString(hand, szFName); // ask if loaded
- U14SendString(hand, ";ERR;"); // add err return
-
- lErr = U14LongsFrom1401(hand, er, 5);
- if (lErr > 0)
- {
- lErr = U14ERR_NOERROR;
- if (er[0] == 255) // if command not loaded at all
- {
- if (vl && *vl) // if we have a path name
- {
- strcpy(filnam, vl);
- if (strchr("\\/:", filnam[strlen(filnam)-1]) == NULL)
- strcat(filnam, PATHSEPSTR); // add separator if none found
- strcat(filnam, szFName); // add the file name
- strcat(filnam, szFExt); // and extension
- }
- else
- strcpy(filnam, szFName); // simple name
-
- lErr = U14LdCmd(hand, filnam); // load cmd
- if (lErr != U14ERR_NOERROR) // spot any errors
- bDone = TRUE; // give up if an error
- }
- }
- else
- bDone = TRUE; // give up if an error
-
- iLoop2 = 0; // Reset pointer to command name string
- ++iLoop1; // and move on through str parameter
- }
- else
- szFName[iLoop2++] = strcopy[iLoop1++]; // no command end, so copy 1 char
- }
- while (!bDone);
- }
-
- if (lErr == U14ERR_NOERROR)
- {
- szLastName[0] = 0; // No error, so clean out command name here
- return lErr;
- }
- else
- return ((dwIndex<<16) | ((unsigned int)lErr & 0x0000FFFF));
-}
-
-// Initialise the library (if not initialised) and return the library version
-U14API(int) U14InitLib(void)
-{
- int iRetVal = U14LIB_VERSION;
- if (iAttached == 0) // only do this the first time please
- {
- int i;
-#ifdef _IS_WINDOWS_
- int j;
- unsigned int dwVersion = GetVersion();
- bWindows9x = FALSE; // Assume not Win9x
-
- if (dwVersion & 0x80000000) // if not windows NT
- {
- if ((LOBYTE(LOWORD(dwVersion)) < 4) && // if Win32s or...
- (HIBYTE(LOWORD(dwVersion)) < 95)) // ...below Windows 95
- iRetVal = 0; // We do not support this
- else
- bWindows9x = TRUE; // Flag we have Win9x
- }
-#endif
-
- for (i = 0; i < MAX1401; i++) // initialise the device area
- {
- aHand1401[i] = INVALID_HANDLE_VALUE; // Clear handle values
- asType1401[i] = U14TYPEUNKNOWN; // and 1401 type codes
- alTimeOutPeriod[i] = 3000; // 3 second timeouts
-#ifdef _IS_WINDOWS_
-#ifndef _WIN64
- abUseNTDIOC[i] = (BOOL)!bWindows9x;
-#endif
- aXferEvent[i] = NULL; // there are no Xfer events
- for (j = 0; j < MAX_TRANSAREAS; j++) // Clear out locked area info
- {
- apAreas[i][j] = NULL;
- auAreas[i][j] = 0;
- }
-#endif
- }
- }
- return iRetVal;
-}
-
-///--------------------------------------------------------------------------------
-/// Functions called when the library is loaded and unloaded to give us a chance to
-/// setup the library.
-
-
-#ifdef _IS_WINDOWS_
-#ifndef U14_NOT_DLL
-/****************************************************************************
-** FUNCTION: DllMain(HANDLE, unsigned int, LPVOID)
-** LibMain is called by Windows when the DLL is initialized, Thread Attached,
-** and other times. Refer to SDK documentation, as to the different ways this
-** may be called.
-****************************************************************************/
-INT APIENTRY DllMain(HANDLE hInst, unsigned int ul_reason_being_called, LPVOID lpReserved)
-{
- int iRetVal = 1;
-
- switch (ul_reason_being_called)
- {
- case DLL_PROCESS_ATTACH:
- iRetVal = U14InitLib() > 0; // does nothing if iAttached != 0
- ++iAttached; // count times attached
- break;
-
- case DLL_PROCESS_DETACH:
- if (--iAttached == 0) // last man out?
- U14CloseAll(); // release all open handles
- break;
- }
- return iRetVal;
-
- UNREFERENCED_PARAMETER(lpReserved);
-}
-#endif
-#endif
-#ifdef LINUX
-void __attribute__((constructor)) use1401_load(void)
-{
- U14InitLib();
- ++iAttached;
-}
-
-void __attribute__((destructor)) use1401_unload(void)
-{
- if (--iAttached == 0) // last man out?
- U14CloseAll(); // release all open handles
-}
-#endif
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index a2f6957e7ee9..36f2c7159250 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -135,13 +135,14 @@ config COMEDI_PCL724
support driver.
Supported boards include:
- Advantech PCL-724 24 channels
- Advantech PCL-722 144 (or 96) channels
- Advantech PCL-731 48 channels
- ADlink ACL-7122 144 (or 96) channels
- ADlink ACL-7124 24 channels
- ADlink PET-48DIO 48 channels
- WinSystems PCM-IO48 48 channels (PC/104)
+ Advantech PCL-724 24 channels
+ Advantech PCL-722 144 (or 96) channels
+ Advantech PCL-731 48 channels
+ ADlink ACL-7122 144 (or 96) channels
+ ADlink ACL-7124 24 channels
+ ADlink PET-48DIO 48 channels
+ WinSystems PCM-IO48 48 channels (PC/104)
+ Diamond Systems ONYX-MM-DIO 48 channels (PC/104)
To compile this driver as a module, choose M here: the module will be
called pcl724.
@@ -172,6 +173,7 @@ config COMEDI_PCL730
Advantech PCL-734 iso - 32 out
Diamond Systems OPMM-1616-XT iso - 16 in/16 out
Diamond Systems PEARL-MM-P iso - 16 out
+ Diamond Systems IR104-PBF iso - 20 in/20 out
To compile this driver as a module, choose M here: the module will be
called pcl730.
@@ -813,7 +815,7 @@ config COMEDI_AMPLC_PC236_PCI
Enable support for Amplicon PCI236 DIO board.
To compile this driver as a module, choose M here: the module will be
- called amplc_pc236.
+ called amplc_pci236.
config COMEDI_AMPLC_PC263_PCI
tristate "Amplicon PCI263 relay board support"
@@ -1012,8 +1014,6 @@ config COMEDI_NI_6527
config COMEDI_NI_65XX
tristate "NI 65xx static dio PCI card support"
- depends on HAS_DMA
- select COMEDI_MITE
---help---
Enable support for National Instruments 65xx static dio boards.
Supported devices: National Instruments PCI-6509 (ni_65xx),
@@ -1037,8 +1037,6 @@ config COMEDI_NI_660X
config COMEDI_NI_670X
tristate "NI 670x PCI card support"
- depends on HAS_DMA
- select COMEDI_MITE
---help---
Enable support for National Instruments PCI-6703 and PCI-6704
@@ -1047,9 +1045,7 @@ config COMEDI_NI_670X
config COMEDI_NI_LABPC_PCI
tristate "NI Lab-PC PCI-1200 support"
- depends on HAS_DMA
select COMEDI_NI_LABPC
- select COMEDI_MITE
---help---
Enable support for National Instruments Lab-PC PCI-1200.
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 6bbbe5b08954..217baf812f87 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -551,21 +551,8 @@ enum i8254_mode {
I8254_BINARY = 0
};
-static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
-{
- if (pfi_channel < 10)
- return 0x1 + pfi_channel;
- else
- return 0xb + pfi_channel;
-}
-
-static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)
-{
- if (rtsi_channel < 7)
- return 0xb + rtsi_channel;
- else
- return 0x1b;
-}
+#define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x)))
+#define NI_USUAL_RTSI_SELECT(x) (((x) < 7) ? (0xb + (x)) : 0x1b)
/* mode bits for NI general-purpose counters, set with
* INSN_CONFIG_SET_COUNTER_MODE */
@@ -659,20 +646,14 @@ enum ni_gpct_clock_source_bits {
NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
};
-static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
-{
- /* NI 660x-specific */
- return 0x10 + n;
-}
-static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
-{
- return 0x18 + n;
-}
-static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
-{
- /* no pfi on NI 660x */
- return 0x20 + n;
-}
+
+/* NI 660x-specific */
+#define NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(x) (0x10 + (x))
+
+#define NI_GPCT_RTSI_CLOCK_SRC_BITS(x) (0x18 + (x))
+
+/* no pfi on NI 660x */
+#define NI_GPCT_PFI_CLOCK_SRC_BITS(x) (0x20 + (x))
/* Possibilities for setting a gate source with
INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
@@ -698,22 +679,11 @@ enum ni_gpct_gate_select {
* known. */
NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
};
-static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
-{
- return 0x102 + n;
-}
-static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
-{
- return NI_USUAL_RTSI_SELECT(n);
-}
-static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
-{
- return NI_USUAL_PFI_SELECT(n);
-}
-static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
-{
- return 0x202 + n;
-}
+
+#define NI_GPCT_GATE_PIN_GATE_SELECT(x) (0x102 + (x))
+#define NI_GPCT_RTSI_GATE_SELECT(x) NI_USUAL_RTSI_SELECT(x)
+#define NI_GPCT_PFI_GATE_SELECT(x) NI_USUAL_PFI_SELECT(x)
+#define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x) (0x202 + (x))
/* Possibilities for setting a source with
INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
@@ -722,15 +692,14 @@ enum ni_gpct_other_index {
NI_GPCT_SOURCE_ENCODER_B,
NI_GPCT_SOURCE_ENCODER_Z
};
+
enum ni_gpct_other_select {
/* m-series gates */
/* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
};
-static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
-{
- return NI_USUAL_PFI_SELECT(n);
-}
+
+#define NI_GPCT_PFI_OTHER_SELECT(x) NI_USUAL_PFI_SELECT(x)
/* start sources for ni general-purpose counters for use with
INSN_CONFIG_ARM */
@@ -777,10 +746,8 @@ enum ni_mio_clock_source {
NI_MIO_PLL_PXI10_CLOCK = 3,
NI_MIO_PLL_RTSI0_CLOCK = 4
};
-static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
-{
- return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
-}
+
+#define NI_MIO_PLL_RTSI_CLOCK(x) (NI_MIO_PLL_RTSI0_CLOCK + (x))
/* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
The numbers assigned are not arbitrary, they correspond to the bits required
@@ -798,10 +765,8 @@ enum ni_rtsi_routing {
NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI
* clock on line 7 */
};
-static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
-{
- return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
-}
+
+#define NI_RTSI_OUTPUT_RTSI_BRD(x) (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x))
/* Signals which can be routed to an NI PFI pin on an m-series board with
* INSN_CONFIG_SET_ROUTING. These numbers are also returned by
@@ -834,10 +799,8 @@ enum ni_pfi_routing {
NI_PFI_OUTPUT_CDI_SAMPLE = 29,
NI_PFI_OUTPUT_CDO_UPDATE = 30
};
-static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
-{
- return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
-}
+
+#define NI_PFI_OUTPUT_RTSI(x) (NI_PFI_OUTPUT_RTSI0 + (x))
/* Signals which can be routed to output on a NI PFI pin on a 660x board
with INSN_CONFIG_SET_ROUTING. The numbers assigned are
@@ -853,14 +816,8 @@ enum ni_660x_pfi_routing {
/* NI External Trigger lines. These values are not arbitrary, but are related
* to the bits required to program the board (offset by 1 for historical
* reasons). */
-static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
-{
- return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
-}
-static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
-{
- return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
-}
+#define NI_EXT_PFI(x) (NI_USUAL_PFI_SELECT(x) - 1)
+#define NI_EXT_RTSI(x) (NI_USUAL_RTSI_SELECT(x) - 1)
/* status bits for INSN_CONFIG_GET_COUNTER_STATUS */
enum comedi_counter_status_flags {
@@ -884,26 +841,15 @@ enum ni_m_series_cdio_scan_begin_src {
NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
};
-static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-{
- return NI_USUAL_PFI_SELECT(pfi_channel);
-}
-static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-{
- return NI_USUAL_RTSI_SELECT(rtsi_channel);
-}
+
+#define NI_CDIO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
+#define NI_CDIO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
/* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
* boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to
* change polarity. */
-static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-{
- return NI_USUAL_PFI_SELECT(pfi_channel);
-}
-static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-{
- return NI_USUAL_RTSI_SELECT(rtsi_channel);
-}
+#define NI_AO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
+#define NI_AO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
/* Bits for setting a clock source with
* INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
@@ -976,4 +922,15 @@ enum amplc_dio_gate_source {
AMPLC_DIO_GAT_NPAT_GONE /* negated "pattern gone away" */
};
+/*
+ * Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
+ * the counter subdevice on the Kolter Electronic PCI-Counter board
+ * (ke_counter driver).
+ */
+enum ke_counter_clock_source {
+ KE_CLK_20MHZ, /* internal 20MHz (default) */
+ KE_CLK_4MHZ, /* internal 4MHz (option) */
+ KE_CLK_EXT /* external clock on pin 21 of D-Sub */
+};
+
#endif /* _COMEDI_H */
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 1e9da405d833..9b6f96f1591c 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -107,10 +107,10 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
chaninfo = compat_alloc_user_space(sizeof(*chaninfo));
/* Copy chaninfo structure. Ignore unused members. */
- if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32))
- || !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) {
+ if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32)) ||
+ !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo)))
return -EFAULT;
- }
+
err = 0;
err |= __get_user(temp.uint, &chaninfo32->subdev);
err |= __put_user(temp.uint, &chaninfo->subdev);
@@ -141,10 +141,10 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo));
/* Copy rangeinfo structure. */
- if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32))
- || !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) {
+ if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32)) ||
+ !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo)))
return -EFAULT;
- }
+
err = 0;
err |= __get_user(temp.uint, &rangeinfo32->range_type);
err |= __put_user(temp.uint, &rangeinfo->range_type);
@@ -168,10 +168,10 @@ static int get_compat_cmd(struct comedi_cmd __user *cmd,
} temp;
/* Copy cmd structure. */
- if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32))
- || !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
+ if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32)) ||
+ !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd)))
return -EFAULT;
- }
+
err = 0;
err |= __get_user(temp.uint, &cmd32->subdev);
err |= __put_user(temp.uint, &cmd->subdev);
@@ -219,10 +219,10 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
/* Assume the pointer values are already valid. */
/* (Could use ptr_to_compat() to set them, but that wasn't implemented
* until kernel version 2.6.11.) */
- if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd))
- || !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
+ if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd)) ||
+ !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32)))
return -EFAULT;
- }
+
err = 0;
err |= __get_user(temp, &cmd->subdev);
err |= __put_user(temp, &cmd32->subdev);
@@ -311,8 +311,8 @@ static int get_compat_insn(struct comedi_insn __user *insn,
/* Copy insn structure. Ignore the unused members. */
err = 0;
- if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
- || !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
+ if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32)) ||
+ !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
return -EFAULT;
err |= __get_user(temp.uint, &insn32->insn);
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index 28e3c3059037..2d0a6fcf60f3 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -25,8 +25,7 @@
#ifdef CONFIG_COMPAT
struct file;
-extern long comedi_compat_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
+long comedi_compat_ioctl(struct file *, unsigned int cmd, unsigned long arg);
#else /* CONFIG_COMPAT */
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 9d99fb3c18a6..2182c7463cdb 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -16,6 +16,8 @@
GNU General Public License for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "comedi_compat32.h"
#include <linux/module.h>
@@ -206,8 +208,8 @@ struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
{
if (minor < COMEDI_NUM_BOARD_MINORS)
return comedi_dev_get_from_board_minor(minor);
- else
- return comedi_dev_get_from_subdevice_minor(minor);
+
+ return comedi_dev_get_from_subdevice_minor(minor);
}
EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor);
@@ -266,7 +268,7 @@ static int resize_async_buffer(struct comedi_device *dev,
return retval;
if (s->buf_change) {
- retval = s->buf_change(dev, s, new_size);
+ retval = s->buf_change(dev, s);
if (retval < 0)
return retval;
}
@@ -968,9 +970,6 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
s = &dev->subdevices[bi.subdevice];
- if (s->lock && s->lock != file)
- return -EACCES;
-
async = s->async;
if (!async) {
@@ -997,7 +996,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
comedi_buf_read_free(s, bi.bytes_read);
if (comedi_is_subdevice_idle(s) &&
- async->buf_write_count == async->buf_read_count) {
+ comedi_buf_n_bytes_ready(s) == 0) {
do_become_nonbusy(dev, s);
}
}
@@ -1076,11 +1075,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
/* by default we allow the insn since we don't have checks for
* all possible cases yet */
default:
- pr_warn("comedi: No check for data length of config insn id %i is implemented.\n",
+ pr_warn("No check for data length of config insn id %i is implemented\n",
data[0]);
- pr_warn("comedi: Add a check to %s in %s.\n",
- __func__, __FILE__);
- pr_warn("comedi: Assuming n=%i is correct.\n", insn->n);
+ pr_warn("Add a check to %s in %s\n", __func__, __FILE__);
+ pr_warn("Assuming n=%i is correct\n", insn->n);
return 0;
}
return -EINVAL;
@@ -1229,10 +1227,9 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
/* Most drivers ignore the base channel in
* insn->chanspec. Fix this here if
* the subdevice has <= 32 channels. */
- unsigned int shift;
- unsigned int orig_mask;
+ unsigned int orig_mask = data[0];
+ unsigned int shift = 0;
- orig_mask = data[0];
if (s->n_chan <= 32) {
shift = CR_CHAN(insn->chanspec);
if (shift > 0) {
@@ -1240,8 +1237,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
data[0] <<= shift;
data[1] <<= shift;
}
- } else
- shift = 0;
+ }
ret = s->insn_bits(dev, s, insn, data);
data[0] = orig_mask;
if (shift > 0)
@@ -1295,7 +1291,7 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
if (copy_from_user(&insnlist, arg, sizeof(insnlist)))
return -EFAULT;
- data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc_array(MAX_SAMPLES, sizeof(unsigned int), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto error;
@@ -1376,7 +1372,7 @@ static int do_insn_ioctl(struct comedi_device *dev,
unsigned int *data = NULL;
int ret = 0;
- data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc_array(MAX_SAMPLES, sizeof(unsigned int), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto error;
@@ -1664,14 +1660,6 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
s->lock = file;
spin_unlock_irqrestore(&s->spin_lock, flags);
-#if 0
- if (ret < 0)
- return ret;
-
- if (s->lock_f)
- ret = s->lock_f(dev, s);
-#endif
-
return ret;
}
@@ -1706,14 +1694,8 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg,
if (s->lock && s->lock != file)
return -EACCES;
- if (s->lock == file) {
-#if 0
- if (s->unlock)
- s->unlock(dev, s);
-#endif
-
+ if (s->lock == file)
s->lock = NULL;
- }
return 0;
}
@@ -1744,9 +1726,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
if (s->async == NULL)
return -EINVAL;
- if (s->lock && s->lock != file)
- return -EACCES;
-
if (!s->busy)
return 0;
@@ -1781,9 +1760,6 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
return -EINVAL;
s = &dev->subdevices[arg];
- if (s->lock && s->lock != file)
- return -EACCES;
-
if (!s->busy)
return 0;
@@ -2186,7 +2162,7 @@ out:
}
static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
- loff_t *offset)
+ loff_t *offset)
{
struct comedi_subdevice *s;
struct comedi_async *async;
@@ -2230,10 +2206,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
n = nbytes;
m = comedi_buf_read_n_available(s);
- /* printk("%d available\n",m); */
if (async->buf_read_ptr + m > async->prealloc_bufsz)
m = async->prealloc_bufsz - async->buf_read_ptr;
- /* printk("%d contiguous\n",m); */
if (m < n)
n = m;
@@ -2303,8 +2277,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
new_s = comedi_read_subdevice(dev, minor);
if (dev->attached && old_detach_count == dev->detach_count &&
s == new_s && new_s->async == async) {
- if (become_nonbusy ||
- async->buf_read_count - async->buf_write_count == 0)
+ if (become_nonbusy || comedi_buf_n_bytes_ready(s) == 0)
do_become_nonbusy(dev, s);
}
mutex_unlock(&dev->mutex);
@@ -2411,12 +2384,6 @@ static const struct file_operations comedi_fops = {
.llseek = noop_llseek,
};
-void comedi_error(const struct comedi_device *dev, const char *s)
-{
- dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
-}
-EXPORT_SYMBOL_GPL(comedi_error);
-
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
@@ -2460,7 +2427,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
struct device *csdev;
unsigned i;
- dev = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL)
return ERR_PTR(-ENOMEM);
comedi_device_init(dev);
@@ -2479,7 +2446,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
mutex_unlock(&dev->mutex);
comedi_device_cleanup(dev);
comedi_dev_put(dev);
- pr_err("comedi: error: ran out of minor numbers for board device files.\n");
+ pr_err("ran out of minor numbers for board device files\n");
return ERR_PTR(-EBUSY);
}
dev->minor = i;
@@ -2532,7 +2499,7 @@ int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
}
mutex_unlock(&comedi_subdevice_minor_table_lock);
if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
- pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
+ pr_err("ran out of minor numbers for subdevice files\n");
return -EBUSY;
}
i += COMEDI_NUM_BOARD_MINORS;
@@ -2582,11 +2549,11 @@ static int __init comedi_init(void)
int i;
int retval;
- pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
+ pr_info("version " COMEDI_RELEASE " - http://www.comedi.org\n");
if (comedi_num_legacy_minors < 0 ||
comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
- pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
+ pr_err("invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n",
COMEDI_NUM_BOARD_MINORS);
return -EINVAL;
}
@@ -2597,7 +2564,14 @@ static int __init comedi_init(void)
return -EIO;
cdev_init(&comedi_cdev, &comedi_fops);
comedi_cdev.owner = THIS_MODULE;
- kobject_set_name(&comedi_cdev.kobj, "comedi");
+
+ retval = kobject_set_name(&comedi_cdev.kobj, "comedi");
+ if (retval) {
+ unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
+ COMEDI_NUM_MINORS);
+ return retval;
+ }
+
if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS);
@@ -2605,7 +2579,7 @@ static int __init comedi_init(void)
}
comedi_class = class_create(THIS_MODULE, "comedi");
if (IS_ERR(comedi_class)) {
- pr_err("comedi: failed to create class\n");
+ pr_err("failed to create class\n");
cdev_del(&comedi_cdev);
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS);
@@ -2628,10 +2602,9 @@ static int __init comedi_init(void)
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS);
return PTR_ERR(dev);
- } else {
- /* comedi_alloc_board_minor() locked the mutex */
- mutex_unlock(&dev->mutex);
}
+ /* comedi_alloc_board_minor() locked the mutex */
+ mutex_unlock(&dev->mutex);
}
return 0;
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index e978c223f5b5..d57817c19aea 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -48,6 +48,7 @@ void comedi_proc_cleanup(void);
static inline void comedi_proc_init(void)
{
}
+
static inline void comedi_proc_cleanup(void)
{
}
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 8f4e44bfbe00..58e58a32e93d 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -75,13 +75,9 @@ struct comedi_subdevice {
struct comedi_cmd *);
int (*poll)(struct comedi_device *, struct comedi_subdevice *);
int (*cancel)(struct comedi_device *, struct comedi_subdevice *);
- /* int (*do_lock)(struct comedi_device *, struct comedi_subdevice *); */
- /* int (*do_unlock)(struct comedi_device *, \
- struct comedi_subdevice *); */
/* called when the buffer changes */
- int (*buf_change)(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size);
+ int (*buf_change)(struct comedi_device *, struct comedi_subdevice *);
void (*munge)(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
@@ -107,43 +103,110 @@ struct comedi_buf_map {
struct kref refcount;
};
+/**
+ * struct comedi_async - control data for asynchronous comedi commands
+ * @prealloc_buf: preallocated buffer
+ * @prealloc_bufsz: buffer size (in bytes)
+ * @buf_map: map of buffer pages
+ * @max_bufsize: maximum buffer size (in bytes)
+ * @buf_write_count: "write completed" count (in bytes, modulo 2**32)
+ * @buf_write_alloc_count: "allocated for writing" count (in bytes,
+ * modulo 2**32)
+ * @buf_read_count: "read completed" count (in bytes, modulo 2**32)
+ * @buf_read_alloc_count: "allocated for reading" count (in bytes,
+ * modulo 2**32)
+ * @buf_write_ptr: buffer position for writer
+ * @buf_read_ptr: buffer position for reader
+ * @cur_chan: current position in chanlist for scan (for those
+ * drivers that use it)
+ * @scan_progress: amount received or sent for current scan (in bytes)
+ * @munge_chan: current position in chanlist for "munging"
+ * @munge_count: "munge" count (in bytes, modulo 2**32)
+ * @munge_ptr: buffer position for "munging"
+ * @events: bit-vector of events that have occurred
+ * @cmd: details of comedi command in progress
+ * @wait_head: task wait queue for file reader or writer
+ * @cb_mask: bit-vector of events that should wake waiting tasks
+ * @inttrig: software trigger function for command, or NULL
+ *
+ * Note about the ..._count and ..._ptr members:
+ *
+ * Think of the _Count values being integers of unlimited size, indexing
+ * into a buffer of infinite length (though only an advancing portion
+ * of the buffer of fixed length prealloc_bufsz is accessible at any time).
+ * Then:
+ *
+ * Buf_Read_Count <= Buf_Read_Alloc_Count <= Munge_Count <=
+ * Buf_Write_Count <= Buf_Write_Alloc_Count <=
+ * (Buf_Read_Count + prealloc_bufsz)
+ *
+ * (Those aren't the actual members, apart from prealloc_bufsz.) When
+ * the buffer is reset, those _Count values start at 0 and only increase
+ * in value, maintaining the above inequalities until the next time the
+ * buffer is reset. The buffer is divided into the following regions by
+ * the inequalities:
+ *
+ * [0, Buf_Read_Count):
+ * old region no longer accessible
+ * [Buf_Read_Count, Buf_Read_Alloc_Count):
+ * filled and munged region allocated for reading but not yet read
+ * [Buf_Read_Alloc_Count, Munge_Count):
+ * filled and munged region not yet allocated for reading
+ * [Munge_Count, Buf_Write_Count):
+ * filled region not yet munged
+ * [Buf_Write_Count, Buf_Write_Alloc_Count):
+ * unfilled region allocated for writing but not yet written
+ * [Buf_Write_Alloc_Count, Buf_Read_Count + prealloc_bufsz):
+ * unfilled region not yet allocated for writing
+ * [Buf_Read_Count + prealloc_bufsz, infinity):
+ * unfilled region not yet accessible
+ *
+ * Data needs to be written into the buffer before it can be read out,
+ * and may need to be converted (or "munged") between the two
+ * operations. Extra unfilled buffer space may need to allocated for
+ * writing (advancing Buf_Write_Alloc_Count) before new data is written.
+ * After writing new data, the newly filled space needs to be released
+ * (advancing Buf_Write_Count). This also results in the new data being
+ * "munged" (advancing Munge_Count). Before data is read out of the
+ * buffer, extra space may need to be allocated for reading (advancing
+ * Buf_Read_Alloc_Count). After the data has been read out, the space
+ * needs to be released (advancing Buf_Read_Count).
+ *
+ * The actual members, buf_read_count, buf_read_alloc_count,
+ * munge_count, buf_write_count, and buf_write_alloc_count take the
+ * value of the corresponding capitalized _Count values modulo 2^32
+ * (UINT_MAX+1). Subtracting a "higher" _count value from a "lower"
+ * _count value gives the same answer as subtracting a "higher" _Count
+ * value from a lower _Count value because prealloc_bufsz < UINT_MAX+1.
+ * The modulo operation is done implicitly.
+ *
+ * The buf_read_ptr, munge_ptr, and buf_write_ptr members take the value
+ * of the corresponding capitalized _Count values modulo prealloc_bufsz.
+ * These correspond to byte indices in the physical buffer. The modulo
+ * operation is done by subtracting prealloc_bufsz when the value
+ * exceeds prealloc_bufsz (assuming prealloc_bufsz plus the increment is
+ * less than or equal to UINT_MAX).
+ */
struct comedi_async {
- void *prealloc_buf; /* pre-allocated buffer */
- unsigned int prealloc_bufsz; /* buffer size, in bytes */
- struct comedi_buf_map *buf_map; /* map of buffer pages */
-
- unsigned int max_bufsize; /* maximum buffer size, bytes */
-
- /* byte count for writer (write completed) */
+ void *prealloc_buf;
+ unsigned int prealloc_bufsz;
+ struct comedi_buf_map *buf_map;
+ unsigned int max_bufsize;
unsigned int buf_write_count;
- /* byte count for writer (allocated for writing) */
unsigned int buf_write_alloc_count;
- /* byte count for reader (read completed) */
unsigned int buf_read_count;
- /* byte count for reader (allocated for reading) */
unsigned int buf_read_alloc_count;
-
- unsigned int buf_write_ptr; /* buffer marker for writer */
- unsigned int buf_read_ptr; /* buffer marker for reader */
-
- unsigned int cur_chan; /* useless channel marker for interrupt */
- /* number of bytes that have been received for current scan */
+ unsigned int buf_write_ptr;
+ unsigned int buf_read_ptr;
+ unsigned int cur_chan;
unsigned int scan_progress;
- /* keeps track of where we are in chanlist as for munging */
unsigned int munge_chan;
- /* number of bytes that have been munged */
unsigned int munge_count;
- /* buffer marker for munging */
unsigned int munge_ptr;
-
- unsigned int events; /* events that have occurred */
-
+ unsigned int events;
struct comedi_cmd cmd;
-
wait_queue_head_t wait_head;
-
unsigned int cb_mask;
-
int (*inttrig)(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int x);
};
@@ -190,6 +253,7 @@ struct comedi_device {
struct comedi_subdevice *subdevices;
/* dumb */
+ void __iomem *mmio;
unsigned long iobase;
unsigned long iolen;
unsigned int irq;
@@ -213,7 +277,6 @@ static inline const void *comedi_board(const struct comedi_device *dev)
*/
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
-void comedi_error(const struct comedi_device *dev, const char *s);
/* we can expand the number of bits used to encode devices/subdevices into
the minor number soon, after more distros support > 8 bit minor numbers
@@ -222,6 +285,7 @@ enum comedi_minor_bits {
COMEDI_DEVICE_MINOR_MASK = 0xf,
COMEDI_SUBDEVICE_MINOR_MASK = 0xf0
};
+
static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
@@ -296,6 +360,12 @@ static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s,
return s->range_table->range[range].min >= 0;
}
+static inline bool comedi_range_is_external(struct comedi_subdevice *s,
+ unsigned int range)
+{
+ return !!(s->range_table->range[range].flags & RF_EXTERNAL);
+}
+
static inline bool comedi_chan_range_is_bipolar(struct comedi_subdevice *s,
unsigned int chan,
unsigned int range)
@@ -310,6 +380,13 @@ static inline bool comedi_chan_range_is_unipolar(struct comedi_subdevice *s,
return s->range_table_list[chan]->range[range].min >= 0;
}
+static inline bool comedi_chan_range_is_external(struct comedi_subdevice *s,
+ unsigned int chan,
+ unsigned int range)
+{
+ return !!(s->range_table_list[chan]->range[range].flags & RF_EXTERNAL);
+}
+
/* munge between offset binary and two's complement values */
static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
unsigned int val)
@@ -321,8 +398,8 @@ static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
{
if (subd->subdev_flags & SDF_LSAMPL)
return sizeof(unsigned int);
- else
- return sizeof(short);
+
+ return sizeof(short);
}
/*
@@ -333,6 +410,11 @@ static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
*/
int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev);
+static inline unsigned int comedi_buf_n_bytes_ready(struct comedi_subdevice *s)
+{
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, unsigned int n);
unsigned int comedi_buf_write_free(struct comedi_subdevice *s, unsigned int n);
@@ -484,9 +566,9 @@ int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
int comedi_pcmcia_driver_register(struct comedi_driver *,
- struct pcmcia_driver *);
+ struct pcmcia_driver *);
void comedi_pcmcia_driver_unregister(struct comedi_driver *,
- struct pcmcia_driver *);
+ struct pcmcia_driver *);
/**
* module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 299726f39e26..9ada130f2a76 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -38,6 +38,7 @@
#include "comedi_internal.h"
struct comedi_driver *comedi_drivers;
+/* protects access to comedi_drivers */
DEFINE_MUTEX(comedi_drivers_list_lock);
int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
@@ -120,6 +121,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
dev->driver = NULL;
dev->board_name = NULL;
dev->board_ptr = NULL;
+ dev->mmio = NULL;
dev->iobase = 0;
dev->iolen = 0;
dev->ioenabled = false;
@@ -319,7 +321,7 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev,
return -ENOMEM;
}
if (s->buf_change) {
- ret = s->buf_change(dev, s, buf_size);
+ ret = s->buf_change(dev, s);
if (ret < 0)
return ret;
}
@@ -566,8 +568,9 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_ptr = comedi_recognize(driv, it->board_name);
if (dev->board_ptr)
break;
- } else if (strcmp(driv->driver_name, it->board_name) == 0)
+ } else if (strcmp(driv->driver_name, it->board_name) == 0) {
break;
+ }
module_put(driv->module);
}
if (driv == NULL) {
@@ -591,8 +594,6 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = -ENOSYS;
goto out;
}
- /* initialize dev->driver here so
- * comedi_error() can be called from attach */
dev->driver = driv;
dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
: dev->driver->driver_name;
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index 5829b46b757b..f8e1ebad304d 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -34,7 +34,7 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
unsigned int *d1,
unsigned int *d2,
unsigned int *nanosec,
- int round_mode)
+ unsigned int flags)
{
unsigned int divider;
unsigned int div1, div2;
@@ -90,8 +90,7 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
}
}
- round_mode &= TRIG_ROUND_MASK;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
ns_high = div1_lub * div2_lub * i8253_osc_base;
@@ -118,7 +117,6 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
/* masking is done since counter maps zero to 0x10000 */
*d1 = div1 & 0xffff;
*d2 = div2 & 0xffff;
- return;
}
#ifndef CMDTEST
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 46113a374133..a33a19622745 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -102,9 +102,8 @@ static int subdev_8255_io(int dir, int port, int data, unsigned long iobase)
if (dir) {
outb(data, iobase + port);
return 0;
- } else {
- return inb(iobase + port);
}
+ return inb(iobase + port);
}
void subdev_8255_interrupt(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 46a385c29ba8..f21e6567ac2f 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -56,7 +56,6 @@ Configuration Options: not applicable, uses PCI auto config
#include "../comedidev.h"
#include "8255.h"
-#include "mite.h"
enum pci_8255_boardid {
BOARD_ADLINK_PCI7224,
@@ -168,9 +167,9 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
},
};
-struct pci_8255_private {
- void __iomem *mmio_base;
-};
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
static int pci_8255_mite_init(struct pci_dev *pcidev)
{
@@ -198,9 +197,8 @@ static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
if (dir) {
writeb(data, mmio_base + port);
return 0;
- } else {
- return readb(mmio_base + port);
}
+ return readb(mmio_base + port);
}
static int pci_8255_auto_attach(struct comedi_device *dev,
@@ -208,7 +206,6 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct pci_8255_boardinfo *board = NULL;
- struct pci_8255_private *devpriv;
struct comedi_subdevice *s;
bool is_mmio;
int ret;
@@ -221,10 +218,6 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
dev->board_ptr = board;
dev->board_name = board->name;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -238,8 +231,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
is_mmio = (pci_resource_flags(pcidev, board->dio_badr) &
IORESOURCE_MEM) != 0;
if (is_mmio) {
- devpriv->mmio_base = pci_ioremap_bar(pcidev, board->dio_badr);
- if (!devpriv->mmio_base)
+ dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr);
+ if (!dev->mmio)
return -ENOMEM;
} else {
dev->iobase = pci_resource_start(pcidev, board->dio_badr);
@@ -259,7 +252,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[i];
if (is_mmio) {
- iobase = (unsigned long)(devpriv->mmio_base + (i * 4));
+ iobase = (unsigned long)(dev->mmio + (i * 4));
ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase);
} else {
iobase = dev->iobase + (i * 4);
@@ -274,10 +267,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
static void pci_8255_detach(struct comedi_device *dev)
{
- struct pci_8255_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mmio_base)
- iounmap(devpriv->mmio_base);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 0757a82ddcfa..8873d4807a01 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_COMEDI_SKEL) += skel.o
# Comedi ISA drivers
obj-$(CONFIG_COMEDI_AMPLC_DIO200_ISA) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236_ISA) += amplc_pc236.o
obj-$(CONFIG_COMEDI_AMPLC_PC263_ISA) += amplc_pc263.o
obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
@@ -80,7 +81,7 @@ obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o
obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o
obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o
obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI) += amplc_dio200_pci.o
-obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI) += amplc_pci236.o
obj-$(CONFIG_COMEDI_AMPLC_PC263_PCI) += amplc_pci263.o
obj-$(CONFIG_COMEDI_AMPLC_PCI224) += amplc_pci224.o
obj-$(CONFIG_COMEDI_AMPLC_PCI230) += amplc_pci230.o
@@ -138,5 +139,6 @@ obj-$(CONFIG_COMEDI_NI_LABPC_ISADMA) += ni_labpc_isadma.o
obj-$(CONFIG_COMEDI_8255) += 8255.o
obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200_common.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236_common.o
obj-$(CONFIG_COMEDI_DAS08) += das08.o
obj-$(CONFIG_COMEDI_FC) += comedi_fc.o
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index dc87df032203..de5843ab01ae 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -157,14 +157,10 @@ static int addi_auto_attach(struct comedi_device *dev,
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND
| SDF_DIFF;
- if (devpriv->s_EeParameters.i_NbrAiChannel) {
- s->n_chan =
- devpriv->s_EeParameters.i_NbrAiChannel;
- devpriv->b_SingelDiff = 0;
- } else {
+ if (devpriv->s_EeParameters.i_NbrAiChannel)
+ s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel;
+ else
s->n_chan = this_board->i_NbrAiChannelDiff;
- devpriv->b_SingelDiff = 1;
- }
s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
s->len_chanlist = this_board->i_AiChannelList;
s->range_table = this_board->pr_AiRangelist;
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index 5c6a11c35ded..a7400a25f620 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -18,25 +18,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#define LOWORD(W) (unsigned short)((W) & 0xFFFF)
-#define HIWORD(W) (unsigned short)(((W) >> 16) & 0xFFFF)
-
-#define ADDI_ENABLE 1
-#define ADDI_DISABLE 0
-#define APCI1710_SAVE_INTERRUPT 1
-
-#define ADDIDATA_EEPROM 1
-#define ADDIDATA_NO_EEPROM 0
-#define ADDIDATA_93C76 "93C76"
-#define ADDIDATA_S5920 "S5920"
-
-/* ADDIDATA Enable Disable */
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* Structures */
-
-/* structure for the boardtype */
struct addi_board {
const char *pc_DriverName; /* driver name */
int i_IorangeBase1;
@@ -141,7 +122,6 @@ struct addi_private {
unsigned char b_InterruptMode; /* eoc eos or dma */
unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */
unsigned int ui_EocEosConversionTime;
- unsigned char b_SingelDiff;
unsigned char b_ExttrigEnable; /* To enable or disable external trigger */
/* Pointer to the current process */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 28450f65a134..cad33f1a04fe 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -177,8 +177,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Disable the hardware trigger */
ui_Command = ui_Command & 0xFFFFF89FUL;
- if (data[4] == ADDIDATA_ENABLE) {
-
+ if (data[4] == 1) {
/* Set the hardware trigger level */
ui_Command = ui_Command | (data[5] << 5);
}
@@ -188,8 +187,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Disable the hardware gate */
ui_Command = ui_Command & 0xFFFFF87FUL;
- if (data[6] == ADDIDATA_ENABLE) {
-
+ if (data[6] == 1) {
/* Set the hardware gate level */
ui_Command = ui_Command | (data[7] << 7);
}
@@ -203,8 +201,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Set the hardware output level */
ui_Command = ui_Command | (data[8] << 2);
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
- if (data[9] == ADDIDATA_ENABLE) {
-
+ if (data[9] == 1) {
/* Set the reload value */
outl(data[11],
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index a633957890d7..1e2fe66818e4 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -872,7 +872,8 @@ static int apci1500_do_write(struct comedi_device *dev,
break;
default:
- comedi_error(dev, " chan spec wrong");
+ dev_err(dev->class_dev,
+ "chan spec wrong\n");
return -EINVAL; /* "sorry channel spec wrong " */
} /* switch(ui_NoOfChannels) */
@@ -950,8 +951,8 @@ static int apci1500_do_write(struct comedi_device *dev,
break;
default:
- comedi_error(dev,
- " chan spec wrong");
+ dev_err(dev->class_dev,
+ "chan spec wrong\n");
return -EINVAL; /* "sorry channel spec wrong " */
} /* switch(ui_NoOfChannels) */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 0ba5385226ae..8a613ae0acba 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -21,17 +21,15 @@
*
*/
-#include "../addi_watchdog.h"
-
#define APCI1564_ADDRESS_RANGE 128
/* Digital Input IRQ Function Selection */
-#define ADDIDATA_OR 0
-#define ADDIDATA_AND 1
+#define APCI1564_DI_INT_OR (0 << 1)
+#define APCI1564_DI_INT_AND (1 << 1)
/* Digital Input Interrupt Enable Disable. */
-#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
-#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb
+#define APCI1564_DI_INT_ENABLE 0x4
+#define APCI1564_DI_INT_DISABLE 0xfffffffb
/* Digital Output Interrupt Enable Disable. */
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
@@ -49,7 +47,7 @@
#define APCI1564_COUNTER4 3
/*
- * devpriv->i_IobaseAmcc Register Map
+ * devpriv->amcc_iobase Register Map
*/
#define APCI1564_DI_REG 0x04
#define APCI1564_DI_INT_MODE1_REG 0x08
@@ -89,46 +87,6 @@
#define APCI1564_TCW_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20))
#define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20))
-/* Global variables */
-static unsigned int ui_InterruptStatus_1564;
-static unsigned int ui_InterruptData, ui_Type;
-
-/*
- * Configures the digital input Subdevice
- *
- * data[0] 1 = Enable interrupt, 0 = Disable interrupt
- * data[1] 0 = ADDIDATA Interrupt OR LOGIC, 1 = ADDIDATA Interrupt AND LOGIC
- * data[2] Interrupt mask for the mode 1
- * data[3] Interrupt mask for the mode 2
- */
-static int apci1564_di_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct addi_private *devpriv = dev->private;
-
- devpriv->tsk_Current = current;
-
- /* Set the digital input logic */
- if (data[0] == ADDIDATA_ENABLE) {
- data[2] = data[2] << 4;
- data[3] = data[3] << 4;
- outl(data[2], devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
- if (data[1] == ADDIDATA_OR)
- outl(0x4, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- else
- outl(0x6, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- } else {
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- }
-
- return insn->n;
-}
-
/*
* Configures The Digital Output Subdevice.
*
@@ -140,33 +98,26 @@ static int apci1564_do_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command = 0;
if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
+ dev_err(dev->class_dev, "Data should be 1 or 0\n");
return -EINVAL;
}
- if (data[0])
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- else
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
-
- if (data[1] == ADDIDATA_ENABLE)
+ if (data[1] == 1)
ul_Command = ul_Command | 0x1;
else
ul_Command = ul_Command & 0xFFFFFFFE;
- if (data[2] == ADDIDATA_ENABLE)
+ if (data[2] == 1)
ul_Command = ul_Command | 0x2;
else
ul_Command = ul_Command & 0xFFFFFFFD;
- outl(ul_Command, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
- ui_InterruptData = inl(devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
- devpriv->tsk_Current = current;
+ outl(ul_Command, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
+ devpriv->tsk_current = current;
return insn->n;
}
@@ -186,31 +137,31 @@ static int apci1564_timer_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- devpriv->tsk_Current = current;
+ devpriv->tsk_current = current;
if (data[0] == ADDIDATA_WATCHDOG) {
- devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+ devpriv->timer_select_mode = ADDIDATA_WATCHDOG;
/* Disable the watchdog */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
/* Loading the Reload value */
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_WDOG_RELOAD_REG);
+ outl(data[3], devpriv->amcc_iobase + APCI1564_WDOG_RELOAD_REG);
} else if (data[0] == ADDIDATA_TIMER) {
/* First Stop The Timer */
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
/* Stop The Timer */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
- devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ devpriv->timer_select_mode = ADDIDATA_TIMER;
if (data[1] == 1) {
/* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */
- outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_IRQ_REG);
+ outl(0x02, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG);
outl(0x0,
dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1));
outl(0x0,
@@ -221,22 +172,22 @@ static int apci1564_timer_config(struct comedi_device *dev,
dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4));
} else {
/* disable Timer interrupt */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
}
/* Loading Timebase */
- outl(data[2], devpriv->i_IobaseAmcc + APCI1564_TIMER_TIMEBASE_REG);
+ outl(data[2], devpriv->amcc_iobase + APCI1564_TIMER_TIMEBASE_REG);
/* Loading the Reload value */
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
+ outl(data[3], devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
/* mode 2 */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
} else if (data[0] == ADDIDATA_COUNTER) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- devpriv->b_ModeSelectRegister = data[5];
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ devpriv->mode_select_register = data[5];
/* First Stop The Counter */
ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
@@ -285,45 +236,45 @@ static int apci1564_timer_write(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) {
switch (data[1]) {
case 0: /* stop the watchdog */
/* disable the watchdog */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
case 1: /* start the watchdog */
- outl(0x0001, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0001, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
case 2: /* Software trigger */
- outl(0x0201, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0201, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
default:
dev_err(dev->class_dev, "Specified functionality does not exist.\n");
return -EINVAL;
}
}
- if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (devpriv->timer_select_mode == ADDIDATA_TIMER) {
if (data[1] == 1) {
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
/* Enable the Timer */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
} else if (data[1] == 0) {
/* Stop The Timer */
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
}
}
- if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
ul_Command1 =
inl(dev->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1));
if (data[1] == 1) {
/* Start the Counter subdevice */
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
@@ -336,7 +287,7 @@ static int apci1564_timer_write(struct comedi_device *dev,
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
}
outl(ul_Command1, dev->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1));
}
return insn->n;
}
@@ -349,27 +300,27 @@ static int apci1564_timer_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) {
/* Stores the status of the Watchdog */
- data[0] = inl(devpriv->i_IobaseAmcc + APCI1564_WDOG_STATUS_REG) & 0x1;
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
- } else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[0] = inl(devpriv->amcc_iobase + APCI1564_WDOG_STATUS_REG) & 0x1;
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_WDOG_REG);
+ } else if (devpriv->timer_select_mode == ADDIDATA_TIMER) {
/* Stores the status of the Timer */
- data[0] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_STATUS_REG) & 0x1;
+ data[0] = inl(devpriv->amcc_iobase + APCI1564_TIMER_STATUS_REG) & 0x1;
/* Stores the Actual value of the Timer */
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_REG);
- } else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_TIMER_REG);
+ } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
/* Read the Counter Actual Value. */
data[0] =
inl(dev->iobase +
- APCI1564_TCW_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_REG(devpriv->mode_select_register - 1));
ul_Command1 =
inl(dev->iobase +
- APCI1564_TCW_STATUS_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_STATUS_REG(devpriv->mode_select_register - 1));
/* Get the software trigger status */
data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
@@ -382,170 +333,10 @@ static int apci1564_timer_read(struct comedi_device *dev,
/* Get the overflow status */
data[4] = (unsigned char) ((ul_Command1 >> 0) & 1);
- } else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
- && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
- && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
+ } else if ((devpriv->timer_select_mode != ADDIDATA_TIMER)
+ && (devpriv->timer_select_mode != ADDIDATA_WATCHDOG)
+ && (devpriv->timer_select_mode != ADDIDATA_COUNTER)) {
dev_err(dev->class_dev, "Invalid Subdevice!\n");
}
return insn->n;
}
-
-/*
- * Reads the interrupt status register
- */
-static int apci1564_do_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- *data = ui_Type;
- return insn->n;
-}
-
-/*
- * Interrupt handler for the interruptible digital inputs
- */
-static void apci1564_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct addi_private *devpriv = dev->private;
- unsigned int ui_DO, ui_DI;
- unsigned int ui_Timer;
- unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
- unsigned int ul_Command2 = 0;
-
- ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG) & 0x01;
- ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG) & 0x01;
- ui_Timer = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_IRQ_REG) & 0x01;
- ui_C1 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
- ui_C2 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
- ui_C3 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
- ui_C4 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
- if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
- && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
- dev_err(dev->class_dev, "Interrupt from unknown source.\n");
- }
-
- if (ui_DI == 1) {
- ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- ui_InterruptStatus_1564 =
- inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
- ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
- /* send signal to the sample */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- /* enable the interrupt */
- outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- return;
- }
-
- if (ui_DO == 1) {
- /* Check for Digital Output interrupt Type */
- /* 1: VCC interrupt */
- /* 2: CC interrupt */
- ui_Type = inl(devpriv->i_IobaseAmcc + APCI1564_DO_INT_STATUS_REG) & 0x3;
- /* Disable the Interrupt */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
-
- /* Sends signal to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- }
-
- if (ui_Timer == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Timer Interrupt */
- ul_Command2 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Timer Interrupt */
-
- outl(ul_Command2, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- }
- }
-
- if (ui_C1 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- }
- }
-
- if (ui_C2 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- }
- }
-
- if (ui_C3 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- }
- }
-
- if (ui_C4 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- }
- }
- return;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index 764c8f17f8fa..77cee876a374 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -270,7 +270,7 @@ static int apci3120_ai_insn_config(struct comedi_device *dev,
if (CR_CHAN(data[4 + i]) >=
this_board->i_NbrAiChannel) {
- printk("bad channel list\n");
+ dev_err(dev->class_dev, "bad channel list\n");
return -2;
}
}
@@ -318,7 +318,8 @@ static int apci3120_setup_chan_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
if (!check)
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev,
+ "range/channel list is empty!\n");
return 0;
}
/* All is ok, so we can setup channel/range list */
@@ -344,11 +345,6 @@ static int apci3120_setup_chan_list(struct comedi_device *dev,
us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */
outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
-
- printk("\n Gain = %i",
- (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
- printk("\n Channel = %i", CR_CHAN(chanlist[i]));
- printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
}
return 1; /* we can serve this with scan logic */
}
@@ -369,10 +365,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev,
unsigned char b_Tmp;
/* fix conversion time to 10 us */
- if (!devpriv->ui_EocEosConversionTime) {
- printk("No timer0 Value using 10 us\n");
+ if (!devpriv->ui_EocEosConversionTime)
us_ConvertTiming = 10;
- } else
+ else
us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */
/* this_board->ai_read(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */
@@ -593,7 +588,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev,
break;
default:
- printk("inputs wrong\n");
+ dev_err(dev->class_dev, "inputs wrong\n");
}
devpriv->ui_EocEosConversionTime = 0; /* re initializing the variable; */
@@ -1051,7 +1046,7 @@ static int apci3120_cyclic_ai(int mode,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_TimerValue2),
+ outw(ui_TimerValue2 & 0xffff,
dev->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1059,7 +1054,7 @@ static int apci3120_cyclic_ai(int mode,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_TimerValue2),
+ outw((ui_TimerValue2 >> 16) & 0xffff,
dev->iobase + APCI3120_TIMER_VALUE);
/* (2) Reset FC_TIMER BIT Clearing timer status register */
@@ -1373,10 +1368,10 @@ static void apci3120_interrupt_dma(int irq, void *d)
if (samplesinbuf <
devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
- comedi_error(dev, "Interrupted DMA transfer!");
+ dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
}
if (samplesinbuf & 1) {
- comedi_error(dev, "Odd count of bytes in DMA ring!");
+ dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
apci3120_cancel(dev, s);
return;
}
@@ -1548,7 +1543,7 @@ static void apci3120_interrupt(int irq, void *d)
int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* get AMCC int register */
if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
- comedi_error(dev, "IRQ from unknown source");
+ dev_err(dev->class_dev, "IRQ from unknown source\n");
return;
}
@@ -1565,9 +1560,9 @@ static void apci3120_interrupt(int irq, void *d)
inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER);
if (int_amcc & MASTER_ABORT_INT)
- comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
if (int_amcc & TARGET_ABORT_INT)
- comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
/* Ckeck if EOC interrupt */
if (((int_daq & 0x8) == 0)
@@ -1740,7 +1735,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
unsigned char b_Tmp;
if (!data[1])
- comedi_error(dev, "config:No timer constant !");
+ dev_err(dev->class_dev, "No timer constant!\n");
devpriv->b_Timer2Interrupt = (unsigned char) data[2]; /* save info whether to enable or disable interrupt */
@@ -1805,7 +1800,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1813,7 +1808,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* timer2 in Timer mode enabled */
devpriv->b_Timer2Mode = APCI3120_TIMER;
@@ -1841,7 +1836,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1850,7 +1845,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* watchdog enabled */
devpriv->b_Timer2Mode = APCI3120_WATCHDOG;
@@ -1886,14 +1881,14 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
- comedi_error(dev, "\nwrite:timer2 not configured ");
+ dev_err(dev->class_dev, "timer2 not configured\n");
return -EINVAL;
}
if (data[0] == 2) { /* write new value */
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
- comedi_error(dev,
- "write :timer2 not configured in TIMER MODE");
+ dev_err(dev->class_dev,
+ "timer2 not configured in TIMER MODE\n");
return -EINVAL;
}
@@ -1991,8 +1986,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
case 2: /* write new value to Timer */
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
- comedi_error(dev,
- "write :timer2 not configured in TIMER MODE");
+ dev_err(dev->class_dev,
+ "timer2 not configured in TIMER MODE\n");
return -EINVAL;
}
/* ui_Timervalue2=data[1]; // passed as argument */
@@ -2017,7 +2012,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -2026,7 +2021,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
break;
@@ -2056,7 +2051,7 @@ static int apci3120_read_insn_timer(struct comedi_device *dev,
if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
- comedi_error(dev, "\nread:timer2 not configured ");
+ dev_err(dev->class_dev, "timer2 not configured\n");
}
/* this_board->timer_read(dev,data); */
@@ -2161,10 +2156,6 @@ static int apci3120_ao_insn_write(struct comedi_device *dev,
}
-/*
- * out put n values at the given channel. printk("\nwaiting for
- * DA_READY BIT");
- */
do { /* Waiting of DA_READY BIT */
us_TmpValue =
((unsigned short) inw(devpriv->iobase +
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index f540394d17b0..5e321f91172f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -47,8 +47,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
+----------+-----------+------------------------------------------------+
*/
-/* #define PRINT_INFO */
-
/* Card Specific information */
/* #define APCI3200_ADDRESS_RANGE 264 */
@@ -455,12 +453,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
BoardInformations->s_Module[w_ModulCounter].
w_GainValue[w_GainIndex] = w_GainValue;
-# ifdef PRINT_INFO
- printk("\n Gain value = %d",
- BoardInformations->s_Module[w_ModulCounter].
- w_GainValue[w_GainIndex]);
-# endif
-
/*************************************/
/** Read gain factor for the module **/
/*************************************/
@@ -472,12 +464,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_GainFactor[w_GainIndex] =
(w_GainFactorValue[1] << 16) +
w_GainFactorValue[0];
-
-# ifdef PRINT_INFO
- printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
- BoardInformations->s_Module[w_ModulCounter].
- ul_GainFactor[w_GainIndex]);
-# endif
}
/***************************************************************/
@@ -499,12 +485,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_CurrentSource[w_Input] =
(w_CurrentSources[0] +
((w_CurrentSources[1] & 0xFFF) << 16));
-
-# ifdef PRINT_INFO
- printk("\n Current sources [%d] = %lu", w_Input,
- BoardInformations->s_Module[w_ModulCounter].
- ul_CurrentSource[w_Input]);
-# endif
}
/***************************************/
@@ -522,12 +502,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_CurrentSourceCJC =
(w_CurrentSources[0] +
((w_CurrentSources[1] & 0xFFF) << 16));
-
-# ifdef PRINT_INFO
- printk("\n Current sources CJC = %lu",
- BoardInformations->s_Module[w_ModulCounter].
- ul_CurrentSourceCJC);
-# endif
}
}
@@ -540,10 +514,6 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
int i_DiffChannel = 0;
int i_Module = 0;
-#ifdef PRINT_INFO
- printk("\n Channel = %u", ui_Channel_num);
-#endif
-
/* Test if single or differential mode */
if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
/* if diff */
@@ -580,16 +550,10 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
/* Test if thermocouple or RTD mode */
*CJCCurrentSource =
s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
-#ifdef PRINT_INFO
- printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
-#endif
*ChannelCurrentSource =
s_BoardInfos[dev->minor].s_Module[i_Module].
ul_CurrentSource[i_DiffChannel];
-#ifdef PRINT_INFO
- printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
-#endif
/* } */
/* } */
@@ -597,9 +561,6 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
*ChannelGainFactor =
s_BoardInfos[dev->minor].s_Module[i_Module].
ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
-#ifdef PRINT_INFO
- printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
-#endif
/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
return 0;
@@ -689,17 +650,11 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /************************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/* Enable the interrupt */
- /************************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/******************************/
/* Write the command register */
@@ -712,11 +667,8 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*************************/
/*Read the EOC Status bit */
@@ -738,7 +690,7 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
s_BoardInfos[dev->minor].i_Offset + 28);
/* END JK 06.07.04: Management of sevrals boards */
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -800,20 +752,11 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
-
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
-
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/**********************/
/*Start the conversion */
@@ -830,13 +773,8 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
-
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -856,7 +794,7 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -915,20 +853,11 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
-
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
-
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/**********************/
/*Start the conversion */
@@ -945,13 +874,8 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
-
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
@@ -973,7 +897,7 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1020,14 +944,9 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
/*Initialise dw_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
}
@@ -1047,12 +966,8 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
@@ -1073,8 +988,7 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
-
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1128,17 +1042,10 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
/*Initialise ui_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
}
/**********************/
@@ -1154,8 +1061,7 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
/* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -1172,7 +1078,7 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1224,14 +1130,9 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
/*Initialise dw_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
}
/**********************/
@@ -1247,8 +1148,7 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
/* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -1264,7 +1164,7 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1340,10 +1240,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
return -EINVAL;
} /* if(i_Initialised==0); */
-#ifdef PRINT_INFO
- printk("\n insn->unused[0] = %i", insn->unused[0]);
-#endif
-
switch (insn->unused[0]) {
case 0:
@@ -1368,15 +1264,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
&s_BoardInfos[dev->minor].
ui_InterruptChannelValue[s_BoardInfos[dev->minor].
i_Count + 8]);
-
-#ifdef PRINT_INFO
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
-#endif
-
/* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
/* BEGIN JK 06.07.04: Management of sevrals boards */
@@ -1532,9 +1419,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
data[4]= ui_InterruptChannelValue[4];
data[5]= ui_InterruptChannelValue[5];
*/
-#ifdef PRINT_INFO
- printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
-#endif
data[0] =
s_BoardInfos[dev->minor].
ui_InterruptChannelValue[0];
@@ -1555,7 +1439,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
ui_InterruptChannelValue[5];
/* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
i_APCI3200_GetChannelCalibrationValue(dev,
s_BoardInfos[dev->minor].ui_Channel_num,
&data[6], &data[7], &data[8]);
@@ -1637,13 +1520,6 @@ static int apci3200_ai_config(struct comedi_device *dev,
unsigned int ui_Dummy = 0;
int i_err = 0;
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-#ifdef PRINT_INFO
- int i = 0, i2 = 0;
-#endif
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* Initialize the structure */
if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
@@ -1669,29 +1545,6 @@ static int apci3200_ai_config(struct comedi_device *dev,
v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
&s_BoardInfos[dev->minor]);
-
-#ifdef PRINT_INFO
- for (i = 0; i < MAX_MODULE; i++) {
- printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
- s_BoardInfos[dev->minor].s_Module[i].
- ul_CurrentSourceCJC);
-
- for (i2 = 0; i2 < 5; i2++) {
- printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].w_GainValue [%i] = %u",
- i, i2,
- s_BoardInfos[dev->minor].s_Module[i].
- w_GainValue[i2]);
- }
- }
-#endif
/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
}
@@ -1811,34 +1664,34 @@ static int apci3200_ai_config(struct comedi_device *dev,
/* END JK 06.07.04: Management of sevrals boards */
if (data[5] == 0) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ if (ui_ChannelNo > 15) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */
+ } /* if(ui_ChannelNo>15) */
} /* if(data[5]==0) */
else {
if (data[14] == 2) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ if (ui_ChannelNo > 3) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */
+ } /* if(ui_ChannelNo>3) */
} /* if(data[14]==2) */
else {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ if (ui_ChannelNo > 7) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */
+ } /* if(ui_ChannelNo>7) */
} /* elseif(data[14]==2) */
} /* elseif(data[5]==0) */
if (data[12] == 0 || data[12] == 1) {
switch (data[5]) {
case 0:
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ if (ui_ChannelNo <= 3) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=0; */
s_BoardInfos[dev->minor].i_Offset = 0;
/* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
+ } /* if(ui_ChannelNo <=3) */
if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=64; */
@@ -1892,12 +1745,12 @@ static int apci3200_ai_config(struct comedi_device *dev,
ui_ChannelNo = 0;
break;
} /* if(data[14]==2) */
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ if (ui_ChannelNo <= 1) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=0; */
s_BoardInfos[dev->minor].i_Offset = 0;
/* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
+ } /* if(ui_ChannelNo <=1) */
if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_ChannelNo=i_ChannelNo-2; */
@@ -2136,8 +1989,7 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
i_ADDIDATAConversionTimeUnit= 1; */
/* i_Temp= i_InterruptFlag ; */
i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
- /* i_InterruptFlag = ADDIDATA_DISABLE; */
- s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
/* if(i_AutoCalibration == FALSE) */
if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
@@ -2176,8 +2028,7 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
i_ADDIDATAConversionTimeUnit= 1; */
/* i_Temp= i_InterruptFlag ; */
i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
- /* i_InterruptFlag = ADDIDATA_DISABLE; */
- s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
/* if(i_AutoCalibration == FALSE) */
if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
@@ -2198,7 +2049,6 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
}
/* i_InterruptFlag=i_Temp ; */
s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
- /* printk("\ni_InterruptFlag=%d\n",i_InterruptFlag); */
return insn->n;
}
@@ -2470,8 +2320,6 @@ static int apci3200_ai_cmd(struct comedi_device *dev,
ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
ui_DelayMode = 1;
} /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
- /* printk("\nui_DelayTime=%u\n",ui_DelayTime); */
- /* printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase); */
if (cmd->convert_src == TRIG_TIMER) {
ui_ConvertTime = cmd->convert_arg & 0xFFFF;
ui_ConvertTimeBase = cmd->convert_arg >> 16;
@@ -2499,13 +2347,6 @@ static int apci3200_ai_cmd(struct comedi_device *dev,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
/* } */
ui_Configuration = 0;
- /* printk("\nfirstchannel=%u\n",i_FirstChannel); */
- /* printk("\nlastchannel=%u\n",i_LastChannel); */
- /* printk("\nui_Trigger=%u\n",ui_Trigger); */
- /* printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge); */
- /* printk("\nui_Triggermode=%u\n",ui_Triggermode); */
- /* printk("\nui_DelayMode=%u\n",ui_DelayMode); */
- /* printk("\nui_ScanMode=%u\n",ui_ScanMode); */
/* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */
ui_Configuration =
@@ -2757,8 +2598,6 @@ static void apci3200_interrupt(int irq, void *d)
int i_ReturnValue = 0;
/* END JK TEST */
- /* printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType); */
-
/* switch(i_ScanType) */
switch (s_BoardInfos[dev->minor].i_ScanType) {
case 0:
@@ -2809,7 +2648,6 @@ static void apci3200_interrupt(int irq, void *d)
/* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
/*
- printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
&s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
&s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
index 4da9db35b8e2..af70c8401880 100644
--- a/drivers/staging/comedi/drivers/addi_apci_035.c
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -18,7 +18,7 @@ static const struct addi_board apci035_boardtypes[] = {
.pc_DriverName = "apci035",
.i_IorangeBase1 = APCI035_ADDRESS_RANGE,
.i_PCIEeprom = 1,
- .pc_EepromChip = ADDIDATA_S5920,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index eab75eb26478..b7a284ac6649 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -15,7 +15,7 @@ static const struct addi_board apci1500_boardtypes[] = {
{
.pc_DriverName = "apci1500",
.i_IorangeBase1 = APCI1500_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .i_PCIEeprom = 0,
.i_NbrDiChannel = 16,
.i_NbrDoChannel = 16,
.i_DoMaxdata = 0xffff,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 13d9962b47ec..543cb074213a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -1,17 +1,114 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include "../comedidev.h"
#include "comedi_fc.h"
-
-#include "addi-data/addi_common.h"
+#include "amcc_s5933.h"
+#include "addi_watchdog.h"
+
+struct apci1564_private {
+ unsigned int amcc_iobase; /* base of AMCC I/O registers */
+ unsigned int mode1; /* riding-edge/high level channels */
+ unsigned int mode2; /* falling-edge/low level channels */
+ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */
+ unsigned char timer_select_mode;
+ unsigned char mode_select_register;
+ struct task_struct *tsk_current;
+};
#include "addi-data/hwdrv_apci1564.c"
-static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+static int apci1564_reset(struct comedi_device *dev)
{
- apci1564_interrupt(irq, d);
- return IRQ_RETVAL(1);
+ struct apci1564_private *devpriv = dev->private;
+
+ /* Disable the input interrupts and reset status register */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+
+ /* Reset the output channels and disable interrupts */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
+
+ /* Reset the watchdog registers */
+ addi_watchdog_reset(devpriv->amcc_iobase + APCI1564_WDOG_REG);
+
+ /* Reset the timer registers */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
+
+ /* Reset the counter registers */
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+
+ return 0;
+}
+
+static irqreturn_t apci1564_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct apci1564_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ unsigned int status;
+ unsigned int ctrl;
+ unsigned int chan;
+
+ /* check interrupt is from this device */
+ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
+ INTCSR_INTR_ASSERTED) == 0)
+ return IRQ_NONE;
+
+ status = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ if (status & APCI1564_DI_INT_ENABLE) {
+ /* disable the interrupt */
+ outl(status & APCI1564_DI_INT_DISABLE,
+ devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+
+ s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG)
+ & 0xffff;
+ comedi_buf_put(s, s->state);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+
+ /* enable the interrupt */
+ outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ }
+
+ status = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG);
+ if (status & 0x01) {
+ /* Disable Timer Interrupt */
+ ctrl = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Timer Interrupt */
+ outl(ctrl, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ }
+
+ for (chan = 0; chan < 4; chan++) {
+ status = inl(dev->iobase + APCI1564_TCW_IRQ_REG(chan));
+ if (status & 0x01) {
+ /* Disable Counter Interrupt */
+ ctrl = inl(dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ctrl, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+ }
+ }
+
+ return IRQ_HANDLED;
}
static int apci1564_di_insn_bits(struct comedi_device *dev,
@@ -19,9 +116,9 @@ static int apci1564_di_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DI_REG);
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_DI_REG);
return insn->n;
}
@@ -31,46 +128,214 @@ static int apci1564_do_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DO_REG);
+ s->state = inl(devpriv->amcc_iobase + APCI1564_DO_REG);
if (comedi_dio_update_state(s, data))
- outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
+ outl(s->state, devpriv->amcc_iobase + APCI1564_DO_REG);
data[1] = s->state;
return insn->n;
}
-static int apci1564_reset(struct comedi_device *dev)
+static int apci1564_diag_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- ui_Type = 0;
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_DO_INT_STATUS_REG) & 3;
- /* Disable the input interrupts and reset status register */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
+ return insn->n;
+}
- /* Reset the output channels and disable interrupts */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
+/*
+ * Change-Of-State (COS) interrupt configuration
+ *
+ * Channels 0 to 15 are interruptible. These channels can be configured
+ * to generate interrupts based on AND/OR logic for the desired channels.
+ *
+ * OR logic
+ * - reacts to rising or falling edges
+ * - interrupt is generated when any enabled channel
+ * meet the desired interrupt condition
+ *
+ * AND logic
+ * - reacts to changes in level of the selected inputs
+ * - interrupt is generated when all enabled channels
+ * meet the desired interrupt condition
+ * - after an interrupt, a change in level must occur on
+ * the selected inputs to release the IRQ logic
+ *
+ * The COS interrupt must be configured before it can be enabled.
+ *
+ * data[0] : INSN_CONFIG_DIGITAL_TRIG
+ * data[1] : trigger number (= 0)
+ * data[2] : configuration operation:
+ * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
+ * data[3] : left-shift for data[4] and data[5]
+ * data[4] : rising-edge/high level channels
+ * data[5] : falling-edge/low level channels
+ */
+static int apci1564_cos_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1564_private *devpriv = dev->private;
+ unsigned int shift, oldmask;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIGITAL_TRIG:
+ if (data[1] != 0)
+ return -EINVAL;
+ shift = data[3];
+ oldmask = (1U << shift) - 1;
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ devpriv->ctrl = 0;
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_OR)) {
+ /* switching to 'OR' mode */
+ devpriv->ctrl = APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_OR;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
+ if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_AND)) {
+ /* switching to 'AND' mode */
+ devpriv->ctrl = APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_AND;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return insn->n;
+}
- /* Reset the watchdog registers */
- addi_watchdog_reset(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
+static int apci1564_cos_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = s->state;
- /* Reset the timer registers */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
+ return 0;
+}
- /* Reset the counter registers */
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+static int apci1564_cos_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ int err = 0;
+
+ /* Step 1 : check if triggers are trivially valid */
+
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+ if (err)
+ return 1;
+
+ /* Step 2a : make sure trigger sources are unique */
+ /* Step 2b : and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
+ * Change-Of-State (COS) 'do_cmd' operation
+ *
+ * Enable the COS interrupt as configured by apci1564_cos_insn_config().
+ */
+static int apci1564_cos_cmd(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct apci1564_private *devpriv = dev->private;
+
+ if (!devpriv->ctrl) {
+ dev_warn(dev->class_dev,
+ "Interrupts disabled due to mode configuration!\n");
+ return -EINVAL;
+ }
+
+ outl(devpriv->mode1, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(devpriv->mode2, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+ outl(devpriv->ctrl, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+
+ return 0;
+}
+
+static int apci1564_cos_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct apci1564_private *devpriv = dev->private;
+
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
return 0;
}
@@ -79,12 +344,10 @@ static int apci1564_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct addi_private *devpriv;
+ struct apci1564_private *devpriv;
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
@@ -94,18 +357,18 @@ static int apci1564_auto_attach(struct comedi_device *dev,
return ret;
dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+ devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
apci1564_reset(dev);
if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = pcidev->irq;
}
- ret = comedi_alloc_subdevices(dev, 3);
+ ret = comedi_alloc_subdevices(dev, 6);
if (ret)
return ret;
@@ -115,9 +378,7 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->subdev_flags = SDF_READABLE;
s->n_chan = 32;
s->maxdata = 1;
- s->len_chanlist = 32;
s->range_table = &range_digital;
- s->insn_config = apci1564_di_config;
s->insn_bits = apci1564_di_insn_bits;
/* Allocate and Initialise DO Subdevice Structures */
@@ -125,15 +386,32 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 32;
- s->maxdata = 0xffffffff;
- s->len_chanlist = 32;
+ s->maxdata = 1;
s->range_table = &range_digital;
s->insn_config = apci1564_do_config;
s->insn_bits = apci1564_do_insn_bits;
- s->insn_read = apci1564_do_read;
- /* Allocate and Initialise Timer Subdevice Structures */
+ /* Change-Of-State (COS) interrupt subdevice */
s = &dev->subdevices[2];
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->len_chanlist = 1;
+ s->insn_config = apci1564_cos_insn_config;
+ s->insn_bits = apci1564_cos_insn_bits;
+ s->do_cmdtest = apci1564_cos_cmdtest;
+ s->do_cmd = apci1564_cos_cmd;
+ s->cancel = apci1564_cos_cancel;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Allocate and Initialise Timer Subdevice Structures */
+ s = &dev->subdevices[3];
s->type = COMEDI_SUBD_TIMER;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 1;
@@ -144,19 +422,30 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->insn_read = apci1564_timer_read;
s->insn_config = apci1564_timer_config;
+ /* Initialize the watchdog subdevice */
+ s = &dev->subdevices[4];
+ ret = addi_watchdog_init(s, devpriv->amcc_iobase + APCI1564_WDOG_REG);
+ if (ret)
+ return ret;
+
+ /* Initialize the diagnostic status subdevice */
+ s = &dev->subdevices[5];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 2;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci1564_diag_insn_bits;
+
return 0;
}
static void apci1564_detach(struct comedi_device *dev)
{
- struct addi_private *devpriv = dev->private;
-
- if (devpriv) {
- if (dev->iobase)
- apci1564_reset(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- }
+ if (dev->iobase)
+ apci1564_reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 0cfb12fa1cbc..0b77f1012d47 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -88,7 +88,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
dev->irq = pcidev->irq;
}
- devpriv->us_UseDma = ADDI_ENABLE;
+ devpriv->us_UseDma = 1;
/* Allocate DMA buffers */
devpriv->b_DmaDoubleBuffer = 0;
@@ -109,7 +109,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
}
}
if (!devpriv->ul_DmaBufferVirtual[0])
- devpriv->us_UseDma = ADDI_DISABLE;
+ devpriv->us_UseDma = 0;
if (devpriv->ul_DmaBufferVirtual[1])
devpriv->b_DmaDoubleBuffer = 1;
@@ -125,13 +125,10 @@ static int apci3120_auto_attach(struct comedi_device *dev,
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND
| SDF_DIFF;
- if (this_board->i_NbrAiChannel) {
+ if (this_board->i_NbrAiChannel)
s->n_chan = this_board->i_NbrAiChannel;
- devpriv->b_SingelDiff = 0;
- } else {
+ else
s->n_chan = this_board->i_NbrAiChannelDiff;
- devpriv->b_SingelDiff = 1;
- }
s->maxdata = this_board->i_AiMaxdata;
s->len_chanlist = this_board->i_AiChannelList;
s->range_table = &range_apci3120_ai;
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
index f0f891a482a3..fe6897eff3db 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -32,8 +32,8 @@ static const struct addi_board apci3200_boardtypes[] = {
[BOARD_APCI3200] = {
.pc_DriverName = "apci3200",
.i_IorangeBase1 = 256,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
+ .i_PCIEeprom = 1,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
@@ -58,8 +58,8 @@ static const struct addi_board apci3200_boardtypes[] = {
[BOARD_APCI3300] = {
.pc_DriverName = "apci3300",
.i_IorangeBase1 = 256,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
+ .i_PCIEeprom = 1,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 8,
.i_AiMaxdata = 0x3ffff,
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index 49bf1fb840f6..d9594f48d00f 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -274,7 +274,7 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
ui_Timer_AOWatchdog = inl(dev->iobase + APCI3501_TIMER_IRQ_REG) & 0x1;
if ((!ui_Timer_AOWatchdog)) {
- comedi_error(dev, "IRQ from unknown source");
+ dev_err(dev->class_dev, "IRQ from unknown source\n");
return IRQ_NONE;
}
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index 0532b6cc40e3..0f0c7fa5daa3 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -353,7 +353,6 @@ static const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
};
struct apci3xxx_private {
- void __iomem *mmio;
unsigned int ai_timer;
unsigned char ai_time_base;
};
@@ -361,18 +360,17 @@ struct apci3xxx_private {
static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
{
struct comedi_device *dev = d;
- struct apci3xxx_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
unsigned int val;
/* Test if interrupt occur */
- status = readl(devpriv->mmio + 16);
+ status = readl(dev->mmio + 16);
if ((status & 0x2) == 0x2) {
/* Reset the interrupt */
- writel(status, devpriv->mmio + 16);
+ writel(status, dev->mmio + 16);
- val = readl(devpriv->mmio + 28);
+ val = readl(dev->mmio + 28);
comedi_buf_put(s, val);
s->async->events |= COMEDI_CB_EOA;
@@ -385,18 +383,14 @@ static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
static int apci3xxx_ai_started(struct comedi_device *dev)
{
- struct apci3xxx_private *devpriv = dev->private;
-
- if ((readl(devpriv->mmio + 8) & 0x80000) == 0x80000)
+ if ((readl(dev->mmio + 8) & 0x80000) == 0x80000)
return 1;
- else
- return 0;
+ return 0;
}
static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(chanspec);
unsigned int range = CR_RANGE(chanspec);
unsigned int aref = CR_AREF(chanspec);
@@ -407,29 +401,29 @@ static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
return -EBUSY;
/* Clear the FIFO */
- writel(0x10000, devpriv->mmio + 12);
+ writel(0x10000, dev->mmio + 12);
/* Get and save the delay mode */
- delay_mode = readl(devpriv->mmio + 4);
+ delay_mode = readl(dev->mmio + 4);
delay_mode &= 0xfffffef0;
/* Channel configuration selection */
- writel(delay_mode, devpriv->mmio + 4);
+ writel(delay_mode, dev->mmio + 4);
/* Make the configuration */
val = (range & 3) | ((range >> 2) << 6) |
((aref == AREF_DIFF) << 7);
- writel(val, devpriv->mmio + 0);
+ writel(val, dev->mmio + 0);
/* Channel selection */
- writel(delay_mode | 0x100, devpriv->mmio + 4);
- writel(chan, devpriv->mmio + 0);
+ writel(delay_mode | 0x100, dev->mmio + 4);
+ writel(chan, dev->mmio + 0);
/* Restore delay mode */
- writel(delay_mode, devpriv->mmio + 4);
+ writel(delay_mode, dev->mmio + 4);
/* Set the number of sequence to 1 */
- writel(1, devpriv->mmio + 48);
+ writel(1, dev->mmio + 48);
return 0;
}
@@ -439,10 +433,9 @@ static int apci3xxx_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + 20);
+ status = readl(dev->mmio + 20);
if (status & 0x1)
return 0;
return -EBUSY;
@@ -453,7 +446,6 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct apci3xxx_private *devpriv = dev->private;
int ret;
int i;
@@ -463,7 +455,7 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* Start the conversion */
- writel(0x80000, devpriv->mmio + 8);
+ writel(0x80000, dev->mmio + 8);
/* Wait the EOS */
ret = comedi_timeout(dev, s, insn, apci3xxx_ai_eoc, 0);
@@ -471,14 +463,14 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
return ret;
/* Read the analog value */
- data[i] = readl(devpriv->mmio + 28);
+ data[i] = readl(dev->mmio + 28);
}
return insn->n;
}
static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
- unsigned int *ns, int round_mode)
+ unsigned int *ns, unsigned int flags)
{
const struct apci3xxx_boardinfo *board = comedi_board(dev);
struct apci3xxx_private *devpriv = dev->private;
@@ -504,7 +496,7 @@ static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
break;
}
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
timer = (*ns + base / 2) / base;
@@ -574,7 +566,7 @@ static int apci3xxx_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->convert_arg;
- err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags & TRIG_ROUND_MASK);
+ err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (err)
@@ -595,13 +587,13 @@ static int apci3xxx_ai_cmd(struct comedi_device *dev,
return ret;
/* Set the convert timing unit */
- writel(devpriv->ai_time_base, devpriv->mmio + 36);
+ writel(devpriv->ai_time_base, dev->mmio + 36);
/* Set the convert timing */
- writel(devpriv->ai_timer, devpriv->mmio + 32);
+ writel(devpriv->ai_timer, dev->mmio + 32);
/* Start the conversion */
- writel(0x180000, devpriv->mmio + 8);
+ writel(0x180000, dev->mmio + 8);
return 0;
}
@@ -617,10 +609,9 @@ static int apci3xxx_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + 96);
+ status = readl(dev->mmio + 96);
if (status & 0x100)
return 0;
return -EBUSY;
@@ -631,7 +622,6 @@ static int apci3xxx_ao_insn_write(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int range = CR_RANGE(insn->chanspec);
int ret;
@@ -639,10 +629,10 @@ static int apci3xxx_ao_insn_write(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* Set the range selection */
- writel(range, devpriv->mmio + 96);
+ writel(range, dev->mmio + 96);
/* Write the analog value to the selected channel */
- writel((data[i] << 8) | chan, devpriv->mmio + 100);
+ writel((data[i] << 8) | chan, dev->mmio + 100);
/* Wait the end of transfer */
ret = comedi_timeout(dev, s, insn, apci3xxx_ao_eoc, 0);
@@ -696,10 +686,9 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev,
/* ignore all other instructions for ports 0 and 1 */
if (chan < 16)
return -EINVAL;
- else
- /* changing any channel in port 2 */
- /* changes the entire port */
- mask = 0xff0000;
+
+ /* changing any channel in port 2 changes the entire port */
+ mask = 0xff0000;
}
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
@@ -742,7 +731,6 @@ static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
static int apci3xxx_reset(struct comedi_device *dev)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int val;
int i;
@@ -750,18 +738,18 @@ static int apci3xxx_reset(struct comedi_device *dev)
disable_irq(dev->irq);
/* Clear the start command */
- writel(0, devpriv->mmio + 8);
+ writel(0, dev->mmio + 8);
/* Reset the interrupt flags */
- val = readl(devpriv->mmio + 16);
- writel(val, devpriv->mmio + 16);
+ val = readl(dev->mmio + 16);
+ writel(val, dev->mmio + 16);
/* clear the EOS */
- readl(devpriv->mmio + 20);
+ readl(dev->mmio + 20);
/* Clear the FIFO */
for (i = 0; i < 16; i++)
- val = readl(devpriv->mmio + 28);
+ val = readl(dev->mmio + 28);
/* Enable the interrupt */
enable_irq(dev->irq);
@@ -796,7 +784,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev,
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
- devpriv->mmio = pci_ioremap_bar(pcidev, 3);
+ dev->mmio = pci_ioremap_bar(pcidev, 3);
if (pcidev->irq > 0) {
ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
@@ -920,8 +908,8 @@ static void apci3xxx_detach(struct comedi_device *dev)
apci3xxx_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
}
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 584fd57ecb70..51edfebb952a 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -75,9 +75,6 @@ TODO:
#include "plx9052.h"
#include "comedi_fc.h"
-#define PCI9111_DRIVER_NAME "adl_pci9111"
-#define PCI9111_HR_DEVICE_ID 0x9111
-
#define PCI9111_FIFO_HALF_SIZE 512
#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000
@@ -189,68 +186,6 @@ static void pci9111_timer_set(struct comedi_device *dev)
i8254_write(timer_base, 1, 1, dev_private->div1);
}
-enum pci9111_trigger_sources {
- software,
- timer_pacer,
- external
-};
-
-static void pci9111_trigger_source_set(struct comedi_device *dev,
- enum pci9111_trigger_sources source)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the EITS and TPST bits */
- flags &= 0x9;
-
- switch (source) {
- case software:
- break;
-
- case timer_pacer:
- flags |= PCI9111_AI_TRIG_CTRL_TPST;
- break;
-
- case external:
- flags |= PCI9111_AI_TRIG_CTRL_ETIS;
- break;
- }
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
-static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the PTRG bit */
- flags &= 0x7;
-
- if (pretrigger)
- flags |= PCI9111_AI_TRIG_CTRL_PTRG;
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
-static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the ASCAN bit */
- flags &= 0xe;
-
- if (autoscan)
- flags |= PCI9111_AI_TRIG_CTRL_ASCAN;
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
enum pci9111_ISC0_sources {
irq_on_eoc,
irq_on_fifo_half_full
@@ -303,9 +238,8 @@ static int pci9111_ai_cancel(struct comedi_device *dev,
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
- pci9111_trigger_source_set(dev, software);
-
- pci9111_autoscan_set(dev, false);
+ /* disable A/D triggers (software trigger mode) and auto scan off */
+ outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
pci9111_fifo_reset(dev);
@@ -454,20 +388,17 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
{
struct pci9111_private_data *dev_private = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ unsigned int trig = 0;
/* Set channel scan limit */
/* PCI9111 allows only scanning from channel 0 to channel n */
/* TODO: handle the case of an external multiplexer */
- if (cmd->chanlist_len > 1) {
- outb(cmd->chanlist_len - 1,
- dev->iobase + PCI9111_AI_CHANNEL_REG);
- pci9111_autoscan_set(dev, true);
- } else {
- outb(CR_CHAN(cmd->chanlist[0]),
- dev->iobase + PCI9111_AI_CHANNEL_REG);
- pci9111_autoscan_set(dev, false);
- }
+ if (cmd->chanlist_len > 1)
+ trig |= PCI9111_AI_TRIG_CTRL_ASCAN;
+
+ outb(last_chan, dev->iobase + PCI9111_AI_CHANNEL_REG);
/* Set gain */
/* This is the same gain on every channel */
@@ -484,12 +415,11 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
/* Set timer pacer */
dev_private->scan_delay = 0;
if (cmd->convert_src == TRIG_TIMER) {
- pci9111_trigger_source_set(dev, software);
+ trig |= PCI9111_AI_TRIG_CTRL_TPST;
pci9111_timer_set(dev);
pci9111_fifo_reset(dev);
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
irq_on_timer_tick);
- pci9111_trigger_source_set(dev, timer_pacer);
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
false, true, true);
@@ -498,14 +428,14 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
(cmd->convert_arg * cmd->chanlist_len)) - 1;
}
} else { /* TRIG_EXT */
- pci9111_trigger_source_set(dev, external);
+ trig |= PCI9111_AI_TRIG_CTRL_ETIS;
pci9111_fifo_reset(dev);
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
irq_on_timer_tick);
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
false, true, true);
-
}
+ outb(trig, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
dev_private->stop_counter *= (1 + dev_private->scan_delay);
dev_private->chunk_counter = 0;
@@ -630,7 +560,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
/* '0' means FIFO is full, data may have been lost */
if (!(status & PCI9111_AI_STAT_FF_FF)) {
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
+ dev_dbg(dev->class_dev, "fifo overflow\n");
outb(0, dev->iobase + PCI9111_INT_CLR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
@@ -771,9 +701,8 @@ static int pci9111_reset(struct comedi_device *dev)
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
- pci9111_trigger_source_set(dev, software);
- pci9111_pretrigger_set(dev, false);
- pci9111_autoscan_set(dev, false);
+ /* disable A/D triggers (software trigger mode) and auto scan off */
+ outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
/* Reset 8254 chip */
dev_private->div1 = 0;
@@ -884,7 +813,7 @@ static int pci9111_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id pci9111_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x9111) },
/* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
{ 0 }
};
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 59a65cbc6db9..f30b84e1987b 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -7,61 +7,62 @@
*
* Author: Michal Dobes <dobes@tesnet.cz>
*
-*/
+ */
+
/*
-Driver: adl_pci9118
-Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
- PCI-9118HR (pci9118hr)
-Status: works
-
-This driver supports AI, AO, DI and DO subdevices.
-AI subdevice supports cmd and insn interface,
-other subdevices support only insn interface.
-For AI:
-- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
-- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
-- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
-- It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
- cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
-- If return value of cmdtest is 5 then you've bad channel list
- (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
- ranges).
-
-There are some hardware limitations:
-a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
- ended inputs.
-b) DMA transfers must have the length aligned to two samples (32 bit),
- so there is some problems if cmd->chanlist_len is odd. This driver tries
- bypass this with adding one sample to the end of the every scan and discard
- it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
- and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
- with interrupt after every sample.
-c) If isn't used DMA then you can use only mode where
- cmd->scan_begin_src=TRIG_FOLLOW.
-
-Configuration options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, then first available PCI
- card will be used.
- [2] - 0= standard 8 DIFF/16 SE channels configuration
- n = external multiplexer connected, 1 <= n <= 256
- [3] - 0=autoselect DMA or EOC interrupts operation
- 1 = disable DMA mode
- 3 = disable DMA and INT, only insn interface will work
- [4] - sample&hold signal - card can generate signal for external S&H board
- 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
- 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
- long delay is requested in ns and sign polarity of the hold
- (in this case external multiplexor can serve only 128 channels)
- [5] - 0=stop measure on all hardware errors
- 2 | = ignore ADOR - A/D Overrun status
- 8|=ignore Bover - A/D Burst Mode Overrun status
- 256|=ignore nFull - A/D FIFO Full status
-
-*/
+ * Driver: adl_pci9118
+ * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
+ * PCI-9118HR (pci9118hr)
+ * Status: works
+ *
+ * This driver supports AI, AO, DI and DO subdevices.
+ * AI subdevice supports cmd and insn interface,
+ * other subdevices support only insn interface.
+ * For AI:
+ * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
+ * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
+ * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
+ * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
+ * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
+ * - If return value of cmdtest is 5 then you've bad channel list
+ * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
+ * ranges).
+ *
+ * There are some hardware limitations:
+ * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
+ * ended inputs.
+ * b) DMA transfers must have the length aligned to two samples (32 bit),
+ * so there is some problems if cmd->chanlist_len is odd. This driver tries
+ * bypass this with adding one sample to the end of the every scan and discard
+ * it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
+ * and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
+ * with interrupt after every sample.
+ * c) If isn't used DMA then you can use only mode where
+ * cmd->scan_begin_src=TRIG_FOLLOW.
+ *
+ * Configuration options:
+ * [0] - PCI bus of device (optional)
+ * [1] - PCI slot of device (optional)
+ * If bus/slot is not specified, then first available PCI
+ * card will be used.
+ * [2] - 0= standard 8 DIFF/16 SE channels configuration
+ * n = external multiplexer connected, 1 <= n <= 256
+ * [3] - 0=autoselect DMA or EOC interrupts operation
+ * 1 = disable DMA mode
+ * 3 = disable DMA and INT, only insn interface will work
+ * [4] - sample&hold signal - card can generate signal for external S&H board
+ * 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
+ * 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
+ * long delay is requested in ns and sign polarity of the hold
+ * (in this case external multiplexor can serve only 128 channels)
+ * [5] - 0=stop measure on all hardware errors
+ * 2 | = ignore ADOR - A/D Overrun status
+ * 8|=ignore Bover - A/D Burst Mode Overrun status
+ * 256|=ignore nFull - A/D FIFO Full status
+ *
+ */
/*
* FIXME
@@ -346,7 +347,7 @@ struct pci9118_private {
* on external start
*/
unsigned short ao_data[2]; /* data output buffer */
- char dma_doublebuf; /* we can use double buffering */
+ char dma_doublebuf; /* use double buffering */
unsigned int dma_actbuf; /* which buffer is used now */
unsigned short *dmabuf_virt[2]; /*
* pointers to begin of
@@ -394,12 +395,12 @@ static int check_channel_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
if ((frontadd + n_chan + backadd) > s->len_chanlist) {
- comedi_error(dev,
- "range/channel list is too long for actual configuration!\n");
+ dev_err(dev->class_dev,
+ "range/channel list is too long for actual configuration!\n");
return 0;
}
@@ -411,23 +412,20 @@ static int check_channel_list(struct comedi_device *dev,
for (i = 1; i < n_chan; i++) { /* check S.E/diff */
if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
(differencial)) {
- comedi_error(dev,
- "Differencial and single ended "
- "inputs can't be mixtured!");
+ dev_err(dev->class_dev,
+ "Differential and single ended inputs can't be mixed!\n");
return 0;
}
if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
(bipolar)) {
- comedi_error(dev,
- "Bipolar and unipolar ranges "
- "can't be mixtured!");
+ dev_err(dev->class_dev,
+ "Bipolar and unipolar ranges can't be mixed!\n");
return 0;
}
if (!devpriv->usemux && differencial &&
(CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
- comedi_error(dev,
- "If AREF_DIFF is used then is "
- "available only first 8 channels!");
+ dev_err(dev->class_dev,
+ "AREF_DIFF is only available for the first 8 channels!\n");
return 0;
}
}
@@ -864,20 +862,21 @@ static char pci9118_decode_error_status(struct comedi_device *dev,
struct pci9118_private *devpriv = dev->private;
if (m & 0x100) {
- comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
+ dev_err(dev->class_dev,
+ "A/D FIFO Full status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x100L;
}
if (m & 0x008) {
- comedi_error(dev,
- "A/D Burst Mode Overrun Status (Fatal Error!)");
+ dev_err(dev->class_dev,
+ "A/D Burst Mode Overrun Status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x008L;
}
if (m & 0x004) {
- comedi_error(dev, "A/D Over Speed Status (Warning!)");
+ dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
devpriv->ai_maskerr &= ~0x004L;
}
if (m & 0x002) {
- comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
+ dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x002L;
}
if (m & devpriv->ai_maskharderr) {
@@ -966,14 +965,14 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
unsigned int next_dma_buf, samplesinbuf, sampls, m;
if (int_amcc & MASTER_ABORT_INT) {
- comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
}
if (int_amcc & TARGET_ABORT_INT) {
- comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
@@ -1427,17 +1426,16 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
devpriv->AdControlReg |= AdControl_TmrTr;
break;
case 2:
- comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
+ dev_err(dev->class_dev, "%s mode 2 bug!\n", __func__);
return -EIO;
case 3:
devpriv->AdControlReg |= AdControl_ExtM;
break;
case 4:
- comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
+ dev_err(dev->class_dev, "%s mode 4 bug!\n", __func__);
return -EIO;
default:
- comedi_error(dev,
- "pci9118_ai_docmd_sampl() mode number bug!\n");
+ dev_err(dev->class_dev, "%s mode number bug!\n", __func__);
return -EIO;
}
@@ -1509,7 +1507,7 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev,
devpriv->AdFunctionReg |= AdFunction_Start;
break;
default:
- comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
+ dev_err(dev->class_dev, "%s mode number bug!\n", __func__);
return -EIO;
}
@@ -1677,9 +1675,8 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
(cmd->convert_src == TRIG_NOW))) {
/* double timed action */
if (!devpriv->usedma) {
- comedi_error(dev,
- "cmd->scan_begin_src=TRIG_TIMER works "
- "only with bus mastering!");
+ dev_err(dev->class_dev,
+ "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index b4ea37704eaf..8b15cbec9891 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -79,20 +79,20 @@ If you do not specify any options, they will default to
#include "../comedidev.h"
/* address scheme (page 2.17 of the manual) */
-#define ADQ12B_SIZE 16
-
-#define ADQ12B_CTREG 0x00
-#define ADQ12B_STINR 0x00
-#define ADQ12B_OUTBR 0x04
-#define ADQ12B_ADLOW 0x08
-#define ADQ12B_ADHIG 0x09
-#define ADQ12B_CONT0 0x0c
-#define ADQ12B_CONT1 0x0d
-#define ADQ12B_CONT2 0x0e
-#define ADQ12B_COWORD 0x0f
-
-/* mask of the bit at STINR to check end of conversion */
-#define ADQ12B_EOC 0x20
+#define ADQ12B_CTREG 0x00
+#define ADQ12B_CTREG_MSKP (1 << 7) /* enable pacer interrupt */
+#define ADQ12B_CTREG_GTP (1 << 6) /* enable pacer */
+#define ADQ12B_CTREG_RANGE(x) ((x) << 4)
+#define ADQ12B_CTREG_CHAN(x) ((x) << 0)
+#define ADQ12B_STINR 0x00
+#define ADQ12B_STINR_OUT2 (1 << 7) /* timer 2 output state */
+#define ADQ12B_STINR_OUTP (1 << 6) /* pacer output state */
+#define ADQ12B_STINR_EOC (1 << 5) /* A/D end-of-conversion */
+#define ADQ12B_STINR_IN_MASK (0x1f << 0)
+#define ADQ12B_OUTBR 0x04
+#define ADQ12B_ADLOW 0x08
+#define ADQ12B_ADHIG 0x09
+#define ADQ12B_TIMER_BASE 0x0c
/* available ranges through the PGA gains */
static const struct comedi_lrange range_adq12b_ai_bipolar = {
@@ -114,10 +114,7 @@ static const struct comedi_lrange range_adq12b_ai_unipolar = {
};
struct adq12b_private {
- int unipolar; /* option 2 of comedi_config (1 is iobase) */
- int differential; /* option 3 of comedi_config */
- int last_channel;
- int last_range;
+ unsigned int last_ctreg;
};
static int adq12b_ai_eoc(struct comedi_device *dev,
@@ -128,50 +125,45 @@ static int adq12b_ai_eoc(struct comedi_device *dev,
unsigned char status;
status = inb(dev->iobase + ADQ12B_STINR);
- if (status & ADQ12B_EOC)
+ if (status & ADQ12B_STINR_EOC)
return 0;
return -EBUSY;
}
-static int adq12b_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
+static int adq12b_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct adq12b_private *devpriv = dev->private;
- int n;
- int range, channel;
- unsigned char hi, lo, status;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int val;
int ret;
+ int i;
/* change channel and range only if it is different from the previous */
- range = CR_RANGE(insn->chanspec);
- channel = CR_CHAN(insn->chanspec);
- if (channel != devpriv->last_channel || range != devpriv->last_range) {
- outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
+ val = ADQ12B_CTREG_RANGE(range) | ADQ12B_CTREG_CHAN(chan);
+ if (val != devpriv->last_ctreg) {
+ outb(val, dev->iobase + ADQ12B_CTREG);
+ devpriv->last_ctreg = val;
udelay(50); /* wait for the mux to settle */
}
- /* trigger conversion */
- status = inb(dev->iobase + ADQ12B_ADLOW);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
+ val = inb(dev->iobase + ADQ12B_ADLOW); /* trigger A/D */
- /* wait for end of conversion */
+ for (i = 0; i < insn->n; i++) {
ret = comedi_timeout(dev, s, insn, adq12b_ai_eoc, 0);
if (ret)
return ret;
- /* read data */
- hi = inb(dev->iobase + ADQ12B_ADHIG);
- lo = inb(dev->iobase + ADQ12B_ADLOW);
-
- data[n] = (hi << 8) | lo;
+ val = inb(dev->iobase + ADQ12B_ADHIG) << 8;
+ val |= inb(dev->iobase + ADQ12B_ADLOW); /* retriggers A/D */
+ data[i] = val;
}
- /* return the number of samples read/written */
- return n;
+ return insn->n;
}
static int adq12b_di_insn_bits(struct comedi_device *dev,
@@ -180,7 +172,7 @@ static int adq12b_di_insn_bits(struct comedi_device *dev,
{
/* only bits 0-4 have information about digital inputs */
- data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f));
+ data[1] = (inb(dev->iobase + ADQ12B_STINR) & ADQ12B_STINR_IN_MASK);
return insn->n;
}
@@ -216,7 +208,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], ADQ12B_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
@@ -224,58 +216,44 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- devpriv->unipolar = it->options[1];
- devpriv->differential = it->options[2];
- /*
- * initialize channel and range to -1 so we make sure we
- * always write at least once to the CTREG in the instruction
- */
- devpriv->last_channel = -1;
- devpriv->last_range = -1;
+ devpriv->last_ctreg = -1; /* force ctreg update */
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
return ret;
+ /* Analog Input subdevice */
s = &dev->subdevices[0];
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- if (devpriv->differential) {
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 8;
+ s->type = COMEDI_SUBD_AI;
+ if (it->options[2]) {
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ s->n_chan = 8;
} else {
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 16;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 16;
}
+ s->maxdata = 0xfff;
+ s->range_table = it->options[1] ? &range_adq12b_ai_unipolar
+ : &range_adq12b_ai_bipolar;
+ s->insn_read = adq12b_ai_insn_read;
- if (devpriv->unipolar)
- s->range_table = &range_adq12b_ai_unipolar;
- else
- s->range_table = &range_adq12b_ai_bipolar;
-
- s->maxdata = 0xfff;
-
- s->len_chanlist = 4; /* This is the maximum chanlist length that
- the board can handle */
- s->insn_read = adq12b_ai_rinsn;
-
+ /* Digital Input subdevice */
s = &dev->subdevices[1];
- /* digital input subdevice */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 5;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_di_insn_bits;
-
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 5;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_di_insn_bits;
+
+ /* Digital Output subdevice */
s = &dev->subdevices[2];
- /* digital output subdevice */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_do_insn_bits;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_do_insn_bits;
return 0;
}
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 602b7a1e40e6..e19ab958791b 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -722,8 +722,8 @@ static int pci171x_ai_cancel(struct comedi_device *dev,
default:
devpriv->CntrlReg &= Control_CNT0;
devpriv->CntrlReg |= Control_SW;
-
- outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
+ /* reset any operations */
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
pci171x_start_pacer(dev, false);
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
@@ -1049,15 +1049,18 @@ static int pci171x_reset(struct comedi_device *dev)
struct pci1710_private *devpriv = dev->private;
outw(0x30, dev->iobase + PCI171x_CNTCTRL);
- devpriv->CntrlReg = Control_SW | Control_CNT0; /* Software trigger, CNT0=external */
- outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
+ /* Software trigger, CNT0=external */
+ devpriv->CntrlReg = Control_SW | Control_CNT0;
+ /* reset any operations */
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */
outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */
pci171x_start_pacer(dev, false);
devpriv->da_ranges = 0;
if (this_board->n_aochan) {
- outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); /* set DACs to 0..5V */
- outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
+ /* set DACs to 0..5V */
+ outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
devpriv->ao_data[0] = 0x0000;
if (this_board->n_aochan > 1) {
outw(0, dev->iobase + PCI171x_DA2);
@@ -1077,10 +1080,11 @@ static int pci171x_reset(struct comedi_device *dev)
static int pci1720_reset(struct comedi_device *dev)
{
struct pci1710_private *devpriv = dev->private;
-
- outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); /* set synchronous output mode */
+ /* set synchronous output mode */
+ outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT);
devpriv->da_ranges = 0xAA;
- outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); /* set all ranges to +/-5V */
+ /* set all ranges to +/-5V */
+ outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE);
outw(0x0800, dev->iobase + PCI1720_DA0); /* set outputs to 0V */
outw(0x0800, dev->iobase + PCI1720_DA1);
outw(0x0800, dev->iobase + PCI1720_DA2);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index 07b107d1ab33..1881df459dae 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -161,11 +161,10 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev,
struct comedi_insn *insn, unsigned int *data)
{
struct pci1723_private *devpriv = dev->private;
- int n, chan;
- chan = CR_CHAN(insn->chanspec);
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int n;
for (n = 0; n < insn->n; n++) {
-
devpriv->ao_data[chan] = data[n];
outw(data[n], dev->iobase + PCI1723_DA(chan));
}
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
index af670acb03d8..bc3c34916768 100644
--- a/drivers/staging/comedi/drivers/adv_pci1724.c
+++ b/drivers/staging/comedi/drivers/adv_pci1724.c
@@ -143,7 +143,8 @@ static int wait_for_dac_idle(struct comedi_device *dev)
udelay(1);
}
if (i == timeout) {
- comedi_error(dev, "Timed out waiting for dac to become idle.");
+ dev_err(dev->class_dev,
+ "Timed out waiting for dac to become idle\n");
return -EIO;
}
return 0;
@@ -195,8 +196,8 @@ static int ao_readback_insn(struct comedi_device *dev,
int i;
if (devpriv->ao_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
@@ -236,8 +237,8 @@ static int offset_read_insn(struct comedi_device *dev,
int i;
if (devpriv->offset_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
@@ -277,8 +278,8 @@ static int gain_read_insn(struct comedi_device *dev,
int i;
if (devpriv->gain_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 2d966a87f2e8..b8c7d9145a54 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -592,7 +592,7 @@ static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
return 0;
}
- comedi_error(dev, "PCI-1760 mailbox request timeout!");
+ dev_err(dev->class_dev, "PCI-1760 mailbox request timeout!\n");
return -ETIME;
}
@@ -610,12 +610,13 @@ static int pci1760_mbxrequest(struct comedi_device *dev,
unsigned char *omb, unsigned char *imb)
{
if (omb[2] == CMD_ClearIMB2) {
- comedi_error(dev,
- "bug! this function should not be used for CMD_ClearIMB2 command");
+ dev_err(dev->class_dev,
+ "bug! this function should not be used for CMD_ClearIMB2 command\n");
return -EINVAL;
}
if (inb(dev->iobase + IMB2) == omb[2]) {
int retval;
+
retval = pci1760_clear_imb2(dev);
if (retval < 0)
return retval;
@@ -826,7 +827,7 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0, dev->iobase + PCI1730_DO + 1);
outb(0, dev->iobase + PCI1730_IDO);
outb(0, dev->iobase + PCI1730_IDO + 1);
- /* NO break there! */
+ /* fallthrough */
case TYPE_PCI1733:
/* disable interrupts */
outb(0, dev->iobase + PCI1730_3_INT_EN);
@@ -886,7 +887,7 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0x80, dev->iobase + PCI1753E_ICR1);
outb(0x80, dev->iobase + PCI1753E_ICR2);
outb(0x80, dev->iobase + PCI1753E_ICR3);
- /* NO break there! */
+ /* fallthrough */
case TYPE_PCI1753:
outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
* interrupts */
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 781104aa533e..7b5ed439c164 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -33,7 +33,6 @@ Configuration Options:
#include <linux/module.h>
#include "../comedidev.h"
-#define AIO_IIRO_16_SIZE 0x08
#define AIO_IIRO_16_RELAY_0_7 0x00
#define AIO_IIRO_16_INPUT_0_7 0x01
#define AIO_IIRO_16_IRQ 0x02
@@ -74,7 +73,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], AIO_IIRO_16_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
index 2ba736444610..cf6a497b092c 100644
--- a/drivers/staging/comedi/drivers/amcc_s5933.h
+++ b/drivers/staging/comedi/drivers/amcc_s5933.h
@@ -41,7 +41,7 @@
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
#define AMCC_FIFO_DEPTH_DWORD 8
-#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
/****************************************************************************/
/* AMCC - PCI Interrupt Control/Status Register */
@@ -52,8 +52,10 @@
#define INTCSR_INBOX_BYTE(x) (((x) & 0x3) << 8)
#define INTCSR_INBOX_SELECT(x) (((x) & 0x3) << 10)
#define INTCSR_INBOX_FULL_INT 0x1000 /* enable inbox full interrupt */
-#define INTCSR_INBOX_INTR_STATUS 0x20000 /* read, or write clear inbox full interrupt */
-#define INTCSR_INTR_ASSERTED 0x800000 /* read only, interrupt asserted */
+/* read, or write clear inbox full interrupt */
+#define INTCSR_INBOX_INTR_STATUS 0x20000
+/* read only, interrupt asserted */
+#define INTCSR_INTR_ASSERTED 0x800000
/****************************************************************************/
/* AMCC - PCI non-volatile ram command register (byte 3 of master control/status register) */
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index dc1dee79fc16..17d2e20663cb 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -278,8 +278,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = comedi_request_region(dev, it->options[0], thisboard->mainsize);
if (ret)
return ret;
- devpriv->io.u.iobase = dev->iobase;
- devpriv->io.regtype = io_regtype;
+
return amplc_dio200_common_attach(dev, irq, 0);
}
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h
index 43160b9944bb..e0afe2cee2d6 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.h
+++ b/drivers/staging/comedi/drivers/amplc_dio200.h
@@ -28,18 +28,6 @@
#define DIO200_PCIE_IO_SIZE 0x4000
/*
- * Register region.
- */
-enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype };
-struct dio200_region {
- union {
- unsigned long iobase; /* I/O base address */
- unsigned char __iomem *membase; /* mapped MMIO base address */
- } u;
- enum dio200_regtype regtype;
-};
-
-/*
* Subdevice types.
*/
enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
@@ -75,7 +63,6 @@ struct dio200_board {
* Comedi device private data.
*/
struct dio200_private {
- struct dio200_region io; /* Register region */
int intr_sd;
};
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c
index 3edaa4028da2..f0d709e0dafc 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200_common.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c
@@ -151,13 +151,12 @@ static unsigned char dio200_read8(struct comedi_device *dev,
unsigned int offset)
{
const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- return inb(devpriv->io.u.iobase + offset);
- else
- return readb(devpriv->io.u.membase + offset);
+
+ if (dev->mmio)
+ return readb(dev->mmio + offset);
+ return inb(dev->iobase + offset);
}
/*
@@ -167,13 +166,13 @@ static void dio200_write8(struct comedi_device *dev, unsigned int offset,
unsigned char val)
{
const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- outb(val, devpriv->io.u.iobase + offset);
+
+ if (dev->mmio)
+ writeb(val, dev->mmio + offset);
else
- writeb(val, devpriv->io.u.membase + offset);
+ outb(val, dev->iobase + offset);
}
/*
@@ -183,13 +182,12 @@ static unsigned int dio200_read32(struct comedi_device *dev,
unsigned int offset)
{
const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- return inl(devpriv->io.u.iobase + offset);
- else
- return readl(devpriv->io.u.membase + offset);
+
+ if (dev->mmio)
+ return readl(dev->mmio + offset);
+ return inl(dev->iobase + offset);
}
/*
@@ -199,13 +197,13 @@ static void dio200_write32(struct comedi_device *dev, unsigned int offset,
unsigned int val)
{
const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- outl(val, devpriv->io.u.iobase + offset);
+
+ if (dev->mmio)
+ writel(val, dev->mmio + offset);
else
- writel(val, devpriv->io.u.membase + offset);
+ outl(val, dev->iobase + offset);
}
/*
@@ -327,7 +325,7 @@ static void dio200_read_scan_intr(struct comedi_device *dev,
/* Error! Stop acquisition. */
dio200_stop_intr(dev, s);
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- comedi_error(dev, "buffer overflow");
+ dev_err(dev->class_dev, "buffer overflow\n");
}
/* Check for end of acquisition. */
@@ -1197,13 +1195,10 @@ EXPORT_SYMBOL_GPL(amplc_dio200_common_attach);
void amplc_dio200_common_detach(struct comedi_device *dev)
{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- if (!thisboard || !devpriv)
- return;
- if (dev->irq)
+ if (dev->irq) {
free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
}
EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
index e0367380b37a..fbf05687347f 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
@@ -228,13 +228,6 @@
#include "amplc_dio200.h"
-/* PCI IDs */
-#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
-#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
-#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
-#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
-#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
-
/*
* Board descriptions.
*/
@@ -394,16 +387,14 @@ static int dio200_pci_auto_attach(struct comedi_device *dev,
return -EINVAL;
}
if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) {
- devpriv->io.u.membase = pci_ioremap_bar(pci_dev, bar);
- if (!devpriv->io.u.membase) {
+ dev->mmio = pci_ioremap_bar(pci_dev, bar);
+ if (!dev->mmio) {
dev_err(dev->class_dev,
"error! cannot remap registers\n");
return -ENOMEM;
}
- devpriv->io.regtype = mmio_regtype;
} else {
- devpriv->io.u.iobase = pci_resource_start(pci_dev, bar);
- devpriv->io.regtype = io_regtype;
+ dev->iobase = pci_resource_start(pci_dev, bar);
}
switch (context_model) {
case pcie215_model:
@@ -421,14 +412,9 @@ static int dio200_pci_auto_attach(struct comedi_device *dev,
static void dio200_pci_detach(struct comedi_device *dev)
{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- if (!thisboard || !devpriv)
- return;
amplc_dio200_common_detach(dev);
- if (devpriv->io.regtype == mmio_regtype)
- iounmap(devpriv->io.u.membase);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -440,22 +426,11 @@ static struct comedi_driver dio200_pci_comedi_driver = {
};
static const struct pci_device_id dio200_pci_table[] = {
- {
- PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215),
- pci215_model
- }, {
- PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272),
- pci272_model
- }, {
- PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236),
- pcie236_model
- }, {
- PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215),
- pcie215_model
- }, {
- PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296),
- pcie296_model
- },
+ { PCI_VDEVICE(AMPLICON, 0x000b), pci215_model },
+ { PCI_VDEVICE(AMPLICON, 0x000a), pci272_model },
+ { PCI_VDEVICE(AMPLICON, 0x0011), pcie236_model },
+ { PCI_VDEVICE(AMPLICON, 0x0012), pcie215_model },
+ { PCI_VDEVICE(AMPLICON, 0x0014), pcie296_model },
{0}
};
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index c9a96ad00559..875cc19cb969 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -1,444 +1,53 @@
/*
- comedi/drivers/amplc_pc236.c
- Driver for Amplicon PC36AT and PCI236 DIO boards.
-
- Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
- 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.
-*/
-/*
-Driver: amplc_pc236
-Description: Amplicon PC36AT, PCI236
-Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
-Updated: Wed, 01 Apr 2009 15:41:25 +0100
-Status: works
-
-Configuration options - PC36AT:
- [0] - I/O port base address
- [1] - IRQ (optional)
-
-Configuration options - PCI236:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, the first available PCI device will be
- used.
-
-The PC36AT ISA board and PCI236 PCI board have a single 8255 appearing
-as subdevice 0.
-
-Subdevice 1 pretends to be a digital input device, but it always returns
-0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
-a rising edge on port C bit 3 acts as an external trigger, which can be
-used to wake up tasks. This is like the comedi_parport device, but the
-only way to physically disable the interrupt on the PC36AT is to remove
-the IRQ jumper. If no interrupt is connected, then subdevice 1 is
-unused.
-*/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_fc.h"
-#include "8255.h"
-#include "plx9052.h"
-
-#define PC236_DRIVER_NAME "amplc_pc236"
-
-#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA)
-#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
-
-/* PCI236 PCI configuration register information */
-#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
-#define PCI_DEVICE_ID_INVALID 0xffff
-
-/* PC36AT / PCI236 registers */
-
-#define PC236_IO_SIZE 4
-#define PC236_LCR_IO_SIZE 128
-
-/* Disable, and clear, interrupts */
-#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1POL | \
- PLX9052_INTCSR_LI2POL | \
- PLX9052_INTCSR_LI1SEL | \
- PLX9052_INTCSR_LI1CLRINT)
-
-/* Enable, and clear, interrupts */
-#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB | \
- PLX9052_INTCSR_LI1POL | \
- PLX9052_INTCSR_LI2POL | \
- PLX9052_INTCSR_PCIENAB | \
- PLX9052_INTCSR_LI1SEL | \
- PLX9052_INTCSR_LI1CLRINT)
-
-/*
- * Board descriptions for Amplicon PC36AT and PCI236.
- */
-
-enum pc236_bustype { isa_bustype, pci_bustype };
-enum pc236_model { pc36at_model, pci236_model, anypci_model };
-
-struct pc236_board {
- const char *name;
- unsigned short devid;
- enum pc236_bustype bustype;
- enum pc236_model model;
-};
-static const struct pc236_board pc236_boards[] = {
-#if DO_ISA
- {
- .name = "pc36at",
- .bustype = isa_bustype,
- .model = pc36at_model,
- },
-#endif
-#if DO_PCI
- {
- .name = "pci236",
- .devid = PCI_DEVICE_ID_AMPLICON_PCI236,
- .bustype = pci_bustype,
- .model = pci236_model,
- },
- {
- .name = PC236_DRIVER_NAME,
- .devid = PCI_DEVICE_ID_INVALID,
- .bustype = pci_bustype,
- .model = anypci_model, /* wildcard */
- },
-#endif
-};
-
-/* this structure is for data unique to this hardware driver. If
- several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the struct comedi_device struct.
- */
-struct pc236_private {
- unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
- int enable_irq;
-};
-
-/* test if ISA supported and this is an ISA board */
-static inline bool is_isa_board(const struct pc236_board *board)
-{
- return DO_ISA && board->bustype == isa_bustype;
-}
-
-/* test if PCI supported and this is a PCI board */
-static inline bool is_pci_board(const struct pc236_board *board)
-{
- return DO_PCI && board->bustype == pci_bustype;
-}
-
-/*
- * This function looks for a board matching the supplied PCI device.
- */
-static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pc236_boards); i++)
- if (is_pci_board(&pc236_boards[i]) &&
- pci_dev->device == pc236_boards[i].devid)
- return &pc236_boards[i];
- return NULL;
-}
-
-/*
- * This function looks for a PCI device matching the requested board name,
- * bus and slot.
- */
-static struct pci_dev *pc236_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pci_dev *pci_dev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
-
- for_each_pci_dev(pci_dev) {
- if (bus || slot) {
- if (bus != pci_dev->bus->number ||
- slot != PCI_SLOT(pci_dev->devfn))
- continue;
- }
- if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
- continue;
-
- if (thisboard->model == anypci_model) {
- /* Wildcard board matches any supported PCI board. */
- const struct pc236_board *foundboard;
-
- foundboard = pc236_find_pci_board(pci_dev);
- if (foundboard == NULL)
- continue;
- /* Replace wildcard board_ptr. */
- dev->board_ptr = foundboard;
- } else {
- /* Match specific model name. */
- if (pci_dev->device != thisboard->devid)
- continue;
- }
- return pci_dev;
- }
- dev_err(dev->class_dev,
- "No supported board found! (req. bus %d, slot %d)\n",
- bus, slot);
- return NULL;
-}
-
-/*
- * This function is called to mark the interrupt as disabled (no command
- * configured on subdevice 1) and to physically disable the interrupt
- * (not possible on the PC36AT, except by removing the IRQ jumper!).
+ * comedi/drivers/amplc_pc236.c
+ * Driver for Amplicon PC36AT DIO boards.
+ *
+ * Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
*/
-static void pc236_intr_disable(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pc236_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->enable_irq = 0;
- if (is_pci_board(thisboard))
- outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
/*
- * This function is called to mark the interrupt as enabled (a command
- * configured on subdevice 1) and to physically enable the interrupt
- * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!).
+ * Driver: amplc_pc236
+ * Description: Amplicon PC36AT
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PC36AT (pc36at)
+ * Updated: Fri, 25 Jul 2014 15:32:40 +0000
+ * Status: works
+ *
+ * Configuration options - PC36AT:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional)
+ *
+ * The PC36AT board has a single 8255 appearing as subdevice 0.
+ *
+ * Subdevice 1 pretends to be a digital input device, but it always returns
+ * 0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
+ * a rising edge on port C bit 3 acts as an external trigger, which can be
+ * used to wake up tasks. This is like the comedi_parport device, but the
+ * only way to physically disable the interrupt on the PC36AT is to remove
+ * the IRQ jumper. If no interrupt is connected, then subdevice 1 is
+ * unused.
*/
-static void pc236_intr_enable(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pc236_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->enable_irq = 1;
- if (is_pci_board(thisboard))
- outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-/*
- * This function is called when an interrupt occurs to check whether
- * the interrupt has been marked as enabled and was generated by the
- * board. If so, the function prepares the hardware for the next
- * interrupt.
- * Returns 0 if the interrupt should be ignored.
- */
-static int pc236_intr_check(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pc236_private *devpriv = dev->private;
- int retval = 0;
- unsigned long flags;
- unsigned int intcsr;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- if (devpriv->enable_irq) {
- retval = 1;
- if (is_pci_board(thisboard)) {
- intcsr = inl(devpriv->lcr_iobase + PLX9052_INTCSR);
- if (!(intcsr & PLX9052_INTCSR_LI1STAT)) {
- retval = 0;
- } else {
- /* Clear interrupt and keep it enabled. */
- outl(PCI236_INTR_ENABLE,
- devpriv->lcr_iobase + PLX9052_INTCSR);
- }
- }
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return retval;
-}
-
-/*
- * Input from subdevice 1.
- * Copied from the comedi_parport driver.
- */
-static int pc236_intr_insn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-/*
- * Subdevice 1 command test.
- * Copied from the comedi_parport driver.
- */
-static int pc236_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
- err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check it arguments are trivially valid */
-
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
- err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: ignored */
-
- if (err)
- return 4;
-
- return 0;
-}
-
-/*
- * Subdevice 1 command.
- */
-static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- pc236_intr_enable(dev);
-
- return 0;
-}
-
-/*
- * Subdevice 1 cancel command.
- */
-static int pc236_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pc236_intr_disable(dev);
-
- return 0;
-}
-
-/*
- * Interrupt service routine.
- * Based on the comedi_parport driver.
- */
-static irqreturn_t pc236_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- int handled;
-
- handled = pc236_intr_check(dev);
- if (dev->attached && handled) {
- comedi_buf_put(s, 0);
- s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- comedi_event(dev, s);
- }
- return IRQ_RETVAL(handled);
-}
-
-static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned long req_irq_flags)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct comedi_subdevice *s;
- int ret;
-
- dev->board_name = thisboard->name;
- dev->iobase = iobase;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* digital i/o subdevice (8255) */
- ret = subdev_8255_init(dev, s, NULL, iobase);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_UNUSED;
- pc236_intr_disable(dev);
- if (irq) {
- if (request_irq(irq, pc236_interrupt, req_irq_flags,
- PC236_DRIVER_NAME, dev) >= 0) {
- dev->irq = irq;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pc236_intr_insn;
- s->len_chanlist = 1;
- s->do_cmdtest = pc236_intr_cmdtest;
- s->do_cmd = pc236_intr_cmd;
- s->cancel = pc236_intr_cancel;
- }
- }
-
- return 0;
-}
-
-static int pc236_pci_common_attach(struct comedi_device *dev,
- struct pci_dev *pci_dev)
-{
- struct pc236_private *devpriv = dev->private;
- unsigned long iobase;
- int ret;
-
- comedi_set_hw_dev(dev, &pci_dev->dev);
+#include <linux/module.h>
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
+#include "../comedidev.h"
- devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
- iobase = pci_resource_start(pci_dev, 2);
- return pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED);
-}
+#include "amplc_pc236.h"
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board. If you specified a board_name array
- * in the driver structure, dev->board_ptr contains that
- * address.
- */
static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct pc236_board *thisboard = comedi_board(dev);
struct pc236_private *devpriv;
int ret;
@@ -446,127 +55,31 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- /* Process options according to bus type. */
- if (is_isa_board(thisboard)) {
- ret = comedi_request_region(dev, it->options[0], PC236_IO_SIZE);
- if (ret)
- return ret;
-
- return pc236_common_attach(dev, dev->iobase, it->options[1], 0);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pci_dev;
-
- pci_dev = pc236_find_pci_dev(dev, it);
- if (!pci_dev)
- return -EIO;
- return pc236_pci_common_attach(dev, pci_dev);
- } else {
- dev_err(dev->class_dev, PC236_DRIVER_NAME
- ": BUG! cannot determine board type!\n");
- return -EINVAL;
- }
-}
-
-/*
- * The auto_attach hook is called at PCI probe time via
- * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
- * There should be a board entry matching the supplied PCI device.
- */
-static int pc236_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- struct pc236_private *devpriv;
-
- if (!DO_PCI)
- return -EINVAL;
-
- dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ ret = comedi_request_region(dev, it->options[0], 0x4);
+ if (ret)
+ return ret;
- dev->board_ptr = pc236_find_pci_board(pci_dev);
- if (dev->board_ptr == NULL) {
- dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
- return -EINVAL;
- }
- /*
- * Need to 'get' the PCI device to match the 'put' in pc236_detach().
- * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
- * support for manual attachment of PCI devices via pc236_attach()
- * has been removed.
- */
- pci_dev_get(pci_dev);
- return pc236_pci_common_attach(dev, pci_dev);
+ return amplc_pc236_common_attach(dev, dev->iobase, it->options[1], 0);
}
-static void pc236_detach(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
-
- if (!thisboard)
- return;
- if (dev->iobase)
- pc236_intr_disable(dev);
- if (is_isa_board(thisboard)) {
- comedi_legacy_detach(dev);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- comedi_pci_disable(dev);
- if (pcidev)
- pci_dev_put(pcidev);
- }
-}
+static const struct pc236_board pc236_boards[] = {
+ {
+ .name = "pc36at",
+ },
+};
-/*
- * The struct comedi_driver structure tells the Comedi core module
- * which functions to call to configure/deconfigure (attach/detach)
- * the board, and also about the kernel module that contains
- * the device code.
- */
static struct comedi_driver amplc_pc236_driver = {
- .driver_name = PC236_DRIVER_NAME,
+ .driver_name = "amplc_pc236",
.module = THIS_MODULE,
.attach = pc236_attach,
- .auto_attach = pc236_auto_attach,
- .detach = pc236_detach,
+ .detach = comedi_legacy_detach,
.board_name = &pc236_boards[0].name,
.offset = sizeof(struct pc236_board),
.num_names = ARRAY_SIZE(pc236_boards),
};
-#if DO_PCI
-static const struct pci_device_id pc236_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) },
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, pc236_pci_table);
-
-static int amplc_pc236_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pc236_driver,
- id->driver_data);
-}
-
-static struct pci_driver amplc_pc236_pci_driver = {
- .name = PC236_DRIVER_NAME,
- .id_table = pc236_pci_table,
- .probe = &amplc_pc236_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-
-module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver);
-#else
module_comedi_driver(amplc_pc236_driver);
-#endif
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PC36AT DIO boards");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.h b/drivers/staging/comedi/drivers/amplc_pc236.h
new file mode 100644
index 000000000000..91d6d9c065b5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236.h
@@ -0,0 +1,42 @@
+/*
+ * comedi/drivers/amplc_pc236.h
+ * Header for "amplc_pc236", "amplc_pci236" and "amplc_pc236_common".
+ *
+ * Copyright (C) 2002-2014 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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 AMPLC_PC236_H_INCLUDED
+#define AMPLC_PC236_H_INCLUDED
+
+#include <linux/types.h>
+
+struct comedi_device;
+
+struct pc236_board {
+ const char *name;
+ void (*intr_update_cb)(struct comedi_device *dev, bool enable);
+ bool (*intr_chk_clr_cb)(struct comedi_device *dev);
+};
+
+struct pc236_private {
+ unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
+ bool enable_irq;
+};
+
+int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
+ unsigned int irq, unsigned long req_irq_flags);
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c
new file mode 100644
index 000000000000..18e237cca419
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c
@@ -0,0 +1,206 @@
+/*
+ * comedi/drivers/amplc_pc236_common.c
+ * Common support code for "amplc_pc236" and "amplc_pci236".
+ *
+ * Copyright (C) 2002-2014 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+
+#include "../comedidev.h"
+
+#include "amplc_pc236.h"
+#include "comedi_fc.h"
+#include "8255.h"
+
+static void pc236_intr_update(struct comedi_device *dev, bool enable)
+{
+ const struct pc236_board *thisboard = comedi_board(dev);
+ struct pc236_private *devpriv = dev->private;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = enable;
+ if (thisboard->intr_update_cb)
+ thisboard->intr_update_cb(dev, enable);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called when an interrupt occurs to check whether
+ * the interrupt has been marked as enabled and was generated by the
+ * board. If so, the function prepares the hardware for the next
+ * interrupt.
+ * Returns false if the interrupt should be ignored.
+ */
+static bool pc236_intr_check(struct comedi_device *dev)
+{
+ const struct pc236_board *thisboard = comedi_board(dev);
+ struct pc236_private *devpriv = dev->private;
+ bool retval = false;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->spinlock, flags);
+ if (devpriv->enable_irq) {
+ if (thisboard->intr_chk_clr_cb)
+ retval = thisboard->intr_chk_clr_cb(dev);
+ else
+ retval = true;
+ }
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return retval;
+}
+
+static int pc236_intr_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = 0;
+ return insn->n;
+}
+
+static int pc236_intr_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
+{
+ int err = 0;
+
+ /* Step 1 : check if triggers are trivially valid */
+
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+ if (err)
+ return 1;
+
+ /* Step 2a : make sure trigger sources are unique */
+ /* Step 2b : and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* Step 3: check it arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ pc236_intr_update(dev, true);
+
+ return 0;
+}
+
+static int pc236_intr_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ pc236_intr_update(dev, false);
+
+ return 0;
+}
+
+static irqreturn_t pc236_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ bool handled;
+
+ handled = pc236_intr_check(dev);
+ if (dev->attached && handled) {
+ comedi_buf_put(s, 0);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ return IRQ_RETVAL(handled);
+}
+
+int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
+ unsigned int irq, unsigned long req_irq_flags)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ dev->iobase = iobase;
+
+ ret = comedi_alloc_subdevices(dev, 2);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[0];
+ /* digital i/o subdevice (8255) */
+ ret = subdev_8255_init(dev, s, NULL, iobase);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[1];
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_UNUSED;
+ pc236_intr_update(dev, false);
+ if (irq) {
+ if (request_irq(irq, pc236_interrupt, req_irq_flags,
+ dev->board_name, dev) >= 0) {
+ dev->irq = irq;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc236_intr_insn;
+ s->len_chanlist = 1;
+ s->do_cmdtest = pc236_intr_cmdtest;
+ s->do_cmd = pc236_intr_cmd;
+ s->cancel = pc236_intr_cancel;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amplc_pc236_common_attach);
+
+static int __init amplc_pc236_common_init(void)
+{
+ return 0;
+}
+module_init(amplc_pc236_common_init);
+
+static void __exit amplc_pc236_common_exit(void)
+{
+}
+module_exit(amplc_pc236_common_exit);
+
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi helper for amplc_pc236 and amplc_pci236");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 7c10d28d2784..f8e551d8fd9e 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -36,10 +36,7 @@ The state of the outputs can be read.
#include <linux/module.h>
#include "../comedidev.h"
-#define PC263_DRIVER_NAME "amplc_pc263"
-
/* PC263 registers */
-#define PC263_IO_SIZE 2
/*
* Board descriptions for Amplicon PC263.
@@ -75,7 +72,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], PC263_IO_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
@@ -98,7 +95,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
static struct comedi_driver amplc_pc263_driver = {
- .driver_name = PC263_DRIVER_NAME,
+ .driver_name = "amplc_pc263",
.module = THIS_MODULE,
.attach = pc263_attach,
.detach = comedi_legacy_detach,
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index 339c47c1eb97..45aba1f950fc 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -108,8 +108,6 @@ Caveats:
#include "comedi_fc.h"
#include "8253.h"
-#define DRIVER_NAME "amplc_pci224"
-
/*
* PCI IDs.
*/
@@ -120,7 +118,6 @@ Caveats:
/*
* PCI224/234 i/o space 1 (PCIBAR2) registers.
*/
-#define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
#define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
#define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
#define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
@@ -133,7 +130,6 @@ Caveats:
/*
* PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
*/
-#define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
@@ -354,7 +350,7 @@ static const struct pci224_board pci224_boards[] = {
.ao_bits = 16,
},
{
- .name = DRIVER_NAME,
+ .name = "amplc_pci224",
.devid = PCI_DEVICE_ID_INVALID,
.model = any_model, /* wildcard */
},
@@ -1206,8 +1202,8 @@ static int pci224_attach_common(struct comedi_device *dev,
if (options) {
for (n = 2; n < 3 + s->n_chan; n++) {
if (options[n] < 0 || options[n] > 1) {
- dev_warn(dev->class_dev, DRIVER_NAME
- ": warning! bad options[%u]=%d\n",
+ dev_warn(dev->class_dev,
+ "warning! bad options[%u]=%d\n",
n, options[n]);
}
}
@@ -1237,8 +1233,8 @@ static int pci224_attach_common(struct comedi_device *dev,
devpriv->hwrange = hwrange_pci224_external;
} else {
if (options && options[2] != 0) {
- dev_warn(dev->class_dev, DRIVER_NAME
- ": warning! bad options[2]=%d\n",
+ dev_warn(dev->class_dev,
+ "warning! bad options[2]=%d\n",
options[2]);
}
s->range_table = &range_pci224_internal;
@@ -1250,14 +1246,13 @@ static int pci224_attach_common(struct comedi_device *dev,
if (irq) {
ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
- DRIVER_NAME, dev);
+ dev->board_name, dev);
if (ret < 0) {
dev_err(dev->class_dev,
"error! unable to allocate irq %u\n", irq);
return ret;
- } else {
- dev->irq = irq;
}
+ dev->irq = irq;
}
return 0;
@@ -1268,7 +1263,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pci224_private *devpriv;
struct pci_dev *pci_dev;
- dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
+ dev_info(dev->class_dev, "attach\n");
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
@@ -1287,8 +1282,7 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
struct pci224_private *devpriv;
- dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
+ dev_info(dev->class_dev, "attach pci %s\n", pci_name(pci_dev));
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
@@ -1297,7 +1291,7 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
dev->board_ptr = pci224_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev,
- DRIVER_NAME ": BUG! cannot determine board type!\n");
+ "BUG! cannot determine board type!\n");
return -EINVAL;
}
/*
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 3895bc7cb3e3..684275d76e8c 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -1,188 +1,189 @@
- /*
- comedi/drivers/amplc_pci230.c
- Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
-
- Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
- 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.
+/*
+ * comedi/drivers/amplc_pci230.c
+ * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
+ *
+ * Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
- 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.
- */
/*
-Driver: amplc_pci230
-Description: Amplicon PCI230, PCI260 Multifunction I/O boards
-Author: Allan Willcox <allanwillcox@ozemail.com.au>,
- Steve D Sharples <steve.sharples@nottingham.ac.uk>,
- Ian Abbott <abbotti@mev.co.uk>
-Updated: Wed, 22 Oct 2008 12:34:49 +0100
-Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
- PCI230+ (pci230+ or amplc_pci230),
- PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
-Status: works
-
-Configuration options:
- [0] - PCI bus of device (optional).
- [1] - PCI slot of device (optional).
- If bus/slot is not specified, the first available PCI device
- will be used.
-
-Configuring a "amplc_pci230" will match any supported card and it will
-choose the best match, picking the "+" models if possible. Configuring
-a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
-a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
-and it will be treated as a PCI260. Configuring a "pci230+" will match
-a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
-
-Subdevices:
-
- PCI230(+) PCI260(+)
- --------- ---------
- Subdevices 3 1
- 0 AI AI
- 1 AO
- 2 DIO
-
-AI Subdevice:
-
- The AI subdevice has 16 single-ended channels or 8 differential
- channels.
-
- The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
- PCI260+ cards have 16-bit resolution.
-
- For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
- inputs 14 and 15 for channel 7). If the card is physically a PCI230
- or PCI260 then it actually uses a "pseudo-differential" mode where the
- inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
- use true differential sampling. Another difference is that if the
- card is physically a PCI230 or PCI260, the inverting input is 2N,
- whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
- PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
- PCI260+) and differential mode is used, the differential inputs need
- to be physically swapped on the connector.
-
- The following input ranges are supported:
-
- 0 => [-10, +10] V
- 1 => [-5, +5] V
- 2 => [-2.5, +2.5] V
- 3 => [-1.25, +1.25] V
- 4 => [0, 10] V
- 5 => [0, 5] V
- 6 => [0, 2.5] V
-
-AI Commands:
-
- +=========+==============+===========+============+==========+
- |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- +=========+==============+===========+============+==========+
- |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
- |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
- | | |TRIG_INT | | |
- | |--------------|-----------| | |
- | | TRIG_TIMER(1)|TRIG_TIMER | | |
- | | TRIG_EXT(2) | | | |
- | | TRIG_INT | | | |
- +---------+--------------+-----------+------------+----------+
-
- Note 1: If AI command and AO command are used simultaneously, only
- one may have scan_begin_src == TRIG_TIMER.
-
- Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
- DIO channel 16 (pin 49) which will need to be configured as
- a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
- (pin 17) is used instead. For PCI230, scan_begin_src ==
- TRIG_EXT is not supported. The trigger is a rising edge
- on the input.
-
- Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
- (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
- convert_arg value is interpreted as follows:
-
- convert_arg == (CR_EDGE | 0) => rising edge
- convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
- convert_arg == 0 => falling edge (backwards compatibility)
- convert_arg == 1 => rising edge (backwards compatibility)
-
- All entries in the channel list must use the same analogue reference.
- If the analogue reference is not AREF_DIFF (not differential) each
- pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
- input range. The input ranges used in the sequence must be all
- bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
- sequence must consist of 1 or more identical subsequences. Within the
- subsequence, channels must be in ascending order with no repeated
- channels. For example, the following sequences are valid: 0 1 2 3
- (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
- subsequence), 1 1 1 1 (repeated valid subsequence). The following
- sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
- (incompletely repeated subsequence). Some versions of the PCI230+ and
- PCI260+ have a bug that requires a subsequence longer than one entry
- long to include channel 0.
-
-AO Subdevice:
-
- The AO subdevice has 2 channels with 12-bit resolution.
-
- The following output ranges are supported:
-
- 0 => [0, 10] V
- 1 => [-10, +10] V
-
-AO Commands:
-
- +=========+==============+===========+============+==========+
- |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- +=========+==============+===========+============+==========+
- |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
- | | TRIG_EXT(2) | | |TRIG_COUNT|
- | | TRIG_INT | | | |
- +---------+--------------+-----------+------------+----------+
-
- Note 1: If AI command and AO command are used simultaneously, only
- one may have scan_begin_src == TRIG_TIMER.
-
- Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
- configured as a PCI230+ and is only supported on later
- versions of the card. As a card configured as a PCI230+ is
- not guaranteed to support external triggering, please consider
- this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
- input (PCI230+ pin 25). Triggering will be on the rising edge
- unless the CR_INVERT flag is set in scan_begin_arg.
-
- The channels in the channel sequence must be in ascending order with
- no repeats. All entries in the channel sequence must use the same
- output range.
-
-DIO Subdevice:
-
- The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO
- channels are configurable as inputs or outputs in four groups:
-
- Port A - channels 0 to 7
- Port B - channels 8 to 15
- Port CL - channels 16 to 19
- Port CH - channels 20 to 23
-
- Only mode 0 of the 8255 chip is supported.
-
- Bit 0 of port C (DIO channel 16) is also used as an external scan
- trigger input for AI commands on PCI230 and PCI230+, so would need to
- be configured as an input to use it for that purpose.
-*/
+ * Driver: amplc_pci230
+ * Description: Amplicon PCI230, PCI260 Multifunction I/O boards
+ * Author: Allan Willcox <allanwillcox@ozemail.com.au>,
+ * Steve D Sharples <steve.sharples@nottingham.ac.uk>,
+ * Ian Abbott <abbotti@mev.co.uk>
+ * Updated: Wed, 22 Oct 2008 12:34:49 +0100
+ * Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
+ * PCI230+ (pci230+ or amplc_pci230),
+ * PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
+ * Status: works
+ *
+ * Configuration options:
+ * [0] - PCI bus of device (optional).
+ * [1] - PCI slot of device (optional).
+ * If bus/slot is not specified, the first available PCI device
+ * will be used.
+ *
+ * Configuring a "amplc_pci230" will match any supported card and it will
+ * choose the best match, picking the "+" models if possible. Configuring
+ * a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
+ * a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
+ * and it will be treated as a PCI260. Configuring a "pci230+" will match
+ * a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
+ *
+ * Subdevices:
+ *
+ * PCI230(+) PCI260(+)
+ * --------- ---------
+ * Subdevices 3 1
+ * 0 AI AI
+ * 1 AO
+ * 2 DIO
+ *
+ * AI Subdevice:
+ *
+ * The AI subdevice has 16 single-ended channels or 8 differential
+ * channels.
+ *
+ * The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
+ * PCI260+ cards have 16-bit resolution.
+ *
+ * For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
+ * inputs 14 and 15 for channel 7). If the card is physically a PCI230
+ * or PCI260 then it actually uses a "pseudo-differential" mode where the
+ * inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
+ * use true differential sampling. Another difference is that if the
+ * card is physically a PCI230 or PCI260, the inverting input is 2N,
+ * whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
+ * PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
+ * PCI260+) and differential mode is used, the differential inputs need
+ * to be physically swapped on the connector.
+ *
+ * The following input ranges are supported:
+ *
+ * 0 => [-10, +10] V
+ * 1 => [-5, +5] V
+ * 2 => [-2.5, +2.5] V
+ * 3 => [-1.25, +1.25] V
+ * 4 => [0, 10] V
+ * 5 => [0, 5] V
+ * 6 => [0, 2.5] V
+ *
+ * AI Commands:
+ *
+ * +=========+==============+===========+============+==========+
+ * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ * +=========+==============+===========+============+==========+
+ * |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
+ * |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
+ * | | |TRIG_INT | | |
+ * | |--------------|-----------| | |
+ * | | TRIG_TIMER(1)|TRIG_TIMER | | |
+ * | | TRIG_EXT(2) | | | |
+ * | | TRIG_INT | | | |
+ * +---------+--------------+-----------+------------+----------+
+ *
+ * Note 1: If AI command and AO command are used simultaneously, only
+ * one may have scan_begin_src == TRIG_TIMER.
+ *
+ * Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
+ * DIO channel 16 (pin 49) which will need to be configured as
+ * a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
+ * (pin 17) is used instead. For PCI230, scan_begin_src ==
+ * TRIG_EXT is not supported. The trigger is a rising edge
+ * on the input.
+ *
+ * Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
+ * (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
+ * convert_arg value is interpreted as follows:
+ *
+ * convert_arg == (CR_EDGE | 0) => rising edge
+ * convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
+ * convert_arg == 0 => falling edge (backwards compatibility)
+ * convert_arg == 1 => rising edge (backwards compatibility)
+ *
+ * All entries in the channel list must use the same analogue reference.
+ * If the analogue reference is not AREF_DIFF (not differential) each
+ * pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
+ * input range. The input ranges used in the sequence must be all
+ * bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
+ * sequence must consist of 1 or more identical subsequences. Within the
+ * subsequence, channels must be in ascending order with no repeated
+ * channels. For example, the following sequences are valid: 0 1 2 3
+ * (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
+ * subsequence), 1 1 1 1 (repeated valid subsequence). The following
+ * sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
+ * (incompletely repeated subsequence). Some versions of the PCI230+ and
+ * PCI260+ have a bug that requires a subsequence longer than one entry
+ * long to include channel 0.
+ *
+ * AO Subdevice:
+ *
+ * The AO subdevice has 2 channels with 12-bit resolution.
+ * The following output ranges are supported:
+ * 0 => [0, 10] V
+ * 1 => [-10, +10] V
+ *
+ * AO Commands:
+ *
+ * +=========+==============+===========+============+==========+
+ * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ * +=========+==============+===========+============+==========+
+ * |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
+ * | | TRIG_EXT(2) | | |TRIG_COUNT|
+ * | | TRIG_INT | | | |
+ * +---------+--------------+-----------+------------+----------+
+ *
+ * Note 1: If AI command and AO command are used simultaneously, only
+ * one may have scan_begin_src == TRIG_TIMER.
+ *
+ * Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
+ * configured as a PCI230+ and is only supported on later
+ * versions of the card. As a card configured as a PCI230+ is
+ * not guaranteed to support external triggering, please consider
+ * this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
+ * input (PCI230+ pin 25). Triggering will be on the rising edge
+ * unless the CR_INVERT flag is set in scan_begin_arg.
+ *
+ * The channels in the channel sequence must be in ascending order with
+ * no repeats. All entries in the channel sequence must use the same
+ * output range.
+ *
+ * DIO Subdevice:
+ *
+ * The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO
+ * channels are configurable as inputs or outputs in four groups:
+ *
+ * Port A - channels 0 to 7
+ * Port B - channels 8 to 15
+ * Port CL - channels 16 to 19
+ * Port CH - channels 20 to 23
+ *
+ * Only mode 0 of the 8255 chip is supported.
+ *
+ * Bit 0 of port C (DIO channel 16) is also used as an external scan
+ * trigger input for AI commands on PCI230 and PCI230+, so would need to
+ * be configured as an input to use it for that purpose.
+ */
+
/*
-Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
-Support for PCI230+/260+, more triggered scan functionality, and workarounds
-for (or detection of) various hardware problems added by Ian Abbott.
-*/
+ * Extra triggered scan functionality, interrupt bug-fix added by Steve
+ * Sharples. Support for PCI230+/260+, more triggered scan functionality,
+ * and workarounds for (or detection of) various hardware problems added
+ * by Ian Abbott.
+ */
#include <linux/module.h>
#include <linux/pci.h>
@@ -195,15 +196,16 @@ for (or detection of) various hardware problems added by Ian Abbott.
#include "8253.h"
#include "8255.h"
-/* PCI230 PCI configuration register information */
+/*
+ * PCI230 PCI configuration register information
+ */
#define PCI_DEVICE_ID_PCI230 0x0000
#define PCI_DEVICE_ID_PCI260 0x0006
#define PCI_DEVICE_ID_INVALID 0xffff
-#define PCI230_IO1_SIZE 32 /* Size of I/O space 1 */
-#define PCI230_IO2_SIZE 16 /* Size of I/O space 2 */
-
-/* PCI230 i/o space 1 registers. */
+/*
+ * PCI230 i/o space 1 registers.
+ */
#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */
#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */
#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */
@@ -219,7 +221,9 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */
#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */
-/* PCI230 i/o space 2 registers. */
+/*
+ * PCI230 i/o space 2 registers.
+ */
#define PCI230_DACCON 0x00 /* DAC control */
#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */
#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */
@@ -242,57 +246,64 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */
#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */
-/* Convertor related constants. */
-#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs */
- /* (DAC itself is 1µs nominally). */
-#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs */
- /* (ADC itself is 1.6µs nominally but we poll
- * anyway). */
-#define PCI230_MUX_SETTLE 10 /* ADC MUX settling time in µS */
- /* - 10µs for se, 20µs de. */
-
-/* DACCON read-write values. */
-#define PCI230_DAC_OR_UNI (0<<0) /* Output range unipolar */
-#define PCI230_DAC_OR_BIP (1<<0) /* Output range bipolar */
-#define PCI230_DAC_OR_MASK (1<<0)
-/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
- * register (and only for PCI230+ hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_EN (1<<8) /* FIFO enable */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_TRIG_NONE (0<<2) /* No trigger */
-#define PCI230P2_DAC_TRIG_SW (1<<2) /* Software trigger trigger */
-#define PCI230P2_DAC_TRIG_EXTP (2<<2) /* EXTTRIG +ve edge trigger */
-#define PCI230P2_DAC_TRIG_EXTN (3<<2) /* EXTTRIG -ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT0 (4<<2) /* CT0-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT1 (5<<2) /* CT1-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT2 (6<<2) /* CT2-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_MASK (7<<2)
-#define PCI230P2_DAC_FIFO_WRAP (1<<7) /* FIFO wraparound mode */
-#define PCI230P2_DAC_INT_FIFO_EMPTY (0<<9) /* FIFO interrupt empty */
-#define PCI230P2_DAC_INT_FIFO_NEMPTY (1<<9)
-#define PCI230P2_DAC_INT_FIFO_NHALF (2<<9) /* FIFO intr not half full */
-#define PCI230P2_DAC_INT_FIFO_HALF (3<<9)
-#define PCI230P2_DAC_INT_FIFO_NFULL (4<<9) /* FIFO interrupt not full */
-#define PCI230P2_DAC_INT_FIFO_FULL (5<<9)
-#define PCI230P2_DAC_INT_FIFO_MASK (7<<9)
-
-/* DACCON read-only values. */
-#define PCI230_DAC_BUSY (1<<1) /* DAC busy. */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1<<5) /* Underrun error */
-#define PCI230P2_DAC_FIFO_EMPTY (1<<13) /* FIFO empty */
-#define PCI230P2_DAC_FIFO_FULL (1<<14) /* FIFO full */
-#define PCI230P2_DAC_FIFO_HALF (1<<15) /* FIFO half full */
-
-/* DACCON write-only, transient values. */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1<<5) /* Clear underrun */
-#define PCI230P2_DAC_FIFO_RESET (1<<12) /* FIFO reset */
-
-/* PCI230+ hardware version 2 DAC FIFO levels. */
+/*
+ * DACCON read-write values.
+ */
+#define PCI230_DAC_OR_UNI (0 << 0) /* Output range unipolar */
+#define PCI230_DAC_OR_BIP (1 << 0) /* Output range bipolar */
+#define PCI230_DAC_OR_MASK (1 << 0)
+/*
+ * The following applies only if DAC FIFO support is enabled in the EXTFUNC
+ * register (and only for PCI230+ hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_EN (1 << 8) /* FIFO enable */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_TRIG_NONE (0 << 2) /* No trigger */
+#define PCI230P2_DAC_TRIG_SW (1 << 2) /* Software trigger trigger */
+#define PCI230P2_DAC_TRIG_EXTP (2 << 2) /* EXTTRIG +ve edge trigger */
+#define PCI230P2_DAC_TRIG_EXTN (3 << 2) /* EXTTRIG -ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT0 (4 << 2) /* CT0-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT1 (5 << 2) /* CT1-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT2 (6 << 2) /* CT2-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_MASK (7 << 2)
+#define PCI230P2_DAC_FIFO_WRAP (1 << 7) /* FIFO wraparound mode */
+#define PCI230P2_DAC_INT_FIFO_EMPTY (0 << 9) /* FIFO interrupt empty */
+#define PCI230P2_DAC_INT_FIFO_NEMPTY (1 << 9)
+#define PCI230P2_DAC_INT_FIFO_NHALF (2 << 9) /* FIFO intr not half full */
+#define PCI230P2_DAC_INT_FIFO_HALF (3 << 9)
+#define PCI230P2_DAC_INT_FIFO_NFULL (4 << 9) /* FIFO interrupt not full */
+#define PCI230P2_DAC_INT_FIFO_FULL (5 << 9)
+#define PCI230P2_DAC_INT_FIFO_MASK (7 << 9)
+
+/*
+ * DACCON read-only values.
+ */
+#define PCI230_DAC_BUSY (1 << 1) /* DAC busy. */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1 << 5) /* Underrun error */
+#define PCI230P2_DAC_FIFO_EMPTY (1 << 13) /* FIFO empty */
+#define PCI230P2_DAC_FIFO_FULL (1 << 14) /* FIFO full */
+#define PCI230P2_DAC_FIFO_HALF (1 << 15) /* FIFO half full */
+
+/*
+ * DACCON write-only, transient values.
+ */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1 << 5) /* Clear underrun */
+#define PCI230P2_DAC_FIFO_RESET (1 << 12) /* FIFO reset */
+
+/*
+ * PCI230+ hardware version 2 DAC FIFO levels.
+ */
#define PCI230P2_DAC_FIFOLEVEL_HALF 512
#define PCI230P2_DAC_FIFOLEVEL_FULL 1024
/* Free space in DAC FIFO. */
@@ -302,56 +313,62 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1
#define PCI230P2_DAC_FIFOROOM_FULL 0
-/* ADCCON read/write values. */
-#define PCI230_ADC_TRIG_NONE (0<<0) /* No trigger */
-#define PCI230_ADC_TRIG_SW (1<<0) /* Software trigger trigger */
-#define PCI230_ADC_TRIG_EXTP (2<<0) /* EXTTRIG +ve edge trigger */
-#define PCI230_ADC_TRIG_EXTN (3<<0) /* EXTTRIG -ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT0 (4<<0) /* CT0-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT1 (5<<0) /* CT1-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT2 (6<<0) /* CT2-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_MASK (7<<0)
-#define PCI230_ADC_IR_UNI (0<<3) /* Input range unipolar */
-#define PCI230_ADC_IR_BIP (1<<3) /* Input range bipolar */
-#define PCI230_ADC_IR_MASK (1<<3)
-#define PCI230_ADC_IM_SE (0<<4) /* Input mode single ended */
-#define PCI230_ADC_IM_DIF (1<<4) /* Input mode differential */
-#define PCI230_ADC_IM_MASK (1<<4)
-#define PCI230_ADC_FIFO_EN (1<<8) /* FIFO enable */
-#define PCI230_ADC_INT_FIFO_EMPTY (0<<9)
-#define PCI230_ADC_INT_FIFO_NEMPTY (1<<9) /* FIFO interrupt not empty */
-#define PCI230_ADC_INT_FIFO_NHALF (2<<9)
-#define PCI230_ADC_INT_FIFO_HALF (3<<9) /* FIFO interrupt half full */
-#define PCI230_ADC_INT_FIFO_NFULL (4<<9)
-#define PCI230_ADC_INT_FIFO_FULL (5<<9) /* FIFO interrupt full */
-#define PCI230P_ADC_INT_FIFO_THRESH (7<<9) /* FIFO interrupt threshold */
-#define PCI230_ADC_INT_FIFO_MASK (7<<9)
-
-/* ADCCON write-only, transient values. */
-#define PCI230_ADC_FIFO_RESET (1<<12) /* FIFO reset */
-#define PCI230_ADC_GLOB_RESET (1<<13) /* Global reset */
-
-/* ADCCON read-only values. */
-#define PCI230_ADC_BUSY (1<<15) /* ADC busy */
-#define PCI230_ADC_FIFO_EMPTY (1<<12) /* FIFO empty */
-#define PCI230_ADC_FIFO_FULL (1<<13) /* FIFO full */
-#define PCI230_ADC_FIFO_HALF (1<<14) /* FIFO half full */
-#define PCI230_ADC_FIFO_FULL_LATCHED (1<<5) /* Indicates overrun occurred */
-
-/* PCI230 ADC FIFO levels. */
+/*
+ * ADCCON read/write values.
+ */
+#define PCI230_ADC_TRIG_NONE (0 << 0) /* No trigger */
+#define PCI230_ADC_TRIG_SW (1 << 0) /* Software trigger trigger */
+#define PCI230_ADC_TRIG_EXTP (2 << 0) /* EXTTRIG +ve edge trigger */
+#define PCI230_ADC_TRIG_EXTN (3 << 0) /* EXTTRIG -ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT0 (4 << 0) /* CT0-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT1 (5 << 0) /* CT1-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT2 (6 << 0) /* CT2-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_MASK (7 << 0)
+#define PCI230_ADC_IR_UNI (0 << 3) /* Input range unipolar */
+#define PCI230_ADC_IR_BIP (1 << 3) /* Input range bipolar */
+#define PCI230_ADC_IR_MASK (1 << 3)
+#define PCI230_ADC_IM_SE (0 << 4) /* Input mode single ended */
+#define PCI230_ADC_IM_DIF (1 << 4) /* Input mode differential */
+#define PCI230_ADC_IM_MASK (1 << 4)
+#define PCI230_ADC_FIFO_EN (1 << 8) /* FIFO enable */
+#define PCI230_ADC_INT_FIFO_EMPTY (0 << 9)
+#define PCI230_ADC_INT_FIFO_NEMPTY (1 << 9) /* FIFO interrupt not empty */
+#define PCI230_ADC_INT_FIFO_NHALF (2 << 9)
+#define PCI230_ADC_INT_FIFO_HALF (3 << 9) /* FIFO interrupt half full */
+#define PCI230_ADC_INT_FIFO_NFULL (4 << 9)
+#define PCI230_ADC_INT_FIFO_FULL (5 << 9) /* FIFO interrupt full */
+#define PCI230P_ADC_INT_FIFO_THRESH (7 << 9) /* FIFO interrupt threshold */
+#define PCI230_ADC_INT_FIFO_MASK (7 << 9)
+
+/*
+ * ADCCON write-only, transient values.
+ */
+#define PCI230_ADC_FIFO_RESET (1 << 12) /* FIFO reset */
+#define PCI230_ADC_GLOB_RESET (1 << 13) /* Global reset */
+
+/*
+ * ADCCON read-only values.
+ */
+#define PCI230_ADC_BUSY (1 << 15) /* ADC busy */
+#define PCI230_ADC_FIFO_EMPTY (1 << 12) /* FIFO empty */
+#define PCI230_ADC_FIFO_FULL (1 << 13) /* FIFO full */
+#define PCI230_ADC_FIFO_HALF (1 << 14) /* FIFO half full */
+#define PCI230_ADC_FIFO_FULL_LATCHED (1 << 5) /* FIFO overrun occurred */
+
+/*
+ * PCI230 ADC FIFO levels.
+ */
#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */
#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */
-/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
- * mode. Can be anything. */
-#define PCI230_ADC_CONV 0xffff
-
-/* PCI230+ EXTFUNC values. */
-#define PCI230P_EXTFUNC_GAT_EXTTRIG (1<<0)
- /* Route EXTTRIG pin to external gate inputs. */
+/*
+ * PCI230+ EXTFUNC values.
+ */
+/* Route EXTTRIG pin to external gate inputs. */
+#define PCI230P_EXTFUNC_GAT_EXTTRIG (1 << 0)
/* PCI230+ hardware version 2 values. */
-#define PCI230P2_EXTFUNC_DACFIFO (1<<1)
- /* Allow DAC FIFO to be enabled. */
+/* Allow DAC FIFO to be enabled. */
+#define PCI230P2_EXTFUNC_DACFIFO (1 << 1)
/*
* Counter/timer clock input configuration sources.
@@ -395,19 +412,20 @@ for (or detection of) various hardware problems added by Ian Abbott.
* Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
*/
-/* Interrupt enables/status register values. */
+/*
+ * Interrupt enables/status register values.
+ */
#define PCI230_INT_DISABLE 0
-#define PCI230_INT_PPI_C0 (1<<0)
-#define PCI230_INT_PPI_C3 (1<<1)
-#define PCI230_INT_ADC (1<<2)
-#define PCI230_INT_ZCLK_CT1 (1<<5)
+#define PCI230_INT_PPI_C0 (1 << 0)
+#define PCI230_INT_PPI_C3 (1 << 1)
+#define PCI230_INT_ADC (1 << 2)
+#define PCI230_INT_ZCLK_CT1 (1 << 5)
/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
-#define PCI230P2_INT_DAC (1<<4)
-
-#define PCI230_TEST_BIT(val, n) ((val>>n)&1)
- /* Assumes bits numbered with zero offset, ie. 0-15 */
+#define PCI230P2_INT_DAC (1 << 4)
-/* (Potentially) shared resources and their owners */
+/*
+ * (Potentially) shared resources and their owners
+ */
enum {
RES_Z2CT0, /* Z2-CT0 */
RES_Z2CT1, /* Z2-CT1 */
@@ -449,83 +467,70 @@ struct pci230_board {
int have_dio;
unsigned int min_hwver; /* Minimum hardware version supported. */
};
+
static const struct pci230_board pci230_boards[] = {
{
- .name = "pci230+",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_chans = 16,
- .ai_bits = 16,
- .ao_chans = 2,
- .ao_bits = 12,
- .have_dio = 1,
- .min_hwver = 1,
- },
+ .name = "pci230+",
+ .id = PCI_DEVICE_ID_PCI230,
+ .ai_chans = 16,
+ .ai_bits = 16,
+ .ao_chans = 2,
+ .ao_bits = 12,
+ .have_dio = 1,
+ .min_hwver = 1,
+ },
{
- .name = "pci260+",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_chans = 16,
- .ai_bits = 16,
- .ao_chans = 0,
- .ao_bits = 0,
- .have_dio = 0,
- .min_hwver = 1,
- },
+ .name = "pci260+",
+ .id = PCI_DEVICE_ID_PCI260,
+ .ai_chans = 16,
+ .ai_bits = 16,
+ .min_hwver = 1,
+ },
{
- .name = "pci230",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_chans = 16,
- .ai_bits = 12,
- .ao_chans = 2,
- .ao_bits = 12,
- .have_dio = 1,
- },
+ .name = "pci230",
+ .id = PCI_DEVICE_ID_PCI230,
+ .ai_chans = 16,
+ .ai_bits = 12,
+ .ao_chans = 2,
+ .ao_bits = 12,
+ .have_dio = 1,
+ },
{
- .name = "pci260",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_chans = 16,
- .ai_bits = 12,
- .ao_chans = 0,
- .ao_bits = 0,
- .have_dio = 0,
- },
+ .name = "pci260",
+ .id = PCI_DEVICE_ID_PCI260,
+ .ai_chans = 16,
+ .ai_bits = 12,
+ },
{
- .name = "amplc_pci230", /* Wildcard matches any above */
- .id = PCI_DEVICE_ID_INVALID,
- },
+ /* Wildcard matches any above */
+ .name = "amplc_pci230",
+ .id = PCI_DEVICE_ID_INVALID,
+ },
};
-/* this structure is for data unique to this hardware driver. If
- several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the struct comedi_device struct. */
struct pci230_private {
spinlock_t isr_spinlock; /* Interrupt spin lock */
spinlock_t res_spinlock; /* Shared resources spin lock */
spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
- unsigned long state; /* State flags */
- unsigned long iobase1; /* PCI230's I/O space 1 */
+ unsigned long state; /* State flags */
+ unsigned long iobase1; /* PCI230's I/O space 1 */
unsigned int ao_readback[2]; /* Used for AO readback */
- unsigned int ai_scan_count; /* Number of analogue input scans
- * remaining. */
- unsigned int ai_scan_pos; /* Current position within analogue
- * input scan */
- unsigned int ao_scan_count; /* Number of analogue output scans
- * remaining. */
- int intr_cpuid; /* ID of CPU running interrupt routine. */
- unsigned short hwver; /* Hardware version (for '+' models). */
- unsigned short adccon; /* ADCCON register value. */
- unsigned short daccon; /* DACCON register value. */
- unsigned short adcfifothresh; /* ADC FIFO programmable interrupt
- * level threshold (PCI230+/260+). */
- unsigned short adcg; /* ADCG register value. */
- unsigned char int_en; /* Interrupt enables bits. */
- unsigned char ai_bipolar; /* Set if bipolar input range so we
- * know to mangle it. */
- unsigned char ao_bipolar; /* Set if bipolar output range so we
- * know to mangle it. */
- unsigned char ier; /* Copy of interrupt enables/status register. */
- unsigned char intr_running; /* Flag set in interrupt routine. */
- unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners. */
+ unsigned int ai_scan_count; /* Number of AI scans remaining */
+ unsigned int ai_scan_pos; /* Current position within AI scan */
+ unsigned int ao_scan_count; /* Number of AO scans remaining. */
+ int intr_cpuid; /* ID of CPU running ISR */
+ unsigned short hwver; /* Hardware version (for '+' models) */
+ unsigned short adccon; /* ADCCON register value */
+ unsigned short daccon; /* DACCON register value */
+ unsigned short adcfifothresh; /* ADC FIFO threshold (PCI230+/260+) */
+ unsigned short adcg; /* ADCG register value */
+ unsigned char int_en; /* Interrupt enable bits */
+ unsigned char ai_bipolar; /* Flag AI range is bipolar */
+ unsigned char ao_bipolar; /* Flag AO range is bipolar */
+ unsigned char ier; /* Copy of interrupt enable register */
+ unsigned char intr_running; /* Flag set in interrupt routine */
+ unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners */
};
/* PCI230 clock source periods in ns */
@@ -575,13 +580,16 @@ static unsigned short pci230_ai_read(struct comedi_device *dev)
/* Read sample. */
data = inw(dev->iobase + PCI230_ADCDATA);
- /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
- * four bits reserved for expansion). */
- /* PCI230+ is 16 bit AI. */
+ /*
+ * PCI230 is 12 bit - stored in upper bits of 16 bit register
+ * (lower four bits reserved for expansion). PCI230+ is 16 bit AI.
+ */
data = data >> (16 - thisboard->ai_bits);
- /* If a bipolar range was specified, mangle it (twos
- * complement->straight binary). */
+ /*
+ * If a bipolar range was specified, mangle it
+ * (twos complement->straight binary).
+ */
if (devpriv->ai_bipolar)
data ^= 1 << (thisboard->ai_bits - 1);
@@ -594,14 +602,17 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
const struct pci230_board *thisboard = comedi_board(dev);
struct pci230_private *devpriv = dev->private;
- /* If a bipolar range was specified, mangle it (straight binary->twos
- * complement). */
+ /*
+ * If a bipolar range was specified, mangle it
+ * (straight binary->twos complement).
+ */
if (devpriv->ao_bipolar)
datum ^= 1 << (thisboard->ao_bits - 1);
- /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
- * four bits reserved for expansion). */
- /* PCI230+ is also 12 bit AO. */
+ /*
+ * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). PCI230+ is also 12 bit AO.
+ */
datum <<= (16 - thisboard->ao_bits);
return datum;
}
@@ -616,10 +627,8 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
devpriv->ao_readback[chan] = datum;
/* Write mangled datum to appropriate DACOUT register. */
- outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
- ? PCI230_DACOUT1
- :
- PCI230_DACOUT2));
+ outw(pci230_ao_mangle_datum(dev, datum),
+ dev->iobase + (((chan) == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2));
}
static inline void pci230_ao_write_fifo(struct comedi_device *dev,
@@ -648,18 +657,17 @@ static int get_resources(struct comedi_device *dev, unsigned int res_mask,
ok = 1;
claimed = 0;
spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- for (b = 1, i = 0; (i < NUM_RESOURCES)
- && (res_mask != 0); b <<= 1, i++) {
- if ((res_mask & b) != 0) {
+ for (b = 1, i = 0; (i < NUM_RESOURCES) && res_mask; b <<= 1, i++) {
+ if (res_mask & b) {
res_mask &= ~b;
if (devpriv->res_owner[i] == OWNER_NONE) {
devpriv->res_owner[i] = owner;
claimed |= b;
} else if (devpriv->res_owner[i] != owner) {
- for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
- if ((claimed & b) != 0) {
- devpriv->res_owner[i]
- = OWNER_NONE;
+ for (b = 1, i = 0; claimed; b <<= 1, i++) {
+ if (claimed & b) {
+ devpriv->res_owner[i] =
+ OWNER_NONE;
claimed &= ~b;
}
}
@@ -687,13 +695,11 @@ static void put_resources(struct comedi_device *dev, unsigned int res_mask,
unsigned long irqflags;
spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- for (b = 1, i = 0; (i < NUM_RESOURCES)
- && (res_mask != 0); b <<= 1, i++) {
- if ((res_mask & b) != 0) {
+ for (b = 1, i = 0; (i < NUM_RESOURCES) && res_mask; b <<= 1, i++) {
+ if (res_mask & b) {
res_mask &= ~b;
if (devpriv->res_owner[i] == owner)
devpriv->res_owner[i] = OWNER_NONE;
-
}
}
spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
@@ -712,15 +718,14 @@ static inline void put_all_resources(struct comedi_device *dev,
}
static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
- unsigned int round_mode)
+ unsigned int flags)
{
uint64_t div;
unsigned int rem;
div = ns;
rem = do_div(div, timebase);
- round_mode &= TRIG_ROUND_MASK;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
default:
case TRIG_ROUND_NEAREST:
div += (rem + (timebase / 2)) / timebase;
@@ -734,36 +739,36 @@ static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
}
-/* Given desired period in ns, returns the required internal clock source
- * and gets the initial count. */
+/*
+ * Given desired period in ns, returns the required internal clock source
+ * and gets the initial count.
+ */
static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
- unsigned int round_mode)
+ unsigned int flags)
{
unsigned int clk_src, cnt;
for (clk_src = CLK_10MHZ;; clk_src++) {
- cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
+ cnt = divide_ns(ns, pci230_timebase[clk_src], flags);
if ((cnt <= 65536) || (clk_src == CLK_1KHZ))
break;
-
}
*count = cnt;
return clk_src;
}
-static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags)
{
unsigned int count;
unsigned int clk_src;
- clk_src = pci230_choose_clk_count(*ns, &count, round);
+ clk_src = pci230_choose_clk_count(*ns, &count, flags);
*ns = count * pci230_timebase[clk_src];
- return;
}
static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
unsigned int mode, uint64_t ns,
- unsigned int round)
+ unsigned int flags)
{
struct pci230_private *devpriv = dev->private;
unsigned int clk_src;
@@ -772,7 +777,7 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
/* Set mode. */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
/* Determine clock source and count. */
- clk_src = pci230_choose_clk_count(ns, &count, round);
+ clk_src = pci230_choose_clk_count(ns, &count, flags);
/* Program clock source. */
outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
/* Set initial count. */
@@ -829,7 +834,8 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
}
}
- /* Use Z2-CT2 as a conversion trigger instead of the built-in
+ /*
+ * Use Z2-CT2 as a conversion trigger instead of the built-in
* software trigger, as otherwise triggering of differential channels
* doesn't work properly for some versions of PCI230/260. Also set
* FIFO mode because the ADC busy bit only works for software triggers.
@@ -842,12 +848,16 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
/* Differential. */
gainshift = chan * 2;
if (devpriv->hwver == 0) {
- /* Original PCI230/260 expects both inputs of the
- * differential channel to be enabled. */
+ /*
+ * Original PCI230/260 expects both inputs of the
+ * differential channel to be enabled.
+ */
adcen = 3 << gainshift;
} else {
- /* PCI230+/260+ expects only one input of the
- * differential channel to be enabled. */
+ /*
+ * PCI230+/260+ expects only one input of the
+ * differential channel to be enabled.
+ */
adcen = 1 << gainshift;
}
adccon |= PCI230_ADC_IM_DIF;
@@ -857,16 +867,18 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
gainshift = chan & ~1;
adccon |= PCI230_ADC_IM_SE;
}
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
- | (pci230_ai_gain[range] << gainshift);
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
+ (pci230_ai_gain[range] << gainshift);
if (devpriv->ai_bipolar)
adccon |= PCI230_ADC_IR_BIP;
else
adccon |= PCI230_ADC_IR_UNI;
- /* Enable only this channel in the scan list - otherwise by default
- * we'll get one sample from each channel. */
+ /*
+ * Enable only this channel in the scan list - otherwise by default
+ * we'll get one sample from each channel.
+ */
outw(adcen, dev->iobase + PCI230_ADCEN);
/* Set gain for channel. */
@@ -878,8 +890,10 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
/* Convert n samples */
for (n = 0; n < insn->n; n++) {
- /* Trigger conversion by toggling Z2-CT2 output (finish with
- * output high). */
+ /*
+ * Trigger conversion by toggling Z2-CT2 output
+ * (finish with output high).
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE0);
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
@@ -913,13 +927,17 @@ static int pci230_ao_winsn(struct comedi_device *dev,
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- /* Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale */
+ /*
+ * Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale
+ */
devpriv->ao_bipolar = pci230_ao_bipolar[range];
outw(range, dev->iobase + PCI230_DACCON);
- /* Writing a list of values to an AO channel is probably not
- * very useful, but that's how the interface is defined. */
+ /*
+ * Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined.
+ */
for (i = 0; i < insn->n; i++) {
/* Write value to DAC and store it. */
pci230_ao_write_nofifo(dev, data[i], chan);
@@ -929,8 +947,10 @@ static int pci230_ao_winsn(struct comedi_device *dev,
return i;
}
-/* AO subdevices should have a read insn as well as a write insn.
- * Usually this means copying a value stored in devpriv. */
+/*
+ * AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv.
+ */
static int pci230_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
@@ -1031,10 +1051,11 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
+/*
+ * Comedi limit due to unsigned int cmd. Driver limit =
+ * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
+ */
#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
- /*- Comedi limit due to unsigned int cmd. Driver limit
- * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
- * clock) = 65.536s */
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
@@ -1044,17 +1065,21 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
MIN_SPEED_AO);
break;
case TRIG_EXT:
- /* External trigger - for PCI230+ hardware version 2 onwards. */
+ /*
+ * External trigger - for PCI230+ hardware version 2 onwards.
+ */
/* Trigger number must be 0. */
- if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
- /* The only flags allowed are CR_EDGE and CR_INVERT. The
- * CR_EDGE flag is ignored. */
- if ((cmd->scan_begin_arg
- & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
+ /*
+ * The only flags allowed are CR_EDGE and CR_INVERT.
+ * The CR_EDGE flag is ignored.
+ */
+ if (cmd->scan_begin_arg &
+ (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
CR_FLAGS_MASK &
~(CR_EDGE | CR_INVERT));
@@ -1074,14 +1099,11 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
if (err)
return 3;
- /* Step 4: fix up any arguments.
- * "argument conflict" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 4: fix up any arguments */
if (cmd->scan_begin_src == TRIG_TIMER) {
tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
if (tmp != cmd->scan_begin_arg)
err++;
}
@@ -1126,8 +1148,10 @@ static void pci230_ao_stop(struct comedi_device *dev,
/* Using DAC FIFO interrupt. */
intsrc = PCI230P2_INT_DAC;
}
- /* Disable interrupt and wait for interrupt routine to finish running
- * unless we are called from the interrupt routine. */
+ /*
+ * Disable interrupt and wait for interrupt routine to finish running
+ * unless we are called from the interrupt routine.
+ */
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
devpriv->int_en &= ~intsrc;
while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
@@ -1140,11 +1164,13 @@ static void pci230_ao_stop(struct comedi_device *dev,
}
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
if (devpriv->hwver >= 2) {
- /* Using DAC FIFO. Reset FIFO, clear underrun error,
- * disable FIFO. */
+ /*
+ * Using DAC FIFO. Reset FIFO, clear underrun error,
+ * disable FIFO.
+ */
devpriv->daccon &= PCI230_DAC_OR_MASK;
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
- | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
dev->iobase + PCI230_DACCON);
}
/* Release resources. */
@@ -1168,7 +1194,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
if (ret == 0) {
s->async->events |= COMEDI_CB_OVERFLOW;
pci230_ao_stop(dev, s);
- comedi_error(dev, "AO buffer underrun");
+ dev_err(dev->class_dev, "AO buffer underrun\n");
return;
}
/* Write value to DAC. */
@@ -1215,26 +1241,28 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
}
if (events == 0) {
/* Check for FIFO underrun. */
- if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
- comedi_error(dev, "AO FIFO underrun");
+ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
+ dev_err(dev->class_dev, "AO FIFO underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
- /* Check for buffer underrun if FIFO less than half full
+ /*
+ * Check for buffer underrun if FIFO less than half full
* (otherwise there will be loads of "DAC FIFO not half full"
- * interrupts). */
- if ((num_scans == 0)
- && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
- comedi_error(dev, "AO buffer underrun");
+ * interrupts).
+ */
+ if ((num_scans == 0) &&
+ ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+ dev_err(dev->class_dev, "AO buffer underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
}
if (events == 0) {
/* Determine how much room is in the FIFO (in samples). */
- if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0)
+ if (dacstat & PCI230P2_DAC_FIFO_FULL)
room = PCI230P2_DAC_FIFOROOM_FULL;
- else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
+ else if (dacstat & PCI230P2_DAC_FIFO_HALF)
room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
- else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
+ else if (dacstat & PCI230P2_DAC_FIFO_EMPTY)
room = PCI230P2_DAC_FIFOROOM_EMPTY;
else
room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
@@ -1257,26 +1285,27 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
if (cmd->stop_src == TRIG_COUNT) {
devpriv->ao_scan_count -= num_scans;
if (devpriv->ao_scan_count == 0) {
- /* All data for the command has been written
+ /*
+ * All data for the command has been written
* to FIFO. Set FIFO interrupt trigger level
- * to 'empty'. */
- devpriv->daccon = (devpriv->daccon
- &
- ~PCI230P2_DAC_INT_FIFO_MASK)
- | PCI230P2_DAC_INT_FIFO_EMPTY;
+ * to 'empty'.
+ */
+ devpriv->daccon =
+ (devpriv->daccon &
+ ~PCI230P2_DAC_INT_FIFO_MASK) |
+ PCI230P2_DAC_INT_FIFO_EMPTY;
outw(devpriv->daccon,
dev->iobase + PCI230_DACCON);
}
}
/* Check if FIFO underrun occurred while writing to FIFO. */
dacstat = inw(dev->iobase + PCI230_DACCON);
- if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
- comedi_error(dev, "AO FIFO underrun");
+ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
+ dev_err(dev->class_dev, "AO FIFO underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
}
- if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
- != 0) {
+ if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
/* Stopping AO due to completion or error. */
pci230_ao_stop(dev, s);
running = 0;
@@ -1294,7 +1323,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
struct pci230_private *devpriv = dev->private;
unsigned long irqflags;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
@@ -1373,11 +1402,10 @@ static void pci230_ao_start(struct comedi_device *dev,
scantrig = PCI230P2_DAC_TRIG_NONE;
break;
}
- devpriv->daccon = (devpriv->daccon
- & ~PCI230P2_DAC_TRIG_MASK) |
+ devpriv->daccon =
+ (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) |
scantrig;
outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
-
}
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
@@ -1441,7 +1469,6 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* Claim Z2-CT1. */
if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
return -EBUSY;
-
}
/* Get number of scans required. */
@@ -1450,8 +1477,10 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else /* TRIG_NONE, user calls cancel */
devpriv->ao_scan_count = 0;
- /* Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale */
+ /*
+ * Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale
+ */
range = CR_RANGE(cmd->chanlist[0]);
devpriv->ao_bipolar = pci230_ao_bipolar[range];
daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
@@ -1474,26 +1503,28 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*
* N.B. DAC FIFO interrupts are currently disabled.
*/
- daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
- | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
- | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
+ daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR |
+ PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
}
/* Set DACCON. */
outw(daccon, dev->iobase + PCI230_DACCON);
/* Preserve most of DACCON apart from write-only, transient bits. */
- devpriv->daccon = daccon
- & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
+ devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Set the counter timer 1 to the specified scan frequency. */
- /* cmd->scan_begin_arg is sampling period in ns */
- /* gate it off for now. */
+ /*
+ * Set the counter timer 1 to the specified scan frequency.
+ * cmd->scan_begin_arg is sampling period in ns.
+ * Gate it off for now.
+ */
outb(GAT_CONFIG(1, GAT_GND),
devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->flags);
}
/* N.B. cmd->start_src == TRIG_INT */
@@ -1519,8 +1550,8 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
chanlist_len = 1;
min_scan_period = chanlist_len * cmd->convert_arg;
- if ((min_scan_period < chanlist_len)
- || (min_scan_period < cmd->convert_arg)) {
+ if ((min_scan_period < chanlist_len) ||
+ (min_scan_period < cmd->convert_arg)) {
/* Arithmetic overflow. */
min_scan_period = UINT_MAX;
err++;
@@ -1570,10 +1601,10 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
if (subseq_len > 0 &&
cmd->chanlist[i % subseq_len] != chanspec) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase or sequence must repeat exactly\n",
- __func__);
- return -EINVAL;
+ dev_dbg(dev->class_dev,
+ "%s: channel numbers must increase or sequence must repeat exactly\n",
+ __func__);
+ return -EINVAL;
}
if (aref != prev_aref) {
@@ -1607,7 +1638,7 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
if (subseq_len == 0)
subseq_len = cmd->chanlist_len;
- if ((cmd->chanlist_len % subseq_len) != 0) {
+ if (cmd->chanlist_len % subseq_len) {
dev_dbg(dev->class_dev,
"%s: sequence must repeat exactly\n", __func__);
return -EINVAL;
@@ -1625,7 +1656,7 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
* the bug, but the second one does, and we can't tell them apart!
*/
if (devpriv->hwver > 0 && devpriv->hwver < 4) {
- if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0]) != 0) {
+ if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) {
dev_info(dev->class_dev,
"amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
devpriv->hwver);
@@ -1680,8 +1711,8 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
* set up to generate a fixed number of timed conversion pulses.
*/
- if ((cmd->scan_begin_src != TRIG_FOLLOW)
- && (cmd->convert_src != TRIG_TIMER))
+ if ((cmd->scan_begin_src != TRIG_FOLLOW) &&
+ (cmd->convert_src != TRIG_TIMER))
err |= -EINVAL;
if (err)
@@ -1694,17 +1725,20 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
+/*
+ * Comedi limit due to unsigned int cmd. Driver limit =
+ * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
+ */
#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
- /*- Comedi limit due to unsigned int cmd. Driver limit
- * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
- * clock) = 65.536s */
if (cmd->convert_src == TRIG_TIMER) {
unsigned int max_speed_ai;
if (devpriv->hwver == 0) {
- /* PCI230 or PCI260. Max speed depends whether
- * single-ended or pseudo-differential. */
+ /*
+ * PCI230 or PCI260. Max speed depends whether
+ * single-ended or pseudo-differential.
+ */
if (cmd->chanlist && (cmd->chanlist_len > 0)) {
/* Peek analogue reference of first channel. */
if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
@@ -1734,17 +1768,19 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
* convert_arg == (CR_EDGE | CR_INVERT | 0)
* => trigger on -ve edge.
*/
- if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
+ if (cmd->convert_arg & CR_FLAGS_MASK) {
/* Trigger number must be 0. */
- if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
+ if (cmd->convert_arg & ~CR_FLAGS_MASK) {
cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
- /* The only flags allowed are CR_INVERT and CR_EDGE.
- * CR_EDGE is required. */
- if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
- != CR_EDGE) {
+ /*
+ * The only flags allowed are CR_INVERT and CR_EDGE.
+ * CR_EDGE is required.
+ */
+ if ((cmd->convert_arg &
+ (CR_FLAGS_MASK & ~CR_INVERT)) != CR_EDGE) {
/* Set CR_EDGE, preserve CR_INVERT. */
cmd->convert_arg = COMBINE(cmd->start_arg,
(CR_EDGE | 0),
@@ -1753,9 +1789,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
err |= -EINVAL;
}
} else {
- /* Backwards compatibility with previous versions. */
- /* convert_arg == 0 => trigger on -ve edge. */
- /* convert_arg == 1 => trigger on +ve edge. */
+ /*
+ * Backwards compatibility with previous versions:
+ * convert_arg == 0 => trigger on -ve edge.
+ * convert_arg == 1 => trigger on +ve edge.
+ */
err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1);
}
} else {
@@ -1768,16 +1806,18 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (cmd->scan_begin_src == TRIG_EXT) {
- /* external "trigger" to begin each scan
+ /*
+ * external "trigger" to begin each scan:
* scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
- * of CT2 (sample convert trigger is CT2) */
- if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ * of CT2 (sample convert trigger is CT2)
+ */
+ if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
/* The only flag allowed is CR_EDGE, which is ignored. */
- if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
CR_FLAGS_MASK & ~CR_EDGE);
err |= -EINVAL;
@@ -1794,14 +1834,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if (err)
return 3;
- /* Step 4: fix up any arguments.
- * "argument conflict" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 4: fix up any arguments */
if (cmd->convert_src == TRIG_TIMER) {
tmp = cmd->convert_arg;
- pci230_ns_to_single_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags);
if (tmp != cmd->convert_arg)
err++;
}
@@ -1809,8 +1846,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
/* N.B. cmd->convert_arg is also TRIG_TIMER */
tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
if (!pci230_ai_check_scan_period(cmd)) {
/* Was below minimum required. Round up. */
pci230_ns_to_single_timer(&cmd->scan_begin_arg,
@@ -1844,7 +1880,7 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
unsigned short triglev;
unsigned short adccon;
- if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
+ if (cmd->flags & TRIG_WAKE_EOS) {
/* Wake at end of scan. */
wake = scanlen - devpriv->ai_scan_pos;
} else {
@@ -1853,8 +1889,8 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
- wake = (devpriv->ai_scan_count * scanlen)
- - devpriv->ai_scan_pos;
+ wake = (devpriv->ai_scan_count * scanlen) -
+ devpriv->ai_scan_pos;
}
}
if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
@@ -1885,27 +1921,30 @@ static int pci230_ai_inttrig_convert(struct comedi_device *dev,
struct pci230_private *devpriv = dev->private;
unsigned long irqflags;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
unsigned int delayus;
- /* Trigger conversion by toggling Z2-CT2 output. Finish
- * with output high. */
+ /*
+ * Trigger conversion by toggling Z2-CT2 output.
+ * Finish with output high.
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE0);
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE1);
- /* Delay. Should driver be responsible for this? An
+ /*
+ * Delay. Should driver be responsible for this? An
* alternative would be to wait until conversion is complete,
* but we can't tell when it's complete because the ADC busy
* bit has a different meaning when FIFO enabled (and when
- * FIFO not enabled, it only works for software triggers). */
- if (((devpriv->adccon & PCI230_ADC_IM_MASK)
- == PCI230_ADC_IM_DIF)
- && (devpriv->hwver == 0)) {
+ * FIFO not enabled, it only works for software triggers).
+ */
+ if (((devpriv->adccon & PCI230_ADC_IM_MASK) ==
+ PCI230_ADC_IM_DIF) && (devpriv->hwver == 0)) {
/* PCI230/260 in differential mode */
delayus = 8;
} else {
@@ -1929,7 +1968,7 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
unsigned long irqflags;
unsigned char zgat;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
@@ -1968,8 +2007,10 @@ static void pci230_ai_stop(struct comedi_device *dev,
pci230_cancel_ct(dev, 0);
}
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- /* Disable ADC interrupt and wait for interrupt routine to finish
- * running unless we are called from the interrupt routine. */
+ /*
+ * Disable ADC interrupt and wait for interrupt routine to finish
+ * running unless we are called from the interrupt routine.
+ */
devpriv->int_en &= ~PCI230_INT_ADC;
while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
@@ -1980,10 +2021,12 @@ static void pci230_ai_stop(struct comedi_device *dev,
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
}
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- /* Reset FIFO, disable FIFO and set start conversion source to none.
- * Keep se/diff and bip/uni settings */
- devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
- | PCI230_ADC_IM_MASK)) |
+ /*
+ * Reset FIFO, disable FIFO and set start conversion source to none.
+ * Keep se/diff and bip/uni settings.
+ */
+ devpriv->adccon =
+ (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) |
PCI230_ADC_TRIG_NONE;
outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
dev->iobase + PCI230_ADCCON);
@@ -2014,8 +2057,10 @@ static void pci230_ai_start(struct comedi_device *dev,
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- /* Update conversion trigger source which is currently set
- * to CT2 output, which is currently stuck high. */
+ /*
+ * Update conversion trigger source which is currently set
+ * to CT2 output, which is currently stuck high.
+ */
switch (cmd->convert_src) {
default:
conv = PCI230_ADC_TRIG_NONE;
@@ -2025,7 +2070,7 @@ static void pci230_ai_start(struct comedi_device *dev,
conv = PCI230_ADC_TRIG_Z2CT2;
break;
case TRIG_EXT:
- if ((cmd->convert_arg & CR_EDGE) != 0) {
+ if (cmd->convert_arg & CR_EDGE) {
if ((cmd->convert_arg & CR_INVERT) == 0) {
/* Trigger on +ve edge. */
conv = PCI230_ADC_TRIG_EXTP;
@@ -2035,7 +2080,7 @@ static void pci230_ai_start(struct comedi_device *dev,
}
} else {
/* Backwards compatibility. */
- if (cmd->convert_arg != 0) {
+ if (cmd->convert_arg) {
/* Trigger on +ve edge. */
conv = PCI230_ADC_TRIG_EXTP;
} else {
@@ -2045,31 +2090,39 @@ static void pci230_ai_start(struct comedi_device *dev,
}
break;
case TRIG_INT:
- /* Use CT2 output for software trigger due to problems
- * in differential mode on PCI230/260. */
+ /*
+ * Use CT2 output for software trigger due to problems
+ * in differential mode on PCI230/260.
+ */
conv = PCI230_ADC_TRIG_Z2CT2;
break;
}
- devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
- | conv;
+ devpriv->adccon =
+ (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv;
outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
if (cmd->convert_src == TRIG_INT)
async->inttrig = pci230_ai_inttrig_convert;
- /* Update FIFO interrupt trigger level, which is currently
- * set to "full". */
+ /*
+ * Update FIFO interrupt trigger level, which is currently
+ * set to "full".
+ */
pci230_ai_update_fifo_trigger_level(dev, s);
if (cmd->convert_src == TRIG_TIMER) {
/* Update timer gates. */
unsigned char zgat;
if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Conversion timer CT2 needs to be gated by
- * inverted output of monostable CT2. */
+ /*
+ * Conversion timer CT2 needs to be gated by
+ * inverted output of monostable CT2.
+ */
zgat = GAT_CONFIG(2, GAT_NOUTNM2);
} else {
- /* Conversion timer CT2 needs to be gated on
- * continuously. */
+ /*
+ * Conversion timer CT2 needs to be gated on
+ * continuously.
+ */
zgat = GAT_CONFIG(2, GAT_VCC);
}
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
@@ -2111,11 +2164,13 @@ static void pci230_ai_start(struct comedi_device *dev,
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- /* Scan period timer CT1 needs to be
- * gated on to start counting. */
+ /*
+ * Scan period timer CT1 needs to be
+ * gated on to start counting.
+ */
zgat = GAT_CONFIG(1, GAT_VCC);
- outb(zgat, devpriv->iobase1
- + PCI230_ZGAT_SCE);
+ outb(zgat, devpriv->iobase1 +
+ PCI230_ZGAT_SCE);
break;
case TRIG_INT:
async->inttrig =
@@ -2163,12 +2218,12 @@ static void pci230_handle_ai(struct comedi_device *dev,
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else if (devpriv->ai_scan_count == 0) {
todo = 0;
- } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
- || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL) ||
+ (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
- todo = (devpriv->ai_scan_count * scanlen)
- - devpriv->ai_scan_pos;
+ todo = (devpriv->ai_scan_count * scanlen) -
+ devpriv->ai_scan_pos;
if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
}
@@ -2179,24 +2234,26 @@ static void pci230_handle_ai(struct comedi_device *dev,
if (fifoamount == 0) {
/* Read FIFO state. */
status_fifo = inw(dev->iobase + PCI230_ADCCON);
- if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
- /* Report error otherwise FIFO overruns will go
- * unnoticed by the caller. */
- comedi_error(dev, "AI FIFO overrun");
+ if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) {
+ /*
+ * Report error otherwise FIFO overruns will go
+ * unnoticed by the caller.
+ */
+ dev_err(dev->class_dev, "AI FIFO overrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
break;
- } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
+ } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) {
/* FIFO empty. */
break;
- } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
+ } else if (status_fifo & PCI230_ADC_FIFO_HALF) {
/* FIFO half full. */
fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
/* FIFO not empty. */
if (devpriv->hwver > 0) {
/* Read PCI230+/260+ ADC FIFO level. */
- fifoamount = inw(dev->iobase
- + PCI230P_ADCFFLEV);
+ fifoamount =
+ inw(dev->iobase + PCI230P_ADCFFLEV);
if (fifoamount == 0) {
/* Shouldn't happen. */
break;
@@ -2209,7 +2266,7 @@ static void pci230_handle_ai(struct comedi_device *dev,
/* Read sample and store in Comedi's circular buffer. */
if (comedi_buf_put(s, pci230_ai_read(dev)) == 0) {
events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- comedi_error(dev, "AI buffer overflow");
+ dev_err(dev->class_dev, "AI buffer overflow\n");
break;
}
fifoamount--;
@@ -2229,8 +2286,8 @@ static void pci230_handle_ai(struct comedi_device *dev,
events |= COMEDI_CB_BLOCK;
}
async->events |= events;
- if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
- COMEDI_CB_OVERFLOW)) != 0) {
+ if (async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) {
/* disable hardware conversions */
pci230_ai_stop(dev, s);
} else {
@@ -2255,8 +2312,10 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* Determine which shared resources are needed.
*/
res_mask = 0;
- /* Need Z2-CT2 to supply a conversion trigger source at a high
- * logic level, even if not doing timed conversions. */
+ /*
+ * Need Z2-CT2 to supply a conversion trigger source at a high
+ * logic level, even if not doing timed conversions.
+ */
res_mask |= (1U << RES_Z2CT2);
if (cmd->scan_begin_src != TRIG_FOLLOW) {
/* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
@@ -2278,7 +2337,8 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ai_scan_count = 0;
devpriv->ai_scan_pos = 0; /* Position within scan. */
- /* Steps;
+ /*
+ * Steps:
* - Set channel scan list.
* - Set channel gains.
* - Enable and reset FIFO, specify uni/bip, se/diff, and set
@@ -2323,20 +2383,24 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (diff) {
gainshift = 2 * chan;
if (devpriv->hwver == 0) {
- /* Original PCI230/260 expects both inputs of
- * the differential channel to be enabled. */
+ /*
+ * Original PCI230/260 expects both inputs of
+ * the differential channel to be enabled.
+ */
adcen |= 3 << gainshift;
} else {
- /* PCI230+/260+ expects only one input of the
- * differential channel to be enabled. */
+ /*
+ * PCI230+/260+ expects only one input of the
+ * differential channel to be enabled.
+ */
adcen |= 1 << gainshift;
}
} else {
gainshift = (chan & ~1);
adcen |= 1 << chan;
}
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
- | (pci230_ai_gain[range] << gainshift);
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
+ (pci230_ai_gain[range] << gainshift);
}
/* Set channel scan list. */
@@ -2345,43 +2409,53 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* Set channel gains. */
outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
- /* Set counter/timer 2 output high for use as the initial start
- * conversion source. */
+ /*
+ * Set counter/timer 2 output high for use as the initial start
+ * conversion source.
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
- /* Temporarily use CT2 output as conversion trigger source and
- * temporarily set FIFO interrupt trigger level to 'full'. */
+ /*
+ * Temporarily use CT2 output as conversion trigger source and
+ * temporarily set FIFO interrupt trigger level to 'full'.
+ */
adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
- /* Enable and reset FIFO, specify FIFO trigger level full, specify
+ /*
+ * Enable and reset FIFO, specify FIFO trigger level full, specify
* uni/bip, se/diff, and temporarily set the start conversion source
* to CT2 output. Note that CT2 output is currently high, and this
* will produce a false conversion trigger on some versions of the
- * PCI230/260, but that will be dealt with later. */
+ * PCI230/260, but that will be dealt with later.
+ */
devpriv->adccon = adccon;
outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
- /* Delay */
- /* Failure to include this will result in the first few channels'-worth
+ /*
+ * Delay -
+ * Failure to include this will result in the first few channels'-worth
* of data being corrupt, normally manifesting itself by large negative
* voltages. It seems the board needs time to settle between the first
* FIFO reset (above) and the second FIFO reset (below). Setting the
* channel gains and scan list _before_ the first FIFO reset also
- * helps, though only slightly. */
- udelay(25);
+ * helps, though only slightly.
+ */
+ usleep_range(25, 100);
/* Reset FIFO again. */
outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
if (cmd->convert_src == TRIG_TIMER) {
- /* Set up CT2 as conversion timer, but gate it off for now.
+ /*
+ * Set up CT2 as conversion timer, but gate it off for now.
* Note, counter/timer output 2 can be monitored on the
- * connector: PCI230 pin 21, PCI260 pin 18. */
+ * connector: PCI230 pin 21, PCI260 pin 18.
+ */
zgat = GAT_CONFIG(2, GAT_GND);
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
/* Set counter/timer 2 to the specified conversion period. */
pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->flags);
if (cmd->scan_begin_src != TRIG_FOLLOW) {
/*
* Set up monostable on CT0 output for scan timing. A
@@ -2398,8 +2472,8 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
zgat = GAT_CONFIG(0, GAT_VCC);
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
- ((uint64_t) cmd->convert_arg
- * cmd->scan_end_arg),
+ ((uint64_t)cmd->convert_arg *
+ cmd->scan_end_arg),
TRIG_ROUND_UP);
if (cmd->scan_begin_src == TRIG_TIMER) {
/*
@@ -2412,9 +2486,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK);
+ cmd->flags);
}
}
}
@@ -2452,9 +2524,11 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
valid_status_int = devpriv->int_en & status_int;
- /* Disable triggered interrupts.
+ /*
+ * Disable triggered interrupts.
* (Only those interrupts that need re-enabling, are, later in the
- * handler). */
+ * handler).
+ */
devpriv->ier = devpriv->int_en & ~status_int;
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
devpriv->intr_running = 1;
@@ -2469,19 +2543,19 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
* two.
*/
- if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
+ if (valid_status_int & PCI230_INT_ZCLK_CT1) {
s = dev->write_subdev;
pci230_handle_ao_nofifo(dev, s);
comedi_event(dev, s);
}
- if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
+ if (valid_status_int & PCI230P2_INT_DAC) {
s = dev->write_subdev;
pci230_handle_ao_fifo(dev, s);
comedi_event(dev, s);
}
- if ((valid_status_int & PCI230_INT_ADC) != 0) {
+ if (valid_status_int & PCI230_INT_ADC) {
s = dev->read_subdev;
pci230_handle_ai(dev, s);
comedi_event(dev, s);
@@ -2511,8 +2585,10 @@ static bool pci230_match_pci_board(const struct pci230_board *board,
/* Looking for a '+' model. First check length of registers. */
if (pci_resource_len(pci_dev, 3) < 32)
return false; /* Not a '+' model. */
- /* TODO: temporarily enable PCI device and read the hardware version
- * register. For now, assume it's okay. */
+ /*
+ * TODO: temporarily enable PCI device and read the hardware version
+ * register. For now, assume it's okay.
+ */
return true;
}
@@ -2601,8 +2677,10 @@ static int pci230_attach_common(struct comedi_device *dev,
if (rc)
return rc;
- /* Read base addresses of the PCI230's two I/O regions from PCI
- * configuration register. */
+ /*
+ * Read base addresses of the PCI230's two I/O regions from PCI
+ * configuration register.
+ */
iobase1 = pci_resource_start(pci_dev, 2);
iobase2 = pci_resource_start(pci_dev, 3);
dev_dbg(dev->class_dev,
@@ -2612,8 +2690,10 @@ static int pci230_attach_common(struct comedi_device *dev,
dev->iobase = iobase2;
/* Read bits of DACCON register - only the output range. */
devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
- /* Read hardware version register and set extended function register
- * if they exist. */
+ /*
+ * Read hardware version register and set extended function register
+ * if they exist.
+ */
if (pci_resource_len(pci_dev, 3) >= 32) {
unsigned short extfunc = 0;
@@ -2627,25 +2707,29 @@ static int pci230_attach_common(struct comedi_device *dev,
}
if (devpriv->hwver > 0) {
if (!thisboard->have_dio) {
- /* No DIO ports. Route counters' external gates
+ /*
+ * No DIO ports. Route counters' external gates
* to the EXTTRIG signal (PCI260+ pin 17).
* (Otherwise, they would be routed to DIO
* inputs PC0, PC1 and PC2 which don't exist
- * on PCI260[+].) */
+ * on PCI260[+].)
+ */
extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
}
- if ((thisboard->ao_chans > 0)
- && (devpriv->hwver >= 2)) {
+ if ((thisboard->ao_chans > 0) &&
+ (devpriv->hwver >= 2)) {
/* Enable DAC FIFO functionality. */
extfunc |= PCI230P2_EXTFUNC_DACFIFO;
}
}
outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
- if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
- /* Temporarily enable DAC FIFO, reset it and disable
- * FIFO wraparound. */
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
- | PCI230P2_DAC_FIFO_RESET,
+ if (extfunc & PCI230P2_EXTFUNC_DACFIFO) {
+ /*
+ * Temporarily enable DAC FIFO, reset it and disable
+ * FIFO wraparound.
+ */
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN |
+ PCI230P2_DAC_FIFO_RESET,
dev->iobase + PCI230_DACCON);
/* Clear DAC FIFO channel enable register. */
outw(0, dev->iobase + PCI230P2_DACEN);
@@ -2657,8 +2741,8 @@ static int pci230_attach_common(struct comedi_device *dev,
outb(0, devpriv->iobase1 + PCI230_INT_SCE);
/* Set ADC to a reasonable state. */
devpriv->adcg = 0;
- devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
- | PCI230_ADC_IR_BIP;
+ devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE |
+ PCI230_ADC_IR_BIP;
outw(1 << 0, dev->iobase + PCI230_ADCEN);
outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
@@ -2682,13 +2766,13 @@ static int pci230_attach_common(struct comedi_device *dev,
s->n_chan = thisboard->ai_chans;
s->maxdata = (1 << thisboard->ai_bits) - 1;
s->range_table = &pci230_ai_range;
- s->insn_read = &pci230_ai_rinsn;
+ s->insn_read = pci230_ai_rinsn;
s->len_chanlist = 256; /* but there are restrictions. */
if (dev->irq) {
dev->read_subdev = s;
s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = &pci230_ai_cmd;
- s->do_cmdtest = &pci230_ai_cmdtest;
+ s->do_cmd = pci230_ai_cmd;
+ s->do_cmdtest = pci230_ai_cmdtest;
s->cancel = pci230_ai_cancel;
}
@@ -2700,14 +2784,14 @@ static int pci230_attach_common(struct comedi_device *dev,
s->n_chan = thisboard->ao_chans;
s->maxdata = (1 << thisboard->ao_bits) - 1;
s->range_table = &pci230_ao_range;
- s->insn_write = &pci230_ao_winsn;
- s->insn_read = &pci230_ao_rinsn;
+ s->insn_write = pci230_ao_winsn;
+ s->insn_read = pci230_ao_rinsn;
s->len_chanlist = thisboard->ao_chans;
if (dev->irq) {
dev->write_subdev = s;
s->subdev_flags |= SDF_CMD_WRITE;
- s->do_cmd = &pci230_ao_cmd;
- s->do_cmdtest = &pci230_ao_cmdtest;
+ s->do_cmd = pci230_ao_cmd;
+ s->do_cmdtest = pci230_ao_cmdtest;
s->cancel = pci230_ao_cancel;
}
} else {
@@ -2748,7 +2832,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
static int pci230_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context_unused)
{
struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
int rc;
diff --git a/drivers/staging/comedi/drivers/amplc_pci236.c b/drivers/staging/comedi/drivers/amplc_pci236.c
new file mode 100644
index 000000000000..436aebaf7621
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci236.c
@@ -0,0 +1,161 @@
+/*
+ * comedi/drivers/amplc_pci236.c
+ * Driver for Amplicon PCI236 DIO boards.
+ *
+ * Copyright (C) 2002-2014 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
+/*
+ * Driver: amplc_pci236
+ * Description: Amplicon PCI236
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PCI236 (amplc_pci236)
+ * Updated: Fri, 25 Jul 2014 15:32:40 +0000
+ * Status: works
+ *
+ * Configuration options:
+ * none
+ *
+ * Manual configuration of PCI board (PCI236) is not supported; it is
+ * configured automatically.
+ *
+ * The PCI236 board has a single 8255 appearing as subdevice 0.
+ *
+ * Subdevice 1 pretends to be a digital input device, but it always
+ * returns 0 when read. However, if you run a command with
+ * scan_begin_src=TRIG_EXT, a rising edge on port C bit 3 acts as an
+ * external trigger, which can be used to wake up tasks. This is like
+ * the comedi_parport device. If no interrupt is connected, then
+ * subdevice 1 is unused.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include "../comedidev.h"
+
+#include "amplc_pc236.h"
+#include "plx9052.h"
+
+/* Disable, and clear, interrupts */
+#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1POL | \
+ PLX9052_INTCSR_LI2POL | \
+ PLX9052_INTCSR_LI1SEL | \
+ PLX9052_INTCSR_LI1CLRINT)
+
+/* Enable, and clear, interrupts */
+#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB | \
+ PLX9052_INTCSR_LI1POL | \
+ PLX9052_INTCSR_LI2POL | \
+ PLX9052_INTCSR_PCIENAB | \
+ PLX9052_INTCSR_LI1SEL | \
+ PLX9052_INTCSR_LI1CLRINT)
+
+static void pci236_intr_update_cb(struct comedi_device *dev, bool enable)
+{
+ struct pc236_private *devpriv = dev->private;
+
+ /* this will also clear the "local interrupt 1" latch */
+ outl(enable ? PCI236_INTR_ENABLE : PCI236_INTR_DISABLE,
+ devpriv->lcr_iobase + PLX9052_INTCSR);
+}
+
+static bool pci236_intr_chk_clr_cb(struct comedi_device *dev)
+{
+ struct pc236_private *devpriv = dev->private;
+
+ /* check if interrupt occurred */
+ if (!(inl(devpriv->lcr_iobase + PLX9052_INTCSR) &
+ PLX9052_INTCSR_LI1STAT))
+ return false;
+ /* clear the interrupt */
+ pci236_intr_update_cb(dev, devpriv->enable_irq);
+ return true;
+}
+
+static const struct pc236_board pc236_pci_board = {
+ .name = "pci236",
+ .intr_update_cb = pci236_intr_update_cb,
+ .intr_chk_clr_cb = pci236_intr_chk_clr_cb,
+};
+
+static int pci236_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ struct pc236_private *devpriv;
+ unsigned long iobase;
+ int ret;
+
+ dev_info(dev->class_dev, "amplc_pci236: attach pci %s\n",
+ pci_name(pci_dev));
+
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
+ return -ENOMEM;
+
+ dev->board_ptr = &pc236_pci_board;
+ dev->board_name = pc236_pci_board.name;
+ ret = comedi_pci_enable(dev);
+ if (ret)
+ return ret;
+
+ devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
+ iobase = pci_resource_start(pci_dev, 2);
+ return amplc_pc236_common_attach(dev, iobase, pci_dev->irq,
+ IRQF_SHARED);
+}
+
+static void pci236_detach(struct comedi_device *dev)
+{
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ comedi_pci_disable(dev);
+}
+
+static struct comedi_driver amplc_pci236_driver = {
+ .driver_name = "amplc_pci236",
+ .module = THIS_MODULE,
+ .auto_attach = pci236_auto_attach,
+ .detach = pci236_detach,
+};
+
+static const struct pci_device_id pci236_pci_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x0009) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, pci236_pci_table);
+
+static int amplc_pci236_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &amplc_pci236_driver,
+ id->driver_data);
+}
+
+static struct pci_driver amplc_pci236_pci_driver = {
+ .name = "amplc_pci236",
+ .id_table = pci236_pci_table,
+ .probe = &amplc_pci236_pci_probe,
+ .remove = comedi_pci_auto_unconfig,
+};
+
+module_comedi_pci_driver(amplc_pci236_driver, amplc_pci236_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PCI236 DIO boards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c
index 93ed03ee416a..748a6b108f32 100644
--- a/drivers/staging/comedi/drivers/amplc_pci263.c
+++ b/drivers/staging/comedi/drivers/amplc_pci263.c
@@ -37,11 +37,6 @@ The state of the outputs can be read.
#include "../comedidev.h"
-#define PCI263_DRIVER_NAME "amplc_pci263"
-
-/* PCI263 PCI configuration register information */
-#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
-
static int pci263_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -88,14 +83,14 @@ static int pci263_auto_attach(struct comedi_device *dev,
}
static struct comedi_driver amplc_pci263_driver = {
- .driver_name = PCI263_DRIVER_NAME,
+ .driver_name = "amplc_pci263",
.module = THIS_MODULE,
.auto_attach = pci263_auto_attach,
.detach = comedi_pci_disable,
};
static const struct pci_device_id pci263_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x000c) },
{0}
};
MODULE_DEVICE_TABLE(pci, pci263_pci_table);
@@ -108,7 +103,7 @@ static int amplc_pci263_pci_probe(struct pci_dev *dev,
}
static struct pci_driver amplc_pci263_pci_driver = {
- .name = PCI263_DRIVER_NAME,
+ .name = "amplc_pci263",
.id_table = pci263_pci_table,
.probe = &amplc_pci263_pci_probe,
.remove = comedi_pci_auto_unconfig,
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index eb1b92d72e87..853733e28845 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -46,8 +46,6 @@ Status: experimental
#include "comedi_fc.h"
#include "8253.h"
-#define DAS16CS_SIZE 18
-
#define DAS16CS_ADC_DATA 0
#define DAS16CS_DIO_MUX 2
#define DAS16CS_MISC1 4
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 7377da1aff7c..4a7bd4e5dd72 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -461,7 +461,6 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
break;
default:
return -EINVAL;
- break;
}
return insn->n;
}
@@ -622,7 +621,7 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
static const int caldac_8800_udelay = 1;
if (address >= num_caldac_channels) {
- comedi_error(dev, "illegal caldac channel");
+ dev_err(dev->class_dev, "illegal caldac channel\n");
return -1;
}
@@ -774,9 +773,8 @@ static int cb_pcidas_trimpot_write(struct comedi_device *dev,
trimpot_8402_write(dev, channel, value);
break;
default:
- comedi_error(dev, "driver bug?");
+ dev_err(dev->class_dev, "driver bug?\n");
return -1;
- break;
}
return 1;
@@ -1251,9 +1249,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
break;
default:
spin_unlock_irqrestore(&dev->spinlock, flags);
- comedi_error(dev, "error setting dac pacer source");
+ dev_err(dev->class_dev, "error setting dac pacer source\n");
return -1;
- break;
}
spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -1303,7 +1300,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
if (cmd->stop_src == TRIG_NONE ||
(cmd->stop_src == TRIG_COUNT
&& devpriv->ao_count)) {
- comedi_error(dev, "dac fifo underflow");
+ dev_err(dev->class_dev, "dac fifo underflow\n");
async->events |= COMEDI_CB_ERROR;
}
async->events |= COMEDI_CB_EOA;
@@ -1414,8 +1411,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
devpriv->control_status + INT_ADCFIFO);
spin_unlock_irqrestore(&dev->spinlock, flags);
} else if (status & EOAI) {
- comedi_error(dev,
- "bug! encountered end of acquisition interrupt?");
+ dev_err(dev->class_dev,
+ "bug! encountered end of acquisition interrupt?\n");
/* clear EOA interrupt latch */
spin_lock_irqsave(&dev->spinlock, flags);
outw(devpriv->adc_fifo_bits | EOAI,
@@ -1424,7 +1421,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
}
/* check for fifo overflow */
if (status & LADFUL) {
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
/* clear overflow interrupt latch */
spin_lock_irqsave(&dev->spinlock, flags);
outw(devpriv->adc_fifo_bits | LADFUL,
@@ -1474,11 +1471,12 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
outl(INTCSR_INBOX_INTR_STATUS,
devpriv->s5933_config + AMCC_OP_REG_INTCSR);
- if (request_irq(pcidev->irq, cb_pcidas_interrupt,
- IRQF_SHARED, dev->driver->driver_name, dev)) {
+ ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret) {
dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
pcidev->irq);
- return -EINVAL;
+ return ret;
}
dev->irq = pcidev->irq;
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 035c3a176005..fa12614cef2a 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -80,8 +80,6 @@ TODO:
make ao fifo size adjustable like ai fifo
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -179,7 +177,7 @@ enum read_write_registers {
DAC_FIFO_REG = 0x300,
};
-/* devpriv->dio_counter_iobase registers */
+/* dev->mmio registers */
enum dio_counter_registers {
DIO_8255_OFFSET = 0x0,
DO_REG = 0x20,
@@ -636,8 +634,8 @@ static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
{
if (board->layout == LAYOUT_4020)
return MAX_AI_DMA_RING_COUNT;
- else
- return MIN_AI_DMA_RING_COUNT;
+
+ return MIN_AI_DMA_RING_COUNT;
}
static const int bytes_in_sample = 2;
@@ -1045,9 +1043,9 @@ static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
if ((thisboard->layout == LAYOUT_64XX && !use_differential) ||
(thisboard->layout == LAYOUT_60XX && use_differential))
return ADC_SE_DIFF_BIT;
- else
- return 0;
-};
+
+ return 0;
+}
struct ext_clock_info {
/* master clock divisor to use for scans with external master clock */
@@ -1064,12 +1062,11 @@ struct pcidas64_private {
/* base addresses (ioremapped) */
void __iomem *plx9080_iobase;
void __iomem *main_iobase;
- void __iomem *dio_counter_iobase;
/* local address (used by dma controller) */
uint32_t local0_iobase;
uint32_t local1_iobase;
/* number of analog input samples remaining */
- volatile unsigned int ai_count;
+ unsigned int ai_count;
/* dma buffers for analog input */
uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
/* physical addresses of ai dma buffers */
@@ -1081,7 +1078,7 @@ struct pcidas64_private {
dma_addr_t ai_dma_desc_bus_addr;
/* index of the ai dma descriptor/buffer
* that is currently being used */
- volatile unsigned int ai_dma_index;
+ unsigned int ai_dma_index;
/* dma buffers for analog output */
uint16_t *ao_buffer[AO_DMA_RING_COUNT];
/* physical addresses of ao dma buffers */
@@ -1089,35 +1086,35 @@ struct pcidas64_private {
struct plx_dma_desc *ao_dma_desc;
dma_addr_t ao_dma_desc_bus_addr;
/* keeps track of buffer where the next ao sample should go */
- volatile unsigned int ao_dma_index;
+ unsigned int ao_dma_index;
/* number of analog output samples remaining */
- volatile unsigned long ao_count;
+ unsigned long ao_count;
/* remember what the analog outputs are set to, to allow readback */
- volatile unsigned int ao_value[2];
+ unsigned int ao_value[2];
unsigned int hw_revision; /* stc chip hardware revision number */
/* last bits sent to INTR_ENABLE_REG register */
- volatile unsigned int intr_enable_bits;
+ unsigned int intr_enable_bits;
/* last bits sent to ADC_CONTROL1_REG register */
- volatile uint16_t adc_control1_bits;
+ uint16_t adc_control1_bits;
/* last bits sent to FIFO_SIZE_REG register */
- volatile uint16_t fifo_size_bits;
+ uint16_t fifo_size_bits;
/* last bits sent to HW_CONFIG_REG register */
- volatile uint16_t hw_config_bits;
- volatile uint16_t dac_control1_bits;
+ uint16_t hw_config_bits;
+ uint16_t dac_control1_bits;
/* last bits written to plx9080 control register */
- volatile uint32_t plx_control_bits;
+ uint32_t plx_control_bits;
/* last bits written to plx interrupt control and status register */
- volatile uint32_t plx_intcsr_bits;
+ uint32_t plx_intcsr_bits;
/* index of calibration source readable through ai ch0 */
- volatile int calibration_source;
+ int calibration_source;
/* bits written to i2c calibration/range register */
- volatile uint8_t i2c_cal_range_bits;
+ uint8_t i2c_cal_range_bits;
/* configure digital triggers to trigger on falling edge */
- volatile unsigned int ext_trig_falling;
+ unsigned int ext_trig_falling;
/* states of various devices stored to enable read-back */
unsigned int ad8402_state[2];
unsigned int caldac_state[8];
- volatile short ai_cmd_running;
+ short ai_cmd_running;
unsigned int ai_fifo_segment_length;
struct ext_clock_info ext_clock;
unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
@@ -1160,7 +1157,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
bits = 0x700;
break;
default:
- comedi_error(dev, "bug! in ai_range_bits_6xxx");
+ dev_err(dev->class_dev, "bug! in %s\n", __func__);
break;
}
if (range->min == 0)
@@ -1180,16 +1177,16 @@ static unsigned int hw_revision(const struct comedi_device *dev,
}
static void set_dac_range_bits(struct comedi_device *dev,
- volatile uint16_t *bits, unsigned int channel,
+ uint16_t *bits, unsigned int channel,
unsigned int range)
{
const struct pcidas64_board *thisboard = comedi_board(dev);
unsigned int code = thisboard->ao_range_code[range];
if (channel > 1)
- comedi_error(dev, "bug! bad channel?");
+ dev_err(dev->class_dev, "bug! bad channel?\n");
if (code & ~0x3)
- comedi_error(dev, "bug! bad range code?");
+ dev_err(dev->class_dev, "bug! bad range code?\n");
*bits &= ~(0x3 << (2 * channel));
*bits |= code << (2 * channel);
@@ -1531,10 +1528,10 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
static inline void warn_external_queue(struct comedi_device *dev)
{
- comedi_error(dev,
- "AO command and AI external channel queue cannot be used simultaneously.");
- comedi_error(dev,
- "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
+ dev_err(dev->class_dev,
+ "AO command and AI external channel queue cannot be used simultaneously\n");
+ dev_err(dev->class_dev,
+ "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n");
}
/* Their i2c requires a huge delay on setting clock or data high for some reason */
@@ -1648,7 +1645,8 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
/* get acknowledge */
if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
+ dev_err(dev->class_dev, "%s failed: no acknowledge\n",
+ __func__);
i2c_stop(dev);
return;
}
@@ -1656,7 +1654,8 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
for (i = 0; i < length; i++) {
i2c_write_byte(dev, data[i]);
if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
+ dev_err(dev->class_dev, "%s failed: no acknowledge\n",
+ __func__);
i2c_stop(dev);
return;
}
@@ -1769,6 +1768,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
* as it is very slow */
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
@@ -1796,8 +1796,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
return ret;
if (thisboard->layout == LAYOUT_4020)
- data[n] = readl(devpriv->dio_counter_iobase +
- ADC_FIFO_REG) & 0xffff;
+ data[n] = readl(dev->mmio + ADC_FIFO_REG) & 0xffff;
else
data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
}
@@ -1874,7 +1873,6 @@ static int ai_config_master_clock_4020(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
data[4] = divisor;
@@ -1890,10 +1888,8 @@ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
switch (thisboard->layout) {
case LAYOUT_4020:
return ai_config_master_clock_4020(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return -EINVAL;
@@ -1907,16 +1903,12 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
switch (id) {
case INSN_CONFIG_ALT_SOURCE:
return ai_config_calibration_source(dev, data);
- break;
case INSN_CONFIG_BLOCK_SIZE:
return ai_config_block_size(dev, data);
- break;
case INSN_CONFIG_TIMER_1:
return ai_config_master_clock(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return -EINVAL;
}
@@ -1991,8 +1983,6 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
scan_divisor = min_scan_divisor;
cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
}
-
- return;
}
static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
@@ -2162,8 +2152,8 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd)
if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
return 1;
- else
- return 0;
+
+ return 0;
}
static void setup_sample_counters(struct comedi_device *dev,
@@ -2224,7 +2214,6 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
break;
default:
return 0;
- break;
}
return count - 3;
}
@@ -2243,7 +2232,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
divisor = devpriv->ext_clock.divisor;
break;
default: /* should never happen */
- comedi_error(dev, "bug! failed to set ai pacing!");
+ dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
divisor = 1000;
break;
}
@@ -2454,6 +2443,7 @@ static int setup_channel_queue(struct comedi_device *dev,
* as it is very slow */
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
@@ -2694,7 +2684,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
}
for (i = 0; read_code != write_code && i < max_transfer;) {
- fifo_data = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG);
+ fifo_data = readl(dev->mmio + ADC_FIFO_REG);
cfc_write_to_buffer(s, fifo_data & 0xffff);
i++;
if (i < max_transfer) {
@@ -2775,7 +2765,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
/* check for fifo overrun */
if (status & ADC_OVERRUN_BIT) {
- comedi_error(dev, "fifo overrun");
+ dev_err(dev->class_dev, "fifo overrun\n");
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
}
/* spin lock makes sure no one else changes plx dma control reg */
@@ -3138,7 +3128,8 @@ static void set_dac_select_reg(struct comedi_device *dev,
first_channel = CR_CHAN(cmd->chanlist[0]);
last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
if (last_channel < first_channel)
- comedi_error(dev, "bug! last ao channel < first ao channel");
+ dev_err(dev->class_dev,
+ "bug! last ao channel < first ao channel\n");
bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
@@ -3161,7 +3152,7 @@ static void set_dac_interval_regs(struct comedi_device *dev,
divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
if (divisor > max_counter_value) {
- comedi_error(dev, "bug! ao divisor too big");
+ dev_err(dev->class_dev, "bug! ao divisor too big\n");
divisor = max_counter_value;
}
writew(divisor & 0xffff,
@@ -3381,32 +3372,31 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int dio_callback(int dir, int port, int data, unsigned long arg)
{
void __iomem *iobase = (void __iomem *)arg;
+
if (dir) {
writeb(data, iobase + port);
return 0;
- } else {
- return readb(iobase + port);
}
+ return readb(iobase + port);
}
static int dio_callback_4020(int dir, int port, int data, unsigned long arg)
{
void __iomem *iobase = (void __iomem *)arg;
+
if (dir) {
writew(data, iobase + 2 * port);
return 0;
- } else {
- return readw(iobase + 2 * port);
}
+ return readw(iobase + 2 * port);
}
static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
unsigned int bits;
- bits = readb(devpriv->dio_counter_iobase + DI_REG);
+ bits = readb(dev->mmio + DI_REG);
bits &= 0xf;
data[1] = bits;
data[0] = 0;
@@ -3419,10 +3409,8 @@ static int do_wbits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
+ writeb(s->state, dev->mmio + DO_REG);
data[1] = s->state;
@@ -3434,15 +3422,13 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writeb(s->io_bits,
- devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+ writeb(s->io_bits, dev->mmio + DIO_DIRECTION_60XX_REG);
return insn->n;
}
@@ -3452,14 +3438,10 @@ static int dio_60xx_wbits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data)) {
- writeb(s->state,
- devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
- }
+ if (comedi_dio_update_state(s, data))
+ writeb(s->state, dev->mmio + DIO_DATA_60XX_REG);
- data[1] = readb(devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
+ data[1] = readb(dev->mmio + DIO_DATA_60XX_REG);
return insn->n;
}
@@ -3496,7 +3478,7 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
static const int caldac_8800_udelay = 1;
if (address >= num_caldac_channels) {
- comedi_error(dev, "illegal caldac channel");
+ dev_err(dev->class_dev, "illegal caldac channel\n");
return -1;
}
for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
@@ -3568,9 +3550,8 @@ static int caldac_i2c_write(struct comedi_device *dev,
serial_bytes[0] = GAIN_1_3;
break;
default:
- comedi_error(dev, "invalid caldac channel\n");
+ dev_err(dev->class_dev, "invalid caldac channel\n");
return -1;
- break;
}
serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
serial_bytes[2] = value & 0xff;
@@ -3863,8 +3844,7 @@ static int setup_subdevices(struct comedi_device *dev)
ret = subdev_8255_init(dev, s, dio_callback_4020,
(unsigned long)dio_8255_iobase);
} else {
- dio_8255_iobase =
- devpriv->dio_counter_iobase + DIO_8255_OFFSET;
+ dio_8255_iobase = dev->mmio + DIO_8255_OFFSET;
ret = subdev_8255_init(dev, s, dio_callback,
(unsigned long)dio_8255_iobase);
}
@@ -3965,10 +3945,9 @@ static int auto_attach(struct comedi_device *dev,
devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
devpriv->main_iobase = pci_ioremap_bar(pcidev, 2);
- devpriv->dio_counter_iobase = pci_ioremap_bar(pcidev, 3);
+ dev->mmio = pci_ioremap_bar(pcidev, 3);
- if (!devpriv->plx9080_iobase || !devpriv->main_iobase
- || !devpriv->dio_counter_iobase) {
+ if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !dev->mmio) {
dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
}
@@ -3997,12 +3976,13 @@ static int auto_attach(struct comedi_device *dev,
devpriv->hw_revision);
init_plx9080(dev);
init_stc_registers(dev);
- /* get irq */
- if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
- "cb_pcidas64", dev)) {
+
+ retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (retval) {
dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
pcidev->irq);
- return -EINVAL;
+ return retval;
}
dev->irq = pcidev->irq;
dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
@@ -4031,8 +4011,8 @@ static void detach(struct comedi_device *dev)
}
if (devpriv->main_iobase)
iounmap(devpriv->main_iobase);
- if (devpriv->dio_counter_iobase)
- iounmap(devpriv->dio_counter_iobase);
+ if (dev->mmio)
+ iounmap(dev->mmio);
/* free pci dma buffers */
for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
if (devpriv->ai_buffer[i])
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index 50e522e6e690..ccb9c72bc0c3 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -47,9 +47,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details.
/* Registers for the PCIM-DAS1602/16 */
-/* sizes of io regions (bytes) */
-#define BADR3_SIZE 16
-
/* DAC Offsets */
#define ADC_TRIG 0
#define DAC0_OFFSET 2
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 67a09aa6b721..845a67905ca6 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -146,10 +146,8 @@ static unsigned short fake_waveform(struct comedi_device *dev,
switch (channel) {
case SAWTOOTH_CHAN:
return fake_sawtooth(dev, range, current_time);
- break;
case SQUARE_CHAN:
return fake_squarewave(dev, range, current_time);
- break;
default:
break;
}
@@ -305,8 +303,8 @@ static int waveform_ai_cmd(struct comedi_device *dev,
struct comedi_cmd *cmd = &s->async->cmd;
if (cmd->flags & TRIG_RT) {
- comedi_error(dev,
- "commands at RT priority not supported in this driver");
+ dev_err(dev->class_dev,
+ "commands at RT priority not supported in this driver\n");
return -1;
}
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index 0a9c32e9db4a..f066fb06dc1d 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -30,8 +30,6 @@ Configuration Options: not applicable, uses comedi PCI auto config
#include "../comedidev.h"
-#define PCI_DEVICE_ID_PIO1616L 0x8172
-
/*
* Register map
*/
@@ -110,7 +108,7 @@ static int contec_pci_dio_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id contec_pci_dio_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, 0x8172) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index a8f6036ad82b..cd369cd40114 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -113,8 +113,8 @@ Configuration options: not applicable, uses PCI auto config
#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin"
-#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
-#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
/* Initialization bits for the Serial EEPROM Control Register */
#define DAQBOARD2000_SECRProgPinHi 0x8001767e
@@ -128,8 +128,8 @@ Configuration options: not applicable, uses PCI auto config
#define DAQBOARD2000_EEPROM_PRESENT 0x10000000
/* CPLD status bits */
-#define DAQBOARD2000_CPLD_INIT 0x0002
-#define DAQBOARD2000_CPLD_DONE 0x0004
+#define DAQBOARD2000_CPLD_INIT 0x0002
+#define DAQBOARD2000_CPLD_DONE 0x0004
static const struct comedi_lrange range_daqboard2000_ai = {
13, {
@@ -274,19 +274,16 @@ struct daqboard2000_private {
enum {
card_daqboard_2000
} card;
- void __iomem *daq;
void __iomem *plx;
unsigned int ao_readback[2];
};
static void writeAcqScanListEntry(struct comedi_device *dev, u16 entry)
{
- struct daqboard2000_private *devpriv = dev->private;
-
/* udelay(4); */
- writew(entry & 0x00ff, devpriv->daq + acqScanListFIFO);
+ writew(entry & 0x00ff, dev->mmio + acqScanListFIFO);
/* udelay(4); */
- writew((entry >> 8) & 0x00ff, devpriv->daq + acqScanListFIFO);
+ writew((entry >> 8) & 0x00ff, dev->mmio + acqScanListFIFO);
}
static void setup_sampling(struct comedi_device *dev, int chan, int gain)
@@ -338,10 +335,9 @@ static int daqboard2000_ai_status(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->daq + acqControl);
+ status = readw(dev->mmio + acqControl);
if (status & context)
return 0;
return -EBUSY;
@@ -352,22 +348,21 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct daqboard2000_private *devpriv = dev->private;
int gain, chan;
int ret;
int i;
writew(DAQBOARD2000_AcqResetScanListFifo |
DAQBOARD2000_AcqResetResultsFifo |
- DAQBOARD2000_AcqResetConfigPipe, devpriv->daq + acqControl);
+ DAQBOARD2000_AcqResetConfigPipe, dev->mmio + acqControl);
/*
* If pacer clock is not set to some high value (> 10 us), we
* risk multiple samples to be put into the result FIFO.
*/
/* 1 second, should be long enough */
- writel(1000000, devpriv->daq + acqPacerClockDivLow);
- writew(0, devpriv->daq + acqPacerClockDivHigh);
+ writel(1000000, dev->mmio + acqPacerClockDivLow);
+ writew(0, dev->mmio + acqPacerClockDivHigh);
gain = CR_RANGE(insn->chanspec);
chan = CR_CHAN(insn->chanspec);
@@ -379,15 +374,14 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
setup_sampling(dev, chan, gain);
/* Enable reading from the scanlist FIFO */
- writew(DAQBOARD2000_SeqStartScanList,
- devpriv->daq + acqControl);
+ writew(DAQBOARD2000_SeqStartScanList, dev->mmio + acqControl);
ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
DAQBOARD2000_AcqConfigPipeFull);
if (ret)
return ret;
- writew(DAQBOARD2000_AdcPacerEnable, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_AdcPacerEnable, dev->mmio + acqControl);
ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
DAQBOARD2000_AcqLogicScanning);
@@ -399,9 +393,9 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
if (ret)
return ret;
- data[i] = readw(devpriv->daq + acqResultsFIFO);
- writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
- writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
+ data[i] = readw(dev->mmio + acqResultsFIFO);
+ writew(DAQBOARD2000_AdcPacerDisable, dev->mmio + acqControl);
+ writew(DAQBOARD2000_SeqStopScanList, dev->mmio + acqControl);
}
return i;
@@ -427,11 +421,10 @@ static int daqboard2000_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int status;
- status = readw(devpriv->daq + dacControl);
+ status = readw(dev->mmio + dacControl);
if ((status & ((chan + 1) * 0x0010)) == 0)
return 0;
return -EBUSY;
@@ -453,11 +446,10 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
* OK, since it works OK without enabling the DAC's,
* let's keep it as simple as possible...
*/
- writew((chan + 2) * 0x0010 | 0x0001,
- devpriv->daq + dacControl);
+ writew((chan + 2) * 0x0010 | 0x0001, dev->mmio + dacControl);
udelay(1000);
#endif
- writew(data[i], devpriv->daq + dacSetting(chan));
+ writew(data[i], dev->mmio + dacSetting(chan));
ret = comedi_timeout(dev, s, insn, daqboard2000_ao_eoc, 0);
if (ret)
@@ -469,8 +461,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
* Since we never enabled the DAC's, we don't need
* to disable it...
*/
- writew((chan + 2) * 0x0010 | 0x0000,
- devpriv->daq + dacControl);
+ writew((chan + 2) * 0x0010 | 0x0000, dev->mmio + dacControl);
udelay(1000);
#endif
}
@@ -512,14 +503,13 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
{
- struct daqboard2000_private *devpriv = dev->private;
int result = 0;
int i;
int cpld;
/* timeout after 50 tries -> 5ms */
for (i = 0; i < 50; i++) {
- cpld = readw(devpriv->daq + 0x1000);
+ cpld = readw(dev->mmio + 0x1000);
if ((cpld & mask) == mask) {
result = 1;
break;
@@ -532,12 +522,11 @@ static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
{
- struct daqboard2000_private *devpriv = dev->private;
int result = 0;
udelay(10);
- writew(data, devpriv->daq + 0x1000);
- if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
+ writew(data, dev->mmio + 0x1000);
+ if ((readw(dev->mmio + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
DAQBOARD2000_CPLD_INIT) {
result = 1;
}
@@ -593,23 +582,21 @@ static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev)
static void daqboard2000_adcDisarm(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
-
/* Disable hardware triggers */
udelay(2);
writew(DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable,
- devpriv->daq + trigControl);
+ dev->mmio + trigControl);
udelay(2);
writew(DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable,
- devpriv->daq + trigControl);
+ dev->mmio + trigControl);
/* Stop the scan list FIFO from loading the configuration pipe */
udelay(2);
- writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_SeqStopScanList, dev->mmio + acqControl);
/* Stop the pacer clock */
udelay(2);
- writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_AdcPacerDisable, dev->mmio + acqControl);
/* Stop the input dma (abort channel 1) */
daqboard2000_adcStopDmaTransfer(dev);
@@ -617,23 +604,22 @@ static void daqboard2000_adcDisarm(struct comedi_device *dev)
static void daqboard2000_activateReferenceDacs(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int val;
int timeout;
/* Set the + reference dac value in the FPGA */
- writew(0x80 | DAQBOARD2000_PosRefDacSelect, devpriv->daq + refDacs);
+ writew(0x80 | DAQBOARD2000_PosRefDacSelect, dev->mmio + refDacs);
for (timeout = 0; timeout < 20; timeout++) {
- val = readw(devpriv->daq + dacControl);
+ val = readw(dev->mmio + dacControl);
if ((val & DAQBOARD2000_RefBusy) == 0)
break;
udelay(2);
}
/* Set the - reference dac value in the FPGA */
- writew(0x80 | DAQBOARD2000_NegRefDacSelect, devpriv->daq + refDacs);
+ writew(0x80 | DAQBOARD2000_NegRefDacSelect, dev->mmio + refDacs);
for (timeout = 0; timeout < 20; timeout++) {
- val = readw(devpriv->daq + dacControl);
+ val = readw(dev->mmio + dacControl);
if ((val & DAQBOARD2000_RefBusy) == 0)
break;
udelay(2);
@@ -673,9 +659,8 @@ static int daqboard2000_8255_cb(int dir, int port, int data,
if (dir) {
writew(data, mmio_base + port * 2);
return 0;
- } else {
- return readw(mmio_base + port * 2);
}
+ return readw(mmio_base + port * 2);
}
static const void *daqboard2000_find_boardinfo(struct comedi_device *dev,
@@ -719,8 +704,8 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
return result;
devpriv->plx = pci_ioremap_bar(pcidev, 0);
- devpriv->daq = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx || !devpriv->daq)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!devpriv->plx || !dev->mmio)
return -ENOMEM;
result = comedi_alloc_subdevices(dev, 3);
@@ -759,7 +744,7 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[2];
result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
- (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit));
+ (unsigned long)(dev->mmio + dioP2ExpansionIO8Bit));
if (result)
return result;
@@ -773,8 +758,8 @@ static void daqboard2000_detach(struct comedi_device *dev)
if (dev->irq)
free_irq(dev->irq, dev);
if (devpriv) {
- if (devpriv->daq)
- iounmap(devpriv->daq);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->plx)
iounmap(devpriv->plx);
}
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index c5e352fb5555..fcf916a80c8d 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -273,7 +273,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
else
data[n] = (1 << 15) - (lsb | (msb & 0x7f) << 8);
} else {
- comedi_error(dev, "bug! unknown ai encoding");
+ dev_err(dev->class_dev, "bug! unknown ai encoding\n");
return -1;
}
}
@@ -452,7 +452,6 @@ static int das08_counter_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 2;
}
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
index d94af09151b0..4ce3eb0a64cc 100644
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ b/drivers/staging/comedi/drivers/das08_pci.c
@@ -38,8 +38,6 @@
#include "das08.h"
-#define PCI_DEVICE_ID_PCIDAS08 0x0029
-
static const struct das08_board_struct das08_pci_boards[] = {
{
.name = "pci-das08",
@@ -90,7 +88,7 @@ static int das08_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id das08_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0029) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, das08_pci_table);
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 2feecf199f27..057bc16f8ddc 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -506,18 +506,18 @@ static void das16_ai_disable(struct comedi_device *dev)
static int disable_dma_on_even(struct comedi_device *dev)
{
struct das16_private_struct *devpriv = dev->private;
- int residue;
- int i;
static const int disable_limit = 100;
static const int enable_timeout = 100;
+ int residue;
+ int new_residue;
+ int i;
+ int j;
disable_dma(devpriv->dma_chan);
residue = get_dma_residue(devpriv->dma_chan);
for (i = 0; i < disable_limit && (residue % 2); ++i) {
- int j;
enable_dma(devpriv->dma_chan);
for (j = 0; j < enable_timeout; ++j) {
- int new_residue;
udelay(2);
new_residue = get_dma_residue(devpriv->dma_chan);
if (new_residue != residue)
@@ -729,14 +729,14 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
}
static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
- int rounding_flags)
+ unsigned int flags)
{
struct das16_private_struct *devpriv = dev->private;
unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG;
i8253_cascade_ns_to_timer(devpriv->clockbase,
&devpriv->divisor1, &devpriv->divisor2,
- &ns, rounding_flags);
+ &ns, flags);
i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
@@ -782,9 +782,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* set counter mode and counts */
- cmd->convert_arg =
- das16_set_pacer(dev, cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
/* enable counters */
byte = 0;
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index ec039fbff0f9..5b6998b54060 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -60,7 +60,6 @@ irq can be omitted, although the cmd interface will not work without it.
#include "8253.h"
#include "comedi_fc.h"
-#define DAS16M1_SIZE 16
#define DAS16M1_SIZE2 8
#define FIFO_SIZE 1024 /* 1024 sample fifo */
@@ -126,7 +125,7 @@ static const struct comedi_lrange range_das16m1 = {
struct das16m1_private_struct {
unsigned int control_state;
- volatile unsigned int adc_count; /* number of samples completed */
+ unsigned int adc_count; /* number of samples completed */
/* initial value in lower half of hardware conversion counter,
* needed to keep track of whether new count has been loaded into
* counter yet (loaded by first sample conversion) */
@@ -460,7 +459,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
* overrun interrupts, but we might as well try */
if (status & OVRUN) {
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
}
cfc_handle_events(dev, s);
@@ -477,7 +476,7 @@ static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s)
das16m1_handler(dev, status);
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static irqreturn_t das16m1_interrupt(int irq, void *d)
@@ -486,7 +485,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d)
struct comedi_device *dev = d;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
/* prevent race with comedi_poll() */
@@ -495,7 +494,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d)
status = inb(dev->iobase + DAS16M1_CS);
if ((status & (IRQDATA | OVRUN)) == 0) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
spin_unlock(&dev->spinlock);
return IRQ_NONE;
}
@@ -549,7 +548,7 @@ static int das16m1_attach(struct comedi_device *dev,
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], DAS16M1_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
/* Request an additional region for the 8255 */
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 859519026c4c..0cfca33965f6 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -421,7 +421,7 @@ static const struct das1800_board das1800_boards[] = {
};
struct das1800_private {
- volatile unsigned int count; /* number of data points left to be taken */
+ unsigned int count; /* number of data points left to be taken */
unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
int irq_dma_bits; /* bits for control register b */
@@ -430,7 +430,7 @@ struct das1800_private {
int dma_bits;
unsigned int dma0; /* dma channels used */
unsigned int dma1;
- volatile unsigned int dma_current; /* dma channel currently in use */
+ unsigned int dma_current; /* dma channel currently in use */
uint16_t *ai_buf0; /* pointers to dma buffers */
uint16_t *ai_buf1;
uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
@@ -492,7 +492,6 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
numPoints * sizeof(devpriv->ai_buf0[0]));
if (cmd->stop_src == TRIG_COUNT)
devpriv->count -= numPoints;
- return;
}
static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
@@ -517,8 +516,6 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
if (cmd->stop_src == TRIG_COUNT)
devpriv->count--;
}
-
- return;
}
/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
@@ -549,8 +546,6 @@ static void das1800_flush_dma_channel(struct comedi_device *dev,
cfc_write_array_to_buffer(s, buffer, num_bytes);
if (cmd->stop_src == TRIG_COUNT)
devpriv->count -= num_samples;
-
- return;
}
/* flushes remaining data from board when external trigger has stopped acquisition
@@ -583,8 +578,6 @@ static void das1800_flush_dma(struct comedi_device *dev,
/* get any remaining samples in fifo */
das1800_handle_fifo_not_empty(dev, s);
-
- return;
}
static void das1800_handle_dma(struct comedi_device *dev,
@@ -619,8 +612,6 @@ static void das1800_handle_dma(struct comedi_device *dev,
}
}
}
-
- return;
}
static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -663,7 +654,7 @@ static void das1800_ai_handler(struct comedi_device *dev)
if (status & OVF) {
/* clear OVF interrupt bit */
outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
- comedi_error(dev, "DAS1800 FIFO overflow");
+ dev_err(dev->class_dev, "FIFO overflow\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
@@ -696,7 +687,7 @@ static int das1800_ai_poll(struct comedi_device *dev,
das1800_ai_handler(dev);
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static irqreturn_t das1800_interrupt(int irq, void *d)
@@ -705,7 +696,7 @@ static irqreturn_t das1800_interrupt(int irq, void *d)
unsigned int status;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
@@ -1060,8 +1051,6 @@ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
enable_dma(devpriv->dma1);
}
release_dma_lock(lock_flags);
-
- return;
}
/* programs channel/gain list into card */
@@ -1088,8 +1077,6 @@ static void program_chanlist(struct comedi_device *dev,
}
outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- return;
}
/* analog input do_cmd */
@@ -1192,7 +1179,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
break;
}
if (i == timeout) {
- comedi_error(dev, "timeout");
+ dev_err(dev->class_dev, "timeout\n");
n = -ETIME;
goto exit;
}
@@ -1301,7 +1288,6 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
dev_err(dev->class_dev,
"dma 5,6 / 6,7 / or 7,5\n");
return -EINVAL;
- break;
}
if (request_dma(dma0, dev->driver->driver_name)) {
dev_err(dev->class_dev,
@@ -1343,84 +1329,60 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
static int das1800_probe(struct comedi_device *dev)
{
+ const struct das1800_board *board = comedi_board(dev);
+ int index;
int id;
- int board;
- id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
- board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
+ /* calc the offset to the boardinfo that was found by the core */
+ index = board - das1800_boards;
+ /* verify that the board id matches the boardinfo */
+ id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
switch (id) {
case 0x3:
- if (board == das1801st_da || board == das1802st_da ||
- board == das1701st_da || board == das1702st_da) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800st-da series\n");
- return das1801st;
+ if (index == das1801st_da || index == das1802st_da ||
+ index == das1701st_da || index == das1702st_da)
+ return index;
+ index = das1801st;
break;
case 0x4:
- if (board == das1802hr_da || board == das1702hr_da) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1802hr-da\n");
- return das1802hr;
+ if (index == das1802hr_da || index == das1702hr_da)
+ return index;
+ index = das1802hr;
break;
case 0x5:
- if (board == das1801ao || board == das1802ao ||
- board == das1701ao || board == das1702ao) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800ao series\n");
- return das1801ao;
+ if (index == das1801ao || index == das1802ao ||
+ index == das1701ao || index == das1702ao)
+ return index;
+ index = das1801ao;
break;
case 0x6:
- if (board == das1802hr || board == das1702hr) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1802hr\n");
- return das1802hr;
+ if (index == das1802hr || index == das1702hr)
+ return index;
+ index = das1802hr;
break;
case 0x7:
- if (board == das1801st || board == das1802st ||
- board == das1701st || board == das1702st) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800st series\n");
- return das1801st;
+ if (index == das1801st || index == das1802st ||
+ index == das1701st || index == das1702st)
+ return index;
+ index = das1801st;
break;
case 0x8:
- if (board == das1801hc || board == das1802hc) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800hc series\n");
- return das1801hc;
+ if (index == das1801hc || index == das1802hc)
+ return index;
+ index = das1801hc;
break;
default:
- printk
- (" Board model: probe returned 0x%x (unknown, please report)\n",
- id);
- return board;
+ dev_err(dev->class_dev,
+ "Board model: probe returned 0x%x (unknown, please report)\n",
+ id);
break;
}
- return -1;
+ dev_err(dev->class_dev,
+ "Board model (probed, not recommended): %s series\n",
+ das1800_boards[index].name);
+
+ return index;
}
static int das1800_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 6f7f8d531dd5..cbbb29797b83 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -65,7 +65,6 @@ cmd triggers supported:
#include "8253.h"
#include "comedi_fc.h"
-#define DAS800_SIZE 8
#define N_CHAN_AI 8 /* number of analog input channels */
/* Registers for the das800 */
@@ -686,7 +685,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], DAS800_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index ad7a5d53b97b..e9cd2517ad81 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -40,9 +40,6 @@ Configuration Options:
#include "comedi_fc.h"
/* Board register addresses */
-
-#define DMM32AT_MEMSIZE 0x10
-
#define DMM32AT_CONV 0x00
#define DMM32AT_AILSB 0x00
#define DMM32AT_AUXDOUT 0x01
@@ -237,7 +234,7 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev,
return n;
}
-static int dmm32at_ns_to_timer(unsigned int *ns, int round)
+static int dmm32at_ns_to_timer(unsigned int *ns, unsigned int flags)
{
/* trivial timer */
return *ns;
@@ -352,12 +349,12 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- dmm32at_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dmm32at_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- dmm32at_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dmm32at_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -491,7 +488,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d)
int i;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
@@ -684,7 +681,7 @@ static int dmm32at_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
- ret = comedi_request_region(dev, it->options[0], DMM32AT_MEMSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 4263014426f8..ad8ba0be4878 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -40,9 +40,6 @@ Configuration options:
#define DT2801_MAX_DMA_SIZE (64 * 1024)
-/* Ports */
-#define DT2801_IOSIZE 2
-
/* define's */
/* ====================== */
@@ -552,7 +549,7 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret = 0;
int n_ai_chans;
- ret = comedi_request_region(dev, it->options[0], DT2801_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index ba7c2ba618e6..a2e9caf3256f 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -169,8 +169,6 @@ static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = {
#define TIMEOUT 10000
-#define DT2811_SIZE 8
-
#define DT2811_ADCSR 0
#define DT2811_ADGCR 1
#define DT2811_ADDATLO 2
@@ -344,7 +342,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
struct comedi_subdevice *s;
- ret = comedi_request_region(dev, it->options[0], DT2811_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index 904c9f0e4afb..9216c35c414e 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -42,8 +42,6 @@ addition, the clock does not seem to be very accurate.
#include "comedi_fc.h"
-#define DT2814_SIZE 2
-
#define DT2814_CSR 0
#define DT2814_DATA 1
@@ -171,7 +169,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->scan_begin_arg;
- dt2814_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dt2814_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
if (err)
@@ -187,9 +185,7 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
int chan;
int trigvar;
- trigvar =
- dt2814_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ trigvar = dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
chan = CR_CHAN(cmd->chanlist[0]);
@@ -209,7 +205,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d)
int data;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
@@ -245,7 +241,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
int i;
- ret = comedi_request_region(dev, it->options[0], DT2814_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index b9ac4ed8babb..a98fb66fdd53 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -56,8 +56,6 @@ Configuration options:
#include <linux/delay.h>
-#define DT2815_SIZE 2
-
#define DT2815_DATA 0
#define DT2815_STATUS 1
@@ -154,7 +152,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct comedi_lrange *current_range_type, *voltage_range_type;
int ret;
- ret = comedi_request_region(dev, it->options[0], DT2815_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
@@ -195,6 +193,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
status = inb(dev->iobase + DT2815_STATUS);
if (status == 4) {
unsigned int program;
+
program = (it->options[4] & 0x3) << 3 | 0x7;
outb(program, dev->iobase + DT2815_DATA);
dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n",
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
index bf589936e546..5131deebf66f 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -36,8 +36,6 @@ Configuration options:
#include <linux/module.h>
#include "../comedidev.h"
-#define DT2817_SIZE 5
-
#define DT2817_CR 0
#define DT2817_DATA 1
@@ -114,7 +112,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
struct comedi_subdevice *s;
- ret = comedi_request_region(dev, it->options[0], DT2817_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x5);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index c2a66dcf99fe..5de26745783a 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -1,55 +1,69 @@
/*
- comedi/drivers/dt282x.c
- Hardware driver for Data Translation DT2821 series
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
-
- 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.
+ * dt282x.c
+ * Comedi driver for Data Translation DT2821 series
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
*/
+
/*
-Driver: dt282x
-Description: Data Translation DT2821 series (including DT-EZ)
-Author: ds
-Devices: [Data Translation] DT2821 (dt2821),
- DT2821-F-16SE (dt2821-f), DT2821-F-8DI (dt2821-f),
- DT2821-G-16SE (dt2821-f), DT2821-G-8DI (dt2821-g),
- DT2823 (dt2823),
- DT2824-PGH (dt2824-pgh), DT2824-PGL (dt2824-pgl), DT2825 (dt2825),
- DT2827 (dt2827), DT2828 (dt2828), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
- DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
-Status: complete
-Updated: Wed, 22 Aug 2001 17:11:34 -0700
-
-Configuration options:
- [0] - I/O port base address
- [1] - IRQ
- [2] - DMA 1
- [3] - DMA 2
- [4] - AI jumpered for 0=single ended, 1=differential
- [5] - AI jumpered for 0=straight binary, 1=2's complement
- [6] - AO 0 jumpered for 0=straight binary, 1=2's complement
- [7] - AO 1 jumpered for 0=straight binary, 1=2's complement
- [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
- [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
- 4=[-2.5,2.5]
- [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
- 4=[-2.5,2.5]
-
-Notes:
- - AO commands might be broken.
- - If you try to run a command on both the AI and AO subdevices
- simultaneously, bad things will happen. The driver needs to
- be fixed to check for this situation and return an error.
-*/
+ * Driver: dt282x
+ * Description: Data Translation DT2821 series (including DT-EZ)
+ * Author: ds
+ * Devices: (Data Translation) DT2821 [dt2821]
+ * (Data Translation) DT2821-F-16SE [dt2821-f]
+ * (Data Translation) DT2821-F-8DI [dt2821-f]
+ * (Data Translation) DT2821-G-16SE [dt2821-g]
+ * (Data Translation) DT2821-G-8DI [dt2821-g]
+ * (Data Translation) DT2823 [dt2823]
+ * (Data Translation) DT2824-PGH [dt2824-pgh]
+ * (Data Translation) DT2824-PGL [dt2824-pgl]
+ * (Data Translation) DT2825 [dt2825]
+ * (Data Translation) DT2827 [dt2827]
+ * (Data Translation) DT2828 [dt2828]
+ * (Data Translation) DT2928 [dt2829]
+ * (Data Translation) DT21-EZ [dt21-ez]
+ * (Data Translation) DT23-EZ [dt23-ez]
+ * (Data Translation) DT24-EZ [dt24-ez]
+ * (Data Translation) DT24-EZ-PGL [dt24-ez-pgl]
+ * Status: complete
+ * Updated: Wed, 22 Aug 2001 17:11:34 -0700
+ *
+ * Configuration options:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional, required for async command support)
+ * [2] - DMA 1 (optional, required for async command support)
+ * [3] - DMA 2 (optional, required for async command support)
+ * [4] - AI jumpered for 0=single ended, 1=differential
+ * [5] - AI jumpered for 0=straight binary, 1=2's complement
+ * [6] - AO 0 data format (deprecated, see below)
+ * [7] - AO 1 data format (deprecated, see below)
+ * [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
+ * [9] - AO channel 0 range (deprecated, see below)
+ * [10]- AO channel 1 range (deprecated, see below)
+ *
+ * Notes:
+ * - AO commands might be broken.
+ * - If you try to run a command on both the AI and AO subdevices
+ * simultaneously, bad things will happen. The driver needs to
+ * be fixed to check for this situation and return an error.
+ * - AO range is not programmable. The AO subdevice has a range_table
+ * containing all the possible analog output ranges. Use the range
+ * that matches your board configuration to convert between data
+ * values and physical units. The format of the data written to the
+ * board is handled automatically based on the unipolar/bipolar
+ * range that is selected.
+ */
#include <linux/module.h>
#include "../comedidev.h"
@@ -63,93 +77,53 @@ Notes:
#include "comedi_fc.h"
-#define DT2821_SIZE 0x10
-
-/*
- * Registers in the DT282x
- */
-
-#define DT2821_ADCSR 0x00 /* A/D Control/Status */
-#define DT2821_CHANCSR 0x02 /* Channel Control/Status */
-#define DT2821_ADDAT 0x04 /* A/D data */
-#define DT2821_DACSR 0x06 /* D/A Control/Status */
-#define DT2821_DADAT 0x08 /* D/A data */
-#define DT2821_DIODAT 0x0a /* digital data */
-#define DT2821_SUPCSR 0x0c /* Supervisor Control/Status */
-#define DT2821_TMRCTR 0x0e /* Timer/Counter */
-
-/*
- * At power up, some registers are in a well-known state. The
- * masks and values are as follows:
- */
-
-#define DT2821_ADCSR_MASK 0xfff0
-#define DT2821_ADCSR_VAL 0x7c00
-
-#define DT2821_CHANCSR_MASK 0xf0f0
-#define DT2821_CHANCSR_VAL 0x70f0
-
-#define DT2821_DACSR_MASK 0x7c93
-#define DT2821_DACSR_VAL 0x7c90
-
-#define DT2821_SUPCSR_MASK 0xf8ff
-#define DT2821_SUPCSR_VAL 0x0000
-
-#define DT2821_TMRCTR_MASK 0xff00
-#define DT2821_TMRCTR_VAL 0xf000
-
/*
- * Bit fields of each register
+ * Register map
*/
-
-/* ADCSR */
-
-#define DT2821_ADERR 0x8000 /* (R) 1 for A/D error */
-#define DT2821_ADCLK 0x0200 /* (R/W) A/D clock enable */
- /* 0x7c00 read as 1's */
-#define DT2821_MUXBUSY 0x0100 /* (R) multiplexer busy */
-#define DT2821_ADDONE 0x0080 /* (R) A/D done */
-#define DT2821_IADDONE 0x0040 /* (R/W) interrupt on A/D done */
- /* 0x0030 gain select */
- /* 0x000f channel select */
-
-/* CHANCSR */
-
-#define DT2821_LLE 0x8000 /* (R/W) Load List Enable */
- /* 0x7000 read as 1's */
- /* 0x0f00 (R) present address */
- /* 0x00f0 read as 1's */
- /* 0x000f (R) number of entries - 1 */
-
-/* DACSR */
-
-#define DT2821_DAERR 0x8000 /* (R) D/A error */
-#define DT2821_YSEL 0x0200 /* (R/W) DAC 1 select */
-#define DT2821_SSEL 0x0100 /* (R/W) single channel select */
-#define DT2821_DACRDY 0x0080 /* (R) DAC ready */
-#define DT2821_IDARDY 0x0040 /* (R/W) interrupt on DAC ready */
-#define DT2821_DACLK 0x0020 /* (R/W) D/A clock enable */
-#define DT2821_HBOE 0x0002 /* (R/W) DIO high byte output enable */
-#define DT2821_LBOE 0x0001 /* (R/W) DIO low byte output enable */
-
-/* SUPCSR */
-
-#define DT2821_DMAD 0x8000 /* (R) DMA done */
-#define DT2821_ERRINTEN 0x4000 /* (R/W) interrupt on error */
-#define DT2821_CLRDMADNE 0x2000 /* (W) clear DMA done */
-#define DT2821_DDMA 0x1000 /* (R/W) dual DMA */
-#define DT2821_DS1 0x0800 /* (R/W) DMA select 1 */
-#define DT2821_DS0 0x0400 /* (R/W) DMA select 0 */
-#define DT2821_BUFFB 0x0200 /* (R/W) buffer B selected */
-#define DT2821_SCDN 0x0100 /* (R) scan done */
-#define DT2821_DACON 0x0080 /* (W) DAC single conversion */
-#define DT2821_ADCINIT 0x0040 /* (W) A/D initialize */
-#define DT2821_DACINIT 0x0020 /* (W) D/A initialize */
-#define DT2821_PRLD 0x0010 /* (W) preload multiplexer */
-#define DT2821_STRIG 0x0008 /* (W) software trigger */
-#define DT2821_XTRIG 0x0004 /* (R/W) external trigger enable */
-#define DT2821_XCLK 0x0002 /* (R/W) external clock enable */
-#define DT2821_BDINIT 0x0001 /* (W) initialize board */
+#define DT2821_ADCSR_REG 0x00
+#define DT2821_ADCSR_ADERR (1 << 15)
+#define DT2821_ADCSR_ADCLK (1 << 9)
+#define DT2821_ADCSR_MUXBUSY (1 << 8)
+#define DT2821_ADCSR_ADDONE (1 << 7)
+#define DT2821_ADCSR_IADDONE (1 << 6)
+#define DT2821_ADCSR_GS(x) (((x) & 0x3) << 4)
+#define DT2821_ADCSR_CHAN(x) (((x) & 0xf) << 0)
+#define DT2821_CHANCSR_REG 0x02
+#define DT2821_CHANCSR_LLE (1 << 15)
+#define DT2821_CHANCSR_PRESLA(x) (((x) & 0xf) >> 8)
+#define DT2821_CHANCSR_NUMB(x) ((((x) - 1) & 0xf) << 0)
+#define DT2821_ADDAT_REG 0x04
+#define DT2821_DACSR_REG 0x06
+#define DT2821_DACSR_DAERR (1 << 15)
+#define DT2821_DACSR_YSEL(x) ((x) << 9)
+#define DT2821_DACSR_SSEL (1 << 8)
+#define DT2821_DACSR_DACRDY (1 << 7)
+#define DT2821_DACSR_IDARDY (1 << 6)
+#define DT2821_DACSR_DACLK (1 << 5)
+#define DT2821_DACSR_HBOE (1 << 1)
+#define DT2821_DACSR_LBOE (1 << 0)
+#define DT2821_DADAT_REG 0x08
+#define DT2821_DIODAT_REG 0x0a
+#define DT2821_SUPCSR_REG 0x0c
+#define DT2821_SUPCSR_DMAD (1 << 15)
+#define DT2821_SUPCSR_ERRINTEN (1 << 14)
+#define DT2821_SUPCSR_CLRDMADNE (1 << 13)
+#define DT2821_SUPCSR_DDMA (1 << 12)
+#define DT2821_SUPCSR_DS_PIO (0 << 10)
+#define DT2821_SUPCSR_DS_AD_CLK (1 << 10)
+#define DT2821_SUPCSR_DS_DA_CLK (2 << 10)
+#define DT2821_SUPCSR_DS_AD_TRIG (3 << 10)
+#define DT2821_SUPCSR_BUFFB (1 << 9)
+#define DT2821_SUPCSR_SCDN (1 << 8)
+#define DT2821_SUPCSR_DACON (1 << 7)
+#define DT2821_SUPCSR_ADCINIT (1 << 6)
+#define DT2821_SUPCSR_DACINIT (1 << 5)
+#define DT2821_SUPCSR_PRLD (1 << 4)
+#define DT2821_SUPCSR_STRIG (1 << 3)
+#define DT2821_SUPCSR_XTRIG (1 << 2)
+#define DT2821_SUPCSR_XCLK (1 << 1)
+#define DT2821_SUPCSR_BDINIT (1 << 0)
+#define DT2821_TMRCTR_REG 0x0e
static const struct comedi_lrange range_dt282x_ai_lo_bipolar = {
4, {
@@ -205,146 +179,326 @@ static const struct comedi_lrange range_dt282x_ai_hi_unipolar = {
}
};
+/*
+ * The Analog Output range is set per-channel using jumpers on the board.
+ * All of these ranges may not be available on some DT2821 series boards.
+ * The default jumper setting has both channels set for +/-10V output.
+ */
+static const struct comedi_lrange dt282x_ao_range = {
+ 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ }
+};
+
struct dt282x_board {
const char *name;
- int adbits;
+ unsigned int ai_maxdata;
int adchan_se;
int adchan_di;
int ai_speed;
int ispgl;
int dachan;
- int dabits;
+ unsigned int ao_maxdata;
+};
+
+static const struct dt282x_board boardtypes[] = {
+ {
+ .name = "dt2821",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2821-f",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 6500,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2821-g",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 4000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2823",
+ .ai_maxdata = 0xffff,
+ .adchan_di = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0xffff,
+ }, {
+ .name = "dt2824-pgh",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ }, {
+ .name = "dt2824-pgl",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .ispgl = 1,
+ }, {
+ .name = "dt2825",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .ispgl = 1,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2827",
+ .ai_maxdata = 0xffff,
+ .adchan_di = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2828",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2829",
+ .ai_maxdata = 0xffff,
+ .adchan_se = 8,
+ .ai_speed = 33250,
+ .dachan = 2,
+ .ao_maxdata = 0xffff,
+ }, {
+ .name = "dt21-ez",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt23-ez",
+ .ai_maxdata = 0xffff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ }, {
+ .name = "dt24-ez",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ }, {
+ .name = "dt24-ez-pgl",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ .ispgl = 1,
+ },
};
struct dt282x_private {
- int ad_2scomp; /* we have 2's comp jumper set */
- int da0_2scomp; /* same, for DAC0 */
- int da1_2scomp; /* same, for DAC1 */
+ unsigned int ad_2scomp:1;
- const struct comedi_lrange *darangelist[2];
+ unsigned int divisor;
- unsigned short ao[2];
+ unsigned short ao_readback[2];
- volatile int dacsr; /* software copies of registers */
- volatile int adcsr;
- volatile int supcsr;
+ int dacsr; /* software copies of registers */
+ int adcsr;
+ int supcsr;
- volatile int ntrig;
- volatile int nread;
+ int ntrig;
+ int nread;
struct {
int chan;
unsigned short *buf; /* DMA buffer */
- volatile int size; /* size of current transfer */
+ int size; /* size of current transfer */
} dma[2];
int dma_maxsize; /* max size of DMA transfer (in bytes) */
- int usedma; /* driver uses DMA */
- volatile int current_dma_index;
+ int current_dma_index;
int dma_dir;
};
-/*
- * Some useless abstractions
- */
-#define chan_to_DAC(a) ((a)&1)
+static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
-static int prep_ai_dma(struct comedi_device *dev, int chan, int size);
-static int prep_ao_dma(struct comedi_device *dev, int chan, int size);
-static int dt282x_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int dt282x_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int dt282x_ns_to_timer(int *nanosec, int round_mode);
-static void dt282x_disable_dma(struct comedi_device *dev);
+ if (!devpriv->ntrig)
+ return 0;
-static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
+ if (n == 0)
+ n = devpriv->dma_maxsize;
+ if (n > devpriv->ntrig * 2)
+ n = devpriv->ntrig * 2;
+ devpriv->ntrig -= n / 2;
-static void dt282x_munge(struct comedi_device *dev, unsigned short *buf,
- unsigned int nbytes)
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
- unsigned int i;
- unsigned short mask = (1 << board->adbits) - 1;
- unsigned short sign = 1 << (board->adbits - 1);
- int n;
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
- if (devpriv->ad_2scomp)
- sign = 1 << (board->adbits - 1);
- else
- sign = 0;
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
- if (nbytes % 2)
- comedi_error(dev, "bug! odd number of bytes from dma xfer");
- n = nbytes / 2;
- for (i = 0; i < n; i++)
- buf[i] = (buf[i] & mask) ^ sign;
+ set_dma_mode(dma_chan, DMA_MODE_WRITE);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
}
-static void dt282x_ao_dma_interrupt(struct comedi_device *dev)
+static void dt282x_disable_dma(struct comedi_device *dev)
{
struct dt282x_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- void *ptr;
- int size;
+
+ disable_dma(devpriv->dma[0].chan);
+ disable_dma(devpriv->dma[1].chan);
+}
+
+static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
+{
+ unsigned int prescale, base, divider;
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ if (prescale == 1)
+ continue;
+ base = 250 * (1 << prescale);
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*ns + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*ns) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*ns + base - 1) / base;
+ break;
+ }
+ if (divider < 256) {
+ *ns = divider * base;
+ return (prescale << 8) | (255 - divider);
+ }
+ }
+ base = 250 * (1 << 15);
+ divider = 255;
+ *ns = divider * base;
+ return (15 << 8) | (255 - divider);
+}
+
+static void dt282x_munge(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned short *buf,
+ unsigned int nbytes)
+{
+ struct dt282x_private *devpriv = dev->private;
+ unsigned int val;
int i;
- outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR);
+ if (nbytes % 2)
+ dev_err(dev->class_dev,
+ "bug! odd number of bytes from dma xfer\n");
- if (!s->async->prealloc_buf) {
- dev_err(dev->class_dev, "no buffer in %s\n", __func__);
- return;
+ for (i = 0; i < nbytes / 2; i++) {
+ val = buf[i];
+ val &= s->maxdata;
+ if (devpriv->ad_2scomp)
+ val = comedi_offset_munge(s, val);
+
+ buf[i] = val;
}
+}
- i = devpriv->current_dma_index;
- ptr = devpriv->dma[i].buf;
+static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int cur_dma = devpriv->current_dma_index;
+ void *ptr = devpriv->dma[cur_dma].buf;
+ int size;
- disable_dma(devpriv->dma[i].chan);
+ outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
+ dev->iobase + DT2821_SUPCSR_REG);
- devpriv->current_dma_index = 1 - i;
+ disable_dma(devpriv->dma[cur_dma].chan);
+
+ devpriv->current_dma_index = 1 - cur_dma;
size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
if (size == 0) {
dev_err(dev->class_dev, "AO underrun\n");
s->async->events |= COMEDI_CB_OVERFLOW;
- return;
+ } else {
+ dt282x_prep_ao_dma(dev, cur_dma, size);
}
- prep_ao_dma(dev, i, size);
- return;
}
-static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
+static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct dt282x_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- void *ptr;
- int size;
- int i;
+ int cur_dma = devpriv->current_dma_index;
+ void *ptr = devpriv->dma[cur_dma].buf;
+ int size = devpriv->dma[cur_dma].size;
int ret;
- outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
+ dev->iobase + DT2821_SUPCSR_REG);
- if (!s->async->prealloc_buf) {
- dev_err(dev->class_dev, "no buffer in %s\n", __func__);
- return;
- }
-
- i = devpriv->current_dma_index;
- ptr = devpriv->dma[i].buf;
- size = devpriv->dma[i].size;
+ disable_dma(devpriv->dma[cur_dma].chan);
- disable_dma(devpriv->dma[i].chan);
+ devpriv->current_dma_index = 1 - cur_dma;
- devpriv->current_dma_index = 1 - i;
-
- dt282x_munge(dev, ptr, size);
+ dt282x_munge(dev, s, ptr, size);
ret = cfc_write_array_to_buffer(s, ptr, size);
if (ret != size) {
s->async->events |= COMEDI_CB_OVERFLOW;
return;
}
- devpriv->nread -= size / 2;
+ devpriv->nread -= size / 2;
if (devpriv->nread < 0) {
dev_info(dev->class_dev, "nread off by one\n");
devpriv->nread = 0;
@@ -357,67 +511,12 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
/* clear the dual dma flag, making this the last dma segment */
/* XXX probably wrong */
if (!devpriv->ntrig) {
- devpriv->supcsr &= ~(DT2821_DDMA);
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr &= ~DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
#endif
/* restart the channel */
- prep_ai_dma(dev, i, 0);
-}
-
-static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- int dma_chan;
- unsigned long dma_ptr;
- unsigned long flags;
-
- if (!devpriv->ntrig)
- return 0;
-
- if (n == 0)
- n = devpriv->dma_maxsize;
- if (n > devpriv->ntrig * 2)
- n = devpriv->ntrig * 2;
- devpriv->ntrig -= n / 2;
-
- devpriv->dma[dma_index].size = n;
- dma_chan = devpriv->dma[dma_index].chan;
- dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
-
- set_dma_mode(dma_chan, DMA_MODE_READ);
- flags = claim_dma_lock();
- clear_dma_ff(dma_chan);
- set_dma_addr(dma_chan, dma_ptr);
- set_dma_count(dma_chan, n);
- release_dma_lock(flags);
-
- enable_dma(dma_chan);
-
- return n;
-}
-
-static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- int dma_chan;
- unsigned long dma_ptr;
- unsigned long flags;
-
- devpriv->dma[dma_index].size = n;
- dma_chan = devpriv->dma[dma_index].chan;
- dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
-
- set_dma_mode(dma_chan, DMA_MODE_WRITE);
- flags = claim_dma_lock();
- clear_dma_ff(dma_chan);
- set_dma_addr(dma_chan, dma_ptr);
- set_dma_count(dma_chan, n);
- release_dma_lock(flags);
-
- enable_dma(dma_chan);
-
- return n;
+ dt282x_prep_ai_dma(dev, cur_dma, 0);
}
static irqreturn_t dt282x_interrupt(int irq, void *d)
@@ -430,42 +529,42 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
int handled = 0;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
- adcsr = inw(dev->iobase + DT2821_ADCSR);
- dacsr = inw(dev->iobase + DT2821_DACSR);
- supcsr = inw(dev->iobase + DT2821_SUPCSR);
- if (supcsr & DT2821_DMAD) {
+ adcsr = inw(dev->iobase + DT2821_ADCSR_REG);
+ dacsr = inw(dev->iobase + DT2821_DACSR_REG);
+ supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
+ if (supcsr & DT2821_SUPCSR_DMAD) {
if (devpriv->dma_dir == DMA_MODE_READ)
- dt282x_ai_dma_interrupt(dev);
+ dt282x_ai_dma_interrupt(dev, s);
else
- dt282x_ao_dma_interrupt(dev);
+ dt282x_ao_dma_interrupt(dev, s_ao);
handled = 1;
}
- if (adcsr & DT2821_ADERR) {
+ if (adcsr & DT2821_ADCSR_ADERR) {
if (devpriv->nread != 0) {
- comedi_error(dev, "A/D error");
+ dev_err(dev->class_dev, "A/D error\n");
s->async->events |= COMEDI_CB_ERROR;
}
handled = 1;
}
- if (dacsr & DT2821_DAERR) {
- comedi_error(dev, "D/A error");
+ if (dacsr & DT2821_DACSR_DAERR) {
+ dev_err(dev->class_dev, "D/A error\n");
s_ao->async->events |= COMEDI_CB_ERROR;
handled = 1;
}
#if 0
- if (adcsr & DT2821_ADDONE) {
+ if (adcsr & DT2821_ADCSR_ADDONE) {
int ret;
unsigned short data;
- data = inw(dev->iobase + DT2821_ADDAT);
- data &= (1 << board->adbits) - 1;
-
+ data = inw(dev->iobase + DT2821_ADDAT_REG);
+ data &= s->maxdata;
if (devpriv->ad_2scomp)
- data ^= 1 << (board->adbits - 1);
+ data = comedi_offset_munge(s, data);
+
ret = comedi_buf_put(s, data);
if (ret == 0)
@@ -475,9 +574,9 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
if (!devpriv->nread) {
s->async->events |= COMEDI_CB_EOA;
} else {
- if (supcsr & DT2821_SCDN)
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ if (supcsr & DT2821_SUPCSR_SCDN)
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
}
handled = 1;
}
@@ -492,17 +591,20 @@ static void dt282x_load_changain(struct comedi_device *dev, int n,
unsigned int *chanlist)
{
struct dt282x_private *devpriv = dev->private;
- unsigned int i;
- unsigned int chan, range;
+ int i;
- outw(DT2821_LLE | (n - 1), dev->iobase + DT2821_CHANCSR);
+ outw(DT2821_CHANCSR_LLE | DT2821_CHANCSR_NUMB(n),
+ dev->iobase + DT2821_CHANCSR_REG);
for (i = 0; i < n; i++) {
- chan = CR_CHAN(chanlist[i]);
- range = CR_RANGE(chanlist[i]);
- outw(devpriv->adcsr | (range << 4) | chan,
- dev->iobase + DT2821_ADCSR);
+ unsigned int chan = CR_CHAN(chanlist[i]);
+ unsigned int range = CR_RANGE(chanlist[i]);
+
+ outw(devpriv->adcsr |
+ DT2821_ADCSR_GS(range) |
+ DT2821_ADCSR_CHAN(chan),
+ dev->iobase + DT2821_ADCSR_REG);
}
- outw(n - 1, dev->iobase + DT2821_CHANCSR);
+ outw(DT2821_CHANCSR_NUMB(n), dev->iobase + DT2821_CHANCSR_REG);
}
static int dt282x_ai_timeout(struct comedi_device *dev,
@@ -512,14 +614,14 @@ static int dt282x_ai_timeout(struct comedi_device *dev,
{
unsigned int status;
- status = inw(dev->iobase + DT2821_ADCSR);
+ status = inw(dev->iobase + DT2821_ADCSR_REG);
switch (context) {
- case DT2821_MUXBUSY:
- if ((status & DT2821_MUXBUSY) == 0)
+ case DT2821_ADCSR_MUXBUSY:
+ if ((status & DT2821_ADCSR_MUXBUSY) == 0)
return 0;
break;
- case DT2821_ADDONE:
- if (status & DT2821_ADDONE)
+ case DT2821_ADCSR_ADDONE:
+ if (status & DT2821_ADCSR_ADDONE)
return 0;
break;
default:
@@ -536,47 +638,53 @@ static int dt282x_ai_timeout(struct comedi_device *dev,
*/
static int dt282x_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
+ unsigned int val;
int ret;
int i;
/* XXX should we really be enabling the ad clock here? */
- devpriv->adcsr = DT2821_ADCLK;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ devpriv->adcsr = DT2821_ADCSR_ADCLK;
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
dt282x_load_changain(dev, 1, &insn->chanspec);
- outw(devpriv->supcsr | DT2821_PRLD, dev->iobase + DT2821_SUPCSR);
- ret = comedi_timeout(dev, s, insn, dt282x_ai_timeout, DT2821_MUXBUSY);
+ outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
+ dev->iobase + DT2821_SUPCSR_REG);
+ ret = comedi_timeout(dev, s, insn,
+ dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
if (ret)
return ret;
for (i = 0; i < insn->n; i++) {
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
- ret = comedi_timeout(dev, s, insn, dt282x_ai_timeout,
- DT2821_ADDONE);
+ ret = comedi_timeout(dev, s, insn,
+ dt282x_ai_timeout, DT2821_ADCSR_ADDONE);
if (ret)
return ret;
- data[i] =
- inw(dev->iobase +
- DT2821_ADDAT) & ((1 << board->adbits) - 1);
+ val = inw(dev->iobase + DT2821_ADDAT_REG);
+ val &= s->maxdata;
if (devpriv->ad_2scomp)
- data[i] ^= (1 << (board->adbits - 1));
+ val = comedi_offset_munge(s, val);
+
+ data[i] = val;
}
return i;
}
static int dt282x_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
const struct dt282x_board *board = comedi_board(dev);
+ struct dt282x_private *devpriv = dev->private;
int err = 0;
unsigned int arg;
@@ -634,7 +742,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->convert_arg;
- dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (err)
@@ -645,81 +753,62 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
- int timer;
int ret;
- if (devpriv->usedma == 0) {
- comedi_error(dev,
- "driver requires 2 dma channels"
- " to execute command");
- return -EIO;
- }
-
dt282x_disable_dma(dev);
- if (cmd->convert_arg < board->ai_speed)
- cmd->convert_arg = board->ai_speed;
- timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
- outw(timer, dev->iobase + DT2821_TMRCTR);
+ outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0;
- } else {
- /* external trigger */
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0 | DT2821_DS1;
- }
- outw(devpriv->supcsr | DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_ADCINIT,
- dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr = DT2821_SUPCSR_ERRINTEN;
+ if (cmd->scan_begin_src == TRIG_FOLLOW)
+ devpriv->supcsr = DT2821_SUPCSR_DS_AD_CLK;
+ else
+ devpriv->supcsr = DT2821_SUPCSR_DS_AD_TRIG;
+ outw(devpriv->supcsr |
+ DT2821_SUPCSR_CLRDMADNE |
+ DT2821_SUPCSR_BUFFB |
+ DT2821_SUPCSR_ADCINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
devpriv->nread = devpriv->ntrig;
devpriv->dma_dir = DMA_MODE_READ;
devpriv->current_dma_index = 0;
- prep_ai_dma(dev, 0, 0);
+ dt282x_prep_ai_dma(dev, 0, 0);
if (devpriv->ntrig) {
- prep_ai_dma(dev, 1, 0);
- devpriv->supcsr |= DT2821_DDMA;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ dt282x_prep_ai_dma(dev, 1, 0);
+ devpriv->supcsr |= DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
devpriv->adcsr = 0;
dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
- devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ devpriv->adcsr = DT2821_ADCSR_ADCLK | DT2821_ADCSR_IADDONE;
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
- outw(devpriv->supcsr | DT2821_PRLD, dev->iobase + DT2821_SUPCSR);
- ret = comedi_timeout(dev, s, NULL, dt282x_ai_timeout, DT2821_MUXBUSY);
+ outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
+ dev->iobase + DT2821_SUPCSR_REG);
+ ret = comedi_timeout(dev, s, NULL,
+ dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
if (ret)
return ret;
if (cmd->scan_begin_src == TRIG_FOLLOW) {
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
} else {
- devpriv->supcsr |= DT2821_XTRIG;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr |= DT2821_SUPCSR_XTRIG;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
return 0;
}
-static void dt282x_disable_dma(struct comedi_device *dev)
-{
- struct dt282x_private *devpriv = dev->private;
-
- if (devpriv->usedma) {
- disable_dma(devpriv->dma[0].chan);
- disable_dma(devpriv->dma[1].chan);
- }
-}
-
static int dt282x_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
@@ -728,101 +817,66 @@ static int dt282x_ai_cancel(struct comedi_device *dev,
dt282x_disable_dma(dev);
devpriv->adcsr = 0;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_ADCINIT, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_ADCINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
return 0;
}
-static int dt282x_ns_to_timer(int *nanosec, int round_mode)
-{
- int prescale, base, divider;
-
- for (prescale = 0; prescale < 16; prescale++) {
- if (prescale == 1)
- continue;
- base = 250 * (1 << prescale);
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- divider = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- divider = (*nanosec + base - 1) / base;
- break;
- }
- if (divider < 256) {
- *nanosec = divider * base;
- return (prescale << 8) | (255 - divider);
- }
- }
- base = 250 * (1 << 15);
- divider = 255;
- *nanosec = divider * base;
- return (15 << 8) | (255 - divider);
-}
-
-/*
- * Analog output routine. Selects single channel conversion,
- * selects correct channel, converts from 2's compliment to
- * offset binary if necessary, loads the data into the DAC
- * data register, and performs the conversion.
- */
static int dt282x_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct dt282x_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
- data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
- return 1;
+ return insn->n;
}
static int dt282x_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
- unsigned short d;
- unsigned int chan;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int val;
+ int i;
- chan = CR_CHAN(insn->chanspec);
- d = data[0];
- d &= (1 << board->dabits) - 1;
- devpriv->ao[chan] = d;
+ devpriv->dacsr |= DT2821_DACSR_SSEL | DT2821_DACSR_YSEL(chan);
- devpriv->dacsr |= DT2821_SSEL;
+ for (i = 0; i < insn->n; i++) {
+ val = data[i];
+ devpriv->ao_readback[chan] = val;
- if (chan) {
- /* select channel */
- devpriv->dacsr |= DT2821_YSEL;
- if (devpriv->da0_2scomp)
- d ^= (1 << (board->dabits - 1));
- } else {
- devpriv->dacsr &= ~DT2821_YSEL;
- if (devpriv->da1_2scomp)
- d ^= (1 << (board->dabits - 1));
- }
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
- outw(d, dev->iobase + DT2821_DADAT);
+ outw(val, dev->iobase + DT2821_DADAT_REG);
- outw(devpriv->supcsr | DT2821_DACON, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_DACON,
+ dev->iobase + DT2821_SUPCSR_REG);
+ }
- return 1;
+ return insn->n;
}
static int dt282x_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
+ struct dt282x_private *devpriv = dev->private;
int err = 0;
unsigned int arg;
@@ -865,7 +919,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->scan_begin_arg;
- dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
if (err)
@@ -892,7 +946,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
dev_err(dev->class_dev, "AO underrun\n");
return -EPIPE;
}
- prep_ao_dma(dev, 0, size);
+ dt282x_prep_ao_dma(dev, 0, size);
size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
devpriv->dma_maxsize);
@@ -900,9 +954,10 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
dev_err(dev->class_dev, "AO underrun\n");
return -EPIPE;
}
- prep_ao_dma(dev, 1, size);
+ dt282x_prep_ao_dma(dev, 1, size);
- outw(devpriv->supcsr | DT2821_STRIG, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
s->async->inttrig = NULL;
return 1;
@@ -911,21 +966,18 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct dt282x_private *devpriv = dev->private;
- int timer;
struct comedi_cmd *cmd = &s->async->cmd;
- if (devpriv->usedma == 0) {
- comedi_error(dev,
- "driver requires 2 dma channels"
- " to execute command");
- return -EIO;
- }
-
dt282x_disable_dma(dev);
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
- outw(devpriv->supcsr | DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT,
- dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr = DT2821_SUPCSR_ERRINTEN |
+ DT2821_SUPCSR_DS_DA_CLK |
+ DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr |
+ DT2821_SUPCSR_CLRDMADNE |
+ DT2821_SUPCSR_BUFFB |
+ DT2821_SUPCSR_DACINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
devpriv->nread = devpriv->ntrig;
@@ -933,11 +985,15 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->dma_dir = DMA_MODE_WRITE;
devpriv->current_dma_index = 0;
- timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
- outw(timer, dev->iobase + DT2821_TMRCTR);
+ outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
+
+ /* clear all bits but the DIO direction bits */
+ devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
- devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ devpriv->dacsr |= (DT2821_DACSR_SSEL |
+ DT2821_DACSR_DACLK |
+ DT2821_DACSR_IDARDY);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
s->async->inttrig = dt282x_ao_inttrig;
@@ -951,11 +1007,14 @@ static int dt282x_ao_cancel(struct comedi_device *dev,
dt282x_disable_dma(dev);
- devpriv->dacsr = 0;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ /* clear all bits but the DIO direction bits */
+ devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
+
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_DACINIT, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_DACINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
return 0;
}
@@ -966,9 +1025,9 @@ static int dt282x_dio_insn_bits(struct comedi_device *dev,
unsigned int *data)
{
if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + DT2821_DIODAT);
+ outw(s->state, dev->iobase + DT2821_DIODAT_REG);
- data[1] = inw(dev->iobase + DT2821_DIODAT);
+ data[1] = inw(dev->iobase + DT2821_DIODAT_REG);
return insn->n;
}
@@ -992,13 +1051,13 @@ static int dt282x_dio_insn_config(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->dacsr &= ~(DT2821_LBOE | DT2821_HBOE);
+ devpriv->dacsr &= ~(DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
if (s->io_bits & 0x00ff)
- devpriv->dacsr |= DT2821_LBOE;
+ devpriv->dacsr |= DT2821_DACSR_LBOE;
if (s->io_bits & 0xff00)
- devpriv->dacsr |= DT2821_HBOE;
+ devpriv->dacsr |= DT2821_DACSR_HBOE;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
return insn->n;
}
@@ -1021,55 +1080,18 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
if (x < 0 || x >= 2)
x = 0;
return ai_range_pgl_table[x];
- } else {
- if (x < 0 || x >= 4)
- x = 0;
- return ai_range_table[x];
}
-}
-static const struct comedi_lrange *const ao_range_table[] = {
- &range_bipolar10,
- &range_unipolar10,
- &range_bipolar5,
- &range_unipolar5,
- &range_bipolar2_5
-};
-
-static const struct comedi_lrange *opt_ao_range_lkup(int x)
-{
- if (x < 0 || x >= 5)
+ if (x < 0 || x >= 4)
x = 0;
- return ao_range_table[x];
+ return ai_range_table[x];
}
-enum { /* i/o base, irq, dma channels */
- opt_iobase = 0, opt_irq, opt_dma1, opt_dma2,
- opt_diff, /* differential */
- opt_ai_twos, opt_ao0_twos, opt_ao1_twos, /* twos comp */
- opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */
-};
-
static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
{
struct dt282x_private *devpriv = dev->private;
int ret;
- devpriv->usedma = 0;
-
- if (!dma1 && !dma2)
- return 0;
-
- if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
- return -EINVAL;
-
- if (dma2 < dma1) {
- int i;
- i = dma1;
- dma1 = dma2;
- dma2 = i;
- }
-
ret = request_dma(dma1, "dt282x A");
if (ret)
return -EBUSY;
@@ -1086,8 +1108,45 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
if (!devpriv->dma[0].buf || !devpriv->dma[1].buf)
return -ENOMEM;
- devpriv->usedma = 1;
+ return 0;
+}
+static void dt282x_free_dma(struct comedi_device *dev)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int i;
+
+ if (!devpriv)
+ return;
+
+ for (i = 0; i < 2; i++) {
+ if (devpriv->dma[i].chan)
+ free_dma(devpriv->dma[i].chan);
+ if (devpriv->dma[i].buf)
+ free_page((unsigned long)devpriv->dma[i].buf);
+ devpriv->dma[i].chan = 0;
+ devpriv->dma[i].buf = NULL;
+ }
+}
+
+static int dt282x_initialize(struct comedi_device *dev)
+{
+ /* Initialize board */
+ outw(DT2821_SUPCSR_BDINIT, dev->iobase + DT2821_SUPCSR_REG);
+ inw(dev->iobase + DT2821_ADCSR_REG);
+
+ /*
+ * At power up, some registers are in a well-known state.
+ * Check them to see if a DT2821 series board is present.
+ */
+ if (((inw(dev->iobase + DT2821_ADCSR_REG) & 0xfff0) != 0x7c00) ||
+ ((inw(dev->iobase + DT2821_CHANCSR_REG) & 0xf0f0) != 0x70f0) ||
+ ((inw(dev->iobase + DT2821_DACSR_REG) & 0x7c93) != 0x7c90) ||
+ ((inw(dev->iobase + DT2821_SUPCSR_REG) & 0xf8ff) != 0x0000) ||
+ ((inw(dev->iobase + DT2821_TMRCTR_REG) & 0xff00) != 0xf000)) {
+ dev_err(dev->class_dev, "board not found\n");
+ return -EIO;
+ }
return 0;
}
@@ -1111,263 +1170,125 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct dt282x_private *devpriv;
struct comedi_subdevice *s;
int ret;
- int i;
- ret = comedi_request_region(dev, it->options[0], DT2821_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
- outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
- i = inw(dev->iobase + DT2821_ADCSR);
-
- if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
- != DT2821_ADCSR_VAL) ||
- ((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
- != DT2821_CHANCSR_VAL) ||
- ((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
- != DT2821_DACSR_VAL) ||
- ((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
- != DT2821_SUPCSR_VAL) ||
- ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
- != DT2821_TMRCTR_VAL)) {
- dev_err(dev->class_dev, "board not found\n");
- return -EIO;
- }
- /* should do board test */
-
- if (it->options[opt_irq] > 0) {
- ret = request_irq(it->options[opt_irq], dt282x_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[opt_irq];
- }
+ ret = dt282x_initialize(dev);
+ if (ret)
+ return ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
- if (dev->irq) {
- ret = dt282x_grab_dma(dev, it->options[opt_dma1],
- it->options[opt_dma2]);
- if (ret < 0)
- return ret;
+ /* an IRQ and 2 DMA channels are required for async command support */
+ if (it->options[1] && it->options[2] && it->options[3]) {
+ unsigned int irq = it->options[1];
+ unsigned int dma1 = it->options[2];
+ unsigned int dma2 = it->options[3];
+
+ if (dma2 < dma1) {
+ unsigned int swap;
+
+ swap = dma1;
+ dma1 = dma2;
+ dma2 = swap;
+ }
+
+ if (dma1 != dma2 &&
+ dma1 >= 5 && dma1 <= 7 &&
+ dma2 >= 5 && dma2 <= 7) {
+ ret = request_irq(irq, dt282x_interrupt, 0,
+ dev->board_name, dev);
+ if (ret == 0) {
+ dev->irq = irq;
+
+ ret = dt282x_grab_dma(dev, dma1, dma2);
+ if (ret < 0) {
+ dt282x_free_dma(dev);
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
+ }
+ }
}
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
return ret;
+ /* Analog Input subdevice */
s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ if ((it->options[4] && board->adchan_di) || board->adchan_se == 0) {
+ s->subdev_flags |= SDF_DIFF;
+ s->n_chan = board->adchan_di;
+ } else {
+ s->subdev_flags |= SDF_COMMON;
+ s->n_chan = board->adchan_se;
+ }
+ s->maxdata = board->ai_maxdata;
+
+ s->range_table = opt_ai_range_lkup(board->ispgl, it->options[8]);
+ devpriv->ad_2scomp = it->options[5] ? 1 : 0;
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE |
- ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
- s->n_chan =
- (it->options[opt_diff]) ? board->adchan_di : board->adchan_se;
- s->insn_read = dt282x_ai_insn_read;
- s->maxdata = (1 << board->adbits) - 1;
- s->range_table =
- opt_ai_range_lkup(board->ispgl, it->options[opt_ai_range]);
- devpriv->ad_2scomp = it->options[opt_ai_twos];
+ s->insn_read = dt282x_ai_insn_read;
if (dev->irq) {
dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 16;
- s->do_cmdtest = dt282x_ai_cmdtest;
- s->do_cmd = dt282x_ai_cmd;
- s->cancel = dt282x_ai_cancel;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = dt282x_ai_cmdtest;
+ s->do_cmd = dt282x_ai_cmd;
+ s->cancel = dt282x_ai_cancel;
}
+ /* Analog Output subdevice */
s = &dev->subdevices[1];
+ if (board->dachan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = board->dachan;
+ s->maxdata = board->ao_maxdata;
- s->n_chan = board->dachan;
- if (s->n_chan) {
- /* ao subsystem */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->insn_read = dt282x_ao_insn_read;
- s->insn_write = dt282x_ao_insn_write;
- s->maxdata = (1 << board->dabits) - 1;
- s->range_table_list = devpriv->darangelist;
- devpriv->darangelist[0] =
- opt_ao_range_lkup(it->options[opt_ao0_range]);
- devpriv->darangelist[1] =
- opt_ao_range_lkup(it->options[opt_ao1_range]);
- devpriv->da0_2scomp = it->options[opt_ao0_twos];
- devpriv->da1_2scomp = it->options[opt_ao1_twos];
+ /* ranges are per-channel, set by jumpers on the board */
+ s->range_table = &dt282x_ao_range;
+
+ s->insn_read = dt282x_ao_insn_read;
+ s->insn_write = dt282x_ao_insn_write;
if (dev->irq) {
dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->len_chanlist = 2;
- s->do_cmdtest = dt282x_ao_cmdtest;
- s->do_cmd = dt282x_ao_cmd;
- s->cancel = dt282x_ao_cancel;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = dt282x_ao_cmdtest;
+ s->do_cmd = dt282x_ao_cmd;
+ s->cancel = dt282x_ao_cancel;
}
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
+ /* Digital I/O subdevice */
s = &dev->subdevices[2];
- /* dio subsystem */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->insn_bits = dt282x_dio_insn_bits;
- s->insn_config = dt282x_dio_insn_config;
- s->maxdata = 1;
- s->range_table = &range_digital;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt282x_dio_insn_bits;
+ s->insn_config = dt282x_dio_insn_config;
return 0;
}
static void dt282x_detach(struct comedi_device *dev)
{
- struct dt282x_private *devpriv = dev->private;
-
- if (dev->private) {
- if (devpriv->dma[0].chan)
- free_dma(devpriv->dma[0].chan);
- if (devpriv->dma[1].chan)
- free_dma(devpriv->dma[1].chan);
- if (devpriv->dma[0].buf)
- free_page((unsigned long)devpriv->dma[0].buf);
- if (devpriv->dma[1].buf)
- free_page((unsigned long)devpriv->dma[1].buf);
- }
+ dt282x_free_dma(dev);
comedi_legacy_detach(dev);
}
-static const struct dt282x_board boardtypes[] = {
- {
- .name = "dt2821",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2821-f",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 6500,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2821-g",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 4000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2823",
- .adbits = 16,
- .adchan_se = 0,
- .adchan_di = 4,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 16,
- }, {
- .name = "dt2824-pgh",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt2824-pgl",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt2825",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2827",
- .adbits = 16,
- .adchan_se = 0,
- .adchan_di = 4,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2828",
- .adbits = 12,
- .adchan_se = 4,
- .adchan_di = 0,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2829",
- .adbits = 16,
- .adchan_se = 8,
- .adchan_di = 0,
- .ai_speed = 33250,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 16,
- }, {
- .name = "dt21-ez",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt23-ez",
- .adbits = 16,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt24-ez",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt24-ez-pgl",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 1,
- .dachan = 0,
- .dabits = 0,
- },
-};
-
static struct comedi_driver dt282x_driver = {
.driver_name = "dt282x",
.module = THIS_MODULE,
@@ -1380,5 +1301,5 @@ static struct comedi_driver dt282x_driver = {
module_comedi_driver(dt282x_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Data Translation DT2821 series");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 4ab4de005924..56e21cc2dcfe 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -244,7 +244,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
#define DT3000_CHANNEL_MODE_DI 1
struct dt3k_private {
- void __iomem *io_addr;
unsigned int lock;
unsigned int ao_readback[2];
unsigned int ai_front;
@@ -255,14 +254,13 @@ struct dt3k_private {
static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
{
- struct dt3k_private *devpriv = dev->private;
int i;
unsigned int status = 0;
- writew(cmd, devpriv->io_addr + DPR_Command_Mbx);
+ writew(cmd, dev->mmio + DPR_Command_Mbx);
for (i = 0; i < TIMEOUT; i++) {
- status = readw(devpriv->io_addr + DPR_Command_Mbx);
+ status = readw(dev->mmio + DPR_Command_Mbx);
if ((status & DT3000_COMPLETION_MASK) != DT3000_NOTPROCESSED)
break;
udelay(1);
@@ -277,28 +275,24 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev,
unsigned int subsys, unsigned int chan,
unsigned int gain)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(subsys, devpriv->io_addr + DPR_SubSys);
+ writew(subsys, dev->mmio + DPR_SubSys);
- writew(chan, devpriv->io_addr + DPR_Params(0));
- writew(gain, devpriv->io_addr + DPR_Params(1));
+ writew(chan, dev->mmio + DPR_Params(0));
+ writew(gain, dev->mmio + DPR_Params(1));
dt3k_send_cmd(dev, CMD_READSINGLE);
- return readw(devpriv->io_addr + DPR_Params(2));
+ return readw(dev->mmio + DPR_Params(2));
}
static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
unsigned int chan, unsigned int data)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(subsys, devpriv->io_addr + DPR_SubSys);
+ writew(subsys, dev->mmio + DPR_SubSys);
- writew(chan, devpriv->io_addr + DPR_Params(0));
- writew(0, devpriv->io_addr + DPR_Params(1));
- writew(data, devpriv->io_addr + DPR_Params(2));
+ writew(chan, dev->mmio + DPR_Params(0));
+ writew(0, dev->mmio + DPR_Params(1));
+ writew(data, dev->mmio + DPR_Params(2));
dt3k_send_cmd(dev, CMD_WRITESINGLE);
}
@@ -313,7 +307,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
int i;
unsigned short data;
- front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+ front = readw(dev->mmio + DPR_AD_Buf_Front);
count = front - devpriv->ai_front;
if (count < 0)
count += AI_FIFO_DEPTH;
@@ -321,7 +315,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
rear = devpriv->ai_rear;
for (i = 0; i < count; i++) {
- data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+ data = readw(dev->mmio + DPR_ADC_buffer + rear);
comedi_buf_put(s, data);
rear++;
if (rear >= AI_FIFO_DEPTH)
@@ -329,17 +323,16 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
}
devpriv->ai_rear = rear;
- writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+ writew(rear, dev->mmio + DPR_AD_Buf_Rear);
}
-static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dt3k_ai_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_STOP);
- writew(0, devpriv->io_addr + DPR_Int_Mask);
+ writew(0, dev->mmio + DPR_Int_Mask);
return 0;
}
@@ -351,14 +344,13 @@ static int debug_n_ints;
static irqreturn_t dt3k_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct dt3k_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
if (!dev->attached)
return IRQ_NONE;
- status = readw(devpriv->io_addr + DPR_Intr_Flag);
+ status = readw(dev->mmio + DPR_Intr_Flag);
if (status & DT3000_ADFULL) {
dt3k_ai_empty_fifo(dev, s);
@@ -377,7 +369,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
}
static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
- unsigned int round_mode)
+ unsigned int flags)
{
int divider, base, prescale;
@@ -386,7 +378,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
for (prescale = 0; prescale < 16; prescale++) {
base = timer_base * (prescale + 1);
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -467,13 +459,13 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- dt3k_ns_to_timer(100, &arg, cmd->flags & TRIG_ROUND_MASK);
+ dt3k_ns_to_timer(100, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- dt3k_ns_to_timer(50, &arg, cmd->flags & TRIG_ROUND_MASK);
+ dt3k_ns_to_timer(50, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -491,7 +483,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct dt3k_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int i;
unsigned int chan, range, aref;
@@ -503,42 +494,40 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
chan = CR_CHAN(cmd->chanlist[i]);
range = CR_RANGE(cmd->chanlist[i]);
- writew((range << 6) | chan,
- devpriv->io_addr + DPR_ADC_buffer + i);
+ writew((range << 6) | chan, dev->mmio + DPR_ADC_buffer + i);
}
aref = CR_AREF(cmd->chanlist[0]);
- writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
+ writew(cmd->scan_end_arg, dev->mmio + DPR_Params(0));
if (cmd->convert_src == TRIG_TIMER) {
- divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
- writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
- writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
+ divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags);
+ writew((divider >> 16), dev->mmio + DPR_Params(1));
+ writew((divider & 0xffff), dev->mmio + DPR_Params(2));
}
if (cmd->scan_begin_src == TRIG_TIMER) {
tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
- writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
- writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
+ cmd->flags);
+ writew((tscandiv >> 16), dev->mmio + DPR_Params(3));
+ writew((tscandiv & 0xffff), dev->mmio + DPR_Params(4));
}
mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
- writew(mode, devpriv->io_addr + DPR_Params(5));
- writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
+ writew(mode, dev->mmio + DPR_Params(5));
+ writew(aref == AREF_DIFF, dev->mmio + DPR_Params(6));
- writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
+ writew(AI_FIFO_DEPTH / 2, dev->mmio + DPR_Params(7));
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_CONFIG);
writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
- devpriv->io_addr + DPR_Int_Mask);
+ dev->mmio + DPR_Int_Mask);
debug_n_ints = 0;
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_START);
return 0;
@@ -594,16 +583,14 @@ static int dt3k_ao_insn_read(struct comedi_device *dev,
static void dt3k_dio_config(struct comedi_device *dev, int bits)
{
- struct dt3k_private *devpriv = dev->private;
-
/* XXX */
- writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_DOUT, dev->mmio + DPR_SubSys);
- writew(bits, devpriv->io_addr + DPR_Params(0));
+ writew(bits, dev->mmio + DPR_Params(0));
#if 0
/* don't know */
- writew(0, devpriv->io_addr + DPR_Params(1));
- writew(0, devpriv->io_addr + DPR_Params(2));
+ writew(0, dev->mmio + DPR_Params(1));
+ writew(0, dev->mmio + DPR_Params(2));
#endif
dt3k_send_cmd(dev, CMD_CONFIG);
@@ -647,20 +634,20 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev,
static int dt3k_mem_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct dt3k_private *devpriv = dev->private;
unsigned int addr = CR_CHAN(insn->chanspec);
int i;
for (i = 0; i < insn->n; i++) {
- writew(SUBS_MEM, devpriv->io_addr + DPR_SubSys);
- writew(addr, devpriv->io_addr + DPR_Params(0));
- writew(1, devpriv->io_addr + DPR_Params(1));
+ writew(SUBS_MEM, dev->mmio + DPR_SubSys);
+ writew(addr, dev->mmio + DPR_Params(0));
+ writew(1, dev->mmio + DPR_Params(1));
dt3k_send_cmd(dev, CMD_READCODE);
- data[i] = readw(devpriv->io_addr + DPR_Params(2));
+ data[i] = readw(dev->mmio + DPR_Params(2));
}
return i;
@@ -690,8 +677,8 @@ static int dt3000_auto_attach(struct comedi_device *dev,
if (ret < 0)
return ret;
- devpriv->io_addr = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->io_addr)
+ dev->mmio = pci_ioremap_bar(pcidev, 0);
+ if (!dev->mmio)
return -ENOMEM;
if (pcidev->irq) {
@@ -765,14 +752,10 @@ static int dt3000_auto_attach(struct comedi_device *dev,
static void dt3000_detach(struct comedi_device *dev)
{
- struct dt3k_private *devpriv = dev->private;
-
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->io_addr)
- iounmap(devpriv->io_addr);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index b3aeb6fb2ad0..bd2ca2b371e6 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -653,6 +653,7 @@ static int dt9812_find_endpoints(struct comedi_device *dev)
for (i = 0; i < host->desc.bNumEndpoints; ++i) {
int dir = -1;
+
ep = &host->endpoint[i].desc;
switch (i) {
case 0:
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 22333c1ad88c..91c1e8cf5d24 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -51,7 +51,7 @@
#include "comedi_fc.h"
/*
- * PCI BAR2 Register map (devpriv->mmio)
+ * PCI BAR2 Register map (dev->mmio)
*/
#define FIRMWARE_REV_REG 0x00
#define FEATURES_REG_PRESENT_BIT (1 << 15)
@@ -148,7 +148,6 @@ static const struct hpdi_board hpdi_boards[] = {
struct hpdi_private {
void __iomem *plx9080_mmio;
- void __iomem *mmio;
uint32_t *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */
/* physical addresses of dma buffers */
dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
@@ -227,11 +226,11 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
return IRQ_NONE;
- hpdi_intr_status = readl(devpriv->mmio + INTERRUPT_STATUS_REG);
- hpdi_board_status = readl(devpriv->mmio + BOARD_STATUS_REG);
+ hpdi_intr_status = readl(dev->mmio + INTERRUPT_STATUS_REG);
+ hpdi_board_status = readl(dev->mmio + BOARD_STATUS_REG);
if (hpdi_intr_status)
- writel(hpdi_intr_status, devpriv->mmio + INTERRUPT_STATUS_REG);
+ writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG);
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
@@ -294,10 +293,8 @@ static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
static int gsc_hpdi_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct hpdi_private *devpriv = dev->private;
-
- writel(0, devpriv->mmio + BOARD_CONTROL_REG);
- writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(0, dev->mmio + BOARD_CONTROL_REG);
+ writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
gsc_hpdi_abort_dma(dev, 0);
@@ -316,7 +313,7 @@ static int gsc_hpdi_cmd(struct comedi_device *dev,
if (s->io_bits)
return -EINVAL;
- writel(RX_FIFO_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(RX_FIFO_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
gsc_hpdi_abort_dma(dev, 0);
@@ -349,13 +346,12 @@ static int gsc_hpdi_cmd(struct comedi_device *dev,
devpriv->dio_count = 1;
/* clear over/under run status flags */
- writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
- devpriv->mmio + BOARD_STATUS_REG);
+ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, dev->mmio + BOARD_STATUS_REG);
/* enable interrupts */
- writel(RX_FULL_INTR, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(RX_FULL_INTR, dev->mmio + INTERRUPT_CONTROL_REG);
- writel(RX_ENABLE_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(RX_ENABLE_BIT, dev->mmio + BOARD_CONTROL_REG);
return 0;
}
@@ -517,20 +513,20 @@ static int gsc_hpdi_init(struct comedi_device *dev)
uint32_t plx_intcsr_bits;
/* wait 10usec after reset before accessing fifos */
- writel(BOARD_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
udelay(10);
writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- devpriv->mmio + RX_PROG_ALMOST_REG);
+ dev->mmio + RX_PROG_ALMOST_REG);
writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- devpriv->mmio + TX_PROG_ALMOST_REG);
+ dev->mmio + TX_PROG_ALMOST_REG);
- devpriv->tx_fifo_size = readl(devpriv->mmio + TX_FIFO_SIZE_REG) &
+ devpriv->tx_fifo_size = readl(dev->mmio + TX_FIFO_SIZE_REG) &
FIFO_SIZE_MASK;
- devpriv->rx_fifo_size = readl(devpriv->mmio + RX_FIFO_SIZE_REG) &
+ devpriv->rx_fifo_size = readl(dev->mmio + RX_FIFO_SIZE_REG) &
FIFO_SIZE_MASK;
- writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
/* enable interrupts */
plx_intcsr_bits =
@@ -621,8 +617,8 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
pci_set_master(pcidev);
devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
- devpriv->mmio = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx9080_mmio || !devpriv->mmio) {
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!devpriv->plx9080_mmio || !dev->mmio) {
dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
}
@@ -696,8 +692,8 @@ static void gsc_hpdi_detach(struct comedi_device *dev)
writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
iounmap(devpriv->plx9080_mmio);
}
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
/* free pci dma buffers */
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
if (devpriv->dio_buffer[i])
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 0b8b2162b76b..a98cef2106a9 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -49,8 +49,6 @@ Configuration options: not applicable, uses PCI auto config
#include "../comedidev.h"
-#define PCI_DEVICE_ID_ICP_MULTI 0x8000
-
#define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */
#define ICP_MULTI_AI 2 /* R: Analogue input data */
#define ICP_MULTI_DAC_CSR 4 /* R/W: DAC command/status register */
@@ -110,7 +108,6 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
struct icp_multi_private {
char valid; /* card is usable */
- void __iomem *io_addr; /* Pointer to mapped io address */
unsigned int AdcCmdStatus; /* ADC Command/Status register */
unsigned int DacCmdStatus; /* DAC Command/Status register */
unsigned int IntEnable; /* Interrupt Enable register */
@@ -166,8 +163,7 @@ static void setup_channel_list(struct comedi_device *dev,
devpriv->AdcCmdStatus |= range;
/* Output channel, range, mode to ICP Multi */
- writew(devpriv->AdcCmdStatus,
- devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ writew(devpriv->AdcCmdStatus, dev->mmio + ICP_MULTI_ADC_CSR);
}
}
@@ -176,10 +172,9 @@ static int icp_multi_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct icp_multi_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ status = readw(dev->mmio + ICP_MULTI_ADC_CSR);
if ((status & ADC_BSY) == 0)
return 0;
return -EBUSY;
@@ -187,7 +182,8 @@ static int icp_multi_ai_eoc(struct comedi_device *dev,
static int icp_multi_insn_read_ai(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct icp_multi_private *devpriv = dev->private;
int ret = 0;
@@ -195,11 +191,11 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
/* Disable A/D conversion ready interrupt */
devpriv->IntEnable &= ~ADC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
/* Set up appropriate channel, mode and range data, for specified ch */
setup_channel_list(dev, s, &insn->chanspec, 1);
@@ -207,8 +203,7 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
for (n = 0; n < insn->n; n++) {
/* Set start ADC bit */
devpriv->AdcCmdStatus |= ADC_ST;
- writew(devpriv->AdcCmdStatus,
- devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ writew(devpriv->AdcCmdStatus, dev->mmio + ICP_MULTI_ADC_CSR);
devpriv->AdcCmdStatus &= ~ADC_ST;
udelay(1);
@@ -218,17 +213,16 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
if (ret)
break;
- data[n] =
- (readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
+ data[n] = (readw(dev->mmio + ICP_MULTI_AI) >> 4) & 0x0fff;
}
/* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
return ret ? ret : n;
}
@@ -238,10 +232,9 @@ static int icp_multi_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct icp_multi_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ status = readw(dev->mmio + ICP_MULTI_DAC_CSR);
if ((status & DAC_BSY) == 0)
return 0;
return -EBUSY;
@@ -249,7 +242,8 @@ static int icp_multi_ao_eoc(struct comedi_device *dev,
static int icp_multi_insn_write_ao(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct icp_multi_private *devpriv = dev->private;
int n, chan, range;
@@ -257,11 +251,11 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
/* Disable D/A conversion ready interrupt */
devpriv->IntEnable &= ~DAC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
/* Get channel number and range */
chan = CR_CHAN(insn->chanspec);
@@ -276,7 +270,7 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
devpriv->DacCmdStatus |= range_codes_analog[range];
devpriv->DacCmdStatus |= (chan << 8);
- writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
for (n = 0; n < insn->n; n++) {
/* Wait for analogue output data register to be
@@ -286,12 +280,12 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
/* Disable interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable,
- devpriv->io_addr + ICP_MULTI_INT_EN);
+ dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus,
- devpriv->io_addr + ICP_MULTI_INT_STAT);
+ dev->mmio + ICP_MULTI_INT_STAT);
/* Clear data received */
devpriv->ao_data[chan] = 0;
@@ -300,12 +294,11 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
}
/* Write data to analogue output data register */
- writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
+ writew(data[n], dev->mmio + ICP_MULTI_AO);
/* Set DAC_ST bit to write the data to selected channel */
devpriv->DacCmdStatus |= DAC_ST;
- writew(devpriv->DacCmdStatus,
- devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
devpriv->DacCmdStatus &= ~DAC_ST;
/* Save analogue output data */
@@ -334,11 +327,10 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev,
static int icp_multi_insn_bits_di(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct icp_multi_private *devpriv = dev->private;
-
- data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
+ data[1] = readw(dev->mmio + ICP_MULTI_DI);
return insn->n;
}
@@ -348,12 +340,10 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct icp_multi_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
+ writew(s->state, dev->mmio + ICP_MULTI_DO);
- data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
+ data[1] = readw(dev->mmio + ICP_MULTI_DI);
return insn->n;
}
@@ -376,11 +366,10 @@ static int icp_multi_insn_write_ctr(struct comedi_device *dev,
static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
{
struct comedi_device *dev = d;
- struct icp_multi_private *devpriv = dev->private;
int int_no;
/* Is this interrupt from our board? */
- int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ;
+ int_no = readw(dev->mmio + ICP_MULTI_INT_STAT) & Status_IRQ;
if (!int_no)
/* No, exit */
return IRQ_NONE;
@@ -420,7 +409,7 @@ static int check_channel_list(struct comedi_device *dev,
/* Check that we at least have one channel to check */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
/* Check all channels */
@@ -428,14 +417,14 @@ static int check_channel_list(struct comedi_device *dev,
/* Check that channel number is < maximum */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
if (CR_CHAN(chanlist[i]) > (s->nchan / 2)) {
- comedi_error(dev,
- "Incorrect differential ai ch-nr");
+ dev_err(dev->class_dev,
+ "Incorrect differential ai ch-nr\n");
return 0;
}
} else {
if (CR_CHAN(chanlist[i]) > s->n_chan) {
- comedi_error(dev,
- "Incorrect ai channel number");
+ dev_err(dev->class_dev,
+ "Incorrect ai channel number\n");
return 0;
}
}
@@ -450,8 +439,8 @@ static int icp_multi_reset(struct comedi_device *dev)
unsigned int i;
/* Clear INT enables and requests */
- writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
- writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(0, dev->mmio + ICP_MULTI_INT_EN);
+ writew(0x00ff, dev->mmio + ICP_MULTI_INT_STAT);
/* Set DACs to 0..5V range and 0V output */
for (i = 0; i < 4; i++) {
@@ -461,21 +450,20 @@ static int icp_multi_reset(struct comedi_device *dev)
devpriv->DacCmdStatus |= (i << 8);
/* Output 0V */
- writew(0, devpriv->io_addr + ICP_MULTI_AO);
+ writew(0, dev->mmio + ICP_MULTI_AO);
/* Set start conversion bit */
devpriv->DacCmdStatus |= DAC_ST;
/* Output to command / status register */
- writew(devpriv->DacCmdStatus,
- devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
/* Delay to allow DAC time to recover */
udelay(1);
}
/* Digital outputs to 0 */
- writew(0, devpriv->io_addr + ICP_MULTI_DO);
+ writew(0, dev->mmio + ICP_MULTI_DO);
return 0;
}
@@ -496,8 +484,8 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->io_addr = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->io_addr)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!dev->mmio)
return -ENOMEM;
ret = comedi_alloc_subdevices(dev, 5);
@@ -575,8 +563,8 @@ static void icp_multi_detach(struct comedi_device *dev)
icp_multi_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv && devpriv->io_addr)
- iounmap(devpriv->io_addr);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -594,7 +582,7 @@ static int icp_multi_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id icp_multi_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ICP, PCI_DEVICE_ID_ICP_MULTI) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ICP, 0x8000) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, icp_multi_pci_table);
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 2516ce834839..687db433e131 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -33,6 +33,7 @@
/*
* Register I/O map
*/
+#define II20K_SIZE 0x400
#define II20K_MOD_OFFSET 0x100
#define II20K_ID_REG 0x00
#define II20K_ID_MOD1_EMPTY (1 << 7)
@@ -135,16 +136,10 @@ struct ii20k_ao_private {
unsigned int last_data[2];
};
-struct ii20k_private {
- void __iomem *ioaddr;
-};
-
static void __iomem *ii20k_module_iobase(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ii20k_private *devpriv = dev->private;
-
- return devpriv->ioaddr + (s->index + 1) * II20K_MOD_OFFSET;
+ return dev->mmio + (s->index + 1) * II20K_MOD_OFFSET;
}
static int ii20k_ao_insn_read(struct comedi_device *dev,
@@ -281,7 +276,6 @@ static int ii20k_ai_insn_read(struct comedi_device *dev,
static void ii20k_dio_config(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ii20k_private *devpriv = dev->private;
unsigned char ctrl01 = 0;
unsigned char ctrl23 = 0;
unsigned char dir_ena = 0;
@@ -338,9 +332,9 @@ static void ii20k_dio_config(struct comedi_device *dev,
ctrl23 |= II20K_CTRL23_SET;
/* order is important */
- writeb(ctrl01, devpriv->ioaddr + II20K_CTRL01_REG);
- writeb(ctrl23, devpriv->ioaddr + II20K_CTRL23_REG);
- writeb(dir_ena, devpriv->ioaddr + II20K_DIR_ENA_REG);
+ writeb(ctrl01, dev->mmio + II20K_CTRL01_REG);
+ writeb(ctrl23, dev->mmio + II20K_CTRL23_REG);
+ writeb(dir_ena, dev->mmio + II20K_DIR_ENA_REG);
}
static int ii20k_dio_insn_config(struct comedi_device *dev,
@@ -375,29 +369,28 @@ static int ii20k_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ii20k_private *devpriv = dev->private;
unsigned int mask;
mask = comedi_dio_update_state(s, data);
if (mask) {
if (mask & 0x000000ff)
writeb((s->state >> 0) & 0xff,
- devpriv->ioaddr + II20K_DIO0_REG);
+ dev->mmio + II20K_DIO0_REG);
if (mask & 0x0000ff00)
writeb((s->state >> 8) & 0xff,
- devpriv->ioaddr + II20K_DIO1_REG);
+ dev->mmio + II20K_DIO1_REG);
if (mask & 0x00ff0000)
writeb((s->state >> 16) & 0xff,
- devpriv->ioaddr + II20K_DIO2_REG);
+ dev->mmio + II20K_DIO2_REG);
if (mask & 0xff000000)
writeb((s->state >> 24) & 0xff,
- devpriv->ioaddr + II20K_DIO3_REG);
+ dev->mmio + II20K_DIO3_REG);
}
- data[1] = readb(devpriv->ioaddr + II20K_DIO0_REG);
- data[1] |= readb(devpriv->ioaddr + II20K_DIO1_REG) << 8;
- data[1] |= readb(devpriv->ioaddr + II20K_DIO2_REG) << 16;
- data[1] |= readb(devpriv->ioaddr + II20K_DIO3_REG) << 24;
+ data[1] = readb(dev->mmio + II20K_DIO0_REG);
+ data[1] |= readb(dev->mmio + II20K_DIO1_REG) << 8;
+ data[1] |= readb(dev->mmio + II20K_DIO2_REG) << 16;
+ data[1] |= readb(dev->mmio + II20K_DIO3_REG) << 24;
return insn->n;
}
@@ -446,19 +439,32 @@ static int ii20k_init_module(struct comedi_device *dev,
static int ii20k_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- struct ii20k_private *devpriv;
struct comedi_subdevice *s;
+ unsigned int membase;
unsigned char id;
bool has_dio;
int ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ membase = it->options[0];
+ if (!membase || (membase & ~(0x100000 - II20K_SIZE))) {
+ dev_warn(dev->class_dev,
+ "%s: invalid memory address specified\n",
+ dev->board_name);
+ return -EINVAL;
+ }
- devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0];
+ if (!request_mem_region(membase, II20K_SIZE, dev->board_name)) {
+ dev_warn(dev->class_dev, "%s: I/O mem conflict (%#x,%u)\n",
+ dev->board_name, membase, II20K_SIZE);
+ return -EIO;
+ }
+ dev->iobase = membase; /* actually, a memory address */
- id = readb(devpriv->ioaddr + II20K_ID_REG);
+ dev->mmio = ioremap(membase, II20K_SIZE);
+ if (!dev->mmio)
+ return -ENOMEM;
+
+ id = readb(dev->mmio + II20K_ID_REG);
switch (id & II20K_ID_MASK) {
case II20K_ID_PCI20001C_1A:
has_dio = false;
@@ -521,11 +527,19 @@ static int ii20k_attach(struct comedi_device *dev,
return 0;
}
+static void ii20k_detach(struct comedi_device *dev)
+{
+ if (dev->mmio)
+ iounmap(dev->mmio);
+ if (dev->iobase) /* actually, a memory address */
+ release_mem_region(dev->iobase, II20K_SIZE);
+}
+
static struct comedi_driver ii20k_driver = {
.driver_name = "ii_pci20kc",
.module = THIS_MODULE,
.attach = ii20k_attach,
- .detach = comedi_legacy_detach,
+ .detach = ii20k_detach,
};
module_comedi_driver(ii20k_driver);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index a8db9d86aadc..7b20e19ecbf7 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -196,6 +196,7 @@ static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
+
result.fx = get_s16(&channel->min_full_scale.fx);
result.fy = get_s16(&channel->min_full_scale.fy);
result.fz = get_s16(&channel->min_full_scale.fz);
@@ -209,6 +210,7 @@ static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
+
result.fx = get_s16(&channel->max_full_scale.fx);
result.fy = get_s16(&channel->max_full_scale.fy);
result.fz = get_s16(&channel->max_full_scale.fz);
@@ -319,6 +321,8 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
unsigned int *val)
{
int result = 0;
+ int value;
+
if (pos && val) {
/* Skip over non hex */
for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
@@ -326,7 +330,6 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
/* Collect value */
*val = 0;
for (; *pos < size; (*pos)++) {
- int value;
value = hex_to_bin(data[*pos]);
if (value >= 0) {
result = 1;
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index ec43c38958de..f46722c2648f 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -93,6 +93,67 @@ static int ke_counter_insn_read(struct comedi_device *dev,
return insn->n;
}
+static void ke_counter_reset(struct comedi_device *dev)
+{
+ unsigned int chan;
+
+ for (chan = 0; chan < 3; chan++)
+ outb(0, dev->iobase + KE_RESET_REG(chan));
+}
+
+static int ke_counter_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned char src;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ switch (data[1]) {
+ case KE_CLK_20MHZ: /* default */
+ src = KE_OSC_SEL_20MHZ;
+ break;
+ case KE_CLK_4MHZ: /* option */
+ src = KE_OSC_SEL_4MHZ;
+ break;
+ case KE_CLK_EXT: /* Pin 21 on D-sub */
+ src = KE_OSC_SEL_EXT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ outb(src, dev->iobase + KE_OSC_SEL_REG);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ src = inb(dev->iobase + KE_OSC_SEL_REG);
+ switch (src) {
+ case KE_OSC_SEL_20MHZ:
+ data[1] = KE_CLK_20MHZ;
+ data[2] = 50; /* 50ns */
+ break;
+ case KE_OSC_SEL_4MHZ:
+ data[1] = KE_CLK_4MHZ;
+ data[2] = 250; /* 250ns */
+ break;
+ case KE_OSC_SEL_EXT:
+ data[1] = KE_CLK_EXT;
+ data[2] = 0; /* Unknown */
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case INSN_CONFIG_RESET:
+ ke_counter_reset(dev);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return insn->n;
+}
+
static int ke_counter_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -130,6 +191,7 @@ static int ke_counter_auto_attach(struct comedi_device *dev,
s->range_table = &range_unknown;
s->insn_read = ke_counter_insn_read;
s->insn_write = ke_counter_insn_write;
+ s->insn_config = ke_counter_insn_config;
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_DO;
@@ -141,9 +203,7 @@ static int ke_counter_auto_attach(struct comedi_device *dev,
outb(KE_OSC_SEL_20MHZ, dev->iobase + KE_OSC_SEL_REG);
- outb(0, dev->iobase + KE_RESET_REG(0));
- outb(0, dev->iobase + KE_RESET_REG(1));
- outb(0, dev->iobase + KE_RESET_REG(2));
+ ke_counter_reset(dev);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 25ce2f78db81..9a5c535451a1 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -170,7 +170,6 @@ broken.
#define ME4000_AI_MIN_TICKS 66
#define ME4000_AI_MIN_SAMPLE_TIME 2000
-#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
#define ME4000_AI_CHANNEL_LIST_COUNT 1024
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 0ff126b1fdfd..37a6fa92c656 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -167,7 +167,6 @@ static const struct me_board me_boards[] = {
struct me_private_data {
void __iomem *plx_regbase; /* PLX configuration base address */
- void __iomem *me_regbase; /* Base address of the Meilhaus card */
unsigned short control_1; /* Mirror of CONTROL_1 register */
unsigned short control_2; /* Mirror of CONTROL_2 register */
@@ -209,7 +208,7 @@ static int me_dio_insn_config(struct comedi_device *dev,
else
devpriv->control_2 &= ~ENABLE_PORT_B;
- writew(devpriv->control_2, devpriv->me_regbase + ME_CONTROL_2);
+ writew(devpriv->control_2, dev->mmio + ME_CONTROL_2);
return insn->n;
}
@@ -219,9 +218,8 @@ static int me_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct me_private_data *dev_private = dev->private;
- void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A;
- void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B;
+ void __iomem *mmio_porta = dev->mmio + ME_DIO_PORT_A;
+ void __iomem *mmio_portb = dev->mmio + ME_DIO_PORT_B;
unsigned int mask;
unsigned int val;
@@ -253,10 +251,9 @@ static int me_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct me_private_data *dev_private = dev->private;
unsigned int status;
- status = readw(dev_private->me_regbase + ME_STATUS);
+ status = readw(dev->mmio + ME_STATUS);
if ((status & 0x0004) == 0)
return 0;
return -EBUSY;
@@ -276,32 +273,32 @@ static int me_ai_insn_read(struct comedi_device *dev,
/* stop any running conversion */
dev_private->control_1 &= 0xFFFC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
/* clear chanlist and ad fifo */
dev_private->control_2 &= ~(ENABLE_ADFIFO | ENABLE_CHANLIST);
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* reset any pending interrupt */
- writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
+ writew(0x00, dev->mmio + ME_RESET_INTERRUPT);
/* enable the chanlist and ADC fifo */
dev_private->control_2 |= (ENABLE_ADFIFO | ENABLE_CHANLIST);
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* write to channel list fifo */
val = chan & 0x0f; /* b3:b0 channel */
val |= (rang & 0x03) << 4; /* b5:b4 gain */
val |= (rang & 0x04) << 4; /* b6 polarity */
val |= ((aref & AREF_DIFF) ? 0x80 : 0); /* b7 differential */
- writew(val & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST);
+ writew(val & 0xff, dev->mmio + ME_CHANNEL_LIST);
/* set ADC mode to software trigger */
dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
/* start conversion by reading from ADC_START */
- readw(dev_private->me_regbase + ME_ADC_START);
+ readw(dev->mmio + ME_ADC_START);
/* wait for ADC fifo not empty flag */
ret = comedi_timeout(dev, s, insn, me_ai_eoc, 0);
@@ -309,13 +306,13 @@ static int me_ai_insn_read(struct comedi_device *dev,
return ret;
/* get value from ADC fifo */
- val = readw(dev_private->me_regbase + ME_READ_AD_FIFO);
+ val = readw(dev->mmio + ME_READ_AD_FIFO);
val = (val ^ 0x800) & 0x0fff;
data[0] = val;
/* stop any running conversion */
dev_private->control_1 &= 0xFFFC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
return 1;
}
@@ -332,11 +329,11 @@ static int me_ao_insn_write(struct comedi_device *dev,
/* Enable all DAC */
dev_private->control_2 |= ENABLE_DAC;
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* and set DAC to "buffered" mode */
dev_private->control_2 |= BUFFERED_DAC;
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* Set dac-control register */
for (i = 0; i < insn->n; i++) {
@@ -349,21 +346,20 @@ static int me_ao_insn_write(struct comedi_device *dev,
dev_private->dac_control |=
((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
}
- writew(dev_private->dac_control,
- dev_private->me_regbase + ME_DAC_CONTROL);
+ writew(dev_private->dac_control, dev->mmio + ME_DAC_CONTROL);
/* Update dac-control register */
- readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);
+ readw(dev->mmio + ME_DAC_CONTROL_UPDATE);
/* Set data register */
for (i = 0; i < insn->n; i++) {
writew((data[0] & s->maxdata),
- dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
+ dev->mmio + ME_DAC_DATA_A + (chan << 1));
dev_private->ao_readback[chan] = (data[0] & s->maxdata);
}
/* Update dac with data registers */
- readw(dev_private->me_regbase + ME_DAC_UPDATE);
+ readw(dev->mmio + ME_DAC_UPDATE);
return insn->n;
}
@@ -396,13 +392,13 @@ static int me2600_xilinx_download(struct comedi_device *dev,
writel(0x00, dev_private->plx_regbase + PLX9052_INTCSR);
/* First, make a dummy read to reset xilinx */
- value = readw(dev_private->me_regbase + XILINX_DOWNLOAD_RESET);
+ value = readw(dev->mmio + XILINX_DOWNLOAD_RESET);
/* Wait until reset is over */
sleep(1);
/* Write a dummy value to Xilinx */
- writeb(0x00, dev_private->me_regbase + 0x0);
+ writeb(0x00, dev->mmio + 0x0);
sleep(1);
/*
@@ -426,12 +422,11 @@ static int me2600_xilinx_download(struct comedi_device *dev,
* Firmware data start at offset 16
*/
for (i = 0; i < file_length; i++)
- writeb((data[16 + i] & 0xff),
- dev_private->me_regbase + 0x0);
+ writeb((data[16 + i] & 0xff), dev->mmio + 0x0);
/* Write 5 dummy values to xilinx */
for (i = 0; i < 5; i++)
- writeb(0x00, dev_private->me_regbase + 0x0);
+ writeb(0x00, dev->mmio + 0x0);
/* Test if there was an error during download -> INTB was thrown */
value = readl(dev_private->plx_regbase + PLX9052_INTCSR);
@@ -459,10 +454,10 @@ static int me_reset(struct comedi_device *dev)
struct me_private_data *dev_private = dev->private;
/* Reset board */
- writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
- writew(0x00, dev_private->me_regbase + ME_CONTROL_2);
- writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
- writew(0x00, dev_private->me_regbase + ME_DAC_CONTROL);
+ writew(0x00, dev->mmio + ME_CONTROL_1);
+ writew(0x00, dev->mmio + ME_CONTROL_2);
+ writew(0x00, dev->mmio + ME_RESET_INTERRUPT);
+ writew(0x00, dev->mmio + ME_DAC_CONTROL);
/* Save values in the board context */
dev_private->dac_control = 0;
@@ -500,8 +495,8 @@ static int me_auto_attach(struct comedi_device *dev,
if (!dev_private->plx_regbase)
return -ENOMEM;
- dev_private->me_regbase = pci_ioremap_bar(pcidev, 2);
- if (!dev_private->me_regbase)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!dev->mmio)
return -ENOMEM;
/* Download firmware and reset card */
@@ -559,9 +554,9 @@ static void me_detach(struct comedi_device *dev)
struct me_private_data *dev_private = dev->private;
if (dev_private) {
- if (dev_private->me_regbase) {
+ if (dev->mmio) {
me_reset(dev);
- iounmap(dev_private->me_regbase);
+ iounmap(dev->mmio);
}
if (dev_private->plx_regbase)
iounmap(dev_private->plx_regbase);
diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c
index a4f7d6f138df..464f4b4745c7 100644
--- a/drivers/staging/comedi/drivers/mf6x4.c
+++ b/drivers/staging/comedi/drivers/mf6x4.c
@@ -93,7 +93,6 @@ struct mf6x4_private {
* and MF634 yet we will call them 0, 1, 2
*/
void __iomem *bar0_mem;
- void __iomem *bar1_mem;
void __iomem *bar2_mem;
/*
@@ -108,25 +107,22 @@ struct mf6x4_private {
};
static int mf6x4_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct mf6x4_private *devpriv = dev->private;
-
- data[1] = ioread16(devpriv->bar1_mem + MF6X4_DIN_R) & MF6X4_DIN_M;
+ data[1] = ioread16(dev->mmio + MF6X4_DIN_R) & MF6X4_DIN_M;
return insn->n;
}
static int mf6x4_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct mf6x4_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- iowrite16(s->state & MF6X4_DOUT_M,
- devpriv->bar1_mem + MF6X4_DOUT_R);
+ iowrite16(s->state & MF6X4_DOUT_M, dev->mmio + MF6X4_DOUT_R);
data[1] = s->state;
@@ -149,40 +145,40 @@ static int mf6x4_ai_eoc(struct comedi_device *dev,
static int mf6x4_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct mf6x4_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int ret;
int i;
int d;
/* Set the ADC channel number in the scan list */
- iowrite16((1 << chan) & MF6X4_ADCTRL_M,
- devpriv->bar1_mem + MF6X4_ADCTRL_R);
+ iowrite16((1 << chan) & MF6X4_ADCTRL_M, dev->mmio + MF6X4_ADCTRL_R);
for (i = 0; i < insn->n; i++) {
/* Trigger ADC conversion by reading ADSTART */
- ioread16(devpriv->bar1_mem + MF6X4_ADSTART_R);
+ ioread16(dev->mmio + MF6X4_ADSTART_R);
ret = comedi_timeout(dev, s, insn, mf6x4_ai_eoc, 0);
if (ret)
return ret;
/* Read the actual value */
- d = ioread16(devpriv->bar1_mem + MF6X4_ADDATA_R);
+ d = ioread16(dev->mmio + MF6X4_ADDATA_R);
d &= s->maxdata;
data[i] = d;
}
- iowrite16(0x0, devpriv->bar1_mem + MF6X4_ADCTRL_R);
+ iowrite16(0x0, dev->mmio + MF6X4_ADCTRL_R);
return insn->n;
}
static int mf6x4_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct mf6x4_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
@@ -195,8 +191,7 @@ static int mf6x4_ao_insn_write(struct comedi_device *dev,
devpriv->gpioc_R);
for (i = 0; i < insn->n; i++) {
- iowrite16(data[i] & MF6X4_DA_M,
- devpriv->bar1_mem + MF6X4_DAC_R(chan));
+ iowrite16(data[i] & MF6X4_DA_M, dev->mmio + MF6X4_DAC_R(chan));
devpriv->ao_readback[chan] = data[i];
}
@@ -246,8 +241,8 @@ static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context)
if (!devpriv->bar0_mem)
return -ENODEV;
- devpriv->bar1_mem = pci_ioremap_bar(pcidev, board->bar_nums[1]);
- if (!devpriv->bar1_mem)
+ dev->mmio = pci_ioremap_bar(pcidev, board->bar_nums[1]);
+ if (!dev->mmio)
return -ENODEV;
devpriv->bar2_mem = pci_ioremap_bar(pcidev, board->bar_nums[2]);
@@ -310,8 +305,8 @@ static void mf6x4_detach(struct comedi_device *dev)
if (devpriv->bar0_mem)
iounmap(devpriv->bar0_mem);
- if (devpriv->bar1_mem)
- iounmap(devpriv->bar1_mem);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->bar2_mem)
iounmap(devpriv->bar2_mem);
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 19c029acbc99..4f7829010a99 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -90,10 +90,12 @@ static unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel));
unsigned empty_count = (fcr_bits >> 16) & 0xff;
unsigned full_count = fcr_bits & 0xff;
+
return empty_count + full_count;
}
-int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
+int mite_setup2(struct comedi_device *dev,
+ struct mite_struct *mite, bool use_win1)
{
unsigned long length;
int i;
@@ -104,24 +106,24 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
mite->mite_io_addr = pci_ioremap_bar(mite->pcidev, 0);
if (!mite->mite_io_addr) {
- dev_err(&mite->pcidev->dev,
+ dev_err(dev->class_dev,
"Failed to remap mite io memory address\n");
return -ENOMEM;
}
mite->mite_phys_addr = pci_resource_start(mite->pcidev, 0);
- mite->daq_io_addr = pci_ioremap_bar(mite->pcidev, 1);
- if (!mite->daq_io_addr) {
- dev_err(&mite->pcidev->dev,
+ dev->mmio = pci_ioremap_bar(mite->pcidev, 1);
+ if (!dev->mmio) {
+ dev_err(dev->class_dev,
"Failed to remap daq io memory address\n");
return -ENOMEM;
}
mite->daq_phys_addr = pci_resource_start(mite->pcidev, 1);
length = pci_resource_len(mite->pcidev, 1);
- if (use_iodwbsr_1) {
+ if (use_win1) {
writel(0, mite->mite_io_addr + MITE_IODWBSR);
- dev_info(&mite->pcidev->dev,
+ dev_info(dev->class_dev,
"using I/O Window Base Size register 1\n");
writel(mite->daq_phys_addr | WENAB |
MITE_IODWBSR_1_WSIZE_bits(length),
@@ -147,7 +149,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
mite->num_channels = mite_csigr_dmac(csigr_bits);
if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
- dev_warn(&mite->pcidev->dev,
+ dev_warn(dev->class_dev,
"mite: bug? chip claims to have %i dma channels. Setting to %i.\n",
mite->num_channels, MAX_MITE_DMA_CHANNELS);
mite->num_channels = MAX_MITE_DMA_CHANNELS;
@@ -162,36 +164,22 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
mite->mite_io_addr + MITE_CHCR(i));
}
mite->fifo_size = mite_fifo_size(mite, 0);
- dev_info(&mite->pcidev->dev, "fifo size is %i.\n", mite->fifo_size);
+ dev_info(dev->class_dev, "fifo size is %i.\n", mite->fifo_size);
return 0;
}
EXPORT_SYMBOL_GPL(mite_setup2);
-int mite_setup(struct mite_struct *mite)
+void mite_detach(struct mite_struct *mite)
{
- return mite_setup2(mite, 0);
-}
-EXPORT_SYMBOL_GPL(mite_setup);
-
-void mite_unsetup(struct mite_struct *mite)
-{
- /* unsigned long offset, start, length; */
-
if (!mite)
return;
- if (mite->mite_io_addr) {
+ if (mite->mite_io_addr)
iounmap(mite->mite_io_addr);
- mite->mite_io_addr = NULL;
- }
- if (mite->daq_io_addr) {
- iounmap(mite->daq_io_addr);
- mite->daq_io_addr = NULL;
- }
- if (mite->mite_phys_addr)
- mite->mite_phys_addr = 0;
+
+ kfree(mite);
}
-EXPORT_SYMBOL_GPL(mite_unsetup);
+EXPORT_SYMBOL_GPL(mite_detach);
struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite)
{
@@ -450,12 +438,14 @@ EXPORT_SYMBOL_GPL(mite_prep_dma);
static u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
+
return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
}
u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
+
return readl(mite->mite_io_addr +
MITE_FCR(mite_chan->channel)) & 0x000000FF;
}
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index e6e58e989b73..b2b12045b3a5 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -55,7 +55,6 @@ struct mite_struct {
resource_size_t mite_phys_addr;
void __iomem *mite_io_addr;
resource_size_t daq_phys_addr;
- void __iomem *daq_io_addr;
struct mite_channel channels[MAX_MITE_DMA_CHANNELS];
short channel_allocated[MAX_MITE_DMA_CHANNELS];
int num_channels;
@@ -65,24 +64,15 @@ struct mite_struct {
struct mite_struct *mite_alloc(struct pci_dev *pcidev);
-static inline void mite_free(struct mite_struct *mite)
-{
- kfree(mite);
-}
-
-static inline unsigned int mite_irq(struct mite_struct *mite)
-{
- return mite->pcidev->irq;
-};
+int mite_setup2(struct comedi_device *, struct mite_struct *, bool use_win1);
-static inline unsigned int mite_device_id(struct mite_struct *mite)
+static inline int mite_setup(struct comedi_device *dev,
+ struct mite_struct *mite)
{
- return mite->pcidev->device;
-};
+ return mite_setup2(dev, mite, false);
+}
-int mite_setup(struct mite_struct *mite);
-int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1);
-void mite_unsetup(struct mite_struct *mite);
+void mite_detach(struct mite_struct *mite);
struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite);
void mite_free_ring(struct mite_dma_descriptor_ring *ring);
struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
@@ -122,11 +112,6 @@ void mite_prep_dma(struct mite_channel *mite_chan,
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
struct comedi_subdevice *s);
-static inline int CHAN_OFFSET(int channel)
-{
- return 0x500 + 0x100 * channel;
-};
-
enum mite_registers {
/* The bits 0x90180700 in MITE_UNKNOWN_DMA_BURST_REG can be
written and read back. The bits 0x1f always read as 1.
@@ -138,90 +123,25 @@ enum mite_registers {
MITE_PCI_CONFIG_OFFSET = 0x300,
MITE_CSIGR = 0x460 /* chip signature */
};
-static inline int MITE_CHOR(int channel)
-{ /* channel operation */
- return CHAN_OFFSET(channel) + 0x0;
-};
-static inline int MITE_CHCR(int channel)
-{ /* channel control */
- return CHAN_OFFSET(channel) + 0x4;
-};
-
-static inline int MITE_TCR(int channel)
-{ /* transfer count */
- return CHAN_OFFSET(channel) + 0x8;
-};
-
-static inline int MITE_MCR(int channel)
-{ /* memory configuration */
- return CHAN_OFFSET(channel) + 0xc;
-};
-
-static inline int MITE_MAR(int channel)
-{ /* memory address */
- return CHAN_OFFSET(channel) + 0x10;
-};
-
-static inline int MITE_DCR(int channel)
-{ /* device configuration */
- return CHAN_OFFSET(channel) + 0x14;
-};
-
-static inline int MITE_DAR(int channel)
-{ /* device address */
- return CHAN_OFFSET(channel) + 0x18;
-};
-
-static inline int MITE_LKCR(int channel)
-{ /* link configuration */
- return CHAN_OFFSET(channel) + 0x1c;
-};
-
-static inline int MITE_LKAR(int channel)
-{ /* link address */
- return CHAN_OFFSET(channel) + 0x20;
-};
-
-static inline int MITE_LLKAR(int channel)
-{ /* see mite section of tnt5002 manual */
- return CHAN_OFFSET(channel) + 0x24;
-};
-
-static inline int MITE_BAR(int channel)
-{ /* base address */
- return CHAN_OFFSET(channel) + 0x28;
-};
-
-static inline int MITE_BCR(int channel)
-{ /* base count */
- return CHAN_OFFSET(channel) + 0x2c;
-};
-
-static inline int MITE_SAR(int channel)
-{ /* ? address */
- return CHAN_OFFSET(channel) + 0x30;
-};
-
-static inline int MITE_WSCR(int channel)
-{ /* ? */
- return CHAN_OFFSET(channel) + 0x34;
-};
-
-static inline int MITE_WSER(int channel)
-{ /* ? */
- return CHAN_OFFSET(channel) + 0x38;
-};
-
-static inline int MITE_CHSR(int channel)
-{ /* channel status */
- return CHAN_OFFSET(channel) + 0x3c;
-};
-
-static inline int MITE_FCR(int channel)
-{ /* fifo count */
- return CHAN_OFFSET(channel) + 0x40;
-};
+#define MITE_CHAN(x) (0x500 + 0x100 * (x))
+#define MITE_CHOR(x) (0x00 + MITE_CHAN(x)) /* channel operation */
+#define MITE_CHCR(x) (0x04 + MITE_CHAN(x)) /* channel control */
+#define MITE_TCR(x) (0x08 + MITE_CHAN(x)) /* transfer count */
+#define MITE_MCR(x) (0x0c + MITE_CHAN(x)) /* memory configuration */
+#define MITE_MAR(x) (0x10 + MITE_CHAN(x)) /* memory address */
+#define MITE_DCR(x) (0x14 + MITE_CHAN(x)) /* device configuration */
+#define MITE_DAR(x) (0x18 + MITE_CHAN(x)) /* device address */
+#define MITE_LKCR(x) (0x1c + MITE_CHAN(x)) /* link configuration */
+#define MITE_LKAR(x) (0x20 + MITE_CHAN(x)) /* link address */
+#define MITE_LLKAR(x) (0x24 + MITE_CHAN(x)) /* see tnt5002 manual */
+#define MITE_BAR(x) (0x28 + MITE_CHAN(x)) /* base address */
+#define MITE_BCR(x) (0x2c + MITE_CHAN(x)) /* base count */
+#define MITE_SAR(x) (0x30 + MITE_CHAN(x)) /* ? address */
+#define MITE_WSCR(x) (0x34 + MITE_CHAN(x)) /* ? */
+#define MITE_WSER(x) (0x38 + MITE_CHAN(x)) /* ? */
+#define MITE_CHSR(x) (0x3c + MITE_CHAN(x)) /* channel status */
+#define MITE_FCR(x) (0x40 + MITE_CHAN(x)) /* fifo count */
enum MITE_IODWBSR_bits {
WENAB = 0x80, /* window enable */
@@ -269,11 +189,9 @@ static inline int mite_csigr_dmac(u32 csigr_bits)
static inline int mite_csigr_wpdep(u32 csigr_bits)
{ /* write post fifo depth */
unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
- if (wpdep_bits == 0)
- return 0;
- else
- return 1 << (wpdep_bits - 1);
-};
+
+ return (wpdep_bits) ? (1 << (wpdep_bits - 1)) : 0;
+}
static inline int mite_csigr_wins(u32 csigr_bits)
{
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index f770400a0e81..1241f9987cab 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -56,9 +56,6 @@ Configuration Options:
#include <linux/delay.h>
-/* Consecutive I/O port addresses */
-#define MPC624_SIZE 16
-
/* Offsets of different ports */
#define MPC624_MASTER_CONTROL 0 /* not used */
#define MPC624_GNMUXCH 1 /* Gain, Mux, Channel of ADC */
@@ -279,7 +276,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], MPC624_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index b74b9e9bfd4a..e841a5a3ec4f 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -28,8 +28,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
#include <linux/interrupt.h>
#include "../comedidev.h"
-#define MULTIQ3_SIZE 16
-
/*
* MULTIQ-3 port offsets
*/
@@ -189,12 +187,12 @@ static int multiq3_encoder_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- int n;
int chan = CR_CHAN(insn->chanspec);
int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+ int value;
+ int n;
for (n = 0; n < insn->n; n++) {
- int value;
outw(control, dev->iobase + MULTIQ3_CONTROL);
outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CONTROL);
@@ -233,7 +231,7 @@ static int multiq3_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], MULTIQ3_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index c8b1fa793a37..e84dac2bf3b2 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -90,7 +90,6 @@ static const struct ni6527_board ni6527_boards[] = {
};
struct ni6527_private {
- void __iomem *mmio_base;
unsigned int filter_interval;
unsigned int filter_enable;
};
@@ -99,14 +98,15 @@ static void ni6527_set_filter_interval(struct comedi_device *dev,
unsigned int val)
{
struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
if (val != devpriv->filter_interval) {
- writeb(val & 0xff, mmio + NI6527_FILT_INTERVAL_REG(0));
- writeb((val >> 8) & 0xff, mmio + NI6527_FILT_INTERVAL_REG(1));
- writeb((val >> 16) & 0x0f, mmio + NI6527_FILT_INTERVAL_REG(2));
+ writeb(val & 0xff, dev->mmio + NI6527_FILT_INTERVAL_REG(0));
+ writeb((val >> 8) & 0xff,
+ dev->mmio + NI6527_FILT_INTERVAL_REG(1));
+ writeb((val >> 16) & 0x0f,
+ dev->mmio + NI6527_FILT_INTERVAL_REG(2));
- writeb(NI6527_CLR_INTERVAL, mmio + NI6527_CLR_REG);
+ writeb(NI6527_CLR_INTERVAL, dev->mmio + NI6527_CLR_REG);
devpriv->filter_interval = val;
}
@@ -115,12 +115,9 @@ static void ni6527_set_filter_interval(struct comedi_device *dev,
static void ni6527_set_filter_enable(struct comedi_device *dev,
unsigned int val)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(val & 0xff, mmio + NI6527_FILT_ENA_REG(0));
- writeb((val >> 8) & 0xff, mmio + NI6527_FILT_ENA_REG(1));
- writeb((val >> 16) & 0xff, mmio + NI6527_FILT_ENA_REG(2));
+ writeb(val & 0xff, dev->mmio + NI6527_FILT_ENA_REG(0));
+ writeb((val >> 8) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(1));
+ writeb((val >> 16) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(2));
}
static int ni6527_di_insn_config(struct comedi_device *dev,
@@ -162,13 +159,11 @@ static int ni6527_di_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int val;
- val = readb(mmio + NI6527_DI_REG(0));
- val |= (readb(mmio + NI6527_DI_REG(1)) << 8);
- val |= (readb(mmio + NI6527_DI_REG(2)) << 16);
+ val = readb(dev->mmio + NI6527_DI_REG(0));
+ val |= (readb(dev->mmio + NI6527_DI_REG(1)) << 8);
+ val |= (readb(dev->mmio + NI6527_DI_REG(2)) << 16);
data[1] = val;
@@ -180,8 +175,6 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int mask;
mask = comedi_dio_update_state(s, data);
@@ -190,11 +183,13 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
unsigned int val = s->state ^ 0xffffff;
if (mask & 0x0000ff)
- writeb(val & 0xff, mmio + NI6527_DO_REG(0));
+ writeb(val & 0xff, dev->mmio + NI6527_DO_REG(0));
if (mask & 0x00ff00)
- writeb((val >> 8) & 0xff, mmio + NI6527_DO_REG(1));
+ writeb((val >> 8) & 0xff,
+ dev->mmio + NI6527_DO_REG(1));
if (mask & 0xff0000)
- writeb((val >> 16) & 0xff, mmio + NI6527_DO_REG(2));
+ writeb((val >> 16) & 0xff,
+ dev->mmio + NI6527_DO_REG(2));
}
data[1] = s->state;
@@ -205,12 +200,10 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
static irqreturn_t ni6527_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct ni6527_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int status;
- status = readb(mmio + NI6527_STATUS_REG);
+ status = readb(dev->mmio + NI6527_STATUS_REG);
if (!(status & NI6527_STATUS_IRQ))
return IRQ_NONE;
@@ -220,7 +213,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
comedi_event(dev, s);
}
- writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
+ writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
return IRQ_HANDLED;
}
@@ -270,11 +263,8 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev,
static int ni6527_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_ENABLE_IRQS, mmio + NI6527_CTRL_REG);
+ writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
+ writeb(NI6527_CTRL_ENABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
return 0;
}
@@ -282,10 +272,7 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
static int ni6527_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
+ writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
return 0;
}
@@ -299,21 +286,37 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev,
}
static void ni6527_set_edge_detection(struct comedi_device *dev,
+ unsigned int mask,
unsigned int rising,
unsigned int falling)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- /* enable rising-edge detection channels */
- writeb(rising & 0xff, mmio + NI6527_RISING_EDGE_REG(0));
- writeb((rising >> 8) & 0xff, mmio + NI6527_RISING_EDGE_REG(1));
- writeb((rising >> 16) & 0xff, mmio + NI6527_RISING_EDGE_REG(2));
-
- /* enable falling-edge detection channels */
- writeb(falling & 0xff, mmio + NI6527_FALLING_EDGE_REG(0));
- writeb((falling >> 8) & 0xff, mmio + NI6527_FALLING_EDGE_REG(1));
- writeb((falling >> 16) & 0xff, mmio + NI6527_FALLING_EDGE_REG(2));
+ unsigned int i;
+
+ rising &= mask;
+ falling &= mask;
+ for (i = 0; i < 2; i++) {
+ if (mask & 0xff) {
+ if (~mask & 0xff) {
+ /* preserve rising-edge detection channels */
+ rising |= readb(dev->mmio +
+ NI6527_RISING_EDGE_REG(i)) &
+ (~mask & 0xff);
+ /* preserve falling-edge detection channels */
+ falling |= readb(dev->mmio +
+ NI6527_FALLING_EDGE_REG(i)) &
+ (~mask & 0xff);
+ }
+ /* update rising-edge detection channels */
+ writeb(rising & 0xff,
+ dev->mmio + NI6527_RISING_EDGE_REG(i));
+ /* update falling-edge detection channels */
+ writeb(falling & 0xff,
+ dev->mmio + NI6527_FALLING_EDGE_REG(i));
+ }
+ rising >>= 8;
+ falling >>= 8;
+ mask >>= 8;
+ }
}
static int ni6527_intr_insn_config(struct comedi_device *dev,
@@ -321,12 +324,45 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ unsigned int mask = 0xffffffff;
+ unsigned int rising, falling, shift;
+
switch (data[0]) {
case INSN_CONFIG_CHANGE_NOTIFY:
/* check_insn_config_length() does not check this instruction */
if (insn->n != 3)
return -EINVAL;
- ni6527_set_edge_detection(dev, data[1], data[2]);
+ rising = data[1];
+ falling = data[2];
+ ni6527_set_edge_detection(dev, mask, rising, falling);
+ break;
+ case INSN_CONFIG_DIGITAL_TRIG:
+ /* check trigger number */
+ if (data[1] != 0)
+ return -EINVAL;
+ /* check digital trigger operation */
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ rising = 0;
+ falling = 0;
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ /* check shift amount */
+ shift = data[3];
+ if (shift >= s->n_chan) {
+ mask = 0;
+ rising = 0;
+ falling = 0;
+ } else {
+ mask <<= shift;
+ rising = data[4] << shift;
+ falling = data[5] << shift;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ ni6527_set_edge_detection(dev, mask, rising, falling);
break;
default:
return -EINVAL;
@@ -337,15 +373,15 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
static void ni6527_reset(struct comedi_device *dev)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
/* disable deglitch filters on all channels */
ni6527_set_filter_enable(dev, 0);
+ /* disable edge detection */
+ ni6527_set_edge_detection(dev, 0xffffffff, 0, 0);
+
writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
- mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
+ dev->mmio + NI6527_CLR_REG);
+ writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
}
static int ni6527_auto_attach(struct comedi_device *dev,
@@ -372,12 +408,12 @@ static int ni6527_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->mmio_base = pci_ioremap_bar(pcidev, 1);
- if (!devpriv->mmio_base)
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
/* make sure this is actually a 6527 device */
- if (readb(devpriv->mmio_base + NI6527_ID_REG) != 0x27)
+ if (readb(dev->mmio + NI6527_ID_REG) != 0x27)
return -ENODEV;
ni6527_reset(dev);
@@ -434,12 +470,12 @@ static int ni6527_auto_attach(struct comedi_device *dev,
static void ni6527_detach(struct comedi_device *dev)
{
- struct ni6527_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mmio_base)
+ if (dev->mmio)
ni6527_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 9a139d6b8ef4..873941be56cb 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -1,46 +1,73 @@
/*
- comedi/drivers/ni_6514.c
- driver for National Instruments PCI-6514
-
- Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
- Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
-
- 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.
+ * ni_65xx.c
+ * Comedi driver for National Instruments PCI-65xx static dio boards
+ *
+ * Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
+ * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
- 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.
-*/
/*
-Driver: ni_65xx
-Description: National Instruments 65xx static dio boards
-Author: Jon Grierson <jd@renko.co.uk>,
- Frank Mori Hess <fmhess@users.sourceforge.net>
-Status: testing
-Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
- PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
- PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
- PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
-Updated: Wed Oct 18 08:59:11 EDT 2006
-
-Based on the PCI-6527 driver by ds.
-The interrupt subdevice (subdevice 3) is probably broken for all boards
-except maybe the 6514.
-
-*/
+ * Driver: ni_65xx
+ * Description: National Instruments 65xx static dio boards
+ * Author: Jon Grierson <jd@renko.co.uk>,
+ * Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Status: testing
+ * Devices: (National Instruments) PCI-6509 [ni_65xx]
+ * (National Instruments) PXI-6509 [ni_65xx]
+ * (National Instruments) PCI-6510 [ni_65xx]
+ * (National Instruments) PCI-6511 [ni_65xx]
+ * (National Instruments) PXI-6511 [ni_65xx]
+ * (National Instruments) PCI-6512 [ni_65xx]
+ * (National Instruments) PXI-6512 [ni_65xx]
+ * (National Instruments) PCI-6513 [ni_65xx]
+ * (National Instruments) PXI-6513 [ni_65xx]
+ * (National Instruments) PCI-6514 [ni_65xx]
+ * (National Instruments) PXI-6514 [ni_65xx]
+ * (National Instruments) PCI-6515 [ni_65xx]
+ * (National Instruments) PXI-6515 [ni_65xx]
+ * (National Instruments) PCI-6516 [ni_65xx]
+ * (National Instruments) PCI-6517 [ni_65xx]
+ * (National Instruments) PCI-6518 [ni_65xx]
+ * (National Instruments) PCI-6519 [ni_65xx]
+ * (National Instruments) PCI-6520 [ni_65xx]
+ * (National Instruments) PCI-6521 [ni_65xx]
+ * (National Instruments) PXI-6521 [ni_65xx]
+ * (National Instruments) PCI-6528 [ni_65xx]
+ * (National Instruments) PXI-6528 [ni_65xx]
+ * Updated: Mon, 21 Jul 2014 12:49:58 +0000
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ *
+ * Based on the PCI-6527 driver by ds.
+ * The interrupt subdevice (subdevice 3) is probably broken for all
+ * boards except maybe the 6514.
+ *
+ * This driver previously inverted the outputs on PCI-6513 through to
+ * PCI-6519 and on PXI-6513 through to PXI-6515. It no longer inverts
+ * outputs on those cards by default as it didn't make much sense. If
+ * you require the outputs to be inverted on those cards for legacy
+ * reasons, set the module parameter "legacy_invert_outputs=true" when
+ * loading the module, or set "ni_65xx.legacy_invert_outputs=true" on
+ * the kernel command line if the driver is built in to the kernel.
+ */
/*
- Manuals (available from ftp://ftp.natinst.com/support/manuals)
-
- 370106b.pdf 6514 Register Level Programmer Manual
-
+ * Manuals (available from ftp://ftp.natinst.com/support/manuals)
+ *
+ * 370106b.pdf 6514 Register Level Programmer Manual
*/
#include <linux/module.h>
@@ -50,59 +77,69 @@ except maybe the 6514.
#include "../comedidev.h"
#include "comedi_fc.h"
-#include "mite.h"
-
-#define NI6514_DIO_SIZE 4096
-#define NI6514_MITE_SIZE 4096
-
-#define NI_65XX_MAX_NUM_PORTS 12
-static const unsigned ni_65xx_channels_per_port = 8;
-static const unsigned ni_65xx_port_offset = 0x10;
-
-static inline unsigned Port_Data(unsigned port)
-{
- return 0x40 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Port_Select(unsigned port)
-{
- return 0x41 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
-{
- return 0x42 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
-{
- return 0x43 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Filter_Enable(unsigned port)
-{
- return 0x44 + port * ni_65xx_port_offset;
-}
-
-#define ID_Register 0x00
-
-#define Clear_Register 0x01
-#define ClrEdge 0x08
-#define ClrOverflow 0x04
-#define Filter_Interval 0x08
-
-#define Change_Status 0x02
-#define MasterInterruptStatus 0x04
-#define Overflow 0x02
-#define EdgeStatus 0x01
+/*
+ * PCI BAR1 Register Map
+ */
-#define Master_Interrupt_Control 0x03
-#define FallingEdgeIntEnable 0x10
-#define RisingEdgeIntEnable 0x08
-#define MasterInterruptEnable 0x04
-#define OverflowIntEnable 0x02
-#define EdgeIntEnable 0x01
+/* Non-recurring Registers (8-bit except where noted) */
+#define NI_65XX_ID_REG 0x00
+#define NI_65XX_CLR_REG 0x01
+#define NI_65XX_CLR_WDOG_INT (1 << 6)
+#define NI_65XX_CLR_WDOG_PING (1 << 5)
+#define NI_65XX_CLR_WDOG_EXP (1 << 4)
+#define NI_65XX_CLR_EDGE_INT (1 << 3)
+#define NI_65XX_CLR_OVERFLOW_INT (1 << 2)
+#define NI_65XX_STATUS_REG 0x02
+#define NI_65XX_STATUS_WDOG_INT (1 << 5)
+#define NI_65XX_STATUS_FALL_EDGE (1 << 4)
+#define NI_65XX_STATUS_RISE_EDGE (1 << 3)
+#define NI_65XX_STATUS_INT (1 << 2)
+#define NI_65XX_STATUS_OVERFLOW_INT (1 << 1)
+#define NI_65XX_STATUS_EDGE_INT (1 << 0)
+#define NI_65XX_CTRL_REG 0x03
+#define NI_65XX_CTRL_WDOG_ENA (1 << 5)
+#define NI_65XX_CTRL_FALL_EDGE_ENA (1 << 4)
+#define NI_65XX_CTRL_RISE_EDGE_ENA (1 << 3)
+#define NI_65XX_CTRL_INT_ENA (1 << 2)
+#define NI_65XX_CTRL_OVERFLOW_ENA (1 << 1)
+#define NI_65XX_CTRL_EDGE_ENA (1 << 0)
+#define NI_65XX_REV_REG 0x04 /* 32-bit */
+#define NI_65XX_FILTER_REG 0x08 /* 32-bit */
+#define NI_65XX_RTSI_ROUTE_REG 0x0c /* 16-bit */
+#define NI_65XX_RTSI_EDGE_REG 0x0e /* 16-bit */
+#define NI_65XX_RTSI_WDOG_REG 0x10 /* 16-bit */
+#define NI_65XX_RTSI_TRIG_REG 0x12 /* 16-bit */
+#define NI_65XX_AUTO_CLK_SEL_REG 0x14 /* PXI-6528 only */
+#define NI_65XX_AUTO_CLK_SEL_STATUS (1 << 1)
+#define NI_65XX_AUTO_CLK_SEL_DISABLE (1 << 0)
+#define NI_65XX_WDOG_CTRL_REG 0x15
+#define NI_65XX_WDOG_CTRL_ENA (1 << 0)
+#define NI_65XX_RTSI_CFG_REG 0x16
+#define NI_65XX_RTSI_CFG_RISE_SENSE (1 << 2)
+#define NI_65XX_RTSI_CFG_FALL_SENSE (1 << 1)
+#define NI_65XX_RTSI_CFG_SYNC_DETECT (1 << 0)
+#define NI_65XX_WDOG_STATUS_REG 0x17
+#define NI_65XX_WDOG_STATUS_EXP (1 << 0)
+#define NI_65XX_WDOG_INTERVAL_REG 0x18 /* 32-bit */
+
+/* Recurring port registers (8-bit) */
+#define NI_65XX_PORT(x) ((x) * 0x10)
+#define NI_65XX_IO_DATA_REG(x) (0x40 + NI_65XX_PORT(x))
+#define NI_65XX_IO_SEL_REG(x) (0x41 + NI_65XX_PORT(x))
+#define NI_65XX_IO_SEL_OUTPUT (0 << 0)
+#define NI_65XX_IO_SEL_INPUT (1 << 0)
+#define NI_65XX_RISE_EDGE_ENA_REG(x) (0x42 + NI_65XX_PORT(x))
+#define NI_65XX_FALL_EDGE_ENA_REG(x) (0x43 + NI_65XX_PORT(x))
+#define NI_65XX_FILTER_ENA(x) (0x44 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_HIZ_REG(x) (0x46 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_ENA(x) (0x47 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_HI_LO_REG(x) (0x48 + NI_65XX_PORT(x))
+#define NI_65XX_RTSI_ENA(x) (0x49 + NI_65XX_PORT(x))
+
+#define NI_65XX_PORT_TO_CHAN(x) ((x) * 8)
+#define NI_65XX_CHAN_TO_PORT(x) ((x) / 8)
+#define NI_65XX_CHAN_TO_MASK(x) (1 << ((x) % 8))
enum ni_65xx_boardid {
BOARD_PCI6509,
@@ -134,7 +171,7 @@ struct ni_65xx_board {
unsigned num_dio_ports;
unsigned num_di_ports;
unsigned num_do_ports;
- unsigned invert_outputs:1;
+ unsigned legacy_invert:1;
};
static const struct ni_65xx_board ni_65xx_boards[] = {
@@ -169,58 +206,58 @@ static const struct ni_65xx_board ni_65xx_boards[] = {
[BOARD_PCI6513] = {
.name = "pci-6513",
.num_do_ports = 8,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6513] = {
.name = "pxi-6513",
.num_do_ports = 8,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6514] = {
.name = "pci-6514",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6514] = {
.name = "pxi-6514",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6515] = {
.name = "pci-6515",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6515] = {
.name = "pxi-6515",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6516] = {
.name = "pci-6516",
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6517] = {
.name = "pci-6517",
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6518] = {
.name = "pci-6518",
.num_di_ports = 2,
.num_do_ports = 2,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6519] = {
.name = "pci-6519",
.num_di_ports = 2,
.num_do_ports = 2,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6520] = {
.name = "pci-6520",
@@ -249,135 +286,174 @@ static const struct ni_65xx_board ni_65xx_boards[] = {
},
};
-static inline unsigned ni_65xx_port_by_channel(unsigned channel)
-{
- return channel / ni_65xx_channels_per_port;
-}
+static bool ni_65xx_legacy_invert_outputs;
+module_param_named(legacy_invert_outputs, ni_65xx_legacy_invert_outputs,
+ bool, 0444);
+MODULE_PARM_DESC(legacy_invert_outputs,
+ "invert outputs of PCI/PXI-6513/6514/6515/6516/6517/6518/6519 for compatibility with old user code");
-static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board
- *board)
+static unsigned int ni_65xx_num_ports(struct comedi_device *dev)
{
+ const struct ni_65xx_board *board = comedi_board(dev);
+
return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
}
-struct ni_65xx_private {
- struct mite_struct *mite;
- unsigned int filter_interval;
- unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
- unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
- unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
-};
+static void ni_65xx_disable_input_filters(struct comedi_device *dev)
+{
+ unsigned int num_ports = ni_65xx_num_ports(dev);
+ int i;
-struct ni_65xx_subdevice_private {
- unsigned base_port;
-};
+ /* disable input filtering on all ports */
+ for (i = 0; i < num_ports; ++i)
+ writeb(0x00, dev->mmio + NI_65XX_FILTER_ENA(i));
-static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice
- *subdev)
-{
- return subdev->private;
+ /* set filter interval to 0 (32bit reg) */
+ writel(0x00000000, dev->mmio + NI_65XX_FILTER_REG);
}
-static int ni_65xx_config_filter(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+/* updates edge detection for base_chan to base_chan+31 */
+static void ni_65xx_update_edge_detection(struct comedi_device *dev,
+ unsigned int base_chan,
+ unsigned int rising,
+ unsigned int falling)
{
- struct ni_65xx_private *devpriv = dev->private;
- const unsigned chan = CR_CHAN(insn->chanspec);
- const unsigned port =
- sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
+ unsigned int num_ports = ni_65xx_num_ports(dev);
+ unsigned int port;
- if (data[0] != INSN_CONFIG_FILTER)
- return -EINVAL;
- if (data[1]) {
- static const unsigned filter_resolution_ns = 200;
- static const unsigned max_filter_interval = 0xfffff;
- unsigned interval =
- (data[1] +
- (filter_resolution_ns / 2)) / filter_resolution_ns;
- if (interval > max_filter_interval)
- interval = max_filter_interval;
- data[1] = interval * filter_resolution_ns;
-
- if (interval != devpriv->filter_interval) {
- writeb(interval,
- devpriv->mite->daq_io_addr +
- Filter_Interval);
- devpriv->filter_interval = interval;
- }
+ if (base_chan >= NI_65XX_PORT_TO_CHAN(num_ports))
+ return;
- devpriv->filter_enable[port] |=
- 1 << (chan % ni_65xx_channels_per_port);
- } else {
- devpriv->filter_enable[port] &=
- ~(1 << (chan % ni_65xx_channels_per_port));
- }
+ for (port = NI_65XX_CHAN_TO_PORT(base_chan); port < num_ports; port++) {
+ int bitshift = (int)(NI_65XX_PORT_TO_CHAN(port) - base_chan);
+ unsigned int port_mask, port_rising, port_falling;
- writeb(devpriv->filter_enable[port],
- devpriv->mite->daq_io_addr + Filter_Enable(port));
+ if (bitshift >= 32)
+ break;
- return 2;
+ if (bitshift >= 0) {
+ port_mask = ~0U >> bitshift;
+ port_rising = rising >> bitshift;
+ port_falling = falling >> bitshift;
+ } else {
+ port_mask = ~0U << -bitshift;
+ port_rising = rising << -bitshift;
+ port_falling = falling << -bitshift;
+ }
+ if (port_mask & 0xff) {
+ if (~port_mask & 0xff) {
+ port_rising |=
+ readb(dev->mmio +
+ NI_65XX_RISE_EDGE_ENA_REG(port)) &
+ ~port_mask;
+ port_falling |=
+ readb(dev->mmio +
+ NI_65XX_FALL_EDGE_ENA_REG(port)) &
+ ~port_mask;
+ }
+ writeb(port_rising & 0xff,
+ dev->mmio + NI_65XX_RISE_EDGE_ENA_REG(port));
+ writeb(port_falling & 0xff,
+ dev->mmio + NI_65XX_FALL_EDGE_ENA_REG(port));
+ }
+ }
+}
+
+static void ni_65xx_disable_edge_detection(struct comedi_device *dev)
+{
+ /* clear edge detection for channels 0 to 31 */
+ ni_65xx_update_edge_detection(dev, 0, 0, 0);
+ /* clear edge detection for channels 32 to 63 */
+ ni_65xx_update_edge_detection(dev, 32, 0, 0);
+ /* clear edge detection for channels 64 to 95 */
+ ni_65xx_update_edge_detection(dev, 64, 0, 0);
}
static int ni_65xx_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct ni_65xx_private *devpriv = dev->private;
- unsigned port;
+ unsigned long base_port = (unsigned long)s->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int chan_mask = NI_65XX_CHAN_TO_MASK(chan);
+ unsigned port = base_port + NI_65XX_CHAN_TO_PORT(chan);
+ unsigned int interval;
+ unsigned int val;
- if (insn->n < 1)
- return -EINVAL;
- port = sprivate(s)->base_port +
- ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
switch (data[0]) {
case INSN_CONFIG_FILTER:
- return ni_65xx_config_filter(dev, s, insn, data);
+ /*
+ * The deglitch filter interval is specified in nanoseconds.
+ * The hardware supports intervals in 200ns increments. Round
+ * the user values up and return the actual interval.
+ */
+ interval = (data[1] + 100) / 200;
+ if (interval > 0xfffff)
+ interval = 0xfffff;
+ data[1] = interval * 200;
+
+ /*
+ * Enable/disable the channel for deglitch filtering. Note
+ * that the filter interval is never set to '0'. This is done
+ * because other channels might still be enabled for filtering.
+ */
+ val = readb(dev->mmio + NI_65XX_FILTER_ENA(port));
+ if (interval) {
+ writel(interval, dev->mmio + NI_65XX_FILTER_REG);
+ val |= chan_mask;
+ } else {
+ val &= ~chan_mask;
+ }
+ writeb(val, dev->mmio + NI_65XX_FILTER_ENA(port));
break;
+
case INSN_CONFIG_DIO_OUTPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- devpriv->dio_direction[port] = COMEDI_OUTPUT;
- writeb(0, devpriv->mite->daq_io_addr + Port_Select(port));
- return 1;
+ writeb(NI_65XX_IO_SEL_OUTPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(port));
break;
+
case INSN_CONFIG_DIO_INPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- devpriv->dio_direction[port] = COMEDI_INPUT;
- writeb(1, devpriv->mite->daq_io_addr + Port_Select(port));
- return 1;
+ writeb(NI_65XX_IO_SEL_INPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(port));
break;
+
case INSN_CONFIG_DIO_QUERY:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- data[1] = devpriv->dio_direction[port];
- return insn->n;
+ val = readb(dev->mmio + NI_65XX_IO_SEL_REG(port));
+ data[1] = (val == NI_65XX_IO_SEL_INPUT) ? COMEDI_INPUT
+ : COMEDI_OUTPUT;
break;
+
default:
- break;
+ return -EINVAL;
}
- return -EINVAL;
+
+ return insn->n;
}
static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct ni_65xx_board *board = comedi_board(dev);
- struct ni_65xx_private *devpriv = dev->private;
- int base_bitfield_channel;
+ unsigned long base_port = (unsigned long)s->private;
+ unsigned int base_chan = CR_CHAN(insn->chanspec);
+ int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1);
unsigned read_bits = 0;
- int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1);
int port_offset;
- base_bitfield_channel = CR_CHAN(insn->chanspec);
- for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel);
+ for (port_offset = NI_65XX_CHAN_TO_PORT(base_chan);
port_offset <= last_port_offset; port_offset++) {
- unsigned port = sprivate(s)->base_port + port_offset;
- int base_port_channel = port_offset * ni_65xx_channels_per_port;
- unsigned port_mask, port_data, port_read_bits;
- int bitshift = base_port_channel - base_bitfield_channel;
+ unsigned port = base_port + port_offset;
+ int base_port_channel = NI_65XX_PORT_TO_CHAN(port_offset);
+ unsigned port_mask, port_data, bits;
+ int bitshift = base_port_channel - base_chan;
if (bitshift >= 32)
break;
@@ -392,32 +468,26 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
}
port_mask &= 0xff;
port_data &= 0xff;
+
+ /* update the outputs */
if (port_mask) {
- unsigned bits;
- devpriv->output_bits[port] &= ~port_mask;
- devpriv->output_bits[port] |=
- port_data & port_mask;
- bits = devpriv->output_bits[port];
- if (board->invert_outputs)
- bits = ~bits;
- writeb(bits,
- devpriv->mite->daq_io_addr +
- Port_Data(port));
- }
- port_read_bits =
- readb(devpriv->mite->daq_io_addr + Port_Data(port));
- if (s->type == COMEDI_SUBD_DO && board->invert_outputs) {
- /* Outputs inverted, so invert value read back from
- * DO subdevice. (Does not apply to boards with DIO
- * subdevice.) */
- port_read_bits ^= 0xFF;
+ bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
+ bits ^= s->io_bits; /* invert if necessary */
+ bits &= ~port_mask;
+ bits |= (port_data & port_mask);
+ bits ^= s->io_bits; /* invert back */
+ writeb(bits, dev->mmio + NI_65XX_IO_DATA_REG(port));
}
+
+ /* read back the actual state */
+ bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
+ bits ^= s->io_bits; /* invert if necessary */
if (bitshift > 0)
- port_read_bits <<= bitshift;
+ bits <<= bitshift;
else
- port_read_bits >>= -bitshift;
+ bits >>= -bitshift;
- read_bits |= port_read_bits;
+ read_bits |= bits;
}
data[1] = read_bits;
return insn->n;
@@ -426,18 +496,17 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
static irqreturn_t ni_65xx_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct ni_65xx_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
- status = readb(devpriv->mite->daq_io_addr + Change_Status);
- if ((status & MasterInterruptStatus) == 0)
+ status = readb(dev->mmio + NI_65XX_STATUS_REG);
+ if ((status & NI_65XX_STATUS_INT) == 0)
return IRQ_NONE;
- if ((status & EdgeStatus) == 0)
+ if ((status & NI_65XX_STATUS_EDGE_INT) == 0)
return IRQ_NONE;
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
comedi_buf_put(s, 0);
s->async->events |= COMEDI_CB_EOS;
@@ -490,13 +559,11 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
static int ni_65xx_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
- writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
- MasterInterruptEnable | EdgeIntEnable,
- devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
+ writeb(NI_65XX_CTRL_FALL_EDGE_ENA | NI_65XX_CTRL_RISE_EDGE_ENA |
+ NI_65XX_CTRL_INT_ENA | NI_65XX_CTRL_EDGE_ENA,
+ dev->mmio + NI_65XX_CTRL_REG);
return 0;
}
@@ -504,16 +571,15 @@ static int ni_65xx_intr_cmd(struct comedi_device *dev,
static int ni_65xx_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
return 0;
}
static int ni_65xx_intr_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
data[1] = 0;
return insn->n;
@@ -524,40 +590,68 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_65xx_private *devpriv = dev->private;
+ switch (data[0]) {
+ case INSN_CONFIG_CHANGE_NOTIFY:
+ /* add instruction to check_insn_config_length() */
+ if (insn->n != 3)
+ return -EINVAL;
- if (insn->n < 1)
- return -EINVAL;
- if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ /* update edge detection for channels 0 to 31 */
+ ni_65xx_update_edge_detection(dev, 0, data[1], data[2]);
+ /* clear edge detection for channels 32 to 63 */
+ ni_65xx_update_edge_detection(dev, 32, 0, 0);
+ /* clear edge detection for channels 64 to 95 */
+ ni_65xx_update_edge_detection(dev, 64, 0, 0);
+ break;
+ case INSN_CONFIG_DIGITAL_TRIG:
+ /* check trigger number */
+ if (data[1] != 0)
+ return -EINVAL;
+ /* check digital trigger operation */
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ ni_65xx_disable_edge_detection(dev);
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ /*
+ * update edge detection for channels data[3]
+ * to (data[3] + 31)
+ */
+ ni_65xx_update_edge_detection(dev, data[3],
+ data[4], data[5]);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
return -EINVAL;
+ }
+
+ return insn->n;
+}
+
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int ni_65xx_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
- writeb(data[1],
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0));
- writeb(data[1] >> 8,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x10));
- writeb(data[1] >> 16,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x20));
- writeb(data[1] >> 24,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x30));
-
- writeb(data[2],
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0));
- writeb(data[2] >> 8,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x10));
- writeb(data[2] >> 16,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x20));
- writeb(data[2] >> 24,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x30));
-
- return 2;
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
}
static int ni_65xx_auto_attach(struct comedi_device *dev,
@@ -565,8 +659,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct ni_65xx_board *board = NULL;
- struct ni_65xx_private *devpriv;
- struct ni_65xx_subdevice_private *spriv;
struct comedi_subdevice *s;
unsigned i;
int ret;
@@ -582,23 +674,27 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ ret = ni_65xx_mite_init(pcidev);
+ if (ret)
+ return ret;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
- return ret;
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
+
+ if (pcidev->irq) {
+ ret = request_irq(pcidev->irq, ni_65xx_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
}
- dev->irq = mite_irq(devpriv->mite);
dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name,
- readb(devpriv->mite->daq_io_addr + ID_Register));
+ readb(dev->mmio + NI_65XX_ID_REG));
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -606,130 +702,111 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[0];
if (board->num_di_ports) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan =
- board->num_di_ports * ni_65xx_channels_per_port;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_config = ni_65xx_dio_insn_config;
- s->insn_bits = ni_65xx_dio_insn_bits;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_di_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->insn_config = ni_65xx_dio_insn_config;
+
+ /* the input ports always start at port 0 */
+ s->private = (void *)0;
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[1];
if (board->num_do_ports) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan =
- board->num_do_ports * ni_65xx_channels_per_port;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = ni_65xx_dio_insn_bits;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = board->num_di_ports;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_do_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+
+ /* the output ports always start after the input ports */
+ s->private = (void *)(unsigned long)board->num_di_ports;
+
+ /*
+ * Use the io_bits to handle the inverted outputs. Inverted
+ * outputs are only supported if the "legacy_invert_outputs"
+ * module parameter is set to "true".
+ */
+ if (ni_65xx_legacy_invert_outputs && board->legacy_invert)
+ s->io_bits = 0xff;
+
+ /* reset all output ports to comedi '0' */
+ for (i = 0; i < board->num_do_ports; ++i) {
+ writeb(s->io_bits, /* inverted if necessary */
+ dev->mmio +
+ NI_65XX_IO_DATA_REG(board->num_di_ports + i));
+ }
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[2];
if (board->num_dio_ports) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan =
- board->num_dio_ports * ni_65xx_channels_per_port;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_config = ni_65xx_dio_insn_config;
- s->insn_bits = ni_65xx_dio_insn_bits;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = 0;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_dio_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->insn_config = ni_65xx_dio_insn_config;
+
+ /* the input/output ports always start at port 0 */
+ s->private = (void *)0;
+
+ /* configure all ports for input */
for (i = 0; i < board->num_dio_ports; ++i) {
- /* configure all ports for input */
- writeb(0x1,
- devpriv->mite->daq_io_addr +
- Port_Select(i));
+ writeb(NI_65XX_IO_SEL_INPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(i));
}
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[3];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->range_table = &range_unknown;
- s->maxdata = 1;
- s->len_chanlist = 1;
- s->do_cmdtest = ni_65xx_intr_cmdtest;
- s->do_cmd = ni_65xx_intr_cmd;
- s->cancel = ni_65xx_intr_cancel;
- s->insn_bits = ni_65xx_intr_insn_bits;
- s->insn_config = ni_65xx_intr_insn_config;
-
- for (i = 0; i < ni_65xx_total_num_ports(board); ++i) {
- writeb(0x00,
- devpriv->mite->daq_io_addr + Filter_Enable(i));
- if (board->invert_outputs)
- writeb(0x01,
- devpriv->mite->daq_io_addr + Port_Data(i));
- else
- writeb(0x00,
- devpriv->mite->daq_io_addr + Port_Data(i));
- }
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
- writeb(0x00,
- devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-
- /* Set filter interval to 0 (32bit reg) */
- writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval);
-
- ret = request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
- "ni_65xx", dev);
- if (ret < 0) {
- dev->irq = 0;
- dev_warn(dev->class_dev, "irq not available\n");
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_intr_insn_bits;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 1;
+ s->insn_config = ni_65xx_intr_insn_config;
+ s->do_cmdtest = ni_65xx_intr_cmdtest;
+ s->do_cmd = ni_65xx_intr_cmd;
+ s->cancel = ni_65xx_intr_cancel;
}
+ ni_65xx_disable_input_filters(dev);
+ ni_65xx_disable_edge_detection(dev);
+
return 0;
}
static void ni_65xx_detach(struct comedi_device *dev)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
- writeb(0x00,
- devpriv->mite->daq_io_addr +
- Master_Interrupt_Control);
+ if (dev->mmio) {
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
+ iounmap(dev->mmio);
}
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
- }
comedi_pci_disable(dev);
}
static struct comedi_driver ni_65xx_driver = {
- .driver_name = "ni_65xx",
- .module = THIS_MODULE,
- .auto_attach = ni_65xx_auto_attach,
- .detach = ni_65xx_detach,
+ .driver_name = "ni_65xx",
+ .module = THIS_MODULE,
+ .auto_attach = ni_65xx_auto_attach,
+ .detach = ni_65xx_detach,
};
static int ni_65xx_pci_probe(struct pci_dev *dev,
@@ -774,5 +851,5 @@ static struct pci_driver ni_65xx_pci_driver = {
module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for NI PCI-65xx static dio boards");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 634cde83a02b..b0b03d4d6081 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -28,7 +28,7 @@
*
* Encoders work. PulseGeneration (both single pulse and pulse train)
* works. Buffered commands work for input but not output.
- *
+ *
* References:
* DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
* DAQ 6601/6602 User Manual (NI 322137B-01)
@@ -161,6 +161,7 @@ enum ni_660x_register {
static inline unsigned IOConfigReg(unsigned pfi_channel)
{
unsigned reg = NI660X_IO_CFG_0_1 + pfi_channel / 2;
+
BUG_ON(reg > NI660X_IO_CFG_38_39);
return reg;
}
@@ -310,10 +311,7 @@ enum clock_config_register_bits {
/* ioconfigreg */
static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
{
- if (pfi_channel % 2)
- return 0;
- else
- return 8;
+ return (pfi_channel % 2) ? 0 : 8;
}
static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
@@ -589,17 +587,14 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
unsigned chip, unsigned bits,
enum ni_660x_register reg)
{
- struct ni_660x_private *devpriv = dev->private;
- void __iomem *write_address =
- devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] +
- registerData[reg].offset;
+ unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
switch (registerData[reg].size) {
case DATA_2B:
- writew(bits, write_address);
+ writew(bits, dev->mmio + addr);
break;
case DATA_4B:
- writel(bits, write_address);
+ writel(bits, dev->mmio + addr);
break;
default:
BUG();
@@ -611,18 +606,13 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
unsigned chip,
enum ni_660x_register reg)
{
- struct ni_660x_private *devpriv = dev->private;
- void __iomem *read_address =
- devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] +
- registerData[reg].offset;
+ unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
switch (registerData[reg].size) {
case DATA_2B:
- return readw(read_address);
- break;
+ return readw(dev->mmio + addr);
case DATA_4B:
- return readl(read_address);
- break;
+ return readl(dev->mmio + addr);
default:
BUG();
break;
@@ -714,8 +704,8 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
mite_ring(devpriv, counter));
if (mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for counter.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for counter\n");
return -EBUSY;
}
mite_chan->dir = direction;
@@ -749,11 +739,11 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
if (retval) {
- comedi_error(dev,
- "no dma channel available for use by counter");
+ dev_err(dev->class_dev,
+ "no dma channel available for use by counter\n");
return retval;
}
- ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ ni_tio_acknowledge(counter);
return ni_tio_cmd(dev, s);
}
@@ -829,8 +819,7 @@ static int ni_660x_input_poll(struct comedi_device *dev,
}
static int ni_660x_buf_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
+ struct comedi_subdevice *s)
{
struct ni_660x_private *devpriv = dev->private;
struct ni_gpct *counter = s->private;
@@ -1083,11 +1072,9 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- ret = mite_setup2(devpriv->mite, 1);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = mite_setup2(dev, devpriv->mite, true);
+ if (ret < 0)
return ret;
- }
ret = ni_660x_alloc_mite_rings(dev);
if (ret < 0)
@@ -1126,9 +1113,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
if (i < ni_660x_num_counters(dev)) {
s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
- SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
+ SDF_LSAMPL | SDF_CMD_READ;
s->n_chan = 3;
s->maxdata = 0xffffffff;
s->insn_read = ni_tio_insn_read;
@@ -1170,13 +1156,13 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
for (i = 0; i < board->n_chips; ++i)
set_tio_counterswap(dev, i);
- ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt,
- IRQF_SHARED, "ni_660x", dev);
+ ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
if (ret < 0) {
dev_warn(dev->class_dev, " irq not available\n");
return ret;
}
- dev->irq = mite_irq(devpriv->mite);
+ dev->irq = pcidev->irq;
global_interrupt_config_bits = Global_Int_Enable_Bit;
if (board->n_chips > 1)
global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
@@ -1195,12 +1181,11 @@ static void ni_660x_detach(struct comedi_device *dev)
if (devpriv) {
if (devpriv->counter_dev)
ni_gpct_device_destroy(devpriv->counter_dev);
- if (devpriv->mite) {
- ni_660x_free_mite_rings(dev);
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ ni_660x_free_mite_rings(dev);
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 1002ceacfdcc..f5caefad0b59 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -39,11 +39,10 @@ Commands are not supported.
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
-#include "mite.h"
-
#define AO_VALUE_OFFSET 0x00
#define AO_CHAN_OFFSET 0x0c
#define AO_STATUS_OFFSET 0x10
@@ -82,8 +81,6 @@ static const struct ni_670x_board ni_670x_boards[] = {
};
struct ni_670x_private {
-
- struct mite_struct *mite;
int boardtype;
int dio;
unsigned int ao_readback[32];
@@ -111,9 +108,9 @@ static int ni_670x_ao_winsn(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* First write in channel register which channel to use */
writel(((chan & 15) << 1) | ((chan & 16) >> 4),
- devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);
+ dev->mmio + AO_CHAN_OFFSET);
/* write channel value */
- writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);
+ writel(data[i], dev->mmio + AO_VALUE_OFFSET);
devpriv->ao_readback[chan] = data[i];
}
@@ -139,14 +136,10 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_670x_private *devpriv = dev->private;
- void __iomem *io_addr = devpriv->mite->daq_io_addr +
- DIO_PORT0_DATA_OFFSET;
-
if (comedi_dio_update_state(s, data))
- writel(s->state, io_addr);
+ writel(s->state, dev->mmio + DIO_PORT0_DATA_OFFSET);
- data[1] = readl(io_addr);
+ data[1] = readl(dev->mmio + DIO_PORT0_DATA_OFFSET);
return insn->n;
}
@@ -156,18 +149,40 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_670x_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
+ writel(s->io_bits, dev->mmio + DIO_PORT0_DIR_OFFSET);
return insn->n;
}
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int ni_670x_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
+
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
+}
+
static int ni_670x_auto_attach(struct comedi_device *dev,
unsigned long context)
{
@@ -193,15 +208,13 @@ static int ni_670x_auto_attach(struct comedi_device *dev,
if (!devpriv)
return -ENOMEM;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
- return -ENOMEM;
-
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = ni_670x_mite_init(pcidev);
+ if (ret)
return ret;
- }
+
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
+ return -ENOMEM;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -242,16 +255,15 @@ static int ni_670x_auto_attach(struct comedi_device *dev,
s->insn_config = ni_670x_dio_insn_config;
/* Config of misc registers */
- writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);
+ writel(0x10, dev->mmio + MISC_CONTROL_OFFSET);
/* Config of ao registers */
- writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);
+ writel(0x00, dev->mmio + AO_CONTROL_OFFSET);
return 0;
}
static void ni_670x_detach(struct comedi_device *dev)
{
- struct ni_670x_private *devpriv = dev->private;
struct comedi_subdevice *s;
if (dev->n_subdevices) {
@@ -259,10 +271,8 @@ static void ni_670x_detach(struct comedi_device *dev)
if (s)
kfree(s->range_table_list);
}
- if (devpriv && devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 5bd19494dbf6..de67161f6185 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -71,7 +71,6 @@ TRIG_WAKE_EOS
#include "8253.h"
#include "comedi_fc.h"
-#define A2150_SIZE 28
#define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
/* Registers and bits */
@@ -156,13 +155,6 @@ struct a2150_private {
int config_bits; /* config register bits */
};
-static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-
-static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
- int flags);
-static int a2150_set_chanlist(struct comedi_device *dev,
- unsigned int start_channel,
- unsigned int num_channels);
/* interrupt service routine */
static irqreturn_t a2150_interrupt(int irq, void *d)
{
@@ -179,7 +171,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
static const int sample_size = sizeof(devpriv->dma_buffer[0]);
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
/* initialize async here to make sure s is not NULL */
@@ -189,18 +181,19 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
status = inw(dev->iobase + STATUS_REG);
if ((status & INTR_BIT) == 0) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_NONE;
}
if (status & OVFL_BIT) {
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
}
if ((status & DMA_TC_BIT) == 0) {
- comedi_error(dev, "caught non-dma interrupt? Aborting.");
+ dev_err(dev->class_dev,
+ "caught non-dma interrupt? Aborting.\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return IRQ_HANDLED;
@@ -287,6 +280,117 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
+/*
+ * sets bits in devpriv->clock_bits to nearest approximation of requested
+ * period, adjusts requested period to actual timing.
+ */
+static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
+ unsigned int flags)
+{
+ const struct a2150_board *thisboard = comedi_board(dev);
+ struct a2150_private *devpriv = dev->private;
+ int lub, glb, temp;
+ int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
+ int i, j;
+
+ /* initialize greatest lower and least upper bounds */
+ lub_divisor_shift = 3;
+ lub_index = 0;
+ lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
+ glb_divisor_shift = 0;
+ glb_index = thisboard->num_clocks - 1;
+ glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
+
+ /* make sure period is in available range */
+ if (*period < glb)
+ *period = glb;
+ if (*period > lub)
+ *period = lub;
+
+ /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
+ for (i = 0; i < 4; i++) {
+ /* there are a maximum of 4 master clocks */
+ for (j = 0; j < thisboard->num_clocks; j++) {
+ /* temp is the period in nanosec we are evaluating */
+ temp = thisboard->clock[j] * (1 << i);
+ /* if it is the best match yet */
+ if (temp < lub && temp >= *period) {
+ lub_divisor_shift = i;
+ lub_index = j;
+ lub = temp;
+ }
+ if (temp > glb && temp <= *period) {
+ glb_divisor_shift = i;
+ glb_index = j;
+ glb = temp;
+ }
+ }
+ }
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ /* if least upper bound is better approximation */
+ if (lub - *period < *period - glb)
+ *period = lub;
+ else
+ *period = glb;
+ break;
+ case TRIG_ROUND_UP:
+ *period = lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ *period = glb;
+ break;
+ }
+
+ /* set clock bits for config register appropriately */
+ devpriv->config_bits &= ~CLOCK_MASK;
+ if (*period == lub) {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(lub_index) |
+ CLOCK_DIVISOR_BITS(lub_divisor_shift);
+ } else {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(glb_index) |
+ CLOCK_DIVISOR_BITS(glb_divisor_shift);
+ }
+
+ return 0;
+}
+
+static int a2150_set_chanlist(struct comedi_device *dev,
+ unsigned int start_channel,
+ unsigned int num_channels)
+{
+ struct a2150_private *devpriv = dev->private;
+
+ if (start_channel + num_channels > 4)
+ return -1;
+
+ devpriv->config_bits &= ~CHANNEL_MASK;
+
+ switch (num_channels) {
+ case 1:
+ devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
+ break;
+ case 2:
+ if (start_channel == 0)
+ devpriv->config_bits |= CHANNEL_BITS(0x2);
+ else if (start_channel == 2)
+ devpriv->config_bits |= CHANNEL_BITS(0x3);
+ else
+ return -1;
+ break;
+ case 4:
+ devpriv->config_bits |= CHANNEL_BITS(0x1);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
static int a2150_ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
@@ -408,8 +512,8 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned int trigger_bits;
if (cmd->flags & TRIG_RT) {
- comedi_error(dev,
- " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
+ dev_err(dev->class_dev,
+ "dma incompatible with hard real-time interrupt (TRIG_RT), aborting\n");
return -1;
}
/* clear fifo and reset triggering circuitry */
@@ -490,7 +594,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
trigger_bits |= HW_TRIG_EN;
} else if (cmd->start_src == TRIG_OTHER) {
/* XXX add support for level/slope start trigger using TRIG_OTHER */
- comedi_error(dev, "you shouldn't see this?");
+ dev_err(dev->class_dev, "you shouldn't see this?\n");
}
/* send trigger config bits */
outw(trigger_bits, dev->iobase + TRIGGER_REG);
@@ -574,123 +678,11 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
return n;
}
-/*
- * sets bits in devpriv->clock_bits to nearest approximation of requested
- * period, adjusts requested period to actual timing.
- */
-static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
- int flags)
-{
- const struct a2150_board *thisboard = comedi_board(dev);
- struct a2150_private *devpriv = dev->private;
- int lub, glb, temp;
- int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
- int i, j;
-
- /* initialize greatest lower and least upper bounds */
- lub_divisor_shift = 3;
- lub_index = 0;
- lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
- glb_divisor_shift = 0;
- glb_index = thisboard->num_clocks - 1;
- glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
-
- /* make sure period is in available range */
- if (*period < glb)
- *period = glb;
- if (*period > lub)
- *period = lub;
-
- /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
- for (i = 0; i < 4; i++) {
- /* there are a maximum of 4 master clocks */
- for (j = 0; j < thisboard->num_clocks; j++) {
- /* temp is the period in nanosec we are evaluating */
- temp = thisboard->clock[j] * (1 << i);
- /* if it is the best match yet */
- if (temp < lub && temp >= *period) {
- lub_divisor_shift = i;
- lub_index = j;
- lub = temp;
- }
- if (temp > glb && temp <= *period) {
- glb_divisor_shift = i;
- glb_index = j;
- glb = temp;
- }
- }
- }
- flags &= TRIG_ROUND_MASK;
- switch (flags) {
- case TRIG_ROUND_NEAREST:
- default:
- /* if least upper bound is better approximation */
- if (lub - *period < *period - glb)
- *period = lub;
- else
- *period = glb;
- break;
- case TRIG_ROUND_UP:
- *period = lub;
- break;
- case TRIG_ROUND_DOWN:
- *period = glb;
- break;
- }
-
- /* set clock bits for config register appropriately */
- devpriv->config_bits &= ~CLOCK_MASK;
- if (*period == lub) {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(lub_index) |
- CLOCK_DIVISOR_BITS(lub_divisor_shift);
- } else {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(glb_index) |
- CLOCK_DIVISOR_BITS(glb_divisor_shift);
- }
-
- return 0;
-}
-
-static int a2150_set_chanlist(struct comedi_device *dev,
- unsigned int start_channel,
- unsigned int num_channels)
-{
- struct a2150_private *devpriv = dev->private;
-
- if (start_channel + num_channels > 4)
- return -1;
-
- devpriv->config_bits &= ~CHANNEL_MASK;
-
- switch (num_channels) {
- case 1:
- devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
- break;
- case 2:
- if (start_channel == 0)
- devpriv->config_bits |= CHANNEL_BITS(0x2);
- else if (start_channel == 2)
- devpriv->config_bits |= CHANNEL_BITS(0x3);
- else
- return -1;
- break;
- case 4:
- devpriv->config_bits |= CHANNEL_BITS(0x1);
- break;
- default:
- return -1;
- break;
- }
-
- return 0;
-}
-
/* probes board type, returns offset */
static int a2150_probe(struct comedi_device *dev)
{
int status = inw(dev->iobase + STATUS_REG);
+
return ID_BITS(status);
}
@@ -709,7 +701,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], A2150_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x1c);
if (ret)
return ret;
@@ -784,8 +776,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
udelay(1000);
}
if (i == timeout) {
- printk
- (" timed out waiting for offset calibration to complete\n");
+ dev_err(dev->class_dev,
+ "timed out waiting for offset calibration to complete\n");
return -ETIME;
}
devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index d03935257b97..2bd9f692a7ae 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -98,233 +98,135 @@ are not supported.
#include "ni_stc.h"
#include "8255.h"
-#define ATMIO 1
-#undef PCIMIO
-
/*
* AT specific setup
*/
-#define NI_SIZE 0x20
-
-#define MAX_N_CALDACS 32
-
static const struct ni_board_struct ni_boards[] = {
- {.device_id = 44,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-mio-16e-1",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- },
- {.device_id = 25,
- .isapnp_id = 0x1900,
- .name = "at-mio-16e-2",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 2048,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- },
- {.device_id = 36,
- .isapnp_id = 0x2400,
- .name = "at-mio-16e-10",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {.device_id = 37,
- .isapnp_id = 0x2500,
- .name = "at-mio-16de-10",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 1,
- },
- {.device_id = 38,
- .isapnp_id = 0x2600,
- .name = "at-mio-64e-3",
- .n_adchan = 64,
- .adbits = 12,
- .ai_fifo_depth = 2048,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- },
- {.device_id = 39,
- .isapnp_id = 0x2700,
- .name = "at-mio-16xe-50",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_8,
- .ai_speed = 50000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 50000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043},
- .has_8255 = 0,
- },
- {.device_id = 50,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-mio-16xe-10",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {.device_id = 51,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-ai-16xe-10",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1, /* unknown */
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- }
+ {
+ .name = "at-mio-16e-1",
+ .device_id = 44,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 8192,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { mb88341 },
+ }, {
+ .name = "at-mio-16e-2",
+ .device_id = 25,
+ .isapnp_id = 0x1900,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 2048,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { mb88341 },
+ }, {
+ .name = "at-mio-16e-10",
+ .device_id = 36,
+ .isapnp_id = 0x2400,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 10000,
+ .caldac = { ad8804_debug },
+ }, {
+ .name = "at-mio-16de-10",
+ .device_id = 37,
+ .isapnp_id = 0x2500,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 10000,
+ .caldac = { ad8804_debug },
+ .has_8255 = 1,
+ }, {
+ .name = "at-mio-64e-3",
+ .device_id = 38,
+ .isapnp_id = 0x2600,
+ .n_adchan = 64,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 2048,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { ad8804_debug },
+ }, {
+ .name = "at-mio-16xe-50",
+ .device_id = 39,
+ .isapnp_id = 0x2700,
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_8,
+ .ai_speed = 50000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 50000,
+ .caldac = { dac8800, dac8043 },
+ }, {
+ .name = "at-mio-16xe-10",
+ .device_id = 50,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { dac8800, dac8043, ad8522 },
+ }, {
+ .name = "at-ai-16xe-10",
+ .device_id = 51,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1, /* unknown */
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
};
static const int ni_irqpin[] = {
-1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7
};
-#define interrupt_pin(a) (ni_irqpin[(a)])
-
-#define IRQ_POLARITY 0
-
-#define NI_E_IRQ_FLAGS 0
-
-struct ni_private {
- struct pnp_dev *isapnp_dev;
- NI_PRIVATE_COMMON
-
-};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
-#define ni_readl(a) (inl((a)+dev->iobase))
-#define ni_writew(a, b) (outw((a), (b)+dev->iobase))
-#define ni_readw(a) (inw((a)+dev->iobase))
-#define ni_writeb(a, b) (outb((a), (b)+dev->iobase))
-#define ni_readb(a) (inb((a)+dev->iobase))
-
-/* How we access windowed registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. The
- * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
-
-static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if ((addr) < 8) {
- ni_writew(data, addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ni_writew(data, Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ret = ni_readw(addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ret = ni_readw(Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-
- return ret;
-}
+#include "ni_mio_common.c"
static struct pnp_device_id device_ids[] = {
{.id = "NIC1900", .driver_data = 0},
@@ -337,8 +239,6 @@ static struct pnp_device_id device_ids[] = {
MODULE_DEVICE_TABLE(pnp, device_ids);
-#include "ni_mio_common.c"
-
static int ni_isapnp_find_board(struct pnp_dev **dev)
{
struct pnp_dev *isapnp_dev = NULL;
@@ -353,20 +253,17 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
if (isapnp_dev == NULL || isapnp_dev->card == NULL)
continue;
- if (pnp_device_attach(isapnp_dev) < 0) {
- printk
- ("ni_atmio: %s found but already active, skipping.\n",
- ni_boards[i].name);
+ if (pnp_device_attach(isapnp_dev) < 0)
continue;
- }
+
if (pnp_activate_dev(isapnp_dev) < 0) {
pnp_device_detach(isapnp_dev);
return -EAGAIN;
}
- if (!pnp_port_valid(isapnp_dev, 0)
- || !pnp_irq_valid(isapnp_dev, 0)) {
+
+ if (!pnp_port_valid(isapnp_dev, 0) ||
+ !pnp_irq_valid(isapnp_dev, 0)) {
pnp_device_detach(isapnp_dev);
- printk("ni_atmio: pnp invalid port or irq, aborting\n");
return -ENOMEM;
}
break;
@@ -388,11 +285,13 @@ static int ni_getboardtype(struct comedi_device *dev)
}
if (device_id == 255)
- printk(" can't find board\n");
+ dev_err(dev->class_dev, "can't find board\n");
else if (device_id == 0)
- printk(" EEPROM read error (?) or device not found\n");
+ dev_err(dev->class_dev,
+ "EEPROM read error (?) or device not found\n");
else
- printk(" unknown device ID %d -- contact author\n", device_id);
+ dev_err(dev->class_dev,
+ "unknown device ID %d -- contact author\n", device_id);
return -1;
}
@@ -413,11 +312,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
return ret;
devpriv = dev->private;
- devpriv->stc_writew = &ni_atmio_win_out;
- devpriv->stc_readw = &ni_atmio_win_in;
- devpriv->stc_writel = &win_out2;
- devpriv->stc_readl = &win_in2;
-
iobase = it->options[0];
irq = it->options[1];
isapnp_dev = NULL;
@@ -428,10 +322,10 @@ static int ni_atmio_attach(struct comedi_device *dev,
iobase = pnp_port_start(isapnp_dev, 0);
irq = pnp_irq(isapnp_dev, 0);
- devpriv->isapnp_dev = isapnp_dev;
+ comedi_set_hw_dev(dev, &isapnp_dev->dev);
}
- ret = comedi_request_region(dev, iobase, NI_SIZE);
+ ret = comedi_request_region(dev, iobase, 0x20);
if (ret)
return ret;
@@ -443,31 +337,23 @@ static int ni_atmio_attach(struct comedi_device *dev,
dev->board_ptr = ni_boards + board;
boardtype = comedi_board(dev);
-
- printk(" %s", boardtype->name);
dev->board_name = boardtype->name;
/* irq stuff */
if (irq != 0) {
- if (irq > 15 || ni_irqpin[irq] == -1) {
- printk(" invalid irq %u\n", irq);
+ if (irq > 15 || ni_irqpin[irq] == -1)
return -EINVAL;
- }
- printk(" ( irq = %u )", irq);
- ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
- "ni_atmio", dev);
-
- if (ret < 0) {
- printk(" irq not available\n");
+ ret = request_irq(irq, ni_E_interrupt, 0,
+ dev->board_name, dev);
+ if (ret < 0)
return -EINVAL;
- }
dev->irq = irq;
}
/* generic E series stuff in ni_mio_common.c */
- ret = ni_E_init(dev);
+ ret = ni_E_init(dev, ni_irqpin[dev->irq], 0);
if (ret < 0)
return ret;
@@ -477,12 +363,14 @@ static int ni_atmio_attach(struct comedi_device *dev,
static void ni_atmio_detach(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
+ struct pnp_dev *isapnp_dev;
mio_common_detach(dev);
comedi_legacy_detach(dev);
- if (devpriv->isapnp_dev)
- pnp_device_detach(devpriv->isapnp_dev);
+
+ isapnp_dev = dev->hw_dev ? to_pnp_dev(dev->hw_dev) : NULL;
+ if (isapnp_dev)
+ pnp_device_detach(isapnp_dev);
}
static struct comedi_driver ni_atmio_driver = {
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 6ad27f50c6ec..9c08da9508f4 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -94,8 +94,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
#define CLOCK_10_KHZ 0x8D25
#define CLOCK_1_KHZ 0x8E25
#define CLOCK_100_HZ 0x8F25
-/* Other miscellaneous defines */
-#define ATMIO16D_SIZE 32 /* bus address range */
struct atmio16_board_t {
@@ -335,12 +333,9 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
} else if (cmd->convert_arg < 655360000) {
base_clock = CLOCK_100_KHZ;
timer = cmd->convert_arg / 10000;
- } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */) {
+ } else /* cmd->convert_arg < 6553600000 */ {
base_clock = CLOCK_10_KHZ;
timer = cmd->convert_arg / 100000;
- } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */) {
- base_clock = CLOCK_1_KHZ;
- timer = cmd->convert_arg / 1000000;
}
outw(0xFF03, dev->iobase + AM9513A_COM_REG);
outw(base_clock, dev->iobase + AM9513A_DATA_REG);
@@ -403,12 +398,9 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
} else if (cmd->scan_begin_arg < 655360000) {
base_clock = CLOCK_100_KHZ;
timer = cmd->scan_begin_arg / 10000;
- } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */) {
+ } else /* cmd->scan_begin_arg < 6553600000 */ {
base_clock = CLOCK_10_KHZ;
timer = cmd->scan_begin_arg / 100000;
- } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */) {
- base_clock = CLOCK_1_KHZ;
- timer = cmd->scan_begin_arg / 1000000;
}
outw(0xFF02, dev->iobase + AM9513A_COM_REG);
outw(base_clock, dev->iobase + AM9513A_DATA_REG);
@@ -630,7 +622,7 @@ static int atmio16d_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], ATMIO16D_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x20);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 728bf7f14f7b..5e472cb7fbd7 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -18,32 +18,34 @@
*/
/*
-Driver: ni_daq_700
-Description: National Instruments PCMCIA DAQCard-700 DIO only
-Author: Fred Brooks <nsaspook@nsaspook.com>,
- based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
-Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
-Status: works
-Updated: Wed, 19 Sep 2012 12:07:20 +0000
-
-The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with
-16 channels and a analog input subdevice (1) with 16 single-ended channels.
-
-Digital: The channel 0 corresponds to the daqcard-700's output
-port, bit 0; channel 8 corresponds to the input port, bit 0.
-
-Digital direction configuration: channels 0-7 output, 8-15 input (8225 device
-emu as port A output, port B input, port C N/A).
-
-Analog: The input range is 0 to 4095 for -10 to +10 volts
-IRQ is assigned but not used.
-
-Version 0.1 Original DIO only driver
-Version 0.2 DIO and basic AI analog input support on 16 se channels
-
-Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
- User Manual: http://www.ni.com/pdf/manuals/320676d.pdf
-*/
+ * Driver: ni_daq_700
+ * Description: National Instruments PCMCIA DAQCard-700
+ * Author: Fred Brooks <nsaspook@nsaspook.com>,
+ * based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
+ * Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
+ * Status: works
+ * Updated: Wed, 21 May 2014 12:07:20 +0000
+ *
+ * The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with
+ * 16 channels and a analog input subdevice (1) with 16 single-ended channels
+ * or 8 differential channels, and three input ranges.
+ *
+ * Digital: The channel 0 corresponds to the daqcard-700's output
+ * port, bit 0; channel 8 corresponds to the input port, bit 0.
+ *
+ * Digital direction configuration: channels 0-7 output, 8-15 input.
+ *
+ * Analog: The input range is 0 to 4095 with a default of -10 to +10 volts.
+ * Valid ranges:
+ * 0 for -10 to 10V bipolar
+ * 1 for -5 to 5V bipolar
+ * 2 for -2.5 to 2.5V bipolar
+ *
+ * IRQ is assigned but not used.
+ *
+ * Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
+ * User Manual: http://www.ni.com/pdf/manuals/320676d.pdf
+ */
#include <linux/module.h>
#include <linux/delay.h>
@@ -69,6 +71,17 @@ Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
#define CDA_R2 0x0A /* RW 8bit */
#define CMO_R 0x0B /* RO 8bit */
#define TIC_R 0x06 /* WO 8bit */
+/* daqcard700 modes */
+#define CMD_R3_DIFF 0x04 /* diff mode */
+
+static const struct comedi_lrange range_daq700_ai = {
+ 3,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5)
+ }
+};
static int daq700_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -131,11 +144,22 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- int n, chan;
+ int n;
int d;
int ret;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int aref = CR_AREF(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int r3_bits = 0;
+
+ /* set channel input modes */
+ if (aref == AREF_DIFF)
+ r3_bits |= CMD_R3_DIFF;
+ /* write channel mode/range */
+ if (range >= 1)
+ range++; /* convert range to hardware value */
+ outb(r3_bits | (range & 0x03), dev->iobase + CMD_R3);
- chan = CR_CHAN(insn->chanspec);
/* write channel to multiplexer */
/* set mask scan bit high to disable scanning */
outb(chan | 0x80, dev->iobase + CMD_R1);
@@ -147,6 +171,9 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
/* trigger conversion with out0 L to H */
outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */
outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */
+ outb(0x00, dev->iobase + ADCLEAR_R); /* clear the ADC FIFO */
+ /* read 16bit junk from FIFO to clear */
+ inw(dev->iobase + ADFIFO_R);
/* mode 1 out0 H, L to H, start conversion */
outb(0x32, dev->iobase + CMO_R);
@@ -222,11 +249,10 @@ static int daq700_auto_attach(struct comedi_device *dev,
/* DAQCard-700 ai */
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_AI;
- /* we support single-ended (ground) */
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
s->n_chan = 16;
s->maxdata = (1 << 12) - 1;
- s->range_table = &range_bipolar10;
+ s->range_table = &range_daq700_ai;
s->insn_read = daq700_ai_rinsn;
daq700_ai_config(dev, s);
@@ -263,5 +289,4 @@ module_comedi_pcmcia_driver(daq700_driver, daq700_cs_driver);
MODULE_AUTHOR("Fred Brooks <nsaspook@nsaspook.com>");
MODULE_DESCRIPTION(
"Comedi driver for National Instruments PCMCIA DAQCard-700 DIO/AI");
-MODULE_VERSION("0.2.00");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 3e3f940fa57c..126d65cb39f2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -72,8 +72,6 @@
#include "ni_labpc_regs.h"
#include "ni_labpc_isadma.h"
-#define LABPC_SIZE 0x20 /* size of ISA io region */
-
enum scan_mode {
MODE_SINGLE_CHAN,
MODE_SINGLE_CHAN_INTERVAL,
@@ -130,24 +128,26 @@ static const struct comedi_lrange range_labpc_ao = {
/* functions that do inb/outb and readb/writeb so we can use
* function pointers to decide which to use */
-static inline unsigned int labpc_inb(unsigned long address)
+static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
{
- return inb(address);
+ return inb(dev->iobase + reg);
}
-static inline void labpc_outb(unsigned int byte, unsigned long address)
+static void labpc_outb(struct comedi_device *dev,
+ unsigned int byte, unsigned long reg)
{
- outb(byte, address);
+ outb(byte, dev->iobase + reg);
}
-static inline unsigned int labpc_readb(unsigned long address)
+static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
{
- return readb((void __iomem *)address);
+ return readb(dev->mmio + reg);
}
-static inline void labpc_writeb(unsigned int byte, unsigned long address)
+static void labpc_writeb(struct comedi_device *dev,
+ unsigned int byte, unsigned long reg)
{
- writeb(byte, (void __iomem *)address);
+ writeb(byte, dev->mmio + reg);
}
#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISA)
@@ -172,38 +172,29 @@ static const struct labpc_boardinfo labpc_boards[] = {
#endif
static void labpc_counter_load(struct comedi_device *dev,
- unsigned long base_address,
+ unsigned long reg,
unsigned int counter_number,
unsigned int count,
unsigned int mode)
{
- const struct labpc_boardinfo *board = comedi_board(dev);
-
- if (board->has_mmio) {
- void __iomem *mmio_base = (void __iomem *)base_address;
-
- i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
- i8254_mm_write(mmio_base, 0, counter_number, count);
+ if (dev->mmio) {
+ i8254_mm_set_mode(dev->mmio + reg, 0, counter_number, mode);
+ i8254_mm_write(dev->mmio + reg, 0, counter_number, count);
} else {
- i8254_set_mode(base_address, 0, counter_number, mode);
- i8254_write(base_address, 0, counter_number, count);
+ i8254_set_mode(dev->iobase + reg, 0, counter_number, mode);
+ i8254_write(dev->iobase + reg, 0, counter_number, count);
}
}
static void labpc_counter_set_mode(struct comedi_device *dev,
- unsigned long base_address,
+ unsigned long reg,
unsigned int counter_number,
unsigned int mode)
{
- const struct labpc_boardinfo *board = comedi_board(dev);
-
- if (board->has_mmio) {
- void __iomem *mmio_base = (void __iomem *)base_address;
-
- i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
- } else {
- i8254_set_mode(base_address, 0, counter_number, mode);
- }
+ if (dev->mmio)
+ i8254_mm_set_mode(dev->mmio + reg, 0, counter_number, mode);
+ else
+ i8254_set_mode(dev->iobase + reg, 0, counter_number, mode);
}
static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -213,11 +204,11 @@ static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
devpriv->cmd3 = 0;
- devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
return 0;
}
@@ -247,7 +238,7 @@ static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
devpriv->cmd1 = CMD1_MA(chan);
devpriv->cmd1 |= CMD1_GAIN(range);
- devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
}
static void labpc_setup_cmd6_reg(struct comedi_device *dev,
@@ -294,14 +285,14 @@ static void labpc_setup_cmd6_reg(struct comedi_device *dev,
else
devpriv->cmd6 &= ~CMD6_SCANUP;
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
{
struct labpc_private *devpriv = dev->private;
- unsigned int lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- unsigned int msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
+ unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);
return (msb << 8) | lsb;
}
@@ -310,7 +301,7 @@ static void labpc_clear_adc_fifo(struct comedi_device *dev)
{
struct labpc_private *devpriv = dev->private;
- devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
labpc_read_adc_fifo(dev);
}
@@ -321,7 +312,7 @@ static int labpc_ai_eoc(struct comedi_device *dev,
{
struct labpc_private *devpriv = dev->private;
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
if (devpriv->stat1 & STAT1_DAVAIL)
return 0;
return -EBUSY;
@@ -353,17 +344,16 @@ static int labpc_ai_insn_read(struct comedi_device *dev,
/* single-ended/differential */
if (aref == AREF_DIFF)
devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
/* initialize pacer counter to prevent any problems */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 0, I8254_MODE2);
labpc_clear_adc_fifo(dev);
for (i = 0; i < insn->n; i++) {
/* trigger conversion */
- devpriv->write_byte(0x1, dev->iobase + ADC_START_CONVERT_REG);
+ devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);
ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
if (ret)
@@ -531,24 +521,26 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
{
+ unsigned int chan0;
+ unsigned int chan1;
+
if (cmd->chanlist_len == 1)
return MODE_SINGLE_CHAN;
- /* chanlist may be NULL during cmdtest. */
+ /* chanlist may be NULL during cmdtest */
if (cmd->chanlist == NULL)
return MODE_MULT_CHAN_UP;
- if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
- return MODE_SINGLE_CHAN_INTERVAL;
+ chan0 = CR_CHAN(cmd->chanlist[0]);
+ chan1 = CR_CHAN(cmd->chanlist[1]);
- if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+ if (chan0 < chan1)
return MODE_MULT_CHAN_UP;
- if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+ if (chan0 > chan1)
return MODE_MULT_CHAN_DOWN;
- pr_err("ni_labpc: bug! cannot determine AI scan mode\n");
- return 0;
+ return MODE_SINGLE_CHAN_INTERVAL;
}
static int labpc_ai_check_chanlist(struct comedi_device *dev,
@@ -749,12 +741,11 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* load counter a1 with count of 3
* (pc+ manual says this is minimum allowed) using mode 0
*/
- labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ labpc_counter_load(dev, COUNTER_A_BASE_REG,
1, 3, I8254_MODE0);
} else {
/* just put counter a1 in mode 0 to set its output low */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 1, I8254_MODE0);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 1, I8254_MODE0);
}
/* figure out what method we will use to transfer data */
@@ -786,37 +777,35 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* list will get screwed when you switch
* between scan up to scan down mode - dunno why */
udelay(1);
- devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
}
- devpriv->write_byte(cmd->chanlist_len,
- dev->iobase + INTERVAL_COUNT_REG);
+ devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
/* load count */
- devpriv->write_byte(0x1, dev->iobase + INTERVAL_STROBE_REG);
+ devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
if (cmd->convert_src == TRIG_TIMER ||
cmd->scan_begin_src == TRIG_TIMER) {
/* set up pacing */
labpc_adc_timing(dev, cmd, mode);
/* load counter b0 in mode 3 */
- labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ labpc_counter_load(dev, COUNTER_B_BASE_REG,
0, devpriv->divisor_b0, I8254_MODE3);
}
/* set up conversion pacing */
if (labpc_ai_convert_period(cmd, mode)) {
/* load counter a0 in mode 2 */
- labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ labpc_counter_load(dev, COUNTER_A_BASE_REG,
0, devpriv->divisor_a0, I8254_MODE2);
} else {
/* initialize pacer counter to prevent any problems */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 0, I8254_MODE2);
}
/* set up scan pacing */
if (labpc_ai_scan_period(cmd, mode)) {
/* load counter b1 in mode 2 */
- labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ labpc_counter_load(dev, COUNTER_B_BASE_REG,
1, devpriv->divisor_b1, I8254_MODE2);
}
@@ -830,7 +819,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* enable fifo not empty interrupt? */
if (xfer == fifo_not_empty_transfer)
devpriv->cmd3 |= CMD3_FIFOINTEN;
- devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
/* setup any external triggering/pacing (cmd4 register) */
devpriv->cmd4 = 0;
@@ -846,7 +835,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* single-ended/differential */
if (aref == AREF_DIFF)
devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
/* startup acquisition */
@@ -863,7 +852,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->stop_src == TRIG_EXT)
devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -880,7 +869,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
const int timeout = 10000;
unsigned int i;
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
i++) {
@@ -892,10 +881,10 @@ static int labpc_drain_fifo(struct comedi_device *dev)
}
data = labpc_read_adc_fifo(dev);
cfc_write_to_buffer(dev->read_subdev, data);
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
}
if (i == timeout) {
- comedi_error(dev, "ai timeout, fifo never empties");
+ dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
return -1;
}
@@ -926,7 +915,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
struct comedi_cmd *cmd;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
@@ -934,9 +923,9 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
cmd = &async->cmd;
/* read board status */
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
if (board->is_labpc1200)
- devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+ devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
STAT1_OVERRUN | STAT1_DAVAIL)) == 0
@@ -947,10 +936,10 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
if (devpriv->stat1 & STAT1_OVERRUN) {
/* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
- comedi_error(dev, "overrun");
+ dev_err(dev->class_dev, "overrun\n");
return IRQ_HANDLED;
}
@@ -960,17 +949,17 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
labpc_drain_fifo(dev);
if (devpriv->stat1 & STAT1_CNTINT) {
- comedi_error(dev, "handled timer interrupt?");
+ dev_err(dev->class_dev, "handled timer interrupt?\n");
/* clear it */
- devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
}
if (devpriv->stat1 & STAT1_OVERFLOW) {
/* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
- comedi_error(dev, "overflow");
+ dev_err(dev->class_dev, "overflow\n");
return IRQ_HANDLED;
}
/* handle external stop trigger */
@@ -1009,7 +998,7 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
* be independently enabled/disabled for its the two channels */
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->cmd2 &= ~CMD2_LDAC(channel);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
/* set range */
@@ -1020,13 +1009,13 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
else
devpriv->cmd6 &= ~CMD6_DACUNI(channel);
/* write to register */
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
/* send data */
lsb = data[0] & 0xff;
msb = (data[0] >> 8) & 0xff;
- devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
- devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
+ devpriv->write_byte(dev, lsb, DAC_LSB_REG(channel));
+ devpriv->write_byte(dev, msb, DAC_MSB_REG(channel));
/* remember value for readback */
devpriv->ao_value[channel] = data[0];
@@ -1046,14 +1035,16 @@ static int labpc_ao_insn_read(struct comedi_device *dev,
return 1;
}
-static int labpc_8255_mmio(int dir, int port, int data, unsigned long iobase)
+static int labpc_8255_mmio(int dir, int port, int data, unsigned long arg)
{
+ struct comedi_device *dev = (struct comedi_device *)arg;
+
if (dir) {
- writeb(data, (void __iomem *)(iobase + port));
+ writeb(data, dev->mmio + DIO_BASE_REG + port);
return 0;
- } else {
- return readb((void __iomem *)(iobase + port));
}
+
+ return readb(dev->mmio + DIO_BASE_REG + port);
}
/* lowlevel write to eeprom/dac */
@@ -1072,11 +1063,11 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
else
devpriv->cmd5 &= ~CMD5_SDATA;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* set clock to load bit */
devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}
}
@@ -1092,14 +1083,14 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
/* set serial clock */
devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* clear clock bit */
devpriv->cmd5 &= ~CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* read bits most significant bit first */
udelay(1);
- devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+ devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
if (devpriv->stat2 & STAT2_PROMOUT)
value |= 1 << (value_width - i);
}
@@ -1120,10 +1111,10 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send read instruction */
labpc_serial_out(dev, read_instruction, write_length);
@@ -1135,7 +1126,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return value;
}
@@ -1150,10 +1141,10 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send read status instruction */
labpc_serial_out(dev, read_status_instruction, write_length);
@@ -1163,7 +1154,7 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return value;
}
@@ -1186,7 +1177,7 @@ static int labpc_eeprom_write(struct comedi_device *dev,
break;
}
if (i == timeout) {
- comedi_error(dev, "eeprom write timed out");
+ dev_err(dev->class_dev, "eeprom write timed out\n");
return -ETIME;
}
/* update software copy of eeprom */
@@ -1195,21 +1186,21 @@ static int labpc_eeprom_write(struct comedi_device *dev,
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send write_enable instruction */
labpc_serial_out(dev, write_enable_instruction, write_length);
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send write instruction */
devpriv->cmd5 |= CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
labpc_serial_out(dev, write_instruction, write_length);
/* send 8 bit address to write to */
labpc_serial_out(dev, address, write_length);
@@ -1217,12 +1208,12 @@ static int labpc_eeprom_write(struct comedi_device *dev,
labpc_serial_out(dev, value, write_length);
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return 0;
}
@@ -1240,7 +1231,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
/* clear caldac load bit and make sure we don't write to eeprom */
devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* write 4 bit channel */
labpc_serial_out(dev, channel, 4);
@@ -1250,10 +1241,10 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
/* set and clear caldac bit to load caldac value */
devpriv->cmd5 |= CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 &= ~CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}
static int labpc_calib_insn_write(struct comedi_device *dev,
@@ -1337,7 +1328,7 @@ int labpc_common_attach(struct comedi_device *dev,
int ret;
int i;
- if (board->has_mmio) {
+ if (dev->mmio) {
devpriv->read_byte = labpc_readb;
devpriv->write_byte = labpc_writeb;
} else {
@@ -1346,13 +1337,13 @@ int labpc_common_attach(struct comedi_device *dev,
}
/* initialize board's command registers */
- devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
- devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
- devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
if (board->is_labpc1200) {
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
if (irq) {
@@ -1402,8 +1393,8 @@ int labpc_common_attach(struct comedi_device *dev,
devpriv->ao_value[i] = s->maxdata / 2;
lsb = devpriv->ao_value[i] & 0xff;
msb = (devpriv->ao_value[i] >> 8) & 0xff;
- devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
- devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
+ devpriv->write_byte(dev, lsb, DAC_LSB_REG(i));
+ devpriv->write_byte(dev, msb, DAC_MSB_REG(i));
}
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -1411,9 +1402,13 @@ int labpc_common_attach(struct comedi_device *dev,
/* 8255 dio */
s = &dev->subdevices[2];
- ret = subdev_8255_init(dev, s,
- (board->has_mmio) ? labpc_8255_mmio : NULL,
- dev->iobase + DIO_BASE_REG);
+ if (dev->mmio) {
+ ret = subdev_8255_init(dev, s, labpc_8255_mmio,
+ (unsigned long)dev);
+ } else {
+ ret = subdev_8255_init(dev, s, NULL,
+ dev->iobase + DIO_BASE_REG);
+ }
if (ret)
return ret;
@@ -1463,7 +1458,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], LABPC_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x20);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index 486589fa6fd8..f6e5cd15a409 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -32,11 +32,9 @@ struct labpc_boardinfo {
unsigned ai_scan_up:1; /* can auto scan up in ai channels */
unsigned has_ao:1; /* has analog outputs */
unsigned is_labpc1200:1; /* has extra regs compared to pc+ */
- unsigned has_mmio:1; /* uses memory mapped io */
};
struct labpc_private {
- struct mite_struct *mite; /* for mite chip on pci-1200 */
/* number of data points left to be taken */
unsigned long long count;
/* software copy of analog output values */
@@ -80,8 +78,9 @@ struct labpc_private {
* function pointers so we can use inb/outb or readb/writeb as
* appropriate
*/
- unsigned int (*read_byte) (unsigned long address);
- void (*write_byte) (unsigned int byte, unsigned long address);
+ unsigned int (*read_byte)(struct comedi_device *, unsigned long reg);
+ void (*write_byte)(struct comedi_device *,
+ unsigned int byte, unsigned long reg);
};
int labpc_common_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
index d9f25fdbb728..cb7d1c952cf2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
@@ -147,7 +147,7 @@ static void handle_isa_dma(struct comedi_device *dev)
enable_dma(devpriv->dma_chan);
/* clear dma tc interrupt */
- devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG);
}
void labpc_handle_dma_status(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
index 739597068297..65984ea0a3ee 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_pci.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c
@@ -35,7 +35,6 @@
#include "../comedidev.h"
-#include "mite.h"
#include "ni_labpc.h"
enum labpc_pci_boardid {
@@ -49,10 +48,32 @@ static const struct labpc_boardinfo labpc_pci_boards[] = {
.ai_scan_up = 1,
.has_ao = 1,
.is_labpc1200 = 1,
- .has_mmio = 1,
},
};
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int labpc_pci_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
+
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
+}
+
static int labpc_pci_auto_attach(struct comedi_device *dev,
unsigned long context)
{
@@ -72,29 +93,25 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
+ ret = labpc_pci_mite_init(pcidev);
+ if (ret)
+ return ret;
+
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
return -ENOMEM;
- ret = mite_setup(devpriv->mite);
- if (ret < 0)
- return ret;
- dev->iobase = (unsigned long)devpriv->mite->daq_io_addr;
- return labpc_common_attach(dev, mite_irq(devpriv->mite), IRQF_SHARED);
+ return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED);
}
static void labpc_pci_detach(struct comedi_device *dev)
{
- struct labpc_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (dev->irq)
free_irq(dev->irq, dev);
comedi_pci_disable(dev);
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 7ffdcc07ef92..297c95d2e0a3 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -194,113 +194,6 @@ static const struct comedi_lrange *const ni_range_lkup[] = {
[ai_gain_6143] = &range_bipolar5
};
-static int ni_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_cdio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_cdio_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static void handle_cdio_interrupt(struct comedi_device *dev);
-static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-
-static int ni_serial_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_serial_hw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in);
-static int ni_serial_sw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in);
-
-static int ni_calib_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static int ni_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-static int ni_pfi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_pfi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static unsigned ni_old_get_pfi_routing(struct comedi_device *dev,
- unsigned chan);
-
-static void ni_rtsi_init(struct comedi_device *dev);
-static int ni_rtsi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_rtsi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_read_eeprom(struct comedi_device *dev, int addr);
-
-#ifndef PCIDMA
-static void ni_handle_fifo_half_full(struct comedi_device *dev);
-static int ni_ao_fifo_half_empty(struct comedi_device *dev,
- struct comedi_subdevice *s);
-#endif
-static void ni_handle_fifo_dregs(struct comedi_device *dev);
-static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-static void ni_load_channelgain_list(struct comedi_device *dev,
- unsigned int n_chan, unsigned int *list);
-static void shutdown_ai_command(struct comedi_device *dev);
-
-static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-
-static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
-
-#ifdef PCIDMA
-static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-#endif
-static void handle_gpct_interrupt(struct comedi_device *dev,
- unsigned short counter_index);
-
-static int init_cs5529(struct comedi_device *dev);
-static int cs5529_do_conversion(struct comedi_device *dev,
- unsigned short *data);
-static int cs5529_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
- unsigned int reg_select_bits);
-
-static int ni_m_series_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_6143_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
- unsigned period_ns);
-static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status);
-static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status);
-
enum aimodes {
AIMODE_NONE = 0,
AIMODE_HALF_FULL = 1,
@@ -330,10 +223,8 @@ static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
switch (counter_index) {
case 0:
return NI_GPCT0_SUBDEV;
- break;
case 1:
return NI_GPCT1_SUBDEV;
- break;
default:
break;
}
@@ -353,12 +244,394 @@ enum timebase_nanoseconds {
static const int num_adc_stages_611x = 3;
-static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ai_mite_status);
-static void handle_b_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ao_mite_status);
-static void get_last_sample_611x(struct comedi_device *dev);
-static void get_last_sample_6143(struct comedi_device *dev);
+static void ni_writel(struct comedi_device *dev, uint32_t data, int reg)
+{
+ if (dev->mmio)
+ writel(data, dev->mmio + reg);
+
+ outl(data, dev->iobase + reg);
+}
+
+static void ni_writew(struct comedi_device *dev, uint16_t data, int reg)
+{
+ if (dev->mmio)
+ writew(data, dev->mmio + reg);
+
+ outw(data, dev->iobase + reg);
+}
+
+static void ni_writeb(struct comedi_device *dev, uint8_t data, int reg)
+{
+ if (dev->mmio)
+ writeb(data, dev->mmio + reg);
+
+ outb(data, dev->iobase + reg);
+}
+
+static uint32_t ni_readl(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readl(dev->mmio + reg);
+
+ return inl(dev->iobase + reg);
+}
+
+static uint16_t ni_readw(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readw(dev->mmio + reg);
+
+ return inw(dev->iobase + reg);
+}
+
+static uint8_t ni_readb(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readb(dev->mmio + reg);
+
+ return inb(dev->iobase + reg);
+}
+
+/*
+ * We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board.
+ *
+ * The AT-MIO and DAQCard devices map the low 8 STC registers to
+ * iobase+reg*2.
+ *
+ * Most PCIMIO devices also map the low 8 STC registers but the
+ * 611x devices map the read registers to iobase+(addr-1)*2.
+ * For now non-windowed STC access is disabled if a PCIMIO device
+ * is detected (devpriv->mite has been initialized).
+ *
+ * The M series devices do not used windowed registers for the
+ * STC registers. The functions below handle the mapping of the
+ * windowed STC registers to the m series register offsets.
+ */
+
+static void m_series_stc_writel(struct comedi_device *dev,
+ uint32_t data, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case AI_SC_Load_A_Registers:
+ offset = M_Offset_AI_SC_Load_A;
+ break;
+ case AI_SI_Load_A_Registers:
+ offset = M_Offset_AI_SI_Load_A;
+ break;
+ case AO_BC_Load_A_Register:
+ offset = M_Offset_AO_BC_Load_A;
+ break;
+ case AO_UC_Load_A_Register:
+ offset = M_Offset_AO_UC_Load_A;
+ break;
+ case AO_UI_Load_A_Register:
+ offset = M_Offset_AO_UI_Load_A;
+ break;
+ case G_Load_A_Register(0):
+ offset = M_Offset_G0_Load_A;
+ break;
+ case G_Load_A_Register(1):
+ offset = M_Offset_G1_Load_A;
+ break;
+ case G_Load_B_Register(0):
+ offset = M_Offset_G0_Load_B;
+ break;
+ case G_Load_B_Register(1):
+ offset = M_Offset_G1_Load_B;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return;
+ }
+ ni_writel(dev, data, offset);
+}
+
+static void m_series_stc_writew(struct comedi_device *dev,
+ uint16_t data, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case ADC_FIFO_Clear:
+ offset = M_Offset_AI_FIFO_Clear;
+ break;
+ case AI_Command_1_Register:
+ offset = M_Offset_AI_Command_1;
+ break;
+ case AI_Command_2_Register:
+ offset = M_Offset_AI_Command_2;
+ break;
+ case AI_Mode_1_Register:
+ offset = M_Offset_AI_Mode_1;
+ break;
+ case AI_Mode_2_Register:
+ offset = M_Offset_AI_Mode_2;
+ break;
+ case AI_Mode_3_Register:
+ offset = M_Offset_AI_Mode_3;
+ break;
+ case AI_Output_Control_Register:
+ offset = M_Offset_AI_Output_Control;
+ break;
+ case AI_Personal_Register:
+ offset = M_Offset_AI_Personal;
+ break;
+ case AI_SI2_Load_A_Register:
+ /* this is a 32 bit register on m series boards */
+ ni_writel(dev, data, M_Offset_AI_SI2_Load_A);
+ return;
+ case AI_SI2_Load_B_Register:
+ /* this is a 32 bit register on m series boards */
+ ni_writel(dev, data, M_Offset_AI_SI2_Load_B);
+ return;
+ case AI_START_STOP_Select_Register:
+ offset = M_Offset_AI_START_STOP_Select;
+ break;
+ case AI_Trigger_Select_Register:
+ offset = M_Offset_AI_Trigger_Select;
+ break;
+ case Analog_Trigger_Etc_Register:
+ offset = M_Offset_Analog_Trigger_Etc;
+ break;
+ case AO_Command_1_Register:
+ offset = M_Offset_AO_Command_1;
+ break;
+ case AO_Command_2_Register:
+ offset = M_Offset_AO_Command_2;
+ break;
+ case AO_Mode_1_Register:
+ offset = M_Offset_AO_Mode_1;
+ break;
+ case AO_Mode_2_Register:
+ offset = M_Offset_AO_Mode_2;
+ break;
+ case AO_Mode_3_Register:
+ offset = M_Offset_AO_Mode_3;
+ break;
+ case AO_Output_Control_Register:
+ offset = M_Offset_AO_Output_Control;
+ break;
+ case AO_Personal_Register:
+ offset = M_Offset_AO_Personal;
+ break;
+ case AO_Start_Select_Register:
+ offset = M_Offset_AO_Start_Select;
+ break;
+ case AO_Trigger_Select_Register:
+ offset = M_Offset_AO_Trigger_Select;
+ break;
+ case Clock_and_FOUT_Register:
+ offset = M_Offset_Clock_and_FOUT;
+ break;
+ case Configuration_Memory_Clear:
+ offset = M_Offset_Configuration_Memory_Clear;
+ break;
+ case DAC_FIFO_Clear:
+ offset = M_Offset_AO_FIFO_Clear;
+ break;
+ case DIO_Control_Register:
+ dev_dbg(dev->class_dev,
+ "%s: FIXME: register 0x%x does not map cleanly on to m-series boards\n",
+ __func__, reg);
+ return;
+ case G_Autoincrement_Register(0):
+ offset = M_Offset_G0_Autoincrement;
+ break;
+ case G_Autoincrement_Register(1):
+ offset = M_Offset_G1_Autoincrement;
+ break;
+ case G_Command_Register(0):
+ offset = M_Offset_G0_Command;
+ break;
+ case G_Command_Register(1):
+ offset = M_Offset_G1_Command;
+ break;
+ case G_Input_Select_Register(0):
+ offset = M_Offset_G0_Input_Select;
+ break;
+ case G_Input_Select_Register(1):
+ offset = M_Offset_G1_Input_Select;
+ break;
+ case G_Mode_Register(0):
+ offset = M_Offset_G0_Mode;
+ break;
+ case G_Mode_Register(1):
+ offset = M_Offset_G1_Mode;
+ break;
+ case Interrupt_A_Ack_Register:
+ offset = M_Offset_Interrupt_A_Ack;
+ break;
+ case Interrupt_A_Enable_Register:
+ offset = M_Offset_Interrupt_A_Enable;
+ break;
+ case Interrupt_B_Ack_Register:
+ offset = M_Offset_Interrupt_B_Ack;
+ break;
+ case Interrupt_B_Enable_Register:
+ offset = M_Offset_Interrupt_B_Enable;
+ break;
+ case Interrupt_Control_Register:
+ offset = M_Offset_Interrupt_Control;
+ break;
+ case IO_Bidirection_Pin_Register:
+ offset = M_Offset_IO_Bidirection_Pin;
+ break;
+ case Joint_Reset_Register:
+ offset = M_Offset_Joint_Reset;
+ break;
+ case RTSI_Trig_A_Output_Register:
+ offset = M_Offset_RTSI_Trig_A_Output;
+ break;
+ case RTSI_Trig_B_Output_Register:
+ offset = M_Offset_RTSI_Trig_B_Output;
+ break;
+ case RTSI_Trig_Direction_Register:
+ offset = M_Offset_RTSI_Trig_Direction;
+ break;
+ /*
+ * FIXME: DIO_Output_Register (16 bit reg) is replaced by
+ * M_Offset_Static_Digital_Output (32 bit) and
+ * M_Offset_SCXI_Serial_Data_Out (8 bit)
+ */
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return;
+ }
+ ni_writew(dev, data, offset);
+}
+
+static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case G_HW_Save_Register(0):
+ offset = M_Offset_G0_HW_Save;
+ break;
+ case G_HW_Save_Register(1):
+ offset = M_Offset_G1_HW_Save;
+ break;
+ case G_Save_Register(0):
+ offset = M_Offset_G0_Save;
+ break;
+ case G_Save_Register(1):
+ offset = M_Offset_G1_Save;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return 0;
+ }
+ return ni_readl(dev, offset);
+}
+
+static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case AI_Status_1_Register:
+ offset = M_Offset_AI_Status_1;
+ break;
+ case AO_Status_1_Register:
+ offset = M_Offset_AO_Status_1;
+ break;
+ case AO_Status_2_Register:
+ offset = M_Offset_AO_Status_2;
+ break;
+ case DIO_Serial_Input_Register:
+ return ni_readb(dev, M_Offset_SCXI_Serial_Data_In);
+ case Joint_Status_1_Register:
+ offset = M_Offset_Joint_Status_1;
+ break;
+ case Joint_Status_2_Register:
+ offset = M_Offset_Joint_Status_2;
+ break;
+ case G_Status_Register:
+ offset = M_Offset_G01_Status;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return 0;
+ }
+ return ni_readw(dev, offset);
+}
+
+static void ni_stc_writew(struct comedi_device *dev, uint16_t data, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags;
+
+ if (devpriv->is_m_series) {
+ m_series_stc_writew(dev, data, reg);
+ } else {
+ spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (!devpriv->mite && reg < 8) {
+ ni_writew(dev, data, reg * 2);
+ } else {
+ ni_writew(dev, reg, Window_Address);
+ ni_writew(dev, data, Window_Data);
+ }
+ spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ }
+}
+
+static void ni_stc_writel(struct comedi_device *dev, uint32_t data, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv->is_m_series) {
+ m_series_stc_writel(dev, data, reg);
+ } else {
+ ni_stc_writew(dev, data >> 16, reg);
+ ni_stc_writew(dev, data & 0xffff, reg + 1);
+ }
+}
+
+static uint16_t ni_stc_readw(struct comedi_device *dev, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags;
+ uint16_t val;
+
+ if (devpriv->is_m_series) {
+ val = m_series_stc_readw(dev, reg);
+ } else {
+ spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (!devpriv->mite && reg < 8) {
+ val = ni_readw(dev, reg * 2);
+ } else {
+ ni_writew(dev, reg, Window_Address);
+ val = ni_readw(dev, Window_Data);
+ }
+ spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ }
+ return val;
+}
+
+static uint32_t ni_stc_readl(struct comedi_device *dev, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ uint32_t val;
+
+ if (devpriv->is_m_series) {
+ val = m_series_stc_readl(dev, reg);
+ } else {
+ val = ni_stc_readw(dev, reg) << 16;
+ val |= ni_stc_readw(dev, reg + 1);
+ }
+ return val;
+}
static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
unsigned bit_mask, unsigned bit_values)
@@ -371,34 +644,34 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
case Interrupt_A_Enable_Register:
devpriv->int_a_enable_reg &= ~bit_mask;
devpriv->int_a_enable_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
- Interrupt_A_Enable_Register);
+ ni_stc_writew(dev, devpriv->int_a_enable_reg,
+ Interrupt_A_Enable_Register);
break;
case Interrupt_B_Enable_Register:
devpriv->int_b_enable_reg &= ~bit_mask;
devpriv->int_b_enable_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
- Interrupt_B_Enable_Register);
+ ni_stc_writew(dev, devpriv->int_b_enable_reg,
+ Interrupt_B_Enable_Register);
break;
case IO_Bidirection_Pin_Register:
devpriv->io_bidirection_pin_reg &= ~bit_mask;
devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
- IO_Bidirection_Pin_Register);
+ ni_stc_writew(dev, devpriv->io_bidirection_pin_reg,
+ IO_Bidirection_Pin_Register);
break;
case AI_AO_Select:
devpriv->ai_ao_select_reg &= ~bit_mask;
devpriv->ai_ao_select_reg |= bit_values & bit_mask;
- ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select);
break;
case G0_G1_Select:
devpriv->g0_g1_select_reg &= ~bit_mask;
devpriv->g0_g1_select_reg |= bit_values & bit_mask;
- ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+ ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select);
break;
default:
- printk("Warning %s() called with invalid register\n", __func__);
- printk("reg is %d\n", reg);
+ dev_err(dev->class_dev,
+ "%s called with invalid register %d\n", __func__, reg);
break;
}
mmiowb();
@@ -406,8 +679,6 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
}
#ifdef PCIDMA
-static int ni_ai_drain_dma(struct comedi_device *dev);
-
/* DMA channel setup */
/* negative channel means no channel */
@@ -472,7 +743,7 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
(ni_stc_dma_channel_select_bitfield(mite_channel) <<
CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
}
- ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
+ ni_writeb(dev, devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
mmiowb();
spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
}
@@ -488,8 +759,8 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
if (devpriv->ai_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for analog input.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for analog input\n");
return -EBUSY;
}
devpriv->ai_mite_chan->dir = COMEDI_INPUT;
@@ -509,8 +780,8 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
if (devpriv->ao_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for analog outut.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for analog outut\n");
return -EBUSY;
}
devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
@@ -535,8 +806,8 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
devpriv->gpct_mite_ring[gpct_index]);
if (mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for counter.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for counter\n");
return -EBUSY;
}
mite_chan->dir = direction;
@@ -561,8 +832,8 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
if (devpriv->cdo_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for correlated digital outut.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for correlated digital output\n");
return -EBUSY;
}
devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
@@ -643,100 +914,71 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
#endif /* PCIDMA */
}
-/* e-series boards use the second irq signals to generate dma requests for their counters */
#ifdef PCIDMA
static void ni_e_series_enable_second_irq(struct comedi_device *dev,
unsigned gpct_index, short enable)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
+ uint16_t val = 0;
+ int reg;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series || gpct_index > 1)
return;
- switch (gpct_index) {
- case 0:
- if (enable) {
- devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
- Second_IRQ_A_Enable_Register);
- } else {
- devpriv->stc_writew(dev, 0,
- Second_IRQ_A_Enable_Register);
- }
- break;
- case 1:
- if (enable) {
- devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
- Second_IRQ_B_Enable_Register);
- } else {
- devpriv->stc_writew(dev, 0,
- Second_IRQ_B_Enable_Register);
- }
- break;
- default:
- BUG();
- break;
+
+ /*
+ * e-series boards use the second irq signals to generate
+ * dma requests for their counters
+ */
+ if (gpct_index == 0) {
+ reg = Second_IRQ_A_Enable_Register;
+ if (enable)
+ val = G0_Gate_Second_Irq_Enable;
+ } else {
+ reg = Second_IRQ_B_Enable_Register;
+ if (enable)
+ val = G1_Gate_Second_Irq_Enable;
}
+ ni_stc_writew(dev, val, reg);
}
#endif /* PCIDMA */
static void ni_clear_ai_fifo(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
- if (board->reg_type == ni_reg_6143) {
+ if (devpriv->is_6143) {
/* Flush the 6143 data FIFO */
- ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */
- ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */
+ ni_writel(dev, 0x10, AIFIFO_Control_6143);
+ ni_writel(dev, 0x00, AIFIFO_Control_6143);
/* Wait for complete */
for (i = 0; i < timeout; i++) {
- if (!(ni_readl(AIFIFO_Status_6143) & 0x10))
+ if (!(ni_readl(dev, AIFIFO_Status_6143) & 0x10))
break;
udelay(1);
}
- if (i == timeout) {
- comedi_error(dev, "FIFO flush timeout.");
- }
+ if (i == timeout)
+ dev_err(dev->class_dev, "FIFO flush timeout\n");
} else {
- devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
- if (board->reg_type == ni_reg_625x) {
- ni_writeb(0, M_Offset_Static_AI_Control(0));
- ni_writeb(1, M_Offset_Static_AI_Control(0));
+ ni_stc_writew(dev, 1, ADC_FIFO_Clear);
+ if (devpriv->is_625x) {
+ ni_writeb(dev, 0, M_Offset_Static_AI_Control(0));
+ ni_writeb(dev, 1, M_Offset_Static_AI_Control(0));
#if 0
/* the NI example code does 3 convert pulses for 625x boards,
but that appears to be wrong in practice. */
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
#endif
}
}
}
-static void win_out2(struct comedi_device *dev, uint32_t data, int reg)
-{
- struct ni_private *devpriv = dev->private;
-
- devpriv->stc_writew(dev, data >> 16, reg);
- devpriv->stc_writew(dev, data & 0xffff, reg + 1);
-}
-
-static uint32_t win_in2(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- uint32_t bits;
-
- bits = devpriv->stc_readw(dev, reg) << 16;
- bits |= devpriv->stc_readw(dev, reg + 1);
- return bits;
-}
-
-#define ao_win_out(data, addr) ni_ao_win_outw(dev, data, addr)
static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
int addr)
{
@@ -744,8 +986,8 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- ni_writew(data, AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ ni_writew(dev, data, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
}
@@ -756,8 +998,8 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- ni_writel(data, AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ ni_writel(dev, data, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
}
@@ -768,8 +1010,8 @@ static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
unsigned short data;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- data = ni_readw(AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ data = ni_readw(dev, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
return data;
}
@@ -796,83 +1038,58 @@ static inline void ni_set_bits(struct comedi_device *dev, int reg,
ni_set_bitfield(dev, reg, bits, bit_values);
}
-static irqreturn_t ni_E_interrupt(int irq, void *d)
+#ifdef PCIDMA
+static void ni_sync_ai_dma(struct comedi_device *dev)
{
- struct comedi_device *dev = d;
struct ni_private *devpriv = dev->private;
- unsigned short a_status;
- unsigned short b_status;
- unsigned int ai_mite_status = 0;
- unsigned int ao_mite_status = 0;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned long flags;
-#ifdef PCIDMA
- struct mite_struct *mite = devpriv->mite;
-#endif
-
- if (!dev->attached)
- return IRQ_NONE;
- smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
-
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&dev->spinlock, flags);
- a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
- b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
-#ifdef PCIDMA
- if (mite) {
- unsigned long flags_too;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
- if (devpriv->ai_mite_chan) {
- ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
- if (ai_mite_status & CHSR_LINKC)
- writel(CHOR_CLRLC,
- devpriv->mite->mite_io_addr +
- MITE_CHOR(devpriv->
- ai_mite_chan->channel));
- }
- if (devpriv->ao_mite_chan) {
- ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
- if (ao_mite_status & CHSR_LINKC)
- writel(CHOR_CLRLC,
- mite->mite_io_addr +
- MITE_CHOR(devpriv->
- ao_mite_chan->channel));
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
- }
-#endif
- ack_a_interrupt(dev, a_status);
- ack_b_interrupt(dev, b_status);
- if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
- handle_a_interrupt(dev, a_status, ai_mite_status);
- if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
- handle_b_interrupt(dev, b_status, ao_mite_status);
- handle_gpct_interrupt(dev, 0);
- handle_gpct_interrupt(dev, 1);
- handle_cdio_interrupt(dev);
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return IRQ_HANDLED;
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan)
+ mite_sync_input_dma(devpriv->ai_mite_chan, s);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
}
-#ifdef PCIDMA
-static void ni_sync_ai_dma(struct comedi_device *dev)
+static int ni_ai_drain_dma(struct comedi_device *dev)
{
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ int i;
+ static const int timeout = 10000;
unsigned long flags;
+ int retval = 0;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan)
- mite_sync_input_dma(devpriv->ai_mite_chan, s);
+ if (devpriv->ai_mite_chan) {
+ for (i = 0; i < timeout; i++) {
+ if ((ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St)
+ && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
+ 0)
+ break;
+ udelay(5);
+ }
+ if (i == timeout) {
+ dev_err(dev->class_dev, "%s timed out\n", __func__);
+ dev_err(dev->class_dev,
+ "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
+ mite_bytes_in_transit(devpriv->ai_mite_chan),
+ ni_stc_readw(dev, AI_Status_1_Register));
+ retval = -1;
+ }
+ }
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ ni_sync_ai_dma(dev);
+
+ return retval;
}
static void mite_handle_b_linkc(struct mite_struct *mite,
struct comedi_device *dev)
{
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
+ struct comedi_subdevice *s = dev->write_subdev;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -883,13 +1100,13 @@ static void mite_handle_b_linkc(struct mite_struct *mite,
static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
+
for (i = 0; i < timeout; i++) {
unsigned short b_status;
- b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+ b_status = ni_stc_readw(dev, AO_Status_1_Register);
if (b_status & AO_FIFO_Half_Full_St)
break;
/* if we poll too often, the pci bus activity seems
@@ -897,247 +1114,19 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
udelay(10);
}
if (i == timeout) {
- comedi_error(dev, "timed out waiting for dma load");
+ dev_err(dev->class_dev, "timed out waiting for dma load\n");
return -EPIPE;
}
return 0;
}
-
#endif /* PCIDMA */
-static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->aimode == AIMODE_SCAN) {
-#ifdef PCIDMA
- static const int timeout = 10;
- int i;
-
- for (i = 0; i < timeout; i++) {
- ni_sync_ai_dma(dev);
- if ((s->async->events & COMEDI_CB_EOS))
- break;
- udelay(1);
- }
-#else
- ni_handle_fifo_dregs(dev);
- s->async->events |= COMEDI_CB_EOS;
-#endif
- }
- /* handle special case of single scan using AI_End_On_End_Of_Scan */
- if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan))
- shutdown_ai_command(dev);
-}
-
-static void shutdown_ai_command(struct comedi_device *dev)
-{
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-
-#ifdef PCIDMA
- ni_ai_drain_dma(dev);
-#endif
- ni_handle_fifo_dregs(dev);
- get_last_sample_611x(dev);
- get_last_sample_6143(dev);
-
- s->async->events |= COMEDI_CB_EOA;
-}
-
-static void handle_gpct_interrupt(struct comedi_device *dev,
- unsigned short counter_index)
-{
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
-
- s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
-
- ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
- s);
- cfc_handle_events(dev, s);
-#endif
-}
-
-static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
-{
- struct ni_private *devpriv = dev->private;
- unsigned short ack = 0;
-
- if (a_status & AI_SC_TC_St)
- ack |= AI_SC_TC_Interrupt_Ack;
- if (a_status & AI_START1_St)
- ack |= AI_START1_Interrupt_Ack;
- if (a_status & AI_START_St)
- ack |= AI_START_Interrupt_Ack;
- if (a_status & AI_STOP_St)
- /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
- ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */;
- if (ack)
- devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
-}
-
-static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ai_mite_status)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-
- /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
- if (s->type == COMEDI_SUBD_UNUSED)
- return;
-
-#ifdef PCIDMA
- if (ai_mite_status & CHSR_LINKC)
- ni_sync_ai_dma(dev);
-
- if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
- printk
- ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
- ai_mite_status);
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- /* disable_irq(dev->irq); */
- }
-#endif
-
- /* test for all uncommon interrupt events at the same time */
- if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
- AI_SC_TC_St | AI_START1_St)) {
- if (status == 0xffff) {
- printk
- ("ni_mio_common: a_status=0xffff. Card removed?\n");
- /* we probably aren't even running a command now,
- * so it's a good idea to be careful. */
- if (comedi_is_subdevice_running(s)) {
- s->async->events |=
- COMEDI_CB_ERROR | COMEDI_CB_EOA;
- cfc_handle_events(dev, s);
- }
- return;
- }
- if (status & (AI_Overrun_St | AI_Overflow_St |
- AI_SC_TC_Error_St)) {
- printk("ni_mio_common: ai error a_status=%04x\n",
- status);
-
- shutdown_ai_command(dev);
-
- s->async->events |= COMEDI_CB_ERROR;
- if (status & (AI_Overrun_St | AI_Overflow_St))
- s->async->events |= COMEDI_CB_OVERFLOW;
-
- cfc_handle_events(dev, s);
- return;
- }
- if (status & AI_SC_TC_St) {
- if (!devpriv->ai_continuous)
- shutdown_ai_command(dev);
- }
- }
-#ifndef PCIDMA
- if (status & AI_FIFO_Half_Full_St) {
- int i;
- static const int timeout = 10;
- /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
- *fail to get the fifo less than half full, so loop to be sure.*/
- for (i = 0; i < timeout; ++i) {
- ni_handle_fifo_half_full(dev);
- if ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Half_Full_St) == 0)
- break;
- }
- }
-#endif /* !PCIDMA */
-
- if ((status & AI_STOP_St))
- ni_handle_eos(dev, s);
-
- cfc_handle_events(dev, s);
-}
-
-static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
-{
- struct ni_private *devpriv = dev->private;
- unsigned short ack = 0;
-
- if (b_status & AO_BC_TC_St)
- ack |= AO_BC_TC_Interrupt_Ack;
- if (b_status & AO_Overrun_St)
- ack |= AO_Error_Interrupt_Ack;
- if (b_status & AO_START_St)
- ack |= AO_START_Interrupt_Ack;
- if (b_status & AO_START1_St)
- ack |= AO_START1_Interrupt_Ack;
- if (b_status & AO_UC_TC_St)
- ack |= AO_UC_TC_Interrupt_Ack;
- if (b_status & AO_UI2_TC_St)
- ack |= AO_UI2_TC_Interrupt_Ack;
- if (b_status & AO_UPDATE_St)
- ack |= AO_UPDATE_Interrupt_Ack;
- if (ack)
- devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
-}
-
-static void handle_b_interrupt(struct comedi_device *dev,
- unsigned short b_status, unsigned ao_mite_status)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
- /* unsigned short ack=0; */
-
-#ifdef PCIDMA
- /* Currently, mite.c requires us to handle LINKC */
- if (ao_mite_status & CHSR_LINKC)
- mite_handle_b_linkc(devpriv->mite, dev);
-
- if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
- printk
- ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
- ao_mite_status);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- }
-#endif
-
- if (b_status == 0xffff)
- return;
- if (b_status & AO_Overrun_St) {
- printk
- ("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
- b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
-
- if (b_status & AO_BC_TC_St)
- s->async->events |= COMEDI_CB_EOA;
-
-#ifndef PCIDMA
- if (b_status & AO_FIFO_Request_St) {
- int ret;
-
- ret = ni_ao_fifo_half_empty(dev, s);
- if (!ret) {
- printk("ni_mio_common: AO buffer underrun\n");
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- AO_FIFO_Interrupt_Enable |
- AO_Error_Interrupt_Enable, 0);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- }
-#endif
-
- cfc_handle_events(dev, s);
-}
#ifndef PCIDMA
static void ni_ao_fifo_load(struct comedi_device *dev,
struct comedi_subdevice *s, int n)
{
- const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
int chan;
@@ -1155,10 +1144,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
range = CR_RANGE(cmd->chanlist[chan]);
- if (board->reg_type & ni_reg_6xxx_mask) {
+ if (devpriv->is_6xxx) {
packed_data = d & 0xffff;
/* 6711 only has 16 bit wide ao fifo */
- if (board->reg_type != ni_reg_6711) {
+ if (!devpriv->is_6711) {
err &= comedi_buf_get(s, &d);
if (err == 0)
break;
@@ -1166,9 +1155,9 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
i++;
packed_data |= (d << 16) & 0xffff0000;
}
- ni_writel(packed_data, DAC_FIFO_Data_611x);
+ ni_writel(dev, packed_data, DAC_FIFO_Data_611x);
} else {
- ni_writew(d, DAC_FIFO_Data);
+ ni_writew(dev, d, DAC_FIFO_Data);
}
chan++;
chan %= cmd->chanlist_len;
@@ -1225,8 +1214,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
int n;
/* reset fifo */
- devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (board->reg_type & ni_reg_6xxx_mask)
+ ni_stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (devpriv->is_6xxx)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
/* load some data */
@@ -1246,17 +1235,16 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
static void ni_ai_fifo_read(struct comedi_device *dev,
struct comedi_subdevice *s, int n)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
int i;
- if (board->reg_type == ni_reg_611x) {
+ if (devpriv->is_611x) {
unsigned short data[2];
u32 dl;
for (i = 0; i < n / 2; i++) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16) & 0xffff;
data[1] = dl & 0xffff;
@@ -1264,17 +1252,17 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
}
/* Check if there's a single sample stuck in the FIFO */
if (n % 2) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
data[0] = dl & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
unsigned short data[2];
u32 dl;
/* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */
for (i = 0; i < n / 2; i++) {
- dl = ni_readl(AIFIFO_Data_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
data[1] = dl & 0xffff;
@@ -1282,21 +1270,23 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
}
if (n % 2) {
/* Assume there is a single sample stuck in the FIFO */
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
} else {
if (n > sizeof(devpriv->ai_fifo_buffer) /
sizeof(devpriv->ai_fifo_buffer[0])) {
- comedi_error(dev, "bug! ai_fifo_buffer too small");
+ dev_err(dev->class_dev,
+ "bug! ai_fifo_buffer too small\n");
async->events |= COMEDI_CB_ERROR;
return;
}
for (i = 0; i < n; i++) {
devpriv->ai_fifo_buffer[i] =
- ni_readw(ADC_FIFO_Data_Register);
+ ni_readw(dev, ADC_FIFO_Data_Register);
}
cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
n *
@@ -1307,7 +1297,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
static void ni_handle_fifo_half_full(struct comedi_device *dev)
{
const struct ni_board_struct *board = comedi_board(dev);
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct comedi_subdevice *s = dev->read_subdev;
int n;
n = board->ai_fifo_depth / 2;
@@ -1316,70 +1306,32 @@ static void ni_handle_fifo_half_full(struct comedi_device *dev)
}
#endif
-#ifdef PCIDMA
-static int ni_ai_drain_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int i;
- static const int timeout = 10000;
- unsigned long flags;
- int retval = 0;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan) {
- for (i = 0; i < timeout; i++) {
- if ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St)
- && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
- 0)
- break;
- udelay(5);
- }
- if (i == timeout) {
- printk("ni_mio_common: wait for dma drain timed out\n");
- printk
- ("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
- mite_bytes_in_transit(devpriv->ai_mite_chan),
- devpriv->stc_readw(dev, AI_Status_1_Register));
- retval = -1;
- }
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- ni_sync_ai_dma(dev);
-
- return retval;
-}
-#endif
/*
Empties the AI fifo
*/
static void ni_handle_fifo_dregs(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data[2];
u32 dl;
unsigned short fifo_empty;
int i;
- if (board->reg_type == ni_reg_611x) {
- while ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
+ if (devpriv->is_611x) {
+ while ((ni_stc_readw(dev, AI_Status_1_Register) &
AI_FIFO_Empty_St) == 0) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16);
data[1] = (dl & 0xffff);
cfc_write_array_to_buffer(s, data, sizeof(data));
}
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
i = 0;
- while (ni_readl(AIFIFO_Status_6143) & 0x04) {
- dl = ni_readl(AIFIFO_Data_6143);
+ while (ni_readl(dev, AIFIFO_Status_6143) & 0x04) {
+ dl = ni_readl(dev, AIFIFO_Data_6143);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16);
@@ -1388,30 +1340,29 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
i += 2;
}
/* Check if stranded sample is present */
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
} else {
- fifo_empty =
- devpriv->stc_readw(dev,
- AI_Status_1_Register) & AI_FIFO_Empty_St;
+ fifo_empty = ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
while (fifo_empty == 0) {
for (i = 0;
i <
sizeof(devpriv->ai_fifo_buffer) /
sizeof(devpriv->ai_fifo_buffer[0]); i++) {
- fifo_empty =
- devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St;
+ fifo_empty = ni_stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
if (fifo_empty)
break;
devpriv->ai_fifo_buffer[i] =
- ni_readw(ADC_FIFO_Data_Register);
+ ni_readw(dev, ADC_FIFO_Data_Register);
}
cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
i *
@@ -1423,18 +1374,17 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
static void get_last_sample_611x(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv __maybe_unused = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data;
u32 dl;
- if (board->reg_type != ni_reg_611x)
+ if (!devpriv->is_611x)
return;
/* Check if there's a single sample stuck in the FIFO */
- if (ni_readb(XXX_Status) & 0x80) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ if (ni_readb(dev, XXX_Status) & 0x80) {
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
data = (dl & 0xffff);
cfc_write_to_buffer(s, data);
}
@@ -1442,19 +1392,19 @@ static void get_last_sample_611x(struct comedi_device *dev)
static void get_last_sample_6143(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv __maybe_unused = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data;
u32 dl;
- if (board->reg_type != ni_reg_6143)
+ if (!devpriv->is_6143)
return;
/* Check if there's a single sample stuck in the FIFO */
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
/* This may get the hi/lo data in the wrong order */
data = (dl >> 16) & 0xffff;
@@ -1462,6 +1412,232 @@ static void get_last_sample_6143(struct comedi_device *dev)
}
}
+static void shutdown_ai_command(struct comedi_device *dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+
+#ifdef PCIDMA
+ ni_ai_drain_dma(dev);
+#endif
+ ni_handle_fifo_dregs(dev);
+ get_last_sample_611x(dev);
+ get_last_sample_6143(dev);
+
+ s->async->events |= COMEDI_CB_EOA;
+}
+
+static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv->aimode == AIMODE_SCAN) {
+#ifdef PCIDMA
+ static const int timeout = 10;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ ni_sync_ai_dma(dev);
+ if ((s->async->events & COMEDI_CB_EOS))
+ break;
+ udelay(1);
+ }
+#else
+ ni_handle_fifo_dregs(dev);
+ s->async->events |= COMEDI_CB_EOS;
+#endif
+ }
+ /* handle special case of single scan using AI_End_On_End_Of_Scan */
+ if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan))
+ shutdown_ai_command(dev);
+}
+
+static void handle_gpct_interrupt(struct comedi_device *dev,
+ unsigned short counter_index)
+{
+#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+
+ s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
+
+ ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
+ s);
+ cfc_handle_events(dev, s);
+#endif
+}
+
+static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
+{
+ unsigned short ack = 0;
+
+ if (a_status & AI_SC_TC_St)
+ ack |= AI_SC_TC_Interrupt_Ack;
+ if (a_status & AI_START1_St)
+ ack |= AI_START1_Interrupt_Ack;
+ if (a_status & AI_START_St)
+ ack |= AI_START_Interrupt_Ack;
+ if (a_status & AI_STOP_St)
+ /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
+ ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */;
+ if (ack)
+ ni_stc_writew(dev, ack, Interrupt_A_Ack_Register);
+}
+
+static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
+ unsigned ai_mite_status)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
+ if (s->type == COMEDI_SUBD_UNUSED)
+ return;
+
+#ifdef PCIDMA
+ if (ai_mite_status & CHSR_LINKC)
+ ni_sync_ai_dma(dev);
+
+ if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ dev_err(dev->class_dev,
+ "unknown mite interrupt (ai_mite_status=%08x)\n",
+ ai_mite_status);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ /* disable_irq(dev->irq); */
+ }
+#endif
+
+ /* test for all uncommon interrupt events at the same time */
+ if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
+ AI_SC_TC_St | AI_START1_St)) {
+ if (status == 0xffff) {
+ dev_err(dev->class_dev, "Card removed?\n");
+ /* we probably aren't even running a command now,
+ * so it's a good idea to be careful. */
+ if (comedi_is_subdevice_running(s)) {
+ s->async->events |=
+ COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ cfc_handle_events(dev, s);
+ }
+ return;
+ }
+ if (status & (AI_Overrun_St | AI_Overflow_St |
+ AI_SC_TC_Error_St)) {
+ dev_err(dev->class_dev, "ai error a_status=%04x\n",
+ status);
+
+ shutdown_ai_command(dev);
+
+ s->async->events |= COMEDI_CB_ERROR;
+ if (status & (AI_Overrun_St | AI_Overflow_St))
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ cfc_handle_events(dev, s);
+ return;
+ }
+ if (status & AI_SC_TC_St) {
+ if (cmd->stop_src == TRIG_COUNT)
+ shutdown_ai_command(dev);
+ }
+ }
+#ifndef PCIDMA
+ if (status & AI_FIFO_Half_Full_St) {
+ int i;
+ static const int timeout = 10;
+ /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
+ *fail to get the fifo less than half full, so loop to be sure.*/
+ for (i = 0; i < timeout; ++i) {
+ ni_handle_fifo_half_full(dev);
+ if ((ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Half_Full_St) == 0)
+ break;
+ }
+ }
+#endif /* !PCIDMA */
+
+ if ((status & AI_STOP_St))
+ ni_handle_eos(dev, s);
+
+ cfc_handle_events(dev, s);
+}
+
+static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
+{
+ unsigned short ack = 0;
+
+ if (b_status & AO_BC_TC_St)
+ ack |= AO_BC_TC_Interrupt_Ack;
+ if (b_status & AO_Overrun_St)
+ ack |= AO_Error_Interrupt_Ack;
+ if (b_status & AO_START_St)
+ ack |= AO_START_Interrupt_Ack;
+ if (b_status & AO_START1_St)
+ ack |= AO_START1_Interrupt_Ack;
+ if (b_status & AO_UC_TC_St)
+ ack |= AO_UC_TC_Interrupt_Ack;
+ if (b_status & AO_UI2_TC_St)
+ ack |= AO_UI2_TC_Interrupt_Ack;
+ if (b_status & AO_UPDATE_St)
+ ack |= AO_UPDATE_Interrupt_Ack;
+ if (ack)
+ ni_stc_writew(dev, ack, Interrupt_B_Ack_Register);
+}
+
+static void handle_b_interrupt(struct comedi_device *dev,
+ unsigned short b_status, unsigned ao_mite_status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ /* unsigned short ack=0; */
+
+#ifdef PCIDMA
+ /* Currently, mite.c requires us to handle LINKC */
+ if (ao_mite_status & CHSR_LINKC) {
+ struct ni_private *devpriv = dev->private;
+
+ mite_handle_b_linkc(devpriv->mite, dev);
+ }
+
+ if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ dev_err(dev->class_dev,
+ "unknown mite interrupt (ao_mite_status=%08x)\n",
+ ao_mite_status);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+#endif
+
+ if (b_status == 0xffff)
+ return;
+ if (b_status & AO_Overrun_St) {
+ dev_err(dev->class_dev,
+ "AO FIFO underrun status=0x%04x status2=0x%04x\n",
+ b_status, ni_stc_readw(dev, AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ if (b_status & AO_BC_TC_St)
+ s->async->events |= COMEDI_CB_EOA;
+
+#ifndef PCIDMA
+ if (b_status & AO_FIFO_Request_St) {
+ int ret;
+
+ ret = ni_ao_fifo_half_empty(dev, s);
+ if (!ret) {
+ dev_err(dev->class_dev, "AO buffer underrun\n");
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable |
+ AO_Error_Interrupt_Enable, 0);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ }
+#endif
+
+ cfc_handle_events(dev, s);
+}
+
static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int chan_index)
@@ -1494,16 +1670,14 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct comedi_subdevice *s = dev->read_subdev;
int retval;
unsigned long flags;
retval = ni_request_ai_mite_channel(dev);
if (retval)
return retval;
-/* printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel); */
/* write alloc the entire buffer */
comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
@@ -1514,18 +1688,13 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
return -EIO;
}
- switch (board->reg_type) {
- case ni_reg_611x:
- case ni_reg_6143:
+ if (devpriv->is_611x || devpriv->is_6143)
mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
- break;
- case ni_reg_628x:
+ else if (devpriv->is_628x)
mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
- break;
- default:
+ else
mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
- break;
- }
+
/*start the MITE */
mite_dma_arm(devpriv->ai_mite_chan);
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -1535,9 +1704,8 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
+ struct comedi_subdevice *s = dev->write_subdev;
int retval;
unsigned long flags;
@@ -1550,7 +1718,7 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
if (devpriv->ao_mite_chan) {
- if (board->reg_type & (ni_reg_611x | ni_reg_6713)) {
+ if (devpriv->is_611x || devpriv->is_6713) {
mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
} else {
/* doing 32 instead of 16 bit wide transfers from memory
@@ -1575,13 +1743,12 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
ni_release_ai_mite_channel(dev);
/* ai configuration */
- devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
- Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_Start | AI_Reset,
+ Joint_Reset_Register);
ni_set_bits(dev, Interrupt_A_Enable_Register,
AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
@@ -1591,56 +1758,58 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
ni_clear_ai_fifo(dev);
- if (board->reg_type != ni_reg_6143)
- ni_writeb(0, Misc_Command);
+ if (!devpriv->is_6143)
+ ni_writeb(dev, 0, Misc_Command);
- devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
- devpriv->stc_writew(dev,
- AI_Start_Stop | AI_Mode_1_Reserved
- /*| AI_Trigger_Once */ ,
- AI_Mode_1_Register);
- devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
+ ni_stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
+ ni_stc_writew(dev, AI_Start_Stop | AI_Mode_1_Reserved
+ /*| AI_Trigger_Once */,
+ AI_Mode_1_Register);
+ ni_stc_writew(dev, 0x0000, AI_Mode_2_Register);
/* generate FIFO interrupts on non-empty */
- devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
- if (board->reg_type == ni_reg_611x) {
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
- devpriv->stc_writew(dev,
- AI_SCAN_IN_PROG_Output_Select(3) |
- AI_EXTMUX_CLK_Output_Select(0) |
- AI_LOCALMUX_CLK_Output_Select(2) |
- AI_SC_TC_Output_Select(3) |
- AI_CONVERT_Output_Select
- (AI_CONVERT_Output_Enable_High),
- AI_Output_Control_Register);
- } else if (board->reg_type == ni_reg_6143) {
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
- devpriv->stc_writew(dev,
- AI_SCAN_IN_PROG_Output_Select(3) |
- AI_EXTMUX_CLK_Output_Select(0) |
- AI_LOCALMUX_CLK_Output_Select(2) |
- AI_SC_TC_Output_Select(3) |
- AI_CONVERT_Output_Select
- (AI_CONVERT_Output_Enable_Low),
- AI_Output_Control_Register);
+ ni_stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
+ if (devpriv->is_611x) {
+ ni_stc_writew(dev,
+ AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
+ ni_stc_writew(dev,
+ AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_High),
+ AI_Output_Control_Register);
+ } else if (devpriv->is_6143) {
+ ni_stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
+ ni_stc_writew(dev,
+ AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_Low),
+ AI_Output_Control_Register);
} else {
unsigned ai_output_control_bits;
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_CONVERT_Pulse_Width |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
+
+ ni_stc_writew(dev,
+ AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_CONVERT_Pulse_Width |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
ai_output_control_bits =
AI_SCAN_IN_PROG_Output_Select(3) |
AI_EXTMUX_CLK_Output_Select(0) |
AI_LOCALMUX_CLK_Output_Select(2) |
AI_SC_TC_Output_Select(3);
- if (board->reg_type == ni_reg_622x)
+ if (devpriv->is_622x)
ai_output_control_bits |=
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_High);
@@ -1648,8 +1817,8 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
ai_output_control_bits |=
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_Low);
- devpriv->stc_writew(dev, ai_output_control_bits,
- AI_Output_Control_Register);
+ ni_stc_writew(dev, ai_output_control_bits,
+ AI_Output_Control_Register);
}
/* the following registers should not be changed, because there
* are no backup registers in devpriv. If you want to change
@@ -1659,9 +1828,17 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
* AI_Personal_Register
* AI_Output_Control_Register
*/
- devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
-
- devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev,
+ AI_SC_TC_Error_Confirm |
+ AI_START_Interrupt_Ack |
+ AI_START2_Interrupt_Ack |
+ AI_START1_Interrupt_Ack |
+ AI_SC_TC_Interrupt_Ack |
+ AI_Error_Interrupt_Ack |
+ AI_STOP_Interrupt_Ack,
+ Interrupt_A_Ack_Register); /* clear interrupts */
+
+ ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
return 0;
}
@@ -1678,127 +1855,26 @@ static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
#else
ni_sync_ai_dma(dev);
#endif
- count = s->async->buf_write_count - s->async->buf_read_count;
+ count = comedi_buf_n_bytes_ready(s);
spin_unlock_irqrestore(&dev->spinlock, flags);
return count;
}
-static int ni_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv = dev->private;
- int i, n;
- const unsigned int mask = (1 << board->adbits) - 1;
- unsigned signbits;
- unsigned short d;
- unsigned long dl;
-
- ni_load_channelgain_list(dev, 1, &insn->chanspec);
-
- ni_clear_ai_fifo(dev);
-
- signbits = devpriv->ai_offset[0];
- if (board->reg_type == ni_reg_611x) {
- for (n = 0; n < num_adc_stages_611x; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- udelay(1);
- }
- for (n = 0; n < insn->n; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- /* The 611x has screwy 32-bit FIFOs. */
- d = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readb(XXX_Status) & 0x80) {
- d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
- & 0xffff;
- break;
- }
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St)) {
- d = ni_readl(ADC_FIFO_Data_611x) &
- 0xffff;
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
- return -ETIME;
- }
- d += signbits;
- data[n] = d;
- }
- } else if (board->reg_type == ni_reg_6143) {
- for (n = 0; n < insn->n; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
-
- /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
- dl = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
- return -ETIME;
- }
- data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
- }
- } else {
- for (n = 0; n < insn->n; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St))
- break;
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in ni_ai_insn_read\n");
- return -ETIME;
- }
- if (board->reg_type & ni_reg_m_series_mask) {
- data[n] =
- ni_readl(M_Offset_AI_FIFO_Data) & mask;
- } else {
- d = ni_readw(ADC_FIFO_Data_Register);
- d += signbits; /* subtle: needs to be short addition */
- data[n] = d;
- }
- }
- }
- return insn->n;
-}
-
static void ni_prime_channelgain_list(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
int i;
- devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
for (i = 0; i < NI_TIMEOUT; ++i) {
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
AI_FIFO_Empty_St)) {
- devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ ni_stc_writew(dev, 1, ADC_FIFO_Clear);
return;
}
udelay(1);
}
- printk("ni_mio_common: timeout loading channel/gain list\n");
+ dev_err(dev->class_dev, "timeout loading channel/gain list\n");
}
static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
@@ -1809,15 +1885,14 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
- unsigned offset;
unsigned int dither;
unsigned range_code;
- devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+ ni_stc_writew(dev, 1, Configuration_Memory_Clear);
-/* offset = 1 << (board->adbits - 1); */
if ((list[0] & CR_ALT_SOURCE)) {
unsigned bypass_bits;
+
chan = CR_CHAN(list[0]);
range = CR_RANGE(list[0]);
range_code = ni_gainlkup[board->gainlkup][range];
@@ -1835,20 +1910,20 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
/* don't use 2's complement encoding */
bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
- ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+ ni_writel(dev, bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
} else {
- ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+ ni_writel(dev, 0, M_Offset_AI_Config_FIFO_Bypass);
}
- offset = 0;
for (i = 0; i < n_chan; i++) {
unsigned config_bits = 0;
+
chan = CR_CHAN(list[i]);
aref = CR_AREF(list[i]);
range = CR_RANGE(list[i]);
dither = ((list[i] & CR_ALT_FILTER) != 0);
range_code = ni_gainlkup[board->gainlkup][range];
- devpriv->ai_offset[i] = offset;
+ devpriv->ai_offset[i] = 0;
switch (aref) {
case AREF_DIFF:
config_bits |=
@@ -1875,7 +1950,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
config_bits |= MSeries_AI_Config_Dither_Bit;
/* don't use 2's complement encoding */
config_bits |= MSeries_AI_Config_Polarity_Bit;
- ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
+ ni_writew(dev, config_bits, M_Offset_AI_Config_FIFO_Data);
}
ni_prime_channelgain_list(dev);
}
@@ -1910,22 +1985,22 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
* valid channels are 0-3
*/
static void ni_load_channelgain_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
unsigned int n_chan, unsigned int *list)
{
const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
+ unsigned int offset = (s->maxdata + 1) >> 1;
unsigned int chan, range, aref;
unsigned int i;
unsigned int hi, lo;
- unsigned offset;
unsigned int dither;
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
ni_m_series_load_channelgain_list(dev, n_chan, list);
return;
}
- if (n_chan == 1 && (board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (n_chan == 1 && !devpriv->is_611x && !devpriv->is_6143) {
if (devpriv->changain_state
&& devpriv->changain_spec == list[0]) {
/* ready to go. */
@@ -1937,61 +2012,58 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
devpriv->changain_state = 0;
}
- devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+ ni_stc_writew(dev, 1, Configuration_Memory_Clear);
/* Set up Calibration mode if required */
- if (board->reg_type == ni_reg_6143) {
+ if (devpriv->is_6143) {
if ((list[0] & CR_ALT_SOURCE)
&& !devpriv->ai_calib_source_enabled) {
/* Strobe Relay enable bit */
- ni_writew(devpriv->ai_calib_source |
- Calibration_Channel_6143_RelayOn,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOn,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source,
+ ni_writew(dev, devpriv->ai_calib_source,
Calibration_Channel_6143);
devpriv->ai_calib_source_enabled = 1;
msleep_interruptible(100); /* Allow relays to change */
} else if (!(list[0] & CR_ALT_SOURCE)
&& devpriv->ai_calib_source_enabled) {
/* Strobe Relay disable bit */
- ni_writew(devpriv->ai_calib_source |
- Calibration_Channel_6143_RelayOff,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source,
+ ni_writew(dev, devpriv->ai_calib_source,
Calibration_Channel_6143);
devpriv->ai_calib_source_enabled = 0;
msleep_interruptible(100); /* Allow relays to change */
}
}
- offset = 1 << (board->adbits - 1);
for (i = 0; i < n_chan; i++) {
- if ((board->reg_type != ni_reg_6143)
- && (list[i] & CR_ALT_SOURCE)) {
+ if (!devpriv->is_6143 && (list[i] & CR_ALT_SOURCE))
chan = devpriv->ai_calib_source;
- } else {
+ else
chan = CR_CHAN(list[i]);
- }
aref = CR_AREF(list[i]);
range = CR_RANGE(list[i]);
dither = ((list[i] & CR_ALT_FILTER) != 0);
/* fix the external/internal range differences */
range = ni_gainlkup[board->gainlkup][range];
- if (board->reg_type == ni_reg_611x)
+ if (devpriv->is_611x)
devpriv->ai_offset[i] = offset;
else
devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
hi = 0;
if ((list[i] & CR_ALT_SOURCE)) {
- if (board->reg_type == ni_reg_611x)
- ni_writew(CR_CHAN(list[i]) & 0x0003,
+ if (devpriv->is_611x)
+ ni_writew(dev, CR_CHAN(list[i]) & 0x0003,
Calibration_Channel_Select_611x);
} else {
- if (board->reg_type == ni_reg_611x)
+ if (devpriv->is_611x)
aref = AREF_DIFF;
- else if (board->reg_type == ni_reg_6143)
+ else if (devpriv->is_6143)
aref = AREF_OTHER;
switch (aref) {
case AREF_DIFF:
@@ -2009,33 +2081,132 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
}
hi |= AI_CONFIG_CHANNEL(chan);
- ni_writew(hi, Configuration_Memory_High);
+ ni_writew(dev, hi, Configuration_Memory_High);
- if (board->reg_type != ni_reg_6143) {
+ if (!devpriv->is_6143) {
lo = range;
if (i == n_chan - 1)
lo |= AI_LAST_CHANNEL;
if (dither)
lo |= AI_DITHER;
- ni_writew(lo, Configuration_Memory_Low);
+ ni_writew(dev, lo, Configuration_Memory_Low);
}
}
/* prime the channel/gain list */
- if ((board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (!devpriv->is_611x && !devpriv->is_6143)
ni_prime_channelgain_list(dev);
+}
+
+static int ni_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned int mask = (s->maxdata + 1) >> 1;
+ int i, n;
+ unsigned signbits;
+ unsigned short d;
+ unsigned long dl;
+
+ ni_load_channelgain_list(dev, s, 1, &insn->chanspec);
+
+ ni_clear_ai_fifo(dev);
+
+ signbits = devpriv->ai_offset[0];
+ if (devpriv->is_611x) {
+ for (n = 0; n < num_adc_stages_611x; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ udelay(1);
+ }
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ /* The 611x has screwy 32-bit FIFOs. */
+ d = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readb(dev, XXX_Status) & 0x80) {
+ d = ni_readl(dev, ADC_FIFO_Data_611x);
+ d >>= 16;
+ d &= 0xffff;
+ break;
+ }
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ d = ni_readl(dev, ADC_FIFO_Data_611x);
+ d &= 0xffff;
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ d += signbits;
+ data[n] = d;
+ }
+ } else if (devpriv->is_6143) {
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+
+ /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+ dl = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01,
+ AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+ }
+ } else {
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St))
+ break;
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ if (devpriv->is_m_series) {
+ dl = ni_readl(dev, M_Offset_AI_FIFO_Data);
+ dl &= mask;
+ data[n] = dl;
+ } else {
+ d = ni_readw(dev, ADC_FIFO_Data_Register);
+ d += signbits; /* subtle: needs to be short addition */
+ data[n] = d;
+ }
+ }
}
+ return insn->n;
}
static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec,
- int round_mode)
+ unsigned int flags)
{
struct ni_private *devpriv = dev->private;
int divider;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
@@ -2061,17 +2232,13 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
unsigned num_channels)
{
const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
- switch (board->reg_type) {
- case ni_reg_611x:
- case ni_reg_6143:
- /* simultaneously-sampled inputs */
+ /* simultaneously-sampled inputs */
+ if (devpriv->is_611x || devpriv->is_6143)
return board->ai_speed;
- break;
- default:
- /* multiplexed inputs */
- break;
- }
+
+ /* multiplexed inputs */
return board->ai_speed * num_channels;
}
@@ -2095,8 +2262,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
TRIG_TIMER | TRIG_EXT);
sources = TRIG_TIMER | TRIG_EXT;
- if (board->reg_type == ni_reg_611x ||
- board->reg_type == ni_reg_6143)
+ if (devpriv->is_611x || devpriv->is_6143)
sources |= TRIG_NOW;
err |= cfc_check_trigger_src(&cmd->convert_src, sources);
@@ -2153,8 +2319,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((board->reg_type == ni_reg_611x)
- || (board->reg_type == ni_reg_6143)) {
+ if (devpriv->is_611x || devpriv->is_6143) {
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
} else {
err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
@@ -2179,7 +2344,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (cmd->stop_src == TRIG_COUNT) {
unsigned int max_count = 0x01000000;
- if (board->reg_type == ni_reg_611x)
+ if (devpriv->is_611x)
max_count -= num_adc_stages_611x;
err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count);
err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
@@ -2198,22 +2363,17 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
cmd->scan_begin_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->scan_begin_arg)
err++;
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (!devpriv->is_611x && !devpriv->is_6143) {
tmp = cmd->convert_arg;
cmd->convert_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->convert_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->convert_arg)
err++;
if (cmd->scan_begin_src == TRIG_TIMER &&
@@ -2232,9 +2392,25 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
return 0;
}
+static int ni_ai_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
+{
+ struct ni_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
+
+ ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
int timer;
@@ -2245,29 +2421,30 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
int interrupt_a_enable = 0;
if (dev->irq == 0) {
- comedi_error(dev, "cannot run command without an irq");
+ dev_err(dev->class_dev, "cannot run command without an irq\n");
return -EIO;
}
ni_clear_ai_fifo(dev);
- ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+ ni_load_channelgain_list(dev, s, cmd->chanlist_len, cmd->chanlist);
/* start configuration */
- devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
/* disable analog triggering for now, since it
* interferes with the use of pfi0 */
devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
switch (cmd->start_src) {
case TRIG_INT:
case TRIG_NOW:
- devpriv->stc_writew(dev, AI_START2_Select(0) |
- AI_START1_Sync | AI_START1_Edge |
- AI_START1_Select(0),
- AI_Trigger_Select_Register);
+ ni_stc_writew(dev,
+ AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Edge |
+ AI_START1_Select(0),
+ AI_Trigger_Select_Register);
break;
case TRIG_EXT:
{
@@ -2279,8 +2456,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
bits |= AI_START1_Polarity;
if (cmd->start_arg & CR_EDGE)
bits |= AI_START1_Edge;
- devpriv->stc_writew(dev, bits,
- AI_Trigger_Select_Register);
+ ni_stc_writew(dev, bits, AI_Trigger_Select_Register);
break;
}
}
@@ -2288,37 +2464,34 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
mode2 &= ~AI_Pre_Trigger;
mode2 &= ~AI_SC_Initial_Load_Source;
mode2 &= ~AI_SC_Reload_Mode;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
- if (cmd->chanlist_len == 1 || (board->reg_type == ni_reg_611x)
- || (board->reg_type == ni_reg_6143)) {
+ if (cmd->chanlist_len == 1 || devpriv->is_611x || devpriv->is_6143) {
start_stop_select |= AI_STOP_Polarity;
start_stop_select |= AI_STOP_Select(31); /* logic low */
start_stop_select |= AI_STOP_Sync;
} else {
start_stop_select |= AI_STOP_Select(19); /* ai configuration memory */
}
- devpriv->stc_writew(dev, start_stop_select,
- AI_START_STOP_Select_Register);
+ ni_stc_writew(dev, start_stop_select, AI_START_STOP_Select_Register);
devpriv->ai_cmd2 = 0;
switch (cmd->stop_src) {
case TRIG_COUNT:
stop_count = cmd->stop_arg - 1;
- if (board->reg_type == ni_reg_611x) {
+ if (devpriv->is_611x) {
/* have to take 3 stage adc pipeline into account */
stop_count += num_adc_stages_611x;
}
/* stage number of scans */
- devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
+ ni_stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
/* load SC (Scan Count) */
- devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
- devpriv->ai_continuous = 0;
if (stop_count == 0) {
devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
interrupt_a_enable |= AI_STOP_Interrupt_Enable;
@@ -2330,16 +2503,13 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
break;
case TRIG_NONE:
/* stage number of scans */
- devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
+ ni_stc_writel(dev, 0, AI_SC_Load_A_Registers);
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
/* load SC (Scan Count) */
- devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
-
- devpriv->ai_continuous = 1;
-
+ ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
break;
}
@@ -2360,20 +2530,20 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
AI_STOP_Select=19 external pin (configuration mem)
*/
start_stop_select |= AI_START_Edge | AI_START_Sync;
- devpriv->stc_writew(dev, start_stop_select,
- AI_START_STOP_Select_Register);
+ ni_stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
mode2 |= AI_SI_Reload_Mode(0);
/* AI_SI_Initial_Load_Source=A */
mode2 &= ~AI_SI_Initial_Load_Source;
/* mode2 |= AI_SC_Reload_Mode; */
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
/* load SI */
timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
- devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
+ ni_stc_writel(dev, timer, AI_SI_Load_A_Registers);
+ ni_stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
break;
case TRIG_EXT:
if (cmd->scan_begin_arg & CR_EDGE)
@@ -2387,7 +2557,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
start_stop_select |= AI_START_Sync;
start_stop_select |=
AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
- devpriv->stc_writew(dev, start_stop_select,
+ ni_stc_writew(dev, start_stop_select,
AI_START_STOP_Select_Register);
break;
}
@@ -2400,31 +2570,32 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else
timer = ni_ns_to_timer(dev, cmd->convert_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */
- devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
+ /* 0,0 does not work */
+ ni_stc_writew(dev, 1, AI_SI2_Load_A_Register);
+ ni_stc_writew(dev, timer, AI_SI2_Load_B_Register);
/* AI_SI2_Reload_Mode = alternate */
/* AI_SI2_Initial_Load_Source = A */
mode2 &= ~AI_SI2_Initial_Load_Source;
mode2 |= AI_SI2_Reload_Mode;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
/* AI_SI2_Load */
- devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
mode2 |= AI_SI2_Reload_Mode; /* alternate */
mode2 |= AI_SI2_Initial_Load_Source; /* B */
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
break;
case TRIG_EXT:
mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
if ((cmd->convert_arg & CR_INVERT) == 0)
mode1 |= AI_CONVERT_Source_Polarity;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
break;
}
@@ -2451,25 +2622,25 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case AIMODE_HALF_FULL:
/*generate FIFO interrupts and DMA requests on half-full */
#ifdef PCIDMA
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF_to_E,
+ AI_Mode_3_Register);
#else
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
#endif
break;
case AIMODE_SAMPLE:
/*generate FIFO interrupts on non-empty */
- devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
break;
case AIMODE_SCAN:
#ifdef PCIDMA
- devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
#else
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
#endif
interrupt_a_enable |= AI_STOP_Interrupt_Enable;
break;
@@ -2477,7 +2648,16 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
break;
}
- devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */
+ /* clear interrupts */
+ ni_stc_writew(dev,
+ AI_Error_Interrupt_Ack |
+ AI_STOP_Interrupt_Ack |
+ AI_START_Interrupt_Ack |
+ AI_START2_Interrupt_Ack |
+ AI_START1_Interrupt_Ack |
+ AI_SC_TC_Interrupt_Ack |
+ AI_SC_TC_Error_Confirm,
+ Interrupt_A_Ack_Register);
ni_set_bits(dev, Interrupt_A_Enable_Register,
interrupt_a_enable, 1);
@@ -2489,25 +2669,26 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* end configuration */
- devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- devpriv->stc_writew(dev,
- AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
- AI_SC_Arm, AI_Command_1_Register);
+ ni_stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
break;
case TRIG_EXT:
/* XXX AI_SI_Arm? */
- devpriv->stc_writew(dev,
- AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
- AI_SC_Arm, AI_Command_1_Register);
+ ni_stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
break;
}
#ifdef PCIDMA
{
int retval = ni_ai_setup_MITE_dma(dev);
+
if (retval)
return retval;
}
@@ -2515,8 +2696,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->start_src == TRIG_NOW) {
/* AI_START1_Pulse */
- devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
- AI_Command_2_Register);
+ ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
s->async->inttrig = NULL;
} else if (cmd->start_src == TRIG_EXT) {
s->async->inttrig = NULL;
@@ -2527,43 +2708,18 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
-static int ni_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
- AI_Command_2_Register);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-static int ni_ai_config_analog_trig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
static int ni_ai_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
if (insn->n < 1)
return -EINVAL;
switch (data[0]) {
- case INSN_CONFIG_ANALOG_TRIG:
- return ni_ai_config_analog_trig(dev, s, insn, data);
case INSN_CONFIG_ALT_SOURCE:
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
MSeries_AI_Bypass_Mode_Mux_Mask |
@@ -2571,7 +2727,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
}
devpriv->ai_calib_source = data[1];
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
unsigned int calib_source;
calib_source = data[1] & 0xf;
@@ -2580,7 +2736,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
devpriv->ai_calib_source = calib_source;
- ni_writew(calib_source, Calibration_Channel_6143);
+ ni_writew(dev, calib_source, Calibration_Channel_6143);
} else {
unsigned int calib_source;
unsigned int calib_source_adjust;
@@ -2591,8 +2747,8 @@ static int ni_ai_insn_config(struct comedi_device *dev,
if (calib_source >= 8)
return -EINVAL;
devpriv->ai_calib_source = calib_source;
- if (board->reg_type == ni_reg_611x) {
- ni_writeb(calib_source_adjust,
+ if (devpriv->is_611x) {
+ ni_writeb(dev, calib_source_adjust,
Cal_Gain_Select_611x);
}
}
@@ -2604,127 +2760,30 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
}
-static int ni_ai_config_analog_trig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv = dev->private;
- unsigned int a, b, modebits;
- int err = 0;
-
- /* data[1] is flags
- * data[2] is analog line
- * data[3] is set level
- * data[4] is reset level */
- if (!board->has_analog_trig)
- return -EINVAL;
- if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
- data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
- err++;
- }
- if (data[2] >= board->n_adchan) {
- data[2] = board->n_adchan - 1;
- err++;
- }
- if (data[3] > 255) { /* a */
- data[3] = 255;
- err++;
- }
- if (data[4] > 255) { /* b */
- data[4] = 255;
- err++;
- }
- /*
- * 00 ignore
- * 01 set
- * 10 reset
- *
- * modes:
- * 1 level: +b- +a-
- * high mode 00 00 01 10
- * low mode 00 00 10 01
- * 2 level: (a<b)
- * hysteresis low mode 10 00 00 01
- * hysteresis high mode 01 00 00 10
- * middle mode 10 01 01 10
- */
-
- a = data[3];
- b = data[4];
- modebits = data[1] & 0xff;
- if (modebits & 0xf0) {
- /* two level mode */
- if (b < a) {
- /* swap order */
- a = data[4];
- b = data[3];
- modebits =
- ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >> 4);
- }
- devpriv->atrig_low = a;
- devpriv->atrig_high = b;
- switch (modebits) {
- case 0x81: /* low hysteresis mode */
- devpriv->atrig_mode = 6;
- break;
- case 0x42: /* high hysteresis mode */
- devpriv->atrig_mode = 3;
- break;
- case 0x96: /* middle window mode */
- devpriv->atrig_mode = 2;
- break;
- default:
- data[1] &= ~0xff;
- err++;
- }
- } else {
- /* one level mode */
- if (b != 0) {
- data[4] = 0;
- err++;
- }
- switch (modebits) {
- case 0x06: /* high window mode */
- devpriv->atrig_high = a;
- devpriv->atrig_mode = 0;
- break;
- case 0x09: /* low window mode */
- devpriv->atrig_low = a;
- devpriv->atrig_mode = 1;
- break;
- default:
- data[1] &= ~0xff;
- err++;
- }
- }
- if (err)
- return -EAGAIN;
- return 5;
-}
-
-/* munge data from unsigned to 2's complement for analog output bipolar modes */
static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int chan_index)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct comedi_async *async = s->async;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int length = num_bytes / sizeof(short);
- unsigned int offset = 1 << (board->aobits - 1);
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int length = num_bytes / bytes_per_sample(s);
unsigned short *array = data;
- unsigned int range;
unsigned int i;
for (i = 0; i < length; i++) {
- range = CR_RANGE(cmd->chanlist[chan_index]);
- if (board->ao_unipolar == 0 || (range & 1) == 0)
- array[i] -= offset;
+ unsigned int range = CR_RANGE(cmd->chanlist[chan_index]);
+ unsigned short val = array[i];
+
+ /*
+ * Munge data from unsigned to two's complement for
+ * bipolar ranges.
+ */
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
#ifdef PCIDMA
- array[i] = cpu_to_le16(array[i]);
+ val = cpu_to_le16(val);
#endif
+ array[i] = val;
+
chan_index++;
chan_index %= cmd->chanlist_len;
}
@@ -2735,7 +2794,6 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans, int timed)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
@@ -2744,15 +2802,16 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
int invert = 0;
if (timed) {
- for (i = 0; i < board->n_aochan; ++i) {
+ for (i = 0; i < s->n_chan; ++i) {
devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
- ni_writeb(devpriv->ao_conf[i],
+ ni_writeb(dev, devpriv->ao_conf[i],
M_Offset_AO_Config_Bank(i));
- ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
+ ni_writeb(dev, 0xf, M_Offset_AO_Waveform_Order(i));
}
}
for (i = 0; i < n_chans; i++) {
const struct comedi_krange *krange;
+
chan = CR_CHAN(chanspec[i]);
range = CR_RANGE(chanspec[i]);
krange = s->range_table->range + range;
@@ -2761,25 +2820,28 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
switch (krange->max - krange->min) {
case 20000000:
conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
- ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ ni_writeb(dev, 0,
+ M_Offset_AO_Reference_Attenuation(chan));
break;
case 10000000:
conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
- ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ ni_writeb(dev, 0,
+ M_Offset_AO_Reference_Attenuation(chan));
break;
case 4000000:
conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
- ni_writeb(MSeries_Attenuate_x5_Bit,
+ ni_writeb(dev, MSeries_Attenuate_x5_Bit,
M_Offset_AO_Reference_Attenuation(chan));
break;
case 2000000:
conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
- ni_writeb(MSeries_Attenuate_x5_Bit,
+ ni_writeb(dev, MSeries_Attenuate_x5_Bit,
M_Offset_AO_Reference_Attenuation(chan));
break;
default:
- printk("%s: bug! unhandled ao reference voltage\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: bug! unhandled ao reference voltage\n",
+ __func__);
break;
}
switch (krange->max + krange->min) {
@@ -2790,15 +2852,16 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
conf |= MSeries_AO_DAC_Offset_5V_Bits;
break;
default:
- printk("%s: bug! unhandled ao offset voltage\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: bug! unhandled ao offset voltage\n",
+ __func__);
break;
}
if (timed)
conf |= MSeries_AO_Update_Timed_Bit;
- ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
+ ni_writeb(dev, conf, M_Offset_AO_Config_Bank(chan));
devpriv->ao_conf[chan] = conf;
- ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
+ ni_writeb(dev, i, M_Offset_AO_Waveform_Order(chan));
}
return invert;
}
@@ -2808,7 +2871,6 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
@@ -2821,19 +2883,14 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
range = CR_RANGE(chanspec[i]);
conf = AO_Channel(chan);
- if (board->ao_unipolar) {
- if ((range & 1) == 0) {
- conf |= AO_Bipolar;
- invert = (1 << (board->aobits - 1));
- } else {
- invert = 0;
- }
- if (range & 2)
- conf |= AO_Ext_Ref;
- } else {
+ if (comedi_range_is_bipolar(s, range)) {
conf |= AO_Bipolar;
- invert = (1 << (board->aobits - 1));
+ invert = (s->maxdata + 1) >> 1;
+ } else {
+ invert = 0;
}
+ if (comedi_range_is_external(s, range))
+ conf |= AO_Ext_Ref;
/* not all boards can deglitch, but this shouldn't hurt */
if (chanspec[i] & CR_DEGLITCH)
@@ -2844,7 +2901,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
conf |= (CR_AREF(chanspec[i]) ==
AREF_OTHER) ? AO_Ground_Ref : 0;
- ni_writew(conf, AO_Configuration);
+ ni_writew(dev, conf, AO_Configuration);
devpriv->ao_conf[chan] = conf;
}
return invert;
@@ -2855,9 +2912,9 @@ static int ni_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[], unsigned int n_chans,
int timed)
{
- const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
timed);
else
@@ -2865,56 +2922,75 @@ static int ni_ao_config_chanlist(struct comedi_device *dev,
}
static int ni_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
unsigned int *data)
{
struct ni_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
- data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao[chan];
- return 1;
+ return insn->n;
}
static int ni_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int invert;
-
- invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
-
- devpriv->ao[chan] = data[0];
-
- if (board->reg_type & ni_reg_m_series_mask) {
- ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
- } else
- ni_writew(data[0] ^ invert,
- (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ int reg;
+ int i;
- return 1;
-}
+ if (devpriv->is_6xxx) {
+ ni_ao_win_outw(dev, 1 << chan, AO_Immediate_671x);
-static int ni_ao_insn_write_671x(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv = dev->private;
- unsigned int chan = CR_CHAN(insn->chanspec);
- unsigned int invert;
-
- ao_win_out(1 << chan, AO_Immediate_671x);
- invert = 1 << (board->aobits - 1);
+ reg = DACx_Direct_Data_671x(chan);
+ } else if (devpriv->is_m_series) {
+ reg = M_Offset_DAC_Direct_Data(chan);
+ } else {
+ reg = (chan) ? DAC1_Direct_Data : DAC0_Direct_Data;
+ }
ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
- devpriv->ao[chan] = data[0];
- ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
+ for (i = 0; i < insn->n; i++) {
+ unsigned int val = data[i];
+
+ devpriv->ao[chan] = val;
+
+ if (devpriv->is_6xxx) {
+ /*
+ * 6xxx boards have bipolar outputs, munge the
+ * unsigned comedi values to 2's complement
+ */
+ val = comedi_offset_munge(s, val);
+
+ ni_ao_win_outw(dev, val, reg);
+ } else if (devpriv->is_m_series) {
+ /*
+ * M-series boards use offset binary values for
+ * bipolar and uinpolar outputs
+ */
+ ni_writew(dev, val, reg);
+ } else {
+ /*
+ * Non-M series boards need two's complement values
+ * for bipolar ranges.
+ */
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
+
+ ni_writew(dev, val, reg);
+ }
+ }
- return 1;
+ return insn->n;
}
static int ni_ao_insn_config(struct comedi_device *dev,
@@ -2937,7 +3013,6 @@ static int ni_ao_insn_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 0;
default:
@@ -2951,7 +3026,6 @@ static int ni_ao_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int trig_num)
{
- const struct ni_board_struct *board __maybe_unused = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int ret;
@@ -2971,8 +3045,8 @@ static int ni_ao_inttrig(struct comedi_device *dev,
AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
interrupt_b_bits = AO_Error_Interrupt_Enable;
#ifdef PCIDMA
- devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (board->reg_type & ni_reg_6xxx_mask)
+ ni_stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (devpriv->is_6xxx)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
ret = ni_ao_setup_MITE_dma(dev);
if (ret)
@@ -2988,35 +3062,36 @@ static int ni_ao_inttrig(struct comedi_device *dev,
interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
#endif
- devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
- AO_Mode_3_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
+ AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
/* wait for DACs to be loaded */
for (i = 0; i < timeout; i++) {
udelay(1);
- if ((devpriv->stc_readw(dev,
- Joint_Status_2_Register) &
+ if ((ni_stc_readw(dev, Joint_Status_2_Register) &
AO_TMRDACWRs_In_Progress_St) == 0)
break;
}
if (i == timeout) {
- comedi_error(dev,
- "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+ dev_err(dev->class_dev,
+ "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear\n");
return -EIO;
}
- /* stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears */
- devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
- Interrupt_B_Ack_Register);
+ /*
+ * stc manual says we are need to clear error interrupt after
+ * AO_TMRDACWRs_In_Progress_St clears
+ */
+ ni_stc_writew(dev, AO_Error_Interrupt_Ack, Interrupt_B_Ack_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
- devpriv->stc_writew(dev,
- devpriv->ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm
- | AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
- AO_Command_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd1 |
+ AO_UI_Arm | AO_UC_Arm | AO_BC_Arm |
+ AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
+ AO_Command_1_Register);
- devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
- AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
+ AO_Command_2_Register);
return 0;
}
@@ -3031,16 +3106,16 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned trigvar;
if (dev->irq == 0) {
- comedi_error(dev, "cannot run command without an irq");
+ dev_err(dev->class_dev, "cannot run command without an irq\n");
return -EIO;
}
- devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
- devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register);
- if (board->reg_type & ni_reg_6xxx_mask) {
- ao_win_out(CLEAR_WG, AO_Misc_611x);
+ if (devpriv->is_6xxx) {
+ ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x);
bits = 0;
for (i = 0; i < cmd->chanlist_len; i++) {
@@ -3048,9 +3123,9 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
chan = CR_CHAN(cmd->chanlist[i]);
bits |= 1 << chan;
- ao_win_out(chan, AO_Waveform_Generation_611x);
+ ni_ao_win_outw(dev, chan, AO_Waveform_Generation_611x);
}
- ao_win_out(bits, AO_Timed_611x);
+ ni_ao_win_outw(dev, bits, AO_Timed_611x);
}
ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
@@ -3062,15 +3137,15 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_mode1 &= ~AO_Continuous;
devpriv->ao_mode1 |= AO_Trigger_Once;
}
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
switch (cmd->start_src) {
case TRIG_INT:
case TRIG_NOW:
devpriv->ao_trigger_select &=
~(AO_START1_Polarity | AO_START1_Select(-1));
devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
break;
case TRIG_EXT:
devpriv->ao_trigger_select =
@@ -3079,52 +3154,50 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_trigger_select |= AO_START1_Polarity; /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
if (cmd->start_arg & CR_EDGE)
devpriv->ao_trigger_select |= AO_START1_Edge; /* 0=edge detection disabled, 1=enabled */
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
break;
default:
BUG();
break;
}
devpriv->ao_mode3 &= ~AO_Trigger_Length;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
if (cmd->stop_src == TRIG_NONE)
- devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
+ ni_stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
else
- devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
- devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, 0, AO_BC_Load_A_Register);
+ ni_stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
/* this is how the NI example code does it for m-series boards, verified correct with 6259 */
- devpriv->stc_writel(dev, cmd->stop_arg - 1,
- AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load,
- AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
} else {
- devpriv->stc_writel(dev, cmd->stop_arg,
- AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load,
- AO_Command_1_Register);
- devpriv->stc_writel(dev, cmd->stop_arg - 1,
- AO_UC_Load_A_Register);
+ ni_stc_writel(dev, cmd->stop_arg,
+ AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
}
break;
case TRIG_NONE:
- devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
break;
default:
- devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ ni_stc_writel(dev, 0, AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
}
devpriv->ao_mode1 &=
@@ -3136,9 +3209,9 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
trigvar =
ni_ns_to_timer(dev, cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
- devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
+ ni_stc_writel(dev, 1, AO_UI_Load_A_Register);
+ ni_stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, trigvar, AO_UI_Load_A_Register);
break;
case TRIG_EXT:
devpriv->ao_mode1 |=
@@ -3151,40 +3224,38 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
BUG();
break;
}
- devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 &=
~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
if (cmd->scan_end_arg > 1) {
devpriv->ao_mode1 |= AO_Multiple_Channels;
- devpriv->stc_writew(dev,
- AO_Number_Of_Channels(cmd->scan_end_arg -
- 1) |
- AO_UPDATE_Output_Select
- (AO_Update_Output_High_Z),
- AO_Output_Control_Register);
+ ni_stc_writew(dev,
+ AO_Number_Of_Channels(cmd->scan_end_arg - 1) |
+ AO_UPDATE_Output_Select(AO_Update_Output_High_Z),
+ AO_Output_Control_Register);
} else {
unsigned bits;
+
devpriv->ao_mode1 &= ~AO_Multiple_Channels;
bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
- if (board->reg_type &
- (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+ if (devpriv->is_m_series || devpriv->is_6xxx) {
bits |= AO_Number_Of_Channels(0);
} else {
bits |=
AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]));
}
- devpriv->stc_writew(dev, bits, AO_Output_Control_Register);
+ ni_stc_writew(dev, bits, AO_Output_Control_Register);
}
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
- devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
- AO_Command_1_Register);
+ ni_stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
+ AO_Command_1_Register);
devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
#ifdef PCIDMA
@@ -3193,7 +3264,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
#endif
devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
AO_TMRDACWR_Pulse_Width;
@@ -3204,18 +3275,18 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
#if 0
/* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
verified with bus analyzer. */
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
bits |= AO_Number_Of_DAC_Packages;
#endif
- devpriv->stc_writew(dev, bits, AO_Personal_Register);
+ ni_stc_writew(dev, bits, AO_Personal_Register);
/* enable sending of ao dma requests */
- devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
+ ni_stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
- devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
if (cmd->stop_src == TRIG_COUNT) {
- devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
- Interrupt_B_Ack_Register);
+ ni_stc_writew(dev, AO_BC_TC_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register,
AO_BC_TC_Interrupt_Enable, 1);
}
@@ -3299,9 +3370,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
cmd->scan_begin_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->scan_begin_arg)
err++;
}
@@ -3313,51 +3382,45 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- /* devpriv->ao0p=0x0000; */
- /* ni_writew(devpriv->ao0p,AO_Configuration); */
-
- /* devpriv->ao1p=AO_Channel(1); */
- /* ni_writew(devpriv->ao1p,AO_Configuration); */
-
ni_release_ao_mite_channel(dev);
- devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
- devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
- devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
- devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
- devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
- AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
- devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
- devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
+ ni_stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
+ ni_stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
+ ni_stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
+ ni_stc_writew(dev, 0, AO_Output_Control_Register);
+ ni_stc_writew(dev, 0, AO_Start_Select_Register);
devpriv->ao_cmd1 = 0;
- devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
devpriv->ao_cmd2 = 0;
- devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
devpriv->ao_mode1 = 0;
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 = 0;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
- if (board->reg_type & ni_reg_m_series_mask)
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (devpriv->is_m_series)
devpriv->ao_mode3 = AO_Last_Gate_Disable;
else
devpriv->ao_mode3 = 0;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
devpriv->ao_trigger_select = 0;
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
- if (board->reg_type & ni_reg_6xxx_mask) {
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ if (devpriv->is_6xxx) {
unsigned immediate_bits = 0;
unsigned i;
+
for (i = 0; i < s->n_chan; ++i)
immediate_bits |= 1 << i;
- ao_win_out(immediate_bits, AO_Immediate_671x);
- ao_win_out(CLEAR_WG, AO_Misc_611x);
+ ni_ao_win_outw(dev, immediate_bits, AO_Immediate_671x);
+ ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x);
}
- devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
return 0;
}
@@ -3378,7 +3441,7 @@ static int ni_dio_insn_config(struct comedi_device *dev,
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
return insn->n;
}
@@ -3397,11 +3460,10 @@ static int ni_dio_insn_bits(struct comedi_device *dev,
if (comedi_dio_update_state(s, data)) {
devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
- devpriv->stc_writew(dev, devpriv->dio_output,
- DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
}
- data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+ data[1] = ni_stc_readw(dev, DIO_Parallel_Input_Register);
return insn->n;
}
@@ -3411,14 +3473,13 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- ni_writel(s->io_bits, M_Offset_DIO_Direction);
+ ni_writel(dev, s->io_bits, M_Offset_DIO_Direction);
return insn->n;
}
@@ -3428,12 +3489,10 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
-
if (comedi_dio_update_state(s, data))
- ni_writel(s->state, M_Offset_Static_Digital_Output);
+ ni_writel(dev, s->state, M_Offset_Static_Digital_Output);
- data[1] = ni_readl(M_Offset_Static_Digital_Input);
+ data[1] = ni_readl(dev, M_Offset_Static_Digital_Input);
return insn->n;
}
@@ -3508,57 +3567,18 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
return 0;
}
-static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv __maybe_unused = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
- unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
- int retval;
-
- ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
- switch (cmd->scan_begin_src) {
- case TRIG_EXT:
- cdo_mode_bits |=
- CR_CHAN(cmd->scan_begin_arg) &
- CDO_Sample_Source_Select_Mask;
- break;
- default:
- BUG();
- break;
- }
- if (cmd->scan_begin_arg & CR_INVERT)
- cdo_mode_bits |= CDO_Polarity_Bit;
- ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
- if (s->io_bits) {
- ni_writel(s->state, M_Offset_CDO_FIFO_Data);
- ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
- ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
- } else {
- comedi_error(dev,
- "attempted to run digital output command with no lines configured as outputs");
- return -EIO;
- }
- retval = ni_request_cdo_mite_channel(dev);
- if (retval < 0)
- return retval;
-
- s->async->inttrig = ni_cdo_inttrig;
-
- return 0;
-}
-
static int ni_cdo_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int trig_num)
{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ const unsigned timeout = 1000;
+ int retval = 0;
+ unsigned i;
#ifdef PCIDMA
struct ni_private *devpriv = dev->private;
unsigned long flags;
#endif
- struct comedi_cmd *cmd = &s->async->cmd;
- int retval = 0;
- unsigned i;
- const unsigned timeout = 1000;
if (trig_num != cmd->start_arg)
return -EINVAL;
@@ -3574,7 +3594,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev,
mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
mite_dma_arm(devpriv->cdo_mite_chan);
} else {
- comedi_error(dev, "BUG: no cdo mite channel?");
+ dev_err(dev->class_dev, "BUG: no cdo mite channel?\n");
retval = -EIO;
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -3583,53 +3603,88 @@ static int ni_cdo_inttrig(struct comedi_device *dev,
#endif
/*
* XXX not sure what interrupt C group does
-* ni_writeb(Interrupt_Group_C_Enable_Bit,
+* ni_writeb(dev, Interrupt_Group_C_Enable_Bit,
* M_Offset_Interrupt_C_Enable); wait for dma to fill output fifo
*/
for (i = 0; i < timeout; ++i) {
- if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
+ if (ni_readl(dev, M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
break;
udelay(10);
}
if (i == timeout) {
- comedi_error(dev, "dma failed to fill cdo fifo!");
- ni_cdio_cancel(dev, s);
+ dev_err(dev->class_dev, "dma failed to fill cdo fifo!\n");
+ s->cancel(dev, s);
return -EIO;
}
- ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
- CDO_Empty_FIFO_Interrupt_Enable_Set_Bit,
+ ni_writel(dev, CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit,
M_Offset_CDIO_Command);
return retval;
}
-static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
+ int retval;
+
+ ni_writel(dev, CDO_Reset_Bit, M_Offset_CDIO_Command);
+ switch (cmd->scan_begin_src) {
+ case TRIG_EXT:
+ cdo_mode_bits |=
+ CR_CHAN(cmd->scan_begin_arg) &
+ CDO_Sample_Source_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (cmd->scan_begin_arg & CR_INVERT)
+ cdo_mode_bits |= CDO_Polarity_Bit;
+ ni_writel(dev, cdo_mode_bits, M_Offset_CDO_Mode);
+ if (s->io_bits) {
+ ni_writel(dev, s->state, M_Offset_CDO_FIFO_Data);
+ ni_writel(dev, CDO_SW_Update_Bit, M_Offset_CDIO_Command);
+ ni_writel(dev, s->io_bits, M_Offset_CDO_Mask_Enable);
+ } else {
+ dev_err(dev->class_dev,
+ "attempted to run digital output command with no lines configured as outputs\n");
+ return -EIO;
+ }
+ retval = ni_request_cdo_mite_channel(dev);
+ if (retval < 0)
+ return retval;
+
+ s->async->inttrig = ni_cdo_inttrig;
- ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
- CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
- CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
+ return 0;
+}
+
+static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ ni_writel(dev, CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
M_Offset_CDIO_Command);
/*
-* XXX not sure what interrupt C group does ni_writeb(0,
+* XXX not sure what interrupt C group does ni_writeb(dev, 0,
* M_Offset_Interrupt_C_Enable);
*/
- ni_writel(0, M_Offset_CDO_Mask_Enable);
+ ni_writel(dev, 0, M_Offset_CDO_Mask_Enable);
ni_release_cdo_mite_channel(dev);
return 0;
}
static void handle_cdio_interrupt(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv __maybe_unused = dev->private;
+ struct ni_private *devpriv = dev->private;
unsigned cdio_status;
struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
#ifdef PCIDMA
unsigned long flags;
#endif
- if ((board->reg_type & ni_reg_m_series_mask) == 0)
+ if (!devpriv->is_m_series)
return;
#ifdef PCIDMA
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -3646,112 +3701,21 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
#endif
- cdio_status = ni_readl(M_Offset_CDIO_Status);
+ cdio_status = ni_readl(dev, M_Offset_CDIO_Status);
if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
- /* printk("cdio error: statux=0x%x\n", cdio_status); */
- ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); /* XXX just guessing this is needed and does something useful */
+ /* XXX just guessing this is needed and does something useful */
+ ni_writel(dev, CDO_Error_Interrupt_Confirm_Bit,
+ M_Offset_CDIO_Command);
s->async->events |= COMEDI_CB_OVERFLOW;
}
if (cdio_status & CDO_FIFO_Empty_Bit) {
- /* printk("cdio fifo empty\n"); */
- ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
+ ni_writel(dev, CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
M_Offset_CDIO_Command);
/* s->async->events |= COMEDI_CB_EOA; */
}
cfc_handle_events(dev, s);
}
-static int ni_serial_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- int err = insn->n;
- unsigned char byte_out, byte_in = 0;
-
- if (insn->n != 2)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_SERIAL_CLOCK:
- devpriv->serial_hw_mode = 1;
- devpriv->dio_control |= DIO_HW_Serial_Enable;
-
- if (data[1] == SERIAL_DISABLED) {
- devpriv->serial_hw_mode = 0;
- devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
- DIO_Software_Serial_Control);
- data[1] = SERIAL_DISABLED;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_600NS) {
- /* Warning: this clock speed is too fast to reliably
- control SCXI. */
- devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase;
- devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
- data[1] = SERIAL_600NS;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_1_2US) {
- devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase |
- DIO_Serial_Out_Divide_By_2;
- data[1] = SERIAL_1_2US;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_10US) {
- devpriv->dio_control |= DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase |
- DIO_Serial_Out_Divide_By_2;
- /* Note: DIO_Serial_Out_Divide_By_2 only affects
- 600ns/1.2us. If you turn divide_by_2 off with the
- slow clock, you will still get 10us, except then
- all your delays are wrong. */
- data[1] = SERIAL_10US;
- devpriv->serial_interval_ns = data[1];
- } else {
- devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
- DIO_Software_Serial_Control);
- devpriv->serial_hw_mode = 0;
- data[1] = (data[1] / 1000) * 1000;
- devpriv->serial_interval_ns = data[1];
- }
-
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return 1;
-
- break;
-
- case INSN_CONFIG_BIDIRECTIONAL_DATA:
-
- if (devpriv->serial_interval_ns == 0)
- return -EINVAL;
-
- byte_out = data[1] & 0xFF;
-
- if (devpriv->serial_hw_mode) {
- err = ni_serial_hw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else if (devpriv->serial_interval_ns > 0) {
- err = ni_serial_sw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else {
- printk("ni_serial_insn_config: serial disabled!\n");
- return -EINVAL;
- }
- if (err < 0)
- return err;
- data[1] = byte_in & 0xFF;
- return insn->n;
-
- break;
- default:
- return -EINVAL;
- }
-
-}
-
static int ni_serial_hw_readwrite8(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned char data_out,
@@ -3763,28 +3727,27 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
devpriv->dio_output &= ~DIO_Serial_Data_Mask;
devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
- devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
- status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
+ status1 = ni_stc_readw(dev, Joint_Status_1_Register);
if (status1 & DIO_Serial_IO_In_Progress_St) {
err = -EBUSY;
goto Error;
}
devpriv->dio_control |= DIO_HW_Serial_Start;
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
devpriv->dio_control &= ~DIO_HW_Serial_Start;
/* Wait until STC says we're done, but don't loop infinitely. */
- while ((status1 =
- devpriv->stc_readw(dev,
- Joint_Status_1_Register)) &
+ while ((status1 = ni_stc_readw(dev, Joint_Status_1_Register)) &
DIO_Serial_IO_In_Progress_St) {
/* Delay one bit per loop */
udelay((devpriv->serial_interval_ns + 999) / 1000);
if (--count < 0) {
- printk
- ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+ dev_err(dev->class_dev,
+ "%s: SPI serial I/O didn't finish in time!\n",
+ __func__);
err = -ETIME;
goto Error;
}
@@ -3795,10 +3758,10 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
udelay((devpriv->serial_interval_ns + 999) / 1000);
if (data_in != NULL)
- *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
+ *data_in = ni_stc_readw(dev, DIO_Serial_Input_Register);
Error:
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
return err;
}
@@ -3821,29 +3784,23 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
devpriv->dio_output &= ~DIO_SDOUT;
if (data_out & mask)
devpriv->dio_output |= DIO_SDOUT;
- devpriv->stc_writew(dev, devpriv->dio_output,
- DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
/* Assert SDCLK (active low, inverted), wait for half of
the delay, deassert SDCLK, and wait for the other half. */
devpriv->dio_control |= DIO_Software_Serial_Control;
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
udelay((devpriv->serial_interval_ns + 999) / 2000);
devpriv->dio_control &= ~DIO_Software_Serial_Control;
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
udelay((devpriv->serial_interval_ns + 999) / 2000);
/* Input current bit */
- if (devpriv->stc_readw(dev,
- DIO_Parallel_Input_Register) & DIO_SDIN) {
- /* printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
+ if (ni_stc_readw(dev, DIO_Parallel_Input_Register) & DIO_SDIN)
input |= mask;
- }
}
if (data_in)
@@ -3852,14 +3809,96 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
return 0;
}
-static void mio_common_detach(struct comedi_device *dev)
+static int ni_serial_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
+ int err = insn->n;
+ unsigned char byte_out, byte_in = 0;
- if (devpriv) {
- if (devpriv->counter_dev)
- ni_gpct_device_destroy(devpriv->counter_dev);
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SERIAL_CLOCK:
+ devpriv->serial_hw_mode = 1;
+ devpriv->dio_control |= DIO_HW_Serial_Enable;
+
+ if (data[1] == SERIAL_DISABLED) {
+ devpriv->serial_hw_mode = 0;
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ data[1] = SERIAL_DISABLED;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_600NS) {
+ /* Warning: this clock speed is too fast to reliably
+ control SCXI. */
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase;
+ devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_600NS;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_1_2US) {
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_1_2US;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_10US) {
+ devpriv->dio_control |= DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ /* Note: DIO_Serial_Out_Divide_By_2 only affects
+ 600ns/1.2us. If you turn divide_by_2 off with the
+ slow clock, you will still get 10us, except then
+ all your delays are wrong. */
+ data[1] = SERIAL_10US;
+ devpriv->serial_interval_ns = data[1];
+ } else {
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ devpriv->serial_hw_mode = 0;
+ data[1] = (data[1] / 1000) * 1000;
+ devpriv->serial_interval_ns = data[1];
+ }
+
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 1;
+
+ break;
+
+ case INSN_CONFIG_BIDIRECTIONAL_DATA:
+
+ if (devpriv->serial_interval_ns == 0)
+ return -EINVAL;
+
+ byte_out = data[1] & 0xFF;
+
+ if (devpriv->serial_hw_mode) {
+ err = ni_serial_hw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else if (devpriv->serial_interval_ns > 0) {
+ err = ni_serial_sw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else {
+ dev_err(dev->class_dev, "%s: serial disabled!\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (err < 0)
+ return err;
+ data[1] = byte_in & 0xFF;
+ return insn->n;
+
+ break;
+ default:
+ return -EINVAL;
}
+
}
static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -3870,12 +3909,13 @@ static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
AO_Configuration_2_67xx);
}
- ao_win_out(0x0, AO_Later_Single_Point_Updates);
+ ni_ao_win_outw(dev, 0x0, AO_Later_Single_Point_Updates);
}
static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
{
unsigned stc_register;
+
switch (reg) {
case NITIO_G0_AUTO_INC:
stc_register = G_Autoincrement_Register(0);
@@ -3960,7 +4000,6 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
__func__, reg);
BUG();
return 0;
- break;
}
return stc_register;
}
@@ -3969,7 +4008,6 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
- struct ni_private *devpriv = dev->private;
unsigned stc_register;
/* bits in the join reset register which are relevant to counters */
static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
@@ -3981,28 +4019,28 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
switch (reg) {
/* m-series-only registers */
case NITIO_G0_CNT_MODE:
- ni_writew(bits, M_Offset_G0_Counting_Mode);
+ ni_writew(dev, bits, M_Offset_G0_Counting_Mode);
break;
case NITIO_G1_CNT_MODE:
- ni_writew(bits, M_Offset_G1_Counting_Mode);
+ ni_writew(dev, bits, M_Offset_G1_Counting_Mode);
break;
case NITIO_G0_GATE2:
- ni_writew(bits, M_Offset_G0_Second_Gate);
+ ni_writew(dev, bits, M_Offset_G0_Second_Gate);
break;
case NITIO_G1_GATE2:
- ni_writew(bits, M_Offset_G1_Second_Gate);
+ ni_writew(dev, bits, M_Offset_G1_Second_Gate);
break;
case NITIO_G0_DMA_CFG:
- ni_writew(bits, M_Offset_G0_DMA_Config);
+ ni_writew(dev, bits, M_Offset_G0_DMA_Config);
break;
case NITIO_G1_DMA_CFG:
- ni_writew(bits, M_Offset_G1_DMA_Config);
+ ni_writew(dev, bits, M_Offset_G1_DMA_Config);
break;
case NITIO_G0_ABZ:
- ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+ ni_writew(dev, bits, M_Offset_G0_MSeries_ABZ);
break;
case NITIO_G1_ABZ:
- ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+ ni_writew(dev, bits, M_Offset_G1_MSeries_ABZ);
break;
/* 32 bit registers */
@@ -4011,7 +4049,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
case NITIO_G0_LOADB:
case NITIO_G1_LOADB:
stc_register = ni_gpct_to_stc_register(reg);
- devpriv->stc_writel(dev, bits, stc_register);
+ ni_stc_writel(dev, bits, stc_register);
break;
/* 16 bit registers */
@@ -4030,7 +4068,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
/* fall-through */
default:
stc_register = ni_gpct_to_stc_register(reg);
- devpriv->stc_writew(dev, bits, stc_register);
+ ni_stc_writew(dev, bits, stc_register);
}
}
@@ -4038,15 +4076,14 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
- struct ni_private *devpriv = dev->private;
unsigned stc_register;
switch (reg) {
/* m-series only registers */
case NITIO_G0_DMA_STATUS:
- return ni_readw(M_Offset_G0_DMA_Status);
+ return ni_readw(dev, M_Offset_G0_DMA_Status);
case NITIO_G1_DMA_STATUS:
- return ni_readw(M_Offset_G1_DMA_Status);
+ return ni_readw(dev, M_Offset_G1_DMA_Status);
/* 32 bit registers */
case NITIO_G0_HW_SAVE:
@@ -4054,506 +4091,101 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
case NITIO_G0_SW_SAVE:
case NITIO_G1_SW_SAVE:
stc_register = ni_gpct_to_stc_register(reg);
- return devpriv->stc_readl(dev, stc_register);
+ return ni_stc_readl(dev, stc_register);
/* 16 bit registers */
default:
stc_register = ni_gpct_to_stc_register(reg);
- return devpriv->stc_readw(dev, stc_register);
- break;
+ return ni_stc_readw(dev, stc_register);
}
return 0;
}
static int ni_freq_out_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
+ unsigned int val = devpriv->clock_and_fout & FOUT_Divider_mask;
+ int i;
- data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
- return 1;
+ for (i = 0; i < insn->n; i++)
+ data[i] = val;
+
+ return insn->n;
}
static int ni_freq_out_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
- devpriv->clock_and_fout &= ~FOUT_Enable;
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- devpriv->clock_and_fout &= ~FOUT_Divider_mask;
- devpriv->clock_and_fout |= FOUT_Divider(data[0]);
- devpriv->clock_and_fout |= FOUT_Enable;
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return insn->n;
-}
+ if (insn->n) {
+ devpriv->clock_and_fout &= ~FOUT_Enable;
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ devpriv->clock_and_fout &= ~FOUT_Divider_mask;
-static int ni_set_freq_out_clock(struct comedi_device *dev,
- unsigned int clock_source)
-{
- struct ni_private *devpriv = dev->private;
+ /* use the last data value to set the fout divider */
+ devpriv->clock_and_fout |= FOUT_Divider(data[insn->n - 1]);
- switch (clock_source) {
- case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
- devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
- break;
- case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
- devpriv->clock_and_fout |= FOUT_Timebase_Select;
- break;
- default:
- return -EINVAL;
- }
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return 3;
-}
-
-static void ni_get_freq_out_clock(struct comedi_device *dev,
- unsigned int *clock_source,
- unsigned int *clock_period_ns)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
- *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
- *clock_period_ns = TIMEBASE_2_NS;
- } else {
- *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
- *clock_period_ns = TIMEBASE_1_NS * 2;
+ devpriv->clock_and_fout |= FOUT_Enable;
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
}
+ return insn->n;
}
static int ni_freq_out_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct ni_private *devpriv = dev->private;
+
switch (data[0]) {
case INSN_CONFIG_SET_CLOCK_SRC:
- return ni_set_freq_out_clock(dev, data[1]);
+ switch (data[1]) {
+ case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
+ devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
+ break;
+ case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
+ devpriv->clock_and_fout |= FOUT_Timebase_Select;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
break;
case INSN_CONFIG_GET_CLOCK_SRC:
- ni_get_freq_out_clock(dev, &data[1], &data[2]);
- return 3;
- default:
+ if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
+ data[1] = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
+ data[2] = TIMEBASE_2_NS;
+ } else {
+ data[1] = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
+ data[2] = TIMEBASE_1_NS * 2;
+ }
break;
- }
- return -EINVAL;
-}
-
-static int ni_alloc_private(struct comedi_device *dev)
-{
- struct ni_private *devpriv;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->window_lock);
- spin_lock_init(&devpriv->soft_reg_copy_lock);
- spin_lock_init(&devpriv->mite_channel_lock);
-
- return 0;
-};
-
-static int ni_E_init(struct comedi_device *dev)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- unsigned j;
- enum ni_gpct_variant counter_variant;
- int ret;
-
- if (board->n_aochan > MAX_N_AO_CHAN) {
- printk("bug! n_aochan > MAX_N_AO_CHAN\n");
+ default:
return -EINVAL;
}
-
- ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
- if (ret)
- return ret;
-
- /* analog input subdevice */
-
- s = &dev->subdevices[NI_AI_SUBDEV];
- dev->read_subdev = s;
- if (board->n_adchan) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags =
- SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
- if (board->reg_type != ni_reg_611x)
- s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
- if (board->adbits > 16)
- s->subdev_flags |= SDF_LSAMPL;
- if (board->reg_type & ni_reg_m_series_mask)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = board->n_adchan;
- s->len_chanlist = 512;
- s->maxdata = (1 << board->adbits) - 1;
- s->range_table = ni_range_lkup[board->gainlkup];
- s->insn_read = &ni_ai_insn_read;
- s->insn_config = &ni_ai_insn_config;
- s->do_cmdtest = &ni_ai_cmdtest;
- s->do_cmd = &ni_ai_cmd;
- s->cancel = &ni_ai_reset;
- s->poll = &ni_ai_poll;
- s->munge = &ni_ai_munge;
-#ifdef PCIDMA
- s->async_dma_dir = DMA_FROM_DEVICE;
-#endif
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* analog output subdevice */
-
- s = &dev->subdevices[NI_AO_SUBDEV];
- if (board->n_aochan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
- if (board->reg_type & ni_reg_m_series_mask)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = board->n_aochan;
- s->maxdata = (1 << board->aobits) - 1;
- s->range_table = board->ao_range_table;
- s->insn_read = &ni_ao_insn_read;
- if (board->reg_type & ni_reg_6xxx_mask)
- s->insn_write = &ni_ao_insn_write_671x;
- else
- s->insn_write = &ni_ao_insn_write;
- s->insn_config = &ni_ao_insn_config;
-#ifdef PCIDMA
- if (board->n_aochan) {
- s->async_dma_dir = DMA_TO_DEVICE;
-#else
- if (board->ao_fifo_depth) {
-#endif
- dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->do_cmd = &ni_ao_cmd;
- s->do_cmdtest = &ni_ao_cmdtest;
- s->len_chanlist = board->n_aochan;
- if ((board->reg_type & ni_reg_m_series_mask) == 0)
- s->munge = ni_ao_munge;
- }
- s->cancel = &ni_ao_reset;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- if ((board->reg_type & ni_reg_67xx_mask))
- init_ao_67xx(dev, s);
-
- /* digital i/o subdevice */
-
- s = &dev->subdevices[NI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->maxdata = 1;
- s->io_bits = 0; /* all bits input */
- s->range_table = &range_digital;
- s->n_chan = board->num_p0_dio_channels;
- if (board->reg_type & ni_reg_m_series_mask) {
- s->subdev_flags |=
- SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */;
- s->insn_bits = &ni_m_series_dio_insn_bits;
- s->insn_config = &ni_m_series_dio_insn_config;
- s->do_cmd = &ni_cdio_cmd;
- s->do_cmdtest = &ni_cdio_cmdtest;
- s->cancel = &ni_cdio_cancel;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- s->len_chanlist = s->n_chan;
-
- ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
- ni_writel(s->io_bits, M_Offset_DIO_Direction);
- } else {
- s->insn_bits = &ni_dio_insn_bits;
- s->insn_config = &ni_dio_insn_config;
- devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
- ni_writew(devpriv->dio_control, DIO_Control_Register);
- }
-
- /* 8255 device */
- s = &dev->subdevices[NI_8255_DIO_SUBDEV];
- if (board->has_8255) {
- ret = subdev_8255_init(dev, s, ni_8255_callback,
- (unsigned long)dev);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* formerly general purpose counter/timer device, but no longer used */
- s = &dev->subdevices[NI_UNUSED_SUBDEV];
- s->type = COMEDI_SUBD_UNUSED;
-
- /* calibration subdevice -- ai and ao */
- s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
- s->type = COMEDI_SUBD_CALIB;
- if (board->reg_type & ni_reg_m_series_mask) {
- /* internal PWM analog output used for AI nonlinearity calibration */
- s->subdev_flags = SDF_INTERNAL;
- s->insn_config = &ni_m_series_pwm_config;
- s->n_chan = 1;
- s->maxdata = 0;
- ni_writel(0x0, M_Offset_Cal_PWM);
- } else if (board->reg_type == ni_reg_6143) {
- /* internal PWM analog output used for AI nonlinearity calibration */
- s->subdev_flags = SDF_INTERNAL;
- s->insn_config = &ni_6143_pwm_config;
- s->n_chan = 1;
- s->maxdata = 0;
- } else {
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- s->insn_read = &ni_calib_insn_read;
- s->insn_write = &ni_calib_insn_write;
- caldac_setup(dev, s);
- }
-
- /* EEPROM */
- s = &dev->subdevices[NI_EEPROM_SUBDEV];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->maxdata = 0xff;
- if (board->reg_type & ni_reg_m_series_mask) {
- s->n_chan = M_SERIES_EEPROM_SIZE;
- s->insn_read = &ni_m_series_eeprom_insn_read;
- } else {
- s->n_chan = 512;
- s->insn_read = &ni_eeprom_insn_read;
- }
-
- /* PFI */
- s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- if (board->reg_type & ni_reg_m_series_mask) {
- unsigned i;
- s->n_chan = 16;
- ni_writew(s->state, M_Offset_PFI_DO);
- for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
- ni_writew(devpriv->pfi_output_select_reg[i],
- M_Offset_PFI_Output_Select(i + 1));
- }
- } else {
- s->n_chan = 10;
- }
- s->maxdata = 1;
- if (board->reg_type & ni_reg_m_series_mask)
- s->insn_bits = &ni_pfi_insn_bits;
- s->insn_config = &ni_pfi_insn_config;
- ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
-
- /* cs5529 calibration adc */
- s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
- if (board->reg_type & ni_reg_67xx_mask) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
- /* one channel for each analog output channel */
- s->n_chan = board->n_aochan;
- s->maxdata = (1 << 16) - 1;
- s->range_table = &range_unknown; /* XXX */
- s->insn_read = cs5529_ai_insn_read;
- s->insn_config = NULL;
- init_cs5529(dev);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Serial */
- s = &dev->subdevices[NI_SERIAL_SUBDEV];
- s->type = COMEDI_SUBD_SERIAL;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 1;
- s->maxdata = 0xff;
- s->insn_config = ni_serial_insn_config;
- devpriv->serial_interval_ns = 0;
- devpriv->serial_hw_mode = 0;
-
- /* RTSI */
- s = &dev->subdevices[NI_RTSI_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- s->maxdata = 1;
- s->insn_bits = ni_rtsi_insn_bits;
- s->insn_config = ni_rtsi_insn_config;
- ni_rtsi_init(dev);
-
- if (board->reg_type & ni_reg_m_series_mask)
- counter_variant = ni_gpct_variant_m_series;
- else
- counter_variant = ni_gpct_variant_e_series;
- devpriv->counter_dev = ni_gpct_device_construct(dev,
- &ni_gpct_write_register,
- &ni_gpct_read_register,
- counter_variant,
- NUM_GPCT);
- if (!devpriv->counter_dev)
- return -ENOMEM;
-
- /* General purpose counters */
- for (j = 0; j < NUM_GPCT; ++j) {
- s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
- s->n_chan = 3;
- if (board->reg_type & ni_reg_m_series_mask)
- s->maxdata = 0xffffffff;
- else
- s->maxdata = 0xffffff;
- s->insn_read = ni_tio_insn_read;
- s->insn_write = ni_tio_insn_read;
- s->insn_config = ni_tio_insn_config;
-#ifdef PCIDMA
- s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
- s->do_cmd = &ni_gpct_cmd;
- s->len_chanlist = 1;
- s->do_cmdtest = ni_tio_cmdtest;
- s->cancel = &ni_gpct_cancel;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
-#endif
- s->private = &devpriv->counter_dev->counters[j];
-
- devpriv->counter_dev->counters[j].chip_index = 0;
- devpriv->counter_dev->counters[j].counter_index = j;
- ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
- }
-
- /* Frequency output */
- s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0xf;
- s->insn_read = &ni_freq_out_insn_read;
- s->insn_write = &ni_freq_out_insn_write;
- s->insn_config = &ni_freq_out_insn_config;
-
- /* ai configuration */
- s = &dev->subdevices[NI_AI_SUBDEV];
- ni_ai_reset(dev, s);
- if ((board->reg_type & ni_reg_6xxx_mask) == 0) {
- /* BEAM is this needed for PCI-6143 ?? */
- devpriv->clock_and_fout =
- Slow_Internal_Time_Divide_By_2 |
- Slow_Internal_Timebase |
- Clock_To_Board_Divide_By_2 |
- Clock_To_Board |
- AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
- } else {
- devpriv->clock_and_fout =
- Slow_Internal_Time_Divide_By_2 |
- Slow_Internal_Timebase |
- Clock_To_Board_Divide_By_2 | Clock_To_Board;
- }
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
-
- /* analog output configuration */
- s = &dev->subdevices[NI_AO_SUBDEV];
- ni_ao_reset(dev, s);
-
- if (dev->irq) {
- devpriv->stc_writew(dev,
- (IRQ_POLARITY ? Interrupt_Output_Polarity :
- 0) | (Interrupt_Output_On_3_Pins & 0) |
- Interrupt_A_Enable | Interrupt_B_Enable |
- Interrupt_A_Output_Select(interrupt_pin
- (dev->irq)) |
- Interrupt_B_Output_Select(interrupt_pin
- (dev->irq)),
- Interrupt_Control_Register);
- }
-
- /* DMA setup */
- ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
- ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
-
- if (board->reg_type & ni_reg_6xxx_mask) {
- ni_writeb(0, Magic_611x);
- } else if (board->reg_type & ni_reg_m_series_mask) {
- int channel;
- for (channel = 0; channel < board->n_aochan; ++channel) {
- ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
- ni_writeb(0x0,
- M_Offset_AO_Reference_Attenuation(channel));
- }
- ni_writeb(0x0, M_Offset_AO_Calibration);
- }
-
- return 0;
+ return insn->n;
}
static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
{
struct comedi_device *dev = (struct comedi_device *)arg;
- struct ni_private *devpriv __maybe_unused = dev->private;
if (dir) {
- ni_writeb(data, Port_A + 2 * port);
+ ni_writeb(dev, data, Port_A + 2 * port);
return 0;
- } else {
- return ni_readb(Port_A + 2 * port);
}
-}
-/*
- presents the EEPROM as a subdevice
-*/
-
-static int ni_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
-
- return 1;
-}
-
-/*
- reads bytes out of eeprom
-*/
-
-static int ni_read_eeprom(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv __maybe_unused = dev->private;
- int bit;
- int bitstring;
-
- bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
- ni_writeb(0x04, Serial_Command);
- for (bit = 0x8000; bit; bit >>= 1) {
- ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
- Serial_Command);
- ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
- Serial_Command);
- }
- bitstring = 0;
- for (bit = 0x80; bit; bit >>= 1) {
- ni_writeb(0x04, Serial_Command);
- ni_writeb(0x05, Serial_Command);
- bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
- }
- ni_writeb(0x00, Serial_Command);
-
- return bitstring;
-}
-
-static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
-
- return 1;
+ return ni_readb(dev, Port_A + 2 * port);
}
static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
@@ -4567,7 +4199,8 @@ static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
static int ni_m_series_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
@@ -4590,7 +4223,6 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
switch (data[3]) {
case TRIG_ROUND_NEAREST:
@@ -4608,7 +4240,6 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
if (up_count * devpriv->clock_ns != data[2] ||
down_count * devpriv->clock_ns != data[4]) {
@@ -4616,26 +4247,24 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
data[4] = down_count * devpriv->clock_ns;
return -EAGAIN;
}
- ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
- MSeries_Cal_PWM_Low_Time_Bits(down_count),
+ ni_writel(dev, MSeries_Cal_PWM_High_Time_Bits(up_count) |
+ MSeries_Cal_PWM_Low_Time_Bits(down_count),
M_Offset_Cal_PWM);
devpriv->pwm_up_count = up_count;
devpriv->pwm_down_count = down_count;
return 5;
- break;
case INSN_CONFIG_GET_PWM_OUTPUT:
return ni_get_pwm_config(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return 0;
}
static int ni_6143_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
@@ -4658,7 +4287,6 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
switch (data[3]) {
case TRIG_ROUND_NEAREST:
@@ -4676,7 +4304,6 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
if (up_count * devpriv->clock_ns != data[2] ||
down_count * devpriv->clock_ns != data[4]) {
@@ -4684,51 +4311,66 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
data[4] = down_count * devpriv->clock_ns;
return -EAGAIN;
}
- ni_writel(up_count, Calibration_HighTime_6143);
+ ni_writel(dev, up_count, Calibration_HighTime_6143);
devpriv->pwm_up_count = up_count;
- ni_writel(down_count, Calibration_LowTime_6143);
+ ni_writel(dev, down_count, Calibration_LowTime_6143);
devpriv->pwm_down_count = down_count;
return 5;
- break;
case INSN_CONFIG_GET_PWM_OUTPUT:
return ni_get_pwm_config(dev, data);
default:
return -EINVAL;
- break;
}
return 0;
}
-static void ni_write_caldac(struct comedi_device *dev, int addr, int val);
-/*
- calibration subdevice
-*/
-static int ni_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int pack_mb88341(int addr, int val, int *bitstring)
{
- ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+ /*
+ Fujitsu MB 88341
+ Note that address bits are reversed. Thanks to
+ Ingo Keen for noticing this.
- return 1;
+ Note also that the 88341 expects address values from
+ 1-12, whereas we use channel numbers 0-11. The NI
+ docs use 1-12, also, so be careful here.
+ */
+ addr++;
+ *bitstring = ((addr & 0x1) << 11) |
+ ((addr & 0x2) << 9) |
+ ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+ return 12;
}
-static int ni_calib_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int pack_dac8800(int addr, int val, int *bitstring)
{
- struct ni_private *devpriv = dev->private;
+ *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
+ return 11;
+}
- data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+static int pack_dac8043(int addr, int val, int *bitstring)
+{
+ *bitstring = val & 0xfff;
+ return 12;
+}
- return 1;
+static int pack_ad8522(int addr, int val, int *bitstring)
+{
+ *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
+ return 16;
}
-static int pack_mb88341(int addr, int val, int *bitstring);
-static int pack_dac8800(int addr, int val, int *bitstring);
-static int pack_dac8043(int addr, int val, int *bitstring);
-static int pack_ad8522(int addr, int val, int *bitstring);
-static int pack_ad8804(int addr, int val, int *bitstring);
-static int pack_ad8842(int addr, int val, int *bitstring);
+static int pack_ad8804(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
+ return 12;
+}
+
+static int pack_ad8842(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr + 1) << 8) | (val & 0xff);
+ return 12;
+}
struct caldac_struct {
int n_chans;
@@ -4746,6 +4388,64 @@ static struct caldac_struct caldacs[] = {
[ad8804_debug] = {16, 8, pack_ad8804},
};
+static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
+{
+ const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
+ unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
+ int i;
+ int type;
+
+ if (devpriv->caldacs[addr] == val)
+ return;
+ devpriv->caldacs[addr] = val;
+
+ for (i = 0; i < 3; i++) {
+ type = board->caldac[i];
+ if (type == caldac_none)
+ break;
+ if (addr < caldacs[type].n_chans) {
+ bits = caldacs[type].packbits(addr, val, &bitstring);
+ loadbit = SerDacLd(i);
+ break;
+ }
+ addr -= caldacs[type].n_chans;
+ }
+
+ for (bit = 1 << (bits - 1); bit; bit >>= 1) {
+ ni_writeb(dev, ((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ udelay(1);
+ ni_writeb(dev, 1 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ udelay(1);
+ }
+ ni_writeb(dev, loadbit, Serial_Command);
+ udelay(1);
+ ni_writeb(dev, 0, Serial_Command);
+}
+
+static int ni_calib_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+
+ return 1;
+}
+
+static int ni_calib_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct ni_private *devpriv = dev->private;
+
+ data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct ni_board_struct *board = comedi_board(dev);
@@ -4777,7 +4477,8 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned int *maxdata_list;
if (n_chans > MAX_N_CALDACS)
- printk("BUG! MAX_N_CALDACS too small\n");
+ dev_err(dev->class_dev,
+ "BUG! MAX_N_CALDACS too small\n");
s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
chan = 0;
for (i = 0; i < n_dacs; i++) {
@@ -4800,221 +4501,106 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
}
}
-static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
+static int ni_read_eeprom(struct comedi_device *dev, int addr)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv = dev->private;
- unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
- int i;
- int type;
-
- /* printk("ni_write_caldac: chan=%d val=%d\n",addr,val); */
- if (devpriv->caldacs[addr] == val)
- return;
- devpriv->caldacs[addr] = val;
+ int bit;
+ int bitstring;
- for (i = 0; i < 3; i++) {
- type = board->caldac[i];
- if (type == caldac_none)
- break;
- if (addr < caldacs[type].n_chans) {
- bits = caldacs[type].packbits(addr, val, &bitstring);
- loadbit = SerDacLd(i);
- /* printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring); */
- break;
- }
- addr -= caldacs[type].n_chans;
+ bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
+ ni_writeb(dev, 0x04, Serial_Command);
+ for (bit = 0x8000; bit; bit >>= 1) {
+ ni_writeb(dev, 0x04 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ ni_writeb(dev, 0x05 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
}
-
- for (bit = 1 << (bits - 1); bit; bit >>= 1) {
- ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
- udelay(1);
- ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
- udelay(1);
+ bitstring = 0;
+ for (bit = 0x80; bit; bit >>= 1) {
+ ni_writeb(dev, 0x04, Serial_Command);
+ ni_writeb(dev, 0x05, Serial_Command);
+ bitstring |= ((ni_readb(dev, XXX_Status) & PROMOUT) ? bit : 0);
}
- ni_writeb(loadbit, Serial_Command);
- udelay(1);
- ni_writeb(0, Serial_Command);
-}
-
-static int pack_mb88341(int addr, int val, int *bitstring)
-{
- /*
- Fujitsu MB 88341
- Note that address bits are reversed. Thanks to
- Ingo Keen for noticing this.
-
- Note also that the 88341 expects address values from
- 1-12, whereas we use channel numbers 0-11. The NI
- docs use 1-12, also, so be careful here.
- */
- addr++;
- *bitstring = ((addr & 0x1) << 11) |
- ((addr & 0x2) << 9) |
- ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
- return 12;
-}
-
-static int pack_dac8800(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
- return 11;
-}
-
-static int pack_dac8043(int addr, int val, int *bitstring)
-{
- *bitstring = val & 0xfff;
- return 12;
-}
+ ni_writeb(dev, 0x00, Serial_Command);
-static int pack_ad8522(int addr, int val, int *bitstring)
-{
- *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
- return 16;
+ return bitstring;
}
-static int pack_ad8804(int addr, int val, int *bitstring)
+static int ni_eeprom_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
- return 12;
-}
+ data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
-static int pack_ad8842(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr + 1) << 8) | (val & 0xff);
- return 12;
+ return 1;
}
-#if 0
-/*
- * Read the GPCTs current value.
- */
-static int GPCT_G_Watch(struct comedi_device *dev, int chan)
+static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int hi1, hi2, lo;
-
- devpriv->gpct_command[chan] &= ~G_Save_Trace;
- devpriv->stc_writew(dev, devpriv->gpct_command[chan],
- G_Command_Register(chan));
-
- devpriv->gpct_command[chan] |= G_Save_Trace;
- devpriv->stc_writew(dev, devpriv->gpct_command[chan],
- G_Command_Register(chan));
+ struct ni_private *devpriv = dev->private;
- /* This procedure is used because the two registers cannot
- * be read atomically. */
- do {
- hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
- lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
- hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
- } while (hi1 != hi2);
+ data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
- return (hi1 << 16) | lo;
+ return 1;
}
-static void GPCT_Reset(struct comedi_device *dev, int chan)
+static unsigned ni_old_get_pfi_routing(struct comedi_device *dev,
+ unsigned chan)
{
- int temp_ack_reg = 0;
-
- /* printk("GPCT_Reset..."); */
- devpriv->gpct_cur_operation[chan] = GPCT_RESET;
-
+ /* pre-m-series boards have fixed signals on pfi pins */
switch (chan) {
case 0:
- devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
- ni_set_bits(dev, Interrupt_A_Enable_Register,
- G0_TC_Interrupt_Enable, 0);
- ni_set_bits(dev, Interrupt_A_Enable_Register,
- G0_Gate_Interrupt_Enable, 0);
- temp_ack_reg |= G0_Gate_Error_Confirm;
- temp_ack_reg |= G0_TC_Error_Confirm;
- temp_ack_reg |= G0_TC_Interrupt_Ack;
- temp_ack_reg |= G0_Gate_Interrupt_Ack;
- devpriv->stc_writew(dev, temp_ack_reg,
- Interrupt_A_Ack_Register);
-
- /* problem...this interferes with the other ctr... */
- devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
- break;
+ return NI_PFI_OUTPUT_AI_START1;
case 1:
- devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- G1_TC_Interrupt_Enable, 0);
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- G0_Gate_Interrupt_Enable, 0);
- temp_ack_reg |= G1_Gate_Error_Confirm;
- temp_ack_reg |= G1_TC_Error_Confirm;
- temp_ack_reg |= G1_TC_Interrupt_Ack;
- temp_ack_reg |= G1_Gate_Interrupt_Ack;
- devpriv->stc_writew(dev, temp_ack_reg,
- Interrupt_B_Ack_Register);
-
- devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
+ return NI_PFI_OUTPUT_AI_START2;
+ case 2:
+ return NI_PFI_OUTPUT_AI_CONVERT;
+ case 3:
+ return NI_PFI_OUTPUT_G_SRC1;
+ case 4:
+ return NI_PFI_OUTPUT_G_GATE1;
+ case 5:
+ return NI_PFI_OUTPUT_AO_UPDATE_N;
+ case 6:
+ return NI_PFI_OUTPUT_AO_START1;
+ case 7:
+ return NI_PFI_OUTPUT_AI_START_PULSE;
+ case 8:
+ return NI_PFI_OUTPUT_G_SRC0;
+ case 9:
+ return NI_PFI_OUTPUT_G_GATE0;
+ default:
+ dev_err(dev->class_dev,
+ "%s: bug, unhandled case in switch.\n", __func__);
break;
}
-
- devpriv->gpct_mode[chan] = 0;
- devpriv->gpct_input_select[chan] = 0;
- devpriv->gpct_command[chan] = 0;
-
- devpriv->gpct_command[chan] |= G_Synchronized_Gate;
-
- devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
- G_Mode_Register(chan));
- devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
- G_Input_Select_Register(chan));
- devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
-
- /* printk("exit GPCT_Reset\n"); */
+ return 0;
}
-#endif
-
-#ifdef PCIDMA
-static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int ni_old_set_pfi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
- COMEDI_INPUT);
- if (retval) {
- comedi_error(dev,
- "no dma channel available for use by counter");
- return retval;
- }
- ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
-
- return ni_tio_cmd(dev, s);
+ /* pre-m-series boards have fixed signals on pfi pins */
+ if (source != ni_old_get_pfi_routing(dev, chan))
+ return -EINVAL;
+ return 2;
}
-#endif
-#ifdef PCIDMA
-static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
+ unsigned chan)
{
- struct ni_gpct *counter = s->private;
- int retval;
+ struct ni_private *devpriv = dev->private;
+ const unsigned array_offset = chan / 3;
- retval = ni_tio_cancel(counter);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
- ni_release_gpct_mite_channel(dev, counter->counter_index);
- return retval;
+ return MSeries_PFI_Output_Select_Source(chan,
+ devpriv->pfi_output_select_reg[array_offset]);
}
-#endif
-
-/*
- *
- * Programmable Function Inputs
- *
- */
-static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static int ni_m_series_set_pfi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
struct ni_private *devpriv = dev->private;
unsigned pfi_reg_index;
@@ -5028,132 +4614,51 @@ static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
~MSeries_PFI_Output_Select_Mask(chan);
devpriv->pfi_output_select_reg[array_offset] |=
MSeries_PFI_Output_Select_Bits(chan, source);
- ni_writew(devpriv->pfi_output_select_reg[array_offset],
+ ni_writew(dev, devpriv->pfi_output_select_reg[array_offset],
M_Offset_PFI_Output_Select(pfi_reg_index));
return 2;
}
-static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
{
- /* pre-m-series boards have fixed signals on pfi pins */
- if (source != ni_old_get_pfi_routing(dev, chan))
- return -EINVAL;
- return 2;
+ struct ni_private *devpriv = dev->private;
+
+ return (devpriv->is_m_series)
+ ? ni_m_series_get_pfi_routing(dev, chan)
+ : ni_old_get_pfi_routing(dev, chan);
}
static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
- const struct ni_board_struct *board = comedi_board(dev);
-
- if (board->reg_type & ni_reg_m_series_mask)
- return ni_m_series_set_pfi_routing(dev, chan, source);
- else
- return ni_old_set_pfi_routing(dev, chan, source);
-}
-
-static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
- unsigned chan)
-{
struct ni_private *devpriv = dev->private;
- const unsigned array_offset = chan / 3;
-
- return MSeries_PFI_Output_Select_Source(chan,
- devpriv->
- pfi_output_select_reg
- [array_offset]);
-}
-
-static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan)
-{
- /* pre-m-series boards have fixed signals on pfi pins */
- switch (chan) {
- case 0:
- return NI_PFI_OUTPUT_AI_START1;
- break;
- case 1:
- return NI_PFI_OUTPUT_AI_START2;
- break;
- case 2:
- return NI_PFI_OUTPUT_AI_CONVERT;
- break;
- case 3:
- return NI_PFI_OUTPUT_G_SRC1;
- break;
- case 4:
- return NI_PFI_OUTPUT_G_GATE1;
- break;
- case 5:
- return NI_PFI_OUTPUT_AO_UPDATE_N;
- break;
- case 6:
- return NI_PFI_OUTPUT_AO_START1;
- break;
- case 7:
- return NI_PFI_OUTPUT_AI_START_PULSE;
- break;
- case 8:
- return NI_PFI_OUTPUT_G_SRC0;
- break;
- case 9:
- return NI_PFI_OUTPUT_G_GATE0;
- break;
- default:
- printk("%s: bug, unhandled case in switch.\n", __func__);
- break;
- }
- return 0;
-}
-
-static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- if (board->reg_type & ni_reg_m_series_mask)
- return ni_m_series_get_pfi_routing(dev, chan);
- else
- return ni_old_get_pfi_routing(dev, chan);
+ return (devpriv->is_m_series)
+ ? ni_m_series_set_pfi_routing(dev, chan, source)
+ : ni_old_set_pfi_routing(dev, chan, source);
}
-static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
+static int ni_config_filter(struct comedi_device *dev,
+ unsigned pfi_channel,
enum ni_pfi_filter_select filter)
{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv __maybe_unused = dev->private;
+ struct ni_private *devpriv = dev->private;
unsigned bits;
- if ((board->reg_type & ni_reg_m_series_mask) == 0)
+ if (!devpriv->is_m_series)
return -ENOTSUPP;
- bits = ni_readl(M_Offset_PFI_Filter);
+
+ bits = ni_readl(dev, M_Offset_PFI_Filter);
bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
- ni_writel(bits, M_Offset_PFI_Filter);
+ ni_writel(dev, bits, M_Offset_PFI_Filter);
return 0;
}
-static int ni_pfi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- const struct ni_board_struct *board = comedi_board(dev);
- struct ni_private *devpriv __maybe_unused = dev->private;
-
- if (!(board->reg_type & ni_reg_m_series_mask))
- return -ENOTSUPP;
-
- if (comedi_dio_update_state(s, data))
- ni_writew(s->state, M_Offset_PFI_DO);
-
- data[1] = ni_readw(M_Offset_PFI_DI);
-
- return insn->n;
-}
-
static int ni_pfi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned int chan;
@@ -5175,78 +4680,178 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
(devpriv->io_bidirection_pin_reg & (1 << chan)) ?
COMEDI_OUTPUT : COMEDI_INPUT;
return 0;
- break;
case INSN_CONFIG_SET_ROUTING:
return ni_set_pfi_routing(dev, chan, data[1]);
- break;
case INSN_CONFIG_GET_ROUTING:
data[1] = ni_get_pfi_routing(dev, chan);
break;
case INSN_CONFIG_FILTER:
return ni_config_filter(dev, chan, data[1]);
- break;
default:
return -EINVAL;
}
return 0;
}
-/*
- *
- * NI RTSI Bus Functions
- *
- */
-static void ni_rtsi_init(struct comedi_device *dev)
+static int ni_pfi_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- /* Initialises the RTSI bus signal switch to a default state */
+ if (!devpriv->is_m_series)
+ return -ENOTSUPP;
- /* Set clock mode to internal */
- devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
- if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
- printk("ni_set_master_clock failed, bug?");
- /* default internal lines routing to RTSI bus lines */
- devpriv->rtsi_trig_a_output_reg =
- RTSI_Trig_Output_Bits(0,
- NI_RTSI_OUTPUT_ADR_START1) |
- RTSI_Trig_Output_Bits(1,
- NI_RTSI_OUTPUT_ADR_START2) |
- RTSI_Trig_Output_Bits(2,
- NI_RTSI_OUTPUT_SCLKG) |
- RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
- RTSI_Trig_A_Output_Register);
- devpriv->rtsi_trig_b_output_reg =
- RTSI_Trig_Output_Bits(4,
- NI_RTSI_OUTPUT_DA_START1) |
- RTSI_Trig_Output_Bits(5,
- NI_RTSI_OUTPUT_G_SRC0) |
- RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
- if (board->reg_type & ni_reg_m_series_mask)
- devpriv->rtsi_trig_b_output_reg |=
- RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
- RTSI_Trig_B_Output_Register);
+ if (comedi_dio_update_state(s, data))
+ ni_writew(dev, s->state, M_Offset_PFI_DO);
-/*
-* Sets the source and direction of the 4 on board lines
-* devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
-*/
+ data[1] = ni_readw(dev, M_Offset_PFI_DI);
+
+ return insn->n;
}
-static int ni_rtsi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int cs5529_wait_for_idle(struct comedi_device *dev)
{
- data[1] = 0;
+ unsigned short status;
+ const int timeout = HZ;
+ int i;
+ for (i = 0; i < timeout; i++) {
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if ((status & CSS_ADC_BUSY) == 0)
+ break;
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(1))
+ return -EIO;
+ }
+ if (i == timeout) {
+ dev_err(dev->class_dev, "%s timeout\n", __func__);
+ return -ETIME;
+ }
+ return 0;
+}
+
+static void cs5529_command(struct comedi_device *dev, unsigned short value)
+{
+ static const int timeout = 100;
+ int i;
+
+ ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
+ /* give time for command to start being serially clocked into cs5529.
+ * this insures that the CSS_ADC_BUSY bit will get properly
+ * set before we exit this function.
+ */
+ for (i = 0; i < timeout; i++) {
+ if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
+ break;
+ udelay(1);
+ }
+ if (i == timeout)
+ dev_err(dev->class_dev,
+ "possible problem - never saw adc go busy?\n");
+}
+
+static int cs5529_do_conversion(struct comedi_device *dev,
+ unsigned short *data)
+{
+ int retval;
+ unsigned short status;
+
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
+ retval = cs5529_wait_for_idle(dev);
+ if (retval) {
+ dev_err(dev->class_dev,
+ "timeout or signal in cs5529_do_conversion()\n");
+ return -ETIME;
+ }
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if (status & CSS_OSC_DETECT) {
+ dev_err(dev->class_dev,
+ "cs5529 conversion error, status CSS_OSC_DETECT\n");
+ return -EIO;
+ }
+ if (status & CSS_OVERRANGE) {
+ dev_err(dev->class_dev,
+ "cs5529 conversion error, overrange (ignoring)\n");
+ }
+ if (data) {
+ *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
+ /* cs5529 returns 16 bit signed data in bipolar mode */
+ *data ^= (1 << 15);
+ }
+ return 0;
+}
+
+static int cs5529_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ int n, retval;
+ unsigned short sample;
+ unsigned int channel_select;
+ const unsigned int INTERNAL_REF = 0x1000;
+
+ /* Set calibration adc source. Docs lie, reference select bits 8 to 11
+ * do nothing. bit 12 seems to chooses internal reference voltage, bit
+ * 13 causes the adc input to go overrange (maybe reads external reference?) */
+ if (insn->chanspec & CR_ALT_SOURCE)
+ channel_select = INTERNAL_REF;
+ else
+ channel_select = CR_CHAN(insn->chanspec);
+ ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+
+ for (n = 0; n < insn->n; n++) {
+ retval = cs5529_do_conversion(dev, &sample);
+ if (retval < 0)
+ return retval;
+ data[n] = sample;
+ }
return insn->n;
}
-/* Find best multiplier/divider to try and get the PLL running at 80 MHz
- * given an arbitrary frequency input clock */
+static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
+ unsigned int reg_select_bits)
+{
+ ni_ao_win_outw(dev, ((value >> 16) & 0xff),
+ CAL_ADC_Config_Data_High_Word_67xx);
+ ni_ao_win_outw(dev, (value & 0xffff),
+ CAL_ADC_Config_Data_Low_Word_67xx);
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ dev_err(dev->class_dev,
+ "timeout or signal in %s\n", __func__);
+}
+
+static int init_cs5529(struct comedi_device *dev)
+{
+ unsigned int config_bits =
+ CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+
+#if 1
+ /* do self-calibration */
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
+ CSCMD_CONFIG_REGISTER);
+ /* need to force a conversion for calibration to run */
+ cs5529_do_conversion(dev, NULL);
+#else
+ /* force gain calibration to 1 */
+ cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
+ CSCMD_CONFIG_REGISTER);
+ if (cs5529_wait_for_idle(dev))
+ dev_err(dev->class_dev,
+ "timeout or signal in %s\n", __func__);
+#endif
+ return 0;
+}
+
+/*
+ * Find best multiplier/divider to try and get the PLL running at 80 MHz
+ * given an arbitrary frequency input clock.
+ */
static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
unsigned *freq_divider,
unsigned *freq_multiplier,
@@ -5266,6 +4871,7 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
static const unsigned target_picosec = 12500;
static const unsigned fudge_factor_80_to_20Mhz = 4;
int best_period_picosec = 0;
+
for (div = 1; div <= max_div; ++div) {
for (mult = 1; mult <= max_mult; ++mult) {
unsigned new_period_ps =
@@ -5278,10 +4884,9 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
}
}
}
- if (best_period_picosec == 0) {
- printk("%s: bug, failed to find pll parameters\n", __func__);
+ if (best_period_picosec == 0)
return -EIO;
- }
+
*freq_divider = best_div;
*freq_multiplier = best_mult;
*actual_period_ns =
@@ -5290,16 +4895,6 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
return 0;
}
-static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
-{
- const struct ni_board_struct *board = comedi_board(dev);
-
- if (board->reg_type & ni_reg_m_series_mask)
- return 8;
- else
- return 7;
-}
-
static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
unsigned source, unsigned period_ns)
{
@@ -5317,15 +4912,14 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
period_ns = 100;
/* these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that */
if (period_ns < min_period_ns || period_ns > max_period_ns) {
- printk
- ("%s: you must specify an input clock frequency between %i and %i nanosec "
- "for the phased-lock loop.\n", __func__,
- min_period_ns, max_period_ns);
+ dev_err(dev->class_dev,
+ "%s: you must specify an input clock frequency between %i and %i nanosec for the phased-lock loop\n",
+ __func__, min_period_ns, max_period_ns);
return -EINVAL;
}
devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
pll_control_bits =
MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
devpriv->clock_and_fout2 |=
@@ -5335,26 +4929,17 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
devpriv->clock_and_fout2 |=
MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
- retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
- &freq_multiplier,
- &devpriv->clock_ns);
- if (retval < 0)
- return retval;
break;
case NI_MIO_PLL_PXI10_CLOCK:
/* pxi clock is 10MHz */
devpriv->clock_and_fout2 |=
MSeries_PLL_In_Source_Select_PXI_Clock10;
- retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
- &freq_multiplier,
- &devpriv->clock_ns);
- if (retval < 0)
- return retval;
break;
default:
{
unsigned rtsi_channel;
static const unsigned max_rtsi_channel = 7;
+
for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
++rtsi_channel) {
if (source ==
@@ -5367,81 +4952,78 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
}
if (rtsi_channel > max_rtsi_channel)
return -EINVAL;
- retval = ni_mseries_get_pll_parameters(period_ns,
- &freq_divider,
- &freq_multiplier,
- &devpriv->
- clock_ns);
- if (retval < 0)
- return retval;
}
break;
}
- ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
+ retval = ni_mseries_get_pll_parameters(period_ns,
+ &freq_divider,
+ &freq_multiplier,
+ &devpriv->clock_ns);
+ if (retval < 0) {
+ dev_err(dev->class_dev,
+ "%s: bug, failed to find pll parameters\n", __func__);
+ return retval;
+ }
+
+ ni_writew(dev, devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
pll_control_bits |=
MSeries_PLL_Divisor_Bits(freq_divider) |
MSeries_PLL_Multiplier_Bits(freq_multiplier);
- /* printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n",
- * freq_divider, freq_multiplier, pll_control_bits); */
- /* printk("clock_ns=%d\n", devpriv->clock_ns); */
- ni_writew(pll_control_bits, M_Offset_PLL_Control);
+ ni_writew(dev, pll_control_bits, M_Offset_PLL_Control);
devpriv->clock_source = source;
/* it seems to typically take a few hundred microseconds for PLL to lock */
for (i = 0; i < timeout; ++i) {
- if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit)
+ if (ni_readw(dev, M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit)
break;
udelay(1);
}
if (i == timeout) {
- printk
- ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
- __func__, source, period_ns);
+ dev_err(dev->class_dev,
+ "%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns\n",
+ __func__, source, period_ns);
return -ETIMEDOUT;
}
return 3;
}
-static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
- unsigned period_ns)
+static int ni_set_master_clock(struct comedi_device *dev,
+ unsigned source, unsigned period_ns)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
if (source == NI_MIO_INTERNAL_CLOCK) {
devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
devpriv->clock_ns = TIMEBASE_1_NS;
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
devpriv->clock_and_fout2 &=
~(MSeries_Timebase1_Select_Bit |
MSeries_Timebase3_Select_Bit);
- ni_writew(devpriv->clock_and_fout2,
+ ni_writew(dev, devpriv->clock_and_fout2,
M_Offset_Clock_and_Fout2);
- ni_writew(0, M_Offset_PLL_Control);
+ ni_writew(dev, 0, M_Offset_PLL_Control);
}
devpriv->clock_source = source;
} else {
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
return ni_mseries_set_pll_master_clock(dev, source,
period_ns);
} else {
if (source == NI_MIO_RTSI_CLOCK) {
devpriv->rtsi_trig_direction_reg |=
Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev,
- devpriv->
- rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev,
+ devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
if (period_ns == 0) {
- printk
- ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: we don't handle an unspecified clock period correctly yet, returning error\n",
+ __func__);
return -EINVAL;
- } else {
- devpriv->clock_ns = period_ns;
}
+ devpriv->clock_ns = period_ns;
devpriv->clock_source = source;
} else
return -EINVAL;
@@ -5450,21 +5032,27 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
return 3;
}
-static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
+
+ return (devpriv->is_m_series) ? 8 : 7;
+}
+
+static int ni_valid_rtsi_output_source(struct comedi_device *dev,
+ unsigned chan, unsigned source)
+{
+ struct ni_private *devpriv = dev->private;
if (chan >= num_configurable_rtsi_channels(dev)) {
if (chan == old_RTSI_clock_channel) {
if (source == NI_RTSI_OUTPUT_RTSI_OSC)
return 1;
- else {
- printk
- ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
- __func__, chan, old_RTSI_clock_channel);
- return 0;
- }
+
+ dev_err(dev->class_dev,
+ "%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards\n",
+ __func__, chan, old_RTSI_clock_channel);
+ return 0;
}
return 0;
}
@@ -5479,21 +5067,15 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
case NI_RTSI_OUTPUT_RGOUT0:
case NI_RTSI_OUTPUT_RTSI_BRD_0:
return 1;
- break;
case NI_RTSI_OUTPUT_RTSI_OSC:
- if (board->reg_type & ni_reg_m_series_mask)
- return 1;
- else
- return 0;
- break;
+ return (devpriv->is_m_series) ? 1 : 0;
default:
return 0;
- break;
}
}
-static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static int ni_set_rtsi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
struct ni_private *devpriv = dev->private;
@@ -5503,14 +5085,14 @@ static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
devpriv->rtsi_trig_a_output_reg |=
RTSI_Trig_Output_Bits(chan, source);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
- RTSI_Trig_A_Output_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
} else if (chan < 8) {
devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
devpriv->rtsi_trig_b_output_reg |=
RTSI_Trig_Output_Bits(chan, source);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
- RTSI_Trig_B_Output_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
}
return 2;
}
@@ -5528,16 +5110,17 @@ static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan)
} else {
if (chan == old_RTSI_clock_channel)
return NI_RTSI_OUTPUT_RTSI_OSC;
- printk("%s: bug! should never get here?\n", __func__);
+ dev_err(dev->class_dev, "%s: bug! should never get here?\n",
+ __func__);
return 0;
}
}
static int ni_rtsi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
@@ -5545,33 +5128,30 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
case INSN_CONFIG_DIO_OUTPUT:
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg |=
- RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0);
+ RTSI_Output_Bit(chan, devpriv->is_m_series);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg |=
Drive_RTSI_Clock_Bit;
}
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
break;
case INSN_CONFIG_DIO_INPUT:
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg &=
- ~RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0);
+ ~RTSI_Output_Bit(chan, devpriv->is_m_series);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg &=
~Drive_RTSI_Clock_Bit;
}
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
break;
case INSN_CONFIG_DIO_QUERY:
if (chan < num_configurable_rtsi_channels(dev)) {
data[1] =
(devpriv->rtsi_trig_direction_reg &
- RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0))
+ RTSI_Output_Bit(chan, devpriv->is_m_series))
? INSN_CONFIG_DIO_OUTPUT
: INSN_CONFIG_DIO_INPUT;
} else if (chan == old_RTSI_clock_channel) {
@@ -5581,160 +5161,600 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT;
}
return 2;
- break;
case INSN_CONFIG_SET_CLOCK_SRC:
return ni_set_master_clock(dev, data[1], data[2]);
- break;
case INSN_CONFIG_GET_CLOCK_SRC:
data[1] = devpriv->clock_source;
data[2] = devpriv->clock_ns;
return 3;
- break;
case INSN_CONFIG_SET_ROUTING:
return ni_set_rtsi_routing(dev, chan, data[1]);
- break;
case INSN_CONFIG_GET_ROUTING:
data[1] = ni_get_rtsi_routing(dev, chan);
return 2;
- break;
default:
return -EINVAL;
- break;
}
return 1;
}
-static int cs5529_wait_for_idle(struct comedi_device *dev)
+static int ni_rtsi_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned short status;
- const int timeout = HZ;
- int i;
+ data[1] = 0;
- for (i = 0; i < timeout; i++) {
- status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
- if ((status & CSS_ADC_BUSY) == 0)
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(1))
- return -EIO;
+ return insn->n;
+}
+
+static void ni_rtsi_init(struct comedi_device *dev)
+{
+ struct ni_private *devpriv = dev->private;
+
+ /* Initialises the RTSI bus signal switch to a default state */
+
+ /* Set clock mode to internal */
+ devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
+ if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
+ dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n");
+ /* default internal lines routing to RTSI bus lines */
+ devpriv->rtsi_trig_a_output_reg =
+ RTSI_Trig_Output_Bits(0,
+ NI_RTSI_OUTPUT_ADR_START1) |
+ RTSI_Trig_Output_Bits(1,
+ NI_RTSI_OUTPUT_ADR_START2) |
+ RTSI_Trig_Output_Bits(2,
+ NI_RTSI_OUTPUT_SCLKG) |
+ RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN);
+ ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ devpriv->rtsi_trig_b_output_reg =
+ RTSI_Trig_Output_Bits(4,
+ NI_RTSI_OUTPUT_DA_START1) |
+ RTSI_Trig_Output_Bits(5,
+ NI_RTSI_OUTPUT_G_SRC0) |
+ RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
+ if (devpriv->is_m_series)
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
+ ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+
+/*
+* Sets the source and direction of the 4 on board lines
+* ni_stc_writew(dev, 0x0000, RTSI_Board_Register);
+*/
+}
+
+#ifdef PCIDMA
+static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
+ COMEDI_INPUT);
+ if (retval) {
+ dev_err(dev->class_dev,
+ "no dma channel available for use by counter\n");
+ return retval;
}
-/* printk("looped %i times waiting for idle\n", i); */
- if (i == timeout) {
- printk("%s: %s: timeout\n", __FILE__, __func__);
- return -ETIME;
+ ni_tio_acknowledge(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
+
+ return ni_tio_cmd(dev, s);
+}
+
+static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
+ ni_release_gpct_mite_channel(dev, counter->counter_index);
+ return retval;
+}
+#endif
+
+#if 0
+/*
+ * Read the GPCTs current value.
+ */
+static int GPCT_G_Watch(struct comedi_device *dev, int chan)
+{
+ unsigned int hi1, hi2, lo;
+
+ devpriv->gpct_command[chan] &= ~G_Save_Trace;
+ ni_stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ devpriv->gpct_command[chan] |= G_Save_Trace;
+ ni_stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ /* This procedure is used because the two registers cannot
+ * be read atomically. */
+ do {
+ hi1 = ni_stc_readw(dev, G_Save_Register_High(chan));
+ lo = ni_stc_readw(dev, G_Save_Register_Low(chan));
+ hi2 = ni_stc_readw(dev, G_Save_Register_High(chan));
+ } while (hi1 != hi2);
+
+ return (hi1 << 16) | lo;
+}
+
+static void GPCT_Reset(struct comedi_device *dev, int chan)
+{
+ int temp_ack_reg = 0;
+
+ devpriv->gpct_cur_operation[chan] = GPCT_RESET;
+
+ switch (chan) {
+ case 0:
+ ni_stc_writew(dev, G0_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G0_Gate_Error_Confirm;
+ temp_ack_reg |= G0_TC_Error_Confirm;
+ temp_ack_reg |= G0_TC_Interrupt_Ack;
+ temp_ack_reg |= G0_Gate_Interrupt_Ack;
+ ni_stc_writew(dev, temp_ack_reg, Interrupt_A_Ack_Register);
+
+ /* problem...this interferes with the other ctr... */
+ devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ case 1:
+ ni_stc_writew(dev, G1_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G1_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G1_Gate_Error_Confirm;
+ temp_ack_reg |= G1_TC_Error_Confirm;
+ temp_ack_reg |= G1_TC_Interrupt_Ack;
+ temp_ack_reg |= G1_Gate_Interrupt_Ack;
+ ni_stc_writew(dev, temp_ack_reg, Interrupt_B_Ack_Register);
+
+ devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
}
- return 0;
+
+ devpriv->gpct_mode[chan] = 0;
+ devpriv->gpct_input_select[chan] = 0;
+ devpriv->gpct_command[chan] = 0;
+
+ devpriv->gpct_command[chan] |= G_Synchronized_Gate;
+
+ ni_stc_writew(dev, devpriv->gpct_mode[chan], G_Mode_Register(chan));
+ ni_stc_writew(dev, devpriv->gpct_input_select[chan],
+ G_Input_Select_Register(chan));
+ ni_stc_writew(dev, 0, G_Autoincrement_Register(chan));
}
+#endif
-static void cs5529_command(struct comedi_device *dev, unsigned short value)
+static irqreturn_t ni_E_interrupt(int irq, void *d)
{
- static const int timeout = 100;
- int i;
+ struct comedi_device *dev = d;
+ unsigned short a_status;
+ unsigned short b_status;
+ unsigned int ai_mite_status = 0;
+ unsigned int ao_mite_status = 0;
+ unsigned long flags;
+#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
+ struct mite_struct *mite = devpriv->mite;
+#endif
- ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
- /* give time for command to start being serially clocked into cs5529.
- * this insures that the CSS_ADC_BUSY bit will get properly
- * set before we exit this function.
- */
- for (i = 0; i < timeout; i++) {
- if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
- break;
- udelay(1);
+ if (!dev->attached)
+ return IRQ_NONE;
+ smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
+
+ /* lock to avoid race with comedi_poll */
+ spin_lock_irqsave(&dev->spinlock, flags);
+ a_status = ni_stc_readw(dev, AI_Status_1_Register);
+ b_status = ni_stc_readw(dev, AO_Status_1_Register);
+#ifdef PCIDMA
+ if (mite) {
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags_too;
+
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
+ if (devpriv->ai_mite_chan) {
+ ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
+ if (ai_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->
+ ai_mite_chan->channel));
+ }
+ if (devpriv->ao_mite_chan) {
+ ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
+ if (ao_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->
+ ao_mite_chan->channel));
+ }
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
}
-/* printk("looped %i times writing command to cs5529\n", i); */
- if (i == timeout)
- comedi_error(dev, "possible problem - never saw adc go busy?");
+#endif
+ ack_a_interrupt(dev, a_status);
+ ack_b_interrupt(dev, b_status);
+ if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
+ handle_a_interrupt(dev, a_status, ai_mite_status);
+ if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
+ handle_b_interrupt(dev, b_status, ao_mite_status);
+ handle_gpct_interrupt(dev, 0);
+ handle_gpct_interrupt(dev, 1);
+ handle_cdio_interrupt(dev);
+
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+ return IRQ_HANDLED;
}
-/* write to cs5529 register */
-static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
- unsigned int reg_select_bits)
+static int ni_alloc_private(struct comedi_device *dev)
{
- ni_ao_win_outw(dev, ((value >> 16) & 0xff),
- CAL_ADC_Config_Data_High_Word_67xx);
- ni_ao_win_outw(dev, (value & 0xffff),
- CAL_ADC_Config_Data_Low_Word_67xx);
- reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
- cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
- if (cs5529_wait_for_idle(dev))
- comedi_error(dev, "time or signal in cs5529_config_write()");
+ struct ni_private *devpriv;
+
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
+ return -ENOMEM;
+
+ spin_lock_init(&devpriv->window_lock);
+ spin_lock_init(&devpriv->soft_reg_copy_lock);
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ return 0;
}
-static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
+static int ni_E_init(struct comedi_device *dev,
+ unsigned interrupt_pin, unsigned irq_polarity)
{
- int retval;
- unsigned short status;
+ const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
- cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
- retval = cs5529_wait_for_idle(dev);
- if (retval) {
- comedi_error(dev,
- "timeout or signal in cs5529_do_conversion()");
- return -ETIME;
+ if (board->n_aochan > MAX_N_AO_CHAN) {
+ dev_err(dev->class_dev, "bug! n_aochan > MAX_N_AO_CHAN\n");
+ return -EINVAL;
}
- status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
- if (status & CSS_OSC_DETECT) {
- printk
- ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
- return -EIO;
+
+ /* initialize clock dividers */
+ devpriv->clock_and_fout = Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 |
+ Clock_To_Board;
+ if (!devpriv->is_6xxx) {
+ /* BEAM is this needed for PCI-6143 ?? */
+ devpriv->clock_and_fout |= (AI_Output_Divide_By_2 |
+ AO_Output_Divide_By_2);
}
- if (status & CSS_OVERRANGE) {
- printk
- ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+ ni_stc_writew(dev, devpriv->clock_and_fout, Clock_and_FOUT_Register);
+
+ ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
+ if (ret)
+ return ret;
+
+ /* Analog Input subdevice */
+ s = &dev->subdevices[NI_AI_SUBDEV];
+ if (board->n_adchan) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_DITHER;
+ if (!devpriv->is_611x)
+ s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
+ if (board->ai_maxdata > 0xffff)
+ s->subdev_flags |= SDF_LSAMPL;
+ if (devpriv->is_m_series)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = board->n_adchan;
+ s->maxdata = board->ai_maxdata;
+ s->range_table = ni_range_lkup[board->gainlkup];
+ s->insn_read = ni_ai_insn_read;
+ s->insn_config = ni_ai_insn_config;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 512;
+ s->do_cmdtest = ni_ai_cmdtest;
+ s->do_cmd = ni_ai_cmd;
+ s->cancel = ni_ai_reset;
+ s->poll = ni_ai_poll;
+ s->munge = ni_ai_munge;
+
+ if (devpriv->mite)
+ s->async_dma_dir = DMA_FROM_DEVICE;
+ }
+
+ /* reset the analog input configuration */
+ ni_ai_reset(dev, s);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- if (data) {
- *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
- /* cs5529 returns 16 bit signed data in bipolar mode */
- *data ^= (1 << 15);
+
+ /* Analog Output subdevice */
+ s = &dev->subdevices[NI_AO_SUBDEV];
+ if (board->n_aochan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
+ if (devpriv->is_m_series)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = board->n_aochan;
+ s->maxdata = board->ao_maxdata;
+ s->range_table = board->ao_range_table;
+ s->insn_read = ni_ao_insn_read;
+ s->insn_write = ni_ao_insn_write;
+ s->insn_config = ni_ao_insn_config;
+
+ /*
+ * Along with the IRQ we need either a FIFO or DMA for
+ * async command support.
+ */
+ if (dev->irq && (board->ao_fifo_depth || devpriv->mite)) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = ni_ao_cmdtest;
+ s->do_cmd = ni_ao_cmd;
+ s->cancel = ni_ao_reset;
+ if (!devpriv->is_m_series)
+ s->munge = ni_ao_munge;
+
+ if (devpriv->mite)
+ s->async_dma_dir = DMA_TO_DEVICE;
+ }
+
+ if (devpriv->is_67xx)
+ init_ao_67xx(dev, s);
+
+ /* reset the analog output configuration */
+ ni_ao_reset(dev, s);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- return 0;
-}
-static int cs5529_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int n, retval;
- unsigned short sample;
- unsigned int channel_select;
- const unsigned int INTERNAL_REF = 0x1000;
+ /* Digital I/O subdevice */
+ s = &dev->subdevices[NI_DIO_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = board->has_32dio_chan ? 32 : 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ if (devpriv->is_m_series) {
+ s->subdev_flags |= SDF_LSAMPL;
+ s->insn_bits = ni_m_series_dio_insn_bits;
+ s->insn_config = ni_m_series_dio_insn_config;
+ if (dev->irq) {
+ s->subdev_flags |= SDF_CMD_WRITE /* | SDF_CMD_READ */;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = ni_cdio_cmdtest;
+ s->do_cmd = ni_cdio_cmd;
+ s->cancel = ni_cdio_cancel;
+
+ /* M-series boards use DMA */
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ }
- /* Set calibration adc source. Docs lie, reference select bits 8 to 11
- * do nothing. bit 12 seems to chooses internal reference voltage, bit
- * 13 causes the adc input to go overrange (maybe reads external reference?) */
- if (insn->chanspec & CR_ALT_SOURCE)
- channel_select = INTERNAL_REF;
- else
- channel_select = CR_CHAN(insn->chanspec);
- ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+ /* reset DIO and set all channels to inputs */
+ ni_writel(dev, CDO_Reset_Bit | CDI_Reset_Bit,
+ M_Offset_CDIO_Command);
+ ni_writel(dev, s->io_bits, M_Offset_DIO_Direction);
+ } else {
+ s->insn_bits = ni_dio_insn_bits;
+ s->insn_config = ni_dio_insn_config;
- for (n = 0; n < insn->n; n++) {
- retval = cs5529_do_conversion(dev, &sample);
- if (retval < 0)
- return retval;
- data[n] = sample;
+ /* set all channels to inputs */
+ devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
+ ni_writew(dev, devpriv->dio_control, DIO_Control_Register);
}
- return insn->n;
-}
-static int init_cs5529(struct comedi_device *dev)
-{
- unsigned int config_bits =
- CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+ /* 8255 device */
+ s = &dev->subdevices[NI_8255_DIO_SUBDEV];
+ if (board->has_8255) {
+ ret = subdev_8255_init(dev, s, ni_8255_callback,
+ (unsigned long)dev);
+ if (ret)
+ return ret;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
-#if 1
- /* do self-calibration */
- cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
- CSCMD_CONFIG_REGISTER);
- /* need to force a conversion for calibration to run */
- cs5529_do_conversion(dev, NULL);
-#else
- /* force gain calibration to 1 */
- cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
- cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
- CSCMD_CONFIG_REGISTER);
- if (cs5529_wait_for_idle(dev))
- comedi_error(dev, "timeout or signal in init_cs5529()\n");
+ /* formerly general purpose counter/timer device, but no longer used */
+ s = &dev->subdevices[NI_UNUSED_SUBDEV];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* Calibration subdevice */
+ s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ if (devpriv->is_m_series) {
+ /* internal PWM output used for AI nonlinearity calibration */
+ s->insn_config = ni_m_series_pwm_config;
+
+ ni_writel(dev, 0x0, M_Offset_Cal_PWM);
+ } else if (devpriv->is_6143) {
+ /* internal PWM output used for AI nonlinearity calibration */
+ s->insn_config = ni_6143_pwm_config;
+ } else {
+ s->subdev_flags |= SDF_WRITABLE;
+ s->insn_read = ni_calib_insn_read;
+ s->insn_write = ni_calib_insn_write;
+
+ /* setup the caldacs and find the real n_chan and maxdata */
+ caldac_setup(dev, s);
+ }
+
+ /* EEPROM subdevice */
+ s = &dev->subdevices[NI_EEPROM_SUBDEV];
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->maxdata = 0xff;
+ if (devpriv->is_m_series) {
+ s->n_chan = M_SERIES_EEPROM_SIZE;
+ s->insn_read = ni_m_series_eeprom_insn_read;
+ } else {
+ s->n_chan = 512;
+ s->insn_read = ni_eeprom_insn_read;
+ }
+
+ /* Digital I/O (PFI) subdevice */
+ s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->maxdata = 1;
+ if (devpriv->is_m_series) {
+ s->n_chan = 16;
+ s->insn_bits = ni_pfi_insn_bits;
+
+ ni_writew(dev, s->state, M_Offset_PFI_DO);
+ for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
+ ni_writew(dev, devpriv->pfi_output_select_reg[i],
+ M_Offset_PFI_Output_Select(i + 1));
+ }
+ } else {
+ s->n_chan = 10;
+ }
+ s->insn_config = ni_pfi_insn_config;
+
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
+
+ /* cs5529 calibration adc */
+ s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
+ if (devpriv->is_67xx) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
+ /* one channel for each analog output channel */
+ s->n_chan = board->n_aochan;
+ s->maxdata = (1 << 16) - 1;
+ s->range_table = &range_unknown; /* XXX */
+ s->insn_read = cs5529_ai_insn_read;
+ s->insn_config = NULL;
+ init_cs5529(dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Serial */
+ s = &dev->subdevices[NI_SERIAL_SUBDEV];
+ s->type = COMEDI_SUBD_SERIAL;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_config = ni_serial_insn_config;
+ devpriv->serial_interval_ns = 0;
+ devpriv->serial_hw_mode = 0;
+
+ /* RTSI */
+ s = &dev->subdevices[NI_RTSI_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->insn_bits = ni_rtsi_insn_bits;
+ s->insn_config = ni_rtsi_insn_config;
+ ni_rtsi_init(dev);
+
+ /* allocate and initialize the gpct counter device */
+ devpriv->counter_dev = ni_gpct_device_construct(dev,
+ ni_gpct_write_register,
+ ni_gpct_read_register,
+ (devpriv->is_m_series)
+ ? ni_gpct_variant_m_series
+ : ni_gpct_variant_e_series,
+ NUM_GPCT);
+ if (!devpriv->counter_dev)
+ return -ENOMEM;
+
+ /* Counter (gpct) subdevices */
+ for (i = 0; i < NUM_GPCT; ++i) {
+ struct ni_gpct *gpct = &devpriv->counter_dev->counters[i];
+
+ /* setup and initialize the counter */
+ gpct->chip_index = 0;
+ gpct->counter_index = i;
+ ni_tio_init_counter(gpct);
+
+ s = &dev->subdevices[NI_GPCT_SUBDEV(i)];
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+ s->n_chan = 3;
+ s->maxdata = (devpriv->is_m_series) ? 0xffffffff
+ : 0x00ffffff;
+ s->insn_read = ni_tio_insn_read;
+ s->insn_write = ni_tio_insn_read;
+ s->insn_config = ni_tio_insn_config;
+#ifdef PCIDMA
+ if (dev->irq && devpriv->mite) {
+ s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
+ s->len_chanlist = 1;
+ s->do_cmdtest = ni_tio_cmdtest;
+ s->do_cmd = ni_gpct_cmd;
+ s->cancel = ni_gpct_cancel;
+
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ }
#endif
+ s->private = gpct;
+ }
+
+ /* Frequency output subdevice */
+ s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xf;
+ s->insn_read = ni_freq_out_insn_read;
+ s->insn_write = ni_freq_out_insn_write;
+ s->insn_config = ni_freq_out_insn_config;
+
+ if (dev->irq) {
+ ni_stc_writew(dev,
+ (irq_polarity ? Interrupt_Output_Polarity : 0) |
+ (Interrupt_Output_On_3_Pins & 0) |
+ Interrupt_A_Enable | Interrupt_B_Enable |
+ Interrupt_A_Output_Select(interrupt_pin) |
+ Interrupt_B_Output_Select(interrupt_pin),
+ Interrupt_Control_Register);
+ }
+
+ /* DMA setup */
+ ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select);
+
+ if (devpriv->is_6xxx) {
+ ni_writeb(dev, 0, Magic_611x);
+ } else if (devpriv->is_m_series) {
+ int channel;
+
+ for (channel = 0; channel < board->n_aochan; ++channel) {
+ ni_writeb(dev, 0xf,
+ M_Offset_AO_Waveform_Order(channel));
+ ni_writeb(dev, 0x0,
+ M_Offset_AO_Reference_Attenuation(channel));
+ }
+ ni_writeb(dev, 0x0, M_Offset_AO_Calibration);
+ }
+
return 0;
}
+
+static void mio_common_detach(struct comedi_device *dev)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv) {
+ if (devpriv->counter_dev)
+ ni_gpct_device_destroy(devpriv->counter_dev);
+ }
+}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index de421486b758..9b201e48233e 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -47,156 +47,85 @@ See the notes in the ni_atmio.o driver.
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-#define ATMIO 1
-#undef PCIMIO
-
/*
* AT specific setup
*/
-#define NI_SIZE 0x20
-
-#define MAX_N_CALDACS 32
-
static const struct ni_board_struct ni_boards[] = {
{
- .device_id = 0x010d,
.name = "DAQCard-ai-16xe-50",
+ .device_id = 0x010d,
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_8,
.ai_speed = 5000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043 },
}, {
- .device_id = 0x010c,
.name = "DAQCard-ai-16e-4",
+ .device_id = 0x010c,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_16,
.ai_speed = 4000,
- .num_p0_dio_channels = 8,
.caldac = { mb88341 }, /* verified */
}, {
- .device_id = 0x02c4,
.name = "DAQCard-6062E",
+ .device_id = 0x02c4,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_16,
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_bipolar10,
.ao_speed = 1176,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* verified */
}, {
/* specs incorrect! */
- .device_id = 0x075e,
.name = "DAQCard-6024E",
+ .device_id = 0x075e,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
}, {
/* specs incorrect! */
- .device_id = 0x0245,
.name = "DAQCard-6036E",
+ .device_id = 0x0245,
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
#if 0
{
- .device_id = 0x0000, /* unknown */
.name = "DAQCard-6715",
+ .device_id = 0x0000, /* unknown */
.n_aochan = 8,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_671x = 8192,
- .num_p0_dio_channels = 8,
.caldac = { mb88341, mb88341 },
},
#endif
};
-#define interrupt_pin(a) 0
-
-#define IRQ_POLARITY 1
-
-struct ni_private {
-
- struct pcmcia_device *link;
-
-NI_PRIVATE_COMMON};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
-#define ni_readl(a) (inl((a)+dev->iobase))
-#define ni_writew(a, b) (outw((a), (b)+dev->iobase))
-#define ni_readw(a) (inw((a)+dev->iobase))
-#define ni_writeb(a, b) (outb((a), (b)+dev->iobase))
-#define ni_readb(a) (inb((a)+dev->iobase))
-
-/* How we access windowed registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. The
- * DAQCard devices map the low 8 STC registers to iobase+addr*2. */
-
-static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ni_writew(data, addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ni_writew(data, Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ret = ni_readw(addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ret = ni_readw(Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-
- return ret;
-}
-
#include "ni_mio_common.c"
static const void *ni_getboardtype(struct comedi_device *dev,
@@ -260,12 +189,8 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
return ret;
devpriv = dev->private;
- devpriv->stc_writew = mio_cs_win_out;
- devpriv->stc_readw = mio_cs_win_in;
- devpriv->stc_writel = win_out2;
- devpriv->stc_readl = win_in2;
- return ni_E_init(dev);
+ return ni_E_init(dev, 0, 1);
}
static void mio_cs_detach(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 5fc74d6ff6af..b5b36af80205 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -58,9 +58,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#include "comedi_fc.h"
#include "mite.h"
-#define PCI_DIO_SIZE 4096
-#define PCI_MITE_SIZE 4096
-
/* defines for the PCI-DIO-32HS */
#define Window_Address 4 /* W */
@@ -297,16 +294,6 @@ struct nidio96_private {
spinlock_t mite_channel_lock;
};
-static int ni_pcidio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int trignum);
-static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
-static int setup_mite_dma(struct comedi_device *dev,
- struct comedi_subdevice *s);
-
static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
{
struct nidio96_private *devpriv = dev->private;
@@ -319,13 +306,13 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
devpriv->di_mite_ring, 1, 2);
if (devpriv->di_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev, "failed to reserve mite dma channel.");
+ dev_err(dev->class_dev, "failed to reserve mite dma channel\n");
return -EBUSY;
}
devpriv->di_mite_chan->dir = COMEDI_INPUT;
writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
- devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ dev->mmio + DMA_Line_Control_Group1);
mmiowb();
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
return 0;
@@ -344,12 +331,36 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
devpriv->di_mite_chan = NULL;
writeb(primary_DMAChannel_bits(0) |
secondary_DMAChannel_bits(0),
- devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ dev->mmio + DMA_Line_Control_Group1);
mmiowb();
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
}
+static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct nidio96_private *devpriv = dev->private;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_pcidio_request_di_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
+
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->di_mite_chan) {
+ mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+ mite_dma_arm(devpriv->di_mite_chan);
+ } else
+ retval = -EIO;
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return retval;
+}
+
static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct nidio96_private *devpriv = dev->private;
@@ -361,7 +372,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
if (devpriv->di_mite_chan)
mite_sync_input_dma(devpriv->di_mite_chan, s);
spin_unlock(&devpriv->mite_channel_lock);
- count = s->async->buf_write_count - s->async->buf_read_count;
+ count = comedi_buf_n_bytes_ready(s);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return count;
}
@@ -392,9 +403,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
/* Lock to avoid race with comedi_poll */
spin_lock(&dev->spinlock);
- status = readb(devpriv->mite->daq_io_addr +
- Interrupt_And_Window_Status);
- flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ status = readb(dev->mmio + Interrupt_And_Window_Status);
+ flags = readb(dev->mmio + Group_1_Flags);
spin_lock(&devpriv->mite_channel_lock);
if (devpriv->di_mite_chan)
@@ -423,8 +433,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
if (work > 20) {
dev_dbg(dev->class_dev, "too much work in interrupt\n");
writeb(0x00,
- devpriv->mite->daq_io_addr +
- Master_DMA_And_Interrupt_Control);
+ dev->mmio + Master_DMA_And_Interrupt_Control);
break;
}
@@ -436,64 +445,50 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
if (work > 100) {
dev_dbg(dev->class_dev,
"too much work in interrupt\n");
- writeb(0x00,
- devpriv->mite->daq_io_addr +
+ writeb(0x00, dev->mmio +
Master_DMA_And_Interrupt_Control
);
goto out;
}
- auxdata =
- readl(devpriv->mite->daq_io_addr +
- Group_1_FIFO);
+ auxdata = readl(dev->mmio + Group_1_FIFO);
data1 = auxdata & 0xffff;
data2 = (auxdata & 0xffff0000) >> 16;
comedi_buf_put(s, data1);
comedi_buf_put(s, data2);
- flags = readb(devpriv->mite->daq_io_addr +
- Group_1_Flags);
+ flags = readb(dev->mmio + Group_1_Flags);
}
async->events |= COMEDI_CB_BLOCK;
}
if (flags & CountExpired) {
- writeb(ClearExpired,
- devpriv->mite->daq_io_addr +
- Group_1_Second_Clear);
+ writeb(ClearExpired, dev->mmio + Group_1_Second_Clear);
async->events |= COMEDI_CB_EOA;
- writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, dev->mmio + OpMode);
break;
} else if (flags & Waited) {
- writeb(ClearWaited,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
break;
} else if (flags & PrimaryTC) {
writeb(ClearPrimaryTC,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA;
} else if (flags & SecondaryTC) {
writeb(ClearSecondaryTC,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA;
}
- flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
- status = readb(devpriv->mite->daq_io_addr +
- Interrupt_And_Window_Status);
+ flags = readb(dev->mmio + Group_1_Flags);
+ status = readb(dev->mmio + Interrupt_And_Window_Status);
}
out:
cfc_handle_events(dev, s);
#if 0
- if (!tag) {
- writeb(0x03,
- devpriv->mite->daq_io_addr +
- Master_DMA_And_Interrupt_Control);
- }
+ if (!tag)
+ writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
#endif
spin_unlock(&dev->spinlock);
@@ -505,14 +500,13 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct nidio96_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(s->io_bits, dev->mmio + Port_Pin_Directions(0));
return insn->n;
}
@@ -522,16 +516,37 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct nidio96_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
+ writel(s->state, dev->mmio + Port_IO(0));
- data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
+ data[1] = readl(dev->mmio + Port_IO(0));
return insn->n;
}
+static int ni_pcidio_ns_to_timer(int *nanosec, unsigned int flags)
+{
+ int divider, base;
+
+ base = TIMER_BASE;
+
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+
+ *nanosec = base * divider;
+ return divider;
+}
+
static int ni_pcidio_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
@@ -596,7 +611,7 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- ni_pcidio_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ ni_pcidio_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
@@ -606,27 +621,20 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
return 0;
}
-static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
+static int ni_pcidio_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
- int divider, base;
+ struct nidio96_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
- base = TIMER_BASE;
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- divider = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- divider = (*nanosec + base - 1) / base;
- break;
- }
+ writeb(devpriv->OpModeBits, dev->mmio + OpMode);
+ s->async->inttrig = NULL;
- *nanosec = base * divider;
- return divider;
+ return 1;
}
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -635,98 +643,94 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
struct comedi_cmd *cmd = &s->async->cmd;
/* XXX configure ports for input */
- writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(0x0000, dev->mmio + Port_Pin_Directions(0));
if (1) {
/* enable fifos A B C D */
- writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(0x0f, dev->mmio + Data_Path);
/* set transfer width a 32 bits */
writeb(TransferWidth(0) | TransferLength(0),
- devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ dev->mmio + Transfer_Size_Control);
} else {
- writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(0x03, dev->mmio + Data_Path);
writeb(TransferWidth(3) | TransferLength(0),
- devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ dev->mmio + Transfer_Size_Control);
}
/* protocol configuration */
if (cmd->scan_begin_src == TRIG_TIMER) {
/* page 4-5, "input with internal REQs" */
- writeb(0, devpriv->mite->daq_io_addr + OpMode);
- writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
- writeb(1, devpriv->mite->daq_io_addr + Sequence);
- writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
- writeb(4, devpriv->mite->daq_io_addr + BlockMode);
- writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
- writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
+ writeb(0, dev->mmio + OpMode);
+ writeb(0x00, dev->mmio + ClockReg);
+ writeb(1, dev->mmio + Sequence);
+ writeb(0x04, dev->mmio + ReqReg);
+ writeb(4, dev->mmio + BlockMode);
+ writeb(3, dev->mmio + LinePolarities);
+ writeb(0xc0, dev->mmio + AckSer);
writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_NEAREST),
- devpriv->mite->daq_io_addr + StartDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
- writeb(1, devpriv->mite->daq_io_addr + AckDelay);
- writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
- writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
+ dev->mmio + StartDelay);
+ writeb(1, dev->mmio + ReqDelay);
+ writeb(1, dev->mmio + ReqNotDelay);
+ writeb(1, dev->mmio + AckDelay);
+ writeb(0x0b, dev->mmio + AckNotDelay);
+ writeb(0x01, dev->mmio + Data1Delay);
/* manual, page 4-5: ClockSpeed comment is incorrectly listed
* on DAQOptions */
- writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
- writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
+ writew(0, dev->mmio + ClockSpeed);
+ writeb(0, dev->mmio + DAQOptions);
} else {
/* TRIG_EXT */
/* page 4-5, "input with external REQs" */
- writeb(0, devpriv->mite->daq_io_addr + OpMode);
- writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
- writeb(0, devpriv->mite->daq_io_addr + Sequence);
- writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
- writeb(4, devpriv->mite->daq_io_addr + BlockMode);
- if (!(cmd->scan_begin_arg & CR_INVERT)) {
- /* Leading Edge pulse mode */
- writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
- } else {
- /* Trailing Edge pulse mode */
- writeb(2, devpriv->mite->daq_io_addr + LinePolarities);
- }
- writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
- writel(1, devpriv->mite->daq_io_addr + StartDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
- writeb(1, devpriv->mite->daq_io_addr + AckDelay);
- writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
- writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
- writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
- writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
+ writeb(0, dev->mmio + OpMode);
+ writeb(0x00, dev->mmio + ClockReg);
+ writeb(0, dev->mmio + Sequence);
+ writeb(0x00, dev->mmio + ReqReg);
+ writeb(4, dev->mmio + BlockMode);
+ if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
+ writeb(0, dev->mmio + LinePolarities);
+ else /* Trailing Edge */
+ writeb(2, dev->mmio + LinePolarities);
+ writeb(0x00, dev->mmio + AckSer);
+ writel(1, dev->mmio + StartDelay);
+ writeb(1, dev->mmio + ReqDelay);
+ writeb(1, dev->mmio + ReqNotDelay);
+ writeb(1, dev->mmio + AckDelay);
+ writeb(0x0C, dev->mmio + AckNotDelay);
+ writeb(0x10, dev->mmio + Data1Delay);
+ writew(0, dev->mmio + ClockSpeed);
+ writeb(0x60, dev->mmio + DAQOptions);
}
if (cmd->stop_src == TRIG_COUNT) {
writel(cmd->stop_arg,
- devpriv->mite->daq_io_addr + Transfer_Count);
+ dev->mmio + Transfer_Count);
} else {
/* XXX */
}
#ifdef USE_DMA
writeb(ClearPrimaryTC | ClearSecondaryTC,
- devpriv->mite->daq_io_addr + Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
{
int retval = setup_mite_dma(dev, s);
+
if (retval)
return retval;
}
#else
- writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ writeb(0x00, dev->mmio + DMA_Line_Control_Group1);
#endif
- writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
+ writeb(0x00, dev->mmio + DMA_Line_Control_Group2);
/* clear and enable interrupts */
- writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
- /* writeb(ClearExpired,
- devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
+ writeb(0xff, dev->mmio + Group_1_First_Clear);
+ /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */
- writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
- writeb(0x03,
- devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ writeb(IntEn, dev->mmio + Interrupt_Control);
+ writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
if (cmd->stop_src == TRIG_NONE) {
devpriv->OpModeBits = DataLatching(0) | RunMode(7);
@@ -735,8 +739,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
if (cmd->start_src == TRIG_NOW) {
/* start */
- writeb(devpriv->OpModeBits,
- devpriv->mite->daq_io_addr + OpMode);
+ writeb(devpriv->OpModeBits, dev->mmio + OpMode);
s->async->inttrig = NULL;
} else {
/* TRIG_INT */
@@ -746,60 +749,17 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
-static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- int retval;
- unsigned long flags;
-
- retval = ni_pcidio_request_di_mite_channel(dev);
- if (retval)
- return retval;
-
- /* write alloc the entire buffer */
- comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->di_mite_chan) {
- mite_prep_dma(devpriv->di_mite_chan, 32, 32);
- mite_dma_arm(devpriv->di_mite_chan);
- } else
- retval = -EIO;
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- return retval;
-}
-
-static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct nidio96_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
static int ni_pcidio_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct nidio96_private *devpriv = dev->private;
-
- writeb(0x00,
- devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control);
ni_pcidio_release_di_mite_channel(dev);
return 0;
}
static int ni_pcidio_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
+ struct comedi_subdevice *s)
{
struct nidio96_private *devpriv = dev->private;
int ret;
@@ -817,19 +777,16 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
const u8 *data, size_t data_len,
unsigned long context)
{
- struct nidio96_private *devpriv = dev->private;
static const int timeout = 1000;
int fpga_index = context;
int i;
size_t j;
- writew(0x80 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
- writew(0xc0 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
+ writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register);
for (i = 0;
- (readw(devpriv->mite->daq_io_addr +
- Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) {
+ (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 &&
+ i < timeout; ++i) {
udelay(1);
}
if (i == timeout) {
@@ -838,11 +795,10 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
fpga_index);
return -EIO;
}
- writew(0x80 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
for (i = 0;
- readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
- 0x3 && i < timeout; ++i) {
+ readw(dev->mmio + Firmware_Status_Register) != 0x3 &&
+ i < timeout; ++i) {
udelay(1);
}
if (i == timeout) {
@@ -853,12 +809,11 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
}
for (j = 0; j + 1 < data_len;) {
unsigned int value = data[j++];
+
value |= data[j++] << 8;
- writew(value,
- devpriv->mite->daq_io_addr + Firmware_Data_Register);
+ writew(value, dev->mmio + Firmware_Data_Register);
for (i = 0;
- (readw(devpriv->mite->daq_io_addr +
- Firmware_Status_Register) & 0x2) == 0
+ (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0
&& i < timeout; ++i) {
udelay(1);
}
@@ -871,7 +826,7 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
if (need_resched())
schedule();
}
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x0, dev->mmio + Firmware_Control_Register);
return 0;
}
@@ -882,30 +837,27 @@ static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
static int pci_6534_reset_fpgas(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
int ret;
int i;
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x0, dev->mmio + Firmware_Control_Register);
for (i = 0; i < 3; ++i) {
ret = pci_6534_reset_fpga(dev, i);
if (ret < 0)
break;
}
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
+ writew(0x0, dev->mmio + Firmware_Mask_Register);
return ret;
}
static void pci_6534_init_main_fpga(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
-
- writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
+ writel(0, dev->mmio + FPGA_Control1_Register);
+ writel(0, dev->mmio + FPGA_Control2_Register);
+ writel(0, dev->mmio + FPGA_SCALS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCAMS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCBLS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCBMS_Counter_Register);
}
static int pci_6534_upload_firmware(struct comedi_device *dev)
@@ -937,15 +889,12 @@ static int pci_6534_upload_firmware(struct comedi_device *dev)
static void nidio_reset_board(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
- void __iomem *daq_mmio = devpriv->mite->daq_io_addr;
-
- writel(0, daq_mmio + Port_IO(0));
- writel(0, daq_mmio + Port_Pin_Directions(0));
- writel(0, daq_mmio + Port_Pin_Mask(0));
+ writel(0, dev->mmio + Port_IO(0));
+ writel(0, dev->mmio + Port_Pin_Directions(0));
+ writel(0, dev->mmio + Port_Pin_Mask(0));
/* disable interrupts on board */
- writeb(0, daq_mmio + Master_DMA_And_Interrupt_Control);
+ writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control);
}
static int nidio_auto_attach(struct comedi_device *dev,
@@ -979,11 +928,9 @@ static int nidio_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = mite_setup(dev, devpriv->mite);
+ if (ret < 0)
return ret;
- }
devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->di_mite_ring == NULL)
@@ -1002,7 +949,7 @@ static int nidio_auto_attach(struct comedi_device *dev,
return ret;
dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
- readb(devpriv->mite->daq_io_addr + Chip_Version));
+ readb(dev->mmio + Chip_Version));
s = &dev->subdevices[0];
@@ -1024,7 +971,7 @@ static int nidio_auto_attach(struct comedi_device *dev,
s->async_dma_dir = DMA_BIDIRECTIONAL;
s->poll = &ni_pcidio_poll;
- irq = mite_irq(devpriv->mite);
+ irq = pcidev->irq;
if (irq) {
ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
dev->board_name, dev);
@@ -1046,11 +993,10 @@ static void nidio_detach(struct comedi_device *dev)
mite_free_ring(devpriv->di_mite_ring);
devpriv->di_mite_ring = NULL;
}
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 89300dc78e35..da61fa70decf 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -118,13 +118,6 @@ Bugs:
#define PCIDMA
-#define PCIMIO 1
-#undef ATMIO
-
-#define MAX_N_CALDACS (16+16+2)
-
-#define DRV_NAME "ni_pcimio"
-
/* These are not all the possible ao ranges for 628x boards.
They can do OFFSET +- REFERENCE where OFFSET can be
0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
@@ -218,87 +211,79 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCIMIO_16XE_50] = {
.name = "pci-mio-16xe-50",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 2048,
.alwaysdither = 1,
.gainlkup = ai_gain_8,
.ai_speed = 50000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 50000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043 },
},
[BOARD_PCIMIO_16XE_10] = {
.name = "pci-mio-16xe-10", /* aka pci-6030E */
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCI6014] = {
.name = "pci-6014",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_range_table = &range_bipolar10,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PXI6030E] = {
.name = "pxi-6030e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCIMIO_16E_1] = {
.name = "pci-mio-16e-1", /* aka pci-6070e */
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { mb88341 },
},
[BOARD_PCIMIO_16E_4] = {
.name = "pci-mio-16e-4", /* aka pci-6040e */
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
/*
@@ -307,216 +292,195 @@ static const struct ni_board_struct ni_boards[] = {
*/
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 512,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* doc says mb88341 */
},
[BOARD_PXI6040E] = {
.name = "pxi-6040e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 512,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { mb88341 },
},
[BOARD_PCI6031E] = {
.name = "pci-6031e",
.n_adchan = 64,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCI6032E] = {
.name = "pci-6032e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCI6033E] = {
.name = "pci-6033e",
.n_adchan = 64,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCI6071E] = {
.name = "pci-6071e",
.n_adchan = 64,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PCI6023E] = {
.name = "pci-6023e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* manual is wrong */
},
[BOARD_PCI6024E] = {
.name = "pci-6024e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* manual is wrong */
},
[BOARD_PCI6025E] = {
.name = "pci-6025e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* manual is wrong */
.has_8255 = 1,
},
[BOARD_PXI6025E] = {
.name = "pxi-6025e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* manual is wrong */
.has_8255 = 1,
},
[BOARD_PCI6034E] = {
.name = "pci-6034e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PCI6035E] = {
.name = "pci-6035e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PCI6052E] = {
.name = "pci-6052e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 3000,
.n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
.ao_speed = 3000,
- .num_p0_dio_channels = 8,
/* manual is wrong */
.caldac = { ad8804_debug, ad8804_debug, ad8522 },
},
[BOARD_PCI6110] = {
.name = "pci-6110",
.n_adchan = 4,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.alwaysdither = 0,
.gainlkup = ai_gain_611x,
.ai_speed = 200,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.reg_type = ni_reg_611x,
.ao_range_table = &range_bipolar10,
.ao_fifo_depth = 2048,
.ao_speed = 250,
- .num_p0_dio_channels = 8,
.caldac = { ad8804, ad8804 },
},
[BOARD_PCI6111] = {
.name = "pci-6111",
.n_adchan = 2,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 200,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.reg_type = ni_reg_611x,
.ao_range_table = &range_bipolar10,
.ao_fifo_depth = 2048,
.ao_speed = 250,
- .num_p0_dio_channels = 8,
.caldac = { ad8804, ad8804 },
},
#if 0
@@ -524,16 +488,15 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6115] = { /* .device_id = 0x2ed0, */
.name = "pci-6115",
.n_adchan = 4,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 100,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_671x = 1,
.ao_fifo_depth = 2048,
.ao_speed = 250,
- .num_p0_dio_channels = 8,
.reg_611x = 1,
/* XXX */
.caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
@@ -543,17 +506,16 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PXI6115] = { /* .device_id = ????, */
.name = "pxi-6115",
.n_adchan = 4,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 100,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_671x = 1,
.ao_fifo_depth = 2048,
.ao_speed = 250,
.reg_611x = 1,
- .num_p0_dio_channels = 8,
/* XXX */
.caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
},
@@ -561,56 +523,51 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6711] = {
.name = "pci-6711",
.n_aochan = 4,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
/* data sheet says 8192, but fifo really holds 16384 samples */
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6711,
.caldac = { ad8804_debug },
},
[BOARD_PXI6711] = {
.name = "pxi-6711",
.n_aochan = 4,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6711,
.caldac = { ad8804_debug },
},
[BOARD_PCI6713] = {
.name = "pci-6713",
.n_aochan = 8,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6713,
.caldac = { ad8804_debug, ad8804_debug },
},
[BOARD_PXI6713] = {
.name = "pxi-6713",
.n_aochan = 8,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6713,
.caldac = { ad8804_debug, ad8804_debug },
},
[BOARD_PCI6731] = {
.name = "pci-6731",
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8192,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6711,
.caldac = { ad8804_debug },
},
@@ -618,10 +575,9 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PXI6731] = { /* .device_id = ????, */
.name = "pxi-6731",
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8192,
.ao_range_table = &range_bipolar10,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6711,
.caldac = { ad8804_debug },
},
@@ -629,759 +585,462 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6733] = {
.name = "pci-6733",
.n_aochan = 8,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6713,
.caldac = { ad8804_debug, ad8804_debug },
},
[BOARD_PXI6733] = {
.name = "pxi-6733",
.n_aochan = 8,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 16384,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6713,
.caldac = { ad8804_debug, ad8804_debug },
},
[BOARD_PXI6071E] = {
.name = "pxi-6071e",
.n_adchan = 64,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PXI6070E] = {
.name = "pxi-6070e",
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 1000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PXI6052E] = {
.name = "pxi-6052e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 3000,
.n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
.ao_speed = 3000,
- .num_p0_dio_channels = 8,
.caldac = { mb88341, mb88341, ad8522 },
},
[BOARD_PXI6031E] = {
.name = "pxi-6031e",
.n_adchan = 64,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
.ao_speed = 10000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043, ad8522 },
},
[BOARD_PCI6036E] = {
.name = "pci-6036e",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_range_table = &range_bipolar10,
.ao_speed = 100000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
[BOARD_PCI6220] = {
.name = "pci-6220",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 512, /* FIXME: guess */
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_622x,
.caldac = { caldac_none },
},
[BOARD_PCI6221] = {
.name = "pci-6221",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6221_37PIN] = {
.name = "pci-6221_37pin",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6224] = {
.name = "pci-6224",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.reg_type = ni_reg_622x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PXI6224] = {
.name = "pxi-6224",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.reg_type = ni_reg_622x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6225] = {
.name = "pci-6225",
.n_adchan = 80,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PXI6225] = {
.name = "pxi-6225",
.n_adchan = 80,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6229] = {
.name = "pci-6229",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6250] = {
.name = "pci-6250",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.reg_type = ni_reg_625x,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6251] = {
.name = "pci-6251",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_speed = 350,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCIE6251] = {
.name = "pcie-6251",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_speed = 350,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PXIE6251] = {
.name = "pxie-6251",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_speed = 350,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6254] = {
.name = "pci-6254",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.reg_type = ni_reg_625x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6259] = {
.name = "pci-6259",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_speed = 350,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCIE6259] = {
.name = "pcie-6259",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_speed = 350,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6280] = {
.name = "pci-6280",
.n_adchan = 16,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.ao_fifo_depth = 8191,
.reg_type = ni_reg_628x,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6281] = {
.name = "pci-6281",
.n_adchan = 16,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_628x_ao,
.reg_type = ni_reg_628x,
- .ao_unipolar = 1,
.ao_speed = 350,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PXI6281] = {
.name = "pxi-6281",
.n_adchan = 16,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_628x_ao,
.reg_type = ni_reg_628x,
- .ao_unipolar = 1,
.ao_speed = 350,
- .num_p0_dio_channels = 8,
.caldac = { caldac_none },
},
[BOARD_PCI6284] = {
.name = "pci-6284",
.n_adchan = 32,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.reg_type = ni_reg_628x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6289] = {
.name = "pci-6289",
.n_adchan = 32,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_628x_ao,
.reg_type = ni_reg_628x,
- .ao_unipolar = 1,
.ao_speed = 350,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6143] = {
.name = "pci-6143",
.n_adchan = 8,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_6143,
.ai_speed = 4000,
.reg_type = ni_reg_6143,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug, ad8804_debug },
},
[BOARD_PXI6143] = {
.name = "pxi-6143",
.n_adchan = 8,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_6143,
.ai_speed = 4000,
.reg_type = ni_reg_6143,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug, ad8804_debug },
},
};
-struct ni_private {
-NI_PRIVATE_COMMON};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (writel((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readl(a) (readl(devpriv->mite->daq_io_addr + (a)))
-#define ni_writew(a, b) (writew((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readw(a) (readw(devpriv->mite->daq_io_addr + (a)))
-#define ni_writeb(a, b) (writeb((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readb(a) (readb(devpriv->mite->daq_io_addr + (a)))
-
-/* How we access STC registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. Most
- * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
- * The 611x devices map the write registers to iobase+addr*2, and
- * the read registers to iobase+(addr-1)*2. */
-/* However, the 611x boards still aren't working, so I'm disabling
- * non-windowed STC access temporarily */
+#include "ni_mio_common.c"
-static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg)
+static int pcimio_ai_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned long flags;
+ int ret;
+
+ ret = mite_buf_change(devpriv->ai_mite_ring, s);
+ if (ret < 0)
+ return ret;
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(reg, Window_Address);
- ni_writew(data, Window_Data);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ return 0;
}
-static uint16_t e_series_win_in(struct comedi_device *dev, int reg)
+static int pcimio_ao_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
+ int ret;
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(reg, Window_Address);
- ret = ni_readw(Window_Data);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ ret = mite_buf_change(devpriv->ao_mite_ring, s);
+ if (ret < 0)
+ return ret;
- return ret;
+ return 0;
}
-static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
- int reg)
+static int pcimio_gpct0_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case ADC_FIFO_Clear:
- offset = M_Offset_AI_FIFO_Clear;
- break;
- case AI_Command_1_Register:
- offset = M_Offset_AI_Command_1;
- break;
- case AI_Command_2_Register:
- offset = M_Offset_AI_Command_2;
- break;
- case AI_Mode_1_Register:
- offset = M_Offset_AI_Mode_1;
- break;
- case AI_Mode_2_Register:
- offset = M_Offset_AI_Mode_2;
- break;
- case AI_Mode_3_Register:
- offset = M_Offset_AI_Mode_3;
- break;
- case AI_Output_Control_Register:
- offset = M_Offset_AI_Output_Control;
- break;
- case AI_Personal_Register:
- offset = M_Offset_AI_Personal;
- break;
- case AI_SI2_Load_A_Register:
- /* this is actually a 32 bit register on m series boards */
- ni_writel(data, M_Offset_AI_SI2_Load_A);
- return;
- break;
- case AI_SI2_Load_B_Register:
- /* this is actually a 32 bit register on m series boards */
- ni_writel(data, M_Offset_AI_SI2_Load_B);
- return;
- break;
- case AI_START_STOP_Select_Register:
- offset = M_Offset_AI_START_STOP_Select;
- break;
- case AI_Trigger_Select_Register:
- offset = M_Offset_AI_Trigger_Select;
- break;
- case Analog_Trigger_Etc_Register:
- offset = M_Offset_Analog_Trigger_Etc;
- break;
- case AO_Command_1_Register:
- offset = M_Offset_AO_Command_1;
- break;
- case AO_Command_2_Register:
- offset = M_Offset_AO_Command_2;
- break;
- case AO_Mode_1_Register:
- offset = M_Offset_AO_Mode_1;
- break;
- case AO_Mode_2_Register:
- offset = M_Offset_AO_Mode_2;
- break;
- case AO_Mode_3_Register:
- offset = M_Offset_AO_Mode_3;
- break;
- case AO_Output_Control_Register:
- offset = M_Offset_AO_Output_Control;
- break;
- case AO_Personal_Register:
- offset = M_Offset_AO_Personal;
- break;
- case AO_Start_Select_Register:
- offset = M_Offset_AO_Start_Select;
- break;
- case AO_Trigger_Select_Register:
- offset = M_Offset_AO_Trigger_Select;
- break;
- case Clock_and_FOUT_Register:
- offset = M_Offset_Clock_and_FOUT;
- break;
- case Configuration_Memory_Clear:
- offset = M_Offset_Configuration_Memory_Clear;
- break;
- case DAC_FIFO_Clear:
- offset = M_Offset_AO_FIFO_Clear;
- break;
- case DIO_Control_Register:
- dev_dbg(dev->class_dev,
- "%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
- __func__, reg);
- return;
- break;
- case G_Autoincrement_Register(0):
- offset = M_Offset_G0_Autoincrement;
- break;
- case G_Autoincrement_Register(1):
- offset = M_Offset_G1_Autoincrement;
- break;
- case G_Command_Register(0):
- offset = M_Offset_G0_Command;
- break;
- case G_Command_Register(1):
- offset = M_Offset_G1_Command;
- break;
- case G_Input_Select_Register(0):
- offset = M_Offset_G0_Input_Select;
- break;
- case G_Input_Select_Register(1):
- offset = M_Offset_G1_Input_Select;
- break;
- case G_Mode_Register(0):
- offset = M_Offset_G0_Mode;
- break;
- case G_Mode_Register(1):
- offset = M_Offset_G1_Mode;
- break;
- case Interrupt_A_Ack_Register:
- offset = M_Offset_Interrupt_A_Ack;
- break;
- case Interrupt_A_Enable_Register:
- offset = M_Offset_Interrupt_A_Enable;
- break;
- case Interrupt_B_Ack_Register:
- offset = M_Offset_Interrupt_B_Ack;
- break;
- case Interrupt_B_Enable_Register:
- offset = M_Offset_Interrupt_B_Enable;
- break;
- case Interrupt_Control_Register:
- offset = M_Offset_Interrupt_Control;
- break;
- case IO_Bidirection_Pin_Register:
- offset = M_Offset_IO_Bidirection_Pin;
- break;
- case Joint_Reset_Register:
- offset = M_Offset_Joint_Reset;
- break;
- case RTSI_Trig_A_Output_Register:
- offset = M_Offset_RTSI_Trig_A_Output;
- break;
- case RTSI_Trig_B_Output_Register:
- offset = M_Offset_RTSI_Trig_B_Output;
- break;
- case RTSI_Trig_Direction_Register:
- offset = M_Offset_RTSI_Trig_Direction;
- break;
- /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
- and M_Offset_SCXI_Serial_Data_Out (8 bit) */
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return;
- break;
- }
- ni_writew(data, offset);
-}
+ int ret;
-static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case AI_Status_1_Register:
- offset = M_Offset_AI_Status_1;
- break;
- case AO_Status_1_Register:
- offset = M_Offset_AO_Status_1;
- break;
- case AO_Status_2_Register:
- offset = M_Offset_AO_Status_2;
- break;
- case DIO_Serial_Input_Register:
- return ni_readb(M_Offset_SCXI_Serial_Data_In);
- break;
- case Joint_Status_1_Register:
- offset = M_Offset_Joint_Status_1;
- break;
- case Joint_Status_2_Register:
- offset = M_Offset_Joint_Status_2;
- break;
- case G_Status_Register:
- offset = M_Offset_G01_Status;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return 0;
- break;
- }
- return ni_readw(offset);
+ ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
-static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
- int reg)
+static int pcimio_gpct1_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case AI_SC_Load_A_Registers:
- offset = M_Offset_AI_SC_Load_A;
- break;
- case AI_SI_Load_A_Registers:
- offset = M_Offset_AI_SI_Load_A;
- break;
- case AO_BC_Load_A_Register:
- offset = M_Offset_AO_BC_Load_A;
- break;
- case AO_UC_Load_A_Register:
- offset = M_Offset_AO_UC_Load_A;
- break;
- case AO_UI_Load_A_Register:
- offset = M_Offset_AO_UI_Load_A;
- break;
- case G_Load_A_Register(0):
- offset = M_Offset_G0_Load_A;
- break;
- case G_Load_A_Register(1):
- offset = M_Offset_G1_Load_A;
- break;
- case G_Load_B_Register(0):
- offset = M_Offset_G0_Load_B;
- break;
- case G_Load_B_Register(1):
- offset = M_Offset_G1_Load_B;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return;
- break;
- }
- ni_writel(data, offset);
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
-static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
+static int pcimio_dio_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case G_HW_Save_Register(0):
- offset = M_Offset_G0_HW_Save;
- break;
- case G_HW_Save_Register(1):
- offset = M_Offset_G1_HW_Save;
- break;
- case G_Save_Register(0):
- offset = M_Offset_G0_Save;
- break;
- case G_Save_Register(1):
- offset = M_Offset_G1_Save;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return 0;
- break;
- }
- return ni_readl(offset);
-}
-
-#define interrupt_pin(a) 0
-#define IRQ_POLARITY 1
+ int ret;
-#define NI_E_IRQ_FLAGS IRQF_SHARED
+ ret = mite_buf_change(devpriv->cdo_mite_ring, s);
+ if (ret < 0)
+ return ret;
-#include "ni_mio_common.c"
+ return 0;
+}
-static int pcimio_ai_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size);
-static int pcimio_ao_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size);
-static int pcimio_gpct0_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
-static int pcimio_gpct1_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
-static int pcimio_dio_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
static void m_series_init_eeprom_buffer(struct comedi_device *dev)
{
@@ -1408,12 +1067,12 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev)
BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
for (i = 0; i < serial_number_eeprom_length; ++i) {
char *byte_ptr = (char *)&devpriv->serial_number + i;
- *byte_ptr = ni_readb(serial_number_eeprom_offset + i);
+ *byte_ptr = ni_readb(dev, serial_number_eeprom_offset + i);
}
devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
- devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+ devpriv->eeprom_buffer[i] = ni_readb(dev, Start_Cal_EEPROM + i);
writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
@@ -1427,21 +1086,26 @@ static void init_6143(struct comedi_device *dev)
struct ni_private *devpriv = dev->private;
/* Disable interrupts */
- devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+ ni_stc_writew(dev, 0, Interrupt_Control_Register);
/* Initialise 6143 AI specific bits */
- ni_writeb(0x00, Magic_6143); /* Set G0,G1 DMA mode to E series version */
- ni_writeb(0x80, PipelineDelay_6143); /* Set EOCMode, ADCMode and pipelinedelay */
- ni_writeb(0x00, EOC_Set_6143); /* Set EOC Delay */
+
+ /* Set G0,G1 DMA mode to E series version */
+ ni_writeb(dev, 0x00, Magic_6143);
+ /* Set EOCMode, ADCMode and pipelinedelay */
+ ni_writeb(dev, 0x80, PipelineDelay_6143);
+ /* Set EOC Delay */
+ ni_writeb(dev, 0x00, EOC_Set_6143);
/* Set the FIFO half full level */
- ni_writel(board->ai_fifo_depth / 2, AIFIFO_Flag_6143);
+ ni_writel(dev, board->ai_fifo_depth / 2, AIFIFO_Flag_6143);
/* Strobe Relay disable bit */
devpriv->ai_calib_source_enabled = 0;
- ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+ ni_writew(dev, devpriv->ai_calib_source, Calibration_Channel_6143);
}
static void pcimio_detach(struct comedi_device *dev)
@@ -1457,11 +1121,10 @@ static void pcimio_detach(struct comedi_device *dev)
mite_free_ring(devpriv->cdo_mite_ring);
mite_free_ring(devpriv->gpct_mite_ring[0]);
mite_free_ring(devpriv->gpct_mite_ring[1]);
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -1494,23 +1157,30 @@ static int pcimio_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- if (board->reg_type & ni_reg_m_series_mask) {
- devpriv->stc_writew = &m_series_stc_writew;
- devpriv->stc_readw = &m_series_stc_readw;
- devpriv->stc_writel = &m_series_stc_writel;
- devpriv->stc_readl = &m_series_stc_readl;
- } else {
- devpriv->stc_writew = &e_series_win_out;
- devpriv->stc_readw = &e_series_win_in;
- devpriv->stc_writel = &win_out2;
- devpriv->stc_readl = &win_in2;
- }
-
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- pr_warn("error setting up mite\n");
+ if (board->reg_type & ni_reg_m_series_mask)
+ devpriv->is_m_series = 1;
+ if (board->reg_type & ni_reg_6xxx_mask)
+ devpriv->is_6xxx = 1;
+ if (board->reg_type == ni_reg_611x)
+ devpriv->is_611x = 1;
+ if (board->reg_type == ni_reg_6143)
+ devpriv->is_6143 = 1;
+ if (board->reg_type == ni_reg_622x)
+ devpriv->is_622x = 1;
+ if (board->reg_type == ni_reg_625x)
+ devpriv->is_625x = 1;
+ if (board->reg_type == ni_reg_628x)
+ devpriv->is_628x = 1;
+ if (board->reg_type & ni_reg_67xx_mask)
+ devpriv->is_67xx = 1;
+ if (board->reg_type == ni_reg_6711)
+ devpriv->is_6711 = 1;
+ if (board->reg_type == ni_reg_6713)
+ devpriv->is_6713 = 1;
+
+ ret = mite_setup(dev, devpriv->mite);
+ if (ret < 0)
return ret;
- }
devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->ai_mite_ring == NULL)
@@ -1528,20 +1198,20 @@ static int pcimio_auto_attach(struct comedi_device *dev,
if (devpriv->gpct_mite_ring[1] == NULL)
return -ENOMEM;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
m_series_init_eeprom_buffer(dev);
- if (board->reg_type == ni_reg_6143)
+ if (devpriv->is_6143)
init_6143(dev);
- irq = mite_irq(devpriv->mite);
+ irq = pcidev->irq;
if (irq) {
- ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
+ ret = request_irq(irq, ni_E_interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = irq;
}
- ret = ni_E_init(dev);
+ ret = ni_E_init(dev, 0, 1);
if (ret < 0)
return ret;
@@ -1554,73 +1224,6 @@ static int pcimio_auto_attach(struct comedi_device *dev,
return 0;
}
-static int pcimio_ai_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ai_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_ao_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ao_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct0_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct1_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_dio_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->cdo_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static struct comedi_driver ni_pcimio_driver = {
.driver_name = "ni_pcimio",
.module = THIS_MODULE,
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
index f0630b7897b5..a2841292ddd4 100644
--- a/drivers/staging/comedi/drivers/ni_stc.h
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -1285,14 +1285,6 @@ static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
return (bits >> ((channel % 3) * 5)) & 0x1f;
};
-enum MSeries_Gi_DMA_Config_Bits {
- Gi_DMA_BankSW_Error_Bit = 0x10,
- Gi_DMA_Reset_Bit = 0x8,
- Gi_DMA_Int_Enable_Bit = 0x4,
- Gi_DMA_Write_Bit = 0x2,
- Gi_DMA_Enable_Bit = 0x1,
-};
-
static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
{
return 0x3 << (channel * 2);
@@ -1388,12 +1380,12 @@ enum Interrupt_C_Status_Bits {
#define M_SERIES_EEPROM_SIZE 1024
struct ni_board_struct {
+ const char *name;
int device_id;
int isapnp_id;
- char *name;
int n_adchan;
- int adbits;
+ unsigned int ai_maxdata;
int ai_fifo_depth;
unsigned int alwaysdither:1;
@@ -1401,107 +1393,100 @@ struct ni_board_struct {
int ai_speed;
int n_aochan;
- int aobits;
+ unsigned int ao_maxdata;
int ao_fifo_depth;
const struct comedi_lrange *ao_range_table;
unsigned ao_speed;
- unsigned num_p0_dio_channels;
-
int reg_type;
- unsigned int ao_unipolar:1;
unsigned int has_8255:1;
- unsigned int has_analog_trig:1;
+ unsigned int has_32dio_chan:1;
enum caldac_enum caldac[3];
};
-#define MAX_N_AO_CHAN 8
-#define NUM_GPCT 2
-
-#define NI_PRIVATE_COMMON \
- uint16_t (*stc_readw)(struct comedi_device *dev, int register); \
- uint32_t (*stc_readl)(struct comedi_device *dev, int register); \
- void (*stc_writew)(struct comedi_device *dev, uint16_t value, int register); \
- void (*stc_writel)(struct comedi_device *dev, uint32_t value, int register); \
- \
- unsigned short dio_output; \
- unsigned short dio_control; \
- int ao0p, ao1p; \
- int lastchan; \
- int last_do; \
- int rt_irq; \
- int irqmask; \
- int aimode; \
- int ai_continuous; \
- int blocksize; \
- int n_left; \
- unsigned int ai_calib_source; \
- unsigned int ai_calib_source_enabled; \
- spinlock_t window_lock; \
- spinlock_t soft_reg_copy_lock; \
- spinlock_t mite_channel_lock; \
- \
- int changain_state; \
- unsigned int changain_spec; \
- \
- unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \
- unsigned short ao[MAX_N_AO_CHAN]; \
- unsigned short caldacs[MAX_N_CALDACS]; \
- \
- unsigned short ai_cmd2; \
- \
- unsigned short ao_conf[MAX_N_AO_CHAN]; \
- unsigned short ao_mode1; \
- unsigned short ao_mode2; \
- unsigned short ao_mode3; \
- unsigned short ao_cmd1; \
- unsigned short ao_cmd2; \
- unsigned short ao_cmd3; \
- unsigned short ao_trigger_select; \
- \
- struct ni_gpct_device *counter_dev; \
- unsigned short an_trig_etc_reg; \
- \
- unsigned ai_offset[512]; \
- \
- unsigned long serial_interval_ns; \
- unsigned char serial_hw_mode; \
- unsigned short clock_and_fout; \
- unsigned short clock_and_fout2; \
- \
- unsigned short int_a_enable_reg; \
- unsigned short int_b_enable_reg; \
- unsigned short io_bidirection_pin_reg; \
- unsigned short rtsi_trig_direction_reg; \
- unsigned short rtsi_trig_a_output_reg; \
- unsigned short rtsi_trig_b_output_reg; \
- unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
- unsigned short ai_ao_select_reg; \
- unsigned short g0_g1_select_reg; \
- unsigned short cdio_dma_select_reg; \
- \
- unsigned clock_ns; \
- unsigned clock_source; \
- \
- unsigned short atrig_mode; \
- unsigned short atrig_high; \
- unsigned short atrig_low; \
- \
- unsigned short pwm_up_count; \
- unsigned short pwm_down_count; \
- \
- unsigned short ai_fifo_buffer[0x2000]; \
- uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
- uint32_t serial_number; \
- \
- struct mite_struct *mite; \
- struct mite_channel *ai_mite_chan; \
- struct mite_channel *ao_mite_chan;\
- struct mite_channel *cdo_mite_chan;\
- struct mite_dma_descriptor_ring *ai_mite_ring; \
- struct mite_dma_descriptor_ring *ao_mite_ring; \
- struct mite_dma_descriptor_ring *cdo_mite_ring; \
+#define MAX_N_CALDACS 34
+#define MAX_N_AO_CHAN 8
+#define NUM_GPCT 2
+
+struct ni_private {
+ unsigned short dio_output;
+ unsigned short dio_control;
+ int aimode;
+ unsigned int ai_calib_source;
+ unsigned int ai_calib_source_enabled;
+ spinlock_t window_lock;
+ spinlock_t soft_reg_copy_lock;
+ spinlock_t mite_channel_lock;
+
+ int changain_state;
+ unsigned int changain_spec;
+
+ unsigned int caldac_maxdata_list[MAX_N_CALDACS];
+ unsigned short ao[MAX_N_AO_CHAN];
+ unsigned short caldacs[MAX_N_CALDACS];
+
+ unsigned short ai_cmd2;
+
+ unsigned short ao_conf[MAX_N_AO_CHAN];
+ unsigned short ao_mode1;
+ unsigned short ao_mode2;
+ unsigned short ao_mode3;
+ unsigned short ao_cmd1;
+ unsigned short ao_cmd2;
+ unsigned short ao_trigger_select;
+
+ struct ni_gpct_device *counter_dev;
+ unsigned short an_trig_etc_reg;
+
+ unsigned ai_offset[512];
+
+ unsigned long serial_interval_ns;
+ unsigned char serial_hw_mode;
+ unsigned short clock_and_fout;
+ unsigned short clock_and_fout2;
+
+ unsigned short int_a_enable_reg;
+ unsigned short int_b_enable_reg;
+ unsigned short io_bidirection_pin_reg;
+ unsigned short rtsi_trig_direction_reg;
+ unsigned short rtsi_trig_a_output_reg;
+ unsigned short rtsi_trig_b_output_reg;
+ unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS];
+ unsigned short ai_ao_select_reg;
+ unsigned short g0_g1_select_reg;
+ unsigned short cdio_dma_select_reg;
+
+ unsigned clock_ns;
+ unsigned clock_source;
+
+ unsigned short pwm_up_count;
+ unsigned short pwm_down_count;
+
+ unsigned short ai_fifo_buffer[0x2000];
+ uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE];
+ uint32_t serial_number;
+
+ struct mite_struct *mite;
+ struct mite_channel *ai_mite_chan;
+ struct mite_channel *ao_mite_chan;
+ struct mite_channel *cdo_mite_chan;
+ struct mite_dma_descriptor_ring *ai_mite_ring;
+ struct mite_dma_descriptor_ring *ao_mite_ring;
+ struct mite_dma_descriptor_ring *cdo_mite_ring;
struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
+ /* ni_pcimio board type flags (based on the boardinfo reg_type) */
+ unsigned int is_m_series:1;
+ unsigned int is_6xxx:1;
+ unsigned int is_611x:1;
+ unsigned int is_6143:1;
+ unsigned int is_622x:1;
+ unsigned int is_625x:1;
+ unsigned int is_628x:1;
+ unsigned int is_67xx:1;
+ unsigned int is_6711:1;
+ unsigned int is_6713:1;
+};
+
#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
index 92691b491c24..0525292c1d8b 100644
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -49,363 +49,336 @@ TODO:
#include "ni_tio_internal.h"
-static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
- unsigned generic_clock_source);
-static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
+/*
+ * clock sources for ni e and m series boards,
+ * get bits with GI_SRC_SEL()
+ */
+#define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */
+#define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
+#define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x)))
+#define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */
+#define NI_M_NEXT_TC_CLK 0x13
+#define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */
+#define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */
+#define NI_M_PXI10_CLK 0x1d
+#define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */
+#define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */
+#define NI_M_LOGIC_LOW_CLK 0x1f
+#define NI_M_MAX_PFI_CHAN 15
+#define NI_M_MAX_RTSI_CHAN 7
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
- ni_gpct_variant
- variant)
+/*
+ * clock sources for ni_660x boards,
+ * get bits with GI_SRC_SEL()
+ */
+#define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */
+#define NI_660X_SRC_PIN_I_CLK 0x1
+#define NI_660X_SRC_PIN_CLK(x) (0x2 + (x))
+#define NI_660X_NEXT_GATE_CLK 0xa
+#define NI_660X_RTSI_CLK(x) (0xb + (x))
+#define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */
+#define NI_660X_NEXT_TC_CLK 0x13
+#define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */
+#define NI_660X_LOGIC_LOW_CLK 0x1f
+#define NI_660X_MAX_SRC_PIN 7
+#define NI_660X_MAX_RTSI_CHAN 6
+
+/* ni m series gate_select */
+#define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0
+#define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
+#define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x)))
+#define NI_M_AI_START2_GATE_SEL 0x12
+#define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13
+#define NI_M_NEXT_OUT_GATE_SEL 0x14
+#define NI_M_AI_START1_GATE_SEL 0x1c
+#define NI_M_NEXT_SRC_GATE_SEL 0x1d
+#define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e
+#define NI_M_LOGIC_LOW_GATE_SEL 0x1f
+
+/* ni_660x gate select */
+#define NI_660X_SRC_PIN_I_GATE_SEL 0x0
+#define NI_660X_GATE_PIN_I_GATE_SEL 0x1
+#define NI_660X_PIN_GATE_SEL(x) (0x2 + (x))
+#define NI_660X_NEXT_SRC_GATE_SEL 0xa
+#define NI_660X_RTSI_GATE_SEL(x) (0xb + (x))
+#define NI_660X_NEXT_OUT_GATE_SEL 0x14
+#define NI_660X_LOGIC_LOW_GATE_SEL 0x1f
+#define NI_660X_MAX_GATE_PIN 7
+
+/* ni_660x second gate select */
+#define NI_660X_SRC_PIN_I_GATE2_SEL 0x0
+#define NI_660X_UD_PIN_I_GATE2_SEL 0x1
+#define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x))
+#define NI_660X_NEXT_SRC_GATE2_SEL 0xa
+#define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x))
+#define NI_660X_NEXT_OUT_GATE2_SEL 0x14
+#define NI_660X_SELECTED_GATE2_SEL 0x1e
+#define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f
+#define NI_660X_MAX_UP_DOWN_PIN 7
+
+static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Alternate_Sync_Bit;
- break;
+ return GI_M_ALT_SYNC;
case ni_gpct_variant_660x:
- return Gi_660x_Alternate_Sync_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_ALT_SYNC;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Prescale_X2_Bit;
- break;
+ return GI_M_PRESCALE_X2;
case ni_gpct_variant_660x:
- return Gi_660x_Prescale_X2_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_PRESCALE_X2;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Prescale_X8_Bit;
- break;
+ return GI_M_PRESCALE_X8;
case ni_gpct_variant_660x:
- return Gi_660x_Prescale_X8_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_PRESCALE_X8;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_HW_Arm_Select_Mask;
- break;
+ return GI_M_HW_ARM_SEL_MASK;
case ni_gpct_variant_660x:
- return Gi_660x_HW_Arm_Select_Mask;
- break;
- default:
- BUG();
- break;
+ return GI_660X_HW_ARM_SEL_MASK;
}
- return 0;
}
-/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */
-enum ni_660x_clock_source {
- NI_660x_Timebase_1_Clock = 0x0, /* 20MHz */
- NI_660x_Source_Pin_i_Clock = 0x1,
- NI_660x_Next_Gate_Clock = 0xa,
- NI_660x_Timebase_2_Clock = 0x12, /* 100KHz */
- NI_660x_Next_TC_Clock = 0x13,
- NI_660x_Timebase_3_Clock = 0x1e, /* 80MHz */
- NI_660x_Logic_Low_Clock = 0x1f,
-};
-static const unsigned ni_660x_max_rtsi_channel = 6;
-static inline unsigned NI_660x_RTSI_Clock(unsigned n)
+static int ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
-}
-
-static const unsigned ni_660x_max_source_pin = 7;
-static inline unsigned NI_660x_Source_Pin_Clock(unsigned n)
-{
- BUG_ON(n > ni_660x_max_source_pin);
- return 0x2 + n;
-}
-
-/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */
-enum ni_m_series_clock_source {
- NI_M_Series_Timebase_1_Clock = 0x0, /* 20MHz */
- NI_M_Series_Timebase_2_Clock = 0x12, /* 100KHz */
- NI_M_Series_Next_TC_Clock = 0x13,
- NI_M_Series_Next_Gate_Clock = 0x14, /* when Gi_Src_SubSelect = 0 */
- NI_M_Series_PXI_Star_Trigger_Clock = 0x14, /* when Gi_Src_SubSelect = 1 */
- NI_M_Series_PXI10_Clock = 0x1d,
- NI_M_Series_Timebase_3_Clock = 0x1e, /* 80MHz, when Gi_Src_SubSelect = 0 */
- NI_M_Series_Analog_Trigger_Out_Clock = 0x1e, /* when Gi_Src_SubSelect = 1 */
- NI_M_Series_Logic_Low_Clock = 0x1f,
-};
-static const unsigned ni_m_series_max_pfi_channel = 15;
-static inline unsigned NI_M_Series_PFI_Clock(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_pfi_channel);
- if (n < 10)
- return 1 + n;
- else
- return 0xb + n;
-}
-
-static const unsigned ni_m_series_max_rtsi_channel = 7;
-static inline unsigned NI_M_Series_RTSI_Clock(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_rtsi_channel);
- if (n == 7)
- return 0x1b;
- else
- return 0xb + n;
-}
-
-enum ni_660x_gate_select {
- NI_660x_Source_Pin_i_Gate_Select = 0x0,
- NI_660x_Gate_Pin_i_Gate_Select = 0x1,
- NI_660x_Next_SRC_Gate_Select = 0xa,
- NI_660x_Next_Out_Gate_Select = 0x14,
- NI_660x_Logic_Low_Gate_Select = 0x1f,
-};
-static const unsigned ni_660x_max_gate_pin = 7;
-static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_gate_pin);
- return 0x2 + n;
-}
-
-static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
-}
-
-enum ni_m_series_gate_select {
- NI_M_Series_Timestamp_Mux_Gate_Select = 0x0,
- NI_M_Series_AI_START2_Gate_Select = 0x12,
- NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13,
- NI_M_Series_Next_Out_Gate_Select = 0x14,
- NI_M_Series_AI_START1_Gate_Select = 0x1c,
- NI_M_Series_Next_SRC_Gate_Select = 0x1d,
- NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e,
- NI_M_Series_Logic_Low_Gate_Select = 0x1f,
-};
-static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_rtsi_channel);
- if (n == 7)
- return 0x1b;
- return 0xb + n;
-}
-
-static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_pfi_channel);
- if (n < 10)
- return 1 + n;
- return 0xb + n;
-}
-
-static inline unsigned Gi_Source_Select_Bits(unsigned source)
-{
- return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask;
-}
-
-static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select)
-{
- return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask;
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ default:
+ return 0;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ }
}
-enum ni_660x_second_gate_select {
- NI_660x_Source_Pin_i_Second_Gate_Select = 0x0,
- NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1,
- NI_660x_Next_SRC_Second_Gate_Select = 0xa,
- NI_660x_Next_Out_Second_Gate_Select = 0x14,
- NI_660x_Selected_Gate_Second_Gate_Select = 0x1e,
- NI_660x_Logic_Low_Second_Gate_Select = 0x1f,
-};
-static const unsigned ni_660x_max_up_down_pin = 7;
-static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n)
+static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
{
- BUG_ON(n > ni_660x_max_up_down_pin);
- return 0x2 + n;
-}
+ unsigned cidx = counter->counter_index;
-static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
+ write_register(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx));
}
-static const unsigned int counter_status_mask =
- COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
-
-struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev,
- void (*write_register) (struct
- ni_gpct
- *
- counter,
- unsigned
- bits,
- enum
- ni_gpct_register
- reg),
- unsigned (*read_register)
- (struct ni_gpct *counter,
- enum ni_gpct_register reg),
- enum ni_gpct_variant variant,
- unsigned num_counters)
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source)
{
- unsigned i;
+ uint64_t clock_period_ps;
- struct ni_gpct_device *counter_dev =
- kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
- if (counter_dev == NULL)
- return NULL;
- counter_dev->dev = dev;
- counter_dev->write_register = write_register;
- counter_dev->read_register = read_register;
- counter_dev->variant = variant;
- spin_lock_init(&counter_dev->regs_lock);
- BUG_ON(num_counters == 0);
- counter_dev->counters =
- kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
- if (counter_dev->counters == NULL) {
- kfree(counter_dev);
- return NULL;
- }
- for (i = 0; i < num_counters; ++i) {
- counter_dev->counters[i].counter_dev = counter_dev;
- spin_lock_init(&counter_dev->counters[i].lock);
+ switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ clock_period_ps = 50000;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ clock_period_ps = 10000000;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ clock_period_ps = 12500;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ clock_period_ps = 100000;
+ break;
+ default:
+ /*
+ * clock period is specified by user with prescaling
+ * already taken into account.
+ */
+ return counter->clock_period_ps;
}
- counter_dev->num_counters = num_counters;
- return counter_dev;
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
-
-void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
-{
- if (counter_dev->counters == NULL)
- return;
- kfree(counter_dev->counters);
- kfree(counter_dev);
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
-static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
- *counter_dev)
-{
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- return 0;
+ switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
break;
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- return 1;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ clock_period_ps *= 2;
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ clock_period_ps *= 8;
break;
default:
BUG();
break;
}
- return 0;
+ return clock_period_ps;
}
-static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
+static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ const unsigned counting_mode_bits =
+ ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
+ unsigned bits = 0;
- write_register(counter, Gi_Reset_Bit(cidx), NITIO_RESET_REG(cidx));
+ if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
+ GI_SRC_POL_INVERT)
+ bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+ if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
+ if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
+ return bits;
}
-void ni_tio_init_counter(struct ni_gpct *counter)
+static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
+ unsigned clock_source = 0;
+ unsigned src;
+ unsigned i;
- ni_tio_reset_count_and_disarm(counter);
-
- /* initialize counter registers */
- counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_AUTO_INC_REG(cidx)],
- NITIO_AUTO_INC_REG(cidx));
-
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- ~0, Gi_Synchronize_Gate_Bit);
-
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
-
- counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_LOADA_REG(cidx)],
- NITIO_LOADA_REG(cidx));
+ src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
- counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_LOADB_REG(cidx)],
- NITIO_LOADB_REG(cidx));
+ switch (src) {
+ case NI_M_TIMEBASE_1_CLK:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_M_TIMEBASE_2_CLK:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_M_TIMEBASE_3_CLK:
+ if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
+ clock_source =
+ NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_M_LOGIC_LOW_CLK:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_M_NEXT_GATE_CLK:
+ if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
+ clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_M_PXI10_CLK:
+ clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
+ break;
+ case NI_M_NEXT_TC_CLK:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (src == NI_M_RTSI_CLK(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_M_MAX_RTSI_CHAN)
+ break;
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (src == NI_M_PFI_CLK(i)) {
+ clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_M_MAX_PFI_CHAN)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
+static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
+{
+ unsigned clock_source = 0;
+ unsigned cidx = counter->counter_index;
+ unsigned src;
+ unsigned i;
- if (ni_tio_counting_mode_registers_present(counter_dev))
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
+ src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
- if (ni_tio_second_gate_registers_present(counter_dev)) {
- counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
- write_register(counter,
- counter_dev->regs[NITIO_GATE2_REG(cidx)],
- NITIO_GATE2_REG(cidx));
+ switch (src) {
+ case NI_660X_TIMEBASE_1_CLK:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_TIMEBASE_2_CLK:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_TIMEBASE_3_CLK:
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_LOGIC_LOW_CLK:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_SRC_PIN_I_CLK:
+ clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_NEXT_GATE_CLK:
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_NEXT_TC_CLK:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (src == NI_660X_RTSI_CLK(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_660X_MAX_RTSI_CHAN)
+ break;
+ for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
+ if (src == NI_660X_SRC_PIN_CLK(i)) {
+ clock_source =
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_660X_MAX_SRC_PIN)
+ break;
+ BUG();
+ break;
}
-
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
-
- ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
}
-EXPORT_SYMBOL_GPL(ni_tio_init_counter);
-static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
{
- unsigned cidx = counter->counter_index;
- const unsigned bits = read_register(counter,
- NITIO_SHARED_STATUS_REG(cidx));
- unsigned int status = 0;
-
- if (bits & Gi_Armed_Bit(cidx)) {
- status |= COMEDI_COUNTER_ARMED;
- if (bits & Gi_Counting_Bit(cidx))
- status |= COMEDI_COUNTER_COUNTING;
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ default:
+ return ni_m_series_clock_src_select(counter);
+ case ni_gpct_variant_660x:
+ return ni_660x_clock_src_select(counter);
}
- return status;
}
static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
@@ -414,34 +387,40 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
unsigned cidx = counter->counter_index;
const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx);
static const uint64_t min_normal_sync_period_ps = 25000;
- const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
- ni_tio_generic_clock_src_select
- (counter));
+ unsigned mode;
+ uint64_t clock_period_ps;
if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
return;
- switch (ni_tio_get_soft_copy(counter, counting_mode_reg) & Gi_Counting_Mode_Mask) {
- case Gi_Counting_Mode_QuadratureX1_Bits:
- case Gi_Counting_Mode_QuadratureX2_Bits:
- case Gi_Counting_Mode_QuadratureX4_Bits:
- case Gi_Counting_Mode_Sync_Source_Bits:
+ mode = ni_tio_get_soft_copy(counter, counting_mode_reg);
+ switch (mode & GI_CNT_MODE_MASK) {
+ case GI_CNT_MODE_QUADX1:
+ case GI_CNT_MODE_QUADX2:
+ case GI_CNT_MODE_QUADX4:
+ case GI_CNT_MODE_SYNC_SRC:
force_alt_sync = 1;
break;
default:
break;
}
- /* It's not clear what we should do if clock_period is unknown, so we are not
- using the alt sync bit in that case, but allow the caller to decide by using the
- force_alt_sync parameter. */
+
+ clock_period_ps = ni_tio_clock_period_ps(counter,
+ ni_tio_generic_clock_src_select(counter));
+
+ /*
+ * It's not clear what we should do if clock_period is unknown, so we
+ * are not using the alt sync bit in that case, but allow the caller
+ * to decide by using the force_alt_sync parameter.
+ */
if (force_alt_sync ||
(clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) {
ni_tio_set_bits(counter, counting_mode_reg,
- Gi_Alternate_Sync_Bit(counter_dev->variant),
- Gi_Alternate_Sync_Bit(counter_dev->variant));
+ GI_ALT_SYNC(counter_dev->variant),
+ GI_ALT_SYNC(counter_dev->variant));
} else {
ni_tio_set_bits(counter, counting_mode_reg,
- Gi_Alternate_Sync_Bit(counter_dev->variant),
+ GI_ALT_SYNC(counter_dev->variant),
0x0);
}
}
@@ -460,18 +439,18 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
- mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
+ mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING;
mode_reg_values = mode & mode_reg_direct_mask;
switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
break;
case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
- mode_reg_values |= Gi_Reload_Source_Switching_Bit;
+ mode_reg_values |= GI_RELOAD_SRC_SWITCHING;
break;
case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
- input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
- mode_reg_mask |= Gi_Gating_Mode_Mask;
- mode_reg_values |= Gi_Level_Gating_Bits;
+ input_select_bits |= GI_GATE_SEL_LOAD_SRC;
+ mode_reg_mask |= GI_GATING_MODE_MASK;
+ mode_reg_values |= GI_LEVEL_GATING;
break;
default:
break;
@@ -480,33 +459,28 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
mode_reg_mask, mode_reg_values);
if (ni_tio_counting_mode_registers_present(counter_dev)) {
- unsigned counting_mode_bits = 0;
- counting_mode_bits |=
- (mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
- Gi_Counting_Mode_Mask;
- counting_mode_bits |=
- ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
- Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
+ unsigned bits = 0;
+
+ bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT);
+ bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT));
if (mode & NI_GPCT_INDEX_ENABLE_BIT)
- counting_mode_bits |= Gi_Index_Mode_Bit;
+ bits |= GI_INDEX_MODE;
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
- Gi_Index_Mode_Bit, counting_mode_bits);
+ GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK |
+ GI_INDEX_MODE, bits);
ni_tio_set_sync_mode(counter, 0);
}
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Up_Down_Mask,
- (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) <<
- Gi_Up_Down_Shift);
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK,
+ GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT));
if (mode & NI_GPCT_OR_GATE_BIT)
- input_select_bits |= Gi_Or_Gate_Bit;
+ input_select_bits |= GI_OR_GATE;
if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
- input_select_bits |= Gi_Output_Polarity_Bit;
+ input_select_bits |= GI_OUTPUT_POL_INVERT;
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
- Gi_Output_Polarity_Bit, input_select_bits);
+ GI_GATE_SEL_LOAD_SRC | GI_OR_GATE |
+ GI_OUTPUT_POL_INVERT, input_select_bits);
return 0;
}
@@ -520,16 +494,19 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
if (arm) {
switch (start_trigger) {
case NI_GPCT_ARM_IMMEDIATE:
- command_transient_bits |= Gi_Arm_Bit;
+ command_transient_bits |= GI_ARM;
break;
case NI_GPCT_ARM_PAIRED_IMMEDIATE:
- command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
+ command_transient_bits |= GI_ARM | GI_ARM_COPY;
break;
default:
break;
}
if (ni_tio_counting_mode_registers_present(counter_dev)) {
- unsigned counting_mode_bits = 0;
+ unsigned bits = 0;
+ unsigned sel_mask;
+
+ sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant);
switch (start_trigger) {
case NI_GPCT_ARM_IMMEDIATE:
@@ -537,29 +514,24 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
break;
default:
if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
- /* pass-through the least significant bits so we can figure out what select later */
- unsigned hw_arm_select_bits =
- (start_trigger <<
- Gi_HW_Arm_Select_Shift) &
- Gi_HW_Arm_Select_Mask
- (counter_dev->variant);
-
- counting_mode_bits |=
- Gi_HW_Arm_Enable_Bit |
- hw_arm_select_bits;
+ /*
+ * pass-through the least significant
+ * bits so we can figure out what
+ * select later
+ */
+ bits |= GI_HW_ARM_ENA |
+ (GI_HW_ARM_SEL(start_trigger) &
+ sel_mask);
} else {
return -EINVAL;
}
break;
}
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_HW_Arm_Select_Mask
- (counter_dev->variant) |
- Gi_HW_Arm_Enable_Bit,
- counting_mode_bits);
+ GI_HW_ARM_ENA | sel_mask, bits);
}
} else {
- command_transient_bits |= Gi_Disarm_Bit;
+ command_transient_bits |= GI_DISARM;
}
ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
0, 0, command_transient_bits);
@@ -567,118 +539,116 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
}
EXPORT_SYMBOL_GPL(ni_tio_arm);
-static unsigned ni_660x_source_select_bits(unsigned int clock_source)
+static unsigned ni_660x_clk_src(unsigned int clock_source)
{
+ unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
unsigned ni_660x_clock;
unsigned i;
- const unsigned clock_select_bits =
- clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- switch (clock_select_bits) {
+ switch (clk_src) {
case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_1_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_1_CLK;
break;
case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_2_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_2_CLK;
break;
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_3_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_3_CLK;
break;
case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Logic_Low_Clock;
+ ni_660x_clock = NI_660X_LOGIC_LOW_CLK;
break;
case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Source_Pin_i_Clock;
+ ni_660x_clock = NI_660X_SRC_PIN_I_CLK;
break;
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Next_Gate_Clock;
+ ni_660x_clock = NI_660X_NEXT_GATE_CLK;
break;
case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Next_TC_Clock;
+ ni_660x_clock = NI_660X_NEXT_TC_CLK;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660x_RTSI_Clock(i);
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660X_RTSI_CLK(i);
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_source_pin; ++i) {
- if (clock_select_bits ==
- NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660x_Source_Pin_Clock(i);
+ for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
+ if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660X_SRC_PIN_CLK(i);
break;
}
}
- if (i <= ni_660x_max_source_pin)
+ if (i <= NI_660X_MAX_SRC_PIN)
break;
ni_660x_clock = 0;
BUG();
break;
}
- return Gi_Source_Select_Bits(ni_660x_clock);
+ return GI_SRC_SEL(ni_660x_clock);
}
-static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
+static unsigned ni_m_clk_src(unsigned int clock_source)
{
+ unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
unsigned ni_m_series_clock;
unsigned i;
- const unsigned clock_select_bits =
- clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- switch (clock_select_bits) {
+
+ switch (clk_src) {
case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_1_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_1_CLK;
break;
case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_2_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_2_CLK;
break;
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_3_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_3_CLK;
break;
case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Logic_Low_Clock;
+ ni_m_series_clock = NI_M_LOGIC_LOW_CLK;
break;
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Next_Gate_Clock;
+ ni_m_series_clock = NI_M_NEXT_GATE_CLK;
break;
case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Next_TC_Clock;
+ ni_m_series_clock = NI_M_NEXT_TC_CLK;
break;
case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_PXI10_Clock;
+ ni_m_series_clock = NI_M_PXI10_CLK;
break;
case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock;
+ ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK;
break;
case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock;
+ ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK;
break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_Series_RTSI_Clock(i);
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_RTSI_CLK(i);
break;
}
}
- if (i <= ni_m_series_max_rtsi_channel)
+ if (i <= NI_M_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_Series_PFI_Clock(i);
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_PFI_CLK(i);
break;
}
}
- if (i <= ni_m_series_max_pfi_channel)
+ if (i <= NI_M_MAX_PFI_CHAN)
break;
- printk(KERN_ERR "invalid clock source 0x%lx\n",
+ pr_err("invalid clock source 0x%lx\n",
(unsigned long)clock_source);
BUG();
ni_m_series_clock = 0;
break;
}
- return Gi_Source_Select_Bits(ni_m_series_clock);
+ return GI_SRC_SEL(ni_m_series_clock);
};
static void ni_tio_set_source_subselect(struct ni_gpct *counter,
@@ -694,17 +664,16 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter,
/* Gi_Source_Subselect is zero */
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit;
+ counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL;
break;
/* Gi_Source_Subselect is one */
case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit;
+ counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL;
break;
/* Gi_Source_Subselect doesn't matter */
default:
return;
- break;
}
write_register(counter, counter_dev->regs[second_gate_reg],
second_gate_reg);
@@ -716,344 +685,109 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- unsigned input_select_bits = 0;
- static const uint64_t pico_per_nano = 1000;
+ unsigned bits = 0;
-/*FIXME: validate clock source */
+ /* FIXME: validate clock source */
switch (counter_dev->variant) {
case ni_gpct_variant_660x:
- input_select_bits |= ni_660x_source_select_bits(clock_source);
+ bits |= ni_660x_clk_src(clock_source);
break;
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- input_select_bits |=
- ni_m_series_source_select_bits(clock_source);
- break;
default:
- BUG();
+ bits |= ni_m_clk_src(clock_source);
break;
}
if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
- input_select_bits |= Gi_Source_Polarity_Bit;
+ bits |= GI_SRC_POL_INVERT;
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
- input_select_bits);
+ GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits);
ni_tio_set_source_subselect(counter, clock_source);
- if (ni_tio_counting_mode_registers_present(counter_dev)) {
- const unsigned prescaling_mode =
- clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
- unsigned counting_mode_bits = 0;
- switch (prescaling_mode) {
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ bits = 0;
+ switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
break;
case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- counting_mode_bits |=
- Gi_Prescale_X2_Bit(counter_dev->variant);
+ bits |= GI_PRESCALE_X2(counter_dev->variant);
break;
case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- counting_mode_bits |=
- Gi_Prescale_X8_Bit(counter_dev->variant);
+ bits |= GI_PRESCALE_X8(counter_dev->variant);
break;
default:
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_Prescale_X2_Bit(counter_dev->variant) |
- Gi_Prescale_X8_Bit(counter_dev->variant),
- counting_mode_bits);
+ GI_PRESCALE_X2(counter_dev->variant) |
+ GI_PRESCALE_X8(counter_dev->variant), bits);
}
- counter->clock_period_ps = pico_per_nano * period_ns;
+ counter->clock_period_ps = period_ns * 1000;
ni_tio_set_sync_mode(counter, 0);
return 0;
}
-static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned cidx = counter->counter_index;
- const unsigned counting_mode_bits =
- ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
- unsigned bits = 0;
-
- if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Polarity_Bit)
- bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
- if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
- if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
- return bits;
-}
-
-static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- unsigned clock_source = 0;
- unsigned i;
- const unsigned input_select =
- (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Select_Mask) >> Gi_Source_Select_Shift;
-
- switch (input_select) {
- case NI_M_Series_Timebase_1_Clock:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Timebase_2_Clock:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Timebase_3_Clock:
- if (counter_dev->regs[second_gate_reg] &
- Gi_Source_Subselect_Bit)
- clock_source =
- NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Logic_Low_Clock:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Next_Gate_Clock:
- if (counter_dev->regs[second_gate_reg] &
- Gi_Source_Subselect_Bit)
- clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_PXI10_Clock:
- clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Next_TC_Clock:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (input_select == NI_M_Series_RTSI_Clock(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_m_series_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (input_select == NI_M_Series_PFI_Clock(i)) {
- clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_m_series_max_pfi_channel)
- break;
- BUG();
- break;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- return clock_source;
-}
-
-static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
-{
- unsigned clock_source = 0;
- unsigned cidx = counter->counter_index;
- const unsigned input_select =
- (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Select_Mask) >> Gi_Source_Select_Shift;
- unsigned i;
-
- switch (input_select) {
- case NI_660x_Timebase_1_Clock:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_660x_Timebase_2_Clock:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_660x_Timebase_3_Clock:
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_660x_Logic_Low_Clock:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_660x_Source_Pin_i_Clock:
- clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
- break;
- case NI_660x_Next_Gate_Clock:
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_660x_Next_TC_Clock:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (input_select == NI_660x_RTSI_Clock(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_source_pin; ++i) {
- if (input_select == NI_660x_Source_Pin_Clock(i)) {
- clock_source =
- NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_660x_max_source_pin)
- break;
- BUG();
- break;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- return clock_source;
-}
-
-static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
-{
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- return ni_m_series_clock_src_select(counter);
- break;
- case ni_gpct_variant_660x:
- return ni_660x_clock_src_select(counter);
- break;
- default:
- BUG();
- break;
- }
- return 0;
-}
-
-static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
- unsigned generic_clock_source)
-{
- uint64_t clock_period_ps;
-
- switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
- case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- clock_period_ps = 50000;
- break;
- case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- clock_period_ps = 10000000;
- break;
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- clock_period_ps = 12500;
- break;
- case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- clock_period_ps = 100000;
- break;
- default:
- /* clock period is specified by user with prescaling already taken into account. */
- return counter->clock_period_ps;
- break;
- }
-
- switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
- case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
- break;
- case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- clock_period_ps *= 2;
- break;
- case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- clock_period_ps *= 8;
- break;
- default:
- BUG();
- break;
- }
- return clock_period_ps;
-}
-
static void ni_tio_get_clock_src(struct ni_gpct *counter,
unsigned int *clock_source,
unsigned int *period_ns)
{
- static const unsigned pico_per_nano = 1000;
uint64_t temp64;
+
*clock_source = ni_tio_generic_clock_src_select(counter);
temp64 = ni_tio_clock_period_ps(counter, *clock_source);
- do_div(temp64, pico_per_nano);
+ do_div(temp64, 1000); /* ps to ns */
*period_ns = temp64;
}
-static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
- const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
+ unsigned int chan = CR_CHAN(gate_source);
unsigned cidx = counter->counter_index;
- unsigned mode_values = 0;
-
- if (gate_source & CR_INVERT)
- mode_values |= Gi_Gate_Polarity_Bit;
- if (gate_source & CR_EDGE)
- mode_values |= Gi_Rising_Edge_Gating_Bits;
- else
- mode_values |= Gi_Level_Gating_Bits;
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
- mode_mask, mode_values);
-}
-
-static int ni_660x_set_first_gate(struct ni_gpct *counter,
- unsigned int gate_source)
-{
- const unsigned selected_gate = CR_CHAN(gate_source);
- unsigned cidx = counter->counter_index;
- /* bits of selected_gate that may be meaningful to input select register */
- const unsigned selected_gate_mask = 0x1f;
- unsigned ni_660x_gate_select;
+ unsigned gate_sel;
unsigned i;
- switch (selected_gate) {
+ switch (chan) {
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select;
+ gate_sel = NI_660X_NEXT_SRC_GATE_SEL;
break;
case NI_GPCT_NEXT_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
case NI_GPCT_GATE_PIN_i_GATE_SELECT:
- ni_660x_gate_select = selected_gate & selected_gate_mask;
+ gate_sel = chan & 0x1f;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_660x_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
- if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
- ni_660x_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
+ if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_gate_pin)
+ if (i <= NI_660X_MAX_GATE_PIN)
break;
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Mask,
- Gi_Gate_Select_Bits(ni_660x_gate_select));
+ GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
return 0;
}
-static int ni_m_series_set_first_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
- const unsigned selected_gate = CR_CHAN(gate_source);
+ unsigned int chan = CR_CHAN(gate_source);
unsigned cidx = counter->counter_index;
- /* bits of selected_gate that may be meaningful to input select register */
- const unsigned selected_gate_mask = 0x1f;
- unsigned ni_m_series_gate_select;
+ unsigned gate_sel;
unsigned i;
- switch (selected_gate) {
+ switch (chan) {
case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
case NI_GPCT_AI_START2_GATE_SELECT:
case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
@@ -1062,120 +796,99 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter,
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- ni_m_series_gate_select = selected_gate & selected_gate_mask;
+ gate_sel = chan & 0x1f;
break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_m_series_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_m_series_max_rtsi_channel)
+ if (i <= NI_M_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) {
- ni_m_series_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (chan == NI_GPCT_PFI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_m_series_max_pfi_channel)
+ if (i <= NI_M_MAX_PFI_CHAN)
break;
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Mask,
- Gi_Gate_Select_Bits(ni_m_series_gate_select));
+ GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
return 0;
}
-static int ni_660x_set_second_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- const unsigned selected_second_gate = CR_CHAN(gate_source);
- /* bits of second_gate that may be meaningful to second gate register */
- static const unsigned selected_second_gate_mask = 0x1f;
- unsigned ni_660x_second_gate_select;
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate2_sel;
unsigned i;
- switch (selected_second_gate) {
+ switch (chan) {
case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
case NI_GPCT_SELECTED_GATE_GATE_SELECT:
case NI_GPCT_NEXT_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- ni_660x_second_gate_select =
- selected_second_gate & selected_second_gate_mask;
+ gate2_sel = chan & 0x1f;
break;
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- ni_660x_second_gate_select =
- NI_660x_Next_SRC_Second_Gate_Select;
+ gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_660x_second_gate_select =
- selected_second_gate &
- selected_second_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate2_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
- if (selected_second_gate ==
- NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
- ni_660x_second_gate_select =
- selected_second_gate &
- selected_second_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
+ if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
+ gate2_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_up_down_pin)
+ if (i <= NI_660X_MAX_UP_DOWN_PIN)
break;
return -EINVAL;
- break;
}
- counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
- counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
- write_register(counter, counter_dev->regs[second_gate_reg],
- second_gate_reg);
+ counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
+ counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
+ write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
return 0;
}
-static int ni_m_series_set_second_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- const unsigned selected_second_gate = CR_CHAN(gate_source);
- /* bits of second_gate that may be meaningful to second gate register */
- static const unsigned selected_second_gate_mask = 0x1f;
- unsigned ni_m_series_second_gate_select;
-
- /* FIXME: We don't know what the m-series second gate codes are, so we'll just pass
- the bits through for now. */
- switch (selected_second_gate) {
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate2_sel;
+
+ /*
+ * FIXME: We don't know what the m-series second gate codes are,
+ * so we'll just pass the bits through for now.
+ */
+ switch (chan) {
default:
- ni_m_series_second_gate_select =
- selected_second_gate & selected_second_gate_mask;
+ gate2_sel = chan & 0x1f;
break;
}
- counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
- counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
- write_register(counter, counter_dev->regs[second_gate_reg],
- second_gate_reg);
+ counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
+ counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
+ write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
return 0;
}
@@ -1184,56 +897,55 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned mode = 0;
switch (gate_index) {
case 0:
- if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
- Gi_Gating_Mode_Mask,
- Gi_Gating_Disabled_Bits);
+ GI_GATING_MODE_MASK,
+ GI_GATING_DISABLED);
return 0;
}
- ni_tio_set_first_gate_modifiers(counter, gate_source);
+ if (gate_source & CR_INVERT)
+ mode |= GI_GATE_POL_INVERT;
+ if (gate_source & CR_EDGE)
+ mode |= GI_RISING_EDGE_GATING;
+ else
+ mode |= GI_LEVEL_GATING;
+ ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
+ GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
+ mode);
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- return ni_m_series_set_first_gate(counter, gate_source);
- break;
- case ni_gpct_variant_660x:
- return ni_660x_set_first_gate(counter, gate_source);
- break;
default:
- BUG();
- break;
+ return ni_m_set_gate(counter, gate_source);
+ case ni_gpct_variant_660x:
+ return ni_660x_set_gate(counter, gate_source);
}
break;
case 1:
- if (ni_tio_second_gate_registers_present(counter_dev) == 0)
+ if (!ni_tio_has_gate2_registers(counter_dev))
return -EINVAL;
- if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
- counter_dev->regs[second_gate_reg] &=
- ~Gi_Second_Gate_Mode_Bit;
- write_register(counter,
- counter_dev->regs[second_gate_reg],
- second_gate_reg);
+
+ if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE;
+ write_register(counter, counter_dev->regs[gate2_reg],
+ gate2_reg);
return 0;
}
- if (gate_source & CR_INVERT) {
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Polarity_Bit;
- } else {
- counter_dev->regs[second_gate_reg] &=
- ~Gi_Second_Gate_Polarity_Bit;
- }
+ if (gate_source & CR_INVERT)
+ counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT;
+ else
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT;
switch (counter_dev->variant) {
case ni_gpct_variant_m_series:
- return ni_m_series_set_second_gate(counter,
- gate_source);
- break;
+ return ni_m_set_gate2(counter, gate_source);
case ni_gpct_variant_660x:
- return ni_660x_set_second_gate(counter, gate_source);
- break;
+ return ni_660x_set_gate2(counter, gate_source);
default:
BUG();
break;
@@ -1241,7 +953,6 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
break;
default:
return -EINVAL;
- break;
}
return 0;
}
@@ -1252,196 +963,142 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ unsigned int abz_reg, shift, mask;
- if (counter_dev->variant == ni_gpct_variant_m_series) {
- unsigned int abz_reg, shift, mask;
+ if (counter_dev->variant != ni_gpct_variant_m_series)
+ return -EINVAL;
- abz_reg = NITIO_ABZ_REG(cidx);
- switch (index) {
- case NI_GPCT_SOURCE_ENCODER_A:
- shift = 10;
- break;
- case NI_GPCT_SOURCE_ENCODER_B:
- shift = 5;
- break;
- case NI_GPCT_SOURCE_ENCODER_Z:
- shift = 0;
- break;
- default:
- return -EINVAL;
- break;
- }
- mask = 0x1f << shift;
- if (source > 0x1f) {
- /* Disable gate */
- source = 0x1f;
- }
- counter_dev->regs[abz_reg] &= ~mask;
- counter_dev->regs[abz_reg] |= (source << shift) & mask;
- write_register(counter, counter_dev->regs[abz_reg], abz_reg);
- return 0;
+ abz_reg = NITIO_ABZ_REG(cidx);
+ switch (index) {
+ case NI_GPCT_SOURCE_ENCODER_A:
+ shift = 10;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_B:
+ shift = 5;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_Z:
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
}
- return -EINVAL;
+ mask = 0x1f << shift;
+ if (source > 0x1f)
+ source = 0x1f; /* Disable gate */
+
+ counter_dev->regs[abz_reg] &= ~mask;
+ counter_dev->regs[abz_reg] |= (source << shift) & mask;
+ write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+ return 0;
}
-static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
- ni_660x_gate_select)
+static unsigned ni_660x_gate_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_660x_gate_select) {
- case NI_660x_Source_Pin_i_Gate_Select:
+ switch (gate) {
+ case NI_660X_SRC_PIN_I_GATE_SEL:
return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Gate_Pin_i_Gate_Select:
+ case NI_660X_GATE_PIN_I_GATE_SEL:
return NI_GPCT_GATE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Next_SRC_Gate_Select:
+ case NI_660X_NEXT_SRC_GATE_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660x_Next_Out_Gate_Select:
+ case NI_660X_NEXT_OUT_GATE_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660x_Logic_Low_Gate_Select:
+ case NI_660X_LOGIC_LOW_GATE_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_660X_RTSI_GATE_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_Gate_Pin_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
+ if (gate == NI_660X_PIN_GATE_SEL(i))
return NI_GPCT_GATE_PIN_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_gate_pin)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
- ni_m_series_gate_select)
+static unsigned ni_m_gate_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_m_series_gate_select) {
- case NI_M_Series_Timestamp_Mux_Gate_Select:
+ switch (gate) {
+ case NI_M_TIMESTAMP_MUX_GATE_SEL:
return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
- break;
- case NI_M_Series_AI_START2_Gate_Select:
+ case NI_M_AI_START2_GATE_SEL:
return NI_GPCT_AI_START2_GATE_SELECT;
- break;
- case NI_M_Series_PXI_Star_Trigger_Gate_Select:
+ case NI_M_PXI_STAR_TRIGGER_GATE_SEL:
return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
- break;
- case NI_M_Series_Next_Out_Gate_Select:
+ case NI_M_NEXT_OUT_GATE_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_M_Series_AI_START1_Gate_Select:
+ case NI_M_AI_START1_GATE_SEL:
return NI_GPCT_AI_START1_GATE_SELECT;
- break;
- case NI_M_Series_Next_SRC_Gate_Select:
+ case NI_M_NEXT_SRC_GATE_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_M_Series_Analog_Trigger_Out_Gate_Select:
+ case NI_M_ANALOG_TRIG_OUT_GATE_SEL:
return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
- break;
- case NI_M_Series_Logic_Low_Gate_Select:
+ case NI_M_LOGIC_LOW_GATE_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (ni_m_series_gate_select ==
- NI_M_Series_RTSI_Gate_Select(i)) {
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_M_RTSI_GATE_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_m_series_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (ni_m_series_gate_select ==
- NI_M_Series_PFI_Gate_Select(i)) {
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (gate == NI_M_PFI_GATE_SEL(i))
return NI_GPCT_PFI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_m_series_max_pfi_channel)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
- ni_660x_gate_select)
+static unsigned ni_660x_gate2_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_660x_gate_select) {
- case NI_660x_Source_Pin_i_Second_Gate_Select:
+ switch (gate) {
+ case NI_660X_SRC_PIN_I_GATE2_SEL:
return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Up_Down_Pin_i_Second_Gate_Select:
+ case NI_660X_UD_PIN_I_GATE2_SEL:
return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Next_SRC_Second_Gate_Select:
+ case NI_660X_NEXT_SRC_GATE2_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660x_Next_Out_Second_Gate_Select:
+ case NI_660X_NEXT_OUT_GATE2_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660x_Selected_Gate_Second_Gate_Select:
+ case NI_660X_SELECTED_GATE2_SEL:
return NI_GPCT_SELECTED_GATE_GATE_SELECT;
- break;
- case NI_660x_Logic_Low_Second_Gate_Select:
+ case NI_660X_LOGIC_LOW_GATE2_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_RTSI_Second_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_660X_RTSI_GATE2_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
+ if (gate == NI_660X_UD_PIN_GATE2_SEL(i))
return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_up_down_pin)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
- ni_m_series_gate_select)
+static unsigned ni_m_gate2_to_generic_gate(unsigned gate)
{
- /*FIXME: the second gate sources for the m series are undocumented, so we just return
- * the raw bits for now. */
- switch (ni_m_series_gate_select) {
+ /*
+ * FIXME: the second gate sources for the m series are undocumented,
+ * so we just return the raw bits for now.
+ */
+ switch (gate) {
default:
- return ni_m_series_gate_select;
- break;
+ return gate;
}
return 0;
};
@@ -1451,84 +1108,62 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned mode_bits =
- ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- unsigned gate_select_bits;
+ unsigned mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate;
switch (gate_index) {
case 0:
- if ((mode_bits & Gi_Gating_Mode_Mask) ==
- Gi_Gating_Disabled_Bits) {
+ if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) {
*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
return 0;
- } else {
- gate_select_bits =
- (ni_tio_get_soft_copy(counter,
- NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift;
}
+
+ gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- *gate_source =
- ni_m_series_first_gate_to_generic_gate_source
- (gate_select_bits);
+ default:
+ *gate_source = ni_m_gate_to_generic_gate(gate);
break;
case ni_gpct_variant_660x:
- *gate_source =
- ni_660x_first_gate_to_generic_gate_source
- (gate_select_bits);
- break;
- default:
- BUG();
+ *gate_source = ni_660x_gate_to_generic_gate(gate);
break;
}
- if (mode_bits & Gi_Gate_Polarity_Bit)
+ if (mode & GI_GATE_POL_INVERT)
*gate_source |= CR_INVERT;
- if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
+ if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
*gate_source |= CR_EDGE;
break;
case 1:
- if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
- || (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Mode_Bit)
- == 0) {
+ if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED ||
+ !(counter_dev->regs[gate2_reg] & GI_GATE2_MODE)) {
*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
return 0;
- } else {
- gate_select_bits =
- (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Select_Mask) >>
- Gi_Second_Gate_Select_Shift;
}
+
+ gate = GI_BITS_TO_GATE2(counter_dev->regs[gate2_reg]);
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- *gate_source =
- ni_m_series_second_gate_to_generic_gate_source
- (gate_select_bits);
+ default:
+ *gate_source = ni_m_gate2_to_generic_gate(gate);
break;
case ni_gpct_variant_660x:
- *gate_source =
- ni_660x_second_gate_to_generic_gate_source
- (gate_select_bits);
- break;
- default:
- BUG();
+ *gate_source = ni_660x_gate2_to_generic_gate(gate);
break;
}
- if (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Polarity_Bit) {
+ if (counter_dev->regs[gate2_reg] & GI_GATE2_POL_INVERT)
*gate_source |= CR_INVERT;
- }
/* second gate can't have edge/level mode set independently */
- if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
+ if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
*gate_source |= CR_EDGE;
break;
default:
return -EINVAL;
- break;
}
return 0;
}
@@ -1539,43 +1174,41 @@ int ni_tio_insn_config(struct comedi_device *dev,
unsigned int *data)
{
struct ni_gpct *counter = s->private;
+ unsigned cidx = counter->counter_index;
+ unsigned status;
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
return ni_tio_set_counter_mode(counter, data[1]);
- break;
case INSN_CONFIG_ARM:
return ni_tio_arm(counter, 1, data[1]);
- break;
case INSN_CONFIG_DISARM:
ni_tio_arm(counter, 0, 0);
return 0;
- break;
case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = ni_tio_counter_status(counter);
- data[2] = counter_status_mask;
+ data[1] = 0;
+ status = read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
+ if (status & GI_ARMED(cidx)) {
+ data[1] |= COMEDI_COUNTER_ARMED;
+ if (status & GI_COUNTING(cidx))
+ data[1] |= COMEDI_COUNTER_COUNTING;
+ }
+ data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
return 0;
- break;
case INSN_CONFIG_SET_CLOCK_SRC:
return ni_tio_set_clock_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_GET_CLOCK_SRC:
ni_tio_get_clock_src(counter, &data[1], &data[2]);
return 0;
- break;
case INSN_CONFIG_SET_GATE_SRC:
return ni_tio_set_gate_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_GET_GATE_SRC:
return ni_tio_get_gate_src(counter, data[1], &data[2]);
- break;
case INSN_CONFIG_SET_OTHER_SRC:
return ni_tio_set_other_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_RESET:
ni_tio_reset_count_and_disarm(counter);
return 0;
- break;
default:
break;
}
@@ -1583,6 +1216,33 @@ int ni_tio_insn_config(struct comedi_device *dev,
}
EXPORT_SYMBOL_GPL(ni_tio_insn_config);
+static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ unsigned cidx = counter->counter_index;
+ unsigned int val;
+
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
+ GI_SAVE_TRACE, GI_SAVE_TRACE);
+
+ /*
+ * The count doesn't get latched until the next clock edge, so it is
+ * possible the count may change (once) while we are reading. Since
+ * the read of the SW_Save_Reg isn't atomic (apparently even when it's
+ * a 32 bit register according to 660x docs), we need to read twice
+ * and make sure the reading hasn't changed. If it has, a third read
+ * will be correct since the count value will definitely have latched
+ * by then.
+ */
+ val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
+ if (val != read_register(counter, NITIO_SW_SAVE_REG(cidx)))
+ val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
+
+ return val;
+}
+
int ni_tio_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -1590,43 +1250,24 @@ int ni_tio_insn_read(struct comedi_device *dev,
{
struct ni_gpct *counter = s->private;
struct ni_gpct_device *counter_dev = counter->counter_dev;
- const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned int channel = CR_CHAN(insn->chanspec);
unsigned cidx = counter->counter_index;
- unsigned first_read;
- unsigned second_read;
- unsigned correct_read;
+ int i;
- if (insn->n < 1)
- return 0;
- switch (channel) {
- case 0:
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Save_Trace_Bit, 0);
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Save_Trace_Bit, Gi_Save_Trace_Bit);
- /* The count doesn't get latched until the next clock edge, so it is possible the count
- may change (once) while we are reading. Since the read of the SW_Save_Reg isn't
- atomic (apparently even when it's a 32 bit register according to 660x docs),
- we need to read twice and make sure the reading hasn't changed. If it has,
- a third read will be correct since the count value will definitely have latched by then. */
- first_read = read_register(counter, NITIO_SW_SAVE_REG(cidx));
- second_read = read_register(counter, NITIO_SW_SAVE_REG(cidx));
- if (first_read != second_read)
- correct_read =
- read_register(counter, NITIO_SW_SAVE_REG(cidx));
- else
- correct_read = first_read;
- data[0] = correct_read;
- return 0;
- break;
- case 1:
- data[0] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
- break;
- case 2:
- data[0] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
- break;
+ for (i = 0; i < insn->n; i++) {
+ switch (channel) {
+ case 0:
+ data[i] = ni_tio_read_sw_save_reg(dev, s);
+ break;
+ case 1:
+ data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
+ break;
+ case 2:
+ data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
+ break;
+ }
}
- return 0;
+ return insn->n;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_read);
@@ -1636,10 +1277,9 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
const unsigned bits =
read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
- if (bits & Gi_Next_Load_Source_Bit(cidx))
- return NITIO_LOADB_REG(cidx);
- else
- return NITIO_LOADA_REG(cidx);
+ return (bits & GI_NEXT_LOAD_SRC(cidx))
+ ? NITIO_LOADB_REG(cidx)
+ : NITIO_LOADA_REG(cidx);
}
int ni_tio_insn_write(struct comedi_device *dev,
@@ -1657,13 +1297,20 @@ int ni_tio_insn_write(struct comedi_device *dev,
return 0;
switch (channel) {
case 0:
- /* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */
- /* Don't disturb load source select, just use whichever load register is already selected. */
+ /*
+ * Unsafe if counter is armed.
+ * Should probably check status and return -EBUSY if armed.
+ */
+
+ /*
+ * Don't disturb load source select, just use whichever
+ * load register is already selected.
+ */
load_reg = ni_tio_next_load_register(counter);
write_register(counter, data[0], load_reg);
ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
- 0, 0, Gi_Load_Bit);
- /* restore state of load reg to whatever the user set last set it to */
+ 0, 0, GI_LOAD);
+ /* restore load reg */
write_register(counter, counter_dev->regs[load_reg], load_reg);
break;
case 1:
@@ -1676,12 +1323,104 @@ int ni_tio_insn_write(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_write);
+void ni_tio_init_counter(struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned cidx = counter->counter_index;
+
+ ni_tio_reset_count_and_disarm(counter);
+
+ /* initialize counter registers */
+ counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_AUTO_INC_REG(cidx));
+
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
+ ~0, GI_SYNC_GATE);
+
+ ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
+
+ counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_LOADA_REG(cidx));
+
+ counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_LOADB_REG(cidx));
+
+ ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
+
+ if (ni_tio_counting_mode_registers_present(counter_dev))
+ ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
+
+ if (ni_tio_has_gate2_registers(counter_dev)) {
+ counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_GATE2_REG(cidx));
+ }
+
+ ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
+
+ ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
+}
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
+
+struct ni_gpct_device *
+ni_gpct_device_construct(struct comedi_device *dev,
+ void (*write_register)(struct ni_gpct *counter,
+ unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register)(struct ni_gpct *counter,
+ enum ni_gpct_register reg),
+ enum ni_gpct_variant variant,
+ unsigned num_counters)
+{
+ struct ni_gpct_device *counter_dev;
+ struct ni_gpct *counter;
+ unsigned i;
+
+ if (num_counters == 0)
+ return NULL;
+
+ counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
+ if (!counter_dev)
+ return NULL;
+
+ counter_dev->dev = dev;
+ counter_dev->write_register = write_register;
+ counter_dev->read_register = read_register;
+ counter_dev->variant = variant;
+
+ spin_lock_init(&counter_dev->regs_lock);
+
+ counter_dev->counters = kcalloc(num_counters, sizeof(*counter),
+ GFP_KERNEL);
+ if (!counter_dev->counters) {
+ kfree(counter_dev);
+ return NULL;
+ }
+
+ for (i = 0; i < num_counters; ++i) {
+ counter = &counter_dev->counters[i];
+ counter->counter_dev = counter_dev;
+ spin_lock_init(&counter->lock);
+ }
+ counter_dev->num_counters = num_counters;
+
+ return counter_dev;
+}
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
+
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
+{
+ if (!counter_dev->counters)
+ return;
+ kfree(counter_dev->counters);
+ kfree(counter_dev);
+}
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
+
static int __init ni_tio_init_module(void)
{
return 0;
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
index 1056bf001e5e..25aedd0e5867 100644
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -149,8 +149,6 @@ int ni_tio_cmdtest(struct comedi_device *, struct comedi_subdevice *,
int ni_tio_cancel(struct ni_gpct *);
void ni_tio_handle_interrupt(struct ni_gpct *, struct comedi_subdevice *);
void ni_tio_set_mite_channel(struct ni_gpct *, struct mite_channel *);
-void ni_tio_acknowledge_and_confirm(struct ni_gpct *,
- int *gate_error, int *tc_error,
- int *perm_stale_data, int *stale_data);
+void ni_tio_acknowledge(struct ni_gpct *);
#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
index 15b81b8fc5c4..2bceae493e23 100644
--- a/drivers/staging/comedi/drivers/ni_tio_internal.h
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -22,296 +22,139 @@
#include "ni_tio.h"
#define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x))
+#define GI_AUTO_INC_MASK 0xff
#define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x))
+#define GI_ARM (1 << 0)
+#define GI_SAVE_TRACE (1 << 1)
+#define GI_LOAD (1 << 2)
+#define GI_DISARM (1 << 4)
+#define GI_CNT_DIR(x) (((x) & 0x3) << 5)
+#define GI_CNT_DIR_MASK (3 << 5)
+#define GI_WRITE_SWITCH (1 << 7)
+#define GI_SYNC_GATE (1 << 8)
+#define GI_LITTLE_BIG_ENDIAN (1 << 9)
+#define GI_BANK_SWITCH_START (1 << 10)
+#define GI_BANK_SWITCH_MODE (1 << 11)
+#define GI_BANK_SWITCH_ENABLE (1 << 12)
+#define GI_ARM_COPY (1 << 13)
+#define GI_SAVE_TRACE_COPY (1 << 14)
+#define GI_DISARM_COPY (1 << 15)
#define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x))
#define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x))
#define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x))
+#define GI_GATING_DISABLED (0 << 0)
+#define GI_LEVEL_GATING (1 << 0)
+#define GI_RISING_EDGE_GATING (2 << 0)
+#define GI_FALLING_EDGE_GATING (3 << 0)
+#define GI_GATING_MODE_MASK (3 << 0)
+#define GI_GATE_ON_BOTH_EDGES (1 << 2)
+#define GI_EDGE_GATE_STARTS_STOPS (0 << 3)
+#define GI_EDGE_GATE_STOPS_STARTS (1 << 3)
+#define GI_EDGE_GATE_STARTS (2 << 3)
+#define GI_EDGE_GATE_NO_STARTS_OR_STOPS (3 << 3)
+#define GI_EDGE_GATE_MODE_MASK (3 << 3)
+#define GI_STOP_ON_GATE (0 << 5)
+#define GI_STOP_ON_GATE_OR_TC (1 << 5)
+#define GI_STOP_ON_GATE_OR_SECOND_TC (2 << 5)
+#define GI_STOP_MODE_MASK (3 << 5)
+#define GI_LOAD_SRC_SEL (1 << 7)
+#define GI_OUTPUT_TC_PULSE (1 << 8)
+#define GI_OUTPUT_TC_TOGGLE (2 << 8)
+#define GI_OUTPUT_TC_OR_GATE_TOGGLE (3 << 8)
+#define GI_OUTPUT_MODE_MASK (3 << 8)
+#define GI_NO_HARDWARE_DISARM (0 << 10)
+#define GI_DISARM_AT_TC (1 << 10)
+#define GI_DISARM_AT_GATE (2 << 10)
+#define GI_DISARM_AT_TC_OR_GATE (3 << 10)
+#define GI_COUNTING_ONCE_MASK (3 << 10)
+#define GI_LOADING_ON_TC (1 << 12)
+#define GI_GATE_POL_INVERT (1 << 13)
+#define GI_LOADING_ON_GATE (1 << 14)
+#define GI_RELOAD_SRC_SWITCHING (1 << 15)
#define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x))
#define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x))
#define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x))
+#define GI_READ_ACKS_IRQ (1 << 0)
+#define GI_WRITE_ACKS_IRQ (1 << 1)
+#define GI_BITS_TO_SRC(x) (((x) >> 2) & 0x1f)
+#define GI_SRC_SEL(x) (((x) & 0x1f) << 2)
+#define GI_SRC_SEL_MASK (0x1f << 2)
+#define GI_BITS_TO_GATE(x) (((x) >> 7) & 0x1f)
+#define GI_GATE_SEL(x) (((x) & 0x1f) << 7)
+#define GI_GATE_SEL_MASK (0x1f << 7)
+#define GI_GATE_SEL_LOAD_SRC (1 << 12)
+#define GI_OR_GATE (1 << 13)
+#define GI_OUTPUT_POL_INVERT (1 << 14)
+#define GI_SRC_POL_INVERT (1 << 15)
#define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x))
+#define GI_CNT_MODE(x) (((x) & 0x7) << 0)
+#define GI_CNT_MODE_NORMAL GI_CNT_MODE(0)
+#define GI_CNT_MODE_QUADX1 GI_CNT_MODE(1)
+#define GI_CNT_MODE_QUADX2 GI_CNT_MODE(2)
+#define GI_CNT_MODE_QUADX4 GI_CNT_MODE(3)
+#define GI_CNT_MODE_TWO_PULSE GI_CNT_MODE(4)
+#define GI_CNT_MODE_SYNC_SRC GI_CNT_MODE(6)
+#define GI_CNT_MODE_MASK (7 << 0)
+#define GI_INDEX_MODE (1 << 4)
+#define GI_INDEX_PHASE(x) (((x) & 0x3) << 5)
+#define GI_INDEX_PHASE_MASK (3 << 5)
+#define GI_HW_ARM_ENA (1 << 7)
+#define GI_HW_ARM_SEL(x) ((x) << 8)
+#define GI_660X_HW_ARM_SEL_MASK (0x7 << 8)
+#define GI_M_HW_ARM_SEL_MASK (0x1f << 8)
+#define GI_660X_PRESCALE_X8 (1 << 12)
+#define GI_M_PRESCALE_X8 (1 << 13)
+#define GI_660X_ALT_SYNC (1 << 13)
+#define GI_M_ALT_SYNC (1 << 14)
+#define GI_660X_PRESCALE_X2 (1 << 14)
+#define GI_M_PRESCALE_X2 (1 << 15)
#define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x))
+#define GI_GATE2_MODE (1 << 0)
+#define GI_BITS_TO_GATE2(x) (((x) >> 7) & 0x1f)
+#define GI_GATE2_SEL(x) (((x) & 0x1f) << 7)
+#define GI_GATE2_SEL_MASK (0x1f << 7)
+#define GI_GATE2_POL_INVERT (1 << 13)
+#define GI_GATE2_SUBSEL (1 << 14)
+#define GI_SRC_SUBSEL (1 << 15)
#define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2))
+#define GI_SAVE(x) (((x) % 2) ? (1 << 1) : (1 << 0))
+#define GI_COUNTING(x) (((x) % 2) ? (1 << 3) : (1 << 2))
+#define GI_NEXT_LOAD_SRC(x) (((x) % 2) ? (1 << 5) : (1 << 4))
+#define GI_STALE_DATA(x) (((x) % 2) ? (1 << 7) : (1 << 6))
+#define GI_ARMED(x) (((x) % 2) ? (1 << 9) : (1 << 8))
+#define GI_NO_LOAD_BETWEEN_GATES(x) (((x) % 2) ? (1 << 11) : (1 << 10))
+#define GI_TC_ERROR(x) (((x) % 2) ? (1 << 13) : (1 << 12))
+#define GI_GATE_ERROR(x) (((x) % 2) ? (1 << 15) : (1 << 14))
#define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2))
+#define GI_RESET(x) (1 << (2 + ((x) % 2)))
#define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2))
#define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2))
+#define GI_OUTPUT(x) (((x) % 2) ? (1 << 1) : (1 << 0))
+#define GI_HW_SAVE(x) (((x) % 2) ? (1 << 13) : (1 << 12))
+#define GI_PERMANENT_STALE(x) (((x) % 2) ? (1 << 15) : (1 << 14))
#define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x))
+#define GI_DMA_ENABLE (1 << 0)
+#define GI_DMA_WRITE (1 << 1)
+#define GI_DMA_INT_ENA (1 << 2)
+#define GI_DMA_RESET (1 << 3)
+#define GI_DMA_BANKSW_ERROR (1 << 4)
#define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x))
+#define GI_DMA_READBANK (1 << 13)
+#define GI_DRQ_ERROR (1 << 14)
+#define GI_DRQ_STATUS (1 << 15)
#define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x))
#define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x))
+#define GI_GATE_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 1) : (1 << 5))
+#define GI_TC_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 2) : (1 << 6))
+#define GI_TC_INTERRUPT_ACK (1 << 14)
+#define GI_GATE_INTERRUPT_ACK (1 << 15)
#define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x))
+#define GI_GATE_INTERRUPT (1 << 2)
+#define GI_TC (1 << 3)
+#define GI_INTERRUPT (1 << 15)
#define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x))
-
-enum Gi_Auto_Increment_Reg_Bits {
- Gi_Auto_Increment_Mask = 0xff
-};
-
-#define Gi_Up_Down_Shift 5
-enum Gi_Command_Reg_Bits {
- Gi_Arm_Bit = 0x1,
- Gi_Save_Trace_Bit = 0x2,
- Gi_Load_Bit = 0x4,
- Gi_Disarm_Bit = 0x10,
- Gi_Up_Down_Mask = 0x3 << Gi_Up_Down_Shift,
- Gi_Always_Down_Bits = 0x0 << Gi_Up_Down_Shift,
- Gi_Always_Up_Bits = 0x1 << Gi_Up_Down_Shift,
- Gi_Up_Down_Hardware_IO_Bits = 0x2 << Gi_Up_Down_Shift,
- Gi_Up_Down_Hardware_Gate_Bits = 0x3 << Gi_Up_Down_Shift,
- Gi_Write_Switch_Bit = 0x80,
- Gi_Synchronize_Gate_Bit = 0x100,
- Gi_Little_Big_Endian_Bit = 0x200,
- Gi_Bank_Switch_Start_Bit = 0x400,
- Gi_Bank_Switch_Mode_Bit = 0x800,
- Gi_Bank_Switch_Enable_Bit = 0x1000,
- Gi_Arm_Copy_Bit = 0x2000,
- Gi_Save_Trace_Copy_Bit = 0x4000,
- Gi_Disarm_Copy_Bit = 0x8000
-};
-
-#define Gi_Index_Phase_Bitshift 5
-#define Gi_HW_Arm_Select_Shift 8
-enum Gi_Counting_Mode_Reg_Bits {
- Gi_Counting_Mode_Mask = 0x7,
- Gi_Counting_Mode_Normal_Bits = 0x0,
- Gi_Counting_Mode_QuadratureX1_Bits = 0x1,
- Gi_Counting_Mode_QuadratureX2_Bits = 0x2,
- Gi_Counting_Mode_QuadratureX4_Bits = 0x3,
- Gi_Counting_Mode_Two_Pulse_Bits = 0x4,
- Gi_Counting_Mode_Sync_Source_Bits = 0x6,
- Gi_Index_Mode_Bit = 0x10,
- Gi_Index_Phase_Mask = 0x3 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_LowA_LowB = 0x0 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_HW_Arm_Enable_Bit = 0x80,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift,
- Gi_660x_Prescale_X8_Bit = 0x1000,
- Gi_M_Series_Prescale_X8_Bit = 0x2000,
- Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift,
- /* must be set for clocks over 40MHz, which includes synchronous
- * counting and quadrature modes */
- Gi_660x_Alternate_Sync_Bit = 0x2000,
- Gi_M_Series_Alternate_Sync_Bit = 0x4000,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_660x_Prescale_X2_Bit = 0x4000,
- Gi_M_Series_Prescale_X2_Bit = 0x8000,
-};
-
-#define Gi_Source_Select_Shift 2
-#define Gi_Gate_Select_Shift 7
-enum Gi_Input_Select_Bits {
- Gi_Read_Acknowledges_Irq = 0x1, /* not present on 660x */
- Gi_Write_Acknowledges_Irq = 0x2, /* not present on 660x */
- Gi_Source_Select_Mask = 0x7c,
- Gi_Gate_Select_Mask = 0x1f << Gi_Gate_Select_Shift,
- Gi_Gate_Select_Load_Source_Bit = 0x1000,
- Gi_Or_Gate_Bit = 0x2000,
- Gi_Output_Polarity_Bit = 0x4000, /* set to invert */
- Gi_Source_Polarity_Bit = 0x8000 /* set to invert */
-};
-
-enum Gi_Mode_Bits {
- Gi_Gating_Mode_Mask = 0x3,
- Gi_Gating_Disabled_Bits = 0x0,
- Gi_Level_Gating_Bits = 0x1,
- Gi_Rising_Edge_Gating_Bits = 0x2,
- Gi_Falling_Edge_Gating_Bits = 0x3,
- Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with
- * rising edge gating mode */
- Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18,
- Gi_Edge_Gate_Starts_Stops_Bits = 0x0,
- Gi_Edge_Gate_Stops_Starts_Bits = 0x8,
- Gi_Edge_Gate_Starts_Bits = 0x10,
- Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18,
- Gi_Stop_Mode_Mask = 0x60,
- Gi_Stop_on_Gate_Bits = 0x00,
- Gi_Stop_on_Gate_or_TC_Bits = 0x20,
- Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40,
- Gi_Load_Source_Select_Bit = 0x80,
- Gi_Output_Mode_Mask = 0x300,
- Gi_Output_TC_Pulse_Bits = 0x100,
- Gi_Output_TC_Toggle_Bits = 0x200,
- Gi_Output_TC_or_Gate_Toggle_Bits = 0x300,
- Gi_Counting_Once_Mask = 0xc00,
- Gi_No_Hardware_Disarm_Bits = 0x000,
- Gi_Disarm_at_TC_Bits = 0x400,
- Gi_Disarm_at_Gate_Bits = 0x800,
- Gi_Disarm_at_TC_or_Gate_Bits = 0xc00,
- Gi_Loading_On_TC_Bit = 0x1000,
- Gi_Gate_Polarity_Bit = 0x2000,
- Gi_Loading_On_Gate_Bit = 0x4000,
- Gi_Reload_Source_Switching_Bit = 0x8000
-};
-
-#define Gi_Second_Gate_Select_Shift 7
-/*FIXME: m-series has a second gate subselect bit */
-/*FIXME: m-series second gate sources are undocumented (by NI)*/
-enum Gi_Second_Gate_Bits {
- Gi_Second_Gate_Mode_Bit = 0x1,
- Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift,
- Gi_Second_Gate_Polarity_Bit = 0x2000,
- Gi_Second_Gate_Subselect_Bit = 0x4000, /* m-series only */
- Gi_Source_Subselect_Bit = 0x8000 /* m-series only */
-};
-static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select)
-{
- return (second_gate_select << Gi_Second_Gate_Select_Shift) &
- Gi_Second_Gate_Select_Mask;
-}
-
-enum Gxx_Status_Bits {
- G0_Save_Bit = 0x1,
- G1_Save_Bit = 0x2,
- G0_Counting_Bit = 0x4,
- G1_Counting_Bit = 0x8,
- G0_Next_Load_Source_Bit = 0x10,
- G1_Next_Load_Source_Bit = 0x20,
- G0_Stale_Data_Bit = 0x40,
- G1_Stale_Data_Bit = 0x80,
- G0_Armed_Bit = 0x100,
- G1_Armed_Bit = 0x200,
- G0_No_Load_Between_Gates_Bit = 0x400,
- G1_No_Load_Between_Gates_Bit = 0x800,
- G0_TC_Error_Bit = 0x1000,
- G1_TC_Error_Bit = 0x2000,
- G0_Gate_Error_Bit = 0x4000,
- G1_Gate_Error_Bit = 0x8000
-};
-static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Counting_Bit;
- return G0_Counting_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Armed_Bit;
- return G0_Armed_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned
- counter_index)
-{
- if (counter_index % 2)
- return G1_Next_Load_Source_Bit;
- return G0_Next_Load_Source_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Stale_Data_Bit;
- return G0_Stale_Data_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_TC_Error_Bit;
- return G0_TC_Error_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Gate_Error_Bit;
- return G0_Gate_Error_Bit;
-}
-
-/* joint reset register bits */
-static inline unsigned Gi_Reset_Bit(unsigned counter_index)
-{
- return 0x1 << (2 + (counter_index % 2));
-}
-
-enum Gxx_Joint_Status2_Bits {
- G0_Output_Bit = 0x1,
- G1_Output_Bit = 0x2,
- G0_HW_Save_Bit = 0x1000,
- G1_HW_Save_Bit = 0x2000,
- G0_Permanent_Stale_Bit = 0x4000,
- G1_Permanent_Stale_Bit = 0x8000
-};
-static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
- counter_index)
-{
- if (counter_index % 2)
- return G1_Permanent_Stale_Bit;
- return G0_Permanent_Stale_Bit;
-}
-
-enum Gi_DMA_Config_Reg_Bits {
- Gi_DMA_Enable_Bit = 0x1,
- Gi_DMA_Write_Bit = 0x2,
- Gi_DMA_Int_Bit = 0x4
-};
-
-enum Gi_DMA_Status_Reg_Bits {
- Gi_DMA_Readbank_Bit = 0x2000,
- Gi_DRQ_Error_Bit = 0x4000,
- Gi_DRQ_Status_Bit = 0x8000
-};
-
-enum G02_Interrupt_Acknowledge_Bits {
- G0_Gate_Error_Confirm_Bit = 0x20,
- G0_TC_Error_Confirm_Bit = 0x40
-};
-enum G13_Interrupt_Acknowledge_Bits {
- G1_Gate_Error_Confirm_Bit = 0x2,
- G1_TC_Error_Confirm_Bit = 0x4
-};
-static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Gate_Error_Confirm_Bit;
- return G0_Gate_Error_Confirm_Bit;
-}
-
-static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_TC_Error_Confirm_Bit;
- return G0_TC_Error_Confirm_Bit;
-}
-
-/* bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers */
-enum Gxx_Interrupt_Acknowledge_Bits {
- Gi_TC_Interrupt_Ack_Bit = 0x4000,
- Gi_Gate_Interrupt_Ack_Bit = 0x8000
-};
-
-enum Gi_Status_Bits {
- Gi_Gate_Interrupt_Bit = 0x4,
- Gi_TC_Bit = 0x8,
- Gi_Interrupt_Bit = 0x8000
-};
-
-enum G02_Interrupt_Enable_Bits {
- G0_TC_Interrupt_Enable_Bit = 0x40,
- G0_Gate_Interrupt_Enable_Bit = 0x100
-};
-enum G13_Interrupt_Enable_Bits {
- G1_TC_Interrupt_Enable_Bit = 0x200,
- G1_Gate_Interrupt_Enable_Bit = 0x400
-};
-static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
-{
- unsigned bit;
-
- if (counter_index % 2)
- bit = G1_Gate_Interrupt_Enable_Bit;
- else
- bit = G0_Gate_Interrupt_Enable_Bit;
- return bit;
-}
+#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 9) : (1 << 6))
+#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 10) : (1 << 8))
static inline void write_register(struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg)
@@ -334,11 +177,9 @@ static inline int ni_tio_counting_mode_registers_present(const struct
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
return 0;
- break;
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
return 1;
- break;
default:
BUG();
break;
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 2557ab48cb6c..299ceddfb233 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -49,40 +49,38 @@ TODO:
#include "ni_tio_internal.h"
#include "mite.h"
-static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
- short read_not_write)
+static void ni_tio_configure_dma(struct ni_gpct *counter,
+ bool enable, bool read)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- unsigned input_select_bits = 0;
+ unsigned mask;
+ unsigned bits;
+
+ mask = GI_READ_ACKS_IRQ | GI_WRITE_ACKS_IRQ;
+ bits = 0;
if (enable) {
- if (read_not_write)
- input_select_bits |= Gi_Read_Acknowledges_Irq;
+ if (read)
+ bits |= GI_READ_ACKS_IRQ;
else
- input_select_bits |= Gi_Write_Acknowledges_Irq;
+ bits |= GI_WRITE_ACKS_IRQ;
}
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
- input_select_bits);
+ ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), mask, bits);
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
break;
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
- {
- unsigned gi_dma_config_bits = 0;
-
- if (enable) {
- gi_dma_config_bits |= Gi_DMA_Enable_Bit;
- gi_dma_config_bits |= Gi_DMA_Int_Bit;
- }
- if (read_not_write == 0)
- gi_dma_config_bits |= Gi_DMA_Write_Bit;
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx),
- Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
- Gi_DMA_Write_Bit, gi_dma_config_bits);
- }
+ mask = GI_DMA_ENABLE | GI_DMA_INT_ENA | GI_DMA_WRITE;
+ bits = 0;
+
+ if (enable)
+ bits |= GI_DMA_ENABLE | GI_DMA_INT_ENA;
+ if (!read)
+ bits |= GI_DMA_WRITE;
+ ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), mask, bits);
break;
}
}
@@ -94,9 +92,7 @@ static int ni_tio_input_inttrig(struct comedi_device *dev,
struct ni_gpct *counter = s->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
- int retval = 0;
-
- BUG_ON(counter == NULL);
+ int ret = 0;
if (trig_num != cmd->start_src)
return -EINVAL;
@@ -105,14 +101,14 @@ static int ni_tio_input_inttrig(struct comedi_device *dev,
if (counter->mite_chan)
mite_dma_arm(counter->mite_chan);
else
- retval = -EIO;
+ ret = -EIO;
spin_unlock_irqrestore(&counter->lock, flags);
- if (retval < 0)
- return retval;
- retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ if (ret < 0)
+ return ret;
+ ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
s->async->inttrig = NULL;
- return retval;
+ return ret;
}
static int ni_tio_input_cmd(struct comedi_subdevice *s)
@@ -122,7 +118,7 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
unsigned cidx = counter->counter_index;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- int retval = 0;
+ int ret = 0;
/* write alloc the entire buffer */
comedi_buf_write_alloc(s, async->prealloc_bufsz);
@@ -139,31 +135,21 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
BUG();
break;
}
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0);
- ni_tio_configure_dma(counter, 1, 1);
- switch (cmd->start_src) {
- case TRIG_NOW:
- async->inttrig = NULL;
- mite_dma_arm(counter->mite_chan);
- retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
- break;
- case TRIG_INT:
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
+ ni_tio_configure_dma(counter, true, true);
+
+ if (cmd->start_src == TRIG_INT) {
async->inttrig = &ni_tio_input_inttrig;
- break;
- case TRIG_EXT:
+ } else { /* TRIG_NOW || TRIG_EXT || TRIG_OTHER */
async->inttrig = NULL;
mite_dma_arm(counter->mite_chan);
- retval = ni_tio_arm(counter, 1, cmd->start_arg);
- break;
- case TRIG_OTHER:
- async->inttrig = NULL;
- mite_dma_arm(counter->mite_chan);
- break;
- default:
- BUG();
- break;
+
+ if (cmd->start_src == TRIG_NOW)
+ ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ else if (cmd->start_src == TRIG_EXT)
+ ret = ni_tio_arm(counter, 1, cmd->start_arg);
}
- return retval;
+ return ret;
}
static int ni_tio_output_cmd(struct comedi_subdevice *s)
@@ -176,7 +162,7 @@ static int ni_tio_output_cmd(struct comedi_subdevice *s)
counter->mite_chan->dir = COMEDI_OUTPUT;
mite_prep_dma(counter->mite_chan, 32, 32);
- ni_tio_configure_dma(counter, 1, 0);
+ ni_tio_configure_dma(counter, true, false);
mite_dma_arm(counter->mite_chan);
return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
}
@@ -201,8 +187,8 @@ static int ni_tio_cmd_setup(struct comedi_subdevice *s)
retval = ni_tio_set_gate_src(counter, 0, gate_source);
if (cmd->flags & TRIG_WAKE_EOS) {
ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx));
+ GI_GATE_INTERRUPT_ENABLE(cidx),
+ GI_GATE_INTERRUPT_ENABLE(cidx));
}
return retval;
}
@@ -319,10 +305,10 @@ int ni_tio_cancel(struct ni_gpct *counter)
if (counter->mite_chan)
mite_dma_disarm(counter->mite_chan);
spin_unlock_irqrestore(&counter->lock, flags);
- ni_tio_configure_dma(counter, 0, 0);
+ ni_tio_configure_dma(counter, false, false);
ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx), 0x0);
+ GI_GATE_INTERRUPT_ENABLE(cidx), 0x0);
return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_cancel);
@@ -342,7 +328,6 @@ static int should_ack_gate(struct ni_gpct *counter)
in register-level manual) */
case ni_gpct_variant_660x:
return 1;
- break;
case ni_gpct_variant_e_series:
spin_lock_irqsave(&counter->lock, flags);
{
@@ -358,9 +343,11 @@ static int should_ack_gate(struct ni_gpct *counter)
return retval;
}
-void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
- int *tc_error, int *perm_stale_data,
- int *stale_data)
+static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
+ int *gate_error,
+ int *tc_error,
+ int *perm_stale_data,
+ int *stale_data)
{
unsigned cidx = counter->counter_index;
const unsigned short gxx_status = read_register(counter,
@@ -378,8 +365,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
if (stale_data)
*stale_data = 0;
- if (gxx_status & Gi_Gate_Error_Bit(cidx)) {
- ack |= Gi_Gate_Error_Confirm_Bit(cidx);
+ if (gxx_status & GI_GATE_ERROR(cidx)) {
+ ack |= GI_GATE_ERROR_CONFIRM(cidx);
if (gate_error) {
/*660x don't support automatic acknowledgement
of gate interrupt via dma read/write
@@ -390,27 +377,27 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
}
}
}
- if (gxx_status & Gi_TC_Error_Bit(cidx)) {
- ack |= Gi_TC_Error_Confirm_Bit(cidx);
+ if (gxx_status & GI_TC_ERROR(cidx)) {
+ ack |= GI_TC_ERROR_CONFIRM(cidx);
if (tc_error)
*tc_error = 1;
}
- if (gi_status & Gi_TC_Bit)
- ack |= Gi_TC_Interrupt_Ack_Bit;
- if (gi_status & Gi_Gate_Interrupt_Bit) {
+ if (gi_status & GI_TC)
+ ack |= GI_TC_INTERRUPT_ACK;
+ if (gi_status & GI_GATE_INTERRUPT) {
if (should_ack_gate(counter))
- ack |= Gi_Gate_Interrupt_Ack_Bit;
+ ack |= GI_GATE_INTERRUPT_ACK;
}
if (ack)
write_register(counter, ack, NITIO_INT_ACK_REG(cidx));
if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) &
- Gi_Loading_On_Gate_Bit) {
- if (gxx_status & Gi_Stale_Data_Bit(cidx)) {
+ GI_LOADING_ON_GATE) {
+ if (gxx_status & GI_STALE_DATA(cidx)) {
if (stale_data)
*stale_data = 1;
}
if (read_register(counter, NITIO_STATUS2_REG(cidx)) &
- Gi_Permanent_Stale_Bit(cidx)) {
+ GI_PERMANENT_STALE(cidx)) {
dev_info(counter->counter_dev->dev->class_dev,
"%s: Gi_Permanent_Stale_Data detected.\n",
__func__);
@@ -419,7 +406,12 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
}
}
}
-EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);
+
+void ni_tio_acknowledge(struct ni_gpct *counter)
+{
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(ni_tio_acknowledge);
void ni_tio_handle_interrupt(struct ni_gpct *counter,
struct comedi_subdevice *s)
@@ -444,7 +436,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) &
- Gi_DRQ_Error_Bit) {
+ GI_DRQ_ERROR) {
dev_notice(counter->counter_dev->dev->class_dev,
"%s: Gi_DRQ_Error detected.\n", __func__);
s->async->events |= COMEDI_CB_OVERFLOW;
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index c38d97a9a899..40f9136f0bb6 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -206,7 +206,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d)
unsigned int data;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index 8af13e790ad1..c7f8eb1cf8de 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -15,6 +15,7 @@
* (ADLink) ACL-7124 [acl7124]
* (ADLink) PET-48DIO [pet48dio]
* (WinSystems) PCM-IO48 [pcmio48]
+ * (Diamond Systems) ONYX-MM-DIO [onyx-mm-dio]
* Author: Michal Dobes <dobes@tesnet.cz>
* Status: untested
*
@@ -73,6 +74,10 @@ static const struct pcl724_board boardtypes[] = {
.name = "pcmio48",
.io_range = 0x08,
.numofports = 2, /* 48 DIO channels */
+ }, {
+ .name = "onyx-mm-dio",
+ .io_range = 0x10,
+ .numofports = 2, /* 48 DIO channels */
},
};
@@ -83,14 +88,12 @@ static int pcl724_8255mapped_io(int dir, int port, int data,
iobase &= 0x0fff;
+ outb(port + movport, iobase);
if (dir) {
- outb(port + movport, iobase);
outb(data, iobase + 1);
return 0;
- } else {
- outb(port + movport, iobase);
- return inb(iobase + 1);
}
+ return inb(iobase + 1);
}
static int pcl724_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index 7fb044ce399b..bdce24c42940 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -19,6 +19,7 @@
* (Advantech) PCL-734 [pcl734]
* (Diamond Systems) OPMM-1616-XT [opmm-1616-xt]
* (Diamond Systems) PEARL-MM-P [prearl-mm-p]
+ * (Diamond Systems) IR104-PBF [ir104-pbf]
* Author: José Luis Sánchez (jsanchezv@teleline.es)
* Status: untested
*
@@ -93,6 +94,15 @@
*
* BASE+0 Isolated outputs 0-7 (write)
* BASE+1 Isolated outputs 8-15 (write)
+ *
+ * The ir104-pbf board has this register mapping:
+ *
+ * BASE+0 Isolated outputs 0-7 (write) (read back)
+ * BASE+1 Isolated outputs 8-15 (write) (read back)
+ * BASE+2 Isolated outputs 16-19 (write) (read back)
+ * BASE+4 Isolated inputs 0-7 (read)
+ * BASE+5 Isolated inputs 8-15 (read)
+ * BASE+6 Isolated inputs 16-19 (read)
*/
struct pcl730_board {
@@ -100,6 +110,7 @@ struct pcl730_board {
unsigned int io_range;
unsigned is_pcl725:1;
unsigned is_acl7225b:1;
+ unsigned is_ir104:1;
unsigned has_readback:1;
unsigned has_ttl_io:1;
int n_subdevs;
@@ -194,6 +205,13 @@ static const struct pcl730_board pcl730_boards[] = {
.io_range = 0x02,
.n_subdevs = 1,
.n_iso_out_chan = 16,
+ }, {
+ .name = "ir104-pbf",
+ .io_range = 0x08,
+ .is_ir104 = 1,
+ .has_readback = 1,
+ .n_iso_out_chan = 20,
+ .n_iso_in_chan = 20,
},
};
@@ -292,7 +310,8 @@ static int pcl730_attach(struct comedi_device *dev,
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pcl730_di_insn_bits;
- s->private = board->is_acl7225b ? (void *)2 :
+ s->private = board->is_ir104 ? (void *)4 :
+ board->is_acl7225b ? (void *)2 :
board->is_pcl725 ? (void *)1 : (void *)0;
}
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 4c1b94706478..803e7790538c 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -985,7 +985,7 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static int pcl812_ai_cancel(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index d9ca7fe16c96..54732c5cab97 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -130,10 +130,6 @@ struct pcl816_private {
unsigned int ai_cmd_canceled:1;
};
-static int check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist, unsigned int chanlen);
-
static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters)
{
struct pcl816_private *devpriv = dev->private;
@@ -363,6 +359,62 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
+static int check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist,
+ unsigned int chanlen)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (chanlen < 1) {
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
+ return 0;
+ }
+
+ if (chanlen > 1) {
+ /* first channel is every time ok */
+ chansegment[0] = chanlist[0];
+ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+ /* we detect loop, this must by finish */
+ if (chanlist[0] == chanlist[i])
+ break;
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) {
+ /* channel list isn't continuous :-( */
+ dev_dbg(dev->class_dev,
+ "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
+ i, CR_CHAN(chanlist[i]), nowmustbechan,
+ CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ /* well, this is next correct channel in list */
+ chansegment[i] = chanlist[i];
+ }
+
+ /* check whole chanlist */
+ for (i = 0, segpos = 0; i < chanlen; i++) {
+ if (chanlist[i] != chansegment[i % seglen]) {
+ dev_dbg(dev->class_dev,
+ "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; /* chan/gain list is strange */
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+
+ return seglen; /* we can serve this with MUX logic */
+}
+
static int pcl816_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
@@ -516,7 +568,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
cfc_handle_events(dev, s);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static int pcl816_ai_cancel(struct comedi_device *dev,
@@ -542,62 +594,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
return 0;
}
-static int
-check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int *chanlist,
- unsigned int chanlen)
-{
- unsigned int chansegment[16];
- unsigned int i, nowmustbechan, seglen, segpos;
-
- /* correct channel and range number check itself comedi/range.c */
- if (chanlen < 1) {
- comedi_error(dev, "range/channel list is empty!");
- return 0;
- }
-
- if (chanlen > 1) {
- /* first channel is every time ok */
- chansegment[0] = chanlist[0];
- for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
- /* we detect loop, this must by finish */
- if (chanlist[0] == chanlist[i])
- break;
- nowmustbechan =
- (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
- if (nowmustbechan != CR_CHAN(chanlist[i])) {
- /* channel list isn't continuous :-( */
- dev_dbg(dev->class_dev,
- "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, CR_CHAN(chanlist[i]), nowmustbechan,
- CR_CHAN(chanlist[0]));
- return 0;
- }
- /* well, this is next correct channel in list */
- chansegment[i] = chanlist[i];
- }
-
- /* check whole chanlist */
- for (i = 0, segpos = 0; i < chanlen; i++) {
- if (chanlist[i] != chansegment[i % seglen]) {
- dev_dbg(dev->class_dev,
- "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(chanlist[i % seglen]),
- CR_RANGE(chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return 0; /* chan/gain list is strange */
- }
- }
- } else {
- seglen = 1;
- }
-
- return seglen; /* we can serve this with MUX logic */
-}
-
static int pcl816_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 7d00ae639d38..000dbf841e45 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -551,7 +551,7 @@ static void pcl818_handle_eoc(struct comedi_device *dev,
unsigned int val;
if (pcl818_ai_eoc(dev, s, NULL, 0)) {
- comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
@@ -608,13 +608,14 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
status = inb(dev->iobase + PCL818_FI_STATUS);
if (status & 4) {
- comedi_error(dev, "A/D mode1/3 FIFO overflow!");
+ dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
if (status & 1) {
- comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
+ dev_err(dev->class_dev,
+ "A/D mode1/3 FIFO interrupt without data!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
@@ -682,7 +683,7 @@ static int check_channel_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 53e73737a906..6e0d78f6095b 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -33,7 +33,6 @@ Copy/pasted/hacked from pcm724.c
#include "8255.h"
-#define PCM3724_SIZE 16
#define SIZE_8255 4
#define BUF_C0 0x1
@@ -66,19 +65,6 @@ struct priv_pcm3724 {
int dio_2;
};
-static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
-{
- unsigned long iobase = arg;
- unsigned char inbres;
- if (dir) {
- outb(data, iobase + port);
- return 0;
- } else {
- inbres = inb(iobase + port);
- return inbres;
- }
-}
-
static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
{
/* 1 in io_bits indicates output */
@@ -215,7 +201,7 @@ static int pcm3724_attach(struct comedi_device *dev,
if (!priv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], PCM3724_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
@@ -225,7 +211,7 @@ static int pcm3724_attach(struct comedi_device *dev,
for (i = 0; i < dev->n_subdevices; i++) {
s = &dev->subdevices[i];
- ret = subdev_8255_init(dev, s, subdev_8255_cb,
+ ret = subdev_8255_init(dev, s, NULL,
dev->iobase + SIZE_8255 * i);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 62914bb342d2..1bca3fba0950 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -333,6 +333,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
if (triggered & (1 << chan))
val |= (1 << i);
}
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index b3bbec0a0d23..b1db61d9d834 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -351,7 +351,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev,
* time that the device will use.
*/
-static int daqp_ns_to_timer(unsigned int *ns, int round)
+static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
{
int timer;
@@ -436,13 +436,13 @@ static int daqp_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- daqp_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ daqp_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- daqp_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ daqp_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
}
@@ -488,15 +488,13 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*/
if (cmd->convert_src == TRIG_TIMER) {
- counter = daqp_ns_to_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags);
outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
scanlist_start_on_every_entry = 1;
} else {
- counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index d55c5893203b..6fc4ed33f66c 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -373,7 +373,6 @@ static const struct rtd_boardinfo rtd520Boards[] = {
struct rtd_private {
/* memory mapped board structures */
- void __iomem *las0;
void __iomem *las1;
void __iomem *lcfg;
@@ -397,11 +396,11 @@ struct rtd_private {
Note: you have to check if the value is larger than the counter range!
*/
static int rtd_ns_to_timer_base(unsigned int *nanosec,
- int round_mode, int base)
+ unsigned int flags, int base)
{
int divider;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -428,9 +427,9 @@ static int rtd_ns_to_timer_base(unsigned int *nanosec,
return the proper counter value (divider-1) for the internal clock.
Sets the original period to be the true value.
*/
-static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
+static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
{
- return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
+ return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
}
/*
@@ -490,21 +489,19 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
static void rtd_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
- struct rtd_private *devpriv = dev->private;
-
if (n_chan > 1) { /* setup channel gain table */
int ii;
- writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
- writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
+ writel(0, dev->mmio + LAS0_CGT_CLEAR);
+ writel(1, dev->mmio + LAS0_CGT_ENABLE);
for (ii = 0; ii < n_chan; ii++) {
writel(rtd_convert_chan_gain(dev, list[ii], ii),
- devpriv->las0 + LAS0_CGT_WRITE);
+ dev->mmio + LAS0_CGT_WRITE);
}
} else { /* just use the channel gain latch */
- writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
+ writel(0, dev->mmio + LAS0_CGT_ENABLE);
writel(rtd_convert_chan_gain(dev, list[0], 0),
- devpriv->las0 + LAS0_CGL_WRITE);
+ dev->mmio + LAS0_CGL_WRITE);
}
}
@@ -512,23 +509,22 @@ static void rtd_load_channelgain_list(struct comedi_device *dev,
empty status flag clears */
static int rtd520_probe_fifo_depth(struct comedi_device *dev)
{
- struct rtd_private *devpriv = dev->private;
unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
unsigned i;
static const unsigned limit = 0x2000;
unsigned fifo_size = 0;
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
rtd_load_channelgain_list(dev, 1, &chanspec);
/* ADC conversion trigger source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
/* convert samples */
for (i = 0; i < limit; ++i) {
unsigned fifo_status;
/* trigger conversion */
- writew(0, devpriv->las0 + LAS0_ADC);
+ writew(0, dev->mmio + LAS0_ADC);
udelay(1);
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
if ((fifo_status & FS_ADC_HEMPTY) == 0) {
fifo_size = 2 * i;
break;
@@ -538,7 +534,7 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
dev_info(dev->class_dev, "failed to probe fifo size.\n");
return -EIO;
}
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
if (fifo_size != 0x400 && fifo_size != 0x2000) {
dev_info(dev->class_dev,
"unexpected fifo size of %i, expected 1024 or 8192.\n",
@@ -553,10 +549,9 @@ static int rtd_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct rtd_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->las0 + LAS0_ADC);
+ status = readl(dev->mmio + LAS0_ADC);
if (status & FS_ADC_NOT_EMPTY)
return 0;
return -EBUSY;
@@ -571,19 +566,19 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
int n;
/* clear any old fifo data */
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
/* write channel to multiplexer and clear channel gain table */
rtd_load_channelgain_list(dev, 1, &insn->chanspec);
/* ADC conversion trigger source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
/* convert n samples */
for (n = 0; n < insn->n; n++) {
unsigned short d;
/* trigger conversion */
- writew(0, devpriv->las0 + LAS0_ADC);
+ writew(0, dev->mmio + LAS0_ADC);
ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
if (ret)
@@ -645,7 +640,7 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct rtd_private *devpriv = dev->private;
- while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
+ while (readl(dev->mmio + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO);
if (0 == devpriv->ai_count) { /* done */
@@ -685,12 +680,12 @@ static irqreturn_t rtd_interrupt(int irq, void *d)
if (!dev->attached)
return IRQ_NONE;
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
/* check for FIFO full, this automatically halts the ADC! */
if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
goto xfer_abort;
- status = readw(devpriv->las0 + LAS0_IT);
+ status = readw(dev->mmio + LAS0_IT);
/* if interrupt was not caused by our board, or handled above */
if (0 == status)
return IRQ_HANDLED;
@@ -725,30 +720,30 @@ static irqreturn_t rtd_interrupt(int irq, void *d)
}
}
- overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
if (overrun)
goto xfer_abort;
/* clear the interrupt */
- writew(status, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(status, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
return IRQ_HANDLED;
xfer_abort:
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
s->async->events |= COMEDI_CB_ERROR;
devpriv->ai_count = 0; /* stop and don't transfer any more */
/* fall into xfer_done */
xfer_done:
/* pacer stop source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_STOP);
- writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- writew(0, devpriv->las0 + LAS0_IT);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + LAS0_IT);
if (devpriv->ai_count > 0) { /* there shouldn't be anything left */
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
ai_read_dregs(dev, s); /* read anything left in FIFO */
}
@@ -756,12 +751,12 @@ xfer_done:
comedi_event(dev, s);
/* clear the interrupt */
- status = readw(devpriv->las0 + LAS0_IT);
- writew(status, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ status = readw(dev->mmio + LAS0_IT);
+ writew(status, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
- overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
+ fifo_status = readl(dev->mmio + LAS0_ADC);
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
return IRQ_HANDLED;
}
@@ -895,13 +890,13 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- rtd_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ rtd_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- rtd_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ rtd_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -931,12 +926,12 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* stop anything currently running */
/* pacer stop source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_STOP);
- writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- writew(0, devpriv->las0 + LAS0_IT);
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
- writel(0, devpriv->las0 + LAS0_OVERRUN);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + LAS0_IT);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_OVERRUN);
/* start configuration */
/* load channel list and reset CGT */
@@ -945,18 +940,18 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* setup the common case and override if needed */
if (cmd->chanlist_len > 1) {
/* pacer start source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_START);
+ writel(0, dev->mmio + LAS0_PACER_START);
/* burst trigger source: PACER */
- writel(1, devpriv->las0 + LAS0_BURST_START);
+ writel(1, dev->mmio + LAS0_BURST_START);
/* ADC conversion trigger source: BURST */
- writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(2, dev->mmio + LAS0_ADC_CONVERSION);
} else { /* single channel */
/* pacer start source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_START);
+ writel(0, dev->mmio + LAS0_PACER_START);
/* ADC conversion trigger source: PACER */
- writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(1, dev->mmio + LAS0_ADC_CONVERSION);
}
- writel((devpriv->fifosz / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
+ writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
if (TRIG_TIMER == cmd->scan_begin_src) {
/* scan_begin_arg is in nanoseconds */
@@ -993,16 +988,16 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
} else {
/* interrupt for each transfer */
writel((devpriv->xfer_count - 1) & 0xffff,
- devpriv->las0 + LAS0_ACNT);
+ dev->mmio + LAS0_ACNT);
}
} else { /* unknown timing, just use 1/2 FIFO */
devpriv->xfer_count = 0;
devpriv->flags &= ~SEND_EOS;
}
/* pacer clock source: INTERNAL 8MHz */
- writel(1, devpriv->las0 + LAS0_PACER_SELECT);
+ writel(1, dev->mmio + LAS0_PACER_SELECT);
/* just interrupt, don't stop */
- writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
+ writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
/* BUG??? these look like enumerated values, but they are bit fields */
@@ -1027,13 +1022,13 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
/* set PACER clock */
- writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
+ writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
break;
case TRIG_EXT:
/* pacer start source: EXTERNAL */
- writel(1, devpriv->las0 + LAS0_PACER_START);
+ writel(1, dev->mmio + LAS0_PACER_START);
break;
}
@@ -1045,33 +1040,32 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
timer = rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_NEAREST);
/* setup BURST clock */
- writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
+ writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
}
break;
case TRIG_EXT: /* external */
/* burst trigger source: EXTERNAL */
- writel(2, devpriv->las0 + LAS0_BURST_START);
+ writel(2, dev->mmio + LAS0_BURST_START);
break;
}
/* end configuration */
/* This doesn't seem to work. There is no way to clear an interrupt
that the priority controller has queued! */
- writew(~0, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(~0, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
/* TODO: allow multiple interrupt sources */
- if (devpriv->xfer_count > 0) { /* transfer every N samples */
- writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
- } else { /* 1/2 FIFO transfers */
- writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
- }
+ if (devpriv->xfer_count > 0) /* transfer every N samples */
+ writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
+ else /* 1/2 FIFO transfers */
+ writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
/* BUG: start_src is ASSUMED to be TRIG_NOW */
/* BUG? it seems like things are running before the "start" */
- readl(devpriv->las0 + LAS0_PACER); /* start pacer */
+ readl(dev->mmio + LAS0_PACER); /* start pacer */
return 0;
}
@@ -1085,13 +1079,13 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
u16 status;
/* pacer stop source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_STOP);
- writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- writew(0, devpriv->las0 + LAS0_IT);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + LAS0_IT);
devpriv->ai_count = 0; /* stop and don't transfer any more */
- status = readw(devpriv->las0 + LAS0_IT);
- overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
+ status = readw(dev->mmio + LAS0_IT);
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
return 0;
}
@@ -1100,12 +1094,11 @@ static int rtd_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct rtd_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
unsigned int status;
- status = readl(devpriv->las0 + LAS0_ADC);
+ status = readl(dev->mmio + LAS0_ADC);
if (status & bit)
return 0;
return -EBUSY;
@@ -1122,8 +1115,8 @@ static int rtd_ao_winsn(struct comedi_device *dev,
int ret;
/* Configure the output range (table index matches the range values) */
- writew(range & 7, devpriv->las0 +
- ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
+ writew(range & 7,
+ dev->mmio + ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
@@ -1143,8 +1136,7 @@ static int rtd_ao_winsn(struct comedi_device *dev,
/* a typical programming sequence */
writew(val, devpriv->las1 +
((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
- writew(0, devpriv->las0 +
- ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
+ writew(0, dev->mmio + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
devpriv->ao_readback[chan] = data[i];
@@ -1179,12 +1171,10 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct rtd_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
+ writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
- data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
+ data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
return insn->n;
}
@@ -1194,7 +1184,6 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct rtd_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
@@ -1204,11 +1193,11 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
/* TODO support digital match interrupts and strobes */
/* set direction */
- writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
- writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
+ writew(0x01, dev->mmio + LAS0_DIO_STATUS);
+ writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
/* clear interrupts */
- writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
+ writew(0x00, dev->mmio + LAS0_DIO_STATUS);
/* port1 can only be all input or all output */
@@ -1221,12 +1210,12 @@ static void rtd_reset(struct comedi_device *dev)
{
struct rtd_private *devpriv = dev->private;
- writel(0, devpriv->las0 + LAS0_BOARD_RESET);
+ writel(0, dev->mmio + LAS0_BOARD_RESET);
udelay(100); /* needed? */
writel(0, devpriv->lcfg + PLX_INTRCS_REG);
- writew(0, devpriv->las0 + LAS0_IT);
- writew(~0, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(0, dev->mmio + LAS0_IT);
+ writew(~0, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
}
/*
@@ -1235,21 +1224,19 @@ static void rtd_reset(struct comedi_device *dev)
*/
static void rtd_init_board(struct comedi_device *dev)
{
- struct rtd_private *devpriv = dev->private;
-
rtd_reset(dev);
- writel(0, devpriv->las0 + LAS0_OVERRUN);
- writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
- writel(0, devpriv->las0 + LAS0_DAC1_RESET);
- writel(0, devpriv->las0 + LAS0_DAC2_RESET);
+ writel(0, dev->mmio + LAS0_OVERRUN);
+ writel(0, dev->mmio + LAS0_CGT_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_DAC1_RESET);
+ writel(0, dev->mmio + LAS0_DAC2_RESET);
/* clear digital IO fifo */
- writew(0, devpriv->las0 + LAS0_DIO_STATUS);
- writeb((0 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
- writeb((1 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
- writeb((2 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
- writeb((3 << 6) | 0x00, devpriv->las0 + LAS0_UTC_CTRL);
+ writew(0, dev->mmio + LAS0_DIO_STATUS);
+ writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
/* TODO: set user out source ??? */
}
@@ -1292,10 +1279,10 @@ static int rtd_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->las0 = pci_ioremap_bar(pcidev, 2);
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
devpriv->las1 = pci_ioremap_bar(pcidev, 3);
devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
+ if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
return -ENOMEM;
rtd_pci_latency_quirk(dev, pcidev);
@@ -1375,7 +1362,7 @@ static void rtd_detach(struct comedi_device *dev)
if (devpriv) {
/* Shut down any board ops by resetting it */
- if (devpriv->las0 && devpriv->lcfg)
+ if (dev->mmio && devpriv->lcfg)
rtd_reset(dev);
if (dev->irq) {
writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
@@ -1383,8 +1370,8 @@ static void rtd_detach(struct comedi_device *dev)
devpriv->lcfg + PLX_INTRCS_REG);
free_irq(dev->irq, dev);
}
- if (devpriv->las0)
- iounmap(devpriv->las0);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->las1)
iounmap(devpriv->las1);
if (devpriv->lcfg)
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index bd447b2add7b..2b1db9783bd6 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -81,8 +81,6 @@
#define RTI800_9513A_CNTRL 0x0d
#define RTI800_9513A_STATUS 0x0d
-#define RTI800_IOSIZE 0x10
-
static const struct comedi_lrange range_rti800_ai_10_bipolar = {
4, {
BIP_RANGE(10),
@@ -281,7 +279,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], RTI800_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index 85d2b7a3c125..83f7433c2452 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -40,13 +40,10 @@ comedi_config /dev/comedi0 s526 0x2C0,0x3
#include "../comedidev.h"
#include <asm/byteorder.h>
-#define S526_SIZE 64
-
#define S526_START_AI_CONV 0
#define S526_AI_READ 0
/* Ports */
-#define S526_IOSIZE 0x40
#define S526_NUM_PORTS 27
/* registers */
@@ -345,7 +342,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
default:
return -EINVAL;
- break;
}
return insn->n;
@@ -557,7 +553,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], S526_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x40);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 0838f8aa6951..080608a840ac 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -77,7 +77,6 @@ struct s626_buffer_dma {
};
struct s626_private {
- void __iomem *mmio;
uint8_t ai_cmd_running; /* ai_cmd is running */
uint8_t ai_continuous; /* continuous acquisition */
int ai_sample_count; /* number of samples to acquire */
@@ -102,60 +101,9 @@ struct s626_private {
unsigned int ao_readback[S626_DAC_CHANNELS];
};
-/* COUNTER OBJECT ------------------------------------------------ */
-struct s626_enc_info {
- /* Pointers to functions that differ for A and B counters: */
- /* Return clock enable. */
- uint16_t (*get_enable)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return interrupt source. */
- uint16_t (*get_int_src)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return preload trigger source. */
- uint16_t (*get_load_trig)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return standardized operating mode. */
- uint16_t (*get_mode)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Generate soft index strobe. */
- void (*pulse_index)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Program clock enable. */
- void (*set_enable)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab);
- /* Program interrupt source. */
- void (*set_int_src)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t int_source);
- /* Program preload trigger source. */
- void (*set_load_trig)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig);
- /* Program standardized operating mode. */
- void (*set_mode)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
- uint16_t disable_int_src);
- /* Reset event capture flags. */
- void (*reset_cap_flags)(struct comedi_device *dev,
- const struct s626_enc_info *k);
-
- uint16_t my_cra; /* address of CRA register */
- uint16_t my_crb; /* address of CRB register */
- uint16_t my_latch_lsw; /* address of Latch least-significant-word
- * register */
- uint16_t my_event_bits[4]; /* bit translations for IntSrc -->RDMISC2 */
-};
-
/* Counter overflow/index event flag masks for RDMISC2. */
#define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
#define S626_OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
-#define S626_EVBITS(C) { 0, S626_OVERMASK(C), S626_INDXMASK(C), \
- S626_OVERMASK(C) | S626_INDXMASK(C) }
-
-/*
- * Translation table to map IntSrc into equivalent RDMISC2 event flag bits.
- * static const uint16_t s626_event_bits[][4] =
- * { S626_EVBITS(0), S626_EVBITS(1), S626_EVBITS(2), S626_EVBITS(3),
- * S626_EVBITS(4), S626_EVBITS(5) };
- */
/*
* Enable/disable a function or test status bit(s) that are accessed
@@ -164,29 +112,25 @@ struct s626_enc_info {
static void s626_mc_enable(struct comedi_device *dev,
unsigned int cmd, unsigned int reg)
{
- struct s626_private *devpriv = dev->private;
unsigned int val = (cmd << 16) | cmd;
mmiowb();
- writel(val, devpriv->mmio + reg);
+ writel(val, dev->mmio + reg);
}
static void s626_mc_disable(struct comedi_device *dev,
unsigned int cmd, unsigned int reg)
{
- struct s626_private *devpriv = dev->private;
-
- writel(cmd << 16 , devpriv->mmio + reg);
+ writel(cmd << 16 , dev->mmio + reg);
mmiowb();
}
static bool s626_mc_test(struct comedi_device *dev,
unsigned int cmd, unsigned int reg)
{
- struct s626_private *devpriv = dev->private;
unsigned int val;
- val = readl(devpriv->mmio + reg);
+ val = readl(dev->mmio + reg);
return (val & cmd) ? true : false;
}
@@ -208,7 +152,6 @@ static const struct comedi_lrange s626_range_table = {
*/
static void s626_debi_transfer(struct comedi_device *dev)
{
- struct s626_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
@@ -225,17 +168,17 @@ static void s626_debi_transfer(struct comedi_device *dev)
udelay(1);
}
if (i == timeout)
- comedi_error(dev,
- "Timeout while uploading to DEBI control register.");
+ dev_err(dev->class_dev,
+ "Timeout while uploading to DEBI control register\n");
/* Wait until DEBI transfer is done */
for (i = 0; i < timeout; i++) {
- if (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_DEBI_S))
+ if (!(readl(dev->mmio + S626_P_PSR) & S626_PSR_DEBI_S))
break;
udelay(1);
}
if (i == timeout)
- comedi_error(dev, "DEBI transfer timeout.");
+ dev_err(dev->class_dev, "DEBI transfer timeout\n");
}
/*
@@ -243,15 +186,13 @@ static void s626_debi_transfer(struct comedi_device *dev)
*/
static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
{
- struct s626_private *devpriv = dev->private;
-
/* Set up DEBI control register value in shadow RAM */
- writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+ writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
/* Execute the DEBI transfer. */
s626_debi_transfer(dev);
- return readl(devpriv->mmio + S626_P_DEBIAD);
+ return readl(dev->mmio + S626_P_DEBIAD);
}
/*
@@ -260,11 +201,9 @@ static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
static void s626_debi_write(struct comedi_device *dev, uint16_t addr,
uint16_t wdata)
{
- struct s626_private *devpriv = dev->private;
-
/* Set up DEBI control register value in shadow RAM */
- writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
- writel(wdata, devpriv->mmio + S626_P_DEBIAD);
+ writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
+ writel(wdata, dev->mmio + S626_P_DEBIAD);
/* Execute the DEBI transfer. */
s626_debi_transfer(dev);
@@ -278,18 +217,17 @@ static void s626_debi_write(struct comedi_device *dev, uint16_t addr,
static void s626_debi_replace(struct comedi_device *dev, unsigned int addr,
unsigned int mask, unsigned int wdata)
{
- struct s626_private *devpriv = dev->private;
unsigned int val;
addr &= 0xffff;
- writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+ writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
s626_debi_transfer(dev);
- writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
- val = readl(devpriv->mmio + S626_P_DEBIAD);
+ writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
+ val = readl(dev->mmio + S626_P_DEBIAD);
val &= mask;
val |= wdata;
- writel(val & 0xffff, devpriv->mmio + S626_P_DEBIAD);
+ writel(val & 0xffff, dev->mmio + S626_P_DEBIAD);
s626_debi_transfer(dev);
}
@@ -310,12 +248,11 @@ static int s626_i2c_handshake_eoc(struct comedi_device *dev,
static int s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
{
- struct s626_private *devpriv = dev->private;
unsigned int ctrl;
int ret;
/* Write I2C command to I2C Transfer Control shadow register */
- writel(val, devpriv->mmio + S626_P_I2CCTRL);
+ writel(val, dev->mmio + S626_P_I2CCTRL);
/*
* Upload I2C shadow registers into working registers and
@@ -328,7 +265,7 @@ static int s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
/* Wait until I2C bus transfer is finished or an error occurs */
do {
- ctrl = readl(devpriv->mmio + S626_P_I2CCTRL);
+ ctrl = readl(dev->mmio + S626_P_I2CCTRL);
} while ((ctrl & (S626_I2C_BUSY | S626_I2C_ERR)) == S626_I2C_BUSY);
/* Return non-zero if I2C error occurred */
@@ -366,7 +303,7 @@ static uint8_t s626_i2c_read(struct comedi_device *dev, uint8_t addr)
/* Abort function and declare error if handshake failed. */
return 0;
- return (readl(devpriv->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
+ return (readl(dev->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
}
/* *********** DAC FUNCTIONS *********** */
@@ -391,27 +328,26 @@ static int s626_send_dac_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct s626_private *devpriv = dev->private;
unsigned int status;
switch (context) {
case s626_send_dac_wait_not_mc1_a2out:
- status = readl(devpriv->mmio + S626_P_MC1);
+ status = readl(dev->mmio + S626_P_MC1);
if (!(status & S626_MC1_A2OUT))
return 0;
break;
case s626_send_dac_wait_ssr_af2_out:
- status = readl(devpriv->mmio + S626_P_SSR);
+ status = readl(dev->mmio + S626_P_SSR);
if (status & S626_SSR_AF2_OUT)
return 0;
break;
case s626_send_dac_wait_fb_buffer2_msb_00:
- status = readl(devpriv->mmio + S626_P_FB_BUFFER2);
+ status = readl(dev->mmio + S626_P_FB_BUFFER2);
if (!(status & 0xff000000))
return 0;
break;
case s626_send_dac_wait_fb_buffer2_msb_ff:
- status = readl(devpriv->mmio + S626_P_FB_BUFFER2);
+ status = readl(dev->mmio + S626_P_FB_BUFFER2);
if (status & 0xff000000)
return 0;
break;
@@ -448,7 +384,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
/* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
/* Copy DAC setpoint value to DAC's output DMA buffer. */
- /* writel(val, devpriv->mmio + (uint32_t)devpriv->dac_wbuf); */
+ /* writel(val, dev->mmio + (uint32_t)devpriv->dac_wbuf); */
*devpriv->dac_wbuf = val;
/*
@@ -466,7 +402,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* other FIFO underflow/overflow flags). When set, this flag
* will indicate that we have emerged from slot 0.
*/
- writel(S626_ISR_AFOU, devpriv->mmio + S626_P_ISR);
+ writel(S626_ISR_AFOU, dev->mmio + S626_P_ISR);
/*
* Wait for the DMA transfer to finish so that there will be data
@@ -478,7 +414,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_not_mc1_a2out);
if (ret) {
- comedi_error(dev, "DMA transfer timeout.");
+ dev_err(dev->class_dev, "DMA transfer timeout\n");
return ret;
}
@@ -491,7 +427,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* detection.
*/
writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Wait for slot 1 to execute to ensure that the Packet will be
@@ -503,7 +439,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_ssr_af2_out);
if (ret) {
- comedi_error(dev, "TSL timeout waiting for slot 1 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 1 to execute\n");
return ret;
}
@@ -515,7 +452,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* buffer register.
*/
writel(S626_XSD2 | S626_XFIFO_2 | S626_RSD2 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
@@ -537,7 +474,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
* the TSL has not yet finished executing slot 5 ...
*/
- if (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
+ if (readl(dev->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
/*
* The trap was set on time and we are still executing somewhere
* in slots 2-5, so we now wait for slot 0 to execute and trap
@@ -548,8 +485,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_fb_buffer2_msb_00);
if (ret) {
- comedi_error(dev,
- "TSL timeout waiting for slot 0 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 0 to execute\n");
return ret;
}
}
@@ -563,7 +500,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* SD3, which is driven only by a pull-up resistor.
*/
writel(S626_RSD3 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Wait for slot 0 to execute, at which time the TSL is setup for
@@ -573,7 +510,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_fb_buffer2_msb_ff);
if (ret) {
- comedi_error(dev, "TSL timeout waiting for slot 0 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 0 to execute\n");
return ret;
}
return 0;
@@ -620,16 +558,16 @@ static int s626_set_dac(struct comedi_device *dev, uint16_t chan,
ws_image = (chan & 2) ? S626_WS1 : S626_WS2;
/* Slot 2: Transmit high data byte to target DAC */
writel(S626_XSD2 | S626_XFIFO_1 | ws_image,
- devpriv->mmio + S626_VECTPORT(2));
+ dev->mmio + S626_VECTPORT(2));
/* Slot 3: Transmit low data byte to target DAC */
writel(S626_XSD2 | S626_XFIFO_0 | ws_image,
- devpriv->mmio + S626_VECTPORT(3));
+ dev->mmio + S626_VECTPORT(3));
/* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
writel(S626_XSD2 | S626_XFIFO_3 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(4));
+ dev->mmio + S626_VECTPORT(4));
/* Slot 5: running after writing target DAC's low data byte */
writel(S626_XSD2 | S626_XFIFO_2 | S626_WS3 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(5));
+ dev->mmio + S626_VECTPORT(5));
/*
* Construct and transmit target DAC's serial packet:
@@ -671,16 +609,16 @@ static int s626_write_trim_dac(struct comedi_device *dev, uint8_t logical_chan,
/* Slot 2: Send high uint8_t to target TrimDac */
writel(S626_XSD2 | S626_XFIFO_1 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(2));
+ dev->mmio + S626_VECTPORT(2));
/* Slot 3: Send low uint8_t to target TrimDac */
writel(S626_XSD2 | S626_XFIFO_0 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(3));
+ dev->mmio + S626_VECTPORT(3));
/* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
writel(S626_XSD2 | S626_XFIFO_3 | S626_WS1,
- devpriv->mmio + S626_VECTPORT(4));
+ dev->mmio + S626_VECTPORT(4));
/* Slot 5: Send NOP low uint8_t to DAC0 */
writel(S626_XSD2 | S626_XFIFO_2 | S626_WS1 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(5));
+ dev->mmio + S626_VECTPORT(5));
/*
* Construct and transmit target DAC's serial packet:
@@ -723,32 +661,14 @@ static int s626_load_trim_dacs(struct comedi_device *dev)
*/
/*
- * Read a counter's output latch.
- */
-static uint32_t s626_read_latch(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- uint32_t value;
-
- /* Latch counts and fetch LSW of latched counts value. */
- value = s626_debi_read(dev, k->my_latch_lsw);
-
- /* Fetch MSW of latched counts and combine with LSW. */
- value |= ((uint32_t)s626_debi_read(dev, k->my_latch_lsw + 2) << 16);
-
- /* Return latched counts. */
- return value;
-}
-
-/*
* Return/set a counter pair's latch trigger source. 0: On read
* access, 1: A index latches A, 2: B index latches B, 3: A overflow
* latches B.
*/
static void s626_set_latch_source(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
~(S626_CRBMSK_INTCTRL | S626_CRBMSK_LATCHSRC),
S626_SET_CRB_LATCHSRC(value));
}
@@ -757,10 +677,10 @@ static void s626_set_latch_source(struct comedi_device *dev,
* Write value into counter preload register.
*/
static void s626_preload(struct comedi_device *dev,
- const struct s626_enc_info *k, uint32_t value)
+ unsigned int chan, uint32_t value)
{
- s626_debi_write(dev, k->my_latch_lsw, value);
- s626_debi_write(dev, k->my_latch_lsw + 2, value >> 16);
+ s626_debi_write(dev, S626_LP_CNTR(chan), value);
+ s626_debi_write(dev, S626_LP_CNTR(chan) + 2, value >> 16);
}
/* ****** PRIVATE COUNTER FUNCTIONS ****** */
@@ -768,28 +688,27 @@ static void s626_preload(struct comedi_device *dev,
/*
* Reset a counter's index and overflow event capture flags.
*/
-static void s626_reset_cap_flags_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+static void s626_reset_cap_flags(struct comedi_device *dev,
+ unsigned int chan)
{
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_A(1)));
-}
+ uint16_t set;
-static void s626_reset_cap_flags_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_B(1)));
+ set = S626_SET_CRB_INTRESETCMD(1);
+ if (chan < 3)
+ set |= S626_SET_CRB_INTRESET_A(1);
+ else
+ set |= S626_SET_CRB_INTRESET_B(1);
+
+ s626_debi_replace(dev, S626_LP_CRB(chan), ~S626_CRBMSK_INTCTRL, set);
}
+#ifdef unused
/*
* Return counter setup in a format (COUNTER_SETUP) that is consistent
* for both A and B counters.
*/
static uint16_t s626_get_mode_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
uint16_t cra;
uint16_t crb;
@@ -797,8 +716,8 @@ static uint16_t s626_get_mode_a(struct comedi_device *dev,
unsigned cntsrc, clkmult, clkpol, encmode;
/* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, k->my_cra);
- crb = s626_debi_read(dev, k->my_crb);
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
/*
* Populate the standardized counter setup bit fields.
@@ -844,7 +763,7 @@ static uint16_t s626_get_mode_a(struct comedi_device *dev,
}
static uint16_t s626_get_mode_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
uint16_t cra;
uint16_t crb;
@@ -852,8 +771,8 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
unsigned cntsrc, clkmult, clkpol, encmode;
/* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, k->my_cra);
- crb = s626_debi_read(dev, k->my_crb);
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
/*
* Populate the standardized counter setup bit fields.
@@ -903,6 +822,14 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
return setup;
}
+static uint16_t s626_get_mode(struct comedi_device *dev,
+ unsigned int chan)
+{
+ return (chan < 3) ? s626_get_mode_a(dev, chan)
+ : s626_get_mode_b(dev, chan);
+}
+#endif
+
/*
* Set the operating mode for the specified counter. The setup
* parameter is treated as a COUNTER_SETUP data type. The following
@@ -910,7 +837,7 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
* ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
*/
static void s626_set_mode_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
+ unsigned int chan, uint16_t setup,
uint16_t disable_int_src)
{
struct s626_private *devpriv = dev->private;
@@ -974,20 +901,21 @@ static void s626_set_mode_a(struct comedi_device *dev,
* enable mask to indicate the counter interrupt is disabled.
*/
if (disable_int_src)
- devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
/*
* While retaining CounterB and LatchSrc configurations, program the
* new counter operating mode.
*/
- s626_debi_replace(dev, k->my_cra,
+ s626_debi_replace(dev, S626_LP_CRA(chan),
S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B, cra);
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A), crb);
}
static void s626_set_mode_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
+ unsigned int chan, uint16_t setup,
uint16_t disable_int_src)
{
struct s626_private *devpriv = dev->private;
@@ -1058,54 +986,64 @@ static void s626_set_mode_b(struct comedi_device *dev,
* enable mask to indicate the counter interrupt is disabled.
*/
if (disable_int_src)
- devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
/*
* While retaining CounterA and LatchSrc configurations, program the
* new counter operating mode.
*/
- s626_debi_replace(dev, k->my_cra,
+ s626_debi_replace(dev, S626_LP_CRA(chan),
~(S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B), cra);
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
S626_CRBMSK_CLKENAB_A | S626_CRBMSK_LATCHSRC, crb);
}
+static void s626_set_mode(struct comedi_device *dev,
+ unsigned int chan,
+ uint16_t setup, uint16_t disable_int_src)
+{
+ if (chan < 3)
+ s626_set_mode_a(dev, chan, setup, disable_int_src);
+ else
+ s626_set_mode_b(dev, chan, setup, disable_int_src);
+}
+
/*
* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
*/
-static void s626_set_enable_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab)
+static void s626_set_enable(struct comedi_device *dev,
+ unsigned int chan, uint16_t enab)
{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A),
- S626_SET_CRB_CLKENAB_A(enab));
-}
+ unsigned int mask = S626_CRBMSK_INTCTRL;
+ unsigned int set;
-static void s626_set_enable_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab)
-{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_B),
- S626_SET_CRB_CLKENAB_B(enab));
+ if (chan < 3) {
+ mask |= S626_CRBMSK_CLKENAB_A;
+ set = S626_SET_CRB_CLKENAB_A(enab);
+ } else {
+ mask |= S626_CRBMSK_CLKENAB_B;
+ set = S626_SET_CRB_CLKENAB_B(enab);
+ }
+ s626_debi_replace(dev, S626_LP_CRB(chan), ~mask, set);
}
-static uint16_t s626_get_enable_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_enable(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_CLKENAB_A(s626_debi_read(dev, k->my_crb));
-}
+ uint16_t crb = s626_debi_read(dev, S626_LP_CRB(chan));
-static uint16_t s626_get_enable_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRB_CLKENAB_B(s626_debi_read(dev, k->my_crb));
+ return (chan < 3) ? S626_GET_CRB_CLKENAB_A(crb)
+ : S626_GET_CRB_CLKENAB_B(crb);
}
+#endif
#ifdef unused
static uint16_t s626_get_latch_source(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, k->my_crb));
+ return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, S626_LP_CRB(chan)));
}
#endif
@@ -1114,295 +1052,244 @@ static uint16_t s626_get_latch_source(struct comedi_device *dev,
* register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
* 2=OverflowA (B counters only), 3=disabled.
*/
-static void s626_set_load_trig_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig)
-{
- s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_LOADSRC_A,
- S626_SET_CRA_LOADSRC_A(trig));
-}
-
-static void s626_set_load_trig_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig)
+static void s626_set_load_trig(struct comedi_device *dev,
+ unsigned int chan, uint16_t trig)
{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL),
- S626_SET_CRB_LOADSRC_B(trig));
-}
+ uint16_t reg;
+ uint16_t mask;
+ uint16_t set;
-static uint16_t s626_get_load_trig_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev, k->my_cra));
+ if (chan < 3) {
+ reg = S626_LP_CRA(chan);
+ mask = S626_CRAMSK_LOADSRC_A;
+ set = S626_SET_CRA_LOADSRC_A(trig);
+ } else {
+ reg = S626_LP_CRB(chan);
+ mask = S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL;
+ set = S626_SET_CRB_LOADSRC_B(trig);
+ }
+ s626_debi_replace(dev, reg, ~mask, set);
}
-static uint16_t s626_get_load_trig_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_load_trig(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev, k->my_crb));
+ if (chan < 3)
+ return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev,
+ S626_LP_CRA(chan)));
+ else
+ return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev,
+ S626_LP_CRB(chan)));
}
+#endif
/*
* Return/set counter interrupt source and clear any captured
* index/overflow events. int_source: 0=Disabled, 1=OverflowOnly,
* 2=IndexOnly, 3=IndexAndOverflow.
*/
-static void s626_set_int_src_a(struct comedi_device *dev,
- const struct s626_enc_info *k,
- uint16_t int_source)
-{
- struct s626_private *devpriv = dev->private;
-
- /* Reset any pending counter overflow or index captures. */
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_A(1)));
-
- /* Program counter interrupt source. */
- s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_INTSRC_A,
- S626_SET_CRA_INTSRC_A(int_source));
-
- /* Update MISC2 interrupt enable mask. */
- devpriv->counter_int_enabs =
- (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
- k->my_event_bits[int_source];
-}
-
-static void s626_set_int_src_b(struct comedi_device *dev,
- const struct s626_enc_info *k,
- uint16_t int_source)
+static void s626_set_int_src(struct comedi_device *dev,
+ unsigned int chan, uint16_t int_source)
{
struct s626_private *devpriv = dev->private;
- uint16_t crb;
+ uint16_t cra_reg = S626_LP_CRA(chan);
+ uint16_t crb_reg = S626_LP_CRB(chan);
+
+ if (chan < 3) {
+ /* Reset any pending counter overflow or index captures */
+ s626_debi_replace(dev, crb_reg, ~S626_CRBMSK_INTCTRL,
+ S626_SET_CRB_INTRESETCMD(1) |
+ S626_SET_CRB_INTRESET_A(1));
+
+ /* Program counter interrupt source */
+ s626_debi_replace(dev, cra_reg, ~S626_CRAMSK_INTSRC_A,
+ S626_SET_CRA_INTSRC_A(int_source));
+ } else {
+ uint16_t crb;
- /* Cache writeable CRB register image. */
- crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+ /* Cache writeable CRB register image */
+ crb = s626_debi_read(dev, crb_reg);
+ crb &= ~S626_CRBMSK_INTCTRL;
- /* Reset any pending counter overflow or index captures. */
- s626_debi_write(dev, k->my_crb, (crb | S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_B(1)));
+ /* Reset any pending counter overflow or index captures */
+ s626_debi_write(dev, crb_reg,
+ crb | S626_SET_CRB_INTRESETCMD(1) |
+ S626_SET_CRB_INTRESET_B(1));
- /* Program counter interrupt source. */
- s626_debi_write(dev, k->my_crb, ((crb & ~S626_CRBMSK_INTSRC_B) |
- S626_SET_CRB_INTSRC_B(int_source)));
+ /* Program counter interrupt source */
+ s626_debi_write(dev, crb_reg,
+ (crb & ~S626_CRBMSK_INTSRC_B) |
+ S626_SET_CRB_INTSRC_B(int_source));
+ }
/* Update MISC2 interrupt enable mask. */
- devpriv->counter_int_enabs =
- (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
- k->my_event_bits[int_source];
-}
-
-static uint16_t s626_get_int_src_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRA_INTSRC_A(s626_debi_read(dev, k->my_cra));
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
+ switch (int_source) {
+ case 0:
+ default:
+ break;
+ case 1:
+ devpriv->counter_int_enabs |= S626_OVERMASK(chan);
+ break;
+ case 2:
+ devpriv->counter_int_enabs |= S626_INDXMASK(chan);
+ break;
+ case 3:
+ devpriv->counter_int_enabs |= (S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
+ break;
+ }
}
-static uint16_t s626_get_int_src_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_int_src(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_INTSRC_B(s626_debi_read(dev, k->my_crb));
+ if (chan < 3)
+ return S626_GET_CRA_INTSRC_A(s626_debi_read(dev,
+ S626_LP_CRA(chan)));
+ else
+ return S626_GET_CRB_INTSRC_B(s626_debi_read(dev,
+ S626_LP_CRB(chan)));
}
+#endif
#ifdef unused
/*
* Return/set the clock multiplier.
*/
static void s626_set_clk_mult(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKMULT) |
- S626_SET_STD_CLKMULT(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_CLKMULT;
+ mode |= S626_SET_STD_CLKMULT(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_clk_mult(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_CLKMULT(k->get_mode(dev, k));
+ return S626_GET_STD_CLKMULT(s626_get_mode(dev, chan));
}
/*
* Return/set the clock polarity.
*/
static void s626_set_clk_pol(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKPOL) |
- S626_SET_STD_CLKPOL(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_CLKPOL;
+ mode |= S626_SET_STD_CLKPOL(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_clk_pol(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_CLKPOL(k->get_mode(dev, k));
+ return S626_GET_STD_CLKPOL(s626_get_mode(dev, chan));
}
/*
* Return/set the encoder mode.
*/
static void s626_set_enc_mode(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_ENCMODE) |
- S626_SET_STD_ENCMODE(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_ENCMODE;
+ mode |= S626_SET_STD_ENCMODE(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_enc_mode(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_ENCMODE(k->get_mode(dev, k));
+ return S626_GET_STD_ENCMODE(s626_get_mode(dev, chan));
}
/*
* Return/set the index polarity.
*/
static void s626_set_index_pol(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXPOL) |
- S626_SET_STD_INDXPOL(value != 0)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_INDXPOL;
+ mode |= S626_SET_STD_INDXPOL(value != 0);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_index_pol(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_INDXPOL(k->get_mode(dev, k));
+ return S626_GET_STD_INDXPOL(s626_get_mode(dev, chan));
}
/*
* Return/set the index source.
*/
static void s626_set_index_src(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXSRC) |
- S626_SET_STD_INDXSRC(value != 0)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_INDXSRC;
+ mode |= S626_SET_STD_INDXSRC(value != 0);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_index_src(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_INDXSRC(k->get_mode(dev, k));
+ return S626_GET_STD_INDXSRC(s626_get_mode(dev, chan));
}
#endif
/*
* Generate an index pulse.
*/
-static void s626_pulse_index_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+static void s626_pulse_index(struct comedi_device *dev,
+ unsigned int chan)
{
- uint16_t cra;
+ if (chan < 3) {
+ uint16_t cra;
- cra = s626_debi_read(dev, k->my_cra);
- /* Pulse index. */
- s626_debi_write(dev, k->my_cra, (cra ^ S626_CRAMSK_INDXPOL_A));
- s626_debi_write(dev, k->my_cra, cra);
-}
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
-static void s626_pulse_index_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- uint16_t crb;
+ /* Pulse index */
+ s626_debi_write(dev, S626_LP_CRA(chan),
+ (cra ^ S626_CRAMSK_INDXPOL_A));
+ s626_debi_write(dev, S626_LP_CRA(chan), cra);
+ } else {
+ uint16_t crb;
- crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
- /* Pulse index. */
- s626_debi_write(dev, k->my_crb, (crb ^ S626_CRBMSK_INDXPOL_B));
- s626_debi_write(dev, k->my_crb, crb);
-}
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
+ crb &= ~S626_CRBMSK_INTCTRL;
-static const struct s626_enc_info s626_enc_chan_info[] = {
- {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR0A,
- .my_crb = S626_LP_CR0B,
- .my_latch_lsw = S626_LP_CNTR0ALSW,
- .my_event_bits = S626_EVBITS(0),
- }, {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR1A,
- .my_crb = S626_LP_CR1B,
- .my_latch_lsw = S626_LP_CNTR1ALSW,
- .my_event_bits = S626_EVBITS(1),
- }, {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR2A,
- .my_crb = S626_LP_CR2B,
- .my_latch_lsw = S626_LP_CNTR2ALSW,
- .my_event_bits = S626_EVBITS(2),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR0A,
- .my_crb = S626_LP_CR0B,
- .my_latch_lsw = S626_LP_CNTR0BLSW,
- .my_event_bits = S626_EVBITS(3),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR1A,
- .my_crb = S626_LP_CR1B,
- .my_latch_lsw = S626_LP_CNTR1BLSW,
- .my_event_bits = S626_EVBITS(4),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR2A,
- .my_crb = S626_LP_CR2B,
- .my_latch_lsw = S626_LP_CNTR2BLSW,
- .my_event_bits = S626_EVBITS(5),
- },
-};
+ /* Pulse index */
+ s626_debi_write(dev, S626_LP_CRB(chan),
+ (crb ^ S626_CRBMSK_INDXPOL_B));
+ s626_debi_write(dev, S626_LP_CRB(chan), crb);
+ }
+}
static unsigned int s626_ai_reg_to_uint(unsigned int data)
{
@@ -1490,11 +1377,8 @@ static void s626_handle_dio_interrupt(struct comedi_device *dev,
}
if (cmd->convert_src == TRIG_TIMER) {
- const struct s626_enc_info *k =
- &s626_enc_chan_info[5];
-
devpriv->ai_convert_count = cmd->chanlist_len;
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
}
}
if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
@@ -1533,7 +1417,6 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- const struct s626_enc_info *k;
uint16_t irqbit;
/* read interrupt type */
@@ -1541,39 +1424,29 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
/* check interrupt on counters */
if (irqbit & S626_IRQ_COINT1A) {
- k = &s626_enc_chan_info[0];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 0);
}
if (irqbit & S626_IRQ_COINT2A) {
- k = &s626_enc_chan_info[1];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 1);
}
if (irqbit & S626_IRQ_COINT3A) {
- k = &s626_enc_chan_info[2];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 2);
}
if (irqbit & S626_IRQ_COINT1B) {
- k = &s626_enc_chan_info[3];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 3);
}
if (irqbit & S626_IRQ_COINT2B) {
- k = &s626_enc_chan_info[4];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 4);
if (devpriv->ai_convert_count > 0) {
devpriv->ai_convert_count--;
if (devpriv->ai_convert_count == 0)
- k->set_enable(dev, k, S626_CLKENAB_INDEX);
+ s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
if (cmd->convert_src == TRIG_TIMER) {
/* Trigger ADC scan loop start */
@@ -1583,10 +1456,8 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
}
}
if (irqbit & S626_IRQ_COINT3B) {
- k = &s626_enc_chan_info[5];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 5);
if (cmd->scan_begin_src == TRIG_TIMER) {
/* Trigger ADC scan loop start */
@@ -1594,9 +1465,8 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
}
if (cmd->convert_src == TRIG_TIMER) {
- k = &s626_enc_chan_info[4];
devpriv->ai_convert_count = cmd->chanlist_len;
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_enable(dev, 4, S626_CLKENAB_ALWAYS);
}
}
}
@@ -1661,7 +1531,6 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev)
static irqreturn_t s626_irq_handler(int irq, void *d)
{
struct comedi_device *dev = d;
- struct s626_private *devpriv = dev->private;
unsigned long flags;
uint32_t irqtype, irqstatus;
@@ -1671,16 +1540,16 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
spin_lock_irqsave(&dev->spinlock, flags);
/* save interrupt enable register state */
- irqstatus = readl(devpriv->mmio + S626_P_IER);
+ irqstatus = readl(dev->mmio + S626_P_IER);
/* read interrupt type */
- irqtype = readl(devpriv->mmio + S626_P_ISR);
+ irqtype = readl(dev->mmio + S626_P_ISR);
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* clear interrupt */
- writel(irqtype, devpriv->mmio + S626_P_ISR);
+ writel(irqtype, dev->mmio + S626_P_ISR);
switch (irqtype) {
case S626_IRQ_RPS1: /* end_of_scan occurs */
@@ -1695,7 +1564,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
}
/* enable interrupt */
- writel(irqstatus, devpriv->mmio + S626_P_IER);
+ writel(irqstatus, dev->mmio + S626_P_IER);
spin_unlock_irqrestore(&dev->spinlock, flags);
return IRQ_HANDLED;
@@ -1723,7 +1592,7 @@ static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl)
/* Initialize RPS instruction pointer */
writel((uint32_t)devpriv->rps_buf.physical_base,
- devpriv->mmio + S626_P_RPSADDR1);
+ dev->mmio + S626_P_RPSADDR1);
/* Construct RPS program in rps_buf DMA buffer */
if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
@@ -1944,10 +1813,9 @@ static int s626_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct s626_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + S626_P_PSR);
+ status = readl(dev->mmio + S626_P_PSR);
if (status & S626_PSR_GPIO2)
return 0;
return -EBUSY;
@@ -1955,9 +1823,9 @@ static int s626_ai_eoc(struct comedi_device *dev,
static int s626_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct s626_private *devpriv = dev->private;
uint16_t chan = CR_CHAN(insn->chanspec);
uint16_t range = CR_RANGE(insn->chanspec);
uint16_t adc_spec = 0;
@@ -1986,17 +1854,14 @@ static int s626_ai_insn_read(struct comedi_device *dev,
udelay(10);
/* Start ADC by pulsing GPIO1 low */
- gpio_image = readl(devpriv->mmio + S626_P_GPIO);
+ gpio_image = readl(dev->mmio + S626_P_GPIO);
/* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/*
* Wait for ADC to complete (GPIO2 is asserted high when
@@ -2011,7 +1876,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Fetch ADC data */
if (n != 0) {
- tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
+ tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
data[n - 1] = s626_ai_reg_to_uint(tmp);
}
@@ -2031,14 +1896,14 @@ static int s626_ai_insn_read(struct comedi_device *dev,
* Start a dummy conversion to cause the data from the
* previous conversion to be shifted in.
*/
- gpio_image = readl(devpriv->mmio + S626_P_GPIO);
+ gpio_image = readl(dev->mmio + S626_P_GPIO);
/* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Wait for the data to arrive in FB BUFFER 1 register. */
@@ -2051,7 +1916,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Fetch ADC data */
if (n != 0) {
- tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
+ tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
data[n - 1] = s626_ai_reg_to_uint(tmp);
}
@@ -2098,13 +1963,13 @@ static int s626_ai_inttrig(struct comedi_device *dev,
* Also, it should adjust ns so that it cooresponds to the actual time
* that the device will use.
*/
-static int s626_ns_to_timer(unsigned int *nanosec, int round_mode)
+static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags)
{
int divider, base;
base = 500; /* 2MHz internal clock */
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -2122,7 +1987,7 @@ static int s626_ns_to_timer(unsigned int *nanosec, int round_mode)
}
static void s626_timer_load(struct comedi_device *dev,
- const struct s626_enc_info *k, int tick)
+ unsigned int chan, int tick)
{
uint16_t setup =
/* Preload upon index. */
@@ -2140,26 +2005,26 @@ static void s626_timer_load(struct comedi_device *dev,
uint16_t value_latchsrc = S626_LATCHSRC_A_INDXA;
/* uint16_t enab = S626_CLKENAB_ALWAYS; */
- k->set_mode(dev, k, setup, false);
+ s626_set_mode(dev, chan, setup, false);
/* Set the preload register */
- s626_preload(dev, k, tick);
+ s626_preload(dev, chan, tick);
/*
* Software index pulse forces the preload register to load
* into the counter
*/
- k->set_load_trig(dev, k, 0);
- k->pulse_index(dev, k);
+ s626_set_load_trig(dev, chan, 0);
+ s626_pulse_index(dev, chan);
/* set reload on counter overflow */
- k->set_load_trig(dev, k, 1);
+ s626_set_load_trig(dev, chan, 1);
/* set interrupt on overflow */
- k->set_int_src(dev, k, S626_INTSRC_OVER);
+ s626_set_int_src(dev, chan, S626_INTSRC_OVER);
- s626_set_latch_source(dev, k, value_latchsrc);
- /* k->set_enable(dev, k, (uint16_t)(enab != 0)); */
+ s626_set_latch_source(dev, chan, value_latchsrc);
+ /* s626_set_enable(dev, chan, (uint16_t)(enab != 0)); */
}
/* TO COMPLETE */
@@ -2168,7 +2033,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
struct s626_private *devpriv = dev->private;
uint8_t ppl[16];
struct comedi_cmd *cmd = &s->async->cmd;
- const struct s626_enc_info *k;
int tick;
if (devpriv->ai_cmd_running) {
@@ -2177,10 +2041,10 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return -EBUSY;
}
/* disable interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* clear interrupt request */
- writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, devpriv->mmio + S626_P_ISR);
+ writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, dev->mmio + S626_P_ISR);
/* clear any pending interrupt */
s626_dio_clear_irq(dev);
@@ -2205,13 +2069,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* set a counter to generate adc trigger at scan_begin_arg
* interval
*/
- k = &s626_enc_chan_info[5];
- tick = s626_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ tick = s626_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
/* load timer value and enable interrupt */
- s626_timer_load(dev, k, tick);
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_timer_load(dev, 5, tick);
+ s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
break;
case TRIG_EXT:
/* set the digital line and interrupt for scan trigger */
@@ -2228,13 +2090,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* set a counter to generate adc trigger at convert_arg
* interval
*/
- k = &s626_enc_chan_info[4];
- tick = s626_ns_to_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ tick = s626_ns_to_timer(&cmd->convert_arg, cmd->flags);
/* load timer value and enable interrupt */
- s626_timer_load(dev, k, tick);
- k->set_enable(dev, k, S626_CLKENAB_INDEX);
+ s626_timer_load(dev, 4, tick);
+ s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
break;
case TRIG_EXT:
/* set the digital line and interrupt for convert trigger */
@@ -2279,7 +2139,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* enable interrupt */
- writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, devpriv->mmio + S626_P_IER);
+ writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, dev->mmio + S626_P_IER);
return 0;
}
@@ -2372,13 +2232,13 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- s626_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ s626_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- s626_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ s626_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -2402,7 +2262,7 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
devpriv->ai_cmd_running = 0;
@@ -2516,6 +2376,7 @@ static int s626_enc_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ unsigned int chan = CR_CHAN(insn->chanspec);
uint16_t setup =
/* Preload upon index. */
S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
@@ -2533,51 +2394,58 @@ static int s626_enc_insn_config(struct comedi_device *dev,
/* uint32_t Preloadvalue; //Counter initial value */
uint16_t value_latchsrc = S626_LATCHSRC_AB_READ;
uint16_t enab = S626_CLKENAB_ALWAYS;
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
/* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
- k->set_mode(dev, k, setup, true);
- s626_preload(dev, k, data[0]);
- k->pulse_index(dev, k);
- s626_set_latch_source(dev, k, value_latchsrc);
- k->set_enable(dev, k, (enab != 0));
+ s626_set_mode(dev, chan, setup, true);
+ s626_preload(dev, chan, data[0]);
+ s626_pulse_index(dev, chan);
+ s626_set_latch_source(dev, chan, value_latchsrc);
+ s626_set_enable(dev, chan, (enab != 0));
return insn->n;
}
static int s626_enc_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int n;
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ uint16_t cntr_latch_reg = S626_LP_CNTR(chan);
+ int i;
- for (n = 0; n < insn->n; n++)
- data[n] = s626_read_latch(dev, k);
+ for (i = 0; i < insn->n; i++) {
+ unsigned int val;
- return n;
+ /*
+ * Read the counter's output latch LSW/MSW.
+ * Latches on LSW read.
+ */
+ val = s626_debi_read(dev, cntr_latch_reg);
+ val |= (s626_debi_read(dev, cntr_latch_reg + 2) << 16);
+ data[i] = val;
+ }
+
+ return insn->n;
}
static int s626_enc_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+ unsigned int chan = CR_CHAN(insn->chanspec);
/* Set the preload register */
- s626_preload(dev, k, data[0]);
+ s626_preload(dev, chan, data[0]);
/*
* Software index pulse forces the preload register to load
* into the counter
*/
- k->set_load_trig(dev, k, 0);
- k->pulse_index(dev, k);
- k->set_load_trig(dev, k, 2);
+ s626_set_load_trig(dev, chan, 0);
+ s626_pulse_index(dev, chan);
+ s626_set_load_trig(dev, chan, 2);
return 1;
}
@@ -2612,7 +2480,6 @@ static void s626_close_dma_b(struct comedi_device *dev,
static void s626_counters_init(struct comedi_device *dev)
{
int chan;
- const struct s626_enc_info *k;
uint16_t setup =
/* Preload upon index. */
S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
@@ -2631,11 +2498,10 @@ static void s626_counters_init(struct comedi_device *dev)
* Disable all counter interrupts and clear any captured counter events.
*/
for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
- k = &s626_enc_chan_info[chan];
- k->set_mode(dev, k, setup, true);
- k->set_int_src(dev, k, 0);
- k->reset_cap_flags(dev, k);
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_mode(dev, chan, setup, true);
+ s626_set_int_src(dev, chan, 0);
+ s626_reset_cap_flags(dev, chan);
+ s626_set_enable(dev, chan, S626_CLKENAB_ALWAYS);
}
}
@@ -2683,13 +2549,13 @@ static int s626_initialize(struct comedi_device *dev)
*/
writel(S626_DEBI_CFG_SLAVE16 |
(S626_DEBI_TOUT << S626_DEBI_CFG_TOUT_BIT) | S626_DEBI_SWAP |
- S626_DEBI_CFG_INTEL, devpriv->mmio + S626_P_DEBICFG);
+ S626_DEBI_CFG_INTEL, dev->mmio + S626_P_DEBICFG);
/* Disable MMU paging */
- writel(S626_DEBI_PAGE_DISABLE, devpriv->mmio + S626_P_DEBIPAGE);
+ writel(S626_DEBI_PAGE_DISABLE, dev->mmio + S626_P_DEBIPAGE);
/* Init GPIO so that ADC Start* is negated */
- writel(S626_GPIO_BASE | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(S626_GPIO_BASE | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* I2C device address for onboard eeprom (revb) */
devpriv->i2c_adrs = 0xA0;
@@ -2699,7 +2565,7 @@ static int s626_initialize(struct comedi_device *dev)
* operation in progress and reset BUSY flag.
*/
writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
- devpriv->mmio + S626_P_I2CSTAT);
+ dev->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
if (ret)
@@ -2710,7 +2576,7 @@ static int s626_initialize(struct comedi_device *dev)
* reg twice to reset all I2C error flags.
*/
for (i = 0; i < 2; i++) {
- writel(S626_I2C_CLKSEL, devpriv->mmio + S626_P_I2CSTAT);
+ writel(S626_I2C_CLKSEL, dev->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
if (ret)
@@ -2723,7 +2589,7 @@ static int s626_initialize(struct comedi_device *dev)
* DAC data setup times are satisfied, enable DAC serial
* clock out.
*/
- writel(S626_ACON2_INIT, devpriv->mmio + S626_P_ACON2);
+ writel(S626_ACON2_INIT, dev->mmio + S626_P_ACON2);
/*
* Set up TSL1 slot list, which is used to control the
@@ -2731,12 +2597,12 @@ static int s626_initialize(struct comedi_device *dev)
* S626_SIB_A1 = store data uint8_t at next available location
* in FB BUFFER1 register.
*/
- writel(S626_RSD1 | S626_SIB_A1, devpriv->mmio + S626_P_TSL1);
+ writel(S626_RSD1 | S626_SIB_A1, dev->mmio + S626_P_TSL1);
writel(S626_RSD1 | S626_SIB_A1 | S626_EOS,
- devpriv->mmio + S626_P_TSL1 + 4);
+ dev->mmio + S626_P_TSL1 + 4);
/* Enable TSL1 slot list so that it executes all the time */
- writel(S626_ACON1_ADCSTART, devpriv->mmio + S626_P_ACON1);
+ writel(S626_ACON1_ADCSTART, dev->mmio + S626_P_ACON1);
/*
* Initialize RPS registers used for ADC
@@ -2744,11 +2610,11 @@ static int s626_initialize(struct comedi_device *dev)
/* Physical start of RPS program */
writel((uint32_t)devpriv->rps_buf.physical_base,
- devpriv->mmio + S626_P_RPSADDR1);
+ dev->mmio + S626_P_RPSADDR1);
/* RPS program performs no explicit mem writes */
- writel(0, devpriv->mmio + S626_P_RPSPAGE1);
+ writel(0, dev->mmio + S626_P_RPSPAGE1);
/* Disable RPS timeouts */
- writel(0, devpriv->mmio + S626_P_RPS1_TOUT);
+ writel(0, dev->mmio + S626_P_RPS1_TOUT);
#if 0
/*
@@ -2804,7 +2670,7 @@ static int s626_initialize(struct comedi_device *dev)
* burst length = 1 DWORD
* threshold = 1 DWORD.
*/
- writel(0, devpriv->mmio + S626_P_PCI_BT_A);
+ writel(0, dev->mmio + S626_P_PCI_BT_A);
/*
* Init Audio2's output DMA physical addresses. The protection
@@ -2814,9 +2680,9 @@ static int s626_initialize(struct comedi_device *dev)
*/
phys_buf = devpriv->ana_buf.physical_base +
(S626_DAC_WDMABUF_OS * sizeof(uint32_t));
- writel((uint32_t)phys_buf, devpriv->mmio + S626_P_BASEA2_OUT);
+ writel((uint32_t)phys_buf, dev->mmio + S626_P_BASEA2_OUT);
writel((uint32_t)(phys_buf + sizeof(uint32_t)),
- devpriv->mmio + S626_P_PROTA2_OUT);
+ dev->mmio + S626_P_PROTA2_OUT);
/*
* Cache Audio2's output DMA buffer logical address. This is
@@ -2831,7 +2697,7 @@ static int s626_initialize(struct comedi_device *dev)
* DMAC will automatically halt and its PCI address pointer
* will be reset when the protection address is reached.
*/
- writel(8, devpriv->mmio + S626_P_PAGEA2_OUT);
+ writel(8, dev->mmio + S626_P_PAGEA2_OUT);
/*
* Initialize time slot list 2 (TSL2), which is used to control
@@ -2847,7 +2713,7 @@ static int s626_initialize(struct comedi_device *dev)
/* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Initialize slot 1, which is constant. Slot 1 causes a
@@ -2859,10 +2725,10 @@ static int s626_initialize(struct comedi_device *dev)
*/
/* Slot 1: Fetch DWORD from Audio2's output FIFO */
- writel(S626_LF_A2, devpriv->mmio + S626_VECTPORT(1));
+ writel(S626_LF_A2, dev->mmio + S626_VECTPORT(1));
/* Start DAC's audio interface (TSL2) running */
- writel(S626_ACON1_DACSTART, devpriv->mmio + S626_P_ACON1);
+ writel(S626_ACON1_DACSTART, dev->mmio + S626_P_ACON1);
/*
* Init Trim DACs to calibrated values. Do it twice because the
@@ -2926,15 +2792,15 @@ static int s626_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->mmio = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->mmio)
+ dev->mmio = pci_ioremap_bar(pcidev, 0);
+ if (!dev->mmio)
return -ENOMEM;
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* soft reset */
- writel(S626_MC1_SOFT_RESET, devpriv->mmio + S626_P_MC1);
+ writel(S626_MC1_SOFT_RESET, dev->mmio + S626_P_MC1);
/* DMA FIXME DMA// */
@@ -3043,20 +2909,20 @@ static void s626_detach(struct comedi_device *dev)
/* stop ai_command */
devpriv->ai_cmd_running = 0;
- if (devpriv->mmio) {
+ if (dev->mmio) {
/* interrupt mask */
/* Disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* Clear board's IRQ status flag */
writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1,
- devpriv->mmio + S626_P_ISR);
+ dev->mmio + S626_P_ISR);
/* Disable the watchdog timer and battery charger. */
s626_write_misc2(dev, 0);
/* Close all interfaces on 7146 device */
- writel(S626_MC1_SHUTDOWN, devpriv->mmio + S626_P_MC1);
- writel(S626_ACON1_BASE, devpriv->mmio + S626_P_ACON1);
+ writel(S626_MC1_SHUTDOWN, dev->mmio + S626_P_MC1);
+ writel(S626_ACON1_BASE, dev->mmio + S626_P_ACON1);
s626_close_dma_b(dev, &devpriv->rps_buf,
S626_DMABUF_SIZE);
@@ -3066,8 +2932,8 @@ static void s626_detach(struct comedi_device *dev)
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
}
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 33b72739c1cb..b83424e7507b 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -229,27 +229,13 @@
#define S626_LP_RDEDGSEL(x) (0x004c + (x) * 0x10) /* R: edge selection */
#define S626_LP_RDCAPSEL(x) (0x004e + (x) * 0x10) /* R: capture enable */
-/* Counter Registers (read/write): */
-#define S626_LP_CR0A 0x0000 /* 0A setup register. */
-#define S626_LP_CR0B 0x0002 /* 0B setup register. */
-#define S626_LP_CR1A 0x0004 /* 1A setup register. */
-#define S626_LP_CR1B 0x0006 /* 1B setup register. */
-#define S626_LP_CR2A 0x0008 /* 2A setup register. */
-#define S626_LP_CR2B 0x000A /* 2B setup register. */
-
-/* Counter PreLoad (write) and Latch (read) Registers: */
-#define S626_LP_CNTR0ALSW 0x000C /* 0A lsw. */
-#define S626_LP_CNTR0AMSW 0x000E /* 0A msw. */
-#define S626_LP_CNTR0BLSW 0x0010 /* 0B lsw. */
-#define S626_LP_CNTR0BMSW 0x0012 /* 0B msw. */
-#define S626_LP_CNTR1ALSW 0x0014 /* 1A lsw. */
-#define S626_LP_CNTR1AMSW 0x0016 /* 1A msw. */
-#define S626_LP_CNTR1BLSW 0x0018 /* 1B lsw. */
-#define S626_LP_CNTR1BMSW 0x001A /* 1B msw. */
-#define S626_LP_CNTR2ALSW 0x001C /* 2A lsw. */
-#define S626_LP_CNTR2AMSW 0x001E /* 2A msw. */
-#define S626_LP_CNTR2BLSW 0x0020 /* 2B lsw. */
-#define S626_LP_CNTR2BMSW 0x0022 /* 2B msw. */
+/* Counter registers (read/write): 0A 1A 2A 0B 1B 2B */
+#define S626_LP_CRA(x) (0x0000 + (((x) % 3) * 0x4))
+#define S626_LP_CRB(x) (0x0002 + (((x) % 3) * 0x4))
+
+/* Counter PreLoad (write) and Latch (read) Registers: 0A 1A 2A 0B 1B 2B */
+#define S626_LP_CNTR(x) (0x000c + (((x) < 3) ? 0x0 : 0x4) + \
+ (((x) % 3) * 0x8))
/* Miscellaneous Registers (read/write): */
#define S626_LP_MISC1 0x0088 /* Read/write Misc1. */
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index 441813ffb175..167f82418cb4 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -174,6 +174,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
} else {
/* Device does not support poll, busy wait */
int retries = 0;
+
while (1) {
retries++;
if (retries >= timeout)
@@ -311,6 +312,7 @@ static void serial2002_write(struct file *f, struct serial_data data)
} else {
unsigned char ch[6];
int i = 0;
+
if (data.value >= (1L << 30)) {
ch[i] = 0x80 | ((data.value >> 30) & 0x03);
i++;
@@ -359,7 +361,8 @@ static int serial2002_setup_subdevice(struct comedi_subdevice *s,
s->n_chan = chan;
s->maxdata = 0;
kfree(s->maxdata_list);
- maxdata_list = kmalloc(sizeof(unsigned int) * s->n_chan, GFP_KERNEL);
+ maxdata_list = kmalloc_array(s->n_chan, sizeof(unsigned int),
+ GFP_KERNEL);
if (!maxdata_list)
return -ENOMEM;
s->maxdata_list = maxdata_list;
@@ -369,9 +372,8 @@ static int serial2002_setup_subdevice(struct comedi_subdevice *s,
if (kind == 1 || kind == 2) {
s->range_table = &range_digital;
} else if (range) {
- range_table_list =
- kmalloc(sizeof(struct serial2002_range_table_t) *
- s->n_chan, GFP_KERNEL);
+ range_table_list = kmalloc_array(s->n_chan, sizeof(*range),
+ GFP_KERNEL);
if (!range_table_list)
return -ENOMEM;
s->range_table_list = range_table_list;
@@ -420,67 +422,65 @@ static int serial2002_setup_subdevs(struct comedi_device *dev)
serial2002_tty_setspeed(devpriv->tty, devpriv->speed);
serial2002_poll_channel(devpriv->tty, 31);
while (1) {
- struct serial_data data;
+ struct serial_data data = serial2002_read(devpriv->tty, 1000);
+ int kind = S2002_CFG_KIND(data.value);
+ int channel = S2002_CFG_CHAN(data.value);
+ int range = S2002_CFG_BASE(data.value);
+ int cmd = S2002_CFG_CMD(data.value);
- data = serial2002_read(devpriv->tty, 1000);
if (data.kind != is_channel || data.index != 31 ||
- S2002_CFG_KIND(data.value) == S2002_CFG_KIND_INVALID) {
+ kind == S2002_CFG_KIND_INVALID)
break;
- } else {
- int channel = S2002_CFG_CHAN(data.value);
- int range = S2002_CFG_BASE(data.value);
- switch (S2002_CFG_KIND(data.value)) {
- case S2002_CFG_KIND_DIGITAL_IN:
- cfg = di_cfg;
- break;
- case S2002_CFG_KIND_DIGITAL_OUT:
- cfg = do_cfg;
- break;
- case S2002_CFG_KIND_ANALOG_IN:
- cfg = ai_cfg;
- break;
- case S2002_CFG_KIND_ANALOG_OUT:
- cfg = ao_cfg;
- break;
- case S2002_CFG_KIND_ENCODER_IN:
- cfg = ai_cfg;
- break;
- default:
- cfg = NULL;
- break;
- }
- if (!cfg)
- continue; /* unknown kind, skip it */
+ switch (kind) {
+ case S2002_CFG_KIND_DIGITAL_IN:
+ cfg = di_cfg;
+ break;
+ case S2002_CFG_KIND_DIGITAL_OUT:
+ cfg = do_cfg;
+ break;
+ case S2002_CFG_KIND_ANALOG_IN:
+ cfg = ai_cfg;
+ break;
+ case S2002_CFG_KIND_ANALOG_OUT:
+ cfg = ao_cfg;
+ break;
+ case S2002_CFG_KIND_ENCODER_IN:
+ cfg = ai_cfg;
+ break;
+ default:
+ cfg = NULL;
+ break;
+ }
+ if (!cfg)
+ continue; /* unknown kind, skip it */
- cfg[channel].kind = S2002_CFG_KIND(data.value);
+ cfg[channel].kind = kind;
- switch (S2002_CFG_CMD(data.value)) {
- case S2002_CFG_CMD_BITS:
- cfg[channel].bits = S2002_CFG_BITS(data.value);
+ switch (cmd) {
+ case S2002_CFG_CMD_BITS:
+ cfg[channel].bits = S2002_CFG_BITS(data.value);
+ break;
+ case S2002_CFG_CMD_MIN:
+ case S2002_CFG_CMD_MAX:
+ switch (S2002_CFG_UNITS(data.value)) {
+ case 0:
+ range *= 1000000;
break;
- case S2002_CFG_CMD_MIN:
- case S2002_CFG_CMD_MAX:
- switch (S2002_CFG_UNITS(data.value)) {
- case 0:
- range *= 1000000;
- break;
- case 1:
- range *= 1000;
- break;
- case 2:
- range *= 1;
- break;
- }
- if (S2002_CFG_SIGN(data.value))
- range = -range;
- if (S2002_CFG_CMD(data.value) ==
- S2002_CFG_CMD_MIN)
- cfg[channel].min = range;
- else
- cfg[channel].max = range;
+ case 1:
+ range *= 1000;
+ break;
+ case 2:
+ range *= 1;
break;
}
+ if (S2002_CFG_SIGN(data.value))
+ range = -range;
+ if (cmd == S2002_CFG_CMD_MIN)
+ cfg[channel].min = range;
+ else
+ cfg[channel].max = range;
+ break;
}
}
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index 3bfa221faf4d..a118678c24a1 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -75,9 +75,6 @@ Configuration Options:
#include "comedi_fc.h"
/* Imaginary registers for the imaginary board */
-
-#define SKEL_SIZE 0
-
#define SKEL_START_AI_CONV 0
#define SKEL_AI_READ 0
@@ -129,7 +126,7 @@ struct skel_private {
* convert ns nanoseconds to a counter value suitable for programming
* the device. Also, it should adjust ns so that it cooresponds to
* the actual time that the device will use. */
-static int skel_ns_to_timer(unsigned int *ns, int round)
+static int skel_ns_to_timer(unsigned int *ns, unsigned int flags)
{
/* trivial timer */
/* if your timing is done through two cascaded timers, the
@@ -287,12 +284,12 @@ static int skel_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- skel_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ skel_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- skel_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ skel_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index adf7cb7086cc..7c2276a086ac 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -43,7 +43,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
#include <linux/delay.h>
#include "../comedidev.h"
-#define DRIVER_NAME "unioxx5"
#define UNIOXX5_SIZE 0x10
#define UNIOXX5_SUBDEV_BASE 0xA000 /* base addr of first subdev */
#define UNIOXX5_SUBDEV_ODDS 0x400
@@ -496,7 +495,7 @@ static void unioxx5_detach(struct comedi_device *dev)
}
static struct comedi_driver unioxx5_driver = {
- .driver_name = DRIVER_NAME,
+ .driver_name = "unioxx5",
.module = THIS_MODULE,
.attach = unioxx5_attach,
.detach = unioxx5_detach,
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 5f65e4213c6e..053bc5090530 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1327,13 +1327,13 @@ static int usbdux_pwm_period(struct comedi_device *dev,
struct usbdux_private *devpriv = dev->private;
int fx2delay = 255;
- if (period < MIN_PWM_PERIOD) {
+ if (period < MIN_PWM_PERIOD)
return -EAGAIN;
- } else {
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
- }
+
+ fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
+ if (fx2delay > 255)
+ return -EAGAIN;
+
devpriv->pwm_delay = fx2delay;
devpriv->pwm_period = period;
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 85f9dcf59403..f85818dd5e11 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -33,8 +33,6 @@
* udev coldplug problem
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -275,8 +273,9 @@ static void usbduxfast_ai_interrupt(struct urb *urb)
return;
default:
- pr_err("non-zero urb status received in ai intr context: %d\n",
- urb->status);
+ dev_err(dev->class_dev,
+ "non-zero urb status received in ai intr context: %d\n",
+ urb->status);
async->events |= COMEDI_CB_EOA;
async->events |= COMEDI_CB_ERROR;
comedi_event(dev, s);
@@ -746,6 +745,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
0x00, (0xff - 0x02) & rngmask, 0x00);
usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
+ break;
case 16:
if (CR_RANGE(cmd->chanlist[0]) > 0)
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index ccc3ef7ba55c..94a09c16de8b 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -136,7 +136,7 @@
static const struct comedi_lrange usbduxsigma_ai_range = {
1, {
- BIP_RANGE(2.65 / 2.0)
+ BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
}
};
@@ -1176,13 +1176,13 @@ static int usbduxsigma_pwm_period(struct comedi_device *dev,
struct usbduxsigma_private *devpriv = dev->private;
int fx2delay = 255;
- if (period < MIN_PWM_PERIOD) {
+ if (period < MIN_PWM_PERIOD)
return -EAGAIN;
- } else {
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
- }
+
+ fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
+ if (fx2delay > 255)
+ return -EAGAIN;
+
devpriv->pwm_delay = fx2delay;
devpriv->pwm_period = period;
return 0;
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 0adf3cffddb0..831c3b702899 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -959,5 +959,4 @@ module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
-MODULE_VERSION("0.8.01");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c
index ca4c2c67dd88..edf9ff2ea25b 100644
--- a/drivers/staging/cptm1217/clearpad_tm1217.c
+++ b/drivers/staging/cptm1217/clearpad_tm1217.c
@@ -147,12 +147,11 @@ static int cp_tm1217_read(struct cp_tm1217_device *ts,
msleep(WAIT_FOR_RESPONSE);
for (i = 0; i < MAX_RETRIES; i++) {
retval = i2c_master_recv(ts->client, &req[1], size);
- if (retval == size) {
+ if (retval == size)
break;
- } else {
- msleep(INCREMENTAL_DELAY);
- dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i);
- }
+
+ msleep(INCREMENTAL_DELAY);
+ dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i);
}
if (retval != size)
dev_err(ts->dev, "cp_tm1217: Read from device failed\n");
@@ -288,11 +287,11 @@ static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle)
if (ts->thread_running == 1) {
mutex_unlock(&ts->thread_mutex);
return IRQ_HANDLED;
- } else {
- ts->thread_running = 1;
- mutex_unlock(&ts->thread_mutex);
}
+ ts->thread_running = 1;
+ mutex_unlock(&ts->thread_mutex);
+
/* Mask the interrupts */
retval = cp_tm1217_mask_interrupt(ts);
diff --git a/drivers/staging/crystalhd/Kconfig b/drivers/staging/crystalhd/Kconfig
deleted file mode 100644
index 56b414bca1a1..000000000000
--- a/drivers/staging/crystalhd/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config CRYSTALHD
- tristate "Broadcom Crystal HD video decoder support"
- depends on PCI
- default n
- help
- Support for the Broadcom Crystal HD video decoder chipset
diff --git a/drivers/staging/crystalhd/Makefile b/drivers/staging/crystalhd/Makefile
deleted file mode 100644
index c31657a9335f..000000000000
--- a/drivers/staging/crystalhd/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_CRYSTALHD) += crystalhd.o
-
-crystalhd-y := crystalhd_cmds.o \
- crystalhd_hw.o \
- crystalhd_lnx.o \
- crystalhd_misc.o
diff --git a/drivers/staging/crystalhd/TODO b/drivers/staging/crystalhd/TODO
deleted file mode 100644
index daca2d4d2a2f..000000000000
--- a/drivers/staging/crystalhd/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
-- Testing
-- Cleanup return codes
-- Cleanup typedefs
-- Allocate an Accelerator device class specific Major number,
- since we don't have any other open sourced accelerators, it is the only
- one in that category for now.
- A somewhat similar device is the DXR2/3
-
-Please send patches to:
-Greg Kroah-Hartman <greg@kroah.com>
-Naren Sankar <nsankar@broadcom.com>
-Jarod Wilson <jarod@wilsonet.com>
-Scott Davilla <davilla@4pi.com>
-Manu Abraham <abraham.manu@gmail.com>
-
diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h
deleted file mode 100644
index 647e116e10de..000000000000
--- a/drivers/staging/crystalhd/bc_dts_defs.h
+++ /dev/null
@@ -1,572 +0,0 @@
-/********************************************************************
- * Copyright(c) 2006-2009 Broadcom Corporation.
- *
- * Name: bc_dts_defs.h
- *
- * Description: Common definitions for all components. Only types
- * is allowed to be included from this file.
- *
- * AU
- *
- * HISTORY:
- *
- ********************************************************************
- * This header is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 2.1 of the License.
- *
- * This header 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 Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License
- * along with this header. If not, see <http://www.gnu.org/licenses/>.
- *******************************************************************/
-
-#ifndef _BC_DTS_DEFS_H_
-#define _BC_DTS_DEFS_H_
-
-#include <linux/types.h>
-
-/* BIT Mask */
-#define BC_BIT(_x) (1 << (_x))
-
-enum BC_STATUS {
- BC_STS_SUCCESS = 0,
- BC_STS_INV_ARG = 1,
- BC_STS_BUSY = 2,
- BC_STS_NOT_IMPL = 3,
- BC_STS_PGM_QUIT = 4,
- BC_STS_NO_ACCESS = 5,
- BC_STS_INSUFF_RES = 6,
- BC_STS_IO_ERROR = 7,
- BC_STS_NO_DATA = 8,
- BC_STS_VER_MISMATCH = 9,
- BC_STS_TIMEOUT = 10,
- BC_STS_FW_CMD_ERR = 11,
- BC_STS_DEC_NOT_OPEN = 12,
- BC_STS_ERR_USAGE = 13,
- BC_STS_IO_USER_ABORT = 14,
- BC_STS_IO_XFR_ERROR = 15,
- BC_STS_DEC_NOT_STARTED = 16,
- BC_STS_FWHEX_NOT_FOUND = 17,
- BC_STS_FMT_CHANGE = 18,
- BC_STS_HIF_ACCESS = 19,
- BC_STS_CMD_CANCELLED = 20,
- BC_STS_FW_AUTH_FAILED = 21,
- BC_STS_BOOTLOADER_FAILED = 22,
- BC_STS_CERT_VERIFY_ERROR = 23,
- BC_STS_DEC_EXIST_OPEN = 24,
- BC_STS_PENDING = 25,
- BC_STS_CLK_NOCHG = 26,
-
- /* Must be the last one.*/
- BC_STS_ERROR = -1
-};
-
-/*------------------------------------------------------*
- * Registry Key Definitions *
- *------------------------------------------------------*/
-#define BC_REG_KEY_MAIN_PATH "Software\\Broadcom\\MediaPC\\70010"
-#define BC_REG_KEY_FWPATH "FirmwareFilePath"
-#define BC_REG_KEY_SEC_OPT "DbgOptions"
-
-/*
- * Options:
- *
- * b[5] = Enable RSA KEY in EEPROM Support
- * b[6] = Enable Old PIB scheme. (0 = Use PIB with video scheme)
- *
- * b[12] = Enable send message to NotifyIcon
- *
- */
-
-enum BC_SW_OPTIONS {
- BC_OPT_DOSER_OUT_ENCRYPT = BC_BIT(3),
- BC_OPT_LINK_OUT_ENCRYPT = BC_BIT(29),
-};
-
-struct BC_REG_CONFIG {
- uint32_t DbgOptions;
-};
-
-#if defined(__KERNEL__) || defined(__LINUX_USER__)
-#else
-/* Align data structures */
-#define ALIGN(x) __declspec(align(x))
-#endif
-
-/* mode
- * b[0]..b[7] = _DtsDeviceOpenMode
- * b[8] = Load new FW
- * b[9] = Load file play back FW
- * b[10] = Disk format (0 for HD DVD and 1 for BLU ray)
- * b[11]-b[15] = default output resolution
- * b[16] = Skip TX CPB Buffer Check
- * b[17] = Adaptive Output Encrypt/Scramble Scheme
- * b[18]-b[31] = reserved for future use
- */
-
-/* To allow multiple apps to open the device. */
-enum DtsDeviceOpenMode {
- DTS_PLAYBACK_MODE = 0,
- DTS_DIAG_MODE,
- DTS_MONITOR_MODE,
- DTS_HWINIT_MODE
-};
-
-/* To enable the filter to selectively enable/disable fixes or erratas */
-enum DtsDeviceFixMode {
- DTS_LOAD_NEW_FW = BC_BIT(8),
- DTS_LOAD_FILE_PLAY_FW = BC_BIT(9),
- DTS_DISK_FMT_BD = BC_BIT(10),
- /* b[11]-b[15] : Default output resolution */
- DTS_SKIP_TX_CHK_CPB = BC_BIT(16),
- DTS_ADAPTIVE_OUTPUT_PER = BC_BIT(17),
- DTS_INTELLIMAP = BC_BIT(18),
- /* b[19]-b[21] : select clock frequency */
- DTS_PLAYBACK_DROP_RPT_MODE = BC_BIT(22)
-};
-
-#define DTS_DFLT_RESOLUTION(x) (x<<11)
-
-#define DTS_DFLT_CLOCK(x) (x<<19)
-
-/* F/W File Version corresponding to S/W Releases */
-enum FW_FILE_VER {
- /* S/W release: 02.04.02 F/W release 2.12.2.0 */
- BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0))
-};
-
-/*------------------------------------------------------*
- * Stream Types for DtsOpenDecoder() *
- *------------------------------------------------------*/
-enum DtsOpenDecStreamTypes {
- BC_STREAM_TYPE_ES = 0,
- BC_STREAM_TYPE_PES = 1,
- BC_STREAM_TYPE_TS = 2,
- BC_STREAM_TYPE_ES_TSTAMP = 6,
-};
-
-/*------------------------------------------------------*
- * Video Algorithms for DtsSetVideoParams() *
- *------------------------------------------------------*/
-enum DtsSetVideoParamsAlgo {
- BC_VID_ALGO_H264 = 0,
- BC_VID_ALGO_MPEG2 = 1,
- BC_VID_ALGO_VC1 = 4,
- BC_VID_ALGO_VC1MP = 7,
-};
-
-/*------------------------------------------------------*
- * MPEG Extension to the PPB *
- *------------------------------------------------------*/
-#define BC_MPEG_VALID_PANSCAN (1)
-
-struct BC_PIB_EXT_MPEG {
- uint32_t valid;
- /* Always valid, defaults to picture size if no
- * sequence display extension in the stream. */
- uint32_t display_horizontal_size;
- uint32_t display_vertical_size;
-
- /* MPEG_VALID_PANSCAN
- * Offsets are a copy values from the MPEG stream. */
- uint32_t offset_count;
- int32_t horizontal_offset[3];
- int32_t vertical_offset[3];
-};
-
-/*------------------------------------------------------*
- * H.264 Extension to the PPB *
- *------------------------------------------------------*/
-/* Bit definitions for 'other.h264.valid' field */
-#define H264_VALID_PANSCAN (1)
-#define H264_VALID_SPS_CROP (2)
-#define H264_VALID_VUI (4)
-
-struct BC_PIB_EXT_H264 {
- /* 'valid' specifies which fields (or sets of
- * fields) below are valid. If the corresponding
- * bit in 'valid' is NOT set then that field(s)
- * is (are) not initialized. */
- uint32_t valid;
-
- /* H264_VALID_PANSCAN */
- uint32_t pan_scan_count;
- int32_t pan_scan_left[3];
- int32_t pan_scan_right[3];
- int32_t pan_scan_top[3];
- int32_t pan_scan_bottom[3];
-
- /* H264_VALID_SPS_CROP */
- int32_t sps_crop_left;
- int32_t sps_crop_right;
- int32_t sps_crop_top;
- int32_t sps_crop_bottom;
-
- /* H264_VALID_VUI */
- uint32_t chroma_top;
- uint32_t chroma_bottom;
-};
-
-/*------------------------------------------------------*
- * VC1 Extension to the PPB *
- *------------------------------------------------------*/
-#define VC1_VALID_PANSCAN (1)
-
-struct BC_PIB_EXT_VC1 {
- uint32_t valid;
-
- /* Always valid, defaults to picture size if no
- * sequence display extension in the stream. */
- uint32_t display_horizontal_size;
- uint32_t display_vertical_size;
-
- /* VC1 pan scan windows */
- uint32_t num_panscan_windows;
- int32_t ps_horiz_offset[4];
- int32_t ps_vert_offset[4];
- int32_t ps_width[4];
- int32_t ps_height[4];
-};
-
-/*------------------------------------------------------*
- * Picture Information Block *
- *------------------------------------------------------*/
-#if defined(__LINUX_USER__)
-/* Values for 'pulldown' field. '0' means no pulldown information
- * was present for this picture. */
-enum {
- vdecNoPulldownInfo = 0,
- vdecTop = 1,
- vdecBottom = 2,
- vdecTopBottom = 3,
- vdecBottomTop = 4,
- vdecTopBottomTop = 5,
- vdecBottomTopBottom = 6,
- vdecFrame_X2 = 7,
- vdecFrame_X3 = 8,
- vdecFrame_X1 = 9,
- vdecFrame_X4 = 10,
-};
-
-/* Values for the 'frame_rate' field. */
-enum {
- vdecFrameRateUnknown = 0,
- vdecFrameRate23_97,
- vdecFrameRate24,
- vdecFrameRate25,
- vdecFrameRate29_97,
- vdecFrameRate30,
- vdecFrameRate50,
- vdecFrameRate59_94,
- vdecFrameRate60,
-};
-
-/* Values for the 'aspect_ratio' field. */
-enum {
- vdecAspectRatioUnknown = 0,
- vdecAspectRatioSquare,
- vdecAspectRatio12_11,
- vdecAspectRatio10_11,
- vdecAspectRatio16_11,
- vdecAspectRatio40_33,
- vdecAspectRatio24_11,
- vdecAspectRatio20_11,
- vdecAspectRatio32_11,
- vdecAspectRatio80_33,
- vdecAspectRatio18_11,
- vdecAspectRatio15_11,
- vdecAspectRatio64_33,
- vdecAspectRatio160_99,
- vdecAspectRatio4_3,
- vdecAspectRatio16_9,
- vdecAspectRatio221_1,
- vdecAspectRatioOther = 255,
-};
-
-/* Values for the 'colour_primaries' field. */
-enum {
- vdecColourPrimariesUnknown = 0,
- vdecColourPrimariesBT709,
- vdecColourPrimariesUnspecified,
- vdecColourPrimariesReserved,
- vdecColourPrimariesBT470_2M = 4,
- vdecColourPrimariesBT470_2BG,
- vdecColourPrimariesSMPTE170M,
- vdecColourPrimariesSMPTE240M,
- vdecColourPrimariesGenericFilm,
-};
-/**
- * @vdecRESOLUTION_CUSTOM: custom
- * @vdecRESOLUTION_480i: 480i
- * @vdecRESOLUTION_1080i: 1080i (1920x1080, 60i)
- * @vdecRESOLUTION_NTSC: NTSC (720x483, 60i)
- * @vdecRESOLUTION_480p: 480p (720x480, 60p)
- * @vdecRESOLUTION_720p: 720p (1280x720, 60p)
- * @vdecRESOLUTION_PAL1: PAL_1 (720x576, 50i)
- * @vdecRESOLUTION_1080i25: 1080i25 (1920x1080, 50i)
- * @vdecRESOLUTION_720p50: 720p50 (1280x720, 50p)
- * @vdecRESOLUTION_576p: 576p (720x576, 50p)
- * @vdecRESOLUTION_1080i29_97: 1080i (1920x1080, 59.94i)
- * @vdecRESOLUTION_720p59_94: 720p (1280x720, 59.94p)
- * @vdecRESOLUTION_SD_DVD: SD DVD (720x483, 60i)
- * @vdecRESOLUTION_480p656: 480p (720x480, 60p),
- * output bus width 8 bit, clock 74.25MHz
- * @vdecRESOLUTION_1080p23_976: 1080p23_976 (1920x1080, 23.976p)
- * @vdecRESOLUTION_720p23_976: 720p23_976 (1280x720p, 23.976p)
- * @vdecRESOLUTION_240p29_97: 240p (1440x240, 29.97p )
- * @vdecRESOLUTION_240p30: 240p (1440x240, 30p)
- * @vdecRESOLUTION_288p25: 288p (1440x288p, 25p)
- * @vdecRESOLUTION_1080p29_97: 1080p29_97 (1920x1080, 29.97p)
- * @vdecRESOLUTION_1080p30: 1080p30 (1920x1080, 30p)
- * @vdecRESOLUTION_1080p24: 1080p24 (1920x1080, 24p)
- * @vdecRESOLUTION_1080p25: 1080p25 (1920x1080, 25p)
- * @vdecRESOLUTION_720p24: 720p24 (1280x720, 25p)
- * @vdecRESOLUTION_720p29_97: 720p29.97 (1280x720, 29.97p)
- * @vdecRESOLUTION_480p23_976: 480p23.976 (720*480, 23.976)
- * @vdecRESOLUTION_480p29_97: 480p29.976 (720*480, 29.97p)
- * @vdecRESOLUTION_576p25: 576p25 (720*576, 25p)
- * @vdecRESOLUTION_480p0: 480p (720x480, 0p)
- * @vdecRESOLUTION_480i0: 480i (720x480, 0i)
- * @vdecRESOLUTION_576p0: 576p (720x576, 0p)
- * @vdecRESOLUTION_720p0: 720p (1280x720, 0p)
- * @vdecRESOLUTION_1080p0: 1080p (1920x1080, 0p)
- * @vdecRESOLUTION_1080i0: 1080i (1920x1080, 0i)
- */
-enum {
- vdecRESOLUTION_CUSTOM = 0x00000000,
- vdecRESOLUTION_480i = 0x00000001,
- vdecRESOLUTION_1080i = 0x00000002,
- vdecRESOLUTION_NTSC = 0x00000003,
- vdecRESOLUTION_480p = 0x00000004,
- vdecRESOLUTION_720p = 0x00000005,
- vdecRESOLUTION_PAL1 = 0x00000006,
- vdecRESOLUTION_1080i25 = 0x00000007,
- vdecRESOLUTION_720p50 = 0x00000008,
- vdecRESOLUTION_576p = 0x00000009,
- vdecRESOLUTION_1080i29_97 = 0x0000000A,
- vdecRESOLUTION_720p59_94 = 0x0000000B,
- vdecRESOLUTION_SD_DVD = 0x0000000C,
- vdecRESOLUTION_480p656 = 0x0000000D,
- vdecRESOLUTION_1080p23_976 = 0x0000000E,
- vdecRESOLUTION_720p23_976 = 0x0000000F,
- vdecRESOLUTION_240p29_97 = 0x00000010,
- vdecRESOLUTION_240p30 = 0x00000011,
- vdecRESOLUTION_288p25 = 0x00000012,
- vdecRESOLUTION_1080p29_97 = 0x00000013,
- vdecRESOLUTION_1080p30 = 0x00000014,
- vdecRESOLUTION_1080p24 = 0x00000015,
- vdecRESOLUTION_1080p25 = 0x00000016,
- vdecRESOLUTION_720p24 = 0x00000017,
- vdecRESOLUTION_720p29_97 = 0x00000018,
- vdecRESOLUTION_480p23_976 = 0x00000019,
- vdecRESOLUTION_480p29_97 = 0x0000001A,
- vdecRESOLUTION_576p25 = 0x0000001B,
- /* For Zero Frame Rate */
- vdecRESOLUTION_480p0 = 0x0000001C,
- vdecRESOLUTION_480i0 = 0x0000001D,
- vdecRESOLUTION_576p0 = 0x0000001E,
- vdecRESOLUTION_720p0 = 0x0000001F,
- vdecRESOLUTION_1080p0 = 0x00000020,
- vdecRESOLUTION_1080i0 = 0x00000021,
-};
-
-/* Bit definitions for 'flags' field */
-#define VDEC_FLAG_EOS (0x0004)
-
-#define VDEC_FLAG_FRAME (0x0000)
-#define VDEC_FLAG_FIELDPAIR (0x0008)
-#define VDEC_FLAG_TOPFIELD (0x0010)
-#define VDEC_FLAG_BOTTOMFIELD (0x0018)
-
-#define VDEC_FLAG_PROGRESSIVE_SRC (0x0000)
-#define VDEC_FLAG_INTERLACED_SRC (0x0020)
-#define VDEC_FLAG_UNKNOWN_SRC (0x0040)
-
-#define VDEC_FLAG_BOTTOM_FIRST (0x0080)
-#define VDEC_FLAG_LAST_PICTURE (0x0100)
-
-#define VDEC_FLAG_PICTURE_META_DATA_PRESENT (0x40000)
-
-#endif /* __LINUX_USER__ */
-
-enum _BC_OUTPUT_FORMAT {
- MODE420 = 0x0,
- MODE422_YUY2 = 0x1,
- MODE422_UYVY = 0x2,
-};
-/**
- * struct BC_PIC_INFO_BLOCK
- * @timeStam;: Timestamp
- * @picture_number: Ordinal display number
- * @width: pixels
- * @height: pixels
- * @chroma_format: 0x420, 0x422 or 0x444
- * @n_drop;: number of non-reference frames
- * remaining to be dropped
- */
-struct BC_PIC_INFO_BLOCK {
- /* Common fields. */
- uint64_t timeStamp;
- uint32_t picture_number;
- uint32_t width;
- uint32_t height;
- uint32_t chroma_format;
- uint32_t pulldown;
- uint32_t flags;
- uint32_t frame_rate;
- uint32_t aspect_ratio;
- uint32_t colour_primaries;
- uint32_t picture_meta_payload;
- uint32_t sess_num;
- uint32_t ycom;
- uint32_t custom_aspect_ratio_width_height;
- uint32_t n_drop; /* number of non-reference frames
- remaining to be dropped */
-
- /* Protocol-specific extensions. */
- union {
- struct BC_PIB_EXT_H264 h264;
- struct BC_PIB_EXT_MPEG mpeg;
- struct BC_PIB_EXT_VC1 vc1;
- } other;
-
-};
-
-/*------------------------------------------------------*
- * ProcOut Info *
- *------------------------------------------------------*/
-
-/**
- * enum POUT_OPTIONAL_IN_FLAGS - Optional flags for ProcOut Interface.
- * @BC_POUT_FLAGS_YV12: Copy Data in YV12 format
- * @BC_POUT_FLAGS_STRIDE: Stride size is valid.
- * @BC_POUT_FLAGS_SIZE: Take size information from Application
- * @BC_POUT_FLAGS_INTERLACED: copy only half the bytes
- * @BC_POUT_FLAGS_INTERLEAVED: interleaved frame
- * @: * @BC_POUT_FLAGS_FMT_CHANGE: Data is not VALID when this flag is set
- * @BC_POUT_FLAGS_PIB_VALID: PIB Information valid
- * @BC_POUT_FLAGS_ENCRYPTED: Data is encrypted.
- * @BC_POUT_FLAGS_FLD_BOT: Bottom Field data
- */
-enum POUT_OPTIONAL_IN_FLAGS_ {
- /* Flags from App to Device */
- BC_POUT_FLAGS_YV12 = 0x01,
- BC_POUT_FLAGS_STRIDE = 0x02,
- BC_POUT_FLAGS_SIZE = 0x04,
- BC_POUT_FLAGS_INTERLACED = 0x08,
- BC_POUT_FLAGS_INTERLEAVED = 0x10,
-
- /* Flags from Device to APP */
- BC_POUT_FLAGS_FMT_CHANGE = 0x10000,
- BC_POUT_FLAGS_PIB_VALID = 0x20000,
- BC_POUT_FLAGS_ENCRYPTED = 0x40000,
- BC_POUT_FLAGS_FLD_BOT = 0x80000,
-};
-
-typedef enum BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width,
- uint32_t height, uint32_t stride, void *pOut);
-
-/* Line 21 Closed Caption */
-/* User Data */
-#define MAX_UD_SIZE 1792 /* 1920 - 128 */
-
-/**
- * struct BC_DTS_PROC_OUT
- * @Ybuff: Caller Supplied buffer for Y data
- * @YbuffSz: Caller Supplied Y buffer size
- * @YBuffDoneSz: Transferred Y datasize
- * @*UVbuff: Caller Supplied buffer for UV data
- * @UVbuffSz: Caller Supplied UV buffer size
- * @UVBuffDoneSz: Transferred UV data size
- * @StrideSz: Caller supplied Stride Size
- * @PoutFlags: Call IN Flags
- * @discCnt: Picture discontinuity count
- * @PicInfo: Picture Information Block Data
- * @b422Mode: Picture output Mode
- * @bPibEnc: PIB encrypted
- */
-struct BC_DTS_PROC_OUT {
- uint8_t *Ybuff;
- uint32_t YbuffSz;
- uint32_t YBuffDoneSz;
-
- uint8_t *UVbuff;
- uint32_t UVbuffSz;
- uint32_t UVBuffDoneSz;
-
- uint32_t StrideSz;
- uint32_t PoutFlags;
-
- uint32_t discCnt;
-
- struct BC_PIC_INFO_BLOCK PicInfo;
-
- /* Line 21 Closed Caption */
- /* User Data */
- uint32_t UserDataSz;
- uint8_t UserData[MAX_UD_SIZE];
-
- void *hnd;
- dts_pout_callback AppCallBack;
- uint8_t DropFrames;
- uint8_t b422Mode;
- uint8_t bPibEnc;
- uint8_t bRevertScramble;
-
-};
-/**
- * struct BC_DTS_STATUS
- * @ReadyListCount: Number of frames in ready list (reported by driver)
- * @PowerStateChange: Number of active state power
- * transitions (reported by driver)
- * @FramesDropped: Number of frames dropped. (reported by DIL)
- * @FramesCaptured: Number of frames captured. (reported by DIL)
- * @FramesRepeated: Number of frames repeated. (reported by DIL)
- * @InputCount: Times compressed video has been sent to the HW.
- * i.e. Successful DtsProcInput() calls (reported by DIL)
- * @InputTotalSize: Amount of compressed video that has been sent to the HW.
- * (reported by DIL)
- * @InputBusyCount: Times compressed video has attempted to be sent to the HW
- * but the input FIFO was full. (reported by DIL)
- * @PIBMissCount: Amount of times a PIB is invalid. (reported by DIL)
- * @cpbEmptySize: supported only for H.264, specifically changed for
- * Adobe. Report size of CPB buffer available. (reported by DIL)
- * @NextTimeStamp: TimeStamp of the next picture that will be returned
- * by a call to ProcOutput. Added for Adobe. Reported
- * back from the driver
- */
-struct BC_DTS_STATUS {
- uint8_t ReadyListCount;
- uint8_t FreeListCount;
- uint8_t PowerStateChange;
- uint8_t reserved_[1];
- uint32_t FramesDropped;
- uint32_t FramesCaptured;
- uint32_t FramesRepeated;
- uint32_t InputCount;
- uint64_t InputTotalSize;
- uint32_t InputBusyCount;
- uint32_t PIBMissCount;
- uint32_t cpbEmptySize;
- uint64_t NextTimeStamp;
- uint8_t reserved__[16];
-};
-
-#define BC_SWAP32(_v) \
- ((((_v) & 0xFF000000)>>24)| \
- (((_v) & 0x00FF0000)>>8)| \
- (((_v) & 0x0000FF00)<<8)| \
- (((_v) & 0x000000FF)<<24))
-
-#define WM_AGENT_TRAYICON_DECODER_OPEN 10001
-#define WM_AGENT_TRAYICON_DECODER_CLOSE 10002
-#define WM_AGENT_TRAYICON_DECODER_START 10003
-#define WM_AGENT_TRAYICON_DECODER_STOP 10004
-#define WM_AGENT_TRAYICON_DECODER_RUN 10005
-#define WM_AGENT_TRAYICON_DECODER_PAUSE 10006
-
-
-#endif /* _BC_DTS_DEFS_H_ */
diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h
deleted file mode 100644
index 92b0cff248cb..000000000000
--- a/drivers/staging/crystalhd/bc_dts_glob_lnx.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/********************************************************************
- * Copyright(c) 2006-2009 Broadcom Corporation.
- *
- * Name: bc_dts_glob_lnx.h
- *
- * Description: Wrapper to Windows dts_glob.h for Link-Linux usage.
- * The idea is to define additional Linux related defs
- * in this file to avoid changes to existing Windows
- * glob file.
- *
- * AU
- *
- * HISTORY:
- *
- ********************************************************************
- * This header is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 2.1 of the License.
- *
- * This header 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 Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License
- * along with this header. If not, see <http://www.gnu.org/licenses/>.
- *******************************************************************/
-
-#ifndef _BC_DTS_GLOB_LNX_H_
-#define _BC_DTS_GLOB_LNX_H_
-
-#ifdef __LINUX_USER__
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <time.h>
-#include <arpa/inet.h>
-#include <linux/param.h>
-#include <linux/ioctl.h>
-#include <sys/select.h>
-
-#define DRVIFLIB_INT_API
-
-#endif
-
-#include "crystalhd.h"
-
-#define CRYSTALHD_API_NAME "crystalhd"
-#define CRYSTALHD_API_DEV_NAME "/dev/crystalhd"
-
-/*
- * These are SW stack tunable parameters shared
- * between the driver and the application.
- */
-enum BC_DTS_GLOBALS {
- BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */
- PCI_CFG_SIZE = 256, /* PCI config size buffer */
- BC_IOCTL_DATA_POOL_SIZE = 8, /* BC_IOCTL_DATA Pool size */
- BC_LINK_MAX_OPENS = 3, /* Maximum simultaneous opens*/
- BC_LINK_MAX_SGLS = 1024, /* Maximum SG elements 4M/4K */
- BC_TX_LIST_CNT = 2, /* Max Tx DMA Rings */
- BC_RX_LIST_CNT = 8, /* Max Rx DMA Rings*/
- BC_PROC_OUTPUT_TIMEOUT = 3000, /* Milliseconds */
- BC_INFIFO_THRESHOLD = 0x10000,
-};
-
-struct BC_CMD_REG_ACC {
- uint32_t Offset;
- uint32_t Value;
-};
-
-struct BC_CMD_DEV_MEM {
- uint32_t StartOff;
- uint32_t NumDwords;
- uint32_t Rsrd;
-};
-
-/* FW Passthrough command structure */
-enum bc_fw_cmd_flags {
- BC_FW_CMD_FLAGS_NONE = 0,
- BC_FW_CMD_PIB_QS = 0x01,
-};
-
-struct BC_FW_CMD {
- uint32_t cmd[BC_MAX_FW_CMD_BUFF_SZ];
- uint32_t rsp[BC_MAX_FW_CMD_BUFF_SZ];
- uint32_t flags;
- uint32_t add_data;
-};
-
-struct BC_HW_TYPE {
- uint16_t PciDevId;
- uint16_t PciVenId;
- uint8_t HwRev;
- uint8_t Align[3];
-};
-
-struct BC_PCI_CFG {
- uint32_t Size;
- uint32_t Offset;
- uint8_t pci_cfg_space[PCI_CFG_SIZE];
-};
-
-struct BC_VERSION_INFO {
- uint8_t DriverMajor;
- uint8_t DriverMinor;
- uint16_t DriverRevision;
-};
-
-struct BC_START_RX_CAP {
- uint32_t Rsrd;
- uint32_t StartDeliveryThsh;
- uint32_t PauseThsh;
- uint32_t ResumeThsh;
-};
-
-struct BC_FLUSH_RX_CAP {
- uint32_t Rsrd;
- uint32_t bDiscardOnly;
-};
-
-struct BC_DTS_STATS {
- uint8_t drvRLL;
- uint8_t drvFLL;
- uint8_t eosDetected;
- uint8_t pwr_state_change;
-
- /* Stats from App */
- uint32_t opFrameDropped;
- uint32_t opFrameCaptured;
- uint32_t ipSampleCnt;
- uint64_t ipTotalSize;
- uint32_t reptdFrames;
- uint32_t pauseCount;
- uint32_t pibMisses;
- uint32_t discCounter;
-
- /* Stats from Driver */
- uint32_t TxFifoBsyCnt;
- uint32_t intCount;
- uint32_t DrvIgnIntrCnt;
- uint32_t DrvTotalFrmDropped;
- uint32_t DrvTotalHWErrs;
- uint32_t DrvTotalPIBFlushCnt;
- uint32_t DrvTotalFrmCaptured;
- uint32_t DrvPIBMisses;
- uint32_t DrvPauseTime;
- uint32_t DrvRepeatedFrms;
- uint32_t res1[13];
-
-};
-
-struct BC_PROC_INPUT {
- uint8_t *pDmaBuff;
- uint32_t BuffSz;
- uint8_t Mapped;
- uint8_t Encrypted;
- uint8_t Rsrd[2];
- uint32_t DramOffset; /* For debug use only */
-};
-
-struct BC_DEC_YUV_BUFFS {
- uint32_t b422Mode;
- uint8_t *YuvBuff;
- uint32_t YuvBuffSz;
- uint32_t UVbuffOffset;
- uint32_t YBuffDoneSz;
- uint32_t UVBuffDoneSz;
- uint32_t RefCnt;
-};
-
-enum DECOUT_COMPLETION_FLAGS {
- COMP_FLAG_NO_INFO = 0x00,
- COMP_FLAG_FMT_CHANGE = 0x01,
- COMP_FLAG_PIB_VALID = 0x02,
- COMP_FLAG_DATA_VALID = 0x04,
- COMP_FLAG_DATA_ENC = 0x08,
- COMP_FLAG_DATA_BOT = 0x10,
-};
-
-struct BC_DEC_OUT_BUFF {
- struct BC_DEC_YUV_BUFFS OutPutBuffs;
- struct BC_PIC_INFO_BLOCK PibInfo;
- uint32_t Flags;
- uint32_t BadFrCnt;
-};
-
-struct BC_NOTIFY_MODE {
- uint32_t Mode;
- uint32_t Rsvr[3];
-};
-
-struct BC_CLOCK {
- uint32_t clk;
- uint32_t Rsvr[3];
-};
-
-struct BC_IOCTL_DATA {
- enum BC_STATUS RetSts;
- uint32_t IoctlDataSz;
- uint32_t Timeout;
- union {
- struct BC_CMD_REG_ACC regAcc;
- struct BC_CMD_DEV_MEM devMem;
- struct BC_FW_CMD fwCmd;
- struct BC_HW_TYPE hwType;
- struct BC_PCI_CFG pciCfg;
- struct BC_VERSION_INFO VerInfo;
- struct BC_PROC_INPUT ProcInput;
- struct BC_DEC_YUV_BUFFS RxBuffs;
- struct BC_DEC_OUT_BUFF DecOutData;
- struct BC_START_RX_CAP RxCap;
- struct BC_FLUSH_RX_CAP FlushRxCap;
- struct BC_DTS_STATS drvStat;
- struct BC_NOTIFY_MODE NotifyMode;
- struct BC_CLOCK clockValue;
- } u;
- struct _BC_IOCTL_DATA *next;
-};
-
-enum BC_DRV_CMD {
- DRV_CMD_VERSION = 0, /* Get SW version */
- DRV_CMD_GET_HWTYPE, /* Get HW version and type Dozer/Tank */
- DRV_CMD_REG_RD, /* Read Device Register */
- DRV_CMD_REG_WR, /* Write Device Register */
- DRV_CMD_FPGA_RD, /* Read FPGA Register */
- DRV_CMD_FPGA_WR, /* Write FPGA Register */
- DRV_CMD_MEM_RD, /* Read Device Memory */
- DRV_CMD_MEM_WR, /* Write Device Memory */
- DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */
- DRV_CMD_WR_PCI_CFG, /* Write the PCI Configuration Space*/
- DRV_CMD_FW_DOWNLOAD, /* Download Firmware */
- DRV_ISSUE_FW_CMD, /* Issue FW Cmd (pass through mode) */
- DRV_CMD_PROC_INPUT, /* Process Input Sample */
- DRV_CMD_ADD_RXBUFFS, /* Add Rx side buffers to driver pool */
- DRV_CMD_FETCH_RXBUFF, /* Get Rx DMAed buffer */
- DRV_CMD_START_RX_CAP, /* Start Rx Buffer Capture */
- DRV_CMD_FLUSH_RX_CAP, /* Stop the capture for now...
- we will enhance this later*/
- DRV_CMD_GET_DRV_STAT, /* Get Driver Internal Statistics */
- DRV_CMD_RST_DRV_STAT, /* Reset Driver Internal Statistics */
- DRV_CMD_NOTIFY_MODE, /* Notify the Mode to driver
- in which the application is Operating*/
- DRV_CMD_CHANGE_CLOCK, /* Change the core clock to either save power
- or improve performance */
-
- /* MUST be the last one.. */
- DRV_CMD_END, /* End of the List.. */
-};
-
-#define BC_IOC_BASE 'b'
-#define BC_IOC_VOID _IOC_NONE
-#define BC_IOC_IOWR(nr, type) _IOWR(BC_IOC_BASE, nr, type)
-#define BC_IOCTL_MB struct BC_IOCTL_DATA
-
-#define BCM_IOC_GET_VERSION BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB)
-#define BCM_IOC_GET_HWTYPE BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB)
-#define BCM_IOC_REG_RD BC_IOC_IOWR(DRV_CMD_REG_RD, BC_IOCTL_MB)
-#define BCM_IOC_REG_WR BC_IOC_IOWR(DRV_CMD_REG_WR, BC_IOCTL_MB)
-#define BCM_IOC_MEM_RD BC_IOC_IOWR(DRV_CMD_MEM_RD, BC_IOCTL_MB)
-#define BCM_IOC_MEM_WR BC_IOC_IOWR(DRV_CMD_MEM_WR, BC_IOCTL_MB)
-#define BCM_IOC_FPGA_RD BC_IOC_IOWR(DRV_CMD_FPGA_RD, BC_IOCTL_MB)
-#define BCM_IOC_FPGA_WR BC_IOC_IOWR(DRV_CMD_FPGA_WR, BC_IOCTL_MB)
-#define BCM_IOC_RD_PCI_CFG BC_IOC_IOWR(DRV_CMD_RD_PCI_CFG, BC_IOCTL_MB)
-#define BCM_IOC_WR_PCI_CFG BC_IOC_IOWR(DRV_CMD_WR_PCI_CFG, BC_IOCTL_MB)
-#define BCM_IOC_PROC_INPUT BC_IOC_IOWR(DRV_CMD_PROC_INPUT, BC_IOCTL_MB)
-#define BCM_IOC_ADD_RXBUFFS BC_IOC_IOWR(DRV_CMD_ADD_RXBUFFS, BC_IOCTL_MB)
-#define BCM_IOC_FETCH_RXBUFF BC_IOC_IOWR(DRV_CMD_FETCH_RXBUFF, BC_IOCTL_MB)
-#define BCM_IOC_FW_CMD BC_IOC_IOWR(DRV_ISSUE_FW_CMD, BC_IOCTL_MB)
-#define BCM_IOC_START_RX_CAP BC_IOC_IOWR(DRV_CMD_START_RX_CAP, BC_IOCTL_MB)
-#define BCM_IOC_FLUSH_RX_CAP BC_IOC_IOWR(DRV_CMD_FLUSH_RX_CAP, BC_IOCTL_MB)
-#define BCM_IOC_GET_DRV_STAT BC_IOC_IOWR(DRV_CMD_GET_DRV_STAT, BC_IOCTL_MB)
-#define BCM_IOC_RST_DRV_STAT BC_IOC_IOWR(DRV_CMD_RST_DRV_STAT, BC_IOCTL_MB)
-#define BCM_IOC_NOTIFY_MODE BC_IOC_IOWR(DRV_CMD_NOTIFY_MODE, BC_IOCTL_MB)
-#define BCM_IOC_FW_DOWNLOAD BC_IOC_IOWR(DRV_CMD_FW_DOWNLOAD, BC_IOCTL_MB)
-#define BCM_IOC_CHG_CLK BC_IOC_IOWR(DRV_CMD_CHANGE_CLOCK, BC_IOCTL_MB)
-#define BCM_IOC_END BC_IOC_VOID
-
-/* Wrapper for main IOCTL data */
-struct crystalhd_ioctl_data {
- struct BC_IOCTL_DATA udata; /* IOCTL from App..*/
- uint32_t u_id; /* Driver specific user ID */
- uint32_t cmd; /* Cmd ID for driver's use. */
- void *add_cdata; /* Additional command specific data..*/
- uint32_t add_cdata_sz; /* Additional command specific data size */
- struct crystalhd_ioctl_data *next; /* List/Fifo management */
-};
-
-enum crystalhd_kmod_ver {
- crystalhd_kmod_major = 0,
- crystalhd_kmod_minor = 9,
- crystalhd_kmod_rev = 27,
-};
-
-#endif
diff --git a/drivers/staging/crystalhd/bcm_70012_regs.h b/drivers/staging/crystalhd/bcm_70012_regs.h
deleted file mode 100644
index da199ad8e27e..000000000000
--- a/drivers/staging/crystalhd/bcm_70012_regs.h
+++ /dev/null
@@ -1,758 +0,0 @@
-/***************************************************************************
- * Copyright (c) 1999-2009, Broadcom Corporation.
- *
- * Name: bcm_70012_regs.h
- *
- * Description: BCM70012 registers
- *
- ********************************************************************
- * This header is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation, either version 2.1 of the License.
- *
- * This header 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 Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License
- * along with this header. If not, see <http://www.gnu.org/licenses/>.
- ***************************************************************************/
-
-#ifndef MACFILE_H__
-#define MACFILE_H__
-
-/**
- * m = memory, c = core, r = register, f = field, d = data.
- */
-#if !defined(GET_FIELD) && !defined(SET_FIELD)
-#define BRCM_ALIGN(c, r, f) c##_##r##_##f##_ALIGN
-#define BRCM_BITS(c, r, f) c##_##r##_##f##_BITS
-#define BRCM_MASK(c, r, f) c##_##r##_##f##_MASK
-#define BRCM_SHIFT(c, r, f) c##_##r##_##f##_SHIFT
-
-#define GET_FIELD(m, c, r, f) \
- ((((m) & BRCM_MASK(c, r, f)) >> BRCM_SHIFT(c, r, f)) << \
- BRCM_ALIGN(c, r, f))
-
-#define SET_FIELD(m, c, r, f, d) \
- ((m) = (((m) & ~BRCM_MASK(c, r, f)) | ((((d) >> BRCM_ALIGN(c, r, f)) << \
- BRCM_SHIFT(c, r, f)) & BRCM_MASK(c, r, f))) \
- )
-
-#define SET_TYPE_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, c##_##d)
-#define SET_NAME_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, c##_##r##_##f##_##d)
-#define SET_VALUE_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, d)
-
-#endif /* GET & SET */
-
-/****************************************************************************
- * Core Enums.
- ***************************************************************************/
-/****************************************************************************
- * Enums: AES_RGR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define AES_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define AES_RGR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: CCE_RGR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define CCE_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define CCE_RGR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: DBU_RGR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define DBU_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define DBU_RGR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: DCI_RGR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define DCI_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define DCI_RGR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: GISB_ARBITER_DEASSERT_ASSERT
- ***************************************************************************/
-#define GISB_ARBITER_DEASSERT_ASSERT_DEASSERT 0
-#define GISB_ARBITER_DEASSERT_ASSERT_ASSERT 1
-
-/****************************************************************************
- * Enums: GISB_ARBITER_UNMASK_MASK
- ***************************************************************************/
-#define GISB_ARBITER_UNMASK_MASK_UNMASK 0
-#define GISB_ARBITER_UNMASK_MASK_MASK 1
-
-/****************************************************************************
- * Enums: GISB_ARBITER_DISABLE_ENABLE
- ***************************************************************************/
-#define GISB_ARBITER_DISABLE_ENABLE_DISABLE 0
-#define GISB_ARBITER_DISABLE_ENABLE_ENABLE 1
-
-/****************************************************************************
- * Enums: I2C_GR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define I2C_GR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define I2C_GR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: MISC_GR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define MISC_GR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define MISC_GR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * Enums: OTP_GR_BRIDGE_RESET_CTRL
- ***************************************************************************/
-#define OTP_GR_BRIDGE_RESET_CTRL_DEASSERT 0
-#define OTP_GR_BRIDGE_RESET_CTRL_ASSERT 1
-
-/****************************************************************************
- * BCM70012_TGT_TOP_PCIE_CFG
- ***************************************************************************/
-#define PCIE_CFG_DEVICE_VENDOR_ID 0x00000000 /* DEVICE_VENDOR_ID Register */
-#define PCIE_CFG_STATUS_COMMAND 0x00000004 /* STATUS_COMMAND Register */
-#define PCIE_CFG_PCI_CLASSCODE_AND_REVISION_ID 0x00000008 /* PCI_CLASSCODE_AND_REVISION_ID Register */
-#define PCIE_CFG_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE 0x0000000c /* BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE Register */
-#define PCIE_CFG_BASE_ADDRESS_1 0x00000010 /* BASE_ADDRESS_1 Register */
-#define PCIE_CFG_BASE_ADDRESS_2 0x00000014 /* BASE_ADDRESS_2 Register */
-#define PCIE_CFG_BASE_ADDRESS_3 0x00000018 /* BASE_ADDRESS_3 Register */
-#define PCIE_CFG_BASE_ADDRESS_4 0x0000001c /* BASE_ADDRESS_4 Register */
-#define PCIE_CFG_CARDBUS_CIS_POINTER 0x00000028 /* CARDBUS_CIS_POINTER Register */
-#define PCIE_CFG_SUBSYSTEM_DEVICE_VENDOR_ID 0x0000002c /* SUBSYSTEM_DEVICE_VENDOR_ID Register */
-#define PCIE_CFG_EXPANSION_ROM_BASE_ADDRESS 0x00000030 /* EXPANSION_ROM_BASE_ADDRESS Register */
-#define PCIE_CFG_CAPABILITIES_POINTER 0x00000034 /* CAPABILITIES_POINTER Register */
-#define PCIE_CFG_INTERRUPT 0x0000003c /* INTERRUPT Register */
-#define PCIE_CFG_VPD_CAPABILITIES 0x00000040 /* VPD_CAPABILITIES Register */
-#define PCIE_CFG_VPD_DATA 0x00000044 /* VPD_DATA Register */
-#define PCIE_CFG_POWER_MANAGEMENT_CAPABILITY 0x00000048 /* POWER_MANAGEMENT_CAPABILITY Register */
-#define PCIE_CFG_POWER_MANAGEMENT_CONTROL_STATUS 0x0000004c /* POWER_MANAGEMENT_CONTROL_STATUS Register */
-#define PCIE_CFG_MSI_CAPABILITY_HEADER 0x00000050 /* MSI_CAPABILITY_HEADER Register */
-#define PCIE_CFG_MSI_LOWER_ADDRESS 0x00000054 /* MSI_LOWER_ADDRESS Register */
-#define PCIE_CFG_MSI_UPPER_ADDRESS_REGISTER 0x00000058 /* MSI_UPPER_ADDRESS_REGISTER Register */
-#define PCIE_CFG_MSI_DATA 0x0000005c /* MSI_DATA Register */
-#define PCIE_CFG_BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER 0x00000060 /* BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER Register */
-#define PCIE_CFG_RESET_COUNTERS_INITIAL_VALUES 0x00000064 /* RESET_COUNTERS_INITIAL_VALUES Register */
-#define PCIE_CFG_MISCELLANEOUS_HOST_CONTROL 0x00000068 /* MISCELLANEOUS_HOST_CONTROL Register */
-#define PCIE_CFG_SPARE 0x0000006c /* SPARE Register */
-#define PCIE_CFG_PCI_STATE 0x00000070 /* PCI_STATE Register */
-#define PCIE_CFG_CLOCK_CONTROL 0x00000074 /* CLOCK_CONTROL Register */
-#define PCIE_CFG_REGISTER_BASE 0x00000078 /* REGISTER_BASE Register */
-#define PCIE_CFG_MEMORY_BASE 0x0000007c /* MEMORY_BASE Register */
-#define PCIE_CFG_REGISTER_DATA 0x00000080 /* REGISTER_DATA Register */
-#define PCIE_CFG_MEMORY_DATA 0x00000084 /* MEMORY_DATA Register */
-#define PCIE_CFG_EXPANSION_ROM_BAR_SIZE 0x00000088 /* EXPANSION_ROM_BAR_SIZE Register */
-#define PCIE_CFG_EXPANSION_ROM_ADDRESS 0x0000008c /* EXPANSION_ROM_ADDRESS Register */
-#define PCIE_CFG_EXPANSION_ROM_DATA 0x00000090 /* EXPANSION_ROM_DATA Register */
-#define PCIE_CFG_VPD_INTERFACE 0x00000094 /* VPD_INTERFACE Register */
-#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER 0x00000098 /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER Register */
-#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER 0x0000009c /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER Register */
-#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER 0x000000a0 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER Register */
-#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER 0x000000a4 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER Register */
-#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER 0x000000a8 /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER Register */
-#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER 0x000000ac /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER Register */
-#define PCIE_CFG_INT_MAILBOX_UPPER 0x000000b0 /* INT_MAILBOX_UPPER Register */
-#define PCIE_CFG_INT_MAILBOX_LOWER 0x000000b4 /* INT_MAILBOX_LOWER Register */
-#define PCIE_CFG_PRODUCT_ID_AND_ASIC_REVISION 0x000000bc /* PRODUCT_ID_AND_ASIC_REVISION Register */
-#define PCIE_CFG_FUNCTION_EVENT 0x000000c0 /* FUNCTION_EVENT Register */
-#define PCIE_CFG_FUNCTION_EVENT_MASK 0x000000c4 /* FUNCTION_EVENT_MASK Register */
-#define PCIE_CFG_FUNCTION_PRESENT 0x000000c8 /* FUNCTION_PRESENT Register */
-#define PCIE_CFG_PCIE_CAPABILITIES 0x000000cc /* PCIE_CAPABILITIES Register */
-#define PCIE_CFG_DEVICE_CAPABILITIES 0x000000d0 /* DEVICE_CAPABILITIES Register */
-#define PCIE_CFG_DEVICE_STATUS_CONTROL 0x000000d4 /* DEVICE_STATUS_CONTROL Register */
-#define PCIE_CFG_LINK_CAPABILITY 0x000000d8 /* LINK_CAPABILITY Register */
-#define PCIE_CFG_LINK_STATUS_CONTROL 0x000000dc /* LINK_STATUS_CONTROL Register */
-#define PCIE_CFG_DEVICE_CAPABILITIES_2 0x000000f0 /* DEVICE_CAPABILITIES_2 Register */
-#define PCIE_CFG_DEVICE_STATUS_CONTROL_2 0x000000f4 /* DEVICE_STATUS_CONTROL_2 Register */
-#define PCIE_CFG_LINK_CAPABILITIES_2 0x000000f8 /* LINK_CAPABILITIES_2 Register */
-#define PCIE_CFG_LINK_STATUS_CONTROL_2 0x000000fc /* LINK_STATUS_CONTROL_2 Register */
-#define PCIE_CFG_ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER 0x00000100 /* ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER Register */
-#define PCIE_CFG_UNCORRECTABLE_ERROR_STATUS 0x00000104 /* UNCORRECTABLE_ERROR_STATUS Register */
-#define PCIE_CFG_UNCORRECTABLE_ERROR_MASK 0x00000108 /* UNCORRECTABLE_ERROR_MASK Register */
-#define PCIE_CFG_UNCORRECTABLE_ERROR_SEVERITY 0x0000010c /* UNCORRECTABLE_ERROR_SEVERITY Register */
-#define PCIE_CFG_CORRECTABLE_ERROR_STATUS 0x00000110 /* CORRECTABLE_ERROR_STATUS Register */
-#define PCIE_CFG_CORRECTABLE_ERROR_MASK 0x00000114 /* CORRECTABLE_ERROR_MASK Register */
-#define PCIE_CFG_ADVANCED_ERROR_CAPABILITIES_AND_CONTROL 0x00000118 /* ADVANCED_ERROR_CAPABILITIES_AND_CONTROL Register */
-#define PCIE_CFG_HEADER_LOG_1 0x0000011c /* HEADER_LOG_1 Register */
-#define PCIE_CFG_HEADER_LOG_2 0x00000120 /* HEADER_LOG_2 Register */
-#define PCIE_CFG_HEADER_LOG_3 0x00000124 /* HEADER_LOG_3 Register */
-#define PCIE_CFG_HEADER_LOG_4 0x00000128 /* HEADER_LOG_4 Register */
-#define PCIE_CFG_VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER 0x0000013c /* VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER Register */
-#define PCIE_CFG_PORT_VC_CAPABILITY 0x00000140 /* PORT_VC_CAPABILITY Register */
-#define PCIE_CFG_PORT_VC_CAPABILITY_2 0x00000144 /* PORT_VC_CAPABILITY_2 Register */
-#define PCIE_CFG_PORT_VC_STATUS_CONTROL 0x00000148 /* PORT_VC_STATUS_CONTROL Register */
-#define PCIE_CFG_VC_RESOURCE_CAPABILITY 0x0000014c /* VC_RESOURCE_CAPABILITY Register */
-#define PCIE_CFG_VC_RESOURCE_CONTROL 0x00000150 /* VC_RESOURCE_CONTROL Register */
-#define PCIE_CFG_VC_RESOURCE_STATUS 0x00000154 /* VC_RESOURCE_STATUS Register */
-#define PCIE_CFG_DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER 0x00000160 /* DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER Register */
-#define PCIE_CFG_DEVICE_SERIAL_NO_LOWER_DW 0x00000164 /* DEVICE_SERIAL_NO_LOWER_DW Register */
-#define PCIE_CFG_DEVICE_SERIAL_NO_UPPER_DW 0x00000168 /* DEVICE_SERIAL_NO_UPPER_DW Register */
-#define PCIE_CFG_POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER 0x0000016c /* POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER Register */
-#define PCIE_CFG_POWER_BUDGETING_DATA_SELECT 0x00000170 /* POWER_BUDGETING_DATA_SELECT Register */
-#define PCIE_CFG_POWER_BUDGETING_DATA 0x00000174 /* POWER_BUDGETING_DATA Register */
-#define PCIE_CFG_POWER_BUDGETING_CAPABILITY 0x00000178 /* POWER_BUDGETING_CAPABILITY Register */
-#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_2_1 0x0000017c /* FIRMWARE_POWER_BUDGETING_2_1 Register */
-#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_4_3 0x00000180 /* FIRMWARE_POWER_BUDGETING_4_3 Register */
-#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_6_5 0x00000184 /* FIRMWARE_POWER_BUDGETING_6_5 Register */
-#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_8_7 0x00000188 /* FIRMWARE_POWER_BUDGETING_8_7 Register */
-#define PCIE_CFG_PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING 0x0000018c /* PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING Register */
-
-
-/****************************************************************************
- * BCM70012_TGT_TOP_PCIE_TL
- ***************************************************************************/
-#define PCIE_TL_TL_CONTROL 0x00000400 /* TL_CONTROL Register */
-#define PCIE_TL_TRANSACTION_CONFIGURATION 0x00000404 /* TRANSACTION_CONFIGURATION Register */
-
-
-/****************************************************************************
- * BCM70012_TGT_TOP_PCIE_DLL
- ***************************************************************************/
-#define PCIE_DLL_DATA_LINK_CONTROL 0x00000500 /* DATA_LINK_CONTROL Register */
-#define PCIE_DLL_DATA_LINK_STATUS 0x00000504 /* DATA_LINK_STATUS Register */
-
-
-/****************************************************************************
- * BCM70012_TGT_TOP_INTR
- ***************************************************************************/
-#define INTR_INTR_STATUS 0x00000700 /* Interrupt Status Register */
-#define INTR_INTR_SET 0x00000704 /* Interrupt Set Register */
-#define INTR_INTR_CLR_REG 0x00000708 /* Interrupt Clear Register */
-#define INTR_INTR_MSK_STS_REG 0x0000070c /* Interrupt Mask Status Register */
-#define INTR_INTR_MSK_SET_REG 0x00000710 /* Interrupt Mask Set Register */
-#define INTR_INTR_MSK_CLR_REG 0x00000714 /* Interrupt Mask Clear Register */
-#define INTR_EOI_CTRL 0x00000720 /* End of interrupt control register */
-
-
-/****************************************************************************
- * BCM70012_MISC_TOP_MISC1
- ***************************************************************************/
-#define MISC1_TX_FIRST_DESC_L_ADDR_LIST0 0x00000c00 /* Tx DMA Descriptor List0 First Descriptor lower Address */
-#define MISC1_TX_FIRST_DESC_U_ADDR_LIST0 0x00000c04 /* Tx DMA Descriptor List0 First Descriptor Upper Address */
-#define MISC1_TX_FIRST_DESC_L_ADDR_LIST1 0x00000c08 /* Tx DMA Descriptor List1 First Descriptor Lower Address */
-#define MISC1_TX_FIRST_DESC_U_ADDR_LIST1 0x00000c0c /* Tx DMA Descriptor List1 First Descriptor Upper Address */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS 0x00000c10 /* Tx DMA Software Descriptor List Control and Status */
-#define MISC1_TX_DMA_ERROR_STATUS 0x00000c18 /* Tx DMA Engine Error Status */
-#define MISC1_TX_DMA_LIST0_CUR_DESC_L_ADDR 0x00000c1c /* Tx DMA List0 Current Descriptor Lower Address */
-#define MISC1_TX_DMA_LIST0_CUR_DESC_U_ADDR 0x00000c20 /* Tx DMA List0 Current Descriptor Upper Address */
-#define MISC1_TX_DMA_LIST0_CUR_BYTE_CNT_REM 0x00000c24 /* Tx DMA List0 Current Descriptor Upper Address */
-#define MISC1_TX_DMA_LIST1_CUR_DESC_L_ADDR 0x00000c28 /* Tx DMA List1 Current Descriptor Lower Address */
-#define MISC1_TX_DMA_LIST1_CUR_DESC_U_ADDR 0x00000c2c /* Tx DMA List1 Current Descriptor Upper Address */
-#define MISC1_TX_DMA_LIST1_CUR_BYTE_CNT_REM 0x00000c30 /* Tx DMA List1 Current Descriptor Upper Address */
-#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c34 /* Y Rx Descriptor List0 First Descriptor Lower Address */
-#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c38 /* Y Rx Descriptor List0 First Descriptor Upper Address */
-#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c3c /* Y Rx Descriptor List1 First Descriptor Lower Address */
-#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c40 /* Y Rx Descriptor List1 First Descriptor Upper Address */
-#define MISC1_Y_RX_SW_DESC_LIST_CTRL_STS 0x00000c44 /* Y Rx Software Descriptor List Control and Status */
-#define MISC1_Y_RX_ERROR_STATUS 0x00000c4c /* Y Rx Engine Error Status */
-#define MISC1_Y_RX_LIST0_CUR_DESC_L_ADDR 0x00000c50 /* Y Rx List0 Current Descriptor Lower Address */
-#define MISC1_Y_RX_LIST0_CUR_DESC_U_ADDR 0x00000c54 /* Y Rx List0 Current Descriptor Upper Address */
-#define MISC1_Y_RX_LIST0_CUR_BYTE_CNT 0x00000c58 /* Y Rx List0 Current Descriptor Byte Count */
-#define MISC1_Y_RX_LIST1_CUR_DESC_L_ADDR 0x00000c5c /* Y Rx List1 Current Descriptor Lower address */
-#define MISC1_Y_RX_LIST1_CUR_DESC_U_ADDR 0x00000c60 /* Y Rx List1 Current Descriptor Upper address */
-#define MISC1_Y_RX_LIST1_CUR_BYTE_CNT 0x00000c64 /* Y Rx List1 Current Descriptor Byte Count */
-#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c68 /* UV Rx Descriptor List0 First Descriptor lower Address */
-#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c6c /* UV Rx Descriptor List0 First Descriptor Upper Address */
-#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c70 /* UV Rx Descriptor List1 First Descriptor Lower Address */
-#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c74 /* UV Rx Descriptor List1 First Descriptor Upper Address */
-#define MISC1_UV_RX_SW_DESC_LIST_CTRL_STS 0x00000c78 /* UV Rx Software Descriptor List Control and Status */
-#define MISC1_UV_RX_ERROR_STATUS 0x00000c7c /* UV Rx Engine Error Status */
-#define MISC1_UV_RX_LIST0_CUR_DESC_L_ADDR 0x00000c80 /* UV Rx List0 Current Descriptor Lower Address */
-#define MISC1_UV_RX_LIST0_CUR_DESC_U_ADDR 0x00000c84 /* UV Rx List0 Current Descriptor Upper Address */
-#define MISC1_UV_RX_LIST0_CUR_BYTE_CNT 0x00000c88 /* UV Rx List0 Current Descriptor Byte Count */
-#define MISC1_UV_RX_LIST1_CUR_DESC_L_ADDR 0x00000c8c /* UV Rx List1 Current Descriptor Lower Address */
-#define MISC1_UV_RX_LIST1_CUR_DESC_U_ADDR 0x00000c90 /* UV Rx List1 Current Descriptor Upper Address */
-#define MISC1_UV_RX_LIST1_CUR_BYTE_CNT 0x00000c94 /* UV Rx List1 Current Descriptor Byte Count */
-#define MISC1_DMA_DEBUG_OPTIONS_REG 0x00000c98 /* DMA Debug Options Register */
-#define MISC1_READ_CHANNEL_ERROR_STATUS 0x00000c9c /* Read Channel Error Status */
-#define MISC1_PCIE_DMA_CTRL 0x00000ca0 /* PCIE DMA Control Register */
-
-
-/****************************************************************************
- * BCM70012_MISC_TOP_MISC2
- ***************************************************************************/
-#define MISC2_GLOBAL_CTRL 0x00000d00 /* Global Control Register */
-#define MISC2_INTERNAL_STATUS 0x00000d04 /* Internal Status Register */
-#define MISC2_INTERNAL_STATUS_MUX_CTRL 0x00000d08 /* Internal Debug Mux Control */
-#define MISC2_DEBUG_FIFO_LENGTH 0x00000d0c /* Debug FIFO Length */
-
-
-/****************************************************************************
- * BCM70012_MISC_TOP_MISC3
- ***************************************************************************/
-#define MISC3_RESET_CTRL 0x00000e00 /* Reset Control Register */
-#define MISC3_BIST_CTRL 0x00000e04 /* BIST Control Register */
-#define MISC3_BIST_STATUS 0x00000e08 /* BIST Status Register */
-#define MISC3_RX_CHECKSUM 0x00000e0c /* Receive Checksum */
-#define MISC3_TX_CHECKSUM 0x00000e10 /* Transmit Checksum */
-#define MISC3_ECO_CTRL_CORE 0x00000e14 /* ECO Core Reset Control Register */
-#define MISC3_CSI_TEST_CTRL 0x00000e18 /* CSI Test Control Register */
-#define MISC3_HD_DVI_TEST_CTRL 0x00000e1c /* HD DVI Test Control Register */
-
-
-/****************************************************************************
- * BCM70012_MISC_TOP_MISC_PERST
- ***************************************************************************/
-#define MISC_PERST_ECO_CTRL_PERST 0x00000e80 /* ECO PCIE Reset Control Register */
-#define MISC_PERST_DECODER_CTRL 0x00000e84 /* Decoder Control Register */
-#define MISC_PERST_CCE_STATUS 0x00000e88 /* Config Copy Engine Status */
-#define MISC_PERST_PCIE_DEBUG 0x00000e8c /* PCIE Debug Control Register */
-#define MISC_PERST_PCIE_DEBUG_STATUS 0x00000e90 /* PCIE Debug Status Register */
-#define MISC_PERST_VREG_CTRL 0x00000e94 /* Voltage Regulator Control Register */
-#define MISC_PERST_MEM_CTRL 0x00000e98 /* Memory Control Register */
-#define MISC_PERST_CLOCK_CTRL 0x00000e9c /* Clock Control Register */
-
-
-/****************************************************************************
- * BCM70012_MISC_TOP_GISB_ARBITER
- ***************************************************************************/
-#define GISB_ARBITER_REVISION 0x00000f00 /* GISB ARBITER REVISION */
-#define GISB_ARBITER_SCRATCH 0x00000f04 /* GISB ARBITER Scratch Register */
-#define GISB_ARBITER_REQ_MASK 0x00000f08 /* GISB ARBITER Master Request Mask Register */
-#define GISB_ARBITER_TIMER 0x00000f0c /* GISB ARBITER Timer Value Register */
-
-
-/****************************************************************************
- * BCM70012_OTP_TOP_OTP
- ***************************************************************************/
-#define OTP_CONFIG_INFO 0x00001400 /* OTP Configuration Register */
-#define OTP_CMD 0x00001404 /* OTP Command Register */
-#define OTP_STATUS 0x00001408 /* OTP Status Register */
-#define OTP_CONTENT_MISC 0x0000140c /* Content : Miscellaneous Register */
-#define OTP_CONTENT_AES_0 0x00001410 /* Content : AES Key 0 Register */
-#define OTP_CONTENT_AES_1 0x00001414 /* Content : AES Key 1 Register */
-#define OTP_CONTENT_AES_2 0x00001418 /* Content : AES Key 2 Register */
-#define OTP_CONTENT_AES_3 0x0000141c /* Content : AES Key 3 Register */
-#define OTP_CONTENT_SHA_0 0x00001420 /* Content : SHA Key 0 Register */
-#define OTP_CONTENT_SHA_1 0x00001424 /* Content : SHA Key 1 Register */
-#define OTP_CONTENT_SHA_2 0x00001428 /* Content : SHA Key 2 Register */
-#define OTP_CONTENT_SHA_3 0x0000142c /* Content : SHA Key 3 Register */
-#define OTP_CONTENT_SHA_4 0x00001430 /* Content : SHA Key 4 Register */
-#define OTP_CONTENT_SHA_5 0x00001434 /* Content : SHA Key 5 Register */
-#define OTP_CONTENT_SHA_6 0x00001438 /* Content : SHA Key 6 Register */
-#define OTP_CONTENT_SHA_7 0x0000143c /* Content : SHA Key 7 Register */
-#define OTP_CONTENT_CHECKSUM 0x00001440 /* Content : Checksum Register */
-#define OTP_PROG_CTRL 0x00001444 /* Programming Control Register */
-#define OTP_PROG_STATUS 0x00001448 /* Programming Status Register */
-#define OTP_PROG_PULSE 0x0000144c /* Program Pulse Width Register */
-#define OTP_VERIFY_PULSE 0x00001450 /* Verify Pulse Width Register */
-#define OTP_PROG_MASK 0x00001454 /* Program Mask Register */
-#define OTP_DATA_INPUT 0x00001458 /* Data Input Register */
-#define OTP_DATA_OUTPUT 0x0000145c /* Data Output Register */
-
-
-/****************************************************************************
- * BCM70012_AES_TOP_AES
- ***************************************************************************/
-#define AES_CONFIG_INFO 0x00001800 /* AES Configuration Information Register */
-#define AES_CMD 0x00001804 /* AES Command Register */
-#define AES_STATUS 0x00001808 /* AES Status Register */
-#define AES_EEPROM_CONFIG 0x0000180c /* AES EEPROM Configuration Register */
-#define AES_EEPROM_DATA_0 0x00001810 /* AES EEPROM Data Register 0 */
-#define AES_EEPROM_DATA_1 0x00001814 /* AES EEPROM Data Register 1 */
-#define AES_EEPROM_DATA_2 0x00001818 /* AES EEPROM Data Register 2 */
-#define AES_EEPROM_DATA_3 0x0000181c /* AES EEPROM Data Register 3 */
-
-
-/****************************************************************************
- * BCM70012_DCI_TOP_DCI
- ***************************************************************************/
-#define DCI_CMD 0x00001c00 /* DCI Command Register */
-#define DCI_STATUS 0x00001c04 /* DCI Status Register */
-#define DCI_DRAM_BASE_ADDR 0x00001c08 /* DRAM Base Address Register */
-#define DCI_FIRMWARE_ADDR 0x00001c0c /* Firmware Address Register */
-#define DCI_FIRMWARE_DATA 0x00001c10 /* Firmware Data Register */
-#define DCI_SIGNATURE_DATA_0 0x00001c14 /* Signature Data Register 0 */
-#define DCI_SIGNATURE_DATA_1 0x00001c18 /* Signature Data Register 1 */
-#define DCI_SIGNATURE_DATA_2 0x00001c1c /* Signature Data Register 2 */
-#define DCI_SIGNATURE_DATA_3 0x00001c20 /* Signature Data Register 3 */
-#define DCI_SIGNATURE_DATA_4 0x00001c24 /* Signature Data Register 4 */
-#define DCI_SIGNATURE_DATA_5 0x00001c28 /* Signature Data Register 5 */
-#define DCI_SIGNATURE_DATA_6 0x00001c2c /* Signature Data Register 6 */
-#define DCI_SIGNATURE_DATA_7 0x00001c30 /* Signature Data Register 7 */
-
-
-/****************************************************************************
- * BCM70012_TGT_TOP_INTR
- ***************************************************************************/
-/****************************************************************************
- * INTR :: INTR_STATUS
- ***************************************************************************/
-/* INTR :: INTR_STATUS :: reserved0 [31:26] */
-#define INTR_INTR_STATUS_reserved0_MASK 0xfc000000
-#define INTR_INTR_STATUS_reserved0_ALIGN 0
-#define INTR_INTR_STATUS_reserved0_BITS 6
-#define INTR_INTR_STATUS_reserved0_SHIFT 26
-
-/* INTR :: INTR_STATUS :: PCIE_TGT_CA_ATTN [25:25] */
-#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_MASK 0x02000000
-#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_ALIGN 0
-#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_BITS 1
-#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_SHIFT 25
-
-/* INTR :: INTR_STATUS :: PCIE_TGT_UR_ATTN [24:24] */
-#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_MASK 0x01000000
-#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_ALIGN 0
-#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_BITS 1
-#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_SHIFT 24
-
-/* INTR :: INTR_STATUS :: reserved1 [23:14] */
-#define INTR_INTR_STATUS_reserved1_MASK 0x00ffc000
-#define INTR_INTR_STATUS_reserved1_ALIGN 0
-#define INTR_INTR_STATUS_reserved1_BITS 10
-#define INTR_INTR_STATUS_reserved1_SHIFT 14
-
-/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_ERR_INTR [13:13] */
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK 0x00002000
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_SHIFT 13
-
-/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_DONE_INTR [12:12] */
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK 0x00001000
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_SHIFT 12
-
-/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_ERR_INTR [11:11] */
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK 0x00000800
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_SHIFT 11
-
-/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_DONE_INTR [10:10] */
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK 0x00000400
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_SHIFT 10
-
-/* INTR :: INTR_STATUS :: L1_TX_DMA_ERR_INTR [09:09] */
-#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK 0x00000200
-#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_SHIFT 9
-
-/* INTR :: INTR_STATUS :: L1_TX_DMA_DONE_INTR [08:08] */
-#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK 0x00000100
-#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_SHIFT 8
-
-/* INTR :: INTR_STATUS :: reserved2 [07:06] */
-#define INTR_INTR_STATUS_reserved2_MASK 0x000000c0
-#define INTR_INTR_STATUS_reserved2_ALIGN 0
-#define INTR_INTR_STATUS_reserved2_BITS 2
-#define INTR_INTR_STATUS_reserved2_SHIFT 6
-
-/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_ERR_INTR [05:05] */
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK 0x00000020
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_SHIFT 5
-
-/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_DONE_INTR [04:04] */
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK 0x00000010
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_SHIFT 4
-
-/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_ERR_INTR [03:03] */
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK 0x00000008
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_SHIFT 3
-
-/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_DONE_INTR [02:02] */
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK 0x00000004
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_SHIFT 2
-
-/* INTR :: INTR_STATUS :: L0_TX_DMA_ERR_INTR [01:01] */
-#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK 0x00000002
-#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_SHIFT 1
-
-/* INTR :: INTR_STATUS :: L0_TX_DMA_DONE_INTR [00:00] */
-#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK 0x00000001
-#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_ALIGN 0
-#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_BITS 1
-#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_SHIFT 0
-
-
-/****************************************************************************
- * MISC1 :: TX_SW_DESC_LIST_CTRL_STS
- ***************************************************************************/
-/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: reserved0 [31:04] */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_MASK 0xfffffff0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_ALIGN 0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_BITS 28
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_SHIFT 4
-
-/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DMA_DATA_SERV_PTR [03:03] */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_MASK 0x00000008
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_ALIGN 0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_BITS 1
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_SHIFT 3
-
-/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DESC_SERV_PTR [02:02] */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_MASK 0x00000004
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_ALIGN 0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_BITS 1
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_SHIFT 2
-
-/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_HALT_ON_ERROR [01:01] */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_MASK 0x00000002
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_ALIGN 0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_BITS 1
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_SHIFT 1
-
-/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_RUN_STOP [00:00] */
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK 0x00000001
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_ALIGN 0
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_BITS 1
-#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_SHIFT 0
-
-
-/****************************************************************************
- * MISC1 :: TX_DMA_ERROR_STATUS
- ***************************************************************************/
-/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved0 [31:10] */
-#define MISC1_TX_DMA_ERROR_STATUS_reserved0_MASK 0xfffffc00
-#define MISC1_TX_DMA_ERROR_STATUS_reserved0_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_reserved0_BITS 22
-#define MISC1_TX_DMA_ERROR_STATUS_reserved0_SHIFT 10
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DESC_TX_ABORT_ERRORS [09:09] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved1 [08:08] */
-#define MISC1_TX_DMA_ERROR_STATUS_reserved1_MASK 0x00000100
-#define MISC1_TX_DMA_ERROR_STATUS_reserved1_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_reserved1_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_reserved1_SHIFT 8
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DESC_TX_ABORT_ERRORS [07:07] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved2 [06:06] */
-#define MISC1_TX_DMA_ERROR_STATUS_reserved2_MASK 0x00000040
-#define MISC1_TX_DMA_ERROR_STATUS_reserved2_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_reserved2_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_reserved2_SHIFT 6
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DMA_DATA_TX_ABORT_ERRORS [05:05] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000020
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_SHIFT 5
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_FIFO_FULL_ERRORS [04:04] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_SHIFT 4
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved3 [03:03] */
-#define MISC1_TX_DMA_ERROR_STATUS_reserved3_MASK 0x00000008
-#define MISC1_TX_DMA_ERROR_STATUS_reserved3_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_reserved3_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_reserved3_SHIFT 3
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DMA_DATA_TX_ABORT_ERRORS [02:02] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000004
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_SHIFT 2
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_FIFO_FULL_ERRORS [01:01] */
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_SHIFT 1
-
-/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved4 [00:00] */
-#define MISC1_TX_DMA_ERROR_STATUS_reserved4_MASK 0x00000001
-#define MISC1_TX_DMA_ERROR_STATUS_reserved4_ALIGN 0
-#define MISC1_TX_DMA_ERROR_STATUS_reserved4_BITS 1
-#define MISC1_TX_DMA_ERROR_STATUS_reserved4_SHIFT 0
-
-
-/****************************************************************************
- * MISC1 :: Y_RX_ERROR_STATUS
- ***************************************************************************/
-/* MISC1 :: Y_RX_ERROR_STATUS :: reserved0 [31:14] */
-#define MISC1_Y_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
-#define MISC1_Y_RX_ERROR_STATUS_reserved0_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_reserved0_BITS 18
-#define MISC1_Y_RX_ERROR_STATUS_reserved0_SHIFT 14
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: reserved1 [08:08] */
-#define MISC1_Y_RX_ERROR_STATUS_reserved1_MASK 0x00000100
-#define MISC1_Y_RX_ERROR_STATUS_reserved1_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_reserved1_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_reserved1_SHIFT 8
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: reserved2 [06:05] */
-#define MISC1_Y_RX_ERROR_STATUS_reserved2_MASK 0x00000060
-#define MISC1_Y_RX_ERROR_STATUS_reserved2_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_reserved2_BITS 2
-#define MISC1_Y_RX_ERROR_STATUS_reserved2_SHIFT 5
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: reserved3 [03:02] */
-#define MISC1_Y_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
-#define MISC1_Y_RX_ERROR_STATUS_reserved3_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_reserved3_BITS 2
-#define MISC1_Y_RX_ERROR_STATUS_reserved3_SHIFT 2
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
-
-/* MISC1 :: Y_RX_ERROR_STATUS :: reserved4 [00:00] */
-#define MISC1_Y_RX_ERROR_STATUS_reserved4_MASK 0x00000001
-#define MISC1_Y_RX_ERROR_STATUS_reserved4_ALIGN 0
-#define MISC1_Y_RX_ERROR_STATUS_reserved4_BITS 1
-#define MISC1_Y_RX_ERROR_STATUS_reserved4_SHIFT 0
-
-
-/****************************************************************************
- * MISC1 :: UV_RX_ERROR_STATUS
- ***************************************************************************/
-/* MISC1 :: UV_RX_ERROR_STATUS :: reserved0 [31:14] */
-#define MISC1_UV_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
-#define MISC1_UV_RX_ERROR_STATUS_reserved0_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_reserved0_BITS 18
-#define MISC1_UV_RX_ERROR_STATUS_reserved0_SHIFT 14
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: reserved1 [08:08] */
-#define MISC1_UV_RX_ERROR_STATUS_reserved1_MASK 0x00000100
-#define MISC1_UV_RX_ERROR_STATUS_reserved1_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_reserved1_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_reserved1_SHIFT 8
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: reserved2 [06:05] */
-#define MISC1_UV_RX_ERROR_STATUS_reserved2_MASK 0x00000060
-#define MISC1_UV_RX_ERROR_STATUS_reserved2_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_reserved2_BITS 2
-#define MISC1_UV_RX_ERROR_STATUS_reserved2_SHIFT 5
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: reserved3 [03:02] */
-#define MISC1_UV_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
-#define MISC1_UV_RX_ERROR_STATUS_reserved3_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_reserved3_BITS 2
-#define MISC1_UV_RX_ERROR_STATUS_reserved3_SHIFT 2
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
-
-/* MISC1 :: UV_RX_ERROR_STATUS :: reserved4 [00:00] */
-#define MISC1_UV_RX_ERROR_STATUS_reserved4_MASK 0x00000001
-#define MISC1_UV_RX_ERROR_STATUS_reserved4_ALIGN 0
-#define MISC1_UV_RX_ERROR_STATUS_reserved4_BITS 1
-#define MISC1_UV_RX_ERROR_STATUS_reserved4_SHIFT 0
-
-/****************************************************************************
- * Datatype Definitions.
- ***************************************************************************/
-#endif /* #ifndef MACFILE_H__ */
-
-/* End of File */
-
diff --git a/drivers/staging/crystalhd/crystalhd.h b/drivers/staging/crystalhd/crystalhd.h
deleted file mode 100644
index b3a550bd5b06..000000000000
--- a/drivers/staging/crystalhd/crystalhd.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _CRYSTALHD_H_
-#define _CRYSTALHD_H_
-
-#include "bc_dts_defs.h"
-#include "crystalhd_misc.h"
-#include "bc_dts_glob_lnx.h"
-#include "crystalhd_hw.h"
-#include "crystalhd_cmds.h"
-#include "crystalhd_lnx.h"
-#include "bcm_70012_regs.h"
-#include "crystalhd_fw_if.h"
-
-#endif
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c
deleted file mode 100644
index 642f438793c3..000000000000
--- a/drivers/staging/crystalhd/crystalhd_cmds.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_cmds . c
- *
- * Description:
- * BCM70010 Linux driver user command interfaces.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#include "crystalhd.h"
-
-static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
-{
- struct crystalhd_user *user = NULL;
- int i;
-
- for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
- if (!ctx->user[i].in_use) {
- user = &ctx->user[i];
- break;
- }
- }
-
- return user;
-}
-
-static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx)
-{
- int i, count = 0;
-
- for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
- if (ctx->user[i].in_use)
- count++;
- }
-
- return count;
-}
-
-static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx)
-{
- int i;
-
- for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
- if (!ctx->user[i].in_use)
- continue;
- if (ctx->user[i].mode == DTS_DIAG_MODE ||
- ctx->user[i].mode == DTS_PLAYBACK_MODE) {
- ctx->pwr_state_change = 1;
- break;
- }
- }
-}
-
-static enum BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- int rc = 0, i = 0;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- if (ctx->user[idata->u_id].mode != DTS_MODE_INV) {
- BCMLOG_ERR("Close the handle first..\n");
- return BC_STS_ERR_USAGE;
- }
- if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) {
- ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
- return BC_STS_SUCCESS;
- }
- if (ctx->state != BC_LINK_INVALID) {
- BCMLOG_ERR("Link invalid state %d\n", ctx->state);
- return BC_STS_ERR_USAGE;
- }
- /* Check for duplicate playback sessions..*/
- for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
- if (ctx->user[i].mode == DTS_DIAG_MODE ||
- ctx->user[i].mode == DTS_PLAYBACK_MODE) {
- BCMLOG_ERR("multiple playback sessions are not supported..\n");
- return BC_STS_ERR_USAGE;
- }
- }
- ctx->cin_wait_exit = 0;
- ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
- /* Setup mmap pool for uaddr sgl mapping..*/
- rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS);
- if (rc)
- return BC_STS_ERROR;
-
- /* Setup Hardware DMA rings */
- return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx);
-}
-
-static enum BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
- idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major;
- idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor;
- idata->udata.u.VerInfo.DriverRevision = crystalhd_kmod_rev;
- return BC_STS_SUCCESS;
-}
-
-
-static enum BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_pci_cfg_rd(ctx->adp, 0, 2,
- (uint32_t *)&idata->udata.u.hwType.PciVenId);
- crystalhd_pci_cfg_rd(ctx->adp, 2, 2,
- (uint32_t *)&idata->udata.u.hwType.PciDevId);
- crystalhd_pci_cfg_rd(ctx->adp, 8, 1,
- (uint32_t *)&idata->udata.u.hwType.HwRev);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
- idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp,
- idata->udata.u.regAcc.Offset);
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
-
- bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
- idata->udata.u.regAcc.Value);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
-
- idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp,
- idata->udata.u.regAcc.Offset);
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
-
- crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
- idata->udata.u.regAcc.Value);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata || !idata->add_cdata)
- return BC_STS_INV_ARG;
-
- if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
- BCMLOG_ERR("insufficient buffer\n");
- return BC_STS_INV_ARG;
- }
- sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff,
- idata->udata.u.devMem.NumDwords,
- (uint32_t *)idata->add_cdata);
- return sts;
-
-}
-
-static enum BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata || !idata->add_cdata)
- return BC_STS_INV_ARG;
-
- if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
- BCMLOG_ERR("insufficient buffer\n");
- return BC_STS_INV_ARG;
- }
-
- sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff,
- idata->udata.u.devMem.NumDwords,
- (uint32_t *)idata->add_cdata);
- return sts;
-}
-
-static enum BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- uint32_t ix, cnt, off, len;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- uint32_t *temp;
-
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
-
- temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
- off = idata->udata.u.pciCfg.Offset;
- len = idata->udata.u.pciCfg.Size;
-
- if (len <= 4)
- return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp);
-
- /* Truncate to dword alignment..*/
- len = 4;
- cnt = idata->udata.u.pciCfg.Size / len;
- for (ix = 0; ix < cnt; ix++) {
- sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("config read : %d\n", sts);
- return sts;
- }
- off += len;
- }
-
- return sts;
-}
-
-static enum BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- uint32_t ix, cnt, off, len;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- uint32_t *temp;
-
- if (!ctx || !idata)
- return BC_STS_INV_ARG;
-
- temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
- off = idata->udata.u.pciCfg.Offset;
- len = idata->udata.u.pciCfg.Size;
-
- if (len <= 4)
- return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]);
-
- /* Truncate to dword alignment..*/
- len = 4;
- cnt = idata->udata.u.pciCfg.Size / len;
- for (ix = 0; ix < cnt; ix++) {
- sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("config write : %d\n", sts);
- return sts;
- }
- off += len;
- }
-
- return sts;
-}
-
-static enum BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- if (ctx->state != BC_LINK_INVALID) {
- BCMLOG_ERR("Link invalid state %d\n", ctx->state);
- return BC_STS_ERR_USAGE;
- }
-
- sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
- idata->add_cdata_sz);
-
- if (sts != BC_STS_SUCCESS)
- BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
- else
- ctx->state |= BC_LINK_INIT;
-
- return sts;
-}
-
-/*
- * We use the FW_CMD interface to sync up playback state with application
- * and firmware. This function will perform the required pre and post
- * processing of the Firmware commands.
- *
- * Pause -
- * Disable capture after decoder pause.
- * Resume -
- * First enable capture and issue decoder resume command.
- * Flush -
- * Abort pending input transfers and issue decoder flush command.
- *
- */
-static enum BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- enum BC_STATUS sts;
- uint32_t *cmd;
-
- if (!(ctx->state & BC_LINK_INIT)) {
- BCMLOG_ERR("Link invalid state %d\n", ctx->state);
- return BC_STS_ERR_USAGE;
- }
-
- cmd = idata->udata.u.fwCmd.cmd;
-
- /* Pre-Process */
- if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
- if (!cmd[3]) {
- ctx->state &= ~BC_LINK_PAUSED;
- crystalhd_hw_unpause(&ctx->hw_ctx);
- }
- } else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) {
- BCMLOG(BCMLOG_INFO, "Flush issued\n");
- if (cmd[3])
- ctx->cin_wait_exit = 1;
- }
-
- sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd);
-
- if (sts != BC_STS_SUCCESS) {
- BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]);
- return sts;
- }
-
- /* Post-Process */
- if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
- if (cmd[3]) {
- ctx->state |= BC_LINK_PAUSED;
- crystalhd_hw_pause(&ctx->hw_ctx);
- }
- }
-
- return sts;
-}
-
-static void bc_proc_in_completion(struct crystalhd_dio_req *dio_hnd,
- wait_queue_head_t *event, enum BC_STATUS sts)
-{
- if (!dio_hnd || !event) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return;
- }
- if (sts == BC_STS_IO_USER_ABORT)
- return;
-
- dio_hnd->uinfo.comp_sts = sts;
- dio_hnd->uinfo.ev_sts = 1;
- crystalhd_set_event(event);
-}
-
-static enum BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
-{
- wait_queue_head_t sleep_ev;
- int rc = 0;
-
- if (ctx->state & BC_LINK_SUSPEND)
- return BC_STS_IO_USER_ABORT;
-
- if (ctx->cin_wait_exit) {
- ctx->cin_wait_exit = 0;
- return BC_STS_CMD_CANCELLED;
- }
- crystalhd_create_event(&sleep_ev);
- crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0);
- if (rc == -EINTR)
- return BC_STS_IO_USER_ABORT;
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata,
- struct crystalhd_dio_req *dio)
-{
- uint32_t tx_listid = 0;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- wait_queue_head_t event;
- int rc = 0;
-
- if (!ctx || !idata || !dio) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_create_event(&event);
-
- ctx->tx_list_id = 0;
- /* msleep_interruptible(2000); */
- sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion,
- &event, &tx_listid,
- idata->udata.u.ProcInput.Encrypted);
-
- while (sts == BC_STS_BUSY) {
- sts = bc_cproc_codein_sleep(ctx);
- if (sts != BC_STS_SUCCESS)
- break;
- sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio,
- bc_proc_in_completion,
- &event, &tx_listid,
- idata->udata.u.ProcInput.Encrypted);
- }
- if (sts != BC_STS_SUCCESS) {
- BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts);
- return sts;
- }
- if (ctx->cin_wait_exit)
- ctx->cin_wait_exit = 0;
-
- ctx->tx_list_id = tx_listid;
-
- /* _post() succeeded.. wait for the completion. */
- crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0);
- ctx->tx_list_id = 0;
- if (!rc) {
- return dio->uinfo.comp_sts;
- } else if (rc == -EBUSY) {
- BCMLOG(BCMLOG_DBG, "_tx_post() T/O\n");
- sts = BC_STS_TIMEOUT;
- } else if (rc == -EINTR) {
- BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n");
- sts = BC_STS_IO_USER_ABORT;
- } else {
- sts = BC_STS_IO_ERROR;
- }
-
- /* We are cancelling the IO from the same context as the _post().
- * so no need to wait on the event again.. the return itself
- * ensures the release of our resources.
- */
- crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid);
-
- return sts;
-}
-
-/* Helper function to check on user buffers */
-static enum BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff,
- uint32_t ub_sz, uint32_t uv_off, bool en_422)
-{
- if (!ubuff || !ub_sz) {
- BCMLOG_ERR("%s->Invalid Arg %p %x\n",
- ((pin) ? "TX" : "RX"), ubuff, ub_sz);
- return BC_STS_INV_ARG;
- }
-
- /* Check for alignment */
- if (((uintptr_t)ubuff) & 0x03) {
- BCMLOG_ERR(
- "%s-->Un-aligned address not implemented yet.. %p\n",
- ((pin) ? "TX" : "RX"), ubuff);
- return BC_STS_NOT_IMPL;
- }
- if (pin)
- return BC_STS_SUCCESS;
-
- if (!en_422 && !uv_off) {
- BCMLOG_ERR("Need UV offset for 420 mode.\n");
- return BC_STS_INV_ARG;
- }
-
- if (en_422 && uv_off) {
- BCMLOG_ERR("UV offset in 422 mode ??\n");
- return BC_STS_INV_ARG;
- }
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- void *ubuff;
- uint32_t ub_sz;
- struct crystalhd_dio_req *dio_hnd = NULL;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- ubuff = idata->udata.u.ProcInput.pDmaBuff;
- ub_sz = idata->udata.u.ProcInput.BuffSz;
-
- sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("dio map - %d\n", sts);
- return sts;
- }
-
- if (!dio_hnd)
- return BC_STS_ERROR;
-
- sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd);
-
- crystalhd_unmap_dio(ctx->adp, dio_hnd);
-
- return sts;
-}
-
-static enum BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- void *ubuff;
- uint32_t ub_sz, uv_off;
- bool en_422;
- struct crystalhd_dio_req *dio_hnd = NULL;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- ubuff = idata->udata.u.RxBuffs.YuvBuff;
- ub_sz = idata->udata.u.RxBuffs.YuvBuffSz;
- uv_off = idata->udata.u.RxBuffs.UVbuffOffset;
- en_422 = idata->udata.u.RxBuffs.b422Mode;
-
- sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off,
- en_422, 0, &dio_hnd);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("dio map - %d\n", sts);
- return sts;
- }
-
- if (!dio_hnd)
- return BC_STS_ERROR;
-
- sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd,
- (ctx->state == BC_LINK_READY));
- if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
- crystalhd_unmap_dio(ctx->adp, dio_hnd);
- return sts;
- }
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
- struct crystalhd_dio_req *dio)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- ctx->state |= BC_LINK_FMT_CHG;
- if (ctx->state == BC_LINK_READY)
- sts = crystalhd_hw_start_capture(&ctx->hw_ctx);
-
- return sts;
-}
-
-static enum BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- struct crystalhd_dio_req *dio = NULL;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- struct BC_DEC_OUT_BUFF *frame;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- if (!(ctx->state & BC_LINK_CAP_EN)) {
- BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state);
- return BC_STS_ERR_USAGE;
- }
-
- frame = &idata->udata.u.DecOutData;
-
- sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
- if (sts != BC_STS_SUCCESS)
- return (ctx->state & BC_LINK_SUSPEND) ?
- BC_STS_IO_USER_ABORT : sts;
-
- frame->Flags = dio->uinfo.comp_flags;
-
- if (frame->Flags & COMP_FLAG_FMT_CHANGE)
- return bc_cproc_fmt_change(ctx, dio);
-
- frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff;
- frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len;
- frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset;
- frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode;
-
- frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz;
- frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz;
-
- crystalhd_unmap_dio(ctx->adp, dio);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- ctx->state |= BC_LINK_CAP_EN;
- if (ctx->state == BC_LINK_READY)
- return crystalhd_hw_start_capture(&ctx->hw_ctx);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- struct crystalhd_dio_req *dio = NULL;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- struct BC_DEC_OUT_BUFF *frame;
- uint32_t count;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- if (!(ctx->state & BC_LINK_CAP_EN))
- return BC_STS_ERR_USAGE;
-
- /* We should ack flush even when we are in paused/suspend state */
- if (!(ctx->state & BC_LINK_READY))
- return crystalhd_hw_stop_capture(&ctx->hw_ctx);
-
- ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG);
-
- frame = &idata->udata.u.DecOutData;
- for (count = 0; count < BC_RX_LIST_CNT; count++) {
-
- sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx,
- &frame->PibInfo, &dio);
- if (sts != BC_STS_SUCCESS)
- break;
-
- crystalhd_unmap_dio(ctx->adp, dio);
- }
-
- return crystalhd_hw_stop_capture(&ctx->hw_ctx);
-}
-
-static enum BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- struct BC_DTS_STATS *stats;
- struct crystalhd_hw_stats hw_stats;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats);
-
- stats = &idata->udata.u.drvStat;
- stats->drvRLL = hw_stats.rdyq_count;
- stats->drvFLL = hw_stats.freeq_count;
- stats->DrvTotalFrmDropped = hw_stats.rx_errors;
- stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors;
- stats->intCount = hw_stats.num_interrupts;
- stats->DrvIgnIntrCnt = hw_stats.num_interrupts -
- hw_stats.dev_interrupts;
- stats->TxFifoBsyCnt = hw_stats.cin_busy;
- stats->pauseCount = hw_stats.pause_cnt;
-
- if (ctx->pwr_state_change)
- stats->pwr_state_change = 1;
- if (ctx->state & BC_LINK_PAUSED)
- stats->DrvPauseTime = 1;
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- crystalhd_hw_stats(&ctx->hw_ctx, NULL);
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- struct BC_CLOCK *clock;
- uint32_t oldClk;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- clock = &idata->udata.u.clockValue;
- oldClk = ctx->hw_ctx.core_clock_mhz;
- ctx->hw_ctx.core_clock_mhz = clock->clk;
-
- if (ctx->state & BC_LINK_READY) {
- sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx);
- if (sts == BC_STS_CLK_NOCHG)
- ctx->hw_ctx.core_clock_mhz = oldClk;
- }
-
- clock->clk = ctx->hw_ctx.core_clock_mhz;
-
- return sts;
-}
-
-/*=============== Cmd Proc Table.. ======================================*/
-static const struct crystalhd_cmd_tbl g_crystalhd_cproc_tbl[] = {
- { BCM_IOC_GET_VERSION, bc_cproc_get_version, 0},
- { BCM_IOC_GET_HWTYPE, bc_cproc_get_hwtype, 0},
- { BCM_IOC_REG_RD, bc_cproc_reg_rd, 0},
- { BCM_IOC_REG_WR, bc_cproc_reg_wr, 0},
- { BCM_IOC_FPGA_RD, bc_cproc_link_reg_rd, 0},
- { BCM_IOC_FPGA_WR, bc_cproc_link_reg_wr, 0},
- { BCM_IOC_MEM_RD, bc_cproc_mem_rd, 0},
- { BCM_IOC_MEM_WR, bc_cproc_mem_wr, 0},
- { BCM_IOC_RD_PCI_CFG, bc_cproc_cfg_rd, 0},
- { BCM_IOC_WR_PCI_CFG, bc_cproc_cfg_wr, 1},
- { BCM_IOC_FW_DOWNLOAD, bc_cproc_download_fw, 1},
- { BCM_IOC_FW_CMD, bc_cproc_do_fw_cmd, 1},
- { BCM_IOC_PROC_INPUT, bc_cproc_proc_input, 1},
- { BCM_IOC_ADD_RXBUFFS, bc_cproc_add_cap_buff, 1},
- { BCM_IOC_FETCH_RXBUFF, bc_cproc_fetch_frame, 1},
- { BCM_IOC_START_RX_CAP, bc_cproc_start_capture, 1},
- { BCM_IOC_FLUSH_RX_CAP, bc_cproc_flush_cap_buffs, 1},
- { BCM_IOC_GET_DRV_STAT, bc_cproc_get_stats, 0},
- { BCM_IOC_RST_DRV_STAT, bc_cproc_reset_stats, 0},
- { BCM_IOC_NOTIFY_MODE, bc_cproc_notify_mode, 0},
- { BCM_IOC_CHG_CLK, bc_cproc_chg_clk, 0},
- { BCM_IOC_END, NULL},
-};
-
-/*=============== Cmd Proc Functions.. ===================================*/
-
-/**
- * crystalhd_suspend - Power management suspend request.
- * @ctx: Command layer context.
- * @idata: Iodata - required for internal use.
- *
- * Return:
- * status
- *
- * 1. Set the state to Suspend.
- * 2. Flush the Rx Buffers it will unmap all the buffers and
- * stop the RxDMA engine.
- * 3. Cancel The TX Io and Stop Dma Engine.
- * 4. Put the DDR in to deep sleep.
- * 5. Stop the hardware putting it in to Reset State.
- *
- * Current gstreamer frame work does not provide any power management
- * related notification to user mode decoder plug-in. As a work-around
- * we pass on the power management notification to our plug-in by completing
- * all outstanding requests with BC_STS_IO_USER_ABORT return code.
- */
-enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!ctx || !idata) {
- BCMLOG_ERR("Invalid Parameters\n");
- return BC_STS_ERROR;
- }
-
- if (ctx->state & BC_LINK_SUSPEND)
- return BC_STS_SUCCESS;
-
- if (ctx->state == BC_LINK_INVALID) {
- BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n");
- return BC_STS_SUCCESS;
- }
-
- ctx->state |= BC_LINK_SUSPEND;
-
- bc_cproc_mark_pwr_state(ctx);
-
- if (ctx->state & BC_LINK_CAP_EN) {
- sts = bc_cproc_flush_cap_buffs(ctx, idata);
- if (sts != BC_STS_SUCCESS)
- return sts;
- }
-
- if (ctx->tx_list_id) {
- sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id);
- if (sts != BC_STS_SUCCESS)
- return sts;
- }
-
- sts = crystalhd_hw_suspend(&ctx->hw_ctx);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n");
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_resume - Resume frame capture.
- * @ctx: Command layer contextx.
- *
- * Return:
- * status
- *
- *
- * Resume frame capture.
- *
- * PM_Resume can't resume the playback state back to pre-suspend state
- * because we don't keep video clip related information within driver.
- * To get back to the pre-suspend state App will re-open the device and
- * start a new playback session from the pre-suspend clip position.
- *
- */
-enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
-{
- BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state);
-
- bc_cproc_mark_pwr_state(ctx);
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_user_open - Create application handle.
- * @ctx: Command layer contextx.
- * @user_ctx: User ID context.
- *
- * Return:
- * status
- *
- * Creates an application specific UID and allocates
- * application specific resources. HW layer initialization
- * is done for the first open request.
- */
-enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
- struct crystalhd_user **user_ctx)
-{
- struct crystalhd_user *uc;
-
- if (!ctx || !user_ctx) {
- BCMLOG_ERR("Invalid arg..\n");
- return BC_STS_INV_ARG;
- }
-
- uc = bc_cproc_get_uid(ctx);
- if (!uc) {
- BCMLOG(BCMLOG_INFO, "No free user context...\n");
- return BC_STS_BUSY;
- }
-
- BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid);
-
- crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
-
- uc->in_use = 1;
-
- *user_ctx = uc;
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_user_close - Close application handle.
- * @ctx: Command layer contextx.
- * @uc: User ID context.
- *
- * Return:
- * status
- *
- * Closer application handle and release app specific
- * resources.
- */
-enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx,
- struct crystalhd_user *uc)
-{
- uint32_t mode = uc->mode;
-
- ctx->user[uc->uid].mode = DTS_MODE_INV;
- ctx->user[uc->uid].in_use = 0;
- ctx->cin_wait_exit = 1;
- ctx->pwr_state_change = 0;
-
- BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid);
-
- if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) {
- crystalhd_hw_free_dma_rings(&ctx->hw_ctx);
- crystalhd_destroy_dio_pool(ctx->adp);
- } else if (bc_cproc_get_user_count(ctx)) {
- return BC_STS_SUCCESS;
- }
-
- crystalhd_hw_close(&ctx->hw_ctx);
-
- ctx->state = BC_LINK_INVALID;
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_setup_cmd_context - Setup Command layer resources.
- * @ctx: Command layer contextx.
- * @adp: Adapter context
- *
- * Return:
- * status
- *
- * Called at the time of driver load.
- */
-enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
- struct crystalhd_adp *adp)
-{
- int i = 0;
-
- if (!ctx || !adp) {
- BCMLOG_ERR("Invalid arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- if (ctx->adp)
- BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n");
-
- ctx->adp = adp;
- for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
- ctx->user[i].uid = i;
- ctx->user[i].in_use = 0;
- ctx->user[i].mode = DTS_MODE_INV;
- }
-
- /*Open and Close the Hardware to put it in to sleep state*/
- crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
- crystalhd_hw_close(&ctx->hw_ctx);
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_delete_cmd_context - Release Command layer resources.
- * @ctx: Command layer contextx.
- *
- * Return:
- * status
- *
- * Called at the time of driver un-load.
- */
-enum BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
-{
- BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");
-
- ctx->adp = NULL;
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_get_cmd_proc - Cproc table lookup.
- * @ctx: Command layer contextx.
- * @cmd: IOCTL command code.
- * @uc: User ID context.
- *
- * Return:
- * command proc function pointer
- *
- * This function checks the process context, application's
- * mode of operation and returns the function pointer
- * from the cproc table.
- */
-crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx,
- uint32_t cmd, struct crystalhd_user *uc)
-{
- crystalhd_cmd_proc cproc = NULL;
- unsigned int i, tbl_sz;
-
- if (!ctx) {
- BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd);
- return NULL;
- }
-
- if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) {
- BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd);
- return NULL;
- }
-
- tbl_sz = sizeof(g_crystalhd_cproc_tbl) /
- sizeof(struct crystalhd_cmd_tbl);
- for (i = 0; i < tbl_sz; i++) {
- if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
- if ((uc->mode == DTS_MONITOR_MODE) &&
- (g_crystalhd_cproc_tbl[i].block_mon)) {
- BCMLOG(BCMLOG_INFO, "Blocking cmd %d\n", cmd);
- break;
- }
- cproc = g_crystalhd_cproc_tbl[i].cmd_proc;
- break;
- }
- }
-
- return cproc;
-}
-
-/**
- * crystalhd_cmd_interrupt - ISR entry point
- * @ctx: Command layer contextx.
- *
- * Return:
- * TRUE: If interrupt from bcm70012 device.
- *
- *
- * ISR entry point from OS layer.
- */
-bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
-{
- if (!ctx) {
- BCMLOG_ERR("Invalid arg..\n");
- return false;
- }
-
- return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
-}
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h
deleted file mode 100644
index b5bf59dbcde9..000000000000
--- a/drivers/staging/crystalhd/crystalhd_cmds.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_cmds . h
- *
- * Description:
- * BCM70010 Linux driver user command interfaces.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#ifndef _CRYSTALHD_CMDS_H_
-#define _CRYSTALHD_CMDS_H_
-
-/*
- * NOTE:: This is the main interface file between the Linux layer
- * and the hardware layer. This file will use the definitions
- * from _dts_glob and dts_defs etc.. which are defined for
- * windows.
- */
-
-#include "crystalhd.h"
-
-enum crystalhd_state {
- BC_LINK_INVALID = 0x00,
- BC_LINK_INIT = 0x01,
- BC_LINK_CAP_EN = 0x02,
- BC_LINK_FMT_CHG = 0x04,
- BC_LINK_SUSPEND = 0x10,
- BC_LINK_PAUSED = 0x20,
- BC_LINK_READY = (BC_LINK_INIT | BC_LINK_CAP_EN | BC_LINK_FMT_CHG),
-};
-
-struct crystalhd_user {
- uint32_t uid;
- uint32_t in_use;
- uint32_t mode;
-};
-
-#define DTS_MODE_INV (-1)
-
-struct crystalhd_cmd {
- uint32_t state;
- struct crystalhd_adp *adp;
- struct crystalhd_user user[BC_LINK_MAX_OPENS];
-
- spinlock_t ctx_lock;
- uint32_t tx_list_id;
- uint32_t cin_wait_exit;
- uint32_t pwr_state_change;
- struct crystalhd_hw hw_ctx;
-};
-
-typedef enum BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *,
- struct crystalhd_ioctl_data *);
-
-struct crystalhd_cmd_tbl {
- uint32_t cmd_id;
- const crystalhd_cmd_proc cmd_proc;
- uint32_t block_mon;
-};
-
-enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx,
- struct crystalhd_ioctl_data *idata);
-enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx);
-crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx,
- uint32_t cmd, struct crystalhd_user *uc);
-enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
- struct crystalhd_user **user_ctx);
-enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx,
- struct crystalhd_user *uc);
-enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
- struct crystalhd_adp *adp);
-enum BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx);
-bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx);
-
-#endif
diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h
deleted file mode 100644
index 05615e2a231a..000000000000
--- a/drivers/staging/crystalhd/crystalhd_fw_if.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_fw_if . h
- *
- * Description:
- * BCM70012 Firmware interface definitions.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#ifndef _CRYSTALHD_FW_IF_H_
-#define _CRYSTALHD_FW_IF_H_
-
-/* TBD: Pull in only required defs into this file.. */
-
-/* User Data Header */
-struct user_data {
- struct user_data *next;
- uint32_t type;
- uint32_t size;
-};
-
-/*------------------------------------------------------*
- * MPEG Extension to the PPB *
- *------------------------------------------------------*/
-struct ppb_mpeg {
- uint32_t to_be_defined;
- uint32_t valid;
-
- /* Always valid, defaults to picture size if no
- sequence display extension in the stream. */
- uint32_t display_horizontal_size;
- uint32_t display_vertical_size;
-
- /* MPEG_VALID_PANSCAN
- Offsets are a copy values from the MPEG stream. */
- uint32_t offset_count;
- int32_t horizontal_offset[3];
- int32_t vertical_offset[3];
-
- /* MPEG_VALID_USERDATA
- User data is in the form of a linked list. */
- int32_t userDataSize;
- struct user_data *userData;
-
-};
-
-
-/*------------------------------------------------------*
- * VC1 Extension to the PPB *
- *------------------------------------------------------*/
-struct ppb_vc1 {
- uint32_t to_be_defined;
- uint32_t valid;
-
- /* Always valid, defaults to picture size if no
- sequence display extension in the stream. */
- uint32_t display_horizontal_size;
- uint32_t display_vertical_size;
-
- /* VC1 pan scan windows */
- uint32_t num_panscan_windows;
- int32_t ps_horiz_offset[4];
- int32_t ps_vert_offset[4];
- int32_t ps_width[4];
- int32_t ps_height[4];
-
- /* VC1_VALID_USERDATA
- User data is in the form of a linked list. */
- int32_t userDataSize;
- struct user_data *userData;
-
-};
-
-/*------------------------------------------------------*
- * H.264 Extension to the PPB *
- *------------------------------------------------------*/
-
-/**
- * @brief Film grain SEI message.
- *
- * Content of the film grain SEI message.
- */
-
-/* maximum number of model-values as for Thomson spec(standard says 5) */
-#define MAX_FGT_MODEL_VALUE (3)
-
-/* maximum number of intervals(as many as 256 intervals?) */
-#define MAX_FGT_VALUE_INTERVAL (256)
-
-struct fgt_sei {
- struct fgt_sei *next;
- unsigned char
- model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
- unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL];
- unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL];
-
- unsigned char cancel_flag; /* Cancel flag: 1 no film grain. */
- unsigned char model_id; /* Model id. */
-
- /* +unused SE based on Thomson spec */
- unsigned char color_desc_flag; /* Separate color description flag. */
- unsigned char bit_depth_luma; /* Bit depth luma minus 8. */
- unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */
- unsigned char full_range_flag; /* Full range flag. */
- unsigned char color_primaries; /* Color primaries. */
- unsigned char transfer_charact; /* Transfer characteristics. */
- unsigned char matrix_coeff; /*< Matrix coefficients. */
- /* -unused SE based on Thomson spec */
-
- unsigned char blending_mode_id; /* Blending mode. */
- unsigned char log2_scale_factor; /* Log2 scale factor (2-7). */
- unsigned char comp_flag[3]; /* Components [0,2]
- parameters present flag. */
- unsigned char num_intervals_minus1[3]; /* Number of
- intensity level intervals. */
- unsigned char num_model_values[3]; /* Number of model values. */
- uint16_t repetition_period; /* Repetition period (0-16384) */
-
-};
-
-struct ppb_h264 {
- /* 'valid' specifies which fields (or sets of
- * fields) below are valid. If the corresponding
- * bit in 'valid' is NOT set then that field(s)
- * is (are) not initialized. */
- uint32_t valid;
-
- int32_t poc_top; /* POC for Top Field/Frame */
- int32_t poc_bottom; /* POC for Bottom Field */
- uint32_t idr_pic_id;
-
- /* H264_VALID_PANSCAN */
- uint32_t pan_scan_count;
- int32_t pan_scan_left[3];
- int32_t pan_scan_right[3];
- int32_t pan_scan_top[3];
- int32_t pan_scan_bottom[3];
-
- /* H264_VALID_CT_TYPE */
- uint32_t ct_type_count;
- uint32_t ct_type[3];
-
- /* H264_VALID_SPS_CROP */
- int32_t sps_crop_left;
- int32_t sps_crop_right;
- int32_t sps_crop_top;
- int32_t sps_crop_bottom;
-
- /* H264_VALID_VUI */
- uint32_t chroma_top;
- uint32_t chroma_bottom;
-
- /* H264_VALID_USER */
- uint32_t user_data_size;
- struct user_data *user_data;
-
- /* H264 VALID FGT */
- struct fgt_sei *pfgt;
-
-};
-
-struct ppb {
- /* Common fields. */
- uint32_t picture_number; /* Ordinal display number */
- uint32_t video_buffer; /* Video (picbuf) number */
- uint32_t video_address; /* Address of picbuf Y */
- uint32_t video_address_uv; /* Address of picbuf UV */
- uint32_t video_stripe; /* Picbuf stripe */
- uint32_t video_width; /* Picbuf width */
- uint32_t video_height; /* Picbuf height */
-
- uint32_t channel_id; /* Decoder channel ID */
- uint32_t status; /* reserved */
- uint32_t width; /* pixels */
- uint32_t height; /* pixels */
- uint32_t chroma_format; /* see above */
- uint32_t pulldown; /* see above */
- uint32_t flags; /* see above */
- uint32_t pts; /* 32 LSBs of PTS */
- uint32_t protocol; /* protocolXXX (above) */
-
- uint32_t frame_rate; /* see above */
- uint32_t matrix_coeff; /* see above */
- uint32_t aspect_ratio; /* see above */
- uint32_t colour_primaries; /* see above */
- uint32_t transfer_char; /* see above */
- uint32_t pcr_offset; /* 45kHz if PCR type; else 27MHz */
- uint32_t n_drop; /* Number of pictures to be dropped */
-
- uint32_t custom_aspect_ratio_width_height;
- /* upper 16-bits is Y and lower 16-bits is X */
-
- uint32_t picture_tag; /* Indexing tag from BUD packets */
- uint32_t picture_done_payload;
- uint32_t picture_meta_payload;
- uint32_t reserved[1];
-
- /* Protocol-specific extensions. */
- union {
- struct ppb_h264 h264;
- struct ppb_mpeg mpeg;
- struct ppb_vc1 vc1;
- } other;
-
-};
-
-struct c011_pib {
- uint32_t bFormatChange;
- uint32_t resolution;
- uint32_t channelId;
- uint32_t ppbPtr;
- int32_t ptsStcOffset;
- uint32_t zeroPanscanValid;
- uint32_t dramOutBufAddr;
- uint32_t yComponent;
- struct ppb ppb;
-
-};
-
-struct dec_rsp_channel_start_video {
- uint32_t command;
- uint32_t sequence;
- uint32_t status;
- uint32_t picBuf;
- uint32_t picRelBuf;
- uint32_t picInfoDeliveryQ;
- uint32_t picInfoReleaseQ;
- uint32_t channelStatus;
- uint32_t userDataDeliveryQ;
- uint32_t userDataReleaseQ;
- uint32_t transportStreamCaptureAddr;
- uint32_t asyncEventQ;
-
-};
-
-#define eCMD_C011_CMD_BASE (0x73763000)
-
-/* host commands */
-enum c011_ts_cmd {
- eCMD_TS_GET_NEXT_PIC = 0x7376F100, /* debug get next picture */
- eCMD_TS_GET_LAST_PIC = 0x7376F102, /* debug get last pic status */
- eCMD_TS_READ_WRITE_MEM = 0x7376F104, /* debug read write memory */
-
- /* New API commands */
- /* General commands */
- eCMD_C011_INIT = eCMD_C011_CMD_BASE + 0x01,
- eCMD_C011_RESET = eCMD_C011_CMD_BASE + 0x02,
- eCMD_C011_SELF_TEST = eCMD_C011_CMD_BASE + 0x03,
- eCMD_C011_GET_VERSION = eCMD_C011_CMD_BASE + 0x04,
- eCMD_C011_GPIO = eCMD_C011_CMD_BASE + 0x05,
- eCMD_C011_DEBUG_SETUP = eCMD_C011_CMD_BASE + 0x06,
-
- /* Decoding commands */
- eCMD_C011_DEC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x100,
- eCMD_C011_DEC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x101,
- eCMD_C011_DEC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x102,
- eCMD_C011_DEC_CHAN_STATUS = eCMD_C011_CMD_BASE + 0x103,
- eCMD_C011_DEC_CHAN_FLUSH = eCMD_C011_CMD_BASE + 0x104,
- eCMD_C011_DEC_CHAN_TRICK_PLAY = eCMD_C011_CMD_BASE + 0x105,
- eCMD_C011_DEC_CHAN_TS_PIDS = eCMD_C011_CMD_BASE + 0x106,
- eCMD_C011_DEC_CHAN_PS_STREAM_ID = eCMD_C011_CMD_BASE + 0x107,
- eCMD_C011_DEC_CHAN_INPUT_PARAMS = eCMD_C011_CMD_BASE + 0x108,
- eCMD_C011_DEC_CHAN_VIDEO_OUTPUT = eCMD_C011_CMD_BASE + 0x109,
- eCMD_C011_DEC_CHAN_OUTPUT_FORMAT = eCMD_C011_CMD_BASE + 0x10A,
- eCMD_C011_DEC_CHAN_SCALING_FILTERS = eCMD_C011_CMD_BASE + 0x10B,
- eCMD_C011_DEC_CHAN_OSD_MODE = eCMD_C011_CMD_BASE + 0x10D,
- eCMD_C011_DEC_CHAN_DROP = eCMD_C011_CMD_BASE + 0x10E,
- eCMD_C011_DEC_CHAN_RELEASE = eCMD_C011_CMD_BASE + 0x10F,
- eCMD_C011_DEC_CHAN_STREAM_SETTINGS = eCMD_C011_CMD_BASE + 0x110,
- eCMD_C011_DEC_CHAN_PAUSE_OUTPUT = eCMD_C011_CMD_BASE + 0x111,
- eCMD_C011_DEC_CHAN_CHANGE = eCMD_C011_CMD_BASE + 0x112,
- eCMD_C011_DEC_CHAN_SET_STC = eCMD_C011_CMD_BASE + 0x113,
- eCMD_C011_DEC_CHAN_SET_PTS = eCMD_C011_CMD_BASE + 0x114,
- eCMD_C011_DEC_CHAN_CC_MODE = eCMD_C011_CMD_BASE + 0x115,
- eCMD_C011_DEC_CREATE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x116,
- eCMD_C011_DEC_COPY_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x117,
- eCMD_C011_DEC_DELETE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x118,
- eCMD_C011_DEC_CHAN_SET_DECYPTION = eCMD_C011_CMD_BASE + 0x119,
- eCMD_C011_DEC_CHAN_START_VIDEO = eCMD_C011_CMD_BASE + 0x11A,
- eCMD_C011_DEC_CHAN_STOP_VIDEO = eCMD_C011_CMD_BASE + 0x11B,
- eCMD_C011_DEC_CHAN_PIC_CAPTURE = eCMD_C011_CMD_BASE + 0x11C,
- eCMD_C011_DEC_CHAN_PAUSE = eCMD_C011_CMD_BASE + 0x11D,
- eCMD_C011_DEC_CHAN_PAUSE_STATE = eCMD_C011_CMD_BASE + 0x11E,
- eCMD_C011_DEC_CHAN_SET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x11F,
- eCMD_C011_DEC_CHAN_GET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x120,
- eCMD_C011_DEC_CHAN_SET_FF_RATE = eCMD_C011_CMD_BASE + 0x121,
- eCMD_C011_DEC_CHAN_GET_FF_RATE = eCMD_C011_CMD_BASE + 0x122,
- eCMD_C011_DEC_CHAN_FRAME_ADVANCE = eCMD_C011_CMD_BASE + 0x123,
- eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x124,
- eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x125,
- eCMD_C011_DEC_CHAN_FILL_PIC_BUF = eCMD_C011_CMD_BASE + 0x126,
- eCMD_C011_DEC_CHAN_SET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x127,
- eCMD_C011_DEC_CHAN_GET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x128,
- eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x129,
- eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x12A,
- eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS = eCMD_C011_CMD_BASE + 0x12B,
- eCMD_C011_DEC_CHAN_I_PICTURE_FOUND = eCMD_C011_CMD_BASE + 0x12C,
- eCMD_C011_DEC_CHAN_SET_PARAMETER = eCMD_C011_CMD_BASE + 0x12D,
- eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE = eCMD_C011_CMD_BASE + 0x12E,
- eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x12F,
- eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x130,
- eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x131,
- eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE = eCMD_C011_CMD_BASE +
- 0x132,
- eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x133,
- eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x134,
- eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD = eCMD_C011_CMD_BASE + 0x135,
- eCMD_C011_DEC_CHAN_STREAM_OPEN = eCMD_C011_CMD_BASE + 0x136,
- eCMD_C011_DEC_CHAN_SET_PCR_PID = eCMD_C011_CMD_BASE + 0x137,
- eCMD_C011_DEC_CHAN_SET_VID_PID = eCMD_C011_CMD_BASE + 0x138,
- eCMD_C011_DEC_CHAN_SET_PAN_SCAN_MODE = eCMD_C011_CMD_BASE + 0x139,
- eCMD_C011_DEC_CHAN_START_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x140,
- eCMD_C011_DEC_CHAN_STOP_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x141,
- eCMD_C011_DEC_CHAN_SET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x142,
- eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x143,
- eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE = eCMD_C011_CMD_BASE + 0x144,
- eCMD_C011_DEC_CHAN_SET_OPERATION_MODE = eCMD_C011_CMD_BASE + 0x145,
- eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS = eCMD_C011_CMD_BASE + 0x146,
- eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE +
- 0x147,
- eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF = eCMD_C011_CMD_BASE + 0x148,
- eCMD_C011_DEC_CHAN_SET_CLIPPING = eCMD_C011_CMD_BASE + 0x149,
- eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST
- = eCMD_C011_CMD_BASE + 0x150,
-
- /* Decoder RevD commands */
- eCMD_C011_DEC_CHAN_SET_CSC = eCMD_C011_CMD_BASE + 0x180, /* color
- space conversion */
- eCMD_C011_DEC_CHAN_SET_RANGE_REMAP = eCMD_C011_CMD_BASE + 0x181,
- eCMD_C011_DEC_CHAN_SET_FGT = eCMD_C011_CMD_BASE + 0x182,
- /* Note: 0x183 not implemented yet in Rev D main */
- eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE +
- 0x183,
-
- /* Decoder 7412 commands (7412-only) */
- eCMD_C011_DEC_CHAN_SET_CONTENT_KEY = eCMD_C011_CMD_BASE + 0x190,
- eCMD_C011_DEC_CHAN_SET_SESSION_KEY = eCMD_C011_CMD_BASE + 0x191,
- eCMD_C011_DEC_CHAN_FMT_CHANGE_ACK = eCMD_C011_CMD_BASE + 0x192,
-
- eCMD_C011_DEC_CHAN_CUSTOM_VIDOUT = eCMD_C011_CMD_BASE + 0x1FF,
-
- /* Encoding commands */
- eCMD_C011_ENC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x200,
- eCMD_C011_ENC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x201,
- eCMD_C011_ENC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x202,
- eCMD_C011_ENC_CHAN_CONTROL = eCMD_C011_CMD_BASE + 0x203,
- eCMD_C011_ENC_CHAN_STATISTICS = eCMD_C011_CMD_BASE + 0x204,
-
- eNOTIFY_C011_ENC_CHAN_EVENT = eCMD_C011_CMD_BASE + 0x210,
-
-};
-
-#endif
diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c
deleted file mode 100644
index 4765d528279b..000000000000
--- a/drivers/staging/crystalhd/crystalhd_hw.c
+++ /dev/null
@@ -1,2458 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_hw . c
- *
- * Description:
- * BCM70010 Linux driver HW layer.
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#include "crystalhd.h"
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-/* Functions internal to this file */
-
-static void crystalhd_enable_uarts(struct crystalhd_adp *adp)
-{
- bc_dec_reg_wr(adp, UartSelectA, BSVS_UART_STREAM);
- bc_dec_reg_wr(adp, UartSelectB, BSVS_UART_DEC_OUTER);
-}
-
-
-static void crystalhd_start_dram(struct crystalhd_adp *adp)
-{
- bc_dec_reg_wr(adp, SDRAM_PARAM, ((40 / 5 - 1) << 0) |
- /* tras (40ns tras)/(5ns period) -1 ((15/5 - 1) << 4) | // trcd */
- ((15 / 5 - 1) << 7) | /* trp */
- ((10 / 5 - 1) << 10) | /* trrd */
- ((15 / 5 + 1) << 12) | /* twr */
- ((2 + 1) << 16) | /* twtr */
- ((70 / 5 - 2) << 19) | /* trfc */
- (0 << 23));
-
- bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
- bc_dec_reg_wr(adp, SDRAM_EXT_MODE, 2);
- bc_dec_reg_wr(adp, SDRAM_MODE, 0x132);
- bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
- bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
- bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
- bc_dec_reg_wr(adp, SDRAM_MODE, 0x32);
- /* setting the refresh rate here */
- bc_dec_reg_wr(adp, SDRAM_REF_PARAM, ((1 << 12) | 96));
-}
-
-
-static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp)
-{
- union link_misc_perst_deco_ctrl rst_deco_cntrl;
- union link_misc_perst_clk_ctrl rst_clk_cntrl;
- uint32_t temp;
-
- /*
- * Link clocks: MISC_PERST_CLOCK_CTRL Clear PLL power down bit,
- * delay to allow PLL to lock Clear alternate clock, stop clock bits
- */
- rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
- rst_clk_cntrl.pll_pwr_dn = 0;
- crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
- msleep_interruptible(50);
-
- rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
- rst_clk_cntrl.stop_core_clk = 0;
- rst_clk_cntrl.sel_alt_clk = 0;
-
- crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
- msleep_interruptible(50);
-
- /*
- * Bus Arbiter Timeout: GISB_ARBITER_TIMER
- * Set internal bus arbiter timeout to 40us based on core clock speed
- * (63MHz * 40us = 0x9D8)
- */
- crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x9D8);
-
- /*
- * Decoder clocks: MISC_PERST_DECODER_CTRL
- * Enable clocks while 7412 reset is asserted, delay
- * De-assert 7412 reset
- */
- rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
- MISC_PERST_DECODER_CTRL);
- rst_deco_cntrl.stop_bcm_7412_clk = 0;
- rst_deco_cntrl.bcm7412_rst = 1;
- crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
- rst_deco_cntrl.whole_reg);
- msleep_interruptible(10);
-
- rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
- MISC_PERST_DECODER_CTRL);
- rst_deco_cntrl.bcm7412_rst = 0;
- crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
- rst_deco_cntrl.whole_reg);
- msleep_interruptible(50);
-
- /* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */
- crystalhd_reg_wr(adp, OTP_CONTENT_MISC, 0);
-
- /* Clear bit 29 of 0x404 */
- temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
- temp &= ~BC_BIT(29);
- crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
-
- /* 2.5V regulator must be set to 2.6 volts (+6%) */
- /* FIXME: jarod: what's the point of this reg read? */
- temp = crystalhd_reg_rd(adp, MISC_PERST_VREG_CTRL);
- crystalhd_reg_wr(adp, MISC_PERST_VREG_CTRL, 0xF3);
-
- return true;
-}
-
-static bool crystalhd_put_in_reset(struct crystalhd_adp *adp)
-{
- union link_misc_perst_deco_ctrl rst_deco_cntrl;
- union link_misc_perst_clk_ctrl rst_clk_cntrl;
- uint32_t temp;
-
- /*
- * Decoder clocks: MISC_PERST_DECODER_CTRL
- * Assert 7412 reset, delay
- * Assert 7412 stop clock
- */
- rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
- MISC_PERST_DECODER_CTRL);
- rst_deco_cntrl.stop_bcm_7412_clk = 1;
- crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
- rst_deco_cntrl.whole_reg);
- msleep_interruptible(50);
-
- /* Bus Arbiter Timeout: GISB_ARBITER_TIMER
- * Set internal bus arbiter timeout to 40us based on core clock speed
- * (6.75MHZ * 40us = 0x10E)
- */
- crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x10E);
-
- /* Link clocks: MISC_PERST_CLOCK_CTRL
- * Stop core clk, delay
- * Set alternate clk, delay, set PLL power down
- */
- rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
- rst_clk_cntrl.stop_core_clk = 1;
- rst_clk_cntrl.sel_alt_clk = 1;
- crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
- msleep_interruptible(50);
-
- rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
- rst_clk_cntrl.pll_pwr_dn = 1;
- crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
-
- /*
- * Read and restore the Transaction Configuration Register
- * after core reset
- */
- temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
-
- /*
- * Link core soft reset: MISC3_RESET_CTRL
- * - Write BIT[0]=1 and read it back for core reset to take place
- */
- crystalhd_reg_wr(adp, MISC3_RESET_CTRL, 1);
- rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC3_RESET_CTRL);
- msleep_interruptible(50);
-
- /* restore the transaction configuration register */
- crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
-
- return true;
-}
-
-static void crystalhd_disable_interrupts(struct crystalhd_adp *adp)
-{
- union intr_mask_reg intr_mask;
- intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
- intr_mask.mask_pcie_err = 1;
- intr_mask.mask_pcie_rbusmast_err = 1;
- intr_mask.mask_pcie_rgr_bridge = 1;
- intr_mask.mask_rx_done = 1;
- intr_mask.mask_rx_err = 1;
- intr_mask.mask_tx_done = 1;
- intr_mask.mask_tx_err = 1;
- crystalhd_reg_wr(adp, INTR_INTR_MSK_SET_REG, intr_mask.whole_reg);
-
- return;
-}
-
-static void crystalhd_enable_interrupts(struct crystalhd_adp *adp)
-{
- union intr_mask_reg intr_mask;
- intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
- intr_mask.mask_pcie_err = 1;
- intr_mask.mask_pcie_rbusmast_err = 1;
- intr_mask.mask_pcie_rgr_bridge = 1;
- intr_mask.mask_rx_done = 1;
- intr_mask.mask_rx_err = 1;
- intr_mask.mask_tx_done = 1;
- intr_mask.mask_tx_err = 1;
- crystalhd_reg_wr(adp, INTR_INTR_MSK_CLR_REG, intr_mask.whole_reg);
-
- return;
-}
-
-static void crystalhd_clear_errors(struct crystalhd_adp *adp)
-{
- uint32_t reg;
-
- /* FIXME: jarod: wouldn't we want to write a 0 to the reg?
- Or does the write clear the bits specified? */
- reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS);
- if (reg)
- crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg);
-
- reg = crystalhd_reg_rd(adp, MISC1_UV_RX_ERROR_STATUS);
- if (reg)
- crystalhd_reg_wr(adp, MISC1_UV_RX_ERROR_STATUS, reg);
-
- reg = crystalhd_reg_rd(adp, MISC1_TX_DMA_ERROR_STATUS);
- if (reg)
- crystalhd_reg_wr(adp, MISC1_TX_DMA_ERROR_STATUS, reg);
-}
-
-static void crystalhd_clear_interrupts(struct crystalhd_adp *adp)
-{
- uint32_t intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
-
- if (intr_sts) {
- crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
-
- /* Write End Of Interrupt for PCIE */
- crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
- }
-}
-
-static void crystalhd_soft_rst(struct crystalhd_adp *adp)
-{
- uint32_t val;
-
- /* Assert c011 soft reset*/
- bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000001);
- msleep_interruptible(50);
-
- /* Release c011 soft reset*/
- bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000000);
-
- /* Disable Stuffing..*/
- val = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
- val |= BC_BIT(8);
- crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, val);
-}
-
-static bool crystalhd_load_firmware_config(struct crystalhd_adp *adp)
-{
- uint32_t i = 0, reg;
-
- crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19));
-
- crystalhd_reg_wr(adp, AES_CMD, 0);
- crystalhd_reg_wr(adp, AES_CONFIG_INFO,
- (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
- crystalhd_reg_wr(adp, AES_CMD, 0x1);
-
- /* FIXME: jarod: I've seen this fail,
- and introducing extra delays helps... */
- for (i = 0; i < 100; ++i) {
- reg = crystalhd_reg_rd(adp, AES_STATUS);
- if (reg & 0x1)
- return true;
- msleep_interruptible(10);
- }
-
- return false;
-}
-
-
-static bool crystalhd_start_device(struct crystalhd_adp *adp)
-{
- uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0;
-
- BCMLOG(BCMLOG_INFO, "Starting BCM70012 Device\n");
-
- reg_pwrmgmt = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
- reg_pwrmgmt &= ~ASPM_L1_ENABLE;
-
- crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg_pwrmgmt);
-
- if (!crystalhd_bring_out_of_rst(adp)) {
- BCMLOG_ERR("Failed To Bring Link Out Of Reset\n");
- return false;
- }
-
- crystalhd_disable_interrupts(adp);
-
- crystalhd_clear_errors(adp);
-
- crystalhd_clear_interrupts(adp);
-
- crystalhd_enable_interrupts(adp);
-
- /* Enable the option for getting the total no. of DWORDS
- * that have been transferred by the RXDMA engine
- */
- dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG);
- dbg_options |= 0x10;
- crystalhd_reg_wr(adp, MISC1_DMA_DEBUG_OPTIONS_REG, dbg_options);
-
- /* Enable PCI Global Control options */
- glb_cntrl = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
- glb_cntrl |= 0x100;
- glb_cntrl |= 0x8000;
- crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, glb_cntrl);
-
- crystalhd_enable_interrupts(adp);
-
- crystalhd_soft_rst(adp);
- crystalhd_start_dram(adp);
- crystalhd_enable_uarts(adp);
-
- return true;
-}
-
-static bool crystalhd_stop_device(struct crystalhd_adp *adp)
-{
- uint32_t reg;
-
- BCMLOG(BCMLOG_INFO, "Stopping BCM70012 Device\n");
- /* Clear and disable interrupts */
- crystalhd_disable_interrupts(adp);
- crystalhd_clear_errors(adp);
- crystalhd_clear_interrupts(adp);
-
- if (!crystalhd_put_in_reset(adp))
- BCMLOG_ERR("Failed to Put Link To Reset State\n");
-
- reg = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
- reg |= ASPM_L1_ENABLE;
- crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg);
-
- /* Set PCI Clk Req */
- reg = crystalhd_reg_rd(adp, PCIE_CLK_REQ_REG);
- reg |= PCI_CLK_REQ_ENABLE;
- crystalhd_reg_wr(adp, PCIE_CLK_REQ_REG, reg);
-
- return true;
-}
-
-static struct crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(
- struct crystalhd_hw *hw)
-{
- unsigned long flags = 0;
- struct crystalhd_rx_dma_pkt *temp = NULL;
-
- if (!hw)
- return NULL;
-
- spin_lock_irqsave(&hw->lock, flags);
- temp = hw->rx_pkt_pool_head;
- if (temp) {
- hw->rx_pkt_pool_head = hw->rx_pkt_pool_head->next;
- temp->dio_req = NULL;
- temp->pkt_tag = 0;
- temp->flags = 0;
- }
- spin_unlock_irqrestore(&hw->lock, flags);
-
- return temp;
-}
-
-static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw,
- struct crystalhd_rx_dma_pkt *pkt)
-{
- unsigned long flags = 0;
-
- if (!hw || !pkt)
- return;
-
- spin_lock_irqsave(&hw->lock, flags);
- pkt->next = hw->rx_pkt_pool_head;
- hw->rx_pkt_pool_head = pkt;
- spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-/*
- * Call back from TX - IOQ deletion.
- *
- * This routine will release the TX DMA rings allocated
- * during setup_dma rings interface.
- *
- * Memory is allocated per DMA ring basis. This is just
- * a place holder to be able to create the dio queues.
- */
-static void crystalhd_tx_desc_rel_call_back(void *context, void *data)
-{
-}
-
-/*
- * Rx Packet release callback..
- *
- * Release All user mapped capture buffers and Our DMA packets
- * back to our free pool. The actual cleanup of the DMA
- * ring descriptors happen during dma ring release.
- */
-static void crystalhd_rx_pkt_rel_call_back(void *context, void *data)
-{
- struct crystalhd_hw *hw = (struct crystalhd_hw *)context;
- struct crystalhd_rx_dma_pkt *pkt = (struct crystalhd_rx_dma_pkt *)data;
-
- if (!pkt || !hw) {
- BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt);
- return;
- }
-
- if (pkt->dio_req)
- crystalhd_unmap_dio(hw->adp, pkt->dio_req);
- else
- BCMLOG_ERR("Missing dio_req: 0x%x\n", pkt->pkt_tag);
-
- crystalhd_hw_free_rx_pkt(hw, pkt);
-}
-
-#define crystalhd_hw_delete_ioq(adp, q) \
-do { \
- if (q) { \
- crystalhd_delete_dioq(adp, q); \
- q = NULL; \
- } \
-} while (0)
-
-static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw)
-{
- if (!hw)
- return;
-
- BCMLOG(BCMLOG_DBG, "Deleting IOQs\n");
- crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq);
- crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq);
- crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq);
- crystalhd_hw_delete_ioq(hw->adp, hw->rx_freeq);
- crystalhd_hw_delete_ioq(hw->adp, hw->rx_rdyq);
-}
-
-#define crystalhd_hw_create_ioq(sts, hw, q, cb) \
-do { \
- sts = crystalhd_create_dioq(hw->adp, &q, cb, hw); \
- if (sts != BC_STS_SUCCESS) \
- goto hw_create_ioq_err; \
-} while (0)
-
-/*
- * Create IOQs..
- *
- * TX - Active & Free
- * RX - Active, Ready and Free.
- */
-static enum BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_hw_create_ioq(sts, hw, hw->tx_freeq,
- crystalhd_tx_desc_rel_call_back);
- crystalhd_hw_create_ioq(sts, hw, hw->tx_actq,
- crystalhd_tx_desc_rel_call_back);
-
- crystalhd_hw_create_ioq(sts, hw, hw->rx_freeq,
- crystalhd_rx_pkt_rel_call_back);
- crystalhd_hw_create_ioq(sts, hw, hw->rx_rdyq,
- crystalhd_rx_pkt_rel_call_back);
- crystalhd_hw_create_ioq(sts, hw, hw->rx_actq,
- crystalhd_rx_pkt_rel_call_back);
-
- return sts;
-
-hw_create_ioq_err:
- crystalhd_hw_delete_ioqs(hw);
-
- return sts;
-}
-
-
-static bool crystalhd_code_in_full(struct crystalhd_adp *adp,
- uint32_t needed_sz, bool b_188_byte_pkts, uint8_t flags)
-{
- uint32_t base, end, writep, readp;
- uint32_t cpbSize, cpbFullness, fifoSize;
-
- if (flags & 0x02) { /* ASF Bit is set */
- base = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Base);
- end = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2End);
- writep = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Wrptr);
- readp = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Rdptr);
- } else if (b_188_byte_pkts) { /*Encrypted 188 byte packets*/
- base = bc_dec_reg_rd(adp, REG_Dec_TsUser0Base);
- end = bc_dec_reg_rd(adp, REG_Dec_TsUser0End);
- writep = bc_dec_reg_rd(adp, REG_Dec_TsUser0Wrptr);
- readp = bc_dec_reg_rd(adp, REG_Dec_TsUser0Rdptr);
- } else {
- base = bc_dec_reg_rd(adp, REG_DecCA_RegCinBase);
- end = bc_dec_reg_rd(adp, REG_DecCA_RegCinEnd);
- writep = bc_dec_reg_rd(adp, REG_DecCA_RegCinWrPtr);
- readp = bc_dec_reg_rd(adp, REG_DecCA_RegCinRdPtr);
- }
-
- cpbSize = end - base;
- if (writep >= readp)
- cpbFullness = writep - readp;
- else
- cpbFullness = (end - base) - (readp - writep);
-
- fifoSize = cpbSize - cpbFullness;
-
- if (fifoSize < BC_INFIFO_THRESHOLD)
- return true;
-
- if (needed_sz > (fifoSize - BC_INFIFO_THRESHOLD))
- return true;
-
- return false;
-}
-
-static enum BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
- uint32_t list_id, enum BC_STATUS cs)
-{
- struct tx_dma_pkt *tx_req;
-
- if (!hw || !list_id) {
- BCMLOG_ERR("Invalid Arg..\n");
- return BC_STS_INV_ARG;
- }
-
- hw->pwr_lock--;
-
- tx_req = (struct tx_dma_pkt *)crystalhd_dioq_find_and_fetch(
- hw->tx_actq, list_id);
- if (!tx_req) {
- if (cs != BC_STS_IO_USER_ABORT)
- BCMLOG_ERR("Find and Fetch Did not find req\n");
- return BC_STS_NO_DATA;
- }
-
- if (tx_req->call_back) {
- tx_req->call_back(tx_req->dio_req, tx_req->cb_event, cs);
- tx_req->dio_req = NULL;
- tx_req->cb_event = NULL;
- tx_req->call_back = NULL;
- } else {
- BCMLOG(BCMLOG_DBG, "Missing Tx Callback - %X\n",
- tx_req->list_tag);
- }
-
- /* Now put back the tx_list back in FreeQ */
- tx_req->list_tag = 0;
-
- return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0);
-}
-
-static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw,
- uint32_t err_sts)
-{
- uint32_t err_mask, tmp;
- unsigned long flags = 0;
-
- err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK |
- MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK |
- MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
-
- if (!(err_sts & err_mask))
- return false;
-
- BCMLOG_ERR("Error on Tx-L0 %x\n", err_sts);
-
- tmp = err_mask;
-
- if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK)
- tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
-
- if (tmp) {
- spin_lock_irqsave(&hw->lock, flags);
- /* reset list index.*/
- hw->tx_list_post_index = 0;
- spin_unlock_irqrestore(&hw->lock, flags);
- }
-
- tmp = err_sts & err_mask;
- crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
-
- return true;
-}
-
-static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw,
- uint32_t err_sts)
-{
- uint32_t err_mask, tmp;
- unsigned long flags = 0;
-
- err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK |
- MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK |
- MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
-
- if (!(err_sts & err_mask))
- return false;
-
- BCMLOG_ERR("Error on Tx-L1 %x\n", err_sts);
-
- tmp = err_mask;
-
- if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK)
- tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
-
- if (tmp) {
- spin_lock_irqsave(&hw->lock, flags);
- /* reset list index.*/
- hw->tx_list_post_index = 0;
- spin_unlock_irqrestore(&hw->lock, flags);
- }
-
- tmp = err_sts & err_mask;
- crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
-
- return true;
-}
-
-static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts)
-{
- uint32_t err_sts;
-
- if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK)
- crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
- BC_STS_SUCCESS);
-
- if (int_sts & INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK)
- crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
- BC_STS_SUCCESS);
-
- if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK |
- INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) {
- /* No error mask set.. */
- return;
- }
-
- /* Handle Tx errors. */
- err_sts = crystalhd_reg_rd(hw->adp, MISC1_TX_DMA_ERROR_STATUS);
-
- if (crystalhd_tx_list0_handler(hw, err_sts))
- crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
- BC_STS_ERROR);
-
- if (crystalhd_tx_list1_handler(hw, err_sts))
- crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
- BC_STS_ERROR);
-
- hw->stats.tx_errors++;
-}
-
-static void crystalhd_hw_dump_desc(struct dma_descriptor *p_dma_desc,
- uint32_t ul_desc_index, uint32_t cnt)
-{
- uint32_t ix, ll = 0;
-
- if (!p_dma_desc || !cnt)
- return;
-
- /* FIXME: jarod: perhaps a modparam desc_debug to enable this,
- rather than setting ll (log level, I presume) to non-zero? */
- if (!ll)
- return;
-
- for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) {
- BCMLOG(ll,
- "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
- ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
- ul_desc_index,
- p_dma_desc[ul_desc_index].buff_addr_high,
- p_dma_desc[ul_desc_index].buff_addr_low,
- p_dma_desc[ul_desc_index].next_desc_addr_high,
- p_dma_desc[ul_desc_index].next_desc_addr_low,
- p_dma_desc[ul_desc_index].xfer_size,
- p_dma_desc[ul_desc_index].intr_enable,
- p_dma_desc[ul_desc_index].last_rec_indicator);
- }
-
-}
-
-static enum BC_STATUS crystalhd_hw_fill_desc(struct crystalhd_dio_req *ioreq,
- struct dma_descriptor *desc,
- dma_addr_t desc_paddr_base,
- uint32_t sg_cnt, uint32_t sg_st_ix,
- uint32_t sg_st_off, uint32_t xfr_sz)
-{
- uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0;
- dma_addr_t desc_phy_addr = desc_paddr_base;
- union addr_64 addr_temp;
-
- if (!ioreq || !desc || !desc_paddr_base || !xfr_sz ||
- (!sg_cnt && !ioreq->uinfo.dir_tx)) {
- BCMLOG_ERR("Invalid Args\n");
- return BC_STS_INV_ARG;
- }
-
- for (ix = 0; ix < sg_cnt; ix++) {
-
- /* Setup SGLE index. */
- sg_ix = ix + sg_st_ix;
-
- /* Get SGLE length */
- len = crystalhd_get_sgle_len(ioreq, sg_ix);
- if (len % 4) {
- BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix,
- sg_cnt);
- return BC_STS_NOT_IMPL;
- }
- /* Setup DMA desc with Phy addr & Length at current index. */
- addr_temp.full_addr = crystalhd_get_sgle_paddr(ioreq, sg_ix);
- if (sg_ix == sg_st_ix) {
- addr_temp.full_addr += sg_st_off;
- len -= sg_st_off;
- }
- memset(&desc[ix], 0, sizeof(desc[ix]));
- desc[ix].buff_addr_low = addr_temp.low_part;
- desc[ix].buff_addr_high = addr_temp.high_part;
- desc[ix].dma_dir = ioreq->uinfo.dir_tx;
-
- /* Chain DMA descriptor. */
- addr_temp.full_addr = desc_phy_addr +
- sizeof(struct dma_descriptor);
- desc[ix].next_desc_addr_low = addr_temp.low_part;
- desc[ix].next_desc_addr_high = addr_temp.high_part;
-
- if ((count + len) > xfr_sz)
- len = xfr_sz - count;
-
- /* Debug.. */
- if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) {
- BCMLOG_ERR(
- "inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
- len, ix, count, xfr_sz, sg_cnt);
- return BC_STS_ERROR;
- }
- /* Length expects Multiple of 4 */
- desc[ix].xfer_size = (len / 4);
-
- crystalhd_hw_dump_desc(desc, ix, 1);
-
- count += len;
- desc_phy_addr += sizeof(struct dma_descriptor);
- }
-
- last_desc_ix = ix - 1;
-
- if (ioreq->fb_size) {
- memset(&desc[ix], 0, sizeof(desc[ix]));
- addr_temp.full_addr = ioreq->fb_pa;
- desc[ix].buff_addr_low = addr_temp.low_part;
- desc[ix].buff_addr_high = addr_temp.high_part;
- desc[ix].dma_dir = ioreq->uinfo.dir_tx;
- desc[ix].xfer_size = 1;
- desc[ix].fill_bytes = 4 - ioreq->fb_size;
- count += ioreq->fb_size;
- last_desc_ix++;
- }
-
- /* setup last descriptor..*/
- desc[last_desc_ix].last_rec_indicator = 1;
- desc[last_desc_ix].next_desc_addr_low = 0;
- desc[last_desc_ix].next_desc_addr_high = 0;
- desc[last_desc_ix].intr_enable = 1;
-
- crystalhd_hw_dump_desc(desc, last_desc_ix, 1);
-
- if (count != xfr_sz) {
- BCMLOG_ERR("internal error sz curr:%x exp:%x\n", count, xfr_sz);
- return BC_STS_ERROR;
- }
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS crystalhd_xlat_sgl_to_dma_desc(
- struct crystalhd_dio_req *ioreq,
- struct dma_desc_mem *pdesc_mem,
- uint32_t *uv_desc_index)
-{
- struct dma_descriptor *desc = NULL;
- dma_addr_t desc_paddr_base = 0;
- uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0;
- uint32_t xfr_sz = 0;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- /* Check params.. */
- if (!ioreq || !pdesc_mem || !uv_desc_index) {
- BCMLOG_ERR("Invalid Args\n");
- return BC_STS_INV_ARG;
- }
-
- if (!pdesc_mem->sz || !pdesc_mem->pdma_desc_start ||
- !ioreq->sg || (!ioreq->sg_cnt && !ioreq->uinfo.dir_tx)) {
- BCMLOG_ERR("Invalid Args\n");
- return BC_STS_INV_ARG;
- }
-
- if ((ioreq->uinfo.dir_tx) && (ioreq->uinfo.uv_offset)) {
- BCMLOG_ERR("UV offset for TX??\n");
- return BC_STS_INV_ARG;
-
- }
-
- desc = pdesc_mem->pdma_desc_start;
- desc_paddr_base = pdesc_mem->phy_addr;
-
- if (ioreq->uinfo.dir_tx || (ioreq->uinfo.uv_offset == 0)) {
- sg_cnt = ioreq->sg_cnt;
- xfr_sz = ioreq->uinfo.xfr_len;
- } else {
- sg_cnt = ioreq->uinfo.uv_sg_ix + 1;
- xfr_sz = ioreq->uinfo.uv_offset;
- }
-
- sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
- sg_st_ix, sg_st_off, xfr_sz);
-
- if ((sts != BC_STS_SUCCESS) || !ioreq->uinfo.uv_offset)
- return sts;
-
- /* Prepare for UV mapping.. */
- desc = &pdesc_mem->pdma_desc_start[sg_cnt];
- desc_paddr_base = pdesc_mem->phy_addr +
- (sg_cnt * sizeof(struct dma_descriptor));
-
- /* Done with desc addr.. now update sg stuff.*/
- sg_cnt = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix;
- xfr_sz = ioreq->uinfo.xfr_len - ioreq->uinfo.uv_offset;
- sg_st_ix = ioreq->uinfo.uv_sg_ix;
- sg_st_off = ioreq->uinfo.uv_sg_off;
-
- sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
- sg_st_ix, sg_st_off, xfr_sz);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- *uv_desc_index = sg_st_ix;
-
- return sts;
-}
-
-static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw)
-{
- uint32_t dma_cntrl;
-
- dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
- if (!(dma_cntrl & DMA_START_BIT)) {
- dma_cntrl |= DMA_START_BIT;
- crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS,
- dma_cntrl);
- }
-
- return;
-}
-
-/* _CHECK_THIS_
- *
- * Verify if the Stop generates a completion interrupt or not.
- * if it does not generate an interrupt, then add polling here.
- */
-static enum BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
-{
- uint32_t dma_cntrl, cnt = 30;
- uint32_t l1 = 1, l2 = 1;
- unsigned long flags = 0;
-
- dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
-
- BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
-
- if (!(dma_cntrl & DMA_START_BIT)) {
- BCMLOG(BCMLOG_DBG, "Already Stopped\n");
- return BC_STS_SUCCESS;
- }
-
- crystalhd_disable_interrupts(hw->adp);
-
- /* Issue stop to HW */
- /* This bit when set gave problems. Please check*/
- dma_cntrl &= ~DMA_START_BIT;
- crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
-
- BCMLOG(BCMLOG_DBG, "Cleared the DMA Start bit\n");
-
- /* Poll for 3seconds (30 * 100ms) on both the lists..*/
- while ((l1 || l2) && cnt) {
-
- if (l1) {
- l1 = crystalhd_reg_rd(hw->adp,
- MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
- l1 &= DMA_START_BIT;
- }
-
- if (l2) {
- l2 = crystalhd_reg_rd(hw->adp,
- MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
- l2 &= DMA_START_BIT;
- }
-
- msleep_interruptible(100);
-
- cnt--;
- }
-
- if (!cnt) {
- BCMLOG_ERR("Failed to stop TX DMA.. l1 %d, l2 %d\n", l1, l2);
- crystalhd_enable_interrupts(hw->adp);
- return BC_STS_ERROR;
- }
-
- spin_lock_irqsave(&hw->lock, flags);
- hw->tx_list_post_index = 0;
- spin_unlock_irqrestore(&hw->lock, flags);
- BCMLOG(BCMLOG_DBG, "stopped TX DMA..\n");
- crystalhd_enable_interrupts(hw->adp);
-
- return BC_STS_SUCCESS;
-}
-
-static uint32_t crystalhd_get_pib_avail_cnt(struct crystalhd_hw *hw)
-{
- /*
- * Position of the PIB Entries can be found at
- * 0th and the 1st location of the Circular list.
- */
- uint32_t Q_addr;
- uint32_t pib_cnt, r_offset, w_offset;
-
- Q_addr = hw->pib_del_Q_addr;
-
- /* Get the Read Pointer */
- crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
-
- /* Get the Write Pointer */
- crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
-
- if (r_offset == w_offset)
- return 0; /* Queue is empty */
-
- if (w_offset > r_offset)
- pib_cnt = w_offset - r_offset;
- else
- pib_cnt = (w_offset + MAX_PIB_Q_DEPTH) -
- (r_offset + MIN_PIB_Q_DEPTH);
-
- if (pib_cnt > MAX_PIB_Q_DEPTH) {
- BCMLOG_ERR("Invalid PIB Count (%u)\n", pib_cnt);
- return 0;
- }
-
- return pib_cnt;
-}
-
-static uint32_t crystalhd_get_addr_from_pib_Q(struct crystalhd_hw *hw)
-{
- uint32_t Q_addr;
- uint32_t addr_entry, r_offset, w_offset;
-
- Q_addr = hw->pib_del_Q_addr;
-
- /* Get the Read Pointer 0Th Location is Read Pointer */
- crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
-
- /* Get the Write Pointer 1st Location is Write pointer */
- crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
-
- /* Queue is empty */
- if (r_offset == w_offset)
- return 0;
-
- if ((r_offset < MIN_PIB_Q_DEPTH) || (r_offset >= MAX_PIB_Q_DEPTH))
- return 0;
-
- /* Get the Actual Address of the PIB */
- crystalhd_mem_rd(hw->adp, Q_addr + (r_offset * sizeof(uint32_t)),
- 1, &addr_entry);
-
- /* Increment the Read Pointer */
- r_offset++;
-
- if (MAX_PIB_Q_DEPTH == r_offset)
- r_offset = MIN_PIB_Q_DEPTH;
-
- /* Write back the read pointer to It's Location */
- crystalhd_mem_wr(hw->adp, Q_addr, 1, &r_offset);
-
- return addr_entry;
-}
-
-static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw,
- uint32_t addr_to_rel)
-{
- uint32_t Q_addr;
- uint32_t r_offset, w_offset, n_offset;
-
- Q_addr = hw->pib_rel_Q_addr;
-
- /* Get the Read Pointer */
- crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
-
- /* Get the Write Pointer */
- crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
-
- if ((r_offset < MIN_PIB_Q_DEPTH) ||
- (r_offset >= MAX_PIB_Q_DEPTH))
- return false;
-
- n_offset = w_offset + 1;
-
- if (MAX_PIB_Q_DEPTH == n_offset)
- n_offset = MIN_PIB_Q_DEPTH;
-
- if (r_offset == n_offset)
- return false; /* should never happen */
-
- /* Write the DRAM ADDR to the Queue at Next Offset */
- crystalhd_mem_wr(hw->adp, Q_addr + (w_offset * sizeof(uint32_t)),
- 1, &addr_to_rel);
-
- /* Put the New value of the write pointer in Queue */
- crystalhd_mem_wr(hw->adp, Q_addr + sizeof(uint32_t), 1, &n_offset);
-
- return true;
-}
-
-static void cpy_pib_to_app(struct c011_pib *src_pib,
- struct BC_PIC_INFO_BLOCK *dst_pib)
-{
- if (!src_pib || !dst_pib) {
- BCMLOG_ERR("Invalid Arguments\n");
- return;
- }
-
- dst_pib->timeStamp = 0;
- dst_pib->picture_number = src_pib->ppb.picture_number;
- dst_pib->width = src_pib->ppb.width;
- dst_pib->height = src_pib->ppb.height;
- dst_pib->chroma_format = src_pib->ppb.chroma_format;
- dst_pib->pulldown = src_pib->ppb.pulldown;
- dst_pib->flags = src_pib->ppb.flags;
- dst_pib->sess_num = src_pib->ptsStcOffset;
- dst_pib->aspect_ratio = src_pib->ppb.aspect_ratio;
- dst_pib->colour_primaries = src_pib->ppb.colour_primaries;
- dst_pib->picture_meta_payload = src_pib->ppb.picture_meta_payload;
- dst_pib->frame_rate = src_pib->resolution;
- return;
-}
-
-static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw)
-{
- unsigned int cnt;
- struct c011_pib src_pib;
- uint32_t pib_addr, pib_cnt;
- struct BC_PIC_INFO_BLOCK *AppPib;
- struct crystalhd_rx_dma_pkt *rx_pkt = NULL;
-
- pib_cnt = crystalhd_get_pib_avail_cnt(hw);
-
- if (!pib_cnt)
- return;
-
- for (cnt = 0; cnt < pib_cnt; cnt++) {
-
- pib_addr = crystalhd_get_addr_from_pib_Q(hw);
- crystalhd_mem_rd(hw->adp, pib_addr, sizeof(struct c011_pib) / 4,
- (uint32_t *)&src_pib);
-
- if (src_pib.bFormatChange) {
- rx_pkt = (struct crystalhd_rx_dma_pkt *)
- crystalhd_dioq_fetch(hw->rx_freeq);
- if (!rx_pkt)
- return;
- rx_pkt->flags = 0;
- rx_pkt->flags |= COMP_FLAG_PIB_VALID |
- COMP_FLAG_FMT_CHANGE;
- AppPib = &rx_pkt->pib;
- cpy_pib_to_app(&src_pib, AppPib);
-
- BCMLOG(BCMLOG_DBG,
- "App PIB:%x %x %x %x %x %x %x %x %x %x\n",
- rx_pkt->pib.picture_number,
- rx_pkt->pib.aspect_ratio,
- rx_pkt->pib.chroma_format,
- rx_pkt->pib.colour_primaries,
- rx_pkt->pib.frame_rate,
- rx_pkt->pib.height,
- rx_pkt->pib.height,
- rx_pkt->pib.n_drop,
- rx_pkt->pib.pulldown,
- rx_pkt->pib.ycom);
-
- crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true,
- rx_pkt->pkt_tag);
-
- }
-
- crystalhd_rel_addr_to_pib_Q(hw, pib_addr);
- }
-}
-
-static void crystalhd_start_rx_dma_engine(struct crystalhd_hw *hw)
-{
- uint32_t dma_cntrl;
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
- if (!(dma_cntrl & DMA_START_BIT)) {
- dma_cntrl |= DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
- if (!(dma_cntrl & DMA_START_BIT)) {
- dma_cntrl |= DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
-
- return;
-}
-
-static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw)
-{
- uint32_t dma_cntrl = 0, count = 30;
- uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1;
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
- if ((dma_cntrl & DMA_START_BIT)) {
- dma_cntrl &= ~DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
- if ((dma_cntrl & DMA_START_BIT)) {
- dma_cntrl &= ~DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
-
- /* Poll for 3seconds (30 * 100ms) on both the lists..*/
- while ((l0y || l0uv || l1y || l1uv) && count) {
-
- if (l0y) {
- l0y = crystalhd_reg_rd(hw->adp,
- MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
- l0y &= DMA_START_BIT;
- if (!l0y)
- hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
- }
-
- if (l1y) {
- l1y = crystalhd_reg_rd(hw->adp,
- MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
- l1y &= DMA_START_BIT;
- if (!l1y)
- hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
- }
-
- if (l0uv) {
- l0uv = crystalhd_reg_rd(hw->adp,
- MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
- l0uv &= DMA_START_BIT;
- if (!l0uv)
- hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
- }
-
- if (l1uv) {
- l1uv = crystalhd_reg_rd(hw->adp,
- MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
- l1uv &= DMA_START_BIT;
- if (!l1uv)
- hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
- }
- msleep_interruptible(100);
- count--;
- }
-
- hw->rx_list_post_index = 0;
-
- BCMLOG(BCMLOG_SSTEP, "Capture Stop: %d List0:Sts:%x List1:Sts:%x\n",
- count, hw->rx_list_sts[0], hw->rx_list_sts[1]);
-}
-
-static enum BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw,
- struct crystalhd_rx_dma_pkt *rx_pkt)
-{
- uint32_t y_low_addr_reg, y_high_addr_reg;
- uint32_t uv_low_addr_reg, uv_high_addr_reg;
- union addr_64 desc_addr;
- unsigned long flags;
-
- if (!hw || !rx_pkt) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- if (hw->rx_list_post_index >= DMA_ENGINE_CNT) {
- BCMLOG_ERR("List Out Of bounds %x\n", hw->rx_list_post_index);
- return BC_STS_INV_ARG;
- }
-
- spin_lock_irqsave(&hw->rx_lock, flags);
- /* FIXME: jarod: sts_free is an enum for 0,
- in crystalhd_hw.h... yuk... */
- if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) {
- spin_unlock_irqrestore(&hw->rx_lock, flags);
- return BC_STS_BUSY;
- }
-
- if (!hw->rx_list_post_index) {
- y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0;
- y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0;
- uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0;
- uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0;
- } else {
- y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1;
- y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1;
- uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1;
- uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1;
- }
- rx_pkt->pkt_tag = hw->rx_pkt_tag_seed + hw->rx_list_post_index;
- hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_y_intr;
- if (rx_pkt->uv_phy_addr)
- hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_uv_intr;
- hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT;
- spin_unlock_irqrestore(&hw->rx_lock, flags);
-
- crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false,
- rx_pkt->pkt_tag);
-
- crystalhd_start_rx_dma_engine(hw);
- /* Program the Y descriptor */
- desc_addr.full_addr = rx_pkt->desc_mem.phy_addr;
- crystalhd_reg_wr(hw->adp, y_high_addr_reg, desc_addr.high_part);
- crystalhd_reg_wr(hw->adp, y_low_addr_reg, desc_addr.low_part | 0x01);
-
- if (rx_pkt->uv_phy_addr) {
- /* Program the UV descriptor */
- desc_addr.full_addr = rx_pkt->uv_phy_addr;
- crystalhd_reg_wr(hw->adp, uv_high_addr_reg,
- desc_addr.high_part);
- crystalhd_reg_wr(hw->adp, uv_low_addr_reg,
- desc_addr.low_part | 0x01);
- }
-
- return BC_STS_SUCCESS;
-}
-
-static enum BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw,
- struct crystalhd_rx_dma_pkt *rx_pkt)
-{
- enum BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt);
-
- if (sts == BC_STS_BUSY)
- crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt,
- false, rx_pkt->pkt_tag);
-
- return sts;
-}
-
-static void crystalhd_get_dnsz(struct crystalhd_hw *hw, uint32_t list_index,
- uint32_t *y_dw_dnsz, uint32_t *uv_dw_dnsz)
-{
- uint32_t y_dn_sz_reg, uv_dn_sz_reg;
-
- if (!list_index) {
- y_dn_sz_reg = MISC1_Y_RX_LIST0_CUR_BYTE_CNT;
- uv_dn_sz_reg = MISC1_UV_RX_LIST0_CUR_BYTE_CNT;
- } else {
- y_dn_sz_reg = MISC1_Y_RX_LIST1_CUR_BYTE_CNT;
- uv_dn_sz_reg = MISC1_UV_RX_LIST1_CUR_BYTE_CNT;
- }
-
- *y_dw_dnsz = crystalhd_reg_rd(hw->adp, y_dn_sz_reg);
- *uv_dw_dnsz = crystalhd_reg_rd(hw->adp, uv_dn_sz_reg);
-}
-
-/*
- * This function should be called only after making sure that the two DMA
- * lists are free. This function does not check if DMA's are active, before
- * turning off the DMA.
- */
-static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw)
-{
- uint32_t dma_cntrl, aspm;
-
- hw->stop_pending = 0;
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
- if (dma_cntrl & DMA_START_BIT) {
- dma_cntrl &= ~DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
-
- dma_cntrl = crystalhd_reg_rd(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
- if (dma_cntrl & DMA_START_BIT) {
- dma_cntrl &= ~DMA_START_BIT;
- crystalhd_reg_wr(hw->adp,
- MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
- }
- hw->rx_list_post_index = 0;
-
- aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
- aspm |= ASPM_L1_ENABLE;
- /* NAREN BCMLOG(BCMLOG_INFO, "aspm on\n"); */
- crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
-}
-
-static enum BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw,
- uint32_t list_index, enum BC_STATUS comp_sts)
-{
- struct crystalhd_rx_dma_pkt *rx_pkt = NULL;
- uint32_t y_dw_dnsz, uv_dw_dnsz;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- if (!hw || list_index >= DMA_ENGINE_CNT) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq,
- hw->rx_pkt_tag_seed + list_index);
- if (!rx_pkt) {
- BCMLOG_ERR(
- "Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
- hw->rx_list_post_index, hw->rx_list_sts[0],
- hw->rx_list_sts[1], list_index,
- hw->rx_pkt_tag_seed + list_index, comp_sts);
- return BC_STS_INV_ARG;
- }
-
- if (comp_sts == BC_STS_SUCCESS) {
- crystalhd_get_dnsz(hw, list_index, &y_dw_dnsz, &uv_dw_dnsz);
- rx_pkt->dio_req->uinfo.y_done_sz = y_dw_dnsz;
- rx_pkt->flags = COMP_FLAG_DATA_VALID;
- if (rx_pkt->uv_phy_addr)
- rx_pkt->dio_req->uinfo.uv_done_sz = uv_dw_dnsz;
- crystalhd_dioq_add(hw->rx_rdyq, rx_pkt, true,
- hw->rx_pkt_tag_seed + list_index);
- return sts;
- }
-
- /* Check if we can post this DIO again. */
- return crystalhd_hw_post_cap_buff(hw, rx_pkt);
-}
-
-static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw,
- uint32_t int_sts, uint32_t y_err_sts, uint32_t uv_err_sts)
-{
- uint32_t tmp;
- enum list_sts tmp_lsts;
-
- if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK))
- return false;
-
- tmp_lsts = hw->rx_list_sts[0];
-
- /* Y0 - DMA */
- tmp = y_err_sts & GET_Y0_ERR_MSK;
- if (int_sts & INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
- hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
-
- if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
- hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
- tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
- }
-
- if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
- hw->rx_list_sts[0] &= ~rx_y_mask;
- hw->rx_list_sts[0] |= rx_y_error;
- tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
- }
-
- if (tmp) {
- hw->rx_list_sts[0] &= ~rx_y_mask;
- hw->rx_list_sts[0] |= rx_y_error;
- hw->rx_list_post_index = 0;
- }
-
- /* UV0 - DMA */
- tmp = uv_err_sts & GET_UV0_ERR_MSK;
- if (int_sts & INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK)
- hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
-
- if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
- hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
- tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
- }
-
- if (uv_err_sts &
- MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
- hw->rx_list_sts[0] &= ~rx_uv_mask;
- hw->rx_list_sts[0] |= rx_uv_error;
- tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
- }
-
- if (tmp) {
- hw->rx_list_sts[0] &= ~rx_uv_mask;
- hw->rx_list_sts[0] |= rx_uv_error;
- hw->rx_list_post_index = 0;
- }
-
- if (y_err_sts & GET_Y0_ERR_MSK) {
- tmp = y_err_sts & GET_Y0_ERR_MSK;
- crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
- }
-
- if (uv_err_sts & GET_UV0_ERR_MSK) {
- tmp = uv_err_sts & GET_UV0_ERR_MSK;
- crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
- }
-
- return tmp_lsts != hw->rx_list_sts[0];
-}
-
-static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw,
- uint32_t int_sts, uint32_t y_err_sts, uint32_t uv_err_sts)
-{
- uint32_t tmp;
- enum list_sts tmp_lsts;
-
- if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK))
- return false;
-
- tmp_lsts = hw->rx_list_sts[1];
-
- /* Y1 - DMA */
- tmp = y_err_sts & GET_Y1_ERR_MSK;
- if (int_sts & INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK)
- hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
-
- if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
- hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
- tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
- }
-
- if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
- /* Add retry-support..*/
- hw->rx_list_sts[1] &= ~rx_y_mask;
- hw->rx_list_sts[1] |= rx_y_error;
- tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
- }
-
- if (tmp) {
- hw->rx_list_sts[1] &= ~rx_y_mask;
- hw->rx_list_sts[1] |= rx_y_error;
- hw->rx_list_post_index = 0;
- }
-
- /* UV1 - DMA */
- tmp = uv_err_sts & GET_UV1_ERR_MSK;
- if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK)
- hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
-
- if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
- hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
- tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
- }
-
- if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
- /* Add retry-support*/
- hw->rx_list_sts[1] &= ~rx_uv_mask;
- hw->rx_list_sts[1] |= rx_uv_error;
- tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
- }
-
- if (tmp) {
- hw->rx_list_sts[1] &= ~rx_uv_mask;
- hw->rx_list_sts[1] |= rx_uv_error;
- hw->rx_list_post_index = 0;
- }
-
- if (y_err_sts & GET_Y1_ERR_MSK) {
- tmp = y_err_sts & GET_Y1_ERR_MSK;
- crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
- }
-
- if (uv_err_sts & GET_UV1_ERR_MSK) {
- tmp = uv_err_sts & GET_UV1_ERR_MSK;
- crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
- }
-
- return tmp_lsts != hw->rx_list_sts[1];
-}
-
-
-static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
-{
- unsigned long flags;
- uint32_t i, list_avail = 0;
- enum BC_STATUS comp_sts = BC_STS_NO_DATA;
- uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
- bool ret = false;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return;
- }
-
- if (!(intr_sts & GET_RX_INTR_MASK))
- return;
-
- y_err_sts = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_ERROR_STATUS);
- uv_err_sts = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_ERROR_STATUS);
-
- for (i = 0; i < DMA_ENGINE_CNT; i++) {
- /* Update States..*/
- spin_lock_irqsave(&hw->rx_lock, flags);
- if (i == 0)
- ret = crystalhd_rx_list0_handler(hw, intr_sts,
- y_err_sts, uv_err_sts);
- else
- ret = crystalhd_rx_list1_handler(hw, intr_sts,
- y_err_sts, uv_err_sts);
- if (ret) {
- switch (hw->rx_list_sts[i]) {
- case sts_free:
- comp_sts = BC_STS_SUCCESS;
- list_avail = 1;
- break;
- case rx_y_error:
- case rx_uv_error:
- case rx_sts_error:
- /* We got error on both or Y or uv. */
- hw->stats.rx_errors++;
- crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz);
- /* FIXME: jarod: this is where
- my mini pci-e card is tripping up */
- BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x UV:%x Int:%x YDnSz:%x UVDnSz:%x\n",
- i, hw->stats.rx_errors, y_err_sts,
- uv_err_sts, intr_sts, y_dn_sz,
- uv_dn_sz);
- hw->rx_list_sts[i] = sts_free;
- comp_sts = BC_STS_ERROR;
- break;
- default:
- /* Wait for completion..*/
- comp_sts = BC_STS_NO_DATA;
- break;
- }
- }
- spin_unlock_irqrestore(&hw->rx_lock, flags);
-
- /* handle completion...*/
- if (comp_sts != BC_STS_NO_DATA) {
- crystalhd_rx_pkt_done(hw, i, comp_sts);
- comp_sts = BC_STS_NO_DATA;
- }
- }
-
- if (list_avail) {
- if (hw->stop_pending) {
- if ((hw->rx_list_sts[0] == sts_free) &&
- (hw->rx_list_sts[1] == sts_free))
- crystalhd_hw_finalize_pause(hw);
- } else {
- crystalhd_hw_start_capture(hw);
- }
- }
-}
-
-static enum BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw,
- struct BC_FW_CMD *fw_cmd)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
- struct dec_rsp_channel_start_video *st_rsp = NULL;
-
- switch (fw_cmd->cmd[0]) {
- case eCMD_C011_DEC_CHAN_START_VIDEO:
- st_rsp = (struct dec_rsp_channel_start_video *)fw_cmd->rsp;
- hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ;
- hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ;
- BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n",
- hw->pib_del_Q_addr, hw->pib_rel_Q_addr);
- break;
- case eCMD_C011_INIT:
- if (!(crystalhd_load_firmware_config(hw->adp))) {
- BCMLOG_ERR("Invalid Params.\n");
- sts = BC_STS_FW_AUTH_FAILED;
- }
- break;
- default:
- break;
- }
- return sts;
-}
-
-static enum BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw)
-{
- uint32_t reg;
- union link_misc_perst_decoder_ctrl rst_cntrl_reg;
-
- /* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */
- rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp,
- MISC_PERST_DECODER_CTRL);
-
- rst_cntrl_reg.bcm_7412_rst = 1;
- crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL,
- rst_cntrl_reg.whole_reg);
- msleep_interruptible(50);
-
- rst_cntrl_reg.bcm_7412_rst = 0;
- crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL,
- rst_cntrl_reg.whole_reg);
-
- /* Close all banks, put DDR in idle */
- bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0);
-
- /* Set bit 25 (drop CKE pin of DDR) */
- reg = bc_dec_reg_rd(hw->adp, SDRAM_PARAM);
- reg |= 0x02000000;
- bc_dec_reg_wr(hw->adp, SDRAM_PARAM, reg);
-
- /* Reset the audio block */
- bc_dec_reg_wr(hw->adp, AUD_DSP_MISC_SOFT_RESET, 0x1);
-
- /* Power down Raptor PLL */
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllCCtl);
- reg |= 0x00008000;
- bc_dec_reg_wr(hw->adp, DecHt_PllCCtl, reg);
-
- /* Power down all Audio PLL */
- bc_dec_reg_wr(hw->adp, AIO_MISC_PLL_RESET, 0x1);
-
- /* Power down video clock (75MHz) */
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllECtl);
- reg |= 0x00008000;
- bc_dec_reg_wr(hw->adp, DecHt_PllECtl, reg);
-
- /* Power down video clock (75MHz) */
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllDCtl);
- reg |= 0x00008000;
- bc_dec_reg_wr(hw->adp, DecHt_PllDCtl, reg);
-
- /* Power down core clock (200MHz) */
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
- reg |= 0x00008000;
- bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
-
- /* Power down core clock (200MHz) */
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllBCtl);
- reg |= 0x00008000;
- bc_dec_reg_wr(hw->adp, DecHt_PllBCtl, reg);
-
- return BC_STS_SUCCESS;
-}
-
-/************************************************
-**
-*************************************************/
-
-enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer,
- uint32_t sz)
-{
- uint32_t reg_data, cnt, *temp_buff;
- uint32_t fw_sig_len = 36;
- uint32_t dram_offset = BC_FWIMG_ST_ADDR, sig_reg;
-
-
- if (!adp || !buffer || !sz) {
- BCMLOG_ERR("Invalid Params.\n");
- return BC_STS_INV_ARG;
- }
-
- reg_data = crystalhd_reg_rd(adp, OTP_CMD);
- if (!(reg_data & 0x02)) {
- BCMLOG_ERR("Invalid hw config.. otp not programmed\n");
- return BC_STS_ERROR;
- }
-
- reg_data = 0;
- crystalhd_reg_wr(adp, DCI_CMD, 0);
- reg_data |= BC_BIT(0);
- crystalhd_reg_wr(adp, DCI_CMD, reg_data);
-
- reg_data = 0;
- cnt = 1000;
- msleep_interruptible(10);
-
- while (reg_data != BC_BIT(4)) {
- reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
- reg_data &= BC_BIT(4);
- if (--cnt == 0) {
- BCMLOG_ERR("Firmware Download RDY Timeout.\n");
- return BC_STS_TIMEOUT;
- }
- }
-
- msleep_interruptible(10);
- /* Load the FW to the FW_ADDR field in the DCI_FIRMWARE_ADDR */
- crystalhd_reg_wr(adp, DCI_FIRMWARE_ADDR, dram_offset);
- temp_buff = (uint32_t *)buffer;
- for (cnt = 0; cnt < (sz - fw_sig_len); cnt += 4) {
- crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (dram_offset >> 19));
- crystalhd_reg_wr(adp, DCI_FIRMWARE_DATA, *temp_buff);
- dram_offset += 4;
- temp_buff++;
- }
- msleep_interruptible(10);
-
- temp_buff++;
-
- sig_reg = (uint32_t)DCI_SIGNATURE_DATA_7;
- for (cnt = 0; cnt < 8; cnt++) {
- uint32_t swapped_data = *temp_buff;
- swapped_data = bswap_32_1(swapped_data);
- crystalhd_reg_wr(adp, sig_reg, swapped_data);
- sig_reg -= 4;
- temp_buff++;
- }
- msleep_interruptible(10);
-
- reg_data = 0;
- reg_data |= BC_BIT(1);
- crystalhd_reg_wr(adp, DCI_CMD, reg_data);
- msleep_interruptible(10);
-
- reg_data = 0;
- reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
-
- if ((reg_data & BC_BIT(9)) == BC_BIT(9)) {
- cnt = 1000;
- while ((reg_data & BC_BIT(0)) != BC_BIT(0)) {
- reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
- reg_data &= BC_BIT(0);
- if (!(--cnt))
- break;
- msleep_interruptible(10);
- }
- reg_data = 0;
- reg_data = crystalhd_reg_rd(adp, DCI_CMD);
- reg_data |= BC_BIT(4);
- crystalhd_reg_wr(adp, DCI_CMD, reg_data);
-
- } else {
- BCMLOG_ERR("F/w Signature mismatch\n");
- return BC_STS_FW_AUTH_FAILED;
- }
-
- BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n");
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw,
- struct BC_FW_CMD *fw_cmd)
-{
- uint32_t cnt = 0, cmd_res_addr;
- uint32_t *cmd_buff, *res_buff;
- wait_queue_head_t fw_cmd_event;
- int rc = 0;
- enum BC_STATUS sts;
-
- crystalhd_create_event(&fw_cmd_event);
-
- if (!hw || !fw_cmd) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- cmd_buff = fw_cmd->cmd;
- res_buff = fw_cmd->rsp;
-
- if (!cmd_buff || !res_buff) {
- BCMLOG_ERR("Invalid Parameters for F/W Command\n");
- return BC_STS_INV_ARG;
- }
-
- hw->pwr_lock++;
-
- hw->fwcmd_evt_sts = 0;
- hw->pfw_cmd_event = &fw_cmd_event;
-
- /*Write the command to the memory*/
- crystalhd_mem_wr(hw->adp, TS_Host2CpuSnd, FW_CMD_BUFF_SZ, cmd_buff);
-
- /*Memory Read for memory arbitrator flush*/
- crystalhd_mem_rd(hw->adp, TS_Host2CpuSnd, 1, &cnt);
-
- /* Write the command address to mailbox */
- bc_dec_reg_wr(hw->adp, Hst2CpuMbx1, TS_Host2CpuSnd);
- msleep_interruptible(50);
-
- crystalhd_wait_on_event(&fw_cmd_event, hw->fwcmd_evt_sts, 20000, rc, 0);
-
- if (!rc) {
- sts = BC_STS_SUCCESS;
- } else if (rc == -EBUSY) {
- BCMLOG_ERR("Firmware command T/O\n");
- sts = BC_STS_TIMEOUT;
- } else if (rc == -EINTR) {
- BCMLOG(BCMLOG_DBG, "FwCmd Wait Signal int.\n");
- sts = BC_STS_IO_USER_ABORT;
- } else {
- BCMLOG_ERR("FwCmd IO Error.\n");
- sts = BC_STS_IO_ERROR;
- }
-
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("FwCmd Failed.\n");
- hw->pwr_lock--;
- return sts;
- }
-
- /*Get the Response Address*/
- cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1);
-
- /*Read the Response*/
- crystalhd_mem_rd(hw->adp, cmd_res_addr, FW_CMD_BUFF_SZ, res_buff);
-
- hw->pwr_lock--;
-
- if (res_buff[2] != C011_RET_SUCCESS) {
- BCMLOG_ERR("res_buff[2] != C011_RET_SUCCESS\n");
- return BC_STS_FW_CMD_ERR;
- }
-
- sts = crystalhd_fw_cmd_post_proc(hw, fw_cmd);
- if (sts != BC_STS_SUCCESS)
- BCMLOG_ERR("crystalhd_fw_cmd_post_proc Failed.\n");
-
- return sts;
-}
-
-bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
-{
- uint32_t intr_sts = 0;
- uint32_t deco_intr = 0;
- bool rc = false;
-
- if (!adp || !hw->dev_started)
- return rc;
-
- hw->stats.num_interrupts++;
- hw->pwr_lock++;
-
- deco_intr = bc_dec_reg_rd(adp, Stream2Host_Intr_Sts);
- intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
-
- if (intr_sts) {
- /* let system know we processed interrupt..*/
- rc = true;
- hw->stats.dev_interrupts++;
- }
-
- if (deco_intr && (deco_intr != 0xdeaddead)) {
-
- if (deco_intr & 0x80000000) {
- /*Set the Event and the status flag*/
- if (hw->pfw_cmd_event) {
- hw->fwcmd_evt_sts = 1;
- crystalhd_set_event(hw->pfw_cmd_event);
- }
- }
-
- if (deco_intr & BC_BIT(1))
- crystalhd_hw_proc_pib(hw);
-
- bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr);
- /* FIXME: jarod: No udelay? might this be
- the real reason mini pci-e cards were stalling out? */
- bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
- rc = true;
- }
-
- /* Rx interrupts */
- crystalhd_rx_isr(hw, intr_sts);
-
- /* Tx interrupts*/
- crystalhd_tx_isr(hw, intr_sts);
-
- /* Clear interrupts */
- if (rc) {
- if (intr_sts)
- crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
-
- crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
- }
-
- hw->pwr_lock--;
-
- return rc;
-}
-
-enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw,
- struct crystalhd_adp *adp)
-{
- if (!hw || !adp) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- if (hw->dev_started)
- return BC_STS_SUCCESS;
-
- memset(hw, 0, sizeof(struct crystalhd_hw));
-
- hw->adp = adp;
- spin_lock_init(&hw->lock);
- spin_lock_init(&hw->rx_lock);
- /* FIXME: jarod: what are these magic numbers?!? */
- hw->tx_ioq_tag_seed = 0x70023070;
- hw->rx_pkt_tag_seed = 0x70029070;
-
- hw->stop_pending = 0;
- crystalhd_start_device(hw->adp);
- hw->dev_started = true;
-
- /* set initial core clock */
- hw->core_clock_mhz = CLOCK_PRESET;
- hw->prev_n = 0;
- hw->pwr_lock = 0;
- crystalhd_hw_set_core_clock(hw);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw)
-{
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- if (!hw->dev_started)
- return BC_STS_SUCCESS;
-
- /* Stop and DDR sleep will happen in here */
- crystalhd_hw_suspend(hw);
- hw->dev_started = false;
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw)
-{
- unsigned int i;
- void *mem;
- size_t mem_len;
- dma_addr_t phy_addr;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- struct crystalhd_rx_dma_pkt *rpkt;
-
- if (!hw || !hw->adp) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- sts = crystalhd_hw_create_ioqs(hw);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("Failed to create IOQs..\n");
- return sts;
- }
-
- mem_len = BC_LINK_MAX_SGLS * sizeof(struct dma_descriptor);
-
- for (i = 0; i < BC_TX_LIST_CNT; i++) {
- mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
- if (mem) {
- memset(mem, 0, mem_len);
- } else {
- BCMLOG_ERR("Insufficient Memory For TX\n");
- crystalhd_hw_free_dma_rings(hw);
- return BC_STS_INSUFF_RES;
- }
- /* rx_pkt_pool -- static memory allocation */
- hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem;
- hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr;
- hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS *
- sizeof(struct dma_descriptor);
- hw->tx_pkt_pool[i].list_tag = 0;
-
- /* Add TX dma requests to Free Queue..*/
- sts = crystalhd_dioq_add(hw->tx_freeq,
- &hw->tx_pkt_pool[i], false, 0);
- if (sts != BC_STS_SUCCESS) {
- crystalhd_hw_free_dma_rings(hw);
- return sts;
- }
- }
-
- for (i = 0; i < BC_RX_LIST_CNT; i++) {
- rpkt = kzalloc(sizeof(*rpkt), GFP_KERNEL);
- if (!rpkt) {
- BCMLOG_ERR("Insufficient Memory For RX\n");
- crystalhd_hw_free_dma_rings(hw);
- return BC_STS_INSUFF_RES;
- }
-
- mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
- if (mem) {
- memset(mem, 0, mem_len);
- } else {
- BCMLOG_ERR("Insufficient Memory For RX\n");
- crystalhd_hw_free_dma_rings(hw);
- kfree(rpkt);
- return BC_STS_INSUFF_RES;
- }
- rpkt->desc_mem.pdma_desc_start = mem;
- rpkt->desc_mem.phy_addr = phy_addr;
- rpkt->desc_mem.sz = BC_LINK_MAX_SGLS *
- sizeof(struct dma_descriptor);
- rpkt->pkt_tag = hw->rx_pkt_tag_seed + i;
- crystalhd_hw_free_rx_pkt(hw, rpkt);
- }
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw)
-{
- unsigned int i;
- struct crystalhd_rx_dma_pkt *rpkt = NULL;
-
- if (!hw || !hw->adp) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- /* Delete all IOQs.. */
- crystalhd_hw_delete_ioqs(hw);
-
- for (i = 0; i < BC_TX_LIST_CNT; i++) {
- if (hw->tx_pkt_pool[i].desc_mem.pdma_desc_start) {
- bc_kern_dma_free(hw->adp,
- hw->tx_pkt_pool[i].desc_mem.sz,
- hw->tx_pkt_pool[i].desc_mem.pdma_desc_start,
- hw->tx_pkt_pool[i].desc_mem.phy_addr);
-
- hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = NULL;
- }
- }
-
- BCMLOG(BCMLOG_DBG, "Releasing RX Pkt pool\n");
- do {
- rpkt = crystalhd_hw_alloc_rx_pkt(hw);
- if (!rpkt)
- break;
- bc_kern_dma_free(hw->adp, rpkt->desc_mem.sz,
- rpkt->desc_mem.pdma_desc_start,
- rpkt->desc_mem.phy_addr);
- kfree(rpkt);
- } while (rpkt);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw,
- struct crystalhd_dio_req *ioreq,
- hw_comp_callback call_back,
- wait_queue_head_t *cb_event, uint32_t *list_id,
- uint8_t data_flags)
-{
- struct tx_dma_pkt *tx_dma_packet = NULL;
- uint32_t first_desc_u_addr, first_desc_l_addr;
- uint32_t low_addr, high_addr;
- union addr_64 desc_addr;
- enum BC_STATUS sts, add_sts;
- uint32_t dummy_index = 0;
- unsigned long flags;
- bool rc;
-
- if (!hw || !ioreq || !call_back || !cb_event || !list_id) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- /*
- * Since we hit code in busy condition very frequently,
- * we will check the code in status first before
- * checking the availability of free elem.
- *
- * This will avoid the Q fetch/add in normal condition.
- */
- rc = crystalhd_code_in_full(hw->adp, ioreq->uinfo.xfr_len,
- false, data_flags);
- if (rc) {
- hw->stats.cin_busy++;
- return BC_STS_BUSY;
- }
-
- /* Get a list from TxFreeQ */
- tx_dma_packet = (struct tx_dma_pkt *)crystalhd_dioq_fetch(
- hw->tx_freeq);
- if (!tx_dma_packet) {
- BCMLOG_ERR("No empty elements..\n");
- return BC_STS_ERR_USAGE;
- }
-
- sts = crystalhd_xlat_sgl_to_dma_desc(ioreq,
- &tx_dma_packet->desc_mem,
- &dummy_index);
- if (sts != BC_STS_SUCCESS) {
- add_sts = crystalhd_dioq_add(hw->tx_freeq, tx_dma_packet,
- false, 0);
- if (add_sts != BC_STS_SUCCESS)
- BCMLOG_ERR("double fault..\n");
-
- return sts;
- }
-
- hw->pwr_lock++;
-
- desc_addr.full_addr = tx_dma_packet->desc_mem.phy_addr;
- low_addr = desc_addr.low_part;
- high_addr = desc_addr.high_part;
-
- tx_dma_packet->call_back = call_back;
- tx_dma_packet->cb_event = cb_event;
- tx_dma_packet->dio_req = ioreq;
-
- spin_lock_irqsave(&hw->lock, flags);
-
- if (hw->tx_list_post_index == 0) {
- first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST0;
- first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST0;
- } else {
- first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST1;
- first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST1;
- }
-
- *list_id = tx_dma_packet->list_tag = hw->tx_ioq_tag_seed +
- hw->tx_list_post_index;
-
- hw->tx_list_post_index = (hw->tx_list_post_index + 1) % DMA_ENGINE_CNT;
-
- spin_unlock_irqrestore(&hw->lock, flags);
-
-
- /* Insert in Active Q..*/
- crystalhd_dioq_add(hw->tx_actq, tx_dma_packet, false,
- tx_dma_packet->list_tag);
-
- /*
- * Interrupt will come as soon as you write
- * the valid bit. So be ready for that. All
- * the initialization should happen before that.
- */
- crystalhd_start_tx_dma_engine(hw);
- crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part);
-
- crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part |
- 0x01);
- /* Be sure we set the valid bit ^^^^ */
-
- return BC_STS_SUCCESS;
-}
-
-/*
- * This is a force cancel and we are racing with ISR.
- *
- * Will try to remove the req from ActQ before ISR gets it.
- * If ISR gets it first then the completion happens in the
- * normal path and we will return _STS_NO_DATA from here.
- *
- * FIX_ME: Not Tested the actual condition..
- */
-enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw,
- uint32_t list_id)
-{
- if (!hw || !list_id) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_stop_tx_dma_engine(hw);
- crystalhd_hw_tx_req_complete(hw, list_id, BC_STS_IO_USER_ABORT);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
- struct crystalhd_dio_req *ioreq, bool en_post)
-{
- struct crystalhd_rx_dma_pkt *rpkt;
- uint32_t tag, uv_desc_ix = 0;
- enum BC_STATUS sts;
-
- if (!hw || !ioreq) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- rpkt = crystalhd_hw_alloc_rx_pkt(hw);
- if (!rpkt) {
- BCMLOG_ERR("Insufficient resources\n");
- return BC_STS_INSUFF_RES;
- }
-
- rpkt->dio_req = ioreq;
- tag = rpkt->pkt_tag;
-
- sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem,
- &uv_desc_ix);
- if (sts != BC_STS_SUCCESS)
- return sts;
-
- rpkt->uv_phy_addr = 0;
-
- /* Store the address of UV in the rx packet for post*/
- if (uv_desc_ix)
- rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr +
- (sizeof(struct dma_descriptor) * (uv_desc_ix + 1));
-
- if (en_post)
- sts = crystalhd_hw_post_cap_buff(hw, rpkt);
- else
- sts = crystalhd_dioq_add(hw->rx_freeq, rpkt, false, tag);
-
- return sts;
-}
-
-enum BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
- struct BC_PIC_INFO_BLOCK *pib,
- struct crystalhd_dio_req **ioreq)
-{
- struct crystalhd_rx_dma_pkt *rpkt;
- uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000;
- uint32_t sig_pending = 0;
-
-
- if (!hw || !ioreq || !pib) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending);
- if (!rpkt) {
- if (sig_pending) {
- BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n",
- sig_pending);
- return BC_STS_IO_USER_ABORT;
- } else {
- return BC_STS_TIMEOUT;
- }
- }
-
- rpkt->dio_req->uinfo.comp_flags = rpkt->flags;
-
- if (rpkt->flags & COMP_FLAG_PIB_VALID)
- memcpy(pib, &rpkt->pib, sizeof(*pib));
-
- *ioreq = rpkt->dio_req;
-
- crystalhd_hw_free_rx_pkt(hw, rpkt);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw)
-{
- struct crystalhd_rx_dma_pkt *rx_pkt;
- enum BC_STATUS sts;
- uint32_t i;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- /* This is start of capture.. Post to both the lists.. */
- for (i = 0; i < DMA_ENGINE_CNT; i++) {
- rx_pkt = crystalhd_dioq_fetch(hw->rx_freeq);
- if (!rx_pkt)
- return BC_STS_NO_DATA;
- sts = crystalhd_hw_post_cap_buff(hw, rx_pkt);
- if (BC_STS_SUCCESS != sts)
- break;
-
- }
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw)
-{
- void *temp = NULL;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- crystalhd_stop_rx_dma_engine(hw);
-
- do {
- temp = crystalhd_dioq_fetch(hw->rx_freeq);
- if (temp)
- crystalhd_rx_pkt_rel_call_back(hw, temp);
- } while (temp);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw)
-{
- hw->stats.pause_cnt++;
- hw->stop_pending = 1;
-
- if ((hw->rx_list_sts[0] == sts_free) &&
- (hw->rx_list_sts[1] == sts_free))
- crystalhd_hw_finalize_pause(hw);
-
- return BC_STS_SUCCESS;
-}
-
-enum BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw)
-{
- enum BC_STATUS sts;
- uint32_t aspm;
-
- hw->stop_pending = 0;
-
- aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
- aspm &= ~ASPM_L1_ENABLE;
-/* NAREN BCMLOG(BCMLOG_INFO, "aspm off\n"); */
- crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
-
- sts = crystalhd_hw_start_capture(hw);
- return sts;
-}
-
-enum BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw)
-{
- enum BC_STATUS sts;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- sts = crystalhd_put_ddr2sleep(hw);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("Failed to Put DDR To Sleep!!\n");
- return BC_STS_ERROR;
- }
-
- if (!crystalhd_stop_device(hw->adp)) {
- BCMLOG_ERR("Failed to Stop Device!!\n");
- return BC_STS_ERROR;
- }
-
- return BC_STS_SUCCESS;
-}
-
-void crystalhd_hw_stats(struct crystalhd_hw *hw,
- struct crystalhd_hw_stats *stats)
-{
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return;
- }
-
- /* if called w/NULL stats, its a req to zero out the stats */
- if (!stats) {
- memset(&hw->stats, 0, sizeof(hw->stats));
- return;
- }
-
- hw->stats.freeq_count = crystalhd_dioq_count(hw->rx_freeq);
- hw->stats.rdyq_count = crystalhd_dioq_count(hw->rx_rdyq);
- memcpy(stats, &hw->stats, sizeof(*stats));
-}
-
-enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw)
-{
- uint32_t reg, n, i;
- uint32_t vco_mg, refresh_reg;
-
- if (!hw) {
- BCMLOG_ERR("Invalid Arguments\n");
- return BC_STS_INV_ARG;
- }
-
- /* FIXME: jarod: wha? */
- /*n = (hw->core_clock_mhz * 3) / 20 + 1; */
- n = hw->core_clock_mhz/5;
-
- if (n == hw->prev_n)
- return BC_STS_CLK_NOCHG;
-
- if (hw->pwr_lock > 0) {
- /* BCMLOG(BCMLOG_INFO,"pwr_lock is %u\n", hw->pwr_lock) */
- return BC_STS_CLK_NOCHG;
- }
-
- i = n * 27;
- if (i < 560)
- vco_mg = 0;
- else if (i < 900)
- vco_mg = 1;
- else if (i < 1030)
- vco_mg = 2;
- else
- vco_mg = 3;
-
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
-
- reg &= 0xFFFFCFC0;
- reg |= n;
- reg |= vco_mg << 12;
-
- BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n",
- hw->core_clock_mhz, n, vco_mg);
-
- /* Change the DRAM refresh rate to accommodate the new frequency */
- /* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/
- refresh_reg = (7 * hw->core_clock_mhz / 16);
- bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg));
-
- bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
-
- i = 0;
-
- for (i = 0; i < 10; i++) {
- reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
-
- if (reg & 0x00020000) {
- hw->prev_n = n;
- /* FIXME: jarod: outputting
- a random "C" is... confusing... */
- BCMLOG(BCMLOG_INFO, "C");
- return BC_STS_SUCCESS;
- } else {
- msleep_interruptible(10);
- }
- }
- BCMLOG(BCMLOG_INFO, "clk change failed\n");
- return BC_STS_CLK_NOCHG;
-}
diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h
deleted file mode 100644
index d5cb68dfe695..000000000000
--- a/drivers/staging/crystalhd/crystalhd_hw.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_hw . h
- *
- * Description:
- * BCM70012 Linux driver hardware layer.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#ifndef _CRYSTALHD_HW_H_
-#define _CRYSTALHD_HW_H_
-
-#include "crystalhd.h"
-
-/* HW constants..*/
-#define DMA_ENGINE_CNT 2
-#define MAX_PIB_Q_DEPTH 64
-#define MIN_PIB_Q_DEPTH 2
-#define WR_POINTER_OFF 4
-
-#define ASPM_L1_ENABLE (BC_BIT(27))
-
-/*************************************************
- 7412 Decoder Registers.
-**************************************************/
-#define FW_CMD_BUFF_SZ 64
-#define TS_Host2CpuSnd 0x00000100
-#define Hst2CpuMbx1 0x00100F00
-#define Cpu2HstMbx1 0x00100F04
-#define MbxStat1 0x00100F08
-#define Stream2Host_Intr_Sts 0x00100F24
-#define C011_RET_SUCCESS 0x0 /* Return status of firmware command. */
-
-/* TS input status register */
-#define TS_StreamAFIFOStatus 0x0010044C
-#define TS_StreamBFIFOStatus 0x0010084C
-
-/*UART Selection definitions*/
-#define UartSelectA 0x00100300
-#define UartSelectB 0x00100304
-
-#define BSVS_UART_DEC_NONE 0x00
-#define BSVS_UART_DEC_OUTER 0x01
-#define BSVS_UART_DEC_INNER 0x02
-#define BSVS_UART_STREAM 0x03
-
-/* Code-In fifo */
-#define REG_DecCA_RegCinCTL 0xa00
-#define REG_DecCA_RegCinBase 0xa0c
-#define REG_DecCA_RegCinEnd 0xa10
-#define REG_DecCA_RegCinWrPtr 0xa04
-#define REG_DecCA_RegCinRdPtr 0xa08
-
-#define REG_Dec_TsUser0Base 0x100864
-#define REG_Dec_TsUser0Rdptr 0x100868
-#define REG_Dec_TsUser0Wrptr 0x10086C
-#define REG_Dec_TsUser0End 0x100874
-
-/* ASF Case ...*/
-#define REG_Dec_TsAudCDB2Base 0x10036c
-#define REG_Dec_TsAudCDB2Rdptr 0x100378
-#define REG_Dec_TsAudCDB2Wrptr 0x100374
-#define REG_Dec_TsAudCDB2End 0x100370
-
-/* DRAM bringup Registers */
-#define SDRAM_PARAM 0x00040804
-#define SDRAM_PRECHARGE 0x000408B0
-#define SDRAM_EXT_MODE 0x000408A4
-#define SDRAM_MODE 0x000408A0
-#define SDRAM_REFRESH 0x00040890
-#define SDRAM_REF_PARAM 0x00040808
-
-#define DecHt_PllACtl 0x34000C
-#define DecHt_PllBCtl 0x340010
-#define DecHt_PllCCtl 0x340014
-#define DecHt_PllDCtl 0x340034
-#define DecHt_PllECtl 0x340038
-#define AUD_DSP_MISC_SOFT_RESET 0x00240104
-#define AIO_MISC_PLL_RESET 0x0026000C
-#define PCIE_CLK_REQ_REG 0xDC
-#define PCI_CLK_REQ_ENABLE (BC_BIT(8))
-
-/*************************************************
- F/W Copy engine definitions..
-**************************************************/
-#define BC_FWIMG_ST_ADDR 0x00000000
-/* FIXME: jarod: there's a kernel function that'll do this for us... */
-#define rotr32_1(x, n) (((x) >> n) | ((x) << (32 - n)))
-#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
-
-#define DecHt_HostSwReset 0x340000
-#define BC_DRAM_FW_CFG_ADDR 0x001c2000
-
-union addr_64 {
- struct {
- uint32_t low_part;
- uint32_t high_part;
- };
-
- uint64_t full_addr;
-
-};
-
-union intr_mask_reg {
- struct {
- uint32_t mask_tx_done:1;
- uint32_t mask_tx_err:1;
- uint32_t mask_rx_done:1;
- uint32_t mask_rx_err:1;
- uint32_t mask_pcie_err:1;
- uint32_t mask_pcie_rbusmast_err:1;
- uint32_t mask_pcie_rgr_bridge:1;
- uint32_t reserved:25;
- };
-
- uint32_t whole_reg;
-
-};
-
-union link_misc_perst_deco_ctrl {
- struct {
- uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held
- in reset. Reset value 1.*/
- uint32_t reserved0:3; /* Reserved.No Effect*/
- uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of
- 27MHz clk used to clk BCM7412*/
- uint32_t reserved1:27; /* Reserved. No Effect*/
- };
-
- uint32_t whole_reg;
-
-};
-
-union link_misc_perst_clk_ctrl {
- struct {
- uint32_t sel_alt_clk:1; /* When set, selects a
- 6.75MHz clock as the source of core_clk */
- uint32_t stop_core_clk:1; /* When set, stops the branch
- of core_clk that is not needed for low power operation */
- uint32_t pll_pwr_dn:1; /* When set, powers down the
- main PLL. The alternate clock bit should be set to
- select an alternate clock before setting this bit.*/
- uint32_t reserved0:5; /* Reserved */
- uint32_t pll_mult:8; /* This setting controls
- the multiplier for the PLL. */
- uint32_t pll_div:4; /* This setting controls
- the divider for the PLL. */
- uint32_t reserved1:12; /* Reserved */
- };
-
- uint32_t whole_reg;
-
-};
-
-union link_misc_perst_decoder_ctrl {
- struct {
- uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held
- in reset. Reset value 1.*/
- uint32_t res0:3; /* Reserved.No Effect*/
- uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz
- clk used to clk BCM7412*/
- uint32_t res1:27; /* Reserved. No Effect */
- };
-
- uint32_t whole_reg;
-
-};
-
-union desc_low_addr_reg {
- struct {
- uint32_t list_valid:1;
- uint32_t reserved:4;
- uint32_t low_addr:27;
- };
-
- uint32_t whole_reg;
-
-};
-
-struct dma_descriptor { /* 8 32-bit values */
- /* 0th u32 */
- uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */
- uint32_t res0:4; /* bits 28-31: Reserved */
-
- /* 1st u32 */
- uint32_t buff_addr_low; /* 1 buffer address low */
- uint32_t buff_addr_high; /* 2 buffer address high */
-
- /* 3rd u32 */
- uint32_t res2:2; /* 0-1 - Reserved */
- uint32_t xfer_size:23; /* 2-24 = Xfer size in words */
- uint32_t res3:6; /* 25-30 reserved */
- uint32_t intr_enable:1; /* 31 - Interrupt After this desc */
-
- /* 4th u32 */
- uint32_t endian_xlat_align:2; /* 0-1 Endian Translation */
- uint32_t next_desc_cont:1; /* 2 - Next desc is in contig memory */
- uint32_t res4:25; /* 3 - 27 Reserved bits */
- uint32_t fill_bytes:2; /* 28-29 Bits Fill Bytes */
- uint32_t dma_dir:1; /* 30 bit DMA Direction */
- uint32_t last_rec_indicator:1; /* 31 bit Last Record Indicator */
-
- /* 5th u32 */
- uint32_t next_desc_addr_low; /* 32-bits Next Desc Addr lower */
-
- /* 6th u32 */
- uint32_t next_desc_addr_high; /* 32-bits Next Desc Addr Higher */
-
- /* 7th u32 */
- uint32_t res8; /* Last 32bits reserved */
-
-};
-
-/*
- * We will allocate the memory in 4K pages
- * the linked list will be a list of 32 byte descriptors.
- * The virtual address will determine what should be freed.
- */
-struct dma_desc_mem {
- struct dma_descriptor *pdma_desc_start; /* 32-bytes for dma
- descriptor. should be first element */
- dma_addr_t phy_addr; /* physical address
- of each DMA desc */
- uint32_t sz;
- struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */
-
-};
-
-enum list_sts {
- sts_free = 0,
-
- /* RX-Y Bits 0:7 */
- rx_waiting_y_intr = 0x00000001,
- rx_y_error = 0x00000004,
-
- /* RX-UV Bits 8:16 */
- rx_waiting_uv_intr = 0x0000100,
- rx_uv_error = 0x0000400,
-
- rx_sts_waiting = (rx_waiting_y_intr|rx_waiting_uv_intr),
- rx_sts_error = (rx_y_error|rx_uv_error),
-
- rx_y_mask = 0x000000FF,
- rx_uv_mask = 0x0000FF00,
-};
-
-struct tx_dma_pkt {
- struct dma_desc_mem desc_mem;
- hw_comp_callback call_back;
- struct crystalhd_dio_req *dio_req;
- wait_queue_head_t *cb_event;
- uint32_t list_tag;
-};
-
-struct crystalhd_rx_dma_pkt {
- struct dma_desc_mem desc_mem;
- struct crystalhd_dio_req *dio_req;
- uint32_t pkt_tag;
- uint32_t flags;
- struct BC_PIC_INFO_BLOCK pib;
- dma_addr_t uv_phy_addr;
- struct crystalhd_rx_dma_pkt *next;
-};
-
-struct crystalhd_hw_stats {
- uint32_t rx_errors;
- uint32_t tx_errors;
- uint32_t freeq_count;
- uint32_t rdyq_count;
- uint32_t num_interrupts;
- uint32_t dev_interrupts;
- uint32_t cin_busy;
- uint32_t pause_cnt;
-};
-
-struct crystalhd_hw {
- struct tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT];
- spinlock_t lock;
-
- uint32_t tx_ioq_tag_seed;
- uint32_t tx_list_post_index;
-
- struct crystalhd_rx_dma_pkt *rx_pkt_pool_head;
- uint32_t rx_pkt_tag_seed;
-
- bool dev_started;
- void *adp;
-
- wait_queue_head_t *pfw_cmd_event;
- int fwcmd_evt_sts;
-
- uint32_t pib_del_Q_addr;
- uint32_t pib_rel_Q_addr;
-
- struct crystalhd_dioq *tx_freeq;
- struct crystalhd_dioq *tx_actq;
-
- /* Rx DMA Engine Specific Locks */
- spinlock_t rx_lock;
- uint32_t rx_list_post_index;
- enum list_sts rx_list_sts[DMA_ENGINE_CNT];
- struct crystalhd_dioq *rx_rdyq;
- struct crystalhd_dioq *rx_freeq;
- struct crystalhd_dioq *rx_actq;
- uint32_t stop_pending;
-
- /* HW counters.. */
- struct crystalhd_hw_stats stats;
-
- /* Core clock in MHz */
- uint32_t core_clock_mhz;
- uint32_t prev_n;
- uint32_t pwr_lock;
-};
-
-/* Clock defines for power control */
-#define CLOCK_PRESET 175
-
-/* DMA engine register BIT mask wrappers.. */
-#define DMA_START_BIT MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
-
-#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK | \
- INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK | \
- INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK | \
- INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK | \
- INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK | \
- INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK | \
- INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK | \
- INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
-
-#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
-
-#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
-
-#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
- MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
-
-#define GET_UV1_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
- MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
-
-
-/**** API Exposed to the other layers ****/
-enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
- void *buffer, uint32_t sz);
-enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw,
- struct BC_FW_CMD *fw_cmd);
-bool crystalhd_hw_interrupt(struct crystalhd_adp *adp,
- struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *,
- struct crystalhd_adp *);
-enum BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
-enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
-enum BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
-
-
-enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw,
- struct crystalhd_dio_req *ioreq,
- hw_comp_callback call_back,
- wait_queue_head_t *cb_event,
- uint32_t *list_id, uint8_t data_flags);
-
-enum BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw,
- uint32_t list_id);
-enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
- struct crystalhd_dio_req *ioreq, bool en_post);
-enum BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
- struct BC_PIC_INFO_BLOCK *pib,
- struct crystalhd_dio_req **ioreq);
-enum BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
-void crystalhd_hw_stats(struct crystalhd_hw *hw,
- struct crystalhd_hw_stats *stats);
-
-/* API to program the core clock on the decoder */
-enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
-
-#endif
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c
deleted file mode 100644
index e6fb331c6735..000000000000
--- a/drivers/staging/crystalhd/crystalhd_lnx.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/***************************************************************************
- BCM70010 Linux driver
- Copyright (c) 2005-2009, Broadcom Corporation.
-
- This driver 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 of the License.
-
- This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
-***************************************************************************/
-
-#include "crystalhd.h"
-
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-
-static DEFINE_MUTEX(chd_dec_mutex);
-static struct class *crystalhd_class;
-
-static struct crystalhd_adp *g_adp_info;
-
-static irqreturn_t chd_dec_isr(int irq, void *arg)
-{
- struct crystalhd_adp *adp = arg;
- int rc = 0;
- if (adp)
- rc = crystalhd_cmd_interrupt(&adp->cmds);
-
- return IRQ_RETVAL(rc);
-}
-
-static int chd_dec_enable_int(struct crystalhd_adp *adp)
-{
- int rc = 0;
-
- if (!adp || !adp->pdev) {
- BCMLOG_ERR("Invalid arg!!\n");
- return -EINVAL;
- }
-
- if (adp->pdev->msi_enabled)
- adp->msi = 1;
- else
- adp->msi = pci_enable_msi(adp->pdev);
-
- rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED,
- adp->name, (void *)adp);
- if (rc) {
- BCMLOG_ERR("Interrupt request failed..\n");
- pci_disable_msi(adp->pdev);
- }
-
- return rc;
-}
-
-static int chd_dec_disable_int(struct crystalhd_adp *adp)
-{
- if (!adp || !adp->pdev) {
- BCMLOG_ERR("Invalid arg!!\n");
- return -EINVAL;
- }
-
- free_irq(adp->pdev->irq, adp);
-
- if (adp->msi)
- pci_disable_msi(adp->pdev);
-
- return 0;
-}
-
-static struct
-crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
- bool isr)
-{
- unsigned long flags = 0;
- struct crystalhd_ioctl_data *temp;
-
- if (!adp)
- return NULL;
-
- spin_lock_irqsave(&adp->lock, flags);
-
- temp = adp->idata_free_head;
- if (temp) {
- adp->idata_free_head = adp->idata_free_head->next;
- memset(temp, 0, sizeof(*temp));
- }
-
- spin_unlock_irqrestore(&adp->lock, flags);
- return temp;
-}
-
-static void chd_dec_free_iodata(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *iodata, bool isr)
-{
- unsigned long flags = 0;
-
- if (!adp || !iodata)
- return;
-
- spin_lock_irqsave(&adp->lock, flags);
- iodata->next = adp->idata_free_head;
- adp->idata_free_head = iodata;
- spin_unlock_irqrestore(&adp->lock, flags);
-}
-
-static inline int crystalhd_user_data(void __user *ud, void *dr,
- int size, int set)
-{
- int rc;
-
- if (!ud || !dr) {
- BCMLOG_ERR("Invalid arg\n");
- return -EINVAL;
- }
-
- if (set)
- rc = copy_to_user(ud, dr, size);
- else
- rc = copy_from_user(dr, ud, size);
-
- if (rc) {
- BCMLOG_ERR("Invalid args for command\n");
- rc = -EFAULT;
- }
-
- return rc;
-}
-
-static int chd_dec_fetch_cdata(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *io, uint32_t m_sz,
- unsigned long ua)
-{
- unsigned long ua_off;
- int rc = 0;
-
- if (!adp || !io || !ua || !m_sz) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return -EINVAL;
- }
-
- io->add_cdata = vmalloc(m_sz);
- if (!io->add_cdata) {
- BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz);
- return -ENOMEM;
- }
-
- io->add_cdata_sz = m_sz;
- ua_off = ua + sizeof(io->udata);
- rc = crystalhd_user_data((void __user *)ua_off, io->add_cdata,
- io->add_cdata_sz, 0);
- if (rc) {
- BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
- io->add_cdata_sz, (unsigned int)ua_off);
- vfree(io->add_cdata);
- io->add_cdata = NULL;
- return -ENODATA;
- }
-
- return rc;
-}
-
-static int chd_dec_release_cdata(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *io,
- unsigned long ua)
-{
- unsigned long ua_off;
- int rc;
-
- if (!adp || !io || !ua) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return -EINVAL;
- }
-
- if (io->cmd != BCM_IOC_FW_DOWNLOAD) {
- ua_off = ua + sizeof(io->udata);
- rc = crystalhd_user_data((void __user *)ua_off, io->add_cdata,
- io->add_cdata_sz, 1);
- if (rc) {
- BCMLOG_ERR(
- "failed to push add_cdata sz:%x ua_off:%x\n",
- io->add_cdata_sz, (unsigned int)ua_off);
- return -ENODATA;
- }
- }
-
- if (io->add_cdata) {
- vfree(io->add_cdata);
- io->add_cdata = NULL;
- }
-
- return 0;
-}
-
-static int chd_dec_proc_user_data(struct crystalhd_adp *adp,
- struct crystalhd_ioctl_data *io,
- unsigned long ua, int set)
-{
- int rc;
- uint32_t m_sz = 0;
-
- if (!adp || !io || !ua) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return -EINVAL;
- }
-
- rc = crystalhd_user_data((void __user *)ua, &io->udata,
- sizeof(io->udata), set);
- if (rc) {
- BCMLOG_ERR("failed to %s iodata\n", (set ? "set" : "get"));
- return rc;
- }
-
- switch (io->cmd) {
- case BCM_IOC_MEM_RD:
- case BCM_IOC_MEM_WR:
- case BCM_IOC_FW_DOWNLOAD:
- m_sz = io->udata.u.devMem.NumDwords * 4;
- if (set)
- rc = chd_dec_release_cdata(adp, io, ua);
- else
- rc = chd_dec_fetch_cdata(adp, io, m_sz, ua);
- break;
- default:
- break;
- }
-
- return rc;
-}
-
-static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua,
- uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func)
-{
- int rc;
- struct crystalhd_ioctl_data *temp;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- temp = chd_dec_alloc_iodata(adp, 0);
- if (!temp) {
- BCMLOG_ERR("Failed to get iodata..\n");
- return -EINVAL;
- }
-
- temp->u_id = uid;
- temp->cmd = cmd;
-
- rc = chd_dec_proc_user_data(adp, temp, ua, 0);
- if (!rc) {
- sts = func(&adp->cmds, temp);
- if (sts == BC_STS_PENDING)
- sts = BC_STS_NOT_IMPL;
- temp->udata.RetSts = sts;
- rc = chd_dec_proc_user_data(adp, temp, ua, 1);
- }
-
- chd_dec_free_iodata(adp, temp, 0);
-
- return rc;
-}
-
-/* API interfaces */
-static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua)
-{
- struct crystalhd_adp *adp = chd_get_adp();
- crystalhd_cmd_proc cproc;
- struct crystalhd_user *uc;
- int ret;
-
- if (!adp || !fd) {
- BCMLOG_ERR("Invalid adp\n");
- return -EINVAL;
- }
-
- uc = fd->private_data;
- if (!uc) {
- BCMLOG_ERR("Failed to get uc\n");
- return -ENODATA;
- }
-
- mutex_lock(&chd_dec_mutex);
- cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
- if (!cproc) {
- BCMLOG_ERR("Unhandled command: %d\n", cmd);
- mutex_unlock(&chd_dec_mutex);
- return -EINVAL;
- }
-
- ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
- mutex_unlock(&chd_dec_mutex);
- return ret;
-}
-
-static int chd_dec_open(struct inode *in, struct file *fd)
-{
- struct crystalhd_adp *adp = chd_get_adp();
- int rc = 0;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- struct crystalhd_user *uc = NULL;
-
- if (!adp) {
- BCMLOG_ERR("Invalid adp\n");
- return -EINVAL;
- }
-
- if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
- BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users);
- return -EBUSY;
- }
-
- sts = crystalhd_user_open(&adp->cmds, &uc);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("cmd_user_open - %d\n", sts);
- rc = -EBUSY;
- }
-
- adp->cfg_users++;
-
- fd->private_data = uc;
-
- return rc;
-}
-
-static int chd_dec_close(struct inode *in, struct file *fd)
-{
- struct crystalhd_adp *adp = chd_get_adp();
- struct crystalhd_user *uc;
-
- if (!adp) {
- BCMLOG_ERR("Invalid adp\n");
- return -EINVAL;
- }
-
- uc = fd->private_data;
- if (!uc) {
- BCMLOG_ERR("Failed to get uc\n");
- return -ENODATA;
- }
-
- crystalhd_user_close(&adp->cmds, uc);
-
- adp->cfg_users--;
-
- return 0;
-}
-
-static const struct file_operations chd_dec_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = chd_dec_ioctl,
- .open = chd_dec_open,
- .release = chd_dec_close,
- .llseek = noop_llseek,
-};
-
-static int chd_dec_init_chdev(struct crystalhd_adp *adp)
-{
- struct crystalhd_ioctl_data *temp;
- struct device *dev;
- int rc = -ENODEV, i = 0;
-
- if (!adp)
- goto fail;
-
- adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME,
- &chd_dec_fops);
- if (adp->chd_dec_major < 0) {
- BCMLOG_ERR("Failed to create config dev\n");
- rc = adp->chd_dec_major;
- goto fail;
- }
-
- /* register crystalhd class */
- crystalhd_class = class_create(THIS_MODULE, "crystalhd");
- if (IS_ERR(crystalhd_class)) {
- rc = PTR_ERR(crystalhd_class);
- BCMLOG_ERR("failed to create class\n");
- goto class_create_fail;
- }
-
- dev = device_create(crystalhd_class, NULL,
- MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd");
- if (IS_ERR(dev)) {
- rc = PTR_ERR(dev);
- BCMLOG_ERR("failed to create device\n");
- goto device_create_fail;
- }
-
- rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ);
- if (rc) {
- BCMLOG_ERR("failed to create device\n");
- goto elem_pool_fail;
- }
-
- /* Allocate general purpose ioctl pool. */
- for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
- temp = kzalloc(sizeof(*temp), GFP_KERNEL);
- if (!temp) {
- BCMLOG_ERR("ioctl data pool kzalloc failed\n");
- rc = -ENOMEM;
- goto kzalloc_fail;
- }
- /* Add to global pool.. */
- chd_dec_free_iodata(adp, temp, 0);
- }
-
- return 0;
-
-kzalloc_fail:
- crystalhd_delete_elem_pool(adp);
-elem_pool_fail:
- device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
-device_create_fail:
- class_destroy(crystalhd_class);
-class_create_fail:
- unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME);
-fail:
- return rc;
-}
-
-static void chd_dec_release_chdev(struct crystalhd_adp *adp)
-{
- struct crystalhd_ioctl_data *temp = NULL;
- if (!adp)
- return;
-
- if (adp->chd_dec_major > 0) {
- /* unregister crystalhd class */
- device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
- unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME);
- BCMLOG(BCMLOG_INFO, "released api device - %d\n",
- adp->chd_dec_major);
- class_destroy(crystalhd_class);
- }
- adp->chd_dec_major = 0;
-
- /* Clear iodata pool.. */
- do {
- temp = chd_dec_alloc_iodata(adp, 0);
- kfree(temp);
- } while (temp);
-
- crystalhd_delete_elem_pool(adp);
-}
-
-static int chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
-{
- int rc;
- unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
- uint32_t mem_len = pci_resource_len(pinfo->pdev, 2);
- unsigned long bar0 = pci_resource_start(pinfo->pdev, 0);
- uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0);
-
- BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n",
- bar2, mem_len, bar0, i2o_len);
-
- rc = check_mem_region(bar2, mem_len);
- if (rc) {
- BCMLOG_ERR("No valid mem region...\n");
- return -ENOMEM;
- }
-
- pinfo->addr = ioremap_nocache(bar2, mem_len);
- if (!pinfo->addr) {
- BCMLOG_ERR("Failed to remap mem region...\n");
- return -ENOMEM;
- }
-
- pinfo->pci_mem_start = bar2;
- pinfo->pci_mem_len = mem_len;
-
- rc = check_mem_region(bar0, i2o_len);
- if (rc) {
- BCMLOG_ERR("No valid mem region...\n");
- return -ENOMEM;
- }
-
- pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len);
- if (!pinfo->i2o_addr) {
- BCMLOG_ERR("Failed to remap mem region...\n");
- return -ENOMEM;
- }
-
- pinfo->pci_i2o_start = bar0;
- pinfo->pci_i2o_len = i2o_len;
-
- rc = pci_request_regions(pinfo->pdev, pinfo->name);
- if (rc < 0) {
- BCMLOG_ERR("Region request failed: %d\n", rc);
- return rc;
- }
-
- BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n",
- (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr);
-
- return 0;
-}
-
-static void chd_pci_release_mem(struct crystalhd_adp *pinfo)
-{
- if (!pinfo)
- return;
-
- if (pinfo->addr)
- iounmap(pinfo->addr);
-
- if (pinfo->i2o_addr)
- iounmap(pinfo->i2o_addr);
-
- pci_release_regions(pinfo->pdev);
-}
-
-
-static void chd_dec_pci_remove(struct pci_dev *pdev)
-{
- struct crystalhd_adp *pinfo;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- pinfo = pci_get_drvdata(pdev);
- if (!pinfo) {
- BCMLOG_ERR("could not get adp\n");
- return;
- }
-
- sts = crystalhd_delete_cmd_context(&pinfo->cmds);
- if (sts != BC_STS_SUCCESS)
- BCMLOG_ERR("cmd delete :%d\n", sts);
-
- chd_dec_release_chdev(pinfo);
-
- chd_dec_disable_int(pinfo);
-
- chd_pci_release_mem(pinfo);
- pci_disable_device(pinfo->pdev);
-
- kfree(pinfo);
- g_adp_info = NULL;
-}
-
-static int chd_dec_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *entry)
-{
- struct crystalhd_adp *pinfo;
- int rc;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- BCMLOG(BCMLOG_DBG,
- "PCI_INFO: Vendor:0x%04x Device:0x%04x s_vendor:0x%04x s_device: 0x%04x\n",
- pdev->vendor, pdev->device, pdev->subsystem_vendor,
- pdev->subsystem_device);
-
- pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
- if (!pinfo) {
- BCMLOG_ERR("Failed to allocate memory\n");
- return -ENOMEM;
- }
-
- pinfo->pdev = pdev;
-
- rc = pci_enable_device(pdev);
- if (rc) {
- BCMLOG_ERR("Failed to enable PCI device\n");
- goto err;
- }
-
- snprintf(pinfo->name, sizeof(pinfo->name), "crystalhd_pci_e:%d:%d:%d",
- pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn));
-
- rc = chd_pci_reserve_mem(pinfo);
- if (rc) {
- BCMLOG_ERR("Failed to setup memory regions.\n");
- pci_disable_device(pdev);
- rc = -ENOMEM;
- goto err;
- }
-
- pinfo->present = 1;
- pinfo->drv_data = entry->driver_data;
-
- /* Setup adapter level lock.. */
- spin_lock_init(&pinfo->lock);
-
- /* setup api stuff.. */
- chd_dec_init_chdev(pinfo);
- rc = chd_dec_enable_int(pinfo);
- if (rc) {
- BCMLOG_ERR("_enable_int err:%d\n", rc);
- pci_disable_device(pdev);
- rc = -ENODEV;
- goto err;
- }
-
- /* Set dma mask... */
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
- pinfo->dmabits = 64;
- } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
- pinfo->dmabits = 32;
- } else {
- BCMLOG_ERR("Unabled to setup DMA %d\n", rc);
- pci_disable_device(pdev);
- rc = -ENODEV;
- goto err;
- }
-
- sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("cmd setup :%d\n", sts);
- pci_disable_device(pdev);
- rc = -ENODEV;
- goto err;
- }
-
- pci_set_master(pdev);
-
- pci_set_drvdata(pdev, pinfo);
-
- g_adp_info = pinfo;
-
- return 0;
-
-err:
- kfree(pinfo);
- return rc;
-}
-
-#ifdef CONFIG_PM
-static int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct crystalhd_adp *adp;
- struct crystalhd_ioctl_data *temp;
- enum BC_STATUS sts = BC_STS_SUCCESS;
-
- adp = pci_get_drvdata(pdev);
- if (!adp) {
- BCMLOG_ERR("could not get adp\n");
- return -ENODEV;
- }
-
- temp = chd_dec_alloc_iodata(adp, false);
- if (!temp) {
- BCMLOG_ERR("could not get ioctl data\n");
- return -ENODEV;
- }
-
- sts = crystalhd_suspend(&adp->cmds, temp);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("BCM70012 Suspend %d\n", sts);
- return -ENODEV;
- }
-
- chd_dec_free_iodata(adp, temp, false);
- chd_dec_disable_int(adp);
- pci_save_state(pdev);
-
- /* Disable IO/bus master/irq router */
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static int chd_dec_pci_resume(struct pci_dev *pdev)
-{
- struct crystalhd_adp *adp;
- enum BC_STATUS sts = BC_STS_SUCCESS;
- int rc;
-
- adp = pci_get_drvdata(pdev);
- if (!adp) {
- BCMLOG_ERR("could not get adp\n");
- return -ENODEV;
- }
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- /* device's irq possibly is changed, driver should take care */
- if (pci_enable_device(pdev)) {
- BCMLOG_ERR("Failed to enable PCI device\n");
- return 1;
- }
-
- pci_set_master(pdev);
-
- rc = chd_dec_enable_int(adp);
- if (rc) {
- BCMLOG_ERR("_enable_int err:%d\n", rc);
- pci_disable_device(pdev);
- return -ENODEV;
- }
-
- sts = crystalhd_resume(&adp->cmds);
- if (sts != BC_STS_SUCCESS) {
- BCMLOG_ERR("BCM70012 Resume %d\n", sts);
- pci_disable_device(pdev);
- return -ENODEV;
- }
-
- return 0;
-}
-#endif
-
-static const struct pci_device_id chd_dec_pci_id_table[] = {
- { PCI_VDEVICE(BROADCOM, 0x1612), 8 },
- { 0, },
-};
-MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
-
-static struct pci_driver bc_chd_70012_driver = {
- .name = "Broadcom 70012 Decoder",
- .probe = chd_dec_pci_probe,
- .remove = chd_dec_pci_remove,
- .id_table = chd_dec_pci_id_table,
-#ifdef CONFIG_PM
- .suspend = chd_dec_pci_suspend,
- .resume = chd_dec_pci_resume
-#endif
-};
-
-void chd_set_log_level(struct crystalhd_adp *adp, char *arg)
-{
- if ((!arg) || (strlen(arg) < 3))
- g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA;
- else if (!strncmp(arg, "sstep", 5))
- g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG |
- BCMLOG_SSTEP | BCMLOG_ERROR;
- else if (!strncmp(arg, "info", 4))
- g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO;
- else if (!strncmp(arg, "debug", 5))
- g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO |
- BCMLOG_DBG;
- else if (!strncmp(arg, "pball", 5))
- g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK);
- else if (!strncmp(arg, "silent", 6))
- g_linklog_level = 0;
- else
- g_linklog_level = 0;
-}
-
-struct crystalhd_adp *chd_get_adp(void)
-{
- return g_adp_info;
-}
-
-static int __init chd_dec_module_init(void)
-{
- int rc;
-
- chd_set_log_level(NULL, "debug");
- BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d\n",
- crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
-
- rc = pci_register_driver(&bc_chd_70012_driver);
-
- if (rc < 0)
- BCMLOG_ERR("Could not find any devices. err:%d\n", rc);
-
- return rc;
-}
-module_init(chd_dec_module_init);
-
-static void __exit chd_dec_module_cleanup(void)
-{
- BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d\n",
- crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
-
- pci_unregister_driver(&bc_chd_70012_driver);
-}
-module_exit(chd_dec_module_cleanup);
-
-MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>");
-MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>");
-MODULE_DESCRIPTION(CRYSTAL_HD_NAME);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("bcm70012");
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h
deleted file mode 100644
index 49e1ef3a19af..000000000000
--- a/drivers/staging/crystalhd/crystalhd_lnx.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_lnx . h
- *
- * Description:
- * BCM70012 Linux driver
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#ifndef _CRYSTALHD_LNX_H_
-#define _CRYSTALHD_LNX_H_
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <linux/vmalloc.h>
-
-#include <linux/io.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <linux/uaccess.h>
-
-#include "crystalhd.h"
-
-#define CRYSTAL_HD_NAME "Broadcom Crystal HD Decoder (BCM70012) Driver"
-
-/* OS specific PCI information structure and adapter information. */
-struct crystalhd_adp {
- /* Hardware board/PCI specifics */
- char name[32];
- struct pci_dev *pdev;
-
- unsigned long pci_mem_start;
- uint32_t pci_mem_len;
- void __iomem *addr;
-
- unsigned long pci_i2o_start;
- uint32_t pci_i2o_len;
- void __iomem *i2o_addr;
-
- unsigned int drv_data;
- unsigned int dmabits; /* 32 | 64 */
- unsigned int registered;
- unsigned int present;
- unsigned int msi;
-
- spinlock_t lock;
-
- /* API Related */
- int chd_dec_major;
- unsigned int cfg_users;
-
- struct crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */
- struct crystalhd_elem *elem_pool_head; /* Queue element pool */
-
- struct crystalhd_cmd cmds;
-
- struct crystalhd_dio_req *ua_map_free_head;
- struct pci_pool *fill_byte_pool;
-};
-
-
-struct crystalhd_adp *chd_get_adp(void);
-void chd_set_log_level(struct crystalhd_adp *adp, char *arg);
-
-#endif
-
diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c
deleted file mode 100644
index 3aabf75b7d97..000000000000
--- a/drivers/staging/crystalhd/crystalhd_misc.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_misc . c
- *
- * Description:
- * BCM70012 Linux driver misc routines.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#include "crystalhd.h"
-
-#include <linux/slab.h>
-
-uint32_t g_linklog_level;
-
-static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp,
- uint32_t mem_off)
-{
- crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
- return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF)));
-}
-
-static inline void crystalhd_dram_wr(struct crystalhd_adp *adp,
- uint32_t mem_off, uint32_t val)
-{
- crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
- bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val);
-}
-
-static inline enum BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp,
- uint32_t start_off, uint32_t cnt)
-{
- return BC_STS_SUCCESS;
-}
-
-static struct crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp)
-{
- unsigned long flags = 0;
- struct crystalhd_dio_req *temp = NULL;
-
- if (!adp) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return temp;
- }
-
- spin_lock_irqsave(&adp->lock, flags);
- temp = adp->ua_map_free_head;
- if (temp)
- adp->ua_map_free_head = adp->ua_map_free_head->next;
- spin_unlock_irqrestore(&adp->lock, flags);
-
- return temp;
-}
-
-static void crystalhd_free_dio(struct crystalhd_adp *adp,
- struct crystalhd_dio_req *dio)
-{
- unsigned long flags = 0;
-
- if (!adp || !dio)
- return;
- spin_lock_irqsave(&adp->lock, flags);
- dio->sig = crystalhd_dio_inv;
- dio->page_cnt = 0;
- dio->fb_size = 0;
- memset(&dio->uinfo, 0, sizeof(dio->uinfo));
- dio->next = adp->ua_map_free_head;
- adp->ua_map_free_head = dio;
- spin_unlock_irqrestore(&adp->lock, flags);
-}
-
-static struct crystalhd_elem *crystalhd_alloc_elem(struct crystalhd_adp *adp)
-{
- unsigned long flags = 0;
- struct crystalhd_elem *temp = NULL;
-
- if (!adp)
- return temp;
- spin_lock_irqsave(&adp->lock, flags);
- temp = adp->elem_pool_head;
- if (temp) {
- adp->elem_pool_head = adp->elem_pool_head->flink;
- memset(temp, 0, sizeof(*temp));
- }
- spin_unlock_irqrestore(&adp->lock, flags);
-
- return temp;
-}
-static void crystalhd_free_elem(struct crystalhd_adp *adp,
- struct crystalhd_elem *elem)
-{
- unsigned long flags = 0;
-
- if (!adp || !elem)
- return;
- spin_lock_irqsave(&adp->lock, flags);
- elem->flink = adp->elem_pool_head;
- adp->elem_pool_head = elem;
- spin_unlock_irqrestore(&adp->lock, flags);
-}
-
-static inline void crystalhd_set_sg(struct scatterlist *sg, struct page *page,
- unsigned int len, unsigned int offset)
-{
- sg_set_page(sg, page, len, offset);
-#ifdef CONFIG_X86_64
- sg->dma_length = len;
-#endif
-}
-
-static inline void crystalhd_init_sg(struct scatterlist *sg,
- unsigned int entries)
-{
- /* http://lkml.org/lkml/2007/11/27/68 */
- sg_init_table(sg, entries);
-}
-
-/*========================== Extern ========================================*/
-/**
- * bc_dec_reg_rd - Read 7412's device register.
- * @adp: Adapter instance
- * @reg_off: Register offset.
- *
- * Return:
- * 32bit value read
- *
- * 7412's device register read routine. This interface use
- * 7412's device access range mapped from BAR-2 (4M) of PCIe
- * configuration space.
- */
-uint32_t bc_dec_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
-{
- if (!adp || (reg_off > adp->pci_mem_len)) {
- BCMLOG_ERR("dec_rd_reg_off outof range: 0x%08x\n", reg_off);
- return 0;
- }
-
- return readl(adp->addr + reg_off);
-}
-
-/**
- * bc_dec_reg_wr - Write 7412's device register
- * @adp: Adapter instance
- * @reg_off: Register offset.
- * @val: Dword value to be written.
- *
- * Return:
- * none.
- *
- * 7412's device register write routine. This interface use
- * 7412's device access range mapped from BAR-2 (4M) of PCIe
- * configuration space.
- */
-void bc_dec_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
-{
- if (!adp || (reg_off > adp->pci_mem_len)) {
- BCMLOG_ERR("dec_wr_reg_off outof range: 0x%08x\n", reg_off);
- return;
- }
- writel(val, adp->addr + reg_off);
- udelay(8);
-}
-
-/**
- * crystalhd_reg_rd - Read Link's device register.
- * @adp: Adapter instance
- * @reg_off: Register offset.
- *
- * Return:
- * 32bit value read
- *
- * Link device register read routine. This interface use
- * Link's device access range mapped from BAR-1 (64K) of PCIe
- * configuration space.
- *
- */
-uint32_t crystalhd_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
-{
- if (!adp || (reg_off > adp->pci_i2o_len)) {
- BCMLOG_ERR("link_rd_reg_off outof range: 0x%08x\n", reg_off);
- return 0;
- }
- return readl(adp->i2o_addr + reg_off);
-}
-
-/**
- * crystalhd_reg_wr - Write Link's device register
- * @adp: Adapter instance
- * @reg_off: Register offset.
- * @val: Dword value to be written.
- *
- * Return:
- * none.
- *
- * Link device register write routine. This interface use
- * Link's device access range mapped from BAR-1 (64K) of PCIe
- * configuration space.
- *
- */
-void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off,
- uint32_t val)
-{
- if (!adp || (reg_off > adp->pci_i2o_len)) {
- BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off);
- return;
- }
- writel(val, adp->i2o_addr + reg_off);
-}
-
-/**
- * crystalhd_mem_rd - Read data from 7412's DRAM area.
- * @adp: Adapter instance
- * @start_off: Start offset.
- * @dw_cnt: Count in dwords.
- * @rd_buff: Buffer to copy the data from dram.
- *
- * Return:
- * Status.
- *
- * 7412's Dram read routine.
- */
-enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off,
- uint32_t dw_cnt, uint32_t *rd_buff)
-{
- uint32_t ix = 0;
-
- if (!adp || !rd_buff ||
- (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
- for (ix = 0; ix < dw_cnt; ix++)
- rd_buff[ix] = crystalhd_dram_rd(adp, (start_off + (ix * 4)));
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_mem_wr - Write data to 7412's DRAM area.
- * @adp: Adapter instance
- * @start_off: Start offset.
- * @dw_cnt: Count in dwords.
- * @wr_buff: Data Buffer to be written.
- *
- * Return:
- * Status.
- *
- * 7412's Dram write routine.
- */
-enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off,
- uint32_t dw_cnt, uint32_t *wr_buff)
-{
- uint32_t ix = 0;
-
- if (!adp || !wr_buff ||
- (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
-
- for (ix = 0; ix < dw_cnt; ix++)
- crystalhd_dram_wr(adp, (start_off + (ix * 4)), wr_buff[ix]);
-
- return BC_STS_SUCCESS;
-}
-/**
- * crystalhd_pci_cfg_rd - PCIe config read
- * @adp: Adapter instance
- * @off: PCI config space offset.
- * @len: Size -- Byte, Word & dword.
- * @val: Value read
- *
- * Return:
- * Status.
- *
- * Get value from Link's PCIe config space.
- */
-enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off,
- uint32_t len, uint32_t *val)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
- int rc = 0;
-
- if (!adp || !val) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
-
- switch (len) {
- case 1:
- rc = pci_read_config_byte(adp->pdev, off, (u8 *)val);
- break;
- case 2:
- rc = pci_read_config_word(adp->pdev, off, (u16 *)val);
- break;
- case 4:
- rc = pci_read_config_dword(adp->pdev, off, (u32 *)val);
- break;
- default:
- rc = -EINVAL;
- sts = BC_STS_INV_ARG;
- BCMLOG_ERR("Invalid len:%d\n", len);
- }
-
- if (rc && (sts == BC_STS_SUCCESS))
- sts = BC_STS_ERROR;
-
- return sts;
-}
-
-/**
- * crystalhd_pci_cfg_wr - PCIe config write
- * @adp: Adapter instance
- * @off: PCI config space offset.
- * @len: Size -- Byte, Word & dword.
- * @val: Value to be written
- *
- * Return:
- * Status.
- *
- * Set value to Link's PCIe config space.
- */
-enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off,
- uint32_t len, uint32_t val)
-{
- enum BC_STATUS sts = BC_STS_SUCCESS;
- int rc = 0;
-
- if (!adp || !val) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
-
- switch (len) {
- case 1:
- rc = pci_write_config_byte(adp->pdev, off, (u8)val);
- break;
- case 2:
- rc = pci_write_config_word(adp->pdev, off, (u16)val);
- break;
- case 4:
- rc = pci_write_config_dword(adp->pdev, off, val);
- break;
- default:
- rc = -EINVAL;
- sts = BC_STS_INV_ARG;
- BCMLOG_ERR("Invalid len:%d\n", len);
- }
-
- if (rc && (sts == BC_STS_SUCCESS))
- sts = BC_STS_ERROR;
-
- return sts;
-}
-
-/**
- * bc_kern_dma_alloc - Allocate memory for Dma rings
- * @adp: Adapter instance
- * @sz: Size of the memory to allocate.
- * @phy_addr: Physical address of the memory allocated.
- * Typedef to system's dma_addr_t (u64)
- *
- * Return:
- * Pointer to allocated memory..
- *
- * Wrapper to Linux kernel interface.
- *
- */
-void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz,
- dma_addr_t *phy_addr)
-{
- void *temp = NULL;
-
- if (!adp || !sz || !phy_addr) {
- BCMLOG_ERR("Invalid Arg..\n");
- return temp;
- }
-
- temp = pci_alloc_consistent(adp->pdev, sz, phy_addr);
- if (temp)
- memset(temp, 0, sz);
-
- return temp;
-}
-
-/**
- * bc_kern_dma_free - Release Dma ring memory.
- * @adp: Adapter instance
- * @sz: Size of the memory to allocate.
- * @ka: Kernel virtual address returned during _dio_alloc()
- * @phy_addr: Physical address of the memory allocated.
- * Typedef to system's dma_addr_t (u64)
- *
- * Return:
- * none.
- */
-void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka,
- dma_addr_t phy_addr)
-{
- if (!adp || !ka || !sz || !phy_addr) {
- BCMLOG_ERR("Invalid Arg..\n");
- return;
- }
-
- pci_free_consistent(adp->pdev, sz, ka, phy_addr);
-}
-
-/**
- * crystalhd_create_dioq - Create Generic DIO queue
- * @adp: Adapter instance
- * @dioq_hnd: Handle to the dio queue created
- * @cb : Optional - Call back To free the element.
- * @cbctx: Context to pass to callback.
- *
- * Return:
- * status
- *
- * Initialize Generic DIO queue to hold any data. Callback
- * will be used to free elements while deleting the queue.
- */
-enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp,
- struct crystalhd_dioq **dioq_hnd,
- crystalhd_data_free_cb cb, void *cbctx)
-{
- struct crystalhd_dioq *dioq = NULL;
-
- if (!adp || !dioq_hnd) {
- BCMLOG_ERR("Invalid arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- dioq = kzalloc(sizeof(*dioq), GFP_KERNEL);
- if (!dioq)
- return BC_STS_INSUFF_RES;
-
- spin_lock_init(&dioq->lock);
- dioq->sig = BC_LINK_DIOQ_SIG;
- dioq->head = (struct crystalhd_elem *)&dioq->head;
- dioq->tail = (struct crystalhd_elem *)&dioq->head;
- crystalhd_create_event(&dioq->event);
- dioq->adp = adp;
- dioq->data_rel_cb = cb;
- dioq->cb_context = cbctx;
- *dioq_hnd = dioq;
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_delete_dioq - Delete Generic DIO queue
- * @adp: Adapter instance
- * @dioq: DIOQ instance..
- *
- * Return:
- * None.
- *
- * Release Generic DIO queue. This function will remove
- * all the entries from the Queue and will release data
- * by calling the call back provided during creation.
- *
- */
-void crystalhd_delete_dioq(struct crystalhd_adp *adp,
- struct crystalhd_dioq *dioq)
-{
- void *temp;
-
- if (!dioq || (dioq->sig != BC_LINK_DIOQ_SIG))
- return;
-
- do {
- temp = crystalhd_dioq_fetch(dioq);
- if (temp && dioq->data_rel_cb)
- dioq->data_rel_cb(dioq->cb_context, temp);
- } while (temp);
- dioq->sig = 0;
- kfree(dioq);
-}
-
-/**
- * crystalhd_dioq_add - Add new DIO request element.
- * @ioq: DIO queue instance
- * @t: DIO request to be added.
- * @wake: True - Wake up suspended process.
- * @tag: Special tag to assign - For search and get.
- *
- * Return:
- * Status.
- *
- * Insert new element to Q tail.
- */
-enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq, void *data,
- bool wake, uint32_t tag)
-{
- unsigned long flags = 0;
- struct crystalhd_elem *tmp;
-
- if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) {
- BCMLOG_ERR("Invalid arg!!\n");
- return BC_STS_INV_ARG;
- }
-
- tmp = crystalhd_alloc_elem(ioq->adp);
- if (!tmp) {
- BCMLOG_ERR("No free elements.\n");
- return BC_STS_INSUFF_RES;
- }
-
- tmp->data = data;
- tmp->tag = tag;
- spin_lock_irqsave(&ioq->lock, flags);
- tmp->flink = (struct crystalhd_elem *)&ioq->head;
- tmp->blink = ioq->tail;
- tmp->flink->blink = tmp;
- tmp->blink->flink = tmp;
- ioq->count++;
- spin_unlock_irqrestore(&ioq->lock, flags);
-
- if (wake)
- crystalhd_set_event(&ioq->event);
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_dioq_fetch - Fetch element from head.
- * @ioq: DIO queue instance
- *
- * Return:
- * data element from the head..
- *
- * Remove an element from Queue.
- */
-void *crystalhd_dioq_fetch(struct crystalhd_dioq *ioq)
-{
- unsigned long flags = 0;
- struct crystalhd_elem *tmp;
- struct crystalhd_elem *ret = NULL;
- void *data = NULL;
-
- if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
- BCMLOG_ERR("Invalid arg!!\n");
- return data;
- }
-
- spin_lock_irqsave(&ioq->lock, flags);
- tmp = ioq->head;
- if (tmp != (struct crystalhd_elem *)&ioq->head) {
- ret = tmp;
- tmp->flink->blink = tmp->blink;
- tmp->blink->flink = tmp->flink;
- ioq->count--;
- }
- spin_unlock_irqrestore(&ioq->lock, flags);
- if (ret) {
- data = ret->data;
- crystalhd_free_elem(ioq->adp, ret);
- }
-
- return data;
-}
-/**
- * crystalhd_dioq_find_and_fetch - Search the tag and Fetch element
- * @ioq: DIO queue instance
- * @tag: Tag to search for.
- *
- * Return:
- * element from the head..
- *
- * Search TAG and remove the element.
- */
-void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq, uint32_t tag)
-{
- unsigned long flags = 0;
- struct crystalhd_elem *tmp;
- struct crystalhd_elem *ret = NULL;
- void *data = NULL;
-
- if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
- BCMLOG_ERR("Invalid arg!!\n");
- return data;
- }
-
- spin_lock_irqsave(&ioq->lock, flags);
- tmp = ioq->head;
- while (tmp != (struct crystalhd_elem *)&ioq->head) {
- if (tmp->tag == tag) {
- ret = tmp;
- tmp->flink->blink = tmp->blink;
- tmp->blink->flink = tmp->flink;
- ioq->count--;
- break;
- }
- tmp = tmp->flink;
- }
- spin_unlock_irqrestore(&ioq->lock, flags);
-
- if (ret) {
- data = ret->data;
- crystalhd_free_elem(ioq->adp, ret);
- }
-
- return data;
-}
-
-/**
- * crystalhd_dioq_fetch_wait - Fetch element from Head.
- * @ioq: DIO queue instance
- * @to_secs: Wait timeout in seconds..
- *
- * Return:
- * element from the head..
- *
- * Return element from head if Q is not empty. Wait for new element
- * if Q is empty for Timeout seconds.
- */
-void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq, uint32_t to_secs,
- uint32_t *sig_pend)
-{
- unsigned long flags = 0;
- int rc = 0, count;
- void *tmp = NULL;
-
- if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !to_secs || !sig_pend) {
- BCMLOG_ERR("Invalid arg!!\n");
- return tmp;
- }
-
- count = to_secs;
- spin_lock_irqsave(&ioq->lock, flags);
- while ((ioq->count == 0) && count) {
- spin_unlock_irqrestore(&ioq->lock, flags);
-
- crystalhd_wait_on_event(&ioq->event,
- (ioq->count > 0), 1000, rc, 0);
- if (rc == 0) {
- goto out;
- } else if (rc == -EINTR) {
- BCMLOG(BCMLOG_INFO, "Cancelling fetch wait\n");
- *sig_pend = 1;
- return tmp;
- }
- spin_lock_irqsave(&ioq->lock, flags);
- count--;
- }
- spin_unlock_irqrestore(&ioq->lock, flags);
-
-out:
- return crystalhd_dioq_fetch(ioq);
-}
-
-/**
- * crystalhd_map_dio - Map user address for DMA
- * @adp: Adapter instance
- * @ubuff: User buffer to map.
- * @ubuff_sz: User buffer size.
- * @uv_offset: UV buffer offset.
- * @en_422mode: TRUE:422 FALSE:420 Capture mode.
- * @dir_tx: TRUE for Tx (To device from host)
- * @dio_hnd: Handle to mapped DIO request.
- *
- * Return:
- * Status.
- *
- * This routine maps user address and lock pages for DMA.
- *
- */
-enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff,
- uint32_t ubuff_sz, uint32_t uv_offset,
- bool en_422mode, bool dir_tx,
- struct crystalhd_dio_req **dio_hnd)
-{
- struct crystalhd_dio_req *dio;
- /* FIXME: jarod: should some of these
- unsigned longs be uint32_t or uintptr_t? */
- unsigned long start = 0, end = 0, uaddr = 0, count = 0;
- unsigned long spsz = 0, uv_start = 0;
- int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0;
-
- if (!adp || !ubuff || !ubuff_sz || !dio_hnd) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
- /* Compute pages */
- uaddr = (unsigned long)ubuff;
- count = (unsigned long)ubuff_sz;
- end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
- start = uaddr >> PAGE_SHIFT;
- nr_pages = end - start;
-
- if (!count || ((uaddr + count) < uaddr)) {
- BCMLOG_ERR("User addr overflow!!\n");
- return BC_STS_INV_ARG;
- }
-
- dio = crystalhd_alloc_dio(adp);
- if (!dio) {
- BCMLOG_ERR("dio pool empty..\n");
- return BC_STS_INSUFF_RES;
- }
-
- if (dir_tx) {
- rw = WRITE;
- dio->direction = DMA_TO_DEVICE;
- } else {
- rw = READ;
- dio->direction = DMA_FROM_DEVICE;
- }
-
- if (nr_pages > dio->max_pages) {
- BCMLOG_ERR("max_pages(%d) exceeded(%d)!!\n",
- dio->max_pages, nr_pages);
- crystalhd_unmap_dio(adp, dio);
- return BC_STS_INSUFF_RES;
- }
-
- if (uv_offset) {
- uv_start = (uaddr + (unsigned long)uv_offset) >> PAGE_SHIFT;
- dio->uinfo.uv_sg_ix = uv_start - start;
- dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) &
- ~PAGE_MASK);
- }
-
- dio->fb_size = ubuff_sz & 0x03;
- if (dio->fb_size) {
- res = copy_from_user(dio->fb_va,
- (void __user *)(uaddr + count - dio->fb_size),
- dio->fb_size);
- if (res) {
- BCMLOG_ERR("failed %d to copy %u fill bytes from %p\n",
- res, dio->fb_size,
- (void *)(uaddr + count-dio->fb_size));
- crystalhd_unmap_dio(adp, dio);
- return BC_STS_INSUFF_RES;
- }
- }
-
- down_read(&current->mm->mmap_sem);
- res = get_user_pages(current, current->mm, uaddr, nr_pages, rw == READ,
- 0, dio->pages, NULL);
- up_read(&current->mm->mmap_sem);
-
- /* Save for release..*/
- dio->sig = crystalhd_dio_locked;
- if (res < nr_pages) {
- BCMLOG_ERR("get pages failed: %d-%d\n", nr_pages, res);
- dio->page_cnt = res;
- crystalhd_unmap_dio(adp, dio);
- return BC_STS_ERROR;
- }
-
- dio->page_cnt = nr_pages;
- /* Get scatter/gather */
- crystalhd_init_sg(dio->sg, dio->page_cnt);
- crystalhd_set_sg(&dio->sg[0], dio->pages[0], 0, uaddr & ~PAGE_MASK);
- if (nr_pages > 1) {
- dio->sg[0].length = PAGE_SIZE - dio->sg[0].offset;
-
-#ifdef CONFIG_X86_64
- dio->sg[0].dma_length = dio->sg[0].length;
-#endif
- count -= dio->sg[0].length;
- for (i = 1; i < nr_pages; i++) {
- if (count < 4) {
- spsz = count;
- skip_fb_sg = 1;
- } else {
- spsz = (count < PAGE_SIZE) ?
- (count & ~0x03) : PAGE_SIZE;
- }
- crystalhd_set_sg(&dio->sg[i], dio->pages[i], spsz, 0);
- count -= spsz;
- }
- } else {
- if (count < 4) {
- dio->sg[0].length = count;
- skip_fb_sg = 1;
- } else {
- dio->sg[0].length = count - dio->fb_size;
- }
-#ifdef CONFIG_X86_64
- dio->sg[0].dma_length = dio->sg[0].length;
-#endif
- }
- dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg,
- dio->page_cnt, dio->direction);
- if (dio->sg_cnt <= 0) {
- BCMLOG_ERR("sg map %d-%d\n", dio->sg_cnt, dio->page_cnt);
- crystalhd_unmap_dio(adp, dio);
- return BC_STS_ERROR;
- }
- if (dio->sg_cnt && skip_fb_sg)
- dio->sg_cnt -= 1;
- dio->sig = crystalhd_dio_sg_mapped;
- /* Fill in User info.. */
- dio->uinfo.xfr_len = ubuff_sz;
- dio->uinfo.xfr_buff = ubuff;
- dio->uinfo.uv_offset = uv_offset;
- dio->uinfo.b422mode = en_422mode;
- dio->uinfo.dir_tx = dir_tx;
-
- *dio_hnd = dio;
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_unmap_sgl - Release mapped resources
- * @adp: Adapter instance
- * @dio: DIO request instance
- *
- * Return:
- * Status.
- *
- * This routine is to unmap the user buffer pages.
- */
-enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp,
- struct crystalhd_dio_req *dio)
-{
- struct page *page = NULL;
- int j = 0;
-
- if (!adp || !dio) {
- BCMLOG_ERR("Invalid arg\n");
- return BC_STS_INV_ARG;
- }
-
- if ((dio->page_cnt > 0) && (dio->sig != crystalhd_dio_inv)) {
- for (j = 0; j < dio->page_cnt; j++) {
- page = dio->pages[j];
- if (page) {
- if (!PageReserved(page) &&
- (dio->direction == DMA_FROM_DEVICE))
- SetPageDirty(page);
- page_cache_release(page);
- }
- }
- }
- if (dio->sig == crystalhd_dio_sg_mapped)
- pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt,
- dio->direction);
-
- crystalhd_free_dio(adp, dio);
-
- return BC_STS_SUCCESS;
-}
-
-/**
- * crystalhd_create_dio_pool - Allocate mem pool for DIO management.
- * @adp: Adapter instance
- * @max_pages: Max pages for size calculation.
- *
- * Return:
- * system error.
- *
- * This routine creates a memory pool to hold dio context for
- * for HW Direct IO operation.
- */
-int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages)
-{
- uint32_t asz = 0, i = 0;
- uint8_t *temp;
- struct crystalhd_dio_req *dio;
-
- if (!adp || !max_pages) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return -EINVAL;
- }
-
- /* Get dma memory for fill byte handling..*/
- adp->fill_byte_pool = pci_pool_create("crystalhd_fbyte",
- adp->pdev, 8, 8, 0);
- if (!adp->fill_byte_pool) {
- BCMLOG_ERR("failed to create fill byte pool\n");
- return -ENOMEM;
- }
-
- /* Get the max size from user based on 420/422 modes */
- asz = (sizeof(*dio->pages) * max_pages) +
- (sizeof(*dio->sg) * max_pages) + sizeof(*dio);
-
- BCMLOG(BCMLOG_DBG, "Initializing Dio pool %d %d %x %p\n",
- BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool);
-
- for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) {
- temp = kzalloc(asz, GFP_KERNEL);
- if ((temp) == NULL) {
- BCMLOG_ERR("Failed to alloc %d mem\n", asz);
- return -ENOMEM;
- }
-
- dio = (struct crystalhd_dio_req *)temp;
- temp += sizeof(*dio);
- dio->pages = (struct page **)temp;
- temp += (sizeof(*dio->pages) * max_pages);
- dio->sg = (struct scatterlist *)temp;
- dio->max_pages = max_pages;
- dio->fb_va = pci_pool_alloc(adp->fill_byte_pool, GFP_KERNEL,
- &dio->fb_pa);
- if (!dio->fb_va) {
- BCMLOG_ERR("fill byte alloc failed.\n");
- return -ENOMEM;
- }
-
- crystalhd_free_dio(adp, dio);
- }
-
- return 0;
-}
-
-/**
- * crystalhd_destroy_dio_pool - Release DIO mem pool.
- * @adp: Adapter instance
- *
- * Return:
- * none.
- *
- * This routine releases dio memory pool during close.
- */
-void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp)
-{
- struct crystalhd_dio_req *dio;
- int count = 0;
-
- if (!adp) {
- BCMLOG_ERR("Invalid Arg!!\n");
- return;
- }
-
- do {
- dio = crystalhd_alloc_dio(adp);
- if (dio) {
- if (dio->fb_va)
- pci_pool_free(adp->fill_byte_pool,
- dio->fb_va, dio->fb_pa);
- count++;
- kfree(dio);
- }
- } while (dio);
-
- if (adp->fill_byte_pool) {
- pci_pool_destroy(adp->fill_byte_pool);
- adp->fill_byte_pool = NULL;
- }
-
- BCMLOG(BCMLOG_DBG, "Released dio pool %d\n", count);
-}
-
-/**
- * crystalhd_create_elem_pool - List element pool creation.
- * @adp: Adapter instance
- * @pool_size: Number of elements in the pool.
- *
- * Return:
- * 0 - success, <0 error
- *
- * Create general purpose list element pool to hold pending,
- * and active requests.
- */
-int crystalhd_create_elem_pool(struct crystalhd_adp *adp,
- uint32_t pool_size)
-{
- uint32_t i;
- struct crystalhd_elem *temp;
-
- if (!adp || !pool_size)
- return -EINVAL;
-
- for (i = 0; i < pool_size; i++) {
- temp = kzalloc(sizeof(*temp), GFP_KERNEL);
- if (!temp) {
- BCMLOG_ERR("kalloc failed\n");
- return -ENOMEM;
- }
- crystalhd_free_elem(adp, temp);
- }
- BCMLOG(BCMLOG_DBG, "allocated %d elem\n", pool_size);
- return 0;
-}
-
-/**
- * crystalhd_delete_elem_pool - List element pool deletion.
- * @adp: Adapter instance
- *
- * Return:
- * none
- *
- * Delete general purpose list element pool.
- */
-void crystalhd_delete_elem_pool(struct crystalhd_adp *adp)
-{
- struct crystalhd_elem *temp;
- int dbg_cnt = 0;
-
- if (!adp)
- return;
-
- do {
- temp = crystalhd_alloc_elem(adp);
- if (temp) {
- kfree(temp);
- dbg_cnt++;
- }
- } while (temp);
-
- BCMLOG(BCMLOG_DBG, "released %d elem\n", dbg_cnt);
-}
-
-/*================ Debug support routines.. ================================*/
-void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount)
-{
- uint32_t i, k = 1;
-
- for (i = 0; i < dwcount; i++) {
- if (k == 1)
- BCMLOG(BCMLOG_DATA, "0x%08X : ", off);
-
- BCMLOG(BCMLOG_DATA, " 0x%08X ", *((uint32_t *)buff));
-
- buff += sizeof(uint32_t);
- off += sizeof(uint32_t);
- k++;
- if ((i == dwcount - 1) || (k > 4)) {
- BCMLOG(BCMLOG_DATA, "\n");
- k = 1;
- }
- }
-}
diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h
deleted file mode 100644
index 0f63827acfb4..000000000000
--- a/drivers/staging/crystalhd/crystalhd_misc.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2005-2009, Broadcom Corporation.
- *
- * Name: crystalhd_misc . h
- *
- * Description:
- * BCM70012 Linux driver general purpose routines.
- * Includes reg/mem read and write routines.
- *
- * HISTORY:
- *
- **********************************************************************
- * This file is part of the crystalhd device driver.
- *
- * This driver 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 of the License.
- *
- * This driver 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 driver. If not, see <http://www.gnu.org/licenses/>.
- **********************************************************************/
-
-#ifndef _CRYSTALHD_MISC_H_
-#define _CRYSTALHD_MISC_H_
-
-#include "crystalhd.h"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioctl.h>
-#include <linux/dma-mapping.h>
-#include <linux/sched.h>
-#include "bc_dts_glob_lnx.h"
-
-/* Global log level variable defined in crystal_misc.c file */
-extern uint32_t g_linklog_level;
-
-/* Global element pool for all Queue management.
- * TX: Active = BC_TX_LIST_CNT, Free = BC_TX_LIST_CNT.
- * RX: Free = BC_RX_LIST_CNT, Active = 2
- * FW-CMD: 4
- */
-#define BC_LINK_ELEM_POOL_SZ ((BC_TX_LIST_CNT * 2) + BC_RX_LIST_CNT + 2 + 4)
-
-/* Driver's IODATA pool count */
-#define CHD_IODATA_POOL_SZ (BC_IOCTL_DATA_POOL_SIZE * BC_LINK_MAX_OPENS)
-
-/* Scatter Gather memory pool size for Tx and Rx */
-#define BC_LINK_SG_POOL_SZ (BC_TX_LIST_CNT + BC_RX_LIST_CNT)
-
-enum crystalhd_dio_sig {
- crystalhd_dio_inv = 0,
- crystalhd_dio_locked,
- crystalhd_dio_sg_mapped,
-};
-
-struct crystalhd_dio_user_info {
- void *xfr_buff;
- uint32_t xfr_len;
- uint32_t uv_offset;
- bool dir_tx;
-
- uint32_t uv_sg_ix;
- uint32_t uv_sg_off;
- int comp_sts;
- int ev_sts;
- uint32_t y_done_sz;
- uint32_t uv_done_sz;
- uint32_t comp_flags;
- bool b422mode;
-};
-
-struct crystalhd_dio_req {
- uint32_t sig;
- uint32_t max_pages;
- struct page **pages;
- struct scatterlist *sg;
- int sg_cnt;
- int page_cnt;
- int direction;
- struct crystalhd_dio_user_info uinfo;
- void *fb_va;
- uint32_t fb_size;
- dma_addr_t fb_pa;
- struct crystalhd_dio_req *next;
-};
-
-#define BC_LINK_DIOQ_SIG (0x09223280)
-
-struct crystalhd_elem {
- struct crystalhd_elem *flink;
- struct crystalhd_elem *blink;
- void *data;
- uint32_t tag;
-};
-
-typedef void (*crystalhd_data_free_cb)(void *context, void *data);
-
-struct crystalhd_dioq {
- uint32_t sig;
- struct crystalhd_adp *adp;
- struct crystalhd_elem *head;
- struct crystalhd_elem *tail;
- uint32_t count;
- spinlock_t lock;
- wait_queue_head_t event;
- crystalhd_data_free_cb data_rel_cb;
- void *cb_context;
-};
-
-typedef void (*hw_comp_callback)(struct crystalhd_dio_req *,
- wait_queue_head_t *event, enum BC_STATUS sts);
-
-/*========= Decoder (7412) register access routines.================= */
-uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t);
-void bc_dec_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
-
-/*========= Link (70012) register access routines.. =================*/
-uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t);
-void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
-
-/*========= Decoder (7412) memory access routines..=================*/
-enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *,
- uint32_t, uint32_t, uint32_t *);
-enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *,
- uint32_t, uint32_t, uint32_t *);
-
-/*==========Link (70012) PCIe Config access routines.================*/
-enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *,
- uint32_t, uint32_t, uint32_t *);
-enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *,
- uint32_t, uint32_t, uint32_t);
-
-/*========= Linux Kernel Interface routines. ======================= */
-void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *);
-void bc_kern_dma_free(struct crystalhd_adp *, uint32_t,
- void *, dma_addr_t);
-#define crystalhd_create_event(_ev) init_waitqueue_head(_ev)
-#define crystalhd_set_event(_ev) wake_up_interruptible(_ev)
-#define crystalhd_wait_on_event(ev, condition, timeout, ret, nosig) \
-do { \
- DECLARE_WAITQUEUE(entry, current); \
- unsigned long end = jiffies + ((timeout * HZ) / 1000); \
- ret = 0; \
- add_wait_queue(ev, &entry); \
- for (;;) { \
- __set_current_state(TASK_INTERRUPTIBLE); \
- if (condition) { \
- break; \
- } \
- if (time_after_eq(jiffies, end)) { \
- ret = -EBUSY; \
- break; \
- } \
- schedule_timeout((HZ / 100 > 1) ? HZ / 100 : 1); \
- if (!nosig && signal_pending(current)) { \
- ret = -EINTR; \
- break; \
- } \
- } \
- __set_current_state(TASK_RUNNING); \
- remove_wait_queue(ev, &entry); \
-} while (0)
-
-/*================ Direct IO mapping routines ==================*/
-extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t);
-extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *);
-extern enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *,
- uint32_t, uint32_t, bool, bool, struct crystalhd_dio_req**);
-
-extern enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *,
- struct crystalhd_dio_req*);
-#define crystalhd_get_sgle_paddr(_dio, _ix) (sg_dma_address(&_dio->sg[_ix]))
-#define crystalhd_get_sgle_len(_dio, _ix) (sg_dma_len(&_dio->sg[_ix]))
-
-/*================ General Purpose Queues ==================*/
-extern enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *,
- struct crystalhd_dioq **, crystalhd_data_free_cb , void *);
-extern void crystalhd_delete_dioq(struct crystalhd_adp *,
- struct crystalhd_dioq *);
-extern enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq,
- void *data, bool wake, uint32_t tag);
-extern void *crystalhd_dioq_fetch(struct crystalhd_dioq *ioq);
-extern void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq,
- uint32_t tag);
-extern void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq,
- uint32_t to_secs, uint32_t *sig_pend);
-
-#define crystalhd_dioq_count(_ioq) ((_ioq) ? _ioq->count : 0)
-
-extern int crystalhd_create_elem_pool(struct crystalhd_adp *, uint32_t);
-extern void crystalhd_delete_elem_pool(struct crystalhd_adp *);
-
-
-/*================ Debug routines/macros .. ================================*/
-extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff,
- uint32_t dwcount);
-
-enum _chd_log_levels {
- BCMLOG_ERROR = 0x80000000, /* Don't disable this option */
- BCMLOG_DATA = 0x40000000, /* Data, enable by default */
- BCMLOG_SPINLOCK = 0x20000000, /* Special case for Spin locks*/
-
- /* Following are allowed only in debug mode */
- BCMLOG_INFO = 0x00000001, /* Generic informational */
- BCMLOG_DBG = 0x00000002, /* First level Debug info */
- BCMLOG_SSTEP = 0x00000004, /* Stepping information */
-};
-
-
-#define BCMLOG(trace, fmt, args...) \
-do { \
- if (g_linklog_level & trace) \
- printk(fmt, ##args); \
-} while (0)
-
-
-#define BCMLOG_ERR(fmt, args...) \
-do { \
- if (g_linklog_level & BCMLOG_ERROR) \
- pr_err("*ERR*:%s:%d: "fmt, \
- __FILE__, __LINE__, ##args); \
-} while (0)
-
-#endif
diff --git a/drivers/staging/cxt1e1/Kconfig b/drivers/staging/cxt1e1/Kconfig
deleted file mode 100644
index 947f42a65c59..000000000000
--- a/drivers/staging/cxt1e1/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
-config CXT1E1
- tristate "SBE wanPMC-C[421]E1T1 hardware support"
- depends on HDLC && PCI
- ---help---
- This driver supports the SBE wanPMC-CxT1E1 1, 2 and 4 port T3
- channelized stream WAN adapter card which contains a HDLC/Transparent
- mode controller.
-
- If you want to compile this driver as a module say M here.
- The module will be called 'cxt1e1'.
-
- If unsure, say N.
-
-config SBE_PMCC4_NCOMM
- bool "SBE PMCC4 NCOMM support"
- depends on CXT1E1
- ---help---
- SBE supplies optional support for NCOMM products.
-
- If you have purchased this optional support you must say Y
- here to allow the driver to operate with the NCOMM product.
diff --git a/drivers/staging/cxt1e1/Makefile b/drivers/staging/cxt1e1/Makefile
deleted file mode 100644
index b879e7b553c2..000000000000
--- a/drivers/staging/cxt1e1/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-obj-$(CONFIG_CXT1E1) += cxt1e1.o
-
-ccflags-y := -DSBE_PMCC4_ENABLE
-ccflags-y += -DSBE_ISR_TASKLET
-
-cxt1e1-y := \
- musycc.o \
- pmcc4_drv.o \
- comet.o \
- linux.o \
- functions.o \
- hwprobe.o \
- pmc93x6_eeprom.o \
- sbecrc.o \
- comet_tables.o \
- sbeid.o
-
-cxt1e1-$(CONFIG_PROC_FS) += sbeproc.o
diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c
deleted file mode 100644
index 7005ad022339..000000000000
--- a/drivers/staging/cxt1e1/comet.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/* Copyright (C) 2003-2005 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/io.h>
-#include <linux/hdlc.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4.h"
-#include "comet.h"
-#include "comet_tables.h"
-
-
-#define COMET_NUM_SAMPLES 24 /* Number of entries in the waveform table */
-#define COMET_NUM_UNITS 5 /* Number of points per entry in table */
-
-/* forward references */
-static void SetPwrLevel(struct s_comet_reg *comet);
-static void WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet,
- u_int32_t *table);
-static void WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet,
- u_int8_t table[COMET_NUM_SAMPLES]
- [COMET_NUM_UNITS]);
-
-
-static void *TWV_table[12] = {
- TWVLongHaul0DB, TWVLongHaul7_5DB, TWVLongHaul15DB, TWVLongHaul22_5DB,
- TWVShortHaul0, TWVShortHaul1, TWVShortHaul2, TWVShortHaul3,
- TWVShortHaul4, TWVShortHaul5,
- /** PORT POINT - 75 Ohm not supported **/
- TWV_E1_75Ohm,
- TWV_E1_120Ohm
-};
-
-
-static int
-lbo_tbl_lkup(int t1, int lbo) {
- /* error switches to default */
- if ((lbo < CFG_LBO_LH0) || (lbo > CFG_LBO_E120)) {
- if (t1)
- /* default T1 waveform table */
- lbo = CFG_LBO_LH0;
-
- else
- /* default E1 waveform table */
- lbo = CFG_LBO_E120;
- }
- /* make index ZERO relative */
- return lbo - 1;
-}
-
-void init_comet(void *ci, struct s_comet_reg *comet, u_int32_t port_mode,
- int clockmaster, u_int8_t moreParams)
-{
- u_int8_t isT1mode;
- /* T1 default */
- u_int8_t tix = CFG_LBO_LH0;
- isT1mode = IS_FRAME_ANY_T1(port_mode);
- /* T1 or E1 */
- if (isT1mode) {
- /* Select T1 Mode & PIO output enabled */
- pci_write_32((u_int32_t *) &comet->gbl_cfg, 0xa0);
- /* default T1 waveform table */
- tix = lbo_tbl_lkup(isT1mode, CFG_LBO_LH0);
- } else {
- /* Select E1 Mode & PIO output enabled */
- pci_write_32((u_int32_t *) &comet->gbl_cfg, 0x81);
- /* default E1 waveform table */
- tix = lbo_tbl_lkup(isT1mode, CFG_LBO_E120);
- }
-
- if (moreParams & CFG_LBO_MASK)
- /* dial-in requested waveform table */
- tix = lbo_tbl_lkup(isT1mode, moreParams & CFG_LBO_MASK);
- /* Tx line Intfc cfg Set for analog & no special patterns */
- /* Transmit Line Interface Config. */
- pci_write_32((u_int32_t *) &comet->tx_line_cfg, 0x00);
- /* master test Ignore Test settings for now */
- /* making sure it's Default value */
- pci_write_32((u_int32_t *) &comet->mtest, 0x00);
- /* Turn on Center (CENT) and everything else off */
- /* RJAT cfg */
- pci_write_32((u_int32_t *) &comet->rjat_cfg, 0x10);
- /* Set Jitter Attenuation to recommend T1 values */
- if (isT1mode) {
- /* RJAT Divider N1 Control */
- pci_write_32((u_int32_t *) &comet->rjat_n1clk, 0x2F);
- /* RJAT Divider N2 Control */
- pci_write_32((u_int32_t *) &comet->rjat_n2clk, 0x2F);
- } else {
- /* RJAT Divider N1 Control */
- pci_write_32((u_int32_t *) &comet->rjat_n1clk, 0xFF);
- /* RJAT Divider N2 Control */
- pci_write_32((u_int32_t *) &comet->rjat_n2clk, 0xFF);
- }
-
- /* Turn on Center (CENT) and everything else off */
- /* TJAT Config. */
- pci_write_32((u_int32_t *) &comet->tjat_cfg, 0x10);
-
- /* Do not bypass jitter attenuation and bypass elastic store */
- /* rx opts */
- pci_write_32((u_int32_t *) &comet->rx_opt, 0x00);
-
- /* TJAT ctrl & TJAT divider ctrl */
- /* Set Jitter Attenuation to recommended T1 values */
- if (isT1mode) {
- /* TJAT Divider N1 Control */
- pci_write_32((u_int32_t *) &comet->tjat_n1clk, 0x2F);
- /* TJAT Divider N2 Control */
- pci_write_32((u_int32_t *) &comet->tjat_n2clk, 0x2F);
- } else {
- /* TJAT Divider N1 Control */
- pci_write_32((u_int32_t *) &comet->tjat_n1clk, 0xFF);
- /* TJAT Divider N2 Control */
- pci_write_32((u_int32_t *) &comet->tjat_n2clk, 0xFF);
- }
-
- /* 1c: rx ELST cfg 20: tx ELST cfg 28&38: rx&tx data link ctrl */
-
- /* Select 193-bit frame format */
- if (isT1mode) {
- pci_write_32((u_int32_t *) &comet->rx_elst_cfg, 0x00);
- pci_write_32((u_int32_t *) &comet->tx_elst_cfg, 0x00);
- } else {
- /* Select 256-bit frame format */
- pci_write_32((u_int32_t *) &comet->rx_elst_cfg, 0x03);
- pci_write_32((u_int32_t *) &comet->tx_elst_cfg, 0x03);
- /* disable T1 data link receive */
- pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x00);
- /* disable T1 data link transmit */
- pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x00);
- }
-
- /* the following is a default value */
- /* Enable 8 out of 10 validation */
- /* t1RBOC enable(BOC:BitOriented Code) */
- pci_write_32((u_int32_t *) &comet->t1_rboc_ena, 0x00);
- if (isT1mode) {
- /* IBCD cfg: aka Inband Code Detection ** loopback code length
- * set to
- */
- /* 6 bit down, 5 bit up (assert) */
- pci_write_32((u_int32_t *) &comet->ibcd_cfg, 0x04);
- /* line loopback activate pattern */
- pci_write_32((u_int32_t *) &comet->ibcd_act, 0x08);
- /* deactivate code pattern (i.e.001) */
- pci_write_32((u_int32_t *) &comet->ibcd_deact, 0x24);
- }
- /* 10: CDRC cfg 28&38: rx&tx data link 1 ctrl 48: t1 frmr cfg */
- /* 50: SIGX cfg, COSS (change of signaling state) 54: XBAS cfg */
- /* 60: t1 ALMI cfg */
- /* Configure Line Coding */
-
- switch (port_mode) {
- /* 1 - T1 B8ZS */
- case CFG_FRAME_SF:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- /* 5:B8ZS */
- pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x20);
- pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0);
- break;
- /* 2 - T1 B8ZS */
- case CFG_FRAME_ESF:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- /* Bit 5: T1 DataLink Enable */
- pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x20);
- /* 5: T1 DataLink Enable */
- pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x20);
- /* 4:ESF 5:ESFFA */
- pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0x30);
- /* 2:ESF */
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0x04);
- /* 4:ESF 5:B8ZS */
- pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x30);
- /* 4:ESF */
- pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0x10);
- break;
- /* 3 - HDB3 */
- case CFG_FRAME_E1PLAIN:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
- break;
- /* 4 - HDB3 */
- case CFG_FRAME_E1CAS:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x60);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0);
- break;
- /* 5 - HDB3 */
- case CFG_FRAME_E1CRC:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x10);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
- break;
- /* 6 - HDB3 */
- case CFG_FRAME_E1CRC_CAS:
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x70);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
- break;
- /* 7 - T1 AMI */
- case CFG_FRAME_SF_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0);
- pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0);
- pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- break;
- /* 8 - T1 AMI */
- case CFG_FRAME_ESF_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- /* 5: T1 DataLink Enable */
- pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x20);
- /* 5: T1 DataLink Enable */
- pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x20);
- /* Bit 4:ESF 5:ESFFA */
- pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0x30);
- /* 2:ESF */
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0x04);
- /* 4:ESF */
- pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x10);
- /* 4:ESF */
- pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0x10);
- break;
- /* 9 - AMI */
- case CFG_FRAME_E1PLAIN_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
- break;
- /* 10 - AMI */
- case CFG_FRAME_E1CAS_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0xe0);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0);
- break;
- /* 11 - AMI */
- case CFG_FRAME_E1CRC_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x90);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
- break;
- /* 12 - AMI */
- case CFG_FRAME_E1CRC_CAS_AMI:
- /* Enable AMI Line Decoding */
- pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
- pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
- pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0xf0);
- pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
- break;
- } /* end switch */
-
- /***
- * Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0)
- * CMODE=1: Clock slave mode with BRCLK as an input,
- * DE=0: Use falling edge of BRCLK for data,
- * FE=0: Use falling edge of BRCLK for frame,
- * CMS=0: Use backplane freq,
- * RATE[1:0]=0,0: T1
- ***/
-
-
- /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */
- /* note "rate bits can only be set once after reset" */
- if (clockmaster) {
- /* CMODE == clockMode, 0=clock master
- * (so all 3 others should be slave)
- */
- /* rate = 1.544 Mb/s */
- if (isT1mode)
- /* Comet 0 Master Mode(CMODE=0) */
- pci_write_32((u_int32_t *) &comet->brif_cfg, 0x00);
- /* rate = 2.048 Mb/s */
- else
- /* Comet 0 Master Mode(CMODE=0) */
- pci_write_32((u_int32_t *) &comet->brif_cfg, 0x01);
-
- /* 31: BRIF frame pulse cfg 06: tx timing options */
-
- /* Master Mode i.e.FPMODE=0 (@0x20) */
- pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x00);
- if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) {
- if (cxt1e1_log_level >= LOG_SBEBUG12)
- pr_info(">> %s: clockmaster internal clock\n",
- __func__);
- /* internal oscillator */
- pci_write_32((u_int32_t *) &comet->tx_time, 0x0d);
- } else {
- /* external clock source */
- if (cxt1e1_log_level >= LOG_SBEBUG12)
- pr_info(">> %s: clockmaster external clock\n",
- __func__);
- /* loop timing(external) */
- pci_write_32((u_int32_t *) &comet->tx_time, 0x09);
- }
-
- } else {
- /* slave */
- if (isT1mode)
- /* Slave Mode(CMODE=1, see above) */
- pci_write_32((u_int32_t *) &comet->brif_cfg, 0x20);
- else
- /* Slave Mode(CMODE=1)*/
- pci_write_32((u_int32_t *) &comet->brif_cfg, 0x21);
- /* Slave Mode i.e. FPMODE=1 (@0x20) */
- pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x20);
- if (cxt1e1_log_level >= LOG_SBEBUG12)
- pr_info(">> %s: clockslave internal clock\n", __func__);
- /* oscillator timing */
- pci_write_32((u_int32_t *) &comet->tx_time, 0x0d);
- }
-
- /* 32: BRIF parity F-bit cfg */
- /* Totem-pole operation */
- /* Receive Backplane Parity/F-bit */
- pci_write_32((u_int32_t *) &comet->brif_pfcfg, 0x01);
-
- /* dc: RLPS equalizer V ref */
- /* Configuration */
- if (isT1mode)
- /* RLPS Equalizer Voltage */
- pci_write_32((u_int32_t *) &comet->rlps_eqvr, 0x2c);
- else
- /* RLPS Equalizer Voltage */
- pci_write_32((u_int32_t *) &comet->rlps_eqvr, 0x34);
-
- /* Reserved bit set and SQUELCH enabled */
- /* f8: RLPS cfg & status f9: RLPS ALOS detect/clear threshold */
- /* RLPS Configuration Status */
- pci_write_32((u_int32_t *) &comet->rlps_cfgsts, 0x11);
- if (isT1mode)
- /* ? */
- pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x55);
- else
- /* ? */
- pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x22);
-
-
- /* Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0) */
- /* CMODE=0: Clock slave mode with BTCLK as an input, DE=1: Use rising */
- /* edge of BTCLK for data, FE=1: Use rising edge of BTCLK for frame, */
- /* CMS=0: Use backplane freq, RATE[1:0]=0,0: T1 */
- /*** Transmit side is always an Input, Slave Clock*/
- /* 40: BTIF cfg 41: loop timing(external) */
- /*BTIF frame pulse cfg */
- if (isT1mode)
- /* BTIF Configuration Reg. */
- pci_write_32((u_int32_t *) &comet->btif_cfg, 0x38);
- else
- /* BTIF Configuration Reg. */
- pci_write_32((u_int32_t *) &comet->btif_cfg, 0x39);
- /* BTIF Frame Pulse Config. */
- pci_write_32((u_int32_t *) &comet->btif_fpcfg, 0x01);
-
- /* 0a: master diag 06: tx timing options */
- /* if set Comet to loop back */
-
- /* Comets set to normal */
- pci_write_32((u_int32_t *) &comet->mdiag, 0x00);
-
- /* BTCLK driven by TCLKI internally (crystal driven) and Xmt Elasted */
- /* Store is enabled. */
-
- WrtXmtWaveformTbl(ci, comet, TWV_table[tix]);
- if (isT1mode)
- WrtRcvEqualizerTbl((ci_t *) ci, comet, &T1_Equalizer[0]);
- else
- WrtRcvEqualizerTbl((ci_t *) ci, comet, &E1_Equalizer[0]);
- SetPwrLevel(comet);
-}
-
-/*
-** Name: WrtXmtWaveform
-** Description: Formulate the Data for the Pulse Waveform Storage
-** Write register, (F2), from the sample and unit inputs.
-** Write the data to the Pulse Waveform Storage Data register.
-** Returns: Nothing
-*/
-static void
-WrtXmtWaveform(ci_t *ci, struct s_comet_reg *comet, u_int32_t sample,
- u_int32_t unit, u_int8_t data)
-{
- u_int8_t WaveformAddr;
-
- WaveformAddr = (sample << 3) + (unit & 7);
- pci_write_32((u_int32_t *) &comet->xlpg_pwave_addr, WaveformAddr);
- /* for write order preservation when Optimizing driver */
- pci_flush_write(ci);
- pci_write_32((u_int32_t *) &comet->xlpg_pwave_data, 0x7F & data);
-}
-
-/*
-** Name: WrtXmtWaveformTbl
-** Description: Fill in the Transmit Waveform Values
-** for driving the transmitter DAC.
-** Returns: Nothing
-*/
-static void
-WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet,
- u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS])
-{
- u_int32_t sample, unit;
-
- for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) {
- for (unit = 0; unit < COMET_NUM_UNITS; unit++)
- WrtXmtWaveform(ci, comet, sample, unit,
- table[sample][unit]);
- }
-
- /* Enable transmitter and set output amplitude */
- pci_write_32((u_int32_t *) &comet->xlpg_cfg,
- table[COMET_NUM_SAMPLES][0]);
-}
-
-
-/*
-** Name: WrtXmtWaveform
-** Description: Fill in the Receive Equalizer RAM from the desired
-** table.
-** Returns: Nothing
-**
-** Remarks: Per PM4351 Device Errata, Receive Equalizer RAM Initialization
-** is coded with early setup of indirect address.
-*/
-
-static void
-WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table)
-{
- u_int32_t ramaddr;
- u_int32_t value;
-
- for (ramaddr = 0; ramaddr < 256; ramaddr++) {
- /*** the following lines are per Errata 7, 2.5 ***/
- {
- /* Set up for a read operation */
- pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0x80);
- /* for write order preservation when Optimizing driver */
- pci_flush_write(ci);
- /* write the addr, initiate a read */
- pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr,
- (u_int8_t) ramaddr);
- /* for write order preservation when Optimizing driver */
- pci_flush_write(ci);
- /*
- * wait 3 line rate clock cycles to ensure address bits are
- * captured by T1/E1 clock
- */
-
- /* 683ns * 3 = 1366 ns, approx 2us (but use 4us) */
- OS_uwait(4, "wret");
- }
-
- value = *table++;
- pci_write_32((u_int32_t *) &comet->rlps_idata3,
- (u_int8_t) (value >> 24));
- pci_write_32((u_int32_t *) &comet->rlps_idata2,
- (u_int8_t) (value >> 16));
- pci_write_32((u_int32_t *) &comet->rlps_idata1,
- (u_int8_t) (value >> 8));
- pci_write_32((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value);
- /* for write order preservation when Optimizing driver */
- pci_flush_write(ci);
-
- /* Storing RAM address, causes RAM to be updated */
-
- /* Set up for a write operation */
- pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0);
- /* for write order preservation when optimizing driver */
- pci_flush_write(ci);
- /* write the addr, initiate a read */
- pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr,
- (u_int8_t) ramaddr);
- /* for write order preservation when optimizing driver */
- pci_flush_write(ci);
-
- /*
- * wait 3 line rate clock cycles to ensure address bits are captured
- * by T1/E1 clock
- */
- /* 683ns * 3 = 1366 ns, approx 2us (but use 4us) */
- OS_uwait(4, "wret");
- }
-
- /* Enable Equalizer & set it to use 256 periods */
- pci_write_32((u_int32_t *) &comet->rlps_eq_cfg, 0xCB);
-}
-
-
-/*
-** Name: SetPwrLevel
-** Description: Implement power level setting algorithm described below
-** Returns: Nothing
-*/
-
-static void
-SetPwrLevel(struct s_comet_reg *comet)
-{
- u_int32_t temp;
-
-/*
-** Algorithm to Balance the Power Distribution of Ttip Tring
-**
-** Zero register F6
-** Write 0x01 to register F4
-** Write another 0x01 to register F4
-** Read register F4
-** Remove the 0x01 bit by Anding register F4 with 0xFE
-** Write the resultant value to register F4
-** Repeat these steps for register F5
-** Write 0x01 to register F6
-*/
- /* XLPG Fuse Data Select */
- pci_write_32((u_int32_t *) &comet->xlpg_fdata_sel, 0x00);
- /* XLPG Analog Test Positive control */
- pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
- pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
- temp = pci_read_32((u_int32_t *) &comet->xlpg_atest_pctl) & 0xfe;
- pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, temp);
- pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
- pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
- /* XLPG Analog Test Negative control */
- temp = pci_read_32((u_int32_t *) &comet->xlpg_atest_nctl) & 0xfe;
- pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, temp);
- /* XLPG */
- pci_write_32((u_int32_t *) &comet->xlpg_fdata_sel, 0x01);
-}
-
-
-/*
-** Name: SetCometOps
-** Description: Set up the selected Comet's clock edge drive for both
-** the transmit out the analog side and receive to the
-** backplane side.
-** Returns: Nothing
-*/
-#if 0
-static void
-SetCometOps(struct s_comet_reg *comet)
-{
- u_int8_t rd_value;
-
- if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) {
- /* read the BRIF Configuration */
- rd_value = (u_int8_t) pci_read_32((u_int32_t *)
- &comet->brif_cfg);
- rd_value &= ~0x20;
- pci_write_32((u_int32_t *) &comet->brif_cfg,
- (u_int32_t) rd_value);
- /* read the BRIF Frame Pulse Configuration */
- rd_value = (u_int8_t) pci_read_32((u_int32_t *)
- &comet->brif_fpcfg);
- rd_value &= ~0x20;
- pci_write_32((u_int32_t *) &comet->brif_fpcfg,
- (u_int8_t) rd_value);
- } else {
- /* read the BRIF Configuration */
- rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg);
- rd_value |= 0x20;
- pci_write_32((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
- /* read the BRIF Frame Pulse Configuration */
- rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_fpcfg);
- rd_value |= 0x20;
- pci_write_32(u_int32_t *) & comet->brif_fpcfg, (u_int8_t) rd_value);
- }
-}
-#endif
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h
deleted file mode 100644
index d5d286e47a4b..000000000000
--- a/drivers/staging/cxt1e1/comet.h
+++ /dev/null
@@ -1,353 +0,0 @@
-#ifndef _INC_COMET_H_
-#define _INC_COMET_H_
-
-/*-----------------------------------------------------------------------------
- * comet.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-
-#define VINT32 volatile u_int32_t
-
-struct s_comet_reg {
- VINT32 gbl_cfg; /* 00 Global Cfg */
- VINT32 clkmon; /* 01 Clk Monitor */
- VINT32 rx_opt; /* 02 RX Options */
- VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */
- VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */
- VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */
- VINT32 tx_time; /* 06 TX Timing Options */
- VINT32 intr_1; /* 07 Intr Source #1 */
- VINT32 intr_2; /* 08 Intr Source #2 */
- VINT32 intr_3; /* 09 Intr Source #3 */
- VINT32 mdiag; /* 0A Master Diagnostics */
- VINT32 mtest; /* 0B Master Test */
- VINT32 adiag; /* 0C Analog Diagnostics */
- VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */
-#define pmon rev_id
- VINT32 reset; /* 0E Reset */
- VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */
- VINT32 cdrc_cfg; /* 10 CDRC Cfg */
- VINT32 cdrc_ien; /* 11 CDRC Intr Enable */
- VINT32 cdrc_ists; /* 12 CDRC Intr Sts */
- VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */
-
- VINT32 rjat_ists; /* 14 RJAT Intr Sts */
- VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */
- VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */
- VINT32 rjat_cfg; /* 17 RJAT Cfg */
-
- VINT32 tjat_ists; /* 18 TJAT Intr Sts */
- VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */
- VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */
- VINT32 tjat_cfg; /* 1B TJAT Cfg */
-
- VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */
- VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */
- VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */
- VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */
-
- VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */
- VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */
- VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */
- VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */
- VINT32 __res24; /* 24 Reserved */
- VINT32 __res25; /* 25 Reserved */
- VINT32 __res26; /* 26 Reserved */
- VINT32 __res27; /* 27 Reserved */
-
- VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */
- VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */
- VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */
- VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */
- VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */
- VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */
- VINT32 _rxce_res2E; /* 2E RXCE Reserved */
- VINT32 _rxce_res2F; /* 2F RXCE Reserved */
-
- VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */
- VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */
- VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */
- VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */
- VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */
- VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */
- VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */
- VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */
-
- VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */
- VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */
- VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */
- VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */
- VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */
- VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */
- VINT32 _txci_res3E; /* 3E TXCI Reserved */
- VINT32 _txci_res3F; /* 3F TXCI Reserved */
-
- VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */
- VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */
- VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */
- VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */
- VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */
- VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */
- VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */
- VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */
- VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */
- VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */
- VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */
- VINT32 __res_4B; /* 4B Reserved */
- VINT32 ibcd_cfg; /* 4C IBCD Cfg */
- VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */
- VINT32 ibcd_act; /* 4E IBCD Activate Code */
- VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */
-
- VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */
- VINT32 sigx_acc_cos; /* 51 SIGX
- * uP Access Sts/Change of Signaling State */
- VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect
- * Addr/Ctl/Change of Signaling State */
- VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data
- * Buffer/Change of Signaling State */
-
- VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */
- VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */
- VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */
- VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */
-
- VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */
- VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */
- VINT32 pmon_feb_lsb; /* 5A PMON
- * OFF/COFA/Far End Block Err Cnt (LSB) */
- VINT32 pmon_feb_msb; /* 5B PMON
- * OFF/COFA/Far End Block Err Cnt (MSB) */
- VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */
- VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */
- VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */
- VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */
-
- VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */
- VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */
- VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */
- VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */
-
- VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */
- VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */
- VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */
- VINT32 t1_xboc_code; /* 67 T1 XBOC Code */
- VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */
- VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */
-
- VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */
- VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */
-
- VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */
- VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */
- VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect
- * Addr/Ctl */
- VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data
- * Buffer */
- VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */
- VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */
- VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect
- * Addr/Ctl */
- VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data
- * Buffer */
- VINT32 __res74; /* 74 Reserved */
- VINT32 __res75; /* 75 Reserved */
- VINT32 __res76; /* 76 Reserved */
- VINT32 __res77; /* 77 Reserved */
-
- VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */
- VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */
- VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */
- VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */
- VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */
- VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */
- VINT32 t1_aprm_1sec_5; /* 7E T1 APRM
- * One Second Content MSB (Octect 5) */
- VINT32 t1_aprm_1sec_6; /* 7F T1 APRM
- * One Second Content MSB (Octect 6) */
-
- VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */
- VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */
- VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */
- VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */
- VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */
- VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */
- VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword
- * Select */
- VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */
- VINT32 __res88; /* 88 Reserved */
- VINT32 __res89; /* 89 Reserved */
- VINT32 __res8A; /* 8A Reserved */
- VINT32 __res8B; /* 8B Reserved */
-
- VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */
- VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */
- VINT32 __res8E; /* 8E Reserved */
- VINT32 __res8F; /* 8F Reserved */
-
- VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */
- VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */
- VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */
- VINT32 e1_frmr_mien; /* 93 E1 FRMR
- * Maintenance/Alarm Sts Intr Enable */
- VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */
- VINT32 e1_frmr_mists; /* 95 E1 FRMR
- * Maintenance/Alarm Sts Indication Enable */
- VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */
- VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */
- VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */
- VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */
- VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */
- VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR
- * National Bit Codeword Intr Enables */
- VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR
- * National Bit Codeword Intr/Sts */
- VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */
- VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR
- * Frame Pulse/Alarm Intr Enables */
- VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */
-
- VINT32 __resA0; /* A0 Reserved */
- VINT32 __resA1; /* A1 Reserved */
- VINT32 __resA2; /* A2 Reserved */
- VINT32 __resA3; /* A3 Reserved */
- VINT32 __resA4; /* A4 Reserved */
- VINT32 __resA5; /* A5 Reserved */
- VINT32 __resA6; /* A6 Reserved */
- VINT32 __resA7; /* A7 Reserved */
-
- VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */
- VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */
- VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */
- VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */
- VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */
- VINT32 tdpr1_data; /* AD TDPR #1 TX Data */
- VINT32 __resAE; /* AE Reserved */
- VINT32 __resAF; /* AF Reserved */
- VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */
- VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */
- VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */
- VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */
- VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */
- VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */
- VINT32 __resB6; /* B6 Reserved */
- VINT32 __resB7; /* B7 Reserved1 */
- VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */
- VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */
- VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */
- VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */
- VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */
- VINT32 tdpr3_data; /* BD TDPR #3 TX Data */
- VINT32 __resBE; /* BE Reserved */
- VINT32 __resBF; /* BF Reserved */
-
- VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */
- VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */
- VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */
- VINT32 rdlc1_data; /* C3 RDLC #1 Data */
- VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */
- VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */
- VINT32 __resC6; /* C6 Reserved */
- VINT32 __resC7; /* C7 Reserved */
- VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */
- VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */
- VINT32 rdlc2_sts; /* CA RDLC #2 Sts */
- VINT32 rdlc2_data; /* CB RDLC #2 Data */
- VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */
- VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */
- VINT32 __resCE; /* CE Reserved */
- VINT32 __resCF; /* CF Reserved */
- VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */
- VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */
- VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */
- VINT32 rdlc3_data; /* D3 RDLC #3 Data */
- VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */
- VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */
-
- VINT32 csu_cfg; /* D6 CSU Cfg */
- VINT32 _csu_resD7; /* D7 CSU Reserved */
-
- VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */
- VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */
- VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */
- VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */
- VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference
- * (E1 missing) */
- VINT32 _rlps_resDD; /* DD RLPS Reserved */
- VINT32 _rlps_resDE; /* DE RLPS Reserved */
- VINT32 _rlps_resDF; /* DF RLPS Reserved */
-
- VINT32 prgd_ctl; /* E0 PRGD Ctl */
- VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */
- VINT32 prgd_shift_len; /* E2 PRGD Shift Length */
- VINT32 prgd_tap; /* E3 PRGD Tap */
- VINT32 prgd_errin; /* E4 PRGD Err Insertion */
- VINT32 _prgd_resE5; /* E5 PRGD Reserved */
- VINT32 _prgd_resE6; /* E6 PRGD Reserved */
- VINT32 _prgd_resE7; /* E7 PRGD Reserved */
- VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */
- VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */
- VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */
- VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */
- VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */
- VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */
- VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */
- VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */
-
- VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */
- VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */
- VINT32 xlpg_pwave_addr; /* F2 XLPG
- * Pulse Waveform Storage Write Addr */
- VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */
- VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */
- VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */
- VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */
- VINT32 _xlpg_resF7; /* F7 XLPG Reserved */
-
- VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */
- VINT32 rlps_alos_thresh; /* F9 RLPS
- * ALOS Detection/Clearance Threshold */
- VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */
- VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */
- VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */
- VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */
- VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */
- VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */
-};
-
-/* 00AH: MDIAG Register bit definitions */
-#define COMET_MDIAG_ID5 0x40
-#define COMET_MDIAG_LBMASK 0x3F
-#define COMET_MDIAG_PAYLB 0x20
-#define COMET_MDIAG_LINELB 0x10
-#define COMET_MDIAG_RAIS 0x08
-#define COMET_MDIAG_DDLB 0x04
-#define COMET_MDIAG_TXMFP 0x02
-#define COMET_MDIAG_TXLOS 0x01
-#define COMET_MDIAG_LBOFF 0x00
-
-#undef VINT32
-
-#ifdef __KERNEL__
-extern void
-init_comet(void *, struct s_comet_reg *, u_int32_t, int, u_int8_t);
-#endif
-
-#endif /* _INC_COMET_H_ */
diff --git a/drivers/staging/cxt1e1/comet_tables.c b/drivers/staging/cxt1e1/comet_tables.c
deleted file mode 100644
index e96665ea3662..000000000000
--- a/drivers/staging/cxt1e1/comet_tables.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*-----------------------------------------------------------------------------
- * comet_tables.c - waveform tables for the PM4351 'COMET'
- *
- * Copyright (C) 2003-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-#include "comet_tables.h"
-
-/*****************************************************************************
-*
-* Array names:
-*
-* TWVLongHaul0DB
-* TWVLongHaul7_5DB
-* TWVLongHaul15DB
-* TWVLongHaul22_5DB
-* TWVShortHaul0
-* TWVShortHaul1
-* TWVShortHaul2
-* TWVShortHaul3
-* TWVShortHaul4
-* TWVShortHaul5
-* TWV_E1_120Ohm
-* TWV_E1_75Ohm <not supported>
-* T1_Equalizer
-* E1_Equalizer
-*
-*****************************************************************************/
-
-u_int8_t TWVLongHaul0DB[25][5] =/* T1 Long Haul 0 DB */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x32, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3E, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3D, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x4C, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x0C} /* PMC's suggested value */
-/* {0x14} Output Amplitude */
-};
-
-u_int8_t TWVLongHaul7_5DB[25][5] = /* T1 Long Haul 7.5 DB */
-{
- {0x00, 0x10, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x01, 0x0E, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x02, 0x0C, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x04, 0x0A, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x08, 0x08, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x0C, 0x06, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x10, 0x04, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x16, 0x02, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x1A, 0x01, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x1E, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x22, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x20, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x1C, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x18, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x12, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x07} /* PMC's suggested value */
-/* { 0x0A } Output Amplitude */
-};
-
-u_int8_t TWVLongHaul15DB[25][5] = /* T1 Long Haul 15 DB */
-{
- {0x00, 0x2A, 0x09, 0x01, 0x00}, /* Sample 0 */
- {0x00, 0x28, 0x08, 0x01, 0x00}, /* Sample 1 */
- {0x00, 0x26, 0x08, 0x01, 0x00}, /* Sample 2 */
- {0x00, 0x24, 0x07, 0x01, 0x00}, /* Sample 3 */
- {0x01, 0x22, 0x07, 0x01, 0x00}, /* Sample 4 */
- {0x02, 0x20, 0x06, 0x01, 0x00}, /* Sample 5 */
- {0x04, 0x1E, 0x06, 0x01, 0x00}, /* Sample 6 */
- {0x07, 0x1C, 0x05, 0x00, 0x00}, /* Sample 7 */
- {0x0A, 0x1B, 0x05, 0x00, 0x00}, /* Sample 8 */
- {0x0D, 0x19, 0x05, 0x00, 0x00}, /* Sample 9 */
- {0x10, 0x18, 0x04, 0x00, 0x00}, /* Sample 10 */
- {0x14, 0x16, 0x04, 0x00, 0x00}, /* Sample 11 */
- {0x18, 0x15, 0x04, 0x00, 0x00}, /* Sample 12 */
- {0x1B, 0x13, 0x03, 0x00, 0x00}, /* Sample 13 */
- {0x1E, 0x12, 0x03, 0x00, 0x00}, /* Sample 14 */
- {0x21, 0x10, 0x03, 0x00, 0x00}, /* Sample 15 */
- {0x24, 0x0F, 0x03, 0x00, 0x00}, /* Sample 16 */
- {0x27, 0x0D, 0x03, 0x00, 0x00}, /* Sample 17 */
- {0x2A, 0x0D, 0x02, 0x00, 0x00}, /* Sample 18 */
- {0x2D, 0x0B, 0x02, 0x00, 0x00}, /* Sample 19 */
- {0x30, 0x0B, 0x02, 0x00, 0x00}, /* Sample 20 */
- {0x30, 0x0A, 0x02, 0x00, 0x00}, /* Sample 21 */
- {0x2E, 0x0A, 0x02, 0x00, 0x00}, /* Sample 22 */
- {0x2C, 0x09, 0x02, 0x00, 0x00}, /* Sample 23 */
- {0x03} /* Output Amplitude */
-};
-
-u_int8_t TWVLongHaul22_5DB[25][5] = /* T1 Long Haul 22.5 DB */
-{
- {0x00, 0x1F, 0x16, 0x06, 0x01}, /* Sample 0 */
- {0x00, 0x20, 0x15, 0x05, 0x01}, /* Sample 1 */
- {0x00, 0x21, 0x15, 0x05, 0x01}, /* Sample 2 */
- {0x00, 0x22, 0x14, 0x05, 0x01}, /* Sample 3 */
- {0x00, 0x22, 0x13, 0x04, 0x00}, /* Sample 4 */
- {0x00, 0x23, 0x12, 0x04, 0x00}, /* Sample 5 */
- {0x01, 0x23, 0x12, 0x04, 0x00}, /* Sample 6 */
- {0x01, 0x24, 0x11, 0x03, 0x00}, /* Sample 7 */
- {0x01, 0x23, 0x10, 0x03, 0x00}, /* Sample 8 */
- {0x02, 0x23, 0x10, 0x03, 0x00}, /* Sample 9 */
- {0x03, 0x22, 0x0F, 0x03, 0x00}, /* Sample 10 */
- {0x05, 0x22, 0x0E, 0x03, 0x00}, /* Sample 11 */
- {0x07, 0x21, 0x0E, 0x02, 0x00}, /* Sample 12 */
- {0x09, 0x20, 0x0D, 0x02, 0x00}, /* Sample 13 */
- {0x0B, 0x1E, 0x0C, 0x02, 0x00}, /* Sample 14 */
- {0x0E, 0x1D, 0x0C, 0x02, 0x00}, /* Sample 15 */
- {0x10, 0x1B, 0x0B, 0x02, 0x00}, /* Sample 16 */
- {0x13, 0x1B, 0x0A, 0x02, 0x00}, /* Sample 17 */
- {0x15, 0x1A, 0x0A, 0x02, 0x00}, /* Sample 18 */
- {0x17, 0x19, 0x09, 0x01, 0x00}, /* Sample 19 */
- {0x19, 0x19, 0x08, 0x01, 0x00}, /* Sample 20 */
- {0x1B, 0x18, 0x08, 0x01, 0x00}, /* Sample 21 */
- {0x1D, 0x17, 0x07, 0x01, 0x00}, /* Sample 22 */
- {0x1E, 0x17, 0x06, 0x01, 0x00}, /* Sample 23 */
- {0x02} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul0[25][5] = /* T1 Short Haul 0 - 110 ft */
-{
- {0x00, 0x45, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x59, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x55, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x4D, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x48, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x0C} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul1[25][5] = /* T1 Short Haul 110 - 220 ft */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x36, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x34, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x68, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x54, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x10} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul2[25][5] = /* T1 Short Haul 220 - 330 ft */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3A, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3A, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x38, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x23, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x6C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x11} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul3[25][5] = /* T1 Short Haul 330 - 440 ft */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x2E, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x19, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x12} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul4[25][5] = /* T1 Short Haul 440 - 550 ft */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x2B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x14} /* Output Amplitude */
-};
-
-u_int8_t TWVShortHaul5[25][5] = /* T1 Short Haul 550 - 660 ft */
-{
- {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x3F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x25, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x5F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x15} /* Output Amplitude */
-};
-
-u_int8_t TWV_E1_120Ohm[25][5] = /* E1 120 Ohm */
-{
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
- {0x0C} /* PMC's suggested value */
-/* { 0x10 } Output Amplitude */
-};
-
-
-
-u_int8_t TWV_E1_75Ohm[25][5] = /* E1 75 Ohm */
-{
-#ifdef PMCC4_DOES_NOT_SUPPORT
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */
- {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */
- {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */
- {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */
- {0x32, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */
- {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */
- {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */
-#endif
- {0x0C} /* Output Amplitude */
-};
-
-
-u_int32_t T1_Equalizer[256] = /* T1 Receiver Equalizer */
-{
- 0x03FE1840, 0x03F61840, 0x03EE1840, 0x03E61840, /* 000 - 003 */
- 0x03DE1840, 0x03D61840, 0x03D61840, 0x03D61840, /* 004 - 007 */
- 0x03CE1840, 0x03CE1840, 0x03CE1840, 0x03CE1840, /* 008 - 011 */
- 0x03C61840, 0x03C61840, 0x03C61840, 0x0BBE1840, /* 012 - 015 */
- 0x0BBE1840, 0x0BBE1840, 0x0BBE1840, 0x0BB61840, /* 016 - 019 */
- 0x0BB61840, 0x0BB61840, 0x0BB61840, 0x13AE1838, /* 020 - 023 */
- 0x13AE183C, 0x13AE1840, 0x13AE1840, 0x13AE1840, /* 024 - 027 */
- 0x13AE1840, 0x1BB618B8, 0x1BAE18B8, 0x1BAE18BC, /* 028 - 031 */
- 0x1BAE18C0, 0x1BAE18C0, 0x23A618C0, 0x23A618C0, /* 032 - 035 */
- 0x23A618C0, 0x23A618C0, 0x23A618C0, 0x239E18C0, /* 036 - 039 */
- 0x239E18C0, 0x239E18C0, 0x239E18C0, 0x239E18C0, /* 040 - 043 */
- 0x2B9618C0, 0x2B9618C0, 0x2B9618C0, 0x33961940, /* 044 - 047 */
- 0x37961940, 0x37961940, 0x37961940, 0x3F9E19C0, /* 048 - 051 */
- 0x3F9E19C0, 0x3F9E19C0, 0x3FA61A40, 0x3FA61A40, /* 052 - 055 */
- 0x3FA61A40, 0x3FA61A40, 0x3F9619C0, 0x3F9619C0, /* 056 - 059 */
- 0x3F9619C0, 0x3F9619C0, 0x479E1A40, 0x479E1A40, /* 060 - 063 */
- 0x479E1A40, 0x47961A40, 0x47961A40, 0x47961A40, /* 064 - 067 */
- 0x47961A40, 0x4F8E1A40, 0x4F8E1A40, 0x4F8E1A40, /* 068 - 071 */
- 0x4F8E1A40, 0x4F8E1A40, 0x57861A40, 0x57861A40, /* 072 - 075 */
- 0x57861A40, 0x57861A40, 0x57861A40, 0x5F861AC0, /* 076 - 079 */
- 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, /* 080 - 083 */
- 0x5F861AC0, 0x5F7E1AC0, 0x5F7E1AC0, 0x5F7E1AC0, /* 084 - 087 */
- 0x5F7E1AC0, 0x5F7E1AC0, 0x677E2AC0, 0x677E2AC0, /* 088 - 091 */
- 0x677E2AC0, 0x677E2AC0, 0x67762AC0, 0x67762AC0, /* 092 - 095 */
- 0x67762AC0, 0x67762AC0, 0x67762AC0, 0x6F6E2AC0, /* 096 - 099 */
- 0x6F6E2AC0, 0x6F6E2AC0, 0x6F6E2AC0, 0x776E3AC0, /* 100 - 103 */
- 0x776E3AC0, 0x776E3AC0, 0x776E3AC0, 0x7F663AC0, /* 104 - 107 */
- 0x7F663AC0, 0x7F664AC0, 0x7F664AC0, 0x7F664AC0, /* 108 - 111 */
- 0x7F664AC0, 0x87665AC0, 0x87665AC0, 0x87665AC0, /* 112 - 115 */
- 0x87665AC0, 0x87665AC0, 0x875E5AC0, 0x875E5AC0, /* 116 - 119 */
- 0x875E5AC0, 0x875E5AC0, 0x875E5AC0, 0x8F5E6AC0, /* 120 - 123 */
- 0x8F5E6AC0, 0x8F5E6AC0, 0x8F5E6AC0, 0x975E7AC0, /* 124 - 127 */
- 0x975E7AC0, 0x975E7AC0, 0x975E7AC0, 0x9F5E8AC0, /* 128 - 131 */
- 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, /* 132 - 135 */
- 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, /* 136 - 139 */
- 0xA756AAC0, 0xA756AAC0, 0xA756AAC0, 0xAF4EAAC0, /* 140 - 143 */
- 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, /* 144 - 147 */
- 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, /* 148 - 151 */
- 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746BAC0, /* 152 - 155 */
- 0xB746BAC0, 0xB746BAC0, 0xBF4EBB40, 0xBF4EBB40, /* 156 - 159 */
- 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, /* 160 - 163 */
- 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBE46CB40, /* 164 - 167 */
- 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, /* 168 - 171 */
- 0xBE46CB40, 0xBE46DB40, 0xBE46DB40, 0xBE46DB40, /* 172 - 175 */
- 0xC63ECB40, 0xC63ECB40, 0xC63EDB40, 0xC63EDB40, /* 176 - 179 */
- 0xC63EDB40, 0xC644DB40, 0xC644DB40, 0xC644DB40, /* 180 - 183 */
- 0xC644DB40, 0xC63CDB40, 0xC63CDB40, 0xC63CDB40, /* 184 - 187 */
- 0xC63CDB40, 0xD634DB40, 0xD634DB40, 0xD634DB40, /* 188 - 191 */
- 0xD634DB40, 0xD634DB40, 0xDE2CDB3C, 0xDE2CDB3C, /* 192 - 195 */
- 0xDE2CDB3C, 0xE62CDB40, 0xE62CDB40, 0xE62CDB40, /* 196 - 199 */
- 0xE62CDB40, 0xE62CDB40, 0xE62CEB40, 0xE62CEB40, /* 200 - 203 */
- 0xE62CEB40, 0xEE2CFB40, 0xEE2CFB40, 0xEE2CFB40, /* 204 - 207 */
- 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, /* 208 - 211 */
- 0xEE2D0B40, 0xF5250B38, 0xF5250B3C, 0xF5250B40, /* 212 - 215 */
- 0xF5251B40, 0xF5251B40, 0xF5251B40, 0xF5251B40, /* 216 - 219 */
- 0xF5251B40, 0xFD252B40, 0xFD252B40, 0xFD252B40, /* 220 - 223 */
- 0xFD252B40, 0xFD252740, 0xFD252740, 0xFD252740, /* 224 - 227 */
- 0xFD252340, 0xFD252340, 0xFD252340, 0xFD253340, /* 228 - 231 */
- 0xFD253340, 0xFD253340, 0xFD253340, 0xFD253340, /* 232 - 235 */
- 0xFD253340, 0xFD253340, 0xFD253340, 0xFC254340, /* 236 - 239 */
- 0xFD254340, 0xFD254340, 0xFD254344, 0xFC254348, /* 240 - 243 */
- 0xFC25434C, 0xFD2543BC, 0xFD2543C0, 0xFC2543C0, /* 244 - 247 */
- 0xFC2343C0, 0xFC2343C0, 0xFD2343C0, 0xFC2143C0, /* 248 - 251 */
- 0xFC2143C0, 0xFC2153C0, 0xFD2153C0, 0xFC2153C0 /* 252 - 255 */
-};
-
-
-u_int32_t E1_Equalizer[256] = /* E1 Receiver Equalizer */
-{
- 0x07DE182C, 0x07DE182C, 0x07D6182C, 0x07D6182C, /* 000 - 003 */
- 0x07D6182C, 0x07CE182C, 0x07CE182C, 0x07CE182C, /* 004 - 007 */
- 0x07C6182C, 0x07C6182C, 0x07C6182C, 0x07BE182C, /* 008 - 011 */
- 0x07BE182C, 0x07BE182C, 0x07BE182C, 0x07BE182C, /* 012 - 015 */
- 0x07B6182C, 0x07B6182C, 0x07B6182C, 0x07B6182C, /* 016 - 019 */
- 0x07B6182C, 0x07AE182C, 0x07AE182C, 0x07AE182C, /* 020 - 023 */
- 0x07AE182C, 0x07AE182C, 0x07B618AC, 0x07AE18AC, /* 024 - 027 */
- 0x07AE18AC, 0x07AE18AC, 0x07AE18AC, 0x07A618AC, /* 028 - 031 */
- 0x07A618AC, 0x07A618AC, 0x07A618AC, 0x079E18AC, /* 032 - 035 */
- 0x07A6192C, 0x07A6192C, 0x07A6192C, 0x0FA6192C, /* 036 - 039 */
- 0x0FA6192C, 0x0F9E192C, 0x0F9E192C, 0x0F9E192C, /* 040 - 043 */
- 0x179E192C, 0x17A619AC, 0x179E19AC, 0x179E19AC, /* 044 - 047 */
- 0x179619AC, 0x1F9619AC, 0x1F9619AC, 0x1F8E19AC, /* 048 - 051 */
- 0x1F8E19AC, 0x1F8E19AC, 0x278E19AC, 0x278E1A2C, /* 052 - 055 */
- 0x278E1A2C, 0x278E1A2C, 0x278E1A2C, 0x2F861A2C, /* 056 - 059 */
- 0x2F861A2C, 0x2F861A2C, 0x2F7E1A2C, 0x2F7E1A2C, /* 060 - 063 */
- 0x2F7E1A2C, 0x377E1A2C, 0x377E1AAC, 0x377E1AAC, /* 064 - 067 */
- 0x377E1AAC, 0x377E1AAC, 0x3F7E2AAC, 0x3F7E2AAC, /* 068 - 071 */
- 0x3F762AAC, 0x3F862B2C, 0x3F7E2B2C, 0x477E2B2C, /* 072 - 075 */
- 0x477E2F2C, 0x477E2F2C, 0x477E2F2C, 0x47762F2C, /* 076 - 079 */
- 0x4F762F2C, 0x4F762F2C, 0x4F6E2F2C, 0x4F6E2F2C, /* 080 - 083 */
- 0x4F6E2F2C, 0x576E2F2C, 0x576E2F2C, 0x576E3F2C, /* 084 - 087 */
- 0x576E3F2C, 0x576E3F2C, 0x5F6E3F2C, 0x5F6E4F2C, /* 088 - 091 */
- 0x5F6E4F2C, 0x5F6E4F2C, 0x5F664F2C, 0x67664F2C, /* 092 - 095 */
- 0x67664F2C, 0x675E4F2C, 0x675E4F2C, 0x67664F2C, /* 096 - 099 */
- 0x67664F2C, 0x67665F2C, 0x6F6E5F2C, 0x6F6E6F2C, /* 100 - 103 */
- 0x6F6E6F2C, 0x6F6E7F2C, 0x6F6E7F2C, 0x6F6E7F2C, /* 104 - 107 */
- 0x77667F2C, 0x77667F2C, 0x775E6F2C, 0x775E7F2C, /* 108 - 111 */
- 0x775E7F2C, 0x7F5E7F2C, 0x7F5E8F2C, 0x7F5E8F2C, /* 112 - 115 */
- 0x7F5E8F2C, 0x87568F2C, 0x87568F2C, 0x87568F2C, /* 116 - 119 */
- 0x874E8F2C, 0x874E8F2C, 0x874E8F2C, 0x8F4E9F2C, /* 120 - 123 */
- 0x8F4E9F2C, 0x8F4EAF2C, 0x8F4EAF2C, 0x8F4EAF2C, /* 124 - 127 */
- 0x974EAF2C, 0x974EAF2C, 0x974EAB2C, 0x974EAB2C, /* 128 - 131 */
- 0x974EAB2C, 0x9F4EAB2C, 0x9F4EBB2C, 0x9F4EBB2C, /* 132 - 135 */
- 0x9F4EBB2C, 0x9F4ECB2C, 0xA74ECB2C, 0xA74ECB2C, /* 136 - 139 */
- 0xA746CB2C, 0xA746CB2C, 0xA746CB2C, 0xA746DB2C, /* 140 - 143 */
- 0xAF46DB2C, 0xAF46EB2C, 0xAF46EB2C, 0xAF4EEB2C, /* 144 - 147 */
- 0xAE4EEB2C, 0xAE4EEB2C, 0xB546FB2C, 0xB554FB2C, /* 148 - 151 */
- 0xB54CEB2C, 0xB554FB2C, 0xB554FB2C, 0xBD54FB2C, /* 152 - 155 */
- 0xBD4CFB2C, 0xBD4CFB2C, 0xBD4CFB2C, 0xBD44EB2C, /* 156 - 159 */
- 0xC544FB2C, 0xC544FB2C, 0xC544FB2C, 0xC5450B2C, /* 160 - 163 */
- 0xC5450B2C, 0xC5450B2C, 0xCD450B2C, 0xCD450B2C, /* 164 - 167 */
- 0xCD3D0B2C, 0xCD3D0B2C, 0xCD3D0B2C, 0xD53D0B2C, /* 168 - 171 */
- 0xD53D0B2C, 0xD53D1B2C, 0xD53D1B2C, 0xD53D1B2C, /* 172 - 175 */
- 0xDD3D1B2C, 0xDD3D1B2C, 0xDD351B2C, 0xDD351B2C, /* 176 - 179 */
- 0xDD351B2C, 0xE5351B2C, 0xE5351B2C, 0xE52D1B2C, /* 180 - 183 */
- 0xE52D1B2C, 0xE52D3B2C, 0xED2D4B2C, 0xED2D1BA8, /* 184 - 187 */
- 0xED2D1BAC, 0xED2D17AC, 0xED2D17AC, 0xED2D27AC, /* 188 - 191 */
- 0xF52D27AC, 0xF52D27AC, 0xF52D2BAC, 0xF52D2BAC, /* 192 - 195 */
- 0xF52D2BAC, 0xFD2D2BAC, 0xFD2B2BAC, 0xFD2B2BAC, /* 196 - 199 */
- 0xFD2B2BAC, 0xFD2B2BAC, 0xFD232BAC, 0xFD232BAC, /* 200 - 203 */
- 0xFD232BAC, 0xFD212BAC, 0xFD212BAC, 0xFD292BAC, /* 204 - 207 */
- 0xFD292BAC, 0xFD2927AC, 0xFD2937AC, 0xFD2923AC, /* 208 - 211 */
- 0xFD2923AC, 0xFD2923AC, 0xFD2923AC, 0xFD2123AC, /* 212 - 215 */
- 0xFD2123AC, 0xFD2123AC, 0xFD2133AC, 0xFD2133AC, /* 216 - 219 */
- 0xFD2133AC, 0xFD2143AC, 0xFD2143AC, 0xFD2143AC, /* 220 - 223 */
- 0xFC2143AC, 0xFC2143AC, 0xFC1943AC, 0xFC1943AC, /* 224 - 227 */
- 0xFC1943AC, 0xFC1943AC, 0xFC1953AC, 0xFC1953AC, /* 228 - 231 */
- 0xFC1953AC, 0xFC1953AC, 0xFC1963AC, 0xFC1963AC, /* 232 - 235 */
- 0xFC1963AC, 0xFC1973AC, 0xFC1973AC, 0xFC1973AC, /* 236 - 239 */
- 0xFC1973AC, 0xFC1973AC, 0xFC1983AC, 0xFC1983AC, /* 240 - 243 */
- 0xFC1983AC, 0xFC1983AC, 0xFC1983AC, 0xFC1993AC, /* 244 - 247 */
- 0xFC1993AC, 0xFC1993AC, 0xFC19A3AC, 0xFC19A3AC, /* 248 - 251 */
- 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC /* 252 - 255 */
-};
-
-/*** End-of-Files ***/
diff --git a/drivers/staging/cxt1e1/comet_tables.h b/drivers/staging/cxt1e1/comet_tables.h
deleted file mode 100644
index 3e2e5badf787..000000000000
--- a/drivers/staging/cxt1e1/comet_tables.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef _INC_COMET_TBLS_H_
-#define _INC_COMET_TBLS_H_
-
-/*-----------------------------------------------------------------------------
- * comet_tables.h - Waveform Tables for the PM4351 'COMET'
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-
-/*****************************************************************************
-*
-* Array names:
-*
-* TWVLongHaul0DB
-* TWVLongHaul7_5DB
-* TWVLongHaul15DB
-* TWVLongHaul22_5DB
-* TWVShortHaul0
-* TWVShortHaul1
-* TWVShortHaul2
-* TWVShortHaul3
-* TWVShortHaul4
-* TWVShortHaul5
-* TWV_E1_120Ohm
-* TWV_E1_75Ohm <not supported>
-* T1_Equalizer
-* E1_Equalizer
-*
-*****************************************************************************/
-
-extern u_int8_t TWVLongHaul0DB[25][5]; /* T1 Long Haul 0 DB */
-extern u_int8_t TWVLongHaul7_5DB[25][5]; /* T1 Long Haul 7.5 DB */
-extern u_int8_t TWVLongHaul15DB[25][5]; /* T1 Long Haul 15 DB */
-extern u_int8_t TWVLongHaul22_5DB[25][5]; /* T1 Long Haul 22.5 DB */
-extern u_int8_t TWVShortHaul0[25][5]; /* T1 Short Haul 0-110 ft */
-extern u_int8_t TWVShortHaul1[25][5]; /* T1 Short Haul 110-220 ft */
-extern u_int8_t TWVShortHaul2[25][5]; /* T1 Short Haul 220-330 ft */
-extern u_int8_t TWVShortHaul3[25][5]; /* T1 Short Haul 330-440 ft */
-extern u_int8_t TWVShortHaul4[25][5]; /* T1 Short Haul 440-550 ft */
-extern u_int8_t TWVShortHaul5[25][5]; /* T1 Short Haul 550-660 ft */
-extern u_int8_t TWV_E1_75Ohm[25][5]; /* E1 75 Ohm */
-extern u_int8_t TWV_E1_120Ohm[25][5]; /* E1 120 Ohm */
-extern u_int32_t T1_Equalizer[256]; /* T1 Receiver Equalizer */
-extern u_int32_t E1_Equalizer[256]; /* E1 Receiver Equalizer */
-
-#endif /* _INC_COMET_TBLS_H_ */
diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c
deleted file mode 100644
index 65b6fc36edf6..000000000000
--- a/drivers/staging/cxt1e1/functions.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* Copyright (C) 2003-2005 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <asm/byteorder.h>
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/hdlc.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4.h"
-
-
-#ifndef USE_MAX_INT_DELAY
-static int dummy = 0;
-
-#endif
-
-extern int drvr_state;
-
-
-#if 1
-u_int32_t
-pci_read_32(u_int32_t *p)
-{
-#ifdef FLOW_DEBUG
- u_int32_t v;
-
- FLUSH_PCI_READ();
- v = le32_to_cpu(*p);
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("pci_read : %x = %x\n", (u_int32_t) p, v);
- return v;
-#else
- FLUSH_PCI_READ(); /* */
- return le32_to_cpu(*p);
-#endif
-}
-
-void
-pci_write_32(u_int32_t *p, u_int32_t v)
-{
-#ifdef FLOW_DEBUG
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("pci_write: %x = %x\n", (u_int32_t) p, v);
-#endif
- *p = cpu_to_le32 (v);
- FLUSH_PCI_WRITE(); /* This routine is called from routines
- * which do multiple register writes
- * which themselves need flushing between
- * writes in order to guarantee write
- * ordering. It is less code-cumbersome
- * to flush here-in then to investigate
- * and code the many other register
- * writing routines. */
-}
-#endif
-
-
-void
-pci_flush_write(ci_t *ci)
-{
- volatile u_int32_t v;
-
- /* issue a PCI read to flush PCI write thru bridge */
- v = *(u_int32_t *) &ci->reg->glcd; /* any address would do */
-
- /*
- * return nothing, this just reads PCI bridge interface to flush
- * previously written data
- */
-}
-
-
-static void
-watchdog_func(unsigned long arg)
-{
- struct watchdog *wd = (void *) arg;
-
- if (drvr_state != SBE_DRVR_AVAILABLE) {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_warning("%s: drvr not available (%x)\n",
- __func__, drvr_state);
- return;
- }
- schedule_work(&wd->work);
- mod_timer(&wd->h, jiffies + wd->ticks);
-}
-
-int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *),
- void *c, int usec)
-{
- wdp->func = f;
- wdp->softc = c;
- wdp->ticks = (HZ) * (usec / 1000) / 1000;
- INIT_WORK(&wdp->work, (void *)f);
- init_timer(&wdp->h);
- {
- ci_t *ci = (ci_t *) c;
-
- wdp->h.data = (unsigned long) &ci->wd;
- }
- wdp->h.function = watchdog_func;
- return 0;
-}
-
-void
-OS_uwait(int usec, char *description)
-{
- int tmp;
-
- if (usec >= 1000) {
- mdelay(usec / 1000);
- /* now delay residual */
- tmp = (usec / 1000) * 1000; /* round */
- tmp = usec - tmp; /* residual */
- if (tmp) { /* wait on residual */
- udelay(tmp);
- }
- } else {
- udelay(usec);
- }
-}
-
-/* dummy short delay routine called as a subroutine so that compiler
- * does not optimize/remove its intent (a short delay)
- */
-
-void
-OS_uwait_dummy(void)
-{
-#ifndef USE_MAX_INT_DELAY
- dummy++;
-#else
- udelay(1);
-#endif
-}
-
-
-void
-OS_sem_init(void *sem, int state)
-{
- switch (state) {
- case SEM_TAKEN:
- sema_init((struct semaphore *) sem, 0);
- break;
- case SEM_AVAILABLE:
- sema_init((struct semaphore *) sem, 1);
- break;
- default: /* otherwise, set sem.count to state's
- * value */
- sema_init(sem, state);
- break;
- }
-}
-
-
-int
-sd_line_is_ok(void *user)
-{
- struct net_device *ndev = (struct net_device *) user;
-
- return netif_carrier_ok(ndev);
-}
-
-void
-sd_line_is_up(void *user)
-{
- struct net_device *ndev = (struct net_device *) user;
-
- netif_carrier_on(ndev);
- return;
-}
-
-void
-sd_line_is_down(void *user)
-{
- struct net_device *ndev = (struct net_device *) user;
-
- netif_carrier_off(ndev);
- return;
-}
-
-void
-sd_disable_xmit(void *user)
-{
- struct net_device *dev = (struct net_device *) user;
-
- netif_stop_queue(dev);
- return;
-}
-
-void
-sd_enable_xmit(void *user)
-{
- struct net_device *dev = (struct net_device *) user;
-
- netif_wake_queue(dev);
- return;
-}
-
-int
-sd_queue_stopped(void *user)
-{
- struct net_device *ndev = (struct net_device *) user;
-
- return netif_queue_stopped(ndev);
-}
-
-void sd_recv_consume(void *token, size_t len, void *user)
-{
- struct net_device *ndev = user;
- struct sk_buff *skb = token;
-
- skb->dev = ndev;
- skb_put(skb, len);
- skb->protocol = hdlc_type_trans(skb, ndev);
- netif_rx(skb);
-}
-
-
-/**
- ** Read some reserved location w/in the COMET chip as a usable
- ** VMETRO trigger point or other trace marking event.
- **/
-
-#include "comet.h"
-
-extern ci_t *CI; /* dummy pointer to board ZERO's data */
-void
-VMETRO_TRIGGER(ci_t *ci, int x)
-{
- struct s_comet_reg *comet;
- volatile u_int32_t data;
-
- comet = ci->port[0].cometbase; /* default to COMET # 0 */
-
- switch (x) {
- default:
- case 0:
- data = pci_read_32((u_int32_t *) &comet->__res24); /* 0x90 */
- break;
- case 1:
- data = pci_read_32((u_int32_t *) &comet->__res25); /* 0x94 */
- break;
- case 2:
- data = pci_read_32((u_int32_t *) &comet->__res26); /* 0x98 */
- break;
- case 3:
- data = pci_read_32((u_int32_t *) &comet->__res27); /* 0x9C */
- break;
- case 4:
- data = pci_read_32((u_int32_t *) &comet->__res88); /* 0x220 */
- break;
- case 5:
- data = pci_read_32((u_int32_t *) &comet->__res89); /* 0x224 */
- break;
- case 6:
- data = pci_read_32((u_int32_t *) &comet->__res8A); /* 0x228 */
- break;
- case 7:
- data = pci_read_32((u_int32_t *) &comet->__res8B); /* 0x22C */
- break;
- case 8:
- data = pci_read_32((u_int32_t *) &comet->__resA0); /* 0x280 */
- break;
- case 9:
- data = pci_read_32((u_int32_t *) &comet->__resA1); /* 0x284 */
- break;
- case 10:
- data = pci_read_32((u_int32_t *) &comet->__resA2); /* 0x288 */
- break;
- case 11:
- data = pci_read_32((u_int32_t *) &comet->__resA3); /* 0x28C */
- break;
- case 12:
- data = pci_read_32((u_int32_t *) &comet->__resA4); /* 0x290 */
- break;
- case 13:
- data = pci_read_32((u_int32_t *) &comet->__resA5); /* 0x294 */
- break;
- case 14:
- data = pci_read_32((u_int32_t *) &comet->__resA6); /* 0x298 */
- break;
- case 15:
- data = pci_read_32((u_int32_t *) &comet->__resA7); /* 0x29C */
- break;
- case 16:
- data = pci_read_32((u_int32_t *) &comet->__res74); /* 0x1D0 */
- break;
- case 17:
- data = pci_read_32((u_int32_t *) &comet->__res75); /* 0x1D4 */
- break;
- case 18:
- data = pci_read_32((u_int32_t *) &comet->__res76); /* 0x1D8 */
- break;
- case 19:
- data = pci_read_32((u_int32_t *) &comet->__res77); /* 0x1DC */
- break;
- }
-}
-
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c
deleted file mode 100644
index 4fa27c8931b1..000000000000
--- a/drivers/staging/cxt1e1/hwprobe.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/* Copyright (C) 2007 One Stop Systems
- * Copyright (C) 2003-2005 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/netdevice.h>
-#include <linux/hdlc.h>
-#include <linux/if_arp.h>
-#include <asm/uaccess.h>
-#include <linux/rtnetlink.h>
-#include <linux/pci.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4_private.h"
-#include "pmcc4.h"
-#include "pmcc4_ioctls.h"
-#include "pmc93x6_eeprom.h"
-#ifdef CONFIG_PROC_FS
-#include "sbeproc.h"
-#endif
-
-extern int error_flag;
-extern int drvr_state;
-
-/* forward references */
-void c4_stopwd(ci_t *);
-struct net_device * __init c4_add_dev(hdw_info_t *, int, unsigned long,
- unsigned long, int, int);
-
-
-struct s_hdw_info hdw_info[MAX_BOARDS];
-
-
-void __init
-show_two(hdw_info_t *hi, int brdno)
-{
- ci_t *ci;
- struct pci_dev *pdev;
- char *bid;
- char banner[80];
- char sn[6] = {0,};
-
- ci = (ci_t *)(netdev_priv(hi->ndev));
- bid = sbeid_get_bdname(ci);
- switch (hi->promfmt) {
- case PROM_FORMAT_TYPE1:
- memcpy(sn, hi->mfg_info.pft1.Serial, 6);
- break;
- case PROM_FORMAT_TYPE2:
- memcpy(sn, hi->mfg_info.pft2.Serial, 6);
- break;
- }
-
- sprintf(banner, "%s: %s S/N %06X, MUSYCC Rev %02X",
- hi->devname, bid,
- ((sn[3] << 16) & 0xff0000) |
- ((sn[4] << 8) & 0x00ff00) |
- (sn[5] & 0x0000ff),
- (u_int8_t) hi->revid[0]);
-
- pr_info("%s\n", banner);
-
- pdev = hi->pdev[0];
- pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
- hi->devname, "MUSYCC",
- (unsigned long) hi->addr_mapped[0], hi->addr[0],
- hi->pci_busno, (u_int8_t) PCI_SLOT(pdev->devfn),
- (u_int8_t) PCI_FUNC(pdev->devfn), pdev->irq);
-
- pdev = hi->pdev[1];
- pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
- hi->devname, "EBUS ",
- (unsigned long) hi->addr_mapped[1], hi->addr[1],
- hi->pci_busno, (u_int8_t) PCI_SLOT(pdev->devfn),
- (u_int8_t) PCI_FUNC(pdev->devfn), pdev->irq);
-}
-
-
-void __init
-hdw_sn_get(hdw_info_t *hi, int brdno)
-{
- /* obtain hardware EEPROM information */
- long addr;
-
- addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET;
-
- /* read EEPROM with largest known format size... */
- pmc_eeprom_read_buffer(addr, 0, (char *)hi->mfg_info.data,
- sizeof(FLD_TYPE2));
-
-#if 0
- {
- unsigned char *ucp = (unsigned char *) &hi->mfg_info.data;
-
- pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3),
- *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7));
- pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11),
- *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15));
- pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19),
- *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23));
- pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27),
- *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31));
- pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35),
- *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39));
- pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
- *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43),
- *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47));
- }
-#endif
-#if 0
- pr_info("sn: %x %x %x %x %x %x\n",
- hi->mfg_info.Serial[0],
- hi->mfg_info.Serial[1],
- hi->mfg_info.Serial[2],
- hi->mfg_info.Serial[3],
- hi->mfg_info.Serial[4],
- hi->mfg_info.Serial[5]);
-#endif
-
- hi->promfmt = pmc_verify_cksum(&hi->mfg_info.data);
- if (hi->promfmt == PROM_FORMAT_Unk) {
- /* bad crc, data is suspect */
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: EEPROM cksum error\n", hi->devname);
- hi->mfg_info_sts = EEPROM_CRCERR;
- } else
- hi->mfg_info_sts = EEPROM_OK;
-}
-
-
- void __init
-prep_hdw_info(void)
-{
- hdw_info_t *hi;
- int i;
-
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- hi->pci_busno = 0xff;
- hi->pci_slot = 0xff;
- hi->pci_pin[0] = 0;
- hi->pci_pin[1] = 0;
- hi->ndev = NULL;
- hi->addr[0] = 0L;
- hi->addr[1] = 0L;
- hi->addr_mapped[0] = NULL;
- hi->addr_mapped[1] = NULL;
- }
-}
-
-void
-cleanup_ioremap(void)
-{
- hdw_info_t *hi;
- int i;
-
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->pci_slot == 0xff)
- break;
- if (hi->addr_mapped[0]) {
- iounmap(hi->addr_mapped[0]);
- release_mem_region((long) hi->addr[0], hi->len[0]);
- hi->addr_mapped[0] = NULL;
- }
- if (hi->addr_mapped[1]) {
- iounmap(hi->addr_mapped[1]);
- release_mem_region((long) hi->addr[1], hi->len[1]);
- hi->addr_mapped[1] = NULL;
- }
- }
-}
-
-
-void
-cleanup_devs(void)
-{
- hdw_info_t *hi;
- int i;
-
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->pci_slot == 0xff || !hi->ndev)
- break;
- c4_stopwd(netdev_priv(hi->ndev));
-#ifdef CONFIG_PROC_FS
- sbecom_proc_brd_cleanup(netdev_priv(hi->ndev));
-#endif
- unregister_netdev(hi->ndev);
- free_irq(hi->pdev[0]->irq, hi->ndev);
-#ifdef CONFIG_SBE_PMCC4_NCOMM
- free_irq(hi->pdev[1]->irq, hi->ndev);
-#endif
- kfree(hi->ndev);
- }
-}
-
-
-static int __init
-c4_hdw_init(struct pci_dev *pdev, int found)
-{
- hdw_info_t *hi;
- int i;
- int fun, slot;
- unsigned char busno = 0xff;
-
- /* our MUSYCC chip supports two functions, 0 & 1 */
- fun = PCI_FUNC(pdev->devfn);
- if (fun > 1) {
- pr_warning("unexpected devfun: 0x%x\n", pdev->devfn);
- return 0;
- }
-
- /* obtain bus number */
- if (pdev->bus)
- busno = pdev->bus->number;
- else
- busno = 0; /* default for system PCI inconsistency */
- slot = pdev->devfn & ~0x07;
-
- /*
- * Functions 0 & 1 for a given board (identified by same bus(busno) and
- * slot(slot)) are placed into the same 'hardware' structure. The first
- * part of the board's functionality will be placed into an unpopulated
- * element, identified by "slot==(0xff)". The second part of a board's
- * functionality will match the previously loaded slot/busno.
- */
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- /*
- * match with board's first found interface, otherwise this is
- * fisrt found
- */
- if ((hi->pci_slot == 0xff) || /* new board */
- ((hi->pci_slot == slot) && (hi->bus == pdev->bus)))
- break; /* found for-loop exit */
- }
-
- /* no match in above loop means MAX exceeded */
- if (i == MAX_BOARDS) {
- pr_warning("exceeded number of allowed devices (>%d)?\n",
- MAX_BOARDS);
- return 0;
- }
-
- if (pdev->bus)
- hi->pci_busno = pdev->bus->number;
- else
- hi->pci_busno = 0; /* default for system PCI inconsistency */
-
- hi->pci_slot = slot;
- pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]);
- pci_read_config_byte(pdev, PCI_REVISION_ID, &hi->revid[fun]);
- hi->bus = pdev->bus;
- hi->addr[fun] = pci_resource_start(pdev, 0);
- hi->len[fun] = pci_resource_end(pdev, 0) - hi->addr[fun] + 1;
- hi->pdev[fun] = pdev;
-
- {
- /*
- * create device name from module name, plus add the appropriate
- * board number
- */
- char *cp = hi->devname;
-
- strcpy(cp, KBUILD_MODNAME);
- cp += strlen(cp); /* reposition */
- *cp++ = '-';
- *cp++ = '0' + (found / 2); /* there are two found interfaces per
- * board */
- *cp = 0; /* termination */
- }
-
- return 1;
-}
-
-status_t __init
-c4hw_attach_all(void)
-{
- hdw_info_t *hi;
- struct pci_dev *pdev = NULL;
- int found = 0, i, j;
-
- error_flag = 0;
- prep_hdw_info();
- /*** scan PCI bus for all possible boards */
- while ((pdev = pci_get_device(PCI_VENDOR_ID_CONEXANT,
- PCI_DEVICE_ID_CN8474,
- pdev))) {
- if (c4_hdw_init(pdev, found))
- found++;
- }
-
- if (!found) {
- pr_warning("No boards found\n");
- return -ENODEV;
- }
-
- /* sanity check for consistent hardware found */
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1])) {
- pr_warning("%s: something very wrong with pci_get_device\n",
- hi->devname);
- return -EIO;
- }
- }
- /* bring board's memory regions on/line */
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->pci_slot == 0xff)
- break;
- for (j = 0; j < 2; j++) {
- if (!request_mem_region(hi->addr[j], hi->len[j], hi->devname)) {
- pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
- hi->devname, hi->addr[j], hi->len[j]);
- cleanup_ioremap();
- return -ENOMEM;
- }
-
- hi->addr_mapped[j] = ioremap(hi->addr[j], hi->len[j]);
- if (!hi->addr_mapped[j]) {
- pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
- hi->devname, hi->addr[j], hi->len[j]);
- cleanup_ioremap();
- return -ENOMEM;
- }
-#ifdef SBE_MAP_DEBUG
- pr_warning("%s: io remapped from phys %x to virt %x\n",
- hi->devname, (u_int32_t) hi->addr[j],
- (u_int32_t) hi->addr_mapped[j]);
-#endif
- }
- }
-
- drvr_state = SBE_DRVR_AVAILABLE;
-
- /* Have now memory mapped all boards. Now allow board's access to system */
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->pci_slot == 0xff)
- break;
- if (pci_enable_device(hi->pdev[0]) ||
- pci_enable_device(hi->pdev[1])) {
- drvr_state = SBE_DRVR_DOWN;
- pr_warning("%s: failed to enable card %d slot %d\n",
- hi->devname, i, hi->pci_slot);
- cleanup_devs();
- cleanup_ioremap();
- return -EIO;
- }
- pci_set_master(hi->pdev[0]);
- pci_set_master(hi->pdev[1]);
- hi->ndev = c4_add_dev(hi, i, (long) hi->addr_mapped[0],
- (long) hi->addr_mapped[1],
- hi->pdev[0]->irq,
- hi->pdev[1]->irq);
- if (!hi->ndev) {
- drvr_state = SBE_DRVR_DOWN;
- cleanup_ioremap();
- /* NOTE: c4_add_dev() does its own device cleanup */
-#if 0
- cleanup_devs();
-#endif
- return error_flag; /* error_flag set w/in add_dev() */
- }
- show_two(hi, i); /* displays found information */
- }
- return 0;
-}
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/libsbew.h b/drivers/staging/cxt1e1/libsbew.h
deleted file mode 100644
index bd2bfba604b3..000000000000
--- a/drivers/staging/cxt1e1/libsbew.h
+++ /dev/null
@@ -1,549 +0,0 @@
-#ifndef _INC_LIBSBEW_H_
-#define _INC_LIBSBEW_H_
-
-/*-----------------------------------------------------------------------------
- * libsbew.h - common library elements, charge across mulitple boards
- *
- * This file contains common Ioctl structures and contents definitions.
- *
- * Copyright (C) 2004-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-/********************************/
-/** set driver logging level **/
-/********************************/
-
-/* routine/ioctl: wancfg_set_loglevel() - SBE_IOC_SET_LOGLEVEL */
-
-#define LOG_NONE 0
-#define LOG_ERROR 1
-#define LOG_SBEBUG3 3 /* hidden, for development/debug usage */
-#define LOG_LSCHANGE 5 /* line state change logging */
-#define LOG_LSIMMEDIATE 6 /* line state change logging w/o hysterisis */
-#define LOG_WARN 8
-#define LOG_MONITOR 10
-#define LOG_SBEBUG12 12 /* hidden, for development/debug usage */
-#define LOG_MONITOR2 14 /* hidden, for development/debug usage */
-#define LOG_DEBUG 16
-
- /* TEMPORARY DEFINES *//* RLD DEBUG */
-#define c4_LOG_NONE LOG_NONE
-#define c4_LOG_ERROR LOG_ERROR
-#define c4_LOG_WARN LOG_WARN
-#define c4_LOG_sTrace LOG_MONITOR /* do some trace logging into
- * functions */
-#define c4_LOG_DEBUG LOG_DEBUG
-#define c4_LOG_MAX LOG_DEBUG
-
-
-
-/******************************/
-/** get driver information **/
-/******************************/
-
-/* routine/ioctl: wancfg_get_drvinfo() - SBE_IOC_GET_DRVINFO */
-
-#define REL_STRLEN 80
- struct sbe_drv_info
- {
- int rel_strlen;
- char release[REL_STRLEN];
- };
-
-
-/*****************************/
-/** get board information **/
-/*****************************/
-
-/* routine/ioctl: wancfg_get_brdinfo() - SBE_IOC_GET_BRDINFO */
-
-#define CHNM_STRLEN 16
- struct sbe_brd_info
- {
- u_int32_t brd_id; /* SBE's unique PCI VENDOR/DEVID */
- u_int32_t brd_sn;
- int brd_chan_cnt; /* number of channels being used */
- int brd_port_cnt; /* number of ports being used */
- unsigned char brdno; /* our board number */
- unsigned char brd_pci_speed; /* PCI speed, 33/66Mhz */
- u_int8_t brd_mac_addr[6];
- char first_iname[CHNM_STRLEN]; /* first assigned channel's
- * interface name */
- char last_iname[CHNM_STRLEN]; /* last assigned channel's
- * interface name */
- u_int8_t brd_hdw_id; /* on/board unique hdw ID */
- u_int8_t reserved8[3]; /* alignment preservation */
- u_int32_t reserved32[3]; /* size preservation */
- };
-
-/* These IDs are sometimes available thru pci_ids.h, but not currently. */
-
-#define PCI_VENDOR_ID_SBE 0x1176
-#define PCI_DEVICE_ID_WANPMC_C4T1E1 0x0701 /* BID 0x0X, BTYP 0x0X */
-#define PCI_DEVICE_ID_WANPTMC_C4T1E1 0x0702 /* BID 0x41 */
-#define PCI_DEVICE_ID_WANADAPT_HC4T1E1 0x0703 /* BID 0x44 */
-#define PCI_DEVICE_ID_WANPTMC_256T3_T1 0x0704 /* BID 0x42 (T1 Version) */
-#define PCI_DEVICE_ID_WANPCI_C4T1E1 0x0705 /* BID 0x1X, BTYP 0x0X */
-#define PCI_DEVICE_ID_WANPMC_C1T3 0x0706 /* BID 0x45 */
-#define PCI_DEVICE_ID_WANPCI_C2T1E1 0x0707 /* BID 0x1X, BTYP 0x2X */
-#define PCI_DEVICE_ID_WANPCI_C1T1E1 0x0708 /* BID 0x1X, BTYP 0x1X */
-#define PCI_DEVICE_ID_WANPMC_C2T1E1 0x0709 /* BID 0x0X, BTYP 0x2X */
-#define PCI_DEVICE_ID_WANPMC_C1T1E1 0x070A /* BID 0x0X, BTYP 0x1X */
-#define PCI_DEVICE_ID_WANPTMC_256T3_E1 0x070B /* BID 0x46 (E1 Version) */
-#define PCI_DEVICE_ID_WANPTMC_C24TE1 0x070C /* BID 0x47 */
-#define PCI_DEVICE_ID_WANPMC_C4T1E1_L 0x070D /* BID 0x2X, BTYPE 0x0X w/FP
- * LEDs */
-#define PCI_DEVICE_ID_WANPMC_C2T1E1_L 0x070E /* BID 0x2X, BTYPE 0x2X w/FP
- * LEDs */
-#define PCI_DEVICE_ID_WANPMC_C1T1E1_L 0x070F /* BID 0x2X, BTYPE 0x1X w/FP
- * LEDs */
-#define PCI_DEVICE_ID_WANPMC_2SSI 0x0801
-#define PCI_DEVICE_ID_WANPCI_4SSI 0x0802
-#define PCI_DEVICE_ID_WANPMC_2T3E3 0x0900 /* BID 0x43 */
-#define SBE_BOARD_ID(v,id) ((v<<16) | id)
-
-#define BINFO_PCI_SPEED_unk 0
-#define BINFO_PCI_SPEED_33 1
-#define BINFO_PCI_SPEED_66 2
-
-/***************************/
-/** obtain interface ID **/
-/***************************/
-
-/* routine/ioctl: wancfg_get_iid() - SBE_IOC_IID_GET */
-
- struct sbe_iid_info
- {
- u_int32_t channum; /* channel requested */
- char iname[CHNM_STRLEN]; /* channel's interface name */
- };
-
-/**************************************/
-/** get board address information **/
-/**************************************/
-
-/* routine/ioctl: wancfg_get_brdaddr() - SBE_IOC_BRDADDR_GET */
-
- struct sbe_brd_addr
- {
- unsigned char func; /* select PCI address space function */
- unsigned char brdno; /* returns brdno requested */
- unsigned char irq;
- unsigned char size; /* returns size of address */
-#define BRDADDR_SIZE_64 1
-#define BRDADDR_SIZE_32 2
- int reserved1; /* mod64 align, reserved for future use */
-
- union
- {
- unsigned long virt64; /* virtual/mapped address */
- u_int32_t virt32[2];
- } v;
- union
- {
- unsigned long phys64; /* physical bus address */
- u_int32_t phys32[2];
- } p;
- int reserved2[4]; /* reserved for future use */
- };
-
-/**********************************/
-/** read/write board registers **/
-/**********************************/
-
-/* routine/ioctl: wancfg_read_vec() - SBE_IOC_READ_VEC */
-/* routine/ioctl: wancfg_write_vec() - SBE_IOC_WRITE_VEC */
-
- struct sbecom_wrt_vec
- {
- u_int32_t reg;
- u_int32_t data;
- };
-
-#define C1T3_CHIP_MSCC_32 0x01000000
-#define C1T3_CHIP_TECT3_8 0x02000000
-#define C1T3_CHIP_CPLD_8 0x03000000
-#define C1T3_CHIP_EEPROM_8 0x04000000
-
-#define W256T3_CHIP_MUSYCC_32 0x02000000
-#define W256T3_CHIP_TEMUX_8 0x10000000
-#define W256T3_CHIP_T8110_8 0x20000000
-#define W256T3_CHIP_T8110_32 0x22000000
-#define W256T3_CHIP_CPLD_8 0x30000000
-#define W256T3_CHIP_EEPROM_8 0x40000000
-
-
-/**********************************/
-/** read write port parameters **/
-/**********************************/
-
-/* routine/ioctl: wancfg_getset_port_param() - SBE_IOC_PORT_GET */
-/* routine/ioctl: wancfg_set_port_param() - SBE_IOC_PORT_SET */
-
-/* NOTE: this structure supports hardware which supports individual per/port control */
-
-struct sbecom_port_param
-{
- u_int8_t portnum;
- u_int8_t port_mode; /* variations of T1 or E1 mode */
- u_int8_t portStatus;
- u_int8_t portP; /* more port parameters (clock source - 0x80;
- * and LBO - 0xf; */
- /* bits 0x70 are reserved for future use ) */
-#ifdef SBE_PMCC4_ENABLE
- u_int32_t hypersize; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
-#endif
- int reserved[3-1]; /* reserved for future use */
- int _res[4];
-};
-
-#define CFG_CLK_PORT_MASK 0x80 /* Loop timing */
-#define CFG_CLK_PORT_INTERNAL 0x80 /* Loop timing */
-#define CFG_CLK_PORT_EXTERNAL 0x00 /* Loop timing */
-
-#define CFG_LBO_MASK 0x0F
-#define CFG_LBO_unk 0 /* <not defined> */
-#define CFG_LBO_LH0 1 /* T1 Long Haul (default) */
-#define CFG_LBO_LH7_5 2 /* T1 Long Haul */
-#define CFG_LBO_LH15 3 /* T1 Long Haul */
-#define CFG_LBO_LH22_5 4 /* T1 Long Haul */
-#define CFG_LBO_SH110 5 /* T1 Short Haul */
-#define CFG_LBO_SH220 6 /* T1 Short Haul */
-#define CFG_LBO_SH330 7 /* T1 Short Haul */
-#define CFG_LBO_SH440 8 /* T1 Short Haul */
-#define CFG_LBO_SH550 9 /* T1 Short Haul */
-#define CFG_LBO_SH660 10 /* T1 Short Haul */
-#define CFG_LBO_E75 11 /* E1 75 Ohm */
-#define CFG_LBO_E120 12 /* E1 120 Ohm (default) */
-
-
-/*************************************/
-/** read write channel parameters **/
-/*************************************/
-
-/* routine/ioctl: wancfg_getset_chan_param() - SBE_IOC_CHAN_GET */
-/* routine/ioctl: wancfg_set_chan_param() - SBE_IOC_CHAN_SET */
-
-/* NOTE: this structure supports hardware which supports individual per/channel control */
-
- struct sbecom_chan_param
- {
- u_int32_t channum; /* 0: */
-#ifdef SBE_PMCC4_ENABLE
- u_int32_t card; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
- u_int32_t port; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */
- u_int8_t bitmask[32];
-#endif
- u_int32_t intr_mask; /* 4: interrupt mask, specify ored
- * (SS7_)INTR_* to disable */
- u_int8_t status; /* 8: channel transceiver status (TX_ENABLED,
- * RX_ENABLED) */
- u_int8_t chan_mode; /* 9: protocol mode */
- u_int8_t idlecode; /* A: idle code, in (FLAG_7E, FLAG_FF,
- * FLAG_00) */
- u_int8_t pad_fill_count; /* B: pad fill count (1-127), 0 - pad
- * fill disabled */
- u_int8_t data_inv; /* C: channel data inversion selection */
- u_int8_t mode_56k; /* D: 56kbps mode */
- u_int8_t reserved[2 + 8]; /* E: */
- };
-
-/* SS7 interrupt signals <intr_mask> */
-#define SS7_INTR_SFILT 0x00000020
-#define SS7_INTR_SDEC 0x00000040
-#define SS7_INTR_SINC 0x00000080
-#define SS7_INTR_SUERR 0x00000100
-/* Other interrupts that can be masked */
-#define INTR_BUFF 0x00000002
-#define INTR_EOM 0x00000004
-#define INTR_MSG 0x00000008
-#define INTR_IDLE 0x00000010
-
-/* transceiver status flags <status> */
-#define TX_ENABLED 0x01
-#define RX_ENABLED 0x02
-
-/* Protocol modes <mode> */
-#define CFG_CH_PROTO_TRANS 0
-#define CFG_CH_PROTO_SS7 1
-#define CFG_CH_PROTO_HDLC_FCS16 2
-#define CFG_CH_PROTO_HDLC_FCS32 3
-#define CFG_CH_PROTO_ISLP_MODE 4
-
-/* Possible idle code assignments <idlecode> */
-#define CFG_CH_FLAG_7E 0
-#define CFG_CH_FLAG_FF 1
-#define CFG_CH_FLAG_00 2
-
-/* data inversion selection <data_inv> */
-#define CFG_CH_DINV_NONE 0x00
-#define CFG_CH_DINV_RX 0x01
-#define CFG_CH_DINV_TX 0x02
-
-
-/* Possible resettable chipsets/functions */
-#define RESET_DEV_TEMUX 1
-#define RESET_DEV_TECT3 RESET_DEV_TEMUX
-#define RESET_DEV_PLL 2
-
-
-/*********************************************/
-/** read reset channel thruput statistics **/
-/*********************************************/
-
-/* routine/ioctl: wancfg_get_chan_stats() - SBE_IOC_CHAN_GET_STAT */
-/* routine/ioctl: wancfg_del_chan_stats() - SBE_IOC_CHAN_DEL_STAT */
-/* routine/ioctl: wancfg_get_card_chan_stats() - SBE_IOC_CARD_CHAN_STAT */
-
- struct sbecom_chan_stats
- {
- unsigned long rx_packets; /* total packets received */
- unsigned long tx_packets; /* total packets transmitted */
- unsigned long rx_bytes; /* total bytes received */
- unsigned long tx_bytes; /* total bytes transmitted */
- unsigned long rx_errors;/* bad packets received */
- unsigned long tx_errors;/* packet transmit problems */
- unsigned long rx_dropped; /* no space in linux buffers */
- unsigned long tx_dropped; /* no space available in linux */
-
- /* detailed rx_errors: */
- unsigned long rx_length_errors;
- unsigned long rx_over_errors; /* receiver ring buff overflow */
- unsigned long rx_crc_errors; /* recved pkt with crc error */
- unsigned long rx_frame_errors; /* recv'd frame alignment error */
- unsigned long rx_fifo_errors; /* recv'r fifo overrun */
- unsigned long rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- unsigned long tx_aborted_errors;
- unsigned long tx_fifo_errors;
- unsigned long tx_pending;
- };
-
-
-/****************************************/
-/** read write card level parameters **/
-/****************************************/
-
- /* NOTE: this structure supports hardware which supports per/card control */
-
- struct sbecom_card_param
- {
- u_int8_t framing_type; /* 0: CBP or M13 */
- u_int8_t loopback; /* 1: one of LOOPBACK_* */
- u_int8_t line_build_out; /* 2: boolean */
- u_int8_t receive_eq; /* 3: boolean */
- u_int8_t transmit_ones; /* 4: boolean */
- u_int8_t clock; /* 5: 0 - internal, i>0 - external (recovered
- * from framer i) */
- u_int8_t h110enable; /* 6: */
- u_int8_t disable_leds; /* 7: */
- u_int8_t reserved1; /* 8: available - old 256t3 hypersized, but
- * never used */
- u_int8_t rear_io; /* 9: rear I/O off/on */
- u_int8_t disable_tx; /* A: disable TX off/on */
- u_int8_t mute_los; /* B: mute LOS off/on */
- u_int8_t los_threshold; /* C: LOS threshold norm/low
- * (default: norm) */
- u_int8_t ds1_mode; /* D: DS1 mode T1/E1 (default: T1) */
- u_int8_t ds3_unchan; /* E: DS3 unchannelized mode off/on */
- u_int8_t reserved[1 + 16]; /* reserved for expansion - must be
- * ZERO filled */
- };
-
-/* framing types <framing_type> */
-#define FRAMING_M13 0
-#define FRAMING_CBP 1
-
-/* card level loopback options <loopback> */
-#define CFG_CARD_LOOPBACK_NONE 0x00
-#define CFG_CARD_LOOPBACK_DIAG 0x01
-#define CFG_CARD_LOOPBACK_LINE 0x02
-#define CFG_CARD_LOOPBACK_PAYLOAD 0x03
-
-/* line level loopback options <loopback> */
-#define CFG_LIU_LOOPBACK_NONE 0x00
-#define CFG_LIU_LOOPBACK_ANALOG 0x10
-#define CFG_LIU_LOOPBACK_DIGITAL 0x11
-#define CFG_LIU_LOOPBACK_REMOTE 0x12
-
-/* card level clock options <clock> */
-#define CFG_CLK_INTERNAL 0x00
-#define CFG_CLK_EXTERNAL 0x01
-
-/* legacy 256T3 loopback values */
-#define LOOPBACK_NONE 0
-#define LOOPBACK_LIU_ANALOG 1
-#define LOOPBACK_LIU_DIGITAL 2
-#define LOOPBACK_FRAMER_DS3 3
-#define LOOPBACK_FRAMER_T1 4
-#define LOOPBACK_LIU_REMOTE 5
-
-/* DS1 mode <ds1_mode> */
-#define CFG_DS1_MODE_MASK 0x0f
-#define CFG_DS1_MODE_T1 0x00
-#define CFG_DS1_MODE_E1 0x01
-#define CFG_DS1_MODE_CHANGE 0x80
-
-/* DS3 unchannelized values <ds1_unchan> */
-#define CFG_DS3_UNCHAN_MASK 0x01
-#define CFG_DS3_UNCHAN_OFF 0x00
-#define CFG_DS3_UNCHAN_ON 0x01
-
-
-/************************************/
-/** read write framer parameters **/
-/************************************/
-
-/* routine/ioctl: wancfg_get_framer() - SBE_IOC_FRAMER_GET */
-/* routine/ioctl: wancfg_set_framer() - SBE_IOC_FRAMER_SET */
-
- struct sbecom_framer_param
- {
- u_int8_t framer_num;
- u_int8_t frame_type; /* SF, ESF, E1PLAIN, E1CAS, E1CRC, E1CRC+CAS */
- u_int8_t loopback_type; /* DIGITAL, LINE, PAYLOAD */
- u_int8_t auto_alarms;/* auto alarms */
- u_int8_t reserved[12]; /* reserved for expansion - must be
- * ZERO filled */
- };
-
-/* frame types <frame_type> */
-#define CFG_FRAME_NONE 0
-#define CFG_FRAME_SF 1 /* T1 B8ZS */
-#define CFG_FRAME_ESF 2 /* T1 B8ZS */
-#define CFG_FRAME_E1PLAIN 3 /* HDB3 w/o CAS,CRC */
-#define CFG_FRAME_E1CAS 4 /* HDB3 */
-#define CFG_FRAME_E1CRC 5 /* HDB3 */
-#define CFG_FRAME_E1CRC_CAS 6 /* HDB3 */
-#define CFG_FRAME_SF_AMI 7 /* T1 AMI */
-#define CFG_FRAME_ESF_AMI 8 /* T1 AMI */
-#define CFG_FRAME_E1PLAIN_AMI 9 /* E1 AMI w/o CAS,CRC */
-#define CFG_FRAME_E1CAS_AMI 10 /* E1 AMI */
-#define CFG_FRAME_E1CRC_AMI 11 /* E1 AMI */
-#define CFG_FRAME_E1CRC_CAS_AMI 12 /* E1 AMI */
-
-#define IS_FRAME_ANY_T1(field) \
- (((field) == CFG_FRAME_NONE) || \
- ((field) == CFG_FRAME_SF) || \
- ((field) == CFG_FRAME_ESF) || \
- ((field) == CFG_FRAME_SF_AMI) || \
- ((field) == CFG_FRAME_ESF_AMI))
-
-#define IS_FRAME_ANY_T1ESF(field) \
- (((field) == CFG_FRAME_ESF) || \
- ((field) == CFG_FRAME_ESF_AMI))
-
-#define IS_FRAME_ANY_E1(field) \
- (((field) == CFG_FRAME_E1PLAIN) || \
- ((field) == CFG_FRAME_E1CAS) || \
- ((field) == CFG_FRAME_E1CRC) || \
- ((field) == CFG_FRAME_E1CRC_CAS) || \
- ((field) == CFG_FRAME_E1PLAIN_AMI) || \
- ((field) == CFG_FRAME_E1CAS_AMI) || \
- ((field) == CFG_FRAME_E1CRC_AMI) || \
- ((field) == CFG_FRAME_E1CRC_CAS_AMI))
-
-#define IS_FRAME_ANY_AMI(field) \
- (((field) == CFG_FRAME_SF_AMI) || \
- ((field) == CFG_FRAME_ESF_AMI) || \
- ((field) == CFG_FRAME_E1PLAIN_AMI) || \
- ((field) == CFG_FRAME_E1CAS_AMI) || \
- ((field) == CFG_FRAME_E1CRC_AMI) || \
- ((field) == CFG_FRAME_E1CRC_CAS_AMI))
-
-/* frame level loopback options <loopback_type> */
-#define CFG_FRMR_LOOPBACK_NONE 0
-#define CFG_FRMR_LOOPBACK_DIAG 1
-#define CFG_FRMR_LOOPBACK_LINE 2
-#define CFG_FRMR_LOOPBACK_PAYLOAD 3
-
-
-/****************************************/
-/** read reset card error statistics **/
-/****************************************/
-
-/* routine/ioctl: wancfg_get_card_stats() - SBE_IOC_CARD_GET_STAT */
-/* routine/ioctl: wancfg_del_card_stats() - SBE_IOC_CARD_DEL_STAT */
-
- struct temux_card_stats
- {
- struct temux_stats
- {
- /* TEMUX DS3 PMON counters */
- u_int32_t lcv;
- u_int32_t err_framing;
- u_int32_t febe;
- u_int32_t err_cpbit;
- u_int32_t err_parity;
- /* TEMUX DS3 FRMR status */
- u_int8_t los;
- u_int8_t oof;
- u_int8_t red;
- u_int8_t yellow;
- u_int8_t idle;
- u_int8_t ais;
- u_int8_t cbit;
- /* TEMUX DS3 FEAC receiver */
- u_int8_t feac;
- u_int8_t feac_last;
- } t;
- u_int32_t tx_pending; /* total */
- };
-
-/**************************************************************/
-
- struct wancfg
- {
- int cs, ds;
- char *p;
- };
- typedef struct wancfg wcfg_t;
-
- extern wcfg_t *wancfg_init(char *, char *);
- extern int wancfg_card_blink(wcfg_t *, int);
- extern int wancfg_ctl(wcfg_t *, int, void *, int, void *, int);
- extern int wancfg_del_card_stats(wcfg_t *);
- extern int wancfg_del_chan_stats(wcfg_t *, int);
- extern int wancfg_enable_ports(wcfg_t *, int);
- extern int wancfg_free(wcfg_t *);
- extern int wancfg_get_brdaddr(wcfg_t *, struct sbe_brd_addr *);
- extern int wancfg_get_brdinfo(wcfg_t *, struct sbe_brd_info *);
- extern int wancfg_get_card(wcfg_t *, struct sbecom_card_param *);
- extern int wancfg_get_card_chan_stats(wcfg_t *, struct sbecom_chan_stats *);
- extern int wancfg_get_card_sn(wcfg_t *);
- extern int wancfg_get_card_stats(wcfg_t *, struct temux_card_stats *);
- extern int wancfg_get_chan(wcfg_t *, int, struct sbecom_chan_param *);
- extern int wancfg_get_chan_stats(wcfg_t *, int, struct sbecom_chan_stats *);
- extern int wancfg_get_drvinfo(wcfg_t *, int, struct sbe_drv_info *);
- extern int wancfg_get_framer(wcfg_t *, int, struct sbecom_framer_param *);
- extern int wancfg_get_iid(wcfg_t *, int, struct sbe_iid_info *);
- extern int wancfg_get_sn(wcfg_t *, unsigned int *);
- extern int wancfg_read(wcfg_t *, int, struct sbecom_wrt_vec *);
- extern int wancfg_reset_device(wcfg_t *, int);
- extern int wancfg_set_card(wcfg_t *, struct sbecom_card_param *);
- extern int wancfg_set_chan(wcfg_t *, int, struct sbecom_chan_param *);
- extern int wancfg_set_framer(wcfg_t *, int, struct sbecom_framer_param *);
- extern int wancfg_set_loglevel(wcfg_t *, uint);
- extern int wancfg_write(wcfg_t *, int, struct sbecom_wrt_vec *);
-
-#ifdef NOT_YET_COMMON
- extern int wancfg_get_tsioc(wcfg_t *, struct wanc1t3_ts_hdr *, struct wanc1t3_ts_param *);
- extern int wancfg_set_tsioc(wcfg_t *, struct wanc1t3_ts_param *);
-#endif
-
-#endif /*** _INC_LIBSBEW_H_ ***/
diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c
deleted file mode 100644
index 09f3d5ca75ac..000000000000
--- a/drivers/staging/cxt1e1/linux.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-/* Copyright (C) 2007-2008 One Stop Systems
- * Copyright (C) 2003-2006 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/module.h>
-#include <linux/hdlc.h>
-#include <linux/if_arp.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/rtnetlink.h>
-#include <linux/skbuff.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4.h"
-#include "pmcc4_ioctls.h"
-#include "pmcc4_private.h"
-#include "sbeproc.h"
-
-/*******************************************************************************
- * Error out early if we have compiler trouble.
- *
- * (This section is included from the kernel's init/main.c as a friendly
- * spiderman recommendation...)
- *
- * Versions of gcc older than that listed below may actually compile and link
- * okay, but the end product can have subtle run time bugs. To avoid associated
- * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
- * too old from the very beginning.
- */
-#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
-#error Sorry, your GCC is too old. It builds incorrect kernels.
-#endif
-
-#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
-#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
-#endif
-
-/*******************************************************************************/
-
-#define CHANNAME "hdlc"
-
-/*******************************************************************/
-/* forward references */
-status_t c4_chan_work_init(mpi_t *, mch_t *);
-void musycc_wq_chan_restart(void *);
-status_t __init c4_init(ci_t *, u_char *, u_char *);
-status_t __init c4_init2(ci_t *);
-int __init c4hw_attach_all(void);
-void __init hdw_sn_get(hdw_info_t *, int);
-
-#ifdef CONFIG_SBE_PMCC4_NCOMM
-irqreturn_t c4_ebus_intr_th_handler(void *);
-
-#endif
-int c4_frame_rw(ci_t *, struct sbecom_port_param *);
-status_t c4_get_port(ci_t *, int);
-int c4_loop_port(ci_t *, int, u_int8_t);
-int c4_musycc_rw(ci_t *, struct c4_musycc_param *);
-int c4_new_chan(ci_t *, int, int, void *);
-status_t c4_set_port(ci_t *, int);
-int c4_pld_rw(ci_t *, struct sbecom_port_param *);
-void cleanup_devs(void);
-void cleanup_ioremap(void);
-status_t musycc_chan_down(ci_t *, int);
-irqreturn_t musycc_intr_th_handler(void *);
-int musycc_start_xmit(ci_t *, int, void *);
-
-extern ci_t *CI;
-extern struct s_hdw_info hdw_info[];
-
-int error_flag; /* module load error reporting */
-int cxt1e1_log_level = LOG_ERROR;
-static int log_level_default = LOG_ERROR;
-module_param(cxt1e1_log_level, int, 0444);
-
-int cxt1e1_max_mru = MUSYCC_MRU;
-static int max_mru_default = MUSYCC_MRU;
-module_param(cxt1e1_max_mru, int, 0444);
-
-int cxt1e1_max_mtu = MUSYCC_MTU;
-int max_mtu_default = MUSYCC_MTU;
-module_param(cxt1e1_max_mtu, int, 0444);
-
-int max_txdesc_used = MUSYCC_TXDESC_MIN;
-int max_txdesc_default = MUSYCC_TXDESC_MIN;
-module_param(max_txdesc_used, int, 0444);
-
-int max_rxdesc_used = MUSYCC_RXDESC_MIN;
-int max_rxdesc_default = MUSYCC_RXDESC_MIN;
-module_param(max_rxdesc_used, int, 0444);
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-void *
-getuserbychan(int channum)
-{
- mch_t *ch;
-
- ch = c4_find_chan(channum);
- return ch ? ch->user : NULL;
-}
-
-
-char *
-get_hdlc_name(hdlc_device *hdlc)
-{
- struct c4_priv *priv = hdlc->priv;
- struct net_device *dev = getuserbychan(priv->channum);
-
- return dev->name;
-}
-
-/***************************************************************************/
-#include <linux/workqueue.h>
-
-/***
- * One workqueue (wq) per port (since musycc allows simultaneous group
- * commands), with individual data for each channel:
- *
- * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using
- * create_workqueue())
- *
- * With work structure (work) statically allocated for each channel:
- *
- * mch_t -> struct work_struct ch_work; (statically allocated using ???)
- *
- ***/
-
-
-/*
- * Called by the start transmit routine when a channel TX_ENABLE is to be
- * issued. This queues the transmission start request among other channels
- * within a port's group.
- */
-void
-c4_wk_chan_restart(mch_t *ch)
-{
- mpi_t *pi = ch->up;
-
-#ifdef RLD_RESTART_DEBUG
- pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n",
- __func__, pi->portnum, ch->channum, ch);
-#endif
-
- /* create new entry w/in workqueue for this channel and let'er rip */
-
- /** queue_work(struct workqueue_struct *queue,
- ** struct work_struct *work);
- **/
- queue_work(pi->wq_port, &ch->ch_work);
-}
-
-status_t
-c4_wk_chan_init(mpi_t *pi, mch_t *ch)
-{
- /*
- * this will be used to restart a stopped channel
- */
-
- /** INIT_WORK(struct work_struct *work,
- ** void (*function)(void *),
- ** void *data);
- **/
- INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart);
- return 0; /* success */
-}
-
-status_t
-c4_wq_port_init(mpi_t *pi)
-{
-
- char name[16]; /* NOTE: name of the queue limited by system
- * to 10 characters */
- if (pi->wq_port)
- return 0; /* already initialized */
-
- /* IE pmcc4-01 */
- snprintf(name, sizeof(name), "%s%d", pi->up->devname, pi->portnum);
-
-#ifdef RLD_RESTART_DEBUG
- pr_info(">> %s: creating workqueue <%s> for Port %d.\n",
- __func__, name, pi->portnum); /* RLD DEBUG */
-#endif
- pi->wq_port = create_singlethread_workqueue(name);
- if (!pi->wq_port)
- return -ENOMEM;
- return 0; /* success */
-}
-
-void
-c4_wq_port_cleanup(mpi_t *pi)
-{
- /*
- * PORT POINT: cannot call this if WQ is statically allocated w/in
- * structure since it calls kfree(wq);
- */
- if (pi->wq_port) {
- destroy_workqueue(pi->wq_port); /* this also calls
- * flush_workqueue() */
- pi->wq_port = NULL;
- }
-}
-
-/***************************************************************************/
-
-static irqreturn_t
-c4_linux_interrupt(int irq, void *dev_instance)
-{
- struct net_device *ndev = dev_instance;
-
- return musycc_intr_th_handler(netdev_priv(ndev));
-}
-
-
-#ifdef CONFIG_SBE_PMCC4_NCOMM
-static irqreturn_t
-c4_ebus_interrupt(int irq, void *dev_instance)
-{
- struct net_device *ndev = dev_instance;
-
- return c4_ebus_intr_th_handler(netdev_priv(ndev));
-}
-#endif
-
-
-static int
-void_open(struct net_device *ndev)
-{
- pr_info("%s: trying to open master device !\n", ndev->name);
- return -1;
-}
-
-
-static int
-chan_open(struct net_device *ndev)
-{
- hdlc_device *hdlc = dev_to_hdlc(ndev);
- const struct c4_priv *priv = hdlc->priv;
- int ret;
-
- ret = hdlc_open(ndev);
- if (ret) {
- pr_info("hdlc_open failure, err %d.\n", ret);
- return ret;
- }
-
- ret = c4_chan_up(priv->ci, priv->channum);
- if (ret < 0)
- return ret;
- try_module_get(THIS_MODULE);
- netif_start_queue(ndev);
- return 0; /* no error = success */
-}
-
-
-static int
-chan_close(struct net_device *ndev)
-{
- hdlc_device *hdlc = dev_to_hdlc(ndev);
- const struct c4_priv *priv = hdlc->priv;
-
- netif_stop_queue(ndev);
- musycc_chan_down((ci_t *) 0, priv->channum);
- hdlc_close(ndev);
- module_put(THIS_MODULE);
- return 0;
-}
-
-
-static int
-chan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- return hdlc_ioctl(dev, ifr, cmd);
-}
-
-
-static int
-chan_attach_noop(struct net_device *ndev, unsigned short foo_1,
- unsigned short foo_2)
-{
- /* our driver has nothing to do here, show's
- * over, go home
- */
- return 0;
-}
-
-
-static struct net_device_stats *
-chan_get_stats(struct net_device *ndev)
-{
- mch_t *ch;
- struct net_device_stats *nstats;
- struct sbecom_chan_stats *stats;
- int channum;
-
- {
- struct c4_priv *priv;
-
- priv = (struct c4_priv *)dev_to_hdlc(ndev)->priv;
- channum = priv->channum;
- }
-
- ch = c4_find_chan(channum);
- if (ch == NULL)
- return NULL;
-
- nstats = &ndev->stats;
- stats = &ch->s;
-
- memset(nstats, 0, sizeof(struct net_device_stats));
- nstats->rx_packets = stats->rx_packets;
- nstats->tx_packets = stats->tx_packets;
- nstats->rx_bytes = stats->rx_bytes;
- nstats->tx_bytes = stats->tx_bytes;
- nstats->rx_errors = stats->rx_length_errors +
- stats->rx_over_errors +
- stats->rx_crc_errors +
- stats->rx_frame_errors +
- stats->rx_fifo_errors +
- stats->rx_missed_errors;
- nstats->tx_errors = stats->tx_dropped +
- stats->tx_aborted_errors +
- stats->tx_fifo_errors;
- nstats->rx_dropped = stats->rx_dropped;
- nstats->tx_dropped = stats->tx_dropped;
-
- nstats->rx_length_errors = stats->rx_length_errors;
- nstats->rx_over_errors = stats->rx_over_errors;
- nstats->rx_crc_errors = stats->rx_crc_errors;
- nstats->rx_frame_errors = stats->rx_frame_errors;
- nstats->rx_fifo_errors = stats->rx_fifo_errors;
- nstats->rx_missed_errors = stats->rx_missed_errors;
-
- nstats->tx_aborted_errors = stats->tx_aborted_errors;
- nstats->tx_fifo_errors = stats->tx_fifo_errors;
-
- return nstats;
-}
-
-
-static ci_t *
-get_ci_by_dev(struct net_device *ndev)
-{
- return (ci_t *)(netdev_priv(ndev));
-}
-
-
-static int
-c4_linux_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
- const struct c4_priv *priv;
- int rval;
-
- hdlc_device *hdlc = dev_to_hdlc(ndev);
-
- priv = hdlc->priv;
-
- rval = musycc_start_xmit(priv->ci, priv->channum, skb);
- return rval;
-}
-
-static const struct net_device_ops chan_ops = {
- .ndo_open = chan_open,
- .ndo_stop = chan_close,
- .ndo_start_xmit = c4_linux_xmit,
- .ndo_do_ioctl = chan_dev_ioctl,
- .ndo_get_stats = chan_get_stats,
-};
-
-static struct net_device *
-create_chan(struct net_device *ndev, ci_t *ci,
- struct sbecom_chan_param *cp)
-{
- hdlc_device *hdlc;
- struct net_device *dev;
- hdw_info_t *hi;
- int ret;
-
- if (c4_find_chan(cp->channum))
- return NULL; /* channel already exists */
-
- {
- struct c4_priv *priv;
-
- /* allocate then fill in private data structure */
- priv = kzalloc(sizeof(struct c4_priv), GFP_KERNEL);
- if (!priv) {
- pr_warning("%s: no memory for net_device !\n",
- ci->devname);
- return NULL;
- }
- dev = alloc_hdlcdev(priv);
- if (!dev) {
- pr_warning("%s: no memory for hdlc_device !\n",
- ci->devname);
- kfree(priv);
- return NULL;
- }
- priv->ci = ci;
- priv->channum = cp->channum;
- }
-
- hdlc = dev_to_hdlc(dev);
-
- dev->base_addr = 0; /* not I/O mapped */
- dev->irq = ndev->irq;
- dev->type = ARPHRD_RAWHDLC;
- *dev->name = 0; /* default ifconfig name = "hdlc" */
-
- hi = (hdw_info_t *)ci->hdw_info;
- if (hi->mfg_info_sts == EEPROM_OK) {
- switch (hi->promfmt) {
- case PROM_FORMAT_TYPE1:
- memcpy(dev->dev_addr,
- (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
- break;
- case PROM_FORMAT_TYPE2:
- memcpy(dev->dev_addr,
- (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
- break;
- default:
- memset(dev->dev_addr, 0, 6);
- break;
- }
- } else
- memset(dev->dev_addr, 0, 6);
-
- hdlc->xmit = c4_linux_xmit;
-
- dev->netdev_ops = &chan_ops;
- /*
- * The native hdlc stack calls this 'attach' routine during
- * hdlc_raw_ioctl(), passing parameters for line encoding and parity.
- * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach'
- * routine is actually registered or not, we supply a dummy routine which
- * does nothing (since encoding and parity are setup for our driver via a
- * special configuration application).
- */
-
- hdlc->attach = chan_attach_noop;
-
- /* needed due to Ioctl calling sequence */
- rtnl_unlock();
- ret = register_hdlc_device(dev);
- /* NOTE: <stats> setting must occur AFTER registration in order to "take" */
- dev->tx_queue_len = MAX_DEFAULT_IFQLEN;
-
- /* needed due to Ioctl calling sequence */
- rtnl_lock();
- if (ret) {
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: create_chan[%d] registration error = %d.\n",
- ci->devname, cp->channum, ret);
- /* cleanup */
- free_netdev(dev);
- /* failed to register */
- return NULL;
- }
- return dev;
-}
-
-
-/* the idea here is to get port information and pass it back (using pointer) */
-static status_t
-do_get_port(struct net_device *ndev, void *data)
-{
- int ret;
- ci_t *ci; /* ci stands for card information */
- struct sbecom_port_param pp;/* copy data to kernel land */
-
- if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- if (pp.portnum >= MUSYCC_NPORTS)
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL; /* get card info */
-
- ret = c4_get_port(ci, pp.portnum);
- if (ret < 0)
- return ret;
- if (copy_to_user(data, &ci->port[pp.portnum].p,
- sizeof(struct sbecom_port_param)))
- return -EFAULT;
- return 0;
-}
-
-/* this function copys the user data and then calls the real action function */
-static status_t
-do_set_port(struct net_device *ndev, void *data)
-{
- ci_t *ci; /* ci stands for card information */
- struct sbecom_port_param pp;/* copy data to kernel land */
-
- if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- if (pp.portnum >= MUSYCC_NPORTS)
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL; /* get card info */
-
- if (pp.portnum >= ci->max_port) /* sanity check */
- return -ENXIO;
-
- memcpy(&ci->port[pp.portnum].p, &pp, sizeof(struct sbecom_port_param));
- return c4_set_port(ci, pp.portnum);
-}
-
-/* work the port loopback mode as per directed */
-static status_t
-do_port_loop(struct net_device *ndev, void *data)
-{
- struct sbecom_port_param pp;
- ci_t *ci;
-
- if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- return c4_loop_port(ci, pp.portnum, pp.port_mode);
-}
-
-/* set the specified register with the given value / or just read it */
-static status_t
-do_framer_rw(struct net_device *ndev, void *data)
-{
- struct sbecom_port_param pp;
- ci_t *ci;
- int ret;
-
- if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- ret = c4_frame_rw(ci, &pp);
- if (ret < 0)
- return ret;
- if (copy_to_user(data, &pp, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- return 0;
-}
-
-/* set the specified register with the given value / or just read it */
-static status_t
-do_pld_rw(struct net_device *ndev, void *data)
-{
- struct sbecom_port_param pp;
- ci_t *ci;
- int ret;
-
- if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
-
- ret = c4_pld_rw(ci, &pp);
- if (ret)
- return ret;
- if (copy_to_user(data, &pp, sizeof(struct sbecom_port_param)))
- return -EFAULT;
- return 0;
-}
-
-/* set the specified register with the given value / or just read it */
-static status_t
-do_musycc_rw(struct net_device *ndev, void *data)
-{
- struct c4_musycc_param mp;
- ci_t *ci;
- int ret;
-
- if (copy_from_user(&mp, data, sizeof(struct c4_musycc_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- ret = c4_musycc_rw(ci, &mp);
- if (ret < 0)
- return ret;
- if (copy_to_user(data, &mp, sizeof(struct c4_musycc_param)))
- return -EFAULT;
- return 0;
-}
-
-static status_t
-do_get_chan(struct net_device *ndev, void *data)
-{
- struct sbecom_chan_param cp;
- int ret;
-
- if (copy_from_user(&cp, data,
- sizeof(struct sbecom_chan_param)))
- return -EFAULT;
-
- ret = c4_get_chan(cp.channum, &cp);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(data, &cp, sizeof(struct sbecom_chan_param)))
- return -EFAULT;
- return 0;
-}
-
-static status_t
-do_set_chan(struct net_device *ndev, void *data)
-{
- struct sbecom_chan_param cp;
- ci_t *ci;
-
- if (copy_from_user(&cp, data, sizeof(struct sbecom_chan_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- return c4_set_chan(cp.channum, &cp);
-}
-
-static status_t
-do_create_chan(struct net_device *ndev, void *data)
-{
- ci_t *ci;
- struct net_device *dev;
- struct sbecom_chan_param cp;
- int ret;
-
- if (copy_from_user(&cp, data, sizeof(struct sbecom_chan_param)))
- return -EFAULT;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- dev = create_chan(ndev, ci, &cp);
- if (!dev)
- return -EBUSY;
- ret = c4_new_chan(ci, cp.port, cp.channum, dev);
- if (ret < 0) {
- /* needed due to Ioctl calling sequence */
- rtnl_unlock();
- unregister_hdlc_device(dev);
- /* needed due to Ioctl calling sequence */
- rtnl_lock();
- free_netdev(dev);
- }
- return ret;
-}
-
-static status_t
-do_get_chan_stats(struct net_device *ndev, void *data)
-{
- struct c4_chan_stats_wrap ccs;
- int ret;
-
- if (copy_from_user(&ccs, data,
- sizeof(struct c4_chan_stats_wrap)))
- return -EFAULT;
-
- ret = c4_get_chan_stats(ccs.channum, &ccs.stats);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(data, &ccs,
- sizeof(struct c4_chan_stats_wrap)))
- return -EFAULT;
- return 0;
-}
-static status_t
-do_set_loglevel(struct net_device *ndev, void *data)
-{
- unsigned int cxt1e1_log_level;
-
- if (copy_from_user(&cxt1e1_log_level, data, sizeof(int)))
- return -EFAULT;
- sbecom_set_loglevel(cxt1e1_log_level);
- return 0;
-}
-
-static status_t
-do_deluser(struct net_device *ndev, int lockit)
-{
- if (ndev->flags & IFF_UP)
- return -EBUSY;
-
- {
- ci_t *ci;
- mch_t *ch;
- const struct c4_priv *priv;
- int channum;
-
- priv = (struct c4_priv *)dev_to_hdlc(ndev)->priv;
- ci = priv->ci;
- channum = priv->channum;
-
- ch = c4_find_chan(channum);
- if (ch == NULL)
- return -ENOENT;
- ch->user = NULL; /* will be freed, below */
- }
-
- /* needed if Ioctl calling sequence */
- if (lockit)
- rtnl_unlock();
- unregister_hdlc_device(ndev);
- /* needed if Ioctl calling sequence */
- if (lockit)
- rtnl_lock();
- free_netdev(ndev);
- return 0;
-}
-
-int
-do_del_chan(struct net_device *musycc_dev, void *data)
-{
- struct sbecom_chan_param cp;
- char buf[sizeof(CHANNAME) + 3];
- struct net_device *dev;
- int ret;
-
- if (copy_from_user(&cp, data,
- sizeof(struct sbecom_chan_param)))
- return -EFAULT;
- if (cp.channum > 999)
- return -EINVAL;
- snprintf(buf, sizeof(buf), CHANNAME "%d", cp.channum);
- dev = __dev_get_by_name(&init_net, buf);
- if (!dev)
- return -ENODEV;
- ret = do_deluser(dev, 1);
- if (ret)
- return ret;
- return c4_del_chan(cp.channum);
-}
-int c4_reset_board(void *);
-
-int
-do_reset(struct net_device *musycc_dev, void *data)
-{
- const struct c4_priv *priv;
- int i;
-
- for (i = 0; i < 128; i++) {
- struct net_device *ndev;
- char buf[sizeof(CHANNAME) + 3];
-
- sprintf(buf, CHANNAME "%d", i);
- ndev = __dev_get_by_name(&init_net, buf);
- if (!ndev)
- continue;
- priv = dev_to_hdlc(ndev)->priv;
-
- if ((unsigned long) (priv->ci) ==
- (unsigned long) (netdev_priv(musycc_dev))) {
- ndev->flags &= ~IFF_UP;
- netif_stop_queue(ndev);
- do_deluser(ndev, 1);
- }
- }
- return 0;
-}
-
-int
-do_reset_chan_stats(struct net_device *musycc_dev, void *data)
-{
- struct sbecom_chan_param cp;
-
- if (copy_from_user(&cp, data,
- sizeof(struct sbecom_chan_param)))
- return -EFAULT;
- return c4_del_chan_stats(cp.channum);
-}
-
-static status_t
-c4_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
-{
- ci_t *ci;
- void *data;
- int iocmd, iolen;
- status_t ret;
- static struct data {
- union {
- u_int8_t c;
- u_int32_t i;
- struct sbe_brd_info bip;
- struct sbe_drv_info dip;
- struct sbe_iid_info iip;
- struct sbe_brd_addr bap;
- struct sbecom_chan_stats stats;
- struct sbecom_chan_param param;
- struct temux_card_stats cards;
- struct sbecom_card_param cardp;
- struct sbecom_framer_param frp;
- } u;
- } arg;
-
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (cmd != SIOCDEVPRIVATE + 15)
- return -EINVAL;
- ci = get_ci_by_dev(ndev);
- if (!ci)
- return -EINVAL;
- if (ci->state != C_RUNNING)
- return -ENODEV;
- if (copy_from_user(&iocmd, ifr->ifr_data, sizeof(iocmd)))
- return -EFAULT;
-#if 0
- if (copy_from_user(&len, ifr->ifr_data + sizeof(iocmd), sizeof(len)))
- return -EFAULT;
-#endif
-
-#if 0
- pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd,
- _IOC_DIR(iocmd), _IOC_TYPE(iocmd), _IOC_NR(iocmd),
- _IOC_SIZE(iocmd));
-#endif
- iolen = _IOC_SIZE(iocmd);
- if (iolen > sizeof(arg))
- return -EFAULT;
- data = ifr->ifr_data + sizeof(iocmd);
- if (copy_from_user(&arg, data, iolen))
- return -EFAULT;
-
- ret = 0;
- switch (iocmd) {
- case SBE_IOC_PORT_GET:
- ret = do_get_port(ndev, data);
- break;
- case SBE_IOC_PORT_SET:
- ret = do_set_port(ndev, data);
- break;
- case SBE_IOC_CHAN_GET:
- ret = do_get_chan(ndev, data);
- break;
- case SBE_IOC_CHAN_SET:
- ret = do_set_chan(ndev, data);
- break;
- case C4_DEL_CHAN:
- ret = do_del_chan(ndev, data);
- break;
- case SBE_IOC_CHAN_NEW:
- ret = do_create_chan(ndev, data);
- break;
- case SBE_IOC_CHAN_GET_STAT:
- ret = do_get_chan_stats(ndev, data);
- break;
- case SBE_IOC_LOGLEVEL:
- ret = do_set_loglevel(ndev, data);
- break;
- case SBE_IOC_RESET_DEV:
- ret = do_reset(ndev, data);
- break;
- case SBE_IOC_CHAN_DEL_STAT:
- ret = do_reset_chan_stats(ndev, data);
- break;
- case C4_LOOP_PORT:
- ret = do_port_loop(ndev, data);
- break;
- case C4_RW_FRMR:
- ret = do_framer_rw(ndev, data);
- break;
- case C4_RW_MSYC:
- ret = do_musycc_rw(ndev, data);
- break;
- case C4_RW_PLD:
- ret = do_pld_rw(ndev, data);
- break;
- case SBE_IOC_IID_GET:
- ret = (iolen == sizeof(struct sbe_iid_info)) ?
- c4_get_iidinfo(ci, &arg.u.iip) : -EFAULT;
- if (ret == 0) /* no error, copy data */
- if (copy_to_user(data, &arg, iolen))
- return -EFAULT;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static const struct net_device_ops c4_ops = {
- .ndo_open = void_open,
- .ndo_start_xmit = c4_linux_xmit,
- .ndo_do_ioctl = c4_ioctl,
-};
-
-static void c4_setup(struct net_device *dev)
-{
- dev->type = ARPHRD_VOID;
- dev->netdev_ops = &c4_ops;
-}
-
-struct net_device *__init
-c4_add_dev(hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
- int irq0, int irq1)
-{
- struct net_device *ndev;
- ci_t *ci;
-
- ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup);
- if (!ndev) {
- pr_warning("%s: no memory for struct net_device !\n",
- hi->devname);
- error_flag = -ENOMEM;
- return NULL;
- }
- ci = (ci_t *)(netdev_priv(ndev));
- ndev->irq = irq0;
-
- ci->hdw_info = hi;
- ci->state = C_INIT; /* mark as hardware not available */
- ci->next = c4_list;
- c4_list = ci;
- ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
-
- if (!CI)
- CI = ci; /* DEBUG, only board 0 usage */
-
- strcpy(ci->devname, hi->devname);
-
- /* tasklet */
-#if defined(SBE_ISR_TASKLET)
- tasklet_init(&ci->ci_musycc_isr_tasklet,
- (void (*) (unsigned long)) musycc_intr_bh_tasklet,
- (unsigned long) ci);
-
- if (atomic_read(&ci->ci_musycc_isr_tasklet.count) == 0)
- tasklet_disable_nosync(&ci->ci_musycc_isr_tasklet);
-#elif defined(SBE_ISR_IMMEDIATE)
- ci->ci_musycc_isr_tq.routine = (void *)(unsigned long)musycc_intr_bh_tasklet;
- ci->ci_musycc_isr_tq.data = ci;
-#endif
-
-
- if (register_netdev(ndev) ||
- (c4_init(ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS)) {
- kfree(netdev_priv(ndev));
- kfree(ndev);
- error_flag = -ENODEV;
- return NULL;
- }
- /*************************************************************
- * int request_irq(unsigned int irq,
- * void (*handler)(int, void *, struct pt_regs *),
- * unsigned long flags, const char *dev_name, void *dev_id);
- * wherein:
- * irq -> The interrupt number that is being requested.
- * handler -> Pointer to handling function being installed.
- * flags -> A bit mask of options related to interrupt management.
- * dev_name -> String used in /proc/interrupts to show owner of interrupt.
- * dev_id -> Pointer (for shared interrupt lines) to point to its own
- * private data area (to identify which device is interrupting).
- *
- * extern void free_irq(unsigned int irq, void *dev_id);
- **************************************************************/
-
- if (request_irq(irq0, &c4_linux_interrupt,
- IRQF_SHARED,
- ndev->name, ndev)) {
- pr_warning("%s: MUSYCC could not get irq: %d\n",
- ndev->name, irq0);
- unregister_netdev(ndev);
- kfree(netdev_priv(ndev));
- kfree(ndev);
- error_flag = -EIO;
- return NULL;
- }
-#ifdef CONFIG_SBE_PMCC4_NCOMM
- if (request_irq(irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev)) {
- pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1);
- unregister_netdev(ndev);
- free_irq(irq0, ndev);
- kfree(netdev_priv(ndev));
- kfree(ndev);
- error_flag = -EIO;
- return NULL;
- }
-#endif
-
- /* setup board identification information */
-
- {
- u_int32_t tmp;
-
- /* also sets PROM format type (promfmt) for later usage */
- hdw_sn_get(hi, brdno);
-
- switch (hi->promfmt) {
- case PROM_FORMAT_TYPE1:
- memcpy(ndev->dev_addr,
- (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
- /* unaligned data acquisition */
- memcpy(&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4);
- ci->brd_id = cpu_to_be32(tmp);
- break;
- case PROM_FORMAT_TYPE2:
- memcpy(ndev->dev_addr,
- (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
- /* unaligned data acquisition */
- memcpy(&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4);
- ci->brd_id = cpu_to_be32(tmp);
- break;
- default:
- ci->brd_id = 0;
- memset(ndev->dev_addr, 0, 6);
- break;
- }
-
-#if 1
- /* requires bid to be preset */
- sbeid_set_hdwbid(ci);
-#else
- /* requires hdw_bid to be preset */
- sbeid_set_bdtype(ci);
-#endif
- }
-
-#ifdef CONFIG_PROC_FS
- sbecom_proc_brd_init(ci);
-#endif
-#if defined(SBE_ISR_TASKLET)
- tasklet_enable(&ci->ci_musycc_isr_tasklet);
-#endif
-
- error_flag = c4_init2(ci);
- if (error_flag != SBE_DRVR_SUCCESS) {
-#ifdef CONFIG_PROC_FS
- sbecom_proc_brd_cleanup(ci);
-#endif
- unregister_netdev(ndev);
- free_irq(irq1, ndev);
- free_irq(irq0, ndev);
- kfree(netdev_priv(ndev));
- kfree(ndev);
- /* failure, error_flag is set */
- return NULL;
- }
- return ndev;
-}
-
-static int __init
-c4_mod_init(void)
-{
- int rtn;
-
- rtn = c4hw_attach_all();
- if (rtn)
- return -rtn; /* installation failure - see system log */
-
- /* housekeeping notifications */
- if (cxt1e1_log_level != log_level_default)
- pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n",
- log_level_default, cxt1e1_log_level);
- if (cxt1e1_max_mru != max_mru_default)
- pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n",
- max_mru_default, cxt1e1_max_mru);
- if (cxt1e1_max_mtu != max_mtu_default)
- pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n",
- max_mtu_default, cxt1e1_max_mtu);
- if (max_rxdesc_used != max_rxdesc_default) {
- if (max_rxdesc_used > 2000)
- max_rxdesc_used = 2000; /* out-of-bounds reset */
- pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
- max_rxdesc_default, max_rxdesc_used);
- }
- if (max_txdesc_used != max_txdesc_default) {
- if (max_txdesc_used > 1000)
- max_txdesc_used = 1000; /* out-of-bounds reset */
- pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
- max_txdesc_default, max_txdesc_used);
- }
- return 0; /* installation success */
-}
-
-
- /*
- * find any still allocated hdlc registrations and unregister via call to
- * do_deluser()
- */
-
-static void __exit
-cleanup_hdlc(void)
-{
- hdw_info_t *hi;
- ci_t *ci;
- struct net_device *ndev;
- int i, j, k;
-
- for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) {
- if (hi->ndev) { /* a board has been attached */
- ci = (ci_t *)(netdev_priv(hi->ndev));
- for (j = 0; j < ci->max_port; j++)
- for (k = 0; k < MUSYCC_NCHANS; k++) {
- ndev = ci->port[j].chan[k]->user;
- if (ndev)
- do_deluser(ndev, 0);
- }
- }
- }
-}
-
-
-static void __exit
-c4_mod_remove(void)
-{
- cleanup_hdlc(); /* delete any missed channels */
- cleanup_devs();
- c4_cleanup();
- cleanup_ioremap();
- pr_info("SBE - driver removed.\n");
-}
-
-module_init(c4_mod_init);
-module_exit(c4_mod_remove);
-
-MODULE_AUTHOR("SBE Technical Services <support@sbei.com>");
-MODULE_DESCRIPTION("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
-#ifdef MODULE_LICENSE
-MODULE_LICENSE("GPL");
-#endif
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c
deleted file mode 100644
index 0bcbd8a3fc84..000000000000
--- a/drivers/staging/cxt1e1/musycc.c
+++ /dev/null
@@ -1,1720 +0,0 @@
-static unsigned int max_intcnt;
-static unsigned int max_bh;
-
-/*-----------------------------------------------------------------------------
- * musycc.c -
- *
- * Copyright (C) 2007 One Stop Systems, Inc.
- * Copyright (C) 2003-2006 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@onestopsystems.com
- * One Stop Systems, Inc. Escondido, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include "pmcc4_sysdep.h"
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4_private.h"
-#include "pmcc4.h"
-#include "musycc.h"
-
-#define sd_find_chan(ci,ch) c4_find_chan(ch)
-
-
-/*******************************************************************/
-/* global driver variables */
-extern ci_t *c4_list;
-extern int drvr_state;
-
-extern int cxt1e1_max_mru;
-extern int cxt1e1_max_mtu;
-extern int max_rxdesc_used;
-extern int max_txdesc_used;
-extern ci_t *CI; /* dummy pointr to board ZEROE's data - DEBUG
- * USAGE */
-
-
-/*******************************************************************/
-/* forward references */
-void c4_fifo_free(mpi_t *, int);
-void c4_wk_chan_restart(mch_t *);
-void musycc_bh_tx_eom(mpi_t *, int);
-int musycc_chan_up(ci_t *, int);
-status_t __init musycc_init(ci_t *);
-void musycc_intr_bh_tasklet(ci_t *);
-void musycc_serv_req(mpi_t *, u_int32_t);
-void musycc_update_timeslots(mpi_t *);
-
-/*******************************************************************/
-
-static int
-musycc_dump_rxbuffer_ring(mch_t *ch, int lockit)
-{
- struct mdesc *m;
- unsigned long flags = 0;
-
- u_int32_t status;
- int n;
-
-#ifdef RLD_DUMP_BUFDATA
- u_int32_t *dp;
- int len = 0;
-#endif
- if (lockit)
- spin_lock_irqsave(&ch->ch_rxlock, flags);
- if (ch->rxd_num == 0)
- pr_info(" ZERO receive buffers allocated for this channel.");
- else {
- FLUSH_MEM_READ();
- m = &ch->mdr[ch->rxix_irq_srv];
- for (n = ch->rxd_num; n; n--) {
- status = le32_to_cpu(m->status);
- pr_info("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
- (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ',
- (unsigned long) m, n,
- status,
- m->data ? (status & HOST_RX_OWNED ? 'H' : 'M') : '-',
- status & POLL_DISABLED ? 'P' : '-',
- status & EOBIRQ_ENABLE ? 'b' : '-',
- status & EOMIRQ_ENABLE ? 'm' : '-',
- status & LENGTH_MASK,
- le32_to_cpu(m->data), le32_to_cpu(m->next));
-#ifdef RLD_DUMP_BUFDATA
- len = status & LENGTH_MASK;
-
-#if 1
- if (m->data && (status & HOST_RX_OWNED))
-#else
- /* always dump regardless of valid RX data */
- if (m->data)
-#endif
- {
- dp = (u_int32_t *)OS_phystov((void *)(le32_to_cpu(m->data)));
- if (len >= 0x10)
- pr_info(" %x[%x]: %08X %08X %08X %08x\n",
- (u_int32_t)dp, len,
- *dp, *(dp + 1),
- *(dp + 2), *(dp + 3));
- else if (len >= 0x08)
- pr_info(" %x[%x]: %08X %08X\n",
- (u_int32_t)dp, len,
- *dp, *(dp + 1));
- else
- pr_info(" %x[%x]: %08X\n",
- (u_int32_t)dp,
- len, *dp);
- }
-#endif
- m = m->snext;
- }
- }
- pr_info("\n");
-
- if (lockit)
- spin_unlock_irqrestore(&ch->ch_rxlock, flags);
- return 0;
-}
-
-static int
-musycc_dump_txbuffer_ring(mch_t *ch, int lockit)
-{
- struct mdesc *m;
- unsigned long flags = 0;
- u_int32_t status;
- int n;
-#ifdef RLD_DUMP_BUFDATA
- u_int32_t *dp;
- int len = 0;
-#endif
-
- if (lockit)
- spin_lock_irqsave(&ch->ch_txlock, flags);
- if (ch->txd_num == 0)
- pr_info(" ZERO transmit buffers allocated for this channel.");
- else {
- FLUSH_MEM_READ();
- m = ch->txd_irq_srv;
- for (n = ch->txd_num; n; n--) {
- status = le32_to_cpu(m->status);
- pr_info("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n",
- (m == ch->txd_usr_add) ? 'F' : ' ',
- (m == ch->txd_irq_srv) ? 'L' : ' ',
- (unsigned long) m, n,
- status,
- m->data ? (status & MUSYCC_TX_OWNED ? 'M' : 'H') : '-',
- status & POLL_DISABLED ? 'P' : '-',
- status & EOBIRQ_ENABLE ? 'b' : '-',
- status & EOMIRQ_ENABLE ? 'm' : '-',
- status & LENGTH_MASK,
- le32_to_cpu(m->data), le32_to_cpu(m->next));
-#ifdef RLD_DUMP_BUFDATA
- len = status & LENGTH_MASK;
-
- if (m->data) {
- dp = (u_int32_t *)OS_phystov((void *)(le32_to_cpu(m->data)));
- if (len >= 0x10)
- pr_info(" %x[%x]: %08X %08X %08X %08x\n",
- (u_int32_t) dp, len,
- *dp, *(dp + 1),
- *(dp + 2), *(dp + 3));
- else if (len >= 0x08)
- pr_info(" %x[%x]: %08X %08X\n",
- (u_int32_t)dp, len,
- *dp, *(dp + 1));
- else
- pr_info(" %x[%x]: %08X\n",
- (u_int32_t)dp, len, *dp);
- }
-#endif
- m = m->snext;
- }
- } /* -for- */
- pr_info("\n");
-
- if (lockit)
- spin_unlock_irqrestore(&ch->ch_txlock, flags);
- return 0;
-}
-
-/*
- * The following supports a backdoor debug facility which can be used to
- * display the state of a board's channel.
- */
-
-status_t
-musycc_dump_ring(ci_t *ci, unsigned int chan)
-{
- mch_t *ch;
- int bh;
-
- if (chan >= MAX_CHANS_USED)
- return SBE_DRVR_FAIL; /* E2BIG */
-
- bh = atomic_read(&ci->bh_pending);
- pr_info(">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n",
- bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt,
- ci->intlog.drvr_intr_thcount,
- ci->intlog.drvr_intr_bhcount,
- ci->wdcount, ci->wd_notify);
- max_bh = 0; /* reset counter */
- max_intcnt = 0; /* reset counter */
-
- ch = sd_find_chan(dummy, chan);
- if (!ch) {
- pr_info(">> musycc_dump_ring: channel %d not up.\n", chan);
- return ENOENT;
- }
- pr_info(">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n",
- ci, chan, ch, ch->state,
- ch->status, ch->p.status);
- pr_info("--------------------------------\n");
- pr_info("TX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n",
- chan, ch->txd_num,
- (u_int32_t)atomic_read(&ci->tx_pending),
- (u_int32_t)atomic_read(&ch->tx_pending),
- ch->txd_required, ch->s.tx_packets);
- pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- ch->user, ch->txd_irq_srv, ch->txd_usr_add,
- sd_queue_stopped(ch->user),
- ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode);
- musycc_dump_txbuffer_ring(ch, 1);
- pr_info("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n",
- chan, ch->rxd_num, ch->rxix_irq_srv,
- &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets);
- musycc_dump_rxbuffer_ring(ch, 1);
-
- return SBE_DRVR_SUCCESS;
-}
-
-
-status_t
-musycc_dump_rings(ci_t *ci, unsigned int start_chan)
-{
- unsigned int chan;
-
- for (chan = start_chan; chan < (start_chan + 5); chan++)
- musycc_dump_ring(ci, chan);
- return SBE_DRVR_SUCCESS;
-}
-
-
-/*
- * NOTE on musycc_init_mdt(): These MUSYCC writes are only operational after
- * a MUSYCC GROUP_INIT command has been issued.
- */
-
-void
-musycc_init_mdt(mpi_t *pi)
-{
- u_int32_t *addr, cfg;
- int i;
-
- /*
- * This Idle Code insertion takes effect prior to channel's first
- * transmitted message. After that, each message contains its own Idle
- * Code information which is to be issued after the message is
- * transmitted (Ref.MUSYCC 5.2.2.3: MCENBL bit in Group Configuration
- * Descriptor).
- */
-
- addr = (u_int32_t *) ((u_long) pi->reg + MUSYCC_MDT_BASE03_ADDR);
- cfg = CFG_CH_FLAG_7E << IDLE_CODE;
-
- for (i = 0; i < 32; addr++, i++)
- pci_write_32(addr, cfg);
-}
-
-
-/* Set TX thp to the next unprocessed md */
-
-void
-musycc_update_tx_thp(mch_t *ch)
-{
- struct mdesc *md;
- unsigned long flags;
-
- spin_lock_irqsave(&ch->ch_txlock, flags);
- while (1) {
- md = ch->txd_irq_srv;
- FLUSH_MEM_READ();
- if (!md->data) {
- /* No MDs with buffers to process */
- spin_unlock_irqrestore(&ch->ch_txlock, flags);
- return;
- }
- if ((le32_to_cpu(md->status)) & MUSYCC_TX_OWNED) {
- /* this is the MD to restart TX with */
- break;
- }
- /*
- * Otherwise, we have a valid, host-owned message descriptor which
- * has been successfully transmitted and whose buffer can be freed,
- * so... process this MD, it's owned by the host. (This might give
- * as a new, updated txd_irq_srv.)
- */
- musycc_bh_tx_eom(ch->up, ch->gchan);
- }
- md = ch->txd_irq_srv;
- ch->up->regram->thp[ch->gchan] = cpu_to_le32(OS_vtophys(md));
- FLUSH_MEM_WRITE();
-
- if (ch->tx_full) {
- ch->tx_full = 0;
- ch->txd_required = 0;
- sd_enable_xmit(ch->user); /* re-enable to catch flow controlled
- * channel */
- }
- spin_unlock_irqrestore(&ch->ch_txlock, flags);
-
-#ifdef RLD_TRANS_DEBUG
- pr_info("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n",
- ch->channum, md, md->status);
-#endif
-}
-
-
-/*
- * This is the workq task executed by the OS when our queue_work() is
- * scheduled and run. It can fire off either RX or TX ACTIVATION depending
- * upon the channel's ch_start_tx and ch_start_rx variables. This routine
- * is implemented as a work queue so that the call to the service request is
- * able to sleep, awaiting an interrupt acknowledgment response (SACK) from
- * the hardware.
- */
-
-void
-musycc_wq_chan_restart(void *arg) /* channel private structure */
-{
- mch_t *ch;
- mpi_t *pi;
- struct mdesc *md;
-
-#if defined(RLD_TRANS_DEBUG) || defined(RLD_RXACT_DEBUG)
- static int hereb4 = 7;
-#endif
-
- ch = container_of(arg, struct c4_chan_info, ch_work);
- pi = ch->up;
-
-#ifdef RLD_TRANS_DEBUG
- pr_info("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n",
- ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status);
-
-#endif
-
- /**********************************/
- /** check for RX restart request **/
- /**********************************/
-
- if ((ch->ch_start_rx) && (ch->status & RX_ENABLED)) {
-
- ch->ch_start_rx = 0;
-#if defined(RLD_TRANS_DEBUG) || defined(RLD_RXACT_DEBUG)
- if (hereb4) { /* RLD DEBUG */
- hereb4--;
-#ifdef RLD_TRANS_DEBUG
- md = &ch->mdr[ch->rxix_irq_srv];
- pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
- ch->channum, ch->rxix_irq_srv, md,
- le32_to_cpu(md->status), ch->s.rx_packets);
-#elif defined(RLD_RXACT_DEBUG)
- md = &ch->mdr[ch->rxix_irq_srv];
- pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n",
- ch->channum, ch->rxix_irq_srv,
- md, le32_to_cpu(md->status),
- ch->s.rx_packets);
- musycc_dump_rxbuffer_ring(ch, 1); /* RLD DEBUG */
-#endif
- }
-#endif
- musycc_serv_req(pi, SR_CHANNEL_ACTIVATE |
- SR_RX_DIRECTION | ch->gchan);
- }
- /**********************************/
- /** check for TX restart request **/
- /**********************************/
-
- if ((ch->ch_start_tx) && (ch->status & TX_ENABLED)) {
- /* find next unprocessed message, then set TX thp to it */
- musycc_update_tx_thp(ch);
-
- md = ch->txd_irq_srv;
- if (!md) {
-#ifdef RLD_TRANS_DEBUG
- pr_info("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n",
- ch->channum);
-#endif
- } else if (md->data && ((le32_to_cpu(md->status)) &
- MUSYCC_TX_OWNED)) {
- ch->ch_start_tx = 0;
-
-#ifdef RLD_TRANS_DEBUG
- pr_info("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n",
- ch->channum, ch->txd_irq_srv,
- ch->txd_irq_srv->status, ch->s.tx_packets);
-#endif
- musycc_serv_req(pi, SR_CHANNEL_ACTIVATE |
- SR_TX_DIRECTION | ch->gchan);
- }
-#ifdef RLD_RESTART_DEBUG
- else {
- /* retain request to start until retried and we have data to xmit */
- pr_info("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n",
- ch->channum, md,
- le32_to_cpu(md->status),
- le32_to_cpu(md->data), ch->ch_start_tx);
- musycc_dump_txbuffer_ring(ch, 0);
- }
-#endif
- }
-}
-
-
- /*
- * Channel restart either fires of a workqueue request (2.6) or lodges a
- * watchdog activation sequence (2.4).
- */
-
-void
-musycc_chan_restart(mch_t *ch)
-{
-#ifdef RLD_RESTART_DEBUG
- pr_info("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n",
- ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status);
-#endif
-
- /* 2.6 - find next unprocessed message, then set TX thp to it */
-#ifdef RLD_RESTART_DEBUG
- pr_info(">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n",
- ch->channum, &ch->ch_work);
-#endif
- c4_wk_chan_restart(ch); /* work queue mechanism fires off: Ref:
- * musycc_wq_chan_restart () */
-}
-
-
-void
-rld_put_led(mpi_t *pi, u_int32_t ledval)
-{
- static u_int32_t led;
-
- if (ledval == 0)
- led = 0;
- else
- led |= ledval;
-
- /* RLD DEBUG TRANHANG */
- pci_write_32((u_int32_t *) &pi->up->cpldbase->leds, led);
-}
-
-
-#define MUSYCC_SR_RETRY_CNT 9
-
-void
-musycc_serv_req(mpi_t *pi, u_int32_t req)
-{
- volatile u_int32_t r;
- int rcnt;
-
- /*
- * PORT NOTE: Semaphore protect service loop guarantees only a single
- * operation at a time. Per MUSYCC Manual - "Issuing service requests to
- * the same channel group without first receiving ACK from each request
- * may cause the host to lose track of which service request has been
- * acknowledged."
- */
-
- SD_SEM_TAKE(&pi->sr_sem_busy, "serv"); /* only 1 thru here, per
- * group */
-
- if (pi->sr_last == req) {
-#ifdef RLD_TRANS_DEBUG
- pr_info(">> same SR, Port %d Req %x\n", pi->portnum, req);
-#endif
-
- /*
- * The most likely repeated request is the channel activation command
- * which follows the occurrence of a Transparent mode TX ONR or a
- * BUFF error. If the previous command was a CHANNEL ACTIVATE,
- * precede it with a NOOP command in order maintain coherent control
- * of this current (re)ACTIVATE.
- */
-
- r = (pi->sr_last & ~SR_GCHANNEL_MASK);
- if ((r == (SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION)) ||
- (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION))) {
-#ifdef RLD_TRANS_DEBUG
- pr_info(">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req);
-#endif
- /* allow this next request */
- SD_SEM_GIVE(&pi->sr_sem_busy);
- musycc_serv_req(pi, SR_NOOP);
- /* relock & continue w/ original req */
- SD_SEM_TAKE(&pi->sr_sem_busy, "serv");
- } else if (req == SR_NOOP) {
- /* no need to issue back-to-back
- * SR_NOOP commands at this time
- */
-#ifdef RLD_TRANS_DEBUG
- pr_info(">> same Port SR_NOOP skipped, Port %d\n",
- pi->portnum);
-#endif
- /* allow this next request */
- SD_SEM_GIVE(&pi->sr_sem_busy);
- return;
- }
- }
- rcnt = 0;
- pi->sr_last = req;
-rewrite:
- pci_write_32((u_int32_t *) &pi->reg->srd, req);
- FLUSH_MEM_WRITE();
-
- /*
- * Per MUSYCC Manual, Section 6.1,2 - "When writing an SCR service
- * request, the host must ensure at least one PCI bus clock cycle has
- * elapsed before writing another service request. To meet this minimum
- * elapsed service request write timing interval, it is recommended that
- * the host follow any SCR write with another operation which reads from
- * the same address."
- */
-
- /* adhere to write timing imposition */
- r = pci_read_32((u_int32_t *) &pi->reg->srd);
-
-
- if ((r != req) && (req != SR_CHIP_RESET) &&
- (++rcnt <= MUSYCC_SR_RETRY_CNT)) {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n",
- pi->up->devname, rcnt, req, pi->sr_last, r,
- (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f));
- /* this delay helps reduce reissue counts
- * (reason not yet researched)
- */
- OS_uwait_dummy();
- goto rewrite;
- }
- if (rcnt > MUSYCC_SR_RETRY_CNT) {
- pr_warning("%s: failed service request (#%d)= %x, group %d.\n",
- pi->up->devname, MUSYCC_SR_RETRY_CNT,
- req, pi->portnum);
- SD_SEM_GIVE(&pi->sr_sem_busy); /* allow any next request */
- return;
- }
- if (req == SR_CHIP_RESET) {
- /*
- * PORT NOTE: the CHIP_RESET command is NOT ack'd by the MUSYCC, thus
- * the upcoming delay is used. Though the MUSYCC documentation
- * suggests a read-after-write would supply the required delay, it's
- * unclear what CPU/BUS clock speeds might have been assumed when
- * suggesting this 'lack of ACK' workaround. Thus the use of uwait.
- */
- OS_uwait(100000, "icard"); /* 100ms */
- } else {
- FLUSH_MEM_READ();
- /* sleep until SACK interrupt occurs */
- SD_SEM_TAKE(&pi->sr_sem_wait, "sakack");
- }
- SD_SEM_GIVE(&pi->sr_sem_busy); /* allow any next request */
-}
-
-
-#ifdef SBE_PMCC4_ENABLE
-void
-musycc_update_timeslots(mpi_t *pi)
-{
- int i, ch;
- char e1mode = IS_FRAME_ANY_E1(pi->p.port_mode);
-
- for (i = 0; i < 32; i++) {
- int usedby = 0, last = 0, ts, j, bits[8];
-
- u_int8_t lastval = 0;
-
- if (((i == 0) && e1mode) || /* disable if E1 mode */
- ((i == 16) && ((pi->p.port_mode == CFG_FRAME_E1CRC_CAS) ||
- (pi->p.port_mode == CFG_FRAME_E1CRC_CAS_AMI))) ||
- ((i > 23) && (!e1mode))) /* disable if T1 mode */
- /* make tslot unavailable for this mode */
- pi->tsm[i] = 0xff;
- else
- /* make tslot available for assignment */
- pi->tsm[i] = 0x00;
- for (j = 0; j < 8; j++)
- bits[j] = -1;
- for (ch = 0; ch < MUSYCC_NCHANS; ch++) {
- if ((pi->chan[ch]->state == UP) &&
- (pi->chan[ch]->p.bitmask[i])) {
- usedby++;
- last = ch;
- lastval = pi->chan[ch]->p.bitmask[i];
- for (j = 0; j < 8; j++)
- if (lastval & (1 << j))
- bits[j] = ch;
- pi->tsm[i] |= lastval;
- }
- }
- if (!usedby)
- ts = 0;
- else if ((usedby == 1) && (lastval == 0xff))
- ts = (4 << 5) | last;
- else if ((usedby == 1) && (lastval == 0x7f))
- ts = (5 << 5) | last;
- else {
- int idx;
-
- if (bits[0] < 0)
- ts = (6 << 5) | (idx = last);
- else
- ts = (7 << 5) | (idx = bits[0]);
- for (j = 1; j < 8; j++) {
- pi->regram->rscm[idx * 8 + j] =
- (bits[j] < 0) ? 0 : (0x80 | bits[j]);
- pi->regram->tscm[idx * 8 + j] =
- (bits[j] < 0) ? 0 : (0x80 | bits[j]);
- }
- }
- pi->regram->rtsm[i] = ts;
- pi->regram->ttsm[i] = ts;
- }
- FLUSH_MEM_WRITE();
-
- musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
- musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
- musycc_serv_req(pi, SR_SUBCHANNEL_MAP | SR_RX_DIRECTION);
- musycc_serv_req(pi, SR_SUBCHANNEL_MAP | SR_TX_DIRECTION);
-}
-#endif
-
-
-#ifdef SBE_WAN256T3_ENABLE
- void
-musycc_update_timeslots(mpi_t *pi)
-{
- mch_t *ch;
-
- u_int8_t ts, hmask, tsen;
- int gchan;
- int i;
-
-#ifdef SBE_PMCC4_ENABLE
- hmask = (0x1f << pi->up->p.hypersize) & 0x1f;
-#endif
-#ifdef SBE_WAN256T3_ENABLE
- hmask = (0x1f << hyperdummy) & 0x1f;
-#endif
- for (i = 0; i < 128; i++) {
- gchan = ((pi->portnum * MUSYCC_NCHANS) +
- (i & hmask)) % MUSYCC_NCHANS;
- ch = pi->chan[gchan];
- if (ch->p.mode_56k)
- tsen = MODE_56KBPS;
- else
- tsen = MODE_64KBPS; /* also the default */
- ts = ((pi->portnum % 4) == (i / 32)) ? (tsen << 5) | (i & hmask) : 0;
- pi->regram->rtsm[i] = ts;
- pi->regram->ttsm[i] = ts;
- }
- FLUSH_MEM_WRITE();
- musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION);
- musycc_serv_req(pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION);
-}
-#endif
-
-
- /*
- * This routine converts a generic library channel configuration parameter
- * into a hardware specific register value (IE. MUSYCC CCD Register).
- */
-u_int32_t
-musycc_chan_proto(int proto)
-{
- int reg;
-
- switch (proto) {
- case CFG_CH_PROTO_TRANS: /* 0 */
- reg = MUSYCC_CCD_TRANS;
- break;
- case CFG_CH_PROTO_SS7: /* 1 */
- reg = MUSYCC_CCD_SS7;
- break;
- default:
- case CFG_CH_PROTO_ISLP_MODE: /* 4 */
- case CFG_CH_PROTO_HDLC_FCS16: /* 2 */
- reg = MUSYCC_CCD_HDLC_FCS16;
- break;
- case CFG_CH_PROTO_HDLC_FCS32: /* 3 */
- reg = MUSYCC_CCD_HDLC_FCS32;
- break;
- }
-
- return reg;
-}
-
-#ifdef SBE_WAN256T3_ENABLE
-static void __init
-musycc_init_port(mpi_t *pi)
-{
- pci_write_32((u_int32_t *) &pi->reg->gbp, OS_vtophys(pi->regram));
-
- pi->regram->grcd =
- __constant_cpu_to_le32(MUSYCC_GRCD_RX_ENABLE |
- MUSYCC_GRCD_TX_ENABLE |
- MUSYCC_GRCD_SF_ALIGN |
- MUSYCC_GRCD_SUBCHAN_DISABLE |
- MUSYCC_GRCD_OOFMP_DISABLE |
- MUSYCC_GRCD_COFAIRQ_DISABLE |
- MUSYCC_GRCD_MC_ENABLE |
- (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
-
- pi->regram->pcd =
- __constant_cpu_to_le32(MUSYCC_PCD_E1X4_MODE |
- MUSYCC_PCD_TXDATA_RISING |
- MUSYCC_PCD_TX_DRIVEN);
-
- /* Message length descriptor */
- pi->regram->mld = __constant_cpu_to_le32(cxt1e1_max_mru | (cxt1e1_max_mru << 16));
- FLUSH_MEM_WRITE();
-
- musycc_serv_req(pi, SR_GROUP_INIT | SR_RX_DIRECTION);
- musycc_serv_req(pi, SR_GROUP_INIT | SR_TX_DIRECTION);
-
- musycc_init_mdt(pi);
-
- musycc_update_timeslots(pi);
-}
-#endif
-
-
-status_t __init
-musycc_init(ci_t *ci)
-{
- char *regaddr; /* temp for address boundary calculations */
- int i, gchan;
-
- OS_sem_init(&ci->sem_wdbusy, SEM_AVAILABLE); /* watchdog exclusion */
-
- /*
- * Per MUSYCC manual, Section 6.3.4 - "The host must allocate a dword
- * aligned memory segment for interrupt queue pointers."
- */
-
-#define INT_QUEUE_BOUNDARY 4
-
- regaddr = kzalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t),
- GFP_KERNEL | GFP_DMA);
- if (!regaddr)
- return -ENOMEM;
- ci->iqd_p_saved = regaddr; /* save orig value for free's usage */
- /* this calculates closest boundary */
- ci->iqd_p = (u_int32_t *) ((unsigned long)(regaddr + INT_QUEUE_BOUNDARY - 1) &
- (~(INT_QUEUE_BOUNDARY - 1)));
-
- for (i = 0; i < INT_QUEUE_SIZE; i++)
- ci->iqd_p[i] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
-
- for (i = 0; i < ci->max_port; i++) {
- mpi_t *pi = &ci->port[i];
-
- /*
- * Per MUSYCC manual, Section 6.3.2 - "The host must allocate a 2KB
- * bound memory segment for Channel Group 0."
- */
-
-#define GROUP_BOUNDARY 0x800
-
- regaddr = kzalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY,
- GFP_KERNEL | GFP_DMA);
- if (!regaddr) {
- for (gchan = 0; gchan < i; gchan++) {
- pi = &ci->port[gchan];
- kfree(pi->reg);
- pi->reg = NULL;
- }
- return -ENOMEM;
- }
- pi->regram_saved = regaddr; /* save orig value for free's usage */
- /* this calculates closest boundary */
- pi->regram = (struct musycc_groupr *) ((unsigned long)(regaddr + GROUP_BOUNDARY - 1) &
- (~(GROUP_BOUNDARY - 1)));
- }
-
- /* any board centric MUSYCC commands will use group ZERO as its "home" */
- ci->regram = ci->port[0].regram;
- musycc_serv_req(&ci->port[0], SR_CHIP_RESET);
-
- pci_write_32((u_int32_t *) &ci->reg->gbp, OS_vtophys(ci->regram));
- pci_flush_write(ci);
-#ifdef CONFIG_SBE_PMCC4_NCOMM
- ci->regram->__glcd = __constant_cpu_to_le32(GCD_MAGIC);
-#else
- /* standard driver POLLS for INTB via CPLD register */
- ci->regram->__glcd = __constant_cpu_to_le32(GCD_MAGIC |
- MUSYCC_GCD_INTB_DISABLE);
-#endif
-
- ci->regram->__iqp = cpu_to_le32(OS_vtophys(&ci->iqd_p[0]));
- ci->regram->__iql = __constant_cpu_to_le32(INT_QUEUE_SIZE - 1);
- pci_write_32((u_int32_t *) &ci->reg->dacbp, 0);
- FLUSH_MEM_WRITE();
-
- ci->state = C_RUNNING; /* mark as full interrupt processing
- * available */
-
- musycc_serv_req(&ci->port[0], SR_GLOBAL_INIT); /* FIRST INTERRUPT ! */
-
- /* sanity check settable parameters */
-
- if (cxt1e1_max_mru > 0xffe) {
- pr_warning("Maximum allowed MRU exceeded, resetting %d to %d.\n",
- cxt1e1_max_mru, 0xffe);
- cxt1e1_max_mru = 0xffe;
- }
- if (cxt1e1_max_mtu > 0xffe) {
- pr_warning("Maximum allowed MTU exceeded, resetting %d to %d.\n",
- cxt1e1_max_mtu, 0xffe);
- cxt1e1_max_mtu = 0xffe;
- }
-#ifdef SBE_WAN256T3_ENABLE
- for (i = 0; i < MUSYCC_NPORTS; i++)
- musycc_init_port(&ci->port[i]);
-#endif
-
- return SBE_DRVR_SUCCESS; /* no error */
-}
-
-
-void
-musycc_bh_tx_eom(mpi_t *pi, int gchan)
-{
- mch_t *ch;
- struct mdesc *md;
-
- volatile u_int32_t status;
-
- ch = pi->chan[gchan];
- if (!ch || ch->state != UP) {
- if (cxt1e1_log_level >= LOG_ERROR)
- pr_info("%s: intr: xmit EOM on uninitialized channel %d\n",
- pi->up->devname, gchan);
- }
- if (!ch || !ch->mdt)
- return; /* note: mdt==0 implies a malloc()
- * failure w/in chan_up() routine */
-
- do {
- FLUSH_MEM_READ();
- md = ch->txd_irq_srv;
- status = le32_to_cpu(md->status);
-
- /*
- * Note: Per MUSYCC Ref 6.4.9, the host does not poll a host-owned
- * Transmit Buffer Descriptor during Transparent Mode.
- */
- if (status & MUSYCC_TX_OWNED) {
- int readCount, loopCount;
-
- /***********************************************************/
- /* HW Bug Fix */
- /* ---------- */
- /* Under certain PCI Bus loading conditions, the data */
- /* associated with an update of Shared Memory is delayed */
- /* relative to its PCI Interrupt. This is caught when */
- /* the host determines it does not yet OWN the descriptor. */
- /***********************************************************/
-
- readCount = 0;
- while (status & MUSYCC_TX_OWNED) {
- for (loopCount = 0; loopCount < 0x30; loopCount++)
- /* use call to avoid optimization
- * removal of dummy delay */
- OS_uwait_dummy();
- FLUSH_MEM_READ();
- status = le32_to_cpu(md->status);
- if (readCount++ > 40)
- break; /* don't wait any longer */
- }
- if (status & MUSYCC_TX_OWNED) {
- if (cxt1e1_log_level >= LOG_MONITOR) {
- pr_info("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n",
- pi->up->devname, pi->portnum,
- ch->channum, md, status);
- pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- ch->user, ch->txd_irq_srv,
- ch->txd_usr_add,
- sd_queue_stopped(ch->user),
- ch->ch_start_tx, ch->tx_full,
- ch->txd_free, ch->p.chan_mode);
- musycc_dump_txbuffer_ring(ch, 0);
- }
- break; /* Not our mdesc, done */
- } else {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n",
- pi->up->devname, pi->portnum,
- ch->channum, readCount,
- md, status);
- }
- }
- ch->txd_irq_srv = md->snext;
-
- md->data = 0;
- if (md->mem_token) {
- /* upcount channel */
- atomic_sub(OS_mem_token_tlen(md->mem_token),
- &ch->tx_pending);
- /* upcount card */
- atomic_sub(OS_mem_token_tlen(md->mem_token),
- &pi->up->tx_pending);
-#ifdef SBE_WAN256T3_ENABLE
- if (!atomic_read(&pi->up->tx_pending))
- wan256t3_led(pi->up, LED_TX, 0);
-#endif
- OS_mem_token_free_irq(md->mem_token);
- md->mem_token = NULL;
- }
- md->status = 0;
-#ifdef RLD_TXFULL_DEBUG
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("~~ tx_eom: tx_full %x txd_free %d -> %d\n",
- ch->tx_full, ch->txd_free, ch->txd_free + 1);
-#endif
- ++ch->txd_free;
- FLUSH_MEM_WRITE();
-
- if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) &&
- (status & EOBIRQ_ENABLE)) {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: Mode (%x) incorrect EOB status (%x)\n",
- pi->up->devname, ch->p.chan_mode,
- status);
- if ((status & EOMIRQ_ENABLE) == 0)
- break;
- }
- } while ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) &&
- ((status & EOMIRQ_ENABLE) == 0));
- /*
- * NOTE: (The above 'while' is coupled w/ previous 'do', way above.) Each
- * Transparent data buffer has the EOB bit, and NOT the EOM bit, set and
- * will furthermore have a separate IQD associated with each messages
- * buffer.
- */
-
- FLUSH_MEM_READ();
- /*
- * Smooth flow control hysterisis by maintaining task stoppage until half
- * the available write buffers are available.
- */
- if (ch->tx_full && (ch->txd_free >= (ch->txd_num / 2))) {
- /*
- * Then, only releave task stoppage if we actually have enough
- * buffers to service the last requested packet. It may require MORE
- * than half the available!
- */
- if (ch->txd_free >= ch->txd_required) {
-
-#ifdef RLD_TXFULL_DEBUG
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n",
- ch->channum,
- ch->txd_free, ch->txd_num / 2);
-#endif
- ch->tx_full = 0;
- ch->txd_required = 0;
- /* re-enable to catch flow controlled channel */
- sd_enable_xmit(ch->user);
- }
- }
-#ifdef RLD_TXFULL_DEBUG
- else if (ch->tx_full) {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n",
- ch->channum,
- ch->txd_free, ch->txd_num / 2);
- }
-#endif
-
- FLUSH_MEM_WRITE();
-}
-
-
-static void
-musycc_bh_rx_eom(mpi_t *pi, int gchan)
-{
- mch_t *ch;
- void *m, *m2;
- struct mdesc *md;
- volatile u_int32_t status;
- u_int32_t error;
-
- ch = pi->chan[gchan];
- if (!ch || ch->state != UP) {
- if (cxt1e1_log_level > LOG_ERROR)
- pr_info("%s: intr: receive EOM on uninitialized channel %d\n",
- pi->up->devname, gchan);
- return;
- }
- if (!ch->mdr)
- return; /* can this happen ? */
-
- for (;;) {
- FLUSH_MEM_READ();
- md = &ch->mdr[ch->rxix_irq_srv];
- status = le32_to_cpu(md->status);
- if (!(status & HOST_RX_OWNED))
- break; /* Not our mdesc, done */
- m = md->mem_token;
- error = (status >> 16) & 0xf;
- if (error == 0) {
- {
- m2 = OS_mem_token_alloc(cxt1e1_max_mru);
- if (m2) {
- /* substitute the mbuf+cluster */
- md->mem_token = m2;
- md->data = cpu_to_le32(OS_vtophys(
- OS_mem_token_data(m2)));
-
- /* pass the received mbuf upward */
- sd_recv_consume(m, status & LENGTH_MASK,
- ch->user);
- ch->s.rx_packets++;
- ch->s.rx_bytes += status & LENGTH_MASK;
- } else
- ch->s.rx_dropped++;
- }
- } else if (error == ERR_FCS)
- ch->s.rx_crc_errors++;
- else if (error == ERR_ALIGN)
- ch->s.rx_missed_errors++;
- else if (error == ERR_ABT)
- ch->s.rx_missed_errors++;
- else if (error == ERR_LNG)
- ch->s.rx_length_errors++;
- else if (error == ERR_SHT)
- ch->s.rx_length_errors++;
- FLUSH_MEM_WRITE();
- status = cxt1e1_max_mru;
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- status |= EOBIRQ_ENABLE;
- md->status = cpu_to_le32(status);
-
- /* Check next mdesc in the ring */
- if (++ch->rxix_irq_srv >= ch->rxd_num)
- ch->rxix_irq_srv = 0;
- FLUSH_MEM_WRITE();
- }
-}
-
-
-irqreturn_t
-musycc_intr_th_handler(void *devp)
-{
- ci_t *ci = (ci_t *) devp;
- volatile u_int32_t status, currInt = 0;
- u_int32_t nextInt, intCnt;
-
- /*
- * Hardware not available, potential interrupt hang. But since interrupt
- * might be shared, just return.
- */
- if (ci->state == C_INIT)
- return IRQ_NONE;
- /*
- * Marked as hardware available. Don't service interrupts, just clear the
- * event.
- */
-
- if (ci->state == C_IDLE) {
- status = pci_read_32((u_int32_t *) &ci->reg->isd);
-
- /* clear the interrupt but process nothing else */
- pci_write_32((u_int32_t *) &ci->reg->isd, status);
- return IRQ_HANDLED;
- }
- FLUSH_PCI_READ();
- FLUSH_MEM_READ();
-
- status = pci_read_32((u_int32_t *) &ci->reg->isd);
- nextInt = INTRPTS_NEXTINT(status);
- intCnt = INTRPTS_INTCNT(status);
- ci->intlog.drvr_intr_thcount++;
-
- /*********************************************************/
- /* HW Bug Fix */
- /* ---------- */
- /* Under certain PCI Bus loading conditions, the */
- /* MUSYCC looses the data associated with an update */
- /* of its ISD and erroneously returns the immediately */
- /* preceding 'nextInt' value. However, the 'intCnt' */
- /* value appears to be correct. By not starting service */
- /* where the 'missing' 'nextInt' SHOULD point causes */
- /* the IQD not to be serviced - the 'not serviced' */
- /* entries then remain and continue to increase as more */
- /* incorrect ISD's are encountered. */
- /*********************************************************/
-
- if (nextInt != INTRPTS_NEXTINT(ci->intlog.this_status_new)) {
- if (cxt1e1_log_level >= LOG_MONITOR) {
- pr_info("%s: note - updated ISD from %08x to %08x\n",
- ci->devname, status,
- (status & (~INTRPTS_NEXTINT_M)) |
- ci->intlog.this_status_new);
- }
- /*
- * Replace bogus status with software corrected value.
- *
- * It's not known whether, during this problem occurrence, if the
- * INTFULL bit is correctly reported or not.
- */
- status = (status & (~INTRPTS_NEXTINT_M)) |
- (ci->intlog.this_status_new);
- nextInt = INTRPTS_NEXTINT(status);
- }
- /**********************************************/
- /* Cn847x Bug Fix */
- /* -------------- */
- /* Fix for inability to write back same index */
- /* as read for a full interrupt queue. */
- /**********************************************/
-
- if (intCnt == INT_QUEUE_SIZE)
- currInt = ((intCnt - 1) + nextInt) & (INT_QUEUE_SIZE - 1);
- else
- /************************************************/
- /* Interrupt Write Location Issues */
- /* ------------------------------- */
- /* When the interrupt status descriptor is */
- /* written, the interrupt line is de-asserted */
- /* by the Cn847x. In the case of MIPS */
- /* microprocessors, this must occur at the */
- /* beginning of the interrupt handler so that */
- /* the interrupt handle is not re-entered due */
- /* to interrupt dis-assertion latency. */
- /* In the case of all other processors, this */
- /* action should occur at the end of the */
- /* interrupt handler to avoid overwriting the */
- /* interrupt queue. */
- /************************************************/
-
- if (intCnt)
- currInt = (intCnt + nextInt) & (INT_QUEUE_SIZE - 1);
- else {
- /*
- * NOTE: Servicing an interrupt whose ISD contains a count of ZERO
- * can be indicative of a Shared Interrupt chain. Our driver can be
- * called from the system's interrupt handler as a matter of the OS
- * walking the chain. As the chain is walked, the interrupt will
- * eventually be serviced by the correct driver/handler.
- */
- return IRQ_NONE;
- }
-
- ci->iqp_tailx = currInt;
-
- currInt <<= INTRPTS_NEXTINT_S;
- ci->intlog.last_status_new = ci->intlog.this_status_new;
- ci->intlog.this_status_new = currInt;
-
- if ((cxt1e1_log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M))
- pr_info("%s: Interrupt queue full condition occurred\n",
- ci->devname);
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n",
- ci->devname, &ci->reg->isd,
- status, nextInt, intCnt,
- (intCnt + nextInt) & (INT_QUEUE_SIZE - 1));
-
- FLUSH_MEM_WRITE();
-#if defined(SBE_ISR_TASKLET)
- pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
- atomic_inc(&ci->bh_pending);
- tasklet_schedule(&ci->ci_musycc_isr_tasklet);
-#elif defined(SBE_ISR_IMMEDIATE)
- pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
- atomic_inc(&ci->bh_pending);
- queue_task(&ci->ci_musycc_isr_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-#elif defined(SBE_ISR_INLINE)
- (void) musycc_intr_bh_tasklet(ci);
- pci_write_32((u_int32_t *) &ci->reg->isd, currInt);
-#endif
- return IRQ_HANDLED;
-}
-
-
-#if defined(SBE_ISR_IMMEDIATE)
-unsigned long
-#else
-void
-#endif
-musycc_intr_bh_tasklet(ci_t *ci)
-{
- mpi_t *pi;
- mch_t *ch;
- unsigned int intCnt;
- volatile u_int32_t currInt = 0;
- volatile unsigned int headx, tailx;
- int readCount, loopCount;
- int group, gchan, event, err, tx;
- u_int32_t badInt = INT_EMPTY_ENTRY;
- u_int32_t badInt2 = INT_EMPTY_ENTRY2;
-
- /*
- * Hardware not available, potential interrupt hang. But since interrupt
- * might be shared, just return.
- */
- if ((drvr_state != SBE_DRVR_AVAILABLE) || (ci->state == C_INIT)) {
-#if defined(SBE_ISR_IMMEDIATE)
- return 0L;
-#else
- return;
-#endif
- }
-#if defined(SBE_ISR_TASKLET) || defined(SBE_ISR_IMMEDIATE)
- if (drvr_state != SBE_DRVR_AVAILABLE) {
-#if defined(SBE_ISR_TASKLET)
- return;
-#elif defined(SBE_ISR_IMMEDIATE)
- return 0L;
-#endif
- }
-#elif defined(SBE_ISR_INLINE)
- /* no semaphore taken, no double checks */
-#endif
-
- ci->intlog.drvr_intr_bhcount++;
- FLUSH_MEM_READ();
- {
- unsigned int bh = atomic_read(&ci->bh_pending);
-
- max_bh = max(bh, max_bh);
- }
- atomic_set(&ci->bh_pending, 0);/* if here, no longer pending */
- while ((headx = ci->iqp_headx) != (tailx = ci->iqp_tailx)) {
- intCnt = (tailx >= headx) ? (tailx - headx) : (tailx - headx + INT_QUEUE_SIZE);
- currInt = le32_to_cpu(ci->iqd_p[headx]);
-
- max_intcnt = max(intCnt, max_intcnt); /* RLD DEBUG */
-
- /**************************************************/
- /* HW Bug Fix */
- /* ---------- */
- /* The following code checks for the condition */
- /* of interrupt assertion before interrupt */
- /* queue update. This is a problem on several */
- /* PCI-Local bridge chips found on some products. */
- /**************************************************/
-
- readCount = 0;
- if ((currInt == badInt) || (currInt == badInt2))
- ci->intlog.drvr_int_failure++;
-
- while ((currInt == badInt) || (currInt == badInt2)) {
- for (loopCount = 0; loopCount < 0x30; loopCount++)
- /* use call to avoid optimization
- * removal of dummy delay
- */
- OS_uwait_dummy();
- FLUSH_MEM_READ();
- currInt = le32_to_cpu(ci->iqd_p[headx]);
- if (readCount++ > 20)
- break;
- }
-
- /* catch failure of Bug Fix checking */
- if ((currInt == badInt) || (currInt == badInt2)) {
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n",
- ci->devname, &ci->iqd_p[headx], headx);
-
- /*
- * If the descriptor has not recovered, then leaving the EMPTY
- * entry set will not signal to the MUSYCC that this descriptor
- * has been serviced. The Interrupt Queue can then start losing
- * available descriptors and MUSYCC eventually encounters and
- * reports the INTFULL condition. Per manual, changing any bit
- * marks descriptor as available, thus the use of different
- * EMPTY_ENTRY values.
- */
-
- if (currInt == badInt)
- ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY2);
- else
- ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
- /* insure wrapness */
- ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1);
- FLUSH_MEM_WRITE();
- FLUSH_MEM_READ();
- continue;
- }
- group = INTRPT_GRP(currInt);
- gchan = INTRPT_CH(currInt);
- event = INTRPT_EVENT(currInt);
- err = INTRPT_ERROR(currInt);
- tx = currInt & INTRPT_DIR_M;
-
- ci->iqd_p[headx] = __constant_cpu_to_le32(INT_EMPTY_ENTRY);
- FLUSH_MEM_WRITE();
-
- if (cxt1e1_log_level >= LOG_DEBUG) {
- if (err != 0)
- pr_info(" %08x -> err: %2d,", currInt, err);
-
- pr_info("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n",
- event, group, gchan, tx ? 'T' : 'R');
- }
- /* notice that here we assume 1-1 group - port mapping */
- pi = &ci->port[group];
- ch = pi->chan[gchan];
- switch (event) {
- case EVE_SACK: /* Service Request Acknowledge */
- if (cxt1e1_log_level >= LOG_DEBUG) {
- volatile u_int32_t r;
-
- r = pci_read_32((u_int32_t *) &pi->reg->srd);
- pr_info("- SACK cmd: %08x (hdw= %08x)\n",
- pi->sr_last, r);
- }
- /* wake up waiting process */
- SD_SEM_GIVE(&pi->sr_sem_wait);
- break;
- case EVE_CHABT: /* Change To Abort Code (0x7e -> 0xff) */
- case EVE_CHIC: /* Change To Idle Code (0xff -> 0x7e) */
- break;
- case EVE_EOM: /* End Of Message */
- case EVE_EOB: /* End Of Buffer (Transparent mode) */
- if (tx)
- musycc_bh_tx_eom(pi, gchan);
- else
- musycc_bh_rx_eom(pi, gchan);
- /*
- * MUSYCC Interrupt Descriptor section states that EOB and EOM
- * can be combined with the NONE error (as well as others). So
- * drop thru to catch this...
- */
- case EVE_NONE:
- if (err == ERR_SHT)
- ch->s.rx_length_errors++;
- break;
- default:
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname,
- event, headx, currInt, group);
- break;
- } /* switch on event */
-
-
- /*
- * Per MUSYCC Manual, Section 6.4.8.3 [Transmit Errors], TX errors
- * are service-affecting and require action to resume normal
- * bit-level processing.
- */
-
- switch (err) {
- case ERR_ONR:
- /*
- * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], this
- * error requires Transmit channel reactivation.
- *
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], this error
- * requires Receive channel reactivation.
- */
- if (tx) {
-
- /*
- * TX ONR Error only occurs when channel is configured for
- * Transparent Mode. However, this code will catch and
- * re-activate on ANY TX ONR error.
- */
-
- /*
- * Set flag to re-enable on any next transmit attempt.
- */
- ch->ch_start_tx = CH_START_TX_ONR;
-
-#ifdef RLD_TRANS_DEBUG
- if (1 || cxt1e1_log_level >= LOG_MONITOR)
-#else
- if (cxt1e1_log_level >= LOG_MONITOR)
-#endif
- {
- pr_info("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n",
- ci->devname, ch->channum,
- ch->p.chan_mode,
- sd_queue_stopped(ch->user),
- ch->txd_free);
-#ifdef RLD_DEBUG
- /* problem = ONR on HDLC mode */
- if (ch->p.chan_mode == 2) {
- pr_info("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n",
- (u_int32_t)ch->txd_irq_srv,
- (u_int32_t)ch->txd_usr_add,
- sd_queue_stopped(ch->user),
- ch->ch_start_tx,
- ch->tx_full,
- ch->txd_free,
- ch->p.chan_mode);
- musycc_dump_txbuffer_ring(ch, 0);
- }
-#endif
- }
- } else { /* RX buffer overrun */
- /*
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors],
- * channel recovery for this RX ONR error IS required. It is
- * also suggested to increase the number of receive buffers
- * for this channel. Receive channel reactivation IS
- * required, and data has been lost.
- */
- ch->s.rx_over_errors++;
- ch->ch_start_rx = CH_START_RX_ONR;
-
- if (cxt1e1_log_level >= LOG_WARN) {
- pr_info("%s: RX buffer overflow [ONR] on channel %d, mode %x\n",
- ci->devname, ch->channum,
- ch->p.chan_mode);
-#ifdef RLD_DEBUG
- musycc_dump_rxbuffer_ring(ch, 0);
-#endif
- }
- }
- musycc_chan_restart(ch);
- break;
- case ERR_BUF:
- if (tx) {
- ch->s.tx_fifo_errors++;
- ch->ch_start_tx = CH_START_TX_BUF;
- /*
- * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors],
- * this BUFF error requires Transmit channel reactivation.
- */
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n",
- ci->devname, ch->channum,
- ch->p.chan_mode);
- } else { /* RX buffer overrun */
- ch->s.rx_over_errors++;
- /*
- * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], HDLC
- * mode requires NO recovery for this RX BUFF error is
- * required. It is suggested to increase the FIFO buffer
- * space for this channel. Receive channel reactivation is
- * not required, but data has been lost.
- */
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n",
- ci->devname, ch->channum,
- ch->p.chan_mode);
- /*
- * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors],
- * Transparent mode DOES require recovery for the RX BUFF
- * error. It is suggested to increase the FIFO buffer space
- * for this channel. Receive channel reactivation IS
- * required and data has been lost.
- */
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- ch->ch_start_rx = CH_START_RX_BUF;
- }
-
- if (tx || (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
- musycc_chan_restart(ch);
- break;
- default:
- break;
- } /* switch on err */
-
- /* Check for interrupt lost condition */
- if ((currInt & INTRPT_ILOST_M) &&
- (cxt1e1_log_level >= LOG_ERROR))
- pr_info("%s: Interrupt queue overflow - ILOST asserted\n",
- ci->devname);
- /* insure wrapness */
- ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1);
- FLUSH_MEM_WRITE();
- FLUSH_MEM_READ();
- } /* while */
- if ((cxt1e1_log_level >= LOG_MONITOR2) &&
- (ci->iqp_headx != ci->iqp_tailx)) {
- int bh;
-
- bh = atomic_read(&CI->bh_pending);
- pr_info("_bh_: late arrivals, head %d != tail %d, pending %d\n",
- ci->iqp_headx, ci->iqp_tailx, bh);
- }
-#if defined(SBE_ISR_IMMEDIATE)
- return 0L;
-#endif
- /* else, nothing returned */
-}
-
-#ifdef SBE_PMCC4_ENABLE
- status_t
-musycc_chan_down(ci_t *dummy, int channum)
-{
- mpi_t *pi;
- mch_t *ch;
- int i, gchan;
-
- ch = sd_find_chan(dummy, channum);
- if (!ch)
- return -EINVAL;
- pi = ch->up;
- gchan = ch->gchan;
-
- /* Deactivate the channel */
- musycc_serv_req(pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan);
- ch->ch_start_rx = 0;
- musycc_serv_req(pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan);
- ch->ch_start_tx = 0;
-
- if (ch->state == DOWN)
- return 0;
- ch->state = DOWN;
-
- pi->regram->thp[gchan] = 0;
- pi->regram->tmp[gchan] = 0;
- pi->regram->rhp[gchan] = 0;
- pi->regram->rmp[gchan] = 0;
- FLUSH_MEM_WRITE();
- for (i = 0; i < ch->txd_num; i++)
- if (ch->mdt[i].mem_token)
- OS_mem_token_free(ch->mdt[i].mem_token);
-
- for (i = 0; i < ch->rxd_num; i++)
- if (ch->mdr[i].mem_token)
- OS_mem_token_free(ch->mdr[i].mem_token);
-
- kfree(ch->mdr);
- ch->mdr = NULL;
- ch->rxd_num = 0;
- kfree(ch->mdt);
- ch->mdt = NULL;
- ch->txd_num = 0;
-
- musycc_update_timeslots(pi);
- c4_fifo_free(pi, ch->gchan);
-
- pi->openchans--;
- return 0;
-}
-#endif
-
-int
-musycc_start_xmit(ci_t *ci, int channum, void *mem_token)
-{
- mch_t *ch;
- struct mdesc *md;
- void *m2;
- int txd_need_cnt;
- u_int32_t len;
-
- ch = sd_find_chan(ci, channum);
- if (!ch)
- return -ENOENT;
-
- /* full interrupt processing available */
- if (ci->state != C_RUNNING)
- return -EINVAL;
- if (ch->state != UP)
- return -EINVAL;
-
- /* how else to flag unwritable state ? */
- if (!(ch->status & TX_ENABLED))
- return -EROFS;
-
-#ifdef RLD_TRANS_DEBUG
- if (1 || cxt1e1_log_level >= LOG_MONITOR2)
-#else
- if (cxt1e1_log_level >= LOG_MONITOR2)
-#endif
- {
- pr_info("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n",
- channum, ch->state, ch->ch_start_tx, ch->tx_full,
- ch->txd_free, ch->txd_required,
- sd_queue_stopped(ch->user));
- }
- /***********************************************/
- /** Determine total amount of data to be sent **/
- /***********************************************/
- m2 = mem_token;
- txd_need_cnt = 0;
- for (len = OS_mem_token_tlen(m2); len > 0;
- m2 = (void *) OS_mem_token_next(m2)) {
- if (!OS_mem_token_len(m2))
- continue;
- txd_need_cnt++;
- len -= OS_mem_token_len(m2);
- }
-
- if (txd_need_cnt == 0) {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("%s channel %d: no TX data in User buffer\n",
- ci->devname, channum);
- OS_mem_token_free(mem_token);
- return 0; /* no data to send */
- }
- /*************************************************/
- /** Are there sufficient descriptors available? **/
- /*************************************************/
- if (txd_need_cnt > ch->txd_num) { /* never enough descriptors for this
- * large a buffer */
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n",
- ch->txd_num, txd_need_cnt + 1);
- ch->s.tx_dropped++;
- OS_mem_token_free(mem_token);
- return 0;
- }
-
- /************************************************************/
- /** flow control the line if not enough descriptors remain **/
- /************************************************************/
- if (txd_need_cnt > ch->txd_free) {
- if (cxt1e1_log_level >= LOG_MONITOR2)
- pr_info("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n",
- channum, ch->txd_free,
- ch->txd_num, txd_need_cnt);
- ch->tx_full = 1;
- ch->txd_required = txd_need_cnt;
- sd_disable_xmit(ch->user);
- return -EBUSY; /* tell user to try again later */
- }
- /**************************************************/
- /** Put the user data into MUSYCC data buffer(s) **/
- /**************************************************/
- m2 = mem_token;
- md = ch->txd_usr_add; /* get current available descriptor */
-
- for (len = OS_mem_token_tlen(m2); len > 0; m2 = OS_mem_token_next(m2)) {
- int u = OS_mem_token_len(m2);
-
- if (!u)
- continue;
- len -= u;
-
- /*
- * Enable following chunks, yet wait to enable the FIRST chunk until
- * after ALL subsequent chunks are setup.
- */
- if (md != ch->txd_usr_add) /* not first chunk */
- /* transfer ownership from HOST to MUSYCC */
- u |= MUSYCC_TX_OWNED;
-
- if (len) /* not last chunk */
- u |= EOBIRQ_ENABLE;
- else if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) {
- /*
- * Per MUSYCC Ref 6.4.9 for Transparent Mode, the host must
- * always clear EOMIRQ_ENABLE in every Transmit Buffer Descriptor
- * (IE. don't set herein).
- */
- u |= EOBIRQ_ENABLE;
- } else
- u |= EOMIRQ_ENABLE; /* EOM, last HDLC chunk */
-
-
- /* last chunk in hdlc mode */
- u |= (ch->p.idlecode << IDLE_CODE);
- if (ch->p.pad_fill_count) {
- u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
- }
- /* Fill in mds on last segment, others set ZERO
- * so that entire token is removed ONLY when ALL
- * segments have been transmitted.
- */
- md->mem_token = len ? NULL : mem_token;
-
- md->data = cpu_to_le32(OS_vtophys(OS_mem_token_data(m2)));
- FLUSH_MEM_WRITE();
- md->status = cpu_to_le32(u);
- --ch->txd_free;
- md = md->snext;
- }
- FLUSH_MEM_WRITE();
-
-
- /*
- * Now transfer ownership of first chunk from HOST to MUSYCC in order to
- * fire-off this XMIT.
- */
- ch->txd_usr_add->status |= __constant_cpu_to_le32(MUSYCC_TX_OWNED);
- FLUSH_MEM_WRITE();
- ch->txd_usr_add = md;
-
- len = OS_mem_token_tlen(mem_token);
- atomic_add(len, &ch->tx_pending);
- atomic_add(len, &ci->tx_pending);
- ch->s.tx_packets++;
- ch->s.tx_bytes += len;
- /*
- * If an ONR was seen, then channel requires poking to restart
- * transmission.
- */
- if (ch->ch_start_tx)
- musycc_chan_restart(ch);
-#ifdef SBE_WAN256T3_ENABLE
- wan256t3_led(ci, LED_TX, LEDV_G);
-#endif
- return 0;
-}
-
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h
deleted file mode 100644
index 56fb42f0f64e..000000000000
--- a/drivers/staging/cxt1e1/musycc.h
+++ /dev/null
@@ -1,427 +0,0 @@
-#ifndef _INC_MUSYCC_H_
-#define _INC_MUSYCC_H_
-
-/*-----------------------------------------------------------------------------
- * musycc.h - Multichannel Synchronous Communications Controller
- * CN8778/8474A/8472A/8471A
- *
- * Copyright (C) 2002-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-
-#define VINT8 volatile u_int8_t
-#define VINT32 volatile u_int32_t
-
-#include "pmcc4_defs.h"
-
-
-/*------------------------------------------------------------------------
-// Vendor, Board Identification definitions
-//------------------------------------------------------------------------
-*/
-
-#define PCI_VENDOR_ID_CONEXANT 0x14f1
-#define PCI_DEVICE_ID_CN8471 0x8471
-#define PCI_DEVICE_ID_CN8472 0x8472
-#define PCI_DEVICE_ID_CN8474 0x8474
-#define PCI_DEVICE_ID_CN8478 0x8478
-#define PCI_DEVICE_ID_CN8500 0x8500
-#define PCI_DEVICE_ID_CN8501 0x8501
-#define PCI_DEVICE_ID_CN8502 0x8502
-#define PCI_DEVICE_ID_CN8503 0x8503
-
-#define INT_QUEUE_SIZE MUSYCC_NIQD
-
-/* RAM image of MUSYCC registers laid out as a C structure */
-struct musycc_groupr {
- VINT32 thp[32]; /* Transmit Head Pointer [5-29] */
- VINT32 tmp[32]; /* Transmit Message Pointer [5-30] */
- VINT32 rhp[32]; /* Receive Head Pointer [5-29] */
- VINT32 rmp[32]; /* Receive Message Pointer [5-30] */
- VINT8 ttsm[128]; /* Time Slot Map [5-22] */
- VINT8 tscm[256]; /* Subchannel Map [5-24] */
- VINT32 tcct[32]; /* Channel Configuration [5-26] */
- VINT8 rtsm[128]; /* Time Slot Map [5-22] */
- VINT8 rscm[256]; /* Subchannel Map [5-24] */
- VINT32 rcct[32]; /* Channel Configuration [5-26] */
- VINT32 __glcd; /* Global Configuration Descriptor [5-10] */
- VINT32 __iqp; /* Interrupt Queue Pointer [5-36] */
- VINT32 __iql; /* Interrupt Queue Length [5-36] */
- VINT32 grcd; /* Group Configuration Descriptor [5-16] */
- VINT32 mpd; /* Memory Protection Descriptor [5-18] */
- VINT32 mld; /* Message Length Descriptor [5-20] */
- VINT32 pcd; /* Port Configuration Descriptor [5-19] */
-};
-
-/* hardware MUSYCC registers laid out as a C structure */
-struct musycc_globalr {
- VINT32 gbp; /* Group Base Pointer */
- VINT32 dacbp; /* Dual Address Cycle Base Pointer */
- VINT32 srd; /* Service Request Descriptor */
- VINT32 isd; /* Interrupt Service Descriptor */
- /*
- * adjust __thp due to above 4 registers, which are not contained
- * within musycc_groupr[]. All __XXX[] are just place holders,
- * anyhow.
- */
- VINT32 __thp[32 - 4]; /* Transmit Head Pointer [5-29] */
- VINT32 __tmp[32]; /* Transmit Message Pointer [5-30] */
- VINT32 __rhp[32]; /* Receive Head Pointer [5-29] */
- VINT32 __rmp[32]; /* Receive Message Pointer [5-30] */
- VINT8 ttsm[128]; /* Time Slot Map [5-22] */
- VINT8 tscm[256]; /* Subchannel Map [5-24] */
- VINT32 tcct[32]; /* Channel Configuration [5-26] */
- VINT8 rtsm[128]; /* Time Slot Map [5-22] */
- VINT8 rscm[256]; /* Subchannel Map [5-24] */
- VINT32 rcct[32]; /* Channel Configuration [5-26] */
- VINT32 glcd; /* Global Configuration Descriptor [5-10] */
- VINT32 iqp; /* Interrupt Queue Pointer [5-36] */
- VINT32 iql; /* Interrupt Queue Length [5-36] */
- VINT32 grcd; /* Group Configuration Descriptor [5-16] */
- VINT32 mpd; /* Memory Protection Descriptor [5-18] */
- VINT32 mld; /* Message Length Descriptor [5-20] */
- VINT32 pcd; /* Port Configuration Descriptor [5-19] */
- VINT32 rbist; /* Receive BIST status [5-4] */
- VINT32 tbist; /* Receive BIST status [5-4] */
-};
-
-/* Global Config Descriptor bit macros */
-#define MUSYCC_GCD_ECLK_ENABLE 0x00000800 /* EBUS clock enable */
-#define MUSYCC_GCD_INTEL_SELECT 0x00000400 /* MPU type select */
-#define MUSYCC_GCD_INTA_DISABLE 0x00000008 /* PCI INTA disable */
-#define MUSYCC_GCD_INTB_DISABLE 0x00000004 /* PCI INTB disable */
-#define MUSYCC_GCD_BLAPSE 12 /* Position index for BLAPSE bit
- * field */
-#define MUSYCC_GCD_ALAPSE 8 /* Position index for ALAPSE bit
- * field */
-#define MUSYCC_GCD_ELAPSE 4 /* Position index for ELAPSE bit
- * field */
-#define MUSYCC_GCD_PORTMAP_3 3 /* Reserved */
-#define MUSYCC_GCD_PORTMAP_2 2 /* Port 0=>Grp 0,1,2,3; Port 1=>Grp
- * 4,5,6,7 */
-#define MUSYCC_GCD_PORTMAP_1 1 /* Port 0=>Grp 0,1; Port 1=>Grp 2,3,
- * etc... */
-#define MUSYCC_GCD_PORTMAP_0 0 /* Port 0=>Grp 0; Port 1=>Grp 2,
- * etc... */
-
-/* and board specific assignments... */
-#ifdef SBE_WAN256T3_ENABLE
-#define BLAPSE_VAL 0
-#define ALAPSE_VAL 0
-#define ELAPSE_VAL 7
-#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_2
-#endif
-
-#ifdef SBE_PMCC4_ENABLE
-#define BLAPSE_VAL 7
-#define ALAPSE_VAL 3
-#define ELAPSE_VAL 7
-#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_0
-#endif
-
-#define GCD_MAGIC (((BLAPSE_VAL)<<(MUSYCC_GCD_BLAPSE)) | \
- ((ALAPSE_VAL)<<(MUSYCC_GCD_ALAPSE)) | \
- ((ELAPSE_VAL)<<(MUSYCC_GCD_ELAPSE)) | \
- (MUSYCC_GCD_ECLK_ENABLE) | PORTMAP_VAL)
-
-/* Group Config Descriptor bit macros */
-#define MUSYCC_GRCD_RX_ENABLE 0x00000001 /* Enable receive processing */
-#define MUSYCC_GRCD_TX_ENABLE 0x00000002 /* Enable transmit processing */
-#define MUSYCC_GRCD_SUBCHAN_DISABLE 0x00000004 /* Master disable for
- * subchanneling */
-#define MUSYCC_GRCD_OOFMP_DISABLE 0x00000008 /* Out of Frame message
- * processing disabled all
- * channels */
-#define MUSYCC_GRCD_OOFIRQ_DISABLE 0x00000010 /* Out of Frame/In Frame irqs
- * disabled */
-#define MUSYCC_GRCD_COFAIRQ_DISABLE 0x00000020 /* Change of Frame Alignment
- * irq disabled */
-#define MUSYCC_GRCD_INHRBSD 0x00000100 /* Receive Buffer Status
- * overwrite disabled */
-#define MUSYCC_GRCD_INHTBSD 0x00000200 /* Transmit Buffer Status
- * overwrite disabled */
-#define MUSYCC_GRCD_SF_ALIGN 0x00008000 /* External frame sync */
-#define MUSYCC_GRCD_MC_ENABLE 0x00000040 /* Message configuration bits
- * copy enable. Conexant sez
- * turn this on */
-#define MUSYCC_GRCD_POLLTH_16 0x00000001 /* Poll every 16th frame */
-#define MUSYCC_GRCD_POLLTH_32 0x00000002 /* Poll every 32nd frame */
-#define MUSYCC_GRCD_POLLTH_64 0x00000003 /* Poll every 64th frame */
-#define MUSYCC_GRCD_POLLTH_SHIFT 10 /* Position index for poll throttle
- * bit field */
-#define MUSYCC_GRCD_SUERM_THRESH_SHIFT 16 /* Position index for SUERM
- * count threshold */
-
-/* Port Config Descriptor bit macros */
-#define MUSYCC_PCD_E1X2_MODE 2 /* Port mode in bits 0-2. T1 and E1 */
-#define MUSYCC_PCD_E1X4_MODE 3 /* are defined in cn847x.h */
-#define MUSYCC_PCD_NX64_MODE 4
-#define MUSYCC_PCD_TXDATA_RISING 0x00000010 /* Sample Tx data on TCLK
- * rising edge */
-#define MUSYCC_PCD_TXSYNC_RISING 0x00000020 /* Sample Tx frame sync on
- * TCLK rising edge */
-#define MUSYCC_PCD_RXDATA_RISING 0x00000040 /* Sample Rx data on RCLK
- * rising edge */
-#define MUSYCC_PCD_RXSYNC_RISING 0x00000080 /* Sample Rx frame sync on
- * RCLK rising edge */
-#define MUSYCC_PCD_ROOF_RISING 0x00000100 /* Sample Rx Out Of Frame
- * signal on RCLK rising edge */
-#define MUSYCC_PCD_TX_DRIVEN 0x00000200 /* No mapped timeslots causes
- * logic 1 on output, else
- * tristate */
-#define MUSYCC_PCD_PORTMODE_MASK 0xfffffff8 /* For changing the port mode
- * between E1 and T1 */
-
-/* Time Slot Descriptor bit macros */
-#define MUSYCC_TSD_MODE_64KBPS 4
-#define MUSYCC_TSD_MODE_56KBPS 5
-#define MUSYCC_TSD_SUBCHANNEL_WO_FIRST 6
-#define MUSYCC_TSD_SUBCHANNEL_WITH_FIRST 7
-
-/* Message Descriptor bit macros */
-#define MUSYCC_MDT_BASE03_ADDR 0x00006000
-
-/* Channel Config Descriptor bit macros */
-#define MUSYCC_CCD_BUFIRQ_DISABLE 0x00000002 /* BUFF and ONR irqs disabled */
-#define MUSYCC_CCD_EOMIRQ_DISABLE 0x00000004 /* EOM irq disabled */
-#define MUSYCC_CCD_MSGIRQ_DISABLE 0x00000008 /* LNG, FCS, ALIGN, and ABT
- * irqs disabled */
-#define MUSYCC_CCD_IDLEIRQ_DISABLE 0x00000010 /* CHABT, CHIC, and SHT irqs
- * disabled */
-#define MUSYCC_CCD_FILTIRQ_DISABLE 0x00000020 /* SFILT irq disabled */
-#define MUSYCC_CCD_SDECIRQ_DISABLE 0x00000040 /* SDEC irq disabled */
-#define MUSYCC_CCD_SINCIRQ_DISABLE 0x00000080 /* SINC irq disabled */
-#define MUSYCC_CCD_SUERIRQ_DISABLE 0x00000100 /* SUERR irq disabled */
-#define MUSYCC_CCD_FCS_XFER 0x00000200 /* Propagate FCS along with
- * received data */
-#define MUSYCC_CCD_PROTO_SHIFT 12 /* Position index for protocol bit
- * field */
-#define MUSYCC_CCD_TRANS 0 /* Protocol mode in bits 12-14 */
-#define MUSYCC_CCD_SS7 1
-#define MUSYCC_CCD_HDLC_FCS16 2
-#define MUSYCC_CCD_HDLC_FCS32 3
-#define MUSYCC_CCD_EOPIRQ_DISABLE 0x00008000 /* EOP irq disabled */
-#define MUSYCC_CCD_INVERT_DATA 0x00800000 /* Invert data */
-#define MUSYCC_CCD_MAX_LENGTH 10 /* Position index for max length bit
- * field */
-#define MUSYCC_CCD_BUFFER_LENGTH 16 /* Position index for internal data
- * buffer length */
-#define MUSYCC_CCD_BUFFER_LOC 24 /* Position index for internal data
- * buffer starting location */
-
-/****************************************************************************
- * Interrupt Descriptor Information */
-
-#define INT_EMPTY_ENTRY 0xfeedface
-#define INT_EMPTY_ENTRY2 0xdeadface
-
-/****************************************************************************
- * Interrupt Status Descriptor
- *
- * NOTE: One must first fetch the value of the interrupt status descriptor
- * into a local variable, then pass that value into the read macros. This
- * is required to avoid race conditions.
- ***/
-
-#define INTRPTS_NEXTINT_M 0x7FFF0000
-#define INTRPTS_NEXTINT_S 16
-#define INTRPTS_NEXTINT(x) ((x & INTRPTS_NEXTINT_M) >> INTRPTS_NEXTINT_S)
-
-#define INTRPTS_INTFULL_M 0x00008000
-#define INTRPTS_INTFULL_S 15
-#define INTRPTS_INTFULL(x) ((x & INTRPTS_INTFULL_M) >> INTRPTS_INTFULL_S)
-
-#define INTRPTS_INTCNT_M 0x00007FFF
-#define INTRPTS_INTCNT_S 0
-#define INTRPTS_INTCNT(x) ((x & INTRPTS_INTCNT_M) >> INTRPTS_INTCNT_S)
-
-
-/****************************************************************************
- * Interrupt Descriptor
- ***/
-
-#define INTRPT_DIR_M 0x80000000
-#define INTRPT_DIR_S 31
-#define INTRPT_DIR(x) ((x & INTRPT_DIR_M) >> INTRPT_DIR_S)
-
-#define INTRPT_GRP_M 0x60000000
-#define INTRPT_GRP_MSB_M 0x00004000
-#define INTRPT_GRP_S 29
-#define INTRPT_GRP_MSB_S 12
-#define INTRPT_GRP(x) (((x & INTRPT_GRP_M) >> INTRPT_GRP_S) | \
- ((x & INTRPT_GRP_MSB_M) >> INTRPT_GRP_MSB_S))
-
-#define INTRPT_CH_M 0x1F000000
-#define INTRPT_CH_S 24
-#define INTRPT_CH(x) ((x & INTRPT_CH_M) >> INTRPT_CH_S)
-
-#define INTRPT_EVENT_M 0x00F00000
-#define INTRPT_EVENT_S 20
-#define INTRPT_EVENT(x) ((x & INTRPT_EVENT_M) >> INTRPT_EVENT_S)
-
-#define INTRPT_ERROR_M 0x000F0000
-#define INTRPT_ERROR_S 16
-#define INTRPT_ERROR(x) ((x & INTRPT_ERROR_M) >> INTRPT_ERROR_S)
-
-#define INTRPT_ILOST_M 0x00008000
-#define INTRPT_ILOST_S 15
-#define INTRPT_ILOST(x) ((x & INTRPT_ILOST_M) >> INTRPT_ILOST_S)
-
-#define INTRPT_PERR_M 0x00004000
-#define INTRPT_PERR_S 14
-#define INTRPT_PERR(x) ((x & INTRPT_PERR_M) >> INTRPT_PERR_S)
-
-#define INTRPT_BLEN_M 0x00003FFF
-#define INTRPT_BLEN_S 0
-#define INTRPT_BLEN(x) ((x & INTRPT_BLEN_M) >> INTRPT_BLEN_S)
-
-
-/* Buffer Descriptor bit macros */
-#define OWNER_BIT 0x80000000 /* Set for MUSYCC owner on xmit, host
- * owner on receive */
-#define HOST_TX_OWNED 0x00000000 /* Host owns descriptor */
-#define MUSYCC_TX_OWNED 0x80000000 /* MUSYCC owns descriptor */
-#define HOST_RX_OWNED 0x80000000 /* Host owns descriptor */
-#define MUSYCC_RX_OWNED 0x00000000 /* MUSYCC owns descriptor */
-
-#define POLL_DISABLED 0x40000000 /* MUSYCC not allowed to poll buffer
- * for ownership */
-#define EOMIRQ_ENABLE 0x20000000 /* This buffer contains the end of
- * the message */
-#define EOBIRQ_ENABLE 0x10000000 /* EOB irq enabled */
-#define PADFILL_ENABLE 0x01000000 /* Enable padfill */
-#define REPEAT_BIT 0x00008000 /* Bit on for FISU descriptor */
-#define LENGTH_MASK 0X3fff /* This part of status descriptor is
- * length */
-#define IDLE_CODE 25 /* Position index for idle code (2
- * bits) */
-#define EXTRA_FLAGS 16 /* Position index for minimum flags
- * between messages (8 bits) */
-#define IDLE_CODE_MASK 0x03 /* Gets rid of garbage before the
- * pattern is OR'd in */
-#define EXTRA_FLAGS_MASK 0xff /* Gets rid of garbage before the
- * pattern is OR'd in */
-#define PCI_PERMUTED_OWNER_BIT 0x00000080 /* For flipping the bit on
- * the polled mode descriptor */
-
-/* Service Request Descriptor bit macros */
-#define SREQ 8 /* Position index for service request bit
- * field */
-#define SR_NOOP (0<<(SREQ)) /* No Operation. Generates SACK */
-#define SR_CHIP_RESET (1<<(SREQ)) /* Soft chip reset */
-#define SR_GROUP_RESET (2<<(SREQ)) /* Group reset */
-#define SR_GLOBAL_INIT (4<<(SREQ)) /* Global init: read global
- * config deswc and interrupt
- * queue desc */
-#define SR_GROUP_INIT (5<<(SREQ)) /* Group init: read Timeslot
- * and Subchannel maps,
- * Channel Config, */
- /*
- * Group Config, Memory Protect, Message Length, and Port Config
- * Descriptors
- */
-#define SR_CHANNEL_ACTIVATE (8<<(SREQ)) /* Init channel, read Head
- * Pointer, process first
- * Message Descriptor */
-#define SR_GCHANNEL_MASK 0x001F /* channel portion (gchan) */
-#define SR_CHANNEL_DEACTIVATE (9<<(SREQ)) /* Stop channel processing */
-#define SR_JUMP (10<<(SREQ)) /* a: Process new Message
- * List */
-#define SR_CHANNEL_CONFIG (11<<(SREQ)) /* b: Read channel
- * Configuration Descriptor */
-#define SR_GLOBAL_CONFIG (16<<(SREQ)) /* 10: Read Global
- * Configuration Descriptor */
-#define SR_INTERRUPT_Q (17<<(SREQ)) /* 11: Read Interrupt Queue
- * Descriptor */
-#define SR_GROUP_CONFIG (18<<(SREQ)) /* 12: Read Group
- * Configuration Descriptor */
-#define SR_MEMORY_PROTECT (19<<(SREQ)) /* 13: Read Memory Protection
- * Descriptor */
-#define SR_MESSAGE_LENGTH (20<<(SREQ)) /* 14: Read Message Length
- * Descriptor */
-#define SR_PORT_CONFIG (21<<(SREQ)) /* 15: Read Port
- * Configuration Descriptor */
-#define SR_TIMESLOT_MAP (24<<(SREQ)) /* 18: Read Timeslot Map */
-#define SR_SUBCHANNEL_MAP (25<<(SREQ)) /* 19: Read Subchannel Map */
-#define SR_CHAN_CONFIG_TABLE (26<<(SREQ)) /* 20: Read Channel
- * Configuration Table for
- * the group */
-#define SR_TX_DIRECTION 0x00000020 /* Transmit direction bit.
- * Bit off indicates receive
- * direction */
-#define SR_RX_DIRECTION 0x00000000
-
-/* Interrupt Descriptor bit macros */
-#define GROUP10 29 /* Position index for the 2 LS group
- * bits */
-#define CHANNEL 24 /* Position index for channel bits */
-#define INT_IQD_TX 0x80000000
-#define INT_IQD_GRP 0x60000000
-#define INT_IQD_CHAN 0x1f000000
-#define INT_IQD_EVENT 0x00f00000
-#define INT_IQD_ERROR 0x000f0000
-#define INT_IQD_ILOST 0x00008000
-#define INT_IQD_PERR 0x00004000
-#define INT_IQD_BLEN 0x00003fff
-
-/* Interrupt Descriptor Events */
-#define EVE_EVENT 20 /* Position index for event bits */
-#define EVE_NONE 0 /* No event to report in this
- * interrupt */
-#define EVE_SACK 1 /* Service Request acknowledge */
-#define EVE_EOB 2 /* End of Buffer */
-#define EVE_EOM 3 /* End of Message */
-#define EVE_EOP 4 /* End of Padfill */
-#define EVE_CHABT 5 /* Change to Abort Code */
-#define EVE_CHIC 6 /* Change to Idle Code */
-#define EVE_FREC 7 /* Frame Recovery */
-#define EVE_SINC 8 /* MTP2 SUERM Increment */
-#define EVE_SDEC 9 /* MTP2 SUERM Decrement */
-#define EVE_SFILT 10 /* MTP2 SUERM Filtered Message */
-/* Interrupt Descriptor Errors */
-#define ERR_ERRORS 16 /* Position index for error bits */
-#define ERR_BUF 1 /* Buffer Error */
-#define ERR_COFA 2 /* Change of Frame Alignment Error */
-#define ERR_ONR 3 /* Owner Bit Error */
-#define ERR_PROT 4 /* Memory Protection Error */
-#define ERR_OOF 8 /* Out of Frame Error */
-#define ERR_FCS 9 /* FCS Error */
-#define ERR_ALIGN 10 /* Octet Alignment Error */
-#define ERR_ABT 11 /* Abort Termination */
-#define ERR_LNG 12 /* Long Message Error */
-#define ERR_SHT 13 /* Short Message Error */
-#define ERR_SUERR 14 /* SUERM threshold exceeded */
-#define ERR_PERR 15 /* PCI Parity Error */
-/* Other Stuff */
-#define TRANSMIT_DIRECTION 0x80000000 /* Transmit direction bit. Bit off
- * indicates receive direction */
-#define ILOST 0x00008000 /* Interrupt Lost */
-#define GROUPMSB 0x00004000 /* Group number MSB */
-#define SACK_IMAGE 0x00100000 /* Used in IRQ for semaphore test */
-#define INITIAL_STATUS 0x10000 /* IRQ status should be this after
- * reset */
-
-/* This must be defined on an entire channel group (Port) basis */
-#define SUERM_THRESHOLD 0x1f
-
-#undef VINT32
-#undef VINT8
-
-#endif /*** _INC_MUSYCC_H_ ***/
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.c b/drivers/staging/cxt1e1/pmc93x6_eeprom.c
deleted file mode 100644
index ba588f1b2110..000000000000
--- a/drivers/staging/cxt1e1/pmc93x6_eeprom.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/* pmc93x6_eeprom.c - PMC's 93LC46 EEPROM Device
- *
- * The 93LC46 is a low-power, serial Electrically Erasable and
- * Programmable Read Only Memory organized as 128 8-bit bytes.
- *
- * Accesses to the 93LC46 are done in a bit serial stream, organized
- * in a 3 wire format. Writes are internally timed by the device
- * (the In data bit is pulled low until the write is complete and
- * then is pulled high) and take about 6 milliseconds.
- *
- * Copyright (C) 2003-2005 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "pmcc4.h"
-#include "sbe_promformat.h"
-#include "pmc93x6_eeprom.h"
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-/*------------------------------------------------------------------------
- * EEPROM address definitions
- *------------------------------------------------------------------------
- *
- * The offset in the definitions below allows the test to skip over
- * areas of the EEPROM that other programs (such a VxWorks) are
- * using.
- */
-
-#define EE_MFG (long)0 /* Index to manufacturing record */
-#define EE_FIRST 0x28 /* Index to start testing at */
-#define EE_LIMIT 128 /* Index to end testing at */
-
-/* Bit Ordering for Instructions
- *
- * A0, A1, A2, A3, A4, A5, A6, OP0, OP1, SB (lsb, or 1st bit out)
- *
- */
-
-#define EPROM_EWEN 0x0019 /* Erase/Write enable (reversed) */
-#define EPROM_EWDS 0x0001 /* Erase/Write disable (reversed) */
-#define EPROM_READ 0x0003 /* Read (reversed) */
-#define EPROM_WRITE 0x0005 /* Write (reversed) */
-#define EPROM_ERASE 0x0007 /* Erase (reversed) */
-#define EPROM_ERAL 0x0009 /* Erase All (reversed) */
-#define EPROM_WRAL 0x0011 /* Write All (reversed) */
-
-#define EPROM_ADR_SZ 7 /* Number of bits in offset address */
-#define EPROM_OP_SZ 3 /* Number of bits in command */
-#define SIZE_ADDR_OP (EPROM_ADR_SZ + EPROM_OP_SZ)
-#define LC46A_MAX_OPS 10 /* Number of bits in Instruction */
-#define NUM_OF_BITS 8 /* Number of bits in data */
-
-/* EEPROM signal bits */
-#define EPROM_ACTIVE_OUT_BIT 0x0001 /* Out data bit */
-#define EPROM_ACTIVE_IN_BIT 0x0002 /* In data bit */
-#define ACTIVE_IN_BIT_SHIFT 0x0001 /* Shift In data bit to LSB */
-#define EPROM_ENCS 0x0004 /* Set EEPROM CS during operation */
-
-/*------------------------------------------------------------------------
- * The ByteReverse table is used to reverses the 8 bits within a byte
- *------------------------------------------------------------------------
- */
-
-static unsigned char ByteReverse[256];
-static int ByteReverseBuilt = FALSE;
-
-/*------------------------------------------------------------------------
- * mfg_template - initial serial EEPROM data structure
- *------------------------------------------------------------------------
- */
-
-static u8 mfg_template[sizeof(FLD_TYPE2)] = {
- PROM_FORMAT_TYPE2, /* type; */
- 0x00, 0x1A, /* length[2]; */
- 0x00, 0x00, 0x00, 0x00, /* Crc32[4]; */
- 0x11, 0x76, /* Id[2]; */
- 0x07, 0x05, /* SubId[2] E1; */
- 0x00, 0xA0, 0xD6, 0x00, 0x00, 0x00, /* Serial[6]; */
- 0x00, 0x00, 0x00, 0x00, /* CreateTime[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunTime[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunIterations[4]; */
- 0x00, 0x00, 0x00, 0x00, /* HeatRunErrors[4]; */
-};
-
-/*------------------------------------------------------------------------
- * BuildByteReverse - build the 8-bit reverse table
- *------------------------------------------------------------------------
- *
- * The 'ByteReverse' table reverses the 8 bits within a byte
- * (the MSB becomes the LSB etc.).
- */
-
-static void BuildByteReverse(void)
-{
- /* Used to build by powers to 2 */
- long half;
- int i;
-
- ByteReverse[0] = 0;
-
- for (half = 1; half < sizeof(ByteReverse); half <<= 1)
- for (i = 0; i < half; i++)
- ByteReverse[half + i] =
- (char)(ByteReverse[i] | (0x80 / half));
-
- ByteReverseBuilt = TRUE;
-}
-
-/*------------------------------------------------------------------------
- * eeprom_delay - small delay for EEPROM timing
- *------------------------------------------------------------------------
- */
-
-static void eeprom_delay(void)
-{
- int timeout;
-
- for (timeout = 20; timeout; --timeout)
- OS_uwait_dummy();
-}
-
-/*------------------------------------------------------------------------
- * eeprom_put_byte - Send a byte to the EEPROM serially
- *------------------------------------------------------------------------
- *
- * Given the PCI address and the data, this routine serially sends
- * the data to the EEPROM.
- */
-
-static void eeprom_put_byte(long addr, long data, int count)
-{
- u_int32_t output;
-
- while (--count >= 0) {
- /* Get next data bit */
- output = (data & EPROM_ACTIVE_OUT_BIT) ? 1 : 0;
- /* Add Chip Select */
- output |= EPROM_ENCS;
- data >>= 1;
-
- eeprom_delay();
- /* Output it */
- pci_write_32((u_int32_t *) addr, output);
- }
-}
-
-/*------------------------------------------------------------------------
- * eeprom_get_byte - Receive a byte from the EEPROM serially
- *------------------------------------------------------------------------
- *
- * Given the PCI address, this routine serially fetches the data
- * from the EEPROM.
- */
-
-static u_int32_t eeprom_get_byte(long addr)
-{
- u_int32_t input;
- u_int32_t data;
- int count;
-
-/* Start the Reading of DATA
- *
- * The first read is a dummy as the data is latched in the
- * EPLD and read on the next read access to the EEPROM.
- */
-
- input = pci_read_32((u_int32_t *) addr);
-
- data = 0;
- count = NUM_OF_BITS;
- while (--count >= 0) {
- eeprom_delay();
- input = pci_read_32((u_int32_t *) addr);
-
- /* Shift data over */
- data <<= 1;
- data |= (input & EPROM_ACTIVE_IN_BIT) ? 1 : 0;
-
- }
-
- return data;
-}
-
-/*------------------------------------------------------------------------
- * disable_pmc_eeprom - Disable writes to the EEPROM
- *------------------------------------------------------------------------
- *
- * Issue the EEPROM command to disable writes.
- */
-
-static void disable_pmc_eeprom(long addr)
-{
- eeprom_put_byte(addr, EPROM_EWDS, SIZE_ADDR_OP);
-
- /* this removes Chip Select from EEPROM */
- pci_write_32((u_int32_t *) addr, 0);
-}
-
-/*------------------------------------------------------------------------
- * enable_pmc_eeprom - Enable writes to the EEPROM
- *------------------------------------------------------------------------
- *
- * Issue the EEPROM command to enable writes.
- */
-
-static void enable_pmc_eeprom(long addr)
-{
- eeprom_put_byte(addr, EPROM_EWEN, SIZE_ADDR_OP);
-
- /* this removes Chip Select from EEPROM */
- pci_write_32((u_int32_t *) addr, 0);
-}
-
-/*------------------------------------------------------------------------
- * pmc_eeprom_read - EEPROM location read
- *------------------------------------------------------------------------
- *
- * Given a EEPROM PCI address and location offset, this routine returns
- * the contents of the specified location to the calling routine.
- */
-
-static u_int32_t pmc_eeprom_read(long addr, long mem_offset)
-{
- /* Data from chip */
- u_int32_t data;
-
- if (!ByteReverseBuilt)
- BuildByteReverse();
-
- /* Reverse address */
- mem_offset = ByteReverse[0x7F & mem_offset];
-
- /*
- * NOTE: The max offset address is 128 or half the reversal table. So
- * the LSB is always zero and counts as a built in shift of one bit.
- * So even though we need to shift 3 bits to make room for the command,
- * we only need to shift twice more because of the built in shift.
- */
-
- /* Shift for command */
- mem_offset <<= 2;
- /* Add command */
- mem_offset |= EPROM_READ;
-
- /* Output chip address */
- eeprom_put_byte(addr, mem_offset, SIZE_ADDR_OP);
-
- /* Read chip data */
- data = eeprom_get_byte(addr);
-
- /* Remove Chip Select from EEPROM */
- pci_write_32((u_int32_t *) addr, 0);
-
- return (data & 0x000000FF);
-}
-
-/*------------------------------------------------------------------------
- * pmc_eeprom_write - EEPROM location write
- *------------------------------------------------------------------------
- *
- * Given a EEPROM PCI address, location offset and value, this
- * routine writes the value to the specified location.
- *
- * Note: it is up to the caller to determine if the write
- * operation succeeded.
- */
-
-static int pmc_eeprom_write(long addr, long mem_offset, u_int32_t data)
-{
- u_int32_t temp;
- int count;
-
- if (!ByteReverseBuilt)
- BuildByteReverse();
-
- /* Reverse address */
- mem_offset = ByteReverse[0x7F & mem_offset];
-
- /*
- * NOTE: The max offset address is 128 or half the reversal table. So
- * the LSB is always zero and counts as a built in shift of one bit.
- * So even though we need to shift 3 bits to make room for the command,
- * we only need to shift twice more because of the built in shift.
- */
-
- /* Shift for command */
- mem_offset <<= 2;
- /* Add command */
- mem_offset |= EPROM_WRITE;
-
- /* Output chip address */
- eeprom_put_byte(addr, mem_offset, SIZE_ADDR_OP);
-
- /* Reverse data */
- data = ByteReverse[0xFF & data];
- /* Output chip data */
- eeprom_put_byte(addr, data, NUM_OF_BITS);
-
- /* Remove Chip Select from EEPROM */
- pci_write_32((u_int32_t *) addr, 0);
-
-/*
- * Must see Data In at a low state before completing this transaction.
- *
- * Afterwards, the data bit will return to a high state, ~6 ms, terminating
- * the operation.
- */
- /* Re-enable Chip Select */
- pci_write_32((u_int32_t *) addr, EPROM_ENCS);
- /* discard first read */
- temp = pci_read_32((u_int32_t *) addr);
- temp = pci_read_32((u_int32_t *) addr);
- if (temp & EPROM_ACTIVE_IN_BIT) {
- temp = pci_read_32((u_int32_t *) addr);
- if (temp & EPROM_ACTIVE_IN_BIT) {
- /* Remove Chip Select from EEPROM */
- pci_write_32((u_int32_t *) addr, 0);
- return 1;
- }
- }
- count = 1000;
- while (count--) {
- for (temp = 0; temp < 0x10; temp++)
- OS_uwait_dummy();
-
- if (pci_read_32((u_int32_t *) addr) & EPROM_ACTIVE_IN_BIT)
- break;
- }
-
- if (count == -1)
- return 2;
-
- return 0;
-}
-
-/*------------------------------------------------------------------------
- * pmcGetBuffValue - read the specified value from buffer
- *------------------------------------------------------------------------
- */
-
-static long pmcGetBuffValue(char *ptr, int size)
-{
- long value = 0;
- int index;
-
- for (index = 0; index < size; ++index) {
- value <<= 8;
- value |= ptr[index] & 0xFF;
- }
-
- return value;
-}
-
-/*------------------------------------------------------------------------
- * pmcSetBuffValue - save the specified value to buffer
- *------------------------------------------------------------------------
- */
-
-static void pmcSetBuffValue(char *ptr, long value, int size)
-{
- int index = size;
-
- while (--index >= 0) {
- ptr[index] = (char)(value & 0xFF);
- value >>= 8;
- }
-}
-
-/*------------------------------------------------------------------------
- * pmc_eeprom_read_buffer - read EEPROM data into specified buffer
- *------------------------------------------------------------------------
- */
-
-void
-pmc_eeprom_read_buffer(long addr, long mem_offset, char *dest_ptr, int size)
-{
- while (--size >= 0)
- *dest_ptr++ = (char)pmc_eeprom_read(addr, mem_offset++);
-}
-
-/*------------------------------------------------------------------------
- * pmc_eeprom_write_buffer - write EEPROM data from specified buffer
- *------------------------------------------------------------------------
- */
-
-void
-pmc_eeprom_write_buffer(long addr, long mem_offset, char *dest_ptr, int size)
-{
- enable_pmc_eeprom(addr);
-
- while (--size >= 0)
- pmc_eeprom_write(addr, mem_offset++, *dest_ptr++);
-
- disable_pmc_eeprom(addr);
-}
-
-/*------------------------------------------------------------------------
- * pmcCalcCrc - calculate the CRC for the serial EEPROM structure
- *------------------------------------------------------------------------
- */
-
-static u_int32_t pmcCalcCrc_T01(void *bufp)
-{
- FLD_TYPE2 *buf = bufp;
- /* CRC of the structure */
- u_int32_t crc;
-
- /* Calc CRC for type and length fields */
- sbeCrc((u_int8_t *) &buf->type,
- (u_int32_t) STRUCT_OFFSET(FLD_TYPE1, Crc32),
- (u_int32_t) 0, (u_int32_t *) &crc);
-
-#ifdef EEPROM_TYPE_DEBUG
- /* RLD DEBUG */
- pr_info("sbeCrc: crc 1 calculated as %08x\n", crc);
-#endif
- return ~crc;
-}
-
-static u_int32_t pmcCalcCrc_T02(void *bufp)
-{
- FLD_TYPE2 *buf = bufp;
- /* CRC of the structure */
- u_int32_t crc;
-
- /* Calc CRC for type and length fields */
- sbeCrc((u_int8_t *) &buf->type,
- (u_int32_t) STRUCT_OFFSET(FLD_TYPE2, Crc32),
- (u_int32_t) 0, (u_int32_t *) &crc);
-
- /* Calc CRC for remaining fields */
- sbeCrc((u_int8_t *) &buf->Id[0],
- (u_int32_t) (sizeof(FLD_TYPE2) - STRUCT_OFFSET(FLD_TYPE2, Id)),
- (u_int32_t) crc, (u_int32_t *) &crc);
-
-#ifdef EEPROM_TYPE_DEBUG
- /* RLD DEBUG */
- pr_info("sbeCrc: crc 2 calculated as %08x\n", crc);
-#endif
- return crc;
-}
-
-/*------------------------------------------------------------------------
- * pmc_init_seeprom - initialize the serial EEPROM structure
- *------------------------------------------------------------------------
- *
- * At the front of the serial EEPROM there is a record that contains
- * manufacturing information. If the info does not already exist, it
- * is created. The only field modifiable by the operator is the
- * serial number field.
- */
-
-void pmc_init_seeprom(u_int32_t addr, u_int32_t serialNum)
-{
- /* Memory image of structure */
- PROMFORMAT buffer;
- /* CRC of structure */
- u_int32_t crc;
- time_t createTime;
-
- createTime = get_seconds();
-
- /* use template data */
- memcpy(&buffer.fldType2, mfg_template, sizeof(buffer.fldType2));
-
- /* Update serial number field in buffer */
- pmcSetBuffValue(&buffer.fldType2.Serial[3], serialNum, 3);
-
- /* Update create time field in buffer */
- pmcSetBuffValue(&buffer.fldType2.CreateTime[0], createTime, 4);
-
- /* Update CRC field in buffer */
- crc = pmcCalcCrc_T02(&buffer);
- pmcSetBuffValue(&buffer.fldType2.Crc32[0], crc, 4);
-
-#ifdef DEBUG
- for (i = 0; i < sizeof(FLD_TYPE2); ++i)
- pr_info("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF);
-#endif
-
- /* Write structure to serial EEPROM */
- pmc_eeprom_write_buffer(addr, EE_MFG, (char *)&buffer,
- sizeof(FLD_TYPE2));
-}
-
-char pmc_verify_cksum(void *bufp)
-{
- FLD_TYPE1 *buf1 = bufp;
- FLD_TYPE2 *buf2 = bufp;
- /* CRC read from EEPROM */
- u_int32_t crc1, crc2;
-
- /* Retrieve contents of CRC field */
- crc1 = pmcGetBuffValue(&buf1->Crc32[0], sizeof(buf1->Crc32));
-#ifdef EEPROM_TYPE_DEBUG
- /* RLD DEBUG */
- pr_info("EEPROM: chksum 1 reads as %08x\n", crc1);
-#endif
- if ((buf1->type == PROM_FORMAT_TYPE1) &&
- (pmcCalcCrc_T01((void *)buf1) == crc1))
- return PROM_FORMAT_TYPE1; /* checksum type 1 verified */
-
- crc2 = pmcGetBuffValue(&buf2->Crc32[0], sizeof(buf2->Crc32));
-#ifdef EEPROM_TYPE_DEBUG
- /* RLD DEBUG */
- pr_info("EEPROM: chksum 2 reads as %08x\n", crc2);
-#endif
- if ((buf2->type == PROM_FORMAT_TYPE2) &&
- (pmcCalcCrc_T02((void *)buf2) == crc2))
- return PROM_FORMAT_TYPE2; /* checksum type 2 verified */
-
- /* failed to validate */
- return PROM_FORMAT_Unk;
-}
diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.h b/drivers/staging/cxt1e1/pmc93x6_eeprom.h
deleted file mode 100644
index 96c48cb83260..000000000000
--- a/drivers/staging/cxt1e1/pmc93x6_eeprom.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _INC_PMC93X6_EEPROM_H_
-#define _INC_PMC93X6_EEPROM_H_
-
-/*-----------------------------------------------------------------------------
- * pmc93x6_eeprom.h -
- *
- * Copyright (C) 2002-2004 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-
-#ifdef __KERNEL__
-
-#include "pmcc4_private.h"
-
-void pmc_eeprom_read_buffer (long, long, char *, int);
-void pmc_eeprom_write_buffer (long, long, char *, int);
-void pmc_init_seeprom (u_int32_t, u_int32_t);
-char pmc_verify_cksum (void *);
-
-#endif /*** __KERNEL__ ***/
-
-#endif
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h
deleted file mode 100644
index b4b5e5ad791b..000000000000
--- a/drivers/staging/cxt1e1/pmcc4.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef _INC_PMCC4_H_
-#define _INC_PMCC4_H_
-
-/*-----------------------------------------------------------------------------
- * pmcc4.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-
-typedef int status_t;
-
-#define SBE_DRVR_FAIL 0
-#define SBE_DRVR_SUCCESS 1
-
-/********************/
-/* PMCC4 memory Map */
-/********************/
-
-#define COMET_OFFSET(x) (0x80000+(x)*0x10000)
-#define EEPROM_OFFSET 0xC0000
-#define CPLD_OFFSET 0xD0000
-
- struct pmcc4_timeslot_param
- {
- u_int8_t card; /* the card number */
- u_int8_t port; /* the port number */
- u_int8_t _reserved1;
- u_int8_t _reserved2;
-
- /*
- * each byte in bitmask below represents one timeslot (bitmask[0] is
- * for timeslot 0 and so on), each bit in the byte selects timeslot
- * bits for this channel (0xff - whole timeslot, 0x7f - 56kbps mode)
- */
- u_int8_t bitmask[32];
- };
-
- struct c4_musycc_param
- {
- u_int8_t RWportnum;
- u_int16_t offset;
- u_int32_t value;
- };
-
-/*Alarm values */
-#define sbeE1RMAI 0x100
-#define sbeYelAlm 0x04
-#define sbeRedAlm 0x02
-#define sbeAISAlm 0x01
-
-#define sbeE1errSMF 0x02
-#define sbeE1CRC 0x01
-
-#ifdef __KERNEL__
-
-/*
- * Device Driver interface, routines are for internal use only.
- */
-
-#include "pmcc4_private.h"
-
-char *get_hdlc_name (hdlc_device *);
-
-/*
- * external interface
- */
-
-void c4_cleanup (void);
-status_t c4_chan_up (ci_t *, int channum);
-status_t c4_del_chan_stats (int channum);
-status_t c4_del_chan (int channum);
-status_t c4_get_iidinfo (ci_t *ci, struct sbe_iid_info *iip);
-int c4_is_chan_up (int channum);
-
-void *getuserbychan (int channum);
-void pci_flush_write (ci_t *ci);
-void sbecom_set_loglevel (int debuglevel);
-char *sbeid_get_bdname (ci_t *ci);
-void sbeid_set_bdtype (ci_t *ci);
-void sbeid_set_hdwbid (ci_t *ci);
-u_int32_t sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *);
-
-void VMETRO_TRIGGER (ci_t *, int); /* Note: int = 0(default)
- * thru 15 */
-
-#if defined (SBE_ISR_TASKLET)
-void musycc_intr_bh_tasklet (ci_t *);
-
-#endif
-
-#endif /*** __KERNEL __ ***/
-#endif /* _INC_PMCC4_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_cpld.h b/drivers/staging/cxt1e1/pmcc4_cpld.h
deleted file mode 100644
index a51209bc5274..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_cpld.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef _INC_PMCC4_CPLD_H_
-#define _INC_PMCC4_CPLD_H_
-
-/*-----------------------------------------------------------------------------
- * pmcc4_cpld.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-
-/********************************/
-/* iSPLD control chip registers */
-/********************************/
-
-#if 0
-#define CPLD_MCSR 0x0
-#define CPLD_MCLK 0x1
-#define CPLD_LEDS 0x2
-#define CPLD_INTR 0x3
-#endif
-
- struct c4_cpld
- {
- volatile u_int32_t mcsr;/* r/w: Master Clock Source Register */
- volatile u_int32_t mclk;/* r/w: Master Clock Register */
- volatile u_int32_t leds;/* r/w: LED Register */
- volatile u_int32_t intr;/* r: Interrupt Register */
- };
-
- typedef struct c4_cpld c4cpld_t;
-
-/* mcsr note: sourcing COMET must be initialized to Master Mode */
-#define PMCC4_CPLD_MCSR_IND 0 /* ports used individual BP Clk as
- * source, no slaves */
-#define PMCC4_CPLD_MCSR_CMT_1 1 /* COMET 1 BP Clk is source, 2,3,4
- * are Clk slaves */
-#define PMCC4_CPLD_MCSR_CMT_2 2 /* COMET 2 BP Clk is source, 1,3,4
- * are Clk slaves */
-#define PMCC4_CPLD_MCSR_CMT_3 3 /* COMET 3 BP Clk is source, 1,2,4
- * are Clk slaves */
-#define PMCC4_CPLD_MCSR_CMT_4 4 /* COMET 4 BP Clk is source, 1,2,3
- * are Clk slaves */
-
-#define PMCC4_CPLD_MCLK_MASK 0x0f
-#define PMCC4_CPLD_MCLK_P1 0x1
-#define PMCC4_CPLD_MCLK_P2 0x2
-#define PMCC4_CPLD_MCLK_P3 0x4
-#define PMCC4_CPLD_MCLK_P4 0x8
-#define PMCC4_CPLD_MCLK_T1 0x00
-#define PMCC4_CPLD_MCLK_P1_E1 0x01
-#define PMCC4_CPLD_MCLK_P2_E1 0x02
-#define PMCC4_CPLD_MCLK_P3_E1 0x04
-#define PMCC4_CPLD_MCLK_P4_E1 0x08
-
-#define PMCC4_CPLD_LED_OFF 0
-#define PMCC4_CPLD_LED_ON 1
-#define PMCC4_CPLD_LED_GP0 0x01 /* port 0, green */
-#define PMCC4_CPLD_LED_YP0 0x02 /* port 0, yellow */
-#define PMCC4_CPLD_LED_GP1 0x04 /* port 1, green */
-#define PMCC4_CPLD_LED_YP1 0x08 /* port 1, yellow */
-#define PMCC4_CPLD_LED_GP2 0x10 /* port 2, green */
-#define PMCC4_CPLD_LED_YP2 0x20 /* port 2, yellow */
-#define PMCC4_CPLD_LED_GP3 0x40 /* port 3, green */
-#define PMCC4_CPLD_LED_YP3 0x80 /* port 3, yellow */
-#define PMCC4_CPLD_LED_GREEN (PMCC4_CPLD_LED_GP0 | PMCC4_CPLD_LED_GP1 | \
- PMCC4_CPLD_LED_GP2 | PMCC4_CPLD_LED_GP3 )
-#define PMCC4_CPLD_LED_YELLOW (PMCC4_CPLD_LED_YP0 | PMCC4_CPLD_LED_YP1 | \
- PMCC4_CPLD_LED_YP2 | PMCC4_CPLD_LED_YP3)
-
-#define PMCC4_CPLD_INTR_MASK 0x0f
-#define PMCC4_CPLD_INTR_CMT_1 0x01
-#define PMCC4_CPLD_INTR_CMT_2 0x02
-#define PMCC4_CPLD_INTR_CMT_3 0x04
-#define PMCC4_CPLD_INTR_CMT_4 0x08
-
-#endif /* _INC_PMCC4_CPLD_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_defs.h b/drivers/staging/cxt1e1/pmcc4_defs.h
deleted file mode 100644
index 83ceae4324b2..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_defs.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef _INC_PMCC4_DEFS_H_
-#define _INC_PMCC4_DEFS_H_
-
-/*-----------------------------------------------------------------------------
- * c4_defs.h -
- *
- * Implementation elements of the wanPMC-C4T1E1 device driver
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-
-#define MAX_BOARDS 8
-#define MAX_CHANS_USED 128
-
-#ifdef SBE_PMCC4_ENABLE
-#define MUSYCC_NPORTS 4 /* CN8474 */
-#endif
-#ifdef SBE_WAN256T3_ENABLE
-#define MUSYCC_NPORTS 8 /* CN8478 */
-#endif
-#define MUSYCC_NCHANS 32 /* actually, chans per port */
-
-#define MUSYCC_NIQD 0x1000 /* power of 2 */
-#define MUSYCC_MRU 2048 /* default */
-#define MUSYCC_MTU 2048 /* default */
-#define MUSYCC_TXDESC_MIN 10 /* HDLC mode default */
-#define MUSYCC_RXDESC_MIN 18 /* HDLC mode default */
-#define MUSYCC_TXDESC_TRANS 4 /* Transparent mode minimum # of TX descriptors */
-#define MUSYCC_RXDESC_TRANS 12 /* Transparent mode minimum # of RX descriptors */
-
-#define MAX_DEFAULT_IFQLEN 32 /* network qlen */
-
-
-#define SBE_IFACETMPL "pmcc4-%d"
-#ifdef IFNAMSIZ
-#define SBE_IFACETMPL_SIZE IFNAMSIZ
-#else
-#define SBE_IFACETMPL_SIZE 16
-#endif
-
-/* we want the PMCC4 watchdog to fire off every 250ms */
-#define WATCHDOG_TIMEOUT 250000
-
-/* if we restart the watchdog every 250ms, then we'll time out
- * an additional 300ms later */
-#define WATCHDOG_UTIMEOUT (WATCHDOG_TIMEOUT+300000)
-
-#if !defined(SBE_ISR_TASKLET) && !defined(SBE_ISR_IMMEDIATE) && !defined(SBE_ISR_INLINE)
-#define SBE_ISR_TASKLET
-#endif
-
-#endif /*** _INC_PMCC4_DEFS_H_ ***/
-
diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c
deleted file mode 100644
index 76bebdd18b3a..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_drv.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-/*-----------------------------------------------------------------------------
- * pmcc4_drv.c -
- *
- * Copyright (C) 2007 One Stop Systems, Inc.
- * Copyright (C) 2002-2006 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@onestopsystems.com
- * One Stop Systems, Inc. Escondido, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include "pmcc4_sysdep.h"
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h> /* include for timer */
-#include <linux/timer.h> /* include for timer */
-#include <linux/hdlc.h>
-#include <linux/io.h>
-
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4_private.h"
-#include "pmcc4.h"
-#include "pmcc4_ioctls.h"
-#include "musycc.h"
-#include "comet.h"
-#include "sbe_bid.h"
-
-#define KERN_WARN KERN_WARNING
-
-/* forward references */
-status_t c4_wk_chan_init (mpi_t *, mch_t *);
-void c4_wq_port_cleanup (mpi_t *);
-status_t c4_wq_port_init (mpi_t *);
-
-int c4_loop_port (ci_t *, int, u_int8_t);
-status_t c4_set_port (ci_t *, int);
-status_t musycc_chan_down (ci_t *, int);
-
-u_int32_t musycc_chan_proto (int);
-status_t musycc_dump_ring (ci_t *, unsigned int);
-status_t __init musycc_init (ci_t *);
-void musycc_init_mdt (mpi_t *);
-void musycc_serv_req (mpi_t *, u_int32_t);
-void musycc_update_timeslots (mpi_t *);
-
-extern void musycc_update_tx_thp (mch_t *);
-extern int cxt1e1_log_level;
-extern int cxt1e1_max_mru;
-extern int cxt1e1_max_mtu;
-extern int max_rxdesc_used, max_rxdesc_default;
-extern int max_txdesc_used, max_txdesc_default;
-
-#if defined (__powerpc__)
-extern void *memset (void *s, int c, size_t n);
-
-#endif
-
-int drvr_state = SBE_DRVR_INIT;
-ci_t *c4_list = NULL;
-ci_t *CI; /* dummy pointer to board ZEROE's data -
- * DEBUG USAGE */
-
-
-void
-sbecom_set_loglevel (int d)
-{
- /*
- * The code within the following -if- clause is a backdoor debug facility
- * which can be used to display the state of a board's channel.
- */
- if (d > LOG_DEBUG)
- {
- unsigned int channum = d - (LOG_DEBUG + 1); /* convert to ZERO
- * relativity */
-
- (void) musycc_dump_ring ((ci_t *) CI, channum); /* CI implies support
- * for card 0 only */
- } else
- {
- if (cxt1e1_log_level != d)
- {
- pr_info("log level changed from %d to %d\n", cxt1e1_log_level, d);
- cxt1e1_log_level = d; /* set new */
- } else
- pr_info("log level is %d\n", cxt1e1_log_level);
- }
-}
-
-
-mch_t *
-c4_find_chan (int channum)
-{
- ci_t *ci;
- mch_t *ch;
- int portnum, gchan;
-
- for (ci = c4_list; ci; ci = ci->next)
- for (portnum = 0; portnum < ci->max_port; portnum++)
- for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
- {
- ch = ci->port[portnum].chan[gchan];
- if (ch) {
- if ((ch->state != UNASSIGNED) &&
- (ch->channum == channum))
- return ch;
- }
- }
- return NULL;
-}
-
-/***
- * Check port state and set LED states using watchdog or ioctl...
- * also check for in-band SF loopback commands (& cause results if they are there)
- *
- * Alarm function depends on comet bits indicating change in
- * link status (linkMask) to keep the link status indication straight.
- *
- * Indications are only LED and system log -- except when ioctl is invoked.
- *
- * "alarmed" record (a.k.a. copyVal, in some cases below) decodes as:
- *
- * RMAI (E1 only) 0x100
- * alarm LED on 0x80
- * link LED on 0x40
- * link returned 0x20 (link was down, now it's back and 'port get' hasn't run)
- * change in LED 0x10 (update LED register because value has changed)
- * link is down 0x08
- * YelAlm(RAI) 0x04
- * RedAlm 0x02
- * AIS(blue)Alm 0x01
- *
- * note "link has returned" indication is reset on read
- * (e.g. by use of the c4_control port get command)
- */
-
-#define sbeLinkMask 0x41 /* change in signal status (lost/recovered) +
- * state */
-#define sbeLinkChange 0x40
-#define sbeLinkDown 0x01
-#define sbeAlarmsMask 0x07 /* red / yellow / blue alarm conditions */
-#define sbeE1AlarmsMask 0x107 /* alarm conditions */
-
-#define COMET_LBCMD_READ 0x80 /* read only (do not set, return read value) */
-
-void
-checkPorts (ci_t *ci)
-{
-#ifndef CONFIG_SBE_PMCC4_NCOMM
- /*
- * PORT POINT - NCOMM needs to avoid this code since the polling of
- * alarms conflicts with NCOMM's interrupt servicing implementation.
- */
-
- struct s_comet_reg *comet;
- volatile u_int32_t value;
- u_int32_t copyVal, LEDval;
-
- u_int8_t portnum;
-
- LEDval = 0;
- for (portnum = 0; portnum < ci->max_port; portnum++)
- {
- copyVal = 0x12f & (ci->alarmed[portnum]); /* port's alarm record */
- comet = ci->port[portnum].cometbase;
- value = pci_read_32 ((u_int32_t *) &comet->cdrc_ists) & sbeLinkMask; /* link loss reg */
-
- if (value & sbeLinkChange) /* is there a change in the link stuff */
- {
- /* if there's been a change (above) and yet it's the same (below) */
- if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown)))
- {
- if (value & sbeLinkDown)
- pr_warning("%s: Port %d momentarily recovered.\n",
- ci->devname, portnum);
- else
- pr_warning("%s: Warning: Port %d link was briefly down.\n",
- ci->devname, portnum);
- } else if (value & sbeLinkDown)
- pr_warning("%s: Warning: Port %d link is down.\n",
- ci->devname, portnum);
- else
- {
- pr_warning("%s: Port %d link has recovered.\n",
- ci->devname, portnum);
- copyVal |= 0x20; /* record link transition to up */
- }
- copyVal |= 0x10; /* change (link) --> update LEDs */
- }
- copyVal &= 0x137; /* clear LED & link old history bits &
- * save others */
- if (value & sbeLinkDown)
- copyVal |= 0x08; /* record link status (now) */
- else
- { /* if link is up, do this */
- copyVal |= 0x40; /* LED indicate link is up */
- /* Alarm things & the like ... first if E1, then if T1 */
- if (IS_FRAME_ANY_E1 (ci->port[portnum].p.port_mode))
- {
- /*
- * first check Codeword (SaX) changes & CRC and
- * sub-multi-frame errors
- */
- /*
- * note these errors are printed every time they are detected
- * vs. alarms
- */
- value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_nat_ists); /* codeword */
- if (value & 0x1f)
- { /* if errors (crc or smf only) */
- if (value & 0x10)
- pr_warning("%s: E1 Port %d Codeword Sa4 change detected.\n",
- ci->devname, portnum);
- if (value & 0x08)
- pr_warning("%s: E1 Port %d Codeword Sa5 change detected.\n",
- ci->devname, portnum);
- if (value & 0x04)
- pr_warning("%s: E1 Port %d Codeword Sa6 change detected.\n",
- ci->devname, portnum);
- if (value & 0x02)
- pr_warning("%s: E1 Port %d Codeword Sa7 change detected.\n",
- ci->devname, portnum);
- if (value & 0x01)
- pr_warning("%s: E1 Port %d Codeword Sa8 change detected.\n",
- ci->devname, portnum);
- }
- value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists); /* crc & smf */
- if (value & 0x3)
- { /* if errors (crc or smf only) */
- if (value & sbeE1CRC)
- pr_warning("%s: E1 Port %d CRC-4 error(s) detected.\n",
- ci->devname, portnum);
- if (value & sbeE1errSMF) /* error in sub-multiframe */
- pr_warning("%s: E1 Port %d received errored SMF.\n",
- ci->devname, portnum);
- }
- value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */
- /*
- * pack alarms together (bitmiser), and construct similar to
- * T1
- */
- /* RAI,RMAI,.,.,LOF,AIS,.,. ==> RMAI,.,.,.,.,.,RAI,LOF,AIS */
- /* see 0x97 */
- value = (value >> 2);
- if (value & 0x30)
- {
- if (value & 0x20)
- value |= 0x40; /* RAI */
- if (value & 0x10)
- value |= 0x100; /* RMAI */
- value &= ~0x30;
- } /* finished packing alarm in handy order */
- if (value != (copyVal & sbeE1AlarmsMask))
- { /* if alarms changed */
- copyVal |= 0x10;/* change LED status */
- if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
- {
- copyVal &= ~sbeRedAlm;
- pr_warning("%s: E1 Port %d LOF alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
- {
- copyVal |= sbeRedAlm;
- pr_warning("%s: E1 Warning: Port %d LOF alarm.\n",
- ci->devname, portnum);
- } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
- {
- copyVal &= ~sbeYelAlm;
- pr_warning("%s: E1 Port %d RAI alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
- {
- copyVal |= sbeYelAlm;
- pr_warning("%s: E1 Warning: Port %d RAI alarm.\n",
- ci->devname, portnum);
- } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI))
- {
- copyVal &= ~sbeE1RMAI;
- pr_warning("%s: E1 Port %d RMAI alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI))
- {
- copyVal |= sbeE1RMAI;
- pr_warning("%s: E1 Warning: Port %d RMAI alarm.\n",
- ci->devname, portnum);
- } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
- {
- copyVal &= ~sbeAISAlm;
- pr_warning("%s: E1 Port %d AIS alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
- {
- copyVal |= sbeAISAlm;
- pr_warning("%s: E1 Warning: Port %d AIS alarm.\n",
- ci->devname, portnum);
- }
- }
- /* end of E1 alarm code */
- } else
- { /* if a T1 mode */
- value = pci_read_32 ((u_int32_t *) &comet->t1_almi_ists); /* alarms */
- value &= sbeAlarmsMask;
- if (value != (copyVal & sbeAlarmsMask))
- { /* if alarms changed */
- copyVal |= 0x10;/* change LED status */
- if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm))
- {
- copyVal &= ~sbeRedAlm;
- pr_warning("%s: Port %d red alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm))
- {
- copyVal |= sbeRedAlm;
- pr_warning("%s: Warning: Port %d red alarm.\n",
- ci->devname, portnum);
- } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm))
- {
- copyVal &= ~sbeYelAlm;
- pr_warning("%s: Port %d yellow (RAI) alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm))
- {
- copyVal |= sbeYelAlm;
- pr_warning("%s: Warning: Port %d yellow (RAI) alarm.\n",
- ci->devname, portnum);
- } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm))
- {
- copyVal &= ~sbeAISAlm;
- pr_warning("%s: Port %d blue (AIS) alarm ended.\n",
- ci->devname, portnum);
- } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm))
- {
- copyVal |= sbeAISAlm;
- pr_warning("%s: Warning: Port %d blue (AIS) alarm.\n",
- ci->devname, portnum);
- }
- }
- } /* end T1 mode alarm checks */
- }
- if (copyVal & sbeAlarmsMask)
- copyVal |= 0x80; /* if alarm turn yel LED on */
- if (copyVal & 0x10)
- LEDval |= 0x100; /* tag if LED values have changed */
- LEDval |= ((copyVal & 0xc0) >> (6 - (portnum * 2)));
-
- ci->alarmed[portnum] &= 0xfffff000; /* out with the old (it's fff
- * ... foo) */
- ci->alarmed[portnum] |= (copyVal); /* in with the new */
-
- /*
- * enough with the alarms and LED's, now let's check for loopback
- * requests
- */
-
- if (IS_FRAME_ANY_T1 (ci->port[portnum].p.port_mode))
- { /* if a T1 mode */
- /*
- * begin in-band (SF) loopback code detection -- start by reading
- * command
- */
- value = pci_read_32 ((u_int32_t *) &comet->ibcd_ies); /* detect reg. */
- value &= 0x3; /* trim to handy bits */
- if (value & 0x2)
- { /* activate loopback (sets for deactivate
- * code length) */
- copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
- * mode */
- if (copyVal != COMET_MDIAG_LINELB) /* don't do it again if
- * already in that mode */
- c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
- * loopback mode */
- }
- if (value & 0x1)
- { /* deactivate loopback (sets for activate
- * code length) */
- copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback
- * mode */
- if (copyVal != COMET_MDIAG_LBOFF) /* don't do it again if
- * already in that mode */
- c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any
- * loopback mode */
- }
- }
- if (IS_FRAME_ANY_T1ESF (ci->port[portnum].p.port_mode))
- { /* if a T1 ESF mode */
- /* begin ESF loopback code */
- value = pci_read_32 ((u_int32_t *) &comet->t1_rboc_sts) & 0x3f; /* read command */
- if (value == 0x07)
- c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line
- * loopback mode */
- if (value == 0x0a)
- c4_loop_port (ci, portnum, COMET_MDIAG_PAYLB); /* put port in payload
- * loopbk mode */
- if ((value == 0x1c) || (value == 0x19) || (value == 0x12))
- c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any
- * loopbk mode */
- if (cxt1e1_log_level >= LOG_DEBUG)
- if (value != 0x3f)
- pr_warning("%s: BOC value = %x on Port %d\n",
- ci->devname, value, portnum);
- /* end ESF loopback code */
- }
- }
-
- /* if something is new, update LED's */
- if (LEDval & 0x100)
- pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, LEDval & 0xff);
-#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/
-}
-
-
-static void
-c4_watchdog (ci_t *ci)
-{
- if (drvr_state != SBE_DRVR_AVAILABLE)
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("drvr not available (%x)\n", drvr_state);
- return;
- }
- ci->wdcount++;
- checkPorts (ci);
- ci->wd_notify = 0;
-}
-
-
-void
-c4_cleanup (void)
-{
- ci_t *ci, *next;
- mpi_t *pi;
- int portnum, j;
-
- ci = c4_list;
- while (ci)
- {
- next = ci->next; /* protect <next> from upcoming <free> */
- pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
- for (portnum = 0; portnum < ci->max_port; portnum++)
- {
- pi = &ci->port[portnum];
- c4_wq_port_cleanup (pi);
- for (j = 0; j < MUSYCC_NCHANS; j++)
- {
- if (pi->chan[j])
- kfree(pi->chan[j]); /* free mch_t struct */
- }
- kfree(pi->regram_saved);
- }
- kfree(ci->iqd_p_saved);
- kfree(ci);
- ci = next; /* cleanup next board, if any */
- }
-}
-
-
-/*
- * This function issues a write to all comet chips and expects the same data
- * to be returned from the subsequent read. This determines the board build
- * to be a 1-port, 2-port, or 4-port build. The value returned represents a
- * bit-mask of the found ports. Only certain configurations are considered
- * VALID or LEGAL builds.
- */
-
-int
-c4_get_portcfg (ci_t *ci)
-{
- struct s_comet_reg *comet;
- int portnum, mask;
- u_int32_t wdata, rdata;
-
- wdata = COMET_MDIAG_LBOFF; /* take port out of any loopback mode */
-
- mask = 0;
- for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
- {
- comet = ci->port[portnum].cometbase;
- pci_write_32 ((u_int32_t *) &comet->mdiag, wdata);
- rdata = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
- if (wdata == rdata)
- mask |= 1 << portnum;
- }
- return mask;
-}
-
-
-/* nothing herein should generate interrupts */
-
-status_t __init
-c4_init (ci_t *ci, u_char *func0, u_char *func1)
-{
- mpi_t *pi;
- mch_t *ch;
- static u_int32_t count = 0;
- int portnum, j;
-
- ci->state = C_INIT;
- ci->brdno = count++;
- ci->intlog.this_status_new = 0;
- atomic_set (&ci->bh_pending, 0);
-
- ci->reg = (struct musycc_globalr *) func0;
- ci->eeprombase = (u_int32_t *) (func1 + EEPROM_OFFSET);
- ci->cpldbase = (c4cpld_t *) ((u_int32_t *) (func1 + ISPLD_OFFSET));
-
- /*** PORT POINT - the following is the first access of any type to the hardware ***/
-#ifdef CONFIG_SBE_PMCC4_NCOMM
- /* NCOMM driver uses INTB interrupt to monitor CPLD register */
- pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC);
-#else
- /* standard driver POLLS for INTB via CPLD register */
- pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
-#endif
-
- {
- int pmsk;
-
- /* need comet addresses available for determination of hardware build */
- for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++)
- {
- pi = &ci->port[portnum];
- pi->cometbase = (struct s_comet_reg *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum)));
- pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800));
- pi->portnum = portnum;
- pi->p.portnum = portnum;
- pi->openchans = 0;
-#ifdef SBE_MAP_DEBUG
- pr_info("Comet-%d: addr = %p\n", portnum, pi->cometbase);
-#endif
- }
- pmsk = c4_get_portcfg (ci);
- switch (pmsk)
- {
- case 0x1:
- ci->max_port = 1;
- break;
- case 0x3:
- ci->max_port = 2;
- break;
-#if 0
- case 0x7: /* not built, but could be... */
- ci->max_port = 3;
- break;
-#endif
- case 0xf:
- ci->max_port = 4;
- break;
- default:
- ci->max_port = 0;
- pr_warning("%s: illegal port configuration (%x)\n",
- ci->devname, pmsk);
- return SBE_DRVR_FAIL;
- }
-#ifdef SBE_MAP_DEBUG
- pr_info(">> %s: c4_get_build - pmsk %x max_port %x\n",
- ci->devname, pmsk, ci->max_port);
-#endif
- }
-
- for (portnum = 0; portnum < ci->max_port; portnum++)
- {
- pi = &ci->port[portnum];
- pi->up = ci;
- pi->sr_last = 0xffffffff;
- pi->p.port_mode = CFG_FRAME_SF; /* T1 B8ZS, the default */
- pi->p.portP = (CFG_CLK_PORT_EXTERNAL | CFG_LBO_LH0); /* T1 defaults */
-
- OS_sem_init (&pi->sr_sem_busy, SEM_AVAILABLE);
- OS_sem_init (&pi->sr_sem_wait, SEM_TAKEN);
-
- for (j = 0; j < 32; j++)
- {
- pi->fifomap[j] = -1;
- pi->tsm[j] = 0; /* no assignments, all available */
- }
-
- /* allocate channel structures for this port */
- for (j = 0; j < MUSYCC_NCHANS; j++)
- {
- ch = kzalloc(sizeof(mch_t), GFP_KERNEL | GFP_DMA);
- if (ch)
- {
- pi->chan[j] = ch;
- ch->state = UNASSIGNED;
- ch->up = pi;
- ch->gchan = (-1); /* channel assignment not yet known */
- ch->channum = (-1); /* channel assignment not yet known */
- ch->p.card = ci->brdno;
- ch->p.port = portnum;
- ch->p.channum = (-1); /* channel assignment not yet known */
- ch->p.mode_56k = 0; /* default is 64kbps mode */
- } else
- {
- pr_warning("failed mch_t malloc, port %d channel %d size %u.\n",
- portnum, j, (unsigned int) sizeof (mch_t));
- break;
- }
- }
- }
-
-
- {
- /*
- * Set LEDs through their paces to supply visual proof that LEDs are
- * functional and not burnt out nor broken.
- *
- * YELLOW + GREEN -> OFF.
- */
-
- pci_write_32 ((u_int32_t *) &ci->cpldbase->leds,
- PMCC4_CPLD_LED_GREEN | PMCC4_CPLD_LED_YELLOW);
- OS_uwait (750000, "leds");
- pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF);
- }
-
- OS_init_watchdog (&ci->wd, (void (*) (void *)) c4_watchdog, ci, WATCHDOG_TIMEOUT);
- return SBE_DRVR_SUCCESS;
-}
-
-
-/* better be fully setup to handle interrupts when you call this */
-
-status_t __init
-c4_init2 (ci_t *ci)
-{
- status_t ret;
-
- /* PORT POINT: this routine generates first interrupt */
- ret = musycc_init(ci);
- if (ret != SBE_DRVR_SUCCESS)
- return ret;
-
-#if 0
- ci->p.framing_type = FRAMING_CBP;
- ci->p.h110enable = 1;
-#if 0
- ci->p.hypersize = 0;
-#else
- hyperdummy = 0;
-#endif
- ci->p.clock = 0; /* Use internal clocking until set to
- * external */
- c4_card_set_params (ci, &ci->p);
-#endif
- OS_start_watchdog (&ci->wd);
- return SBE_DRVR_SUCCESS;
-}
-
-
-/* This function sets the loopback mode (or clears it, as the case may be). */
-
-int
-c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd)
-{
- struct s_comet_reg *comet;
- volatile u_int32_t loopValue;
-
- comet = ci->port[portnum].cometbase;
- loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
-
- if (cmd & COMET_LBCMD_READ)
- return loopValue; /* return the read value */
-
- if (loopValue != cmd)
- {
- switch (cmd)
- {
- case COMET_MDIAG_LINELB:
- /* set(SF)loopback down (turn off) code length to 6 bits */
- pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x05);
- break;
- case COMET_MDIAG_LBOFF:
- /* set (SF) loopback up (turn on) code length to 5 bits */
- pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x00);
- break;
- }
-
- pci_write_32 ((u_int32_t *) &comet->mdiag, cmd);
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: loopback mode changed to %2x from %2x on Port %d\n",
- ci->devname, cmd, loopValue, portnum);
- loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK;
- if (loopValue != cmd)
- {
- if (cxt1e1_log_level >= LOG_ERROR)
- pr_info("%s: write to loop register failed, unknown state for Port %d\n",
- ci->devname, portnum);
- }
- } else
- {
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: loopback already in that mode (%2x)\n",
- ci->devname, loopValue);
- }
- return 0;
-}
-
-
-/* c4_frame_rw: read or write the comet register specified
- * (modifies use of port_param to non-standard use of struct)
- * Specifically:
- * pp.portnum (one guess)
- * pp.port_mode offset of register
- * pp.portP write (or not, i.e. read)
- * pp.portStatus write value
- * BTW:
- * pp.portStatus also used to return read value
- * pp.portP also used during write, to return old reg value
- */
-
-status_t
-c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp)
-{
- struct s_comet_reg *comet;
- volatile u_int32_t data;
-
- if (pp->portnum >= ci->max_port)/* sanity check */
- return -ENXIO;
-
- comet = ci->port[pp->portnum].cometbase;
- data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
-
- if (pp->portP)
- { /* control says this is a register
- * _write_ */
- if (pp->portStatus == data)
- pr_info("%s: Port %d already that value! Writing again anyhow.\n",
- ci->devname, pp->portnum);
- pp->portP = (u_int8_t) data;
- pci_write_32 ((u_int32_t *) comet + pp->port_mode,
- pp->portStatus);
- data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff;
- }
- pp->portStatus = (u_int8_t) data;
- return 0;
-}
-
-
-/* c4_pld_rw: read or write the pld register specified
- * (modifies use of port_param to non-standard use of struct)
- * Specifically:
- * pp.port_mode offset of register
- * pp.portP write (or not, i.e. read)
- * pp.portStatus write value
- * BTW:
- * pp.portStatus also used to return read value
- * pp.portP also used during write, to return old reg value
- */
-
-status_t
-c4_pld_rw (ci_t *ci, struct sbecom_port_param *pp)
-{
- volatile u_int32_t *regaddr;
- volatile u_int32_t data;
- int regnum = pp->port_mode;
-
- regaddr = (u_int32_t *) ci->cpldbase + regnum;
- data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
-
- if (pp->portP)
- { /* control says this is a register
- * _write_ */
- pp->portP = (u_int8_t) data;
- pci_write_32 ((u_int32_t *) regaddr, pp->portStatus);
- data = pci_read_32 ((u_int32_t *) regaddr) & 0xff;
- }
- pp->portStatus = (u_int8_t) data;
- return 0;
-}
-
-/* c4_musycc_rw: read or write the musycc register specified
- * (modifies use of port_param to non-standard use of struct)
- * Specifically:
- * mcp.RWportnum port number and write indication bit (0x80)
- * mcp.offset offset of register
- * mcp.value write value going in and read value returning
- */
-
-/* PORT POINT: TX Subchannel Map registers are write-only
- * areas within the MUSYCC and always return FF */
-/* PORT POINT: regram and reg structures are minorly different and <offset> ioctl
- * settings are aligned with the <reg> struct musycc_globalr{} usage.
- * Also, regram is separately allocated shared memory, allocated for each port.
- * PORT POINT: access offsets of 0x6000 for Msg Cfg Desc Tbl are for 4-port MUSYCC
- * only. (An 8-port MUSYCC has 0x16000 offsets for accessing its upper 4 tables.)
- */
-
-status_t
-c4_musycc_rw (ci_t *ci, struct c4_musycc_param *mcp)
-{
- mpi_t *pi;
- volatile u_int32_t *dph; /* hardware implemented register */
- u_int32_t *dpr = NULL; /* RAM image of registers for group command
- * usage */
- int offset = mcp->offset % 0x800; /* group relative address
- * offset, mcp->portnum is
- * not used */
- int portnum, ramread = 0;
- volatile u_int32_t data;
-
- /*
- * Sanity check hardware accessibility. The 0x6000 portion handles port
- * numbers associated with Msg Descr Tbl decoding.
- */
- portnum = (mcp->offset % 0x6000) / 0x800;
- if (portnum >= ci->max_port)
- return -ENXIO;
- pi = &ci->port[portnum];
- if (mcp->offset >= 0x6000)
- offset += 0x6000; /* put back in MsgCfgDesc address offset */
- dph = (u_int32_t *) ((u_long) pi->reg + offset);
-
- /* read of TX are from RAM image, since hardware returns FF */
- dpr = (u_int32_t *) ((u_long) pi->regram + offset);
- if (mcp->offset < 0x6000) /* non MsgDesc Tbl accesses might require
- * RAM access */
- {
- if (offset >= 0x200 && offset < 0x380)
- ramread = 1;
- if (offset >= 0x10 && offset < 0x200)
- ramread = 1;
- }
- /* read register from RAM or hardware, depending... */
- if (ramread)
- {
- data = *dpr;
- //pr_info("c4_musycc_rw: RAM addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */
- } else
- {
- data = pci_read_32 ((u_int32_t *) dph);
- //pr_info("c4_musycc_rw: REG addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */
- }
-
-
- if (mcp->RWportnum & 0x80)
- { /* control says this is a register
- * _write_ */
- if (mcp->value == data)
- pr_info("%s: musycc grp%d already that value! writing again anyhow.\n",
- ci->devname, (mcp->RWportnum & 0x7));
- /* write register RAM */
- if (ramread)
- *dpr = mcp->value;
- /* write hardware register */
- pci_write_32 ((u_int32_t *) dph, mcp->value);
- }
- mcp->value = data; /* return the read value (or the 'old
- * value', if is write) */
- return 0;
-}
-
-status_t
-c4_get_port (ci_t *ci, int portnum)
-{
- if (portnum >= ci->max_port) /* sanity check */
- return -ENXIO;
-
- SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per
- * board */
- checkPorts (ci);
- ci->port[portnum].p.portStatus = (u_int8_t) ci->alarmed[portnum];
- ci->alarmed[portnum] &= 0xdf;
- SD_SEM_GIVE (&ci->sem_wdbusy); /* release per-board hold */
- return 0;
-}
-
-status_t
-c4_set_port (ci_t *ci, int portnum)
-{
- mpi_t *pi;
- struct sbecom_port_param *pp;
- int e1mode;
- u_int8_t clck;
- int i;
-
- if (portnum >= ci->max_port) /* sanity check */
- return -ENXIO;
-
- pi = &ci->port[portnum];
- pp = &ci->port[portnum].p;
- e1mode = IS_FRAME_ANY_E1 (pp->port_mode);
- if (cxt1e1_log_level >= LOG_MONITOR2)
- {
- pr_info("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n",
- ci->devname,
- portnum, e1mode, pi->openchans);
- }
- if (pi->openchans)
- return -EBUSY; /* group needs initialization only for
- * first channel of a group */
-
- {
- status_t ret;
-
- ret = c4_wq_port_init(pi);
- if (ret) /* create/init workqueue_struct */
- return ret;
- }
-
- init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
- clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK;
- if (e1mode)
- clck |= 1 << portnum;
- else
- clck &= 0xf ^ (1 << portnum);
-
- pci_write_32 ((u_int32_t *) &ci->cpldbase->mclk, clck);
- pci_write_32 ((u_int32_t *) &ci->cpldbase->mcsr, PMCC4_CPLD_MCSR_IND);
- pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram));
-
- /*********************************************************************/
- /* ERRATA: If transparent mode is used, do not set OOFMP_DISABLE bit */
- /*********************************************************************/
-
- pi->regram->grcd =
- __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE |
- MUSYCC_GRCD_TX_ENABLE |
- MUSYCC_GRCD_OOFMP_DISABLE |
- MUSYCC_GRCD_SF_ALIGN | /* per MUSYCC ERRATA,
- * for T1 * fix */
- MUSYCC_GRCD_COFAIRQ_DISABLE |
- MUSYCC_GRCD_MC_ENABLE |
- (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT));
-
- pi->regram->pcd =
- __constant_cpu_to_le32 ((e1mode ? 1 : 0) |
- MUSYCC_PCD_TXSYNC_RISING |
- MUSYCC_PCD_RXSYNC_RISING |
- MUSYCC_PCD_RXDATA_RISING);
-
- /* Message length descriptor */
- pi->regram->mld = __constant_cpu_to_le32 (cxt1e1_max_mru | (cxt1e1_max_mru << 16));
-
- /* tsm algorithm */
- for (i = 0; i < 32; i++)
- {
-
- /*** ASSIGNMENT NOTES: ***/
- /*** Group's channel ZERO unavailable if E1. ***/
- /*** Group's channel 16 unavailable if E1 CAS. ***/
- /*** Group's channels 24-31 unavailable if T1. ***/
-
- if (((i == 0) && e1mode) ||
- ((i == 16) && ((pp->port_mode == CFG_FRAME_E1CRC_CAS) || (pp->port_mode == CFG_FRAME_E1CRC_CAS_AMI)))
- || ((i > 23) && (!e1mode)))
- {
- pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */
- } else
- {
- pi->tsm[i] = 0x00; /* make tslot available for assignment */
- }
- }
- for (i = 0; i < MUSYCC_NCHANS; i++)
- {
- pi->regram->ttsm[i] = 0;
- pi->regram->rtsm[i] = 0;
- }
- FLUSH_MEM_WRITE ();
- musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION);
- musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION);
-
- musycc_init_mdt (pi);
-
- pi->group_is_set = 1;
- pi->p = *pp;
- return 0;
-}
-
-
-unsigned int max_int = 0;
-
-status_t
-c4_new_chan (ci_t *ci, int portnum, int channum, void *user)
-{
- mpi_t *pi;
- mch_t *ch;
- int gchan;
-
- if (c4_find_chan (channum)) /* a new channel shouldn't already exist */
- return -EEXIST;
-
- if (portnum >= ci->max_port) /* sanity check */
- return -ENXIO;
-
- pi = &(ci->port[portnum]);
- /* find any available channel within this port */
- for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++)
- {
- ch = pi->chan[gchan];
- if (ch && ch->state == UNASSIGNED) /* no assignment is good! */
- break;
- }
- if (gchan == MUSYCC_NCHANS) /* exhausted table, all were assigned */
- return -ENFILE;
-
- ch->up = pi;
-
- /* NOTE: mch_t already cleared during OS_kmalloc() */
- ch->state = DOWN;
- ch->user = user;
- ch->gchan = gchan;
- ch->channum = channum; /* mark our channel assignment */
- ch->p.channum = channum;
-#if 1
- ch->p.card = ci->brdno;
- ch->p.port = portnum;
-#endif
- ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16;
- ch->p.idlecode = CFG_CH_FLAG_7E;
- ch->p.pad_fill_count = 2;
- spin_lock_init (&ch->ch_rxlock);
- spin_lock_init (&ch->ch_txlock);
-
- {
- status_t ret;
-
- ret = c4_wk_chan_init(pi, ch);
- if (ret)
- return ret;
- }
-
- /* save off interface assignments which bound a board */
- if (!ci->first_if) /* first channel registered is assumed to
- * be the lowest channel */
- {
- ci->first_if = ci->last_if = user;
- ci->first_channum = ci->last_channum = channum;
- } else
- {
- ci->last_if = user;
- if (ci->last_channum < channum) /* higher number channel found */
- ci->last_channum = channum;
- }
- return 0;
-}
-
-status_t
-c4_del_chan (int channum)
-{
- mch_t *ch;
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
- if (ch->state == UP)
- musycc_chan_down ((ci_t *) 0, channum);
- ch->state = UNASSIGNED;
- ch->gchan = (-1);
- ch->channum = (-1);
- ch->p.channum = (-1);
- return 0;
-}
-
-status_t
-c4_del_chan_stats (int channum)
-{
- mch_t *ch;
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
- memset (&ch->s, 0, sizeof (struct sbecom_chan_stats));
- return 0;
-}
-
-
-status_t
-c4_set_chan (int channum, struct sbecom_chan_param *p)
-{
- mch_t *ch;
- int i, x = 0;
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
-#if 1
- if (ch->p.card != p->card ||
- ch->p.port != p->port ||
- ch->p.channum != p->channum)
- return -EINVAL;
-#endif
-
- if (!(ch->up->group_is_set))
- {
- return -EIO; /* out of order, SET_PORT command
- * required prior to first group's
- * SET_CHAN command */
- }
- /*
- * Check for change of parameter settings in order to invoke closing of
- * channel prior to hardware poking.
- */
-
- if (ch->p.status != p->status || ch->p.chan_mode != p->chan_mode ||
- ch->p.data_inv != p->data_inv || ch->p.intr_mask != p->intr_mask ||
- ch->txd_free < ch->txd_num) /* to clear out queued messages */
- x = 1; /* we have a change requested */
- for (i = 0; i < 32; i++) /* check for timeslot mapping changes */
- if (ch->p.bitmask[i] != p->bitmask[i])
- x = 1; /* we have a change requested */
- ch->p = *p;
- if (x && (ch->state == UP)) /* if change request and channel is
- * open... */
- {
- status_t ret;
-
- ret = musycc_chan_down((ci_t *)0, channum);
- if (ret)
- return ret;
- ret = c4_chan_up(ch->up->up, channum);
- if (ret)
- return ret;
- sd_enable_xmit (ch->user); /* re-enable to catch flow controlled
- * channel */
- }
- return 0;
-}
-
-
-status_t
-c4_get_chan (int channum, struct sbecom_chan_param *p)
-{
- mch_t *ch;
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
- *p = ch->p;
- return 0;
-}
-
-status_t
-c4_get_chan_stats (int channum, struct sbecom_chan_stats *p)
-{
- mch_t *ch;
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
- *p = ch->s;
- p->tx_pending = atomic_read (&ch->tx_pending);
- return 0;
-}
-
-static int
-c4_fifo_alloc (mpi_t *pi, int chan, int *len)
-{
- int i, l = 0, start = 0, max = 0, maxstart = 0;
-
- for (i = 0; i < 32; i++)
- {
- if (pi->fifomap[i] != -1)
- {
- l = 0;
- start = i + 1;
- continue;
- }
- ++l;
- if (l > max)
- {
- max = l;
- maxstart = start;
- }
- if (max == *len)
- break;
- }
- if (max != *len)
- {
- if (cxt1e1_log_level >= LOG_WARN)
- pr_info("%s: wanted to allocate %d fifo space, but got only %d\n",
- pi->up->devname, *len, max);
- *len = max;
- }
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("%s: allocated %d fifo at %d for channel %d/%d\n",
- pi->up->devname, max, start, chan, pi->p.portnum);
- for (i = maxstart; i < (maxstart + max); i++)
- pi->fifomap[i] = chan;
- return start;
-}
-
-void
-c4_fifo_free (mpi_t *pi, int chan)
-{
- int i;
-
- if (cxt1e1_log_level >= LOG_DEBUG)
- pr_info("%s: deallocated fifo for channel %d/%d\n",
- pi->up->devname, chan, pi->p.portnum);
- for (i = 0; i < 32; i++)
- if (pi->fifomap[i] == chan)
- pi->fifomap[i] = -1;
-}
-
-
-status_t
-c4_chan_up (ci_t *ci, int channum)
-{
- mpi_t *pi;
- mch_t *ch;
- struct mbuf *m;
- struct mdesc *md;
- int nts, nbuf, txnum, rxnum;
- int addr, i, j, gchan;
- u_int32_t tmp; /* for optimizing conversion across BE
- * platform */
-
- ch = c4_find_chan(channum);
- if (!ch)
- return -ENOENT;
-
- if (ch->state == UP)
- {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: channel already UP, graceful early exit\n",
- ci->devname);
- return 0;
- }
- pi = ch->up;
- gchan = ch->gchan;
- /* find nts ('number of timeslots') */
- nts = 0;
- for (i = 0; i < 32; i++)
- {
- if (ch->p.bitmask[i] & pi->tsm[i])
- {
- if (1 || cxt1e1_log_level >= LOG_WARN)
- {
- pr_info("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n",
- ci->devname, channum, i);
- pr_info("+ ask4 %x, currently %x\n",
- ch->p.bitmask[i], pi->tsm[i]);
- }
- return -EINVAL;
- }
- for (j = 0; j < 8; j++)
- if (ch->p.bitmask[i] & (1 << j))
- nts++;
- }
-
- nbuf = nts / 8 ? nts / 8 : 1;
- if (!nbuf)
- {
- /* if( cxt1e1_log_level >= LOG_WARN) */
- pr_info("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n",
- ci->devname, channum);
- return -ENOBUFS; /* this should not happen */
- }
- addr = c4_fifo_alloc (pi, gchan, &nbuf);
- ch->state = UP;
-
- /* Setup the Time Slot Map */
- musycc_update_timeslots (pi);
-
- /* ch->tx_limit = nts; */
- ch->s.tx_pending = 0;
-
- /* Set Channel Configuration Descriptors */
- {
- u_int32_t ccd;
-
- ccd = musycc_chan_proto (ch->p.chan_mode) << MUSYCC_CCD_PROTO_SHIFT;
- if ((ch->p.chan_mode == CFG_CH_PROTO_ISLP_MODE) ||
- (ch->p.chan_mode == CFG_CH_PROTO_TRANS))
- {
- ccd |= MUSYCC_CCD_FCS_XFER; /* Non FSC Mode */
- }
- ccd |= 2 << MUSYCC_CCD_MAX_LENGTH; /* Select second MTU */
- ccd |= ch->p.intr_mask;
- ccd |= addr << MUSYCC_CCD_BUFFER_LOC;
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- ccd |= (nbuf) << MUSYCC_CCD_BUFFER_LENGTH;
- else
- ccd |= (nbuf - 1) << MUSYCC_CCD_BUFFER_LENGTH;
-
- if (ch->p.data_inv & CFG_CH_DINV_TX)
- ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */
- pi->regram->tcct[gchan] = cpu_to_le32 (ccd);
-
- if (ch->p.data_inv & CFG_CH_DINV_RX)
- ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */
- else
- ccd &= ~MUSYCC_CCD_INVERT_DATA; /* take away data inversion */
- pi->regram->rcct[gchan] = cpu_to_le32 (ccd);
- FLUSH_MEM_WRITE ();
- }
-
- /* Reread the Channel Configuration Descriptor for this channel */
- musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_RX_DIRECTION | gchan);
- musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_TX_DIRECTION | gchan);
-
- /*
- * Figure out how many buffers we want. If the customer has changed from
- * the defaults, then use the changed values. Otherwise, use Transparent
- * mode's specific minimum default settings.
- */
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- {
- if (max_rxdesc_used == max_rxdesc_default) /* use default setting */
- max_rxdesc_used = MUSYCC_RXDESC_TRANS;
- if (max_txdesc_used == max_txdesc_default) /* use default setting */
- max_txdesc_used = MUSYCC_TXDESC_TRANS;
- }
- /*
- * Increase counts when hyperchanneling, since this implies an increase
- * in throughput per channel
- */
- rxnum = max_rxdesc_used + (nts / 4);
- txnum = max_txdesc_used + (nts / 4);
-
-#if 0
- /* DEBUG INFO */
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n",
- ci->devname, ch->p.chan_mode,
- rxnum, max_rxdesc_used, max_rxdesc_default,
- txnum, max_txdesc_used, max_txdesc_default);
-#endif
-
- ch->rxd_num = rxnum;
- ch->txd_num = txnum;
- ch->rxix_irq_srv = 0;
-
- ch->mdr = kzalloc(sizeof(struct mdesc) * rxnum, GFP_KERNEL | GFP_DMA);
- ch->mdt = kzalloc(sizeof(struct mdesc) * txnum, GFP_KERNEL | GFP_DMA);
- if (ch->p.chan_mode == CFG_CH_PROTO_TRANS)
- tmp = __constant_cpu_to_le32 (cxt1e1_max_mru | EOBIRQ_ENABLE);
- else
- tmp = __constant_cpu_to_le32 (cxt1e1_max_mru);
-
- for (i = 0, md = ch->mdr; i < rxnum; i++, md++)
- {
- if (i == (rxnum - 1))
- {
- md->snext = &ch->mdr[0];/* wrapness */
- } else
- {
- md->snext = &ch->mdr[i + 1];
- }
- md->next = cpu_to_le32 (OS_vtophys (md->snext));
-
- m = OS_mem_token_alloc(cxt1e1_max_mru);
- if (!m) {
- if (cxt1e1_log_level >= LOG_MONITOR)
- pr_info(
- "%s: c4_chan_up[%d] - token alloc failure, size = %d.\n",
- ci->devname, channum, cxt1e1_max_mru);
- goto errfree;
- }
- md->mem_token = m;
- md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m)));
- md->status = tmp | MUSYCC_RX_OWNED; /* MUSYCC owns RX descriptor **
- * CODING NOTE:
- * MUSYCC_RX_OWNED = 0 so no
- * need to byteSwap */
- }
-
- for (i = 0, md = ch->mdt; i < txnum; i++, md++)
- {
- md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
- * NOTE: HOST_TX_OWNED = 0 so no need to
- * byteSwap */
- md->mem_token = NULL;
- md->data = 0;
- if (i == (txnum - 1))
- {
- md->snext = &ch->mdt[0];/* wrapness */
- } else
- {
- md->snext = &ch->mdt[i + 1];
- }
- md->next = cpu_to_le32 (OS_vtophys (md->snext));
- }
- ch->txd_irq_srv = ch->txd_usr_add = &ch->mdt[0];
- ch->txd_free = txnum;
- ch->tx_full = 0;
- ch->txd_required = 0;
-
- /* Configure it into the chip */
- tmp = cpu_to_le32 (OS_vtophys (&ch->mdt[0]));
- pi->regram->thp[gchan] = tmp;
- pi->regram->tmp[gchan] = tmp;
-
- tmp = cpu_to_le32 (OS_vtophys (&ch->mdr[0]));
- pi->regram->rhp[gchan] = tmp;
- pi->regram->rmp[gchan] = tmp;
-
- /* Activate the Channel */
- FLUSH_MEM_WRITE ();
- if (ch->p.status & RX_ENABLED)
- {
-#ifdef RLD_TRANS_DEBUG
- pr_info("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum);
-#endif
- ch->ch_start_rx = 0; /* we are restarting RX... */
- musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan);
- }
- if (ch->p.status & TX_ENABLED)
- {
-#ifdef RLD_TRANS_DEBUG
- pr_info("++ c4_chan_up() CHAN TX ACTIVATE: chan %d <delayed>\n", ch->channum);
-#endif
- ch->ch_start_tx = CH_START_TX_1ST; /* we are delaying start
- * until receipt from user of
- * first packet to transmit. */
- }
- ch->status = ch->p.status;
- pi->openchans++;
- return 0;
-
-errfree:
- while (i > 0)
- {
- /* Don't leak all the previously allocated mbufs in this loop */
- i--;
- OS_mem_token_free (ch->mdr[i].mem_token);
- }
- kfree(ch->mdt);
- ch->mdt = NULL;
- ch->txd_num = 0;
- kfree(ch->mdr);
- ch->mdr = NULL;
- ch->rxd_num = 0;
- ch->state = DOWN;
- return -ENOBUFS;
-}
-
-/* stop the hardware from servicing & interrupting */
-
-void
-c4_stopwd (ci_t *ci)
-{
- OS_stop_watchdog (&ci->wd);
- SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_"); /* ensure WD not running */
- SD_SEM_GIVE (&ci->sem_wdbusy);
-}
-
-
-void
-sbecom_get_brdinfo (ci_t *ci, struct sbe_brd_info *bip, u_int8_t *bsn)
-{
- char *np;
- u_int32_t sn = 0;
- int i;
-
- bip->brdno = ci->brdno; /* our board number */
- bip->brd_id = ci->brd_id;
- bip->brd_hdw_id = ci->hdw_bid;
- bip->brd_chan_cnt = MUSYCC_NCHANS *ci->max_port; /* number of channels
- * being used */
- bip->brd_port_cnt = ci->max_port; /* number of ports being used */
- bip->brd_pci_speed = BINFO_PCI_SPEED_unk; /* PCI speed not yet
- * determinable */
-
- if (ci->first_if)
- {
- {
- struct net_device *dev;
-
- dev = (struct net_device *) ci->first_if;
- np = (char *) dev->name;
- }
- strncpy (bip->first_iname, np, CHNM_STRLEN - 1);
- } else
- strcpy (bip->first_iname, "<NULL>");
- if (ci->last_if)
- {
- {
- struct net_device *dev;
-
- dev = (struct net_device *) ci->last_if;
- np = (char *) dev->name;
- }
- strncpy (bip->last_iname, np, CHNM_STRLEN - 1);
- } else
- strcpy (bip->last_iname, "<NULL>");
-
- if (bsn)
- {
- for (i = 0; i < 3; i++)
- {
- bip->brd_mac_addr[i] = *bsn++;
- }
- for (; i < 6; i++)
- {
- bip->brd_mac_addr[i] = *bsn;
- sn = (sn << 8) | *bsn++;
- }
- } else
- {
- for (i = 0; i < 6; i++)
- bip->brd_mac_addr[i] = 0;
- }
- bip->brd_sn = sn;
-}
-
-
-status_t
-c4_get_iidinfo (ci_t *ci, struct sbe_iid_info *iip)
-{
- struct net_device *dev;
- char *np;
-
- dev = getuserbychan(iip->channum);
- if (!dev)
- return -ENOENT;
-
- np = dev->name;
- strncpy (iip->iname, np, CHNM_STRLEN - 1);
- iip->iname[CHNM_STRLEN - 1] = '\0';
- return 0;
-}
-
-
-#ifdef CONFIG_SBE_PMCC4_NCOMM
-void (*nciInterrupt[MAX_BOARDS][4]) (void);
-extern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler);
-
-void
-wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler)
-{
- if (cardID < MAX_BOARDS) /* sanity check */
- nciInterrupt[cardID][deviceID] = handler;
-}
-
-irqreturn_t
-c4_ebus_intr_th_handler (void *devp)
-{
- ci_t *ci = (ci_t *) devp;
- volatile u_int32_t ists;
- int handled = 0;
- int brdno;
-
- /* which COMET caused the interrupt */
- brdno = ci->brdno;
- ists = pci_read_32 ((u_int32_t *) &ci->cpldbase->intr);
- if (ists & PMCC4_CPLD_INTR_CMT_1)
- {
- handled = 0x1;
- if (nciInterrupt[brdno][0] != NULL)
- (*nciInterrupt[brdno][0]) ();
- }
- if (ists & PMCC4_CPLD_INTR_CMT_2)
- {
- handled |= 0x2;
- if (nciInterrupt[brdno][1] != NULL)
- (*nciInterrupt[brdno][1]) ();
- }
- if (ists & PMCC4_CPLD_INTR_CMT_3)
- {
- handled |= 0x4;
- if (nciInterrupt[brdno][2] != NULL)
- (*nciInterrupt[brdno][2]) ();
- }
- if (ists & PMCC4_CPLD_INTR_CMT_4)
- {
- handled |= 0x8;
- if (nciInterrupt[brdno][3] != NULL)
- (*nciInterrupt[brdno][3]) ();
- }
-#if 0
- /*** Test code just de-implements the asserted interrupt. Alternate
- vendor will supply COMET interrupt handling code herein or such.
- ***/
- pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE);
-#endif
-
- return IRQ_RETVAL (handled);
-}
-
-
-unsigned long
-wanpmcC4T1E1_getBaseAddress (int cardID, int deviceID)
-{
- ci_t *ci;
- unsigned long base = 0;
-
- ci = c4_list;
- while (ci)
- {
- if (ci->brdno == cardID) /* found valid device */
- {
- if (deviceID < ci->max_port) /* comet is supported */
- base = ((unsigned long) ci->port[deviceID].cometbase);
- break;
- }
- ci = ci->next; /* next board, if any */
- }
- return base;
-}
-
-#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/
-
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/pmcc4_ioctls.h b/drivers/staging/cxt1e1/pmcc4_ioctls.h
deleted file mode 100644
index 56a1ee39be18..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_ioctls.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _INC_PMCC4_IOCTLS_H_
-#define _INC_PMCC4_IOCTLS_H_
-
-/*-----------------------------------------------------------------------------
- * pmcc4_ioctls.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-#include "sbew_ioc.h"
-
-enum
-{
- // C4_GET_PORT = 0,
- // C4_SET_PORT,
- // C4_GET_CHAN,
- // C4_SET_CHAN,
- C4_DEL_CHAN = 0,
- // C4_CREATE_CHAN,
- // C4_GET_CHAN_STATS,
- // C4_RESET,
- // C4_DEBUG,
- C4_RESET_STATS,
- C4_LOOP_PORT,
- C4_RW_FRMR,
- C4_RW_MSYC,
- C4_RW_PLD
-};
-
-#define C4_GET_PORT SBE_IOC_PORT_GET
-#define C4_SET_PORT SBE_IOC_PORT_SET
-#define C4_GET_CHAN SBE_IOC_CHAN_GET
-#define C4_SET_CHAN SBE_IOC_CHAN_SET
-// #define C4_DEL_CHAN XXX
-#define C4_CREATE_CHAN SBE_IOC_CHAN_NEW
-#define C4_GET_CHAN_STATS SBE_IOC_CHAN_GET_STAT
-#define C4_RESET SBE_IOC_RESET_DEV
-#define C4_DEBUG SBE_IOC_LOGLEVEL
-// #define C4_RESET_STATS XXX
-// #define C4_LOOP_PORT XXX
-// #define C4_RW_FRMR XXX
-// #define C4_RW_MSYC XXX
-// #define C4_RW_PLD XXX
-
-struct c4_chan_stats_wrap
-{
- int channum;
- struct sbecom_chan_stats stats;
-};
-
-#endif /* _INC_PMCC4_IOCTLS_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h
deleted file mode 100644
index 451f12f5b04c..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_private.h
+++ /dev/null
@@ -1,295 +0,0 @@
-#ifndef _INC_PMCC4_PRIVATE_H_
-#define _INC_PMCC4_PRIVATE_H_
-
-/*-----------------------------------------------------------------------------
- * pmcc4_private.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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/kernel.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h> /* support for tasklets */
-#include <linux/timer.h> /* support for timer */
-#include <linux/workqueue.h>
-#include <linux/hdlc.h>
-
-#include "libsbew.h"
-#include "pmcc4_defs.h"
-#include "pmcc4_cpld.h"
-#include "musycc.h"
-#include "sbe_promformat.h"
-#include "comet.h"
-
-
-/* driver state */
-#define SBE_DRVR_INIT 0x0
-#define SBE_DRVR_AVAILABLE 0x69734F4E
-#define SBE_DRVR_DOWN 0x1
-
-/******************************************************************************
- * MUSYCC Message Descriptor - coupled to hardware implementation, the first
- * three u_int32 must not be reordered.
- */
-
-struct mdesc
-{
- volatile u_int32_t status; /* Buffer Descriptor */
- u_int32_t data; /* Data Pointer */
- u_int32_t next; /* MUSYCC view of Next Pointer */
- void *mem_token; /* Data */
- struct mdesc *snext;
-};
-
-
-/*************************************************************************
- * Private driver data structures, internal use only.
- */
-
-struct c4_chan_info
-{
- int gchan; /* channel number within group/port 0-31 */
- int channum; /* absolute channel number 0-128 */
- u_int8_t status;
-#define TX_RECOVERY_MASK 0x0f
-#define TX_ONR_RECOVERY 0x01
-#define TX_BUFF_RECOVERY 0x02
-#define RX_RECOVERY_MASK 0xf0
-#define RX_ONR_RECOVERY 0x10
-
- unsigned char ch_start_rx;
-#define CH_START_RX_NOW 1
-#define CH_START_RX_ONR 2
-#define CH_START_RX_BUF 3
-
- unsigned char ch_start_tx;
-#define CH_START_TX_1ST 1
-#define CH_START_TX_ONR 2
-#define CH_START_TX_BUF 3
-
- char tx_full; /* boolean */
- short txd_free; /* count of TX Desc available */
- short txd_required; /* count of TX Desc needed by mesg */
- unsigned short rxd_num; /* must support range up to 2000 */
- unsigned short txd_num; /* must support range up to 1000 */
- int rxix_irq_srv;
-
- enum
- {
- UNASSIGNED, /* AVAILABLE, NOTINUSE */
- DOWN, /* ASSIGNED, NOTINUSE */
- UP /* ASSIGNED and INUSE */
- } state;
-
- struct c4_port_info *up;
- void *user;
-
- struct work_struct ch_work;
- struct mdesc *mdt;
- struct mdesc *mdr;
- struct mdesc *txd_irq_srv;
- struct mdesc *txd_usr_add;
-
-#if 0
- /*
- * FUTURE CODE MIGHT SEPARATE TIMESLOT MAP SETUPS INTO SINGLE IOCTL and
- * REMOVE MAPS FROM CHANNEL PARAMETER STRUCTURE
- */
- /*
- * each byte in bitmask below represents one timeslot (bitmask[0] is for
- * timeslot 0 and so on), each bit in the byte selects timeslot bits for
- * this channel (0xff - whole timeslot, 0x7f - 56kbps mode)
- */
-
- u_int8_t ts_bitmask[32];
-#endif
- spinlock_t ch_rxlock;
- spinlock_t ch_txlock;
- atomic_t tx_pending;
-
- struct sbecom_chan_stats s;
- struct sbecom_chan_param p;
-};
-typedef struct c4_chan_info mch_t;
-
-struct c4_port_info
-{
-
- struct musycc_globalr *reg;
- struct musycc_groupr *regram;
- void *regram_saved; /* Original malloc value may have non-2KB
- * boundary. Need to save for use when
- * freeing. */
- struct s_comet_reg *cometbase;
- struct sbe_card_info *up;
-
- /*
- * The workqueue is used for TX restart of ONR'd channels when in
- * Transparent mode.
- */
-
- struct workqueue_struct *wq_port; /* chan restart work queue */
- struct semaphore sr_sem_busy; /* service request exclusion
- * semaphore */
- struct semaphore sr_sem_wait; /* service request handshake
- * semaphore */
- u_int32_t sr_last;
- short openchans;
- char portnum;
- char group_is_set; /* GROUP_INIT command issued to MUSYCC,
- * otherwise SET_CHAN Ioctl fails */
-
- mch_t *chan[MUSYCC_NCHANS];
- struct sbecom_port_param p;
-
- /*
- * The MUSYCC timeslot mappings are maintained within the driver and are
- * modified and reloaded as each of a group's channels are configured.
- */
- u_int8_t tsm[32]; /* tsm (time slot map) */
- int fifomap[32];
-};
-typedef struct c4_port_info mpi_t;
-
-
-#define COMET_OFFSET(x) (0x80000+(x)*0x10000)
-#define EEPROM_OFFSET 0xC0000
-#define ISPLD_OFFSET 0xD0000
-
-/* iSPLD control chip registers */
-#define ISPLD_MCSR 0x0
-#define ISPLD_MCLK 0x1
-#define ISPLD_LEDS 0x2
-#define ISPLD_INTR 0x3
-#define ISPLD_MAX 0x3
-
-struct sbe_card_info
-{
- struct musycc_globalr *reg;
- struct musycc_groupr *regram;
- u_int32_t *iqd_p; /* pointer to dword aligned interrupt queue
- * descriptors */
- void *iqd_p_saved; /* Original malloc value may have non-dword
- * aligned boundary. Need to save for use
- * when freeing. */
- unsigned int iqp_headx, iqp_tailx;
-
- struct semaphore sem_wdbusy;/* watchdog exclusion semaphore */
- struct watchdog wd; /* statically allocated watchdog structure */
- atomic_t bh_pending; /* bh queued, but not yet running */
- u_int32_t brd_id; /* unique PCI ID */
- u_int16_t hdw_bid; /* on/board hardware ID */
- unsigned short wdcount;
- unsigned char max_port;
- unsigned char brdno; /* our board number */
- unsigned char wd_notify;
-#define WD_NOTIFY_1TX 1
-#define WD_NOTIFY_BUF 2
-#define WD_NOTIFY_ONR 4
- enum /* state as regards interrupt processing */
- {
- C_INIT, /* of-board-address not configured or are in
- * process of being removed, don't access
- * hardware */
- C_IDLE, /* off-board-addresses are configured, but
- * don't service interrupts, just clear them
- * from hardware */
- C_RUNNING /* life is good, service away */
- } state;
-
- struct sbe_card_info *next;
- u_int32_t *eeprombase; /* mapped address of board's EEPROM */
- c4cpld_t *cpldbase; /* mapped address of board's CPLD hardware */
- void *hdw_info;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *dir_dev;
-#endif
-
- /* saved off interface assignments which bound a board */
- hdlc_device *first_if;
- hdlc_device *last_if;
- short first_channum, last_channum;
-
- struct intlog
- {
- u_int32_t this_status_new;
- u_int32_t last_status_new;
- u_int32_t drvr_intr_thcount;
- u_int32_t drvr_intr_bhcount;
- u_int32_t drvr_int_failure;
- } intlog;
-
- mpi_t port[MUSYCC_NPORTS];
- char devname[SBE_IFACETMPL_SIZE + 1];
- atomic_t tx_pending;
- u_int32_t alarmed[4]; /* dpm211 */
-
-#if defined(SBE_ISR_TASKLET)
- struct tasklet_struct ci_musycc_isr_tasklet;
-#elif defined(SBE_ISR_IMMEDIATE)
- struct tq_struct ci_musycc_isr_tq;
-#endif
-};
-typedef struct sbe_card_info ci_t;
-
-struct s_hdw_info
-{
- u_int8_t pci_busno;
- u_int8_t pci_slot;
- u_int8_t pci_pin[2];
- u_int8_t revid[2];
- u_int8_t mfg_info_sts;
-#define EEPROM_OK 0x00
-#define EEPROM_CRCERR 0x01
- char promfmt; /* prom type, from sbe_promformat.h */
-
- char devname[SBE_IFACETMPL_SIZE];
- struct pci_bus *bus;
- struct net_device *ndev;
- struct pci_dev *pdev[2];
-
- unsigned long addr[2];
- void __iomem *addr_mapped[2];
- unsigned long len[2];
-
- union
- {
- char data[128];
- FLD_TYPE1 pft1; /* prom field, type #1 */
- FLD_TYPE2 pft2; /* prom field, type #2 */
- } mfg_info;
-};
-typedef struct s_hdw_info hdw_info_t;
-
-/*****************************************************************/
-
-struct c4_priv
-{
- int channum;
- struct sbe_card_info *ci;
-};
-
-
-/*****************************************************************/
-
-extern ci_t *c4_list;
-
-mch_t *c4_find_chan (int);
-int c4_set_chan (int channum, struct sbecom_chan_param *);
-int c4_get_chan (int channum, struct sbecom_chan_param *);
-int c4_get_chan_stats (int channum, struct sbecom_chan_stats *);
-
-#endif /* _INC_PMCC4_PRIVATE_H_ */
diff --git a/drivers/staging/cxt1e1/pmcc4_sysdep.h b/drivers/staging/cxt1e1/pmcc4_sysdep.h
deleted file mode 100644
index 2916c2cb13f9..000000000000
--- a/drivers/staging/cxt1e1/pmcc4_sysdep.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _INC_PMCC4_SYSDEP_H_
-#define _INC_PMCC4_SYSDEP_H_
-
-/*-----------------------------------------------------------------------------
- * pmcc4_sysdep.h -
- *
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- */
-
-/* reduce multiple autoconf entries to a single definition */
-
-#ifdef CONFIG_SBE_PMCC4_HDLC_V7_MODULE
-#undef CONFIG_SBE_PMCC4_HDLC_V7
-#define CONFIG_SBE_PMCC4_HDLC_V7 1
-#endif
-
-#ifdef CONFIG_SBE_PMCC4_NCOMM_MODULE
-#undef CONFIG_SBE_PMCC4_NCOMM
-#define CONFIG_SBE_PMCC4_NCOMM 1
-#endif
-
-
-/* FLUSH MACROS - if using ioremap_nocache(), then these can be NOOPS,
- * otherwise a memory barrier needs to be inserted.
- */
-
-#define FLUSH_PCI_READ() rmb()
-#define FLUSH_PCI_WRITE() wmb()
-#define FLUSH_MEM_READ() rmb()
-#define FLUSH_MEM_WRITE() wmb()
-
-
-/*
- * System dependent callbacks routines, not inlined...
- * For inlined system dependent routines, see include/sbecom_inlinux_linux.h
- */
-
-/*
- * passes received memory token back to the system, <user> is parameter from
- * sd_new_chan() used to create the channel which the data arrived on
- */
-
-void sd_recv_consume(void *token, size_t len, void *user);
-
-void sd_disable_xmit (void *user);
-void sd_enable_xmit (void *user);
-int sd_line_is_ok (void *user);
-void sd_line_is_up (void *user);
-void sd_line_is_down (void *user);
-int sd_queue_stopped (void *user);
-
-#endif /*** _INC_PMCC4_SYSDEP_H_ ***/
-extern int cxt1e1_log_level;
diff --git a/drivers/staging/cxt1e1/sbe_bid.h b/drivers/staging/cxt1e1/sbe_bid.h
deleted file mode 100644
index abc2e55f62fc..000000000000
--- a/drivers/staging/cxt1e1/sbe_bid.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _INC_SBEBID_H_
-#define _INC_SBEBID_H_
-
-/*-----------------------------------------------------------------------------
- * sbe_bid.h -
- *
- * Copyright (C) 2004-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *
- *-----------------------------------------------------------------------------
- */
-
-#define SBE_BID_REG 0x00000000 /* Board ID Register */
-
-#define SBE_BID_256T3_E1 0x46 /* SBE wanPTMC-256T3 (E1 Version) */
-#define SBE_BID_256T3_T1 0x42 /* SBE wanPTMC-256T3 (T1 Version) */
-#define SBE_BID_2T3E3 0x43 /* SBE wanPMC-2T3E3 */
-#define SBE_BID_C1T3 0x45 /* SBE wanPMC-C1T3 */
-#define SBE_BID_C24TE1 0x47 /* SBE wanPTMC-C24TE1 */
-#define SBE_BID_C24TE1_RTM_24 0x48 /* C24TE1 RTM (24 Port) */
-#define SBE_BID_C24TE1_RTM_12 0x49 /* C24TE1 RTM (12 Port) */
-#define SBE_BID_C24TE1_RTM_12DSU 0x4A /* C24TE1 RTM (12 Port/DSU) */
-#define SBE_BID_C24TE1_RTM_T3 0x4B /* C24TE1 RTM (T3) */
-#define SBE_BID_C4T1E1 0x41 /* SBE wanPTMC-C4T1E1 */
-#define SBE_BID_HC4T1E1 0x44 /* SBE wanADAPT-HC4T1E1 */
-
-/* bogus temporary usage values */
-#define SBE_BID_PMC_C4T1E1 0xC4 /* SBE wanPMC-C4T1E1 (4 Port) */
-#define SBE_BID_PMC_C2T1E1 0xC2 /* SBE wanPMC-C2T1E1 (2 Port) */
-#define SBE_BID_PMC_C1T1E1 0xC1 /* SBE wanPMC-C1T1E1 (1 Port) */
-#define SBE_BID_PCI_C4T1E1 0x04 /* SBE wanPCI-C4T1E1 (4 Port) */
-#define SBE_BID_PCI_C2T1E1 0x02 /* SBE wanPCI-C2T1E1 (2 Port) */
-#define SBE_BID_PCI_C1T1E1 0x01 /* SBE wanPCI-C1T1E1 (1 Port) */
-
-#endif /*** _INC_SBEBID_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbe_promformat.h b/drivers/staging/cxt1e1/sbe_promformat.h
deleted file mode 100644
index aad411d185f5..000000000000
--- a/drivers/staging/cxt1e1/sbe_promformat.h
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef _INC_SBE_PROMFORMAT_H_
-#define _INC_SBE_PROMFORMAT_H_
-
-/*-----------------------------------------------------------------------------
- * sbe_promformat.h - Contents of seeprom used by dvt and manufacturing tests
- *
- * Copyright (C) 2002-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *
- *-----------------------------------------------------------------------------
- */
-
-
-/***
- * PMCC4 SAMPLE EEPROM IMAGE
- *
- * eeprom[00]: 01 11 76 07 01 00 a0 d6
- * eeprom[08]: 22 34 56 3e 5b c1 1c 3e
- * eeprom[16]: 5b e1 b6 00 00 00 01 00
- * eeprom[24]: 00 08 46 d3 7b 5e a8 fb
- * eeprom[32]: f7 ef df bf 7f 55 00 01
- * eeprom[40]: 02 04 08 10 20 40 80 ff
- * eeprom[48]: fe fd fb f7 ef df bf 7f
- *
- ***/
-
-
-/*------------------------------------------------------------------------
- * Type 1 Format
- * byte:
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
- * -------------------------------------------------------------------------
- * 01 11 76 SS SS 00 0A D6 <SERIAL NUM> <Create TIME> <Heatrun TIME>
- * SBE SUB SERIAL # (BCD) (time_t) (time_t)
- * ID VENDOR (format) (format)
- *
- * 19 20 21 22 23 24 25 26
- * Heat Run Heat Run
- * Iterations Errors
- *------------------------------------------------------------------------
- *
- *
- *
- * Type 2 Format - Added length, CRC in fixed position
- * byte:
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- * -------------------------------------------------------------------------
- * 02 00 1A CC CC CC CC 11 76 07 03 00 0A D6 <SERIAL NUM>
- * Payload SBE Crc32 SUB System System SERIAL/MAC
- * Length VENDOR ID ID
- *
- * 17 18 19 20 21 22 23 24 25 26 27 28 29 39 31 32
- * --------------------------------------------------------------------------
- * <Create TIME> <Heatrun TIME> Heat Run Heat Run
- * (time_t) (time_t) Iterations Errors
- *
- */
-
-#define STRUCT_OFFSET(type, symbol) ((long)&(((type *)0)->symbol))
-
-/*------------------------------------------------------------------------
- * Historically different Prom format types.
- *
- * For diagnostic and failure purposes, do not create a type 0x00 or a
- * type 0xff
- *------------------------------------------------------------------------
- */
-#define PROM_FORMAT_Unk (-1)
-#define PROM_FORMAT_TYPE1 1
-#define PROM_FORMAT_TYPE2 2
-
-
-/****** bit fields for a type 1 formatted seeprom **************************/
- typedef struct
- {
- char type; /* 0x00 */
- char Id[2]; /* 0x01-0x02 */
- char SubId[2]; /* 0x03-0x04 */
- char Serial[6]; /* 0x05-0x0a */
- char CreateTime[4]; /* 0x0b-0x0e */
- char HeatRunTime[4]; /* 0x0f-0x12 */
- char HeatRunIterations[4]; /* 0x13-0x16 */
- char HeatRunErrors[4]; /* 0x17-0x1a */
- char Crc32[4]; /* 0x1b-0x1e */
- } FLD_TYPE1;
-
-
-/****** bit fields for a type 2 formatted seeprom **************************/
- typedef struct
- {
- char type; /* 0x00 */
- char length[2]; /* 0x01-0x02 */
- char Crc32[4]; /* 0x03-0x06 */
- char Id[2]; /* 0x07-0x08 */
- char SubId[2]; /* 0x09-0x0a */
- char Serial[6]; /* 0x0b-0x10 */
- char CreateTime[4]; /* 0x11-0x14 */
- char HeatRunTime[4]; /* 0x15-0x18 */
- char HeatRunIterations[4]; /* 0x19-0x1c */
- char HeatRunErrors[4]; /* 0x1d-0x20 */
- } FLD_TYPE2;
-
-
-
-/***** this union allows us to access the seeprom as an array of bytes ***/
-/***** or as individual fields ***/
-
-#define SBE_EEPROM_SIZE 128
-#define SBE_MFG_INFO_SIZE sizeof(FLD_TYPE2)
-
- typedef union
- {
- char bytes[128];
- FLD_TYPE1 fldType1;
- FLD_TYPE2 fldType2;
- } PROMFORMAT;
-
-#endif /*** _INC_SBE_PROMFORMAT_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h
deleted file mode 100644
index f5835c29ef32..000000000000
--- a/drivers/staging/cxt1e1/sbecom_inline_linux.h
+++ /dev/null
@@ -1,193 +0,0 @@
-#ifndef _INC_SBECOM_INLNX_H_
-#define _INC_SBECOM_INLNX_H_
-
-/*-----------------------------------------------------------------------------
- * sbecom_inline_linux.h - SBE common Linux inlined routines
- *
- * Copyright (C) 2007 One Stop Systems, Inc.
- * Copyright (C) 2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@onestopsystems.com
- * One Stop Systems, Inc. Escondido, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/kernel.h> /* resolves kmalloc references */
-#include <linux/skbuff.h> /* resolves skb references */
-#include <linux/netdevice.h> /* resolves dev_kree_skb_any */
-#include <asm/byteorder.h> /* resolves cpu_to_le32 */
-
-/* forward reference */
-u_int32_t pci_read_32 (u_int32_t *p);
-void pci_write_32 (u_int32_t *p, u_int32_t v);
-
-
-/*
- * system dependent callbacks
- */
-
-/****************/
-/* memory token */
-/****************/
-
-static inline void *
-OS_mem_token_alloc (size_t size)
-{
- struct sk_buff *skb;
-
- skb = dev_alloc_skb (size);
- if (!skb)
- {
- //pr_warning("no mem in OS_mem_token_alloc !\n");
- return NULL;
- }
- return skb;
-}
-
-
-static inline void
-OS_mem_token_free (void *token)
-{
- dev_kfree_skb_any (token);
-}
-
-
-static inline void
-OS_mem_token_free_irq (void *token)
-{
- dev_kfree_skb_irq (token);
-}
-
-
-static inline void *
-OS_mem_token_data (void *token)
-{
- return ((struct sk_buff *) token)->data;
-}
-
-
-static inline void *
-OS_mem_token_next (void *token)
-{
- return NULL;
-}
-
-
-static inline int
-OS_mem_token_len (void *token)
-{
- return ((struct sk_buff *) token)->len;
-}
-
-
-static inline int
-OS_mem_token_tlen (void *token)
-{
- return ((struct sk_buff *) token)->len;
-}
-
-
-/***************************************/
-/* virtual to physical addr conversion */
-/***************************************/
-
-static inline u_long
-OS_phystov (void *addr)
-{
- return (u_long) __va (addr);
-}
-
-
-static inline u_long
-OS_vtophys (void *addr)
-{
- return __pa (addr);
-}
-
-
-/**********/
-/* semops */
-/**********/
-
-void OS_sem_init (void *, int);
-
-
-static inline void
-OS_sem_free (void *sem)
-{
- /*
- * NOOP - since semaphores structures predeclared w/in structures, no
- * longer malloc'd
- */
-}
-
-#define SD_SEM_TAKE(sem,desc) down(sem)
-#define SD_SEM_GIVE(sem) up(sem)
-#define SEM_AVAILABLE 1
-#define SEM_TAKEN 0
-
-
-/**********************/
-/* watchdog functions */
-/**********************/
-
-struct watchdog
-{
- struct timer_list h;
- struct work_struct work;
- void *softc;
- void (*func) (void *softc);
- int ticks;
- int init_tq;
-};
-
-
-static inline int
-OS_start_watchdog (struct watchdog *wd)
-{
- wd->h.expires = jiffies + wd->ticks;
- add_timer (&wd->h);
- return 0;
-}
-
-
-static inline int
-OS_stop_watchdog (struct watchdog *wd)
-{
- del_timer_sync (&wd->h);
- return 0;
-}
-
-
-static inline int
-OS_free_watchdog (struct watchdog *wd)
-{
- OS_stop_watchdog (wd);
- kfree(wd);
- return 0;
-}
-
-
-/* sleep in microseconds */
-void OS_uwait (int usec, char *description);
-void OS_uwait_dummy (void);
-
-
-/* watchdog functions */
-int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *ci, int usec);
-
-
-#endif /*** _INC_SBECOM_INLNX_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbecrc.c b/drivers/staging/cxt1e1/sbecrc.c
deleted file mode 100644
index a51780f60484..000000000000
--- a/drivers/staging/cxt1e1/sbecrc.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs'
- * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
- * values as ZMODEM and PKZIP
- *
- * Copyright (C) 2002-2005 SBE, Inc.
- *
- * 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/types.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "sbe_promformat.h"
-
-/* defines */
-#define CRC32_POLYNOMIAL 0xEDB88320L
-#define CRC_TABLE_ENTRIES 256
-
-
-
-static u_int32_t crcTableInit;
-
-#ifdef STATIC_CRC_TABLE
-static u_int32_t CRCTable[CRC_TABLE_ENTRIES];
-
-#endif
-
-
-/***************************************************************************
-*
-* genCrcTable - fills in CRCTable, as used by sbeCrc()
-*
-* RETURNS: N/A
-*
-* ERRNO: N/A
-***************************************************************************/
-
-static void
-genCrcTable(u_int32_t *CRCTable)
-{
- int ii, jj;
- u_int32_t crc;
-
- for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) {
- crc = ii;
- for (jj = 8; jj > 0; jj--) {
- if (crc & 1)
- crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
- else
- crc >>= 1;
- }
- CRCTable[ii] = crc;
- }
-
- crcTableInit++;
-}
-
-
-/***************************************************************************
-*
-* sbeCrc - generates a CRC on a given buffer, and initial CRC
-*
-* This routine calculates the CRC for a buffer of data using the
-* table lookup method. It accepts an original value for the crc,
-* and returns the updated value. This permits "catenation" of
-* discontiguous buffers. An original value of 0 for the "first"
-* buffer is the norm.
-*
-* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's
-* Journal, May 1992, pp. 64-67. This algorithm generates the same CRC
-* values as ZMODEM and PKZIP.
-*
-* RETURNS: calculated crc of block
-*
-*/
-
-void
-sbeCrc(u_int8_t *buffer, /* data buffer to crc */
- u_int32_t count, /* length of block in bytes */
- u_int32_t initialCrc, /* starting CRC */
- u_int32_t *result)
-{
- u_int32_t *tbl = NULL;
- u_int32_t temp1, temp2, crc;
-
- /*
- * if table not yet created, do so. Don't care about "extra" time
- * checking this every time sbeCrc() is called, since CRC calculations
- * are already time consuming
- */
- if (!crcTableInit) {
-#ifdef STATIC_CRC_TABLE
- tbl = &CRCTable;
- genCrcTable(tbl);
-#else
- tbl = kzalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t),
- GFP_KERNEL);
- if (!tbl) {
- *result = 0; /* dummy up return value due to malloc
- * failure */
- return;
- }
- genCrcTable(tbl);
-#endif
- }
- /* inverting bits makes ZMODEM & PKZIP compatible */
- crc = initialCrc ^ 0xFFFFFFFFL;
-
- while (count-- != 0) {
- temp1 = (crc >> 8) & 0x00FFFFFFL;
- temp2 = tbl[((int) crc ^ *buffer++) & 0xff];
- crc = temp1 ^ temp2;
- }
-
- crc ^= 0xFFFFFFFFL;
-
- *result = crc;
-
-#ifndef STATIC_CRC_TABLE
- crcTableInit = 0;
- kfree(tbl);
-#endif
-}
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/sbeid.c b/drivers/staging/cxt1e1/sbeid.c
deleted file mode 100644
index 97c5c6e7e299..000000000000
--- a/drivers/staging/cxt1e1/sbeid.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Copyright (C) 2005 SBE, Inc.
- *
- * 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/types.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "libsbew.h"
-#include "pmcc4_private.h"
-#include "pmcc4.h"
-#include "sbe_bid.h"
-
-char *
-sbeid_get_bdname(ci_t *ci)
-{
- char *np = NULL;
-
- switch (ci->brd_id) {
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
- np = "wanPTMC-256T3 <E1>";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
- np = "wanPTMC-256T3 <T1>";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
- np = "wanPMC-C4T1E1";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
- np = "wanPMC-C2T1E1";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
- np = "wanPMC-C1T1E1";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
- np = "wanPCI-C4T1E1";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
- np = "wanPCI-C2T1E1";
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
- np = "wanPCI-C1T1E1";
- break;
- default:
- /*** np = "<unknown>"; ***/
- np = "wanPCI-CxT1E1";
- break;
- }
-
- return np;
-}
-
-
-/* given the presetting of brd_id, set the corresponding hdw_id */
-
-void
-sbeid_set_hdwbid(ci_t *ci)
-{
- /*
- * set SBE's unique hardware identification (for legacy boards might not
- * have this register implemented)
- */
-
- switch (ci->brd_id) {
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
- ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1
- * Version) */
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
- ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1
- * Version) */
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
- /*
- * This Board ID is a generic identification. Use the found number
- * of ports to further define this hardware.
- */
- switch (ci->max_port) {
- default: /* shouldn't need a default, but have one
- * anyway */
- case 4:
- ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */
- break;
- case 2:
- ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
- break;
- case 1:
- ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
- break;
- }
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
- ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
- ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */
- break;
-#ifdef SBE_PMCC4_ENABLE
- /*
- * This case is entered as a result of the inability to obtain the
- * <bid> from the board's EEPROM. Assume a PCI board and set
- * <hdsbid> according to the number ofr found ports.
- */
- case 0:
- /* start by assuming 4-port for ZERO casing */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
- /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */
-#endif
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
- /*
- * This Board ID is a generic identification. Use the number of
- * found ports to further define this hardware.
- */
- switch (ci->max_port) {
- default: /* shouldn't need a default, but have one
- * anyway */
- case 4:
- ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */
- break;
- case 2:
- ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
- break;
- case 1:
- ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
- break;
- }
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
- ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
- ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */
- break;
- default:
- /*** bid = "<unknown>"; ***/
- ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */
- break;
- }
-}
-
-/* given the presetting of hdw_bid, set the corresponding brd_id */
-
-void
-sbeid_set_bdtype(ci_t *ci)
-{
- /* set SBE's unique PCI VENDOR/DEVID */
- switch (ci->hdw_bid) {
- case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3);
- break;
- case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1);
- break;
- case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1);
- break;
- case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1);
- break;
- case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1);
- break;
- case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1);
- break;
- case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1);
- break;
- case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
- break;
- case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1);
- break;
- case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1);
- break;
-
- default:
- /*** hdw_bid = "<unknown>"; ***/
- ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1);
- break;
- }
-}
-
-
-/*** End-of-File ***/
diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c
deleted file mode 100644
index 1c2e52e8b5fe..000000000000
--- a/drivers/staging/cxt1e1/sbeproc.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (C) 2004-2005 SBE, Inc.
- *
- * 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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/sched.h>
-#include <asm/uaccess.h>
-#include "pmcc4_sysdep.h"
-#include "sbecom_inline_linux.h"
-#include "pmcc4_private.h"
-#include "sbeproc.h"
-
-extern void sbecom_get_brdinfo(ci_t *, struct sbe_brd_info *, u_int8_t *);
-extern struct s_hdw_info hdw_info[MAX_BOARDS];
-
-void sbecom_proc_brd_cleanup(ci_t *ci)
-{
- if (ci->dir_dev) {
- char dir[7 + SBE_IFACETMPL_SIZE + 1];
- snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
- remove_proc_entry("info", ci->dir_dev);
- remove_proc_entry(dir, NULL);
- ci->dir_dev = NULL;
- }
-}
-
-static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
-{
- hdw_info_t *hi = &hdw_info[ci->brdno];
- u_int8_t *bsn = NULL;
-
- switch (hi->promfmt)
- {
- case PROM_FORMAT_TYPE1:
- bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
- break;
- case PROM_FORMAT_TYPE2:
- bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
- break;
- }
-
- sbecom_get_brdinfo (ci, bip, bsn);
-
- pr_devel(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
- bip->first_iname, bip->first_iname,
- bip->last_iname, bip->last_iname);
-}
-
-/*
- * Describe the driver state through /proc
- */
-static int sbecom_proc_get_sbe_info(struct seq_file *m, void *v)
-{
- ci_t *ci = m->private;
- char *spd;
- struct sbe_brd_info *bip;
-
- bip = kzalloc(sizeof(struct sbe_brd_info), GFP_KERNEL | GFP_DMA);
- if (!bip)
- return -ENOMEM;
-
- pr_devel(">> sbecom_proc_get_sbe_info: entered\n");
-
- sbecom_proc_get_brdinfo(ci, bip);
-
- seq_puts(m, "Board Type: ");
- switch (bip->brd_id) {
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
- seq_puts(m, "wanPMC-C1T3");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
- seq_puts(m, "wanPTMC-256T3 <E1>");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
- seq_puts(m, "wanPTMC-256T3 <T1>");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
- seq_puts(m, "wanPTMC-C24TE1");
- break;
-
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
- seq_puts(m, "wanPMC-C4T1E1");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
- seq_puts(m, "wanPMC-C2T1E1");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
- seq_puts(m, "wanPMC-C1T1E1");
- break;
-
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
- seq_puts(m, "wanPCI-C4T1E1");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
- seq_puts(m, "wanPCI-C2T1E1");
- break;
- case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
- seq_puts(m, "wanPCI-C1T1E1");
- break;
-
- default:
- seq_puts(m, "unknown");
- break;
- }
-
- seq_printf(m, " [%08X]\n", bip->brd_id);
-
- seq_printf(m, "Board Number: %d\n", bip->brdno);
- seq_printf(m, "Hardware ID: 0x%02X\n", ci->hdw_bid);
- seq_printf(m, "Board SN: %06X\n", bip->brd_sn);
- seq_printf(m, "Board MAC: %pMF\n", bip->brd_mac_addr);
- seq_printf(m, "Ports: %d\n", ci->max_port);
- seq_printf(m, "Channels: %d\n", bip->brd_chan_cnt);
-#if 1
- seq_printf(m, "Interface: %s -> %s\n",
- bip->first_iname, bip->last_iname);
-#else
- seq_printf(m, "Interface: <not available> 1st %p lst %p\n",
- bip->first_iname, bip->last_iname);
-#endif
-
- switch (bip->brd_pci_speed) {
- case BINFO_PCI_SPEED_33:
- spd = "33Mhz";
- break;
- case BINFO_PCI_SPEED_66:
- spd = "66Mhz";
- break;
- default:
- spd = "<not available>";
- break;
- }
- seq_printf(m, "PCI Bus Speed: %s\n", spd);
-
-#ifdef SBE_PMCC4_ENABLE
- {
- extern int cxt1e1_max_mru;
-#if 0
- extern int max_chans_used;
- extern int cxt1e1_max_mtu;
-#endif
- extern int max_rxdesc_used, max_txdesc_used;
-
- seq_printf(m, "\ncxt1e1_max_mru: %d\n", cxt1e1_max_mru);
-#if 0
- seq_printf(m, "\nmax_chans_used: %d\n", max_chans_used);
- seq_printf(m, "cxt1e1_max_mtu: %d\n", cxt1e1_max_mtu);
-#endif
- seq_printf(m, "max_rxdesc_used: %d\n", max_rxdesc_used);
- seq_printf(m, "max_txdesc_used: %d\n", max_txdesc_used);
- }
-#endif
-
- kfree(bip);
-
- pr_devel(">> proc_fs: finished\n");
- return 0;
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int sbecom_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, sbecom_proc_get_sbe_info, PDE_DATA(inode));
-}
-
-static const struct file_operations sbecom_proc_fops = {
- .open = sbecom_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/*
- * Initialize the /proc subsystem for the specific SBE driver
- */
-int __init sbecom_proc_brd_init(ci_t *ci)
-{
- char dir[7 + SBE_IFACETMPL_SIZE + 1];
-
- snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
- ci->dir_dev = proc_mkdir(dir, NULL);
- if (!ci->dir_dev) {
- pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
- goto fail;
- }
-
- if (!proc_create_data("info", S_IFREG | S_IRUGO, ci->dir_dev,
- &sbecom_proc_fops, ci)) {
- pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
- goto fail;
- }
- return 0;
-
-fail:
- sbecom_proc_brd_cleanup(ci);
- return 1;
-}
diff --git a/drivers/staging/cxt1e1/sbeproc.h b/drivers/staging/cxt1e1/sbeproc.h
deleted file mode 100644
index 37285df359c1..000000000000
--- a/drivers/staging/cxt1e1/sbeproc.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _INC_SBEPROC_H_
-#define _INC_SBEPROC_H_
-
-/*-----------------------------------------------------------------------------
- * sbeproc.h -
- *
- * Copyright (C) 2004-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *-----------------------------------------------------------------------------
- */
-
-
-#ifdef CONFIG_PROC_FS
-void sbecom_proc_brd_cleanup (ci_t *);
-int __init sbecom_proc_brd_init (ci_t *);
-
-#else
-
-static inline void sbecom_proc_brd_cleanup(ci_t *ci)
-{
-}
-
-static inline int __init sbecom_proc_brd_init(ci_t *ci)
-{
- return 0;
-}
-
-#endif /*** CONFIG_PROC_FS ***/
-
-#endif /*** _INC_SBEPROC_H_ ***/
diff --git a/drivers/staging/cxt1e1/sbew_ioc.h b/drivers/staging/cxt1e1/sbew_ioc.h
deleted file mode 100644
index e1e5bfc9ad37..000000000000
--- a/drivers/staging/cxt1e1/sbew_ioc.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef _INC_SBEWIOC_H_
-#define _INC_SBEWIOC_H_
-
-/*-----------------------------------------------------------------------------
- * sbew_ioc.h -
- *
- * Copyright (C) 2002-2005 SBE, Inc.
- *
- * 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.
- *
- * For further information, contact via email: support@sbei.com
- * SBE, Inc. San Ramon, California U.S.A.
- *
- *-----------------------------------------------------------------------------
- */
-
-#include <linux/ioctl.h>
-
-#define SBE_LOCKFILE "/tmp/.sbewan.LCK"
-
-#define SBE_IOC_COOKIE 0x19780926
-#define SBE_IOC_MAGIC ('s')
-
-/* IOW write - data has to go into driver from application */
-/* IOR read - data has to be returned to application from driver */
-
-/*
- * Note: for an IOWR Ioctl, the read and write data do not have to
- * be the same size, but the entity declared within the IOC must be
- * the larger of the two.
- */
-
-#define SBE_IOC_LOGLEVEL _IOW(SBE_IOC_MAGIC, 0x00, int)
-#define SBE_IOC_CHAN_NEW _IOW(SBE_IOC_MAGIC, 0x01, int) /* unused */
-#define SBE_IOC_CHAN_UP _IOW(SBE_IOC_MAGIC, 0x02, int) /* unused */
-#define SBE_IOC_CHAN_DOWN _IOW(SBE_IOC_MAGIC, 0x03, int) /* unused */
-#define SBE_IOC_CHAN_GET _IOWR(SBE_IOC_MAGIC, 0x04, struct sbecom_chan_param)
-#define SBE_IOC_CHAN_SET _IOW(SBE_IOC_MAGIC, 0x05, struct sbecom_chan_param)
-#define SBE_IOC_CHAN_GET_STAT _IOWR(SBE_IOC_MAGIC, 0x06, struct sbecom_chan_stats)
-#define SBE_IOC_CHAN_DEL_STAT _IOW(SBE_IOC_MAGIC, 0x07, int)
-#define SBE_IOC_PORTS_ENABLE _IOW(SBE_IOC_MAGIC, 0x0A, int)
-#define SBE_IOC_PORT_GET _IOWR(SBE_IOC_MAGIC, 0x0C, struct sbecom_port_param)
-#define SBE_IOC_PORT_SET _IOW(SBE_IOC_MAGIC, 0x0D, struct sbecom_port_param)
-#define SBE_IOC_READ_VEC _IOWR(SBE_IOC_MAGIC, 0x10, struct sbecom_wrt_vec)
-#define SBE_IOC_WRITE_VEC _IOWR(SBE_IOC_MAGIC, 0x11, struct sbecom_wrt_vec)
-#define SBE_IOC_GET_SN _IOR(SBE_IOC_MAGIC, 0x12, u_int32_t)
-#define SBE_IOC_RESET_DEV _IOW(SBE_IOC_MAGIC, 0x13, int)
-#define SBE_IOC_FRAMER_GET _IOWR(SBE_IOC_MAGIC, 0x14, struct sbecom_framer_param)
-#define SBE_IOC_FRAMER_SET _IOW(SBE_IOC_MAGIC, 0x15, struct sbecom_framer_param)
-#define SBE_IOC_CARD_GET _IOR(SBE_IOC_MAGIC, 0x20, struct sbecom_card_param)
-#define SBE_IOC_CARD_SET _IOW(SBE_IOC_MAGIC, 0x21, struct sbecom_card_param)
-#define SBE_IOC_CARD_GET_STAT _IOR(SBE_IOC_MAGIC, 0x22, struct temux_card_stats)
-#define SBE_IOC_CARD_DEL_STAT _IO(SBE_IOC_MAGIC, 0x23)
-#define SBE_IOC_CARD_CHAN_STAT _IOR(SBE_IOC_MAGIC, 0x24, struct sbecom_chan_stats)
-#define SBE_IOC_CARD_BLINK _IOW(SBE_IOC_MAGIC, 0x30, int)
-#define SBE_IOC_DRVINFO_GET _IOWR(SBE_IOC_MAGIC, 0x31, struct sbe_drv_info)
-#define SBE_IOC_BRDINFO_GET _IOR(SBE_IOC_MAGIC, 0x32, struct sbe_brd_info)
-#define SBE_IOC_IID_GET _IOWR(SBE_IOC_MAGIC, 0x33, struct sbe_iid_info)
-#define SBE_IOC_BRDADDR_GET _IOWR(SBE_IOC_MAGIC, 0x34, struct sbe_brd_addr)
-
-#ifdef NOT_YET_COMMON
-#define SBE_IOC_TSIOC_GET _IOWR(SBE_IOC_MAGIC, 0x16, struct wanc1t3_ts_param)
-#define SBE_IOC_TSIOC_SET _IOW(SBE_IOC_MAGIC, 0x17, struct wanc1t3_ts_param)
-#endif
-
-/*
- * Restrict SBE_IOC_WRITE_VEC & READ_VEC to a single parameter pair, application
- * then must issue multiple Ioctls for large blocks of contiguous data.
- */
-
-#define SBE_IOC_MAXVEC 1
-
-#endif /*** _INC_SBEWIOC_H_ ***/
diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c
index 170d6f3e4221..06c55cb57090 100644
--- a/drivers/staging/dgap/dgap.c
+++ b/drivers/staging/dgap/dgap.c
@@ -70,14 +70,14 @@ MODULE_SUPPORTED_DEVICE("dgap");
static int dgap_start(void);
static void dgap_init_globals(void);
-static int dgap_found_board(struct pci_dev *pdev, int id);
+static struct board_t *dgap_found_board(struct pci_dev *pdev, int id,
+ int boardnum);
static void dgap_cleanup_board(struct board_t *brd);
static void dgap_poll_handler(ulong dummy);
-static int dgap_init_pci(void);
static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void dgap_remove_one(struct pci_dev *dev);
-static int dgap_probe1(struct pci_dev *pdev, int card_type);
static int dgap_do_remap(struct board_t *brd);
+static void dgap_release_remap(struct board_t *brd);
static irqreturn_t dgap_intr(int irq, void *voidbrd);
static int dgap_tty_open(struct tty_struct *tty, struct file *file);
@@ -86,12 +86,12 @@ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file,
struct channel_t *ch);
static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
unsigned long arg);
-static int dgap_tty_digigeta(struct tty_struct *tty,
- struct digi_t __user *retinfo);
-static int dgap_tty_digiseta(struct tty_struct *tty,
- struct digi_t __user *new_info);
+static int dgap_tty_digigeta(struct channel_t *ch, struct digi_t __user *retinfo);
+static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, struct digi_t __user *new_info);
static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo);
-static int dgap_tty_digisetedelay(struct tty_struct *tty, int __user *new_info);
+static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, int __user *new_info);
static int dgap_tty_write_room(struct tty_struct *tty);
static int dgap_tty_chars_in_buffer(struct tty_struct *tty);
static void dgap_tty_start(struct tty_struct *tty);
@@ -102,14 +102,14 @@ static void dgap_tty_flush_chars(struct tty_struct *tty);
static void dgap_tty_flush_buffer(struct tty_struct *tty);
static void dgap_tty_hangup(struct tty_struct *tty);
static int dgap_wait_for_drain(struct tty_struct *tty);
-static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command,
- unsigned int __user *value);
+static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, struct un_t *un,
+ unsigned int command, unsigned int __user *value);
static int dgap_get_modem_info(struct channel_t *ch,
unsigned int __user *value);
-static int dgap_tty_digisetcustombaud(struct tty_struct *tty,
- int __user *new_info);
-static int dgap_tty_digigetcustombaud(struct tty_struct *tty,
- int __user *retinfo);
+static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, int __user *new_info);
+static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un,
+ int __user *retinfo);
static int dgap_tty_tiocmget(struct tty_struct *tty);
static int dgap_tty_tiocmset(struct tty_struct *tty, unsigned int set,
unsigned int clear);
@@ -123,8 +123,10 @@ static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c);
static void dgap_tty_send_xchar(struct tty_struct *tty, char ch);
static int dgap_tty_register(struct board_t *brd);
+static void dgap_tty_unregister(struct board_t *brd);
static int dgap_tty_init(struct board_t *);
-static void dgap_tty_uninit(struct board_t *);
+static void dgap_tty_free(struct board_t *);
+static void dgap_cleanup_tty(struct board_t *);
static void dgap_carrier(struct channel_t *ch);
static void dgap_input(struct channel_t *ch);
@@ -139,7 +141,7 @@ static void dgap_cmdb(struct channel_t *ch, u8 cmd, u8 byte1,
u8 byte2, uint ncmds);
static void dgap_cmdw(struct channel_t *ch, u8 cmd, u16 word, uint ncmds);
static void dgap_wmove(struct channel_t *ch, char *buf, uint cnt);
-static int dgap_param(struct tty_struct *tty);
+static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type);
static void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf,
unsigned char *fbuf, int *len);
static uint dgap_get_custom_baud(struct channel_t *ch);
@@ -148,9 +150,8 @@ static void dgap_firmware_reset_port(struct channel_t *ch);
/*
* Function prototypes from dgap_parse.c.
*/
-static int dgap_gettok(char **in, struct cnode *p);
+static int dgap_gettok(char **in);
static char *dgap_getword(char **in);
-static struct cnode *dgap_newnode(int t);
static int dgap_checknode(struct cnode *p);
static void dgap_err(char *s);
@@ -175,7 +176,7 @@ static void dgap_remove_tty_sysfs(struct device *c);
/*
* Function prototypes from dgap_parse.h
*/
-static int dgap_parsefile(char **in, int remove);
+static int dgap_parsefile(char **in);
static struct cnode *dgap_find_config(int type, int bus, int slot);
static uint dgap_config_get_num_prts(struct board_t *bd);
static char *dgap_create_config_string(struct board_t *bd, char *string);
@@ -188,15 +189,18 @@ static void dgap_do_fep_load(struct board_t *brd, const u8 *ufep, int len);
#ifdef DIGI_CONCENTRATORS_SUPPORTED
static void dgap_do_conc_load(struct board_t *brd, u8 *uaddr, int len);
#endif
-static int dgap_after_config_loaded(int board);
-static int dgap_finalize_board_init(struct board_t *brd);
+static int dgap_alloc_flipbuf(struct board_t *brd);
+static void dgap_free_flipbuf(struct board_t *brd);
+static int dgap_request_irq(struct board_t *brd);
+static void dgap_free_irq(struct board_t *brd);
static void dgap_get_vpd(struct board_t *brd);
static void dgap_do_reset_board(struct board_t *brd);
static int dgap_test_bios(struct board_t *brd);
static int dgap_test_fep(struct board_t *brd);
static int dgap_tty_register_ports(struct board_t *brd);
-static int dgap_firmware_load(struct pci_dev *pdev, int card_type);
+static int dgap_firmware_load(struct pci_dev *pdev, int card_type,
+ struct board_t *brd);
static void dgap_cleanup_module(void);
@@ -212,9 +216,7 @@ static const struct file_operations dgap_board_fops = {
static uint dgap_numboards;
static struct board_t *dgap_board[MAXBOARDS];
static ulong dgap_poll_counter;
-static char *dgap_config_buf;
static int dgap_driver_state = DRIVER_INITIALIZED;
-static wait_queue_head_t dgap_dl_wait;
static int dgap_poll_tick = 20; /* Poll interval - 20 ms */
static struct class *dgap_class;
@@ -474,7 +476,7 @@ static int dgap_init_module(void)
if (rc)
return rc;
- rc = dgap_init_pci();
+ rc = pci_register_driver(&dgap_driver);
if (rc)
goto err_cleanup;
@@ -558,17 +560,10 @@ failed_class:
return rc;
}
-/*
- * Register pci driver, and return how many boards we have.
- */
-static int dgap_init_pci(void)
-{
- return pci_register_driver(&dgap_driver);
-}
-
static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
+ struct board_t *brd;
if (dgap_numboards >= MAXBOARDS)
return -EPERM;
@@ -577,17 +572,57 @@ static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return -EIO;
- rc = dgap_probe1(pdev, ent->driver_data);
+ brd = dgap_found_board(pdev, ent->driver_data, dgap_numboards);
+ if (IS_ERR(brd))
+ return PTR_ERR(brd);
+
+ rc = dgap_firmware_load(pdev, ent->driver_data, brd);
if (rc)
- return rc;
+ goto cleanup_brd;
- dgap_numboards++;
- return dgap_firmware_load(pdev, ent->driver_data);
-}
+ rc = dgap_alloc_flipbuf(brd);
+ if (rc)
+ goto cleanup_brd;
-static int dgap_probe1(struct pci_dev *pdev, int card_type)
-{
- return dgap_found_board(pdev, card_type);
+ rc = dgap_tty_register(brd);
+ if (rc)
+ goto free_flipbuf;
+
+ rc = dgap_request_irq(brd);
+ if (rc)
+ goto unregister_tty;
+
+ /*
+ * Do tty device initialization.
+ */
+ rc = dgap_tty_init(brd);
+ if (rc < 0)
+ goto free_irq;
+
+ rc = dgap_tty_register_ports(brd);
+ if (rc)
+ goto tty_free;
+
+ brd->state = BOARD_READY;
+ brd->dpastatus = BD_RUNNING;
+
+ dgap_board[dgap_numboards++] = brd;
+
+ return 0;
+
+tty_free:
+ dgap_tty_free(brd);
+free_irq:
+ dgap_free_irq(brd);
+unregister_tty:
+ dgap_tty_unregister(brd);
+free_flipbuf:
+ dgap_free_flipbuf(brd);
+cleanup_brd:
+ dgap_release_remap(brd);
+ kfree(brd);
+
+ return rc;
}
static void dgap_remove_one(struct pci_dev *dev)
@@ -620,7 +655,7 @@ static void dgap_cleanup_module(void)
for (i = 0; i < dgap_numboards; ++i) {
dgap_remove_ports_sysfiles(dgap_board[i]);
- dgap_tty_uninit(dgap_board[i]);
+ dgap_cleanup_tty(dgap_board[i]);
dgap_cleanup_board(dgap_board[i]);
}
@@ -640,8 +675,7 @@ static void dgap_cleanup_board(struct board_t *brd)
if (!brd || brd->magic != DGAP_BOARD_MAGIC)
return;
- if (brd->intr_used && brd->irq)
- free_irq(brd->irq, brd);
+ dgap_free_irq(brd);
tasklet_kill(&brd->helper_tasklet);
@@ -674,23 +708,22 @@ static void dgap_cleanup_board(struct board_t *brd)
*
* A board has been found, init it.
*/
-static int dgap_found_board(struct pci_dev *pdev, int id)
+static struct board_t *dgap_found_board(struct pci_dev *pdev, int id,
+ int boardnum)
{
struct board_t *brd;
unsigned int pci_irq;
int i;
+ int ret;
/* get the board structure and prep it */
brd = kzalloc(sizeof(struct board_t), GFP_KERNEL);
if (!brd)
- return -ENOMEM;
-
- dgap_board[dgap_numboards] = brd;
+ return ERR_PTR(-ENOMEM);
/* store the info for the board we've found */
brd->magic = DGAP_BOARD_MAGIC;
- brd->boardnum = dgap_numboards;
- brd->firstminor = 0;
+ brd->boardnum = boardnum;
brd->vendor = dgap_pci_tbl[id].vendor;
brd->device = dgap_pci_tbl[id].device;
brd->pdev = pdev;
@@ -734,8 +767,10 @@ static int dgap_found_board(struct pci_dev *pdev, int id)
brd->membase_end = pci_resource_end(pdev, 0);
}
- if (!brd->membase)
- return -ENODEV;
+ if (!brd->membase) {
+ ret = -ENODEV;
+ goto free_brd;
+ }
if (brd->membase & 1)
brd->membase &= ~3;
@@ -776,18 +811,23 @@ static int dgap_found_board(struct pci_dev *pdev, int id)
tasklet_init(&brd->helper_tasklet, dgap_poll_tasklet,
(unsigned long) brd);
- i = dgap_do_remap(brd);
- if (i)
- brd->state = BOARD_FAILED;
+ ret = dgap_do_remap(brd);
+ if (ret)
+ goto free_brd;
pr_info("dgap: board %d: %s (rev %d), irq %ld\n",
- dgap_numboards, brd->name, brd->rev, brd->irq);
+ boardnum, brd->name, brd->rev, brd->irq);
- return 0;
+ return brd;
+
+free_brd:
+ kfree(brd);
+
+ return ERR_PTR(ret);
}
-static int dgap_finalize_board_init(struct board_t *brd)
+static int dgap_request_irq(struct board_t *brd)
{
int rc;
@@ -814,17 +854,24 @@ static int dgap_finalize_board_init(struct board_t *brd)
return 0;
}
-static int dgap_firmware_load(struct pci_dev *pdev, int card_type)
+static void dgap_free_irq(struct board_t *brd)
+{
+ if (brd->intr_used && brd->irq)
+ free_irq(brd->irq, brd);
+}
+
+static int dgap_firmware_load(struct pci_dev *pdev, int card_type,
+ struct board_t *brd)
{
- struct board_t *brd = dgap_board[dgap_numboards - 1];
const struct firmware *fw;
char *tmp_ptr;
int ret;
+ char *dgap_config_buf;
dgap_get_vpd(brd);
dgap_do_reset_board(brd);
- if ((fw_info[card_type].conf_name) && !dgap_config_buf) {
+ if (fw_info[card_type].conf_name) {
ret = request_firmware(&fw, fw_info[card_type].conf_name,
&pdev->dev);
if (ret) {
@@ -849,16 +896,13 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type)
*/
tmp_ptr = dgap_config_buf;
- if (dgap_parsefile(&tmp_ptr, TRUE) != 0) {
+ if (dgap_parsefile(&tmp_ptr) != 0) {
kfree(dgap_config_buf);
return -EINVAL;
}
kfree(dgap_config_buf);
}
- ret = dgap_after_config_loaded(brd->boardnum);
- if (ret)
- return ret;
/*
* Match this board to a config the user created for us.
*/
@@ -880,14 +924,6 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type)
return -EINVAL;
}
- ret = dgap_tty_register(brd);
- if (ret)
- return ret;
-
- ret = dgap_finalize_board_init(brd);
- if (ret)
- return ret;
-
if (fw_info[card_type].bios_name) {
ret = request_firmware(&fw, fw_info[card_type].bios_name,
&pdev->dev);
@@ -950,21 +986,6 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type)
release_firmware(fw);
}
#endif
- /*
- * Do tty device initialization.
- */
- ret = dgap_tty_init(brd);
- if (ret < 0) {
- dgap_tty_uninit(brd);
- return ret;
- }
-
- ret = dgap_tty_register_ports(brd);
- if (ret)
- return ret;
-
- brd->state = BOARD_READY;
- brd->dpastatus = BD_RUNNING;
return 0;
}
@@ -1004,6 +1025,12 @@ static int dgap_do_remap(struct board_t *brd)
return 0;
}
+static void dgap_release_remap(struct board_t *brd)
+{
+ release_mem_region(brd->membase, 0x200000);
+ release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
+ iounmap(brd->re_map_membase);
+}
/*****************************************************************************
*
* Function:
@@ -1171,8 +1198,6 @@ static void dgap_init_globals(void)
dgap_board[i] = NULL;
init_timer(&dgap_poll_timer);
-
- init_waitqueue_head(&dgap_dl_wait);
}
/************************************************************************
@@ -1311,6 +1336,14 @@ free_serial_drv:
return rc;
}
+static void dgap_tty_unregister(struct board_t *brd)
+{
+ tty_unregister_driver(brd->print_driver);
+ tty_unregister_driver(brd->serial_driver);
+ put_tty_driver(brd->print_driver);
+ put_tty_driver(brd->serial_driver);
+}
+
/*
* dgap_tty_init()
*
@@ -1327,9 +1360,7 @@ static int dgap_tty_init(struct board_t *brd)
struct channel_t *ch;
struct bs_t __iomem *bs;
struct cm_t __iomem *cm;
-
- if (!brd)
- return -EIO;
+ int ret;
/*
* Initialize board structure elements.
@@ -1376,11 +1407,11 @@ static int dgap_tty_init(struct board_t *brd)
* when the driver was first loaded.
*/
for (i = 0; i < brd->nasync; i++) {
+ brd->channels[i] =
+ kzalloc(sizeof(struct channel_t), GFP_KERNEL);
if (!brd->channels[i]) {
- brd->channels[i] =
- kzalloc(sizeof(struct channel_t), GFP_KERNEL);
- if (!brd->channels[i])
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_chan;
}
}
@@ -1395,9 +1426,6 @@ static int dgap_tty_init(struct board_t *brd)
/* Set up channel variables */
for (i = 0; i < brd->nasync; i++, ch = brd->channels[i], bs++) {
- if (!brd->channels[i])
- continue;
-
spin_lock_init(&ch->ch_lock);
/* Store all our magic numbers */
@@ -1480,15 +1508,34 @@ static int dgap_tty_init(struct board_t *brd)
}
return 0;
+
+free_chan:
+ while (--i >= 0) {
+ kfree(brd->channels[i]);
+ brd->channels[i] = NULL;
+ }
+ return ret;
}
/*
- * dgap_tty_uninit()
+ * dgap_tty_free()
+ *
+ * Free the channles which are allocated in dgap_tty_init().
+ */
+static void dgap_tty_free(struct board_t *brd)
+{
+ int i;
+
+ for (i = 0; i < brd->nasync; i++)
+ kfree(brd->channels[i]);
+}
+/*
+ * dgap_cleanup_tty()
*
* Uninitialize the TTY portion of this driver. Free all memory and
* resources.
*/
-static void dgap_tty_uninit(struct board_t *brd)
+static void dgap_cleanup_tty(struct board_t *brd)
{
struct device *dev;
int i;
@@ -1981,7 +2028,7 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
/*
* Run param in case we changed anything
*/
- dgap_param(tty);
+ dgap_param(ch, brd, un->un_type);
/*
* follow protocol for opening port
@@ -2133,10 +2180,7 @@ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file,
spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
- if (retval)
- return retval;
-
- return 0;
+ return retval;
}
/*
@@ -2459,22 +2503,9 @@ static int dgap_wait_for_drain(struct tty_struct *tty)
* returns the new bytes_available. This only affects printer
* output.
*/
-static int dgap_maxcps_room(struct tty_struct *tty, int bytes_available)
+static int dgap_maxcps_room(struct channel_t *ch, struct un_t *un,
+ int bytes_available)
{
- struct channel_t *ch;
- struct un_t *un;
-
- if (!tty)
- return bytes_available;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return bytes_available;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return bytes_available;
-
/*
* If its not the Transparent print device, return
* the full data amount.
@@ -2576,7 +2607,7 @@ static int dgap_tty_write_room(struct tty_struct *tty)
ret += ch->ch_tsize;
/* Limit printer to maxcps */
- ret = dgap_maxcps_room(tty, ret);
+ ret = dgap_maxcps_room(ch, un, ret);
/*
* If we are printer device, leave space for
@@ -2681,7 +2712,7 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf,
* Limit printer output to maxcps overall, with bursts allowed
* up to bufsize characters.
*/
- bufcount = dgap_maxcps_room(tty, bufcount);
+ bufcount = dgap_maxcps_room(ch, un, bufcount);
/*
* Take minimum of what the user wants to send, and the
@@ -2892,7 +2923,7 @@ static int dgap_tty_tiocmset(struct tty_struct *tty,
ch->ch_mval &= ~(D_DTR(ch));
}
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3014,8 +3045,6 @@ static void dgap_tty_send_xchar(struct tty_struct *tty, char c)
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
-
- return;
}
/*
@@ -3028,9 +3057,6 @@ static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value)
ulong lock_flags;
int rc;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EIO;
-
spin_lock_irqsave(&ch->ch_lock, lock_flags);
mstat = readb(&(ch->ch_bs->m_stat));
@@ -3064,32 +3090,14 @@ static int dgap_get_modem_info(struct channel_t *ch, unsigned int __user *value)
*
* Set modem signals, called by ld.
*/
-static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command,
- unsigned int __user *value)
+static int dgap_set_modem_info(struct channel_t *ch, struct board_t *bd, struct un_t *un,
+ unsigned int command, unsigned int __user *value)
{
- struct board_t *bd;
- struct channel_t *ch;
- struct un_t *un;
int ret;
unsigned int arg;
ulong lock_flags;
ulong lock_flags2;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EIO;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EIO;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EIO;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGAP_BOARD_MAGIC)
- return -EIO;
-
ret = get_user(arg, value);
if (ret)
return ret;
@@ -3143,7 +3151,7 @@ static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command,
spin_lock_irqsave(&bd->bd_lock, lock_flags);
spin_lock_irqsave(&ch->ch_lock, lock_flags2);
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3159,28 +3167,14 @@ static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command,
*
*
*/
-static int dgap_tty_digigeta(struct tty_struct *tty,
- struct digi_t __user *retinfo)
+static int dgap_tty_digigeta(struct channel_t *ch, struct digi_t __user *retinfo)
{
- struct channel_t *ch;
- struct un_t *un;
struct digi_t tmp;
ulong lock_flags;
if (!retinfo)
return -EFAULT;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EFAULT;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EFAULT;
-
memset(&tmp, 0, sizeof(tmp));
spin_lock_irqsave(&ch->ch_lock, lock_flags);
@@ -3201,31 +3195,13 @@ static int dgap_tty_digigeta(struct tty_struct *tty,
*
*
*/
-static int dgap_tty_digiseta(struct tty_struct *tty,
- struct digi_t __user *new_info)
+static int dgap_tty_digiseta(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, struct digi_t __user *new_info)
{
- struct board_t *bd;
- struct channel_t *ch;
- struct un_t *un;
struct digi_t new_digi;
ulong lock_flags = 0;
unsigned long lock_flags2;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EFAULT;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EFAULT;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGAP_BOARD_MAGIC)
- return -EFAULT;
-
if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t)))
return -EFAULT;
@@ -3255,7 +3231,7 @@ static int dgap_tty_digiseta(struct tty_struct *tty,
if (ch->ch_digi.digi_offlen > DIGI_PLEN)
ch->ch_digi.digi_offlen = DIGI_PLEN;
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3310,30 +3286,13 @@ static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo)
* Ioctl to set the EDELAY setting
*
*/
-static int dgap_tty_digisetedelay(struct tty_struct *tty, int __user *new_info)
+static int dgap_tty_digisetedelay(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, int __user *new_info)
{
- struct board_t *bd;
- struct channel_t *ch;
- struct un_t *un;
int new_digi;
ulong lock_flags;
ulong lock_flags2;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EFAULT;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EFAULT;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGAP_BOARD_MAGIC)
- return -EFAULT;
-
if (copy_from_user(&new_digi, new_info, sizeof(int)))
return -EFAULT;
@@ -3342,7 +3301,7 @@ static int dgap_tty_digisetedelay(struct tty_struct *tty, int __user *new_info)
writew((u16) new_digi, &(ch->ch_bs->edelay));
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3355,28 +3314,15 @@ static int dgap_tty_digisetedelay(struct tty_struct *tty, int __user *new_info)
*
* Ioctl to get the current custom baud rate setting.
*/
-static int dgap_tty_digigetcustombaud(struct tty_struct *tty,
- int __user *retinfo)
+static int dgap_tty_digigetcustombaud(struct channel_t *ch, struct un_t *un,
+ int __user *retinfo)
{
- struct channel_t *ch;
- struct un_t *un;
int tmp;
ulong lock_flags;
if (!retinfo)
return -EFAULT;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EFAULT;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EFAULT;
-
memset(&tmp, 0, sizeof(tmp));
spin_lock_irqsave(&ch->ch_lock, lock_flags);
@@ -3394,32 +3340,13 @@ static int dgap_tty_digigetcustombaud(struct tty_struct *tty,
*
* Ioctl to set the custom baud rate setting
*/
-static int dgap_tty_digisetcustombaud(struct tty_struct *tty,
- int __user *new_info)
+static int dgap_tty_digisetcustombaud(struct channel_t *ch, struct board_t *bd,
+ struct un_t *un, int __user *new_info)
{
- struct board_t *bd;
- struct channel_t *ch;
- struct un_t *un;
uint new_rate;
ulong lock_flags;
ulong lock_flags2;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EFAULT;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EFAULT;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGAP_BOARD_MAGIC)
- return -EFAULT;
-
-
if (copy_from_user(&new_rate, new_info, sizeof(unsigned int)))
return -EFAULT;
@@ -3430,7 +3357,7 @@ static int dgap_tty_digisetcustombaud(struct tty_struct *tty,
ch->ch_custom_speed = new_rate;
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3477,7 +3404,7 @@ static void dgap_tty_set_termios(struct tty_struct *tty,
ch->ch_stopc = tty->termios.c_cc[VSTOP];
dgap_carrier(ch);
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3884,7 +3811,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
spin_lock_irqsave(&ch->ch_lock, lock_flags2);
tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) |
(arg ? CLOCAL : 0));
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
@@ -3900,7 +3827,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case TIOCMSET:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_set_modem_info(tty, cmd, uarg);
+ return dgap_set_modem_info(ch, bd, un, cmd, uarg);
/*
* Here are any additional ioctl's that we want to implement
@@ -4048,7 +3975,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
/* get information for ditty */
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_tty_digigeta(tty, uarg);
+ return dgap_tty_digigeta(ch, uarg);
case DIGI_SETAW:
case DIGI_SETAF:
@@ -4070,7 +3997,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case DIGI_SETA:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_tty_digiseta(tty, uarg);
+ return dgap_tty_digiseta(ch, bd, un, uarg);
case DIGI_GEDELAY:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
@@ -4080,21 +4007,21 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case DIGI_SEDELAY:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_tty_digisetedelay(tty, uarg);
+ return dgap_tty_digisetedelay(ch, bd, un, uarg);
case DIGI_GETCUSTOMBAUD:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_tty_digigetcustombaud(tty, uarg);
+ return dgap_tty_digigetcustombaud(ch, un, uarg);
case DIGI_SETCUSTOMBAUD:
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
- return dgap_tty_digisetcustombaud(tty, uarg);
+ return dgap_tty_digisetcustombaud(ch, bd, un, uarg);
case DIGI_RESET_PORT:
dgap_firmware_reset_port(ch);
- dgap_param(tty);
+ dgap_param(ch, bd, un->un_type);
spin_unlock_irqrestore(&ch->ch_lock, lock_flags2);
spin_unlock_irqrestore(&bd->bd_lock, lock_flags);
return 0;
@@ -4107,29 +4034,30 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
}
}
-static int dgap_after_config_loaded(int board)
+static int dgap_alloc_flipbuf(struct board_t *brd)
{
/*
- * Initialize KME waitqueues...
- */
- init_waitqueue_head(&(dgap_board[board]->kme_wait));
-
- /*
* allocate flip buffer for board.
*/
- dgap_board[board]->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
- if (!dgap_board[board]->flipbuf)
+ brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
+ if (!brd->flipbuf)
return -ENOMEM;
- dgap_board[board]->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
- if (!dgap_board[board]->flipflagbuf) {
- kfree(dgap_board[board]->flipbuf);
+ brd->flipflagbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
+ if (!brd->flipflagbuf) {
+ kfree(brd->flipbuf);
return -ENOMEM;
}
return 0;
}
+static void dgap_free_flipbuf(struct board_t *brd)
+{
+ kfree(brd->flipbuf);
+ kfree(brd->flipflagbuf);
+}
+
/*
* Create pr and tty device entries
*/
@@ -4137,6 +4065,7 @@ static int dgap_tty_register_ports(struct board_t *brd)
{
struct channel_t *ch;
int i;
+ int ret;
brd->serial_ports = kcalloc(brd->nasync, sizeof(*brd->serial_ports),
GFP_KERNEL);
@@ -4146,8 +4075,8 @@ static int dgap_tty_register_ports(struct board_t *brd)
brd->printer_ports = kcalloc(brd->nasync, sizeof(*brd->printer_ports),
GFP_KERNEL);
if (!brd->printer_ports) {
- kfree(brd->serial_ports);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_serial_ports;
}
for (i = 0; i < brd->nasync; i++) {
@@ -4161,15 +4090,25 @@ static int dgap_tty_register_ports(struct board_t *brd)
struct device *classp;
classp = tty_port_register_device(&brd->serial_ports[i],
- brd->serial_driver,
- brd->firstminor + i, NULL);
+ brd->serial_driver,
+ i, NULL);
+
+ if (IS_ERR(classp)) {
+ ret = PTR_ERR(classp);
+ goto unregister_ttys;
+ }
dgap_create_tty_sysfs(&ch->ch_tun, classp);
ch->ch_tun.un_sysfs = classp;
classp = tty_port_register_device(&brd->printer_ports[i],
- brd->print_driver,
- brd->firstminor + i, NULL);
+ brd->print_driver,
+ i, NULL);
+
+ if (IS_ERR(classp)) {
+ ret = PTR_ERR(classp);
+ goto unregister_ttys;
+ }
dgap_create_tty_sysfs(&ch->ch_pun, classp);
ch->ch_pun.un_sysfs = classp;
@@ -4177,6 +4116,35 @@ static int dgap_tty_register_ports(struct board_t *brd)
dgap_create_ports_sysfiles(brd);
return 0;
+
+unregister_ttys:
+ while (i >= 0) {
+ ch = brd->channels[i];
+ if (ch->ch_tun.un_sysfs) {
+ dgap_remove_tty_sysfs(ch->ch_tun.un_sysfs);
+ tty_unregister_device(brd->serial_driver, i);
+ }
+
+ if (ch->ch_pun.un_sysfs) {
+ dgap_remove_tty_sysfs(ch->ch_pun.un_sysfs);
+ tty_unregister_device(brd->print_driver, i);
+ }
+ i--;
+ }
+
+ for (i = 0; i < brd->nasync; i++) {
+ tty_port_destroy(&brd->serial_ports[i]);
+ tty_port_destroy(&brd->printer_ports[i]);
+ }
+
+ kfree(brd->printer_ports);
+ brd->printer_ports = NULL;
+
+free_serial_ports:
+ kfree(brd->serial_ports);
+ brd->serial_ports = NULL;
+
+ return ret;
}
/*
@@ -4995,40 +4963,14 @@ static void dgap_firmware_reset_port(struct channel_t *ch)
* struct tty_struct * - TTY for port.
*
*=======================================================================*/
-static int dgap_param(struct tty_struct *tty)
+static int dgap_param(struct channel_t *ch, struct board_t *bd, u32 un_type)
{
- struct ktermios *ts;
- struct board_t *bd;
- struct channel_t *ch;
- struct bs_t __iomem *bs;
- struct un_t *un;
u16 head;
u16 cflag;
u16 iflag;
u8 mval;
u8 hflow;
- if (!tty || tty->magic != TTY_MAGIC)
- return -EIO;
-
- un = (struct un_t *) tty->driver_data;
- if (!un || un->magic != DGAP_UNIT_MAGIC)
- return -EIO;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
- return -EIO;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGAP_BOARD_MAGIC)
- return -EIO;
-
- bs = ch->ch_bs;
- if (!bs)
- return -EIO;
-
- ts = &tty->termios;
-
/*
* If baud rate is zero, flush queues, and set mval to drop DTR.
*/
@@ -5108,7 +5050,7 @@ static int dgap_param(struct tty_struct *tty)
* terminal unit is NOT open
*/
if (!(ch->ch_tun.un_flags & UN_ISOPEN) &&
- (un->un_type == DGAP_PRINT))
+ un_type == DGAP_PRINT)
baud = C_BAUD(ch->ch_pun.un_tty) & 0xff;
else
baud = C_BAUD(ch->ch_tun.un_tty) & 0xff;
@@ -5281,6 +5223,7 @@ static int dgap_param(struct tty_struct *tty)
*/
if (bd->bd_flags & BD_FEP5PLUS) {
u16 hflow2 = 0;
+
if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
hflow2 |= (D_RTS(ch));
if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)
@@ -5305,7 +5248,7 @@ static int dgap_param(struct tty_struct *tty)
/*
* Read modem signals, and then call carrier function.
*/
- ch->ch_mistat = readb(&(bs->m_stat));
+ ch->ch_mistat = readb(&(ch->ch_bs->m_stat));
dgap_carrier(ch);
/*
@@ -5690,6 +5633,7 @@ static int dgap_create_driver_sysfiles(struct pci_driver *dgap_driver)
static void dgap_remove_driver_sysfiles(struct pci_driver *dgap_driver)
{
struct device_driver *driverfs = &dgap_driver->driver;
+
driver_remove_file(driverfs, &driver_attr_version);
driver_remove_file(driverfs, &driver_attr_boards);
driver_remove_file(driverfs, &driver_attr_maxboards);
@@ -6283,6 +6227,7 @@ static ssize_t dgap_tty_name_show(struct device *d,
if (cptr->type == TNODE && found == TRUE) {
char *ptr1;
+
if (strstr(cptr->u.ttyname, "tty")) {
ptr1 = cptr->u.ttyname;
ptr1 += 3;
@@ -6381,7 +6326,7 @@ static void dgap_remove_tty_sysfs(struct device *c)
/*
* Parse a configuration file read into memory as a string.
*/
-static int dgap_parsefile(char **in, int remove)
+static int dgap_parsefile(char **in)
{
struct cnode *p, *brd, *line, *conc;
int rc;
@@ -6396,7 +6341,7 @@ static int dgap_parsefile(char **in, int remove)
p = p->next;
/* file must start with a BEGIN */
- while ((rc = dgap_gettok(in, p)) != BEGIN) {
+ while ((rc = dgap_gettok(in)) != BEGIN) {
if (rc == 0) {
dgap_err("unexpected EOF");
return -1;
@@ -6404,17 +6349,13 @@ static int dgap_parsefile(char **in, int remove)
}
for (; ;) {
- rc = dgap_gettok(in, p);
+ rc = dgap_gettok(in);
if (rc == 0) {
dgap_err("unexpected EOF");
return -1;
}
switch (rc) {
- case 0:
- dgap_err("unexpected end of file");
- return -1;
-
case BEGIN: /* should only be 1 begin */
dgap_err("unexpected config_begin\n");
return -1;
@@ -6425,13 +6366,15 @@ static int dgap_parsefile(char **in, int remove)
case BOARD: /* board info */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(BNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
p = p->next;
+ p->type = BNODE;
p->u.board.status = kstrdup("No", GFP_KERNEL);
line = conc = NULL;
brd = p;
@@ -6716,12 +6659,16 @@ static int dgap_parsefile(char **in, int remove)
case TTYN: /* tty name prefix */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(TNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = TNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpeced end of file");
@@ -6737,12 +6684,16 @@ static int dgap_parsefile(char **in, int remove)
case CU: /* cu name prefix */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(CUNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = CUNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpeced end of file");
@@ -6767,12 +6718,15 @@ static int dgap_parsefile(char **in, int remove)
dgap_err("line not vaild for PC/em");
return -1;
}
- p->next = dgap_newnode(LNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = LNODE;
conc = NULL;
line = p;
linecnt++;
@@ -6785,13 +6739,17 @@ static int dgap_parsefile(char **in, int remove)
dgap_err("must specify line info before concentrator");
return -1;
}
- p->next = dgap_newnode(CNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = CNODE;
conc = p;
+
if (linecnt)
brd->u.board.conc2++;
else
@@ -6834,12 +6792,15 @@ static int dgap_parsefile(char **in, int remove)
return -1;
}
}
- p->next = dgap_newnode(MNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
p = p->next;
+ p->type = MNODE;
+
if (linecnt)
brd->u.board.module2++;
else
@@ -6920,12 +6881,16 @@ static int dgap_parsefile(char **in, int remove)
case PRINT: /* transparent print name prefix */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(PNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = PNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpeced end of file");
@@ -6941,12 +6906,16 @@ static int dgap_parsefile(char **in, int remove)
case CMAJOR: /* major number */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(JNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = JNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -6961,12 +6930,16 @@ static int dgap_parsefile(char **in, int remove)
case ALTPIN: /* altpin setting */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(ANODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = ANODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -6981,12 +6954,14 @@ static int dgap_parsefile(char **in, int remove)
case USEINTR: /* enable interrupt setting */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(INTRNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
p = p->next;
+ p->type = INTRNODE;
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7001,12 +6976,16 @@ static int dgap_parsefile(char **in, int remove)
case TTSIZ: /* size of tty structure */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(TSNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = TSNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7021,12 +7000,16 @@ static int dgap_parsefile(char **in, int remove)
case CHSIZ: /* channel structure size */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(CSNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = CSNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7041,12 +7024,16 @@ static int dgap_parsefile(char **in, int remove)
case BSSIZ: /* board structure size */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(BSNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = BSNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7061,12 +7048,16 @@ static int dgap_parsefile(char **in, int remove)
case UNTSIZ: /* sched structure size */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(USNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = USNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7081,12 +7072,16 @@ static int dgap_parsefile(char **in, int remove)
case F2SIZ: /* f2200 structure size */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(FSNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = FSNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7101,12 +7096,16 @@ static int dgap_parsefile(char **in, int remove)
case VPSIZ: /* vpix structure size */
if (dgap_checknode(p))
return -1;
- p->next = dgap_newnode(VSNODE);
+
+ p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next) {
dgap_err("out of memory");
return -1;
}
+
p = p->next;
+ p->type = VSNODE;
+
s = dgap_getword(in);
if (!s) {
dgap_err("unexpected end of file");
@@ -7158,12 +7157,12 @@ static char *dgap_sindex(char *string, char *group)
/*
* Get a token from the input file; return 0 if end of file is reached
*/
-static int dgap_gettok(char **in, struct cnode *p)
+static int dgap_gettok(char **in)
{
char *w;
struct toklist *t;
- if (strstr(dgap_cword, "boar")) {
+ if (strstr(dgap_cword, "board")) {
w = dgap_getword(in);
snprintf(dgap_cword, MAXCWORD, "%s", w);
for (t = dgap_tlist; t->token != 0; t++) {
@@ -7223,21 +7222,6 @@ static void dgap_err(char *s)
}
/*
- * allocate a new configuration node of type t
- */
-static struct cnode *dgap_newnode(int t)
-{
- struct cnode *n;
-
- n = kmalloc(sizeof(struct cnode), GFP_KERNEL);
- if (n) {
- memset((char *)n, 0, sizeof(struct cnode));
- n->type = t;
- }
- return n;
-}
-
-/*
* dgap_checknode: see if all the necessary info has been supplied for a node
* before creating the next node.
*/
diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h
index 03c020e35f88..9728d59c94d1 100644
--- a/drivers/staging/dgap/dgap.h
+++ b/drivers/staging/dgap/dgap.h
@@ -529,7 +529,6 @@ struct macounter {
struct board_t {
int magic; /* Board Magic number. */
int boardnum; /* Board number: 0-3 */
- int firstminor; /* First minor, e.g. 0, 30, 60 */
int type; /* Type of board */
char *name; /* Product Name */
@@ -604,7 +603,6 @@ struct board_t {
/* by DPA */
u16 dpastatus; /* The board "status", as defined */
/* by DPA */
- wait_queue_head_t kme_wait; /* Needed for DPA support */
u32 conc_dl_status; /* Status of any pending conc */
/* download */
diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile
index 888c4334236b..733434f63700 100644
--- a/drivers/staging/dgnc/Makefile
+++ b/drivers/staging/dgnc/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_DGNC) += dgnc.o
dgnc-objs := dgnc_cls.o dgnc_driver.o\
dgnc_mgmt.o dgnc_neo.o\
- dgnc_trace.o dgnc_tty.o dgnc_sysfs.o
+ dgnc_tty.o dgnc_sysfs.o
diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c
index 8e265c20db59..cfa8384c0077 100644
--- a/drivers/staging/dgnc/dgnc_cls.c
+++ b/drivers/staging/dgnc/dgnc_cls.c
@@ -41,7 +41,6 @@
#include "dgnc_driver.h" /* Driver main header file */
#include "dgnc_cls.h"
#include "dgnc_tty.h"
-#include "dgnc_trace.h"
static inline void cls_parse_isr(struct dgnc_board *brd, uint port);
static inline void cls_clear_break(struct channel_t *ch, int force);
@@ -1040,16 +1039,13 @@ static void cls_flush_uart_read(struct channel_t *ch)
* For complete POSIX compatibility, we should be purging the
* read FIFO in the UART here.
*
- * However, doing the statement below also incorrectly flushes
- * write data as well as just basically trashing the FIFO.
+ * However, clearing the read FIFO (UART_FCR_CLEAR_RCVR) also
+ * incorrectly flushes write data as well as just basically trashing the
+ * FIFO.
*
- * I believe this is a BUG in this UART.
- * So for now, we will leave the code #ifdef'ed out...
+ * Presumably, this is a bug in this UART.
*/
-#if 0
- writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR),
- &ch->ch_cls_uart->isr_fcr);
-#endif
+
udelay(10);
}
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index 5af8300dfb0d..764613b2f4b4 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -40,7 +40,6 @@
#include "dpacompat.h"
#include "dgnc_mgmt.h"
#include "dgnc_tty.h"
-#include "dgnc_trace.h"
#include "dgnc_cls.h"
#include "dgnc_neo.h"
#include "dgnc_sysfs.h"
@@ -88,8 +87,7 @@ module_exit(dgnc_cleanup_module);
/*
* File operations permitted on Control/Management major.
*/
-static const struct file_operations dgnc_BoardFops =
-{
+static const struct file_operations dgnc_BoardFops = {
.owner = THIS_MODULE,
.unlocked_ioctl = dgnc_mgmt_ioctl,
.open = dgnc_mgmt_open,
@@ -389,10 +387,6 @@ void dgnc_cleanup_module(void)
dgnc_tty_post_uninit();
-#if defined(DGNC_TRACER)
- /* last thing, make sure we release the tracebuffer */
- dgnc_tracer_free();
-#endif
if (dgnc_NumBoards)
pci_unregister_driver(&dgnc_driver);
}
@@ -407,7 +401,7 @@ static void dgnc_cleanup_board(struct dgnc_board *brd)
{
int i = 0;
- if(!brd || brd->magic != DGNC_BOARD_MAGIC)
+ if (!brd || brd->magic != DGNC_BOARD_MAGIC)
return;
switch (brd->device) {
@@ -480,7 +474,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
/* get the board structure and prep it */
brd = dgnc_Board[dgnc_NumBoards] =
kzalloc(sizeof(*brd), GFP_KERNEL);
- if (!brd)
+ if (!brd)
return -ENOMEM;
/* make a temporary message buffer for the boot messages */
@@ -523,7 +517,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
brd->irq = pci_irq;
- switch(brd->device) {
+ switch (brd->device) {
case PCI_DEVICE_CLASSIC_4_DID:
case PCI_DEVICE_CLASSIC_8_DID:
@@ -710,7 +704,8 @@ failed:
}
-static int dgnc_finalize_board_init(struct dgnc_board *brd) {
+static int dgnc_finalize_board_init(struct dgnc_board *brd)
+{
int rc = 0;
DPR_INIT(("dgnc_finalize_board_init() - start\n"));
@@ -886,7 +881,7 @@ int dgnc_ms_sleep(ulong ms)
*/
char *dgnc_ioctl_name(int cmd)
{
- switch(cmd) {
+ switch (cmd) {
case TCGETA: return "TCGETA";
case TCGETS: return "TCGETS";
diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h
index 3519b803e753..58b5aa7b68ed 100644
--- a/drivers/staging/dgnc/dgnc_driver.h
+++ b/drivers/staging/dgnc/dgnc_driver.h
@@ -91,57 +91,6 @@
#define DBG_CARR (dgnc_debug & 0x10000)
-
-#if defined(DGNC_TRACER)
-
-# if defined(TRC_TO_KMEM)
-/* Choose one: */
-# define TRC_ON_OVERFLOW_WRAP_AROUND
-# undef TRC_ON_OVERFLOW_SHIFT_BUFFER
-# endif //TRC_TO_KMEM
-
-# define TRC_MAXMSG 1024
-# define TRC_OVERFLOW "(OVERFLOW)"
-# define TRC_DTRC "/usr/bin/dtrc"
-
-#if defined TRC_TO_CONSOLE
-#define PRINTF_TO_CONSOLE(args) { printk(DRVSTR": "); printk args; }
-#else //!defined TRACE_TO_CONSOLE
-#define PRINTF_TO_CONSOLE(args)
-#endif
-
-#if defined TRC_TO_KMEM
-#define PRINTF_TO_KMEM(args) dgnc_tracef args
-#else //!defined TRC_TO_KMEM
-#define PRINTF_TO_KMEM(args)
-#endif
-
-#define TRC(args) { PRINTF_TO_KMEM(args); PRINTF_TO_CONSOLE(args) }
-
-# define DPR_INIT(ARGS) if (DBG_INIT) TRC(ARGS)
-# define DPR_BASIC(ARGS) if (DBG_BASIC) TRC(ARGS)
-# define DPR_CORE(ARGS) if (DBG_CORE) TRC(ARGS)
-# define DPR_OPEN(ARGS) if (DBG_OPEN) TRC(ARGS)
-# define DPR_CLOSE(ARGS) if (DBG_CLOSE) TRC(ARGS)
-# define DPR_READ(ARGS) if (DBG_READ) TRC(ARGS)
-# define DPR_WRITE(ARGS) if (DBG_WRITE) TRC(ARGS)
-# define DPR_IOCTL(ARGS) if (DBG_IOCTL) TRC(ARGS)
-# define DPR_PROC(ARGS) if (DBG_PROC) TRC(ARGS)
-# define DPR_PARAM(ARGS) if (DBG_PARAM) TRC(ARGS)
-# define DPR_PSCAN(ARGS) if (DBG_PSCAN) TRC(ARGS)
-# define DPR_EVENT(ARGS) if (DBG_EVENT) TRC(ARGS)
-# define DPR_DRAIN(ARGS) if (DBG_DRAIN) TRC(ARGS)
-# define DPR_CARR(ARGS) if (DBG_CARR) TRC(ARGS)
-# define DPR_MGMT(ARGS) if (DBG_MGMT) TRC(ARGS)
-# define DPR_INTR(ARGS) if (DBG_INTR) TRC(ARGS)
-# define DPR_MSIGS(ARGS) if (DBG_MSIGS) TRC(ARGS)
-
-# define DPR(ARGS) if (dgnc_debug) TRC(ARGS)
-# define P(X) dgnc_tracef(#X "=%p\n", X)
-# define X(X) dgnc_tracef(#X "=%x\n", X)
-
-#else//!defined DGNC_TRACER
-
#define PRINTF_TO_KMEM(args)
# define TRC(ARGS)
# define DPR_INIT(ARGS)
@@ -164,8 +113,6 @@
# define DPR(args)
-#endif//DGNC_TRACER
-
/* Number of boards we support at once. */
#define MAXBOARDS 20
#define MAXPORTS 8
@@ -219,8 +166,8 @@
* Makes spotting lock/unlock locations easier.
*/
# define DGNC_SPINLOCK_INIT(x) spin_lock_init(&(x))
-# define DGNC_LOCK(x,y) spin_lock_irqsave(&(x), y)
-# define DGNC_UNLOCK(x,y) spin_unlock_irqrestore(&(x), y)
+# define DGNC_LOCK(x, y) spin_lock_irqsave(&(x), y)
+# define DGNC_UNLOCK(x, y) spin_unlock_irqrestore(&(x), y)
/*
* All the possible states the driver can be while being loaded.
diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c
index 9de988cc892b..68ff1161e677 100644
--- a/drivers/staging/dgnc/dgnc_neo.c
+++ b/drivers/staging/dgnc/dgnc_neo.c
@@ -41,7 +41,6 @@
#include "dgnc_driver.h" /* Driver main header file */
#include "dgnc_neo.h" /* Our header file */
#include "dgnc_tty.h"
-#include "dgnc_trace.h"
static inline void neo_parse_lsr(struct dgnc_board *brd, uint port);
static inline void neo_parse_isr(struct dgnc_board *brd, uint port);
diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c
index 0f0e8fcb663f..3f321bb2b79d 100644
--- a/drivers/staging/dgnc/dgnc_sysfs.c
+++ b/drivers/staging/dgnc/dgnc_sysfs.c
@@ -150,15 +150,17 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
}
-#define DGNC_VERIFY_BOARD(p, bd) \
- if (!p) \
- return 0; \
- \
- bd = dev_get_drvdata(p); \
- if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
- return 0; \
- if (bd->state != BOARD_READY) \
- return 0; \
+#define DGNC_VERIFY_BOARD(p, bd) \
+ do { \
+ if (!p) \
+ return 0; \
+ \
+ bd = dev_get_drvdata(p); \
+ if (!bd || bd->magic != DGNC_BOARD_MAGIC) \
+ return 0; \
+ if (bd->state != BOARD_READY) \
+ return 0; \
+ } while (0)
diff --git a/drivers/staging/dgnc/dgnc_trace.c b/drivers/staging/dgnc/dgnc_trace.c
deleted file mode 100644
index 2f62f2a43542..000000000000
--- a/drivers/staging/dgnc/dgnc_trace.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2003 Digi International (www.digi.com)
- * Scott H Kilau <Scott_Kilau at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
- *
- * This is shared code between Digi's CVS archive and the
- * Linux Kernel sources.
- * Changing the source just for reformatting needlessly breaks
- * our CVS diff history.
- *
- * Send any bug fixes/changes to: Eng.Linux at digi dot com.
- * Thank you.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h> /* For jiffies, task states */
-#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
-#include <linux/vmalloc.h>
-
-#include "dgnc_driver.h"
-#include "dgnc_trace.h"
-
-#define TRC_TO_CONSOLE 1
-
-/* file level globals */
-static char *dgnc_trcbuf; /* the ringbuffer */
-
-#if defined(TRC_TO_KMEM)
-static int dgnc_trcbufi = 0; /* index of the tilde at the end of */
-#endif
-
-#if defined(TRC_TO_KMEM)
-static DEFINE_SPINLOCK(dgnc_tracef_lock);
-#endif
-
-
-#if 0
-
-#if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
-
-void dgnc_tracef(const char *fmt, ...)
-{
- return;
-}
-
-#else /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
-
-void dgnc_tracef(const char *fmt, ...)
-{
- va_list ap;
- char buf[TRC_MAXMSG+1];
- size_t lenbuf;
- int i;
- static int failed = FALSE;
-# if defined(TRC_TO_KMEM)
- unsigned long flags;
-#endif
-
- if (failed)
- return;
-# if defined(TRC_TO_KMEM)
- DGNC_LOCK(dgnc_tracef_lock, flags);
-#endif
-
- /* Format buf using fmt and arguments contained in ap. */
- va_start(ap, fmt);
- i = vsprintf(buf, fmt, ap);
- va_end(ap);
- lenbuf = strlen(buf);
-
-# if defined(TRC_TO_KMEM)
- {
- static int initd = 0;
-
- /*
- * Now, in addition to (or instead of) printing this stuff out
- * (which is a buffered operation), also tuck it away into a
- * corner of memory which can be examined post-crash in kdb.
- */
- if (!initd) {
- dgnc_trcbuf = (char *) vmalloc(dgnc_trcbuf_size);
- if (!dgnc_trcbuf) {
- failed = TRUE;
- printk("dgnc: tracing init failed!\n");
- return;
- }
-
- memset(dgnc_trcbuf, '\0', dgnc_trcbuf_size);
- dgnc_trcbufi = 0;
- initd++;
-
- printk("dgnc: tracing enabled - " TRC_DTRC
- " 0x%lx 0x%x\n",
- (unsigned long)dgnc_trcbuf,
- dgnc_trcbuf_size);
- }
-
-# if defined(TRC_ON_OVERFLOW_WRAP_AROUND)
- /*
- * This is the less CPU-intensive way to do things. We simply
- * wrap around before we fall off the end of the buffer. A
- * tilde (~) demarcates the current end of the trace.
- *
- * This method should be used if you are concerned about race
- * conditions as it is less likely to affect the timing of
- * things.
- */
-
- if (dgnc_trcbufi + lenbuf >= dgnc_trcbuf_size) {
- /* We are wrapping, so wipe out the last tilde. */
- dgnc_trcbuf[dgnc_trcbufi] = '\0';
- /* put the new string at the beginning of the buffer */
- dgnc_trcbufi = 0;
- }
-
- strcpy(&dgnc_trcbuf[dgnc_trcbufi], buf);
- dgnc_trcbufi += lenbuf;
- dgnc_trcbuf[dgnc_trcbufi] = '~';
-
-# elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER)
- /*
- * This is the more CPU-intensive way to do things. If we
- * venture into the last 1/8 of the buffer, we shift the
- * last 7/8 of the buffer forward, wiping out the first 1/8.
- * Advantage: No wrap-around, only truncation from the
- * beginning.
- *
- * This method should not be used if you are concerned about
- * timing changes affecting the behaviour of the driver (ie,
- * race conditions).
- */
- strcpy(&dgnc_trcbuf[dgnc_trcbufi], buf);
- dgnc_trcbufi += lenbuf;
- dgnc_trcbuf[dgnc_trcbufi] = '~';
- dgnc_trcbuf[dgnc_trcbufi+1] = '\0';
-
- /* If we're near the end of the trace buffer... */
- if (dgnc_trcbufi > (dgnc_trcbuf_size/8)*7) {
- /* Wipe out the first eighth to make some more room. */
- strcpy(dgnc_trcbuf, &dgnc_trcbuf[dgnc_trcbuf_size/8]);
- dgnc_trcbufi = strlen(dgnc_trcbuf)-1;
- /* Plop overflow message at the top of the buffer. */
- bcopy(TRC_OVERFLOW, dgnc_trcbuf, strlen(TRC_OVERFLOW));
- }
-# else
-# error "TRC_ON_OVERFLOW_WRAP_AROUND or TRC_ON_OVERFLOW_SHIFT_BUFFER?"
-# endif
- }
- DGNC_UNLOCK(dgnc_tracef_lock, flags);
-
-# endif /* defined(TRC_TO_KMEM) */
-}
-
-#endif /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
-
-#endif
-
-
-/*
- * dgnc_tracer_free()
- *
- *
- */
-void dgnc_tracer_free(void)
-{
- if (dgnc_trcbuf)
- vfree(dgnc_trcbuf);
-}
diff --git a/drivers/staging/dgnc/dgnc_trace.h b/drivers/staging/dgnc/dgnc_trace.h
deleted file mode 100644
index efed88a627dc..000000000000
--- a/drivers/staging/dgnc/dgnc_trace.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2003 Digi International (www.digi.com)
- * Scott H Kilau <Scott_Kilau at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * NOTE: THIS IS A SHARED HEADER. DO NOT CHANGE CODING STYLE!!!
- *
- *****************************************************************************
- * Header file for dgnc_trace.c
- *
- */
-
-#ifndef __DGNC_TRACE_H
-#define __DGNC_TRACE_H
-
-#include "dgnc_driver.h"
-
-#if 0
-
-# if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
- void dgnc_tracef(const char *fmt, ...);
-# else
- void dgnc_tracef(const char *fmt, ...);
-# endif
-
-#endif
-
-void dgnc_tracer_free(void);
-
-#endif
-
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 4135cb0ed9f5..c712b431f969 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -53,7 +53,6 @@
#include "dgnc_driver.h"
#include "dgnc_tty.h"
#include "dgnc_types.h"
-#include "dgnc_trace.h"
#include "dgnc_neo.h"
#include "dgnc_cls.h"
#include "dpacompat.h"
@@ -200,9 +199,6 @@ int dgnc_tty_register(struct dgnc_board *brd)
DPR_INIT(("tty_register start\n"));
- memset(&brd->SerialDriver, 0, sizeof(brd->SerialDriver));
- memset(&brd->PrintDriver, 0, sizeof(brd->PrintDriver));
-
brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
snprintf(brd->SerialName, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
@@ -417,10 +413,8 @@ int dgnc_tty_init(struct dgnc_board *brd)
*/
void dgnc_tty_post_uninit(void)
{
- if (dgnc_TmpWriteBuf) {
- kfree(dgnc_TmpWriteBuf);
- dgnc_TmpWriteBuf = NULL;
- }
+ kfree(dgnc_TmpWriteBuf);
+ dgnc_TmpWriteBuf = NULL;
}
@@ -456,14 +450,10 @@ void dgnc_tty_uninit(struct dgnc_board *brd)
brd->dgnc_Major_TransparentPrint_Registered = FALSE;
}
- if (brd->SerialDriver.ttys) {
- kfree(brd->SerialDriver.ttys);
- brd->SerialDriver.ttys = NULL;
- }
- if (brd->PrintDriver.ttys) {
- kfree(brd->PrintDriver.ttys);
- brd->PrintDriver.ttys = NULL;
- }
+ kfree(brd->SerialDriver.ttys);
+ brd->SerialDriver.ttys = NULL;
+ kfree(brd->PrintDriver.ttys);
+ brd->PrintDriver.ttys = NULL;
}
@@ -1642,10 +1632,10 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
un->un_open_count = 1;
}
- if (--un->un_open_count < 0) {
+ if (un->un_open_count)
+ un->un_open_count--;
+ else
APR(("bad serial port open count of %d\n", un->un_open_count));
- un->un_open_count = 0;
- }
ch->ch_open_count--;
@@ -2116,24 +2106,6 @@ static int dgnc_tty_write(struct tty_struct *tty,
ch->ch_w_head = head;
}
-#if 0
- /*
- * If this is the print device, and the
- * printer is still on, we need to turn it
- * off before going idle.
- */
- if (count == orig_count) {
- if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
- head &= tmask;
- ch->ch_w_head = head;
- dgnc_wmove(ch, ch->ch_digi.digi_offstr,
- (int) ch->ch_digi.digi_offlen);
- head = (ch->ch_w_head) & tmask;
- ch->ch_flags &= ~CH_PRON;
- }
- }
-#endif
-
/* Update printer buffer empty time. */
if ((un->un_type == DGNC_PRINT) && (ch->ch_digi.digi_maxcps > 0)
&& (ch->ch_digi.digi_bufsize > 0)) {
@@ -3436,11 +3408,4 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
return -ENOIOCTLCMD;
}
-
- DGNC_UNLOCK(ch->ch_lock, lock_flags);
-
- DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
- dgnc_ioctl_name(cmd), cmd, arg));
-
- return 0;
}
diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h
index 6a9adf6591eb..252791835044 100644
--- a/drivers/staging/dgnc/digi.h
+++ b/drivers/staging/dgnc/digi.h
@@ -394,23 +394,22 @@ struct digi_getcounter {
#define DIGI_REALPORT_GETCOUNTERS ('e'<<8 ) | 110
#define DIGI_REALPORT_GETEVENTS ('e'<<8 ) | 111
-#define EV_OPU 0x0001 //!<Output paused by client
-#define EV_OPS 0x0002 //!<Output paused by reqular sw flowctrl
-#define EV_OPX 0x0004 //!<Output paused by extra sw flowctrl
-#define EV_OPH 0x0008 //!<Output paused by hw flowctrl
-#define EV_OPT 0x0800 //!<Output paused for RTS Toggle predelay
-
-#define EV_IPU 0x0010 //!<Input paused unconditionally by user
-#define EV_IPS 0x0020 //!<Input paused by high/low water marks
-//#define EV_IPH 0x0040 //!<Input paused w/ hardware
-#define EV_IPA 0x0400 //!<Input paused by pattern alarm module
-
-#define EV_TXB 0x0040 //!<Transmit break pending
-#define EV_TXI 0x0080 //!<Transmit immediate pending
-#define EV_TXF 0x0100 //!<Transmit flowctrl char pending
-#define EV_RXB 0x0200 //!<Break received
-
-#define EV_OPALL 0x080f //!<Output pause flags
-#define EV_IPALL 0x0430 //!<Input pause flags
+#define EV_OPU 0x0001 /* !<Output paused by client */
+#define EV_OPS 0x0002 /* !<Output paused by reqular sw flowctrl */
+#define EV_OPX 0x0004 /* !<Output paused by extra sw flowctrl */
+#define EV_OPH 0x0008 /* !<Output paused by hw flowctrl */
+#define EV_OPT 0x0800 /* !<Output paused for RTS Toggle predelay */
+
+#define EV_IPU 0x0010 /* !<Input paused unconditionally by user */
+#define EV_IPS 0x0020 /* !<Input paused by high/low water marks */
+#define EV_IPA 0x0400 /* !<Input paused by pattern alarm module */
+
+#define EV_TXB 0x0040 /* !<Transmit break pending */
+#define EV_TXI 0x0080 /* !<Transmit immediate pending */
+#define EV_TXF 0x0100 /* !<Transmit flowctrl char pending */
+#define EV_RXB 0x0200 /* !<Break received */
+
+#define EV_OPALL 0x080f /* !<Output pause flags */
+#define EV_IPALL 0x0430 /* !<Input pause flags */
#endif /* DIGI_H */
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig
deleted file mode 100644
index e4c41552923a..000000000000
--- a/drivers/staging/dgrp/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config DGRP
- tristate "Digi Realport driver"
- default n
- depends on SYSFS && TTY
- ---help---
- Support for Digi Realport devices. These devices allow you to
- access remote serial ports as if they are local tty devices. This
- will build the kernel driver, you will still need the userspace
- component to make your Realport device work.
diff --git a/drivers/staging/dgrp/Makefile b/drivers/staging/dgrp/Makefile
deleted file mode 100644
index d9c3b88d7162..000000000000
--- a/drivers/staging/dgrp/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-obj-$(CONFIG_DGRP) += dgrp.o
-
-dgrp-y := \
- dgrp_common.o \
- dgrp_dpa_ops.o \
- dgrp_driver.o \
- dgrp_mon_ops.o \
- dgrp_net_ops.o \
- dgrp_ports_ops.o \
- dgrp_specproc.o \
- dgrp_tty.o \
- dgrp_sysfs.o
diff --git a/drivers/staging/dgrp/README b/drivers/staging/dgrp/README
deleted file mode 100644
index 1d8aaee270e8..000000000000
--- a/drivers/staging/dgrp/README
+++ /dev/null
@@ -1,2 +0,0 @@
-The user space code to work with this driver is located at
-https://github.com/wfp5p/dgrp-utils
diff --git a/drivers/staging/dgrp/TODO b/drivers/staging/dgrp/TODO
deleted file mode 100644
index 3ef2611bc6d7..000000000000
--- a/drivers/staging/dgrp/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
-- Use configfs for config stuff. This will require changes to the
- user space code.
-
-- dgrp_send() and dgrp_receive() could use some refactoring
-
-- Don't automatically create CHAN_MAX (64) channel array entries for
- every device as many devices are going to have much less than 64
- channels.
-
-- The locking needs to be checked. It seems haphazardly done in most
- places.
-
-- Check Kconfig dependencies
diff --git a/drivers/staging/dgrp/dgrp_common.c b/drivers/staging/dgrp/dgrp_common.c
deleted file mode 100644
index 9a9b45624ba9..000000000000
--- a/drivers/staging/dgrp/dgrp_common.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_common.c
- *
- * Description:
- *
- * Definitions of global variables and functions which are either
- * shared by the tty, mon, and net drivers; or which cross them
- * functionally (like the poller).
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-#include <linux/cred.h>
-
-#include "dgrp_common.h"
-
-/**
- * dgrp_carrier -- check for carrier change state and act
- * @ch: struct ch_struct *
- */
-void dgrp_carrier(struct ch_struct *ch)
-{
- struct nd_struct *nd;
-
- int virt_carrier = 0;
- int phys_carrier = 0;
-
- /* fix case when the tty has already closed. */
-
- if (!ch)
- return;
- nd = ch->ch_nd;
- if (!nd)
- return;
-
- /*
- * If we are currently waiting to determine the status of the port,
- * we don't yet know the state of the modem lines. As a result,
- * we ignore state changes when we are waiting for the modem lines
- * to be established. We know, as a result of code in dgrp_net_ops,
- * that we will be called again immediately following the reception
- * of the status message with the true modem status flags in it.
- */
- if (ch->ch_expect & RR_STATUS)
- return;
-
- /*
- * If CH_HANGUP is set, we gotta keep trying to get all the processes
- * that have the port open to close the port.
- * So lets just keep sending a hangup every time we get here.
- */
- if ((ch->ch_flag & CH_HANGUP) &&
- (ch->ch_tun.un_open_count > 0))
- tty_hangup(ch->ch_tun.un_tty);
-
- /*
- * Compute the effective state of both the physical and virtual
- * senses of carrier.
- */
-
- if (ch->ch_s_mlast & DM_CD)
- phys_carrier = 1;
-
- if ((ch->ch_s_mlast & DM_CD) ||
- (ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
- (ch->ch_flag & CH_CLOCAL))
- virt_carrier = 1;
-
- /*
- * Test for a VIRTUAL carrier transition to HIGH.
- *
- * The CH_HANGUP condition is intended to prevent any action
- * except for close. As a result, we ignore positive carrier
- * transitions during CH_HANGUP.
- */
- if (((ch->ch_flag & CH_HANGUP) == 0) &&
- ((ch->ch_flag & CH_VIRT_CD) == 0) &&
- (virt_carrier == 1)) {
- /*
- * When carrier rises, wake any threads waiting
- * for carrier in the open routine.
- */
- nd->nd_tx_work = 1;
-
- if (waitqueue_active(&ch->ch_flag_wait))
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
- /*
- * Test for a PHYSICAL transition to low, so long as we aren't
- * currently ignoring physical transitions (which is what "virtual
- * carrier" indicates).
- *
- * The transition of the virtual carrier to low really doesn't
- * matter... it really only means "ignore carrier state", not
- * "make pretend that carrier is there".
- */
- if ((virt_carrier == 0) &&
- ((ch->ch_flag & CH_PHYS_CD) != 0) &&
- (phys_carrier == 0)) {
- /*
- * When carrier drops:
- *
- * Do a Hard Hangup if that is called for.
- *
- * Drop carrier on all open units.
- *
- * Flush queues, waking up any task waiting in the
- * line discipline.
- *
- * Send a hangup to the control terminal.
- *
- * Enable all select calls.
- */
-
- nd->nd_tx_work = 1;
-
- ch->ch_flag &= ~(CH_LOW | CH_EMPTY | CH_DRAIN | CH_INPUT);
-
- if (waitqueue_active(&ch->ch_flag_wait))
- wake_up_interruptible(&ch->ch_flag_wait);
-
- if (ch->ch_tun.un_open_count > 0)
- tty_hangup(ch->ch_tun.un_tty);
-
- if (ch->ch_pun.un_open_count > 0)
- tty_hangup(ch->ch_pun.un_tty);
- }
-
- /*
- * Make sure that our cached values reflect the current reality.
- */
- if (virt_carrier == 1)
- ch->ch_flag |= CH_VIRT_CD;
- else
- ch->ch_flag &= ~CH_VIRT_CD;
-
- if (phys_carrier == 1)
- ch->ch_flag |= CH_PHYS_CD;
- else
- ch->ch_flag &= ~CH_PHYS_CD;
-
-}
diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h
deleted file mode 100644
index 23aba6c4d22c..000000000000
--- a/drivers/staging/dgrp/dgrp_common.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-#ifndef __DGRP_COMMON_H
-#define __DGRP_COMMON_H
-
-#define DIGI_VERSION "1.9-29"
-
-#include <linux/fs.h>
-#include <linux/timer.h>
-#include "drp.h"
-
-#define DGRP_TTIME 100
-#define DGRP_RTIME 100
-
-/************************************************************************
- * All global storage allocation.
- ************************************************************************/
-
-extern int dgrp_register_cudevices; /* enable legacy cu devices */
-extern int dgrp_register_prdevices; /* enable transparent print devices */
-extern int dgrp_poll_tick; /* Poll interval - in ms */
-
-extern struct list_head nd_struct_list;
-
-struct dgrp_poll_data {
- spinlock_t poll_lock;
- struct timer_list timer;
- int poll_tick;
- ulong poll_round; /* Timer rouding factor */
- long node_active_count;
-};
-
-extern struct dgrp_poll_data dgrp_poll_data;
-extern void dgrp_poll_handler(unsigned long arg);
-
-/* from dgrp_mon_ops.c */
-extern const struct file_operations dgrp_mon_ops;
-
-/* from dgrp_tty.c */
-extern int dgrp_tty_init(struct nd_struct *nd);
-extern void dgrp_tty_uninit(struct nd_struct *nd);
-
-/* from dgrp_ports_ops.c */
-extern const struct file_operations dgrp_ports_ops;
-
-/* from dgrp_net_ops.c */
-extern const struct file_operations dgrp_net_ops;
-
-/* from dgrp_dpa_ops.c */
-extern const struct file_operations dgrp_dpa_ops;
-extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int);
-
-/* from dgrp_sysfs.c */
-extern int dgrp_create_class_sysfs_files(void);
-extern void dgrp_remove_class_sysfs_files(void);
-
-extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd);
-extern void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd);
-
-extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c);
-extern void dgrp_remove_tty_sysfs(struct device *c);
-
-/* from dgrp_specproc.c */
-extern void dgrp_unregister_proc(void);
-extern void dgrp_register_proc(void);
-
-/*-----------------------------------------------------------------------*
- *
- * Declarations for common operations:
- *
- * (either used by more than one of net, mon, or tty,
- * or in interrupt context (i.e. the poller))
- *
- *-----------------------------------------------------------------------*/
-
-void dgrp_carrier(struct ch_struct *ch);
-
-
-/*
- * ID manipulation macros (where c1 & c2 are characters, i is
- * a long integer, and s is a character array of at least three members
- */
-
-static inline void ID_TO_CHAR(long i, char *s)
-{
- s[0] = ((i & 0xff00)>>8);
- s[1] = (i & 0xff);
- s[2] = 0;
-}
-
-static inline long CHAR_TO_ID(char *s)
-{
- return ((s[0] & 0xff) << 8) | (s[1] & 0xff);
-}
-
-static inline struct nd_struct *nd_struct_get(long major)
-{
- struct nd_struct *nd;
-
- list_for_each_entry(nd, &nd_struct_list, list) {
- if (major == nd->nd_major)
- return nd;
- }
-
- return NULL;
-}
-
-static inline int nd_struct_add(struct nd_struct *entry)
-{
- struct nd_struct *ptr;
-
- ptr = nd_struct_get(entry->nd_major);
-
- if (ptr)
- return -EBUSY;
-
- list_add_tail(&entry->list, &nd_struct_list);
-
- return 0;
-}
-
-static inline int nd_struct_del(struct nd_struct *entry)
-{
- struct nd_struct *nd;
-
- nd = nd_struct_get(entry->nd_major);
-
- if (!nd)
- return -ENODEV;
-
- list_del(&nd->list);
- return 0;
-}
-
-#endif /* __DGRP_COMMON_H */
diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c
deleted file mode 100644
index 69bfe309376d..000000000000
--- a/drivers/staging/dgrp/dgrp_dpa_ops.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_dpa_ops.c
- *
- * Description:
- *
- * Handle the file operations required for the "dpa" devices.
- * Includes those functions required to register the "dpa" devices
- * in "/proc".
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/tty.h>
-#include <linux/poll.h>
-#include <linux/cred.h>
-#include <linux/sched.h>
-#include <linux/ratelimit.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-
-#include "dgrp_common.h"
-
-/* File operation declarations */
-static int dgrp_dpa_open(struct inode *, struct file *);
-static int dgrp_dpa_release(struct inode *, struct file *);
-static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *);
-static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);
-
-const struct file_operations dgrp_dpa_ops = {
- .owner = THIS_MODULE,
- .read = dgrp_dpa_read,
- .poll = dgrp_dpa_select,
- .unlocked_ioctl = dgrp_dpa_ioctl,
- .open = dgrp_dpa_open,
- .release = dgrp_dpa_release,
-};
-
-struct digi_node {
- uint nd_state; /* Node state: 1 = up, 0 = down. */
- uint nd_chan_count; /* Number of channels found */
- uint nd_tx_byte; /* Tx data count */
- uint nd_rx_byte; /* RX data count */
- u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
-};
-
-#define DIGI_GETNODE (('d'<<8) | 249) /* get board info */
-
-
-struct digi_chan {
- uint ch_port; /* Port number to get info on */
- uint ch_open; /* 1 if open, 0 if not */
- uint ch_txcount; /* TX data count */
- uint ch_rxcount; /* RX data count */
- uint ch_s_brate; /* Realport BRATE */
- uint ch_s_estat; /* Realport ELAST */
- uint ch_s_cflag; /* Realport CFLAG */
- uint ch_s_iflag; /* Realport IFLAG */
- uint ch_s_oflag; /* Realport OFLAG */
- uint ch_s_xflag; /* Realport XFLAG */
- uint ch_s_mstat; /* Realport MLAST */
-};
-
-#define DIGI_GETCHAN (('d'<<8) | 248) /* get channel info */
-
-
-struct digi_vpd {
- int vpd_len;
- char vpd_data[VPDSIZE];
-};
-
-#define DIGI_GETVPD (('d'<<8) | 246) /* get VPD info */
-
-
-struct digi_debug {
- int onoff;
- int port;
-};
-
-#define DIGI_SETDEBUG (('d'<<8) | 247) /* set debug info */
-
-
-/*
- * dgrp_dpa_open -- open the DPA device for a particular PortServer
- */
-static int dgrp_dpa_open(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
- int rtn = 0;
-
- rtn = try_module_get(THIS_MODULE);
- if (!rtn)
- return -ENXIO;
-
- rtn = 0;
-
- if (!capable(CAP_SYS_ADMIN)) {
- rtn = -EPERM;
- goto done;
- }
-
- /*
- * Make sure that the "private_data" field hasn't already been used.
- */
- if (file->private_data) {
- rtn = -EINVAL;
- goto done;
- }
-
- /*
- * Get the node pointer, and fail if it doesn't exist.
- */
- nd = PDE_DATA(inode);
- if (!nd) {
- rtn = -ENXIO;
- goto done;
- }
-
- file->private_data = (void *) nd;
-
- /*
- * Allocate the DPA buffer.
- */
-
- if (nd->nd_dpa_buf) {
- rtn = -EBUSY;
- } else {
- nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL);
-
- if (!nd->nd_dpa_buf) {
- rtn = -ENOMEM;
- } else {
- nd->nd_dpa_out = 0;
- nd->nd_dpa_in = 0;
- nd->nd_dpa_lbolt = jiffies;
- }
- }
-
-done:
-
- if (rtn)
- module_put(THIS_MODULE);
- return rtn;
-}
-
-/*
- * dgrp_dpa_release -- close the DPA device for a particular PortServer
- */
-static int dgrp_dpa_release(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
- u8 *buf;
- unsigned long lock_flags;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- goto done;
-
- /*
- * Free the dpa buffer.
- */
-
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
-
- buf = nd->nd_dpa_buf;
-
- nd->nd_dpa_buf = NULL;
- nd->nd_dpa_out = nd->nd_dpa_in;
-
- /*
- * Wakeup any thread waiting for buffer space.
- */
-
- if (nd->nd_dpa_flag & DPA_WAIT_SPACE) {
- nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
- wake_up_interruptible(&nd->nd_dpa_wqueue);
- }
-
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
-
- kfree(buf);
-
-done:
- module_put(THIS_MODULE);
- file->private_data = NULL;
- return 0;
-}
-
-/*
- * dgrp_dpa_read
- *
- * Copy data from the monitoring buffer to the user, freeing space
- * in the monitoring buffer for more messages
- */
-static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct nd_struct *nd;
- int n;
- int r;
- int offset = 0;
- int res = 0;
- ssize_t rtn;
- unsigned long lock_flags;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- return -ENXIO;
-
- /*
- * Wait for some data to appear in the buffer.
- */
-
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
-
- for (;;) {
- n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
-
- if (n != 0)
- break;
-
- nd->nd_dpa_flag |= DPA_WAIT_DATA;
-
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
-
- /*
- * Go to sleep waiting until the condition becomes true.
- */
- rtn = wait_event_interruptible(nd->nd_dpa_wqueue,
- ((nd->nd_dpa_flag & DPA_WAIT_DATA) == 0));
-
- if (rtn)
- return rtn;
-
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
- }
-
- /*
- * Read whatever is there.
- */
-
- if (n > count)
- n = count;
-
- res = n;
-
- r = DPA_MAX - nd->nd_dpa_out;
-
- if (r <= n) {
-
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
- rtn = copy_to_user((void __user *)buf,
- nd->nd_dpa_buf + nd->nd_dpa_out, r);
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
-
- if (rtn) {
- rtn = -EFAULT;
- goto done;
- }
-
- nd->nd_dpa_out = 0;
- n -= r;
- offset = r;
- }
-
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
- rtn = copy_to_user((void __user *)buf + offset,
- nd->nd_dpa_buf + nd->nd_dpa_out, n);
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
-
- if (rtn) {
- rtn = -EFAULT;
- goto done;
- }
-
- nd->nd_dpa_out += n;
-
- *ppos += res;
-
- rtn = res;
-
- /*
- * Wakeup any thread waiting for buffer space.
- */
-
- n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
-
- if (nd->nd_dpa_flag & DPA_WAIT_SPACE &&
- (DPA_MAX - n) > DPA_HIGH_WATER) {
- nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
- wake_up_interruptible(&nd->nd_dpa_wqueue);
- }
-
- done:
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
- return rtn;
-}
-
-static unsigned int dgrp_dpa_select(struct file *file,
- struct poll_table_struct *table)
-{
- unsigned int retval = 0;
- struct nd_struct *nd = file->private_data;
-
- if (nd->nd_dpa_out != nd->nd_dpa_in)
- retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
-
- retval |= POLLOUT | POLLWRNORM; /* Always writeable */
-
- return retval;
-}
-
-static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
-
- struct nd_struct *nd;
- struct digi_chan getchan;
- struct digi_node getnode;
- struct ch_struct *ch;
- struct digi_debug setdebug;
- struct digi_vpd vpd;
- unsigned int port;
- void __user *uarg = (void __user *) arg;
-
- nd = file->private_data;
-
- switch (cmd) {
- case DIGI_GETCHAN:
- if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan)))
- return -EFAULT;
-
- port = getchan.ch_port;
-
- if (port > nd->nd_chan_count)
- return -EINVAL;
-
- ch = nd->nd_chan + port;
-
- getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0;
- getchan.ch_txcount = ch->ch_txcount;
- getchan.ch_rxcount = ch->ch_rxcount;
- getchan.ch_s_brate = ch->ch_s_brate;
- getchan.ch_s_estat = ch->ch_s_elast;
- getchan.ch_s_cflag = ch->ch_s_cflag;
- getchan.ch_s_iflag = ch->ch_s_iflag;
- getchan.ch_s_oflag = ch->ch_s_oflag;
- getchan.ch_s_xflag = ch->ch_s_xflag;
- getchan.ch_s_mstat = ch->ch_s_mlast;
-
- if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan)))
- return -EFAULT;
- break;
-
-
- case DIGI_GETNODE:
- getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0;
- getnode.nd_chan_count = nd->nd_chan_count;
- getnode.nd_tx_byte = nd->nd_tx_byte;
- getnode.nd_rx_byte = nd->nd_rx_byte;
-
- memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
- strlcpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
-
- if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
- return -EFAULT;
- break;
-
-
- case DIGI_SETDEBUG:
- if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug)))
- return -EFAULT;
-
- nd->nd_dpa_debug = setdebug.onoff;
- nd->nd_dpa_port = setdebug.port;
- break;
-
-
- case DIGI_GETVPD:
- memset(&vpd, 0, sizeof(vpd));
- if (nd->nd_vpd_len > 0) {
- vpd.vpd_len = nd->nd_vpd_len;
- memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len);
- } else {
- vpd.vpd_len = 0;
- }
-
- if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd)))
- return -EFAULT;
- break;
- }
-
- return 0;
-}
-
-/**
- * dgrp_dpa() -- send data to the device monitor queue
- * @nd: pointer to a node structure
- * @buf: buffer of data to copy to the monitoring buffer
- * @len: number of bytes to transfer to the buffer
- *
- * Called by the net device routines to send data to the device
- * monitor queue. If the device monitor buffer is too full to
- * accept the data, it waits until the buffer is ready.
- */
-static void dgrp_dpa(struct nd_struct *nd, u8 *buf, int nbuf)
-{
- int n;
- int r;
- unsigned long lock_flags;
-
- /*
- * Grab DPA lock.
- */
- spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
-
- /*
- * Loop while data remains.
- */
- while (nbuf > 0 && nd->nd_dpa_buf != NULL) {
-
- n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK;
-
- /*
- * Enforce flow control on the DPA device.
- */
- if (n < (DPA_MAX - DPA_HIGH_WATER))
- nd->nd_dpa_flag |= DPA_WAIT_SPACE;
-
- /*
- * This should never happen, as the flow control above
- * should have stopped things before they got to this point.
- */
- if (n == 0) {
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
- return;
- }
-
- /*
- * Copy as much data as will fit.
- */
-
- if (n > nbuf)
- n = nbuf;
-
- r = DPA_MAX - nd->nd_dpa_in;
-
- if (r <= n) {
- memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, r);
-
- n -= r;
-
- nd->nd_dpa_in = 0;
-
- buf += r;
- nbuf -= r;
- }
-
- memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n);
-
- nd->nd_dpa_in += n;
-
- buf += n;
- nbuf -= n;
-
- if (nd->nd_dpa_in >= DPA_MAX)
- pr_info_ratelimited("%s - nd->nd_dpa_in (%i) >= DPA_MAX\n",
- __func__, nd->nd_dpa_in);
-
- /*
- * Wakeup any thread waiting for data
- */
- if (nd->nd_dpa_flag & DPA_WAIT_DATA) {
- nd->nd_dpa_flag &= ~DPA_WAIT_DATA;
- wake_up_interruptible(&nd->nd_dpa_wqueue);
- }
- }
-
- /*
- * Release the DPA lock.
- */
- spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
-}
-
-/**
- * dgrp_monitor_data() -- builds a DPA data packet
- * @nd: pointer to a node structure
- * @type: type of message to be logged in the DPA buffer
- * @buf: buffer of data to be logged in the DPA buffer
- * @size -- number of bytes in the "buf" buffer
- */
-void dgrp_dpa_data(struct nd_struct *nd, int type, u8 *buf, int size)
-{
- u8 header[5];
-
- header[0] = type;
-
- put_unaligned_be32(size, header + 1);
-
- dgrp_dpa(nd, header, sizeof(header));
- dgrp_dpa(nd, buf, size);
-}
diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c
deleted file mode 100644
index b60a8da6350a..000000000000
--- a/drivers/staging/dgrp/dgrp_driver.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * Copyright 1999-2003 Digi International (www.digi.com)
- * Jeff Randall
- * James Puzzo <jamesp at digi dot com>
- * Scott Kilau <Scott_Kilau at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- * Driver specific includes
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-
-/*
- * PortServer includes
- */
-#include "dgrp_common.h"
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Digi International, http://www.digi.com");
-MODULE_DESCRIPTION("RealPort driver for Digi's ethernet-based serial connectivity product line");
-MODULE_VERSION(DIGI_VERSION);
-
-struct list_head nd_struct_list;
-struct dgrp_poll_data dgrp_poll_data;
-
-int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
-int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
-int dgrp_poll_tick = 20; /* Poll interval - in ms */
-
-module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
-MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
-
-module_param_named(register_prdevices, dgrp_register_prdevices, int, 0644);
-MODULE_PARM_DESC(register_prdevices, "Turn on/off registering transparent print devices");
-
-module_param_named(pollrate, dgrp_poll_tick, int, 0644);
-MODULE_PARM_DESC(pollrate, "Poll interval in ms");
-
-/*
- * init_module()
- *
- * Module load. This is where it all starts.
- */
-static int __init dgrp_init_module(void)
-{
- int ret;
-
- INIT_LIST_HEAD(&nd_struct_list);
-
- spin_lock_init(&dgrp_poll_data.poll_lock);
- init_timer(&dgrp_poll_data.timer);
- dgrp_poll_data.poll_tick = dgrp_poll_tick;
- dgrp_poll_data.timer.function = dgrp_poll_handler;
- dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data;
-
- ret = dgrp_create_class_sysfs_files();
- if (ret)
- return ret;
-
- dgrp_register_proc();
-
- return 0;
-}
-
-
-/*
- * Module unload. This is where it all ends.
- */
-static void __exit dgrp_cleanup_module(void)
-{
- struct nd_struct *nd, *next;
-
- /*
- * Attempting to free resources in backwards
- * order of allocation, in case that helps
- * memory pool fragmentation.
- */
- dgrp_unregister_proc();
-
- dgrp_remove_class_sysfs_files();
-
-
- list_for_each_entry_safe(nd, next, &nd_struct_list, list) {
- dgrp_tty_uninit(nd);
- kfree(nd);
- }
-}
-
-module_init(dgrp_init_module);
-module_exit(dgrp_cleanup_module);
diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c
deleted file mode 100644
index d18be4180e3b..000000000000
--- a/drivers/staging/dgrp/dgrp_mon_ops.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*****************************************************************************
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_mon_ops.c
- *
- * Description:
- *
- * Handle the file operations required for the "monitor" devices.
- * Includes those functions required to register the "mon" devices
- * in "/proc".
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-#include <asm/unaligned.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/uaccess.h>
-
-#include "dgrp_common.h"
-
-/* File operation declarations */
-static int dgrp_mon_open(struct inode *, struct file *);
-static int dgrp_mon_release(struct inode *, struct file *);
-static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *);
-static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-
-const struct file_operations dgrp_mon_ops = {
- .owner = THIS_MODULE,
- .read = dgrp_mon_read,
- .unlocked_ioctl = dgrp_mon_ioctl,
- .open = dgrp_mon_open,
- .release = dgrp_mon_release,
-};
-
-/**
- * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer
- * @inode: struct inode *
- * @file: struct file *
- *
- * Open function to open the /proc/dgrp/ports device for a PortServer.
- */
-static int dgrp_mon_open(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
- struct timeval tv;
- uint32_t time;
- u8 *buf;
- int rtn;
-
- rtn = try_module_get(THIS_MODULE);
- if (!rtn)
- return -ENXIO;
-
- rtn = 0;
-
- if (!capable(CAP_SYS_ADMIN)) {
- rtn = -EPERM;
- goto done;
- }
-
- /*
- * Make sure that the "private_data" field hasn't already been used.
- */
- if (file->private_data) {
- rtn = -EINVAL;
- goto done;
- }
-
- /*
- * Get the node pointer, and fail if it doesn't exist.
- */
- nd = PDE_DATA(inode);
- if (!nd) {
- rtn = -ENXIO;
- goto done;
- }
-
- file->private_data = (void *) nd;
-
- /*
- * Allocate the monitor buffer.
- */
-
- /*
- * Grab the MON lock.
- */
- down(&nd->nd_mon_semaphore);
-
- if (nd->nd_mon_buf) {
- rtn = -EBUSY;
- goto done_up;
- }
-
- nd->nd_mon_buf = kmalloc(MON_MAX, GFP_KERNEL);
-
- if (!nd->nd_mon_buf) {
- rtn = -ENOMEM;
- goto done_up;
- }
-
- /*
- * Enter an RPDUMP file header into the buffer.
- */
-
- buf = nd->nd_mon_buf;
-
- strcpy(buf, RPDUMP_MAGIC);
- buf += strlen(buf) + 1;
-
- do_gettimeofday(&tv);
-
- /*
- * tv.tv_sec might be a 64 bit quantity. Pare
- * it down to 32 bits before attempting to encode
- * it.
- */
- time = (uint32_t) (tv.tv_sec & 0xffffffff);
-
- put_unaligned_be32(time, buf);
- put_unaligned_be16(0, buf + 4);
- buf += 6;
-
- if (nd->nd_tx_module) {
- buf[0] = RPDUMP_CLIENT;
- put_unaligned_be32(0, buf + 1);
- put_unaligned_be16(1, buf + 5);
- buf[7] = 0xf0 + nd->nd_tx_module;
- buf += 8;
- }
-
- if (nd->nd_rx_module) {
- buf[0] = RPDUMP_SERVER;
- put_unaligned_be32(0, buf + 1);
- put_unaligned_be16(1, buf + 5);
- buf[7] = 0xf0 + nd->nd_rx_module;
- buf += 8;
- }
-
- nd->nd_mon_out = 0;
- nd->nd_mon_in = buf - nd->nd_mon_buf;
- nd->nd_mon_lbolt = jiffies;
-
-done_up:
- up(&nd->nd_mon_semaphore);
-
-done:
- if (rtn)
- module_put(THIS_MODULE);
- return rtn;
-}
-
-
-/**
- * dgrp_mon_release() - Close the MON device for a particular PortServer
- * @inode: struct inode *
- * @file: struct file *
- */
-static int dgrp_mon_release(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- goto done;
-
- /*
- * Free the monitor buffer.
- */
-
- down(&nd->nd_mon_semaphore);
-
- kfree(nd->nd_mon_buf);
- nd->nd_mon_buf = NULL;
- nd->nd_mon_out = nd->nd_mon_in;
-
- /*
- * Wakeup any thread waiting for buffer space.
- */
-
- if (nd->nd_mon_flag & MON_WAIT_SPACE) {
- nd->nd_mon_flag &= ~MON_WAIT_SPACE;
- wake_up_interruptible(&nd->nd_mon_wqueue);
- }
-
- up(&nd->nd_mon_semaphore);
-
- /*
- * Make sure there is no thread in the middle of writing a packet.
- */
- down(&nd->nd_net_semaphore);
- up(&nd->nd_net_semaphore);
-
-done:
- module_put(THIS_MODULE);
- file->private_data = NULL;
- return 0;
-}
-
-/**
- * dgrp_mon_read() -- Copy data from the monitoring buffer to the user
- */
-static ssize_t dgrp_mon_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct nd_struct *nd;
- int r;
- int offset = 0;
- int res = 0;
- ssize_t rtn;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- return -ENXIO;
-
- /*
- * Wait for some data to appear in the buffer.
- */
-
- down(&nd->nd_mon_semaphore);
-
- for (;;) {
- res = (nd->nd_mon_in - nd->nd_mon_out) & MON_MASK;
-
- if (res)
- break;
-
- nd->nd_mon_flag |= MON_WAIT_DATA;
-
- up(&nd->nd_mon_semaphore);
-
- /*
- * Go to sleep waiting until the condition becomes true.
- */
- rtn = wait_event_interruptible(nd->nd_mon_wqueue,
- ((nd->nd_mon_flag & MON_WAIT_DATA) == 0));
-
- if (rtn)
- return rtn;
-
- down(&nd->nd_mon_semaphore);
- }
-
- /*
- * Read whatever is there.
- */
-
- if (res > count)
- res = count;
-
- r = MON_MAX - nd->nd_mon_out;
-
- if (r <= res) {
- rtn = copy_to_user((void __user *)buf,
- nd->nd_mon_buf + nd->nd_mon_out, r);
- if (rtn) {
- up(&nd->nd_mon_semaphore);
- return -EFAULT;
- }
-
- nd->nd_mon_out = 0;
- res -= r;
- offset = r;
- }
-
- rtn = copy_to_user((void __user *) buf + offset,
- nd->nd_mon_buf + nd->nd_mon_out, res);
- if (rtn) {
- up(&nd->nd_mon_semaphore);
- return -EFAULT;
- }
-
- nd->nd_mon_out += res;
-
- *ppos += res;
-
- up(&nd->nd_mon_semaphore);
-
- /*
- * Wakeup any thread waiting for buffer space.
- */
-
- if (nd->nd_mon_flag & MON_WAIT_SPACE) {
- nd->nd_mon_flag &= ~MON_WAIT_SPACE;
- wake_up_interruptible(&nd->nd_mon_wqueue);
- }
-
- return res;
-}
-
-/* ioctl is not valid on monitor device */
-static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return -EINVAL;
-}
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c
deleted file mode 100644
index 33ac7fb88cbd..000000000000
--- a/drivers/staging/dgrp/dgrp_net_ops.c
+++ /dev/null
@@ -1,3666 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_net_ops.c
- *
- * Description:
- *
- * Handle the file operations required for the "network" devices.
- * Includes those functions required to register the "net" devices
- * in "/proc".
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/spinlock.h>
-#include <linux/poll.h>
-#include <linux/sched.h>
-#include <linux/ratelimit.h>
-#include <asm/unaligned.h>
-
-#define MYFLIPLEN TBUF_MAX
-
-#include "dgrp_common.h"
-
-#define TTY_FLIPBUF_SIZE 512
-#define DEVICE_NAME_SIZE 50
-
-/*
- * Generic helper function declarations
- */
-static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
- unsigned char *fbuf, int *len);
-
-/*
- * File operation declarations
- */
-static int dgrp_net_open(struct inode *, struct file *);
-static int dgrp_net_release(struct inode *, struct file *);
-static ssize_t dgrp_net_read(struct file *, char __user *, size_t, loff_t *);
-static ssize_t dgrp_net_write(struct file *, const char __user *, size_t,
- loff_t *);
-static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg);
-static unsigned int dgrp_net_select(struct file *file,
- struct poll_table_struct *table);
-
-const struct file_operations dgrp_net_ops = {
- .owner = THIS_MODULE,
- .read = dgrp_net_read,
- .write = dgrp_net_write,
- .poll = dgrp_net_select,
- .unlocked_ioctl = dgrp_net_ioctl,
- .open = dgrp_net_open,
- .release = dgrp_net_release,
-};
-
-/**
- * dgrp_dump() -- prints memory for debugging purposes.
- * @mem: Memory location which should be printed to the console
- * @len: Number of bytes to be dumped
- */
-static void dgrp_dump(u8 *mem, int len)
-{
- int i;
-
- pr_debug("dgrp dump length = %d, data = ", len);
- for (i = 0; i < len; ++i)
- pr_debug("%.2x ", mem[i]);
- pr_debug("\n");
-}
-
-/**
- * dgrp_read_data_block() -- Read a data block
- * @ch: struct ch_struct *
- * @flipbuf: u8 *
- * @flipbuf_size: size of flipbuf
- */
-static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
- int flipbuf_size)
-{
- int t;
- int n;
-
- if (flipbuf_size <= 0)
- return;
-
- t = RBUF_MAX - ch->ch_rout;
- n = flipbuf_size;
-
- if (n >= t) {
- memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, t);
- flipbuf += t;
- n -= t;
- ch->ch_rout = 0;
- }
-
- memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, n);
- flipbuf += n;
- ch->ch_rout += n;
-}
-
-
-/**
- * dgrp_input() -- send data to the line disipline
- * @ch: pointer to channel struct
- *
- * Copys the rbuf to the flipbuf and sends to line discipline.
- * Sends input buffer data to the line discipline.
- *
- */
-static void dgrp_input(struct ch_struct *ch)
-{
- struct nd_struct *nd;
- struct tty_struct *tty;
- int data_len;
- int len;
- int tty_count;
- ulong lock_flags;
- u8 *myflipbuf;
- u8 *myflipflagbuf;
-
- if (!ch)
- return;
-
- nd = ch->ch_nd;
-
- if (!nd)
- return;
-
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
-
- myflipbuf = nd->nd_inputbuf;
- myflipflagbuf = nd->nd_inputflagbuf;
-
- if (!ch->ch_open_count) {
- ch->ch_rout = ch->ch_rin;
- goto out;
- }
-
- if (ch->ch_tun.un_flag & UN_CLOSING) {
- ch->ch_rout = ch->ch_rin;
- goto out;
- }
-
- tty = (ch->ch_tun).un_tty;
-
-
- if (!tty || tty->magic != TTY_MAGIC) {
- ch->ch_rout = ch->ch_rin;
- goto out;
- }
-
- tty_count = tty->count;
- if (!tty_count) {
- ch->ch_rout = ch->ch_rin;
- goto out;
- }
-
- if (tty->closing || test_bit(TTY_CLOSING, &tty->flags)) {
- ch->ch_rout = ch->ch_rin;
- goto out;
- }
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-
- /* data_len should be the number of chars that we read in */
- data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
-
- /* len is the amount of data we are going to transfer here */
- len = tty_buffer_request_room(&ch->port, data_len);
-
- /* Check DPA flow control */
- if ((nd->nd_dpa_debug) &&
- (nd->nd_dpa_flag & DPA_WAIT_SPACE) &&
- (nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))))
- len = 0;
-
- if ((len) && !(ch->ch_flag & CH_RXSTOP)) {
-
- dgrp_read_data_block(ch, myflipbuf, len);
-
- if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
- parity_scan(ch, myflipbuf, myflipflagbuf, &len);
- else
- memset(myflipflagbuf, TTY_NORMAL, len);
-
- if ((nd->nd_dpa_debug) &&
- (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
- dgrp_dpa_data(nd, 1, myflipbuf, len);
-
- tty_insert_flip_string_flags(&ch->port, myflipbuf,
- myflipflagbuf, len);
- tty_flip_buffer_push(&ch->port);
-
- ch->ch_rxcount += len;
- }
-
- /*
- * Wake up any sleepers (maybe dgrp close) that might be waiting
- * for a channel flag state change.
- */
- wake_up_interruptible(&ch->ch_flag_wait);
- return;
-
-out:
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-}
-
-
-/*
- * parity_scan
- *
- * Loop to inspect each single character or 0xFF escape.
- *
- * if PARMRK & ~DOSMODE:
- * 0xFF 0xFF Normal 0xFF character, escaped
- * to eliminate confusion.
- * 0xFF 0x00 0x00 Break
- * 0xFF 0x00 CC Error character CC.
- * CC Normal character CC.
- *
- * if PARMRK & DOSMODE:
- * 0xFF 0x18 0x00 Break
- * 0xFF 0x08 0x00 Framing Error
- * 0xFF 0x04 0x00 Parity error
- * 0xFF 0x0C 0x00 Both Framing and Parity error
- *
- * TODO: do we need to do the XMODEM, XOFF, XON, XANY processing??
- * as per protocol
- */
-static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
- unsigned char *fbuf, int *len)
-{
- int l = *len;
- int count = 0;
- int DOS = ((ch->ch_iflag & IF_DOSMODE) == 0 ? 0 : 1);
- unsigned char *cout; /* character buffer */
- unsigned char *fout; /* flag buffer */
- unsigned char *in;
- unsigned char c;
-
- in = cbuf;
- cout = cbuf;
- fout = fbuf;
-
- while (l--) {
- c = *in;
- in++;
-
- switch (ch->ch_pscan_state) {
- default:
- /* reset to sanity and fall through */
- ch->ch_pscan_state = 0;
-
- case 0:
- /* No FF seen yet */
- if (c == 0xff) /* delete this character from stream */
- ch->ch_pscan_state = 1;
- else {
- *cout++ = c;
- *fout++ = TTY_NORMAL;
- count += 1;
- }
- break;
-
- case 1:
- /* first FF seen */
- if (c == 0xff) {
- /* doubled ff, transform to single ff */
- *cout++ = c;
- *fout++ = TTY_NORMAL;
- count += 1;
- ch->ch_pscan_state = 0;
- } else {
- /* save value examination in next state */
- ch->ch_pscan_savechar = c;
- ch->ch_pscan_state = 2;
- }
- break;
-
- case 2:
- /* third character of ff sequence */
- *cout++ = c;
- if (DOS) {
- if (ch->ch_pscan_savechar & 0x10)
- *fout++ = TTY_BREAK;
- else if (ch->ch_pscan_savechar & 0x08)
- *fout++ = TTY_FRAME;
- else
- /*
- * either marked as a parity error,
- * indeterminate, or not in DOSMODE
- * call it a parity error
- */
- *fout++ = TTY_PARITY;
- } else {
- /* case FF XX ?? where XX is not 00 */
- if (ch->ch_pscan_savechar & 0xff) {
- /* this should not happen */
- pr_info("%s: parity_scan: error unexpected byte\n",
- __func__);
- *fout++ = TTY_PARITY;
- }
- /* case FF 00 XX where XX is not 00 */
- else if (c == 0xff)
- *fout++ = TTY_PARITY;
- /* case FF 00 00 */
- else
- *fout++ = TTY_BREAK;
-
- }
- count += 1;
- ch->ch_pscan_state = 0;
- }
- }
- *len = count;
-}
-
-
-/**
- * dgrp_net_idle() -- Idle the network connection
- * @nd: pointer to node structure to idle
- */
-static void dgrp_net_idle(struct nd_struct *nd)
-{
- struct ch_struct *ch;
- int i;
-
- nd->nd_tx_work = 1;
-
- nd->nd_state = NS_IDLE;
- nd->nd_flag = 0;
-
- for (i = nd->nd_seq_out; ; i = (i + 1) & SEQ_MASK) {
- if (!nd->nd_seq_wait[i]) {
- nd->nd_seq_wait[i] = 0;
- wake_up_interruptible(&nd->nd_seq_wque[i]);
- }
-
- if (i == nd->nd_seq_in)
- break;
- }
-
- nd->nd_seq_out = nd->nd_seq_in;
-
- nd->nd_unack = 0;
- nd->nd_remain = 0;
-
- nd->nd_tx_module = 0x10;
- nd->nd_rx_module = 0x00;
-
- for (i = 0, ch = nd->nd_chan; i < CHAN_MAX; i++, ch++) {
- ch->ch_state = CS_IDLE;
-
- ch->ch_otype = 0;
- ch->ch_otype_waiting = 0;
- }
-}
-
-/*
- * Increase the number of channels, waking up any
- * threads that might be waiting for the channels
- * to appear.
- */
-static void increase_channel_count(struct nd_struct *nd, int n)
-{
- struct ch_struct *ch;
- struct device *classp;
- char name[DEVICE_NAME_SIZE];
- int ret;
- u8 *buf;
- int i;
-
- for (i = nd->nd_chan_count; i < n; ++i) {
- ch = nd->nd_chan + i;
-
- /* FIXME: return a useful error instead! */
- buf = kmalloc(TBUF_MAX, GFP_KERNEL);
- if (!buf)
- return;
-
- if (ch->ch_tbuf)
- pr_info_ratelimited("%s - ch_tbuf was not NULL\n",
- __func__);
-
- ch->ch_tbuf = buf;
-
- buf = kmalloc(RBUF_MAX, GFP_KERNEL);
- if (!buf)
- return;
-
- if (ch->ch_rbuf)
- pr_info("%s - ch_rbuf was not NULL\n",
- __func__);
- ch->ch_rbuf = buf;
-
- classp = tty_port_register_device(&ch->port,
- nd->nd_serial_ttdriver, i,
- NULL);
-
- ch->ch_tun.un_sysfs = classp;
- snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
-
- dgrp_create_tty_sysfs(&ch->ch_tun, classp);
- ret = sysfs_create_link(&nd->nd_class_dev->kobj,
- &classp->kobj, name);
-
- /* NOTE: We don't support "cu" devices anymore,
- * so you will notice we don't register them
- * here anymore. */
- if (dgrp_register_prdevices) {
- classp = tty_register_device(nd->nd_xprint_ttdriver,
- i, NULL);
- ch->ch_pun.un_sysfs = classp;
- snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
-
- dgrp_create_tty_sysfs(&ch->ch_pun, classp);
- ret = sysfs_create_link(&nd->nd_class_dev->kobj,
- &classp->kobj, name);
- }
-
- nd->nd_chan_count = i + 1;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-}
-
-/*
- * Decrease the number of channels, and wake up any threads that might
- * be waiting on the channels that vanished.
- */
-static void decrease_channel_count(struct nd_struct *nd, int n)
-{
- struct ch_struct *ch;
- char name[DEVICE_NAME_SIZE];
- int i;
-
- for (i = nd->nd_chan_count - 1; i >= n; --i) {
- ch = nd->nd_chan + i;
-
- /*
- * Make any open ports inoperative.
- */
- ch->ch_state = CS_IDLE;
-
- ch->ch_otype = 0;
- ch->ch_otype_waiting = 0;
-
- /*
- * Only "HANGUP" if we care about carrier
- * transitions and we are already open.
- */
- if (ch->ch_open_count != 0) {
- ch->ch_flag |= CH_HANGUP;
- dgrp_carrier(ch);
- }
-
- /*
- * Unlike the CH_HANGUP flag above, use another
- * flag to indicate to the RealPort state machine
- * that this port has disappeared.
- */
- if (ch->ch_open_count != 0)
- ch->ch_flag |= CH_PORT_GONE;
-
- wake_up_interruptible(&ch->ch_flag_wait);
-
- nd->nd_chan_count = i;
-
- kfree(ch->ch_tbuf);
- ch->ch_tbuf = NULL;
-
- kfree(ch->ch_rbuf);
- ch->ch_rbuf = NULL;
-
- nd->nd_chan_count = i;
-
- dgrp_remove_tty_sysfs(ch->ch_tun.un_sysfs);
- snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
- sysfs_remove_link(&nd->nd_class_dev->kobj, name);
- tty_unregister_device(nd->nd_serial_ttdriver, i);
-
- /*
- * NOTE: We don't support "cu" devices anymore, so don't
- * unregister them here anymore.
- */
-
- if (dgrp_register_prdevices) {
- dgrp_remove_tty_sysfs(ch->ch_pun.un_sysfs);
- snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
- sysfs_remove_link(&nd->nd_class_dev->kobj, name);
- tty_unregister_device(nd->nd_xprint_ttdriver, i);
- }
- }
-}
-
-/**
- * dgrp_chan_count() -- Adjust the node channel count.
- * @nd: pointer to a node structure
- * @n: new value for channel count
- *
- * Adjusts the node channel count. If new ports have appeared, it tries
- * to signal those processes that might have been waiting for ports to
- * appear. If ports have disappeared it tries to signal those processes
- * that might be hung waiting for a response for the now non-existant port.
- */
-static void dgrp_chan_count(struct nd_struct *nd, int n)
-{
- if (n == nd->nd_chan_count)
- return;
-
- if (n > nd->nd_chan_count)
- increase_channel_count(nd, n);
-
- if (n < nd->nd_chan_count)
- decrease_channel_count(nd, n);
-}
-
-/**
- * dgrp_monitor() -- send data to the device monitor queue
- * @nd: pointer to a node structure
- * @buf: data to copy to the monitoring buffer
- * @len: number of bytes to transfer to the buffer
- *
- * Called by the net device routines to send data to the device
- * monitor queue. If the device monitor buffer is too full to
- * accept the data, it waits until the buffer is ready.
- */
-static void dgrp_monitor(struct nd_struct *nd, u8 *buf, int len)
-{
- int n;
- int r;
- int rtn;
-
- /*
- * Grab monitor lock.
- */
- down(&nd->nd_mon_semaphore);
-
- /*
- * Loop while data remains.
- */
- while ((len > 0) && (nd->nd_mon_buf)) {
- /*
- * Determine the amount of available space left in the
- * buffer. If there's none, wait until some appears.
- */
-
- n = (nd->nd_mon_out - nd->nd_mon_in - 1) & MON_MASK;
-
- if (!n) {
- nd->nd_mon_flag |= MON_WAIT_SPACE;
-
- up(&nd->nd_mon_semaphore);
-
- /*
- * Go to sleep waiting until the condition becomes true.
- */
- rtn = wait_event_interruptible(nd->nd_mon_wqueue,
- ((nd->nd_mon_flag & MON_WAIT_SPACE) == 0));
-
-/* FIXME: really ignore rtn? */
-
- /*
- * We can't exit here if we receive a signal, since
- * to do so would trash the debug stream.
- */
-
- down(&nd->nd_mon_semaphore);
-
- continue;
- }
-
- /*
- * Copy as much data as will fit.
- */
-
- if (n > len)
- n = len;
-
- r = MON_MAX - nd->nd_mon_in;
-
- if (r <= n) {
- memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, r);
-
- n -= r;
-
- nd->nd_mon_in = 0;
-
- buf += r;
- len -= r;
- }
-
- memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, n);
-
- nd->nd_mon_in += n;
-
- buf += n;
- len -= n;
-
- if (nd->nd_mon_in >= MON_MAX)
- pr_info_ratelimited("%s - nd_mon_in (%i) >= MON_MAX\n",
- __func__, nd->nd_mon_in);
-
- /*
- * Wakeup any thread waiting for data
- */
-
- if (nd->nd_mon_flag & MON_WAIT_DATA) {
- nd->nd_mon_flag &= ~MON_WAIT_DATA;
- wake_up_interruptible(&nd->nd_mon_wqueue);
- }
- }
-
- /*
- * Release the monitor lock.
- */
- up(&nd->nd_mon_semaphore);
-}
-
-/**
- * dgrp_encode_time() -- Encodes rpdump time into a 4-byte quantity.
- * @nd: pointer to a node structure
- * @buf: destination buffer
- *
- * Encodes "rpdump" time into a 4-byte quantity. Time is measured since
- * open.
- */
-static void dgrp_encode_time(struct nd_struct *nd, u8 *buf)
-{
- ulong t;
-
- /*
- * Convert time in HZ since open to time in milliseconds
- * since open.
- */
- t = jiffies - nd->nd_mon_lbolt;
- t = 1000 * (t / HZ) + 1000 * (t % HZ) / HZ;
-
- put_unaligned_be32((uint)(t & 0xffffffff), buf);
-}
-
-
-
-/**
- * dgrp_monitor_message() -- Builds a rpdump style message.
- * @nd: pointer to a node structure
- * @message: destination buffer
- */
-static void dgrp_monitor_message(struct nd_struct *nd, char *message)
-{
- u8 header[7];
- int n;
-
- header[0] = RPDUMP_MESSAGE;
-
- dgrp_encode_time(nd, header + 1);
-
- n = strlen(message);
-
- put_unaligned_be16(n, header + 5);
-
- dgrp_monitor(nd, header, sizeof(header));
- dgrp_monitor(nd, (u8 *) message, n);
-}
-
-
-
-/**
- * dgrp_monitor_reset() -- Note a reset in the monitoring buffer.
- * @nd: pointer to a node structure
- */
-static void dgrp_monitor_reset(struct nd_struct *nd)
-{
- u8 header[5];
-
- header[0] = RPDUMP_RESET;
-
- dgrp_encode_time(nd, header + 1);
-
- dgrp_monitor(nd, header, sizeof(header));
-}
-
-/**
- * dgrp_monitor_data() -- builds a monitor data packet
- * @nd: pointer to a node structure
- * @type: type of message to be logged
- * @buf: data to be logged
- * @size: number of bytes in the buffer
- */
-static void dgrp_monitor_data(struct nd_struct *nd, u8 type, u8 *buf, int size)
-{
- u8 header[7];
-
- header[0] = type;
-
- dgrp_encode_time(nd, header + 1);
-
- put_unaligned_be16(size, header + 5);
-
- dgrp_monitor(nd, header, sizeof(header));
- dgrp_monitor(nd, buf, size);
-}
-
-static int alloc_nd_buffers(struct nd_struct *nd)
-{
-
- nd->nd_iobuf = NULL;
- nd->nd_writebuf = NULL;
- nd->nd_inputbuf = NULL;
- nd->nd_inputflagbuf = NULL;
-
- /*
- * Allocate the network read/write buffer.
- */
- nd->nd_iobuf = kzalloc(UIO_MAX + 10, GFP_KERNEL);
- if (!nd->nd_iobuf)
- goto out_err;
-
- /*
- * Allocate a buffer for doing the copy from user space to
- * kernel space in the write routines.
- */
- nd->nd_writebuf = kzalloc(WRITEBUFLEN, GFP_KERNEL);
- if (!nd->nd_writebuf)
- goto out_err;
-
- /*
- * Allocate a buffer for doing the copy from kernel space to
- * tty buffer space in the read routines.
- */
- nd->nd_inputbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
- if (!nd->nd_inputbuf)
- goto out_err;
-
- /*
- * Allocate a buffer for doing the copy from kernel space to
- * tty buffer space in the read routines.
- */
- nd->nd_inputflagbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
- if (!nd->nd_inputflagbuf)
- goto out_err;
-
- return 0;
-
-out_err:
- kfree(nd->nd_iobuf);
- kfree(nd->nd_writebuf);
- kfree(nd->nd_inputbuf);
- kfree(nd->nd_inputflagbuf);
- return -ENOMEM;
-}
-
-/*
- * dgrp_net_open() -- Open the NET device for a particular PortServer
- */
-static int dgrp_net_open(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
- ulong lock_flags;
- int rtn;
-
- rtn = try_module_get(THIS_MODULE);
- if (!rtn)
- return -EAGAIN;
-
- if (!capable(CAP_SYS_ADMIN)) {
- rtn = -EPERM;
- goto done;
- }
-
- /*
- * Make sure that the "private_data" field hasn't already been used.
- */
- if (file->private_data) {
- rtn = -EINVAL;
- goto done;
- }
-
- /*
- * Get the node pointer, and fail if it doesn't exist.
- */
- nd = PDE_DATA(inode);
- if (!nd) {
- rtn = -ENXIO;
- goto done;
- }
-
- file->private_data = (void *) nd;
-
- /*
- * Grab the NET lock.
- */
- down(&nd->nd_net_semaphore);
-
- if (nd->nd_state != NS_CLOSED) {
- rtn = -EBUSY;
- goto unlock;
- }
-
- /*
- * Initialize the link speed parameters.
- */
-
- nd->nd_link.lk_fast_rate = UIO_MAX;
- nd->nd_link.lk_slow_rate = UIO_MAX;
-
- nd->nd_link.lk_fast_delay = 1000;
- nd->nd_link.lk_slow_delay = 1000;
-
- nd->nd_link.lk_header_size = 46;
-
-
- rtn = alloc_nd_buffers(nd);
- if (rtn)
- goto unlock;
-
- /*
- * The port is now open, so move it to the IDLE state
- */
- dgrp_net_idle(nd);
-
- nd->nd_tx_time = jiffies;
-
- /*
- * If the polling routing is not running, start it running here
- */
- spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
-
- if (!dgrp_poll_data.node_active_count) {
- dgrp_poll_data.node_active_count = 2;
- dgrp_poll_data.timer.expires = jiffies +
- dgrp_poll_tick * HZ / 1000;
- add_timer(&dgrp_poll_data.timer);
- }
-
- spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
-
- dgrp_monitor_message(nd, "Net Open");
-
-unlock:
- /*
- * Release the NET lock.
- */
- up(&nd->nd_net_semaphore);
-
-done:
- if (rtn)
- module_put(THIS_MODULE);
-
- return rtn;
-}
-
-/* dgrp_net_release() -- close the NET device for a particular PortServer */
-static int dgrp_net_release(struct inode *inode, struct file *file)
-{
- struct nd_struct *nd;
- ulong lock_flags;
-
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- goto done;
-
-/* TODO : historical locking placeholder */
-/*
- * In the HPUX version of the RealPort driver (which served as a basis
- * for this driver) this locking code was used. Saved if ever we need
- * to review the locking under Linux.
- */
-/* spinlock(&nd->nd_lock); */
-
-
- /*
- * Grab the NET lock.
- */
- down(&nd->nd_net_semaphore);
-
- /*
- * Before "closing" the internal connection, make sure all
- * ports are "idle".
- */
- dgrp_net_idle(nd);
-
- nd->nd_state = NS_CLOSED;
- nd->nd_flag = 0;
-
- /*
- * TODO ... must the wait queue be reset on close?
- * should any pending waiters be reset?
- * Let's decide to assert that the waitq is empty... and see
- * how soon we break.
- */
- if (waitqueue_active(&nd->nd_tx_waitq))
- pr_info("%s - expected waitqueue_active to be false\n",
- __func__);
-
- nd->nd_send = 0;
-
- kfree(nd->nd_iobuf);
- nd->nd_iobuf = NULL;
-
-/* TODO : historical locking placeholder */
-/*
- * In the HPUX version of the RealPort driver (which served as a basis
- * for this driver) this locking code was used. Saved if ever we need
- * to review the locking under Linux.
- */
-/* spinunlock( &nd->nd_lock ); */
-
-
- kfree(nd->nd_writebuf);
- nd->nd_writebuf = NULL;
-
- kfree(nd->nd_inputbuf);
- nd->nd_inputbuf = NULL;
-
- kfree(nd->nd_inputflagbuf);
- nd->nd_inputflagbuf = NULL;
-
-/* TODO : historical locking placeholder */
-/*
- * In the HPUX version of the RealPort driver (which served as a basis
- * for this driver) this locking code was used. Saved if ever we need
- * to review the locking under Linux.
- */
-/* spinlock(&nd->nd_lock); */
-
- /*
- * Set the active port count to zero.
- */
- dgrp_chan_count(nd, 0);
-
-/* TODO : historical locking placeholder */
-/*
- * In the HPUX version of the RealPort driver (which served as a basis
- * for this driver) this locking code was used. Saved if ever we need
- * to review the locking under Linux.
- */
-/* spinunlock(&nd->nd_lock); */
-
- /*
- * Release the NET lock.
- */
- up(&nd->nd_net_semaphore);
-
- /*
- * Cause the poller to stop scheduling itself if this is
- * the last active node.
- */
- spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
-
- if (dgrp_poll_data.node_active_count == 2) {
- del_timer(&dgrp_poll_data.timer);
- dgrp_poll_data.node_active_count = 0;
- }
-
- spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
-
- down(&nd->nd_net_semaphore);
-
- dgrp_monitor_message(nd, "Net Close");
-
- up(&nd->nd_net_semaphore);
-
-done:
- module_put(THIS_MODULE);
- file->private_data = NULL;
- return 0;
-}
-
-/* used in dgrp_send to setup command header */
-static inline u8 *set_cmd_header(u8 *b, u8 port, u8 cmd)
-{
- *b++ = 0xb0 + (port & 0x0f);
- *b++ = cmd;
- return b;
-}
-
-/**
- * dgrp_send() -- build a packet for transmission to the server
- * @nd: pointer to a node structure
- * @tmax: maximum bytes to transmit
- *
- * returns number of bytes sent
- */
-static int dgrp_send(struct nd_struct *nd, long tmax)
-{
- struct ch_struct *ch = nd->nd_chan;
- u8 *b;
- u8 *buf;
- u8 *mbuf;
- u8 port;
- int mod;
- long send;
- int maxport;
- long lastport = -1;
- ushort rwin;
- long in;
- ushort n;
- long t;
- long ttotal;
- long tchan;
- long tsend;
- ushort tsafe;
- long work;
- long send_sync;
- long wanted_sync_port = -1;
- ushort tdata[CHAN_MAX];
- long used_buffer;
-
- mbuf = nd->nd_iobuf + UIO_BASE;
- buf = b = mbuf;
-
- send_sync = nd->nd_link.lk_slow_rate < UIO_MAX;
-
- ttotal = 0;
- tchan = 0;
-
- memset(tdata, 0, sizeof(tdata));
-
-
- /*
- * If there are any outstanding requests to be serviced,
- * service them here.
- */
- if (nd->nd_send & NR_PASSWORD) {
-
- /*
- * Send Password response.
- */
-
- b[0] = 0xfc;
- b[1] = 0x20;
- put_unaligned_be16(strlen(nd->password), b + 2);
- b += 4;
- b += strlen(nd->password);
- nd->nd_send &= ~(NR_PASSWORD);
- }
-
-
- /*
- * Loop over all modules to generate commands, and determine
- * the amount of data queued for transmit.
- */
-
- for (mod = 0, port = 0; port < nd->nd_chan_count; mod++) {
- /*
- * If this is not the current module, enter a module select
- * code in the buffer.
- */
-
- if (mod != nd->nd_tx_module)
- mbuf = ++b;
-
- /*
- * Loop to process one module.
- */
-
- maxport = port + 16;
-
- if (maxport > nd->nd_chan_count)
- maxport = nd->nd_chan_count;
-
- for (; port < maxport; port++, ch++) {
- /*
- * Switch based on channel state.
- */
-
- switch (ch->ch_state) {
- /*
- * Send requests when the port is closed, and there
- * are no Open, Close or Cancel requests expected.
- */
-
- case CS_IDLE:
- /*
- * Wait until any open error code
- * has been delivered to all
- * associated ports.
- */
-
- if (ch->ch_open_error) {
- if (ch->ch_wait_count[ch->ch_otype]) {
- work = 1;
- break;
- }
-
- ch->ch_open_error = 0;
- }
-
- /*
- * Wait until the channel HANGUP flag is reset
- * before sending the first open. We can only
- * get to this state after a server disconnect.
- */
-
- if ((ch->ch_flag & CH_HANGUP) != 0)
- break;
-
- /*
- * If recovering from a TCP disconnect, or if
- * there is an immediate open pending, send an
- * Immediate Open request.
- */
- if ((ch->ch_flag & CH_PORT_GONE) ||
- ch->ch_wait_count[OTYPE_IMMEDIATE] != 0) {
- b = set_cmd_header(b, port, 10);
- *b++ = 0;
-
- ch->ch_state = CS_WAIT_OPEN;
- ch->ch_otype = OTYPE_IMMEDIATE;
- break;
- }
-
- /*
- * If there is no Persistent or Incoming Open on the wait
- * list in the server, and a thread is waiting for a
- * Persistent or Incoming Open, send a Persistent or Incoming
- * Open Request.
- */
- if (ch->ch_otype_waiting == 0) {
- if (ch->ch_wait_count[OTYPE_PERSISTENT] != 0) {
- b = set_cmd_header(b, port, 10);
- *b++ = 1;
-
- ch->ch_state = CS_WAIT_OPEN;
- ch->ch_otype = OTYPE_PERSISTENT;
- } else if (ch->ch_wait_count[OTYPE_INCOMING] != 0) {
- b = set_cmd_header(b, port, 10);
- *b++ = 2;
-
- ch->ch_state = CS_WAIT_OPEN;
- ch->ch_otype = OTYPE_INCOMING;
- }
- break;
- }
-
- /*
- * If a Persistent or Incoming Open is pending in
- * the server, but there is no longer an open
- * thread waiting for it, cancel the request.
- */
-
- if (ch->ch_wait_count[ch->ch_otype_waiting] == 0) {
- b = set_cmd_header(b, port, 10);
- *b++ = 4;
-
- ch->ch_state = CS_WAIT_CANCEL;
- ch->ch_otype = ch->ch_otype_waiting;
- }
- break;
-
- /*
- * Send port parameter queries.
- */
- case CS_SEND_QUERY:
- /*
- * Clear out all FEP state that might remain
- * from the last connection.
- */
-
- ch->ch_flag |= CH_PARAM;
-
- ch->ch_flag &= ~CH_RX_FLUSH;
-
- ch->ch_expect = 0;
-
- ch->ch_s_tin = 0;
- ch->ch_s_tpos = 0;
- ch->ch_s_tsize = 0;
- ch->ch_s_treq = 0;
- ch->ch_s_elast = 0;
-
- ch->ch_s_rin = 0;
- ch->ch_s_rwin = 0;
- ch->ch_s_rsize = 0;
-
- ch->ch_s_tmax = 0;
- ch->ch_s_ttime = 0;
- ch->ch_s_rmax = 0;
- ch->ch_s_rtime = 0;
- ch->ch_s_rlow = 0;
- ch->ch_s_rhigh = 0;
-
- ch->ch_s_brate = 0;
- ch->ch_s_iflag = 0;
- ch->ch_s_cflag = 0;
- ch->ch_s_oflag = 0;
- ch->ch_s_xflag = 0;
-
- ch->ch_s_mout = 0;
- ch->ch_s_mflow = 0;
- ch->ch_s_mctrl = 0;
- ch->ch_s_xon = 0;
- ch->ch_s_xoff = 0;
- ch->ch_s_lnext = 0;
- ch->ch_s_xxon = 0;
- ch->ch_s_xxoff = 0;
-
- /* Send Sequence Request */
- b = set_cmd_header(b, port, 14);
-
- /* Configure Event Conditions Packet */
- b = set_cmd_header(b, port, 42);
- put_unaligned_be16(0x02c0, b);
- b += 2;
- *b++ = (DM_DTR | DM_RTS | DM_CTS |
- DM_DSR | DM_RI | DM_CD);
-
- /* Send Status Request */
- b = set_cmd_header(b, port, 16);
-
- /* Send Buffer Request */
- b = set_cmd_header(b, port, 20);
-
- /* Send Port Capability Request */
- b = set_cmd_header(b, port, 22);
-
- ch->ch_expect = (RR_SEQUENCE |
- RR_STATUS |
- RR_BUFFER |
- RR_CAPABILITY);
-
- ch->ch_state = CS_WAIT_QUERY;
-
- /* Raise modem signals */
- b = set_cmd_header(b, port, 44);
-
- if (ch->ch_flag & CH_PORT_GONE)
- ch->ch_s_mout = ch->ch_mout;
- else
- ch->ch_s_mout = ch->ch_mout = DM_DTR | DM_RTS;
-
- *b++ = ch->ch_mout;
- *b++ = ch->ch_s_mflow = 0;
- *b++ = ch->ch_s_mctrl = ch->ch_mctrl = 0;
-
- if (ch->ch_flag & CH_PORT_GONE)
- ch->ch_flag &= ~CH_PORT_GONE;
-
- break;
-
- /*
- * Handle normal open and ready mode.
- */
-
- case CS_READY:
-
- /*
- * If the port is not open, and there are no
- * no longer any ports requesting an open,
- * then close the port.
- */
-
- if (ch->ch_open_count == 0 &&
- ch->ch_wait_count[ch->ch_otype] == 0) {
- goto send_close;
- }
-
- /*
- * Process waiting input.
- *
- * If there is no one to read it, discard the data.
- *
- * Otherwise if we are not in fastcook mode, or if there is a
- * fastcook thread waiting for data, send the data to the
- * line discipline.
- */
- if (ch->ch_rin != ch->ch_rout) {
- if (ch->ch_tun.un_open_count == 0 ||
- (ch->ch_tun.un_flag & UN_CLOSING) ||
- (ch->ch_cflag & CF_CREAD) == 0) {
- ch->ch_rout = ch->ch_rin;
- } else if ((ch->ch_flag & CH_FAST_READ) == 0 ||
- ch->ch_inwait != 0) {
- dgrp_input(ch);
-
- if (ch->ch_rin != ch->ch_rout)
- work = 1;
- }
- }
-
- /*
- * Handle receive flush, and changes to
- * server port parameters.
- */
-
- if (ch->ch_flag & (CH_RX_FLUSH | CH_PARAM)) {
- /*
- * If we are in receive flush mode,
- * and enough data has gone by, reset
- * receive flush mode.
- */
- if (ch->ch_flag & CH_RX_FLUSH) {
- if (((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >
- ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK))
- ch->ch_flag &= ~CH_RX_FLUSH;
- else
- work = 1;
- }
-
- /*
- * Send TMAX, TTIME.
- */
-
- if (ch->ch_s_tmax != ch->ch_tmax ||
- ch->ch_s_ttime != ch->ch_ttime) {
- b = set_cmd_header(b, port, 48);
-
- ch->ch_s_tmax = ch->ch_tmax;
- ch->ch_s_ttime = ch->ch_ttime;
-
- put_unaligned_be16(ch->ch_s_tmax,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_ttime,
- b);
- b += 2;
- }
-
- /*
- * Send RLOW, RHIGH.
- */
-
- if (ch->ch_s_rlow != ch->ch_rlow ||
- ch->ch_s_rhigh != ch->ch_rhigh) {
- b = set_cmd_header(b, port, 45);
-
- ch->ch_s_rlow = ch->ch_rlow;
- ch->ch_s_rhigh = ch->ch_rhigh;
-
- put_unaligned_be16(ch->ch_s_rlow,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_rhigh,
- b);
- b += 2;
- }
-
- /*
- * Send BRATE, CFLAG, IFLAG,
- * OFLAG, XFLAG.
- */
-
- if (ch->ch_s_brate != ch->ch_brate ||
- ch->ch_s_cflag != ch->ch_cflag ||
- ch->ch_s_iflag != ch->ch_iflag ||
- ch->ch_s_oflag != ch->ch_oflag ||
- ch->ch_s_xflag != ch->ch_xflag) {
- b = set_cmd_header(b, port, 40);
-
- ch->ch_s_brate = ch->ch_brate;
- ch->ch_s_cflag = ch->ch_cflag;
- ch->ch_s_iflag = ch->ch_iflag;
- ch->ch_s_oflag = ch->ch_oflag;
- ch->ch_s_xflag = ch->ch_xflag;
-
- put_unaligned_be16(ch->ch_s_brate,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_cflag,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_iflag,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_oflag,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_xflag,
- b);
- b += 2;
- }
-
- /*
- * Send MOUT, MFLOW, MCTRL.
- */
-
- if (ch->ch_s_mout != ch->ch_mout ||
- ch->ch_s_mflow != ch->ch_mflow ||
- ch->ch_s_mctrl != ch->ch_mctrl) {
- b = set_cmd_header(b, port, 44);
-
- *b++ = ch->ch_s_mout = ch->ch_mout;
- *b++ = ch->ch_s_mflow = ch->ch_mflow;
- *b++ = ch->ch_s_mctrl = ch->ch_mctrl;
- }
-
- /*
- * Send Flow control characters.
- */
-
- if (ch->ch_s_xon != ch->ch_xon ||
- ch->ch_s_xoff != ch->ch_xoff ||
- ch->ch_s_lnext != ch->ch_lnext ||
- ch->ch_s_xxon != ch->ch_xxon ||
- ch->ch_s_xxoff != ch->ch_xxoff) {
- b = set_cmd_header(b, port, 46);
-
- *b++ = ch->ch_s_xon = ch->ch_xon;
- *b++ = ch->ch_s_xoff = ch->ch_xoff;
- *b++ = ch->ch_s_lnext = ch->ch_lnext;
- *b++ = ch->ch_s_xxon = ch->ch_xxon;
- *b++ = ch->ch_s_xxoff = ch->ch_xxoff;
- }
-
- /*
- * Send RMAX, RTIME.
- */
-
- if (ch->ch_s_rmax != ch->ch_rmax ||
- ch->ch_s_rtime != ch->ch_rtime) {
- b = set_cmd_header(b, port, 47);
-
- ch->ch_s_rmax = ch->ch_rmax;
- ch->ch_s_rtime = ch->ch_rtime;
-
- put_unaligned_be16(ch->ch_s_rmax,
- b);
- b += 2;
-
- put_unaligned_be16(ch->ch_s_rtime,
- b);
- b += 2;
- }
-
- ch->ch_flag &= ~CH_PARAM;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
-
- /*
- * Handle action commands.
- */
-
- if (ch->ch_send != 0) {
- /* int send = ch->ch_send & ~ch->ch_expect; */
- send = ch->ch_send & ~ch->ch_expect;
-
- /* Send character immediate */
- if ((send & RR_TX_ICHAR) != 0) {
- b = set_cmd_header(b, port, 60);
-
- *b++ = ch->ch_xon;
- ch->ch_expect |= RR_TX_ICHAR;
- }
-
- /* BREAK request */
- if ((send & RR_TX_BREAK) != 0) {
- if (ch->ch_break_time != 0) {
- b = set_cmd_header(b, port, 61);
- put_unaligned_be16(ch->ch_break_time,
- b);
- b += 2;
-
- ch->ch_expect |= RR_TX_BREAK;
- ch->ch_break_time = 0;
- } else {
- ch->ch_send &= ~RR_TX_BREAK;
- ch->ch_flag &= ~CH_TX_BREAK;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
- }
-
- /*
- * Flush input/output buffers.
- */
-
- if ((send & (RR_RX_FLUSH | RR_TX_FLUSH)) != 0) {
- b = set_cmd_header(b, port, 62);
-
- *b++ = ((send & RR_TX_FLUSH) == 0 ? 1 :
- (send & RR_RX_FLUSH) == 0 ? 2 : 3);
-
- if (send & RR_RX_FLUSH) {
- ch->ch_flush_seq = nd->nd_seq_in;
- ch->ch_flag |= CH_RX_FLUSH;
- work = 1;
- send_sync = 1;
- wanted_sync_port = port;
- }
-
- ch->ch_send &= ~(RR_RX_FLUSH | RR_TX_FLUSH);
- }
-
- /* Pause input/output */
- if ((send & (RR_RX_STOP | RR_TX_STOP)) != 0) {
- b = set_cmd_header(b, port, 63);
- *b = 0;
-
- if ((send & RR_TX_STOP) != 0)
- *b |= EV_OPU;
-
- if ((send & RR_RX_STOP) != 0)
- *b |= EV_IPU;
-
- b++;
-
- ch->ch_send &= ~(RR_RX_STOP | RR_TX_STOP);
- }
-
- /* Start input/output */
- if ((send & (RR_RX_START | RR_TX_START)) != 0) {
- b = set_cmd_header(b, port, 64);
- *b = 0;
-
- if ((send & RR_TX_START) != 0)
- *b |= EV_OPU | EV_OPS | EV_OPX;
-
- if ((send & RR_RX_START) != 0)
- *b |= EV_IPU | EV_IPS;
-
- b++;
-
- ch->ch_send &= ~(RR_RX_START | RR_TX_START);
- }
- }
-
-
- /*
- * Send a window sequence to acknowledge received data.
- */
-
- rwin = (ch->ch_s_rin +
- ((ch->ch_rout - ch->ch_rin - 1) & RBUF_MASK));
-
- n = (rwin - ch->ch_s_rwin) & 0xffff;
-
- if (n >= RBUF_MAX / 4) {
- b[0] = 0xa0 + (port & 0xf);
- ch->ch_s_rwin = rwin;
- put_unaligned_be16(rwin, b + 1);
- b += 3;
- }
-
- /*
- * If the terminal is waiting on LOW
- * water or EMPTY, and the condition
- * is now satisfied, call the line
- * discipline to put more data in the
- * buffer.
- */
-
- n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
-
- if ((ch->ch_tun.un_flag & (UN_EMPTY|UN_LOW)) != 0) {
- if ((ch->ch_tun.un_flag & UN_LOW) != 0 ?
- (n <= TBUF_LOW) :
- (n == 0 && ch->ch_s_tpos == ch->ch_s_tin)) {
- ch->ch_tun.un_flag &= ~(UN_EMPTY|UN_LOW);
-
- if (waitqueue_active(&((ch->ch_tun.un_tty)->write_wait)))
- wake_up_interruptible(&((ch->ch_tun.un_tty)->write_wait));
- tty_wakeup(ch->ch_tun.un_tty);
- n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
- }
- }
-
- /*
- * If the printer is waiting on LOW
- * water, TIME, EMPTY or PWAIT, and is
- * now ready to put more data in the
- * buffer, call the line discipline to
- * do the job.
- */
-
- /* FIXME: jiffies - ch->ch_waketime can never
- be < 0. Someone needs to work out what is
- actually intended here */
- if (ch->ch_pun.un_open_count &&
- (ch->ch_pun.un_flag &
- (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) {
-
- if ((ch->ch_pun.un_flag & UN_LOW) != 0 ?
- (n <= TBUF_LOW) :
- (ch->ch_pun.un_flag & UN_TIME) != 0 ?
- time_is_before_jiffies(ch->ch_waketime) :
- (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) &&
- ((ch->ch_pun.un_flag & UN_EMPTY) != 0 ||
- ((ch->ch_tun.un_open_count &&
- ch->ch_tun.un_tty->ops->chars_in_buffer) ?
- (ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) == 0
- : 1
- )
- )) {
- ch->ch_pun.un_flag &= ~(UN_EMPTY | UN_TIME | UN_LOW | UN_PWAIT);
-
- if (waitqueue_active(&((ch->ch_pun.un_tty)->write_wait)))
- wake_up_interruptible(&((ch->ch_pun.un_tty)->write_wait));
- tty_wakeup(ch->ch_pun.un_tty);
- n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
-
- } else if ((ch->ch_pun.un_flag & UN_TIME) != 0) {
- work = 1;
- }
- }
-
-
- /*
- * Determine the max number of bytes
- * this port can send, including
- * packet header overhead.
- */
-
- t = ((ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff);
-
- if (n > t)
- n = t;
-
- if (n != 0) {
- n += (n <= 8 ? 1 : n <= 255 ? 2 : 3);
-
- tdata[tchan++] = n;
- ttotal += n;
- }
- break;
-
- /*
- * Close the port.
- */
-
-send_close:
- case CS_SEND_CLOSE:
- b = set_cmd_header(b, port, 10);
- if (ch->ch_otype == OTYPE_IMMEDIATE)
- *b++ = 3;
- else
- *b++ = 4;
-
- ch->ch_state = CS_WAIT_CLOSE;
- break;
-
- /*
- * Wait for a previous server request.
- */
-
- case CS_WAIT_OPEN:
- case CS_WAIT_CANCEL:
- case CS_WAIT_FAIL:
- case CS_WAIT_QUERY:
- case CS_WAIT_CLOSE:
- break;
-
- default:
- pr_info("%s - unexpected channel state (%i)\n",
- __func__, ch->ch_state);
- }
- }
-
- /*
- * If a module select code is needed, drop one in. If space
- * was reserved for one, but none is needed, recover the space.
- */
-
- if (mod != nd->nd_tx_module) {
- if (b != mbuf) {
- mbuf[-1] = 0xf0 | mod;
- nd->nd_tx_module = mod;
- } else {
- b--;
- }
- }
- }
-
- /*
- * Adjust "tmax" so that under worst case conditions we do
- * not overflow either the daemon buffer or the internal
- * buffer in the loop that follows. Leave a safe area
- * of 64 bytes so we start getting asserts before we start
- * losing data or clobbering memory.
- */
-
- n = UIO_MAX - UIO_BASE;
-
- if (tmax > n)
- tmax = n;
-
- tmax -= 64;
-
- tsafe = tmax;
-
- /*
- * Allocate space for 5 Module Selects, 1 Sequence Request,
- * and 1 Set TREQ for each active channel.
- */
-
- tmax -= 5 + 3 + 4 * nd->nd_chan_count;
-
- /*
- * Further reduce "tmax" to the available transmit credit.
- * Note that this is a soft constraint; The transmit credit
- * can go negative for a time and then recover.
- */
-
- n = nd->nd_tx_deposit - nd->nd_tx_charge - nd->nd_link.lk_header_size;
-
- if (tmax > n)
- tmax = n;
-
- /*
- * Finally reduce tmax by the number of bytes already in
- * the buffer.
- */
-
- tmax -= b - buf;
-
- /*
- * Suspend data transmit unless every ready channel can send
- * at least 1 character.
- */
- if (tmax < 2 * nd->nd_chan_count) {
- tsend = 1;
-
- } else if (tchan > 1 && ttotal > tmax) {
-
- /*
- * If transmit is limited by the credit budget, find the
- * largest number of characters we can send without driving
- * the credit negative.
- */
-
- long tm = tmax;
- int tc = tchan;
- int try;
-
- tsend = tm / tc;
-
- for (try = 0; try < 3; try++) {
- int i;
- int c = 0;
-
- for (i = 0; i < tc; i++) {
- if (tsend < tdata[i])
- tdata[c++] = tdata[i];
- else
- tm -= tdata[i];
- }
-
- if (c == tc)
- break;
-
- tsend = tm / c;
-
- if (c == 1)
- break;
-
- tc = c;
- }
-
- tsend = tm / nd->nd_chan_count;
-
- if (tsend < 2)
- tsend = 1;
-
- } else {
- /*
- * If no budgetary constraints, or only one channel ready
- * to send, set the character limit to the remaining
- * buffer size.
- */
-
- tsend = tmax;
- }
-
- tsend -= (tsend <= 9) ? 1 : (tsend <= 257) ? 2 : 3;
-
- /*
- * Loop over all channels, sending queued data.
- */
-
- port = 0;
- ch = nd->nd_chan;
- used_buffer = tmax;
-
- for (mod = 0; port < nd->nd_chan_count; mod++) {
- /*
- * If this is not the current module, enter a module select
- * code in the buffer.
- */
-
- if (mod != nd->nd_tx_module)
- mbuf = ++b;
-
- /*
- * Loop to process one module.
- */
-
- maxport = port + 16;
-
- if (maxport > nd->nd_chan_count)
- maxport = nd->nd_chan_count;
-
- for (; port < maxport; port++, ch++) {
- if (ch->ch_state != CS_READY)
- continue;
-
- lastport = port;
-
- n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
-
- /*
- * If there is data that can be sent, send it.
- */
-
- if (n != 0 && used_buffer > 0) {
- t = (ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff;
-
- if (n > t)
- n = t;
-
- if (n > tsend) {
- work = 1;
- n = tsend;
- }
-
- if (n > used_buffer) {
- work = 1;
- n = used_buffer;
- }
-
- if (n <= 0)
- continue;
-
- /*
- * Create the correct size transmit header,
- * depending on the amount of data to transmit.
- */
-
- if (n <= 8) {
-
- b[0] = ((n - 1) << 4) + (port & 0xf);
- b += 1;
-
- } else if (n <= 255) {
-
- b[0] = 0x80 + (port & 0xf);
- b[1] = n;
- b += 2;
-
- } else {
-
- b[0] = 0x90 + (port & 0xf);
- put_unaligned_be16(n, b + 1);
- b += 3;
- }
-
- ch->ch_s_tin = (ch->ch_s_tin + n) & 0xffff;
-
- /*
- * Copy transmit data to the packet.
- */
-
- t = TBUF_MAX - ch->ch_tout;
-
- if (n >= t) {
- memcpy(b, ch->ch_tbuf + ch->ch_tout, t);
- b += t;
- n -= t;
- used_buffer -= t;
- ch->ch_tout = 0;
- }
-
- memcpy(b, ch->ch_tbuf + ch->ch_tout, n);
- b += n;
- used_buffer -= n;
- ch->ch_tout += n;
- n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
- }
-
- /*
- * Wake any terminal unit process waiting in the
- * dgrp_write routine for low water.
- */
-
- if (n > TBUF_LOW)
- continue;
-
- if ((ch->ch_flag & CH_LOW) != 0) {
- ch->ch_flag &= ~CH_LOW;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
- /* selwakeup tty_sel */
- if (ch->ch_tun.un_open_count) {
- struct tty_struct *tty = (ch->ch_tun.un_tty);
-
- if (waitqueue_active(&tty->write_wait))
- wake_up_interruptible(&tty->write_wait);
-
- tty_wakeup(tty);
- }
-
- if (ch->ch_pun.un_open_count) {
- struct tty_struct *tty = (ch->ch_pun.un_tty);
-
- if (waitqueue_active(&tty->write_wait))
- wake_up_interruptible(&tty->write_wait);
-
- tty_wakeup(tty);
- }
-
- /*
- * Do EMPTY processing.
- */
-
- if (n != 0)
- continue;
-
- if ((ch->ch_flag & (CH_EMPTY | CH_DRAIN)) != 0 ||
- (ch->ch_pun.un_flag & UN_EMPTY) != 0) {
- /*
- * If there is still data in the server, ask the server
- * to notify us when its all gone.
- */
-
- if (ch->ch_s_treq != ch->ch_s_tin) {
- b = set_cmd_header(b, port, 43);
-
- ch->ch_s_treq = ch->ch_s_tin;
- put_unaligned_be16(ch->ch_s_treq,
- b);
- b += 2;
- }
-
- /*
- * If there is a thread waiting for buffer empty,
- * and we are truly empty, wake the thread.
- */
-
- else if ((ch->ch_flag & CH_EMPTY) != 0 &&
- (ch->ch_send & RR_TX_BREAK) == 0) {
- ch->ch_flag &= ~CH_EMPTY;
-
- wake_up_interruptible(&ch->ch_flag_wait);
- }
- }
- }
-
- /*
- * If a module select code is needed, drop one in. If space
- * was reserved for one, but none is needed, recover the space.
- */
-
- if (mod != nd->nd_tx_module) {
- if (b != mbuf) {
- mbuf[-1] = 0xf0 | mod;
- nd->nd_tx_module = mod;
- } else {
- b--;
- }
- }
- }
-
- /*
- * Send a synchronization sequence associated with the last open
- * channel that sent data, and remember the time when the data was
- * sent.
- */
-
- in = nd->nd_seq_in;
-
- if ((send_sync || nd->nd_seq_wait[in] != 0) && lastport >= 0) {
- u8 *bb = b;
-
- /*
- * Attempt the use the port that really wanted the sync.
- * This gets around a race condition where the "lastport" is in
- * the middle of the close() routine, and by the time we
- * send this command, it will have already acked the close, and
- * thus not send the sync response.
- */
- if (wanted_sync_port >= 0)
- lastport = wanted_sync_port;
- /*
- * Set a flag just in case the port is in the middle of a close,
- * it will not be permitted to actually close until we get an
- * sync response, and clear the flag there.
- */
- ch = nd->nd_chan + lastport;
- ch->ch_flag |= CH_WAITING_SYNC;
-
- mod = lastport >> 4;
-
- if (mod != nd->nd_tx_module) {
- bb[0] = 0xf0 + mod;
- bb += 1;
-
- nd->nd_tx_module = mod;
- }
-
- bb = set_cmd_header(bb, lastport, 12);
- *bb++ = in;
-
- nd->nd_seq_size[in] = bb - buf;
- nd->nd_seq_time[in] = jiffies;
-
- if (++in >= SEQ_MAX)
- in = 0;
-
- if (in != nd->nd_seq_out) {
- b = bb;
- nd->nd_seq_in = in;
- nd->nd_unack += b - buf;
- }
- }
-
- /*
- * If there are no open ports, a sync cannot be sent.
- * There is nothing left to wait for anyway, so wake any
- * thread waiting for an acknowledgement.
- */
-
- else if (nd->nd_seq_wait[in] != 0) {
- nd->nd_seq_wait[in] = 0;
-
- wake_up_interruptible(&nd->nd_seq_wque[in]);
- }
-
- /*
- * If there is no traffic for an interval of IDLE_MAX, then
- * send a single byte packet.
- */
-
- if (b != buf) {
- nd->nd_tx_time = jiffies;
- } else if ((ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX) {
- *b++ = 0xf0 | nd->nd_tx_module;
- nd->nd_tx_time = jiffies;
- }
-
- n = b - buf;
-
- if (n >= tsafe)
- pr_info("%s - n(%i) >= tsafe(%i)\n",
- __func__, n, tsafe);
-
- if (tsend < 0)
- dgrp_dump(buf, n);
-
- nd->nd_tx_work = work;
-
- return n;
-}
-
-/*
- * dgrp_net_read()
- * Data to be sent TO the PortServer from the "async." half of the driver.
- */
-static ssize_t dgrp_net_read(struct file *file, char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct nd_struct *nd;
- long n;
- u8 *local_buf;
- u8 *b;
- ssize_t rtn;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- return -ENXIO;
-
- if (count < UIO_MIN)
- return -EINVAL;
-
- /*
- * Only one read/write operation may be in progress at
- * any given time.
- */
-
- /*
- * Grab the NET lock.
- */
- down(&nd->nd_net_semaphore);
-
- nd->nd_read_count++;
-
- nd->nd_tx_ready = 0;
-
- /*
- * Determine the effective size of the buffer.
- */
-
- if (nd->nd_remain > UIO_BASE)
- pr_info_ratelimited("%s - nd_remain(%i) > UIO_BASE\n",
- __func__, nd->nd_remain);
-
- b = local_buf = nd->nd_iobuf + UIO_BASE;
-
- /*
- * Generate data according to the node state.
- */
-
- switch (nd->nd_state) {
- /*
- * Initialize the connection.
- */
-
- case NS_IDLE:
- if (nd->nd_mon_buf)
- dgrp_monitor_reset(nd);
-
- /*
- * Request a Product ID Packet.
- */
-
- b[0] = 0xfb;
- b[1] = 0x01;
- b += 2;
-
- nd->nd_expect |= NR_IDENT;
-
- /*
- * Request a Server Capability ID Response.
- */
-
- b[0] = 0xfb;
- b[1] = 0x02;
- b += 2;
-
- nd->nd_expect |= NR_CAPABILITY;
-
- /*
- * Request a Server VPD Response.
- */
-
- b[0] = 0xfb;
- b[1] = 0x18;
- b += 2;
-
- nd->nd_expect |= NR_VPD;
-
- nd->nd_state = NS_WAIT_QUERY;
- break;
-
- /*
- * We do serious communication with the server only in
- * the READY state.
- */
-
- case NS_READY:
- b = dgrp_send(nd, count) + local_buf;
- break;
-
- /*
- * Send off an error after receiving a bogus message
- * from the server.
- */
-
- case NS_SEND_ERROR:
- n = strlen(nd->nd_error);
-
- b[0] = 0xff;
- b[1] = n;
- memcpy(b + 2, nd->nd_error, n);
- b += 2 + n;
-
- dgrp_net_idle(nd);
- /*
- * Set the active port count to zero.
- */
- dgrp_chan_count(nd, 0);
- break;
-
- default:
- break;
- }
-
- n = b - local_buf;
-
- if (n != 0) {
- nd->nd_send_count++;
-
- nd->nd_tx_byte += n + nd->nd_link.lk_header_size;
- nd->nd_tx_charge += n + nd->nd_link.lk_header_size;
- }
-
- rtn = copy_to_user((void __user *)buf, local_buf, n);
- if (rtn) {
- rtn = -EFAULT;
- goto done;
- }
-
- *ppos += n;
-
- rtn = n;
-
- if (nd->nd_mon_buf)
- dgrp_monitor_data(nd, RPDUMP_CLIENT, local_buf, n);
-
- /*
- * Release the NET lock.
- */
-done:
- up(&nd->nd_net_semaphore);
-
- return rtn;
-}
-
-/**
- * dgrp_receive() -- decode data packets received from the remote PortServer.
- * @nd: pointer to a node structure
- */
-static void dgrp_receive(struct nd_struct *nd)
-{
- struct ch_struct *ch;
- u8 *buf;
- u8 *b;
- u8 *dbuf;
- char *error;
- long port;
- long dlen;
- long plen;
- long remain;
- long n;
- long mlast;
- long elast;
- long mstat;
- long estat;
-
- char ID[3];
-
- nd->nd_tx_time = jiffies;
-
- ID_TO_CHAR(nd->nd_ID, ID);
-
- b = buf = nd->nd_iobuf;
- remain = nd->nd_remain;
-
- /*
- * Loop to process Realport protocol packets.
- */
-
- while (remain > 0) {
- int n0 = b[0] >> 4;
- int n1 = b[0] & 0x0f;
-
- if (n0 <= 12) {
- port = (nd->nd_rx_module << 4) + n1;
-
- if (port >= nd->nd_chan_count) {
- error = "Improper Port Number";
- goto prot_error;
- }
-
- ch = nd->nd_chan + port;
- } else {
- port = -1;
- ch = NULL;
- }
-
- /*
- * Process by major packet type.
- */
-
- switch (n0) {
-
- /*
- * Process 1-byte header data packet.
- */
-
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- dlen = n0 + 1;
- plen = dlen + 1;
-
- dbuf = b + 1;
- goto data;
-
- /*
- * Process 2-byte header data packet.
- */
-
- case 8:
- if (remain < 3)
- goto done;
-
- dlen = b[1];
- plen = dlen + 2;
-
- dbuf = b + 2;
- goto data;
-
- /*
- * Process 3-byte header data packet.
- */
-
- case 9:
- if (remain < 4)
- goto done;
-
- dlen = get_unaligned_be16(b + 1);
- plen = dlen + 3;
-
- dbuf = b + 3;
-
- /*
- * Common packet handling code.
- */
-
-data:
- nd->nd_tx_work = 1;
-
- /*
- * Otherwise data should appear only when we are
- * in the CS_READY state.
- */
-
- if (ch->ch_state < CS_READY) {
- error = "Data received before RWIN established";
- goto prot_error;
- }
-
- /*
- * Assure that the data received is within the
- * allowable window.
- */
-
- n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;
-
- if (dlen > n) {
- error = "Receive data overrun";
- goto prot_error;
- }
-
- /*
- * If we received 3 or less characters,
- * assume it is a human typing, and set RTIME
- * to 10 milliseconds.
- *
- * If we receive 10 or more characters,
- * assume its not a human typing, and set RTIME
- * to 100 milliseconds.
- */
-
- if (ch->ch_edelay != DGRP_RTIME) {
- if (ch->ch_rtime != ch->ch_edelay) {
- ch->ch_rtime = ch->ch_edelay;
- ch->ch_flag |= CH_PARAM;
- }
- } else if (dlen <= 3) {
- if (ch->ch_rtime != 10) {
- ch->ch_rtime = 10;
- ch->ch_flag |= CH_PARAM;
- }
- } else {
- if (ch->ch_rtime != DGRP_RTIME) {
- ch->ch_rtime = DGRP_RTIME;
- ch->ch_flag |= CH_PARAM;
- }
- }
-
- /*
- * If a portion of the packet is outside the
- * buffer, shorten the effective length of the
- * data packet to be the amount of data received.
- */
-
- if (remain < plen)
- dlen -= plen - remain;
-
- /*
- * Detect if receive flush is now complete.
- */
-
- if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
- ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
- ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
- ch->ch_flag &= ~CH_RX_FLUSH;
- }
-
- /*
- * If we are ready to receive, move the data into
- * the receive buffer.
- */
-
- ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;
-
- if (ch->ch_state == CS_READY &&
- (ch->ch_tun.un_open_count != 0) &&
- (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
- (ch->ch_cflag & CF_CREAD) != 0 &&
- (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
- (ch->ch_send & RR_RX_FLUSH) == 0) {
-
- if (ch->ch_rin + dlen >= RBUF_MAX) {
- n = RBUF_MAX - ch->ch_rin;
-
- memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);
-
- ch->ch_rin = 0;
- dbuf += n;
- dlen -= n;
- }
-
- memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);
-
- ch->ch_rin += dlen;
-
-
- /*
- * If we are not in fastcook mode, or
- * if there is a fastcook thread
- * waiting for data, send the data to
- * the line discipline.
- */
-
- if ((ch->ch_flag & CH_FAST_READ) == 0 ||
- ch->ch_inwait != 0) {
- dgrp_input(ch);
- }
-
- /*
- * If there is a read thread waiting
- * in select, and we are in fastcook
- * mode, wake him up.
- */
-
- if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
- (ch->ch_flag & CH_FAST_READ) != 0)
- wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);
-
- /*
- * Wake any thread waiting in the
- * fastcook loop.
- */
-
- if ((ch->ch_flag & CH_INPUT) != 0) {
- ch->ch_flag &= ~CH_INPUT;
-
- wake_up_interruptible(&ch->ch_flag_wait);
- }
- }
-
- /*
- * Fabricate and insert a data packet header to
- * preced the remaining data when it comes in.
- */
-
- if (remain < plen) {
- dlen = plen - remain;
- b = buf;
-
- b[0] = 0x90 + n1;
- put_unaligned_be16(dlen, b + 1);
-
- remain = 3;
- goto done;
- }
- break;
-
- /*
- * Handle Window Sequence packets.
- */
-
- case 10:
- plen = 3;
- if (remain < plen)
- goto done;
-
- nd->nd_tx_work = 1;
-
- {
- ushort tpos = get_unaligned_be16(b + 1);
-
- ushort ack = (tpos - ch->ch_s_tpos) & 0xffff;
- ushort unack = (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
- ushort notify = (ch->ch_s_treq - ch->ch_s_tpos) & 0xffff;
-
- if (ch->ch_state < CS_READY || ack > unack) {
- error = "Improper Window Sequence";
- goto prot_error;
- }
-
- ch->ch_s_tpos = tpos;
-
- if (notify <= ack)
- ch->ch_s_treq = tpos;
- }
- break;
-
- /*
- * Handle Command response packets.
- */
-
- case 11:
-
- /*
- * RealPort engine fix - 03/11/2004
- *
- * This check did not used to be here.
- *
- * We were using b[1] without verifying that the data
- * is actually there and valid. On a split packet, it
- * might not be yet.
- *
- * NOTE: I have never actually seen the failure happen
- * under Linux, but since I have seen it occur
- * under both Solaris and HP-UX, the assumption
- * is that it *could* happen here as well...
- */
- if (remain < 2)
- goto done;
-
-
- switch (b[1]) {
-
- /*
- * Handle Open Response.
- */
-
- case 11:
- plen = 6;
- if (remain < plen)
- goto done;
-
- nd->nd_tx_work = 1;
-
- {
- int req = b[2];
- int resp = b[3];
- port = get_unaligned_be16(b + 4);
-
- if (port >= nd->nd_chan_count) {
- error = "Open channel number out of range";
- goto prot_error;
- }
-
- ch = nd->nd_chan + port;
-
- /*
- * How we handle an open response depends primarily
- * on our current channel state.
- */
-
- switch (ch->ch_state) {
- case CS_IDLE:
-
- /*
- * Handle a delayed open.
- */
-
- if (ch->ch_otype_waiting != 0 &&
- req == ch->ch_otype_waiting &&
- resp == 0) {
- ch->ch_otype = req;
- ch->ch_otype_waiting = 0;
- ch->ch_state = CS_SEND_QUERY;
- break;
- }
- goto open_error;
-
- case CS_WAIT_OPEN:
-
- /*
- * Handle the open response.
- */
-
- if (req == ch->ch_otype) {
- switch (resp) {
-
- /*
- * On successful response, open the
- * port and proceed normally.
- */
-
- case 0:
- ch->ch_state = CS_SEND_QUERY;
- break;
-
- /*
- * On a busy response to a persistent open,
- * remember that the open is pending.
- */
-
- case 1:
- case 2:
- if (req != OTYPE_IMMEDIATE) {
- ch->ch_otype_waiting = req;
- ch->ch_state = CS_IDLE;
- break;
- }
-
- /*
- * Otherwise the server open failed. If
- * the Unix port is open, hang it up.
- */
-
- default:
- if (ch->ch_open_count != 0) {
- ch->ch_flag |= CH_HANGUP;
- dgrp_carrier(ch);
- ch->ch_state = CS_IDLE;
- break;
- }
-
- ch->ch_open_error = resp;
- ch->ch_state = CS_IDLE;
-
- wake_up_interruptible(&ch->ch_flag_wait);
- }
- break;
- }
-
- /*
- * Handle delayed response arrival preceding
- * the open response we are waiting for.
- */
-
- if (ch->ch_otype_waiting != 0 &&
- req == ch->ch_otype_waiting &&
- resp == 0) {
- ch->ch_otype = ch->ch_otype_waiting;
- ch->ch_otype_waiting = 0;
- ch->ch_state = CS_WAIT_FAIL;
- break;
- }
- goto open_error;
-
-
- case CS_WAIT_FAIL:
-
- /*
- * Handle response to immediate open arriving
- * after a delayed open success.
- */
-
- if (req == OTYPE_IMMEDIATE) {
- ch->ch_state = CS_SEND_QUERY;
- break;
- }
- goto open_error;
-
-
- case CS_WAIT_CANCEL:
- /*
- * Handle delayed open response arriving before
- * the cancel response.
- */
-
- if (req == ch->ch_otype_waiting &&
- resp == 0) {
- ch->ch_otype_waiting = 0;
- break;
- }
-
- /*
- * Handle cancel response.
- */
-
- if (req == 4 && resp == 0) {
- ch->ch_otype_waiting = 0;
- ch->ch_state = CS_IDLE;
- break;
- }
- goto open_error;
-
-
- case CS_WAIT_CLOSE:
- /*
- * Handle a successful response to a port
- * close.
- */
-
- if (req >= 3) {
- ch->ch_state = CS_IDLE;
- break;
- }
- goto open_error;
-
-open_error:
- default:
- {
- error = "Improper Open Response";
- goto prot_error;
- }
- }
- }
- break;
-
- /*
- * Handle Synchronize Response.
- */
-
- case 13:
- plen = 3;
- if (remain < plen)
- goto done;
- {
- int seq = b[2];
- int s;
-
- /*
- * If channel was waiting for this sync response,
- * unset the flag, and wake up anyone waiting
- * on the event.
- */
- if (ch->ch_flag & CH_WAITING_SYNC) {
- ch->ch_flag &= ~(CH_WAITING_SYNC);
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
- if (((seq - nd->nd_seq_out) & SEQ_MASK) >=
- ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
- break;
- }
-
- for (s = nd->nd_seq_out;; s = (s + 1) & SEQ_MASK) {
- if (nd->nd_seq_wait[s] != 0) {
- nd->nd_seq_wait[s] = 0;
-
- wake_up_interruptible(&nd->nd_seq_wque[s]);
- }
-
- nd->nd_unack -= nd->nd_seq_size[s];
-
- if (s == seq)
- break;
- }
-
- nd->nd_seq_out = (seq + 1) & SEQ_MASK;
- }
- break;
-
- /*
- * Handle Sequence Response.
- */
-
- case 15:
- plen = 6;
- if (remain < plen)
- goto done;
-
- {
- /* Record that we have received the Sequence
- * Response, but we aren't interested in the
- * sequence numbers. We were using RIN like it
- * was ROUT and that was causing problems,
- * fixed 7-13-2001 David Fries. See comment in
- * drp.h for ch_s_rin variable.
- int rin = get_unaligned_be16(b + 2);
- int tpos = get_unaligned_be16(b + 4);
- */
-
- ch->ch_send &= ~RR_SEQUENCE;
- ch->ch_expect &= ~RR_SEQUENCE;
- }
- goto check_query;
-
- /*
- * Handle Status Response.
- */
-
- case 17:
- plen = 5;
- if (remain < plen)
- goto done;
-
- {
- ch->ch_s_elast = get_unaligned_be16(b + 2);
- ch->ch_s_mlast = b[4];
-
- ch->ch_expect &= ~RR_STATUS;
- ch->ch_send &= ~RR_STATUS;
-
- /*
- * CH_PHYS_CD is cleared because something _could_ be
- * waiting for the initial sense of carrier... and if
- * carrier is high immediately, we want to be sure to
- * wake them as soon as possible.
- */
- ch->ch_flag &= ~CH_PHYS_CD;
-
- dgrp_carrier(ch);
- }
- goto check_query;
-
- /*
- * Handle Line Error Response.
- */
-
- case 19:
- plen = 14;
- if (remain < plen)
- goto done;
-
- break;
-
- /*
- * Handle Buffer Response.
- */
-
- case 21:
- plen = 6;
- if (remain < plen)
- goto done;
-
- {
- ch->ch_s_rsize = get_unaligned_be16(b + 2);
- ch->ch_s_tsize = get_unaligned_be16(b + 4);
-
- ch->ch_send &= ~RR_BUFFER;
- ch->ch_expect &= ~RR_BUFFER;
- }
- goto check_query;
-
- /*
- * Handle Port Capability Response.
- */
-
- case 23:
- plen = 32;
- if (remain < plen)
- goto done;
-
- {
- ch->ch_send &= ~RR_CAPABILITY;
- ch->ch_expect &= ~RR_CAPABILITY;
- }
-
- /*
- * When all queries are complete, set those parameters
- * derived from the query results, then transition
- * to the READY state.
- */
-
-check_query:
- if (ch->ch_state == CS_WAIT_QUERY &&
- (ch->ch_expect & (RR_SEQUENCE |
- RR_STATUS |
- RR_BUFFER |
- RR_CAPABILITY)) == 0) {
- ch->ch_tmax = ch->ch_s_tsize / 4;
-
- if (ch->ch_edelay == DGRP_TTIME)
- ch->ch_ttime = DGRP_TTIME;
- else
- ch->ch_ttime = ch->ch_edelay;
-
- ch->ch_rmax = ch->ch_s_rsize / 4;
-
- if (ch->ch_edelay == DGRP_RTIME)
- ch->ch_rtime = DGRP_RTIME;
- else
- ch->ch_rtime = ch->ch_edelay;
-
- ch->ch_rlow = 2 * ch->ch_s_rsize / 8;
- ch->ch_rhigh = 6 * ch->ch_s_rsize / 8;
-
- ch->ch_state = CS_READY;
-
- nd->nd_tx_work = 1;
- wake_up_interruptible(&ch->ch_flag_wait);
-
- }
- break;
-
- default:
- goto decode_error;
- }
- break;
-
- /*
- * Handle Events.
- */
-
- case 12:
- plen = 4;
- if (remain < plen)
- goto done;
-
- mlast = ch->ch_s_mlast;
- elast = ch->ch_s_elast;
-
- mstat = ch->ch_s_mlast = b[1];
- estat = ch->ch_s_elast = get_unaligned_be16(b + 2);
-
- /*
- * Handle modem changes.
- */
-
- if (((mstat ^ mlast) & DM_CD) != 0)
- dgrp_carrier(ch);
-
-
- /*
- * Handle received break.
- */
-
- if ((estat & ~elast & EV_RXB) != 0 &&
- (ch->ch_tun.un_open_count != 0) &&
- I_BRKINT(ch->ch_tun.un_tty) &&
- !(I_IGNBRK(ch->ch_tun.un_tty))) {
-
- tty_buffer_request_room(&ch->port, 1);
- tty_insert_flip_char(&ch->port, 0, TTY_BREAK);
- tty_flip_buffer_push(&ch->port);
-
- }
-
- /*
- * On transmit break complete, if more break traffic
- * is waiting then send it. Otherwise wake any threads
- * waiting for transmitter empty.
- */
-
- if ((~estat & elast & EV_TXB) != 0 &&
- (ch->ch_expect & RR_TX_BREAK) != 0) {
-
- nd->nd_tx_work = 1;
-
- ch->ch_expect &= ~RR_TX_BREAK;
-
- if (ch->ch_break_time != 0) {
- ch->ch_send |= RR_TX_BREAK;
- } else {
- ch->ch_send &= ~RR_TX_BREAK;
- ch->ch_flag &= ~CH_TX_BREAK;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
- }
- break;
-
- case 13:
- case 14:
- error = "Unrecognized command";
- goto prot_error;
-
- /*
- * Decode Special Codes.
- */
-
- case 15:
- switch (n1) {
- /*
- * One byte module select.
- */
-
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- plen = 1;
- nd->nd_rx_module = n1;
- break;
-
- /*
- * Two byte module select.
- */
-
- case 8:
- plen = 2;
- if (remain < plen)
- goto done;
-
- nd->nd_rx_module = b[1];
- break;
-
- /*
- * ID Request packet.
- */
-
- case 11:
- if (remain < 4)
- goto done;
-
- plen = get_unaligned_be16(b + 2);
-
- if (plen < 12 || plen > 1000) {
- error = "Response Packet length error";
- goto prot_error;
- }
-
- nd->nd_tx_work = 1;
-
- switch (b[1]) {
- /*
- * Echo packet.
- */
-
- case 0:
- nd->nd_send |= NR_ECHO;
- break;
-
- /*
- * ID Response packet.
- */
-
- case 1:
- nd->nd_send |= NR_IDENT;
- break;
-
- /*
- * ID Response packet.
- */
-
- case 32:
- nd->nd_send |= NR_PASSWORD;
- break;
-
- }
- break;
-
- /*
- * Various node-level response packets.
- */
-
- case 12:
- if (remain < 4)
- goto done;
-
- plen = get_unaligned_be16(b + 2);
-
- if (plen < 4 || plen > 1000) {
- error = "Response Packet length error";
- goto prot_error;
- }
-
- nd->nd_tx_work = 1;
-
- switch (b[1]) {
- /*
- * Echo packet.
- */
-
- case 0:
- nd->nd_expect &= ~NR_ECHO;
- break;
-
- /*
- * Product Response Packet.
- */
-
- case 1:
- {
- int desclen;
-
- nd->nd_hw_ver = (b[8] << 8) | b[9];
- nd->nd_sw_ver = (b[10] << 8) | b[11];
- nd->nd_hw_id = b[6];
- desclen = (plen - 12 > MAX_DESC_LEN - 1) ? MAX_DESC_LEN - 1 :
- plen - 12;
-
- if (desclen <= 0) {
- error = "Response Packet desclen error";
- goto prot_error;
- }
-
- strncpy(nd->nd_ps_desc, b + 12, desclen);
- nd->nd_ps_desc[desclen] = 0;
- }
-
- nd->nd_expect &= ~NR_IDENT;
- break;
-
- /*
- * Capability Response Packet.
- */
-
- case 2:
- {
- int nn = get_unaligned_be16(b + 4);
-
- if (nn > CHAN_MAX)
- nn = CHAN_MAX;
-
- dgrp_chan_count(nd, nn);
- }
-
- nd->nd_expect &= ~NR_CAPABILITY;
- break;
-
- /*
- * VPD Response Packet.
- */
-
- case 15:
- /*
- * NOTE: case 15 is here ONLY because the EtherLite
- * is broken, and sends a response to 24 back as 15.
- * To resolve this, the EtherLite firmware is now
- * fixed to send back 24 correctly, but, for backwards
- * compatibility, we now have reserved 15 for the
- * bad EtherLite response to 24 as well.
- */
-
- /* Fallthru! */
-
- case 24:
-
- /*
- * If the product doesn't support VPD,
- * it will send back a null IDRESP,
- * which is a length of 4 bytes.
- */
- if (plen > 4) {
- memcpy(nd->nd_vpd, b + 4, min(plen - 4, (long) VPDSIZE));
- nd->nd_vpd_len = min(plen - 4, (long) VPDSIZE);
- }
-
- nd->nd_expect &= ~NR_VPD;
- break;
-
- default:
- goto decode_error;
- }
-
- if (nd->nd_expect == 0 &&
- nd->nd_state == NS_WAIT_QUERY) {
- nd->nd_state = NS_READY;
- }
- break;
-
- /*
- * Debug packet.
- */
-
- case 14:
- if (remain < 4)
- goto done;
-
- plen = get_unaligned_be16(b + 2) + 4;
-
- if (plen > 1000) {
- error = "Debug Packet too large";
- goto prot_error;
- }
-
- if (remain < plen)
- goto done;
- break;
-
- /*
- * Handle reset packet.
- */
-
- case 15:
- if (remain < 2)
- goto done;
-
- plen = 2 + b[1];
-
- if (remain < plen)
- goto done;
-
- nd->nd_tx_work = 1;
-
- n = b[plen];
- b[plen] = 0;
-
- b[plen] = n;
-
- error = "Client Reset Acknowledge";
- goto prot_error;
-
- default:
- goto decode_error;
- }
- break;
-
- default:
- goto decode_error;
- }
-
- b += plen;
- remain -= plen;
- }
-
- /*
- * When the buffer is exhausted, copy any data left at the
- * top of the buffer back down to the bottom for the next
- * read request.
- */
-
-done:
- if (remain > 0 && b != buf)
- memcpy(buf, b, remain);
-
- nd->nd_remain = remain;
- return;
-
-/*
- * Handle a decode error.
- */
-
-decode_error:
- error = "Protocol decode error";
-
-/*
- * Handle a general protocol error.
- */
-
-prot_error:
- nd->nd_remain = 0;
- nd->nd_state = NS_SEND_ERROR;
- nd->nd_error = error;
-}
-
-/*
- * dgrp_net_write() -- write data to the network device.
- *
- * A zero byte write indicates that the connection to the RealPort
- * device has been broken.
- *
- * A non-zero write indicates data from the RealPort device.
- */
-static ssize_t dgrp_net_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct nd_struct *nd;
- ssize_t rtn = 0;
- long n;
- long total = 0;
-
- /*
- * Get the node pointer, and quit if it doesn't exist.
- */
- nd = (struct nd_struct *)(file->private_data);
- if (!nd)
- return -ENXIO;
-
- /*
- * Grab the NET lock.
- */
- down(&nd->nd_net_semaphore);
-
- nd->nd_write_count++;
-
- /*
- * Handle disconnect.
- */
-
- if (count == 0) {
- dgrp_net_idle(nd);
- /*
- * Set the active port count to zero.
- */
- dgrp_chan_count(nd, 0);
- goto unlock;
- }
-
- /*
- * Loop to process entire receive packet.
- */
-
- while (count > 0) {
- n = UIO_MAX - nd->nd_remain;
-
- if (n > count)
- n = count;
-
- nd->nd_rx_byte += n + nd->nd_link.lk_header_size;
-
- rtn = copy_from_user(nd->nd_iobuf + nd->nd_remain,
- (void __user *) buf + total, n);
- if (rtn) {
- rtn = -EFAULT;
- goto unlock;
- }
-
- *ppos += n;
-
- total += n;
-
- count -= n;
-
- if (nd->nd_mon_buf)
- dgrp_monitor_data(nd, RPDUMP_SERVER,
- nd->nd_iobuf + nd->nd_remain, n);
-
- nd->nd_remain += n;
-
- dgrp_receive(nd);
- }
-
- rtn = total;
-
-unlock:
- /*
- * Release the NET lock.
- */
- up(&nd->nd_net_semaphore);
-
- return rtn;
-}
-
-
-/*
- * dgrp_net_select()
- * Determine whether a device is ready to be read or written to, and
- * sleep if not.
- */
-static unsigned int dgrp_net_select(struct file *file,
- struct poll_table_struct *table)
-{
- unsigned int retval = 0;
- struct nd_struct *nd = file->private_data;
-
- poll_wait(file, &nd->nd_tx_waitq, table);
-
- if (nd->nd_tx_ready)
- retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
-
- retval |= POLLOUT | POLLWRNORM; /* Always writeable */
-
- return retval;
-}
-
-/*
- * dgrp_net_ioctl
- *
- * Implement those functions which allow the network daemon to control
- * the network parameters in the driver. The ioctls include ones to
- * get and set the link speed parameters for the PortServer.
- */
-static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct nd_struct *nd;
- int rtn = 0;
- long size = _IOC_SIZE(cmd);
- struct link_struct link;
-
- nd = file->private_data;
-
- if (_IOC_DIR(cmd) & _IOC_READ)
- rtn = access_ok(VERIFY_WRITE, (void __user *) arg, size);
- else if (_IOC_DIR(cmd) & _IOC_WRITE)
- rtn = access_ok(VERIFY_READ, (void __user *) arg, size);
-
- if (!rtn)
- return rtn;
-
- switch (cmd) {
- case DIGI_SETLINK:
- if (size != sizeof(struct link_struct))
- return -EINVAL;
-
- if (copy_from_user(&link, (void __user *)arg, size))
- return -EFAULT;
-
- if (link.lk_fast_rate < 9600)
- link.lk_fast_rate = 9600;
-
- if (link.lk_slow_rate < 2400)
- link.lk_slow_rate = 2400;
-
- if (link.lk_fast_rate > 10000000)
- link.lk_fast_rate = 10000000;
-
- if (link.lk_slow_rate > link.lk_fast_rate)
- link.lk_slow_rate = link.lk_fast_rate;
-
- if (link.lk_fast_delay > 2000)
- link.lk_fast_delay = 2000;
-
- if (link.lk_slow_delay > 10000)
- link.lk_slow_delay = 10000;
-
- if (link.lk_fast_delay < 60)
- link.lk_fast_delay = 60;
-
- if (link.lk_slow_delay < link.lk_fast_delay)
- link.lk_slow_delay = link.lk_fast_delay;
-
- if (link.lk_header_size < 2)
- link.lk_header_size = 2;
-
- if (link.lk_header_size > 128)
- link.lk_header_size = 128;
-
- link.lk_fast_rate /= 8 * 1000 / dgrp_poll_tick;
- link.lk_slow_rate /= 8 * 1000 / dgrp_poll_tick;
-
- link.lk_fast_delay /= dgrp_poll_tick;
- link.lk_slow_delay /= dgrp_poll_tick;
-
- nd->nd_link = link;
-
- break;
-
- case DIGI_GETLINK:
- if (size != sizeof(struct link_struct))
- return -EINVAL;
-
- if (copy_to_user((void __user *)arg, (void *)(&nd->nd_link),
- size))
- return -EFAULT;
-
- break;
-
- default:
- return -EINVAL;
-
- }
-
- return 0;
-}
-
-/**
- * dgrp_poll_handler() -- handler for poll timer
- *
- * As each timer expires, it determines (a) whether the "transmit"
- * waiter needs to be woken up, and (b) whether the poller needs to
- * be rescheduled.
- */
-void dgrp_poll_handler(unsigned long arg)
-{
- struct dgrp_poll_data *poll_data;
- struct nd_struct *nd;
- struct link_struct *lk;
- ulong time;
- ulong poll_time;
- ulong freq;
- ulong lock_flags;
-
- poll_data = (struct dgrp_poll_data *) arg;
- freq = 1000 / poll_data->poll_tick;
- poll_data->poll_round += 17;
-
- if (poll_data->poll_round >= freq)
- poll_data->poll_round -= freq;
-
- /*
- * Loop to process all open nodes.
- *
- * For each node, determine the rate at which it should
- * be transmitting data. Then if the node should wake up
- * and transmit data now, enable the net receive select
- * to get the transmit going.
- */
-
- list_for_each_entry(nd, &nd_struct_list, list) {
-
- lk = &nd->nd_link;
-
- /*
- * Decrement statistics. These are only for use with
- * KME, so don't worry that the operations are done
- * unlocked, and so the results are occasionally wrong.
- */
-
- nd->nd_read_count -= (nd->nd_read_count +
- poll_data->poll_round) / freq;
- nd->nd_write_count -= (nd->nd_write_count +
- poll_data->poll_round) / freq;
- nd->nd_send_count -= (nd->nd_send_count +
- poll_data->poll_round) / freq;
- nd->nd_tx_byte -= (nd->nd_tx_byte +
- poll_data->poll_round) / freq;
- nd->nd_rx_byte -= (nd->nd_rx_byte +
- poll_data->poll_round) / freq;
-
- /*
- * Wake the daemon to transmit data only when there is
- * enough byte credit to send data.
- *
- * The results are approximate because the operations
- * are performed unlocked, and we are inspecting
- * data asynchronously updated elsewhere. The whole
- * thing is just approximation anyway, so that should
- * be okay.
- */
-
- if (lk->lk_slow_rate >= UIO_MAX) {
-
- nd->nd_delay = 0;
- nd->nd_rate = UIO_MAX;
-
- nd->nd_tx_deposit = nd->nd_tx_charge + 3 * UIO_MAX;
- nd->nd_tx_credit = 3 * UIO_MAX;
-
- } else {
-
- long rate;
- long delay;
- long deposit;
- long charge;
- long size;
- long excess;
-
- long seq_in = nd->nd_seq_in;
- long seq_out = nd->nd_seq_out;
-
- /*
- * If there are no outstanding packets, run at the
- * fastest rate.
- */
-
- if (seq_in == seq_out) {
- delay = 0;
- rate = lk->lk_fast_rate;
- }
-
- /*
- * Otherwise compute the transmit rate based on the
- * delay since the oldest packet.
- */
-
- else {
- /*
- * The actual delay is computed as the
- * time since the oldest unacknowledged
- * packet was sent, minus the time it
- * took to send that packet to the server.
- */
-
- delay = ((jiffies - nd->nd_seq_time[seq_out])
- - (nd->nd_seq_size[seq_out] /
- lk->lk_fast_rate));
-
- /*
- * If the delay is less than the "fast"
- * delay, transmit full speed. If greater
- * than the "slow" delay, transmit at the
- * "slow" speed. In between, interpolate
- * between the fast and slow speeds.
- */
-
- rate =
- (delay <= lk->lk_fast_delay ?
- lk->lk_fast_rate :
- delay >= lk->lk_slow_delay ?
- lk->lk_slow_rate :
- (lk->lk_slow_rate +
- (lk->lk_slow_delay - delay) *
- (lk->lk_fast_rate - lk->lk_slow_rate) /
- (lk->lk_slow_delay - lk->lk_fast_delay)
- )
- );
- }
-
- nd->nd_delay = delay;
- nd->nd_rate = rate;
-
- /*
- * Increase the transmit credit by depositing the
- * current transmit rate.
- */
-
- deposit = nd->nd_tx_deposit;
- charge = nd->nd_tx_charge;
-
- deposit += rate;
-
- /*
- * If the available transmit credit becomes too large,
- * reduce the deposit to correct the value.
- *
- * Too large is the max of:
- * 6 times the header size
- * 3 times the current transmit rate.
- */
-
- size = 2 * nd->nd_link.lk_header_size;
-
- if (size < rate)
- size = rate;
-
- size *= 3;
-
- excess = deposit - charge - size;
-
- if (excess > 0)
- deposit -= excess;
-
- nd->nd_tx_deposit = deposit;
- nd->nd_tx_credit = deposit - charge;
-
- /*
- * Wake the transmit task only if the transmit credit
- * is at least 3 times the transmit header size.
- */
-
- size = 3 * lk->lk_header_size;
-
- if (nd->nd_tx_credit < size)
- continue;
- }
-
-
- /*
- * Enable the READ select to wake the daemon if there
- * is useful work for the drp_read routine to perform.
- */
-
- if (waitqueue_active(&nd->nd_tx_waitq) &&
- (nd->nd_tx_work != 0 ||
- (ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX)) {
- nd->nd_tx_ready = 1;
-
- wake_up_interruptible(&nd->nd_tx_waitq);
-
- /* not needed */
- /* nd->nd_flag &= ~ND_SELECT; */
- }
- }
-
-
- /*
- * Schedule ourself back at the nominal wakeup interval.
- */
- spin_lock_irqsave(&poll_data->poll_lock, lock_flags);
-
- poll_data->node_active_count--;
- if (poll_data->node_active_count > 0) {
- poll_data->node_active_count++;
- poll_time = poll_data->timer.expires +
- poll_data->poll_tick * HZ / 1000;
-
- time = poll_time - jiffies;
-
- if (time >= 2 * poll_data->poll_tick)
- poll_time = jiffies + dgrp_poll_tick * HZ / 1000;
-
- poll_data->timer.expires = poll_time;
- add_timer(&poll_data->timer);
- }
-
- spin_unlock_irqrestore(&poll_data->poll_lock, lock_flags);
-}
diff --git a/drivers/staging/dgrp/dgrp_ports_ops.c b/drivers/staging/dgrp/dgrp_ports_ops.c
deleted file mode 100644
index 4ce030815f27..000000000000
--- a/drivers/staging/dgrp/dgrp_ports_ops.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *
- * Copyright 1999-2000 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_ports_ops.c
- *
- * Description:
- *
- * Handle the file operations required for the /proc/dgrp/ports/...
- * devices. Basically gathers tty status for the node and returns it.
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-#include <linux/seq_file.h>
-
-#include "dgrp_common.h"
-
-/* File operation declarations */
-static int dgrp_ports_open(struct inode *, struct file *);
-
-const struct file_operations dgrp_ports_ops = {
- .owner = THIS_MODULE,
- .open = dgrp_ports_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
-static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
-{
- if (*pos == 0)
- seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT IFLAG OFLAG CFLAG BPS DIGIFLAGS\n");
-
- return pos;
-}
-
-static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- struct nd_struct *nd = seq->private;
-
- if (*pos >= nd->nd_chan_count)
- return NULL;
-
- *pos += 1;
-
- return pos;
-}
-
-static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static int dgrp_ports_seq_show(struct seq_file *seq, void *v)
-{
- loff_t *pos = v;
- struct nd_struct *nd;
- struct ch_struct *ch;
- struct un_struct *tun, *pun;
- unsigned int totcnt;
-
- nd = seq->private;
- if (!nd)
- return 0;
-
- if (*pos >= nd->nd_chan_count)
- return 0;
-
- ch = &nd->nd_chan[*pos];
- tun = &ch->ch_tun;
- pun = &ch->ch_pun;
-
- /*
- * If port is not open and no one is waiting to
- * open it, the modem signal values can't be
- * trusted, and will be zeroed.
- */
- totcnt = tun->un_open_count +
- pun->un_open_count +
- ch->ch_wait_count[0] +
- ch->ch_wait_count[1] +
- ch->ch_wait_count[2];
-
- seq_printf(seq, "%02d %02d %02d %02d 0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n",
- (int) *pos,
- tun->un_open_count,
- pun->un_open_count,
- ch->ch_wait_count[0] +
- ch->ch_wait_count[1] +
- ch->ch_wait_count[2],
- (totcnt ? ch->ch_s_mlast : 0),
- ch->ch_s_iflag,
- ch->ch_s_oflag,
- ch->ch_s_cflag,
- (ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0),
- ch->ch_digi.digi_flags);
-
- return 0;
-}
-
-static const struct seq_operations ports_seq_ops = {
- .start = dgrp_ports_seq_start,
- .next = dgrp_ports_seq_next,
- .stop = dgrp_ports_seq_stop,
- .show = dgrp_ports_seq_show,
-};
-
-/**
- * dgrp_ports_open -- open the /proc/dgrp/ports/... device
- * @inode: struct inode *
- * @file: struct file *
- *
- * Open function to open the /proc/dgrp/ports device for a PortServer.
- * This is the open function for struct file_operations
- */
-static int dgrp_ports_open(struct inode *inode, struct file *file)
-{
- struct seq_file *seq;
- int rtn;
-
- rtn = seq_open(file, &ports_seq_ops);
- if (!rtn) {
- seq = file->private_data;
- seq->private = PDE_DATA(inode);
- }
-
- return rtn;
-}
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c
deleted file mode 100644
index 205d80ef4455..000000000000
--- a/drivers/staging/dgrp/dgrp_specproc.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * James Puzzo <jamesp at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_specproc.c
- *
- * Description:
- *
- * Handle the "config" proc entry for the linux realport device driver
- * and provide slots for the "net" and "mon" devices
- *
- * Author:
- *
- * James A. Puzzo
- *
- */
-
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/sched.h>
-#include <linux/cred.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <linux/vmalloc.h>
-
-#include "dgrp_common.h"
-
-static struct proc_dir_entry *dgrp_proc_dir_entry;
-
-static int dgrp_add_id(long id);
-static int dgrp_remove_nd(struct nd_struct *nd);
-static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
- struct proc_dir_entry *root,
- const struct file_operations *fops);
-
-/* File operation declarations */
-static int parse_write_config(char *);
-
-static ssize_t dgrp_config_proc_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *pos);
-
-static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file);
-static int dgrp_info_proc_open(struct inode *inode, struct file *file);
-static int dgrp_config_proc_open(struct inode *inode, struct file *file);
-
-static const struct file_operations config_proc_file_ops = {
- .owner = THIS_MODULE,
- .open = dgrp_config_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
- .write = dgrp_config_proc_write,
-};
-
-static const struct file_operations info_proc_file_ops = {
- .owner = THIS_MODULE,
- .open = dgrp_info_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations nodeinfo_proc_file_ops = {
- .owner = THIS_MODULE,
- .open = dgrp_nodeinfo_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static struct proc_dir_entry *net_entry_pointer;
-static struct proc_dir_entry *mon_entry_pointer;
-static struct proc_dir_entry *dpa_entry_pointer;
-static struct proc_dir_entry *ports_entry_pointer;
-
-static void remove_files(struct nd_struct *nd)
-{
- char buf[3];
- ID_TO_CHAR(nd->nd_ID, buf);
- dgrp_remove_node_class_sysfs_files(nd);
- if (nd->nd_net_de)
- remove_proc_entry(buf, net_entry_pointer);
- if (nd->nd_mon_de)
- remove_proc_entry(buf, mon_entry_pointer);
- if (nd->nd_dpa_de)
- remove_proc_entry(buf, dpa_entry_pointer);
- if (nd->nd_ports_de)
- remove_proc_entry(buf, ports_entry_pointer);
-}
-
-void dgrp_unregister_proc(void)
-{
- net_entry_pointer = NULL;
- mon_entry_pointer = NULL;
- dpa_entry_pointer = NULL;
- ports_entry_pointer = NULL;
-
- if (dgrp_proc_dir_entry) {
- struct nd_struct *nd;
- list_for_each_entry(nd, &nd_struct_list, list)
- remove_files(nd);
- remove_proc_entry("dgrp/config", NULL);
- remove_proc_entry("dgrp/info", NULL);
- remove_proc_entry("dgrp/nodeinfo", NULL);
- remove_proc_entry("dgrp/net", NULL);
- remove_proc_entry("dgrp/mon", NULL);
- remove_proc_entry("dgrp/dpa", NULL);
- remove_proc_entry("dgrp/ports", NULL);
- remove_proc_entry("dgrp", NULL);
- dgrp_proc_dir_entry = NULL;
- }
-}
-
-void dgrp_register_proc(void)
-{
- /*
- * Register /proc/dgrp
- */
- dgrp_proc_dir_entry = proc_mkdir("dgrp", NULL);
- if (!dgrp_proc_dir_entry)
- return;
- proc_create("dgrp/config", 0644, NULL, &config_proc_file_ops);
- proc_create("dgrp/info", 0644, NULL, &info_proc_file_ops);
- proc_create("dgrp/nodeinfo", 0644, NULL, &nodeinfo_proc_file_ops);
- net_entry_pointer = proc_mkdir_mode("dgrp/net", 0500, NULL);
- mon_entry_pointer = proc_mkdir_mode("dgrp/mon", 0500, NULL);
- dpa_entry_pointer = proc_mkdir_mode("dgrp/dpa", 0500, NULL);
- ports_entry_pointer = proc_mkdir_mode("dgrp/ports", 0500, NULL);
-}
-
-static void *dgrp_config_proc_start(struct seq_file *m, loff_t *pos)
-{
- return seq_list_start_head(&nd_struct_list, *pos);
-}
-
-static void *dgrp_config_proc_next(struct seq_file *p, void *v, loff_t *pos)
-{
- return seq_list_next(v, &nd_struct_list, pos);
-}
-
-static void dgrp_config_proc_stop(struct seq_file *m, void *v)
-{
-}
-
-static int dgrp_config_proc_show(struct seq_file *m, void *v)
-{
- struct nd_struct *nd;
- char tmp_id[4];
-
- if (v == &nd_struct_list) {
- seq_puts(m, "#-----------------------------------------------------------------------------\n");
- seq_puts(m, "# Avail\n");
- seq_puts(m, "# ID Major State Ports\n");
- return 0;
- }
-
- nd = list_entry(v, struct nd_struct, list);
-
- ID_TO_CHAR(nd->nd_ID, tmp_id);
-
- seq_printf(m, " %-2.2s %-5ld %-10.10s %-5d\n",
- tmp_id,
- nd->nd_major,
- ND_STATE_STR(nd->nd_state),
- nd->nd_chan_count);
-
- return 0;
-}
-
-static const struct seq_operations proc_config_ops = {
- .start = dgrp_config_proc_start,
- .next = dgrp_config_proc_next,
- .stop = dgrp_config_proc_stop,
- .show = dgrp_config_proc_show,
-};
-
-static int dgrp_config_proc_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &proc_config_ops);
-}
-
-
-/*
- * When writing configuration information, each "record" (i.e. each
- * write) is treated as an independent request. See the "parse"
- * description for more details.
- */
-static ssize_t dgrp_config_proc_write(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *pos)
-{
- ssize_t retval;
- char *inbuf, *sp;
- char *line, *ldelim;
-
- if (count > 32768)
- return -EINVAL;
-
- inbuf = sp = vzalloc(count + 1);
- if (!inbuf)
- return -ENOMEM;
-
- if (copy_from_user(inbuf, buffer, count)) {
- retval = -EFAULT;
- goto done;
- }
-
- inbuf[count] = 0;
-
- ldelim = "\n";
-
- line = strpbrk(sp, ldelim);
- while (line) {
- *line = 0;
- retval = parse_write_config(sp);
- if (retval)
- goto done;
-
- sp = line + 1;
- line = strpbrk(sp, ldelim);
- }
-
- retval = count;
-done:
- vfree(inbuf);
- return retval;
-}
-
-/*
- * ------------------------------------------------------------------------
- *
- * The following are the functions to parse input
- *
- * ------------------------------------------------------------------------
- */
-static inline char *skip_past_ws(const char *str)
-{
- while ((*str) && !isspace(*str))
- ++str;
-
- return skip_spaces(str);
-}
-
-static int parse_id(char **c, char *cID)
-{
- int tmp = **c;
-
- if (isalnum(tmp) || (tmp == '_'))
- cID[0] = tmp;
- else
- return -EINVAL;
-
- (*c)++; tmp = **c;
-
- if (isalnum(tmp) || (tmp == '_')) {
- cID[1] = tmp;
- (*c)++;
- } else
- cID[1] = 0;
-
- return 0;
-}
-
-static int parse_add_config(char *buf)
-{
- char *c = buf;
- int retval;
- char cID[2];
- long ID;
-
- c = skip_past_ws(c);
-
- retval = parse_id(&c, cID);
- if (retval < 0)
- return retval;
-
- ID = CHAR_TO_ID(cID);
-
- c = skip_past_ws(c);
-
- return dgrp_add_id(ID);
-}
-
-static int parse_del_config(char *buf)
-{
- char *c = buf;
- int retval;
- struct nd_struct *nd;
- char cID[2];
- long ID;
- long major;
-
- c = skip_past_ws(c);
-
- retval = parse_id(&c, cID);
- if (retval < 0)
- return retval;
-
- ID = CHAR_TO_ID(cID);
-
- c = skip_past_ws(c);
-
- retval = kstrtol(c, 10, &major);
- if (retval)
- return retval;
-
- nd = nd_struct_get(major);
- if (!nd)
- return -EINVAL;
-
- if ((nd->nd_major != major) || (nd->nd_ID != ID))
- return -EINVAL;
-
- return dgrp_remove_nd(nd);
-}
-
-static int parse_chg_config(char *buf)
-{
- return -EINVAL;
-}
-
-/*
- * The passed character buffer represents a single configuration request.
- * If the first character is a "+", it is parsed as a request to add a
- * PortServer
- * If the first character is a "-", it is parsed as a request to delete a
- * PortServer
- * If the first character is a "*", it is parsed as a request to change a
- * PortServer
- * Any other character (including whitespace) causes the record to be
- * ignored.
- */
-static int parse_write_config(char *buf)
-{
- int retval;
-
- switch (buf[0]) {
- case '+':
- retval = parse_add_config(buf);
- break;
- case '-':
- retval = parse_del_config(buf);
- break;
- case '*':
- retval = parse_chg_config(buf);
- break;
- default:
- retval = -EINVAL;
- }
-
- return retval;
-}
-
-static int dgrp_info_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "version: %s\n", DIGI_VERSION);
- seq_puts(m, "register_with_sysfs: 1\n");
- seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
- dgrp_poll_tick, dgrp_poll_tick);
-
- return 0;
-}
-
-static int dgrp_info_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dgrp_info_proc_show, NULL);
-}
-
-
-static void *dgrp_nodeinfo_start(struct seq_file *m, loff_t *pos)
-{
- return seq_list_start_head(&nd_struct_list, *pos);
-}
-
-static void *dgrp_nodeinfo_next(struct seq_file *p, void *v, loff_t *pos)
-{
- return seq_list_next(v, &nd_struct_list, pos);
-}
-
-static void dgrp_nodeinfo_stop(struct seq_file *m, void *v)
-{
-}
-
-static int dgrp_nodeinfo_show(struct seq_file *m, void *v)
-{
- struct nd_struct *nd;
- char hwver[8];
- char swver[8];
- char tmp_id[4];
-
- if (v == &nd_struct_list) {
- seq_puts(m, "#-----------------------------------------------------------------------------\n");
- seq_puts(m, "# HW HW SW\n");
- seq_puts(m, "# ID State Version ID Version Description\n");
- return 0;
- }
-
- nd = list_entry(v, struct nd_struct, list);
-
- ID_TO_CHAR(nd->nd_ID, tmp_id);
-
- if (nd->nd_state == NS_READY) {
- sprintf(hwver, "%d.%d", (nd->nd_hw_ver >> 8) & 0xff,
- nd->nd_hw_ver & 0xff);
- sprintf(swver, "%d.%d", (nd->nd_sw_ver >> 8) & 0xff,
- nd->nd_sw_ver & 0xff);
- seq_printf(m, " %-2.2s %-10.10s %-7.7s %-3d %-7.7s %-35.35s\n",
- tmp_id,
- ND_STATE_STR(nd->nd_state),
- hwver,
- nd->nd_hw_id,
- swver,
- nd->nd_ps_desc);
-
- } else {
- seq_printf(m, " %-2.2s %-10.10s\n",
- tmp_id,
- ND_STATE_STR(nd->nd_state));
- }
-
- return 0;
-}
-
-
-static const struct seq_operations nodeinfo_ops = {
- .start = dgrp_nodeinfo_start,
- .next = dgrp_nodeinfo_next,
- .stop = dgrp_nodeinfo_stop,
- .show = dgrp_nodeinfo_show,
-};
-
-static int dgrp_nodeinfo_proc_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &nodeinfo_ops);
-}
-
-/**
- * dgrp_add_id() -- creates new nd struct and adds it to list
- * @id: id of device to add
- */
-static int dgrp_add_id(long id)
-{
- struct nd_struct *nd;
- int ret;
- int i;
-
- nd = kzalloc(sizeof(struct nd_struct), GFP_KERNEL);
- if (!nd)
- return -ENOMEM;
-
- nd->nd_major = 0;
- nd->nd_ID = id;
-
- spin_lock_init(&nd->nd_lock);
-
- init_waitqueue_head(&nd->nd_tx_waitq);
- init_waitqueue_head(&nd->nd_mon_wqueue);
- init_waitqueue_head(&nd->nd_dpa_wqueue);
- sema_init(&nd->nd_mon_semaphore, 1);
- sema_init(&nd->nd_net_semaphore, 1);
- spin_lock_init(&nd->nd_dpa_lock);
- nd->nd_state = NS_CLOSED;
- for (i = 0; i < SEQ_MAX; i++)
- init_waitqueue_head(&nd->nd_seq_wque[i]);
-
- /* setup the structures to get the major number */
- ret = dgrp_tty_init(nd);
- if (ret)
- goto error_out;
-
- nd->nd_major = nd->nd_serial_ttdriver->major;
-
- ret = nd_struct_add(nd);
- if (ret)
- goto error_out;
-
- dgrp_create_node_class_sysfs_files(nd);
- nd->nd_net_de = add_proc_file(nd, net_entry_pointer, &dgrp_net_ops);
- nd->nd_mon_de = add_proc_file(nd, mon_entry_pointer, &dgrp_mon_ops);
- nd->nd_dpa_de = add_proc_file(nd, dpa_entry_pointer, &dgrp_dpa_ops);
- nd->nd_ports_de = add_proc_file(nd, ports_entry_pointer,
- &dgrp_ports_ops);
- return 0;
-
- /* FIXME this guy should free the tty driver stored in nd and destroy
- * all channel ports */
-error_out:
- kfree(nd);
- return ret;
-
-}
-
-static int dgrp_remove_nd(struct nd_struct *nd)
-{
- int ret;
-
- /* Check to see if the selected structure is in use */
- if (nd->nd_tty_ref_cnt)
- return -EBUSY;
-
- remove_files(nd);
-
- dgrp_tty_uninit(nd);
-
- ret = nd_struct_del(nd);
- if (ret)
- return ret;
-
- kfree(nd);
- return 0;
-}
-
-static struct proc_dir_entry *add_proc_file(struct nd_struct *node,
- struct proc_dir_entry *root,
- const struct file_operations *fops)
-{
- char buf[3];
- ID_TO_CHAR(node->nd_ID, buf);
- return proc_create_data(buf, 0600, root, fops, node);
-}
diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c
deleted file mode 100644
index 2f9345ff0abb..000000000000
--- a/drivers/staging/dgrp/dgrp_sysfs.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright 2004 Digi International (www.digi.com)
- * Scott H Kilau <Scott_Kilau at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-#include "dgrp_common.h"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/serial_reg.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-
-
-#define PORTSERVER_DIVIDEND 1843200
-#define SERIAL_TYPE_NORMAL 1
-#define SERIAL_TYPE_CALLOUT 2
-#define SERIAL_TYPE_XPRINT 3
-
-
-static struct class *dgrp_class;
-static struct device *dgrp_class_nodes_dev;
-static struct device *dgrp_class_global_settings_dev;
-
-
-static ssize_t dgrp_class_version_show(struct class *class,
- struct class_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
-}
-static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
-
-
-static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "1\n");
-}
-static DEVICE_ATTR(register_with_sysfs, 0400,
- dgrp_class_register_with_sysfs_show, NULL);
-
-
-static ssize_t dgrp_class_pollrate_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
-}
-
-static ssize_t dgrp_class_pollrate_store(struct device *c,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- if (sscanf(buf, "0x%x\n", &dgrp_poll_tick) != 1)
- return -EINVAL;
-
- return count;
-}
-static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
- dgrp_class_pollrate_store);
-
-static struct attribute *dgrp_sysfs_global_settings_entries[] = {
- &dev_attr_pollrate.attr,
- &dev_attr_register_with_sysfs.attr,
- NULL
-};
-
-
-static struct attribute_group dgrp_global_settings_attribute_group = {
- .name = NULL,
- .attrs = dgrp_sysfs_global_settings_entries,
-};
-
-
-
-int dgrp_create_class_sysfs_files(void)
-{
- int ret = 0;
- int max_majors = 1U << (32 - MINORBITS);
-
- dgrp_class = class_create(THIS_MODULE, "digi_realport");
- if (IS_ERR(dgrp_class))
- return PTR_ERR(dgrp_class);
- ret = class_create_file(dgrp_class, &class_attr_driver_version);
- if (ret)
- goto err_class;
-
- dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
- MKDEV(0, max_majors + 1), NULL, "driver_settings");
- if (IS_ERR(dgrp_class_global_settings_dev)) {
- ret = PTR_ERR(dgrp_class_global_settings_dev);
- goto err_file;
- }
- ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
- &dgrp_global_settings_attribute_group);
- if (ret) {
- pr_alert("%s: failed to create sysfs global settings device attributes.\n",
- __func__);
- goto err_dev1;
- }
-
- dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
- MKDEV(0, max_majors + 2), NULL, "nodes");
- if (IS_ERR(dgrp_class_nodes_dev)) {
- ret = PTR_ERR(dgrp_class_nodes_dev);
- goto err_group;
- }
-
- return 0;
-err_group:
- sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
- &dgrp_global_settings_attribute_group);
-err_dev1:
- device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
-err_file:
- class_remove_file(dgrp_class, &class_attr_driver_version);
-err_class:
- class_destroy(dgrp_class);
- return ret;
-}
-
-
-void dgrp_remove_class_sysfs_files(void)
-{
- struct nd_struct *nd;
- int max_majors = 1U << (32 - MINORBITS);
-
- list_for_each_entry(nd, &nd_struct_list, list)
- dgrp_remove_node_class_sysfs_files(nd);
-
- sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
- &dgrp_global_settings_attribute_group);
-
- class_remove_file(dgrp_class, &class_attr_driver_version);
-
- device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
- device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
- class_destroy(dgrp_class);
-}
-
-static ssize_t dgrp_node_state_show(struct device *c,
- struct device_attribute *attr, char *buf)
-{
- struct nd_struct *nd;
-
- if (!c)
- return 0;
- nd = dev_get_drvdata(c);
- if (!nd)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
-}
-
-static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
-
-static ssize_t dgrp_node_description_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- struct nd_struct *nd;
-
- if (!c)
- return 0;
- nd = dev_get_drvdata(c);
- if (!nd)
- return 0;
-
- if (nd->nd_state == NS_READY)
- return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
- return 0;
-}
-static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
-
-static ssize_t dgrp_node_hw_version_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- struct nd_struct *nd;
-
- if (!c)
- return 0;
- nd = dev_get_drvdata(c);
- if (!nd)
- return 0;
-
- if (nd->nd_state == NS_READY)
- return snprintf(buf, PAGE_SIZE, "%d.%d\n",
- (nd->nd_hw_ver >> 8) & 0xff,
- nd->nd_hw_ver & 0xff);
-
- return 0;
-}
-static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
-
-static ssize_t dgrp_node_hw_id_show(struct device *c,
- struct device_attribute *attr, char *buf)
-{
- struct nd_struct *nd;
-
- if (!c)
- return 0;
- nd = dev_get_drvdata(c);
- if (!nd)
- return 0;
-
-
- if (nd->nd_state == NS_READY)
- return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
- return 0;
-}
-static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
-
-static ssize_t dgrp_node_sw_version_show(struct device *c,
- struct device_attribute *attr,
- char *buf)
-{
- struct nd_struct *nd;
-
- if (!c)
- return 0;
-
- nd = dev_get_drvdata(c);
- if (!nd)
- return 0;
-
- if (nd->nd_state == NS_READY)
- return snprintf(buf, PAGE_SIZE, "%d.%d\n",
- (nd->nd_sw_ver >> 8) & 0xff,
- nd->nd_sw_ver & 0xff);
-
- return 0;
-}
-static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
-
-
-static struct attribute *dgrp_sysfs_node_entries[] = {
- &dev_attr_state.attr,
- &dev_attr_description_info.attr,
- &dev_attr_hw_version_info.attr,
- &dev_attr_hw_id_info.attr,
- &dev_attr_sw_version_info.attr,
- NULL
-};
-
-
-static struct attribute_group dgrp_node_attribute_group = {
- .name = NULL,
- .attrs = dgrp_sysfs_node_entries,
-};
-
-
-void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
-{
- int ret;
- char name[10];
-
- if (nd->nd_ID)
- ID_TO_CHAR(nd->nd_ID, name);
- else
- sprintf(name, "node%ld", nd->nd_major);
-
- nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
- MKDEV(0, nd->nd_major), NULL, "%s", name);
-
- ret = sysfs_create_group(&nd->nd_class_dev->kobj,
- &dgrp_node_attribute_group);
-
- if (ret) {
- pr_alert("%s: failed to create sysfs node device attributes.\n",
- __func__);
- sysfs_remove_group(&nd->nd_class_dev->kobj,
- &dgrp_node_attribute_group);
- return;
- }
-
- dev_set_drvdata(nd->nd_class_dev, nd);
-
-}
-
-
-void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
-{
- if (nd->nd_class_dev) {
- sysfs_remove_group(&nd->nd_class_dev->kobj,
- &dgrp_node_attribute_group);
-
- device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
- nd->nd_class_dev = NULL;
- }
-}
-
-
-
-static ssize_t dgrp_tty_state_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%s\n",
- un->un_open_count ? "Open" : "Closed");
-}
-static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
-
-static ssize_t dgrp_tty_baud_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%d\n",
- un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
-}
-static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
-
-
-static ssize_t dgrp_tty_msignals_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
-
- if (ch->ch_open_count) {
- return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
- (ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
- (ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
- (ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
- (ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
- (ch->ch_s_mlast & DM_CD) ? "DCD" : "",
- (ch->ch_s_mlast & DM_RI) ? "RI" : "");
- }
- return 0;
-}
-static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
-
-
-static ssize_t dgrp_tty_iflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
-}
-static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
-
-
-static ssize_t dgrp_tty_cflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
-}
-static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
-
-
-static ssize_t dgrp_tty_oflag_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
-}
-static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
-
-
-static ssize_t dgrp_tty_digi_flag_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
-}
-static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
-
-
-static ssize_t dgrp_tty_rxcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
-}
-static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
-
-
-static ssize_t dgrp_tty_txcount_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct ch_struct *ch;
- struct un_struct *un;
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
-}
-static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
-
-
-static ssize_t dgrp_tty_name_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct nd_struct *nd;
- struct ch_struct *ch;
- struct un_struct *un;
- char name[10];
-
- if (!d)
- return 0;
- un = dev_get_drvdata(d);
- if (!un)
- return 0;
- ch = un->un_ch;
- if (!ch)
- return 0;
- nd = ch->ch_nd;
- if (!nd)
- return 0;
-
- ID_TO_CHAR(nd->nd_ID, name);
-
- return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
- un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
- name, ch->ch_portnum);
-}
-static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
-
-
-static struct attribute *dgrp_sysfs_tty_entries[] = {
- &dev_attr_state_info.attr,
- &dev_attr_baud_info.attr,
- &dev_attr_msignals_info.attr,
- &dev_attr_iflag_info.attr,
- &dev_attr_cflag_info.attr,
- &dev_attr_oflag_info.attr,
- &dev_attr_digi_flag_info.attr,
- &dev_attr_rxcount_info.attr,
- &dev_attr_txcount_info.attr,
- &dev_attr_custom_name.attr,
- NULL
-};
-
-
-static struct attribute_group dgrp_tty_attribute_group = {
- .name = NULL,
- .attrs = dgrp_sysfs_tty_entries,
-};
-
-
-void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
-{
- int ret;
-
- ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
- if (ret) {
- pr_alert("%s: failed to create sysfs tty device attributes.\n",
- __func__);
- sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
- return;
- }
-
- dev_set_drvdata(c, un);
-
-}
-
-
-void dgrp_remove_tty_sysfs(struct device *c)
-{
- sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
-}
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c
deleted file mode 100644
index 30d26029b21e..000000000000
--- a/drivers/staging/dgrp/dgrp_tty.c
+++ /dev/null
@@ -1,3337 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * Gene Olson <Gene_Olson at digi dot com>
- * James Puzzo <jamesp at digi dot com>
- * Jeff Randall
- * Scott Kilau <scottk at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/*
- *
- * Filename:
- *
- * dgrp_tty.c
- *
- * Description:
- *
- * This file implements the tty driver functionality for the
- * RealPort driver software.
- *
- * Author:
- *
- * James A. Puzzo
- * Ann-Marie Westgate
- *
- */
-
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/device.h>
-#include <linux/sched.h>
-#include <linux/uaccess.h>
-
-#include "dgrp_common.h"
-
-#ifndef _POSIX_VDISABLE
-#define _POSIX_VDISABLE ('\0')
-#endif
-
-/*
- * forward declarations
- */
-
-static void drp_param(struct ch_struct *);
-static void dgrp_tty_close(struct tty_struct *, struct file *);
-
-/* ioctl helper functions */
-static int set_modem_info(struct ch_struct *, unsigned int, unsigned int *);
-static int get_modem_info(struct ch_struct *, unsigned int *);
-static void dgrp_set_custom_speed(struct ch_struct *, int);
-static int dgrp_tty_digigetedelay(struct tty_struct *, int *);
-static int dgrp_tty_digisetedelay(struct tty_struct *, int *);
-static int dgrp_send_break(struct ch_struct *, int);
-
-static ushort tty_to_ch_flags(struct tty_struct *, char);
-static tcflag_t ch_to_tty_flags(unsigned short, char);
-
-static void dgrp_tty_input_start(struct tty_struct *);
-static void dgrp_tty_input_stop(struct tty_struct *);
-
-static void drp_wmove(struct ch_struct *, int, void*, int);
-
-static int dgrp_tty_open(struct tty_struct *, struct file *);
-static void dgrp_tty_close(struct tty_struct *, struct file *);
-static int dgrp_tty_write(struct tty_struct *, const unsigned char *, int);
-static int dgrp_tty_write_room(struct tty_struct *);
-static void dgrp_tty_flush_buffer(struct tty_struct *);
-static int dgrp_tty_chars_in_buffer(struct tty_struct *);
-static int dgrp_tty_ioctl(struct tty_struct *, unsigned int, unsigned long);
-static void dgrp_tty_set_termios(struct tty_struct *, struct ktermios *);
-static void dgrp_tty_stop(struct tty_struct *);
-static void dgrp_tty_start(struct tty_struct *);
-static void dgrp_tty_throttle(struct tty_struct *);
-static void dgrp_tty_unthrottle(struct tty_struct *);
-static void dgrp_tty_hangup(struct tty_struct *);
-static int dgrp_tty_put_char(struct tty_struct *, unsigned char);
-static int dgrp_tty_tiocmget(struct tty_struct *);
-static int dgrp_tty_tiocmset(struct tty_struct *, unsigned int, unsigned int);
-static int dgrp_tty_send_break(struct tty_struct *, int);
-static void dgrp_tty_send_xchar(struct tty_struct *, char);
-
-/*
- * tty defines
- */
-#define SERIAL_TYPE_NORMAL 1
-#define SERIAL_TYPE_CALLOUT 2
-#define SERIAL_TYPE_XPRINT 3
-
-
-/*
- * tty globals/statics
- */
-
-
-#define PORTSERVER_DIVIDEND 1843200
-
-/*
- * Default transparent print information.
- */
-static struct digi_struct digi_init = {
- .digi_flags = DIGI_COOK, /* Flags */
- .digi_maxcps = 100, /* Max CPS */
- .digi_maxchar = 50, /* Max chars in print queue */
- .digi_bufsize = 100, /* Printer buffer size */
- .digi_onlen = 4, /* size of printer on string */
- .digi_offlen = 4, /* size of printer off string */
- .digi_onstr = "\033[5i", /* ANSI printer on string */
- .digi_offstr = "\033[4i", /* ANSI printer off string */
- .digi_term = "ansi" /* default terminal type */
-};
-
-/*
- * Define a local default termios struct. All ports will be created
- * with this termios initially.
- *
- * This defines a raw port at 9600 baud, 8 data bits, no parity,
- * 1 stop bit.
- */
-static struct ktermios DefaultTermios = {
- .c_iflag = (ICRNL | IXON),
- .c_oflag = (OPOST | ONLCR),
- .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
- .c_lflag = (ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL
- | ECHOKE | IEXTEN),
- .c_cc = INIT_C_CC,
- .c_line = 0,
-};
-
-/* Define our tty operations struct */
-static const struct tty_operations dgrp_tty_ops = {
- .open = dgrp_tty_open,
- .close = dgrp_tty_close,
- .write = dgrp_tty_write,
- .write_room = dgrp_tty_write_room,
- .flush_buffer = dgrp_tty_flush_buffer,
- .chars_in_buffer = dgrp_tty_chars_in_buffer,
- .flush_chars = NULL,
- .ioctl = dgrp_tty_ioctl,
- .set_termios = dgrp_tty_set_termios,
- .stop = dgrp_tty_stop,
- .start = dgrp_tty_start,
- .throttle = dgrp_tty_throttle,
- .unthrottle = dgrp_tty_unthrottle,
- .hangup = dgrp_tty_hangup,
- .put_char = dgrp_tty_put_char,
- .tiocmget = dgrp_tty_tiocmget,
- .tiocmset = dgrp_tty_tiocmset,
- .break_ctl = dgrp_tty_send_break,
- .send_xchar = dgrp_tty_send_xchar
-};
-
-
-static int calc_baud_rate(struct un_struct *un)
-{
- int i;
- int brate;
-
- struct baud_rates {
- unsigned int rate;
- unsigned int cflag;
- };
-
- static struct baud_rates baud_rates[] = {
- { 921600, B921600 },
- { 460800, B460800 },
- { 230400, B230400 },
- { 115200, B115200 },
- { 57600, B57600 },
- { 38400, B38400 },
- { 19200, B19200 },
- { 9600, B9600 },
- { 4800, B4800 },
- { 2400, B2400 },
- { 1200, B1200 },
- { 600, B600 },
- { 300, B300 },
- { 200, B200 },
- { 150, B150 },
- { 134, B134 },
- { 110, B110 },
- { 75, B75 },
- { 50, B50 },
- { 0, B9600 }
- };
-
- brate = C_BAUD(un->un_tty);
-
- for (i = 0; baud_rates[i].rate; i++) {
- if (baud_rates[i].cflag == brate)
- break;
- }
-
- return baud_rates[i].rate;
-}
-
-static int calc_fastbaud_rate(struct un_struct *un, struct ktermios *uts)
-{
- int i;
- int brate;
-
- ulong bauds[2][16] = {
- { /* fastbaud*/
- 0, 57600, 76800, 115200,
- 131657, 153600, 230400, 460800,
- 921600, 1200, 1800, 2400,
- 4800, 9600, 19200, 38400 },
- { /* fastbaud & CBAUDEX */
- 0, 57600, 115200, 230400,
- 460800, 150, 200, 921600,
- 600, 1200, 1800, 2400,
- 4800, 9600, 19200, 38400 }
- };
-
- brate = C_BAUD(un->un_tty) & 0xff;
-
- i = (uts->c_cflag & CBAUDEX) ? 1 : 0;
-
-
- if ((i >= 0) && (i < 2) && (brate >= 0) && (brate < 16))
- brate = bauds[i][brate];
- else
- brate = 0;
-
- return brate;
-}
-
-/**
- * drp_param() -- send parameter values to be sent to the node
- * @ch: channel structure of port to modify
- *
- * Interprets the tty and modem changes made by an application
- * program (by examining the termios structures) and sets up
- * parameter values to be sent to the node.
- */
-static void drp_param(struct ch_struct *ch)
-{
- struct nd_struct *nd;
- struct un_struct *un;
- int brate;
- int mflow;
- int xflag;
- int iflag;
- struct ktermios *tts, *pts, *uts;
-
- nd = ch->ch_nd;
-
- /*
- * If the terminal device is open, use it to set up all tty
- * modes and functions. Otherwise use the printer device.
- */
-
- if (ch->ch_tun.un_open_count) {
-
- un = &ch->ch_tun;
- tts = &ch->ch_tun.un_tty->termios;
-
- /*
- * If both devices are open, copy critical line
- * parameters from the tty device to the printer,
- * so that if the tty is closed, the printer will
- * continue without disruption.
- */
-
- if (ch->ch_pun.un_open_count) {
-
- pts = &ch->ch_pun.un_tty->termios;
-
- pts->c_cflag ^=
- (pts->c_cflag ^ tts->c_cflag) &
- (CBAUD | CSIZE | CSTOPB | CREAD | PARENB |
- PARODD | HUPCL | CLOCAL);
-
- pts->c_iflag ^=
- (pts->c_iflag ^ tts->c_iflag) &
- (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK |
- ISTRIP | IXON | IXANY | IXOFF);
-
- pts->c_cc[VSTART] = tts->c_cc[VSTART];
- pts->c_cc[VSTOP] = tts->c_cc[VSTOP];
- }
- } else if (ch->ch_pun.un_open_count == 0) {
- pr_warn("%s - ch_pun.un_open_count shouldn't be 0\n",
- __func__);
- return;
- } else {
- un = &ch->ch_pun;
- }
-
- uts = &un->un_tty->termios;
-
- /*
- * Determine if FAST writes can be performed.
- */
-
- if ((ch->ch_digi.digi_flags & DIGI_COOK) != 0 &&
- (ch->ch_tun.un_open_count != 0) &&
- !((un->un_tty)->ldisc->ops->flags & LDISC_FLAG_DEFINED) &&
- !(L_XCASE(un->un_tty))) {
- ch->ch_flag |= CH_FAST_WRITE;
- } else {
- ch->ch_flag &= ~CH_FAST_WRITE;
- }
-
- /*
- * If FAST writes can be performed, and OPOST is on in the
- * terminal device, do OPOST handling in the server.
- */
-
- if ((ch->ch_flag & CH_FAST_WRITE) &&
- O_OPOST(un->un_tty) != 0) {
- int oflag = tty_to_ch_flags(un->un_tty, 'o');
-
- /* add to ch_ocook any processing flags set in the termio */
- ch->ch_ocook |= oflag & (OF_OLCUC |
- OF_ONLCR |
- OF_OCRNL |
- OF_ONLRET |
- OF_TABDLY);
-
- /*
- * the hpux driver clears any flags set in ch_ocook
- * from the termios oflag. It is STILL reported though
- * by a TCGETA
- */
-
- oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
- uts->c_oflag &= ~oflag;
-
- } else {
- /* clear the ch->ch_ocook flag */
- int oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
- uts->c_oflag |= oflag;
- ch->ch_ocook = 0;
- }
-
- ch->ch_oflag = ch->ch_ocook;
-
-
- ch->ch_flag &= ~CH_FAST_READ;
-
- /*
- * Generate channel flags
- */
-
- if (C_BAUD(un->un_tty) == B0) {
- if (!(ch->ch_flag & CH_BAUD0)) {
- /* TODO : the HPUX driver flushes line */
- /* TODO : discipline, I assume I don't have to */
-
- ch->ch_tout = ch->ch_tin;
- ch->ch_rout = ch->ch_rin;
-
- ch->ch_break_time = 0;
-
- ch->ch_send |= RR_TX_FLUSH | RR_RX_FLUSH;
-
- ch->ch_mout &= ~(DM_DTR | DM_RTS);
-
- ch->ch_flag |= CH_BAUD0;
- }
- } else if (ch->ch_custom_speed) {
- ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed;
-
- if (ch->ch_flag & CH_BAUD0) {
- ch->ch_mout |= DM_DTR | DM_RTS;
-
- ch->ch_flag &= ~CH_BAUD0;
- }
- } else {
- /*
- * Baud rate mapping.
- *
- * If FASTBAUD isn't on, we can scan the new baud rate list
- * as required.
- *
- * However, if FASTBAUD is on, we must go to the old
- * baud rate mapping that existed many many moons ago,
- * for compatibility reasons.
- */
-
- if (!(ch->ch_digi.digi_flags & DIGI_FAST))
- brate = calc_baud_rate(un);
- else
- brate = calc_fastbaud_rate(un, uts);
-
- if (brate == 0)
- brate = 9600;
-
- ch->ch_brate = PORTSERVER_DIVIDEND / brate;
-
- if (ch->ch_flag & CH_BAUD0) {
- ch->ch_mout |= DM_DTR | DM_RTS;
-
- ch->ch_flag &= ~CH_BAUD0;
- }
- }
-
- /*
- * Generate channel cflags from the termio.
- */
-
- ch->ch_cflag = tty_to_ch_flags(un->un_tty, 'c');
-
- /*
- * Generate channel iflags from the termio.
- */
-
- iflag = (int) tty_to_ch_flags(un->un_tty, 'i');
-
- if (START_CHAR(un->un_tty) == _POSIX_VDISABLE ||
- STOP_CHAR(un->un_tty) == _POSIX_VDISABLE) {
- iflag &= ~(IF_IXON | IF_IXANY | IF_IXOFF);
- }
-
- ch->ch_iflag = iflag;
-
- /*
- * Generate flow control characters
- */
-
- /*
- * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
- * is defined for the terminal device file, and the value
- * of one of the changeable special control characters (see
- * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
- * disabled, that is, no input data shall be recognized as
- * the disabled special character."
- *
- * OK, so we don't ever assign S/DXB XON or XOFF to _POSIX_VDISABLE.
- */
-
- if (uts->c_cc[VSTART] != _POSIX_VDISABLE)
- ch->ch_xon = uts->c_cc[VSTART];
- if (uts->c_cc[VSTOP] != _POSIX_VDISABLE)
- ch->ch_xoff = uts->c_cc[VSTOP];
-
- ch->ch_lnext = (uts->c_cc[VLNEXT] == _POSIX_VDISABLE ? 0 :
- uts->c_cc[VLNEXT]);
-
- /*
- * Also, if either c_cc[START] or c_cc[STOP] is set to
- * _POSIX_VDISABLE, we can't really do software flow
- * control--in either direction--so we turn it off as
- * far as S/DXB is concerned. In essence, if you disable
- * one, you disable the other too.
- */
- if ((uts->c_cc[VSTART] == _POSIX_VDISABLE) ||
- (uts->c_cc[VSTOP] == _POSIX_VDISABLE))
- ch->ch_iflag &= ~(IF_IXOFF | IF_IXON);
-
- /*
- * Update xflags.
- */
-
- xflag = 0;
-
- if (ch->ch_digi.digi_flags & DIGI_AIXON)
- xflag = XF_XIXON;
-
- if ((ch->ch_xxon == _POSIX_VDISABLE) ||
- (ch->ch_xxoff == _POSIX_VDISABLE))
- xflag &= ~XF_XIXON;
-
- ch->ch_xflag = xflag;
-
-
- /*
- * Figure effective DCD value.
- */
-
- if (C_CLOCAL(un->un_tty))
- ch->ch_flag |= CH_CLOCAL;
- else
- ch->ch_flag &= ~CH_CLOCAL;
-
- /*
- * Check modem signals
- */
-
- dgrp_carrier(ch);
-
- /*
- * Get hardware handshake value.
- */
-
- mflow = 0;
-
- if (C_CRTSCTS(un->un_tty))
- mflow |= (DM_RTS | DM_CTS);
-
- if (ch->ch_digi.digi_flags & RTSPACE)
- mflow |= DM_RTS;
-
- if (ch->ch_digi.digi_flags & DTRPACE)
- mflow |= DM_DTR;
-
- if (ch->ch_digi.digi_flags & CTSPACE)
- mflow |= DM_CTS;
-
- if (ch->ch_digi.digi_flags & DSRPACE)
- mflow |= DM_DSR;
-
- if (ch->ch_digi.digi_flags & DCDPACE)
- mflow |= DM_CD;
-
- if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
- mflow |= DM_RTS_TOGGLE;
-
- ch->ch_mflow = mflow;
-
- /*
- * Send the changes to the server.
- */
-
- ch->ch_flag |= CH_PARAM;
- (ch->ch_nd)->nd_tx_work = 1;
-
- if (waitqueue_active(&ch->ch_flag_wait))
- wake_up_interruptible(&ch->ch_flag_wait);
-}
-
-/*
- * This function is just used as a callback for timeouts
- * waiting on the ch_sleep flag.
- */
-static void wake_up_drp_sleep_timer(unsigned long ptr)
-{
- struct ch_struct *ch = (struct ch_struct *) ptr;
- if (ch)
- wake_up(&ch->ch_sleep);
-}
-
-
-/*
- * Set up our own sleep that can't be cancelled
- * until our timeout occurs.
- */
-static void drp_my_sleep(struct ch_struct *ch)
-{
- struct timer_list drp_wakeup_timer;
- DECLARE_WAITQUEUE(wait, current);
-
- /*
- * First make sure we're ready to receive the wakeup.
- */
-
- add_wait_queue(&ch->ch_sleep, &wait);
- current->state = TASK_UNINTERRUPTIBLE;
-
- /*
- * Since we are uninterruptible, set a timer to
- * unset the uninterruptable state in 1 second.
- */
-
- init_timer(&drp_wakeup_timer);
- drp_wakeup_timer.function = wake_up_drp_sleep_timer;
- drp_wakeup_timer.data = (unsigned long) ch;
- drp_wakeup_timer.expires = jiffies + (1 * HZ);
- add_timer(&drp_wakeup_timer);
-
- schedule();
-
- del_timer(&drp_wakeup_timer);
-
- remove_wait_queue(&ch->ch_sleep, &wait);
-}
-
-/*
- * dgrp_tty_open()
- *
- * returns:
- * -EBUSY - this is a callout device and the normal device is active
- * - there is an error in opening the tty
- * -ENODEV - the channel does not exist
- * -EAGAIN - we are in the middle of hanging up or closing
- * - IMMEDIATE_OPEN fails
- * -ENXIO or -EAGAIN
- * - if the port is outside physical range
- * -EINTR - the open is interrupted
- *
- */
-static int dgrp_tty_open(struct tty_struct *tty, struct file *file)
-{
- int retval = 0;
- struct nd_struct *nd;
- struct ch_struct *ch;
- struct un_struct *un;
- int port;
- int delay_error;
- int otype;
- int unf;
- int wait_carrier;
- int category;
- int counts_were_incremented = 0;
- ulong lock_flags;
- DECLARE_WAITQUEUE(wait, current);
-
- /*
- * Do some initial checks to see if the node and port exist
- */
-
- nd = nd_struct_get(MAJOR(tty_devnum(tty)));
- port = PORT_NUM(MINOR(tty_devnum(tty)));
- category = OPEN_CATEGORY(MINOR(tty_devnum(tty)));
-
- if (!nd)
- return -ENODEV;
-
- if (port >= CHAN_MAX)
- return -ENODEV;
-
- /*
- * The channel exists.
- */
-
- ch = nd->nd_chan + port;
-
- un = IS_PRINT(MINOR(tty_devnum(tty))) ? &ch->ch_pun : &ch->ch_tun;
- un->un_tty = tty;
- tty->driver_data = un;
-
- /*
- * If we are in the middle of hanging up,
- * then return an error
- */
- if (tty_hung_up_p(file)) {
- retval = ((un->un_flag & UN_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
- goto done;
- }
-
- /*
- * If the port is in the middle of closing, then block
- * until it is done, then try again.
- */
- retval = wait_event_interruptible(un->un_close_wait,
- ((un->un_flag & UN_CLOSING) == 0));
-
- if (retval)
- goto done;
-
- /*
- * If the port is in the middle of a reopen after a network disconnect,
- * wait until it is done, then try again.
- */
- retval = wait_event_interruptible(ch->ch_flag_wait,
- ((ch->ch_flag & CH_PORT_GONE) == 0));
-
- if (retval)
- goto done;
-
- /*
- * If this is a callout device, then just make sure the normal
- * device isn't being used.
- */
-
- if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
- if (un->un_flag & UN_NORMAL_ACTIVE) {
- retval = -EBUSY;
- goto done;
- } else {
- un->un_flag |= UN_CALLOUT_ACTIVE;
- }
- }
-
- /*
- * Loop waiting until the open can be successfully completed.
- */
-
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
-
- nd->nd_tx_work = 1;
-
- for (;;) {
- wait_carrier = 0;
-
- /*
- * Determine the open type from the flags provided.
- */
-
- /*
- * If the port is not enabled, then exit
- */
- if (test_bit(TTY_IO_ERROR, &tty->flags)) {
- /* there was an error in opening the tty */
- if (un->un_flag & UN_CALLOUT_ACTIVE)
- retval = -EBUSY;
- else
- un->un_flag |= UN_NORMAL_ACTIVE;
- goto unlock;
- }
-
- if (file->f_flags & O_NONBLOCK) {
-
- /*
- * if the O_NONBLOCK is set, errors on read and write
- * must return -EAGAIN immediately and NOT sleep
- * on the waitqs.
- */
- otype = OTYPE_IMMEDIATE;
- delay_error = -EAGAIN;
-
- } else if (!OPEN_WAIT_AVAIL(category) ||
- (file->f_flags & O_NDELAY) != 0) {
- otype = OTYPE_IMMEDIATE;
- delay_error = -EBUSY;
-
- } else if (!OPEN_WAIT_CARRIER(category) ||
- ((ch->ch_digi.digi_flags & DIGI_FORCEDCD) != 0) ||
- C_CLOCAL(tty)) {
- otype = OTYPE_PERSISTENT;
- delay_error = 0;
-
- } else {
- otype = OTYPE_INCOMING;
- delay_error = 0;
- }
-
- /*
- * Handle port currently outside physical port range.
- */
-
- if (port >= nd->nd_chan_count) {
- if (otype == OTYPE_IMMEDIATE) {
- retval = (nd->nd_state == NS_READY) ?
- -ENXIO : -EAGAIN;
- goto unlock;
- }
- }
-
- /*
- * Handle port not currently open.
- */
-
- else if (ch->ch_open_count == 0) {
- /*
- * Return an error when an Incoming Open
- * response indicates the port is busy.
- */
-
- if (ch->ch_open_error != 0 && otype == ch->ch_otype) {
- retval = (ch->ch_open_error <= 2) ?
- delay_error : -ENXIO;
- goto unlock;
- }
-
- /*
- * Fail any new Immediate open if we do not have
- * a normal connection to the server.
- */
-
- if (nd->nd_state != NS_READY &&
- otype == OTYPE_IMMEDIATE) {
- retval = -EAGAIN;
- goto unlock;
- }
-
- /*
- * If a Realport open of the correct type has
- * succeeded, complete the open.
- */
-
- if (ch->ch_state == CS_READY && ch->ch_otype == otype)
- break;
- }
-
- /*
- * Handle port already open and active as a device
- * of same category.
- */
-
- else if ((ch->ch_category == category) ||
- IS_PRINT(MINOR(tty_devnum(tty)))) {
- /*
- * Fail if opening the device now would
- * violate exclusive use.
- */
- unf = ch->ch_tun.un_flag | ch->ch_pun.un_flag;
-
- if ((file->f_flags & O_EXCL) || (unf & UN_EXCL)) {
- retval = -EBUSY;
- goto unlock;
- }
-
- /*
- * If the open device is in the hangup state, all
- * system calls fail except close().
- */
-
- /* TODO : check on hangup_p calls */
-
- if (ch->ch_flag & CH_HANGUP) {
- retval = -ENXIO;
- goto unlock;
- }
-
- /*
- * If the port is ready, and carrier is ignored
- * or present, then complete the open.
- */
-
- if (ch->ch_state == CS_READY &&
- (otype != OTYPE_INCOMING ||
- ch->ch_flag & CH_VIRT_CD))
- break;
-
- wait_carrier = 1;
- }
-
- /*
- * Handle port active with a different category device.
- */
-
- else {
- if (otype == OTYPE_IMMEDIATE) {
- retval = delay_error;
- goto unlock;
- }
- }
-
- /*
- * Wait until conditions change, then take another
- * try at the open.
- */
-
- ch->ch_wait_count[otype]++;
-
- if (wait_carrier)
- ch->ch_wait_carrier++;
-
- /*
- * Prepare the task to accept the wakeup, then
- * release our locks and release control.
- */
-
- add_wait_queue(&ch->ch_flag_wait, &wait);
- current->state = TASK_INTERRUPTIBLE;
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-
- /*
- * Give up control, we'll come back if we're
- * interrupted or are woken up.
- */
- schedule();
- remove_wait_queue(&ch->ch_flag_wait, &wait);
-
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
-
- current->state = TASK_RUNNING;
-
- ch->ch_wait_count[otype]--;
-
- if (wait_carrier)
- ch->ch_wait_carrier--;
-
- nd->nd_tx_work = 1;
-
- if (signal_pending(current)) {
- retval = -EINTR;
- goto unlock;
- }
- } /* end for(;;) */
-
- /*
- * The open has succeeded. No turning back.
- */
- counts_were_incremented = 1;
- un->un_open_count++;
- ch->ch_open_count++;
-
- /*
- * Initialize the channel, if it's not already open.
- */
-
- if (ch->ch_open_count == 1) {
- ch->ch_flag = 0;
- ch->ch_inwait = 0;
- ch->ch_category = category;
- ch->ch_pscan_state = 0;
-
- /* TODO : find out what PS-1 bug Gene was referring to */
- /* TODO : in the following comment. */
-
- ch->ch_send = RR_TX_START | RR_RX_START; /* PS-1 bug */
-
- if (C_CLOCAL(tty) ||
- ch->ch_s_mlast & DM_CD ||
- ch->ch_digi.digi_flags & DIGI_FORCEDCD)
- ch->ch_flag |= CH_VIRT_CD;
- else if (OPEN_FORCES_CARRIER(category))
- ch->ch_flag |= CH_VIRT_CD;
-
- }
-
- /*
- * Initialize the unit, if it is not already open.
- */
-
- if (un->un_open_count == 1) {
- /*
- * Since all terminal options are always sticky in Linux,
- * we don't need the UN_STICKY flag to be handled specially.
- */
- /* clears all the digi flags, leaves serial flags */
- un->un_flag &= ~UN_DIGI_MASK;
-
- if (file->f_flags & O_EXCL)
- un->un_flag |= UN_EXCL;
-
- /* TODO : include "session" and "pgrp" */
-
- /*
- * In Linux, all terminal parameters are intended to be sticky.
- * as a result, we "remove" the code which once reset the ports
- * to sane values.
- */
-
- drp_param(ch);
-
- }
-
- un->un_flag |= UN_INITIALIZED;
-
- retval = 0;
-
-unlock:
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-
-done:
- /*
- * Linux does a close for every open, even failed ones!
- */
- if (!counts_were_incremented) {
- un->un_open_count++;
- ch->ch_open_count++;
- }
-
- if (retval)
- dev_err(tty->dev, "tty open bad return (%i)\n", retval);
-
- return retval;
-}
-
-
-
-
-/*
- * dgrp_tty_close() -- close function for tty_operations
- */
-static void dgrp_tty_close(struct tty_struct *tty, struct file *file)
-{
- struct ch_struct *ch;
- struct un_struct *un;
- struct nd_struct *nd;
- int tpos;
- int port;
- int err = 0;
- int s = 0;
- ulong waketime;
- ulong lock_flags;
- int sent_printer_offstr = 0;
-
- port = PORT_NUM(MINOR(tty_devnum(tty)));
-
- un = tty->driver_data;
-
- if (!un)
- return;
-
- ch = un->un_ch;
-
- if (!ch)
- return;
-
- nd = ch->ch_nd;
-
- if (!nd)
- return;
-
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
-
-
- /* Used to be on channel basis, now we check on a unit basis. */
- if (un->un_open_count != 1)
- goto unlock;
-
- /*
- * OK, its the last close on the unit
- */
- un->un_flag |= UN_CLOSING;
-
- /*
- * Notify the discipline to only process XON/XOFF characters.
- */
- tty->closing = 1;
-
- /*
- * Wait for output to drain only if this is
- * the last close against the channel
- */
-
- if (ch->ch_open_count == 1) {
- /*
- * If its the print device, we need to ensure at all costs that
- * the offstr will fit. If it won't, flush our tbuf.
- */
- if (IS_PRINT(MINOR(tty_devnum(tty))) &&
- (((ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK) <
- ch->ch_digi.digi_offlen))
- ch->ch_tin = ch->ch_tout;
-
- /*
- * Turn off the printer. Don't bother checking to see if its
- * IS_PRINT... Since this is the last close the flag is going
- * to be cleared, so we MUST make sure the offstr gets inserted
- * into tbuf.
- */
-
- if ((ch->ch_flag & CH_PRON) != 0) {
- drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
- ch->ch_digi.digi_offlen);
- ch->ch_flag &= ~CH_PRON;
- sent_printer_offstr = 1;
- }
- }
-
- /*
- * Wait until either the output queue has drained, or we see
- * absolutely no progress for 15 seconds.
- */
-
- tpos = ch->ch_s_tpos;
-
- waketime = jiffies + 15 * HZ;
-
- for (;;) {
-
- /*
- * Make sure the port still exists.
- */
-
- if (port >= nd->nd_chan_count) {
- err = 1;
- break;
- }
-
- if (signal_pending(current)) {
- err = 1;
- break;
- }
-
- /*
- * If the port is idle (not opened on the server), we have
- * no way of draining/flushing/closing the port on that server.
- * So break out of loop.
- */
- if (ch->ch_state == CS_IDLE)
- break;
-
- nd->nd_tx_work = 1;
-
- /*
- * Exit if the queues for this unit are empty,
- * and either the other unit is still open or all
- * data has drained.
- */
-
- if ((un->un_tty)->ops->chars_in_buffer ?
- ((un->un_tty)->ops->chars_in_buffer)(un->un_tty) == 0 : 1) {
-
- /*
- * We don't need to wait for a buffer to drain
- * if the other unit is open.
- */
-
- if (ch->ch_open_count != un->un_open_count)
- break;
-
- /*
- * The wait is complete when all queues are
- * drained, and any break in progress is complete.
- */
-
- if (ch->ch_tin == ch->ch_tout &&
- ch->ch_s_tin == ch->ch_s_tpos &&
- (ch->ch_send & RR_TX_BREAK) == 0) {
- break;
- }
- }
-
- /*
- * Flush TX data and exit the wait if NDELAY is set,
- * or this is not a DIGI printer, and the close timeout
- * expires.
- */
-
- if ((file->f_flags & (O_NDELAY | O_NONBLOCK)) ||
- ((long)(jiffies - waketime) >= 0 &&
- (ch->ch_digi.digi_flags & DIGI_PRINTER) == 0)) {
-
- /*
- * If we sent the printer off string, we cannot
- * flush our internal buffers, or we might lose
- * the offstr.
- */
- if (!sent_printer_offstr)
- dgrp_tty_flush_buffer(tty);
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
- tty_ldisc_flush(tty);
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
- break;
- }
-
- /*
- * Otherwise take a short nap.
- */
-
- ch->ch_flag |= CH_DRAIN;
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-
- schedule_timeout_interruptible(1);
- s = signal_pending(current);
-
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
-
- if (s) {
- /*
- * If we had sent the printer off string, we now have
- * some problems.
- *
- * The system won't let us sleep since we got an error
- * back from sleep, presumably because the user did
- * a ctrl-c...
- * But we need to ensure that the offstr gets sent!
- * Thus, we have to do something else besides sleeping.
- * The plan:
- * 1) Make this task uninterruptable.
- * 2) Set up a timer to go off in 1 sec.
- * 3) Act as tho we just got out of the sleep above.
- *
- * Thankfully, in the real world, this just
- * never happens.
- */
-
- if (sent_printer_offstr) {
- spin_unlock_irqrestore(&nd->nd_lock,
- lock_flags);
- drp_my_sleep(ch);
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
- } else {
- err = 1;
- break;
- }
- }
-
- /*
- * Restart the wait if any progress is seen.
- */
-
- if (ch->ch_s_tpos != tpos) {
- tpos = ch->ch_s_tpos;
-
- /* TODO: this gives us timeout problems with nist ?? */
- waketime = jiffies + 15 * HZ;
- }
- }
-
- /*
- * Close the line discipline
- */
-
- /* this is done in tty_io.c */
- /* if ((un->un_tty)->ldisc.close)
- * ((un->un_tty)->ldisc.close)(un->un_tty);
- */
-
- /* don't do this here */
- /* un->un_flag = 0; */
-
- /*
- * Flush the receive buffer on terminal unit close only.
- */
-
- if (!IS_PRINT(MINOR(tty_devnum(tty))))
- ch->ch_rout = ch->ch_rin;
-
-
- /*
- * Don't permit the close to happen until we get any pending
- * sync request responses.
- * There could be other ports depending upon the response as well.
- *
- * Also, don't permit the close to happen until any parameter
- * changes have been sent out from the state machine as well.
- * This is required because of a ditty -a race with -HUPCL
- * We MUST make sure all channel parameters have been sent to the
- * Portserver before sending a close.
- */
-
- if ((err != 1) && (ch->ch_state != CS_IDLE)) {
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
- s = wait_event_interruptible(ch->ch_flag_wait,
- ((ch->ch_flag & (CH_WAITING_SYNC | CH_PARAM)) == 0));
- spin_lock_irqsave(&nd->nd_lock, lock_flags);
- }
-
- /*
- * Cleanup the channel if last unit open.
- */
-
- if (ch->ch_open_count == 1) {
- ch->ch_flag = 0;
- ch->ch_category = 0;
- ch->ch_send = 0;
- ch->ch_expect = 0;
- ch->ch_tout = ch->ch_tin;
- /* (un->un_tty)->device = 0; */
-
- if (ch->ch_state == CS_READY)
- ch->ch_state = CS_SEND_CLOSE;
- }
-
- /*
- * Send the changes to the server
- */
- if (ch->ch_state != CS_IDLE) {
- ch->ch_flag |= CH_PARAM;
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
- nd->nd_tx_work = 1;
- nd->nd_tx_ready = 1;
-
-unlock:
- tty->closing = 0;
-
- if (ch->ch_open_count <= 0)
- dev_info(tty->dev,
- "%s - unexpected value for ch->ch_open_count: %i\n",
- __func__, ch->ch_open_count);
- else
- ch->ch_open_count--;
-
- if (un->un_open_count <= 0)
- dev_info(tty->dev,
- "%s - unexpected value for un->un_open_count: %i\n",
- __func__, un->un_open_count);
- else
- un->un_open_count--;
-
- un->un_flag &= ~(UN_NORMAL_ACTIVE | UN_CALLOUT_ACTIVE | UN_CLOSING);
- if (waitqueue_active(&un->un_close_wait))
- wake_up_interruptible(&un->un_close_wait);
-
- spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
-
- return;
-
-}
-
-static void drp_wmove(struct ch_struct *ch, int from_user, void *buf, int count)
-{
- int n;
- int ret = 0;
-
- ch->ch_nd->nd_tx_work = 1;
-
- n = TBUF_MAX - ch->ch_tin;
-
- if (count >= n) {
- if (from_user)
- ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
- (void __user *) buf, n);
- else
- memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
-
- buf = (char *) buf + n;
- count -= n;
- ch->ch_tin = 0;
- }
-
- if (from_user)
- ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
- (void __user *) buf, count);
- else
- memcpy(ch->ch_tbuf + ch->ch_tin, buf, count);
-
- ch->ch_tin += count;
-}
-
-
-static int dgrp_calculate_txprint_bounds(struct ch_struct *ch, int space,
- int *un_flag)
-{
- clock_t tt;
- clock_t mt;
- unsigned short tmax = 0;
-
- /*
- * If the terminal device is busy, reschedule when
- * the terminal device becomes idle.
- */
-
- if (ch->ch_tun.un_open_count != 0 &&
- ch->ch_tun.un_tty->ops->chars_in_buffer &&
- ((ch->ch_tun.un_tty->ops->chars_in_buffer)
- (ch->ch_tun.un_tty) != 0)) {
- *un_flag = UN_PWAIT;
- return 0;
- }
-
- /*
- * Assure that whenever there is printer data in the output
- * buffer, there always remains enough space after it to
- * turn the printer off.
- */
- space -= ch->ch_digi.digi_offlen;
-
- if (space <= 0) {
- *un_flag = UN_EMPTY;
- return 0;
- }
-
- /*
- * We measure printer CPS speed by incrementing
- * ch_cpstime by (HZ / digi_maxcps) for every
- * character we output, restricting output so
- * that ch_cpstime never exceeds lbolt.
- *
- * However if output has not been done for some
- * time, lbolt will grow to very much larger than
- * ch_cpstime, which would allow essentially
- * unlimited amounts of output until ch_cpstime
- * finally caught up. To avoid this, we adjust
- * cps_time when necessary so the difference
- * between lbolt and ch_cpstime never results
- * in sending more than digi_bufsize characters.
- *
- * This nicely models a printer with an internal
- * buffer of digi_bufsize characters.
- *
- * Get the time between lbolt and ch->ch_cpstime;
- */
-
- tt = jiffies - ch->ch_cpstime;
-
- /*
- * Compute the time required to send digi_bufsize
- * characters.
- */
-
- mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
-
- /*
- * Compute the number of characters that can be sent
- * without violating the time constraint. If the
- * direct calculation of this number is bigger than
- * digi_bufsize, limit the number to digi_bufsize,
- * and adjust cpstime to match.
- */
-
- if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
- tmax = ch->ch_digi.digi_bufsize;
- ch->ch_cpstime = jiffies - mt;
- } else {
- tmax = ch->ch_digi.digi_maxcps * tt / HZ;
- }
-
- /*
- * If the time constraint now binds, limit the transmit
- * count accordingly, and tentatively arrange to be
- * rescheduled based on time.
- */
-
- if (tmax < space) {
- *un_flag = UN_TIME;
- space = tmax;
- }
-
- /*
- * Compute the total number of characters we can
- * output before the total number of characters known
- * to be in the output queue exceeds digi_maxchar.
- */
-
- tmax = (ch->ch_digi.digi_maxchar -
- ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
- ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
-
-
- /*
- * If the digi_maxchar constraint now holds, limit
- * the transmit count accordingly, and arrange to
- * be rescheduled when the queue becomes empty.
- */
-
- if (space > tmax) {
- *un_flag = UN_EMPTY;
- space = tmax;
- }
-
- if (space <= 0)
- *un_flag |= UN_EMPTY;
-
- return space;
-}
-
-
-static int dgrp_tty_write(struct tty_struct *tty,
- const unsigned char *buf,
- int count)
-{
- struct nd_struct *nd;
- struct un_struct *un;
- struct ch_struct *ch;
- int space;
- int n;
- int t;
- int sendcount;
- int un_flag;
- ulong lock_flags;
-
- if (tty == NULL)
- return 0;
-
- un = tty->driver_data;
- if (!un)
- return 0;
-
- ch = un->un_ch;
- if (!ch)
- return 0;
-
- nd = ch->ch_nd;
- if (!nd)
- return 0;
-
- /*
- * Ignore the request if the channel is not ready.
- */
- if (ch->ch_state != CS_READY)
- return 0;
-
- spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
-
- /*
- * Ignore the request if output is blocked.
- */
- if ((un->un_flag & (UN_EMPTY | UN_LOW | UN_TIME | UN_PWAIT)) != 0) {
- count = 0;
- goto out;
- }
-
- /*
- * Also ignore the request if DPA has this port open,
- * and is flow controlled on reading more data.
- */
- if (nd->nd_dpa_debug && nd->nd_dpa_flag & DPA_WAIT_SPACE &&
- nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))) {
- count = 0;
- goto out;
- }
-
- /*
- * Limit amount we will write to the amount of space
- * available in the channel buffer.
- */
- sendcount = 0;
-
- space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
-
- /*
- * Handle the printer device.
- */
-
- un_flag = UN_LOW;
-
- if (IS_PRINT(MINOR(tty_devnum(tty)))) {
- clock_t tt;
- clock_t mt;
- unsigned short tmax = 0;
-
- /*
- * If the terminal device is busy, reschedule when
- * the terminal device becomes idle.
- */
-
- if (ch->ch_tun.un_open_count != 0 &&
- ((ch->ch_tun.un_tty->ops->chars_in_buffer)
- (ch->ch_tun.un_tty) != 0)) {
- un->un_flag |= UN_PWAIT;
- count = 0;
- goto out;
- }
-
- /*
- * Assure that whenever there is printer data in the output
- * buffer, there always remains enough space after it to
- * turn the printer off.
- */
- space -= ch->ch_digi.digi_offlen;
-
- /*
- * Output the printer on string.
- */
-
- if ((ch->ch_flag & CH_PRON) == 0) {
- space -= ch->ch_digi.digi_onlen;
-
- if (space < 0) {
- un->un_flag |= UN_EMPTY;
- (ch->ch_nd)->nd_tx_work = 1;
- count = 0;
- goto out;
- }
-
- drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
- ch->ch_digi.digi_onlen);
-
- ch->ch_flag |= CH_PRON;
- }
-
- /*
- * We measure printer CPS speed by incrementing
- * ch_cpstime by (HZ / digi_maxcps) for every
- * character we output, restricting output so
- * that ch_cpstime never exceeds lbolt.
- *
- * However if output has not been done for some
- * time, lbolt will grow to very much larger than
- * ch_cpstime, which would allow essentially
- * unlimited amounts of output until ch_cpstime
- * finally caught up. To avoid this, we adjust
- * cps_time when necessary so the difference
- * between lbolt and ch_cpstime never results
- * in sending more than digi_bufsize characters.
- *
- * This nicely models a printer with an internal
- * buffer of digi_bufsize characters.
- *
- * Get the time between lbolt and ch->ch_cpstime;
- */
-
- tt = jiffies - ch->ch_cpstime;
-
- /*
- * Compute the time required to send digi_bufsize
- * characters.
- */
-
- mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
-
- /*
- * Compute the number of characters that can be sent
- * without violating the time constraint. If the
- * direct calculation of this number is bigger than
- * digi_bufsize, limit the number to digi_bufsize,
- * and adjust cpstime to match.
- */
-
- if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
- tmax = ch->ch_digi.digi_bufsize;
- ch->ch_cpstime = jiffies - mt;
- } else {
- tmax = ch->ch_digi.digi_maxcps * tt / HZ;
- }
-
- /*
- * If the time constraint now binds, limit the transmit
- * count accordingly, and tentatively arrange to be
- * rescheduled based on time.
- */
-
- if (tmax < space) {
- space = tmax;
- un_flag = UN_TIME;
- }
-
- /*
- * Compute the total number of characters we can
- * output before the total number of characters known
- * to be in the output queue exceeds digi_maxchar.
- */
-
- tmax = (ch->ch_digi.digi_maxchar -
- ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
- ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
-
-
- /*
- * If the digi_maxchar constraint now holds, limit
- * the transmit count accordingly, and arrange to
- * be rescheduled when the queue becomes empty.
- */
-
- if (space > tmax) {
- space = tmax;
- un_flag = UN_EMPTY;
- }
-
- }
- /*
- * Handle the terminal device.
- */
- else {
-
- /*
- * If the printer device is on, turn it off.
- */
-
- if ((ch->ch_flag & CH_PRON) != 0) {
-
- space -= ch->ch_digi.digi_offlen;
-
- drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
- ch->ch_digi.digi_offlen);
-
- ch->ch_flag &= ~CH_PRON;
- }
- }
-
- /*
- * If space is 0 and its because the ch->tbuf
- * is full, then Linux will handle a callback when queue
- * space becomes available.
- * tty_write returns count = 0
- */
-
- if (space <= 0) {
- /* the linux tty_io.c handles this if we return 0 */
- /* if (fp->flags & O_NONBLOCK) return -EAGAIN; */
-
- un->un_flag |= UN_EMPTY;
- (ch->ch_nd)->nd_tx_work = 1;
- count = 0;
- goto out;
- }
-
- count = min(count, space);
-
- if (count > 0) {
-
- un->un_tbusy++;
-
- /*
- * Copy the buffer contents to the ch_tbuf
- * being careful to wrap around the circular queue
- */
-
- t = TBUF_MAX - ch->ch_tin;
- n = count;
-
- if (n >= t) {
- memcpy(ch->ch_tbuf + ch->ch_tin, buf, t);
- if (nd->nd_dpa_debug && nd->nd_dpa_port ==
- PORT_NUM(MINOR(tty_devnum(un->un_tty))))
- dgrp_dpa_data(nd, 0, (char *) buf, t);
- buf += t;
- n -= t;
- ch->ch_tin = 0;
- sendcount += n;
- }
-
- memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
- if (nd->nd_dpa_debug && nd->nd_dpa_port ==
- PORT_NUM(MINOR(tty_devnum(un->un_tty))))
- dgrp_dpa_data(nd, 0, (char *) buf, n);
- buf += n;
- ch->ch_tin += n;
- sendcount += n;
-
- un->un_tbusy--;
- (ch->ch_nd)->nd_tx_work = 1;
- if (ch->ch_edelay != DGRP_RTIME) {
- (ch->ch_nd)->nd_tx_ready = 1;
- wake_up_interruptible(&nd->nd_tx_waitq);
- }
- }
-
- ch->ch_txcount += count;
-
- if (IS_PRINT(MINOR(tty_devnum(tty)))) {
-
- /*
- * Adjust ch_cpstime to account
- * for the characters just output.
- */
-
- if (sendcount > 0) {
- int cc = HZ * sendcount + ch->ch_cpsrem;
-
- ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
- ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
- }
-
- /*
- * If we are now waiting on time, schedule ourself
- * back when we'll be able to send a block of
- * digi_maxchar characters.
- */
-
- if ((un_flag & UN_TIME) != 0) {
- ch->ch_waketime = (ch->ch_cpstime +
- (ch->ch_digi.digi_maxchar * HZ /
- ch->ch_digi.digi_maxcps));
- }
- }
-
- /*
- * If the printer unit is waiting for completion
- * of terminal output, get him going again.
- */
-
- if ((ch->ch_pun.un_flag & UN_PWAIT) != 0)
- (ch->ch_nd)->nd_tx_work = 1;
-
-out:
- spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
-
- return count;
-}
-
-
-/*
- * Put a character into ch->ch_buf
- *
- * - used by the line discipline for OPOST processing
- */
-
-static int dgrp_tty_put_char(struct tty_struct *tty, unsigned char new_char)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- ulong lock_flags;
- int space;
- int retval = 0;
-
- if (tty == NULL)
- return 0;
-
- un = tty->driver_data;
- if (!un)
- return 0;
-
- ch = un->un_ch;
- if (!ch)
- return 0;
-
- if (ch->ch_state != CS_READY)
- return 0;
-
- spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
-
-
- /*
- * If space is 0 and its because the ch->tbuf
- * Warn and dump the character, there isn't anything else
- * we can do about it. David_Fries@digi.com
- */
-
- space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
-
- un->un_tbusy++;
-
- /*
- * Output the printer on string if device is TXPrint.
- */
- if (IS_PRINT(MINOR(tty_devnum(tty))) && (ch->ch_flag & CH_PRON) == 0) {
- if (space < ch->ch_digi.digi_onlen) {
- un->un_tbusy--;
- goto out;
- }
- space -= ch->ch_digi.digi_onlen;
- drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
- ch->ch_digi.digi_onlen);
- ch->ch_flag |= CH_PRON;
- }
-
- /*
- * Output the printer off string if device is NOT TXPrint.
- */
-
- if (!IS_PRINT(MINOR(tty_devnum(tty))) &&
- ((ch->ch_flag & CH_PRON) != 0)) {
- if (space < ch->ch_digi.digi_offlen) {
- un->un_tbusy--;
- goto out;
- }
-
- space -= ch->ch_digi.digi_offlen;
- drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
- ch->ch_digi.digi_offlen);
- ch->ch_flag &= ~CH_PRON;
- }
-
- if (!space) {
- un->un_tbusy--;
- goto out;
- }
-
- /*
- * Copy the character to the ch_tbuf being
- * careful to wrap around the circular queue
- */
- ch->ch_tbuf[ch->ch_tin] = new_char;
- ch->ch_tin = (1 + ch->ch_tin) & TBUF_MASK;
-
- if (IS_PRINT(MINOR(tty_devnum(tty)))) {
-
- /*
- * Adjust ch_cpstime to account
- * for the character just output.
- */
-
- int cc = HZ + ch->ch_cpsrem;
-
- ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
- ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
-
- /*
- * If we are now waiting on time, schedule ourself
- * back when we'll be able to send a block of
- * digi_maxchar characters.
- */
-
- ch->ch_waketime = (ch->ch_cpstime +
- (ch->ch_digi.digi_maxchar * HZ /
- ch->ch_digi.digi_maxcps));
- }
-
-
- un->un_tbusy--;
- (ch->ch_nd)->nd_tx_work = 1;
-
- retval = 1;
-out:
- spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
- return retval;
-}
-
-
-
-/*
- * Flush TX buffer (make in == out)
- *
- * check tty_ioctl.c -- this is called after TCOFLUSH
- */
-static void dgrp_tty_flush_buffer(struct tty_struct *tty)
-{
- struct un_struct *un;
- struct ch_struct *ch;
-
- if (!tty)
- return;
- un = tty->driver_data;
- if (!un)
- return;
-
- ch = un->un_ch;
- if (!ch)
- return;
-
- ch->ch_tout = ch->ch_tin;
- /* do NOT do this here! */
- /* ch->ch_s_tpos = ch->ch_s_tin = 0; */
-
- /* send the flush output command now */
- ch->ch_send |= RR_TX_FLUSH;
- (ch->ch_nd)->nd_tx_ready = 1;
- (ch->ch_nd)->nd_tx_work = 1;
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-
- if (waitqueue_active(&tty->write_wait))
- wake_up_interruptible(&tty->write_wait);
-
- tty_wakeup(tty);
-
-}
-
-/*
- * Return space available in Tx buffer
- * count = ( ch->ch_tout - ch->ch_tin ) mod (TBUF_MAX - 1)
- */
-static int dgrp_tty_write_room(struct tty_struct *tty)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int count;
-
- if (!tty)
- return 0;
-
- un = tty->driver_data;
- if (!un)
- return 0;
-
- ch = un->un_ch;
- if (!ch)
- return 0;
-
- count = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
-
- /* We *MUST* check this, and return 0 if the Printer Unit cannot
- * take any more data within its time constraints... If we don't
- * return 0 and the printer has hit it time constraint, the ld will
- * call us back doing a put_char, which cannot be rejected!!!
- */
- if (IS_PRINT(MINOR(tty_devnum(tty)))) {
- int un_flag = 0;
- count = dgrp_calculate_txprint_bounds(ch, count, &un_flag);
- if (count <= 0)
- count = 0;
-
- ch->ch_pun.un_flag |= un_flag;
- (ch->ch_nd)->nd_tx_work = 1;
- }
-
- return count;
-}
-
-/*
- * Return number of characters that have not been transmitted yet.
- * chars_in_buffer = ( ch->ch_tin - ch->ch_tout ) mod (TBUF_MAX - 1)
- * + ( ch->ch_s_tin - ch->ch_s_tout ) mod (0xffff)
- * = number of characters "in transit"
- *
- * Remember that sequence number math is always with a sixteen bit
- * mask, not the TBUF_MASK.
- */
-
-static int dgrp_tty_chars_in_buffer(struct tty_struct *tty)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int count;
- int count1;
-
- if (!tty)
- return 0;
-
- un = tty->driver_data;
- if (!un)
- return 0;
-
- ch = un->un_ch;
- if (!ch)
- return 0;
-
- count1 = count = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
- count += (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
- /* one for tbuf, one for the PS */
-
- /*
- * If we are busy transmitting add 1
- */
- count += un->un_tbusy;
-
- return count;
-}
-
-
-/*****************************************************************************
- *
- * Helper applications for dgrp_tty_ioctl()
- *
- *****************************************************************************
- */
-
-
-/**
- * ch_to_tty_flags() -- convert channel flags to termio flags
- * @ch_flag: Digi channel flags
- * @flagtype: type of ch_flag (iflag, oflag or cflag)
- *
- * take the channel flags of the specified type and return the
- * corresponding termio flag
- */
-static tcflag_t ch_to_tty_flags(ushort ch_flag, char flagtype)
-{
- tcflag_t retval = 0;
-
- switch (flagtype) {
- case 'i':
- retval = ((ch_flag & IF_IGNBRK) ? IGNBRK : 0)
- | ((ch_flag & IF_BRKINT) ? BRKINT : 0)
- | ((ch_flag & IF_IGNPAR) ? IGNPAR : 0)
- | ((ch_flag & IF_PARMRK) ? PARMRK : 0)
- | ((ch_flag & IF_INPCK) ? INPCK : 0)
- | ((ch_flag & IF_ISTRIP) ? ISTRIP : 0)
- | ((ch_flag & IF_IXON) ? IXON : 0)
- | ((ch_flag & IF_IXANY) ? IXANY : 0)
- | ((ch_flag & IF_IXOFF) ? IXOFF : 0);
- break;
-
- case 'o':
- retval = ((ch_flag & OF_OLCUC) ? OLCUC : 0)
- | ((ch_flag & OF_ONLCR) ? ONLCR : 0)
- | ((ch_flag & OF_OCRNL) ? OCRNL : 0)
- | ((ch_flag & OF_ONOCR) ? ONOCR : 0)
- | ((ch_flag & OF_ONLRET) ? ONLRET : 0)
- /* | ((ch_flag & OF_OTAB3) ? OFILL : 0) */
- | ((ch_flag & OF_TABDLY) ? TABDLY : 0);
- break;
-
- case 'c':
- retval = ((ch_flag & CF_CSTOPB) ? CSTOPB : 0)
- | ((ch_flag & CF_CREAD) ? CREAD : 0)
- | ((ch_flag & CF_PARENB) ? PARENB : 0)
- | ((ch_flag & CF_PARODD) ? PARODD : 0)
- | ((ch_flag & CF_HUPCL) ? HUPCL : 0);
-
- switch (ch_flag & CF_CSIZE) {
- case CF_CS5:
- retval |= CS5;
- break;
- case CF_CS6:
- retval |= CS6;
- break;
- case CF_CS7:
- retval |= CS7;
- break;
- case CF_CS8:
- retval |= CS8;
- break;
- default:
- retval |= CS8;
- break;
- }
- break;
- case 'x':
- break;
- case 'l':
- break;
- default:
- return 0;
- }
-
- return retval;
-}
-
-
-/**
- * tty_to_ch_flags() -- convert termio flags to digi channel flags
- * @tty: pointer to a TTY structure holding flag to be converted
- * @flagtype: identifies which flag (iflags, oflags, or cflags) should
- * be converted
- *
- * take the termio flag of the specified type and return the
- * corresponding Digi version of the flags
- */
-static ushort tty_to_ch_flags(struct tty_struct *tty, char flagtype)
-{
- ushort retval = 0;
- tcflag_t tflag = 0;
-
- switch (flagtype) {
- case 'i':
- tflag = tty->termios.c_iflag;
- retval = (I_IGNBRK(tty) ? IF_IGNBRK : 0)
- | (I_BRKINT(tty) ? IF_BRKINT : 0)
- | (I_IGNPAR(tty) ? IF_IGNPAR : 0)
- | (I_PARMRK(tty) ? IF_PARMRK : 0)
- | (I_INPCK(tty) ? IF_INPCK : 0)
- | (I_ISTRIP(tty) ? IF_ISTRIP : 0)
- | (I_IXON(tty) ? IF_IXON : 0)
- | (I_IXANY(tty) ? IF_IXANY : 0)
- | (I_IXOFF(tty) ? IF_IXOFF : 0);
- break;
- case 'o':
- tflag = tty->termios.c_oflag;
- /*
- * If OPOST is set, then do the post processing in the
- * firmware by setting all the processing flags on.
- * If ~OPOST, then make sure we are not doing any
- * output processing!!
- */
- if (!O_OPOST(tty))
- retval = 0;
- else
- retval = (O_OLCUC(tty) ? OF_OLCUC : 0)
- | (O_ONLCR(tty) ? OF_ONLCR : 0)
- | (O_OCRNL(tty) ? OF_OCRNL : 0)
- | (O_ONOCR(tty) ? OF_ONOCR : 0)
- | (O_ONLRET(tty) ? OF_ONLRET : 0)
- /* | (O_OFILL(tty) ? OF_TAB3 : 0) */
- | (O_TABDLY(tty) ? OF_TABDLY : 0);
- break;
- case 'c':
- tflag = tty->termios.c_cflag;
- retval = (C_CSTOPB(tty) ? CF_CSTOPB : 0)
- | (C_CREAD(tty) ? CF_CREAD : 0)
- | (C_PARENB(tty) ? CF_PARENB : 0)
- | (C_PARODD(tty) ? CF_PARODD : 0)
- | (C_HUPCL(tty) ? CF_HUPCL : 0);
- switch (C_CSIZE(tty)) {
- case CS8:
- retval |= CF_CS8;
- break;
- case CS7:
- retval |= CF_CS7;
- break;
- case CS6:
- retval |= CF_CS6;
- break;
- case CS5:
- retval |= CF_CS5;
- break;
- default:
- retval |= CF_CS8;
- break;
- }
- break;
- case 'x':
- break;
- case 'l':
- break;
- default:
- return 0;
- }
-
- return retval;
-}
-
-
-static int dgrp_tty_send_break(struct tty_struct *tty, int msec)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int ret = -EIO;
-
- if (!tty)
- return ret;
-
- un = tty->driver_data;
- if (!un)
- return ret;
-
- ch = un->un_ch;
- if (!ch)
- return ret;
-
- dgrp_send_break(ch, msec);
- return 0;
-}
-
-
-/*
- * This routine sends a break character out the serial port.
- *
- * duration is in 1/1000's of a second
- */
-static int dgrp_send_break(struct ch_struct *ch, int msec)
-{
- ulong x;
-
- wait_event_interruptible(ch->ch_flag_wait,
- ((ch->ch_flag & CH_TX_BREAK) == 0));
- ch->ch_break_time += max(msec, 250);
- ch->ch_send |= RR_TX_BREAK;
- ch->ch_flag |= CH_TX_BREAK;
- (ch->ch_nd)->nd_tx_work = 1;
-
- x = (msec * HZ) / 1000;
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-
- return 0;
-}
-
-
-/*
- * Return modem signals to ld.
- */
-static int dgrp_tty_tiocmget(struct tty_struct *tty)
-{
- unsigned int mlast;
- struct un_struct *un = tty->driver_data;
- struct ch_struct *ch;
-
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
- (ch->ch_mout & (DM_RTS | DM_DTR)));
-
- /* defined in /usr/include/asm/termios.h */
- mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
- | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
- | ((mlast & DM_CD) ? TIOCM_CAR : 0)
- | ((mlast & DM_RI) ? TIOCM_RNG : 0)
- | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
- | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
-
- return mlast;
-}
-
-
-/*
- * Set modem lines
- */
-static int dgrp_tty_tiocmset(struct tty_struct *tty,
- unsigned int set, unsigned int clear)
-{
- ulong lock_flags;
- struct un_struct *un = tty->driver_data;
- struct ch_struct *ch;
-
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- if (set & TIOCM_RTS)
- ch->ch_mout |= DM_RTS;
-
- if (set & TIOCM_DTR)
- ch->ch_mout |= DM_DTR;
-
- if (clear & TIOCM_RTS)
- ch->ch_mout &= ~(DM_RTS);
-
- if (clear & TIOCM_DTR)
- ch->ch_mout &= ~(DM_DTR);
-
- spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
- ch->ch_flag |= CH_PARAM;
- (ch->ch_nd)->nd_tx_work = 1;
- wake_up_interruptible(&ch->ch_flag_wait);
-
- spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
-
- return 0;
-}
-
-
-
-/*
- * Get current modem status
- */
-static int get_modem_info(struct ch_struct *ch, unsigned int *value)
-{
- unsigned int mlast;
-
- mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
- (ch->ch_mout & (DM_RTS | DM_DTR)));
-
- /* defined in /usr/include/asm/termios.h */
- mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
- | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
- | ((mlast & DM_CD) ? TIOCM_CAR : 0)
- | ((mlast & DM_RI) ? TIOCM_RNG : 0)
- | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
- | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
- return put_user(mlast, (unsigned int __user *) value);
-}
-
-/*
- * Set modem lines
- */
-static int set_modem_info(struct ch_struct *ch, unsigned int command,
- unsigned int *value)
-{
- int error;
- unsigned int arg;
- int mval = 0;
- ulong lock_flags;
-
- error = access_ok(VERIFY_READ, (void __user *) value, sizeof(int));
- if (error == 0)
- return -EFAULT;
-
- if (get_user(arg, (unsigned int __user *) value))
- return -EFAULT;
- mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
- | ((arg & TIOCM_DTR) ? DM_DTR : 0);
-
- switch (command) {
- case TIOCMBIS: /* set flags */
- ch->ch_mout |= mval;
- break;
- case TIOCMBIC: /* clear flags */
- ch->ch_mout &= ~mval;
- break;
- case TIOCMSET:
- ch->ch_mout = mval;
- break;
- default:
- return -EINVAL;
- }
-
- spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
-
- ch->ch_flag |= CH_PARAM;
- (ch->ch_nd)->nd_tx_work = 1;
- wake_up_interruptible(&ch->ch_flag_wait);
-
- spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
-
- return 0;
-}
-
-
-/*
- * Assign the custom baud rate to the channel structure
- */
-static void dgrp_set_custom_speed(struct ch_struct *ch, int newrate)
-{
- int testdiv;
- int testrate_high;
- int testrate_low;
-
- int deltahigh, deltalow;
-
- if (newrate < 0)
- newrate = 0;
-
- /*
- * Since the divisor is stored in a 16-bit integer, we make sure
- * we don't allow any rates smaller than a 16-bit integer would allow.
- * And of course, rates above the dividend won't fly.
- */
- if (newrate && newrate < ((PORTSERVER_DIVIDEND / 0xFFFF) + 1))
- newrate = ((PORTSERVER_DIVIDEND / 0xFFFF) + 1);
- if (newrate && newrate > PORTSERVER_DIVIDEND)
- newrate = PORTSERVER_DIVIDEND;
-
- while (newrate > 0) {
- testdiv = PORTSERVER_DIVIDEND / newrate;
-
- /*
- * If we try to figure out what rate the PortServer would use
- * with the test divisor, it will be either equal or higher
- * than the requested baud rate. If we then determine the
- * rate with a divisor one higher, we will get the next lower
- * supported rate below the requested.
- */
- testrate_high = PORTSERVER_DIVIDEND / testdiv;
- testrate_low = PORTSERVER_DIVIDEND / (testdiv + 1);
-
- /*
- * If the rate for the requested divisor is correct, just
- * use it and be done.
- */
- if (testrate_high == newrate)
- break;
-
- /*
- * Otherwise, pick the rate that is closer (i.e. whichever rate
- * has a smaller delta).
- */
- deltahigh = testrate_high - newrate;
- deltalow = newrate - testrate_low;
-
- if (deltahigh < deltalow)
- newrate = testrate_high;
- else
- newrate = testrate_low;
-
- break;
- }
-
- ch->ch_custom_speed = newrate;
-
- drp_param(ch);
-
- return;
-}
-
-
-/*
- # dgrp_tty_digiseta()
- *
- * Ioctl to set the information from ditty.
- *
- * NOTE: DIGI_IXON, DSRPACE, DCDPACE, and DTRPACE are unsupported. JAR 990922
- */
-static int dgrp_tty_digiseta(struct tty_struct *tty,
- struct digi_struct *new_info)
-{
- struct un_struct *un = tty->driver_data;
- struct ch_struct *ch;
-
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- if (copy_from_user(&ch->ch_digi, (void __user *) new_info,
- sizeof(struct digi_struct)))
- return -EFAULT;
-
- if ((ch->ch_digi.digi_flags & RTSPACE) ||
- (ch->ch_digi.digi_flags & CTSPACE))
- tty->termios.c_cflag |= CRTSCTS;
- else
- tty->termios.c_cflag &= ~CRTSCTS;
-
- if (ch->ch_digi.digi_maxcps < 1)
- ch->ch_digi.digi_maxcps = 1;
-
- if (ch->ch_digi.digi_maxcps > 10000)
- ch->ch_digi.digi_maxcps = 10000;
-
- if (ch->ch_digi.digi_bufsize < 10)
- ch->ch_digi.digi_bufsize = 10;
-
- if (ch->ch_digi.digi_maxchar < 1)
- ch->ch_digi.digi_maxchar = 1;
-
- if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
- ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
-
- if (ch->ch_digi.digi_onlen > DIGI_PLEN)
- ch->ch_digi.digi_onlen = DIGI_PLEN;
-
- if (ch->ch_digi.digi_offlen > DIGI_PLEN)
- ch->ch_digi.digi_offlen = DIGI_PLEN;
-
- /* make the changes now */
- drp_param(ch);
-
- return 0;
-}
-
-
-
-/*
- * dgrp_tty_digigetedelay()
- *
- * Ioctl to get the current edelay setting.
- *
- *
- *
- */
-static int dgrp_tty_digigetedelay(struct tty_struct *tty, int *retinfo)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int tmp;
-
- if (!retinfo)
- return -EFAULT;
-
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
-
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- tmp = ch->ch_edelay;
-
- if (copy_to_user((void __user *) retinfo, &tmp, sizeof(*retinfo)))
- return -EFAULT;
-
- return 0;
-}
-
-
-/*
- * dgrp_tty_digisetedelay()
- *
- * Ioctl to set the EDELAY setting
- *
- */
-static int dgrp_tty_digisetedelay(struct tty_struct *tty, int *new_info)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int new_digi;
-
- if (!tty || tty->magic != TTY_MAGIC)
- return -EFAULT;
-
- un = tty->driver_data;
-
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- if (copy_from_user(&new_digi, (void __user *)new_info, sizeof(int)))
- return -EFAULT;
-
- ch->ch_edelay = new_digi;
-
- /* make the changes now */
- drp_param(ch);
-
- return 0;
-}
-
-
-/*
- * The usual assortment of ioctl's
- *
- * note: use tty_check_change to make sure that we are not
- * changing the state of a terminal when we are not a process
- * in the forground. See tty_io.c
- * rc = tty_check_change(tty);
- * if (rc) return rc;
- */
-static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
- unsigned long arg)
-{
- struct un_struct *un;
- struct ch_struct *ch;
- int rc;
- struct digiflow_struct dflow;
-
- if (!tty)
- return -ENODEV;
-
- un = tty->driver_data;
- if (!un)
- return -ENODEV;
-
- ch = un->un_ch;
- if (!ch)
- return -ENODEV;
-
- switch (cmd) {
-
- /*
- * Here are all the standard ioctl's that we MUST implement
- */
-
- case TCSBRK:
- /*
- * TCSBRK is SVID version: non-zero arg --> no break
- * this behaviour is exploited by tcdrain().
- *
- * According to POSIX.1 spec (7.2.2.1.2) breaks should be
- * between 0.25 and 0.5 seconds
- */
-
- rc = tty_check_change(tty);
- if (rc)
- return rc;
- tty_wait_until_sent(tty, 0);
-
- if (!arg)
- rc = dgrp_send_break(ch, 250); /* 1/4 second */
-
- if (dgrp_tty_chars_in_buffer(tty) != 0)
- return -EINTR;
-
- return 0;
-
- case TCSBRKP:
- /* support for POSIX tcsendbreak()
- *
- * According to POSIX.1 spec (7.2.2.1.2) breaks should be
- * between 0.25 and 0.5 seconds so we'll ask for something
- * in the middle: 0.375 seconds.
- */
- rc = tty_check_change(tty);
- if (rc)
- return rc;
- tty_wait_until_sent(tty, 0);
-
- rc = dgrp_send_break(ch, arg ? arg*250 : 250);
-
- if (dgrp_tty_chars_in_buffer(tty) != 0)
- return -EINTR;
- return 0;
-
- case TIOCSBRK:
- rc = tty_check_change(tty);
- if (rc)
- return rc;
- tty_wait_until_sent(tty, 0);
-
- /*
- * RealPort doesn't support turning on a break unconditionally.
- * The RealPort device will stop sending a break automatically
- * after the specified time value that we send in.
- */
- rc = dgrp_send_break(ch, 250); /* 1/4 second */
-
- if (dgrp_tty_chars_in_buffer(tty) != 0)
- return -EINTR;
- return 0;
-
- case TIOCCBRK:
- /*
- * RealPort doesn't support turning off a break unconditionally.
- * The RealPort device will stop sending a break automatically
- * after the specified time value that was sent when turning on
- * the break.
- */
- return 0;
-
- case TIOCMGET:
- rc = access_ok(VERIFY_WRITE, (void __user *) arg,
- sizeof(unsigned int));
- if (rc == 0)
- return -EFAULT;
- return get_modem_info(ch, (unsigned int *) arg);
-
- case TIOCMBIS:
- case TIOCMBIC:
- case TIOCMSET:
- return set_modem_info(ch, cmd, (unsigned int *) arg);
-
- /*
- * Here are any additional ioctl's that we want to implement
- */
-
- case TCFLSH:
- /*
- * The linux tty driver doesn't have a flush
- * input routine for the driver, assuming all backed
- * up data is in the line disc. buffers. However,
- * we all know that's not the case. Here, we
- * act on the ioctl, but then lie and say we didn't
- * so the line discipline will process the flush
- * also.
- */
- rc = tty_check_change(tty);
- if (rc)
- return rc;
-
- switch (arg) {
- case TCIFLUSH:
- case TCIOFLUSH:
- /* only flush input if this is the only open unit */
- if (!IS_PRINT(MINOR(tty_devnum(tty)))) {
- ch->ch_rout = ch->ch_rin;
- ch->ch_send |= RR_RX_FLUSH;
- (ch->ch_nd)->nd_tx_work = 1;
- (ch->ch_nd)->nd_tx_ready = 1;
- wake_up_interruptible(
- &(ch->ch_nd)->nd_tx_waitq);
- }
- if (arg == TCIFLUSH)
- break;
-
- case TCOFLUSH: /* flush output, or the receive buffer */
- /*
- * This is handled in the tty_ioctl.c code
- * calling tty_flush_buffer
- */
- break;
-
- default:
- /* POSIX.1 says return EINVAL if we got a bad arg */
- return -EINVAL;
- }
- /* pretend we didn't recognize this IOCTL */
- return -ENOIOCTLCMD;
-
-#ifdef TIOCGETP
- case TIOCGETP:
-#endif
- /*****************************************
- Linux HPUX Function
- TCSETA TCSETA - set the termios
- TCSETAF TCSETAF - wait for drain first, then set termios
- TCSETAW TCSETAW - wait for drain,
- flush the input queue, then set termios
- - looking at the tty_ioctl code, these command all call our
- tty_set_termios at the driver's end, when a TCSETA* is sent,
- it is expecting the tty to have a termio structure,
- NOT a termios structure. These two structures differ in size
- and the tty_ioctl code does a conversion before processing them both.
- - we should treat the TCSETAW TCSETAF ioctls the same, and let
- the tty_ioctl code do the conversion stuff.
-
- TCSETS
- TCSETSF (none)
- TCSETSW
- - the associated tty structure has a termios structure.
- *****************************************/
-
- case TCGETS:
- case TCGETA:
- return -ENOIOCTLCMD;
-
- case TCSETAW:
- case TCSETAF:
- case TCSETSF:
- case TCSETSW:
- /*
- * The linux tty driver doesn't have a flush
- * input routine for the driver, assuming all backed
- * up data is in the line disc. buffers. However,
- * we all know that's not the case. Here, we
- * act on the ioctl, but then lie and say we didn't
- * so the line discipline will process the flush
- * also.
- */
-
- /*
- * Also, now that we have TXPrint, we have to check
- * if this is the TXPrint device and the terminal
- * device is open. If so, do NOT run check_change,
- * as the terminal device is ALWAYS the parent.
- */
- if (!IS_PRINT(MINOR(tty_devnum(tty))) ||
- !ch->ch_tun.un_open_count) {
- rc = tty_check_change(tty);
- if (rc)
- return rc;
- }
-
- /* wait for all the characters in tbuf to drain */
- tty_wait_until_sent(tty, 0);
-
- if ((cmd == TCSETSF) || (cmd == TCSETAF)) {
- /* flush the contents of the rbuf queue */
- /* TODO: check if this is print device? */
- ch->ch_send |= RR_RX_FLUSH;
- (ch->ch_nd)->nd_tx_ready = 1;
- (ch->ch_nd)->nd_tx_work = 1;
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
- /* do we need to do this? just to be safe! */
- ch->ch_rout = ch->ch_rin;
- }
-
- /* pretend we didn't recognize this */
- return -ENOIOCTLCMD;
-
- case TCXONC:
- /*
- * The Linux Line Discipline (LD) would do this for us if we
- * let it, but we have the special firmware options to do this
- * the "right way" regardless of hardware or software flow
- * control so we'll do it outselves instead of letting the LD
- * do it.
- */
- rc = tty_check_change(tty);
- if (rc)
- return rc;
-
- switch (arg) {
- case TCOON:
- dgrp_tty_start(tty);
- return 0;
- case TCOOFF:
- dgrp_tty_stop(tty);
- return 0;
- case TCION:
- dgrp_tty_input_start(tty);
- return 0;
- case TCIOFF:
- dgrp_tty_input_stop(tty);
- return 0;
- default:
- return -EINVAL;
- }
-
- case DIGI_GETA:
- /* get information for ditty */
- if (copy_to_user((struct digi_struct __user *) arg,
- &ch->ch_digi, sizeof(struct digi_struct)))
- return -EFAULT;
- break;
-
- case DIGI_SETAW:
- case DIGI_SETAF:
- /* wait for all the characters in tbuf to drain */
- tty_wait_until_sent(tty, 0);
-
- if (cmd == DIGI_SETAF) {
- /* flush the contents of the rbuf queue */
- /* send down a packet with RR_RX_FLUSH set */
- ch->ch_send |= RR_RX_FLUSH;
- (ch->ch_nd)->nd_tx_ready = 1;
- (ch->ch_nd)->nd_tx_work = 1;
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
- /* do we need to do this? just to be safe! */
- ch->ch_rout = ch->ch_rin;
- }
-
- /* pretend we didn't recognize this */
- /* fall-through */
-
- case DIGI_SETA:
- return dgrp_tty_digiseta(tty, (struct digi_struct *) arg);
-
- case DIGI_SEDELAY:
- return dgrp_tty_digisetedelay(tty, (int *) arg);
-
- case DIGI_GEDELAY:
- return dgrp_tty_digigetedelay(tty, (int *) arg);
-
- case DIGI_GETFLOW:
- case DIGI_GETAFLOW:
- if (cmd == (DIGI_GETFLOW)) {
- dflow.startc = tty->termios.c_cc[VSTART];
- dflow.stopc = tty->termios.c_cc[VSTOP];
- } else {
- dflow.startc = ch->ch_xxon;
- dflow.stopc = ch->ch_xxoff;
- }
-
- if (copy_to_user((char __user *)arg, &dflow, sizeof(dflow)))
- return -EFAULT;
- break;
-
- case DIGI_SETFLOW:
- case DIGI_SETAFLOW:
-
- if (copy_from_user(&dflow, (char __user *)arg, sizeof(dflow)))
- return -EFAULT;
-
- if (cmd == (DIGI_SETFLOW)) {
- tty->termios.c_cc[VSTART] = dflow.startc;
- tty->termios.c_cc[VSTOP] = dflow.stopc;
- } else {
- ch->ch_xxon = dflow.startc;
- ch->ch_xxoff = dflow.stopc;
- }
- break;
-
- case DIGI_GETCUSTOMBAUD:
- if (put_user(ch->ch_custom_speed, (unsigned int __user *) arg))
- return -EFAULT;
- break;
-
- case DIGI_SETCUSTOMBAUD:
- {
- int new_rate;
-
- if (get_user(new_rate, (unsigned int __user *) arg))
- return -EFAULT;
- dgrp_set_custom_speed(ch, new_rate);
-
- break;
- }
-
- default:
- return -ENOIOCTLCMD;
- }
-
- return 0;
-}
-
-/*
- * This routine allows the tty driver to be notified when
- * the device's termios setting have changed. Note that we
- * should be prepared to accept the case where old == NULL
- * and try to do something rational.
- *
- * So we need to make sure that our copies of ch_oflag,
- * ch_clag, and ch_iflag reflect the tty->termios flags.
- */
-static void dgrp_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
-{
- struct ktermios *ts;
- struct ch_struct *ch;
- struct un_struct *un;
-
- /* seems silly, but we have to check all these! */
- if (!tty)
- return;
-
- un = tty->driver_data;
- if (!un)
- return;
-
- ts = &tty->termios;
-
- ch = un->un_ch;
- if (!ch)
- return;
-
- drp_param(ch);
-
- /* the CLOCAL flag has just been set */
- if (!(old->c_cflag & CLOCAL) && C_CLOCAL(tty))
- wake_up_interruptible(&un->un_open_wait);
-}
-
-
-/*
- * Throttle receiving data. We just set a bit and stop reading
- * data out of the channel buffer. It will back up and the
- * FEP will do whatever is necessary to stop the far end.
- */
-static void dgrp_tty_throttle(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- ch->ch_flag |= CH_RXSTOP;
-}
-
-
-static void dgrp_tty_unthrottle(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- ch->ch_flag &= ~CH_RXSTOP;
-}
-
-/*
- * Stop the transmitter
- */
-static void dgrp_tty_stop(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- ch->ch_send |= RR_TX_STOP;
- ch->ch_send &= ~RR_TX_START;
-
- /* make the change NOW! */
- (ch->ch_nd)->nd_tx_ready = 1;
- if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-}
-
-/*
- * Start the transmitter
- */
-static void dgrp_tty_start(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- /* TODO: don't do anything if the transmitter is not stopped */
-
- ch->ch_send |= RR_TX_START;
- ch->ch_send &= ~RR_TX_STOP;
-
- /* make the change NOW! */
- (ch->ch_nd)->nd_tx_ready = 1;
- (ch->ch_nd)->nd_tx_work = 1;
- if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-
-}
-
-/*
- * Stop the receiver
- */
-static void dgrp_tty_input_stop(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- ch->ch_send |= RR_RX_STOP;
- ch->ch_send &= ~RR_RX_START;
- (ch->ch_nd)->nd_tx_ready = 1;
- if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-
-}
-
-
-static void dgrp_tty_send_xchar(struct tty_struct *tty, char c)
-{
- struct un_struct *un;
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- un = tty->driver_data;
- if (!un)
- return;
-
- ch = un->un_ch;
- if (!ch)
- return;
- if (c == STOP_CHAR(tty))
- ch->ch_send |= RR_RX_STOP;
- else if (c == START_CHAR(tty))
- ch->ch_send |= RR_RX_START;
-
- ch->ch_nd->nd_tx_ready = 1;
- ch->ch_nd->nd_tx_work = 1;
-
- return;
-}
-
-
-static void dgrp_tty_input_start(struct tty_struct *tty)
-{
- struct ch_struct *ch;
-
- if (!tty)
- return;
-
- ch = ((struct un_struct *) tty->driver_data)->un_ch;
- if (!ch)
- return;
-
- ch->ch_send |= RR_RX_START;
- ch->ch_send &= ~RR_RX_STOP;
- (ch->ch_nd)->nd_tx_ready = 1;
- (ch->ch_nd)->nd_tx_work = 1;
- if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
- wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
-
-}
-
-
-/*
- * Hangup the port. Like a close, but don't wait for output
- * to drain.
- *
- * How do we close all the channels that are open?
- */
-static void dgrp_tty_hangup(struct tty_struct *tty)
-{
- struct ch_struct *ch;
- struct nd_struct *nd;
- struct un_struct *un;
-
- if (!tty)
- return;
-
- un = tty->driver_data;
- if (!un)
- return;
-
- ch = un->un_ch;
- if (!ch)
- return;
-
- nd = ch->ch_nd;
-
- if (C_HUPCL(tty)) {
- /* LOWER DTR */
- ch->ch_mout &= ~DM_DTR;
- /* Don't do this here */
- /* ch->ch_flag |= CH_HANGUP; */
- ch->ch_nd->nd_tx_ready = 1;
- ch->ch_nd->nd_tx_work = 1;
- if (waitqueue_active(&ch->ch_flag_wait))
- wake_up_interruptible(&ch->ch_flag_wait);
- }
-
-}
-
-/************************************************************************/
-/* */
-/* TTY Initialization/Cleanup Functions */
-/* */
-/************************************************************************/
-
-/*
- * Uninitialize the TTY portion of the supplied node. Free all
- * memory and resources associated with this node. Do it in reverse
- * allocation order: this might possibly result in less fragmentation
- * of memory, though I don't know this for sure.
- */
-void
-dgrp_tty_uninit(struct nd_struct *nd)
-{
- unsigned int i;
- char id[3];
-
- ID_TO_CHAR(nd->nd_ID, id);
-
- if (nd->nd_ttdriver_flags & SERIAL_TTDRV_REG) {
- tty_unregister_driver(nd->nd_serial_ttdriver);
-
- kfree(nd->nd_serial_ttdriver->ttys);
- nd->nd_serial_ttdriver->ttys = NULL;
-
- put_tty_driver(nd->nd_serial_ttdriver);
- nd->nd_ttdriver_flags &= ~SERIAL_TTDRV_REG;
- }
-
- if (nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG) {
- tty_unregister_driver(nd->nd_callout_ttdriver);
-
- kfree(nd->nd_callout_ttdriver->ttys);
- nd->nd_callout_ttdriver->ttys = NULL;
-
- put_tty_driver(nd->nd_callout_ttdriver);
- nd->nd_ttdriver_flags &= ~CALLOUT_TTDRV_REG;
- }
-
- if (nd->nd_ttdriver_flags & XPRINT_TTDRV_REG) {
- tty_unregister_driver(nd->nd_xprint_ttdriver);
-
- kfree(nd->nd_xprint_ttdriver->ttys);
- nd->nd_xprint_ttdriver->ttys = NULL;
-
- put_tty_driver(nd->nd_xprint_ttdriver);
- nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
- }
- for (i = 0; i < CHAN_MAX; i++)
- tty_port_destroy(&nd->nd_chan[i].port);
-}
-
-
-
-/*
- * Initialize the TTY portion of the supplied node.
- */
-int
-dgrp_tty_init(struct nd_struct *nd)
-{
- char id[3];
- int rc;
- int i;
-
- ID_TO_CHAR(nd->nd_ID, id);
-
- /*
- * Initialize the TTDRIVER structures.
- */
-
- nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX);
- if (!nd->nd_serial_ttdriver)
- return -ENOMEM;
-
- sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id);
-
- nd->nd_serial_ttdriver->owner = THIS_MODULE;
- nd->nd_serial_ttdriver->name = nd->nd_serial_name;
- nd->nd_serial_ttdriver->name_base = 0;
- nd->nd_serial_ttdriver->major = 0;
- nd->nd_serial_ttdriver->minor_start = 0;
- nd->nd_serial_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
- nd->nd_serial_ttdriver->subtype = SERIAL_TYPE_NORMAL;
- nd->nd_serial_ttdriver->init_termios = DefaultTermios;
- nd->nd_serial_ttdriver->driver_name = "dgrp";
- nd->nd_serial_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV |
- TTY_DRIVER_HARDWARE_BREAK);
-
- /* The kernel wants space to store pointers to tty_structs. */
- nd->nd_serial_ttdriver->ttys =
- kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
- if (!nd->nd_serial_ttdriver->ttys)
- return -ENOMEM;
-
- tty_set_operations(nd->nd_serial_ttdriver, &dgrp_tty_ops);
-
- if (!(nd->nd_ttdriver_flags & SERIAL_TTDRV_REG)) {
- /*
- * Register tty devices
- */
- rc = tty_register_driver(nd->nd_serial_ttdriver);
- if (rc < 0) {
- /*
- * If errno is EBUSY, this means there are no more
- * slots available to have us auto-majored.
- * (Which is currently supported up to 256)
- *
- * We can still request majors above 256,
- * we just have to do it manually.
- */
- if (rc == -EBUSY) {
- int i;
- int max_majors = 1U << (32 - MINORBITS);
- for (i = 256; i < max_majors; i++) {
- nd->nd_serial_ttdriver->major = i;
- rc = tty_register_driver
- (nd->nd_serial_ttdriver);
- if (rc >= 0)
- break;
- }
- /* Really fail now, since we ran out
- * of majors to try. */
- if (i == max_majors)
- return rc;
-
- } else {
- return rc;
- }
- }
- nd->nd_ttdriver_flags |= SERIAL_TTDRV_REG;
- }
-
- nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX);
- if (!nd->nd_callout_ttdriver)
- return -ENOMEM;
-
- sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id);
-
- nd->nd_callout_ttdriver->owner = THIS_MODULE;
- nd->nd_callout_ttdriver->name = nd->nd_callout_name;
- nd->nd_callout_ttdriver->name_base = 0;
- nd->nd_callout_ttdriver->major = nd->nd_serial_ttdriver->major;
- nd->nd_callout_ttdriver->minor_start = 0x40;
- nd->nd_callout_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
- nd->nd_callout_ttdriver->subtype = SERIAL_TYPE_CALLOUT;
- nd->nd_callout_ttdriver->init_termios = DefaultTermios;
- nd->nd_callout_ttdriver->driver_name = "dgrp";
- nd->nd_callout_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV |
- TTY_DRIVER_HARDWARE_BREAK);
-
- /* The kernel wants space to store pointers to tty_structs. */
- nd->nd_callout_ttdriver->ttys =
- kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
- if (!nd->nd_callout_ttdriver->ttys)
- return -ENOMEM;
-
- tty_set_operations(nd->nd_callout_ttdriver, &dgrp_tty_ops);
-
- if (dgrp_register_cudevices) {
- if (!(nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG)) {
- /*
- * Register cu devices
- */
- rc = tty_register_driver(nd->nd_callout_ttdriver);
- if (rc < 0)
- return rc;
- nd->nd_ttdriver_flags |= CALLOUT_TTDRV_REG;
- }
- }
-
-
- nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX);
- if (!nd->nd_xprint_ttdriver)
- return -ENOMEM;
-
- sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id);
-
- nd->nd_xprint_ttdriver->owner = THIS_MODULE;
- nd->nd_xprint_ttdriver->name = nd->nd_xprint_name;
- nd->nd_xprint_ttdriver->name_base = 0;
- nd->nd_xprint_ttdriver->major = nd->nd_serial_ttdriver->major;
- nd->nd_xprint_ttdriver->minor_start = 0x80;
- nd->nd_xprint_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
- nd->nd_xprint_ttdriver->subtype = SERIAL_TYPE_XPRINT;
- nd->nd_xprint_ttdriver->init_termios = DefaultTermios;
- nd->nd_xprint_ttdriver->driver_name = "dgrp";
- nd->nd_xprint_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV |
- TTY_DRIVER_HARDWARE_BREAK);
-
- /* The kernel wants space to store pointers to tty_structs. */
- nd->nd_xprint_ttdriver->ttys =
- kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
- if (!nd->nd_xprint_ttdriver->ttys)
- return -ENOMEM;
-
- tty_set_operations(nd->nd_xprint_ttdriver, &dgrp_tty_ops);
-
- if (dgrp_register_prdevices) {
- if (!(nd->nd_ttdriver_flags & XPRINT_TTDRV_REG)) {
- /*
- * Register transparent print devices
- */
- rc = tty_register_driver(nd->nd_xprint_ttdriver);
- if (rc < 0)
- return rc;
- nd->nd_ttdriver_flags |= XPRINT_TTDRV_REG;
- }
- }
-
- for (i = 0; i < CHAN_MAX; i++) {
- struct ch_struct *ch = nd->nd_chan + i;
-
- ch->ch_nd = nd;
- ch->ch_digi = digi_init;
- ch->ch_edelay = 100;
- ch->ch_custom_speed = 0;
- ch->ch_portnum = i;
- ch->ch_tun.un_ch = ch;
- ch->ch_pun.un_ch = ch;
- ch->ch_tun.un_type = SERIAL_TYPE_NORMAL;
- ch->ch_pun.un_type = SERIAL_TYPE_XPRINT;
-
- init_waitqueue_head(&(ch->ch_flag_wait));
- init_waitqueue_head(&(ch->ch_sleep));
-
- init_waitqueue_head(&(ch->ch_tun.un_open_wait));
- init_waitqueue_head(&(ch->ch_tun.un_close_wait));
-
- init_waitqueue_head(&(ch->ch_pun.un_open_wait));
- init_waitqueue_head(&(ch->ch_pun.un_close_wait));
- tty_port_init(&ch->port);
- }
- return 0;
-}
diff --git a/drivers/staging/dgrp/digirp.h b/drivers/staging/dgrp/digirp.h
deleted file mode 100644
index 33c1394fade7..000000000000
--- a/drivers/staging/dgrp/digirp.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/************************************************************************
- * HP-UX Realport Daemon interface file.
- *
- * Copyright (C) 1998, by Digi International. All Rights Reserved.
- ************************************************************************/
-
-#ifndef _DIGIDRP_H
-#define _DIGIDRP_H
-
-/************************************************************************
- * This file contains defines for the ioctl() interface to
- * the realport driver. This ioctl() interface is used by the
- * daemon to set speed setup parameters honored by the driver.
- ************************************************************************/
-
-struct link_struct {
- int lk_fast_rate; /* Fast line rate to be used
- when the delay is less-equal
- to lk_fast_delay */
-
- int lk_fast_delay; /* Fast line rate delay in
- milliseconds */
-
- int lk_slow_rate; /* Slow line rate to be used when
- the delay is greater-equal
- to lk_slow_delay */
-
- int lk_slow_delay; /* Slow line rate delay in
- milliseconds */
-
- int lk_header_size; /* Estimated packet header size
- when sent across the slowest
- link. */
-};
-
-#define DIGI_GETLINK _IOW('e', 103, struct link_struct) /* Get link parameters */
-#define DIGI_SETLINK _IOW('e', 104, struct link_struct) /* Set link parameters */
-
-
-/************************************************************************
- * This module provides application access to special Digi
- * serial line enhancements which are not standard UNIX(tm) features.
- ************************************************************************/
-
-struct digiflow_struct {
- unsigned char startc; /* flow cntl start char */
- unsigned char stopc; /* flow cntl stop char */
-};
-
-/************************************************************************
- * Values for digi_flags
- ************************************************************************/
-#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
-#define DIGI_FAST 0x0002 /* Fast baud rates */
-#define RTSPACE 0x0004 /* RTS input flow control */
-#define CTSPACE 0x0008 /* CTS output flow control */
-#define DSRPACE 0x0010 /* DSR output flow control */
-#define DCDPACE 0x0020 /* DCD output flow control */
-#define DTRPACE 0x0040 /* DTR input flow control */
-#define DIGI_COOK 0x0080 /* Cooked processing done in FEP */
-#define DIGI_FORCEDCD 0x0100 /* Force carrier */
-#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
-#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
-#define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl */
-#define DIGI_PP_INPUT 0x1000 /* Change parallel port to input */
-#define DIGI_422 0x4000 /* Change parallel port to input */
-#define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */
-
-
-/************************************************************************
- * Values associated with transparent print
- ************************************************************************/
-#define DIGI_PLEN 8 /* String length */
-#define DIGI_TSIZ 10 /* Terminal string len */
-
-
-/************************************************************************
- * Structure used with ioctl commands for DIGI parameters.
- ************************************************************************/
-struct digi_struct {
- unsigned short digi_flags; /* Flags (see above) */
- unsigned short digi_maxcps; /* Max printer CPS */
- unsigned short digi_maxchar; /* Max chars in print queue */
- unsigned short digi_bufsize; /* Buffer size */
- unsigned char digi_onlen; /* Length of ON string */
- unsigned char digi_offlen; /* Length of OFF string */
- char digi_onstr[DIGI_PLEN]; /* Printer on string */
- char digi_offstr[DIGI_PLEN]; /* Printer off string */
- char digi_term[DIGI_TSIZ]; /* terminal string */
-};
-
-/************************************************************************
- * Ioctl command arguments for DIGI parameters.
- ************************************************************************/
-/* Read params */
-#define DIGI_GETA _IOR('e', 94, struct digi_struct)
-
-/* Set params */
-#define DIGI_SETA _IOW('e', 95, struct digi_struct)
-
-/* Drain & set params */
-#define DIGI_SETAW _IOW('e', 96, struct digi_struct)
-
-/* Drain, flush & set params */
-#define DIGI_SETAF _IOW('e', 97, struct digi_struct)
-
-/* Get startc/stopc flow control characters */
-#define DIGI_GETFLOW _IOR('e', 99, struct digiflow_struct)
-
-/* Set startc/stopc flow control characters */
-#define DIGI_SETFLOW _IOW('e', 100, struct digiflow_struct)
-
-/* Get Aux. startc/stopc flow control chars */
-#define DIGI_GETAFLOW _IOR('e', 101, struct digiflow_struct)
-
-/* Set Aux. startc/stopc flow control chars */
-#define DIGI_SETAFLOW _IOW('e', 102, struct digiflow_struct)
-
-/* Set integer baud rate */
-#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int)
-
-/* Get integer baud rate */
-#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int)
-
-#define DIGI_GEDELAY _IOR('d', 246, int) /* Get edelay */
-#define DIGI_SEDELAY _IOW('d', 247, int) /* Get edelay */
-
-
-#endif /* _DIGIDRP_H */
diff --git a/drivers/staging/dgrp/drp.h b/drivers/staging/dgrp/drp.h
deleted file mode 100644
index 4024b488eba9..000000000000
--- a/drivers/staging/dgrp/drp.h
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- *
- * Copyright 1999 Digi International (www.digi.com)
- * Gene Olson <gene at digi dot com>
- * James Puzzo <jamesp at digi dot com>
- * Scott Kilau <scottk at digi dot 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- */
-
-/************************************************************************
- * Master include file for Linux Realport Driver.
- ************************************************************************/
-
-#ifndef __DRP_H
-#define __DRP_H
-
-#include <linux/types.h>
-#include <linux/wait.h>
-#include <linux/semaphore.h>
-#include <linux/tty.h>
-
-
-#include "digirp.h"
-
-/************************************************************************
- * Tuning parameters.
- ************************************************************************/
-
-#define CHAN_MAX 64 /* Max # ports per server */
-
-#define SEQ_MAX 128 /* Max # transmit sequences (2^n) */
-#define SEQ_MASK (SEQ_MAX-1) /* Sequence buffer modulus mask */
-
-#define TBUF_MAX 4096 /* Size of transmit buffer (2^n) */
-#define RBUF_MAX 4096 /* Size of receive buffer (2^n) */
-
-#define TBUF_MASK (TBUF_MAX-1) /* Transmit buffer modulus mask */
-#define RBUF_MASK (RBUF_MAX-1) /* Receive buffer modulus mask */
-
-#define TBUF_LOW 1000 /* Transmit low water mark */
-
-#define UIO_BASE 1000 /* Base for write operations */
-#define UIO_MIN 2000 /* Minimum size application buffer */
-#define UIO_MAX 8100 /* Unix I/O buffer size */
-
-#define MON_MAX 65536 /* Monitor buffer size (2^n) */
-#define MON_MASK (MON_MAX-1) /* Monitor wrap mask */
-
-#define DPA_MAX 65536 /* DPA buffer size (2^n) */
-#define DPA_MASK (DPA_MAX-1) /* DPA wrap mask */
-#define DPA_HIGH_WATER 58000 /* Enforce flow control when
- * over this amount
- */
-
-#define IDLE_MAX (20 * HZ) /* Max TCP link idle time */
-
-#define MAX_DESC_LEN 100 /* Maximum length of stored PS
- * description
- */
-
-#define WRITEBUFLEN ((4096) + 4) /* 4 extra for alignment play space */
-
-#define VPDSIZE 512
-
-/************************************************************************
- * Minor device decoding conventions.
- ************************************************************************
- *
- * For Linux, the net and mon devices are handled via "proc", so we
- * only have to mux the "tty" devices. Since every PortServer will
- * have an individual major number, the PortServer number does not
- * need to be encoded, and in fact, does not need to exist.
- *
- */
-
-/*
- * Port device decoding conventions:
- *
- * Device 00 - 3f 64 dial-in modem devices. (tty)
- * Device 40 - 7f 64 dial-out tty devices. (cu)
- * Device 80 - bf 64 dial-out printer devices.
- *
- * IS_PRINT(dev) This is a printer device.
- *
- * OPEN_CATEGORY(dev) Specifies the device category. No two
- * devices of different categories may be open
- * at the same time.
- *
- * The following require the category returned by OPEN_CATEGORY().
- *
- * OPEN_WAIT_AVAIL(cat) Waits on open until the device becomes
- * available. Fails if NDELAY specified.
- *
- * OPEN_WAIT_CARRIER(cat) Waits on open if carrier is not present.
- * Succeeds if NDELAY is given.
- *
- * OPEN_FORCES_CARRIER(cat) Carrier is forced high on open.
- *
- */
-
-#define PORT_NUM(dev) ((dev) & 0x3f)
-
-#define OPEN_CATEGORY(dev) ((((dev) & 0x80) & 0x40))
-#define IS_PRINT(dev) (((dev) & 0xff) >= 0x80)
-
-#define OPEN_WAIT_AVAIL(cat) (((cat) & 0x40) == 0x000)
-#define OPEN_WAIT_CARRIER(cat) (((cat) & 0x40) == 0x000)
-#define OPEN_FORCES_CARRIER(cat) (((cat) & 0x40) != 0x000)
-
-
-/************************************************************************
- * Modem signal defines for 16450/16550 compatible FEP.
- * set in ch_mout, ch_mflow, ch_mlast etc
- ************************************************************************/
-
-/* TODO : Re-verify that these modem signal definitions are correct */
-
-#define DM_DTR 0x01
-#define DM_RTS 0x02
-#define DM_RTS_TOGGLE 0x04
-
-#define DM_OUT1 0x04
-#define DM_OUT2 0x08
-
-#define DM_CTS 0x10
-#define DM_DSR 0x20
-#define DM_RI 0x40
-#define DM_CD 0x80 /* This is the DCD flag */
-
-
-/************************************************************************
- * Realport Event Flags.
- ************************************************************************/
-
-#define EV_OPU 0x0001 /* Ouput paused by client */
-#define EV_OPS 0x0002 /* Output paused by XOFF */
-#define EV_OPX 0x0004 /* Output paused by XXOFF */
-#define EV_OPH 0x0008 /* Output paused by MFLOW */
-#define EV_IPU 0x0010 /* Input paused by client */
-#define EV_IPS 0x0020 /* Input paused by hi/low water */
-#define EV_TXB 0x0040 /* Transmit break pending */
-#define EV_TXI 0x0080 /* Transmit immediate pending */
-#define EV_TXF 0x0100 /* Transmit flow control pending */
-#define EV_RXB 0x0200 /* Break received */
-
-
-/************************************************************************
- * Realport CFLAGS.
- ************************************************************************/
-
-#define CF_CS5 0x0000 /* 5 bit characters */
-#define CF_CS6 0x0010 /* 6 bit characters */
-#define CF_CS7 0x0020 /* 7 bit characters */
-#define CF_CS8 0x0030 /* 8 bit characters */
-#define CF_CSIZE 0x0030 /* Character size */
-#define CF_CSTOPB 0x0040 /* Two stop bits */
-#define CF_CREAD 0x0080 /* Enable receiver */
-#define CF_PARENB 0x0100 /* Enable parity */
-#define CF_PARODD 0x0200 /* Odd parity */
-#define CF_HUPCL 0x0400 /* Drop DTR on close */
-
-
-/************************************************************************
- * Realport XFLAGS.
- ************************************************************************/
-
-#define XF_XPAR 0x0001 /* Enable Mark/Space Parity */
-#define XF_XMODEM 0x0002 /* Enable in-band modem signalling */
-#define XF_XCASE 0x0004 /* Convert special characters */
-#define XF_XEDATA 0x0008 /* Error data in stream */
-#define XF_XTOSS 0x0010 /* Toss IXANY characters */
-#define XF_XIXON 0x0020 /* xxon/xxoff enable */
-
-
-/************************************************************************
- * Realport IFLAGS.
- ************************************************************************/
-
-#define IF_IGNBRK 0x0001 /* Ignore input break */
-#define IF_BRKINT 0x0002 /* Break interrupt */
-#define IF_IGNPAR 0x0004 /* Ignore error characters */
-#define IF_PARMRK 0x0008 /* Error chars marked with 0xff */
-#define IF_INPCK 0x0010 /* Input parity checking enabled */
-#define IF_ISTRIP 0x0020 /* Input chars masked with 0x7F */
-#define IF_IXON 0x0400 /* Output software flow control */
-#define IF_IXANY 0x0800 /* Restart output on any char */
-#define IF_IXOFF 0x1000 /* Input software flow control */
-#define IF_DOSMODE 0x8000 /* 16450-compatible errors */
-
-
-/************************************************************************
- * Realport OFLAGS.
- ************************************************************************/
-
-#define OF_OLCUC 0x0002 /* Map lower to upper case */
-#define OF_ONLCR 0x0004 /* Map NL to CR-NL */
-#define OF_OCRNL 0x0008 /* Map CR to NL */
-#define OF_ONOCR 0x0010 /* No CR output at column 0 */
-#define OF_ONLRET 0x0020 /* Assume NL does NL/CR */
-#define OF_TAB3 0x1800 /* Tabs expand to 8 spaces */
-#define OF_TABDLY 0x1800 /* Tab delay */
-
-/************************************************************************
- * Unit flag definitions for un_flag.
- ************************************************************************/
-
-/* These are the DIGI unit flags */
-#define UN_EXCL 0x00010000 /* Exclusive open */
-#define UN_STICKY 0x00020000 /* TTY Settings are now sticky */
-#define UN_BUSY 0x00040000 /* Some work this channel */
-#define UN_PWAIT 0x00080000 /* Printer waiting for terminal */
-#define UN_TIME 0x00100000 /* Waiting on time */
-#define UN_EMPTY 0x00200000 /* Waiting output queue empty */
-#define UN_LOW 0x00400000 /* Waiting output low water */
-#define UN_DIGI_MASK 0x00FF0000 /* Waiting output low water */
-
-/*
- * Definitions for async_struct (and serial_struct) flags field
- *
- * these are the ASYNC flags copied from serial.h
- *
- */
-#define UN_HUP_NOTIFY 0x0001 /* Notify getty on hangups and
- * closes on the callout port
- */
-#define UN_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
-#define UN_SAK 0x0004 /* Secure Attention Key (Orange book) */
-#define UN_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
-
-#define UN_SPD_MASK 0x0030
-#define UN_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
-#define UN_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
-#define UN_SPD_CUST 0x0030 /* Use user-specified divisor */
-
-#define UN_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
-#define UN_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
-
-#define UN_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
-#define UN_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
-#define UN_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
-
-#define UN_FLAGS 0x0FFF /* Possible legal async flags */
-#define UN_USR_MASK 0x0430 /* Legal flags that non-privileged
- * users can set or reset
- */
-
-#define UN_INITIALIZED 0x80000000 /* Serial port was initialized */
-#define UN_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
-#define UN_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
-#define UN_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
-#define UN_CLOSING 0x08000000 /* Serial port is closing */
-#define UN_CTS_FLOW 0x04000000 /* Do CTS flow control */
-#define UN_CHECK_CD 0x02000000 /* i.e., CLOCAL */
-#define UN_SHARE_IRQ 0x01000000 /* for multifunction cards */
-
-
-/************************************************************************
- * Structure for terminal or printer unit. struct un_struct
- *
- * Note that in some places the code assumes the "tty_t" is placed
- * first in the structure.
- ************************************************************************/
-
-struct un_struct {
- struct tty_struct *un_tty; /* System TTY struct */
- struct ch_struct *un_ch; /* Associated channel */
-
- ushort un_open_count; /* Successful open count */
- int un_flag; /* Unit flags */
- ushort un_tbusy; /* Busy transmit count */
-
- wait_queue_head_t un_open_wait;
- wait_queue_head_t un_close_wait;
- ushort un_type;
- struct device *un_sysfs;
-};
-
-
-/************************************************************************
- * Channel State Numbers for ch_state.
- ************************************************************************/
-
-/*
- * The ordering is important.
- *
- * state <= CS_WAIT_CANCEL implies the channel is definitely closed.
- *
- * state >= CS_WAIT_FAIL implies the channel is definitely open.
- *
- * state >= CS_READY implies data is allowed on the channel.
- */
-
-enum dgrp_ch_state_t {
- CS_IDLE = 0, /* Channel is idle */
- CS_WAIT_OPEN = 1, /* Waiting for Immediate Open Resp */
- CS_WAIT_CANCEL = 2, /* Waiting for Per/Incom Cancel Resp */
- CS_WAIT_FAIL = 3, /* Waiting for Immed Open Failure */
- CS_SEND_QUERY = 4, /* Ready to send Port Query */
- CS_WAIT_QUERY = 5, /* Waiting for Port Query Response */
- CS_READY = 6, /* Ready to accept commands and data */
- CS_SEND_CLOSE = 7, /* Ready to send Close Request */
- CS_WAIT_CLOSE = 8 /* Waiting for Close Response */
-};
-
-/************************************************************************
- * Device flag definitions for ch_flag.
- ************************************************************************/
-
-/*
- * Note that the state of the two carrier based flags is key. When
- * we check for carrier state transitions, we look at the current
- * physical state of the DCD line and compare it with PHYS_CD (which
- * was the state the last time we checked), and we also determine
- * a new virtual state (composite of the physical state, FORCEDCD,
- * CLOCAL, etc.) and compare it with VIRT_CD.
- *
- * VIRTUAL transitions high will have the side effect of waking blocked
- * opens.
- *
- * PHYSICAL transitions low will cause hangups to occur _IF_ the virtual
- * state is also low. We DON'T want to hangup on a PURE virtual drop.
- */
-
-#define CH_HANGUP 0x00002 /* Server port ready to close */
-
-#define CH_VIRT_CD 0x00004 /* Carrier was virtually present */
-#define CH_PHYS_CD 0x00008 /* Carrier was physically present */
-
-#define CH_CLOCAL 0x00010 /* CLOCAL set in cflags */
-#define CH_BAUD0 0x00020 /* Baud rate zero hangup */
-
-#define CH_FAST_READ 0x00040 /* Fast reads are enabled */
-#define CH_FAST_WRITE 0x00080 /* Fast writes are enabled */
-
-#define CH_PRON 0x00100 /* Printer on string active */
-#define CH_RX_FLUSH 0x00200 /* Flushing receive data */
-#define CH_LOW 0x00400 /* Thread waiting for LOW water */
-#define CH_EMPTY 0x00800 /* Thread waiting for EMPTY */
-#define CH_DRAIN 0x01000 /* Close is waiting to drain */
-#define CH_INPUT 0x02000 /* Thread waiting for INPUT */
-#define CH_RXSTOP 0x04000 /* Stop output to ldisc */
-#define CH_PARAM 0x08000 /* A parameter was updated */
-#define CH_WAITING_SYNC 0x10000 /* A pending sync was assigned
- * to this port.
- */
-#define CH_PORT_GONE 0x20000 /* Port has disappeared */
-#define CH_TX_BREAK 0x40000 /* TX Break to be sent,
- * but has not yet.
- */
-
-/************************************************************************
- * Types of Open Requests for ch_otype.
- ************************************************************************/
-
-#define OTYPE_IMMEDIATE 0 /* Immediate Open */
-#define OTYPE_PERSISTENT 1 /* Persistent Open */
-#define OTYPE_INCOMING 2 /* Incoming Open */
-
-
-/************************************************************************
- * Request/Response flags.
- ************************************************************************/
-
-#define RR_SEQUENCE 0x0001 /* Get server RLAST, TIN */
-#define RR_STATUS 0x0002 /* Get server MINT, EINT */
-#define RR_BUFFER 0x0004 /* Get server RSIZE, TSIZE */
-#define RR_CAPABILITY 0x0008 /* Get server port capabilities */
-
-#define RR_TX_FLUSH 0x0040 /* Flush output buffers */
-#define RR_RX_FLUSH 0x0080 /* Flush input buffers */
-
-#define RR_TX_STOP 0x0100 /* Pause output */
-#define RR_RX_STOP 0x0200 /* Pause input */
-#define RR_TX_START 0x0400 /* Start output */
-#define RR_RX_START 0x0800 /* Start input */
-
-#define RR_TX_BREAK 0x1000 /* Send BREAK */
-#define RR_TX_ICHAR 0x2000 /* Send character immediate */
-
-
-/************************************************************************
- * Channel information structure. struct ch_struct
- ************************************************************************/
-
-struct ch_struct {
- struct digi_struct ch_digi; /* Digi variables */
- int ch_edelay; /* Digi edelay */
-
- struct tty_port port;
- struct un_struct ch_tun; /* Terminal unit info */
- struct un_struct ch_pun; /* Printer unit info */
-
- struct nd_struct *ch_nd; /* Node pointer */
- u8 *ch_tbuf; /* Local Transmit Buffer */
- u8 *ch_rbuf; /* Local Receive Buffer */
- ulong ch_cpstime; /* Printer CPS time */
- ulong ch_waketime; /* Printer wake time */
-
- ulong ch_flag; /* CH_* flags */
-
- enum dgrp_ch_state_t ch_state; /* CS_* Protocol state */
- ushort ch_send; /* Bit vector of RR_* requests */
- ushort ch_expect; /* Bit vector of RR_* responses */
- ushort ch_wait_carrier; /* Thread count waiting for carrier */
- ushort ch_wait_count[3]; /* Thread count waiting by otype */
-
- ushort ch_portnum; /* Port number */
- ushort ch_open_count; /* Successful open count */
- ushort ch_category; /* Device category */
- ushort ch_open_error; /* Last open error number */
- ushort ch_break_time; /* Pending break request time */
- ushort ch_cpsrem; /* Printer CPS remainder */
- ushort ch_ocook; /* Realport fastcook oflags */
- ushort ch_inwait; /* Thread count in CLIST input */
-
- ushort ch_tin; /* Local transmit buffer in ptr */
- ushort ch_tout; /* Local transmit buffer out ptr */
- ushort ch_s_tin; /* Realport TIN */
- ushort ch_s_tpos; /* Realport TPOS */
- ushort ch_s_tsize; /* Realport TSIZE */
- ushort ch_s_treq; /* Realport TREQ */
- ushort ch_s_elast; /* Realport ELAST */
-
- ushort ch_rin; /* Local receive buffer in ptr */
- ushort ch_rout; /* Local receive buffer out ptr */
- ushort ch_s_rin; /* Realport RIN */
- /* David Fries 7-13-2001, ch_s_rin should be renamed ch_s_rout because
- * the variable we want to represent is the PortServer's ROUT, which is
- * the sequence number for the next byte the PortServer will send us.
- * RIN is the sequence number for the next byte the PortServer will
- * receive from the uart. The port server will send data as long as
- * ROUT is less than RWIN. What would happen is the port is opened, it
- * receives data, it gives the value of RIN, we set the RWIN to
- * RIN+RBUF_MAX-1, it sends us RWIN-ROUT bytes which overflows. ROUT
- * is set to zero when the port is opened, so we start at zero and
- * count up as data is received.
- */
- ushort ch_s_rwin; /* Realport RWIN */
- ushort ch_s_rsize; /* Realport RSIZE */
-
- ushort ch_tmax; /* Local TMAX */
- ushort ch_ttime; /* Local TTIME */
- ushort ch_rmax; /* Local RMAX */
- ushort ch_rtime; /* Local RTIME */
- ushort ch_rlow; /* Local RLOW */
- ushort ch_rhigh; /* Local RHIGH */
-
- ushort ch_s_tmax; /* Realport TMAX */
- ushort ch_s_ttime; /* Realport TTIME */
- ushort ch_s_rmax; /* Realport RMAX */
- ushort ch_s_rtime; /* Realport RTIME */
- ushort ch_s_rlow; /* Realport RLOW */
- ushort ch_s_rhigh; /* Realport RHIGH */
-
- ushort ch_brate; /* Local baud rate */
- ushort ch_cflag; /* Local tty cflags */
- ushort ch_iflag; /* Local tty iflags */
- ushort ch_oflag; /* Local tty oflags */
- ushort ch_xflag; /* Local tty xflags */
-
- ushort ch_s_brate; /* Realport BRATE */
- ushort ch_s_cflag; /* Realport CFLAG */
- ushort ch_s_iflag; /* Realport IFLAG */
- ushort ch_s_oflag; /* Realport OFLAG */
- ushort ch_s_xflag; /* Realport XFLAG */
-
- u8 ch_otype; /* Open request type */
- u8 ch_pscan_savechar; /* Last character read by parity scan */
- u8 ch_pscan_state; /* PScan State based on last 2 chars */
- u8 ch_otype_waiting; /* Type of open pending in server */
- u8 ch_flush_seq; /* Receive flush end sequence */
- u8 ch_s_mlast; /* Realport MLAST */
-
- u8 ch_mout; /* Local MOUT */
- u8 ch_mflow; /* Local MFLOW */
- u8 ch_mctrl; /* Local MCTRL */
- u8 ch_xon; /* Local XON */
- u8 ch_xoff; /* Local XOFF */
- u8 ch_lnext; /* Local LNEXT */
- u8 ch_xxon; /* Local XXON */
- u8 ch_xxoff; /* Local XXOFF */
-
- u8 ch_s_mout; /* Realport MOUT */
- u8 ch_s_mflow; /* Realport MFLOW */
- u8 ch_s_mctrl; /* Realport MCTRL */
- u8 ch_s_xon; /* Realport XON */
- u8 ch_s_xoff; /* Realport XOFF */
- u8 ch_s_lnext; /* Realport LNEXT */
- u8 ch_s_xxon; /* Realport XXON */
- u8 ch_s_xxoff; /* Realport XXOFF */
-
- wait_queue_head_t ch_flag_wait; /* Wait queue for ch_flag changes */
- wait_queue_head_t ch_sleep; /* Wait queue for my_sleep() */
-
- int ch_custom_speed; /* Realport custom speed */
- int ch_txcount; /* Running TX count */
- int ch_rxcount; /* Running RX count */
-};
-
-
-/************************************************************************
- * Node State definitions.
- ************************************************************************/
-
-enum dgrp_nd_state_t {
- NS_CLOSED = 0, /* Network device is closed */
- NS_IDLE = 1, /* Network connection inactive */
- NS_SEND_QUERY = 2, /* Send server query */
- NS_WAIT_QUERY = 3, /* Wait for query response */
- NS_READY = 4, /* Network ready */
- NS_SEND_ERROR = 5 /* Must send error hangup */
-};
-
-#define ND_STATE_STR(x) \
- ((x) == NS_CLOSED ? "CLOSED" : \
- ((x) == NS_IDLE ? "IDLE" : \
- ((x) == NS_SEND_QUERY ? "SEND_QUERY" : \
- ((x) == NS_WAIT_QUERY ? "WAIT_QUERY" : \
- ((x) == NS_READY ? "READY" : \
- ((x) == NS_SEND_ERROR ? "SEND_ERROR" : "UNKNOWN"))))))
-
-/************************************************************************
- * Node Flag definitions.
- ************************************************************************/
-
-#define ND_SELECT 0x0001 /* Multiple net read selects */
-#define ND_DEB_WAIT 0x0002 /* Debug Device waiting */
-
-
-/************************************************************************
- * Monitoring flag definitions.
- ************************************************************************/
-
-#define MON_WAIT_DATA 0x0001 /* Waiting for buffer data */
-#define MON_WAIT_SPACE 0x0002 /* Waiting for buffer space */
-
-/************************************************************************
- * DPA flag definitions.
- ************************************************************************/
-
-#define DPA_WAIT_DATA 0x0001 /* Waiting for buffer data */
-#define DPA_WAIT_SPACE 0x0002 /* Waiting for buffer space */
-
-
-/************************************************************************
- * Definitions taken from Realport Dump.
- ************************************************************************/
-
-#define RPDUMP_MAGIC "Digi-RealPort-1.0"
-
-#define RPDUMP_MESSAGE 0xE2 /* Descriptive message */
-#define RPDUMP_RESET 0xE7 /* Connection reset */
-#define RPDUMP_CLIENT 0xE8 /* Client data */
-#define RPDUMP_SERVER 0xE9 /* Server data */
-
-
-/************************************************************************
- * Node request/response definitions.
- ************************************************************************/
-
-#define NR_ECHO 0x0001 /* Server echo packet */
-#define NR_IDENT 0x0002 /* Server Product ID */
-#define NR_CAPABILITY 0x0004 /* Server Capabilties */
-#define NR_VPD 0x0008 /* Server VPD, if any */
-#define NR_PASSWORD 0x0010 /* Server Password */
-
-/************************************************************************
- * Registration status of the node's Linux struct tty_driver structures.
- ************************************************************************/
-#define SERIAL_TTDRV_REG 0x0001 /* nd_serial_ttdriver registered */
-#define CALLOUT_TTDRV_REG 0x0002 /* nd_callout_ttdriver registered */
-#define XPRINT_TTDRV_REG 0x0004 /* nd_xprint_ttdriver registered */
-
-
-/************************************************************************
- * Node structure. There exists one of these for each associated
- * realport server.
- ************************************************************************/
-
-struct nd_struct {
- struct list_head list;
- long nd_major; /* Node's major number */
- long nd_ID; /* Node's ID code */
-
- char nd_serial_name[50]; /* "tty_dgrp_<id>_" + null */
- char nd_callout_name[50]; /* "cu_dgrp_<id>_" + null */
- char nd_xprint_name[50]; /* "pr_dgrp_<id>_" + null */
-
- char password[16]; /* Password for server, if needed */
- int nd_tty_ref_cnt; /* Linux tty reference count */
-
- struct proc_dir_entry *nd_net_de; /* Dir entry for /proc/dgrp/net */
- struct proc_dir_entry *nd_mon_de; /* Dir entry for /proc/dgrp/mon */
- struct proc_dir_entry *nd_ports_de; /* Dir entry for /proc/dgrp/ports*/
- struct proc_dir_entry *nd_dpa_de; /* Dir entry for /proc/dgrp/dpa */
-
- spinlock_t nd_lock; /* General node lock */
-
- struct semaphore nd_net_semaphore; /* Net read/write lock */
- struct semaphore nd_mon_semaphore; /* Monitor buffer lock */
- spinlock_t nd_dpa_lock; /* DPA buffer lock */
-
- enum dgrp_nd_state_t nd_state; /* NS_* network state */
- int nd_chan_count; /* # active channels */
- int nd_flag; /* Node flags */
- int nd_send; /* Responses to send */
- int nd_expect; /* Responses we expect */
-
- u8 *nd_iobuf; /* Network R/W Buffer */
- wait_queue_head_t nd_tx_waitq; /* Network select wait queue */
-
- u8 *nd_inputbuf; /* Input Buffer */
- u8 *nd_inputflagbuf; /* Input Flags Buffer */
-
- int nd_tx_deposit; /* Accumulated transmit deposits */
- int nd_tx_charge; /* Accumulated transmit charges */
- int nd_tx_credit; /* Current TX credit */
- int nd_tx_ready; /* Ready to transmit */
- int nd_tx_work; /* TX work waiting */
- ulong nd_tx_time; /* Last transmit time */
- ulong nd_poll_time; /* Next scheduled poll time */
-
- int nd_delay; /* Current TX delay */
- int nd_rate; /* Current TX rate */
- struct link_struct nd_link; /* Link speed params. */
-
- int nd_seq_in; /* TX seq in ptr */
- int nd_seq_out; /* TX seq out ptr */
- int nd_unack; /* Unacknowledged byte count */
- int nd_remain; /* Remaining receive bytes */
- int nd_tx_module; /* Current TX module # */
- int nd_rx_module; /* Current RX module # */
- char *nd_error; /* Protocol error message */
-
- int nd_write_count; /* drp_write() call count */
- int nd_read_count; /* drp_read() count */
- int nd_send_count; /* TCP message sent */
- int nd_tx_byte; /* Transmit byte count */
- int nd_rx_byte; /* Receive byte count */
-
- ulong nd_mon_lbolt; /* Monitor start time */
- int nd_mon_flag; /* Monitor flags */
- int nd_mon_in; /* Monitor in pointer */
- int nd_mon_out; /* Monitor out pointer */
- wait_queue_head_t nd_mon_wqueue; /* Monitor wait queue (on flags) */
- u8 *nd_mon_buf; /* Monitor buffer */
-
- ulong nd_dpa_lbolt; /* DPA start time */
- int nd_dpa_flag; /* DPA flags */
- int nd_dpa_in; /* DPA in pointer */
- int nd_dpa_out; /* DPA out pointer */
- wait_queue_head_t nd_dpa_wqueue; /* DPA wait queue (on flags) */
- u8 *nd_dpa_buf; /* DPA buffer */
-
- uint nd_dpa_debug;
- uint nd_dpa_port;
-
- wait_queue_head_t nd_seq_wque[SEQ_MAX]; /* TX thread wait queues */
- u8 nd_seq_wait[SEQ_MAX]; /* Transmit thread wait count */
-
- ushort nd_seq_size[SEQ_MAX]; /* Transmit seq packet size */
- ulong nd_seq_time[SEQ_MAX]; /* Transmit seq packet time */
-
- ushort nd_hw_ver; /* HW version returned from PS */
- ushort nd_sw_ver; /* SW version returned from PS */
- uint nd_hw_id; /* HW ID returned from PS */
- u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
- uint nd_vpd_len; /* VPD len, if any */
- u8 nd_vpd[VPDSIZE]; /* VPD, if any */
-
- ulong nd_ttdriver_flags; /* Registration status */
- struct tty_driver *nd_serial_ttdriver; /* Linux TTYDRIVER structure */
- struct tty_driver *nd_callout_ttdriver; /* Linux TTYDRIVER structure */
- struct tty_driver *nd_xprint_ttdriver; /* Linux TTYDRIVER structure */
-
- u8 *nd_writebuf; /* Used to cache data read
- * from user
- */
- struct ch_struct nd_chan[CHAN_MAX]; /* Channel array */
- struct device *nd_class_dev; /* Hang our sysfs stuff off of here */
-};
-
-#endif /* __DRP_H */
diff --git a/drivers/staging/emxx_udc/Kconfig b/drivers/staging/emxx_udc/Kconfig
new file mode 100644
index 000000000000..9bc6d3db86d9
--- /dev/null
+++ b/drivers/staging/emxx_udc/Kconfig
@@ -0,0 +1,10 @@
+config USB_EMXX
+ boolean "EMXX USB Function Device Controller"
+ depends on USB_GADGET && (ARCH_SHMOBILE || (ARM && COMPILE_TEST))
+ help
+ The Emma Mobile series of SoCs from Renesas Electronics and
+ former NEC Electronics include USB Function hardware.
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "emxx_udc" and force all
+ gadget drivers to also be dynamically linked.
diff --git a/drivers/staging/emxx_udc/Makefile b/drivers/staging/emxx_udc/Makefile
new file mode 100644
index 000000000000..6352724c0b57
--- /dev/null
+++ b/drivers/staging/emxx_udc/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_EMXX) := emxx_udc.o
diff --git a/drivers/staging/emxx_udc/TODO b/drivers/staging/emxx_udc/TODO
new file mode 100644
index 000000000000..1319379beb7e
--- /dev/null
+++ b/drivers/staging/emxx_udc/TODO
@@ -0,0 +1,4 @@
+* add clock framework support (platform device with CCF needs special care)
+* break out board-specific VBUS GPIO to work with multiplatform
+* DT bindings
+* move driver into drivers/usb/gadget/
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
new file mode 100644
index 000000000000..b2eaf0108e46
--- /dev/null
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -0,0 +1,3520 @@
+/*
+ * drivers/usb/gadget/emxx_udc.c
+ * EMXX FCD (Function Controller Driver) for USB.
+ *
+ * Copyright (C) 2010 Renesas Electronics Corporation
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include "emxx_udc.h"
+
+#define DRIVER_DESC "EMXX UDC driver"
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+static const char driver_name[] = "emxx_udc";
+static const char driver_desc[] = DRIVER_DESC;
+
+/*===========================================================================*/
+/* Prototype */
+static void _nbu2ss_ep_dma_abort(struct nbu2ss_udc *, struct nbu2ss_ep *);
+static void _nbu2ss_ep0_enable(struct nbu2ss_udc *);
+/*static void _nbu2ss_ep0_disable(struct nbu2ss_udc *);*/
+static void _nbu2ss_ep_done(struct nbu2ss_ep *, struct nbu2ss_req *, int);
+static void _nbu2ss_set_test_mode(struct nbu2ss_udc *, u32 mode);
+static void _nbu2ss_endpoint_toggle_reset(struct nbu2ss_udc *udc, u8 ep_adrs);
+
+static int _nbu2ss_pullup(struct nbu2ss_udc *, int);
+static void _nbu2ss_fifo_flush(struct nbu2ss_udc *, struct nbu2ss_ep *);
+
+/*===========================================================================*/
+/* Macro */
+#define _nbu2ss_zero_len_pkt(udc, epnum) \
+ _nbu2ss_ep_in_end(udc, epnum, 0, 0)
+
+
+/*===========================================================================*/
+/* Global */
+struct nbu2ss_udc udc_controller;
+
+
+/*-------------------------------------------------------------------------*/
+/* Read */
+static inline u32 _nbu2ss_readl(void *address)
+{
+ return __raw_readl(address) ;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Write */
+static inline void _nbu2ss_writel(void *address, u32 udata)
+{
+ __raw_writel(udata, address) ;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Set Bit */
+static inline void _nbu2ss_bitset(void *address, u32 udata)
+{
+ u32 reg_dt = __raw_readl(address) | (udata);
+ __raw_writel(reg_dt, address) ;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Clear Bit */
+static inline void _nbu2ss_bitclr(void *address, u32 udata)
+{
+ u32 reg_dt = __raw_readl(address) & ~(udata);
+ __raw_writel(reg_dt, address) ;
+}
+
+#ifdef UDC_DEBUG_DUMP
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_dump_register(struct nbu2ss_udc *udc)
+{
+ int i;
+ u32 reg_data;
+
+ pr_info("=== %s()\n", __func__);
+
+ if (udc == NULL) {
+ ERR("%s udc == NULL\n", __func__);
+ return;
+ }
+
+ spin_unlock(&udc->lock);
+
+ printk(KERN_DEBUG "\n-USB REG-\n");
+ for (i = 0x0 ; i < USB_BASE_SIZE ; i += 16) {
+ reg_data = _nbu2ss_readl(
+ (u32 *)IO_ADDRESS(USB_BASE_ADDRESS + i));
+ printk(KERN_DEBUG "USB%04x =%08x", i, (int)reg_data);
+
+ reg_data = _nbu2ss_readl(
+ (u32 *)IO_ADDRESS(USB_BASE_ADDRESS + i + 4));
+ printk(KERN_DEBUG " %08x", (int)reg_data);
+
+ reg_data = _nbu2ss_readl(
+ (u32 *)IO_ADDRESS(USB_BASE_ADDRESS + i + 8));
+ printk(KERN_DEBUG " %08x", (int)reg_data);
+
+ reg_data = _nbu2ss_readl(
+ (u32 *)IO_ADDRESS(USB_BASE_ADDRESS + i + 12));
+ printk(KERN_DEBUG " %08x\n", (int)reg_data);
+
+ }
+
+ spin_lock(&udc->lock);
+}
+#endif /* UDC_DEBUG_DUMP */
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint 0 Callback (Complete) */
+static void _nbu2ss_ep0_complete(struct usb_ep *_ep, struct usb_request *_req)
+{
+ u8 recipient;
+ u16 selector;
+ u32 test_mode;
+ struct usb_ctrlrequest *p_ctrl;
+ struct nbu2ss_udc *udc;
+
+ if ((_ep == NULL) || (_req == NULL))
+ return;
+
+ udc = (struct nbu2ss_udc *)_req->context;
+ p_ctrl = &udc->ctrl;
+ if ((p_ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+
+ if (p_ctrl->bRequest == USB_REQ_SET_FEATURE) {
+ /*-------------------------------------------------*/
+ /* SET_FEATURE */
+ recipient = (u8)(p_ctrl->bRequestType & USB_RECIP_MASK);
+ selector = p_ctrl->wValue;
+ if ((recipient == USB_RECIP_DEVICE) &&
+ (selector == USB_DEVICE_TEST_MODE)) {
+ test_mode = (u32)(p_ctrl->wIndex >> 8);
+ _nbu2ss_set_test_mode(udc, test_mode);
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+/* Initialization usb_request */
+static void _nbu2ss_create_ep0_packet(
+ struct nbu2ss_udc *udc,
+ void *p_buf,
+ unsigned length
+)
+{
+ udc->ep0_req.req.buf = p_buf;
+ udc->ep0_req.req.length = length;
+ udc->ep0_req.req.dma = 0;
+ udc->ep0_req.req.zero = TRUE;
+ udc->ep0_req.req.complete = _nbu2ss_ep0_complete;
+ udc->ep0_req.req.status = -EINPROGRESS;
+ udc->ep0_req.req.context = udc;
+ udc->ep0_req.req.actual = 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Acquisition of the first address of RAM(FIFO) */
+static u32 _nbu2ss_get_begin_ram_address(struct nbu2ss_udc *udc)
+{
+ u32 num, buf_type;
+ u32 data, last_ram_adr, use_ram_size;
+
+ PT_EP_REGS p_ep_regs;
+
+ last_ram_adr = (D_RAM_SIZE_CTRL / sizeof(u32)) * 2;
+ use_ram_size = 0;
+
+ for (num = 0; num < NUM_ENDPOINTS - 1; num++) {
+ p_ep_regs = &udc->p_regs->EP_REGS[num];
+ data = _nbu2ss_readl(&p_ep_regs->EP_PCKT_ADRS);
+ buf_type = _nbu2ss_readl(&p_ep_regs->EP_CONTROL) & EPn_BUF_TYPE;
+ if (buf_type == 0) {
+ /* Single Buffer */
+ use_ram_size += (data & EPn_MPKT) / sizeof(u32);
+ } else {
+ /* Double Buffer */
+ use_ram_size += ((data & EPn_MPKT) / sizeof(u32)) * 2;
+ }
+
+ if ((data >> 16) > last_ram_adr)
+ last_ram_adr = data>>16;
+ }
+
+ return last_ram_adr + use_ram_size;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Construction of Endpoint */
+static int _nbu2ss_ep_init(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ u32 num;
+ u32 data;
+ u32 begin_adrs;
+
+ if (ep->epnum == 0)
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ /*-------------------------------------------------------------*/
+ /* RAM Transfer Address */
+ begin_adrs = _nbu2ss_get_begin_ram_address(udc);
+ data = (begin_adrs << 16) | ep->ep.maxpacket;
+ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_PCKT_ADRS, data);
+
+ /*-------------------------------------------------------------*/
+ /* Interrupt Enable */
+ data = 1 << (ep->epnum + 8);
+ _nbu2ss_bitset(&udc->p_regs->USB_INT_ENA, data);
+
+ /*-------------------------------------------------------------*/
+ /* Endpoint Type(Mode) */
+ /* Bulk, Interrupt, ISO */
+ switch (ep->ep_type) {
+ case USB_ENDPOINT_XFER_BULK:
+ data = EPn_BULK;
+ break;
+
+ case USB_ENDPOINT_XFER_INT:
+ data = EPn_BUF_SINGLE | EPn_INTERRUPT;
+ break;
+
+ case USB_ENDPOINT_XFER_ISOC:
+ data = EPn_ISO;
+ break;
+
+ default:
+ data = 0;
+ break;
+ }
+
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+ _nbu2ss_endpoint_toggle_reset(udc, (ep->epnum|ep->direct));
+
+ if (ep->direct == USB_DIR_OUT) {
+ /*---------------------------------------------------------*/
+ /* OUT */
+ data = EPn_EN | EPn_BCLR | EPn_DIR0;
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = (EPn_ONAK | EPn_OSTL_EN | EPn_OSTL);
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = (EPn_OUT_EN | EPn_OUT_END_EN);
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_INT_ENA, data);
+ } else {
+ /*---------------------------------------------------------*/
+ /* IN */
+ data = (EPn_EN | EPn_BCLR | EPn_AUTO);
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = (EPn_ISTL);
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = (EPn_IN_EN | EPn_IN_END_EN);
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_INT_ENA, data);
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Release of Endpoint */
+static int _nbu2ss_epn_exit(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ u32 num;
+ u32 data;
+
+ if ((ep->epnum == 0) || (udc->vbus_active == 0))
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ /*-------------------------------------------------------------*/
+ /* RAM Transfer Address */
+ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_PCKT_ADRS, 0);
+
+ /*-------------------------------------------------------------*/
+ /* Interrupt Disable */
+ data = 1 << (ep->epnum + 8);
+ _nbu2ss_bitclr(&udc->p_regs->USB_INT_ENA, data);
+
+ if (ep->direct == USB_DIR_OUT) {
+ /*---------------------------------------------------------*/
+ /* OUT */
+ data = EPn_ONAK | EPn_BCLR;
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = EPn_EN | EPn_DIR0;
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = EPn_OUT_EN | EPn_OUT_END_EN;
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_INT_ENA, data);
+ } else {
+ /*---------------------------------------------------------*/
+ /* IN */
+ data = EPn_BCLR;
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = EPn_EN | EPn_AUTO;
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+
+ data = EPn_IN_EN | EPn_IN_END_EN;
+ _nbu2ss_bitclr(&udc->p_regs->EP_REGS[num].EP_INT_ENA, data);
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* DMA setting (without Endpoint 0) */
+static void _nbu2ss_ep_dma_init(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ u32 num;
+ u32 data;
+
+ data = _nbu2ss_readl(&udc->p_regs->USBSSCONF);
+ if (((ep->epnum == 0) || (data & (1 << ep->epnum)) == 0))
+ return; /* Not Support DMA */
+
+ num = ep->epnum - 1;
+
+ if (ep->direct == USB_DIR_OUT) {
+ /*---------------------------------------------------------*/
+ /* OUT */
+ data = ep->ep.maxpacket;
+ _nbu2ss_writel(&udc->p_regs->EP_DCR[num].EP_DCR2, data);
+
+ /*---------------------------------------------------------*/
+ /* Transfer Direct */
+ data = DCR1_EPn_DIR0;
+ _nbu2ss_bitset(&udc->p_regs->EP_DCR[num].EP_DCR1, data);
+
+ /*---------------------------------------------------------*/
+ /* DMA Mode etc. */
+ data = EPn_STOP_MODE | EPn_STOP_SET | EPn_DMAMODE0;
+ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_DMA_CTRL, data);
+ } else {
+ /*---------------------------------------------------------*/
+ /* IN */
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, EPn_AUTO);
+
+ /*---------------------------------------------------------*/
+ /* DMA Mode etc. */
+ data = EPn_BURST_SET | EPn_DMAMODE0;
+ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_DMA_CTRL, data);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+/* DMA setting release */
+static void _nbu2ss_ep_dma_exit(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ u32 num;
+ u32 data;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (udc->vbus_active == 0)
+ return; /* VBUS OFF */
+
+ data = _nbu2ss_readl(&preg->USBSSCONF);
+ if ((ep->epnum == 0) || ((data & (1 << ep->epnum)) == 0))
+ return; /* Not Support DMA */
+
+ num = ep->epnum - 1;
+
+ _nbu2ss_ep_dma_abort(udc, ep);
+
+ if (ep->direct == USB_DIR_OUT) {
+ /*---------------------------------------------------------*/
+ /* OUT */
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR2, 0);
+ _nbu2ss_bitclr(&preg->EP_DCR[num].EP_DCR1, DCR1_EPn_DIR0);
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_DMA_CTRL, 0);
+ } else {
+ /*---------------------------------------------------------*/
+ /* IN */
+ _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL, EPn_AUTO);
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_DMA_CTRL, 0);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+/* Abort DMA */
+static void _nbu2ss_ep_dma_abort(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ PT_FC_REGS preg = udc->p_regs;
+
+ _nbu2ss_bitclr(&preg->EP_DCR[ep->epnum-1].EP_DCR1, DCR1_EPn_REQEN);
+ mdelay(DMA_DISABLE_TIME); /* DCR1_EPn_REQEN Clear */
+ _nbu2ss_bitclr(&preg->EP_REGS[ep->epnum-1].EP_DMA_CTRL, EPn_DMA_EN);
+}
+
+/*-------------------------------------------------------------------------*/
+/* Start IN Transfer */
+static void _nbu2ss_ep_in_end(
+ struct nbu2ss_udc *udc,
+ u32 epnum,
+ u32 data32,
+ u32 length
+)
+{
+ u32 data;
+ u32 num;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (length >= sizeof(u32))
+ return;
+
+ if (epnum == 0) {
+ _nbu2ss_bitclr(&preg->EP0_CONTROL, EP0_AUTO);
+
+ /* Writing of 1-4 bytes */
+ if (length)
+ _nbu2ss_writel(&preg->EP0_WRITE, data32);
+
+ data = ((length << 5) & EP0_DW) | EP0_DEND;
+ _nbu2ss_writel(&preg->EP0_CONTROL, data);
+
+ _nbu2ss_bitset(&preg->EP0_CONTROL, EP0_AUTO);
+ } else {
+ num = epnum - 1;
+
+ _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL, EPn_AUTO);
+
+ /* Writing of 1-4 bytes */
+ if (length)
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_WRITE, data32);
+
+ data = (((((u32)length) << 5) & EPn_DW) | EPn_DEND);
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data);
+
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, EPn_AUTO);
+ }
+
+ return;
+}
+
+#ifdef USE_DMA
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_dma_map_single(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u8 direct
+)
+{
+ if (req->req.dma == DMA_ADDR_INVALID) {
+ if (req->unaligned)
+ req->req.dma = ep->phys_buf;
+ else {
+ req->req.dma = dma_map_single(
+ udc->gadget.dev.parent,
+ req->req.buf,
+ req->req.length,
+ (direct == USB_DIR_IN)
+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ }
+ req->mapped = 1;
+ } else {
+ if (!req->unaligned)
+ dma_sync_single_for_device(
+ udc->gadget.dev.parent,
+ req->req.dma,
+ req->req.length,
+ (direct == USB_DIR_IN)
+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+ req->mapped = 0;
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_dma_unmap_single(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u8 direct
+)
+{
+ u8 data[4];
+ u8 *p;
+ u32 count = 0;
+
+ if (direct == USB_DIR_OUT) {
+ count = req->req.actual % 4;
+ if (count) {
+ p = req->req.buf;
+ p += (req->req.actual - count);
+ memcpy(data, p, count);
+ }
+ }
+
+ if (req->mapped) {
+ if (req->unaligned) {
+ if (direct == USB_DIR_OUT)
+ memcpy(req->req.buf, ep->virt_buf,
+ req->req.actual & 0xfffffffc);
+ } else
+ dma_unmap_single(udc->gadget.dev.parent,
+ req->req.dma, req->req.length,
+ (direct == USB_DIR_IN)
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ req->req.dma = DMA_ADDR_INVALID;
+ req->mapped = 0;
+ } else {
+ if (!req->unaligned)
+ dma_sync_single_for_cpu(udc->gadget.dev.parent,
+ req->req.dma, req->req.length,
+ (direct == USB_DIR_IN)
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ }
+
+ if (count) {
+ p = req->req.buf;
+ p += (req->req.actual - count);
+ memcpy(p, data, count);
+ }
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint 0 OUT Transfer (PIO) */
+static int EP0_out_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length)
+{
+ u32 i;
+ int nret = 0;
+ u32 iWordLength = 0;
+ USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf;
+
+ /*------------------------------------------------------------*/
+ /* Read Length */
+ iWordLength = length / sizeof(u32);
+
+ /*------------------------------------------------------------*/
+ /* PIO Read */
+ if (iWordLength) {
+ for (i = 0; i < iWordLength; i++) {
+ pBuf32->dw = _nbu2ss_readl(&udc->p_regs->EP0_READ);
+ pBuf32++;
+ }
+ nret = iWordLength * sizeof(u32);
+ }
+
+ return nret;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint 0 OUT Transfer (PIO, OverBytes) */
+static int EP0_out_OverBytes(struct nbu2ss_udc *udc, u8 *pBuf, u32 length)
+{
+ u32 i;
+ u32 iReadSize = 0;
+ USB_REG_ACCESS Temp32;
+ USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf;
+
+ if ((0 < length) && (length < sizeof(u32))) {
+ Temp32.dw = _nbu2ss_readl(&udc->p_regs->EP0_READ);
+ for (i = 0 ; i < length ; i++)
+ pBuf32->byte.DATA[i] = Temp32.byte.DATA[i];
+ iReadSize += length;
+ }
+
+ return iReadSize;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint 0 IN Transfer (PIO) */
+static int EP0_in_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length)
+{
+ u32 i;
+ u32 iMaxLength = EP0_PACKETSIZE;
+ u32 iWordLength = 0;
+ u32 iWriteLength = 0;
+ USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf;
+
+ /*------------------------------------------------------------*/
+ /* Transfer Length */
+ if (iMaxLength < length)
+ iWordLength = iMaxLength / sizeof(u32);
+ else
+ iWordLength = length / sizeof(u32);
+
+ /*------------------------------------------------------------*/
+ /* PIO */
+ for (i = 0; i < iWordLength; i++) {
+ _nbu2ss_writel(&udc->p_regs->EP0_WRITE, pBuf32->dw);
+ pBuf32++;
+ iWriteLength += sizeof(u32);
+ }
+
+ return iWriteLength;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint 0 IN Transfer (PIO, OverBytes) */
+static int EP0_in_OverBytes(struct nbu2ss_udc *udc, u8 *pBuf, u32 iRemainSize)
+{
+ u32 i;
+ USB_REG_ACCESS Temp32;
+ USB_REG_ACCESS *pBuf32 = (USB_REG_ACCESS *)pBuf;
+
+ if ((0 < iRemainSize) && (iRemainSize < sizeof(u32))) {
+ for (i = 0 ; i < iRemainSize ; i++)
+ Temp32.byte.DATA[i] = pBuf32->byte.DATA[i];
+ _nbu2ss_ep_in_end(udc, 0, Temp32.dw, iRemainSize);
+
+ return iRemainSize;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Transfer NULL Packet (Epndoint 0) */
+static int EP0_send_NULL(struct nbu2ss_udc *udc, bool pid_flag)
+{
+ u32 data;
+
+ data = _nbu2ss_readl(&udc->p_regs->EP0_CONTROL);
+ data &= ~(u32)EP0_INAK;
+
+ if (pid_flag)
+ data |= (EP0_INAK_EN | EP0_PIDCLR | EP0_DEND);
+ else
+ data |= (EP0_INAK_EN | EP0_DEND);
+
+ _nbu2ss_writel(&udc->p_regs->EP0_CONTROL, data);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Receive NULL Packet (Endpoint 0) */
+static int EP0_receive_NULL(struct nbu2ss_udc *udc, bool pid_flag)
+{
+ u32 data;
+
+ data = _nbu2ss_readl(&udc->p_regs->EP0_CONTROL);
+ data &= ~(u32)EP0_ONAK;
+
+ if (pid_flag)
+ data |= EP0_PIDCLR;
+
+ _nbu2ss_writel(&udc->p_regs->EP0_CONTROL, data);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_ep0_in_transfer(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req
+)
+{
+ u8 *pBuffer; /* IN Data Buffer */
+ u32 data;
+ u32 iRemainSize = 0;
+ int result = 0;
+
+ /*-------------------------------------------------------------*/
+ /* End confirmation */
+ if (req->req.actual == req->req.length) {
+ if ((req->req.actual % EP0_PACKETSIZE) == 0) {
+ if (req->zero) {
+ req->zero = 0;
+ EP0_send_NULL(udc, FALSE);
+ return 1;
+ }
+ }
+
+ return 0; /* Transfer End */
+ }
+
+ /*-------------------------------------------------------------*/
+ /* NAK release */
+ data = _nbu2ss_readl(&udc->p_regs->EP0_CONTROL);
+ data |= EP0_INAK_EN;
+ data &= ~(u32)EP0_INAK;
+ _nbu2ss_writel(&udc->p_regs->EP0_CONTROL, data);
+
+ iRemainSize = req->req.length - req->req.actual;
+ pBuffer = (u8 *)req->req.buf;
+ pBuffer += req->req.actual;
+
+ /*-------------------------------------------------------------*/
+ /* Data transfer */
+ result = EP0_in_PIO(udc, pBuffer, iRemainSize);
+
+ req->div_len = result;
+ iRemainSize -= result;
+
+ if (iRemainSize == 0) {
+ EP0_send_NULL(udc, FALSE);
+ return result;
+ }
+
+ if ((iRemainSize < sizeof(u32)) && (result != EP0_PACKETSIZE)) {
+ pBuffer += result;
+ result += EP0_in_OverBytes(udc, pBuffer, iRemainSize);
+ req->div_len = result;
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_ep0_out_transfer(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req
+)
+{
+ u8 *pBuffer;
+ u32 iRemainSize;
+ u32 iRecvLength;
+ int result = 0;
+ int fRcvZero;
+
+ /*-------------------------------------------------------------*/
+ /* Receive data confirmation */
+ iRecvLength = _nbu2ss_readl(&udc->p_regs->EP0_LENGTH) & EP0_LDATA;
+ if (iRecvLength != 0) {
+
+ fRcvZero = 0;
+
+ iRemainSize = req->req.length - req->req.actual;
+ pBuffer = (u8 *)req->req.buf;
+ pBuffer += req->req.actual;
+
+ result = EP0_out_PIO(udc, pBuffer
+ , min(iRemainSize, iRecvLength));
+ if (result < 0)
+ return result;
+
+ req->req.actual += result;
+ iRecvLength -= result;
+
+ if ((0 < iRecvLength) && (iRecvLength < sizeof(u32))) {
+ pBuffer += result;
+ iRemainSize -= result;
+
+ result = EP0_out_OverBytes(udc, pBuffer
+ , min(iRemainSize, iRecvLength));
+ req->req.actual += result;
+ }
+ } else {
+ fRcvZero = 1;
+ }
+
+ /*-------------------------------------------------------------*/
+ /* End confirmation */
+ if (req->req.actual == req->req.length) {
+ if ((req->req.actual % EP0_PACKETSIZE) == 0) {
+ if (req->zero) {
+ req->zero = 0;
+ EP0_receive_NULL(udc, FALSE);
+ return 1;
+ }
+ }
+
+ return 0; /* Transfer End */
+ }
+
+ if ((req->req.actual % EP0_PACKETSIZE) != 0)
+ return 0; /* Short Packet Transfer End */
+
+ if (req->req.actual > req->req.length) {
+ ERR(" *** Overrun Error\n");
+ return -EOVERFLOW;
+ }
+
+ if (fRcvZero != 0) {
+ iRemainSize = _nbu2ss_readl(&udc->p_regs->EP0_CONTROL);
+ if (iRemainSize & EP0_ONAK) {
+ /*---------------------------------------------------*/
+ /* NACK release */
+ _nbu2ss_bitclr(&udc->p_regs->EP0_CONTROL, EP0_ONAK);
+ }
+ result = 1;
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_out_dma(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_req *req,
+ u32 num,
+ u32 length
+)
+{
+ u8 *pBuffer;
+ u32 mpkt;
+ u32 lmpkt;
+ u32 dmacnt;
+ u32 burst = 1;
+ u32 data;
+ int result = -EINVAL;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (req->dma_flag)
+ return 1; /* DMA is forwarded */
+
+ req->dma_flag = TRUE;
+ pBuffer = (u8 *)req->req.dma;
+ pBuffer += req->req.actual;
+
+ /* DMA Address */
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_TADR, (u32)pBuffer);
+
+ /* Number of transfer packets */
+ mpkt = _nbu2ss_readl(&preg->EP_REGS[num].EP_PCKT_ADRS) & EPn_MPKT;
+ dmacnt = (length / mpkt);
+ lmpkt = (length % mpkt) & ~(u32)0x03;
+
+ if (DMA_MAX_COUNT < dmacnt) {
+ dmacnt = DMA_MAX_COUNT;
+ lmpkt = 0;
+ } else if (0 != lmpkt) {
+ if (0 == dmacnt)
+ burst = 0; /* Burst OFF */
+ dmacnt++;
+ }
+
+ data = mpkt | (lmpkt << 16);
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR2, data);
+
+ data = ((dmacnt & 0xff) << 16) | DCR1_EPn_DIR0 | DCR1_EPn_REQEN;
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR1, data);
+
+ if (0 == burst) {
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_LEN_DCNT, 0);
+ _nbu2ss_bitclr(&preg->EP_REGS[num].EP_DMA_CTRL, EPn_BURST_SET);
+ } else {
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_LEN_DCNT
+ , (dmacnt << 16));
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_DMA_CTRL, EPn_BURST_SET);
+ }
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_DMA_CTRL, EPn_DMA_EN);
+
+ result = length & ~(u32)0x03;
+ req->div_len = result;
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_out_pio(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u32 length
+)
+{
+ u8 *pBuffer;
+ u32 i;
+ u32 data;
+ u32 iWordLength;
+ USB_REG_ACCESS Temp32;
+ USB_REG_ACCESS *pBuf32;
+ int result = 0;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (req->dma_flag)
+ return 1; /* DMA is forwarded */
+
+ if (length == 0)
+ return 0;
+
+ pBuffer = (u8 *)req->req.buf;
+ pBuf32 = (USB_REG_ACCESS *)(pBuffer + req->req.actual);
+
+ iWordLength = length / sizeof(u32);
+ if (iWordLength > 0) {
+ /*---------------------------------------------------------*/
+ /* Copy of every four bytes */
+ for (i = 0; i < iWordLength; i++) {
+ pBuf32->dw =
+ _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_READ);
+ pBuf32++;
+ }
+ result = iWordLength * sizeof(u32);
+ }
+
+ data = length - result;
+ if (data > 0) {
+ /*---------------------------------------------------------*/
+ /* Copy of fraction byte */
+ Temp32.dw = _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_READ);
+ for (i = 0 ; i < data ; i++)
+ pBuf32->byte.DATA[i] = Temp32.byte.DATA[i];
+ result += data;
+ }
+
+ req->req.actual += result;
+
+ if ((req->req.actual == req->req.length)
+ || ((req->req.actual % ep->ep.maxpacket) != 0)) {
+
+ result = 0;
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_out_data(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u32 data_size
+)
+{
+ u32 num;
+ u32 iBufSize;
+ int nret = 1;
+
+ if (ep->epnum == 0)
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ iBufSize = min((req->req.length - req->req.actual), data_size);
+
+ if ((ep->ep_type != USB_ENDPOINT_XFER_INT)
+ && (req->req.dma != 0)
+ && (iBufSize >= sizeof(u32))) {
+ nret = _nbu2ss_out_dma(udc, req, num, iBufSize);
+ } else {
+ iBufSize = min(iBufSize, (u32)ep->ep.maxpacket);
+ nret = _nbu2ss_epn_out_pio(udc, ep, req, iBufSize);
+ }
+
+ return nret;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_out_transfer(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req
+)
+{
+ u32 num;
+ u32 iRecvLength;
+ int result = 1;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (ep->epnum == 0)
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ /*-------------------------------------------------------------*/
+ /* Receive Length */
+ iRecvLength
+ = _nbu2ss_readl(&preg->EP_REGS[num].EP_LEN_DCNT) & EPn_LDATA;
+
+ if (iRecvLength != 0) {
+ result = _nbu2ss_epn_out_data(udc, ep, req, iRecvLength);
+ if (iRecvLength < ep->ep.maxpacket) {
+ if (iRecvLength == result) {
+ req->req.actual += result;
+ result = 0;
+ }
+ }
+ } else {
+ if ((req->req.actual == req->req.length)
+ || ((req->req.actual % ep->ep.maxpacket) != 0)) {
+
+ result = 0;
+ }
+ }
+
+ if (result == 0) {
+ if ((req->req.actual % ep->ep.maxpacket) == 0) {
+ if (req->zero) {
+ req->zero = 0;
+ return 1;
+ }
+ }
+ }
+
+ if (req->req.actual > req->req.length) {
+ ERR(" *** Overrun Error\n");
+ ERR(" *** actual = %d, length = %d\n",
+ req->req.actual, req->req.length);
+ result = -EOVERFLOW;
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_in_dma(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u32 num,
+ u32 length
+)
+{
+ u8 *pBuffer;
+ u32 mpkt; /* MaxPacketSize */
+ u32 lmpkt; /* Last Packet Data Size */
+ u32 dmacnt; /* IN Data Size */
+ u32 iWriteLength;
+ u32 data;
+ int result = -EINVAL;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (req->dma_flag)
+ return 1; /* DMA is forwarded */
+
+#ifdef USE_DMA
+ if (req->req.actual == 0)
+ _nbu2ss_dma_map_single(udc, ep, req, USB_DIR_IN);
+#endif
+ req->dma_flag = TRUE;
+
+ /* MAX Packet Size */
+ mpkt = _nbu2ss_readl(&preg->EP_REGS[num].EP_PCKT_ADRS) & EPn_MPKT;
+
+ if ((DMA_MAX_COUNT * mpkt) < length)
+ iWriteLength = DMA_MAX_COUNT * mpkt;
+ else
+ iWriteLength = length;
+
+ /*------------------------------------------------------------*/
+ /* Number of transmission packets */
+ if (mpkt < iWriteLength) {
+ dmacnt = iWriteLength / mpkt;
+ lmpkt = (iWriteLength % mpkt) & ~(u32)0x3;
+ if (lmpkt != 0)
+ dmacnt++;
+ else
+ lmpkt = mpkt & ~(u32)0x3;
+
+ } else {
+ dmacnt = 1;
+ lmpkt = iWriteLength & ~(u32)0x3;
+ }
+
+ /* Packet setting */
+ data = mpkt | (lmpkt << 16);
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR2, data);
+
+ /* Address setting */
+ pBuffer = (u8 *)req->req.dma;
+ pBuffer += req->req.actual;
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_TADR, (u32)pBuffer);
+
+ /* Packet and DMA setting */
+ data = ((dmacnt & 0xff) << 16) | DCR1_EPn_REQEN;
+ _nbu2ss_writel(&preg->EP_DCR[num].EP_DCR1, data);
+
+ /* Packet setting of EPC */
+ data = dmacnt << 16;
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_LEN_DCNT, data);
+
+ /*DMA setting of EPC */
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_DMA_CTRL, EPn_DMA_EN);
+
+ result = iWriteLength & ~(u32)0x3;
+ req->div_len = result;
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_in_pio(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u32 length
+)
+{
+ u8 *pBuffer;
+ u32 i;
+ u32 data;
+ u32 iWordLength;
+ USB_REG_ACCESS Temp32;
+ USB_REG_ACCESS *pBuf32 = NULL;
+ int result = 0;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (req->dma_flag)
+ return 1; /* DMA is forwarded */
+
+ if (length > 0) {
+ pBuffer = (u8 *)req->req.buf;
+ pBuf32 = (USB_REG_ACCESS *)(pBuffer + req->req.actual);
+
+ iWordLength = length / sizeof(u32);
+ if (iWordLength > 0) {
+ for (i = 0; i < iWordLength; i++) {
+ _nbu2ss_writel(
+ &preg->EP_REGS[ep->epnum-1].EP_WRITE
+ , pBuf32->dw
+ );
+
+ pBuf32++;
+ }
+ result = iWordLength * sizeof(u32);
+ }
+ }
+
+ if (result != ep->ep.maxpacket) {
+ data = length - result;
+ Temp32.dw = 0;
+ for (i = 0 ; i < data ; i++)
+ Temp32.byte.DATA[i] = pBuf32->byte.DATA[i];
+
+ _nbu2ss_ep_in_end(udc, ep->epnum, Temp32.dw, data);
+ result += data;
+ }
+
+ req->div_len = result;
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_in_data(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ u32 data_size
+)
+{
+ u32 num;
+ int nret = 1;
+
+ if (ep->epnum == 0)
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ if ((ep->ep_type != USB_ENDPOINT_XFER_INT)
+ && (req->req.dma != 0)
+ && (data_size >= sizeof(u32))) {
+ nret = _nbu2ss_in_dma(udc, ep, req, num, data_size);
+ } else {
+ data_size = min(data_size, (u32)ep->ep.maxpacket);
+ nret = _nbu2ss_epn_in_pio(udc, ep, req, data_size);
+ }
+
+ return nret;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_epn_in_transfer(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req
+)
+{
+ u32 num;
+ u32 iBufSize;
+ int result = 0;
+ u32 status;
+
+ if (ep->epnum == 0)
+ return -EINVAL;
+
+ num = ep->epnum - 1;
+
+ status = _nbu2ss_readl(&udc->p_regs->EP_REGS[num].EP_STATUS);
+
+ /*-------------------------------------------------------------*/
+ /* State confirmation of FIFO */
+ if (req->req.actual == 0) {
+ if ((status & EPn_IN_EMPTY) == 0)
+ return 1; /* Not Empty */
+
+ } else {
+ if ((status & EPn_IN_FULL) != 0)
+ return 1; /* Not Empty */
+ }
+
+ /*-------------------------------------------------------------*/
+ /* Start tranfer */
+ iBufSize = req->req.length - req->req.actual;
+ if (iBufSize > 0)
+ result = _nbu2ss_epn_in_data(udc, ep, req, iBufSize);
+ else if (req->req.length == 0)
+ _nbu2ss_zero_len_pkt(udc, ep->epnum);
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_start_transfer(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ bool bflag)
+{
+ int nret = -EINVAL;
+
+ req->dma_flag = FALSE;
+ req->div_len = 0;
+
+ if (req->req.length == 0)
+ req->zero = 0;
+ else {
+ if ((req->req.length % ep->ep.maxpacket) == 0)
+ req->zero = req->req.zero;
+ else
+ req->zero = 0;
+ }
+
+ if (ep->epnum == 0) {
+ /* EP0 */
+ switch (udc->ep0state) {
+ case EP0_IN_DATA_PHASE:
+ nret = _nbu2ss_ep0_in_transfer(udc, ep, req);
+ break;
+
+ case EP0_OUT_DATA_PHASE:
+ nret = _nbu2ss_ep0_out_transfer(udc, ep, req);
+ break;
+
+ case EP0_IN_STATUS_PHASE:
+ nret = EP0_send_NULL(udc, TRUE);
+ break;
+
+ default:
+ break;
+ }
+
+ } else {
+ /* EPn */
+ if (ep->direct == USB_DIR_OUT) {
+ /* OUT */
+ if (bflag == FALSE)
+ nret = _nbu2ss_epn_out_transfer(udc, ep, req);
+ } else {
+ /* IN */
+ nret = _nbu2ss_epn_in_transfer(udc, ep, req);
+ }
+ }
+
+ return nret;
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_restert_transfer(struct nbu2ss_ep *ep)
+{
+ u32 length;
+ bool bflag = FALSE;
+ struct nbu2ss_req *req;
+
+ if (list_empty(&ep->queue))
+ req = NULL;
+ else
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+
+ if (req == NULL)
+ return;
+
+ if (ep->epnum > 0) {
+ length = _nbu2ss_readl(
+ &ep->udc->p_regs->EP_REGS[ep->epnum-1].EP_LEN_DCNT);
+
+ length &= EPn_LDATA;
+ if (length < ep->ep.maxpacket)
+ bflag = TRUE;
+ }
+
+ _nbu2ss_start_transfer(ep->udc, ep, req, bflag);
+}
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint Toggle Reset */
+static void _nbu2ss_endpoint_toggle_reset(
+ struct nbu2ss_udc *udc,
+ u8 ep_adrs)
+{
+ u8 num;
+ u32 data;
+
+ if ((ep_adrs == 0) || (ep_adrs == 0x80))
+ return;
+
+ num = (ep_adrs & 0x7F) - 1;
+
+ if (ep_adrs & USB_DIR_IN)
+ data = EPn_IPIDCLR;
+ else
+ data = EPn_BCLR | EPn_OPIDCLR;
+
+ _nbu2ss_bitset(&udc->p_regs->EP_REGS[num].EP_CONTROL, data);
+}
+
+/*-------------------------------------------------------------------------*/
+/* Endpoint STALL set */
+static void _nbu2ss_set_endpoint_stall(
+ struct nbu2ss_udc *udc,
+ u8 ep_adrs,
+ bool bstall)
+{
+ u8 num, epnum;
+ u32 data;
+ struct nbu2ss_ep *ep;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if ((ep_adrs == 0) || (ep_adrs == 0x80)) {
+ if (bstall) {
+ /* Set STALL */
+ _nbu2ss_bitset(&preg->EP0_CONTROL, EP0_STL);
+ } else {
+ /* Clear STALL */
+ _nbu2ss_bitclr(&preg->EP0_CONTROL, EP0_STL);
+ }
+ } else {
+ epnum = ep_adrs & USB_ENDPOINT_NUMBER_MASK;
+ num = epnum - 1;
+ ep = &udc->ep[epnum];
+
+ if (bstall) {
+ /* Set STALL */
+ ep->halted = TRUE;
+
+ if (ep_adrs & USB_DIR_IN)
+ data = EPn_BCLR | EPn_ISTL;
+ else
+ data = EPn_OSTL_EN | EPn_OSTL;
+
+ _nbu2ss_bitset(&preg->EP_REGS[num].EP_CONTROL, data);
+ } else {
+ /* Clear STALL */
+ ep->stalled = FALSE;
+ if (ep_adrs & USB_DIR_IN) {
+ _nbu2ss_bitclr(&preg->EP_REGS[num].EP_CONTROL
+ , EPn_ISTL);
+ } else {
+ data =
+ _nbu2ss_readl(&preg->EP_REGS[num].EP_CONTROL);
+
+ data &= ~EPn_OSTL;
+ data |= EPn_OSTL_EN;
+
+ _nbu2ss_writel(&preg->EP_REGS[num].EP_CONTROL
+ , data);
+ }
+
+ ep->stalled = FALSE;
+ if (ep->halted) {
+ ep->halted = FALSE;
+ _nbu2ss_restert_transfer(ep);
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* Device Descriptor */
+static struct usb_device_descriptor device_desc = {
+ .bLength = sizeof(device_desc),
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bDeviceClass = USB_CLASS_VENDOR_SPEC,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ .bMaxPacketSize0 = 64,
+ .idVendor = __constant_cpu_to_le16 (0x0409),
+ .idProduct = __constant_cpu_to_le16 (0xfff0),
+ .bcdDevice = 0xffff,
+ .iManufacturer = 0x00,
+ .iProduct = 0x00,
+ .iSerialNumber = 0x00,
+ .bNumConfigurations = 0x01,
+};
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_set_test_mode(struct nbu2ss_udc *udc, u32 mode)
+{
+ u32 data;
+
+ if (mode > MAX_TEST_MODE_NUM)
+ return;
+
+ pr_info("SET FEATURE : test mode = %d\n", mode);
+
+ data = _nbu2ss_readl(&udc->p_regs->USB_CONTROL);
+ data &= ~TEST_FORCE_ENABLE;
+ data |= mode << TEST_MODE_SHIFT;
+
+ _nbu2ss_writel(&udc->p_regs->USB_CONTROL, data);
+ _nbu2ss_bitset(&udc->p_regs->TEST_CONTROL, CS_TESTMODEEN);
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_set_feature_device(
+ struct nbu2ss_udc *udc,
+ u16 selector,
+ u16 wIndex
+)
+{
+ int result = -EOPNOTSUPP;
+
+ switch (selector) {
+ case USB_DEVICE_REMOTE_WAKEUP:
+ if (0x0000 == wIndex) {
+ udc->remote_wakeup = U2F_ENABLE;
+ result = 0;
+ }
+ break;
+
+ case USB_DEVICE_TEST_MODE:
+ wIndex = wIndex >> 8;
+ if (wIndex <= MAX_TEST_MODE_NUM)
+ result = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_get_ep_stall(struct nbu2ss_udc *udc, u8 ep_adrs)
+{
+ u8 epnum;
+ u32 data = 0, bit_data;
+ PT_FC_REGS preg = udc->p_regs;
+
+ epnum = ep_adrs & ~USB_ENDPOINT_DIR_MASK;
+ if (epnum == 0) {
+ data = _nbu2ss_readl(&preg->EP0_CONTROL);
+ bit_data = EP0_STL;
+
+ } else {
+ data = _nbu2ss_readl(&preg->EP_REGS[epnum-1].EP_CONTROL);
+ if ((data & EPn_EN) == 0)
+ return -1;
+
+ if (ep_adrs & USB_ENDPOINT_DIR_MASK)
+ bit_data = EPn_ISTL;
+ else
+ bit_data = EPn_OSTL;
+ }
+
+ if ((data & bit_data) == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline int _nbu2ss_req_feature(struct nbu2ss_udc *udc, bool bset)
+{
+ u8 recipient = (u8)(udc->ctrl.bRequestType & USB_RECIP_MASK);
+ u8 direction = (u8)(udc->ctrl.bRequestType & USB_DIR_IN);
+ u16 selector = udc->ctrl.wValue;
+ u16 wIndex = udc->ctrl.wIndex;
+ u8 ep_adrs;
+ int result = -EOPNOTSUPP;
+
+ if ((0x0000 != udc->ctrl.wLength) ||
+ (USB_DIR_OUT != direction)) {
+ return -EINVAL;
+ }
+
+ switch (recipient) {
+ case USB_RECIP_DEVICE:
+ if (bset)
+ result =
+ _nbu2ss_set_feature_device(udc, selector, wIndex);
+ break;
+
+ case USB_RECIP_ENDPOINT:
+ if (0x0000 == (wIndex & 0xFF70)) {
+ if (USB_ENDPOINT_HALT == selector) {
+ ep_adrs = wIndex & 0xFF;
+ if (bset == FALSE) {
+ _nbu2ss_endpoint_toggle_reset(
+ udc, ep_adrs);
+ }
+
+ _nbu2ss_set_endpoint_stall(
+ udc, ep_adrs, bset);
+
+ result = 0;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (result >= 0)
+ _nbu2ss_create_ep0_packet(udc, udc->ep0_buf, 0);
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline enum usb_device_speed _nbu2ss_get_speed(struct nbu2ss_udc *udc)
+{
+ u32 data;
+ enum usb_device_speed speed = USB_SPEED_FULL;
+
+ data = _nbu2ss_readl(&udc->p_regs->USB_STATUS);
+ if (data & HIGH_SPEED)
+ speed = USB_SPEED_HIGH;
+
+ return speed;
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_epn_set_stall(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep
+)
+{
+ u8 ep_adrs;
+ u32 regdata;
+ int limit_cnt = 0;
+
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (ep->direct == USB_DIR_IN) {
+ for (limit_cnt = 0
+ ; limit_cnt < IN_DATA_EMPTY_COUNT
+ ; limit_cnt++) {
+
+ regdata = _nbu2ss_readl(
+ &preg->EP_REGS[ep->epnum-1].EP_STATUS);
+
+ if ((regdata & EPn_IN_DATA) == 0)
+ break;
+
+ mdelay(1);
+ }
+ }
+
+ ep_adrs = ep->epnum | ep->direct;
+ _nbu2ss_set_endpoint_stall(udc, ep_adrs, 1);
+}
+
+/*-------------------------------------------------------------------------*/
+static int std_req_get_status(struct nbu2ss_udc *udc)
+{
+ u32 length;
+ u16 status_data = 0;
+ u8 recipient = (u8)(udc->ctrl.bRequestType & USB_RECIP_MASK);
+ u8 direction = (u8)(udc->ctrl.bRequestType & USB_DIR_IN);
+ u8 ep_adrs;
+ int result = -EINVAL;
+
+ if ((0x0000 != udc->ctrl.wValue)
+ || (USB_DIR_IN != direction)) {
+
+ return result;
+ }
+
+ length = min(udc->ctrl.wLength, (u16)sizeof(status_data));
+
+ switch (recipient) {
+ case USB_RECIP_DEVICE:
+ if (udc->ctrl.wIndex == 0x0000) {
+ if (udc->self_powered)
+ status_data |= (1 << USB_DEVICE_SELF_POWERED);
+
+ if (udc->remote_wakeup)
+ status_data |= (1 << USB_DEVICE_REMOTE_WAKEUP);
+
+ result = 0;
+ }
+ break;
+
+ case USB_RECIP_ENDPOINT:
+ if (0x0000 == (udc->ctrl.wIndex & 0xFF70)) {
+ ep_adrs = (u8)(udc->ctrl.wIndex & 0xFF);
+ result = _nbu2ss_get_ep_stall(udc, ep_adrs);
+
+ if (result > 0)
+ status_data |= (1 << USB_ENDPOINT_HALT);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (result >= 0) {
+ memcpy(udc->ep0_buf, &status_data, length);
+ _nbu2ss_create_ep0_packet(udc, udc->ep0_buf, length);
+ _nbu2ss_ep0_in_transfer(udc, &udc->ep[0], &udc->ep0_req);
+
+ } else {
+ ERR("*** Error GET_STATUS\n");
+ }
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int std_req_clear_feature(struct nbu2ss_udc *udc)
+{
+ return _nbu2ss_req_feature(udc, FALSE);
+}
+
+/*-------------------------------------------------------------------------*/
+static int std_req_set_feature(struct nbu2ss_udc *udc)
+{
+ return _nbu2ss_req_feature(udc, TRUE);
+}
+
+/*-------------------------------------------------------------------------*/
+static int std_req_set_address(struct nbu2ss_udc *udc)
+{
+ int result = 0;
+ u32 wValue = udc->ctrl.wValue;
+
+ if ((0x00 != udc->ctrl.bRequestType) ||
+ (0x0000 != udc->ctrl.wIndex) ||
+ (0x0000 != udc->ctrl.wLength)) {
+ return -EINVAL;
+ }
+
+ if (wValue != (wValue & 0x007F))
+ return -EINVAL;
+
+ wValue = wValue << USB_ADRS_SHIFT;
+
+ _nbu2ss_writel(&udc->p_regs->USB_ADDRESS, wValue);
+ _nbu2ss_create_ep0_packet(udc, udc->ep0_buf, 0);
+
+ return result;
+}
+
+/*-------------------------------------------------------------------------*/
+static int std_req_set_configuration(struct nbu2ss_udc *udc)
+{
+ u32 ConfigValue = (u32)(udc->ctrl.wValue & 0x00ff);
+
+ if ((0x0000 != udc->ctrl.wIndex) ||
+ (0x0000 != udc->ctrl.wLength) ||
+ (0x00 != udc->ctrl.bRequestType)) {
+ return -EINVAL;
+ }
+
+ udc->curr_config = ConfigValue;
+
+ if (ConfigValue > 0) {
+ _nbu2ss_bitset(&udc->p_regs->USB_CONTROL, CONF);
+ udc->devstate = USB_STATE_CONFIGURED;
+
+ } else {
+ _nbu2ss_bitclr(&udc->p_regs->USB_CONTROL, CONF);
+ udc->devstate = USB_STATE_ADDRESS;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_read_request_data(struct nbu2ss_udc *udc, u32 *pdata)
+{
+ if ((udc == NULL) && (pdata == NULL))
+ return;
+
+ *pdata = _nbu2ss_readl(&udc->p_regs->SETUP_DATA0);
+ pdata++;
+ *pdata = _nbu2ss_readl(&udc->p_regs->SETUP_DATA1);
+}
+
+/*-------------------------------------------------------------------------*/
+static inline int _nbu2ss_decode_request(struct nbu2ss_udc *udc)
+{
+ bool bcall_back = TRUE;
+ int nret = -EINVAL;
+ struct usb_ctrlrequest *p_ctrl;
+
+ p_ctrl = &udc->ctrl;
+ _nbu2ss_read_request_data(udc, (u32 *)p_ctrl);
+
+ /* ep0 state control */
+ if (p_ctrl->wLength == 0) {
+ udc->ep0state = EP0_IN_STATUS_PHASE;
+
+ } else {
+ if (p_ctrl->bRequestType & USB_DIR_IN)
+ udc->ep0state = EP0_IN_DATA_PHASE;
+ else
+ udc->ep0state = EP0_OUT_DATA_PHASE;
+ }
+
+ if ((p_ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+ switch (p_ctrl->bRequest) {
+ case USB_REQ_GET_STATUS:
+ nret = std_req_get_status(udc);
+ bcall_back = FALSE;
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ nret = std_req_clear_feature(udc);
+ bcall_back = FALSE;
+ break;
+
+ case USB_REQ_SET_FEATURE:
+ nret = std_req_set_feature(udc);
+ bcall_back = FALSE;
+ break;
+
+ case USB_REQ_SET_ADDRESS:
+ nret = std_req_set_address(udc);
+ bcall_back = FALSE;
+ break;
+
+ case USB_REQ_SET_CONFIGURATION:
+ nret = std_req_set_configuration(udc);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (bcall_back == FALSE) {
+ if (udc->ep0state == EP0_IN_STATUS_PHASE) {
+ if (nret >= 0) {
+ /*--------------------------------------*/
+ /* Status Stage */
+ nret = EP0_send_NULL(udc, TRUE);
+ }
+ }
+
+ } else {
+ spin_unlock(&udc->lock);
+ nret = udc->driver->setup(&udc->gadget, &udc->ctrl);
+ spin_lock(&udc->lock);
+ }
+
+ if (nret < 0)
+ udc->ep0state = EP0_IDLE;
+
+ return nret;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline int _nbu2ss_ep0_in_data_stage(struct nbu2ss_udc *udc)
+{
+ int nret;
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep = &udc->ep[0];
+
+ if (list_empty(&ep->queue))
+ req = NULL;
+ else
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+
+ if (req == NULL)
+ req = &udc->ep0_req;
+
+ req->req.actual += req->div_len;
+ req->div_len = 0;
+
+ nret = _nbu2ss_ep0_in_transfer(udc, ep, req);
+ if (nret == 0) {
+ udc->ep0state = EP0_OUT_STATUS_PAHSE;
+ EP0_receive_NULL(udc, TRUE);
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline int _nbu2ss_ep0_out_data_stage(struct nbu2ss_udc *udc)
+{
+ int nret;
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep = &udc->ep[0];
+
+ if (list_empty(&ep->queue))
+ req = NULL;
+ else
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+
+ if (req == NULL)
+ req = &udc->ep0_req;
+
+ nret = _nbu2ss_ep0_out_transfer(udc, ep, req);
+ if (nret == 0) {
+ udc->ep0state = EP0_IN_STATUS_PHASE;
+ EP0_send_NULL(udc, TRUE);
+
+ } else if (nret < 0) {
+ _nbu2ss_bitset(&udc->p_regs->EP0_CONTROL, EP0_BCLR);
+ req->req.status = nret;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline int _nbu2ss_ep0_status_stage(struct nbu2ss_udc *udc)
+{
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep = &udc->ep[0];
+
+ if (list_empty(&ep->queue))
+ req = NULL;
+ else
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+
+ if (req == NULL) {
+ req = &udc->ep0_req;
+ if (req->req.complete)
+ req->req.complete(&ep->ep, &req->req);
+
+ } else {
+ if (req->req.complete)
+ _nbu2ss_ep_done(ep, req, 0);
+ }
+
+ udc->ep0state = EP0_IDLE;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_ep0_int(struct nbu2ss_udc *udc)
+{
+ int i;
+ u32 status;
+ u32 intr;
+ int nret = -1;
+
+ status = _nbu2ss_readl(&udc->p_regs->EP0_STATUS);
+ intr = status & EP0_STATUS_RW_BIT;
+ _nbu2ss_writel(&udc->p_regs->EP0_STATUS, ~(u32)intr);
+
+ status &= (SETUP_INT | EP0_IN_INT | EP0_OUT_INT
+ | STG_END_INT | EP0_OUT_NULL_INT);
+
+ if (status == 0) {
+ pr_info("--- %s Not Decode Interrupt\n", __func__);
+ pr_info("--- EP0_STATUS = 0x%08x\n", intr);
+ return;
+ }
+
+ if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+ udc->gadget.speed = _nbu2ss_get_speed(udc);
+
+ for (i = 0; i < EP0_END_XFER; i++) {
+ switch (udc->ep0state) {
+ case EP0_IDLE:
+ if (status & SETUP_INT) {
+ status = 0;
+ nret = _nbu2ss_decode_request(udc);
+ }
+ break;
+
+ case EP0_IN_DATA_PHASE:
+ if (status & EP0_IN_INT) {
+ status &= ~EP0_IN_INT;
+ nret = _nbu2ss_ep0_in_data_stage(udc);
+ }
+ break;
+
+ case EP0_OUT_DATA_PHASE:
+ if (status & EP0_OUT_INT) {
+ status &= ~EP0_OUT_INT;
+ nret = _nbu2ss_ep0_out_data_stage(udc);
+ }
+ break;
+
+ case EP0_IN_STATUS_PHASE:
+ if ((status & STG_END_INT) || (status & SETUP_INT)) {
+ status &= ~(STG_END_INT | EP0_IN_INT);
+ nret = _nbu2ss_ep0_status_stage(udc);
+ }
+ break;
+
+ case EP0_OUT_STATUS_PAHSE:
+ if ((status & STG_END_INT)
+ || (status & SETUP_INT)
+ || (status & EP0_OUT_NULL_INT)) {
+ status &= ~(STG_END_INT
+ | EP0_OUT_INT
+ | EP0_OUT_NULL_INT);
+
+ nret = _nbu2ss_ep0_status_stage(udc);
+ }
+
+ break;
+
+ default:
+ status = 0;
+ break;
+ }
+
+ if (status == 0)
+ break;
+ }
+
+ if (nret < 0) {
+ /* Send Stall */
+ _nbu2ss_set_endpoint_stall(udc, 0, TRUE);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_ep_done(
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req,
+ int status)
+{
+ struct nbu2ss_udc *udc = ep->udc;
+
+ list_del_init(&req->queue);
+
+ if (status == -ECONNRESET)
+ _nbu2ss_fifo_flush(udc, ep);
+
+ if (likely(req->req.status == -EINPROGRESS))
+ req->req.status = status;
+
+ if (ep->stalled)
+ _nbu2ss_epn_set_stall(udc, ep);
+ else {
+ if (!list_empty(&ep->queue))
+ _nbu2ss_restert_transfer(ep);
+ }
+
+#ifdef USE_DMA
+ if ((ep->direct == USB_DIR_OUT) && (ep->epnum > 0) &&
+ (req->req.dma != 0))
+ _nbu2ss_dma_unmap_single(udc, ep, req, USB_DIR_OUT);
+#endif
+
+ spin_unlock(&udc->lock);
+ req->req.complete(&ep->ep, &req->req);
+ spin_lock(&udc->lock);
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_epn_in_int(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req)
+{
+ int result = 0;
+ u32 status;
+
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (req->dma_flag)
+ return; /* DMA is forwarded */
+
+ req->req.actual += req->div_len;
+ req->div_len = 0;
+
+ if (req->req.actual != req->req.length) {
+ /*---------------------------------------------------------*/
+ /* remainder of data */
+ result = _nbu2ss_epn_in_transfer(udc, ep, req);
+
+ } else {
+ if ((req->zero != 0)
+ && ((req->req.actual % ep->ep.maxpacket) == 0)) {
+
+ status =
+ _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_STATUS);
+
+ if ((status & EPn_IN_FULL) == 0) {
+ /*-----------------------------------------*/
+ /* 0 Length Packet */
+ req->zero = 0;
+ _nbu2ss_zero_len_pkt(udc, ep->epnum);
+ }
+ return;
+ }
+ }
+
+ if (result <= 0) {
+ /*---------------------------------------------------------*/
+ /* Complete */
+ _nbu2ss_ep_done(ep, req, result);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_epn_out_int(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req)
+{
+ int result;
+
+ result = _nbu2ss_epn_out_transfer(udc, ep, req);
+ if (result <= 0)
+ _nbu2ss_ep_done(ep, req, result);
+
+ return;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_epn_in_dma_int(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req)
+{
+ u32 mpkt;
+ u32 size;
+ struct usb_request *preq;
+
+ preq = &req->req;
+
+ if (req->dma_flag == FALSE)
+ return;
+
+ preq->actual += req->div_len;
+ req->div_len = 0;
+ req->dma_flag = FALSE;
+
+#ifdef USE_DMA
+ _nbu2ss_dma_unmap_single(udc, ep, req, USB_DIR_IN);
+#endif
+
+ if (preq->actual != preq->length) {
+ _nbu2ss_epn_in_transfer(udc, ep, req);
+ } else {
+ mpkt = ep->ep.maxpacket;
+ size = preq->actual % mpkt;
+ if (size > 0) {
+ if (((preq->actual & 0x03) == 0) && (size < mpkt))
+ _nbu2ss_ep_in_end(udc, ep->epnum, 0, 0);
+ } else {
+ _nbu2ss_epn_in_int(udc, ep, req);
+ }
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_epn_out_dma_int(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ struct nbu2ss_req *req)
+{
+ int i;
+ u32 num;
+ u32 dmacnt, ep_dmacnt;
+ u32 mpkt;
+ PT_FC_REGS preg = udc->p_regs;
+
+ num = ep->epnum - 1;
+
+ if (req->req.actual == req->req.length) {
+ if ((req->req.length % ep->ep.maxpacket)
+ && (req->zero == 0)) {
+ req->div_len = 0;
+ req->dma_flag = FALSE;
+ _nbu2ss_ep_done(ep, req, 0);
+ return;
+ }
+ }
+
+ ep_dmacnt = _nbu2ss_readl(&preg->EP_REGS[num].EP_LEN_DCNT)
+ & EPn_DMACNT;
+ ep_dmacnt >>= 16;
+
+ for (i = 0; i < EPC_PLL_LOCK_COUNT; i++) {
+ dmacnt = _nbu2ss_readl(&preg->EP_DCR[num].EP_DCR1)
+ & DCR1_EPn_DMACNT;
+ dmacnt >>= 16;
+ if (ep_dmacnt == dmacnt)
+ break;
+ }
+
+ _nbu2ss_bitclr(&preg->EP_DCR[num].EP_DCR1, DCR1_EPn_REQEN);
+
+ if (dmacnt != 0) {
+ mpkt = ep->ep.maxpacket;
+ if ((req->div_len % mpkt) == 0)
+ req->div_len -= mpkt * dmacnt;
+ }
+
+ if ((req->req.actual % ep->ep.maxpacket) > 0) {
+ if (req->req.actual == req->div_len) {
+ req->div_len = 0;
+ req->dma_flag = FALSE;
+ _nbu2ss_ep_done(ep, req, 0);
+ return;
+ }
+ }
+
+ req->req.actual += req->div_len;
+ req->div_len = 0;
+ req->dma_flag = FALSE;
+
+ _nbu2ss_epn_out_int(udc, ep, req);
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_epn_int(struct nbu2ss_udc *udc, u32 epnum)
+{
+ u32 num;
+ u32 status;
+
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep = &udc->ep[epnum];
+
+ num = epnum - 1;
+
+ /* Interrupt Status */
+ status = _nbu2ss_readl(&udc->p_regs->EP_REGS[num].EP_STATUS);
+
+ /* Interrupt Clear */
+ _nbu2ss_writel(&udc->p_regs->EP_REGS[num].EP_STATUS, ~(u32)status);
+
+ if (list_empty(&ep->queue))
+ req = NULL;
+ else
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+
+ if (req == NULL) {
+ /* pr_warning("=== %s(%d) req == NULL\n", __func__, epnum); */
+ return;
+ }
+
+ if (status & EPn_OUT_END_INT) {
+ status &= ~EPn_OUT_INT;
+ _nbu2ss_epn_out_dma_int(udc, ep, req);
+ }
+
+ if (status & EPn_OUT_INT)
+ _nbu2ss_epn_out_int(udc, ep, req);
+
+ if (status & EPn_IN_END_INT) {
+ status &= ~EPn_IN_INT;
+ _nbu2ss_epn_in_dma_int(udc, ep, req);
+ }
+
+ if (status & EPn_IN_INT)
+ _nbu2ss_epn_in_int(udc, ep, req);
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_ep_int(struct nbu2ss_udc *udc, u32 epnum)
+{
+ if (epnum == 0)
+ _nbu2ss_ep0_int(udc);
+ else
+ _nbu2ss_epn_int(udc, epnum);
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_ep0_enable(struct nbu2ss_udc *udc)
+{
+ _nbu2ss_bitset(&udc->p_regs->EP0_CONTROL, (EP0_AUTO | EP0_BCLR));
+ _nbu2ss_writel(&udc->p_regs->EP0_INT_ENA, EP0_INT_EN_BIT);
+
+ return;
+}
+
+#if 0
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_ep0_disable(struct nbu2ss_udc *udc)
+{
+ _nbu2ss_bitclr(&udc->p_regs->EP0_INT_ENA, EP0_INT_EN_BIT);
+
+ _nbu2ss_bitset(&udc->p_regs->EP0_CONTROL
+ , (EP0_BCLR | EP0_INAK | EP0_ONAK | EP0_BCLR));
+
+ _nbu2ss_bitclr(&udc->p_regs->EP0_CONTROL, EP0_AUTO);
+
+ return;
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_nuke(struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ int status)
+{
+ struct nbu2ss_req *req;
+
+ /* Endpoint Disable */
+ _nbu2ss_epn_exit(udc, ep);
+
+ /* DMA Disable */
+ _nbu2ss_ep_dma_exit(udc, ep);
+
+ if (list_empty(&ep->queue))
+ return 0;
+
+ /* called with irqs blocked */
+ while (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct nbu2ss_req, queue);
+ _nbu2ss_ep_done(ep, req, status);
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_quiesce(struct nbu2ss_udc *udc)
+{
+ struct nbu2ss_ep *ep;
+
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+ _nbu2ss_nuke(udc, &udc->ep[0], -ESHUTDOWN);
+
+ /* Endpoint n */
+ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+ _nbu2ss_nuke(udc, ep, -ESHUTDOWN);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_pullup(struct nbu2ss_udc *udc, int is_on)
+{
+ u32 reg_dt;
+
+ if (!udc) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ if (udc->vbus_active == 0)
+ return -ESHUTDOWN;
+
+ if (is_on) {
+ /* D+ Pullup */
+/* INFO(" --- D+ Pullup\n"); */
+
+ if (udc->driver) {
+ reg_dt = (_nbu2ss_readl(&udc->p_regs->USB_CONTROL)
+ | PUE2) & ~(u32)CONNECTB;
+
+ _nbu2ss_writel(&udc->p_regs->USB_CONTROL, reg_dt);
+ }
+
+ } else {
+ /* D+ Pulldown */
+/* INFO(" --- D+ Pulldown\n"); */
+
+ reg_dt = (_nbu2ss_readl(&udc->p_regs->USB_CONTROL) | CONNECTB)
+ & ~(u32)PUE2;
+
+ _nbu2ss_writel(&udc->p_regs->USB_CONTROL, reg_dt);
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_fifo_flush(struct nbu2ss_udc *udc, struct nbu2ss_ep *ep)
+{
+ PT_FC_REGS p = udc->p_regs;
+
+ if (udc->vbus_active == 0)
+ return;
+
+ if (ep->epnum == 0) {
+ /* EP0 */
+ _nbu2ss_bitset(&p->EP0_CONTROL, EP0_BCLR);
+
+ } else {
+ /* EPn */
+ _nbu2ss_ep_dma_abort(udc, ep);
+ _nbu2ss_bitset(&p->EP_REGS[ep->epnum - 1].EP_CONTROL, EPn_BCLR);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static int _nbu2ss_enable_controller(struct nbu2ss_udc *udc)
+{
+ int waitcnt = 0;
+
+ if (udc->udc_enabled)
+ return 0;
+
+#if 0
+ emxx_open_clockgate(EMXX_CLK_USB1);
+ /* emxx_clkctrl_off(EMXX_CLKCTRL_USB1); */
+ /* emxx_clkctrl_on(EMXX_CLKCTRL_USB1); */
+ emxx_unreset_device(EMXX_RST_USB1);
+#endif
+ /*
+ Reset
+ */
+ _nbu2ss_bitset(&udc->p_regs->EPCTR, (DIRPD | EPC_RST));
+ udelay(EPC_RST_DISABLE_TIME); /* 1us wait */
+
+ _nbu2ss_bitclr(&udc->p_regs->EPCTR, DIRPD);
+ mdelay(EPC_DIRPD_DISABLE_TIME); /* 1ms wait */
+
+ _nbu2ss_bitclr(&udc->p_regs->EPCTR, EPC_RST);
+
+ _nbu2ss_writel(&udc->p_regs->AHBSCTR, WAIT_MODE);
+
+#if 0
+ /* DMA Mode Setting */
+ if ((system_rev & EMXX_REV_MASK) == EMXX_REV_ES1) {
+ _nbu2ss_bitset(&udc->p_regs->AHBMCTR, BURST_TYPE);
+ _nbu2ss_bitclr(&udc->p_regs->AHBMCTR, HTRANS_MODE);
+ } else
+#endif
+ _nbu2ss_writel(&udc->p_regs->AHBMCTR,
+ HBUSREQ_MODE | HTRANS_MODE | WBURST_TYPE);
+
+ while (!(_nbu2ss_readl(&udc->p_regs->EPCTR) & PLL_LOCK)) {
+ waitcnt++;
+ udelay(1); /* 1us wait */
+ if (waitcnt == EPC_PLL_LOCK_COUNT) {
+ ERR("*** Reset Cancel failed\n");
+ return -EINVAL;
+ }
+ };
+
+#if 0
+ if ((system_rev & EMXX_REV_MASK) < EMXX_REV_ES3)
+#endif
+ _nbu2ss_bitset(&udc->p_regs->UTMI_CHARACTER_1, USB_SQUSET);
+
+ _nbu2ss_bitset(&udc->p_regs->USB_CONTROL, (INT_SEL | SOF_RCV));
+
+ /* EP0 */
+ _nbu2ss_ep0_enable(udc);
+
+ /* USB Interrupt Enable */
+ _nbu2ss_bitset(&udc->p_regs->USB_INT_ENA, USB_INT_EN_BIT);
+
+ udc->udc_enabled = TRUE;
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_reset_controller(struct nbu2ss_udc *udc)
+{
+ _nbu2ss_bitset(&udc->p_regs->EPCTR, EPC_RST);
+ _nbu2ss_bitclr(&udc->p_regs->EPCTR, EPC_RST);
+}
+
+/*-------------------------------------------------------------------------*/
+static void _nbu2ss_disable_controller(struct nbu2ss_udc *udc)
+{
+ if (udc->udc_enabled) {
+ udc->udc_enabled = FALSE;
+ _nbu2ss_reset_controller(udc);
+ _nbu2ss_bitset(&udc->p_regs->EPCTR, (DIRPD | EPC_RST));
+ }
+#if 0
+ emxx_reset_device(EMXX_RST_USB1);
+ /* emxx_clkctrl_on(EMXX_CLKCTRL_USB1); */
+ emxx_close_clockgate(EMXX_CLK_USB1);
+#endif
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_check_vbus(struct nbu2ss_udc *udc)
+{
+ int nret;
+ u32 reg_dt;
+
+ /* chattering */
+ mdelay(VBUS_CHATTERING_MDELAY); /* wait (ms) */
+
+ /* VBUS ON Check*/
+ reg_dt = gpio_get_value(VBUS_VALUE);
+ if (reg_dt == 0) {
+
+ udc->linux_suspended = 0;
+
+ _nbu2ss_reset_controller(udc);
+ pr_info(" ----- VBUS OFF\n");
+
+ if (udc->vbus_active == 1) {
+ /* VBUS OFF */
+ udc->vbus_active = 0;
+ if (udc->usb_suspended) {
+ udc->usb_suspended = 0;
+ /* _nbu2ss_reset_controller(udc); */
+ }
+ udc->devstate = USB_STATE_NOTATTACHED;
+
+ _nbu2ss_quiesce(udc);
+ if (udc->driver) {
+ spin_unlock(&udc->lock);
+ udc->driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
+
+ _nbu2ss_disable_controller(udc);
+ }
+ } else {
+ mdelay(5); /* wait (5ms) */
+ reg_dt = gpio_get_value(VBUS_VALUE);
+ if (reg_dt == 0)
+ return;
+
+ pr_info(" ----- VBUS ON\n");
+
+ if (udc->linux_suspended)
+ return;
+
+ if (udc->vbus_active == 0) {
+ /* VBUS ON */
+ udc->vbus_active = 1;
+ udc->devstate = USB_STATE_POWERED;
+
+ nret = _nbu2ss_enable_controller(udc);
+ if (nret < 0) {
+ _nbu2ss_disable_controller(udc);
+ udc->vbus_active = 0;
+ return;
+ }
+
+ _nbu2ss_pullup(udc, 1);
+
+#ifdef UDC_DEBUG_DUMP
+ _nbu2ss_dump_register(udc);
+#endif /* UDC_DEBUG_DUMP */
+
+ } else {
+ if (udc->devstate == USB_STATE_POWERED)
+ _nbu2ss_pullup(udc, 1);
+ }
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_int_bus_reset(struct nbu2ss_udc *udc)
+{
+ udc->devstate = USB_STATE_DEFAULT;
+ udc->remote_wakeup = 0;
+
+ _nbu2ss_quiesce(udc);
+
+ udc->ep0state = EP0_IDLE;
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_int_usb_resume(struct nbu2ss_udc *udc)
+{
+ if (udc->usb_suspended == 1) {
+ udc->usb_suspended = 0;
+ if (udc->driver && udc->driver->resume) {
+ spin_unlock(&udc->lock);
+ udc->driver->resume(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static inline void _nbu2ss_int_usb_suspend(struct nbu2ss_udc *udc)
+{
+ u32 reg_dt;
+
+ if (udc->usb_suspended == 0) {
+ reg_dt = gpio_get_value(VBUS_VALUE);
+
+ if (reg_dt == 0)
+ return;
+
+ udc->usb_suspended = 1;
+ if (udc->driver && udc->driver->suspend) {
+ spin_unlock(&udc->lock);
+ udc->driver->suspend(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
+
+ _nbu2ss_bitset(&udc->p_regs->USB_CONTROL, SUSPEND);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+/* VBUS (GPIO153) Interrupt */
+static irqreturn_t _nbu2ss_vbus_irq(int irq, void *_udc)
+{
+ struct nbu2ss_udc *udc = (struct nbu2ss_udc *)_udc;
+
+ spin_lock(&udc->lock);
+ _nbu2ss_check_vbus(udc);
+ spin_unlock(&udc->lock);
+
+ return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+/* Interrupt (udc) */
+static irqreturn_t _nbu2ss_udc_irq(int irq, void *_udc)
+{
+ u8 suspend_flag = 0;
+ u32 status;
+ u32 epnum, int_bit;
+
+ struct nbu2ss_udc *udc = (struct nbu2ss_udc *)_udc;
+ PT_FC_REGS preg = udc->p_regs;
+
+ if (gpio_get_value(VBUS_VALUE) == 0) {
+ _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW);
+ _nbu2ss_writel(&preg->USB_INT_ENA, 0);
+ return IRQ_HANDLED;
+ }
+
+ spin_lock(&udc->lock);
+
+ for (;;) {
+ if (gpio_get_value(VBUS_VALUE) == 0) {
+ _nbu2ss_writel(&preg->USB_INT_STA, ~USB_INT_STA_RW);
+ _nbu2ss_writel(&preg->USB_INT_ENA, 0);
+ status = 0;
+ } else
+ status = _nbu2ss_readl(&preg->USB_INT_STA);
+
+ if (status == 0)
+ break;
+
+ _nbu2ss_writel(&preg->USB_INT_STA, ~(status & USB_INT_STA_RW));
+
+ if (status & USB_RST_INT) {
+ /* USB Reset */
+ _nbu2ss_int_bus_reset(udc);
+ }
+
+ if (status & RSUM_INT) {
+ /* Resume */
+ _nbu2ss_int_usb_resume(udc);
+ }
+
+ if (status & SPND_INT) {
+ /* Suspend */
+ suspend_flag = 1;
+ }
+
+ if (status & EPn_INT) {
+ /* EP INT */
+ int_bit = status >> 8;
+
+ for (epnum = 0; epnum < NUM_ENDPOINTS; epnum++) {
+
+ if (0x01 & int_bit)
+ _nbu2ss_ep_int(udc, epnum);
+
+ int_bit >>= 1;
+
+ if (int_bit == 0)
+ break;
+ }
+ }
+ }
+
+ if (suspend_flag)
+ _nbu2ss_int_usb_suspend(udc);
+
+ spin_unlock(&udc->lock);
+
+ return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+/* usb_ep_ops */
+static int nbu2ss_ep_enable(
+ struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ u8 ep_type;
+ unsigned long flags;
+
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+
+ if ((_ep == NULL) || (desc == NULL)) {
+ ERR(" *** %s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if ((ep == NULL) || (ep->udc == NULL)) {
+ ERR(" *** %s, ep == NULL !!\n", __func__);
+ return -EINVAL;
+ }
+
+ ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ if ((ep_type == USB_ENDPOINT_XFER_CONTROL)
+ || (ep_type == USB_ENDPOINT_XFER_ISOC)) {
+
+ ERR(" *** %s, bat bmAttributes\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = ep->udc;
+ if (udc->vbus_active == 0)
+ return -ESHUTDOWN;
+
+ if ((udc->driver == NULL)
+ || (udc->gadget.speed == USB_SPEED_UNKNOWN)) {
+
+ ERR(" *** %s, udc !!\n", __func__);
+ return -ESHUTDOWN;
+ }
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ ep->desc = desc;
+ ep->epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ ep->direct = desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
+ ep->ep_type = ep_type;
+ ep->wedged = 0;
+ ep->halted = FALSE;
+ ep->stalled = FALSE;
+
+ ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+
+ /* DMA setting */
+ _nbu2ss_ep_dma_init(udc, ep);
+
+ /* Endpoint setting */
+ _nbu2ss_ep_init(udc, ep);
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_ep_disable(struct usb_ep *_ep)
+{
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+ if (_ep == NULL) {
+ ERR(" *** %s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if ((ep == NULL) || (ep->udc == NULL)) {
+ ERR(" *** %s, ep == NULL !!\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = ep->udc;
+ if (udc->vbus_active == 0)
+ return -ESHUTDOWN;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ _nbu2ss_nuke(udc, ep, -EINPROGRESS); /* dequeue request */
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct usb_request *nbu2ss_ep_alloc_request(
+ struct usb_ep *ep,
+ gfp_t gfp_flags)
+{
+ struct nbu2ss_req *req;
+
+ req = kzalloc(sizeof(*req), gfp_flags);
+ if (!req)
+ return 0;
+
+#ifdef USE_DMA
+ req->req.dma = DMA_ADDR_INVALID;
+#endif
+ INIT_LIST_HEAD(&req->queue);
+
+ return &req->req;
+}
+
+/*-------------------------------------------------------------------------*/
+static void nbu2ss_ep_free_request(
+ struct usb_ep *_ep,
+ struct usb_request *_req)
+{
+ struct nbu2ss_req *req;
+
+ if (_req != NULL) {
+ req = container_of(_req, struct nbu2ss_req, req);
+
+ if (req != NULL)
+ kfree(req);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_ep_queue(
+ struct usb_ep *_ep,
+ struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+ bool bflag;
+ int result = -EINVAL;
+
+ /* catch various bogus parameters */
+ if ((_ep == NULL) || (_req == NULL)) {
+ if (_ep == NULL)
+ ERR("*** %s --- _ep == NULL\n", __func__);
+
+ if (_req == NULL)
+ ERR("*** %s --- _req == NULL\n", __func__);
+
+ return -EINVAL;
+ }
+
+ req = container_of(_req, struct nbu2ss_req, req);
+ if (unlikely
+ (!_req->complete || !_req->buf
+ || !list_empty(&req->queue))) {
+
+ if (!_req->complete)
+ ERR("*** %s --- !_req->complete\n", __func__);
+
+ if (!_req->buf)
+ ERR("*** %s --- !_req->buf\n", __func__);
+
+ if (!list_empty(&req->queue))
+ ERR("*** %s --- !list_empty(&req->queue)\n", __func__);
+
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ udc = ep->udc;
+
+/* INFO("=== %s(ep%d), zero=%d\n", __func__, ep->epnum, _req->zero); */
+
+ if (udc->vbus_active == 0) {
+ pr_info("Can't ep_queue (VBUS OFF)\n");
+ return -ESHUTDOWN;
+ }
+
+ if (unlikely(!udc->driver)) {
+ ERR("%s, bogus device state %p\n", __func__, udc->driver);
+ return -ESHUTDOWN;
+ }
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+#ifdef USE_DMA
+ if ((u32)req->req.buf & 0x3)
+ req->unaligned = TRUE;
+ else
+ req->unaligned = FALSE;
+
+ if (req->unaligned) {
+ if (ep->virt_buf == NULL)
+ ep->virt_buf = (u8 *)dma_alloc_coherent(
+ NULL, PAGE_SIZE,
+ &ep->phys_buf, GFP_KERNEL | GFP_DMA);
+ if (ep->epnum > 0) {
+ if (ep->direct == USB_DIR_IN)
+ memcpy(ep->virt_buf, req->req.buf,
+ req->req.length);
+ }
+ }
+
+ if ((ep->epnum > 0) && (ep->direct == USB_DIR_OUT) &&
+ (req->req.dma != 0))
+ _nbu2ss_dma_map_single(udc, ep, req, USB_DIR_OUT);
+#endif
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ bflag = list_empty(&ep->queue);
+ list_add_tail(&req->queue, &ep->queue);
+
+ if ((bflag != FALSE) && (ep->stalled == FALSE)) {
+
+ result = _nbu2ss_start_transfer(udc, ep, req, FALSE);
+ if (result < 0) {
+ ERR(" *** %s, result = %d\n", __func__, result);
+ list_del(&req->queue);
+ } else if ((ep->epnum > 0) && (ep->direct == USB_DIR_OUT)) {
+#ifdef USE_DMA
+ if (req->req.length < 4 &&
+ req->req.length == req->req.actual)
+#else
+ if (req->req.length == req->req.actual)
+#endif
+ _nbu2ss_ep_done(ep, req, result);
+ }
+ }
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_ep_dequeue(
+ struct usb_ep *_ep,
+ struct usb_request *_req)
+{
+ struct nbu2ss_req *req;
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+ /*INFO("=== %s()\n", __func__);*/
+
+ /* catch various bogus parameters */
+ if ((_ep == NULL) || (_req == NULL)) {
+ /* ERR("%s, bad param(1)\n", __func__); */
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if (!ep) {
+ ERR("%s, ep == NULL !!\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = ep->udc;
+ if (udc == NULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ /* make sure it's actually queued on this endpoint */
+ list_for_each_entry(req, &ep->queue, queue) {
+ if (&req->req == _req)
+ break;
+ }
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&udc->lock, flags);
+ pr_debug("%s no queue(EINVAL)\n", __func__);
+ return -EINVAL;
+ }
+
+ _nbu2ss_ep_done(ep, req, -ECONNRESET);
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_ep_set_halt(struct usb_ep *_ep, int value)
+{
+ u8 ep_adrs;
+ unsigned long flags;
+
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (!_ep) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if (!ep) {
+ ERR("%s, bad ep\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = ep->udc;
+ if (!udc) {
+ ERR(" *** %s, bad udc\n", __func__);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ ep_adrs = ep->epnum | ep->direct;
+ if (value == 0) {
+ _nbu2ss_set_endpoint_stall(udc, ep_adrs, value);
+ ep->stalled = FALSE;
+ } else {
+ if (list_empty(&ep->queue))
+ _nbu2ss_epn_set_stall(udc, ep);
+ else
+ ep->stalled = TRUE;
+ }
+
+ if (value == 0)
+ ep->wedged = 0;
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+static int nbu2ss_ep_set_wedge(struct usb_ep *_ep)
+{
+ return nbu2ss_ep_set_halt(_ep, 1);
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_ep_fifo_status(struct usb_ep *_ep)
+{
+ u32 data;
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+ PT_FC_REGS preg;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (!_ep) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if (!ep) {
+ ERR("%s, bad ep\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = ep->udc;
+ if (!udc) {
+ ERR("%s, bad udc\n", __func__);
+ return -EINVAL;
+ }
+
+ preg = udc->p_regs;
+
+ data = gpio_get_value(VBUS_VALUE);
+ if (data == 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ if (ep->epnum == 0) {
+ data = _nbu2ss_readl(&preg->EP0_LENGTH) & EP0_LDATA;
+
+ } else {
+ data = _nbu2ss_readl(&preg->EP_REGS[ep->epnum-1].EP_LEN_DCNT)
+ & EPn_LDATA;
+ }
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void nbu2ss_ep_fifo_flush(struct usb_ep *_ep)
+{
+ u32 data;
+ struct nbu2ss_ep *ep;
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (!_ep) {
+ ERR("%s, bad param\n", __func__);
+ return;
+ }
+
+ ep = container_of(_ep, struct nbu2ss_ep, ep);
+ if (!_ep) {
+ ERR("%s, bad ep\n", __func__);
+ return;
+ }
+
+ udc = ep->udc;
+ if (!udc) {
+ ERR("%s, bad udc\n", __func__);
+ return;
+ }
+
+ data = gpio_get_value(VBUS_VALUE);
+ if (data == 0)
+ return;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ _nbu2ss_fifo_flush(udc, ep);
+ spin_unlock_irqrestore(&udc->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+static struct usb_ep_ops nbu2ss_ep_ops = {
+ .enable = nbu2ss_ep_enable,
+ .disable = nbu2ss_ep_disable,
+
+ .alloc_request = nbu2ss_ep_alloc_request,
+ .free_request = nbu2ss_ep_free_request,
+
+ .queue = nbu2ss_ep_queue,
+ .dequeue = nbu2ss_ep_dequeue,
+
+ .set_halt = nbu2ss_ep_set_halt,
+ .set_wedge = nbu2ss_ep_set_wedge,
+
+ .fifo_status = nbu2ss_ep_fifo_status,
+ .fifo_flush = nbu2ss_ep_fifo_flush,
+};
+
+
+/*-------------------------------------------------------------------------*/
+/* usb_gadget_ops */
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_get_frame(struct usb_gadget *pgadget)
+{
+ u32 data;
+ struct nbu2ss_udc *udc;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (pgadget == NULL) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = container_of(pgadget, struct nbu2ss_udc, gadget);
+ if (udc == NULL) {
+ ERR("%s, udc == NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ data = gpio_get_value(VBUS_VALUE);
+ if (data == 0)
+ return -EINVAL;
+
+ data = _nbu2ss_readl(&udc->p_regs->USB_ADDRESS) & FRAME;
+
+ return data;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_wakeup(struct usb_gadget *pgadget)
+{
+ int i;
+ u32 data;
+
+ struct nbu2ss_udc *udc;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (pgadget == NULL) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = container_of(pgadget, struct nbu2ss_udc, gadget);
+ if (udc == NULL) {
+ ERR("%s, udc == NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ data = gpio_get_value(VBUS_VALUE);
+ if (data == 0) {
+ pr_warning("VBUS LEVEL = %d\n", data);
+ return -EINVAL;
+ }
+
+ _nbu2ss_bitset(&udc->p_regs->EPCTR, PLL_RESUME);
+
+ for (i = 0; i < EPC_PLL_LOCK_COUNT; i++) {
+ data = _nbu2ss_readl(&udc->p_regs->EPCTR);
+
+ if (data & PLL_LOCK)
+ break;
+ }
+
+ _nbu2ss_bitclr(&udc->p_regs->EPCTR, PLL_RESUME);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_set_selfpowered(struct usb_gadget *pgadget,
+ int is_selfpowered)
+{
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (pgadget == NULL) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = container_of(pgadget, struct nbu2ss_udc, gadget);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ udc->self_powered = (is_selfpowered != 0);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_vbus_session(struct usb_gadget *pgadget, int is_active)
+{
+/* INFO("=== %s()\n", __func__); */
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_vbus_draw(struct usb_gadget *pgadget, unsigned mA)
+{
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (pgadget == NULL) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = container_of(pgadget, struct nbu2ss_udc, gadget);
+
+ spin_lock_irqsave(&udc->lock, flags);
+ udc->mA = mA;
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_pullup(struct usb_gadget *pgadget, int is_on)
+{
+ struct nbu2ss_udc *udc;
+ unsigned long flags;
+
+/* INFO("=== %s()\n", __func__); */
+
+ if (pgadget == NULL) {
+ ERR("%s, bad param\n", __func__);
+ return -EINVAL;
+ }
+
+ udc = container_of(pgadget, struct nbu2ss_udc, gadget);
+
+ if (udc->driver == NULL) {
+ pr_warning("%s, Not Regist Driver\n", __func__);
+ return -EINVAL;
+ }
+
+ if (udc->vbus_active == 0)
+ return -ESHUTDOWN;
+
+ spin_lock_irqsave(&udc->lock, flags);
+ _nbu2ss_pullup(udc, is_on);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_gad_ioctl(
+ struct usb_gadget *pgadget,
+ unsigned code,
+ unsigned long param)
+{
+/* INFO("=== %s()\n", __func__); */
+ return 0;
+}
+
+
+static const struct usb_gadget_ops nbu2ss_gadget_ops = {
+ .get_frame = nbu2ss_gad_get_frame,
+ .wakeup = nbu2ss_gad_wakeup,
+ .set_selfpowered = nbu2ss_gad_set_selfpowered,
+ .vbus_session = nbu2ss_gad_vbus_session,
+ .vbus_draw = nbu2ss_gad_vbus_draw,
+ .pullup = nbu2ss_gad_pullup,
+ .ioctl = nbu2ss_gad_ioctl,
+};
+
+static char g_ep0_name[] = "ep0";
+static char g_ep1_name[] = "ep1-bulk";
+static char g_ep2_name[] = "ep2-bulk";
+static char g_ep3_name[] = "ep3in-int";
+static char g_ep4_name[] = "ep4-iso";
+static char g_ep5_name[] = "ep5-iso";
+static char g_ep6_name[] = "ep6-bulk";
+static char g_ep7_name[] = "ep7-bulk";
+static char g_ep8_name[] = "ep8in-int";
+static char g_ep9_name[] = "ep9-iso";
+static char g_epa_name[] = "epa-iso";
+static char g_epb_name[] = "epb-bulk";
+static char g_epc_name[] = "epc-nulk";
+static char g_epd_name[] = "epdin-int";
+
+static char *gp_ep_name[NUM_ENDPOINTS] = {
+ g_ep0_name,
+ g_ep1_name,
+ g_ep2_name,
+ g_ep3_name,
+ g_ep4_name,
+ g_ep5_name,
+ g_ep6_name,
+ g_ep7_name,
+ g_ep8_name,
+ g_ep9_name,
+ g_epa_name,
+ g_epb_name,
+ g_epc_name,
+ g_epd_name,
+};
+
+/*-------------------------------------------------------------------------*/
+static void __init nbu2ss_drv_set_ep_info(
+ struct nbu2ss_udc *udc,
+ struct nbu2ss_ep *ep,
+ u8 *name)
+{
+ ep->udc = udc;
+ ep->desc = NULL;
+
+ ep->ep.driver_data = NULL;
+ ep->ep.name = name;
+ ep->ep.ops = &nbu2ss_ep_ops;
+
+ if (isdigit(name[2])) {
+
+ long num;
+ int res;
+ char tempbuf[2];
+
+ tempbuf[0] = name[2];
+ tempbuf[1] = '\0';
+ res = kstrtol(tempbuf, 16, &num);
+
+ if (num == 0)
+ ep->ep.maxpacket = EP0_PACKETSIZE;
+ else
+ ep->ep.maxpacket = EP_PACKETSIZE;
+
+ } else {
+ ep->ep.maxpacket = EP_PACKETSIZE;
+ }
+
+ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+ INIT_LIST_HEAD(&ep->queue);
+}
+
+/*-------------------------------------------------------------------------*/
+static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
+{
+ int i;
+
+ INIT_LIST_HEAD(&udc->gadget.ep_list);
+ udc->gadget.ep0 = &udc->ep[0].ep;
+
+
+ for (i = 0; i < NUM_ENDPOINTS; i++)
+ nbu2ss_drv_set_ep_info(udc, &udc->ep[i], gp_ep_name[i]);
+
+ list_del_init(&udc->ep[0].ep.ep_list);
+}
+
+/*-------------------------------------------------------------------------*/
+/* platform_driver */
+static int __init nbu2ss_drv_contest_init(
+ struct platform_device *pdev,
+ struct nbu2ss_udc *udc)
+{
+ spin_lock_init(&udc->lock);
+ udc->dev = &pdev->dev;
+
+ udc->self_powered = 1;
+ udc->devstate = USB_STATE_NOTATTACHED;
+ udc->pdev = pdev;
+ udc->mA = 0;
+
+ udc->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ /* init Endpoint */
+ nbu2ss_drv_ep_init(udc);
+
+ /* init Gadget */
+ udc->gadget.ops = &nbu2ss_gadget_ops;
+ udc->gadget.ep0 = &udc->ep[0].ep;
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+ udc->gadget.name = driver_name;
+ /* udc->gadget.is_dualspeed = 1; */
+
+ device_initialize(&udc->gadget.dev);
+
+ dev_set_name(&udc->gadget.dev, "gadget");
+ udc->gadget.dev.parent = &pdev->dev;
+ udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
+
+ return 0;
+}
+
+/*
+ * probe - binds to the platform device
+ */
+static int nbu2ss_drv_probe(struct platform_device *pdev)
+{
+ int status = -ENODEV;
+ struct nbu2ss_udc *udc;
+ struct resource *r;
+ int irq;
+ void __iomem *mmio_base;
+
+ udc = &udc_controller;
+ memset(udc, 0, sizeof(struct nbu2ss_udc));
+
+ platform_set_drvdata(pdev, udc);
+
+ /* require I/O memory and IRQ to be provided as resources */
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mmio_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(mmio_base))
+ return PTR_ERR(mmio_base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ\n");
+ return irq;
+ }
+ status = devm_request_irq(&pdev->dev, irq, _nbu2ss_udc_irq,
+ 0, driver_name, udc);
+
+ /* IO Memory */
+ udc->p_regs = (PT_FC_REGS)mmio_base;
+
+ /* USB Function Controller Interrupt */
+ if (status != 0) {
+ ERR("request_irq(USB_UDC_IRQ_1) failed\n");
+ goto cleanup1;
+ }
+
+ /* Driver Initialization */
+ status = nbu2ss_drv_contest_init(pdev, udc);
+ if (status < 0) {
+ /* Error */
+ goto cleanup1;
+ }
+
+ /* VBUS Interrupt */
+ irq_set_irq_type(INT_VBUS, IRQ_TYPE_EDGE_BOTH);
+ status = request_irq(INT_VBUS,
+ _nbu2ss_vbus_irq,
+ IRQF_SHARED,
+ driver_name,
+ udc);
+
+ if (status != 0) {
+ ERR("request_irq(INT_VBUS) failed\n");
+ goto cleanup1;
+ }
+
+ return status;
+
+cleanup1:
+ return status;
+}
+
+/*-------------------------------------------------------------------------*/
+static void nbu2ss_drv_shutdown(struct platform_device *pdev)
+{
+ struct nbu2ss_udc *udc;
+
+ udc = platform_get_drvdata(pdev);
+ if (udc == NULL)
+ return;
+
+ _nbu2ss_disable_controller(udc);
+}
+
+/*-------------------------------------------------------------------------*/
+static int __exit nbu2ss_drv_remove(struct platform_device *pdev)
+{
+ struct nbu2ss_udc *udc;
+ struct nbu2ss_ep *ep;
+ int i;
+
+ udc = &udc_controller;
+
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ ep = &udc->ep[i];
+ if (ep->virt_buf)
+ dma_free_coherent(NULL, PAGE_SIZE,
+ (void *)ep->virt_buf, ep->phys_buf);
+ }
+
+ /* Interrupt Handler - Release */
+ free_irq(INT_VBUS, udc);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct nbu2ss_udc *udc;
+
+ udc = platform_get_drvdata(pdev);
+ if (udc == NULL)
+ return 0;
+
+ if (udc->vbus_active) {
+ udc->vbus_active = 0;
+ udc->devstate = USB_STATE_NOTATTACHED;
+ udc->linux_suspended = 1;
+
+ if (udc->usb_suspended) {
+ udc->usb_suspended = 0;
+ _nbu2ss_reset_controller(udc);
+ }
+
+ _nbu2ss_quiesce(udc);
+ }
+ _nbu2ss_disable_controller(udc);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static int nbu2ss_drv_resume(struct platform_device *pdev)
+{
+ u32 data;
+ struct nbu2ss_udc *udc;
+
+ udc = platform_get_drvdata(pdev);
+ if (udc == NULL)
+ return 0;
+
+ data = gpio_get_value(VBUS_VALUE);
+ if (data) {
+ udc->vbus_active = 1;
+ udc->devstate = USB_STATE_POWERED;
+ _nbu2ss_enable_controller(udc);
+ _nbu2ss_pullup(udc, 1);
+ }
+
+ udc->linux_suspended = 0;
+
+ return 0;
+}
+
+
+static struct platform_driver udc_driver = {
+ .probe = nbu2ss_drv_probe,
+ .shutdown = nbu2ss_drv_shutdown,
+ .remove = __exit_p(nbu2ss_drv_remove),
+ .suspend = nbu2ss_drv_suspend,
+ .resume = nbu2ss_drv_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = driver_name,
+ },
+};
+
+module_platform_driver(udc_driver);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Renesas Electronics Corporation");
+MODULE_LICENSE("GPL");
+
+
diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h
new file mode 100644
index 000000000000..578fdcfed5e9
--- /dev/null
+++ b/drivers/staging/emxx_udc/emxx_udc.h
@@ -0,0 +1,653 @@
+/*
+ * EMXX FCD (Function Controller Driver) for USB.
+ *
+ * Copyright (C) 2010 Renesas Electronics Corporation
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
+ */
+
+
+
+
+#ifndef _LINUX_EMXX_H
+#define _LINUX_EMXX_H
+
+
+
+/*---------------------------------------------------------------------------*/
+/*----------------- Default undef */
+#if 0
+#define DEBUG
+#define UDC_DEBUG_DUMP
+#endif
+
+/* #define USE_INT_COUNT_OVER */
+
+/*----------------- Default define */
+#define USE_DMA 1
+#define USE_SUSPEND_WAIT 1
+
+
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+
+/*------------ Board dependence(Resource) */
+#define VBUS_VALUE GPIO_VBUS
+
+/* below hacked up for staging integration */
+#define GPIO_VBUS 0 /* GPIO_P153 on KZM9D */
+#define INT_VBUS 0 /* IRQ for GPIO_P153 */
+
+/*------------ Board dependence(Wait) */
+
+/* CHATTERING wait time ms */
+#define VBUS_CHATTERING_MDELAY 1
+/* DMA Abort wait time ms */
+#define DMA_DISABLE_TIME 10
+
+
+
+/*------------ Controller dependence */
+#define NUM_ENDPOINTS 14 /* Endpoint */
+#define REG_EP_NUM 15 /* Endpoint Register */
+#define DMA_MAX_COUNT 256 /* DMA Block */
+
+
+
+#define EPC_RST_DISABLE_TIME 1 /* 1 usec */
+#define EPC_DIRPD_DISABLE_TIME 1 /* 1 msec */
+#define EPC_PLL_LOCK_COUNT 1000 /* 1000 */
+#define IN_DATA_EMPTY_COUNT 1000 /* 1000 */
+
+#define CHATGER_TIME 700 /* 700msec */
+#define USB_SUSPEND_TIME 2000 /* 2 sec */
+
+
+/* U2F FLAG */
+#define U2F_ENABLE 1
+#define U2F_DISABLE 0
+
+
+/*------- BIT */
+#define BIT00 0x00000001
+#define BIT01 0x00000002
+#define BIT02 0x00000004
+#define BIT03 0x00000008
+#define BIT04 0x00000010
+#define BIT05 0x00000020
+#define BIT06 0x00000040
+#define BIT07 0x00000080
+#define BIT08 0x00000100
+#define BIT09 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
+
+#if 0
+/*------- (0x0000) USB Control Register */
+#define USBTESTMODE (BIT18+BIT17+BIT16)
+#define TEST_J BIT16
+#define TEST_K BIT17
+#define TEST_SE0_NAK (BIT17+BIT16)
+#define TEST_PACKET BIT18
+#endif
+#define TEST_FORCE_ENABLE (BIT18+BIT16)
+
+#define INT_SEL BIT10
+#define CONSTFS BIT09
+#define SOF_RCV BIT08
+#define RSUM_IN BIT07
+#define SUSPEND BIT06
+#define CONF BIT05
+#define DEFAULT BIT04
+#define CONNECTB BIT03
+#define PUE2 BIT02
+
+#define MAX_TEST_MODE_NUM 0x05
+#define TEST_MODE_SHIFT 16
+
+/*------- (0x0004) USB Status Register */
+#define SPEED_MODE BIT06
+#define HIGH_SPEED BIT06
+
+#define CONF BIT05
+#define DEFAULT BIT04
+#define USB_RST BIT03
+#define SPND_OUT BIT02
+#define RSUM_OUT BIT01
+
+/*------- (0x0008) USB Address Register */
+#define USB_ADDR 0x007F0000
+#define SOF_STATUS BIT15
+#define UFRAME (BIT14+BIT13+BIT12)
+#define FRAME 0x000007FF
+
+#define USB_ADRS_SHIFT 16
+
+/*------- (0x000C) UTMI Characteristic 1 Register */
+#define SQUSET (BIT07+BIT06+BIT05+BIT04)
+
+#define USB_SQUSET (BIT06+BIT05+BIT04)
+
+/*------- (0x0010) TEST Control Register */
+#define FORCEHS BIT02
+#define CS_TESTMODEEN BIT01
+#define LOOPBACK BIT00
+
+/*------- (0x0018) Setup Data 0 Register */
+/*------- (0x001C) Setup Data 1 Register */
+
+/*------- (0x0020) USB Interrupt Status Register */
+#define EPn_INT 0x00FFFF00
+#define EP15_INT BIT23
+#define EP14_INT BIT22
+#define EP13_INT BIT21
+#define EP12_INT BIT20
+#define EP11_INT BIT19
+#define EP10_INT BIT18
+#define EP9_INT BIT17
+#define EP8_INT BIT16
+#define EP7_INT BIT15
+#define EP6_INT BIT14
+#define EP5_INT BIT13
+#define EP4_INT BIT12
+#define EP3_INT BIT11
+#define EP2_INT BIT10
+#define EP1_INT BIT09
+#define EP0_INT BIT08
+#define SPEED_MODE_INT BIT06
+#define SOF_ERROR_INT BIT05
+#define SOF_INT BIT04
+#define USB_RST_INT BIT03
+#define SPND_INT BIT02
+#define RSUM_INT BIT01
+
+#define USB_INT_STA_RW 0x7E
+
+/*------- (0x0024) USB Interrupt Enable Register */
+#define EP15_0_EN 0x00FFFF00
+#define EP15_EN BIT23
+#define EP14_EN BIT22
+#define EP13_EN BIT21
+#define EP12_EN BIT20
+#define EP11_EN BIT19
+#define EP10_EN BIT18
+#define EP9_EN BIT17
+#define EP8_EN BIT16
+#define EP7_EN BIT15
+#define EP6_EN BIT14
+#define EP5_EN BIT13
+#define EP4_EN BIT12
+#define EP3_EN BIT11
+#define EP2_EN BIT10
+#define EP1_EN BIT09
+#define EP0_EN BIT08
+#define SPEED_MODE_EN BIT06
+#define SOF_ERROR_EN BIT05
+#define SOF_EN BIT04
+#define USB_RST_EN BIT03
+#define SPND_EN BIT02
+#define RSUM_EN BIT01
+
+#define USB_INT_EN_BIT \
+ (EP0_EN|SPEED_MODE_EN|USB_RST_EN|SPND_EN|RSUM_EN)
+
+/*------- (0x0028) EP0 Control Register */
+#define EP0_STGSEL BIT18
+#define EP0_OVERSEL BIT17
+#define EP0_AUTO BIT16
+#define EP0_PIDCLR BIT09
+#define EP0_BCLR BIT08
+#define EP0_DEND BIT07
+#define EP0_DW (BIT06+BIT05)
+#define EP0_DW4 0
+#define EP0_DW3 (BIT06+BIT05)
+#define EP0_DW2 BIT06
+#define EP0_DW1 BIT05
+
+#define EP0_INAK_EN BIT04
+#define EP0_PERR_NAK_CLR BIT03
+#define EP0_STL BIT02
+#define EP0_INAK BIT01
+#define EP0_ONAK BIT00
+
+/*------- (0x002C) EP0 Status Register */
+#define EP0_PID BIT18
+#define EP0_PERR_NAK BIT17
+#define EP0_PERR_NAK_INT BIT16
+#define EP0_OUT_NAK_INT BIT15
+#define EP0_OUT_NULL BIT14
+#define EP0_OUT_FULL BIT13
+#define EP0_OUT_EMPTY BIT12
+#define EP0_IN_NAK_INT BIT11
+#define EP0_IN_DATA BIT10
+#define EP0_IN_FULL BIT09
+#define EP0_IN_EMPTY BIT08
+#define EP0_OUT_NULL_INT BIT07
+#define EP0_OUT_OR_INT BIT06
+#define EP0_OUT_INT BIT05
+#define EP0_IN_INT BIT04
+#define EP0_STALL_INT BIT03
+#define STG_END_INT BIT02
+#define STG_START_INT BIT01
+#define SETUP_INT BIT00
+
+#define EP0_STATUS_RW_BIT (BIT16|BIT15|BIT11|0xFF)
+
+/*------- (0x0030) EP0 Interrupt Enable Register */
+#define EP0_PERR_NAK_EN BIT16
+#define EP0_OUT_NAK_EN BIT15
+
+#define EP0_IN_NAK_EN BIT11
+
+#define EP0_OUT_NULL_EN BIT07
+#define EP0_OUT_OR_EN BIT06
+#define EP0_OUT_EN BIT05
+#define EP0_IN_EN BIT04
+#define EP0_STALL_EN BIT03
+#define STG_END_EN BIT02
+#define STG_START_EN BIT01
+#define SETUP_EN BIT00
+
+#define EP0_INT_EN_BIT \
+ (EP0_OUT_OR_EN|EP0_OUT_EN|EP0_IN_EN|STG_END_EN|SETUP_EN)
+
+/*------- (0x0034) EP0 Length Register */
+#define EP0_LDATA 0x0000007F
+
+/*------- (0x0038) EP0 Read Register */
+/*------- (0x003C) EP0 Write Register */
+
+/*------- (0x0040:) EPn Control Register */
+#define EPn_EN BIT31
+#define EPn_BUF_TYPE BIT30
+#define EPn_BUF_SINGLE BIT30
+
+#define EPn_DIR0 BIT26
+#define EPn_MODE (BIT25+BIT24)
+#define EPn_BULK 0
+#define EPn_INTERRUPT BIT24
+#define EPn_ISO BIT25
+
+#define EPn_OVERSEL BIT17
+#define EPn_AUTO BIT16
+
+#define EPn_IPIDCLR BIT11
+#define EPn_OPIDCLR BIT10
+#define EPn_BCLR BIT09
+#define EPn_CBCLR BIT08
+#define EPn_DEND BIT07
+#define EPn_DW (BIT06+BIT05)
+#define EPn_DW4 0
+#define EPn_DW3 (BIT06+BIT05)
+#define EPn_DW2 BIT06
+#define EPn_DW1 BIT05
+
+#define EPn_OSTL_EN BIT04
+#define EPn_ISTL BIT03
+#define EPn_OSTL BIT02
+
+#define EPn_ONAK BIT00
+
+/*------- (0x0044:) EPn Status Register */
+#define EPn_ISO_PIDERR BIT29 /* R */
+#define EPn_OPID BIT28 /* R */
+#define EPn_OUT_NOTKN BIT27 /* R */
+#define EPn_ISO_OR BIT26 /* R */
+
+#define EPn_ISO_CRC BIT24 /* R */
+#define EPn_OUT_END_INT BIT23 /* RW */
+#define EPn_OUT_OR_INT BIT22 /* RW */
+#define EPn_OUT_NAK_ERR_INT BIT21 /* RW */
+#define EPn_OUT_STALL_INT BIT20 /* RW */
+#define EPn_OUT_INT BIT19 /* RW */
+#define EPn_OUT_NULL_INT BIT18 /* RW */
+#define EPn_OUT_FULL BIT17 /* R */
+#define EPn_OUT_EMPTY BIT16 /* R */
+
+#define EPn_IPID BIT10 /* R */
+#define EPn_IN_NOTKN BIT09 /* R */
+#define EPn_ISO_UR BIT08 /* R */
+#define EPn_IN_END_INT BIT07 /* RW */
+
+#define EPn_IN_NAK_ERR_INT BIT05 /* RW */
+#define EPn_IN_STALL_INT BIT04 /* RW */
+#define EPn_IN_INT BIT03 /* RW */
+#define EPn_IN_DATA BIT02 /* R */
+#define EPn_IN_FULL BIT01 /* R */
+#define EPn_IN_EMPTY BIT00 /* R */
+
+#define EPn_INT_EN \
+ (EPn_OUT_END_INT|EPn_OUT_INT|EPn_IN_END_INT|EPn_IN_INT)
+
+/*------- (0x0048:) EPn Interrupt Enable Register */
+#define EPn_OUT_END_EN BIT23 /* RW */
+#define EPn_OUT_OR_EN BIT22 /* RW */
+#define EPn_OUT_NAK_ERR_EN BIT21 /* RW */
+#define EPn_OUT_STALL_EN BIT20 /* RW */
+#define EPn_OUT_EN BIT19 /* RW */
+#define EPn_OUT_NULL_EN BIT18 /* RW */
+
+#define EPn_IN_END_EN BIT07 /* RW */
+
+#define EPn_IN_NAK_ERR_EN BIT05 /* RW */
+#define EPn_IN_STALL_EN BIT04 /* RW */
+#define EPn_IN_EN BIT03 /* RW */
+
+/*------- (0x004C:) EPn Interrupt Enable Register */
+#define EPn_STOP_MODE BIT11
+#define EPn_DEND_SET BIT10
+#define EPn_BURST_SET BIT09
+#define EPn_STOP_SET BIT08
+
+#define EPn_DMA_EN BIT04
+
+#define EPn_DMAMODE0 BIT00
+
+/*------- (0x0050:) EPn MaxPacket & BaseAddress Register */
+#define EPn_BASEAD 0x1FFF0000
+#define EPn_MPKT 0x000007FF
+
+/*------- (0x0054:) EPn Length & DMA Count Register */
+#define EPn_DMACNT 0x01FF0000
+#define EPn_LDATA 0x000007FF
+
+/*------- (0x0058:) EPn Read Register */
+/*------- (0x005C:) EPn Write Register */
+
+/*------- (0x1000) AHBSCTR Register */
+#define WAIT_MODE BIT00
+
+/*------- (0x1004) AHBMCTR Register */
+#define ARBITER_CTR BIT31 /* RW */
+#define MCYCLE_RST BIT12 /* RW */
+
+#define ENDIAN_CTR (BIT09+BIT08) /* RW */
+#define ENDIAN_BYTE_SWAP BIT09
+#define ENDIAN_HALF_WORD_SWAP ENDIAN_CTR
+
+#define HBUSREQ_MODE BIT05 /* RW */
+#define HTRANS_MODE BIT04 /* RW */
+
+#define WBURST_TYPE BIT02 /* RW */
+#define BURST_TYPE (BIT01+BIT00) /* RW */
+#define BURST_MAX_16 0
+#define BURST_MAX_8 BIT00
+#define BURST_MAX_4 BIT01
+#define BURST_SINGLE BURST_TYPE
+
+/*------- (0x1008) AHBBINT Register */
+#define DMA_ENDINT 0xFFFE0000 /* RW */
+
+#define AHB_VBUS_INT BIT13 /* RW */
+
+#define MBUS_ERRINT BIT06 /* RW */
+
+#define SBUS_ERRINT0 BIT04 /* RW */
+#define ERR_MASTER 0x0000000F /* R */
+
+/*------- (0x100C) AHBBINTEN Register */
+#define DMA_ENDINTEN 0xFFFE0000 /* RW */
+
+#define VBUS_INTEN BIT13 /* RW */
+
+#define MBUS_ERRINTEN BIT06 /* RW */
+
+#define SBUS_ERRINT0EN BIT04 /* RW */
+
+/*------- (0x1010) EPCTR Register */
+#define DIRPD BIT12 /* RW */
+
+#define VBUS_LEVEL BIT08 /* R */
+
+#define PLL_RESUME BIT05 /* RW */
+#define PLL_LOCK BIT04 /* R */
+
+#ifdef CONFIG_MACH_EMGR
+#define PLL_RST BIT02 /* RW */
+#endif
+
+#define EPC_RST BIT00 /* RW */
+
+/*------- (0x1014) USBF_EPTEST Register */
+#define LINESTATE (BIT09+BIT08) /* R */
+#define DM_LEVEL BIT09 /* R */
+#define DP_LEVEL BIT08 /* R */
+
+#define PHY_TST BIT01 /* RW */
+#define PHY_TSTCLK BIT00 /* RW */
+
+/*------- (0x1020) USBSSVER Register */
+#define AHBB_VER 0x00FF0000 /* R */
+#define EPC_VER 0x0000FF00 /* R */
+#define SS_VER 0x000000FF /* R */
+
+/*------- (0x1024) USBSSCONF Register */
+#define EP_AVAILABLE 0xFFFF0000 /* R */
+#define DMA_AVAILABLE 0x0000FFFF /* R */
+
+/*------- (0x1110:) EPnDCR1 Register */
+#define DCR1_EPn_DMACNT 0x00FF0000 /* RW */
+
+#define DCR1_EPn_DIR0 BIT01 /* RW */
+#define DCR1_EPn_REQEN BIT00 /* RW */
+
+/*------- (0x1114:) EPnDCR2 Register */
+#define DCR2_EPn_LMPKT 0x07FF0000 /* RW */
+
+#define DCR2_EPn_MPKT 0x000007FF /* RW */
+
+/*------- (0x1118:) EPnTADR Register */
+#define EPn_TADR 0xFFFFFFFF /* RW */
+
+
+
+/*===========================================================================*/
+/* Struct */
+/*------- T_EP_REGS */
+typedef struct _T_EP_REGS {
+ u32 EP_CONTROL; /* EP Control */
+ u32 EP_STATUS; /* EP Status */
+ u32 EP_INT_ENA; /* EP Interrupt Enable */
+ u32 EP_DMA_CTRL; /* EP DMA Control */
+ u32 EP_PCKT_ADRS; /* EP Maxpacket & BaseAddress */
+ u32 EP_LEN_DCNT; /* EP Length & DMA count */
+ u32 EP_READ; /* EP Read */
+ u32 EP_WRITE; /* EP Write */
+} T_EP_REGS, *PT_EP_REGS;
+
+/*------- T_EP_DCR */
+typedef struct _T_EP_DCR {
+ u32 EP_DCR1; /* EP_DCR1 */
+ u32 EP_DCR2; /* EP_DCR2 */
+ u32 EP_TADR; /* EP_TADR */
+ u32 Reserved; /* Reserved */
+} T_EP_DCR, *PT_EP_DCR;
+
+/*------- Function Registers */
+typedef struct _T_FC_REGS {
+ u32 USB_CONTROL; /* (0x0000) USB Control */
+ u32 USB_STATUS; /* (0x0004) USB Status */
+ u32 USB_ADDRESS; /* (0x0008) USB Address */
+ u32 UTMI_CHARACTER_1; /* (0x000C) UTMI Setting */
+ u32 TEST_CONTROL; /* (0x0010) TEST Control */
+ u32 Reserved_14; /* (0x0014) Reserved */
+ u32 SETUP_DATA0; /* (0x0018) Setup Data0 */
+ u32 SETUP_DATA1; /* (0x001C) Setup Data1 */
+ u32 USB_INT_STA; /* (0x0020) USB Interrupt Status */
+ u32 USB_INT_ENA; /* (0x0024) USB Interrupt Enable */
+ u32 EP0_CONTROL; /* (0x0028) EP0 Control */
+ u32 EP0_STATUS; /* (0x002C) EP0 Status */
+ u32 EP0_INT_ENA; /* (0x0030) EP0 Interrupt Enable */
+ u32 EP0_LENGTH; /* (0x0034) EP0 Length */
+ u32 EP0_READ; /* (0x0038) EP0 Read */
+ u32 EP0_WRITE; /* (0x003C) EP0 Write */
+
+ T_EP_REGS EP_REGS[REG_EP_NUM]; /* Endpoint Register */
+
+ u8 Reserved220[0x1000-0x220]; /* (0x0220:0x0FFF) Reserved */
+
+ u32 AHBSCTR; /* (0x1000) AHBSCTR */
+ u32 AHBMCTR; /* (0x1004) AHBMCTR */
+ u32 AHBBINT; /* (0x1008) AHBBINT */
+ u32 AHBBINTEN; /* (0x100C) AHBBINTEN */
+ u32 EPCTR; /* (0x1010) EPCTR */
+ u32 USBF_EPTEST; /* (0x1014) USBF_EPTEST */
+
+ u8 Reserved1018[0x20-0x18]; /* (0x1018:0x101F) Reserved */
+
+ u32 USBSSVER; /* (0x1020) USBSSVER */
+ u32 USBSSCONF; /* (0x1024) USBSSCONF */
+
+ u8 Reserved1028[0x110-0x28]; /* (0x1028:0x110F) Reserved */
+
+ T_EP_DCR EP_DCR[REG_EP_NUM]; /* */
+
+ u8 Reserved1200[0x1000-0x200]; /* Reserved */
+
+} __attribute__ ((aligned(32))) T_FC_REGS, *PT_FC_REGS;
+
+
+
+
+
+
+
+
+#define EP0_PACKETSIZE 64
+#define EP_PACKETSIZE 1024
+
+/* EPn RAM SIZE */
+#define D_RAM_SIZE_CTRL 64
+
+/* EPn Bulk Endpoint Max Packet Size */
+#define D_FS_RAM_SIZE_BULK 64
+#define D_HS_RAM_SIZE_BULK 512
+
+
+struct nbu2ss_udc;
+
+
+enum ep0_state {
+ EP0_IDLE,
+ EP0_IN_DATA_PHASE,
+ EP0_OUT_DATA_PHASE,
+ EP0_IN_STATUS_PHASE,
+ EP0_OUT_STATUS_PAHSE,
+ EP0_END_XFER,
+ EP0_SUSPEND,
+ EP0_STALL,
+};
+
+struct nbu2ss_req {
+ struct usb_request req;
+ struct list_head queue;
+
+ u32 div_len;
+ bool dma_flag;
+ bool zero;
+
+ bool unaligned;
+
+ unsigned mapped:1;
+};
+
+struct nbu2ss_ep {
+ struct usb_ep ep;
+ struct list_head queue;
+
+ struct nbu2ss_udc *udc;
+
+ const struct usb_endpoint_descriptor *desc;
+
+ u8 epnum;
+ u8 direct;
+ u8 ep_type;
+
+ unsigned wedged:1;
+ unsigned halted:1;
+ unsigned stalled:1;
+
+ u8 *virt_buf;
+ dma_addr_t phys_buf;
+};
+
+
+struct nbu2ss_udc {
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+ struct platform_device *pdev;
+ struct device *dev;
+ spinlock_t lock;
+ struct completion *pdone;
+
+ enum ep0_state ep0state;
+ enum usb_device_state devstate;
+ struct usb_ctrlrequest ctrl;
+ struct nbu2ss_req ep0_req;
+ u8 ep0_buf[EP0_PACKETSIZE];
+
+ struct nbu2ss_ep ep[NUM_ENDPOINTS];
+
+ unsigned softconnect:1;
+ unsigned vbus_active:1;
+ unsigned linux_suspended:1;
+ unsigned linux_resume:1;
+ unsigned usb_suspended:1;
+ unsigned self_powered:1;
+ unsigned remote_wakeup:1;
+ unsigned udc_enabled:1;
+
+ unsigned mA;
+
+ u32 curr_config; /* Current Configuration Number */
+
+ PT_FC_REGS p_regs;
+};
+
+/* USB register access structure */
+typedef volatile union {
+ struct {
+ unsigned char DATA[4];
+ } byte;
+ unsigned int dw;
+} USB_REG_ACCESS;
+
+/*-------------------------------------------------------------------------*/
+#define ERR(stuff...) printk(KERN_ERR "udc: " stuff)
+
+#endif /* _LINUX_EMXX_H */
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 08356b6955a4..8bf1eb485163 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -285,7 +285,7 @@ struct fbr_lookup {
dma_addr_t buffsize;
};
-/* struct rx_ring is the sructure representing the adaptor's local
+/* struct rx_ring is the structure representing the adaptor's local
* reference(s) to the rings
*/
struct rx_ring {
@@ -532,8 +532,6 @@ struct et131x_adapter {
/* Stats */
struct ce_stats stats;
-
- struct net_device_stats net_stats;
};
static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
@@ -1943,7 +1941,7 @@ static void et131x_disable_interrupts(struct et131x_adapter *adapter)
/* et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 */
static void et131x_tx_dma_disable(struct et131x_adapter *adapter)
{
- /* Setup the tramsmit dma configuration register */
+ /* Setup the transmit dma configuration register */
writel(ET_TXDMA_CSR_HALT | ET_TXDMA_SNGL_EPKT,
&adapter->regs->txdma.csr);
}
@@ -2618,7 +2616,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter)
return NULL;
}
- adapter->net_stats.rx_bytes += rfd->len;
+ adapter->netdev->stats.rx_bytes += rfd->len;
memcpy(skb_put(skb, rfd->len), fbr->virt[buff_index], rfd->len);
@@ -2666,7 +2664,7 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
continue;
/* Increment the number of packets we received */
- adapter->net_stats.rx_packets++;
+ adapter->netdev->stats.rx_packets++;
/* Set the status on the packet, either resources or success */
if (rx_ring->num_ready_recv < RFD_LOW_WATER_MARK)
@@ -3037,7 +3035,7 @@ static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
dev_kfree_skb_any(skb);
skb = NULL;
- adapter->net_stats.tx_dropped++;
+ adapter->netdev->stats.tx_dropped++;
} else {
status = send_packet(skb, adapter);
if (status != 0 && status != -ENOMEM) {
@@ -3046,7 +3044,7 @@ static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
*/
dev_kfree_skb_any(skb);
skb = NULL;
- adapter->net_stats.tx_dropped++;
+ adapter->netdev->stats.tx_dropped++;
}
}
}
@@ -3065,7 +3063,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter,
{
unsigned long flags;
struct tx_desc *desc = NULL;
- struct net_device_stats *stats = &adapter->net_stats;
+ struct net_device_stats *stats = &adapter->netdev->stats;
struct tx_ring *tx_ring = &adapter->tx_ring;
u64 dma_addr;
@@ -3110,7 +3108,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter,
/* Add the TCB to the Ready Q */
spin_lock_irqsave(&adapter->tcb_ready_qlock, flags);
- adapter->net_stats.tx_packets++;
+ stats->tx_packets++;
if (tx_ring->tcb_qtail)
tx_ring->tcb_qtail->next = tcb;
@@ -4025,7 +4023,7 @@ static void et131x_isr_handler(struct work_struct *work)
if (status & ET_INTR_RXDMA_STAT_LOW) {
/* Same idea as with the two Free Buffer Rings. Packets going
* from the network to the host each consume a free buffer
- * resource and a packet status resource. These resoures are
+ * resource and a packet status resource. These resources are
* passed to the OS. When the OS is done with the resources,
* they need to be returned to the ET1310. This is one method
* of returning the resources.
@@ -4134,7 +4132,7 @@ out:
static struct net_device_stats *et131x_stats(struct net_device *netdev)
{
struct et131x_adapter *adapter = netdev_priv(netdev);
- struct net_device_stats *stats = &adapter->net_stats;
+ struct net_device_stats *stats = &adapter->netdev->stats;
struct ce_stats *devstat = &adapter->stats;
stats->rx_errors = devstat->rx_length_errs +
@@ -4426,7 +4424,7 @@ static void et131x_tx_timeout(struct net_device *netdev)
tcb->index,
tcb->flags);
- adapter->net_stats.tx_errors++;
+ adapter->netdev->stats.tx_errors++;
/* perform reset of tx/rx */
et131x_disable_txrx(netdev);
@@ -4633,7 +4631,7 @@ static int et131x_pci_setup(struct pci_dev *pdev,
/* Allocate DMA memory */
rc = et131x_adapter_memory_alloc(adapter);
if (rc < 0) {
- dev_err(&pdev->dev, "Could not alloc adapater memory (DMA)\n");
+ dev_err(&pdev->dev, "Could not alloc adapter memory (DMA)\n");
goto err_iounmap;
}
diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
index 2ac6e9980117..1318439db13e 100644
--- a/drivers/staging/et131x/et131x.h
+++ b/drivers/staging/et131x/et131x.h
@@ -145,7 +145,7 @@
*31: selfclr_disable
*/
-#define ET_RESET_ALL 0x007F;
+#define ET_RESET_ALL 0x007F
/*
* SLV Timer reg at address 0x002C (low 24 bits)
@@ -394,7 +394,7 @@ struct txdma_regs { /* Location: */
* 11-0: psr ndes
*/
-#define ET_RXDMA_PSR_NUM_DES_MASK 0xFFF;
+#define ET_RXDMA_PSR_NUM_DES_MASK 0xFFF
/*
* structure for packet status ring available offset reg in rxdma address map
@@ -755,7 +755,7 @@ struct txmac_regs { /* Location: */
*/
/*
- * structure for Unicast Paket Filter Address 1 reg in rxmac address map
+ * structure for Unicast Packet Filter Address 1 reg in rxmac address map
* located at address 0x4068
*
* 31-24: addr1_3
@@ -769,7 +769,7 @@ struct txmac_regs { /* Location: */
#define ET_RX_UNI_PF_ADDR1_5_SHIFT 8
/*
- * structure for Unicast Paket Filter Address 2 reg in rxmac address map
+ * structure for Unicast Packet Filter Address 2 reg in rxmac address map
* located at address 0x406C
*
* 31-24: addr2_3
@@ -783,7 +783,7 @@ struct txmac_regs { /* Location: */
#define ET_RX_UNI_PF_ADDR2_5_SHIFT 8
/*
- * structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map
+ * structure for Unicast Packet Filter Address 1 & 2 reg in rxmac address map
* located at address 0x4070
*
* 31-24: addr2_1
@@ -815,11 +815,11 @@ struct txmac_regs { /* Location: */
* 0: filter_broad_en
*/
-#define ET_RX_PFCTRL_MIN_PKT_SZ_SHIFT 16;
-#define ET_RX_PFCTRL_FRAG_FILTER_ENABLE 0x0008;
-#define ET_RX_PFCTRL_UNICST_FILTER_ENABLE 0x0004;
-#define ET_RX_PFCTRL_MLTCST_FILTER_ENABLE 0x0002;
-#define ET_RX_PFCTRL_BRDCST_FILTER_ENABLE 0x0001;
+#define ET_RX_PFCTRL_MIN_PKT_SZ_SHIFT 16
+#define ET_RX_PFCTRL_FRAG_FILTER_ENABLE 0x0008
+#define ET_RX_PFCTRL_UNICST_FILTER_ENABLE 0x0004
+#define ET_RX_PFCTRL_MLTCST_FILTER_ENABLE 0x0002
+#define ET_RX_PFCTRL_BRDCST_FILTER_ENABLE 0x0001
/*
* structure for Memory Controller Interface Control Max Segment reg in rxmac
@@ -831,9 +831,9 @@ struct txmac_regs { /* Location: */
* 0: seg_en
*/
-#define ET_RX_MCIF_CTRL_MAX_SEG_SIZE_SHIFT 2;
-#define ET_RX_MCIF_CTRL_MAX_SEG_FC_ENABLE 0x0002;
-#define ET_RX_MCIF_CTRL_MAX_SEG_ENABLE 0x0001;
+#define ET_RX_MCIF_CTRL_MAX_SEG_SIZE_SHIFT 2
+#define ET_RX_MCIF_CTRL_MAX_SEG_FC_ENABLE 0x0002
+#define ET_RX_MCIF_CTRL_MAX_SEG_ENABLE 0x0001
/*
* structure for Memory Controller Interface Water Mark reg in rxmac address
@@ -987,15 +987,15 @@ struct rxmac_regs { /* Location: */
* 0: full duplex
*/
-#define ET_MAC_CFG2_PREAMBLE_SHIFT 12;
-#define ET_MAC_CFG2_IFMODE_MASK 0x0300;
-#define ET_MAC_CFG2_IFMODE_1000 0x0200;
-#define ET_MAC_CFG2_IFMODE_100 0x0100;
-#define ET_MAC_CFG2_IFMODE_HUGE_FRAME 0x0020;
-#define ET_MAC_CFG2_IFMODE_LEN_CHECK 0x0010;
-#define ET_MAC_CFG2_IFMODE_PAD_CRC 0x0004;
-#define ET_MAC_CFG2_IFMODE_CRC_ENABLE 0x0002;
-#define ET_MAC_CFG2_IFMODE_FULL_DPLX 0x0001;
+#define ET_MAC_CFG2_PREAMBLE_SHIFT 12
+#define ET_MAC_CFG2_IFMODE_MASK 0x0300
+#define ET_MAC_CFG2_IFMODE_1000 0x0200
+#define ET_MAC_CFG2_IFMODE_100 0x0100
+#define ET_MAC_CFG2_IFMODE_HUGE_FRAME 0x0020
+#define ET_MAC_CFG2_IFMODE_LEN_CHECK 0x0010
+#define ET_MAC_CFG2_IFMODE_PAD_CRC 0x0004
+#define ET_MAC_CFG2_IFMODE_CRC_ENABLE 0x0002
+#define ET_MAC_CFG2_IFMODE_FULL_DPLX 0x0001
/*
* structure for Interpacket gap reg in mac address map.
@@ -1084,7 +1084,7 @@ struct rxmac_regs { /* Location: */
* 15-0: phy control
*/
-#define ET_MAC_MIIMGMT_STAT_PHYCRTL_MASK 0xFFFF;
+#define ET_MAC_MIIMGMT_STAT_PHYCRTL_MASK 0xFFFF
/*
* structure for MII Management Indicators reg in mac address map.
diff --git a/drivers/staging/frontier/Kconfig b/drivers/staging/frontier/Kconfig
deleted file mode 100644
index 4da290b2f5bd..000000000000
--- a/drivers/staging/frontier/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config TRANZPORT
- tristate "Frontier Tranzport and Alphatrack support"
- depends on USB
- ---help---
- Enable support for the Frontier Tranzport and Alphatrack devices.
diff --git a/drivers/staging/frontier/Makefile b/drivers/staging/frontier/Makefile
deleted file mode 100644
index 2d2ac97492dd..000000000000
--- a/drivers/staging/frontier/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_TRANZPORT) += tranzport.o
-obj-$(CONFIG_TRANZPORT) += alphatrack.o
diff --git a/drivers/staging/frontier/README b/drivers/staging/frontier/README
deleted file mode 100644
index cd07af22406a..000000000000
--- a/drivers/staging/frontier/README
+++ /dev/null
@@ -1,47 +0,0 @@
-This directory contains the Linux USB Tranzport and Alphatrack Kernel drivers.
-
-See http://www.frontierdesign.com for details on these devices.
-
-Userspace test code is available from
-
-git://toutatis.isc.org/home/d/src/git/frontier.git
-
-At present the tranzport does reads/writes of 8 byte cmds to
-/dev/tranzport0 to control the lights, screen, and wheel.
-
-At present the alphatrack accepts reads/writes of 12 byte cmds to
-/dev/tranzport0 to control the lights, screen, fader and touchpad.
-
-The tranzport driver provides a rudimentary sysfs interface for the status of
-the device and a writable parameter for turning wheel compression on and off.
-
-The API is nothing more than the USB commands issued to the device. Why?
-
-The control wheel/fader can generate events far too quickly for
-a typical userspace application to keep up with them via libusb. Input
-needs to be 100% accurate and fast in order for the alphatrack or tranzport
-to be useful.
-
-UIO would be useful except that usb disconnect events need
-to be handled correctly.
-
-A sysfs interface is perfect for simple userspace apps to do fun things with
-the lights and screen. But it's fairly lousy for handling input events and
-very lousy for watching the state of the shuttle wheel.
-
-A linux input events interface is great for the input events and shuttle wheel.
-* It's theoretically OK on LEDs.
-* A fader can be mapped to an absolute mouse device.
-* But there is no LCD support at all, or fader feedback support in that API
-
-So, thus, these stubby drivers exist.
-
-In the end this could be driven by a midi layer, which handles all those
-cases via a well defined API, but - among other things - is slow, doesn't do
-flow control, and is a LOT of extra work, none of which is required at
-the kernel level (probably). Frankly, I'd like to keep the
-core driver simple because the only realtime work really required is
-the bottom half interrupt handler and the output overlapping.
-
-Exposing some sort of clean api to userspace would be perfect. What that
-API looks like? Gah. beats me.
diff --git a/drivers/staging/frontier/TODO b/drivers/staging/frontier/TODO
deleted file mode 100644
index 3620ad2df3ee..000000000000
--- a/drivers/staging/frontier/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-TODO:
- - checkpatch.pl clean
- - sparse clean
- - fix userspace interface to be sane
- - possibly just port to userspace with libusb
- - review by the USB developer community
-
-Please send any patches for this driver to Greg Kroah-Hartman <greg@kroah.com>
-and David Taht <d@teklibre.com>.
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
deleted file mode 100644
index 226b23163109..000000000000
--- a/drivers/staging/frontier/alphatrack.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Frontier Designs Alphatrack driver
- *
- * Copyright (C) 2007 Michael Taht (m@taht.net)
- *
- * Based on the usbled driver and ldusb drivers by
- *
- * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de>
- *
- * The ldusb driver was, in turn, derived from Lego USB Tower driver
- * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net>
- * 2001-2004 Juergen Stuber <starblue@users.sourceforge.net>
- *
- * 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.
- *
- */
-
-/**
- * This driver uses a ring buffer for time critical reading of
- * interrupt in reports and provides read and write methods for
- * raw interrupt reports.
- */
-
-/*
- * Note: this currently uses a dumb ringbuffer for reads and writes.
- * A more optimal driver would cache and kill off outstanding urbs that are
- * now invalid, and ignore ones that already were in the queue but valid
- * as we only have 30 commands for the alphatrack. In particular this is
- * key for getting lights to flash in time as otherwise many commands
- * can be buffered up before the light change makes it to the interface.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kobject.h>
-#include <linux/mutex.h>
-
-#include <linux/uaccess.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/poll.h>
-
-#include "alphatrack.h"
-
-#define VENDOR_ID 0x165b
-#define PRODUCT_ID 0xfad1
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-#define USB_ALPHATRACK_MINOR_BASE 0
-#else
-/* FIXME 176 - is another driver's minor - apply for that */
-#define USB_ALPHATRACK_MINOR_BASE 176
-#endif
-
-/* table of devices that work with this driver */
-static const struct usb_device_id usb_alphatrack_table[] = {
- {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, usb_alphatrack_table);
-MODULE_VERSION("0.41");
-MODULE_AUTHOR("Mike Taht <m@taht.net>");
-MODULE_DESCRIPTION("Alphatrack USB Driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("Frontier Designs Alphatrack Control Surface");
-
-/* These aren't done yet */
-
-#define SUPPRESS_EXTRA_ONLINE_EVENTS 0
-#define BUFFERED_WRITES 0
-#define SUPPRESS_EXTRA_OFFLINE_EVENTS 0
-#define COMPRESS_FADER_EVENTS 0
-
-#define BUFFERED_READS 1
-#define RING_BUFFER_SIZE 512
-#define WRITE_BUFFER_SIZE 34
-#define ALPHATRACK_USB_TIMEOUT 10
-#define OUTPUT_CMD_SIZE 8
-#define INPUT_CMD_SIZE 12
-#define ALPHATRACK_DEBUG 0
-
-static int debug = ALPHATRACK_DEBUG;
-
-/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do \
- { if (debug) dev_info(dev , format , ## arg); } while (0)
-
-#define alphatrack_ocmd_info(dev, cmd, format, arg...)
-
-#define alphatrack_icmd_info(dev, cmd, format, arg...)
-
-/* Module parameters */
-
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-/*
- * All interrupt in transfers are collected in a ring buffer to
- * avoid racing conditions and get better performance of the driver.
- */
-
-static int ring_buffer_size = RING_BUFFER_SIZE;
-
-module_param(ring_buffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
-
-/* The write_buffer can one day contain more than one interrupt out transfer.*/
-
-static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
-
-/*
- * Increase the interval for debugging purposes.
- * or set to 1 to use the standard interval from the endpoint descriptors.
- */
-
-static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT;
-module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval,
- "Minimum interrupt in interval in ms");
-
-static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT;
-module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval,
- "Minimum interrupt out interval in ms");
-
-/* Structure to hold all of our device specific stuff */
-
-struct usb_alphatrack {
- struct mutex mtx; /* locks this structure */
- struct usb_interface *intf; /* save off the usb interface pointer */
- int open_count; /* number of times this port has been opened */
-
- /* make gcc happy */
- struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE];
- struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE];
- unsigned int ring_head;
- unsigned int ring_tail;
-
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
-
- unsigned char *interrupt_in_buffer;
- unsigned char *oldi_buffer;
- struct usb_endpoint_descriptor *interrupt_in_endpoint;
- struct urb *interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
-
- char *interrupt_out_buffer;
- struct usb_endpoint_descriptor *interrupt_out_endpoint;
- struct urb *interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
-
- atomic_t writes_pending;
- int event; /* alternate interface to events */
- int fader; /* 10 bits */
- int lights; /* 23 bits */
- unsigned char dump_state; /* 0 if disabled 1 if enabled */
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char verbose; /* be verbose in error reporting */
- unsigned char last_cmd[OUTPUT_CMD_SIZE];
- unsigned char screen[32];
-};
-
-/* prevent races between open() and disconnect() */
-static DEFINE_MUTEX(disconnect_mutex);
-
-/* forward declaration */
-
-static struct usb_driver usb_alphatrack_driver;
-
-/**
- * usb_alphatrack_abort_transfers
- * aborts transfers and frees associated data structures
- */
-static void usb_alphatrack_abort_transfers(struct usb_alphatrack *dev)
-{
- /* shutdown transfer */
- if (dev->interrupt_in_running) {
- dev->interrupt_in_running = 0;
- if (dev->intf)
- usb_kill_urb(dev->interrupt_in_urb);
- }
- if (dev->interrupt_out_busy)
- if (dev->intf)
- usb_kill_urb(dev->interrupt_out_urb);
-}
-
-/** usb_alphatrack_delete */
-static void usb_alphatrack_delete(struct usb_alphatrack *dev)
-{
- usb_alphatrack_abort_transfers(dev);
- usb_free_urb(dev->interrupt_in_urb);
- usb_free_urb(dev->interrupt_out_urb);
- kfree(dev->ring_buffer);
- kfree(dev->interrupt_in_buffer);
- kfree(dev->interrupt_out_buffer);
- kfree(dev->oldi_buffer);
- kfree(dev->write_buffer);
- kfree(dev);
-}
-
-/** usb_alphatrack_interrupt_in_callback */
-
-static void usb_alphatrack_interrupt_in_callback(struct urb *urb)
-{
- struct usb_alphatrack *dev = urb->context;
- unsigned int next_ring_head;
- int retval = -1;
-
- if (urb->status) {
- if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) {
- goto exit;
- } else {
- dbg_info(&dev->intf->dev,
- "%s: nonzero status received: %d\n", __func__,
- urb->status);
- goto resubmit; /* maybe we can recover */
- }
- }
-
- if (urb->actual_length != INPUT_CMD_SIZE) {
- dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent\n",
- urb->actual_length);
- } else {
- alphatrack_ocmd_info(&dev->intf->dev,
- &(*dev->ring_buffer)[dev->ring_tail].cmd,
- "%s", "bla");
- if (memcmp
- (dev->interrupt_in_buffer, dev->oldi_buffer,
- INPUT_CMD_SIZE) == 0) {
- goto resubmit;
- }
- memcpy(dev->oldi_buffer, dev->interrupt_in_buffer,
- INPUT_CMD_SIZE);
-
-#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
- goto resubmit;
- if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
- dev->offline = 2;
- goto resubmit;
- }
-/* Always pass one offline event up the stack */
- if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
- dev->offline = 0;
- if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
- dev->offline = 1;
-#endif
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
- next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
-
- if (next_ring_head != dev->ring_tail) {
- memcpy(&((*dev->ring_buffer)[dev->ring_head]),
- dev->interrupt_in_buffer, urb->actual_length);
- dev->ring_head = next_ring_head;
- retval = 0;
- memset(dev->interrupt_in_buffer, 0, urb->actual_length);
- } else {
- dev_warn(&dev->intf->dev,
- "Ring buffer overflow, %d bytes dropped\n",
- urb->actual_length);
- memset(dev->interrupt_in_buffer, 0, urb->actual_length);
- }
- }
-
-resubmit:
- /* resubmit if we're still running */
- if (dev->interrupt_in_running && dev->intf) {
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&dev->intf->dev,
- "usb_submit_urb failed (%d)\n", retval);
- }
-
-exit:
- dev->interrupt_in_done = 1;
- wake_up_interruptible(&dev->read_wait);
-}
-
-/** usb_alphatrack_interrupt_out_callback */
-static void usb_alphatrack_interrupt_out_callback(struct urb *urb)
-{
- struct usb_alphatrack *dev = urb->context;
-
- /* sync/async unlink faults aren't errors */
- if (urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
- dbg_info(&dev->intf->dev,
- "%s - nonzero write interrupt status received: %d\n",
- __func__, urb->status);
- atomic_dec(&dev->writes_pending);
- dev->interrupt_out_busy = 0;
- wake_up_interruptible(&dev->write_wait);
-}
-
-/** usb_alphatrack_open */
-static int usb_alphatrack_open(struct inode *inode, struct file *file)
-{
- struct usb_alphatrack *dev;
- int subminor;
- int retval = 0;
- struct usb_interface *interface;
-
- nonseekable_open(inode, file);
- subminor = iminor(inode);
-
- mutex_lock(&disconnect_mutex);
-
- interface = usb_find_interface(&usb_alphatrack_driver, subminor);
-
- if (!interface) {
- pr_err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
- retval = -ENODEV;
- goto unlock_disconnect_exit;
- }
-
- dev = usb_get_intfdata(interface);
-
- if (!dev) {
- retval = -ENODEV;
- goto unlock_disconnect_exit;
- }
-
- /* lock this device */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto unlock_disconnect_exit;
- }
-
- /* allow opening only once */
- if (dev->open_count) {
- retval = -EBUSY;
- goto unlock_exit;
- }
- dev->open_count = 1;
-
- /* initialize in direction */
- dev->ring_head = 0;
- dev->ring_tail = 0;
- usb_fill_int_urb(dev->interrupt_in_urb,
- interface_to_usbdev(interface),
- usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->
- bEndpointAddress),
- dev->interrupt_in_buffer,
- dev->interrupt_in_endpoint_size,
- usb_alphatrack_interrupt_in_callback, dev,
- dev->interrupt_in_interval);
-
- dev->interrupt_in_running = 1;
- dev->interrupt_in_done = 0;
- dev->enable = 1;
- dev->offline = 0;
-
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&interface->dev,
- "Couldn't submit interrupt_in_urb %d\n", retval);
- dev->interrupt_in_running = 0;
- dev->open_count = 0;
- goto unlock_exit;
- }
-
- /* save device in the file's private structure */
- file->private_data = dev;
-
-unlock_exit:
- mutex_unlock(&dev->mtx);
-
-unlock_disconnect_exit:
- mutex_unlock(&disconnect_mutex);
-
- return retval;
-}
-
-/** usb_alphatrack_release */
-static int usb_alphatrack_release(struct inode *inode, struct file *file)
-{
- struct usb_alphatrack *dev;
- int retval = 0;
-
- dev = file->private_data;
-
- if (dev == NULL) {
- retval = -ENODEV;
- goto exit;
- }
-
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- if (dev->open_count != 1) {
- retval = -ENODEV;
- goto unlock_exit;
- }
-
- if (dev->intf == NULL) {
- /* the device was unplugged before the file was released */
- mutex_unlock(&dev->mtx);
- /* unlock here as usb_alphatrack_delete frees dev */
- usb_alphatrack_delete(dev);
- retval = -ENODEV;
- goto exit;
- }
-
- /* wait until write transfer is finished */
- if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait,
- !dev->interrupt_out_busy,
- 2 * HZ);
- usb_alphatrack_abort_transfers(dev);
- dev->open_count = 0;
-
-unlock_exit:
- mutex_unlock(&dev->mtx);
-
-exit:
- return retval;
-}
-
-/** usb_alphatrack_poll */
-static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
-{
- struct usb_alphatrack *dev;
- unsigned int mask = 0;
-
- dev = file->private_data;
-
- poll_wait(file, &dev->read_wait, wait);
- poll_wait(file, &dev->write_wait, wait);
-
- if (dev->ring_head != dev->ring_tail)
- mask |= POLLIN | POLLRDNORM;
- if (!dev->interrupt_out_busy)
- mask |= POLLOUT | POLLWRNORM;
-
- return mask;
-}
-
-/** usb_alphatrack_read */
-static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct usb_alphatrack *dev;
- int retval = 0;
-
- int c = 0;
-
- dev = file->private_data;
-
- /* verify that we actually have some data to read */
- if (count == 0)
- goto exit;
-
- /* lock this object */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
- retval = -ENODEV;
- pr_err("%s: No device or device unplugged %d\n",
- __func__, retval);
- goto unlock_exit;
- }
-
- while (dev->ring_head == dev->ring_tail) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- dev->interrupt_in_done = 0;
- retval =
- wait_event_interruptible(dev->read_wait,
- dev->interrupt_in_done);
- if (retval < 0)
- goto unlock_exit;
- }
-
- alphatrack_ocmd_info(&dev->intf->dev,
- &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s",
- ": copying to userspace");
-
- c = 0;
- while ((c < count) && (dev->ring_tail != dev->ring_head)) {
- if (copy_to_user
- (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail],
- INPUT_CMD_SIZE)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
- dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
- c += INPUT_CMD_SIZE;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
- }
- retval = c;
-
-unlock_exit:
- /* unlock the device */
- mutex_unlock(&dev->mtx);
-
-exit:
- return retval;
-}
-
-/** usb_alphatrack_write */
-static ssize_t usb_alphatrack_write(struct file *file,
- const char __user *buffer, size_t count,
- loff_t *ppos)
-{
- struct usb_alphatrack *dev;
- size_t bytes_to_write;
- int retval = 0;
-
- dev = file->private_data;
-
- /* verify that we actually have some data to write */
- if (count == 0)
- goto exit;
-
- /* lock this object */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
- retval = -ENODEV;
- pr_err("%s: No device or device unplugged %d\n",
- __func__, retval);
- goto unlock_exit;
- }
-
- /* wait until previous transfer is finished */
- if (dev->interrupt_out_busy) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- retval =
- wait_event_interruptible(dev->write_wait,
- !dev->interrupt_out_busy);
- if (retval < 0)
- goto unlock_exit;
- }
-
- /* write the data into interrupt_out_buffer from userspace */
- /* FIXME - if you write more than 12 bytes this breaks */
- bytes_to_write =
- min(count, write_buffer_size * dev->interrupt_out_endpoint_size);
- if (bytes_to_write < count)
- dev_warn(&dev->intf->dev,
- "Write buffer overflow, %zd bytes dropped\n",
- count - bytes_to_write);
-
- dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
- __func__, count, bytes_to_write);
-
- if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
-
- if (dev->interrupt_out_endpoint == NULL) {
- dev_err(&dev->intf->dev, "Endpoint should not be null!\n");
- goto unlock_exit;
- }
-
- /* send off the urb */
- usb_fill_int_urb(dev->interrupt_out_urb,
- interface_to_usbdev(dev->intf),
- usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->
- bEndpointAddress),
- dev->interrupt_out_buffer, bytes_to_write,
- usb_alphatrack_interrupt_out_callback, dev,
- dev->interrupt_out_interval);
- dev->interrupt_out_busy = 1;
- atomic_inc(&dev->writes_pending);
- wmb();
-
- retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
- if (retval) {
- dev->interrupt_out_busy = 0;
- dev_err(&dev->intf->dev,
- "Couldn't submit interrupt_out_urb %d\n", retval);
- atomic_dec(&dev->writes_pending);
- goto unlock_exit;
- }
- retval = bytes_to_write;
-
-unlock_exit:
- /* unlock the device */
- mutex_unlock(&dev->mtx);
-
-exit:
- return retval;
-}
-
-/* file operations needed when we register this driver */
-static const struct file_operations usb_alphatrack_fops = {
- .owner = THIS_MODULE,
- .read = usb_alphatrack_read,
- .write = usb_alphatrack_write,
- .open = usb_alphatrack_open,
- .release = usb_alphatrack_release,
- .poll = usb_alphatrack_poll,
- .llseek = no_llseek,
-};
-
-/*
- * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with the driver core
- */
-
-static struct usb_class_driver usb_alphatrack_class = {
- .name = "alphatrack%d",
- .fops = &usb_alphatrack_fops,
- .minor_base = USB_ALPHATRACK_MINOR_BASE,
-};
-
-/**
- * usb_alphatrack_probe
- *
- * Called by the usb core when a new device is connected that it thinks
- * this driver might be interested in.
- */
-static int usb_alphatrack_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_alphatrack *dev = NULL;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int i;
- int true_size;
- int retval = -ENOMEM;
-
- /* allocate memory for our device state and initialize it */
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- goto exit;
-
- mutex_init(&dev->mtx);
- dev->intf = intf;
- init_waitqueue_head(&dev->read_wait);
- init_waitqueue_head(&dev->write_wait);
-
- iface_desc = intf->cur_altsetting;
-
- /* set up the endpoint information */
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(endpoint))
- dev->interrupt_in_endpoint = endpoint;
-
- if (usb_endpoint_is_int_out(endpoint))
- dev->interrupt_out_endpoint = endpoint;
- }
- if (dev->interrupt_in_endpoint == NULL) {
- dev_err(&intf->dev, "Interrupt in endpoint not found\n");
- goto error;
- }
- if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev,
- "Interrupt out endpoint not found (using control endpoint instead)\n");
-
- dev->interrupt_in_endpoint_size =
- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
-
- if (dev->interrupt_in_endpoint_size != 64)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
-
- if (ring_buffer_size == 0)
- ring_buffer_size = RING_BUFFER_SIZE;
-
- true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
-
- /*
- * FIXME - there are more usb_alloc routines for dma correctness.
- * Needed?
- */
- dev->ring_buffer = kmalloc_array(true_size,
- sizeof(struct alphatrack_icmd),
- GFP_KERNEL);
- if (!dev->ring_buffer)
- goto error;
-
- dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size,
- GFP_KERNEL);
- if (!dev->interrupt_in_buffer)
- goto error;
-
- dev->oldi_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
- if (!dev->oldi_buffer)
- goto error;
-
- dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->interrupt_in_urb) {
- dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
- goto error;
- }
-
- dev->interrupt_out_endpoint_size =
- dev->interrupt_out_endpoint ? le16_to_cpu(dev->
- interrupt_out_endpoint->
- wMaxPacketSize) : udev->
- descriptor.bMaxPacketSize0;
-
- if (dev->interrupt_out_endpoint_size != 64)
- dev_warn(&intf->dev,
- "Interrupt out endpoint size is not 64!)\n");
-
- if (write_buffer_size == 0)
- write_buffer_size = WRITE_BUFFER_SIZE;
- true_size = min(write_buffer_size, WRITE_BUFFER_SIZE);
-
- dev->interrupt_out_buffer =
- kmalloc_array(true_size,
- dev->interrupt_out_endpoint_size,
- GFP_KERNEL);
- if (!dev->interrupt_out_buffer)
- goto error;
-
- dev->write_buffer = kmalloc_array(true_size,
- sizeof(struct alphatrack_ocmd),
- GFP_KERNEL);
- if (!dev->write_buffer)
- goto error;
-
- dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->interrupt_out_urb) {
- dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
- goto error;
- }
- dev->interrupt_in_interval =
- min_interrupt_in_interval >
- dev->interrupt_in_endpoint->
- bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->
- bInterval;
- if (dev->interrupt_out_endpoint)
- dev->interrupt_out_interval =
- min_interrupt_out_interval >
- dev->interrupt_out_endpoint->
- bInterval ? min_interrupt_out_interval : dev->
- interrupt_out_endpoint->bInterval;
-
- /* we can register the device now, as it is ready */
- usb_set_intfdata(intf, dev);
-
- atomic_set(&dev->writes_pending, 0);
- retval = usb_register_dev(intf, &usb_alphatrack_class);
- if (retval) {
- /* something prevented us from registering this driver */
- dev_err(&intf->dev,
- "Not able to get a minor for this device.\n");
- usb_set_intfdata(intf, NULL);
- goto error;
- }
-
- /* let the user know what node this device is now attached to */
- dev_info(&intf->dev,
- "Alphatrack Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR,
- intf->minor);
-
-exit:
- return retval;
-
-error:
- usb_alphatrack_delete(dev);
-
- return retval;
-}
-
-/**
- * usb_alphatrack_disconnect
- *
- * Called by the usb core when the device is removed from the system.
- */
-static void usb_alphatrack_disconnect(struct usb_interface *intf)
-{
- struct usb_alphatrack *dev;
- int minor;
-
- mutex_lock(&disconnect_mutex);
-
- dev = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
-
- mutex_lock(&dev->mtx);
-
- minor = intf->minor;
-
- /* give back our minor */
- usb_deregister_dev(intf, &usb_alphatrack_class);
-
- /* if the device is not opened, then we clean up right now */
- if (!dev->open_count) {
- mutex_unlock(&dev->mtx);
- usb_alphatrack_delete(dev);
- } else {
- atomic_set(&dev->writes_pending, 0);
- dev->intf = NULL;
- mutex_unlock(&dev->mtx);
- }
-
- mutex_unlock(&disconnect_mutex);
-
- dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
- (minor - USB_ALPHATRACK_MINOR_BASE));
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver usb_alphatrack_driver = {
- .name = "alphatrack",
- .probe = usb_alphatrack_probe,
- .disconnect = usb_alphatrack_disconnect,
- .id_table = usb_alphatrack_table,
-};
-
-module_usb_driver(usb_alphatrack_driver);
diff --git a/drivers/staging/frontier/alphatrack.h b/drivers/staging/frontier/alphatrack.h
deleted file mode 100644
index 418c6053c027..000000000000
--- a/drivers/staging/frontier/alphatrack.h
+++ /dev/null
@@ -1,78 +0,0 @@
-struct alphatrack_icmd {
- unsigned char cmd[12];
-};
-
-struct alphatrack_ocmd {
- unsigned char cmd[8];
-};
-
-/*
- * These are unused by the present driver but provide documentation for the
- * userspace API.
- */
-enum LightID {
- LIGHT_EQ = 0,
- LIGHT_OUT,
- LIGHT_F2,
- LIGHT_SEND,
- LIGHT_IN,
- LIGHT_F1,
- LIGHT_PAN,
- LIGHT_UNDEF1,
- LIGHT_UNDEF2,
- LIGHT_SHIFT,
- LIGHT_TRACKMUTE,
- LIGHT_TRACKSOLO,
- LIGHT_TRACKREC,
- LIGHT_READ,
- LIGHT_WRITE,
- LIGHT_ANYSOLO,
- LIGHT_AUTO,
- LIGHT_F4,
- LIGHT_RECORD,
- LIGHT_WINDOW,
- LIGHT_PLUGIN,
- LIGHT_F3,
- LIGHT_LOOP
-};
-
-#define BUTTONMASK_BATTERY 0x00004000
-#define BUTTONMASK_BACKLIGHT 0x00008000
-#define BUTTONMASK_FASTFORWARD 0x04000000
-#define BUTTONMASK_TRACKMUTE 0x00040000
-#define BUTTONMASK_TRACKSOLO 0x00800000
-#define BUTTONMASK_TRACKLEFT 0x80000000
-#define BUTTONMASK_RECORD 0x02000000
-#define BUTTONMASK_SHIFT 0x20000000
-#define BUTTONMASK_PUNCH 0x00800000
-#define BUTTONMASK_TRACKRIGHT 0x00020000
-#define BUTTONMASK_REWIND 0x01000000
-#define BUTTONMASK_STOP 0x10000000
-#define BUTTONMASK_LOOP 0x00010000
-#define BUTTONMASK_TRACKREC 0x00001000
-#define BUTTONMASK_PLAY 0x08000000
-#define BUTTONMASK_TOUCH1 0x00000008
-#define BUTTONMASK_TOUCH2 0x00000010
-#define BUTTONMASK_TOUCH3 0x00000020
-
-#define BUTTONMASK_PRESS1 0x00000009
-#define BUTTONMASK_PRESS2 0x00008010
-#define BUTTONMASK_PRESS3 0x00002020
-
-/*
- * last 3 bytes are the slider position
- * 40 is the actual slider moving, the most sig bits, and 3 lsb
- */
-
-#define BUTTONMASK_FLIP 0x40000000
-#define BUTTONMASK_F1 0x00100000
-#define BUTTONMASK_F2 0x00400000
-#define BUTTONMASK_F3 0x00200000
-#define BUTTONMASK_F4 0x00080000
-#define BUTTONMASK_PAN 0x00000200
-#define BUTTONMASK_SEND 0x00000800
-#define BUTTONMASK_EQ 0x00004000
-#define BUTTONMASK_PLUGIN 0x00000400
-#define BUTTONMASK_AUTO 0x00000100
-
-/* #define BUTTONMASK_FOOTSWITCH FIXME */
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
deleted file mode 100644
index 2f86163d7013..000000000000
--- a/drivers/staging/frontier/tranzport.c
+++ /dev/null
@@ -1,973 +0,0 @@
-/*
- * Frontier Designs Tranzport driver
- *
- * Copyright (C) 2007 Michael Taht (m@taht.net)
- *
- * Based on the usbled driver and ldusb drivers by
- *
- * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de>
- *
- * The ldusb driver was, in turn, derived from Lego USB Tower driver
- * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net>
- * 2001-2004 Juergen Stuber <starblue@users.sourceforge.net>
- *
- * 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.
- *
- */
-
-/*
- * This driver uses a ring buffer for time critical reading of
- * interrupt in reports and provides read and write methods for
- * raw interrupt reports.
- */
-
-/* Note: this currently uses a dumb ringbuffer for reads and writes.
- * A more optimal driver would cache and kill off outstanding urbs that are
- * now invalid, and ignore ones that already were in the queue but valid
- * as we only have 17 commands for the tranzport. In particular this is
- * key for getting lights to flash in time as otherwise many commands
- * can be buffered up before the light change makes it to the interface.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <linux/uaccess.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/poll.h>
-
-/* Define these values to match your devices */
-#define VENDOR_ID 0x165b
-#define PRODUCT_ID 0x8101
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-#define USB_TRANZPORT_MINOR_BASE 0
-#else /* FIXME 177- is the another driver's minor - apply for a minor soon */
-#define USB_TRANZPORT_MINOR_BASE 177
-#endif
-
-/* table of devices that work with this driver */
-static const struct usb_device_id usb_tranzport_table[] = {
- {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, usb_tranzport_table);
-MODULE_VERSION("0.35");
-MODULE_AUTHOR("Mike Taht <m@taht.net>");
-MODULE_DESCRIPTION("Tranzport USB Driver");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("Frontier Designs Tranzport Control Surface");
-
-#define SUPPRESS_EXTRA_OFFLINE_EVENTS 1
-#define COMPRESS_WHEEL_EVENTS 1
-#define BUFFERED_READS 1
-#define RING_BUFFER_SIZE 1000
-#define WRITE_BUFFER_SIZE 34
-#define TRANZPORT_USB_TIMEOUT 10
-#define TRANZPORT_DEBUG 0
-
-static int debug = TRANZPORT_DEBUG;
-
-/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do \
- { if (debug) dev_info(dev , format , ## arg); } while (0)
-
-/* Module parameters */
-
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-/*
- * All interrupt in transfers are collected in a ring buffer to
- * avoid racing conditions and get better performance of the driver.
- */
-
-static int ring_buffer_size = RING_BUFFER_SIZE;
-
-module_param(ring_buffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
-
-/*
- * The write_buffer can one day contain more than one interrupt out transfer.
- */
-static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
-
-/*
- * Increase the interval for debugging purposes.
- * or set to 1 to use the standard interval from the endpoint descriptors.
- */
-
-static int min_interrupt_in_interval = TRANZPORT_USB_TIMEOUT;
-module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval,
- "Minimum interrupt in interval in ms");
-
-static int min_interrupt_out_interval = TRANZPORT_USB_TIMEOUT;
-module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval,
- "Minimum interrupt out interval in ms");
-
-struct tranzport_cmd {
- unsigned char cmd[8];
-};
-
-/* Structure to hold all of our device specific stuff */
-
-struct usb_tranzport {
- struct mutex mtx; /* locks this structure */
- struct usb_interface *intf; /* save off the usb interface pointer */
- int open_count; /* number of times this port opened */
- struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE];
- unsigned int ring_head;
- unsigned int ring_tail;
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
- unsigned char *interrupt_in_buffer;
- struct usb_endpoint_descriptor *interrupt_in_endpoint;
- struct urb *interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
- char *interrupt_out_buffer;
- struct usb_endpoint_descriptor *interrupt_out_endpoint;
- struct urb *interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
-
- /* Sysfs support */
-
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char compress_wheel; /* flag to compress wheel events */
-};
-
-/* prevent races between open() and disconnect() */
-static DEFINE_MUTEX(disconnect_mutex);
-
-static struct usb_driver usb_tranzport_driver;
-
-/**
- * usb_tranzport_abort_transfers
- * aborts transfers and frees associated data structures
- */
-static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
-{
- /* shutdown transfer */
- if (dev->interrupt_in_running) {
- dev->interrupt_in_running = 0;
- if (dev->intf)
- usb_kill_urb(dev->interrupt_in_urb);
- }
- if (dev->interrupt_out_busy)
- if (dev->intf)
- usb_kill_urb(dev->interrupt_out_urb);
-}
-
-#define show_int(value) \
- static ssize_t value##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
- { \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%d\n", t->value); \
- } \
- static DEVICE_ATTR_RO(value)
-
-#define show_set_int(value) \
- static ssize_t value##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
- { \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%d\n", t->value); \
- } \
- static ssize_t value##_store(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
- { \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- unsigned long temp; \
- if (kstrtoul(buf, 10, &temp)) \
- return -EINVAL; \
- t->value = temp; \
- return count; \
- } \
- static DEVICE_ATTR_RW(value)
-
-show_int(enable);
-show_int(offline);
-show_set_int(compress_wheel);
-
-/**
- * usb_tranzport_delete
- */
-static void usb_tranzport_delete(struct usb_tranzport *dev)
-{
- usb_tranzport_abort_transfers(dev);
- if (dev->intf != NULL) {
- device_remove_file(&dev->intf->dev, &dev_attr_enable);
- device_remove_file(&dev->intf->dev, &dev_attr_offline);
- device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
- }
-
- /* free data structures */
- usb_free_urb(dev->interrupt_in_urb);
- usb_free_urb(dev->interrupt_out_urb);
- kfree(dev->ring_buffer);
- kfree(dev->interrupt_in_buffer);
- kfree(dev->interrupt_out_buffer);
- kfree(dev);
-}
-
-/**
- * usb_tranzport_interrupt_in_callback
- */
-
-static void usb_tranzport_interrupt_in_callback(struct urb *urb)
-{
- struct usb_tranzport *dev = urb->context;
- unsigned int next_ring_head;
- int retval = -1;
-
- if (urb->status) {
- if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
- goto exit;
- } else {
- dbg_info(&dev->intf->dev,
- "%s: nonzero status received: %d\n",
- __func__, urb->status);
- goto resubmit; /* maybe we can recover */
- }
- }
-
- if (urb->actual_length != 8) {
- dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent\n",
- urb->actual_length);
- } else {
- dbg_info(&dev->intf->dev,
- "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, dev->interrupt_in_buffer[0],
- dev->interrupt_in_buffer[1],
- dev->interrupt_in_buffer[2],
- dev->interrupt_in_buffer[3],
- dev->interrupt_in_buffer[4],
- dev->interrupt_in_buffer[5],
- dev->interrupt_in_buffer[6],
- dev->interrupt_in_buffer[7]);
-#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
- goto resubmit;
- if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
- dev->offline = 2;
- goto resubmit;
- }
-
- /* Always pass one offline event up the stack */
- if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
- dev->offline = 0;
- if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
- dev->offline = 1;
-
-#endif /* SUPPRESS_EXTRA_OFFLINE_EVENTS */
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
-
- next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
-
- if (next_ring_head != dev->ring_tail) {
- memcpy(&((*dev->ring_buffer)[dev->ring_head]),
- dev->interrupt_in_buffer, urb->actual_length);
- dev->ring_head = next_ring_head;
- retval = 0;
- memset(dev->interrupt_in_buffer, 0, urb->actual_length);
- } else {
- dev_warn(&dev->intf->dev,
- "Ring buffer overflow, %d bytes dropped\n",
- urb->actual_length);
- memset(dev->interrupt_in_buffer, 0, urb->actual_length);
- }
- }
-
-resubmit:
-/* resubmit if we're still running */
- if (dev->interrupt_in_running && dev->intf) {
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (retval)
- dev_err(&dev->intf->dev,
- "usb_submit_urb failed (%d)\n", retval);
- }
-
-exit:
- dev->interrupt_in_done = 1;
- wake_up_interruptible(&dev->read_wait);
-}
-
-/**
- * usb_tranzport_interrupt_out_callback
- */
-static void usb_tranzport_interrupt_out_callback(struct urb *urb)
-{
- struct usb_tranzport *dev = urb->context;
- /* sync/async unlink faults aren't errors */
- if (urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
- dbg_info(&dev->intf->dev,
- "%s - nonzero write interrupt status received: %d\n",
- __func__, urb->status);
-
- dev->interrupt_out_busy = 0;
- wake_up_interruptible(&dev->write_wait);
-}
-/**
- * usb_tranzport_open
- */
-static int usb_tranzport_open(struct inode *inode, struct file *file)
-{
- struct usb_tranzport *dev;
- int subminor;
- int retval = 0;
- struct usb_interface *interface;
-
- nonseekable_open(inode, file);
- subminor = iminor(inode);
-
- mutex_lock(&disconnect_mutex);
-
- interface = usb_find_interface(&usb_tranzport_driver, subminor);
-
- if (!interface) {
- pr_err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
- retval = -ENODEV;
- goto unlock_disconnect_exit;
- }
-
- dev = usb_get_intfdata(interface);
-
- if (!dev) {
- retval = -ENODEV;
- goto unlock_disconnect_exit;
- }
-
- /* lock this device */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto unlock_disconnect_exit;
- }
-
- /* allow opening only once */
- if (dev->open_count) {
- retval = -EBUSY;
- goto unlock_exit;
- }
- dev->open_count = 1;
-
- /* initialize in direction */
- dev->ring_head = 0;
- dev->ring_tail = 0;
- usb_fill_int_urb(dev->interrupt_in_urb,
- interface_to_usbdev(interface),
- usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->
- bEndpointAddress),
- dev->interrupt_in_buffer,
- dev->interrupt_in_endpoint_size,
- usb_tranzport_interrupt_in_callback, dev,
- dev->interrupt_in_interval);
-
- dev->interrupt_in_running = 1;
- dev->interrupt_in_done = 0;
- dev->enable = 1;
- dev->offline = 0;
- dev->compress_wheel = 1;
-
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
- if (retval) {
- dev_err(&interface->dev,
- "Couldn't submit interrupt_in_urb %d\n", retval);
- dev->interrupt_in_running = 0;
- dev->open_count = 0;
- goto unlock_exit;
- }
-
- /* save device in the file's private structure */
- file->private_data = dev;
-
-unlock_exit:
- mutex_unlock(&dev->mtx);
-
-unlock_disconnect_exit:
- mutex_unlock(&disconnect_mutex);
-
- return retval;
-}
-
-/**
- * usb_tranzport_release
- */
-static int usb_tranzport_release(struct inode *inode, struct file *file)
-{
- struct usb_tranzport *dev;
- int retval = 0;
-
- dev = file->private_data;
-
- if (dev == NULL) {
- retval = -ENODEV;
- goto exit;
- }
-
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- if (dev->open_count != 1) {
- retval = -ENODEV;
- goto unlock_exit;
- }
-
- if (dev->intf == NULL) {
- /* the device was unplugged before the file was released */
- mutex_unlock(&dev->mtx);
- /* unlock here as usb_tranzport_delete frees dev */
- usb_tranzport_delete(dev);
- retval = -ENODEV;
- goto exit;
- }
-
- /* wait until write transfer is finished */
- if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait,
- !dev->interrupt_out_busy,
- 2 * HZ);
- usb_tranzport_abort_transfers(dev);
- dev->open_count = 0;
-
-unlock_exit:
- mutex_unlock(&dev->mtx);
-
-exit:
- return retval;
-}
-
-/**
- * usb_tranzport_poll
- */
-static unsigned int usb_tranzport_poll(struct file *file, poll_table *wait)
-{
- struct usb_tranzport *dev;
- unsigned int mask = 0;
-
- dev = file->private_data;
- poll_wait(file, &dev->read_wait, wait);
- poll_wait(file, &dev->write_wait, wait);
- if (dev->ring_head != dev->ring_tail)
- mask |= POLLIN | POLLRDNORM;
- if (!dev->interrupt_out_busy)
- mask |= POLLOUT | POLLWRNORM;
- return mask;
-}
-/**
- * usb_tranzport_read
- */
-
-static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct usb_tranzport *dev;
- int retval = 0;
-#if BUFFERED_READS
- int c = 0;
-#endif
-#if COMPRESS_WHEEL_EVENTS
- signed char oldwheel;
- signed char newwheel;
- int cancompress = 1;
- int next_tail;
-#endif
-
- /* do I have such a thing as a null event? */
-
- dev = file->private_data;
-
- /* verify that we actually have some data to read */
- if (count == 0)
- goto exit;
-
- /* lock this object */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
- retval = -ENODEV;
- pr_err("%s: No device or device unplugged %d\n",
- __func__, retval);
- goto unlock_exit;
- }
-
- while (dev->ring_head == dev->ring_tail) {
-
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- /* tiny race - FIXME: make atomic? */
- /* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */
- dev->interrupt_in_done = 0;
- retval = wait_event_interruptible(dev->read_wait,
- dev->interrupt_in_done);
- if (retval < 0)
- goto unlock_exit;
- }
-
- dbg_info(&dev->intf->dev,
- "%s: copying to userspace: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__,
- (*dev->ring_buffer)[dev->ring_tail].cmd[0],
- (*dev->ring_buffer)[dev->ring_tail].cmd[1],
- (*dev->ring_buffer)[dev->ring_tail].cmd[2],
- (*dev->ring_buffer)[dev->ring_tail].cmd[3],
- (*dev->ring_buffer)[dev->ring_tail].cmd[4],
- (*dev->ring_buffer)[dev->ring_tail].cmd[5],
- (*dev->ring_buffer)[dev->ring_tail].cmd[6],
- (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
-#if BUFFERED_READS
- c = 0;
- while ((c < count) && (dev->ring_tail != dev->ring_head)) {
-
-#if COMPRESS_WHEEL_EVENTS
- next_tail = (dev->ring_tail+1) % ring_buffer_size;
- if (dev->compress_wheel)
- cancompress = 1;
- while (dev->ring_head != next_tail && cancompress == 1) {
- newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
- oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
- /* if both are wheel events, and
- * no buttons have changes (FIXME, do I have to check?),
- * and we are the same sign, we can compress +- 7F
- */
- dbg_info(&dev->intf->dev,
- "%s: trying to compress: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__,
- (*dev->ring_buffer)[dev->ring_tail].cmd[0],
- (*dev->ring_buffer)[dev->ring_tail].cmd[1],
- (*dev->ring_buffer)[dev->ring_tail].cmd[2],
- (*dev->ring_buffer)[dev->ring_tail].cmd[3],
- (*dev->ring_buffer)[dev->ring_tail].cmd[4],
- (*dev->ring_buffer)[dev->ring_tail].cmd[5],
- (*dev->ring_buffer)[dev->ring_tail].cmd[6],
- (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
- if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
- (*dev->ring_buffer)[next_tail].cmd[6] != 0) &&
- ((newwheel > 0 && oldwheel > 0) ||
- (newwheel < 0 && oldwheel < 0)) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[2] ==
- (*dev->ring_buffer)[next_tail].cmd[2]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[3] ==
- (*dev->ring_buffer)[next_tail].cmd[3]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[4] ==
- (*dev->ring_buffer)[next_tail].cmd[4]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[5] ==
- (*dev->ring_buffer)[next_tail].cmd[5])) {
- dbg_info(&dev->intf->dev,
- "%s: should compress: "
- "%02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__,
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[0],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[1],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[2],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[3],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[4],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[5],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[6],
- (*dev->ring_buffer)[dev->ring_tail].
- cmd[7]);
- newwheel += oldwheel;
- if (oldwheel > 0 && !(newwheel > 0)) {
- newwheel = 0x7f;
- cancompress = 0;
- }
- if (oldwheel < 0 && !(newwheel < 0)) {
- newwheel = 0x80;
- cancompress = 0;
- }
-
- (*dev->ring_buffer)[next_tail].cmd[6] =
- newwheel;
- dev->ring_tail = next_tail;
- next_tail =
- (dev->ring_tail + 1) % ring_buffer_size;
- } else {
- cancompress = 0;
- }
- }
-#endif /* COMPRESS_WHEEL_EVENTS */
- if (copy_to_user(
- &buffer[c],
- &(*dev->ring_buffer)[dev->ring_tail], 8)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
- dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
- c += 8;
- dbg_info(&dev->intf->dev,
- "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
- }
- retval = c;
-
-#else
-/* if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */
- retval = -EFAULT;
- goto unlock_exit;
-}
-
-dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
-dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
- __func__, dev->ring_head, dev->ring_tail);
-
-retval = 8;
-#endif /* BUFFERED_READS */
-
-unlock_exit:
-/* unlock the device */
-mutex_unlock(&dev->mtx);
-
-exit:
-return retval;
-}
-
-/**
- * usb_tranzport_write
- */
-static ssize_t usb_tranzport_write(struct file *file,
- const char __user *buffer, size_t count,
- loff_t *ppos)
-{
- struct usb_tranzport *dev;
- size_t bytes_to_write;
- int retval = 0;
-
- dev = file->private_data;
-
- /* verify that we actually have some data to write */
- if (count == 0)
- goto exit;
-
- /* lock this object */
- if (mutex_lock_interruptible(&dev->mtx)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
- retval = -ENODEV;
- pr_err("%s: No device or device unplugged %d\n",
- __func__, retval);
- goto unlock_exit;
- }
-
- /* wait until previous transfer is finished */
- if (dev->interrupt_out_busy) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- retval = wait_event_interruptible(dev->write_wait,
- !dev->interrupt_out_busy);
- if (retval < 0)
- goto unlock_exit;
- }
-
- /* write the data into interrupt_out_buffer from userspace */
- bytes_to_write = min(count,
- write_buffer_size *
- dev->interrupt_out_endpoint_size);
- if (bytes_to_write < count)
- dev_warn(&dev->intf->dev,
- "Write buffer overflow, %zd bytes dropped\n",
- count - bytes_to_write);
-
- dbg_info(&dev->intf->dev,
- "%s: count = %zd, bytes_to_write = %zd\n", __func__,
- count, bytes_to_write);
-
- if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
-
- if (dev->interrupt_out_endpoint == NULL) {
- dev_err(&dev->intf->dev, "Endpoint should not be null!\n");
- goto unlock_exit;
- }
-
- /* send off the urb */
- usb_fill_int_urb(dev->interrupt_out_urb,
- interface_to_usbdev(dev->intf),
- usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->
- bEndpointAddress),
- dev->interrupt_out_buffer, bytes_to_write,
- usb_tranzport_interrupt_out_callback, dev,
- dev->interrupt_out_interval);
-
- dev->interrupt_out_busy = 1;
- wmb();
-
- retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
- if (retval) {
- dev->interrupt_out_busy = 0;
- dev_err(&dev->intf->dev,
- "Couldn't submit interrupt_out_urb %d\n", retval);
- goto unlock_exit;
- }
- retval = bytes_to_write;
-
-unlock_exit:
- /* unlock the device */
- mutex_unlock(&dev->mtx);
-
-exit:
- return retval;
-}
-
-/* file operations needed when we register this driver */
-static const struct file_operations usb_tranzport_fops = {
- .owner = THIS_MODULE,
- .read = usb_tranzport_read,
- .write = usb_tranzport_write,
- .open = usb_tranzport_open,
- .release = usb_tranzport_release,
- .poll = usb_tranzport_poll,
- .llseek = no_llseek,
-};
-
-/*
- * usb class driver info in order to get a minor number from the usb core,
- * and to have the device registered with the driver core
- */
-static struct usb_class_driver usb_tranzport_class = {
- .name = "tranzport%d",
- .fops = &usb_tranzport_fops,
- .minor_base = USB_TRANZPORT_MINOR_BASE,
-};
-
-/**
- * usb_tranzport_probe
- *
- * Called by the usb core when a new device is connected that it thinks
- * this driver might be interested in.
- */
-static int usb_tranzport_probe(struct usb_interface *intf,
- const struct usb_device_id *id) {
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_tranzport *dev = NULL;
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int i;
- int true_size;
- int retval = -ENOMEM;
-
- /* allocate memory for our device state and initialize it */
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL)
- goto exit;
-
- mutex_init(&dev->mtx);
- dev->intf = intf;
- init_waitqueue_head(&dev->read_wait);
- init_waitqueue_head(&dev->write_wait);
-
- iface_desc = intf->cur_altsetting;
-
- /* set up the endpoint information */
- for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
- endpoint = &iface_desc->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(endpoint))
- dev->interrupt_in_endpoint = endpoint;
-
- if (usb_endpoint_is_int_out(endpoint))
- dev->interrupt_out_endpoint = endpoint;
- }
- if (dev->interrupt_in_endpoint == NULL) {
- dev_err(&intf->dev, "Interrupt in endpoint not found\n");
- goto error;
- }
- if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev,
- "Interrupt out endpoint not found (using control endpoint instead)\n");
-
- dev->interrupt_in_endpoint_size =
- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
-
- if (dev->interrupt_in_endpoint_size != 8)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
-
- if (ring_buffer_size == 0)
- ring_buffer_size = RING_BUFFER_SIZE;
- true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
-
- /*
- * FIXME - there are more usb_alloc routines for dma correctness.
- * Needed?
- */
-
- dev->ring_buffer =
- kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
- if (!dev->ring_buffer)
- goto error;
-
- dev->interrupt_in_buffer =
- kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
- if (!dev->interrupt_in_buffer)
- goto error;
-
- dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->interrupt_in_urb) {
- dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
- goto error;
- }
- dev->interrupt_out_endpoint_size =
- dev->interrupt_out_endpoint ?
- le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
- udev->descriptor.bMaxPacketSize0;
-
- if (dev->interrupt_out_endpoint_size != 8)
- dev_warn(&intf->dev,
- "Interrupt out endpoint size is not 8!)\n");
-
- dev->interrupt_out_buffer =
- kmalloc_array(write_buffer_size,
- dev->interrupt_out_endpoint_size, GFP_KERNEL);
- if (!dev->interrupt_out_buffer)
- goto error;
-
- dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->interrupt_out_urb) {
- dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
- goto error;
- }
- dev->interrupt_in_interval =
- min_interrupt_in_interval >
- dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval
- : dev->interrupt_in_endpoint->bInterval;
-
- if (dev->interrupt_out_endpoint) {
- dev->interrupt_out_interval =
- min_interrupt_out_interval >
- dev->interrupt_out_endpoint->bInterval ?
- min_interrupt_out_interval :
- dev->interrupt_out_endpoint->bInterval;
- }
-
- /* we can register the device now, as it is ready */
- usb_set_intfdata(intf, dev);
-
- retval = usb_register_dev(intf, &usb_tranzport_class);
- if (retval) {
- /* something prevented us from registering this driver */
- dev_err(&intf->dev,
- "Not able to get a minor for this device.\n");
- usb_set_intfdata(intf, NULL);
- goto error;
- }
-
- retval = device_create_file(&intf->dev, &dev_attr_compress_wheel);
- if (retval)
- goto error;
- retval = device_create_file(&intf->dev, &dev_attr_enable);
- if (retval)
- goto error;
- retval = device_create_file(&intf->dev, &dev_attr_offline);
- if (retval)
- goto error;
-
- /* let the user know what node this device is now attached to */
- dev_info(&intf->dev,
- "Tranzport Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR,
- intf->minor);
-
-exit:
- return retval;
-
-error:
- usb_tranzport_delete(dev);
- return retval;
-}
-
-/**
- * usb_tranzport_disconnect
- *
- * Called by the usb core when the device is removed from the system.
- */
-static void usb_tranzport_disconnect(struct usb_interface *intf)
-{
- struct usb_tranzport *dev;
- int minor;
-
- mutex_lock(&disconnect_mutex);
- dev = usb_get_intfdata(intf);
- usb_set_intfdata(intf, NULL);
- mutex_lock(&dev->mtx);
- minor = intf->minor;
- /* give back our minor */
- usb_deregister_dev(intf, &usb_tranzport_class);
-
- /* if the device is not opened, then we clean up right now */
- if (!dev->open_count) {
- mutex_unlock(&dev->mtx);
- usb_tranzport_delete(dev);
- } else {
- dev->intf = NULL;
- mutex_unlock(&dev->mtx);
- }
-
- mutex_unlock(&disconnect_mutex);
-
- dev_info(&intf->dev, "Tranzport Surface #%d now disconnected\n",
- (minor - USB_TRANZPORT_MINOR_BASE));
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver usb_tranzport_driver = {
- .name = "tranzport",
- .probe = usb_tranzport_probe,
- .disconnect = usb_tranzport_disconnect,
- .id_table = usb_tranzport_table,
-};
-
-module_usb_driver(usb_tranzport_driver);
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/Makefile b/drivers/staging/ft1000/ft1000-pcmcia/Makefile
index 660b7a50e891..715de3f00e33 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/Makefile
+++ b/drivers/staging/ft1000/ft1000-pcmcia/Makefile
@@ -1,3 +1,2 @@
obj-$(CONFIG_FT1000_PCMCIA) = ft1000_pcmcia.o
-ft1000_pcmcia-y := ft1000_hw.o ft1000_dnld.o ft1000_proc.o ft1000_cs.o
-
+ft1000_pcmcia-y := ft1000_hw.o ft1000_dnld.o ft1000_cs.o
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h
index 0c21ac680038..1d52738fff49 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h
@@ -47,8 +47,6 @@ extern struct net_device *init_ft1000_card(struct pcmcia_device *link,
extern void stop_ft1000_card(struct net_device *dev);
extern int card_download(struct net_device *dev, const u8 *pFileStart,
size_t FileLength);
-extern void ft1000InitProc(struct net_device *dev);
-extern void ft1000CleanupProc(struct net_device *dev);
extern u16 ft1000_read_dpram(struct net_device *dev, int offset);
extern void card_bootload(struct net_device *dev);
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
index d44e8583ad1e..afaab07862fb 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
@@ -15,8 +15,8 @@
Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------
- Description: This module will handshake with the DSP bootloader to
- download the DSP runtime image.
+ Description: This module will handshake with the DSP bootloader to
+ download the DSP runtime image.
---------------------------------------------------------------------------*/
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
index a6158bef58e5..21f09fe168e9 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
@@ -19,8 +19,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/proc_fs.h>
-
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
@@ -2102,7 +2100,6 @@ void stop_ft1000_card(struct net_device *dev)
release_region(dev->base_addr,256);
release_firmware(fw_entry);
flarion_ft1000_cnt--;
- ft1000CleanupProc(dev);
}
@@ -2247,7 +2244,6 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link,
ft1000_enable_interrupts(dev);
- ft1000InitProc(dev);
ft1000_card_present = 1;
dev->ethtool_ops = &ops;
printk(KERN_INFO "ft1000: %s: addr 0x%04lx irq %d, MAC addr %pM\n",
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
deleted file mode 100644
index 88f6f9ce304a..000000000000
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*---------------------------------------------------------------------------
- FT1000 driver for Flarion Flash OFDM NIC Device
-
- Copyright (C) 2006 Patrik Ostrihon, All rights reserved.
- Copyright (C) 2006 ProWeb Consulting, a.s, 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. 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., 59 Temple Place -
- Suite 330, Boston, MA 02111-1307, USA.
------------------------------------------------------------------------------*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-#include <linux/netdevice.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include "ft1000.h"
-
-#define FT1000_PROC "ft1000"
-#define MAX_FILE_LEN 255
-
-#define seq_putx(m, message, size, var) \
- seq_printf(m, message); \
- for (i = 0; i < (size - 1); i++) { \
- seq_printf(m, "%02x:", var[i]); \
- } \
- seq_printf(m, "%02x\n", var[i])
-
-#define seq_putd(m, message, size, var) \
- seq_printf(m, message); \
- for (i = 0; i < (size - 1); i++) { \
- seq_printf(m, "%d.", var[i]); \
- } \
- seq_printf(m, "%d\n", var[i])
-
-static int ft1000ReadProc(struct seq_file *m, void *v)
-{
- static const char *status[] = {
- "Idle (Disconnect)", "Searching", "Active (Connected)",
- "Waiting for L2", "Sleep", "No Coverage", "", ""
- };
- static const char *signal[] = { "", "*", "**", "***", "****" };
-
- struct net_device *dev = m->private;
- struct ft1000_info *info = netdev_priv(dev);
- int i;
- int strength;
- int quality;
- struct timeval tv;
- time_t delta;
-
- if (info->AsicID == ELECTRABUZZ_ID) {
- if (info->ProgConStat != 0xFF) {
- info->LedStat =
- ft1000_read_dpram(dev, FT1000_DSP_LED);
- info->ConStat =
- ft1000_read_dpram(dev, FT1000_DSP_CON_STATE);
- } else {
- info->ConStat = 0xf;
- }
- } else {
- if (info->ProgConStat != 0xFF) {
- info->LedStat =
- ntohs(ft1000_read_dpram_mag_16(
- dev, FT1000_MAG_DSP_LED,
- FT1000_MAG_DSP_LED_INDX));
- info->ConStat =
- ntohs(ft1000_read_dpram_mag_16(
- dev, FT1000_MAG_DSP_CON_STATE,
- FT1000_MAG_DSP_CON_STATE_INDX));
- } else {
- info->ConStat = 0xf;
- }
- }
-
- i = (info->LedStat) & 0xf;
- switch (i) {
- case 0x1:
- strength = 1;
- break;
- case 0x3:
- strength = 2;
- break;
- case 0x7:
- strength = 3;
- break;
- case 0xf:
- strength = 4;
- break;
- default:
- strength = 0;
- }
-
- i = (info->LedStat >> 8) & 0xf;
- switch (i) {
- case 0x1:
- quality = 1;
- break;
- case 0x3:
- quality = 2;
- break;
- case 0x7:
- quality = 3;
- break;
- case 0xf:
- quality = 4;
- break;
- default:
- quality = 0;
- }
-
- do_gettimeofday(&tv);
- delta = tv.tv_sec - info->ConTm;
- seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
- ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
- seq_printf(m, "Connection Time[s]: %ld\n", delta);
- seq_printf(m, "Asic ID: %s\n",
- info->AsicID ==
- ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
- seq_putx(m, "SKU: ", SKUSZ, info->Sku);
- seq_putx(m, "EUI64: ", EUISZ, info->eui64);
- seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
- seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum);
- seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer);
- seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate);
- seq_printf(m, "Media State: %s\n",
- (info->mediastate) ? "link" : "no link");
- seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]);
- seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets);
- seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets);
- seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes);
- seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes);
- seq_printf(m, "Signal Strength: %s\n", signal[strength]);
- seq_printf(m, "Signal Quality: %s\n", signal[quality]);
- return 0;
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int ft1000_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ft1000ReadProc, PDE_DATA(inode));
-}
-
-static const struct file_operations ft1000_proc_fops = {
- .open = ft1000_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int ft1000NotifyProc(struct notifier_block *this, unsigned long event,
- void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct ft1000_info *info;
-
- info = netdev_priv(dev);
-
- switch (event) {
- case NETDEV_CHANGENAME:
- remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
- proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
- &ft1000_proc_fops, dev);
- snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
- break;
- }
- return NOTIFY_DONE;
-}
-
-static struct notifier_block ft1000_netdev_notifier = {
- .notifier_call = ft1000NotifyProc
-};
-
-void ft1000InitProc(struct net_device *dev)
-{
- struct ft1000_info *info;
-
- info = netdev_priv(dev);
-
- info->ft1000_proc_dir = proc_mkdir(FT1000_PROC, init_net.proc_net);
-
- proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
- &ft1000_proc_fops, dev);
-
- snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
- register_netdevice_notifier(&ft1000_netdev_notifier);
-}
-
-void ft1000CleanupProc(struct net_device *dev)
-{
- struct ft1000_info *info;
-
- info = netdev_priv(dev);
-
- remove_proc_entry(dev->name, info->ft1000_proc_dir);
- remove_proc_entry(FT1000_PROC, init_net.proc_net);
- unregister_netdevice_notifier(&ft1000_netdev_notifier);
-}
diff --git a/drivers/staging/ft1000/ft1000-usb/Makefile b/drivers/staging/ft1000/ft1000-usb/Makefile
index f0f524015888..7c4b78456254 100644
--- a/drivers/staging/ft1000/ft1000-usb/Makefile
+++ b/drivers/staging/ft1000/ft1000-usb/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_FT1000_USB) += ft1000.o
-ft1000-y := ft1000_debug.o ft1000_download.o ft1000_hw.o ft1000_proc.o ft1000_usb.o
+ft1000-y := ft1000_debug.o ft1000_download.o ft1000_hw.o ft1000_usb.o
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
index a8945b785967..9f4c7858a059 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
@@ -482,14 +482,14 @@ static long ft1000_ioctl(struct file *file, unsigned int command,
/* Connect Message */
DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n");
ConnectionMsg[79] = 0xfc;
- card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
+ result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
break;
case IOCTL_DISCONNECT:
/* Disconnect Message */
DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n");
ConnectionMsg[79] = 0xfd;
- card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
+ result = card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
break;
case IOCTL_GET_DSP_STAT_CMD:
/* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */
@@ -652,7 +652,7 @@ static long ft1000_ioctl(struct file *file, unsigned int command,
}
pmsg++;
ppseudo_hdr = (struct pseudo_hdr *)pmsg;
- card_send_command(ft1000dev,(unsigned short*)dpram_data,total_len+2);
+ result = card_send_command(ft1000dev,(unsigned short*)dpram_data,total_len+2);
ft1000dev->app_info[app_index].nTxMsg++;
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
index b6a77088cfe4..7012e09a1599 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
@@ -322,18 +322,23 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value)
* ptempbuffer - command buffer
* size - command buffer size
*/
-void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
+int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
int size)
{
+ int ret;
unsigned short temp;
unsigned char *commandbuf;
DEBUG("card_send_command: enter card_send_command... size=%d\n", size);
commandbuf = kmalloc(size + 2, GFP_KERNEL);
+ if (!commandbuf)
+ return -ENOMEM;
memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
- ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
+ ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
+ if (ret)
+ return ret;
if (temp & 0x0100)
usleep_range(900, 1100);
@@ -345,19 +350,23 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
if (size % 4)
size += 4 - (size % 4);
- ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
+ ret = ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
+ if (ret)
+ return ret;
usleep_range(900, 1100);
- ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
+ ret = ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
FT1000_REG_DOORBELL);
+ if (ret)
+ return ret;
usleep_range(900, 1100);
- ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
+ ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
#if 0
if ((temp & 0x0100) == 0)
DEBUG("card_send_command: Message sent\n");
#endif
-
+ return ret;
}
/* load or reload the DSP */
@@ -1375,8 +1384,10 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size)
*pmsg++ = convert.wrd;
*pmsg++ = htons(info->DrvErrNum);
- card_send_command(dev, (unsigned char *)&tempbuffer[0],
+ status = card_send_command(dev, (unsigned char *)&tempbuffer[0],
(u16)(0x0012 + PSEUDOSZ));
+ if (status)
+ goto out;
info->DrvErrNum = 0;
}
dev->DrvMsgPend = 0;
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
deleted file mode 100644
index e89b5d2c8e62..000000000000
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * ft1000_proc.c - ft1000 proc interface
- *
- * Copyright (C) 2009-2010 Quintec
- * (C) 2010 Open-nandra
- * <marek.belisko@open-nandra.com>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file "COPYING" in the main directory of this
- * archive for more details.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/netdevice.h>
-
-
-#include "ft1000_usb.h"
-
-#define FT1000_PROC_DIR "ft1000"
-
-
-#define seq_putx(m, message, size, var) \
- do { \
- seq_printf(m, message); \
- for (i = 0; i < (size - 1); i++) \
- seq_printf(m, "%02x:", var[i]); \
- seq_printf(m, "%02x\n", var[i]); \
- } while (0)
-
-#define seq_putd(m, message, size, var) \
- do { \
- seq_printf(m, message); \
- for (i = 0; i < (size - 1); i++) \
- seq_printf(m, "%d.", var[i]); \
- seq_printf(m, "%d\n", var[i]); \
- } while (0)
-
-#define FTNET_PROC init_net.proc_net
-
-
-int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx,
- u8 *buffer, u8 highlow);
-
-
-static int ft1000ReadProc(struct seq_file *m, void *v)
-{
- static const char *status[] = {
- "Idle (Disconnect)",
- "Searching",
- "Active (Connected)",
- "Waiting for L2",
- "Sleep",
- "No Coverage",
- "",
- "",
- };
- static const char *signal[] = { "", "*", "**", "***", "****" };
-
- struct net_device *dev = m->private;
- struct ft1000_info *info = netdev_priv(dev);
- int i;
- unsigned short ledStat;
- unsigned short conStat;
- int strength;
- int quality;
- struct timeval tv;
- time_t delta;
-
- if (info->ProgConStat != 0xFF) {
- ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_LED,
- (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX);
- info->LedStat = ntohs(ledStat);
-
- ft1000_read_dpram16(info->priv, FT1000_MAG_DSP_CON_STATE,
- (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
- info->ConStat = ntohs(conStat);
- do_gettimeofday(&tv);
- delta = (tv.tv_sec - info->ConTm);
- } else {
- info->ConStat = 0xf;
- delta = 0;
- }
-
- i = (info->LedStat) & 0xf;
- switch (i) {
- case 0x1:
- strength = 1;
- break;
- case 0x3:
- strength = 2;
- break;
- case 0x7:
- strength = 3;
- break;
- case 0xf:
- strength = 4;
- break;
- default:
- strength = 0;
- }
-
- i = (info->LedStat >> 8) & 0xf;
- switch (i) {
- case 0x1:
- quality = 1;
- break;
- case 0x3:
- quality = 2;
- break;
- case 0x7:
- quality = 3;
- break;
- case 0xf:
- quality = 4;
- break;
- default:
- quality = 0;
- }
-
- seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n",
- ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60));
- seq_printf(m, "Connection Time[s]: %ld\n", delta);
- seq_printf(m, "Asic ID: %s\n",
- (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC");
- seq_putx(m, "SKU: ", SKUSZ, info->Sku);
- seq_putx(m, "EUI64: ", EUISZ, info->eui64);
- seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer);
- seq_putx(m, "Hardware Serial Number: ", HWSERNUMSZ, info->HwSerNum);
- seq_putx(m, "Caliberation Version: ", CALVERSZ, info->RfCalVer);
- seq_putd(m, "Caliberation Date: ", CALDATESZ, info->RfCalDate);
- seq_printf(m, "Media State: %s\n", (info->mediastate) ? "link" : "no link");
- seq_printf(m, "Connection Status: %s\n", status[info->ConStat & 0x7]);
- seq_printf(m, "RX packets: %ld\n", info->stats.rx_packets);
- seq_printf(m, "TX packets: %ld\n", info->stats.tx_packets);
- seq_printf(m, "RX bytes: %ld\n", info->stats.rx_bytes);
- seq_printf(m, "TX bytes: %ld\n", info->stats.tx_bytes);
- seq_printf(m, "Signal Strength: %s\n", signal[strength]);
- seq_printf(m, "Signal Quality: %s\n", signal[quality]);
- return 0;
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int ft1000_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ft1000ReadProc, PDE_DATA(inode));
-}
-
-static const struct file_operations ft1000_proc_fops = {
- .open = ft1000_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int
-ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- struct ft1000_info *info;
- struct proc_dir_entry *ft1000_proc_file;
-
- info = netdev_priv(dev);
-
- switch (event) {
- case NETDEV_CHANGENAME:
- remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
- ft1000_proc_file =
- proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
- &ft1000_proc_fops, dev);
- snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block ft1000_netdev_notifier = {
- .notifier_call = ft1000NotifyProc,
-};
-
-
-int ft1000_init_proc(struct net_device *dev)
-{
- struct ft1000_info *info;
- struct proc_dir_entry *ft1000_proc_file;
- int ret = -EINVAL;
-
- info = netdev_priv(dev);
-
- info->ft1000_proc_dir = proc_mkdir(FT1000_PROC_DIR, FTNET_PROC);
- if (info->ft1000_proc_dir == NULL) {
- netdev_warn(dev, "Unable to create %s dir.\n",
- FT1000_PROC_DIR);
- goto fail;
- }
-
- ft1000_proc_file =
- proc_create_data(dev->name, 0644, info->ft1000_proc_dir,
- &ft1000_proc_fops, dev);
-
- if (!ft1000_proc_file) {
- netdev_warn(dev, "Unable to create /proc entry.\n");
- goto fail_entry;
- }
-
- snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name);
-
- ret = register_netdevice_notifier(&ft1000_netdev_notifier);
- if (ret)
- goto fail_notif;
-
- return 0;
-
-fail_notif:
- remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
-fail_entry:
- remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC);
-fail:
- return ret;
-}
-
-void ft1000_cleanup_proc(struct ft1000_info *info)
-{
- remove_proc_entry(info->netdevname, info->ft1000_proc_dir);
- remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC);
- unregister_netdevice_notifier(&ft1000_netdev_notifier);
-}
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
index 0a2544c78292..cc740c96845d 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
@@ -196,17 +196,10 @@ static int ft1000_probe(struct usb_interface *interface,
if (ret)
goto err_thread;
- ret = ft1000_init_proc(ft1000dev->net);
- if (ret)
- goto err_proc;
-
ft1000dev->NetDevRegDone = 1;
return 0;
-err_proc:
- unregister_netdev(ft1000dev->net);
- free_netdev(ft1000dev->net);
err_thread:
kthread_stop(ft1000dev->pPollThread);
err_load:
@@ -230,7 +223,6 @@ static void ft1000_disconnect(struct usb_interface *interface)
if (pft1000info) {
ft1000dev = pft1000info->priv;
- ft1000_cleanup_proc(pft1000info);
if (ft1000dev->pPollThread)
kthread_stop(ft1000dev->pPollThread);
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
index 2d4b02e2382d..8f7ccae57f31 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
@@ -136,7 +136,7 @@ extern spinlock_t free_buff_lock;
int ft1000_create_dev(struct ft1000_usb *dev);
void ft1000_destroy_dev(struct net_device *dev);
-extern void card_send_command(struct ft1000_usb *ft1000dev,
+extern int card_send_command(struct ft1000_usb *ft1000dev,
void *ptempbuffer, int size);
struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist);
@@ -149,7 +149,4 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev,
struct usb_interface *intf);
int ft1000_poll(void *dev_id);
-int ft1000_init_proc(struct net_device *dev);
-void ft1000_cleanup_proc(struct ft1000_info *info);
-
#endif /* _FT1000_USB_H_ */
diff --git a/drivers/staging/ft1000/ft1000.h b/drivers/staging/ft1000/ft1000.h
index db57430f3b94..8a2e4caa532d 100644
--- a/drivers/staging/ft1000/ft1000.h
+++ b/drivers/staging/ft1000/ft1000.h
@@ -363,6 +363,4 @@ struct ft1000_info {
u16 Rec[MAX_DSP_SESS_REC];
u32 MagRec[MAX_DSP_SESS_REC/2];
} DSPSess;
- struct proc_dir_entry *ft1000_proc_dir;
- char netdevname[IFNAMSIZ];
};
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c
index 384758b11e3c..af0c3878358c 100644
--- a/drivers/staging/fwserial/fwserial.c
+++ b/drivers/staging/fwserial/fwserial.c
@@ -785,6 +785,7 @@ static int fwtty_tx(struct fwtty_port *port, bool drain)
len = dma_fifo_out_level(&port->tx_fifo);
if (len) {
unsigned long delay = (n == -ENOMEM) ? HZ : 1;
+
schedule_delayed_work(&port->drain, delay);
}
len = dma_fifo_level(&port->tx_fifo);
@@ -1995,6 +1996,7 @@ static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card,
list_for_each_entry_rcu(peer, &serial->peer_list, list) {
int g = peer->generation;
+
smp_rmb();
if (generation == g && id == peer->node_id)
return peer;
@@ -2015,6 +2017,7 @@ static void __dump_peer_list(struct fw_card *card)
list_for_each_entry_rcu(peer, &serial->peer_list, list) {
int g = peer->generation;
+
smp_rmb();
fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n",
g, peer->node_id, (unsigned long long) peer->guid);
@@ -2120,6 +2123,7 @@ static int fwserial_add_peer(struct fw_serial *serial, struct fw_unit *unit)
serial->self = peer;
if (create_loop_dev) {
struct fwtty_port *port;
+
port = fwserial_claim_port(peer, num_ttys);
if (!IS_ERR(port)) {
struct virt_plug_params params;
@@ -2611,7 +2615,6 @@ cleanup:
if (port)
fwserial_release_port(port, false);
kfree(pkt);
- return;
}
static void fwserial_handle_unplug_req(struct work_struct *work)
@@ -2663,7 +2666,6 @@ cleanup:
if (port)
fwserial_release_port(port, true);
kfree(pkt);
- return;
}
static int fwserial_parse_mgmt_write(struct fwtty_peer *peer,
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index 64c55b99fda4..c657639f884b 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -447,6 +447,7 @@ static int gdm_lte_tx(struct sk_buff *skb, struct net_device *dev)
*/
if (nic_type & NIC_TYPE_F_VLAN) {
struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data;
+
nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK;
data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN);
data_len = skb->len - (VLAN_ETH_HLEN - ETH_HLEN);
@@ -505,6 +506,7 @@ static int gdm_lte_tx(struct sk_buff *skb, struct net_device *dev)
static struct net_device_stats *gdm_lte_stats(struct net_device *dev)
{
struct nic *nic = netdev_priv(dev);
+
return &nic->stats;
}
@@ -885,7 +887,7 @@ int register_lte_device(struct phy_dev *phy_dev,
/* Allocate netdev */
net = alloc_netdev(sizeof(struct nic), pdn_dev_name,
- ether_setup);
+ NET_NAME_UNKNOWN, ether_setup);
if (net == NULL) {
pr_err("alloc_netdev failed\n");
ret = -ENOMEM;
diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c
index fe47cd3eb2ed..001348ccacf9 100644
--- a/drivers/staging/gdm724x/gdm_tty.c
+++ b/drivers/staging/gdm724x/gdm_tty.c
@@ -111,24 +111,28 @@ static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
static int gdm_tty_open(struct tty_struct *tty, struct file *filp)
{
struct gdm *gdm = tty->driver_data;
+
return tty_port_open(&gdm->port, tty, filp);
}
static void gdm_tty_cleanup(struct tty_struct *tty)
{
struct gdm *gdm = tty->driver_data;
+
tty_port_put(&gdm->port);
}
static void gdm_tty_hangup(struct tty_struct *tty)
{
struct gdm *gdm = tty->driver_data;
+
tty_port_hangup(&gdm->port);
}
static void gdm_tty_close(struct tty_struct *tty, struct file *filp)
{
struct gdm *gdm = tty->driver_data;
+
tty_port_close(&gdm->port, tty, filp);
}
@@ -139,6 +143,7 @@ static int gdm_tty_recv_complete(void *data,
int complete)
{
struct gdm *gdm = tty_dev->gdm[index];
+
if (!GDM_TTY_READY(gdm)) {
if (complete == RECV_PACKET_PROCESS_COMPLETE)
gdm_tty_recv(gdm, gdm_tty_recv_complete);
diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c
index ee6e40facca7..483185bb4ecf 100644
--- a/drivers/staging/gdm724x/gdm_usb.c
+++ b/drivers/staging/gdm724x/gdm_usb.c
@@ -125,11 +125,11 @@ static struct usb_tx_sdu *alloc_tx_sdu_struct(void)
{
struct usb_tx_sdu *t_sdu;
- t_sdu = kzalloc(sizeof(struct usb_tx_sdu), GFP_ATOMIC);
+ t_sdu = kzalloc(sizeof(struct usb_tx_sdu), GFP_KERNEL);
if (!t_sdu)
return NULL;
- t_sdu->buf = kmalloc(SDU_BUF_SIZE, GFP_ATOMIC);
+ t_sdu->buf = kmalloc(SDU_BUF_SIZE, GFP_KERNEL);
if (!t_sdu->buf) {
kfree(t_sdu);
return NULL;
@@ -183,14 +183,14 @@ static struct usb_rx *alloc_rx_struct(void)
struct usb_rx *r = NULL;
int ret = 0;
- r = kmalloc(sizeof(struct usb_rx), GFP_ATOMIC);
+ r = kmalloc(sizeof(struct usb_rx), GFP_KERNEL);
if (!r) {
ret = -ENOMEM;
goto out;
}
- r->urb = usb_alloc_urb(0, GFP_ATOMIC);
- r->buf = kmalloc(RX_BUF_SIZE, GFP_ATOMIC);
+ r->urb = usb_alloc_urb(0, GFP_KERNEL);
+ r->buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
if (!r->urb || !r->buf) {
ret = -ENOMEM;
goto out;
@@ -264,28 +264,25 @@ static void release_usb(struct lte_udev *udev)
unsigned long flags;
spin_lock_irqsave(&tx->lock, flags);
- list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->sdu_list, list)
- {
+ list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->sdu_list, list) {
list_del(&t_sdu->list);
free_tx_sdu_struct(t_sdu);
}
- list_for_each_entry_safe(t, t_next, &tx->hci_list, list)
- {
+ list_for_each_entry_safe(t, t_next, &tx->hci_list, list) {
list_del(&t->list);
free_tx_struct(t);
}
- list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->free_list, list)
- {
+ list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->free_list, list) {
list_del(&t_sdu->list);
free_tx_sdu_struct(t_sdu);
}
spin_unlock_irqrestore(&tx->lock, flags);
spin_lock_irqsave(&rx->submit_lock, flags);
- list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, rx_submit_list)
- {
+ list_for_each_entry_safe(r, r_next, &rx->rx_submit_list,
+ rx_submit_list) {
spin_unlock_irqrestore(&rx->submit_lock, flags);
usb_kill_urb(r->urb);
spin_lock_irqsave(&rx->submit_lock, flags);
@@ -293,16 +290,14 @@ static void release_usb(struct lte_udev *udev)
spin_unlock_irqrestore(&rx->submit_lock, flags);
spin_lock_irqsave(&rx->rx_lock, flags);
- list_for_each_entry_safe(r, r_next, &rx->free_list, free_list)
- {
+ list_for_each_entry_safe(r, r_next, &rx->free_list, free_list) {
list_del(&r->free_list);
free_rx_struct(r);
}
spin_unlock_irqrestore(&rx->rx_lock, flags);
spin_lock_irqsave(&rx->to_host_lock, flags);
- list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list)
- {
+ list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) {
if (r->index == (void *)udev) {
list_del(&r->to_host_list);
free_rx_struct(r);
@@ -366,6 +361,7 @@ static int init_usb(struct lte_udev *udev)
INIT_DELAYED_WORK(&udev->work_rx, do_rx);
return 0;
fail:
+ release_usb(udev);
return ret;
}
@@ -457,9 +453,8 @@ static void remove_rx_submit_list(struct usb_rx *r, struct rx_cxt *rx)
struct usb_rx *r_remove, *r_remove_next;
spin_lock_irqsave(&rx->submit_lock, flags);
- list_for_each_entry_safe(r_remove,
- r_remove_next, &rx->rx_submit_list, rx_submit_list)
- {
+ list_for_each_entry_safe(r_remove, r_remove_next,
+ &rx->rx_submit_list, rx_submit_list) {
if (r == r_remove) {
list_del(&r->rx_submit_list);
break;
@@ -895,6 +890,7 @@ static void gdm_usb_disconnect(struct usb_interface *intf)
struct lte_udev *udev;
u16 idVendor, idProduct;
struct usb_device *usbdev;
+
usbdev = interface_to_usbdev(intf);
idVendor = __le16_to_cpu(usbdev->descriptor.idVendor);
@@ -936,8 +932,8 @@ static int gdm_usb_suspend(struct usb_interface *intf, pm_message_t pm_msg)
udev->usb_state = PM_SUSPEND;
spin_lock_irqsave(&rx->submit_lock, flags);
- list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, rx_submit_list)
- {
+ list_for_each_entry_safe(r, r_next, &rx->rx_submit_list,
+ rx_submit_list) {
spin_unlock_irqrestore(&rx->submit_lock, flags);
usb_kill_urb(r->urb);
spin_lock_irqsave(&rx->submit_lock, flags);
diff --git a/drivers/staging/gdm724x/netlink_k.c b/drivers/staging/gdm724x/netlink_k.c
index 5ddd36948a2f..59a18304ef4a 100644
--- a/drivers/staging/gdm724x/netlink_k.c
+++ b/drivers/staging/gdm724x/netlink_k.c
@@ -54,7 +54,7 @@ static void netlink_rcv_cb(struct sk_buff *skb)
return;
}
- if (skb->len < NLMSG_SPACE(0)) {
+ if (skb->len < NLMSG_HDRLEN) {
pr_err("nl cb - invalid skb length\n");
return;
}
diff --git a/drivers/staging/gdm72xx/Kconfig b/drivers/staging/gdm72xx/Kconfig
index dd8a3913f6b9..5836503caa7b 100644
--- a/drivers/staging/gdm72xx/Kconfig
+++ b/drivers/staging/gdm72xx/Kconfig
@@ -6,21 +6,29 @@ menuconfig WIMAX_GDM72XX
tristate "GCT GDM72xx WiMAX support"
depends on NET && (USB || MMC)
help
- Support for the GCT GDM72xx WiMAX chip
+ Support a WiMAX module based on the GCT GDM72xx WiMAX chip.
if WIMAX_GDM72XX
config WIMAX_GDM72XX_QOS
bool "Enable QoS support"
default n
+ help
+ Enable Quality of Service support based on the data protocol of
+ transmitting packets.
config WIMAX_GDM72XX_K_MODE
bool "Enable K mode"
default n
+ help
+ Enable support for proprietary functions for KT (Korea Telecom).
config WIMAX_GDM72XX_WIMAX2
bool "Enable WiMAX2 support"
default n
+ help
+ Enable support for transmitting multiple packets (packet
+ aggregation) from the WiMAX module to the host processor.
choice
prompt "Select interface"
@@ -28,10 +36,16 @@ choice
config WIMAX_GDM72XX_USB
bool "USB interface"
depends on (USB = y || USB = WIMAX_GDM72XX)
+ help
+ Select this option if the WiMAX module interfaces with the host
+ processor via USB.
config WIMAX_GDM72XX_SDIO
bool "SDIO interface"
depends on (MMC = y || MMC = WIMAX_GDM72XX)
+ help
+ Select this option if the WiMAX module interfaces with the host
+ processor via SDIO.
endchoice
@@ -40,6 +54,9 @@ if WIMAX_GDM72XX_USB
config WIMAX_GDM72XX_USB_PM
bool "Enable power management support"
depends on PM_RUNTIME
+ help
+ Enable USB power management in order to reduce power consumption
+ while the interface is not in use.
endif # WIMAX_GDM72XX_USB
diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c
index df6f000534d4..af24c57b8232 100644
--- a/drivers/staging/gdm72xx/gdm_qos.c
+++ b/drivers/staging/gdm72xx/gdm_qos.c
@@ -24,8 +24,6 @@
#include "hci.h"
#include "gdm_qos.h"
-#define B2H(x) __be16_to_cpu(x)
-
#define MAX_FREE_LIST_CNT 32
static struct {
struct list_head head;
@@ -100,7 +98,7 @@ void gdm_qos_init(void *nic_ptr)
for (i = 0; i < QOS_MAX; i++) {
INIT_LIST_HEAD(&qcb->qos_list[i]);
qcb->csr[i].qos_buf_count = 0;
- qcb->csr[i].enabled = 0;
+ qcb->csr[i].enabled = false;
}
qcb->qos_list_cnt = 0;
@@ -127,7 +125,7 @@ void gdm_qos_release_list(void *nic_ptr)
for (i = 0; i < QOS_MAX; i++) {
qcb->csr[i].qos_buf_count = 0;
- qcb->csr[i].enabled = 0;
+ qcb->csr[i].enabled = false;
}
qcb->qos_list_cnt = 0;
@@ -142,7 +140,7 @@ void gdm_qos_release_list(void *nic_ptr)
free_qos_entry_list(&free_list);
}
-static u32 chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port)
+static int chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port)
{
int i;
@@ -188,17 +186,17 @@ static u32 chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *stream, u8 *port)
return 0;
}
-static u32 get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph)
+static int get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph)
{
- u32 IP_ver, i;
+ int ip_ver, i;
struct qos_cb_s *qcb = &nic->qos;
if (iph == NULL || tcpudph == NULL)
return -1;
- IP_ver = (iph[0]>>4)&0xf;
+ ip_ver = (iph[0]>>4)&0xf;
- if (IP_ver != 4)
+ if (ip_ver != 4)
return -1;
for (i = 0; i < QOS_MAX; i++) {
@@ -213,7 +211,7 @@ static u32 get_qos_index(struct nic *nic, u8 *iph, u8 *tcpudph)
return -1;
}
-static u32 extract_qos_list(struct nic *nic, struct list_head *head)
+static void extract_qos_list(struct nic *nic, struct list_head *head)
{
struct qos_cb_s *qcb = &nic->qos;
struct qos_entry_s *entry;
@@ -238,8 +236,6 @@ static u32 extract_qos_list(struct nic *nic, struct list_head *head)
if (!list_empty(&qcb->qos_list[i]))
netdev_warn(nic->netdev, "Index(%d) is piled!!\n", i);
}
-
- return 0;
}
static void send_qos_list(struct nic *nic, struct list_head *head)
@@ -268,7 +264,7 @@ int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev)
tcph = (struct tcphdr *)iph + iph->ihl*4;
- if (B2H(ethh->h_proto) == ETH_P_IP) {
+ if (ethh->h_proto == cpu_to_be16(ETH_P_IP)) {
if (qcb->qos_list_cnt && !qos_free_list.cnt) {
entry = alloc_qos_entry();
entry->skb = skb;
@@ -305,19 +301,19 @@ out:
return ret;
}
-static u32 get_csr(struct qos_cb_s *qcb, u32 SFID, int mode)
+static int get_csr(struct qos_cb_s *qcb, u32 sfid, int mode)
{
int i;
for (i = 0; i < qcb->qos_list_cnt; i++) {
- if (qcb->csr[i].SFID == SFID)
+ if (qcb->csr[i].sfid == sfid)
return i;
}
if (mode) {
for (i = 0; i < QOS_MAX; i++) {
- if (qcb->csr[i].enabled == 0) {
- qcb->csr[i].enabled = 1;
+ if (!qcb->csr[i].enabled) {
+ qcb->csr[i].enabled = true;
qcb->qos_list_cnt++;
return i;
}
@@ -333,7 +329,8 @@ static u32 get_csr(struct qos_cb_s *qcb, u32 SFID, int mode)
void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
{
struct nic *nic = nic_ptr;
- u32 i, SFID, index, pos;
+ int i, index, pos;
+ u32 sfid;
u8 sub_cmd_evt;
struct qos_cb_s *qcb = &nic->qos;
struct qos_entry_s *entry, *n;
@@ -346,11 +343,11 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
if (sub_cmd_evt == QOS_REPORT) {
spin_lock_irqsave(&qcb->qos_lock, flags);
for (i = 0; i < qcb->qos_list_cnt; i++) {
- SFID = ((buf[(i*5)+6]<<24)&0xff000000);
- SFID += ((buf[(i*5)+7]<<16)&0xff0000);
- SFID += ((buf[(i*5)+8]<<8)&0xff00);
- SFID += (buf[(i*5)+9]);
- index = get_csr(qcb, SFID, 0);
+ sfid = ((buf[(i*5)+6]<<24)&0xff000000);
+ sfid += ((buf[(i*5)+7]<<16)&0xff0000);
+ sfid += ((buf[(i*5)+8]<<8)&0xff00);
+ sfid += (buf[(i*5)+9]);
+ index = get_csr(qcb, sfid, 0);
if (index == -1) {
spin_unlock_irqrestore(&qcb->qos_lock, flags);
netdev_err(nic->netdev, "QoS ERROR: No SF\n");
@@ -367,12 +364,12 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
/* sub_cmd_evt == QOS_ADD || sub_cmd_evt == QOS_CHANG_DEL */
pos = 6;
- SFID = ((buf[pos++]<<24)&0xff000000);
- SFID += ((buf[pos++]<<16)&0xff0000);
- SFID += ((buf[pos++]<<8)&0xff00);
- SFID += (buf[pos++]);
+ sfid = ((buf[pos++]<<24)&0xff000000);
+ sfid += ((buf[pos++]<<16)&0xff0000);
+ sfid += ((buf[pos++]<<8)&0xff00);
+ sfid += (buf[pos++]);
- index = get_csr(qcb, SFID, 1);
+ index = get_csr(qcb, sfid, 1);
if (index == -1) {
netdev_err(nic->netdev,
"QoS ERROR: csr Update Error / Wrong index (%d)\n",
@@ -382,10 +379,10 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
if (sub_cmd_evt == QOS_ADD) {
netdev_dbg(nic->netdev, "QOS_ADD SFID = 0x%x, index=%d\n",
- SFID, index);
+ sfid, index);
spin_lock_irqsave(&qcb->qos_lock, flags);
- qcb->csr[index].SFID = SFID;
+ qcb->csr[index].sfid = sfid;
qcb->csr[index].classifier_rule_en = ((buf[pos++]<<8)&0xff00);
qcb->csr[index].classifier_rule_en += buf[pos++];
if (qcb->csr[index].classifier_rule_en == 0)
@@ -423,12 +420,12 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size)
spin_unlock_irqrestore(&qcb->qos_lock, flags);
} else if (sub_cmd_evt == QOS_CHANGE_DEL) {
netdev_dbg(nic->netdev, "QOS_CHANGE_DEL SFID = 0x%x, index=%d\n",
- SFID, index);
+ sfid, index);
INIT_LIST_HEAD(&free_list);
spin_lock_irqsave(&qcb->qos_lock, flags);
- qcb->csr[index].enabled = 0;
+ qcb->csr[index].enabled = false;
qcb->qos_list_cnt--;
qcb->qos_limit_size = 254/qcb->qos_list_cnt;
diff --git a/drivers/staging/gdm72xx/gdm_qos.h b/drivers/staging/gdm72xx/gdm_qos.h
index 6543cff2a876..bbc8aab338b5 100644
--- a/drivers/staging/gdm72xx/gdm_qos.h
+++ b/drivers/staging/gdm72xx/gdm_qos.h
@@ -11,15 +11,13 @@
* GNU General Public License for more details.
*/
-#if !defined(GDM_QOS_H_20090403)
-#define GDM_QOS_H_20090403
+#ifndef __GDM72XX_GDM_QOS_H__
+#define __GDM72XX_GDM_QOS_H__
#include <linux/types.h>
#include <linux/usb.h>
#include <linux/list.h>
-#define BOOLEAN u8
-
#define QOS_MAX 16
#define IPTYPEOFSERVICE 0x8000
#define PROTOCOL 0x4000
@@ -34,8 +32,8 @@
#define IEEE802_1QVLANID 0x10
struct gdm_wimax_csr_s {
- BOOLEAN enabled;
- u32 SFID;
+ bool enabled;
+ u32 sfid;
u8 qos_buf_count;
u16 classifier_rule_en;
u8 ip2s_lo;
@@ -61,11 +59,11 @@ struct qos_entry_s {
struct qos_cb_s {
struct list_head qos_list[QOS_MAX];
- u32 qos_list_cnt;
- u32 qos_null_idx;
+ int qos_list_cnt;
+ int qos_null_idx;
struct gdm_wimax_csr_s csr[QOS_MAX];
spinlock_t qos_lock;
- u32 qos_limit_size;
+ int qos_limit_size;
};
void gdm_qos_init(void *nic_ptr);
@@ -73,4 +71,4 @@ void gdm_qos_release_list(void *nic_ptr);
int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev);
void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size);
-#endif
+#endif /* __GDM72XX_GDM_QOS_H__ */
diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c
index 7398d451ccc2..7a0a0f221418 100644
--- a/drivers/staging/gdm72xx/gdm_sdio.c
+++ b/drivers/staging/gdm72xx/gdm_sdio.c
@@ -38,9 +38,6 @@
#define TX_HZ 2000
#define TX_INTERVAL (1000000/TX_HZ)
-static int init_sdio(struct sdiowm_dev *sdev);
-static void release_sdio(struct sdiowm_dev *sdev);
-
static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx)
{
struct sdio_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC);
@@ -124,6 +121,43 @@ static void put_rx_struct(struct rx_cxt *rx, struct sdio_rx *r)
list_add_tail(&r->list, &rx->free_list);
}
+static void release_sdio(struct sdiowm_dev *sdev)
+{
+ struct tx_cxt *tx = &sdev->tx;
+ struct rx_cxt *rx = &sdev->rx;
+ struct sdio_tx *t, *t_next;
+ struct sdio_rx *r, *r_next;
+
+ kfree(tx->sdu_buf);
+
+ list_for_each_entry_safe(t, t_next, &tx->free_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ list_for_each_entry_safe(t, t_next, &tx->hci_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ kfree(rx->rx_buf);
+
+ list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
+ list_del(&r->list);
+ free_rx_struct(r);
+ }
+
+ list_for_each_entry_safe(r, r_next, &rx->req_list, list) {
+ list_del(&r->list);
+ free_rx_struct(r);
+ }
+}
+
static int init_sdio(struct sdiowm_dev *sdev)
{
int ret = 0, i;
@@ -176,43 +210,6 @@ fail:
return ret;
}
-static void release_sdio(struct sdiowm_dev *sdev)
-{
- struct tx_cxt *tx = &sdev->tx;
- struct rx_cxt *rx = &sdev->rx;
- struct sdio_tx *t, *t_next;
- struct sdio_rx *r, *r_next;
-
- kfree(tx->sdu_buf);
-
- list_for_each_entry_safe(t, t_next, &tx->free_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- list_for_each_entry_safe(t, t_next, &tx->hci_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- kfree(rx->rx_buf);
-
- list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
- list_del(&r->list);
- free_rx_struct(r);
- }
-
- list_for_each_entry_safe(r, r_next, &rx->req_list, list) {
- list_del(&r->list);
- free_rx_struct(r);
- }
-}
-
static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len)
{
int n, blocks, ret, remain;
@@ -275,14 +272,14 @@ static void send_sdu(struct sdio_func *func, struct tx_cxt *tx)
aggr_len = pos;
hci = (struct hci_s *)(tx->sdu_buf + TYPE_A_HEADER_SIZE);
- hci->cmd_evt = H2B(WIMAX_TX_SDU_AGGR);
- hci->length = H2B(aggr_len - TYPE_A_HEADER_SIZE - HCI_HEADER_SIZE);
+ hci->cmd_evt = cpu_to_be16(WIMAX_TX_SDU_AGGR);
+ hci->length = cpu_to_be16(aggr_len - TYPE_A_HEADER_SIZE -
+ HCI_HEADER_SIZE);
spin_unlock_irqrestore(&tx->lock, flags);
- print_hex_dump_debug("sdio_send: ", DUMP_PREFIX_NONE, 16, 1,
- tx->sdu_buf + TYPE_A_HEADER_SIZE,
- aggr_len - TYPE_A_HEADER_SIZE, false);
+ dev_dbg(&func->dev, "sdio_send: %*ph\n", aggr_len - TYPE_A_HEADER_SIZE,
+ tx->sdu_buf + TYPE_A_HEADER_SIZE);
for (pos = TYPE_A_HEADER_SIZE; pos < aggr_len; pos += TX_CHUNK_SIZE) {
len = aggr_len - pos;
@@ -317,9 +314,9 @@ static void send_hci(struct sdio_func *func, struct tx_cxt *tx,
{
unsigned long flags;
- print_hex_dump_debug("sdio_send: ", DUMP_PREFIX_NONE, 16, 1,
- t->buf + TYPE_A_HEADER_SIZE,
- t->len - TYPE_A_HEADER_SIZE, false);
+ dev_dbg(&func->dev, "sdio_send: %*ph\n", t->len - TYPE_A_HEADER_SIZE,
+ t->buf + TYPE_A_HEADER_SIZE);
+
send_sdio_pkt(func, t->buf, t->len);
spin_lock_irqsave(&tx->lock, flags);
@@ -390,7 +387,8 @@ static int gdm_sdio_send(void *priv_dev, void *data, int len,
u16 cmd_evt;
unsigned long flags;
- BUG_ON(len > TX_BUF_SIZE - TYPE_A_HEADER_SIZE);
+ if (len > TX_BUF_SIZE - TYPE_A_HEADER_SIZE)
+ return -EINVAL;
spin_lock_irqsave(&tx->lock, flags);
@@ -439,9 +437,7 @@ static int gdm_sdio_send(void *priv_dev, void *data, int len,
return 0;
}
-/*
- * Handle the HCI, WIMAX_SDU_TX_FLOW.
- */
+/* Handle the HCI, WIMAX_SDU_TX_FLOW. */
static int control_sdu_tx_flow(struct sdiowm_dev *sdev, u8 *hci_data, int len)
{
struct tx_cxt *tx = &sdev->tx;
@@ -462,8 +458,7 @@ static int control_sdu_tx_flow(struct sdiowm_dev *sdev, u8 *hci_data, int len)
tx->stop_sdu_tx = 0;
if (tx->can_send)
schedule_work(&sdev->ws);
- /*
- * If free buffer for sdu tx doesn't exist, then tx queue
+ /* If free buffer for sdu tx doesn't exist, then tx queue
* should not be woken. For this reason, don't pass the command,
* START_SDU_TX.
*/
@@ -553,8 +548,8 @@ static void gdm_sdio_irq(struct sdio_func *func)
}
end_io:
- print_hex_dump_debug("sdio_receive: ", DUMP_PREFIX_NONE, 16, 1,
- rx->rx_buf, len, false);
+ dev_dbg(&func->dev, "sdio_receive: %*ph\n", len, rx->rx_buf);
+
len = control_sdu_tx_flow(sdev, rx->rx_buf, len);
spin_lock_irqsave(&rx->lock, flags);
diff --git a/drivers/staging/gdm72xx/gdm_sdio.h b/drivers/staging/gdm72xx/gdm_sdio.h
index 0c0e2cbb727e..77ad9d686f8e 100644
--- a/drivers/staging/gdm72xx/gdm_sdio.h
+++ b/drivers/staging/gdm72xx/gdm_sdio.h
@@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
-#ifndef __GDM_SDIO_H__
-#define __GDM_SDIO_H__
+#ifndef __GDM72XX_GDM_SDIO_H__
+#define __GDM72XX_GDM_SDIO_H__
#include <linux/types.h>
#include <linux/time.h>
@@ -60,4 +60,4 @@ struct sdiowm_dev {
struct work_struct ws;
};
-#endif /* __GDM_SDIO_H__ */
+#endif /* __GDM72XX_GDM_SDIO_H__ */
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c
index 78d6667fa0d5..eac2f3478bb9 100644
--- a/drivers/staging/gdm72xx/gdm_usb.c
+++ b/drivers/staging/gdm72xx/gdm_usb.c
@@ -36,10 +36,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
#define GDM7205_PADDING 256
-#define H2B(x) __cpu_to_be16(x)
-#define B2H(x) __be16_to_cpu(x)
-#define DB2H(x) __be32_to_cpu(x)
-
#define DOWNLOAD_CONF_VALUE 0x21
#ifdef CONFIG_WIMAX_GDM72XX_K_MODE
@@ -53,9 +49,6 @@ static int k_mode_stop;
#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */
-static int init_usb(struct usbwm_dev *udev);
-static void release_usb(struct usbwm_dev *udev);
-
static struct usb_tx *alloc_tx_struct(struct tx_cxt *tx)
{
struct usb_tx *t = kzalloc(sizeof(*t), GFP_ATOMIC);
@@ -164,6 +157,48 @@ static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r)
list_move(&r->list, &rx->free_list);
}
+static void release_usb(struct usbwm_dev *udev)
+{
+ struct tx_cxt *tx = &udev->tx;
+ struct rx_cxt *rx = &udev->rx;
+ struct usb_tx *t, *t_next;
+ struct usb_rx *r, *r_next;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tx->lock, flags);
+
+ list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ list_for_each_entry_safe(t, t_next, &tx->hci_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ list_for_each_entry_safe(t, t_next, &tx->free_list, list) {
+ list_del(&t->list);
+ free_tx_struct(t);
+ }
+
+ spin_unlock_irqrestore(&tx->lock, flags);
+
+ spin_lock_irqsave(&rx->lock, flags);
+
+ list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
+ list_del(&r->list);
+ free_rx_struct(r);
+ }
+
+ list_for_each_entry_safe(r, r_next, &rx->used_list, list) {
+ list_del(&r->list);
+ free_rx_struct(r);
+ }
+
+ spin_unlock_irqrestore(&rx->lock, flags);
+}
+
static int init_usb(struct usbwm_dev *udev)
{
int ret = 0, i;
@@ -214,48 +249,6 @@ fail:
return ret;
}
-static void release_usb(struct usbwm_dev *udev)
-{
- struct tx_cxt *tx = &udev->tx;
- struct rx_cxt *rx = &udev->rx;
- struct usb_tx *t, *t_next;
- struct usb_rx *r, *r_next;
- unsigned long flags;
-
- spin_lock_irqsave(&tx->lock, flags);
-
- list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- list_for_each_entry_safe(t, t_next, &tx->hci_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- list_for_each_entry_safe(t, t_next, &tx->free_list, list) {
- list_del(&t->list);
- free_tx_struct(t);
- }
-
- spin_unlock_irqrestore(&tx->lock, flags);
-
- spin_lock_irqsave(&rx->lock, flags);
-
- list_for_each_entry_safe(r, r_next, &rx->free_list, list) {
- list_del(&r->list);
- free_rx_struct(r);
- }
-
- list_for_each_entry_safe(r, r_next, &rx->used_list, list) {
- list_del(&r->list);
- free_rx_struct(r);
- }
-
- spin_unlock_irqrestore(&rx->lock, flags);
-}
-
static void __gdm_usb_send_complete(struct urb *urb)
{
struct usb_tx *t = urb->context;
@@ -312,7 +305,8 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
return -ENODEV;
}
- BUG_ON(len > TX_BUF_SIZE - padding - 1);
+ if (len > TX_BUF_SIZE - padding - 1)
+ return -EINVAL;
spin_lock_irqsave(&tx->lock, flags);
@@ -338,8 +332,7 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
t->callback = cb;
t->cb_data = cb_data;
- /*
- * In some cases, USB Module of WiMax is blocked when data size is
+ /* In some cases, USB Module of WiMax is blocked when data size is
* the multiple of 512. So, increment length by one in that case.
*/
if ((len % 512) == 0)
@@ -348,8 +341,8 @@ static int gdm_usb_send(void *priv_dev, void *data, int len,
usb_fill_bulk_urb(t->urb, usbdev, usb_sndbulkpipe(usbdev, 1), t->buf,
len + padding, gdm_usb_send_complete, t);
- print_hex_dump_debug("usb_send: ", DUMP_PREFIX_NONE, 16, 1, t->buf,
- len + padding, false);
+ dev_dbg(&usbdev->dev, "usb_send: %*ph\n", len + padding, t->buf);
+
#ifdef CONFIG_WIMAX_GDM72XX_USB_PM
if (usbdev->state & USB_STATE_SUSPENDED) {
list_add_tail(&t->p_list, &tx->pending_list);
@@ -427,8 +420,10 @@ static void gdm_usb_rcv_complete(struct urb *urb)
if (!urb->status) {
cmd_evt = (r->buf[0] << 8) | (r->buf[1]);
- print_hex_dump_debug("usb_receive: ", DUMP_PREFIX_NONE, 16, 1,
- r->buf, urb->actual_length, false);
+
+ dev_dbg(&dev->dev, "usb_receive: %*ph\n", urb->actual_length,
+ r->buf);
+
if (cmd_evt == WIMAX_SDU_TX_FLOW) {
if (r->buf[4] == 0) {
dev_dbg(&dev->dev, "WIMAX ==> STOP SDU TX\n");
@@ -439,8 +434,7 @@ static void gdm_usb_rcv_complete(struct urb *urb)
list_for_each_entry(t, &tx->sdu_list, list) {
usb_submit_urb(t->urb, GFP_ATOMIC);
}
- /*
- * If free buffer for sdu tx doesn't
+ /* If free buffer for sdu tx doesn't
* exist, then tx queue should not be
* woken. For this reason, don't pass
* the command, START_SDU_TX.
@@ -542,9 +536,9 @@ static int gdm_usb_probe(struct usb_interface *intf,
bConfigurationValue = usbdev->actconfig->desc.bConfigurationValue;
/*USB description is set up with Little-Endian*/
- idVendor = L2H(usbdev->descriptor.idVendor);
- idProduct = L2H(usbdev->descriptor.idProduct);
- bcdDevice = L2H(usbdev->descriptor.bcdDevice);
+ idVendor = le16_to_cpu(usbdev->descriptor.idVendor);
+ idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
+ bcdDevice = le16_to_cpu(usbdev->descriptor.bcdDevice);
dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n",
idVendor, idProduct);
@@ -627,12 +621,11 @@ static void gdm_usb_disconnect(struct usb_interface *intf)
phy_dev = usb_get_intfdata(intf);
/*USB description is set up with Little-Endian*/
- idProduct = L2H(usbdev->descriptor.idProduct);
+ idProduct = le16_to_cpu(usbdev->descriptor.idProduct);
if (idProduct != EMERGENCY_PID &&
bConfigurationValue != DOWNLOAD_CONF_VALUE &&
(idProduct & B_DOWNLOAD) == 0) {
-
udev = phy_dev->priv_dev;
udev->usbdev = NULL;
@@ -710,10 +703,8 @@ static int k_mode_thread(void *arg)
int ret;
while (!k_mode_stop) {
-
spin_lock_irqsave(&k_lock, flags2);
while (!list_empty(&k_list)) {
-
udev = list_entry(k_list.next, struct usbwm_dev, list);
tx = &udev->tx;
rx = &udev->rx;
diff --git a/drivers/staging/gdm72xx/gdm_usb.h b/drivers/staging/gdm72xx/gdm_usb.h
index 30506529a8cc..8e58a25e7143 100644
--- a/drivers/staging/gdm72xx/gdm_usb.h
+++ b/drivers/staging/gdm72xx/gdm_usb.h
@@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
-#ifndef __GDM_USB_H__
-#define __GDM_USB_H__
+#ifndef __GDM72XX_GDM_USB_H__
+#define __GDM72XX_GDM_USB_H__
#include <linux/types.h>
#include <linux/usb.h>
@@ -75,4 +75,4 @@ struct usbwm_dev {
int padding;
};
-#endif /* __GDM_USB_H__ */
+#endif /* __GDM72XX_GDM_USB_H__ */
diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c
index e5e511585122..f5a3378c3951 100644
--- a/drivers/staging/gdm72xx/gdm_wimax.c
+++ b/drivers/staging/gdm72xx/gdm_wimax.c
@@ -41,12 +41,6 @@ struct evt_entry {
int size;
};
-static void __gdm_wimax_event_send(struct work_struct *work);
-static inline struct evt_entry *alloc_event_entry(void);
-static inline void free_event_entry(struct evt_entry *e);
-static struct evt_entry *get_event_entry(void);
-static void put_event_entry(struct evt_entry *e);
-
static struct {
int ref_cnt;
struct sock *sock;
@@ -58,114 +52,10 @@ static struct {
static u8 gdm_wimax_macaddr[6] = {0x00, 0x0a, 0x3b, 0xf0, 0x01, 0x30};
-static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm);
-static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up);
-
-static const char *get_protocol_name(u16 protocol)
-{
- static char buf[32];
- const char *name = "-";
-
- switch (protocol) {
- case ETH_P_ARP:
- name = "ARP";
- break;
- case ETH_P_IP:
- name = "IP";
- break;
- case ETH_P_IPV6:
- name = "IPv6";
- break;
- }
-
- sprintf(buf, "0x%04x(%s)", protocol, name);
- return buf;
-}
-
-static const char *get_ip_protocol_name(u8 ip_protocol)
-{
- static char buf[32];
- const char *name = "-";
-
- switch (ip_protocol) {
- case IPPROTO_TCP:
- name = "TCP";
- break;
- case IPPROTO_UDP:
- name = "UDP";
- break;
- case IPPROTO_ICMP:
- name = "ICMP";
- break;
- }
-
- sprintf(buf, "%u(%s)", ip_protocol, name);
- return buf;
-}
-
-static const char *get_port_name(u16 port)
-{
- static char buf[32];
- const char *name = "-";
-
- switch (port) {
- case 67:
- name = "DHCP-Server";
- break;
- case 68:
- name = "DHCP-Client";
- break;
- case 69:
- name = "TFTP";
- break;
- }
-
- sprintf(buf, "%u(%s)", port, name);
- return buf;
-}
-
-static void dump_eth_packet(struct net_device *dev, const char *title,
- u8 *data, int len)
-{
- struct iphdr *ih = NULL;
- struct udphdr *uh = NULL;
- u16 protocol = 0;
- u8 ip_protocol = 0;
- u16 port = 0;
-
- protocol = (data[12]<<8) | data[13];
- ih = (struct iphdr *)(data+ETH_HLEN);
-
- if (protocol == ETH_P_IP) {
- uh = (struct udphdr *)((char *)ih + sizeof(struct iphdr));
- ip_protocol = ih->protocol;
- port = ntohs(uh->dest);
- } else if (protocol == ETH_P_IPV6) {
- struct ipv6hdr *i6h = (struct ipv6hdr *)data;
-
- uh = (struct udphdr *)((char *)i6h + sizeof(struct ipv6hdr));
- ip_protocol = i6h->nexthdr;
- port = ntohs(uh->dest);
- }
-
- netdev_dbg(dev, "[%s] len=%d, %s, %s, %s\n", title, len,
- get_protocol_name(protocol),
- get_ip_protocol_name(ip_protocol),
- get_port_name(port));
-
- if (!(data[0] == 0xff && data[1] == 0xff)) {
- if (protocol == ETH_P_IP)
- netdev_dbg(dev, " src=%pI4\n", &ih->saddr);
- else if (protocol == ETH_P_IPV6)
- netdev_dbg(dev, " src=%pI6\n", &ih->saddr);
- }
-
- print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, data, len, false);
-}
-
static inline int gdm_wimax_header(struct sk_buff **pskb)
{
u16 buf[HCI_HEADER_SIZE / sizeof(u16)];
+ struct hci_s *hci = (struct hci_s *)buf;
struct sk_buff *skb = *pskb;
if (unlikely(skb_headroom(skb) < HCI_HEADER_SIZE)) {
@@ -181,14 +71,45 @@ static inline int gdm_wimax_header(struct sk_buff **pskb)
}
skb_push(skb, HCI_HEADER_SIZE);
- buf[0] = H2B(WIMAX_TX_SDU);
- buf[1] = H2B(skb->len - HCI_HEADER_SIZE);
+ hci->cmd_evt = cpu_to_be16(WIMAX_TX_SDU);
+ hci->length = cpu_to_be16(skb->len - HCI_HEADER_SIZE);
memcpy(skb->data, buf, HCI_HEADER_SIZE);
*pskb = skb;
return 0;
}
+static inline struct evt_entry *alloc_event_entry(void)
+{
+ return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC);
+}
+
+static inline void free_event_entry(struct evt_entry *e)
+{
+ kfree(e);
+}
+
+static struct evt_entry *get_event_entry(void)
+{
+ struct evt_entry *e;
+
+ if (list_empty(&wm_event.freeq)) {
+ e = alloc_event_entry();
+ } else {
+ e = list_entry(wm_event.freeq.next, struct evt_entry, list);
+ list_del(&e->list);
+ }
+
+ return e;
+}
+
+static void put_event_entry(struct evt_entry *e)
+{
+ BUG_ON(!e);
+
+ list_add_tail(&e->list, &wm_event.freeq);
+}
+
static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg,
int len)
{
@@ -203,6 +124,30 @@ static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg,
gdm_wimax_send(nic, msg, len);
}
+static void __gdm_wimax_event_send(struct work_struct *work)
+{
+ int idx;
+ unsigned long flags;
+ struct evt_entry *e;
+
+ spin_lock_irqsave(&wm_event.evt_lock, flags);
+
+ while (!list_empty(&wm_event.evtq)) {
+ e = list_entry(wm_event.evtq.next, struct evt_entry, list);
+ spin_unlock_irqrestore(&wm_event.evt_lock, flags);
+
+ if (sscanf(e->dev->name, "wm%d", &idx) == 1)
+ netlink_send(wm_event.sock, idx, 0, e->evt_data,
+ e->size);
+
+ spin_lock_irqsave(&wm_event.evt_lock, flags);
+ list_del(&e->list);
+ put_event_entry(e);
+ }
+
+ spin_unlock_irqrestore(&wm_event.evt_lock, flags);
+}
+
static int gdm_wimax_event_init(void)
{
if (!wm_event.ref_cnt) {
@@ -248,60 +193,6 @@ static void gdm_wimax_event_exit(void)
}
}
-static inline struct evt_entry *alloc_event_entry(void)
-{
- return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC);
-}
-
-static inline void free_event_entry(struct evt_entry *e)
-{
- kfree(e);
-}
-
-static struct evt_entry *get_event_entry(void)
-{
- struct evt_entry *e;
-
- if (list_empty(&wm_event.freeq)) {
- e = alloc_event_entry();
- } else {
- e = list_entry(wm_event.freeq.next, struct evt_entry, list);
- list_del(&e->list);
- }
-
- return e;
-}
-
-static void put_event_entry(struct evt_entry *e)
-{
- BUG_ON(!e);
-
- list_add_tail(&e->list, &wm_event.freeq);
-}
-
-static void __gdm_wimax_event_send(struct work_struct *work)
-{
- int idx;
- unsigned long flags;
- struct evt_entry *e;
-
- spin_lock_irqsave(&wm_event.evt_lock, flags);
-
- while (!list_empty(&wm_event.evtq)) {
- e = list_entry(wm_event.evtq.next, struct evt_entry, list);
- spin_unlock_irqrestore(&wm_event.evt_lock, flags);
-
- sscanf(e->dev->name, "wm%d", &idx);
- netlink_send(wm_event.sock, idx, 0, e->evt_data, e->size);
-
- spin_lock_irqsave(&wm_event.evt_lock, flags);
- list_del(&e->list);
- put_event_entry(e);
- }
-
- spin_unlock_irqrestore(&wm_event.evt_lock, flags);
-}
-
static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size)
{
struct evt_entry *e;
@@ -358,8 +249,8 @@ int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev)
return ret;
}
- nic->stats.tx_packets++;
- nic->stats.tx_bytes += skb->len - HCI_HEADER_SIZE;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len - HCI_HEADER_SIZE;
kfree_skb(skb);
return ret;
}
@@ -367,10 +258,6 @@ int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev)
static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev)
{
int ret = 0;
- struct nic *nic = netdev_priv(dev);
- struct fsm_s *fsm = (struct fsm_s *)nic->sdk_data[SIOC_DATA_FSM].buf;
-
- dump_eth_packet(dev, "TX", skb->data, skb->len);
ret = gdm_wimax_header(&skb);
if (ret < 0) {
@@ -378,17 +265,6 @@ static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev)
return ret;
}
- #if !defined(LOOPBACK_TEST)
- if (!fsm) {
- netdev_err(dev, "ASSERTION ERROR: fsm is NULL!!\n");
- } else if (fsm->m_status != M_CONNECTED) {
- netdev_emerg(dev, "ASSERTION ERROR: Device is NOT ready. status=%d\n",
- fsm->m_status);
- kfree_skb(skb);
- return 0;
- }
- #endif
-
#if defined(CONFIG_WIMAX_GDM72XX_QOS)
ret = gdm_qos_send_hci_pkt(skb, dev);
#else
@@ -408,7 +284,7 @@ static int gdm_wimax_set_config(struct net_device *dev, struct ifmap *map)
static void __gdm_wimax_set_mac_addr(struct net_device *dev, char *mac_addr)
{
u16 hci_pkt_buf[32 / sizeof(u16)];
- u8 *pkt = (u8 *)&hci_pkt_buf[0];
+ struct hci_s *hci = (struct hci_s *)hci_pkt_buf;
struct nic *nic = netdev_priv(dev);
/* Since dev is registered as a ethernet device,
@@ -419,13 +295,13 @@ static void __gdm_wimax_set_mac_addr(struct net_device *dev, char *mac_addr)
/* Let lower layer know of this change by sending
* SetInformation(MAC Address)
*/
- hci_pkt_buf[0] = H2B(WIMAX_SET_INFO); /* cmd_evt */
- hci_pkt_buf[1] = H2B(8); /* size */
- pkt[4] = 0; /* T */
- pkt[5] = 6; /* L */
- memcpy(pkt + 6, mac_addr, dev->addr_len); /* V */
+ hci->cmd_evt = cpu_to_be16(WIMAX_SET_INFO);
+ hci->length = cpu_to_be16(8);
+ hci->data[0] = 0; /* T */
+ hci->data[1] = 6; /* L */
+ memcpy(&hci->data[2], mac_addr, dev->addr_len); /* V */
- gdm_wimax_send(nic, pkt, HCI_HEADER_SIZE + 8);
+ gdm_wimax_send(nic, hci, HCI_HEADER_SIZE + 8);
}
/* A driver function */
@@ -444,11 +320,20 @@ static int gdm_wimax_set_mac_addr(struct net_device *dev, void *p)
return 0;
}
-static struct net_device_stats *gdm_wimax_stats(struct net_device *dev)
+static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up)
{
- struct nic *nic = netdev_priv(dev);
+ u16 buf[32 / sizeof(u16)];
+ struct hci_s *hci = (struct hci_s *)buf;
+ unsigned char up_down;
+
+ up_down = if_up ? WIMAX_IF_UP : WIMAX_IF_DOWN;
- return &nic->stats;
+ /* Indicate updating fsm */
+ hci->cmd_evt = cpu_to_be16(WIMAX_IF_UPDOWN);
+ hci->length = cpu_to_be16(sizeof(up_down));
+ hci->data[0] = up_down;
+
+ gdm_wimax_event_send(dev, (char *)hci, HCI_HEADER_SIZE+sizeof(up_down));
}
static int gdm_wimax_open(struct net_device *dev)
@@ -533,6 +418,20 @@ static void gdm_wimax_cleanup_ioctl(struct net_device *dev)
kdelete(&nic->sdk_data[i].buf);
}
+static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm)
+{
+ u16 buf[32 / sizeof(u16)];
+ struct hci_s *hci = (struct hci_s *)buf;
+
+ /* Indicate updating fsm */
+ hci->cmd_evt = cpu_to_be16(WIMAX_FSM_UPDATE);
+ hci->length = cpu_to_be16(sizeof(struct fsm_s));
+ memcpy(&hci->data[0], fsm, sizeof(struct fsm_s));
+
+ gdm_wimax_event_send(dev, (char *)hci,
+ HCI_HEADER_SIZE + sizeof(struct fsm_s));
+}
+
static void gdm_update_fsm(struct net_device *dev, struct fsm_s *new_fsm)
{
struct nic *nic = netdev_priv(dev);
@@ -580,8 +479,9 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return ret;
} else if (req->cmd == SIOCS_DATA) {
if (req->data_id == SIOC_DATA_FSM) {
- /*NOTE: gdm_update_fsm should be called
- before gdm_wimax_ioctl_set_data is called*/
+ /* NOTE: gdm_update_fsm should be called
+ * before gdm_wimax_ioctl_set_data is called.
+ */
gdm_update_fsm(dev,
(struct fsm_s *)req->data.buf);
}
@@ -606,39 +506,35 @@ static void gdm_wimax_prepare_device(struct net_device *dev)
struct hci_s *hci = (struct hci_s *)buf;
u16 len = 0;
u32 val = 0;
-
- #define BIT_MULTI_CS 0
- #define BIT_WIMAX 1
- #define BIT_QOS 2
- #define BIT_AGGREGATION 3
+ __be32 val_be32;
/* GetInformation mac address */
len = 0;
- hci->cmd_evt = H2B(WIMAX_GET_INFO);
+ hci->cmd_evt = cpu_to_be16(WIMAX_GET_INFO);
hci->data[len++] = TLV_T(T_MAC_ADDRESS);
- hci->length = H2B(len);
+ hci->length = cpu_to_be16(len);
gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);
- val = (1<<BIT_WIMAX) | (1<<BIT_MULTI_CS);
+ val = T_CAPABILITY_WIMAX | T_CAPABILITY_MULTI_CS;
#if defined(CONFIG_WIMAX_GDM72XX_QOS)
- val |= (1<<BIT_QOS);
+ val |= T_CAPABILITY_QOS;
#endif
#if defined(CONFIG_WIMAX_GDM72XX_WIMAX2)
- val |= (1<<BIT_AGGREGATION);
+ val |= T_CAPABILITY_AGGREGATION;
#endif
/* Set capability */
len = 0;
- hci->cmd_evt = H2B(WIMAX_SET_INFO);
+ hci->cmd_evt = cpu_to_be16(WIMAX_SET_INFO);
hci->data[len++] = TLV_T(T_CAPABILITY);
hci->data[len++] = TLV_L(T_CAPABILITY);
- val = DH2B(val);
- memcpy(&hci->data[len], &val, TLV_L(T_CAPABILITY));
+ val_be32 = cpu_to_be32(val);
+ memcpy(&hci->data[len], &val_be32, TLV_L(T_CAPABILITY));
len += TLV_L(T_CAPABILITY);
- hci->length = H2B(len);
+ hci->length = cpu_to_be16(len);
gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);
- netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val));
+ netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", val);
}
static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V)
@@ -648,7 +544,7 @@ static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V)
*T = buf[0];
if (buf[1] == 0x82) {
- *L = B2H(__U82U16(&buf[2]));
+ *L = be16_to_cpu(__U82U16(&buf[2]));
next_pos = 1/*type*/+3/*len*/;
} else {
*L = buf[1];
@@ -668,8 +564,8 @@ static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf,
u16 cmd_evt, cmd_len;
int pos = HCI_HEADER_SIZE;
- cmd_evt = B2H(*(u16 *)&buf[0]);
- cmd_len = B2H(*(u16 *)&buf[2]);
+ cmd_evt = be16_to_cpup((const __be16 *)&buf[0]);
+ cmd_len = be16_to_cpup((const __be16 *)&buf[2]);
if (len < cmd_len + HCI_HEADER_SIZE) {
netdev_err(dev, "%s: invalid length [%d/%d]\n", __func__,
@@ -705,12 +601,9 @@ static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf,
static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
{
- struct nic *nic = netdev_priv(dev);
struct sk_buff *skb;
int ret;
- dump_eth_packet(dev, "RX", buf, len);
-
skb = dev_alloc_skb(len + 2);
if (!skb) {
netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__);
@@ -718,8 +611,8 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
}
skb_reserve(skb, 2);
- nic->stats.rx_packets++;
- nic->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
memcpy(skb_put(skb, len), buf, len);
@@ -742,13 +635,13 @@ static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf,
while (len > 0) {
hci = (struct hci_s *)buf;
- if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) {
+ if (hci->cmd_evt != cpu_to_be16(WIMAX_RX_SDU)) {
netdev_err(dev, "Wrong cmd_evt(0x%04X)\n",
- B2H(hci->cmd_evt));
+ be16_to_cpu(hci->cmd_evt));
break;
}
- length = B2H(hci->length);
+ length = be16_to_cpu(hci->length);
gdm_wimax_netif_rx(dev, hci->data, length);
if (length & 0x3) {
@@ -773,8 +666,8 @@ static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len)
if (len == 0)
return;
- cmd_evt = B2H(*(u16 *)&buf[0]);
- cmd_len = B2H(*(u16 *)&buf[2]);
+ cmd_evt = be16_to_cpup((const __be16 *)&buf[0]);
+ cmd_len = be16_to_cpup((const __be16 *)&buf[2]);
if (len < cmd_len + HCI_HEADER_SIZE) {
if (len)
@@ -811,36 +704,6 @@ static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len)
}
}
-static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm)
-{
- u16 buf[32 / sizeof(u16)];
- u8 *hci_pkt_buf = (u8 *)&buf[0];
-
- /* Indicate updating fsm */
- buf[0] = H2B(WIMAX_FSM_UPDATE);
- buf[1] = H2B(sizeof(struct fsm_s));
- memcpy(&hci_pkt_buf[HCI_HEADER_SIZE], fsm, sizeof(struct fsm_s));
-
- gdm_wimax_event_send(dev, hci_pkt_buf,
- HCI_HEADER_SIZE + sizeof(struct fsm_s));
-}
-
-static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up)
-{
- u16 buf[32 / sizeof(u16)];
- struct hci_s *hci = (struct hci_s *)buf;
- unsigned char up_down;
-
- up_down = if_up ? WIMAX_IF_UP : WIMAX_IF_DOWN;
-
- /* Indicate updating fsm */
- hci->cmd_evt = H2B(WIMAX_IF_UPDOWN);
- hci->length = H2B(sizeof(up_down));
- hci->data[0] = up_down;
-
- gdm_wimax_event_send(dev, (char *)hci, HCI_HEADER_SIZE+sizeof(up_down));
-}
-
static void rx_complete(void *arg, void *data, int len)
{
struct nic *nic = arg;
@@ -875,7 +738,6 @@ static struct net_device_ops gdm_netdev_ops = {
.ndo_stop = gdm_wimax_close,
.ndo_set_config = gdm_wimax_set_config,
.ndo_start_xmit = gdm_wimax_tx,
- .ndo_get_stats = gdm_wimax_stats,
.ndo_set_mac_address = gdm_wimax_set_mac_addr,
.ndo_do_ioctl = gdm_wimax_ioctl,
};
@@ -886,7 +748,8 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
struct net_device *dev;
int ret;
- dev = alloc_netdev(sizeof(*nic), "wm%d", ether_setup);
+ dev = alloc_netdev(sizeof(*nic), "wm%d", NET_NAME_UNKNOWN,
+ ether_setup);
if (dev == NULL) {
pr_err("alloc_etherdev failed\n");
@@ -900,8 +763,6 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
memcpy(dev->dev_addr, gdm_wimax_macaddr, sizeof(gdm_wimax_macaddr));
nic = netdev_priv(dev);
- memset(nic, 0, sizeof(*nic));
-
nic->netdev = dev;
nic->phy_dev = phy_dev;
phy_dev->netdev = dev;
@@ -917,12 +778,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
if (ret)
goto cleanup;
- #if defined(LOOPBACK_TEST)
- netif_start_queue(dev);
- netif_carrier_on(dev);
- #else
netif_carrier_off(dev);
- #endif
#ifdef CONFIG_WIMAX_GDM72XX_QOS
gdm_qos_init(nic);
diff --git a/drivers/staging/gdm72xx/gdm_wimax.h b/drivers/staging/gdm72xx/gdm_wimax.h
index 7e2c88877ed0..3330cd798c69 100644
--- a/drivers/staging/gdm72xx/gdm_wimax.h
+++ b/drivers/staging/gdm72xx/gdm_wimax.h
@@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
-#ifndef __GDM_WIMAX_H__
-#define __GDM_WIMAX_H__
+#ifndef __GDM72XX_GDM_WIMAX_H__
+#define __GDM72XX_GDM_WIMAX_H__
#include <linux/netdevice.h>
#include <linux/types.h>
@@ -23,16 +23,6 @@
#define DRIVER_VERSION "3.2.3"
-#define H2L(x) __cpu_to_le16(x)
-#define L2H(x) __le16_to_cpu(x)
-#define DH2L(x) __cpu_to_le32(x)
-#define DL2H(x) __le32_to_cpu(x)
-
-#define H2B(x) __cpu_to_be16(x)
-#define B2H(x) __be16_to_cpu(x)
-#define DH2B(x) __cpu_to_be32(x)
-#define DB2H(x) __be32_to_cpu(x)
-
struct phy_dev {
void *priv_dev;
struct net_device *netdev;
@@ -46,7 +36,6 @@ struct phy_dev {
struct nic {
struct net_device *netdev;
struct phy_dev *phy_dev;
- struct net_device_stats stats;
struct data_s sdk_data[SIOC_DATA_MAX];
#if defined(CONFIG_WIMAX_GDM72XX_QOS)
struct qos_cb_s qos;
@@ -57,4 +46,4 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev);
int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev);
void unregister_wimax_device(struct phy_dev *phy_dev);
-#endif
+#endif /* __GDM72XX_GDM_WIMAX_H__ */
diff --git a/drivers/staging/gdm72xx/hci.h b/drivers/staging/gdm72xx/hci.h
index 2485a3799123..10a6bfa6e998 100644
--- a/drivers/staging/gdm72xx/hci.h
+++ b/drivers/staging/gdm72xx/hci.h
@@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
-#ifndef HCI_H_20080801
-#define HCI_H_20080801
+#ifndef __GDM72XX_HCI_H__
+#define __GDM72XX_HCI_H__
#define HCI_HEADER_SIZE 4
#define HCI_VALUE_OFFS (HCI_HEADER_SIZE)
@@ -112,13 +112,11 @@
#define W_SCAN_ALL_SUBSCRIPTION 1
#define W_SCAN_SPECIFIED_SUBSCRIPTION 2
-/*
- * TLV
+/* TLV
*
* [31:31] indicates the type is composite.
* [30:16] is the length of the type. 0 length means length is variable.
* [15:0] is the actual type.
- *
*/
#define TLV_L(x) (((x) >> 16) & 0xff)
#define TLV_T(x) ((x) & 0xff)
@@ -200,10 +198,16 @@
#define T_FFTSIZE (0xda | (4 << 16))
#define T_DUPLEX_MODE (0xdb | (4 << 16))
+/* T_CAPABILITY */
+#define T_CAPABILITY_MULTI_CS (1 << 0)
+#define T_CAPABILITY_WIMAX (1 << 1)
+#define T_CAPABILITY_QOS (1 << 2)
+#define T_CAPABILITY_AGGREGATION (1 << 3)
+
struct hci_s {
- unsigned short cmd_evt;
- unsigned short length;
- unsigned char data[0];
+ __be16 cmd_evt;
+ __be16 length;
+ u8 data[0];
} __packed;
-#endif
+#endif /* __GDM72XX_HCI_H__ */
diff --git a/drivers/staging/gdm72xx/netlink_k.h b/drivers/staging/gdm72xx/netlink_k.h
index b6caac16b3d3..1fe7198d539e 100644
--- a/drivers/staging/gdm72xx/netlink_k.h
+++ b/drivers/staging/gdm72xx/netlink_k.h
@@ -11,8 +11,9 @@
* GNU General Public License for more details.
*/
-#if !defined(NETLINK_H_20081202)
-#define NETLINK_H_20081202
+#ifndef __GDM72XX_NETLINK_K_H__
+#define __GDM72XX_NETLINK_K_H__
+
#include <linux/netdevice.h>
#include <net/sock.h>
@@ -21,4 +22,4 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type,
void netlink_exit(struct sock *sock);
int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len);
-#endif
+#endif /* __GDM72XX_NETLINK_K_H__ */
diff --git a/drivers/staging/gdm72xx/sdio_boot.h b/drivers/staging/gdm72xx/sdio_boot.h
index 045c1f450539..e0800c6fe2fd 100644
--- a/drivers/staging/gdm72xx/sdio_boot.h
+++ b/drivers/staging/gdm72xx/sdio_boot.h
@@ -11,11 +11,11 @@
* GNU General Public License for more details.
*/
-#ifndef __SDIO_BOOT_H__
-#define __SDIO_BOOT_H__
+#ifndef __GDM72XX_SDIO_BOOT_H__
+#define __GDM72XX_SDIO_BOOT_H__
struct sdio_func;
int sdio_boot(struct sdio_func *func);
-#endif /* __SDIO_BOOT_H__ */
+#endif /* __GDM72XX_SDIO_BOOT_H__ */
diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c
index d59bac872ffe..3ccc447730e8 100644
--- a/drivers/staging/gdm72xx/usb_boot.c
+++ b/drivers/staging/gdm72xx/usb_boot.c
@@ -36,8 +36,8 @@
#define FW_FS "ramdisk.jffs2"
struct dn_header {
- u32 magic_num;
- u32 file_size;
+ __be32 magic_num;
+ __be32 file_size;
};
struct img_header {
@@ -69,7 +69,7 @@ static void array_le32_to_cpu(u32 *arr, int num)
int i;
for (i = 0; i < num; i++, arr++)
- *arr = __le32_to_cpu(*arr);
+ le32_to_cpus(arr);
}
static u8 *tx_buf;
@@ -115,8 +115,8 @@ static int download_image(struct usb_device *usbdev,
u32 size;
size = ALIGN(img_len, DOWNLOAD_SIZE);
- h.magic_num = __cpu_to_be32(magic_num);
- h.file_size = __cpu_to_be32(size);
+ h.magic_num = cpu_to_be32(magic_num);
+ h.file_size = cpu_to_be32(size);
ret = gdm_wibro_send(usbdev, &h, sizeof(h));
if (ret < 0)
diff --git a/drivers/staging/gdm72xx/usb_boot.h b/drivers/staging/gdm72xx/usb_boot.h
index 05308e253050..5bf7190377e2 100644
--- a/drivers/staging/gdm72xx/usb_boot.h
+++ b/drivers/staging/gdm72xx/usb_boot.h
@@ -11,12 +11,12 @@
* GNU General Public License for more details.
*/
-#ifndef __USB_BOOT_H__
-#define __USB_BOOT_H__
+#ifndef __GDM72XX_USB_BOOT_H__
+#define __GDM72XX_USB_BOOT_H__
struct usb_device;
int usb_boot(struct usb_device *usbdev, u16 pid);
int usb_emergency(struct usb_device *usbdev);
-#endif /* __USB_BOOT_H__ */
+#endif /* __GDM72XX_USB_BOOT_H__ */
diff --git a/drivers/staging/gdm72xx/usb_ids.h b/drivers/staging/gdm72xx/usb_ids.h
index 1a61b3599765..8ce544de7342 100644
--- a/drivers/staging/gdm72xx/usb_ids.h
+++ b/drivers/staging/gdm72xx/usb_ids.h
@@ -11,8 +11,8 @@
* GNU General Public License for more details.
*/
-#ifndef __USB_IDS_H__
-#define __USB_IDS_H__
+#ifndef __GDM72XX_USB_IDS_H__
+#define __GDM72XX_USB_IDS_H__
/*You can replace vendor-ID as yours.*/
#define GCT_VID 0x1076
@@ -79,4 +79,4 @@ static const struct usb_device_id id_table[] = {
{ }
};
-#endif /* __USB_IDS_H__ */
+#endif /* __GDM72XX_USB_IDS_H__ */
diff --git a/drivers/staging/gdm72xx/wm_ioctl.h b/drivers/staging/gdm72xx/wm_ioctl.h
index d022c6ca0e23..ed8f649c0042 100644
--- a/drivers/staging/gdm72xx/wm_ioctl.h
+++ b/drivers/staging/gdm72xx/wm_ioctl.h
@@ -11,8 +11,9 @@
* GNU General Public License for more details.
*/
-#if !defined(WM_IOCTL_H_20080714)
-#define WM_IOCTL_H_20080714
+#ifndef __GDM72XX_WM_IOCTL_H__
+#define __GDM72XX_WM_IOCTL_H__
+
#if !defined(__KERNEL__)
#include <net/if.h>
#endif
@@ -92,4 +93,4 @@ struct wm_req_s {
#define ifr_name ifr_ifrn.ifrn_name
#endif
-#endif
+#endif /* __GDM72XX_WM_IOCTL_H__ */
diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c
index cbd456770af0..c89d0b87a446 100644
--- a/drivers/staging/goldfish/goldfish_audio.c
+++ b/drivers/staging/goldfish/goldfish_audio.c
@@ -203,10 +203,10 @@ static int goldfish_audio_open(struct inode *ip, struct file *fp)
AUDIO_INT_WRITE_BUFFER_2_EMPTY);
AUDIO_WRITE(audio_data, AUDIO_INT_ENABLE, AUDIO_INT_MASK);
return 0;
- } else {
- atomic_dec(&open_count);
- return -EBUSY;
}
+
+ atomic_dec(&open_count);
+ return -EBUSY;
}
static int goldfish_audio_release(struct inode *ip, struct file *fp)
@@ -223,8 +223,8 @@ static long goldfish_audio_ioctl(struct file *fp, unsigned int cmd,
/* temporary workaround, until we switch to the ALSA API */
if (cmd == 315)
return -1;
- else
- return 0;
+
+ return 0;
}
static irqreturn_t goldfish_audio_interrupt(int irq, void *dev_id)
@@ -274,11 +274,9 @@ static int goldfish_audio_probe(struct platform_device *pdev)
struct goldfish_audio *data;
dma_addr_t buf_addr;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL) {
- ret = -ENOMEM;
- goto err_data_alloc_failed;
- }
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
spin_lock_init(&data->lock);
init_waitqueue_head(&data->wait);
platform_set_drvdata(pdev, data);
@@ -286,38 +284,33 @@ static int goldfish_audio_probe(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "platform_get_resource failed\n");
- ret = -ENODEV;
- goto err_no_io_base;
- }
- data->reg_base = ioremap(r->start, PAGE_SIZE);
- if (data->reg_base == NULL) {
- ret = -ENOMEM;
- goto err_no_io_base;
+ return -ENODEV;
}
+ data->reg_base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE);
+ if (data->reg_base == NULL)
+ return -ENOMEM;
data->irq = platform_get_irq(pdev, 0);
if (data->irq < 0) {
dev_err(&pdev->dev, "platform_get_irq failed\n");
- ret = -ENODEV;
- goto err_no_irq;
+ return -ENODEV;
}
- data->buffer_virt = dma_alloc_coherent(&pdev->dev,
+ data->buffer_virt = dmam_alloc_coherent(&pdev->dev,
COMBINED_BUFFER_SIZE, &buf_addr, GFP_KERNEL);
- if (data->buffer_virt == 0) {
- ret = -ENOMEM;
+ if (data->buffer_virt == NULL) {
dev_err(&pdev->dev, "allocate buffer failed\n");
- goto err_alloc_write_buffer_failed;
+ return -ENOMEM;
}
data->buffer_phys = buf_addr;
data->write_buffer1 = data->buffer_virt;
data->write_buffer2 = data->buffer_virt + WRITE_BUFFER_SIZE;
data->read_buffer = data->buffer_virt + 2 * WRITE_BUFFER_SIZE;
- ret = request_irq(data->irq, goldfish_audio_interrupt,
+ ret = devm_request_irq(&pdev->dev, data->irq, goldfish_audio_interrupt,
IRQF_SHARED, pdev->name, data);
if (ret) {
dev_err(&pdev->dev, "request_irq failed\n");
- goto err_request_irq_failed;
+ return ret;
}
ret = misc_register(&goldfish_audio_device);
@@ -325,7 +318,7 @@ static int goldfish_audio_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"misc_register returned %d in goldfish_audio_init\n",
ret);
- goto err_misc_register_failed;
+ return ret;
}
AUDIO_WRITE64(data, AUDIO_SET_WRITE_BUFFER_1,
@@ -344,31 +337,11 @@ static int goldfish_audio_probe(struct platform_device *pdev)
audio_data = data;
return 0;
-
-err_misc_register_failed:
- free_irq(data->irq, data);
-err_request_irq_failed:
- dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
- data->buffer_virt, data->buffer_phys);
-err_alloc_write_buffer_failed:
-err_no_irq:
- iounmap(data->reg_base);
-err_no_io_base:
- kfree(data);
-err_data_alloc_failed:
- return ret;
}
static int goldfish_audio_remove(struct platform_device *pdev)
{
- struct goldfish_audio *data = platform_get_drvdata(pdev);
-
misc_deregister(&goldfish_audio_device);
- free_irq(data->irq, data);
- dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
- data->buffer_virt, data->buffer_phys);
- iounmap(data->reg_base);
- kfree(data);
audio_data = NULL;
return 0;
}
diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index 40d0ecac047f..044ea196aa6f 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -305,9 +305,12 @@ int main(int argc, char **argv)
read_size = read(fp,
data,
toread*scan_size);
- if (read_size == -EAGAIN) {
- printf("nothing available\n");
- continue;
+ if (read_size < 0) {
+ if (errno == -EAGAIN) {
+ printf("nothing available\n");
+ continue;
+ } else
+ break;
}
for (i = 0; i < read_size/scan_size; i++)
process_scan(data + scan_size*i,
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
index 3a9b00087403..569d6f8face5 100644
--- a/drivers/staging/iio/Documentation/iio_event_monitor.c
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -46,6 +46,9 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_TIMESTAMP] = "timestamp",
[IIO_CAPACITANCE] = "capacitance",
[IIO_ALTVOLTAGE] = "altvoltage",
+ [IIO_CCT] = "cct",
+ [IIO_PRESSURE] = "pressure",
+ [IIO_HUMIDITYRELATIVE] = "humidityrelative",
};
static const char * const iio_ev_type_text[] = {
@@ -70,6 +73,8 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
+ [IIO_MOD_LIGHT_BOTH] = "both",
+ [IIO_MOD_LIGHT_IR] = "ir",
[IIO_MOD_LIGHT_CLEAR] = "clear",
[IIO_MOD_LIGHT_RED] = "red",
[IIO_MOD_LIGHT_GREEN] = "green",
@@ -100,6 +105,9 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_TIMESTAMP:
case IIO_CAPACITANCE:
case IIO_ALTVOLTAGE:
+ case IIO_CCT:
+ case IIO_PRESSURE:
+ case IIO_HUMIDITYRELATIVE:
break;
default:
return false;
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index a9cfc06edb01..0973a092224a 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -633,7 +633,7 @@ error_free:
int read_sysfs_float(char *filename, char *basedir, float *val)
{
- float ret = 0;
+ int ret = 0;
FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) {
@@ -653,9 +653,9 @@ error_free:
return ret;
}
-read_sysfs_string(const char *filename, const char *basedir, char *str)
+int read_sysfs_string(const char *filename, const char *basedir, char *str)
{
- float ret = 0;
+ int ret = 0;
FILE *sysfsfp;
char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
if (temp == NULL) {
diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs b/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs
deleted file mode 100644
index 5235e6c749ab..000000000000
--- a/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs
+++ /dev/null
@@ -1,11 +0,0 @@
-What: /sys/bus/iio/devices/triggerX/trigger_now
-KernelVersion: 2.6.38
-Contact: linux-iio@vger.kernel.org
-Description:
- This file is provided by the iio-trig-sysfs stand-alone trigger
- driver. Writing this file with any value triggers an event
- driven driver, associated with this trigger, to capture data
- into an in kernel buffer. This approach can be valuable during
- automated testing or in situations, where other trigger methods
- are not applicable. For example no RTC or spare GPIOs.
- X is the IIO index of the trigger.
diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt
index 64e2e08fb4d0..7c0e505e4f04 100644
--- a/drivers/staging/iio/Documentation/trigger.txt
+++ b/drivers/staging/iio/Documentation/trigger.txt
@@ -31,5 +31,5 @@ consumers.
Trigger Consumers
Currently triggers are only used for the filling of software
-buffers and as such any device supporting INDIO_RING_TRIGGERED has the
+buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the
consumer interface automatically created.
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 2105576fa77c..50ba1fa7f98a 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -131,17 +131,17 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16201_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12),
- ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 0, 12),
+ ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
- ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(7)
};
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 409a28ed9043..f472137b0069 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -99,13 +99,14 @@ static int adis16203_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16203_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12),
- ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12),
+ ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 0, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
/* Fixme: Not what it appears to be - see data sheet */
- ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14),
- ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12),
+ ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y,
+ 0, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index b8ea76857cd6..19eaebc77d7a 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -136,15 +136,15 @@ static int adis16204_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16204_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 12),
- ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12),
- ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 0, 12),
+ ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 0, 12),
+ ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 14),
ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT,
- ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 14),
+ ADIS16204_SCAN_ACC_XY, BIT(IIO_CHAN_INFO_PEAK), 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(5),
};
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 4492e51d8886..374dc6edbcf5 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -130,16 +130,18 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16209_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14),
- ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12),
+ ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 0, 14),
+ ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS), 14),
- ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12),
- ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14),
- ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14),
- ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 14),
+ BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
+ ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 0, 12),
+ ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X,
+ 0, 0, 14),
+ ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y,
+ 0, 0, 14),
+ ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 0, 14),
IIO_CHAN_SOFT_TIMESTAMP(8)
};
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index 3a303a03d028..74ace2a8769d 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -173,15 +173,15 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
}
static const struct iio_chan_spec adis16240_channels[] = {
- ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10),
- ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10),
+ ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 0, 10),
+ ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 0, 10),
ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z,
- BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 10),
- ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10),
+ BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_PEAK), 0, 10),
+ ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 0, 10),
IIO_CHAN_SOFT_TIMESTAMP(6)
};
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 79cefe0a516a..bf33fdead479 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -31,7 +31,7 @@ irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
struct lis3l02dq_state *st = iio_priv(indio_dev);
if (st->trigger_on) {
- iio_trigger_poll(st->trig, iio_get_time_ns());
+ iio_trigger_poll(st->trig);
return IRQ_HANDLED;
} else
return IRQ_WAKE_THREAD;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 198710651e0e..33f0e9235be7 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -141,6 +141,11 @@ static int sca3000_ring_get_bytes_per_datum(struct iio_buffer *r)
return 6;
}
+static bool sca3000_ring_buf_data_available(struct iio_buffer *r)
+{
+ return r->stufftoread;
+}
+
static IIO_BUFFER_ENABLE_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
@@ -274,6 +279,7 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
.read_first_n = &sca3000_read_first_n_hw_rb,
.get_length = &sca3000_ring_get_length,
.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+ .data_available = sca3000_ring_buf_data_available,
.release = sca3000_ring_release,
};
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index b87e382ad768..d01c7076a342 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -3,13 +3,6 @@
#
menu "Analog to digital converters"
-config AD7291
- tristate "Analog Devices AD7291 ADC driver"
- depends on I2C
- help
- Say yes here to build support for Analog Devices AD7291
- 8 Channel ADC with temperature sensor.
-
config AD7606
tristate "Analog Devices AD7606 ADC driver"
depends on GPIOLIB
@@ -94,7 +87,7 @@ config LPC32XX_ADC
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
- depends on ARCH_MXS || COMPILE_TEST
+ depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
depends on INPUT
select STMP_DEVICE
select IIO_BUFFER
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index afdcd1ff08ff..1c4277dbd318 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -8,7 +8,6 @@ ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
-obj-$(CONFIG_AD7291) += ad7291.o
obj-$(CONFIG_AD7780) += ad7780.o
obj-$(CONFIG_AD7816) += ad7816.o
obj-$(CONFIG_AD7192) += ad7192.o
diff --git a/drivers/staging/iio/adc/ad7291.h b/drivers/staging/iio/adc/ad7291.h
deleted file mode 100644
index bbd89fa51188..000000000000
--- a/drivers/staging/iio/adc/ad7291.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __IIO_AD7291_H__
-#define __IIO_AD7291_H__
-
-/**
- * struct ad7291_platform_data - AD7291 platform data
- * @use_external_ref: Whether to use an external or internal reference voltage
- */
-struct ad7291_platform_data {
- bool use_external_ref;
-};
-
-#endif
diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c
index 8a48d18de788..7511839ba94e 100644
--- a/drivers/staging/iio/adc/ad7606_par.c
+++ b/drivers/staging/iio/adc/ad7606_par.c
@@ -53,7 +53,7 @@ static int ad7606_par_probe(struct platform_device *pdev)
struct iio_dev *indio_dev;
void __iomem *addr;
resource_size_t remap_size;
- int ret, irq;
+ int irq;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -62,56 +62,31 @@ static int ad7606_par_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -ENODEV;
+ addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(addr))
+ return PTR_ERR(addr);
remap_size = resource_size(res);
- /* Request the regions */
- if (!request_mem_region(res->start, remap_size, "iio-ad7606")) {
- ret = -EBUSY;
- goto out1;
- }
- addr = ioremap(res->start, remap_size);
- if (!addr) {
- ret = -ENOMEM;
- goto out1;
- }
-
indio_dev = ad7606_probe(&pdev->dev, irq, addr,
platform_get_device_id(pdev)->driver_data,
remap_size > 1 ? &ad7606_par16_bops :
&ad7606_par8_bops);
- if (IS_ERR(indio_dev)) {
- ret = PTR_ERR(indio_dev);
- goto out2;
- }
+ if (IS_ERR(indio_dev))
+ return PTR_ERR(indio_dev);
platform_set_drvdata(pdev, indio_dev);
return 0;
-
-out2:
- iounmap(addr);
-out1:
- release_mem_region(res->start, remap_size);
-
- return ret;
}
static int ad7606_par_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
- struct resource *res;
- struct ad7606_state *st = iio_priv(indio_dev);
ad7606_remove(indio_dev, platform_get_irq(pdev, 0));
- iounmap(st->base_address);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, resource_size(res));
-
return 0;
}
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 52d7517b342e..468327f4a753 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -1170,7 +1170,7 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
mxs_lradc_handle_touch(lradc);
if (iio_buffer_enabled(iio))
- iio_trigger_poll(iio->trig, iio_get_time_ns());
+ iio_trigger_poll(iio->trig);
else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
complete(&lradc->completion);
diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c
index c7d0307c8e76..cf68159a5848 100644
--- a/drivers/staging/iio/frequency/ad9832.c
+++ b/drivers/staging/iio/frequency/ad9832.c
@@ -57,7 +57,7 @@ static int ad9832_write_frequency(struct ad9832_state *st,
}
static int ad9832_write_phase(struct ad9832_state *st,
- unsigned long addr, unsigned long phase)
+ unsigned long addr, unsigned long phase)
{
if (phase > (1 << AD9832_PHASE_BITS))
return -EINVAL;
@@ -72,10 +72,8 @@ static int ad9832_write_phase(struct ad9832_state *st,
return spi_sync(st->spi, &st->phase_msg);
}
-static ssize_t ad9832_write(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
+static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad9832_state *st = iio_priv(indio_dev);
@@ -109,11 +107,11 @@ static ssize_t ad9832_write(struct device *dev,
ret = spi_sync(st->spi, &st->msg);
break;
case AD9832_FREQ_SYM:
- if (val == 1)
+ if (val == 1) {
st->ctrl_fp |= AD9832_FREQ;
- else if (val == 0)
+ } else if (val == 0) {
st->ctrl_fp &= ~AD9832_FREQ;
- else {
+ } else {
ret = -EINVAL;
break;
}
@@ -122,7 +120,7 @@ static ssize_t ad9832_write(struct device *dev,
ret = spi_sync(st->spi, &st->msg);
break;
case AD9832_PHASE_SYM:
- if (val < 0 || val > 3) {
+ if (val > 3) {
ret = -EINVAL;
break;
}
diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c
index af877ff680e9..8727933cafcf 100644
--- a/drivers/staging/iio/frequency/ad9850.c
+++ b/drivers/staging/iio/frequency/ad9850.c
@@ -21,9 +21,6 @@
#define DRV_NAME "ad9850"
-#define value_mask (u16)0xf000
-#define addr_shift 12
-
/* Register format: 4 bits addr + 12 bits value */
struct ad9850_config {
u8 control[5];
@@ -50,9 +47,6 @@ static ssize_t ad9850_set_parameter(struct device *dev,
mutex_lock(&st->lock);
ret = spi_sync_transfer(st->sdev, &xfer, 1);
- if (ret)
- goto error_ret;
-error_ret:
mutex_unlock(&st->lock);
return ret ? ret : len;
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index fd334a03a49a..bf78e6f0311f 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -550,6 +550,7 @@ error_ret:
static __init int iio_dummy_init(void)
{
int i, ret;
+
if (instances > 10) {
instances = 1;
return -EINVAL;
@@ -577,6 +578,7 @@ module_init(iio_dummy_init);
static __exit void iio_dummy_exit(void)
{
int i;
+
for (i = 0; i < instances; i++)
iio_dummy_remove(i);
kfree(iio_dummy_devs);
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 34634da1f9f7..dec814a7a073 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -4,15 +4,37 @@
menu "Magnetometer sensors"
config SENSORS_HMC5843
- tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
- depends on I2C
+ tristate
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
+
+config SENSORS_HMC5843_I2C
+ tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer (I2C)"
+ depends on I2C
+ select SENSORS_HMC5843
+ select REGMAP_I2C
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
- To compile this driver as a module, choose M here: the module
- will be called hmc5843.
+ This driver can also be compiled as a set of modules.
+ If so, these modules will be created:
+ - hmc5843_core (core functions)
+ - hmc5843_i2c (support for HMC5843, HMC5883, HMC5883L and HMC5983)
+
+config SENSORS_HMC5843_SPI
+ tristate "Honeywell HMC5983 3-Axis Magnetometer (SPI)"
+ depends on SPI_MASTER
+ select SENSORS_HMC5843
+ select REGMAP_SPI
+ help
+ Say Y here to add support for the Honeywell HMC5983 3-Axis Magnetometer
+ (digital compass).
+
+ This driver can also be compiled as a set of modules.
+ If so, these modules will be created:
+ - hmc5843_core (core functions)
+ - hmc5843_spi (support for HMC5983)
+
endmenu
diff --git a/drivers/staging/iio/magnetometer/Makefile b/drivers/staging/iio/magnetometer/Makefile
index f9bfb2e11d7d..33761a19a956 100644
--- a/drivers/staging/iio/magnetometer/Makefile
+++ b/drivers/staging/iio/magnetometer/Makefile
@@ -2,4 +2,6 @@
# Makefile for industrial I/O Magnetometer sensors
#
-obj-$(CONFIG_SENSORS_HMC5843) += hmc5843.o
+obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o
+obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o
+obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o
diff --git a/drivers/staging/iio/magnetometer/hmc5843.h b/drivers/staging/iio/magnetometer/hmc5843.h
new file mode 100644
index 000000000000..b784e3eb4591
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843.h
@@ -0,0 +1,59 @@
+/*
+ * Header file for hmc5843 driver
+ *
+ * Split from hmc5843.c
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * 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.
+ *
+ * */
+
+
+#ifndef HMC5843_CORE_H
+#define HMC5843_CORE_H
+
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+
+#define HMC5843_CONFIG_REG_A 0x00
+#define HMC5843_CONFIG_REG_B 0x01
+#define HMC5843_MODE_REG 0x02
+#define HMC5843_DATA_OUT_MSB_REGS 0x03
+#define HMC5843_STATUS_REG 0x09
+#define HMC5843_ID_REG 0x0a
+#define HMC5843_ID_END 0x0c
+
+enum hmc5843_ids {
+ HMC5843_ID,
+ HMC5883_ID,
+ HMC5883L_ID,
+ HMC5983_ID,
+};
+
+struct hmc5843_data {
+ struct device *dev;
+ struct mutex lock;
+ struct regmap *regmap;
+ const struct hmc5843_chip_info *variant;
+ __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
+};
+
+int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
+ enum hmc5843_ids id);
+int hmc5843_common_remove(struct device *dev);
+
+int hmc5843_common_suspend(struct device *dev);
+int hmc5843_common_resume(struct device *dev);
+
+#ifdef CONFIG_PM_SLEEP
+static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops,
+ hmc5843_common_suspend,
+ hmc5843_common_resume);
+#define HMC5843_PM_OPS (&hmc5843_pm_ops)
+#else
+#define HMC5843_PM_OPS NULL
+#endif
+
+#endif /* HMC5843_CORE_H */
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843_core.c
index d4f4dd90c699..914ae1acd31d 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843_core.c
@@ -4,6 +4,8 @@
Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
+ Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
+
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
@@ -20,7 +22,7 @@
*/
#include <linux/module.h>
-#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger_consumer.h>
@@ -28,18 +30,7 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/delay.h>
-#define HMC5843_CONFIG_REG_A 0x00
-#define HMC5843_CONFIG_REG_B 0x01
-#define HMC5843_MODE_REG 0x02
-#define HMC5843_DATA_OUT_MSB_REGS 0x03
-#define HMC5843_STATUS_REG 0x09
-#define HMC5843_ID_REG 0x0a
-
-enum hmc5843_ids {
- HMC5843_ID,
- HMC5883_ID,
- HMC5883L_ID,
-};
+#include "hmc5843.h"
/*
* Range gain settings in (+-)Ga
@@ -48,7 +39,7 @@ enum hmc5843_ids {
*/
#define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01
-#define HMC5843_RANGE_GAINS 8
+#define HMC5843_RANGE_GAIN_MASK 0xe0
/* Device status */
#define HMC5843_DATA_READY 0x01
@@ -67,7 +58,7 @@ enum hmc5843_ids {
*/
#define HMC5843_RATE_OFFSET 0x02
#define HMC5843_RATE_DEFAULT 0x04
-#define HMC5843_RATES 7
+#define HMC5843_RATE_MASK 0x1c
/* Device measurement configuration */
#define HMC5843_MEAS_CONF_NORMAL 0x00
@@ -76,15 +67,15 @@ enum hmc5843_ids {
#define HMC5843_MEAS_CONF_MASK 0x03
/* Scaling factors: 10000000/Gain */
-static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5843_regval_to_nanoscale[] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
};
-static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883_regval_to_nanoscale[] = {
7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
};
-static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
+static const int hmc5883l_regval_to_nanoscale[] = {
7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
};
@@ -101,32 +92,27 @@ static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
* 6 | 50 | 75
* 7 | Not used | Not used
*/
-static const int hmc5843_regval_to_samp_freq[7][2] = {
+static const int hmc5843_regval_to_samp_freq[][2] = {
{0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
};
-static const int hmc5883_regval_to_samp_freq[7][2] = {
+static const int hmc5883_regval_to_samp_freq[][2] = {
{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
{75, 0}
};
+static const int hmc5983_regval_to_samp_freq[][2] = {
+ {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
+ {75, 0}, {220, 0}
+};
+
/* Describe chip variants */
struct hmc5843_chip_info {
const struct iio_chan_spec *channels;
const int (*regval_to_samp_freq)[2];
+ const int n_regval_to_samp_freq;
const int *regval_to_nanoscale;
-};
-
-/* Each client has this additional data */
-struct hmc5843_data {
- struct i2c_client *client;
- struct mutex lock;
- u8 rate;
- u8 meas_conf;
- u8 operating_mode;
- u8 range;
- const struct hmc5843_chip_info *variant;
- __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
+ const int n_regval_to_nanoscale;
};
/* The lower two bits contain the current conversion mode */
@@ -135,10 +121,8 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
- operating_mode & HMC5843_MODE_MASK);
- if (ret >= 0)
- data->operating_mode = operating_mode;
+ ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
+ HMC5843_MODE_MASK, operating_mode);
mutex_unlock(&data->lock);
return ret;
@@ -146,21 +130,21 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
static int hmc5843_wait_measurement(struct hmc5843_data *data)
{
- s32 result;
int tries = 150;
+ int val;
+ int ret;
while (tries-- > 0) {
- result = i2c_smbus_read_byte_data(data->client,
- HMC5843_STATUS_REG);
- if (result < 0)
- return result;
- if (result & HMC5843_DATA_READY)
+ ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
+ if (ret < 0)
+ return ret;
+ if (val & HMC5843_DATA_READY)
break;
msleep(20);
}
if (tries < 0) {
- dev_err(&data->client->dev, "data not ready\n");
+ dev_err(data->dev, "data not ready\n");
return -EIO;
}
@@ -171,20 +155,20 @@ static int hmc5843_wait_measurement(struct hmc5843_data *data)
static int hmc5843_read_measurement(struct hmc5843_data *data,
int idx, int *val)
{
- s32 result;
__be16 values[3];
+ int ret;
mutex_lock(&data->lock);
- result = hmc5843_wait_measurement(data);
- if (result < 0) {
+ ret = hmc5843_wait_measurement(data);
+ if (ret < 0) {
mutex_unlock(&data->lock);
- return result;
+ return ret;
}
- result = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ values, sizeof(values));
mutex_unlock(&data->lock);
- if (result < 0)
- return -EINVAL;
+ if (ret < 0)
+ return ret;
*val = sign_extend32(be16_to_cpu(values[idx]), 15);
return IIO_VAL_INT;
@@ -208,16 +192,13 @@ static int hmc5843_read_measurement(struct hmc5843_data *data,
* and BN.
*
*/
-static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
+static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
{
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- (meas_conf & HMC5843_MEAS_CONF_MASK) |
- (data->rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->meas_conf = meas_conf;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_MEAS_CONF_MASK, meas_conf);
mutex_unlock(&data->lock);
return ret;
@@ -228,7 +209,15 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
char *buf)
{
struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- return sprintf(buf, "%d\n", data->meas_conf);
+ int val;
+ int ret;
+
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
+ if (ret)
+ return ret;
+ val &= HMC5843_MEAS_CONF_MASK;
+
+ return sprintf(buf, "%d\n", val);
}
static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
@@ -264,7 +253,7 @@ static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
size_t len = 0;
int i;
- for (i = 0; i < HMC5843_RATES; i++)
+ for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
len += scnprintf(buf + len, PAGE_SIZE - len,
"%d.%d ", data->variant->regval_to_samp_freq[i][0],
data->variant->regval_to_samp_freq[i][1]);
@@ -282,10 +271,8 @@ static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- data->meas_conf | (rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->rate = rate;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_RATE_MASK, rate << HMC5843_RATE_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -296,7 +283,7 @@ static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
{
int i;
- for (i = 0; i < HMC5843_RATES; i++)
+ for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
if (val == data->variant->regval_to_samp_freq[i][0] &&
val2 == data->variant->regval_to_samp_freq[i][1])
return i;
@@ -309,10 +296,9 @@ static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
- range << HMC5843_RANGE_GAIN_OFFSET);
- if (ret >= 0)
- data->range = range;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
+ HMC5843_RANGE_GAIN_MASK,
+ range << HMC5843_RANGE_GAIN_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -326,7 +312,7 @@ static ssize_t hmc5843_show_scale_avail(struct device *dev,
size_t len = 0;
int i;
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
len += scnprintf(buf + len, PAGE_SIZE - len,
"0.%09d ", data->variant->regval_to_nanoscale[i]);
@@ -346,7 +332,7 @@ static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
if (val != 0)
return -EINVAL;
- for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+ for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
if (val2 == data->variant->regval_to_nanoscale[i])
return i;
@@ -358,17 +344,27 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
+ int rval;
+ int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
return hmc5843_read_measurement(data, chan->scan_index, val);
case IIO_CHAN_INFO_SCALE:
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RANGE_GAIN_OFFSET;
*val = 0;
- *val2 = data->variant->regval_to_nanoscale[data->range];
+ *val2 = data->variant->regval_to_nanoscale[rval];
return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_SAMP_FREQ:
- *val = data->variant->regval_to_samp_freq[data->rate][0];
- *val2 = data->variant->regval_to_samp_freq[data->rate][1];
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RATE_OFFSET;
+ *val = data->variant->regval_to_samp_freq[rval][0];
+ *val2 = data->variant->regval_to_samp_freq[rval][1];
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
@@ -426,9 +422,9 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
goto done;
}
- ret = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
- (u8 *) data->buffer);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ data->buffer, 3 * sizeof(__be16));
+
mutex_unlock(&data->lock);
if (ret < 0)
goto done;
@@ -466,7 +462,7 @@ static const struct iio_chan_spec hmc5843_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
-/* Beware: Y and Z are exchanged on HMC5883 */
+/* Beware: Y and Z are exchanged on HMC5883 and 5983 */
static const struct iio_chan_spec hmc5883_channels[] = {
HMC5843_CHANNEL(X, 0),
HMC5843_CHANNEL(Z, 1),
@@ -489,18 +485,39 @@ static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
[HMC5843_ID] = {
.channels = hmc5843_channels,
.regval_to_samp_freq = hmc5843_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5843_regval_to_samp_freq),
.regval_to_nanoscale = hmc5843_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5843_regval_to_nanoscale),
},
[HMC5883_ID] = {
.channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5883_regval_to_samp_freq),
.regval_to_nanoscale = hmc5883_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883_regval_to_nanoscale),
},
[HMC5883L_ID] = {
.channels = hmc5883_channels,
.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5883_regval_to_samp_freq),
.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
},
+ [HMC5983_ID] = {
+ .channels = hmc5883_channels,
+ .regval_to_samp_freq = hmc5983_regval_to_samp_freq,
+ .n_regval_to_samp_freq =
+ ARRAY_SIZE(hmc5983_regval_to_samp_freq),
+ .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
+ .n_regval_to_nanoscale =
+ ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
+ }
};
static int hmc5843_init(struct hmc5843_data *data)
@@ -508,12 +525,12 @@ static int hmc5843_init(struct hmc5843_data *data)
int ret;
u8 id[3];
- ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
- sizeof(id), id);
+ ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
+ id, ARRAY_SIZE(id));
if (ret < 0)
return ret;
if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
- dev_err(&data->client->dev, "no HMC5843/5883/5883L sensor\n");
+ dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");
return -ENODEV;
}
@@ -539,27 +556,43 @@ static const struct iio_info hmc5843_info = {
static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
-static int hmc5843_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+
+int hmc5843_common_suspend(struct device *dev)
+{
+ return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
+ HMC5843_MODE_CONVERSION_CONTINUOUS);
+}
+EXPORT_SYMBOL(hmc5843_common_suspend);
+
+int hmc5843_common_resume(struct device *dev)
+{
+ return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
+ HMC5843_MODE_SLEEP);
+}
+EXPORT_SYMBOL(hmc5843_common_resume);
+
+int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
+ enum hmc5843_ids id)
{
struct hmc5843_data *data;
struct iio_dev *indio_dev;
int ret;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (indio_dev == NULL)
return -ENOMEM;
+ dev_set_drvdata(dev, indio_dev);
+
/* default settings at probe */
data = iio_priv(indio_dev);
- data->client = client;
- data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+ data->dev = dev;
+ data->regmap = regmap;
+ data->variant = &hmc5843_chip_info_tbl[id];
mutex_init(&data->lock);
- i2c_set_clientdata(client, indio_dev);
+ indio_dev->dev.parent = dev;
indio_dev->info = &hmc5843_info;
- indio_dev->name = id->name;
- indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->variant->channels;
indio_dev->num_channels = 4;
@@ -584,10 +617,11 @@ buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
return ret;
}
+EXPORT_SYMBOL(hmc5843_common_probe);
-static int hmc5843_remove(struct i2c_client *client)
+int hmc5843_common_remove(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
@@ -597,56 +631,8 @@ static int hmc5843_remove(struct i2c_client *client)
return 0;
}
-
-#ifdef CONFIG_PM_SLEEP
-static int hmc5843_suspend(struct device *dev)
-{
- struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
-
- return hmc5843_set_mode(data, HMC5843_MODE_SLEEP);
-}
-
-static int hmc5843_resume(struct device *dev)
-{
- struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
- to_i2c_client(dev)));
-
- return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
-}
-
-static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
-#define HMC5843_PM_OPS (&hmc5843_pm_ops)
-#else
-#define HMC5843_PM_OPS NULL
-#endif
-
-static const struct i2c_device_id hmc5843_id[] = {
- { "hmc5843", HMC5843_ID },
- { "hmc5883", HMC5883_ID },
- { "hmc5883l", HMC5883L_ID },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, hmc5843_id);
-
-static const struct of_device_id hmc5843_of_match[] = {
- { .compatible = "honeywell,hmc5843" },
- {}
-};
-MODULE_DEVICE_TABLE(of, hmc5843_of_match);
-
-static struct i2c_driver hmc5843_driver = {
- .driver = {
- .name = "hmc5843",
- .pm = HMC5843_PM_OPS,
- .of_match_table = hmc5843_of_match,
- },
- .id_table = hmc5843_id,
- .probe = hmc5843_probe,
- .remove = hmc5843_remove,
-};
-module_i2c_driver(hmc5843_driver);
+EXPORT_SYMBOL(hmc5843_common_remove);
MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
-MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
+MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_i2c.c b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
new file mode 100644
index 000000000000..6acd614cdbc6
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843_i2c.c
@@ -0,0 +1,104 @@
+/*
+ * i2c driver for hmc5843/5843/5883/5883l/5983
+ *
+ * Split from hmc5843.c
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * 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/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include "hmc5843.h"
+
+static const struct regmap_range hmc5843_readable_ranges[] = {
+ regmap_reg_range(0, HMC5843_ID_END),
+};
+
+static struct regmap_access_table hmc5843_readable_table = {
+ .yes_ranges = hmc5843_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
+};
+
+static const struct regmap_range hmc5843_writable_ranges[] = {
+ regmap_reg_range(0, HMC5843_MODE_REG),
+};
+
+static struct regmap_access_table hmc5843_writable_table = {
+ .yes_ranges = hmc5843_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
+};
+
+static const struct regmap_range hmc5843_volatile_ranges[] = {
+ regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
+};
+
+static struct regmap_access_table hmc5843_volatile_table = {
+ .yes_ranges = hmc5843_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
+};
+
+static struct regmap_config hmc5843_i2c_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .rd_table = &hmc5843_readable_table,
+ .wr_table = &hmc5843_writable_table,
+ .volatile_table = &hmc5843_volatile_table,
+
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int hmc5843_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return hmc5843_common_probe(&client->dev,
+ devm_regmap_init_i2c(client, &hmc5843_i2c_regmap_config),
+ id->driver_data);
+}
+
+static int hmc5843_i2c_remove(struct i2c_client *client)
+{
+ return hmc5843_common_remove(&client->dev);
+}
+
+static const struct i2c_device_id hmc5843_id[] = {
+ { "hmc5843", HMC5843_ID },
+ { "hmc5883", HMC5883_ID },
+ { "hmc5883l", HMC5883L_ID },
+ { "hmc5983", HMC5983_ID },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, hmc5843_id);
+
+static const struct of_device_id hmc5843_of_match[] = {
+ { .compatible = "honeywell,hmc5843", .data = (void *)HMC5843_ID },
+ { .compatible = "honeywell,hmc5883", .data = (void *)HMC5883_ID },
+ { .compatible = "honeywell,hmc5883l", .data = (void *)HMC5883L_ID },
+ { .compatible = "honeywell,hmc5983", .data = (void *)HMC5983_ID },
+ {}
+};
+MODULE_DEVICE_TABLE(of, hmc5843_of_match);
+
+static struct i2c_driver hmc5843_driver = {
+ .driver = {
+ .name = "hmc5843",
+ .pm = HMC5843_PM_OPS,
+ .of_match_table = hmc5843_of_match,
+ },
+ .id_table = hmc5843_id,
+ .probe = hmc5843_i2c_probe,
+ .remove = hmc5843_i2c_remove,
+};
+module_i2c_driver(hmc5843_driver);
+
+MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
+MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 i2c driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/magnetometer/hmc5843_spi.c b/drivers/staging/iio/magnetometer/hmc5843_spi.c
new file mode 100644
index 000000000000..98c4b57101c9
--- /dev/null
+++ b/drivers/staging/iio/magnetometer/hmc5843_spi.c
@@ -0,0 +1,100 @@
+/*
+ * SPI driver for hmc5983
+ *
+ * Copyright (C) Josef Gajdusek <atx@atx.name>
+ *
+ * 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/module.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+
+#include "hmc5843.h"
+
+static const struct regmap_range hmc5843_readable_ranges[] = {
+ regmap_reg_range(0, HMC5843_ID_END),
+};
+
+static struct regmap_access_table hmc5843_readable_table = {
+ .yes_ranges = hmc5843_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
+};
+
+static const struct regmap_range hmc5843_writable_ranges[] = {
+ regmap_reg_range(0, HMC5843_MODE_REG),
+};
+
+static struct regmap_access_table hmc5843_writable_table = {
+ .yes_ranges = hmc5843_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
+};
+
+static const struct regmap_range hmc5843_volatile_ranges[] = {
+ regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
+};
+
+static struct regmap_access_table hmc5843_volatile_table = {
+ .yes_ranges = hmc5843_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
+};
+
+static struct regmap_config hmc5843_spi_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .rd_table = &hmc5843_readable_table,
+ .wr_table = &hmc5843_writable_table,
+ .volatile_table = &hmc5843_volatile_table,
+
+ /* Autoincrement address pointer */
+ .read_flag_mask = 0xc0,
+
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int hmc5843_spi_probe(struct spi_device *spi)
+{
+ int ret;
+
+ spi->mode = SPI_MODE_3;
+ spi->max_speed_hz = 8000000;
+ spi->bits_per_word = 8;
+ ret = spi_setup(spi);
+ if (ret)
+ return ret;
+
+ return hmc5843_common_probe(&spi->dev,
+ devm_regmap_init_spi(spi, &hmc5843_spi_regmap_config),
+ HMC5983_ID);
+}
+
+static int hmc5843_spi_remove(struct spi_device *spi)
+{
+ return hmc5843_common_remove(&spi->dev);
+}
+
+static const struct spi_device_id hmc5843_id[] = {
+ { "hmc5983", HMC5983_ID },
+ { }
+};
+
+static struct spi_driver hmc5843_driver = {
+ .driver = {
+ .name = "hmc5843",
+ .pm = HMC5843_PM_OPS,
+ .owner = THIS_MODULE,
+ },
+ .id_table = hmc5843_id,
+ .probe = hmc5843_spi_probe,
+ .remove = hmc5843_spi_remove,
+};
+
+module_spi_driver(hmc5843_driver);
+
+MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
+MODULE_DESCRIPTION("HMC5983 SPI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c
index 7a94ddd42f59..ea01b8f7a2c3 100644
--- a/drivers/staging/iio/meter/ade7758_trigger.c
+++ b/drivers/staging/iio/meter/ade7758_trigger.c
@@ -21,7 +21,7 @@
static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
{
disable_irq_nosync(irq);
- iio_trigger_poll(private, iio_get_time_ns());
+ iio_trigger_poll(private);
return IRQ_HANDLED;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 26e1ca0b7800..a21b7c514776 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -154,7 +154,7 @@ static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
struct bfin_tmr_state *st = devid;
clear_gptimer_intr(st->t->id);
- iio_trigger_poll(st->trig, 0);
+ iio_trigger_poll(st->trig);
return IRQ_HANDLED;
}
@@ -182,45 +182,40 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
unsigned int config;
int ret;
- st = kzalloc(sizeof(*st), GFP_KERNEL);
- if (st == NULL) {
- ret = -ENOMEM;
- goto out;
- }
+ st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
st->irq = platform_get_irq(pdev, 0);
if (!st->irq) {
dev_err(&pdev->dev, "No IRQs specified");
- ret = -ENODEV;
- goto out1;
+ return -ENODEV;
}
ret = iio_bfin_tmr_get_number(st->irq);
if (ret < 0)
- goto out1;
+ return ret;
st->timer_num = ret;
st->t = &iio_bfin_timer_code[st->timer_num];
st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num);
- if (!st->trig) {
- ret = -ENOMEM;
- goto out1;
- }
+ if (!st->trig)
+ return -ENOMEM;
st->trig->ops = &iio_bfin_tmr_trigger_ops;
st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
iio_trigger_set_drvdata(st->trig, st);
ret = iio_trigger_register(st->trig);
if (ret)
- goto out2;
+ goto out;
ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
0, st->trig->name, st);
if (ret) {
dev_err(&pdev->dev,
"request IRQ-%d failed", st->irq);
- goto out4;
+ goto out1;
}
config = PWM_OUT | PERIOD_CNT | IRQ_ENA;
@@ -260,13 +255,10 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
return 0;
out_free_irq:
free_irq(st->irq, st);
-out4:
- iio_trigger_unregister(st->trig);
-out2:
- iio_trigger_put(st->trig);
out1:
- kfree(st);
+ iio_trigger_unregister(st->trig);
out:
+ iio_trigger_put(st->trig);
return ret;
}
@@ -280,7 +272,6 @@ static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
free_irq(st->irq, st);
iio_trigger_unregister(st->trig);
iio_trigger_put(st->trig);
- kfree(st);
return 0;
}
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
index 38ecb4bb6e4c..b1aeb88273c9 100644
--- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -26,16 +26,22 @@ struct iio_prtc_trigger_info {
struct rtc_device *rtc;
int frequency;
struct rtc_task task;
+ bool state;
};
static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state)
{
struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
- if (trig_info->frequency == 0)
+ int ret;
+ if (trig_info->frequency == 0 && state)
return -EINVAL;
- dev_info(&trig_info->rtc->dev, "trigger frequency is %d\n",
+ dev_dbg(&trig_info->rtc->dev, "trigger frequency is %d\n",
trig_info->frequency);
- return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
+ if (ret == 0)
+ trig_info->state = state;
+
+ return ret;
}
static ssize_t iio_trig_periodic_read_freq(struct device *dev,
@@ -61,7 +67,14 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
if (ret)
goto error_ret;
- ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
+ if (val > 0) {
+ ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
+ if (ret == 0 && trig_info->state && trig_info->frequency == 0)
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 1);
+ } else if (val == 0) {
+ ret = rtc_irq_set_state(trig_info->rtc, &trig_info->task, 0);
+ } else
+ ret = -EINVAL;
if (ret)
goto error_ret;
@@ -93,8 +106,7 @@ static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
static void iio_prtc_trigger_poll(void *private_data)
{
- /* Timestamp is not provided currently */
- iio_trigger_poll(private_data, 0);
+ iio_trigger_poll(private_data);
}
static const struct iio_trigger_ops iio_prtc_trigger_ops = {
@@ -128,8 +140,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
iio_trigger_set_drvdata(trig, trig_info);
trig->ops = &iio_prtc_trigger_ops;
/* RTC access */
- trig_info->rtc
- = rtc_class_open(pdata[i]);
+ trig_info->rtc = rtc_class_open(pdata[i]);
if (trig_info->rtc == NULL) {
ret = -EINVAL;
goto error_free_trig_info;
@@ -199,5 +210,5 @@ static struct platform_driver iio_trig_periodic_rtc_driver = {
module_platform_driver(iio_trig_periodic_rtc_driver);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
+MODULE_DESCRIPTION("Periodic realtime clock trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
index def8280d7ee6..6b22106534d8 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
@@ -202,7 +202,7 @@ static const struct file_operations imx_drm_driver_fops = {
void imx_drm_connector_destroy(struct drm_connector *connector)
{
- drm_sysfs_connector_remove(connector);
+ drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
EXPORT_SYMBOL_GPL(imx_drm_connector_destroy);
@@ -293,10 +293,10 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
* userspace will expect to be able to access DRM at this point.
*/
list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
- ret = drm_sysfs_connector_add(connector);
+ ret = drm_connector_register(connector);
if (ret) {
dev_err(drm->dev,
- "[CONNECTOR:%d:%s] drm_sysfs_connector_add failed: %d\n",
+ "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
connector->base.id,
connector->name, ret);
goto err_unbind;
@@ -570,22 +570,6 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == np;
}
-static LIST_HEAD(imx_drm_components);
-
-static int imx_drm_add_components(struct device *master, struct master *m)
-{
- struct imx_drm_component *component;
- int ret;
-
- list_for_each_entry(component, &imx_drm_components, list) {
- ret = component_master_add_child(m, compare_of,
- component->of_node);
- if (ret)
- return ret;
- }
- return 0;
-}
-
static int imx_drm_bind(struct device *dev)
{
return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
@@ -597,43 +581,14 @@ static void imx_drm_unbind(struct device *dev)
}
static const struct component_master_ops imx_drm_ops = {
- .add_components = imx_drm_add_components,
.bind = imx_drm_bind,
.unbind = imx_drm_unbind,
};
-static struct imx_drm_component *imx_drm_find_component(struct device *dev,
- struct device_node *node)
-{
- struct imx_drm_component *component;
-
- list_for_each_entry(component, &imx_drm_components, list)
- if (component->of_node == node)
- return component;
-
- return NULL;
-}
-
-static int imx_drm_add_component(struct device *dev, struct device_node *node)
-{
- struct imx_drm_component *component;
-
- if (imx_drm_find_component(dev, node))
- return 0;
-
- component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
- if (!component)
- return -ENOMEM;
-
- component->of_node = node;
- list_add_tail(&component->list, &imx_drm_components);
-
- return 0;
-}
-
static int imx_drm_platform_probe(struct platform_device *pdev)
{
struct device_node *ep, *port, *remote;
+ struct component_match *match = NULL;
int ret;
int i;
@@ -647,9 +602,7 @@ static int imx_drm_platform_probe(struct platform_device *pdev)
if (!port)
break;
- ret = imx_drm_add_component(&pdev->dev, port);
- if (ret < 0)
- return ret;
+ component_match_add(&pdev->dev, &match, compare_of, port);
}
if (i == 0) {
@@ -675,10 +628,8 @@ static int imx_drm_platform_probe(struct platform_device *pdev)
continue;
}
- ret = imx_drm_add_component(&pdev->dev, remote);
+ component_match_add(&pdev->dev, &match, compare_of, remote);
of_node_put(remote);
- if (ret < 0)
- return ret;
}
of_node_put(port);
}
@@ -687,7 +638,7 @@ static int imx_drm_platform_probe(struct platform_device *pdev)
if (ret)
return ret;
- return component_master_add(&pdev->dev, &imx_drm_ops);
+ return component_master_add_with_match(&pdev->dev, &imx_drm_ops, match);
}
static int imx_drm_platform_remove(struct platform_device *pdev)
diff --git a/drivers/staging/keucr/Kconfig b/drivers/staging/keucr/Kconfig
deleted file mode 100644
index ba756bf20665..000000000000
--- a/drivers/staging/keucr/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-config USB_ENESTORAGE
- tristate "USB ENE SM card reader support"
- depends on USB && SCSI && m
- ---help---
- Say Y here if you wish to control a ENE SM Card reader.
- To use SD/MS card, please build driver/usb/storage/ums-eneub6250.ko
-
- This option depends on 'SCSI' support being enabled, but you
- probably also need 'SCSI device support: SCSI disk support'
- (BLK_DEV_SD) for most USB storage devices.
-
- To compile this driver as a module, choose M here: the
- module will be called keucr.
-
diff --git a/drivers/staging/keucr/Makefile b/drivers/staging/keucr/Makefile
deleted file mode 100644
index c180bf4fab93..000000000000
--- a/drivers/staging/keucr/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-ccflags-y := -Idrivers/scsi
-
-obj-$(CONFIG_USB_ENESTORAGE) += keucr.o
-
-keucr-y := \
- usb.o \
- scsiglue.o \
- transport.o \
- init.o \
- smscsi.o \
- smilmain.o \
- smilsub.o \
- smilecc.o
diff --git a/drivers/staging/keucr/TODO b/drivers/staging/keucr/TODO
deleted file mode 100644
index d6da656eee1d..000000000000
--- a/drivers/staging/keucr/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
- - checkpatch.pl clean
- - sparse clean
- - determine if the driver should not be using a duplicate
- version of the usb-storage scsi interface code, but should
- be merged into the drivers/usb/storage/ directory and
- infrastructure instead.
- - review by the USB developer community
- - smcommon.h & smilsub.c: use kernel hweight8(), hweight16()
-
-Please send any patches for this driver to Al Cho <acho@novell.com> and
-Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
diff --git a/drivers/staging/keucr/common.h b/drivers/staging/keucr/common.h
deleted file mode 100644
index f0b977616cd5..000000000000
--- a/drivers/staging/keucr/common.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef COMMON_INCD
-#define COMMON_INCD
-
-#define BYTE_MASK 0xff
-
-#endif
-
diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c
deleted file mode 100644
index 1e7449d6d120..000000000000
--- a/drivers/staging/keucr/init.c
+++ /dev/null
@@ -1,333 +0,0 @@
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_device.h>
-
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-#include "smil.h"
-#include "init.h"
-
-/*
- * ENE_InitMedia():
- */
-int ENE_InitMedia(struct us_data *us)
-{
- int result;
- u8 MiscReg03 = 0;
-
- dev_info(&us->pusb_dev->dev, "--- Init Media ---\n");
- result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev, "Failed to read register\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
- dev_info(&us->pusb_dev->dev, "MiscReg03 = %x\n", MiscReg03);
-
- if (MiscReg03 & 0x02) {
- if (!us->SM_Status.Ready && !us->MS_Status.Ready) {
- result = ENE_SMInit(us);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- }
- return result;
-}
-
-/*
- * ene_read_byte() :
- */
-int ene_read_byte(struct us_data *us, u16 index, void *buf)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x01;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xED;
- bcb->CDB[2] = (u8)(index>>8);
- bcb->CDB[3] = (u8)index;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
- return result;
-}
-
-/*
- *ENE_SMInit()
- */
-int ENE_SMInit(struct us_data *us)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u8 buf[0x200];
-
- dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SMInit\n");
-
- result = ENE_LoadBinCode(us, SM_INIT_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_info(&us->pusb_dev->dev,
- "Failed to load SmartMedia init code\n: result= %x\n",
- result);
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x01;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia init code: result = %x\n",
- result);
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- us->SM_Status = *(struct keucr_sm_status *)&buf[0];
-
- us->SM_DeviceID = buf[1];
- us->SM_CardID = buf[2];
-
- if (us->SM_Status.Insert && us->SM_Status.Ready) {
- dev_info(&us->pusb_dev->dev, "Insert = %x\n",
- us->SM_Status.Insert);
- dev_info(&us->pusb_dev->dev, "Ready = %x\n",
- us->SM_Status.Ready);
- dev_info(&us->pusb_dev->dev, "WtP = %x\n",
- us->SM_Status.WtP);
- dev_info(&us->pusb_dev->dev, "DeviceID = %x\n",
- us->SM_DeviceID);
- dev_info(&us->pusb_dev->dev, "CardID = %x\n",
- us->SM_CardID);
- MediaChange = 1;
- Check_D_MediaFmt(us);
- } else {
- dev_err(&us->pusb_dev->dev,
- "SmartMedia Card Not Ready --- %x\n", buf[0]);
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/*
- * ENE_LoadBinCode()
- */
-int ENE_LoadBinCode(struct us_data *us, u8 flag)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- /* void *buf; */
- u8 *buf;
-
- /* dev_info(&us->pusb_dev->dev, "transport --- ENE_LoadBinCode\n"); */
- if (us->BIN_FLAG == flag)
- return USB_STOR_TRANSPORT_GOOD;
-
- buf = kmalloc(0x800, GFP_KERNEL);
- if (buf == NULL)
- return USB_STOR_TRANSPORT_ERROR;
- switch (flag) {
- /* For SS */
- case SM_INIT_PATTERN:
- dev_dbg(&us->pusb_dev->dev, "SM_INIT_PATTERN\n");
- memcpy(buf, SM_Init, 0x800);
- break;
- case SM_RW_PATTERN:
- dev_dbg(&us->pusb_dev->dev, "SM_RW_PATTERN\n");
- memcpy(buf, SM_Rdwr, 0x800);
- break;
- }
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x800;
- bcb->Flags = 0x00;
- bcb->CDB[0] = 0xEF;
-
- result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
-
- kfree(buf);
- us->BIN_FLAG = flag;
- return result;
-}
-
-/*
- * ENE_SendScsiCmd():
- */
-int ENE_SendScsiCmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
-
- int result;
- unsigned int transfer_length = bcb->DataTransferLength,
- cswlen = 0, partial = 0;
- unsigned int residue;
-
- /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SendScsiCmd\n"); */
- /* send cmd to out endpoint */
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
- bcb, US_BULK_CB_WRAP_LEN, NULL);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "send cmd to out endpoint fail ---\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- if (buf) {
- unsigned int pipe = fDir;
-
- if (fDir == FDIR_READ)
- pipe = us->recv_bulk_pipe;
- else
- pipe = us->send_bulk_pipe;
-
- /* Bulk */
- if (use_sg)
- result = usb_stor_bulk_srb(us, pipe, us->srb);
- else
- result = usb_stor_bulk_transfer_sg(us, pipe, buf,
- transfer_length, 0, &partial);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev, "data transfer fail ---\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
- }
-
- /* Get CSW for device status */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, &cswlen);
-
- if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
- dev_warn(&us->pusb_dev->dev,
- "Received 0-length CSW; retrying...\n");
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
- bcs, US_BULK_CS_WRAP_LEN, &cswlen);
- }
-
- if (result == USB_STOR_XFER_STALLED) {
- /* get the status again */
- dev_warn(&us->pusb_dev->dev,
- "Attempting to get CSW (2nd try)...\n");
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
- bcs, US_BULK_CS_WRAP_LEN, NULL);
- }
-
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* check bulk status */
- residue = le32_to_cpu(bcs->Residue);
-
- /*
- * try to compute the actual residue, based on how much data
- * was really transferred and what the device tells us
- */
- if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
- residue = min(residue, transfer_length);
- if (us->srb)
- scsi_set_resid(us->srb, max(scsi_get_resid(us->srb),
- (int) residue));
- }
-
- if (bcs->Status != US_BULK_STAT_OK)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/*
- * ENE_Read_Data()
- */
-int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
- int result;
-
- /* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_Read_Data\n"); */
- /* set up the command wrapper */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = length;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xED;
- bcb->CDB[2] = 0xFF;
- bcb->CDB[3] = 0x81;
-
- /* send cmd to out endpoint */
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
- US_BULK_CB_WRAP_LEN, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* R/W data */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
- buf, length, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* Get CSW for device status */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
- if (bcs->Status != US_BULK_STAT_OK)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/*
- * ENE_Write_Data():
- */
-int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
- int result;
-
- /* printk("transport --- ENE_Write_Data\n"); */
- /* set up the command wrapper */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = length;
- bcb->Flags = 0x00;
- bcb->CDB[0] = 0xEE;
- bcb->CDB[2] = 0xFF;
- bcb->CDB[3] = 0x81;
-
- /* send cmd to out endpoint */
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
- US_BULK_CB_WRAP_LEN, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* R/W data */
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
- buf, length, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* Get CSW for device status */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, NULL);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
- if (bcs->Status != US_BULK_STAT_OK)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
diff --git a/drivers/staging/keucr/init.h b/drivers/staging/keucr/init.h
deleted file mode 100644
index d1367e726ff1..000000000000
--- a/drivers/staging/keucr/init.h
+++ /dev/null
@@ -1,518 +0,0 @@
-#include "common.h"
-
-static u8 SM_Init[] = {
-0x7B, 0x09, 0x7C, 0xF0, 0x7D, 0x10, 0x7E, 0xE9,
-0x7F, 0xCC, 0x12, 0x2F, 0x71, 0x90, 0xE9, 0xCC,
-0xE0, 0xB4, 0x07, 0x12, 0x90, 0xFF, 0x09, 0xE0,
-0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80,
-0xF0, 0x12, 0x2F, 0x5C, 0xD3, 0x22, 0x78, 0x00,
-0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x0A,
-0x20, 0x0A, 0x03, 0x02, 0xE0, 0xD0, 0x7F, 0x00,
-0x12, 0x2F, 0xCB, 0x20, 0x01, 0x05, 0xC2, 0x25,
-0x02, 0xE0, 0xEB, 0xC3, 0xE8, 0x94, 0x02, 0x40,
-0x03, 0x02, 0xE0, 0xD0, 0xC0, 0x00, 0x90, 0xFE,
-0x66, 0x74, 0x90, 0xF0, 0x12, 0xE1, 0x40, 0x90,
-0xFF, 0x95, 0xE0, 0xC2, 0xE4, 0xF0, 0x90, 0xFF,
-0x97, 0x74, 0x01, 0xF0, 0x7E, 0x01, 0x7F, 0x90,
-0x12, 0x2F, 0x74, 0x90, 0xFF, 0x97, 0x74, 0x03,
-0xF0, 0x90, 0xFE, 0xC5, 0xE4, 0xF0, 0x74, 0x00,
-0x90, 0xFE, 0x6A, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0,
-0xA3, 0xF0, 0x7E, 0x23, 0x7F, 0xDC, 0x12, 0x2F,
-0x74, 0x12, 0x2F, 0x5C, 0x90, 0xFE, 0x64, 0xE0,
-0x54, 0x01, 0x60, 0x04, 0xD2, 0x02, 0x80, 0x02,
-0xC2, 0x02, 0x90, 0xFF, 0x95, 0xE0, 0xD2, 0xE4,
-0xF0, 0x78, 0x10, 0x79, 0x04, 0x12, 0xE1, 0x71,
-0x50, 0x3A, 0x90, 0xE9, 0xC6, 0xE0, 0x90, 0xE9,
-0xC3, 0xF0, 0x78, 0x9A, 0x79, 0x04, 0x12, 0xE1,
-0x71, 0x50, 0x29, 0x90, 0xE9, 0xC7, 0xE0, 0xB4,
-0xB5, 0x22, 0x90, 0xE9, 0xC4, 0xF0, 0xD0, 0x00,
-0xD2, 0x00, 0xC2, 0x01, 0xC2, 0x25, 0x80, 0x1B,
-0xC2, 0x00, 0xD2, 0x01, 0x74, 0xFF, 0x90, 0xE9,
-0xC3, 0xF0, 0xA3, 0xF0, 0x51, 0x01, 0xC2, 0x0A,
-0xC2, 0x02, 0x80, 0x07, 0xD0, 0x00, 0x05, 0x00,
-0x02, 0xE0, 0x43, 0x90, 0xFF, 0x09, 0xE0, 0x30,
-0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0,
-0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC, 0xE4,
-0xA2, 0x0A, 0x92, 0xE0, 0xA2, 0x00, 0x92, 0xE1,
-0xA2, 0x01, 0x92, 0xE2, 0xA2, 0x02, 0x92, 0xE6,
-0xA2, 0x25, 0x92, 0xE7, 0x90, 0xF4, 0x00, 0xF0,
-0x90, 0xE9, 0xC3, 0xE0, 0x90, 0xF4, 0x01, 0xF0,
-0x90, 0xE9, 0xC4, 0xE0, 0x90, 0xF4, 0x02, 0xF0,
-0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74,
-0x00, 0xF0, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
-0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
-0x90, 0xFE, 0x71, 0xE4, 0xF0, 0x90, 0xFE, 0x72,
-0x74, 0x01, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0x0C,
-0xF0, 0x90, 0xFE, 0x64, 0x74, 0x00, 0x45, 0x4E,
-0xF0, 0x90, 0xFE, 0x64, 0xE0, 0x54, 0x10, 0x60,
-0x08, 0x90, 0xFE, 0x72, 0x74, 0x81, 0xF0, 0xD3,
-0x22, 0x90, 0xFE, 0x64, 0x74, 0x08, 0xF0, 0xC3,
-0x22, 0x90, 0xFE, 0x6F, 0xE9, 0x14, 0xF0, 0x90,
-0xFE, 0x70, 0xE0, 0x54, 0xFC, 0xF0, 0x90, 0xFE,
-0x68, 0x74, 0x00, 0xF0, 0xB8, 0x9A, 0x2A, 0x74,
-0x15, 0x90, 0xFE, 0x64, 0xF0, 0x74, 0x9A, 0x90,
-0xFE, 0x60, 0xF0, 0x74, 0x16, 0x90, 0xFE, 0x64,
-0xF0, 0x74, 0x00, 0x90, 0xFE, 0x60, 0xF0, 0x30,
-0x0A, 0x5D, 0x90, 0xFE, 0x64, 0xE0, 0x20, 0xE7,
-0xF6, 0x74, 0x14, 0x90, 0xFE, 0x64, 0xF0, 0x80,
-0x20, 0x90, 0xFE, 0x6E, 0xE8, 0x44, 0x01, 0xF0,
-0xC2, 0x09, 0x12, 0xE3, 0x26, 0x20, 0x08, 0x0E,
-0x12, 0xE3, 0x32, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
-0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x20, 0x09,
-0x2E, 0x7A, 0xE9, 0x7B, 0xC5, 0x7C, 0xFE, 0x7D,
-0x60, 0xB8, 0x10, 0x07, 0x90, 0xFE, 0x69, 0xE0,
-0x20, 0xE6, 0xFC, 0x8C, 0x83, 0x8D, 0x82, 0xE0,
-0x8A, 0x83, 0x8B, 0x82, 0xF0, 0xA3, 0xAA, 0x83,
-0xAB, 0x82, 0xD9, 0xE5, 0xB8, 0x9A, 0x06, 0x74,
-0x10, 0x90, 0xFE, 0x64, 0xF0, 0xD3, 0x22, 0xC3,
-0x22, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92,
-0x25, 0x20, 0x25, 0x06, 0xC2, 0x1F, 0xD2, 0x19,
-0xC3, 0x22, 0x7F, 0x02, 0x12, 0x2F, 0xCB, 0x20,
-0x19, 0x05, 0x30, 0x1F, 0x02, 0xD3, 0x22, 0x90,
-0xEA, 0x44, 0x74, 0x80, 0xF0, 0x7F, 0x10, 0x12,
-0x2F, 0xC5, 0x90, 0xFE, 0x47, 0xE0, 0x44, 0x80,
-0xF0, 0x78, 0x00, 0xE8, 0xC3, 0x94, 0x04, 0x50,
-0x0A, 0x7F, 0x88, 0x7E, 0x13, 0x12, 0xE3, 0x4D,
-0x08, 0x80, 0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54,
-0xFB, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x54, 0xBF,
-0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0,
-0x90, 0xFE, 0x45, 0xE0, 0x54, 0x7F, 0xF0, 0x90,
-0xFE, 0x46, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0xFE,
-0x45, 0xE0, 0x54, 0xC7, 0x44, 0x18, 0xF0, 0x90,
-0xFE, 0x47, 0xE0, 0x44, 0x08, 0xF0, 0x90, 0xFE,
-0x45, 0xE0, 0x44, 0x40, 0xF0, 0x7F, 0x32, 0x7E,
-0x00, 0x12, 0xE3, 0x4D, 0x90, 0xFE, 0x51, 0xE0,
-0x54, 0x33, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02,
-0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9,
-0x90, 0xFE, 0x51, 0xE0, 0x54, 0x0F, 0xF0, 0x90,
-0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04,
-0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x44, 0x74,
-0x04, 0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE2,
-0xF9, 0x90, 0xFE, 0x4C, 0xE0, 0xF0, 0x90, 0xFE,
-0x4D, 0xE0, 0xF0, 0x90, 0xFE, 0x48, 0x74, 0x7F,
-0xF0, 0x90, 0xFE, 0x49, 0x74, 0x9F, 0xF0, 0x90,
-0xFE, 0x51, 0xE0, 0x54, 0x3C, 0x44, 0x02, 0xF0,
-0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25,
-0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x46,
-0xE0, 0x44, 0x20, 0xF0, 0x79, 0x02, 0x7A, 0x06,
-0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x06, 0x7E, 0xEB,
-0x7F, 0xC9, 0x12, 0x2F, 0xA7, 0x40, 0x03, 0x02,
-0xE3, 0x04, 0xD3, 0x22, 0xE4, 0x90, 0xFE, 0x48,
-0xF0, 0x90, 0xFE, 0x49, 0xF0, 0x90, 0xFE, 0x4C,
-0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x90,
-0xFE, 0x47, 0xE0, 0x54, 0x7F, 0xF0, 0xC2, 0x25,
-0xC2, 0x1F, 0xD2, 0x19, 0xC3, 0x22, 0xC2, 0x3E,
-0x75, 0x7C, 0x00, 0x75, 0x7D, 0x00, 0x75, 0x7E,
-0x00, 0x22, 0x05, 0x7C, 0xE5, 0x7C, 0x70, 0x14,
-0x05, 0x7D, 0xE5, 0x7D, 0x70, 0x04, 0x05, 0x7E,
-0x80, 0x0A, 0xB4, 0x17, 0x07, 0xE5, 0x7E, 0xB4,
-0x06, 0x02, 0xD2, 0x3E, 0x22, 0x75, 0x8A, 0x00,
-0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65,
-0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA,
-0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3,
-0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F,
-0x40, 0xEC, 0xC2, 0x8C, 0x22, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x58, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x20,
-0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 };
-
-static u8 SM_Rdwr[] = {
-0x7B, 0x0C, 0x7C, 0xF0, 0x7D, 0x10, 0x7E, 0xE9,
-0x7F, 0xCC, 0x12, 0x2F, 0x71, 0x90, 0xE9, 0xC3,
-0xE0, 0xB4, 0x73, 0x04, 0x74, 0x40, 0x80, 0x09,
-0xB4, 0x75, 0x04, 0x74, 0x40, 0x80, 0x02, 0x74,
-0xC0, 0x90, 0xFE, 0x70, 0xF0, 0x90, 0xFF, 0x09,
-0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74,
-0x80, 0xF0, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1,
-0x92, 0x0A, 0x40, 0x01, 0x22, 0x90, 0xFE, 0x6A,
-0xE4, 0xF0, 0x90, 0xE9, 0xCC, 0xE0, 0xB4, 0x02,
-0x05, 0xD2, 0x06, 0x02, 0xE0, 0x78, 0xB4, 0x03,
-0x03, 0x02, 0xE3, 0xD0, 0xB4, 0x04, 0x03, 0x02,
-0xE1, 0xC6, 0xB4, 0x05, 0x03, 0x02, 0xE5, 0x20,
-0xB4, 0x06, 0x03, 0x02, 0xE5, 0xE0, 0xB4, 0x07,
-0x05, 0x12, 0x2F, 0x5C, 0xD3, 0x22, 0xB4, 0x08,
-0x05, 0xC2, 0x06, 0x02, 0xE6, 0x3B, 0xC3, 0x22,
-0xE5, 0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA, 0xF0,
-0xC0, 0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0, 0x12,
-0xE0, 0xD8, 0xEF, 0x70, 0x21, 0x20, 0x37, 0x07,
-0x20, 0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05, 0xD0,
-0xF0, 0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90, 0xFF,
-0x28, 0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF, 0x28,
-0xE0, 0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0, 0xF0,
-0x90, 0xE9, 0xCF, 0xE0, 0x24, 0x01, 0xF0, 0x90,
-0xE9, 0xCE, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9,
-0xCD, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0, 0x14,
-0x70, 0xB6, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
-0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
-0xC2, 0x08, 0xC2, 0x36, 0xC2, 0x37, 0xE4, 0x90,
-0xEB, 0xC2, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0xF8,
-0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90, 0xFE, 0x6B,
-0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8, 0xF0, 0x90,
-0xFE, 0x6F, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0x70,
-0xE0, 0x54, 0xFC, 0x44, 0x02, 0xF0, 0x90, 0xFE,
-0xC6, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0F, 0xF0,
-0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0, 0x74, 0x00,
-0xA3, 0xF0, 0x90, 0xFE, 0x68, 0x74, 0x21, 0xF0,
-0x90, 0xFE, 0x64, 0x74, 0x70, 0x45, 0x4E, 0xF0,
-0x90, 0xFE, 0x64, 0x74, 0x30, 0x45, 0x4E, 0xF0,
-0x30, 0x06, 0x07, 0x90, 0xFF, 0x09, 0xE0, 0x30,
-0xE5, 0xFC, 0x90, 0xFE, 0x6E, 0x74, 0x51, 0xF0,
-0x90, 0xFE, 0xC4, 0x74, 0x21, 0xF0, 0xC2, 0x09,
-0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E, 0x12, 0xE7,
-0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE, 0xD8, 0x74,
-0x01, 0xF0, 0xD2, 0x09, 0x30, 0x09, 0x03, 0x7F,
-0x00, 0x22, 0x12, 0xE7, 0xB0, 0x20, 0x36, 0x11,
-0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E,
-0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2,
-0x37, 0x30, 0x37, 0x03, 0x7F, 0x00, 0x22, 0x90,
-0xFE, 0x64, 0x74, 0x10, 0x45, 0x4E, 0xF0, 0x90,
-0xFE, 0x64, 0x74, 0x00, 0x45, 0x4E, 0xF0, 0x12,
-0x2F, 0x65, 0x12, 0x2F, 0x68, 0xBF, 0x00, 0x09,
-0x74, 0x02, 0x90, 0xEB, 0xC2, 0xF0, 0x7F, 0x00,
-0x22, 0x12, 0x2F, 0x6B, 0xBF, 0x00, 0x0F, 0x12,
-0x2F, 0x6E, 0xBF, 0x00, 0x09, 0x74, 0x01, 0x90,
-0xEB, 0xC2, 0xF0, 0x7F, 0x00, 0x22, 0x30, 0x06,
-0x0A, 0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3,
-0x74, 0x00, 0xF0, 0x7F, 0x01, 0x22, 0x12, 0xE3,
-0xAA, 0x74, 0x01, 0x90, 0xE9, 0xCB, 0xF0, 0xE5,
-0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA, 0xF0, 0xC0,
-0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0, 0x12, 0xE2,
-0x2F, 0xEF, 0x70, 0x21, 0x20, 0x37, 0x07, 0x20,
-0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05, 0xD0, 0xF0,
-0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90, 0xFF, 0x28,
-0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF, 0x28, 0xE0,
-0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0, 0xF0, 0x90,
-0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0, 0x90, 0xE9,
-0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD0,
-0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0, 0x14, 0x70,
-0xB6, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00, 0x75,
-0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22, 0xC2,
-0x08, 0xC2, 0x36, 0xC2, 0x37, 0x90, 0xFE, 0x68,
-0x74, 0x31, 0xF0, 0x90, 0xE9, 0xD0, 0xE0, 0xF8,
-0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90, 0xFE, 0x6B,
-0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8, 0xF0, 0x90,
-0xFE, 0x6F, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0x70,
-0xE0, 0x54, 0xFC, 0x44, 0x22, 0xF0, 0x90, 0xE9,
-0xCB, 0xE0, 0x70, 0x0C, 0x90, 0xFE, 0xC0, 0x74,
-0xF4, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x80, 0x0A,
-0x90, 0xFE, 0xC0, 0x74, 0xF0, 0xF0, 0xA3, 0x74,
-0x00, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0xF0, 0x45,
-0x4E, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0xB0, 0x45,
-0x4E, 0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x81, 0xF0,
-0x90, 0xE9, 0xCB, 0xE0, 0x70, 0x0D, 0x90, 0xFE,
-0xC6, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x0F, 0xF0,
-0x02, 0xE3, 0x56, 0x20, 0x2D, 0x03, 0x02, 0xE2,
-0xEF, 0x90, 0xFE, 0xC6, 0x74, 0x01, 0xF0, 0xA3,
-0x74, 0xFF, 0xF0, 0x90, 0xFF, 0x09, 0x30, 0x0A,
-0x04, 0xE0, 0x30, 0xE1, 0xF9, 0x90, 0xFE, 0xC4,
-0x74, 0x23, 0xF0, 0x12, 0xE7, 0xB0, 0x20, 0x36,
-0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30,
-0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0,
-0xD2, 0x37, 0x30, 0x37, 0x02, 0x61, 0xA7, 0x90,
-0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF,
-0x23, 0x74, 0x80, 0xF0, 0x02, 0xE3, 0x3F, 0x90,
-0xFE, 0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x3F, 0xF0,
-0x78, 0x08, 0xC0, 0x00, 0xC2, 0x36, 0xC2, 0x37,
-0x90, 0xFF, 0x09, 0x30, 0x0A, 0x04, 0xE0, 0x30,
-0xE1, 0xF9, 0x90, 0xFE, 0xC4, 0x74, 0x23, 0xF0,
-0x12, 0xE7, 0xB0, 0x20, 0x36, 0x11, 0x20, 0x37,
-0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF4, 0x90,
-0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x37, 0x90,
-0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF,
-0x23, 0x74, 0x80, 0xF0, 0x30, 0x37, 0x04, 0xD0,
-0x00, 0x80, 0x6C, 0xD0, 0x00, 0xD8, 0xBB, 0xC2,
-0x36, 0xC2, 0x37, 0x90, 0xFE, 0xC6, 0xE4, 0xF0,
-0xA3, 0x74, 0x0F, 0xF0, 0x90, 0xFE, 0xC0, 0x74,
-0xF6, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE,
-0xC4, 0x74, 0x23, 0xF0, 0x12, 0xE7, 0xB0, 0x20,
-0x36, 0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC,
-0x30, 0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01,
-0xF0, 0xD2, 0x37, 0x30, 0x37, 0x02, 0x80, 0x2F,
-0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E,
-0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
-0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x30, 0x09,
-0x02, 0x80, 0x14, 0x90, 0xFE, 0x64, 0x74, 0x90,
-0x45, 0x4E, 0xF0, 0x90, 0xFE, 0x64, 0x74, 0x80,
-0x45, 0x4E, 0xF0, 0x12, 0x2F, 0x59, 0x22, 0x7F,
-0x00, 0x22, 0x90, 0xF6, 0x00, 0x7F, 0x06, 0x74,
-0xFF, 0xF0, 0xA3, 0xDF, 0xFC, 0x7B, 0x02, 0x7C,
-0xE9, 0x7D, 0xD3, 0x7E, 0xF6, 0x7F, 0x06, 0x12,
-0x2F, 0x71, 0x7B, 0x02, 0x7C, 0xE9, 0x7D, 0xD3,
-0x7E, 0xF6, 0x7F, 0x0B, 0x12, 0x2F, 0x71, 0x22,
-0x90, 0xFE, 0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x0F,
-0xF0, 0x90, 0xFE, 0x6F, 0xF0, 0x90, 0xFE, 0x70,
-0xE0, 0x54, 0xFC, 0xF0, 0x90, 0xFE, 0xC0, 0x74,
-0xF6, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE,
-0x68, 0x74, 0x21, 0xF0, 0x90, 0xFE, 0x66, 0xE0,
-0x54, 0xEF, 0xF0, 0x90, 0xE9, 0xD3, 0xE0, 0xF5,
-0x08, 0xA3, 0xE0, 0xF5, 0x09, 0x90, 0xFF, 0x09,
-0xE0, 0x30, 0xE5, 0xFC, 0xE4, 0xF5, 0x10, 0x7E,
-0xF4, 0x7F, 0x00, 0xC0, 0x06, 0xC0, 0x07, 0xC2,
-0x36, 0xC2, 0x37, 0xC2, 0x09, 0x90, 0xE9, 0xCD,
-0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3, 0xE0, 0x90,
-0xFE, 0x6B, 0xF0, 0xA3, 0xE9, 0xF0, 0xA3, 0xE8,
-0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x71, 0xF0, 0x90,
-0xFE, 0xC4, 0x74, 0x21, 0xF0, 0x90, 0xFE, 0x65,
-0x12, 0xE7, 0xB0, 0xE0, 0x20, 0xE4, 0x11, 0x12,
-0xE7, 0xBC, 0x30, 0x3E, 0xF6, 0x90, 0xFE, 0xD8,
-0x74, 0x01, 0xF0, 0xD2, 0x09, 0x02, 0xE4, 0x72,
-0x74, 0x10, 0xF0, 0x12, 0xE7, 0xB0, 0x20, 0x36,
-0x11, 0x20, 0x37, 0x0E, 0x12, 0xE7, 0xBC, 0x30,
-0x3E, 0xF4, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0,
-0xD2, 0x37, 0x20, 0x09, 0x05, 0x20, 0x37, 0x02,
-0x80, 0x10, 0x90, 0xFE, 0x66, 0xE0, 0x44, 0x10,
-0xF0, 0x12, 0x2F, 0x5C, 0xD0, 0x07, 0xD0, 0x06,
-0xC3, 0x22, 0xD0, 0x07, 0xD0, 0x06, 0x7B, 0x10,
-0x7C, 0xF6, 0x7D, 0x00, 0x12, 0x2F, 0x71, 0x05,
-0x10, 0xC3, 0xE5, 0x09, 0x94, 0x01, 0xF5, 0x09,
-0xE5, 0x08, 0x94, 0x00, 0xF5, 0x08, 0x45, 0x09,
-0x70, 0x03, 0x02, 0xE4, 0xEF, 0x90, 0xE9, 0xCF,
-0xE0, 0x24, 0x20, 0xF0, 0x90, 0xE9, 0xCE, 0xE0,
-0x34, 0x00, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0x34,
-0x00, 0xF0, 0xC3, 0xEF, 0x24, 0x10, 0xFF, 0xEE,
-0x34, 0x00, 0xFE, 0xE5, 0x10, 0x64, 0x20, 0x60,
-0x03, 0x02, 0xE4, 0x13, 0x90, 0xFF, 0x2A, 0x74,
-0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x75, 0x10,
-0x00, 0x7E, 0xF4, 0x7F, 0x00, 0x90, 0xFF, 0x09,
-0xE0, 0x30, 0xE5, 0xFC, 0x02, 0xE4, 0x13, 0xE5,
-0x10, 0x60, 0x17, 0x7E, 0x00, 0x7F, 0x00, 0x78,
-0x04, 0xC3, 0x33, 0xFF, 0xEE, 0x33, 0xFE, 0xEF,
-0xD8, 0xF8, 0x90, 0xFF, 0x2A, 0xEE, 0xF0, 0xA3,
-0xEF, 0xF0, 0x90, 0xFE, 0x66, 0xE0, 0x44, 0x10,
-0xF0, 0x12, 0x2F, 0x5C, 0x78, 0x00, 0x88, 0x3C,
-0x88, 0x3D, 0x88, 0x3E, 0x88, 0x3F, 0xD3, 0x22,
-0x12, 0x2F, 0x5F, 0x12, 0x2F, 0x62, 0x90, 0xFE,
-0xC6, 0xE4, 0xF0, 0xA3, 0x74, 0x0F, 0xF0, 0x90,
-0xFE, 0x6F, 0xF0, 0x90, 0xFE, 0x70, 0xE0, 0x54,
-0xFC, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF6, 0xF0,
-0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0x68, 0x74,
-0x31, 0xF0, 0x90, 0xE9, 0xD3, 0xE0, 0xF8, 0xC0,
-0x00, 0xC2, 0x08, 0xC2, 0x36, 0xC2, 0x37, 0x90,
-0xE9, 0xD0, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9, 0xA3,
-0xE0, 0x90, 0xFE, 0x6B, 0xF0, 0xA3, 0xE9, 0xF0,
-0xA3, 0xE8, 0xF0, 0x90, 0xFE, 0x6E, 0x74, 0x81,
-0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x23, 0xF0, 0x12,
-0xE7, 0xB0, 0x20, 0x36, 0x11, 0x20, 0x37, 0x0E,
-0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF4, 0x90, 0xFE,
-0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x37, 0x30, 0x37,
-0x07, 0xD0, 0x00, 0x12, 0x2F, 0x5C, 0xC3, 0x22,
-0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20, 0x08, 0x0E,
-0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7, 0x90, 0xFE,
-0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09, 0x20, 0x09,
-0xE0, 0x90, 0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0,
-0x90, 0xE9, 0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90,
-0xE9, 0xD0, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0x00,
-0x18, 0xE8, 0x60, 0x03, 0x02, 0xE5, 0x4F, 0x12,
-0x2F, 0x5C, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00,
-0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22,
-0x90, 0xE9, 0xD0, 0xE0, 0xF8, 0xA3, 0xE0, 0xF9,
-0xA3, 0xE0, 0x90, 0xFE, 0x6B, 0xF0, 0xA3, 0xE9,
-0xF0, 0xA3, 0xE8, 0xF0, 0x90, 0xFE, 0x68, 0x74,
-0x00, 0xF0, 0xC2, 0x08, 0x90, 0xFE, 0x6E, 0x74,
-0xB1, 0xF0, 0xC2, 0x09, 0x12, 0xE7, 0xB0, 0x20,
-0x08, 0x0E, 0x12, 0xE7, 0xBC, 0x30, 0x3E, 0xF7,
-0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xD2, 0x09,
-0x20, 0x09, 0x1E, 0x90, 0xFE, 0x70, 0xE0, 0x44,
-0x10, 0xF0, 0x54, 0xEF, 0xF0, 0x12, 0x2F, 0x59,
-0xEF, 0x60, 0x0E, 0x75, 0x3C, 0x00, 0x75, 0x3D,
-0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3,
-0x22, 0xC3, 0x22, 0x7B, 0x03, 0x7C, 0xE9, 0x7D,
-0xCD, 0x7E, 0xE9, 0x7F, 0xD7, 0x12, 0x2F, 0x71,
-0x12, 0xE3, 0xAA, 0x90, 0xE9, 0xD5, 0xE0, 0x60,
-0x12, 0xF9, 0x12, 0xE7, 0x17, 0x40, 0x01, 0x22,
-0x90, 0xF6, 0x00, 0x78, 0x06, 0x74, 0xFF, 0xF0,
-0xA3, 0xD8, 0xFC, 0x74, 0x01, 0x90, 0xE9, 0xCB,
-0xF0, 0xE5, 0x3E, 0xC3, 0x13, 0x90, 0xE9, 0xCA,
-0xF0, 0xC0, 0xE0, 0x75, 0xF0, 0x02, 0xC0, 0xF0,
-0x12, 0xE2, 0x2F, 0xEF, 0x70, 0x21, 0x20, 0x37,
-0x07, 0x20, 0x09, 0x04, 0xD0, 0xF0, 0x80, 0x05,
-0xD0, 0xF0, 0xD5, 0xF0, 0xE9, 0xD0, 0xE0, 0x90,
-0xFF, 0x28, 0xE0, 0x30, 0xE7, 0xFC, 0x90, 0xFF,
-0x28, 0xE0, 0x44, 0x01, 0xF0, 0xC3, 0x22, 0xD0,
-0xF0, 0x90, 0xE9, 0xD2, 0xE0, 0x24, 0x01, 0xF0,
-0x90, 0xE9, 0xD1, 0xE0, 0x34, 0x00, 0xF0, 0x90,
-0xE9, 0xD0, 0xE0, 0x34, 0x00, 0xF0, 0xD0, 0xE0,
-0x14, 0x70, 0xB6, 0x90, 0xE9, 0xD5, 0xE0, 0xF8,
-0x90, 0xE9, 0xCA, 0xE0, 0x28, 0xF5, 0xF0, 0xC3,
-0x74, 0x20, 0x95, 0xF0, 0x60, 0x22, 0xF9, 0x90,
-0xE9, 0xCA, 0xE0, 0xF5, 0xF0, 0x90, 0xE9, 0xCF,
-0xE0, 0x25, 0xF0, 0xF0, 0x90, 0xE9, 0xCE, 0xE0,
-0x34, 0x00, 0xF0, 0x90, 0xE9, 0xCD, 0xE0, 0x34,
-0x00, 0xF0, 0x12, 0xE7, 0x17, 0x40, 0x01, 0x22,
-0x90, 0xE9, 0xD6, 0xE0, 0x70, 0x13, 0x7B, 0x03,
-0x7C, 0xE9, 0x7D, 0xD7, 0x7E, 0xE9, 0x7F, 0xD0,
-0x12, 0x2F, 0x71, 0x12, 0xE5, 0xE0, 0x40, 0x01,
-0x22, 0x75, 0x3C, 0x00, 0x75, 0x3D, 0x00, 0x75,
-0x3E, 0x00, 0x75, 0x3F, 0x00, 0xD3, 0x22, 0x90,
-0xE9, 0xD6, 0xE0, 0x60, 0x18, 0x74, 0xFF, 0x90,
-0xF4, 0x00, 0x78, 0xFF, 0xF0, 0xA3, 0x18, 0xB8,
-0x00, 0xFA, 0x78, 0xFF, 0xF0, 0xA3, 0x18, 0xB8,
-0x00, 0xFA, 0xF0, 0xA3, 0xF0, 0xC0, 0x01, 0x12,
-0xE7, 0x70, 0x40, 0x04, 0xD0, 0x01, 0xC3, 0x22,
-0x90, 0xE9, 0xCF, 0xE0, 0x24, 0x01, 0xF0, 0x90,
-0xE9, 0xCE, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9,
-0xCD, 0xE0, 0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD2,
-0xE0, 0x24, 0x01, 0xF0, 0x90, 0xE9, 0xD1, 0xE0,
-0x34, 0x00, 0xF0, 0x90, 0xE9, 0xD0, 0xE0, 0x34,
-0x00, 0xF0, 0xD0, 0x01, 0xD9, 0xC7, 0xD3, 0x22,
-0xC2, 0x06, 0x90, 0xE9, 0xD6, 0xE0, 0x70, 0x28,
-0x12, 0xE0, 0xD8, 0xEF, 0x60, 0x03, 0x02, 0xE7,
-0xA0, 0x90, 0xEB, 0xC2, 0xE0, 0x60, 0x17, 0x64,
-0x02, 0x60, 0x15, 0x90, 0xF6, 0x00, 0x78, 0x06,
-0x74, 0xFF, 0xF0, 0xA3, 0xD8, 0xFC, 0x74, 0xF0,
-0x90, 0xF6, 0x04, 0xF0, 0x80, 0x02, 0xC3, 0x22,
-0xE4, 0x90, 0xE9, 0xCB, 0xF0, 0x12, 0xE2, 0x2F,
-0xEF, 0x70, 0x03, 0x02, 0xE7, 0x81, 0xD3, 0x22,
-0xC2, 0x3E, 0x75, 0x7C, 0x00, 0x75, 0x7D, 0x00,
-0x75, 0x7E, 0x00, 0x22, 0x05, 0x7C, 0xE5, 0x7C,
-0x70, 0x14, 0x05, 0x7D, 0xE5, 0x7D, 0x70, 0x04,
-0x05, 0x7E, 0x80, 0x0A, 0xB4, 0x17, 0x07, 0xE5,
-0x7E, 0xB4, 0x06, 0x02, 0xD2, 0x3E, 0x22, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x58, 0x44, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 };
-
diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c
deleted file mode 100644
index 7d8d444910c1..000000000000
--- a/drivers/staging/keucr/scsiglue.c
+++ /dev/null
@@ -1,467 +0,0 @@
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_devinfo.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_eh.h>
-
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-
-/* Host functions */
-/*
- * host_info()
- */
-static const char *host_info(struct Scsi_Host *host)
-{
- /* pr_info("scsiglue --- host_info\n"); */
- return "SCSI emulation for USB Mass Storage devices";
-}
-
-/*
- * slave_alloc()
- */
-static int slave_alloc(struct scsi_device *sdev)
-{
- struct us_data *us = host_to_us(sdev->host);
-
- /* pr_info("scsiglue --- slave_alloc\n"); */
- sdev->inquiry_len = 36;
-
- blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
-
- if (us->subclass == USB_SC_UFI)
- sdev->sdev_target->pdt_1f_for_no_lun = 1;
-
- return 0;
-}
-
-/*
- * slave_configure()
- */
-static int slave_configure(struct scsi_device *sdev)
-{
- struct us_data *us = host_to_us(sdev->host);
-
- /* pr_info("scsiglue --- slave_configure\n"); */
- if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
- unsigned int max_sectors = 64;
-
- if (us->fflags & US_FL_MAX_SECTORS_MIN)
- max_sectors = PAGE_CACHE_SIZE >> 9;
- if (queue_max_sectors(sdev->request_queue) > max_sectors)
- blk_queue_max_hw_sectors(sdev->request_queue,
- max_sectors);
- }
-
- if (sdev->type == TYPE_DISK) {
- if (us->subclass != USB_SC_SCSI &&
- us->subclass != USB_SC_CYP_ATACB)
- sdev->use_10_for_ms = 1;
- sdev->use_192_bytes_for_3f = 1;
- if (us->fflags & US_FL_NO_WP_DETECT)
- sdev->skip_ms_page_3f = 1;
- sdev->skip_ms_page_8 = 1;
- if (us->fflags & US_FL_FIX_CAPACITY)
- sdev->fix_capacity = 1;
- if (us->fflags & US_FL_CAPACITY_HEURISTICS)
- sdev->guess_capacity = 1;
- if (sdev->scsi_level > SCSI_2)
- sdev->sdev_target->scsi_level = sdev->scsi_level
- = SCSI_2;
- sdev->retry_hwerror = 1;
- sdev->allow_restart = 1;
- sdev->last_sector_bug = 1;
- } else {
- sdev->use_10_for_ms = 1;
- }
-
- if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_CBI) &&
- sdev->scsi_level == SCSI_UNKNOWN)
- us->max_lun = 0;
-
- if (us->fflags & US_FL_NOT_LOCKABLE)
- sdev->lockable = 0;
-
- return 0;
-}
-
-/* This is always called with scsi_lock(host) held */
-/*
- * queuecommand()
- */
-static int queuecommand_lck(struct scsi_cmnd *srb,
- void (*done)(struct scsi_cmnd *))
-{
- struct us_data *us = host_to_us(srb->device->host);
-
- /* pr_info("scsiglue --- queuecommand\n"); */
-
- /* check for state-transition errors */
- if (us->srb != NULL) {
- /* pr_info("Error in %s: us->srb = %p\n"
- __func__, us->srb); */
- return SCSI_MLQUEUE_HOST_BUSY;
- }
-
- /* fail the command if we are disconnecting */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
- pr_info("Fail command during disconnect\n");
- srb->result = DID_NO_CONNECT << 16;
- done(srb);
- return 0;
- }
-
- /* enqueue the command and wake up the control thread */
- srb->scsi_done = done;
- us->srb = srb;
- complete(&us->cmnd_ready);
-
- return 0;
-}
-
-static DEF_SCSI_QCMD(queuecommand)
-
-/***********************************************************************
- * Error handling functions
- ***********************************************************************/
-
-/* Command timeout and abort */
-/*
- * command_abort()
- */
-static int command_abort(struct scsi_cmnd *srb)
-{
- struct us_data *us = host_to_us(srb->device->host);
-
- /* pr_info("scsiglue --- command_abort\n"); */
-
- scsi_lock(us_to_host(us));
- if (us->srb != srb) {
- scsi_unlock(us_to_host(us));
- dev_info(&us->pusb_dev->dev, "-- nothing to abort\n");
- return FAILED;
- }
-
- set_bit(US_FLIDX_TIMED_OUT, &us->dflags);
- if (!test_bit(US_FLIDX_RESETTING, &us->dflags)) {
- set_bit(US_FLIDX_ABORTING, &us->dflags);
- usb_stor_stop_transport(us);
- }
- scsi_unlock(us_to_host(us));
-
- /* Wait for the aborted command to finish */
- wait_for_completion(&us->notify);
- return SUCCESS;
-}
-
-/* This invokes the transport reset mechanism to reset the state of the
- * device.
- */
-/*
- * device_reset()
- */
-static int device_reset(struct scsi_cmnd *srb)
-{
- struct us_data *us = host_to_us(srb->device->host);
- int result;
-
- /* pr_info("scsiglue --- device_reset\n"); */
-
- /* lock the device pointers and do the reset */
- mutex_lock(&(us->dev_mutex));
- result = us->transport_reset(us);
- mutex_unlock(&us->dev_mutex);
-
- return result < 0 ? FAILED : SUCCESS;
-}
-
-/*
- * bus_reset()
- */
-static int bus_reset(struct scsi_cmnd *srb)
-{
- struct us_data *us = host_to_us(srb->device->host);
- int result;
-
- /* pr_info("scsiglue --- bus_reset\n"); */
- result = usb_stor_port_reset(us);
- return result < 0 ? FAILED : SUCCESS;
-}
-
-/*
- * usb_stor_report_device_reset()
- */
-void usb_stor_report_device_reset(struct us_data *us)
-{
- int i;
- struct Scsi_Host *host = us_to_host(us);
-
- /* pr_info("scsiglue --- usb_stor_report_device_reset\n"); */
- scsi_report_device_reset(host, 0, 0);
- if (us->fflags & US_FL_SCM_MULT_TARG) {
- for (i = 1; i < host->max_id; ++i)
- scsi_report_device_reset(host, 0, i);
- }
-}
-
-/*
- * usb_stor_report_bus_reset()
- */
-void usb_stor_report_bus_reset(struct us_data *us)
-{
- struct Scsi_Host *host = us_to_host(us);
-
- /* pr_info("scsiglue --- usb_stor_report_bus_reset\n"); */
- scsi_lock(host);
- scsi_report_bus_reset(host, 0);
- scsi_unlock(host);
-}
-
-/***********************************************************************
- * /proc/scsi/ functions
- ***********************************************************************/
-
-/* we use this macro to help us write into the buffer */
-#undef SPRINTF
-#define SPRINTF(args...) seq_printf(m, ##args)
-
-static int write_info(struct Scsi_Host *host, char *buffer, int length)
-{
- return length;
-}
-
-static int show_info(struct seq_file *m, struct Scsi_Host *host)
-{
- struct us_data *us = host_to_us(host);
- const char *string;
-
- /* print the controller name */
- SPRINTF(" Host scsi%d: usb-storage\n", host->host_no);
-
- /* print product, vendor, and serial number strings */
- if (us->pusb_dev->manufacturer)
- string = us->pusb_dev->manufacturer;
- else if (us->unusual_dev->vendorName)
- string = us->unusual_dev->vendorName;
- else
- string = "Unknown";
- SPRINTF(" Vendor: %s\n", string);
- if (us->pusb_dev->product)
- string = us->pusb_dev->product;
- else if (us->unusual_dev->productName)
- string = us->unusual_dev->productName;
- else
- string = "Unknown";
- SPRINTF(" Product: %s\n", string);
- if (us->pusb_dev->serial)
- string = us->pusb_dev->serial;
- else
- string = "None";
- SPRINTF("Serial Number: %s\n", string);
-
- /* show the protocol and transport */
- SPRINTF(" Protocol: %s\n", us->protocol_name);
- SPRINTF(" Transport: %s\n", us->transport_name);
-
- /* show the device flags */
- SPRINTF(" Quirks:");
-
-#define US_FLAG(name, value) \
- do { \
- if (us->fflags & value) \
- SPRINTF(" " #name); \
- } while (0);
-US_DO_ALL_FLAGS
-#undef US_FLAG
- seq_putc(m, '\n');
- return 0;
-}
-
-/***********************************************************************
- * Sysfs interface
- ***********************************************************************/
-
-/* Output routine for the sysfs max_sectors file */
-static ssize_t max_sectors_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct scsi_device *sdev = to_scsi_device(dev);
-
- /* pr_info("scsiglue --- ssize_t show_max_sectors\n"); */
- return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue));
-}
-
-/* Input routine for the sysfs max_sectors file */
-static ssize_t max_sectors_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct scsi_device *sdev = to_scsi_device(dev);
- unsigned short ms;
-
- /* pr_info("scsiglue --- ssize_t store_max_sectors\n"); */
- if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS) {
- blk_queue_max_hw_sectors(sdev->request_queue, ms);
- return strlen(buf);
- }
- return -EINVAL;
-}
-static DEVICE_ATTR_RW(max_sectors);
-
-static struct device_attribute *sysfs_device_attr_list[] = {
- &dev_attr_max_sectors, NULL,
-};
-
-/* this defines our host template, with which we'll allocate hosts */
-
-/*
- * usb_stor_host_template()
- */
-struct scsi_host_template usb_stor_host_template = {
- /* basic userland interface stuff */
- .name = "eucr-storage",
- .proc_name = "eucr-storage",
- .write_info = write_info,
- .show_info = show_info,
- .info = host_info,
-
- /* command interface -- queued only */
- .queuecommand = queuecommand,
-
- /* error and abort handlers */
- .eh_abort_handler = command_abort,
- .eh_device_reset_handler = device_reset,
- .eh_bus_reset_handler = bus_reset,
-
- /* queue commands only, only one command per LUN */
- .can_queue = 1,
- .cmd_per_lun = 1,
-
- /* unknown initiator id */
- .this_id = -1,
-
- .slave_alloc = slave_alloc,
- .slave_configure = slave_configure,
-
- /* lots of sg segments can be handled */
- .sg_tablesize = SG_ALL,
-
- /* limit the total size of a transfer to 120 KB */
- .max_sectors = 240,
-
- /* merge commands... this seems to help performance, but
- * periodically someone should test to see which setting is more
- * optimal.
- */
- .use_clustering = 1,
-
- /* emulated HBA */
- .emulated = 1,
-
- /* we do our own delay after a device or bus reset */
- .skip_settle_delay = 1,
-
- /* sysfs device attributes */
- .sdev_attrs = sysfs_device_attr_list,
-
- /* module management */
- .module = THIS_MODULE
-};
-
-/* To Report "Illegal Request: Invalid Field in CDB */
-unsigned char usb_stor_sense_invalidCDB[18] = {
- [0] = 0x70, /* current error */
- [2] = ILLEGAL_REQUEST, /* Illegal Request = 0x05 */
- [7] = 0x0a, /* additional length */
- [12] = 0x24 /* Invalid Field in CDB */
-};
-
-/***********************************************************************
- * Scatter-gather transfer buffer access routines
- ***********************************************************************/
-
-/*
- * usb_stor_access_xfer_buf()
- */
-unsigned int usb_stor_access_xfer_buf(struct us_data *us,
- unsigned char *buffer, unsigned int buflen,
- struct scsi_cmnd *srb, struct scatterlist **sgptr,
- unsigned int *offset, enum xfer_buf_dir dir)
-{
- unsigned int cnt;
-
- /* pr_info("transport --- usb_stor_access_xfer_buf\n"); */
- struct scatterlist *sg = *sgptr;
-
- if (!sg)
- sg = scsi_sglist(srb);
-
- cnt = 0;
- while (cnt < buflen && sg) {
- struct page *page = sg_page(sg) +
- ((sg->offset + *offset) >> PAGE_SHIFT);
- unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1);
- unsigned int sglen = sg->length - *offset;
-
- if (sglen > buflen - cnt) {
- /* Transfer ends within this s-g entry */
- sglen = buflen - cnt;
- *offset += sglen;
- } else {
- /* Transfer continues to next s-g entry */
- *offset = 0;
- sg = sg_next(sg);
- }
-
- while (sglen > 0) {
- unsigned int plen = min(sglen,
- (unsigned int)PAGE_SIZE - poff);
- unsigned char *ptr = kmap(page);
-
- if (dir == TO_XFER_BUF)
- memcpy(ptr + poff, buffer + cnt, plen);
- else
- memcpy(buffer + cnt, ptr + poff, plen);
- kunmap(page);
-
- /* Start at the beginning of the next page */
- poff = 0;
- ++page;
- cnt += plen;
- sglen -= plen;
- }
- }
- *sgptr = sg;
-
- /* Return the amount actually transferred */
- return cnt;
-}
-
-/*
- * Store the contents of buffer into srb's transfer
- * buffer and set the SCSI residue.
- */
-/*
- * usb_stor_set_xfer_buf()
- */
-void usb_stor_set_xfer_buf(struct us_data *us, unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, unsigned int dir)
-{
- unsigned int offset = 0;
- struct scatterlist *sg = NULL;
-
- /* pr_info("transport --- usb_stor_set_xfer_buf\n"); */
- /* TO_XFER_BUF = 0, FROM_XFER_BUF = 1 */
- buflen = min(buflen, scsi_bufflen(srb));
- buflen = usb_stor_access_xfer_buf(us, buffer, buflen, srb,
- &sg, &offset, dir);
- if (buflen < scsi_bufflen(srb))
- scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
-}
diff --git a/drivers/staging/keucr/scsiglue.h b/drivers/staging/keucr/scsiglue.h
deleted file mode 100644
index c7e59f0f9cd6..000000000000
--- a/drivers/staging/keucr/scsiglue.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _SCSIGLUE_H_
-#define _SCSIGLUE_H_
-
-extern void usb_stor_report_device_reset(struct us_data *us);
-extern void usb_stor_report_bus_reset(struct us_data *us);
-
-extern unsigned char usb_stor_sense_invalidCDB[18];
-extern struct scsi_host_template usb_stor_host_template;
-
-#endif
diff --git a/drivers/staging/keucr/smcommon.h b/drivers/staging/keucr/smcommon.h
deleted file mode 100644
index 1d2752a1d5c4..000000000000
--- a/drivers/staging/keucr/smcommon.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*----- < SMCommon.h> --------------------------------------------------*/
-#ifndef SMCOMMON_INCD
-#define SMCOMMON_INCD
-
-
-/***************************************************************************
-Define Definition
-***************************************************************************/
-#define SMSUCCESS 0x0000 /* SUCCESS */
-#define ERROR 0xFFFF /* ERROR */
-#define CORRECT 0x0001 /* CORRECTABLE */
-
-/***************************************************************************/
-#define NO_ERROR 0x0000 /* NO ERROR */
-#define ERR_WriteFault 0x0003 /* Peripheral Device Write Fault */
-#define ERR_HwError 0x0004 /* Hardware Error */
-#define ERR_DataStatus 0x0010 /* DataStatus Error */
-#define ERR_EccReadErr 0x0011 /* Unrecovered Read Error */
-#define ERR_CorReadErr 0x0018 /* Recovered Read Data with ECC */
-#define ERR_OutOfLBA 0x0021 /* Illegal Logical Block Address */
-#define ERR_WrtProtect 0x0027 /* Write Protected */
-#define ERR_ChangedMedia 0x0028 /* Medium Changed */
-#define ERR_UnknownMedia 0x0030 /* Incompatible Medium Installed */
-#define ERR_IllegalFmt 0x0031 /* Medium Format Corrupted */
-#define ERR_NoSmartMedia 0x003A /* Medium Not Present */
-
-/***************************************************************************/
-
-#endif
diff --git a/drivers/staging/keucr/smil.h b/drivers/staging/keucr/smil.h
deleted file mode 100644
index f938759337e6..000000000000
--- a/drivers/staging/keucr/smil.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*----- < smil.h> ----------------------------------------------------*/
-#ifndef SMIL_INCD
-#define SMIL_INCD
-
-/***************************************************************************
-Define Definition
-***************************************************************************/
-#define K_BYTE 1024 /* Kilo Byte */
-#define SECTSIZE 512 /* Sector buffer size */
-#define REDTSIZE 16 /* Redundant buffer size */
-
-/***************************************************************************/
-#define DUMMY_DATA 0xFF /* No Assign Sector Read Data */
-
-/***************************************************************************
-Max Zone/Block/Sectors Data Definition
-***************************************************************************/
-#define MAX_ZONENUM 128 /* Max Zone Numbers in a SmartMedia */
-#define MAX_BLOCKNUM 0x0400 /* Max Block Numbers in a Zone */
-#define MAX_SECTNUM 0x20 /* Max Sector Numbers in a Block */
-#define MAX_LOGBLOCK 1000 /* Max Logical Block Numbers in a Zone */
-
-/***************************************************************************/
-#define CIS_SEARCH_SECT 0x08 /* Max CIS Search Sector Number */
-
-/***************************************************************************
-Logical to Physical Block Table Data Definition
-***************************************************************************/
-#define NO_ASSIGN 0xFFFF /* No Assign Logical Block Address */
-
-/***************************************************************************
-'SectCopyMode' Data
-***************************************************************************/
-#define COMPLETED 0 /* Sector Copy Completed */
-#define REQ_ERASE 1 /* Request Read Block Erase */
-#define REQ_FAIL 2 /* Request Read Block Failed */
-
-/***************************************************************************
-Retry Counter Definition
-***************************************************************************/
-#define RDERR_REASSIGN 1 /* Reassign with Read Error */
-#define L2P_ERR_ERASE 1 /* BlockErase for Contradicted L2P Table */
-
-/***************************************************************************
-Hardware ECC Definition
-***************************************************************************/
-#define HW_ECC_SUPPORTED 1 /* Hardware ECC Supported */
-/* No definition for Software ECC */
-
-/***************************************************************************
-SmartMedia Command & Status Definition
-***************************************************************************/
-/* SmartMedia Command */
-#define WRDATA 0x80
-/* #define READ 0x00 */
-#define READ_REDT 0x50
-/* #define WRITE 0x10 */
-#define RDSTATUS 0x70
-
-#define READ1 0x00 /* NO */
-#define READ2 0x01 /* NO */
-#define READ3 0x50 /* NO */
-#define RST_CHIP 0xFF
-#define ERASE1 0x60
-#define ERASE2 0xD0
-#define READ_ID_1 0x90
-#define READ_ID_2 0x91
-#define READ_ID_3 0x9A
-
-/* 712 SmartMedia Command */
-#define SM_CMD_RESET 0x00 /* 0xFF */
-#define SM_CMD_READ_ID_1 0x10 /* 0x90 */
-#define SM_CMD_READ_ID_2 0x20 /* 0x91 */
-#define SM_CMD_READ_STAT 0x30 /* 0x70 */
-#define SM_CMD_RDMULTPL_STAT 0x40 /* 0x71 */
-#define SM_CMD_READ_1 0x50 /* 0x00 */
-#define SM_CMD_READ_2 0x60 /* 0x01 */
-#define SM_CMD_READ_3 0x70 /* 0x50 */
-#define SM_CMD_PAGPRGM_TRUE 0x80 /* {0x80, 0x10} */
-#define SM_CMD_PAGPRGM_DUMY 0x90 /* {0x80, 0x11} */
-#define SM_CMD_PAGPRGM_MBLK 0xA0 /* {0x80, 0x15} */
-#define SM_CMD_BLKERASE 0xB0 /* {0x60, 0xD0} */
-#define SM_CMD_BLKERASE_MULTPL 0xC0 /* {0x60-0x60, 0xD0} */
-
-#define SM_CRADDTCT_DEBNCETIMER_EN 0x02
-#define SM_CMD_START_BIT 0x01
-
-#define SM_WaitCmdDone { while (!SM_CmdDone); }
-#define SM_WaitDmaDone { while (!SM_DmaDone); }
-
-/* SmartMedia Status */
-#define WR_FAIL 0x01 /* 0:Pass, 1:Fail */
-#define SUSPENDED 0x20 /* 0:Not Suspended, 1:Suspended */
-#define READY 0x40 /* 0:Busy, 1:Ready */
-#define WR_PRTCT 0x80 /* 0:Protect, 1:Not Protect */
-
-/* SmartMedia Busy Time (1bit:0.1ms) */
-#define BUSY_PROG 200 /* tPROG : 20ms ----- Program Time old : 200 */
-#define BUSY_ERASE 4000 /* tBERASE : 400ms ----- Block Erase Time old : 4000 */
-
-/*for 712 Test */
-/* #define BUSY_READ 1 *//* tR : 100us ----- Data transfer Time old : 1 */
-/* #define BUSY_READ 10 *//* tR : 100us ----- Data transfer Time old : 1 */
-
-#define BUSY_READ 200 /* tR : 20ms ----- Data transfer Time old : 1 */
-
-/* #define BUSY_RESET 60 *//* tRST : 6ms ----- Device Resetting Time old : 60 */
-
-#define BUSY_RESET 600 /* tRST : 60ms ----- Device Resetting Time old : 60 */
-
-/* Hardware Timer (1bit:0.1ms) */
-#define TIME_PON 3000 /* 300ms ------ Power On Wait Time */
-#define TIME_CDCHK 200 /* 20ms ------ Card Check Interval Timer */
-#define TIME_WPCHK 50 /* 5ms ------ WP Check Interval Timer */
-#define TIME_5VCHK 10 /* 1ms ------ 5V Check Interval Timer */
-
-/***************************************************************************
-Redundant Data
-***************************************************************************/
-#define REDT_DATA 0x04
-#define REDT_BLOCK 0x05
-#define REDT_ADDR1H 0x06
-#define REDT_ADDR1L 0x07
-#define REDT_ADDR2H 0x0B
-#define REDT_ADDR2L 0x0C
-#define REDT_ECC10 0x0D
-#define REDT_ECC11 0x0E
-#define REDT_ECC12 0x0F
-#define REDT_ECC20 0x08
-#define REDT_ECC21 0x09
-#define REDT_ECC22 0x0A
-
-/***************************************************************************
-SmartMedia Model & Attribute
-***************************************************************************/
-/* SmartMedia Attribute */
-#define NOWP 0x00 /* 0... .... No Write Protect */
-#define WP 0x80 /* 1... .... Write Protected */
-#define MASK 0x00 /* .00. .... NAND MASK ROM Model */
-#define FLASH 0x20 /* .01. .... NAND Flash ROM Model */
-#define AD3CYC 0x00 /* ...0 .... Address 3-cycle */
-#define AD4CYC 0x10 /* ...1 .... Address 4-cycle */
-#define BS16 0x00 /* .... 00.. 16page/block */
-#define BS32 0x04 /* .... 01.. 32page/block */
-#define PS256 0x00 /* .... ..00 256byte/page */
-#define PS512 0x01 /* .... ..01 512byte/page */
-#define MWP 0x80 /* WriteProtect mask */
-#define MFLASH 0x60 /* Flash Rom mask */
-#define MADC 0x10 /* Address Cycle */
-#define MBS 0x0C /* BlockSize mask */
-#define MPS 0x03 /* PageSize mask */
-
-/* SmartMedia Model */
-#define NOSSFDC 0x00 /* NO SmartMedia */
-#define SSFDC1MB 0x01 /* 1MB SmartMedia */
-#define SSFDC2MB 0x02 /* 2MB SmartMedia */
-#define SSFDC4MB 0x03 /* 4MB SmartMedia */
-#define SSFDC8MB 0x04 /* 8MB SmartMedia */
-#define SSFDC16MB 0x05 /* 16MB SmartMedia */
-#define SSFDC32MB 0x06 /* 32MB SmartMedia */
-#define SSFDC64MB 0x07 /* 64MB SmartMedia */
-#define SSFDC128MB 0x08 /*128MB SmartMedia */
-#define SSFDC256MB 0x09
-#define SSFDC512MB 0x0A
-#define SSFDC1GB 0x0B
-#define SSFDC2GB 0x0C
-
-/***************************************************************************
-Struct Definition
-***************************************************************************/
-struct keucr_media_info {
- u8 Model;
- u8 Attribute;
- u8 MaxZones;
- u8 MaxSectors;
- u16 MaxBlocks;
- u16 MaxLogBlocks;
-};
-
-struct keucr_media_address {
- u8 Zone; /* Zone Number */
- u8 Sector; /* Sector(512byte) Number on Block */
- u16 PhyBlock; /* Physical Block Number on Zone */
- u16 LogBlock; /* Logical Block Number of Zone */
-};
-
-struct keucr_media_area {
- u8 Sector; /* Sector(512byte) Number on Block */
- u16 PhyBlock; /* Physical Block Number on Zone 0 */
-};
-
-extern u16 ReadBlock;
-extern u16 WriteBlock;
-extern u32 MediaChange;
-
-extern struct keucr_media_info Ssfdc;
-extern struct keucr_media_address Media;
-extern struct keucr_media_area CisArea;
-
-/*
- * SMILMain.c
- */
-/******************************************/
-int Init_D_SmartMedia(void);
-int Pwoff_D_SmartMedia(void);
-int Check_D_SmartMedia(void);
-int Check_D_MediaFmt(struct us_data *);
-int Check_D_Parameter(struct us_data *, u16 *, u8 *, u8 *);
-int Media_D_ReadSector(struct us_data *, u32, u16, u8 *);
-int Media_D_WriteSector(struct us_data *, u32, u16, u8 *);
-int Media_D_CopySector(struct us_data *, u32, u16, u8 *);
-int Media_D_EraseBlock(struct us_data *, u32, u16);
-int Media_D_EraseAll(struct us_data *);
-/******************************************/
-int Media_D_OneSectWriteStart(struct us_data *, u32, u8 *);
-int Media_D_OneSectWriteNext(struct us_data *, u8 *);
-int Media_D_OneSectWriteFlush(struct us_data *);
-
-/******************************************/
-extern int SM_FreeMem(void); /* ENE SM function */
-void SM_EnableLED(struct us_data *, bool);
-void Led_D_TernOn(void);
-void Led_D_TernOff(void);
-
-int Media_D_EraseAllRedtData(u32 Index, bool CheckBlock);
-/*DWORD Media_D_GetMediaInfo(struct us_data * fdoExt,
- PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut); */
-
-/*
- * SMILSub.c
- */
-/******************************************/
-int Check_D_DataBlank(u8 *);
-int Check_D_FailBlock(u8 *);
-int Check_D_DataStatus(u8 *);
-int Load_D_LogBlockAddr(u8 *);
-void Clr_D_RedundantData(u8 *);
-void Set_D_LogBlockAddr(u8 *);
-void Set_D_FailBlock(u8 *);
-void Set_D_DataStaus(u8 *);
-
-/******************************************/
-void Ssfdc_D_Reset(struct us_data *);
-int Ssfdc_D_ReadCisSect(struct us_data *, u8 *, u8 *);
-void Ssfdc_D_WriteRedtMode(void);
-void Ssfdc_D_ReadID(u8 *, u8);
-int Ssfdc_D_ReadSect(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_ReadBlock(struct us_data *, u16, u8 *, u8 *);
-int Ssfdc_D_WriteSect(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_WriteBlock(struct us_data *, u16, u8 *, u8 *);
-int Ssfdc_D_CopyBlock(struct us_data *, u16, u8 *, u8 *);
-int Ssfdc_D_WriteSectForCopy(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_EraseBlock(struct us_data *);
-int Ssfdc_D_ReadRedtData(struct us_data *, u8 *);
-int Ssfdc_D_WriteRedtData(struct us_data *, u8 *);
-int Ssfdc_D_CheckStatus(void);
-int Set_D_SsfdcModel(u8);
-void Cnt_D_Reset(void);
-int Cnt_D_PowerOn(void);
-void Cnt_D_PowerOff(void);
-void Cnt_D_LedOn(void);
-void Cnt_D_LedOff(void);
-int Check_D_CntPower(void);
-int Check_D_CardExist(void);
-int Check_D_CardStsChg(void);
-int Check_D_SsfdcWP(void);
-int SM_ReadBlock(struct us_data *, u8 *, u8 *);
-
-int Ssfdc_D_ReadSect_DMA(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_ReadSect_PIO(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_WriteSect_DMA(struct us_data *, u8 *, u8 *);
-int Ssfdc_D_WriteSect_PIO(struct us_data *, u8 *, u8 *);
-
-/******************************************/
-int Check_D_ReadError(u8 *);
-int Check_D_Correct(u8 *, u8 *);
-int Check_D_CISdata(u8 *, u8 *);
-void Set_D_RightECC(u8 *);
-
-/*
- * SMILECC.c
- */
-void calculate_ecc(u8 *, u8 *, u8 *, u8 *, u8 *);
-u8 correct_data(u8 *, u8 *, u8, u8, u8);
-int _Correct_D_SwECC(u8 *, u8 *, u8 *);
-void _Calculate_D_SwECC(u8 *, u8 *);
-
-#endif /* already included */
diff --git a/drivers/staging/keucr/smilecc.c b/drivers/staging/keucr/smilecc.c
deleted file mode 100644
index ffe6030f5e4d..000000000000
--- a/drivers/staging/keucr/smilecc.c
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-/* #include "stdlib.h" */
-/* #include "EUCR6SK.h" */
-#include "smcommon.h"
-#include "smil.h"
-
-/* #include <stdio.h> */
-/* #include <stdlib.h> */
-/* #include <string.h> */
-/* #include <dos.h> */
-/* #include "EMCRIOS.h" */
-
-/* CP0-CP5 code table */
-static u8 ecctable[256] = {
-0x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F, 0x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03,
-0x56, 0x55, 0x00, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
-0x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69,
-0x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65, 0x30, 0x33, 0x66, 0x03, 0x56, 0x55, 0x00,
-0x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03, 0x69,
-0x3C, 0x3F, 0x6A, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F,
-0x3C, 0x69, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00,
-0x55, 0x0F, 0x5A, 0x59, 0x0C, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55,
-0x55, 0x00, 0x03, 0x56, 0x0C, 0x59, 0x5A, 0x0F, 0x6A, 0x3F, 0x3C, 0x69, 0x33,
-0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F, 0x6A, 0x6A, 0x3F,
-0x3C, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F,
-0x6A, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56,
-0x0C, 0x59, 0x5A, 0x0F, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56,
-0x03, 0x00, 0x55, 0x0F, 0x5A, 0x59, 0x0C, 0x69, 0x3C, 0x3F, 0x6A, 0x30, 0x65,
-0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F, 0x3C, 0x69, 0x03, 0x56, 0x55,
-0x00, 0x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03,
-0x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69, 0x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65,
-0x30, 0x33, 0x66, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
-0x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F,
-0x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03, 0x56, 0x55, 0x00
-};
-
-static void trans_result(u8, u8, u8 *, u8 *);
-
-#define BIT7 0x80
-#define BIT6 0x40
-#define BIT5 0x20
-#define BIT4 0x10
-#define BIT3 0x08
-#define BIT2 0x04
-#define BIT1 0x02
-#define BIT0 0x01
-#define BIT1BIT0 0x03
-#define BIT23 0x00800000L
-#define MASK_CPS 0x3f
-#define CORRECTABLE 0x00555554L
-
-/*
- * reg2; * LP14,LP12,LP10,...
- * reg3; * LP15,LP13,LP11,...
- * *ecc1; * LP15,LP14,LP13,...
- * *ecc2; * LP07,LP06,LP05,...
- */
-static void trans_result(u8 reg2, u8 reg3, u8 *ecc1, u8 *ecc2)
-{
- u8 a; /* Working for reg2,reg3 */
- u8 b; /* Working for ecc1,ecc2 */
- u8 i; /* For counting */
-
- a = BIT7; b = BIT7; /* 80h=10000000b */
- *ecc1 = *ecc2 = 0; /* Clear ecc1,ecc2 */
- for (i = 0; i < 4; ++i) {
- if ((reg3&a) != 0)
- *ecc1 |= b; /* LP15,13,11,9 -> ecc1 */
- b = b>>1; /* Right shift */
- if ((reg2&a) != 0)
- *ecc1 |= b; /* LP14,12,10,8 -> ecc1 */
- b = b>>1; /* Right shift */
- a = a>>1; /* Right shift */
- }
-
- b = BIT7; /* 80h=10000000b */
- for (i = 0; i < 4; ++i) {
- if ((reg3&a) != 0)
- *ecc2 |= b; /* LP7,5,3,1 -> ecc2 */
- b = b>>1; /* Right shift */
- if ((reg2&a) != 0)
- *ecc2 |= b; /* LP6,4,2,0 -> ecc2 */
- b = b>>1; /* Right shift */
- a = a>>1; /* Right shift */
- }
-}
-
-/*static void calculate_ecc(table,data,ecc1,ecc2,ecc3) */
-/*
- * *table; * CP0-CP5 code table
- * *data; * DATA
- * *ecc1; * LP15,LP14,LP13,...
- * *ecc2; * LP07,LP06,LP05,...
- * *ecc3; * CP5,CP4,CP3,...,"1","1"
- */
-void calculate_ecc(u8 *table, u8 *data, u8 *ecc1, u8 *ecc2, u8 *ecc3)
-{
- u32 i; /* For counting */
- u8 a; /* Working for table */
- u8 reg1; /* D-all,CP5,CP4,CP3,... */
- u8 reg2; /* LP14,LP12,L10,... */
- u8 reg3; /* LP15,LP13,L11,... */
-
- reg1 = reg2 = reg3 = 0; /* Clear parameter */
- for (i = 0; i < 256; ++i) {
- a = table[data[i]]; /* Get CP0-CP5 code from table */
- reg1 ^= (a&MASK_CPS); /* XOR with a */
- if ((a&BIT6) != 0) { /* If D_all(all bit XOR) = 1 */
- reg3 ^= (u8)i; /* XOR with counter */
- reg2 ^= ~((u8)i); /* XOR with inv. of counter */
- }
- }
-
- /* Trans LP14,12,10,... & LP15,13,11,... ->
- LP15,14,13,... & LP7,6,5,.. */
- trans_result(reg2, reg3, ecc1, ecc2);
- *ecc1 = ~(*ecc1); *ecc2 = ~(*ecc2); /* Inv. ecc2 & ecc3 */
- *ecc3 = ((~reg1)<<2)|BIT1BIT0; /* Make TEL format */
-}
-
-/*
- * *data; * DATA
- * *eccdata; * ECC DATA
- * ecc1; * LP15,LP14,LP13,...
- * ecc2; * LP07,LP06,LP05,...
- * ecc3; * CP5,CP4,CP3,...,"1","1"
- */
-u8 correct_data(u8 *data, u8 *eccdata, u8 ecc1, u8 ecc2, u8 ecc3)
-{
- u32 l; /* Working to check d */
- u32 d; /* Result of comparison */
- u32 i; /* For counting */
- u8 d1, d2, d3; /* Result of comparison */
- u8 a; /* Working for add */
- u8 add; /* Byte address of cor. DATA */
- u8 b; /* Working for bit */
- u8 bit; /* Bit address of cor. DATA */
-
- d1 = ecc1^eccdata[1]; d2 = ecc2^eccdata[0]; /* Compare LP's */
- d3 = ecc3^eccdata[2]; /* Compare CP's */
- d = ((u32)d1<<16) /* Result of comparison */
- +((u32)d2<<8)
- +(u32)d3;
-
- if (d == 0)
- return 0; /* If No error, return */
-
- if (((d^(d>>1))&CORRECTABLE) == CORRECTABLE) { /* If correctable */
- l = BIT23;
- add = 0; /* Clear parameter */
- a = BIT7;
-
- for (i = 0; i < 8; ++i) { /* Checking 8 bit */
- if ((d&l) != 0)
- add |= a; /* Make byte address from LP's */
- l >>= 2; a >>= 1; /* Right Shift */
- }
-
- bit = 0; /* Clear parameter */
- b = BIT2;
- for (i = 0; i < 3; ++i) { /* Checking 3 bit */
- if ((d&l) != 0)
- bit |= b; /* Make bit address from CP's */
- l >>= 2; b >>= 1; /* Right shift */
- }
-
- b = BIT0;
- data[add] ^= (b<<bit); /* Put corrected data */
- return 1;
- }
-
- i = 0; /* Clear count */
- d &= 0x00ffffffL; /* Masking */
-
- while (d) { /* If d=0 finish counting */
- if (d&BIT0)
- ++i; /* Count number of 1 bit */
- d >>= 1; /* Right shift */
- }
-
- if (i == 1) { /* If ECC error */
- eccdata[1] = ecc1; eccdata[0] = ecc2; /* Put right ECC code */
- eccdata[2] = ecc3;
- return 2;
- }
- return 3; /* Uncorrectable error */
-}
-
-int _Correct_D_SwECC(u8 *buf, u8 *redundant_ecc, u8 *calculate_ecc)
-{
- u32 err;
-
- err = correct_data(buf, redundant_ecc, *(calculate_ecc + 1),
- *(calculate_ecc), *(calculate_ecc + 2));
- if (err == 1)
- memcpy(calculate_ecc, redundant_ecc, 3);
-
- if (err == 0 || err == 1 || err == 2)
- return 0;
-
- return -1;
-}
-
-void _Calculate_D_SwECC(u8 *buf, u8 *ecc)
-{
- calculate_ecc(ecctable, buf, ecc+1, ecc+0, ecc+2);
-}
-
-
diff --git a/drivers/staging/keucr/smilmain.c b/drivers/staging/keucr/smilmain.c
deleted file mode 100644
index 42ec8a669ad3..000000000000
--- a/drivers/staging/keucr/smilmain.c
+++ /dev/null
@@ -1,760 +0,0 @@
-#include <linux/slab.h>
-#include "usb.h"
-#include "scsiglue.h"
-#include "smcommon.h"
-#include "smil.h"
-
-static int Conv_D_MediaAddr(struct us_data *, u32);
-static int Inc_D_MediaAddr(struct us_data *);
-static int Media_D_ReadOneSect(struct us_data *, u16, u8 *);
-
-static int Copy_D_BlockAll(struct us_data *, u32);
-
-static int Assign_D_WriteBlock(void);
-static int Release_D_ReadBlock(struct us_data *);
-static int Release_D_WriteBlock(struct us_data *);
-static int Release_D_CopySector(struct us_data *);
-
-static int Copy_D_PhyOneSect(struct us_data *);
-static int Read_D_PhyOneSect(struct us_data *, u16, u8 *);
-static int Erase_D_PhyOneBlock(struct us_data *);
-
-static int Set_D_PhyFmtValue(struct us_data *);
-static int Search_D_CIS(struct us_data *);
-static int Make_D_LogTable(struct us_data *);
-
-static int MarkFail_D_PhyOneBlock(struct us_data *);
-
-static u32 ErrCode;
-static u8 WorkBuf[SECTSIZE];
-static u8 Redundant[REDTSIZE];
-static u8 WorkRedund[REDTSIZE];
-/* 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; */
-static u16 *Log2Phy[MAX_ZONENUM];
-static u8 Assign[MAX_ZONENUM][MAX_BLOCKNUM / 8];
-static u16 AssignStart[MAX_ZONENUM];
-u16 ReadBlock;
-u16 WriteBlock;
-u32 MediaChange;
-static u32 SectCopyMode;
-
-/* BIT Control Macro */
-static u8 BitData[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
-#define Set_D_Bit(a, b) (a[(u8)((b) / 8)] |= BitData[(b) % 8])
-#define Clr_D_Bit(a, b) (a[(u8)((b) / 8)] &= ~BitData[(b) % 8])
-#define Chk_D_Bit(a, b) (a[(u8)((b) / 8)] & BitData[(b) % 8])
-
-/* ----- SM_FreeMem() ------------------------------------------------- */
-int SM_FreeMem(void)
-{
- int i;
-
- pr_info("SM_FreeMem start\n");
- for (i = 0; i < MAX_ZONENUM; i++) {
- if (Log2Phy[i] != NULL) {
- pr_info("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
- kfree(Log2Phy[i]);
- Log2Phy[i] = NULL;
- }
- }
- return NO_ERROR;
-}
-
-/* SmartMedia Read/Write/Erase Function */
-/* ----- Media_D_ReadSector() ------------------------------------------- */
-int Media_D_ReadSector(struct us_data *us, u32 start, u16 count, u8 *buf)
-{
- u16 len, bn;
-
- if (Conv_D_MediaAddr(us, start))
- return ErrCode;
-
- while (1) {
- len = Ssfdc.MaxSectors - Media.Sector;
- if (count > len)
- bn = len;
- else
- bn = count;
-
- if (Media_D_ReadOneSect(us, bn, buf)) {
- ErrCode = ERR_EccReadErr;
- return ErrCode;
- }
-
- Media.Sector += bn;
- count -= bn;
-
- if (count <= 0)
- break;
-
- buf += bn * SECTSIZE;
-
- if (Inc_D_MediaAddr(us))
- return ErrCode;
- }
-
- return NO_ERROR;
-}
-/* here */
-/* ----- Media_D_CopySector() ------------------------------------------ */
-int Media_D_CopySector(struct us_data *us, u32 start, u16 count, u8 *buf)
-{
- u16 len, bn;
-
- /* pr_info("Media_D_CopySector !!!\n"); */
- if (Conv_D_MediaAddr(us, start))
- return ErrCode;
-
- while (1) {
- if (Assign_D_WriteBlock())
- return ERROR;
-
- len = Ssfdc.MaxSectors - Media.Sector;
- if (count > len)
- bn = len;
- else
- bn = count;
-
- if (Ssfdc_D_CopyBlock(us, bn, buf, Redundant)) {
- ErrCode = ERR_WriteFault;
- return ErrCode;
- }
-
- Media.Sector = 0x1F;
- if (Release_D_CopySector(us)) {
- if (ErrCode == ERR_HwError) {
- ErrCode = ERR_WriteFault;
- return ErrCode;
- }
- }
- count -= bn;
-
- if (count <= 0)
- break;
-
- buf += bn * SECTSIZE;
-
- if (Inc_D_MediaAddr(us))
- return ErrCode;
-
- }
- return NO_ERROR;
-}
-
-/* SmartMedia Physical Format Test Subroutine */
-/* ----- Check_D_MediaFmt() --------------------------------------------- */
-int Check_D_MediaFmt(struct us_data *us)
-{
- pr_info("Check_D_MediaFmt\n");
-
- if (!MediaChange)
- return SMSUCCESS;
-
- MediaChange = ERROR;
- SectCopyMode = COMPLETED;
-
- if (Set_D_PhyFmtValue(us)) {
- ErrCode = ERR_UnknownMedia;
- return ERROR;
- }
-
- if (Search_D_CIS(us)) {
- ErrCode = ERR_IllegalFmt;
- return ERROR;
- }
-
- MediaChange = SMSUCCESS;
- return SMSUCCESS;
-}
-
-/* ----- Release_D_CopySector() ------------------------------------------ */
-static int Release_D_CopySector(struct us_data *us)
-{
- Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
- Media.PhyBlock = ReadBlock;
-
- if (Media.PhyBlock == NO_ASSIGN) {
- Media.PhyBlock = WriteBlock;
- return SMSUCCESS;
- }
-
- Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
- Media.PhyBlock = WriteBlock;
-
- return SMSUCCESS;
-}
-
-/* SmartMedia Physical Address Control Subroutine */
-/* ----- Conv_D_MediaAddr() --------------------------------------------- */
-static int Conv_D_MediaAddr(struct us_data *us, u32 addr)
-{
- u32 temp;
-
- temp = addr / Ssfdc.MaxSectors;
- Media.Zone = (u8) (temp / Ssfdc.MaxLogBlocks);
-
- if (Log2Phy[Media.Zone] == NULL) {
- if (Make_D_LogTable(us)) {
- ErrCode = ERR_IllegalFmt;
- return ERROR;
- }
- }
-
- Media.Sector = (u8) (addr % Ssfdc.MaxSectors);
- Media.LogBlock = (u16) (temp % Ssfdc.MaxLogBlocks);
-
- if (Media.Zone < Ssfdc.MaxZones) {
- Clr_D_RedundantData(Redundant);
- Set_D_LogBlockAddr(Redundant);
- Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
- return SMSUCCESS;
- }
-
- ErrCode = ERR_OutOfLBA;
- return ERROR;
-}
-
-/* ----- Inc_D_MediaAddr() ---------------------------------------------- */
-static int Inc_D_MediaAddr(struct us_data *us)
-{
- u16 LogBlock = Media.LogBlock;
-
- if (++Media.Sector < Ssfdc.MaxSectors)
- return SMSUCCESS;
-
- if (Log2Phy[Media.Zone] == NULL) {
- if (Make_D_LogTable(us)) {
- ErrCode = ERR_IllegalFmt;
- return ERROR;
- }
- }
-
- Media.Sector = 0;
- Media.LogBlock = LogBlock;
-
- if (++Media.LogBlock < Ssfdc.MaxLogBlocks) {
- Clr_D_RedundantData(Redundant);
- Set_D_LogBlockAddr(Redundant);
- Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
- return SMSUCCESS;
- }
-
- Media.LogBlock = 0;
-
- if (++Media.Zone < Ssfdc.MaxZones) {
- if (Log2Phy[Media.Zone] == NULL) {
- if (Make_D_LogTable(us)) {
- ErrCode = ERR_IllegalFmt;
- return ERROR;
- }
- }
-
- Media.LogBlock = 0;
-
- Clr_D_RedundantData(Redundant);
- Set_D_LogBlockAddr(Redundant);
- Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
- return SMSUCCESS;
- }
-
- Media.Zone = 0;
- ErrCode = ERR_OutOfLBA;
-
- return ERROR;
-}
-
-/* SmartMedia Read/Write Subroutine with Retry */
-/* ----- Media_D_ReadOneSect() ------------------------------------------ */
-static int Media_D_ReadOneSect(struct us_data *us, u16 count, u8 *buf)
-{
- u32 err, retry;
-
- if (!Read_D_PhyOneSect(us, count, buf))
- return SMSUCCESS;
- if (ErrCode == ERR_HwError)
- return ERROR;
- if (ErrCode == ERR_DataStatus)
- return ERROR;
-
-#ifdef RDERR_REASSIGN
- if (Ssfdc.Attribute & MWP) {
- if (ErrCode == ERR_CorReadErr)
- return SMSUCCESS;
- return ERROR;
- }
-
- err = ErrCode;
- for (retry = 0; retry < 2; retry++) {
- if (Copy_D_BlockAll(us,
- (err == ERR_EccReadErr) ? REQ_FAIL : REQ_ERASE)) {
- if (ErrCode == ERR_HwError)
- return ERROR;
- continue;
- }
-
- ErrCode = err;
- if (ErrCode == ERR_CorReadErr)
- return SMSUCCESS;
- return ERROR;
- }
-
- MediaChange = ERROR;
-#else
- if (ErrCode == ERR_CorReadErr)
- return SMSUCCESS;
-#endif
-
- return ERROR;
-}
-
-/* SmartMedia Physical Sector Data Copy Subroutine */
-/* ----- Copy_D_BlockAll() ---------------------------------------------- */
-static int Copy_D_BlockAll(struct us_data *us, u32 mode)
-{
- u8 sect;
-
- sect = Media.Sector;
-
- if (Assign_D_WriteBlock())
- return ERROR;
- if (mode == REQ_FAIL)
- SectCopyMode = REQ_FAIL;
-
- for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
- Media.Sector++) {
- if (Copy_D_PhyOneSect(us)) {
- if (ErrCode == ERR_HwError)
- return ERROR;
- if (Release_D_WriteBlock(us))
- return ERROR;
-
- ErrCode = ERR_WriteFault;
- Media.PhyBlock = ReadBlock;
- Media.Sector = sect;
-
- return ERROR;
- }
- }
-
- if (Release_D_ReadBlock(us))
- return ERROR;
-
- Media.PhyBlock = WriteBlock;
- Media.Sector = sect;
- return SMSUCCESS;
-}
-
-/* SmartMedia Physical Block Assign/Release Subroutine */
-/* ----- Assign_D_WriteBlock() ------------------------------------------ */
-static int Assign_D_WriteBlock(void)
-{
- ReadBlock = Media.PhyBlock;
-
- for (WriteBlock = AssignStart[Media.Zone];
- WriteBlock < Ssfdc.MaxBlocks; WriteBlock++) {
- if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
- Set_D_Bit(Assign[Media.Zone], WriteBlock);
- AssignStart[Media.Zone] = WriteBlock + 1;
- Media.PhyBlock = WriteBlock;
- SectCopyMode = REQ_ERASE;
- return SMSUCCESS;
- }
- }
-
- for (WriteBlock = 0;
- WriteBlock < AssignStart[Media.Zone]; WriteBlock++) {
- if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
- Set_D_Bit(Assign[Media.Zone], WriteBlock);
- AssignStart[Media.Zone] = WriteBlock + 1;
- Media.PhyBlock = WriteBlock;
- SectCopyMode = REQ_ERASE;
- return SMSUCCESS;
- }
- }
-
- WriteBlock = NO_ASSIGN;
- ErrCode = ERR_WriteFault;
-
- return ERROR;
-}
-
-/* ----- Release_D_ReadBlock() ------------------------------------------ */
-static int Release_D_ReadBlock(struct us_data *us)
-{
- u32 mode;
-
- mode = SectCopyMode;
- SectCopyMode = COMPLETED;
-
- if (mode == COMPLETED)
- return SMSUCCESS;
-
- Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
- Media.PhyBlock = ReadBlock;
-
- if (Media.PhyBlock == NO_ASSIGN) {
- Media.PhyBlock = WriteBlock;
- return SMSUCCESS;
- }
-
- if (mode == REQ_ERASE) {
- if (Erase_D_PhyOneBlock(us)) {
- if (ErrCode == ERR_HwError)
- return ERROR;
- if (MarkFail_D_PhyOneBlock(us))
- return ERROR;
- } else
- Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
- } else if (MarkFail_D_PhyOneBlock(us))
- return ERROR;
-
- Media.PhyBlock = WriteBlock;
- return SMSUCCESS;
-}
-
-/* ----- Release_D_WriteBlock() ----------------------------------------- */
-static int Release_D_WriteBlock(struct us_data *us)
-{
- SectCopyMode = COMPLETED;
- Media.PhyBlock = WriteBlock;
-
- if (MarkFail_D_PhyOneBlock(us))
- return ERROR;
-
- Media.PhyBlock = ReadBlock;
- return SMSUCCESS;
-}
-
-/* SmartMedia Physical Sector Data Copy Subroutine */
-/* ----- Copy_D_PhyOneSect() -------------------------------------------- */
-static int Copy_D_PhyOneSect(struct us_data *us)
-{
- int i;
- u32 err, retry;
-
- /* pr_info("Copy_D_PhyOneSect --- Sector = %x\n", Media.Sector); */
- if (ReadBlock != NO_ASSIGN) {
- Media.PhyBlock = ReadBlock;
- for (retry = 0; retry < 2; retry++) {
- if (retry != 0) {
- Ssfdc_D_Reset(us);
- if (Ssfdc_D_ReadCisSect(us, WorkBuf,
- WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
-
- if (Check_D_CISdata(WorkBuf, WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- }
-
- if (Ssfdc_D_ReadSect(us, WorkBuf, WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- if (Check_D_DataStatus(WorkRedund)) {
- err = ERROR;
- break;
- }
- if (!Check_D_ReadError(WorkRedund)) {
- err = SMSUCCESS;
- break;
- }
- if (!Check_D_Correct(WorkBuf, WorkRedund)) {
- err = SMSUCCESS;
- break;
- }
-
- err = ERROR;
- SectCopyMode = REQ_FAIL;
- }
- } else {
- err = SMSUCCESS;
- for (i = 0; i < SECTSIZE; i++)
- WorkBuf[i] = DUMMY_DATA;
- Clr_D_RedundantData(WorkRedund);
- }
-
- Set_D_LogBlockAddr(WorkRedund);
- if (err == ERROR) {
- Set_D_RightECC(WorkRedund);
- Set_D_DataStaus(WorkRedund);
- }
-
- Media.PhyBlock = WriteBlock;
-
- if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- if (Ssfdc_D_CheckStatus()) {
- ErrCode = ERR_WriteFault;
- return ERROR;
- }
-
- Media.PhyBlock = ReadBlock;
- return SMSUCCESS;
-}
-
-/* SmartMedia Physical Sector Read/Write/Erase Subroutine */
-/* ----- Read_D_PhyOneSect() -------------------------------------------- */
-static int Read_D_PhyOneSect(struct us_data *us, u16 count, u8 *buf)
-{
- int i;
- u32 retry;
-
- if (Media.PhyBlock == NO_ASSIGN) {
- for (i = 0; i < SECTSIZE; i++)
- *buf++ = DUMMY_DATA;
- return SMSUCCESS;
- }
-
- for (retry = 0; retry < 2; retry++) {
- if (retry != 0) {
- Ssfdc_D_Reset(us);
-
- if (Ssfdc_D_ReadCisSect(us, WorkBuf, WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- if (Check_D_CISdata(WorkBuf, WorkRedund)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- }
-
- if (Ssfdc_D_ReadBlock(us, count, buf, Redundant)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- if (Check_D_DataStatus(Redundant)) {
- ErrCode = ERR_DataStatus;
- return ERROR;
- }
-
- if (!Check_D_ReadError(Redundant))
- return SMSUCCESS;
-
- if (!Check_D_Correct(buf, Redundant)) {
- ErrCode = ERR_CorReadErr;
- return ERROR;
- }
- }
-
- ErrCode = ERR_EccReadErr;
- return ERROR;
-}
-
-/* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
-static int Erase_D_PhyOneBlock(struct us_data *us)
-{
- if (Ssfdc_D_EraseBlock(us)) {
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- }
- if (Ssfdc_D_CheckStatus()) {
- ErrCode = ERR_WriteFault;
- return ERROR;
- }
-
- return SMSUCCESS;
-}
-
-/* SmartMedia Physical Format Check Local Subroutine */
-/* ----- Set_D_PhyFmtValue() -------------------------------------------- */
-static int Set_D_PhyFmtValue(struct us_data *us)
-{
- if (Set_D_SsfdcModel(us->SM_DeviceID))
- return ERROR;
-
- return SMSUCCESS;
-}
-
-/* ----- Search_D_CIS() ------------------------------------------------- */
-static int Search_D_CIS(struct us_data *us)
-{
- Media.Zone = 0;
- Media.Sector = 0;
-
- for (Media.PhyBlock = 0;
- Media.PhyBlock < (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1);
- Media.PhyBlock++) {
- if (Ssfdc_D_ReadRedtData(us, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- if (!Check_D_FailBlock(Redundant))
- break;
- }
-
- if (Media.PhyBlock == (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- while (Media.Sector < CIS_SEARCH_SECT) {
- if (Media.Sector) {
- if (Ssfdc_D_ReadRedtData(us, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
- }
- if (!Check_D_DataStatus(Redundant)) {
- if (Ssfdc_D_ReadSect(us, WorkBuf, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- if (Check_D_CISdata(WorkBuf, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- CisArea.PhyBlock = Media.PhyBlock;
- CisArea.Sector = Media.Sector;
- Ssfdc_D_Reset(us);
- return SMSUCCESS;
- }
-
- Media.Sector++;
- }
-
- Ssfdc_D_Reset(us);
- return ERROR;
-}
-
-/* ----- Make_D_LogTable() ---------------------------------------------- */
-static int Make_D_LogTable(struct us_data *us)
-{
- u16 phyblock, logblock;
-
- if (Log2Phy[Media.Zone] == NULL) {
- Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK * sizeof(u16),
- GFP_KERNEL);
- /* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
- Media.Zone, Log2Phy[Media.Zone]); */
- if (Log2Phy[Media.Zone] == NULL)
- return ERROR;
- }
-
- Media.Sector = 0;
-
- /* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
- Media.Zone); */
- for (Media.LogBlock = 0; Media.LogBlock < Ssfdc.MaxLogBlocks;
- Media.LogBlock++)
- Log2Phy[Media.Zone][Media.LogBlock] = NO_ASSIGN;
-
- for (Media.PhyBlock = 0; Media.PhyBlock < (MAX_BLOCKNUM / 8);
- Media.PhyBlock++)
- Assign[Media.Zone][Media.PhyBlock] = 0x00;
-
- for (Media.PhyBlock = 0; Media.PhyBlock < Ssfdc.MaxBlocks;
- Media.PhyBlock++) {
- if ((!Media.Zone) && (Media.PhyBlock <= CisArea.PhyBlock)) {
- Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
- continue;
- }
-
- if (Ssfdc_D_ReadRedtData(us, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- if (!Check_D_DataBlank(Redundant))
- continue;
-
- Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
-
- if (Check_D_FailBlock(Redundant))
- continue;
-
- if (Load_D_LogBlockAddr(Redundant))
- continue;
-
- if (Media.LogBlock >= Ssfdc.MaxLogBlocks)
- continue;
-
- if (Log2Phy[Media.Zone][Media.LogBlock] == NO_ASSIGN) {
- Log2Phy[Media.Zone][Media.LogBlock] = Media.PhyBlock;
- continue;
- }
-
- phyblock = Media.PhyBlock;
- logblock = Media.LogBlock;
- Media.Sector = (u8)(Ssfdc.MaxSectors - 1);
-
- if (Ssfdc_D_ReadRedtData(us, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- if (!Load_D_LogBlockAddr(Redundant) &&
- (Media.LogBlock == logblock)) {
- Media.PhyBlock = Log2Phy[Media.Zone][logblock];
-
- if (Ssfdc_D_ReadRedtData(us, Redundant)) {
- Ssfdc_D_Reset(us);
- return ERROR;
- }
-
- Media.PhyBlock = phyblock;
-
- if (!Load_D_LogBlockAddr(Redundant)) {
- if (Media.LogBlock != logblock) {
- Media.PhyBlock =
- Log2Phy[Media.Zone][logblock];
- Log2Phy[Media.Zone][logblock] =
- phyblock;
- }
- } else {
- Media.PhyBlock = Log2Phy[Media.Zone][logblock];
- Log2Phy[Media.Zone][logblock] = phyblock;
- }
- }
-
- Media.Sector = 0;
- Media.PhyBlock = phyblock;
-
- AssignStart[Media.Zone] = 0;
-
- } /* End for (Media.Zone<MAX_ZONENUM) */
-
- Ssfdc_D_Reset(us);
- return SMSUCCESS;
-}
-
-/* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
-static int MarkFail_D_PhyOneBlock(struct us_data *us)
-{
- u8 sect;
-
- sect = Media.Sector;
- Set_D_FailBlock(WorkRedund);
-
- for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
- Media.Sector++) {
- if (Ssfdc_D_WriteRedtData(us, WorkRedund)) {
- Ssfdc_D_Reset(us);
- Media.Sector = sect;
- ErrCode = ERR_HwError;
- MediaChange = ERROR;
- return ERROR;
- } /* NO Status Check */
- }
-
- Ssfdc_D_Reset(us);
- Media.Sector = sect;
- return SMSUCCESS;
-}
diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c
deleted file mode 100644
index e981f14f3bf9..000000000000
--- a/drivers/staging/keucr/smilsub.c
+++ /dev/null
@@ -1,679 +0,0 @@
-#include <linux/slab.h>
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-
-#include "smcommon.h"
-#include "smil.h"
-
-static u8 _Check_D_DevCode(u8);
-static u32 ErrXDCode;
-static u8 IsSSFDCCompliance;
-static u8 IsXDCompliance;
-
-struct keucr_media_info Ssfdc;
-struct keucr_media_address Media;
-struct keucr_media_area CisArea;
-
-static u8 EccBuf[6];
-
-#define EVEN 0 /* Even Page for 256byte/page */
-#define ODD 1 /* Odd Page for 256byte/page */
-
-
-/* SmartMedia Redundant buffer data Control Subroutine
- *----- Check_D_DataBlank() --------------------------------------------
- */
-int Check_D_DataBlank(u8 *redundant)
-{
- char i;
-
- for (i = 0; i < REDTSIZE; i++)
- if (*redundant++ != 0xFF)
- return ERROR;
-
- return SMSUCCESS;
-}
-
-/* ----- Check_D_FailBlock() -------------------------------------------- */
-int Check_D_FailBlock(u8 *redundant)
-{
- redundant += REDT_BLOCK;
-
- if (*redundant == 0xFF)
- return SMSUCCESS;
- if (!*redundant)
- return ERROR;
- if (hweight8(*redundant) < 7)
- return ERROR;
-
- return SMSUCCESS;
-}
-
-/* ----- Check_D_DataStatus() ------------------------------------------- */
-int Check_D_DataStatus(u8 *redundant)
-{
- redundant += REDT_DATA;
-
- if (*redundant == 0xFF)
- return SMSUCCESS;
- if (!*redundant) {
- ErrXDCode = ERR_DataStatus;
- return ERROR;
- } else
- ErrXDCode = NO_ERROR;
-
- if (hweight8(*redundant) < 5)
- return ERROR;
-
- return SMSUCCESS;
-}
-
-/* ----- Load_D_LogBlockAddr() ------------------------------------------ */
-int Load_D_LogBlockAddr(u8 *redundant)
-{
- u16 addr1, addr2;
-
- addr1 = (u16)*(redundant + REDT_ADDR1H)*0x0100 +
- (u16)*(redundant + REDT_ADDR1L);
- addr2 = (u16)*(redundant + REDT_ADDR2H)*0x0100 +
- (u16)*(redundant + REDT_ADDR2L);
-
- if (addr1 == addr2)
- if ((addr1 & 0xF000) == 0x1000) {
- Media.LogBlock = (addr1 & 0x0FFF) / 2;
- return SMSUCCESS;
- }
-
- if (hweight16((u16)(addr1^addr2)) != 0x01)
- return ERROR;
-
- if ((addr1 & 0xF000) == 0x1000)
- if (!(hweight16(addr1) & 0x01)) {
- Media.LogBlock = (addr1 & 0x0FFF) / 2;
- return SMSUCCESS;
- }
-
- if ((addr2 & 0xF000) == 0x1000)
- if (!(hweight16(addr2) & 0x01)) {
- Media.LogBlock = (addr2 & 0x0FFF) / 2;
- return SMSUCCESS;
- }
-
- return ERROR;
-}
-
-/* ----- Clr_D_RedundantData() ------------------------------------------ */
-void Clr_D_RedundantData(u8 *redundant)
-{
- char i;
-
- for (i = 0; i < REDTSIZE; i++)
- *(redundant + i) = 0xFF;
-}
-
-/* ----- Set_D_LogBlockAddr() ------------------------------------------- */
-void Set_D_LogBlockAddr(u8 *redundant)
-{
- u16 addr;
-
- *(redundant + REDT_BLOCK) = 0xFF;
- *(redundant + REDT_DATA) = 0xFF;
- addr = Media.LogBlock*2 + 0x1000;
-
- if ((hweight16(addr) % 2))
- addr++;
-
- *(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) =
- (u8)(addr / 0x0100);
- *(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (u8)addr;
-}
-
-/*----- Set_D_FailBlock() ---------------------------------------------- */
-void Set_D_FailBlock(u8 *redundant)
-{
- char i;
-
- for (i = 0; i < REDTSIZE; i++)
- *redundant++ = (u8)((i == REDT_BLOCK) ? 0xF0 : 0xFF);
-}
-
-/* ----- Set_D_DataStaus() ---------------------------------------------- */
-void Set_D_DataStaus(u8 *redundant)
-{
- redundant += REDT_DATA;
- *redundant = 0x00;
-}
-
-/* SmartMedia Function Command Subroutine
- * 6250 CMD 6
- */
-/* ----- Ssfdc_D_Reset() ------------------------------------------------ */
-void Ssfdc_D_Reset(struct us_data *us)
-{
- return;
-}
-
-/* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
-int Ssfdc_D_ReadCisSect(struct us_data *us, u8 *buf, u8 *redundant)
-{
- u8 zone, sector;
- u16 block;
-
- zone = Media.Zone; block = Media.PhyBlock; sector = Media.Sector;
- Media.Zone = 0;
- Media.PhyBlock = CisArea.PhyBlock;
- Media.Sector = CisArea.Sector;
-
- if (Ssfdc_D_ReadSect(us, buf, redundant)) {
- Media.Zone = zone;
- Media.PhyBlock = block;
- Media.Sector = sector;
- return ERROR;
- }
-
- Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
- return SMSUCCESS;
-}
-
-/* 6250 CMD 1 */
-/* ----- Ssfdc_D_ReadSect() --------------------------------------------- */
-int Ssfdc_D_ReadSect(struct us_data *us, u8 *buf, u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors + Media.Sector;
-
- /* Read sect data */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x02;
- bcb->CDB[4] = (u8)addr;
- bcb->CDB[3] = (u8)(addr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* Read redundant */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x10;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x03;
- bcb->CDB[4] = (u8)addr;
- bcb->CDB[3] = (u8)(addr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
- bcb->CDB[8] = 0;
- bcb->CDB[9] = 1;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
-int Ssfdc_D_ReadBlock(struct us_data *us, u16 count, u8 *buf,
- u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors + Media.Sector;
-
- /* Read sect data */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200*count;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x02;
- bcb->CDB[4] = (u8)addr;
- bcb->CDB[3] = (u8)(addr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* Read redundant */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x10;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x03;
- bcb->CDB[4] = (u8)addr;
- bcb->CDB[3] = (u8)(addr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
- bcb->CDB[8] = 0;
- bcb->CDB[9] = 1;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-
-/* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
-int Ssfdc_D_CopyBlock(struct us_data *us, u16 count, u8 *buf,
- u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 ReadAddr, WriteAddr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- ReadAddr = (u16)Media.Zone*Ssfdc.MaxBlocks + ReadBlock;
- ReadAddr = ReadAddr*(u16)Ssfdc.MaxSectors;
- WriteAddr = (u16)Media.Zone*Ssfdc.MaxBlocks + WriteBlock;
- WriteAddr = WriteAddr*(u16)Ssfdc.MaxSectors;
-
- /* Write sect data */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200*count;
- bcb->Flags = 0x00;
- bcb->CDB[0] = 0xF0;
- bcb->CDB[1] = 0x08;
- bcb->CDB[7] = (u8)WriteAddr;
- bcb->CDB[6] = (u8)(WriteAddr / 0x0100);
- bcb->CDB[5] = Media.Zone / 2;
- bcb->CDB[8] = *(redundant + REDT_ADDR1H);
- bcb->CDB[9] = *(redundant + REDT_ADDR1L);
- bcb->CDB[10] = Media.Sector;
-
- if (ReadBlock != NO_ASSIGN) {
- bcb->CDB[4] = (u8)ReadAddr;
- bcb->CDB[3] = (u8)(ReadAddr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
- } else
- bcb->CDB[11] = 1;
-
- result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
-int Ssfdc_D_WriteSectForCopy(struct us_data *us, u8 *buf, u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors + Media.Sector;
-
- /* Write sect data */
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200;
- bcb->Flags = 0x00;
- bcb->CDB[0] = 0xF0;
- bcb->CDB[1] = 0x04;
- bcb->CDB[7] = (u8)addr;
- bcb->CDB[6] = (u8)(addr / 0x0100);
- bcb->CDB[5] = Media.Zone / 2;
- bcb->CDB[8] = *(redundant + REDT_ADDR1H);
- bcb->CDB[9] = *(redundant + REDT_ADDR1L);
-
- result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* 6250 CMD 5 */
-/* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
-int Ssfdc_D_EraseBlock(struct us_data *us)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors;
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x200;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF2;
- bcb->CDB[1] = 0x06;
- bcb->CDB[7] = (u8)addr;
- bcb->CDB[6] = (u8)(addr / 0x0100);
- bcb->CDB[5] = Media.Zone / 2;
-
- result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* 6250 CMD 2 */
-/*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
-int Ssfdc_D_ReadRedtData(struct us_data *us, u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
- u8 *buf;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors + Media.Sector;
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x10;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF1;
- bcb->CDB[1] = 0x03;
- bcb->CDB[4] = (u8)addr;
- bcb->CDB[3] = (u8)(addr / 0x0100);
- bcb->CDB[2] = Media.Zone / 2;
- bcb->CDB[8] = 0;
- bcb->CDB[9] = 1;
-
- buf = kmalloc(0x10, GFP_KERNEL);
- result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
- memcpy(redundant, buf, 0x10);
- kfree(buf);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* 6250 CMD 4 */
-/* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
-int Ssfdc_D_WriteRedtData(struct us_data *us, u8 *redundant)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- int result;
- u16 addr;
-
- result = ENE_LoadBinCode(us, SM_RW_PATTERN);
- if (result != USB_STOR_XFER_GOOD) {
- dev_err(&us->pusb_dev->dev,
- "Failed to load SmartMedia read/write code\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- addr = (u16)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
- addr = addr*(u16)Ssfdc.MaxSectors + Media.Sector;
-
- memset(bcb, 0, sizeof(struct bulk_cb_wrap));
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = 0x10;
- bcb->Flags = 0x80;
- bcb->CDB[0] = 0xF2;
- bcb->CDB[1] = 0x05;
- bcb->CDB[7] = (u8)addr;
- bcb->CDB[6] = (u8)(addr / 0x0100);
- bcb->CDB[5] = Media.Zone / 2;
- bcb->CDB[8] = *(redundant + REDT_ADDR1H);
- bcb->CDB[9] = *(redundant + REDT_ADDR1L);
-
- result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
-int Ssfdc_D_CheckStatus(void)
-{
- return SMSUCCESS;
-}
-
-
-
-/* SmartMedia ID Code Check & Mode Set Subroutine
- * ----- Set_D_SsfdcModel() ---------------------------------------------
- */
-int Set_D_SsfdcModel(u8 dcode)
-{
- switch (_Check_D_DevCode(dcode)) {
- case SSFDC1MB:
- Ssfdc.Model = SSFDC1MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
- Ssfdc.MaxZones = 1;
- Ssfdc.MaxBlocks = 256;
- Ssfdc.MaxLogBlocks = 250;
- Ssfdc.MaxSectors = 8;
- break;
- case SSFDC2MB:
- Ssfdc.Model = SSFDC2MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256;
- Ssfdc.MaxZones = 1;
- Ssfdc.MaxBlocks = 512;
- Ssfdc.MaxLogBlocks = 500;
- Ssfdc.MaxSectors = 8;
- break;
- case SSFDC4MB:
- Ssfdc.Model = SSFDC4MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
- Ssfdc.MaxZones = 1;
- Ssfdc.MaxBlocks = 512;
- Ssfdc.MaxLogBlocks = 500;
- Ssfdc.MaxSectors = 16;
- break;
- case SSFDC8MB:
- Ssfdc.Model = SSFDC8MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512;
- Ssfdc.MaxZones = 1;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 16;
- break;
- case SSFDC16MB:
- Ssfdc.Model = SSFDC16MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
- Ssfdc.MaxZones = 1;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC32MB:
- Ssfdc.Model = SSFDC32MB;
- Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512;
- Ssfdc.MaxZones = 2;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC64MB:
- Ssfdc.Model = SSFDC64MB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 4;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC128MB:
- Ssfdc.Model = SSFDC128MB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 8;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC256MB:
- Ssfdc.Model = SSFDC256MB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 16;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC512MB:
- Ssfdc.Model = SSFDC512MB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 32;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC1GB:
- Ssfdc.Model = SSFDC1GB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 64;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- case SSFDC2GB:
- Ssfdc.Model = SSFDC2GB;
- Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512;
- Ssfdc.MaxZones = 128;
- Ssfdc.MaxBlocks = 1024;
- Ssfdc.MaxLogBlocks = 1000;
- Ssfdc.MaxSectors = 32;
- break;
- default:
- Ssfdc.Model = NOSSFDC;
- return ERROR;
- }
-
- return SMSUCCESS;
-}
-
-/* ----- _Check_D_DevCode() --------------------------------------------- */
-static u8 _Check_D_DevCode(u8 dcode)
-{
- switch (dcode) {
- case 0x6E:
- case 0xE8:
- case 0xEC: return SSFDC1MB; /* 8Mbit (1M) NAND */
- case 0x64:
- case 0xEA: return SSFDC2MB; /* 16Mbit (2M) NAND */
- case 0x6B:
- case 0xE3:
- case 0xE5: return SSFDC4MB; /* 32Mbit (4M) NAND */
- case 0xE6: return SSFDC8MB; /* 64Mbit (8M) NAND */
- case 0x73: return SSFDC16MB; /* 128Mbit (16M)NAND */
- case 0x75: return SSFDC32MB; /* 256Mbit (32M)NAND */
- case 0x76: return SSFDC64MB; /* 512Mbit (64M)NAND */
- case 0x79: return SSFDC128MB; /* 1Gbit(128M)NAND */
- case 0x71: return SSFDC256MB;
- case 0xDC: return SSFDC512MB;
- case 0xD3: return SSFDC1GB;
- case 0xD5: return SSFDC2GB;
- default: return NOSSFDC;
- }
-}
-
-
-
-
-/* SmartMedia ECC Control Subroutine
- * ----- Check_D_ReadError() ----------------------------------------------
- */
-int Check_D_ReadError(u8 *redundant)
-{
- return SMSUCCESS;
-}
-
-/* ----- Check_D_Correct() ---------------------------------------------- */
-int Check_D_Correct(u8 *buf, u8 *redundant)
-{
- return SMSUCCESS;
-}
-
-/* ----- Check_D_CISdata() ---------------------------------------------- */
-int Check_D_CISdata(u8 *buf, u8 *redundant)
-{
- u8 cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02,
- 0xDF, 0x01, 0x20};
-
- int cis_len = sizeof(cis);
-
- if (!IsSSFDCCompliance && !IsXDCompliance)
- return SMSUCCESS;
-
- if (!memcmp(redundant + 0x0D, EccBuf, 3))
- return memcmp(buf, cis, cis_len);
-
- if (!_Correct_D_SwECC(buf, redundant + 0x0D, EccBuf))
- return memcmp(buf, cis, cis_len);
-
- buf += 0x100;
- if (!memcmp(redundant + 0x08, EccBuf + 0x03, 3))
- return memcmp(buf, cis, cis_len);
-
- if (!_Correct_D_SwECC(buf, redundant + 0x08, EccBuf + 0x03))
- return memcmp(buf, cis, cis_len);
-
- return ERROR;
-}
-
-/* ----- Set_D_RightECC() ---------------------------------------------- */
-void Set_D_RightECC(u8 *redundant)
-{
- /* Driver ECC Check */
- return;
-}
-
-
diff --git a/drivers/staging/keucr/smscsi.c b/drivers/staging/keucr/smscsi.c
deleted file mode 100644
index 20858f6777c8..000000000000
--- a/drivers/staging/keucr/smscsi.c
+++ /dev/null
@@ -1,194 +0,0 @@
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_device.h>
-
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-#include "smil.h"
-
-static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb);
-static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb);
-static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb);
-static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb);
-static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb);
-static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb);
-
-/* ----- SM_SCSIIrp() -------------------------------------------------- */
-int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
-{
- int result;
-
- us->SrbStatus = SS_SUCCESS;
- switch (srb->cmnd[0]) {
- case TEST_UNIT_READY:
- result = SM_SCSI_Test_Unit_Ready(us, srb);
- break; /* 0x00 */
- case INQUIRY:
- result = SM_SCSI_Inquiry(us, srb);
- break; /* 0x12 */
- case MODE_SENSE:
- result = SM_SCSI_Mode_Sense(us, srb);
- break; /* 0x1A */
- case READ_CAPACITY:
- result = SM_SCSI_Read_Capacity(us, srb);
- break; /* 0x25 */
- case READ_10:
- result = SM_SCSI_Read(us, srb);
- break; /* 0x28 */
- case WRITE_10:
- result = SM_SCSI_Write(us, srb);
- break; /* 0x2A */
-
- default:
- us->SrbStatus = SS_ILLEGAL_REQUEST;
- result = USB_STOR_TRANSPORT_FAILED;
- break;
- }
- return result;
-}
-
-/* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */
-static int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
-{
- if (us->SM_Status.Insert && us->SM_Status.Ready)
- return USB_STOR_TRANSPORT_GOOD;
- else {
- ENE_SMInit(us);
- return USB_STOR_TRANSPORT_GOOD;
- }
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- SM_SCSI_Inquiry() --------------------------------------------- */
-static int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
-{
- u8 data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00,
- 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20,
- 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65,
- 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
-
- usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-
-/* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */
-static int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
-{
- u8 mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
- 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
- u8 mediaWP[12] = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
- 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
-
- if (us->SM_Status.WtP)
- usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
- else
- usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF);
-
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- SM_SCSI_Read_Capacity() --------------------------------------- */
-static int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
-{
- unsigned int offset = 0;
- struct scatterlist *sg = NULL;
- u32 bl_num;
- u16 bl_len;
- u8 buf[8];
-
- dev_dbg(&us->pusb_dev->dev, "SM_SCSI_Read_Capacity\n");
-
- bl_len = 0x200;
- bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1;
-
- us->bl_num = bl_num;
- dev_dbg(&us->pusb_dev->dev, "bl_len = %x\n", bl_len);
- dev_dbg(&us->pusb_dev->dev, "bl_num = %x\n", bl_num);
-
- buf[0] = (bl_num >> 24) & 0xff;
- buf[1] = (bl_num >> 16) & 0xff;
- buf[2] = (bl_num >> 8) & 0xff;
- buf[3] = (bl_num >> 0) & 0xff;
- buf[4] = (bl_len >> 24) & 0xff;
- buf[5] = (bl_len >> 16) & 0xff;
- buf[6] = (bl_len >> 8) & 0xff;
- buf[7] = (bl_len >> 0) & 0xff;
-
- usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- SM_SCSI_Read() -------------------------------------------------- */
-static int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
-{
- int result = 0;
- u8 *Cdb = srb->cmnd;
- u32 bn = ((Cdb[2] << 24) & 0xff000000) |
- ((Cdb[3] << 16) & 0x00ff0000) |
- ((Cdb[4] << 8) & 0x0000ff00) |
- ((Cdb[5] << 0) & 0x000000ff);
- u16 blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff);
- u32 blenByte = blen * 0x200;
- void *buf;
-
-
- if (bn > us->bl_num)
- return USB_STOR_TRANSPORT_ERROR;
-
- buf = kmalloc(blenByte, GFP_KERNEL);
- if (buf == NULL)
- return USB_STOR_TRANSPORT_ERROR;
- result = Media_D_ReadSector(us, bn, blen, buf);
- usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF);
- kfree(buf);
-
- if (!result)
- return USB_STOR_TRANSPORT_GOOD;
- else
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
-/* ----- SM_SCSI_Write() -------------------------------------------------- */
-static int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
-{
- int result = 0;
- u8 *Cdb = srb->cmnd;
- u32 bn = ((Cdb[2] << 24) & 0xff000000) |
- ((Cdb[3] << 16) & 0x00ff0000) |
- ((Cdb[4] << 8) & 0x0000ff00) |
- ((Cdb[5] << 0) & 0x000000ff);
- u16 blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff);
- u32 blenByte = blen * 0x200;
- void *buf;
-
-
- if (bn > us->bl_num)
- return USB_STOR_TRANSPORT_ERROR;
-
- buf = kmalloc(blenByte, GFP_KERNEL);
- if (buf == NULL)
- return USB_STOR_TRANSPORT_ERROR;
- usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF);
- result = Media_D_CopySector(us, bn, blen, buf);
- kfree(buf);
-
- if (!result)
- return USB_STOR_TRANSPORT_GOOD;
- else
- return USB_STOR_TRANSPORT_ERROR;
-
- return USB_STOR_TRANSPORT_GOOD;
-}
-
diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c
deleted file mode 100644
index 5e59525271f8..000000000000
--- a/drivers/staging/keucr/transport.c
+++ /dev/null
@@ -1,865 +0,0 @@
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_device.h>
-
-#include "usb.h"
-#include "scsiglue.h"
-#include "transport.h"
-
-/***********************************************************************
- * Data transfer routines
- ***********************************************************************/
-/*
- * usb_stor_blocking_completion()
- */
-static void usb_stor_blocking_completion(struct urb *urb)
-{
- struct completion *urb_done_ptr = urb->context;
-
- /* pr_info("transport --- usb_stor_blocking_completion\n"); */
- complete(urb_done_ptr);
-}
-
-/*
- * usb_stor_msg_common()
- */
-static int usb_stor_msg_common(struct us_data *us, int timeout)
-{
- struct completion urb_done;
- long timeleft;
- int status;
-
- /* pr_info("transport --- usb_stor_msg_common\n"); */
- if (test_bit(US_FLIDX_ABORTING, &us->dflags))
- return -EIO;
-
- init_completion(&urb_done);
-
- us->current_urb->context = &urb_done;
- us->current_urb->actual_length = 0;
- us->current_urb->error_count = 0;
- us->current_urb->status = 0;
-
- us->current_urb->transfer_flags = 0;
- if (us->current_urb->transfer_buffer == us->iobuf)
- us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- us->current_urb->transfer_dma = us->iobuf_dma;
- us->current_urb->setup_dma = us->cr_dma;
-
- status = usb_submit_urb(us->current_urb, GFP_NOIO);
- if (status)
- return status;
-
- set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
-
- if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
- if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
- /* pr_info("-- cancelling URB\n"); */
- usb_unlink_urb(us->current_urb);
- }
- }
-
- timeleft = wait_for_completion_interruptible_timeout(&urb_done,
- timeout ? : MAX_SCHEDULE_TIMEOUT);
- clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
-
- if (timeleft <= 0) {
- /* pr_info("%s -- cancelling URB\n",
- timeleft == 0 ? "Timeout" : "Signal"); */
- usb_kill_urb(us->current_urb);
- }
-
- return us->current_urb->status;
-}
-
-/*
- * usb_stor_print_cmd():
- */
-static void usb_stor_print_cmd(struct us_data *us, struct scsi_cmnd *srb)
-{
- u8 *Cdb = srb->cmnd;
- u32 cmd = Cdb[0];
-
- switch (cmd) {
- case TEST_UNIT_READY:
- break;
- case INQUIRY:
- dev_dbg(&us->pusb_dev->dev,
- "scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
- break;
- case MODE_SENSE:
- dev_dbg(&us->pusb_dev->dev,
- "scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
- break;
- case START_STOP:
- dev_dbg(&us->pusb_dev->dev,
- "scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
- break;
- case READ_CAPACITY:
- dev_dbg(&us->pusb_dev->dev,
- "scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
- break;
- case READ_10:
- break;
- case WRITE_10:
- break;
- case ALLOW_MEDIUM_REMOVAL:
- dev_dbg(&us->pusb_dev->dev,
- "scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
- break;
- default:
- dev_dbg(&us->pusb_dev->dev, "scsi cmd %X --- Other cmd\n", cmd);
- break;
- }
-}
-
-/*
- * usb_stor_control_msg()
- */
-int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
- u8 request, u8 requesttype, u16 value, u16 index,
- void *data, u16 size, int timeout)
-{
- int status;
-
- /* pr_info("transport --- usb_stor_control_msg\n"); */
-
- /* fill in the devrequest structure */
- us->cr->bRequestType = requesttype;
- us->cr->bRequest = request;
- us->cr->wValue = cpu_to_le16(value);
- us->cr->wIndex = cpu_to_le16(index);
- us->cr->wLength = cpu_to_le16(size);
-
- /* fill and submit the URB */
- usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
- (unsigned char *) us->cr, data, size,
- usb_stor_blocking_completion, NULL);
- status = usb_stor_msg_common(us, timeout);
-
- /* return the actual length of the data transferred if no error */
- if (status == 0)
- status = us->current_urb->actual_length;
- return status;
-}
-
-/*
- * usb_stor_clear_halt()
- */
-int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
-{
- int result;
- int endp = usb_pipeendpoint(pipe);
-
- /* pr_info("transport --- usb_stor_clear_halt\n"); */
- if (usb_pipein(pipe))
- endp |= USB_DIR_IN;
-
- result = usb_stor_control_msg(us, us->send_ctrl_pipe,
- USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
- USB_ENDPOINT_HALT, endp,
- NULL, 0, 3*HZ);
-
- /* reset the endpoint toggle */
- if (result >= 0)
- /* usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
- usb_pipeout(pipe), 0); */
- usb_reset_endpoint(us->pusb_dev, endp);
-
- return result;
-}
-
-/*
- * interpret_urb_result()
- */
-static int interpret_urb_result(struct us_data *us, unsigned int pipe,
- unsigned int length, int result, unsigned int partial)
-{
- /* pr_info("transport --- interpret_urb_result\n"); */
- switch (result) {
- /* no error code; did we send all the data? */
- case 0:
- if (partial != length) {
- /* pr_info("-- short transfer\n"); */
- return USB_STOR_XFER_SHORT;
- }
- /* pr_info("-- transfer complete\n"); */
- return USB_STOR_XFER_GOOD;
- case -EPIPE:
- if (usb_pipecontrol(pipe)) {
- /* pr_info("-- stall on control pipe\n"); */
- return USB_STOR_XFER_STALLED;
- }
- /* pr_info("clearing endpoint halt for pipe 0x%x\n", pipe); */
- if (usb_stor_clear_halt(us, pipe) < 0)
- return USB_STOR_XFER_ERROR;
- return USB_STOR_XFER_STALLED;
- case -EOVERFLOW:
- /* pr_info("-- babble\n"); */
- return USB_STOR_XFER_LONG;
- case -ECONNRESET:
- /* pr_info("-- transfer cancelled\n"); */
- return USB_STOR_XFER_ERROR;
- case -EREMOTEIO:
- /* pr_info("-- short read transfer\n"); */
- return USB_STOR_XFER_SHORT;
- case -EIO:
- /* pr_info("-- abort or disconnect in progress\n"); */
- return USB_STOR_XFER_ERROR;
- default:
- /* pr_info("-- unknown error\n"); */
- return USB_STOR_XFER_ERROR;
- }
-}
-
-/*
- * usb_stor_bulk_transfer_buf()
- */
-int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
- void *buf, unsigned int length, unsigned int *act_len)
-{
- int result;
-
- /* pr_info("transport --- usb_stor_bulk_transfer_buf\n"); */
-
- /* fill and submit the URB */
- usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf,
- length, usb_stor_blocking_completion, NULL);
- result = usb_stor_msg_common(us, 0);
-
- /* store the actual length of the data transferred */
- if (act_len)
- *act_len = us->current_urb->actual_length;
-
- return interpret_urb_result(us, pipe, length, result,
- us->current_urb->actual_length);
-}
-
-/*
- * usb_stor_bulk_transfer_sglist()
- */
-static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
- struct scatterlist *sg, int num_sg, unsigned int length,
- unsigned int *act_len)
-{
- int result;
-
- /* pr_info("transport --- usb_stor_bulk_transfer_sglist\n"); */
- if (test_bit(US_FLIDX_ABORTING, &us->dflags))
- return USB_STOR_XFER_ERROR;
-
- /* initialize the scatter-gather request block */
- result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
- sg, num_sg, length, GFP_NOIO);
- if (result) {
- /* pr_info("usb_sg_init returned %d\n", result); */
- return USB_STOR_XFER_ERROR;
- }
-
- /* since the block has been initialized successfully,
- it's now okay to cancel it */
- set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
-
- /* did an abort/disconnect occur during the submission? */
- if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
- /* cancel the request, if it hasn't been cancelled already */
- if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
- /* pr_info("-- cancelling sg request\n"); */
- usb_sg_cancel(&us->current_sg);
- }
- }
-
- /* wait for the completion of the transfer */
- usb_sg_wait(&us->current_sg);
- clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
-
- result = us->current_sg.status;
- if (act_len)
- *act_len = us->current_sg.bytes;
-
- return interpret_urb_result(us, pipe, length,
- result, us->current_sg.bytes);
-}
-
-/*
- * usb_stor_bulk_srb()
- */
-int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
- struct scsi_cmnd *srb)
-{
- unsigned int partial;
- int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
- scsi_sg_count(srb), scsi_bufflen(srb),
- &partial);
-
- scsi_set_resid(srb, scsi_bufflen(srb) - partial);
- return result;
-}
-
-/*
- * usb_stor_bulk_transfer_sg()
- */
-int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
- void *buf, unsigned int length_left, int use_sg, int *residual)
-{
- int result;
- unsigned int partial;
-
- /* pr_info("transport --- usb_stor_bulk_transfer_sg\n"); */
- /* are we scatter-gathering? */
- if (use_sg) {
- /* use the usb core scatter-gather primitives */
- result = usb_stor_bulk_transfer_sglist(us, pipe,
- (struct scatterlist *) buf, use_sg,
- length_left, &partial);
- length_left -= partial;
- } else {
- /* no scatter-gather, just make the request */
- result = usb_stor_bulk_transfer_buf(us, pipe, buf,
- length_left, &partial);
- length_left -= partial;
- }
-
- /* store the residual and return the error code */
- if (residual)
- *residual = length_left;
- return result;
-}
-
-/***********************************************************************
- * Transport routines
- ***********************************************************************/
-/*
- * usb_stor_invoke_transport()
- */
-void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
-{
- int need_auto_sense;
- int result;
-
- /* pr_info("transport --- usb_stor_invoke_transport\n"); */
- usb_stor_print_cmd(us, srb);
- /* send the command to the transport layer */
- scsi_set_resid(srb, 0);
- result = us->transport(srb, us); /* usb_stor_Bulk_transport; */
-
- /* if the command gets aborted by the higher layers,
- we need to short-circuit all other processing */
- if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
- /* pr_info("-- command was aborted\n"); */
- srb->result = DID_ABORT << 16;
- goto Handle_Errors;
- }
-
- /* if there is a transport error, reset and don't auto-sense */
- if (result == USB_STOR_TRANSPORT_ERROR) {
- /* pr_info("-- transport indicates error, resetting\n"); */
- srb->result = DID_ERROR << 16;
- goto Handle_Errors;
- }
-
- /* if the transport provided its own sense data, don't auto-sense */
- if (result == USB_STOR_TRANSPORT_NO_SENSE) {
- srb->result = SAM_STAT_CHECK_CONDITION;
- return;
- }
-
- srb->result = SAM_STAT_GOOD;
-
- /* Determine if we need to auto-sense */
- need_auto_sense = 0;
-
- if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
- srb->sc_data_direction != DMA_FROM_DEVICE) {
- /* pr_info("-- CB transport device requiring auto-sense\n"); */
- need_auto_sense = 1;
- }
-
- if (result == USB_STOR_TRANSPORT_FAILED) {
- /* pr_info("-- transport indicates command failure\n"); */
- need_auto_sense = 1;
- }
-
- /* Now, if we need to do the auto-sense, let's do it */
- if (need_auto_sense) {
- int temp_result;
- struct scsi_eh_save ses;
-
- pr_info("Issuing auto-REQUEST_SENSE\n");
-
- scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
-
- /* we must do the protocol translation here */
- if (us->subclass == USB_SC_RBC ||
- us->subclass == USB_SC_SCSI ||
- us->subclass == USB_SC_CYP_ATACB) {
- srb->cmd_len = 6;
- } else {
- srb->cmd_len = 12;
- }
- /* issue the auto-sense command */
- scsi_set_resid(srb, 0);
- temp_result = us->transport(us->srb, us);
-
- /* let's clean up right away */
- scsi_eh_restore_cmnd(srb, &ses);
-
- if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
- /* pr_info("-- auto-sense aborted\n"); */
- srb->result = DID_ABORT << 16;
- goto Handle_Errors;
- }
- if (temp_result != USB_STOR_TRANSPORT_GOOD) {
- /* pr_info("-- auto-sense failure\n"); */
- srb->result = DID_ERROR << 16;
- if (!(us->fflags & US_FL_SCM_MULT_TARG))
- goto Handle_Errors;
- return;
- }
-
- /* set the result so the higher layers expect this data */
- srb->result = SAM_STAT_CHECK_CONDITION;
-
- if (result == USB_STOR_TRANSPORT_GOOD &&
- (srb->sense_buffer[2] & 0xaf) == 0 &&
- srb->sense_buffer[12] == 0 &&
- srb->sense_buffer[13] == 0) {
- srb->result = SAM_STAT_GOOD;
- srb->sense_buffer[0] = 0x0;
- }
- }
-
- /* Did we transfer less than the minimum amount required? */
- if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
- scsi_get_resid(srb) < srb->underflow)
- srb->result = (DID_ERROR << 16);
- /* v02 | (SUGGEST_RETRY << 24); */
-
- return;
-
-Handle_Errors:
- scsi_lock(us_to_host(us));
- set_bit(US_FLIDX_RESETTING, &us->dflags);
- clear_bit(US_FLIDX_ABORTING, &us->dflags);
- scsi_unlock(us_to_host(us));
-
- mutex_unlock(&us->dev_mutex);
- result = usb_stor_port_reset(us);
- mutex_lock(&us->dev_mutex);
-
- if (result < 0) {
- scsi_lock(us_to_host(us));
- usb_stor_report_device_reset(us);
- scsi_unlock(us_to_host(us));
- us->transport_reset(us);
- }
- clear_bit(US_FLIDX_RESETTING, &us->dflags);
-}
-
-/*
- * ENE_stor_invoke_transport()
- */
-void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
-{
- int result = 0;
-
- /* pr_info("transport --- ENE_stor_invoke_transport\n"); */
- usb_stor_print_cmd(us, srb);
- /* send the command to the transport layer */
- scsi_set_resid(srb, 0);
- if (!(us->SM_Status.Ready))
- result = ENE_InitMedia(us);
-
- if (us->Power_IsResum == true) {
- result = ENE_InitMedia(us);
- us->Power_IsResum = false;
- }
-
- if (us->SM_Status.Ready)
- result = SM_SCSIIrp(us, srb);
-
- /* if the command gets aborted by the higher layers,
- we need to short-circuit all other processing */
- if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
- /* pr_info("-- command was aborted\n"); */
- srb->result = DID_ABORT << 16;
- goto Handle_Errors;
- }
-
- /* if there is a transport error, reset and don't auto-sense */
- if (result == USB_STOR_TRANSPORT_ERROR) {
- /* pr_info("-- transport indicates error, resetting\n"); */
- srb->result = DID_ERROR << 16;
- goto Handle_Errors;
- }
-
- /* if the transport provided its own sense data, don't auto-sense */
- if (result == USB_STOR_TRANSPORT_NO_SENSE) {
- srb->result = SAM_STAT_CHECK_CONDITION;
- return;
- }
-
- srb->result = SAM_STAT_GOOD;
- if (result == USB_STOR_TRANSPORT_FAILED) {
- /* pr_info("-- transport indicates command failure\n"); */
- /* need_auto_sense = 1; */
- BuildSenseBuffer(srb, us->SrbStatus);
- srb->result = SAM_STAT_CHECK_CONDITION;
- }
-
- /* Did we transfer less than the minimum amount required? */
- if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
- scsi_get_resid(srb) < srb->underflow)
- srb->result = (DID_ERROR << 16);
- /* v02 | (SUGGEST_RETRY << 24); */
-
- return;
-
-Handle_Errors:
- scsi_lock(us_to_host(us));
- set_bit(US_FLIDX_RESETTING, &us->dflags);
- clear_bit(US_FLIDX_ABORTING, &us->dflags);
- scsi_unlock(us_to_host(us));
-
- mutex_unlock(&us->dev_mutex);
- result = usb_stor_port_reset(us);
- mutex_lock(&us->dev_mutex);
-
- if (result < 0) {
- scsi_lock(us_to_host(us));
- usb_stor_report_device_reset(us);
- scsi_unlock(us_to_host(us));
- us->transport_reset(us);
- }
- clear_bit(US_FLIDX_RESETTING, &us->dflags);
-}
-
-/*
- * BuildSenseBuffer()
- */
-void BuildSenseBuffer(struct scsi_cmnd *srb, int SrbStatus)
-{
- u8 *buf = srb->sense_buffer;
- u8 asc;
-
- pr_info("transport --- BuildSenseBuffer\n");
- switch (SrbStatus) {
- case SS_NOT_READY:
- asc = 0x3a;
- break; /* sense key = 0x02 */
- case SS_MEDIUM_ERR:
- asc = 0x0c;
- break; /* sense key = 0x03 */
- case SS_ILLEGAL_REQUEST:
- asc = 0x20;
- break; /* sense key = 0x05 */
- default:
- asc = 0x00;
- break; /* ?? */
- }
-
- memset(buf, 0, 18);
- buf[0x00] = 0xf0;
- buf[0x02] = SrbStatus;
- buf[0x07] = 0x0b;
- buf[0x0c] = asc;
-}
-
-/*
- * usb_stor_stop_transport()
- */
-void usb_stor_stop_transport(struct us_data *us)
-{
- /* pr_info("transport --- usb_stor_stop_transport\n"); */
-
- if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
- /* pr_info("-- cancelling URB\n"); */
- usb_unlink_urb(us->current_urb);
- }
-
- if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
- /* pr_info("-- cancelling sg request\n"); */
- usb_sg_cancel(&us->current_sg);
- }
-}
-
-/*
- * usb_stor_Bulk_max_lun()
- */
-int usb_stor_Bulk_max_lun(struct us_data *us)
-{
- int result;
-
- /* pr_info("transport --- usb_stor_Bulk_max_lun\n"); */
- /* issue the command */
- us->iobuf[0] = 0;
- result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
- US_BULK_GET_MAX_LUN,
- USB_DIR_IN | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE,
- 0, us->ifnum, us->iobuf, 1, HZ);
-
- /* pr_info("GetMaxLUN command result is %d, data is %d\n",
- result, us->iobuf[0]); */
-
- /* if we have a successful request, return the result */
- if (result > 0)
- return us->iobuf[0];
-
- return 0;
-}
-
-/*
- * usb_stor_Bulk_transport()
- */
-int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
-{
- struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
- struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
- unsigned int transfer_length = scsi_bufflen(srb);
- unsigned int residue;
- int result;
- int fake_sense = 0;
- unsigned int cswlen;
- unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
-
- /* pr_info("transport --- usb_stor_Bulk_transport\n"); */
- /* Take care of BULK32 devices; set extra byte to 0 */
- if (unlikely(us->fflags & US_FL_BULK32)) {
- cbwlen = 32;
- us->iobuf[31] = 0;
- }
-
- /* set up the command wrapper */
- bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb->DataTransferLength = cpu_to_le32(transfer_length);
- bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
- bcb->Tag = ++us->tag;
- bcb->Lun = srb->device->lun;
- if (us->fflags & US_FL_SCM_MULT_TARG)
- bcb->Lun |= srb->device->id << 4;
- bcb->Length = srb->cmd_len;
-
- /* copy the command payload */
- memset(bcb->CDB, 0, sizeof(bcb->CDB));
- memcpy(bcb->CDB, srb->cmnd, bcb->Length);
-
- /* send command */
- /* send it to out endpoint */
- /* pr_info("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
- le32_to_cpu(bcb->Signature), bcb->Tag,
- le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
- (bcb->Lun >> 4), (bcb->Lun & 0x0F),
- bcb->Length); */
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
- bcb, cbwlen, NULL);
- /* pr_info("Bulk command transfer result=%d\n", result); */
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- if (unlikely(us->fflags & US_FL_GO_SLOW))
- udelay(125);
-
- /* R/W data */
- if (transfer_length) {
- unsigned int pipe;
-
- if (srb->sc_data_direction == DMA_FROM_DEVICE)
- pipe = us->recv_bulk_pipe;
- else
- pipe = us->send_bulk_pipe;
-
- result = usb_stor_bulk_srb(us, pipe, srb);
- /* pr_info("Bulk data transfer result 0x%x\n", result); */
- if (result == USB_STOR_XFER_ERROR)
- return USB_STOR_TRANSPORT_ERROR;
-
- if (result == USB_STOR_XFER_LONG)
- fake_sense = 1;
- }
-
- /* get CSW for device status */
- /* pr_info("Attempting to get CSW...\n"); */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, &cswlen);
-
- if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
- /* pr_info("Received 0-length CSW; retrying...\n"); */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, &cswlen);
- }
-
- /* did the attempt to read the CSW fail? */
- if (result == USB_STOR_XFER_STALLED) {
- /* get the status again */
- /* pr_info("Attempting to get CSW (2nd try)...\n"); */
- result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
- US_BULK_CS_WRAP_LEN, NULL);
- }
-
- /* if we still have a failure at this point, we're in trouble */
- /* pr_info("Bulk status result = %d\n", result); */
- if (result != USB_STOR_XFER_GOOD)
- return USB_STOR_TRANSPORT_ERROR;
-
- /* check bulk status */
- residue = le32_to_cpu(bcs->Residue);
- /* pr_info("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
- le32_to_cpu(bcs->Signature),
- bcs->Tag, residue, bcs->Status); */
- if (!(bcs->Tag == us->tag ||
- (us->fflags & US_FL_BULK_IGNORE_TAG)) ||
- bcs->Status > US_BULK_STAT_PHASE) {
- /* pr_info("Bulk logical error\n"); */
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- if (!us->bcs_signature) {
- us->bcs_signature = bcs->Signature;
- /* if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) */
- /* pr_info("Learnt BCS signature 0x%08X\n",
- le32_to_cpu(us->bcs_signature)); */
- } else if (bcs->Signature != us->bcs_signature) {
- /* pr_info("Signature mismatch: got %08X, expecting %08X\n",
- le32_to_cpu(bcs->Signature),
- le32_to_cpu(us->bcs_signature)); */
- return USB_STOR_TRANSPORT_ERROR;
- }
-
- /* try to compute the actual residue, based on how much data
- * was really transferred and what the device tells us */
- if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
-
- /* Heuristically detect devices that generate bogus residues
- * by seeing what happens with INQUIRY and READ CAPACITY
- * commands.
- */
- if (bcs->Status == US_BULK_STAT_OK &&
- scsi_get_resid(srb) == 0 &&
- ((srb->cmnd[0] == INQUIRY &&
- transfer_length == 36) ||
- (srb->cmnd[0] == READ_CAPACITY &&
- transfer_length == 8))) {
- us->fflags |= US_FL_IGNORE_RESIDUE;
-
- } else {
- residue = min(residue, transfer_length);
- scsi_set_resid(srb, max_t(int, scsi_get_resid(srb),
- residue));
- }
- }
-
- /* based on the status code, we report good or bad */
- switch (bcs->Status) {
- case US_BULK_STAT_OK:
- if (fake_sense) {
- memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
- sizeof(usb_stor_sense_invalidCDB));
- return USB_STOR_TRANSPORT_NO_SENSE;
- }
- return USB_STOR_TRANSPORT_GOOD;
-
- case US_BULK_STAT_FAIL:
- return USB_STOR_TRANSPORT_FAILED;
-
- case US_BULK_STAT_PHASE:
- return USB_STOR_TRANSPORT_ERROR;
- }
- return USB_STOR_TRANSPORT_ERROR;
-}
-
-/***********************************************************************
- * Reset routines
- ***********************************************************************/
-/*
- * usb_stor_reset_common()
- */
-static int usb_stor_reset_common(struct us_data *us,
- u8 request, u8 requesttype,
- u16 value, u16 index, void *data, u16 size)
-{
- int result;
- int result2;
-
- /* pr_info("transport --- usb_stor_reset_common\n"); */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
- /* pr_info("No reset during disconnect\n"); */
- return -EIO;
- }
-
- result = usb_stor_control_msg(us, us->send_ctrl_pipe,
- request, requesttype, value, index, data, size, 5*HZ);
-
- if (result < 0) {
- /* pr_info("Soft reset failed: %d\n", result); */
- return result;
- }
-
- wait_event_interruptible_timeout(us->delay_wait,
- test_bit(US_FLIDX_DISCONNECTING, &us->dflags), HZ*6);
-
- if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
- /* pr_info("Reset interrupted by disconnect\n"); */
- return -EIO;
- }
-
- /* pr_info("Soft reset: clearing bulk-in endpoint halt\n"); */
- result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
-
- /* pr_info("Soft reset: clearing bulk-out endpoint halt\n"); */
- result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);
-
- /* return a result code based on the result of the clear-halts */
- if (result >= 0)
- result = result2;
- /* if (result < 0) */
- /* pr_info("Soft reset failed\n"); */
- /* else */
- /* pr_info("Soft reset done\n"); */
- return result;
-}
-
-/*
- * usb_stor_Bulk_reset()
- */
-int usb_stor_Bulk_reset(struct us_data *us)
-{
- /* pr_info("transport --- usb_stor_Bulk_reset\n"); */
- return usb_stor_reset_common(us, US_BULK_RESET_REQUEST,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, us->ifnum, NULL, 0);
-}
-
-/*
- * usb_stor_port_reset()
- */
-int usb_stor_port_reset(struct us_data *us)
-{
- int result;
-
- /* pr_info("transport --- usb_stor_port_reset\n"); */
- result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
- if (result < 0)
- pr_info("unable to lock device for reset: %d\n", result);
- else {
- /* Were we disconnected while waiting for the lock? */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
- result = -EIO;
- /* pr_info("No reset during disconnect\n"); */
- } else {
- result = usb_reset_device(us->pusb_dev);
- /* pr_info("usb_reset_composite_device returns %d\n",
- result); */
- }
- usb_unlock_device(us->pusb_dev);
- }
- return result;
-}
-
-
diff --git a/drivers/staging/keucr/transport.h b/drivers/staging/keucr/transport.h
deleted file mode 100644
index abd8e5a3dd6e..000000000000
--- a/drivers/staging/keucr/transport.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _TRANSPORT_H_
-#define _TRANSPORT_H_
-
-#include <linux/blkdev.h>
-
-/* usb_stor_bulk_transfer_xxx() return codes, in order of severity */
-#define USB_STOR_XFER_GOOD 0 /* good transfer */
-#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
-#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
-#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
-#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
-
-/* Transport return codes */
-#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
-#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
-#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
-#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
-
-/*
- * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
- * return codes. But now the transport and low-level transfer routines
- * treat an abort as just another error (-ENOENT for a cancelled URB).
- * It is up to the invoke_transport() function to test for aborts and
- * distinguish them from genuine communication errors.
- */
-
-/* CBI accept device specific command */
-#define US_CBI_ADSC 0
-extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
-extern int usb_stor_Bulk_max_lun(struct us_data *);
-extern int usb_stor_Bulk_reset(struct us_data *);
-extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
-extern void usb_stor_stop_transport(struct us_data *);
-extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
- u8 request, u8 requesttype, u16 value, u16 index,
- void *data, u16 size, int timeout);
-extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe);
-extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
- void *buf, unsigned int length, unsigned int *act_len);
-extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
- void *buf, unsigned int length, int use_sg, int *residual);
-extern int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
- struct scsi_cmnd *srb);
-extern int usb_stor_port_reset(struct us_data *us);
-
-/* Protocol handling routines */
-enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
-extern unsigned int usb_stor_access_xfer_buf(struct us_data*,
- unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
- struct scatterlist **, unsigned int *offset, enum xfer_buf_dir dir);
-extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb,
- unsigned int dir);
-
-/*
- * ENE scsi function
- */
-extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data *);
-extern int ENE_InitMedia(struct us_data *);
-extern int ENE_SMInit(struct us_data *);
-extern int ENE_SendScsiCmd(struct us_data*, u8, void*, int);
-extern int ENE_LoadBinCode(struct us_data*, u8);
-extern int ene_read_byte(struct us_data*, u16 index, void *buf);
-extern int ENE_Read_Data(struct us_data*, void *buf, unsigned int length);
-extern int ENE_Write_Data(struct us_data*, void *buf, unsigned int length);
-extern void BuildSenseBuffer(struct scsi_cmnd *, int);
-
-/*
- * ENE scsi function
- */
-extern int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
-
-#endif
diff --git a/drivers/staging/keucr/usb.c b/drivers/staging/keucr/usb.c
deleted file mode 100644
index 12ebde7315cd..000000000000
--- a/drivers/staging/keucr/usb.c
+++ /dev/null
@@ -1,642 +0,0 @@
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/freezer.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/mutex.h>
-#include <linux/utsname.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-
-#include "usb.h"
-#include "scsiglue.h"
-#include "smil.h"
-#include "transport.h"
-
-/* Some informational data */
-MODULE_AUTHOR("Domao");
-MODULE_DESCRIPTION("ENE USB Mass Storage driver for Linux");
-MODULE_LICENSE("GPL");
-
-static unsigned int delay_use = 1;
-
-static struct usb_device_id eucr_usb_ids[] = {
- { USB_DEVICE(0x058f, 0x6366) },
- { USB_DEVICE(0x0cf2, 0x6230) },
- { USB_DEVICE(0x0cf2, 0x6250) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, eucr_usb_ids);
-
-
-#ifdef CONFIG_PM
-
-static int eucr_suspend(struct usb_interface *iface, pm_message_t message)
-{
- struct us_data *us = usb_get_intfdata(iface);
- pr_info("--- eucr_suspend ---\n");
- /* Wait until no command is running */
- mutex_lock(&us->dev_mutex);
-
- if (us->suspend_resume_hook)
- (us->suspend_resume_hook)(us, US_SUSPEND);
-
- mutex_unlock(&us->dev_mutex);
- return 0;
-}
-
-static int eucr_resume(struct usb_interface *iface)
-{
- u8 tmp = 0;
-
- struct us_data *us = usb_get_intfdata(iface);
- pr_info("--- eucr_resume---\n");
- mutex_lock(&us->dev_mutex);
-
- if (us->suspend_resume_hook)
- (us->suspend_resume_hook)(us, US_RESUME);
-
-
- mutex_unlock(&us->dev_mutex);
-
- us->Power_IsResum = true;
-
- us->SM_Status = *(struct keucr_sm_status *)&tmp;
-
- return 0;
-}
-
-static int eucr_reset_resume(struct usb_interface *iface)
-{
- u8 tmp = 0;
- struct us_data *us = usb_get_intfdata(iface);
-
- pr_info("--- eucr_reset_resume---\n");
-
- /* Report the reset to the SCSI core */
- usb_stor_report_bus_reset(us);
-
- /*
- * FIXME: Notify the subdrivers that they need to reinitialize
- * the device
- */
-
- us->Power_IsResum = true;
-
- us->SM_Status = *(struct keucr_sm_status *)&tmp;
-
- return 0;
-}
-
-#else
-
-#define eucr_suspend NULL
-#define eucr_resume NULL
-#define eucr_reset_resume NULL
-
-#endif
-
-static int eucr_pre_reset(struct usb_interface *iface)
-{
- struct us_data *us = usb_get_intfdata(iface);
-
- pr_info("usb --- eucr_pre_reset\n");
-
- /* Make sure no command runs during the reset */
- mutex_lock(&us->dev_mutex);
- return 0;
-}
-
-static int eucr_post_reset(struct usb_interface *iface)
-{
- struct us_data *us = usb_get_intfdata(iface);
-
- pr_info("usb --- eucr_post_reset\n");
-
- /* Report the reset to the SCSI core */
- usb_stor_report_bus_reset(us);
-
- mutex_unlock(&us->dev_mutex);
- return 0;
-}
-
-void fill_inquiry_response(struct us_data *us, unsigned char *data,
- unsigned int data_len)
-{
- pr_info("usb --- fill_inquiry_response\n");
- if (data_len < 36) /* You lose. */
- return;
-
- if (data[0]&0x20) {
- memset(data+8, 0, 28);
- } else {
- u16 bcdDevice =
- le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
- memcpy(data+8, us->unusual_dev->vendorName,
- strlen(us->unusual_dev->vendorName) > 8 ? 8 :
- strlen(us->unusual_dev->vendorName));
- memcpy(data+16, us->unusual_dev->productName,
- strlen(us->unusual_dev->productName) > 16 ? 16 :
- strlen(us->unusual_dev->productName));
- data[32] = 0x30 + ((bcdDevice>>12) & 0x0F);
- data[33] = 0x30 + ((bcdDevice>>8) & 0x0F);
- data[34] = 0x30 + ((bcdDevice>>4) & 0x0F);
- data[35] = 0x30 + ((bcdDevice) & 0x0F);
- }
- usb_stor_set_xfer_buf(us, data, data_len, us->srb, TO_XFER_BUF);
-}
-
-static int usb_stor_control_thread(void *__us)
-{
- struct us_data *us = (struct us_data *)__us;
- struct Scsi_Host *host = us_to_host(us);
-
- pr_info("usb --- usb_stor_control_thread\n");
- for (;;) {
- if (wait_for_completion_interruptible(&us->cmnd_ready))
- break;
-
- /* lock the device pointers */
- mutex_lock(&(us->dev_mutex));
-
- /* if the device has disconnected, we are free to exit */
- if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
- mutex_unlock(&us->dev_mutex);
- break;
- }
-
- /* lock access to the state */
- scsi_lock(host);
-
- /* When we are called with no command pending, we're done */
- if (us->srb == NULL) {
- scsi_unlock(host);
- mutex_unlock(&us->dev_mutex);
- break;
- }
-
- /* has the command timed out *already* ? */
- if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
- us->srb->result = DID_ABORT << 16;
- goto SkipForAbort;
- }
-
- scsi_unlock(host);
-
- if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
- us->srb->result = DID_ERROR << 16;
- } else if (us->srb->device->id
- && !(us->fflags & US_FL_SCM_MULT_TARG)) {
- us->srb->result = DID_BAD_TARGET << 16;
- } else if (us->srb->device->lun > us->max_lun) {
- us->srb->result = DID_BAD_TARGET << 16;
- } else if ((us->srb->cmnd[0] == INQUIRY)
- && (us->fflags & US_FL_FIX_INQUIRY)) {
- unsigned char data_ptr[36] = {0x00, 0x80, 0x02, 0x02,
- 0x1F, 0x00, 0x00, 0x00};
-
- fill_inquiry_response(us, data_ptr, 36);
- us->srb->result = SAM_STAT_GOOD;
- } else {
- us->proto_handler(us->srb, us);
- }
-
- /* lock access to the state */
- scsi_lock(host);
-
- /* indicate that the command is done */
- if (us->srb->result != DID_ABORT << 16) {
- us->srb->scsi_done(us->srb);
- } else {
-SkipForAbort:
- pr_info("scsi command aborted\n");
- }
-
- if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
- complete(&(us->notify));
-
- /* Allow USB transfers to resume */
- clear_bit(US_FLIDX_ABORTING, &us->dflags);
- clear_bit(US_FLIDX_TIMED_OUT, &us->dflags);
- }
-
- /* finished working on this command */
- us->srb = NULL;
- scsi_unlock(host);
-
- /* unlock the device pointers */
- mutex_unlock(&us->dev_mutex);
- } /* for (;;) */
-
- /* Wait until we are told to stop */
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop())
- break;
- schedule();
- }
- __set_current_state(TASK_RUNNING);
- return 0;
-}
-
-static int associate_dev(struct us_data *us, struct usb_interface *intf)
-{
- pr_info("usb --- associate_dev\n");
-
- /* Fill in the device-related fields */
- us->pusb_dev = interface_to_usbdev(intf);
- us->pusb_intf = intf;
- us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
-
- /* Store our private data in the interface */
- usb_set_intfdata(intf, us);
-
- /* Allocate the device-related DMA-mapped buffers */
- us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL,
- &us->cr_dma);
- if (!us->cr) {
- pr_info("usb_ctrlrequest allocation failed\n");
- return -ENOMEM;
- }
-
- us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL,
- &us->iobuf_dma);
- if (!us->iobuf) {
- pr_info("I/O buffer allocation failed\n");
- return -ENOMEM;
- }
-
- us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
- if (!us->sensebuf)
- return -ENOMEM;
-
- return 0;
-}
-
-static int get_device_info(struct us_data *us, const struct usb_device_id *id)
-{
- struct usb_device *dev = us->pusb_dev;
- struct usb_interface_descriptor *idesc =
- &us->pusb_intf->cur_altsetting->desc;
-
- pr_info("usb --- get_device_info\n");
-
- us->subclass = idesc->bInterfaceSubClass;
- us->protocol = idesc->bInterfaceProtocol;
- us->fflags = id->driver_info;
- us->Power_IsResum = false;
-
- if (us->fflags & US_FL_IGNORE_DEVICE) {
- pr_info("device ignored\n");
- return -ENODEV;
- }
-
- if (dev->speed != USB_SPEED_HIGH)
- us->fflags &= ~US_FL_GO_SLOW;
-
- return 0;
-}
-
-static int get_transport(struct us_data *us)
-{
- pr_info("usb --- get_transport\n");
- switch (us->protocol) {
- case USB_PR_BULK:
- us->transport_name = "Bulk";
- us->transport = usb_stor_Bulk_transport;
- us->transport_reset = usb_stor_Bulk_reset;
- break;
-
- default:
- return -EIO;
- }
-
- /* fix for single-lun devices */
- if (us->fflags & US_FL_SINGLE_LUN)
- us->max_lun = 0;
- return 0;
-}
-
-static int get_protocol(struct us_data *us)
-{
- pr_info("usb --- get_protocol\n");
- pr_info("us->pusb_dev->descriptor.idVendor = %x\n",
- us->pusb_dev->descriptor.idVendor);
- pr_info("us->pusb_dev->descriptor.idProduct = %x\n",
- us->pusb_dev->descriptor.idProduct);
- switch (us->subclass) {
- case USB_SC_SCSI:
- us->protocol_name = "Transparent SCSI";
- if ((us->pusb_dev->descriptor.idVendor == 0x0CF2)
- && (us->pusb_dev->descriptor.idProduct == 0x6250))
- us->proto_handler = ENE_stor_invoke_transport;
- else
- us->proto_handler = usb_stor_invoke_transport;
- break;
-
- default:
- return -EIO;
- }
- return 0;
-}
-
-static int get_pipes(struct us_data *us)
-{
- struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
- int i;
- struct usb_endpoint_descriptor *ep;
- struct usb_endpoint_descriptor *ep_in = NULL;
- struct usb_endpoint_descriptor *ep_out = NULL;
- struct usb_endpoint_descriptor *ep_int = NULL;
-
- pr_info("usb --- get_pipes\n");
-
- for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
- ep = &altsetting->endpoint[i].desc;
-
- if (usb_endpoint_xfer_bulk(ep)) {
- if (usb_endpoint_dir_in(ep)) {
- if (!ep_in)
- ep_in = ep;
- } else {
- if (!ep_out)
- ep_out = ep;
- }
- } else if (usb_endpoint_is_int_in(ep)) {
- if (!ep_int)
- ep_int = ep;
- }
- }
-
- if (!ep_in || !ep_out || (us->protocol == USB_PR_CBI && !ep_int)) {
- pr_info("Endpoint sanity check failed! Rejecting dev.\n");
- return -EIO;
- }
-
- /* Calculate and store the pipe values */
- us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
- us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
- us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- if (ep_int) {
- us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
- ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- us->ep_bInterval = ep_int->bInterval;
- }
- return 0;
-}
-
-static int usb_stor_acquire_resources(struct us_data *us)
-{
- struct task_struct *th;
-
- pr_info("usb --- usb_stor_acquire_resources\n");
- us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!us->current_urb) {
- pr_info("URB allocation failed\n");
- return -ENOMEM;
- }
-
- /* Start up our control thread */
- th = kthread_run(usb_stor_control_thread, us, "eucr-storage");
- if (IS_ERR(th)) {
- pr_info("Unable to start control thread\n");
- return PTR_ERR(th);
- }
- us->ctl_thread = th;
-
- return 0;
-}
-
-static void usb_stor_release_resources(struct us_data *us)
-{
- pr_info("usb --- usb_stor_release_resources\n");
-
- SM_FreeMem();
-
- complete(&us->cmnd_ready);
- if (us->ctl_thread)
- kthread_stop(us->ctl_thread);
-
- /* Call the destructor routine, if it exists */
- if (us->extra_destructor) {
- pr_info("-- calling extra_destructor()\n");
- us->extra_destructor(us->extra);
- }
-
- /* Free the extra data and the URB */
- kfree(us->extra);
- usb_free_urb(us->current_urb);
-}
-
-static void dissociate_dev(struct us_data *us)
-{
- pr_info("usb --- dissociate_dev\n");
-
- kfree(us->sensebuf);
-
- /* Free the device-related DMA-mapped buffers */
- usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
- usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
- us->iobuf_dma);
-
- /* Remove our private data from the interface */
- usb_set_intfdata(us->pusb_intf, NULL);
-}
-
-static void quiesce_and_remove_host(struct us_data *us)
-{
- struct Scsi_Host *host = us_to_host(us);
-
- pr_info("usb --- quiesce_and_remove_host\n");
-
- /* If the device is really gone, cut short reset delays */
- if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
- set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
-
- /*
- * Prevent SCSI-scanning (if it hasn't started yet)
- * and wait for the SCSI-scanning thread to stop.
- */
- set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
- wake_up(&us->delay_wait);
- wait_for_completion(&us->scanning_done);
-
- /*
- * Removing the host will perform an orderly shutdown: caches
- * synchronized, disks spun down, etc.
- */
- scsi_remove_host(host);
-
- /*
- * Prevent any new commands from being accepted and cut short
- * reset delays.
- */
- scsi_lock(host);
- set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
- scsi_unlock(host);
- wake_up(&us->delay_wait);
-}
-
-static void release_everything(struct us_data *us)
-{
- pr_info("usb --- release_everything\n");
-
- usb_stor_release_resources(us);
- dissociate_dev(us);
- scsi_host_put(us_to_host(us));
-}
-
-static int usb_stor_scan_thread(void *__us)
-{
- struct us_data *us = (struct us_data *)__us;
-
- pr_info("usb --- usb_stor_scan_thread\n");
- pr_info("EUCR : device found at %d\n", us->pusb_dev->devnum);
-
- set_freezable();
- /* Wait for the timeout to expire or for a disconnect */
- if (delay_use > 0) {
- wait_event_freezable_timeout(us->delay_wait,
- test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
- delay_use * HZ);
- }
-
- /* If the device is still connected, perform the scanning */
- if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
- /* For bulk-only devices, determine the max LUN value */
- if (us->protocol == USB_PR_BULK
- && !(us->fflags & US_FL_SINGLE_LUN)) {
- mutex_lock(&us->dev_mutex);
- us->max_lun = usb_stor_Bulk_max_lun(us);
- mutex_unlock(&us->dev_mutex);
- }
- scsi_scan_host(us_to_host(us));
- pr_info("EUCR : device scan complete\n");
- }
- complete_and_exit(&us->scanning_done, 0);
-}
-
-static int eucr_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct Scsi_Host *host;
- struct us_data *us;
- int result;
- u8 MiscReg03 = 0;
- struct task_struct *th;
-
- pr_info("usb --- eucr_probe\n");
-
- host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
- if (!host) {
- pr_info("Unable to allocate the scsi host\n");
- return -ENOMEM;
- }
-
- /* Allow 16-byte CDBs and thus > 2TB */
- host->max_cmd_len = 16;
- us = host_to_us(host);
- memset(us, 0, sizeof(struct us_data));
- mutex_init(&(us->dev_mutex));
- init_completion(&us->cmnd_ready);
- init_completion(&(us->notify));
- init_waitqueue_head(&us->delay_wait);
- init_completion(&us->scanning_done);
-
- /* Associate the us_data structure with the USB device */
- result = associate_dev(us, intf);
- if (result)
- goto BadDevice;
-
- /* Get Device info */
- result = get_device_info(us, id);
- if (result)
- goto BadDevice;
-
- /* Get the transport, protocol, and pipe settings */
- result = get_transport(us);
- if (result)
- goto BadDevice;
- result = get_protocol(us);
- if (result)
- goto BadDevice;
- result = get_pipes(us);
- if (result)
- goto BadDevice;
-
- /* Acquire all the other resources and add the host */
- result = usb_stor_acquire_resources(us);
- if (result)
- goto BadDevice;
-
- result = scsi_add_host(host, &intf->dev);
- if (result) {
- pr_info("Unable to add the scsi host\n");
- goto BadDevice;
- }
-
- /* Start up the thread for delayed SCSI-device scanning */
- th = kthread_create(usb_stor_scan_thread, us, "eucr-stor-scan");
- if (IS_ERR(th)) {
- pr_info("Unable to start the device-scanning thread\n");
- complete(&us->scanning_done);
- quiesce_and_remove_host(us);
- result = PTR_ERR(th);
- goto BadDevice;
- }
- wake_up_process(th);
-
- /* probe card type */
- result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03);
- if (result != USB_STOR_XFER_GOOD) {
- result = USB_STOR_TRANSPORT_ERROR;
- quiesce_and_remove_host(us);
- goto BadDevice;
- }
-
- if (!(MiscReg03 & 0x02)) {
- result = -ENODEV;
- quiesce_and_remove_host(us);
- pr_info("keucr: The driver only supports SM/MS card. To use SD card, please build driver/usb/storage/ums-eneub6250.ko\n");
- goto BadDevice;
- }
-
- return 0;
-
- /* We come here if there are any problems */
-BadDevice:
- pr_info("usb --- eucr_probe failed\n");
- release_everything(us);
- return result;
-}
-
-static void eucr_disconnect(struct usb_interface *intf)
-{
- struct us_data *us = usb_get_intfdata(intf);
-
- pr_info("usb --- eucr_disconnect\n");
- quiesce_and_remove_host(us);
- release_everything(us);
-}
-
-/* Initialization and registration */
-static struct usb_driver usb_storage_driver = {
- .name = "eucr",
- .probe = eucr_probe,
- .suspend = eucr_suspend,
- .resume = eucr_resume,
- .reset_resume = eucr_reset_resume,
- .disconnect = eucr_disconnect,
- .pre_reset = eucr_pre_reset,
- .post_reset = eucr_post_reset,
- .id_table = eucr_usb_ids,
- .soft_unbind = 1,
-};
-
-module_usb_driver(usb_storage_driver);
diff --git a/drivers/staging/keucr/usb.h b/drivers/staging/keucr/usb.h
deleted file mode 100644
index e894f840c708..000000000000
--- a/drivers/staging/keucr/usb.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Driver for USB Mass Storage compliant devices */
-
-#ifndef _USB_H_
-#define _USB_H_
-
-#include <linux/usb.h>
-#include <linux/usb_usual.h>
-#include <linux/blkdev.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-#include <scsi/scsi_host.h>
-#include "common.h"
-
-struct us_data;
-struct scsi_cmnd;
-
-/*
- * Unusual device list definitions
- */
-
-struct us_unusual_dev {
- const char *vendorName;
- const char *productName;
- __u8 useProtocol;
- __u8 useTransport;
- int (*initFunction)(struct us_data *);
-};
-
-/* EnE HW Register */
-#define REG_CARD_STATUS 0xFF83
-#define REG_HW_TRAP1 0xFF89
-
-/* SRB Status. Refers /usr/include/wine/wine/wnaspi32.h & SCSI sense key */
-#define SS_SUCCESS 0x00 /* No Sense */
-#define SS_NOT_READY 0x02
-#define SS_MEDIUM_ERR 0x03
-#define SS_HW_ERR 0x04
-#define SS_ILLEGAL_REQUEST 0x05
-#define SS_UNIT_ATTENTION 0x06
-
-/* ENE Load FW Pattern */
-#define SD_INIT1_PATTERN 1
-#define SD_INIT2_PATTERN 2
-#define SD_RW_PATTERN 3
-#define MS_INIT_PATTERN 4
-#define MSP_RW_PATTERN 5
-#define MS_RW_PATTERN 6
-#define SM_INIT_PATTERN 7
-#define SM_RW_PATTERN 8
-
-#define FDIR_WRITE 0
-#define FDIR_READ 1
-
-struct keucr_sd_status {
- u8 Insert:1;
- u8 Ready:1;
- u8 MediaChange:1;
- u8 IsMMC:1;
- u8 HiCapacity:1;
- u8 HiSpeed:1;
- u8 WtP:1;
- u8 Reserved:1;
-};
-
-struct keucr_ms_status {
- u8 Insert:1;
- u8 Ready:1;
- u8 MediaChange:1;
- u8 IsMSPro:1;
- u8 IsMSPHG:1;
- u8 Reserved1:1;
- u8 WtP:1;
- u8 Reserved2:1;
-};
-
-struct keucr_sm_status {
- u8 Insert:1;
- u8 Ready:1;
- u8 MediaChange:1;
- u8 Reserved:3;
- u8 WtP:1;
- u8 IsMS:1;
-};
-
-/* SD Block Length */
-#define SD_BLOCK_LEN 9 /* 2^9 = 512 Bytes,
- The HW maximum read/write data length */
-
-/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
-#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */
-#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */
-#define US_FLIDX_ABORTING 2 /* abort is in progress */
-#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
-#define US_FLIDX_RESETTING 4 /* device reset in progress */
-#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
-#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */
-
-
-#define USB_STOR_STRING_LEN 32
-
-/*
- * We provide a DMA-mapped I/O buffer for use with small USB transfers.
- * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a
- * 31-byte buffer. But Freecom needs a 64-byte buffer, so that's the
- * size we'll allocate.
- */
-
-#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */
-#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */
-
-typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data *);
-typedef int (*trans_reset)(struct us_data *);
-typedef void (*proto_cmnd)(struct scsi_cmnd *, struct us_data *);
-typedef void (*extra_data_destructor)(void *); /* extra data destructor */
-typedef void (*pm_hook)(struct us_data *, int); /* power management hook */
-
-#define US_SUSPEND 0
-#define US_RESUME 1
-
-/* we allocate one of these for every device that we remember */
-struct us_data {
- /* The device we're working with
- * It's important to note:
- * (o) you must hold dev_mutex to change pusb_dev
- */
- struct mutex dev_mutex; /* protect pusb_dev */
- struct usb_device *pusb_dev; /* this usb_device */
- struct usb_interface *pusb_intf; /* this interface */
- struct us_unusual_dev *unusual_dev; /* device-filter entry */
- unsigned long fflags; /* fixed flags from filter */
- unsigned long dflags; /* dynamic atomic bitflags */
- unsigned int send_bulk_pipe; /* cached pipe values */
- unsigned int recv_bulk_pipe;
- unsigned int send_ctrl_pipe;
- unsigned int recv_ctrl_pipe;
- unsigned int recv_intr_pipe;
-
- /* information about the device */
- char *transport_name;
- char *protocol_name;
- __le32 bcs_signature;
- u8 subclass;
- u8 protocol;
- u8 max_lun;
-
- u8 ifnum; /* interface number */
- u8 ep_bInterval; /* interrupt interval */
-
- /* function pointers for this device */
- trans_cmnd transport; /* transport function */
- trans_reset transport_reset; /* transport device reset */
- proto_cmnd proto_handler; /* protocol handler */
-
- /* SCSI interfaces */
- struct scsi_cmnd *srb; /* current srb */
- unsigned int tag; /* current dCBWTag */
-
- /* control and bulk communications data */
- struct urb *current_urb; /* USB requests */
- struct usb_ctrlrequest *cr; /* control requests */
- struct usb_sg_request current_sg; /* scatter-gather req. */
- unsigned char *iobuf; /* I/O buffer */
- unsigned char *sensebuf; /* sense data buffer */
- dma_addr_t cr_dma; /* buffer DMA addresses */
- dma_addr_t iobuf_dma;
- struct task_struct *ctl_thread; /* the control thread */
-
- /* mutual exclusion and synchronization structures */
- struct completion cmnd_ready; /* to sleep thread on */
- struct completion notify; /* thread begin/end */
- wait_queue_head_t delay_wait; /* wait during scan, reset */
- struct completion scanning_done; /* wait for scan thread */
-
- /* subdriver information */
- void *extra; /* Any extra data */
- extra_data_destructor extra_destructor;/* extra data destructor */
-#ifdef CONFIG_PM
- pm_hook suspend_resume_hook;
-#endif
- /* for 6250 code */
- struct keucr_sd_status SD_Status;
- struct keucr_ms_status MS_Status;
- struct keucr_sm_status SM_Status;
-
- /* ----- SD Control Data ---------------- */
- /* SD_REGISTER SD_Regs; */
- u16 SD_Block_Mult;
- u8 SD_READ_BL_LEN;
- u16 SD_C_SIZE;
- u8 SD_C_SIZE_MULT;
-
- /* SD/MMC New spec. */
- u8 SD_SPEC_VER;
- u8 SD_CSD_VER;
- u8 SD20_HIGH_CAPACITY;
- u32 HC_C_SIZE;
- u8 MMC_SPEC_VER;
- u8 MMC_BusWidth;
- u8 MMC_HIGH_CAPACITY;
-
- /* ----- MS Control Data ---------------- */
- bool MS_SWWP;
- u32 MSP_TotalBlock;
- /* MS_LibControl MS_Lib; */
- bool MS_IsRWPage;
- u16 MS_Model;
-
- /* ----- SM Control Data ---------------- */
- u8 SM_DeviceID;
- u8 SM_CardID;
-
- u8 *testbuf;
- u8 BIN_FLAG;
- u32 bl_num;
- int SrbStatus;
-
- /* ------Power Managerment --------------- */
- bool Power_IsResum;
-};
-
-/* Convert between us_data and the corresponding Scsi_Host */
-static inline struct Scsi_Host *us_to_host(struct us_data *us)
-{
- return container_of((void *) us, struct Scsi_Host, hostdata);
-}
-static inline struct us_data *host_to_us(struct Scsi_Host *host)
-{
- return (struct us_data *) host->hostdata;
-}
-
-/* Function to fill an inquiry response. See usb.c for details */
-extern void fill_inquiry_response(struct us_data *us,
- unsigned char *data, unsigned int data_len);
-
-/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
- * single queue element srb for write access */
-#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
-#define scsi_lock(host) spin_lock_irq(host->host_lock)
-
-#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index ef511c76a6e3..503b2d763595 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -663,7 +663,7 @@ static int line6_probe(struct usb_interface *interface,
case LINE6_DEVID_POCKETPOD:
switch (interface_number) {
case 0:
- return 0; /* this interface has no endpoints */
+ return -ENODEV; /* this interface has no endpoints */
case 1:
alternate = 0;
break;
diff --git a/drivers/staging/lustre/Makefile b/drivers/staging/lustre/Makefile
index fb0e0faf0760..95ffe337a80a 100644
--- a/drivers/staging/lustre/Makefile
+++ b/drivers/staging/lustre/Makefile
@@ -1,4 +1,2 @@
-subdir-ccflags-y := -I$(src)/include/
-
obj-$(CONFIG_LNET) += lnet/
obj-$(CONFIG_LUSTRE_FS) += lustre/
diff --git a/drivers/staging/lustre/TODO b/drivers/staging/lustre/TODO
index e325e1e98326..0512594b5199 100644
--- a/drivers/staging/lustre/TODO
+++ b/drivers/staging/lustre/TODO
@@ -9,5 +9,4 @@
* Other minor misc cleanups...
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>, Andreas Dilger
-<andreas.dilger@intel.com>, Oleg Drokin <oleg.drokin@intel.com>. CCing
-hpdd-discuss <hpdd-discuss@lists.01.org> would be great too.
+<andreas.dilger@intel.com>, and Oleg Drokin <oleg.drokin@intel.com>.
diff --git a/drivers/staging/lustre/include/linux/libcfs/bitmap.h b/drivers/staging/lustre/include/linux/libcfs/bitmap.h
deleted file mode 100644
index 8b137891791f..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/bitmap.h
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/drivers/staging/lustre/include/linux/libcfs/curproc.h b/drivers/staging/lustre/include/linux/libcfs/curproc.h
index b314f34d2e68..1edfca58c1c6 100644
--- a/drivers/staging/lustre/include/linux/libcfs/curproc.h
+++ b/drivers/staging/lustre/include/linux/libcfs/curproc.h
@@ -73,7 +73,7 @@ typedef __u32 cfs_cap_t;
(1 << CFS_CAP_DAC_OVERRIDE) | \
(1 << CFS_CAP_DAC_READ_SEARCH) | \
(1 << CFS_CAP_FOWNER) | \
- (1 << CFS_CAP_FSETID ) | \
+ (1 << CFS_CAP_FSETID) | \
(1 << CFS_CAP_LINUX_IMMUTABLE) | \
(1 << CFS_CAP_SYS_ADMIN) | \
(1 << CFS_CAP_SYS_BOOT) | \
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index 26b53f6420e5..7d37bec918f3 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -41,21 +41,21 @@
#define __attribute__(x)
#endif
-#include <linux/libcfs/linux/libcfs.h>
+#include "linux/libcfs.h"
#include <linux/gfp.h>
#include "curproc.h"
#ifndef offsetof
-# define offsetof(typ,memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
+# define offsetof(typ, memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
#endif
#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) ((sizeof (a)) / (sizeof ((a)[0])))
+#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
#endif
#if !defined(swap)
-#define swap(x,y) do { typeof(x) z = x; x = y; y = z; } while (0)
+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
#endif
#if !defined(container_of)
@@ -89,18 +89,18 @@ static inline int __is_po2(unsigned long long val)
int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
int libcfs_ipif_enumerate(char ***names);
void libcfs_ipif_free_enumeration(char **names, int n);
-int libcfs_sock_listen(socket_t **sockp, __u32 ip, int port, int backlog);
-int libcfs_sock_accept(socket_t **newsockp, socket_t *sock);
-void libcfs_sock_abort_accept(socket_t *sock);
-int libcfs_sock_connect(socket_t **sockp, int *fatal,
+int libcfs_sock_listen(struct socket **sockp, __u32 ip, int port, int backlog);
+int libcfs_sock_accept(struct socket **newsockp, struct socket *sock);
+void libcfs_sock_abort_accept(struct socket *sock);
+int libcfs_sock_connect(struct socket **sockp, int *fatal,
__u32 local_ip, int local_port,
__u32 peer_ip, int peer_port);
-int libcfs_sock_setbuf(socket_t *socket, int txbufsize, int rxbufsize);
-int libcfs_sock_getbuf(socket_t *socket, int *txbufsize, int *rxbufsize);
-int libcfs_sock_getaddr(socket_t *socket, int remote, __u32 *ip, int *port);
-int libcfs_sock_write(socket_t *sock, void *buffer, int nob, int timeout);
-int libcfs_sock_read(socket_t *sock, void *buffer, int nob, int timeout);
-void libcfs_sock_release(socket_t *sock);
+int libcfs_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
+int libcfs_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
+int libcfs_sock_getaddr(struct socket *socket, int remote, __u32 *ip, int *port);
+int libcfs_sock_write(struct socket *sock, void *buffer, int nob, int timeout);
+int libcfs_sock_read(struct socket *sock, void *buffer, int nob, int timeout);
+void libcfs_sock_release(struct socket *sock);
/* need both kernel and user-land acceptor */
#define LNET_ACCEPTOR_MIN_RESERVED_PORT 512
@@ -155,20 +155,19 @@ unsigned int cfs_rand(void);
void cfs_srand(unsigned int, unsigned int);
void cfs_get_random_bytes(void *buf, int size);
-#include <linux/libcfs/libcfs_debug.h>
-#include <linux/libcfs/libcfs_cpu.h>
-#include <linux/libcfs/libcfs_private.h>
-#include <linux/libcfs/libcfs_ioctl.h>
-#include <linux/libcfs/libcfs_prim.h>
-#include <linux/libcfs/libcfs_time.h>
-#include <linux/libcfs/libcfs_string.h>
-#include <linux/libcfs/libcfs_kernelcomm.h>
-#include <linux/libcfs/libcfs_workitem.h>
-#include <linux/libcfs/libcfs_hash.h>
-#include <linux/libcfs/libcfs_heap.h>
-#include <linux/libcfs/libcfs_fail.h>
-#include <linux/libcfs/params_tree.h>
-#include <linux/libcfs/libcfs_crypto.h>
+#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_kernelcomm.h"
+#include "libcfs_workitem.h"
+#include "libcfs_hash.h"
+#include "libcfs_heap.h"
+#include "libcfs_fail.h"
+#include "libcfs_crypto.h"
/* container_of depends on "likely" which is defined in libcfs_private.h */
static inline void *__container_of(void *ptr, unsigned long shift)
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index b270d84def98..30098f39181f 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -165,7 +165,7 @@ struct ptldebug_header {
#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
#define CDEBUG_DEFAULT_BACKOFF 2
struct cfs_debug_limit_state {
- cfs_time_t cdls_next;
+ unsigned long cdls_next;
unsigned int cdls_delay;
int cdls_count;
};
@@ -254,19 +254,19 @@ do { \
goto label; \
} while (0)
-extern int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
+int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
const char *format1, ...)
__attribute__ ((format (printf, 2, 3)));
-extern int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
+int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
const char *format1,
va_list args, const char *format2, ...)
__attribute__ ((format (printf, 4, 5)));
/* other external symbols that tracefile provides: */
-extern int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
+int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
const char *usr_buffer, int usr_buffer_nob);
-extern int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
+int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
const char *knl_buffer, char *append);
#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
index 8393c2703ce6..1934ec20e536 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
@@ -153,6 +153,7 @@ static inline void cfs_race(__u32 id)
if (CFS_FAIL_PRECHECK(id)) {
if (unlikely(__cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET))) {
int rc;
+
cfs_race_state = 0;
CERROR("cfs_race id %x sleeping\n", id);
cfs_wait_event_interruptible(cfs_race_waitq,
@@ -165,6 +166,7 @@ static inline void cfs_race(__u32 id)
}
}
}
+
#define CFS_RACE(id) cfs_race(id)
#endif /* _LIBCFS_FAIL_H */
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
index 954164361ca4..375586bf7312 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
@@ -628,21 +628,21 @@ static inline int cfs_hash_bd_dec_and_lock(struct cfs_hash *hs, struct cfs_hash_
}
static inline struct hlist_head *cfs_hash_bd_hhead(struct cfs_hash *hs,
- struct cfs_hash_bd *bd)
+ struct cfs_hash_bd *bd)
{
return hs->hs_hops->hop_hhead(hs, bd);
}
struct hlist_node *cfs_hash_bd_lookup_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bd, const void *key);
+ struct cfs_hash_bd *bd, const void *key);
struct hlist_node *cfs_hash_bd_peek_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bd, const void *key);
+ struct cfs_hash_bd *bd, const void *key);
struct hlist_node *cfs_hash_bd_findadd_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bd, const void *key,
+ struct cfs_hash_bd *bd, const void *key,
struct hlist_node *hnode,
int insist_add);
struct hlist_node *cfs_hash_bd_finddel_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bd, const void *key,
+ struct cfs_hash_bd *bd, const void *key,
struct hlist_node *hnode);
/**
@@ -661,21 +661,21 @@ static inline void cfs_hash_dual_bd_get_and_lock(struct cfs_hash *hs, const void
}
struct hlist_node *cfs_hash_dual_bd_lookup_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bds,
+ struct cfs_hash_bd *bds,
const void *key);
struct hlist_node *cfs_hash_dual_bd_findadd_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bds,
+ struct cfs_hash_bd *bds,
const void *key,
struct hlist_node *hnode,
int insist_add);
struct hlist_node *cfs_hash_dual_bd_finddel_locked(struct cfs_hash *hs,
- struct cfs_hash_bd *bds,
+ struct cfs_hash_bd *bds,
const void *key,
struct hlist_node *hnode);
/* Hash init/cleanup functions */
struct cfs_hash *cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
- unsigned bkt_bits, unsigned extra_bytes,
+ unsigned bkt_bits, unsigned extra_bytes,
unsigned min_theta, unsigned max_theta,
cfs_hash_ops_t *ops, unsigned flags);
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
index 49ba62a4daa8..87f2d901c7c1 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
@@ -41,7 +41,6 @@
#ifndef __LIBCFS_IOCTL_H__
#define __LIBCFS_IOCTL_H__
-
#define LIBCFS_IOCTL_VERSION 0x0001000a
struct libcfs_ioctl_data {
@@ -90,7 +89,6 @@ do { \
data.ioc_len = sizeof(data); \
} while (0)
-
struct libcfs_ioctl_handler {
struct list_head item;
int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_data *data);
@@ -102,11 +100,9 @@ struct libcfs_ioctl_handler {
/* .handle_ioctl = */ func \
}
-
/* FIXME check conflict with lustre_lib.h */
#define LIBCFS_IOC_DEBUG_MASK _IOWR('f', 250, long)
-
/* ioctls for manipulating snapshots 30- */
#define IOC_LIBCFS_TYPE 'e'
#define IOC_LIBCFS_MIN_NR 30
@@ -149,6 +145,7 @@ struct libcfs_ioctl_handler {
static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
{
int len = sizeof(*data);
+
len += cfs_size_round(data->ioc_inllen1);
len += cfs_size_round(data->ioc_inllen2);
return len;
@@ -157,64 +154,62 @@ static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
static inline int libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
{
if (data->ioc_len > (1<<30)) {
- CERROR ("LIBCFS ioctl: ioc_len larger than 1<<30\n");
+ CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen1 > (1<<30)) {
- CERROR ("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
+ CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
return 1;
}
if (data->ioc_inllen2 > (1<<30)) {
- CERROR ("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
+ CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
return 1;
}
if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
- CERROR ("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
+ CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
- CERROR ("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
+ CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf1 && !data->ioc_plen1) {
- CERROR ("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
+ CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
return 1;
}
if (data->ioc_pbuf2 && !data->ioc_plen2) {
- CERROR ("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
+ CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
return 1;
}
if (data->ioc_plen1 && !data->ioc_pbuf1) {
- CERROR ("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
+ CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
return 1;
}
if (data->ioc_plen2 && !data->ioc_pbuf2) {
- CERROR ("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
+ CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
return 1;
}
- if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len ) {
- CERROR ("LIBCFS ioctl: packlen != ioc_len\n");
+ if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len) {
+ CERROR("LIBCFS ioctl: packlen != ioc_len\n");
return 1;
}
if (data->ioc_inllen1 &&
data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
- CERROR ("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
+ CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
return 1;
}
if (data->ioc_inllen2 &&
data->ioc_bulk[cfs_size_round(data->ioc_inllen1) +
data->ioc_inllen2 - 1] != '\0') {
- CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
+ CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
return 1;
}
return 0;
}
-
int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
int libcfs_ioctl_getdata(char *buf, char *end, void *arg);
int libcfs_ioctl_popdata(void *arg, void *buf, int size);
-
#endif /* __LIBCFS_IOCTL_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h
index 037ae8a6d531..f19a121a37cd 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h
@@ -47,7 +47,6 @@
#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
#endif
-
/* KUC message header.
* All current and future KUC messages should use this header.
* To avoid having to include Lustre headers from libcfs, define this here.
@@ -90,12 +89,12 @@ typedef int (*libcfs_kkuc_cb_t)(__u32 data, void *cb_arg);
#define KUC_GRP_MAX KUC_GRP_HSM
/* Kernel methods */
-extern int libcfs_kkuc_msg_put(struct file *fp, void *payload);
-extern int libcfs_kkuc_group_put(int group, void *payload);
-extern int libcfs_kkuc_group_add(struct file *fp, int uid, int group,
+int libcfs_kkuc_msg_put(struct file *fp, void *payload);
+int libcfs_kkuc_group_put(int group, void *payload);
+int libcfs_kkuc_group_add(struct file *fp, int uid, int group,
__u32 data);
-extern int libcfs_kkuc_group_rem(int uid, int group);
-extern int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
+int libcfs_kkuc_group_rem(int uid, int group);
+int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
void *cb_arg);
#define LK_FLG_STOP 0x01
@@ -111,9 +110,9 @@ typedef struct lustre_kernelcomm {
} __attribute__((packed)) lustre_kernelcomm;
/* Userspace methods */
-extern int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
-extern int libcfs_ukuc_stop(lustre_kernelcomm *l);
-extern int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
+int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
+int libcfs_ukuc_stop(lustre_kernelcomm *l);
+int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
int transport);
#endif /* __LIBCFS_KERNELCOMM_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h
index 7cf34aa78f79..a38209506d6c 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h
@@ -50,10 +50,10 @@ void add_wait_queue_exclusive_head(wait_queue_head_t *, wait_queue_t *);
void cfs_init_timer(struct timer_list *t);
void cfs_timer_init(struct timer_list *t, cfs_timer_func_t *func, void *arg);
void cfs_timer_done(struct timer_list *t);
-void cfs_timer_arm(struct timer_list *t, cfs_time_t deadline);
+void cfs_timer_arm(struct timer_list *t, unsigned long deadline);
void cfs_timer_disarm(struct timer_list *t);
int cfs_timer_is_armed(struct timer_list *t);
-cfs_time_t cfs_timer_deadline(struct timer_list *t);
+unsigned long cfs_timer_deadline(struct timer_list *t);
/*
* Memory
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
index 740bfcd2f09a..82a269cee6dd 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
@@ -43,14 +43,13 @@
#define __LIBCFS_PRIVATE_H__
/* XXX this layering violation is for nidstrings */
-#include <linux/lnet/types.h>
+#include "../lnet/types.h"
#ifndef DEBUG_SUBSYSTEM
# define DEBUG_SUBSYSTEM S_UNDEFINED
#endif
-
/*
* When this is on, LASSERT macro includes check for assignment used instead
* of equality check, but doesn't have unlikely(). Turn this on from time to
@@ -58,7 +57,6 @@
*/
#define LASSERT_CHECKED (0)
-
#define LASSERTF(cond, fmt, ...) \
do { \
if (unlikely(!(cond))) { \
@@ -80,18 +78,18 @@ do { \
*/
# define LINVRNT(exp) LASSERT(exp)
#else
-# define LINVRNT(exp) ((void)sizeof!!(exp))
+# define LINVRNT(exp) ((void)sizeof !!(exp))
#endif
#define KLASSERT(e) LASSERT(e)
-void lbug_with_loc(struct libcfs_debug_msg_data *) __attribute__((noreturn));
+void lbug_with_loc(struct libcfs_debug_msg_data *)__attribute__((noreturn));
#define LBUG() \
do { \
LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL); \
lbug_with_loc(&msgdata); \
-} while(0)
+} while (0)
extern atomic_t libcfs_kmemory;
/*
@@ -111,7 +109,6 @@ do { \
# define libcfs_kmem_read() \
atomic_read(&libcfs_kmemory)
-
#ifndef LIBCFS_VMALLOC_SIZE
#define LIBCFS_VMALLOC_SIZE (2 << PAGE_CACHE_SHIFT) /* 2 pages */
#endif
@@ -220,7 +217,6 @@ int libcfs_debug_mark_buffer(const char *text);
void libcfs_debug_set_level(unsigned int debug_level);
-
/*
* allocate per-cpu-partition data, returned value is an array of pointers,
* variable can be indexed by CPU ID.
@@ -339,8 +335,8 @@ do { \
#define LASSERT_ATOMIC_ZERO(a) LASSERT_ATOMIC_EQ(a, 0)
#define LASSERT_ATOMIC_POS(a) LASSERT_ATOMIC_GT(a, 0)
-#define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof (*(ptr)));
-#define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof (*(ptr)));
+#define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr)));
+#define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr)));
/*
* percpu partition lock
@@ -363,7 +359,6 @@ enum {
CFS_PERCPT_LOCK_EX = -1, /* negative */
};
-
struct cfs_percpt_lock {
/* cpu-partition-table for this lock */
struct cfs_cpt_table *pcl_cptab;
@@ -380,7 +375,6 @@ cfs_percpt_lock_num(struct cfs_percpt_lock *pcl)
return cfs_cpt_number(pcl->pcl_cptab);
}
-
/*
* create a cpu-partition lock based on CPU partition table \a cptab,
* each private lock has extra \a psize bytes padding data
@@ -400,7 +394,6 @@ void cfs_percpt_atomic_free(atomic_t **refs);
/* return sum of all percpu refs */
int cfs_percpt_atomic_summary(atomic_t **refs);
-
/** Compile-time assertion.
* Check an invariant described by a constant expression at compile time by
@@ -415,7 +408,7 @@ int cfs_percpt_atomic_summary(atomic_t **refs);
* value after conversion...
*
*/
-#define CLASSERT(cond) do {switch(42) {case (cond): case 0: break;}} while (0)
+#define CLASSERT(cond) do {switch (42) {case (cond): case 0: break; } } while (0)
/* support decl needed both by kernel and liblustre */
int libcfs_isknown_lnd(int type);
@@ -440,11 +433,11 @@ int cfs_match_nid(lnet_nid_t nid, struct list_head *list);
/** extract the network part of an lnet_nid_t */
#define LNET_NIDNET(nid) ((__u32)(((nid) >> 32)) & 0xffffffff)
/** make an lnet_nid_t from a network part and an address part */
-#define LNET_MKNID(net,addr) ((((__u64)(net))<<32)|((__u64)(addr)))
+#define LNET_MKNID(net, addr) ((((__u64)(net))<<32)|((__u64)(addr)))
/* how net encodes type:number */
#define LNET_NETNUM(net) ((net) & 0xffff)
#define LNET_NETTYP(net) (((net) >> 16) & 0xffff)
-#define LNET_MKNET(typ,num) ((((__u32)(typ))<<16)|((__u32)(num)))
+#define LNET_MKNET(typ, num) ((((__u32)(typ))<<16)|((__u32)(num)))
/** @} lnet_addr */
/* max value for numeric network address */
@@ -458,7 +451,6 @@ int cfs_match_nid(lnet_nid_t nid, struct list_head *list);
/* --------------------------------------------------------------------
* Light-weight trace
* Support for temporary event tracing with minimal Heisenberg effect.
- * All stuff about lwt are put in arch/kp30.h
* -------------------------------------------------------------------- */
struct libcfs_device_userstate
@@ -469,24 +461,25 @@ struct libcfs_device_userstate
/* what used to be in portals_lib.h */
#ifndef MIN
-# define MIN(a,b) (((a)<(b)) ? (a): (b))
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
-# define MAX(a,b) (((a)>(b)) ? (a): (b))
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
-#define MKSTR(ptr) ((ptr))? (ptr) : ""
+#define MKSTR(ptr) ((ptr)) ? (ptr) : ""
-static inline int cfs_size_round4 (int val)
+static inline int cfs_size_round4(int val)
{
return (val + 3) & (~0x3);
}
#ifndef HAVE_CFS_SIZE_ROUND
-static inline int cfs_size_round (int val)
+static inline int cfs_size_round(int val)
{
return (val + 7) & (~0x7);
}
+
#define HAVE_CFS_SIZE_ROUND
#endif
@@ -525,21 +518,21 @@ static inline unsigned int cfs_power2_roundup(unsigned int val)
return val;
}
-#define LOGL(var,len,ptr) \
+#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) \
+#define LOGU(var, len, ptr) \
do { \
if (var) \
memcpy((char *)var, (const char *)ptr, len); \
ptr += cfs_size_round(len); \
} while (0)
-#define LOGL0(var,len,ptr) \
+#define LOGL0(var, len, ptr) \
do { \
if (!len) \
break; \
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
index 4bdd77163d5e..1344139c46c3 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
@@ -43,28 +43,27 @@
* generic time manipulation functions.
*/
-static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
+static inline unsigned long cfs_time_add(unsigned long t, long d)
{
- return (cfs_time_t)(t + d);
+ return (unsigned long)(t + d);
}
-static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
+static inline unsigned long cfs_time_sub(unsigned long t1, unsigned long t2)
{
- return (cfs_time_t)(t1 - t2);
+ return (unsigned long)(t1 - t2);
}
-static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2)
+static inline int cfs_time_after(unsigned long t1, unsigned long t2)
{
- return cfs_time_before(t2, t1);
+ return time_before(t2, t1);
}
-static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2)
+static inline int cfs_time_aftereq(unsigned long t1, unsigned long t2)
{
- return cfs_time_beforeq(t2, t1);
+ return time_before_eq(t2, t1);
}
-
-static inline cfs_time_t cfs_time_shift(int seconds)
+static inline unsigned long cfs_time_shift(int seconds)
{
return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
}
@@ -72,7 +71,7 @@ static inline cfs_time_t cfs_time_shift(int seconds)
static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small,
struct timeval *result)
{
- long r = (long) (
+ long r = (long)(
(large->tv_sec - small->tv_sec) * ONE_MILLION +
(large->tv_usec - small->tv_usec));
if (result != NULL) {
@@ -82,12 +81,12 @@ static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small,
return r;
}
-static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg)
+static inline void cfs_slow_warning(unsigned long now, int seconds, char *msg)
{
if (cfs_time_after(cfs_time_current(),
cfs_time_add(now, cfs_time_seconds(15))))
CERROR("slow %s "CFS_TIME_T" sec\n", msg,
- cfs_duration_sec(cfs_time_sub(cfs_time_current(),now)));
+ cfs_duration_sec(cfs_time_sub(cfs_time_current(), now)));
}
#define CFS_RATELIMIT(seconds) \
@@ -112,7 +111,7 @@ static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg)
*/
static inline void cfs_fs_timeval(struct timeval *tv)
{
- cfs_fs_time_t time;
+ struct timespec time;
cfs_fs_time_current(&time);
cfs_fs_time_usec(&time, tv);
@@ -122,7 +121,7 @@ static inline void cfs_fs_timeval(struct timeval *tv)
* return valid time-out based on user supplied one. Currently we only check
* that time-out is not shorted than allowed.
*/
-static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout)
+static inline long cfs_timeout_cap(long timeout)
{
if (timeout < CFS_TICK)
timeout = CFS_TICK;
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h b/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h
deleted file mode 100644
index a09fed3c6ea8..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h
+++ /dev/null
@@ -1,93 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef __LIBCFS_LINUX_KP30_H__
-#define __LIBCFS_LINUX_KP30_H__
-
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/kmod.h>
-#include <linux/notifier.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/vmalloc.h>
-#include <linux/time.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-#include <linux/module.h>
-#include <asm/atomic.h>
-#include <asm/uaccess.h>
-#include <linux/rwsem.h>
-#include <linux/proc_fs.h>
-#include <linux/file.h>
-#include <linux/smp.h>
-#include <linux/ctype.h>
-#include <linux/compiler.h>
-#include <linux/mm_inline.h>
-#include <linux/kallsyms.h>
-#include <linux/moduleparam.h>
-#include <linux/scatterlist.h>
-
-#include <linux/libcfs/linux/portals_compat25.h>
-
-/* this is a bit chunky */
-
-# define LPU64 "%llu"
-# define LPD64 "%lld"
-# define LPX64 "%#llx"
-# define LPX64i "%llx"
-# define LPO64 "%#llo"
-# define LPF64 "L"
-
-/*
- * long_ptr_t & ulong_ptr_t, same to "long" for gcc
- */
-# define LPLU "%lu"
-# define LPLD "%ld"
-# define LPLX "%#lx"
-
-/*
- * pid_t
- */
-# define LPPID "%d"
-
-#endif
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h
index a7bca40e9fb7..ccc55fc41a9e 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h
@@ -42,28 +42,57 @@
#endif
-
-#include <stdarg.h>
-#include <linux/libcfs/linux/linux-cpu.h>
-#include <linux/libcfs/linux/linux-time.h>
-#include <linux/libcfs/linux/linux-mem.h>
-#include <linux/libcfs/linux/linux-prim.h>
-#include <linux/libcfs/linux/linux-lock.h>
-#include <linux/libcfs/linux/linux-tcpip.h>
-#include <linux/libcfs/linux/linux-bitops.h>
-#include <linux/libcfs/linux/linux-types.h>
-#include <linux/libcfs/linux/kp30.h>
-
-#include <asm/types.h>
+#include <linux/bitops.h>
+#include <linux/compiler.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/kthread.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/mm_inline.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+#include <linux/rbtree.h>
+#include <linux/rwsem.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/timer.h>
#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/vmalloc.h>
+#include <net/sock.h>
+#include <asm/atomic.h>
+#include <asm/div64.h>
#include <asm/timex.h>
-#include <linux/sched.h> /* THREAD_SIZE */
-#include <linux/rbtree.h>
+#include <asm/uaccess.h>
+#include <stdarg.h>
+#include "linux-cpu.h"
+#include "linux-time.h"
+#include "linux-mem.h"
+#include "portals_compat25.h"
+
#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
#if !defined(__x86_64__)
-# ifdef __ia64__
+# ifdef __ia64__
# define CDEBUG_STACK() (THREAD_SIZE - \
((unsigned long)__builtin_dwarf_cfa() & \
(THREAD_SIZE - 1)))
@@ -89,7 +118,7 @@ do { \
} while (0)
#define CFS_CHECK_STACK(msgdata, mask, cdls) __CHECK_STACK(msgdata, mask, cdls)
#else /* __x86_64__ */
-#define CFS_CHECK_STACK(msgdata, mask, cdls) do {} while(0)
+#define CFS_CHECK_STACK(msgdata, mask, cdls) do {} while (0)
#define CDEBUG_STACK() (0L)
#endif /* __x86_64__ */
@@ -103,7 +132,7 @@ do { \
*
* Implementation is in linux-curproc.c
*/
-#define CFS_CURPROC_COMM_MAX (sizeof ((struct task_struct *)0)->comm)
+#define CFS_CURPROC_COMM_MAX (sizeof((struct task_struct *)0)->comm)
#include <linux/capability.h>
@@ -116,6 +145,4 @@ typedef long long_ptr_t;
#endif
-
-
#endif /* _LINUX_LIBCFS_H */
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h
deleted file mode 100644
index 43936e349dd4..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h
+++ /dev/null
@@ -1,38 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/linux/linux-bitops.h
- */
-#include <linux/bitops.h>
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h
index 8dd354d51606..520209f17173 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h
@@ -42,7 +42,6 @@
#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
#endif
-
#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/topology.h>
@@ -79,88 +78,5 @@ struct cfs_cpt_table {
nodemask_t *ctb_nodemask;
};
-/**
- * comment out definitions for compatible layer
- *
- * typedef cpumask_t cfs_cpumask_t;
- *
- * #define cfs_cpu_current() smp_processor_id()
- * #define cfs_cpu_online(i) cpu_online(i)
- * #define cfs_cpu_online_num() num_online_cpus()
- * #define cfs_cpu_online_for_each(i) for_each_online_cpu(i)
- * #define cfs_cpu_possible_num() num_possible_cpus()
- * #define cfs_cpu_possible_for_each(i) for_each_possible_cpu(i)
- *
- * #ifdef CONFIG_CPUMASK_SIZE
- * #define cfs_cpu_mask_size() cpumask_size()
- * #else
- * #define cfs_cpu_mask_size() sizeof(cfs_cpumask_t)
- * #endif
- *
- * #define cfs_cpu_mask_set(i, mask) cpu_set(i, mask)
- * #define cfs_cpu_mask_unset(i, mask) cpu_clear(i, mask)
- * #define cfs_cpu_mask_isset(i, mask) cpu_isset(i, mask)
- * #define cfs_cpu_mask_clear(mask) cpus_clear(mask)
- * #define cfs_cpu_mask_empty(mask) cpus_empty(mask)
- * #define cfs_cpu_mask_weight(mask) cpus_weight(mask)
- * #define cfs_cpu_mask_first(mask) first_cpu(mask)
- * #define cfs_cpu_mask_any_online(mask) (any_online_cpu(mask) != NR_CPUS)
- * #define cfs_cpu_mask_for_each(i, mask) for_each_cpu_mask(i, mask)
- * #define cfs_cpu_mask_bind(t, mask) set_cpus_allowed(t, mask)
- *
- * #ifdef HAVE_CPUMASK_COPY
- * #define cfs_cpu_mask_copy(dst, src) cpumask_copy(dst, src)
- * #else
- * #define cfs_cpu_mask_copy(dst, src) memcpy(dst, src, sizeof(*src))
- * #endif
- *
- * static inline void
- * cfs_cpu_mask_of_online(cfs_cpumask_t *mask)
- * {
- * cfs_cpu_mask_copy(mask, &cpu_online_map);
- * }
- *
- * #ifdef CONFIG_NUMA
- *
- * #define CFS_NODE_NR MAX_NUMNODES
- *
- * typedef nodemask_t cfs_node_mask_t;
- *
- * #define cfs_node_of_cpu(cpu) cpu_to_node(cpu)
- * #define cfs_node_online(i) node_online(i)
- * #define cfs_node_online_num() num_online_nodes()
- * #define cfs_node_online_for_each(i) for_each_online_node(i)
- * #define cfs_node_possible_num() num_possible_nodes()
- * #define cfs_node_possible_for_each(i) for_each_node(i)
- *
- * static inline void cfs_node_to_cpumask(int node, cfs_cpumask_t *mask)
- * {
- * #if defined(HAVE_NODE_TO_CPUMASK)
- * *mask = node_to_cpumask(node);
- * #elif defined(HAVE_CPUMASK_OF_NODE)
- * cfs_cpu_mask_copy(mask, cpumask_of_node(node));
- * #else
- * # error "Needs node_to_cpumask or cpumask_of_node"
- * #endif
- * }
- *
- * #define cfs_node_mask_set(i, mask) node_set(i, mask)
- * #define cfs_node_mask_unset(i, mask) node_clear(i, mask)
- * #define cfs_node_mask_isset(i, mask) node_isset(i, mask)
- * #define cfs_node_mask_clear(mask) nodes_reset(mask)
- * #define cfs_node_mask_empty(mask) nodes_empty(mask)
- * #define cfs_node_mask_weight(mask) nodes_weight(mask)
- * #define cfs_node_mask_for_each(i, mask) for_each_node_mask(i, mask)
- * #define cfs_node_mask_copy(dst, src) memcpy(dst, src, sizeof(*src))
- *
- * static inline void
- * cfs_node_mask_of_online(cfs_node_mask_t *mask)
- * {
- * cfs_node_mask_copy(mask, &node_online_map);
- * }
- *
- * #endif
- */
-
#endif /* CONFIG_SMP */
#endif /* __LIBCFS_LINUX_CPU_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h
deleted file mode 100644
index b75e401d9a97..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h
+++ /dev/null
@@ -1,204 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/linux/linux-lock.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_LINUX_CFS_LOCK_H__
-#define __LIBCFS_LINUX_CFS_LOCK_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
-#endif
-
-
-#include <linux/mutex.h>
-
-/*
- * IMPORTANT !!!!!!!!
- *
- * All locks' declaration are not guaranteed to be initialized,
- * although some of them are initialized in Linux. All locks
- * declared by CFS_DECL_* should be initialized explicitly.
- */
-
-/*
- * spin_lock "implementation" (use Linux kernel's primitives)
- *
- * - spin_lock_init(x)
- * - spin_lock(x)
- * - spin_lock_bh(x)
- * - spin_lock_bh_init(x)
- * - spin_unlock(x)
- * - spin_unlock_bh(x)
- * - spin_trylock(x)
- * - assert_spin_locked(x)
- *
- * - spin_lock_irq(x)
- * - spin_lock_irqsave(x, f)
- * - spin_unlock_irqrestore(x, f)
- * - read_lock_irqsave(lock, f)
- * - write_lock_irqsave(lock, f)
- * - write_unlock_irqrestore(lock, f)
- */
-
-/*
- * spinlock "implementation"
- */
-
-
-
-
-/*
- * rw_semaphore "implementation" (use Linux kernel's primitives)
- *
- * - sema_init(x)
- * - init_rwsem(x)
- * - down_read(x)
- * - up_read(x)
- * - down_write(x)
- * - up_write(x)
- */
-
-
-#define fini_rwsem(s) do {} while (0)
-
-
-/*
- * rwlock_t "implementation" (use Linux kernel's primitives)
- *
- * - rwlock_init(x)
- * - read_lock(x)
- * - read_unlock(x)
- * - write_lock(x)
- * - write_unlock(x)
- * - write_lock_bh(x)
- * - write_unlock_bh(x)
- *
- * - RW_LOCK_UNLOCKED
- */
-
-
-#ifndef DEFINE_RWLOCK
-#define DEFINE_RWLOCK(lock) rwlock_t lock = __RW_LOCK_UNLOCKED(lock)
-#endif
-
-/*
- * completion "implementation" (use Linux kernel's primitives)
- *
- * - DECLARE_COMPLETION(work)
- * - INIT_COMPLETION(c)
- * - COMPLETION_INITIALIZER(work)
- * - init_completion(c)
- * - complete(c)
- * - wait_for_completion(c)
- * - wait_for_completion_interruptible(c)
- * - fini_completion(c)
- */
-#define fini_completion(c) do { } while (0)
-
-/*
- * semaphore "implementation" (use Linux kernel's primitives)
- * - DEFINE_SEMAPHORE(name)
- * - sema_init(sem, val)
- * - up(sem)
- * - down(sem)
- * - down_interruptible(sem)
- * - down_trylock(sem)
- */
-
-/*
- * mutex "implementation" (use Linux kernel's primitives)
- *
- * - DEFINE_MUTEX(name)
- * - mutex_init(x)
- * - mutex_lock(x)
- * - mutex_unlock(x)
- * - mutex_trylock(x)
- * - mutex_is_locked(x)
- * - mutex_destroy(x)
- */
-
-#ifndef lockdep_set_class
-
-/**************************************************************************
- *
- * Lockdep "implementation". Also see liblustre.h
- *
- **************************************************************************/
-
-struct lock_class_key {
- ;
-};
-
-#define lockdep_set_class(lock, key) \
- do { (void)sizeof(lock); (void)sizeof(key); } while (0)
-/* This has to be a macro, so that `subclass' can be undefined in kernels
- * that do not support lockdep. */
-
-
-static inline void lockdep_off(void)
-{
-}
-
-static inline void lockdep_on(void)
-{
-}
-#else
-
-#endif /* lockdep_set_class */
-
-#ifndef CONFIG_DEBUG_LOCK_ALLOC
-#ifndef mutex_lock_nested
-#define mutex_lock_nested(mutex, subclass) mutex_lock(mutex)
-#endif
-
-#ifndef spin_lock_nested
-#define spin_lock_nested(lock, subclass) spin_lock(lock)
-#endif
-
-#ifndef down_read_nested
-#define down_read_nested(lock, subclass) down_read(lock)
-#endif
-
-#ifndef down_write_nested
-#define down_write_nested(lock, subclass) down_write(lock)
-#endif
-#endif /* CONFIG_DEBUG_LOCK_ALLOC */
-
-
-#endif /* __LIBCFS_LINUX_CFS_LOCK_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
index ccee5c3e4142..0f2fd79e5ec8 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
@@ -45,7 +45,6 @@
#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
#endif
-
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
@@ -55,7 +54,7 @@
#ifndef HAVE_LIBCFS_CPT
/* Need this for cfs_cpt_table */
-#include <linux/libcfs/libcfs_cpu.h>
+#include "../libcfs_cpu.h"
#endif
#define CFS_PAGE_MASK (~((__u64)PAGE_CACHE_SIZE-1))
@@ -73,15 +72,9 @@
#define NUM_CACHEPAGES totalram_pages
#endif
-/*
- * In Linux there is no way to determine whether current execution context is
- * blockable.
- */
-#define ALLOC_ATOMIC_TRY GFP_ATOMIC
-
#define DECL_MMSPACE mm_segment_t __oldfs
#define MMSPACE_OPEN \
- do { __oldfs = get_fs(); set_fs(get_ds());} while(0)
+ do { __oldfs = get_fs(); set_fs(get_ds()); } while (0)
#define MMSPACE_CLOSE set_fs(__oldfs)
#endif /* __LINUX_CFS_MEM_H__ */
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h
deleted file mode 100644
index 2aeff27b1641..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h
+++ /dev/null
@@ -1,82 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/linux/linux-prim.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_LINUX_CFS_PRIM_H__
-#define __LIBCFS_LINUX_CFS_PRIM_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
-#endif
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/random.h>
-
-#include <linux/miscdevice.h>
-#include <linux/libcfs/linux/portals_compat25.h>
-#include <asm/div64.h>
-
-#include <linux/libcfs/linux/linux-time.h>
-
-/*
- * Sysctl register
- */
-typedef struct ctl_table ctl_table_t;
-typedef struct ctl_table_header ctl_table_header_t;
-
-#define DECLARE_PROC_HANDLER(name) \
-static int \
-LL_PROC_PROTO(name) \
-{ \
- DECLARE_LL_PROC_PPOS_DECL; \
- \
- return proc_call_handler(table->data, write, \
- ppos, buffer, lenp, \
- __##name); \
-}
-
-#endif
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h
deleted file mode 100644
index 7a8d006903b9..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h
+++ /dev/null
@@ -1,72 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * libcfs/include/libcfs/linux/linux-tcpip.h
- *
- * Basic library routines.
- */
-
-#ifndef __LIBCFS_LINUX_CFS_TCP_H__
-#define __LIBCFS_LINUX_CFS_TCP_H__
-
-#ifndef __LIBCFS_LIBCFS_H__
-#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
-#endif
-
-
-#include <net/sock.h>
-
-typedef struct socket socket_t;
-
-#define SOCK_SNDBUF(so) ((so)->sk->sk_sndbuf)
-#define SOCK_TEST_NOSPACE(so) test_bit(SOCK_NOSPACE, &(so)->flags)
-
-static inline int
-cfs_sock_error(struct socket *sock)
-{
- return sock->sk->sk_err;
-}
-
-static inline int
-cfs_sock_wmem_queued(struct socket *sock)
-{
- return sock->sk->sk_wmem_queued;
-}
-
-#define cfs_sk_sleep(sk) sk_sleep(sk)
-
-#define DEFAULT_NET (&init_net)
-
-#endif
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
index a386d1b1286b..1158a3112bcc 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
@@ -45,56 +45,15 @@
#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
#endif
-
-/* Portable time API */
-
-/*
- * Platform provides three opaque data-types:
- *
- * cfs_time_t represents point in time. This is internal kernel
- * time rather than "wall clock". This time bears no
- * relation to gettimeofday().
- *
- * cfs_duration_t represents time interval with resolution of internal
- * platform clock
- *
- * cfs_fs_time_t represents instance in world-visible time. This is
- * used in file-system time-stamps
- *
- * cfs_time_t cfs_time_current(void);
- * cfs_time_t cfs_time_add (cfs_time_t, cfs_duration_t);
- * cfs_duration_t cfs_time_sub (cfs_time_t, cfs_time_t);
- * int cfs_impl_time_before (cfs_time_t, cfs_time_t);
- * int cfs_impl_time_before_eq(cfs_time_t, cfs_time_t);
- *
- * cfs_duration_t cfs_duration_build(int64_t);
- *
- * time_t cfs_duration_sec (cfs_duration_t);
- * void cfs_duration_usec(cfs_duration_t, struct timeval *);
- * void cfs_duration_nsec(cfs_duration_t, struct timespec *);
- *
- * void cfs_fs_time_current(cfs_fs_time_t *);
- * time_t cfs_fs_time_sec (cfs_fs_time_t *);
- * void cfs_fs_time_usec (cfs_fs_time_t *, struct timeval *);
- * void cfs_fs_time_nsec (cfs_fs_time_t *, struct timespec *);
- * int cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
- * int cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
- *
- * CFS_TIME_FORMAT
- * CFS_DURATION_FORMAT
- *
- */
-
#define ONE_BILLION ((u_int64_t)1000000000)
#define ONE_MILLION 1000000
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <asm/div64.h>
-#include <linux/libcfs/linux/portals_compat25.h>
+#include "portals_compat25.h"
/*
* post 2.5 kernels.
@@ -102,133 +61,58 @@
#include <linux/jiffies.h>
-typedef struct timespec cfs_fs_time_t;
-static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+static inline void cfs_fs_time_usec(struct timespec *t, struct timeval *v)
{
v->tv_sec = t->tv_sec;
v->tv_usec = t->tv_nsec / 1000;
}
-static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
-{
- *s = *t;
-}
-
-/*
- * internal helper function used by cfs_fs_time_before*()
- */
-static inline unsigned long long __cfs_fs_time_flat(cfs_fs_time_t *t)
-{
- return (unsigned long long)t->tv_sec * ONE_BILLION + t->tv_nsec;
-}
-
-
/*
* Generic kernel stuff
*/
-typedef unsigned long cfs_time_t; /* jiffies */
-typedef long cfs_duration_t;
-typedef cycles_t cfs_cycles_t;
-
-static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
-{
- return time_before(t1, t2);
-}
-
-static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
-{
- return time_before_eq(t1, t2);
-}
-
-static inline cfs_time_t cfs_time_current(void)
+static inline unsigned long cfs_time_current(void)
{
return jiffies;
}
-static inline time_t cfs_time_current_sec(void)
-{
- return get_seconds();
-}
-
-static inline void cfs_fs_time_current(cfs_fs_time_t *t)
+static inline void cfs_fs_time_current(struct timespec *t)
{
*t = CURRENT_TIME;
}
-static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
+static inline time_t cfs_fs_time_sec(struct timespec *t)
{
return t->tv_sec;
}
-static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
-{
- return __cfs_fs_time_flat(t1) < __cfs_fs_time_flat(t2);
-}
-
-static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
-{
- return __cfs_fs_time_flat(t1) <= __cfs_fs_time_flat(t2);
-}
-
-#if 0
-static inline cfs_duration_t cfs_duration_build(int64_t nano)
-{
-#if (BITS_PER_LONG == 32)
- /* We cannot use do_div(t, ONE_BILLION), do_div can only process
- * 64 bits n and 32 bits base */
- int64_t t = nano * HZ;
- do_div(t, 1000);
- do_div(t, 1000000);
- return (cfs_duration_t)t;
-#else
- return (nano * HZ / ONE_BILLION);
-#endif
-}
-#endif
-
-static inline cfs_duration_t cfs_time_seconds(int seconds)
+static inline long cfs_time_seconds(int seconds)
{
- return ((cfs_duration_t)seconds) * HZ;
+ return ((long)seconds) * HZ;
}
-static inline time_t cfs_duration_sec(cfs_duration_t d)
+static inline time_t cfs_duration_sec(long d)
{
return d / HZ;
}
-static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
+static inline void cfs_duration_usec(long d, struct timeval *s)
{
#if (BITS_PER_LONG == 32) && (HZ > 4096)
__u64 t;
s->tv_sec = d / HZ;
- t = (d - (cfs_duration_t)s->tv_sec * HZ) * ONE_MILLION;
+ t = (d - (long)s->tv_sec * HZ) * ONE_MILLION;
do_div(t, HZ);
s->tv_usec = t;
#else
s->tv_sec = d / HZ;
- s->tv_usec = ((d - (cfs_duration_t)s->tv_sec * HZ) * \
+ s->tv_usec = ((d - (long)s->tv_sec * HZ) * \
ONE_MILLION) / HZ;
#endif
}
-static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
-{
-#if (BITS_PER_LONG == 32)
- __u64 t;
-
- s->tv_sec = d / HZ;
- t = (d - s->tv_sec * HZ) * ONE_BILLION;
- do_div(t, HZ);
- s->tv_nsec = t;
-#else
- s->tv_sec = d / HZ;
- s->tv_nsec = ((d - s->tv_sec * HZ) * ONE_BILLION) / HZ;
-#endif
-}
-
#define cfs_time_current_64 get_jiffies_64
static inline __u64 cfs_time_add_64(__u64 t, __u64 d)
@@ -252,7 +136,6 @@ static inline int cfs_time_beforeq_64(__u64 t1, __u64 t2)
return (__s64)t2 - (__s64)t1 >= 0;
}
-
/*
* One jiffy
*/
@@ -261,14 +144,4 @@ static inline int cfs_time_beforeq_64(__u64 t1, __u64 t2)
#define CFS_TIME_T "%lu"
#define CFS_DURATION_T "%ld"
-
#endif /* __LIBCFS_LINUX_LINUX_TIME_H__ */
-/*
- * Local variables:
- * c-indentation-style: "K&R"
- * c-basic-offset: 8
- * tab-width: 8
- * fill-column: 80
- * scroll-step: 1
- * End:
- */
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h
deleted file mode 100644
index 142394925567..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h
+++ /dev/null
@@ -1,36 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 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.
- *
- * libcfs/include/libcfs/user-bitops.h
- */
-#include <linux/types.h>
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h b/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h
index fe4c63fb40a4..442d61be1c18 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h
@@ -37,14 +37,14 @@
#ifndef __LIBCFS_LINUX_PORTALS_COMPAT_H__
#define __LIBCFS_LINUX_PORTALS_COMPAT_H__
-// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+/* XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved */
#if defined(SPINLOCK_DEBUG) && SPINLOCK_DEBUG
# define SIGNAL_MASK_ASSERT() \
LASSERT(current->sighand->siglock.magic == SPINLOCK_MAGIC)
#else
# define SIGNAL_MASK_ASSERT()
#endif
-// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+/* XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved */
#define SIGNAL_MASK_LOCK(task, flags) \
spin_lock_irqsave(&task->sighand->siglock, flags)
@@ -78,22 +78,4 @@
#define __cfs_fls __fls
#endif
-#define ll_proc_dointvec(table, write, filp, buffer, lenp, ppos) \
- proc_dointvec(table, write, buffer, lenp, ppos);
-
-#define ll_proc_dolongvec(table, write, filp, buffer, lenp, ppos) \
- proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
-#define ll_proc_dostring(table, write, filp, buffer, lenp, ppos) \
- proc_dostring(table, write, buffer, lenp, ppos);
-#define LL_PROC_PROTO(name) \
- name(ctl_table_t *table, int write, \
- void __user *buffer, size_t *lenp, loff_t *ppos)
-#define DECLARE_LL_PROC_PPOS_DECL
-
-/* helper for sysctl handlers */
-int proc_call_handler(void *data, int write,
- loff_t *ppos, void *buffer, size_t *lenp,
- int (*handler)(void *data, int write,
- loff_t pos, void *buffer, int len));
-
#endif /* _PORTALS_COMPAT_H */
diff --git a/drivers/staging/lustre/include/linux/libcfs/lucache.h b/drivers/staging/lustre/include/linux/libcfs/lucache.h
index 9668b397f0f6..5d6e1b9de206 100644
--- a/drivers/staging/lustre/include/linux/libcfs/lucache.h
+++ b/drivers/staging/lustre/include/linux/libcfs/lucache.h
@@ -37,7 +37,7 @@
#ifndef _LUCACHE_H
#define _LUCACHE_H
-#include <linux/libcfs/libcfs.h>
+#include "libcfs.h"
/** \defgroup ucache ucache
*
@@ -88,8 +88,8 @@ struct upcall_cache_entry {
atomic_t ue_refcount;
int ue_flags;
wait_queue_head_t ue_waitq;
- cfs_time_t ue_acquire_expire;
- cfs_time_t ue_expire;
+ unsigned long ue_acquire_expire;
+ unsigned long ue_expire;
union {
struct md_identity identity;
} u;
@@ -104,17 +104,17 @@ struct upcall_cache;
struct upcall_cache_ops {
void (*init_entry)(struct upcall_cache_entry *, void *args);
void (*free_entry)(struct upcall_cache *,
- struct upcall_cache_entry *);
+ struct upcall_cache_entry *);
int (*upcall_compare)(struct upcall_cache *,
- struct upcall_cache_entry *,
+ struct upcall_cache_entry *,
__u64 key, void *args);
int (*downcall_compare)(struct upcall_cache *,
- struct upcall_cache_entry *,
+ struct upcall_cache_entry *,
__u64 key, void *args);
int (*do_upcall)(struct upcall_cache *,
- struct upcall_cache_entry *);
+ struct upcall_cache_entry *);
int (*parse_downcall)(struct upcall_cache *,
- struct upcall_cache_entry *, void *);
+ struct upcall_cache_entry *, void *);
};
struct upcall_cache {
diff --git a/drivers/staging/lustre/include/linux/libcfs/params_tree.h b/drivers/staging/lustre/include/linux/libcfs/params_tree.h
deleted file mode 100644
index 78a2c4ed4d6c..000000000000
--- a/drivers/staging/lustre/include/linux/libcfs/params_tree.h
+++ /dev/null
@@ -1,164 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * API and structure definitions for params_tree.
- *
- * Author: LiuYing <emoly.liu@oracle.com>
- */
-#ifndef __PARAMS_TREE_H__
-#define __PARAMS_TREE_H__
-
-#include <linux/libcfs/libcfs.h>
-
-#undef LPROCFS
-#if defined(CONFIG_PROC_FS)
-# define LPROCFS
-#endif
-
-#ifdef LPROCFS
-typedef struct file cfs_param_file_t;
-typedef struct inode cfs_inode_t;
-typedef struct proc_inode cfs_proc_inode_t;
-typedef struct seq_file cfs_seq_file_t;
-typedef struct seq_operations cfs_seq_ops_t;
-typedef struct file_operations cfs_param_file_ops_t;
-typedef struct proc_dir_entry cfs_param_dentry_t;
-typedef struct poll_table_struct cfs_poll_table_t;
-#define CFS_PARAM_MODULE THIS_MODULE
-#define cfs_file_private(file) (file->private_data)
-#define cfs_dentry_data(dentry) (dentry->data)
-#define cfs_proc_inode_pde(proc_inode) (proc_inode->pde)
-#define cfs_proc_inode(proc_inode) (proc_inode->vfs_inode)
-#define cfs_seq_read_common seq_read
-#define cfs_seq_lseek_common seq_lseek
-#define cfs_seq_private(seq) (seq->private)
-#define cfs_seq_printf(seq, format, ...) seq_printf(seq, format, \
- ## __VA_ARGS__)
-#define cfs_seq_release(inode, file) seq_release(inode, file)
-#define cfs_seq_puts(seq, s) seq_puts(seq, s)
-#define cfs_seq_putc(seq, s) seq_putc(seq, s)
-#define cfs_seq_read(file, buf, count, ppos, rc) (rc = seq_read(file, buf, \
- count, ppos))
-#define cfs_seq_open(file, ops, rc) (rc = seq_open(file, ops))
-
-#else /* !LPROCFS */
-
-typedef struct cfs_params_file {
- void *param_private;
- loff_t param_pos;
- unsigned int param_flags;
-} cfs_param_file_t;
-
-typedef struct cfs_param_inode {
- void *param_private;
-} cfs_inode_t;
-
-typedef struct cfs_param_dentry {
- void *param_data;
-} cfs_param_dentry_t;
-
-typedef struct cfs_proc_inode {
- cfs_param_dentry_t *param_pde;
- cfs_inode_t param_inode;
-} cfs_proc_inode_t;
-
-struct cfs_seq_operations;
-typedef struct cfs_seq_file {
- char *buf;
- size_t size;
- size_t from;
- size_t count;
- loff_t index;
- loff_t version;
- struct mutex lock;
- struct cfs_seq_operations *op;
- void *private;
-} cfs_seq_file_t;
-
-typedef struct cfs_seq_operations {
- void *(*start) (cfs_seq_file_t *m, loff_t *pos);
- void (*stop) (cfs_seq_file_t *m, void *v);
- void *(*next) (cfs_seq_file_t *m, void *v, loff_t *pos);
- int (*show) (cfs_seq_file_t *m, void *v);
-} cfs_seq_ops_t;
-
-typedef void *cfs_poll_table_t;
-
-typedef struct cfs_param_file_ops {
- struct module *owner;
- int (*open) (cfs_inode_t *, struct file *);
- loff_t (*llseek)(struct file *, loff_t, int);
- int (*release) (cfs_inode_t *, cfs_param_file_t *);
- unsigned int (*poll) (struct file *, cfs_poll_table_t *);
- ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
- ssize_t (*read)(struct file *, char *, size_t, loff_t *);
-} cfs_param_file_ops_t;
-typedef cfs_param_file_ops_t *cfs_lproc_filep_t;
-
-static inline cfs_proc_inode_t *FAKE_PROC_I(const cfs_inode_t *inode)
-{
- return container_of(inode, cfs_proc_inode_t, param_inode);
-}
-
-#define CFS_PARAM_MODULE NULL
-#define cfs_file_private(file) (file->param_private)
-#define cfs_dentry_data(dentry) (dentry->param_data)
-#define cfs_proc_inode(proc_inode) (proc_inode->param_inode)
-#define cfs_proc_inode_pde(proc_inode) (proc_inode->param_pde)
-#define cfs_seq_read_common NULL
-#define cfs_seq_lseek_common NULL
-#define cfs_seq_private(seq) (seq->private)
-#define cfs_seq_read(file, buf, count, ppos, rc) do {} while(0)
-#define cfs_seq_open(file, ops, rc) \
-do { \
- cfs_seq_file_t *p = cfs_file_private(file); \
- if (!p) { \
- LIBCFS_ALLOC(p, sizeof(*p)); \
- if (!p) { \
- rc = -ENOMEM; \
- break; \
- } \
- cfs_file_private(file) = p; \
- } \
- memset(p, 0, sizeof(*p)); \
- p->op = ops; \
- rc = 0; \
-} while(0)
-
-#endif /* LPROCFS */
-
-/* XXX: params_tree APIs */
-
-#endif /* __PARAMS_TREE_H__ */
diff --git a/drivers/staging/lustre/include/linux/lnet/api-support.h b/drivers/staging/lustre/include/linux/lnet/api-support.h
index a8d91dbe6060..8f7fa28b517c 100644
--- a/drivers/staging/lustre/include/linux/lnet/api-support.h
+++ b/drivers/staging/lustre/include/linux/lnet/api-support.h
@@ -35,10 +35,10 @@
#ifndef __LNET_API_SUPPORT_H__
#define __LNET_API_SUPPORT_H__
-#include <linux/lnet/linux/api-support.h>
+#include "linux/api-support.h"
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/types.h>
-#include <linux/lnet/lnet.h>
+#include "../libcfs/libcfs.h"
+#include "types.h"
+#include "lnet.h"
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/api.h b/drivers/staging/lustre/include/linux/lnet/api.h
index e8642e33860d..cd865175703f 100644
--- a/drivers/staging/lustre/include/linux/lnet/api.h
+++ b/drivers/staging/lustre/include/linux/lnet/api.h
@@ -47,7 +47,7 @@
* @{
*/
-#include <linux/lnet/types.h>
+#include "../lnet/types.h"
/** \defgroup lnet_init_fini Initialization and cleanup
* The LNet must be properly initialized before any LNet calls can be made.
@@ -84,7 +84,6 @@ void LNetSnprintHandle(char *str, int str_len, lnet_handle_any_t handle);
/** @} lnet_addr */
-
/** \defgroup lnet_me Match entries
*
* A match entry (abbreviated as ME) describes a set of criteria to accept
@@ -171,7 +170,6 @@ int LNetEQFree(lnet_handle_eq_t eventq_in);
int LNetEQGet(lnet_handle_eq_t eventq_in,
lnet_event_t *event_out);
-
int LNetEQWait(lnet_handle_eq_t eventq_in,
lnet_event_t *event_out);
@@ -204,7 +202,6 @@ int LNetGet(lnet_nid_t self,
unsigned int offset_in);
/** @} lnet_data */
-
/** \defgroup lnet_misc Miscellaneous operations.
* Miscellaneous operations.
* @{ */
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 06ff463e4af6..5e8ea222b49f 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -41,12 +41,11 @@
#ifndef __LNET_LIB_LNET_H__
#define __LNET_LIB_LNET_H__
-#include <linux/lnet/linux/lib-lnet.h>
-
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/types.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-types.h>
+#include "linux/lib-lnet.h"
+#include "../libcfs/libcfs.h"
+#include "types.h"
+#include "lnet.h"
+#include "lib-types.h"
extern lnet_t the_lnet; /* THE network */
@@ -167,7 +166,6 @@ lnet_net_lock_current(void)
#define LNET_LOCK() lnet_net_lock(LNET_LOCK_EX)
#define LNET_UNLOCK() lnet_net_unlock(LNET_LOCK_EX)
-
#define lnet_ptl_lock(ptl) spin_lock(&(ptl)->ptl_lock)
#define lnet_ptl_unlock(ptl) spin_unlock(&(ptl)->ptl_lock)
#define lnet_eq_wait_lock() spin_lock(&the_lnet.ln_eq_wait_lock)
@@ -177,7 +175,6 @@ lnet_net_lock_current(void)
#define LNET_MUTEX_LOCK(m) mutex_lock(m)
#define LNET_MUTEX_UNLOCK(m) mutex_unlock(m)
-
#define MAX_PORTALS 64
/* these are only used by code with LNET_USE_LIB_FREELIST, but we still
@@ -215,7 +212,6 @@ lnet_freelist_free(lnet_freelist_t *fl, void *obj)
list_add(&o->fo_list, &fl->fl_list);
}
-
static inline lnet_eq_t *
lnet_eq_alloc(void)
{
@@ -572,7 +568,7 @@ lnet_peer_addref_locked(lnet_peer_t *lp)
lp->lp_refcount++;
}
-extern void lnet_destroy_peer_locked(lnet_peer_t *lp);
+void lnet_destroy_peer_locked(lnet_peer_t *lp);
static inline void
lnet_peer_decref_locked(lnet_peer_t *lp)
@@ -641,15 +637,14 @@ lnet_net2rnethash(__u32 net)
extern lnd_t the_lolnd;
+int lnet_cpt_of_nid_locked(lnet_nid_t nid);
+int lnet_cpt_of_nid(lnet_nid_t nid);
+lnet_ni_t *lnet_nid2ni_locked(lnet_nid_t nid, int cpt);
+lnet_ni_t *lnet_net2ni_locked(__u32 net, int cpt);
+lnet_ni_t *lnet_net2ni(__u32 net);
-extern int lnet_cpt_of_nid_locked(lnet_nid_t nid);
-extern int lnet_cpt_of_nid(lnet_nid_t nid);
-extern lnet_ni_t *lnet_nid2ni_locked(lnet_nid_t nid, int cpt);
-extern lnet_ni_t *lnet_net2ni_locked(__u32 net, int cpt);
-extern lnet_ni_t *lnet_net2ni(__u32 net);
-
-int lnet_notify(lnet_ni_t *ni, lnet_nid_t peer, int alive, cfs_time_t when);
-void lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when);
+int lnet_notify(lnet_ni_t *ni, lnet_nid_t peer, int alive, unsigned long when);
+void lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, unsigned long when);
int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway_nid,
unsigned int priority);
int lnet_check_routes(void);
@@ -715,7 +710,7 @@ lnet_ptl_unsetopt(lnet_portal_t *ptl, int opt)
/* match-table functions */
struct list_head *lnet_mt_match_head(struct lnet_match_table *mtable,
- lnet_process_id_t id, __u64 mbits);
+ lnet_process_id_t id, __u64 mbits);
struct lnet_match_table *lnet_mt_of_attach(unsigned int index,
lnet_process_id_t id, __u64 mbits,
__u64 ignore_bits,
@@ -735,7 +730,7 @@ void lnet_portals_destroy(void);
/* message functions */
int lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr,
- lnet_nid_t fromnid, void *private, int rdma_req);
+ lnet_nid_t fromnid, void *private, int rdma_req);
void lnet_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
unsigned int offset, unsigned int mlen, unsigned int rlen);
lnet_msg_t *lnet_create_reply_msg(lnet_ni_t *ni, lnet_msg_t *get_msg);
@@ -758,7 +753,7 @@ void lnet_counters_reset(void);
unsigned int lnet_iov_nob(unsigned int niov, struct iovec *iov);
int lnet_extract_iov(int dst_niov, struct iovec *dst,
- int src_niov, struct iovec *src,
+ int src_niov, struct iovec *src,
unsigned int offset, unsigned int len);
unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
@@ -767,19 +762,19 @@ int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
unsigned int offset, unsigned int len);
void lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov,
- unsigned int doffset,
+ unsigned int doffset,
unsigned int nsiov, struct iovec *siov,
unsigned int soffset, unsigned int nob);
void lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov,
- unsigned int iovoffset,
+ unsigned int iovoffset,
unsigned int nkiov, lnet_kiov_t *kiov,
unsigned int kiovoffset, unsigned int nob);
void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
- unsigned int kiovoffset,
+ unsigned int kiovoffset,
unsigned int niov, struct iovec *iov,
unsigned int iovoffset, unsigned int nob);
void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
- unsigned int doffset,
+ unsigned int doffset,
unsigned int nskiov, lnet_kiov_t *skiov,
unsigned int soffset, unsigned int nob);
@@ -810,6 +805,7 @@ lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
int slen, void *src, unsigned int soffset, unsigned int nob)
{
struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
+
lnet_copy_iov2iov(ndiov, diov, doffset,
1, &siov, soffset, nob);
}
@@ -819,6 +815,7 @@ lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov, unsigned int doffset
int slen, void *src, unsigned int soffset, unsigned int nob)
{
struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
+
lnet_copy_iov2kiov(ndiov, dkiov, doffset,
1, &siov, soffset, nob);
}
@@ -832,7 +829,7 @@ void lnet_register_lnd(lnd_t *lnd);
void lnet_unregister_lnd(lnd_t *lnd);
int lnet_set_ip_niaddr(lnet_ni_t *ni);
-int lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
+int lnet_connect(struct socket **sockp, lnet_nid_t peer_nid,
__u32 local_ip, __u32 peer_ip, int peer_port);
void lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
__u32 peer_ip, int port);
@@ -871,5 +868,4 @@ void lnet_peer_tables_destroy(void);
int lnet_peer_tables_create(void);
void lnet_debug_peer(lnet_nid_t nid);
-
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index a63654b660de..f16213f1771a 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -42,11 +42,11 @@
#ifndef __LNET_LIB_TYPES_H__
#define __LNET_LIB_TYPES_H__
-#include <linux/lnet/linux/lib-types.h>
+#include "linux/lib-types.h"
-#include <linux/libcfs/libcfs.h>
+#include "../libcfs/libcfs.h"
#include <linux/list.h>
-#include <linux/lnet/types.h>
+#include "types.h"
#define WIRE_ATTR __attribute__((packed))
@@ -156,7 +156,6 @@ typedef struct {
* "stub" reply using their current protocol */
#define LNET_PROTO_MAGIC 0x45726963 /* ! */
-
#define LNET_PROTO_TCP_VERSION_MAJOR 1
#define LNET_PROTO_TCP_VERSION_MINOR 0
@@ -225,7 +224,6 @@ typedef struct lnet_msg {
lnet_hdr_t msg_hdr;
} lnet_msg_t;
-
typedef struct lnet_libhandle {
struct list_head lh_hash_chain;
__u64 lh_cookie;
@@ -280,6 +278,7 @@ typedef struct lnet_libmd {
#define LNET_MD_FLAG_ZOMBIE (1 << 0)
#define LNET_MD_FLAG_AUTO_UNLINK (1 << 1)
+#define LNET_MD_FLAG_ABORTED (1 << 2)
#ifdef LNET_USE_LIB_FREELIST
typedef struct {
@@ -363,10 +362,10 @@ typedef struct lnet_lnd {
void (*lnd_notify)(struct lnet_ni *ni, lnet_nid_t peer, int alive);
/* query of peer aliveness */
- void (*lnd_query)(struct lnet_ni *ni, lnet_nid_t peer, cfs_time_t *when);
+ void (*lnd_query)(struct lnet_ni *ni, lnet_nid_t peer, unsigned long *when);
/* accept a new connection */
- int (*lnd_accept)(struct lnet_ni *ni, socket_t *sock);
+ int (*lnd_accept)(struct lnet_ni *ni, struct socket *sock);
} lnd_t;
@@ -458,11 +457,11 @@ typedef struct lnet_peer {
unsigned int lp_ping_notsent; /* SEND event outstanding from ping */
int lp_alive_count; /* # times router went dead<->alive */
long lp_txqnob; /* bytes queued for sending */
- cfs_time_t lp_timestamp; /* time of last aliveness news */
- cfs_time_t lp_ping_timestamp; /* time of last ping attempt */
- cfs_time_t lp_ping_deadline; /* != 0 if ping reply expected */
- cfs_time_t lp_last_alive; /* when I was last alive */
- cfs_time_t lp_last_query; /* when lp_ni was queried last time */
+ unsigned long lp_timestamp; /* time of last aliveness news */
+ unsigned long lp_ping_timestamp; /* time of last ping attempt */
+ unsigned long lp_ping_deadline; /* != 0 if ping reply expected */
+ unsigned long lp_last_alive; /* when I was last alive */
+ unsigned long lp_last_query; /* when lp_ni was queried last time */
lnet_ni_t *lp_ni; /* interface peer is on */
lnet_nid_t lp_nid; /* peer's NID */
int lp_refcount; /* # refs */
diff --git a/drivers/staging/lustre/include/linux/lnet/linux/api-support.h b/drivers/staging/lustre/include/linux/lnet/linux/api-support.h
index ca78a0a4e908..e237ad6af422 100644
--- a/drivers/staging/lustre/include/linux/lnet/linux/api-support.h
+++ b/drivers/staging/lustre/include/linux/lnet/linux/api-support.h
@@ -39,5 +39,4 @@
#error Do not #include this file directly. #include <lnet /api-support.h> instead
#endif
-
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h
index d2c0a70f1f7e..0f8f04d1ecff 100644
--- a/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h
@@ -42,10 +42,10 @@
# include <asm/page.h>
# include <linux/string.h>
# include <asm/io.h>
-# include <linux/libcfs/libcfs.h>
+#include "../../libcfs/libcfs.h"
static inline __u64
-lnet_page2phys (struct page *p)
+lnet_page2phys(struct page *p)
{
/* compiler optimizer will elide unused branches */
@@ -66,7 +66,6 @@ lnet_page2phys (struct page *p)
}
}
-
#define LNET_ROUTER
#endif /* __LNET_LINUX_LIB_LNET_H__ */
diff --git a/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h b/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h
index 1bde44ebb911..2dee1b97fb88 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h
+++ b/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h
@@ -37,7 +37,6 @@
#if defined(CONFIG_SYSCTL)
-
#define CTL_KRANAL 201
#define CTL_O2IBLND 205
#define CTL_PTLLND 206
@@ -45,7 +44,6 @@
#define CTL_SOCKLND 208
#define CTL_GNILND 210
-
#endif
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lnet.h b/drivers/staging/lustre/include/linux/lnet/lnet.h
index c532b15d7643..75c0ab9193cc 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lnet.h
@@ -40,10 +40,10 @@
*
* User application interface file
*/
-#include <linux/lnet/linux/lnet.h>
+#include "linux/lnet.h"
-#include <linux/lnet/types.h>
-#include <linux/lnet/api.h>
+#include "types.h"
+#include "api.h"
#define LNET_NIDSTR_COUNT 1024 /* # of nidstrings */
#define LNET_NIDSTR_SIZE 32 /* size of each one (see below for usage) */
diff --git a/drivers/staging/lustre/include/linux/lnet/lnetctl.h b/drivers/staging/lustre/include/linux/lnet/lnetctl.h
index b22daa234255..98181d389396 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnetctl.h
+++ b/drivers/staging/lustre/include/linux/lnet/lnetctl.h
@@ -19,8 +19,8 @@
#ifndef _PTLCTL_H_
#define _PTLCTL_H_
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/types.h>
+#include "../libcfs/libcfs.h"
+#include "types.h"
#define LNET_DEV_ID 0
#define LNET_DEV_PATH "/dev/lnet"
@@ -43,10 +43,10 @@ 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_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);
@@ -56,11 +56,11 @@ 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_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);
diff --git a/drivers/staging/lustre/include/linux/lnet/lnetst.h b/drivers/staging/lustre/include/linux/lnet/lnetst.h
index 87fe9ac76a6c..885f708d4031 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnetst.h
+++ b/drivers/staging/lustre/include/linux/lnet/lnetst.h
@@ -41,9 +41,9 @@
#ifndef __LNET_ST_H__
#define __LNET_ST_H__
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-types.h>
+#include "../libcfs/libcfs.h"
+#include "lnet.h"
+#include "lib-types.h"
#define LST_FEAT_NONE (0)
#define LST_FEAT_BULK_LEN (1 << 0) /* enable variable page size */
diff --git a/drivers/staging/lustre/include/linux/lnet/ptllnd.h b/drivers/staging/lustre/include/linux/lnet/ptllnd.h
index 313442a7ed3e..c91d65329995 100644
--- a/drivers/staging/lustre/include/linux/lnet/ptllnd.h
+++ b/drivers/staging/lustre/include/linux/lnet/ptllnd.h
@@ -46,11 +46,10 @@
*/
#define LUSTRE_PORTALS_UNLINK_SEMANTICS
-
#ifdef _USING_LUSTRE_PORTALS_
/* NIDs are 64-bits on Lustre Portals */
-#define FMT_NID LPU64
+#define FMT_NID "%llu"
#define FMT_PID "%d"
/* When using Lustre Portals Lustre completion semantics are imlicit*/
diff --git a/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h b/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h
index 0d3ec5be0a00..808f37b64a4f 100644
--- a/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h
+++ b/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h
@@ -54,7 +54,6 @@
* enough to avoid RDMA for anything sent while control is not in liblustre */
#define PTLLND_MAX_ULND_MSG_SIZE 512
-
/************************************************************************
* Portals LND Wire message format.
* These are sent in sender's byte order (i.e. receiver flips).
@@ -103,7 +102,7 @@ typedef struct {
} kptl_msg_t;
/* kptl_msg_t::ptlm_credits is only a __u8 */
-#define PTLLND_MSG_MAX_CREDITS ((typeof(((kptl_msg_t*) 0)->ptlm_credits)) - 1)
+#define PTLLND_MSG_MAX_CREDITS ((typeof(((kptl_msg_t *)0)->ptlm_credits)) - 1)
#define PTLLND_MSG_MAGIC LNET_PROTO_PTL_MAGIC
#define PTLLND_MSG_VERSION 0x04
diff --git a/drivers/staging/lustre/include/linux/lnet/socklnd.h b/drivers/staging/lustre/include/linux/lnet/socklnd.h
index bacc74933a39..389038b122c5 100644
--- a/drivers/staging/lustre/include/linux/lnet/socklnd.h
+++ b/drivers/staging/lustre/include/linux/lnet/socklnd.h
@@ -38,8 +38,8 @@
#ifndef __LNET_LNET_SOCKLND_H__
#define __LNET_LNET_SOCKLND_H__
-#include <linux/lnet/types.h>
-#include <linux/lnet/lib-types.h>
+#include "types.h"
+#include "lib-types.h"
#define SOCKLND_CONN_NONE (-1)
#define SOCKLND_CONN_ANY 0
diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h
index 2add7976b3b2..68d8139a2b11 100644
--- a/drivers/staging/lustre/include/linux/lnet/types.h
+++ b/drivers/staging/lustre/include/linux/lnet/types.h
@@ -40,7 +40,7 @@
/** \addtogroup lnet
* @{ */
-#include <linux/libcfs/libcfs.h>
+#include "../libcfs/libcfs.h"
/** \addtogroup lnet_addr
* @{ */
@@ -110,7 +110,7 @@ static inline void LNetInvalidateHandle(lnet_handle_any_t *h)
*
* \return 1 if handles are equal, 0 if otherwise.
*/
-static inline int LNetHandleIsEqual (lnet_handle_any_t h1, lnet_handle_any_t h2)
+static inline int LNetHandleIsEqual(lnet_handle_any_t h1, lnet_handle_any_t h2)
{
return h1.cookie == h2.cookie;
}
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile b/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
index 71b7d8418357..e0a7aa72b7d5 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
@@ -1,5 +1,2 @@
obj-$(CONFIG_LNET_XPRT_IB) += ko2iblnd.o
ko2iblnd-y := o2iblnd.o o2iblnd_cb.o o2iblnd_modparams.o
-
-
-ccflags-y := -I$(src)/../../include
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 892c41991f83..ab1643943496 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -959,7 +959,7 @@ kiblnd_close_stale_conns_locked (kib_peer_t *peer,
continue;
CDEBUG(D_NET, "Closing stale conn -> %s version: %x, "
- "incarnation:"LPX64"(%x, "LPX64")\n",
+ "incarnation:%#llx(%x, %#llx)\n",
libcfs_nid2str(peer->ibp_nid),
conn->ibc_version, conn->ibc_incarnation,
version, incarnation);
@@ -1074,10 +1074,10 @@ kiblnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg)
}
void
-kiblnd_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
+kiblnd_query (lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when)
{
- cfs_time_t last_alive = 0;
- cfs_time_t now = cfs_time_current();
+ unsigned long last_alive = 0;
+ unsigned long now = cfs_time_current();
rwlock_t *glock = &kiblnd_data.kib_global_lock;
kib_peer_t *peer;
unsigned long flags;
@@ -1202,7 +1202,7 @@ kiblnd_map_rx_descs(kib_conn_t *conn)
rx->rx_msgaddr));
KIBLND_UNMAP_ADDR_SET(rx, rx_msgunmap, rx->rx_msgaddr);
- CDEBUG(D_NET,"rx %d: %p "LPX64"("LPX64")\n",
+ CDEBUG(D_NET,"rx %d: %p %#llx(%#llx)\n",
i, rx->rx_msg, rx->rx_msgaddr,
lnet_page2phys(pg) + pg_off);
@@ -1509,7 +1509,7 @@ kiblnd_init_fmr_poolset(kib_fmr_poolset_t *fps, int cpt, kib_net_t *net,
}
static int
-kiblnd_fmr_pool_is_idle(kib_fmr_pool_t *fpo, cfs_time_t now)
+kiblnd_fmr_pool_is_idle(kib_fmr_pool_t *fpo, unsigned long now)
{
if (fpo->fpo_map_count != 0) /* still in use */
return 0;
@@ -1524,7 +1524,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
LIST_HEAD (zombies);
kib_fmr_pool_t *fpo = fmr->fmr_pool;
kib_fmr_poolset_t *fps = fpo->fpo_owner;
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
kib_fmr_pool_t *tmp;
int rc;
@@ -1606,7 +1606,7 @@ kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages, int npages,
}
- if (cfs_time_before(cfs_time_current(), fps->fps_next_retry)) {
+ if (time_before(cfs_time_current(), fps->fps_next_retry)) {
/* someone failed recently */
spin_unlock(&fps->fps_lock);
return -EAGAIN;
@@ -1731,7 +1731,7 @@ kiblnd_init_poolset(kib_poolset_t *ps, int cpt,
}
static int
-kiblnd_pool_is_idle(kib_pool_t *pool, cfs_time_t now)
+kiblnd_pool_is_idle(kib_pool_t *pool, unsigned long now)
{
if (pool->po_allocated != 0) /* still in use */
return 0;
@@ -1746,7 +1746,7 @@ kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node)
LIST_HEAD (zombies);
kib_poolset_t *ps = pool->po_owner;
kib_pool_t *tmp;
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
spin_lock(&ps->ps_lock);
@@ -1808,7 +1808,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps)
goto again;
}
- if (cfs_time_before(cfs_time_current(), ps->ps_next_retry)) {
+ if (time_before(cfs_time_current(), ps->ps_next_retry)) {
/* someone failed recently */
spin_unlock(&ps->ps_lock);
return NULL;
@@ -2336,7 +2336,7 @@ kiblnd_hdev_get_attr(kib_hca_dev_t *hdev)
return 0;
}
- CERROR("Invalid mr size: "LPX64"\n", hdev->ibh_mr_size);
+ CERROR("Invalid mr size: %#llx\n", hdev->ibh_mr_size);
return -EINVAL;
}
@@ -2418,8 +2418,8 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev)
if (hdev->ibh_mr_shift < 32 || hdev->ibh_nmrs > 1024) {
/* it's 4T..., assume we will re-code at that time */
- CERROR("Can't support memory size: x"LPX64
- " with MR size: x"LPX64"\n", mm_size, mr_size);
+ CERROR("Can't support memory size: x%#llx with MR size: x%#llx\n",
+ mm_size, mr_size);
return -EINVAL;
}
@@ -2430,8 +2430,6 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev)
return -ENOMEM;
}
- memset(hdev->ibh_mrs, 0, sizeof(*hdev->ibh_mrs) * hdev->ibh_nmrs);
-
for (i = 0; i < hdev->ibh_nmrs; i++) {
struct ib_phys_buf ipb;
__u64 iova;
@@ -2442,8 +2440,7 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev)
mr = ib_reg_phys_mr(hdev->ibh_pd, &ipb, 1, acflags, &iova);
if (IS_ERR(mr)) {
- CERROR("Failed ib_reg_phys_mr addr "LPX64
- " size "LPX64" : %ld\n",
+ CERROR("Failed ib_reg_phys_mr addr %#llx size %#llx : %ld\n",
ipb.addr, ipb.size, PTR_ERR(mr));
kiblnd_hdev_cleanup_mrs(hdev);
return PTR_ERR(mr);
@@ -2456,8 +2453,7 @@ kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev)
out:
if (hdev->ibh_mr_size != ~0ULL || hdev->ibh_nmrs != 1)
- LCONSOLE_INFO("Register global MR array, MR size: "
- LPX64", array size: %d\n",
+ LCONSOLE_INFO("Register global MR array, MR size: %#llx, array size: %d\n",
hdev->ibh_mr_size, hdev->ibh_nmrs);
return 0;
}
@@ -2704,7 +2700,6 @@ kiblnd_create_dev(char *ifname)
if (dev == NULL)
return NULL;
- memset(dev, 0, sizeof(*dev));
netdev = dev_get_by_name(&init_net, ifname);
if (netdev == NULL) {
dev->ibd_can_failover = 0;
@@ -3088,8 +3083,6 @@ kiblnd_startup (lnet_ni_t *ni)
if (net == NULL)
goto failed;
- memset(net, 0, sizeof(*net));
-
do_gettimeofday(&tv);
net->ibn_incarnation = (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index ce05d558b223..4306d9804a10 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -62,10 +62,10 @@
#define DEBUG_SUBSYSTEM S_LND
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-lnet.h>
-#include <linux/lnet/lnet-sysctl.h>
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "../../../include/linux/lnet/lnet.h"
+#include "../../../include/linux/lnet/lib-lnet.h"
+#include "../../../include/linux/lnet/lnet-sysctl.h"
#include <rdma/rdma_cm.h>
#include <rdma/ib_cm.h>
@@ -195,7 +195,7 @@ typedef struct
char ibd_ifname[KIB_IFNAME_SIZE];
int ibd_nnets; /* # nets extant */
- cfs_time_t ibd_next_failover;
+ unsigned long ibd_next_failover;
int ibd_failed_failover; /* # failover failures */
unsigned int ibd_failover; /* failover in progress */
unsigned int ibd_can_failover; /* IPoIB interface is a bonding master */
@@ -261,7 +261,7 @@ typedef struct kib_poolset
char ps_name[IBLND_POOL_NAME_LEN]; /* pool set name */
struct list_head ps_pool_list; /* list of pools */
struct list_head ps_failed_pool_list; /* failed pool list */
- cfs_time_t ps_next_retry; /* time stamp for retry if failed to allocate */
+ unsigned long ps_next_retry; /* time stamp for retry if failed to allocate */
int ps_increasing; /* is allocating new pool */
int ps_pool_size; /* new pool size */
int ps_cpt; /* CPT id */
@@ -277,7 +277,7 @@ typedef struct kib_pool
struct list_head po_list; /* chain on pool list */
struct list_head po_free_list; /* pre-allocated node */
kib_poolset_t *po_owner; /* pool_set of this pool */
- cfs_time_t po_deadline; /* deadline of this pool */
+ unsigned long po_deadline; /* deadline of this pool */
int po_allocated; /* # of elements in use */
int po_failed; /* pool is created on failed HCA */
int po_size; /* # of pre-allocated elements */
@@ -317,7 +317,7 @@ typedef struct
/* is allocating new pool */
int fps_increasing;
/* time stamp for retry if failed to allocate */
- cfs_time_t fps_next_retry;
+ unsigned long fps_next_retry;
} kib_fmr_poolset_t;
typedef struct
@@ -326,7 +326,7 @@ typedef struct
struct kib_hca_dev *fpo_hdev; /* device for this pool */
kib_fmr_poolset_t *fpo_owner; /* owner of this pool */
struct ib_fmr_pool *fpo_fmr_pool; /* IB FMR pool */
- cfs_time_t fpo_deadline; /* deadline of this pool */
+ unsigned long fpo_deadline; /* deadline of this pool */
int fpo_failed; /* fmr pool is failed */
int fpo_map_count; /* # of mapped FMR */
} kib_fmr_pool_t;
@@ -642,7 +642,7 @@ typedef struct kib_peer
int ibp_connecting; /* current active connection attempts */
int ibp_accepting; /* current passive connection attempts */
int ibp_error; /* errno on closing this peer */
- cfs_time_t ibp_last_alive; /* when (in jiffies) I was last alive */
+ unsigned long ibp_last_alive; /* when (in jiffies) I was last alive */
} kib_peer_t;
extern kib_data_t kiblnd_data;
@@ -990,7 +990,7 @@ void kiblnd_pmr_pool_unmap(kib_phys_mr_t *pmr);
int kiblnd_startup (lnet_ni_t *ni);
void kiblnd_shutdown (lnet_ni_t *ni);
int kiblnd_ctl (lnet_ni_t *ni, unsigned int cmd, void *arg);
-void kiblnd_query (struct lnet_ni *ni, lnet_nid_t nid, cfs_time_t *when);
+void kiblnd_query (struct lnet_ni *ni, lnet_nid_t nid, unsigned long *when);
int kiblnd_tunables_init(void);
void kiblnd_tunables_fini(void);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index dfd16e7ca8a2..306d72876432 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -247,7 +247,7 @@ kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie)
if (tx == NULL) {
spin_unlock(&conn->ibc_lock);
- CWARN("Unmatched completion type %x cookie "LPX64" from %s\n",
+ CWARN("Unmatched completion type %x cookie %#llx from %s\n",
txtype, cookie, libcfs_nid2str(conn->ibc_peer->ibp_nid));
kiblnd_close_conn(conn, -EPROTO);
return;
@@ -1005,8 +1005,7 @@ kiblnd_tx_complete (kib_tx_t *tx, int status)
if (failed) {
if (conn->ibc_state == IBLND_CONN_ESTABLISHED)
- CNETERR("Tx -> %s cookie "LPX64
- " sending %d waiting %d: failed %d\n",
+ CNETERR("Tx -> %s cookie %#llx sending %d waiting %d: failed %d\n",
libcfs_nid2str(conn->ibc_peer->ibp_nid),
tx->tx_cookie, tx->tx_sending, tx->tx_waiting,
status);
@@ -1830,7 +1829,7 @@ static void
kiblnd_peer_notify (kib_peer_t *peer)
{
int error = 0;
- cfs_time_t last_alive = 0;
+ unsigned long last_alive = 0;
unsigned long flags;
read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
@@ -3465,8 +3464,8 @@ kiblnd_failover_thread(void *arg)
list_for_each_entry(dev, &kiblnd_data.kib_failed_devs,
ibd_fail_list) {
- if (cfs_time_before(cfs_time_current(),
- dev->ibd_next_failover))
+ if (time_before(cfs_time_current(),
+ dev->ibd_next_failover))
continue;
do_failover = 1;
break;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/Makefile b/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
index 6494b2bada05..f3fb8778c3ad 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
@@ -1,7 +1,3 @@
obj-$(CONFIG_LNET) += ksocklnd.o
ksocklnd-y := socklnd.o socklnd_cb.o socklnd_proto.o socklnd_modparams.o socklnd_lib-linux.o
-
-
-
-ccflags-y := -I$(src)/../../include
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index 775dcd29c200..038854e8302f 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -43,10 +43,10 @@
#include "socklnd.h"
-lnd_t the_ksocklnd;
-ksock_nal_data_t ksocknal_data;
+static lnd_t the_ksocklnd;
+ksock_nal_data_t ksocknal_data;
-ksock_interface_t *
+static ksock_interface_t *
ksocknal_ip2iface(lnet_ni_t *ni, __u32 ip)
{
ksock_net_t *net = ni->ni_data;
@@ -64,7 +64,7 @@ ksocknal_ip2iface(lnet_ni_t *ni, __u32 ip)
return NULL;
}
-ksock_route_t *
+static ksock_route_t *
ksocknal_create_route (__u32 ipaddr, int port)
{
ksock_route_t *route;
@@ -99,7 +99,7 @@ ksocknal_destroy_route (ksock_route_t *route)
LIBCFS_FREE (route, sizeof (*route));
}
-int
+static int
ksocknal_create_peer (ksock_peer_t **peerp, lnet_ni_t *ni, lnet_process_id_t id)
{
ksock_net_t *net = ni->ni_data;
@@ -113,8 +113,6 @@ ksocknal_create_peer (ksock_peer_t **peerp, lnet_ni_t *ni, lnet_process_id_t id)
if (peer == NULL)
return -ENOMEM;
- memset (peer, 0, sizeof (*peer)); /* NULL pointers/clear flags etc */
-
peer->ksnp_ni = ni;
peer->ksnp_id = id;
atomic_set (&peer->ksnp_refcount, 1); /* 1 ref for caller */
@@ -216,7 +214,7 @@ ksocknal_find_peer (lnet_ni_t *ni, lnet_process_id_t id)
return peer;
}
-void
+static void
ksocknal_unlink_peer_locked (ksock_peer_t *peer)
{
int i;
@@ -246,7 +244,7 @@ ksocknal_unlink_peer_locked (ksock_peer_t *peer)
ksocknal_peer_decref(peer);
}
-int
+static int
ksocknal_get_peer_info (lnet_ni_t *ni, int index,
lnet_process_id_t *id, __u32 *myip, __u32 *peer_ip,
int *port, int *conn_count, int *share_count)
@@ -321,7 +319,7 @@ ksocknal_get_peer_info (lnet_ni_t *ni, int index,
return rc;
}
-void
+static void
ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn)
{
ksock_peer_t *peer = route->ksnr_peer;
@@ -366,7 +364,7 @@ ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn)
route->ksnr_retry_interval = 0;
}
-void
+static void
ksocknal_add_route_locked (ksock_peer_t *peer, ksock_route_t *route)
{
struct list_head *tmp;
@@ -407,7 +405,7 @@ ksocknal_add_route_locked (ksock_peer_t *peer, ksock_route_t *route)
}
}
-void
+static void
ksocknal_del_route_locked (ksock_route_t *route)
{
ksock_peer_t *peer = route->ksnr_peer;
@@ -509,7 +507,7 @@ ksocknal_add_peer (lnet_ni_t *ni, lnet_process_id_t id, __u32 ipaddr, int port)
return 0;
}
-void
+static void
ksocknal_del_peer_locked (ksock_peer_t *peer, __u32 ip)
{
ksock_conn_t *conn;
@@ -564,7 +562,7 @@ ksocknal_del_peer_locked (ksock_peer_t *peer, __u32 ip)
/* NB peer unlinks itself when last conn/route is removed */
}
-int
+static int
ksocknal_del_peer (lnet_ni_t *ni, lnet_process_id_t id, __u32 ip)
{
LIST_HEAD (zombies);
@@ -623,7 +621,7 @@ ksocknal_del_peer (lnet_ni_t *ni, lnet_process_id_t id, __u32 ip)
return rc;
}
-ksock_conn_t *
+static ksock_conn_t *
ksocknal_get_conn_by_idx (lnet_ni_t *ni, int index)
{
ksock_peer_t *peer;
@@ -660,7 +658,7 @@ ksocknal_get_conn_by_idx (lnet_ni_t *ni, int index)
return NULL;
}
-ksock_sched_t *
+static ksock_sched_t *
ksocknal_choose_scheduler_locked(unsigned int cpt)
{
struct ksock_sched_info *info = ksocknal_data.ksnd_sched_info[cpt];
@@ -683,7 +681,7 @@ ksocknal_choose_scheduler_locked(unsigned int cpt)
return sched;
}
-int
+static int
ksocknal_local_ipvec (lnet_ni_t *ni, __u32 *ipaddrs)
{
ksock_net_t *net = ni->ni_data;
@@ -711,7 +709,7 @@ ksocknal_local_ipvec (lnet_ni_t *ni, __u32 *ipaddrs)
return nip;
}
-int
+static int
ksocknal_match_peerip (ksock_interface_t *iface, __u32 *ips, int nips)
{
int best_netmatch = 0;
@@ -743,7 +741,7 @@ ksocknal_match_peerip (ksock_interface_t *iface, __u32 *ips, int nips)
return best;
}
-int
+static int
ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips)
{
rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock;
@@ -845,7 +843,7 @@ ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips)
return n_ips;
}
-void
+static void
ksocknal_create_routes(ksock_peer_t *peer, int port,
__u32 *peer_ipaddrs, int npeer_ipaddrs)
{
@@ -964,7 +962,7 @@ ksocknal_create_routes(ksock_peer_t *peer, int port,
}
int
-ksocknal_accept (lnet_ni_t *ni, socket_t *sock)
+ksocknal_accept (lnet_ni_t *ni, struct socket *sock)
{
ksock_connreq_t *cr;
int rc;
@@ -995,7 +993,7 @@ ksocknal_accept (lnet_ni_t *ni, socket_t *sock)
return 0;
}
-int
+static int
ksocknal_connecting (ksock_peer_t *peer, __u32 ipaddr)
{
ksock_route_t *route;
@@ -1010,7 +1008,7 @@ ksocknal_connecting (ksock_peer_t *peer, __u32 ipaddr)
int
ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
- socket_t *sock, int type)
+ struct socket *sock, int type)
{
rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock;
LIST_HEAD (zombies);
@@ -1040,8 +1038,6 @@ ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
goto failed_0;
}
- memset (conn, 0, sizeof (*conn));
-
conn->ksnc_peer = NULL;
conn->ksnc_route = NULL;
conn->ksnc_sock = sock;
@@ -1262,7 +1258,7 @@ ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
conn->ksnc_tx_last_post = cfs_time_current();
/* Set the deadline for the outgoing HELLO to drain */
- conn->ksnc_tx_bufnob = cfs_sock_wmem_queued(sock);
+ conn->ksnc_tx_bufnob = sock->sk->sk_wmem_queued;
conn->ksnc_tx_deadline = cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
mb(); /* order with adding to peer's conn list */
@@ -1293,7 +1289,7 @@ ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
*/
CDEBUG(D_NET, "New conn %s p %d.x %pI4h -> %pI4h/%d"
- " incarnation:"LPD64" sched[%d:%d]\n",
+ " incarnation:%lld sched[%d:%d]\n",
libcfs_id2str(peerid), conn->ksnc_proto->pro_version,
&conn->ksnc_myipaddr, &conn->ksnc_ipaddr,
conn->ksnc_port, incarnation, cpt,
@@ -1487,7 +1483,7 @@ void
ksocknal_peer_failed (ksock_peer_t *peer)
{
int notify = 0;
- cfs_time_t last_alive = 0;
+ unsigned long last_alive = 0;
/* There has been a connection failure or comms error; but I'll only
* tell LNET I think the peer is dead if it's to another kernel and
@@ -1624,7 +1620,7 @@ ksocknal_queue_zombie_conn (ksock_conn_t *conn)
void
ksocknal_destroy_conn (ksock_conn_t *conn)
{
- cfs_time_t last_rcv;
+ unsigned long last_rcv;
/* Final coup-de-grace of the reaper */
CDEBUG (D_NET, "connection %p\n", conn);
@@ -1793,11 +1789,11 @@ ksocknal_notify (lnet_ni_t *ni, lnet_nid_t gw_nid, int alive)
}
void
-ksocknal_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
+ksocknal_query (lnet_ni_t *ni, lnet_nid_t nid, unsigned long *when)
{
int connect = 1;
- cfs_time_t last_alive = 0;
- cfs_time_t now = cfs_time_current();
+ unsigned long last_alive = 0;
+ unsigned long now = cfs_time_current();
ksock_peer_t *peer = NULL;
rwlock_t *glock = &ksocknal_data.ksnd_global_lock;
lnet_process_id_t id = {.nid = nid, .pid = LUSTRE_SRV_LNET_PID};
@@ -1812,7 +1808,7 @@ ksocknal_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
list_for_each (tmp, &peer->ksnp_conns) {
conn = list_entry(tmp, ksock_conn_t, ksnc_list);
- bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+ bufnob = conn->ksnc_sock->sk->sk_wmem_queued;
if (bufnob < conn->ksnc_tx_bufnob) {
/* something got ACKed */
@@ -1853,7 +1849,7 @@ ksocknal_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
return;
}
-void
+static void
ksocknal_push_peer (ksock_peer_t *peer)
{
int index;
@@ -1886,7 +1882,7 @@ ksocknal_push_peer (ksock_peer_t *peer)
}
}
-int
+static int
ksocknal_push (lnet_ni_t *ni, lnet_process_id_t id)
{
ksock_peer_t *peer;
@@ -1935,7 +1931,7 @@ ksocknal_push (lnet_ni_t *ni, lnet_process_id_t id)
return rc;
}
-int
+static int
ksocknal_add_interface(lnet_ni_t *ni, __u32 ipaddress, __u32 netmask)
{
ksock_net_t *net = ni->ni_data;
@@ -1997,7 +1993,7 @@ ksocknal_add_interface(lnet_ni_t *ni, __u32 ipaddress, __u32 netmask)
return rc;
}
-void
+static void
ksocknal_peer_del_interface_locked(ksock_peer_t *peer, __u32 ipaddr)
{
struct list_head *tmp;
@@ -2038,7 +2034,7 @@ ksocknal_peer_del_interface_locked(ksock_peer_t *peer, __u32 ipaddr)
}
}
-int
+static int
ksocknal_del_interface(lnet_ni_t *ni, __u32 ipaddress)
{
ksock_net_t *net = ni->ni_data;
@@ -2213,7 +2209,7 @@ ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg)
/* not reached */
}
-void
+static void
ksocknal_free_buffers (void)
{
LASSERT (atomic_read(&ksocknal_data.ksnd_nactive_txs) == 0);
@@ -2256,7 +2252,7 @@ ksocknal_free_buffers (void)
}
}
-void
+static void
ksocknal_base_shutdown(void)
{
struct ksock_sched_info *info;
@@ -2349,7 +2345,7 @@ ksocknal_base_shutdown(void)
module_put(THIS_MODULE);
}
-__u64
+static __u64
ksocknal_new_incarnation (void)
{
struct timeval tv;
@@ -2364,7 +2360,7 @@ ksocknal_new_incarnation (void)
return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
}
-int
+static int
ksocknal_base_startup(void)
{
struct ksock_sched_info *info;
@@ -2449,7 +2445,7 @@ ksocknal_base_startup(void)
ksocknal_data.ksnd_connd_starting = 0;
ksocknal_data.ksnd_connd_failed_stamp = 0;
- ksocknal_data.ksnd_connd_starting_stamp = cfs_time_current_sec();
+ ksocknal_data.ksnd_connd_starting_stamp = get_seconds();
/* must have at least 2 connds to remain responsive to accepts while
* connecting */
if (*ksocknal_tunables.ksnd_nconnds < SOCKNAL_CONND_RESV + 1)
@@ -2496,7 +2492,7 @@ ksocknal_base_startup(void)
return -ENETDOWN;
}
-void
+static void
ksocknal_debug_peerhash (lnet_ni_t *ni)
{
ksock_peer_t *peer = NULL;
@@ -2521,7 +2517,7 @@ ksocknal_debug_peerhash (lnet_ni_t *ni)
ksock_conn_t *conn;
CWARN ("Active peer on shutdown: %s, ref %d, scnt %d, "
- "closing %d, accepting %d, err %d, zcookie "LPU64", "
+ "closing %d, accepting %d, err %d, zcookie %llu, "
"txq %d, zc_req %d\n", libcfs_id2str(peer->ksnp_id),
atomic_read(&peer->ksnp_refcount),
peer->ksnp_sharecount, peer->ksnp_closing,
@@ -2603,7 +2599,7 @@ ksocknal_shutdown (lnet_ni_t *ni)
ksocknal_base_shutdown();
}
-int
+static int
ksocknal_enumerate_interfaces(ksock_net_t *net)
{
char **names;
@@ -2660,7 +2656,7 @@ ksocknal_enumerate_interfaces(ksock_net_t *net)
return j;
}
-int
+static int
ksocknal_search_new_ipif(ksock_net_t *net)
{
int new_ipif = 0;
@@ -2702,7 +2698,7 @@ ksocknal_search_new_ipif(ksock_net_t *net)
return new_ipif;
}
-int
+static int
ksocknal_start_schedulers(struct ksock_sched_info *info)
{
int nthrs;
@@ -2748,7 +2744,7 @@ ksocknal_start_schedulers(struct ksock_sched_info *info)
return rc;
}
-int
+static int
ksocknal_net_start_threads(ksock_net_t *net, __u32 *cpts, int ncpts)
{
int newif = ksocknal_search_new_ipif(net);
@@ -2860,13 +2856,13 @@ ksocknal_startup (lnet_ni_t *ni)
}
-void __exit
+static void __exit
ksocknal_module_fini (void)
{
lnet_unregister_lnd(&the_ksocklnd);
}
-int __init
+static int __init
ksocknal_module_init (void)
{
int rc;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index 109a23932471..f7cce9d9b7ba 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -30,11 +30,11 @@
#include "socklnd_lib-linux.h"
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-lnet.h>
-#include <linux/lnet/socklnd.h>
-#include <linux/lnet/lnet-sysctl.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 "../../../include/linux/lnet/lnet-sysctl.h"
#define SOCKNAL_PEER_HASH_SIZE 101 /* # peer lists */
#define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */
@@ -164,7 +164,7 @@ typedef struct
struct list_head ksnd_zombie_conns; /* conns to free: reaper_lock */
struct list_head ksnd_enomem_conns; /* conns to retry: reaper_lock*/
wait_queue_head_t ksnd_reaper_waitq; /* reaper sleeps here */
- cfs_time_t ksnd_reaper_waketime;/* when reaper will wake */
+ unsigned long ksnd_reaper_waketime;/* when reaper will wake */
spinlock_t ksnd_reaper_lock; /* serialise */
int ksnd_enomem_tx; /* test ENOMEM sender */
@@ -225,7 +225,7 @@ typedef struct /* transmit packet */
lnet_kiov_t *tx_kiov; /* packet page frags */
struct ksock_conn *tx_conn; /* owning conn */
lnet_msg_t *tx_lnetmsg; /* lnet message for lnet_finalize() */
- cfs_time_t tx_deadline; /* when (in jiffies) tx times out */
+ unsigned long tx_deadline; /* when (in jiffies) tx times out */
ksock_msg_t tx_msg; /* socklnd message buffer */
int tx_desc_size; /* size of this descriptor */
union {
@@ -262,7 +262,7 @@ typedef struct ksock_conn
struct ksock_peer *ksnc_peer; /* owning peer */
struct ksock_route *ksnc_route; /* owning route */
struct list_head ksnc_list; /* stash on peer's conn list */
- socket_t *ksnc_sock; /* actual socket */
+ struct socket *ksnc_sock; /* actual socket */
void *ksnc_saved_data_ready; /* socket's original data_ready() callback */
void *ksnc_saved_write_space; /* socket's original write_space() callback */
atomic_t ksnc_conn_refcount; /* conn refcount */
@@ -280,7 +280,7 @@ typedef struct ksock_conn
/* reader */
struct list_head ksnc_rx_list; /* where I enq waiting input or a forwarding descriptor */
- cfs_time_t ksnc_rx_deadline; /* when (in jiffies) receive times out */
+ unsigned long ksnc_rx_deadline; /* when (in jiffies) receive times out */
__u8 ksnc_rx_started; /* started receiving a message */
__u8 ksnc_rx_ready; /* data ready to read */
__u8 ksnc_rx_scheduled;/* being progressed */
@@ -305,12 +305,12 @@ typedef struct ksock_conn
struct list_head ksnc_tx_list; /* where I enq waiting for output space */
struct list_head ksnc_tx_queue; /* packets waiting to be sent */
ksock_tx_t *ksnc_tx_carrier; /* next TX that can carry a LNet message or ZC-ACK */
- cfs_time_t ksnc_tx_deadline; /* when (in jiffies) tx times out */
+ unsigned long ksnc_tx_deadline; /* when (in jiffies) tx times out */
int ksnc_tx_bufnob; /* send buffer marker */
atomic_t ksnc_tx_nob; /* # bytes queued */
int ksnc_tx_ready; /* write space */
int ksnc_tx_scheduled; /* being progressed */
- cfs_time_t ksnc_tx_last_post; /* time stamp of the last posted TX */
+ unsigned long ksnc_tx_last_post; /* time stamp of the last posted TX */
} ksock_conn_t;
typedef struct ksock_route
@@ -319,8 +319,8 @@ typedef struct ksock_route
struct list_head ksnr_connd_list; /* chain on ksnr_connd_routes */
struct ksock_peer *ksnr_peer; /* owning peer */
atomic_t ksnr_refcount; /* # users */
- cfs_time_t ksnr_timeout; /* when (in jiffies) reconnection can happen next */
- cfs_duration_t ksnr_retry_interval; /* how long between retries */
+ unsigned long ksnr_timeout; /* when (in jiffies) reconnection can happen next */
+ long ksnr_retry_interval; /* how long between retries */
__u32 ksnr_myipaddr; /* my IP */
__u32 ksnr_ipaddr; /* IP address to connect to */
int ksnr_port; /* port to connect to */
@@ -337,7 +337,7 @@ typedef struct ksock_route
typedef struct ksock_peer
{
struct list_head ksnp_list; /* stash on global peer list */
- cfs_time_t ksnp_last_alive; /* when (in jiffies) I was last alive */
+ unsigned long ksnp_last_alive; /* when (in jiffies) I was last alive */
lnet_process_id_t ksnp_id; /* who's on the other end(s) */
atomic_t ksnp_refcount; /* # users */
int ksnp_sharecount; /* lconf usage counter */
@@ -352,7 +352,7 @@ typedef struct ksock_peer
struct list_head ksnp_tx_queue; /* waiting packets */
spinlock_t ksnp_lock; /* serialize, g_lock unsafe */
struct list_head ksnp_zc_req_list; /* zero copy requests wait for ACK */
- cfs_time_t ksnp_send_keepalive; /* time to send keepalive */
+ unsigned long ksnp_send_keepalive; /* time to send keepalive */
lnet_ni_t *ksnp_ni; /* which network */
int ksnp_n_passive_ips; /* # of... */
__u32 ksnp_passive_ips[LNET_MAX_INTERFACES]; /* preferred local interfaces */
@@ -362,7 +362,7 @@ typedef struct ksock_connreq
{
struct list_head ksncr_list; /* stash on ksnd_connd_connreqs */
lnet_ni_t *ksncr_ni; /* chosen NI */
- socket_t *ksncr_sock; /* accepted socket */
+ struct socket *ksncr_sock; /* accepted socket */
} ksock_connreq_t;
extern ksock_nal_data_t ksocknal_data;
@@ -527,14 +527,14 @@ int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
int delayed, unsigned int niov,
struct iovec *iov, lnet_kiov_t *kiov,
unsigned int offset, unsigned int mlen, unsigned int rlen);
-int ksocknal_accept(lnet_ni_t *ni, socket_t *sock);
+int ksocknal_accept(lnet_ni_t *ni, struct socket *sock);
extern int ksocknal_add_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ip, int port);
extern ksock_peer_t *ksocknal_find_peer_locked (lnet_ni_t *ni, lnet_process_id_t id);
extern ksock_peer_t *ksocknal_find_peer (lnet_ni_t *ni, lnet_process_id_t id);
extern void ksocknal_peer_failed (ksock_peer_t *peer);
extern int ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
- socket_t *sock, int type);
+ struct socket *sock, int type);
extern void ksocknal_close_conn_locked (ksock_conn_t *conn, int why);
extern void ksocknal_terminate_conn (ksock_conn_t *conn);
extern void ksocknal_destroy_conn (ksock_conn_t *conn);
@@ -555,7 +555,7 @@ extern void ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn);
extern void ksocknal_txlist_done (lnet_ni_t *ni, struct list_head *txlist,
int error);
extern void ksocknal_notify (lnet_ni_t *ni, lnet_nid_t gw_nid, int alive);
-extern void ksocknal_query (struct lnet_ni *ni, lnet_nid_t nid, cfs_time_t *when);
+extern void ksocknal_query (struct lnet_ni *ni, lnet_nid_t nid, unsigned long *when);
extern int ksocknal_thread_start(int (*fn)(void *arg), void *arg, char *name);
extern void ksocknal_thread_fini (void);
extern void ksocknal_launch_all_connections_locked (ksock_peer_t *peer);
@@ -574,12 +574,12 @@ extern void ksocknal_read_callback(ksock_conn_t *conn);
extern void ksocknal_write_callback(ksock_conn_t *conn);
extern int ksocknal_lib_zc_capable(ksock_conn_t *conn);
-extern void ksocknal_lib_save_callback(socket_t *sock, ksock_conn_t *conn);
-extern void ksocknal_lib_set_callback(socket_t *sock, ksock_conn_t *conn);
-extern void ksocknal_lib_reset_callback(socket_t *sock, ksock_conn_t *conn);
+extern void ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn);
+extern void ksocknal_lib_set_callback(struct socket *sock, ksock_conn_t *conn);
+extern void ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn);
extern void ksocknal_lib_push_conn (ksock_conn_t *conn);
extern int ksocknal_lib_get_conn_addrs (ksock_conn_t *conn);
-extern int ksocknal_lib_setup_sock (socket_t *so);
+extern int ksocknal_lib_setup_sock (struct socket *so);
extern int ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx);
extern int ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx);
extern void ksocknal_lib_eager_ack (ksock_conn_t *conn);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 75bd6583493e..521439954fcb 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -212,7 +212,7 @@ ksocknal_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
rc = ksocknal_send_kiov (conn, tx);
}
- bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+ bufnob = conn->ksnc_sock->sk->sk_wmem_queued;
if (rc > 0) /* sent something? */
conn->ksnc_tx_bufnob += rc; /* account it */
@@ -630,7 +630,7 @@ ksocknal_find_conn_locked(ksock_peer_t *peer, ksock_tx_t *tx, int nonblk)
list_for_each (tmp, &peer->ksnp_conns) {
ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list);
int nob = atomic_read(&c->ksnc_tx_nob) +
- cfs_sock_wmem_queued(c->ksnc_sock);
+ c->ksnc_sock->sk->sk_wmem_queued;
int rc;
LASSERT (!c->ksnc_closing);
@@ -726,7 +726,7 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
* FIXME: SOCK_WMEM_QUEUED and SOCK_ERROR could block in __DARWIN8__
* but they're used inside spinlocks a lot.
*/
- bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+ bufnob = conn->ksnc_sock->sk->sk_wmem_queued;
spin_lock_bh(&sched->kss_lock);
if (list_empty(&conn->ksnc_tx_queue) && bufnob == 0) {
@@ -780,7 +780,7 @@ ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
ksock_route_t *
ksocknal_find_connectable_route_locked (ksock_peer_t *peer)
{
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
struct list_head *tmp;
ksock_route_t *route;
@@ -1199,7 +1199,7 @@ ksocknal_process_receive (ksock_conn_t *conn)
conn->ksnc_msg.ksm_zc_cookies[1]);
if (rc != 0) {
- CERROR("%s: Unknown ZC-ACK cookie: "LPU64", "LPU64"\n",
+ CERROR("%s: Unknown ZC-ACK cookie: %llu, %llu\n",
libcfs_id2str(conn->ksnc_peer->ksnp_id),
cookie, conn->ksnc_msg.ksm_zc_cookies[1]);
ksocknal_new_packet(conn, 0);
@@ -1699,7 +1699,7 @@ ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn,
* EALREADY lost connection race
* EPROTO protocol version mismatch
*/
- socket_t *sock = conn->ksnc_sock;
+ struct socket *sock = conn->ksnc_sock;
int active = (conn->ksnc_proto != NULL);
int timeout;
int proto_match;
@@ -1844,8 +1844,8 @@ ksocknal_connect (ksock_route_t *route)
ksock_peer_t *peer = route->ksnr_peer;
int type;
int wanted;
- socket_t *sock;
- cfs_time_t deadline;
+ struct socket *sock;
+ unsigned long deadline;
int retry_later = 0;
int rc = 0;
@@ -2059,7 +2059,7 @@ ksocknal_connd_check_start(long sec, long *timeout)
/* we tried ... */
LASSERT(ksocknal_data.ksnd_connd_starting > 0);
ksocknal_data.ksnd_connd_starting--;
- ksocknal_data.ksnd_connd_failed_stamp = cfs_time_current_sec();
+ ksocknal_data.ksnd_connd_failed_stamp = get_seconds();
return 1;
}
@@ -2111,7 +2111,7 @@ static ksock_route_t *
ksocknal_connd_get_route_locked(signed long *timeout_p)
{
ksock_route_t *route;
- cfs_time_t now;
+ unsigned long now;
now = cfs_time_current();
@@ -2152,7 +2152,7 @@ ksocknal_connd (void *arg)
while (!ksocknal_data.ksnd_shuttingdown) {
ksock_route_t *route = NULL;
- long sec = cfs_time_current_sec();
+ long sec = get_seconds();
long timeout = MAX_SCHEDULE_TIMEOUT;
int dropped_lock = 0;
@@ -2260,7 +2260,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
/* SOCK_ERROR will reset error code of socket in
* some platform (like Darwin8.x) */
- error = cfs_sock_error(conn->ksnc_sock);
+ error = conn->ksnc_sock->sk->sk_err;
if (error != 0) {
ksocknal_conn_addref(conn);
@@ -2311,7 +2311,7 @@ ksocknal_find_timed_out_conn (ksock_peer_t *peer)
}
if ((!list_empty(&conn->ksnc_tx_queue) ||
- cfs_sock_wmem_queued(conn->ksnc_sock) != 0) &&
+ conn->ksnc_sock->sk->sk_wmem_queued != 0) &&
cfs_time_aftereq(cfs_time_current(),
conn->ksnc_tx_deadline)) {
/* Timed out messages queued for sending or
@@ -2368,13 +2368,12 @@ ksocknal_send_keepalive_locked(ksock_peer_t *peer)
return 0;
if (*ksocknal_tunables.ksnd_keepalive <= 0 ||
- cfs_time_before(cfs_time_current(),
- cfs_time_add(peer->ksnp_last_alive,
- cfs_time_seconds(*ksocknal_tunables.ksnd_keepalive))))
+ time_before(cfs_time_current(),
+ cfs_time_add(peer->ksnp_last_alive,
+ cfs_time_seconds(*ksocknal_tunables.ksnd_keepalive))))
return 0;
- if (cfs_time_before(cfs_time_current(),
- peer->ksnp_send_keepalive))
+ if (time_before(cfs_time_current(), peer->ksnp_send_keepalive))
return 0;
/* retry 10 secs later, so we wouldn't put pressure
@@ -2431,7 +2430,7 @@ ksocknal_check_peer_timeouts (int idx)
read_lock(&ksocknal_data.ksnd_global_lock);
list_for_each_entry(peer, peers, ksnp_list) {
- cfs_time_t deadline = 0;
+ unsigned long deadline = 0;
int resid = 0;
int n = 0;
@@ -2508,7 +2507,7 @@ ksocknal_check_peer_timeouts (int idx)
"resid: %d, wmem: %d\n",
n, libcfs_nid2str(peer->ksnp_id.nid), tx,
cfs_duration_sec(cfs_time_current() - deadline),
- resid, cfs_sock_wmem_queued(conn->ksnc_sock));
+ resid, conn->ksnc_sock->sk->sk_wmem_queued);
ksocknal_close_conn_and_siblings (conn, -ETIMEDOUT);
ksocknal_conn_decref(conn);
@@ -2526,10 +2525,10 @@ ksocknal_reaper (void *arg)
ksock_sched_t *sched;
struct list_head enomem_conns;
int nenomem_conns;
- cfs_duration_t timeout;
+ long timeout;
int i;
int peer_index = 0;
- cfs_time_t deadline = cfs_time_current();
+ unsigned long deadline = cfs_time_current();
cfs_block_allsigs ();
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
index d18bab19cd9a..245c9d7560af 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
@@ -695,7 +695,7 @@ ksocknal_lib_memory_pressure(ksock_conn_t *conn)
sched = conn->ksnc_scheduler;
spin_lock_bh(&sched->kss_lock);
- if (!SOCK_TEST_NOSPACE(conn->ksnc_sock) &&
+ if (!test_bit(SOCK_NOSPACE, &conn->ksnc_sock->flags) &&
!conn->ksnc_tx_ready) {
/* SOCK_NOSPACE is set when the socket fills
* and cleared in the write_space callback
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h
index 025cb65ddc70..f14a60ce0916 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h
@@ -62,8 +62,8 @@
#include <asm/div64.h>
#include <linux/syscalls.h>
-#include <linux/libcfs/libcfs.h>
-#include <linux/libcfs/linux/portals_compat25.h>
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "../../../include/linux/libcfs/linux/portals_compat25.h"
#include <linux/crc32.h>
static inline __u32 ksocknal_csum(__u32 crc, unsigned char const *p, size_t len)
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
index 2d91571cbab2..050a58d08809 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
@@ -192,7 +192,7 @@ ksocknal_queue_tx_zcack_v3(ksock_conn_t *conn,
if (cookie == tx->tx_msg.ksm_zc_cookies[0] ||
cookie == tx->tx_msg.ksm_zc_cookies[1]) {
- CWARN("%s: duplicated ZC cookie: "LPU64"\n",
+ CWARN("%s: duplicated ZC cookie: %llu\n",
libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
return 1; /* XXX return error in the future */
}
@@ -244,7 +244,7 @@ ksocknal_queue_tx_zcack_v3(ksock_conn_t *conn,
/* ksm_zc_cookies[0] < ksm_zc_cookies[1], it is range of cookies */
if (cookie >= tx->tx_msg.ksm_zc_cookies[0] &&
cookie <= tx->tx_msg.ksm_zc_cookies[1]) {
- CWARN("%s: duplicated ZC cookie: "LPU64"\n",
+ CWARN("%s: duplicated ZC cookie: %llu\n",
libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
return 1; /* XXX: return error in the future */
}
@@ -452,7 +452,7 @@ ksocknal_handle_zcack(ksock_conn_t *conn, __u64 cookie1, __u64 cookie2)
static int
ksocknal_send_hello_v1 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
{
- socket_t *sock = conn->ksnc_sock;
+ struct socket *sock = conn->ksnc_sock;
lnet_hdr_t *hdr;
lnet_magicversion_t *hmv;
int rc;
@@ -527,7 +527,7 @@ out:
static int
ksocknal_send_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
{
- socket_t *sock = conn->ksnc_sock;
+ struct socket *sock = conn->ksnc_sock;
int rc;
hello->kshm_magic = LNET_PROTO_MAGIC;
@@ -570,7 +570,7 @@ ksocknal_send_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
static int
ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello,int timeout)
{
- socket_t *sock = conn->ksnc_sock;
+ struct socket *sock = conn->ksnc_sock;
lnet_hdr_t *hdr;
int rc;
int i;
@@ -646,7 +646,7 @@ out:
static int
ksocknal_recv_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout)
{
- socket_t *sock = conn->ksnc_sock;
+ struct socket *sock = conn->ksnc_sock;
int rc;
int i;
diff --git a/drivers/staging/lustre/lnet/lnet/Makefile b/drivers/staging/lustre/lnet/lnet/Makefile
index b815fe12b10a..336b8ea4fdf6 100644
--- a/drivers/staging/lustre/lnet/lnet/Makefile
+++ b/drivers/staging/lustre/lnet/lnet/Makefile
@@ -3,6 +3,3 @@ obj-$(CONFIG_LNET) += lnet.o
lnet-y := api-ni.o config.o lib-me.o lib-msg.o lib-eq.o \
lib-md.o lib-ptl.o lib-move.o module.o lo.o router.o \
router_proc.o acceptor.o peer.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c
index 09ea6cb1492c..5dfb887a03ae 100644
--- a/drivers/staging/lustre/lnet/lnet/acceptor.c
+++ b/drivers/staging/lustre/lnet/lnet/acceptor.c
@@ -35,16 +35,16 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
static int accept_port = 988;
static int accept_backlog = 127;
static int accept_timeout = 5;
-struct {
+static struct {
int pta_shutdown;
- socket_t *pta_sock;
+ struct socket *pta_sock;
struct completion pta_signal;
} lnet_acceptor_state;
@@ -75,7 +75,7 @@ MODULE_PARM_DESC(accept_timeout, "Acceptor's timeout (seconds)");
static char *accept_type;
-int
+static int
lnet_acceptor_get_tunables(void)
{
/* Userland acceptor uses 'accept_type' instead of 'accept', due to
@@ -139,11 +139,11 @@ lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
EXPORT_SYMBOL(lnet_connect_console_error);
int
-lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
+lnet_connect(struct socket **sockp, lnet_nid_t peer_nid,
__u32 local_ip, __u32 peer_ip, int peer_port)
{
lnet_acceptor_connreq_t cr;
- socket_t *sock;
+ struct socket *sock;
int rc;
int port;
int fatal;
@@ -207,8 +207,8 @@ EXPORT_SYMBOL(lnet_connect);
/* Below is the code common for both kernel and MT user-space */
-int
-lnet_accept(socket_t *sock, __u32 magic)
+static int
+lnet_accept(struct socket *sock, __u32 magic)
{
lnet_acceptor_connreq_t cr;
__u32 peer_ip;
@@ -329,10 +329,10 @@ lnet_accept(socket_t *sock, __u32 magic)
return rc;
}
-int
+static int
lnet_acceptor(void *arg)
{
- socket_t *newsock;
+ struct socket *newsock;
int rc;
__u32 magic;
__u32 peer_ip;
@@ -457,10 +457,8 @@ lnet_acceptor_start(void)
init_completion(&lnet_acceptor_state.pta_signal);
rc = accept2secure(accept_type, &secure);
- if (rc <= 0) {
- fini_completion(&lnet_acceptor_state.pta_signal);
+ if (rc <= 0)
return rc;
- }
if (lnet_count_acceptor_nis() == 0) /* not required */
return 0;
@@ -470,7 +468,6 @@ lnet_acceptor_start(void)
"acceptor_%03ld", secure));
if (IS_ERR_VALUE(rc2)) {
CERROR("Can't start acceptor thread: %ld\n", rc2);
- fini_completion(&lnet_acceptor_state.pta_signal);
return -ESRCH;
}
@@ -485,7 +482,6 @@ lnet_acceptor_start(void)
}
LASSERT(lnet_acceptor_state.pta_sock == NULL);
- fini_completion(&lnet_acceptor_state.pta_signal);
return -ENETDOWN;
}
@@ -501,6 +497,4 @@ lnet_acceptor_stop(void)
/* block until acceptor signals exit */
wait_for_completion(&lnet_acceptor_state.pta_signal);
-
- fini_completion(&lnet_acceptor_state.pta_signal);
}
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 3f878dee2e42..b28734a76fac 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -35,7 +35,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
#include <linux/log2.h>
#define D_LNI D_CONSOLE
@@ -60,13 +60,13 @@ static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
module_param(rnet_htable_size, int, 0444);
MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table");
-char *
+static char *
lnet_get_routes(void)
{
return routes;
}
-char *
+static char *
lnet_get_networks(void)
{
char *nets;
@@ -89,7 +89,7 @@ lnet_get_networks(void)
return "tcp";
}
-void
+static void
lnet_init_locks(void)
{
spin_lock_init(&the_lnet.ln_eq_wait_lock);
@@ -98,7 +98,7 @@ lnet_init_locks(void)
mutex_init(&the_lnet.ln_api_mutex);
}
-void
+static void
lnet_fini_locks(void)
{
}
@@ -177,7 +177,7 @@ lnet_create_locks(void)
return -ENOMEM;
}
-void lnet_assert_wire_constants (void)
+static void lnet_assert_wire_constants (void)
{
/* Wire protocol assertions generated by 'wirecheck'
* running on Linux robert.bartonsoftware.com 2.6.8-1.521
@@ -270,7 +270,7 @@ void lnet_assert_wire_constants (void)
CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4);
}
-lnd_t *
+static lnd_t *
lnet_find_lnd_by_type (int type)
{
lnd_t *lnd;
@@ -415,7 +415,7 @@ lnet_freelist_fini (lnet_freelist_t *fl)
#endif /* LNET_USE_LIB_FREELIST */
-__u64
+static __u64
lnet_create_interface_cookie (void)
{
/* NB the interface cookie in wire handles guards against delayed
@@ -446,7 +446,7 @@ lnet_res_type2str(int type)
}
}
-void
+static void
lnet_res_container_cleanup(struct lnet_res_container *rec)
{
int count = 0;
@@ -490,7 +490,7 @@ lnet_res_container_cleanup(struct lnet_res_container *rec)
rec->rec_type = 0; /* mark it as finalized */
}
-int
+static int
lnet_res_container_setup(struct lnet_res_container *rec,
int cpt, int type, int objnum, int objsz)
{
@@ -608,7 +608,7 @@ lnet_res_lh_initialize(struct lnet_res_container *rec, lnet_libhandle_t *lh)
int lnet_unprepare(void);
-int
+static int
lnet_prepare(lnet_pid_t requested_pid)
{
/* Prepare to bring up the network */
@@ -913,7 +913,7 @@ lnet_ni_tq_credits(lnet_ni_t *ni)
return credits;
}
-void
+static void
lnet_shutdown_lndnis (void)
{
int i;
@@ -1030,7 +1030,7 @@ lnet_shutdown_lndnis (void)
}
}
-int
+static int
lnet_startup_lndnis (void)
{
lnd_t *lnd;
@@ -1452,7 +1452,7 @@ LNetCtl(unsigned int cmd, void *arg)
case IOC_LIBCFS_NOTIFY_ROUTER:
return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
cfs_time_current() -
- cfs_time_seconds(cfs_time_current_sec() -
+ cfs_time_seconds(get_seconds() -
(time_t)data->ioc_u64[0]));
case IOC_LIBCFS_PORTALS_COMPATIBILITY:
@@ -1575,7 +1575,7 @@ EXPORT_SYMBOL(LNetGetId);
void
LNetSnprintHandle(char *str, int len, lnet_handle_any_t h)
{
- snprintf(str, len, LPX64, h.cookie);
+ snprintf(str, len, "%#llx", h.cookie);
}
EXPORT_SYMBOL(LNetSnprintHandle);
@@ -1662,7 +1662,7 @@ lnet_destroy_ping_info(void)
int
lnet_ping_target_init(void)
{
- lnet_md_t md = {0};
+ lnet_md_t md = { NULL };
lnet_handle_me_t meh;
lnet_process_id_t id;
int rc;
@@ -1770,7 +1770,7 @@ lnet_ping (lnet_process_id_t id, int timeout_ms, lnet_process_id_t *ids, int n_i
lnet_handle_eq_t eqh;
lnet_handle_md_t mdh;
lnet_event_t event;
- lnet_md_t md = {0};
+ lnet_md_t md = { NULL };
int which;
int unlinked = 0;
int replied = 0;
diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
index d97464e95ddb..7c8b9476bfbb 100644
--- a/drivers/staging/lustre/lnet/lnet/config.c
+++ b/drivers/staging/lustre/lnet/lnet/config.c
@@ -35,7 +35,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
typedef struct { /* tmp struct for parsing routes */
struct list_head ltb_list; /* stash on lists */
@@ -166,7 +166,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist)
/* LND will fill in the address part of the NID */
ni->ni_nid = LNET_MKNID(net, 0);
- ni->ni_last_alive = cfs_time_current_sec();
+ ni->ni_last_alive = get_seconds();
list_add_tail(&ni->ni_list, nilist);
return ni;
failed:
diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c
index d25dcd8ba563..bd45478e9948 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-eq.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c
@@ -39,7 +39,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
/**
* Create an event queue that has room for \a count number of events.
@@ -330,7 +330,7 @@ __must_hold(&the_lnet.ln_eq_wait_lock)
int tms = *timeout_ms;
int wait;
wait_queue_t wl;
- cfs_time_t now;
+ unsigned long now;
if (tms == 0)
return -1; /* don't want to wait and no new event */
diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c
index ae643f26933b..1f386e09b530 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-md.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-md.c
@@ -40,7 +40,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
/* must be called with lnet_res_lock held */
void
@@ -387,7 +387,8 @@ EXPORT_SYMBOL(LNetMDBind);
/**
* Unlink the memory descriptor from any ME it may be linked to and release
- * the internal resources associated with it.
+ * the internal resources associated with it. As a result, active messages
+ * associated with the MD may get aborted.
*
* This function does not free the memory region associated with the MD;
* i.e., the memory the user allocated for this MD. If the ME associated with
@@ -433,12 +434,11 @@ LNetMDUnlink (lnet_handle_md_t mdh)
return -ENOENT;
}
+ md->md_flags |= LNET_MD_FLAG_ABORTED;
/* If the MD is busy, lnet_md_unlink just marks it for deletion, and
- * when the NAL is done, the completion event flags that the MD was
+ * when the LND is done, the completion event flags that the MD was
* unlinked. Otherwise, we enqueue an event now... */
-
- if (md->md_eq != NULL &&
- md->md_refcount == 0) {
+ if (md->md_eq != NULL && md->md_refcount == 0) {
lnet_build_unlink_event(md, &ev);
lnet_eq_enqueue_event(md->md_eq, &ev);
}
diff --git a/drivers/staging/lustre/lnet/lnet/lib-me.c b/drivers/staging/lustre/lnet/lnet/lib-me.c
index 0081075cabee..a3f929244711 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-me.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-me.c
@@ -40,7 +40,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
/**
* Create and attach a match entry to the match list of \a portal. The new
@@ -246,11 +246,12 @@ LNetMEUnlink(lnet_handle_me_t meh)
}
md = me->me_md;
- if (md != NULL &&
- md->md_eq != NULL &&
- md->md_refcount == 0) {
- lnet_build_unlink_event(md, &ev);
- lnet_eq_enqueue_event(md->md_eq, &ev);
+ if (md != NULL) {
+ md->md_flags |= LNET_MD_FLAG_ABORTED;
+ if (md->md_eq != NULL && md->md_refcount == 0) {
+ lnet_build_unlink_event(md, &ev);
+ lnet_eq_enqueue_event(md->md_eq, &ev);
+ }
}
lnet_me_unlink(me);
@@ -282,7 +283,7 @@ lnet_me_unlink(lnet_me_t *me)
static void
lib_me_dump(lnet_me_t *me)
{
- CWARN("Match Entry %p ("LPX64")\n", me,
+ CWARN("Match Entry %p (%#llx)\n", me,
me->me_lh.lh_cookie);
CWARN("\tMatch/Ignore\t= %016lx / %016lx\n",
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index bbf43ae04ed0..4b9567d67f33 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -40,7 +40,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
static int local_nid_dist_zero = 1;
module_param(local_nid_dist_zero, int, 0444);
@@ -682,7 +682,7 @@ lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg)
void
lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp)
{
- cfs_time_t last_alive = 0;
+ unsigned long last_alive = 0;
LASSERT(lnet_peer_aliveness_enabled(lp));
LASSERT(ni->ni_lnd->lnd_query != NULL);
@@ -699,10 +699,10 @@ lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp)
/* NB: always called with lnet_net_lock held */
static inline int
-lnet_peer_is_alive(lnet_peer_t *lp, cfs_time_t now)
+lnet_peer_is_alive(lnet_peer_t *lp, unsigned long now)
{
int alive;
- cfs_time_t deadline;
+ unsigned long deadline;
LASSERT(lnet_peer_aliveness_enabled(lp));
@@ -734,7 +734,7 @@ lnet_peer_is_alive(lnet_peer_t *lp, cfs_time_t now)
int
lnet_peer_alive_locked(lnet_peer_t *lp)
{
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
if (!lnet_peer_aliveness_enabled(lp))
return -ENODEV;
@@ -747,11 +747,11 @@ lnet_peer_alive_locked(lnet_peer_t *lp)
if (lp->lp_last_query != 0) {
static const int lnet_queryinterval = 1;
- cfs_time_t next_query =
+ unsigned long next_query =
cfs_time_add(lp->lp_last_query,
cfs_time_seconds(lnet_queryinterval));
- if (cfs_time_before(now, next_query)) {
+ if (time_before(now, next_query)) {
if (lp->lp_alive)
CWARN("Unexpected aliveness of peer %s: "
"%d < %d (%d/%d)\n",
@@ -773,26 +773,30 @@ lnet_peer_alive_locked(lnet_peer_t *lp)
return 0;
}
-int
+/**
+ * \param msg The message to be sent.
+ * \param do_send True if lnet_ni_send() should be called in this function.
+ * lnet_send() is going to lnet_net_unlock immediately after this, so
+ * it sets do_send FALSE and I don't do the unlock/send/lock bit.
+ *
+ * \retval 0 If \a msg sent or OK to send.
+ * \retval EAGAIN If \a msg blocked for credit.
+ * \retval EHOSTUNREACH If the next hop of the message appears dead.
+ * \retval ECANCELED If the MD of the message has been unlinked.
+ */
+static int
lnet_post_send_locked(lnet_msg_t *msg, int do_send)
{
- /* lnet_send is going to lnet_net_unlock immediately after this,
- * so it sets do_send FALSE and I don't do the unlock/send/lock bit.
- * I return EAGAIN if msg blocked, EHOSTUNREACH if msg_txpeer
- * appears dead, and 0 if sent or OK to send */
- struct lnet_peer *lp = msg->msg_txpeer;
- struct lnet_ni *ni = lp->lp_ni;
- struct lnet_tx_queue *tq;
- int cpt;
+ lnet_peer_t *lp = msg->msg_txpeer;
+ lnet_ni_t *ni = lp->lp_ni;
+ int cpt = msg->msg_tx_cpt;
+ struct lnet_tx_queue *tq = ni->ni_tx_queues[cpt];
/* non-lnet_send() callers have checked before */
LASSERT(!do_send || msg->msg_tx_delayed);
LASSERT(!msg->msg_receiving);
LASSERT(msg->msg_tx_committed);
- cpt = msg->msg_tx_cpt;
- tq = ni->ni_tx_queues[cpt];
-
/* NB 'lp' is always the next hop */
if ((msg->msg_target.pid & LNET_PID_USERFLAG) == 0 &&
lnet_peer_alive_locked(lp) == 0) {
@@ -809,6 +813,20 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send)
return EHOSTUNREACH;
}
+ if (msg->msg_md != NULL &&
+ (msg->msg_md->md_flags & LNET_MD_FLAG_ABORTED) != 0) {
+ lnet_net_unlock(cpt);
+
+ CNETERR("Aborting message for %s: LNetM[DE]Unlink() already "
+ "called on the MD/ME.\n",
+ libcfs_id2str(msg->msg_target));
+ if (do_send)
+ lnet_finalize(ni, msg, -ECANCELED);
+
+ lnet_net_lock(cpt);
+ return ECANCELED;
+ }
+
if (!msg->msg_peertxcredit) {
LASSERT((lp->lp_txcredits < 0) ==
!list_empty(&lp->lp_txq));
@@ -1327,13 +1345,13 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
rc = lnet_post_send_locked(msg, 0);
lnet_net_unlock(cpt);
- if (rc == EHOSTUNREACH)
- return -EHOSTUNREACH;
+ if (rc == EHOSTUNREACH || rc == ECANCELED)
+ return -rc;
if (rc == 0)
lnet_ni_send(src_ni, msg);
- return 0;
+ return 0; /* rc == 0 or EAGAIN */
}
static void
@@ -1408,8 +1426,7 @@ lnet_parse_put(lnet_ni_t *ni, lnet_msg_t *msg)
/* fall through */
case LNET_MATCHMD_DROP:
- CNETERR("Dropping PUT from %s portal %d match "LPU64
- " offset %d length %d: %d\n",
+ CNETERR("Dropping PUT from %s portal %d match %llu offset %d length %d: %d\n",
libcfs_id2str(info.mi_id), info.mi_portal,
info.mi_mbits, info.mi_roffset, info.mi_rlength, rc);
@@ -1441,8 +1458,7 @@ lnet_parse_get(lnet_ni_t *ni, lnet_msg_t *msg, int rdma_get)
rc = lnet_ptl_match_md(&info, msg);
if (rc == LNET_MATCHMD_DROP) {
- CNETERR("Dropping GET from %s portal %d match "LPU64
- " offset %d length %d\n",
+ CNETERR("Dropping GET from %s portal %d match %llu offset %d length %d\n",
libcfs_id2str(info.mi_id), info.mi_portal,
info.mi_mbits, info.mi_roffset, info.mi_rlength);
return ENOENT; /* +ve: OK but no match */
@@ -1502,8 +1518,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
/* NB handles only looked up by creator (no flips) */
md = lnet_wire_handle2md(&hdr->msg.reply.dst_wmd);
if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
- CNETERR("%s: Dropping REPLY from %s for %s "
- "MD "LPX64"."LPX64"\n",
+ CNETERR("%s: Dropping REPLY from %s for %s MD %#llx.%#llx\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
(md == NULL) ? "invalid" : "inactive",
hdr->msg.reply.dst_wmd.wh_interface_cookie,
@@ -1523,8 +1538,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
if (mlength < rlength &&
(md->md_options & LNET_MD_TRUNCATE) == 0) {
- CNETERR("%s: Dropping REPLY from %s length %d "
- "for MD "LPX64" would overflow (%d)\n",
+ CNETERR("%s: Dropping REPLY from %s length %d for MD %#llx would overflow (%d)\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
rlength, hdr->msg.reply.dst_wmd.wh_object_cookie,
mlength);
@@ -1532,7 +1546,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
return ENOENT; /* +ve: OK but no match */
}
- CDEBUG(D_NET, "%s: Reply from %s of length %d/%d into md "LPX64"\n",
+ CDEBUG(D_NET, "%s: Reply from %s of length %d/%d into md %#llx\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
mlength, rlength, hdr->msg.reply.dst_wmd.wh_object_cookie);
@@ -1572,7 +1586,7 @@ lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg)
if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
/* Don't moan; this is expected */
CDEBUG(D_NET,
- "%s: Dropping ACK from %s to %s MD "LPX64"."LPX64"\n",
+ "%s: Dropping ACK from %s to %s MD %#llx.%#llx\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
(md == NULL) ? "invalid" : "inactive",
hdr->msg.ack.dst_wmd.wh_interface_cookie,
@@ -1585,7 +1599,7 @@ lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg)
return ENOENT; /* +ve! */
}
- CDEBUG(D_NET, "%s: ACK from %s into md "LPX64"\n",
+ CDEBUG(D_NET, "%s: ACK from %s into md %#llx\n",
libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
hdr->msg.ack.dst_wmd.wh_object_cookie);
@@ -1662,20 +1676,20 @@ lnet_print_hdr(lnet_hdr_t *hdr)
break;
case LNET_MSG_PUT:
- CWARN(" Ptl index %d, ack md "LPX64"."LPX64", "
- "match bits "LPU64"\n",
+ CWARN(" Ptl index %d, ack md %#llx.%#llx, "
+ "match bits %llu\n",
hdr->msg.put.ptl_index,
hdr->msg.put.ack_wmd.wh_interface_cookie,
hdr->msg.put.ack_wmd.wh_object_cookie,
hdr->msg.put.match_bits);
- CWARN(" Length %d, offset %d, hdr data "LPX64"\n",
+ CWARN(" Length %d, offset %d, hdr data %#llx\n",
hdr->payload_length, hdr->msg.put.offset,
hdr->msg.put.hdr_data);
break;
case LNET_MSG_GET:
- CWARN(" Ptl index %d, return md "LPX64"."LPX64", "
- "match bits "LPU64"\n", hdr->msg.get.ptl_index,
+ CWARN(" Ptl index %d, return md %#llx.%#llx, "
+ "match bits %llu\n", hdr->msg.get.ptl_index,
hdr->msg.get.return_wmd.wh_interface_cookie,
hdr->msg.get.return_wmd.wh_object_cookie,
hdr->msg.get.match_bits);
@@ -1685,7 +1699,7 @@ lnet_print_hdr(lnet_hdr_t *hdr)
break;
case LNET_MSG_ACK:
- CWARN(" dst md "LPX64"."LPX64", "
+ CWARN(" dst md %#llx.%#llx, "
"manipulated length %d\n",
hdr->msg.ack.dst_wmd.wh_interface_cookie,
hdr->msg.ack.dst_wmd.wh_object_cookie,
@@ -1693,7 +1707,7 @@ lnet_print_hdr(lnet_hdr_t *hdr)
break;
case LNET_MSG_REPLY:
- CWARN(" dst md "LPX64"."LPX64", "
+ CWARN(" dst md %#llx.%#llx, "
"length %d\n",
hdr->msg.reply.dst_wmd.wh_interface_cookie,
hdr->msg.reply.dst_wmd.wh_object_cookie,
@@ -1762,11 +1776,11 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
}
if (the_lnet.ln_routing &&
- ni->ni_last_alive != cfs_time_current_sec()) {
+ ni->ni_last_alive != get_seconds()) {
lnet_ni_lock(ni);
/* NB: so far here is the only place to set NI status to "up */
- ni->ni_last_alive = cfs_time_current_sec();
+ ni->ni_last_alive = get_seconds();
if (ni->ni_status != NULL &&
ni->ni_status->ns_status == LNET_NI_STATUS_DOWN)
ni->ni_status->ns_status = LNET_NI_STATUS_UP;
@@ -1945,8 +1959,7 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
LASSERT(msg->msg_rxpeer != NULL);
LASSERT(msg->msg_hdr.type == LNET_MSG_PUT);
- CWARN("Dropping delayed PUT from %s portal %d match "LPU64
- " offset %d length %d: %s\n",
+ CWARN("Dropping delayed PUT from %s portal %d match %llu offset %d length %d: %s\n",
libcfs_id2str(id),
msg->msg_hdr.msg.put.ptl_index,
msg->msg_hdr.msg.put.match_bits,
@@ -1991,7 +2004,7 @@ lnet_recv_delayed_msg_list(struct list_head *head)
LASSERT(msg->msg_hdr.type == LNET_MSG_PUT);
CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d "
- "match "LPU64" offset %d length %d.\n",
+ "match %llu offset %d length %d.\n",
libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index,
msg->msg_hdr.msg.put.match_bits,
msg->msg_hdr.msg.put.offset,
@@ -2079,7 +2092,7 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
md = lnet_handle2md(&mdh);
if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
- CERROR("Dropping PUT ("LPU64":%d:%s): MD (%d) invalid\n",
+ CERROR("Dropping PUT (%llu:%d:%s): MD (%d) invalid\n",
match_bits, portal, libcfs_id2str(target),
md == NULL ? -1 : md->md_threshold);
if (md != NULL && md->md_me != NULL)
@@ -2278,7 +2291,7 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
md = lnet_handle2md(&mdh);
if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
- CERROR("Dropping GET ("LPU64":%d:%s): MD (%d) invalid\n",
+ CERROR("Dropping GET (%llu:%d:%s): MD (%d) invalid\n",
match_bits, portal, libcfs_id2str(target),
md == NULL ? -1 : md->md_threshold);
if (md != NULL && md->md_me != NULL)
@@ -2288,7 +2301,6 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
lnet_res_unlock(cpt);
lnet_msg_free(msg);
-
return -ENOENT;
}
diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
index 761f1e12f847..a46ccbf6608f 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
@@ -40,7 +40,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
void
lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev)
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 920df69960a5..91767c9e15dd 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
/* NB: add /proc interfaces in upcoming patches */
int portal_rotor = LNET_PTL_ROTOR_HASH_RT;
@@ -184,8 +184,7 @@ lnet_try_match_md(lnet_libmd_t *md,
mlength = info->mi_rlength;
} else if ((md->md_options & LNET_MD_TRUNCATE) == 0) {
/* this packet _really_ is too big */
- CERROR("Matching packet from %s, match "LPU64
- " length %d too big: %d left, %d allowed\n",
+ CERROR("Matching packet from %s, match %llu length %d too big: %d left, %d allowed\n",
libcfs_id2str(info->mi_id), info->mi_mbits,
info->mi_rlength, md->md_length - offset, mlength);
@@ -194,7 +193,7 @@ lnet_try_match_md(lnet_libmd_t *md,
/* Commit to this ME/MD */
CDEBUG(D_NET, "Incoming %s index %x from %s of "
- "length %d/%d into md "LPX64" [%d] + %d\n",
+ "length %d/%d into md %#llx [%d] + %d\n",
(info->mi_opc == LNET_MD_OP_PUT) ? "put" : "get",
info->mi_portal, libcfs_id2str(info->mi_id), mlength,
info->mi_rlength, md->md_lh.lh_cookie, md->md_niov, offset);
@@ -541,9 +540,9 @@ lnet_ptl_match_md(struct lnet_match_info *info, struct lnet_msg *msg)
struct lnet_portal *ptl;
int rc;
- CDEBUG(D_NET, "Request from %s of length %d into portal %d "
- "MB="LPX64"\n", libcfs_id2str(info->mi_id),
- info->mi_rlength, info->mi_portal, info->mi_mbits);
+ CDEBUG(D_NET, "Request from %s of length %d into portal %d MB=%#llx\n",
+ libcfs_id2str(info->mi_id), info->mi_rlength, info->mi_portal,
+ info->mi_mbits);
if (info->mi_portal >= the_lnet.ln_nportals) {
CERROR("Invalid portal %d not in [0-%d]\n",
@@ -597,7 +596,7 @@ lnet_ptl_match_md(struct lnet_match_info *info, struct lnet_msg *msg)
if (msg->msg_rx_delayed) {
CDEBUG(D_NET,
- "Delaying %s from %s ptl %d MB "LPX64" off %d len %d\n",
+ "Delaying %s from %s ptl %d MB %#llx off %d len %d\n",
info->mi_opc == LNET_MD_OP_PUT ? "PUT" : "GET",
libcfs_id2str(info->mi_id), info->mi_portal,
info->mi_mbits, info->mi_roffset, info->mi_rlength);
@@ -687,8 +686,7 @@ lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md,
if ((rc & LNET_MATCHMD_OK) != 0) {
list_add_tail(&msg->msg_list, matches);
- CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d "
- "match "LPU64" offset %d length %d.\n",
+ CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d match %llu offset %d length %d.\n",
libcfs_id2str(info.mi_id),
info.mi_portal, info.mi_mbits,
info.mi_roffset, info.mi_rlength);
diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c
index efc798e01934..be31dfc5fa4b 100644
--- a/drivers/staging/lustre/lnet/lnet/lo.c
+++ b/drivers/staging/lustre/lnet/lnet/lo.c
@@ -33,7 +33,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
int
lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c
index 3bd42a485a32..e84d59d23ae0 100644
--- a/drivers/staging/lustre/lnet/lnet/module.c
+++ b/drivers/staging/lustre/lnet/lnet/module.c
@@ -35,7 +35,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
static int config_on_load;
module_param(config_on_load, int, 0444);
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index 72802b0404a4..c93ae8510530 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -38,7 +38,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.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 926923a104c5..ac38ad271071 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -22,7 +22,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/lnet/lib-lnet.h"
#if defined(LNET_ROUTER)
@@ -107,9 +107,9 @@ lnet_peers_start_down(void)
}
void
-lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when)
+lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, unsigned long when)
{
- if (cfs_time_before(when, lp->lp_timestamp)) { /* out of date information */
+ if (time_before(when, lp->lp_timestamp)) { /* out of date information */
CDEBUG(D_NET, "Out of date\n");
return;
}
@@ -135,7 +135,7 @@ lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when)
CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive);
}
-void
+static void
lnet_ni_notify_locked(lnet_ni_t *ni, lnet_peer_t *lp)
{
int alive;
@@ -273,7 +273,7 @@ static void lnet_shuffle_seed(void)
}
/* NB expects LNET_LOCK held */
-void
+static void
lnet_add_route_to_rnet (lnet_remotenet_t *rnet, lnet_route_t *route)
{
unsigned int len = 0;
@@ -796,7 +796,7 @@ lnet_update_ni_status_locked(void)
timeout = router_ping_timeout +
MAX(live_router_check_interval, dead_router_check_interval);
- now = cfs_time_current_sec();
+ now = get_seconds();
list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
if (ni->ni_lnd->lnd_type == LOLND)
continue;
@@ -866,7 +866,6 @@ lnet_create_rc_data_locked(lnet_peer_t *gateway)
if (pi == NULL)
goto out;
- memset(pi, 0, LNET_PINGINFO_SIZE);
for (i = 0; i < LNET_MAX_RTR_NIS; i++) {
pi->pi_ni[i].ns_nid = LNET_NID_ANY;
pi->pi_ni[i].ns_status = LNET_NI_STATUS_INVALID;
@@ -932,7 +931,7 @@ static void
lnet_ping_router_locked (lnet_peer_t *rtr)
{
lnet_rc_data_t *rcd = NULL;
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
int secs;
lnet_peer_addref_locked(rtr);
@@ -1498,10 +1497,10 @@ lnet_rtrpools_alloc(int im_a_router)
}
int
-lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, cfs_time_t when)
+lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when)
{
struct lnet_peer *lp = NULL;
- cfs_time_t now = cfs_time_current();
+ unsigned long now = cfs_time_current();
int cpt = lnet_cpt_of_nid(nid);
LASSERT (!in_interrupt ());
@@ -1577,7 +1576,7 @@ lnet_get_tunables (void)
#else
int
-lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, cfs_time_t when)
+lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when)
{
return -EOPNOTSUPP;
}
@@ -1588,7 +1587,7 @@ lnet_router_checker (void)
static time_t last = 0;
static int running = 0;
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
int interval = now - last;
int rc;
__u64 version;
diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c
index 0cbd9fc98e07..166c1e647e2b 100644
--- a/drivers/staging/lustre/lnet/lnet/router_proc.c
+++ b/drivers/staging/lustre/lnet/lnet/router_proc.c
@@ -22,15 +22,15 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/lib-lnet.h"
#if defined(LNET_ROUTER)
/* This is really lnet_proc.c. You might need to update sanity test 215
* if any file format is changed. */
-static ctl_table_header_t *lnet_table_header;
+static struct ctl_table_header *lnet_table_header;
#define CTL_LNET (0x100)
enum {
@@ -90,6 +90,24 @@ enum {
#define LNET_PROC_VERSION(v) ((unsigned int)((v) & LNET_PROC_VER_MASK))
+static int proc_call_handler(void *data, int write, loff_t *ppos, void *buffer,
+ size_t *lenp, int (*handler)(void *data, int write,
+ loff_t pos, void *buffer, int len))
+{
+ int rc = handler(data, write, *ppos, buffer, *lenp);
+
+ if (rc < 0)
+ return rc;
+
+ if (write) {
+ *ppos += *lenp;
+ } else {
+ *lenp = rc;
+ *ppos += rc;
+ }
+ return 0;
+}
+
static int __proc_lnet_stats(void *data, int write,
loff_t pos, void *buffer, int nob)
{
@@ -97,7 +115,7 @@ static int __proc_lnet_stats(void *data, int write,
lnet_counters_t *ctrs;
int len;
char *tmpstr;
- const int tmpsiz = 256; /* 7 %u and 4 LPU64 */
+ const int tmpsiz = 256; /* 7 %u and 4 %llu */
if (write) {
lnet_counters_reset();
@@ -119,8 +137,7 @@ static int __proc_lnet_stats(void *data, int write,
lnet_counters_get(ctrs);
len = snprintf(tmpstr, tmpsiz,
- "%u %u %u %u %u %u %u "LPU64" "LPU64" "
- LPU64" "LPU64,
+ "%u %u %u %u %u %u %u %llu %llu %llu %llu",
ctrs->msgs_alloc, ctrs->msgs_max,
ctrs->errors,
ctrs->send_count, ctrs->recv_count,
@@ -139,9 +156,15 @@ static int __proc_lnet_stats(void *data, int write,
return rc;
}
-DECLARE_PROC_HANDLER(proc_lnet_stats);
+static int proc_lnet_stats(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_lnet_stats);
+}
-int LL_PROC_PROTO(proc_lnet_routes)
+int proc_lnet_routes(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
const int tmpsiz = 256;
char *tmpstr;
@@ -151,8 +174,6 @@ int LL_PROC_PROTO(proc_lnet_routes)
int ver;
int off;
- DECLARE_LL_PROC_PPOS_DECL;
-
CLASSERT(sizeof(loff_t) >= 4);
off = LNET_PROC_HOFF_GET(*ppos);
@@ -268,7 +289,8 @@ int LL_PROC_PROTO(proc_lnet_routes)
return rc;
}
-int LL_PROC_PROTO(proc_lnet_routers)
+int proc_lnet_routers(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int rc = 0;
char *tmpstr;
@@ -278,8 +300,6 @@ int LL_PROC_PROTO(proc_lnet_routers)
int ver;
int off;
- DECLARE_LL_PROC_PPOS_DECL;
-
off = LNET_PROC_HOFF_GET(*ppos);
ver = LNET_PROC_VER_GET(*ppos);
@@ -337,8 +357,8 @@ int LL_PROC_PROTO(proc_lnet_routers)
if (peer != NULL) {
lnet_nid_t nid = peer->lp_nid;
- cfs_time_t now = cfs_time_current();
- cfs_time_t deadline = peer->lp_ping_deadline;
+ unsigned long now = cfs_time_current();
+ unsigned long deadline = peer->lp_ping_deadline;
int nrefs = peer->lp_refcount;
int nrtrrefs = peer->lp_rtr_refcount;
int alive_cnt = peer->lp_alive_count;
@@ -404,7 +424,8 @@ int LL_PROC_PROTO(proc_lnet_routers)
return rc;
}
-int LL_PROC_PROTO(proc_lnet_peers)
+int proc_lnet_peers(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
const int tmpsiz = 256;
struct lnet_peer_table *ptable;
@@ -515,8 +536,8 @@ int LL_PROC_PROTO(proc_lnet_peers)
aliveness = peer->lp_alive ? "up" : "down";
if (lnet_peer_aliveness_enabled(peer)) {
- cfs_time_t now = cfs_time_current();
- cfs_duration_t delta;
+ unsigned long now = cfs_time_current();
+ long delta;
delta = cfs_time_sub(now, peer->lp_last_alive);
lastalive = cfs_duration_sec(delta);
@@ -628,9 +649,15 @@ static int __proc_lnet_buffers(void *data, int write,
return rc;
}
-DECLARE_PROC_HANDLER(proc_lnet_buffers);
+static int proc_lnet_buffers(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_lnet_buffers);
+}
-int LL_PROC_PROTO(proc_lnet_nis)
+int proc_lnet_nis(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int tmpsiz = 128 * LNET_CPT_NUMBER;
int rc = 0;
@@ -638,8 +665,6 @@ int LL_PROC_PROTO(proc_lnet_nis)
char *s;
int len;
- DECLARE_LL_PROC_PPOS_DECL;
-
LASSERT(!write);
if (*lenp == 0)
@@ -681,7 +706,7 @@ int LL_PROC_PROTO(proc_lnet_nis)
if (ni != NULL) {
struct lnet_tx_queue *tq;
char *stat;
- long now = cfs_time_current_sec();
+ long now = get_seconds();
int last_alive = -1;
int i;
int j;
@@ -849,9 +874,16 @@ out:
LIBCFS_FREE(buf, buf_len);
return rc;
}
-DECLARE_PROC_HANDLER(proc_lnet_portal_rotor);
-static ctl_table_t lnet_table[] = {
+static int proc_lnet_portal_rotor(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_lnet_portal_rotor);
+}
+
+static struct ctl_table lnet_table[] = {
/*
* NB No .strategy entries have been provided since sysctl(8) prefers
* to go via /proc for portability.
@@ -895,7 +927,7 @@ static ctl_table_t lnet_table[] = {
}
};
-static ctl_table_t top_table[] = {
+static struct ctl_table top_table[] = {
{
.procname = "lnet",
.mode = 0555,
diff --git a/drivers/staging/lustre/lnet/selftest/Makefile b/drivers/staging/lustre/lnet/selftest/Makefile
index 1e40aeea2962..c0de6e2d96d0 100644
--- a/drivers/staging/lustre/lnet/selftest/Makefile
+++ b/drivers/staging/lustre/lnet/selftest/Makefile
@@ -2,5 +2,3 @@ obj-$(CONFIG_LNET_SELFTEST) := lnet_selftest.o
lnet_selftest-y := console.o conrpc.o conctl.o framework.o timer.o rpc.o \
module.o ping_test.o brw_test.o
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c
index 3f8020cb93e6..bcce919c0433 100644
--- a/drivers/staging/lustre/lnet/selftest/brw_test.c
+++ b/drivers/staging/lustre/lnet/selftest/brw_test.c
@@ -216,7 +216,7 @@ brw_check_page(struct page *pg, int pattern, __u64 magic)
LBUG();
bad_data:
- CERROR("Bad data in page %p: "LPX64", "LPX64" expected\n",
+ CERROR("Bad data in page %p: %#llx, %#llx expected\n",
pg, data, magic);
return 1;
}
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index 68e1a171209c..ae7b0fcd818d 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -40,9 +40,9 @@
* Author: Liang Zhen <liangzhen@clusterfs.com>
*/
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lib-lnet.h>
-#include <linux/lnet/lnetst.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/lib-lnet.h"
+#include "../../include/linux/lnet/lnetst.h"
#include "console.h"
int
@@ -837,7 +837,7 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data)
mutex_lock(&console_session.ses_mutex);
- console_session.ses_laststamp = cfs_time_current_sec();
+ console_session.ses_laststamp = get_seconds();
if (console_session.ses_shutdown) {
rc = -ESHUTDOWN;
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 8d1eea4cef6f..a3a60d6e9081 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -41,8 +41,8 @@
*/
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/lib-lnet.h"
#include "timer.h"
#include "conrpc.h"
#include "console.h"
@@ -477,7 +477,7 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
lstcon_rpc_t *crpc;
srpc_msg_t *msg;
lstcon_node_t *nd;
- cfs_duration_t dur;
+ long dur;
struct timeval tv;
int error;
@@ -503,8 +503,8 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
nd = crpc->crp_node;
- dur = (cfs_duration_t)cfs_time_sub(crpc->crp_stamp,
- (cfs_time_t)console_session.ses_id.ses_stamp);
+ dur = (long)cfs_time_sub(crpc->crp_stamp,
+ (unsigned long)console_session.ses_id.ses_stamp);
cfs_duration_usec(dur, &tv);
if (copy_to_user(&ent->rpe_peer,
@@ -1187,7 +1187,7 @@ lstcon_rpc_pinger(void *arg)
}
if (!console_session.ses_expired &&
- cfs_time_current_sec() - console_session.ses_laststamp >
+ get_seconds() - console_session.ses_laststamp >
(time_t)console_session.ses_timeout)
console_session.ses_expired = 1;
@@ -1274,7 +1274,7 @@ lstcon_rpc_pinger(void *arg)
CDEBUG(D_NET, "Ping %d nodes in session\n", count);
- ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
+ ptimer->stt_expires = (unsigned long)(get_seconds() + LST_PING_INTERVAL);
stt_add_timer(ptimer);
mutex_unlock(&console_session.ses_mutex);
@@ -1297,7 +1297,7 @@ lstcon_rpc_pinger_start(void)
}
ptimer = &console_session.ses_ping_timer;
- ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
+ ptimer->stt_expires = (unsigned long)(get_seconds() + LST_PING_INTERVAL);
stt_add_timer(ptimer);
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index 9aba24a2eab9..fc1cb56cbab2 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -43,10 +43,10 @@
#ifndef __LST_CONRPC_H__
#define __LST_CONRPC_H__
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-types.h>
-#include <linux/lnet/lnetst.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 "rpc.h"
#include "selftest.h"
@@ -75,7 +75,7 @@ typedef struct lstcon_rpc {
/** RPC is embedded in other structure and can't free it */
unsigned int crp_embedded:1;
int crp_status; /* console rpc errors */
- cfs_time_t crp_stamp; /* replied time stamp */
+ unsigned long crp_stamp; /* replied time stamp */
} lstcon_rpc_t;
typedef struct lstcon_rpc_trans {
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 352fc96398d2..89e1b4bd5a50 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -41,8 +41,8 @@
*/
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lib-lnet.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/lib-lnet.h"
#include "console.h"
#include "conrpc.h"
@@ -204,9 +204,6 @@ lstcon_group_alloc(char *name, lstcon_group_t **grpp)
if (grp == NULL)
return -ENOMEM;
- memset(grp, 0, offsetof(lstcon_group_t,
- grp_ndl_hash[LST_NODE_HASHSIZE]));
-
grp->grp_ref = 1;
if (name != NULL)
strcpy(grp->grp_name, name);
@@ -815,8 +812,6 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
return -ENOMEM;
}
- memset(gentp, 0, sizeof(lstcon_ndlist_ent_t));
-
list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link)
LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp);
@@ -971,8 +966,6 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t *ent_up, int server,
if (entp == NULL)
return -ENOMEM;
- memset(entp, 0, sizeof(lstcon_test_batch_ent_t));
-
if (test == NULL) {
entp->u.tbe_batch.bae_ntest = bat->bat_ntest;
entp->u.tbe_batch.bae_state = bat->bat_state;
@@ -1319,7 +1312,6 @@ lstcon_test_add(char *batch_name, int type, int loop,
goto out;
}
- memset(test, 0, offsetof(lstcon_test_t, tes_param[paramlen]));
test->tes_hdr.tsb_id = batch->bat_hdr.tsb_id;
test->tes_batch = batch;
test->tes_type = type;
@@ -1789,8 +1781,6 @@ lstcon_session_info(lst_sid_t *sid_up, int *key_up, unsigned *featp,
if (entp == NULL)
return -ENOMEM;
- memset(entp, 0, sizeof(*entp));
-
list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
LST_NODE_STATE_COUNTER(ndl->ndl_node, entp);
@@ -2016,7 +2006,7 @@ lstcon_console_init(void)
console_session.ses_expired = 0;
console_session.ses_feats_updated = 0;
console_session.ses_features = LST_FEATS_MASK;
- console_session.ses_laststamp = cfs_time_current_sec();
+ console_session.ses_laststamp = get_seconds();
mutex_init(&console_session.ses_mutex);
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h
index 393dc0f64109..f960174ceff8 100644
--- a/drivers/staging/lustre/lnet/selftest/console.h
+++ b/drivers/staging/lustre/lnet/selftest/console.h
@@ -44,10 +44,10 @@
#define __LST_CONSOLE_H__
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-types.h>
-#include <linux/lnet/lnetst.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 "selftest.h"
#include "conrpc.h"
@@ -56,7 +56,7 @@ typedef struct lstcon_node {
int nd_ref; /* reference count */
int nd_state; /* state of the node */
int nd_timeout; /* session timeout */
- cfs_time_t nd_stamp; /* timestamp of last replied RPC */
+ unsigned long nd_stamp; /* timestamp of last replied RPC */
struct lstcon_rpc nd_ping; /* ping rpc */
} lstcon_node_t; /*** node descriptor */
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index 050723a0243a..7e83dff2fcb4 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -149,7 +149,6 @@ sfw_register_test (srpc_service_t *service, sfw_test_client_ops_t *cliops)
if (tsc == NULL)
return -ENOMEM;
- memset(tsc, 0, sizeof(sfw_test_case_t));
tsc->tsc_cli_ops = cliops;
tsc->tsc_srv_service = service;
@@ -172,7 +171,7 @@ sfw_add_session_timer (void)
sn->sn_timer_active = 1;
timer->stt_expires = cfs_time_add(sn->sn_timeout,
- cfs_time_current_sec());
+ get_seconds());
stt_add_timer(timer);
return;
}
@@ -249,7 +248,7 @@ sfw_session_expired (void *data)
LASSERT (sn->sn_timer_active);
LASSERT (sn == sfw_data.fw_session);
- CWARN ("Session expired! sid: %s-"LPU64", name: %s\n",
+ CWARN ("Session expired! sid: %s-%llu, name: %s\n",
libcfs_nid2str(sn->sn_id.ses_nid),
sn->sn_id.ses_stamp, &sn->sn_name[0]);
@@ -742,12 +741,11 @@ sfw_add_test_instance (sfw_batch_t *tsb, srpc_server_rpc_t *rpc)
LIBCFS_ALLOC(tsi, sizeof(*tsi));
if (tsi == NULL) {
- CERROR ("Can't allocate test instance for batch: "LPU64"\n",
+ CERROR ("Can't allocate test instance for batch: %llu\n",
tsb->bat_id.bat_id);
return -ENOMEM;
}
- memset(tsi, 0, sizeof(*tsi));
spin_lock_init(&tsi->tsi_lock);
atomic_set(&tsi->tsi_nactive, 0);
INIT_LIST_HEAD(&tsi->tsi_units);
@@ -1004,7 +1002,7 @@ sfw_run_batch (sfw_batch_t *tsb)
sfw_test_instance_t *tsi;
if (sfw_batch_active(tsb)) {
- CDEBUG(D_NET, "Batch already active: "LPU64" (%d)\n",
+ CDEBUG(D_NET, "Batch already active: %llu (%d)\n",
tsb->bat_id.bat_id, atomic_read(&tsb->bat_nactive));
return 0;
}
@@ -1039,7 +1037,7 @@ sfw_stop_batch (sfw_batch_t *tsb, int force)
srpc_client_rpc_t *rpc;
if (!sfw_batch_active(tsb)) {
- CDEBUG(D_NET, "Batch "LPU64" inactive\n", tsb->bat_id.bat_id);
+ CDEBUG(D_NET, "Batch %llu inactive\n", tsb->bat_id.bat_id);
return 0;
}
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index 9fc0429e8296..a9f29d8833a9 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -386,7 +386,7 @@ srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf,
}
CDEBUG (D_NET,
- "Posted passive RDMA: peer %s, portal %d, matchbits "LPX64"\n",
+ "Posted passive RDMA: peer %s, portal %d, matchbits %#llx\n",
libcfs_id2str(peer), portal, matchbits);
return 0;
}
@@ -426,7 +426,7 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len,
}
if (rc != 0) {
- CERROR ("LNet%s(%s, %d, "LPD64") failed: %d\n",
+ CERROR ("LNet%s(%s, %d, %lld) failed: %d\n",
((options & LNET_MD_OP_PUT) != 0) ? "Put" : "Get",
libcfs_id2str(peer), portal, matchbits, rc);
@@ -437,7 +437,7 @@ srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len,
LASSERT (rc == 0);
} else {
CDEBUG (D_NET,
- "Posted active RDMA: peer %s, portal %u, matchbits "LPX64"\n",
+ "Posted active RDMA: peer %s, portal %u, matchbits %#llx\n",
libcfs_id2str(peer), portal, matchbits);
}
return 0;
@@ -563,7 +563,7 @@ srpc_add_buffer(struct swi_workitem *wi)
}
if (rc != 0) {
- scd->scd_buf_err_stamp = cfs_time_current_sec();
+ scd->scd_buf_err_stamp = get_seconds();
scd->scd_buf_err = rc;
LASSERT(scd->scd_buf_posting > 0);
@@ -1098,7 +1098,7 @@ srpc_add_client_rpc_timer (srpc_client_rpc_t *rpc)
timer->stt_data = rpc;
timer->stt_func = srpc_client_rpc_expired;
timer->stt_expires = cfs_time_add(rpc->crpc_timeout,
- cfs_time_current_sec());
+ get_seconds());
stt_add_timer(timer);
return;
}
@@ -1481,7 +1481,7 @@ srpc_lnet_ev_handler(lnet_event_t *ev)
}
if (scd->scd_buf_err_stamp != 0 &&
- scd->scd_buf_err_stamp < cfs_time_current_sec()) {
+ scd->scd_buf_err_stamp < get_seconds()) {
/* re-enable adding buffer */
scd->scd_buf_err_stamp = 0;
scd->scd_buf_err = 0;
@@ -1587,7 +1587,7 @@ srpc_startup (void)
/* 1 second pause to avoid timestamp reuse */
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(cfs_time_seconds(1));
- srpc_data.rpc_matchbits = ((__u64) cfs_time_current_sec()) << 48;
+ srpc_data.rpc_matchbits = ((__u64) get_seconds()) << 48;
srpc_data.rpc_state = SRPC_STATE_NONE;
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.h b/drivers/staging/lustre/lnet/selftest/rpc.h
index b905d49a351f..fbeb75fe5922 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.h
+++ b/drivers/staging/lustre/lnet/selftest/rpc.h
@@ -37,7 +37,7 @@
#ifndef __SELFTEST_RPC_H__
#define __SELFTEST_RPC_H__
-#include <linux/lnet/lnetst.h>
+#include "../../include/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 f4806a6bc942..9b5c5df6eb2c 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -43,11 +43,11 @@
#define LNET_ONLY
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
-#include <linux/lnet/lib-lnet.h>
-#include <linux/lnet/lib-types.h>
-#include <linux/lnet/lnetst.h>
+#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 "rpc.h"
#include "timer.h"
@@ -334,7 +334,7 @@ typedef struct {
atomic_t sn_refcount;
atomic_t sn_brw_errors;
atomic_t sn_ping_errors;
- cfs_time_t sn_started;
+ unsigned long sn_started;
} sfw_session_t;
#define sfw_sid_equal(sid0, sid1) ((sid0).ses_nid == (sid1).ses_nid && \
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index b8e50ef0bb4e..91d4caa4edb0 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -60,7 +60,7 @@
struct st_timer_data {
spinlock_t stt_lock;
/* start time of the slot processed previously */
- cfs_time_t stt_prev_slot;
+ unsigned long stt_prev_slot;
struct list_head stt_hash[STTIMER_NSLOTS];
int stt_shuttingdown;
wait_queue_head_t stt_waitq;
@@ -78,7 +78,7 @@ stt_add_timer(stt_timer_t *timer)
LASSERT(!stt_data.stt_shuttingdown);
LASSERT(timer->stt_func != NULL);
LASSERT(list_empty(&timer->stt_list));
- LASSERT(cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
+ LASSERT(cfs_time_after(timer->stt_expires, get_seconds()));
/* a simple insertion sort */
list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) {
@@ -122,7 +122,7 @@ stt_del_timer(stt_timer_t *timer)
/* called with stt_data.stt_lock held */
int
-stt_expire_list(struct list_head *slot, cfs_time_t now)
+stt_expire_list(struct list_head *slot, unsigned long now)
{
int expired = 0;
stt_timer_t *timer;
@@ -146,13 +146,13 @@ stt_expire_list(struct list_head *slot, cfs_time_t now)
}
int
-stt_check_timers(cfs_time_t *last)
+stt_check_timers(unsigned long *last)
{
int expired = 0;
- cfs_time_t now;
- cfs_time_t this_slot;
+ unsigned long now;
+ unsigned long this_slot;
- now = cfs_time_current_sec();
+ now = get_seconds();
this_slot = now & STTIMER_SLOTTIMEMASK;
spin_lock(&stt_data.stt_lock);
@@ -212,7 +212,7 @@ stt_startup(void)
int i;
stt_data.stt_shuttingdown = 0;
- stt_data.stt_prev_slot = cfs_time_current_sec() & STTIMER_SLOTTIMEMASK;
+ stt_data.stt_prev_slot = get_seconds() & STTIMER_SLOTTIMEMASK;
spin_lock_init(&stt_data.stt_lock);
for (i = 0; i < STTIMER_NSLOTS; i++)
diff --git a/drivers/staging/lustre/lnet/selftest/timer.h b/drivers/staging/lustre/lnet/selftest/timer.h
index 56dbfe5ea1e5..d727c1e2b0ce 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.h
+++ b/drivers/staging/lustre/lnet/selftest/timer.h
@@ -40,7 +40,7 @@
typedef struct {
struct list_head stt_list;
- cfs_time_t stt_expires;
+ unsigned long stt_expires;
void (*stt_func) (void *);
void *stt_data;
} stt_timer_t;
diff --git a/drivers/staging/lustre/lustre/Kconfig b/drivers/staging/lustre/lustre/Kconfig
index 209e4c7e6f8a..4f65ba1158bf 100644
--- a/drivers/staging/lustre/lustre/Kconfig
+++ b/drivers/staging/lustre/lustre/Kconfig
@@ -57,4 +57,5 @@ config LUSTRE_TRANSLATE_ERRNOS
config LUSTRE_LLITE_LLOOP
tristate "Lustre virtual block device"
depends on LUSTRE_FS && BLOCK
+ depends on !PPC_64K_PAGES && !ARM64_64K_PAGES
default m
diff --git a/drivers/staging/lustre/lustre/fid/Makefile b/drivers/staging/lustre/lustre/fid/Makefile
index d24f2df7c0af..5513ce416a35 100644
--- a/drivers/staging/lustre/lustre/fid/Makefile
+++ b/drivers/staging/lustre/lustre/fid/Makefile
@@ -1,6 +1,3 @@
obj-$(CONFIG_LUSTRE_FS) += fid.o
fid-y := fid_request.o fid_lib.o
fid-$(CONFIG_PROC_FS) += lproc_fid.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h
index 1dbe46be0f41..eb607c52ef3b 100644
--- a/drivers/staging/lustre/lustre/fid/fid_internal.h
+++ b/drivers/staging/lustre/lustre/fid/fid_internal.h
@@ -40,16 +40,16 @@
#ifndef __FID_INTERNAL_H
#define __FID_INTERNAL_H
-#include <lustre/lustre_idl.h>
-#include <linux/libcfs/libcfs.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../../include/linux/libcfs/libcfs.h"
/* Functions used internally in module. */
int seq_client_alloc_super(struct lu_client_seq *seq,
const struct lu_env *env);
-# ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern struct lprocfs_vars seq_client_proc_list[];
-# endif
+#endif
extern struct proc_dir_entry *seq_type_proc_dir;
diff --git a/drivers/staging/lustre/lustre/fid/fid_lib.c b/drivers/staging/lustre/lustre/fid/fid_lib.c
index f03afdec027a..dd65159ebb38 100644
--- a/drivers/staging/lustre/lustre/fid/fid_lib.c
+++ b/drivers/staging/lustre/lustre/fid/fid_lib.c
@@ -43,10 +43,10 @@
#define DEBUG_SUBSYSTEM S_FID
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/module.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_fid.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../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 3401c9ad42ac..992d07591b08 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -42,15 +42,15 @@
#define DEBUG_SUBSYSTEM S_FID
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/module.h>
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_fid.h>
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
/* mdc RPC locks */
-#include <lustre_mdc.h>
+#include "../include/lustre_mdc.h"
#include "fid_internal.h"
static int seq_client_rpc(struct lu_client_seq *seq,
@@ -197,7 +197,7 @@ static int seq_client_alloc_seq(const struct lu_env *env,
rc = seq_client_alloc_meta(env, seq);
if (rc) {
CERROR("%s: Can't allocate new meta-sequence, rc %d\n",
- seq->lcs_name, rc);
+ seq->lcs_name, rc);
return rc;
} else {
CDEBUG(D_INFO, "%s: New range - "DRANGE"\n",
@@ -211,7 +211,7 @@ static int seq_client_alloc_seq(const struct lu_env *env,
*seqnr = seq->lcs_space.lsr_start;
seq->lcs_space.lsr_start += 1;
- CDEBUG(D_INFO, "%s: Allocated sequence ["LPX64"]\n", seq->lcs_name,
+ CDEBUG(D_INFO, "%s: Allocated sequence [%#llx]\n", seq->lcs_name,
*seqnr);
return rc;
@@ -267,14 +267,14 @@ int seq_client_get_seq(const struct lu_env *env,
rc = seq_client_alloc_seq(env, seq, seqnr);
if (rc) {
CERROR("%s: Can't allocate new sequence, rc %d\n",
- seq->lcs_name, rc);
+ seq->lcs_name, rc);
seq_fid_alloc_fini(seq);
mutex_unlock(&seq->lcs_mutex);
return rc;
}
- CDEBUG(D_INFO, "%s: allocate sequence [0x%16.16"LPF64"x]\n",
- seq->lcs_name, *seqnr);
+ CDEBUG(D_INFO, "%s: allocate sequence [0x%16.16Lx]\n",
+ seq->lcs_name, *seqnr);
/* Since the caller require the whole seq,
* so marked this seq to be used */
@@ -330,14 +330,14 @@ int seq_client_alloc_fid(const struct lu_env *env,
rc = seq_client_alloc_seq(env, seq, &seqnr);
if (rc) {
CERROR("%s: Can't allocate new sequence, rc %d\n",
- seq->lcs_name, rc);
+ seq->lcs_name, rc);
seq_fid_alloc_fini(seq);
mutex_unlock(&seq->lcs_mutex);
return rc;
}
- CDEBUG(D_INFO, "%s: Switch to sequence [0x%16.16"LPF64"x]\n",
- seq->lcs_name, seqnr);
+ CDEBUG(D_INFO, "%s: Switch to sequence [0x%16.16Lx]\n",
+ seq->lcs_name, seqnr);
seq->lcs_fid.f_oid = LUSTRE_FID_INIT_OID;
seq->lcs_fid.f_seq = seqnr;
@@ -400,18 +400,18 @@ EXPORT_SYMBOL(seq_client_flush);
static void seq_client_proc_fini(struct lu_client_seq *seq)
{
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
if (seq->lcs_proc_dir) {
if (!IS_ERR(seq->lcs_proc_dir))
lprocfs_remove(&seq->lcs_proc_dir);
seq->lcs_proc_dir = NULL;
}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
}
static int seq_client_proc_init(struct lu_client_seq *seq)
{
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int rc;
seq->lcs_proc_dir = lprocfs_register(seq->lcs_name,
@@ -429,7 +429,7 @@ static int seq_client_proc_init(struct lu_client_seq *seq)
seq_client_proc_list, seq);
if (rc) {
CERROR("%s: Can't init sequence manager proc, rc %d\n",
- seq->lcs_name, rc);
+ seq->lcs_name, rc);
GOTO(out_cleanup, rc);
}
@@ -439,7 +439,7 @@ out_cleanup:
seq_client_proc_fini(seq);
return rc;
-#else /* LPROCFS */
+#else /* CONFIG_PROC_FS */
return 0;
#endif
}
diff --git a/drivers/staging/lustre/lustre/fid/lproc_fid.c b/drivers/staging/lustre/lustre/fid/lproc_fid.c
index 6f5674d1aa72..92a27fa9667c 100644
--- a/drivers/staging/lustre/lustre/fid/lproc_fid.c
+++ b/drivers/staging/lustre/lustre/fid/lproc_fid.c
@@ -42,16 +42,16 @@
#define DEBUG_SUBSYSTEM S_FID
-# include <linux/libcfs/libcfs.h>
-# include <linux/module.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <dt_object.h>
-#include <md_object.h>
-#include <obd_support.h>
-#include <lustre_req_layout.h>
-#include <lustre_fid.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/module.h>
+
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/dt_object.h"
+#include "../include/md_object.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_fid.h"
#include "fid_internal.h"
/* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */
@@ -98,9 +98,10 @@ static ssize_t lprocfs_fid_space_seq_write(struct file *file,
const char __user *buffer,
size_t count, loff_t *off)
{
- struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
+ struct lu_client_seq *seq;
int rc;
+ seq = ((struct seq_file *)file->private_data)->private;
LASSERT(seq != NULL);
mutex_lock(&seq->lcs_mutex);
@@ -125,7 +126,7 @@ lprocfs_fid_space_seq_show(struct seq_file *m, void *unused)
LASSERT(seq != NULL);
mutex_lock(&seq->lcs_mutex);
- rc = seq_printf(m, "["LPX64" - "LPX64"]:%x:%s\n", PRANGE(&seq->lcs_space));
+ rc = seq_printf(m, "[%#llx - %#llx]:%x:%s\n", PRANGE(&seq->lcs_space));
mutex_unlock(&seq->lcs_mutex);
return rc;
@@ -135,10 +136,11 @@ static ssize_t lprocfs_fid_width_seq_write(struct file *file,
const char __user *buffer,
size_t count, loff_t *off)
{
- struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
+ struct lu_client_seq *seq;
__u64 max;
int rc, val;
+ seq = ((struct seq_file *)file->private_data)->private;
LASSERT(seq != NULL);
rc = lprocfs_write_helper(buffer, count, &val);
@@ -155,7 +157,7 @@ static ssize_t lprocfs_fid_width_seq_write(struct file *file,
seq->lcs_width = val;
if (rc == 0) {
- CDEBUG(D_INFO, "%s: Sequence size: "LPU64"\n",
+ CDEBUG(D_INFO, "%s: Sequence size: %llu\n",
seq->lcs_name, seq->lcs_width);
}
}
@@ -174,7 +176,7 @@ lprocfs_fid_width_seq_show(struct seq_file *m, void *unused)
LASSERT(seq != NULL);
mutex_lock(&seq->lcs_mutex);
- rc = seq_printf(m, LPU64"\n", seq->lcs_width);
+ rc = seq_printf(m, "%llu\n", seq->lcs_width);
mutex_unlock(&seq->lcs_mutex);
return rc;
diff --git a/drivers/staging/lustre/lustre/fld/Makefile b/drivers/staging/lustre/lustre/fld/Makefile
index 640fba4b827d..2bbf08433dca 100644
--- a/drivers/staging/lustre/lustre/fld/Makefile
+++ b/drivers/staging/lustre/lustre/fld/Makefile
@@ -1,6 +1,3 @@
obj-$(CONFIG_LUSTRE_FS) += fld.o
fld-y := fld_request.o fld_cache.o
fld-$(CONFIG_PROC_FS) += lproc_fld.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c
index a06a642f549e..759a233a7028 100644
--- a/drivers/staging/lustre/lustre/fld/fld_cache.c
+++ b/drivers/staging/lustre/lustre/fld/fld_cache.c
@@ -43,20 +43,20 @@
#define DEBUG_SUBSYSTEM S_FLD
-# include <linux/libcfs/libcfs.h>
-# include <linux/module.h>
-# include <asm/div64.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <lustre_ver.h>
-#include <obd_support.h>
-#include <lprocfs_status.h>
-
-#include <dt_object.h>
-#include <md_object.h>
-#include <lustre_req_layout.h>
-#include <lustre_fld.h>
+#include "../../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 "../include/dt_object.h"
+#include "../include/md_object.h"
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_fld.h"
#include "fld_internal.h"
/**
@@ -113,9 +113,9 @@ void fld_cache_fini(struct fld_cache *cache)
}
CDEBUG(D_INFO, "FLD cache statistics (%s):\n", cache->fci_name);
- CDEBUG(D_INFO, " Total reqs: "LPU64"\n", cache->fci_stat.fst_count);
- CDEBUG(D_INFO, " Cache reqs: "LPU64"\n", cache->fci_stat.fst_cache);
- CDEBUG(D_INFO, " Cache hits: "LPU64"%%\n", pct);
+ CDEBUG(D_INFO, " Total reqs: %llu\n", cache->fci_stat.fst_count);
+ CDEBUG(D_INFO, " Cache reqs: %llu\n", cache->fci_stat.fst_cache);
+ CDEBUG(D_INFO, " Cache hits: %llu%%\n", pct);
OBD_FREE_PTR(cache);
}
diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h
index 8661a788f120..5da0c1da0d39 100644
--- a/drivers/staging/lustre/lustre/fld/fld_internal.h
+++ b/drivers/staging/lustre/lustre/fld/fld_internal.h
@@ -41,12 +41,12 @@
#ifndef __FLD_INTERNAL_H
#define __FLD_INTERNAL_H
-#include <lustre/lustre_idl.h>
-#include <dt_object.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../include/dt_object.h"
-#include <linux/libcfs/libcfs.h>
-#include <lustre_req_layout.h>
-#include <lustre_fld.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_fld.h"
enum {
LUSTRE_FLD_INIT = 1 << 0,
@@ -142,7 +142,7 @@ extern struct lu_fld_hash fld_hash[];
int fld_client_rpc(struct obd_export *exp,
struct lu_seq_range *range, __u32 fld_op);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern struct lprocfs_vars fld_client_proc_list[];
#endif
diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c
index 1f8abba31428..8e512f9c3db0 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -42,21 +42,21 @@
#define DEBUG_SUBSYSTEM S_FLD
-# include <linux/libcfs/libcfs.h>
-# include <linux/module.h>
-# include <asm/div64.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <lustre_ver.h>
-#include <obd_support.h>
-#include <lprocfs_status.h>
-
-#include <dt_object.h>
-#include <md_object.h>
-#include <lustre_req_layout.h>
-#include <lustre_fld.h>
-#include <lustre_mdc.h>
+#include "../../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 "../include/dt_object.h"
+#include "../include/md_object.h"
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_fld.h"
+#include "../include/lustre_mdc.h"
#include "fld_internal.h"
/* TODO: these 3 functions are copies of flow-control code from mdc_lib.c
@@ -138,7 +138,7 @@ fld_rrb_scan(struct lu_client_fld *fld, seqno_t seq)
return target;
}
- CERROR("%s: Can't find target by hash %d (seq "LPX64"). Targets (%d):\n",
+ CERROR("%s: Can't find target by hash %d (seq %#llx). Targets (%d):\n",
fld->lcf_name, hash, seq, fld->lcf_count);
list_for_each_entry(target, &fld->lcf_targets, ft_chain) {
@@ -148,7 +148,7 @@ fld_rrb_scan(struct lu_client_fld *fld, seqno_t seq)
(char *)target->ft_exp->exp_obd->obd_uuid.uuid :
"<null>";
- CERROR(" exp: 0x%p (%s), srv: 0x%p (%s), idx: "LPU64"\n",
+ CERROR(" exp: 0x%p (%s), srv: 0x%p (%s), idx: %llu\n",
target->ft_exp, exp_name, target->ft_srv,
srv_name, target->ft_idx);
}
@@ -168,7 +168,7 @@ struct lu_fld_hash fld_hash[] = {
.fh_scan_func = fld_rrb_scan
},
{
- 0,
+ NULL,
}
};
@@ -184,9 +184,8 @@ fld_client_get_target(struct lu_client_fld *fld, seqno_t seq)
spin_unlock(&fld->lcf_lock);
if (target != NULL) {
- CDEBUG(D_INFO, "%s: Found target (idx "LPU64
- ") by seq "LPX64"\n", fld->lcf_name,
- target->ft_idx, seq);
+ CDEBUG(D_INFO, "%s: Found target (idx %llu) by seq %#llx\n",
+ fld->lcf_name, target->ft_idx, seq);
}
return target;
@@ -208,12 +207,12 @@ int fld_client_add_target(struct lu_client_fld *fld,
LASSERT(tar->ft_srv != NULL || tar->ft_exp != NULL);
if (fld->lcf_flags != LUSTRE_FLD_INIT) {
- CERROR("%s: Attempt to add target %s (idx "LPU64") on fly - skip it\n",
+ CERROR("%s: Attempt to add target %s (idx %llu) on fly - skip it\n",
fld->lcf_name, name, tar->ft_idx);
return 0;
} else {
- CDEBUG(D_INFO, "%s: Adding target %s (idx "
- LPU64")\n", fld->lcf_name, name, tar->ft_idx);
+ CDEBUG(D_INFO, "%s: Adding target %s (idx %llu)\n",
+ fld->lcf_name, name, tar->ft_idx);
}
OBD_ALLOC_PTR(target);
@@ -225,7 +224,7 @@ int fld_client_add_target(struct lu_client_fld *fld,
if (tmp->ft_idx == tar->ft_idx) {
spin_unlock(&fld->lcf_lock);
OBD_FREE_PTR(target);
- CERROR("Target %s exists in FLD and known as %s:#"LPU64"\n",
+ CERROR("Target %s exists in FLD and known as %s:#%llu\n",
name, fld_target_name(tmp), tmp->ft_idx);
return -EEXIST;
}
@@ -274,7 +273,7 @@ EXPORT_SYMBOL(fld_client_del_target);
struct proc_dir_entry *fld_type_proc_dir = NULL;
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
static int fld_client_proc_init(struct lu_client_fld *fld)
{
int rc;
@@ -324,7 +323,6 @@ void fld_client_proc_fini(struct lu_client_fld *fld)
return;
}
#endif
-
EXPORT_SYMBOL(fld_client_proc_fini);
static inline int hash_is_sane(int hash)
@@ -474,7 +472,7 @@ int fld_client_lookup(struct lu_client_fld *fld, seqno_t seq, mdsno_t *mds,
target = fld_client_get_target(fld, seq);
LASSERT(target != NULL);
- CDEBUG(D_INFO, "%s: Lookup fld entry (seq: "LPX64") on target %s (idx "LPU64")\n",
+ CDEBUG(D_INFO, "%s: Lookup fld entry (seq: %#llx) on target %s (idx %llu)\n",
fld->lcf_name, seq, fld_target_name(target), target->ft_idx);
res.lsr_start = seq;
diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c
index 530adde46963..7f6bcc63c5eb 100644
--- a/drivers/staging/lustre/lustre/fld/lproc_fld.c
+++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c
@@ -43,17 +43,17 @@
#define DEBUG_SUBSYSTEM S_FLD
-# include <linux/libcfs/libcfs.h>
-# include <linux/module.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <dt_object.h>
-#include <md_object.h>
-#include <obd_support.h>
-#include <lustre_req_layout.h>
-#include <lustre_fld.h>
-#include <lustre_fid.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include <linux/module.h>
+
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/dt_object.h"
+#include "../include/md_object.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_fld.h"
+#include "../include/lustre_fid.h"
#include "fld_internal.h"
static int
@@ -91,10 +91,11 @@ static ssize_t
fld_proc_hash_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct lu_client_fld *fld = ((struct seq_file *)file->private_data)->private;
+ struct lu_client_fld *fld;
struct lu_fld_hash *hash = NULL;
int i;
+ fld = ((struct seq_file *)file->private_data)->private;
LASSERT(fld != NULL);
for (i = 0; fld_hash[i].fh_name != NULL; i++) {
diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index c809239c0866..e51cd690f907 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -97,10 +97,10 @@
/*
* super-class definitions.
*/
-#include <lu_object.h>
-#include <lvfs.h>
-# include <linux/mutex.h>
-# include <linux/radix-tree.h>
+#include "lu_object.h"
+#include "lvfs.h"
+#include <linux/mutex.h>
+#include <linux/radix-tree.h>
struct inode;
diff --git a/drivers/staging/lustre/lustre/include/dt_object.h b/drivers/staging/lustre/lustre/include/dt_object.h
index 9b7921d1dea8..212ebaea8555 100644
--- a/drivers/staging/lustre/lustre/include/dt_object.h
+++ b/drivers/staging/lustre/lustre/include/dt_object.h
@@ -53,9 +53,9 @@
/*
* super-class definitions.
*/
-#include <lu_object.h>
+#include "lu_object.h"
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
struct seq_file;
struct proc_dir_entry;
@@ -1481,7 +1481,7 @@ static inline struct dt_thread_info *dt_info(const struct lu_env *env)
int dt_global_init(void);
void dt_global_fini(void);
-# ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
int count, int *eof, void *data);
int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
@@ -1494,6 +1494,6 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
int count, int *eof, void *data);
int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
int count, int *eof, void *data);
-# endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
#endif /* __LUSTRE_DT_OBJECT_H */
diff --git a/drivers/staging/lustre/lustre/include/interval_tree.h b/drivers/staging/lustre/lustre/include/interval_tree.h
index dfdb8aa4e035..1815783edae6 100644
--- a/drivers/staging/lustre/lustre/include/interval_tree.h
+++ b/drivers/staging/lustre/lustre/include/interval_tree.h
@@ -40,7 +40,7 @@
#ifndef _INTERVAL_H__
#define _INTERVAL_H__
-#include <linux/libcfs/libcfs.h> /* LASSERT. */
+#include "../../include/linux/libcfs/libcfs.h" /* LASSERT. */
struct interval_node {
struct interval_node *in_left;
diff --git a/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h b/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h
index 4bcc4dcca3da..cb76b5d6f71a 100644
--- a/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h
@@ -50,7 +50,7 @@
#include <linux/seq_file.h>
#include <linux/smp.h>
#include <linux/rwsem.h>
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#include <linux/statfs.h>
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_acl.h b/drivers/staging/lustre/lustre/include/linux/lustre_acl.h
index a91c5497d22c..b17273d403bb 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_acl.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_acl.h
@@ -56,7 +56,7 @@
(sizeof(posix_acl_xattr_header) + \
LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(posix_acl_xattr_entry))
-#include <linux/lustre_intent.h>
+#include "lustre_intent.h"
#include <linux/xattr.h> /* XATTR_{REPLACE,CREATE} */
#ifndef LUSTRE_POSIX_ACL_MAX_SIZE
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
index 81cc7a0134bb..8621bac5058b 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
@@ -39,9 +39,9 @@
#include <linux/fs_struct.h>
#include <linux/namei.h>
-#include <linux/libcfs/linux/portals_compat25.h>
+#include "../../../include/linux/libcfs/linux/portals_compat25.h"
-#include <linux/lustre_patchless_compat.h>
+#include "lustre_patchless_compat.h"
# define LOCK_FS_STRUCT(fs) spin_lock(&(fs)->lock)
# define UNLOCK_FS_STRUCT(fs) spin_unlock(&(fs)->lock)
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h b/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h
index 4da6e372e00b..d5c97beb66f5 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h
@@ -46,8 +46,8 @@
#endif
-#include <obd.h>
-#include <obd_class.h>
+#include "../obd.h"
+#include "../obd_class.h"
typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd,
void *data, int error);
@@ -90,12 +90,12 @@ static inline char *fsfilt_get_label(struct obd_device *obd,
#define __fsfilt_check_slow(obd, start, msg) \
do { \
- if (cfs_time_before(jiffies, start + 15 * HZ)) \
+ if (time_before(jiffies, start + 15 * HZ)) \
break; \
- else if (cfs_time_before(jiffies, start + 30 * HZ)) \
+ else if (time_before(jiffies, start + 30 * HZ)) \
CDEBUG(D_VFSTRACE, "%s: slow %s %lus\n", obd->obd_name, \
msg, (jiffies-start) / HZ); \
- else if (cfs_time_before(jiffies, start + DISK_TIMEOUT * HZ)) \
+ else if (time_before(jiffies, start + DISK_TIMEOUT * HZ)) \
CWARN("%s: slow %s %lus\n", obd->obd_name, msg, \
(jiffies - start) / HZ); \
else \
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lib.h b/drivers/staging/lustre/lustre/include/linux/lustre_lib.h
index 57f3b01d1a32..0a4c65ae9242 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_lib.h
@@ -49,8 +49,8 @@
# include <linux/sched.h>
# include <linux/signal.h>
# include <linux/types.h>
-# include <linux/lustre_compat25.h>
-# include <linux/lustre_common.h>
+#include "lustre_compat25.h"
+#include "lustre_common.h"
#ifndef LP_POISON
# define LI_POISON 0x5a5a5a5a
diff --git a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
index df9391275617..99eed4987635 100644
--- a/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
+++ b/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
@@ -46,13 +46,13 @@
#include <linux/dcache.h>
#include <linux/proc_fs.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_ha.h>
+#include "../obd_class.h"
+#include "../lustre_net.h"
+#include "../lustre_ha.h"
#include <linux/rbtree.h>
-#include <linux/lustre_compat25.h>
-#include <linux/lustre_common.h>
+#include "../../include/linux/lustre_compat25.h"
+#include "../../include/linux/lustre_common.h"
#include <linux/pagemap.h>
/* lprocfs.c */
diff --git a/drivers/staging/lustre/lustre/include/linux/lvfs.h b/drivers/staging/lustre/lustre/include/linux/lvfs.h
index e61f1b87f822..dd1be9c39829 100644
--- a/drivers/staging/lustre/lustre/include/linux/lvfs.h
+++ b/drivers/staging/lustre/lustre/include/linux/lvfs.h
@@ -45,9 +45,9 @@
#error Do not #include this file directly. #include <lvfs.h> instead
#endif
-#include <linux/lustre_compat25.h>
-#include <linux/lustre_common.h>
-#include <linux/lvfs_linux.h>
+#include "lustre_compat25.h"
+#include "lustre_common.h"
+#include "lvfs_linux.h"
#define LLOG_LVFS
diff --git a/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h b/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h
index 140a60f1f0c9..fff22ec1f869 100644
--- a/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h
+++ b/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h
@@ -41,15 +41,10 @@
#include <linux/namei.h>
#include <linux/sched.h>
-#include <lvfs.h>
-
-#define l_file file
-#define l_dentry dentry
-
-#define l_filp_open filp_open
+#include "../lvfs.h"
struct lvfs_run_ctxt;
-struct l_file *l_dentry_open(struct lvfs_run_ctxt *, struct l_dentry *,
+struct file *l_dentry_open(struct lvfs_run_ctxt *, struct dentry *,
int flags);
struct l_linux_dirent {
diff --git a/drivers/staging/lustre/lustre/include/linux/obd.h b/drivers/staging/lustre/lustre/include/linux/obd.h
index f96f65d5168f..2a3a88cbb192 100644
--- a/drivers/staging/lustre/lustre/include/linux/obd.h
+++ b/drivers/staging/lustre/lustre/include/linux/obd.h
@@ -41,14 +41,14 @@
#error Do not #include this file directly. #include <obd.h> instead
#endif
-#include <obd_support.h>
+#include "../obd_support.h"
# include <linux/fs.h>
# include <linux/list.h>
# include <linux/sched.h> /* for struct task_struct, for current.h */
# include <linux/proc_fs.h>
# include <linux/mount.h>
-# include <linux/lustre_intent.h>
+#include "lustre_intent.h"
struct ll_iattr {
struct iattr iattr;
diff --git a/drivers/staging/lustre/lustre/include/linux/obd_support.h b/drivers/staging/lustre/lustre/include/linux/obd_support.h
index 9166503408aa..ea03b8434f62 100644
--- a/drivers/staging/lustre/lustre/include/linux/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/linux/obd_support.h
@@ -50,14 +50,14 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/swap.h>
-#include <linux/lustre_compat25.h>
-#include <linux/lustre_common.h>
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
+#include "../../include/linux/lustre_compat25.h"
+#include "lustre_common.h"
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "../lustre/lustre_idl.h"
# include <linux/types.h>
# include <linux/blkdev.h>
-# include <lvfs.h>
+# include "../lvfs.h"
#endif
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index 1b7f6a9bf62c..16b3d6887ff6 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -42,9 +42,8 @@
#ifndef _LPROCFS_SNMP_H
#define _LPROCFS_SNMP_H
-#include <linux/lprocfs_status.h>
-#include <lustre/lustre_idl.h>
-#include <linux/libcfs/params_tree.h>
+#include "linux/lprocfs_status.h"
+#include "lustre/lustre_idl.h"
struct lprocfs_vars {
const char *name;
@@ -375,7 +374,7 @@ extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
int *val, int mult);
extern int lprocfs_read_frac_helper(char *buffer, unsigned long count,
long val, int mult);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats,
unsigned int cpuid);
@@ -605,7 +604,7 @@ extern int lprocfs_obd_seq_create(struct obd_device *dev, const char *name,
extern int lprocfs_rd_u64(struct seq_file *m, void *data);
extern int lprocfs_rd_atomic(struct seq_file *m, void *data);
-extern int lprocfs_wr_atomic(struct file *file, const char *buffer,
+extern int lprocfs_wr_atomic(struct file *file, const char __user *buffer,
unsigned long count, void *data);
extern int lprocfs_rd_uint(struct seq_file *m, void *data);
extern int lprocfs_wr_uint(struct file *file, const char *buffer,
@@ -662,8 +661,8 @@ unsigned long lprocfs_oh_sum(struct obd_histogram *oh);
void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
struct lprocfs_counter *cnt);
-extern int lprocfs_single_release(cfs_inode_t *, struct file *);
-extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
+extern int lprocfs_single_release(struct inode *, struct file *);
+extern int lprocfs_seq_release(struct inode *, struct file *);
/* You must use these macros when you want to refer to
* the import in a client obd_device for a lprocfs entry */
@@ -684,7 +683,7 @@ extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally,
call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */
#define __LPROC_SEQ_FOPS(name, custom_seq_write) \
-static int name##_single_open(cfs_inode_t *inode, struct file *file) \
+static int name##_single_open(struct inode *inode, struct file *file) \
{ \
return single_open(file, name##_seq_show, PDE_DATA(inode)); \
} \
@@ -727,7 +726,7 @@ static struct file_operations name##_fops = { \
{ \
return lprocfs_wr_##type(file, buffer, count, off); \
} \
- static int name##_##type##_open(cfs_inode_t *inode, struct file *file) \
+ static int name##_##type##_open(struct inode *inode, struct file *file) \
{ \
return single_open(file, NULL, PDE_DATA(inode)); \
} \
@@ -806,7 +805,7 @@ extern int lprocfs_quota_wr_qs_factor(struct file *file,
const char *buffer,
unsigned long count, void *data);
#else
-/* LPROCFS is not defined */
+/* CONFIG_PROC_FS is not defined */
#define proc_lustre_root NULL
@@ -1000,6 +999,6 @@ __u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx,
/* lproc_ptlrpc.c */
#define target_print_req NULL
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
#endif /* LPROCFS_SNMP_H */
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index 98149f5da153..d5c368bab5bd 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -38,9 +38,9 @@
#define __LUSTRE_LU_OBJECT_H
#include <stdarg.h>
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
-#include <lu_ref.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "lustre/lustre_idl.h"
+#include "lu_ref.h"
struct seq_file;
struct proc_dir_entry;
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index 83014c9fea65..757146273724 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -91,14 +91,11 @@
#ifndef _LUSTRE_IDL_H_
#define _LUSTRE_IDL_H_
-#if !defined(LPU64)
-#include <linux/libcfs/libcfs.h> /* for LPUX64, etc */
-#endif
+#include "../../../include/linux/libcfs/libcfs.h"
/* Defn's shared with user-space. */
-#include <lustre/lustre_user.h>
-
-#include <lustre/lustre_errno.h>
+#include "lustre_user.h"
+#include "lustre_errno.h"
/*
* GENERAL STUFF
@@ -302,7 +299,7 @@ static inline int range_compare_loc(const struct lu_seq_range *r1,
r1->lsr_flags != r2->lsr_flags;
}
-#define DRANGE "[%#16.16"LPF64"x-%#16.16"LPF64"x):%x:%s"
+#define DRANGE "[%#16.16Lx-%#16.16Lx):%x:%s"
#define PRANGE(range) \
(range)->lsr_start, \
@@ -682,14 +679,14 @@ static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
{
if (fid_seq_is_mdt0(ostid_seq(oi))) {
if (oid >= IDIF_MAX_OID) {
- CERROR("Bad "LPU64" to set "DOSTID"\n",
+ CERROR("Bad %llu to set "DOSTID"\n",
oid, POSTID(oi));
return;
}
oi->oi.oi_id = oid;
} else {
if (oid > OBIF_MAX_OID) {
- CERROR("Bad "LPU64" to set "DOSTID"\n",
+ CERROR("Bad %llu to set "DOSTID"\n",
oid, POSTID(oi));
return;
}
@@ -2748,7 +2745,7 @@ struct ldlm_res_id {
__u64 name[RES_NAME_SIZE];
};
-#define DLDLMRES "["LPX64":"LPX64":"LPX64"]."LPX64i
+#define DLDLMRES "[%#llx:%#llx:%#llx].%llx"
#define PLDLMRES(res) (res)->lr_name.name[0], (res)->lr_name.name[1], \
(res)->lr_name.name[2], (res)->lr_name.name[3]
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
index 95c754f2075f..a69b27a78042 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
@@ -46,8 +46,8 @@
* @{
*/
-#include <lustre/ll_fiemap.h>
-#include <linux/lustre_user.h>
+#include "ll_fiemap.h"
+#include "../linux/lustre_user.h"
/* for statfs() */
#define LL_SUPER_MAGIC 0x0BD00BD0
@@ -179,7 +179,7 @@ struct ost_id {
};
};
-#define DOSTID LPX64":"LPU64
+#define DOSTID "%#llx:%llu"
#define POSTID(oi) ostid_seq(oi), ostid_id(oi)
/*
@@ -475,7 +475,7 @@ static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen)
e.g. printf("file FID is "DFID"\n", PFID(fid)); */
#define FID_NOBRACE_LEN 40
#define FID_LEN (FID_NOBRACE_LEN + 2)
-#define DFID_NOBRACE LPX64":0x%x:0x%x"
+#define DFID_NOBRACE "%#llx:0x%x:0x%x"
#define DFID "["DFID_NOBRACE"]"
#define PFID(fid) \
(fid)->f_seq, \
@@ -484,11 +484,7 @@ static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen)
/* scanf input parse format -- strip '[' first.
e.g. sscanf(fidstr, SFID, RFID(&fid)); */
-/* #define SFID "0x"LPX64i":0x"LPSZX":0x"LPSZX""
-liblustreapi.c:2893: warning: format '%lx' expects type 'long unsigned int *', but argument 4 has type 'unsigned int *'
-liblustreapi.c:2893: warning: format '%lx' expects type 'long unsigned int *', but argument 5 has type 'unsigned int *'
-*/
-#define SFID "0x"LPX64i":0x%x:0x%x"
+#define SFID "0x%llx:0x%x:0x%x"
#define RFID(fid) \
&((fid)->f_seq), \
&((fid)->f_oid), \
diff --git a/drivers/staging/lustre/lustre/include/lustre_acl.h b/drivers/staging/lustre/lustre/include/lustre_acl.h
index 5cfb87b180c3..0b6ea0782229 100644
--- a/drivers/staging/lustre/lustre/include/lustre_acl.h
+++ b/drivers/staging/lustre/lustre/include/lustre_acl.h
@@ -37,6 +37,6 @@
#ifndef _LUSTRE_ACL_H
#define _LUSTRE_ACL_H
-#include <linux/lustre_acl.h>
+#include "linux/lustre_acl.h"
#endif
diff --git a/drivers/staging/lustre/lustre/include/lustre_capa.h b/drivers/staging/lustre/lustre/include/lustre_capa.h
index d77bffc0b59d..ab6b9ea98a70 100644
--- a/drivers/staging/lustre/lustre/include/lustre_capa.h
+++ b/drivers/staging/lustre/lustre/include/lustre_capa.h
@@ -50,7 +50,7 @@
* capability
*/
#include <linux/crypto.h>
-#include <lustre/lustre_idl.h>
+#include "lustre/lustre_idl.h"
#define CAPA_TIMEOUT 1800 /* sec, == 30 min */
#define CAPA_KEY_TIMEOUT (24 * 60 * 60) /* sec, == 1 days */
@@ -82,7 +82,7 @@ struct obd_capa {
struct lustre_capa c_capa; /* capa */
atomic_t c_refc; /* ref count */
- cfs_time_t c_expiry; /* jiffies */
+ unsigned long c_expiry; /* jiffies */
spinlock_t c_lock; /* protect capa content */
int c_site;
@@ -167,7 +167,7 @@ do { \
#define DEBUG_CAPA_KEY(level, k, fmt, args...) \
do { \
-CDEBUG(level, fmt " capability key@%p seq "LPU64" keyid %u\n", \
+CDEBUG(level, fmt " capability key@%p seq %llu keyid %u\n", \
##args, k, capa_key_seq(k), capa_key_keyid(k)); \
} while (0)
@@ -266,20 +266,20 @@ static inline __u64 capa_open_opc(int mode)
static inline void set_capa_expiry(struct obd_capa *ocapa)
{
- cfs_time_t expiry = cfs_time_sub((cfs_time_t)ocapa->c_capa.lc_expiry,
- cfs_time_current_sec());
+ unsigned long expiry = cfs_time_sub((unsigned long)ocapa->c_capa.lc_expiry,
+ get_seconds());
ocapa->c_expiry = cfs_time_add(cfs_time_current(),
cfs_time_seconds(expiry));
}
static inline int capa_is_expired_sec(struct lustre_capa *capa)
{
- return (capa->lc_expiry - cfs_time_current_sec() <= 0);
+ return (capa->lc_expiry - get_seconds() <= 0);
}
static inline int capa_is_expired(struct obd_capa *ocapa)
{
- return cfs_time_beforeq(ocapa->c_expiry, cfs_time_current());
+ return time_before_eq(ocapa->c_expiry, cfs_time_current());
}
static inline int capa_opc_supported(struct lustre_capa *capa, __u64 opc)
diff --git a/drivers/staging/lustre/lustre/include/lustre_cfg.h b/drivers/staging/lustre/lustre/include/lustre_cfg.h
index 3680668a8920..03017fe49d46 100644
--- a/drivers/staging/lustre/lustre/include/lustre_cfg.h
+++ b/drivers/staging/lustre/lustre/include/lustre_cfg.h
@@ -222,7 +222,7 @@ static inline int lustre_cfg_len(__u32 bufcount, __u32 *buflens)
}
-#include <obd_support.h>
+#include "obd_support.h"
static inline struct lustre_cfg *lustre_cfg_new(int cmd,
struct lustre_cfg_bufs *bufs)
@@ -286,7 +286,7 @@ static inline int lustre_cfg_sanity_check(void *buf, int len)
return 0;
}
-#include <lustre/lustre_user.h>
+#include "lustre/lustre_user.h"
/** @} cfg */
diff --git a/drivers/staging/lustre/lustre/include/lustre_debug.h b/drivers/staging/lustre/lustre/include/lustre_debug.h
index 6146ccb8cce0..6c92d0bc943b 100644
--- a/drivers/staging/lustre/lustre/include/lustre_debug.h
+++ b/drivers/staging/lustre/lustre/include/lustre_debug.h
@@ -42,8 +42,8 @@
* @{
*/
-#include <lustre_net.h>
-#include <obd.h>
+#include "lustre_net.h"
+#include "obd.h"
/* lib/debug.c */
void dump_lniobuf(struct niobuf_local *lnb);
diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h
index ac08164793cb..7f191eed2a81 100644
--- a/drivers/staging/lustre/lustre/include/lustre_disk.h
+++ b/drivers/staging/lustre/lustre/include/lustre_disk.h
@@ -48,8 +48,8 @@
* @{
*/
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/types.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/types.h"
#include <linux/backing-dev.h>
/****************** on-disk files *********************/
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index 0c6b7841e56d..30b1812f4bf6 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -48,14 +48,14 @@
#ifndef _LUSTRE_DLM_H__
#define _LUSTRE_DLM_H__
-#include <linux/lustre_dlm.h>
+#include "linux/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"
@@ -441,7 +441,7 @@ struct ldlm_namespace {
* \see ldlm_namespace_dump. Increased by 10 seconds every time
* it is called.
*/
- cfs_time_t ns_next_dump;
+ unsigned long ns_next_dump;
/** "policy" function that does actual lock conflict determination */
ldlm_res_policy ns_policy;
@@ -783,13 +783,13 @@ struct ldlm_lock {
* Seconds. It will be updated if there is any activity related to
* the lock, e.g. enqueue the lock or send blocking AST.
*/
- cfs_time_t l_last_activity;
+ unsigned long l_last_activity;
/**
* Time last used by e.g. being matched by lock match.
* Jiffies. Should be converted to time if needed.
*/
- cfs_time_t l_last_used;
+ unsigned long l_last_used;
/** Originally requested extent for the extent lock. */
struct ldlm_extent l_req_extent;
@@ -837,7 +837,7 @@ struct ldlm_lock {
* under this lock.
* \see ost_rw_prolong_locks
*/
- cfs_time_t l_callback_timeout;
+ unsigned long l_callback_timeout;
/** Local PID of process which created this lock. */
__u32 l_pid;
@@ -951,7 +951,7 @@ struct ldlm_resource {
void *lr_lvb_data;
/** When the resource was considered as contended. */
- cfs_time_t lr_contention_time;
+ unsigned long lr_contention_time;
/** List of references to this resource. For debugging. */
struct lu_ref lr_reference;
@@ -1285,7 +1285,7 @@ void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client);
void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client);
void ldlm_namespace_get(struct ldlm_namespace *ns);
void ldlm_namespace_put(struct ldlm_namespace *ns);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int ldlm_proc_setup(void);
void ldlm_proc_cleanup(void);
#else
@@ -1390,7 +1390,7 @@ int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *head,
int ldlm_cancel_resource_local(struct ldlm_resource *res,
struct list_head *cancels,
ldlm_policy_data_t *policy,
- ldlm_mode_t mode, int lock_flags,
+ ldlm_mode_t mode, __u64 lock_flags,
ldlm_cancel_flags_t cancel_flags, void *opaque);
int ldlm_cli_cancel_list_local(struct list_head *cancels, int count,
ldlm_cancel_flags_t flags);
diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h
index 103f7a8bd83f..e5f8e86cd887 100644
--- a/drivers/staging/lustre/lustre/include/lustre_export.h
+++ b/drivers/staging/lustre/lustre/include/lustre_export.h
@@ -46,9 +46,9 @@
* @{
*/
-#include <lprocfs_status.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_dlm.h>
+#include "lprocfs_status.h"
+#include "lustre/lustre_idl.h"
+#include "lustre_dlm.h"
struct mds_client_data;
struct mdt_client_data;
@@ -209,7 +209,7 @@ struct obd_export {
/** Last committed transno for this export */
__u64 exp_last_committed;
/** When was last request received */
- cfs_time_t exp_last_request_time;
+ unsigned long exp_last_request_time;
/** On replay all requests waiting for replay are linked here */
struct list_head exp_req_replay_queue;
/**
@@ -245,7 +245,7 @@ struct obd_export {
enum lustre_sec_part exp_sp_peer;
struct sptlrpc_flavor exp_flvr; /* current */
struct sptlrpc_flavor exp_flvr_old[2]; /* about-to-expire */
- cfs_time_t exp_flvr_expire[2]; /* seconds */
+ unsigned long exp_flvr_expire[2]; /* seconds */
/** protects exp_hp_rpcs */
spinlock_t exp_rpc_lock;
@@ -294,11 +294,11 @@ static inline int exp_connect_multibulk(struct obd_export *exp)
return exp_max_brw_size(exp) > ONE_MB_BRW_SIZE;
}
-static inline int exp_expired(struct obd_export *exp, cfs_duration_t age)
+static inline int exp_expired(struct obd_export *exp, long age)
{
LASSERT(exp->exp_delayed);
- return cfs_time_before(cfs_time_add(exp->exp_last_request_time, age),
- cfs_time_current_sec());
+ return time_before(cfs_time_add(exp->exp_last_request_time, age),
+ get_seconds());
}
static inline int exp_connect_cancelset(struct obd_export *exp)
diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h
index 5e7b3165a851..ffb00f171240 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fid.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fid.h
@@ -152,8 +152,8 @@
* Even so, the MDT and OST resources are also in different LDLM namespaces.
*/
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "lustre/lustre_idl.h"
struct lu_env;
struct lu_site;
@@ -312,7 +312,7 @@ static inline void lu_last_id_fid(struct lu_fid *fid, __u64 seq)
fid->f_seq = fid_idif_seq(0, 0);
} else {
LASSERTF(fid_seq_is_norm(seq) || fid_seq_is_echo(seq) ||
- fid_seq_is_idif(seq), LPX64"\n", seq);
+ fid_seq_is_idif(seq), "%#llx\n", seq);
fid->f_seq = seq;
}
fid->f_oid = 0;
diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h
index 550fff587458..ce6330f9bb50 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fld.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fld.h
@@ -42,8 +42,8 @@
* @{
*/
-#include <lustre/lustre_idl.h>
-#include <linux/libcfs/libcfs.h>
+#include "lustre/lustre_idl.h"
+#include "../../include/linux/libcfs/libcfs.h"
struct lu_client_fld;
struct lu_server_fld;
diff --git a/drivers/staging/lustre/lustre/include/lustre_fsfilt.h b/drivers/staging/lustre/lustre/include/lustre_fsfilt.h
index 9dcc332cb2f3..9749c3f5568e 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fsfilt.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fsfilt.h
@@ -41,7 +41,7 @@
#ifndef _LUSTRE_FSFILT_H
#define _LUSTRE_FSFILT_H
-#include <linux/lustre_fsfilt.h>
+#include "../include/linux/lustre_fsfilt.h"
#define LU221_BAD_TIME (0x80000000U + 24 * 3600)
diff --git a/drivers/staging/lustre/lustre/include/lustre_handles.h b/drivers/staging/lustre/lustre/include/lustre_handles.h
index fcd40f33426a..94989c5e361f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_handles.h
+++ b/drivers/staging/lustre/lustre/include/lustre_handles.h
@@ -42,9 +42,9 @@
* @{
*/
-#include <linux/lustre_handles.h>
+#include "linux/lustre_handles.h"
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
struct portals_handle_ops {
diff --git a/drivers/staging/lustre/lustre/include/lustre_idmap.h b/drivers/staging/lustre/lustre/include/lustre_idmap.h
index 2da859691d6a..5624b8bae919 100644
--- a/drivers/staging/lustre/lustre/include/lustre_idmap.h
+++ b/drivers/staging/lustre/lustre/include/lustre_idmap.h
@@ -47,7 +47,7 @@
* @{
*/
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#define CFS_NGROUPS_PER_BLOCK ((int)(PAGE_CACHE_SIZE / sizeof(gid_t)))
diff --git a/drivers/staging/lustre/lustre/include/lustre_import.h b/drivers/staging/lustre/lustre/include/lustre_import.h
index 01ed786b40b9..8304a55b92f9 100644
--- a/drivers/staging/lustre/lustre/include/lustre_import.h
+++ b/drivers/staging/lustre/lustre/include/lustre_import.h
@@ -47,8 +47,8 @@
* @{
*/
-#include <lustre_handles.h>
-#include <lustre/lustre_idl.h>
+#include "lustre_handles.h"
+#include "lustre/lustre_idl.h"
/**
@@ -200,7 +200,7 @@ struct obd_import {
*/
struct ptlrpc_sec *imp_sec;
struct mutex imp_sec_mutex;
- cfs_time_t imp_sec_expire;
+ unsigned long imp_sec_expire;
/** @} */
/** Wait queue for those who need to wait for recovery completion */
@@ -247,7 +247,7 @@ struct obd_import {
*/
struct lustre_handle imp_remote_handle;
/** When to perform next ping. time in jiffies. */
- cfs_time_t imp_next_ping;
+ unsigned long imp_next_ping;
/** When we last successfully connected. time in 64bit jiffies */
__u64 imp_last_success_conn;
@@ -350,7 +350,7 @@ static inline void at_reset(struct adaptive_timeout *at, int val) {
spin_lock(&at->at_lock);
at->at_current = val;
at->at_worst_ever = val;
- at->at_worst_time = cfs_time_current_sec();
+ at->at_worst_time = get_seconds();
spin_unlock(&at->at_lock);
}
static inline void at_init(struct adaptive_timeout *at, int val, int flags) {
diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 3c26bbdc44b7..de493fabab46 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -46,20 +46,20 @@
* @{
*/
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_ver.h>
-#include <lustre_cfg.h>
-#include <linux/lustre_lib.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "lustre/lustre_idl.h"
+#include "lustre_ver.h"
+#include "lustre_cfg.h"
+#include "linux/lustre_lib.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 <lvfs.h>
+#include "lustre_ha.h"
+#include "lustre_net.h"
+#include "lvfs.h"
int target_pack_pool_reply(struct ptlrpc_request *req);
@@ -241,7 +241,7 @@ static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
}
-#include <obd_support.h>
+#include "obd_support.h"
/* function defined in lustre/obdclass/<platform>/<platform>-module.c */
int obd_ioctl_getdata(char **buf, int *len, void *arg);
@@ -459,8 +459,8 @@ static inline int back_to_sleep(void *arg)
#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
struct l_wait_info {
- cfs_duration_t lwi_timeout;
- cfs_duration_t lwi_interval;
+ long lwi_timeout;
+ long lwi_interval;
int lwi_allow_intr;
int (*lwi_on_timeout)(void *);
void (*lwi_on_signal)(void *);
@@ -516,7 +516,7 @@ struct l_wait_info {
#define __l_wait_event(wq, condition, info, ret, l_add_wait) \
do { \
wait_queue_t __wait; \
- cfs_duration_t __timeout = info->lwi_timeout; \
+ long __timeout = info->lwi_timeout; \
sigset_t __blocked; \
int __allow_intr = info->lwi_allow_intr; \
\
@@ -548,11 +548,11 @@ do { \
if (__timeout == 0) { \
schedule(); \
} else { \
- cfs_duration_t interval = info->lwi_interval? \
- min_t(cfs_duration_t, \
+ long interval = info->lwi_interval? \
+ min_t(long, \
info->lwi_interval,__timeout):\
__timeout; \
- cfs_duration_t remaining = schedule_timeout(interval);\
+ long remaining = schedule_timeout(interval);\
__timeout = cfs_time_sub(__timeout, \
cfs_time_sub(interval, remaining));\
if (__timeout == 0) { \
diff --git a/drivers/staging/lustre/lustre/include/lustre_lite.h b/drivers/staging/lustre/lustre/include/lustre_lite.h
index beccb5e4065f..eee900638720 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lite.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lite.h
@@ -42,19 +42,19 @@
* @{
*/
-#include <linux/lustre_lite.h>
+#include "linux/lustre_lite.h"
-#include <obd_class.h>
-#include <obd_ost.h>
-#include <lustre_net.h>
-#include <lustre_mds.h>
-#include <lustre_ha.h>
+#include "obd_class.h"
+#include "obd_ost.h"
+#include "lustre_net.h"
+#include "lustre_mds.h"
+#include "lustre_ha.h"
/* 4UL * 1024 * 1024 */
#define LL_MAX_BLKSIZE_BITS (22)
#define LL_MAX_BLKSIZE (1UL<<LL_MAX_BLKSIZE_BITS)
-#include <lustre/lustre_user.h>
+#include "lustre/lustre_user.h"
struct lustre_rw_params {
diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h
index 1a9a9228b795..d02ea24a7e40 100644
--- a/drivers/staging/lustre/lustre/include/lustre_log.h
+++ b/drivers/staging/lustre/lustre/include/lustre_log.h
@@ -56,12 +56,12 @@
* @{
*/
-#include <linux/lustre_log.h>
+#include "linux/lustre_log.h"
-#include <obd_class.h>
-#include <obd_ost.h>
-#include <lustre/lustre_idl.h>
-#include <dt_object.h>
+#include "obd_class.h"
+#include "obd_ost.h"
+#include "lustre/lustre_idl.h"
+#include "dt_object.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 66765d4d201d..39bbc3634b06 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mdc.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h
@@ -50,14 +50,14 @@
#include <linux/fs.h>
#include <linux/dcache.h>
-#include <linux/lustre_intent.h>
-#include <lustre_handles.h>
-#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 "linux/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"
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 b386f87471e3..f0cce41c55c0 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mds.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mds.h
@@ -47,12 +47,12 @@
* @{
*/
-#include <lustre_handles.h>
-#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 "../../include/linux/libcfs/libcfs.h"
+#include "lustre/lustre_idl.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 f6b7d10cb78c..d6af2ca3acdb 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -55,21 +55,21 @@
* @{
*/
-#include <linux/lustre_net.h>
+#include "linux/lustre_net.h"
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
// #include <obd.h>
-#include <linux/lnet/lnet.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 "../../include/linux/lnet/lnet.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"
/* MD flags we _always_ use */
#define PTLRPC_MD_OPTIONS 0
@@ -1591,7 +1591,8 @@ struct ptlrpc_request {
rq_replay:1,
rq_no_resend:1, rq_waiting:1, rq_receiving_reply:1,
rq_no_delay:1, rq_net_err:1, rq_wait_ctx:1,
- rq_early:1, rq_must_unlink:1,
+ rq_early:1,
+ rq_req_unlink:1, rq_reply_unlink:1,
rq_memalloc:1, /* req originated from "kswapd" */
/* server-side flags */
rq_packed_final:1, /* packed final reply */
@@ -1712,9 +1713,9 @@ struct ptlrpc_request {
lnet_handle_md_t rq_req_md_h;
struct ptlrpc_cb_id rq_req_cbid;
/** optional time limit for send attempts */
- cfs_duration_t rq_delay_limit;
+ long rq_delay_limit;
/** time request was first queued */
- cfs_time_t rq_queued_time;
+ unsigned long rq_queued_time;
/* server-side... */
/** request arrival time */
@@ -2355,7 +2356,7 @@ struct ptlrpc_service_part {
/** incoming reqs */
struct list_head scp_req_incoming;
/** timeout before re-posting reqs, in tick */
- cfs_duration_t scp_rqbd_timeout;
+ long scp_rqbd_timeout;
/**
* all threads sleep on this. This wait-queue is signalled when new
* incoming request arrives and when difficult reply has to be handled.
@@ -2406,7 +2407,7 @@ struct ptlrpc_service_part {
/** early reply timer */
struct timer_list scp_at_timer;
/** debug */
- cfs_time_t scp_at_checktime;
+ unsigned long scp_at_checktime;
/** check early replies */
unsigned scp_at_check;
/** @} */
@@ -2593,7 +2594,7 @@ static inline int ptlrpc_client_bulk_active(struct ptlrpc_request *req)
desc = req->rq_bulk;
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_BULK_UNLINK) &&
- req->rq_bulk_deadline > cfs_time_current_sec())
+ req->rq_bulk_deadline > get_seconds())
return 1;
if (!desc)
@@ -3001,7 +3002,7 @@ static inline int
ptlrpc_client_early(struct ptlrpc_request *req)
{
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
- req->rq_reply_deadline > cfs_time_current_sec())
+ req->rq_reply_deadline > get_seconds())
return 0;
return req->rq_early;
}
@@ -3013,7 +3014,7 @@ static inline int
ptlrpc_client_replied(struct ptlrpc_request *req)
{
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
- req->rq_reply_deadline > cfs_time_current_sec())
+ req->rq_reply_deadline > get_seconds())
return 0;
return req->rq_replied;
}
@@ -3023,7 +3024,7 @@ static inline int
ptlrpc_client_recv(struct ptlrpc_request *req)
{
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
- req->rq_reply_deadline > cfs_time_current_sec())
+ req->rq_reply_deadline > get_seconds())
return 1;
return req->rq_receiving_reply;
}
@@ -3035,11 +3036,12 @@ ptlrpc_client_recv_or_unlink(struct ptlrpc_request *req)
spin_lock(&req->rq_lock);
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
- req->rq_reply_deadline > cfs_time_current_sec()) {
+ req->rq_reply_deadline > get_seconds()) {
spin_unlock(&req->rq_lock);
return 1;
}
- rc = req->rq_receiving_reply || req->rq_must_unlink;
+ rc = req->rq_receiving_reply;
+ rc = rc || req->rq_req_unlink || req->rq_reply_unlink;
spin_unlock(&req->rq_lock);
return rc;
}
@@ -3098,9 +3100,9 @@ static inline int ptlrpc_req_get_repsize(struct ptlrpc_request *req)
static inline int ptlrpc_send_limit_expired(struct ptlrpc_request *req)
{
if (req->rq_delay_limit != 0 &&
- cfs_time_before(cfs_time_add(req->rq_queued_time,
- cfs_time_seconds(req->rq_delay_limit)),
- cfs_time_current())) {
+ time_before(cfs_time_add(req->rq_queued_time,
+ cfs_time_seconds(req->rq_delay_limit)),
+ cfs_time_current())) {
return 1;
}
return 0;
@@ -3227,7 +3229,7 @@ void ptlrpcd_decref(void);
* @{
*/
const char* ll_opcode2str(__u32 opcode);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void ptlrpc_lprocfs_register_obd(struct obd_device *obd);
void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd);
void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes);
diff --git a/drivers/staging/lustre/lustre/include/lustre_quota.h b/drivers/staging/lustre/lustre/include/lustre_quota.h
index 07cb7c310bcc..1ae72e3ff1bf 100644
--- a/drivers/staging/lustre/lustre/include/lustre_quota.h
+++ b/drivers/staging/lustre/lustre/include/lustre_quota.h
@@ -32,11 +32,11 @@
*
*/
-#include <linux/lustre_quota.h>
+#include "linux/lustre_quota.h"
-#include <dt_object.h>
-#include <lustre_fid.h>
-#include <lustre_dlm.h>
+#include "dt_object.h"
+#include "lustre_fid.h"
+#include "lustre_dlm.h"
#ifndef MAX_IQ_TIME
#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
diff --git a/drivers/staging/lustre/lustre/include/lustre_req_layout.h b/drivers/staging/lustre/lustre/include/lustre_req_layout.h
index a83db61a30be..c6457b27c4e7 100644
--- a/drivers/staging/lustre/lustre/include/lustre_req_layout.h
+++ b/drivers/staging/lustre/lustre/include/lustre_req_layout.h
@@ -73,7 +73,7 @@ struct req_capsule {
#if !defined(__REQ_LAYOUT_USER__)
/* struct ptlrpc_request, lustre_msg* */
-#include <lustre_net.h>
+#include "lustre_net.h"
void req_capsule_init(struct req_capsule *pill, struct ptlrpc_request *req,
enum req_location location);
diff --git a/drivers/staging/lustre/lustre/include/lustre_sec.h b/drivers/staging/lustre/lustre/include/lustre_sec.h
index bf3ee3915c28..dc31bf93a1d7 100644
--- a/drivers/staging/lustre/lustre/include/lustre_sec.h
+++ b/drivers/staging/lustre/lustre/include/lustre_sec.h
@@ -387,7 +387,7 @@ struct ptlrpc_ctx_ops {
/**
* Force the \a ctx to die.
*/
- void (*die) (struct ptlrpc_cli_ctx *ctx,
+ void (*force_die) (struct ptlrpc_cli_ctx *ctx,
int grace);
int (*display) (struct ptlrpc_cli_ctx *ctx,
char *buf, int bufsize);
@@ -510,7 +510,7 @@ struct ptlrpc_cli_ctx {
atomic_t cc_refcount;
struct ptlrpc_sec *cc_sec;
struct ptlrpc_ctx_ops *cc_ops;
- cfs_time_t cc_expire; /* in seconds */
+ unsigned long cc_expire; /* in seconds */
unsigned int cc_early_expire:1;
unsigned long cc_flags;
struct vfs_cred cc_vcred;
@@ -835,8 +835,8 @@ struct ptlrpc_sec {
* garbage collection
*/
struct list_head ps_gc_list;
- cfs_time_t ps_gc_interval; /* in seconds */
- cfs_time_t ps_gc_next; /* in seconds */
+ unsigned long ps_gc_interval; /* in seconds */
+ unsigned long ps_gc_next; /* in seconds */
};
static inline int sec_is_reverse(struct ptlrpc_sec *sec)
@@ -1064,7 +1064,7 @@ const char * sec2target_str(struct ptlrpc_sec *sec);
/*
* lprocfs
*/
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
struct proc_dir_entry;
extern struct proc_dir_entry *sptlrpc_proc_root;
int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev);
diff --git a/drivers/staging/lustre/lustre/include/lvfs.h b/drivers/staging/lustre/lustre/include/lvfs.h
index 28f1a6b76f73..32dcd57c47cc 100644
--- a/drivers/staging/lustre/lustre/include/lvfs.h
+++ b/drivers/staging/lustre/lustre/include/lvfs.h
@@ -41,10 +41,10 @@
#define LL_FID_NAMELEN (16 + 1 + 8 + 1)
-#include <linux/libcfs/libcfs.h>
-#include <linux/lvfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "linux/lvfs.h"
-#include <linux/libcfs/lucache.h>
+#include "../../include/linux/libcfs/lucache.h"
/* lvfs_common.c */
diff --git a/drivers/staging/lustre/lustre/include/md_object.h b/drivers/staging/lustre/lustre/include/md_object.h
index ef46b2c461a6..2e5d55030a63 100644
--- a/drivers/staging/lustre/lustre/include/md_object.h
+++ b/drivers/staging/lustre/lustre/include/md_object.h
@@ -56,7 +56,7 @@
/*
* super-class definitions.
*/
-#include <dt_object.h>
+#include "dt_object.h"
struct md_device;
struct md_device_operations;
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index d5c4613f182d..489bdd399627 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -37,7 +37,7 @@
#ifndef __OBD_H
#define __OBD_H
-#include <linux/obd.h>
+#include "linux/obd.h"
#define IOC_OSC_TYPE 'h'
#define IOC_OSC_MIN_NR 20
@@ -48,14 +48,13 @@
#define IOC_MDC_MIN_NR 20
#define IOC_MDC_MAX_NR 50
-#include <lustre/lustre_idl.h>
-#include <lustre_lib.h>
-#include <linux/libcfs/bitmap.h>
-#include <lu_ref.h>
-#include <lustre_export.h>
-#include <lustre_fid.h>
-#include <lustre_fld.h>
-#include <lustre_capa.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_capa.h"
#define MAX_OBD_DEVICES 8192
@@ -282,7 +281,7 @@ enum llog_ctxt_id {
struct timeout_item {
enum timeout_event ti_event;
- cfs_time_t ti_timeout;
+ unsigned long ti_timeout;
timeout_cb_t ti_cb;
void *ti_cb_data;
struct list_head ti_obd_list;
@@ -338,7 +337,7 @@ struct client_obd {
* See osc_{reserve|unreserve}_grant for details. */
long cl_reserved_grant;
struct list_head cl_cache_waiters; /* waiting for cache/grant */
- cfs_time_t cl_next_shrink_grant; /* jiffies */
+ unsigned long cl_next_shrink_grant; /* jiffies */
struct list_head cl_grant_shrink_list; /* Timeout event list */
int cl_grant_shrink_interval; /* seconds */
diff --git a/drivers/staging/lustre/lustre/include/obd_cksum.h b/drivers/staging/lustre/lustre/include/obd_cksum.h
index 5f740f1743ca..662a78062963 100644
--- a/drivers/staging/lustre/lustre/include/obd_cksum.h
+++ b/drivers/staging/lustre/lustre/include/obd_cksum.h
@@ -34,8 +34,8 @@
#ifndef __OBD_CKSUM
#define __OBD_CKSUM
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "lustre/lustre_idl.h"
static inline unsigned char cksum_obd2cfs(cksum_type_t cksum_type)
{
diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h
index e265820c009f..1d401c9e5e8c 100644
--- a/drivers/staging/lustre/lustre/include/obd_class.h
+++ b/drivers/staging/lustre/lustre/include/obd_class.h
@@ -37,15 +37,15 @@
#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 "lustre/lustre_idl.h"
+#include "lprocfs_status.h"
-#include <linux/obd_class.h>
+#include "linux/obd_class.h"
#define OBD_STATFS_NODELAY 0x0001 /* requests should be send without delay
* and resends for avoid deadlocks */
@@ -141,7 +141,7 @@ int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg);
int class_add_uuid(const char *uuid, __u64 nid);
/*obdecho*/
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars);
#else
static inline void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars)
@@ -347,7 +347,7 @@ do { \
} while (0)
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
#define OBD_COUNTER_OFFSET(op) \
((offsetof(struct obd_ops, o_ ## op) - \
offsetof(struct obd_ops, o_iocontrol)) \
@@ -1160,13 +1160,12 @@ static inline int obd_statfs_async(struct obd_export *exp,
OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP);
OBD_COUNTER_INCREMENT(obd, statfs);
- CDEBUG(D_SUPER, "%s: osfs %p age "LPU64", max_age "LPU64"\n",
+ CDEBUG(D_SUPER, "%s: osfs %p age %llu, max_age %llu\n",
obd->obd_name, &obd->obd_osfs, obd->obd_osfs_age, max_age);
if (cfs_time_before_64(obd->obd_osfs_age, max_age)) {
rc = OBP(obd, statfs_async)(exp, oinfo, max_age, rqset);
} else {
- CDEBUG(D_SUPER,"%s: use %p cache blocks "LPU64"/"LPU64
- " objects "LPU64"/"LPU64"\n",
+ CDEBUG(D_SUPER,"%s: use %p cache blocks %llu/%llu objects %llu/%llu\n",
obd->obd_name, &obd->obd_osfs,
obd->obd_osfs.os_bavail, obd->obd_osfs.os_blocks,
obd->obd_osfs.os_ffree, obd->obd_osfs.os_files);
@@ -1217,7 +1216,7 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp,
OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP);
OBD_COUNTER_INCREMENT(obd, statfs);
- CDEBUG(D_SUPER, "osfs "LPU64", max_age "LPU64"\n",
+ CDEBUG(D_SUPER, "osfs %llu, max_age %llu\n",
obd->obd_osfs_age, max_age);
if (cfs_time_before_64(obd->obd_osfs_age, max_age)) {
rc = OBP(obd, statfs)(env, exp, osfs, max_age, flags);
@@ -1228,8 +1227,7 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp,
spin_unlock(&obd->obd_osfs_lock);
}
} else {
- CDEBUG(D_SUPER, "%s: use %p cache blocks "LPU64"/"LPU64
- " objects "LPU64"/"LPU64"\n",
+ CDEBUG(D_SUPER, "%s: use %p cache blocks %llu/%llu objects %llu/%llu\n",
obd->obd_name, &obd->obd_osfs,
obd->obd_osfs.os_bavail, obd->obd_osfs.os_blocks,
obd->obd_osfs.os_ffree, obd->obd_osfs.os_files);
@@ -1818,7 +1816,7 @@ static inline int md_enqueue(struct obd_export *exp,
struct lustre_handle *lockh,
void *lmm, int lmmsize,
struct ptlrpc_request **req,
- int extra_lock_flags)
+ __u64 extra_lock_flags)
{
int rc;
diff --git a/drivers/staging/lustre/lustre/include/obd_ost.h b/drivers/staging/lustre/lustre/include/obd_ost.h
index af89843c312b..60de42972ec9 100644
--- a/drivers/staging/lustre/lustre/include/obd_ost.h
+++ b/drivers/staging/lustre/lustre/include/obd_ost.h
@@ -43,7 +43,7 @@
#ifndef _LUSTRE_OST_H
#define _LUSTRE_OST_H
-#include <obd_class.h>
+#include "obd_class.h"
struct osc_brw_async_args {
struct obdo *aa_oa;
@@ -87,6 +87,10 @@ struct osc_enqueue_args {
unsigned int oa_agl:1;
};
+extern void osc_update_enqueue(struct lustre_handle *lov_lockhp,
+ struct lov_oinfo *loi, __u64 flags,
+ struct ost_lvb *lvb, __u32 mode, int rc);
+
#if 0
int osc_extent_blocking_cb(struct ldlm_lock *lock,
struct ldlm_lock_desc *new, void *data,
diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h
index cc5af509b261..92c89925ff67 100644
--- a/drivers/staging/lustre/lustre/include/obd_support.h
+++ b/drivers/staging/lustre/lustre/include/obd_support.h
@@ -37,11 +37,10 @@
#ifndef _OBD_SUPPORT
#define _OBD_SUPPORT
-#include <linux/libcfs/libcfs.h>
-#include <lvfs.h>
-#include <lprocfs_status.h>
-
-#include <linux/obd_support.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "lvfs.h"
+#include "lprocfs_status.h"
+#include "linux/obd_support.h"
/* global variables */
extern struct lprocfs_stats *obd_memory;
@@ -509,7 +508,7 @@ extern atomic_t libcfs_kmemory;
extern void obd_update_maxusage(void);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
#define obd_memory_add(size) \
lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size))
#define obd_memory_sub(size) \
@@ -663,7 +662,7 @@ do { \
if (unlikely((ptr) == NULL)) { \
CERROR("vmalloc of '" #ptr "' (%d bytes) failed\n", \
(int)(size)); \
- CERROR(LPU64" total bytes allocated by Lustre, %d by LNET\n", \
+ CERROR("%llu total bytes allocated by Lustre, %d by LNET\n", \
obd_memory_sum(), atomic_read(&libcfs_kmemory)); \
} else { \
OBD_ALLOC_POST(ptr, size, "vmalloced"); \
@@ -823,11 +822,11 @@ do { \
alloc_page(gfp_mask) : \
alloc_pages_node(cfs_cpt_spread_node(cptab, cpt), gfp_mask, 0);\
if (unlikely((ptr) == NULL)) { \
- CERROR("alloc_pages of '" #ptr "' %d page(s) / "LPU64" bytes "\
+ CERROR("alloc_pages of '" #ptr "' %d page(s) / %llu bytes "\
"failed\n", (int)1, \
(__u64)(1 << PAGE_CACHE_SHIFT)); \
- CERROR(LPU64" total bytes and "LPU64" total pages " \
- "("LPU64" bytes) allocated by Lustre, " \
+ CERROR("%llu total bytes and %llu total pages " \
+ "(%llu bytes) allocated by Lustre, " \
"%d total bytes by LNET\n", \
obd_memory_sum(), \
obd_pages_sum() << PAGE_CACHE_SHIFT, \
@@ -836,7 +835,7 @@ do { \
} else { \
obd_pages_add(0); \
CDEBUG(D_MALLOC, "alloc_pages '" #ptr "': %d page(s) / " \
- LPU64" bytes at %p.\n", \
+ "%llu bytes at %p.\n", \
(int)1, \
(__u64)(1 << PAGE_CACHE_SHIFT), ptr); \
} \
@@ -851,7 +850,7 @@ do { \
do { \
LASSERT(ptr); \
obd_pages_sub(0); \
- CDEBUG(D_MALLOC, "free_pages '" #ptr "': %d page(s) / "LPU64" bytes " \
+ CDEBUG(D_MALLOC, "free_pages '" #ptr "': %d page(s) / %llu bytes " \
"at %p.\n", \
(int)1, (__u64)(1 << PAGE_CACHE_SHIFT), \
ptr); \
diff --git a/drivers/staging/lustre/lustre/lclient/glimpse.c b/drivers/staging/lustre/lustre/lclient/glimpse.c
index 7bbca4bf6b82..b9f2bb66de21 100644
--- a/drivers/staging/lustre/lustre/lclient/glimpse.c
+++ b/drivers/staging/lustre/lustre/lclient/glimpse.c
@@ -40,20 +40,20 @@
* Author: Oleg Drokin <oleg.drokin@sun.com>
*/
-#include <linux/libcfs/libcfs.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <obd.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/obd.h"
-# include <lustre_dlm.h>
-# include <lustre_lite.h>
-# include <lustre_mdc.h>
-# include <linux/pagemap.h>
-# include <linux/file.h>
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_mdc.h"
+#include <linux/pagemap.h>
+#include <linux/file.h>
-#include "cl_object.h"
-#include "lclient.h"
-# include "../llite/llite_internal.h"
+#include "../include/cl_object.h"
+#include "../include/lclient.h"
+#include "../llite/llite_internal.h"
static const struct cl_lock_descr whole_file = {
.cld_start = 0,
@@ -177,7 +177,7 @@ static int cl_io_get(struct inode *inode, struct lu_env **envout,
io->ci_obj = clob;
*envout = env;
*ioout = io;
- result = +1;
+ result = 1;
} else
result = PTR_ERR(env);
} else
@@ -204,7 +204,7 @@ int cl_glimpse_size0(struct inode *inode, int agl)
result = cl_io_get(inode, &env, &io, &refcheck);
if (result > 0) {
- again:
+again:
io->ci_verify_layout = 1;
result = cl_io_init(env, io, CIT_MISC, io->ci_obj);
if (result > 0)
diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
index 1b0c216bc568..94f759d0b5ad 100644
--- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
@@ -41,7 +41,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
# include <linux/fs.h>
# include <linux/sched.h>
# include <linux/mm.h>
@@ -50,16 +50,16 @@
# include <linux/pagemap.h>
# include <linux/rbtree.h>
-#include <obd.h>
-#include <obd_support.h>
-#include <lustre_fid.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
-#include <lustre_ver.h>
-#include <lustre_mdc.h>
-#include <cl_object.h>
+#include "../include/obd.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_ver.h"
+#include "../include/lustre_mdc.h"
+#include "../include/cl_object.h"
-#include <lclient.h>
+#include "../include/lclient.h"
#include "../llite/llite_internal.h"
@@ -126,6 +126,7 @@ void ccc_key_fini(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct ccc_thread_info *info = data;
+
OBD_SLAB_FREE_PTR(info, ccc_thread_kmem);
}
@@ -144,6 +145,7 @@ void ccc_session_key_fini(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct ccc_session *session = data;
+
OBD_SLAB_FREE_PTR(session, ccc_session_kmem);
}
@@ -264,7 +266,7 @@ int ccc_req_init(const struct lu_env *env, struct cl_device *dev,
* fails. Access to this environment is serialized by ccc_inode_fini_guard
* mutex.
*/
-static struct lu_env *ccc_inode_fini_env = NULL;
+static struct lu_env *ccc_inode_fini_env;
/**
* A mutex serializing calls to slp_inode_fini() under extreme memory
@@ -572,6 +574,7 @@ void ccc_lock_delete(const struct lu_env *env,
void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice)
{
struct ccc_lock *clk = cl2ccc_lock(slice);
+
OBD_SLAB_FREE_PTR(clk, ccc_lock_kmem);
}
@@ -733,6 +736,7 @@ int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io,
loff_t start, loff_t end)
{
struct cl_object *obj = io->ci_obj;
+
return ccc_io_one_lock_index(env, io, enqflags, mode,
cl_index(obj, start), cl_index(obj, end));
}
@@ -817,11 +821,12 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj,
* linux-2.6.18-128.1.1 miss to do that.
* --bug 17336 */
loff_t size = cl_isize_read(inode);
- unsigned long cur_index = start >> PAGE_CACHE_SHIFT;
+ loff_t cur_index = start >> PAGE_CACHE_SHIFT;
+ loff_t size_index = ((size - 1) >> PAGE_CACHE_SHIFT);
if ((size == 0 && cur_index != 0) ||
- (((size - 1) >> PAGE_CACHE_SHIFT) < cur_index))
- *exceed = 1;
+ size_index < cur_index)
+ *exceed = 1;
}
return result;
} else {
@@ -838,7 +843,7 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj,
if (cl_isize_read(inode) < kms) {
cl_isize_write_nolock(inode, kms);
CDEBUG(D_VFSTRACE,
- DFID" updating i_size "LPU64"\n",
+ DFID" updating i_size %llu\n",
PFID(lu_object_fid(&obj->co_lu)),
(__u64)cl_isize_read(inode));
@@ -1269,7 +1274,7 @@ struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode)
return lov_lsm_get(cl_i2info(inode)->lli_clob);
}
-void inline ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm)
+inline void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm)
{
lov_lsm_put(cl_i2info(inode)->lli_clob, lsm);
}
diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c b/drivers/staging/lustre/lustre/lclient/lcommon_misc.c
index 21de1cd2afba..01bf894d4a87 100644
--- a/drivers/staging/lustre/lustre/lclient/lcommon_misc.c
+++ b/drivers/staging/lustre/lustre/lclient/lcommon_misc.c
@@ -37,13 +37,13 @@
* future).
*
*/
-#include <obd_class.h>
-#include <obd_support.h>
-#include <obd.h>
-#include <cl_object.h>
-#include <lclient.h>
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/obd.h"
+#include "../include/cl_object.h"
+#include "../include/lclient.h"
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
/* Initialize the default and maximum LOV EA and cookie sizes. This allows
@@ -63,7 +63,7 @@ int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp)
if (rc)
return rc;
- stripes = min(desc.ld_tgt_count, (__u32)LOV_MAX_STRIPE_COUNT);
+ stripes = min_t(__u32, desc.ld_tgt_count, LOV_MAX_STRIPE_COUNT);
lsm.lsm_stripe_count = stripes;
easize = obd_size_diskmd(dt_exp, &lsm);
@@ -103,7 +103,7 @@ int cl_ocd_update(struct obd_device *host,
cli = &watched->u.cli;
lco = owner;
flags = cli->cl_import->imp_connect_data.ocd_connect_flags;
- CDEBUG(D_SUPER, "Changing connect_flags: "LPX64" -> "LPX64"\n",
+ CDEBUG(D_SUPER, "Changing connect_flags: %#llx -> %#llx\n",
lco->lco_flags, flags);
mutex_lock(&lco->lco_lock);
lco->lco_flags &= flags;
diff --git a/drivers/staging/lustre/lustre/ldlm/interval_tree.c b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
index 1de1d8eb9b41..a3d7a7292417 100644
--- a/drivers/staging/lustre/lustre/ldlm/interval_tree.c
+++ b/drivers/staging/lustre/lustre/ldlm/interval_tree.c
@@ -38,9 +38,9 @@
* Author: Huang Wei <huangwei@clusterfs.com>
* Author: Jay Xiong <jinshan.xiong@sun.com>
*/
-# include <lustre_dlm.h>
-#include <obd_support.h>
-#include <interval_tree.h>
+#include "../include/lustre_dlm.h"
+#include "../include/obd_support.h"
+#include "../include/interval_tree.h"
enum {
INTERVAL_RED = 0,
diff --git a/drivers/staging/lustre/lustre/ldlm/l_lock.c b/drivers/staging/lustre/lustre/ldlm/l_lock.c
index 32f4d52b5362..cd8ab40e3267 100644
--- a/drivers/staging/lustre/lustre/ldlm/l_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/l_lock.c
@@ -35,10 +35,10 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <lustre_dlm.h>
-#include <lustre_lib.h>
+#include "../include/lustre_dlm.h"
+#include "../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 bde3a82ce0dd..0c09b611f4a6 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
@@ -50,14 +50,12 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-# 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 "../../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 "ldlm_internal.h"
@@ -92,7 +90,7 @@ __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms)
if (lck->l_policy_data.l_extent.end + 1 > kms)
kms = lck->l_policy_data.l_extent.end + 1;
}
- LASSERTF(kms <= old_kms, "kms "LPU64" old_kms "LPU64"\n", kms, old_kms);
+ LASSERTF(kms <= old_kms, "kms %llu old_kms %llu\n", kms, old_kms);
return kms;
}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 986bf384bff7..b798daa094bc 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -56,12 +56,11 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include <lustre_dlm.h>
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_lib.h>
+#include "../include/lustre_dlm.h"
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_lib.h"
#include <linux/list.h>
-
#include "ldlm_internal.h"
int ldlm_flock_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
@@ -261,9 +260,8 @@ ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq,
int splitted = 0;
const struct ldlm_callback_suite null_cbs = { NULL };
- CDEBUG(D_DLMTRACE, "flags %#llx owner "LPU64" pid %u mode %u start "
- LPU64" end "LPU64"\n", *flags,
- new->l_policy_data.l_flock.owner,
+ CDEBUG(D_DLMTRACE, "flags %#llx owner %llu pid %u mode %u start %llu end %llu\n",
+ *flags, new->l_policy_data.l_flock.owner,
new->l_policy_data.l_flock.pid, mode,
req->l_policy_data.l_flock.start,
req->l_policy_data.l_flock.end);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
index 574b2ff43b74..40d3338506ae 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
@@ -53,10 +53,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include <lustre_dlm.h>
-#include <obd_support.h>
-#include <lustre_lib.h>
-
+#include "../include/lustre_dlm.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_lib.h"
#include "ldlm_internal.h"
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
index 8bb59155968f..fda9926bea3b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
@@ -43,12 +43,12 @@
#define DEBUG_SUBSYSTEM S_LDLM
-# 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 "../../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 "ldlm_internal.h"
/* @priority: If non-zero, move the selected connection to the list head.
@@ -74,9 +74,8 @@ static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
if (create) {
OBD_ALLOC(imp_conn, sizeof(*imp_conn));
- if (!imp_conn) {
+ if (!imp_conn)
GOTO(out_put, rc = -ENOMEM);
- }
}
spin_lock(&imp->imp_lock);
@@ -511,14 +510,14 @@ int client_connect_import(const struct lu_env *env,
rc = ptlrpc_connect_import(imp);
if (rc != 0) {
- LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
+ LASSERT(imp->imp_state == LUSTRE_IMP_DISCON);
GOTO(out_ldlm, rc);
}
LASSERT(*exp != NULL && (*exp)->exp_connection);
if (data) {
LASSERTF((ocd->ocd_connect_flags & data->ocd_connect_flags) ==
- ocd->ocd_connect_flags, "old "LPX64", new "LPX64"\n",
+ ocd->ocd_connect_flags, "old %#llx, new %#llx\n",
data->ocd_connect_flags, ocd->ocd_connect_flags);
data->ocd_connect_flags = ocd->ocd_connect_flags;
}
@@ -546,7 +545,7 @@ int client_disconnect_export(struct obd_export *exp)
int rc = 0, err;
if (!obd) {
- CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
+ CERROR("invalid export for disconnect: exp %p cookie %#llx\n",
exp, exp ? exp->exp_handle.h_cookie : -1);
return -EINVAL;
}
@@ -662,33 +661,32 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
struct ptlrpc_reply_state *rs;
struct obd_export *exp;
- if (req->rq_no_reply) {
+ if (req->rq_no_reply)
return;
- }
svcpt = req->rq_rqbd->rqbd_svcpt;
rs = req->rq_reply_state;
if (rs == NULL || !rs->rs_difficult) {
/* no notifiers */
- target_send_reply_msg (req, rc, fail_id);
+ target_send_reply_msg(req, rc, fail_id);
return;
}
/* must be an export if locks saved */
- LASSERT (req->rq_export != NULL);
+ LASSERT(req->rq_export != NULL);
/* req/reply consistent */
LASSERT(rs->rs_svcpt == svcpt);
/* "fresh" reply */
- LASSERT (!rs->rs_scheduled);
- LASSERT (!rs->rs_scheduled_ever);
- LASSERT (!rs->rs_handled);
- LASSERT (!rs->rs_on_net);
- LASSERT (rs->rs_export == NULL);
- LASSERT (list_empty(&rs->rs_obd_list));
- LASSERT (list_empty(&rs->rs_exp_list));
+ LASSERT(!rs->rs_scheduled);
+ LASSERT(!rs->rs_scheduled_ever);
+ LASSERT(!rs->rs_handled);
+ LASSERT(!rs->rs_on_net);
+ LASSERT(rs->rs_export == NULL);
+ LASSERT(list_empty(&rs->rs_obd_list));
+ LASSERT(list_empty(&rs->rs_exp_list));
- exp = class_export_get (req->rq_export);
+ exp = class_export_get(req->rq_export);
/* disable reply scheduling while I'm setting up */
rs->rs_scheduled = 1;
@@ -699,7 +697,7 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
rs->rs_opc = lustre_msg_get_opc(req->rq_reqmsg);
spin_lock(&exp->exp_uncommitted_replies_lock);
- CDEBUG(D_NET, "rs transno = "LPU64", last committed = "LPU64"\n",
+ CDEBUG(D_NET, "rs transno = %llu, last committed = %llu\n",
rs->rs_transno, exp->exp_last_committed);
if (rs->rs_transno > exp->exp_last_committed) {
/* not committed already */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 1b3f5c1eb808..d022666fb705 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -41,10 +41,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-# include <linux/libcfs/libcfs.h>
-# include <linux/lustre_intent.h>
-
-#include <obd_class.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/linux/lustre_intent.h"
+#include "../include/obd_class.h"
#include "ldlm_internal.h"
/* lock types */
@@ -625,8 +624,7 @@ void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc)
LASSERTF(lock->l_policy_data.l_inodebits.bits ==
(MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE |
MDS_INODELOCK_LAYOUT),
- "Inappropriate inode lock bits during "
- "conversion " LPU64 "\n",
+ "Inappropriate inode lock bits during conversion %llu\n",
lock->l_policy_data.l_inodebits.bits);
ldlm_res2desc(lock->l_resource, &desc->l_resource);
@@ -899,7 +897,7 @@ void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode)
void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode)
{
struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0);
- LASSERTF(lock != NULL, "Non-existing lock: "LPX64"\n", lockh->cookie);
+ LASSERTF(lock != NULL, "Non-existing lock: %#llx\n", lockh->cookie);
ldlm_lock_decref_internal(lock, mode);
LDLM_LOCK_PUT(lock);
}
@@ -1351,7 +1349,7 @@ ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
}
out2:
if (rc) {
- LDLM_DEBUG(lock, "matched ("LPU64" "LPU64")",
+ LDLM_DEBUG(lock, "matched (%llu %llu)",
(type == LDLM_PLAIN || type == LDLM_IBITS) ?
res_id->name[2] : policy->l_extent.start,
(type == LDLM_PLAIN || type == LDLM_IBITS) ?
@@ -1370,9 +1368,8 @@ ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
LDLM_LOCK_RELEASE(lock);
} else if (!(flags & LDLM_FL_TEST_LOCK)) {/*less verbose for test-only*/
- LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res "
- LPU64"/"LPU64" ("LPU64" "LPU64")", ns,
- type, mode, res_id->name[0], res_id->name[1],
+ LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res %llu/%llu (%llu %llu)",
+ ns, type, mode, res_id->name[0], res_id->name[1],
(type == LDLM_PLAIN || type == LDLM_IBITS) ?
res_id->name[2] :policy->l_extent.start,
(type == LDLM_PLAIN || type == LDLM_IBITS) ?
@@ -1595,7 +1592,7 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
ldlm_error_t rc = ELDLM_OK;
struct ldlm_interval *node = NULL;
- lock->l_last_activity = cfs_time_current_sec();
+ lock->l_last_activity = get_seconds();
/* policies are not executed on the client or during replay */
if ((*flags & (LDLM_FL_HAS_INTENT|LDLM_FL_REPLAY)) == LDLM_FL_HAS_INTENT
&& !local && ns->ns_policy) {
@@ -2258,9 +2255,9 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
if (resource == NULL) {
libcfs_debug_vmsg2(msgdata, fmt, args,
- " ns: \?\? lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
- "res: \?\? rrc=\?\? type: \?\?\? flags: "LPX64" nid: %s "
- "remote: "LPX64" expref: %d pid: %u timeout: %lu "
+ " ns: \?\? lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
+ "res: \?\? rrc=\?\? type: \?\?\? flags: %#llx nid: %s "
+ "remote: %#llx expref: %d pid: %u timeout: %lu "
"lvb_type: %d\n",
lock,
lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
@@ -2277,10 +2274,10 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
switch (resource->lr_type) {
case LDLM_EXTENT:
libcfs_debug_vmsg2(msgdata, fmt, args,
- " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
- "res: "DLDLMRES" rrc: %d type: %s ["LPU64"->"LPU64"] "
- "(req "LPU64"->"LPU64") flags: "LPX64" nid: %s remote: "
- LPX64" expref: %d pid: %u timeout: %lu lvb_type: %d\n",
+ " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
+ "res: "DLDLMRES" rrc: %d type: %s [%llu->%llu] "
+ "(req %llu->%llu) flags: %#llx nid: %s remote: "
+ "%#llx expref: %d pid: %u timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock), lock,
lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
lock->l_readers, lock->l_writers,
@@ -2300,10 +2297,10 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
case LDLM_FLOCK:
libcfs_debug_vmsg2(msgdata, fmt, args,
- " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+ " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
"res: "DLDLMRES" rrc: %d type: %s pid: %d "
- "["LPU64"->"LPU64"] flags: "LPX64" nid: %s "
- "remote: "LPX64" expref: %d pid: %u timeout: %lu\n",
+ "[%llu->%llu] flags: %#llx nid: %s "
+ "remote: %#llx expref: %d pid: %u timeout: %lu\n",
ldlm_lock_to_ns_name(lock), lock,
lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
lock->l_readers, lock->l_writers,
@@ -2322,9 +2319,9 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
case LDLM_IBITS:
libcfs_debug_vmsg2(msgdata, fmt, args,
- " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
- "res: "DLDLMRES" bits "LPX64" rrc: %d type: %s "
- "flags: "LPX64" nid: %s remote: "LPX64" expref: %d "
+ " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
+ "res: "DLDLMRES" bits %#llx rrc: %d type: %s "
+ "flags: %#llx nid: %s remote: %#llx expref: %d "
"pid: %u timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock),
lock, lock->l_handle.h_cookie,
@@ -2344,9 +2341,9 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
default:
libcfs_debug_vmsg2(msgdata, fmt, args,
- " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
- "res: "DLDLMRES" rrc: %d type: %s flags: "LPX64" "
- "nid: %s remote: "LPX64" expref: %d pid: %u "
+ " ns: %s lock: %p/%#llx lrc: %d/%d,%d mode: %s/%s "
+ "res: "DLDLMRES" rrc: %d type: %s flags: %#llx "
+ "nid: %s remote: %#llx expref: %d pid: %u "
"timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock),
lock, lock->l_handle.h_cookie,
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 7e63cf355cd9..952e10eb6178 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -41,10 +41,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-# include <linux/libcfs/libcfs.h>
-
-#include <lustre_dlm.h>
-#include <obd_class.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/lustre_dlm.h"
+#include "../include/obd_class.h"
#include <linux/list.h>
#include "ldlm_internal.h"
@@ -70,7 +69,7 @@ struct ldlm_cb_async_args {
static struct ldlm_state *ldlm_state;
-inline cfs_time_t round_timeout(cfs_time_t timeout)
+inline unsigned long round_timeout(unsigned long timeout)
{
return cfs_time_seconds((int)cfs_duration_sec(cfs_time_sub(timeout, 0)) + 1);
}
@@ -526,7 +525,7 @@ static inline void ldlm_callback_errmsg(struct ptlrpc_request *req,
struct lustre_handle *handle)
{
DEBUG_REQ((req->rq_no_reply || rc) ? D_WARNING : D_DLMTRACE, req,
- "%s: [nid %s] [rc %d] [lock "LPX64"]",
+ "%s: [nid %s] [rc %d] [lock %#llx]",
msg, libcfs_id2str(req->rq_peer), rc,
handle ? handle->cookie : 0);
if (req->rq_no_reply)
@@ -636,7 +635,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
lock = ldlm_handle2lock_long(&dlm_req->lock_handle[0], 0);
if (!lock) {
- CDEBUG(D_DLMTRACE, "callback on lock "LPX64" - lock "
+ CDEBUG(D_DLMTRACE, "callback on lock %#llx - lock "
"disappeared\n", dlm_req->lock_handle[0].cookie);
rc = ldlm_callback_reply(req, -EINVAL);
ldlm_callback_errmsg(req, "Operate with invalid parameter", rc,
@@ -661,7 +660,7 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
(lock->l_flags & LDLM_FL_BL_DONE)) ||
(lock->l_flags & LDLM_FL_FAILED)) {
LDLM_DEBUG(lock, "callback on lock "
- LPX64" - lock disappeared\n",
+ "%#llx - lock disappeared\n",
dlm_req->lock_handle[0].cookie);
unlock_res_and_lock(lock);
LDLM_LOCK_RELEASE(lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c b/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
index ec29e28624fe..a1fe2c161e38 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
@@ -52,9 +52,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include <lustre_dlm.h>
-#include <obd_support.h>
-#include <lustre_lib.h>
+#include "../include/lustre_dlm.h"
+#include "../include/obd_support.h"
+#include "../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 2cc698179b63..db36b3f46e49 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -97,12 +97,10 @@
#define DEBUG_SUBSYSTEM S_LDLM
-# include <lustre_dlm.h>
-
-#include <cl_object.h>
-
-#include <obd_class.h>
-#include <obd_support.h>
+#include "../include/lustre_dlm.h"
+#include "../include/cl_object.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
#include "ldlm_internal.h"
@@ -336,12 +334,12 @@ static int ldlm_srv_pool_recalc(struct ldlm_pool *pl)
{
time_t recalc_interval_sec;
- recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
+ recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
if (recalc_interval_sec < pl->pl_recalc_period)
return 0;
spin_lock(&pl->pl_lock);
- recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
+ recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
if (recalc_interval_sec < pl->pl_recalc_period) {
spin_unlock(&pl->pl_lock);
return 0;
@@ -362,7 +360,7 @@ static int ldlm_srv_pool_recalc(struct ldlm_pool *pl)
*/
ldlm_pool_recalc_grant_plan(pl);
- pl->pl_recalc_time = cfs_time_current_sec();
+ pl->pl_recalc_time = get_seconds();
lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
recalc_interval_sec);
spin_unlock(&pl->pl_lock);
@@ -473,7 +471,7 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
{
time_t recalc_interval_sec;
- recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
+ recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
if (recalc_interval_sec < pl->pl_recalc_period)
return 0;
@@ -481,7 +479,7 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
/*
* Check if we need to recalc lists now.
*/
- recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
+ recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
if (recalc_interval_sec < pl->pl_recalc_period) {
spin_unlock(&pl->pl_lock);
return 0;
@@ -492,7 +490,7 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
*/
ldlm_cli_pool_pop_slv(pl);
- pl->pl_recalc_time = cfs_time_current_sec();
+ pl->pl_recalc_time = get_seconds();
lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
recalc_interval_sec);
spin_unlock(&pl->pl_lock);
@@ -566,7 +564,7 @@ int ldlm_pool_recalc(struct ldlm_pool *pl)
time_t recalc_interval_sec;
int count;
- recalc_interval_sec = cfs_time_current_sec() - pl->pl_recalc_time;
+ recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
if (recalc_interval_sec <= 0)
goto recalc;
@@ -591,7 +589,7 @@ int ldlm_pool_recalc(struct ldlm_pool *pl)
lprocfs_counter_add(pl->pl_stats, LDLM_POOL_RECALC_STAT,
count);
}
- recalc_interval_sec = pl->pl_recalc_time - cfs_time_current_sec() +
+ recalc_interval_sec = pl->pl_recalc_time - get_seconds() +
pl->pl_recalc_period;
return recalc_interval_sec;
@@ -638,7 +636,7 @@ int ldlm_pool_setup(struct ldlm_pool *pl, int limit)
}
EXPORT_SYMBOL(ldlm_pool_setup);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
{
int granted, grant_rate, cancel_rate, grant_step;
@@ -661,8 +659,8 @@ static int lprocfs_pool_state_seq_show(struct seq_file *m, void *unused)
spin_unlock(&pl->pl_lock);
seq_printf(m, "LDLM pool state (%s):\n"
- " SLV: "LPU64"\n"
- " CLV: "LPU64"\n"
+ " SLV: %llu\n"
+ " CLV: %llu\n"
" LVF: %d\n",
pl->pl_name, slv, clv, lvf);
@@ -823,14 +821,14 @@ static void ldlm_pool_proc_fini(struct ldlm_pool *pl)
pl->pl_proc_dir = NULL;
}
}
-#else /* !LPROCFS */
+#else /* !CONFIG_PROC_FS */
static int ldlm_pool_proc_init(struct ldlm_pool *pl)
{
return 0;
}
static void ldlm_pool_proc_fini(struct ldlm_pool *pl) {}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
int idx, ldlm_side_t client)
@@ -839,7 +837,7 @@ int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
spin_lock_init(&pl->pl_lock);
atomic_set(&pl->pl_granted, 0);
- pl->pl_recalc_time = cfs_time_current_sec();
+ pl->pl_recalc_time = get_seconds();
atomic_set(&pl->pl_lock_volume_factor, 1);
atomic_set(&pl->pl_grant_rate, 0);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index fcc7a99ce395..8867dc175325 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -61,9 +61,9 @@
#define DEBUG_SUBSYSTEM S_LDLM
-#include <lustre_dlm.h>
-#include <obd_class.h>
-#include <obd.h>
+#include "../include/lustre_dlm.h"
+#include "../include/obd_class.h"
+#include "../include/obd.h"
#include "ldlm_internal.h"
@@ -95,18 +95,18 @@ int ldlm_expired_completion_wait(void *data)
struct obd_device *obd;
if (lock->l_conn_export == NULL) {
- static cfs_time_t next_dump = 0, last_dump = 0;
+ static unsigned long next_dump = 0, last_dump = 0;
LCONSOLE_WARN("lock timed out (enqueued at "CFS_TIME_T", "
CFS_DURATION_T"s ago)\n",
lock->l_last_activity,
- cfs_time_sub(cfs_time_current_sec(),
+ cfs_time_sub(get_seconds(),
lock->l_last_activity));
LDLM_DEBUG(lock, "lock timed out (enqueued at "CFS_TIME_T", "
CFS_DURATION_T"s ago); not entering recovery in "
"server code, just going back to sleep",
lock->l_last_activity,
- cfs_time_sub(cfs_time_current_sec(),
+ cfs_time_sub(get_seconds(),
lock->l_last_activity));
if (cfs_time_after(cfs_time_current(), next_dump)) {
last_dump = next_dump;
@@ -125,7 +125,7 @@ int ldlm_expired_completion_wait(void *data)
LDLM_ERROR(lock, "lock timed out (enqueued at "CFS_TIME_T", "
CFS_DURATION_T"s ago), entering recovery for %s@%s",
lock->l_last_activity,
- cfs_time_sub(cfs_time_current_sec(), lock->l_last_activity),
+ cfs_time_sub(get_seconds(), lock->l_last_activity),
obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
return 0;
@@ -160,7 +160,7 @@ static int ldlm_completion_tail(struct ldlm_lock *lock)
LDLM_DEBUG(lock, "client-side enqueue: destroyed");
result = -EIO;
} else {
- delay = cfs_time_sub(cfs_time_current_sec(),
+ delay = cfs_time_sub(get_seconds(),
lock->l_last_activity);
LDLM_DEBUG(lock, "client-side enqueue: granted after "
CFS_DURATION_T"s", delay);
@@ -592,7 +592,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
LDLM_FL_NO_TIMEOUT);
unlock_res_and_lock(lock);
- CDEBUG(D_INFO, "local: %p, remote cookie: "LPX64", flags: 0x%llx\n",
+ CDEBUG(D_INFO, "local: %p, remote cookie: %#llx, flags: 0x%llx\n",
lock, reply->lock_handle.cookie, *flags);
/* If enqueue returned a blocked lock but the completion handler has
@@ -1276,8 +1276,7 @@ int ldlm_cli_update_pool(struct ptlrpc_request *req)
* server-side namespace is not possible. */
if (lustre_msg_get_slv(req->rq_repmsg) == 0 ||
lustre_msg_get_limit(req->rq_repmsg) == 0) {
- DEBUG_REQ(D_HA, req, "Zero SLV or Limit found "
- "(SLV: "LPU64", Limit: %u)",
+ DEBUG_REQ(D_HA, req, "Zero SLV or Limit found (SLV: %llu, Limit: %u)",
lustre_msg_get_slv(req->rq_repmsg),
lustre_msg_get_limit(req->rq_repmsg));
return 0;
@@ -1447,10 +1446,10 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns,
int unused, int added,
int count)
{
- cfs_time_t cur = cfs_time_current();
+ unsigned long cur = cfs_time_current();
struct ldlm_pool *pl = &ns->ns_pool;
__u64 slv, lvf, lv;
- cfs_time_t la;
+ unsigned long la;
/* Stop LRU processing when we reach past @count or have checked all
* locks in LRU. */
@@ -1508,9 +1507,8 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns,
{
/* Stop LRU processing if young lock is found and we reach past count */
return ((added >= count) &&
- cfs_time_before(cfs_time_current(),
- cfs_time_add(lock->l_last_used,
- ns->ns_max_age))) ?
+ time_before(cfs_time_current(),
+ cfs_time_add(lock->l_last_used, ns->ns_max_age))) ?
LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK;
}
@@ -1768,7 +1766,7 @@ int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr,
int ldlm_cancel_resource_local(struct ldlm_resource *res,
struct list_head *cancels,
ldlm_policy_data_t *policy,
- ldlm_mode_t mode, int lock_flags,
+ ldlm_mode_t mode, __u64 lock_flags,
ldlm_cancel_flags_t cancel_flags, void *opaque)
{
struct ldlm_lock *lock;
@@ -1894,7 +1892,7 @@ int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
res = ldlm_resource_get(ns, NULL, res_id, 0, 0);
if (res == NULL) {
/* This is not a problem. */
- CDEBUG(D_INFO, "No resource "LPU64"\n", res_id->name[0]);
+ CDEBUG(D_INFO, "No resource %llu\n", res_id->name[0]);
return 0;
}
@@ -2105,8 +2103,8 @@ static int replay_lock_interpret(const struct lu_env *env,
lock = ldlm_handle2lock(&aa->lock_handle);
if (!lock) {
- CERROR("received replay ack for unknown local cookie "LPX64
- " remote cookie "LPX64 " from server %s id %s\n",
+ CERROR("received replay ack for unknown local cookie %#llx"
+ " remote cookie %#llx from server %s id %s\n",
aa->lock_handle.cookie, reply->lock_handle.cookie,
req->rq_export->exp_client_uuid.uuid,
libcfs_id2str(req->rq_peer));
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index c55d72f79b26..efd45e513416 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -40,10 +40,9 @@
*/
#define DEBUG_SUBSYSTEM S_LDLM
-# include <lustre_dlm.h>
-
-#include <lustre_fid.h>
-#include <obd_class.h>
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_fid.h"
+#include "../include/obd_class.h"
#include "ldlm_internal.h"
struct kmem_cache *ldlm_resource_slab, *ldlm_lock_slab;
@@ -72,7 +71,7 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay;
* DDOS. */
unsigned int ldlm_dump_granted_max = 256;
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
@@ -190,13 +189,15 @@ static int lprocfs_lru_size_seq_show(struct seq_file *m, void *v)
return lprocfs_rd_uint(m, nr);
}
-static ssize_t lprocfs_lru_size_seq_write(struct file *file, const char *buffer,
- size_t count, loff_t *off)
+static ssize_t lprocfs_lru_size_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
- char dummy[MAX_STRING_SIZE + 1], *end;
+ char dummy[MAX_STRING_SIZE + 1];
unsigned long tmp;
int lru_resize;
+ int err;
dummy[MAX_STRING_SIZE] = '\0';
if (copy_from_user(dummy, buffer, MAX_STRING_SIZE))
@@ -228,8 +229,8 @@ static ssize_t lprocfs_lru_size_seq_write(struct file *file, const char *buffer,
return count;
}
- tmp = simple_strtoul(dummy, &end, 0);
- if (dummy == end) {
+ err = kstrtoul(dummy, 10, &tmp);
+ if (err != 0) {
CERROR("invalid value written\n");
return -EINVAL;
}
@@ -382,12 +383,12 @@ int ldlm_namespace_proc_register(struct ldlm_namespace *ns)
return 0;
}
#undef MAX_STRING_SIZE
-#else /* LPROCFS */
+#else /* CONFIG_PROC_FS */
#define ldlm_namespace_proc_unregister(ns) ({;})
#define ldlm_namespace_proc_register(ns) ({0;})
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
static unsigned ldlm_res_hop_hash(struct cfs_hash *hs,
const void *key, unsigned mask)
@@ -854,9 +855,8 @@ void ldlm_namespace_free_prior(struct ldlm_namespace *ns,
{
int rc;
- if (!ns) {
+ if (!ns)
return;
- }
spin_lock(&ns->ns_lock);
ns->ns_stopping = 1;
@@ -888,9 +888,8 @@ void ldlm_namespace_free_prior(struct ldlm_namespace *ns,
*/
void ldlm_namespace_free_post(struct ldlm_namespace *ns)
{
- if (!ns) {
+ if (!ns)
return;
- }
/* Make sure that nobody can find this ns in its list. */
ldlm_namespace_unregister(ns, ns->ns_client);
@@ -1135,9 +1134,9 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CREATE_RESOURCE, 2);
rc = ns->ns_lvbo->lvbo_init(res);
if (rc < 0) {
- CERROR("%s: lvbo_init failed for resource "LPX64":"
- LPX64": rc = %d\n", ns->ns_obd->obd_name,
- name->name[0], name->name[1], rc);
+ CERROR("%s: lvbo_init failed for resource %#llx:%#llx: rc = %d\n",
+ ns->ns_obd->obd_name, name->name[0],
+ name->name[1], rc);
if (res->lr_lvb_data) {
OBD_FREE(res->lr_lvb_data, res->lr_lvb_len);
res->lr_lvb_data = NULL;
@@ -1371,7 +1370,7 @@ void ldlm_namespace_dump(int level, struct ldlm_namespace *ns)
ldlm_ns_name(ns), atomic_read(&ns->ns_bref),
ns_is_client(ns) ? "client" : "server");
- if (cfs_time_before(cfs_time_current(), ns->ns_next_dump))
+ if (time_before(cfs_time_current(), ns->ns_next_dump))
return;
cfs_hash_for_each_nolock(ns->ns_rs_hash,
diff --git a/drivers/staging/lustre/lustre/libcfs/Makefile b/drivers/staging/lustre/lustre/libcfs/Makefile
index 6e489d7aaa8b..aeeaab73a1fd 100644
--- a/drivers/staging/lustre/lustre/libcfs/Makefile
+++ b/drivers/staging/lustre/lustre/libcfs/Makefile
@@ -16,6 +16,3 @@ libcfs-all-objs := debug.o fail.o nidstrings.o module.o tracefile.o \
libcfs_mem.o libcfs_lock.o
libcfs-objs := $(libcfs-linux-objs) $(libcfs-all-objs)
-
-ccflags-y := -I$(src)/../include
-ccflags-y += -I$(src)/
diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c
index 1e4c5ad26157..6b584698d3ae 100644
--- a/drivers/staging/lustre/lustre/libcfs/debug.c
+++ b/drivers/staging/lustre/lustre/libcfs/debug.c
@@ -41,7 +41,7 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include "tracefile.h"
static char debug_file_name[1024];
@@ -342,8 +342,8 @@ void libcfs_debug_dumplog_internal(void *arg)
if (strncmp(libcfs_debug_file_path_arr, "NONE", 4) != 0) {
snprintf(debug_file_name, sizeof(debug_file_name) - 1,
- "%s.%ld." LPLD, libcfs_debug_file_path_arr,
- cfs_time_current_sec(), (long_ptr_t)arg);
+ "%s.%ld.%ld", libcfs_debug_file_path_arr,
+ get_seconds(), (long_ptr_t)arg);
printk(KERN_ALERT "LustreError: dumping log to %s\n",
debug_file_name);
cfs_tracefile_dump_all_pages(debug_file_name);
@@ -463,7 +463,7 @@ EXPORT_SYMBOL(libcfs_debug_set_level);
void libcfs_log_goto(struct libcfs_debug_msg_data *msgdata, const char *label,
long_ptr_t rc)
{
- libcfs_debug_msg(msgdata, "Process leaving via %s (rc=" LPLU " : " LPLD
- " : " LPLX ")\n", label, (ulong_ptr_t)rc, rc, rc);
+ libcfs_debug_msg(msgdata, "Process leaving via %s (rc=%lu : %ld : %#lx)\n",
+ label, (ulong_ptr_t)rc, rc, rc);
}
EXPORT_SYMBOL(libcfs_log_goto);
diff --git a/drivers/staging/lustre/lustre/libcfs/fail.c b/drivers/staging/lustre/lustre/libcfs/fail.c
index ba43ff7f7900..1bf9c90b4789 100644
--- a/drivers/staging/lustre/lustre/libcfs/fail.c
+++ b/drivers/staging/lustre/lustre/libcfs/fail.c
@@ -33,16 +33,18 @@
* Lustre is a trademark of Oracle Corporation, Inc.
*/
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
unsigned long cfs_fail_loc = 0;
-unsigned int cfs_fail_val = 0;
-wait_queue_head_t cfs_race_waitq;
-int cfs_race_state;
-
EXPORT_SYMBOL(cfs_fail_loc);
+
+unsigned int cfs_fail_val = 0;
EXPORT_SYMBOL(cfs_fail_val);
+
+wait_queue_head_t cfs_race_waitq;
EXPORT_SYMBOL(cfs_race_waitq);
+
+int cfs_race_state;
EXPORT_SYMBOL(cfs_race_state);
int __cfs_fail_check_set(__u32 id, __u32 value, int set)
diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c
index 6d2b455d1be4..8ef1deb59d4a 100644
--- a/drivers/staging/lustre/lustre/libcfs/hash.c
+++ b/drivers/staging/lustre/lustre/libcfs/hash.c
@@ -107,7 +107,7 @@
* table. Also, user can break the iteration by return 1 in callback.
*/
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/seq_file.h>
#if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
@@ -351,7 +351,7 @@ cfs_hash_dh_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
cfs_hash_dhead_t, dh_head);
if (dh->dh_tail != NULL) /* not empty */
- hlist_add_after(dh->dh_tail, hnode);
+ hlist_add_behind(hnode, dh->dh_tail);
else /* empty list */
hlist_add_head(hnode, &dh->dh_head);
dh->dh_tail = hnode;
@@ -406,7 +406,7 @@ cfs_hash_dd_hnode_add(struct cfs_hash *hs, struct cfs_hash_bd *bd,
cfs_hash_dhead_dep_t, dd_head);
if (dh->dd_tail != NULL) /* not empty */
- hlist_add_after(dh->dd_tail, hnode);
+ hlist_add_behind(hnode, dh->dd_tail);
else /* empty list */
hlist_add_head(hnode, &dh->dd_head);
dh->dd_tail = hnode;
diff --git a/drivers/staging/lustre/lustre/libcfs/heap.c b/drivers/staging/lustre/lustre/libcfs/heap.c
index 147e4fe4762d..bf6d0b91c35f 100644
--- a/drivers/staging/lustre/lustre/libcfs/heap.c
+++ b/drivers/staging/lustre/lustre/libcfs/heap.c
@@ -35,7 +35,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#define CBH_ALLOC(ptr, h) \
do { \
diff --git a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
index b6ddc998f750..e2aa637abcf9 100644
--- a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
+++ b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
@@ -42,7 +42,7 @@
#define DEBUG_SUBSYSTEM S_CLASS
#define D_KUC D_OTHER
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/* This is the kernel side (liblustre as well). */
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c
index a1a7bf44cccf..dbb81b6cc200 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_cpu.c
@@ -35,7 +35,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/** Global CPU partition table */
struct cfs_cpt_table *cfs_cpt_table __read_mostly = NULL;
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
index a2ce4c0eb3dc..2c199c7259fe 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_lock.c
@@ -32,7 +32,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/** destroy cpu-partition lock, see libcfs_private.h for more detail */
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
index feab537c728c..1debdda72e72 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_mem.c
@@ -33,7 +33,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
struct cfs_var_array {
unsigned int va_count; /* # of buffers */
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
index ed0a6b531058..fb88733607a9 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
@@ -40,7 +40,7 @@
* Author: Nathan Rutman <nathan.rutman@sun.com>
*/
-#include <linux/libcfs/libcfs.h>
+#include "../../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/lustre/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c
index fc21210d77ec..224c65b5ce4e 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-cpu.c
@@ -35,7 +35,7 @@
#include <linux/cpu.h>
#include <linux/sched.h>
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#ifdef CONFIG_SMP
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c
index 20b2d61d9ff2..5e185fa5942a 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto-adler.c
@@ -32,12 +32,11 @@
#include <linux/module.h>
#include <linux/zutil.h>
#include <crypto/internal/hash.h>
-
+#include "linux-crypto.h"
#define CHKSUM_BLOCK_SIZE 1
#define CHKSUM_DIGEST_SIZE 4
-
static u32 __adler32(u32 cksum, unsigned char const *p, size_t len)
{
return zlib_adler32(cksum, p, len);
@@ -135,10 +134,8 @@ int cfs_crypto_adler32_register(void)
{
return crypto_register_shash(&alg);
}
-EXPORT_SYMBOL(cfs_crypto_adler32_register);
void cfs_crypto_adler32_unregister(void)
{
crypto_unregister_shash(&alg);
}
-EXPORT_SYMBOL(cfs_crypto_adler32_unregister);
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
index b6c79bc177ad..aa3fffed1519 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.c
@@ -29,8 +29,8 @@
#include <linux/crypto.h>
#include <linux/scatterlist.h>
-#include <linux/libcfs/libcfs.h>
-#include <linux/libcfs/linux/linux-crypto.h>
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "linux-crypto.h"
/**
* Array of hash algorithm speed in MByte per second
*/
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.h
index 97c771cf691f..18e8cd4d8758 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-crypto.h
@@ -22,28 +22,8 @@
* GPL HEADER END
*/
-/*
- * Copyright 2012 Xyratex Technology Limited
- */
-
-/**
- * Linux crypto hash specific functions.
- */
-
-/**
- * Functions for start/stop shash CRC32 algorithm.
- */
-int cfs_crypto_crc32_register(void);
-void cfs_crypto_crc32_unregister(void);
-
/**
* Functions for start/stop shash adler32 algorithm.
*/
int cfs_crypto_adler32_register(void);
void cfs_crypto_adler32_unregister(void);
-
-/**
- * Functions for start/stop shash crc32 pclmulqdq
- */
-int cfs_crypto_crc32_pclmul_register(void);
-void cfs_crypto_crc32_pclmul_unregister(void);
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
index bd301ce02255..d71ad5ed1f6d 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
@@ -48,7 +48,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
/*
* Implementation of cfs_curproc API (see portals/include/libcfs/curproc.h)
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c
index cc565b1fb994..eaa423d13650 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c
@@ -55,10 +55,10 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
-#include <linux/libcfs/linux/portals_compat25.h>
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "../../../include/linux/libcfs/linux/portals_compat25.h"
-#include "tracefile.h"
+#include "../tracefile.h"
#include <linux/kallsyms.h>
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-module.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-module.c
index 581b4728c6ca..de3c199654a0 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-module.c
@@ -36,7 +36,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#define LNET_MINOR 240
@@ -99,7 +99,7 @@ int libcfs_ioctl_popdata(void *arg, void *data, int size)
extern struct cfs_psdev_ops libcfs_psdev_ops;
static int
-libcfs_psdev_open(struct inode * inode, struct file * file)
+libcfs_psdev_open(struct inode *inode, struct file *file)
{
struct libcfs_device_userstate **pdu = NULL;
int rc = 0;
@@ -116,7 +116,7 @@ libcfs_psdev_open(struct inode * inode, struct file * file)
/* called when closing /dev/device */
static int
-libcfs_psdev_release(struct inode * inode, struct file * file)
+libcfs_psdev_release(struct inode *inode, struct file *file)
{
struct libcfs_device_userstate *pdu;
int rc = 0;
@@ -140,9 +140,9 @@ static long libcfs_ioctl(struct file *file,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if ( _IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
+ if (_IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
_IOC_NR(cmd) < IOC_LIBCFS_MIN_NR ||
- _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR ) {
+ _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR) {
CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
_IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
return (-EINVAL);
@@ -154,7 +154,7 @@ static long libcfs_ioctl(struct file *file,
if (!capable(CFS_CAP_SYS_BOOT))
return (-EPERM);
panic("debugctl-invoked panic");
- return (0);
+ return 0;
case IOC_LIBCFS_MEMHOG:
if (!capable(CFS_CAP_SYS_ADMIN))
return -EPERM;
@@ -167,10 +167,10 @@ static long libcfs_ioctl(struct file *file,
rc = libcfs_psdev_ops.p_ioctl(&pfile, cmd, (void *)arg);
else
rc = -EPERM;
- return (rc);
+ return rc;
}
-static struct file_operations libcfs_fops = {
+static const struct file_operations libcfs_fops = {
.unlocked_ioctl = libcfs_ioctl,
.open = libcfs_psdev_open,
.release = libcfs_psdev_release,
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c
index 9a40d1415a65..871ba44b29f3 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-prim.c
@@ -40,7 +40,7 @@
#include <linux/fs_struct.h>
#include <linux/sched.h>
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#if defined(CONFIG_KGDB)
#include <asm/kgdb.h>
@@ -90,7 +90,7 @@ void cfs_timer_done(struct timer_list *t)
}
EXPORT_SYMBOL(cfs_timer_done);
-void cfs_timer_arm(struct timer_list *t, cfs_time_t deadline)
+void cfs_timer_arm(struct timer_list *t, unsigned long deadline)
{
mod_timer(t, deadline);
}
@@ -108,7 +108,7 @@ int cfs_timer_is_armed(struct timer_list *t)
}
EXPORT_SYMBOL(cfs_timer_is_armed);
-cfs_time_t cfs_timer_deadline(struct timer_list *t)
+unsigned long cfs_timer_deadline(struct timer_list *t)
{
return t->expires;
}
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
index e947b9128c58..13a9266acfa0 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
@@ -61,11 +61,11 @@
# define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#include <asm/div64.h>
-#include "tracefile.h"
+#include "../tracefile.h"
-static ctl_table_header_t *lnet_table_header = NULL;
+static struct ctl_table_header *lnet_table_header = NULL;
extern char lnet_upcall[1024];
/**
* The path of debug log dump upcall script.
@@ -98,11 +98,9 @@ enum {
PSDEV_LNET_FAIL_VAL, /* userdata for fail loc */
};
-int
-proc_call_handler(void *data, int write,
- loff_t *ppos, void *buffer, size_t *lenp,
- int (*handler)(void *data, int write,
- loff_t pos, void *buffer, int len))
+static int proc_call_handler(void *data, int write, loff_t *ppos, void *buffer,
+ size_t *lenp, int (*handler)(void *data, int write,
+ loff_t pos, void *buffer, int len))
{
int rc = handler(data, write, *ppos, buffer, *lenp);
@@ -117,7 +115,6 @@ proc_call_handler(void *data, int write,
}
return 0;
}
-EXPORT_SYMBOL(proc_call_handler);
static int __proc_dobitmasks(void *data, int write,
loff_t pos, void *buffer, int nob)
@@ -160,7 +157,12 @@ static int __proc_dobitmasks(void *data, int write,
return rc;
}
-DECLARE_PROC_HANDLER(proc_dobitmasks)
+static int proc_dobitmasks(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_dobitmasks);
+}
static int min_watchdog_ratelimit = 0; /* disable ratelimiting */
static int max_watchdog_ratelimit = (24*60*60); /* limit to once per day */
@@ -174,7 +176,12 @@ static int __proc_dump_kernel(void *data, int write,
return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
}
-DECLARE_PROC_HANDLER(proc_dump_kernel)
+static int proc_dump_kernel(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_dump_kernel);
+}
static int __proc_daemon_file(void *data, int write,
loff_t pos, void *buffer, int nob)
@@ -192,7 +199,12 @@ static int __proc_daemon_file(void *data, int write,
return cfs_trace_daemon_command_usrstr(buffer, nob);
}
-DECLARE_PROC_HANDLER(proc_daemon_file)
+static int proc_daemon_file(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_daemon_file);
+}
static int __proc_debug_mb(void *data, int write,
loff_t pos, void *buffer, int nob)
@@ -212,26 +224,32 @@ static int __proc_debug_mb(void *data, int write,
return cfs_trace_set_debug_mb_usrstr(buffer, nob);
}
-DECLARE_PROC_HANDLER(proc_debug_mb)
+static int proc_debug_mb(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_debug_mb);
+}
-int LL_PROC_PROTO(proc_console_max_delay_cs)
+int proc_console_max_delay_cs(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc, max_delay_cs;
- ctl_table_t dummy = *table;
- cfs_duration_t d;
+ struct ctl_table dummy = *table;
+ long d;
dummy.data = &max_delay_cs;
dummy.proc_handler = &proc_dointvec;
if (!write) { /* read */
max_delay_cs = cfs_duration_sec(libcfs_console_max_delay * 100);
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
return rc;
}
/* write */
max_delay_cs = 0;
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
if (rc < 0)
return rc;
if (max_delay_cs <= 0)
@@ -245,24 +263,25 @@ int LL_PROC_PROTO(proc_console_max_delay_cs)
return rc;
}
-int LL_PROC_PROTO(proc_console_min_delay_cs)
+int proc_console_min_delay_cs(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc, min_delay_cs;
- ctl_table_t dummy = *table;
- cfs_duration_t d;
+ struct ctl_table dummy = *table;
+ long d;
dummy.data = &min_delay_cs;
dummy.proc_handler = &proc_dointvec;
if (!write) { /* read */
min_delay_cs = cfs_duration_sec(libcfs_console_min_delay * 100);
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
return rc;
}
/* write */
min_delay_cs = 0;
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
if (rc < 0)
return rc;
if (min_delay_cs <= 0)
@@ -276,23 +295,24 @@ int LL_PROC_PROTO(proc_console_min_delay_cs)
return rc;
}
-int LL_PROC_PROTO(proc_console_backoff)
+int proc_console_backoff(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc, backoff;
- ctl_table_t dummy = *table;
+ struct ctl_table dummy = *table;
dummy.data = &backoff;
dummy.proc_handler = &proc_dointvec;
if (!write) { /* read */
backoff= libcfs_console_backoff;
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
return rc;
}
/* write */
backoff = 0;
- rc = ll_proc_dointvec(&dummy, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(&dummy, write, buffer, lenp, ppos);
if (rc < 0)
return rc;
if (backoff <= 0)
@@ -303,19 +323,21 @@ int LL_PROC_PROTO(proc_console_backoff)
return rc;
}
-int LL_PROC_PROTO(libcfs_force_lbug)
+int libcfs_force_lbug(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
if (write)
LBUG();
return 0;
}
-int LL_PROC_PROTO(proc_fail_loc)
+int proc_fail_loc(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int rc;
long old_fail_loc = cfs_fail_loc;
- rc = ll_proc_dolongvec(table, write, filp, buffer, lenp, ppos);
+ rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
if (old_fail_loc != cfs_fail_loc)
wake_up(&cfs_race_waitq);
return rc;
@@ -361,9 +383,15 @@ static int __proc_cpt_table(void *data, int write,
LIBCFS_FREE(buf, len);
return rc;
}
-DECLARE_PROC_HANDLER(proc_cpt_table)
-static ctl_table_t lnet_table[] = {
+static int proc_cpt_table(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ return proc_call_handler(table->data, write, ppos, buffer, lenp,
+ __proc_cpt_table);
+}
+
+static struct ctl_table lnet_table[] = {
/*
* NB No .strategy entries have been provided since sysctl(8) prefers
* to go via /proc for portability.
@@ -516,7 +544,7 @@ static ctl_table_t lnet_table[] = {
}
};
-static ctl_table_t top_table[] = {
+static struct ctl_table top_table[] = {
{
.procname = "lnet",
.mode = 0555,
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
index ac3a444a918d..a93b6210705b 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
@@ -35,7 +35,7 @@
*/
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../../include/linux/libcfs/libcfs.h"
#include <linux/if.h>
#include <linux/in.h>
@@ -46,16 +46,31 @@
int
libcfs_sock_ioctl(int cmd, unsigned long arg)
{
+ mm_segment_t oldmm = get_fs();
struct socket *sock;
- int rc;
+ int rc;
+ struct file *sock_filp;
rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);
if (rc != 0) {
CERROR ("Can't create socket: %d\n", rc);
return rc;
}
- rc = kernel_sock_ioctl(sock, cmd, arg);
- sock_release(sock);
+
+ sock_filp = sock_alloc_file(sock, 0, NULL);
+ if (IS_ERR(sock_filp)) {
+ sock_release(sock);
+ rc = PTR_ERR(sock_filp);
+ goto out;
+ }
+
+ set_fs(KERNEL_DS);
+ if (sock_filp->f_op->unlocked_ioctl)
+ rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);
+ set_fs(oldmm);
+
+ fput(sock_filp);
+out:
return rc;
}
@@ -183,8 +198,6 @@ libcfs_ipif_enumerate (char ***namesp)
rc = -ENOMEM;
goto out1;
}
- /* NULL out all names[i] */
- memset (names, 0, nfound * sizeof(*names));
for (i = 0; i < nfound; i++) {
@@ -532,7 +545,7 @@ libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
newsock->ops = sock->ops;
set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(cfs_sk_sleep(sock->sk), &wait);
+ add_wait_queue(sk_sleep(sock->sk), &wait);
rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
if (rc == -EAGAIN) {
@@ -541,7 +554,7 @@ libcfs_sock_accept (struct socket **newsockp, struct socket *sock)
rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
}
- remove_wait_queue(cfs_sk_sleep(sock->sk), &wait);
+ remove_wait_queue(sk_sleep(sock->sk), &wait);
set_current_state(TASK_RUNNING);
if (rc != 0)
@@ -560,7 +573,7 @@ EXPORT_SYMBOL(libcfs_sock_accept);
void
libcfs_sock_abort_accept (struct socket *sock)
{
- wake_up_all(cfs_sk_sleep(sock->sk));
+ wake_up_all(sk_sleep(sock->sk));
}
EXPORT_SYMBOL(libcfs_sock_abort_accept);
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
index 162beee24a73..976c61ed49f4 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
@@ -37,8 +37,8 @@
#define DEBUG_SUBSYSTEM S_LNET
#define LUSTRE_TRACEFILE_PRIVATE
-#include <linux/libcfs/libcfs.h>
-#include "tracefile.h"
+#include "../../../include/linux/libcfs/libcfs.h"
+#include "../tracefile.h"
/* percents to share the total debug memory for each type */
static unsigned int pages_factor[CFS_TCD_TYPE_MAX] = {
@@ -112,8 +112,6 @@ void cfs_tracefile_fini_arch(void)
kfree(cfs_trace_data[i]);
cfs_trace_data[i] = NULL;
}
-
- fini_rwsem(&cfs_tracefile_sem);
}
void cfs_tracefile_read_lock(void)
diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c
index b16ee08fe742..3396858098b0 100644
--- a/drivers/staging/lustre/lustre/libcfs/module.c
+++ b/drivers/staging/lustre/lustre/libcfs/module.c
@@ -36,10 +36,10 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
-#include <linux/libcfs/libcfs_crypto.h>
-#include <linux/lnet/lib-lnet.h>
-#include <linux/lnet/lnet.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/libcfs/libcfs_crypto.h"
+#include "../../include/linux/lnet/lib-lnet.h"
+#include "../../include/linux/lnet/lnet.h"
#include "tracefile.h"
void
@@ -439,9 +439,6 @@ static void exit_libcfs_module(void)
printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n",
rc);
- fini_rwsem(&ioctl_list_sem);
- fini_rwsem(&cfs_tracefile_sem);
-
libcfs_arch_cleanup();
}
diff --git a/drivers/staging/lustre/lustre/libcfs/nidstrings.c b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
index 87705ae4480f..47c239f22ba8 100644
--- a/drivers/staging/lustre/lustre/libcfs/nidstrings.c
+++ b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
@@ -40,8 +40,8 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
-#include <linux/lnet/lnet.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../../include/linux/lnet/lnet.h"
/* CAVEAT VENDITOR! Keep the canonical string representation of nets/nids
* consistent in all conversion functions. Some code fragments are copied
@@ -74,8 +74,7 @@ libcfs_next_nidstring(void)
spin_lock_irqsave(&libcfs_nidstring_lock, flags);
str = libcfs_nidstrings[libcfs_nidstring_idx++];
- if (libcfs_nidstring_idx ==
- sizeof(libcfs_nidstrings)/sizeof(libcfs_nidstrings[0]))
+ if (libcfs_nidstring_idx == ARRAY_SIZE(libcfs_nidstrings))
libcfs_nidstring_idx = 0;
spin_unlock_irqrestore(&libcfs_nidstring_lock, flags);
@@ -198,7 +197,7 @@ static struct netstrfns libcfs_netstrfns[] = {
{/* .nf_type */ -1},
};
-const int libcfs_nnetstrfns = sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]);
+const int libcfs_nnetstrfns = ARRAY_SIZE(libcfs_netstrfns);
int
libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
diff --git a/drivers/staging/lustre/lustre/libcfs/prng.c b/drivers/staging/lustre/lustre/libcfs/prng.c
index f87e9e516546..4147664ff57a 100644
--- a/drivers/staging/lustre/lustre/libcfs/prng.c
+++ b/drivers/staging/lustre/lustre/libcfs/prng.c
@@ -39,7 +39,7 @@
* algorithm recommended by Marsaglia
*/
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/*
From: George Marsaglia <geo@stat.fsu.edu>
diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c
index 07845e844243..0569bf8c75f3 100644
--- a/drivers/staging/lustre/lustre/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c
@@ -44,7 +44,7 @@
#define LUSTRE_TRACEFILE_PRIVATE
#include "tracefile.h"
-#include <linux/libcfs/libcfs.h>
+#include "../../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/lustre/libcfs/tracefile.h b/drivers/staging/lustre/lustre/libcfs/tracefile.h
index 55ecfc9f201b..8df4af36c91d 100644
--- a/drivers/staging/lustre/lustre/libcfs/tracefile.h
+++ b/drivers/staging/lustre/lustre/libcfs/tracefile.h
@@ -37,7 +37,7 @@
#ifndef __LIBCFS_TRACEFILE_H__
#define __LIBCFS_TRACEFILE_H__
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include "linux/linux-tracefile.h"
diff --git a/drivers/staging/lustre/lustre/libcfs/upcall_cache.c b/drivers/staging/lustre/lustre/libcfs/upcall_cache.c
index 8085e32e5e7a..88af82034e92 100644
--- a/drivers/staging/lustre/lustre/libcfs/upcall_cache.c
+++ b/drivers/staging/lustre/lustre/libcfs/upcall_cache.c
@@ -39,7 +39,7 @@
*/
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/lucache.h>
+#include "../../include/linux/libcfs/lucache.h"
static struct upcall_cache_entry *alloc_entry(struct upcall_cache *cache,
__u64 key, void *args)
@@ -68,7 +68,7 @@ static void free_entry(struct upcall_cache *cache,
cache->uc_ops->free_entry(cache, entry);
list_del(&entry->ue_hash);
- CDEBUG(D_OTHER, "destroy cache entry %p for key "LPU64"\n",
+ CDEBUG(D_OTHER, "destroy cache entry %p for key %llu\n",
entry, entry->ue_key);
LIBCFS_FREE(entry, sizeof(*entry));
}
@@ -117,13 +117,12 @@ static int check_unlink_entry(struct upcall_cache *cache,
struct upcall_cache_entry *entry)
{
if (UC_CACHE_IS_VALID(entry) &&
- cfs_time_before(cfs_time_current(), entry->ue_expire))
+ time_before(cfs_time_current(), entry->ue_expire))
return 0;
if (UC_CACHE_IS_ACQUIRING(entry)) {
if (entry->ue_acquire_expire == 0 ||
- cfs_time_before(cfs_time_current(),
- entry->ue_acquire_expire))
+ time_before(cfs_time_current(), entry->ue_acquire_expire))
return 0;
UC_CACHE_SET_EXPIRED(entry);
@@ -230,7 +229,7 @@ find_again:
if (UC_CACHE_IS_ACQUIRING(entry)) {
/* we're interrupted or upcall failed in the middle */
rc = left > 0 ? -EINTR : -ETIMEDOUT;
- CERROR("acquire for key "LPU64": error %d\n",
+ CERROR("acquire for key %llu: error %d\n",
entry->ue_key, rc);
put_entry(cache, entry);
GOTO(out, entry = ERR_PTR(rc));
@@ -303,7 +302,7 @@ int upcall_cache_downcall(struct upcall_cache *cache, __u32 err, __u64 key,
}
if (!found) {
- CDEBUG(D_OTHER, "%s: upcall for key "LPU64" not expected\n",
+ CDEBUG(D_OTHER, "%s: upcall for key %llu not expected\n",
cache->uc_name, key);
/* haven't found, it's possible */
spin_unlock(&cache->uc_lock);
@@ -311,19 +310,19 @@ int upcall_cache_downcall(struct upcall_cache *cache, __u32 err, __u64 key,
}
if (err) {
- CDEBUG(D_OTHER, "%s: upcall for key "LPU64" returned %d\n",
+ CDEBUG(D_OTHER, "%s: upcall for key %llu returned %d\n",
cache->uc_name, entry->ue_key, err);
GOTO(out, rc = -EINVAL);
}
if (!UC_CACHE_IS_ACQUIRING(entry)) {
- CDEBUG(D_RPCTRACE,"%s: found uptodate entry %p (key "LPU64")\n",
+ CDEBUG(D_RPCTRACE,"%s: found uptodate entry %p (key %llu)\n",
cache->uc_name, entry, entry->ue_key);
GOTO(out, rc = 0);
}
if (UC_CACHE_IS_INVALID(entry) || UC_CACHE_IS_EXPIRED(entry)) {
- CERROR("%s: found a stale entry %p (key "LPU64") in ioctl\n",
+ CERROR("%s: found a stale entry %p (key %llu) in ioctl\n",
cache->uc_name, entry, entry->ue_key);
GOTO(out, rc = -EINVAL);
}
@@ -337,7 +336,7 @@ int upcall_cache_downcall(struct upcall_cache *cache, __u32 err, __u64 key,
entry->ue_expire = cfs_time_shift(cache->uc_entry_expire);
UC_CACHE_SET_VALID(entry);
- CDEBUG(D_OTHER, "%s: created upcall cache entry %p for key "LPU64"\n",
+ CDEBUG(D_OTHER, "%s: created upcall cache entry %p for key %llu\n",
cache->uc_name, entry, entry->ue_key);
out:
if (rc) {
@@ -402,11 +401,10 @@ void upcall_cache_flush_one(struct upcall_cache *cache, __u64 key, void *args)
}
if (found) {
- CWARN("%s: flush entry %p: key "LPU64", ref %d, fl %x, "
- "cur %lu, ex %ld/%ld\n",
+ CWARN("%s: flush entry %p: key %llu, ref %d, fl %x, cur %lu, ex %ld/%ld\n",
cache->uc_name, entry, entry->ue_key,
atomic_read(&entry->ue_refcount), entry->ue_flags,
- cfs_time_current_sec(), entry->ue_acquire_expire,
+ get_seconds(), entry->ue_acquire_expire,
entry->ue_expire);
UC_CACHE_SET_EXPIRED(entry);
if (!atomic_read(&entry->ue_refcount))
diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c
index 0a03bf7ba3eb..65629579bd7d 100644
--- a/drivers/staging/lustre/lustre/libcfs/workitem.c
+++ b/drivers/staging/lustre/lustre/libcfs/workitem.c
@@ -41,7 +41,7 @@
#define DEBUG_SUBSYSTEM S_LNET
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#define CFS_WS_NAME_LEN 16
diff --git a/drivers/staging/lustre/lustre/llite/Makefile b/drivers/staging/lustre/lustre/llite/Makefile
index c76f3cfedab0..7d70115d5bc7 100644
--- a/drivers/staging/lustre/lustre/llite/Makefile
+++ b/drivers/staging/lustre/lustre/llite/Makefile
@@ -9,6 +9,3 @@ lustre-y := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o \
lustre-$(CONFIG_PROC_FS) += lproc_llite.o
llite_lloop-y := lloop.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c
index 7d520d8f4a69..49ae207ad425 100644
--- a/drivers/staging/lustre/lustre/llite/dcache.c
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
@@ -40,10 +40,10 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd_support.h>
-#include <lustre_lite.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_dlm.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre/lustre_idl.h"
+#include "../include/lustre_dlm.h"
#include "llite_internal.h"
@@ -213,8 +213,8 @@ void ll_intent_drop_lock(struct lookup_intent *it)
handle.cookie = it->d.lustre.it_lock_handle;
- CDEBUG(D_DLMTRACE, "releasing lock with cookie "LPX64
- " from it %p\n", handle.cookie, it);
+ CDEBUG(D_DLMTRACE, "releasing lock with cookie %#llx from it %p\n",
+ handle.cookie, it);
ldlm_lock_decref(&handle, it->d.lustre.it_lock_mode);
/* bug 494: intent_release may be called multiple times, from
@@ -223,8 +223,8 @@ void ll_intent_drop_lock(struct lookup_intent *it)
if (it->d.lustre.it_remote_lock_mode != 0) {
handle.cookie = it->d.lustre.it_remote_lock_handle;
- CDEBUG(D_DLMTRACE, "releasing remote lock with cookie"
- LPX64" from it %p\n", handle.cookie, it);
+ CDEBUG(D_DLMTRACE, "releasing remote lock with cookie%#llx from it %p\n",
+ handle.cookie, it);
ldlm_lock_decref(&handle,
it->d.lustre.it_remote_lock_mode);
it->d.lustre.it_remote_lock_mode = 0;
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index ae6f61aa4da6..efa2faf080d7 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -48,13 +48,13 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_lib.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
-#include <lustre_fid.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_lib.h"
+#include "../include/lustre/lustre_idl.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_fid.h"
#include "llite_internal.h"
/*
@@ -158,7 +158,7 @@ static int ll_dir_filler(void *_hash, struct page *page0)
int i;
int rc;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) hash "LPU64"\n",
+ CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) hash %llu\n",
inode->i_ino, inode->i_generation, inode, hash);
LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES);
@@ -302,9 +302,9 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
*start = le64_to_cpu(dp->ldp_hash_start);
*end = le64_to_cpu(dp->ldp_hash_end);
}
- LASSERTF(*start <= *hash, "start = "LPX64",end = "
- LPX64",hash = "LPX64"\n", *start, *end, *hash);
- CDEBUG(D_VFSTRACE, "page %lu [%llu %llu], hash "LPU64"\n",
+ LASSERTF(*start <= *hash, "start = %#llx,end = %#llx,hash = %#llx\n",
+ *start, *end, *hash);
+ CDEBUG(D_VFSTRACE, "page %lu [%llu %llu], hash %llu\n",
offset, *start, *end, *hash);
if (*hash > *end) {
ll_release_page(page, 0);
@@ -376,7 +376,7 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
if (request)
ptlrpc_req_finished(request);
if (rc < 0) {
- CERROR("lock enqueue: "DFID" at "LPU64": rc %d\n",
+ CERROR("lock enqueue: "DFID" at %llu: rc %d\n",
PFID(ll_inode2fid(dir)), hash, rc);
return ERR_PTR(rc);
}
@@ -396,7 +396,7 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
mutex_lock(&lli->lli_readdir_mutex);
page = ll_dir_page_locate(dir, &lhash, &start, &end);
if (IS_ERR(page)) {
- CERROR("dir page locate: "DFID" at "LPU64": rc %ld\n",
+ CERROR("dir page locate: "DFID" at %llu: rc %ld\n",
PFID(ll_inode2fid(dir)), lhash, PTR_ERR(page));
GOTO(out_unlock, page);
} else if (page != NULL) {
@@ -420,7 +420,7 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
page = read_cache_page(mapping, hash_x_index(hash, hash64),
ll_dir_filler, &lhash);
if (IS_ERR(page)) {
- CERROR("read cache page: "DFID" at "LPU64": rc %ld\n",
+ CERROR("read cache page: "DFID" at %llu: rc %ld\n",
PFID(ll_inode2fid(dir)), hash, PTR_ERR(page));
GOTO(out_unlock, page);
}
@@ -428,14 +428,14 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash,
wait_on_page_locked(page);
(void)kmap(page);
if (!PageUptodate(page)) {
- CERROR("page not updated: "DFID" at "LPU64": rc %d\n",
+ CERROR("page not updated: "DFID" at %llu: rc %d\n",
PFID(ll_inode2fid(dir)), hash, -5);
goto fail;
}
if (!PageChecked(page))
ll_check_page(dir, page);
if (PageError(page)) {
- CERROR("page error: "DFID" at "LPU64": rc %d\n",
+ CERROR("page error: "DFID" at %llu: rc %d\n",
PFID(ll_inode2fid(dir)), hash, -5);
goto fail;
}
@@ -452,10 +452,9 @@ hash_collision:
}
if (end == start) {
LASSERT(start == lhash);
- CWARN("Page-wide hash collision: "LPU64"\n", end);
+ CWARN("Page-wide hash collision: %llu\n", end);
if (BITS_PER_LONG == 32 && hash64)
- CWARN("Real page-wide hash collision at ["LPU64" "LPU64
- "] with hash "LPU64"\n",
+ CWARN("Real page-wide hash collision at [%llu %llu] with hash %llu\n",
le64_to_cpu(dp->ldp_hash_start),
le64_to_cpu(dp->ldp_hash_end), hash);
/*
@@ -926,8 +925,7 @@ static int ll_ioc_copy_start(struct super_block *sb, struct hsm_copy *copy)
iput(inode);
if (rc != 0) {
CDEBUG(D_HSM, "Could not read file data version of "
- DFID" (rc = %d). Archive request ("
- LPX64") could not be done.\n",
+ DFID" (rc = %d). Archive request (%#llx) could not be done.\n",
PFID(&copy->hc_hai.hai_fid), rc,
copy->hc_hai.hai_cookie);
hpk.hpk_flags |= HP_FLAG_RETRY;
@@ -1023,7 +1021,7 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy)
(copy->hc_data_version != data_version)) {
CDEBUG(D_HSM, "File data version mismatched. "
"File content was changed during archiving. "
- DFID", start:"LPX64" current:"LPX64"\n",
+ DFID", start:%#llx current:%#llx\n",
PFID(&copy->hc_hai.hai_fid),
copy->hc_data_version, data_version);
/* File was changed, send error to cdt. Do not ask for
@@ -1266,7 +1264,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (mdtidx < 0)
return mdtidx;
- if (put_user((int)mdtidx, (int*)arg))
+ if (put_user((int)mdtidx, (int *)arg))
return -EFAULT;
return 0;
@@ -1501,7 +1499,7 @@ out_rmdir:
GOTO(out_req, rc = -EFAULT);
rc = -EOVERFLOW;
}
- skip_lmm:
+skip_lmm:
if (cmd == IOC_MDC_GETFILEINFO || cmd == LL_IOC_MDC_GETINFO) {
struct lov_user_mds_data *lmdp;
lstat_t st = { 0 };
@@ -1525,7 +1523,7 @@ out_rmdir:
GOTO(out_req, rc = -EFAULT);
}
- out_req:
+out_req:
ptlrpc_req_finished(request);
if (filename)
ll_putname(filename);
@@ -1589,9 +1587,9 @@ out_rmdir:
if (copy_to_user(&lumd->lmd_st, &st, sizeof(st)))
GOTO(free_lsm, rc = -EFAULT);
- free_lsm:
+free_lsm:
obd_free_memmd(sbi->ll_dt_exp, &lsm);
- free_lmm:
+free_lmm:
OBD_FREE_LARGE(lmm, lmmsize);
return rc;
}
@@ -1653,7 +1651,7 @@ out_rmdir:
CDEBUG(D_QUOTA, "copy_to_user failed\n");
GOTO(out_poll, rc);
}
- out_poll:
+out_poll:
OBD_FREE_PTR(check);
return rc;
}
@@ -1702,9 +1700,9 @@ out_rmdir:
rc = -EFAULT;
}
- out_quotactl_20:
+out_quotactl_20:
OBD_FREE_PTR(qctl_20);
- out_quotactl_18:
+out_quotactl_18:
OBD_FREE_PTR(qctl_18);
return rc;
}
@@ -1726,7 +1724,7 @@ out_rmdir:
if (rc == 0 && copy_to_user((void *)arg,qctl,sizeof(*qctl)))
rc = -EFAULT;
- out_quotactl:
+out_quotactl:
OBD_FREE_PTR(qctl);
return rc;
}
@@ -1778,7 +1776,7 @@ out_rmdir:
return -EFAULT;
return 0;
case LL_IOC_GET_CONNECT_FLAGS: {
- return obd_iocontrol(cmd, sbi->ll_md_exp, 0, NULL, (void*)arg);
+ return obd_iocontrol(cmd, sbi->ll_md_exp, 0, NULL, (void *)arg);
}
case OBD_IOC_CHANGELOG_SEND:
case OBD_IOC_CHANGELOG_CLEAR:
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 716e1ee0104f..fd1b75a3a569 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -41,14 +41,14 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_dlm.h>
-#include <lustre_lite.h>
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_lite.h"
#include <linux/pagemap.h>
#include <linux/file.h>
#include "llite_internal.h"
-#include <lustre/ll_fiemap.h>
+#include "../include/lustre/ll_fiemap.h"
-#include "cl_object.h"
+#include "../include/cl_object.h"
static int
ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg);
@@ -140,7 +140,7 @@ static int ll_close_inode_openhandle(struct obd_export *md_exp,
* XXX: in case of LMV, is this correct to access
* ->exp_handle?
*/
- CERROR("Invalid MDC connection handle "LPX64"\n",
+ CERROR("Invalid MDC connection handle %#llx\n",
ll_i2mdexp(inode)->exp_handle.h_cookie);
GOTO(out, rc = 0);
}
@@ -290,7 +290,7 @@ static int ll_md_close(struct obd_export *md_exp, struct inode *inode,
we can skip talking to MDS */
if (file->f_dentry->d_inode) { /* Can this ever be false? */
int lockmode;
- int flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK;
+ __u64 flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK;
struct lustre_handle lockh;
struct inode *inode = file->f_dentry->d_inode;
ldlm_policy_data_t policy = {.l_inodebits={MDS_INODELOCK_OPEN}};
@@ -471,7 +471,7 @@ void ll_ioepoch_open(struct ll_inode_info *lli, __u64 ioepoch)
{
if (ioepoch && lli->lli_ioepoch != ioepoch) {
lli->lli_ioepoch = ioepoch;
- CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID"\n",
+ CDEBUG(D_INODE, "Epoch %llu opened on "DFID"\n",
ioepoch, PFID(&lli->lli_fid));
}
}
@@ -1008,7 +1008,7 @@ int ll_merge_lvb(const struct lu_env *env, struct inode *inode)
if (lvb.lvb_mtime < attr->cat_mtime)
lvb.lvb_mtime = attr->cat_mtime;
- CDEBUG(D_VFSTRACE, DFID" updating i_size "LPU64"\n",
+ CDEBUG(D_VFSTRACE, DFID" updating i_size %llu\n",
PFID(&lli->lli_fid), attr->cat_size);
cl_isize_write_nolock(inode, attr->cat_size);
@@ -2623,7 +2623,7 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
struct md_op_data *op_data;
struct lustre_handle lockh = {0};
ldlm_policy_data_t flock = {{0}};
- int flags = 0;
+ __u64 flags = 0;
int rc;
int rc2 = 0;
@@ -2708,9 +2708,9 @@ ll_file_flock(struct file *file, int cmd, struct file_lock *file_lock)
if (IS_ERR(op_data))
return PTR_ERR(op_data);
- CDEBUG(D_DLMTRACE, "inode=%lu, pid=%u, flags=%#x, mode=%u, "
- "start="LPU64", end="LPU64"\n", inode->i_ino, flock.l_flock.pid,
- flags, einfo.ei_mode, flock.l_flock.start, flock.l_flock.end);
+ CDEBUG(D_DLMTRACE, "inode=%lu, pid=%u, flags=%#llx, mode=%u, start=%llu, end=%llu\n",
+ inode->i_ino, flock.l_flock.pid, flags, einfo.ei_mode,
+ flock.l_flock.start, flock.l_flock.end);
rc = md_enqueue(sbi->ll_md_exp, &einfo, NULL,
op_data, &lockh, &flock, 0, NULL /* req */, flags);
diff --git a/drivers/staging/lustre/lustre/llite/llite_capa.c b/drivers/staging/lustre/lustre/llite/llite_capa.c
index d06d0b1ab08a..023c40518c6d 100644
--- a/drivers/staging/lustre/lustre/llite/llite_capa.c
+++ b/drivers/staging/lustre/lustre/llite/llite_capa.c
@@ -41,11 +41,11 @@
#define DEBUG_SUBSYSTEM S_LLITE
#include <linux/fs.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/kmod.h>
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
/* for obd_capa.c_list, client capa might stay in three places:
@@ -63,16 +63,16 @@ static struct list_head *ll_capa_list = &capa_list[CAPA_SITE_CLIENT];
struct timer_list ll_capa_timer;
/* for debug: indicate whether capa on llite is enabled or not */
static atomic_t ll_capa_debug = ATOMIC_INIT(0);
-static unsigned long long ll_capa_renewed = 0;
-static unsigned long long ll_capa_renewal_noent = 0;
-static unsigned long long ll_capa_renewal_failed = 0;
-static unsigned long long ll_capa_renewal_retries = 0;
+static unsigned long long ll_capa_renewed;
+static unsigned long long ll_capa_renewal_noent;
+static unsigned long long ll_capa_renewal_failed;
+static unsigned long long ll_capa_renewal_retries;
static int ll_update_capa(struct obd_capa *ocapa, struct lustre_capa *capa);
-static inline void update_capa_timer(struct obd_capa *ocapa, cfs_time_t expiry)
+static inline void update_capa_timer(struct obd_capa *ocapa, unsigned long expiry)
{
- if (cfs_time_before(expiry, ll_capa_timer.expires) ||
+ if (time_before(expiry, ll_capa_timer.expires) ||
!timer_pending(&ll_capa_timer)) {
mod_timer(&ll_capa_timer, expiry);
DEBUG_CAPA(D_SEC, &ocapa->c_capa,
@@ -80,7 +80,7 @@ static inline void update_capa_timer(struct obd_capa *ocapa, cfs_time_t expiry)
}
}
-static inline cfs_time_t capa_renewal_time(struct obd_capa *ocapa)
+static inline unsigned long capa_renewal_time(struct obd_capa *ocapa)
{
return cfs_time_sub(ocapa->c_expiry,
cfs_time_seconds(ocapa->c_capa.lc_timeout) / 2);
@@ -88,7 +88,7 @@ static inline cfs_time_t capa_renewal_time(struct obd_capa *ocapa)
static inline int capa_is_to_expire(struct obd_capa *ocapa)
{
- return cfs_time_beforeq(capa_renewal_time(ocapa), cfs_time_current());
+ return time_before_eq(capa_renewal_time(ocapa), cfs_time_current());
}
static inline int have_expired_capa(void)
@@ -359,7 +359,7 @@ struct obd_capa *ll_osscapa_get(struct inode *inode, __u64 opc)
ocapa = NULL;
if (atomic_read(&ll_capa_debug)) {
- CERROR("no capability for "DFID" opc "LPX64"\n",
+ CERROR("no capability for "DFID" opc %#llx\n",
PFID(&lli->lli_fid), opc);
atomic_set(&ll_capa_debug, 0);
}
@@ -511,7 +511,7 @@ struct obd_capa *ll_add_capa(struct inode *inode, struct obd_capa *ocapa)
return ocapa;
}
-static inline void delay_capa_renew(struct obd_capa *oc, cfs_time_t delay)
+static inline void delay_capa_renew(struct obd_capa *oc, unsigned long delay)
{
/* NB: set a fake expiry for this capa to prevent it renew too soon */
oc->c_expiry = cfs_time_add(oc->c_expiry, cfs_time_seconds(delay));
diff --git a/drivers/staging/lustre/lustre/llite/llite_close.c b/drivers/staging/lustre/lustre/llite/llite_close.c
index 38c2d0e947db..6a3a7a303043 100644
--- a/drivers/staging/lustre/lustre/llite/llite_close.c
+++ b/drivers/staging/lustre/lustre/llite/llite_close.c
@@ -42,7 +42,7 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
/** records that a write is in flight */
@@ -170,7 +170,7 @@ void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
GOTO(out, 0);
}
}
- CDEBUG(D_INODE, "Epoch "LPU64" closed on "DFID"\n",
+ CDEBUG(D_INODE, "Epoch %llu closed on "DFID"\n",
ll_i2info(inode)->lli_ioepoch, PFID(&lli->lli_fid));
op_data->op_flags |= MF_EPOCH_CLOSE;
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 140ee947ba49..634ffa645e06 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -36,16 +36,16 @@
#ifndef LLITE_INTERNAL_H
#define LLITE_INTERNAL_H
-#include <lustre_debug.h>
-#include <lustre_ver.h>
-#include <lustre_disk.h> /* for s2sbi */
-#include <lustre_eacl.h>
+#include "../include/lustre_debug.h"
+#include "../include/lustre_ver.h"
+#include "../include/lustre_disk.h" /* for s2sbi */
+#include "../include/lustre_eacl.h"
/* for struct cl_lock_descr and struct cl_io */
-#include <cl_object.h>
-#include <lclient.h>
-#include <lustre_mdc.h>
-#include <linux/lustre_intent.h>
+#include "../include/cl_object.h"
+#include "../include/lclient.h"
+#include "../include/lustre_mdc.h"
+#include "../include/linux/lustre_intent.h"
#include <linux/compat.h>
#include <linux/posix_acl_xattr.h>
@@ -145,7 +145,7 @@ struct ll_inode_info {
* capability needs renewal */
atomic_t lli_open_count;
struct obd_capa *lli_mds_capa;
- cfs_time_t lli_rmtperm_time;
+ unsigned long lli_rmtperm_time;
/* handle is to be sent to MDS later on done_writing and setattr.
* Open handle data are needed for the recovery to reconstruct
@@ -213,7 +213,7 @@ struct ll_inode_info {
struct mutex f_write_mutex;
struct rw_semaphore f_glimpse_sem;
- cfs_time_t f_glimpse_time;
+ unsigned long f_glimpse_time;
struct list_head f_agl_list;
__u64 f_agl_index;
@@ -670,7 +670,7 @@ void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar);
struct ll_ra_read *ll_ra_read_get(struct file *f);
/* llite/lproc_llite.c */
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
struct super_block *sb, char *osc, char *mdc);
void lprocfs_unregister_mountpoint(struct ll_sb_info *sbi);
@@ -1432,7 +1432,7 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
if (it->d.lustre.it_remote_lock_mode) {
handle.cookie = it->d.lustre.it_remote_lock_handle;
CDEBUG(D_DLMTRACE, "setting l_data to inode %p"
- "(%lu/%u) for remote lock "LPX64"\n", inode,
+ "(%lu/%u) for remote lock %#llx\n", inode,
inode->i_ino, inode->i_generation,
handle.cookie);
md_set_lock_data(exp, &handle.cookie, inode, NULL);
@@ -1441,7 +1441,7 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode,
handle.cookie = it->d.lustre.it_lock_handle;
CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)"
- " for lock "LPX64"\n", inode, inode->i_ino,
+ " for lock %#llx\n", inode, inode->i_ino,
inode->i_generation, handle.cookie);
md_set_lock_data(exp, &handle.cookie, inode,
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index deca27ea33fe..0367f5a2cfe4 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -44,15 +44,15 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include <lustre_lite.h>
-#include <lustre_ha.h>
-#include <lustre_dlm.h>
-#include <lprocfs_status.h>
-#include <lustre_disk.h>
-#include <lustre_param.h>
-#include <lustre_log.h>
-#include <cl_object.h>
-#include <obd_cksum.h>
+#include "../include/lustre_lite.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 "llite_internal.h"
struct kmem_cache *ll_file_data_slab;
@@ -152,7 +152,7 @@ static void ll_free_sbi(struct super_block *sb)
static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
struct vfsmount *mnt)
{
- struct inode *root = 0;
+ struct inode *root = NULL;
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct obd_device *obd;
struct obd_capa *oc = NULL;
@@ -426,7 +426,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
data->ocd_connect_flags |= OBD_CONNECT_RMT_CLIENT_FORCE;
- CDEBUG(D_RPCTRACE, "ocd_connect_flags: "LPX64" ocd_version: %d "
+ CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d "
"ocd_grant: %d\n", data->ocd_connect_flags,
data->ocd_version, data->ocd_grant);
@@ -1296,7 +1296,7 @@ static int ll_setattr_done_writing(struct inode *inode,
if (!S_ISREG(inode->i_mode))
return 0;
- CDEBUG(D_INODE, "Epoch "LPU64" closed on "DFID" for truncate\n",
+ CDEBUG(D_INODE, "Epoch %llu closed on "DFID" for truncate\n",
op_data->op_ioepoch, PFID(&lli->lli_fid));
op_data->op_flags = MF_EPOCH_CLOSE;
@@ -1377,7 +1377,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
* OST maximum object size and number of stripes. This
* needs another check in addition to the VFS check above. */
if (attr->ia_size > ll_file_maxbytes(inode)) {
- CDEBUG(D_INODE,"file "DFID" too large %llu > "LPU64"\n",
+ CDEBUG(D_INODE,"file "DFID" too large %llu > %llu\n",
PFID(&lli->lli_fid), attr->ia_size,
ll_file_maxbytes(inode));
return -EFBIG;
@@ -1412,7 +1412,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n",
LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
- cfs_time_current_sec());
+ get_seconds());
/* If we are changing file size, file content is modified, flag it. */
if (attr->ia_valid & ATTR_SIZE) {
@@ -1537,12 +1537,14 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
!(attr->ia_mode & S_ISGID))))
attr->ia_valid |= ATTR_FORCE;
- if ((mode & S_ISUID) &&
+ if ((attr->ia_valid & ATTR_MODE) &&
+ (mode & S_ISUID) &&
!(attr->ia_mode & S_ISUID) &&
!(attr->ia_valid & ATTR_KILL_SUID))
attr->ia_valid |= ATTR_KILL_SUID;
- if (((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
+ if ((attr->ia_valid & ATTR_MODE) &&
+ ((mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP)) &&
!(attr->ia_mode & S_ISGID) &&
!(attr->ia_valid & ATTR_KILL_SGID))
attr->ia_valid |= ATTR_KILL_SGID;
@@ -1565,7 +1567,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
osfs->os_type = sb->s_magic;
- CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+ CDEBUG(D_SUPER, "MDC blocks %llu/%llu objects %llu/%llu\n",
osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
if (sbi->ll_flags & LL_SBI_LAZYSTATFS)
@@ -1577,7 +1579,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
return rc;
}
- CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n",
+ CDEBUG(D_SUPER, "OSC blocks %llu/%llu objects %llu/%llu\n",
obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree,
obd_osfs.os_files);
@@ -1604,7 +1606,7 @@ int ll_statfs(struct dentry *de, struct kstatfs *sfs)
struct obd_statfs osfs;
int rc;
- CDEBUG(D_VFSTRACE, "VFS Op: at "LPU64" jiffies\n", get_jiffies_64());
+ CDEBUG(D_VFSTRACE, "VFS Op: at %llu jiffies\n", get_jiffies_64());
ll_stats_ops_tally(ll_s2sbi(sb), LPROC_LL_STAFS, 1);
/* Some amount of caching on the client is allowed */
@@ -1697,9 +1699,9 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
}
if (body->valid & OBD_MD_FLMTIME) {
if (body->mtime > LTIME_S(inode->i_mtime)) {
- CDEBUG(D_INODE, "setting ino %lu mtime from %lu "
- "to "LPU64"\n", inode->i_ino,
- LTIME_S(inode->i_mtime), body->mtime);
+ CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %llu\n",
+ inode->i_ino, LTIME_S(inode->i_mtime),
+ body->mtime);
LTIME_S(inode->i_mtime) = body->mtime;
}
lli->lli_lvb.lvb_mtime = body->mtime;
@@ -1997,7 +1999,7 @@ void ll_umount_begin(struct super_block *sb)
obd = class_exp2obd(sbi->ll_md_exp);
if (obd == NULL) {
- CERROR("Invalid MDC connection handle "LPX64"\n",
+ CERROR("Invalid MDC connection handle %#llx\n",
sbi->ll_md_exp->exp_handle.h_cookie);
return;
}
@@ -2005,7 +2007,7 @@ void ll_umount_begin(struct super_block *sb)
obd = class_exp2obd(sbi->ll_dt_exp);
if (obd == NULL) {
- CERROR("Invalid LOV connection handle "LPX64"\n",
+ CERROR("Invalid LOV connection handle %#llx\n",
sbi->ll_dt_exp->exp_handle.h_cookie);
return;
}
@@ -2245,7 +2247,7 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data,
op_data->op_name = name;
op_data->op_namelen = namelen;
op_data->op_mode = mode;
- op_data->op_mod_time = cfs_time_current_sec();
+ op_data->op_mod_time = get_seconds();
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();
diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c
index 426c73961665..7dae610f5c86 100644
--- a/drivers/staging/lustre/lustre/llite/llite_mmap.c
+++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c
@@ -47,9 +47,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
-#include <linux/lustre_compat25.h>
+#include "../include/linux/lustre_compat25.h"
static const struct vm_operations_struct ll_file_vm_ops;
@@ -449,7 +449,7 @@ int ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last)
{
int rc = -ENOENT;
- LASSERTF(last > first, "last "LPU64" first "LPU64"\n", last, first);
+ LASSERTF(last > first, "last %llu first %llu\n", last, first);
if (mapping_mapped(mapping)) {
rc = 0;
unmap_mapping_range(mapping, first + PAGE_CACHE_SIZE - 1,
diff --git a/drivers/staging/lustre/lustre/llite/llite_nfs.c b/drivers/staging/lustre/lustre/llite/llite_nfs.c
index a614b913ddc2..8fdd6e093d1a 100644
--- a/drivers/staging/lustre/lustre/llite/llite_nfs.c
+++ b/drivers/staging/lustre/lustre/llite/llite_nfs.c
@@ -42,7 +42,7 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include <linux/exportfs.h>
diff --git a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c
index 4c610369cb9b..be0c3eff108c 100644
--- a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c
+++ b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c
@@ -44,8 +44,8 @@
#ifdef CONFIG_FS_POSIX_ACL
-#include <lustre_lite.h>
-#include <lustre_eacl.h>
+#include "../include/lustre_lite.h"
+#include "../include/lustre_eacl.h"
#include "llite_internal.h"
static inline __u32 rce_hashfunc(uid_t id)
diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c
index 0ff8c3362a8d..808663898b73 100644
--- a/drivers/staging/lustre/lustre/llite/lloop.c
+++ b/drivers/staging/lustre/lustre/llite/lloop.c
@@ -103,8 +103,8 @@
#include <asm/uaccess.h>
-#include <lustre_lib.h>
-#include <lustre_lite.h>
+#include "../include/lustre_lib.h"
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
#define LLOOP_MAX_SEGMENTS LNET_MAX_IOV
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index 77ee9e58cf87..77f68b507fea 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -35,10 +35,10 @@
*/
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
-#include <lprocfs_status.h>
+#include "../include/lustre_lite.h"
+#include "../include/lprocfs_status.h"
#include <linux/seq_file.h>
-#include <obd_support.h>
+#include "../include/obd_support.h"
#include "llite_internal.h"
#include "vvp_internal.h"
@@ -82,7 +82,7 @@ static int ll_kbytestotal_seq_show(struct seq_file *m, void *v)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -105,7 +105,7 @@ static int ll_kbytesfree_seq_show(struct seq_file *m, void *v)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -128,7 +128,7 @@ static int ll_kbytesavail_seq_show(struct seq_file *m, void *v)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -145,7 +145,7 @@ static int ll_filestotal_seq_show(struct seq_file *m, void *v)
cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
OBD_STATFS_NODELAY);
if (!rc)
- rc = seq_printf(m, LPU64"\n", osfs.os_files);
+ rc = seq_printf(m, "%llu\n", osfs.os_files);
return rc;
}
LPROC_SEQ_FOPS_RO(ll_filestotal);
@@ -161,7 +161,7 @@ static int ll_filesfree_seq_show(struct seq_file *m, void *v)
cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
OBD_STATFS_NODELAY);
if (!rc)
- rc = seq_printf(m, LPU64"\n", osfs.os_ffree);
+ rc = seq_printf(m, "%llu\n", osfs.os_ffree);
return rc;
}
LPROC_SEQ_FOPS_RO(ll_filesfree);
@@ -811,38 +811,39 @@ static ssize_t ll_xattr_cache_seq_write(struct file *file, const char *buffer,
LPROC_SEQ_FOPS(ll_xattr_cache);
static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
- { "uuid", &ll_sb_uuid_fops, 0, 0 },
+ { "uuid", &ll_sb_uuid_fops, NULL, 0 },
//{ "mntpt_path", ll_rd_path, 0, 0 },
- { "fstype", &ll_fstype_fops, 0, 0 },
- { "site", &ll_site_stats_fops, 0, 0 },
- { "blocksize", &ll_blksize_fops, 0, 0 },
- { "kbytestotal", &ll_kbytestotal_fops, 0, 0 },
- { "kbytesfree", &ll_kbytesfree_fops, 0, 0 },
- { "kbytesavail", &ll_kbytesavail_fops, 0, 0 },
- { "filestotal", &ll_filestotal_fops, 0, 0 },
- { "filesfree", &ll_filesfree_fops, 0, 0 },
- { "client_type", &ll_client_type_fops, 0, 0 },
+ { "fstype", &ll_fstype_fops, NULL, 0 },
+ { "site", &ll_site_stats_fops, NULL, 0 },
+ { "blocksize", &ll_blksize_fops, NULL, 0 },
+ { "kbytestotal", &ll_kbytestotal_fops, NULL, 0 },
+ { "kbytesfree", &ll_kbytesfree_fops, NULL, 0 },
+ { "kbytesavail", &ll_kbytesavail_fops, NULL, 0 },
+ { "filestotal", &ll_filestotal_fops, NULL, 0 },
+ { "filesfree", &ll_filesfree_fops, NULL, 0 },
+ { "client_type", &ll_client_type_fops, NULL, 0 },
//{ "filegroups", lprocfs_rd_filegroups, 0, 0 },
- { "max_read_ahead_mb", &ll_max_readahead_mb_fops, 0 },
- { "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops, 0 },
- { "max_read_ahead_whole_mb", &ll_max_read_ahead_whole_mb_fops, 0 },
- { "max_cached_mb", &ll_max_cached_mb_fops, 0 },
- { "checksum_pages", &ll_checksum_fops, 0 },
- { "max_rw_chunk", &ll_max_rw_chunk_fops, 0 },
- { "stats_track_pid", &ll_track_pid_fops, 0 },
- { "stats_track_ppid", &ll_track_ppid_fops, 0 },
- { "stats_track_gid", &ll_track_gid_fops, 0 },
- { "statahead_max", &ll_statahead_max_fops, 0 },
- { "statahead_agl", &ll_statahead_agl_fops, 0 },
- { "statahead_stats", &ll_statahead_stats_fops, 0, 0 },
- { "lazystatfs", &ll_lazystatfs_fops, 0 },
- { "max_easize", &ll_max_easize_fops, 0, 0 },
- { "default_easize", &ll_defult_easize_fops, 0, 0 },
- { "max_cookiesize", &ll_max_cookiesize_fops, 0, 0 },
- { "default_cookiesize", &ll_defult_cookiesize_fops, 0, 0 },
- { "sbi_flags", &ll_sbi_flags_fops, 0, 0 },
- { "xattr_cache", &ll_xattr_cache_fops, 0, 0 },
- { 0 }
+ { "max_read_ahead_mb", &ll_max_readahead_mb_fops, NULL },
+ { "max_read_ahead_per_file_mb", &ll_max_readahead_per_file_mb_fops,
+ NULL },
+ { "max_read_ahead_whole_mb", &ll_max_read_ahead_whole_mb_fops, NULL },
+ { "max_cached_mb", &ll_max_cached_mb_fops, NULL },
+ { "checksum_pages", &ll_checksum_fops, NULL },
+ { "max_rw_chunk", &ll_max_rw_chunk_fops, NULL },
+ { "stats_track_pid", &ll_track_pid_fops, NULL },
+ { "stats_track_ppid", &ll_track_ppid_fops, NULL },
+ { "stats_track_gid", &ll_track_gid_fops, NULL },
+ { "statahead_max", &ll_statahead_max_fops, NULL },
+ { "statahead_agl", &ll_statahead_agl_fops, NULL },
+ { "statahead_stats", &ll_statahead_stats_fops, NULL, 0 },
+ { "lazystatfs", &ll_lazystatfs_fops, NULL },
+ { "max_easize", &ll_max_easize_fops, NULL, 0 },
+ { "default_easize", &ll_defult_easize_fops, NULL, 0 },
+ { "max_cookiesize", &ll_max_cookiesize_fops, NULL, 0 },
+ { "default_cookiesize", &ll_defult_cookiesize_fops, NULL, 0 },
+ { "sbi_flags", &ll_sbi_flags_fops, NULL, 0 },
+ { "xattr_cache", &ll_xattr_cache_fops, NULL, 0 },
+ { NULL }
};
#define MAX_STRING_SIZE 128
@@ -909,7 +910,7 @@ void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count)
sbi->ll_stats_track_id == current->pid)
lprocfs_counter_add(sbi->ll_stats, op, count);
else if (sbi->ll_stats_track_type == STATS_TRACK_PPID &&
- sbi->ll_stats_track_id == current->parent->pid)
+ sbi->ll_stats_track_id == current->real_parent->pid)
lprocfs_counter_add(sbi->ll_stats, op, count);
else if (sbi->ll_stats_track_type == STATS_TRACK_GID &&
sbi->ll_stats_track_id ==
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c
index dfa1e745dfd6..0dc7173bbd41 100644
--- a/drivers/staging/lustre/lustre/llite/namei.c
+++ b/drivers/staging/lustre/lustre/llite/namei.c
@@ -44,11 +44,11 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd_support.h>
-#include <lustre_fid.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
-#include <lustre_ver.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_ver.h"
#include "llite_internal.h"
static int ll_create_it(struct inode *, struct dentry *,
@@ -105,7 +105,7 @@ static int ll_set_inode(struct inode *inode, void *opaque)
lli->lli_fid = body->fid1;
if (unlikely(!(body->valid & OBD_MD_FLTYPE))) {
CERROR("Can not initialize inode "DFID" without object type: "
- "valid = "LPX64"\n", PFID(&lli->lli_fid), body->valid);
+ "valid = %#llx\n", PFID(&lli->lli_fid), body->valid);
return -EINVAL;
}
@@ -758,7 +758,7 @@ static void ll_update_times(struct ptlrpc_request *request,
LASSERT(body);
if (body->valid & OBD_MD_FLMTIME &&
body->mtime > LTIME_S(inode->i_mtime)) {
- CDEBUG(D_INODE, "setting ino %lu mtime from %lu to "LPU64"\n",
+ CDEBUG(D_INODE, "setting ino %lu mtime from %lu to %llu\n",
inode->i_ino, LTIME_S(inode->i_mtime), body->mtime);
LTIME_S(inode->i_mtime) = body->mtime;
}
diff --git a/drivers/staging/lustre/lustre/llite/remote_perm.c b/drivers/staging/lustre/lustre/llite/remote_perm.c
index a8b1117b8f60..f61fefc9baf0 100644
--- a/drivers/staging/lustre/lustre/llite/remote_perm.c
+++ b/drivers/staging/lustre/lustre/llite/remote_perm.c
@@ -46,12 +46,12 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <lustre_lite.h>
-#include <lustre_ha.h>
-#include <lustre_dlm.h>
-#include <lprocfs_status.h>
-#include <lustre_disk.h>
-#include <lustre_param.h>
+#include "../include/lustre_lite.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 "llite_internal.h"
struct kmem_cache *ll_remote_perm_cachep = NULL;
@@ -249,7 +249,7 @@ int lustre_check_remote_perm(struct inode *inode, int mask)
struct ptlrpc_request *req = NULL;
struct mdt_remote_perm *perm;
struct obd_capa *oc;
- cfs_time_t save;
+ unsigned long save;
int i = 0, rc;
do {
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c
index 56162103cc79..ecd7a229cf9b 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -54,10 +54,10 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
-#include <obd_cksum.h>
+#include "../include/lustre_lite.h"
+#include "../include/obd_cksum.h"
#include "llite_internal.h"
-#include <linux/lustre_compat25.h>
+#include "../include/linux/lustre_compat25.h"
/**
* Finalizes cl-data before exiting typical address_space operation. Dual to
@@ -496,14 +496,9 @@ static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io,
struct cl_object *clob = ll_i2info(mapping->host)->lli_clob;
struct cl_page *page;
enum ra_stat which = _NR_RA_STAT; /* keep gcc happy */
- unsigned int gfp_mask;
int rc = 0;
const char *msg = NULL;
- gfp_mask = GFP_HIGHUSER & ~__GFP_WAIT;
-#ifdef __GFP_NOWARN
- gfp_mask |= __GFP_NOWARN;
-#endif
vmpage = grab_cache_page_nowait(mapping, index);
if (vmpage != NULL) {
/* Check if vmpage was truncated or reclaimed */
@@ -601,7 +596,7 @@ stride_pg_count(pgoff_t st_off, unsigned long st_len, unsigned long st_pgs,
if (end_left > st_pgs)
end_left = st_pgs;
- CDEBUG(D_READA, "start "LPU64", end "LPU64" start_left %lu end_left %lu \n",
+ CDEBUG(D_READA, "start %llu, end %llu start_left %lu end_left %lu \n",
start, end, start_left, end_left);
if (start == end)
@@ -1013,7 +1008,7 @@ void ras_update(struct ll_sb_info *sbi, struct inode *inode,
kms_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
PAGE_CACHE_SHIFT;
- CDEBUG(D_READA, "kmsp "LPU64" mwp %lu mp %lu\n", kms_pages,
+ CDEBUG(D_READA, "kmsp %llu mwp %lu mp %lu\n", kms_pages,
ra->ra_max_read_ahead_whole_pages, ra->ra_max_pages_per_file);
if (kms_pages &&
diff --git a/drivers/staging/lustre/lustre/llite/rw26.c b/drivers/staging/lustre/lustre/llite/rw26.c
index af84c1aaa5f8..3f157e76a15c 100644
--- a/drivers/staging/lustre/lustre/llite/rw26.c
+++ b/drivers/staging/lustre/lustre/llite/rw26.c
@@ -55,9 +55,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
-#include <linux/lustre_compat25.h>
+#include "../include/linux/lustre_compat25.h"
/**
* Implements Linux VM address_space::invalidatepage() method. This method is
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 1b47774d7447..c39cf8d47d6e 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -42,9 +42,9 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd_support.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
#include "llite_internal.h"
#define SA_OMITTED_ENTRY_MAX 8ULL
@@ -206,7 +206,7 @@ ll_sa_entry_alloc(struct ll_statahead_info *sai, __u64 index,
if (unlikely(entry == NULL))
return ERR_PTR(-ENOMEM);
- CDEBUG(D_READA, "alloc sa entry %.*s(%p) index "LPU64"\n",
+ CDEBUG(D_READA, "alloc sa entry %.*s(%p) index %llu\n",
len, name, entry, index);
entry->se_index = index;
@@ -325,7 +325,7 @@ static void ll_sa_entry_put(struct ll_statahead_info *sai,
struct ll_sa_entry *entry)
{
if (atomic_dec_and_test(&entry->se_refcount)) {
- CDEBUG(D_READA, "free sa entry %.*s(%p) index "LPU64"\n",
+ CDEBUG(D_READA, "free sa entry %.*s(%p) index %llu\n",
entry->se_qstr.len, entry->se_qstr.name, entry,
entry->se_index);
@@ -528,8 +528,8 @@ static void ll_sai_put(struct ll_statahead_info *sai)
spin_unlock(&lli->lli_sa_lock);
if (sai->sai_sent > sai->sai_replied)
- CDEBUG(D_READA,"statahead for dir "DFID" does not "
- "finish: [sent:"LPU64"] [replied:"LPU64"]\n",
+ CDEBUG(D_READA,"statahead for dir "DFID
+ " does not finish: [sent:%llu] [replied:%llu]\n",
PFID(&lli->lli_fid),
sai->sai_sent, sai->sai_replied);
@@ -587,7 +587,7 @@ static void ll_agl_trigger(struct inode *inode, struct ll_statahead_info *sai)
* affect the performance.
*/
if (lli->lli_glimpse_time != 0 &&
- cfs_time_before(cfs_time_shift(-1), lli->lli_glimpse_time)) {
+ time_before(cfs_time_shift(-1), lli->lli_glimpse_time)) {
up_write(&lli->lli_glimpse_sem);
lli->lli_agl_index = 0;
iput(inode);
@@ -595,7 +595,7 @@ static void ll_agl_trigger(struct inode *inode, struct ll_statahead_info *sai)
}
CDEBUG(D_READA, "Handling (init) async glimpse: inode = "
- DFID", idx = "LPU64"\n", PFID(&lli->lli_fid), index);
+ DFID", idx = %llu\n", PFID(&lli->lli_fid), index);
cl_agl(inode);
lli->lli_agl_index = 0;
@@ -603,7 +603,7 @@ static void ll_agl_trigger(struct inode *inode, struct ll_statahead_info *sai)
up_write(&lli->lli_glimpse_sem);
CDEBUG(D_READA, "Handled (init) async glimpse: inode= "
- DFID", idx = "LPU64", rc = %d\n",
+ DFID", idx = %llu, rc = %d\n",
PFID(&lli->lli_fid), index, rc);
iput(inode);
@@ -1081,8 +1081,7 @@ static int ll_statahead_thread(void *arg)
if (IS_ERR(page)) {
rc = PTR_ERR(page);
- CDEBUG(D_READA, "error reading dir "DFID" at "LPU64
- "/"LPU64": [rc %d] [parent %u]\n",
+ CDEBUG(D_READA, "error reading dir "DFID" at %llu/%llu: [rc %d] [parent %u]\n",
PFID(ll_inode2fid(dir)), pos, sai->sai_index,
rc, plli->lli_opendir_pid);
GOTO(out, rc);
@@ -1362,8 +1361,7 @@ static int is_first_dirent(struct inode *dir, struct dentry *dentry)
struct ll_inode_info *lli = ll_i2info(dir);
rc = PTR_ERR(page);
- CERROR("error reading dir "DFID" at "LPU64": "
- "[rc %d] [parent %u]\n",
+ CERROR("error reading dir "DFID" at %llu: [rc %d] [parent %u]\n",
PFID(ll_inode2fid(dir)), pos,
rc, lli->lli_opendir_pid);
break;
@@ -1479,8 +1477,8 @@ ll_sai_unplug(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
if (sa_low_hit(sai) && thread_is_running(thread)) {
atomic_inc(&sbi->ll_sa_wrong);
CDEBUG(D_READA, "Statahead for dir "DFID" hit "
- "ratio too low: hit/miss "LPU64"/"LPU64
- ", sent/replied "LPU64"/"LPU64", stopping "
+ "ratio too low: hit/miss %llu/%llu"
+ ", sent/replied %llu/%llu, stopping "
"statahead thread\n",
PFID(&lli->lli_fid), sai->sai_hit,
sai->sai_miss, sai->sai_sent,
diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c
index 951fdb1265b9..078c0e95f4cf 100644
--- a/drivers/staging/lustre/lustre/llite/super25.c
+++ b/drivers/staging/lustre/lustre/llite/super25.c
@@ -38,12 +38,12 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <lustre_lite.h>
-#include <lustre_ha.h>
-#include <lustre_dlm.h>
+#include "../include/lustre_lite.h"
+#include "../include/lustre_ha.h"
+#include "../include/lustre_dlm.h"
#include <linux/init.h>
#include <linux/fs.h>
-#include <lprocfs_status.h>
+#include "../include/lprocfs_status.h"
#include "llite_internal.h"
static struct kmem_cache *ll_inode_cachep;
diff --git a/drivers/staging/lustre/lustre/llite/symlink.c b/drivers/staging/lustre/lustre/llite/symlink.c
index 129d3023dcea..20e678b31c7b 100644
--- a/drivers/staging/lustre/lustre/llite/symlink.c
+++ b/drivers/staging/lustre/lustre/llite/symlink.c
@@ -39,7 +39,7 @@
#include <linux/stat.h>
#define DEBUG_SUBSYSTEM S_LLITE
-#include <lustre_lite.h>
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
static int ll_readlink_internal(struct inode *inode,
diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c
index 0f68c16abe30..0f2e79d6b7f8 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_dev.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c
@@ -41,8 +41,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd.h>
-#include <lustre_lite.h>
+#include "../include/obd.h"
+#include "../include/lustre_lite.h"
#include "llite_internal.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index 3c9a03d99559..2162bf6c08a7 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -40,7 +40,7 @@
#define VVP_INTERNAL_H
-#include <cl_object.h>
+#include "../include/cl_object.h"
#include "llite_internal.h"
int vvp_io_init (const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index 0e0b404cb5e6..a4117d6a3866 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -42,8 +42,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd.h>
-#include <lustre_lite.h>
+#include "../include/obd.h"
+#include "../include/lustre_lite.h"
#include "vvp_internal.h"
@@ -269,8 +269,10 @@ static int vvp_mmap_locks(const struct lu_env *env,
descr->cld_mode, descr->cld_start,
descr->cld_end);
- if (result < 0)
+ if (result < 0) {
+ up_read(&mm->mmap_sem);
return result;
+ }
if (vma->vm_end - addr >= count)
break;
@@ -622,7 +624,7 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio)
page_private(vmf->page), vmf->virtual_address);
if (unlikely(!(cfio->fault.ft_flags & VM_FAULT_LOCKED))) {
lock_page(vmf->page);
- cfio->fault.ft_flags &= VM_FAULT_LOCKED;
+ cfio->fault.ft_flags |= VM_FAULT_LOCKED;
}
cfio->ft_vmpage = vmf->page;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c
index e16b31e4ff72..372633e164b9 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_lock.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c
@@ -39,8 +39,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd.h>
-#include <lustre_lite.h>
+#include "../include/obd.h"
+#include "../include/lustre_lite.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 65b6db1b71b4..b6f6d4cb6e41 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_object.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_object.c
@@ -41,10 +41,10 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd.h>
-#include <lustre_lite.h>
+#include "../include/obd.h"
+#include "../include/lustre_lite.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c
index 1c02c128e0ee..4626346f6ee1 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_page.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_page.c
@@ -42,8 +42,8 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd.h>
-#include <lustre_lite.h>
+#include "../include/obd.h"
+#include "../include/lustre_lite.h"
#include "vvp_internal.h"
diff --git a/drivers/staging/lustre/lustre/llite/xattr.c b/drivers/staging/lustre/lustre/llite/xattr.c
index c6c27bbb43b4..665ca572027f 100644
--- a/drivers/staging/lustre/lustre/llite/xattr.c
+++ b/drivers/staging/lustre/lustre/llite/xattr.c
@@ -41,11 +41,11 @@
#define DEBUG_SUBSYSTEM S_LLITE
-#include <obd_support.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
-#include <lustre_ver.h>
-#include <lustre_eacl.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_ver.h"
+#include "../include/lustre_eacl.h"
#include "llite_internal.h"
@@ -246,6 +246,7 @@ int ll_setxattr(struct dentry *dentry, const char *name,
int lum_size = (lump->lmm_magic == LOV_USER_MAGIC_V1) ?
sizeof(*lump) : sizeof(struct lov_user_md_v3);
+ memset(&f, 0, sizeof(f)); /* f.f_flags is used below */
f.f_dentry = dentry;
rc = ll_lov_setstripe_ea_info(inode, &f, flags, lump,
lum_size);
diff --git a/drivers/staging/lustre/lustre/llite/xattr_cache.c b/drivers/staging/lustre/lustre/llite/xattr_cache.c
index 4dd83fc03687..edec945d2eb3 100644
--- a/drivers/staging/lustre/lustre/llite/xattr_cache.c
+++ b/drivers/staging/lustre/lustre/llite/xattr_cache.c
@@ -10,10 +10,10 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <obd_support.h>
-#include <lustre_lite.h>
-#include <lustre_dlm.h>
-#include <lustre_ver.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_ver.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/lmv/Makefile b/drivers/staging/lustre/lustre/lmv/Makefile
index 9162ef724aea..a7a15369af15 100644
--- a/drivers/staging/lustre/lustre/lmv/Makefile
+++ b/drivers/staging/lustre/lustre/lmv/Makefile
@@ -1,5 +1,3 @@
obj-$(CONFIG_LUSTRE_FS) += lmv.o
lmv-y := lmv_obd.o lmv_intent.o lmv_fld.o
lmv-$(CONFIG_PROC_FS) += lproc_lmv.o
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
index fd6b5ec61d8a..8289bcc5f8e1 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c
@@ -41,14 +41,14 @@
#include <asm/div64.h>
#include <linux/seq_file.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.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 "../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 "lmv_internal.h"
int lmv_fld_lookup(struct lmv_obd *lmv,
@@ -66,8 +66,8 @@ int lmv_fld_lookup(struct lmv_obd *lmv,
rc = fld_client_lookup(&lmv->lmv_fld, fid_seq(fid), mds,
LU_SEQ_RANGE_MDT, NULL);
if (rc) {
- CERROR("Error while looking for mds number. Seq "LPX64
- ", err = %d\n", fid_seq(fid), rc);
+ CERROR("Error while looking for mds number. Seq %#llx, err = %d\n",
+ fid_seq(fid), rc);
return rc;
}
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_intent.c b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
index 9ba5a0a57390..aba698f4489c 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_intent.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_intent.c
@@ -41,15 +41,14 @@
#include <asm/div64.h>
#include <linux/seq_file.h>
#include <linux/namei.h>
-#include <linux/lustre_intent.h>
-
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_lib.h>
-#include <lustre_net.h>
-#include <lustre_dlm.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include "../include/linux/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/obd_class.h"
+#include "../include/lprocfs_status.h"
#include "lmv_internal.h"
static int lmv_intent_remote(struct obd_export *exp, void *lmm,
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
index f75b0a987681..eb18a5900e13 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h
+++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h
@@ -37,8 +37,8 @@
#ifndef _LMV_INTERNAL_H_
#define _LMV_INTERNAL_H_
-#include <lustre/lustre_idl.h>
-#include <obd.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../include/obd.h"
#define LMV_MAX_TGT_COUNT 128
@@ -146,7 +146,7 @@ struct lmv_tgt_desc
*lmv_locate_mds(struct lmv_obd *lmv, struct md_op_data *op_data,
struct lu_fid *fid);
/* lproc_lmv.c */
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars);
#else
static inline void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 4edf8a31221c..a66b3e000d57 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -45,14 +45,14 @@
#include <linux/namei.h>
#include <asm/uaccess.h>
-#include <lustre/lustre_idl.h>
-#include <obd_support.h>
-#include <lustre_lib.h>
-#include <lustre_net.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
-#include <lustre_lite.h>
-#include <lustre_fid.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_lib.h"
+#include "../include/lustre_net.h"
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_lite.h"
+#include "../include/lustre_fid.h"
#include "lmv_internal.h"
static void lmv_activate_target(struct lmv_obd *lmv,
@@ -90,7 +90,7 @@ static int lmv_set_mdc_active(struct lmv_obd *lmv, struct obd_uuid *uuid,
if (tgt == NULL || tgt->ltd_exp == NULL)
continue;
- CDEBUG(D_INFO, "Target idx %d is %s conn "LPX64"\n", i,
+ CDEBUG(D_INFO, "Target idx %d is %s conn %#llx\n", i,
tgt->ltd_uuid.uuid, tgt->ltd_exp->exp_handle.h_cookie);
if (obd_uuid_equals(uuid, &tgt->ltd_uuid))
@@ -735,7 +735,7 @@ repeat_fid2path:
*ptr = '/';
}
- CDEBUG(D_INFO, "%s: get path %s "DFID" rec: "LPU64" ln: %u\n",
+ CDEBUG(D_INFO, "%s: get path %s "DFID" rec: %llu ln: %u\n",
tgt->ltd_exp->exp_obd->obd_name,
gf->gf_path, PFID(&gf->gf_fid), gf->gf_recno,
gf->gf_linkno);
@@ -1339,7 +1339,7 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
lprocfs_lmv_init_vars(&lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
{
rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
0444, &lmv_proc_target_fops, obd);
@@ -1715,7 +1715,7 @@ static int
lmv_enqueue_remote(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
struct lookup_intent *it, struct md_op_data *op_data,
struct lustre_handle *lockh, void *lmm, int lmmsize,
- int extra_lock_flags)
+ __u64 extra_lock_flags)
{
struct ptlrpc_request *req = it->d.lustre.it_data;
struct obd_device *obd = exp->exp_obd;
@@ -2173,7 +2173,7 @@ static int lmv_readpage(struct obd_export *exp, struct md_op_data *op_data,
if (rc)
return rc;
- CDEBUG(D_INODE, "READPAGE at "LPX64" from "DFID"\n",
+ CDEBUG(D_INODE, "READPAGE at %#llx from "DFID"\n",
offset, PFID(&op_data->op_fid1));
tgt = lmv_find_target(lmv, &op_data->op_fid1);
@@ -2315,7 +2315,7 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
obd = class_exp2obd(exp);
if (obd == NULL) {
- CDEBUG(D_IOCTL, "Invalid client cookie "LPX64"\n",
+ CDEBUG(D_IOCTL, "Invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
@@ -2381,7 +2381,7 @@ int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
obd = class_exp2obd(exp);
if (obd == NULL) {
- CDEBUG(D_IOCTL, "Invalid client cookie "LPX64"\n",
+ CDEBUG(D_IOCTL, "Invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index ae73c82ce499..310df44f948d 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -38,8 +38,8 @@
#include <linux/seq_file.h>
#include <asm/statfs.h>
-#include <lprocfs_status.h>
-#include <obd_class.h>
+#include "../include/lprocfs_status.h"
+#include "../include/obd_class.h"
static int lmv_numobd_seq_show(struct seq_file *m, void *v)
{
diff --git a/drivers/staging/lustre/lustre/lov/Makefile b/drivers/staging/lustre/lustre/lov/Makefile
index a908edb533d3..6fe56a24b165 100644
--- a/drivers/staging/lustre/lustre/lov/Makefile
+++ b/drivers/staging/lustre/lustre/lov/Makefile
@@ -4,7 +4,3 @@ lov-y := lov_obd.o lov_pack.o lov_offset.o lov_merge.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
lov-$(CONFIG_PROC_FS) += lproc_lov.o
-
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
index 3965d5e4e725..99ade92c5e64 100644
--- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h
@@ -46,10 +46,10 @@
#ifndef LOV_CL_INTERNAL_H
#define LOV_CL_INTERNAL_H
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd.h>
-#include <cl_object.h>
+#include "../include/obd.h"
+#include "../include/cl_object.h"
#include "lov_internal.h"
/** \defgroup lov lov
diff --git a/drivers/staging/lustre/lustre/lov/lov_dev.c b/drivers/staging/lustre/lustre/lov/lov_dev.c
index 53e5781ba1d9..796a015d070c 100644
--- a/drivers/staging/lustre/lustre/lov/lov_dev.c
+++ b/drivers/staging/lustre/lustre/lov/lov_dev.c
@@ -41,7 +41,7 @@
#define DEBUG_SUBSYSTEM S_LOV
/* class_name2obd() */
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include "lov_cl_internal.h"
#include "lov_internal.h"
@@ -453,7 +453,7 @@ static int lov_process_config(const struct lu_env *env,
case LCFG_LOV_ADD_INA:
rc = lov_cl_add_target(env, d, index);
if (rc != 0)
- lov_del_target(d->ld_obd, index, 0, 0);
+ lov_del_target(d->ld_obd, index, NULL, 0);
break;
case LCFG_LOV_DEL_OBD:
lov_cl_del_target(env, d, index);
diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c
index a0c148e31f69..2401ca872507 100644
--- a/drivers/staging/lustre/lustre/lov/lov_ea.c
+++ b/drivers/staging/lustre/lustre/lov/lov_ea.c
@@ -41,10 +41,10 @@
#define DEBUG_SUBSYSTEM S_LOV
#include <asm/div64.h>
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_class.h>
-#include <lustre/lustre_idl.h>
+#include "../include/obd_class.h"
+#include "../include/lustre/lustre_idl.h"
#include "lov_internal.h"
@@ -348,7 +348,7 @@ const struct lsm_operations lsm_v3_ops = {
void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm)
{
- CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes "LPX64", magic 0x%08X,"
+ CDEBUG(level, "lsm %p, objid "DOSTID", maxbytes %#llx, magic 0x%08X,"
" stripe_size %u, stripe_count %u, refc: %d,"
" layout_gen %u, pool ["LOV_POOLNAMEF"]\n", lsm,
POSTID(&lsm->lsm_oi), lsm->lsm_maxbytes, lsm->lsm_magic,
diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h
index 38508a5c827f..017961a5cc3e 100644
--- a/drivers/staging/lustre/lustre/lov/lov_internal.h
+++ b/drivers/staging/lustre/lustre/lov/lov_internal.h
@@ -37,8 +37,8 @@
#ifndef LOV_INTERNAL_H
#define LOV_INTERNAL_H
-#include <obd_class.h>
-#include <lustre/lustre_user.h>
+#include "../include/obd_class.h"
+#include "../include/lustre/lustre_user.h"
/* lov_do_div64(a, b) returns a % b, and a = a / b.
* The 32-bit code is LOV-specific due to knowing about stripe limits in
@@ -252,7 +252,7 @@ int lov_prep_match_set(struct obd_export *exp, struct obd_info *oinfo,
ldlm_policy_data_t *policy, __u32 mode,
struct lustre_handle *lockh,
struct lov_request_set **reqset);
-int lov_fini_match_set(struct lov_request_set *set, __u32 mode, int flags);
+int lov_fini_match_set(struct lov_request_set *set, __u32 mode, __u64 flags);
int lov_prep_cancel_set(struct obd_export *exp, struct obd_info *oinfo,
struct lov_stripe_md *lsm,
__u32 mode, struct lustre_handle *lockh,
@@ -310,7 +310,7 @@ void dump_lsm(unsigned int level, const struct lov_stripe_md *lsm);
int lovea_destroy_object(struct lov_obd *lov, struct lov_stripe_md *lsm,
struct obdo *oa, void *data);
/* lproc_lov.c */
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern const struct file_operations lov_proc_target_fops;
void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars);
#else
diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c
index 65133ea308b6..ce074c54a003 100644
--- a/drivers/staging/lustre/lustre/lov/lov_io.c
+++ b/drivers/staging/lustre/lustre/lov/lov_io.c
@@ -398,7 +398,7 @@ static int lov_io_iter_init(const struct lu_env *env,
start, end);
rc = cl_io_iter_init(sub->sub_env, sub->sub_io);
lov_sub_put(sub);
- CDEBUG(D_VFSTRACE, "shrink: %d ["LPU64", "LPU64")\n",
+ CDEBUG(D_VFSTRACE, "shrink: %d [%llu, %llu)\n",
stripe, start, end);
} else
rc = PTR_ERR(sub);
@@ -436,8 +436,8 @@ static int lov_io_rw_iter_init(const struct lu_env *env,
next) - io->u.ci_rw.crw_pos;
lio->lis_pos = io->u.ci_rw.crw_pos;
lio->lis_endpos = io->u.ci_rw.crw_pos + io->u.ci_rw.crw_count;
- CDEBUG(D_VFSTRACE, "stripe: "LPU64" chunk: ["LPU64", "LPU64") "
- LPU64"\n", (__u64)start, lio->lis_pos, lio->lis_endpos,
+ CDEBUG(D_VFSTRACE, "stripe: %llu chunk: [%llu, %llu) %llu\n",
+ (__u64)start, lio->lis_pos, lio->lis_endpos,
(__u64)lio->lis_io_endpos);
}
/*
diff --git a/drivers/staging/lustre/lustre/lov/lov_merge.c b/drivers/staging/lustre/lustre/lov/lov_merge.c
index da959e901371..85144b8da96d 100644
--- a/drivers/staging/lustre/lustre/lov/lov_merge.c
+++ b/drivers/staging/lustre/lustre/lov/lov_merge.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include "lov_internal.h"
/** Merge the lock value block(&lvb) attributes and KMS from each of the
@@ -61,10 +61,9 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm,
assert_spin_locked(&lsm->lsm_lock);
LASSERT(lsm->lsm_lock_owner == current_pid());
- CDEBUG(D_INODE, "MDT ID "DOSTID" initial value: s="LPU64" m="LPU64
- " a="LPU64" c="LPU64" b="LPU64"\n", POSTID(&lsm->lsm_oi),
- lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime,
- lvb->lvb_blocks);
+ CDEBUG(D_INODE, "MDT ID "DOSTID" initial value: s=%llu m=%llu a=%llu c=%llu b=%llu\n",
+ POSTID(&lsm->lsm_oi), lvb->lvb_size, lvb->lvb_mtime,
+ lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks);
for (i = 0; i < lsm->lsm_stripe_count; i++) {
struct lov_oinfo *loi = lsm->lsm_oinfo[i];
obd_size lov_size, tmpsize;
@@ -94,11 +93,11 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm,
if (loi->loi_lvb.lvb_ctime > current_ctime)
current_ctime = loi->loi_lvb.lvb_ctime;
- CDEBUG(D_INODE, "MDT ID "DOSTID" on OST[%u]: s="LPU64" m="LPU64
- " a="LPU64" c="LPU64" b="LPU64"\n", POSTID(&lsm->lsm_oi),
- loi->loi_ost_idx, loi->loi_lvb.lvb_size,
- loi->loi_lvb.lvb_mtime, loi->loi_lvb.lvb_atime,
- loi->loi_lvb.lvb_ctime, loi->loi_lvb.lvb_blocks);
+ CDEBUG(D_INODE, "MDT ID "DOSTID" on OST[%u]: s=%llu m=%llu a=%llu c=%llu b=%llu\n",
+ POSTID(&lsm->lsm_oi), loi->loi_ost_idx,
+ loi->loi_lvb.lvb_size, loi->loi_lvb.lvb_mtime,
+ loi->loi_lvb.lvb_atime, loi->loi_lvb.lvb_ctime,
+ loi->loi_lvb.lvb_blocks);
}
*kms_place = kms;
@@ -131,9 +130,9 @@ int lov_merge_lvb(struct obd_export *exp,
if (kms_only)
lvb->lvb_size = kms;
- CDEBUG(D_INODE, "merged for ID "DOSTID" s="LPU64" m="LPU64" a="LPU64
- " c="LPU64" b="LPU64"\n", POSTID(&lsm->lsm_oi), lvb->lvb_size,
- lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks);
+ CDEBUG(D_INODE, "merged for ID "DOSTID" s=%llu m=%llu a=%llu c=%llu b=%llu\n",
+ POSTID(&lsm->lsm_oi), lvb->lvb_size, lvb->lvb_mtime,
+ lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks);
return rc;
}
@@ -153,7 +152,7 @@ int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm,
struct lov_oinfo *loi = lsm->lsm_oinfo[stripe];
kms = lov_size_to_stripe(lsm, size, stripe);
CDEBUG(D_INODE,
- "stripe %d KMS %sing "LPU64"->"LPU64"\n",
+ "stripe %d KMS %sing %llu->%llu\n",
stripe, kms > loi->loi_kms ? "increase":"shrink",
loi->loi_kms, kms);
loi_kms_set(loi, loi->loi_lvb.lvb_size = kms);
@@ -166,7 +165,7 @@ int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm,
kms = lov_size_to_stripe(lsm, size, stripe);
loi = lsm->lsm_oinfo[stripe];
- CDEBUG(D_INODE, "stripe %d KMS %sincreasing "LPU64"->"LPU64"\n",
+ CDEBUG(D_INODE, "stripe %d KMS %sincreasing %llu->%llu\n",
stripe, kms > loi->loi_kms ? "" : "not ", loi->loi_kms, kms);
if (kms > loi->loi_kms)
loi_kms_set(loi, kms);
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 2d843b1c1ded..e4f4fe3f71c7 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -42,22 +42,22 @@
*/
#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
-
-#include <obd_support.h>
-#include <lustre_lib.h>
-#include <lustre_net.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_dlm.h>
-#include <lustre_mds.h>
-#include <obd_class.h>
-#include <obd_ost.h>
-#include <lprocfs_status.h>
-#include <lustre_param.h>
-#include <cl_object.h>
-#include <lclient.h> /* for cl_client_lru */
-#include <lustre/ll_fiemap.h>
-#include <lustre_fid.h>
+#include "../../include/linux/libcfs/libcfs.h"
+
+#include "../include/obd_support.h"
+#include "../include/lustre_lib.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre/lustre_idl.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_mds.h"
+#include "../include/obd_class.h"
+#include "../include/obd_ost.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_param.h"
+#include "../include/cl_object.h"
+#include "../include/lclient.h" /* for cl_client_lru */
+#include "../include/lustre/ll_fiemap.h"
+#include "../include/lustre_fid.h"
#include "lov_internal.h"
@@ -382,7 +382,7 @@ static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid,
if (!tgt->ltd_exp)
continue;
- CDEBUG(D_INFO, "lov idx %d is %s conn "LPX64"\n",
+ CDEBUG(D_INFO, "lov idx %d is %s conn %#llx\n",
index, obd_uuid2str(&tgt->ltd_uuid),
tgt->ltd_exp->exp_handle.h_cookie);
if (obd_uuid_equals(uuid, &tgt->ltd_uuid))
@@ -727,8 +727,7 @@ void lov_fix_desc_stripe_size(__u64 *val)
*val = LOV_DESC_STRIPE_SIZE_DEFAULT;
} else if (*val & (LOV_MIN_STRIPE_SIZE - 1)) {
*val &= ~(LOV_MIN_STRIPE_SIZE - 1);
- LCONSOLE_WARN("Changing default stripe size to "LPU64" (a "
- "multiple of %u)\n",
+ LCONSOLE_WARN("Changing default stripe size to %llu (a multiple of %u)\n",
*val, LOV_MIN_STRIPE_SIZE);
}
}
@@ -821,7 +820,7 @@ int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
lprocfs_lov_init_vars(&lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
{
int rc1;
@@ -900,7 +899,7 @@ static int lov_cleanup(struct obd_device *obd)
" deathrow=%d, lovrc=%d\n",
i, lov->lov_death_row,
atomic_read(&lov->lov_refcount));
- lov_del_target(obd, i, 0, 0);
+ lov_del_target(obd, i, NULL, 0);
}
obd_putref(obd);
OBD_FREE(lov->lov_tgts, sizeof(*lov->lov_tgts) *
@@ -944,7 +943,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg,
GOTO(out, rc);
}
case LCFG_PARAM: {
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
struct lov_desc *desc = &(obd->u.lov.desc);
if (!desc)
@@ -1463,7 +1462,7 @@ static int lov_sync(const struct lu_env *env, struct obd_export *exp,
if (rc)
return rc;
- CDEBUG(D_INFO, "fsync objid "DOSTID" ["LPX64", "LPX64"]\n",
+ CDEBUG(D_INFO, "fsync objid "DOSTID" [%#llx, %#llx]\n",
POSTID(&set->set_oi->oi_oa->o_oi), start, end);
list_for_each(pos, &set->set_list) {
@@ -2636,9 +2635,8 @@ static int lov_extent_calc(struct obd_export *exp, struct lov_stripe_md *lsm,
lov_do_div64(start, ssize);
start = start * ssize;
- CDEBUG(D_DLMTRACE, "offset "LPU64", stripe %u, start "LPU64
- ", end "LPU64"\n", *offset, ssize, start,
- start + ssize - 1);
+ CDEBUG(D_DLMTRACE, "offset %llu, stripe %u, start %llu, end %llu\n",
+ *offset, ssize, start, start + ssize - 1);
if (cmd == OBD_CALC_STRIPE_END) {
*offset = start + ssize - 1;
} else if (cmd == OBD_CALC_STRIPE_START) {
@@ -2818,7 +2816,7 @@ struct kmem_cache *lov_oinfo_slab;
int __init lov_init(void)
{
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc;
/* print an address of _any_ initialized kernel symbol from this
diff --git a/drivers/staging/lustre/lustre/lov/lov_offset.c b/drivers/staging/lustre/lustre/lov/lov_offset.c
index 379568f8245c..8e1c3bacc0a0 100644
--- a/drivers/staging/lustre/lustre/lov/lov_offset.c
+++ b/drivers/staging/lustre/lustre/lov/lov_offset.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include "lov_internal.h"
@@ -223,7 +223,7 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno,
start_side = lov_stripe_offset(lsm, start, stripeno, obd_start);
end_side = lov_stripe_offset(lsm, end, stripeno, obd_end);
- CDEBUG(D_INODE, "["LPU64"->"LPU64"] -> [(%d) "LPU64"->"LPU64" (%d)]\n",
+ CDEBUG(D_INODE, "[%llu->%llu] -> [(%d) %llu->%llu (%d)]\n",
start, end, start_side, *obd_start, *obd_end, end_side);
/* this stripe doesn't intersect the file extent when neither
diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c
index 59ab7c30ffbf..a5b190f32c0f 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pack.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pack.c
@@ -42,11 +42,11 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include <lustre_net.h>
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_user.h>
+#include "../include/lustre_net.h"
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lustre/lustre_user.h"
#include "lov_internal.h"
@@ -555,7 +555,7 @@ int lov_setea(struct obd_export *exp, struct lov_stripe_md **lsmp,
return rc;
if (ostid_id(&lmm_objects[i].l_ost_oi) > last_id) {
CERROR("Setting EA for object > than last id on"
- " ost idx %d "DOSTID" > "LPD64" \n",
+ " ost idx %d "DOSTID" > %lld \n",
lmm_objects[i].l_ost_idx,
POSTID(&lmm_objects[i].l_ost_oi), last_id);
return -EINVAL;
diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c
index 3bda0c1f3c19..91b3509a8083 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pool.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pool.c
@@ -44,9 +44,9 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd.h>
+#include "../include/obd.h"
#include "lov_internal.h"
#define pool_tgt(_p, _i) \
@@ -152,7 +152,7 @@ cfs_hash_ops_t pool_hash_operations = {
};
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
/* ifdef needed for liblustre support */
/*
* pool /proc seq_file methods
@@ -294,7 +294,7 @@ static struct file_operations pool_proc_operations = {
.llseek = seq_lseek,
.release = seq_release,
};
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
void lov_dump_pool(int level, struct pool_desc *pool)
{
@@ -452,7 +452,7 @@ int lov_pool_new(struct obd_device *obd, char *poolname)
INIT_HLIST_NODE(&new_pool->pool_hash);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
/* we need this assert seq_file is not implemented for liblustre */
/* get ref for /proc file */
lov_pool_getref(new_pool);
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index bd6490d0129c..e4bb02a54b0d 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -36,11 +36,11 @@
#define DEBUG_SUBSYSTEM S_LOV
-#include <linux/libcfs/libcfs.h>
-
-#include <obd_class.h>
-#include <lustre/lustre_idl.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/obd_class.h"
+#include "../include/obd_ost.h"
+#include "../include/lustre/lustre_idl.h"
#include "lov_internal.h"
static void lov_init_set(struct lov_request_set *set)
@@ -140,16 +140,16 @@ void lov_set_add_req(struct lov_request *req, struct lov_request_set *set)
static int lov_check_set(struct lov_obd *lov, int idx)
{
- int rc = 0;
- mutex_lock(&lov->lov_lock);
-
- if (lov->lov_tgts[idx] == NULL ||
- lov->lov_tgts[idx]->ltd_active ||
- (lov->lov_tgts[idx]->ltd_exp != NULL &&
- class_exp2cliimp(lov->lov_tgts[idx]->ltd_exp)->imp_connect_tried))
- rc = 1;
+ int rc;
+ struct lov_tgt_desc *tgt;
+ mutex_lock(&lov->lov_lock);
+ tgt = lov->lov_tgts[idx];
+ rc = !tgt || tgt->ltd_active ||
+ (tgt->ltd_exp &&
+ class_exp2cliimp(tgt->ltd_exp)->imp_connect_tried);
mutex_unlock(&lov->lov_lock);
+
return rc;
}
@@ -194,13 +194,9 @@ out:
return rc;
}
-extern void osc_update_enqueue(struct lustre_handle *lov_lockhp,
- struct lov_oinfo *loi, int flags,
- struct ost_lvb *lvb, __u32 mode, int rc);
-
static int lov_update_enqueue_lov(struct obd_export *exp,
struct lustre_handle *lov_lockhp,
- struct lov_oinfo *loi, int flags, int idx,
+ struct lov_oinfo *loi, __u64 flags, int idx,
struct ost_id *oi, int rc)
{
struct lov_obd *lov = &exp->exp_obd->u.lov;
@@ -443,7 +439,7 @@ out_set:
return rc;
}
-int lov_fini_match_set(struct lov_request_set *set, __u32 mode, int flags)
+int lov_fini_match_set(struct lov_request_set *set, __u32 mode, __u64 flags)
{
int rc = 0;
@@ -482,7 +478,7 @@ int lov_prep_match_set(struct obd_export *exp, struct obd_info *oinfo,
GOTO(out_set, rc = -ENOMEM);
lockh->cookie = set->set_lockh->llh_handle.h_cookie;
- for (i = 0; i < lsm->lsm_stripe_count; i++){
+ for (i = 0; i < lsm->lsm_stripe_count; i++) {
struct lov_oinfo *loi;
struct lov_request *req;
obd_off start, end;
@@ -570,7 +566,7 @@ int lov_prep_cancel_set(struct obd_export *exp, struct obd_info *oinfo,
}
lockh->cookie = set->set_lockh->llh_handle.h_cookie;
- for (i = 0; i < lsm->lsm_stripe_count; i++){
+ for (i = 0; i < lsm->lsm_stripe_count; i++) {
struct lov_request *req;
struct lustre_handle *lov_lockhp;
struct lov_oinfo *loi = lsm->lsm_oinfo[i];
@@ -738,7 +734,7 @@ int lov_prep_brw_set(struct obd_export *exp, struct obd_info *oinfo,
/* alloc and initialize lov request */
shift = 0;
- for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++){
+ for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++) {
struct lov_oinfo *loi = NULL;
struct lov_request *req;
@@ -840,6 +836,7 @@ static int cb_getattr_update(void *cookie, int rc)
{
struct obd_info *oinfo = cookie;
struct lov_request *lovreq;
+
lovreq = container_of(oinfo, struct lov_request, rq_oi);
return lov_update_common_set(lovreq->rq_rqset, lovreq, rc);
}
@@ -1022,6 +1019,7 @@ static int cb_setattr_update(void *cookie, int rc)
{
struct obd_info *oinfo = cookie;
struct lov_request *lovreq;
+
lovreq = container_of(oinfo, struct lov_request, rq_oi);
return lov_update_setattr_set(lovreq->rq_rqset, lovreq, rc);
}
@@ -1080,7 +1078,7 @@ int lov_prep_setattr_set(struct obd_export *exp, struct obd_info *oinfo,
if (off < 0 && req->rq_oi.oi_oa->o_size)
req->rq_oi.oi_oa->o_size--;
- CDEBUG(D_INODE, "stripe %d has size "LPU64"/"LPU64"\n",
+ CDEBUG(D_INODE, "stripe %d has size %llu/%llu\n",
i, req->rq_oi.oi_oa->o_size,
oinfo->oi_oa->o_size);
}
@@ -1145,6 +1143,7 @@ static int cb_update_punch(void *cookie, int rc)
{
struct obd_info *oinfo = cookie;
struct lov_request *lovreq;
+
lovreq = container_of(oinfo, struct lov_request, rq_oi);
return lov_update_punch_set(lovreq->rq_rqset, lovreq, rc);
}
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index bd7da56b0713..c993f25fb303 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <asm/statfs.h>
-#include <lprocfs_status.h>
-#include <obd_class.h>
+#include "../include/lprocfs_status.h"
+#include "../include/obd_class.h"
#include <linux/seq_file.h>
#include "lov_internal.h"
@@ -48,7 +48,7 @@ static int lov_stripesize_seq_show(struct seq_file *m, void *v)
LASSERT(dev != NULL);
desc = &dev->u.lov.desc;
- return seq_printf(m, LPU64"\n", desc->ld_default_stripe_size);
+ return seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
}
static ssize_t lov_stripesize_seq_write(struct file *file, const char *buffer,
@@ -78,7 +78,7 @@ static int lov_stripeoffset_seq_show(struct seq_file *m, void *v)
LASSERT(dev != NULL);
desc = &dev->u.lov.desc;
- return seq_printf(m, LPU64"\n", desc->ld_default_stripe_offset);
+ return seq_printf(m, "%llu\n", desc->ld_default_stripe_offset);
}
static ssize_t lov_stripeoffset_seq_write(struct file *file, const char *buffer,
diff --git a/drivers/staging/lustre/lustre/lvfs/Makefile b/drivers/staging/lustre/lustre/lvfs/Makefile
index e0367c3fc416..387eee307e2d 100644
--- a/drivers/staging/lustre/lustre/lvfs/Makefile
+++ b/drivers/staging/lustre/lustre/lvfs/Makefile
@@ -2,6 +2,3 @@ obj-$(CONFIG_LUSTRE_FS) += lvfs.o
lvfs-y := lvfs_linux.o fsfilt.o
lvfs-$(CONFIG_PROC_FS) += lvfs_lib.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/lvfs/fsfilt.c b/drivers/staging/lustre/lustre/lvfs/fsfilt.c
index 0d6ed69ddb22..a4df056a2853 100644
--- a/drivers/staging/lustre/lustre/lvfs/fsfilt.c
+++ b/drivers/staging/lustre/lustre/lvfs/fsfilt.c
@@ -38,8 +38,8 @@
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/slab.h>
-#include <linux/libcfs/libcfs.h>
-#include <lustre_fsfilt.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/lustre_fsfilt.h"
LIST_HEAD(fsfilt_types);
diff --git a/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c b/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c
index 7e47fc4a7e4e..cfc4f896b127 100644
--- a/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c
+++ b/drivers/staging/lustre/lustre/lvfs/lvfs_lib.c
@@ -40,8 +40,8 @@
* Author: Andreas Dilger <adilger@clusterfs.com>
*/
#include <linux/module.h>
-#include <lustre_lib.h>
-#include <lprocfs_status.h>
+#include "../include/lustre_lib.h"
+#include "../include/lprocfs_status.h"
void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount)
{
diff --git a/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c b/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
index 374a9b78e1d2..eea0b2c94ba9 100644
--- a/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
+++ b/drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
@@ -45,13 +45,13 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
-#include <linux/libcfs/libcfs.h>
#include <linux/module.h>
-#include <linux/lustre_compat25.h>
-#include <lvfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/linux/lustre_compat25.h"
+#include "../include/lvfs.h"
-#include <obd.h>
-#include <lustre_lib.h>
+#include "../include/obd.h"
+#include "../include/lustre_lib.h"
struct lprocfs_stats *obd_memory = NULL;
EXPORT_SYMBOL(obd_memory);
@@ -233,8 +233,8 @@ put_old:
EXPORT_SYMBOL(lustre_rename);
/* Note: dput(dchild) will *not* be called if there is an error */
-struct l_file *l_dentry_open(struct lvfs_run_ctxt *ctxt, struct l_dentry *de,
- int flags)
+struct file *l_dentry_open(struct lvfs_run_ctxt *ctxt, struct dentry *de,
+ int flags)
{
struct path path = {
.dentry = de,
@@ -244,7 +244,7 @@ struct l_file *l_dentry_open(struct lvfs_run_ctxt *ctxt, struct l_dentry *de,
}
EXPORT_SYMBOL(l_dentry_open);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
__s64 lprocfs_read_helper(struct lprocfs_counter *lc,
struct lprocfs_counter_header *header,
enum lprocfs_stats_flags flags,
@@ -286,7 +286,7 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc,
return ret;
}
EXPORT_SYMBOL(lprocfs_read_helper);
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS*/
MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
MODULE_DESCRIPTION("Lustre VFS Filesystem Helper v0.1");
diff --git a/drivers/staging/lustre/lustre/mdc/Makefile b/drivers/staging/lustre/lustre/mdc/Makefile
index 4c0bed14de80..2516551a6dc3 100644
--- a/drivers/staging/lustre/lustre/mdc/Makefile
+++ b/drivers/staging/lustre/lustre/mdc/Makefile
@@ -1,6 +1,3 @@
obj-$(CONFIG_LUSTRE_FS) += mdc.o
mdc-y := mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o
mdc-$(CONFIG_PROC_FS) += lproc_mdc.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 2663480a68c5..d1d891b91663 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/vfs.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
{
@@ -172,39 +172,39 @@ LPROC_SEQ_FOPS_RW_TYPE(mdc, import);
LPROC_SEQ_FOPS_RW_TYPE(mdc, pinger_recov);
static struct lprocfs_vars lprocfs_mdc_obd_vars[] = {
- { "uuid", &mdc_uuid_fops, 0, 0 },
- { "ping", &mdc_ping_fops, 0, 0222 },
- { "connect_flags", &mdc_connect_flags_fops, 0, 0 },
- { "blocksize", &mdc_blksize_fops, 0, 0 },
- { "kbytestotal", &mdc_kbytestotal_fops, 0, 0 },
- { "kbytesfree", &mdc_kbytesfree_fops, 0, 0 },
- { "kbytesavail", &mdc_kbytesavail_fops, 0, 0 },
- { "filestotal", &mdc_filestotal_fops, 0, 0 },
- { "filesfree", &mdc_filesfree_fops, 0, 0 },
- /*{ "filegroups", lprocfs_rd_filegroups, 0, 0 },*/
- { "mds_server_uuid", &mdc_server_uuid_fops, 0, 0 },
- { "mds_conn_uuid", &mdc_conn_uuid_fops, 0, 0 },
+ { "uuid", &mdc_uuid_fops, NULL, 0 },
+ { "ping", &mdc_ping_fops, NULL, 0222 },
+ { "connect_flags", &mdc_connect_flags_fops, NULL, 0 },
+ { "blocksize", &mdc_blksize_fops, NULL, 0 },
+ { "kbytestotal", &mdc_kbytestotal_fops, NULL, 0 },
+ { "kbytesfree", &mdc_kbytesfree_fops, NULL, 0 },
+ { "kbytesavail", &mdc_kbytesavail_fops, NULL, 0 },
+ { "filestotal", &mdc_filestotal_fops, NULL, 0 },
+ { "filesfree", &mdc_filesfree_fops, NULL, 0 },
+ /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/
+ { "mds_server_uuid", &mdc_server_uuid_fops, NULL, 0 },
+ { "mds_conn_uuid", &mdc_conn_uuid_fops, NULL, 0 },
/*
* FIXME: below proc entry is provided, but not in used, instead
* sbi->sb_md_brw_size is used, the per obd variable should be used
* when CMD is enabled, and dir pages are managed in MDC layer.
* Remember to enable proc write function.
*/
- { "max_pages_per_rpc", &mdc_obd_max_pages_per_rpc_fops, 0, 0 },
- { "max_rpcs_in_flight", &mdc_max_rpcs_in_flight_fops, 0, 0 },
- { "timeouts", &mdc_timeouts_fops, 0, 0 },
- { "import", &mdc_import_fops, 0 },
- { "state", &mdc_state_fops, 0, 0 },
- { "hsm_nl", &mdc_kuc_fops, 0, 0200 },
- { "pinger_recov", &mdc_pinger_recov_fops, 0, 0 },
- { 0 }
+ { "max_pages_per_rpc", &mdc_obd_max_pages_per_rpc_fops, NULL, 0 },
+ { "max_rpcs_in_flight", &mdc_max_rpcs_in_flight_fops, NULL, 0 },
+ { "timeouts", &mdc_timeouts_fops, NULL, 0 },
+ { "import", &mdc_import_fops, NULL, 0 },
+ { "state", &mdc_state_fops, NULL, 0 },
+ { "hsm_nl", &mdc_kuc_fops, NULL, 0200 },
+ { "pinger_recov", &mdc_pinger_recov_fops, NULL, 0 },
+ { NULL }
};
LPROC_SEQ_FOPS_RO_TYPE(mdc, numrefs);
static struct lprocfs_vars lprocfs_mdc_module_vars[] = {
- { "num_refs", &mdc_numrefs_fops, 0, 0 },
- { 0 }
+ { "num_refs", &mdc_numrefs_fops, NULL, 0 },
+ { NULL }
};
void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars)
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
index c78bf003c2c5..e8235559e27f 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h
+++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h
@@ -37,10 +37,10 @@
#ifndef _MDC_INTERNAL_H
#define _MDC_INTERNAL_H
-#include <lustre_mdc.h>
-#include <lustre_mds.h>
+#include "../include/lustre_mdc.h"
+#include "../include/lustre_mds.h"
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars);
#else
static inline 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 5b9f37141512..f54dd90c7e50 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
@@ -35,8 +35,8 @@
*/
#define DEBUG_SUBSYSTEM S_MDC
-#include <lustre_net.h>
-#include <lustre/lustre_idl.h>
+#include "../include/lustre_net.h"
+#include "../include/lustre/lustre_idl.h"
#include "mdc_internal.h"
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index 1a8cd98ad6d7..71219b90e22b 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -38,14 +38,14 @@
# include <linux/module.h>
-#include <linux/lustre_intent.h>
-#include <obd.h>
-#include <obd_class.h>
-#include <lustre_dlm.h>
-#include <lustre_fid.h> /* fid_res_name_eq() */
-#include <lustre_mdc.h>
-#include <lustre_net.h>
-#include <lustre_req_layout.h>
+#include "../include/linux/lustre_intent.h"
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_fid.h" /* fid_res_name_eq() */
+#include "../include/lustre_mdc.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre_req_layout.h"
#include "mdc_internal.h"
struct mdc_getattr_args {
@@ -860,7 +860,7 @@ resend:
if (resends) {
req->rq_generation_set = 1;
req->rq_import_generation = generation;
- req->rq_sent = cfs_time_current_sec() + resends;
+ req->rq_sent = get_seconds() + resends;
}
/* It is important to obtain rpc_lock first (if applicable), so that
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
index 08e80940ee4d..c5420a42bc33 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c
@@ -39,9 +39,9 @@
# include <linux/module.h>
# include <linux/kernel.h>
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include "mdc_internal.h"
-#include <lustre_fid.h>
+#include "../include/lustre_fid.h"
/* mdc_setattr does its own semaphore handling */
static int mdc_reint(struct ptlrpc_request *request,
@@ -273,7 +273,7 @@ rebuild:
if (resends) {
req->rq_generation_set = 1;
req->rq_import_generation = generation;
- req->rq_sent = cfs_time_current_sec() + resends;
+ req->rq_sent = get_seconds() + resends;
}
level = LUSTRE_IMP_FULL;
resend:
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index fca43cf1d671..4a1cc4eb73d5 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -42,12 +42,12 @@
# include <linux/init.h>
# include <linux/utsname.h>
-#include <lustre_acl.h>
-#include <obd_class.h>
-#include <lustre_fid.h>
-#include <lprocfs_status.h>
-#include <lustre_param.h>
-#include <lustre_log.h>
+#include "../include/lustre_acl.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_fid.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_param.h"
+#include "../include/lustre_log.h"
#include "mdc_internal.h"
@@ -136,7 +136,7 @@ static int send_getstatus(struct obd_import *imp, struct lu_fid *rootfid,
*rootfid = body->fid1;
CDEBUG(D_NET,
- "root fid="DFID", last_committed="LPU64"\n",
+ "root fid="DFID", last_committed=%llu\n",
PFID(rootfid),
lustre_msg_get_last_committed(req->rq_repmsg));
out:
@@ -397,7 +397,7 @@ static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt,
rec->sx_suppgid2 = -1;
rec->sx_fid = *fid;
rec->sx_valid = valid | OBD_MD_FLCTIME;
- rec->sx_time = cfs_time_current_sec();
+ rec->sx_time = get_seconds();
rec->sx_size = output_size;
rec->sx_flags = flags;
@@ -670,7 +670,7 @@ void mdc_replay_open(struct ptlrpc_request *req)
LASSERT(och->och_magic == OBD_CLIENT_HANDLE_MAGIC);
file_fh = &och->och_fh;
- CDEBUG(D_HA, "updating handle from "LPX64" to "LPX64"\n",
+ CDEBUG(D_HA, "updating handle from %#llx to %#llx\n",
file_fh->cookie, body->handle.cookie);
old = *file_fh;
*file_fh = body->handle;
@@ -1182,7 +1182,7 @@ static int mdc_ioc_fid2path(struct obd_export *exp, struct getinfo_fid2path *gf)
memcpy(key, KEY_FID2PATH, sizeof(KEY_FID2PATH));
memcpy(key + cfs_size_round(sizeof(KEY_FID2PATH)), gf, sizeof(*gf));
- CDEBUG(D_IOCTL, "path get "DFID" from "LPU64" #%d\n",
+ CDEBUG(D_IOCTL, "path get "DFID" from %llu #%d\n",
PFID(&gf->gf_fid), gf->gf_recno, gf->gf_linkno);
if (!fid_is_sane(&gf->gf_fid))
@@ -1200,7 +1200,7 @@ static int mdc_ioc_fid2path(struct obd_export *exp, struct getinfo_fid2path *gf)
else if (vallen > sizeof(*gf) + gf->gf_pathlen)
GOTO(out, rc = -EOVERFLOW);
- CDEBUG(D_IOCTL, "path get "DFID" from "LPU64" #%d\n%s\n",
+ CDEBUG(D_IOCTL, "path get "DFID" from %llu #%d\n%s\n",
PFID(&gf->gf_fid), gf->gf_recno, gf->gf_linkno, gf->gf_path);
out:
@@ -1515,12 +1515,12 @@ static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh,
if (rec->cr.cr_index < cs->cs_startrec) {
/* Skip entries earlier than what we are interested in */
- CDEBUG(D_CHANGELOG, "rec="LPU64" start="LPU64"\n",
+ CDEBUG(D_CHANGELOG, "rec=%llu start=%llu\n",
rec->cr.cr_index, cs->cs_startrec);
return 0;
}
- CDEBUG(D_CHANGELOG, LPU64" %02d%-5s "LPU64" 0x%x t="DFID" p="DFID
+ CDEBUG(D_CHANGELOG, "%llu %02d%-5s %llu 0x%x t="DFID" p="DFID
" %.*s\n", rec->cr.cr_index, rec->cr.cr_type,
changelog_type2str(rec->cr.cr_type), rec->cr.cr_time,
rec->cr.cr_flags & CLF_FLAGMASK,
@@ -1547,7 +1547,7 @@ static int mdc_changelog_send_thread(void *csdata)
struct kuc_hdr *kuch;
int rc;
- CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n",
+ CDEBUG(D_CHANGELOG, "changelog to fp=%p start %llu\n",
cs->cs_fp, cs->cs_startrec);
OBD_ALLOC(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE);
@@ -2423,7 +2423,7 @@ struct ldlm_valblock_ops inode_lvbo = {
static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg)
{
struct client_obd *cli = &obd->u.cli;
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc;
OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
@@ -2566,7 +2566,7 @@ static int mdc_llog_finish(struct obd_device *obd, int count)
static int mdc_process_config(struct obd_device *obd, obd_count len, void *buf)
{
struct lustre_cfg *lcfg = buf;
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc = 0;
lprocfs_mdc_init_vars(&lvars);
@@ -2737,7 +2737,7 @@ struct md_ops mdc_md_ops = {
int __init mdc_init(void)
{
int rc;
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
lprocfs_mdc_init_vars(&lvars);
rc = class_register_type(&mdc_obd_ops, &mdc_md_ops, lvars.module_vars,
diff --git a/drivers/staging/lustre/lustre/mgc/Makefile b/drivers/staging/lustre/lustre/mgc/Makefile
index 2f5ee649456d..cc6e9f51a8e8 100644
--- a/drivers/staging/lustre/lustre/mgc/Makefile
+++ b/drivers/staging/lustre/lustre/mgc/Makefile
@@ -1,6 +1,3 @@
obj-$(CONFIG_LUSTRE_FS) += mgc.o
mgc-y := mgc_request.o
mgc-$(CONFIG_PROC_FS) += lproc_mgc.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/mgc/libmgc.c b/drivers/staging/lustre/lustre/mgc/libmgc.c
index 9b40c57d3cd4..8012f0f1bfcd 100644
--- a/drivers/staging/lustre/lustre/mgc/libmgc.c
+++ b/drivers/staging/lustre/lustre/mgc/libmgc.c
@@ -44,13 +44,13 @@
#define DEBUG_SUBSYSTEM S_MGC
-#include <liblustre.h>
+#include "../include/liblustre.h"
-#include <obd_class.h>
-#include <lustre_dlm.h>
-#include <lustre_log.h>
-#include <lustre_fsfilt.h>
-#include <lustre_disk.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_log.h"
+#include "../include/lustre_fsfilt.h"
+#include "../include/lustre_disk.h"
static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
diff --git a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
index 6c877c5a6a71..c4ea38e5f077 100644
--- a/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
+++ b/drivers/staging/lustre/lustre/mgc/lproc_mgc.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/vfs.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
#include "mgc_internal.h"
LPROC_SEQ_FOPS_RO_TYPE(mgc, uuid);
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_internal.h b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
index 73b454898844..a6f8b3ced2e7 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_internal.h
+++ b/drivers/staging/lustre/lustre/mgc/mgc_internal.h
@@ -37,14 +37,14 @@
#ifndef _MGC_INTERNAL_H
#define _MGC_INTERNAL_H
-#include <linux/libcfs/libcfs.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_lib.h>
-#include <lustre_dlm.h>
-#include <lustre_log.h>
-#include <lustre_export.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"
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void lprocfs_mgc_init_vars(struct lprocfs_static_vars *lvars);
int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data);
#else
@@ -56,7 +56,7 @@ static inline int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
{
return 0;
}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld);
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index a806aeffe026..f520591d5784 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -42,12 +42,12 @@
#define D_MGC D_CONFIG /*|D_WARNING*/
#include <linux/module.h>
-#include <obd_class.h>
-#include <lustre_dlm.h>
-#include <lprocfs_status.h>
-#include <lustre_log.h>
-#include <lustre_disk.h>
-#include <dt_object.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_log.h"
+#include "../include/lustre_disk.h"
+#include "../include/dt_object.h"
#include "mgc_internal.h"
@@ -83,7 +83,7 @@ static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
LBUG();
}
res_id->name[1] = cpu_to_le64(resname);
- CDEBUG(D_MGC, "log %s to resid "LPX64"/"LPX64" (%.8s)\n", name,
+ CDEBUG(D_MGC, "log %s to resid %#llx/%#llx (%.8s)\n", name,
res_id->name[0], res_id->name[1], (char *)&res_id->name[0]);
return 0;
}
@@ -197,7 +197,7 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd,
int rc;
CDEBUG(D_MGC, "do adding config log %s:%p\n", logname,
- cfg ? cfg->cfg_instance : 0);
+ cfg ? cfg->cfg_instance : NULL);
OBD_ALLOC(cld, sizeof(*cld) + strlen(logname) + 1);
if (!cld)
@@ -445,7 +445,7 @@ static int config_log_end(char *logname, struct config_llog_instance *cfg)
return rc;
}
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
{
struct obd_device *obd = data;
@@ -950,7 +950,10 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
}
/* Not sure where this should go... */
-#define MGC_ENQUEUE_LIMIT 50
+/* This is the timeout value for MGS_CONNECT request plus a ping interval, such
+ * that we can have a chance to try the secondary MGS if any. */
+#define MGC_ENQUEUE_LIMIT (INITIAL_CONNECT_TIMEOUT + (AT_OFF ? 0 : at_min) \
+ + PING_INTERVAL)
#define MGC_TARGET_REG_LIMIT 10
#define MGC_SEND_PARAM_LIMIT 10
@@ -1008,7 +1011,7 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
int short_limit = cld_is_sptlrpc(cld);
int rc;
- CDEBUG(D_MGC, "Enqueue for %s (res "LPX64")\n", cld->cld_logname,
+ CDEBUG(D_MGC, "Enqueue for %s (res %#llx)\n", cld->cld_logname,
cld->cld_resid.name[0]);
/* We need a callback for every lockholder, so don't try to
@@ -1454,7 +1457,7 @@ static int mgc_apply_recover_logs(struct obd_device *mgc,
break;
}
- CDEBUG(D_INFO, "ir apply logs "LPD64"/"LPD64" for %s -> %s\n",
+ CDEBUG(D_INFO, "ir apply logs %lld/%lld for %s -> %s\n",
prev_version, max_version, obdname, params);
rc = class_process_config(lcfg);
@@ -1557,7 +1560,7 @@ again:
cfg->cfg_last_idx = res->mcr_offset;
eof = res->mcr_offset == res->mcr_size;
- CDEBUG(D_INFO, "Latest version "LPD64", more %d.\n",
+ CDEBUG(D_INFO, "Latest version %lld, more %d.\n",
res->mcr_offset, eof == false);
ealen = sptlrpc_cli_unwrap_bulk_read(req, req->rq_bulk, 0);
diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile
index 8a0e08ced454..ba10043fdd50 100644
--- a/drivers/staging/lustre/lustre/obdclass/Makefile
+++ b/drivers/staging/lustre/lustre/obdclass/Makefile
@@ -8,6 +8,3 @@ obdclass-y := linux/linux-module.o linux/linux-obdo.o linux/linux-sysctl.o \
mea.o lu_object.o dt_object.o capa.o cl_object.o \
cl_page.o cl_lock.o cl_io.o lu_ref.o acl.o idmap.o \
lu_ucred.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/obdclass/acl.c b/drivers/staging/lustre/lustre/obdclass/acl.c
index f0bb632a70aa..3b394a0bff9d 100644
--- a/drivers/staging/lustre/lustre/obdclass/acl.c
+++ b/drivers/staging/lustre/lustre/obdclass/acl.c
@@ -41,10 +41,10 @@
*/
#define DEBUG_SUBSYSTEM S_SEC
-#include <lu_object.h>
-#include <lustre_acl.h>
-#include <lustre_eacl.h>
-#include <obd_support.h>
+#include "../include/lu_object.h"
+#include "../include/lustre_acl.h"
+#include "../include/lustre_eacl.h"
+#include "../include/obd_support.h"
#ifdef CONFIG_FS_POSIX_ACL
diff --git a/drivers/staging/lustre/lustre/obdclass/capa.c b/drivers/staging/lustre/lustre/obdclass/capa.c
index be1c613383a6..5af61a8c0b85 100644
--- a/drivers/staging/lustre/lustre/obdclass/capa.c
+++ b/drivers/staging/lustre/lustre/obdclass/capa.c
@@ -48,12 +48,12 @@
#include <linux/module.h>
#include <linux/crypto.h>
-#include <obd_class.h>
-#include <lustre_debug.h>
-#include <lustre/lustre_idl.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_debug.h"
+#include "../include/lustre/lustre_idl.h"
#include <linux/list.h>
-#include <lustre_capa.h>
+#include "../include/lustre_capa.h"
#define NR_CAPAHASH 32
#define CAPA_HASH_SIZE 3000 /* for MDS & OSS */
@@ -143,9 +143,9 @@ static inline int capa_hashfn(struct lu_fid *fid)
* client renew right after obtaining it. */
static inline int capa_is_to_expire(struct obd_capa *oc)
{
- return cfs_time_before(cfs_time_sub(oc->c_expiry,
- cfs_time_seconds(oc->c_capa.lc_timeout)*2/3),
- cfs_time_current());
+ return time_before(cfs_time_sub(oc->c_expiry,
+ cfs_time_seconds(oc->c_capa.lc_timeout)*2/3),
+ cfs_time_current());
}
static struct obd_capa *find_capa(struct lustre_capa *capa,
@@ -279,6 +279,7 @@ int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key)
}
keylen = alg->ha_keylen;
+ sg_init_table(&sl, 1);
sg_set_page(&sl, virt_to_page(capa),
offsetof(struct lustre_capa, lc_hmac),
(unsigned long)(capa) % PAGE_CACHE_SIZE);
@@ -320,9 +321,11 @@ int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
GOTO(out, rc);
}
+ sg_init_table(&sd, 1);
sg_set_page(&sd, virt_to_page(d), 16,
(unsigned long)(d) % PAGE_CACHE_SIZE);
+ sg_init_table(&ss, 1);
sg_set_page(&ss, virt_to_page(s), 16,
(unsigned long)(s) % PAGE_CACHE_SIZE);
desc.tfm = tfm;
@@ -370,9 +373,11 @@ int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen)
GOTO(out, rc);
}
+ sg_init_table(&sd, 1);
sg_set_page(&sd, virt_to_page(d), 16,
(unsigned long)(d) % PAGE_CACHE_SIZE);
+ sg_init_table(&ss, 1);
sg_set_page(&ss, virt_to_page(s), 16,
(unsigned long)(s) % PAGE_CACHE_SIZE);
@@ -406,8 +411,8 @@ void _debug_capa(struct lustre_capa *c,
va_list args;
va_start(args, fmt);
libcfs_debug_vmsg2(msgdata, fmt, args,
- " capability@%p fid "DFID" opc "LPX64" uid "LPU64
- " gid "LPU64" flags %u alg %d keyid %u timeout %u "
+ " capability@%p fid "DFID" opc %#llx uid %llu"
+ " gid %llu flags %u alg %d keyid %u timeout %u "
"expiry %u\n", c, PFID(capa_fid(c)), capa_opc(c),
capa_uid(c), capa_gid(c), capa_flags(c),
capa_alg(c), capa_keyid(c), capa_timeout(c),
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 3bebc78e7673..6870ee823736 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -40,11 +40,11 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_fid.h>
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
#include <linux/list.h>
-#include <cl_object.h>
+#include "../include/cl_object.h"
#include "cl_internal.h"
/*****************************************************************************
@@ -227,7 +227,7 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
LINVRNT(io->ci_obj != NULL);
LU_OBJECT_HEADER(D_VFSTRACE, env, &io->ci_obj->co_lu,
- "io range: %u ["LPU64", "LPU64") %u %u\n",
+ "io range: %u [%llu, %llu) %u %u\n",
iot, (__u64)pos, (__u64)pos + count,
io->u.ci_rw.crw_nonblock, io->u.ci_wr.wr_append);
io->u.ci_rw.crw_pos = pos;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index df77c4fc0eac..7d99319b714e 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -40,11 +40,11 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_fid.h>
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
#include <linux/list.h>
-#include <cl_object.h>
+#include "../include/cl_object.h"
#include "cl_internal.h"
/** Lock class of cl_lock::cll_guard */
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 41cbc95b916e..ce96bd279111 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -51,14 +51,14 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/* class_put_type() */
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_fid.h>
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_fid.h"
#include <linux/list.h>
-#include <linux/libcfs/libcfs_hash.h> /* for cfs_hash stuff */
-#include <cl_object.h>
+#include "../../include/linux/libcfs/libcfs_hash.h" /* for cfs_hash stuff */
+#include "../include/cl_object.h"
#include "cl_internal.h"
static struct kmem_cache *cl_env_kmem;
@@ -295,8 +295,7 @@ int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
}
}
LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
- "size: "LPU64" mtime: "LPU64" atime: "LPU64" "
- "ctime: "LPU64" blocks: "LPU64"\n",
+ "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
lvb->lvb_ctime, lvb->lvb_blocks);
return result;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 1b616e4fe140..b7dd04808060 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -40,12 +40,12 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <linux/libcfs/libcfs.h>
-#include <obd_class.h>
-#include <obd_support.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
#include <linux/list.h>
-#include <cl_object.h>
+#include "../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 dde04b767a6d..8b19f3caa68f 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -37,14 +37,14 @@
#define DEBUG_SUBSYSTEM S_CLASS
# include <asm/atomic.h>
-#include <obd_support.h>
-#include <obd_class.h>
-#include <linux/lnet/lnetctl.h>
-#include <lustre_debug.h>
-#include <lprocfs_status.h>
-#include <lustre/lustre_build_version.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 "../include/lustre/lustre_build_version.h"
#include <linux/list.h>
-#include <cl_object.h>
+#include "../include/cl_object.h"
#include "llog_internal.h"
@@ -141,11 +141,11 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type,
{
if (ptr == NULL ||
(cfs_rand() & OBD_ALLOC_FAIL_MASK) < obd_alloc_fail_rate) {
- CERROR("%s%salloc of %s ("LPU64" bytes) failed at %s:%d\n",
+ CERROR("%s%salloc of %s (%llu bytes) failed at %s:%d\n",
ptr ? "force " :"", type, name, (__u64)size, file,
line);
- CERROR(LPU64" total bytes and "LPU64" total pages "
- "("LPU64" bytes) allocated by Lustre, "
+ CERROR("%llu total bytes and %llu total pages "
+ "(%llu bytes) allocated by Lustre, "
"%d total bytes by LNET\n",
obd_memory_sum(),
obd_pages_sum() << PAGE_CACHE_SHIFT,
@@ -420,61 +420,61 @@ int obd_init_checks(void)
char buf[64];
int len, ret = 0;
- CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", LPU64, LPD64, LPX64);
+ CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", "%llu", "%lld", "%#llx");
- CDEBUG(D_INFO, "OBD_OBJECT_EOF = "LPX64"\n", (__u64)OBD_OBJECT_EOF);
+ CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
u64val = OBD_OBJECT_EOF;
- CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = "LPX64"\n", u64val);
+ CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
if (u64val != OBD_OBJECT_EOF) {
- CERROR("__u64 "LPX64"(%d) != 0xffffffffffffffff\n",
+ CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
u64val, (int)sizeof(u64val));
ret = -EINVAL;
}
- len = snprintf(buf, sizeof(buf), LPX64, u64val);
+ len = snprintf(buf, sizeof(buf), "%#llx", u64val);
if (len != 18) {
CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
ret = -EINVAL;
}
div64val = OBD_OBJECT_EOF;
- CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = "LPX64"\n", u64val);
+ CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
if (u64val != OBD_OBJECT_EOF) {
- CERROR("__u64 "LPX64"(%d) != 0xffffffffffffffff\n",
+ CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
u64val, (int)sizeof(u64val));
ret = -EOVERFLOW;
}
if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
- CERROR("__u64 "LPX64"(%d) != 0xffffffffffffffff\n",
+ CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
u64val, (int)sizeof(u64val));
return -EOVERFLOW;
}
if (do_div(div64val, 256) != (u64val & 255)) {
- CERROR("do_div("LPX64",256) != "LPU64"\n", u64val, u64val &255);
+ CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val &255);
return -EOVERFLOW;
}
if (u64val >> 8 != div64val) {
- CERROR("do_div("LPX64",256) "LPU64" != "LPU64"\n",
+ CERROR("do_div(%#llx,256) %llu != %llu\n",
u64val, div64val, u64val >> 8);
return -EOVERFLOW;
}
- len = snprintf(buf, sizeof(buf), LPX64, u64val);
+ len = snprintf(buf, sizeof(buf), "%#llx", u64val);
if (len != 18) {
CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
ret = -EINVAL;
}
- len = snprintf(buf, sizeof(buf), LPU64, u64val);
+ len = snprintf(buf, sizeof(buf), "%llu", u64val);
if (len != 20) {
CWARN("LPU64 wrong length! strlen(%s)=%d != 20\n", buf, len);
ret = -EINVAL;
}
- len = snprintf(buf, sizeof(buf), LPD64, u64val);
+ len = snprintf(buf, sizeof(buf), "%lld", u64val);
if (len != 2) {
CWARN("LPD64 wrong length! strlen(%s)=%d != 2\n", buf, len);
ret = -EINVAL;
}
if ((u64val & ~CFS_PAGE_MASK) >= PAGE_CACHE_SIZE) {
- CWARN("mask failed: u64val "LPU64" >= "LPU64"\n", u64val,
+ CWARN("mask failed: u64val %llu >= %llu\n", u64val,
(__u64)PAGE_CACHE_SIZE);
ret = -EINVAL;
}
@@ -483,7 +483,7 @@ int obd_init_checks(void)
}
extern spinlock_t obd_types_lock;
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
extern int class_procfs_init(void);
extern int class_procfs_clean(void);
#else
@@ -594,7 +594,7 @@ void obd_update_maxusage(void)
}
EXPORT_SYMBOL(obd_update_maxusage);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
__u64 obd_memory_max(void)
{
__u64 ret;
@@ -662,10 +662,10 @@ static void cleanup_obdclass(void)
lprocfs_free_stats(&obd_memory);
CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
- "obd_memory max: "LPU64", leaked: "LPU64"\n",
+ "obd_memory max: %llu, leaked: %llu\n",
memory_max, memory_leaked);
CDEBUG((pages_leaked) ? D_ERROR : D_INFO,
- "obd_memory_pages max: "LPU64", leaked: "LPU64"\n",
+ "obd_memory_pages max: %llu, leaked: %llu\n",
pages_max, pages_leaked);
}
diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c
index a4e7e754177f..e8aa42beb3c7 100644
--- a/drivers/staging/lustre/lustre/obdclass/debug.c
+++ b/drivers/staging/lustre/lustre/obdclass/debug.c
@@ -41,15 +41,15 @@
#define DEBUG_SUBSYSTEM D_OTHER
-#include <obd_ost.h>
-#include <obd_support.h>
-#include <lustre_debug.h>
-#include <lustre_net.h>
+#include "../include/obd_ost.h"
+#include "../include/obd_support.h"
+#include "../include/lustre_debug.h"
+#include "../include/lustre_net.h"
void dump_lniobuf(struct niobuf_local *nb)
{
CDEBUG(D_RPCTRACE,
- "niobuf_local: file_offset="LPD64", len=%d, page=%p, rc=%d\n",
+ "niobuf_local: file_offset=%lld, len=%d, page=%p, rc=%d\n",
nb->lnb_file_offset, nb->len, nb->page, nb->rc);
CDEBUG(D_RPCTRACE, "nb->page: index = %ld\n",
nb->page ? page_index(nb->page) : -1);
@@ -84,25 +84,25 @@ int block_debug_check(char *who, void *addr, int end, __u64 off, __u64 id)
ne_off = le64_to_cpu (off);
id = le64_to_cpu (id);
if (memcmp(addr, (char *)&ne_off, LPDS)) {
- CDEBUG(D_ERROR, "%s: id "LPX64" offset "LPU64" off: "LPX64" != "
- LPX64"\n", who, id, off, *(__u64 *)addr, ne_off);
+ CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n",
+ who, id, off, *(__u64 *)addr, ne_off);
err = -EINVAL;
}
if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
- CDEBUG(D_ERROR, "%s: id "LPX64" offset "LPU64" id: "LPX64" != "LPX64"\n",
+ CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n",
who, id, off, *(__u64 *)(addr + LPDS), id);
err = -EINVAL;
}
addr += end - LPDS - LPDS;
if (memcmp(addr, (char *)&ne_off, LPDS)) {
- CDEBUG(D_ERROR, "%s: id "LPX64" offset "LPU64" end off: "LPX64" != "
- LPX64"\n", who, id, off, *(__u64 *)addr, ne_off);
+ CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n",
+ who, id, off, *(__u64 *)addr, ne_off);
err = -EINVAL;
}
if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
- CDEBUG(D_ERROR, "%s: id "LPX64" offset "LPU64" end id: "LPX64" != "
- LPX64"\n", who, id, off, *(__u64 *)(addr + LPDS), id);
+ CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n",
+ who, id, off, *(__u64 *)(addr + LPDS), id);
err = -EINVAL;
}
diff --git a/drivers/staging/lustre/lustre/obdclass/dt_object.c b/drivers/staging/lustre/lustre/obdclass/dt_object.c
index 1b164c7027b1..130b8dd0b418 100644
--- a/drivers/staging/lustre/lustre/obdclass/dt_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/dt_object.c
@@ -43,13 +43,13 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd.h>
-#include <dt_object.h>
+#include "../include/obd.h"
+#include "../include/dt_object.h"
#include <linux/list.h>
/* fid_be_to_cpu() */
-#include <lustre_fid.h>
+#include "../include/lustre_fid.h"
-#include <lustre_quota.h>
+#include "../include/lustre_quota.h"
/* context key constructor/destructor: dt_global_key_init, dt_global_key_fini */
LU_KEY_INIT(dt_global, struct dt_thread_info);
@@ -929,7 +929,7 @@ out:
}
EXPORT_SYMBOL(dt_index_read);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
int count, int *eof, void *data)
@@ -963,7 +963,7 @@ int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
result <<= 1;
*eof = 1;
- rc = snprintf(page, count, LPU64"\n", result);
+ rc = snprintf(page, count, "%llu\n", result);
}
return rc;
@@ -985,7 +985,7 @@ int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
result <<= 1;
*eof = 1;
- rc = snprintf(page, count, LPU64"\n", result);
+ rc = snprintf(page, count, "%llu\n", result);
}
return rc;
@@ -1007,7 +1007,7 @@ int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
result <<= 1;
*eof = 1;
- rc = snprintf(page, count, LPU64"\n", result);
+ rc = snprintf(page, count, "%llu\n", result);
}
return rc;
@@ -1023,7 +1023,7 @@ int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
int rc = dt_statfs(NULL, dt, &osfs);
if (rc == 0) {
*eof = 1;
- rc = snprintf(page, count, LPU64"\n", osfs.os_files);
+ rc = snprintf(page, count, "%llu\n", osfs.os_files);
}
return rc;
@@ -1039,11 +1039,11 @@ int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
int rc = dt_statfs(NULL, dt, &osfs);
if (rc == 0) {
*eof = 1;
- rc = snprintf(page, count, LPU64"\n", osfs.os_ffree);
+ rc = snprintf(page, count, "%llu\n", osfs.os_ffree);
}
return rc;
}
EXPORT_SYMBOL(lprocfs_dt_rd_filesfree);
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 3210ad8184b9..504c59aabaef 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -40,9 +40,9 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_ost.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include "../include/obd_ost.h"
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
extern struct list_head obd_types;
spinlock_t obd_types_lock;
@@ -699,7 +699,7 @@ struct obd_export *class_conn2export(struct lustre_handle *conn)
return NULL;
}
- CDEBUG(D_INFO, "looking for export cookie "LPX64"\n", conn->cookie);
+ CDEBUG(D_INFO, "looking for export cookie %#llx\n", conn->cookie);
export = class_handle2object(conn->cookie);
return export;
}
@@ -842,7 +842,7 @@ struct obd_export *class_new_export(struct obd_device *obd,
INIT_LIST_HEAD(&export->exp_handle.h_link);
INIT_LIST_HEAD(&export->exp_hp_rpcs);
class_handle_hash(&export->exp_handle, &export_handle_ops);
- export->exp_last_request_time = cfs_time_current_sec();
+ export->exp_last_request_time = get_seconds();
spin_lock_init(&export->exp_lock);
spin_lock_init(&export->exp_rpc_lock);
INIT_HLIST_NODE(&export->exp_uuid_hash);
@@ -1113,7 +1113,7 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd,
conn->cookie = export->exp_handle.h_cookie;
class_export_put(export);
- CDEBUG(D_IOCTL, "connect: client %s, cookie "LPX64"\n",
+ CDEBUG(D_IOCTL, "connect: client %s, cookie %#llx\n",
cluuid->uuid, conn->cookie);
return 0;
}
@@ -1190,7 +1190,7 @@ int class_disconnect(struct obd_export *export)
GOTO(no_disconn, already_disconnected);
}
- CDEBUG(D_IOCTL, "disconnect: cookie "LPX64"\n",
+ CDEBUG(D_IOCTL, "disconnect: cookie %#llx\n",
export->exp_handle.h_cookie);
if (!hlist_unhashed(&export->exp_nid_hash))
@@ -1493,7 +1493,7 @@ static void print_export_data(struct obd_export *exp, const char *status,
}
spin_unlock(&exp->exp_lock);
- CDEBUG(D_HA, "%s: %s %p %s %s %d (%d %d %d) %d %d %d %d: %p %s "LPU64"\n",
+ CDEBUG(D_HA, "%s: %s %p %s %s %d (%d %d %d) %d %d %d %d: %p %s %llu\n",
exp->exp_obd->obd_name, status, exp, exp->exp_client_uuid.uuid,
obd_export_nid2str(exp), atomic_read(&exp->exp_refcount),
atomic_read(&exp->exp_rpc_count),
diff --git a/drivers/staging/lustre/lustre/obdclass/idmap.c b/drivers/staging/lustre/lustre/obdclass/idmap.c
index ec2590f5cfe9..1190885c06b6 100644
--- a/drivers/staging/lustre/lustre/obdclass/idmap.c
+++ b/drivers/staging/lustre/lustre/obdclass/idmap.c
@@ -42,9 +42,9 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <lustre_idmap.h>
-#include <md_object.h>
-#include <obd_support.h>
+#include "../include/lustre_idmap.h"
+#include "../include/md_object.h"
+#include "../include/obd_support.h"
#define lustre_get_group_info(group_info) do { \
atomic_inc(&(group_info)->usage); \
diff --git a/drivers/staging/lustre/lustre/obdclass/linkea.c b/drivers/staging/lustre/lustre/obdclass/linkea.c
index b5c19ac1470f..8a1c7b6fefe9 100644
--- a/drivers/staging/lustre/lustre/obdclass/linkea.c
+++ b/drivers/staging/lustre/lustre/obdclass/linkea.c
@@ -27,9 +27,9 @@
* Author: Di Wang <di.wang@intel.com>
*/
-#include <lustre/lustre_idl.h>
-#include <obd.h>
-#include <lustre_linkea.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../include/obd.h"
+#include "../include/lustre_linkea.h"
int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index bdf2eed2952a..9ce3d36c685d 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -65,13 +65,13 @@
#include <linux/miscdevice.h>
#include <linux/seq_file.h>
-#include <linux/libcfs/libcfs.h>
-#include <obd_support.h>
-#include <obd_class.h>
-#include <linux/lnet/lnetctl.h>
-#include <lprocfs_status.h>
-#include <lustre_ver.h>
-#include <lustre/lustre_build_version.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_ver.h"
+#include "../../include/lustre/lustre_build_version.h"
int proc_version;
@@ -212,7 +212,7 @@ struct miscdevice obd_psdev = {
};
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int obd_proc_version_seq_show(struct seq_file *m, void *v)
{
return seq_printf(m, "lustre: %s\nkernel: %s\nbuild: %s\n",
@@ -328,7 +328,7 @@ struct lprocfs_vars lprocfs_base[] = {
{ "jobid_var", &obd_proc_jobid_var_fops },
{ .name = "jobid_name",
.fops = &obd_proc_jobid_name_fops},
- { 0 }
+ { NULL }
};
static void *obd_device_list_seq_start(struct seq_file *p, loff_t *pos)
@@ -435,4 +435,4 @@ int class_procfs_clean(void)
}
return 0;
}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
index d3bb5ffc564b..bb15202f1aae 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c
@@ -43,8 +43,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <linux/module.h>
-#include <obd_class.h>
-#include <lustre/lustre_idl.h>
+#include "../../include/obd_class.h"
+#include "../../include/lustre/lustre_idl.h"
#include <linux/fs.h>
#include <linux/pagemap.h> /* for PAGE_CACHE_SIZE */
@@ -151,7 +151,7 @@ void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid)
if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
CDEBUG(D_INODE,
- "valid "LPX64", cur time %lu/%lu, new "LPU64"/"LPU64"\n",
+ "valid %#llx, cur time %lu/%lu, new %llu/%llu\n",
src->o_valid, LTIME_S(dst->i_mtime),
LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime);
@@ -190,7 +190,7 @@ void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid)
if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
CDEBUG(D_INODE,
- "valid "LPX64", cur time %lu/%lu, new "LPU64"/"LPU64"\n",
+ "valid %#llx, cur time %lu/%lu, new %llu/%llu\n",
src->o_valid, LTIME_S(dst->i_mtime),
LTIME_S(dst->i_ctime), src->o_mtime, src->o_ctime);
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
index c1ef0c9b5a1a..38a9b319355e 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-sysctl.c
@@ -42,17 +42,17 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/ctype.h>
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
#include <linux/utsname.h>
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_support.h>
-#include <lprocfs_status.h>
+#include "../../include/obd_support.h"
+#include "../../include/lprocfs_status.h"
#ifdef CONFIG_SYSCTL
-ctl_table_header_t *obd_table_header = NULL;
+static struct ctl_table_header *obd_table_header;
#endif
@@ -79,21 +79,22 @@ enum {
};
-int LL_PROC_PROTO(proc_set_timeout)
+static int proc_set_timeout(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc;
- rc = ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
+ rc = proc_dointvec(table, write, buffer, lenp, ppos);
if (ldlm_timeout >= obd_timeout)
ldlm_timeout = max(obd_timeout / 3, 1U);
return rc;
}
-int LL_PROC_PROTO(proc_memory_alloc)
+static int proc_memory_alloc(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
char buf[22];
int len;
- DECLARE_LL_PROC_PPOS_DECL;
if (!*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -102,7 +103,7 @@ int LL_PROC_PROTO(proc_memory_alloc)
if (write)
return -EINVAL;
- len = snprintf(buf, sizeof(buf), LPU64"\n", obd_memory_sum());
+ len = snprintf(buf, sizeof(buf), "%llu\n", obd_memory_sum());
if (len > *lenp)
len = *lenp;
buf[len] = '\0';
@@ -113,11 +114,11 @@ int LL_PROC_PROTO(proc_memory_alloc)
return 0;
}
-int LL_PROC_PROTO(proc_pages_alloc)
+static int proc_pages_alloc(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
char buf[22];
int len;
- DECLARE_LL_PROC_PPOS_DECL;
if (!*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -126,7 +127,7 @@ int LL_PROC_PROTO(proc_pages_alloc)
if (write)
return -EINVAL;
- len = snprintf(buf, sizeof(buf), LPU64"\n", obd_pages_sum());
+ len = snprintf(buf, sizeof(buf), "%llu\n", obd_pages_sum());
if (len > *lenp)
len = *lenp;
buf[len] = '\0';
@@ -137,11 +138,11 @@ int LL_PROC_PROTO(proc_pages_alloc)
return 0;
}
-int LL_PROC_PROTO(proc_mem_max)
+static int proc_mem_max(struct ctl_table *table, int write, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
char buf[22];
int len;
- DECLARE_LL_PROC_PPOS_DECL;
if (!*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -150,7 +151,7 @@ int LL_PROC_PROTO(proc_mem_max)
if (write)
return -EINVAL;
- len = snprintf(buf, sizeof(buf), LPU64"\n", obd_memory_max());
+ len = snprintf(buf, sizeof(buf), "%llu\n", obd_memory_max());
if (len > *lenp)
len = *lenp;
buf[len] = '\0';
@@ -161,11 +162,11 @@ int LL_PROC_PROTO(proc_mem_max)
return 0;
}
-int LL_PROC_PROTO(proc_pages_max)
+static int proc_pages_max(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
char buf[22];
int len;
- DECLARE_LL_PROC_PPOS_DECL;
if (!*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -174,7 +175,7 @@ int LL_PROC_PROTO(proc_pages_max)
if (write)
return -EINVAL;
- len = snprintf(buf, sizeof(buf), LPU64"\n", obd_pages_max());
+ len = snprintf(buf, sizeof(buf), "%llu\n", obd_pages_max());
if (len > *lenp)
len = *lenp;
buf[len] = '\0';
@@ -185,10 +186,10 @@ int LL_PROC_PROTO(proc_pages_max)
return 0;
}
-int LL_PROC_PROTO(proc_max_dirty_pages_in_mb)
+static int proc_max_dirty_pages_in_mb(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc = 0;
- DECLARE_LL_PROC_PPOS_DECL;
if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -196,7 +197,7 @@ int LL_PROC_PROTO(proc_max_dirty_pages_in_mb)
}
if (write) {
rc = lprocfs_write_frac_helper(buffer, *lenp,
- (unsigned int*)table->data,
+ (unsigned int *)table->data,
1 << (20 - PAGE_CACHE_SHIFT));
/* Don't allow them to let dirty pages exceed 90% of system
* memory and set a hard minimum of 4MB. */
@@ -214,7 +215,7 @@ int LL_PROC_PROTO(proc_max_dirty_pages_in_mb)
int len;
len = lprocfs_read_frac_helper(buf, sizeof(buf),
- *(unsigned int*)table->data,
+ *(unsigned int *)table->data,
1 << (20 - PAGE_CACHE_SHIFT));
if (len > *lenp)
len = *lenp;
@@ -227,10 +228,10 @@ int LL_PROC_PROTO(proc_max_dirty_pages_in_mb)
return rc;
}
-int LL_PROC_PROTO(proc_alloc_fail_rate)
+static int proc_alloc_fail_rate(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
int rc = 0;
- DECLARE_LL_PROC_PPOS_DECL;
if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) {
*lenp = 0;
@@ -238,14 +239,14 @@ int LL_PROC_PROTO(proc_alloc_fail_rate)
}
if (write) {
rc = lprocfs_write_frac_helper(buffer, *lenp,
- (unsigned int*)table->data,
+ (unsigned int *)table->data,
OBD_ALLOC_FAIL_MULT);
} else {
char buf[21];
int len;
len = lprocfs_read_frac_helper(buf, 21,
- *(unsigned int*)table->data,
+ *(unsigned int *)table->data,
OBD_ALLOC_FAIL_MULT);
if (len > *lenp)
len = *lenp;
@@ -258,29 +259,8 @@ int LL_PROC_PROTO(proc_alloc_fail_rate)
return rc;
}
-int LL_PROC_PROTO(proc_at_min)
-{
- return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
-}
-int LL_PROC_PROTO(proc_at_max)
-{
- return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
-}
-int LL_PROC_PROTO(proc_at_extra)
-{
- return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
-}
-int LL_PROC_PROTO(proc_at_early_margin)
-{
- return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
-}
-int LL_PROC_PROTO(proc_at_history)
-{
- return ll_proc_dointvec(table, write, filp, buffer, lenp, ppos);
-}
-
#ifdef CONFIG_SYSCTL
-static ctl_table_t obd_table[] = {
+static struct ctl_table obd_table[] = {
{
.procname = "timeout",
.data = &obd_timeout,
@@ -363,40 +343,40 @@ static ctl_table_t obd_table[] = {
.data = &at_min,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_at_min
+ .proc_handler = &proc_dointvec,
},
{
.procname = "at_max",
.data = &at_max,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_at_max
+ .proc_handler = &proc_dointvec,
},
{
.procname = "at_extra",
.data = &at_extra,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_at_extra
+ .proc_handler = &proc_dointvec,
},
{
.procname = "at_early_margin",
.data = &at_early_margin,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_at_early_margin
+ .proc_handler = &proc_dointvec,
},
{
.procname = "at_history",
.data = &at_history,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_at_history
+ .proc_handler = &proc_dointvec,
},
{}
};
-static ctl_table_t parent_table[] = {
+static struct ctl_table parent_table[] = {
{
.procname = "lustre",
.data = NULL,
@@ -408,18 +388,18 @@ static ctl_table_t parent_table[] = {
};
#endif
-void obd_sysctl_init (void)
+void obd_sysctl_init(void)
{
#ifdef CONFIG_SYSCTL
- if ( !obd_table_header )
+ if (!obd_table_header)
obd_table_header = register_sysctl_table(parent_table);
#endif
}
-void obd_sysctl_clean (void)
+void obd_sysctl_clean(void)
{
#ifdef CONFIG_SYSCTL
- if ( obd_table_header )
+ if (obd_table_header)
unregister_sysctl_table(obd_table_header);
obd_table_header = NULL;
#endif
diff --git a/drivers/staging/lustre/lustre/obdclass/llog.c b/drivers/staging/lustre/lustre/obdclass/llog.c
index e0dfb089dd90..cce86890c563 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog.c
@@ -48,8 +48,8 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd_class.h>
-#include <lustre_log.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_log.h"
#include "llog_internal.h"
/*
@@ -188,7 +188,7 @@ static int llog_read_header(const struct lu_env *env,
llh->llh_hdr.lrh_type = LLOG_HDR_MAGIC;
llh->llh_hdr.lrh_len = llh->llh_tail.lrt_len = LLOG_CHUNK_SIZE;
llh->llh_hdr.lrh_index = llh->llh_tail.lrt_index = 0;
- llh->llh_timestamp = cfs_time_current_sec();
+ llh->llh_timestamp = get_seconds();
if (uuid)
memcpy(&llh->llh_tgtuuid, uuid,
sizeof(llh->llh_tgtuuid));
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_cat.c b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
index 1d999310ec92..ca9927ccde68 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_cat.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_cat.c
@@ -49,7 +49,7 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd_class.h>
+#include "../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 539e1d4f9d4c..5332131a2a2e 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_internal.h
+++ b/drivers/staging/lustre/lustre/obdclass/llog_internal.h
@@ -37,7 +37,7 @@
#ifndef __LLOG_INTERNAL_H__
#define __LLOG_INTERNAL_H__
-#include <lustre_log.h>
+#include "../include/lustre_log.h"
struct llog_process_info {
struct llog_handle *lpi_loghandle;
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_ioctl.c b/drivers/staging/lustre/lustre/obdclass/llog_ioctl.c
index e192aab193bb..9b7fa1d5e79a 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_ioctl.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_ioctl.c
@@ -36,8 +36,8 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd_class.h>
-#include <lustre_log.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_log.h"
#include "llog_internal.h"
static int str2logid(struct llog_logid *logid, char *str, int len)
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_lvfs.c b/drivers/staging/lustre/lustre/obdclass/llog_lvfs.c
index d86bb8c60354..fd48d59cf315 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_lvfs.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_lvfs.c
@@ -46,20 +46,20 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd.h>
-#include <obd_class.h>
-#include <lustre_log.h>
-#include <obd_ost.h>
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_log.h"
+#include "../include/obd_ost.h"
#include <linux/list.h>
-#include <lvfs.h>
-#include <lustre_fsfilt.h>
-#include <lustre_disk.h>
+#include "../include/lvfs.h"
+#include "../include/lustre_fsfilt.h"
+#include "../include/lustre_disk.h"
#include "llog_internal.h"
#if defined(LLOG_LVFS)
-static int llog_lvfs_pad(struct obd_device *obd, struct l_file *file,
- int len, int index)
+static int llog_lvfs_pad(struct obd_device *obd, struct file *file, int len,
+ int index)
{
struct llog_rec_hdr rec = { 0 };
struct llog_rec_tail tail;
@@ -88,7 +88,7 @@ static int llog_lvfs_pad(struct obd_device *obd, struct l_file *file,
return rc;
}
-static int llog_lvfs_write_blob(struct obd_device *obd, struct l_file *file,
+static int llog_lvfs_write_blob(struct obd_device *obd, struct file *file,
struct llog_rec_hdr *rec, void *buf, loff_t off)
{
int rc;
@@ -140,7 +140,7 @@ static int llog_lvfs_write_blob(struct obd_device *obd, struct l_file *file,
return rc;
}
-static int llog_lvfs_read_blob(struct obd_device *obd, struct l_file *file,
+static int llog_lvfs_read_blob(struct obd_device *obd, struct file *file,
void *buf, int size, loff_t off)
{
loff_t offset = off;
@@ -389,7 +389,7 @@ static int llog_lvfs_next_block(const struct lu_env *env,
if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
return -EINVAL;
- CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n",
+ CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off %llu)\n",
next_idx, *cur_idx, *cur_offset);
while (*cur_offset < i_size_read(loghandle->lgh_file->f_dentry->d_inode)) {
@@ -408,7 +408,7 @@ static int llog_lvfs_next_block(const struct lu_env *env,
cur_offset);
if (rc < 0) {
CERROR("Cant read llog block at log id "DOSTID
- "/%u offset "LPU64"\n",
+ "/%u offset %llu\n",
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen,
*cur_offset);
@@ -426,8 +426,8 @@ static int llog_lvfs_next_block(const struct lu_env *env,
return 0;
if (rc < sizeof(*tail)) {
- CERROR("Invalid llog block at log id "DOSTID"/%u offset"
- LPU64"\n", POSTID(&loghandle->lgh_id.lgl_oi),
+ CERROR("Invalid llog block at log id "DOSTID"/%u offset%llu\n",
+ POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, *cur_offset);
return -EINVAL;
}
@@ -451,8 +451,8 @@ static int llog_lvfs_next_block(const struct lu_env *env,
/* this shouldn't happen */
if (tail->lrt_index == 0) {
- CERROR("Invalid llog tail at log id "DOSTID"/%u offset "
- LPU64"\n", POSTID(&loghandle->lgh_id.lgl_oi),
+ CERROR("Invalid llog tail at log id "DOSTID"/%u offset %llu\n",
+ POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, *cur_offset);
return -EINVAL;
}
@@ -496,7 +496,7 @@ static int llog_lvfs_prev_block(const struct lu_env *env,
&cur_offset);
if (rc < 0) {
CERROR("Cant read llog block at log id "DOSTID
- "/%u offset "LPU64"\n",
+ "/%u offset %llu\n",
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen,
cur_offset);
@@ -510,8 +510,8 @@ static int llog_lvfs_prev_block(const struct lu_env *env,
return 0;
if (rc < sizeof(*tail)) {
- CERROR("Invalid llog block at log id "DOSTID"/%u offset"
- LPU64"\n", POSTID(&loghandle->lgh_id.lgl_oi),
+ CERROR("Invalid llog block at log id "DOSTID"/%u offset%llu\n",
+ POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, cur_offset);
return -EINVAL;
}
@@ -533,8 +533,8 @@ static int llog_lvfs_prev_block(const struct lu_env *env,
/* this shouldn't happen */
if (tail->lrt_index == 0) {
- CERROR("Invalid llog tail at log id "DOSTID"/%u offset"
- LPU64"\n", POSTID(&loghandle->lgh_id.lgl_oi),
+ CERROR("Invalid llog tail at log id "DOSTID"/%u offset%llu\n",
+ POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, cur_offset);
return -EINVAL;
}
@@ -567,7 +567,7 @@ static struct file *llog_filp_open(char *dir, char *name, int flags, int mode)
if (len >= PATH_MAX - 1) {
filp = ERR_PTR(-ENAMETOOLONG);
} else {
- filp = l_filp_open(logname, flags, mode);
+ filp = filp_open(logname, flags, mode);
if (IS_ERR(filp) && PTR_ERR(filp) != -ENOENT)
CERROR("logfile creation %s: %ld\n", logname,
PTR_ERR(filp));
@@ -581,7 +581,7 @@ static int llog_lvfs_open(const struct lu_env *env, struct llog_handle *handle,
enum llog_open_param open_param)
{
struct llog_ctxt *ctxt = handle->lgh_ctxt;
- struct l_dentry *dchild = NULL;
+ struct dentry *dchild = NULL;
struct obd_device *obd;
int rc = 0;
@@ -672,7 +672,7 @@ static int llog_lvfs_create(const struct lu_env *env,
{
struct llog_ctxt *ctxt = handle->lgh_ctxt;
struct obd_device *obd;
- struct l_dentry *dchild = NULL;
+ struct dentry *dchild = NULL;
struct file *file;
struct obdo *oa = NULL;
int rc = 0;
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
index 2c6d81eb5c65..8ff01d3f90b4 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
@@ -37,8 +37,8 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd_class.h>
-#include <lustre_log.h>
+#include "../include/obd_class.h"
+#include "../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_osd.c b/drivers/staging/lustre/lustre/obdclass/llog_osd.c
index 682279de8bea..2c6a51e90697 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_osd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_osd.c
@@ -41,10 +41,10 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <obd.h>
-#include <obd_class.h>
-#include <lustre_fid.h>
-#include <dt_object.h>
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_fid.h"
+#include "../include/dt_object.h"
#include "llog_internal.h"
#include "local_storage.h"
@@ -533,7 +533,7 @@ static int llog_osd_next_block(const struct lu_env *env,
if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
return -EINVAL;
- CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n",
+ CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off %llu)\n",
next_idx, *cur_idx, *cur_offset);
LASSERT(loghandle);
@@ -574,7 +574,7 @@ static int llog_osd_next_block(const struct lu_env *env,
dt_read_unlock(env, o);
if (rc < 0) {
CERROR("%s: can't read llog block from log "DFID
- " offset "LPU64": rc = %d\n",
+ " offset %llu: rc = %d\n",
o->do_lu.lo_dev->ld_obd->obd_name,
PFID(lu_object_fid(&o->do_lu)), *cur_offset,
rc);
@@ -592,7 +592,7 @@ static int llog_osd_next_block(const struct lu_env *env,
if (rc < sizeof(*tail)) {
CERROR("%s: invalid llog block at log id "DOSTID"/%u "
- "offset "LPU64"\n",
+ "offset %llu\n",
o->do_lu.lo_dev->ld_obd->obd_name,
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, *cur_offset);
@@ -618,7 +618,7 @@ static int llog_osd_next_block(const struct lu_env *env,
/* this shouldn't happen */
if (tail->lrt_index == 0) {
CERROR("%s: invalid llog tail at log id "DOSTID"/%u "
- "offset "LPU64"\n",
+ "offset %llu\n",
o->do_lu.lo_dev->ld_obd->obd_name,
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, *cur_offset);
@@ -687,7 +687,7 @@ static int llog_osd_prev_block(const struct lu_env *env,
dt_read_unlock(env, o);
if (rc < 0) {
CERROR("%s: can't read llog block from log "DFID
- " offset "LPU64": rc = %d\n",
+ " offset %llu: rc = %d\n",
o->do_lu.lo_dev->ld_obd->obd_name,
PFID(lu_object_fid(&o->do_lu)), cur_offset, rc);
GOTO(out, rc);
@@ -698,7 +698,7 @@ static int llog_osd_prev_block(const struct lu_env *env,
if (rc < sizeof(*tail)) {
CERROR("%s: invalid llog block at log id "DOSTID"/%u "
- "offset "LPU64"\n",
+ "offset %llu\n",
o->do_lu.lo_dev->ld_obd->obd_name,
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, cur_offset);
@@ -722,7 +722,7 @@ static int llog_osd_prev_block(const struct lu_env *env,
/* this shouldn't happen */
if (tail->lrt_index == 0) {
CERROR("%s: invalid llog tail at log id "DOSTID"/%u "
- "offset "LPU64"\n",
+ "offset %llu\n",
o->do_lu.lo_dev->ld_obd->obd_name,
POSTID(&loghandle->lgh_id.lgl_oi),
loghandle->lgh_id.lgl_ogen, cur_offset);
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
index 24ca099b01da..b3247fb7a35a 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
@@ -43,7 +43,7 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <lustre_log.h>
+#include "../include/lustre_log.h"
static void print_llogd_body(struct llogd_body *d)
{
@@ -56,7 +56,7 @@ static void print_llogd_body(struct llogd_body *d)
CDEBUG(D_OTHER, "\tlgd_index: %#x\n", d->lgd_index);
CDEBUG(D_OTHER, "\tlgd_saved_index: %#x\n", d->lgd_saved_index);
CDEBUG(D_OTHER, "\tlgd_len: %#x\n", d->lgd_len);
- CDEBUG(D_OTHER, "\tlgd_cur_offset: "LPX64"\n", d->lgd_cur_offset);
+ CDEBUG(D_OTHER, "\tlgd_cur_offset: %#llx\n", d->lgd_cur_offset);
}
void lustre_swab_lu_fid(struct lu_fid *fid)
@@ -284,7 +284,7 @@ static void print_llog_hdr(struct llog_log_hdr *h)
CDEBUG(D_OTHER, "\tllh_hdr.lrh_index: %#x\n", h->llh_hdr.lrh_index);
CDEBUG(D_OTHER, "\tllh_hdr.lrh_len: %#x\n", h->llh_hdr.lrh_len);
CDEBUG(D_OTHER, "\tllh_hdr.lrh_type: %#x\n", h->llh_hdr.lrh_type);
- CDEBUG(D_OTHER, "\tllh_timestamp: "LPX64"\n", h->llh_timestamp);
+ CDEBUG(D_OTHER, "\tllh_timestamp: %#llx\n", h->llh_timestamp);
CDEBUG(D_OTHER, "\tllh_count: %#x\n", h->llh_count);
CDEBUG(D_OTHER, "\tllh_bitmap_offset: %#x\n", h->llh_bitmap_offset);
CDEBUG(D_OTHER, "\tllh_flags: %#x\n", h->llh_flags);
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_test.c b/drivers/staging/lustre/lustre/obdclass/llog_test.c
index 764068fc4ef7..ef008abd331c 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_test.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_test.c
@@ -44,9 +44,9 @@
#include <linux/module.h>
#include <linux/init.h>
-#include <obd_class.h>
-#include <lustre_fid.h>
-#include <lustre_log.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_fid.h"
+#include "../include/lustre_log.h"
/* This is slightly more than the number of records that can fit into a
* single llog file, because the llog_log_header takes up some of the
@@ -939,9 +939,9 @@ cleanup_ctxt:
return rc;
}
-#ifdef LPROCFS
-static struct lprocfs_vars lprocfs_llog_test_obd_vars[] = { {0} };
-static struct lprocfs_vars lprocfs_llog_test_module_vars[] = { {0} };
+#if defined (CONFIG_PROC_FS)
+static struct lprocfs_vars lprocfs_llog_test_obd_vars[] = { { NULL } };
+static struct lprocfs_vars lprocfs_llog_test_module_vars[] = { { NULL } };
static void lprocfs_llog_test_init_vars(struct lprocfs_static_vars *lvars)
{
lvars->module_vars = lprocfs_llog_test_module_vars;
diff --git a/drivers/staging/lustre/lustre/obdclass/local_storage.c b/drivers/staging/lustre/lustre/obdclass/local_storage.c
index e76f7d044231..78190225ac7a 100644
--- a/drivers/staging/lustre/lustre/obdclass/local_storage.c
+++ b/drivers/staging/lustre/lustre/obdclass/local_storage.c
@@ -670,7 +670,7 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
return PTR_ERR(root);
/* find old last_id file */
- snprintf(dti->dti_buf, sizeof(dti->dti_buf), "seq-"LPX64"-lastid",
+ snprintf(dti->dti_buf, sizeof(dti->dti_buf), "seq-%#llx-lastid",
lastid_seq);
rc = dt_lookup_dir(env, root, dti->dti_buf, &dti->dti_fid);
lu_object_put_nocache(env, &root->do_lu);
@@ -693,7 +693,7 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
} else if (rc < 0) {
return rc;
} else {
- CDEBUG(D_INFO, "Found old lastid file for sequence "LPX64"\n",
+ CDEBUG(D_INFO, "Found old lastid file for sequence %#llx\n",
lastid_seq);
o = ls_locate(env, ls, &dti->dti_fid);
if (IS_ERR(o))
@@ -709,12 +709,12 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
dt_read_unlock(env, o);
lu_object_put_nocache(env, &o->do_lu);
if (rc == 0 && le32_to_cpu(losd.lso_magic) != LOS_MAGIC) {
- CERROR("%s: wrong content of seq-"LPX64"-lastid file, magic %x\n",
+ CERROR("%s: wrong content of seq-%#llx-lastid file, magic %x\n",
o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq,
le32_to_cpu(losd.lso_magic));
return -EINVAL;
} else if (rc < 0) {
- CERROR("%s: failed to read seq-"LPX64"-lastid: rc = %d\n",
+ CERROR("%s: failed to read seq-%#llx-lastid: rc = %d\n",
o->do_lu.lo_dev->ld_obd->obd_name, lastid_seq, rc);
return rc;
}
@@ -837,7 +837,7 @@ out_trans:
rc = dt_record_read(env, o, &dti->dti_lb, &dti->dti_off);
dt_read_unlock(env, o);
if (rc == 0 && le64_to_cpu(lastid) > OBIF_MAX_OID) {
- CERROR("%s: bad oid "LPU64" is read from LAST_ID\n",
+ CERROR("%s: bad oid %llu is read from LAST_ID\n",
o->do_lu.lo_dev->ld_obd->obd_name,
le64_to_cpu(lastid));
rc = -EINVAL;
diff --git a/drivers/staging/lustre/lustre/obdclass/local_storage.h b/drivers/staging/lustre/lustre/obdclass/local_storage.h
index 0f63b8c073b4..0b9ad33d1152 100644
--- a/drivers/staging/lustre/lustre/obdclass/local_storage.h
+++ b/drivers/staging/lustre/lustre/obdclass/local_storage.h
@@ -32,10 +32,10 @@
#ifndef __LOCAL_STORAGE_H
#define __LOCAL_STORAGE_H
-#include <dt_object.h>
-#include <obd.h>
-#include <lustre_fid.h>
-#include <lustre_disk.h>
+#include "../include/dt_object.h"
+#include "../include/obd.h"
+#include "../include/lustre_fid.h"
+#include "../include/lustre_disk.h"
struct ls_device {
struct dt_device ls_top_dev;
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index 1432dd74fe95..8309d4ce6d60 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -41,9 +41,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
-#include <lprocfs_status.h>
-#include <lustre/lustre_idl.h>
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre/lustre_idl.h"
#include <linux/seq_file.h>
static const char * const obd_connect_names[] = {
@@ -116,7 +116,7 @@ int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep)
}
if (flags & ~(mask - 1))
ret += snprintf(page + ret, count - ret,
- "%sunknown flags "LPX64,
+ "%sunknown flags %#llx",
ret ? sep : "", flags & ~(mask - 1));
return ret;
}
@@ -220,7 +220,7 @@ int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
}
EXPORT_SYMBOL(lprocfs_write_frac_helper);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
static int lprocfs_no_percpu_stats = 0;
module_param(lprocfs_no_percpu_stats, int, 0644);
@@ -400,7 +400,7 @@ EXPORT_SYMBOL(lprocfs_wr_uint);
int lprocfs_rd_u64(struct seq_file *m, void *data)
{
- return seq_printf(m, LPU64"\n", *(__u64 *)data);
+ return seq_printf(m, "%llu\n", *(__u64 *)data);
}
EXPORT_SYMBOL(lprocfs_rd_u64);
@@ -476,7 +476,7 @@ int lprocfs_rd_kbytestotal(struct seq_file *m, void *data)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -496,7 +496,7 @@ int lprocfs_rd_kbytesfree(struct seq_file *m, void *data)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -516,7 +516,7 @@ int lprocfs_rd_kbytesavail(struct seq_file *m, void *data)
while (blk_size >>= 1)
result <<= 1;
- rc = seq_printf(m, LPU64"\n", result);
+ rc = seq_printf(m, "%llu\n", result);
}
return rc;
}
@@ -530,7 +530,7 @@ int lprocfs_rd_filestotal(struct seq_file *m, void *data)
cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
OBD_STATFS_NODELAY);
if (!rc)
- rc = seq_printf(m, LPU64"\n", osfs.os_files);
+ rc = seq_printf(m, "%llu\n", osfs.os_files);
return rc;
}
@@ -544,7 +544,7 @@ int lprocfs_rd_filesfree(struct seq_file *m, void *data)
cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
OBD_STATFS_NODELAY);
if (!rc)
- rc = seq_printf(m, LPU64"\n", osfs.os_ffree);
+ rc = seq_printf(m, "%llu\n", osfs.os_ffree);
return rc;
}
EXPORT_SYMBOL(lprocfs_rd_filesfree);
@@ -667,7 +667,7 @@ static void obd_connect_seq_flags2str(struct seq_file *m, __u64 flags, char *sep
}
}
if (flags & ~(mask - 1))
- seq_printf(m, "%sunknown flags "LPX64,
+ seq_printf(m, "%sunknown flags %#llx",
first ? sep : "", flags & ~(mask - 1));
}
@@ -744,7 +744,7 @@ int lprocfs_rd_import(struct seq_file *m, void *data)
" inflight: %u\n"
" unregistering: %u\n"
" timeouts: %u\n"
- " avg_waittime: "LPU64" %s\n",
+ " avg_waittime: %llu %s\n",
atomic_read(&imp->imp_inflight),
atomic_read(&imp->imp_unregistering),
atomic_read(&imp->imp_timeouts),
@@ -766,9 +766,9 @@ int lprocfs_rd_import(struct seq_file *m, void *data)
seq_printf(m,
" transactions:\n"
- " last_replay: "LPU64"\n"
- " peer_committed: "LPU64"\n"
- " last_checked: "LPU64"\n",
+ " last_replay: %llu\n"
+ " peer_committed: %llu\n"
+ " last_checked: %llu\n",
imp->imp_last_replay_transno,
imp->imp_peer_committed_transno,
imp->imp_last_transno_checked);
@@ -785,7 +785,7 @@ int lprocfs_rd_import(struct seq_file *m, void *data)
ret.lc_sum = sum;
seq_printf(m,
" %s_data_averages:\n"
- " bytes_per_rpc: "LPU64"\n",
+ " bytes_per_rpc: %llu\n",
rw ? "write" : "read",
ret.lc_sum);
}
@@ -799,7 +799,7 @@ int lprocfs_rd_import(struct seq_file *m, void *data)
do_div(sum, ret.lc_count);
ret.lc_sum = sum;
seq_printf(m,
- " %s_per_rpc: "LPU64"\n",
+ " %s_per_rpc: %llu\n",
header->lc_units, ret.lc_sum);
j = (int)ret.lc_sum;
if (j > 0)
@@ -868,7 +868,7 @@ int lprocfs_rd_timeouts(struct seq_file *m, void *data)
LPROCFS_CLIMP_CHECK(obd);
imp = obd->u.cli.cl_import;
- now = cfs_time_current_sec();
+ now = get_seconds();
/* Some network health info for kicks */
s2dhms(&ts, now - imp->imp_last_reply_time);
@@ -908,7 +908,7 @@ int lprocfs_rd_connect_flags(struct seq_file *m, void *data)
LPROCFS_CLIMP_CHECK(obd);
flags = obd->u.cli.cl_import->imp_connect_data.ocd_connect_flags;
- seq_printf(m, "flags="LPX64"\n", flags);
+ seq_printf(m, "flags=%#llx\n", flags);
obd_connect_seq_flags2str(m, flags, "\n");
seq_printf(m, "\n");
LPROCFS_CLIMP_EXIT(obd);
@@ -1175,19 +1175,19 @@ static int lprocfs_stats_seq_show(struct seq_file *p, void *v)
if (ctr.lc_count == 0)
goto out;
- rc = seq_printf(p, "%-25s "LPD64" samples [%s]", hdr->lc_name,
+ rc = seq_printf(p, "%-25s %lld samples [%s]", hdr->lc_name,
ctr.lc_count, hdr->lc_units);
if (rc < 0)
goto out;
if ((hdr->lc_config & LPROCFS_CNTR_AVGMINMAX) && (ctr.lc_count > 0)) {
- rc = seq_printf(p, " "LPD64" "LPD64" "LPD64,
+ rc = seq_printf(p, " %lld %lld %lld",
ctr.lc_min, ctr.lc_max, ctr.lc_sum);
if (rc < 0)
goto out;
if (hdr->lc_config & LPROCFS_CNTR_STDDEV)
- rc = seq_printf(p, " "LPD64, ctr.lc_sumsquare);
+ rc = seq_printf(p, " %lld", ctr.lc_sumsquare);
if (rc < 0)
goto out;
}
@@ -1196,7 +1196,7 @@ out:
return (rc < 0) ? rc : 0;
}
-struct seq_operations lprocfs_stats_seq_sops = {
+static const struct seq_operations lprocfs_stats_seq_sops = {
.start = lprocfs_stats_seq_start,
.stop = lprocfs_stats_seq_stop,
.next = lprocfs_stats_seq_next,
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 92e8a15a5e5d..2fc037cfb62f 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -44,18 +44,18 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
# include <linux/module.h>
/* hash_long() */
-#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 <lu_ref.h>
+#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/lu_ref.h"
#include <linux/list.h>
static void lu_object_free(const struct lu_env *env, struct lu_object *o);
@@ -1994,7 +1994,7 @@ void lu_global_fini(void)
static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx)
{
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
struct lprocfs_counter ret;
lprocfs_stats_collect(stats, idx, &ret);
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_ref.c b/drivers/staging/lustre/lustre/obdclass/lu_ref.c
index 23a76f158356..993697b660f6 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_ref.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_ref.c
@@ -42,9 +42,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lu_ref.h>
+#include "../include/obd.h"
+#include "../include/obd_class.h"
+#include "../include/obd_support.h"
+#include "../include/lu_ref.h"
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_ucred.c b/drivers/staging/lustre/lustre/obdclass/lu_ucred.c
index e23e545b0d66..3676563ab330 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_ucred.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_ucred.c
@@ -44,10 +44,10 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <linux/libcfs/libcfs.h>
-#include <obd_support.h>
-#include <lu_object.h>
-#include <md_object.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/obd_support.h"
+#include "../include/lu_object.h"
+#include "../include/md_object.h"
/* context key constructor/destructor: lu_ucred_key_init, lu_ucred_key_fini */
LU_KEY_INIT_FINI(lu_ucred, struct lu_ucred);
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
index be31d32b82c8..2010463429b1 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c
@@ -40,9 +40,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_support.h>
-#include <lustre_handles.h>
-#include <lustre_lib.h>
+#include "../include/obd_support.h"
+#include "../include/lustre_handles.h"
+#include "../include/lustre_lib.h"
static __u64 handle_base;
@@ -97,7 +97,7 @@ void class_handle_hash(struct portals_handle *h,
h->h_in = 1;
spin_unlock(&bucket->lock);
- CDEBUG(D_INFO, "added object %p with handle "LPX64" to hash\n",
+ CDEBUG(D_INFO, "added object %p with handle %#llx to hash\n",
h, h->h_cookie);
}
EXPORT_SYMBOL(class_handle_hash);
@@ -105,12 +105,12 @@ EXPORT_SYMBOL(class_handle_hash);
static void class_handle_unhash_nolock(struct portals_handle *h)
{
if (list_empty(&h->h_link)) {
- CERROR("removing an already-removed handle ("LPX64")\n",
+ CERROR("removing an already-removed handle (%#llx)\n",
h->h_cookie);
return;
}
- CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n",
+ CDEBUG(D_INFO, "removing object %p with handle %#llx from hash\n",
h, h->h_cookie);
spin_lock(&h->h_lock);
@@ -230,7 +230,7 @@ static int cleanup_all_handles(void)
spin_lock(&handle_hash[i].lock);
list_for_each_entry_rcu(h, &(handle_hash[i].head), h_link) {
- CERROR("force clean handle "LPX64" addr %p ops %p\n",
+ CERROR("force clean handle %#llx addr %p ops %p\n",
h->h_cookie, h, h->h_ops);
class_handle_unhash_nolock(h);
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
index df4936ad2375..64b2f35e224f 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
@@ -36,13 +36,13 @@
#define DEBUG_SUBSYSTEM S_RPC
-#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>
+#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"
#define NIDS_MAX 32
diff --git a/drivers/staging/lustre/lustre/obdclass/md_attrs.c b/drivers/staging/lustre/lustre/obdclass/md_attrs.c
index f080cceb384c..d9e6348de4fa 100644
--- a/drivers/staging/lustre/lustre/obdclass/md_attrs.c
+++ b/drivers/staging/lustre/lustre/obdclass/md_attrs.c
@@ -27,9 +27,9 @@
* Author: Johann Lombardi <johann.lombardi@intel.com>
*/
-#include <lustre/lustre_idl.h>
-#include <obd.h>
-#include <md_object.h>
+#include "../include/lustre/lustre_idl.h"
+#include "../include/obd.h"
+#include "../include/md_object.h"
/**
* Initialize new \a lma. Only fid is stored.
diff --git a/drivers/staging/lustre/lustre/obdclass/mea.c b/drivers/staging/lustre/lustre/obdclass/mea.c
index c4f0dbc23611..d6ce084da902 100644
--- a/drivers/staging/lustre/lustre/obdclass/mea.c
+++ b/drivers/staging/lustre/lustre/obdclass/mea.c
@@ -33,13 +33,13 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include <linux/kmod.h> /* for request_module() */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
-#include <lprocfs_status.h>
-#include <lustre/lustre_idl.h>
+#include "../include/lprocfs_status.h"
+#include "../include/lustre/lustre_idl.h"
static int mea_last_char_hash(int count, char *name, int namelen)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c
index 2d5777699f47..0d81d3232f31 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_config.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c
@@ -39,11 +39,11 @@
*/
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include <linux/string.h>
-#include <lustre_log.h>
-#include <lprocfs_status.h>
-#include <lustre_param.h>
+#include "../include/lustre_log.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_param.h"
#include "llog_internal.h"
@@ -1093,9 +1093,9 @@ int class_process_config(struct lustre_cfg *lcfg)
GOTO(out, err);
}
case LCFG_ADD_UUID: {
- CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
- " (%s)\n", lustre_cfg_string(lcfg, 1),
- lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
+ CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n",
+ lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
+ libcfs_nid2str(lcfg->lcfg_nid));
err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
GOTO(out, err);
@@ -1161,7 +1161,7 @@ int class_process_config(struct lustre_cfg *lcfg)
char *tmp;
/* llite has no obd */
if ((class_match_param(lustre_cfg_string(lcfg, 1),
- PARAM_LLITE, 0) == 0) &&
+ PARAM_LLITE, NULL) == 0) &&
client_process_config) {
err = (*client_process_config)(lcfg);
GOTO(out, err);
@@ -1303,8 +1303,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
/* Search proc entries */
while (lvars[j].name) {
var = &lvars[j];
- if (class_match_param(key, (char *)var->name, 0) == 0 &&
- keylen == strlen(var->name)) {
+ if (class_match_param(key, (char *)var->name, NULL) == 0
+ && keylen == strlen(var->name)) {
matched++;
rc = -EROFS;
if (var->fops && var->fops->write) {
@@ -1614,7 +1614,7 @@ int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf, int size)
ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
if (lcfg->lcfg_nid)
- ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ",
+ ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n ",
libcfs_nid2str(lcfg->lcfg_nid),
lcfg->lcfg_nid);
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
index a034aee37fc1..d972f71c9d97 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
@@ -45,13 +45,13 @@
#define D_MOUNT (D_SUPER|D_CONFIG/*|D_WARNING */)
#define PRINT_CMD CDEBUG
-#include <obd.h>
-#include <lvfs.h>
-#include <obd_class.h>
-#include <lustre/lustre_user.h>
-#include <lustre_log.h>
-#include <lustre_disk.h>
-#include <lustre_param.h>
+#include "../include/obd.h"
+#include "../include/lvfs.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"
static int (*client_fill_super)(struct super_block *sb,
struct vfsmount *mnt);
@@ -219,7 +219,6 @@ int lustre_start_mgc(struct super_block *sb)
lnet_nid_t nid;
char *mgcname = NULL, *niduuid = NULL, *mgssec = NULL;
char *ptr;
- int recov_bk;
int rc = 0, i = 0, j, len;
LASSERT(lsi->lsi_lmd);
@@ -269,6 +268,8 @@ int lustre_start_mgc(struct super_block *sb)
obd = class_name2obd(mgcname);
if (obd && !obd->obd_stopping) {
+ int recov_bk;
+
rc = obd_set_info_async(NULL, obd->obd_self_export,
strlen(KEY_MGSSEC), KEY_MGSSEC,
strlen(mgssec), mgssec, NULL);
@@ -429,16 +430,6 @@ int lustre_start_mgc(struct super_block *sb)
so we know when we can get rid of the mgc. */
atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
- /* Try all connections, but only once. */
- recov_bk = 1;
- rc = obd_set_info_async(NULL, obd->obd_self_export,
- sizeof(KEY_INIT_RECOV_BACKUP),
- KEY_INIT_RECOV_BACKUP,
- sizeof(recov_bk), &recov_bk, NULL);
- if (rc)
- /* nonfatal */
- CWARN("can't set %s %d\n", KEY_INIT_RECOV_BACKUP, rc);
-
/* We connect to the MGS at setup, and don't disconnect until cleanup */
data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
@@ -1225,7 +1216,9 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
if (lmd_is_client(lmd)) {
CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
- if (!client_fill_super) {
+ if (client_fill_super == NULL)
+ request_module("lustre");
+ if (client_fill_super == NULL) {
LCONSOLE_ERROR_MSG(0x165, "Nothing registered for "
"client mount! Is the 'lustre' "
"module loaded?\n");
@@ -1308,6 +1301,7 @@ struct file_system_type lustre_fs_type = {
.fs_flags = FS_BINARY_MOUNTDATA | FS_REQUIRES_DEV |
FS_HAS_FIEMAP | FS_RENAME_DOES_D_MOVE,
};
+MODULE_ALIAS_FS("lustre");
int lustre_register_fs(void)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c
index 3b1b28afd6b1..c9fa36b17919 100644
--- a/drivers/staging/lustre/lustre/obdclass/obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/obdo.c
@@ -42,8 +42,8 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_class.h>
-#include <lustre/lustre_idl.h>
+#include "../include/obd_class.h"
+#include "../include/lustre/lustre_idl.h"
void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent)
{
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(obdo_from_inode);
void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid)
{
- CDEBUG(D_INODE, "src obdo "DOSTID" valid "LPX64", dst obdo "DOSTID"\n",
+ CDEBUG(D_INODE, "src obdo "DOSTID" valid %#llx, dst obdo "DOSTID"\n",
POSTID(&src->o_oi), src->o_valid, POSTID(&dst->o_oi));
if (valid & OBD_MD_FLATIME)
dst->o_atime = src->o_atime;
@@ -252,7 +252,7 @@ void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid)
valid &= oa->o_valid;
if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
- CDEBUG(D_INODE, "valid "LPX64", new time "LPU64"/"LPU64"\n",
+ CDEBUG(D_INODE, "valid %#llx, new time %llu/%llu\n",
oa->o_valid, oa->o_mtime, oa->o_ctime);
attr->ia_valid = 0;
diff --git a/drivers/staging/lustre/lustre/obdclass/statfs_pack.c b/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
index c3b7a78dba50..33b1a83f4014 100644
--- a/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
+++ b/drivers/staging/lustre/lustre/obdclass/statfs_pack.c
@@ -41,10 +41,10 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <lustre_export.h>
-#include <lustre_net.h>
-#include <obd_support.h>
-#include <obd_class.h>
+#include "../include/lustre_export.h"
+#include "../include/lustre_net.h"
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs)
{
diff --git a/drivers/staging/lustre/lustre/obdclass/uuid.c b/drivers/staging/lustre/lustre/obdclass/uuid.c
index e87a19900770..ff0a01bcf8da 100644
--- a/drivers/staging/lustre/lustre/obdclass/uuid.c
+++ b/drivers/staging/lustre/lustre/obdclass/uuid.c
@@ -38,10 +38,10 @@
#define DEBUG_SUBSYSTEM S_CLASS
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_support.h>
-#include <obd_class.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
static inline __u32 consume(int nob, __u8 **ptr)
diff --git a/drivers/staging/lustre/lustre/obdecho/Makefile b/drivers/staging/lustre/lustre/obdecho/Makefile
index 4c48e2432f9b..672028fc7f6e 100644
--- a/drivers/staging/lustre/lustre/obdecho/Makefile
+++ b/drivers/staging/lustre/lustre/obdecho/Makefile
@@ -1,5 +1,2 @@
obj-$(CONFIG_LUSTRE_FS) += obdecho.o
obdecho-y := echo_client.o lproc_echo.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/obdecho/echo.c b/drivers/staging/lustre/lustre/obdecho/echo.c
index 96a807f82ec1..dae1599af384 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo.c
@@ -41,11 +41,11 @@
#define DEBUG_SUBSYSTEM S_ECHO
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_debug.h>
-#include <lustre_dlm.h>
-#include <lprocfs_status.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_debug.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lprocfs_status.h"
#include "echo_internal.h"
@@ -120,18 +120,18 @@ static int echo_create(const struct lu_env *env, struct obd_export *exp,
struct obd_device *obd = class_exp2obd(exp);
if (!obd) {
- CERROR("invalid client cookie "LPX64"\n",
+ CERROR("invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
- if (!(oa->o_mode && S_IFMT)) {
+ if (!(oa->o_mode & S_IFMT)) {
CERROR("echo obd: no type!\n");
return -ENOENT;
}
if (!(oa->o_valid & OBD_MD_FLTYPE)) {
- CERROR("invalid o_valid "LPX64"\n", oa->o_valid);
+ CERROR("invalid o_valid %#llx\n", oa->o_valid);
return -EINVAL;
}
@@ -150,13 +150,13 @@ static int echo_destroy(const struct lu_env *env, struct obd_export *exp,
struct obd_device *obd = class_exp2obd(exp);
if (!obd) {
- CERROR("invalid client cookie "LPX64"\n",
+ CERROR("invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
if (!(oa->o_valid & OBD_MD_FLID)) {
- CERROR("obdo missing FLID valid flag: "LPX64"\n", oa->o_valid);
+ CERROR("obdo missing FLID valid flag: %#llx\n", oa->o_valid);
return -EINVAL;
}
@@ -176,13 +176,13 @@ static int echo_getattr(const struct lu_env *env, struct obd_export *exp,
obd_id id = ostid_id(&oinfo->oi_oa->o_oi);
if (!obd) {
- CERROR("invalid client cookie "LPX64"\n",
+ CERROR("invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {
- CERROR("obdo missing FLID valid flag: "LPX64"\n",
+ CERROR("obdo missing FLID valid flag: %#llx\n",
oinfo->oi_oa->o_valid);
return -EINVAL;
}
@@ -200,13 +200,13 @@ static int echo_setattr(const struct lu_env *env, struct obd_export *exp,
struct obd_device *obd = class_exp2obd(exp);
if (!obd) {
- CERROR("invalid client cookie "LPX64"\n",
+ CERROR("invalid client cookie %#llx\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
if (!(oinfo->oi_oa->o_valid & OBD_MD_FLID)) {
- CERROR("obdo missing FLID valid flag: "LPX64"\n",
+ CERROR("obdo missing FLID valid flag: %#llx\n",
oinfo->oi_oa->o_valid);
return -EINVAL;
}
@@ -327,7 +327,7 @@ static int echo_map_nb_to_lb(struct obdo *oa, struct obd_ioobj *obj,
}
}
- CDEBUG(D_PAGE, "$$$$ get page %p @ "LPU64" for %d\n",
+ CDEBUG(D_PAGE, "$$$$ get page %p @ %llu for %d\n",
res->page, res->lnb_file_offset, res->len);
if (cmd & OBD_BRW_READ)
@@ -365,7 +365,7 @@ static int echo_finalize_lb(struct obdo *oa, struct obd_ioobj *obj,
void *addr;
if (page == NULL) {
- CERROR("null page objid "LPU64":%p, buf %d/%d\n",
+ CERROR("null page objid %llu:%p, buf %d/%d\n",
ostid_id(&obj->ioo_oid), page, i,
obj->ioo_bufcnt);
return -EFAULT;
@@ -373,7 +373,7 @@ static int echo_finalize_lb(struct obdo *oa, struct obd_ioobj *obj,
addr = kmap(page);
- CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@"LPU64"\n",
+ CDEBUG(D_PAGE, "$$$$ use page %p, addr %p@%llu\n",
res->page, addr, res->lnb_file_offset);
if (verify) {
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index cdc46719bbd4..f1847f3f579d 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -35,18 +35,18 @@
*/
#define DEBUG_SUBSYSTEM S_ECHO
-#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 <md_object.h>
-#include <lustre_fid.h>
-#include <lustre_acl.h>
-#include <lustre_net.h>
+#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/md_object.h"
+#include "../include/lustre_fid.h"
+#include "../include/lustre_acl.h"
+#include "../include/lustre_net.h"
#include "echo_internal.h"
@@ -1228,7 +1228,7 @@ static int cl_echo_cancel0(struct lu_env *env, struct echo_device *ed,
spin_lock(&ec->ec_lock);
list_for_each (el, &ec->ec_locks) {
ecl = list_entry (el, struct echo_lock, el_chain);
- CDEBUG(D_INFO, "ecl: %p, cookie: "LPX64"\n", ecl, ecl->el_cookie);
+ CDEBUG(D_INFO, "ecl: %p, cookie: %#llx\n", ecl, ecl->el_cookie);
found = (ecl->el_cookie == cookie);
if (found) {
if (atomic_dec_and_test(&ecl->el_refcount))
@@ -1430,7 +1430,7 @@ echo_copyin_lsm (struct echo_device *ed, struct lov_stripe_md *lsm,
static inline void echo_md_build_name(struct lu_name *lname, char *name,
__u64 id)
{
- sprintf(name, LPU64, id);
+ sprintf(name, "%llu", id);
lname->ln_name = name;
lname->ln_namelen = strlen(name);
}
@@ -1540,7 +1540,7 @@ int echo_attr_get_complex(const struct lu_env *env, struct md_object *next,
#endif
out:
ma->ma_need = need;
- CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64" ma_lmm=%p\n",
+ CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = %#llx ma_lmm=%p\n",
rc, ma->ma_valid, ma->ma_lmm);
return rc;
}
@@ -2408,7 +2408,7 @@ static int echo_client_page_debug_check(struct lov_stripe_md *lsm,
addr + delta, OBD_ECHO_BLOCK_SIZE,
stripe_off, stripe_id);
if (rc2 != 0) {
- CERROR ("Error in echo object "LPX64"\n", id);
+ CERROR ("Error in echo object %#llx\n", id);
rc = rc2;
}
}
@@ -2703,7 +2703,7 @@ echo_client_enqueue(struct obd_export *exp, struct obdo *oa,
rc = cl_echo_enqueue(eco, offset, end, mode, &ulh->cookie);
if (rc == 0) {
oa->o_valid |= OBD_MD_FLHANDLE;
- CDEBUG(D_INFO, "Cookie is "LPX64"\n", ulh->cookie);
+ CDEBUG(D_INFO, "Cookie is %#llx\n", ulh->cookie);
}
echo_put_object(eco);
return rc;
@@ -2718,7 +2718,7 @@ echo_client_cancel(struct obd_export *exp, struct obdo *oa)
if ((oa->o_valid & OBD_MD_FLHANDLE) == 0)
return -EINVAL;
- CDEBUG(D_INFO, "Cookie is "LPX64"\n", cookie);
+ CDEBUG(D_INFO, "Cookie is %#llx\n", cookie);
return cl_echo_cancel(ed, cookie);
}
@@ -3084,7 +3084,7 @@ static int echo_client_disconnect(struct obd_export *exp)
rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm,
ecl->ecl_mode, &ecl->ecl_lock_handle);
- CDEBUG (D_INFO, "Cancel lock on object "LPX64" on disconnect "
+ CDEBUG (D_INFO, "Cancel lock on object %#llx on disconnect "
"(%d)\n", ecl->ecl_object->eco_id, rc);
echo_put_object (ecl->ecl_object);
@@ -3113,7 +3113,7 @@ static struct obd_ops echo_client_obd_ops = {
int echo_client_init(void)
{
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc;
lprocfs_echo_init_vars(&lvars);
diff --git a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c b/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
index 8fe9245a8aad..1d3bf6c93129 100644
--- a/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
+++ b/drivers/staging/lustre/lustre/obdecho/lproc_echo.c
@@ -33,25 +33,25 @@
*/
#define DEBUG_SUBSYSTEM S_ECHO
-#include <lprocfs_status.h>
-#include <obd_class.h>
+#include "../include/lprocfs_status.h"
+#include "../include/obd_class.h"
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
LPROC_SEQ_FOPS_RO_TYPE(echo, uuid);
static struct lprocfs_vars lprocfs_echo_obd_vars[] = {
{ "uuid", &echo_uuid_fops, NULL, 0 },
- { 0 }
+ { NULL }
};
LPROC_SEQ_FOPS_RO_TYPE(echo, numrefs);
static struct lprocfs_vars lprocfs_echo_module_vars[] = {
{ "num_refs", &echo_numrefs_fops, NULL, 0 },
- { 0 }
+ { NULL }
};
void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars)
{
- lvars->module_vars = lprocfs_echo_module_vars;
- lvars->obd_vars = lprocfs_echo_obd_vars;
+ lvars->module_vars = lprocfs_echo_module_vars;
+ lvars->obd_vars = lprocfs_echo_obd_vars;
}
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
diff --git a/drivers/staging/lustre/lustre/osc/Makefile b/drivers/staging/lustre/lustre/osc/Makefile
index 4488162d228a..54927fba4eb4 100644
--- a/drivers/staging/lustre/lustre/osc/Makefile
+++ b/drivers/staging/lustre/lustre/osc/Makefile
@@ -2,7 +2,3 @@ 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
osc-$(CONFIG_PROC_FS) += lproc_osc.o
-
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 0cadfcd92262..2ab403548b5e 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -36,9 +36,9 @@
#define DEBUG_SUBSYSTEM S_CLASS
#include <asm/statfs.h>
-#include <obd_cksum.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include "../include/obd_cksum.h"
+#include "../include/obd_class.h"
+#include "../include/lprocfs_status.h"
#include <linux/seq_file.h>
#include "osc_internal.h"
@@ -693,11 +693,11 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "snapshot_time: %lu.%lu (secs.usecs)\n",
now.tv_sec, (unsigned long)now.tv_usec);
- seq_printf(seq, "lockless_write_bytes\t\t"LPU64"\n",
+ seq_printf(seq, "lockless_write_bytes\t\t%llu\n",
stats->os_lockless_writes);
- seq_printf(seq, "lockless_read_bytes\t\t"LPU64"\n",
+ seq_printf(seq, "lockless_read_bytes\t\t%llu\n",
stats->os_lockless_reads);
- seq_printf(seq, "lockless_truncate\t\t"LPU64"\n",
+ seq_printf(seq, "lockless_truncate\t\t%llu\n",
stats->os_lockless_truncates);
return 0;
}
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 00f38eeb5786..57d7dba23479 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -871,7 +871,8 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
LASSERT(sanity_check_nolock(ext) == 0);
/* `Kick' this extent only if the caller is waiting for it to be
* written out. */
- if (state == OES_INV && !ext->oe_urgent && !ext->oe_hp) {
+ if (state == OES_INV && !ext->oe_urgent && !ext->oe_hp &&
+ !ext->oe_trunc_pending) {
if (ext->oe_state == OES_ACTIVE) {
ext->oe_urgent = 1;
} else if (ext->oe_state == OES_CACHE) {
@@ -922,8 +923,8 @@ static int osc_extent_truncate(struct osc_extent *ext, pgoff_t trunc_index,
int rc = 0;
LASSERT(sanity_check(ext) == 0);
- LASSERT(ext->oe_state == OES_TRUNC);
- LASSERT(!ext->oe_urgent);
+ EASSERT(ext->oe_state == OES_TRUNC, ext);
+ EASSERT(!ext->oe_urgent, ext);
/* Request new lu_env.
* We can't use that env from osc_cache_truncate_start() because
@@ -2153,7 +2154,7 @@ int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops,
INIT_LIST_HEAD(&oap->oap_rpc_item);
spin_lock_init(&oap->oap_lock);
- CDEBUG(D_INFO, "oap %p page %p obj off "LPU64"\n",
+ CDEBUG(D_INFO, "oap %p page %p obj off %llu\n",
oap, page, oap->oap_obj_off);
return 0;
}
@@ -2594,7 +2595,7 @@ again:
break;
}
- OSC_EXTENT_DUMP(D_CACHE, ext, "try to trunc:"LPU64".\n", size);
+ OSC_EXTENT_DUMP(D_CACHE, ext, "try to trunc:%llu.\n", size);
osc_extent_get(ext);
if (ext->oe_state == OES_ACTIVE) {
@@ -2655,7 +2656,7 @@ again:
LASSERT(oio->oi_trunc == NULL);
oio->oi_trunc = osc_extent_get(ext);
OSC_EXTENT_DUMP(D_CACHE, ext,
- "trunc at "LPU64"\n", size);
+ "trunc at %llu\n", size);
}
osc_extent_put(env, ext);
}
diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
index e74b7bb9776c..2d1f977dca36 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
@@ -46,13 +46,13 @@
#ifndef OSC_CL_INTERNAL_H
#define OSC_CL_INTERNAL_H
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd.h>
+#include "../include/obd.h"
/* osc_build_res_name() */
-#include <obd_ost.h>
-#include <cl_object.h>
-#include <lclient.h>
+#include "../include/obd_ost.h"
+#include "../include/cl_object.h"
+#include "../include/lclient.h"
#include "osc_internal.h"
/** \defgroup osc osc
@@ -118,7 +118,7 @@ struct osc_object {
* True if locking against this stripe got -EUSERS.
*/
int oo_contended;
- cfs_time_t oo_contention_time;
+ unsigned long oo_contention_time;
/**
* List of pages in transfer.
*/
@@ -387,7 +387,7 @@ struct osc_page {
/**
* Submit time - the time when the page is starting RPC. For debugging.
*/
- cfs_time_t ops_submit_time;
+ unsigned long ops_submit_time;
/**
* A lock of which we hold a reference covers this page. Only used by
diff --git a/drivers/staging/lustre/lustre/osc/osc_dev.c b/drivers/staging/lustre/lustre/osc/osc_dev.c
index a7c1ec0d56fe..4935fc7c0706 100644
--- a/drivers/staging/lustre/lustre/osc/osc_dev.c
+++ b/drivers/staging/lustre/lustre/osc/osc_dev.c
@@ -41,7 +41,7 @@
#define DEBUG_SUBSYSTEM S_OSC
/* class_name2obd() */
-#include <obd_class.h>
+#include "../include/obd_class.h"
#include "osc_cl_internal.h"
@@ -61,32 +61,32 @@ struct lu_kmem_descr osc_caches[] = {
{
.ckd_cache = &osc_lock_kmem,
.ckd_name = "osc_lock_kmem",
- .ckd_size = sizeof (struct osc_lock)
+ .ckd_size = sizeof(struct osc_lock)
},
{
.ckd_cache = &osc_object_kmem,
.ckd_name = "osc_object_kmem",
- .ckd_size = sizeof (struct osc_object)
+ .ckd_size = sizeof(struct osc_object)
},
{
.ckd_cache = &osc_thread_kmem,
.ckd_name = "osc_thread_kmem",
- .ckd_size = sizeof (struct osc_thread_info)
+ .ckd_size = sizeof(struct osc_thread_info)
},
{
.ckd_cache = &osc_session_kmem,
.ckd_name = "osc_session_kmem",
- .ckd_size = sizeof (struct osc_session)
+ .ckd_size = sizeof(struct osc_session)
},
{
.ckd_cache = &osc_req_kmem,
.ckd_name = "osc_req_kmem",
- .ckd_size = sizeof (struct osc_req)
+ .ckd_size = sizeof(struct osc_req)
},
{
.ckd_cache = &osc_extent_kmem,
.ckd_name = "osc_extent_kmem",
- .ckd_size = sizeof (struct osc_extent)
+ .ckd_size = sizeof(struct osc_extent)
},
{
.ckd_cache = &osc_quota_kmem,
@@ -132,6 +132,7 @@ static void osc_key_fini(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct osc_thread_info *info = data;
+
OBD_SLAB_FREE_PTR(info, osc_thread_kmem);
}
@@ -156,6 +157,7 @@ static void osc_session_fini(const struct lu_context *ctx,
struct lu_context_key *key, void *data)
{
struct osc_session *info = data;
+
OBD_SLAB_FREE_PTR(info, osc_session_kmem);
}
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index efc5db47c260..f67a70083621 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -97,7 +97,7 @@ void osc_update_next_shrink(struct client_obd *cli);
/*
* cl integration.
*/
-#include <cl_object.h>
+#include "../include/cl_object.h"
extern struct ptlrpc_request_set *PTLRPCD_SET;
@@ -112,7 +112,7 @@ int osc_cancel_base(struct lustre_handle *lockh, __u32 mode);
int osc_match_base(struct obd_export *exp, struct ldlm_res_id *res_id,
__u32 type, ldlm_policy_data_t *policy, __u32 mode,
- int *flags, void *data, struct lustre_handle *lockh,
+ __u64 *flags, void *data, struct lustre_handle *lockh,
int unref);
int osc_setattr_async_base(struct obd_export *exp, struct obd_info *oinfo,
@@ -136,7 +136,7 @@ extern spinlock_t osc_ast_guard;
int osc_cleanup(struct obd_device *obd);
int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int lproc_osc_attach_seqstat(struct obd_device *dev);
void lprocfs_osc_init_vars(struct lprocfs_static_vars *lvars);
#else
diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c
index 09e06eb08530..54fe836a64cd 100644
--- a/drivers/staging/lustre/lustre/osc/osc_io.c
+++ b/drivers/staging/lustre/lustre/osc/osc_io.c
@@ -204,7 +204,7 @@ static void osc_page_touch_at(const struct lu_env *env,
*
* here
*/
- CDEBUG(D_INODE, "stripe KMS %sincreasing "LPU64"->"LPU64" "LPU64"\n",
+ CDEBUG(D_INODE, "stripe KMS %sincreasing %llu->%llu %llu\n",
kms > loi->loi_kms ? "" : "not ", loi->loi_kms, kms,
loi->loi_lvb.lvb_size);
@@ -355,7 +355,7 @@ static int trunc_check_cb(const struct lu_env *env, struct cl_io *io,
if (oap->oap_cmd & OBD_BRW_WRITE &&
!list_empty(&oap->oap_pending_item))
- CL_PAGE_DEBUG(D_ERROR, env, page, "exists " LPU64 "/%s.\n",
+ CL_PAGE_DEBUG(D_ERROR, env, page, "exists %llu/%s.\n",
start, current->comm);
{
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index a46129bec17a..8138856fda8c 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -40,9 +40,9 @@
#define DEBUG_SUBSYSTEM S_OSC
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
/* fid_build_reg_res_name() */
-#include <lustre_fid.h>
+#include "../include/lustre_fid.h"
#include "osc_cl_internal.h"
@@ -369,20 +369,19 @@ static void osc_lock_lvb_update(const struct lu_env *env, struct osc_lock *olck,
if (size > dlmlock->l_policy_data.l_extent.end)
size = dlmlock->l_policy_data.l_extent.end + 1;
if (size >= oinfo->loi_kms) {
- LDLM_DEBUG(dlmlock, "lock acquired, setting rss="LPU64
- ", kms="LPU64, lvb->lvb_size, size);
+ LDLM_DEBUG(dlmlock, "lock acquired, setting rss=%llu, kms=%llu",
+ lvb->lvb_size, size);
valid |= CAT_KMS;
attr->cat_kms = size;
} else {
- LDLM_DEBUG(dlmlock, "lock acquired, setting rss="
- LPU64"; leaving kms="LPU64", end="LPU64,
+ LDLM_DEBUG(dlmlock, "lock acquired, setting rss=%llu; leaving kms=%llu, end=%llu",
lvb->lvb_size, oinfo->loi_kms,
dlmlock->l_policy_data.l_extent.end);
}
ldlm_lock_allow_match_locked(dlmlock);
} else if (rc == -ENAVAIL && olck->ols_glimpse) {
- CDEBUG(D_INODE, "glimpsed, setting rss="LPU64"; leaving"
- " kms="LPU64"\n", lvb->lvb_size, oinfo->loi_kms);
+ CDEBUG(D_INODE, "glimpsed, setting rss=%llu; leaving kms=%llu\n",
+ lvb->lvb_size, oinfo->loi_kms);
} else
valid = 0;
@@ -1400,7 +1399,7 @@ static int osc_lock_print(const struct lu_env *env, void *cookie,
/*
* XXX print ldlm lock and einfo properly.
*/
- (*p)(env, cookie, "%p %#16llx "LPX64" %d %p ",
+ (*p)(env, cookie, "%p %#16llx %#llx %d %p ",
lock->ols_lock, lock->ols_flags, lock->ols_handle.cookie,
lock->ols_state, lock->ols_owner);
osc_lvb_print(env, cookie, p, &lock->ols_lvb);
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index f9bfdc820125..69000584619d 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -128,8 +128,7 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj)
int osc_lvb_print(const struct lu_env *env, void *cookie,
lu_printer_t p, const struct ost_lvb *lvb)
{
- return (*p)(env, cookie, "size: "LPU64" mtime: "LPU64" atime: "LPU64" "
- "ctime: "LPU64" blocks: "LPU64,
+ return (*p)(env, cookie, "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu",
lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
lvb->lvb_ctime, lvb->lvb_blocks);
}
@@ -142,8 +141,7 @@ static int osc_object_print(const struct lu_env *env, void *cookie,
struct osc_async_rc *ar = &oinfo->loi_ar;
(*p)(env, cookie, "id: "DOSTID" "
- "idx: %d gen: %d kms_valid: %u kms "LPU64" "
- "rc: %d force_sync: %d min_xid: "LPU64" ",
+ "idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ",
POSTID(&oinfo->loi_oi), oinfo->loi_ost_idx,
oinfo->loi_ost_gen, oinfo->loi_kms_valid, oinfo->loi_kms,
ar->ar_rc, ar->ar_force_sync, ar->ar_min_xid);
@@ -179,7 +177,7 @@ int osc_attr_set(const struct lu_env *env, struct cl_object *obj,
if (valid & CAT_BLOCKS)
lvb->lvb_blocks = attr->cat_blocks;
if (valid & CAT_KMS) {
- CDEBUG(D_CACHE, "set kms from "LPU64"to "LPU64"\n",
+ CDEBUG(D_CACHE, "set kms from %llu to %llu\n",
oinfo->loi_kms, (__u64)attr->cat_kms);
loi_kms_set(oinfo, attr->cat_kms);
}
@@ -213,8 +211,8 @@ int osc_object_is_contended(struct osc_object *obj)
{
struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev);
int osc_contention_time = dev->od_contention_time;
- cfs_time_t cur_time = cfs_time_current();
- cfs_time_t retry_time;
+ unsigned long cur_time = cfs_time_current();
+ unsigned long retry_time;
if (OBD_FAIL_CHECK(OBD_FAIL_OSC_OBJECT_CONTENTION))
return 1;
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 96cb6e2b9c4e..fcd079b1af01 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -70,7 +70,7 @@ static int osc_page_is_dlocked(const struct lu_env *env,
struct lustre_handle *lockh;
ldlm_policy_data_t *policy;
ldlm_mode_t dlmmode;
- int flags;
+ __u64 flags;
might_sleep();
@@ -352,7 +352,7 @@ static const char *osc_list(struct list_head *head)
return list_empty(head) ? "-" : "+";
}
-static inline cfs_time_t osc_submit_duration(struct osc_page *opg)
+static inline unsigned long osc_submit_duration(struct osc_page *opg)
{
if (opg->ops_submit_time == 0)
return 0;
@@ -371,7 +371,7 @@ static int osc_page_print(const struct lu_env *env,
return (*printer)(env, cookie, LUSTRE_OSC_NAME"-page@%p: "
"1< %#x %d %u %s %s > "
- "2< "LPU64" %u %u %#x %#x | %p %p %p > "
+ "2< %llu %u %u %#x %#x | %p %p %p > "
"3< %s %p %d %lu %d > "
"4< %d %d %d %lu %s | %s %s %s %s > "
"5< %s %s %s %s | %d %s | %d %s %s>\n",
diff --git a/drivers/staging/lustre/lustre/osc/osc_quota.c b/drivers/staging/lustre/lustre/osc/osc_quota.c
index 0235fabaaffe..3563809072b4 100644
--- a/drivers/staging/lustre/lustre/osc/osc_quota.c
+++ b/drivers/staging/lustre/lustre/osc/osc_quota.c
@@ -28,7 +28,7 @@
* Code originally extracted from quota directory
*/
-#include <obd_ost.h>
+#include "../include/obd_ost.h"
#include "osc_internal.h"
static inline struct osc_quota_info *osc_oqi_alloc(obd_uid id)
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 294db843012b..fb0d9fb9cebc 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -36,21 +36,21 @@
#define DEBUG_SUBSYSTEM S_OSC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <lustre_dlm.h>
-#include <lustre_net.h>
-#include <lustre/lustre_user.h>
-#include <obd_cksum.h>
-#include <obd_ost.h>
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre/lustre_user.h"
+#include "../include/obd_cksum.h"
+#include "../include/obd_ost.h"
-#include <lustre_ha.h>
-#include <lprocfs_status.h>
-#include <lustre_log.h>
-#include <lustre_debug.h>
-#include <lustre_param.h>
-#include <lustre_fid.h>
+#include "../include/lustre_ha.h"
+#include "../include/lprocfs_status.h"
+#include "../include/lustre_log.h"
+#include "../include/lustre_debug.h"
+#include "../include/lustre_param.h"
+#include "../include/lustre_fid.h"
#include "osc_internal.h"
#include "osc_cl_internal.h"
@@ -483,7 +483,7 @@ int osc_real_create(struct obd_export *exp, struct obdo *oa,
}
}
- CDEBUG(D_HA, "transno: "LPD64"\n",
+ CDEBUG(D_HA, "transno: %lld\n",
lustre_msg_get_transno(req->rq_repmsg));
out_req:
ptlrpc_req_finished(req);
@@ -635,7 +635,7 @@ static int osc_sync(const struct lu_env *env, struct obd_export *exp,
* locks added to @cancels list. */
static int osc_resource_get_unused(struct obd_export *exp, struct obdo *oa,
struct list_head *cancels,
- ldlm_mode_t mode, int lock_flags)
+ ldlm_mode_t mode, __u64 lock_flags)
{
struct ldlm_namespace *ns = exp->exp_obd->obd_namespace;
struct ldlm_res_id res_id;
@@ -836,7 +836,7 @@ static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
oa->o_dropped = cli->cl_lost_grant;
cli->cl_lost_grant = 0;
client_obd_list_unlock(&cli->cl_loi_list_lock);
- CDEBUG(D_CACHE,"dirty: "LPU64" undirty: %u dropped %u grant: "LPU64"\n",
+ CDEBUG(D_CACHE,"dirty: %llu undirty: %u dropped %u grant: %llu\n",
oa->o_dirty, oa->o_undirty, oa->o_dropped, oa->o_grant);
}
@@ -859,7 +859,7 @@ static void __osc_update_grant(struct client_obd *cli, obd_size grant)
static void osc_update_grant(struct client_obd *cli, struct ost_body *body)
{
if (body->oa.o_valid & OBD_MD_FLGRANT) {
- CDEBUG(D_CACHE, "got "LPU64" extra grant\n", body->oa.o_grant);
+ CDEBUG(D_CACHE, "got %llu extra grant\n", body->oa.o_grant);
__osc_update_grant(cli, body->oa.o_grant);
}
}
@@ -966,8 +966,8 @@ int osc_shrink_grant_to_target(struct client_obd *cli, __u64 target_bytes)
static int osc_should_shrink_grant(struct client_obd *client)
{
- cfs_time_t time = cfs_time_current();
- cfs_time_t next_shrink = client->cl_next_shrink_grant;
+ unsigned long time = cfs_time_current();
+ unsigned long next_shrink = client->cl_next_shrink_grant;
if ((client->cl_import->imp_connect_data.ocd_connect_flags &
OBD_CONNECT_GRANT_SHRINK) == 0)
@@ -1313,11 +1313,11 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa,
ergo(i > 0 && i < page_count - 1,
poff == 0 && pg->count == PAGE_CACHE_SIZE) &&
ergo(i == page_count - 1, poff == 0)),
- "i: %d/%d pg: %p off: "LPU64", count: %u\n",
+ "i: %d/%d pg: %p off: %llu, count: %u\n",
i, page_count, pg, pg->off, pg->count);
LASSERTF(i == 0 || pg->off > pg_prev->off,
- "i %d p_c %u pg %p [pri %lu ind %lu] off "LPU64
- " prev_pg %p [pri %lu ind %lu] off "LPU64"\n",
+ "i %d p_c %u pg %p [pri %lu ind %lu] off %llu"
+ " prev_pg %p [pri %lu ind %lu] off %llu\n",
i, page_count,
pg->pg, page_private(pg->pg), pg->pg->index, pg->off,
pg_prev->pg, page_private(pg_prev->pg),
@@ -1452,7 +1452,7 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer,
"likely false positive due to mmap IO (bug 11742)";
LCONSOLE_ERROR_MSG(0x132, "BAD WRITE CHECKSUM: %s: from %s inode "DFID
- " object "DOSTID" extent ["LPU64"-"LPU64"]\n",
+ " object "DOSTID" extent [%llu-%llu]\n",
msg, libcfs_nid2str(peer->nid),
oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : (__u64)0,
oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0,
@@ -1492,7 +1492,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
body->oa.o_valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) {
unsigned int qid[MAXQUOTAS] = { body->oa.o_uid, body->oa.o_gid };
- CDEBUG(D_QUOTA, "setdq for [%u %u] with valid "LPX64", flags %x\n",
+ CDEBUG(D_QUOTA, "setdq for [%u %u] with valid %#llx, flags %x\n",
body->oa.o_uid, body->oa.o_gid, body->oa.o_valid,
body->oa.o_flags);
osc_quota_setdq(cli, qid, body->oa.o_valid, body->oa.o_flags);
@@ -1570,15 +1570,10 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
router = libcfs_nid2str(req->rq_bulk->bd_sender);
}
- if (server_cksum == ~0 && rc > 0) {
- CERROR("Protocol error: server %s set the 'checksum' "
- "bit, but didn't send a checksum. Not fatal, "
- "but please notify on http://bugs.whamcloud.com/\n",
- libcfs_nid2str(peer->nid));
- } else if (server_cksum != client_cksum) {
+ if (server_cksum != client_cksum) {
LCONSOLE_ERROR_MSG(0x133, "%s: BAD READ CHECKSUM: from "
"%s%s%s inode "DFID" object "DOSTID
- " extent ["LPU64"-"LPU64"]\n",
+ " extent [%llu-%llu]\n",
req->rq_import->imp_obd->obd_name,
libcfs_nid2str(peer->nid),
via, router,
@@ -1644,7 +1639,7 @@ restart_bulk:
if (resends) {
req->rq_generation_set = 1;
req->rq_import_generation = generation;
- req->rq_sent = cfs_time_current_sec() + resends;
+ req->rq_sent = get_seconds() + resends;
}
rc = ptlrpc_queue_wait(req);
@@ -1727,9 +1722,9 @@ static int osc_brw_redo_request(struct ptlrpc_request *request,
/* cap resend delay to the current request timeout, this is similar to
* what ptlrpc does (see after_reply()) */
if (aa->aa_resends > new_req->rq_timeout)
- new_req->rq_sent = cfs_time_current_sec() + new_req->rq_timeout;
+ new_req->rq_sent = get_seconds() + new_req->rq_timeout;
else
- new_req->rq_sent = cfs_time_current_sec() + aa->aa_resends;
+ new_req->rq_sent = get_seconds() + aa->aa_resends;
new_req->rq_generation_set = 1;
new_req->rq_import_generation = request->rq_import_generation;
@@ -1935,8 +1930,7 @@ static int brw_interpret(const struct lu_env *env,
client_should_resend(aa->aa_resends, aa->aa_cli)) {
rc = osc_brw_redo_request(req, aa, rc);
} else {
- CERROR("%s: too many resent retries for object: "
- ""LPU64":"LPU64", rc = %d.\n",
+ CERROR("%s: too many resent retries for object: %llu:%llu, rc = %d.\n",
req->rq_import->imp_obd->obd_name,
POSTID(&aa->aa_oa->o_oi), rc);
}
@@ -2326,7 +2320,7 @@ static int osc_enqueue_fini(struct ptlrpc_request *req, struct ost_lvb *lvb,
if ((intent != 0 && rc == ELDLM_LOCK_ABORTED && agl == 0) ||
(rc == 0)) {
*flags |= LDLM_FL_LVB_READY;
- CDEBUG(D_INODE,"got kms "LPU64" blocks "LPU64" mtime "LPU64"\n",
+ CDEBUG(D_INODE,"got kms %llu blocks %llu mtime %llu\n",
lvb->lvb_size, lvb->lvb_blocks, lvb->lvb_mtime);
}
@@ -2398,7 +2392,7 @@ static int osc_enqueue_interpret(const struct lu_env *env,
}
void osc_update_enqueue(struct lustre_handle *lov_lockhp,
- struct lov_oinfo *loi, int flags,
+ struct lov_oinfo *loi, __u64 flags,
struct ost_lvb *lvb, __u32 mode, int rc)
{
struct ldlm_lock *lock = ldlm_handle2lock(lov_lockhp);
@@ -2414,12 +2408,11 @@ void osc_update_enqueue(struct lustre_handle *lov_lockhp,
if (tmp > lock->l_policy_data.l_extent.end)
tmp = lock->l_policy_data.l_extent.end + 1;
if (tmp >= loi->loi_kms) {
- LDLM_DEBUG(lock, "lock acquired, setting rss="LPU64
- ", kms="LPU64, loi->loi_lvb.lvb_size, tmp);
+ LDLM_DEBUG(lock, "lock acquired, setting rss=%llu, kms=%llu",
+ loi->loi_lvb.lvb_size, tmp);
loi_kms_set(loi, tmp);
} else {
- LDLM_DEBUG(lock, "lock acquired, setting rss="
- LPU64"; leaving kms="LPU64", end="LPU64,
+ LDLM_DEBUG(lock, "lock acquired, setting rss=%llu; leaving kms=%llu, end=%llu",
loi->loi_lvb.lvb_size, loi->loi_kms,
lock->l_policy_data.l_extent.end);
}
@@ -2428,8 +2421,8 @@ void osc_update_enqueue(struct lustre_handle *lov_lockhp,
LASSERT(lock != NULL);
loi->loi_lvb = *lvb;
ldlm_lock_allow_match(lock);
- CDEBUG(D_INODE, "glimpsed, setting rss="LPU64"; leaving"
- " kms="LPU64"\n", loi->loi_lvb.lvb_size, loi->loi_kms);
+ CDEBUG(D_INODE, "glimpsed, setting rss=%llu; leaving kms=%llu\n",
+ loi->loi_lvb.lvb_size, loi->loi_kms);
rc = ELDLM_OK;
}
@@ -2462,7 +2455,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
struct obd_device *obd = exp->exp_obd;
struct ptlrpc_request *req = NULL;
int intent = *flags & LDLM_FL_HAS_INTENT;
- int match_lvb = (agl != 0 ? 0 : LDLM_FL_LVB_READY);
+ __u64 match_lvb = (agl != 0 ? 0 : LDLM_FL_LVB_READY);
ldlm_mode_t mode;
int rc;
@@ -2613,11 +2606,11 @@ static int osc_enqueue(struct obd_export *exp, struct obd_info *oinfo,
int osc_match_base(struct obd_export *exp, struct ldlm_res_id *res_id,
__u32 type, ldlm_policy_data_t *policy, __u32 mode,
- int *flags, void *data, struct lustre_handle *lockh,
+ __u64 *flags, void *data, struct lustre_handle *lockh,
int unref)
{
struct obd_device *obd = exp->exp_obd;
- int lflags = *flags;
+ __u64 lflags = *flags;
ldlm_mode_t rc;
if (OBD_FAIL_CHECK(OBD_FAIL_OSC_MATCH))
@@ -3267,7 +3260,7 @@ static int osc_reconnect(const struct lu_env *env,
cli->cl_lost_grant = 0;
client_obd_list_unlock(&cli->cl_loi_list_lock);
- CDEBUG(D_RPCTRACE, "ocd_connect_flags: "LPX64" ocd_version: %d"
+ CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d"
" ocd_grant: %d, lost: %ld.\n", data->ocd_connect_flags,
data->ocd_version, data->ocd_grant, lost_grant);
}
@@ -3428,7 +3421,7 @@ static int brw_queue_work(const struct lu_env *env, void *data)
int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
{
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
struct client_obd *cli = &obd->u.cli;
void *handler;
int rc;
@@ -3552,7 +3545,7 @@ int osc_cleanup(struct obd_device *obd)
int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg)
{
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc = 0;
lprocfs_osc_init_vars(&lvars);
@@ -3619,7 +3612,7 @@ extern struct lock_class_key osc_ast_guard_class;
int __init osc_init(void)
{
- struct lprocfs_static_vars lvars = { 0 };
+ struct lprocfs_static_vars lvars = { NULL };
int rc;
/* print an address of _any_ initialized kernel symbol from this
diff --git a/drivers/staging/lustre/lustre/ptlrpc/Makefile b/drivers/staging/lustre/lustre/ptlrpc/Makefile
index 1c338aaf18a6..fb50cd4c65b6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/Makefile
+++ b/drivers/staging/lustre/lustre/ptlrpc/Makefile
@@ -18,8 +18,3 @@ ptlrpc_objs += sec_null.o sec_plain.o nrs.o nrs_fifo.o
ptlrpc-y := $(ldlm_objs) $(ptlrpc_objs)
ptlrpc-$(CONFIG_PROC_FS) += sec_lproc.o
ptlrpc-$(CONFIG_LUSTRE_TRANSLATE_ERRNOS) += errno.o
-
-obj-$(CONFIG_PTLRPC_GSS) += gss/
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 7246e8ce9c19..4146e8b29a6d 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -38,12 +38,12 @@
#define DEBUG_SUBSYSTEM S_RPC
-#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 "../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 "ptlrpc_internal.h"
@@ -283,7 +283,7 @@ static void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req,
{
unsigned int nl, oldnl;
struct imp_at *at;
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
LASSERT(req->rq_import);
at = &req->rq_import->imp_at;
@@ -367,13 +367,13 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req)
olddl = req->rq_deadline;
/* server assumes it now has rq_timeout from when it sent the
* early reply, so client should give it at least that long. */
- req->rq_deadline = cfs_time_current_sec() + req->rq_timeout +
+ req->rq_deadline = get_seconds() + req->rq_timeout +
ptlrpc_at_get_net_latency(req);
DEBUG_REQ(D_ADAPTTO, req,
"Early reply #%d, new deadline in "CFS_DURATION_T"s "
"("CFS_DURATION_T"s)", req->rq_early_count,
- cfs_time_sub(req->rq_deadline, cfs_time_current_sec()),
+ cfs_time_sub(req->rq_deadline, get_seconds()),
cfs_time_sub(req->rq_deadline, olddl));
return rc;
@@ -1181,7 +1181,7 @@ static void ptlrpc_save_versions(struct ptlrpc_request *req)
LASSERT(versions);
lustre_msg_set_versions(reqmsg, versions);
- CDEBUG(D_INFO, "Client save versions ["LPX64"/"LPX64"]\n",
+ CDEBUG(D_INFO, "Client save versions [%#llx/%#llx]\n",
versions[0], versions[1]);
}
@@ -1202,7 +1202,7 @@ static int after_reply(struct ptlrpc_request *req)
LASSERT(obd != NULL);
/* repbuf must be unlinked */
- LASSERT(!req->rq_receiving_reply && !req->rq_must_unlink);
+ LASSERT(!req->rq_receiving_reply && !req->rq_reply_unlink);
if (req->rq_reply_truncate) {
if (ptlrpc_no_resend(req)) {
@@ -1248,7 +1248,7 @@ static int after_reply(struct ptlrpc_request *req)
/* retry indefinitely on EINPROGRESS */
if (lustre_msg_get_status(req->rq_repmsg) == -EINPROGRESS &&
ptlrpc_no_resend(req) == 0 && !req->rq_no_retry_einprogress) {
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
DEBUG_REQ(D_RPCTRACE, req, "Resending request on EINPROGRESS");
req->rq_resend = 1;
@@ -1395,7 +1395,7 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
int rc;
LASSERT(req->rq_phase == RQ_PHASE_NEW);
- if (req->rq_sent && (req->rq_sent > cfs_time_current_sec()) &&
+ if (req->rq_sent && (req->rq_sent > get_seconds()) &&
(!req->rq_generation_set ||
req->rq_import_generation == imp->imp_generation))
return 0;
@@ -1451,7 +1451,7 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
}
CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc"
- " %s:%s:%d:"LPU64":%s:%d\n", current_comm(),
+ " %s:%s:%d:%llu:%s:%d\n", current_comm(),
imp->imp_obd->obd_uuid.uuid,
lustre_msg_get_status(req->rq_reqmsg), req->rq_xid,
libcfs_nid2str(imp->imp_connection->c_peer.nid),
@@ -1496,6 +1496,8 @@ static inline int ptlrpc_set_producer(struct ptlrpc_request_set *set)
* and no more replies are expected.
* (it is possible to get less replies than requests sent e.g. due to timed out
* requests or requests that we had trouble to send out)
+ *
+ * NOTE: This function contains a potential schedule point (cond_resched()).
*/
int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
{
@@ -1513,6 +1515,14 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
int unregistered = 0;
int rc = 0;
+ /* This schedule point is mainly for the ptlrpcd caller of this
+ * function. Most ptlrpc sets are not long-lived and unbounded
+ * in length, but at the least the set used by the ptlrpcd is.
+ * Since the processing time is unbounded, we need to insert an
+ * explicit schedule point to make the thread well-behaved.
+ */
+ cond_resched();
+
if (req->rq_phase == RQ_PHASE_NEW &&
ptlrpc_send_new_req(req)) {
force_timer_recalc = 1;
@@ -1524,7 +1534,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
/* delayed resend - skip */
if (req->rq_phase == RQ_PHASE_RPC && req->rq_resend &&
- req->rq_sent > cfs_time_current_sec())
+ req->rq_sent > get_seconds())
continue;
if (!(req->rq_phase == RQ_PHASE_RPC ||
@@ -1688,9 +1698,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
/* ensure previous bulk fails */
old_xid = req->rq_xid;
req->rq_xid = ptlrpc_next_xid();
- CDEBUG(D_HA, "resend bulk "
- "old x"LPU64
- " new x"LPU64"\n",
+ CDEBUG(D_HA, "resend bulk old x%llu new x%llu\n",
old_xid, req->rq_xid);
}
}
@@ -1821,7 +1829,7 @@ interpret:
CDEBUG(req->rq_reqmsg != NULL ? D_RPCTRACE : 0,
"Completed RPC pname:cluuid:pid:xid:nid:"
- "opc %s:%s:%d:"LPU64":%s:%d\n",
+ "opc %s:%s:%d:%llu:%s:%d\n",
current_comm(), imp->imp_obd->obd_uuid.uuid,
lustre_msg_get_status(req->rq_reqmsg), req->rq_xid,
libcfs_nid2str(imp->imp_connection->c_peer.nid),
@@ -1884,7 +1892,7 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink)
"/real "CFS_DURATION_T"]",
req->rq_net_err ? "failed due to network error" :
((req->rq_real_sent == 0 ||
- cfs_time_before(req->rq_real_sent, req->rq_sent) ||
+ time_before((unsigned long)req->rq_real_sent, (unsigned long)req->rq_sent) ||
cfs_time_aftereq(req->rq_real_sent, req->rq_deadline)) ?
"timed out for sent delay" : "timed out for slow reply"),
req->rq_sent, req->rq_real_sent);
@@ -1945,7 +1953,7 @@ int ptlrpc_expired_set(void *data)
{
struct ptlrpc_request_set *set = data;
struct list_head *tmp;
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
LASSERT(set != NULL);
@@ -2028,7 +2036,7 @@ EXPORT_SYMBOL(ptlrpc_interrupted_set);
int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set)
{
struct list_head *tmp;
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
int timeout = 0;
struct ptlrpc_request *req;
int deadline;
@@ -2346,7 +2354,7 @@ int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
*/
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
async && request->rq_reply_deadline == 0)
- request->rq_reply_deadline = cfs_time_current_sec()+LONG_UNLINK;
+ request->rq_reply_deadline = get_seconds()+LONG_UNLINK;
/*
* Nothing left to do.
@@ -2396,9 +2404,10 @@ int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
}
LASSERT(rc == -ETIMEDOUT);
- DEBUG_REQ(D_WARNING, request, "Unexpectedly long timeout "
- "rvcng=%d unlnk=%d", request->rq_receiving_reply,
- request->rq_must_unlink);
+ DEBUG_REQ(D_WARNING, request,
+ "Unexpectedly long timeout rvcng=%d unlnk=%d/%d",
+ request->rq_receiving_reply,
+ request->rq_req_unlink, request->rq_reply_unlink);
}
return 0;
}
@@ -2456,11 +2465,11 @@ void ptlrpc_free_committed(struct obd_import *imp)
if (imp->imp_peer_committed_transno == imp->imp_last_transno_checked &&
imp->imp_generation == imp->imp_last_generation_checked) {
- CDEBUG(D_INFO, "%s: skip recheck: last_committed "LPU64"\n",
+ CDEBUG(D_INFO, "%s: skip recheck: last_committed %llu\n",
imp->imp_obd->obd_name, imp->imp_peer_committed_transno);
return;
}
- CDEBUG(D_RPCTRACE, "%s: committing for last_committed "LPU64" gen %d\n",
+ CDEBUG(D_RPCTRACE, "%s: committing for last_committed %llu gen %d\n",
imp->imp_obd->obd_name, imp->imp_peer_committed_transno,
imp->imp_generation);
@@ -2498,7 +2507,7 @@ void ptlrpc_free_committed(struct obd_import *imp)
continue;
}
- DEBUG_REQ(D_INFO, req, "commit (last_committed "LPU64")",
+ DEBUG_REQ(D_INFO, req, "commit (last_committed %llu)",
imp->imp_peer_committed_transno);
free_req:
ptlrpc_free_request(req);
@@ -2530,10 +2539,19 @@ EXPORT_SYMBOL(ptlrpc_cleanup_client);
void ptlrpc_resend_req(struct ptlrpc_request *req)
{
DEBUG_REQ(D_HA, req, "going to resend");
+ spin_lock(&req->rq_lock);
+
+ /* Request got reply but linked to the import list still.
+ Let ptlrpc_check_set() to process it. */
+ if (ptlrpc_client_replied(req)) {
+ spin_unlock(&req->rq_lock);
+ DEBUG_REQ(D_HA, req, "it has reply, so skip it");
+ return;
+ }
+
lustre_msg_set_handle(req->rq_reqmsg, &(struct lustre_handle){ 0 });
req->rq_status = -EAGAIN;
- spin_lock(&req->rq_lock);
req->rq_resend = 1;
req->rq_net_err = 0;
req->rq_timedout = 0;
@@ -2542,7 +2560,7 @@ void ptlrpc_resend_req(struct ptlrpc_request *req)
/* ensure previous bulk fails */
req->rq_xid = ptlrpc_next_xid();
- CDEBUG(D_HA, "resend bulk old x"LPU64" new x"LPU64"\n",
+ CDEBUG(D_HA, "resend bulk old x%llu new x%llu\n",
old_xid, req->rq_xid);
}
ptlrpc_client_wake_req(req);
@@ -2705,7 +2723,7 @@ static int ptlrpc_replay_interpret(const struct lu_env *env,
LASSERTF(lustre_msg_get_transno(req->rq_reqmsg) ==
lustre_msg_get_transno(req->rq_repmsg) ||
lustre_msg_get_transno(req->rq_repmsg) == 0,
- LPX64"/"LPX64"\n",
+ "%#llx/%#llx\n",
lustre_msg_get_transno(req->rq_reqmsg),
lustre_msg_get_transno(req->rq_repmsg));
}
@@ -2721,8 +2739,8 @@ static int ptlrpc_replay_interpret(const struct lu_env *env,
/* transaction number shouldn't be bigger than the latest replayed */
if (req->rq_transno > lustre_msg_get_transno(req->rq_reqmsg)) {
DEBUG_REQ(D_ERROR, req,
- "Reported transno "LPU64" is bigger than the "
- "replayed one: "LPU64, req->rq_transno,
+ "Reported transno %llu is bigger than the replayed one: %llu",
+ req->rq_transno,
lustre_msg_get_transno(req->rq_reqmsg));
GOTO(out, rc = -EINVAL);
}
@@ -2907,7 +2925,7 @@ static spinlock_t ptlrpc_last_xid_lock;
#define YEAR_2004 (1ULL << 30)
void ptlrpc_init_xid(void)
{
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
spin_lock_init(&ptlrpc_last_xid_lock);
if (now < YEAR_2004) {
@@ -2996,7 +3014,7 @@ static void ptlrpcd_add_work_req(struct ptlrpc_request *req)
{
/* re-initialize the req */
req->rq_timeout = obd_timeout;
- req->rq_sent = cfs_time_current_sec();
+ req->rq_sent = get_seconds();
req->rq_deadline = req->rq_sent + req->rq_timeout;
req->rq_reply_deadline = req->rq_deadline;
req->rq_phase = RQ_PHASE_INTERPRET;
@@ -3062,7 +3080,7 @@ void *ptlrpcd_alloc_work(struct obd_import *imp,
req->rq_interpret_reply = work_interpreter;
/* don't want reply */
req->rq_receiving_reply = 0;
- req->rq_must_unlink = 0;
+ req->rq_req_unlink = req->rq_reply_unlink = 0;
req->rq_no_delay = req->rq_no_resend = 1;
req->rq_pill.rc_fmt = (void *)&worker_format;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/connection.c b/drivers/staging/lustre/lustre/ptlrpc/connection.c
index 6756356faac1..adff1ab4f5a4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/connection.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/connection.c
@@ -35,9 +35,9 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../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 1c1006333960..73f8374f190e 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 <linux/libcfs/libcfs.h>
-#include <lustre/lustre_errno.h>
+#include "../../include/linux/libcfs/libcfs.h"
+#include "../include/lustre/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 aa85239f6cd5..c3ec21d5d29f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -36,14 +36,14 @@
#define DEBUG_SUBSYSTEM S_RPC
-# include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
# ifdef __mips64__
# include <linux/kernel.h>
# endif
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_sec.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre_sec.h"
#include "ptlrpc_internal.h"
lnet_handle_eq_t ptlrpc_eq_h;
@@ -63,19 +63,20 @@ void request_out_callback(lnet_event_t *ev)
DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status);
sptlrpc_request_out_callback(req);
- req->rq_real_sent = cfs_time_current_sec();
+ spin_lock(&req->rq_lock);
+ req->rq_real_sent = get_seconds();
+ if (ev->unlinked)
+ req->rq_req_unlink = 0;
if (ev->type == LNET_EVENT_UNLINK || ev->status != 0) {
/* Failed send: make it seem like the reply timed out, just
* like failing sends in client.c does currently... */
- spin_lock(&req->rq_lock);
req->rq_net_err = 1;
- spin_unlock(&req->rq_lock);
-
ptlrpc_client_wake_req(req);
}
+ spin_unlock(&req->rq_lock);
ptlrpc_req_finished(req);
}
@@ -102,7 +103,7 @@ void reply_in_callback(lnet_event_t *ev)
req->rq_receiving_reply = 0;
req->rq_early = 0;
if (ev->unlinked)
- req->rq_must_unlink = 0;
+ req->rq_reply_unlink = 0;
if (ev->status)
goto out_wake;
@@ -145,6 +146,8 @@ void reply_in_callback(lnet_event_t *ev)
/* Real reply */
req->rq_rep_swab_mask = 0;
req->rq_replied = 1;
+ /* Got reply, no resend required */
+ req->rq_resend = 0;
req->rq_reply_off = ev->offset;
req->rq_nob_received = ev->mlength;
/* LNetMDUnlink can't be called under the LNET_LOCK,
@@ -155,7 +158,7 @@ void reply_in_callback(lnet_event_t *ev)
ev->mlength, ev->offset, req->rq_replen);
}
- req->rq_import->imp_last_reply_time = cfs_time_current_sec();
+ req->rq_import->imp_last_reply_time = get_seconds();
out_wake:
/* NB don't unlock till after wakeup; req can disappear under us
@@ -307,7 +310,7 @@ void request_in_callback(lnet_event_t *ev)
/* We moaned above already... */
return;
}
- req = ptlrpc_request_cache_alloc(ALLOC_ATOMIC_TRY);
+ req = ptlrpc_request_cache_alloc(GFP_ATOMIC);
if (req == NULL) {
CERROR("Can't allocate incoming request descriptor: "
"Dropping %s RPC from %s\n",
@@ -334,7 +337,7 @@ void request_in_callback(lnet_event_t *ev)
INIT_LIST_HEAD(&req->rq_exp_list);
atomic_set(&req->rq_refcount, 1);
if (ev->type == LNET_EVENT_PUT)
- CDEBUG(D_INFO, "incoming req@%p x"LPU64" msgsize %u\n",
+ CDEBUG(D_INFO, "incoming req@%p x%llu msgsize %u\n",
req, req->rq_xid, ev->mlength);
CDEBUG(D_RPCTRACE, "peer: %s\n", libcfs_id2str(req->rq_peer));
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/Makefile b/drivers/staging/lustre/lustre/ptlrpc/gss/Makefile
deleted file mode 100644
index 8cdfbeed64e6..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-obj-$(CONFIG_LUSTRE_FS) := ptlrpc_gss.o
-
-ptlrpc_gss-y := sec_gss.o gss_bulk.o gss_cli_upcall.o gss_svc_upcall.o \
- gss_rawobj.o lproc_gss.o gss_generic_token.o \
- gss_mech_switch.o gss_krb5_mech.o
-
-
-ccflags-y := -I$(src)/../include
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_api.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_api.h
deleted file mode 100644
index 0e9f6c472a37..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_api.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * Somewhat simplified version of the gss api.
- *
- * Dug Song <dugsong@monkey.org>
- * Andy Adamson <andros@umich.edu>
- * Bruce Fields <bfields@umich.edu>
- * Copyright (c) 2000 The Regents of the University of Michigan
- *
- */
-
-#ifndef __PTLRPC_GSS_GSS_API_H_
-#define __PTLRPC_GSS_GSS_API_H_
-
-struct gss_api_mech;
-
-/* The mechanism-independent gss-api context: */
-struct gss_ctx {
- struct gss_api_mech *mech_type;
- void *internal_ctx_id;
-};
-
-#define GSS_C_NO_BUFFER ((rawobj_t) 0)
-#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
-#define GSS_C_NULL_OID ((rawobj_t) 0)
-
-/*
- * gss-api prototypes; note that these are somewhat simplified versions of
- * the prototypes specified in RFC 2744.
- */
-__u32 lgss_import_sec_context(
- rawobj_t *input_token,
- struct gss_api_mech *mech,
- struct gss_ctx **ctx);
-__u32 lgss_copy_reverse_context(
- struct gss_ctx *ctx,
- struct gss_ctx **ctx_new);
-__u32 lgss_inquire_context(
- struct gss_ctx *ctx,
- unsigned long *endtime);
-__u32 lgss_get_mic(
- struct gss_ctx *ctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token);
-__u32 lgss_verify_mic(
- struct gss_ctx *ctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token);
-__u32 lgss_wrap(
- struct gss_ctx *ctx,
- rawobj_t *gsshdr,
- rawobj_t *msg,
- int msg_buflen,
- rawobj_t *out_token);
-__u32 lgss_unwrap(
- struct gss_ctx *ctx,
- rawobj_t *gsshdr,
- rawobj_t *token,
- rawobj_t *out_msg);
-__u32 lgss_prep_bulk(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc);
-__u32 lgss_wrap_bulk(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob);
-__u32 lgss_unwrap_bulk(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob);
-__u32 lgss_delete_sec_context(
- struct gss_ctx **ctx);
-int lgss_display(
- struct gss_ctx *ctx,
- char *buf,
- int bufsize);
-
-struct subflavor_desc {
- __u32 sf_subflavor;
- __u32 sf_qop;
- __u32 sf_service;
- char *sf_name;
-};
-
-/* Each mechanism is described by the following struct: */
-struct gss_api_mech {
- struct list_head gm_list;
- struct module *gm_owner;
- char *gm_name;
- rawobj_t gm_oid;
- atomic_t gm_count;
- struct gss_api_ops *gm_ops;
- int gm_sf_num;
- struct subflavor_desc *gm_sfs;
-};
-
-/* and must provide the following operations: */
-struct gss_api_ops {
- __u32 (*gss_import_sec_context)(
- rawobj_t *input_token,
- struct gss_ctx *ctx);
- __u32 (*gss_copy_reverse_context)(
- struct gss_ctx *ctx,
- struct gss_ctx *ctx_new);
- __u32 (*gss_inquire_context)(
- struct gss_ctx *ctx,
- unsigned long *endtime);
- __u32 (*gss_get_mic)(
- struct gss_ctx *ctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token);
- __u32 (*gss_verify_mic)(
- struct gss_ctx *ctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token);
- __u32 (*gss_wrap)(
- struct gss_ctx *ctx,
- rawobj_t *gsshdr,
- rawobj_t *msg,
- int msg_buflen,
- rawobj_t *out_token);
- __u32 (*gss_unwrap)(
- struct gss_ctx *ctx,
- rawobj_t *gsshdr,
- rawobj_t *token,
- rawobj_t *out_msg);
- __u32 (*gss_prep_bulk)(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc);
- __u32 (*gss_wrap_bulk)(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob);
- __u32 (*gss_unwrap_bulk)(
- struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob);
- void (*gss_delete_sec_context)(
- void *ctx);
- int (*gss_display)(
- struct gss_ctx *ctx,
- char *buf,
- int bufsize);
-};
-
-int lgss_mech_register(struct gss_api_mech *mech);
-void lgss_mech_unregister(struct gss_api_mech *mech);
-
-struct gss_api_mech * lgss_OID_to_mech(rawobj_t *oid);
-struct gss_api_mech * lgss_name_to_mech(char *name);
-struct gss_api_mech * lgss_subflavor_to_mech(__u32 subflavor);
-
-struct gss_api_mech * lgss_mech_get(struct gss_api_mech *mech);
-void lgss_mech_put(struct gss_api_mech *mech);
-
-#endif /* __PTLRPC_GSS_GSS_API_H_ */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h
deleted file mode 100644
index bdfd83880422..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_asn1.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * minimal asn1 for generic encoding/decoding of gss tokens
- *
- * Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
- * lib/gssapi/krb5/gssapiP_krb5.h, and others
- *
- * Copyright (c) 2000 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Andy Adamson <andros@umich.edu>
- */
-
-/*
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-#define SIZEOF_INT 4
-
-/* from gssapi_err_generic.h */
-#define G_BAD_SERVICE_NAME (-2045022976L)
-#define G_BAD_STRING_UID (-2045022975L)
-#define G_NOUSER (-2045022974L)
-#define G_VALIDATE_FAILED (-2045022973L)
-#define G_BUFFER_ALLOC (-2045022972L)
-#define G_BAD_MSG_CTX (-2045022971L)
-#define G_WRONG_SIZE (-2045022970L)
-#define G_BAD_USAGE (-2045022969L)
-#define G_UNKNOWN_QOP (-2045022968L)
-#define G_NO_HOSTNAME (-2045022967L)
-#define G_BAD_HOSTNAME (-2045022966L)
-#define G_WRONG_MECH (-2045022965L)
-#define G_BAD_TOK_HEADER (-2045022964L)
-#define G_BAD_DIRECTION (-2045022963L)
-#define G_TOK_TRUNC (-2045022962L)
-#define G_REFLECT (-2045022961L)
-#define G_WRONG_TOKID (-2045022960L)
-
-#define g_OID_equal(o1, o2) \
- (((o1)->len == (o2)->len) && \
- (memcmp((o1)->data, (o2)->data, (int) (o1)->len) == 0))
-
-__u32 g_verify_token_header(rawobj_t *mech,
- int *body_size,
- unsigned char **buf_in,
- int toksize);
-
-__u32 g_get_mech_oid(rawobj_t *mech,
- rawobj_t *in_buf);
-
-int g_token_size(rawobj_t *mech,
- unsigned int body_size);
-
-void g_make_token_header(rawobj_t *mech,
- int body_size,
- unsigned char **buf);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_bulk.c
deleted file mode 100644
index 93794bd928cb..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_bulk.c
+++ /dev/null
@@ -1,505 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 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.
- *
- * lustre/ptlrpc/gss/gss_bulk.c
- *
- * Author: Eric Mei <eric.mei@sun.com>
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <linux/crypto.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- struct gss_cli_ctx *gctx;
- struct lustre_msg *msg;
- struct ptlrpc_bulk_sec_desc *bsd;
- rawobj_t token;
- __u32 maj;
- int offset;
- int rc;
-
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_read || req->rq_bulk_write);
-
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
- LASSERT(gctx->gc_mechctx);
-
- switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
- case SPTLRPC_SVC_NULL:
- LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
- msg = req->rq_reqbuf;
- offset = msg->lm_bufcount - 1;
- break;
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
- msg = req->rq_reqbuf;
- offset = msg->lm_bufcount - 2;
- break;
- case SPTLRPC_SVC_PRIV:
- LASSERT(req->rq_clrbuf->lm_bufcount >= 2);
- msg = req->rq_clrbuf;
- offset = msg->lm_bufcount - 1;
- break;
- default:
- LBUG();
- }
-
- bsd = lustre_msg_buf(msg, offset, sizeof(*bsd));
- bsd->bsd_version = 0;
- bsd->bsd_flags = 0;
- bsd->bsd_type = SPTLRPC_BULK_DEFAULT;
- bsd->bsd_svc = SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc);
-
- if (bsd->bsd_svc == SPTLRPC_BULK_SVC_NULL)
- return 0;
-
- LASSERT(bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
- bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
-
- if (req->rq_bulk_read) {
- /*
- * bulk read: prepare receiving pages only for privacy mode.
- */
- if (bsd->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
- return gss_cli_prep_bulk(req, desc);
- } else {
- /*
- * bulk write: sign or encrypt bulk pages.
- */
- bsd->bsd_nob = desc->bd_nob;
-
- if (bsd->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
- /* integrity mode */
- token.data = bsd->bsd_data;
- token.len = lustre_msg_buflen(msg, offset) -
- sizeof(*bsd);
-
- maj = lgss_get_mic(gctx->gc_mechctx, 0, NULL,
- desc->bd_iov_count, desc->bd_iov,
- &token);
- if (maj != GSS_S_COMPLETE) {
- CWARN("failed to sign bulk data: %x\n", maj);
- return -EACCES;
- }
- } else {
- /* privacy mode */
- if (desc->bd_iov_count == 0)
- return 0;
-
- rc = sptlrpc_enc_pool_get_pages(desc);
- if (rc) {
- CERROR("bulk write: failed to allocate "
- "encryption pages: %d\n", rc);
- return rc;
- }
-
- token.data = bsd->bsd_data;
- token.len = lustre_msg_buflen(msg, offset) -
- sizeof(*bsd);
-
- maj = lgss_wrap_bulk(gctx->gc_mechctx, desc, &token, 0);
- if (maj != GSS_S_COMPLETE) {
- CWARN("fail to encrypt bulk data: %x\n", maj);
- return -EACCES;
- }
- }
- }
-
- return 0;
-}
-
-int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- struct gss_cli_ctx *gctx;
- struct lustre_msg *rmsg, *vmsg;
- struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
- rawobj_t token;
- __u32 maj;
- int roff, voff;
-
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_read || req->rq_bulk_write);
-
- switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
- case SPTLRPC_SVC_NULL:
- vmsg = req->rq_repdata;
- LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 3);
- voff = vmsg->lm_bufcount - 1;
-
- rmsg = req->rq_reqbuf;
- LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 3);
- roff = rmsg->lm_bufcount - 1; /* last segment */
- break;
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- vmsg = req->rq_repdata;
- LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 4);
- voff = vmsg->lm_bufcount - 2;
-
- rmsg = req->rq_reqbuf;
- LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 4);
- roff = rmsg->lm_bufcount - 2; /* second last segment */
- break;
- case SPTLRPC_SVC_PRIV:
- vmsg = req->rq_repdata;
- LASSERT(vmsg != NULL && vmsg->lm_bufcount >= 2);
- voff = vmsg->lm_bufcount - 1;
-
- rmsg = req->rq_clrbuf;
- LASSERT(rmsg != NULL && rmsg->lm_bufcount >= 2);
- roff = rmsg->lm_bufcount - 1; /* last segment */
- break;
- default:
- LBUG();
- }
-
- bsdr = lustre_msg_buf(rmsg, roff, sizeof(*bsdr));
- bsdv = lustre_msg_buf(vmsg, voff, sizeof(*bsdv));
- LASSERT(bsdr && bsdv);
-
- if (bsdr->bsd_version != bsdv->bsd_version ||
- bsdr->bsd_type != bsdv->bsd_type ||
- bsdr->bsd_svc != bsdv->bsd_svc) {
- CERROR("bulk security descriptor mismatch: "
- "(%u,%u,%u) != (%u,%u,%u)\n",
- bsdr->bsd_version, bsdr->bsd_type, bsdr->bsd_svc,
- bsdv->bsd_version, bsdv->bsd_type, bsdv->bsd_svc);
- return -EPROTO;
- }
-
- LASSERT(bsdv->bsd_svc == SPTLRPC_BULK_SVC_NULL ||
- bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG ||
- bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV);
-
- /*
- * in privacy mode if return success, make sure bd_nob_transferred
- * is the actual size of the clear text, otherwise upper layer
- * may be surprised.
- */
- if (req->rq_bulk_write) {
- if (bsdv->bsd_flags & BSD_FL_ERR) {
- CERROR("server reported bulk i/o failure\n");
- return -EIO;
- }
-
- if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV)
- desc->bd_nob_transferred = desc->bd_nob;
- } else {
- /*
- * bulk read, upon return success, bd_nob_transferred is
- * the size of plain text actually received.
- */
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
- LASSERT(gctx->gc_mechctx);
-
- if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_INTG) {
- int i, nob;
-
- /* fix the actual data size */
- for (i = 0, nob = 0; i < desc->bd_iov_count; i++) {
- if (desc->bd_iov[i].kiov_len + nob >
- desc->bd_nob_transferred) {
- desc->bd_iov[i].kiov_len =
- desc->bd_nob_transferred - nob;
- }
- nob += desc->bd_iov[i].kiov_len;
- }
-
- token.data = bsdv->bsd_data;
- token.len = lustre_msg_buflen(vmsg, voff) -
- sizeof(*bsdv);
-
- maj = lgss_verify_mic(gctx->gc_mechctx, 0, NULL,
- desc->bd_iov_count, desc->bd_iov,
- &token);
- if (maj != GSS_S_COMPLETE) {
- CERROR("failed to verify bulk read: %x\n", maj);
- return -EACCES;
- }
- } else if (bsdv->bsd_svc == SPTLRPC_BULK_SVC_PRIV) {
- desc->bd_nob = bsdv->bsd_nob;
- if (desc->bd_nob == 0)
- return 0;
-
- token.data = bsdv->bsd_data;
- token.len = lustre_msg_buflen(vmsg, voff) -
- sizeof(*bsdr);
-
- maj = lgss_unwrap_bulk(gctx->gc_mechctx, desc,
- &token, 1);
- if (maj != GSS_S_COMPLETE) {
- CERROR("failed to decrypt bulk read: %x\n",
- maj);
- return -EACCES;
- }
-
- desc->bd_nob_transferred = desc->bd_nob;
- }
- }
-
- return 0;
-}
-
-static int gss_prep_bulk(struct ptlrpc_bulk_desc *desc,
- struct gss_ctx *mechctx)
-{
- int rc;
-
- if (desc->bd_iov_count == 0)
- return 0;
-
- rc = sptlrpc_enc_pool_get_pages(desc);
- if (rc)
- return rc;
-
- if (lgss_prep_bulk(mechctx, desc) != GSS_S_COMPLETE)
- return -EACCES;
-
- return 0;
-}
-
-int gss_cli_prep_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- int rc;
-
- LASSERT(req->rq_cli_ctx);
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_read);
-
- if (SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc) != SPTLRPC_BULK_SVC_PRIV)
- return 0;
-
- rc = gss_prep_bulk(desc, ctx2gctx(req->rq_cli_ctx)->gc_mechctx);
- if (rc)
- CERROR("bulk read: failed to prepare encryption "
- "pages: %d\n", rc);
-
- return rc;
-}
-
-int gss_svc_prep_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- struct gss_svc_reqctx *grctx;
- struct ptlrpc_bulk_sec_desc *bsd;
- int rc;
-
- LASSERT(req->rq_svc_ctx);
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_write);
-
- grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- LASSERT(grctx->src_reqbsd);
- LASSERT(grctx->src_repbsd);
- LASSERT(grctx->src_ctx);
- LASSERT(grctx->src_ctx->gsc_mechctx);
-
- bsd = grctx->src_reqbsd;
- if (bsd->bsd_svc != SPTLRPC_BULK_SVC_PRIV)
- return 0;
-
- rc = gss_prep_bulk(desc, grctx->src_ctx->gsc_mechctx);
- if (rc)
- CERROR("bulk write: failed to prepare encryption "
- "pages: %d\n", rc);
-
- return rc;
-}
-
-int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- struct gss_svc_reqctx *grctx;
- struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
- rawobj_t token;
- __u32 maj;
-
- LASSERT(req->rq_svc_ctx);
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_write);
-
- grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-
- LASSERT(grctx->src_reqbsd);
- LASSERT(grctx->src_repbsd);
- LASSERT(grctx->src_ctx);
- LASSERT(grctx->src_ctx->gsc_mechctx);
-
- bsdr = grctx->src_reqbsd;
- bsdv = grctx->src_repbsd;
-
- /* bsdr has been sanity checked during unpacking */
- bsdv->bsd_version = 0;
- bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
- bsdv->bsd_svc = bsdr->bsd_svc;
- bsdv->bsd_flags = 0;
-
- switch (bsdv->bsd_svc) {
- case SPTLRPC_BULK_SVC_INTG:
- token.data = bsdr->bsd_data;
- token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
-
- maj = lgss_verify_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
- desc->bd_iov_count, desc->bd_iov, &token);
- if (maj != GSS_S_COMPLETE) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("failed to verify bulk signature: %x\n", maj);
- return -EACCES;
- }
- break;
- case SPTLRPC_BULK_SVC_PRIV:
- if (bsdr->bsd_nob != desc->bd_nob) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("prepared nob %d doesn't match the actual "
- "nob %d\n", desc->bd_nob, bsdr->bsd_nob);
- return -EPROTO;
- }
-
- if (desc->bd_iov_count == 0) {
- LASSERT(desc->bd_nob == 0);
- break;
- }
-
- token.data = bsdr->bsd_data;
- token.len = grctx->src_reqbsd_size - sizeof(*bsdr);
-
- maj = lgss_unwrap_bulk(grctx->src_ctx->gsc_mechctx,
- desc, &token, 0);
- if (maj != GSS_S_COMPLETE) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("failed decrypt bulk data: %x\n", maj);
- return -EACCES;
- }
- break;
- }
-
- return 0;
-}
-
-int gss_svc_wrap_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc)
-{
- struct gss_svc_reqctx *grctx;
- struct ptlrpc_bulk_sec_desc *bsdr, *bsdv;
- rawobj_t token;
- __u32 maj;
- int rc;
-
- LASSERT(req->rq_svc_ctx);
- LASSERT(req->rq_pack_bulk);
- LASSERT(req->rq_bulk_read);
-
- grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-
- LASSERT(grctx->src_reqbsd);
- LASSERT(grctx->src_repbsd);
- LASSERT(grctx->src_ctx);
- LASSERT(grctx->src_ctx->gsc_mechctx);
-
- bsdr = grctx->src_reqbsd;
- bsdv = grctx->src_repbsd;
-
- /* bsdr has been sanity checked during unpacking */
- bsdv->bsd_version = 0;
- bsdv->bsd_type = SPTLRPC_BULK_DEFAULT;
- bsdv->bsd_svc = bsdr->bsd_svc;
- bsdv->bsd_flags = 0;
-
- switch (bsdv->bsd_svc) {
- case SPTLRPC_BULK_SVC_INTG:
- token.data = bsdv->bsd_data;
- token.len = grctx->src_repbsd_size - sizeof(*bsdv);
-
- maj = lgss_get_mic(grctx->src_ctx->gsc_mechctx, 0, NULL,
- desc->bd_iov_count, desc->bd_iov, &token);
- if (maj != GSS_S_COMPLETE) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("failed to sign bulk data: %x\n", maj);
- return -EACCES;
- }
- break;
- case SPTLRPC_BULK_SVC_PRIV:
- bsdv->bsd_nob = desc->bd_nob;
-
- if (desc->bd_iov_count == 0) {
- LASSERT(desc->bd_nob == 0);
- break;
- }
-
- rc = sptlrpc_enc_pool_get_pages(desc);
- if (rc) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("bulk read: failed to allocate encryption "
- "pages: %d\n", rc);
- return rc;
- }
-
- token.data = bsdv->bsd_data;
- token.len = grctx->src_repbsd_size - sizeof(*bsdv);
-
- maj = lgss_wrap_bulk(grctx->src_ctx->gsc_mechctx,
- desc, &token, 1);
- if (maj != GSS_S_COMPLETE) {
- bsdv->bsd_flags |= BSD_FL_ERR;
- CERROR("failed to encrypt bulk data: %x\n", maj);
- return -EACCES;
- }
- break;
- }
-
- return 0;
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_cli_upcall.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_cli_upcall.c
deleted file mode 100644
index c279edf5b2a5..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_cli_upcall.c
+++ /dev/null
@@ -1,446 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/ptlrpc/gss/gss_cli_upcall.c
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-/**********************************************
- * gss context init/fini helper *
- **********************************************/
-
-static
-int ctx_init_pack_request(struct obd_import *imp,
- struct ptlrpc_request *req,
- int lustre_srv,
- uid_t uid, gid_t gid,
- long token_size,
- char __user *token)
-{
- struct lustre_msg *msg = req->rq_reqbuf;
- struct gss_sec *gsec;
- struct gss_header *ghdr;
- struct ptlrpc_user_desc *pud;
- __u32 *p, size, offset = 2;
- rawobj_t obj;
-
- LASSERT(msg->lm_bufcount <= 4);
- LASSERT(req->rq_cli_ctx);
- LASSERT(req->rq_cli_ctx->cc_sec);
-
- /* gss hdr */
- ghdr = lustre_msg_buf(msg, 0, sizeof(*ghdr));
- ghdr->gh_version = PTLRPC_GSS_VERSION;
- ghdr->gh_sp = (__u8) imp->imp_sec->ps_part;
- ghdr->gh_flags = 0;
- ghdr->gh_proc = PTLRPC_GSS_PROC_INIT;
- ghdr->gh_seq = 0;
- ghdr->gh_svc = SPTLRPC_SVC_NULL;
- ghdr->gh_handle.len = 0;
-
- /* fix the user desc */
- if (req->rq_pack_udesc) {
- ghdr->gh_flags |= LUSTRE_GSS_PACK_USER;
-
- pud = lustre_msg_buf(msg, offset, sizeof(*pud));
- LASSERT(pud);
- pud->pud_uid = pud->pud_fsuid = uid;
- pud->pud_gid = pud->pud_fsgid = gid;
- pud->pud_cap = 0;
- pud->pud_ngroups = 0;
- offset++;
- }
-
- /* security payload */
- p = lustre_msg_buf(msg, offset, 0);
- size = msg->lm_buflens[offset];
- LASSERT(p);
-
- /* 1. lustre svc type */
- LASSERT(size > 4);
- *p++ = cpu_to_le32(lustre_srv);
- size -= 4;
-
- /* 2. target uuid */
- obj.len = strlen(imp->imp_obd->u.cli.cl_target_uuid.uuid) + 1;
- obj.data = imp->imp_obd->u.cli.cl_target_uuid.uuid;
- if (rawobj_serialize(&obj, &p, &size))
- LBUG();
-
- /* 3. reverse context handle. actually only needed by root user,
- * but we send it anyway. */
- gsec = sec2gsec(req->rq_cli_ctx->cc_sec);
- obj.len = sizeof(gsec->gs_rvs_hdl);
- obj.data = (__u8 *) &gsec->gs_rvs_hdl;
- if (rawobj_serialize(&obj, &p, &size))
- LBUG();
-
- /* 4. now the token */
- LASSERT(size >= (sizeof(__u32) + token_size));
- *p++ = cpu_to_le32(((__u32) token_size));
- if (copy_from_user(p, token, token_size)) {
- CERROR("can't copy token\n");
- return -EFAULT;
- }
- size -= sizeof(__u32) + cfs_size_round4(token_size);
-
- req->rq_reqdata_len = lustre_shrink_msg(req->rq_reqbuf, offset,
- msg->lm_buflens[offset] - size, 0);
- return 0;
-}
-
-static
-int ctx_init_parse_reply(struct lustre_msg *msg, int swabbed,
- char __user *outbuf, long outlen)
-{
- struct gss_rep_header *ghdr;
- __u32 obj_len, round_len;
- __u32 status, effective = 0;
-
- if (msg->lm_bufcount != 3) {
- CERROR("unexpected bufcount %u\n", msg->lm_bufcount);
- return -EPROTO;
- }
-
- ghdr = (struct gss_rep_header *) gss_swab_header(msg, 0, swabbed);
- if (ghdr == NULL) {
- CERROR("unable to extract gss reply header\n");
- return -EPROTO;
- }
-
- if (ghdr->gh_version != PTLRPC_GSS_VERSION) {
- CERROR("invalid gss version %u\n", ghdr->gh_version);
- return -EPROTO;
- }
-
- if (outlen < (4 + 2) * 4 + cfs_size_round4(ghdr->gh_handle.len) +
- cfs_size_round4(msg->lm_buflens[2])) {
- CERROR("output buffer size %ld too small\n", outlen);
- return -EFAULT;
- }
-
- status = 0;
- effective = 0;
-
- if (copy_to_user(outbuf, &status, 4))
- return -EFAULT;
- outbuf += 4;
- if (copy_to_user(outbuf, &ghdr->gh_major, 4))
- return -EFAULT;
- outbuf += 4;
- if (copy_to_user(outbuf, &ghdr->gh_minor, 4))
- return -EFAULT;
- outbuf += 4;
- if (copy_to_user(outbuf, &ghdr->gh_seqwin, 4))
- return -EFAULT;
- outbuf += 4;
- effective += 4 * 4;
-
- /* handle */
- obj_len = ghdr->gh_handle.len;
- round_len = (obj_len + 3) & ~ 3;
- if (copy_to_user(outbuf, &obj_len, 4))
- return -EFAULT;
- outbuf += 4;
- if (copy_to_user(outbuf, (char *) ghdr->gh_handle.data, round_len))
- return -EFAULT;
- outbuf += round_len;
- effective += 4 + round_len;
-
- /* out token */
- obj_len = msg->lm_buflens[2];
- round_len = (obj_len + 3) & ~ 3;
- if (copy_to_user(outbuf, &obj_len, 4))
- return -EFAULT;
- outbuf += 4;
- if (copy_to_user(outbuf, lustre_msg_buf(msg, 2, 0), round_len))
- return -EFAULT;
- outbuf += round_len;
- effective += 4 + round_len;
-
- return effective;
-}
-
-/* XXX move to where lgssd could see */
-struct lgssd_ioctl_param {
- int version; /* in */
- int secid; /* in */
- char *uuid; /* in */
- int lustre_svc; /* in */
- uid_t uid; /* in */
- gid_t gid; /* in */
- long send_token_size;/* in */
- char *send_token; /* in */
- long reply_buf_size; /* in */
- char *reply_buf; /* in */
- long status; /* out */
- long reply_length; /* out */
-};
-
-int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
-{
- struct obd_import *imp;
- struct ptlrpc_request *req;
- struct lgssd_ioctl_param param;
- struct obd_device *obd;
- char obdname[64];
- long lsize;
- int rc;
-
- if (count != sizeof(param)) {
- CERROR("ioctl size %lu, expect %lu, please check lgss_keyring "
- "version\n", count, (unsigned long) sizeof(param));
- return -EINVAL;
- }
- if (copy_from_user(&param, buffer, sizeof(param))) {
- CERROR("failed copy data from lgssd\n");
- return -EFAULT;
- }
-
- if (param.version != GSSD_INTERFACE_VERSION) {
- CERROR("gssd interface version %d (expect %d)\n",
- param.version, GSSD_INTERFACE_VERSION);
- return -EINVAL;
- }
-
- /* take name */
- if (strncpy_from_user(obdname, param.uuid, sizeof(obdname)) <= 0) {
- CERROR("Invalid obdname pointer\n");
- return -EFAULT;
- }
-
- obd = class_name2obd(obdname);
- if (!obd) {
- CERROR("no such obd %s\n", obdname);
- return -EINVAL;
- }
-
- if (unlikely(!obd->obd_set_up)) {
- CERROR("obd %s not setup\n", obdname);
- return -EINVAL;
- }
-
- spin_lock(&obd->obd_dev_lock);
- if (obd->obd_stopping) {
- CERROR("obd %s has stopped\n", obdname);
- spin_unlock(&obd->obd_dev_lock);
- return -EINVAL;
- }
-
- if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
- strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
- strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
- CERROR("obd %s is not a client device\n", obdname);
- spin_unlock(&obd->obd_dev_lock);
- return -EINVAL;
- }
- spin_unlock(&obd->obd_dev_lock);
-
- down_read(&obd->u.cli.cl_sem);
- if (obd->u.cli.cl_import == NULL) {
- CERROR("obd %s: import has gone\n", obd->obd_name);
- up_read(&obd->u.cli.cl_sem);
- return -EINVAL;
- }
- imp = class_import_get(obd->u.cli.cl_import);
- up_read(&obd->u.cli.cl_sem);
-
- if (imp->imp_deactive) {
- CERROR("import has been deactivated\n");
- class_import_put(imp);
- return -EINVAL;
- }
-
- req = ptlrpc_request_alloc_pack(imp, &RQF_SEC_CTX, LUSTRE_OBD_VERSION,
- SEC_CTX_INIT);
- if (req == NULL) {
- param.status = -ENOMEM;
- goto out_copy;
- }
-
- if (req->rq_cli_ctx->cc_sec->ps_id != param.secid) {
- CWARN("original secid %d, now has changed to %d, "
- "cancel this negotiation\n", param.secid,
- req->rq_cli_ctx->cc_sec->ps_id);
- param.status = -EINVAL;
- goto out_copy;
- }
-
- /* get token */
- rc = ctx_init_pack_request(imp, req,
- param.lustre_svc,
- param.uid, param.gid,
- param.send_token_size,
- param.send_token);
- if (rc) {
- param.status = rc;
- goto out_copy;
- }
-
- ptlrpc_request_set_replen(req);
-
- rc = ptlrpc_queue_wait(req);
- if (rc) {
- /* If any _real_ denial be made, we expect server return
- * -EACCES reply or return success but indicate gss error
- * inside reply message. All other errors are treated as
- * timeout, caller might try the negotiation repeatedly,
- * leave recovery decisions to general ptlrpc layer.
- *
- * FIXME maybe some other error code shouldn't be treated
- * as timeout. */
- param.status = rc;
- if (rc != -EACCES)
- param.status = -ETIMEDOUT;
- goto out_copy;
- }
-
- LASSERT(req->rq_repdata);
- lsize = ctx_init_parse_reply(req->rq_repdata,
- ptlrpc_rep_need_swab(req),
- param.reply_buf, param.reply_buf_size);
- if (lsize < 0) {
- param.status = (int) lsize;
- goto out_copy;
- }
-
- param.status = 0;
- param.reply_length = lsize;
-
-out_copy:
- if (copy_to_user(buffer, &param, sizeof(param)))
- rc = -EFAULT;
- else
- rc = 0;
-
- class_import_put(imp);
- ptlrpc_req_finished(req);
- return rc;
-}
-
-int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
-{
- struct ptlrpc_cli_ctx *ctx = &gctx->gc_base;
- struct obd_import *imp = ctx->cc_sec->ps_import;
- struct ptlrpc_request *req;
- struct ptlrpc_user_desc *pud;
- int rc;
-
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- if (cli_ctx_is_error(ctx) || !cli_ctx_is_uptodate(ctx)) {
- CDEBUG(D_SEC, "ctx %p(%u->%s) not uptodate, "
- "don't send destroy rpc\n", ctx,
- ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
- return 0;
- }
-
- might_sleep();
-
- CWARN("%s ctx %p idx "LPX64" (%u->%s)\n",
- sec_is_reverse(ctx->cc_sec) ?
- "server finishing reverse" : "client finishing forward",
- ctx, gss_handle_to_u64(&gctx->gc_handle),
- ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
-
- gctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
-
- req = ptlrpc_request_alloc(imp, &RQF_SEC_CTX);
- if (req == NULL) {
- CWARN("ctx %p(%u): fail to prepare rpc, destroy locally\n",
- ctx, ctx->cc_vcred.vc_uid);
- GOTO(out, rc = -ENOMEM);
- }
-
- rc = ptlrpc_request_bufs_pack(req, LUSTRE_OBD_VERSION, SEC_CTX_FINI,
- NULL, ctx);
- if (rc) {
- ptlrpc_request_free(req);
- GOTO(out_ref, rc);
- }
-
- /* fix the user desc */
- if (req->rq_pack_udesc) {
- /* we rely the fact that this request is in AUTH mode,
- * and user_desc at offset 2. */
- pud = lustre_msg_buf(req->rq_reqbuf, 2, sizeof(*pud));
- LASSERT(pud);
- pud->pud_uid = pud->pud_fsuid = ctx->cc_vcred.vc_uid;
- pud->pud_gid = pud->pud_fsgid = ctx->cc_vcred.vc_gid;
- pud->pud_cap = 0;
- pud->pud_ngroups = 0;
- }
-
- req->rq_phase = RQ_PHASE_RPC;
- rc = ptl_send_rpc(req, 1);
- if (rc)
- CWARN("ctx %p(%u->%s): rpc error %d, destroy locally\n", ctx,
- ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec), rc);
-
-out_ref:
- ptlrpc_req_finished(req);
-out:
- return rc;
-}
-
-int __init gss_init_cli_upcall(void)
-{
- return 0;
-}
-
-void __exit gss_exit_cli_upcall(void)
-{
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h
deleted file mode 100644
index 37ec101e14e5..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_err.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
- *
- * Copyright (c) 2002 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Andy Adamson <andros@umich.edu>
- */
-
-/*
- * Copyright 1993 by OpenVision Technologies, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __PTLRPC_GSS_GSS_ERR_H_
-#define __PTLRPC_GSS_GSS_ERR_H_
-
-typedef unsigned int OM_uint32;
-
-/*
- * Flag bits for context-level services.
- */
-#define GSS_C_DELEG_FLAG (1)
-#define GSS_C_MUTUAL_FLAG (2)
-#define GSS_C_REPLAY_FLAG (4)
-#define GSS_C_SEQUENCE_FLAG (8)
-#define GSS_C_CONF_FLAG (16)
-#define GSS_C_INTEG_FLAG (32)
-#define GSS_C_ANON_FLAG (64)
-#define GSS_C_PROT_READY_FLAG (128)
-#define GSS_C_TRANS_FLAG (256)
-
-/*
- * Credential usage options
- */
-#define GSS_C_BOTH (0)
-#define GSS_C_INITIATE (1)
-#define GSS_C_ACCEPT (2)
-
-/*
- * Status code types for gss_display_status
- */
-#define GSS_C_GSS_CODE (1)
-#define GSS_C_MECH_CODE (2)
-
-
-/*
- * Define the default Quality of Protection for per-message services. Note
- * that an implementation that offers multiple levels of QOP may either reserve
- * a value (for example zero, as assumed here) to mean "default protection", or
- * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
- * QOP value. However a value of 0 should always be interpreted by a GSSAPI
- * implementation as a request for the default protection level.
- */
-#define GSS_C_QOP_DEFAULT (0)
-
-/*
- * Expiration time of 2^32-1 seconds means infinite lifetime for a
- * credential or security context
- */
-#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
-
-
-/* Major status codes */
-
-#define GSS_S_COMPLETE (0)
-
-/*
- * Some "helper" definitions to make the status code macros obvious.
- */
-#define GSS_C_CALLING_ERROR_OFFSET (24)
-#define GSS_C_ROUTINE_ERROR_OFFSET (16)
-#define GSS_C_SUPPLEMENTARY_OFFSET (0)
-#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
-#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
-#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
-
-/*
- * The macros that test status codes for error conditions. Note that the
- * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
- * evaluates its argument only once.
- */
-#define GSS_CALLING_ERROR(x) \
- ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
-#define GSS_ROUTINE_ERROR(x) \
- ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
-#define GSS_SUPPLEMENTARY_INFO(x) \
- ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
-#define GSS_ERROR(x) \
- ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
- (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
-
-/*
- * Now the actual status code definitions
- */
-
-/*
- * Calling errors:
- */
-#define GSS_S_CALL_INACCESSIBLE_READ \
- (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
-#define GSS_S_CALL_INACCESSIBLE_WRITE \
- (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
-#define GSS_S_CALL_BAD_STRUCTURE \
- (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
-
-/*
- * Routine errors:
- */
-#define GSS_S_BAD_MECH \
- (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_NAME \
- (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_NAMETYPE \
- (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_BINDINGS \
- (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_STATUS \
- (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_SIG \
- (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_NO_CRED \
- (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_NO_CONTEXT \
- (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DEFECTIVE_TOKEN \
- (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DEFECTIVE_CREDENTIAL \
- (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_CREDENTIALS_EXPIRED \
- (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_CONTEXT_EXPIRED \
- (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_FAILURE \
- (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_BAD_QOP \
- (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_UNAUTHORIZED \
- (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_UNAVAILABLE \
- (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_DUPLICATE_ELEMENT \
- (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-#define GSS_S_NAME_NOT_MN \
- (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
-
-/*
- * Supplementary info bits:
- */
-#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
-#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
-#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
-#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
-#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
-
-/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
-
-#define GSS_CALLING_ERROR_FIELD(x) \
- (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
-#define GSS_ROUTINE_ERROR_FIELD(x) \
- (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
-#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
- (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
-
-/* XXXX This is a necessary evil until the spec is fixed */
-#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
-
-#endif /* __PTLRPC_GSS_GSS_ERR_H_ */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_generic_token.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_generic_token.c
deleted file mode 100644
index 8dc5c724958d..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_generic_token.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/net/sunrpc/gss_generic_token.c
- *
- * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic/util_token.c
- *
- * Copyright (c) 2000 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Andy Adamson <andros@umich.edu>
- */
-
-/*
- * Copyright 1993 by OpenVision Technologies, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appears in all copies and
- * that both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OpenVision not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. OpenVision makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-#include "gss_krb5.h"
-#include "gss_asn1.h"
-
-
-/* TWRITE_STR from gssapiP_generic.h */
-#define TWRITE_STR(ptr, str, len) \
- memcpy((ptr), (char *) (str), (len)); \
- (ptr) += (len);
-
-/* XXXX this code currently makes the assumption that a mech oid will
- never be longer than 127 bytes. This assumption is not inherent in
- the interfaces, so the code can be fixed if the OSI namespace
- balloons unexpectedly. */
-
-/* Each token looks like this:
-
-0x60 tag for APPLICATION 0, SEQUENCE
- (constructed, definite-length)
- <length> possible multiple bytes, need to parse/generate
- 0x06 tag for OBJECT IDENTIFIER
- <moid_length> compile-time constant string (assume 1 byte)
- <moid_bytes> compile-time constant string
- <inner_bytes> the ANY containing the application token
- bytes 0,1 are the token type
- bytes 2,n are the token data
-
-For the purposes of this abstraction, the token "header" consists of
-the sequence tag and length octets, the mech OID DER encoding, and the
-first two inner bytes, which indicate the token type. The token
-"body" consists of everything else.
-
-*/
-
-static
-int der_length_size(int length)
-{
- if (length < (1 << 7))
- return 1;
- else if (length < (1 << 8))
- return 2;
-#if (SIZEOF_INT == 2)
- else
- return 3;
-#else
- else if (length < (1 << 16))
- return 3;
- else if (length < (1 << 24))
- return 4;
- else
- return 5;
-#endif
-}
-
-static
-void der_write_length(unsigned char **buf, int length)
-{
- if (length < (1 << 7)) {
- *(*buf)++ = (unsigned char) length;
- } else {
- *(*buf)++ = (unsigned char) (der_length_size(length) + 127);
-#if (SIZEOF_INT > 2)
- if (length >= (1 << 24))
- *(*buf)++ = (unsigned char) (length >> 24);
- if (length >= (1 << 16))
- *(*buf)++ = (unsigned char) ((length >> 16) & 0xff);
-#endif
- if (length >= (1 << 8))
- *(*buf)++ = (unsigned char) ((length >> 8) & 0xff);
- *(*buf)++ = (unsigned char) (length & 0xff);
- }
-}
-
-/*
- * returns decoded length, or < 0 on failure. Advances buf and
- * decrements bufsize
- */
-static
-int der_read_length(unsigned char **buf, int *bufsize)
-{
- unsigned char sf;
- int ret;
-
- if (*bufsize < 1)
- return -1;
- sf = *(*buf)++;
- (*bufsize)--;
- if (sf & 0x80) {
- sf &= 0x7f;
- if (((*bufsize) - 1) < sf)
- return -1;
- if (sf > SIZEOF_INT)
- return -1;
- ret = 0;
- for (; sf; sf--) {
- ret = (ret << 8) + (*(*buf)++);
- (*bufsize)--;
- }
- } else {
- ret = sf;
- }
-
- return ret;
-}
-
-/*
- * returns the length of a token, given the mech oid and the body size
- */
-int g_token_size(rawobj_t *mech, unsigned int body_size)
-{
- /* set body_size to sequence contents size */
- body_size += 4 + (int) mech->len; /* NEED overflow check */
- return (1 + der_length_size(body_size) + body_size);
-}
-
-/*
- * fills in a buffer with the token header. The buffer is assumed to
- * be the right size. buf is advanced past the token header
- */
-void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf)
-{
- *(*buf)++ = 0x60;
- der_write_length(buf, 4 + mech->len + body_size);
- *(*buf)++ = 0x06;
- *(*buf)++ = (unsigned char) mech->len;
- TWRITE_STR(*buf, mech->data, ((int) mech->len));
-}
-
-/*
- * Given a buffer containing a token, reads and verifies the token,
- * leaving buf advanced past the token header, and setting body_size
- * to the number of remaining bytes. Returns 0 on success,
- * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
- * mechanism in the token does not match the mech argument. buf and
- * *body_size are left unmodified on error.
- */
-__u32 g_verify_token_header(rawobj_t *mech, int *body_size,
- unsigned char **buf_in, int toksize)
-{
- unsigned char *buf = *buf_in;
- int seqsize;
- rawobj_t toid;
- int ret = 0;
-
- toksize -= 1;
- if (0 > toksize)
- return (G_BAD_TOK_HEADER);
- if (*buf++ != 0x60)
- return (G_BAD_TOK_HEADER);
-
- seqsize = der_read_length(&buf, &toksize);
- if (seqsize < 0)
- return(G_BAD_TOK_HEADER);
-
- if (seqsize != toksize)
- return (G_BAD_TOK_HEADER);
-
- toksize -= 1;
- if (0 > toksize)
- return (G_BAD_TOK_HEADER);
- if (*buf++ != 0x06)
- return (G_BAD_TOK_HEADER);
-
- toksize -= 1;
- if (0 > toksize)
- return (G_BAD_TOK_HEADER);
- toid.len = *buf++;
-
- toksize -= toid.len;
- if (0 > toksize)
- return (G_BAD_TOK_HEADER);
- toid.data = buf;
- buf += toid.len;
-
- if (!g_OID_equal(&toid, mech))
- ret = G_WRONG_MECH;
-
- /* G_WRONG_MECH is not returned immediately because it's more
- * important to return G_BAD_TOK_HEADER if the token header is
- * in fact bad
- */
- toksize -= 2;
- if (0 > toksize)
- return (G_BAD_TOK_HEADER);
-
- if (ret)
- return (ret);
-
- if (!ret) {
- *buf_in = buf;
- *body_size = toksize;
- }
-
- return (ret);
-}
-
-/*
- * Given a buffer containing a token, returns a copy of the mech oid in
- * the parameter mech.
- */
-__u32 g_get_mech_oid(rawobj_t *mech, rawobj_t *in_buf)
-{
- unsigned char *buf = in_buf->data;
- int len = in_buf->len;
- int ret = 0;
- int seqsize;
-
- len -= 1;
- if (0 > len)
- return (G_BAD_TOK_HEADER);
- if (*buf++ != 0x60)
- return (G_BAD_TOK_HEADER);
-
- seqsize = der_read_length(&buf, &len);
- if (seqsize < 0)
- return (G_BAD_TOK_HEADER);
-
- len -= 1;
- if (0 > len)
- return (G_BAD_TOK_HEADER);
- if (*buf++ != 0x06)
- return (G_BAD_TOK_HEADER);
-
- len -= 1;
- if (0 > len)
- return (G_BAD_TOK_HEADER);
- mech->len = *buf++;
-
- len -= mech->len;
- if (0 > len)
- return (G_BAD_TOK_HEADER);
- OBD_ALLOC_LARGE(mech->data, mech->len);
- if (!mech->data)
- return (G_BUFFER_ALLOC);
- memcpy(mech->data, buf, mech->len);
-
- return ret;
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_internal.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_internal.h
deleted file mode 100644
index cbfc47cb3f7b..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_internal.h
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Modified from NFSv4 project for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-#ifndef __PTLRPC_GSS_GSS_INTERNAL_H_
-#define __PTLRPC_GSS_GSS_INTERNAL_H_
-
-#include <lustre_sec.h>
-
-/*
- * rawobj stuff
- */
-typedef struct netobj_s {
- __u32 len;
- __u8 data[0];
-} netobj_t;
-
-#define NETOBJ_EMPTY ((netobj_t) { 0 })
-
-typedef struct rawobj_s {
- __u32 len;
- __u8 *data;
-} rawobj_t;
-
-#define RAWOBJ_EMPTY ((rawobj_t) { 0, NULL })
-
-typedef struct rawobj_buf_s {
- __u32 dataoff;
- __u32 datalen;
- __u32 buflen;
- __u8 *buf;
-} rawobj_buf_t;
-
-int rawobj_empty(rawobj_t *obj);
-int rawobj_alloc(rawobj_t *obj, char *buf, int len);
-void rawobj_free(rawobj_t *obj);
-int rawobj_equal(rawobj_t *a, rawobj_t *b);
-int rawobj_dup(rawobj_t *dest, rawobj_t *src);
-int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen);
-int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen);
-int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen);
-int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen);
-int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen);
-int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj);
-int rawobj_from_netobj_alloc(rawobj_t *obj, netobj_t *netobj);
-
-int buffer_extract_bytes(const void **buf, __u32 *buflen,
- void *res, __u32 reslen);
-
-/*
- * several timeout values. client refresh upcall timeout we using
- * default in pipefs implemnetation.
- */
-#define __TIMEOUT_DELTA (10)
-
-#define GSS_SECINIT_RPC_TIMEOUT \
- (obd_timeout < __TIMEOUT_DELTA ? \
- __TIMEOUT_DELTA : obd_timeout - __TIMEOUT_DELTA)
-
-#define GSS_SECFINI_RPC_TIMEOUT (__TIMEOUT_DELTA)
-#define GSS_SECSVC_UPCALL_TIMEOUT (GSS_SECINIT_RPC_TIMEOUT)
-
-/*
- * default gc interval
- */
-#define GSS_GC_INTERVAL (60 * 60) /* 60 minutes */
-
-static inline
-unsigned long gss_round_ctx_expiry(unsigned long expiry,
- unsigned long sec_flags)
-{
- if (sec_flags & PTLRPC_SEC_FL_REVERSE)
- return expiry;
-
- if (get_seconds() + __TIMEOUT_DELTA <= expiry)
- return expiry - __TIMEOUT_DELTA;
-
- return expiry;
-}
-
-/*
- * Max encryption element in block cipher algorithms.
- */
-#define GSS_MAX_CIPHER_BLOCK (16)
-
-/*
- * XXX make it visible of kernel and lgssd/lsvcgssd
- */
-#define GSSD_INTERFACE_VERSION (1)
-
-#define PTLRPC_GSS_VERSION (1)
-
-
-enum ptlrpc_gss_proc {
- PTLRPC_GSS_PROC_DATA = 0,
- PTLRPC_GSS_PROC_INIT = 1,
- PTLRPC_GSS_PROC_CONTINUE_INIT = 2,
- PTLRPC_GSS_PROC_DESTROY = 3,
- PTLRPC_GSS_PROC_ERR = 4,
-};
-
-enum ptlrpc_gss_tgt {
- LUSTRE_GSS_TGT_MGS = 0,
- LUSTRE_GSS_TGT_MDS = 1,
- LUSTRE_GSS_TGT_OSS = 2,
-};
-
-enum ptlrpc_gss_header_flags {
- LUSTRE_GSS_PACK_BULK = 1,
- LUSTRE_GSS_PACK_USER = 2,
-};
-
-static inline
-__u32 import_to_gss_svc(struct obd_import *imp)
-{
- const char *name = imp->imp_obd->obd_type->typ_name;
-
- if (!strcmp(name, LUSTRE_MGC_NAME))
- return LUSTRE_GSS_TGT_MGS;
- if (!strcmp(name, LUSTRE_MDC_NAME))
- return LUSTRE_GSS_TGT_MDS;
- if (!strcmp(name, LUSTRE_OSC_NAME))
- return LUSTRE_GSS_TGT_OSS;
- LBUG();
- return 0;
-}
-
-/*
- * following 3 header must have the same size and offset
- */
-struct gss_header {
- __u8 gh_version; /* gss version */
- __u8 gh_sp; /* sec part */
- __u16 gh_pad0;
- __u32 gh_flags; /* wrap flags */
- __u32 gh_proc; /* proc */
- __u32 gh_seq; /* sequence */
- __u32 gh_svc; /* service */
- __u32 gh_pad1;
- __u32 gh_pad2;
- __u32 gh_pad3;
- netobj_t gh_handle; /* context handle */
-};
-
-struct gss_rep_header {
- __u8 gh_version;
- __u8 gh_sp;
- __u16 gh_pad0;
- __u32 gh_flags;
- __u32 gh_proc;
- __u32 gh_major;
- __u32 gh_minor;
- __u32 gh_seqwin;
- __u32 gh_pad2;
- __u32 gh_pad3;
- netobj_t gh_handle;
-};
-
-struct gss_err_header {
- __u8 gh_version;
- __u8 gh_sp;
- __u16 gh_pad0;
- __u32 gh_flags;
- __u32 gh_proc;
- __u32 gh_major;
- __u32 gh_minor;
- __u32 gh_pad1;
- __u32 gh_pad2;
- __u32 gh_pad3;
- netobj_t gh_handle;
-};
-
-/*
- * part of wire context information send from client which be saved and
- * used later by server.
- */
-struct gss_wire_ctx {
- __u32 gw_flags;
- __u32 gw_proc;
- __u32 gw_seq;
- __u32 gw_svc;
- rawobj_t gw_handle;
-};
-
-#define PTLRPC_GSS_MAX_HANDLE_SIZE (8)
-#define PTLRPC_GSS_HEADER_SIZE (sizeof(struct gss_header) + \
- PTLRPC_GSS_MAX_HANDLE_SIZE)
-
-
-static inline __u64 gss_handle_to_u64(rawobj_t *handle)
-{
- if (handle->len != PTLRPC_GSS_MAX_HANDLE_SIZE)
- return -1;
- return *((__u64 *) handle->data);
-}
-
-#define GSS_SEQ_WIN (2048)
-#define GSS_SEQ_WIN_MAIN GSS_SEQ_WIN
-#define GSS_SEQ_WIN_BACK (128)
-#define GSS_SEQ_REPACK_THRESHOLD (GSS_SEQ_WIN_MAIN / 2 + \
- GSS_SEQ_WIN_MAIN / 4)
-
-struct gss_svc_seq_data {
- spinlock_t ssd_lock;
- /*
- * highest sequence number seen so far, for main and back window
- */
- __u32 ssd_max_main;
- __u32 ssd_max_back;
- /*
- * main and back window
- * for i such that ssd_max - GSS_SEQ_WIN < i <= ssd_max, the i-th bit
- * of ssd_win is nonzero iff sequence number i has been seen already.
- */
- unsigned long ssd_win_main[GSS_SEQ_WIN_MAIN/BITS_PER_LONG];
- unsigned long ssd_win_back[GSS_SEQ_WIN_BACK/BITS_PER_LONG];
-};
-
-struct gss_svc_ctx {
- struct gss_ctx *gsc_mechctx;
- struct gss_svc_seq_data gsc_seqdata;
- rawobj_t gsc_rvs_hdl;
- __u32 gsc_rvs_seq;
- uid_t gsc_uid;
- gid_t gsc_gid;
- uid_t gsc_mapped_uid;
- unsigned int gsc_usr_root:1,
- gsc_usr_mds:1,
- gsc_usr_oss:1,
- gsc_remote:1,
- gsc_reverse:1;
-};
-
-struct gss_svc_reqctx {
- struct ptlrpc_svc_ctx src_base;
- /*
- * context
- */
- struct gss_wire_ctx src_wirectx;
- struct gss_svc_ctx *src_ctx;
- /*
- * record place of bulk_sec_desc in request/reply buffer
- */
- struct ptlrpc_bulk_sec_desc *src_reqbsd;
- int src_reqbsd_size;
- struct ptlrpc_bulk_sec_desc *src_repbsd;
- int src_repbsd_size;
- /*
- * flags
- */
- unsigned int src_init:1,
- src_init_continue:1,
- src_err_notify:1;
- int src_reserve_len;
-};
-
-struct gss_cli_ctx {
- struct ptlrpc_cli_ctx gc_base;
- __u32 gc_flavor;
- __u32 gc_proc;
- __u32 gc_win;
- atomic_t gc_seq;
- rawobj_t gc_handle;
- struct gss_ctx *gc_mechctx;
- /* handle for the buddy svc ctx */
- rawobj_t gc_svc_handle;
-};
-
-struct gss_cli_ctx_keyring {
- struct gss_cli_ctx gck_base;
- struct key *gck_key;
- struct timer_list *gck_timer;
-};
-
-struct gss_sec {
- struct ptlrpc_sec gs_base;
- struct gss_api_mech *gs_mech;
- spinlock_t gs_lock;
- __u64 gs_rvs_hdl;
-};
-
-struct gss_sec_pipefs {
- struct gss_sec gsp_base;
- int gsp_chash_size; /* must be 2^n */
- struct hlist_head gsp_chash[0];
-};
-
-/*
- * FIXME cleanup the keyring upcall mutexes
- */
-#define HAVE_KEYRING_UPCALL_SERIALIZED 1
-
-struct gss_sec_keyring {
- struct gss_sec gsk_base;
- /*
- * all contexts listed here. access is protected by sec spinlock.
- */
- struct hlist_head gsk_clist;
- /*
- * specially point to root ctx (only one at a time). access is
- * protected by sec spinlock.
- */
- struct ptlrpc_cli_ctx *gsk_root_ctx;
- /*
- * specially serialize upcalls for root context.
- */
- struct mutex gsk_root_uc_lock;
-
-#ifdef HAVE_KEYRING_UPCALL_SERIALIZED
- struct mutex gsk_uc_lock; /* serialize upcalls */
-#endif
-};
-
-static inline struct gss_cli_ctx *ctx2gctx(struct ptlrpc_cli_ctx *ctx)
-{
- return container_of(ctx, struct gss_cli_ctx, gc_base);
-}
-
-static inline
-struct gss_cli_ctx_keyring *ctx2gctx_keyring(struct ptlrpc_cli_ctx *ctx)
-{
- return container_of(ctx2gctx(ctx),
- struct gss_cli_ctx_keyring, gck_base);
-}
-
-static inline struct gss_sec *sec2gsec(struct ptlrpc_sec *sec)
-{
- return container_of(sec, struct gss_sec, gs_base);
-}
-
-static inline struct gss_sec_pipefs *sec2gsec_pipefs(struct ptlrpc_sec *sec)
-{
- return container_of(sec2gsec(sec), struct gss_sec_pipefs, gsp_base);
-}
-
-static inline struct gss_sec_keyring *sec2gsec_keyring(struct ptlrpc_sec *sec)
-{
- return container_of(sec2gsec(sec), struct gss_sec_keyring, gsk_base);
-}
-
-
-#define GSS_CTX_INIT_MAX_LEN (1024)
-
-/*
- * This only guaranteed be enough for current krb5 des-cbc-crc . We might
- * adjust this when new enc type or mech added in.
- */
-#define GSS_PRIVBUF_PREFIX_LEN (32)
-#define GSS_PRIVBUF_SUFFIX_LEN (32)
-
-static inline
-struct gss_svc_reqctx *gss_svc_ctx2reqctx(struct ptlrpc_svc_ctx *ctx)
-{
- LASSERT(ctx);
- return container_of(ctx, struct gss_svc_reqctx, src_base);
-}
-
-static inline
-struct gss_svc_ctx *gss_svc_ctx2gssctx(struct ptlrpc_svc_ctx *ctx)
-{
- LASSERT(ctx);
- return gss_svc_ctx2reqctx(ctx)->src_ctx;
-}
-
-/* sec_gss.c */
-int gss_cli_ctx_match(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred);
-int gss_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize);
-int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
-int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
-int gss_cli_ctx_seal(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
-int gss_cli_ctx_unseal(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req);
-
-int gss_sec_install_rctx(struct obd_import *imp, struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx);
-int gss_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
- int msgsize);
-void gss_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
-int gss_alloc_repbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
- int msgsize);
-void gss_free_repbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
-int gss_enlarge_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
- int segment, int newsize);
-
-int gss_svc_accept(struct ptlrpc_sec_policy *policy,
- struct ptlrpc_request *req);
-void gss_svc_invalidate_ctx(struct ptlrpc_svc_ctx *svc_ctx);
-int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen);
-int gss_svc_authorize(struct ptlrpc_request *req);
-void gss_svc_free_rs(struct ptlrpc_reply_state *rs);
-void gss_svc_free_ctx(struct ptlrpc_svc_ctx *ctx);
-
-int cli_ctx_expire(struct ptlrpc_cli_ctx *ctx);
-int cli_ctx_check_death(struct ptlrpc_cli_ctx *ctx);
-
-int gss_copy_rvc_cli_ctx(struct ptlrpc_cli_ctx *cli_ctx,
- struct ptlrpc_svc_ctx *svc_ctx);
-
-struct gss_header *gss_swab_header(struct lustre_msg *msg, int segment,
- int swabbed);
-netobj_t *gss_swab_netobj(struct lustre_msg *msg, int segment);
-
-void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx);
-int gss_pack_err_notify(struct ptlrpc_request *req, __u32 major, __u32 minor);
-int gss_check_seq_num(struct gss_svc_seq_data *sd, __u32 seq_num, int set);
-
-int gss_sec_create_common(struct gss_sec *gsec,
- struct ptlrpc_sec_policy *policy,
- struct obd_import *imp,
- struct ptlrpc_svc_ctx *ctx,
- struct sptlrpc_flavor *sf);
-void gss_sec_destroy_common(struct gss_sec *gsec);
-void gss_sec_kill(struct ptlrpc_sec *sec);
-
-int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_ctx_ops *ctxops,
- struct vfs_cred *vcred);
-int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx);
-
-void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize);
-
-/* gss_keyring.c */
-int __init gss_init_keyring(void);
-void __exit gss_exit_keyring(void);
-
-/* gss_pipefs.c */
-int __init gss_init_pipefs(void);
-void __exit gss_exit_pipefs(void);
-
-/* gss_bulk.c */
-int gss_cli_prep_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-int gss_svc_prep_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-int gss_svc_wrap_bulk(struct ptlrpc_request *req,
- struct ptlrpc_bulk_desc *desc);
-
-/* gss_mech_switch.c */
-int init_kerberos_module(void);
-void cleanup_kerberos_module(void);
-
-/* gss_generic_token.c */
-int g_token_size(rawobj_t *mech, unsigned int body_size);
-void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf);
-__u32 g_verify_token_header(rawobj_t *mech, int *body_size,
- unsigned char **buf_in, int toksize);
-
-
-/* gss_cli_upcall.c */
-int gss_do_ctx_init_rpc(char *buffer, unsigned long count);
-int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx);
-
-int __init gss_init_cli_upcall(void);
-void __exit gss_exit_cli_upcall(void);
-
-/* gss_svc_upcall.c */
-__u64 gss_get_next_ctx_index(void);
-int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
- struct gss_sec *gsec,
- struct gss_cli_ctx *gctx);
-int gss_svc_upcall_expire_rvs_ctx(rawobj_t *handle);
-int gss_svc_upcall_dup_handle(rawobj_t *handle, struct gss_svc_ctx *ctx);
-int gss_svc_upcall_update_sequence(rawobj_t *handle, __u32 seq);
-int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
- struct gss_svc_reqctx *grctx,
- struct gss_wire_ctx *gw,
- struct obd_device *target,
- __u32 lustre_svc,
- rawobj_t *rvs_hdl,
- rawobj_t *in_token);
-struct gss_svc_ctx *gss_svc_upcall_get_ctx(struct ptlrpc_request *req,
- struct gss_wire_ctx *gw);
-void gss_svc_upcall_put_ctx(struct gss_svc_ctx *ctx);
-void gss_svc_upcall_destroy_ctx(struct gss_svc_ctx *ctx);
-
-int __init gss_init_svc_upcall(void);
-void __exit gss_exit_svc_upcall(void);
-
-/* lproc_gss.c */
-void gss_stat_oos_record_cli(int behind);
-void gss_stat_oos_record_svc(int phase, int replay);
-
-int __init gss_init_lproc(void);
-void __exit gss_exit_lproc(void);
-
-/* gss_krb5_mech.c */
-int __init init_kerberos_module(void);
-void __exit cleanup_kerberos_module(void);
-
-
-/* debug */
-static inline
-void __dbg_memdump(char *name, void *ptr, int size)
-{
- char *buf, *p = (char *) ptr;
- int bufsize = size * 2 + 1, i;
-
- OBD_ALLOC(buf, bufsize);
- if (!buf) {
- CDEBUG(D_ERROR, "DUMP ERROR: can't alloc %d bytes\n", bufsize);
- return;
- }
-
- for (i = 0; i < size; i++)
- sprintf(&buf[i+i], "%02x", (__u8) p[i]);
- buf[size + size] = '\0';
- LCONSOLE_INFO("DUMP %s@%p(%d): %s\n", name, ptr, size, buf);
- OBD_FREE(buf, bufsize);
-}
-
-#endif /* __PTLRPC_GSS_GSS_INTERNAL_H_ */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c
deleted file mode 100644
index 4642bbfb9273..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_keyring.c
+++ /dev/null
@@ -1,1409 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/ptlrpc/gss/gss_keyring.c
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/crypto.h>
-#include <linux/key.h>
-#include <linux/keyctl.h>
-#include <linux/key-type.h>
-#include <linux/mutex.h>
-#include <asm/atomic.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_sec.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-static struct ptlrpc_sec_policy gss_policy_keyring;
-static struct ptlrpc_ctx_ops gss_keyring_ctxops;
-static struct key_type gss_key_type;
-
-static int sec_install_rctx_kr(struct ptlrpc_sec *sec,
- struct ptlrpc_svc_ctx *svc_ctx);
-
-/*
- * the timeout is only for the case that upcall child process die abnormally.
- * in any other cases it should finally update kernel key.
- *
- * FIXME we'd better to incorporate the client & server side upcall timeouts
- * into the framework of Adaptive Timeouts, but we need to figure out how to
- * make sure that kernel knows the upcall processes is in-progress or died
- * unexpectedly.
- */
-#define KEYRING_UPCALL_TIMEOUT (obd_timeout + obd_timeout)
-
-/****************************************
- * internal helpers *
- ****************************************/
-
-#define DUMP_PROCESS_KEYRINGS(tsk) \
-{ \
- CWARN("DUMP PK: %s[%u,%u/%u](<-%s[%u,%u/%u]): " \
- "a %d, t %d, p %d, s %d, u %d, us %d, df %d\n", \
- tsk->comm, tsk->pid, tsk->uid, tsk->fsuid, \
- tsk->parent->comm, tsk->parent->pid, \
- tsk->parent->uid, tsk->parent->fsuid, \
- tsk->request_key_auth ? \
- tsk->request_key_auth->serial : 0, \
- key_cred(tsk)->thread_keyring ? \
- key_cred(tsk)->thread_keyring->serial : 0, \
- key_tgcred(tsk)->process_keyring ? \
- key_tgcred(tsk)->process_keyring->serial : 0, \
- key_tgcred(tsk)->session_keyring ? \
- key_tgcred(tsk)->session_keyring->serial : 0, \
- key_cred(tsk)->user->uid_keyring ? \
- key_cred(tsk)->user->uid_keyring->serial : 0, \
- key_cred(tsk)->user->session_keyring ? \
- key_cred(tsk)->user->session_keyring->serial : 0, \
- key_cred(tsk)->jit_keyring \
- ); \
-}
-
-#define DUMP_KEY(key) \
-{ \
- CWARN("DUMP KEY: %p(%d) ref %d u%u/g%u desc %s\n", \
- key, key->serial, atomic_read(&key->usage), \
- key->uid, key->gid, \
- key->description ? key->description : "n/a" \
- ); \
-}
-
-#define key_cred(tsk) ((tsk)->cred)
-#define key_tgcred(tsk) ((tsk)->cred->tgcred)
-
-static inline void keyring_upcall_lock(struct gss_sec_keyring *gsec_kr)
-{
-#ifdef HAVE_KEYRING_UPCALL_SERIALIZED
- mutex_lock(&gsec_kr->gsk_uc_lock);
-#endif
-}
-
-static inline void keyring_upcall_unlock(struct gss_sec_keyring *gsec_kr)
-{
-#ifdef HAVE_KEYRING_UPCALL_SERIALIZED
- mutex_unlock(&gsec_kr->gsk_uc_lock);
-#endif
-}
-
-static inline void key_revoke_locked(struct key *key)
-{
- set_bit(KEY_FLAG_REVOKED, &key->flags);
-}
-
-static void ctx_upcall_timeout_kr(unsigned long data)
-{
- struct ptlrpc_cli_ctx *ctx = (struct ptlrpc_cli_ctx *) data;
- struct key *key = ctx2gctx_keyring(ctx)->gck_key;
-
- CWARN("ctx %p, key %p\n", ctx, key);
-
- LASSERT(key);
-
- cli_ctx_expire(ctx);
- key_revoke_locked(key);
-}
-
-static
-void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout)
-{
- struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
- struct timer_list *timer = gctx_kr->gck_timer;
-
- LASSERT(timer);
-
- CDEBUG(D_SEC, "ctx %p: start timer %lds\n", ctx, timeout);
- timeout = timeout * HZ + cfs_time_current();
-
- init_timer(timer);
- timer->expires = timeout;
- timer->data = (unsigned long) ctx;
- timer->function = ctx_upcall_timeout_kr;
-
- add_timer(timer);
-}
-
-/*
- * caller should make sure no race with other threads
- */
-static
-void ctx_clear_timer_kr(struct ptlrpc_cli_ctx *ctx)
-{
- struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
- struct timer_list *timer = gctx_kr->gck_timer;
-
- if (timer == NULL)
- return;
-
- CDEBUG(D_SEC, "ctx %p, key %p\n", ctx, gctx_kr->gck_key);
-
- gctx_kr->gck_timer = NULL;
-
- del_singleshot_timer_sync(timer);
-
- OBD_FREE_PTR(timer);
-}
-
-static
-struct ptlrpc_cli_ctx *ctx_create_kr(struct ptlrpc_sec *sec,
- struct vfs_cred *vcred)
-{
- struct ptlrpc_cli_ctx *ctx;
- struct gss_cli_ctx_keyring *gctx_kr;
-
- OBD_ALLOC_PTR(gctx_kr);
- if (gctx_kr == NULL)
- return NULL;
-
- OBD_ALLOC_PTR(gctx_kr->gck_timer);
- if (gctx_kr->gck_timer == NULL) {
- OBD_FREE_PTR(gctx_kr);
- return NULL;
- }
- init_timer(gctx_kr->gck_timer);
-
- ctx = &gctx_kr->gck_base.gc_base;
-
- if (gss_cli_ctx_init_common(sec, ctx, &gss_keyring_ctxops, vcred)) {
- OBD_FREE_PTR(gctx_kr->gck_timer);
- OBD_FREE_PTR(gctx_kr);
- return NULL;
- }
-
- ctx->cc_expire = cfs_time_current_sec() + KEYRING_UPCALL_TIMEOUT;
- clear_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags);
- atomic_inc(&ctx->cc_refcount); /* for the caller */
-
- return ctx;
-}
-
-static void ctx_destroy_kr(struct ptlrpc_cli_ctx *ctx)
-{
- struct ptlrpc_sec *sec = ctx->cc_sec;
- struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
-
- CDEBUG(D_SEC, "destroying ctx %p\n", ctx);
-
- /* at this time the association with key has been broken. */
- LASSERT(sec);
- LASSERT(atomic_read(&sec->ps_refcount) > 0);
- LASSERT(atomic_read(&sec->ps_nctx) > 0);
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
- LASSERT(gctx_kr->gck_key == NULL);
-
- ctx_clear_timer_kr(ctx);
- LASSERT(gctx_kr->gck_timer == NULL);
-
- if (gss_cli_ctx_fini_common(sec, ctx))
- return;
-
- OBD_FREE_PTR(gctx_kr);
-
- atomic_dec(&sec->ps_nctx);
- sptlrpc_sec_put(sec);
-}
-
-static void ctx_release_kr(struct ptlrpc_cli_ctx *ctx, int sync)
-{
- if (sync) {
- ctx_destroy_kr(ctx);
- } else {
- atomic_inc(&ctx->cc_refcount);
- sptlrpc_gc_add_ctx(ctx);
- }
-}
-
-static void ctx_put_kr(struct ptlrpc_cli_ctx *ctx, int sync)
-{
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- if (atomic_dec_and_test(&ctx->cc_refcount))
- ctx_release_kr(ctx, sync);
-}
-
-/*
- * key <-> ctx association and rules:
- * - ctx might not bind with any key
- * - key/ctx binding is protected by key semaphore (if the key present)
- * - key and ctx each take a reference of the other
- * - ctx enlist/unlist is protected by ctx spinlock
- * - never enlist a ctx after it's been unlisted
- * - whoever do enlist should also do bind, lock key before enlist:
- * - lock key -> lock ctx -> enlist -> unlock ctx -> bind -> unlock key
- * - whoever do unlist should also do unbind:
- * - lock key -> lock ctx -> unlist -> unlock ctx -> unbind -> unlock key
- * - lock ctx -> unlist -> unlock ctx -> lock key -> unbind -> unlock key
- */
-
-static inline void spin_lock_if(spinlock_t *lock, int condition)
-{
- if (condition)
- spin_lock(lock);
-}
-
-static inline void spin_unlock_if(spinlock_t *lock, int condition)
-{
- if (condition)
- spin_unlock(lock);
-}
-
-static void ctx_enlist_kr(struct ptlrpc_cli_ctx *ctx, int is_root, int locked)
-{
- struct ptlrpc_sec *sec = ctx->cc_sec;
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
-
- LASSERT(!test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- spin_lock_if(&sec->ps_lock, !locked);
-
- atomic_inc(&ctx->cc_refcount);
- set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
- hlist_add_head(&ctx->cc_cache, &gsec_kr->gsk_clist);
- if (is_root)
- gsec_kr->gsk_root_ctx = ctx;
-
- spin_unlock_if(&sec->ps_lock, !locked);
-}
-
-/*
- * Note after this get called, caller should not access ctx again because
- * it might have been freed, unless caller hold at least one refcount of
- * the ctx.
- *
- * return non-zero if we indeed unlist this ctx.
- */
-static int ctx_unlist_kr(struct ptlrpc_cli_ctx *ctx, int locked)
-{
- struct ptlrpc_sec *sec = ctx->cc_sec;
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
-
- /* if hashed bit has gone, leave the job to somebody who is doing it */
- if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0)
- return 0;
-
- /* drop ref inside spin lock to prevent race with other operations */
- spin_lock_if(&sec->ps_lock, !locked);
-
- if (gsec_kr->gsk_root_ctx == ctx)
- gsec_kr->gsk_root_ctx = NULL;
- hlist_del_init(&ctx->cc_cache);
- atomic_dec(&ctx->cc_refcount);
-
- spin_unlock_if(&sec->ps_lock, !locked);
-
- return 1;
-}
-
-/*
- * bind a key with a ctx together.
- * caller must hold write lock of the key, as well as ref on key & ctx.
- */
-static void bind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx)
-{
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(atomic_read(&key->usage) > 0);
- LASSERT(ctx2gctx_keyring(ctx)->gck_key == NULL);
- LASSERT(key->payload.data == NULL);
-
- /* at this time context may or may not in list. */
- key_get(key);
- atomic_inc(&ctx->cc_refcount);
- ctx2gctx_keyring(ctx)->gck_key = key;
- key->payload.data = ctx;
-}
-
-/*
- * unbind a key and a ctx.
- * caller must hold write lock, as well as a ref of the key.
- */
-static void unbind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx)
-{
- LASSERT(key->payload.data == ctx);
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
-
- /* must revoke the key, or others may treat it as newly created */
- key_revoke_locked(key);
-
- key->payload.data = NULL;
- ctx2gctx_keyring(ctx)->gck_key = NULL;
-
- /* once ctx get split from key, the timer is meaningless */
- ctx_clear_timer_kr(ctx);
-
- ctx_put_kr(ctx, 1);
- key_put(key);
-}
-
-/*
- * given a ctx, unbind with its coupled key, if any.
- * unbind could only be called once, so we don't worry the key be released
- * by someone else.
- */
-static void unbind_ctx_kr(struct ptlrpc_cli_ctx *ctx)
-{
- struct key *key = ctx2gctx_keyring(ctx)->gck_key;
-
- if (key) {
- LASSERT(key->payload.data == ctx);
-
- key_get(key);
- down_write(&key->sem);
- unbind_key_ctx(key, ctx);
- up_write(&key->sem);
- key_put(key);
- }
-}
-
-/*
- * given a key, unbind with its coupled ctx, if any.
- * caller must hold write lock, as well as a ref of the key.
- */
-static void unbind_key_locked(struct key *key)
-{
- struct ptlrpc_cli_ctx *ctx = key->payload.data;
-
- if (ctx)
- unbind_key_ctx(key, ctx);
-}
-
-/*
- * unlist a ctx, and unbind from coupled key
- */
-static void kill_ctx_kr(struct ptlrpc_cli_ctx *ctx)
-{
- if (ctx_unlist_kr(ctx, 0))
- unbind_ctx_kr(ctx);
-}
-
-/*
- * given a key, unlist and unbind with the coupled ctx (if any).
- * caller must hold write lock, as well as a ref of the key.
- */
-static void kill_key_locked(struct key *key)
-{
- struct ptlrpc_cli_ctx *ctx = key->payload.data;
-
- if (ctx && ctx_unlist_kr(ctx, 0))
- unbind_key_locked(key);
-}
-
-/*
- * caller should hold one ref on contexts in freelist.
- */
-static void dispose_ctx_list_kr(struct hlist_head *freelist)
-{
- struct hlist_node *next;
- struct ptlrpc_cli_ctx *ctx;
- struct gss_cli_ctx *gctx;
-
- hlist_for_each_entry_safe(ctx, next, freelist, cc_cache) {
- hlist_del_init(&ctx->cc_cache);
-
- /* reverse ctx: update current seq to buddy svcctx if exist.
- * ideally this should be done at gss_cli_ctx_finalize(), but
- * the ctx destroy could be delayed by:
- * 1) ctx still has reference;
- * 2) ctx destroy is asynchronous;
- * and reverse import call inval_all_ctx() require this be done
- *_immediately_ otherwise newly created reverse ctx might copy
- * the very old sequence number from svcctx. */
- gctx = ctx2gctx(ctx);
- if (!rawobj_empty(&gctx->gc_svc_handle) &&
- sec_is_reverse(gctx->gc_base.cc_sec)) {
- gss_svc_upcall_update_sequence(&gctx->gc_svc_handle,
- (__u32) atomic_read(&gctx->gc_seq));
- }
-
- /* we need to wakeup waiting reqs here. the context might
- * be forced released before upcall finished, then the
- * late-arrived downcall can't find the ctx even. */
- sptlrpc_cli_ctx_wakeup(ctx);
-
- unbind_ctx_kr(ctx);
- ctx_put_kr(ctx, 0);
- }
-}
-
-/*
- * lookup a root context directly in a sec, return root ctx with a
- * reference taken or NULL.
- */
-static
-struct ptlrpc_cli_ctx * sec_lookup_root_ctx_kr(struct ptlrpc_sec *sec)
-{
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
- struct ptlrpc_cli_ctx *ctx = NULL;
-
- spin_lock(&sec->ps_lock);
-
- ctx = gsec_kr->gsk_root_ctx;
-
- if (ctx == NULL && unlikely(sec_is_reverse(sec))) {
- struct ptlrpc_cli_ctx *tmp;
-
- /* reverse ctx, search root ctx in list, choose the one
- * with shortest expire time, which is most possibly have
- * an established peer ctx at client side. */
- hlist_for_each_entry(tmp, &gsec_kr->gsk_clist, cc_cache) {
- if (ctx == NULL || ctx->cc_expire == 0 ||
- ctx->cc_expire > tmp->cc_expire) {
- ctx = tmp;
- /* promote to be root_ctx */
- gsec_kr->gsk_root_ctx = ctx;
- }
- }
- }
-
- if (ctx) {
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(!hlist_empty(&gsec_kr->gsk_clist));
- atomic_inc(&ctx->cc_refcount);
- }
-
- spin_unlock(&sec->ps_lock);
-
- return ctx;
-}
-
-#define RVS_CTX_EXPIRE_NICE (10)
-
-static
-void rvs_sec_install_root_ctx_kr(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *new_ctx,
- struct key *key)
-{
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
- struct ptlrpc_cli_ctx *ctx;
- cfs_time_t now;
-
- LASSERT(sec_is_reverse(sec));
-
- spin_lock(&sec->ps_lock);
-
- now = cfs_time_current_sec();
-
- /* set all existing ctxs short expiry */
- hlist_for_each_entry(ctx, &gsec_kr->gsk_clist, cc_cache) {
- if (ctx->cc_expire > now + RVS_CTX_EXPIRE_NICE) {
- ctx->cc_early_expire = 1;
- ctx->cc_expire = now + RVS_CTX_EXPIRE_NICE;
- }
- }
-
- /* if there's root_ctx there, instead obsolete the current
- * immediately, we leave it continue operating for a little while.
- * hopefully when the first backward rpc with newest ctx send out,
- * the client side already have the peer ctx well established. */
- ctx_enlist_kr(new_ctx, gsec_kr->gsk_root_ctx ? 0 : 1, 1);
-
- if (key)
- bind_key_ctx(key, new_ctx);
-
- spin_unlock(&sec->ps_lock);
-}
-
-static void construct_key_desc(void *buf, int bufsize,
- struct ptlrpc_sec *sec, uid_t uid)
-{
- snprintf(buf, bufsize, "%d@%x", uid, sec->ps_id);
- ((char *)buf)[bufsize - 1] = '\0';
-}
-
-/****************************************
- * sec apis *
- ****************************************/
-
-static
-struct ptlrpc_sec * gss_sec_create_kr(struct obd_import *imp,
- struct ptlrpc_svc_ctx *svcctx,
- struct sptlrpc_flavor *sf)
-{
- struct gss_sec_keyring *gsec_kr;
-
- OBD_ALLOC(gsec_kr, sizeof(*gsec_kr));
- if (gsec_kr == NULL)
- return NULL;
-
- INIT_HLIST_HEAD(&gsec_kr->gsk_clist);
- gsec_kr->gsk_root_ctx = NULL;
- mutex_init(&gsec_kr->gsk_root_uc_lock);
-#ifdef HAVE_KEYRING_UPCALL_SERIALIZED
- mutex_init(&gsec_kr->gsk_uc_lock);
-#endif
-
- if (gss_sec_create_common(&gsec_kr->gsk_base, &gss_policy_keyring,
- imp, svcctx, sf))
- goto err_free;
-
- if (svcctx != NULL &&
- sec_install_rctx_kr(&gsec_kr->gsk_base.gs_base, svcctx)) {
- gss_sec_destroy_common(&gsec_kr->gsk_base);
- goto err_free;
- }
-
- return &gsec_kr->gsk_base.gs_base;
-
-err_free:
- OBD_FREE(gsec_kr, sizeof(*gsec_kr));
- return NULL;
-}
-
-static
-void gss_sec_destroy_kr(struct ptlrpc_sec *sec)
-{
- struct gss_sec *gsec = sec2gsec(sec);
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
-
- CDEBUG(D_SEC, "destroy %s@%p\n", sec->ps_policy->sp_name, sec);
-
- LASSERT(hlist_empty(&gsec_kr->gsk_clist));
- LASSERT(gsec_kr->gsk_root_ctx == NULL);
-
- gss_sec_destroy_common(gsec);
-
- OBD_FREE(gsec_kr, sizeof(*gsec_kr));
-}
-
-static inline int user_is_root(struct ptlrpc_sec *sec, struct vfs_cred *vcred)
-{
- /* except the ROOTONLY flag, treat it as root user only if real uid
- * is 0, euid/fsuid being 0 are handled as setuid scenarios */
- if (sec_is_rootonly(sec) || (vcred->vc_uid == 0))
- return 1;
- else
- return 0;
-}
-
-/*
- * unlink request key from it's ring, which is linked during request_key().
- * sadly, we have to 'guess' which keyring it's linked to.
- *
- * FIXME this code is fragile, depend on how request_key_link() is implemented.
- */
-static void request_key_unlink(struct key *key)
-{
- struct task_struct *tsk = current;
- struct key *ring;
-
- switch (key_cred(tsk)->jit_keyring) {
- case KEY_REQKEY_DEFL_DEFAULT:
- case KEY_REQKEY_DEFL_THREAD_KEYRING:
- ring = key_get(key_cred(tsk)->thread_keyring);
- if (ring)
- break;
- case KEY_REQKEY_DEFL_PROCESS_KEYRING:
- ring = key_get(key_tgcred(tsk)->process_keyring);
- if (ring)
- break;
- case KEY_REQKEY_DEFL_SESSION_KEYRING:
- rcu_read_lock();
- ring = key_get(rcu_dereference(key_tgcred(tsk)
- ->session_keyring));
- rcu_read_unlock();
- if (ring)
- break;
- case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
- ring = key_get(key_cred(tsk)->user->session_keyring);
- break;
- case KEY_REQKEY_DEFL_USER_KEYRING:
- ring = key_get(key_cred(tsk)->user->uid_keyring);
- break;
- case KEY_REQKEY_DEFL_GROUP_KEYRING:
- default:
- LBUG();
- }
-
- LASSERT(ring);
- key_unlink(ring, key);
- key_put(ring);
-}
-
-static
-struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_kr(struct ptlrpc_sec *sec,
- struct vfs_cred *vcred,
- int create, int remove_dead)
-{
- struct obd_import *imp = sec->ps_import;
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
- struct ptlrpc_cli_ctx *ctx = NULL;
- unsigned int is_root = 0, create_new = 0;
- struct key *key;
- char desc[24];
- char *coinfo;
- int coinfo_size;
- char *co_flags = "";
-
- LASSERT(imp != NULL);
-
- is_root = user_is_root(sec, vcred);
-
- /* a little bit optimization for root context */
- if (is_root) {
- ctx = sec_lookup_root_ctx_kr(sec);
- /*
- * Only lookup directly for REVERSE sec, which should
- * always succeed.
- */
- if (ctx || sec_is_reverse(sec))
- return ctx;
- }
-
- LASSERT(create != 0);
-
- /* for root context, obtain lock and check again, this time hold
- * the root upcall lock, make sure nobody else populated new root
- * context after last check. */
- if (is_root) {
- mutex_lock(&gsec_kr->gsk_root_uc_lock);
-
- ctx = sec_lookup_root_ctx_kr(sec);
- if (ctx)
- goto out;
-
- /* update reverse handle for root user */
- sec2gsec(sec)->gs_rvs_hdl = gss_get_next_ctx_index();
-
- switch (sec->ps_part) {
- case LUSTRE_SP_MDT:
- co_flags = "m";
- break;
- case LUSTRE_SP_OST:
- co_flags = "o";
- break;
- case LUSTRE_SP_MGC:
- co_flags = "rmo";
- break;
- case LUSTRE_SP_CLI:
- co_flags = "r";
- break;
- case LUSTRE_SP_MGS:
- default:
- LBUG();
- }
- }
-
- /* in case of setuid, key will be constructed as owner of fsuid/fsgid,
- * but we do authentication based on real uid/gid. the key permission
- * bits will be exactly as POS_ALL, so only processes who subscribed
- * this key could have the access, although the quota might be counted
- * on others (fsuid/fsgid).
- *
- * keyring will use fsuid/fsgid as upcall parameters, so we have to
- * encode real uid/gid into callout info.
- */
-
- construct_key_desc(desc, sizeof(desc), sec, vcred->vc_uid);
-
- /* callout info format:
- * secid:mech:uid:gid:flags:svc_type:peer_nid:target_uuid
- */
- coinfo_size = sizeof(struct obd_uuid) + MAX_OBD_NAME + 64;
- OBD_ALLOC(coinfo, coinfo_size);
- if (coinfo == NULL)
- goto out;
-
- snprintf(coinfo, coinfo_size, "%d:%s:%u:%u:%s:%d:"LPX64":%s",
- sec->ps_id, sec2gsec(sec)->gs_mech->gm_name,
- vcred->vc_uid, vcred->vc_gid,
- co_flags, import_to_gss_svc(imp),
- imp->imp_connection->c_peer.nid, imp->imp_obd->obd_name);
-
- CDEBUG(D_SEC, "requesting key for %s\n", desc);
-
- keyring_upcall_lock(gsec_kr);
- key = request_key(&gss_key_type, desc, coinfo);
- keyring_upcall_unlock(gsec_kr);
-
- OBD_FREE(coinfo, coinfo_size);
-
- if (IS_ERR(key)) {
- CERROR("failed request key: %ld\n", PTR_ERR(key));
- goto out;
- }
- CDEBUG(D_SEC, "obtained key %08x for %s\n", key->serial, desc);
-
- /* once payload.data was pointed to a ctx, it never changes until
- * we de-associate them; but parallel request_key() may return
- * a key with payload.data == NULL at the same time. so we still
- * need wirtelock of key->sem to serialize them. */
- down_write(&key->sem);
-
- if (likely(key->payload.data != NULL)) {
- ctx = key->payload.data;
-
- LASSERT(atomic_read(&ctx->cc_refcount) >= 1);
- LASSERT(ctx2gctx_keyring(ctx)->gck_key == key);
- LASSERT(atomic_read(&key->usage) >= 2);
-
- /* simply take a ref and return. it's upper layer's
- * responsibility to detect & replace dead ctx. */
- atomic_inc(&ctx->cc_refcount);
- } else {
- /* pre initialization with a cli_ctx. this can't be done in
- * key_instantiate() because we'v no enough information
- * there. */
- ctx = ctx_create_kr(sec, vcred);
- if (ctx != NULL) {
- ctx_enlist_kr(ctx, is_root, 0);
- bind_key_ctx(key, ctx);
-
- ctx_start_timer_kr(ctx, KEYRING_UPCALL_TIMEOUT);
-
- CDEBUG(D_SEC, "installed key %p <-> ctx %p (sec %p)\n",
- key, ctx, sec);
- } else {
- /* we'd prefer to call key_revoke(), but we more like
- * to revoke it within this key->sem locked period. */
- key_revoke_locked(key);
- }
-
- create_new = 1;
- }
-
- up_write(&key->sem);
-
- if (is_root && create_new)
- request_key_unlink(key);
-
- key_put(key);
-out:
- if (is_root)
- mutex_unlock(&gsec_kr->gsk_root_uc_lock);
- return ctx;
-}
-
-static
-void gss_sec_release_ctx_kr(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx,
- int sync)
-{
- LASSERT(atomic_read(&sec->ps_refcount) > 0);
- LASSERT(atomic_read(&ctx->cc_refcount) == 0);
- ctx_release_kr(ctx, sync);
-}
-
-/*
- * flush context of normal user, we must resort to keyring itself to find out
- * contexts which belong to me.
- *
- * Note here we suppose only to flush _my_ context, the "uid" will
- * be ignored in the search.
- */
-static
-void flush_user_ctx_cache_kr(struct ptlrpc_sec *sec,
- uid_t uid,
- int grace, int force)
-{
- struct key *key;
- char desc[24];
-
- /* nothing to do for reverse or rootonly sec */
- if (sec_is_reverse(sec) || sec_is_rootonly(sec))
- return;
-
- construct_key_desc(desc, sizeof(desc), sec, uid);
-
- /* there should be only one valid key, but we put it in the
- * loop in case of any weird cases */
- for (;;) {
- key = request_key(&gss_key_type, desc, NULL);
- if (IS_ERR(key)) {
- CDEBUG(D_SEC, "No more key found for current user\n");
- break;
- }
-
- down_write(&key->sem);
-
- kill_key_locked(key);
-
- /* kill_key_locked() should usually revoke the key, but we
- * revoke it again to make sure, e.g. some case the key may
- * not well coupled with a context. */
- key_revoke_locked(key);
-
- up_write(&key->sem);
-
- key_put(key);
- }
-}
-
-/*
- * flush context of root or all, we iterate through the list.
- */
-static
-void flush_spec_ctx_cache_kr(struct ptlrpc_sec *sec,
- uid_t uid,
- int grace, int force)
-{
- struct gss_sec_keyring *gsec_kr;
- struct hlist_head freelist = HLIST_HEAD_INIT;
- struct hlist_node *next;
- struct ptlrpc_cli_ctx *ctx;
-
- gsec_kr = sec2gsec_keyring(sec);
-
- spin_lock(&sec->ps_lock);
- hlist_for_each_entry_safe(ctx, next,
- &gsec_kr->gsk_clist, cc_cache) {
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
- continue;
-
- /* at this moment there's at least 2 base reference:
- * key association and in-list. */
- if (atomic_read(&ctx->cc_refcount) > 2) {
- if (!force)
- continue;
- CWARN("flush busy ctx %p(%u->%s, extra ref %d)\n",
- ctx, ctx->cc_vcred.vc_uid,
- sec2target_str(ctx->cc_sec),
- atomic_read(&ctx->cc_refcount) - 2);
- }
-
- set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags);
- if (!grace)
- clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
-
- atomic_inc(&ctx->cc_refcount);
-
- if (ctx_unlist_kr(ctx, 1)) {
- hlist_add_head(&ctx->cc_cache, &freelist);
- } else {
- LASSERT(atomic_read(&ctx->cc_refcount) >= 2);
- atomic_dec(&ctx->cc_refcount);
- }
- }
- spin_unlock(&sec->ps_lock);
-
- dispose_ctx_list_kr(&freelist);
-}
-
-static
-int gss_sec_flush_ctx_cache_kr(struct ptlrpc_sec *sec,
- uid_t uid, int grace, int force)
-{
- CDEBUG(D_SEC, "sec %p(%d, nctx %d), uid %d, grace %d, force %d\n",
- sec, atomic_read(&sec->ps_refcount),
- atomic_read(&sec->ps_nctx),
- uid, grace, force);
-
- if (uid != -1 && uid != 0)
- flush_user_ctx_cache_kr(sec, uid, grace, force);
- else
- flush_spec_ctx_cache_kr(sec, uid, grace, force);
-
- return 0;
-}
-
-static
-void gss_sec_gc_ctx_kr(struct ptlrpc_sec *sec)
-{
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
- struct hlist_head freelist = HLIST_HEAD_INIT;
- struct hlist_node *next;
- struct ptlrpc_cli_ctx *ctx;
-
- CWARN("running gc\n");
-
- spin_lock(&sec->ps_lock);
- hlist_for_each_entry_safe(ctx, next,
- &gsec_kr->gsk_clist, cc_cache) {
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- atomic_inc(&ctx->cc_refcount);
-
- if (cli_ctx_check_death(ctx) && ctx_unlist_kr(ctx, 1)) {
- hlist_add_head(&ctx->cc_cache, &freelist);
- CWARN("unhashed ctx %p\n", ctx);
- } else {
- LASSERT(atomic_read(&ctx->cc_refcount) >= 2);
- atomic_dec(&ctx->cc_refcount);
- }
- }
- spin_unlock(&sec->ps_lock);
-
- dispose_ctx_list_kr(&freelist);
-}
-
-static
-int gss_sec_display_kr(struct ptlrpc_sec *sec, struct seq_file *seq)
-{
- struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
- struct hlist_node *next;
- struct ptlrpc_cli_ctx *ctx;
- struct gss_cli_ctx *gctx;
- time_t now = cfs_time_current_sec();
-
- spin_lock(&sec->ps_lock);
- hlist_for_each_entry_safe(ctx, next,
- &gsec_kr->gsk_clist, cc_cache) {
- struct key *key;
- char flags_str[40];
- char mech[40];
-
- gctx = ctx2gctx(ctx);
- key = ctx2gctx_keyring(ctx)->gck_key;
-
- gss_cli_ctx_flags2str(ctx->cc_flags,
- flags_str, sizeof(flags_str));
-
- if (gctx->gc_mechctx)
- lgss_display(gctx->gc_mechctx, mech, sizeof(mech));
- else
- snprintf(mech, sizeof(mech), "N/A");
- mech[sizeof(mech) - 1] = '\0';
-
- seq_printf(seq, "%p: uid %u, ref %d, expire %ld(%+ld), fl %s, "
- "seq %d, win %u, key %08x(ref %d), "
- "hdl "LPX64":"LPX64", mech: %s\n",
- ctx, ctx->cc_vcred.vc_uid,
- atomic_read(&ctx->cc_refcount),
- ctx->cc_expire,
- ctx->cc_expire ? ctx->cc_expire - now : 0,
- flags_str,
- atomic_read(&gctx->gc_seq),
- gctx->gc_win,
- key ? key->serial : 0,
- key ? atomic_read(&key->usage) : 0,
- gss_handle_to_u64(&gctx->gc_handle),
- gss_handle_to_u64(&gctx->gc_svc_handle),
- mech);
- }
- spin_unlock(&sec->ps_lock);
-
- return 0;
-}
-
-/****************************************
- * cli_ctx apis *
- ****************************************/
-
-static
-int gss_cli_ctx_refresh_kr(struct ptlrpc_cli_ctx *ctx)
-{
- /* upcall is already on the way */
- return 0;
-}
-
-static
-int gss_cli_ctx_validate_kr(struct ptlrpc_cli_ctx *ctx)
-{
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(ctx->cc_sec);
-
- if (cli_ctx_check_death(ctx)) {
- kill_ctx_kr(ctx);
- return 1;
- }
-
- if (cli_ctx_is_ready(ctx))
- return 0;
- return 1;
-}
-
-static
-void gss_cli_ctx_die_kr(struct ptlrpc_cli_ctx *ctx, int grace)
-{
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(ctx->cc_sec);
-
- cli_ctx_expire(ctx);
- kill_ctx_kr(ctx);
-}
-
-/****************************************
- * (reverse) service *
- ****************************************/
-
-/*
- * reverse context could have nothing to do with keyrings. here we still keep
- * the version which bind to a key, for future reference.
- */
-#define HAVE_REVERSE_CTX_NOKEY
-
-
-static
-int sec_install_rctx_kr(struct ptlrpc_sec *sec,
- struct ptlrpc_svc_ctx *svc_ctx)
-{
- struct ptlrpc_cli_ctx *cli_ctx;
- struct vfs_cred vcred = { 0, 0 };
- int rc;
-
- LASSERT(sec);
- LASSERT(svc_ctx);
-
- cli_ctx = ctx_create_kr(sec, &vcred);
- if (cli_ctx == NULL)
- return -ENOMEM;
-
- rc = gss_copy_rvc_cli_ctx(cli_ctx, svc_ctx);
- if (rc) {
- CERROR("failed copy reverse cli ctx: %d\n", rc);
-
- ctx_put_kr(cli_ctx, 1);
- return rc;
- }
-
- rvs_sec_install_root_ctx_kr(sec, cli_ctx, NULL);
-
- ctx_put_kr(cli_ctx, 1);
-
- return 0;
-}
-
-
-/****************************************
- * service apis *
- ****************************************/
-
-static
-int gss_svc_accept_kr(struct ptlrpc_request *req)
-{
- return gss_svc_accept(&gss_policy_keyring, req);
-}
-
-static
-int gss_svc_install_rctx_kr(struct obd_import *imp,
- struct ptlrpc_svc_ctx *svc_ctx)
-{
- struct ptlrpc_sec *sec;
- int rc;
-
- sec = sptlrpc_import_sec_ref(imp);
- LASSERT(sec);
-
- rc = sec_install_rctx_kr(sec, svc_ctx);
- sptlrpc_sec_put(sec);
-
- return rc;
-}
-
-/****************************************
- * key apis *
- ****************************************/
-
-static
-int gss_kt_instantiate(struct key *key, const void *data, size_t datalen)
-{
- int rc;
-
- if (data != NULL || datalen != 0) {
- CERROR("invalid: data %p, len %lu\n", data, (long)datalen);
- return -EINVAL;
- }
-
- if (key->payload.data != 0) {
- CERROR("key already have payload\n");
- return -EINVAL;
- }
-
- /* link the key to session keyring, so following context negotiation
- * rpc fired from user space could find this key. This will be unlinked
- * automatically when upcall processes die.
- *
- * we can't do this through keyctl from userspace, because the upcall
- * might be neither possessor nor owner of the key (setuid).
- *
- * the session keyring is created upon upcall, and don't change all
- * the way until upcall finished, so rcu lock is not needed here.
- */
- LASSERT(key_tgcred(current)->session_keyring);
-
- lockdep_off();
- rc = key_link(key_tgcred(current)->session_keyring, key);
- lockdep_on();
- if (unlikely(rc)) {
- CERROR("failed to link key %08x to keyring %08x: %d\n",
- key->serial,
- key_tgcred(current)->session_keyring->serial, rc);
- return rc;
- }
-
- CDEBUG(D_SEC, "key %p instantiated, ctx %p\n", key, key->payload.data);
- return 0;
-}
-
-/*
- * called with key semaphore write locked. it means we can operate
- * on the context without fear of losing refcount.
- */
-static
-int gss_kt_update(struct key *key, const void *data, size_t datalen)
-{
- struct ptlrpc_cli_ctx *ctx = key->payload.data;
- struct gss_cli_ctx *gctx;
- rawobj_t tmpobj = RAWOBJ_EMPTY;
- __u32 datalen32 = (__u32) datalen;
- int rc;
-
- if (data == NULL || datalen == 0) {
- CWARN("invalid: data %p, len %lu\n", data, (long)datalen);
- return -EINVAL;
- }
-
- /* if upcall finished negotiation too fast (mostly likely because
- * of local error happened) and call kt_update(), the ctx
- * might be still NULL. but the key will finally be associate
- * with a context, or be revoked. if key status is fine, return
- * -EAGAIN to allow userspace sleep a while and call again. */
- if (ctx == NULL) {
- CDEBUG(D_SEC, "update too soon: key %p(%x) flags %lx\n",
- key, key->serial, key->flags);
-
- rc = key_validate(key);
- if (rc == 0)
- return -EAGAIN;
- else
- return rc;
- }
-
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(ctx->cc_sec);
-
- ctx_clear_timer_kr(ctx);
-
- /* don't proceed if already refreshed */
- if (cli_ctx_is_refreshed(ctx)) {
- CWARN("ctx already done refresh\n");
- return 0;
- }
-
- sptlrpc_cli_ctx_get(ctx);
- gctx = ctx2gctx(ctx);
-
- rc = buffer_extract_bytes(&data, &datalen32, &gctx->gc_win,
- sizeof(gctx->gc_win));
- if (rc) {
- CERROR("failed extract seq_win\n");
- goto out;
- }
-
- if (gctx->gc_win == 0) {
- __u32 nego_rpc_err, nego_gss_err;
-
- rc = buffer_extract_bytes(&data, &datalen32, &nego_rpc_err,
- sizeof(nego_rpc_err));
- if (rc) {
- CERROR("failed to extrace rpc rc\n");
- goto out;
- }
-
- rc = buffer_extract_bytes(&data, &datalen32, &nego_gss_err,
- sizeof(nego_gss_err));
- if (rc) {
- CERROR("failed to extrace gss rc\n");
- goto out;
- }
-
- CERROR("negotiation: rpc err %d, gss err %x\n",
- nego_rpc_err, nego_gss_err);
-
- rc = nego_rpc_err ? nego_rpc_err : -EACCES;
- } else {
- rc = rawobj_extract_local_alloc(&gctx->gc_handle,
- (__u32 **) &data, &datalen32);
- if (rc) {
- CERROR("failed extract handle\n");
- goto out;
- }
-
- rc = rawobj_extract_local(&tmpobj, (__u32 **) &data,&datalen32);
- if (rc) {
- CERROR("failed extract mech\n");
- goto out;
- }
-
- rc = lgss_import_sec_context(&tmpobj,
- sec2gsec(ctx->cc_sec)->gs_mech,
- &gctx->gc_mechctx);
- if (rc != GSS_S_COMPLETE)
- CERROR("failed import context\n");
- else
- rc = 0;
- }
-out:
- /* we don't care what current status of this ctx, even someone else
- * is operating on the ctx at the same time. we just add up our own
- * opinions here. */
- if (rc == 0) {
- gss_cli_ctx_uptodate(gctx);
- } else {
- /* this will also revoke the key. has to be done before
- * wakeup waiters otherwise they can find the stale key */
- kill_key_locked(key);
-
- cli_ctx_expire(ctx);
-
- if (rc != -ERESTART)
- set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
- }
-
- /* let user space think it's a success */
- sptlrpc_cli_ctx_put(ctx, 1);
- return 0;
-}
-
-static
-int gss_kt_match(const struct key *key, const void *desc)
-{
- return (strcmp(key->description, (const char *) desc) == 0);
-}
-
-static
-void gss_kt_destroy(struct key *key)
-{
- LASSERT(key->payload.data == NULL);
- CDEBUG(D_SEC, "destroy key %p\n", key);
-}
-
-static
-void gss_kt_describe(const struct key *key, struct seq_file *s)
-{
- if (key->description == NULL)
- seq_puts(s, "[null]");
- else
- seq_puts(s, key->description);
-}
-
-static struct key_type gss_key_type =
-{
- .name = "lgssc",
- .def_datalen = 0,
- .instantiate = gss_kt_instantiate,
- .update = gss_kt_update,
- .match = gss_kt_match,
- .destroy = gss_kt_destroy,
- .describe = gss_kt_describe,
-};
-
-/****************************************
- * lustre gss keyring policy *
- ****************************************/
-
-static struct ptlrpc_ctx_ops gss_keyring_ctxops = {
- .match = gss_cli_ctx_match,
- .refresh = gss_cli_ctx_refresh_kr,
- .validate = gss_cli_ctx_validate_kr,
- .die = gss_cli_ctx_die_kr,
- .sign = gss_cli_ctx_sign,
- .verify = gss_cli_ctx_verify,
- .seal = gss_cli_ctx_seal,
- .unseal = gss_cli_ctx_unseal,
- .wrap_bulk = gss_cli_ctx_wrap_bulk,
- .unwrap_bulk = gss_cli_ctx_unwrap_bulk,
-};
-
-static struct ptlrpc_sec_cops gss_sec_keyring_cops = {
- .create_sec = gss_sec_create_kr,
- .destroy_sec = gss_sec_destroy_kr,
- .kill_sec = gss_sec_kill,
- .lookup_ctx = gss_sec_lookup_ctx_kr,
- .release_ctx = gss_sec_release_ctx_kr,
- .flush_ctx_cache = gss_sec_flush_ctx_cache_kr,
- .gc_ctx = gss_sec_gc_ctx_kr,
- .install_rctx = gss_sec_install_rctx,
- .alloc_reqbuf = gss_alloc_reqbuf,
- .free_reqbuf = gss_free_reqbuf,
- .alloc_repbuf = gss_alloc_repbuf,
- .free_repbuf = gss_free_repbuf,
- .enlarge_reqbuf = gss_enlarge_reqbuf,
- .display = gss_sec_display_kr,
-};
-
-static struct ptlrpc_sec_sops gss_sec_keyring_sops = {
- .accept = gss_svc_accept_kr,
- .invalidate_ctx = gss_svc_invalidate_ctx,
- .alloc_rs = gss_svc_alloc_rs,
- .authorize = gss_svc_authorize,
- .free_rs = gss_svc_free_rs,
- .free_ctx = gss_svc_free_ctx,
- .prep_bulk = gss_svc_prep_bulk,
- .unwrap_bulk = gss_svc_unwrap_bulk,
- .wrap_bulk = gss_svc_wrap_bulk,
- .install_rctx = gss_svc_install_rctx_kr,
-};
-
-static struct ptlrpc_sec_policy gss_policy_keyring = {
- .sp_owner = THIS_MODULE,
- .sp_name = "gss.keyring",
- .sp_policy = SPTLRPC_POLICY_GSS,
- .sp_cops = &gss_sec_keyring_cops,
- .sp_sops = &gss_sec_keyring_sops,
-};
-
-
-int __init gss_init_keyring(void)
-{
- int rc;
-
- rc = register_key_type(&gss_key_type);
- if (rc) {
- CERROR("failed to register keyring type: %d\n", rc);
- return rc;
- }
-
- rc = sptlrpc_register_policy(&gss_policy_keyring);
- if (rc) {
- unregister_key_type(&gss_key_type);
- return rc;
- }
-
- return 0;
-}
-
-void __exit gss_exit_keyring(void)
-{
- unregister_key_type(&gss_key_type);
- sptlrpc_unregister_policy(&gss_policy_keyring);
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5.h b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5.h
deleted file mode 100644
index 676d4b96311a..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/include/linux/sunrpc/gss_krb5_types.h
- *
- * Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
- * lib/gssapi/krb5/gssapiP_krb5.h, and others
- *
- * Copyright (c) 2000 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Andy Adamson <andros@umich.edu>
- * Bruce Fields <bfields@umich.edu>
- */
-
-/*
- * Copyright 1995 by the Massachusetts Institute of Technology.
- * All Rights Reserved.
- *
- * Export of this software from the United States of America may
- * require a specific license from the United States Government.
- * It is the responsibility of any person or organization contemplating
- * export to obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of M.I.T. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. Furthermore if you modify this software you must label
- * your software as modified software and not distribute it in such a
- * fashion that it might be confused with the original M.I.T. software.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- */
-
-#ifndef PTLRPC_GSS_KRB5_H
-#define PTLRPC_GSS_KRB5_H
-
-/*
- * RFC 4142
- */
-
-#define KG_USAGE_ACCEPTOR_SEAL 22
-#define KG_USAGE_ACCEPTOR_SIGN 23
-#define KG_USAGE_INITIATOR_SEAL 24
-#define KG_USAGE_INITIATOR_SIGN 25
-
-#define KG_TOK_MIC_MSG 0x0404
-#define KG_TOK_WRAP_MSG 0x0504
-
-#define FLAG_SENDER_IS_ACCEPTOR 0x01
-#define FLAG_WRAP_CONFIDENTIAL 0x02
-#define FLAG_ACCEPTOR_SUBKEY 0x04
-
-struct krb5_header {
- __u16 kh_tok_id; /* token id */
- __u8 kh_flags; /* acceptor flags */
- __u8 kh_filler; /* 0xff */
- __u16 kh_ec; /* extra count */
- __u16 kh_rrc; /* right rotation count */
- __u64 kh_seq; /* sequence number */
- __u8 kh_cksum[0]; /* checksum */
-};
-
-struct krb5_keyblock {
- rawobj_t kb_key;
- struct ll_crypto_cipher *kb_tfm;
-};
-
-struct krb5_ctx {
- unsigned int kc_initiate:1,
- kc_cfx:1,
- kc_seed_init:1,
- kc_have_acceptor_subkey:1;
- __s32 kc_endtime;
- __u8 kc_seed[16];
- __u64 kc_seq_send;
- __u64 kc_seq_recv;
- __u32 kc_enctype;
- struct krb5_keyblock kc_keye; /* encryption */
- struct krb5_keyblock kc_keyi; /* integrity */
- struct krb5_keyblock kc_keyc; /* checksum */
- rawobj_t kc_mech_used;
-};
-
-enum sgn_alg {
- SGN_ALG_DES_MAC_MD5 = 0x0000,
- SGN_ALG_MD2_5 = 0x0001,
- SGN_ALG_DES_MAC = 0x0002,
- SGN_ALG_3 = 0x0003, /* not published */
- SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
- SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
-};
-
-enum seal_alg {
- SEAL_ALG_NONE = 0xffff,
- SEAL_ALG_DES = 0x0000,
- SEAL_ALG_1 = 0x0001, /* not published */
- SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
- SEAL_ALG_DES3KD = 0x0002
-};
-
-#define CKSUMTYPE_CRC32 0x0001
-#define CKSUMTYPE_RSA_MD4 0x0002
-#define CKSUMTYPE_RSA_MD4_DES 0x0003
-#define CKSUMTYPE_DESCBC 0x0004
-/* des-mac-k */
-/* rsa-md4-des-k */
-#define CKSUMTYPE_RSA_MD5 0x0007
-#define CKSUMTYPE_RSA_MD5_DES 0x0008
-#define CKSUMTYPE_NIST_SHA 0x0009
-#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
-#define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f
-#define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010
-#define CKSUMTYPE_HMAC_MD5_ARCFOUR -138
-
-/* from gssapi_err_krb5.h */
-#define KG_CCACHE_NOMATCH (39756032L)
-#define KG_KEYTAB_NOMATCH (39756033L)
-#define KG_TGT_MISSING (39756034L)
-#define KG_NO_SUBKEY (39756035L)
-#define KG_CONTEXT_ESTABLISHED (39756036L)
-#define KG_BAD_SIGN_TYPE (39756037L)
-#define KG_BAD_LENGTH (39756038L)
-#define KG_CTX_INCOMPLETE (39756039L)
-#define KG_CONTEXT (39756040L)
-#define KG_CRED (39756041L)
-#define KG_ENC_DESC (39756042L)
-#define KG_BAD_SEQ (39756043L)
-#define KG_EMPTY_CCACHE (39756044L)
-#define KG_NO_CTYPES (39756045L)
-
-/* per Kerberos v5 protocol spec crypto types from the wire.
- * these get mapped to linux kernel crypto routines.
- */
-#define ENCTYPE_NULL 0x0000
-#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
-#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
-#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
-#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
-/* XXX deprecated? */
-#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
-#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
-#define ENCTYPE_DES_HMAC_SHA1 0x0008
-#define ENCTYPE_DES3_CBC_SHA1 0x0010
-#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
-#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
-#define ENCTYPE_ARCFOUR_HMAC 0x0017
-#define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018
-#define ENCTYPE_UNKNOWN 0x01ff
-
-#endif /* PTLRPC_GSS_KRB5_H */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c
deleted file mode 100644
index d03f6c114171..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_krb5_mech.c
+++ /dev/null
@@ -1,1786 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/net/sunrpc/gss_krb5_mech.c
- * linux/net/sunrpc/gss_krb5_crypto.c
- * linux/net/sunrpc/gss_krb5_seal.c
- * linux/net/sunrpc/gss_krb5_seqnum.c
- * linux/net/sunrpc/gss_krb5_unseal.c
- *
- * Copyright (c) 2001 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Andy Adamson <andros@umich.edu>
- * J. Bruce Fields <bfields@umich.edu>
- *
- * 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 name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
- *
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/crypto.h>
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-#include "gss_asn1.h"
-#include "gss_krb5.h"
-
-static spinlock_t krb5_seq_lock;
-
-struct krb5_enctype {
- char *ke_dispname;
- char *ke_enc_name; /* linux tfm name */
- char *ke_hash_name; /* linux tfm name */
- int ke_enc_mode; /* linux tfm mode */
- int ke_hash_size; /* checksum size */
- int ke_conf_size; /* confounder size */
- unsigned int ke_hash_hmac:1; /* is hmac? */
-};
-
-/*
- * NOTE: for aes128-cts and aes256-cts, MIT implementation use CTS encryption.
- * but currently we simply CBC with padding, because linux doesn't support CTS
- * yet. this need to be fixed in the future.
- */
-static struct krb5_enctype enctypes[] = {
- [ENCTYPE_DES_CBC_RAW] = { /* des-cbc-md5 */
- "des-cbc-md5",
- "cbc(des)",
- "md5",
- 0,
- 16,
- 8,
- 0,
- },
- [ENCTYPE_DES3_CBC_RAW] = { /* des3-hmac-sha1 */
- "des3-hmac-sha1",
- "cbc(des3_ede)",
- "hmac(sha1)",
- 0,
- 20,
- 8,
- 1,
- },
- [ENCTYPE_AES128_CTS_HMAC_SHA1_96] = { /* aes128-cts */
- "aes128-cts-hmac-sha1-96",
- "cbc(aes)",
- "hmac(sha1)",
- 0,
- 12,
- 16,
- 1,
- },
- [ENCTYPE_AES256_CTS_HMAC_SHA1_96] = { /* aes256-cts */
- "aes256-cts-hmac-sha1-96",
- "cbc(aes)",
- "hmac(sha1)",
- 0,
- 12,
- 16,
- 1,
- },
- [ENCTYPE_ARCFOUR_HMAC] = { /* arcfour-hmac-md5 */
- "arcfour-hmac-md5",
- "ecb(arc4)",
- "hmac(md5)",
- 0,
- 16,
- 8,
- 1,
- },
-};
-
-#define MAX_ENCTYPES sizeof(enctypes)/sizeof(struct krb5_enctype)
-
-static const char * enctype2str(__u32 enctype)
-{
- if (enctype < MAX_ENCTYPES && enctypes[enctype].ke_dispname)
- return enctypes[enctype].ke_dispname;
-
- return "unknown";
-}
-
-static
-int keyblock_init(struct krb5_keyblock *kb, char *alg_name, int alg_mode)
-{
- kb->kb_tfm = crypto_alloc_blkcipher(alg_name, alg_mode, 0);
- if (IS_ERR(kb->kb_tfm)) {
- CERROR("failed to alloc tfm: %s, mode %d\n",
- alg_name, alg_mode);
- return -1;
- }
-
- if (crypto_blkcipher_setkey(kb->kb_tfm, kb->kb_key.data, kb->kb_key.len)) {
- CERROR("failed to set %s key, len %d\n",
- alg_name, kb->kb_key.len);
- return -1;
- }
-
- return 0;
-}
-
-static
-int krb5_init_keys(struct krb5_ctx *kctx)
-{
- struct krb5_enctype *ke;
-
- if (kctx->kc_enctype >= MAX_ENCTYPES ||
- enctypes[kctx->kc_enctype].ke_hash_size == 0) {
- CERROR("unsupported enctype %x\n", kctx->kc_enctype);
- return -1;
- }
-
- ke = &enctypes[kctx->kc_enctype];
-
- /* tfm arc4 is stateful, user should alloc-use-free by his own */
- if (kctx->kc_enctype != ENCTYPE_ARCFOUR_HMAC &&
- keyblock_init(&kctx->kc_keye, ke->ke_enc_name, ke->ke_enc_mode))
- return -1;
-
- /* tfm hmac is stateful, user should alloc-use-free by his own */
- if (ke->ke_hash_hmac == 0 &&
- keyblock_init(&kctx->kc_keyi, ke->ke_enc_name, ke->ke_enc_mode))
- return -1;
- if (ke->ke_hash_hmac == 0 &&
- keyblock_init(&kctx->kc_keyc, ke->ke_enc_name, ke->ke_enc_mode))
- return -1;
-
- return 0;
-}
-
-static
-void keyblock_free(struct krb5_keyblock *kb)
-{
- rawobj_free(&kb->kb_key);
- if (kb->kb_tfm)
- crypto_free_blkcipher(kb->kb_tfm);
-}
-
-static
-int keyblock_dup(struct krb5_keyblock *new, struct krb5_keyblock *kb)
-{
- return rawobj_dup(&new->kb_key, &kb->kb_key);
-}
-
-static
-int get_bytes(char **ptr, const char *end, void *res, int len)
-{
- char *p, *q;
- p = *ptr;
- q = p + len;
- if (q > end || q < p)
- return -1;
- memcpy(res, p, len);
- *ptr = q;
- return 0;
-}
-
-static
-int get_rawobj(char **ptr, const char *end, rawobj_t *res)
-{
- char *p, *q;
- __u32 len;
-
- p = *ptr;
- if (get_bytes(&p, end, &len, sizeof(len)))
- return -1;
-
- q = p + len;
- if (q > end || q < p)
- return -1;
-
- OBD_ALLOC_LARGE(res->data, len);
- if (!res->data)
- return -1;
-
- res->len = len;
- memcpy(res->data, p, len);
- *ptr = q;
- return 0;
-}
-
-static
-int get_keyblock(char **ptr, const char *end,
- struct krb5_keyblock *kb, __u32 keysize)
-{
- char *buf;
-
- OBD_ALLOC_LARGE(buf, keysize);
- if (buf == NULL)
- return -1;
-
- if (get_bytes(ptr, end, buf, keysize)) {
- OBD_FREE_LARGE(buf, keysize);
- return -1;
- }
-
- kb->kb_key.len = keysize;
- kb->kb_key.data = buf;
- return 0;
-}
-
-static
-void delete_context_kerberos(struct krb5_ctx *kctx)
-{
- rawobj_free(&kctx->kc_mech_used);
-
- keyblock_free(&kctx->kc_keye);
- keyblock_free(&kctx->kc_keyi);
- keyblock_free(&kctx->kc_keyc);
-}
-
-static
-__u32 import_context_rfc1964(struct krb5_ctx *kctx, char *p, char *end)
-{
- unsigned int tmp_uint, keysize;
-
- /* seed_init flag */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)))
- goto out_err;
- kctx->kc_seed_init = (tmp_uint != 0);
-
- /* seed */
- if (get_bytes(&p, end, kctx->kc_seed, sizeof(kctx->kc_seed)))
- goto out_err;
-
- /* sign/seal algorithm, not really used now */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)) ||
- get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)))
- goto out_err;
-
- /* end time */
- if (get_bytes(&p, end, &kctx->kc_endtime, sizeof(kctx->kc_endtime)))
- goto out_err;
-
- /* seq send */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)))
- goto out_err;
- kctx->kc_seq_send = tmp_uint;
-
- /* mech oid */
- if (get_rawobj(&p, end, &kctx->kc_mech_used))
- goto out_err;
-
- /* old style enc/seq keys in format:
- * - enctype (u32)
- * - keysize (u32)
- * - keydata
- * we decompose them to fit into the new context
- */
-
- /* enc key */
- if (get_bytes(&p, end, &kctx->kc_enctype, sizeof(kctx->kc_enctype)))
- goto out_err;
-
- if (get_bytes(&p, end, &keysize, sizeof(keysize)))
- goto out_err;
-
- if (get_keyblock(&p, end, &kctx->kc_keye, keysize))
- goto out_err;
-
- /* seq key */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)) ||
- tmp_uint != kctx->kc_enctype)
- goto out_err;
-
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)) ||
- tmp_uint != keysize)
- goto out_err;
-
- if (get_keyblock(&p, end, &kctx->kc_keyc, keysize))
- goto out_err;
-
- /* old style fallback */
- if (keyblock_dup(&kctx->kc_keyi, &kctx->kc_keyc))
- goto out_err;
-
- if (p != end)
- goto out_err;
-
- CDEBUG(D_SEC, "successfully imported rfc1964 context\n");
- return 0;
-out_err:
- return GSS_S_FAILURE;
-}
-
-/* Flags for version 2 context flags */
-#define KRB5_CTX_FLAG_INITIATOR 0x00000001
-#define KRB5_CTX_FLAG_CFX 0x00000002
-#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
-
-static
-__u32 import_context_rfc4121(struct krb5_ctx *kctx, char *p, char *end)
-{
- unsigned int tmp_uint, keysize;
-
- /* end time */
- if (get_bytes(&p, end, &kctx->kc_endtime, sizeof(kctx->kc_endtime)))
- goto out_err;
-
- /* flags */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)))
- goto out_err;
-
- if (tmp_uint & KRB5_CTX_FLAG_INITIATOR)
- kctx->kc_initiate = 1;
- if (tmp_uint & KRB5_CTX_FLAG_CFX)
- kctx->kc_cfx = 1;
- if (tmp_uint & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY)
- kctx->kc_have_acceptor_subkey = 1;
-
- /* seq send */
- if (get_bytes(&p, end, &kctx->kc_seq_send, sizeof(kctx->kc_seq_send)))
- goto out_err;
-
- /* enctype */
- if (get_bytes(&p, end, &kctx->kc_enctype, sizeof(kctx->kc_enctype)))
- goto out_err;
-
- /* size of each key */
- if (get_bytes(&p, end, &keysize, sizeof(keysize)))
- goto out_err;
-
- /* number of keys - should always be 3 */
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint)))
- goto out_err;
-
- if (tmp_uint != 3) {
- CERROR("Invalid number of keys: %u\n", tmp_uint);
- goto out_err;
- }
-
- /* ke */
- if (get_keyblock(&p, end, &kctx->kc_keye, keysize))
- goto out_err;
- /* ki */
- if (get_keyblock(&p, end, &kctx->kc_keyi, keysize))
- goto out_err;
- /* ki */
- if (get_keyblock(&p, end, &kctx->kc_keyc, keysize))
- goto out_err;
-
- CDEBUG(D_SEC, "successfully imported v2 context\n");
- return 0;
-out_err:
- return GSS_S_FAILURE;
-}
-
-/*
- * The whole purpose here is trying to keep user level gss context parsing
- * from nfs-utils unchanged as possible as we can, they are not quite mature
- * yet, and many stuff still not clear, like heimdal etc.
- */
-static
-__u32 gss_import_sec_context_kerberos(rawobj_t *inbuf,
- struct gss_ctx *gctx)
-{
- struct krb5_ctx *kctx;
- char *p = (char *) inbuf->data;
- char *end = (char *) (inbuf->data + inbuf->len);
- unsigned int tmp_uint, rc;
-
- if (get_bytes(&p, end, &tmp_uint, sizeof(tmp_uint))) {
- CERROR("Fail to read version\n");
- return GSS_S_FAILURE;
- }
-
- /* only support 0, 1 for the moment */
- if (tmp_uint > 2) {
- CERROR("Invalid version %u\n", tmp_uint);
- return GSS_S_FAILURE;
- }
-
- OBD_ALLOC_PTR(kctx);
- if (!kctx)
- return GSS_S_FAILURE;
-
- if (tmp_uint == 0 || tmp_uint == 1) {
- kctx->kc_initiate = tmp_uint;
- rc = import_context_rfc1964(kctx, p, end);
- } else {
- rc = import_context_rfc4121(kctx, p, end);
- }
-
- if (rc == 0)
- rc = krb5_init_keys(kctx);
-
- if (rc) {
- delete_context_kerberos(kctx);
- OBD_FREE_PTR(kctx);
-
- return GSS_S_FAILURE;
- }
-
- gctx->internal_ctx_id = kctx;
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_copy_reverse_context_kerberos(struct gss_ctx *gctx,
- struct gss_ctx *gctx_new)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_ctx *knew;
-
- OBD_ALLOC_PTR(knew);
- if (!knew)
- return GSS_S_FAILURE;
-
- knew->kc_initiate = kctx->kc_initiate ? 0 : 1;
- knew->kc_cfx = kctx->kc_cfx;
- knew->kc_seed_init = kctx->kc_seed_init;
- knew->kc_have_acceptor_subkey = kctx->kc_have_acceptor_subkey;
- knew->kc_endtime = kctx->kc_endtime;
-
- memcpy(knew->kc_seed, kctx->kc_seed, sizeof(kctx->kc_seed));
- knew->kc_seq_send = kctx->kc_seq_recv;
- knew->kc_seq_recv = kctx->kc_seq_send;
- knew->kc_enctype = kctx->kc_enctype;
-
- if (rawobj_dup(&knew->kc_mech_used, &kctx->kc_mech_used))
- goto out_err;
-
- if (keyblock_dup(&knew->kc_keye, &kctx->kc_keye))
- goto out_err;
- if (keyblock_dup(&knew->kc_keyi, &kctx->kc_keyi))
- goto out_err;
- if (keyblock_dup(&knew->kc_keyc, &kctx->kc_keyc))
- goto out_err;
- if (krb5_init_keys(knew))
- goto out_err;
-
- gctx_new->internal_ctx_id = knew;
- CDEBUG(D_SEC, "successfully copied reverse context\n");
- return GSS_S_COMPLETE;
-
-out_err:
- delete_context_kerberos(knew);
- OBD_FREE_PTR(knew);
- return GSS_S_FAILURE;
-}
-
-static
-__u32 gss_inquire_context_kerberos(struct gss_ctx *gctx,
- unsigned long *endtime)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
-
- *endtime = (unsigned long) ((__u32) kctx->kc_endtime);
- return GSS_S_COMPLETE;
-}
-
-static
-void gss_delete_sec_context_kerberos(void *internal_ctx)
-{
- struct krb5_ctx *kctx = internal_ctx;
-
- delete_context_kerberos(kctx);
- OBD_FREE_PTR(kctx);
-}
-
-static
-void buf_to_sg(struct scatterlist *sg, void *ptr, int len)
-{
- sg_set_buf(sg, ptr, len);
-}
-
-static
-__u32 krb5_encrypt(struct crypto_blkcipher *tfm,
- int decrypt,
- void * iv,
- void * in,
- void * out,
- int length)
-{
- struct blkcipher_desc desc;
- struct scatterlist sg;
- __u8 local_iv[16] = {0};
- __u32 ret = -EINVAL;
-
- LASSERT(tfm);
- desc.tfm = tfm;
- desc.info = local_iv;
- desc.flags= 0;
-
- if (length % crypto_blkcipher_blocksize(tfm) != 0) {
- CERROR("output length %d mismatch blocksize %d\n",
- length, crypto_blkcipher_blocksize(tfm));
- goto out;
- }
-
- if (crypto_blkcipher_ivsize(tfm) > 16) {
- CERROR("iv size too large %d\n", crypto_blkcipher_ivsize(tfm));
- goto out;
- }
-
- if (iv)
- memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm));
-
- memcpy(out, in, length);
- buf_to_sg(&sg, out, length);
-
- if (decrypt)
- ret = crypto_blkcipher_decrypt_iv(&desc, &sg, &sg, length);
- else
- ret = crypto_blkcipher_encrypt_iv(&desc, &sg, &sg, length);
-
-out:
- return(ret);
-}
-
-
-static inline
-int krb5_digest_hmac(struct crypto_hash *tfm,
- rawobj_t *key,
- struct krb5_header *khdr,
- int msgcnt, rawobj_t *msgs,
- int iovcnt, lnet_kiov_t *iovs,
- rawobj_t *cksum)
-{
- struct hash_desc desc;
- struct scatterlist sg[1];
- int i;
-
- crypto_hash_setkey(tfm, key->data, key->len);
- desc.tfm = tfm;
- desc.flags= 0;
-
- crypto_hash_init(&desc);
-
- for (i = 0; i < msgcnt; i++) {
- if (msgs[i].len == 0)
- continue;
- buf_to_sg(sg, (char *) msgs[i].data, msgs[i].len);
- crypto_hash_update(&desc, sg, msgs[i].len);
- }
-
- for (i = 0; i < iovcnt; i++) {
- if (iovs[i].kiov_len == 0)
- continue;
-
- sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
- iovs[i].kiov_offset);
- crypto_hash_update(&desc, sg, iovs[i].kiov_len);
- }
-
- if (khdr) {
- buf_to_sg(sg, (char *) khdr, sizeof(*khdr));
- crypto_hash_update(&desc, sg, sizeof(*khdr));
- }
-
- return crypto_hash_final(&desc, cksum->data);
-}
-
-
-static inline
-int krb5_digest_norm(struct crypto_hash *tfm,
- struct krb5_keyblock *kb,
- struct krb5_header *khdr,
- int msgcnt, rawobj_t *msgs,
- int iovcnt, lnet_kiov_t *iovs,
- rawobj_t *cksum)
-{
- struct hash_desc desc;
- struct scatterlist sg[1];
- int i;
-
- LASSERT(kb->kb_tfm);
- desc.tfm = tfm;
- desc.flags= 0;
-
- crypto_hash_init(&desc);
-
- for (i = 0; i < msgcnt; i++) {
- if (msgs[i].len == 0)
- continue;
- buf_to_sg(sg, (char *) msgs[i].data, msgs[i].len);
- crypto_hash_update(&desc, sg, msgs[i].len);
- }
-
- for (i = 0; i < iovcnt; i++) {
- if (iovs[i].kiov_len == 0)
- continue;
-
- sg_set_page(&sg[0], iovs[i].kiov_page, iovs[i].kiov_len,
- iovs[i].kiov_offset);
- crypto_hash_update(&desc, sg, iovs[i].kiov_len);
- }
-
- if (khdr) {
- buf_to_sg(sg, (char *) khdr, sizeof(*khdr));
- crypto_hash_update(&desc, sg, sizeof(*khdr));
- }
-
- crypto_hash_final(&desc, cksum->data);
-
- return krb5_encrypt(kb->kb_tfm, 0, NULL, cksum->data,
- cksum->data, cksum->len);
-}
-
-/*
- * compute (keyed/keyless) checksum against the plain text which appended
- * with krb5 wire token header.
- */
-static
-__s32 krb5_make_checksum(__u32 enctype,
- struct krb5_keyblock *kb,
- struct krb5_header *khdr,
- int msgcnt, rawobj_t *msgs,
- int iovcnt, lnet_kiov_t *iovs,
- rawobj_t *cksum)
-{
- struct krb5_enctype *ke = &enctypes[enctype];
- struct crypto_hash *tfm;
- __u32 code = GSS_S_FAILURE;
- int rc;
-
- tfm = ll_crypto_alloc_hash(ke->ke_hash_name, 0, 0);
- if (!tfm) {
- CERROR("failed to alloc TFM: %s\n", ke->ke_hash_name);
- return GSS_S_FAILURE;
- }
-
- cksum->len = crypto_hash_digestsize(tfm);
- OBD_ALLOC_LARGE(cksum->data, cksum->len);
- if (!cksum->data) {
- cksum->len = 0;
- goto out_tfm;
- }
-
- if (ke->ke_hash_hmac)
- rc = krb5_digest_hmac(tfm, &kb->kb_key,
- khdr, msgcnt, msgs, iovcnt, iovs, cksum);
- else
- rc = krb5_digest_norm(tfm, kb,
- khdr, msgcnt, msgs, iovcnt, iovs, cksum);
-
- if (rc == 0)
- code = GSS_S_COMPLETE;
-out_tfm:
- crypto_free_hash(tfm);
- return code;
-}
-
-static void fill_krb5_header(struct krb5_ctx *kctx,
- struct krb5_header *khdr,
- int privacy)
-{
- unsigned char acceptor_flag;
-
- acceptor_flag = kctx->kc_initiate ? 0 : FLAG_SENDER_IS_ACCEPTOR;
-
- if (privacy) {
- khdr->kh_tok_id = cpu_to_be16(KG_TOK_WRAP_MSG);
- khdr->kh_flags = acceptor_flag | FLAG_WRAP_CONFIDENTIAL;
- khdr->kh_ec = cpu_to_be16(0);
- khdr->kh_rrc = cpu_to_be16(0);
- } else {
- khdr->kh_tok_id = cpu_to_be16(KG_TOK_MIC_MSG);
- khdr->kh_flags = acceptor_flag;
- khdr->kh_ec = cpu_to_be16(0xffff);
- khdr->kh_rrc = cpu_to_be16(0xffff);
- }
-
- khdr->kh_filler = 0xff;
- spin_lock(&krb5_seq_lock);
- khdr->kh_seq = cpu_to_be64(kctx->kc_seq_send++);
- spin_unlock(&krb5_seq_lock);
-}
-
-static __u32 verify_krb5_header(struct krb5_ctx *kctx,
- struct krb5_header *khdr,
- int privacy)
-{
- unsigned char acceptor_flag;
- __u16 tok_id, ec_rrc;
-
- acceptor_flag = kctx->kc_initiate ? FLAG_SENDER_IS_ACCEPTOR : 0;
-
- if (privacy) {
- tok_id = KG_TOK_WRAP_MSG;
- ec_rrc = 0x0;
- } else {
- tok_id = KG_TOK_MIC_MSG;
- ec_rrc = 0xffff;
- }
-
- /* sanity checks */
- if (be16_to_cpu(khdr->kh_tok_id) != tok_id) {
- CERROR("bad token id\n");
- return GSS_S_DEFECTIVE_TOKEN;
- }
- if ((khdr->kh_flags & FLAG_SENDER_IS_ACCEPTOR) != acceptor_flag) {
- CERROR("bad direction flag\n");
- return GSS_S_BAD_SIG;
- }
- if (privacy && (khdr->kh_flags & FLAG_WRAP_CONFIDENTIAL) == 0) {
- CERROR("missing confidential flag\n");
- return GSS_S_BAD_SIG;
- }
- if (khdr->kh_filler != 0xff) {
- CERROR("bad filler\n");
- return GSS_S_DEFECTIVE_TOKEN;
- }
- if (be16_to_cpu(khdr->kh_ec) != ec_rrc ||
- be16_to_cpu(khdr->kh_rrc) != ec_rrc) {
- CERROR("bad EC or RRC\n");
- return GSS_S_DEFECTIVE_TOKEN;
- }
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_get_mic_kerberos(struct gss_ctx *gctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *token)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- rawobj_t cksum = RAWOBJ_EMPTY;
-
- /* fill krb5 header */
- LASSERT(token->len >= sizeof(*khdr));
- khdr = (struct krb5_header *) token->data;
- fill_krb5_header(kctx, khdr, 0);
-
- /* checksum */
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyc,
- khdr, msgcnt, msgs, iovcnt, iovs, &cksum))
- return GSS_S_FAILURE;
-
- LASSERT(cksum.len >= ke->ke_hash_size);
- LASSERT(token->len >= sizeof(*khdr) + ke->ke_hash_size);
- memcpy(khdr + 1, cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size);
-
- token->len = sizeof(*khdr) + ke->ke_hash_size;
- rawobj_free(&cksum);
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_verify_mic_kerberos(struct gss_ctx *gctx,
- int msgcnt,
- rawobj_t *msgs,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *token)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- rawobj_t cksum = RAWOBJ_EMPTY;
- __u32 major;
-
- if (token->len < sizeof(*khdr)) {
- CERROR("short signature: %u\n", token->len);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- khdr = (struct krb5_header *) token->data;
-
- major = verify_krb5_header(kctx, khdr, 0);
- if (major != GSS_S_COMPLETE) {
- CERROR("bad krb5 header\n");
- return major;
- }
-
- if (token->len < sizeof(*khdr) + ke->ke_hash_size) {
- CERROR("short signature: %u, require %d\n",
- token->len, (int) sizeof(*khdr) + ke->ke_hash_size);
- return GSS_S_FAILURE;
- }
-
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyc,
- khdr, msgcnt, msgs, iovcnt, iovs, &cksum)) {
- CERROR("failed to make checksum\n");
- return GSS_S_FAILURE;
- }
-
- LASSERT(cksum.len >= ke->ke_hash_size);
- if (memcmp(khdr + 1, cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size)) {
- CERROR("checksum mismatch\n");
- rawobj_free(&cksum);
- return GSS_S_BAD_SIG;
- }
-
- rawobj_free(&cksum);
- return GSS_S_COMPLETE;
-}
-
-static
-int add_padding(rawobj_t *msg, int msg_buflen, int blocksize)
-{
- int padding;
-
- padding = (blocksize - (msg->len & (blocksize - 1))) &
- (blocksize - 1);
- if (!padding)
- return 0;
-
- if (msg->len + padding > msg_buflen) {
- CERROR("bufsize %u too small: datalen %u, padding %u\n",
- msg_buflen, msg->len, padding);
- return -EINVAL;
- }
-
- memset(msg->data + msg->len, padding, padding);
- msg->len += padding;
- return 0;
-}
-
-static
-int krb5_encrypt_rawobjs(struct crypto_blkcipher *tfm,
- int mode_ecb,
- int inobj_cnt,
- rawobj_t *inobjs,
- rawobj_t *outobj,
- int enc)
-{
- struct blkcipher_desc desc;
- struct scatterlist src, dst;
- __u8 local_iv[16] = {0}, *buf;
- __u32 datalen = 0;
- int i, rc;
-
- buf = outobj->data;
- desc.tfm = tfm;
- desc.info = local_iv;
- desc.flags = 0;
-
- for (i = 0; i < inobj_cnt; i++) {
- LASSERT(buf + inobjs[i].len <= outobj->data + outobj->len);
-
- buf_to_sg(&src, inobjs[i].data, inobjs[i].len);
- buf_to_sg(&dst, buf, outobj->len - datalen);
-
- if (mode_ecb) {
- if (enc)
- rc = crypto_blkcipher_encrypt(
- &desc, &dst, &src, src.length);
- else
- rc = crypto_blkcipher_decrypt(
- &desc, &dst, &src, src.length);
- } else {
- if (enc)
- rc = crypto_blkcipher_encrypt_iv(
- &desc, &dst, &src, src.length);
- else
- rc = crypto_blkcipher_decrypt_iv(
- &desc, &dst, &src, src.length);
- }
-
- if (rc) {
- CERROR("encrypt error %d\n", rc);
- return rc;
- }
-
- datalen += inobjs[i].len;
- buf += inobjs[i].len;
- }
-
- outobj->len = datalen;
- return 0;
-}
-
-/*
- * if adj_nob != 0, we adjust desc->bd_nob to the actual cipher text size.
- */
-static
-int krb5_encrypt_bulk(struct crypto_blkcipher *tfm,
- struct krb5_header *khdr,
- char *confounder,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *cipher,
- int adj_nob)
-{
- struct blkcipher_desc ciph_desc;
- __u8 local_iv[16] = {0};
- struct scatterlist src, dst;
- int blocksize, i, rc, nob = 0;
-
- LASSERT(desc->bd_iov_count);
- LASSERT(desc->bd_enc_iov);
-
- blocksize = crypto_blkcipher_blocksize(tfm);
- LASSERT(blocksize > 1);
- LASSERT(cipher->len == blocksize + sizeof(*khdr));
-
- ciph_desc.tfm = tfm;
- ciph_desc.info = local_iv;
- ciph_desc.flags = 0;
-
- /* encrypt confounder */
- buf_to_sg(&src, confounder, blocksize);
- buf_to_sg(&dst, cipher->data, blocksize);
-
- rc = crypto_blkcipher_encrypt_iv(&ciph_desc, &dst, &src, blocksize);
- if (rc) {
- CERROR("error to encrypt confounder: %d\n", rc);
- return rc;
- }
-
- /* encrypt clear pages */
- for (i = 0; i < desc->bd_iov_count; i++) {
- sg_set_page(&src, desc->bd_iov[i].kiov_page,
- (desc->bd_iov[i].kiov_len + blocksize - 1) &
- (~(blocksize - 1)),
- desc->bd_iov[i].kiov_offset);
- if (adj_nob)
- nob += src.length;
- sg_set_page(&dst, desc->bd_enc_iov[i].kiov_page, src.length,
- src.offset);
-
- desc->bd_enc_iov[i].kiov_offset = dst.offset;
- desc->bd_enc_iov[i].kiov_len = dst.length;
-
- rc = crypto_blkcipher_encrypt_iv(&ciph_desc, &dst, &src,
- src.length);
- if (rc) {
- CERROR("error to encrypt page: %d\n", rc);
- return rc;
- }
- }
-
- /* encrypt krb5 header */
- buf_to_sg(&src, khdr, sizeof(*khdr));
- buf_to_sg(&dst, cipher->data + blocksize, sizeof(*khdr));
-
- rc = crypto_blkcipher_encrypt_iv(&ciph_desc,
- &dst, &src, sizeof(*khdr));
- if (rc) {
- CERROR("error to encrypt krb5 header: %d\n", rc);
- return rc;
- }
-
- if (adj_nob)
- desc->bd_nob = nob;
-
- return 0;
-}
-
-/*
- * desc->bd_nob_transferred is the size of cipher text received.
- * desc->bd_nob is the target size of plain text supposed to be.
- *
- * if adj_nob != 0, we adjust each page's kiov_len to the actual
- * plain text size.
- * - for client read: we don't know data size for each page, so
- * bd_iov[]->kiov_len is set to PAGE_SIZE, but actual data received might
- * be smaller, so we need to adjust it according to bd_enc_iov[]->kiov_len.
- * this means we DO NOT support the situation that server send an odd size
- * data in a page which is not the last one.
- * - for server write: we knows exactly data size for each page being expected,
- * thus kiov_len is accurate already, so we should not adjust it at all.
- * and bd_enc_iov[]->kiov_len should be round_up(bd_iov[]->kiov_len) which
- * should have been done by prep_bulk().
- */
-static
-int krb5_decrypt_bulk(struct crypto_blkcipher *tfm,
- struct krb5_header *khdr,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *cipher,
- rawobj_t *plain,
- int adj_nob)
-{
- struct blkcipher_desc ciph_desc;
- __u8 local_iv[16] = {0};
- struct scatterlist src, dst;
- int ct_nob = 0, pt_nob = 0;
- int blocksize, i, rc;
-
- LASSERT(desc->bd_iov_count);
- LASSERT(desc->bd_enc_iov);
- LASSERT(desc->bd_nob_transferred);
-
- blocksize = crypto_blkcipher_blocksize(tfm);
- LASSERT(blocksize > 1);
- LASSERT(cipher->len == blocksize + sizeof(*khdr));
-
- ciph_desc.tfm = tfm;
- ciph_desc.info = local_iv;
- ciph_desc.flags = 0;
-
- if (desc->bd_nob_transferred % blocksize) {
- CERROR("odd transferred nob: %d\n", desc->bd_nob_transferred);
- return -EPROTO;
- }
-
- /* decrypt head (confounder) */
- buf_to_sg(&src, cipher->data, blocksize);
- buf_to_sg(&dst, plain->data, blocksize);
-
- rc = crypto_blkcipher_decrypt_iv(&ciph_desc, &dst, &src, blocksize);
- if (rc) {
- CERROR("error to decrypt confounder: %d\n", rc);
- return rc;
- }
-
- for (i = 0; i < desc->bd_iov_count && ct_nob < desc->bd_nob_transferred;
- i++) {
- if (desc->bd_enc_iov[i].kiov_offset % blocksize != 0 ||
- desc->bd_enc_iov[i].kiov_len % blocksize != 0) {
- CERROR("page %d: odd offset %u len %u, blocksize %d\n",
- i, desc->bd_enc_iov[i].kiov_offset,
- desc->bd_enc_iov[i].kiov_len, blocksize);
- return -EFAULT;
- }
-
- if (adj_nob) {
- if (ct_nob + desc->bd_enc_iov[i].kiov_len >
- desc->bd_nob_transferred)
- desc->bd_enc_iov[i].kiov_len =
- desc->bd_nob_transferred - ct_nob;
-
- desc->bd_iov[i].kiov_len = desc->bd_enc_iov[i].kiov_len;
- if (pt_nob + desc->bd_enc_iov[i].kiov_len >desc->bd_nob)
- desc->bd_iov[i].kiov_len = desc->bd_nob -pt_nob;
- } else {
- /* this should be guaranteed by LNET */
- LASSERT(ct_nob + desc->bd_enc_iov[i].kiov_len <=
- desc->bd_nob_transferred);
- LASSERT(desc->bd_iov[i].kiov_len <=
- desc->bd_enc_iov[i].kiov_len);
- }
-
- if (desc->bd_enc_iov[i].kiov_len == 0)
- continue;
-
- sg_set_page(&src, desc->bd_enc_iov[i].kiov_page,
- desc->bd_enc_iov[i].kiov_len,
- desc->bd_enc_iov[i].kiov_offset);
- dst = src;
- if (desc->bd_iov[i].kiov_len % blocksize == 0)
- sg_assign_page(&dst, desc->bd_iov[i].kiov_page);
-
- rc = crypto_blkcipher_decrypt_iv(&ciph_desc, &dst, &src,
- src.length);
- if (rc) {
- CERROR("error to decrypt page: %d\n", rc);
- return rc;
- }
-
- if (desc->bd_iov[i].kiov_len % blocksize != 0) {
- memcpy(page_address(desc->bd_iov[i].kiov_page) +
- desc->bd_iov[i].kiov_offset,
- page_address(desc->bd_enc_iov[i].kiov_page) +
- desc->bd_iov[i].kiov_offset,
- desc->bd_iov[i].kiov_len);
- }
-
- ct_nob += desc->bd_enc_iov[i].kiov_len;
- pt_nob += desc->bd_iov[i].kiov_len;
- }
-
- if (unlikely(ct_nob != desc->bd_nob_transferred)) {
- CERROR("%d cipher text transferred but only %d decrypted\n",
- desc->bd_nob_transferred, ct_nob);
- return -EFAULT;
- }
-
- if (unlikely(!adj_nob && pt_nob != desc->bd_nob)) {
- CERROR("%d plain text expected but only %d received\n",
- desc->bd_nob, pt_nob);
- return -EFAULT;
- }
-
- /* if needed, clear up the rest unused iovs */
- if (adj_nob)
- while (i < desc->bd_iov_count)
- desc->bd_iov[i++].kiov_len = 0;
-
- /* decrypt tail (krb5 header) */
- buf_to_sg(&src, cipher->data + blocksize, sizeof(*khdr));
- buf_to_sg(&dst, cipher->data + blocksize, sizeof(*khdr));
-
- rc = crypto_blkcipher_decrypt_iv(&ciph_desc,
- &dst, &src, sizeof(*khdr));
- if (rc) {
- CERROR("error to decrypt tail: %d\n", rc);
- return rc;
- }
-
- if (memcmp(cipher->data + blocksize, khdr, sizeof(*khdr))) {
- CERROR("krb5 header doesn't match\n");
- return -EACCES;
- }
-
- return 0;
-}
-
-static
-__u32 gss_wrap_kerberos(struct gss_ctx *gctx,
- rawobj_t *gsshdr,
- rawobj_t *msg,
- int msg_buflen,
- rawobj_t *token)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- int blocksize;
- rawobj_t cksum = RAWOBJ_EMPTY;
- rawobj_t data_desc[3], cipher;
- __u8 conf[GSS_MAX_CIPHER_BLOCK];
- int rc = 0;
-
- LASSERT(ke);
- LASSERT(ke->ke_conf_size <= GSS_MAX_CIPHER_BLOCK);
- LASSERT(kctx->kc_keye.kb_tfm == NULL ||
- ke->ke_conf_size >=
- crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm));
-
- /*
- * final token format:
- * ---------------------------------------------------
- * | krb5 header | cipher text | checksum (16 bytes) |
- * ---------------------------------------------------
- */
-
- /* fill krb5 header */
- LASSERT(token->len >= sizeof(*khdr));
- khdr = (struct krb5_header *) token->data;
- fill_krb5_header(kctx, khdr, 1);
-
- /* generate confounder */
- cfs_get_random_bytes(conf, ke->ke_conf_size);
-
- /* get encryption blocksize. note kc_keye might not associated with
- * a tfm, currently only for arcfour-hmac */
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- LASSERT(kctx->kc_keye.kb_tfm == NULL);
- blocksize = 1;
- } else {
- LASSERT(kctx->kc_keye.kb_tfm);
- blocksize = crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm);
- }
- LASSERT(blocksize <= ke->ke_conf_size);
-
- /* padding the message */
- if (add_padding(msg, msg_buflen, blocksize))
- return GSS_S_FAILURE;
-
- /*
- * clear text layout for checksum:
- * ------------------------------------------------------
- * | confounder | gss header | clear msgs | krb5 header |
- * ------------------------------------------------------
- */
- data_desc[0].data = conf;
- data_desc[0].len = ke->ke_conf_size;
- data_desc[1].data = gsshdr->data;
- data_desc[1].len = gsshdr->len;
- data_desc[2].data = msg->data;
- data_desc[2].len = msg->len;
-
- /* compute checksum */
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyi,
- khdr, 3, data_desc, 0, NULL, &cksum))
- return GSS_S_FAILURE;
- LASSERT(cksum.len >= ke->ke_hash_size);
-
- /*
- * clear text layout for encryption:
- * -----------------------------------------
- * | confounder | clear msgs | krb5 header |
- * -----------------------------------------
- */
- data_desc[0].data = conf;
- data_desc[0].len = ke->ke_conf_size;
- data_desc[1].data = msg->data;
- data_desc[1].len = msg->len;
- data_desc[2].data = (__u8 *) khdr;
- data_desc[2].len = sizeof(*khdr);
-
- /* cipher text will be directly inplace */
- cipher.data = (__u8 *) (khdr + 1);
- cipher.len = token->len - sizeof(*khdr);
- LASSERT(cipher.len >= ke->ke_conf_size + msg->len + sizeof(*khdr));
-
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- rawobj_t arc4_keye;
- struct crypto_blkcipher *arc4_tfm;
-
- if (krb5_make_checksum(ENCTYPE_ARCFOUR_HMAC, &kctx->kc_keyi,
- NULL, 1, &cksum, 0, NULL, &arc4_keye)) {
- CERROR("failed to obtain arc4 enc key\n");
- GOTO(arc4_out, rc = -EACCES);
- }
-
- arc4_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 0);
- if (IS_ERR(arc4_tfm)) {
- CERROR("failed to alloc tfm arc4 in ECB mode\n");
- GOTO(arc4_out_key, rc = -EACCES);
- }
-
- if (crypto_blkcipher_setkey(arc4_tfm, arc4_keye.data,
- arc4_keye.len)) {
- CERROR("failed to set arc4 key, len %d\n",
- arc4_keye.len);
- GOTO(arc4_out_tfm, rc = -EACCES);
- }
-
- rc = krb5_encrypt_rawobjs(arc4_tfm, 1,
- 3, data_desc, &cipher, 1);
-arc4_out_tfm:
- crypto_free_blkcipher(arc4_tfm);
-arc4_out_key:
- rawobj_free(&arc4_keye);
-arc4_out:
- do {} while (0); /* just to avoid compile warning */
- } else {
- rc = krb5_encrypt_rawobjs(kctx->kc_keye.kb_tfm, 0,
- 3, data_desc, &cipher, 1);
- }
-
- if (rc != 0) {
- rawobj_free(&cksum);
- return GSS_S_FAILURE;
- }
-
- /* fill in checksum */
- LASSERT(token->len >= sizeof(*khdr) + cipher.len + ke->ke_hash_size);
- memcpy((char *)(khdr + 1) + cipher.len,
- cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size);
- rawobj_free(&cksum);
-
- /* final token length */
- token->len = sizeof(*khdr) + cipher.len + ke->ke_hash_size;
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_prep_bulk_kerberos(struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- int blocksize, i;
-
- LASSERT(desc->bd_iov_count);
- LASSERT(desc->bd_enc_iov);
- LASSERT(kctx->kc_keye.kb_tfm);
-
- blocksize = crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm);
-
- for (i = 0; i < desc->bd_iov_count; i++) {
- LASSERT(desc->bd_enc_iov[i].kiov_page);
- /*
- * offset should always start at page boundary of either
- * client or server side.
- */
- if (desc->bd_iov[i].kiov_offset & blocksize) {
- CERROR("odd offset %d in page %d\n",
- desc->bd_iov[i].kiov_offset, i);
- return GSS_S_FAILURE;
- }
-
- desc->bd_enc_iov[i].kiov_offset = desc->bd_iov[i].kiov_offset;
- desc->bd_enc_iov[i].kiov_len = (desc->bd_iov[i].kiov_len +
- blocksize - 1) & (~(blocksize - 1));
- }
-
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_wrap_bulk_kerberos(struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token, int adj_nob)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- int blocksize;
- rawobj_t cksum = RAWOBJ_EMPTY;
- rawobj_t data_desc[1], cipher;
- __u8 conf[GSS_MAX_CIPHER_BLOCK];
- int rc = 0;
-
- LASSERT(ke);
- LASSERT(ke->ke_conf_size <= GSS_MAX_CIPHER_BLOCK);
-
- /*
- * final token format:
- * --------------------------------------------------
- * | krb5 header | head/tail cipher text | checksum |
- * --------------------------------------------------
- */
-
- /* fill krb5 header */
- LASSERT(token->len >= sizeof(*khdr));
- khdr = (struct krb5_header *) token->data;
- fill_krb5_header(kctx, khdr, 1);
-
- /* generate confounder */
- cfs_get_random_bytes(conf, ke->ke_conf_size);
-
- /* get encryption blocksize. note kc_keye might not associated with
- * a tfm, currently only for arcfour-hmac */
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- LASSERT(kctx->kc_keye.kb_tfm == NULL);
- blocksize = 1;
- } else {
- LASSERT(kctx->kc_keye.kb_tfm);
- blocksize = crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm);
- }
-
- /*
- * we assume the size of krb5_header (16 bytes) must be n * blocksize.
- * the bulk token size would be exactly (sizeof(krb5_header) +
- * blocksize + sizeof(krb5_header) + hashsize)
- */
- LASSERT(blocksize <= ke->ke_conf_size);
- LASSERT(sizeof(*khdr) >= blocksize && sizeof(*khdr) % blocksize == 0);
- LASSERT(token->len >= sizeof(*khdr) + blocksize + sizeof(*khdr) + 16);
-
- /*
- * clear text layout for checksum:
- * ------------------------------------------
- * | confounder | clear pages | krb5 header |
- * ------------------------------------------
- */
- data_desc[0].data = conf;
- data_desc[0].len = ke->ke_conf_size;
-
- /* compute checksum */
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyi,
- khdr, 1, data_desc,
- desc->bd_iov_count, desc->bd_iov,
- &cksum))
- return GSS_S_FAILURE;
- LASSERT(cksum.len >= ke->ke_hash_size);
-
- /*
- * clear text layout for encryption:
- * ------------------------------------------
- * | confounder | clear pages | krb5 header |
- * ------------------------------------------
- * | | |
- * ---------- (cipher pages) |
- * result token: | |
- * -------------------------------------------
- * | krb5 header | cipher text | cipher text |
- * -------------------------------------------
- */
- data_desc[0].data = conf;
- data_desc[0].len = ke->ke_conf_size;
-
- cipher.data = (__u8 *) (khdr + 1);
- cipher.len = blocksize + sizeof(*khdr);
-
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- LBUG();
- rc = 0;
- } else {
- rc = krb5_encrypt_bulk(kctx->kc_keye.kb_tfm, khdr,
- conf, desc, &cipher, adj_nob);
- }
-
- if (rc != 0) {
- rawobj_free(&cksum);
- return GSS_S_FAILURE;
- }
-
- /* fill in checksum */
- LASSERT(token->len >= sizeof(*khdr) + cipher.len + ke->ke_hash_size);
- memcpy((char *)(khdr + 1) + cipher.len,
- cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size);
- rawobj_free(&cksum);
-
- /* final token length */
- token->len = sizeof(*khdr) + cipher.len + ke->ke_hash_size;
- return GSS_S_COMPLETE;
-}
-
-static
-__u32 gss_unwrap_kerberos(struct gss_ctx *gctx,
- rawobj_t *gsshdr,
- rawobj_t *token,
- rawobj_t *msg)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- unsigned char *tmpbuf;
- int blocksize, bodysize;
- rawobj_t cksum = RAWOBJ_EMPTY;
- rawobj_t cipher_in, plain_out;
- rawobj_t hash_objs[3];
- int rc = 0;
- __u32 major;
-
- LASSERT(ke);
-
- if (token->len < sizeof(*khdr)) {
- CERROR("short signature: %u\n", token->len);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- khdr = (struct krb5_header *) token->data;
-
- major = verify_krb5_header(kctx, khdr, 1);
- if (major != GSS_S_COMPLETE) {
- CERROR("bad krb5 header\n");
- return major;
- }
-
- /* block size */
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- LASSERT(kctx->kc_keye.kb_tfm == NULL);
- blocksize = 1;
- } else {
- LASSERT(kctx->kc_keye.kb_tfm);
- blocksize = crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm);
- }
-
- /* expected token layout:
- * ----------------------------------------
- * | krb5 header | cipher text | checksum |
- * ----------------------------------------
- */
- bodysize = token->len - sizeof(*khdr) - ke->ke_hash_size;
-
- if (bodysize % blocksize) {
- CERROR("odd bodysize %d\n", bodysize);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if (bodysize <= ke->ke_conf_size + sizeof(*khdr)) {
- CERROR("incomplete token: bodysize %d\n", bodysize);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if (msg->len < bodysize - ke->ke_conf_size - sizeof(*khdr)) {
- CERROR("buffer too small: %u, require %d\n",
- msg->len, bodysize - ke->ke_conf_size);
- return GSS_S_FAILURE;
- }
-
- /* decrypting */
- OBD_ALLOC_LARGE(tmpbuf, bodysize);
- if (!tmpbuf)
- return GSS_S_FAILURE;
-
- major = GSS_S_FAILURE;
-
- cipher_in.data = (__u8 *) (khdr + 1);
- cipher_in.len = bodysize;
- plain_out.data = tmpbuf;
- plain_out.len = bodysize;
-
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- rawobj_t arc4_keye;
- struct crypto_blkcipher *arc4_tfm;
-
- cksum.data = token->data + token->len - ke->ke_hash_size;
- cksum.len = ke->ke_hash_size;
-
- if (krb5_make_checksum(ENCTYPE_ARCFOUR_HMAC, &kctx->kc_keyi,
- NULL, 1, &cksum, 0, NULL, &arc4_keye)) {
- CERROR("failed to obtain arc4 enc key\n");
- GOTO(arc4_out, rc = -EACCES);
- }
-
- arc4_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, 0);
- if (IS_ERR(arc4_tfm)) {
- CERROR("failed to alloc tfm arc4 in ECB mode\n");
- GOTO(arc4_out_key, rc = -EACCES);
- }
-
- if (crypto_blkcipher_setkey(arc4_tfm,
- arc4_keye.data, arc4_keye.len)) {
- CERROR("failed to set arc4 key, len %d\n",
- arc4_keye.len);
- GOTO(arc4_out_tfm, rc = -EACCES);
- }
-
- rc = krb5_encrypt_rawobjs(arc4_tfm, 1,
- 1, &cipher_in, &plain_out, 0);
-arc4_out_tfm:
- crypto_free_blkcipher(arc4_tfm);
-arc4_out_key:
- rawobj_free(&arc4_keye);
-arc4_out:
- cksum = RAWOBJ_EMPTY;
- } else {
- rc = krb5_encrypt_rawobjs(kctx->kc_keye.kb_tfm, 0,
- 1, &cipher_in, &plain_out, 0);
- }
-
- if (rc != 0) {
- CERROR("error decrypt\n");
- goto out_free;
- }
- LASSERT(plain_out.len == bodysize);
-
- /* expected clear text layout:
- * -----------------------------------------
- * | confounder | clear msgs | krb5 header |
- * -----------------------------------------
- */
-
- /* verify krb5 header in token is not modified */
- if (memcmp(khdr, plain_out.data + plain_out.len - sizeof(*khdr),
- sizeof(*khdr))) {
- CERROR("decrypted krb5 header mismatch\n");
- goto out_free;
- }
-
- /* verify checksum, compose clear text as layout:
- * ------------------------------------------------------
- * | confounder | gss header | clear msgs | krb5 header |
- * ------------------------------------------------------
- */
- hash_objs[0].len = ke->ke_conf_size;
- hash_objs[0].data = plain_out.data;
- hash_objs[1].len = gsshdr->len;
- hash_objs[1].data = gsshdr->data;
- hash_objs[2].len = plain_out.len - ke->ke_conf_size - sizeof(*khdr);
- hash_objs[2].data = plain_out.data + ke->ke_conf_size;
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyi,
- khdr, 3, hash_objs, 0, NULL, &cksum))
- goto out_free;
-
- LASSERT(cksum.len >= ke->ke_hash_size);
- if (memcmp((char *)(khdr + 1) + bodysize,
- cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size)) {
- CERROR("checksum mismatch\n");
- goto out_free;
- }
-
- msg->len = bodysize - ke->ke_conf_size - sizeof(*khdr);
- memcpy(msg->data, tmpbuf + ke->ke_conf_size, msg->len);
-
- major = GSS_S_COMPLETE;
-out_free:
- OBD_FREE_LARGE(tmpbuf, bodysize);
- rawobj_free(&cksum);
- return major;
-}
-
-static
-__u32 gss_unwrap_bulk_kerberos(struct gss_ctx *gctx,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token, int adj_nob)
-{
- struct krb5_ctx *kctx = gctx->internal_ctx_id;
- struct krb5_enctype *ke = &enctypes[kctx->kc_enctype];
- struct krb5_header *khdr;
- int blocksize;
- rawobj_t cksum = RAWOBJ_EMPTY;
- rawobj_t cipher, plain;
- rawobj_t data_desc[1];
- int rc;
- __u32 major;
-
- LASSERT(ke);
-
- if (token->len < sizeof(*khdr)) {
- CERROR("short signature: %u\n", token->len);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- khdr = (struct krb5_header *) token->data;
-
- major = verify_krb5_header(kctx, khdr, 1);
- if (major != GSS_S_COMPLETE) {
- CERROR("bad krb5 header\n");
- return major;
- }
-
- /* block size */
- if (kctx->kc_enctype == ENCTYPE_ARCFOUR_HMAC) {
- LASSERT(kctx->kc_keye.kb_tfm == NULL);
- blocksize = 1;
- LBUG();
- } else {
- LASSERT(kctx->kc_keye.kb_tfm);
- blocksize = crypto_blkcipher_blocksize(kctx->kc_keye.kb_tfm);
- }
- LASSERT(sizeof(*khdr) >= blocksize && sizeof(*khdr) % blocksize == 0);
-
- /*
- * token format is expected as:
- * -----------------------------------------------
- * | krb5 header | head/tail cipher text | cksum |
- * -----------------------------------------------
- */
- if (token->len < sizeof(*khdr) + blocksize + sizeof(*khdr) +
- ke->ke_hash_size) {
- CERROR("short token size: %u\n", token->len);
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- cipher.data = (__u8 *) (khdr + 1);
- cipher.len = blocksize + sizeof(*khdr);
- plain.data = cipher.data;
- plain.len = cipher.len;
-
- rc = krb5_decrypt_bulk(kctx->kc_keye.kb_tfm, khdr,
- desc, &cipher, &plain, adj_nob);
- if (rc)
- return GSS_S_DEFECTIVE_TOKEN;
-
- /*
- * verify checksum, compose clear text as layout:
- * ------------------------------------------
- * | confounder | clear pages | krb5 header |
- * ------------------------------------------
- */
- data_desc[0].data = plain.data;
- data_desc[0].len = blocksize;
-
- if (krb5_make_checksum(kctx->kc_enctype, &kctx->kc_keyi,
- khdr, 1, data_desc,
- desc->bd_iov_count, desc->bd_iov,
- &cksum))
- return GSS_S_FAILURE;
- LASSERT(cksum.len >= ke->ke_hash_size);
-
- if (memcmp(plain.data + blocksize + sizeof(*khdr),
- cksum.data + cksum.len - ke->ke_hash_size,
- ke->ke_hash_size)) {
- CERROR("checksum mismatch\n");
- rawobj_free(&cksum);
- return GSS_S_BAD_SIG;
- }
-
- rawobj_free(&cksum);
- return GSS_S_COMPLETE;
-}
-
-int gss_display_kerberos(struct gss_ctx *ctx,
- char *buf,
- int bufsize)
-{
- struct krb5_ctx *kctx = ctx->internal_ctx_id;
- int written;
-
- written = snprintf(buf, bufsize, "krb5 (%s)",
- enctype2str(kctx->kc_enctype));
- return written;
-}
-
-static struct gss_api_ops gss_kerberos_ops = {
- .gss_import_sec_context = gss_import_sec_context_kerberos,
- .gss_copy_reverse_context = gss_copy_reverse_context_kerberos,
- .gss_inquire_context = gss_inquire_context_kerberos,
- .gss_get_mic = gss_get_mic_kerberos,
- .gss_verify_mic = gss_verify_mic_kerberos,
- .gss_wrap = gss_wrap_kerberos,
- .gss_unwrap = gss_unwrap_kerberos,
- .gss_prep_bulk = gss_prep_bulk_kerberos,
- .gss_wrap_bulk = gss_wrap_bulk_kerberos,
- .gss_unwrap_bulk = gss_unwrap_bulk_kerberos,
- .gss_delete_sec_context = gss_delete_sec_context_kerberos,
- .gss_display = gss_display_kerberos,
-};
-
-static struct subflavor_desc gss_kerberos_sfs[] = {
- {
- .sf_subflavor = SPTLRPC_SUBFLVR_KRB5N,
- .sf_qop = 0,
- .sf_service = SPTLRPC_SVC_NULL,
- .sf_name = "krb5n"
- },
- {
- .sf_subflavor = SPTLRPC_SUBFLVR_KRB5A,
- .sf_qop = 0,
- .sf_service = SPTLRPC_SVC_AUTH,
- .sf_name = "krb5a"
- },
- {
- .sf_subflavor = SPTLRPC_SUBFLVR_KRB5I,
- .sf_qop = 0,
- .sf_service = SPTLRPC_SVC_INTG,
- .sf_name = "krb5i"
- },
- {
- .sf_subflavor = SPTLRPC_SUBFLVR_KRB5P,
- .sf_qop = 0,
- .sf_service = SPTLRPC_SVC_PRIV,
- .sf_name = "krb5p"
- },
-};
-
-/*
- * currently we leave module owner NULL
- */
-static struct gss_api_mech gss_kerberos_mech = {
- .gm_owner = NULL, /*THIS_MODULE, */
- .gm_name = "krb5",
- .gm_oid = (rawobj_t)
- {9, "\052\206\110\206\367\022\001\002\002"},
- .gm_ops = &gss_kerberos_ops,
- .gm_sf_num = 4,
- .gm_sfs = gss_kerberos_sfs,
-};
-
-int __init init_kerberos_module(void)
-{
- int status;
-
- spin_lock_init(&krb5_seq_lock);
-
- status = lgss_mech_register(&gss_kerberos_mech);
- if (status)
- CERROR("Failed to register kerberos gss mechanism!\n");
- return status;
-}
-
-void __exit cleanup_kerberos_module(void)
-{
- lgss_mech_unregister(&gss_kerberos_mech);
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_mech_switch.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_mech_switch.c
deleted file mode 100644
index 99462e085da7..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_mech_switch.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/net/sunrpc/gss_mech_switch.c
- *
- * Copyright (c) 2001 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * J. Bruce Fields <bfields@umich.edu>
- *
- * 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 name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
- *
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-static LIST_HEAD(registered_mechs);
-static DEFINE_SPINLOCK(registered_mechs_lock);
-
-int lgss_mech_register(struct gss_api_mech *gm)
-{
- spin_lock(&registered_mechs_lock);
- list_add(&gm->gm_list, &registered_mechs);
- spin_unlock(&registered_mechs_lock);
- CWARN("Register %s mechanism\n", gm->gm_name);
- return 0;
-}
-
-void lgss_mech_unregister(struct gss_api_mech *gm)
-{
- spin_lock(&registered_mechs_lock);
- list_del(&gm->gm_list);
- spin_unlock(&registered_mechs_lock);
- CWARN("Unregister %s mechanism\n", gm->gm_name);
-}
-
-
-struct gss_api_mech *lgss_mech_get(struct gss_api_mech *gm)
-{
- __module_get(gm->gm_owner);
- return gm;
-}
-
-struct gss_api_mech *lgss_name_to_mech(char *name)
-{
- struct gss_api_mech *pos, *gm = NULL;
-
- spin_lock(&registered_mechs_lock);
- list_for_each_entry(pos, &registered_mechs, gm_list) {
- if (0 == strcmp(name, pos->gm_name)) {
- if (!try_module_get(pos->gm_owner))
- continue;
- gm = pos;
- break;
- }
- }
- spin_unlock(&registered_mechs_lock);
- return gm;
-
-}
-
-static inline
-int mech_supports_subflavor(struct gss_api_mech *gm, __u32 subflavor)
-{
- int i;
-
- for (i = 0; i < gm->gm_sf_num; i++) {
- if (gm->gm_sfs[i].sf_subflavor == subflavor)
- return 1;
- }
- return 0;
-}
-
-struct gss_api_mech *lgss_subflavor_to_mech(__u32 subflavor)
-{
- struct gss_api_mech *pos, *gm = NULL;
-
- spin_lock(&registered_mechs_lock);
- list_for_each_entry(pos, &registered_mechs, gm_list) {
- if (!try_module_get(pos->gm_owner))
- continue;
- if (!mech_supports_subflavor(pos, subflavor)) {
- module_put(pos->gm_owner);
- continue;
- }
- gm = pos;
- break;
- }
- spin_unlock(&registered_mechs_lock);
- return gm;
-}
-
-void lgss_mech_put(struct gss_api_mech *gm)
-{
- module_put(gm->gm_owner);
-}
-
-/* The mech could probably be determined from the token instead, but it's just
- * as easy for now to pass it in. */
-__u32 lgss_import_sec_context(rawobj_t *input_token,
- struct gss_api_mech *mech,
- struct gss_ctx **ctx_id)
-{
- OBD_ALLOC_PTR(*ctx_id);
- if (*ctx_id == NULL)
- return GSS_S_FAILURE;
-
- (*ctx_id)->mech_type = lgss_mech_get(mech);
-
- LASSERT(mech);
- LASSERT(mech->gm_ops);
- LASSERT(mech->gm_ops->gss_import_sec_context);
- return mech->gm_ops->gss_import_sec_context(input_token, *ctx_id);
-}
-
-__u32 lgss_copy_reverse_context(struct gss_ctx *ctx_id,
- struct gss_ctx **ctx_id_new)
-{
- struct gss_api_mech *mech = ctx_id->mech_type;
- __u32 major;
-
- LASSERT(mech);
-
- OBD_ALLOC_PTR(*ctx_id_new);
- if (*ctx_id_new == NULL)
- return GSS_S_FAILURE;
-
- (*ctx_id_new)->mech_type = lgss_mech_get(mech);
-
- LASSERT(mech);
- LASSERT(mech->gm_ops);
- LASSERT(mech->gm_ops->gss_copy_reverse_context);
-
- major = mech->gm_ops->gss_copy_reverse_context(ctx_id, *ctx_id_new);
- if (major != GSS_S_COMPLETE) {
- lgss_mech_put(mech);
- OBD_FREE_PTR(*ctx_id_new);
- *ctx_id_new = NULL;
- }
- return major;
-}
-
-/*
- * this interface is much simplified, currently we only need endtime.
- */
-__u32 lgss_inquire_context(struct gss_ctx *context_handle,
- unsigned long *endtime)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_inquire_context);
-
- return context_handle->mech_type->gm_ops
- ->gss_inquire_context(context_handle,
- endtime);
-}
-
-/* gss_get_mic: compute a mic over message and return mic_token. */
-__u32 lgss_get_mic(struct gss_ctx *context_handle,
- int msgcnt,
- rawobj_t *msg,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_get_mic);
-
- return context_handle->mech_type->gm_ops
- ->gss_get_mic(context_handle,
- msgcnt,
- msg,
- iovcnt,
- iovs,
- mic_token);
-}
-
-/* gss_verify_mic: check whether the provided mic_token verifies message. */
-__u32 lgss_verify_mic(struct gss_ctx *context_handle,
- int msgcnt,
- rawobj_t *msg,
- int iovcnt,
- lnet_kiov_t *iovs,
- rawobj_t *mic_token)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_verify_mic);
-
- return context_handle->mech_type->gm_ops
- ->gss_verify_mic(context_handle,
- msgcnt,
- msg,
- iovcnt,
- iovs,
- mic_token);
-}
-
-__u32 lgss_wrap(struct gss_ctx *context_handle,
- rawobj_t *gsshdr,
- rawobj_t *msg,
- int msg_buflen,
- rawobj_t *out_token)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_wrap);
-
- return context_handle->mech_type->gm_ops
- ->gss_wrap(context_handle, gsshdr, msg, msg_buflen, out_token);
-}
-
-__u32 lgss_unwrap(struct gss_ctx *context_handle,
- rawobj_t *gsshdr,
- rawobj_t *token,
- rawobj_t *out_msg)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_unwrap);
-
- return context_handle->mech_type->gm_ops
- ->gss_unwrap(context_handle, gsshdr, token, out_msg);
-}
-
-
-__u32 lgss_prep_bulk(struct gss_ctx *context_handle,
- struct ptlrpc_bulk_desc *desc)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_prep_bulk);
-
- return context_handle->mech_type->gm_ops
- ->gss_prep_bulk(context_handle, desc);
-}
-
-__u32 lgss_wrap_bulk(struct gss_ctx *context_handle,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_wrap_bulk);
-
- return context_handle->mech_type->gm_ops
- ->gss_wrap_bulk(context_handle, desc, token, adj_nob);
-}
-
-__u32 lgss_unwrap_bulk(struct gss_ctx *context_handle,
- struct ptlrpc_bulk_desc *desc,
- rawobj_t *token,
- int adj_nob)
-{
- LASSERT(context_handle);
- LASSERT(context_handle->mech_type);
- LASSERT(context_handle->mech_type->gm_ops);
- LASSERT(context_handle->mech_type->gm_ops->gss_unwrap_bulk);
-
- return context_handle->mech_type->gm_ops
- ->gss_unwrap_bulk(context_handle, desc, token, adj_nob);
-}
-
-/* gss_delete_sec_context: free all resources associated with context_handle.
- * Note this differs from the RFC 2744-specified prototype in that we don't
- * bother returning an output token, since it would never be used anyway. */
-
-__u32 lgss_delete_sec_context(struct gss_ctx **context_handle)
-{
- struct gss_api_mech *mech;
-
- CDEBUG(D_SEC, "deleting %p\n", *context_handle);
-
- if (!*context_handle)
- return(GSS_S_NO_CONTEXT);
-
- mech = (*context_handle)->mech_type;
- if ((*context_handle)->internal_ctx_id != 0) {
- LASSERT(mech);
- LASSERT(mech->gm_ops);
- LASSERT(mech->gm_ops->gss_delete_sec_context);
- mech->gm_ops->gss_delete_sec_context(
- (*context_handle)->internal_ctx_id);
- }
- if (mech)
- lgss_mech_put(mech);
-
- OBD_FREE_PTR(*context_handle);
- *context_handle=NULL;
- return GSS_S_COMPLETE;
-}
-
-int lgss_display(struct gss_ctx *ctx,
- char *buf,
- int bufsize)
-{
- LASSERT(ctx);
- LASSERT(ctx->mech_type);
- LASSERT(ctx->mech_type->gm_ops);
- LASSERT(ctx->mech_type->gm_ops->gss_display);
-
- return ctx->mech_type->gm_ops->gss_display(ctx, buf, bufsize);
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_pipefs.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_pipefs.c
deleted file mode 100644
index 3be5bc14c4ed..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_pipefs.c
+++ /dev/null
@@ -1,1233 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/net/sunrpc/auth_gss.c
- *
- * RPCSEC_GSS client authentication.
- *
- * Copyright (c) 2000 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Dug Song <dugsong@monkey.org>
- * Andy Adamson <andros@umich.edu>
- *
- * 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 name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
- *
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <linux/crypto.h>
-#include <asm/atomic.h>
-struct rpc_clnt; /* for rpc_pipefs */
-#include <linux/sunrpc/rpc_pipe_fs.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_sec.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-static struct ptlrpc_sec_policy gss_policy_pipefs;
-static struct ptlrpc_ctx_ops gss_pipefs_ctxops;
-
-static int gss_cli_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx);
-
-static int gss_sec_pipe_upcall_init(struct gss_sec *gsec)
-{
- return 0;
-}
-
-static void gss_sec_pipe_upcall_fini(struct gss_sec *gsec)
-{
-}
-
-/****************************************
- * internal context helpers *
- ****************************************/
-
-static
-struct ptlrpc_cli_ctx *ctx_create_pf(struct ptlrpc_sec *sec,
- struct vfs_cred *vcred)
-{
- struct gss_cli_ctx *gctx;
- int rc;
-
- OBD_ALLOC_PTR(gctx);
- if (gctx == NULL)
- return NULL;
-
- rc = gss_cli_ctx_init_common(sec, &gctx->gc_base,
- &gss_pipefs_ctxops, vcred);
- if (rc) {
- OBD_FREE_PTR(gctx);
- return NULL;
- }
-
- return &gctx->gc_base;
-}
-
-static
-void ctx_destroy_pf(struct ptlrpc_sec *sec, struct ptlrpc_cli_ctx *ctx)
-{
- struct gss_cli_ctx *gctx = ctx2gctx(ctx);
-
- if (gss_cli_ctx_fini_common(sec, ctx))
- return;
-
- OBD_FREE_PTR(gctx);
-
- atomic_dec(&sec->ps_nctx);
- sptlrpc_sec_put(sec);
-}
-
-static
-void ctx_enhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *hash)
-{
- set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
- atomic_inc(&ctx->cc_refcount);
- hlist_add_head(&ctx->cc_cache, hash);
-}
-
-/*
- * caller must hold spinlock
- */
-static
-void ctx_unhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *freelist)
-{
- assert_spin_locked(&ctx->cc_sec->ps_lock);
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
- LASSERT(!hlist_unhashed(&ctx->cc_cache));
-
- clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
-
- if (atomic_dec_and_test(&ctx->cc_refcount)) {
- __hlist_del(&ctx->cc_cache);
- hlist_add_head(&ctx->cc_cache, freelist);
- } else {
- hlist_del_init(&ctx->cc_cache);
- }
-}
-
-/*
- * return 1 if the context is dead.
- */
-static
-int ctx_check_death_pf(struct ptlrpc_cli_ctx *ctx,
- struct hlist_head *freelist)
-{
- if (cli_ctx_check_death(ctx)) {
- if (freelist)
- ctx_unhash_pf(ctx, freelist);
- return 1;
- }
-
- return 0;
-}
-
-static inline
-int ctx_check_death_locked_pf(struct ptlrpc_cli_ctx *ctx,
- struct hlist_head *freelist)
-{
- LASSERT(ctx->cc_sec);
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
-
- return ctx_check_death_pf(ctx, freelist);
-}
-
-static inline
-int ctx_match_pf(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred)
-{
- /* a little bit optimization for null policy */
- if (!ctx->cc_ops->match)
- return 1;
-
- return ctx->cc_ops->match(ctx, vcred);
-}
-
-static
-void ctx_list_destroy_pf(struct hlist_head *head)
-{
- struct ptlrpc_cli_ctx *ctx;
-
- while (!hlist_empty(head)) {
- ctx = hlist_entry(head->first, struct ptlrpc_cli_ctx,
- cc_cache);
-
- LASSERT(atomic_read(&ctx->cc_refcount) == 0);
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT,
- &ctx->cc_flags) == 0);
-
- hlist_del_init(&ctx->cc_cache);
- ctx_destroy_pf(ctx->cc_sec, ctx);
- }
-}
-
-/****************************************
- * context apis *
- ****************************************/
-
-static
-int gss_cli_ctx_validate_pf(struct ptlrpc_cli_ctx *ctx)
-{
- if (ctx_check_death_pf(ctx, NULL))
- return 1;
- if (cli_ctx_is_ready(ctx))
- return 0;
- return 1;
-}
-
-static
-void gss_cli_ctx_die_pf(struct ptlrpc_cli_ctx *ctx, int grace)
-{
- LASSERT(ctx->cc_sec);
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- cli_ctx_expire(ctx);
-
- spin_lock(&ctx->cc_sec->ps_lock);
-
- if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags)) {
- LASSERT(!hlist_unhashed(&ctx->cc_cache));
- LASSERT(atomic_read(&ctx->cc_refcount) > 1);
-
- hlist_del_init(&ctx->cc_cache);
- if (atomic_dec_and_test(&ctx->cc_refcount))
- LBUG();
- }
-
- spin_unlock(&ctx->cc_sec->ps_lock);
-}
-
-/****************************************
- * reverse context installation *
- ****************************************/
-
-static inline
-unsigned int ctx_hash_index(int hashsize, __u64 key)
-{
- return (unsigned int) (key & ((__u64) hashsize - 1));
-}
-
-static
-void gss_sec_ctx_replace_pf(struct gss_sec *gsec,
- struct ptlrpc_cli_ctx *new)
-{
- struct gss_sec_pipefs *gsec_pf;
- struct ptlrpc_cli_ctx *ctx;
- struct hlist_node *next;
- HLIST_HEAD(freelist);
- unsigned int hash;
-
- gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
-
- hash = ctx_hash_index(gsec_pf->gsp_chash_size,
- (__u64) new->cc_vcred.vc_uid);
- LASSERT(hash < gsec_pf->gsp_chash_size);
-
- spin_lock(&gsec->gs_base.ps_lock);
-
- hlist_for_each_entry_safe(ctx, next,
- &gsec_pf->gsp_chash[hash], cc_cache) {
- if (!ctx_match_pf(ctx, &new->cc_vcred))
- continue;
-
- cli_ctx_expire(ctx);
- ctx_unhash_pf(ctx, &freelist);
- break;
- }
-
- ctx_enhash_pf(new, &gsec_pf->gsp_chash[hash]);
-
- spin_unlock(&gsec->gs_base.ps_lock);
-
- ctx_list_destroy_pf(&freelist);
-}
-
-static
-int gss_install_rvs_cli_ctx_pf(struct gss_sec *gsec,
- struct ptlrpc_svc_ctx *svc_ctx)
-{
- struct vfs_cred vcred;
- struct ptlrpc_cli_ctx *cli_ctx;
- int rc;
-
- vcred.vc_uid = 0;
- vcred.vc_gid = 0;
-
- cli_ctx = ctx_create_pf(&gsec->gs_base, &vcred);
- if (!cli_ctx)
- return -ENOMEM;
-
- rc = gss_copy_rvc_cli_ctx(cli_ctx, svc_ctx);
- if (rc) {
- ctx_destroy_pf(cli_ctx->cc_sec, cli_ctx);
- return rc;
- }
-
- gss_sec_ctx_replace_pf(gsec, cli_ctx);
- return 0;
-}
-
-static
-void gss_ctx_cache_gc_pf(struct gss_sec_pipefs *gsec_pf,
- struct hlist_head *freelist)
-{
- struct ptlrpc_sec *sec;
- struct ptlrpc_cli_ctx *ctx;
- struct hlist_node *next;
- int i;
-
- sec = &gsec_pf->gsp_base.gs_base;
-
- CDEBUG(D_SEC, "do gc on sec %s@%p\n", sec->ps_policy->sp_name, sec);
-
- for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
- hlist_for_each_entry_safe(ctx, next,
- &gsec_pf->gsp_chash[i], cc_cache)
- ctx_check_death_locked_pf(ctx, freelist);
- }
-
- sec->ps_gc_next = cfs_time_current_sec() + sec->ps_gc_interval;
-}
-
-static
-struct ptlrpc_sec* gss_sec_create_pf(struct obd_import *imp,
- struct ptlrpc_svc_ctx *ctx,
- struct sptlrpc_flavor *sf)
-{
- struct gss_sec_pipefs *gsec_pf;
- int alloc_size, hash_size, i;
-
-#define GSS_SEC_PIPEFS_CTX_HASH_SIZE (32)
-
- if (ctx ||
- sf->sf_flags & (PTLRPC_SEC_FL_ROOTONLY | PTLRPC_SEC_FL_REVERSE))
- hash_size = 1;
- else
- hash_size = GSS_SEC_PIPEFS_CTX_HASH_SIZE;
-
- alloc_size = sizeof(*gsec_pf) +
- sizeof(struct hlist_head) * hash_size;
-
- OBD_ALLOC(gsec_pf, alloc_size);
- if (!gsec_pf)
- return NULL;
-
- gsec_pf->gsp_chash_size = hash_size;
- for (i = 0; i < hash_size; i++)
- INIT_HLIST_HEAD(&gsec_pf->gsp_chash[i]);
-
- if (gss_sec_create_common(&gsec_pf->gsp_base, &gss_policy_pipefs,
- imp, ctx, sf))
- goto err_free;
-
- if (ctx == NULL) {
- if (gss_sec_pipe_upcall_init(&gsec_pf->gsp_base))
- goto err_destroy;
- } else {
- if (gss_install_rvs_cli_ctx_pf(&gsec_pf->gsp_base, ctx))
- goto err_destroy;
- }
-
- return &gsec_pf->gsp_base.gs_base;
-
-err_destroy:
- gss_sec_destroy_common(&gsec_pf->gsp_base);
-err_free:
- OBD_FREE(gsec_pf, alloc_size);
- return NULL;
-}
-
-static
-void gss_sec_destroy_pf(struct ptlrpc_sec *sec)
-{
- struct gss_sec_pipefs *gsec_pf;
- struct gss_sec *gsec;
-
- CWARN("destroy %s@%p\n", sec->ps_policy->sp_name, sec);
-
- gsec = container_of(sec, struct gss_sec, gs_base);
- gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
-
- LASSERT(gsec_pf->gsp_chash);
- LASSERT(gsec_pf->gsp_chash_size);
-
- gss_sec_pipe_upcall_fini(gsec);
-
- gss_sec_destroy_common(gsec);
-
- OBD_FREE(gsec, sizeof(*gsec_pf) +
- sizeof(struct hlist_head) * gsec_pf->gsp_chash_size);
-}
-
-static
-struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_pf(struct ptlrpc_sec *sec,
- struct vfs_cred *vcred,
- int create, int remove_dead)
-{
- struct gss_sec *gsec;
- struct gss_sec_pipefs *gsec_pf;
- struct ptlrpc_cli_ctx *ctx = NULL, *new = NULL;
- struct hlist_head *hash_head;
- struct hlist_node *next;
- HLIST_HEAD(freelist);
- unsigned int hash, gc = 0, found = 0;
-
- might_sleep();
-
- gsec = container_of(sec, struct gss_sec, gs_base);
- gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
-
- hash = ctx_hash_index(gsec_pf->gsp_chash_size,
- (__u64) vcred->vc_uid);
- hash_head = &gsec_pf->gsp_chash[hash];
- LASSERT(hash < gsec_pf->gsp_chash_size);
-
-retry:
- spin_lock(&sec->ps_lock);
-
- /* gc_next == 0 means never do gc */
- if (remove_dead && sec->ps_gc_next &&
- cfs_time_after(cfs_time_current_sec(), sec->ps_gc_next)) {
- gss_ctx_cache_gc_pf(gsec_pf, &freelist);
- gc = 1;
- }
-
- hlist_for_each_entry_safe(ctx, next, hash_head, cc_cache) {
- if (gc == 0 &&
- ctx_check_death_locked_pf(ctx,
- remove_dead ? &freelist : NULL))
- continue;
-
- if (ctx_match_pf(ctx, vcred)) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (new && new != ctx) {
- /* lost the race, just free it */
- hlist_add_head(&new->cc_cache, &freelist);
- new = NULL;
- }
-
- /* hot node, move to head */
- if (hash_head->first != &ctx->cc_cache) {
- __hlist_del(&ctx->cc_cache);
- hlist_add_head(&ctx->cc_cache, hash_head);
- }
- } else {
- /* don't allocate for reverse sec */
- if (sec_is_reverse(sec)) {
- spin_unlock(&sec->ps_lock);
- return NULL;
- }
-
- if (new) {
- ctx_enhash_pf(new, hash_head);
- ctx = new;
- } else if (create) {
- spin_unlock(&sec->ps_lock);
- new = ctx_create_pf(sec, vcred);
- if (new) {
- clear_bit(PTLRPC_CTX_NEW_BIT, &new->cc_flags);
- goto retry;
- }
- } else {
- ctx = NULL;
- }
- }
-
- /* hold a ref */
- if (ctx)
- atomic_inc(&ctx->cc_refcount);
-
- spin_unlock(&sec->ps_lock);
-
- /* the allocator of the context must give the first push to refresh */
- if (new) {
- LASSERT(new == ctx);
- gss_cli_ctx_refresh_pf(new);
- }
-
- ctx_list_destroy_pf(&freelist);
- return ctx;
-}
-
-static
-void gss_sec_release_ctx_pf(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx,
- int sync)
-{
- LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
- LASSERT(hlist_unhashed(&ctx->cc_cache));
-
- /* if required async, we must clear the UPTODATE bit to prevent extra
- * rpcs during destroy procedure. */
- if (!sync)
- clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
-
- /* destroy this context */
- ctx_destroy_pf(sec, ctx);
-}
-
-/*
- * @uid: which user. "-1" means flush all.
- * @grace: mark context DEAD, allow graceful destroy like notify
- * server side, etc.
- * @force: also flush busy entries.
- *
- * return the number of busy context encountered.
- *
- * In any cases, never touch "eternal" contexts.
- */
-static
-int gss_sec_flush_ctx_cache_pf(struct ptlrpc_sec *sec,
- uid_t uid,
- int grace, int force)
-{
- struct gss_sec *gsec;
- struct gss_sec_pipefs *gsec_pf;
- struct ptlrpc_cli_ctx *ctx;
- struct hlist_node *next;
- HLIST_HEAD(freelist);
- int i, busy = 0;
-
- might_sleep_if(grace);
-
- gsec = container_of(sec, struct gss_sec, gs_base);
- gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
-
- spin_lock(&sec->ps_lock);
- for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
- hlist_for_each_entry_safe(ctx, next,
- &gsec_pf->gsp_chash[i],
- cc_cache) {
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
-
- if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
- continue;
-
- if (atomic_read(&ctx->cc_refcount) > 1) {
- busy++;
- if (!force)
- continue;
-
- CWARN("flush busy(%d) ctx %p(%u->%s) by force, "
- "grace %d\n",
- atomic_read(&ctx->cc_refcount),
- ctx, ctx->cc_vcred.vc_uid,
- sec2target_str(ctx->cc_sec), grace);
- }
- ctx_unhash_pf(ctx, &freelist);
-
- set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags);
- if (!grace)
- clear_bit(PTLRPC_CTX_UPTODATE_BIT,
- &ctx->cc_flags);
- }
- }
- spin_unlock(&sec->ps_lock);
-
- ctx_list_destroy_pf(&freelist);
- return busy;
-}
-
-/****************************************
- * service apis *
- ****************************************/
-
-static
-int gss_svc_accept_pf(struct ptlrpc_request *req)
-{
- return gss_svc_accept(&gss_policy_pipefs, req);
-}
-
-static
-int gss_svc_install_rctx_pf(struct obd_import *imp,
- struct ptlrpc_svc_ctx *ctx)
-{
- struct ptlrpc_sec *sec;
- int rc;
-
- sec = sptlrpc_import_sec_ref(imp);
- LASSERT(sec);
- rc = gss_install_rvs_cli_ctx_pf(sec2gsec(sec), ctx);
-
- sptlrpc_sec_put(sec);
- return rc;
-}
-
-/****************************************
- * rpc_pipefs definitions *
- ****************************************/
-
-#define LUSTRE_PIPE_ROOT "/lustre"
-#define LUSTRE_PIPE_KRB5 LUSTRE_PIPE_ROOT"/krb5"
-
-struct gss_upcall_msg_data {
- __u32 gum_seq;
- __u32 gum_uid;
- __u32 gum_gid;
- __u32 gum_svc; /* MDS/OSS... */
- __u64 gum_nid; /* peer NID */
- __u8 gum_obd[64]; /* client obd name */
-};
-
-struct gss_upcall_msg {
- struct rpc_pipe_msg gum_base;
- atomic_t gum_refcount;
- struct list_head gum_list;
- __u32 gum_mechidx;
- struct gss_sec *gum_gsec;
- struct gss_cli_ctx *gum_gctx;
- struct gss_upcall_msg_data gum_data;
-};
-
-static atomic_t upcall_seq = ATOMIC_INIT(0);
-
-static inline
-__u32 upcall_get_sequence(void)
-{
- return (__u32) atomic_inc_return(&upcall_seq);
-}
-
-enum mech_idx_t {
- MECH_KRB5 = 0,
- MECH_MAX
-};
-
-static inline
-__u32 mech_name2idx(const char *name)
-{
- LASSERT(!strcmp(name, "krb5"));
- return MECH_KRB5;
-}
-
-/* pipefs dentries for each mechanisms */
-static struct dentry *de_pipes[MECH_MAX] = { NULL, };
-/* all upcall messages linked here */
-static struct list_head upcall_lists[MECH_MAX];
-/* and protected by this */
-static spinlock_t upcall_locks[MECH_MAX];
-
-static inline
-void upcall_list_lock(int idx)
-{
- spin_lock(&upcall_locks[idx]);
-}
-
-static inline
-void upcall_list_unlock(int idx)
-{
- spin_unlock(&upcall_locks[idx]);
-}
-
-static
-void upcall_msg_enlist(struct gss_upcall_msg *msg)
-{
- __u32 idx = msg->gum_mechidx;
-
- upcall_list_lock(idx);
- list_add(&msg->gum_list, &upcall_lists[idx]);
- upcall_list_unlock(idx);
-}
-
-static
-void upcall_msg_delist(struct gss_upcall_msg *msg)
-{
- __u32 idx = msg->gum_mechidx;
-
- upcall_list_lock(idx);
- list_del_init(&msg->gum_list);
- upcall_list_unlock(idx);
-}
-
-/****************************************
- * rpc_pipefs upcall helpers *
- ****************************************/
-
-static
-void gss_release_msg(struct gss_upcall_msg *gmsg)
-{
- LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
-
- if (!atomic_dec_and_test(&gmsg->gum_refcount)) {
- return;
- }
-
- if (gmsg->gum_gctx) {
- sptlrpc_cli_ctx_wakeup(&gmsg->gum_gctx->gc_base);
- sptlrpc_cli_ctx_put(&gmsg->gum_gctx->gc_base, 1);
- gmsg->gum_gctx = NULL;
- }
-
- LASSERT(list_empty(&gmsg->gum_list));
- LASSERT(list_empty(&gmsg->gum_base.list));
- OBD_FREE_PTR(gmsg);
-}
-
-static
-void gss_unhash_msg_nolock(struct gss_upcall_msg *gmsg)
-{
- __u32 idx = gmsg->gum_mechidx;
-
- LASSERT(idx < MECH_MAX);
- assert_spin_locked(&upcall_locks[idx]);
-
- if (list_empty(&gmsg->gum_list))
- return;
-
- list_del_init(&gmsg->gum_list);
- LASSERT(atomic_read(&gmsg->gum_refcount) > 1);
- atomic_dec(&gmsg->gum_refcount);
-}
-
-static
-void gss_unhash_msg(struct gss_upcall_msg *gmsg)
-{
- __u32 idx = gmsg->gum_mechidx;
-
- LASSERT(idx < MECH_MAX);
- upcall_list_lock(idx);
- gss_unhash_msg_nolock(gmsg);
- upcall_list_unlock(idx);
-}
-
-static
-void gss_msg_fail_ctx(struct gss_upcall_msg *gmsg)
-{
- if (gmsg->gum_gctx) {
- struct ptlrpc_cli_ctx *ctx = &gmsg->gum_gctx->gc_base;
-
- LASSERT(atomic_read(&ctx->cc_refcount) > 0);
- sptlrpc_cli_ctx_expire(ctx);
- set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
- }
-}
-
-static
-struct gss_upcall_msg * gss_find_upcall(__u32 mechidx, __u32 seq)
-{
- struct gss_upcall_msg *gmsg;
-
- upcall_list_lock(mechidx);
- list_for_each_entry(gmsg, &upcall_lists[mechidx], gum_list) {
- if (gmsg->gum_data.gum_seq != seq)
- continue;
-
- LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
- LASSERT(gmsg->gum_mechidx == mechidx);
-
- atomic_inc(&gmsg->gum_refcount);
- upcall_list_unlock(mechidx);
- return gmsg;
- }
- upcall_list_unlock(mechidx);
- return NULL;
-}
-
-static
-int simple_get_bytes(char **buf, __u32 *buflen, void *res, __u32 reslen)
-{
- if (*buflen < reslen) {
- CERROR("buflen %u < %u\n", *buflen, reslen);
- return -EINVAL;
- }
-
- memcpy(res, *buf, reslen);
- *buf += reslen;
- *buflen -= reslen;
- return 0;
-}
-
-/****************************************
- * rpc_pipefs apis *
- ****************************************/
-
-static
-ssize_t gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
- char *dst, size_t buflen)
-{
- char *data = (char *)msg->data + msg->copied;
- ssize_t mlen = msg->len;
- ssize_t left;
-
- if (mlen > buflen)
- mlen = buflen;
- left = copy_to_user(dst, data, mlen);
- if (left < 0) {
- msg->errno = left;
- return left;
- }
- mlen -= left;
- msg->copied += mlen;
- msg->errno = 0;
- return mlen;
-}
-
-static
-ssize_t gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
-{
- struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
- struct gss_upcall_msg *gss_msg;
- struct ptlrpc_cli_ctx *ctx;
- struct gss_cli_ctx *gctx = NULL;
- char *buf, *data;
- int datalen;
- int timeout, rc;
- __u32 mechidx, seq, gss_err;
-
- mechidx = (__u32) (long) rpci->private;
- LASSERT(mechidx < MECH_MAX);
-
- OBD_ALLOC(buf, mlen);
- if (!buf)
- return -ENOMEM;
-
- if (copy_from_user(buf, src, mlen)) {
- CERROR("failed copy user space data\n");
- GOTO(out_free, rc = -EFAULT);
- }
- data = buf;
- datalen = mlen;
-
- /* data passed down format:
- * - seq
- * - timeout
- * - gc_win / error
- * - wire_ctx (rawobj)
- * - mech_ctx (rawobj)
- */
- if (simple_get_bytes(&data, &datalen, &seq, sizeof(seq))) {
- CERROR("fail to get seq\n");
- GOTO(out_free, rc = -EFAULT);
- }
-
- gss_msg = gss_find_upcall(mechidx, seq);
- if (!gss_msg) {
- CERROR("upcall %u has aborted earlier\n", seq);
- GOTO(out_free, rc = -EINVAL);
- }
-
- gss_unhash_msg(gss_msg);
- gctx = gss_msg->gum_gctx;
- LASSERT(gctx);
- LASSERT(atomic_read(&gctx->gc_base.cc_refcount) > 0);
-
- /* timeout is not in use for now */
- if (simple_get_bytes(&data, &datalen, &timeout, sizeof(timeout)))
- GOTO(out_msg, rc = -EFAULT);
-
- /* lgssd signal an error by gc_win == 0 */
- if (simple_get_bytes(&data, &datalen, &gctx->gc_win,
- sizeof(gctx->gc_win)))
- GOTO(out_msg, rc = -EFAULT);
-
- if (gctx->gc_win == 0) {
- /* followed by:
- * - rpc error
- * - gss error
- */
- if (simple_get_bytes(&data, &datalen, &rc, sizeof(rc)))
- GOTO(out_msg, rc = -EFAULT);
- if (simple_get_bytes(&data, &datalen, &gss_err,sizeof(gss_err)))
- GOTO(out_msg, rc = -EFAULT);
-
- if (rc == 0 && gss_err == GSS_S_COMPLETE) {
- CWARN("both rpc & gss error code not set\n");
- rc = -EPERM;
- }
- } else {
- rawobj_t tmpobj;
-
- /* handle */
- if (rawobj_extract_local(&tmpobj, (__u32 **) &data, &datalen))
- GOTO(out_msg, rc = -EFAULT);
- if (rawobj_dup(&gctx->gc_handle, &tmpobj))
- GOTO(out_msg, rc = -ENOMEM);
-
- /* mechctx */
- if (rawobj_extract_local(&tmpobj, (__u32 **) &data, &datalen))
- GOTO(out_msg, rc = -EFAULT);
- gss_err = lgss_import_sec_context(&tmpobj,
- gss_msg->gum_gsec->gs_mech,
- &gctx->gc_mechctx);
- rc = 0;
- }
-
- if (likely(rc == 0 && gss_err == GSS_S_COMPLETE)) {
- gss_cli_ctx_uptodate(gctx);
- } else {
- ctx = &gctx->gc_base;
- sptlrpc_cli_ctx_expire(ctx);
- if (rc != -ERESTART || gss_err != GSS_S_COMPLETE)
- set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
-
- CERROR("refresh ctx %p(uid %d) failed: %d/0x%08x: %s\n",
- ctx, ctx->cc_vcred.vc_uid, rc, gss_err,
- test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags) ?
- "fatal error" : "non-fatal");
- }
-
- rc = mlen;
-
-out_msg:
- gss_release_msg(gss_msg);
-
-out_free:
- OBD_FREE(buf, mlen);
- /* FIXME
- * hack pipefs: always return asked length unless all following
- * downcalls might be messed up. */
- rc = mlen;
- return rc;
-}
-
-static
-void gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
-{
- struct gss_upcall_msg *gmsg;
- struct gss_upcall_msg_data *gumd;
- static cfs_time_t ratelimit = 0;
-
- LASSERT(list_empty(&msg->list));
-
- /* normally errno is >= 0 */
- if (msg->errno >= 0) {
- return;
- }
-
- gmsg = container_of(msg, struct gss_upcall_msg, gum_base);
- gumd = &gmsg->gum_data;
- LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
-
- CERROR("failed msg %p (seq %u, uid %u, svc %u, nid "LPX64", obd %.*s): "
- "errno %d\n", msg, gumd->gum_seq, gumd->gum_uid, gumd->gum_svc,
- gumd->gum_nid, (int) sizeof(gumd->gum_obd),
- gumd->gum_obd, msg->errno);
-
- atomic_inc(&gmsg->gum_refcount);
- gss_unhash_msg(gmsg);
- if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
- cfs_time_t now = cfs_time_current_sec();
-
- if (cfs_time_after(now, ratelimit)) {
- CWARN("upcall timed out, is lgssd running?\n");
- ratelimit = now + 15;
- }
- }
- gss_msg_fail_ctx(gmsg);
- gss_release_msg(gmsg);
-}
-
-static
-void gss_pipe_release(struct inode *inode)
-{
- struct rpc_inode *rpci = RPC_I(inode);
- __u32 idx;
-
- idx = (__u32) (long) rpci->private;
- LASSERT(idx < MECH_MAX);
-
- upcall_list_lock(idx);
- while (!list_empty(&upcall_lists[idx])) {
- struct gss_upcall_msg *gmsg;
- struct gss_upcall_msg_data *gumd;
-
- gmsg = list_entry(upcall_lists[idx].next,
- struct gss_upcall_msg, gum_list);
- gumd = &gmsg->gum_data;
- LASSERT(list_empty(&gmsg->gum_base.list));
-
- CERROR("failing remaining msg %p:seq %u, uid %u, svc %u, "
- "nid "LPX64", obd %.*s\n", gmsg,
- gumd->gum_seq, gumd->gum_uid, gumd->gum_svc,
- gumd->gum_nid, (int) sizeof(gumd->gum_obd),
- gumd->gum_obd);
-
- gmsg->gum_base.errno = -EPIPE;
- atomic_inc(&gmsg->gum_refcount);
- gss_unhash_msg_nolock(gmsg);
-
- gss_msg_fail_ctx(gmsg);
-
- upcall_list_unlock(idx);
- gss_release_msg(gmsg);
- upcall_list_lock(idx);
- }
- upcall_list_unlock(idx);
-}
-
-static struct rpc_pipe_ops gss_upcall_ops = {
- .upcall = gss_pipe_upcall,
- .downcall = gss_pipe_downcall,
- .destroy_msg = gss_pipe_destroy_msg,
- .release_pipe = gss_pipe_release,
-};
-
-/****************************************
- * upcall helper functions *
- ****************************************/
-
-static
-int gss_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx)
-{
- struct obd_import *imp;
- struct gss_sec *gsec;
- struct gss_upcall_msg *gmsg;
- int rc = 0;
-
- might_sleep();
-
- LASSERT(ctx->cc_sec);
- LASSERT(ctx->cc_sec->ps_import);
- LASSERT(ctx->cc_sec->ps_import->imp_obd);
-
- imp = ctx->cc_sec->ps_import;
- if (!imp->imp_connection) {
- CERROR("import has no connection set\n");
- return -EINVAL;
- }
-
- gsec = container_of(ctx->cc_sec, struct gss_sec, gs_base);
-
- OBD_ALLOC_PTR(gmsg);
- if (!gmsg)
- return -ENOMEM;
-
- /* initialize pipefs base msg */
- INIT_LIST_HEAD(&gmsg->gum_base.list);
- gmsg->gum_base.data = &gmsg->gum_data;
- gmsg->gum_base.len = sizeof(gmsg->gum_data);
- gmsg->gum_base.copied = 0;
- gmsg->gum_base.errno = 0;
-
- /* init upcall msg */
- atomic_set(&gmsg->gum_refcount, 1);
- gmsg->gum_mechidx = mech_name2idx(gsec->gs_mech->gm_name);
- gmsg->gum_gsec = gsec;
- gmsg->gum_gctx = container_of(sptlrpc_cli_ctx_get(ctx),
- struct gss_cli_ctx, gc_base);
- gmsg->gum_data.gum_seq = upcall_get_sequence();
- gmsg->gum_data.gum_uid = ctx->cc_vcred.vc_uid;
- gmsg->gum_data.gum_gid = 0; /* not used for now */
- gmsg->gum_data.gum_svc = import_to_gss_svc(imp);
- gmsg->gum_data.gum_nid = imp->imp_connection->c_peer.nid;
- strncpy(gmsg->gum_data.gum_obd, imp->imp_obd->obd_name,
- sizeof(gmsg->gum_data.gum_obd));
-
- /* This only could happen when sysadmin set it dead/expired
- * using lctl by force. */
- if (ctx->cc_flags & PTLRPC_CTX_STATUS_MASK) {
- CWARN("ctx %p(%u->%s) was set flags %lx unexpectedly\n",
- ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
- ctx->cc_flags);
-
- LASSERT(!(ctx->cc_flags & PTLRPC_CTX_UPTODATE));
- ctx->cc_flags |= PTLRPC_CTX_DEAD | PTLRPC_CTX_ERROR;
-
- rc = -EIO;
- goto err_free;
- }
-
- upcall_msg_enlist(gmsg);
-
- rc = rpc_queue_upcall(de_pipes[gmsg->gum_mechidx]->d_inode,
- &gmsg->gum_base);
- if (rc) {
- CERROR("rpc_queue_upcall failed: %d\n", rc);
-
- upcall_msg_delist(gmsg);
- goto err_free;
- }
-
- return 0;
-err_free:
- OBD_FREE_PTR(gmsg);
- return rc;
-}
-
-static
-int gss_cli_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx)
-{
- /* if we are refreshing for root, also update the reverse
- * handle index, do not confuse reverse contexts. */
- if (ctx->cc_vcred.vc_uid == 0) {
- struct gss_sec *gsec;
-
- gsec = container_of(ctx->cc_sec, struct gss_sec, gs_base);
- gsec->gs_rvs_hdl = gss_get_next_ctx_index();
- }
-
- return gss_ctx_refresh_pf(ctx);
-}
-
-/****************************************
- * lustre gss pipefs policy *
- ****************************************/
-
-static struct ptlrpc_ctx_ops gss_pipefs_ctxops = {
- .match = gss_cli_ctx_match,
- .refresh = gss_cli_ctx_refresh_pf,
- .validate = gss_cli_ctx_validate_pf,
- .die = gss_cli_ctx_die_pf,
- .sign = gss_cli_ctx_sign,
- .verify = gss_cli_ctx_verify,
- .seal = gss_cli_ctx_seal,
- .unseal = gss_cli_ctx_unseal,
- .wrap_bulk = gss_cli_ctx_wrap_bulk,
- .unwrap_bulk = gss_cli_ctx_unwrap_bulk,
-};
-
-static struct ptlrpc_sec_cops gss_sec_pipefs_cops = {
- .create_sec = gss_sec_create_pf,
- .destroy_sec = gss_sec_destroy_pf,
- .kill_sec = gss_sec_kill,
- .lookup_ctx = gss_sec_lookup_ctx_pf,
- .release_ctx = gss_sec_release_ctx_pf,
- .flush_ctx_cache = gss_sec_flush_ctx_cache_pf,
- .install_rctx = gss_sec_install_rctx,
- .alloc_reqbuf = gss_alloc_reqbuf,
- .free_reqbuf = gss_free_reqbuf,
- .alloc_repbuf = gss_alloc_repbuf,
- .free_repbuf = gss_free_repbuf,
- .enlarge_reqbuf = gss_enlarge_reqbuf,
-};
-
-static struct ptlrpc_sec_sops gss_sec_pipefs_sops = {
- .accept = gss_svc_accept_pf,
- .invalidate_ctx = gss_svc_invalidate_ctx,
- .alloc_rs = gss_svc_alloc_rs,
- .authorize = gss_svc_authorize,
- .free_rs = gss_svc_free_rs,
- .free_ctx = gss_svc_free_ctx,
- .unwrap_bulk = gss_svc_unwrap_bulk,
- .wrap_bulk = gss_svc_wrap_bulk,
- .install_rctx = gss_svc_install_rctx_pf,
-};
-
-static struct ptlrpc_sec_policy gss_policy_pipefs = {
- .sp_owner = THIS_MODULE,
- .sp_name = "gss.pipefs",
- .sp_policy = SPTLRPC_POLICY_GSS_PIPEFS,
- .sp_cops = &gss_sec_pipefs_cops,
- .sp_sops = &gss_sec_pipefs_sops,
-};
-
-static
-int __init gss_init_pipefs_upcall(void)
-{
- struct dentry *de;
-
- /* pipe dir */
- de = rpc_mkdir(LUSTRE_PIPE_ROOT, NULL);
- if (IS_ERR(de) && PTR_ERR(de) != -EEXIST) {
- CERROR("Failed to create gss pipe dir: %ld\n", PTR_ERR(de));
- return PTR_ERR(de);
- }
-
- /* FIXME hack pipefs: dput will sometimes cause oops during module
- * unload and lgssd close the pipe fds. */
-
- /* krb5 mechanism */
- de = rpc_mkpipe(LUSTRE_PIPE_KRB5, (void *) MECH_KRB5, &gss_upcall_ops,
- RPC_PIPE_WAIT_FOR_OPEN);
- if (!de || IS_ERR(de)) {
- CERROR("failed to make rpc_pipe %s: %ld\n",
- LUSTRE_PIPE_KRB5, PTR_ERR(de));
- rpc_rmdir(LUSTRE_PIPE_ROOT);
- return PTR_ERR(de);
- }
-
- de_pipes[MECH_KRB5] = de;
- INIT_LIST_HEAD(&upcall_lists[MECH_KRB5]);
- spin_lock_init(&upcall_locks[MECH_KRB5]);
-
- return 0;
-}
-
-static
-void __exit gss_exit_pipefs_upcall(void)
-{
- __u32 i;
-
- for (i = 0; i < MECH_MAX; i++) {
- LASSERT(list_empty(&upcall_lists[i]));
-
- /* dput pipe dentry here might cause lgssd oops. */
- de_pipes[i] = NULL;
- }
-
- rpc_unlink(LUSTRE_PIPE_KRB5);
- rpc_rmdir(LUSTRE_PIPE_ROOT);
-}
-
-int __init gss_init_pipefs(void)
-{
- int rc;
-
- rc = gss_init_pipefs_upcall();
- if (rc)
- return rc;
-
- rc = sptlrpc_register_policy(&gss_policy_pipefs);
- if (rc) {
- gss_exit_pipefs_upcall();
- return rc;
- }
-
- return 0;
-}
-
-void __exit gss_exit_pipefs(void)
-{
- gss_exit_pipefs_upcall();
- sptlrpc_unregister_policy(&gss_policy_pipefs);
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_rawobj.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_rawobj.c
deleted file mode 100644
index fb298aef66eb..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_rawobj.c
+++ /dev/null
@@ -1,242 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/ptlrpc/gss/gss_rawobj.c
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_sec.h>
-
-#include "gss_internal.h"
-
-int rawobj_empty(rawobj_t *obj)
-{
- LASSERT(equi(obj->len, obj->data));
- return (obj->len == 0);
-}
-
-int rawobj_alloc(rawobj_t *obj, char *buf, int len)
-{
- LASSERT(obj);
- LASSERT(len >= 0);
-
- obj->len = len;
- if (len) {
- OBD_ALLOC_LARGE(obj->data, len);
- if (!obj->data) {
- obj->len = 0;
- return -ENOMEM;
- }
- memcpy(obj->data, buf, len);
- } else
- obj->data = NULL;
- return 0;
-}
-
-void rawobj_free(rawobj_t *obj)
-{
- LASSERT(obj);
-
- if (obj->len) {
- LASSERT(obj->data);
- OBD_FREE_LARGE(obj->data, obj->len);
- obj->len = 0;
- obj->data = NULL;
- } else
- LASSERT(!obj->data);
-}
-
-int rawobj_equal(rawobj_t *a, rawobj_t *b)
-{
- LASSERT(a && b);
-
- return (a->len == b->len &&
- (!a->len || !memcmp(a->data, b->data, a->len)));
-}
-
-int rawobj_dup(rawobj_t *dest, rawobj_t *src)
-{
- LASSERT(src && dest);
-
- dest->len = src->len;
- if (dest->len) {
- OBD_ALLOC_LARGE(dest->data, dest->len);
- if (!dest->data) {
- dest->len = 0;
- return -ENOMEM;
- }
- memcpy(dest->data, src->data, dest->len);
- } else
- dest->data = NULL;
- return 0;
-}
-
-int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen)
-{
- __u32 len;
-
- LASSERT(obj);
- LASSERT(buf);
- LASSERT(buflen);
-
- len = cfs_size_round4(obj->len);
-
- if (*buflen < 4 + len) {
- CERROR("buflen %u < %u\n", *buflen, 4 + len);
- return -EINVAL;
- }
-
- *(*buf)++ = cpu_to_le32(obj->len);
- memcpy(*buf, obj->data, obj->len);
- *buf += (len >> 2);
- *buflen -= (4 + len);
-
- return 0;
-}
-
-static int __rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen,
- int alloc, int local)
-{
- __u32 len;
-
- if (*buflen < sizeof(__u32)) {
- CERROR("buflen %u\n", *buflen);
- return -EINVAL;
- }
-
- obj->len = *(*buf)++;
- if (!local)
- obj->len = le32_to_cpu(obj->len);
- *buflen -= sizeof(__u32);
-
- if (!obj->len) {
- obj->data = NULL;
- return 0;
- }
-
- len = local ? obj->len : cfs_size_round4(obj->len);
- if (*buflen < len) {
- CERROR("buflen %u < %u\n", *buflen, len);
- obj->len = 0;
- return -EINVAL;
- }
-
- if (!alloc)
- obj->data = (__u8 *) *buf;
- else {
- OBD_ALLOC_LARGE(obj->data, obj->len);
- if (!obj->data) {
- CERROR("fail to alloc %u bytes\n", obj->len);
- obj->len = 0;
- return -ENOMEM;
- }
- memcpy(obj->data, *buf, obj->len);
- }
-
- *((char **)buf) += len;
- *buflen -= len;
-
- return 0;
-}
-
-int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen)
-{
- return __rawobj_extract(obj, buf, buflen, 0, 0);
-}
-
-int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
-{
- return __rawobj_extract(obj, buf, buflen, 1, 0);
-}
-
-int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen)
-{
- return __rawobj_extract(obj, buf, buflen, 0, 1);
-}
-
-int rawobj_extract_local_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen)
-{
- return __rawobj_extract(obj, buf, buflen, 1, 1);
-}
-
-int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj)
-{
- rawobj->len = netobj->len;
- rawobj->data = netobj->data;
- return 0;
-}
-
-int rawobj_from_netobj_alloc(rawobj_t *rawobj, netobj_t *netobj)
-{
- rawobj->len = 0;
- rawobj->data = NULL;
-
- if (netobj->len == 0)
- return 0;
-
- OBD_ALLOC_LARGE(rawobj->data, netobj->len);
- if (rawobj->data == NULL)
- return -ENOMEM;
-
- rawobj->len = netobj->len;
- memcpy(rawobj->data, netobj->data, netobj->len);
- return 0;
-}
-
-/****************************************
- * misc more *
- ****************************************/
-
-int buffer_extract_bytes(const void **buf, __u32 *buflen,
- void *res, __u32 reslen)
-{
- if (*buflen < reslen) {
- CERROR("buflen %u < %u\n", *buflen, reslen);
- return -EINVAL;
- }
-
- memcpy(res, *buf, reslen);
- *buf += reslen;
- *buflen -= reslen;
- return 0;
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_svc_upcall.c b/drivers/staging/lustre/lustre/ptlrpc/gss/gss_svc_upcall.c
deleted file mode 100644
index 359c48ec2f5b..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/gss_svc_upcall.c
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * Neil Brown <neilb@cse.unsw.edu.au>
- * J. Bruce Fields <bfields@umich.edu>
- * Andy Adamson <andros@umich.edu>
- * Dug Song <dugsong@monkey.org>
- *
- * RPCSEC_GSS server authentication.
- * This implements RPCSEC_GSS as defined in rfc2203 (rpcsec_gss) and rfc2078
- * (gssapi)
- *
- * The RPCSEC_GSS involves three stages:
- * 1/ context creation
- * 2/ data exchange
- * 3/ context destruction
- *
- * Context creation is handled largely by upcalls to user-space.
- * In particular, GSS_Accept_sec_context is handled by an upcall
- * Data exchange is handled entirely within the kernel
- * In particular, GSS_GetMIC, GSS_VerifyMIC, GSS_Seal, GSS_Unseal are in-kernel.
- * Context destruction is handled in-kernel
- * GSS_Delete_sec_context is in-kernel
- *
- * Context creation is initiated by a RPCSEC_GSS_INIT request arriving.
- * The context handle and gss_token are used as a key into the rpcsec_init cache.
- * The content of this cache includes some of the outputs of GSS_Accept_sec_context,
- * being major_status, minor_status, context_handle, reply_token.
- * These are sent back to the client.
- * Sequence window management is handled by the kernel. The window size if currently
- * a compile time constant.
- *
- * When user-space is happy that a context is established, it places an entry
- * in the rpcsec_context cache. The key for this cache is the context_handle.
- * The content includes:
- * uid/gidlist - for determining access rights
- * mechanism type
- * mechanism specific information, such as a key
- *
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/hash.h>
-#include <linux/mutex.h>
-#include <linux/sunrpc/cache.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-#define GSS_SVC_UPCALL_TIMEOUT (20)
-
-static spinlock_t __ctx_index_lock;
-static __u64 __ctx_index;
-
-__u64 gss_get_next_ctx_index(void)
-{
- __u64 idx;
-
- spin_lock(&__ctx_index_lock);
- idx = __ctx_index++;
- spin_unlock(&__ctx_index_lock);
-
- return idx;
-}
-
-static inline unsigned long hash_mem(char *buf, int length, int bits)
-{
- unsigned long hash = 0;
- unsigned long l = 0;
- int len = 0;
- unsigned char c;
-
- do {
- if (len == length) {
- c = (char) len;
- len = -1;
- } else
- c = *buf++;
-
- l = (l << 8) | c;
- len++;
-
- if ((len & (BITS_PER_LONG/8-1)) == 0)
- hash = hash_long(hash^l, BITS_PER_LONG);
- } while (len);
-
- return hash >> (BITS_PER_LONG - bits);
-}
-
-/****************************************
- * rsi cache *
- ****************************************/
-
-#define RSI_HASHBITS (6)
-#define RSI_HASHMAX (1 << RSI_HASHBITS)
-#define RSI_HASHMASK (RSI_HASHMAX - 1)
-
-struct rsi {
- struct cache_head h;
- __u32 lustre_svc;
- __u64 nid;
- wait_queue_head_t waitq;
- rawobj_t in_handle, in_token;
- rawobj_t out_handle, out_token;
- int major_status, minor_status;
-};
-
-static struct cache_head *rsi_table[RSI_HASHMAX];
-static struct cache_detail rsi_cache;
-static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
-static struct rsi *rsi_lookup(struct rsi *item);
-
-static inline int rsi_hash(struct rsi *item)
-{
- return hash_mem((char *)item->in_handle.data, item->in_handle.len,
- RSI_HASHBITS) ^
- hash_mem((char *)item->in_token.data, item->in_token.len,
- RSI_HASHBITS);
-}
-
-static inline int __rsi_match(struct rsi *item, struct rsi *tmp)
-{
- return (rawobj_equal(&item->in_handle, &tmp->in_handle) &&
- rawobj_equal(&item->in_token, &tmp->in_token));
-}
-
-static void rsi_free(struct rsi *rsi)
-{
- rawobj_free(&rsi->in_handle);
- rawobj_free(&rsi->in_token);
- rawobj_free(&rsi->out_handle);
- rawobj_free(&rsi->out_token);
-}
-
-static void rsi_request(struct cache_detail *cd,
- struct cache_head *h,
- char **bpp, int *blen)
-{
- struct rsi *rsi = container_of(h, struct rsi, h);
- __u64 index = 0;
-
- /* if in_handle is null, provide kernel suggestion */
- if (rsi->in_handle.len == 0)
- index = gss_get_next_ctx_index();
-
- qword_addhex(bpp, blen, (char *) &rsi->lustre_svc,
- sizeof(rsi->lustre_svc));
- qword_addhex(bpp, blen, (char *) &rsi->nid, sizeof(rsi->nid));
- qword_addhex(bpp, blen, (char *) &index, sizeof(index));
- qword_addhex(bpp, blen, rsi->in_handle.data, rsi->in_handle.len);
- qword_addhex(bpp, blen, rsi->in_token.data, rsi->in_token.len);
- (*bpp)[-1] = '\n';
-}
-
-static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
-{
- return sunrpc_cache_pipe_upcall(cd, h, rsi_request);
-}
-
-static inline void __rsi_init(struct rsi *new, struct rsi *item)
-{
- new->out_handle = RAWOBJ_EMPTY;
- new->out_token = RAWOBJ_EMPTY;
-
- new->in_handle = item->in_handle;
- item->in_handle = RAWOBJ_EMPTY;
- new->in_token = item->in_token;
- item->in_token = RAWOBJ_EMPTY;
-
- new->lustre_svc = item->lustre_svc;
- new->nid = item->nid;
- init_waitqueue_head(&new->waitq);
-}
-
-static inline void __rsi_update(struct rsi *new, struct rsi *item)
-{
- LASSERT(new->out_handle.len == 0);
- LASSERT(new->out_token.len == 0);
-
- new->out_handle = item->out_handle;
- item->out_handle = RAWOBJ_EMPTY;
- new->out_token = item->out_token;
- item->out_token = RAWOBJ_EMPTY;
-
- new->major_status = item->major_status;
- new->minor_status = item->minor_status;
-}
-
-static void rsi_put(struct kref *ref)
-{
- struct rsi *rsi = container_of(ref, struct rsi, h.ref);
-
- LASSERT(rsi->h.next == NULL);
- rsi_free(rsi);
- OBD_FREE_PTR(rsi);
-}
-
-static int rsi_match(struct cache_head *a, struct cache_head *b)
-{
- struct rsi *item = container_of(a, struct rsi, h);
- struct rsi *tmp = container_of(b, struct rsi, h);
-
- return __rsi_match(item, tmp);
-}
-
-static void rsi_init(struct cache_head *cnew, struct cache_head *citem)
-{
- struct rsi *new = container_of(cnew, struct rsi, h);
- struct rsi *item = container_of(citem, struct rsi, h);
-
- __rsi_init(new, item);
-}
-
-static void update_rsi(struct cache_head *cnew, struct cache_head *citem)
-{
- struct rsi *new = container_of(cnew, struct rsi, h);
- struct rsi *item = container_of(citem, struct rsi, h);
-
- __rsi_update(new, item);
-}
-
-static struct cache_head *rsi_alloc(void)
-{
- struct rsi *rsi;
-
- OBD_ALLOC_PTR(rsi);
- if (rsi)
- return &rsi->h;
- else
- return NULL;
-}
-
-static int rsi_parse(struct cache_detail *cd, char *mesg, int mlen)
-{
- char *buf = mesg;
- char *ep;
- int len;
- struct rsi rsii, *rsip = NULL;
- time_t expiry;
- int status = -EINVAL;
-
- memset(&rsii, 0, sizeof(rsii));
-
- /* handle */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
- if (rawobj_alloc(&rsii.in_handle, buf, len)) {
- status = -ENOMEM;
- goto out;
- }
-
- /* token */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
- if (rawobj_alloc(&rsii.in_token, buf, len)) {
- status = -ENOMEM;
- goto out;
- }
-
- rsip = rsi_lookup(&rsii);
- if (!rsip)
- goto out;
-
- rsii.h.flags = 0;
- /* expiry */
- expiry = get_expiry(&mesg);
- if (expiry == 0)
- goto out;
-
- len = qword_get(&mesg, buf, mlen);
- if (len <= 0)
- goto out;
-
- /* major */
- rsii.major_status = simple_strtol(buf, &ep, 10);
- if (*ep)
- goto out;
-
- /* minor */
- len = qword_get(&mesg, buf, mlen);
- if (len <= 0)
- goto out;
- rsii.minor_status = simple_strtol(buf, &ep, 10);
- if (*ep)
- goto out;
-
- /* out_handle */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
- if (rawobj_alloc(&rsii.out_handle, buf, len)) {
- status = -ENOMEM;
- goto out;
- }
-
- /* out_token */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
- if (rawobj_alloc(&rsii.out_token, buf, len)) {
- status = -ENOMEM;
- goto out;
- }
-
- rsii.h.expiry_time = expiry;
- rsip = rsi_update(&rsii, rsip);
- status = 0;
-out:
- rsi_free(&rsii);
- if (rsip) {
- wake_up_all(&rsip->waitq);
- cache_put(&rsip->h, &rsi_cache);
- } else {
- status = -ENOMEM;
- }
-
- if (status)
- CERROR("rsi parse error %d\n", status);
- return status;
-}
-
-static struct cache_detail rsi_cache = {
- .hash_size = RSI_HASHMAX,
- .hash_table = rsi_table,
- .name = "auth.sptlrpc.init",
- .cache_put = rsi_put,
- .cache_upcall = rsi_upcall,
- .cache_parse = rsi_parse,
- .match = rsi_match,
- .init = rsi_init,
- .update = update_rsi,
- .alloc = rsi_alloc,
-};
-
-static struct rsi *rsi_lookup(struct rsi *item)
-{
- struct cache_head *ch;
- int hash = rsi_hash(item);
-
- ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
- if (ch)
- return container_of(ch, struct rsi, h);
- else
- return NULL;
-}
-
-static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
-{
- struct cache_head *ch;
- int hash = rsi_hash(new);
-
- ch = sunrpc_cache_update(&rsi_cache, &new->h, &old->h, hash);
- if (ch)
- return container_of(ch, struct rsi, h);
- else
- return NULL;
-}
-
-/****************************************
- * rsc cache *
- ****************************************/
-
-#define RSC_HASHBITS (10)
-#define RSC_HASHMAX (1 << RSC_HASHBITS)
-#define RSC_HASHMASK (RSC_HASHMAX - 1)
-
-struct rsc {
- struct cache_head h;
- struct obd_device *target;
- rawobj_t handle;
- struct gss_svc_ctx ctx;
-};
-
-static struct cache_head *rsc_table[RSC_HASHMAX];
-static struct cache_detail rsc_cache;
-static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
-static struct rsc *rsc_lookup(struct rsc *item);
-
-static void rsc_free(struct rsc *rsci)
-{
- rawobj_free(&rsci->handle);
- rawobj_free(&rsci->ctx.gsc_rvs_hdl);
- lgss_delete_sec_context(&rsci->ctx.gsc_mechctx);
-}
-
-static inline int rsc_hash(struct rsc *rsci)
-{
- return hash_mem((char *)rsci->handle.data,
- rsci->handle.len, RSC_HASHBITS);
-}
-
-static inline int __rsc_match(struct rsc *new, struct rsc *tmp)
-{
- return rawobj_equal(&new->handle, &tmp->handle);
-}
-
-static inline void __rsc_init(struct rsc *new, struct rsc *tmp)
-{
- new->handle = tmp->handle;
- tmp->handle = RAWOBJ_EMPTY;
-
- new->target = NULL;
- memset(&new->ctx, 0, sizeof(new->ctx));
- new->ctx.gsc_rvs_hdl = RAWOBJ_EMPTY;
-}
-
-static inline void __rsc_update(struct rsc *new, struct rsc *tmp)
-{
- new->ctx = tmp->ctx;
- tmp->ctx.gsc_rvs_hdl = RAWOBJ_EMPTY;
- tmp->ctx.gsc_mechctx = NULL;
-
- memset(&new->ctx.gsc_seqdata, 0, sizeof(new->ctx.gsc_seqdata));
- spin_lock_init(&new->ctx.gsc_seqdata.ssd_lock);
-}
-
-static void rsc_put(struct kref *ref)
-{
- struct rsc *rsci = container_of(ref, struct rsc, h.ref);
-
- LASSERT(rsci->h.next == NULL);
- rsc_free(rsci);
- OBD_FREE_PTR(rsci);
-}
-
-static int rsc_match(struct cache_head *a, struct cache_head *b)
-{
- struct rsc *new = container_of(a, struct rsc, h);
- struct rsc *tmp = container_of(b, struct rsc, h);
-
- return __rsc_match(new, tmp);
-}
-
-static void rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
-{
- struct rsc *new = container_of(cnew, struct rsc, h);
- struct rsc *tmp = container_of(ctmp, struct rsc, h);
-
- __rsc_init(new, tmp);
-}
-
-static void update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
-{
- struct rsc *new = container_of(cnew, struct rsc, h);
- struct rsc *tmp = container_of(ctmp, struct rsc, h);
-
- __rsc_update(new, tmp);
-}
-
-static struct cache_head * rsc_alloc(void)
-{
- struct rsc *rsc;
-
- OBD_ALLOC_PTR(rsc);
- if (rsc)
- return &rsc->h;
- else
- return NULL;
-}
-
-static int rsc_parse(struct cache_detail *cd, char *mesg, int mlen)
-{
- char *buf = mesg;
- int len, rv, tmp_int;
- struct rsc rsci, *rscp = NULL;
- time_t expiry;
- int status = -EINVAL;
- struct gss_api_mech *gm = NULL;
-
- memset(&rsci, 0, sizeof(rsci));
-
- /* context handle */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0) goto out;
- status = -ENOMEM;
- if (rawobj_alloc(&rsci.handle, buf, len))
- goto out;
-
- rsci.h.flags = 0;
- /* expiry */
- expiry = get_expiry(&mesg);
- status = -EINVAL;
- if (expiry == 0)
- goto out;
-
- /* remote flag */
- rv = get_int(&mesg, &tmp_int);
- if (rv) {
- CERROR("fail to get remote flag\n");
- goto out;
- }
- rsci.ctx.gsc_remote = (tmp_int != 0);
-
- /* root user flag */
- rv = get_int(&mesg, &tmp_int);
- if (rv) {
- CERROR("fail to get oss user flag\n");
- goto out;
- }
- rsci.ctx.gsc_usr_root = (tmp_int != 0);
-
- /* mds user flag */
- rv = get_int(&mesg, &tmp_int);
- if (rv) {
- CERROR("fail to get mds user flag\n");
- goto out;
- }
- rsci.ctx.gsc_usr_mds = (tmp_int != 0);
-
- /* oss user flag */
- rv = get_int(&mesg, &tmp_int);
- if (rv) {
- CERROR("fail to get oss user flag\n");
- goto out;
- }
- rsci.ctx.gsc_usr_oss = (tmp_int != 0);
-
- /* mapped uid */
- rv = get_int(&mesg, (int *) &rsci.ctx.gsc_mapped_uid);
- if (rv) {
- CERROR("fail to get mapped uid\n");
- goto out;
- }
-
- rscp = rsc_lookup(&rsci);
- if (!rscp)
- goto out;
-
- /* uid, or NEGATIVE */
- rv = get_int(&mesg, (int *) &rsci.ctx.gsc_uid);
- if (rv == -EINVAL)
- goto out;
- if (rv == -ENOENT) {
- CERROR("NOENT? set rsc entry negative\n");
- set_bit(CACHE_NEGATIVE, &rsci.h.flags);
- } else {
- rawobj_t tmp_buf;
- unsigned long ctx_expiry;
-
- /* gid */
- if (get_int(&mesg, (int *) &rsci.ctx.gsc_gid))
- goto out;
-
- /* mech name */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
- gm = lgss_name_to_mech(buf);
- status = -EOPNOTSUPP;
- if (!gm)
- goto out;
-
- status = -EINVAL;
- /* mech-specific data: */
- len = qword_get(&mesg, buf, mlen);
- if (len < 0)
- goto out;
-
- tmp_buf.len = len;
- tmp_buf.data = (unsigned char *)buf;
- if (lgss_import_sec_context(&tmp_buf, gm,
- &rsci.ctx.gsc_mechctx))
- goto out;
-
- /* currently the expiry time passed down from user-space
- * is invalid, here we retrieve it from mech. */
- if (lgss_inquire_context(rsci.ctx.gsc_mechctx, &ctx_expiry)) {
- CERROR("unable to get expire time, drop it\n");
- goto out;
- }
- expiry = (time_t) ctx_expiry;
- }
-
- rsci.h.expiry_time = expiry;
- rscp = rsc_update(&rsci, rscp);
- status = 0;
-out:
- if (gm)
- lgss_mech_put(gm);
- rsc_free(&rsci);
- if (rscp)
- cache_put(&rscp->h, &rsc_cache);
- else
- status = -ENOMEM;
-
- if (status)
- CERROR("parse rsc error %d\n", status);
- return status;
-}
-
-static struct cache_detail rsc_cache = {
- .hash_size = RSC_HASHMAX,
- .hash_table = rsc_table,
- .name = "auth.sptlrpc.context",
- .cache_put = rsc_put,
- .cache_parse = rsc_parse,
- .match = rsc_match,
- .init = rsc_init,
- .update = update_rsc,
- .alloc = rsc_alloc,
-};
-
-static struct rsc *rsc_lookup(struct rsc *item)
-{
- struct cache_head *ch;
- int hash = rsc_hash(item);
-
- ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
- if (ch)
- return container_of(ch, struct rsc, h);
- else
- return NULL;
-}
-
-static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
-{
- struct cache_head *ch;
- int hash = rsc_hash(new);
-
- ch = sunrpc_cache_update(&rsc_cache, &new->h, &old->h, hash);
- if (ch)
- return container_of(ch, struct rsc, h);
- else
- return NULL;
-}
-
-#define COMPAT_RSC_PUT(item, cd) cache_put((item), (cd))
-
-/****************************************
- * rsc cache flush *
- ****************************************/
-
-typedef int rsc_entry_match(struct rsc *rscp, long data);
-
-static void rsc_flush(rsc_entry_match *match, long data)
-{
- struct cache_head **ch;
- struct rsc *rscp;
- int n;
-
- write_lock(&rsc_cache.hash_lock);
- for (n = 0; n < RSC_HASHMAX; n++) {
- for (ch = &rsc_cache.hash_table[n]; *ch;) {
- rscp = container_of(*ch, struct rsc, h);
-
- if (!match(rscp, data)) {
- ch = &((*ch)->next);
- continue;
- }
-
- /* it seems simply set NEGATIVE doesn't work */
- *ch = (*ch)->next;
- rscp->h.next = NULL;
- cache_get(&rscp->h);
- set_bit(CACHE_NEGATIVE, &rscp->h.flags);
- COMPAT_RSC_PUT(&rscp->h, &rsc_cache);
- rsc_cache.entries--;
- }
- }
- write_unlock(&rsc_cache.hash_lock);
-}
-
-static int match_uid(struct rsc *rscp, long uid)
-{
- if ((int) uid == -1)
- return 1;
- return ((int) rscp->ctx.gsc_uid == (int) uid);
-}
-
-static int match_target(struct rsc *rscp, long target)
-{
- return (rscp->target == (struct obd_device *) target);
-}
-
-static inline void rsc_flush_uid(int uid)
-{
- if (uid == -1)
- CWARN("flush all gss contexts...\n");
-
- rsc_flush(match_uid, (long) uid);
-}
-
-static inline void rsc_flush_target(struct obd_device *target)
-{
- rsc_flush(match_target, (long) target);
-}
-
-void gss_secsvc_flush(struct obd_device *target)
-{
- rsc_flush_target(target);
-}
-EXPORT_SYMBOL(gss_secsvc_flush);
-
-static struct rsc *gss_svc_searchbyctx(rawobj_t *handle)
-{
- struct rsc rsci;
- struct rsc *found;
-
- memset(&rsci, 0, sizeof(rsci));
- if (rawobj_dup(&rsci.handle, handle))
- return NULL;
-
- found = rsc_lookup(&rsci);
- rsc_free(&rsci);
- if (!found)
- return NULL;
- if (cache_check(&rsc_cache, &found->h, NULL))
- return NULL;
- return found;
-}
-
-int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
- struct gss_sec *gsec,
- struct gss_cli_ctx *gctx)
-{
- struct rsc rsci, *rscp = NULL;
- unsigned long ctx_expiry;
- __u32 major;
- int rc;
-
- memset(&rsci, 0, sizeof(rsci));
-
- if (rawobj_alloc(&rsci.handle, (char *) &gsec->gs_rvs_hdl,
- sizeof(gsec->gs_rvs_hdl)))
- GOTO(out, rc = -ENOMEM);
-
- rscp = rsc_lookup(&rsci);
- if (rscp == NULL)
- GOTO(out, rc = -ENOMEM);
-
- major = lgss_copy_reverse_context(gctx->gc_mechctx,
- &rsci.ctx.gsc_mechctx);
- if (major != GSS_S_COMPLETE)
- GOTO(out, rc = -ENOMEM);
-
- if (lgss_inquire_context(rsci.ctx.gsc_mechctx, &ctx_expiry)) {
- CERROR("unable to get expire time, drop it\n");
- GOTO(out, rc = -EINVAL);
- }
- rsci.h.expiry_time = (time_t) ctx_expiry;
-
- if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0)
- rsci.ctx.gsc_usr_mds = 1;
- else if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0)
- rsci.ctx.gsc_usr_oss = 1;
- else
- rsci.ctx.gsc_usr_root = 1;
-
- rscp = rsc_update(&rsci, rscp);
- if (rscp == NULL)
- GOTO(out, rc = -ENOMEM);
-
- rscp->target = imp->imp_obd;
- rawobj_dup(&gctx->gc_svc_handle, &rscp->handle);
-
- CWARN("create reverse svc ctx %p to %s: idx "LPX64"\n",
- &rscp->ctx, obd2cli_tgt(imp->imp_obd), gsec->gs_rvs_hdl);
- rc = 0;
-out:
- if (rscp)
- cache_put(&rscp->h, &rsc_cache);
- rsc_free(&rsci);
-
- if (rc)
- CERROR("create reverse svc ctx: idx "LPX64", rc %d\n",
- gsec->gs_rvs_hdl, rc);
- return rc;
-}
-
-int gss_svc_upcall_expire_rvs_ctx(rawobj_t *handle)
-{
- const cfs_time_t expire = 20;
- struct rsc *rscp;
-
- rscp = gss_svc_searchbyctx(handle);
- if (rscp) {
- CDEBUG(D_SEC, "reverse svcctx %p (rsc %p) expire soon\n",
- &rscp->ctx, rscp);
-
- rscp->h.expiry_time = cfs_time_current_sec() + expire;
- COMPAT_RSC_PUT(&rscp->h, &rsc_cache);
- }
- return 0;
-}
-
-int gss_svc_upcall_dup_handle(rawobj_t *handle, struct gss_svc_ctx *ctx)
-{
- struct rsc *rscp = container_of(ctx, struct rsc, ctx);
-
- return rawobj_dup(handle, &rscp->handle);
-}
-
-int gss_svc_upcall_update_sequence(rawobj_t *handle, __u32 seq)
-{
- struct rsc *rscp;
-
- rscp = gss_svc_searchbyctx(handle);
- if (rscp) {
- CDEBUG(D_SEC, "reverse svcctx %p (rsc %p) update seq to %u\n",
- &rscp->ctx, rscp, seq + 1);
-
- rscp->ctx.gsc_rvs_seq = seq + 1;
- COMPAT_RSC_PUT(&rscp->h, &rsc_cache);
- }
- return 0;
-}
-
-static struct cache_deferred_req* cache_upcall_defer(struct cache_req *req)
-{
- return NULL;
-}
-static struct cache_req cache_upcall_chandle = { cache_upcall_defer };
-
-int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
- struct gss_svc_reqctx *grctx,
- struct gss_wire_ctx *gw,
- struct obd_device *target,
- __u32 lustre_svc,
- rawobj_t *rvs_hdl,
- rawobj_t *in_token)
-{
- struct ptlrpc_reply_state *rs;
- struct rsc *rsci = NULL;
- struct rsi *rsip = NULL, rsikey;
- wait_queue_t wait;
- int replen = sizeof(struct ptlrpc_body);
- struct gss_rep_header *rephdr;
- int first_check = 1;
- int rc = SECSVC_DROP;
-
- memset(&rsikey, 0, sizeof(rsikey));
- rsikey.lustre_svc = lustre_svc;
- rsikey.nid = (__u64) req->rq_peer.nid;
-
- /* duplicate context handle. for INIT it always 0 */
- if (rawobj_dup(&rsikey.in_handle, &gw->gw_handle)) {
- CERROR("fail to dup context handle\n");
- GOTO(out, rc);
- }
-
- if (rawobj_dup(&rsikey.in_token, in_token)) {
- CERROR("can't duplicate token\n");
- rawobj_free(&rsikey.in_handle);
- GOTO(out, rc);
- }
-
- rsip = rsi_lookup(&rsikey);
- rsi_free(&rsikey);
- if (!rsip) {
- CERROR("error in rsi_lookup.\n");
-
- if (!gss_pack_err_notify(req, GSS_S_FAILURE, 0))
- rc = SECSVC_COMPLETE;
-
- GOTO(out, rc);
- }
-
- cache_get(&rsip->h); /* take an extra ref */
- init_waitqueue_head(&rsip->waitq);
- init_waitqueue_entry(&wait, current);
- add_wait_queue(&rsip->waitq, &wait);
-
-cache_check:
- /* Note each time cache_check() will drop a reference if return
- * non-zero. We hold an extra reference on initial rsip, but must
- * take care of following calls. */
- rc = cache_check(&rsi_cache, &rsip->h, &cache_upcall_chandle);
- switch (rc) {
- case -EAGAIN: {
- int valid;
-
- if (first_check) {
- first_check = 0;
-
- read_lock(&rsi_cache.hash_lock);
- valid = test_bit(CACHE_VALID, &rsip->h.flags);
- if (valid == 0)
- set_current_state(TASK_INTERRUPTIBLE);
- read_unlock(&rsi_cache.hash_lock);
-
- if (valid == 0)
- schedule_timeout(GSS_SVC_UPCALL_TIMEOUT *
- HZ);
-
- cache_get(&rsip->h);
- goto cache_check;
- }
- CWARN("waited %ds timeout, drop\n", GSS_SVC_UPCALL_TIMEOUT);
- break;
- }
- case -ENOENT:
- CWARN("cache_check return ENOENT, drop\n");
- break;
- case 0:
- /* if not the first check, we have to release the extra
- * reference we just added on it. */
- if (!first_check)
- cache_put(&rsip->h, &rsi_cache);
- CDEBUG(D_SEC, "cache_check is good\n");
- break;
- }
-
- remove_wait_queue(&rsip->waitq, &wait);
- cache_put(&rsip->h, &rsi_cache);
-
- if (rc)
- GOTO(out, rc = SECSVC_DROP);
-
- rc = SECSVC_DROP;
- rsci = gss_svc_searchbyctx(&rsip->out_handle);
- if (!rsci) {
- CERROR("authentication failed\n");
-
- if (!gss_pack_err_notify(req, GSS_S_FAILURE, 0))
- rc = SECSVC_COMPLETE;
-
- GOTO(out, rc);
- } else {
- cache_get(&rsci->h);
- grctx->src_ctx = &rsci->ctx;
- }
-
- if (rawobj_dup(&rsci->ctx.gsc_rvs_hdl, rvs_hdl)) {
- CERROR("failed duplicate reverse handle\n");
- GOTO(out, rc);
- }
-
- rsci->target = target;
-
- CDEBUG(D_SEC, "server create rsc %p(%u->%s)\n",
- rsci, rsci->ctx.gsc_uid, libcfs_nid2str(req->rq_peer.nid));
-
- if (rsip->out_handle.len > PTLRPC_GSS_MAX_HANDLE_SIZE) {
- CERROR("handle size %u too large\n", rsip->out_handle.len);
- GOTO(out, rc = SECSVC_DROP);
- }
-
- grctx->src_init = 1;
- grctx->src_reserve_len = cfs_size_round4(rsip->out_token.len);
-
- rc = lustre_pack_reply_v2(req, 1, &replen, NULL, 0);
- if (rc) {
- CERROR("failed to pack reply: %d\n", rc);
- GOTO(out, rc = SECSVC_DROP);
- }
-
- rs = req->rq_reply_state;
- LASSERT(rs->rs_repbuf->lm_bufcount == 3);
- LASSERT(rs->rs_repbuf->lm_buflens[0] >=
- sizeof(*rephdr) + rsip->out_handle.len);
- LASSERT(rs->rs_repbuf->lm_buflens[2] >= rsip->out_token.len);
-
- rephdr = lustre_msg_buf(rs->rs_repbuf, 0, 0);
- rephdr->gh_version = PTLRPC_GSS_VERSION;
- rephdr->gh_flags = 0;
- rephdr->gh_proc = PTLRPC_GSS_PROC_ERR;
- rephdr->gh_major = rsip->major_status;
- rephdr->gh_minor = rsip->minor_status;
- rephdr->gh_seqwin = GSS_SEQ_WIN;
- rephdr->gh_handle.len = rsip->out_handle.len;
- memcpy(rephdr->gh_handle.data, rsip->out_handle.data,
- rsip->out_handle.len);
-
- memcpy(lustre_msg_buf(rs->rs_repbuf, 2, 0), rsip->out_token.data,
- rsip->out_token.len);
-
- rs->rs_repdata_len = lustre_shrink_msg(rs->rs_repbuf, 2,
- rsip->out_token.len, 0);
-
- rc = SECSVC_OK;
-
-out:
- /* it looks like here we should put rsip also, but this mess up
- * with NFS cache mgmt code... FIXME */
-#if 0
- if (rsip)
- rsi_put(&rsip->h, &rsi_cache);
-#endif
-
- if (rsci) {
- /* if anything went wrong, we don't keep the context too */
- if (rc != SECSVC_OK)
- set_bit(CACHE_NEGATIVE, &rsci->h.flags);
- else
- CDEBUG(D_SEC, "create rsc with idx "LPX64"\n",
- gss_handle_to_u64(&rsci->handle));
-
- COMPAT_RSC_PUT(&rsci->h, &rsc_cache);
- }
- return rc;
-}
-
-struct gss_svc_ctx *gss_svc_upcall_get_ctx(struct ptlrpc_request *req,
- struct gss_wire_ctx *gw)
-{
- struct rsc *rsc;
-
- rsc = gss_svc_searchbyctx(&gw->gw_handle);
- if (!rsc) {
- CWARN("Invalid gss ctx idx "LPX64" from %s\n",
- gss_handle_to_u64(&gw->gw_handle),
- libcfs_nid2str(req->rq_peer.nid));
- return NULL;
- }
-
- return &rsc->ctx;
-}
-
-void gss_svc_upcall_put_ctx(struct gss_svc_ctx *ctx)
-{
- struct rsc *rsc = container_of(ctx, struct rsc, ctx);
-
- COMPAT_RSC_PUT(&rsc->h, &rsc_cache);
-}
-
-void gss_svc_upcall_destroy_ctx(struct gss_svc_ctx *ctx)
-{
- struct rsc *rsc = container_of(ctx, struct rsc, ctx);
-
- /* can't be found */
- set_bit(CACHE_NEGATIVE, &rsc->h.flags);
- /* to be removed at next scan */
- rsc->h.expiry_time = 1;
-}
-
-int __init gss_init_svc_upcall(void)
-{
- int i;
-
- spin_lock_init(&__ctx_index_lock);
- /*
- * this helps reducing context index confliction. after server reboot,
- * conflicting request from clients might be filtered out by initial
- * sequence number checking, thus no chance to sent error notification
- * back to clients.
- */
- cfs_get_random_bytes(&__ctx_index, sizeof(__ctx_index));
-
-
- cache_register(&rsi_cache);
- cache_register(&rsc_cache);
-
- /* FIXME this looks stupid. we intend to give lsvcgssd a chance to open
- * the init upcall channel, otherwise there's big chance that the first
- * upcall issued before the channel be opened thus nfsv4 cache code will
- * drop the request direclty, thus lead to unnecessary recovery time.
- * here we wait at maximum 1.5 seconds. */
- for (i = 0; i < 6; i++) {
- if (atomic_read(&rsi_cache.readers) > 0)
- break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- LASSERT(HZ >= 4);
- schedule_timeout(HZ / 4);
- }
-
- if (atomic_read(&rsi_cache.readers) == 0)
- CWARN("Init channel is not opened by lsvcgssd, following "
- "request might be dropped until lsvcgssd is active\n");
-
- return 0;
-}
-
-void __exit gss_exit_svc_upcall(void)
-{
- cache_purge(&rsi_cache);
- cache_unregister(&rsi_cache);
-
- cache_purge(&rsc_cache);
- cache_unregister(&rsc_cache);
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c b/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c
deleted file mode 100644
index a0a74e5542ed..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/lproc_gss.c
+++ /dev/null
@@ -1,220 +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.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lprocfs_status.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-static struct proc_dir_entry *gss_proc_root = NULL;
-static struct proc_dir_entry *gss_proc_lk = NULL;
-
-/*
- * statistic of "out-of-sequence-window"
- */
-static struct {
- spinlock_t oos_lock;
- atomic_t oos_cli_count; /* client occurrence */
- int oos_cli_behind; /* client max seqs behind */
- atomic_t oos_svc_replay[3]; /* server replay detected */
- atomic_t oos_svc_pass[3]; /* server verified ok */
-} gss_stat_oos = {
- .oos_cli_count = ATOMIC_INIT(0),
- .oos_cli_behind = 0,
- .oos_svc_replay = { ATOMIC_INIT(0), },
- .oos_svc_pass = { ATOMIC_INIT(0), },
-};
-
-void gss_stat_oos_record_cli(int behind)
-{
- atomic_inc(&gss_stat_oos.oos_cli_count);
-
- spin_lock(&gss_stat_oos.oos_lock);
- if (behind > gss_stat_oos.oos_cli_behind)
- gss_stat_oos.oos_cli_behind = behind;
- spin_unlock(&gss_stat_oos.oos_lock);
-}
-
-void gss_stat_oos_record_svc(int phase, int replay)
-{
- LASSERT(phase >= 0 && phase <= 2);
-
- if (replay)
- atomic_inc(&gss_stat_oos.oos_svc_replay[phase]);
- else
- atomic_inc(&gss_stat_oos.oos_svc_pass[phase]);
-}
-
-static int gss_proc_oos_seq_show(struct seq_file *m, void *v)
-{
- return seq_printf(m,
- "seqwin: %u\n"
- "backwin: %u\n"
- "client fall behind seqwin\n"
- " occurrence: %d\n"
- " max seq behind: %d\n"
- "server replay detected:\n"
- " phase 0: %d\n"
- " phase 1: %d\n"
- " phase 2: %d\n"
- "server verify ok:\n"
- " phase 2: %d\n",
- GSS_SEQ_WIN_MAIN,
- GSS_SEQ_WIN_BACK,
- atomic_read(&gss_stat_oos.oos_cli_count),
- gss_stat_oos.oos_cli_behind,
- atomic_read(&gss_stat_oos.oos_svc_replay[0]),
- atomic_read(&gss_stat_oos.oos_svc_replay[1]),
- atomic_read(&gss_stat_oos.oos_svc_replay[2]),
- atomic_read(&gss_stat_oos.oos_svc_pass[2]));
-}
-LPROC_SEQ_FOPS_RO(gss_proc_oos);
-
-static int gss_proc_write_secinit(struct file *file, const char *buffer,
- size_t count, off_t *off)
-{
- int rc;
-
- rc = gss_do_ctx_init_rpc((char *) buffer, count);
- if (rc) {
- LASSERT(rc < 0);
- return rc;
- }
-
- return count;
-}
-
-static const struct file_operations gss_proc_secinit = {
- .write = gss_proc_write_secinit,
-};
-
-static struct lprocfs_vars gss_lprocfs_vars[] = {
- { "replays", &gss_proc_oos_fops },
- { "init_channel", &gss_proc_secinit, NULL, 0222 },
- { NULL }
-};
-
-/*
- * for userspace helper lgss_keyring.
- *
- * debug_level: [0, 4], defined in utils/gss/lgss_utils.h
- */
-static int gss_lk_debug_level = 1;
-
-static int gss_lk_proc_dl_seq_show(struct seq_file *m, void *v)
-{
- return seq_printf(m, "%u\n", gss_lk_debug_level);
-}
-
-static int gss_lk_proc_dl_seq_write(struct file *file, const char *buffer,
- size_t count, off_t *off)
-{
- int val, rc;
-
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
-
- if (val < 0 || val > 4)
- return -ERANGE;
-
- gss_lk_debug_level = val;
- return count;
-}
-LPROC_SEQ_FOPS(gss_lk_proc_dl);
-
-static struct lprocfs_vars gss_lk_lprocfs_vars[] = {
- { "debug_level", &gss_lk_proc_dl_fops },
- { NULL }
-};
-
-void gss_exit_lproc(void)
-{
- if (gss_proc_lk) {
- lprocfs_remove(&gss_proc_lk);
- gss_proc_lk = NULL;
- }
-
- if (gss_proc_root) {
- lprocfs_remove(&gss_proc_root);
- gss_proc_root = NULL;
- }
-}
-
-int gss_init_lproc(void)
-{
- int rc;
-
- spin_lock_init(&gss_stat_oos.oos_lock);
-
- gss_proc_root = lprocfs_register("gss", sptlrpc_proc_root,
- gss_lprocfs_vars, NULL);
- if (IS_ERR(gss_proc_root)) {
- rc = PTR_ERR(gss_proc_root);
- gss_proc_root = NULL;
- GOTO(err_out, rc);
- }
-
- gss_proc_lk = lprocfs_register("lgss_keyring", gss_proc_root,
- gss_lk_lprocfs_vars, NULL);
- if (IS_ERR(gss_proc_lk)) {
- rc = PTR_ERR(gss_proc_lk);
- gss_proc_lk = NULL;
- GOTO(err_out, rc);
- }
-
- return 0;
-
-err_out:
- CERROR("failed to initialize gss lproc entries: %d\n", rc);
- gss_exit_lproc();
- return rc;
-}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c b/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c
deleted file mode 100644
index 383601cdd4e6..000000000000
--- a/drivers/staging/lustre/lustre/ptlrpc/gss/sec_gss.c
+++ /dev/null
@@ -1,2889 +0,0 @@
-/*
- * Modifications for Lustre
- *
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- *
- * Author: Eric Mei <ericm@clusterfs.com>
- */
-
-/*
- * linux/net/sunrpc/auth_gss.c
- *
- * RPCSEC_GSS client authentication.
- *
- * Copyright (c) 2000 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Dug Song <dugsong@monkey.org>
- * Andy Adamson <andros@umich.edu>
- *
- * 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 name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
- *
- */
-
-#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/dcache.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <asm/atomic.h>
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <obd_cksum.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_sec.h>
-
-#include "gss_err.h"
-#include "gss_internal.h"
-#include "gss_api.h"
-
-#include <linux/crypto.h>
-#include <linux/crc32.h>
-
-/*
- * early reply have fixed size, respectively in privacy and integrity mode.
- * so we calculate them only once.
- */
-static int gss_at_reply_off_integ;
-static int gss_at_reply_off_priv;
-
-
-static inline int msg_last_segidx(struct lustre_msg *msg)
-{
- LASSERT(msg->lm_bufcount > 0);
- return msg->lm_bufcount - 1;
-}
-static inline int msg_last_seglen(struct lustre_msg *msg)
-{
- return msg->lm_buflens[msg_last_segidx(msg)];
-}
-
-/********************************************
- * wire data swabber *
- ********************************************/
-
-static
-void gss_header_swabber(struct gss_header *ghdr)
-{
- __swab32s(&ghdr->gh_flags);
- __swab32s(&ghdr->gh_proc);
- __swab32s(&ghdr->gh_seq);
- __swab32s(&ghdr->gh_svc);
- __swab32s(&ghdr->gh_pad1);
- __swab32s(&ghdr->gh_handle.len);
-}
-
-struct gss_header *gss_swab_header(struct lustre_msg *msg, int segment,
- int swabbed)
-{
- struct gss_header *ghdr;
-
- ghdr = lustre_msg_buf(msg, segment, sizeof(*ghdr));
- if (ghdr == NULL)
- return NULL;
-
- if (swabbed)
- gss_header_swabber(ghdr);
-
- if (sizeof(*ghdr) + ghdr->gh_handle.len > msg->lm_buflens[segment]) {
- CERROR("gss header has length %d, now %u received\n",
- (int) sizeof(*ghdr) + ghdr->gh_handle.len,
- msg->lm_buflens[segment]);
- return NULL;
- }
-
- return ghdr;
-}
-
-#if 0
-static
-void gss_netobj_swabber(netobj_t *obj)
-{
- __swab32s(&obj->len);
-}
-
-netobj_t *gss_swab_netobj(struct lustre_msg *msg, int segment)
-{
- netobj_t *obj;
-
- obj = lustre_swab_buf(msg, segment, sizeof(*obj), gss_netobj_swabber);
- if (obj && sizeof(*obj) + obj->len > msg->lm_buflens[segment]) {
- CERROR("netobj require length %u but only %u received\n",
- (unsigned int) sizeof(*obj) + obj->len,
- msg->lm_buflens[segment]);
- return NULL;
- }
-
- return obj;
-}
-#endif
-
-/*
- * payload should be obtained from mechanism. but currently since we
- * only support kerberos, we could simply use fixed value.
- * krb5 "meta" data:
- * - krb5 header: 16
- * - krb5 checksum: 20
- *
- * for privacy mode, payload also include the cipher text which has the same
- * size as plain text, plus possible confounder, padding both at maximum cipher
- * block size.
- */
-#define GSS_KRB5_INTEG_MAX_PAYLOAD (40)
-
-static inline
-int gss_mech_payload(struct gss_ctx *mechctx, int msgsize, int privacy)
-{
- if (privacy)
- return GSS_KRB5_INTEG_MAX_PAYLOAD + 16 + 16 + 16 + msgsize;
- else
- return GSS_KRB5_INTEG_MAX_PAYLOAD;
-}
-
-/*
- * return signature size, otherwise < 0 to indicate error
- */
-static int gss_sign_msg(struct lustre_msg *msg,
- struct gss_ctx *mechctx,
- enum lustre_sec_part sp,
- __u32 flags, __u32 proc, __u32 seq, __u32 svc,
- rawobj_t *handle)
-{
- struct gss_header *ghdr;
- rawobj_t text[4], mic;
- int textcnt, max_textcnt, mic_idx;
- __u32 major;
-
- LASSERT(msg->lm_bufcount >= 2);
-
- /* gss hdr */
- LASSERT(msg->lm_buflens[0] >=
- sizeof(*ghdr) + (handle ? handle->len : 0));
- ghdr = lustre_msg_buf(msg, 0, 0);
-
- ghdr->gh_version = PTLRPC_GSS_VERSION;
- ghdr->gh_sp = (__u8) sp;
- ghdr->gh_flags = flags;
- ghdr->gh_proc = proc;
- ghdr->gh_seq = seq;
- ghdr->gh_svc = svc;
- if (!handle) {
- /* fill in a fake one */
- ghdr->gh_handle.len = 0;
- } else {
- ghdr->gh_handle.len = handle->len;
- memcpy(ghdr->gh_handle.data, handle->data, handle->len);
- }
-
- /* no actual signature for null mode */
- if (svc == SPTLRPC_SVC_NULL)
- return lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
-
- /* MIC */
- mic_idx = msg_last_segidx(msg);
- max_textcnt = (svc == SPTLRPC_SVC_AUTH) ? 1 : mic_idx;
-
- for (textcnt = 0; textcnt < max_textcnt; textcnt++) {
- text[textcnt].len = msg->lm_buflens[textcnt];
- text[textcnt].data = lustre_msg_buf(msg, textcnt, 0);
- }
-
- mic.len = msg->lm_buflens[mic_idx];
- mic.data = lustre_msg_buf(msg, mic_idx, 0);
-
- major = lgss_get_mic(mechctx, textcnt, text, 0, NULL, &mic);
- if (major != GSS_S_COMPLETE) {
- CERROR("fail to generate MIC: %08x\n", major);
- return -EPERM;
- }
- LASSERT(mic.len <= msg->lm_buflens[mic_idx]);
-
- return lustre_shrink_msg(msg, mic_idx, mic.len, 0);
-}
-
-/*
- * return gss error
- */
-static
-__u32 gss_verify_msg(struct lustre_msg *msg,
- struct gss_ctx *mechctx,
- __u32 svc)
-{
- rawobj_t text[4], mic;
- int textcnt, max_textcnt;
- int mic_idx;
- __u32 major;
-
- LASSERT(msg->lm_bufcount >= 2);
-
- if (svc == SPTLRPC_SVC_NULL)
- return GSS_S_COMPLETE;
-
- mic_idx = msg_last_segidx(msg);
- max_textcnt = (svc == SPTLRPC_SVC_AUTH) ? 1 : mic_idx;
-
- for (textcnt = 0; textcnt < max_textcnt; textcnt++) {
- text[textcnt].len = msg->lm_buflens[textcnt];
- text[textcnt].data = lustre_msg_buf(msg, textcnt, 0);
- }
-
- mic.len = msg->lm_buflens[mic_idx];
- mic.data = lustre_msg_buf(msg, mic_idx, 0);
-
- major = lgss_verify_mic(mechctx, textcnt, text, 0, NULL, &mic);
- if (major != GSS_S_COMPLETE)
- CERROR("mic verify error: %08x\n", major);
-
- return major;
-}
-
-/*
- * return gss error code
- */
-static
-__u32 gss_unseal_msg(struct gss_ctx *mechctx,
- struct lustre_msg *msgbuf,
- int *msg_len, int msgbuf_len)
-{
- rawobj_t clear_obj, hdrobj, token;
- __u8 *clear_buf;
- int clear_buflen;
- __u32 major;
-
- if (msgbuf->lm_bufcount != 2) {
- CERROR("invalid bufcount %d\n", msgbuf->lm_bufcount);
- return GSS_S_FAILURE;
- }
-
- /* allocate a temporary clear text buffer, same sized as token,
- * we assume the final clear text size <= token size */
- clear_buflen = lustre_msg_buflen(msgbuf, 1);
- OBD_ALLOC_LARGE(clear_buf, clear_buflen);
- if (!clear_buf)
- return GSS_S_FAILURE;
-
- /* buffer objects */
- hdrobj.len = lustre_msg_buflen(msgbuf, 0);
- hdrobj.data = lustre_msg_buf(msgbuf, 0, 0);
- token.len = lustre_msg_buflen(msgbuf, 1);
- token.data = lustre_msg_buf(msgbuf, 1, 0);
- clear_obj.len = clear_buflen;
- clear_obj.data = clear_buf;
-
- major = lgss_unwrap(mechctx, &hdrobj, &token, &clear_obj);
- if (major != GSS_S_COMPLETE) {
- CERROR("unwrap message error: %08x\n", major);
- GOTO(out_free, major = GSS_S_FAILURE);
- }
- LASSERT(clear_obj.len <= clear_buflen);
- LASSERT(clear_obj.len <= msgbuf_len);
-
- /* now the decrypted message */
- memcpy(msgbuf, clear_obj.data, clear_obj.len);
- *msg_len = clear_obj.len;
-
- major = GSS_S_COMPLETE;
-out_free:
- OBD_FREE_LARGE(clear_buf, clear_buflen);
- return major;
-}
-
-/********************************************
- * gss client context manipulation helpers *
- ********************************************/
-
-int cli_ctx_expire(struct ptlrpc_cli_ctx *ctx)
-{
- LASSERT(atomic_read(&ctx->cc_refcount));
-
- if (!test_and_set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags)) {
- if (!ctx->cc_early_expire)
- clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
-
- CWARN("ctx %p(%u->%s) get expired: %lu(%+lds)\n",
- ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
- ctx->cc_expire,
- ctx->cc_expire == 0 ? 0 :
- cfs_time_sub(ctx->cc_expire, cfs_time_current_sec()));
-
- sptlrpc_cli_ctx_wakeup(ctx);
- return 1;
- }
-
- return 0;
-}
-
-/*
- * return 1 if the context is dead.
- */
-int cli_ctx_check_death(struct ptlrpc_cli_ctx *ctx)
-{
- if (unlikely(cli_ctx_is_dead(ctx)))
- return 1;
-
- /* expire is 0 means never expire. a newly created gss context
- * which during upcall may has 0 expiration */
- if (ctx->cc_expire == 0)
- return 0;
-
- /* check real expiration */
- if (cfs_time_after(ctx->cc_expire, cfs_time_current_sec()))
- return 0;
-
- cli_ctx_expire(ctx);
- return 1;
-}
-
-void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx)
-{
- struct ptlrpc_cli_ctx *ctx = &gctx->gc_base;
- unsigned long ctx_expiry;
-
- if (lgss_inquire_context(gctx->gc_mechctx, &ctx_expiry)) {
- CERROR("ctx %p(%u): unable to inquire, expire it now\n",
- gctx, ctx->cc_vcred.vc_uid);
- ctx_expiry = 1; /* make it expired now */
- }
-
- ctx->cc_expire = gss_round_ctx_expiry(ctx_expiry,
- ctx->cc_sec->ps_flvr.sf_flags);
-
- /* At this point this ctx might have been marked as dead by
- * someone else, in which case nobody will make further use
- * of it. we don't care, and mark it UPTODATE will help
- * destroying server side context when it be destroyed. */
- set_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
-
- if (sec_is_reverse(ctx->cc_sec)) {
- CWARN("server installed reverse ctx %p idx "LPX64", "
- "expiry %lu(%+lds)\n", ctx,
- gss_handle_to_u64(&gctx->gc_handle),
- ctx->cc_expire, ctx->cc_expire - cfs_time_current_sec());
- } else {
- CWARN("client refreshed ctx %p idx "LPX64" (%u->%s), "
- "expiry %lu(%+lds)\n", ctx,
- gss_handle_to_u64(&gctx->gc_handle),
- ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
- ctx->cc_expire, ctx->cc_expire - cfs_time_current_sec());
-
- /* install reverse svc ctx for root context */
- if (ctx->cc_vcred.vc_uid == 0)
- gss_sec_install_rctx(ctx->cc_sec->ps_import,
- ctx->cc_sec, ctx);
- }
-
- sptlrpc_cli_ctx_wakeup(ctx);
-}
-
-static void gss_cli_ctx_finalize(struct gss_cli_ctx *gctx)
-{
- LASSERT(gctx->gc_base.cc_sec);
-
- if (gctx->gc_mechctx) {
- lgss_delete_sec_context(&gctx->gc_mechctx);
- gctx->gc_mechctx = NULL;
- }
-
- if (!rawobj_empty(&gctx->gc_svc_handle)) {
- /* forward ctx: mark buddy reverse svcctx soon-expire. */
- if (!sec_is_reverse(gctx->gc_base.cc_sec) &&
- !rawobj_empty(&gctx->gc_svc_handle))
- gss_svc_upcall_expire_rvs_ctx(&gctx->gc_svc_handle);
-
- rawobj_free(&gctx->gc_svc_handle);
- }
-
- rawobj_free(&gctx->gc_handle);
-}
-
-/*
- * Based on sequence number algorithm as specified in RFC 2203.
- *
- * modified for our own problem: arriving request has valid sequence number,
- * but unwrapping request might cost a long time, after that its sequence
- * are not valid anymore (fall behind the window). It rarely happen, mostly
- * under extreme load.
- *
- * note we should not check sequence before verify the integrity of incoming
- * request, because just one attacking request with high sequence number might
- * cause all following request be dropped.
- *
- * so here we use a multi-phase approach: prepare 2 sequence windows,
- * "main window" for normal sequence and "back window" for fall behind sequence.
- * and 3-phase checking mechanism:
- * 0 - before integrity verification, perform a initial sequence checking in
- * main window, which only try and don't actually set any bits. if the
- * sequence is high above the window or fit in the window and the bit
- * is 0, then accept and proceed to integrity verification. otherwise
- * reject this sequence.
- * 1 - after integrity verification, check in main window again. if this
- * sequence is high above the window or fit in the window and the bit
- * is 0, then set the bit and accept; if it fit in the window but bit
- * already set, then reject; if it fall behind the window, then proceed
- * to phase 2.
- * 2 - check in back window. if it is high above the window or fit in the
- * window and the bit is 0, then set the bit and accept. otherwise reject.
- *
- * return value:
- * 1: looks like a replay
- * 0: is ok
- * -1: is a replay
- *
- * note phase 0 is necessary, because otherwise replay attacking request of
- * sequence which between the 2 windows can't be detected.
- *
- * this mechanism can't totally solve the problem, but could help much less
- * number of valid requests be dropped.
- */
-static
-int gss_do_check_seq(unsigned long *window, __u32 win_size, __u32 *max_seq,
- __u32 seq_num, int phase)
-{
- LASSERT(phase >= 0 && phase <= 2);
-
- if (seq_num > *max_seq) {
- /*
- * 1. high above the window
- */
- if (phase == 0)
- return 0;
-
- if (seq_num >= *max_seq + win_size) {
- memset(window, 0, win_size / 8);
- *max_seq = seq_num;
- } else {
- while (*max_seq < seq_num) {
- (*max_seq)++;
- __clear_bit((*max_seq) % win_size, window);
- }
- }
- __set_bit(seq_num % win_size, window);
- } else if (seq_num + win_size <= *max_seq) {
- /*
- * 2. low behind the window
- */
- if (phase == 0 || phase == 2)
- goto replay;
-
- CWARN("seq %u is %u behind (size %d), check backup window\n",
- seq_num, *max_seq - win_size - seq_num, win_size);
- return 1;
- } else {
- /*
- * 3. fit into the window
- */
- switch (phase) {
- case 0:
- if (test_bit(seq_num % win_size, window))
- goto replay;
- break;
- case 1:
- case 2:
- if (__test_and_set_bit(seq_num % win_size, window))
- goto replay;
- break;
- }
- }
-
- return 0;
-
-replay:
- CERROR("seq %u (%s %s window) is a replay: max %u, winsize %d\n",
- seq_num,
- seq_num + win_size > *max_seq ? "in" : "behind",
- phase == 2 ? "backup " : "main",
- *max_seq, win_size);
- return -1;
-}
-
-/*
- * Based on sequence number algorithm as specified in RFC 2203.
- *
- * if @set == 0: initial check, don't set any bit in window
- * if @sec == 1: final check, set bit in window
- */
-int gss_check_seq_num(struct gss_svc_seq_data *ssd, __u32 seq_num, int set)
-{
- int rc = 0;
-
- spin_lock(&ssd->ssd_lock);
-
- if (set == 0) {
- /*
- * phase 0 testing
- */
- rc = gss_do_check_seq(ssd->ssd_win_main, GSS_SEQ_WIN_MAIN,
- &ssd->ssd_max_main, seq_num, 0);
- if (unlikely(rc))
- gss_stat_oos_record_svc(0, 1);
- } else {
- /*
- * phase 1 checking main window
- */
- rc = gss_do_check_seq(ssd->ssd_win_main, GSS_SEQ_WIN_MAIN,
- &ssd->ssd_max_main, seq_num, 1);
- switch (rc) {
- case -1:
- gss_stat_oos_record_svc(1, 1);
- /* fall through */
- case 0:
- goto exit;
- }
- /*
- * phase 2 checking back window
- */
- rc = gss_do_check_seq(ssd->ssd_win_back, GSS_SEQ_WIN_BACK,
- &ssd->ssd_max_back, seq_num, 2);
- if (rc)
- gss_stat_oos_record_svc(2, 1);
- else
- gss_stat_oos_record_svc(2, 0);
- }
-exit:
- spin_unlock(&ssd->ssd_lock);
- return rc;
-}
-
-/***************************************
- * cred APIs *
- ***************************************/
-
-static inline int gss_cli_payload(struct ptlrpc_cli_ctx *ctx,
- int msgsize, int privacy)
-{
- return gss_mech_payload(NULL, msgsize, privacy);
-}
-
-static int gss_cli_bulk_payload(struct ptlrpc_cli_ctx *ctx,
- struct sptlrpc_flavor *flvr,
- int reply, int read)
-{
- int payload = sizeof(struct ptlrpc_bulk_sec_desc);
-
- LASSERT(SPTLRPC_FLVR_BULK_TYPE(flvr->sf_rpc) == SPTLRPC_BULK_DEFAULT);
-
- if ((!reply && !read) || (reply && read)) {
- switch (SPTLRPC_FLVR_BULK_SVC(flvr->sf_rpc)) {
- case SPTLRPC_BULK_SVC_NULL:
- break;
- case SPTLRPC_BULK_SVC_INTG:
- payload += gss_cli_payload(ctx, 0, 0);
- break;
- case SPTLRPC_BULK_SVC_PRIV:
- payload += gss_cli_payload(ctx, 0, 1);
- break;
- case SPTLRPC_BULK_SVC_AUTH:
- default:
- LBUG();
- }
- }
-
- return payload;
-}
-
-int gss_cli_ctx_match(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred)
-{
- return (ctx->cc_vcred.vc_uid == vcred->vc_uid);
-}
-
-void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize)
-{
- buf[0] = '\0';
-
- if (flags & PTLRPC_CTX_NEW)
- strncat(buf, "new,", bufsize);
- if (flags & PTLRPC_CTX_UPTODATE)
- strncat(buf, "uptodate,", bufsize);
- if (flags & PTLRPC_CTX_DEAD)
- strncat(buf, "dead,", bufsize);
- if (flags & PTLRPC_CTX_ERROR)
- strncat(buf, "error,", bufsize);
- if (flags & PTLRPC_CTX_CACHED)
- strncat(buf, "cached,", bufsize);
- if (flags & PTLRPC_CTX_ETERNAL)
- strncat(buf, "eternal,", bufsize);
- if (buf[0] == '\0')
- strncat(buf, "-,", bufsize);
-
- buf[strlen(buf) - 1] = '\0';
-}
-
-int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req)
-{
- struct gss_cli_ctx *gctx = ctx2gctx(ctx);
- __u32 flags = 0, seq, svc;
- int rc;
-
- LASSERT(req->rq_reqbuf);
- LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
- LASSERT(req->rq_cli_ctx == ctx);
-
- /* nothing to do for context negotiation RPCs */
- if (req->rq_ctx_init)
- return 0;
-
- svc = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc);
- if (req->rq_pack_bulk)
- flags |= LUSTRE_GSS_PACK_BULK;
- if (req->rq_pack_udesc)
- flags |= LUSTRE_GSS_PACK_USER;
-
-redo:
- seq = atomic_inc_return(&gctx->gc_seq);
-
- rc = gss_sign_msg(req->rq_reqbuf, gctx->gc_mechctx,
- ctx->cc_sec->ps_part,
- flags, gctx->gc_proc, seq, svc,
- &gctx->gc_handle);
- if (rc < 0)
- return rc;
-
- /* gss_sign_msg() msg might take long time to finish, in which period
- * more rpcs could be wrapped up and sent out. if we found too many
- * of them we should repack this rpc, because sent it too late might
- * lead to the sequence number fall behind the window on server and
- * be dropped. also applies to gss_cli_ctx_seal().
- *
- * Note: null mode doesn't check sequence number. */
- if (svc != SPTLRPC_SVC_NULL &&
- atomic_read(&gctx->gc_seq) - seq > GSS_SEQ_REPACK_THRESHOLD) {
- int behind = atomic_read(&gctx->gc_seq) - seq;
-
- gss_stat_oos_record_cli(behind);
- CWARN("req %p: %u behind, retry signing\n", req, behind);
- goto redo;
- }
-
- req->rq_reqdata_len = rc;
- return 0;
-}
-
-static
-int gss_cli_ctx_handle_err_notify(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req,
- struct gss_header *ghdr)
-{
- struct gss_err_header *errhdr;
- int rc;
-
- LASSERT(ghdr->gh_proc == PTLRPC_GSS_PROC_ERR);
-
- errhdr = (struct gss_err_header *) ghdr;
-
- CWARN("req x"LPU64"/t"LPU64", ctx %p idx "LPX64"(%u->%s): "
- "%sserver respond (%08x/%08x)\n",
- req->rq_xid, req->rq_transno, ctx,
- gss_handle_to_u64(&ctx2gctx(ctx)->gc_handle),
- ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
- sec_is_reverse(ctx->cc_sec) ? "reverse" : "",
- errhdr->gh_major, errhdr->gh_minor);
-
- /* context fini rpc, let it failed */
- if (req->rq_ctx_fini) {
- CWARN("context fini rpc failed\n");
- return -EINVAL;
- }
-
- /* reverse sec, just return error, don't expire this ctx because it's
- * crucial to callback rpcs. note if the callback rpc failed because
- * of bit flip during network transfer, the client will be evicted
- * directly. so more gracefully we probably want let it retry for
- * number of times. */
- if (sec_is_reverse(ctx->cc_sec))
- return -EINVAL;
-
- if (errhdr->gh_major != GSS_S_NO_CONTEXT &&
- errhdr->gh_major != GSS_S_BAD_SIG)
- return -EACCES;
-
- /* server return NO_CONTEXT might be caused by context expire
- * or server reboot/failover. we try to refresh a new ctx which
- * be transparent to upper layer.
- *
- * In some cases, our gss handle is possible to be incidentally
- * identical to another handle since the handle itself is not
- * fully random. In krb5 case, the GSS_S_BAD_SIG will be
- * returned, maybe other gss error for other mechanism.
- *
- * if we add new mechanism, make sure the correct error are
- * returned in this case. */
- CWARN("%s: server might lost the context, retrying\n",
- errhdr->gh_major == GSS_S_NO_CONTEXT ? "NO_CONTEXT" : "BAD_SIG");
-
- sptlrpc_cli_ctx_expire(ctx);
-
- /* we need replace the ctx right here, otherwise during
- * resent we'll hit the logic in sptlrpc_req_refresh_ctx()
- * which keep the ctx with RESEND flag, thus we'll never
- * get rid of this ctx. */
- rc = sptlrpc_req_replace_dead_ctx(req);
- if (rc == 0)
- req->rq_resend = 1;
-
- return rc;
-}
-
-int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req)
-{
- struct gss_cli_ctx *gctx;
- struct gss_header *ghdr, *reqhdr;
- struct lustre_msg *msg = req->rq_repdata;
- __u32 major;
- int pack_bulk, swabbed, rc = 0;
-
- LASSERT(req->rq_cli_ctx == ctx);
- LASSERT(msg);
-
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
-
- /* special case for context negotiation, rq_repmsg/rq_replen actually
- * are not used currently. but early reply always be treated normally */
- if (req->rq_ctx_init && !req->rq_early) {
- req->rq_repmsg = lustre_msg_buf(msg, 1, 0);
- req->rq_replen = msg->lm_buflens[1];
- return 0;
- }
-
- if (msg->lm_bufcount < 2 || msg->lm_bufcount > 4) {
- CERROR("unexpected bufcount %u\n", msg->lm_bufcount);
- return -EPROTO;
- }
-
- swabbed = ptlrpc_rep_need_swab(req);
-
- ghdr = gss_swab_header(msg, 0, swabbed);
- if (ghdr == NULL) {
- CERROR("can't decode gss header\n");
- return -EPROTO;
- }
-
- /* sanity checks */
- reqhdr = lustre_msg_buf(msg, 0, sizeof(*reqhdr));
- LASSERT(reqhdr);
-
- if (ghdr->gh_version != reqhdr->gh_version) {
- CERROR("gss version %u mismatch, expect %u\n",
- ghdr->gh_version, reqhdr->gh_version);
- return -EPROTO;
- }
-
- switch (ghdr->gh_proc) {
- case PTLRPC_GSS_PROC_DATA:
- pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK;
-
- if (!req->rq_early &&
- !equi(req->rq_pack_bulk == 1, pack_bulk)) {
- CERROR("%s bulk flag in reply\n",
- req->rq_pack_bulk ? "missing" : "unexpected");
- return -EPROTO;
- }
-
- if (ghdr->gh_seq != reqhdr->gh_seq) {
- CERROR("seqnum %u mismatch, expect %u\n",
- ghdr->gh_seq, reqhdr->gh_seq);
- return -EPROTO;
- }
-
- if (ghdr->gh_svc != reqhdr->gh_svc) {
- CERROR("svc %u mismatch, expect %u\n",
- ghdr->gh_svc, reqhdr->gh_svc);
- return -EPROTO;
- }
-
- if (swabbed)
- gss_header_swabber(ghdr);
-
- major = gss_verify_msg(msg, gctx->gc_mechctx, reqhdr->gh_svc);
- if (major != GSS_S_COMPLETE) {
- CERROR("failed to verify reply: %x\n", major);
- return -EPERM;
- }
-
- if (req->rq_early && reqhdr->gh_svc == SPTLRPC_SVC_NULL) {
- __u32 cksum;
-
- cksum = crc32_le(!(__u32) 0,
- lustre_msg_buf(msg, 1, 0),
- lustre_msg_buflen(msg, 1));
- if (cksum != msg->lm_cksum) {
- CWARN("early reply checksum mismatch: "
- "%08x != %08x\n", cksum, msg->lm_cksum);
- return -EPROTO;
- }
- }
-
- if (pack_bulk) {
- /* bulk checksum is right after the lustre msg */
- if (msg->lm_bufcount < 3) {
- CERROR("Invalid reply bufcount %u\n",
- msg->lm_bufcount);
- return -EPROTO;
- }
-
- rc = bulk_sec_desc_unpack(msg, 2, swabbed);
- if (rc) {
- CERROR("unpack bulk desc: %d\n", rc);
- return rc;
- }
- }
-
- req->rq_repmsg = lustre_msg_buf(msg, 1, 0);
- req->rq_replen = msg->lm_buflens[1];
- break;
- case PTLRPC_GSS_PROC_ERR:
- if (req->rq_early) {
- CERROR("server return error with early reply\n");
- rc = -EPROTO;
- } else {
- rc = gss_cli_ctx_handle_err_notify(ctx, req, ghdr);
- }
- break;
- default:
- CERROR("unknown gss proc %d\n", ghdr->gh_proc);
- rc = -EPROTO;
- }
-
- return rc;
-}
-
-int gss_cli_ctx_seal(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req)
-{
- struct gss_cli_ctx *gctx;
- rawobj_t hdrobj, msgobj, token;
- struct gss_header *ghdr;
- __u32 buflens[2], major;
- int wiresize, rc;
-
- LASSERT(req->rq_clrbuf);
- LASSERT(req->rq_cli_ctx == ctx);
- LASSERT(req->rq_reqlen);
-
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
-
- /* final clear data length */
- req->rq_clrdata_len = lustre_msg_size_v2(req->rq_clrbuf->lm_bufcount,
- req->rq_clrbuf->lm_buflens);
-
- /* calculate wire data length */
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = gss_cli_payload(&gctx->gc_base, req->rq_clrdata_len, 1);
- wiresize = lustre_msg_size_v2(2, buflens);
-
- /* allocate wire buffer */
- if (req->rq_pool) {
- /* pre-allocated */
- LASSERT(req->rq_reqbuf);
- LASSERT(req->rq_reqbuf != req->rq_clrbuf);
- LASSERT(req->rq_reqbuf_len >= wiresize);
- } else {
- OBD_ALLOC_LARGE(req->rq_reqbuf, wiresize);
- if (!req->rq_reqbuf)
- return -ENOMEM;
- req->rq_reqbuf_len = wiresize;
- }
-
- lustre_init_msg_v2(req->rq_reqbuf, 2, buflens, NULL);
- req->rq_reqbuf->lm_secflvr = req->rq_flvr.sf_rpc;
-
- /* gss header */
- ghdr = lustre_msg_buf(req->rq_reqbuf, 0, 0);
- ghdr->gh_version = PTLRPC_GSS_VERSION;
- ghdr->gh_sp = (__u8) ctx->cc_sec->ps_part;
- ghdr->gh_flags = 0;
- ghdr->gh_proc = gctx->gc_proc;
- ghdr->gh_svc = SPTLRPC_SVC_PRIV;
- ghdr->gh_handle.len = gctx->gc_handle.len;
- memcpy(ghdr->gh_handle.data, gctx->gc_handle.data, gctx->gc_handle.len);
- if (req->rq_pack_bulk)
- ghdr->gh_flags |= LUSTRE_GSS_PACK_BULK;
- if (req->rq_pack_udesc)
- ghdr->gh_flags |= LUSTRE_GSS_PACK_USER;
-
-redo:
- ghdr->gh_seq = atomic_inc_return(&gctx->gc_seq);
-
- /* buffer objects */
- hdrobj.len = PTLRPC_GSS_HEADER_SIZE;
- hdrobj.data = (__u8 *) ghdr;
- msgobj.len = req->rq_clrdata_len;
- msgobj.data = (__u8 *) req->rq_clrbuf;
- token.len = lustre_msg_buflen(req->rq_reqbuf, 1);
- token.data = lustre_msg_buf(req->rq_reqbuf, 1, 0);
-
- major = lgss_wrap(gctx->gc_mechctx, &hdrobj, &msgobj,
- req->rq_clrbuf_len, &token);
- if (major != GSS_S_COMPLETE) {
- CERROR("priv: wrap message error: %08x\n", major);
- GOTO(err_free, rc = -EPERM);
- }
- LASSERT(token.len <= buflens[1]);
-
- /* see explain in gss_cli_ctx_sign() */
- if (unlikely(atomic_read(&gctx->gc_seq) - ghdr->gh_seq >
- GSS_SEQ_REPACK_THRESHOLD)) {
- int behind = atomic_read(&gctx->gc_seq) - ghdr->gh_seq;
-
- gss_stat_oos_record_cli(behind);
- CWARN("req %p: %u behind, retry sealing\n", req, behind);
-
- ghdr->gh_seq = atomic_inc_return(&gctx->gc_seq);
- goto redo;
- }
-
- /* now set the final wire data length */
- req->rq_reqdata_len = lustre_shrink_msg(req->rq_reqbuf, 1, token.len,0);
- return 0;
-
-err_free:
- if (!req->rq_pool) {
- OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
- req->rq_reqbuf = NULL;
- req->rq_reqbuf_len = 0;
- }
- return rc;
-}
-
-int gss_cli_ctx_unseal(struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_request *req)
-{
- struct gss_cli_ctx *gctx;
- struct gss_header *ghdr;
- struct lustre_msg *msg = req->rq_repdata;
- int msglen, pack_bulk, swabbed, rc;
- __u32 major;
-
- LASSERT(req->rq_cli_ctx == ctx);
- LASSERT(req->rq_ctx_init == 0);
- LASSERT(msg);
-
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
- swabbed = ptlrpc_rep_need_swab(req);
-
- ghdr = gss_swab_header(msg, 0, swabbed);
- if (ghdr == NULL) {
- CERROR("can't decode gss header\n");
- return -EPROTO;
- }
-
- /* sanity checks */
- if (ghdr->gh_version != PTLRPC_GSS_VERSION) {
- CERROR("gss version %u mismatch, expect %u\n",
- ghdr->gh_version, PTLRPC_GSS_VERSION);
- return -EPROTO;
- }
-
- switch (ghdr->gh_proc) {
- case PTLRPC_GSS_PROC_DATA:
- pack_bulk = ghdr->gh_flags & LUSTRE_GSS_PACK_BULK;
-
- if (!req->rq_early &&
- !equi(req->rq_pack_bulk == 1, pack_bulk)) {
- CERROR("%s bulk flag in reply\n",
- req->rq_pack_bulk ? "missing" : "unexpected");
- return -EPROTO;
- }
-
- if (swabbed)
- gss_header_swabber(ghdr);
-
- /* use rq_repdata_len as buffer size, which assume unseal
- * doesn't need extra memory space. for precise control, we'd
- * better calculate out actual buffer size as
- * (repbuf_len - offset - repdata_len) */
- major = gss_unseal_msg(gctx->gc_mechctx, msg,
- &msglen, req->rq_repdata_len);
- if (major != GSS_S_COMPLETE) {
- CERROR("failed to unwrap reply: %x\n", major);
- rc = -EPERM;
- break;
- }
-
- swabbed = __lustre_unpack_msg(msg, msglen);
- if (swabbed < 0) {
- CERROR("Failed to unpack after decryption\n");
- return -EPROTO;
- }
-
- if (msg->lm_bufcount < 1) {
- CERROR("Invalid reply buffer: empty\n");
- return -EPROTO;
- }
-
- if (pack_bulk) {
- if (msg->lm_bufcount < 2) {
- CERROR("bufcount %u: missing bulk sec desc\n",
- msg->lm_bufcount);
- return -EPROTO;
- }
-
- /* bulk checksum is the last segment */
- if (bulk_sec_desc_unpack(msg, msg->lm_bufcount - 1,
- swabbed))
- return -EPROTO;
- }
-
- req->rq_repmsg = lustre_msg_buf(msg, 0, 0);
- req->rq_replen = msg->lm_buflens[0];
-
- rc = 0;
- break;
- case PTLRPC_GSS_PROC_ERR:
- if (req->rq_early) {
- CERROR("server return error with early reply\n");
- rc = -EPROTO;
- } else {
- rc = gss_cli_ctx_handle_err_notify(ctx, req, ghdr);
- }
- break;
- default:
- CERROR("unexpected proc %d\n", ghdr->gh_proc);
- rc = -EPERM;
- }
-
- return rc;
-}
-
-/*********************************************
- * reverse context installation *
- *********************************************/
-
-static inline
-int gss_install_rvs_svc_ctx(struct obd_import *imp,
- struct gss_sec *gsec,
- struct gss_cli_ctx *gctx)
-{
- return gss_svc_upcall_install_rvs_ctx(imp, gsec, gctx);
-}
-
-/*********************************************
- * GSS security APIs *
- *********************************************/
-int gss_sec_create_common(struct gss_sec *gsec,
- struct ptlrpc_sec_policy *policy,
- struct obd_import *imp,
- struct ptlrpc_svc_ctx *svcctx,
- struct sptlrpc_flavor *sf)
-{
- struct ptlrpc_sec *sec;
-
- LASSERT(imp);
- LASSERT(SPTLRPC_FLVR_POLICY(sf->sf_rpc) == SPTLRPC_POLICY_GSS);
-
- gsec->gs_mech = lgss_subflavor_to_mech(
- SPTLRPC_FLVR_BASE_SUB(sf->sf_rpc));
- if (!gsec->gs_mech) {
- CERROR("gss backend 0x%x not found\n",
- SPTLRPC_FLVR_BASE_SUB(sf->sf_rpc));
- return -EOPNOTSUPP;
- }
-
- spin_lock_init(&gsec->gs_lock);
- gsec->gs_rvs_hdl = 0ULL;
-
- /* initialize upper ptlrpc_sec */
- sec = &gsec->gs_base;
- sec->ps_policy = policy;
- atomic_set(&sec->ps_refcount, 0);
- atomic_set(&sec->ps_nctx, 0);
- sec->ps_id = sptlrpc_get_next_secid();
- sec->ps_flvr = *sf;
- sec->ps_import = class_import_get(imp);
- spin_lock_init(&sec->ps_lock);
- INIT_LIST_HEAD(&sec->ps_gc_list);
-
- if (!svcctx) {
- sec->ps_gc_interval = GSS_GC_INTERVAL;
- } else {
- LASSERT(sec_is_reverse(sec));
-
- /* never do gc on reverse sec */
- sec->ps_gc_interval = 0;
- }
-
- if (SPTLRPC_FLVR_BULK_SVC(sec->ps_flvr.sf_rpc) == SPTLRPC_BULK_SVC_PRIV)
- sptlrpc_enc_pool_add_user();
-
- CDEBUG(D_SEC, "create %s%s@%p\n", (svcctx ? "reverse " : ""),
- policy->sp_name, gsec);
- return 0;
-}
-
-void gss_sec_destroy_common(struct gss_sec *gsec)
-{
- struct ptlrpc_sec *sec = &gsec->gs_base;
-
- LASSERT(sec->ps_import);
- LASSERT(atomic_read(&sec->ps_refcount) == 0);
- LASSERT(atomic_read(&sec->ps_nctx) == 0);
-
- if (gsec->gs_mech) {
- lgss_mech_put(gsec->gs_mech);
- gsec->gs_mech = NULL;
- }
-
- class_import_put(sec->ps_import);
-
- if (SPTLRPC_FLVR_BULK_SVC(sec->ps_flvr.sf_rpc) == SPTLRPC_BULK_SVC_PRIV)
- sptlrpc_enc_pool_del_user();
-}
-
-void gss_sec_kill(struct ptlrpc_sec *sec)
-{
- sec->ps_dying = 1;
-}
-
-int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx,
- struct ptlrpc_ctx_ops *ctxops,
- struct vfs_cred *vcred)
-{
- struct gss_cli_ctx *gctx = ctx2gctx(ctx);
-
- gctx->gc_win = 0;
- atomic_set(&gctx->gc_seq, 0);
-
- INIT_HLIST_NODE(&ctx->cc_cache);
- atomic_set(&ctx->cc_refcount, 0);
- ctx->cc_sec = sec;
- ctx->cc_ops = ctxops;
- ctx->cc_expire = 0;
- ctx->cc_flags = PTLRPC_CTX_NEW;
- ctx->cc_vcred = *vcred;
- spin_lock_init(&ctx->cc_lock);
- INIT_LIST_HEAD(&ctx->cc_req_list);
- INIT_LIST_HEAD(&ctx->cc_gc_chain);
-
- /* take a ref on belonging sec, balanced in ctx destroying */
- atomic_inc(&sec->ps_refcount);
- /* statistic only */
- atomic_inc(&sec->ps_nctx);
-
- CDEBUG(D_SEC, "%s@%p: create ctx %p(%u->%s)\n",
- sec->ps_policy->sp_name, ctx->cc_sec,
- ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
- return 0;
-}
-
-/*
- * return value:
- * 1: the context has been taken care of by someone else
- * 0: proceed to really destroy the context locally
- */
-int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx)
-{
- struct gss_cli_ctx *gctx = ctx2gctx(ctx);
-
- LASSERT(atomic_read(&sec->ps_nctx) > 0);
- LASSERT(atomic_read(&ctx->cc_refcount) == 0);
- LASSERT(ctx->cc_sec == sec);
-
- /*
- * remove UPTODATE flag of reverse ctx thus we won't send fini rpc,
- * this is to avoid potential problems of client side reverse svc ctx
- * be mis-destroyed in various recovery scenarios. anyway client can
- * manage its reverse ctx well by associating it with its buddy ctx.
- */
- if (sec_is_reverse(sec))
- ctx->cc_flags &= ~PTLRPC_CTX_UPTODATE;
-
- if (gctx->gc_mechctx) {
- /* the final context fini rpc will use this ctx too, and it's
- * asynchronous which finished by request_out_callback(). so
- * we add refcount, whoever drop finally drop the refcount to
- * 0 should responsible for the rest of destroy. */
- atomic_inc(&ctx->cc_refcount);
-
- gss_do_ctx_fini_rpc(gctx);
- gss_cli_ctx_finalize(gctx);
-
- if (!atomic_dec_and_test(&ctx->cc_refcount))
- return 1;
- }
-
- if (sec_is_reverse(sec))
- CWARN("reverse sec %p: destroy ctx %p\n",
- ctx->cc_sec, ctx);
- else
- CWARN("%s@%p: destroy ctx %p(%u->%s)\n",
- sec->ps_policy->sp_name, ctx->cc_sec,
- ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
-
- return 0;
-}
-
-static
-int gss_alloc_reqbuf_intg(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int svc, int msgsize)
-{
- int bufsize, txtsize;
- int bufcnt = 2;
- __u32 buflens[5];
-
- /*
- * on-wire data layout:
- * - gss header
- * - lustre message
- * - user descriptor (optional)
- * - bulk sec descriptor (optional)
- * - signature (optional)
- * - svc == NULL: NULL
- * - svc == AUTH: signature of gss header
- * - svc == INTG: signature of all above
- *
- * if this is context negotiation, reserver fixed space
- * at the last (signature) segment regardless of svc mode.
- */
-
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- txtsize = buflens[0];
-
- buflens[1] = msgsize;
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[1];
-
- if (req->rq_pack_udesc) {
- buflens[bufcnt] = sptlrpc_current_user_desc_size();
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[bufcnt];
- bufcnt++;
- }
-
- if (req->rq_pack_bulk) {
- buflens[bufcnt] = gss_cli_bulk_payload(req->rq_cli_ctx,
- &req->rq_flvr,
- 0, req->rq_bulk_read);
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[bufcnt];
- bufcnt++;
- }
-
- if (req->rq_ctx_init)
- buflens[bufcnt++] = GSS_CTX_INIT_MAX_LEN;
- else if (svc != SPTLRPC_SVC_NULL)
- buflens[bufcnt++] = gss_cli_payload(req->rq_cli_ctx, txtsize,0);
-
- bufsize = lustre_msg_size_v2(bufcnt, buflens);
-
- if (!req->rq_reqbuf) {
- bufsize = size_roundup_power2(bufsize);
-
- OBD_ALLOC_LARGE(req->rq_reqbuf, bufsize);
- if (!req->rq_reqbuf)
- return -ENOMEM;
-
- req->rq_reqbuf_len = bufsize;
- } else {
- LASSERT(req->rq_pool);
- LASSERT(req->rq_reqbuf_len >= bufsize);
- memset(req->rq_reqbuf, 0, bufsize);
- }
-
- lustre_init_msg_v2(req->rq_reqbuf, bufcnt, buflens, NULL);
- req->rq_reqbuf->lm_secflvr = req->rq_flvr.sf_rpc;
-
- req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, 1, msgsize);
- LASSERT(req->rq_reqmsg);
-
- /* pack user desc here, later we might leave current user's process */
- if (req->rq_pack_udesc)
- sptlrpc_pack_user_desc(req->rq_reqbuf, 2);
-
- return 0;
-}
-
-static
-int gss_alloc_reqbuf_priv(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int msgsize)
-{
- __u32 ibuflens[3], wbuflens[2];
- int ibufcnt;
- int clearsize, wiresize;
-
- LASSERT(req->rq_clrbuf == NULL);
- LASSERT(req->rq_clrbuf_len == 0);
-
- /* Inner (clear) buffers
- * - lustre message
- * - user descriptor (optional)
- * - bulk checksum (optional)
- */
- ibufcnt = 1;
- ibuflens[0] = msgsize;
-
- if (req->rq_pack_udesc)
- ibuflens[ibufcnt++] = sptlrpc_current_user_desc_size();
- if (req->rq_pack_bulk)
- ibuflens[ibufcnt++] = gss_cli_bulk_payload(req->rq_cli_ctx,
- &req->rq_flvr, 0,
- req->rq_bulk_read);
-
- clearsize = lustre_msg_size_v2(ibufcnt, ibuflens);
- /* to allow append padding during encryption */
- clearsize += GSS_MAX_CIPHER_BLOCK;
-
- /* Wrapper (wire) buffers
- * - gss header
- * - cipher text
- */
- wbuflens[0] = PTLRPC_GSS_HEADER_SIZE;
- wbuflens[1] = gss_cli_payload(req->rq_cli_ctx, clearsize, 1);
- wiresize = lustre_msg_size_v2(2, wbuflens);
-
- if (req->rq_pool) {
- /* rq_reqbuf is preallocated */
- LASSERT(req->rq_reqbuf);
- LASSERT(req->rq_reqbuf_len >= wiresize);
-
- memset(req->rq_reqbuf, 0, req->rq_reqbuf_len);
-
- /* if the pre-allocated buffer is big enough, we just pack
- * both clear buf & request buf in it, to avoid more alloc. */
- if (clearsize + wiresize <= req->rq_reqbuf_len) {
- req->rq_clrbuf =
- (void *) (((char *) req->rq_reqbuf) + wiresize);
- } else {
- CWARN("pre-allocated buf size %d is not enough for "
- "both clear (%d) and cipher (%d) text, proceed "
- "with extra allocation\n", req->rq_reqbuf_len,
- clearsize, wiresize);
- }
- }
-
- if (!req->rq_clrbuf) {
- clearsize = size_roundup_power2(clearsize);
-
- OBD_ALLOC_LARGE(req->rq_clrbuf, clearsize);
- if (!req->rq_clrbuf)
- return -ENOMEM;
- }
- req->rq_clrbuf_len = clearsize;
-
- lustre_init_msg_v2(req->rq_clrbuf, ibufcnt, ibuflens, NULL);
- req->rq_reqmsg = lustre_msg_buf(req->rq_clrbuf, 0, msgsize);
-
- if (req->rq_pack_udesc)
- sptlrpc_pack_user_desc(req->rq_clrbuf, 1);
-
- return 0;
-}
-
-/*
- * NOTE: any change of request buffer allocation should also consider
- * changing enlarge_reqbuf() series functions.
- */
-int gss_alloc_reqbuf(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int msgsize)
-{
- int svc = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc);
-
- LASSERT(!req->rq_pack_bulk ||
- (req->rq_bulk_read || req->rq_bulk_write));
-
- switch (svc) {
- case SPTLRPC_SVC_NULL:
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- return gss_alloc_reqbuf_intg(sec, req, svc, msgsize);
- case SPTLRPC_SVC_PRIV:
- return gss_alloc_reqbuf_priv(sec, req, msgsize);
- default:
- LASSERTF(0, "bad rpc flavor %x\n", req->rq_flvr.sf_rpc);
- return 0;
- }
-}
-
-void gss_free_reqbuf(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req)
-{
- int privacy;
-
- LASSERT(!req->rq_pool || req->rq_reqbuf);
- privacy = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc) == SPTLRPC_SVC_PRIV;
-
- if (!req->rq_clrbuf)
- goto release_reqbuf;
-
- /* release clear buffer */
- LASSERT(privacy);
- LASSERT(req->rq_clrbuf_len);
-
- if (req->rq_pool == NULL ||
- req->rq_clrbuf < req->rq_reqbuf ||
- (char *) req->rq_clrbuf >=
- (char *) req->rq_reqbuf + req->rq_reqbuf_len)
- OBD_FREE_LARGE(req->rq_clrbuf, req->rq_clrbuf_len);
-
- req->rq_clrbuf = NULL;
- req->rq_clrbuf_len = 0;
-
-release_reqbuf:
- if (!req->rq_pool && req->rq_reqbuf) {
- LASSERT(req->rq_reqbuf_len);
-
- OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
- req->rq_reqbuf = NULL;
- req->rq_reqbuf_len = 0;
- }
-}
-
-static int do_alloc_repbuf(struct ptlrpc_request *req, int bufsize)
-{
- bufsize = size_roundup_power2(bufsize);
-
- OBD_ALLOC_LARGE(req->rq_repbuf, bufsize);
- if (!req->rq_repbuf)
- return -ENOMEM;
-
- req->rq_repbuf_len = bufsize;
- return 0;
-}
-
-static
-int gss_alloc_repbuf_intg(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int svc, int msgsize)
-{
- int txtsize;
- __u32 buflens[4];
- int bufcnt = 2;
- int alloc_size;
-
- /*
- * on-wire data layout:
- * - gss header
- * - lustre message
- * - bulk sec descriptor (optional)
- * - signature (optional)
- * - svc == NULL: NULL
- * - svc == AUTH: signature of gss header
- * - svc == INTG: signature of all above
- *
- * if this is context negotiation, reserver fixed space
- * at the last (signature) segment regardless of svc mode.
- */
-
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- txtsize = buflens[0];
-
- buflens[1] = msgsize;
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[1];
-
- if (req->rq_pack_bulk) {
- buflens[bufcnt] = gss_cli_bulk_payload(req->rq_cli_ctx,
- &req->rq_flvr,
- 1, req->rq_bulk_read);
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[bufcnt];
- bufcnt++;
- }
-
- if (req->rq_ctx_init)
- buflens[bufcnt++] = GSS_CTX_INIT_MAX_LEN;
- else if (svc != SPTLRPC_SVC_NULL)
- buflens[bufcnt++] = gss_cli_payload(req->rq_cli_ctx, txtsize,0);
-
- alloc_size = lustre_msg_size_v2(bufcnt, buflens);
-
- /* add space for early reply */
- alloc_size += gss_at_reply_off_integ;
-
- return do_alloc_repbuf(req, alloc_size);
-}
-
-static
-int gss_alloc_repbuf_priv(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int msgsize)
-{
- int txtsize;
- __u32 buflens[2];
- int bufcnt;
- int alloc_size;
-
- /* inner buffers */
- bufcnt = 1;
- buflens[0] = msgsize;
-
- if (req->rq_pack_bulk)
- buflens[bufcnt++] = gss_cli_bulk_payload(req->rq_cli_ctx,
- &req->rq_flvr,
- 1, req->rq_bulk_read);
- txtsize = lustre_msg_size_v2(bufcnt, buflens);
- txtsize += GSS_MAX_CIPHER_BLOCK;
-
- /* wrapper buffers */
- bufcnt = 2;
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = gss_cli_payload(req->rq_cli_ctx, txtsize, 1);
-
- alloc_size = lustre_msg_size_v2(bufcnt, buflens);
- /* add space for early reply */
- alloc_size += gss_at_reply_off_priv;
-
- return do_alloc_repbuf(req, alloc_size);
-}
-
-int gss_alloc_repbuf(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int msgsize)
-{
- int svc = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc);
-
- LASSERT(!req->rq_pack_bulk ||
- (req->rq_bulk_read || req->rq_bulk_write));
-
- switch (svc) {
- case SPTLRPC_SVC_NULL:
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- return gss_alloc_repbuf_intg(sec, req, svc, msgsize);
- case SPTLRPC_SVC_PRIV:
- return gss_alloc_repbuf_priv(sec, req, msgsize);
- default:
- LASSERTF(0, "bad rpc flavor %x\n", req->rq_flvr.sf_rpc);
- return 0;
- }
-}
-
-void gss_free_repbuf(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req)
-{
- OBD_FREE_LARGE(req->rq_repbuf, req->rq_repbuf_len);
- req->rq_repbuf = NULL;
- req->rq_repbuf_len = 0;
- req->rq_repdata = NULL;
- req->rq_repdata_len = 0;
-}
-
-static int get_enlarged_msgsize(struct lustre_msg *msg,
- int segment, int newsize)
-{
- int save, newmsg_size;
-
- LASSERT(newsize >= msg->lm_buflens[segment]);
-
- save = msg->lm_buflens[segment];
- msg->lm_buflens[segment] = newsize;
- newmsg_size = lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
- msg->lm_buflens[segment] = save;
-
- return newmsg_size;
-}
-
-static int get_enlarged_msgsize2(struct lustre_msg *msg,
- int segment1, int newsize1,
- int segment2, int newsize2)
-{
- int save1, save2, newmsg_size;
-
- LASSERT(newsize1 >= msg->lm_buflens[segment1]);
- LASSERT(newsize2 >= msg->lm_buflens[segment2]);
-
- save1 = msg->lm_buflens[segment1];
- save2 = msg->lm_buflens[segment2];
- msg->lm_buflens[segment1] = newsize1;
- msg->lm_buflens[segment2] = newsize2;
- newmsg_size = lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
- msg->lm_buflens[segment1] = save1;
- msg->lm_buflens[segment2] = save2;
-
- return newmsg_size;
-}
-
-static
-int gss_enlarge_reqbuf_intg(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int svc,
- int segment, int newsize)
-{
- struct lustre_msg *newbuf;
- int txtsize, sigsize = 0, i;
- int newmsg_size, newbuf_size;
-
- /*
- * gss header is at seg 0;
- * embedded msg is at seg 1;
- * signature (if any) is at the last seg
- */
- LASSERT(req->rq_reqbuf);
- LASSERT(req->rq_reqbuf_len > req->rq_reqlen);
- LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
- LASSERT(lustre_msg_buf(req->rq_reqbuf, 1, 0) == req->rq_reqmsg);
-
- /* 1. compute new embedded msg size */
- newmsg_size = get_enlarged_msgsize(req->rq_reqmsg, segment, newsize);
- LASSERT(newmsg_size >= req->rq_reqbuf->lm_buflens[1]);
-
- /* 2. compute new wrapper msg size */
- if (svc == SPTLRPC_SVC_NULL) {
- /* no signature, get size directly */
- newbuf_size = get_enlarged_msgsize(req->rq_reqbuf,
- 1, newmsg_size);
- } else {
- txtsize = req->rq_reqbuf->lm_buflens[0];
-
- if (svc == SPTLRPC_SVC_INTG) {
- for (i = 1; i < req->rq_reqbuf->lm_bufcount; i++)
- txtsize += req->rq_reqbuf->lm_buflens[i];
- txtsize += newmsg_size - req->rq_reqbuf->lm_buflens[1];
- }
-
- sigsize = gss_cli_payload(req->rq_cli_ctx, txtsize, 0);
- LASSERT(sigsize >= msg_last_seglen(req->rq_reqbuf));
-
- newbuf_size = get_enlarged_msgsize2(
- req->rq_reqbuf,
- 1, newmsg_size,
- msg_last_segidx(req->rq_reqbuf),
- sigsize);
- }
-
- /* request from pool should always have enough buffer */
- LASSERT(!req->rq_pool || req->rq_reqbuf_len >= newbuf_size);
-
- if (req->rq_reqbuf_len < newbuf_size) {
- newbuf_size = size_roundup_power2(newbuf_size);
-
- OBD_ALLOC_LARGE(newbuf, newbuf_size);
- if (newbuf == NULL)
- return -ENOMEM;
-
- memcpy(newbuf, req->rq_reqbuf, req->rq_reqbuf_len);
-
- OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
- req->rq_reqbuf = newbuf;
- req->rq_reqbuf_len = newbuf_size;
- req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, 1, 0);
- }
-
- /* do enlargement, from wrapper to embedded, from end to begin */
- if (svc != SPTLRPC_SVC_NULL)
- _sptlrpc_enlarge_msg_inplace(req->rq_reqbuf,
- msg_last_segidx(req->rq_reqbuf),
- sigsize);
-
- _sptlrpc_enlarge_msg_inplace(req->rq_reqbuf, 1, newmsg_size);
- _sptlrpc_enlarge_msg_inplace(req->rq_reqmsg, segment, newsize);
-
- req->rq_reqlen = newmsg_size;
- return 0;
-}
-
-static
-int gss_enlarge_reqbuf_priv(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int segment, int newsize)
-{
- struct lustre_msg *newclrbuf;
- int newmsg_size, newclrbuf_size, newcipbuf_size;
- __u32 buflens[3];
-
- /*
- * embedded msg is at seg 0 of clear buffer;
- * cipher text is at seg 2 of cipher buffer;
- */
- LASSERT(req->rq_pool ||
- (req->rq_reqbuf == NULL && req->rq_reqbuf_len == 0));
- LASSERT(req->rq_reqbuf == NULL ||
- (req->rq_pool && req->rq_reqbuf->lm_bufcount == 3));
- LASSERT(req->rq_clrbuf);
- LASSERT(req->rq_clrbuf_len > req->rq_reqlen);
- LASSERT(lustre_msg_buf(req->rq_clrbuf, 0, 0) == req->rq_reqmsg);
-
- /* compute new embedded msg size */
- newmsg_size = get_enlarged_msgsize(req->rq_reqmsg, segment, newsize);
-
- /* compute new clear buffer size */
- newclrbuf_size = get_enlarged_msgsize(req->rq_clrbuf, 0, newmsg_size);
- newclrbuf_size += GSS_MAX_CIPHER_BLOCK;
-
- /* compute new cipher buffer size */
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = gss_cli_payload(req->rq_cli_ctx, buflens[0], 0);
- buflens[2] = gss_cli_payload(req->rq_cli_ctx, newclrbuf_size, 1);
- newcipbuf_size = lustre_msg_size_v2(3, buflens);
-
- /* handle the case that we put both clear buf and cipher buf into
- * pre-allocated single buffer. */
- if (unlikely(req->rq_pool) &&
- req->rq_clrbuf >= req->rq_reqbuf &&
- (char *) req->rq_clrbuf <
- (char *) req->rq_reqbuf + req->rq_reqbuf_len) {
- /* it couldn't be better we still fit into the
- * pre-allocated buffer. */
- if (newclrbuf_size + newcipbuf_size <= req->rq_reqbuf_len) {
- void *src, *dst;
-
- /* move clear text backward. */
- src = req->rq_clrbuf;
- dst = (char *) req->rq_reqbuf + newcipbuf_size;
-
- memmove(dst, src, req->rq_clrbuf_len);
-
- req->rq_clrbuf = (struct lustre_msg *) dst;
- req->rq_clrbuf_len = newclrbuf_size;
- req->rq_reqmsg = lustre_msg_buf(req->rq_clrbuf, 0, 0);
- } else {
- /* sadly we have to split out the clear buffer */
- LASSERT(req->rq_reqbuf_len >= newcipbuf_size);
- LASSERT(req->rq_clrbuf_len < newclrbuf_size);
- }
- }
-
- if (req->rq_clrbuf_len < newclrbuf_size) {
- newclrbuf_size = size_roundup_power2(newclrbuf_size);
-
- OBD_ALLOC_LARGE(newclrbuf, newclrbuf_size);
- if (newclrbuf == NULL)
- return -ENOMEM;
-
- memcpy(newclrbuf, req->rq_clrbuf, req->rq_clrbuf_len);
-
- if (req->rq_reqbuf == NULL ||
- req->rq_clrbuf < req->rq_reqbuf ||
- (char *) req->rq_clrbuf >=
- (char *) req->rq_reqbuf + req->rq_reqbuf_len) {
- OBD_FREE_LARGE(req->rq_clrbuf, req->rq_clrbuf_len);
- }
-
- req->rq_clrbuf = newclrbuf;
- req->rq_clrbuf_len = newclrbuf_size;
- req->rq_reqmsg = lustre_msg_buf(req->rq_clrbuf, 0, 0);
- }
-
- _sptlrpc_enlarge_msg_inplace(req->rq_clrbuf, 0, newmsg_size);
- _sptlrpc_enlarge_msg_inplace(req->rq_reqmsg, segment, newsize);
- req->rq_reqlen = newmsg_size;
-
- return 0;
-}
-
-int gss_enlarge_reqbuf(struct ptlrpc_sec *sec,
- struct ptlrpc_request *req,
- int segment, int newsize)
-{
- int svc = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc);
-
- LASSERT(!req->rq_ctx_init && !req->rq_ctx_fini);
-
- switch (svc) {
- case SPTLRPC_SVC_NULL:
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- return gss_enlarge_reqbuf_intg(sec, req, svc, segment, newsize);
- case SPTLRPC_SVC_PRIV:
- return gss_enlarge_reqbuf_priv(sec, req, segment, newsize);
- default:
- LASSERTF(0, "bad rpc flavor %x\n", req->rq_flvr.sf_rpc);
- return 0;
- }
-}
-
-int gss_sec_install_rctx(struct obd_import *imp,
- struct ptlrpc_sec *sec,
- struct ptlrpc_cli_ctx *ctx)
-{
- struct gss_sec *gsec;
- struct gss_cli_ctx *gctx;
- int rc;
-
- gsec = container_of(sec, struct gss_sec, gs_base);
- gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
-
- rc = gss_install_rvs_svc_ctx(imp, gsec, gctx);
- return rc;
-}
-
-/********************************************
- * server side API *
- ********************************************/
-
-static inline
-int gss_svc_reqctx_is_special(struct gss_svc_reqctx *grctx)
-{
- LASSERT(grctx);
- return (grctx->src_init || grctx->src_init_continue ||
- grctx->src_err_notify);
-}
-
-static
-void gss_svc_reqctx_free(struct gss_svc_reqctx *grctx)
-{
- if (grctx->src_ctx)
- gss_svc_upcall_put_ctx(grctx->src_ctx);
-
- sptlrpc_policy_put(grctx->src_base.sc_policy);
- OBD_FREE_PTR(grctx);
-}
-
-static inline
-void gss_svc_reqctx_addref(struct gss_svc_reqctx *grctx)
-{
- LASSERT(atomic_read(&grctx->src_base.sc_refcount) > 0);
- atomic_inc(&grctx->src_base.sc_refcount);
-}
-
-static inline
-void gss_svc_reqctx_decref(struct gss_svc_reqctx *grctx)
-{
- LASSERT(atomic_read(&grctx->src_base.sc_refcount) > 0);
-
- if (atomic_dec_and_test(&grctx->src_base.sc_refcount))
- gss_svc_reqctx_free(grctx);
-}
-
-static
-int gss_svc_sign(struct ptlrpc_request *req,
- struct ptlrpc_reply_state *rs,
- struct gss_svc_reqctx *grctx,
- __u32 svc)
-{
- __u32 flags = 0;
- int rc;
-
- LASSERT(rs->rs_msg == lustre_msg_buf(rs->rs_repbuf, 1, 0));
-
- /* embedded lustre_msg might have been shrunk */
- if (req->rq_replen != rs->rs_repbuf->lm_buflens[1])
- lustre_shrink_msg(rs->rs_repbuf, 1, req->rq_replen, 1);
-
- if (req->rq_pack_bulk)
- flags |= LUSTRE_GSS_PACK_BULK;
-
- rc = gss_sign_msg(rs->rs_repbuf, grctx->src_ctx->gsc_mechctx,
- LUSTRE_SP_ANY, flags, PTLRPC_GSS_PROC_DATA,
- grctx->src_wirectx.gw_seq, svc, NULL);
- if (rc < 0)
- return rc;
-
- rs->rs_repdata_len = rc;
-
- if (likely(req->rq_packed_final)) {
- if (lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)
- req->rq_reply_off = gss_at_reply_off_integ;
- else
- req->rq_reply_off = 0;
- } else {
- if (svc == SPTLRPC_SVC_NULL)
- rs->rs_repbuf->lm_cksum = crc32_le(!(__u32) 0,
- lustre_msg_buf(rs->rs_repbuf, 1, 0),
- lustre_msg_buflen(rs->rs_repbuf, 1));
- req->rq_reply_off = 0;
- }
-
- return 0;
-}
-
-int gss_pack_err_notify(struct ptlrpc_request *req, __u32 major, __u32 minor)
-{
- struct gss_svc_reqctx *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- struct ptlrpc_reply_state *rs;
- struct gss_err_header *ghdr;
- int replen = sizeof(struct ptlrpc_body);
- int rc;
-
- //if (OBD_FAIL_CHECK_ORSET(OBD_FAIL_SVCGSS_ERR_NOTIFY, OBD_FAIL_ONCE))
- // return -EINVAL;
-
- grctx->src_err_notify = 1;
- grctx->src_reserve_len = 0;
-
- rc = lustre_pack_reply_v2(req, 1, &replen, NULL, 0);
- if (rc) {
- CERROR("could not pack reply, err %d\n", rc);
- return rc;
- }
-
- /* gss hdr */
- rs = req->rq_reply_state;
- LASSERT(rs->rs_repbuf->lm_buflens[1] >= sizeof(*ghdr));
- ghdr = lustre_msg_buf(rs->rs_repbuf, 0, 0);
- ghdr->gh_version = PTLRPC_GSS_VERSION;
- ghdr->gh_flags = 0;
- ghdr->gh_proc = PTLRPC_GSS_PROC_ERR;
- ghdr->gh_major = major;
- ghdr->gh_minor = minor;
- ghdr->gh_handle.len = 0; /* fake context handle */
-
- rs->rs_repdata_len = lustre_msg_size_v2(rs->rs_repbuf->lm_bufcount,
- rs->rs_repbuf->lm_buflens);
-
- CDEBUG(D_SEC, "prepare gss error notify(0x%x/0x%x) to %s\n",
- major, minor, libcfs_nid2str(req->rq_peer.nid));
- return 0;
-}
-
-static
-int gss_svc_handle_init(struct ptlrpc_request *req,
- struct gss_wire_ctx *gw)
-{
- struct gss_svc_reqctx *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- struct lustre_msg *reqbuf = req->rq_reqbuf;
- struct obd_uuid *uuid;
- struct obd_device *target;
- rawobj_t uuid_obj, rvs_hdl, in_token;
- __u32 lustre_svc;
- __u32 *secdata, seclen;
- int swabbed, rc;
-
- CDEBUG(D_SEC, "processing gss init(%d) request from %s\n", gw->gw_proc,
- libcfs_nid2str(req->rq_peer.nid));
-
- req->rq_ctx_init = 1;
-
- if (gw->gw_flags & LUSTRE_GSS_PACK_BULK) {
- CERROR("unexpected bulk flag\n");
- return SECSVC_DROP;
- }
-
- if (gw->gw_proc == PTLRPC_GSS_PROC_INIT && gw->gw_handle.len != 0) {
- CERROR("proc %u: invalid handle length %u\n",
- gw->gw_proc, gw->gw_handle.len);
- return SECSVC_DROP;
- }
-
- if (reqbuf->lm_bufcount < 3 || reqbuf->lm_bufcount > 4) {
- CERROR("Invalid bufcount %d\n", reqbuf->lm_bufcount);
- return SECSVC_DROP;
- }
-
- swabbed = ptlrpc_req_need_swab(req);
-
- /* ctx initiate payload is in last segment */
- secdata = lustre_msg_buf(reqbuf, reqbuf->lm_bufcount - 1, 0);
- seclen = reqbuf->lm_buflens[reqbuf->lm_bufcount - 1];
-
- if (seclen < 4 + 4) {
- CERROR("sec size %d too small\n", seclen);
- return SECSVC_DROP;
- }
-
- /* lustre svc type */
- lustre_svc = le32_to_cpu(*secdata++);
- seclen -= 4;
-
- /* extract target uuid, note this code is somewhat fragile
- * because touched internal structure of obd_uuid */
- if (rawobj_extract(&uuid_obj, &secdata, &seclen)) {
- CERROR("failed to extract target uuid\n");
- return SECSVC_DROP;
- }
- uuid_obj.data[uuid_obj.len - 1] = '\0';
-
- uuid = (struct obd_uuid *) uuid_obj.data;
- target = class_uuid2obd(uuid);
- if (!target || target->obd_stopping || !target->obd_set_up) {
- CERROR("target '%s' is not available for context init (%s)\n",
- uuid->uuid, target == NULL ? "no target" :
- (target->obd_stopping ? "stopping" : "not set up"));
- return SECSVC_DROP;
- }
-
- /* extract reverse handle */
- if (rawobj_extract(&rvs_hdl, &secdata, &seclen)) {
- CERROR("failed extract reverse handle\n");
- return SECSVC_DROP;
- }
-
- /* extract token */
- if (rawobj_extract(&in_token, &secdata, &seclen)) {
- CERROR("can't extract token\n");
- return SECSVC_DROP;
- }
-
- rc = gss_svc_upcall_handle_init(req, grctx, gw, target, lustre_svc,
- &rvs_hdl, &in_token);
- if (rc != SECSVC_OK)
- return rc;
-
- if (grctx->src_ctx->gsc_usr_mds || grctx->src_ctx->gsc_usr_oss ||
- grctx->src_ctx->gsc_usr_root)
- CWARN("create svc ctx %p: user from %s authenticated as %s\n",
- grctx->src_ctx, libcfs_nid2str(req->rq_peer.nid),
- grctx->src_ctx->gsc_usr_mds ? "mds" :
- (grctx->src_ctx->gsc_usr_oss ? "oss" : "root"));
- else
- CWARN("create svc ctx %p: accept user %u from %s\n",
- grctx->src_ctx, grctx->src_ctx->gsc_uid,
- libcfs_nid2str(req->rq_peer.nid));
-
- if (gw->gw_flags & LUSTRE_GSS_PACK_USER) {
- if (reqbuf->lm_bufcount < 4) {
- CERROR("missing user descriptor\n");
- return SECSVC_DROP;
- }
- if (sptlrpc_unpack_user_desc(reqbuf, 2, swabbed)) {
- CERROR("Mal-formed user descriptor\n");
- return SECSVC_DROP;
- }
-
- req->rq_pack_udesc = 1;
- req->rq_user_desc = lustre_msg_buf(reqbuf, 2, 0);
- }
-
- req->rq_reqmsg = lustre_msg_buf(reqbuf, 1, 0);
- req->rq_reqlen = lustre_msg_buflen(reqbuf, 1);
-
- return rc;
-}
-
-/*
- * last segment must be the gss signature.
- */
-static
-int gss_svc_verify_request(struct ptlrpc_request *req,
- struct gss_svc_reqctx *grctx,
- struct gss_wire_ctx *gw,
- __u32 *major)
-{
- struct gss_svc_ctx *gctx = grctx->src_ctx;
- struct lustre_msg *msg = req->rq_reqbuf;
- int offset = 2;
- int swabbed;
-
- *major = GSS_S_COMPLETE;
-
- if (msg->lm_bufcount < 2) {
- CERROR("Too few segments (%u) in request\n", msg->lm_bufcount);
- return -EINVAL;
- }
-
- if (gw->gw_svc == SPTLRPC_SVC_NULL)
- goto verified;
-
- if (gss_check_seq_num(&gctx->gsc_seqdata, gw->gw_seq, 0)) {
- CERROR("phase 0: discard replayed req: seq %u\n", gw->gw_seq);
- *major = GSS_S_DUPLICATE_TOKEN;
- return -EACCES;
- }
-
- *major = gss_verify_msg(msg, gctx->gsc_mechctx, gw->gw_svc);
- if (*major != GSS_S_COMPLETE) {
- CERROR("failed to verify request: %x\n", *major);
- return -EACCES;
- }
-
- if (gctx->gsc_reverse == 0 &&
- gss_check_seq_num(&gctx->gsc_seqdata, gw->gw_seq, 1)) {
- CERROR("phase 1+: discard replayed req: seq %u\n", gw->gw_seq);
- *major = GSS_S_DUPLICATE_TOKEN;
- return -EACCES;
- }
-
-verified:
- swabbed = ptlrpc_req_need_swab(req);
-
- /* user descriptor */
- if (gw->gw_flags & LUSTRE_GSS_PACK_USER) {
- if (msg->lm_bufcount < (offset + 1)) {
- CERROR("no user desc included\n");
- return -EINVAL;
- }
-
- if (sptlrpc_unpack_user_desc(msg, offset, swabbed)) {
- CERROR("Mal-formed user descriptor\n");
- return -EINVAL;
- }
-
- req->rq_pack_udesc = 1;
- req->rq_user_desc = lustre_msg_buf(msg, offset, 0);
- offset++;
- }
-
- /* check bulk_sec_desc data */
- if (gw->gw_flags & LUSTRE_GSS_PACK_BULK) {
- if (msg->lm_bufcount < (offset + 1)) {
- CERROR("missing bulk sec descriptor\n");
- return -EINVAL;
- }
-
- if (bulk_sec_desc_unpack(msg, offset, swabbed))
- return -EINVAL;
-
- req->rq_pack_bulk = 1;
- grctx->src_reqbsd = lustre_msg_buf(msg, offset, 0);
- grctx->src_reqbsd_size = lustre_msg_buflen(msg, offset);
- }
-
- req->rq_reqmsg = lustre_msg_buf(msg, 1, 0);
- req->rq_reqlen = msg->lm_buflens[1];
- return 0;
-}
-
-static
-int gss_svc_unseal_request(struct ptlrpc_request *req,
- struct gss_svc_reqctx *grctx,
- struct gss_wire_ctx *gw,
- __u32 *major)
-{
- struct gss_svc_ctx *gctx = grctx->src_ctx;
- struct lustre_msg *msg = req->rq_reqbuf;
- int swabbed, msglen, offset = 1;
-
- if (gss_check_seq_num(&gctx->gsc_seqdata, gw->gw_seq, 0)) {
- CERROR("phase 0: discard replayed req: seq %u\n", gw->gw_seq);
- *major = GSS_S_DUPLICATE_TOKEN;
- return -EACCES;
- }
-
- *major = gss_unseal_msg(gctx->gsc_mechctx, msg,
- &msglen, req->rq_reqdata_len);
- if (*major != GSS_S_COMPLETE) {
- CERROR("failed to unwrap request: %x\n", *major);
- return -EACCES;
- }
-
- if (gss_check_seq_num(&gctx->gsc_seqdata, gw->gw_seq, 1)) {
- CERROR("phase 1+: discard replayed req: seq %u\n", gw->gw_seq);
- *major = GSS_S_DUPLICATE_TOKEN;
- return -EACCES;
- }
-
- swabbed = __lustre_unpack_msg(msg, msglen);
- if (swabbed < 0) {
- CERROR("Failed to unpack after decryption\n");
- return -EINVAL;
- }
- req->rq_reqdata_len = msglen;
-
- if (msg->lm_bufcount < 1) {
- CERROR("Invalid buffer: is empty\n");
- return -EINVAL;
- }
-
- if (gw->gw_flags & LUSTRE_GSS_PACK_USER) {
- if (msg->lm_bufcount < offset + 1) {
- CERROR("no user descriptor included\n");
- return -EINVAL;
- }
-
- if (sptlrpc_unpack_user_desc(msg, offset, swabbed)) {
- CERROR("Mal-formed user descriptor\n");
- return -EINVAL;
- }
-
- req->rq_pack_udesc = 1;
- req->rq_user_desc = lustre_msg_buf(msg, offset, 0);
- offset++;
- }
-
- if (gw->gw_flags & LUSTRE_GSS_PACK_BULK) {
- if (msg->lm_bufcount < offset + 1) {
- CERROR("no bulk checksum included\n");
- return -EINVAL;
- }
-
- if (bulk_sec_desc_unpack(msg, offset, swabbed))
- return -EINVAL;
-
- req->rq_pack_bulk = 1;
- grctx->src_reqbsd = lustre_msg_buf(msg, offset, 0);
- grctx->src_reqbsd_size = lustre_msg_buflen(msg, offset);
- }
-
- req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, 0, 0);
- req->rq_reqlen = req->rq_reqbuf->lm_buflens[0];
- return 0;
-}
-
-static
-int gss_svc_handle_data(struct ptlrpc_request *req,
- struct gss_wire_ctx *gw)
-{
- struct gss_svc_reqctx *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- __u32 major = 0;
- int rc = 0;
-
- grctx->src_ctx = gss_svc_upcall_get_ctx(req, gw);
- if (!grctx->src_ctx) {
- major = GSS_S_NO_CONTEXT;
- goto error;
- }
-
- switch (gw->gw_svc) {
- case SPTLRPC_SVC_NULL:
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- rc = gss_svc_verify_request(req, grctx, gw, &major);
- break;
- case SPTLRPC_SVC_PRIV:
- rc = gss_svc_unseal_request(req, grctx, gw, &major);
- break;
- default:
- CERROR("unsupported gss service %d\n", gw->gw_svc);
- rc = -EINVAL;
- }
-
- if (rc == 0)
- return SECSVC_OK;
-
- CERROR("svc %u failed: major 0x%08x: req xid "LPU64" ctx %p idx "
- LPX64"(%u->%s)\n", gw->gw_svc, major, req->rq_xid,
- grctx->src_ctx, gss_handle_to_u64(&gw->gw_handle),
- grctx->src_ctx->gsc_uid, libcfs_nid2str(req->rq_peer.nid));
-error:
- /* we only notify client in case of NO_CONTEXT/BAD_SIG, which
- * might happen after server reboot, to allow recovery. */
- if ((major == GSS_S_NO_CONTEXT || major == GSS_S_BAD_SIG) &&
- gss_pack_err_notify(req, major, 0) == 0)
- return SECSVC_COMPLETE;
-
- return SECSVC_DROP;
-}
-
-static
-int gss_svc_handle_destroy(struct ptlrpc_request *req,
- struct gss_wire_ctx *gw)
-{
- struct gss_svc_reqctx *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- __u32 major;
-
- req->rq_ctx_fini = 1;
- req->rq_no_reply = 1;
-
- grctx->src_ctx = gss_svc_upcall_get_ctx(req, gw);
- if (!grctx->src_ctx) {
- CDEBUG(D_SEC, "invalid gss context handle for destroy.\n");
- return SECSVC_DROP;
- }
-
- if (gw->gw_svc != SPTLRPC_SVC_INTG) {
- CERROR("svc %u is not supported in destroy.\n", gw->gw_svc);
- return SECSVC_DROP;
- }
-
- if (gss_svc_verify_request(req, grctx, gw, &major))
- return SECSVC_DROP;
-
- CWARN("destroy svc ctx %p idx "LPX64" (%u->%s)\n",
- grctx->src_ctx, gss_handle_to_u64(&gw->gw_handle),
- grctx->src_ctx->gsc_uid, libcfs_nid2str(req->rq_peer.nid));
-
- gss_svc_upcall_destroy_ctx(grctx->src_ctx);
-
- if (gw->gw_flags & LUSTRE_GSS_PACK_USER) {
- if (req->rq_reqbuf->lm_bufcount < 4) {
- CERROR("missing user descriptor, ignore it\n");
- return SECSVC_OK;
- }
- if (sptlrpc_unpack_user_desc(req->rq_reqbuf, 2,
- ptlrpc_req_need_swab(req))) {
- CERROR("Mal-formed user descriptor, ignore it\n");
- return SECSVC_OK;
- }
-
- req->rq_pack_udesc = 1;
- req->rq_user_desc = lustre_msg_buf(req->rq_reqbuf, 2, 0);
- }
-
- return SECSVC_OK;
-}
-
-int gss_svc_accept(struct ptlrpc_sec_policy *policy, struct ptlrpc_request *req)
-{
- struct gss_header *ghdr;
- struct gss_svc_reqctx *grctx;
- struct gss_wire_ctx *gw;
- int swabbed, rc;
-
- LASSERT(req->rq_reqbuf);
- LASSERT(req->rq_svc_ctx == NULL);
-
- if (req->rq_reqbuf->lm_bufcount < 2) {
- CERROR("buf count only %d\n", req->rq_reqbuf->lm_bufcount);
- return SECSVC_DROP;
- }
-
- swabbed = ptlrpc_req_need_swab(req);
-
- ghdr = gss_swab_header(req->rq_reqbuf, 0, swabbed);
- if (ghdr == NULL) {
- CERROR("can't decode gss header\n");
- return SECSVC_DROP;
- }
-
- /* sanity checks */
- if (ghdr->gh_version != PTLRPC_GSS_VERSION) {
- CERROR("gss version %u, expect %u\n", ghdr->gh_version,
- PTLRPC_GSS_VERSION);
- return SECSVC_DROP;
- }
-
- req->rq_sp_from = ghdr->gh_sp;
-
- /* alloc grctx data */
- OBD_ALLOC_PTR(grctx);
- if (!grctx)
- return SECSVC_DROP;
-
- grctx->src_base.sc_policy = sptlrpc_policy_get(policy);
- atomic_set(&grctx->src_base.sc_refcount, 1);
- req->rq_svc_ctx = &grctx->src_base;
- gw = &grctx->src_wirectx;
-
- /* save wire context */
- gw->gw_flags = ghdr->gh_flags;
- gw->gw_proc = ghdr->gh_proc;
- gw->gw_seq = ghdr->gh_seq;
- gw->gw_svc = ghdr->gh_svc;
- rawobj_from_netobj(&gw->gw_handle, &ghdr->gh_handle);
-
- /* keep original wire header which subject to checksum verification */
- if (swabbed)
- gss_header_swabber(ghdr);
-
- switch (ghdr->gh_proc) {
- case PTLRPC_GSS_PROC_INIT:
- case PTLRPC_GSS_PROC_CONTINUE_INIT:
- rc = gss_svc_handle_init(req, gw);
- break;
- case PTLRPC_GSS_PROC_DATA:
- rc = gss_svc_handle_data(req, gw);
- break;
- case PTLRPC_GSS_PROC_DESTROY:
- rc = gss_svc_handle_destroy(req, gw);
- break;
- default:
- CERROR("unknown proc %u\n", gw->gw_proc);
- rc = SECSVC_DROP;
- break;
- }
-
- switch (rc) {
- case SECSVC_OK:
- LASSERT(grctx->src_ctx);
-
- req->rq_auth_gss = 1;
- req->rq_auth_remote = grctx->src_ctx->gsc_remote;
- req->rq_auth_usr_mdt = grctx->src_ctx->gsc_usr_mds;
- req->rq_auth_usr_ost = grctx->src_ctx->gsc_usr_oss;
- req->rq_auth_usr_root = grctx->src_ctx->gsc_usr_root;
- req->rq_auth_uid = grctx->src_ctx->gsc_uid;
- req->rq_auth_mapped_uid = grctx->src_ctx->gsc_mapped_uid;
- break;
- case SECSVC_COMPLETE:
- break;
- case SECSVC_DROP:
- gss_svc_reqctx_free(grctx);
- req->rq_svc_ctx = NULL;
- break;
- }
-
- return rc;
-}
-
-void gss_svc_invalidate_ctx(struct ptlrpc_svc_ctx *svc_ctx)
-{
- struct gss_svc_reqctx *grctx;
-
- if (svc_ctx == NULL) {
- return;
- }
-
- grctx = gss_svc_ctx2reqctx(svc_ctx);
-
- CWARN("gss svc invalidate ctx %p(%u)\n",
- grctx->src_ctx, grctx->src_ctx->gsc_uid);
- gss_svc_upcall_destroy_ctx(grctx->src_ctx);
-}
-
-static inline
-int gss_svc_payload(struct gss_svc_reqctx *grctx, int early,
- int msgsize, int privacy)
-{
- /* we should treat early reply normally, but which is actually sharing
- * the same ctx with original request, so in this case we should
- * ignore the special ctx's special flags */
- if (early == 0 && gss_svc_reqctx_is_special(grctx))
- return grctx->src_reserve_len;
-
- return gss_mech_payload(NULL, msgsize, privacy);
-}
-
-static int gss_svc_bulk_payload(struct gss_svc_ctx *gctx,
- struct sptlrpc_flavor *flvr,
- int read)
-{
- int payload = sizeof(struct ptlrpc_bulk_sec_desc);
-
- if (read) {
- switch (SPTLRPC_FLVR_BULK_SVC(flvr->sf_rpc)) {
- case SPTLRPC_BULK_SVC_NULL:
- break;
- case SPTLRPC_BULK_SVC_INTG:
- payload += gss_mech_payload(NULL, 0, 0);
- break;
- case SPTLRPC_BULK_SVC_PRIV:
- payload += gss_mech_payload(NULL, 0, 1);
- break;
- case SPTLRPC_BULK_SVC_AUTH:
- default:
- LBUG();
- }
- }
-
- return payload;
-}
-
-int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
-{
- struct gss_svc_reqctx *grctx;
- struct ptlrpc_reply_state *rs;
- int early, privacy, svc, bsd_off = 0;
- __u32 ibuflens[2], buflens[4];
- int ibufcnt = 0, bufcnt;
- int txtsize, wmsg_size, rs_size;
-
- LASSERT(msglen % 8 == 0);
-
- if (req->rq_pack_bulk && !req->rq_bulk_read && !req->rq_bulk_write) {
- CERROR("client request bulk sec on non-bulk rpc\n");
- return -EPROTO;
- }
-
- svc = SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc);
- early = (req->rq_packed_final == 0);
-
- grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- if (!early && gss_svc_reqctx_is_special(grctx))
- privacy = 0;
- else
- privacy = (svc == SPTLRPC_SVC_PRIV);
-
- if (privacy) {
- /* inner clear buffers */
- ibufcnt = 1;
- ibuflens[0] = msglen;
-
- if (req->rq_pack_bulk) {
- LASSERT(grctx->src_reqbsd);
-
- bsd_off = ibufcnt;
- ibuflens[ibufcnt++] = gss_svc_bulk_payload(
- grctx->src_ctx,
- &req->rq_flvr,
- req->rq_bulk_read);
- }
-
- txtsize = lustre_msg_size_v2(ibufcnt, ibuflens);
- txtsize += GSS_MAX_CIPHER_BLOCK;
-
- /* wrapper buffer */
- bufcnt = 2;
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = gss_svc_payload(grctx, early, txtsize, 1);
- } else {
- bufcnt = 2;
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = msglen;
-
- txtsize = buflens[0];
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[1];
-
- if (req->rq_pack_bulk) {
- LASSERT(grctx->src_reqbsd);
-
- bsd_off = bufcnt;
- buflens[bufcnt] = gss_svc_bulk_payload(
- grctx->src_ctx,
- &req->rq_flvr,
- req->rq_bulk_read);
- if (svc == SPTLRPC_SVC_INTG)
- txtsize += buflens[bufcnt];
- bufcnt++;
- }
-
- if ((!early && gss_svc_reqctx_is_special(grctx)) ||
- svc != SPTLRPC_SVC_NULL)
- buflens[bufcnt++] = gss_svc_payload(grctx, early,
- txtsize, 0);
- }
-
- wmsg_size = lustre_msg_size_v2(bufcnt, buflens);
-
- rs_size = sizeof(*rs) + wmsg_size;
- rs = req->rq_reply_state;
-
- if (rs) {
- /* pre-allocated */
- LASSERT(rs->rs_size >= rs_size);
- } else {
- OBD_ALLOC_LARGE(rs, rs_size);
- if (rs == NULL)
- return -ENOMEM;
-
- rs->rs_size = rs_size;
- }
-
- rs->rs_repbuf = (struct lustre_msg *) (rs + 1);
- rs->rs_repbuf_len = wmsg_size;
-
- /* initialize the buffer */
- if (privacy) {
- lustre_init_msg_v2(rs->rs_repbuf, ibufcnt, ibuflens, NULL);
- rs->rs_msg = lustre_msg_buf(rs->rs_repbuf, 0, msglen);
- } else {
- lustre_init_msg_v2(rs->rs_repbuf, bufcnt, buflens, NULL);
- rs->rs_repbuf->lm_secflvr = req->rq_flvr.sf_rpc;
-
- rs->rs_msg = lustre_msg_buf(rs->rs_repbuf, 1, 0);
- }
-
- if (bsd_off) {
- grctx->src_repbsd = lustre_msg_buf(rs->rs_repbuf, bsd_off, 0);
- grctx->src_repbsd_size = lustre_msg_buflen(rs->rs_repbuf,
- bsd_off);
- }
-
- gss_svc_reqctx_addref(grctx);
- rs->rs_svc_ctx = req->rq_svc_ctx;
-
- LASSERT(rs->rs_msg);
- req->rq_reply_state = rs;
- return 0;
-}
-
-static int gss_svc_seal(struct ptlrpc_request *req,
- struct ptlrpc_reply_state *rs,
- struct gss_svc_reqctx *grctx)
-{
- struct gss_svc_ctx *gctx = grctx->src_ctx;
- rawobj_t hdrobj, msgobj, token;
- struct gss_header *ghdr;
- __u8 *token_buf;
- int token_buflen;
- __u32 buflens[2], major;
- int msglen, rc;
-
- /* get clear data length. note embedded lustre_msg might
- * have been shrunk */
- if (req->rq_replen != lustre_msg_buflen(rs->rs_repbuf, 0))
- msglen = lustre_shrink_msg(rs->rs_repbuf, 0, req->rq_replen, 1);
- else
- msglen = lustre_msg_size_v2(rs->rs_repbuf->lm_bufcount,
- rs->rs_repbuf->lm_buflens);
-
- /* temporarily use tail of buffer to hold gss header data */
- LASSERT(msglen + PTLRPC_GSS_HEADER_SIZE <= rs->rs_repbuf_len);
- ghdr = (struct gss_header *) ((char *) rs->rs_repbuf +
- rs->rs_repbuf_len - PTLRPC_GSS_HEADER_SIZE);
- ghdr->gh_version = PTLRPC_GSS_VERSION;
- ghdr->gh_sp = LUSTRE_SP_ANY;
- ghdr->gh_flags = 0;
- ghdr->gh_proc = PTLRPC_GSS_PROC_DATA;
- ghdr->gh_seq = grctx->src_wirectx.gw_seq;
- ghdr->gh_svc = SPTLRPC_SVC_PRIV;
- ghdr->gh_handle.len = 0;
- if (req->rq_pack_bulk)
- ghdr->gh_flags |= LUSTRE_GSS_PACK_BULK;
-
- /* allocate temporary cipher buffer */
- token_buflen = gss_mech_payload(gctx->gsc_mechctx, msglen, 1);
- OBD_ALLOC_LARGE(token_buf, token_buflen);
- if (token_buf == NULL)
- return -ENOMEM;
-
- hdrobj.len = PTLRPC_GSS_HEADER_SIZE;
- hdrobj.data = (__u8 *) ghdr;
- msgobj.len = msglen;
- msgobj.data = (__u8 *) rs->rs_repbuf;
- token.len = token_buflen;
- token.data = token_buf;
-
- major = lgss_wrap(gctx->gsc_mechctx, &hdrobj, &msgobj,
- rs->rs_repbuf_len - PTLRPC_GSS_HEADER_SIZE, &token);
- if (major != GSS_S_COMPLETE) {
- CERROR("wrap message error: %08x\n", major);
- GOTO(out_free, rc = -EPERM);
- }
- LASSERT(token.len <= token_buflen);
-
- /* we are about to override data at rs->rs_repbuf, nullify pointers
- * to which to catch further illegal usage. */
- if (req->rq_pack_bulk) {
- grctx->src_repbsd = NULL;
- grctx->src_repbsd_size = 0;
- }
-
- /* now fill the actual wire data
- * - gss header
- * - gss token
- */
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = token.len;
-
- rs->rs_repdata_len = lustre_msg_size_v2(2, buflens);
- LASSERT(rs->rs_repdata_len <= rs->rs_repbuf_len);
-
- lustre_init_msg_v2(rs->rs_repbuf, 2, buflens, NULL);
- rs->rs_repbuf->lm_secflvr = req->rq_flvr.sf_rpc;
-
- memcpy(lustre_msg_buf(rs->rs_repbuf, 0, 0), ghdr,
- PTLRPC_GSS_HEADER_SIZE);
- memcpy(lustre_msg_buf(rs->rs_repbuf, 1, 0), token.data, token.len);
-
- /* reply offset */
- if (req->rq_packed_final &&
- (lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT))
- req->rq_reply_off = gss_at_reply_off_priv;
- else
- req->rq_reply_off = 0;
-
- /* to catch upper layer's further access */
- rs->rs_msg = NULL;
- req->rq_repmsg = NULL;
- req->rq_replen = 0;
-
- rc = 0;
-out_free:
- OBD_FREE_LARGE(token_buf, token_buflen);
- return rc;
-}
-
-int gss_svc_authorize(struct ptlrpc_request *req)
-{
- struct ptlrpc_reply_state *rs = req->rq_reply_state;
- struct gss_svc_reqctx *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
- struct gss_wire_ctx *gw = &grctx->src_wirectx;
- int early, rc;
-
- early = (req->rq_packed_final == 0);
-
- if (!early && gss_svc_reqctx_is_special(grctx)) {
- LASSERT(rs->rs_repdata_len != 0);
-
- req->rq_reply_off = gss_at_reply_off_integ;
- return 0;
- }
-
- /* early reply could happen in many cases */
- if (!early &&
- gw->gw_proc != PTLRPC_GSS_PROC_DATA &&
- gw->gw_proc != PTLRPC_GSS_PROC_DESTROY) {
- CERROR("proc %d not support\n", gw->gw_proc);
- return -EINVAL;
- }
-
- LASSERT(grctx->src_ctx);
-
- switch (gw->gw_svc) {
- case SPTLRPC_SVC_NULL:
- case SPTLRPC_SVC_AUTH:
- case SPTLRPC_SVC_INTG:
- rc = gss_svc_sign(req, rs, grctx, gw->gw_svc);
- break;
- case SPTLRPC_SVC_PRIV:
- rc = gss_svc_seal(req, rs, grctx);
- break;
- default:
- CERROR("Unknown service %d\n", gw->gw_svc);
- GOTO(out, rc = -EINVAL);
- }
- rc = 0;
-
-out:
- return rc;
-}
-
-void gss_svc_free_rs(struct ptlrpc_reply_state *rs)
-{
- struct gss_svc_reqctx *grctx;
-
- LASSERT(rs->rs_svc_ctx);
- grctx = container_of(rs->rs_svc_ctx, struct gss_svc_reqctx, src_base);
-
- gss_svc_reqctx_decref(grctx);
- rs->rs_svc_ctx = NULL;
-
- if (!rs->rs_prealloc)
- OBD_FREE_LARGE(rs, rs->rs_size);
-}
-
-void gss_svc_free_ctx(struct ptlrpc_svc_ctx *ctx)
-{
- LASSERT(atomic_read(&ctx->sc_refcount) == 0);
- gss_svc_reqctx_free(gss_svc_ctx2reqctx(ctx));
-}
-
-int gss_copy_rvc_cli_ctx(struct ptlrpc_cli_ctx *cli_ctx,
- struct ptlrpc_svc_ctx *svc_ctx)
-{
- struct gss_cli_ctx *cli_gctx = ctx2gctx(cli_ctx);
- struct gss_svc_ctx *svc_gctx = gss_svc_ctx2gssctx(svc_ctx);
- struct gss_ctx *mechctx = NULL;
-
- LASSERT(cli_gctx);
- LASSERT(svc_gctx && svc_gctx->gsc_mechctx);
-
- cli_gctx->gc_proc = PTLRPC_GSS_PROC_DATA;
- cli_gctx->gc_win = GSS_SEQ_WIN;
-
- /* The problem is the reverse ctx might get lost in some recovery
- * situations, and the same svc_ctx will be used to re-create it.
- * if there's callback be sentout before that, new reverse ctx start
- * with sequence 0 will lead to future callback rpc be treated as
- * replay.
- *
- * each reverse root ctx will record its latest sequence number on its
- * buddy svcctx before be destroyed, so here we continue use it.
- */
- atomic_set(&cli_gctx->gc_seq, svc_gctx->gsc_rvs_seq);
-
- if (gss_svc_upcall_dup_handle(&cli_gctx->gc_svc_handle, svc_gctx)) {
- CERROR("failed to dup svc handle\n");
- goto err_out;
- }
-
- if (lgss_copy_reverse_context(svc_gctx->gsc_mechctx, &mechctx) !=
- GSS_S_COMPLETE) {
- CERROR("failed to copy mech context\n");
- goto err_svc_handle;
- }
-
- if (rawobj_dup(&cli_gctx->gc_handle, &svc_gctx->gsc_rvs_hdl)) {
- CERROR("failed to dup reverse handle\n");
- goto err_ctx;
- }
-
- cli_gctx->gc_mechctx = mechctx;
- gss_cli_ctx_uptodate(cli_gctx);
-
- return 0;
-
-err_ctx:
- lgss_delete_sec_context(&mechctx);
-err_svc_handle:
- rawobj_free(&cli_gctx->gc_svc_handle);
-err_out:
- return -ENOMEM;
-}
-
-static void gss_init_at_reply_offset(void)
-{
- __u32 buflens[3];
- int clearsize;
-
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = lustre_msg_early_size();
- buflens[2] = gss_cli_payload(NULL, buflens[1], 0);
- gss_at_reply_off_integ = lustre_msg_size_v2(3, buflens);
-
- buflens[0] = lustre_msg_early_size();
- clearsize = lustre_msg_size_v2(1, buflens);
- buflens[0] = PTLRPC_GSS_HEADER_SIZE;
- buflens[1] = gss_cli_payload(NULL, clearsize, 0);
- buflens[2] = gss_cli_payload(NULL, clearsize, 1);
- gss_at_reply_off_priv = lustre_msg_size_v2(3, buflens);
-}
-
-int __init sptlrpc_gss_init(void)
-{
- int rc;
-
- rc = gss_init_lproc();
- if (rc)
- return rc;
-
- rc = gss_init_cli_upcall();
- if (rc)
- goto out_lproc;
-
- rc = gss_init_svc_upcall();
- if (rc)
- goto out_cli_upcall;
-
- rc = init_kerberos_module();
- if (rc)
- goto out_svc_upcall;
-
- /* register policy after all other stuff be initialized, because it
- * might be in used immediately after the registration. */
-
- rc = gss_init_keyring();
- if (rc)
- goto out_kerberos;
-
-#ifdef HAVE_GSS_PIPEFS
- rc = gss_init_pipefs();
- if (rc)
- goto out_keyring;
-#endif
-
- gss_init_at_reply_offset();
-
- return 0;
-
-#ifdef HAVE_GSS_PIPEFS
-out_keyring:
- gss_exit_keyring();
-#endif
-
-out_kerberos:
- cleanup_kerberos_module();
-out_svc_upcall:
- gss_exit_svc_upcall();
-out_cli_upcall:
- gss_exit_cli_upcall();
-out_lproc:
- gss_exit_lproc();
- return rc;
-}
-
-static void __exit sptlrpc_gss_exit(void)
-{
- gss_exit_keyring();
-#ifdef HAVE_GSS_PIPEFS
- gss_exit_pipefs();
-#endif
- cleanup_kerberos_module();
- gss_exit_svc_upcall();
- gss_exit_cli_upcall();
- gss_exit_lproc();
-}
-
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("GSS security policy for Lustre");
-MODULE_LICENSE("GPL");
-
-module_init(sptlrpc_gss_init);
-module_exit(sptlrpc_gss_exit);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 8573f328bd2a..f522fc5d3a93 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -40,14 +40,14 @@
#define DEBUG_SUBSYSTEM S_RPC
-#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 "../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 "ptlrpc_internal.h"
@@ -66,7 +66,7 @@ static void __import_set_state(struct obd_import *imp,
imp->imp_state = state;
imp->imp_state_hist[imp->imp_state_hist_idx].ish_state = state;
imp->imp_state_hist[imp->imp_state_hist_idx].ish_time =
- cfs_time_current_sec();
+ get_seconds();
imp->imp_state_hist_idx = (imp->imp_state_hist_idx + 1) %
IMP_STATE_HIST_LEN;
}
@@ -242,7 +242,7 @@ ptlrpc_inflight_deadline(struct ptlrpc_request *req, time_t now)
static unsigned int ptlrpc_inflight_timeout(struct obd_import *imp)
{
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
struct list_head *tmp, *n;
struct ptlrpc_request *req;
unsigned int timeout = 0;
@@ -275,6 +275,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
if (!imp->imp_invalid || imp->imp_obd->obd_no_recov)
ptlrpc_deactivate_import(imp);
+ CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_CONNECT_NET, 3 * cfs_fail_val / 2);
LASSERT(imp->imp_invalid);
/* Wait forever until inflight == 0. We really can't do it another
@@ -392,6 +393,19 @@ void ptlrpc_activate_import(struct obd_import *imp)
}
EXPORT_SYMBOL(ptlrpc_activate_import);
+static void ptlrpc_pinger_force(struct obd_import *imp)
+{
+ CDEBUG(D_HA, "%s: waking up pinger s:%s\n", obd2cli_tgt(imp->imp_obd),
+ ptlrpc_import_state_name(imp->imp_state));
+
+ spin_lock(&imp->imp_lock);
+ imp->imp_force_verify = 1;
+ spin_unlock(&imp->imp_lock);
+
+ if (imp->imp_state != LUSTRE_IMP_CONNECTING)
+ ptlrpc_pinger_wake_up();
+}
+
void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
{
LASSERT(!imp->imp_dlm_fake);
@@ -406,20 +420,30 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
ptlrpc_deactivate_import(imp);
}
- CDEBUG(D_HA, "%s: waking up pinger\n",
- obd2cli_tgt(imp->imp_obd));
-
- spin_lock(&imp->imp_lock);
- imp->imp_force_verify = 1;
- spin_unlock(&imp->imp_lock);
-
- ptlrpc_pinger_wake_up();
+ ptlrpc_pinger_force(imp);
}
}
EXPORT_SYMBOL(ptlrpc_fail_import);
int ptlrpc_reconnect_import(struct obd_import *imp)
{
+#ifdef ENABLE_PINGER
+ struct l_wait_info lwi;
+ int secs = cfs_time_seconds(obd_timeout);
+ int rc;
+
+ ptlrpc_pinger_force(imp);
+
+ CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
+ obd2cli_tgt(imp->imp_obd), secs);
+
+ lwi = LWI_TIMEOUT(secs, NULL, NULL);
+ rc = l_wait_event(imp->imp_recovery_waitq,
+ !ptlrpc_import_in_recovery(imp), &lwi);
+ CDEBUG(D_HA, "%s: recovery finished s:%s\n", obd2cli_tgt(imp->imp_obd),
+ ptlrpc_import_state_name(imp->imp_state));
+ return rc;
+#else
ptlrpc_set_import_discon(imp, 0);
/* Force a new connect attempt */
ptlrpc_invalidate_import(imp);
@@ -444,6 +468,7 @@ int ptlrpc_reconnect_import(struct obd_import *imp)
/* Attempt a new connect */
ptlrpc_recover_import(imp, NULL, 0);
return 0;
+#endif
}
EXPORT_SYMBOL(ptlrpc_reconnect_import);
@@ -469,7 +494,7 @@ static int import_select_connection(struct obd_import *imp)
}
list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
- CDEBUG(D_HA, "%s: connect to NID %s last attempt "LPU64"\n",
+ CDEBUG(D_HA, "%s: connect to NID %s last attempt %llu\n",
imp->imp_obd->obd_name,
libcfs_nid2str(conn->oic_conn->c_peer.nid),
conn->oic_last_attempt);
@@ -817,8 +842,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="LPX64" grranted="LPX64"\n",
+ CERROR("%s: Server didn't granted asked subset of flags: asked=%#llx grranted=%#llx\n",
imp->imp_obd->obd_name,imp->imp_connect_flags_orig,
ocd->ocd_connect_flags);
GOTO(out, rc = -EPROTO);
@@ -876,8 +900,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
memset(&old_hdl, 0, sizeof(old_hdl));
if (!memcmp(&old_hdl, lustre_msg_get_handle(request->rq_repmsg),
sizeof(old_hdl))) {
- LCONSOLE_WARN("Reconnect to %s (at @%s) failed due "
- "bad handle "LPX64"\n",
+ LCONSOLE_WARN("Reconnect to %s (at @%s) failed due bad handle %#llx\n",
obd2cli_tgt(imp->imp_obd),
imp->imp_connection->c_remote_uuid.uuid,
imp->imp_dlm_handle.cookie);
@@ -898,9 +921,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
* participate since we can reestablish all of our state
* with server again */
if ((MSG_CONNECT_RECOVERING & msg_flags)) {
- CDEBUG(level,"%s@%s changed server handle from "
- LPX64" to "LPX64
- " but is still in recovery\n",
+ CDEBUG(level,"%s@%s changed server handle from %#llx to %#llx but is still in recovery\n",
obd2cli_tgt(imp->imp_obd),
imp->imp_connection->c_remote_uuid.uuid,
imp->imp_remote_handle.cookie,
@@ -908,8 +929,7 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
request->rq_repmsg)->cookie);
} else {
LCONSOLE_WARN("Evicted from %s (at %s) "
- "after server handle changed from "
- LPX64" to "LPX64"\n",
+ "after server handle changed from %#llx to %#llx\n",
obd2cli_tgt(imp->imp_obd),
imp->imp_connection-> \
c_remote_uuid.uuid,
@@ -973,8 +993,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env,
if (lustre_msg_get_last_committed(request->rq_repmsg) > 0 &&
lustre_msg_get_last_committed(request->rq_repmsg) <
aa->pcaa_peer_committed) {
- CERROR("%s went back in time (transno "LPD64
- " was previously committed, server now claims "LPD64
+ CERROR("%s went back in time (transno %lld"
+ " was previously committed, server now claims %lld"
")! See https://bugzilla.lustre.org/show_bug.cgi?"
"id=9646\n",
obd2cli_tgt(imp->imp_obd), aa->pcaa_peer_committed,
@@ -1092,9 +1112,8 @@ finish:
* disable lru_resize, etc. */
if (old_connect_flags != exp_connect_flags(exp) ||
aa->pcaa_initial_connect) {
- CDEBUG(D_HA, "%s: Resetting ns_connect_flags to server "
- "flags: "LPX64"\n", imp->imp_obd->obd_name,
- ocd->ocd_connect_flags);
+ CDEBUG(D_HA, "%s: Resetting ns_connect_flags to server flags: %#llx\n",
+ imp->imp_obd->obd_name, ocd->ocd_connect_flags);
imp->imp_obd->obd_namespace->ns_connect_flags =
ocd->ocd_connect_flags;
imp->imp_obd->obd_namespace->ns_orig_connect_flags =
@@ -1429,7 +1448,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
if (ptlrpc_import_in_recovery(imp)) {
struct l_wait_info lwi;
- cfs_duration_t timeout;
+ long timeout;
if (AT_OFF) {
if (imp->imp_server_timeout)
@@ -1512,7 +1531,7 @@ extern unsigned int at_min, at_max, at_history;
int at_measured(struct adaptive_timeout *at, unsigned int val)
{
unsigned int old = at->at_current;
- time_t now = cfs_time_current_sec();
+ time_t now = get_seconds();
time_t binlimit = max_t(time_t, at_history / AT_BINS, 1);
LASSERT(at);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index 41c12e00129f..511cb9cbf0d4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -53,21 +53,21 @@
#include <linux/module.h>
/* LUSTRE_VERSION_CODE */
-#include <lustre_ver.h>
+#include "../include/lustre_ver.h"
-#include <obd_support.h>
+#include "../include/obd_support.h"
/* lustre_swab_mdt_body */
-#include <lustre/lustre_idl.h>
+#include "../include/lustre/lustre_idl.h"
/* obd2cli_tgt() (required by DEBUG_REQ()) */
-#include <obd.h>
+#include "../include/obd.h"
/* __REQ_LAYOUT_USER__ */
#endif
/* struct ptlrpc_request, lustre_msg* */
-#include <lustre_req_layout.h>
-#include <lustre_update.h>
-#include <lustre_acl.h>
-#include <lustre_debug.h>
+#include "../include/lustre_req_layout.h"
+#include "../include/lustre_update.h"
+#include "../include/lustre_acl.h"
+#include "../include/lustre_debug.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 ab084541fddb..6a1ab5c98bc6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/llog_client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/llog_client.c
@@ -42,11 +42,11 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_class.h>
-#include <lustre_log.h>
-#include <lustre_net.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_log.h"
+#include "../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 17c06a32df62..e9052bba6692 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/llog_net.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/llog_net.c
@@ -46,13 +46,13 @@
#define DEBUG_SUBSYSTEM S_LOG
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_class.h>
-#include <lustre_log.h>
+#include "../include/obd_class.h"
+#include "../include/lustre_log.h"
#include <linux/list.h>
-#include <lvfs.h>
-#include <lustre_fsfilt.h>
+#include "../include/lvfs.h"
+#include "../include/lustre_fsfilt.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 6b9c6db1f2df..bc220308e7d7 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -36,12 +36,12 @@
#define DEBUG_SUBSYSTEM S_CLASS
-#include <obd_support.h>
-#include <obd.h>
-#include <lprocfs_status.h>
-#include <lustre/lustre_idl.h>
-#include <lustre_net.h>
-#include <obd_class.h>
+#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 "ptlrpc_internal.h"
@@ -180,7 +180,7 @@ const char* ll_eopcode2str(__u32 opcode)
LASSERT(ll_eopcode_table[opcode].opcode == opcode);
return ll_eopcode_table[opcode].opname;
}
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
char *name, struct proc_dir_entry **procroot_ret,
struct lprocfs_stats **stats_ret)
@@ -628,7 +628,8 @@ out:
* if the optional token is omitted, the operation is performed on both the
* regular and high-priority (if the service has one) NRS head.
*/
-static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file, const char *buffer,
+static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file,
+ const char __user *buffer,
size_t count, loff_t *off)
{
struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
@@ -726,12 +727,12 @@ ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt,
* be near the head), we shouldn't have to do long
* re-scans */
LASSERTF(srhi->srhi_seq == srhi->srhi_req->rq_history_seq,
- "%s:%d: seek seq "LPU64", request seq "LPU64"\n",
+ "%s:%d: seek seq %llu, request seq %llu\n",
svcpt->scp_service->srv_name, svcpt->scp_cpt,
srhi->srhi_seq, srhi->srhi_req->rq_history_seq);
LASSERTF(!list_empty(&svcpt->scp_hist_reqs),
- "%s:%d: seek offset "LPU64", request seq "LPU64", "
- "last culled "LPU64"\n",
+ "%s:%d: seek offset %llu, request seq %llu, "
+ "last culled %llu\n",
svcpt->scp_service->srv_name, svcpt->scp_cpt,
seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled);
e = &srhi->srhi_req->rq_history_list;
@@ -932,7 +933,7 @@ static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
* must be just as careful as the service's request
* 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, LPD64":%s:%s:x"LPU64":%d:%s:%ld:%lds(%+lds) ",
+ seq_printf(s, "%lld:%s:%s:x%llu:%d:%s:%ld:%lds(%+lds) ",
req->rq_history_seq, libcfs_nid2str(req->rq_self),
libcfs_id2str(req->rq_peer), req->rq_xid,
req->rq_reqlen, ptlrpc_rqphase2str(req),
@@ -991,7 +992,7 @@ static int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n)
cur = at_get(&svcpt->scp_at_estimate);
worst = svcpt->scp_at_estimate.at_worst_ever;
worstt = svcpt->scp_at_estimate.at_worst_time;
- s2dhms(&ts, cfs_time_current_sec() - worstt);
+ s2dhms(&ts, get_seconds() - worstt);
seq_printf(m, "%10s : cur %3u worst %3u (at %ld, "
DHMS_FMT" ago) ", "service",
@@ -1339,4 +1340,4 @@ int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
}
EXPORT_SYMBOL(lprocfs_wr_pinger_recov);
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index a47a8d807d5b..89fc7f77b498 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -35,11 +35,11 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <lustre_net.h>
-#include <lustre_lib.h>
-#include <obd.h>
-#include <obd_class.h>
+#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 "ptlrpc_internal.h"
/**
@@ -79,7 +79,7 @@ static int ptl_send_buf(lnet_handle_md_t *mdh, void *base, int len,
return -ENOMEM;
}
- CDEBUG(D_NET, "Sending %d bytes to portal %d, xid "LPD64", offset %u\n",
+ CDEBUG(D_NET, "Sending %d bytes to portal %d, xid %lld, offset %u\n",
len, portal, xid, offset);
rc = LNetPut(conn->c_self, *mdh, ack,
@@ -89,7 +89,7 @@ static int ptl_send_buf(lnet_handle_md_t *mdh, void *base, int len,
/* We're going to get an UNLINK event when I unlink below,
* which will complete just like any other failed send, so
* I fall through and return success here! */
- CERROR("LNetPut(%s, %d, "LPD64") failed: %d\n",
+ CERROR("LNetPut(%s, %d, %lld) failed: %d\n",
libcfs_id2str(conn->c_peer), portal, xid, rc);
rc2 = LNetMDUnlink(*mdh);
LASSERTF(rc2 == 0, "rc2 = %d\n", rc2);
@@ -159,7 +159,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req)
LASSERTF(!(desc->bd_registered &&
req->rq_send_state != LUSTRE_IMP_REPLAY) ||
xid != desc->bd_last_xid,
- "registered: %d rq_xid: "LPU64" bd_last_xid: "LPU64"\n",
+ "registered: %d rq_xid: %llu bd_last_xid: %llu\n",
desc->bd_registered, xid, desc->bd_last_xid);
total_md = (desc->bd_iov_count + LNET_MAX_IOV - 1) / LNET_MAX_IOV;
@@ -179,7 +179,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req)
rc = LNetMEAttach(desc->bd_portal, peer, xid, 0,
LNET_UNLINK, LNET_INS_AFTER, &me_h);
if (rc != 0) {
- CERROR("%s: LNetMEAttach failed x"LPU64"/%d: rc = %d\n",
+ CERROR("%s: LNetMEAttach failed x%llu/%d: rc = %d\n",
desc->bd_import->imp_obd->obd_name, xid,
posted_md, rc);
break;
@@ -189,7 +189,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req)
rc = LNetMDAttach(me_h, md, LNET_UNLINK,
&desc->bd_mds[posted_md]);
if (rc != 0) {
- CERROR("%s: LNetMDAttach failed x"LPU64"/%d: rc = %d\n",
+ CERROR("%s: LNetMDAttach failed x%llu/%d: rc = %d\n",
desc->bd_import->imp_obd->obd_name, xid,
posted_md, rc);
rc2 = LNetMEUnlink(me_h);
@@ -213,7 +213,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req)
* infer the number of bulks that were prepared */
req->rq_xid = --xid;
LASSERTF(desc->bd_last_xid == (req->rq_xid & PTLRPC_BULK_OPS_MASK),
- "bd_last_xid = x"LPU64", rq_xid = x"LPU64"\n",
+ "bd_last_xid = x%llu, rq_xid = x%llu\n",
desc->bd_last_xid, req->rq_xid);
spin_lock(&desc->bd_lock);
@@ -225,7 +225,7 @@ int ptlrpc_register_bulk(struct ptlrpc_request *req)
spin_unlock(&desc->bd_lock);
CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, "
- "xid x"LPX64"-"LPX64", portal %u\n", desc->bd_md_count,
+ "xid x%#llx-%#llx, portal %u\n", desc->bd_md_count,
desc->bd_type == BULK_GET_SOURCE ? "get-source" : "put-sink",
desc->bd_iov_count, desc->bd_nob,
desc->bd_last_xid, req->rq_xid, desc->bd_portal);
@@ -252,7 +252,7 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
/* Let's setup deadline for reply unlink. */
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_BULK_UNLINK) &&
async && req->rq_bulk_deadline == 0)
- req->rq_bulk_deadline = cfs_time_current_sec() + LONG_UNLINK;
+ req->rq_bulk_deadline = get_seconds() + LONG_UNLINK;
if (ptlrpc_client_bulk_active(req) == 0) /* completed or */
return 1; /* never registered */
@@ -303,7 +303,7 @@ static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags)
{
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
struct ptlrpc_service *svc = svcpt->scp_service;
- int service_time = max_t(int, cfs_time_current_sec() -
+ int service_time = max_t(int, get_seconds() -
req->rq_arrival_time.tv_sec, 1);
if (!(flags & PTLRPC_REPLY_EARLY) &&
@@ -422,7 +422,7 @@ int ptlrpc_send_reply(struct ptlrpc_request *req, int flags)
if (unlikely(rc))
goto out;
- req->rq_sent = cfs_time_current_sec();
+ req->rq_sent = get_seconds();
rc = ptl_send_buf(&rs->rs_md_h, rs->rs_repbuf, rs->rs_repdata_len,
(rs->rs_difficult && !rs->rs_no_ack) ?
@@ -505,11 +505,12 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
/* If this is a re-transmit, we're required to have disengaged
* cleanly from the previous attempt */
LASSERT(!request->rq_receiving_reply);
+ LASSERT(!((lustre_msg_get_flags(request->rq_reqmsg) & MSG_REPLAY) &&
+ (request->rq_import->imp_state == LUSTRE_IMP_FULL)));
- if (request->rq_import->imp_obd &&
- request->rq_import->imp_obd->obd_fail) {
+ if (unlikely(obd != NULL && obd->obd_fail)) {
CDEBUG(D_HA, "muting rpc for failed imp obd %s\n",
- request->rq_import->imp_obd->obd_name);
+ obd->obd_name);
/* this prevents us from waiting in ptlrpc_queue_wait */
spin_lock(&request->rq_lock);
request->rq_err = 1;
@@ -579,8 +580,9 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
spin_lock(&request->rq_lock);
/* If the MD attach succeeds, there _will_ be a reply_in callback */
request->rq_receiving_reply = !noreply;
+ request->rq_req_unlink = 1;
/* We are responsible for unlinking the reply buffer */
- request->rq_must_unlink = !noreply;
+ request->rq_reply_unlink = !noreply;
/* Clear any flags that may be present from previous sends. */
request->rq_replied = 0;
request->rq_err = 0;
@@ -603,7 +605,7 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
reply_md.user_ptr = &request->rq_reply_cbid;
reply_md.eq_handle = ptlrpc_eq_h;
- /* We must see the unlink callback to unset rq_must_unlink,
+ /* We must see the unlink callback to unset rq_reply_unlink,
so we can't auto-unlink */
rc = LNetMDAttach(reply_me_h, reply_md, LNET_RETAIN,
&request->rq_reply_md_h);
@@ -617,22 +619,21 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply)
GOTO(cleanup_me, rc = -ENOMEM);
}
- CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid "LPU64
- ", portal %u\n",
+ CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid %llu, portal %u\n",
request->rq_repbuf_len, request->rq_xid,
request->rq_reply_portal);
}
/* add references on request for request_out_callback */
ptlrpc_request_addref(request);
- if (obd->obd_svc_stats != NULL)
+ if (obd != NULL && obd->obd_svc_stats != NULL)
lprocfs_counter_add(obd->obd_svc_stats, PTLRPC_REQACTIVE_CNTR,
atomic_read(&request->rq_import->imp_inflight));
OBD_FAIL_TIMEOUT(OBD_FAIL_PTLRPC_DELAY_SEND, request->rq_timeout + 5);
do_gettimeofday(&request->rq_arrival_time);
- request->rq_sent = cfs_time_current_sec();
+ request->rq_sent = get_seconds();
/* We give the server rq_timeout secs to process the req, and
add the network latency for our local timeout. */
request->rq_deadline = request->rq_sent + request->rq_timeout +
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
index 12151aa2a1e5..9ea24f8d9865 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
@@ -40,11 +40,11 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lprocfs_status.h>
-#include <linux/libcfs/libcfs.h>
+#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 "ptlrpc_internal.h"
/* XXX: This is just for liblustre. Remove the #if defined directive when the
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
index 7d3ee9706c9b..28363307ee35 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
@@ -47,9 +47,9 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <linux/libcfs/libcfs.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../../include/linux/libcfs/libcfs.h"
#include "ptlrpc_internal.h"
/**
@@ -174,9 +174,9 @@ struct ptlrpc_nrs_request * nrs_fifo_req_get(struct ptlrpc_nrs_policy *policy,
list_del_init(&nrq->nr_u.fifo.fr_list);
- CDEBUG(D_RPCTRACE, "NRS start %s request from %s, seq: "LPU64
- "\n", policy->pol_desc->pd_name,
- libcfs_id2str(req->rq_peer), nrq->nr_u.fifo.fr_sequence);
+ CDEBUG(D_RPCTRACE, "NRS start %s request from %s, seq: %llu\n",
+ policy->pol_desc->pd_name, libcfs_id2str(req->rq_peer),
+ nrq->nr_u.fifo.fr_sequence);
}
return nrq;
@@ -236,7 +236,7 @@ static void nrs_fifo_req_stop(struct ptlrpc_nrs_policy *policy,
struct ptlrpc_request *req = container_of(nrq, struct ptlrpc_request,
rq_nrq);
- CDEBUG(D_RPCTRACE, "NRS stop %s request from %s, seq: "LPU64"\n",
+ CDEBUG(D_RPCTRACE, "NRS stop %s request from %s, seq: %llu\n",
policy->pol_desc->pd_name, libcfs_id2str(req->rq_peer),
nrq->nr_u.fifo.fr_sequence);
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index cddeeb6bb23d..ac562932ccdf 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -44,13 +44,13 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <obd_cksum.h>
-#include <lustre/ll_fiemap.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_net.h"
+#include "../include/obd_cksum.h"
+#include "../include/lustre/ll_fiemap.h"
static inline int lustre_msg_hdr_size_v2(int count)
{
@@ -2140,8 +2140,8 @@ static void print_lum(struct lov_user_md *lum)
CDEBUG(D_OTHER, "lov_user_md %p:\n", lum);
CDEBUG(D_OTHER, "\tlmm_magic: %#x\n", lum->lmm_magic);
CDEBUG(D_OTHER, "\tlmm_pattern: %#x\n", lum->lmm_pattern);
- CDEBUG(D_OTHER, "\tlmm_object_id: "LPU64"\n", lmm_oi_id(&lum->lmm_oi));
- CDEBUG(D_OTHER, "\tlmm_object_gr: "LPU64"\n", lmm_oi_seq(&lum->lmm_oi));
+ CDEBUG(D_OTHER, "\tlmm_object_id: %llu\n", lmm_oi_id(&lum->lmm_oi));
+ CDEBUG(D_OTHER, "\tlmm_object_gr: %llu\n", lmm_oi_seq(&lum->lmm_oi));
CDEBUG(D_OTHER, "\tlmm_stripe_size: %#x\n", lum->lmm_stripe_size);
CDEBUG(D_OTHER, "\tlmm_stripe_count: %#x\n", lum->lmm_stripe_count);
CDEBUG(D_OTHER, "\tlmm_stripe_offset/lmm_layout_gen: %#x\n",
@@ -2292,7 +2292,7 @@ EXPORT_SYMBOL(dump_ioo);
void dump_rniobuf(struct niobuf_remote *nb)
{
- CDEBUG(D_RPCTRACE, "niobuf_remote: offset="LPU64", len=%d, flags=%x\n",
+ CDEBUG(D_RPCTRACE, "niobuf_remote: offset=%llu, len=%d, flags=%x\n",
nb->offset, nb->len, nb->flags);
}
EXPORT_SYMBOL(dump_rniobuf);
@@ -2305,20 +2305,20 @@ void dump_obdo(struct obdo *oa)
if (valid & OBD_MD_FLID)
CDEBUG(D_RPCTRACE, "obdo: id = "DOSTID"\n", POSTID(&oa->o_oi));
if (valid & OBD_MD_FLFID)
- CDEBUG(D_RPCTRACE, "obdo: o_parent_seq = "LPX64"\n",
+ CDEBUG(D_RPCTRACE, "obdo: o_parent_seq = %#llx\n",
oa->o_parent_seq);
if (valid & OBD_MD_FLSIZE)
- CDEBUG(D_RPCTRACE, "obdo: o_size = "LPD64"\n", oa->o_size);
+ CDEBUG(D_RPCTRACE, "obdo: o_size = %lld\n", oa->o_size);
if (valid & OBD_MD_FLMTIME)
- CDEBUG(D_RPCTRACE, "obdo: o_mtime = "LPD64"\n", oa->o_mtime);
+ CDEBUG(D_RPCTRACE, "obdo: o_mtime = %lld\n", oa->o_mtime);
if (valid & OBD_MD_FLATIME)
- CDEBUG(D_RPCTRACE, "obdo: o_atime = "LPD64"\n", oa->o_atime);
+ CDEBUG(D_RPCTRACE, "obdo: o_atime = %lld\n", oa->o_atime);
if (valid & OBD_MD_FLCTIME)
- CDEBUG(D_RPCTRACE, "obdo: o_ctime = "LPD64"\n", oa->o_ctime);
+ CDEBUG(D_RPCTRACE, "obdo: o_ctime = %lld\n", oa->o_ctime);
if (valid & OBD_MD_FLBLOCKS) /* allocation of space */
- CDEBUG(D_RPCTRACE, "obdo: o_blocks = "LPD64"\n", oa->o_blocks);
+ CDEBUG(D_RPCTRACE, "obdo: o_blocks = %lld\n", oa->o_blocks);
if (valid & OBD_MD_FLGRANT)
- CDEBUG(D_RPCTRACE, "obdo: o_grant = "LPD64"\n", oa->o_grant);
+ CDEBUG(D_RPCTRACE, "obdo: o_grant = %lld\n", oa->o_grant);
if (valid & OBD_MD_FLBLKSZ)
CDEBUG(D_RPCTRACE, "obdo: o_blksize = %d\n", oa->o_blksize);
if (valid & (OBD_MD_FLTYPE | OBD_MD_FLMODE))
@@ -2344,7 +2344,7 @@ void dump_obdo(struct obdo *oa)
CDEBUG(D_RPCTRACE, "obdo: o_parent_oid = %x\n",
oa->o_parent_oid);
if (valid & OBD_MD_FLEPOCH)
- CDEBUG(D_RPCTRACE, "obdo: o_ioepoch = "LPD64"\n",
+ CDEBUG(D_RPCTRACE, "obdo: o_ioepoch = %lld\n",
oa->o_ioepoch);
if (valid & OBD_MD_FLFID) {
CDEBUG(D_RPCTRACE, "obdo: o_stripe_idx = %u\n",
@@ -2353,7 +2353,7 @@ void dump_obdo(struct obdo *oa)
oa->o_parent_ver);
}
if (valid & OBD_MD_FLHANDLE)
- CDEBUG(D_RPCTRACE, "obdo: o_handle = "LPD64"\n",
+ CDEBUG(D_RPCTRACE, "obdo: o_handle = %lld\n",
oa->o_handle.cookie);
if (valid & OBD_MD_FLCOOKIE)
CDEBUG(D_RPCTRACE, "obdo: o_lcookie = "
@@ -2421,7 +2421,7 @@ void _debug_req(struct ptlrpc_request *req,
va_start(args, fmt);
libcfs_debug_vmsg2(msgdata, fmt, args,
- " req@%p x"LPU64"/t"LPD64"("LPD64") o%d->%s@%s:%d/%d"
+ " req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d"
" lens %d/%d e %d to %d dl "CFS_TIME_T" ref %d "
"fl "REQ_FLAGS_FMT"/%x/%x rc %d/%d\n",
req, req->rq_xid, req->rq_transno,
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pers.c b/drivers/staging/lustre/lustre/ptlrpc/pers.c
index d926d2b36fb4..e1334c24ebe3 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pers.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pers.c
@@ -34,11 +34,11 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_lib.h>
-#include <lustre_ha.h>
-#include <lustre_import.h>
+#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 "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index 38099d9dfdae..5e4e49fab63c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -40,8 +40,8 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
#include "ptlrpc_internal.h"
static int suppress_pings;
@@ -141,10 +141,10 @@ static inline int ptlrpc_next_reconnect(struct obd_import *imp)
return cfs_time_shift(obd_timeout);
}
-cfs_duration_t pinger_check_timeout(cfs_time_t time)
+long pinger_check_timeout(unsigned long time)
{
struct timeout_item *item;
- cfs_time_t timeout = PING_INTERVAL;
+ unsigned long timeout = PING_INTERVAL;
/* The timeout list is a increase order sorted list */
mutex_lock(&pinger_mutex);
@@ -224,6 +224,11 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp,
"or recovery disabled: %s)\n",
imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd),
ptlrpc_import_state_name(level));
+ if (force) {
+ spin_lock(&imp->imp_lock);
+ imp->imp_force_verify = 1;
+ spin_unlock(&imp->imp_lock);
+ }
} else if ((imp->imp_pingable && !suppress) || force_next || force) {
ptlrpc_ping(imp);
}
@@ -239,9 +244,9 @@ static int ptlrpc_pinger_main(void *arg)
/* And now, loop forever, pinging as needed. */
while (1) {
- cfs_time_t this_ping = cfs_time_current();
+ unsigned long this_ping = cfs_time_current();
struct l_wait_info lwi;
- cfs_duration_t time_to_next_wake;
+ long time_to_next_wake;
struct timeout_item *item;
struct list_head *iter;
@@ -278,8 +283,7 @@ static int ptlrpc_pinger_main(void *arg)
CFS_TIME_T")\n", time_to_next_wake,
cfs_time_add(this_ping,cfs_time_seconds(PING_INTERVAL)));
if (time_to_next_wake > 0) {
- lwi = LWI_TIMEOUT(max_t(cfs_duration_t,
- time_to_next_wake,
+ lwi = LWI_TIMEOUT(max_t(long, time_to_next_wake,
cfs_time_seconds(1)),
NULL, NULL);
l_wait_event(thread->t_ctl_waitq,
@@ -601,7 +605,7 @@ static int ping_evictor_main(void *arg)
obd_evict_list);
spin_unlock(&pet_lock);
- expire_time = cfs_time_current_sec() - PING_EVICT_TIMEOUT;
+ expire_time = get_seconds() - PING_EVICT_TIMEOUT;
CDEBUG(D_HA, "evicting all exports of obd %s older than %ld\n",
obd->obd_name, expire_time);
@@ -626,9 +630,9 @@ static int ping_evictor_main(void *arg)
obd->obd_name,
obd_uuid2str(&exp->exp_client_uuid),
obd_export_nid2str(exp),
- (long)(cfs_time_current_sec() -
+ (long)(get_seconds() -
exp->exp_last_request_time),
- exp, (long)cfs_time_current_sec(),
+ exp, (long)get_seconds(),
(long)expire_time,
(long)exp->exp_last_request_time);
CDEBUG(D_HA, "Last request was at %ld\n",
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index 7c9405530596..f7be007c88cb 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -76,7 +76,7 @@ void ptlrpc_initiate_recovery(struct obd_import *imp);
int lustre_unpack_req_ptlrpc_body(struct ptlrpc_request *req, int offset);
int lustre_unpack_rep_ptlrpc_body(struct ptlrpc_request *req, int offset);
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
void ptlrpc_lprocfs_register_service(struct proc_dir_entry *proc_entry,
struct ptlrpc_service *svc);
void ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc);
@@ -88,7 +88,7 @@ void ptlrpc_lprocfs_do_request_stat(struct ptlrpc_request *req,
#define ptlrpc_lprocfs_unregister_service(params...) do {} while (0)
#define ptlrpc_lprocfs_rpc_sent(params...) do {} while (0)
#define ptlrpc_lprocfs_do_request_stat(params...) do {} while (0)
-#endif /* LPROCFS */
+#endif /* CONFIG_PROC_FS */
/* NRS */
@@ -263,7 +263,7 @@ void sptlrpc_enc_pool_fini(void);
int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v);
/* sec_lproc.c */
-#ifdef LPROCFS
+#if defined (CONFIG_PROC_FS)
int sptlrpc_lproc_init(void);
void sptlrpc_lproc_fini(void);
#else
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
index 251ae75c2dd9..6d92a56da620 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c
@@ -37,10 +37,10 @@
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_req_layout.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_net.h"
+#include "../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 ca734ce079c1..9c60e2af43bf 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -55,16 +55,15 @@
#define DEBUG_SUBSYSTEM S_RPC
-# 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 "../../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 "ptlrpc_internal.h"
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index 9cec8a649dc3..5e4a1a52e0da 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -39,16 +39,16 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-# 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_ost.h>
-#include <obd_class.h>
+#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_ost.h"
+#include "../include/obd_class.h"
#include <linux/list.h>
#include "ptlrpc_internal.h"
@@ -85,7 +85,7 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight)
last_transno = imp->imp_last_replay_transno;
spin_unlock(&imp->imp_lock);
- CDEBUG(D_HA, "import %p from %s committed "LPU64" last "LPU64"\n",
+ CDEBUG(D_HA, "import %p from %s committed %llu last %llu\n",
imp, obd2cli_tgt(imp->imp_obd),
imp->imp_peer_committed_transno, last_transno);
@@ -164,8 +164,8 @@ int ptlrpc_replay_next(struct obd_import *imp, int *inflight)
if (req != NULL) {
rc = ptlrpc_replay_req(req);
if (rc) {
- CERROR("recovery replay error %d for req "
- LPU64"\n", rc, req->rq_xid);
+ CERROR("recovery replay error %d for req %llu\n",
+ rc, req->rq_xid);
return rc;
}
*inflight = 1;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 28ac824a73fb..5cff7ee6ee7b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -40,17 +40,17 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/crypto.h>
#include <linux/key.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 "../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 "ptlrpc_internal.h"
@@ -305,8 +305,8 @@ EXPORT_SYMBOL(sptlrpc_cli_ctx_put);
*/
void sptlrpc_cli_ctx_expire(struct ptlrpc_cli_ctx *ctx)
{
- LASSERT(ctx->cc_ops->die);
- ctx->cc_ops->die(ctx, 0);
+ LASSERT(ctx->cc_ops->force_die);
+ ctx->cc_ops->force_die(ctx, 0);
}
EXPORT_SYMBOL(sptlrpc_cli_ctx_expire);
@@ -344,7 +344,7 @@ static int import_sec_check_expire(struct obd_import *imp)
spin_lock(&imp->imp_lock);
if (imp->imp_sec_expire &&
- imp->imp_sec_expire < cfs_time_current_sec()) {
+ imp->imp_sec_expire < get_seconds()) {
adapt = 1;
imp->imp_sec_expire = 0;
}
@@ -591,7 +591,7 @@ int ctx_refresh_timeout(void *data)
* later than the context refresh expire time.
*/
if (rc == 0)
- req->rq_cli_ctx->cc_ops->die(req->rq_cli_ctx, 0);
+ req->rq_cli_ctx->cc_ops->force_die(req->rq_cli_ctx, 0);
return rc;
}
@@ -992,7 +992,7 @@ static int do_cli_unwrap_reply(struct ptlrpc_request *req)
case 0:
break;
default:
- CERROR("failed unpack reply: x"LPU64"\n", req->rq_xid);
+ CERROR("failed unpack reply: x%llu\n", req->rq_xid);
return -EPROTO;
}
@@ -1774,7 +1774,7 @@ int sptlrpc_target_export_check(struct obd_export *exp,
exp->exp_flvr_old[1] = exp->exp_flvr_old[0];
exp->exp_flvr_expire[1] = exp->exp_flvr_expire[0];
exp->exp_flvr_old[0] = exp->exp_flvr;
- exp->exp_flvr_expire[0] = cfs_time_current_sec() +
+ exp->exp_flvr_expire[0] = get_seconds() +
EXP_FLVR_UPDATE_EXPIRE;
exp->exp_flvr = flavor;
@@ -1848,7 +1848,7 @@ int sptlrpc_target_export_check(struct obd_export *exp,
}
if (exp->exp_flvr_expire[0]) {
- if (exp->exp_flvr_expire[0] >= cfs_time_current_sec()) {
+ if (exp->exp_flvr_expire[0] >= get_seconds()) {
if (flavor_allowed(&exp->exp_flvr_old[0], req)) {
CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the "
"middle one ("CFS_DURATION_T")\n", exp,
@@ -1856,7 +1856,7 @@ int sptlrpc_target_export_check(struct obd_export *exp,
exp->exp_flvr_old[0].sf_rpc,
exp->exp_flvr_old[1].sf_rpc,
exp->exp_flvr_expire[0] -
- cfs_time_current_sec());
+ get_seconds());
spin_unlock(&exp->exp_lock);
return 0;
}
@@ -1873,7 +1873,7 @@ int sptlrpc_target_export_check(struct obd_export *exp,
/* now it doesn't match the current flavor, the only chance we can
* accept it is match the old flavors which is not expired. */
if (exp->exp_flvr_changed == 0 && exp->exp_flvr_expire[1]) {
- if (exp->exp_flvr_expire[1] >= cfs_time_current_sec()) {
+ if (exp->exp_flvr_expire[1] >= get_seconds()) {
if (flavor_allowed(&exp->exp_flvr_old[1], req)) {
CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the "
"oldest one ("CFS_DURATION_T")\n", exp,
@@ -1881,7 +1881,7 @@ int sptlrpc_target_export_check(struct obd_export *exp,
exp->exp_flvr_old[0].sf_rpc,
exp->exp_flvr_old[1].sf_rpc,
exp->exp_flvr_expire[1] -
- cfs_time_current_sec());
+ get_seconds());
spin_unlock(&exp->exp_lock);
return 0;
}
@@ -1911,11 +1911,11 @@ int sptlrpc_target_export_check(struct obd_export *exp,
exp->exp_flvr_old[0].sf_rpc,
exp->exp_flvr_expire[0] ?
(unsigned long) (exp->exp_flvr_expire[0] -
- cfs_time_current_sec()) : 0,
+ get_seconds()) : 0,
exp->exp_flvr_old[1].sf_rpc,
exp->exp_flvr_expire[1] ?
(unsigned long) (exp->exp_flvr_expire[1] -
- cfs_time_current_sec()) : 0);
+ get_seconds()) : 0);
return -EACCES;
}
EXPORT_SYMBOL(sptlrpc_target_export_check);
@@ -2033,7 +2033,7 @@ int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req)
case 0:
break;
default:
- CERROR("error unpacking request from %s x"LPU64"\n",
+ CERROR("error unpacking request from %s x%llu\n",
libcfs_id2str(req->rq_peer), req->rq_xid);
return SECSVC_DROP;
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
index 9d51badea73d..874789b200a3 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
@@ -40,17 +40,17 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/crypto.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 "../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 "ptlrpc_internal.h"
@@ -113,7 +113,7 @@ static struct ptlrpc_enc_page_pool {
unsigned long epp_st_missings; /* # of cache missing */
unsigned long epp_st_lowfree; /* lowest free pages reached */
unsigned int epp_st_max_wqlen; /* highest waitqueue length */
- cfs_time_t epp_st_max_wait; /* in jiffies */
+ unsigned long epp_st_max_wait; /* in jiffies */
/*
* pointers to pools
*/
@@ -156,8 +156,8 @@ int sptlrpc_proc_enc_pool_seq_show(struct seq_file *m, void *v)
page_pools.epp_total_pages,
page_pools.epp_free_pages,
page_pools.epp_idle_idx,
- cfs_time_current_sec() - page_pools.epp_last_shrink,
- cfs_time_current_sec() - page_pools.epp_last_access,
+ get_seconds() - page_pools.epp_last_shrink,
+ get_seconds() - page_pools.epp_last_access,
page_pools.epp_st_max_pages,
page_pools.epp_st_grows,
page_pools.epp_st_grow_fails,
@@ -228,7 +228,7 @@ static unsigned long enc_pools_shrink_count(struct shrinker *s,
* if no pool access for a long time, we consider it's fully idle.
* a little race here is fine.
*/
- if (unlikely(cfs_time_current_sec() - page_pools.epp_last_access >
+ if (unlikely(get_seconds() - page_pools.epp_last_access >
CACHE_QUIESCENT_PERIOD)) {
spin_lock(&page_pools.epp_lock);
page_pools.epp_idle_idx = IDLE_IDX_MAX;
@@ -255,7 +255,7 @@ static unsigned long enc_pools_shrink_scan(struct shrinker *s,
(long)sc->nr_to_scan, page_pools.epp_free_pages);
page_pools.epp_st_shrinks++;
- page_pools.epp_last_shrink = cfs_time_current_sec();
+ page_pools.epp_last_shrink = get_seconds();
}
spin_unlock(&page_pools.epp_lock);
@@ -263,7 +263,7 @@ static unsigned long enc_pools_shrink_scan(struct shrinker *s,
* if no pool access for a long time, we consider it's fully idle.
* a little race here is fine.
*/
- if (unlikely(cfs_time_current_sec() - page_pools.epp_last_access >
+ if (unlikely(get_seconds() - page_pools.epp_last_access >
CACHE_QUIESCENT_PERIOD)) {
spin_lock(&page_pools.epp_lock);
page_pools.epp_idle_idx = IDLE_IDX_MAX;
@@ -498,7 +498,7 @@ int sptlrpc_enc_pool_get_pages(struct ptlrpc_bulk_desc *desc)
{
wait_queue_t waitlink;
unsigned long this_idle = -1;
- cfs_time_t tick = 0;
+ unsigned long tick = 0;
long now;
int p_idx, g_idx;
int i;
@@ -523,7 +523,7 @@ again:
if (tick == 0)
tick = cfs_time_current();
- now = cfs_time_current_sec();
+ now = get_seconds();
page_pools.epp_st_missings++;
page_pools.epp_pages_short += desc->bd_iov_count;
@@ -602,7 +602,7 @@ again:
this_idle) /
(IDLE_IDX_WEIGHT + 1);
- page_pools.epp_last_access = cfs_time_current_sec();
+ page_pools.epp_last_access = get_seconds();
spin_unlock(&page_pools.epp_lock);
return 0;
@@ -729,8 +729,8 @@ int sptlrpc_enc_pool_init(void)
page_pools.epp_growing = 0;
page_pools.epp_idle_idx = 0;
- page_pools.epp_last_shrink = cfs_time_current_sec();
- page_pools.epp_last_access = cfs_time_current_sec();
+ page_pools.epp_last_shrink = get_seconds();
+ page_pools.epp_last_access = get_seconds();
spin_lock_init(&page_pools.epp_lock);
page_pools.epp_total_pages = 0;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
index 231656ed7660..01f8b0d6660e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c
@@ -36,20 +36,20 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/crypto.h>
#include <linux/key.h>
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_log.h>
-#include <lustre_disk.h>
-#include <lustre_dlm.h>
-#include <lustre_param.h>
-#include <lustre_sec.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_log.h"
+#include "../include/lustre_disk.h"
+#include "../include/lustre_dlm.h"
+#include "../include/lustre_param.h"
+#include "../include/lustre_sec.h"
#include "ptlrpc_internal.h"
@@ -918,7 +918,7 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd)
if (imp) {
spin_lock(&imp->imp_lock);
if (imp->imp_sec)
- imp->imp_sec_expire = cfs_time_current_sec() +
+ imp->imp_sec_expire = get_seconds() +
SEC_ADAPT_DELAY;
spin_unlock(&imp->imp_lock);
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index d2eb20eb56db..c500aff66193 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -40,12 +40,12 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_sec.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre_sec.h"
#define SEC_GC_INTERVAL (30 * 60)
@@ -67,7 +67,7 @@ void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
LASSERT(sec->ps_gc_interval > 0);
LASSERT(list_empty(&sec->ps_gc_list));
- sec->ps_gc_next = cfs_time_current_sec() + sec->ps_gc_interval;
+ sec->ps_gc_next = get_seconds() + sec->ps_gc_interval;
spin_lock(&sec_gc_list_lock);
list_add_tail(&sec_gc_list, &sec->ps_gc_list);
@@ -152,11 +152,11 @@ static void sec_do_gc(struct ptlrpc_sec *sec)
CDEBUG(D_SEC, "check on sec %p(%s)\n", sec, sec->ps_policy->sp_name);
- if (cfs_time_after(sec->ps_gc_next, cfs_time_current_sec()))
+ if (cfs_time_after(sec->ps_gc_next, get_seconds()))
return;
sec->ps_policy->sp_cops->gc_ctx(sec);
- sec->ps_gc_next = cfs_time_current_sec() + sec->ps_gc_interval;
+ sec->ps_gc_next = get_seconds() + sec->ps_gc_interval;
}
static int sec_gc_main(void *arg)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
index 1213621ca5aa..0d08145a6c7e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_lproc.c
@@ -38,16 +38,16 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <linux/libcfs/libcfs.h>
+#include "../../include/linux/libcfs/libcfs.h"
#include <linux/crypto.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 "../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 "ptlrpc_internal.h"
@@ -55,7 +55,7 @@
struct proc_dir_entry *sptlrpc_proc_root = NULL;
EXPORT_SYMBOL(sptlrpc_proc_root);
-char *sec_flags2str(unsigned long flags, char *buf, int bufsize)
+static char *sec_flags2str(unsigned long flags, char *buf, int bufsize)
{
buf[0] = '\0';
@@ -104,7 +104,7 @@ static int sptlrpc_info_lprocfs_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "gc internal %ld\n", sec->ps_gc_interval);
seq_printf(seq, "gc next %ld\n",
sec->ps_gc_interval ?
- sec->ps_gc_next - cfs_time_current_sec() : 0);
+ sec->ps_gc_next - get_seconds() : 0);
sptlrpc_sec_put(sec);
out:
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
index ff1137fe4dd6..a47791411149 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_null.c
@@ -41,11 +41,11 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <obd_support.h>
-#include <obd_cksum.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_sec.h>
+#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"
static struct ptlrpc_sec_policy null_policy;
static struct ptlrpc_sec null_sec;
@@ -260,11 +260,22 @@ int null_enlarge_reqbuf(struct ptlrpc_sec *sec,
if (newbuf == NULL)
return -ENOMEM;
+ /* Must lock this, so that otherwise unprotected change of
+ * rq_reqmsg is not racing with parallel processing of
+ * imp_replay_list traversing threads. See LU-3333
+ * This is a bandaid at best, we really need to deal with this
+ * in request enlarging code before unpacking that's already
+ * there */
+ if (req->rq_import)
+ spin_lock(&req->rq_import->imp_lock);
memcpy(newbuf, req->rq_reqbuf, req->rq_reqlen);
OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
req->rq_reqbuf = req->rq_reqmsg = newbuf;
req->rq_reqbuf_len = alloc_size;
+
+ if (req->rq_import)
+ spin_unlock(&req->rq_import->imp_lock);
}
_sptlrpc_enlarge_msg_inplace(req->rq_reqmsg, segment, newsize);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
index 416401be6d4f..3d72b810c45c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_plain.c
@@ -41,11 +41,11 @@
#define DEBUG_SUBSYSTEM S_SEC
-#include <obd_support.h>
-#include <obd_cksum.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_sec.h>
+#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"
struct plain_sec {
struct ptlrpc_sec pls_base;
@@ -669,6 +669,15 @@ int plain_enlarge_reqbuf(struct ptlrpc_sec *sec,
if (newbuf == NULL)
return -ENOMEM;
+ /* Must lock this, so that otherwise unprotected change of
+ * rq_reqmsg is not racing with parallel processing of
+ * imp_replay_list traversing threads. See LU-3333
+ * This is a bandaid at best, we really need to deal with this
+ * in request enlarging code before unpacking that's already
+ * there */
+ if (req->rq_import)
+ spin_lock(&req->rq_import->imp_lock);
+
memcpy(newbuf, req->rq_reqbuf, req->rq_reqbuf_len);
OBD_FREE_LARGE(req->rq_reqbuf, req->rq_reqbuf_len);
@@ -676,6 +685,9 @@ int plain_enlarge_reqbuf(struct ptlrpc_sec *sec,
req->rq_reqbuf_len = newbuf_size;
req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf,
PLAIN_PACK_MSG_OFF, 0);
+
+ if (req->rq_import)
+ spin_unlock(&req->rq_import->imp_lock);
}
_sptlrpc_enlarge_msg_inplace(req->rq_reqbuf, PLAIN_PACK_MSG_OFF,
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index d278f2e21803..c88eae27bbf4 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -35,11 +35,11 @@
*/
#define DEBUG_SUBSYSTEM S_RPC
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lu_object.h>
-#include <linux/lnet/types.h>
+#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 "ptlrpc_internal.h"
/* The following are visible and mutable through /sys/module/ptlrpc */
@@ -1037,7 +1037,7 @@ static void ptlrpc_update_export_timer(struct obd_export *exp, long extra_delay)
will make it to the top of the list. */
/* Do not pay attention on 1sec or smaller renewals. */
- new_time = cfs_time_current_sec() + extra_delay;
+ new_time = get_seconds() + extra_delay;
if (exp->exp_last_request_time + 1 /*second */ >= new_time)
return;
@@ -1070,20 +1070,20 @@ static void ptlrpc_update_export_timer(struct obd_export *exp, long extra_delay)
/* Note - racing to start/reset the obd_eviction timer is safe */
if (exp->exp_obd->obd_eviction_timer == 0) {
/* Check if the oldest entry is expired. */
- if (cfs_time_current_sec() > (oldest_time + PING_EVICT_TIMEOUT +
+ if (get_seconds() > (oldest_time + PING_EVICT_TIMEOUT +
extra_delay)) {
/* We need a second timer, in case the net was down and
* it just came back. Since the pinger may skip every
* other PING_INTERVAL (see note in ptlrpc_pinger_main),
* we better wait for 3. */
exp->exp_obd->obd_eviction_timer =
- cfs_time_current_sec() + 3 * PING_INTERVAL;
+ get_seconds() + 3 * PING_INTERVAL;
CDEBUG(D_HA, "%s: Think about evicting %s from "CFS_TIME_T"\n",
exp->exp_obd->obd_name,
obd_export_nid2str(oldest_exp), oldest_time);
}
} else {
- if (cfs_time_current_sec() >
+ if (get_seconds() >
(exp->exp_obd->obd_eviction_timer + extra_delay)) {
/* The evictor won't evict anyone who we've heard from
* recently, so we don't have to check before we start
@@ -1100,6 +1100,7 @@ static void ptlrpc_update_export_timer(struct obd_export *exp, long extra_delay)
*/
static int ptlrpc_check_req(struct ptlrpc_request *req)
{
+ struct obd_device *obd = req->rq_export->exp_obd;
int rc = 0;
if (unlikely(lustre_msg_get_conn_cnt(req->rq_reqmsg) <
@@ -1110,26 +1111,24 @@ static int ptlrpc_check_req(struct ptlrpc_request *req)
req->rq_export->exp_conn_cnt);
return -EEXIST;
}
- if (unlikely(req->rq_export->exp_obd &&
- req->rq_export->exp_obd->obd_fail)) {
+ if (unlikely(obd == NULL || obd->obd_fail)) {
/*
* Failing over, don't handle any more reqs, send
* error response instead.
*/
CDEBUG(D_RPCTRACE, "Dropping req %p for failed obd %s\n",
- req, req->rq_export->exp_obd->obd_name);
+ req, (obd != NULL) ? obd->obd_name : "unknown");
rc = -ENODEV;
} else if (lustre_msg_get_flags(req->rq_reqmsg) &
(MSG_REPLAY | MSG_REQ_REPLAY_DONE) &&
- !(req->rq_export->exp_obd->obd_recovering)) {
+ !obd->obd_recovering) {
DEBUG_REQ(D_ERROR, req,
"Invalid replay without recovery");
class_fail_export(req->rq_export);
rc = -ENODEV;
} else if (lustre_msg_get_transno(req->rq_reqmsg) != 0 &&
- !(req->rq_export->exp_obd->obd_recovering)) {
- DEBUG_REQ(D_ERROR, req, "Invalid req with transno "
- LPU64" without recovery",
+ !obd->obd_recovering) {
+ DEBUG_REQ(D_ERROR, req, "Invalid req with transno %llu without recovery",
lustre_msg_get_transno(req->rq_reqmsg));
class_fail_export(req->rq_export);
rc = -ENODEV;
@@ -1153,7 +1152,7 @@ static void ptlrpc_at_set_timer(struct ptlrpc_service_part *svcpt)
}
/* Set timer for closest deadline */
- next = (__s32)(array->paa_deadline - cfs_time_current_sec() -
+ next = (__s32)(array->paa_deadline - get_seconds() -
at_early_margin);
if (next <= 0) {
ptlrpc_at_timer((unsigned long)svcpt);
@@ -1243,7 +1242,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
struct ptlrpc_request *reqcopy;
struct lustre_msg *reqmsg;
- cfs_duration_t olddl = req->rq_deadline - cfs_time_current_sec();
+ long olddl = req->rq_deadline - get_seconds();
time_t newdl;
int rc;
@@ -1288,7 +1287,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
/* Fake our processing time into the future to ask the clients
* for some extra amount of time */
at_measured(&svcpt->scp_at_estimate, at_extra +
- cfs_time_current_sec() -
+ get_seconds() -
req->rq_arrival_time.tv_sec);
/* Check to see if we've actually increased the deadline -
@@ -1299,11 +1298,11 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
"(%ld/%ld), not sending early reply\n",
olddl, req->rq_arrival_time.tv_sec +
at_get(&svcpt->scp_at_estimate) -
- cfs_time_current_sec());
+ get_seconds());
return -ETIMEDOUT;
}
}
- newdl = cfs_time_current_sec() + at_get(&svcpt->scp_at_estimate);
+ newdl = get_seconds() + at_get(&svcpt->scp_at_estimate);
reqcopy = ptlrpc_request_cache_alloc(GFP_NOFS);
if (reqcopy == NULL)
@@ -1381,8 +1380,8 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
struct list_head work_list;
__u32 index, count;
time_t deadline;
- time_t now = cfs_time_current_sec();
- cfs_duration_t delay;
+ time_t now = get_seconds();
+ long delay;
int first, counter = 0;
spin_lock(&svcpt->scp_at_lock);
@@ -1766,24 +1765,24 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
if (SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc) != SPTLRPC_POLICY_NULL) {
rc = ptlrpc_unpack_req_msg(req, req->rq_reqlen);
if (rc != 0) {
- CERROR("error unpacking request: ptl %d from %s "
- "x"LPU64"\n", svc->srv_req_portal,
- libcfs_id2str(req->rq_peer), req->rq_xid);
+ CERROR("error unpacking request: ptl %d from %s x%llu\n",
+ svc->srv_req_portal, libcfs_id2str(req->rq_peer),
+ req->rq_xid);
goto err_req;
}
}
rc = lustre_unpack_req_ptlrpc_body(req, MSG_PTLRPC_BODY_OFF);
if (rc) {
- CERROR("error unpacking ptlrpc body: ptl %d from %s x"
- LPU64"\n", svc->srv_req_portal,
- libcfs_id2str(req->rq_peer), req->rq_xid);
+ CERROR("error unpacking ptlrpc body: ptl %d from %s x%llu\n",
+ svc->srv_req_portal, libcfs_id2str(req->rq_peer),
+ req->rq_xid);
goto err_req;
}
if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DROP_REQ_OPC) &&
lustre_msg_get_opc(req->rq_reqmsg) == cfs_fail_val) {
- CERROR("drop incoming rpc opc %u, x"LPU64"\n",
+ CERROR("drop incoming rpc opc %u, x%llu\n",
cfs_fail_val, req->rq_xid);
goto err_req;
}
@@ -1808,7 +1807,7 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
break;
}
- CDEBUG(D_RPCTRACE, "got req x"LPU64"\n", req->rq_xid);
+ CDEBUG(D_RPCTRACE, "got req x%llu\n", req->rq_xid);
req->rq_export = class_conn2export(
lustre_msg_get_handle(req->rq_reqmsg));
@@ -1827,9 +1826,9 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
}
/* req_in handling should/must be fast */
- if (cfs_time_current_sec() - req->rq_arrival_time.tv_sec > 5)
+ if (get_seconds() - req->rq_arrival_time.tv_sec > 5)
DEBUG_REQ(D_WARNING, req, "Slow req_in handling "CFS_DURATION_T"s",
- cfs_time_sub(cfs_time_current_sec(),
+ cfs_time_sub(get_seconds(),
req->rq_arrival_time.tv_sec));
/* Set rpc server deadline and add it to the timed list */
@@ -1918,7 +1917,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
request->rq_session.lc_cookie = 0x5;
lu_context_enter(&request->rq_session);
- CDEBUG(D_NET, "got req "LPU64"\n", request->rq_xid);
+ CDEBUG(D_NET, "got req %llu\n", request->rq_xid);
request->rq_svc_thread = thread;
if (thread)
@@ -1932,19 +1931,19 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
/* Discard requests queued for longer than the deadline.
The deadline is increased if we send an early reply. */
- if (cfs_time_current_sec() > request->rq_deadline) {
+ if (get_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",
libcfs_id2str(request->rq_peer),
cfs_time_sub(request->rq_deadline,
request->rq_arrival_time.tv_sec),
- cfs_time_sub(cfs_time_current_sec(),
+ cfs_time_sub(get_seconds(),
request->rq_deadline));
goto put_conn;
}
CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc "
- "%s:%s+%d:%d:x"LPU64":%s:%d\n", current_comm(),
+ "%s:%s+%d:%d:x%llu:%s:%d\n", current_comm(),
(request->rq_export ?
(char *)request->rq_export->exp_client_uuid.uuid : "0"),
(request->rq_export ?
@@ -1964,22 +1963,22 @@ put_conn:
lu_context_exit(&request->rq_session);
lu_context_fini(&request->rq_session);
- if (unlikely(cfs_time_current_sec() > request->rq_deadline)) {
+ if (unlikely(get_seconds() > request->rq_deadline)) {
DEBUG_REQ(D_WARNING, request,
"Request took longer than estimated ("
CFS_DURATION_T":"CFS_DURATION_T
"s); client may timeout.",
cfs_time_sub(request->rq_deadline,
request->rq_arrival_time.tv_sec),
- cfs_time_sub(cfs_time_current_sec(),
+ cfs_time_sub(get_seconds(),
request->rq_deadline));
}
do_gettimeofday(&work_end);
timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc "
- "%s:%s+%d:%d:x"LPU64":%s:%d Request processed in "
- "%ldus (%ldus total) trans "LPU64" rc %d/%d\n",
+ "%s:%s+%d:%d:x%llu:%s:%d Request processed in "
+ "%ldus (%ldus total) trans %llu rc %d/%d\n",
current_comm(),
(request->rq_export ?
(char *)request->rq_export->exp_client_uuid.uuid : "0"),
@@ -2084,8 +2083,7 @@ ptlrpc_handle_rs(struct ptlrpc_reply_state *rs)
if (nlocks == 0 && !been_handled) {
/* If we see this, we should already have seen the warning
* in mds_steal_ack_locks() */
- CDEBUG(D_HA, "All locks stolen from rs %p x"LPD64".t"LPD64
- " o%d NID %s\n",
+ CDEBUG(D_HA, "All locks stolen from rs %p x%lld.t%lld o%d NID %s\n",
rs,
rs->rs_xid, rs->rs_transno, rs->rs_opc,
libcfs_nid2str(exp->exp_connection->c_peer.nid));
diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
index 3c8846006a7b..0624420135c2 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c
@@ -39,10 +39,10 @@
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
-#include <obd_support.h>
-#include <obd_class.h>
-#include <lustre_net.h>
-#include <lustre_disk.h>
+#include "../include/obd_support.h"
+#include "../include/obd_class.h"
+#include "../include/lustre_net.h"
+#include "../include/lustre_disk.h"
void lustre_assert_wire_constants(void)
{
/* Wire protocol assertions generated by 'wirecheck'
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index a9f2e63a7c9c..3323eb5e77b0 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -29,20 +29,10 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
source "drivers/staging/media/dt3155v4l/Kconfig"
-source "drivers/staging/media/go7007/Kconfig"
-
-source "drivers/staging/media/msi3101/Kconfig"
-
source "drivers/staging/media/omap24xx/Kconfig"
-source "drivers/staging/media/sn9c102/Kconfig"
-
-source "drivers/staging/media/solo6x10/Kconfig"
-
source "drivers/staging/media/omap4iss/Kconfig"
-source "drivers/staging/media/rtl2832u_sdr/Kconfig"
-
# Keep LIRC at the end, as it has sub-menus
source "drivers/staging/media/lirc/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 8e2c5d272162..7db83f373f63 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,14 +2,9 @@ obj-$(CONFIG_DVB_AS102) += as102/
obj-$(CONFIG_I2C_BCM2048) += bcm2048/
obj-$(CONFIG_DVB_CXD2099) += cxd2099/
obj-$(CONFIG_LIRC_STAGING) += lirc/
-obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
-obj-$(CONFIG_VIDEO_GO7007) += go7007/
-obj-$(CONFIG_USB_MSI3101) += msi3101/
obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
-obj-$(CONFIG_USB_SN9C102) += sn9c102/
obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/
obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/
-obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832u_sdr/
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
index bbf236e842a9..2bba370a47ca 100644
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -369,13 +369,12 @@ static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg,
data[0] = reg & 0xff;
data[1] = value & 0xff;
- if (i2c_master_send(client, data, 2) == 2) {
+ if (i2c_master_send(client, data, 2) == 2)
return 0;
- } else {
- dev_err(&bdev->client->dev, "BCM I2C error!\n");
- dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
- return -EIO;
- }
+
+ dev_err(&bdev->client->dev, "BCM I2C error!\n");
+ dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
+ return -EIO;
}
static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg,
@@ -725,8 +724,8 @@ static int bcm2048_get_fm_deemphasis(struct bcm2048_device *bdev)
if (!err) {
if (value & BCM2048_DE_EMPHASIS_SELECT)
return BCM2048_DE_EMPHASIS_75us;
- else
- return BCM2048_DE_EMPHASIS_50us;
+
+ return BCM2048_DE_EMPHASIS_50us;
}
return err;
@@ -1971,7 +1970,8 @@ static ssize_t bcm2048_##prop##_write(struct device *dev, \
if (!bdev) \
return -ENODEV; \
\
- sscanf(buf, mask, &value); \
+ if (sscanf(buf, mask, &value) != 1) \
+ return -EINVAL; \
\
if (check) \
return -EDOM; \
@@ -2242,6 +2242,7 @@ static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
i = 0;
while (i < count) {
unsigned char tmpbuf[3];
+
tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index+i+2];
tmpbuf[i+1] = bdev->rds_info.radio_text[bdev->rd_index+i+1];
tmpbuf[i+2] = ((bdev->rds_info.radio_text[bdev->rd_index+i]
@@ -2598,7 +2599,6 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client,
bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
if (!bdev) {
- dev_dbg(&client->dev, "Failed to alloc video device.\n");
err = -ENOMEM;
goto exit;
}
@@ -2618,7 +2618,7 @@ static int bcm2048_i2c_driver_probe(struct i2c_client *client,
if (client->irq) {
err = request_irq(client->irq,
- bcm2048_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+ bcm2048_handler, IRQF_TRIGGER_FALLING,
client->name, bdev);
if (err < 0) {
dev_err(&client->dev, "Could not request IRQ\n");
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index b7044a380fe3..bdc7f005b3ba 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1268,6 +1268,7 @@ static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
for (i = 0; i < ARRAY_SIZE(ipipe_modules); i++) {
unsigned int bit = 1 << i;
+
if (cfg->flag & bit) {
const struct ipipe_module_if *module_if =
&ipipe_modules[i];
@@ -1310,6 +1311,7 @@ static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
for (i = 1; i < ARRAY_SIZE(ipipe_modules); i++) {
unsigned int bit = 1 << i;
+
if (cfg->flag & bit) {
const struct ipipe_module_if *module_if =
&ipipe_modules[i];
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
index 010fdb247faf..81176fb9d164 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
@@ -479,7 +479,6 @@
#define RSZ_TYP_Y_SHIFT 0
#define RSZ_TYP_C_SHIFT 1
#define RSZ_LPF_INT_MASK 0x3f
-#define RSZ_LPF_INT_MASK 0x3f
#define RSZ_LPF_INT_C_SHIFT 6
#define RSZ_H_PHS_MASK 0x3fff
#define RSZ_H_DIF_MASK 0x3fff
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 59540cd4bb98..6d4893b44c1f 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -196,6 +196,7 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd)
int data_shift;
int pack_mode;
int source1;
+ int tmp;
ipipeif_base_addr = ipipeif->ipipeif_base_addr;
@@ -206,8 +207,8 @@ static int ipipeif_hw_setup(struct v4l2_subdev *sd)
outformat = &ipipeif->formats[IPIPEIF_PAD_SOURCE];
/* Combine all the fields to make CFG1 register of IPIPEIF */
- val = get_oneshot_mode(ipipeif->input);
- if (val < 0) {
+ tmp = val = get_oneshot_mode(ipipeif->input);
+ if (tmp < 0) {
pr_err("ipipeif: links setup required");
return -EINVAL;
}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 8e13bd494c98..8828d6c2aab1 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -219,7 +219,7 @@ configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index,
* @resizer: Pointer to VPFE resizer subdevice.
* @index: index RSZ_A-resizer-A RSZ_B-resizer-B.
*/
-void
+static void
resizer_calculate_resize_ratios(struct vpfe_resizer_device *resizer, int index)
{
struct resizer_params *param = &resizer->config;
@@ -310,7 +310,7 @@ resizer_calculate_sdram_offsets(struct vpfe_resizer_device *resizer, int index)
return 0;
}
-int resizer_configure_output_win(struct vpfe_resizer_device *resizer)
+static int resizer_configure_output_win(struct vpfe_resizer_device *resizer)
{
struct resizer_params *param = &resizer->config;
struct vpfe_rsz_output_spec output_specs;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index d95c427043d4..6f9171c39bdc 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -1606,7 +1606,6 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
if (ret < 0)
return ret;
- set_bit(V4L2_FL_USE_FH_PRIO, &video->video_dev.flags);
video_set_drvdata(&video->video_dev, video);
return 0;
diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README
deleted file mode 100644
index 3af0d9062811..000000000000
--- a/drivers/staging/media/go7007/README
+++ /dev/null
@@ -1,137 +0,0 @@
-Todo:
- - create an API for motion detection
- - let s2250-board use i2c subdevs as well instead of hardcoding
- support for the i2c devices.
- - when the driver is moved out of staging, support for saa7134-go7007
- should be added to the saa7134 driver. The patch for that is
- included below.
-
-Patch for saa7134:
-
-diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
-index dc68cf1..9a53794 100644
---- a/drivers/media/pci/saa7134/saa7134-cards.c
-+++ b/drivers/media/pci/saa7134/saa7134-cards.c
-@@ -5790,6 +5790,29 @@ struct saa7134_board saa7134_boards[] = {
- .gpio = 0x6010000,
- } },
- },
-+ [SAA7134_BOARD_WIS_VOYAGER] = {
-+ .name = "WIS Voyager or compatible",
-+ .audio_clock = 0x00200000,
-+ .tuner_type = TUNER_PHILIPS_TDA8290,
-+ .radio_type = UNSET,
-+ .tuner_addr = ADDR_UNSET,
-+ .radio_addr = ADDR_UNSET,
-+ .mpeg = SAA7134_MPEG_GO7007,
-+ .inputs = { {
-+ .name = name_comp1,
-+ .vmux = 0,
-+ .amux = LINE2,
-+ }, {
-+ .name = name_tv,
-+ .vmux = 3,
-+ .amux = TV,
-+ .tv = 1,
-+ }, {
-+ .name = name_svideo,
-+ .vmux = 6,
-+ .amux = LINE1,
-+ } },
-+ },
-
- };
-
-@@ -7037,6 +7060,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
- .subdevice = 0x0911,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
-+ .vendor = PCI_VENDOR_ID_PHILIPS,
-+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
-+ .subvendor = 0x1905, /* WIS */
-+ .subdevice = 0x7007,
-+ .driver_data = SAA7134_BOARD_WIS_VOYAGER,
-+ }, {
- /* --- boards without eeprom + subsystem ID --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
-diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
-index 8fd24e7..0a849ea 100644
---- a/drivers/media/pci/saa7134/saa7134-core.c
-+++ b/drivers/media/pci/saa7134/saa7134-core.c
-@@ -156,6 +156,8 @@ static void request_module_async(struct work_struct *work){
- request_module("saa7134-empress");
- if (card_is_dvb(dev))
- request_module("saa7134-dvb");
-+ if (card_is_go7007(dev))
-+ request_module("saa7134-go7007");
- if (alsa) {
- if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
- request_module("saa7134-alsa");
-@@ -557,8 +559,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
- saa7134_irq_vbi_done(dev,status);
-
- if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
-- card_has_mpeg(dev))
-- saa7134_irq_ts_done(dev,status);
-+ card_has_mpeg(dev)) {
-+ if (dev->mops->irq_ts_done != NULL)
-+ dev->mops->irq_ts_done(dev, status);
-+ else
-+ saa7134_irq_ts_done(dev, status);
-+ }
-
- if (report & SAA7134_IRQ_REPORT_GPIO16) {
- switch (dev->has_remote) {
-diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
-index 62169dd..5fad39a 100644
---- a/drivers/media/pci/saa7134/saa7134.h
-+++ b/drivers/media/pci/saa7134/saa7134.h
-@@ -334,6 +334,7 @@ struct saa7134_card_ir {
- #define SAA7134_BOARD_KWORLD_PC150U 189
- #define SAA7134_BOARD_ASUSTeK_PS3_100 190
- #define SAA7134_BOARD_HAWELL_HW_9004V1 191
-+#define SAA7134_BOARD_WIS_VOYAGER 192
-
- #define SAA7134_MAXBOARDS 32
- #define SAA7134_INPUT_MAX 8
-@@ -364,6 +365,7 @@ enum saa7134_mpeg_type {
- SAA7134_MPEG_UNUSED,
- SAA7134_MPEG_EMPRESS,
- SAA7134_MPEG_DVB,
-+ SAA7134_MPEG_GO7007,
- };
-
- enum saa7134_mpeg_ts_type {
-@@ -403,6 +405,7 @@ struct saa7134_board {
- #define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
- #define card_is_empress(dev) (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
- #define card_is_dvb(dev) (SAA7134_MPEG_DVB == saa7134_boards[dev->board].mpeg)
-+#define card_is_go7007(dev) (SAA7134_MPEG_GO7007 == saa7134_boards[dev->board].mpeg)
- #define card_has_mpeg(dev) (SAA7134_MPEG_UNUSED != saa7134_boards[dev->board].mpeg)
- #define card(dev) (saa7134_boards[dev->board])
- #define card_in(dev,n) (saa7134_boards[dev->board].inputs[n])
-@@ -535,6 +538,8 @@ struct saa7134_mpeg_ops {
- int (*init)(struct saa7134_dev *dev);
- int (*fini)(struct saa7134_dev *dev);
- void (*signal_change)(struct saa7134_dev *dev);
-+ void (*irq_ts_done)(struct saa7134_dev *dev,
-+ unsigned long status);
- };
-
- /* global device status */
-diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
-index 9c6ad4a..1b23689 100644
---- a/drivers/staging/media/go7007/Makefile
-+++ b/drivers/staging/media/go7007/Makefile
-@@ -8,8 +8,7 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
-
- s2250-y := s2250-board.o
-
--# Uncomment when the saa7134 patches get into upstream
--#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
--#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-+obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-+ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
-
- ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
deleted file mode 100644
index 54b989738982..000000000000
--- a/drivers/staging/media/go7007/go7007.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and the associated README documentation file (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.
- *
- * 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.
- */
-
-struct go7007_md_params {
- __u16 region;
- __u16 trigger;
- __u16 pixel_threshold;
- __u16 motion_threshold;
- __u32 reserved[8];
-};
-
-struct go7007_md_region {
- __u16 region;
- __u16 flags;
- struct v4l2_clip *clips;
- __u32 reserved[8];
-};
-
-#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
- struct go7007_md_params)
-#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
- struct go7007_md_params)
-#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
- struct go7007_md_region)
diff --git a/drivers/staging/media/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
deleted file mode 100644
index c8e5eb09d385..000000000000
--- a/drivers/staging/media/go7007/go7007.txt
+++ /dev/null
@@ -1,478 +0,0 @@
-This is a driver for the WIS GO7007SB multi-format video encoder.
-
-Pete Eberlein <pete@sensoray.com>
-
-The driver was originally released under the GPL and is currently hosted at:
-http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
-The go7007 firmware can be acquired from the package on the site above.
-
-I've modified the driver to support the following Video4Linux2 MPEG
-controls, with acceptable values:
-
-V4L2_CID_MPEG_STREAM_TYPE V4L2_MPEG_STREAM_TYPE_MPEG2_DVD
- V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
-V4L2_CID_MPEG_VIDEO_ENCODING V4L2_MPEG_VIDEO_ENCODING_MPEG_1
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4
-V4L2_CID_MPEG_VIDEO_ASPECT V4L2_MPEG_VIDEO_ASPECT_1x1
- V4L2_MPEG_VIDEO_ASPECT_4x3
- V4L2_MPEG_VIDEO_ASPECT_16x9
-V4L2_CID_MPEG_VIDEO_GOP_SIZE integer
-V4L2_CID_MPEG_VIDEO_BITRATE 64000 .. 10000000
-
-These should be used instead of the non-standard GO7007 ioctls described
-below.
-
-
-The README files from the orignal package appear below:
-
----------------------------------------------------------------------------
- WIS GO7007SB Public Linux Driver
----------------------------------------------------------------------------
-
-
-*** Please see the file RELEASE-NOTES for important last-minute updates ***
-
-
- 0. OVERVIEW AND LICENSING/DISCLAIMER
-
-
-This driver kit contains Linux drivers for the WIS GO7007SB multi-format
-video encoder. Only kernel version 2.6.x is supported. The video stream
-is available through the Video4Linux2 API and the audio stream is available
-through the ALSA API (or the OSS emulation layer of the ALSA system).
-
-The files in kernel/ and hotplug/ are licensed under the GNU General Public
-License Version 2 from the Free Software Foundation. A copy of the license
-is included in the file COPYING.
-
-The example applications in apps/ and C header files in include/ are
-licensed under a permissive license included in the source files which
-allows copying, modification and redistribution for any purpose without
-attribution.
-
-The firmware files included in the firmware/ directory may be freely
-redistributed only in conjunction with this document; but modification,
-tampering and reverse engineering are prohibited.
-
-MICRONAS USA, INC., MAKES NO WARRANTIES TO ANY PERSON OR ENTITY WITH
-RESPECT TO THE SOFTWARE OR ANY DERIVATIVES THEREOF OR ANY SERVICES OR
-LICENSES AND DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION
-WARRANTIES OF MERCHANTABILITY, SUPPORT, AND FITNESS FOR A PARTICULAR
-PURPOSE AND NON-INFRINGEMENT.
-
-
- 1. SYSTEM REQUIREMENTS
-
-
-This driver requires Linux kernel 2.6. Kernel 2.4 is not supported. Using
-kernel 2.6.10 or later is recommended, as earlier kernels are known to have
-unstable USB 2.0 support.
-
-A fully built kernel source tree must be available. Typically this will be
-linked from "/lib/modules/<KERNEL VERSION>/build" for convenience. If this
-link does not exist, an extra parameter will need to be passed to the
-`make` command.
-
-All vendor-built kernels should already be configured properly. However,
-for custom-built kernels, the following options need to be enabled in the
-kernel as built-in or modules:
-
- CONFIG_MODULES - Enable loadable module support
- CONFIG_FW_LOADER - Hotplug firmware loading support
- CONFIG_I2C - I2C support
- CONFIG_VIDEO_DEV - Video For Linux
- CONFIG_SOUND - Sound card support
- CONFIG_SND - Advanced Linux Sound Architecture
- CONFIG_USB - Support for Host-side USB
- CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
-
-Additionally, to use the example application, the following options need to
-be enabled in the ALSA section:
-
- CONFIG_SND_MIXER_OSS - OSS Mixer API
- CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
-
-The hotplug scripts, along with the fxload utility, must also be installed.
-These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
-Hotplugging is used for loading firmware into the Cypruss EZ-USB chip using
-fxload and for loading firmware into the driver using the firmware agent.
-
-
- 2. COMPILING AND INSTALLING THE DRIVER
-
-
-Most users should be able to compile the driver by simply running:
-
- $ make
-
-in the top-level directory of the driver kit. First the kernel modules
-will be built, followed by the example applications.
-
-If the build system is unable to locate the kernel source tree for the
-currently-running kernel, or if the module should be built for a kernel
-other than the currently-running kernel, an additional parameter will need
-to be passed to make to specify the appropriate kernel source directory:
-
- $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
-
-Once the compile completes, the driver and firmware files should be
-installed by running:
-
- $ make install
-
-The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
-and the firmware files will be placed in the appropriate hotplug firmware
-directory, usually /lib/firmware. In addition, USB maps and scripts will
-be placed in /etc/hotplug/usb to enable fxload to initialize the EZ-USB
-control chip when the device is connected.
-
-
- 3. PAL/SECAM TUNER CONFIGURATION (TV402U-EU only)
-
-
-The PAL model of the Plextor ConvertX TV402U may require additional
-configuration to correctly select the appropriate TV frequency band and
-audio subchannel.
-
-Users with a device other than the Plextor ConvertX TV402U-EU should skip
-this section.
-
-The wide variety of PAL TV systems used in Europe requires that additional
-information about the local TV standards be passed to the driver in order
-to properly tune TV channels. The two necessary parameters are (a) the PAL
-TV band, and (b) the audio subchannel format in use.
-
-In many cases, the appropriate TV band selection is passed to the driver
-from applications. However, in some cases, the application only specifies
-that the driver should use PAL but not the specific information about the
-appropriate TV band. To work around this issue, the correct TV band may be
-specified in the "force_band" parameter to the wis-sony-tuner module:
-
- TV band force_band
- ------- ----------
- PAL B/G B
- PAL I I
- PAL D/K D
- SECAM L L
-
-If the "force_band" parameter is specified, the driver will ignore any TV
-band specified by applications and will always use the band provided in the
-module parameter.
-
-The other parameter that can be specified is the audio subchannel format.
-There are several stereo audio carrier systems in use, including NICAM and
-three varieties of A2. To receive audio broadcast on one of these stereo
-carriers, the "force_mpx_mode" parameter must be specified to the
-wis-sony-tuner module.
-
- TV band Audio subcarrier force_mpx_mode
- ------- ---------------- --------------
- PAL B/G Mono (default) 1
- PAL B/G A2 2
- PAL B/G NICAM 3
- PAL I Mono (default) 4
- PAL I NICAM 5
- PAL D/K Mono (default) 6
- PAL D/K A2 (1) 7
- PAL D/K A2 (2) 8
- PAL D/K A2 (3) 9
- PAL D/K NICAM 10
- SECAM L Mono (default) 11
- SECAM L NICAM 12
-
-If the "force_mpx_mode" parameter is not specified, the correct mono-only
-mode will be chosen based on the TV band. However, the tuner will not
-receive stereo audio or bilingual broadcasts correctly.
-
-To pass the "force_band" or "force_mpx_mode" parameters to the
-wis-sony-tuner module, the following line must be added to the modprobe
-configuration file, which varies from one Linux distribution to another.
-
- options wis-sony-tuner force_band=B force_mpx_mode=2
-
-The above example would force the tuner to the PAL B/G TV band and receive
-stereo audio broadcasts on the A2 carrier.
-
-To verify that the configuration has been placed in the correct location,
-execute:
-
- $ modprobe -c | grep wis-sony-tuner
-
-If the configuration line appears, then modprobe will pass the parameters
-correctly the next time the wis-sony-tuner module is loaded into the
-kernel.
-
-
- 4. TESTING THE DRIVER
-
-
-Because few Linux applications are able to correctly capture from
-Video4Linux2 devices with only compressed formats supported, the new driver
-should be tested with the "gorecord" application in the apps/ directory.
-
-First connect a video source to the device, such as a DVD player or VCR.
-This will be captured to a file for testing the driver. If an input source
-is unavailable, a test file can still be captured, but the video will be
-black and the audio will be silent.
-
-This application will auto-detect the V4L2 and ALSA/OSS device names of the
-hardware and will record video and audio to an AVI file for a specified
-number of seconds. For example:
-
- $ apps/gorecord -duration 60 capture.avi
-
-If this application does not successfully record an AVI file, the error
-messages produced by gorecord and recorded in the system log (usually in
-/var/log/messages) should provide information to help resolve the problem.
-
-Supplying no parameters to gorecord will cause it to probe the available
-devices and exit. Use the -help flag for usage information.
-
-
- 5. USING THE DRIVER
-
-
-The V4L2 device implemented by the driver provides a standard compressed
-format API, within the following criteria:
-
- * Applications that only support the original Video4Linux1 API will not
- be able to communicate with this driver at all.
-
- * No raw video modes are supported, so applications like xawtv that
- expect only uncompressed video will not function.
-
- * Supported compression formats are: Motion-JPEG, MPEG1, MPEG2 and MPEG4.
-
- * MPEG video formats are delivered as Video Elementary Streams only.
- Program Stream (PS), Transport Stream (TS) and Packetized Elementary
- Stream (PES) formats are not supported.
-
- * Video parameters such as format and input port may not be changed while
- the encoder is active.
-
- * The audio capture device only functions when the video encoder is
- actively capturing video. Attempts to read from the audio device when
- the encoder is inactive will result in an I/O error.
-
- * The native format of the audio device is 48Khz 2-channel 16-bit
- little-endian PCM, delivered through the ALSA system. No audio
- compression is implemented in the hardware. ALSA may convert to other
- uncompressed formats on the fly.
-
-The include/ directory contains a C header file describing non-standard
-features of the GO7007SB encoder, which are described below:
-
-
- GO7007IOC_S_COMP_PARAMS, GO7007IOC_G_COMP_PARAMS
-
- These ioctls are used to negotiate general compression parameters.
-
- To query the current parameters, call the GO7007IOC_G_COMP_PARAMS ioctl
- with a pointer to a struct go7007_comp_params. If the driver is not
- set to MPEG format, the EINVAL error code will be returned.
-
- To change the current parameters, initialize all fields of a struct
- go7007_comp_params and call the GO7007_IOC_S_COMP_PARAMS ioctl with a
- pointer to this structure. The driver will return the current
- parameters with any necessary changes to conform to the limitations of
- the hardware or current compression mode. Any or all fields can be set
- to zero to request a reasonable default value. If the driver is not
- set to MPEG format, the EINVAL error code will be returned. When I/O
- is in progress, the EBUSY error code will be returned.
-
- Fields in struct go7007_comp_params:
-
- __u32 The maximum number of frames in each
- gop_size Group Of Pictures; i.e. the maximum
- number of frames minus one between
- each key frame.
-
- __u32 The maximum number of sequential
- max_b_frames bidirectionally-predicted frames.
- (B-frames are not yet supported.)
-
- enum go7007_aspect_ratio The aspect ratio to be encoded in the
- aspect_ratio meta-data of the compressed format.
-
- Choices are:
- GO7007_ASPECT_RATIO_1_1
- GO7007_ASPECT_RATIO_4_3_NTSC
- GO7007_ASPECT_RATIO_4_3_PAL
- GO7007_ASPECT_RATIO_16_9_NTSC
- GO7007_ASPECT_RATIO_16_9_PAL
-
- __u32 Bit-wise OR of control flags (below)
- flags
-
- Flags in struct go7007_comp_params:
-
- GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
- to produce streams appropriate for
- random seeking.
-
- GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
-
-
- GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
-
- These ioctls are used to negotiate MPEG-specific stream parameters when
- the pixelformat has been set to V4L2_PIX_FMT_MPEG.
-
- To query the current parameters, call the GO7007IOC_G_MPEG_PARAMS ioctl
- with a pointer to a struct go7007_mpeg_params. If the driver is not
- set to MPEG format, the EINVAL error code will be returned.
-
- To change the current parameters, initialize all fields of a struct
- go7007_mpeg_params and call the GO7007_IOC_S_MPEG_PARAMS ioctl with a
- pointer to this structure. The driver will return the current
- parameters with any necessary changes to conform to the limitations of
- the hardware or selected MPEG mode. Any or all fields can be set to
- zero to request a reasonable default value. If the driver is not set
- to MPEG format, the EINVAL error code will be returned. When I/O is in
- progress, the EBUSY error code will be returned.
-
- Fields in struct go7007_mpeg_params:
-
- enum go7007_mpeg_video_standard
- mpeg_video_standard The MPEG video standard in which to
- compress the video.
-
- Choices are:
- GO7007_MPEG_VIDEO_MPEG1
- GO7007_MPEG_VIDEO_MPEG2
- GO7007_MPEG_VIDEO_MPEG4
-
- __u32 Bit-wise OR of control flags (below)
- flags
-
- __u32 The profile and level indication to be
- pali stored in the sequence header. This
- is only used as an indicator to the
- decoder, and does not affect the MPEG
- features used in the video stream.
- Not valid for MPEG1.
-
- Choices for MPEG2 are:
- GO7007_MPEG2_PROFILE_MAIN_MAIN
-
- Choices for MPEG4 are:
- GO7007_MPEG4_PROFILE_S_L0
- GO7007_MPEG4_PROFILE_S_L1
- GO7007_MPEG4_PROFILE_S_L2
- GO7007_MPEG4_PROFILE_S_L3
- GO7007_MPEG4_PROFILE_ARTS_L1
- GO7007_MPEG4_PROFILE_ARTS_L2
- GO7007_MPEG4_PROFILE_ARTS_L3
- GO7007_MPEG4_PROFILE_ARTS_L4
- GO7007_MPEG4_PROFILE_AS_L0
- GO7007_MPEG4_PROFILE_AS_L1
- GO7007_MPEG4_PROFILE_AS_L2
- GO7007_MPEG4_PROFILE_AS_L3
- GO7007_MPEG4_PROFILE_AS_L4
- GO7007_MPEG4_PROFILE_AS_L5
-
- Flags in struct go7007_mpeg_params:
-
- GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
- bitrate control settings to comply
- with DVD MPEG2 stream requirements.
- This overrides most compression and
- bitrate settings!
-
- GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
-
- GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
- the start of each GOP.
-
-
- GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
-
- These ioctls are used to set and query the target bitrate value for the
- compressed video stream. The bitrate may be selected by storing the
- target bits per second in an int and calling GO7007IOC_S_BITRATE with a
- pointer to the int. The bitrate may be queried by calling
- GO7007IOC_G_BITRATE with a pointer to an int where the current bitrate
- will be stored.
-
- Note that this is the primary means of controlling the video quality
- for all compression modes, including V4L2_PIX_FMT_MJPEG. The
- VIDIOC_S_JPEGCOMP ioctl is not supported.
-
-
-----------------------------------------------------------------------------
- Installing the WIS PCI Voyager Driver
----------------------------------------------------------------------------
-
-The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
-kernel source tree before compiling the driver. These patches update the
-in-kernel SAA7134 driver to the newest development version and patch bugs
-in the TDA8290/TDA8275 tuner driver.
-
-The following patches must be downloaded from Gerd Knorr's website and
-applied in the order listed:
-
- http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner
- http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner2
- http://dl.bytesex.org/patches/2.6.11-2/v4l2-api-mpeg
- http://dl.bytesex.org/patches/2.6.11-2/saa7134-update
-
-The following patches are included with this SDK and can be applied in any
-order:
-
- patches/2.6.11/saa7134-voyager.diff
- patches/2.6.11/tda8275-newaddr.diff
- patches/2.6.11/tda8290-ntsc.diff
-
-Check to make sure the CONFIG_VIDEO_SAA7134 option is enabled in the kernel
-configuration, and build and install the kernel.
-
-After rebooting into the new kernel, the GO7007 driver can be compiled and
-installed:
-
- $ make SAA7134_BUILD=y
- $ make install
- $ modprobe saa7134-go7007
-
-There will be two V4L video devices associated with the PCI Voyager. The
-first device (most likely /dev/video0) provides access to the raw video
-capture mode of the SAA7133 device and is used to configure the source
-video parameters and tune the TV tuner. This device can be used with xawtv
-or other V4L(2) video software as a standard uncompressed device.
-
-The second device (most likely /dev/video1) provides access to the
-compression functions of the GO7007. It can be tested using the gorecord
-application in the apps/ directory of this SDK:
-
- $ apps/gorecord -vdevice /dev/video1 -noaudio test.avi
-
-Currently the frame resolution is fixed at 720x480 (NTSC) or 720x576 (PAL),
-and the video standard must be specified to both the raw and the compressed
-video devices (xawtv and gorecord, for example).
-
-
---------------------------------------------------------------------------
-RELEASE NOTES FOR WIS GO7007SB LINUX DRIVER
----------------------------------------------------------------------------
-
-Last updated: 5 November 2005
-
- - Release 0.9.7 includes new support for using udev to run fxload. The
- install script should automatically detect whether the old hotplug
- scripts or the new udev rules should be used. To force the use of
- hotplug, run "make install USE_UDEV=n". To force the use of udev, run
- "make install USE_UDEV=y".
-
- - Motion detection is supported but undocumented. Try the `modet` app
- for a demonstration of how to use the facility.
-
- - Using USB2.0 devices such as the TV402U with USB1.1 HCDs or hubs can
- cause buffer overruns and frame drops, even at low framerates, due to
- inconsistency in the bitrate control mechanism.
-
- - On devices with an SAA7115, including the Plextor ConvertX, video height
- values of 96, 128, 160, 192, 256, 320, and 384 do not work in NTSC mode.
- All valid heights up to 512 work correctly in PAL mode.
-
- - The WIS Star Trek and PCI Voyager boards have no support yet for audio
- or the TV tuner.
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
deleted file mode 100644
index e40f7fbfc0a5..000000000000
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * 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, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <asm/byteorder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-
-#include "saa7134.h"
-#include "saa7134-reg.h"
-#include "go7007.h"
-#include "go7007-priv.h"
-
-/*#define GO7007_HPI_DEBUG*/
-
-enum hpi_address {
- HPI_ADDR_VIDEO_BUFFER = 0xe4,
- HPI_ADDR_INIT_BUFFER = 0xea,
- HPI_ADDR_INTR_RET_VALUE = 0xee,
- HPI_ADDR_INTR_RET_DATA = 0xec,
- HPI_ADDR_INTR_STATUS = 0xf4,
- HPI_ADDR_INTR_WR_PARAM = 0xf6,
- HPI_ADDR_INTR_WR_INDEX = 0xf8,
-};
-
-enum gpio_command {
- GPIO_COMMAND_RESET = 0x00, /* 000b */
- GPIO_COMMAND_REQ1 = 0x04, /* 001b */
- GPIO_COMMAND_WRITE = 0x20, /* 010b */
- GPIO_COMMAND_REQ2 = 0x24, /* 011b */
- GPIO_COMMAND_READ = 0x80, /* 100b */
- GPIO_COMMAND_VIDEO = 0x84, /* 101b */
- GPIO_COMMAND_IDLE = 0xA0, /* 110b */
- GPIO_COMMAND_ADDR = 0xA4, /* 111b */
-};
-
-struct saa7134_go7007 {
- struct v4l2_subdev sd;
- struct saa7134_dev *dev;
- u8 *top;
- u8 *bottom;
- dma_addr_t top_dma;
- dma_addr_t bottom_dma;
-};
-
-static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct saa7134_go7007, sd);
-}
-
-static const struct go7007_board_info board_voyager = {
- .flags = 0,
- .sensor_flags = GO7007_SENSOR_656 |
- GO7007_SENSOR_VALID_ENABLE |
- GO7007_SENSOR_TV |
- GO7007_SENSOR_VBI,
- .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
- GO7007_AUDIO_WORD_16,
- .audio_rate = 48000,
- .audio_bclk_div = 8,
- .audio_main_div = 2,
- .hpi_buffer_cap = 7,
- .num_inputs = 1,
- .inputs = {
- {
- .name = "SAA7134",
- },
- },
-};
-
-/********************* Driver for GPIO HPI interface *********************/
-
-static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
-{
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- /* Write HPI address */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Write low byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Write high byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- return 0;
-}
-
-static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
-{
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- /* Write HPI address */
- saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
- /* Read low byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- /* Read high byte */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
- return 0;
-}
-
-static int saa7134_go7007_interface_reset(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- u32 status;
- u16 intr_val, intr_data;
- int count = 20;
-
- saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
- saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
- msleep(1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
- msleep(10);
-
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
- status = saa_readb(SAA7134_GPIO_GPSTATUS2);
- /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
-
- /* enter command mode...(?) */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
-
- do {
- saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
- status = saa_readb(SAA7134_GPIO_GPSTATUS2);
- /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
- } while (--count > 0);
-
- /* Wait for an interrupt to indicate successful hardware reset */
- if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
- (intr_val & ~0x1) != 0x55aa) {
- printk(KERN_ERR
- "saa7134-go7007: unable to reset the GO7007\n");
- return -1;
- }
- return 0;
-}
-
-static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- int i;
- u16 status_reg;
-
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG
- "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
-
- for (i = 0; i < 100; ++i) {
- gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
- if (!(status_reg & 0x0010))
- break;
- msleep(10);
- }
- if (i == 100) {
- printk(KERN_ERR
- "saa7134-go7007: device is hung, status reg = 0x%04x\n",
- status_reg);
- return -1;
- }
- gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
- gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
-
- return 0;
-}
-
-static int saa7134_go7007_read_interrupt(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
-
- /* XXX we need to wait if there is no interrupt available */
- go->interrupt_available = 1;
- gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
- gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
- go->interrupt_value, go->interrupt_data);
-#endif
- return 0;
-}
-
-static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
- unsigned long status)
-{
- struct go7007 *go = video_get_drvdata(dev->empress_dev);
- struct saa7134_go7007 *saa = go->hpi_context;
-
- if (!vb2_is_streaming(&go->vidq))
- return;
- if (0 != (status & 0x000f0000))
- printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
- (status >> 16) & 0x0f);
- if (status & 0x100000) {
- dma_sync_single_for_cpu(&dev->pci->dev,
- saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
- go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
- saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
- } else {
- dma_sync_single_for_cpu(&dev->pci->dev,
- saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
- go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
- saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
- }
-}
-
-static int saa7134_go7007_stream_start(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
-
- saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
- 0, PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&dev->pci->dev, saa->top_dma))
- return -ENOMEM;
- saa->bottom_dma = dma_map_page(&dev->pci->dev,
- virt_to_page(saa->bottom),
- 0, PAGE_SIZE, DMA_FROM_DEVICE);
- if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) {
- dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
- return -ENOMEM;
- }
-
- saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
- saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
-
- /* Set HPI interface for video */
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
- /* Enable TS interface */
- saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
-
- /* Reset TS interface */
- saa_setb(SAA7134_TS_SERIAL1, 0x01);
- saa_clearb(SAA7134_TS_SERIAL1, 0x01);
-
- /* Set up transfer block size */
- saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
- saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
- saa_writeb(SAA7134_TS_DMA1, 0);
- saa_writeb(SAA7134_TS_DMA2, 0);
-
- /* Enable video streaming mode */
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
-
- saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
- saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
- saa_writel(SAA7134_RS_PITCH(5), 128);
- saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
-
- /* Enable TS FIFO */
- saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
-
- /* Enable DMA IRQ */
- saa_setl(SAA7134_IRQ1,
- SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
- return 0;
-}
-
-static int saa7134_go7007_stream_stop(struct go7007 *go)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev;
-
- if (!saa)
- return -EINVAL;
- dev = saa->dev;
- if (!dev)
- return -EINVAL;
-
- /* Shut down TS FIFO */
- saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
-
- /* Disable DMA IRQ */
- saa_clearl(SAA7134_IRQ1,
- SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
- /* Disable TS interface */
- saa_clearb(SAA7134_TS_PARALLEL, 0x80);
-
- dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
- dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
- DMA_FROM_DEVICE);
-
- return 0;
-}
-
-static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
-{
- struct saa7134_go7007 *saa = go->hpi_context;
- struct saa7134_dev *dev = saa->dev;
- u16 status_reg;
- int i;
-
-#ifdef GO7007_HPI_DEBUG
- printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
- "sending %d bytes\n", len);
-#endif
-
- while (len > 0) {
- i = len > 64 ? 64 : len;
- saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
- saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
- while (i-- > 0) {
- saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
- saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
- ++data;
- --len;
- }
- for (i = 0; i < 100; ++i) {
- gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
- if (!(status_reg & 0x0002))
- break;
- }
- if (i == 100) {
- printk(KERN_ERR "saa7134-go7007: device is hung, "
- "status reg = 0x%04x\n", status_reg);
- return -1;
- }
- }
- return 0;
-}
-
-static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
- .interface_reset = saa7134_go7007_interface_reset,
- .write_interrupt = saa7134_go7007_write_interrupt,
- .read_interrupt = saa7134_go7007_read_interrupt,
- .stream_start = saa7134_go7007_stream_start,
- .stream_stop = saa7134_go7007_stream_stop,
- .send_firmware = saa7134_go7007_send_firmware,
-};
-MODULE_FIRMWARE("go7007/go7007tv.bin");
-
-/* --------------------------------------------------------------------------*/
-
-static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
-
- return saa7134_s_std_internal(dev, NULL, norm);
-}
-
-static int saa7134_go7007_queryctrl(struct v4l2_subdev *sd,
- struct v4l2_queryctrl *query)
-{
- return saa7134_queryctrl(NULL, NULL, query);
-}
-static int saa7134_go7007_s_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
- return saa7134_s_ctrl_internal(dev, NULL, ctrl);
-}
-
-static int saa7134_go7007_g_ctrl(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct saa7134_go7007 *saa = to_state(sd);
- struct saa7134_dev *dev = saa->dev;
- return saa7134_g_ctrl_internal(dev, NULL, ctrl);
-}
-
-/* --------------------------------------------------------------------------*/
-
-static const struct v4l2_subdev_core_ops saa7134_go7007_core_ops = {
- .g_ctrl = saa7134_go7007_g_ctrl,
- .s_ctrl = saa7134_go7007_s_ctrl,
- .queryctrl = saa7134_go7007_queryctrl,
-};
-
-static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = {
- .s_std = saa7134_go7007_s_std,
-};
-
-static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
- .core = &saa7134_go7007_core_ops,
- .video = &saa7134_go7007_video_ops,
-};
-
-/* --------------------------------------------------------------------------*/
-
-
-/********************* Add/remove functions *********************/
-
-static int saa7134_go7007_init(struct saa7134_dev *dev)
-{
- struct go7007 *go;
- struct saa7134_go7007 *saa;
- struct v4l2_subdev *sd;
-
- printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
-
- go = go7007_alloc(&board_voyager, &dev->pci->dev);
- if (go == NULL)
- return -ENOMEM;
-
- saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
- if (saa == NULL) {
- kfree(go);
- return -ENOMEM;
- }
-
- go->board_id = GO7007_BOARDID_PCI_VOYAGER;
- snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
- strlcpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
- go->hpi_ops = &saa7134_go7007_hpi_ops;
- go->hpi_context = saa;
- saa->dev = dev;
-
- /* Init the subdevice interface */
- sd = &saa->sd;
- v4l2_subdev_init(sd, &saa7134_go7007_sd_ops);
- v4l2_set_subdevdata(sd, saa);
- strncpy(sd->name, "saa7134-go7007", sizeof(sd->name));
-
- /* Allocate a couple pages for receiving the compressed stream */
- saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
- if (!saa->top)
- goto allocfail;
- saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
- if (!saa->bottom)
- goto allocfail;
-
- /* Boot the GO7007 */
- if (go7007_boot_encoder(go, go->board_info->flags &
- GO7007_BOARD_USE_ONBOARD_I2C) < 0)
- goto allocfail;
-
- /* Do any final GO7007 initialization, then register the
- * V4L2 and ALSA interfaces */
- if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
- goto allocfail;
-
- /* Register the subdevice interface with the go7007 device */
- if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
- printk(KERN_INFO "saa7134-go7007: register subdev failed\n");
-
- dev->empress_dev = &go->vdev;
-
- go->status = STATUS_ONLINE;
- return 0;
-
-allocfail:
- if (saa->top)
- free_page((unsigned long)saa->top);
- if (saa->bottom)
- free_page((unsigned long)saa->bottom);
- kfree(saa);
- kfree(go);
- return -ENOMEM;
-}
-
-static int saa7134_go7007_fini(struct saa7134_dev *dev)
-{
- struct go7007 *go;
- struct saa7134_go7007 *saa;
-
- if (NULL == dev->empress_dev)
- return 0;
-
- go = video_get_drvdata(dev->empress_dev);
- if (go->audio_enabled)
- go7007_snd_remove(go);
-
- saa = go->hpi_context;
- go->status = STATUS_SHUTDOWN;
- free_page((unsigned long)saa->top);
- free_page((unsigned long)saa->bottom);
- v4l2_device_unregister_subdev(&saa->sd);
- kfree(saa);
- video_unregister_device(&go->vdev);
-
- v4l2_device_put(&go->v4l2_dev);
- dev->empress_dev = NULL;
-
- return 0;
-}
-
-static struct saa7134_mpeg_ops saa7134_go7007_ops = {
- .type = SAA7134_MPEG_GO7007,
- .init = saa7134_go7007_init,
- .fini = saa7134_go7007_fini,
- .irq_ts_done = saa7134_go7007_irq_ts_done,
-};
-
-static int __init saa7134_go7007_mod_init(void)
-{
- return saa7134_ts_register(&saa7134_go7007_ops);
-}
-
-static void __exit saa7134_go7007_mod_cleanup(void)
-{
- saa7134_ts_unregister(&saa7134_go7007_ops);
-}
-
-module_init(saa7134_go7007_mod_init);
-module_exit(saa7134_go7007_mod_cleanup);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 44b0d0766084..431d1e86ebf9 100644
--- a/drivers/staging/media/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
@@ -209,12 +209,6 @@ static int unregister_from_lirc(struct igorplug *ir)
struct lirc_driver *d;
int devnum;
- if (!ir) {
- dev_err(&ir->usbdev->dev,
- "%s: called with NULL device struct!\n", __func__);
- return -EINVAL;
- }
-
devnum = ir->devnum;
d = ir->d;
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index a5b62eec5e21..96c76b33770b 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -189,6 +189,7 @@ MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
static void free_imon_context(struct imon_context *context)
{
struct device *dev = context->driver->dev;
+
usb_free_urb(context->tx_urb);
usb_free_urb(context->rx_urb);
lirc_buffer_free(context->driver->rbuf);
@@ -481,8 +482,6 @@ static void usb_tx_callback(struct urb *urb)
/* notify waiters that write has finished */
atomic_set(&context->tx.busy, 0);
complete(&context->tx.finished);
-
- return;
}
/**
@@ -547,7 +546,6 @@ static void ir_close(void *data)
}
mutex_unlock(&context->ctx_lock);
- return;
}
/**
@@ -572,7 +570,6 @@ static void submit_data(struct imon_context *context)
lirc_buffer_write(context->driver->rbuf, buf);
wake_up(&context->driver->rbuf->wait_poll);
- return;
}
static inline int tv2int(const struct timeval *a, const struct timeval *b)
@@ -656,6 +653,7 @@ static void imon_incoming_packet(struct imon_context *context,
mask = 0x80;
for (bit = 0; bit < 8; ++bit) {
int curr_bit = !(buf[octet] & mask);
+
if (curr_bit != context->rx.prev_bit) {
if (context->rx.count) {
submit_data(context);
@@ -707,8 +705,6 @@ static void usb_rx_callback(struct urb *urb)
}
usb_submit_urb(context->rx_urb, GFP_ATOMIC);
-
- return;
}
/**
@@ -775,6 +771,7 @@ static int imon_probe(struct usb_interface *interface,
struct usb_endpoint_descriptor *ep;
int ep_dir;
int ep_type;
+
ep = &iface_desc->endpoint[i].desc;
ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 1394f020e46b..672858a089f3 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -169,23 +169,22 @@ static unsigned int init_lirc_timer(void)
newtimer = (1000000*count)/timeelapsed;
pr_info("%u Hz timer detected\n", newtimer);
return newtimer;
- } else {
- newtimer = (1000000*count)/timeelapsed;
- if (abs(newtimer - default_timer) > default_timer/10) {
- /* bad timer */
- pr_notice("bad timer: %u Hz\n", newtimer);
- pr_notice("using default timer: %u Hz\n",
- default_timer);
- return default_timer;
- } else {
- pr_info("%u Hz timer detected\n", newtimer);
- return newtimer; /* use detected value */
- }
}
- } else {
- pr_notice("no timer detected\n");
- return 0;
+ newtimer = (1000000*count)/timeelapsed;
+ if (abs(newtimer - default_timer) > default_timer/10) {
+ /* bad timer */
+ pr_notice("bad timer: %u Hz\n", newtimer);
+ pr_notice("using default timer: %u Hz\n",
+ default_timer);
+ return default_timer;
+ } else {
+ pr_info("%u Hz timer detected\n", newtimer);
+ return newtimer; /* use detected value */
+ }
}
+
+ pr_notice("no timer detected\n");
+ return 0;
}
static int lirc_claim(void)
@@ -661,7 +660,8 @@ static int __init lirc_parallel_init(void)
goto exit_device_put;
}
ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
- pf, kf, lirc_lirc_irq_handler, 0, NULL);
+ pf, kf, lirc_lirc_irq_handler, 0,
+ NULL);
parport_put_port(pport);
if (ppdevice == NULL) {
pr_notice("parport_register_device() failed\n");
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index efe561cd0935..bae0d467093e 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -782,7 +782,7 @@ static int lirc_serial_probe(struct platform_device *dev)
{
int i, nlow, nhigh, result;
- result = request_irq(irq, lirc_irq_handler,
+ result = devm_request_irq(&dev->dev, irq, lirc_irq_handler,
(share_irq ? IRQF_SHARED : 0),
LIRC_DRIVER_NAME, (void *)&hardware);
if (result < 0) {
@@ -800,22 +800,22 @@ static int lirc_serial_probe(struct platform_device *dev)
* for the NSLU2 it's done in boot code.
*/
if (((iommap != 0)
- && (request_mem_region(iommap, 8 << ioshift,
- LIRC_DRIVER_NAME) == NULL))
+ && (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift,
+ LIRC_DRIVER_NAME) == NULL))
|| ((iommap == 0)
- && (request_region(io, 8, LIRC_DRIVER_NAME) == NULL))) {
+ && (devm_request_region(&dev->dev, io, 8,
+ LIRC_DRIVER_NAME) == NULL))) {
dev_err(&dev->dev, "port %04x already in use\n", io);
dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n");
dev_warn(&dev->dev,
"or compile the serial port driver as module and\n");
dev_warn(&dev->dev, "make sure this module is loaded first\n");
- result = -EBUSY;
- goto exit_free_irq;
+ return -EBUSY;
}
result = hardware_init_port();
if (result < 0)
- goto exit_release_region;
+ return result;
/* Initialize pulse/space widths */
init_timing_params(duty_cycle, freq);
@@ -847,28 +847,6 @@ static int lirc_serial_probe(struct platform_device *dev)
dprintk("Interrupt %d, port %04x obtained\n", irq, io);
return 0;
-
-exit_release_region:
- if (iommap != 0)
- release_mem_region(iommap, 8 << ioshift);
- else
- release_region(io, 8);
-exit_free_irq:
- free_irq(irq, (void *)&hardware);
-
- return result;
-}
-
-static int lirc_serial_remove(struct platform_device *dev)
-{
- free_irq(irq, (void *)&hardware);
-
- if (iommap != 0)
- release_mem_region(iommap, 8 << ioshift);
- else
- release_region(io, 8);
-
- return 0;
}
static int set_use_inc(void *data)
@@ -1081,7 +1059,6 @@ static int lirc_serial_resume(struct platform_device *dev)
static struct platform_driver lirc_serial_driver = {
.probe = lirc_serial_probe,
- .remove = lirc_serial_remove,
.suspend = lirc_serial_suspend,
.resume = lirc_serial_resume,
.driver = {
diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index e31cbb81f059..79da3adf1bd5 100644
--- a/drivers/staging/media/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
@@ -55,13 +55,6 @@
#include <asm/irq.h>
#include <linux/fcntl.h>
#include <linux/platform_device.h>
-#ifdef LIRC_ON_SA1100
-#include <asm/hardware.h>
-#ifdef CONFIG_SA1100_COLLIE
-#include <asm/arch/tc35143.h>
-#include <asm/ucb1200.h>
-#endif
-#endif
#include <linux/timer.h>
@@ -94,35 +87,6 @@ static void init_act200(void);
static void init_act220(void);
#endif
-/*** SA1100 ***/
-#ifdef LIRC_ON_SA1100
-struct sa1100_ser2_registers {
- /* HSSP control register */
- unsigned char hscr0;
- /* UART registers */
- unsigned char utcr0;
- unsigned char utcr1;
- unsigned char utcr2;
- unsigned char utcr3;
- unsigned char utcr4;
- unsigned char utdr;
- unsigned char utsr0;
- unsigned char utsr1;
-} sr;
-
-static int irq = IRQ_Ser2ICP;
-
-#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0
-
-/* pulse/space ratio of 50/50 */
-static unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
-/* 1000000/freq-pulse_width */
-static unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY);
-static unsigned int freq = 38000; /* modulation frequency */
-static unsigned int duty_cycle = 50; /* duty cycle of 50% */
-
-#endif
-
#define RBUF_LEN 1024
#define WBUF_LEN 1024
@@ -205,17 +169,6 @@ static void drop_hardware(void);
static int init_port(void);
static void drop_port(void);
-#ifdef LIRC_ON_SA1100
-static void on(void)
-{
- PPSR |= PPC_TXD2;
-}
-
-static void off(void)
-{
- PPSR &= ~PPC_TXD2;
-}
-#else
static inline unsigned int sinp(int offset)
{
return inb(io + offset);
@@ -225,7 +178,6 @@ static inline void soutp(int offset, int value)
{
outb(value, io + offset);
}
-#endif
#ifndef MAX_UDELAY_MS
#define MAX_UDELAY_US 5000
@@ -305,10 +257,6 @@ static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n,
if (IS_ERR(tx_buf))
return PTR_ERR(tx_buf);
i = 0;
-#ifdef LIRC_ON_SA1100
- /* disable receiver */
- Ser2UTCR3 = 0;
-#endif
local_irq_save(flags);
while (1) {
if (i >= count)
@@ -323,15 +271,6 @@ static ssize_t lirc_write(struct file *file, const char __user *buf, size_t n,
i++;
}
local_irq_restore(flags);
-#ifdef LIRC_ON_SA1100
- off();
- udelay(1000); /* wait 1ms for IR diode to recover */
- Ser2UTCR3 = 0;
- /* clear status register to prevent unwanted interrupts */
- Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
- /* enable receiver */
- Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE;
-#endif
kfree(tx_buf);
return count;
}
@@ -341,25 +280,12 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
u32 __user *uptr = (u32 __user *)arg;
int retval = 0;
u32 value = 0;
-#ifdef LIRC_ON_SA1100
-
- if (cmd == LIRC_GET_FEATURES)
- value = LIRC_CAN_SEND_PULSE |
- LIRC_CAN_SET_SEND_DUTY_CYCLE |
- LIRC_CAN_SET_SEND_CARRIER |
- LIRC_CAN_REC_MODE2;
- else if (cmd == LIRC_GET_SEND_MODE)
- value = LIRC_MODE_PULSE;
- else if (cmd == LIRC_GET_REC_MODE)
- value = LIRC_MODE_MODE2;
-#else
if (cmd == LIRC_GET_FEATURES)
value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2;
else if (cmd == LIRC_GET_SEND_MODE)
value = LIRC_MODE_PULSE;
else if (cmd == LIRC_GET_REC_MODE)
value = LIRC_MODE_MODE2;
-#endif
switch (cmd) {
case LIRC_GET_FEATURES:
@@ -372,37 +298,6 @@ static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
case LIRC_SET_REC_MODE:
retval = get_user(value, uptr);
break;
-#ifdef LIRC_ON_SA1100
- case LIRC_SET_SEND_DUTY_CYCLE:
- retval = get_user(value, uptr);
- if (retval)
- return retval;
- if (value <= 0 || value > 100)
- return -EINVAL;
- /* (value/100)*(1000000/freq) */
- duty_cycle = value;
- pulse_width = (unsigned long) duty_cycle*10000/freq;
- space_width = (unsigned long) 1000000L/freq-pulse_width;
- if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
- pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY;
- if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
- space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY;
- break;
- case LIRC_SET_SEND_CARRIER:
- retval = get_user(value, uptr);
- if (retval)
- return retval;
- if (value > 500000 || value < 20000)
- return -EINVAL;
- freq = value;
- pulse_width = (unsigned long) duty_cycle*10000/freq;
- space_width = (unsigned long) 1000000L/freq-pulse_width;
- if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
- pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY;
- if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY)
- space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY;
- break;
-#endif
default:
retval = -ENOIOCTLCMD;
@@ -539,10 +434,8 @@ static void sir_timeout(unsigned long data)
/* avoid interference with interrupt */
spin_lock_irqsave(&timer_lock, flags);
if (last_value) {
-#ifndef LIRC_ON_SA1100
/* clear unread bits in UART and restart */
outb(UART_FCR_CLEAR_RCVR, io + UART_FCR);
-#endif
/* determine 'virtual' pulse end: */
pulse_end = delta(&last_tv, &last_intr_tv);
dprintk("timeout add %d for %lu usec\n", last_value, pulse_end);
@@ -558,62 +451,6 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)
unsigned char data;
struct timeval curr_tv;
static unsigned long deltv;
-#ifdef LIRC_ON_SA1100
- int status;
- static int n;
-
- status = Ser2UTSR0;
- /*
- * Deal with any receive errors first. The bytes in error may be
- * the only bytes in the receive FIFO, so we do this first.
- */
- while (status & UTSR0_EIF) {
- int bstat;
-
- if (debug) {
- dprintk("EIF\n");
- bstat = Ser2UTSR1;
-
- if (bstat & UTSR1_FRE)
- dprintk("frame error\n");
- if (bstat & UTSR1_ROR)
- dprintk("receive fifo overrun\n");
- if (bstat & UTSR1_PRE)
- dprintk("parity error\n");
- }
-
- bstat = Ser2UTDR;
- n++;
- status = Ser2UTSR0;
- }
-
- if (status & (UTSR0_RFS | UTSR0_RID)) {
- do_gettimeofday(&curr_tv);
- deltv = delta(&last_tv, &curr_tv);
- do {
- data = Ser2UTDR;
- dprintk("%d data: %u\n", n, (unsigned int) data);
- n++;
- } while (status & UTSR0_RID && /* do not empty fifo in order to
- * get UTSR0_RID in any case */
- Ser2UTSR1 & UTSR1_RNE); /* data ready */
-
- if (status&UTSR0_RID) {
- add_read_queue(0 , deltv - n * TIME_CONST); /*space*/
- add_read_queue(1, n * TIME_CONST); /*pulse*/
- n = 0;
- last_tv = curr_tv;
- }
- }
-
- if (status & UTSR0_TFS)
- pr_err("transmit fifo not full, shouldn't happen\n");
-
- /* We must clear certain bits. */
- status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
- if (status)
- Ser2UTSR0 = status;
-#else
unsigned long deltintrtv;
unsigned long flags;
int iir, lsr;
@@ -698,44 +535,9 @@ static irqreturn_t sir_interrupt(int irq, void *dev_id)
break;
}
}
-#endif
return IRQ_RETVAL(IRQ_HANDLED);
}
-#ifdef LIRC_ON_SA1100
-static void send_pulse(unsigned long length)
-{
- unsigned long k, delay;
- int flag;
-
- if (length == 0)
- return;
- /*
- * this won't give us the carrier frequency we really want
- * due to integer arithmetic, but we can accept this inaccuracy
- */
-
- for (k = flag = 0; k < length; k += delay, flag = !flag) {
- if (flag) {
- off();
- delay = space_width;
- } else {
- on();
- delay = pulse_width;
- }
- safe_udelay(delay);
- }
- off();
-}
-
-static void send_space(unsigned long length)
-{
- if (length == 0)
- return;
- off();
- safe_udelay(length);
-}
-#else
static void send_space(unsigned long len)
{
safe_udelay(len);
@@ -755,31 +557,6 @@ static void send_pulse(unsigned long len)
;
}
}
-#endif
-
-#ifdef CONFIG_SA1100_COLLIE
-static int sa1100_irda_set_power_collie(int state)
-{
- if (state) {
- /*
- * 0 - off
- * 1 - short range, lowest power
- * 2 - medium range, medium power
- * 3 - maximum range, high power
- */
- ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
- TC35143_IODIR_OUTPUT);
- ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW);
- udelay(100);
- } else {
- /* OFF */
- ucb1200_set_io_direction(TC35143_GPIO_IR_ON,
- TC35143_IODIR_OUTPUT);
- ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH);
- }
- return 0;
-}
-#endif
static int init_hardware(void)
{
@@ -787,51 +564,7 @@ static int init_hardware(void)
spin_lock_irqsave(&hardware_lock, flags);
/* reset UART */
-#ifdef LIRC_ON_SA1100
-#ifdef CONFIG_SA1100_COLLIE
- sa1100_irda_set_power_collie(3); /* power on */
-#endif
- sr.hscr0 = Ser2HSCR0;
-
- sr.utcr0 = Ser2UTCR0;
- sr.utcr1 = Ser2UTCR1;
- sr.utcr2 = Ser2UTCR2;
- sr.utcr3 = Ser2UTCR3;
- sr.utcr4 = Ser2UTCR4;
-
- sr.utdr = Ser2UTDR;
- sr.utsr0 = Ser2UTSR0;
- sr.utsr1 = Ser2UTSR1;
-
- /* configure GPIO */
- /* output */
- PPDR |= PPC_TXD2;
- PSDR |= PPC_TXD2;
- /* set output to 0 */
- off();
-
- /* Enable HP-SIR modulation, and ensure that the port is disabled. */
- Ser2UTCR3 = 0;
- Ser2HSCR0 = sr.hscr0 & (~HSCR0_HSSP);
-
- /* clear status register to prevent unwanted interrupts */
- Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
-
- /* 7N1 */
- Ser2UTCR0 = UTCR0_1StpBit|UTCR0_7BitData;
- /* 115200 */
- Ser2UTCR1 = 0;
- Ser2UTCR2 = 1;
- /* use HPSIR, 1.6 usec pulses */
- Ser2UTCR4 = UTCR4_HPSIR|UTCR4_Z1_6us;
-
- /* enable receiver, receive fifo interrupt */
- Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE;
-
- /* clear status register to prevent unwanted interrupts */
- Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
-
-#elif defined(LIRC_SIR_TEKRAM)
+#if defined(LIRC_SIR_TEKRAM)
/* disable FIFO */
soutp(UART_FCR,
UART_FCR_CLEAR_RCVR|
@@ -927,23 +660,9 @@ static void drop_hardware(void)
spin_lock_irqsave(&hardware_lock, flags);
-#ifdef LIRC_ON_SA1100
- Ser2UTCR3 = 0;
-
- Ser2UTCR0 = sr.utcr0;
- Ser2UTCR1 = sr.utcr1;
- Ser2UTCR2 = sr.utcr2;
- Ser2UTCR4 = sr.utcr4;
- Ser2UTCR3 = sr.utcr3;
-
- Ser2HSCR0 = sr.hscr0;
-#ifdef CONFIG_SA1100_COLLIE
- sa1100_irda_set_power_collie(0); /* power off */
-#endif
-#else
/* turn off interrupts */
outb(0, io + UART_IER);
-#endif
+
spin_unlock_irqrestore(&hardware_lock, flags);
}
@@ -954,24 +673,18 @@ static int init_port(void)
int retval;
/* get I/O port access and IRQ line */
-#ifndef LIRC_ON_SA1100
if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) {
pr_err("i/o port 0x%.4x already in use.\n", io);
return -EBUSY;
}
-#endif
retval = request_irq(irq, sir_interrupt, 0,
LIRC_DRIVER_NAME, NULL);
if (retval < 0) {
-# ifndef LIRC_ON_SA1100
release_region(io, 8);
-# endif
pr_err("IRQ %d already in use.\n", irq);
return retval;
}
-#ifndef LIRC_ON_SA1100
pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq);
-#endif
init_timer(&timerlist);
timerlist.function = sir_timeout;
@@ -984,9 +697,7 @@ static void drop_port(void)
{
free_irq(irq, NULL);
del_timer_sync(&timerlist);
-#ifndef LIRC_ON_SA1100
release_region(io, 8);
-#endif
}
#ifdef LIRC_SIR_ACTISYS_ACT200L
@@ -1284,9 +995,6 @@ module_exit(lirc_sir_exit);
#ifdef LIRC_SIR_TEKRAM
MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210");
MODULE_AUTHOR("Christoph Bartelmus");
-#elif defined(LIRC_ON_SA1100)
-MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor");
-MODULE_AUTHOR("Christoph Bartelmus");
#elif defined(LIRC_SIR_ACTISYS_ACT200L)
MODULE_DESCRIPTION("LIRC driver for Actisys Act200L");
MODULE_AUTHOR("Karl Bongers");
@@ -1299,10 +1007,6 @@ MODULE_AUTHOR("Milan Pikula");
#endif
MODULE_LICENSE("GPL");
-#ifdef LIRC_ON_SA1100
-module_param(irq, int, S_IRUGO);
-MODULE_PARM_DESC(irq, "Interrupt (16)");
-#else
module_param(io, int, S_IRUGO);
MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)");
@@ -1311,7 +1015,6 @@ MODULE_PARM_DESC(irq, "Interrupt (4 or 3)");
module_param(threshold, int, S_IRUGO);
MODULE_PARM_DESC(threshold, "space detection threshold (3)");
-#endif
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/drivers/staging/media/msi3101/Kconfig b/drivers/staging/media/msi3101/Kconfig
deleted file mode 100644
index de0b3bba3873..000000000000
--- a/drivers/staging/media/msi3101/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config USB_MSI3101
- tristate "Mirics MSi3101 SDR Dongle"
- depends on USB && VIDEO_DEV && VIDEO_V4L2 && SPI
- select VIDEOBUF2_CORE
- select VIDEOBUF2_VMALLOC
- select MEDIA_TUNER_MSI001
-
-config MEDIA_TUNER_MSI001
- tristate "Mirics MSi001"
- depends on VIDEO_V4L2 && SPI
diff --git a/drivers/staging/media/msi3101/Makefile b/drivers/staging/media/msi3101/Makefile
deleted file mode 100644
index daf4f58d9a56..000000000000
--- a/drivers/staging/media/msi3101/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_USB_MSI3101) += sdr-msi3101.o
-obj-$(CONFIG_MEDIA_TUNER_MSI001) += msi001.o
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig
index 78b0fba7047e..8afc6fee40c5 100644
--- a/drivers/staging/media/omap4iss/Kconfig
+++ b/drivers/staging/media/omap4iss/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_OMAP4
bool "OMAP 4 Camera support"
- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && I2C && ARCH_OMAP4
+ depends on VIDEO_V4L2=y && VIDEO_V4L2_SUBDEV_API && I2C=y && ARCH_OMAP4
select VIDEOBUF2_DMA_CONTIG
---help---
Driver for an OMAP 4 ISS controller.
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 2e422dde074e..d548371db65a 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1003,33 +1003,18 @@ static void iss_disable_clocks(struct iss_device *iss)
clk_disable(iss->iss_fck);
}
-static void iss_put_clocks(struct iss_device *iss)
-{
- if (iss->iss_fck) {
- clk_put(iss->iss_fck);
- iss->iss_fck = NULL;
- }
-
- if (iss->iss_ctrlclk) {
- clk_put(iss->iss_ctrlclk);
- iss->iss_ctrlclk = NULL;
- }
-}
-
static int iss_get_clocks(struct iss_device *iss)
{
- iss->iss_fck = clk_get(iss->dev, "iss_fck");
+ iss->iss_fck = devm_clk_get(iss->dev, "iss_fck");
if (IS_ERR(iss->iss_fck)) {
dev_err(iss->dev, "Unable to get iss_fck clock info\n");
- iss_put_clocks(iss);
return PTR_ERR(iss->iss_fck);
}
- iss->iss_ctrlclk = clk_get(iss->dev, "iss_ctrlclk");
+ iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk");
if (IS_ERR(iss->iss_ctrlclk)) {
dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
- iss_put_clocks(iss);
- return PTR_ERR(iss->iss_fck);
+ return PTR_ERR(iss->iss_ctrlclk);
}
return 0;
@@ -1104,29 +1089,11 @@ static int iss_map_mem_resource(struct platform_device *pdev,
{
struct resource *mem;
- /* request the mem region for the camera registers */
-
mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
- if (!mem) {
- dev_err(iss->dev, "no mem resource?\n");
- return -ENODEV;
- }
- if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
- dev_err(iss->dev,
- "cannot reserve camera register I/O region\n");
- return -ENODEV;
- }
- iss->res[res] = mem;
+ iss->regs[res] = devm_ioremap_resource(iss->dev, mem);
- /* map the region */
- iss->regs[res] = ioremap_nocache(mem->start, resource_size(mem));
- if (!iss->regs[res]) {
- dev_err(iss->dev, "cannot map camera register I/O region\n");
- return -ENODEV;
- }
-
- return 0;
+ return PTR_ERR_OR_ZERO(iss->regs[res]);
}
static void iss_unregister_entities(struct iss_device *iss)
@@ -1389,7 +1356,7 @@ static int iss_probe(struct platform_device *pdev)
if (pdata == NULL)
return -EINVAL;
- iss = kzalloc(sizeof(*iss), GFP_KERNEL);
+ iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
if (!iss) {
dev_err(&pdev->dev, "Could not allocate memory\n");
return -ENOMEM;
@@ -1456,7 +1423,8 @@ static int iss_probe(struct platform_device *pdev)
goto error_iss;
}
- if (request_irq(iss->irq_num, iss_isr, IRQF_SHARED, "OMAP4 ISS", iss)) {
+ if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
+ "OMAP4 ISS", iss)) {
dev_err(iss->dev, "Unable to request IRQ\n");
ret = -EINVAL;
goto error_iss;
@@ -1465,7 +1433,7 @@ static int iss_probe(struct platform_device *pdev)
/* Entities */
ret = iss_initialize_modules(iss);
if (ret < 0)
- goto error_irq;
+ goto error_iss;
ret = iss_register_entities(iss);
if (ret < 0)
@@ -1477,29 +1445,12 @@ static int iss_probe(struct platform_device *pdev)
error_modules:
iss_cleanup_modules(iss);
-error_irq:
- free_irq(iss->irq_num, iss);
error_iss:
omap4iss_put(iss);
error:
- iss_put_clocks(iss);
-
- for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
- if (iss->regs[i]) {
- iounmap(iss->regs[i]);
- iss->regs[i] = NULL;
- }
-
- if (iss->res[i]) {
- release_mem_region(iss->res[i]->start,
- resource_size(iss->res[i]));
- iss->res[i] = NULL;
- }
- }
platform_set_drvdata(pdev, NULL);
mutex_destroy(&iss->iss_mutex);
- kfree(iss);
return ret;
}
@@ -1507,29 +1458,10 @@ error:
static int iss_remove(struct platform_device *pdev)
{
struct iss_device *iss = platform_get_drvdata(pdev);
- unsigned int i;
iss_unregister_entities(iss);
iss_cleanup_modules(iss);
- free_irq(iss->irq_num, iss);
- iss_put_clocks(iss);
-
- for (i = 0; i < OMAP4_ISS_MEM_LAST; i++) {
- if (iss->regs[i]) {
- iounmap(iss->regs[i]);
- iss->regs[i] = NULL;
- }
-
- if (iss->res[i]) {
- release_mem_region(iss->res[i]->start,
- resource_size(iss->res[i]));
- iss->res[i] = NULL;
- }
- }
-
- kfree(iss);
-
return 0;
}
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 05cd9bf3b41f..734cfeeb0314 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -97,7 +97,7 @@ struct iss_device {
u64 raw_dmamask;
struct mutex iss_mutex; /* For handling ref_count field */
- bool crashed;
+ unsigned int crashed;
int has_context;
int ref_count;
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index bf8a65726107..9ae4871928d8 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -317,7 +317,7 @@ static void csi2_ctx_enable(struct iss_csi2_device *csi2, u8 ctxnum, u8 enable)
static void csi2_ctx_config(struct iss_csi2_device *csi2,
struct iss_csi2_ctx_cfg *ctx)
{
- u32 reg;
+ u32 reg = 0;
/* Set up CSI2_CTx_CTRL1 */
if (ctx->eof_enabled)
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index cbf455d66f73..943b5b09c632 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -25,6 +25,9 @@
#include "iss_video.h"
#include "iss.h"
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
/* -----------------------------------------------------------------------------
* Helper functions
@@ -328,15 +331,6 @@ static int iss_video_buf_prepare(struct vb2_buffer *vb)
if (vb2_plane_size(vb, 0) < size)
return -ENOBUFS;
- /* Refuse to prepare the buffer is the video node has registered an
- * error. We don't need to take any lock here as the operation is
- * inherently racy. The authoritative check will be performed in the
- * queue handler, which can't return an error, this check is just a best
- * effort to notify userspace as early as possible.
- */
- if (unlikely(video->error))
- return -EIO;
-
addr = vb2_dma_contig_plane_dma_addr(vb, 0);
if (!IS_ALIGNED(addr, 32)) {
dev_dbg(video->iss->dev,
@@ -360,6 +354,11 @@ static void iss_video_buf_queue(struct vb2_buffer *vb)
spin_lock_irqsave(&video->qlock, flags);
+ /* Mark the buffer is faulty and give it back to the queue immediately
+ * if the video node has registered an error. vb2 will perform the same
+ * check when preparing the buffer, but that is inherently racy, so we
+ * need to handle the race condition with an authoritative check here.
+ */
if (unlikely(video->error)) {
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
spin_unlock_irqrestore(&video->qlock, flags);
@@ -510,6 +509,7 @@ void omap4iss_video_cancel_stream(struct iss_video *video)
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
}
+ vb2_queue_error(video->queue);
video->error = true;
spin_unlock_irqrestore(&video->qlock, flags);
@@ -895,7 +895,6 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
video->queue = &vfh->queue;
INIT_LIST_HEAD(&video->dmaqueue);
- spin_lock_init(&video->qlock);
video->error = false;
atomic_set(&pipe->frame_number, -1);
@@ -1044,6 +1043,8 @@ static int iss_video_open(struct file *file)
if (handle == NULL)
return -ENOMEM;
+ video->video.debug = debug;
+
v4l2_fh_init(&handle->vfh, &video->video);
v4l2_fh_add(&handle->vfh);
@@ -1175,6 +1176,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
if (ret < 0)
return ret;
+ spin_lock_init(&video->qlock);
mutex_init(&video->mutex);
atomic_set(&video->active, 0);
diff --git a/drivers/staging/media/rtl2832u_sdr/Kconfig b/drivers/staging/media/rtl2832u_sdr/Kconfig
deleted file mode 100644
index 3ede5fe8f0a5..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config DVB_RTL2832_SDR
- tristate "Realtek RTL2832 SDR"
- depends on USB && DVB_CORE && I2C && VIDEO_V4L2 && DVB_USB_RTL28XXU
- select DVB_RTL2832
- select VIDEOBUF2_VMALLOC
- default m if !MEDIA_SUBDRV_AUTOSELECT
-
diff --git a/drivers/staging/media/rtl2832u_sdr/Makefile b/drivers/staging/media/rtl2832u_sdr/Makefile
deleted file mode 100644
index 7e00a0df4631..000000000000
--- a/drivers/staging/media/rtl2832u_sdr/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/sn9c102/Kconfig b/drivers/staging/media/sn9c102/Kconfig
deleted file mode 100644
index c9aba59258d9..000000000000
--- a/drivers/staging/media/sn9c102/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config USB_SN9C102
- tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)"
- depends on VIDEO_V4L2 && MEDIA_USB_SUPPORT
- ---help---
- This driver is DEPRECATED, please use the gspca sonixb and
- sonixj modules instead.
-
- Say Y here if you want support for cameras based on SONiX SN9C101,
- SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
-
- See <file:drivers/staging/media/sn9c102/sn9c102.txt> for more info.
-
- If you have webcams that are only supported by this driver and not by
- the gspca driver, then contact the linux-media mailinglist.
-
- To compile this driver as a module, choose M here: the
- module will be called sn9c102.
diff --git a/drivers/staging/media/sn9c102/Makefile b/drivers/staging/media/sn9c102/Makefile
deleted file mode 100644
index 7ecd5a90c7c9..000000000000
--- a/drivers/staging/media/sn9c102/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-sn9c102-objs := sn9c102_core.o \
- sn9c102_hv7131d.o \
- sn9c102_hv7131r.o \
- sn9c102_mi0343.o \
- sn9c102_mi0360.o \
- sn9c102_mt9v111.o \
- sn9c102_ov7630.o \
- sn9c102_ov7660.o \
- sn9c102_pas106b.o \
- sn9c102_pas202bcb.o \
- sn9c102_tas5110c1b.o \
- sn9c102_tas5110d.o \
- sn9c102_tas5130d1b.o
-
-obj-$(CONFIG_USB_SN9C102) += sn9c102.o
diff --git a/drivers/staging/media/sn9c102/sn9c102.h b/drivers/staging/media/sn9c102/sn9c102.h
deleted file mode 100644
index 37ca7225fcf7..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2006 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_H_
-#define _SN9C102_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-device.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/param.h>
-#include <linux/rwsem.h>
-#include <linux/mutex.h>
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/kref.h>
-
-#include "sn9c102_config.h"
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-enum sn9c102_frame_state {
- F_UNUSED,
- F_QUEUED,
- F_GRABBING,
- F_DONE,
- F_ERROR,
-};
-
-struct sn9c102_frame_t {
- void *bufmem;
- struct v4l2_buffer buf;
- enum sn9c102_frame_state state;
- struct list_head frame;
- unsigned long vma_use_count;
-};
-
-enum sn9c102_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-enum sn9c102_io_method {
- IO_NONE,
- IO_READ,
- IO_MMAP,
-};
-
-enum sn9c102_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON,
-};
-
-typedef char sn9c102_sof_header_t[62];
-
-struct sn9c102_sof_t {
- sn9c102_sof_header_t header;
- u16 bytesread;
-};
-
-struct sn9c102_sysfs_attr {
- u16 reg, i2c_reg;
- sn9c102_sof_header_t frame_header;
-};
-
-struct sn9c102_module_param {
- u8 force_munmap;
- u16 frame_timeout;
-};
-
-static DEFINE_MUTEX(sn9c102_sysfs_lock);
-static DECLARE_RWSEM(sn9c102_dev_lock);
-
-struct sn9c102_device {
- struct video_device *v4ldev;
-
- struct v4l2_device v4l2_dev;
-
- enum sn9c102_bridge bridge;
- struct sn9c102_sensor sensor;
-
- struct usb_device *usbdev;
- struct urb *urb[SN9C102_URBS];
- void *transfer_buffer[SN9C102_URBS];
- u8 *control_buffer;
-
- struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES];
- struct list_head inqueue, outqueue;
- u32 frame_count, nbuffers, nreadbuffers;
-
- enum sn9c102_io_method io;
- enum sn9c102_stream_state stream;
-
- struct v4l2_jpegcompression compression;
-
- struct sn9c102_sysfs_attr sysfs;
- struct sn9c102_sof_t sof;
- u16 reg[384];
-
- struct sn9c102_module_param module_param;
-
- struct kref kref;
- enum sn9c102_dev_state state;
- u8 users;
-
- struct completion probe;
- struct mutex open_mutex, fileop_mutex;
- spinlock_t queue_lock;
- wait_queue_head_t wait_open, wait_frame, wait_stream;
-};
-
-/*****************************************************************************/
-
-struct sn9c102_device*
-sn9c102_match_id(struct sn9c102_device *cam, const struct usb_device_id *id)
-{
- return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
-}
-
-
-void
-sn9c102_attach_sensor(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
-}
-
-
-enum sn9c102_bridge
-sn9c102_get_bridge(struct sn9c102_device *cam)
-{
- return cam->bridge;
-}
-
-
-struct sn9c102_sensor *sn9c102_get_sensor(struct sn9c102_device *cam)
-{
- return &cam->sensor;
-}
-
-/*****************************************************************************/
-
-#undef DBG
-#undef KDBG
-#ifdef SN9C102_DEBUG
-# define DBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1) \
- dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) == 2) \
- dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) >= 3) \
- dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-# define V4LDBG(level, name, cmd) \
-do { \
- if (debug >= (level)) \
- v4l_printk_ioctl(name, cmd); \
-} while (0)
-# define KDBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1 || (level) == 2) \
- pr_info("sn9c102: " fmt "\n", ## args); \
- else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-#else
-# define DBG(level, fmt, args...) do { ; } while (0)
-# define V4LDBG(level, name, cmd) do { ; } while (0)
-# define KDBG(level, fmt, args...) do { ; } while (0)
-#endif
-
-#undef PDBG
-#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \
- __LINE__ , ## args)
-
-#undef PDBGG
-#define PDBGG(fmt, args...) do { ; } while (0) /* placeholder */
-
-#endif /* _SN9C102_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102.txt b/drivers/staging/media/sn9c102/sn9c102.txt
deleted file mode 100644
index b4f67040403a..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102.txt
+++ /dev/null
@@ -1,592 +0,0 @@
-
- SN9C1xx PC Camera Controllers
- Driver for Linux
- =============================
-
- - Documentation -
-
-
-Index
-=====
-1. Copyright
-2. Disclaimer
-3. License
-4. Overview and features
-5. Module dependencies
-6. Module loading
-7. Module parameters
-8. Optional device control through "sysfs"
-9. Supported devices
-10. Notes for V4L2 application developers
-11. Video frame formats
-12. Contact information
-13. Credits
-
-
-1. Copyright
-============
-Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
-
-
-2. Disclaimer
-=============
-SONiX is a trademark of SONiX Technology Company Limited, inc.
-This software is not sponsored or developed by SONiX.
-
-
-3. License
-==========
-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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-
-4. Overview and features
-========================
-This driver attempts to support the video interface of the devices assembling
-the SONiX SN9C101, SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers
-("SN9C1xx" from now on).
-
-The driver relies on the Video4Linux2 and USB core modules. It has been
-designed to run properly on SMP systems as well.
-
-The latest version of the SN9C1xx driver can be found at the following URL:
-http://www.linux-projects.org/
-
-Some of the features of the driver are:
-
-- full compliance with the Video4Linux2 API (see also "Notes for V4L2
- application developers" paragraph);
-- available mmap or read/poll methods for video streaming through isochronous
- data transfers;
-- automatic detection of image sensor;
-- support for built-in microphone interface;
-- support for any window resolutions and optional panning within the maximum
- pixel area of image sensor;
-- image downscaling with arbitrary scaling factors from 1, 2 and 4 in both
- directions (see "Notes for V4L2 application developers" paragraph);
-- two different video formats for uncompressed or compressed data in low or
- high compression quality (see also "Notes for V4L2 application developers"
- and "Video frame formats" paragraphs);
-- full support for the capabilities of many of the possible image sensors that
- can be connected to the SN9C1xx bridges, including, for instance, red, green,
- blue and global gain adjustments and exposure (see "Supported devices"
- paragraph for details);
-- use of default color settings for sunlight conditions;
-- dynamic I/O interface for both SN9C1xx and image sensor control and
- monitoring (see "Optional device control through 'sysfs'" paragraph);
-- dynamic driver control thanks to various module parameters (see "Module
- parameters" paragraph);
-- up to 64 cameras can be handled at the same time; they can be connected and
- disconnected from the host many times without turning off the computer, if
- the system supports hotplugging;
-- no known bugs.
-
-
-5. Module dependencies
-======================
-For it to work properly, the driver needs kernel support for Video4Linux and
-USB.
-
-The following options of the kernel configuration file must be enabled and
-corresponding modules must be compiled:
-
- # Multimedia devices
- #
- CONFIG_VIDEO_DEV=m
-
-To enable advanced debugging functionality on the device through /sysfs:
-
- # Multimedia devices
- #
- CONFIG_VIDEO_ADV_DEBUG=y
-
- # USB support
- #
- CONFIG_USB=m
-
-In addition, depending on the hardware being used, the modules below are
-necessary:
-
- # USB Host Controller Drivers
- #
- CONFIG_USB_EHCI_HCD=m
- CONFIG_USB_UHCI_HCD=m
- CONFIG_USB_OHCI_HCD=m
-
-The SN9C103, SN9c105 and SN9C120 controllers also provide a built-in microphone
-interface. It is supported by the USB Audio driver thanks to the ALSA API:
-
- # Sound
- #
- CONFIG_SOUND=y
-
- # Advanced Linux Sound Architecture
- #
- CONFIG_SND=m
-
- # USB devices
- #
- CONFIG_SND_USB_AUDIO=m
-
-And finally:
-
- # USB Multimedia devices
- #
- CONFIG_USB_SN9C102=m
-
-
-6. Module loading
-=================
-To use the driver, it is necessary to load the "sn9c102" module into memory
-after every other module required: "videodev", "v4l2_common", "compat_ioctl32",
-"usbcore" and, depending on the USB host controller you have, "ehci-hcd",
-"uhci-hcd" or "ohci-hcd".
-
-Loading can be done as shown below:
-
- [root@localhost home]# modprobe sn9c102
-
-Note that the module is called "sn9c102" for historic reasons, although it
-does not just support the SN9C102.
-
-At this point all the devices supported by the driver and connected to the USB
-ports should be recognized. You can invoke "dmesg" to analyze kernel messages
-and verify that the loading process has gone well:
-
- [user@localhost home]$ dmesg
-
-or, to isolate all the kernel messages generated by the driver:
-
- [user@localhost home]$ dmesg | grep sn9c102
-
-
-7. Module parameters
-====================
-Module parameters are listed below:
--------------------------------------------------------------------------------
-Name: video_nr
-Type: short array (min = 0, max = 64)
-Syntax: <-1|n[,...]>
-Description: Specify V4L2 minor mode number:
- -1 = use next available
- n = use minor number n
- You can specify up to 64 cameras this way.
- For example:
- video_nr=-1,2,-1 would assign minor number 2 to the second
- recognized camera and use auto for the first one and for every
- other camera.
-Default: -1
--------------------------------------------------------------------------------
-Name: force_munmap
-Type: bool array (min = 0, max = 64)
-Syntax: <0|1[,...]>
-Description: Force the application to unmap previously mapped buffer memory
- before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
- all the applications support this feature. This parameter is
- specific for each detected camera.
- 0 = do not force memory unmapping
- 1 = force memory unmapping (save memory)
-Default: 0
--------------------------------------------------------------------------------
-Name: frame_timeout
-Type: uint array (min = 0, max = 64)
-Syntax: <0|n[,...]>
-Description: Timeout for a video frame in seconds before returning an I/O
- error; 0 for infinity. This parameter is specific for each
- detected camera and can be changed at runtime thanks to the
- /sys filesystem interface.
-Default: 2
--------------------------------------------------------------------------------
-Name: debug
-Type: ushort
-Syntax: <n>
-Description: Debugging information level, from 0 to 3:
- 0 = none (use carefully)
- 1 = critical errors
- 2 = significant information
- 3 = more verbose messages
- Level 3 is useful for testing only. It also shows some more
- information about the hardware being detected.
- This parameter can be changed at runtime thanks to the /sys
- filesystem interface.
-Default: 2
--------------------------------------------------------------------------------
-
-
-8. Optional device control through "sysfs" [1]
-==========================================
-If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled,
-it is possible to read and write both the SN9C1xx and the image sensor
-registers by using the "sysfs" filesystem interface.
-
-Every time a supported device is recognized, a write-only file named "green" is
-created in the /sys/class/video4linux/videoX directory. You can set the green
-channel's gain by writing the desired value to it. The value may range from 0
-to 15 for the SN9C101 or SN9C102 bridges, from 0 to 127 for the SN9C103,
-SN9C105 and SN9C120 bridges.
-Similarly, only for the SN9C103, SN9C105 and SN9C120 controllers, blue and red
-gain control files are available in the same directory, for which accepted
-values may range from 0 to 127.
-
-There are other four entries in the directory above for each registered camera:
-"reg", "val", "i2c_reg" and "i2c_val". The first two files control the
-SN9C1xx bridge, while the other two control the sensor chip. "reg" and
-"i2c_reg" hold the values of the current register index where the following
-reading/writing operations are addressed at through "val" and "i2c_val". Their
-use is not intended for end-users. Note that "i2c_reg" and "i2c_val" will not
-be created if the sensor does not actually support the standard I2C protocol or
-its registers are not 8-bit long. Also, remember that you must be logged in as
-root before writing to them.
-
-As an example, suppose we were to want to read the value contained in the
-register number 1 of the sensor register table - which is usually the product
-identifier - of the camera registered as "/dev/video0":
-
- [root@localhost #] cd /sys/class/video4linux/video0
- [root@localhost #] echo 1 > i2c_reg
- [root@localhost #] cat i2c_val
-
-Note that "cat" will fail if sensor registers cannot be read.
-
-Now let's set the green gain's register of the SN9C101 or SN9C102 chips to 2:
-
- [root@localhost #] echo 0x11 > reg
- [root@localhost #] echo 2 > val
-
-Note that the SN9C1xx always returns 0 when some of its registers are read.
-To avoid race conditions, all the I/O accesses to the above files are
-serialized.
-The sysfs interface also provides the "frame_header" entry, which exports the
-frame header of the most recent requested and captured video frame. The header
-is always 18-bytes long and is appended to every video frame by the SN9C1xx
-controllers. As an example, this additional information can be used by the user
-application for implementing auto-exposure features via software.
-
-The following table describes the frame header exported by the SN9C101 and
-SN9C102:
-
-Byte # Value or bits Description
------- ------------- -----------
-0x00 0xFF Frame synchronisation pattern
-0x01 0xFF Frame synchronisation pattern
-0x02 0x00 Frame synchronisation pattern
-0x03 0xC4 Frame synchronisation pattern
-0x04 0xC4 Frame synchronisation pattern
-0x05 0x96 Frame synchronisation pattern
-0x06 [3:0] Read channel gain control = (1+R_GAIN/8)
- [7:4] Blue channel gain control = (1+B_GAIN/8)
-0x07 [ 0 ] Compression mode. 0=No compression, 1=Compression enabled
- [2:1] Maximum scale factor for compression
- [ 3 ] 1 = USB fifo(2K bytes) is full
- [ 4 ] 1 = Digital gain is finish
- [ 5 ] 1 = Exposure is finish
- [7:6] Frame index
-0x08 [7:0] Y sum inside Auto-Exposure area (low-byte)
-0x09 [7:0] Y sum inside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 32
-0x0A [7:0] Y sum outside Auto-Exposure area (low-byte)
-0x0B [7:0] Y sum outside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 128
-0x0C 0xXX Not used
-0x0D 0xXX Not used
-0x0E 0xXX Not used
-0x0F 0xXX Not used
-0x10 0xXX Not used
-0x11 0xXX Not used
-
-The following table describes the frame header exported by the SN9C103:
-
-Byte # Value or bits Description
------- ------------- -----------
-0x00 0xFF Frame synchronisation pattern
-0x01 0xFF Frame synchronisation pattern
-0x02 0x00 Frame synchronisation pattern
-0x03 0xC4 Frame synchronisation pattern
-0x04 0xC4 Frame synchronisation pattern
-0x05 0x96 Frame synchronisation pattern
-0x06 [6:0] Read channel gain control = (1/2+R_GAIN/64)
-0x07 [6:0] Blue channel gain control = (1/2+B_GAIN/64)
- [7:4]
-0x08 [ 0 ] Compression mode. 0=No compression, 1=Compression enabled
- [2:1] Maximum scale factor for compression
- [ 3 ] 1 = USB fifo(2K bytes) is full
- [ 4 ] 1 = Digital gain is finish
- [ 5 ] 1 = Exposure is finish
- [7:6] Frame index
-0x09 [7:0] Y sum inside Auto-Exposure area (low-byte)
-0x0A [7:0] Y sum inside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 32
-0x0B [7:0] Y sum outside Auto-Exposure area (low-byte)
-0x0C [7:0] Y sum outside Auto-Exposure area (high-byte)
- where Y sum = (R/4 + 5G/16 + B/8) / 128
-0x0D [1:0] Audio frame number
- [ 2 ] 1 = Audio is recording
-0x0E [7:0] Audio summation (low-byte)
-0x0F [7:0] Audio summation (high-byte)
-0x10 [7:0] Audio sample count
-0x11 [7:0] Audio peak data in audio frame
-
-The AE area (sx, sy, ex, ey) in the active window can be set by programming the
-registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C1xx controllers, where one unit
-corresponds to 32 pixels.
-
-[1] The frame headers exported by the SN9C105 and SN9C120 are not described.
-
-
-9. Supported devices
-====================
-None of the names of the companies as well as their products will be mentioned
-here. They have never collaborated with the author, so no advertising.
-
-From the point of view of a driver, what unambiguously identify a device are
-its vendor and product USB identifiers. Below is a list of known identifiers of
-devices assembling the SN9C1xx PC camera controllers:
-
-Vendor ID Product ID
---------- ----------
-0x0458 0x7025
-0x045e 0x00f5
-0x045e 0x00f7
-0x0471 0x0327
-0x0471 0x0328
-0x0c45 0x6001
-0x0c45 0x6005
-0x0c45 0x6007
-0x0c45 0x6009
-0x0c45 0x600d
-0x0c45 0x6011
-0x0c45 0x6019
-0x0c45 0x6024
-0x0c45 0x6025
-0x0c45 0x6028
-0x0c45 0x6029
-0x0c45 0x602a
-0x0c45 0x602b
-0x0c45 0x602c
-0x0c45 0x602d
-0x0c45 0x602e
-0x0c45 0x6030
-0x0c45 0x603f
-0x0c45 0x6080
-0x0c45 0x6082
-0x0c45 0x6083
-0x0c45 0x6088
-0x0c45 0x608a
-0x0c45 0x608b
-0x0c45 0x608c
-0x0c45 0x608e
-0x0c45 0x608f
-0x0c45 0x60a0
-0x0c45 0x60a2
-0x0c45 0x60a3
-0x0c45 0x60a8
-0x0c45 0x60aa
-0x0c45 0x60ab
-0x0c45 0x60ac
-0x0c45 0x60ae
-0x0c45 0x60af
-0x0c45 0x60b0
-0x0c45 0x60b2
-0x0c45 0x60b3
-0x0c45 0x60b8
-0x0c45 0x60ba
-0x0c45 0x60bb
-0x0c45 0x60bc
-0x0c45 0x60be
-0x0c45 0x60c0
-0x0c45 0x60c2
-0x0c45 0x60c8
-0x0c45 0x60cc
-0x0c45 0x60ea
-0x0c45 0x60ec
-0x0c45 0x60ef
-0x0c45 0x60fa
-0x0c45 0x60fb
-0x0c45 0x60fc
-0x0c45 0x60fe
-0x0c45 0x6102
-0x0c45 0x6108
-0x0c45 0x610f
-0x0c45 0x6130
-0x0c45 0x6138
-0x0c45 0x613a
-0x0c45 0x613b
-0x0c45 0x613c
-0x0c45 0x613e
-
-The list above does not imply that all those devices work with this driver: up
-until now only the ones that assemble the following pairs of SN9C1xx bridges
-and image sensors are supported; kernel messages will always tell you whether
-this is the case (see "Module loading" paragraph):
-
-Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
--------------------------------------------------------------------------------
-HV7131D Hynix Semiconductor | Yes No No No
-HV7131R Hynix Semiconductor | No Yes Yes Yes
-MI-0343 Micron Technology | Yes No No No
-MI-0360 Micron Technology | No Yes Yes Yes
-OV7630 OmniVision Technologies | Yes Yes Yes Yes
-OV7660 OmniVision Technologies | No No Yes Yes
-PAS106B PixArt Imaging | Yes No No No
-PAS202B PixArt Imaging | Yes Yes No No
-TAS5110C1B Taiwan Advanced Sensor | Yes No No No
-TAS5110D Taiwan Advanced Sensor | Yes No No No
-TAS5130D1B Taiwan Advanced Sensor | Yes No No No
-
-"Yes" means that the pair is supported by the driver, while "No" means that the
-pair does not exist or is not supported by the driver.
-
-Only some of the available control settings of each image sensor are supported
-through the V4L2 interface.
-
-Donations of new models for further testing and support would be much
-appreciated. Non-available hardware will not be supported by the author of this
-driver.
-
-
-10. Notes for V4L2 application developers
-=========================================
-This driver follows the V4L2 API specifications. In particular, it enforces two
-rules:
-
-- exactly one I/O method, either "mmap" or "read", is associated with each
-file descriptor. Once it is selected, the application must close and reopen the
-device to switch to the other I/O method;
-
-- although it is not mandatory, previously mapped buffer memory should always
-be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
-The same number of buffers as before will be allocated again to match the size
-of the new video frames, so you have to map the buffers again before any I/O
-attempts on them.
-
-Consistently with the hardware limits, this driver also supports image
-downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
-However, the V4L2 API specifications don't correctly define how the scaling
-factor can be chosen arbitrarily by the "negotiation" of the "source" and
-"target" rectangles. To work around this flaw, we have added the convention
-that, during the negotiation, whenever the "VIDIOC_S_CROP" ioctl is issued, the
-scaling factor is restored to 1.
-
-This driver supports two different video formats: the first one is the "8-bit
-Sequential Bayer" format and can be used to obtain uncompressed video data
-from the device through the current I/O method, while the second one provides
-either "raw" compressed video data (without frame headers not related to the
-compressed data) or standard JPEG (with frame headers). The compression quality
-may vary from 0 to 1 and can be selected or queried thanks to the
-VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
-both the default active video format and the default compression quality
-depend on how the image sensor being used is initialized.
-
-
-11. Video frame formats [1]
-=======================
-The SN9C1xx PC Camera Controllers can send images in two possible video
-formats over the USB: either native "Sequential RGB Bayer" or compressed.
-The compression is used to achieve high frame rates. With regard to the
-SN9C101, SN9C102 and SN9C103, the compression is based on the Huffman encoding
-algorithm described below, while with regard to the SN9C105 and SN9C120 the
-compression is based on the JPEG standard.
-The current video format may be selected or queried from the user application
-by calling the VIDIOC_S_FMT or VIDIOC_G_FMT ioctl's, as described in the V4L2
-API specifications.
-
-The name "Sequential Bayer" indicates the organization of the red, green and
-blue pixels in one video frame. Each pixel is associated with a 8-bit long
-value and is disposed in memory according to the pattern shown below:
-
-B[0] G[1] B[2] G[3] ... B[m-2] G[m-1]
-G[m] R[m+1] G[m+2] R[m+2] ... G[2m-2] R[2m-1]
-...
-... B[(n-1)(m-2)] G[(n-1)(m-1)]
-... G[n(m-2)] R[n(m-1)]
-
-The above matrix also represents the sequential or progressive read-out mode of
-the (n, m) Bayer color filter array used in many CCD or CMOS image sensors.
-
-The Huffman compressed video frame consists of a bitstream that encodes for
-every R, G, or B pixel the difference between the value of the pixel itself and
-some reference pixel value. Pixels are organised in the Bayer pattern and the
-Bayer sub-pixels are tracked individually and alternatingly. For example, in
-the first line values for the B and G1 pixels are alternatingly encoded, while
-in the second line values for the G2 and R pixels are alternatingly encoded.
-
-The pixel reference value is calculated as follows:
-- the 4 top left pixels are encoded in raw uncompressed 8-bit format;
-- the value in the top two rows is the value of the pixel left of the current
- pixel;
-- the value in the left column is the value of the pixel above the current
- pixel;
-- for all other pixels, the reference value is the average of the value of the
- pixel on the left and the value of the pixel above the current pixel;
-- there is one code in the bitstream that specifies the value of a pixel
- directly (in 4-bit resolution);
-- pixel values need to be clamped inside the range [0..255] for proper
- decoding.
-
-The algorithm purely describes the conversion from compressed Bayer code used
-in the SN9C101, SN9C102 and SN9C103 chips to uncompressed Bayer. Additional
-steps are required to convert this to a color image (i.e. a color interpolation
-algorithm).
-
-The following Huffman codes have been found:
-0: +0 (relative to reference pixel value)
-100: +4
-101: -4?
-1110xxxx: set absolute value to xxxx.0000
-1101: +11
-1111: -11
-11001: +20
-110000: -20
-110001: ??? - these codes are apparently not used
-
-[1] The Huffman compression algorithm has been reverse-engineered and
- documented by Bertrik Sikken.
-
-
-12. Contact information
-=======================
-The author may be contacted by e-mail at <luca.risolia@studio.unibo.it>.
-
-GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is
-'FCE635A4'; the public 1024-bit key should be available at any keyserver;
-the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
-
-
-13. Credits
-===========
-Many thanks to following persons for their contribute (listed in alphabetical
-order):
-
-- David Anderson for the donation of a webcam;
-- Luca Capello for the donation of a webcam;
-- Philippe Coval for having helped testing the PAS202BCA image sensor;
-- Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
- donation of a webcam;
-- Dennis Heitmann for the donation of a webcam;
-- Jon Hollstrom for the donation of a webcam;
-- Nick McGill for the donation of a webcam;
-- Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB
- image sensor;
-- Stefano Mozzi, who donated 45 EU;
-- Andrew Pearce for the donation of a webcam;
-- John Pullan for the donation of a webcam;
-- Bertrik Sikken, who reverse-engineered and documented the Huffman compression
- algorithm used in the SN9C101, SN9C102 and SN9C103 controllers and
- implemented the first decoder;
-- Ronny Standke for the donation of a webcam;
-- Mizuno Takafumi for the donation of a webcam;
-- an "anonymous" donator (who didn't want his name to be revealed) for the
- donation of a webcam.
-- an anonymous donator for the donation of four webcams and two boards with ten
- image sensors.
diff --git a/drivers/staging/media/sn9c102/sn9c102_config.h b/drivers/staging/media/sn9c102/sn9c102_config.h
deleted file mode 100644
index 0f4e0378b071..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Global parameters for the V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_CONFIG_H_
-#define _SN9C102_CONFIG_H_
-
-#include <linux/types.h>
-#include <linux/jiffies.h>
-
-#define SN9C102_DEBUG
-#define SN9C102_DEBUG_LEVEL 2
-#define SN9C102_MAX_DEVICES 64
-#define SN9C102_PRESERVE_IMGSCALE 0
-#define SN9C102_FORCE_MUNMAP 0
-#define SN9C102_MAX_FRAMES 32
-#define SN9C102_URBS 2
-#define SN9C102_ISO_PACKETS 7
-#define SN9C102_ALTERNATE_SETTING 8
-#define SN9C102_URB_TIMEOUT msecs_to_jiffies(2 * SN9C102_ISO_PACKETS)
-#define SN9C102_CTRL_TIMEOUT 300
-#define SN9C102_FRAME_TIMEOUT 0
-
-/*****************************************************************************/
-
-static const u8 SN9C102_Y_QTABLE0[64] = {
- 8, 5, 5, 8, 12, 20, 25, 30,
- 6, 6, 7, 9, 13, 29, 30, 27,
- 7, 6, 8, 12, 20, 28, 34, 28,
- 7, 8, 11, 14, 25, 43, 40, 31,
- 9, 11, 18, 28, 34, 54, 51, 38,
- 12, 17, 27, 32, 40, 52, 56, 46,
- 24, 32, 39, 43, 51, 60, 60, 50,
- 36, 46, 47, 49, 56, 50, 51, 49
-};
-
-static const u8 SN9C102_UV_QTABLE0[64] = {
- 8, 9, 12, 23, 49, 49, 49, 49,
- 9, 10, 13, 33, 49, 49, 49, 49,
- 12, 13, 28, 49, 49, 49, 49, 49,
- 23, 33, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49
-};
-
-static const u8 SN9C102_Y_QTABLE1[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-
-static const u8 SN9C102_UV_QTABLE1[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
-};
-
-#endif /* _SN9C102_CONFIG_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102_core.c b/drivers/staging/media/sn9c102/sn9c102_core.c
deleted file mode 100644
index 98b30579b0ac..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_core.c
+++ /dev/null
@@ -1,3465 +0,0 @@
-/***************************************************************************
- * V4L2 driver for SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/version.h>
-#include <linux/page-flags.h>
-#include <asm/byteorder.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "sn9c102.h"
-
-/*****************************************************************************/
-
-#define SN9C102_MODULE_NAME "V4L2 driver for SN9C1xx PC Camera Controllers"
-#define SN9C102_MODULE_ALIAS "sn9c1xx"
-#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
-#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
-#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.48"
-
-/*****************************************************************************/
-
-MODULE_DEVICE_TABLE(usb, sn9c102_id_table);
-
-MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL);
-MODULE_DESCRIPTION(SN9C102_MODULE_NAME);
-MODULE_ALIAS(SN9C102_MODULE_ALIAS);
-MODULE_VERSION(SN9C102_MODULE_VERSION);
-MODULE_LICENSE(SN9C102_MODULE_LICENSE);
-
-static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1};
-module_param_array(video_nr, short, NULL, 0444);
-MODULE_PARM_DESC(video_nr,
- " <-1|n[,...]>"
- "\nSpecify V4L2 minor mode number."
- "\n-1 = use next available (default)"
- "\n n = use minor number n (integer >= 0)"
- "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES)
- " cameras this way."
- "\nFor example:"
- "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
- "\nthe second camera and use auto for the first"
- "\none and for every other camera."
- "\n");
-
-static bool force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FORCE_MUNMAP};
-module_param_array(force_munmap, bool, NULL, 0444);
-MODULE_PARM_DESC(force_munmap,
- " <0|1[,...]>"
- "\nForce the application to unmap previously"
- "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
- "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
- "\nthis feature. This parameter is specific for each"
- "\ndetected camera."
- "\n0 = do not force memory unmapping"
- "\n1 = force memory unmapping (save memory)"
- "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
- "\n");
-
-static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FRAME_TIMEOUT};
-module_param_array(frame_timeout, uint, NULL, 0644);
-MODULE_PARM_DESC(frame_timeout,
- " <0|n[,...]>"
- "\nTimeout for a video frame in seconds before"
- "\nreturning an I/O error; 0 for infinity."
- "\nThis parameter is specific for each detected camera."
- "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"."
- "\n");
-
-#ifdef SN9C102_DEBUG
-static unsigned short debug = SN9C102_DEBUG_LEVEL;
-module_param(debug, ushort, 0644);
-MODULE_PARM_DESC(debug,
- " <n>"
- "\nDebugging information level, from 0 to 3:"
- "\n0 = none (use carefully)"
- "\n1 = critical errors"
- "\n2 = significant informations"
- "\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only."
- "\nDefault value is "__MODULE_STRING(SN9C102_DEBUG_LEVEL)"."
- "\n");
-#endif
-
-/*
- Add the probe entries to this table. Be sure to add the entry in the right
- place, since, on failure, the next probing routine is called according to
- the order of the list below, from top to bottom.
-*/
-static int (*sn9c102_sensor_table[])(struct sn9c102_device *) = {
- &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */
- &sn9c102_probe_hv7131r, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0343, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mi0360, /* strong detection based on SENSOR ids */
- &sn9c102_probe_mt9v111, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */
- &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7630, /* strong detection based on SENSOR ids */
- &sn9c102_probe_ov7660, /* strong detection based on SENSOR ids */
- &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
- &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
-};
-
-/*****************************************************************************/
-
-static u32
-sn9c102_request_buffers(struct sn9c102_device *cam, u32 count,
- enum sn9c102_io_method io)
-{
- struct v4l2_pix_format *p = &(cam->sensor.pix_format);
- struct v4l2_rect *r = &(cam->sensor.cropcap.bounds);
- size_t imagesize = cam->module_param.force_munmap || io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
- void *buff = NULL;
- u32 i;
-
- if (count > SN9C102_MAX_FRAMES)
- count = SN9C102_MAX_FRAMES;
-
- if (cam->bridge == BRIDGE_SN9C105 || cam->bridge == BRIDGE_SN9C120)
- imagesize += 589 + 2; /* length of JPEG header + EOI marker */
-
- cam->nbuffers = count;
- while (cam->nbuffers > 0) {
- buff = vmalloc_32_user(cam->nbuffers * PAGE_ALIGN(imagesize));
- if (buff)
- break;
- cam->nbuffers--;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.index = i;
- cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.length = imagesize;
- cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->frame[i].buf.sequence = 0;
- cam->frame[i].buf.field = V4L2_FIELD_NONE;
- cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
- cam->frame[i].buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- }
-
- return cam->nbuffers;
-}
-
-
-static void sn9c102_release_buffers(struct sn9c102_device *cam)
-{
- if (cam->nbuffers) {
- vfree(cam->frame[0].bufmem);
- cam->nbuffers = 0;
- }
- cam->frame_current = NULL;
-}
-
-
-static void sn9c102_empty_framequeues(struct sn9c102_device *cam)
-{
- u32 i;
-
- INIT_LIST_HEAD(&cam->inqueue);
- INIT_LIST_HEAD(&cam->outqueue);
-
- for (i = 0; i < SN9C102_MAX_FRAMES; i++) {
- cam->frame[i].state = F_UNUSED;
- cam->frame[i].buf.bytesused = 0;
- }
-}
-
-
-static void sn9c102_requeue_outqueue(struct sn9c102_device *cam)
-{
- struct sn9c102_frame_t *i;
-
- list_for_each_entry(i, &cam->outqueue, frame) {
- i->state = F_QUEUED;
- list_add(&i->frame, &cam->inqueue);
- }
-
- INIT_LIST_HEAD(&cam->outqueue);
-}
-
-
-static void sn9c102_queue_unusedframes(struct sn9c102_device *cam)
-{
- unsigned long lock_flags;
- u32 i;
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].state == F_UNUSED) {
- cam->frame[i].state = F_QUEUED;
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[i].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- }
-}
-
-/*****************************************************************************/
-
-/*
- Write a sequence of count value/register pairs. Returns -1 after the first
- failed write, or 0 for no errors.
-*/
-int sn9c102_write_regs(struct sn9c102_device *cam, const u8 valreg[][2],
- int count)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int i, res;
-
- for (i = 0; i < count; i++) {
- u8 index = valreg[i][1];
-
- /*
- index is a u8, so it must be <256 and can't be out of range.
- If we put in a check anyway, gcc annoys us with a warning
- hat our check is useless. People get all uppity when they
- see warnings in the kernel compile.
- */
-
- *buff = valreg[i][0];
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
- 0x41, index, 0, buff, 1,
- SN9C102_CTRL_TIMEOUT);
-
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, "
- "index 0x%02X, error %d)", *buff, index, res);
- return -1;
- }
-
- cam->reg[index] = *buff;
- }
-
- return 0;
-}
-
-
-int sn9c102_write_reg(struct sn9c102_device *cam, u8 value, u16 index)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int res;
-
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- *buff = value;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0) {
- DBG(3, "Failed to write a register (value 0x%02X, index "
- "0x%02X, error %d)", value, index, res);
- return -1;
- }
-
- cam->reg[index] = value;
-
- return 0;
-}
-
-
-/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
-int sn9c102_read_reg(struct sn9c102_device *cam, u16 index)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *buff = cam->control_buffer;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- index, 0, buff, 1, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- DBG(3, "Failed to read a register (index 0x%02X, error %d)",
- index, res);
-
- return (res >= 0) ? (int)(*buff) : -1;
-}
-
-
-int sn9c102_pread_reg(struct sn9c102_device *cam, u16 index)
-{
- if (index >= ARRAY_SIZE(cam->reg))
- return -1;
-
- return cam->reg[index];
-}
-
-
-static int
-sn9c102_i2c_wait(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int i, r;
-
- for (i = 1; i <= 5; i++) {
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- return -EIO;
- if (r & 0x04)
- return 0;
- if (sensor->frequency & SN9C102_I2C_400KHZ)
- udelay(5*16);
- else
- udelay(16*16);
- }
- return -EBUSY;
-}
-
-
-static int
-sn9c102_i2c_detect_read_error(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int r , err = 0;
-
- r = sn9c102_read_reg(cam, 0x08);
- if (r < 0)
- err += r;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- if (!(r & 0x08))
- err += -1;
- } else {
- if (r & 0x08)
- err += -1;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_i2c_detect_write_error(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor)
-{
- int r;
-
- r = sn9c102_read_reg(cam, 0x08);
- return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0;
-}
-
-
-int
-sn9c102_i2c_try_raw_read(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[])
-{
- struct usb_device *udev = cam->usbdev;
- u8 *data = cam->control_buffer;
- int i = 0, err = 0, res;
-
- /* Write cycle */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) | 0x10;
- data[1] = data0; /* I2C slave id */
- data[2] = data1; /* address */
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* Read cycle - n bytes */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0) |
- (n << 4) | 0x02;
- data[1] = data0;
- data[7] = 0x10;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
-
- /* The first read byte will be placed in data[4] */
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1,
- 0x0a, 0, data, 5, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_detect_read_error(cam, sensor);
-
- PDBGG("I2C read: address 0x%02X, first read byte: 0x%02X", data1,
- data[4]);
-
- if (err) {
- DBG(3, "I2C read failed for %s image sensor", sensor->name);
- return -1;
- }
-
- if (buffer)
- for (i = 0; i < n && i < 5; i++)
- buffer[n-i-1] = data[4-i];
-
- return (int)data[4];
-}
-
-
-int
-sn9c102_i2c_try_raw_write(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 n, u8 data0,
- u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
-{
- struct usb_device *udev = cam->usbdev;
- u8 *data = cam->control_buffer;
- int err = 0, res;
-
- /* Write cycle. It usually is address + value */
- data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
- ((sensor->frequency & SN9C102_I2C_400KHZ) ? 0x01 : 0)
- | ((n - 1) << 4);
- data[1] = data0;
- data[2] = data1;
- data[3] = data2;
- data[4] = data3;
- data[5] = data4;
- data[6] = data5;
- data[7] = 0x17;
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08, 0x41,
- 0x08, 0, data, 8, SN9C102_CTRL_TIMEOUT);
- if (res < 0)
- err += res;
-
- err += sn9c102_i2c_wait(cam, sensor);
- err += sn9c102_i2c_detect_write_error(cam, sensor);
-
- if (err)
- DBG(3, "I2C write failed for %s image sensor", sensor->name);
-
- PDBGG("I2C raw write: %u bytes, data0 = 0x%02X, data1 = 0x%02X, "
- "data2 = 0x%02X, data3 = 0x%02X, data4 = 0x%02X, data5 = 0x%02X",
- n, data0, data1, data2, data3, data4, data5);
-
- return err ? -1 : 0;
-}
-
-
-int
-sn9c102_i2c_try_read(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 address)
-{
- return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
- address, 1, NULL);
-}
-
-
-static int sn9c102_i2c_try_write(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor,
- u8 address, u8 value)
-{
- return sn9c102_i2c_try_raw_write(cam, sensor, 3,
- sensor->i2c_slave_id, address,
- value, 0, 0, 0);
-}
-
-
-int sn9c102_i2c_read(struct sn9c102_device *cam, u8 address)
-{
- return sn9c102_i2c_try_read(cam, &cam->sensor, address);
-}
-
-
-int sn9c102_i2c_write(struct sn9c102_device *cam, u8 address, u8 value)
-{
- return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
-}
-
-/*****************************************************************************/
-
-static size_t sn9c102_sof_length(struct sn9c102_device *cam)
-{
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- return 12;
- case BRIDGE_SN9C103:
- return 18;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- return 62;
- }
-
- return 0;
-}
-
-
-static void*
-sn9c102_find_sof_header(struct sn9c102_device *cam, void *mem, size_t len)
-{
- static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
- const char *m = mem;
- size_t soflen = 0, i, j;
-
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < len; i++) {
- size_t b;
-
- /* Read the variable part of the header */
- if (unlikely(cam->sof.bytesread >= sizeof(marker))) {
- cam->sof.header[cam->sof.bytesread] = *(m+i);
- if (++cam->sof.bytesread == soflen) {
- cam->sof.bytesread = 0;
- return mem + i;
- }
- continue;
- }
-
- /* Search for the SOF marker (fixed part) in the header */
- for (j = 0, b = cam->sof.bytesread; j+b < sizeof(marker); j++) {
- if (unlikely(i+j == len))
- return NULL;
- if (*(m+i+j) == marker[cam->sof.bytesread]) {
- cam->sof.header[cam->sof.bytesread] = *(m+i+j);
- if (++cam->sof.bytesread == sizeof(marker)) {
- PDBGG("Bytes to analyze: %zd. SOF "
- "starts at byte #%zd", len, i);
- i += j+1;
- break;
- }
- } else {
- cam->sof.bytesread = 0;
- break;
- }
- }
- }
-
- return NULL;
-}
-
-
-static void*
-sn9c102_find_eof_header(struct sn9c102_device *cam, void *mem, size_t len)
-{
- static const u8 eof_header[4][4] = {
- {0x00, 0x00, 0x00, 0x00},
- {0x40, 0x00, 0x00, 0x00},
- {0x80, 0x00, 0x00, 0x00},
- {0xc0, 0x00, 0x00, 0x00},
- };
- size_t i, j;
-
- /* The EOF header does not exist in compressed data */
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- return NULL;
-
- /*
- The EOF header might cross the packet boundary, but this is not a
- problem, since the end of a frame is determined by checking its size
- in the first place.
- */
- for (i = 0; (len >= 4) && (i <= len - 4); i++)
- for (j = 0; j < ARRAY_SIZE(eof_header); j++)
- if (!memcmp(mem + i, eof_header[j], 4))
- return mem + i;
-
- return NULL;
-}
-
-
-static void
-sn9c102_write_jpegheader(struct sn9c102_device *cam, struct sn9c102_frame_t *f)
-{
- static const u8 jpeg_header[589] = {
- 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05,
- 0x06, 0x05, 0x04, 0x06, 0x06, 0x05, 0x06, 0x07, 0x07, 0x06,
- 0x08, 0x0a, 0x10, 0x0a, 0x0a, 0x09, 0x09, 0x0a, 0x14, 0x0e,
- 0x0f, 0x0c, 0x10, 0x17, 0x14, 0x18, 0x18, 0x17, 0x14, 0x16,
- 0x16, 0x1a, 0x1d, 0x25, 0x1f, 0x1a, 0x1b, 0x23, 0x1c, 0x16,
- 0x16, 0x20, 0x2c, 0x20, 0x23, 0x26, 0x27, 0x29, 0x2a, 0x29,
- 0x19, 0x1f, 0x2d, 0x30, 0x2d, 0x28, 0x30, 0x25, 0x28, 0x29,
- 0x28, 0x01, 0x07, 0x07, 0x07, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
- 0x0a, 0x13, 0x28, 0x1a, 0x16, 0x1a, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0xc4, 0x01, 0xa2,
- 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01,
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00,
- 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04,
- 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
- 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61,
- 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23,
- 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62,
- 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
- 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
- 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
- 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
- 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3,
- 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
- 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04,
- 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
- 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
- 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
- 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19,
- 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
- 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
- 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
- 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
- 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
- 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11,
- 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, 0x01, 0x21, 0x00, 0x02,
- 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03,
- 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
- };
- u8 *pos = f->bufmem;
-
- memcpy(pos, jpeg_header, sizeof(jpeg_header));
- *(pos + 6) = 0x00;
- *(pos + 7 + 64) = 0x01;
- if (cam->compression.quality == 0) {
- memcpy(pos + 7, SN9C102_Y_QTABLE0, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE0, 64);
- } else if (cam->compression.quality == 1) {
- memcpy(pos + 7, SN9C102_Y_QTABLE1, 64);
- memcpy(pos + 8 + 64, SN9C102_UV_QTABLE1, 64);
- }
- *(pos + 564) = cam->sensor.pix_format.width & 0xFF;
- *(pos + 563) = (cam->sensor.pix_format.width >> 8) & 0xFF;
- *(pos + 562) = cam->sensor.pix_format.height & 0xFF;
- *(pos + 561) = (cam->sensor.pix_format.height >> 8) & 0xFF;
- *(pos + 567) = 0x21;
-
- f->buf.bytesused += sizeof(jpeg_header);
-}
-
-
-static void sn9c102_urb_complete(struct urb *urb)
-{
- struct sn9c102_device *cam = urb->context;
- struct sn9c102_frame_t **f;
- size_t imagesize, soflen;
- u8 i;
- int err = 0;
-
- if (urb->status == -ENOENT)
- return;
-
- f = &cam->frame_current;
-
- if (cam->stream == STREAM_INTERRUPT) {
- cam->stream = STREAM_OFF;
- if ((*f))
- (*f)->state = F_QUEUED;
- cam->sof.bytesread = 0;
- DBG(3, "Stream interrupted by application");
- wake_up(&cam->wait_stream);
- }
-
- if (cam->state & DEV_DISCONNECTED)
- return;
-
- if (cam->state & DEV_MISCONFIGURED) {
- wake_up_interruptible(&cam->wait_frame);
- return;
- }
-
- if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
- goto resubmit_urb;
-
- if (!(*f))
- (*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
- frame);
-
- imagesize = (cam->sensor.pix_format.width *
- cam->sensor.pix_format.height *
- cam->sensor.pix_format.priv) / 8;
- if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- imagesize += 589; /* length of jpeg header */
- soflen = sn9c102_sof_length(cam);
-
- for (i = 0; i < urb->number_of_packets; i++) {
- unsigned int img, len, status;
- void *pos, *sof, *eof;
-
- len = urb->iso_frame_desc[i].actual_length;
- status = urb->iso_frame_desc[i].status;
- pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-
- if (status) {
- DBG(3, "Error in isochronous frame");
- (*f)->state = F_ERROR;
- cam->sof.bytesread = 0;
- continue;
- }
-
- PDBGG("Isochrnous frame: length %u, #%u i", len, i);
-
-redo:
- sof = sn9c102_find_sof_header(cam, pos, len);
- if (likely(!sof)) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if ((*f)->state == F_GRABBING) {
-end_of_frame:
- img = len;
-
- if (eof)
- img = (eof > pos) ? eof - pos - 1 : 0;
-
- if ((*f)->buf.bytesused + img > imagesize) {
- u32 b;
- b = (*f)->buf.bytesused + img -
- imagesize;
- img = imagesize - (*f)->buf.bytesused;
- PDBGG("Expected EOF not found: video "
- "frame cut");
- if (eof)
- DBG(3, "Exceeded limit: +%u "
- "bytes", (unsigned)(b));
- }
-
- memcpy((*f)->bufmem + (*f)->buf.bytesused, pos,
- img);
-
- if ((*f)->buf.bytesused == 0)
- v4l2_get_timestamp(
- &(*f)->buf.timestamp);
-
- (*f)->buf.bytesused += img;
-
- if ((*f)->buf.bytesused == imagesize ||
- ((cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) && eof)) {
- u32 b;
-
- b = (*f)->buf.bytesused;
- (*f)->state = F_DONE;
- (*f)->buf.sequence = ++cam->frame_count;
-
- spin_lock(&cam->queue_lock);
- list_move_tail(&(*f)->frame,
- &cam->outqueue);
- if (!list_empty(&cam->inqueue))
- (*f) = list_entry(
- cam->inqueue.next,
- struct sn9c102_frame_t,
- frame);
- else
- (*f) = NULL;
- spin_unlock(&cam->queue_lock);
-
- memcpy(cam->sysfs.frame_header,
- cam->sof.header, soflen);
-
- DBG(3, "Video frame captured: %lu "
- "bytes", (unsigned long)(b));
-
- if (!(*f))
- goto resubmit_urb;
-
- } else if (eof) {
- (*f)->state = F_ERROR;
- DBG(3, "Not expected EOF after %lu "
- "bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- }
-
- if (sof) /* (1) */
- goto start_of_frame;
-
- } else if (eof) {
- DBG(3, "EOF without SOF");
- continue;
-
- } else {
- PDBGG("Ignoring pointless isochronous frame");
- continue;
- }
-
- } else if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) {
-start_of_frame:
- (*f)->state = F_GRABBING;
- (*f)->buf.bytesused = 0;
- len -= (sof - pos);
- pos = sof;
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG)
- sn9c102_write_jpegheader(cam, (*f));
- DBG(3, "SOF detected: new video frame");
- if (len)
- goto redo;
-
- } else if ((*f)->state == F_GRABBING) {
- eof = sn9c102_find_eof_header(cam, pos, len);
- if (eof && eof < sof)
- goto end_of_frame; /* (1) */
- else {
- if (cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_SN9C10X ||
- cam->sensor.pix_format.pixelformat ==
- V4L2_PIX_FMT_JPEG) {
- if (sof - pos >= soflen) {
- eof = sof - soflen;
- } else { /* remove header */
- eof = pos;
- (*f)->buf.bytesused -=
- (soflen - (sof - pos));
- }
- goto end_of_frame;
- } else {
- DBG(3, "SOF before expected EOF after "
- "%lu bytes of image data",
- (unsigned long)
- ((*f)->buf.bytesused));
- goto start_of_frame;
- }
- }
- }
- }
-
-resubmit_urb:
- urb->dev = cam->usbdev;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -EPERM) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "usb_submit_urb() failed");
- }
-
- wake_up_interruptible(&cam->wait_frame);
-}
-
-
-static int sn9c102_start_transfer(struct sn9c102_device *cam)
-{
- struct usb_device *udev = cam->usbdev;
- struct urb *urb;
- struct usb_host_interface *altsetting = usb_altnum_to_altsetting(
- usb_ifnum_to_if(udev, 0),
- SN9C102_ALTERNATE_SETTING);
- const unsigned int psz = le16_to_cpu(altsetting->
- endpoint[0].desc.wMaxPacketSize);
- s8 i, j;
- int err = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz,
- GFP_KERNEL);
- if (!cam->transfer_buffer[i]) {
- err = -ENOMEM;
- DBG(1, "Not enough memory");
- goto free_buffers;
- }
- }
-
- for (i = 0; i < SN9C102_URBS; i++) {
- urb = usb_alloc_urb(SN9C102_ISO_PACKETS, GFP_KERNEL);
- cam->urb[i] = urb;
- if (!urb) {
- err = -ENOMEM;
- DBG(1, "usb_alloc_urb() failed");
- goto free_urbs;
- }
- urb->dev = udev;
- urb->context = cam;
- urb->pipe = usb_rcvisocpipe(udev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = SN9C102_ISO_PACKETS;
- urb->complete = sn9c102_urb_complete;
- urb->transfer_buffer = cam->transfer_buffer[i];
- urb->transfer_buffer_length = psz * SN9C102_ISO_PACKETS;
- urb->interval = 1;
- for (j = 0; j < SN9C102_ISO_PACKETS; j++) {
- urb->iso_frame_desc[j].offset = psz * j;
- urb->iso_frame_desc[j].length = psz;
- }
- }
-
- /* Enable video */
- if (!(cam->reg[0x01] & 0x04)) {
- err = sn9c102_write_reg(cam, cam->reg[0x01] | 0x04, 0x01);
- if (err) {
- err = -EIO;
- DBG(1, "I/O hardware error");
- goto free_urbs;
- }
- }
-
- err = usb_set_interface(udev, 0, SN9C102_ALTERNATE_SETTING);
- if (err) {
- DBG(1, "usb_set_interface() failed");
- goto free_urbs;
- }
-
- cam->frame_current = NULL;
- cam->sof.bytesread = 0;
-
- for (i = 0; i < SN9C102_URBS; i++) {
- err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
- if (err) {
- for (j = i-1; j >= 0; j--)
- usb_kill_urb(cam->urb[j]);
- DBG(1, "usb_submit_urb() failed, error %d", err);
- goto free_urbs;
- }
- }
-
- return 0;
-
-free_urbs:
- for (i = 0; (i < SN9C102_URBS) && cam->urb[i]; i++)
- usb_free_urb(cam->urb[i]);
-
-free_buffers:
- for (i = 0; (i < SN9C102_URBS) && cam->transfer_buffer[i]; i++)
- kfree(cam->transfer_buffer[i]);
-
- return err;
-}
-
-
-static int sn9c102_stop_transfer(struct sn9c102_device *cam)
-{
- struct usb_device *udev = cam->usbdev;
- s8 i;
- int err = 0;
-
- if (cam->state & DEV_DISCONNECTED)
- return 0;
-
- for (i = SN9C102_URBS-1; i >= 0; i--) {
- usb_kill_urb(cam->urb[i]);
- usb_free_urb(cam->urb[i]);
- kfree(cam->transfer_buffer[i]);
- }
-
- err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
- if (err)
- DBG(3, "usb_set_interface() failed");
-
- return err;
-}
-
-
-static int sn9c102_stream_interrupt(struct sn9c102_device *cam)
-{
- cam->stream = STREAM_INTERRUPT;
- wait_event_timeout(cam->wait_stream,
- (cam->stream == STREAM_OFF) ||
- (cam->state & DEV_DISCONNECTED),
- SN9C102_URB_TIMEOUT);
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- else if (cam->stream != STREAM_OFF) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "URB timeout reached. The camera is misconfigured. "
- "To use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static u16 sn9c102_strtou16(const char *buff, size_t len, ssize_t *count)
-{
- char str[7];
- char *endp;
- unsigned long val;
-
- if (len < 6) {
- strncpy(str, buff, len);
- str[len] = '\0';
- } else {
- strncpy(str, buff, 6);
- str[6] = '\0';
- }
-
- val = simple_strtoul(str, &endp, 0);
-
- *count = 0;
- if (val <= 0xffff)
- *count = (ssize_t)(endp - str);
- if ((*count) && (len == *count+1) && (buff[*count] == '\n'))
- *count += 1;
-
- return (u16)val;
-}
-
-/*
- NOTE 1: being inside one of the following methods implies that the v4l
- device exists for sure (see kobjects and reference counters)
- NOTE 2: buffers are PAGE_SIZE long
-*/
-
-static ssize_t sn9c102_show_reg(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.reg);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_reg(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (index >= ARRAY_SIZE(cam->reg) || !count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.reg = index;
-
- DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_val(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- val = sn9c102_read_reg(cam, cam->sysfs.reg);
- if (val < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_val(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_write_reg(cam, value, cam->sysfs.reg);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X",
- cam->sysfs.reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_reg(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg);
-
- DBG(3, "Read bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_reg(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 index;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- index = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- cam->sysfs.i2c_reg = index;
-
- DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t sn9c102_show_i2c_val(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
- int val;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg);
- if (val < 0) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- count = sprintf(buf, "%d\n", val);
-
- DBG(3, "Read bytes: %zd, value: %d", count, val);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_i2c_val(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- u16 value;
- ssize_t count;
- int err;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENOSYS;
- }
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EINVAL;
- }
-
- err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value);
- if (err) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -EIO;
- }
-
- DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X",
- cam->sysfs.i2c_reg, value);
- DBG(3, "Written bytes: %zd", count);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- return count;
-}
-
-
-static ssize_t
-sn9c102_store_green(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct sn9c102_device *cam;
- enum sn9c102_bridge bridge;
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- if (mutex_lock_interruptible(&sn9c102_sysfs_lock))
- return -ERESTARTSYS;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam) {
- mutex_unlock(&sn9c102_sysfs_lock);
- return -ENODEV;
- }
-
- bridge = cam->bridge;
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count)
- return -EINVAL;
-
- switch (bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- if (value > 0x0f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x11", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- case BRIDGE_SN9C103:
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (value > 0x7f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x07", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
- break;
- }
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_blue(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
-
- res = sn9c102_store_reg(cd, attr, "0x06", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t
-sn9c102_store_red(struct device *cd, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- ssize_t res = 0;
- u16 value;
- ssize_t count;
-
- value = sn9c102_strtou16(buf, len, &count);
- if (!count || value > 0x7f)
- return -EINVAL;
- res = sn9c102_store_reg(cd, attr, "0x05", 4);
- if (res >= 0)
- res = sn9c102_store_val(cd, attr, buf, len);
-
- return res;
-}
-
-
-static ssize_t sn9c102_show_frame_header(struct device *cd,
- struct device_attribute *attr,
- char *buf)
-{
- struct sn9c102_device *cam;
- ssize_t count;
-
- cam = video_get_drvdata(container_of(cd, struct video_device, dev));
- if (!cam)
- return -ENODEV;
-
- count = sizeof(cam->sysfs.frame_header);
- memcpy(buf, cam->sysfs.frame_header, count);
-
- DBG(3, "Frame header, read bytes: %zd", count);
-
- return count;
-}
-
-
-static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);
-static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);
-static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
-static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
- sn9c102_show_i2c_val, sn9c102_store_i2c_val);
-static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
-static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
-static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
-static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
-
-
-static int sn9c102_create_sysfs(struct sn9c102_device *cam)
-{
- struct device *dev = &(cam->v4ldev->dev);
- int err = 0;
-
- err = device_create_file(dev, &dev_attr_reg);
- if (err)
- goto err_out;
- err = device_create_file(dev, &dev_attr_val);
- if (err)
- goto err_reg;
- err = device_create_file(dev, &dev_attr_frame_header);
- if (err)
- goto err_val;
-
- if (cam->sensor.sysfs_ops) {
- err = device_create_file(dev, &dev_attr_i2c_reg);
- if (err)
- goto err_frame_header;
- err = device_create_file(dev, &dev_attr_i2c_val);
- if (err)
- goto err_i2c_reg;
- }
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
- err = device_create_file(dev, &dev_attr_green);
- if (err)
- goto err_i2c_val;
- } else {
- err = device_create_file(dev, &dev_attr_blue);
- if (err)
- goto err_i2c_val;
- err = device_create_file(dev, &dev_attr_red);
- if (err)
- goto err_blue;
- }
-
- return 0;
-
-err_blue:
- device_remove_file(dev, &dev_attr_blue);
-err_i2c_val:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_val);
-err_i2c_reg:
- if (cam->sensor.sysfs_ops)
- device_remove_file(dev, &dev_attr_i2c_reg);
-err_frame_header:
- device_remove_file(dev, &dev_attr_frame_header);
-err_val:
- device_remove_file(dev, &dev_attr_val);
-err_reg:
- device_remove_file(dev, &dev_attr_reg);
-err_out:
- return err;
-}
-#endif /* CONFIG_VIDEO_ADV_DEBUG */
-
-/*****************************************************************************/
-
-static int
-sn9c102_set_pix_format(struct sn9c102_device *cam, struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- }
- } else {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f,
- 0x18);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80,
- 0x18);
- break;
- }
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int
-sn9c102_set_compression(struct sn9c102_device *cam,
- struct v4l2_jpegcompression *compression)
-{
- int i, err = 0;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (compression->quality == 0)
- err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01,
- 0x17);
- else if (compression->quality == 1)
- err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe,
- 0x17);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (compression->quality == 0) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] & 0xbf,
- 0x18);
- } else if (compression->quality == 1) {
- for (i = 0; i <= 63; i++) {
- err += sn9c102_write_reg(cam,
- SN9C102_Y_QTABLE1[i],
- 0x100 + i);
- err += sn9c102_write_reg(cam,
- SN9C102_UV_QTABLE1[i],
- 0x140 + i);
- }
- err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x40,
- 0x18);
- }
- break;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int sn9c102_set_scale(struct sn9c102_device *cam, u8 scale)
-{
- u8 r = 0;
- int err = 0;
-
- if (scale == 1)
- r = cam->reg[0x18] & 0xcf;
- else if (scale == 2) {
- r = cam->reg[0x18] & 0xcf;
- r |= 0x10;
- } else if (scale == 4)
- r = cam->reg[0x18] | 0x20;
-
- err += sn9c102_write_reg(cam, r, 0x18);
- if (err)
- return -EIO;
-
- PDBGG("Scaling factor: %u", scale);
-
- return 0;
-}
-
-
-static int sn9c102_set_crop(struct sn9c102_device *cam, struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
- v_start = (u8)(rect->top - s->cropcap.bounds.top),
- h_size = (u8)(rect->width / 16),
- v_size = (u8)(rect->height / 16);
- int err = 0;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
- err += sn9c102_write_reg(cam, h_size, 0x15);
- err += sn9c102_write_reg(cam, v_size, 0x16);
- if (err)
- return -EIO;
-
- PDBGG("h_start, v_start, h_size, v_size, ho_size, vo_size "
- "%u %u %u %u", h_start, v_start, h_size, v_size);
-
- return 0;
-}
-
-
-static int sn9c102_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- struct v4l2_queryctrl *qctrl;
- struct v4l2_rect *rect;
- u8 i = 0;
- int err = 0;
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->open_mutex);
- init_waitqueue_head(&cam->wait_open);
- qctrl = s->qctrl;
- rect = &(s->cropcap.defrect);
- } else { /* use current values */
- qctrl = s->_qctrl;
- rect = &(s->_rect);
- }
-
- err += sn9c102_set_scale(cam, rect->width / s->pix_format.width);
- err += sn9c102_set_crop(cam, rect);
- if (err)
- return err;
-
- if (s->init) {
- err = s->init(cam);
- if (err) {
- DBG(3, "Sensor initialization failed");
- return err;
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED))
- if (cam->bridge == BRIDGE_SN9C101 ||
- cam->bridge == BRIDGE_SN9C102 ||
- cam->bridge == BRIDGE_SN9C103) {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- s->pix_format.pixelformat = V4L2_PIX_FMT_SBGGR8;
- cam->compression.quality = cam->reg[0x17] & 0x01 ?
- 0 : 1;
- } else {
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
- s->pix_format.pixelformat = V4L2_PIX_FMT_JPEG;
- cam->compression.quality = cam->reg[0x18] & 0x40 ?
- 0 : 1;
- err += sn9c102_set_compression(cam, &cam->compression);
- }
- else
- err += sn9c102_set_compression(cam, &cam->compression);
- err += sn9c102_set_pix_format(cam, &s->pix_format);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, &s->pix_format);
- if (err)
- return err;
-
- if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X ||
- s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG)
- DBG(3, "Compressed video format is active, quality %d",
- cam->compression.quality);
- else
- DBG(3, "Uncompressed video format is active");
-
- if (s->set_crop) {
- err = s->set_crop(cam, rect);
- if (err) {
- DBG(3, "set_crop() failed");
- return err;
- }
- }
-
- if (s->set_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (s->qctrl[i].id != 0 &&
- !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl.id = s->qctrl[i].id;
- ctrl.value = qctrl[i].default_value;
- err = s->set_ctrl(cam, &ctrl);
- if (err) {
- DBG(3, "Set %s control failed",
- s->qctrl[i].name);
- return err;
- }
- DBG(3, "Image sensor supports '%s' control",
- s->qctrl[i].name);
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->fileop_mutex);
- spin_lock_init(&cam->queue_lock);
- init_waitqueue_head(&cam->wait_frame);
- init_waitqueue_head(&cam->wait_stream);
- cam->nreadbuffers = 2;
- memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
- memcpy(&(s->_rect), &(s->cropcap.defrect),
- sizeof(struct v4l2_rect));
- cam->state |= DEV_INITIALIZED;
- }
-
- DBG(2, "Initialization succeeded");
- return 0;
-}
-
-/*****************************************************************************/
-
-static void sn9c102_release_resources(struct kref *kref)
-{
- struct sn9c102_device *cam;
-
- mutex_lock(&sn9c102_sysfs_lock);
-
- cam = container_of(kref, struct sn9c102_device, kref);
-
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
- video_set_drvdata(cam->v4ldev, NULL);
- video_unregister_device(cam->v4ldev);
- v4l2_device_unregister(&cam->v4l2_dev);
- usb_put_dev(cam->usbdev);
- kfree(cam->control_buffer);
- kfree(cam);
-
- mutex_unlock(&sn9c102_sysfs_lock);
-
-}
-
-
-static int sn9c102_open(struct file *filp)
-{
- struct sn9c102_device *cam;
- int err = 0;
-
- /*
- A read_trylock() in open() is the only safe way to prevent race
- conditions with disconnect(), one close() and multiple (not
- necessarily simultaneous) attempts to open(). For example, it
- prevents from waiting for a second access, while the device
- structure is being deallocated, after a possible disconnect() and
- during a following close() holding the write lock: given that, after
- this deallocation, no access will be possible anymore, using the
- non-trylock version would have let open() gain the access to the
- device structure improperly.
- For this reason the lock must also not be per-device.
- */
- if (!down_read_trylock(&sn9c102_dev_lock))
- return -ERESTARTSYS;
-
- cam = video_drvdata(filp);
-
- if (wait_for_completion_interruptible(&cam->probe)) {
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- kref_get(&cam->kref);
-
- /*
- Make sure to isolate all the simultaneous opens.
- */
- if (mutex_lock_interruptible(&cam->open_mutex)) {
- kref_put(&cam->kref, sn9c102_release_resources);
- up_read(&sn9c102_dev_lock);
- return -ERESTARTSYS;
- }
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- err = -ENODEV;
- goto out;
- }
-
- if (cam->users) {
- DBG(2, "Device %s is already in use",
- video_device_node_name(cam->v4ldev));
- DBG(3, "Simultaneous opens are not supported");
- /*
- open() must follow the open flags and should block
- eventually while the device is in use.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (filp->f_flags & O_NDELAY)) {
- err = -EWOULDBLOCK;
- goto out;
- }
- DBG(2, "A blocking open() has been requested. Wait for the "
- "device to be released...");
- up_read(&sn9c102_dev_lock);
- /*
- We will not release the "open_mutex" lock, so that only one
- process can be in the wait queue below. This way the process
- will be sleeping while holding the lock, without losing its
- priority after any wake_up().
- */
- err = wait_event_interruptible_exclusive(cam->wait_open,
- (cam->state & DEV_DISCONNECTED)
- || !cam->users);
- down_read(&sn9c102_dev_lock);
- if (err)
- goto out;
- if (cam->state & DEV_DISCONNECTED) {
- err = -ENODEV;
- goto out;
- }
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- err = sn9c102_init(cam);
- if (err) {
- DBG(1, "Initialization failed again. "
- "I will retry on next open().");
- goto out;
- }
- cam->state &= ~DEV_MISCONFIGURED;
- }
-
- err = sn9c102_start_transfer(cam);
- if (err)
- goto out;
-
- filp->private_data = cam;
- cam->users++;
- cam->io = IO_NONE;
- cam->stream = STREAM_OFF;
- cam->nbuffers = 0;
- cam->frame_count = 0;
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Video device %s is open", video_device_node_name(cam->v4ldev));
-
-out:
- mutex_unlock(&cam->open_mutex);
- if (err)
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_read(&sn9c102_dev_lock);
- return err;
-}
-
-
-static int sn9c102_release(struct file *filp)
-{
- struct sn9c102_device *cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = video_drvdata(filp);
-
- sn9c102_stop_transfer(cam);
- sn9c102_release_buffers(cam);
- cam->users--;
- wake_up_interruptible_nr(&cam->wait_open, 1);
-
- DBG(3, "Video device %s closed", video_device_node_name(cam->v4ldev));
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-
- return 0;
-}
-
-
-static ssize_t
-sn9c102_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t *f, *i;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (cam->io == IO_MMAP) {
- DBG(3, "Close and open the device again to choose "
- "the read method");
- mutex_unlock(&cam->fileop_mutex);
- return -EBUSY;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
- DBG(1, "read() failed, not enough memory");
- mutex_unlock(&cam->fileop_mutex);
- return -ENOMEM;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (list_empty(&cam->inqueue)) {
- if (!list_empty(&cam->outqueue))
- sn9c102_empty_framequeues(cam);
- sn9c102_queue_unusedframes(cam);
- }
-
- if (!count) {
- mutex_unlock(&cam->fileop_mutex);
- return 0;
- }
-
- if (list_empty(&cam->outqueue)) {
- if (filp->f_flags & O_NONBLOCK) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED));
- if (err) {
- mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- } else {
- timeout = wait_event_interruptible_timeout
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- msecs_to_jiffies(
- cam->module_param.frame_timeout * 1000
- )
- );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
- } else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED) {
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
- if (cam->state & DEV_MISCONFIGURED) {
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
-
- f = list_entry(cam->outqueue.prev, struct sn9c102_frame_t, frame);
-
- if (count > f->buf.bytesused)
- count = f->buf.bytesused;
-
- if (copy_to_user(buf, f->bufmem, count)) {
- err = -EFAULT;
- goto exit;
- }
- *f_pos += count;
-
-exit:
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(i, &cam->outqueue, frame)
- i->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- sn9c102_queue_unusedframes(cam);
-
- PDBGG("Frame #%lu, bytes read: %zu",
- (unsigned long)f->buf.index, count);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return count;
-}
-
-
-static unsigned int sn9c102_poll(struct file *filp, poll_table *wait)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- struct sn9c102_frame_t *f;
- unsigned long lock_flags;
- unsigned int mask = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return POLLERR;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- goto error;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- goto error;
- }
-
- if (cam->io == IO_NONE) {
- if (!sn9c102_request_buffers(cam, cam->nreadbuffers,
- IO_READ)) {
- DBG(1, "poll() failed, not enough memory");
- goto error;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (cam->io == IO_READ) {
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(f, &cam->outqueue, frame)
- f->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- sn9c102_queue_unusedframes(cam);
- }
-
- poll_wait(filp, &cam->wait_frame, wait);
-
- if (!list_empty(&cam->outqueue))
- mask |= POLLIN | POLLRDNORM;
-
- mutex_unlock(&cam->fileop_mutex);
-
- return mask;
-
-error:
- mutex_unlock(&cam->fileop_mutex);
- return POLLERR;
-}
-
-
-static void sn9c102_vm_open(struct vm_area_struct *vma)
-{
- struct sn9c102_frame_t *f = vma->vm_private_data;
- f->vma_use_count++;
-}
-
-
-static void sn9c102_vm_close(struct vm_area_struct *vma)
-{
- /* NOTE: buffers are not freed here */
- struct sn9c102_frame_t *f = vma->vm_private_data;
- f->vma_use_count--;
-}
-
-
-static const struct vm_operations_struct sn9c102_vm_ops = {
- .open = sn9c102_vm_open,
- .close = sn9c102_vm_close,
-};
-
-
-static int sn9c102_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- unsigned long size = vma->vm_end - vma->vm_start,
- start = vma->vm_start;
- void *pos;
- u32 i;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EACCES;
- }
-
- if (cam->io != IO_MMAP ||
- size != PAGE_ALIGN(cam->frame[0].buf.length)) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
- if (i == cam->nbuffers) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
-
- pos = cam->frame[i].bufmem;
- while (size > 0) { /* size is page-aligned */
- if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &sn9c102_vm_ops;
- vma->vm_private_data = &cam->frame[i];
- sn9c102_vm_open(vma);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int
-sn9c102_vidioc_querycap(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_capability cap = {
- .driver = "sn9c102",
- .version = LINUX_VERSION_CODE,
- .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING,
- };
-
- strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
- if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
- sizeof(cap.bus_info));
-
- if (copy_to_user(arg, &cap, sizeof(cap)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enuminput(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_input i;
-
- if (copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- if (i.index)
- return -EINVAL;
-
- memset(&i, 0, sizeof(i));
- strcpy(i.name, "Camera");
- i.type = V4L2_INPUT_TYPE_CAMERA;
- i.capabilities = V4L2_IN_CAP_STD;
-
- if (copy_to_user(arg, &i, sizeof(i)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_input(struct sn9c102_device *cam, void __user *arg)
-{
- int index = 0;
-
- if (copy_to_user(arg, &index, sizeof(index)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_input(struct sn9c102_device *cam, void __user *arg)
-{
- int index;
-
- if (copy_from_user(&index, arg, sizeof(index)))
- return -EFAULT;
-
- if (index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_query_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_queryctrl qc;
- u8 i;
-
- if (copy_from_user(&qc, arg, sizeof(qc)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (qc.id && qc.id == s->qctrl[i].id) {
- memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
- if (copy_to_user(arg, &qc, sizeof(qc)))
- return -EFAULT;
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int
-sn9c102_vidioc_g_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- int err = 0;
- u8 i;
-
- if (!s->get_ctrl && !s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- if (!s->get_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (ctrl.id && ctrl.id == s->qctrl[i].id) {
- ctrl.value = s->_qctrl[i].default_value;
- goto exit;
- }
- return -EINVAL;
- } else
- err = s->get_ctrl(cam, &ctrl);
-
-exit:
- if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
- return -EFAULT;
-
- PDBGG("VIDIOC_G_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return err;
-}
-
-
-static int
-sn9c102_vidioc_s_ctrl(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_control ctrl;
- u8 i;
- int err = 0;
-
- if (!s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
- if (ctrl.id == s->qctrl[i].id) {
- if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
- if (ctrl.value < s->qctrl[i].minimum ||
- ctrl.value > s->qctrl[i].maximum)
- return -ERANGE;
- ctrl.value -= ctrl.value % s->qctrl[i].step;
- break;
- }
- }
- if (i == ARRAY_SIZE(s->qctrl))
- return -EINVAL;
- err = s->set_ctrl(cam, &ctrl);
- if (err)
- return err;
-
- s->_qctrl[i].default_value = ctrl.value;
-
- PDBGG("VIDIOC_S_CTRL: id %lu, value %lu",
- (unsigned long)ctrl.id, (unsigned long)ctrl.value);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_cropcap(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_cropcap *cc = &(cam->sensor.cropcap);
-
- cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cc->pixelaspect.numerator = 1;
- cc->pixelaspect.denominator = 1;
-
- if (copy_to_user(arg, cc, sizeof(*cc)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_crop(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_crop crop = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- };
-
- memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
-
- if (copy_to_user(arg, &crop, sizeof(crop)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_crop(struct sn9c102_device *cam, void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_crop crop;
- struct v4l2_rect *rect;
- struct v4l2_rect *bounds = &(s->cropcap.bounds);
- struct v4l2_pix_format *pix_format = &(s->pix_format);
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&crop, arg, sizeof(crop)))
- return -EFAULT;
-
- rect = &(crop.c);
-
- if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_CROP failed. "
- "Unmap the buffers first.");
- return -EBUSY;
- }
-
- /* Preserve R,G or B origin */
- rect->left = (s->_rect.left & 1L) ? rect->left | 1L : rect->left & ~1L;
- rect->top = (s->_rect.top & 1L) ? rect->top | 1L : rect->top & ~1L;
-
- if (rect->width < 16)
- rect->width = 16;
- if (rect->height < 16)
- rect->height = 16;
- if (rect->width > bounds->width)
- rect->width = bounds->width;
- if (rect->height > bounds->height)
- rect->height = bounds->height;
- if (rect->left < bounds->left)
- rect->left = bounds->left;
- if (rect->top < bounds->top)
- rect->top = bounds->top;
- if (rect->left + rect->width > bounds->left + bounds->width)
- rect->left = bounds->left+bounds->width - rect->width;
- if (rect->top + rect->height > bounds->top + bounds->height)
- rect->top = bounds->top+bounds->height - rect->height;
-
- rect->width &= ~15L;
- rect->height &= ~15L;
-
- if (SN9C102_PRESERVE_IMGSCALE) {
- /* Calculate the actual scaling factor */
- u32 a, b;
- a = rect->width * rect->height;
- b = pix_format->width * pix_format->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- } else
- scale = 1;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- if (copy_to_user(arg, &crop, sizeof(crop))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err = sn9c102_set_crop(cam, rect);
- if (s->set_crop)
- err += s->set_crop(cam, rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- s->pix_format.width = rect->width/scale;
- s->pix_format.height = rect->height/scale;
- memcpy(&(s->_rect), rect, sizeof(*rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_framesizes(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_frmsizeenum frmsize;
-
- if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
- return -EFAULT;
-
- if (frmsize.index != 0)
- return -EINVAL;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (frmsize.pixel_format != V4L2_PIX_FMT_SN9C10X &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG &&
- frmsize.pixel_format != V4L2_PIX_FMT_SBGGR8)
- return -EINVAL;
- break;
- }
-
- frmsize.type = V4L2_FRMSIZE_TYPE_STEPWISE;
- frmsize.stepwise.min_width = frmsize.stepwise.step_width = 16;
- frmsize.stepwise.min_height = frmsize.stepwise.step_height = 16;
- frmsize.stepwise.max_width = cam->sensor.cropcap.bounds.width;
- frmsize.stepwise.max_height = cam->sensor.cropcap.bounds.height;
- memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
-
- if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enum_fmt(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_fmtdesc fmtd;
-
- if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
- return -EFAULT;
-
- if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (fmtd.index == 0) {
- strcpy(fmtd.description, "bayer rgb");
- fmtd.pixelformat = V4L2_PIX_FMT_SBGGR8;
- } else if (fmtd.index == 1) {
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- strcpy(fmtd.description, "compressed");
- fmtd.pixelformat = V4L2_PIX_FMT_SN9C10X;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- strcpy(fmtd.description, "JPEG");
- fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
- break;
- }
- fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
- } else
- return -EINVAL;
-
- fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
-
- if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_fmt(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_format format;
- struct v4l2_pix_format *pfmt = &(cam->sensor.pix_format);
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pfmt->bytesperline = (pfmt->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pfmt->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pfmt->width * pfmt->priv) / 8;
- pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
- pfmt->field = V4L2_FIELD_NONE;
- memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
-
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_try_s_fmt(struct sn9c102_device *cam, unsigned int cmd,
- void __user *arg)
-{
- struct sn9c102_sensor *s = &cam->sensor;
- struct v4l2_format format;
- struct v4l2_pix_format *pix;
- struct v4l2_pix_format *pfmt = &(s->pix_format);
- struct v4l2_rect *bounds = &(s->cropcap.bounds);
- struct v4l2_rect rect;
- u8 scale;
- const enum sn9c102_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- pix = &(format.fmt.pix);
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memcpy(&rect, &(s->_rect), sizeof(rect));
-
- { /* calculate the actual scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- rect.width = scale * pix->width;
- rect.height = scale * pix->height;
-
- if (rect.width < 16)
- rect.width = 16;
- if (rect.height < 16)
- rect.height = 16;
- if (rect.width > bounds->left + bounds->width - rect.left)
- rect.width = bounds->left + bounds->width - rect.left;
- if (rect.height > bounds->top + bounds->height - rect.top)
- rect.height = bounds->top + bounds->height - rect.top;
-
- rect.width &= ~15L;
- rect.height &= ~15L;
-
- { /* adjust the scaling factor */
- u32 a, b;
- a = rect.width * rect.height;
- b = pix->width * pix->height;
- scale = b ? (u8)((a / b) < 4 ? 1 : ((a / b) < 16 ? 2 : 4)) : 1;
- }
-
- pix->width = rect.width / scale;
- pix->height = rect.height / scale;
-
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat != V4L2_PIX_FMT_SN9C10X &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat != V4L2_PIX_FMT_JPEG &&
- pix->pixelformat != V4L2_PIX_FMT_SBGGR8)
- pix->pixelformat = pfmt->pixelformat;
- break;
- }
- pix->priv = pfmt->priv; /* bpp */
- pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_JPEG) ?
- V4L2_COLORSPACE_JPEG : V4L2_COLORSPACE_SRGB;
- pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_SN9C10X ||
- pix->pixelformat == V4L2_PIX_FMT_JPEG)
- ? 0 : (pix->width * pix->priv) / 8;
- pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
- pix->field = V4L2_FIELD_NONE;
-
- if (cmd == VIDIOC_TRY_FMT) {
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
- return 0;
- }
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_FMT failed. Unmap the "
- "buffers first.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- if (copy_to_user(arg, &format, sizeof(format))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- sn9c102_release_buffers(cam);
-
- err += sn9c102_set_pix_format(cam, pix);
- err += sn9c102_set_crop(cam, &rect);
- if (s->set_pix_format)
- err += s->set_pix_format(cam, pix);
- if (s->set_crop)
- err += s->set_crop(cam, &rect);
- err += sn9c102_set_scale(cam, scale);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- memcpy(pfmt, pix, sizeof(*pix));
- memcpy(&(s->_rect), &rect, sizeof(rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != sn9c102_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- sn9c102_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- sn9c102_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_jpegcomp(struct sn9c102_device *cam, void __user *arg)
-{
- if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_jpegcomp(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_jpegcompression jc;
- const enum sn9c102_stream_state stream = cam->stream;
- int err = 0;
-
- if (copy_from_user(&jc, arg, sizeof(jc)))
- return -EFAULT;
-
- if (jc.quality != 0 && jc.quality != 1)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- err += sn9c102_set_compression(cam, &jc);
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware problems. "
- "To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- cam->compression.quality = jc.quality;
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_reqbufs(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_requestbuffers rb;
- u32 i;
- int err;
-
- if (copy_from_user(&rb, arg, sizeof(rb)))
- return -EFAULT;
-
- if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- rb.memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (cam->io == IO_READ) {
- DBG(3, "Close and open the device again to choose the mmap "
- "I/O method");
- return -EBUSY;
- }
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_REQBUFS failed. Previous buffers are "
- "still mapped.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- sn9c102_empty_framequeues(cam);
-
- sn9c102_release_buffers(cam);
- if (rb.count)
- rb.count = sn9c102_request_buffers(cam, rb.count, IO_MMAP);
-
- if (copy_to_user(arg, &rb, sizeof(rb))) {
- sn9c102_release_buffers(cam);
- cam->io = IO_NONE;
- return -EFAULT;
- }
-
- cam->io = rb.count ? IO_MMAP : IO_NONE;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_querybuf(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_buffer b;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- b = cam->frame[b.index].buf;
-
- if (cam->frame[b.index].vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (cam->frame[b.index].state == F_DONE)
- b.flags |= V4L2_BUF_FLAG_DONE;
- else if (cam->frame[b.index].state != F_UNUSED)
- b.flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_qbuf(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_buffer b;
- unsigned long lock_flags;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->frame[b.index].state != F_UNUSED)
- return -EINVAL;
-
- cam->frame[b.index].state = F_QUEUED;
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- PDBGG("Frame #%lu queued", (unsigned long)b.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_dqbuf(struct sn9c102_device *cam, struct file *filp,
- void __user *arg)
-{
- struct v4l2_buffer b;
- struct sn9c102_frame_t *f;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (list_empty(&cam->outqueue)) {
- if (cam->stream == STREAM_OFF)
- return -EINVAL;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- if (!cam->module_param.frame_timeout) {
- err = wait_event_interruptible
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED));
- if (err)
- return err;
- } else {
- timeout = wait_event_interruptible_timeout
- (cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1));
- if (timeout < 0)
- return timeout;
- else if (timeout == 0 &&
- !(cam->state & DEV_DISCONNECTED)) {
- DBG(1, "Video frame timeout elapsed");
- return -EIO;
- }
- }
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- if (cam->state & DEV_MISCONFIGURED)
- return -EIO;
- }
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- f = list_entry(cam->outqueue.next, struct sn9c102_frame_t, frame);
- list_del(cam->outqueue.next);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- f->state = F_UNUSED;
-
- b = f->buf;
- if (f->vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamon(struct sn9c102_device *cam, void __user *arg)
-{
- int type;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- cam->stream = STREAM_ON;
-
- DBG(3, "Stream on");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_streamoff(struct sn9c102_device *cam, void __user *arg)
-{
- int type, err;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON) {
- err = sn9c102_stream_interrupt(cam);
- if (err)
- return err;
- }
-
- sn9c102_empty_framequeues(cam);
-
- DBG(3, "Stream off");
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_parm(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_parm(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
-
- if (sp.parm.capture.readbuffers == 0)
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (sp.parm.capture.readbuffers > SN9C102_MAX_FRAMES)
- sp.parm.capture.readbuffers = SN9C102_MAX_FRAMES;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- cam->nreadbuffers = sp.parm.capture.readbuffers;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_enumaudio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- strcpy(audio.name, "Microphone");
- audio.capability = 0;
- audio.mode = 0;
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_g_audio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- memset(&audio, 0, sizeof(audio));
- strcpy(audio.name, "Microphone");
-
- if (copy_to_user(arg, &audio, sizeof(audio)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-sn9c102_vidioc_s_audio(struct sn9c102_device *cam, void __user *arg)
-{
- struct v4l2_audio audio;
-
- if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
- return -EINVAL;
-
- if (copy_from_user(&audio, arg, sizeof(audio)))
- return -EFAULT;
-
- if (audio.index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static long sn9c102_ioctl_v4l2(struct file *filp,
- unsigned int cmd, void __user *arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
-
- switch (cmd) {
-
- case VIDIOC_QUERYCAP:
- return sn9c102_vidioc_querycap(cam, arg);
-
- case VIDIOC_ENUMINPUT:
- return sn9c102_vidioc_enuminput(cam, arg);
-
- case VIDIOC_G_INPUT:
- return sn9c102_vidioc_g_input(cam, arg);
-
- case VIDIOC_S_INPUT:
- return sn9c102_vidioc_s_input(cam, arg);
-
- case VIDIOC_QUERYCTRL:
- return sn9c102_vidioc_query_ctrl(cam, arg);
-
- case VIDIOC_G_CTRL:
- return sn9c102_vidioc_g_ctrl(cam, arg);
-
- case VIDIOC_S_CTRL:
- return sn9c102_vidioc_s_ctrl(cam, arg);
-
- case VIDIOC_CROPCAP:
- return sn9c102_vidioc_cropcap(cam, arg);
-
- case VIDIOC_G_CROP:
- return sn9c102_vidioc_g_crop(cam, arg);
-
- case VIDIOC_S_CROP:
- return sn9c102_vidioc_s_crop(cam, arg);
-
- case VIDIOC_ENUM_FRAMESIZES:
- return sn9c102_vidioc_enum_framesizes(cam, arg);
-
- case VIDIOC_ENUM_FMT:
- return sn9c102_vidioc_enum_fmt(cam, arg);
-
- case VIDIOC_G_FMT:
- return sn9c102_vidioc_g_fmt(cam, arg);
-
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT:
- return sn9c102_vidioc_try_s_fmt(cam, cmd, arg);
-
- case VIDIOC_G_JPEGCOMP:
- return sn9c102_vidioc_g_jpegcomp(cam, arg);
-
- case VIDIOC_S_JPEGCOMP:
- return sn9c102_vidioc_s_jpegcomp(cam, arg);
-
- case VIDIOC_REQBUFS:
- return sn9c102_vidioc_reqbufs(cam, arg);
-
- case VIDIOC_QUERYBUF:
- return sn9c102_vidioc_querybuf(cam, arg);
-
- case VIDIOC_QBUF:
- return sn9c102_vidioc_qbuf(cam, arg);
-
- case VIDIOC_DQBUF:
- return sn9c102_vidioc_dqbuf(cam, filp, arg);
-
- case VIDIOC_STREAMON:
- return sn9c102_vidioc_streamon(cam, arg);
-
- case VIDIOC_STREAMOFF:
- return sn9c102_vidioc_streamoff(cam, arg);
-
- case VIDIOC_G_PARM:
- return sn9c102_vidioc_g_parm(cam, arg);
-
- case VIDIOC_S_PARM:
- return sn9c102_vidioc_s_parm(cam, arg);
-
- case VIDIOC_ENUMAUDIO:
- return sn9c102_vidioc_enumaudio(cam, arg);
-
- case VIDIOC_G_AUDIO:
- return sn9c102_vidioc_g_audio(cam, arg);
-
- case VIDIOC_S_AUDIO:
- return sn9c102_vidioc_s_audio(cam, arg);
-
- default:
- return -ENOTTY;
-
- }
-}
-
-
-static long sn9c102_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct sn9c102_device *cam = video_drvdata(filp);
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- V4LDBG(3, "sn9c102", cmd);
-
- err = sn9c102_ioctl_v4l2(filp, cmd, (void __user *)arg);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return err;
-}
-
-/*****************************************************************************/
-
-static const struct v4l2_file_operations sn9c102_fops = {
- .owner = THIS_MODULE,
- .open = sn9c102_open,
- .release = sn9c102_release,
- .unlocked_ioctl = sn9c102_ioctl,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
-};
-
-/*****************************************************************************/
-
-/* It exists a single interface only. We do not need to validate anything. */
-static int
-sn9c102_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct sn9c102_device *cam;
- static unsigned int dev_nr;
- unsigned int i;
- int err = 0, r;
-
- cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
- cam->usbdev = udev;
-
- /* register v4l2_device early so it can be used for printks */
- if (v4l2_device_register(&intf->dev, &cam->v4l2_dev)) {
- dev_err(&intf->dev, "v4l2_device_register failed\n");
- err = -ENOMEM;
- goto fail;
- }
-
- cam->control_buffer = kzalloc(8, GFP_KERNEL);
- if (!cam->control_buffer) {
- DBG(1, "kzalloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- cam->v4ldev = video_device_alloc();
- if (!cam->v4ldev) {
- DBG(1, "video_device_alloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- r = sn9c102_read_reg(cam, 0x00);
- if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) {
- DBG(1, "Sorry, this is not a SN9C1xx-based camera "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- err = -ENODEV;
- goto fail;
- }
-
- cam->bridge = id->driver_info;
- switch (cam->bridge) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- DBG(2, "SN9C10[12] PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C103:
- DBG(2, "SN9C103 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C105:
- DBG(2, "SN9C105 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- case BRIDGE_SN9C120:
- DBG(2, "SN9C120 PC Camera Controller detected "
- "(vid:pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
- err = sn9c102_sensor_table[i](cam);
- if (!err)
- break;
- }
-
- if (!err) {
- DBG(2, "%s image sensor detected", cam->sensor.name);
- DBG(3, "Support for %s maintained by %s",
- cam->sensor.name, cam->sensor.maintainer);
- } else {
- DBG(1, "No supported image sensor detected for this bridge");
- err = -ENODEV;
- goto fail;
- }
-
- if (!(cam->bridge & cam->sensor.supported_bridge)) {
- DBG(1, "Bridge not supported");
- err = -ENODEV;
- goto fail;
- }
-
- if (sn9c102_init(cam)) {
- DBG(1, "Initialization failed. I will retry on open().");
- cam->state |= DEV_MISCONFIGURED;
- }
-
- strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
- cam->v4ldev->fops = &sn9c102_fops;
- cam->v4ldev->release = video_device_release;
- cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
-
- init_completion(&cam->probe);
-
- err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
- video_nr[dev_nr]);
- if (err) {
- DBG(1, "V4L2 device registration failed");
- if (err == -ENFILE && video_nr[dev_nr] == -1)
- DBG(1, "Free /dev/videoX node not found");
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
- complete_all(&cam->probe);
- goto fail;
- }
-
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
-
- video_set_drvdata(cam->v4ldev, cam);
- cam->module_param.force_munmap = force_munmap[dev_nr];
- cam->module_param.frame_timeout = frame_timeout[dev_nr];
-
- dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- err = sn9c102_create_sysfs(cam);
- if (!err)
- DBG(2, "Optional device control through 'sysfs' "
- "interface ready");
- else
- DBG(2, "Failed to create optional 'sysfs' interface for "
- "device controlling. Error #%d", err);
-#else
- DBG(2, "Optional device control through 'sysfs' interface disabled");
- DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' "
- "configuration option to enable it.");
-#endif
-
- usb_set_intfdata(intf, cam);
- kref_init(&cam->kref);
- usb_get_dev(cam->usbdev);
-
- complete_all(&cam->probe);
-
- return 0;
-
-fail:
- if (cam) {
- kfree(cam->control_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
- v4l2_device_unregister(&cam->v4l2_dev);
- kfree(cam);
- }
- return err;
-}
-
-
-static void sn9c102_usb_disconnect(struct usb_interface *intf)
-{
- struct sn9c102_device *cam;
-
- down_write(&sn9c102_dev_lock);
-
- cam = usb_get_intfdata(intf);
-
- DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-
- if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and memory "
- "deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
- cam->state |= DEV_MISCONFIGURED;
- sn9c102_stop_transfer(cam);
- cam->state |= DEV_DISCONNECTED;
- wake_up_interruptible(&cam->wait_frame);
- wake_up(&cam->wait_stream);
- } else
- cam->state |= DEV_DISCONNECTED;
-
- wake_up_interruptible_all(&cam->wait_open);
-
- v4l2_device_disconnect(&cam->v4l2_dev);
-
- kref_put(&cam->kref, sn9c102_release_resources);
-
- up_write(&sn9c102_dev_lock);
-}
-
-
-static struct usb_driver sn9c102_usb_driver = {
- .name = "sn9c102",
- .id_table = sn9c102_id_table,
- .probe = sn9c102_usb_probe,
- .disconnect = sn9c102_usb_disconnect,
-};
-
-module_usb_driver(sn9c102_usb_driver);
diff --git a/drivers/staging/media/sn9c102/sn9c102_devtable.h b/drivers/staging/media/sn9c102/sn9c102_devtable.h
deleted file mode 100644
index b187a8a304eb..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_devtable.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/***************************************************************************
- * Table of device identifiers of the SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_DEVTABLE_H_
-#define _SN9C102_DEVTABLE_H_
-
-#include <linux/usb.h>
-
-struct sn9c102_device;
-
-/*
- Each SN9C1xx camera has proper PID/VID identifiers.
- SN9C103, SN9C105, SN9C120 support multiple interfaces, but we only have to
- handle the video class interface.
-*/
-#define SN9C102_USB_DEVICE(vend, prod, bridge) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = (vend), \
- .idProduct = (prod), \
- .bInterfaceClass = 0xff, \
- .driver_info = (bridge)
-
-static const struct usb_device_id sn9c102_id_table[] = {
- /* SN9C101 and SN9C102 */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x6001, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */
- { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6028, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
- { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */
- { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
-#endif
- { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, /* not in sonixb */
- /* SN9C103 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, /* not in sonixb */
-#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */
- { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5110, non existent */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, non existent ? */
- { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ba, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bb, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, non existent ? */
-#endif
- /* SN9C105 */
-#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE
- { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, PO1030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, OM6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, HV7131GP */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, non existent ? */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, MO4000 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, ICM105C */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, OV7648 */
- { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
- { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
- /* SN9C120 */
- { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, po2030 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, om6801 */
-/* { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, S5K53BEB */
- { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), },
-/* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */
- { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
- { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
-#endif
- { }
-};
-
-/*
- Probing functions: on success, you must attach the sensor to the camera
- by calling sn9c102_attach_sensor().
- To enable the I2C communication, you might need to perform a really basic
- initialization of the SN9C1XX chip.
- Functions must return 0 on success, the appropriate error otherwise.
-*/
-extern int sn9c102_probe_hv7131d(struct sn9c102_device *cam);
-extern int sn9c102_probe_hv7131r(struct sn9c102_device *cam);
-extern int sn9c102_probe_mi0343(struct sn9c102_device *cam);
-extern int sn9c102_probe_mi0360(struct sn9c102_device *cam);
-extern int sn9c102_probe_mt9v111(struct sn9c102_device *cam);
-extern int sn9c102_probe_ov7630(struct sn9c102_device *cam);
-extern int sn9c102_probe_ov7660(struct sn9c102_device *cam);
-extern int sn9c102_probe_pas106b(struct sn9c102_device *cam);
-extern int sn9c102_probe_pas202bcb(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5110c1b(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5110d(struct sn9c102_device *cam);
-extern int sn9c102_probe_tas5130d1b(struct sn9c102_device *cam);
-
-#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
deleted file mode 100644
index f1d94f0190c6..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131D image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131d_init(struct sn9c102_device *cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x60, 0x17},
- {0x0e, 0x18}, {0xf2, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- err += sn9c102_i2c_write(cam, 0x02, 0x00);
- err += sn9c102_i2c_write(cam, 0x28, 0x00);
-
- return err;
-}
-
-
-static int hv7131d_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x26),
- r2 = sn9c102_i2c_read(cam, 0x27);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 8) | (r2 & 0xff);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x31);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x33);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x32);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = 0x3f - (ctrl->value & 0x3f);
- return 0;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- ctrl->value = sn9c102_i2c_read(cam, 0x30);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- return 0;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- ctrl->value = sn9c102_i2c_read(cam, 0x34);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x07;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131d_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x26, ctrl->value >> 8);
- err += sn9c102_i2c_write(cam, 0x27, ctrl->value & 0xff);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, 0x3f - ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, 0x3f - ctrl->value);
- break;
- case SN9C102_V4L2_CID_RESET_LEVEL:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE:
- err += sn9c102_i2c_write(cam, 0x34, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131d_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131d_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x42, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xf2, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131d = {
- .name = "HV7131D",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131d_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x0250,
- .maximum = 0xffff,
- .step = 0x0001,
- .default_value = 0x0250,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1e,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_RESET_LEVEL,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "reset level",
- .minimum = 0x19,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x30,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "pixel bias voltage",
- .minimum = 0x00,
- .maximum = 0x07,
- .step = 0x01,
- .default_value = 0x02,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131d_get_ctrl,
- .set_ctrl = &hv7131d_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131d_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131d_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131d(struct sn9c102_device *cam)
-{
- int r0 = 0, r1 = 0, err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
-
- r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (err || r0 < 0 || r1 < 0)
- return -EIO;
-
- if ((r0 != 0x00 && r0 != 0x01) || r1 != 0x04)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131d);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
deleted file mode 100644
index 51b24e000e88..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/***************************************************************************
- * Plug-in for HV7131R image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int hv7131r_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x03}, {0x1a, 0x04},
- {0x20, 0x05}, {0x20, 0x06},
- {0x03, 0x10}, {0x00, 0x14},
- {0x60, 0x17}, {0x0a, 0x18},
- {0xf0, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x44, 0x05}, {0x3e, 0x06},
- {0x1a, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa3, 0x17},
- {0x4b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_write(cam, 0x20, 0x00);
- err += sn9c102_i2c_write(cam, 0x21, 0xd6);
- err += sn9c102_i2c_write(cam, 0x25, 0x06);
-
- return err;
-}
-
-
-static int hv7131r_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x30);
- if (ctrl->value < 0)
- return -EIO;
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x31);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x33);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x32);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = ctrl->value & 0x3f;
- return 0;
- case V4L2_CID_BLACK_LEVEL:
- ctrl->value = sn9c102_i2c_read(cam, 0x01);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x08) ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int hv7131r_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x30, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x31, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x33, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x32, ctrl->value);
- break;
- case V4L2_CID_BLACK_LEVEL:
- {
- int r = sn9c102_i2c_read(cam, 0x01);
-
- if (r < 0)
- return -EIO;
- err += sn9c102_i2c_write(cam, 0x01,
- (ctrl->value<<3) | (r&0xf7));
- }
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int hv7131r_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int hv7131r_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0x30, 0x19);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xa5, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x24);
- } else {
- err += sn9c102_write_reg(cam, 0xa3, 0x17);
- err += sn9c102_i2c_write(cam, 0x01, 0x04);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor hv7131r = {
- .name = "HV7131R",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x11,
- .init = &hv7131r_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x40,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x08,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x1a,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x2f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLACK_LEVEL,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto black level compensation",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &hv7131r_get_ctrl,
- .set_ctrl = &hv7131r_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &hv7131r_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &hv7131r_set_pix_format
-};
-
-
-int sn9c102_probe_hv7131r(struct sn9c102_device *cam)
-{
- int devid, err;
-
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x02},
- {0x34, 0x01}, {0x20, 0x17},
- {0x34, 0x01}, {0x46, 0x01});
-
- devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
- if (err || devid < 0)
- return -EIO;
-
- if (devid != 0x02)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &hv7131r);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0343.c b/drivers/staging/media/sn9c102/sn9c102_mi0343.c
deleted file mode 100644
index b20fdb6541d3..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mi0343.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0343 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0343_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0343_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- break;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- break;
- default:
- return -EINVAL;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = data[1] | (data[0] << 8);
- if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
- ctrl->value -= 0x10;
- else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
- ctrl->value -= 0x60;
- else if (ctrl->value >= 0xe0 && ctrl->value <= 0xff)
- ctrl->value -= 0xe0;
- }
-
- return 0;
-}
-
-
-static int mi0343_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u16 reg = 0;
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- case V4L2_CID_RED_BALANCE:
- case V4L2_CID_BLUE_BALANCE:
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (ctrl->value <= (0x3f-0x10))
- reg = 0x10 + ctrl->value;
- else if (ctrl->value <= ((0x3f-0x10) + (0x7f-0x60)))
- reg = 0x60 + (ctrl->value - (0x3f-0x10));
- else
- reg = 0xe0 + (ctrl->value - (0x3f-0x10) - (0x7f-0x60));
- break;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, reg >> 8, reg & 0xff,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, reg >> 8, reg & 0xff,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0343_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0343_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x03, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0xa0, 0x19);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0343 = {
- .name = "MI-0343",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0343_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x06,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),/*0x6d*/
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = (0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = ((0x3f-0x10)+(0x7f-0x60)+(0xff-0xe0)),
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0343_get_ctrl,
- .set_ctrl = &mi0343_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0343_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0343_set_pix_format
-};
-
-
-int sn9c102_probe_mi0343(struct sn9c102_device *cam)
-{
- u8 data[2];
-
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[1] != 0x42 || data[0] != 0xe3)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0343);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0360.c b/drivers/staging/media/sn9c102/sn9c102_mi0360.c
deleted file mode 100644
index 5f21d1b43e32..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mi0360.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/***************************************************************************
- * Plug-in for MI-0360 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mi0360_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x50, 0x05}, {0x20, 0x06},
- {0x10, 0x07}, {0x03, 0x10},
- {0x08, 0x14}, {0xa2, 0x17},
- {0x47, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3F},
- {0xC7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xC7, 0x48}, {0x01, 0x49},
- {0xC7, 0x4A}, {0x01, 0x4B},
- {0xC7, 0x4C}, {0x01, 0x4D},
- {0x44, 0x4E}, {0x00, 0x4F},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xC7, 0x54}, {0x01, 0x55},
- {0xC7, 0x56}, {0x01, 0x57},
- {0xC7, 0x58}, {0x01, 0x59},
- {0x44, 0x5A}, {0x00, 0x5B},
- {0x44, 0x5C}, {0x00, 0x5D},
- {0x44, 0x5E}, {0x00, 0x5F},
- {0xC7, 0x60}, {0x01, 0x61},
- {0xC7, 0x62}, {0x01, 0x63},
- {0xC7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6A}, {0x00, 0x6B},
- {0xC7, 0x6C}, {0x01, 0x6D},
- {0xC7, 0x6E}, {0x01, 0x6F},
- {0xC7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xC7, 0x78}, {0x01, 0x79},
- {0xC7, 0x7A}, {0x01, 0x7B},
- {0xC7, 0x7C}, {0x01, 0x7D},
- {0x44, 0x7E}, {0x00, 0x7F},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xEC, 0x8A}, {0x0f, 0x8B},
- {0xD8, 0x8C}, {0x0f, 0x8D},
- {0x3D, 0x8E}, {0x00, 0x8F},
- {0x3D, 0x90}, {0x00, 0x91},
- {0xCD, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0C, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9A}, {0x00, 0x9B},
- {0x04, 0x9C}, {0x00, 0x9D},
- {0x08, 0x9E}, {0x00, 0x9F},
- {0x2D, 0xC0}, {0x2D, 0xC1},
- {0x3A, 0xC2}, {0x05, 0xC3},
- {0x04, 0xC4}, {0x3F, 0xC5},
- {0x00, 0xC6}, {0x00, 0xC7},
- {0x50, 0xC8}, {0x3C, 0xC9},
- {0x28, 0xCA}, {0xD8, 0xCB},
- {0x14, 0xCC}, {0xEC, 0xCD},
- {0x32, 0xCE}, {0xDD, 0xCF},
- {0x32, 0xD0}, {0xDD, 0xD1},
- {0x6A, 0xD2}, {0x50, 0xD3},
- {0x00, 0xD4}, {0x00, 0xD5},
- {0x00, 0xD6});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe1, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x81, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x17, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x11, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x62,
- 0x04, 0x9a, 0, 0);
-
- return err;
-}
-
-
-static int mi0360_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[0];
- return 0;
- case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1];
- return 0;
- case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x20 ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-static int mi0360_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x09, ctrl->value, 0x00,
- 0, 0);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x35, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2c, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2d, 0x03, ctrl->value,
- 0, 0);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2b, 0x03, ctrl->value,
- 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x2e, 0x03, ctrl->value,
- 0, 0);
- break;
- case V4L2_CID_HFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x40:0x00,
- ctrl->value ? 0x20:0x00,
- 0, 0);
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20, ctrl->value ? 0x80:0x00,
- ctrl->value ? 0x80:0x00,
- 0, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int mi0360_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int mi0360_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x05, 0, 0);
- err += sn9c102_write_reg(cam, 0x60, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa6, 0x17);
- } else {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x02, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
- sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mi0360 = {
- .name = "MI-0360",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5d,
- .init = &mi0360_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x0f,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x32,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x25,
- .flags = 0,
- },
- },
- .get_ctrl = &mi0360_get_ctrl,
- .set_ctrl = &mi0360_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mi0360_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mi0360_set_pix_format
-};
-
-
-int sn9c102_probe_mi0360(struct sn9c102_device *cam)
-{
-
- u8 data[2];
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C103:
- if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17}))
- return -EIO;
- break;
- default:
- break;
- }
-
- if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
- 2, data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x43)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mi0360);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_mt9v111.c b/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
deleted file mode 100644
index 95986eb492e4..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_mt9v111.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/***************************************************************************
- * Plug-in for MT9V111 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int mt9v111_init(struct sn9c102_device *cam)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x1f, 0x05}, {0x20, 0x06},
- {0x1f, 0x07}, {0x81, 0x08},
- {0x5c, 0x09}, {0x00, 0x0a},
- {0x00, 0x0b}, {0x00, 0x0c},
- {0x00, 0x0d}, {0x00, 0x0e},
- {0x00, 0x0f}, {0x03, 0x10},
- {0x00, 0x11}, {0x00, 0x12},
- {0x02, 0x13}, {0x14, 0x14},
- {0x28, 0x15}, {0x1e, 0x16},
- {0xe2, 0x17}, {0x06, 0x18},
- {0x00, 0x19}, {0x00, 0x1a},
- {0x00, 0x1b}, {0x08, 0x20},
- {0x39, 0x21}, {0x51, 0x22},
- {0x63, 0x23}, {0x73, 0x24},
- {0x82, 0x25}, {0x8f, 0x26},
- {0x9b, 0x27}, {0xa7, 0x28},
- {0xb1, 0x29}, {0xbc, 0x2a},
- {0xc6, 0x2b}, {0xcf, 0x2c},
- {0xd8, 0x2d}, {0xe1, 0x2e},
- {0xea, 0x2f}, {0xf2, 0x30},
- {0x13, 0x84}, {0x00, 0x85},
- {0x25, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xee, 0x8a}, {0x0f, 0x8b},
- {0xe5, 0x8c}, {0x0f, 0x8d},
- {0x2e, 0x8e}, {0x00, 0x8f},
- {0x30, 0x90}, {0x00, 0x91},
- {0xd4, 0x92}, {0x0f, 0x93},
- {0xfc, 0x94}, {0x0f, 0x95},
- {0x14, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x60, 0x99},
- {0x07, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x05, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x2d, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x01, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x04, 0x80, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x08,
- 0x00, 0x08, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x02,
- 0x00, 0x16, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x03,
- 0x01, 0xe7, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x04,
- 0x02, 0x87, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x06,
- 0x00, 0x40, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x05,
- 0x00, 0x09, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x07,
- 0x30, 0x02, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0c,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x12,
- 0x00, 0xb0, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x13,
- 0x00, 0x7c, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x1e,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x20,
- 0x00, 0x00, 0, 0);
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x01,
- 0x00, 0x04, 0, 0);
-
- return err;
-}
-
-static int mt9v111_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 data[2];
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
- data) < 0)
- return -EIO;
- ctrl->value = data[1] & 0x80 ? 1 : 0;
- return 0;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x20,
- ctrl->value ? 0x80 : 0x00,
- ctrl->value ? 0x80 : 0x00, 0,
- 0);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-static int mt9v111_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 v_start = (u8) (rect->top - s->cropcap.bounds.top) + 2;
-
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-static int mt9v111_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xb4, 0x17);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor mt9v111 = {
- .name = "MT9V111",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x5c,
- .init = &mt9v111_init,
- .qctrl = {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- },
- },
- .get_ctrl = &mt9v111_get_ctrl,
- .set_ctrl = &mt9v111_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &mt9v111_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &mt9v111_set_pix_format
-};
-
-
-int sn9c102_probe_mt9v111(struct sn9c102_device *cam)
-{
- u8 data[2];
- int err = 0;
-
- err += sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x42, 0x17},
- {0x62, 0x17}, {0x08, 0x01});
- err += sn9c102_i2c_try_raw_write(cam, &mt9v111, 4,
- mt9v111.i2c_slave_id, 0x01, 0x00,
- 0x04, 0, 0);
- if (err || sn9c102_i2c_try_raw_read(cam, &mt9v111,
- mt9v111.i2c_slave_id, 0x36, 2,
- data) < 0)
- return -EIO;
-
- if (data[0] != 0x82 || data[1] != 0x3a)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &mt9v111);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7630.c b/drivers/staging/media/sn9c102/sn9c102_ov7630.c
deleted file mode 100644
index 9ec304dc4705..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_ov7630.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7630 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int ov7630_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
- {0x0f, 0x18}, {0x50, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x15, 0x35);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1c);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x06);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x20, 0x05},
- {0x20, 0x06}, {0x20, 0x07},
- {0x03, 0x10}, {0x0a, 0x14},
- {0x60, 0x17}, {0x0f, 0x18},
- {0x50, 0x19}, {0x1d, 0x1a},
- {0x10, 0x1b}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x8d);
- err += sn9c102_i2c_write(cam, 0x12, 0x0d);
- err += sn9c102_i2c_write(cam, 0x15, 0x34);
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x20, 0x44);
- err += sn9c102_i2c_write(cam, 0x23, 0xee);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0x9a);
- err += sn9c102_i2c_write(cam, 0x28, 0x20);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
- err += sn9c102_i2c_write(cam, 0x30, 0x24);
- err += sn9c102_i2c_write(cam, 0x32, 0x86);
- err += sn9c102_i2c_write(cam, 0x60, 0xa9);
- err += sn9c102_i2c_write(cam, 0x61, 0x42);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x88);
- err += sn9c102_i2c_write(cam, 0x70, 0x0b);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x74, 0x21);
- err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x03, 0x10},
- {0x0a, 0x14}, {0xe2, 0x17},
- {0x0b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x24, 0x21},
- {0x3b, 0x22}, {0x47, 0x23},
- {0x60, 0x24}, {0x71, 0x25},
- {0x80, 0x26}, {0x8f, 0x27},
- {0x9d, 0x28}, {0xaa, 0x29},
- {0xb8, 0x2a}, {0xc4, 0x2b},
- {0xd1, 0x2c}, {0xdd, 0x2d},
- {0xe8, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3f},
- {0xc7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xc7, 0x48}, {0x01, 0x49},
- {0xc7, 0x4a}, {0x01, 0x4b},
- {0xc7, 0x4c}, {0x01, 0x4d},
- {0x44, 0x4e}, {0x00, 0x4f},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xc7, 0x54}, {0x01, 0x55},
- {0xc7, 0x56}, {0x01, 0x57},
- {0xc7, 0x58}, {0x01, 0x59},
- {0x44, 0x5a}, {0x00, 0x5b},
- {0x44, 0x5c}, {0x00, 0x5d},
- {0x44, 0x5e}, {0x00, 0x5f},
- {0xc7, 0x60}, {0x01, 0x61},
- {0xc7, 0x62}, {0x01, 0x63},
- {0xc7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6a}, {0x00, 0x6b},
- {0xc7, 0x6c}, {0x01, 0x6d},
- {0xc7, 0x6e}, {0x01, 0x6f},
- {0xc7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xc7, 0x78}, {0x01, 0x79},
- {0xc7, 0x7a}, {0x01, 0x7b},
- {0xc7, 0x7c}, {0x01, 0x7d},
- {0x44, 0x7e}, {0x00, 0x7f},
- {0x17, 0x84}, {0x00, 0x85},
- {0x2e, 0x86}, {0x00, 0x87},
- {0x09, 0x88}, {0x00, 0x89},
- {0xe8, 0x8a}, {0x0f, 0x8b},
- {0xda, 0x8c}, {0x0f, 0x8d},
- {0x40, 0x8e}, {0x00, 0x8f},
- {0x37, 0x90}, {0x00, 0x91},
- {0xcf, 0x92}, {0x0f, 0x93},
- {0xfa, 0x94}, {0x0f, 0x95},
- {0x00, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x00, 0x9a}, {0x40, 0x9b},
- {0x20, 0x9c}, {0x00, 0x9d},
- {0x00, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x00, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3c, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x32, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x60, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x80);
- err += sn9c102_i2c_write(cam, 0x12, 0x48);
- err += sn9c102_i2c_write(cam, 0x01, 0x80);
- err += sn9c102_i2c_write(cam, 0x02, 0x80);
- err += sn9c102_i2c_write(cam, 0x03, 0x80);
- err += sn9c102_i2c_write(cam, 0x04, 0x10);
- err += sn9c102_i2c_write(cam, 0x05, 0x20);
- err += sn9c102_i2c_write(cam, 0x06, 0x80);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- err += sn9c102_i2c_write(cam, 0x0c, 0x20);
- err += sn9c102_i2c_write(cam, 0x0d, 0x20);
- err += sn9c102_i2c_write(cam, 0x15, 0x80);
- err += sn9c102_i2c_write(cam, 0x16, 0x03);
- err += sn9c102_i2c_write(cam, 0x17, 0x1b);
- err += sn9c102_i2c_write(cam, 0x18, 0xbd);
- err += sn9c102_i2c_write(cam, 0x19, 0x05);
- err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
- err += sn9c102_i2c_write(cam, 0x1b, 0x04);
- err += sn9c102_i2c_write(cam, 0x21, 0x1b);
- err += sn9c102_i2c_write(cam, 0x22, 0x00);
- err += sn9c102_i2c_write(cam, 0x23, 0xde);
- err += sn9c102_i2c_write(cam, 0x24, 0x10);
- err += sn9c102_i2c_write(cam, 0x25, 0x8a);
- err += sn9c102_i2c_write(cam, 0x26, 0xa0);
- err += sn9c102_i2c_write(cam, 0x27, 0xca);
- err += sn9c102_i2c_write(cam, 0x28, 0xa2);
- err += sn9c102_i2c_write(cam, 0x29, 0x74);
- err += sn9c102_i2c_write(cam, 0x2a, 0x88);
- err += sn9c102_i2c_write(cam, 0x2b, 0x34);
- err += sn9c102_i2c_write(cam, 0x2c, 0x88);
- err += sn9c102_i2c_write(cam, 0x2e, 0x00);
- err += sn9c102_i2c_write(cam, 0x2f, 0x00);
- err += sn9c102_i2c_write(cam, 0x30, 0x00);
- err += sn9c102_i2c_write(cam, 0x32, 0xc2);
- err += sn9c102_i2c_write(cam, 0x33, 0x08);
- err += sn9c102_i2c_write(cam, 0x4c, 0x40);
- err += sn9c102_i2c_write(cam, 0x4d, 0xf3);
- err += sn9c102_i2c_write(cam, 0x60, 0x05);
- err += sn9c102_i2c_write(cam, 0x61, 0x40);
- err += sn9c102_i2c_write(cam, 0x62, 0x12);
- err += sn9c102_i2c_write(cam, 0x63, 0x57);
- err += sn9c102_i2c_write(cam, 0x64, 0x73);
- err += sn9c102_i2c_write(cam, 0x65, 0x00);
- err += sn9c102_i2c_write(cam, 0x66, 0x55);
- err += sn9c102_i2c_write(cam, 0x67, 0x01);
- err += sn9c102_i2c_write(cam, 0x68, 0xac);
- err += sn9c102_i2c_write(cam, 0x69, 0x38);
- err += sn9c102_i2c_write(cam, 0x6f, 0x1f);
- err += sn9c102_i2c_write(cam, 0x70, 0x01);
- err += sn9c102_i2c_write(cam, 0x71, 0x00);
- err += sn9c102_i2c_write(cam, 0x72, 0x10);
- err += sn9c102_i2c_write(cam, 0x73, 0x50);
- err += sn9c102_i2c_write(cam, 0x74, 0x20);
- err += sn9c102_i2c_write(cam, 0x76, 0x01);
- err += sn9c102_i2c_write(cam, 0x77, 0xf3);
- err += sn9c102_i2c_write(cam, 0x78, 0x90);
- err += sn9c102_i2c_write(cam, 0x79, 0x98);
- err += sn9c102_i2c_write(cam, 0x7a, 0x98);
- err += sn9c102_i2c_write(cam, 0x7b, 0x00);
- err += sn9c102_i2c_write(cam, 0x7c, 0x38);
- err += sn9c102_i2c_write(cam, 0x7d, 0xff);
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static int ov7630_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- ctrl->value = sn9c102_i2c_read(cam, 0x10);
- if (ctrl->value < 0)
- return -EIO;
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
- else
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
- break;
- break;
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x00);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x0c);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_WHITENESS:
- ctrl->value = sn9c102_i2c_read(cam, 0x0d);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x3f;
- break;
- case V4L2_CID_AUTOGAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x13);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x01;
- break;
- case V4L2_CID_VFLIP:
- ctrl->value = sn9c102_i2c_read(cam, 0x75);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x80) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_GAMMA:
- ctrl->value = sn9c102_i2c_read(cam, 0x14);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- ctrl->value = sn9c102_i2c_read(cam, 0x2d);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x02) ? 1 : 0;
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- enum sn9c102_bridge bridge = sn9c102_get_bridge(cam);
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case V4L2_CID_RED_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120)
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- else
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- case V4L2_CID_WHITENESS:
- err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
- break;
- case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, ctrl->value |
- (ctrl->value << 1));
- break;
- case V4L2_CID_VFLIP:
- err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
- break;
- case SN9C102_V4L2_CID_GAMMA:
- err += sn9c102_i2c_write(cam, 0x14, ctrl->value << 2);
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7630_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int ov7630_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- case BRIDGE_SN9C103:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8)
- err += sn9c102_write_reg(cam, 0x50, 0x19);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
- err += sn9c102_write_reg(cam, 0xe5, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x04);
- } else {
- err += sn9c102_write_reg(cam, 0xe2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x02);
- }
- break;
- default:
- break;
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor ov7630 = {
- .name = "OV7630",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103 |
- BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x21,
- .init = &ov7630_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x60,
- .flags = 0,
- },
- {
- .id = V4L2_CID_WHITENESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: red",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_DO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "white balance background: blue",
- .minimum = 0x00,
- .maximum = 0x3f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto adjust",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x20,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_BAND_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "band filter",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GAMMA,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "rgb gamma",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &ov7630_get_ctrl,
- .set_ctrl = &ov7630_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &ov7630_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SN9C10X,
- .priv = 8,
- },
- .set_pix_format = &ov7630_set_pix_format
-};
-
-
-int sn9c102_probe_ov7630(struct sn9c102_device *cam)
-{
- int pid, ver, err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
- break;
- case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
- {0x28, 0x17}, {0x44, 0x02});
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) /* try a different initialization */
- err += sn9c102_write_const_regs(cam, {0x01, 0x01},
- {0x00, 0x01});
- break;
- case BRIDGE_SN9C105:
- case BRIDGE_SN9C120:
- err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x29, 0x01}, {0x74, 0x02},
- {0x0e, 0x01}, {0x44, 0x01});
- break;
- default:
- break;
- }
-
- pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- ver = sn9c102_i2c_try_read(cam, &ov7630, 0x0b);
- if (err || pid < 0 || ver < 0)
- return -EIO;
- if (pid != 0x76 || ver != 0x31)
- return -ENODEV;
- sn9c102_attach_sensor(cam, &ov7630);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7660.c b/drivers/staging/media/sn9c102/sn9c102_ov7660.c
deleted file mode 100644
index ac07805d122e..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_ov7660.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/***************************************************************************
- * Plug-in for OV7660 image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int ov7660_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x03, 0x10},
- {0x08, 0x14}, {0x20, 0x17},
- {0x8b, 0x18}, {0x00, 0x19},
- {0x1d, 0x1a}, {0x10, 0x1b},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x29, 0x21},
- {0x40, 0x22}, {0x54, 0x23},
- {0x66, 0x24}, {0x76, 0x25},
- {0x85, 0x26}, {0x94, 0x27},
- {0xa1, 0x28}, {0xae, 0x29},
- {0xbb, 0x2a}, {0xc7, 0x2b},
- {0xd3, 0x2c}, {0xde, 0x2d},
- {0xea, 0x2e}, {0xf4, 0x2f},
- {0xff, 0x30}, {0x00, 0x3f},
- {0xc7, 0x40}, {0x01, 0x41},
- {0x44, 0x42}, {0x00, 0x43},
- {0x44, 0x44}, {0x00, 0x45},
- {0x44, 0x46}, {0x00, 0x47},
- {0xc7, 0x48}, {0x01, 0x49},
- {0xc7, 0x4a}, {0x01, 0x4b},
- {0xc7, 0x4c}, {0x01, 0x4d},
- {0x44, 0x4e}, {0x00, 0x4f},
- {0x44, 0x50}, {0x00, 0x51},
- {0x44, 0x52}, {0x00, 0x53},
- {0xc7, 0x54}, {0x01, 0x55},
- {0xc7, 0x56}, {0x01, 0x57},
- {0xc7, 0x58}, {0x01, 0x59},
- {0x44, 0x5a}, {0x00, 0x5b},
- {0x44, 0x5c}, {0x00, 0x5d},
- {0x44, 0x5e}, {0x00, 0x5f},
- {0xc7, 0x60}, {0x01, 0x61},
- {0xc7, 0x62}, {0x01, 0x63},
- {0xc7, 0x64}, {0x01, 0x65},
- {0x44, 0x66}, {0x00, 0x67},
- {0x44, 0x68}, {0x00, 0x69},
- {0x44, 0x6a}, {0x00, 0x6b},
- {0xc7, 0x6c}, {0x01, 0x6d},
- {0xc7, 0x6e}, {0x01, 0x6f},
- {0xc7, 0x70}, {0x01, 0x71},
- {0x44, 0x72}, {0x00, 0x73},
- {0x44, 0x74}, {0x00, 0x75},
- {0x44, 0x76}, {0x00, 0x77},
- {0xc7, 0x78}, {0x01, 0x79},
- {0xc7, 0x7a}, {0x01, 0x7b},
- {0xc7, 0x7c}, {0x01, 0x7d},
- {0x44, 0x7e}, {0x00, 0x7f},
- {0x14, 0x84}, {0x00, 0x85},
- {0x27, 0x86}, {0x00, 0x87},
- {0x07, 0x88}, {0x00, 0x89},
- {0xec, 0x8a}, {0x0f, 0x8b},
- {0xd8, 0x8c}, {0x0f, 0x8d},
- {0x3d, 0x8e}, {0x00, 0x8f},
- {0x3d, 0x90}, {0x00, 0x91},
- {0xcd, 0x92}, {0x0f, 0x93},
- {0xf7, 0x94}, {0x0f, 0x95},
- {0x0c, 0x96}, {0x00, 0x97},
- {0x00, 0x98}, {0x66, 0x99},
- {0x05, 0x9a}, {0x00, 0x9b},
- {0x04, 0x9c}, {0x00, 0x9d},
- {0x08, 0x9e}, {0x00, 0x9f},
- {0x2d, 0xc0}, {0x2d, 0xc1},
- {0x3a, 0xc2}, {0x05, 0xc3},
- {0x04, 0xc4}, {0x3f, 0xc5},
- {0x00, 0xc6}, {0x00, 0xc7},
- {0x50, 0xc8}, {0x3C, 0xc9},
- {0x28, 0xca}, {0xd8, 0xcb},
- {0x14, 0xcc}, {0xec, 0xcd},
- {0x32, 0xce}, {0xdd, 0xcf},
- {0x32, 0xd0}, {0xdd, 0xd1},
- {0x6a, 0xd2}, {0x50, 0xd3},
- {0x00, 0xd4}, {0x00, 0xd5},
- {0x00, 0xd6});
-
- err += sn9c102_i2c_write(cam, 0x12, 0x80);
- err += sn9c102_i2c_write(cam, 0x11, 0x09);
- err += sn9c102_i2c_write(cam, 0x00, 0x0A);
- err += sn9c102_i2c_write(cam, 0x01, 0x80);
- err += sn9c102_i2c_write(cam, 0x02, 0x80);
- err += sn9c102_i2c_write(cam, 0x03, 0x00);
- err += sn9c102_i2c_write(cam, 0x04, 0x00);
- err += sn9c102_i2c_write(cam, 0x05, 0x08);
- err += sn9c102_i2c_write(cam, 0x06, 0x0B);
- err += sn9c102_i2c_write(cam, 0x07, 0x00);
- err += sn9c102_i2c_write(cam, 0x08, 0x1C);
- err += sn9c102_i2c_write(cam, 0x09, 0x01);
- err += sn9c102_i2c_write(cam, 0x0A, 0x76);
- err += sn9c102_i2c_write(cam, 0x0B, 0x60);
- err += sn9c102_i2c_write(cam, 0x0C, 0x00);
- err += sn9c102_i2c_write(cam, 0x0D, 0x08);
- err += sn9c102_i2c_write(cam, 0x0E, 0x04);
- err += sn9c102_i2c_write(cam, 0x0F, 0x6F);
- err += sn9c102_i2c_write(cam, 0x10, 0x20);
- err += sn9c102_i2c_write(cam, 0x11, 0x03);
- err += sn9c102_i2c_write(cam, 0x12, 0x05);
- err += sn9c102_i2c_write(cam, 0x13, 0xC7);
- err += sn9c102_i2c_write(cam, 0x14, 0x2C);
- err += sn9c102_i2c_write(cam, 0x15, 0x00);
- err += sn9c102_i2c_write(cam, 0x16, 0x02);
- err += sn9c102_i2c_write(cam, 0x17, 0x10);
- err += sn9c102_i2c_write(cam, 0x18, 0x60);
- err += sn9c102_i2c_write(cam, 0x19, 0x02);
- err += sn9c102_i2c_write(cam, 0x1A, 0x7B);
- err += sn9c102_i2c_write(cam, 0x1B, 0x02);
- err += sn9c102_i2c_write(cam, 0x1C, 0x7F);
- err += sn9c102_i2c_write(cam, 0x1D, 0xA2);
- err += sn9c102_i2c_write(cam, 0x1E, 0x01);
- err += sn9c102_i2c_write(cam, 0x1F, 0x0E);
- err += sn9c102_i2c_write(cam, 0x20, 0x05);
- err += sn9c102_i2c_write(cam, 0x21, 0x05);
- err += sn9c102_i2c_write(cam, 0x22, 0x05);
- err += sn9c102_i2c_write(cam, 0x23, 0x05);
- err += sn9c102_i2c_write(cam, 0x24, 0x68);
- err += sn9c102_i2c_write(cam, 0x25, 0x58);
- err += sn9c102_i2c_write(cam, 0x26, 0xD4);
- err += sn9c102_i2c_write(cam, 0x27, 0x80);
- err += sn9c102_i2c_write(cam, 0x28, 0x80);
- err += sn9c102_i2c_write(cam, 0x29, 0x30);
- err += sn9c102_i2c_write(cam, 0x2A, 0x00);
- err += sn9c102_i2c_write(cam, 0x2B, 0x00);
- err += sn9c102_i2c_write(cam, 0x2C, 0x80);
- err += sn9c102_i2c_write(cam, 0x2D, 0x00);
- err += sn9c102_i2c_write(cam, 0x2E, 0x00);
- err += sn9c102_i2c_write(cam, 0x2F, 0x0E);
- err += sn9c102_i2c_write(cam, 0x30, 0x08);
- err += sn9c102_i2c_write(cam, 0x31, 0x30);
- err += sn9c102_i2c_write(cam, 0x32, 0xB4);
- err += sn9c102_i2c_write(cam, 0x33, 0x00);
- err += sn9c102_i2c_write(cam, 0x34, 0x07);
- err += sn9c102_i2c_write(cam, 0x35, 0x84);
- err += sn9c102_i2c_write(cam, 0x36, 0x00);
- err += sn9c102_i2c_write(cam, 0x37, 0x0C);
- err += sn9c102_i2c_write(cam, 0x38, 0x02);
- err += sn9c102_i2c_write(cam, 0x39, 0x43);
- err += sn9c102_i2c_write(cam, 0x3A, 0x00);
- err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
- err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
- err += sn9c102_i2c_write(cam, 0x3D, 0x99);
- err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
- err += sn9c102_i2c_write(cam, 0x3F, 0x41);
- err += sn9c102_i2c_write(cam, 0x40, 0xC1);
- err += sn9c102_i2c_write(cam, 0x41, 0x22);
- err += sn9c102_i2c_write(cam, 0x42, 0x08);
- err += sn9c102_i2c_write(cam, 0x43, 0xF0);
- err += sn9c102_i2c_write(cam, 0x44, 0x10);
- err += sn9c102_i2c_write(cam, 0x45, 0x78);
- err += sn9c102_i2c_write(cam, 0x46, 0xA8);
- err += sn9c102_i2c_write(cam, 0x47, 0x60);
- err += sn9c102_i2c_write(cam, 0x48, 0x80);
- err += sn9c102_i2c_write(cam, 0x49, 0x00);
- err += sn9c102_i2c_write(cam, 0x4A, 0x00);
- err += sn9c102_i2c_write(cam, 0x4B, 0x00);
- err += sn9c102_i2c_write(cam, 0x4C, 0x00);
- err += sn9c102_i2c_write(cam, 0x4D, 0x00);
- err += sn9c102_i2c_write(cam, 0x4E, 0x00);
- err += sn9c102_i2c_write(cam, 0x4F, 0x46);
- err += sn9c102_i2c_write(cam, 0x50, 0x36);
- err += sn9c102_i2c_write(cam, 0x51, 0x0F);
- err += sn9c102_i2c_write(cam, 0x52, 0x17);
- err += sn9c102_i2c_write(cam, 0x53, 0x7F);
- err += sn9c102_i2c_write(cam, 0x54, 0x96);
- err += sn9c102_i2c_write(cam, 0x55, 0x40);
- err += sn9c102_i2c_write(cam, 0x56, 0x40);
- err += sn9c102_i2c_write(cam, 0x57, 0x40);
- err += sn9c102_i2c_write(cam, 0x58, 0x0F);
- err += sn9c102_i2c_write(cam, 0x59, 0xBA);
- err += sn9c102_i2c_write(cam, 0x5A, 0x9A);
- err += sn9c102_i2c_write(cam, 0x5B, 0x22);
- err += sn9c102_i2c_write(cam, 0x5C, 0xB9);
- err += sn9c102_i2c_write(cam, 0x5D, 0x9B);
- err += sn9c102_i2c_write(cam, 0x5E, 0x10);
- err += sn9c102_i2c_write(cam, 0x5F, 0xF0);
- err += sn9c102_i2c_write(cam, 0x60, 0x05);
- err += sn9c102_i2c_write(cam, 0x61, 0x60);
- err += sn9c102_i2c_write(cam, 0x62, 0x00);
- err += sn9c102_i2c_write(cam, 0x63, 0x00);
- err += sn9c102_i2c_write(cam, 0x64, 0x50);
- err += sn9c102_i2c_write(cam, 0x65, 0x30);
- err += sn9c102_i2c_write(cam, 0x66, 0x00);
- err += sn9c102_i2c_write(cam, 0x67, 0x80);
- err += sn9c102_i2c_write(cam, 0x68, 0x7A);
- err += sn9c102_i2c_write(cam, 0x69, 0x90);
- err += sn9c102_i2c_write(cam, 0x6A, 0x80);
- err += sn9c102_i2c_write(cam, 0x6B, 0x0A);
- err += sn9c102_i2c_write(cam, 0x6C, 0x30);
- err += sn9c102_i2c_write(cam, 0x6D, 0x48);
- err += sn9c102_i2c_write(cam, 0x6E, 0x80);
- err += sn9c102_i2c_write(cam, 0x6F, 0x74);
- err += sn9c102_i2c_write(cam, 0x70, 0x64);
- err += sn9c102_i2c_write(cam, 0x71, 0x60);
- err += sn9c102_i2c_write(cam, 0x72, 0x5C);
- err += sn9c102_i2c_write(cam, 0x73, 0x58);
- err += sn9c102_i2c_write(cam, 0x74, 0x54);
- err += sn9c102_i2c_write(cam, 0x75, 0x4C);
- err += sn9c102_i2c_write(cam, 0x76, 0x40);
- err += sn9c102_i2c_write(cam, 0x77, 0x38);
- err += sn9c102_i2c_write(cam, 0x78, 0x34);
- err += sn9c102_i2c_write(cam, 0x79, 0x30);
- err += sn9c102_i2c_write(cam, 0x7A, 0x2F);
- err += sn9c102_i2c_write(cam, 0x7B, 0x2B);
- err += sn9c102_i2c_write(cam, 0x7C, 0x03);
- err += sn9c102_i2c_write(cam, 0x7D, 0x07);
- err += sn9c102_i2c_write(cam, 0x7E, 0x17);
- err += sn9c102_i2c_write(cam, 0x7F, 0x34);
- err += sn9c102_i2c_write(cam, 0x80, 0x41);
- err += sn9c102_i2c_write(cam, 0x81, 0x4D);
- err += sn9c102_i2c_write(cam, 0x82, 0x58);
- err += sn9c102_i2c_write(cam, 0x83, 0x63);
- err += sn9c102_i2c_write(cam, 0x84, 0x6E);
- err += sn9c102_i2c_write(cam, 0x85, 0x77);
- err += sn9c102_i2c_write(cam, 0x86, 0x87);
- err += sn9c102_i2c_write(cam, 0x87, 0x95);
- err += sn9c102_i2c_write(cam, 0x88, 0xAF);
- err += sn9c102_i2c_write(cam, 0x89, 0xC7);
- err += sn9c102_i2c_write(cam, 0x8A, 0xDF);
- err += sn9c102_i2c_write(cam, 0x8B, 0x99);
- err += sn9c102_i2c_write(cam, 0x8C, 0x99);
- err += sn9c102_i2c_write(cam, 0x8D, 0xCF);
- err += sn9c102_i2c_write(cam, 0x8E, 0x20);
- err += sn9c102_i2c_write(cam, 0x8F, 0x26);
- err += sn9c102_i2c_write(cam, 0x90, 0x10);
- err += sn9c102_i2c_write(cam, 0x91, 0x0C);
- err += sn9c102_i2c_write(cam, 0x92, 0x25);
- err += sn9c102_i2c_write(cam, 0x93, 0x00);
- err += sn9c102_i2c_write(cam, 0x94, 0x50);
- err += sn9c102_i2c_write(cam, 0x95, 0x50);
- err += sn9c102_i2c_write(cam, 0x96, 0x00);
- err += sn9c102_i2c_write(cam, 0x97, 0x01);
- err += sn9c102_i2c_write(cam, 0x98, 0x10);
- err += sn9c102_i2c_write(cam, 0x99, 0x40);
- err += sn9c102_i2c_write(cam, 0x9A, 0x40);
- err += sn9c102_i2c_write(cam, 0x9B, 0x20);
- err += sn9c102_i2c_write(cam, 0x9C, 0x00);
- err += sn9c102_i2c_write(cam, 0x9D, 0x99);
- err += sn9c102_i2c_write(cam, 0x9E, 0x7F);
- err += sn9c102_i2c_write(cam, 0x9F, 0x00);
- err += sn9c102_i2c_write(cam, 0xA0, 0x00);
- err += sn9c102_i2c_write(cam, 0xA1, 0x00);
-
- return err;
-}
-
-
-static int ov7660_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- ctrl->value = sn9c102_i2c_read(cam, 0x10);
- if (ctrl->value < 0)
- return -EIO;
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_read_reg(cam, 0x02);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
- break;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_read_reg(cam, 0x05);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_read_reg(cam, 0x06);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_read_reg(cam, 0x07);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x7f;
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- ctrl->value = sn9c102_i2c_read(cam, 0x3b);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x08;
- break;
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x00);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- break;
- case V4L2_CID_AUTOGAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x13);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x01;
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7660_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case V4L2_CID_DO_WHITE_BALANCE:
- err += sn9c102_write_reg(cam, 0x43 | (ctrl->value << 2), 0x02);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x05);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x06);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_write_reg(cam, ctrl->value, 0x07);
- break;
- case SN9C102_V4L2_CID_BAND_FILTER:
- err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
- break;
- case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
- (ctrl->value * 0x07));
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int ov7660_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int ov7660_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int r0, err = 0;
-
- r0 = sn9c102_pread_reg(cam, 0x01);
-
- if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
- err += sn9c102_write_reg(cam, r0 | 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x00);
- } else {
- err += sn9c102_write_reg(cam, r0 | 0x40, 0x01);
- err += sn9c102_write_reg(cam, 0xa2, 0x17);
- err += sn9c102_i2c_write(cam, 0x11, 0x0d);
- }
-
- return err;
-}
-
-
-static const struct sn9c102_sensor ov7660 = {
- .name = "OV7660",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x21,
- .init = &ov7660_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x09,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x27,
- .flags = 0,
- },
- {
- .id = V4L2_CID_DO_WHITE_BALANCE,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "night mode",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "auto adjust",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x7f,
- .step = 0x01,
- .default_value = 0x14,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_BAND_FILTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "band filter",
- .minimum = 0x00,
- .maximum = 0x01,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .get_ctrl = &ov7660_get_ctrl,
- .set_ctrl = &ov7660_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &ov7660_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_JPEG,
- .priv = 8,
- },
- .set_pix_format = &ov7660_set_pix_format
-};
-
-
-int sn9c102_probe_ov7660(struct sn9c102_device *cam)
-{
- int pid, ver, err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
- {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
-
- pid = sn9c102_i2c_try_read(cam, &ov7660, 0x0a);
- ver = sn9c102_i2c_try_read(cam, &ov7660, 0x0b);
- if (err || pid < 0 || ver < 0)
- return -EIO;
- if (pid != 0x76 || ver != 0x60)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &ov7660);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_pas106b.c b/drivers/staging/media/sn9c102/sn9c102_pas106b.c
deleted file mode 100644
index 895931ecac48..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_pas106b.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/***************************************************************************
- * Plug-in for PAS106B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/delay.h>
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int pas106b_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x20, 0x19}, {0x09, 0x18});
-
- err += sn9c102_i2c_write(cam, 0x02, 0x0c);
- err += sn9c102_i2c_write(cam, 0x05, 0x5a);
- err += sn9c102_i2c_write(cam, 0x06, 0x88);
- err += sn9c102_i2c_write(cam, 0x07, 0x80);
- err += sn9c102_i2c_write(cam, 0x10, 0x06);
- err += sn9c102_i2c_write(cam, 0x11, 0x06);
- err += sn9c102_i2c_write(cam, 0x12, 0x00);
- err += sn9c102_i2c_write(cam, 0x14, 0x02);
- err += sn9c102_i2c_write(cam, 0x13, 0x01);
-
- msleep(400);
-
- return err;
-}
-
-
-static int pas106b_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x03),
- r2 = sn9c102_i2c_read(cam, 0x04);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 4) | (r2 & 0x0f);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x0c);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x09);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x0e);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case V4L2_CID_CONTRAST:
- ctrl->value = sn9c102_i2c_read(cam, 0x0f);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x07;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x0a);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value = (ctrl->value & 0x1f) << 1;
- return 0;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- ctrl->value = sn9c102_i2c_read(cam, 0x08);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0xf8;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int pas106b_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x03, ctrl->value >> 4);
- err += sn9c102_i2c_write(cam, 0x04, ctrl->value & 0x0f);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x0e, ctrl->value);
- break;
- case V4L2_CID_CONTRAST:
- err += sn9c102_i2c_write(cam, 0x0f, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x0a, ctrl->value >> 1);
- err += sn9c102_i2c_write(cam, 0x0b, ctrl->value >> 1);
- break;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- err += sn9c102_i2c_write(cam, 0x08, ctrl->value << 3);
- break;
- default:
- return -EINVAL;
- }
- err += sn9c102_i2c_write(cam, 0x13, 0x01);
-
- return err ? -EIO : 0;
-}
-
-
-static int pas106b_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static int pas106b_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x2c, 0x17);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x17);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor pas106b = {
- .name = "PAS106B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x40,
- .init = &pas106b_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x125,
- .maximum = 0xfff,
- .step = 0x001,
- .default_value = 0x140,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x0d,
- .flags = 0,
- },
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "contrast",
- .minimum = 0x00,
- .maximum = 0x07,
- .step = 0x01,
- .default_value = 0x00, /* 0x00~0x03 have same effect */
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x04,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x06,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x3e,
- .step = 0x02,
- .default_value = 0x02,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "DAC magnitude",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x01,
- .flags = 0,
- },
- },
- .get_ctrl = &pas106b_get_ctrl,
- .set_ctrl = &pas106b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &pas106b_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8, /* we use this field as 'bits per pixel' */
- },
- .set_pix_format = &pas106b_set_pix_format
-};
-
-
-int sn9c102_probe_pas106b(struct sn9c102_device *cam)
-{
- int r0 = 0, r1 = 0;
- unsigned int pid = 0;
-
- /*
- Minimal initialization to enable the I2C communication
- NOTE: do NOT change the values!
- */
- if (sn9c102_write_const_regs(cam,
- {0x01, 0x01}, /* sensor power down */
- {0x00, 0x01}, /* sensor power on */
- {0x28, 0x17})) /* sensor clock at 24 MHz */
- return -EIO;
-
- r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
- if (r0 < 0 || r1 < 0)
- return -EIO;
-
- pid = (r0 << 11) | ((r1 & 0xf0) >> 4);
- if (pid != 0x007)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &pas106b);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c b/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c
deleted file mode 100644
index f9e31ae2ad9f..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/***************************************************************************
- * Plug-in for PAS202BCB image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004 by Carlos Eduardo Medaglia Dyonisio *
- * <medaglia@undl.org.br> *
- * *
- * Support for SN9C103, DAC Magnitude, exposure and green gain controls *
- * added by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/delay.h>
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int pas202bcb_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x30, 0x19}, {0x09, 0x18});
- break;
- case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
- {0x1a, 0x04}, {0x20, 0x05},
- {0x20, 0x06}, {0x20, 0x07},
- {0x00, 0x10}, {0x00, 0x11},
- {0x00, 0x14}, {0x20, 0x17},
- {0x30, 0x19}, {0x09, 0x18},
- {0x02, 0x1c}, {0x03, 0x1d},
- {0x0f, 0x1e}, {0x0c, 0x1f},
- {0x00, 0x20}, {0x10, 0x21},
- {0x20, 0x22}, {0x30, 0x23},
- {0x40, 0x24}, {0x50, 0x25},
- {0x60, 0x26}, {0x70, 0x27},
- {0x80, 0x28}, {0x90, 0x29},
- {0xa0, 0x2a}, {0xb0, 0x2b},
- {0xc0, 0x2c}, {0xd0, 0x2d},
- {0xe0, 0x2e}, {0xf0, 0x2f},
- {0xff, 0x30});
- break;
- default:
- break;
- }
-
- err += sn9c102_i2c_write(cam, 0x02, 0x14);
- err += sn9c102_i2c_write(cam, 0x03, 0x40);
- err += sn9c102_i2c_write(cam, 0x0d, 0x2c);
- err += sn9c102_i2c_write(cam, 0x0e, 0x01);
- err += sn9c102_i2c_write(cam, 0x0f, 0xa9);
- err += sn9c102_i2c_write(cam, 0x10, 0x08);
- err += sn9c102_i2c_write(cam, 0x13, 0x63);
- err += sn9c102_i2c_write(cam, 0x15, 0x70);
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
-
- msleep(400);
-
- return err;
-}
-
-
-static int pas202bcb_get_ctrl(struct sn9c102_device *cam,
- struct v4l2_control *ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = sn9c102_i2c_read(cam, 0x04),
- r2 = sn9c102_i2c_read(cam, 0x05);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 6) | (r2 & 0x3f);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x09);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x07);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_GAIN:
- ctrl->value = sn9c102_i2c_read(cam, 0x10);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_i2c_read(cam, 0x08);
- if (ctrl->value < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- ctrl->value = sn9c102_i2c_read(cam, 0x0c);
- if (ctrl->value < 0)
- return -EIO;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int pas202bcb_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x28, 0x17);
- else
- err += sn9c102_write_reg(cam, 0x20, 0x17);
-
- return err;
-}
-
-
-static int pas202bcb_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x04, ctrl->value >> 6);
- err += sn9c102_i2c_write(cam, 0x05, ctrl->value & 0x3f);
- break;
- case V4L2_CID_RED_BALANCE:
- err += sn9c102_i2c_write(cam, 0x09, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += sn9c102_i2c_write(cam, 0x07, ctrl->value);
- break;
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x10, ctrl->value);
- break;
- case SN9C102_V4L2_CID_GREEN_BALANCE:
- err += sn9c102_i2c_write(cam, 0x08, ctrl->value);
- break;
- case SN9C102_V4L2_CID_DAC_MAGNITUDE:
- err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- err += sn9c102_i2c_write(cam, 0x11, 0x01);
-
- return err ? -EIO : 0;
-}
-
-
-static int pas202bcb_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3;
-
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4;
- break;
- case BRIDGE_SN9C103:
- h_start = (u8)(rect->left - s->cropcap.bounds.left) + 3;
- break;
- default:
- break;
- }
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor pas202bcb = {
- .name = "PAS202BCB",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
- .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_400KHZ | SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x40,
- .init = &pas202bcb_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x01e5,
- .maximum = 0x3fff,
- .step = 0x0001,
- .default_value = 0x01e5,
- .flags = 0,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x0b,
- .flags = 0,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = SN9C102_V4L2_CID_DAC_MAGNITUDE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "DAC magnitude",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x04,
- .flags = 0,
- },
- },
- .get_ctrl = &pas202bcb_get_ctrl,
- .set_ctrl = &pas202bcb_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &pas202bcb_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &pas202bcb_set_pix_format
-};
-
-
-int sn9c102_probe_pas202bcb(struct sn9c102_device *cam)
-{
- int r0 = 0, r1 = 0, err = 0;
- unsigned int pid = 0;
-
- /*
- * Minimal initialization to enable the I2C communication
- * NOTE: do NOT change the values!
- */
- switch (sn9c102_get_bridge(cam)) {
- case BRIDGE_SN9C101:
- case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam,
- {0x01, 0x01}, /* power down */
- {0x40, 0x01}, /* power on */
- {0x28, 0x17});/* clock 24 MHz */
- break;
- case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
- {0x44, 0x02}, {0x29, 0x17});
- break;
- default:
- break;
- }
-
- r0 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x00);
- r1 = sn9c102_i2c_try_read(cam, &pas202bcb, 0x01);
-
- if (err || r0 < 0 || r1 < 0)
- return -EIO;
-
- pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
- if (pid != 0x017)
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &pas202bcb);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_sensor.h b/drivers/staging/media/sn9c102/sn9c102_sensor.h
deleted file mode 100644
index 9f59c815d48b..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_sensor.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/***************************************************************************
- * API for image sensors connected to the SN9C1xx PC Camera Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _SN9C102_SENSOR_H_
-#define _SN9C102_SENSOR_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/device.h>
-#include <linux/stddef.h>
-#include <linux/errno.h>
-#include <asm/types.h>
-
-struct sn9c102_device;
-struct sn9c102_sensor;
-
-/*****************************************************************************/
-
-/*
- OVERVIEW.
- This is a small interface that allows you to add support for any CCD/CMOS
- image sensors connected to the SN9C1XX bridges. The entire API is documented
- below. In the most general case, to support a sensor there are three steps
- you have to follow:
- 1) define the main "sn9c102_sensor" structure by setting the basic fields;
- 2) write a probing function to be called by the core module when the USB
- camera is recognized, then add both the USB ids and the name of that
- function to the two corresponding tables in sn9c102_devtable.h;
- 3) implement the methods that you want/need (and fill the rest of the main
- structure accordingly).
- "sn9c102_pas106b.c" is an example of all this stuff. Remember that you do
- NOT need to touch the source code of the core module for the things to work
- properly, unless you find bugs or flaws in it. Finally, do not forget to
- read the V4L2 API for completeness.
-*/
-
-/*****************************************************************************/
-
-enum sn9c102_bridge {
- BRIDGE_SN9C101 = 0x01,
- BRIDGE_SN9C102 = 0x02,
- BRIDGE_SN9C103 = 0x04,
- BRIDGE_SN9C105 = 0x08,
- BRIDGE_SN9C120 = 0x10,
-};
-
-/* Return the bridge name */
-enum sn9c102_bridge sn9c102_get_bridge(struct sn9c102_device *cam);
-
-/* Return a pointer the sensor struct attached to the camera */
-struct sn9c102_sensor *sn9c102_get_sensor(struct sn9c102_device *cam);
-
-/* Identify a device */
-extern struct sn9c102_device*
-sn9c102_match_id(struct sn9c102_device *cam, const struct usb_device_id *id);
-
-/* Attach a probed sensor to the camera. */
-extern void
-sn9c102_attach_sensor(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor);
-
-/*
- Read/write routines: they always return -1 on error, 0 or the read value
- otherwise. NOTE that a real read operation is not supported by the SN9C1XX
- chip for some of its registers. To work around this problem, a pseudo-read
- call is provided instead: it returns the last successfully written value
- on the register (0 if it has never been written), the usual -1 on error.
-*/
-
-/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,
- const struct sn9c102_sensor*, u8 address);
-
-/*
- These must be used if and only if the sensor doesn't implement the standard
- I2C protocol. There are a number of good reasons why you must use the
- single-byte versions of these functions: do not abuse. The first function
- writes n bytes, from data0 to datan, to registers 0x09 - 0x09+n of SN9C1XX
- chip. The second one programs the registers 0x09 and 0x10 with data0 and
- data1, and places the n bytes read from the sensor register table in the
- buffer pointed by 'buffer'. Both the functions return -1 on error; the write
- version returns 0 on success, while the read version returns the first read
- byte.
-*/
-extern int sn9c102_i2c_try_raw_write(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor, u8 n,
- u8 data0, u8 data1, u8 data2, u8 data3,
- u8 data4, u8 data5);
-extern int sn9c102_i2c_try_raw_read(struct sn9c102_device *cam,
- const struct sn9c102_sensor *sensor,
- u8 data0, u8 data1, u8 n, u8 buffer[]);
-
-/* To be used after the sensor struct has been attached to the camera struct */
-extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
-extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
-
-/* I/O on registers in the bridge. Could be used by the sensor methods too */
-extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
-extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
-extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
-extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
- int count);
-/*
- Write multiple registers with constant values. For example:
- sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- Register addresses must be < 256.
-*/
-#define sn9c102_write_const_regs(sn9c102_device, data...) \
- ({ static const u8 _valreg[][2] = {data}; \
- sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
-
-/*****************************************************************************/
-
-enum sn9c102_i2c_sysfs_ops {
- SN9C102_I2C_READ = 0x01,
- SN9C102_I2C_WRITE = 0x02,
-};
-
-enum sn9c102_i2c_frequency { /* sensors may support both the frequencies */
- SN9C102_I2C_100KHZ = 0x01,
- SN9C102_I2C_400KHZ = 0x02,
-};
-
-enum sn9c102_i2c_interface {
- SN9C102_I2C_2WIRES,
- SN9C102_I2C_3WIRES,
-};
-
-#define SN9C102_MAX_CTRLS (V4L2_CID_LASTP1-V4L2_CID_BASE+10)
-
-struct sn9c102_sensor {
- char name[32], /* sensor name */
- maintainer[64]; /* name of the maintainer <email> */
-
- enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */
-
- /* Supported operations through the 'sysfs' interface */
- enum sn9c102_i2c_sysfs_ops sysfs_ops;
-
- /*
- These sensor capabilities must be provided if the SN9C1XX controller
- needs to communicate through the sensor serial interface by using
- at least one of the i2c functions available.
- */
- enum sn9c102_i2c_frequency frequency;
- enum sn9c102_i2c_interface interface;
-
- /*
- This identifier must be provided if the image sensor implements
- the standard I2C protocol.
- */
- u8 i2c_slave_id; /* reg. 0x09 */
-
- /*
- NOTE: Where not noted,most of the functions below are not mandatory.
- Set to null if you do not implement them. If implemented,
- they must return 0 on success, the proper error otherwise.
- */
-
- int (*init)(struct sn9c102_device *cam);
- /*
- This function will be called after the sensor has been attached.
- It should be used to initialize the sensor only, but may also
- configure part of the SN9C1XX chip if necessary. You don't need to
- setup picture settings like brightness, contrast, etc.. here, if
- the corresponding controls are implemented (see below), since
- they are adjusted in the core driver by calling the set_ctrl()
- method after init(), where the arguments are the default values
- specified in the v4l2_queryctrl list of supported controls;
- Same suggestions apply for other settings, _if_ the corresponding
- methods are present; if not, the initialization must configure the
- sensor according to the default configuration structures below.
- */
-
- struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
- /*
- Optional list of default controls, defined as indicated in the
- V4L2 API. Menu type controls are not handled by this interface.
- */
-
- int (*get_ctrl)(struct sn9c102_device *cam, struct v4l2_control *ctrl);
- int (*set_ctrl)(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl);
- /*
- You must implement at least the set_ctrl method if you have defined
- the list above. The returned value must follow the V4L2
- specifications for the VIDIOC_G|C_CTRL ioctls. V4L2_CID_H|VCENTER
- are not supported by this driver, so do not implement them. Also,
- you don't have to check whether the passed values are out of bounds,
- given that this is done by the core module.
- */
-
- struct v4l2_cropcap cropcap;
- /*
- Think the image sensor as a grid of R,G,B monochromatic pixels
- disposed according to a particular Bayer pattern, which describes
- the complete array of pixels, from (0,0) to (xmax, ymax). We will
- use this coordinate system from now on. It is assumed the sensor
- chip can be programmed to capture/transmit a subsection of that
- array of pixels: we will call this subsection "active window".
- It is not always true that the largest achievable active window can
- cover the whole array of pixels. The V4L2 API defines another
- area called "source rectangle", which, in turn, is a subrectangle of
- the active window. The SN9C1XX chip is always programmed to read the
- source rectangle.
- The bounds of both the active window and the source rectangle are
- specified in the cropcap substructures 'bounds' and 'defrect'.
- By default, the source rectangle should cover the largest possible
- area. Again, it is not always true that the largest source rectangle
- can cover the entire active window, although it is a rare case for
- the hardware we have. The bounds of the source rectangle _must_ be
- multiple of 16 and must use the same coordinate system as indicated
- before; their centers shall align initially.
- If necessary, the sensor chip must be initialized during init() to
- set the bounds of the active sensor window; however, by default, it
- usually covers the largest achievable area (maxwidth x maxheight)
- of pixels, so no particular initialization is needed, if you have
- defined the correct default bounds in the structures.
- See the V4L2 API for further details.
- NOTE: once you have defined the bounds of the active window
- (struct cropcap.bounds) you must not change them.anymore.
- Only 'bounds' and 'defrect' fields are mandatory, other fields
- will be ignored.
- */
-
- int (*set_crop)(struct sn9c102_device *cam,
- const struct v4l2_rect *rect);
- /*
- To be called on VIDIOC_C_SETCROP. The core module always calls a
- default routine which configures the appropriate SN9C1XX regs (also
- scaling), but you may need to override/adjust specific stuff.
- 'rect' contains width and height values that are multiple of 16: in
- case you override the default function, you always have to program
- the chip to match those values; on error return the corresponding
- error code without rolling back.
- NOTE: in case, you must program the SN9C1XX chip to get rid of
- blank pixels or blank lines at the _start_ of each line or
- frame after each HSYNC or VSYNC, so that the image starts with
- real RGB data (see regs 0x12, 0x13) (having set H_SIZE and,
- V_SIZE you don't have to care about blank pixels or blank
- lines at the end of each line or frame).
- */
-
- struct v4l2_pix_format pix_format;
- /*
- What you have to define here are: 1) initial 'width' and 'height' of
- the target rectangle 2) the initial 'pixelformat', which can be
- either V4L2_PIX_FMT_SN9C10X, V4L2_PIX_FMT_JPEG (for ompressed video)
- or V4L2_PIX_FMT_SBGGR8 3) 'priv', which we'll be used to indicate
- the number of bits per pixel for uncompressed video, 8 or 9 (despite
- the current value of 'pixelformat').
- NOTE 1: both 'width' and 'height' _must_ be either 1/1 or 1/2 or 1/4
- of cropcap.defrect.width and cropcap.defrect.height. I
- suggest 1/1.
- NOTE 2: The initial compression quality is defined by the first bit
- of reg 0x17 during the initialization of the image sensor.
- NOTE 3: as said above, you have to program the SN9C1XX chip to get
- rid of any blank pixels, so that the output of the sensor
- matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR).
- */
-
- int (*set_pix_format)(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix);
- /*
- To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to
- SN9C10X pixel format or viceversa. On error return the corresponding
- error code without rolling back.
- */
-
- /*
- Do NOT write to the data below, it's READ ONLY. It is used by the
- core module to store successfully updated values of the above
- settings, for rollbacks..etc..in case of errors during atomic I/O
- */
- struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
- struct v4l2_rect _rect;
-};
-
-/*****************************************************************************/
-
-/* Private ioctl's for control settings supported by some image sensors */
-#define SN9C102_V4L2_CID_DAC_MAGNITUDE (V4L2_CID_PRIVATE_BASE + 0)
-#define SN9C102_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 1)
-#define SN9C102_V4L2_CID_RESET_LEVEL (V4L2_CID_PRIVATE_BASE + 2)
-#define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE (V4L2_CID_PRIVATE_BASE + 3)
-#define SN9C102_V4L2_CID_GAMMA (V4L2_CID_PRIVATE_BASE + 4)
-#define SN9C102_V4L2_CID_BAND_FILTER (V4L2_CID_PRIVATE_BASE + 5)
-#define SN9C102_V4L2_CID_BRIGHT_LEVEL (V4L2_CID_PRIVATE_BASE + 6)
-
-#endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c
deleted file mode 100644
index 6a00b626d347..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5110C1B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5110c1b_init(struct sn9c102_device *cam)
-{
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x44, 0x01},
- {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x60, 0x17},
- {0x06, 0x18}, {0xfb, 0x19});
-
- err += sn9c102_i2c_write(cam, 0xc0, 0x80);
-
- return err;
-}
-
-
-static int tas5110c1b_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int tas5110c1b_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- /* Don't change ! */
- err += sn9c102_write_reg(cam, 0x14, 0x1a);
- err += sn9c102_write_reg(cam, 0x0a, 0x1b);
- err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
-
- return err;
-}
-
-
-static int tas5110c1b_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x2b, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5110c1b = {
- .name = "TAS5110C1B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_3WIRES,
- .init = &tas5110c1b_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xf6,
- .step = 0x01,
- .default_value = 0x40,
- .flags = 0,
- },
- },
- .set_ctrl = &tas5110c1b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &tas5110c1b_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5110c1b_set_pix_format
-};
-
-
-int sn9c102_probe_tas5110c1b(struct sn9c102_device *cam)
-{
- const struct usb_device_id tas5110c1b_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6001), },
- { USB_DEVICE(0x0c45, 0x6005), },
- { USB_DEVICE(0x0c45, 0x60ab), },
- { }
- };
-
- /* Sensor detection is based on USB pid/vid */
- if (!sn9c102_match_id(cam, tas5110c1b_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5110c1b);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5110d.c b/drivers/staging/media/sn9c102/sn9c102_tas5110d.c
deleted file mode 100644
index eefbf8670c3e..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_tas5110d.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5110D image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5110d_init(struct sn9c102_device *cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x04, 0x01},
- {0x0a, 0x14}, {0x60, 0x17},
- {0x06, 0x18}, {0xfb, 0x19});
-
- err += sn9c102_i2c_write(cam, 0x9a, 0xca);
-
- return err;
-}
-
-
-static int tas5110d_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- err += sn9c102_write_reg(cam, 0x14, 0x1a);
- err += sn9c102_write_reg(cam, 0x0a, 0x1b);
-
- return err;
-}
-
-
-static int tas5110d_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x3b, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xfb, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5110d = {
- .name = "TAS5110D",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_2WIRES,
- .i2c_slave_id = 0x61,
- .init = &tas5110d_init,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 352,
- .height = 288,
- },
- },
- .set_crop = &tas5110d_set_crop,
- .pix_format = {
- .width = 352,
- .height = 288,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5110d_set_pix_format
-};
-
-
-int sn9c102_probe_tas5110d(struct sn9c102_device *cam)
-{
- const struct usb_device_id tas5110d_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6007), },
- { }
- };
-
- if (!sn9c102_match_id(cam, tas5110d_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5110d);
-
- return 0;
-}
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c
deleted file mode 100644
index 725de857de45..000000000000
--- a/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/***************************************************************************
- * Plug-in for TAS5130D1B image sensor connected to the SN9C1xx PC Camera *
- * Controllers *
- * *
- * Copyright (C) 2004-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include "sn9c102_sensor.h"
-#include "sn9c102_devtable.h"
-
-
-static int tas5130d1b_init(struct sn9c102_device *cam)
-{
- int err;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x20, 0x17},
- {0x04, 0x01}, {0x01, 0x10},
- {0x00, 0x11}, {0x00, 0x14},
- {0x60, 0x17}, {0x07, 0x18});
-
- return err;
-}
-
-
-static int tas5130d1b_set_ctrl(struct sn9c102_device *cam,
- const struct v4l2_control *ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
- break;
- case V4L2_CID_EXPOSURE:
- err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value);
- break;
- default:
- return -EINVAL;
- }
-
- return err ? -EIO : 0;
-}
-
-
-static int tas5130d1b_set_crop(struct sn9c102_device *cam,
- const struct v4l2_rect *rect)
-{
- struct sn9c102_sensor *s = sn9c102_get_sensor(cam);
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12;
- int err = 0;
-
- err += sn9c102_write_reg(cam, h_start, 0x12);
- err += sn9c102_write_reg(cam, v_start, 0x13);
-
- /* Do NOT change! */
- err += sn9c102_write_reg(cam, 0x1f, 0x1a);
- err += sn9c102_write_reg(cam, 0x1a, 0x1b);
- err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19);
-
- return err;
-}
-
-
-static int tas5130d1b_set_pix_format(struct sn9c102_device *cam,
- const struct v4l2_pix_format *pix)
-{
- int err = 0;
-
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
- err += sn9c102_write_reg(cam, 0x63, 0x19);
- else
- err += sn9c102_write_reg(cam, 0xf3, 0x19);
-
- return err;
-}
-
-
-static const struct sn9c102_sensor tas5130d1b = {
- .name = "TAS5130D1B",
- .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
- .sysfs_ops = SN9C102_I2C_WRITE,
- .frequency = SN9C102_I2C_100KHZ,
- .interface = SN9C102_I2C_3WIRES,
- .init = &tas5130d1b_init,
- .qctrl = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0xf6,
- .step = 0x02,
- .default_value = 0x00,
- .flags = 0,
- },
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0x47,
- .step = 0x01,
- .default_value = 0x00,
- .flags = 0,
- },
- },
- .set_ctrl = &tas5130d1b_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .set_crop = &tas5130d1b_set_crop,
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_SBGGR8,
- .priv = 8,
- },
- .set_pix_format = &tas5130d1b_set_pix_format
-};
-
-
-int sn9c102_probe_tas5130d1b(struct sn9c102_device *cam)
-{
- const struct usb_device_id tas5130d1b_id_table[] = {
- { USB_DEVICE(0x0c45, 0x6024), },
- { USB_DEVICE(0x0c45, 0x6025), },
- { USB_DEVICE(0x0c45, 0x60aa), },
- { }
- };
-
- /* Sensor detection is based on USB pid/vid */
- if (!sn9c102_match_id(cam, tas5130d1b_id_table))
- return -ENODEV;
-
- sn9c102_attach_sensor(cam, &tas5130d1b);
-
- return 0;
-}
diff --git a/drivers/staging/media/solo6x10/TODO b/drivers/staging/media/solo6x10/TODO
deleted file mode 100644
index 7b8db75b1acb..000000000000
--- a/drivers/staging/media/solo6x10/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
-- batch up desc requests for more efficient use of p2m?
-- encoder on/off controls
-- mpeg cid bitrate mode (vbr/cbr)
-- mpeg cid bitrate/bitrate-peak
-- mpeg encode of user data
-- mpeg decode of user data
-- implement CID controls for mozaic areas
-
-- sound
- - implement playback via external sound jack
- - implement loopback of external sound jack with incoming audio?
- - implement pause/resume (make use of in bc-server)
-
-Please send patches to the linux media list <linux-media@vger.kernel.org> and
-Cc Ismael Luceno <ismael.luceno@corp.bluecherry.net>.
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
index e320d6bae913..9bf407d6241a 100644
--- a/drivers/staging/netlogic/xlr_net.c
+++ b/drivers/staging/netlogic/xlr_net.c
@@ -185,7 +185,6 @@ static void xlr_net_fmn_handler(int bkt, int src_stnid, int size,
if (skb_new)
send_to_rfr_fifo(priv, skb_new->data);
}
- return;
}
/* Ethtool operation */
diff --git a/drivers/staging/nokia_h4p/nokia_core.c b/drivers/staging/nokia_h4p/nokia_core.c
index 5e19cd6ccda3..775e1d043230 100644
--- a/drivers/staging/nokia_h4p/nokia_core.c
+++ b/drivers/staging/nokia_h4p/nokia_core.c
@@ -756,6 +756,7 @@ static int hci_h4p_reset(struct hci_h4p_info *info)
static int hci_h4p_hci_flush(struct hci_dev *hdev)
{
struct hci_h4p_info *info = hci_get_drvdata(hdev);
+
skb_queue_purge(&info->txq);
return 0;
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 90f1c4d7fa89..a93208adbfcf 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -232,8 +232,7 @@ static size_t nvec_msg_size(struct nvec_msg *msg)
return 2;
else if (event_length == NVEC_3BYTES)
return 3;
- else
- return 0;
+ return 0;
}
/**
@@ -807,10 +806,9 @@ static int tegra_nvec_probe(struct platform_device *pdev)
}
nvec = devm_kzalloc(&pdev->dev, sizeof(struct nvec_chip), GFP_KERNEL);
- if (nvec == NULL) {
- dev_err(&pdev->dev, "failed to reserve memory\n");
+ if (nvec == NULL)
return -ENOMEM;
- }
+
platform_set_drvdata(pdev, nvec);
nvec->dev = &pdev->dev;
@@ -823,8 +821,8 @@ static int tegra_nvec_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res) {
+ nvec->irq = platform_get_irq(pdev, 0);
+ if (nvec->irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
return -ENODEV;
}
@@ -842,7 +840,6 @@ static int tegra_nvec_probe(struct platform_device *pdev)
}
nvec->base = base;
- nvec->irq = res->start;
nvec->i2c_clk = i2c_clk;
nvec->rx = &nvec->msg_pool[0];
@@ -895,7 +892,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
}
ret = mfd_add_devices(nvec->dev, -1, nvec_devices,
- ARRAY_SIZE(nvec_devices), base, 0, NULL);
+ ARRAY_SIZE(nvec_devices), NULL, 0, NULL);
if (ret)
dev_err(nvec->dev, "error adding subdevices\n");
@@ -962,7 +959,7 @@ static int nvec_resume(struct device *dev)
}
#endif
-static const SIMPLE_DEV_PM_OPS(nvec_pm_ops, nvec_suspend, nvec_resume);
+static SIMPLE_DEV_PM_OPS(nvec_pm_ops, nvec_suspend, nvec_resume);
/* Match table for of_platform binding */
static const struct of_device_id nvidia_nvec_of_match[] = {
diff --git a/drivers/staging/nvec/nvec_paz00.c b/drivers/staging/nvec/nvec_paz00.c
index 934b796222a2..e2e675a6e95a 100644
--- a/drivers/staging/nvec/nvec_paz00.c
+++ b/drivers/staging/nvec/nvec_paz00.c
@@ -35,6 +35,7 @@ static void nvec_led_brightness_set(struct led_classdev *led_cdev,
{
struct nvec_led *led = to_nvec_led(led_cdev);
unsigned char buf[] = NVEC_LED_REQ;
+
buf[4] = value;
nvec_write_async(led->nvec, buf, sizeof(buf));
diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c
index aacfcd6954a3..6446e151866f 100644
--- a/drivers/staging/nvec/nvec_power.c
+++ b/drivers/staging/nvec/nvec_power.c
@@ -226,6 +226,7 @@ static int nvec_power_get_property(struct power_supply *psy,
union power_supply_propval *val)
{
struct nvec_power *power = dev_get_drvdata(psy->dev->parent);
+
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = power->on;
diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c
index 45b2f1308e01..f56f1db15bad 100644
--- a/drivers/staging/nvec/nvec_ps2.c
+++ b/drivers/staging/nvec/nvec_ps2.c
@@ -53,12 +53,14 @@ static struct nvec_ps2 ps2_dev;
static int ps2_startstreaming(struct serio *ser_dev)
{
unsigned char buf[] = { NVEC_PS2, AUTO_RECEIVE_N, PACKET_SIZE };
+
return nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
}
static void ps2_stopstreaming(struct serio *ser_dev)
{
unsigned char buf[] = { NVEC_PS2, CANCEL_AUTO_RECEIVE };
+
nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
}
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index c4c731f60529..095cc146eefc 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -422,8 +422,6 @@ struct cvmx_usb_state {
struct octeon_hcd {
spinlock_t lock;
struct cvmx_usb_state usb;
- struct tasklet_struct dequeue_tasklet;
- struct list_head dequeue_list;
};
/* This macro spins on a field waiting for it to reach a value */
@@ -2164,17 +2162,12 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
struct usb_hcd *hcd = octeon_to_hcd(priv);
struct device *dev = hcd->self.controller;
- urb->actual_length = bytes_transferred;
- urb->hcpriv = NULL;
+ if (likely(status == CVMX_USB_COMPLETE_SUCCESS))
+ urb->actual_length = bytes_transferred;
+ else
+ urb->actual_length = 0;
- if (!list_empty(&urb->urb_list))
- /*
- * It is on the dequeue_list, but we are going to call
- * usb_hcd_giveback_urb(), so we must clear it from
- * the list. We got to it before the
- * octeon_usb_urb_dequeue_work() tasklet did.
- */
- list_del_init(&urb->urb_list);
+ urb->hcpriv = NULL;
/* For Isochronous transactions we need to update the URB packet status
list from data in our private copy */
@@ -2241,6 +2234,7 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
urb->status = -EPROTO;
break;
}
+ usb_hcd_unlink_urb_from_ep(octeon_to_hcd(priv), urb);
spin_unlock(&priv->lock);
usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
spin_lock(&priv->lock);
@@ -2850,8 +2844,9 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
__cvmx_usb_perform_complete(usb, pipe, transaction,
CVMX_USB_COMPLETE_BABBLEERR);
} else if (usbc_hcint.s.datatglerr) {
- /* We'll retry the exact same transaction again */
- transaction->retries++;
+ /* Data toggle error */
+ __cvmx_usb_perform_complete(usb, pipe, transaction,
+ CVMX_USB_COMPLETE_DATATGLERR);
} else if (usbc_hcint.s.nyet) {
/*
* NYET as a response is only allowed in three cases: as a
@@ -3302,11 +3297,17 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
unsigned long flags;
struct cvmx_usb_iso_packet *iso_packet;
struct usb_host_endpoint *ep = urb->ep;
+ int rc;
urb->status = 0;
- INIT_LIST_HEAD(&urb->urb_list); /* not enqueued on dequeue_list */
spin_lock_irqsave(&priv->lock, flags);
+ rc = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (rc) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return rc;
+ }
+
if (!ep->hcpriv) {
enum cvmx_usb_transfer transfer_type;
enum cvmx_usb_speed speed;
@@ -3382,6 +3383,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
>> 11) & 0x3,
split_device, split_port);
if (!pipe) {
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(dev, "Failed to create pipe\n");
return -ENOMEM;
@@ -3452,6 +3454,7 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
break;
}
if (!transaction) {
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(dev, "Failed to submit\n");
return -ENOMEM;
@@ -3461,43 +3464,30 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
return 0;
}
-static void octeon_usb_urb_dequeue_work(unsigned long arg)
-{
- struct urb *urb;
- struct urb *next;
- unsigned long flags;
- struct octeon_hcd *priv = (struct octeon_hcd *)arg;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- list_for_each_entry_safe(urb, next, &priv->dequeue_list, urb_list) {
- list_del_init(&urb->urb_list);
- cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
static int octeon_usb_urb_dequeue(struct usb_hcd *hcd,
struct urb *urb,
int status)
{
struct octeon_hcd *priv = hcd_to_octeon(hcd);
unsigned long flags;
+ int rc;
if (!urb->dev)
return -EINVAL;
spin_lock_irqsave(&priv->lock, flags);
+ rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (rc)
+ goto out;
+
urb->status = status;
- list_add_tail(&urb->urb_list, &priv->dequeue_list);
+ cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
+out:
spin_unlock_irqrestore(&priv->lock, flags);
- tasklet_schedule(&priv->dequeue_tasklet);
-
- return 0;
+ return rc;
}
static void octeon_usb_endpoint_disable(struct usb_hcd *hcd,
@@ -3638,7 +3628,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
desc->bDescLength = 9;
desc->bDescriptorType = 0x29;
desc->bNbrPorts = 1;
- desc->wHubCharacteristics = 0x08;
+ desc->wHubCharacteristics = cpu_to_le16(0x08);
desc->bPwrOn2PwrGood = 1;
desc->bHubContrCurrent = 0;
desc->u.hs.DeviceRemovable[0] = 0;
@@ -3868,10 +3858,6 @@ static int octeon_usb_probe(struct platform_device *pdev)
spin_lock_init(&priv->lock);
- tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work,
- (unsigned long)priv);
- INIT_LIST_HEAD(&priv->dequeue_list);
-
status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags);
if (status) {
dev_dbg(dev, "USB initialization failed with %d\n", status);
@@ -3908,7 +3894,6 @@ static int octeon_usb_remove(struct platform_device *pdev)
unsigned long flags;
usb_remove_hcd(hcd);
- tasklet_kill(&priv->dequeue_tasklet);
spin_lock_irqsave(&priv->lock, flags);
status = cvmx_usb_shutdown(&priv->usb);
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 3f067f189b3d..ebfa9c9e71b1 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -116,7 +116,34 @@ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(priv->phydev, rq, cmd);
}
-static void cvm_oct_adjust_link(struct net_device *dev)
+static void cvm_oct_note_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t li)
+{
+ if (li.s.link_up) {
+ pr_notice_ratelimited("%s: %u Mbps %s duplex, port %d\n",
+ netdev_name(priv->netdev), li.s.speed,
+ (li.s.full_duplex) ? "Full" : "Half",
+ priv->port);
+ } else {
+ pr_notice_ratelimited("%s: Link down\n",
+ netdev_name(priv->netdev));
+ }
+}
+
+void cvm_oct_set_carrier(struct octeon_ethernet *priv,
+ cvmx_helper_link_info_t link_info)
+{
+ cvm_oct_note_carrier(priv, link_info);
+ if (link_info.s.link_up) {
+ if (!netif_carrier_ok(priv->netdev))
+ netif_carrier_on(priv->netdev);
+ } else {
+ if (netif_carrier_ok(priv->netdev))
+ netif_carrier_off(priv->netdev);
+ }
+}
+
+void cvm_oct_adjust_link(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
cvmx_helper_link_info_t link_info;
@@ -127,28 +154,32 @@ static void cvm_oct_adjust_link(struct net_device *dev)
link_info.s.link_up = priv->last_link ? 1 : 0;
link_info.s.full_duplex = priv->phydev->duplex ? 1 : 0;
link_info.s.speed = priv->phydev->speed;
+
cvmx_helper_link_set(priv->port, link_info);
- if (priv->last_link) {
- netif_carrier_on(dev);
- if (priv->queue != -1)
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, queue %2d\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port, priv->queue);
- else
- printk_ratelimited("%s: %u Mbps %s duplex, "
- "port %2d, POW\n", dev->name,
- priv->phydev->speed,
- priv->phydev->duplex ? "Full" : "Half",
- priv->port);
- } else {
- netif_carrier_off(dev);
- printk_ratelimited("%s: Link down\n", dev->name);
- }
+ cvm_oct_note_carrier(priv, link_info);
}
}
+int cvm_oct_common_stop(struct net_device *dev)
+{
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ cvmx_helper_link_info_t link_info;
+
+ priv->poll = NULL;
+
+ if (priv->phydev)
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+
+ if (priv->last_link) {
+ link_info.u64 = 0;
+ priv->last_link = 0;
+
+ cvmx_helper_link_set(priv->port, link_info);
+ cvm_oct_note_carrier(priv, link_info);
+ }
+ return 0;
+}
/**
* cvm_oct_phy_setup_device - setup the PHY
@@ -163,11 +194,11 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
struct device_node *phy_node;
if (!priv->of_node)
- return 0;
+ goto no_phy;
phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
if (!phy_node)
- return 0;
+ goto no_phy;
priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
PHY_INTERFACE_MODE_GMII);
@@ -179,4 +210,10 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
phy_start_aneg(priv->phydev);
return 0;
+no_phy:
+ /* If there is no phy, assume a direct MAC connection and that
+ * the link is up.
+ */
+ netif_carrier_on(dev);
+ return 0;
}
diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
index bf666b023190..964da860f4c4 100644
--- a/drivers/staging/octeon/ethernet-mem.c
+++ b/drivers/staging/octeon/ethernet-mem.c
@@ -46,9 +46,10 @@
static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
{
int freed = elements;
- while (freed) {
+ while (freed) {
struct sk_buff *skb = dev_alloc_skb(size + 256);
+
if (unlikely(skb == NULL))
break;
skb_reserve(skb, 256 - (((unsigned long)skb->data) & 0x7f));
@@ -81,10 +82,10 @@ static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
if (elements < 0)
pr_warn("Freeing of pool %u had too many skbuffs (%d)\n",
- pool, elements);
+ pool, elements);
else if (elements > 0)
pr_warn("Freeing of pool %u is missing %d skbuffs\n",
- pool, elements);
+ pool, elements);
}
/**
@@ -115,7 +116,7 @@ static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
memory = kmalloc(size + 256, GFP_ATOMIC);
if (unlikely(memory == NULL)) {
pr_warn("Unable to allocate %u bytes for FPA pool %d\n",
- elements * size, pool);
+ elements * size, pool);
break;
}
fpa = (char *)(((unsigned long)memory + 256) & ~0x7fUL);
@@ -136,6 +137,7 @@ static void cvm_oct_free_hw_memory(int pool, int size, int elements)
{
char *memory;
char *fpa;
+
do {
fpa = cvmx_fpa_alloc(pool);
if (fpa) {
@@ -157,6 +159,7 @@ static void cvm_oct_free_hw_memory(int pool, int size, int elements)
int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
{
int freed;
+
if (USE_SKBUFFS_IN_HW && pool == CVMX_FPA_PACKET_POOL)
freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
else
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index 0ec0da328215..651be7e1a8a7 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -36,6 +36,7 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
@@ -302,15 +303,28 @@ int cvm_oct_rgmii_open(struct net_device *dev)
int interface = INTERFACE(priv->port);
int index = INDEX(priv->port);
cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 1;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_rgmii_poll;
+ }
}
return 0;
@@ -326,7 +340,7 @@ int cvm_oct_rgmii_stop(struct net_device *dev)
gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
gmx_cfg.s.en = 0;
cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
+ return cvm_oct_common_stop(dev);
}
static void cvm_oct_rgmii_immediate_poll(struct work_struct *work)
@@ -384,7 +398,6 @@ int cvm_oct_rgmii_init(struct net_device *dev)
gmx_rx_int_en.s.phy_spd = 1;
cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
gmx_rx_int_en.u64);
- priv->poll = cvm_oct_rgmii_poll;
}
}
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
index d3e82430eba6..e1878449e683 100644
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,45 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_sgmii_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
-
- return 0;
-}
-
-int cvm_oct_sgmii_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_sgmii_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -109,13 +77,58 @@ static void cvm_oct_sgmii_poll(struct net_device *dev)
}
}
-int cvm_oct_sgmii_init(struct net_device *dev)
+int cvm_oct_sgmii_open(struct net_device *dev)
{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_sgmii_poll;
+ cvm_oct_sgmii_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_sgmii_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
+int cvm_oct_sgmii_init(struct net_device *dev)
+{
cvm_oct_common_init(dev);
dev->netdev_ops->ndo_stop(dev);
- if (!octeon_is_simulation() && priv->phydev == NULL)
- priv->poll = cvm_oct_sgmii_poll;
/* FIXME: Need autoneg logic */
return 0;
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
index 419f8c34ecdf..3cc286ee3599 100644
--- a/drivers/staging/octeon/ethernet-xaui.c
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -24,6 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
**********************************************************************/
+#include <linux/phy.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/ratelimit.h>
@@ -34,44 +35,12 @@
#include "ethernet-defines.h"
#include "octeon-ethernet.h"
#include "ethernet-util.h"
+#include "ethernet-mdio.h"
#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-gmxx-defs.h>
-int cvm_oct_xaui_open(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
- cvmx_helper_link_info_t link_info;
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 1;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
-
- if (!octeon_is_simulation()) {
- link_info = cvmx_helper_link_get(priv->port);
- if (!link_info.s.link_up)
- netif_carrier_off(dev);
- }
- return 0;
-}
-
-int cvm_oct_xaui_stop(struct net_device *dev)
-{
- union cvmx_gmxx_prtx_cfg gmx_cfg;
- struct octeon_ethernet *priv = netdev_priv(dev);
- int interface = INTERFACE(priv->port);
- int index = INDEX(priv->port);
-
- gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
- gmx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
- return 0;
-}
-
static void cvm_oct_xaui_poll(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
@@ -108,9 +77,58 @@ static void cvm_oct_xaui_poll(struct net_device *dev)
}
}
+int cvm_oct_xaui_open(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+ cvmx_helper_link_info_t link_info;
+ int rv;
+
+ rv = cvm_oct_phy_setup_device(dev);
+ if (rv)
+ return rv;
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 1;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+ if (octeon_is_simulation())
+ return 0;
+
+ if (priv->phydev) {
+ int r = phy_read_status(priv->phydev);
+ if (r == 0 && priv->phydev->link == 0)
+ netif_carrier_off(dev);
+ cvm_oct_adjust_link(dev);
+ } else {
+ link_info = cvmx_helper_link_get(priv->port);
+ if (!link_info.s.link_up)
+ netif_carrier_off(dev);
+ priv->poll = cvm_oct_xaui_poll;
+ cvm_oct_xaui_poll(dev);
+ }
+ return 0;
+}
+
+int cvm_oct_xaui_stop(struct net_device *dev)
+{
+ union cvmx_gmxx_prtx_cfg gmx_cfg;
+ struct octeon_ethernet *priv = netdev_priv(dev);
+ int interface = INTERFACE(priv->port);
+ int index = INDEX(priv->port);
+
+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+ gmx_cfg.s.en = 0;
+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+ return cvm_oct_common_stop(dev);
+}
+
int cvm_oct_xaui_init(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
+
cvm_oct_common_init(dev);
dev->netdev_ops->ndo_stop(dev);
if (!octeon_is_simulation() && priv->phydev == NULL)
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index da9dd6bc5660..2aa723562155 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -471,7 +471,6 @@ int cvm_oct_common_init(struct net_device *dev)
dev->features |= NETIF_F_LLTX;
dev->ethtool_ops = &cvm_oct_ethtool_ops;
- cvm_oct_phy_setup_device(dev);
cvm_oct_set_mac_filter(dev);
dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
@@ -722,6 +721,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
/* Initialize the device private structure. */
priv = netdev_priv(dev);
+ priv->netdev = dev;
priv->of_node = cvm_oct_node_for_port(pip, interface,
port_index);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index 4cf3884070fa..d0e321119914 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -44,6 +44,8 @@ struct octeon_ethernet {
int queue;
/* Hardware fetch and add to count outstanding tx buffers */
int fau;
+ /* My netdev. */
+ struct net_device *netdev;
/*
* Type of port. This is one of the enums in
* cvmx_helper_interface_mode_t
@@ -85,6 +87,8 @@ extern int cvm_oct_xaui_stop(struct net_device *dev);
extern int cvm_oct_common_init(struct net_device *dev);
extern void cvm_oct_common_uninit(struct net_device *dev);
+void cvm_oct_adjust_link(struct net_device *dev);
+int cvm_oct_common_stop(struct net_device *dev);
extern int always_use_pow;
extern int pow_send_group;
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 4e9229363c36..6d1a32097d3c 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -1800,11 +1800,12 @@ static inline int input_state_high(struct logical_input *input)
input->high_timer++;
}
return 1;
- } else {
- /* else signal falling down. Let's fall through. */
- input->state = INPUT_ST_FALLING;
- input->fall_timer = 0;
}
+
+ /* else signal falling down. Let's fall through. */
+ input->state = INPUT_ST_FALLING;
+ input->fall_timer = 0;
+
return 0;
}
diff --git a/drivers/staging/phison/Kconfig b/drivers/staging/phison/Kconfig
deleted file mode 100644
index 1b56119a7657..000000000000
--- a/drivers/staging/phison/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config IDE_PHISON
- tristate "PCIE ATA PS5000 IDE support"
- depends on PCI && ATA && ATA_SFF && ATA_BMDMA
- ---help---
- This is an experimental driver for PS5000 IDE driver.
diff --git a/drivers/staging/phison/Makefile b/drivers/staging/phison/Makefile
deleted file mode 100644
index 7642a2190e91..000000000000
--- a/drivers/staging/phison/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_IDE_PHISON) += phison.o
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
deleted file mode 100644
index 3826561e7742..000000000000
--- a/drivers/staging/phison/phison.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2006 Red Hat <evan_ko@phison.com>
- *
- * May be copied or modified under the terms of the GNU General Public License
- *
- * [Modify History]
- * #0001, Evan, 2008.10.22, V0.00, New release.
- * #0002, Evan, 2008.11.01, V0.90, Test Work In Ubuntu Linux 8.04.
- * #0003, Evan, 2008.01.08, V0.91, Change Name "PCIE-SSD" to "E-BOX".
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <scsi/scsi_host.h>
-#include <linux/libata.h>
-#include <linux/ata.h>
-
-#define PHISON_DEBUG
-
-#define DRV_NAME "phison_e-box" /* #0003 */
-#define DRV_VERSION "0.91" /* #0003 */
-
-#define PCI_VENDOR_ID_PHISON 0x1987
-#define PCI_DEVICE_ID_PS5000 0x5000
-
-static int phison_pre_reset(struct ata_link *link, unsigned long deadline)
-{
- int ret;
- struct ata_port *ap = link->ap;
-
- ap->cbl = ATA_CBL_NONE;
- ret = ata_std_prereset(link, deadline);
- dev_dbg(ap->dev, "phison_pre_reset(), ret = %x\n", ret);
- return ret;
-}
-
-static struct scsi_host_template phison_sht = {
- ATA_BMDMA_SHT(DRV_NAME),
-};
-
-static struct ata_port_operations phison_ops = {
- .inherits = &ata_bmdma_port_ops,
- .prereset = phison_pre_reset,
-};
-
-static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- int ret;
- struct ata_port_info info = {
- .flags = ATA_FLAG_NO_ATAPI,
-
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5,
-
- .port_ops = &phison_ops,
- };
- const struct ata_port_info *ppi[] = { &info, NULL };
-
- ret = ata_pci_bmdma_init_one(pdev, ppi, &phison_sht, NULL, 0);
-
- dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret);
-
- return ret;
-}
-
-static const struct pci_device_id phison_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000),
- PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
- { 0, },
-};
-MODULE_DEVICE_TABLE(pci, phison_pci_tbl);
-
-static struct pci_driver phison_pci_driver = {
- .name = DRV_NAME,
- .id_table = phison_pci_tbl,
- .probe = phison_init_one,
- .remove = ata_pci_remove_one,
-#ifdef CONFIG_PM /* haven't tested it. */
- .suspend = ata_pci_device_suspend,
- .resume = ata_pci_device_resume,
-#endif
-};
-
-module_pci_driver(phison_pci_driver);
-
-MODULE_AUTHOR("Evan Ko");
-MODULE_DESCRIPTION("PCIE driver module for PHISON PS5000 E-BOX");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/staging/quickstart/Kconfig b/drivers/staging/quickstart/Kconfig
deleted file mode 100644
index 5bea4875d373..000000000000
--- a/drivers/staging/quickstart/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config ACPI_QUICKSTART
- tristate "ACPI Quickstart key driver"
- depends on ACPI && INPUT
- help
- Say Y here if you have a platform that supports the ACPI
- quickstart key protocol.
-
- To compile this driver as a module, choose M here: the module will be
- called quickstart.
-
diff --git a/drivers/staging/quickstart/Makefile b/drivers/staging/quickstart/Makefile
deleted file mode 100644
index 290e0e476797..000000000000
--- a/drivers/staging/quickstart/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_ACPI_QUICKSTART) += quickstart.o
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
deleted file mode 100644
index a85c3d68c462..000000000000
--- a/drivers/staging/quickstart/quickstart.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * quickstart.c - ACPI Direct App Launch driver
- *
- *
- * Copyright (C) 2007-2010 Angelo Arrifano <miknix@gmail.com>
- *
- * Information gathered from disassembled dsdt and from here:
- * <http://www.microsoft.com/whdc/system/platform/firmware/DirAppLaunch.mspx>
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define QUICKSTART_VERSION "1.04"
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/acpi.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-
-MODULE_AUTHOR("Angelo Arrifano");
-MODULE_DESCRIPTION("ACPI Direct App Launch driver");
-MODULE_LICENSE("GPL");
-
-#define QUICKSTART_ACPI_DEVICE_NAME "quickstart"
-#define QUICKSTART_ACPI_CLASS "quickstart"
-#define QUICKSTART_ACPI_HID "PNP0C32"
-
-#define QUICKSTART_PF_DRIVER_NAME "quickstart"
-#define QUICKSTART_PF_DEVICE_NAME "quickstart"
-
-/*
- * There will be two events:
- * 0x02 - A hot button was pressed while device was off/sleeping.
- * 0x80 - A hot button was pressed while device was up.
- */
-#define QUICKSTART_EVENT_WAKE 0x02
-#define QUICKSTART_EVENT_RUNTIME 0x80
-
-struct quickstart_button {
- char *name;
- unsigned int id;
- struct list_head list;
-};
-
-struct quickstart_acpi {
- struct acpi_device *device;
- struct quickstart_button *button;
-};
-
-static LIST_HEAD(buttons);
-static struct quickstart_button *pressed;
-
-static struct input_dev *quickstart_input;
-
-/* Platform driver functions */
-static ssize_t buttons_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- int count = 0;
- struct quickstart_button *b;
-
- if (list_empty(&buttons))
- return snprintf(buf, PAGE_SIZE, "none");
-
- list_for_each_entry(b, &buttons, list) {
- count += snprintf(buf + count, PAGE_SIZE - count, "%u\t%s\n",
- b->id, b->name);
-
- if (count >= PAGE_SIZE) {
- count = PAGE_SIZE;
- break;
- }
- }
-
- return count;
-}
-
-static ssize_t pressed_button_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%s\n",
- (pressed ? pressed->name : "none"));
-}
-
-
-static ssize_t pressed_button_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- if (count < 2)
- return -EINVAL;
-
- if (strncasecmp(buf, "none", 4) != 0)
- return -EINVAL;
-
- pressed = NULL;
- return count;
-}
-
-/* Helper functions */
-static struct quickstart_button *quickstart_buttons_add(void)
-{
- struct quickstart_button *b;
-
- b = kzalloc(sizeof(*b), GFP_KERNEL);
- if (!b)
- return NULL;
-
- list_add_tail(&b->list, &buttons);
-
- return b;
-}
-
-static void quickstart_button_del(struct quickstart_button *data)
-{
- if (!data)
- return;
-
- list_del(&data->list);
- kfree(data->name);
- kfree(data);
-}
-
-static void quickstart_buttons_free(void)
-{
- struct quickstart_button *b, *n;
-
- list_for_each_entry_safe(b, n, &buttons, list)
- quickstart_button_del(b);
-}
-
-/* ACPI Driver functions */
-static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data)
-{
- struct quickstart_acpi *quickstart = data;
-
- if (!quickstart)
- return;
-
- switch (event) {
- case QUICKSTART_EVENT_WAKE:
- pressed = quickstart->button;
- break;
- case QUICKSTART_EVENT_RUNTIME:
- input_report_key(quickstart_input, quickstart->button->id, 1);
- input_sync(quickstart_input);
- input_report_key(quickstart_input, quickstart->button->id, 0);
- input_sync(quickstart_input);
- break;
- default:
- pr_err("Unexpected ACPI event notify (%u)\n", event);
- break;
- }
-}
-
-static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart)
-{
- acpi_status status;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- int ret = 0;
-
- /*
- * This returns a buffer telling the button usage ID,
- * and triggers pending notify events (The ones before booting).
- */
- status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL,
- &buffer);
- if (ACPI_FAILURE(status)) {
- pr_err("%s GHID method failed\n", quickstart->button->name);
- return -EINVAL;
- }
-
- /*
- * <<The GHID method can return a BYTE, WORD, or DWORD.
- * The value must be encoded in little-endian byte
- * order (least significant byte first).>>
- */
- switch (buffer.length) {
- case 1:
- quickstart->button->id = *(uint8_t *)buffer.pointer;
- break;
- case 2:
- quickstart->button->id = *(uint16_t *)buffer.pointer;
- break;
- case 4:
- quickstart->button->id = *(uint32_t *)buffer.pointer;
- break;
- case 8:
- quickstart->button->id = *(uint64_t *)buffer.pointer;
- break;
- default:
- pr_err("%s GHID method returned buffer of unexpected length %lu\n",
- quickstart->button->name,
- (unsigned long)buffer.length);
- ret = -EINVAL;
- break;
- }
-
- kfree(buffer.pointer);
-
- return ret;
-}
-
-static int quickstart_acpi_config(struct quickstart_acpi *quickstart)
-{
- char *bid = acpi_device_bid(quickstart->device);
- char *name;
-
- name = kmalloc(strlen(bid) + 1, GFP_KERNEL);
- if (!name)
- return -ENOMEM;
-
- /* Add new button to list */
- quickstart->button = quickstart_buttons_add();
- if (!quickstart->button) {
- kfree(name);
- return -ENOMEM;
- }
-
- quickstart->button->name = name;
- strcpy(quickstart->button->name, bid);
-
- return 0;
-}
-
-static int quickstart_acpi_add(struct acpi_device *device)
-{
- int ret;
- acpi_status status;
- struct quickstart_acpi *quickstart;
-
- if (!device)
- return -EINVAL;
-
- quickstart = kzalloc(sizeof(*quickstart), GFP_KERNEL);
- if (!quickstart)
- return -ENOMEM;
-
- quickstart->device = device;
-
- strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME);
- strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS);
- device->driver_data = quickstart;
-
- /* Add button to list and initialize some stuff */
- ret = quickstart_acpi_config(quickstart);
- if (ret < 0)
- goto fail_config;
-
- status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY,
- quickstart_acpi_notify,
- quickstart);
- if (ACPI_FAILURE(status)) {
- pr_err("Notify handler install error\n");
- ret = -ENODEV;
- goto fail_installnotify;
- }
-
- ret = quickstart_acpi_ghid(quickstart);
- if (ret < 0)
- goto fail_ghid;
-
- return 0;
-
-fail_ghid:
- acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
- quickstart_acpi_notify);
-
-fail_installnotify:
- quickstart_button_del(quickstart->button);
-
-fail_config:
-
- kfree(quickstart);
-
- return ret;
-}
-
-static int quickstart_acpi_remove(struct acpi_device *device)
-{
- acpi_status status;
- struct quickstart_acpi *quickstart;
-
- if (!device)
- return -EINVAL;
-
- quickstart = acpi_driver_data(device);
- if (!quickstart)
- return -EINVAL;
-
- status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
- quickstart_acpi_notify);
- if (ACPI_FAILURE(status))
- pr_err("Error removing notify handler\n");
-
- kfree(quickstart);
-
- return 0;
-}
-
-/* Platform driver structs */
-static DEVICE_ATTR_RW(pressed_button);
-static DEVICE_ATTR_RO(buttons);
-static struct platform_device *pf_device;
-static struct platform_driver pf_driver = {
- .driver = {
- .name = QUICKSTART_PF_DRIVER_NAME,
- .owner = THIS_MODULE,
- }
-};
-
-static const struct acpi_device_id quickstart_device_ids[] = {
- {QUICKSTART_ACPI_HID, 0},
- {"", 0},
-};
-
-static struct acpi_driver quickstart_acpi_driver = {
- .name = "quickstart",
- .class = QUICKSTART_ACPI_CLASS,
- .ids = quickstart_device_ids,
- .ops = {
- .add = quickstart_acpi_add,
- .remove = quickstart_acpi_remove,
- },
-};
-
-/* Module functions */
-static void quickstart_exit(void)
-{
- input_unregister_device(quickstart_input);
-
- device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
- device_remove_file(&pf_device->dev, &dev_attr_buttons);
-
- platform_device_unregister(pf_device);
-
- platform_driver_unregister(&pf_driver);
-
- acpi_bus_unregister_driver(&quickstart_acpi_driver);
-
- quickstart_buttons_free();
-}
-
-static int __init quickstart_init_input(void)
-{
- struct quickstart_button *b;
- int ret;
-
- quickstart_input = input_allocate_device();
-
- if (!quickstart_input)
- return -ENOMEM;
-
- quickstart_input->name = "Quickstart ACPI Buttons";
- quickstart_input->id.bustype = BUS_HOST;
-
- list_for_each_entry(b, &buttons, list) {
- set_bit(EV_KEY, quickstart_input->evbit);
- set_bit(b->id, quickstart_input->keybit);
- }
-
- ret = input_register_device(quickstart_input);
- if (ret) {
- input_free_device(quickstart_input);
- return ret;
- }
-
- return 0;
-}
-
-static int __init quickstart_init(void)
-{
- int ret;
-
- /* ACPI driver register */
- ret = acpi_bus_register_driver(&quickstart_acpi_driver);
- if (ret)
- return ret;
-
- /* If existing bus with no devices */
- if (list_empty(&buttons)) {
- ret = -ENODEV;
- goto fail_pfdrv_reg;
- }
-
- /* Platform driver register */
- ret = platform_driver_register(&pf_driver);
- if (ret)
- goto fail_pfdrv_reg;
-
- /* Platform device register */
- pf_device = platform_device_alloc(QUICKSTART_PF_DEVICE_NAME, -1);
- if (!pf_device) {
- ret = -ENOMEM;
- goto fail_pfdev_alloc;
- }
- ret = platform_device_add(pf_device);
- if (ret)
- goto fail_pfdev_add;
-
- /* Create device sysfs file */
- ret = device_create_file(&pf_device->dev, &dev_attr_pressed_button);
- if (ret)
- goto fail_dev_file;
-
- ret = device_create_file(&pf_device->dev, &dev_attr_buttons);
- if (ret)
- goto fail_dev_file2;
-
- /* Input device */
- ret = quickstart_init_input();
- if (ret)
- goto fail_input;
-
- pr_info("ACPI Direct App Launch ver %s\n", QUICKSTART_VERSION);
-
- return 0;
-fail_input:
- device_remove_file(&pf_device->dev, &dev_attr_buttons);
-
-fail_dev_file2:
- device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
-
-fail_dev_file:
- platform_device_del(pf_device);
-
-fail_pfdev_add:
- platform_device_put(pf_device);
-
-fail_pfdev_alloc:
- platform_driver_unregister(&pf_driver);
-
-fail_pfdrv_reg:
- acpi_bus_unregister_driver(&quickstart_acpi_driver);
-
- return ret;
-}
-
-module_init(quickstart_init);
-module_exit(quickstart_exit);
diff --git a/drivers/staging/rtl8188eu/Kconfig b/drivers/staging/rtl8188eu/Kconfig
index e45c106c2162..5a38b4149408 100644
--- a/drivers/staging/rtl8188eu/Kconfig
+++ b/drivers/staging/rtl8188eu/Kconfig
@@ -17,12 +17,4 @@ config 88EU_AP_MODE
will never be used as an AP, or the target system has limited memory,
"Y" should be selected.
-config 88EU_P2P
- bool "Realtek RTL8188EU Peer-to-peer mode"
- default y
- ---help---
- This option enables peer-to-peer mode for the r8188eu driver. Unless you
- know that peer-to-peer (P2P) mode will never be used, or the target system has
- limited memory, "Y" should be selected.
-
endif
diff --git a/drivers/staging/rtl8188eu/Makefile b/drivers/staging/rtl8188eu/Makefile
index 6a138ff699e9..aeebf9311f15 100644
--- a/drivers/staging/rtl8188eu/Makefile
+++ b/drivers/staging/rtl8188eu/Makefile
@@ -1,20 +1,15 @@
r8188eu-y := \
core/rtw_ap.o \
- core/rtw_br_ext.o \
core/rtw_cmd.o \
core/rtw_debug.o \
core/rtw_efuse.o \
core/rtw_ieee80211.o \
- core/rtw_io.o \
core/rtw_ioctl_set.o \
core/rtw_iol.o \
core/rtw_led.o \
core/rtw_mlme.o \
core/rtw_mlme_ext.o \
- core/rtw_mp.o \
- core/rtw_mp_ioctl.o \
core/rtw_pwrctrl.o \
- core/rtw_p2p.o \
core/rtw_recv.o \
core/rtw_rf.o \
core/rtw_security.o \
@@ -25,7 +20,6 @@ r8188eu-y := \
hal/HalHWImg8188E_MAC.o \
hal/HalHWImg8188E_BB.o \
hal/HalHWImg8188E_RF.o \
- hal/HalPhyRf.o \
hal/HalPhyRf_8188e.o \
hal/HalPwrSeqCmd.o \
hal/Hal8188EPwrSeq.o \
@@ -40,17 +34,14 @@ r8188eu-y := \
hal/rtl8188e_cmd.o \
hal/rtl8188e_dm.o \
hal/rtl8188e_hal_init.o \
- hal/rtl8188e_mp.o \
hal/rtl8188e_phycfg.o \
hal/rtl8188e_rf6052.o \
hal/rtl8188e_rxdesc.o \
- hal/rtl8188e_sreset.o \
hal/rtl8188e_xmit.o \
hal/rtl8188eu_led.o \
hal/rtl8188eu_recv.o \
hal/rtl8188eu_xmit.o \
hal/usb_halinit.o \
- hal/usb_ops_linux.o \
os_dep/ioctl_linux.o \
os_dep/mlme_linux.o \
os_dep/os_intfs.o \
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index 85fda6128db9..9224e029ef2b 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -288,14 +288,14 @@ void expire_timeout_chk(struct adapter *padapter)
plist = phead->next;
/* check auth_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, auth_list);
plist = plist->next;
if (psta->expire_to > 0) {
psta->expire_to--;
if (psta->expire_to == 0) {
- rtw_list_delete(&psta->auth_list);
+ list_del_init(&psta->auth_list);
pstapriv->auth_list_cnt--;
DBG_88E("auth expire %6ph\n",
@@ -322,7 +322,7 @@ void expire_timeout_chk(struct adapter *padapter)
plist = phead->next;
/* check asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, asoc_list);
plist = plist->next;
@@ -365,7 +365,7 @@ void expire_timeout_chk(struct adapter *padapter)
continue;
}
- rtw_list_delete(&psta->asoc_list);
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
@@ -421,7 +421,7 @@ void expire_timeout_chk(struct adapter *padapter)
DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
spin_lock_bh(&pstapriv->asoc_list_lock);
- rtw_list_delete(&psta->asoc_list);
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
spin_unlock_bh(&pstapriv->asoc_list_lock);
@@ -548,7 +548,7 @@ static void update_bmc_sta(struct adapter *padapter)
psta->ieee8021x_blocked = 0;
- _rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
+ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
/* prepare for add_RATid */
supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
@@ -671,7 +671,7 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
/* todo: init other variables */
- _rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
+ memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
spin_lock_bh(&psta->lock);
psta->state |= _FW_LINKED;
@@ -723,9 +723,6 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
struct HT_info_element *pht_info = NULL;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
cur_channel = pnetwork->Configuration.DSConfig;
@@ -827,11 +824,6 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
/* let pnetwork_mlmeext == pnetwork_mlme. */
memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
-#ifdef CONFIG_88EU_P2P
- memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
- pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
-#endif /* CONFIG_88EU_P2P */
-
if (pmlmeext->bstart_bss) {
update_beacon(padapter, _TIM_IE_, NULL, false);
@@ -886,7 +878,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pbss_network->IELength = len;
- _rtw_memset(ie, 0, MAX_IE_SZ);
+ memset(ie, 0, MAX_IE_SZ);
memcpy(ie, pbuf, pbss_network->IELength);
@@ -900,15 +892,15 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
/* beacon interval */
p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
- pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
+ pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p);
/* capability */
- cap = RTW_GET_LE16(ie);
+ cap = get_unaligned_le16(ie);
/* SSID */
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p && ie_len > 0) {
- _rtw_memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
+ memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
pbss_network->Ssid.SsidLength = ie_len;
}
@@ -922,7 +914,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pbss_network->Configuration.DSConfig = channel;
- _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
+ memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
/* get supported rates */
p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
if (p != NULL) {
@@ -1146,7 +1138,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
phead = get_list_head(pacl_node_q);
plist = phead->next;
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
plist = plist->next;
@@ -1170,13 +1162,13 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
paclnode = &pacl_list->aclnode[i];
if (!paclnode->valid) {
- _rtw_init_listhead(&paclnode->list);
+ INIT_LIST_HEAD(&paclnode->list);
memcpy(paclnode->addr, addr, ETH_ALEN);
paclnode->valid = true;
- rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
+ list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
pacl_list->num++;
@@ -1207,7 +1199,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
phead = get_list_head(pacl_node_q);
plist = phead->next;
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
plist = plist->next;
@@ -1215,7 +1207,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
if (paclnode->valid) {
paclnode->valid = false;
- rtw_list_delete(&paclnode->list);
+ list_del_init(&paclnode->list);
pacl_list->num--;
}
@@ -1505,7 +1497,7 @@ void associated_clients_update(struct adapter *padapter, u8 updated)
plist = phead->next;
/* check asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, asoc_list);
plist = plist->next;
@@ -1779,7 +1771,7 @@ int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset)
plist = phead->next;
/* for each sta in asoc_queue */
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, asoc_list);
plist = plist->next;
@@ -1813,12 +1805,12 @@ int rtw_sta_flush(struct adapter *padapter)
plist = phead->next;
/* free sta asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, asoc_list);
plist = plist->next;
- rtw_list_delete(&psta->asoc_list);
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
@@ -1910,11 +1902,11 @@ void start_ap_mode(struct adapter *padapter)
pmlmepriv->p2p_probe_resp_ie = NULL;
/* for ACL */
- _rtw_init_listhead(&(pacl_list->acl_node_q.queue));
+ INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
pacl_list->num = 0;
pacl_list->mode = 0;
for (i = 0; i < NUM_ACL; i++) {
- _rtw_init_listhead(&pacl_list->aclnode[i].list);
+ INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
pacl_list->aclnode[i].valid = false;
}
}
@@ -1934,7 +1926,7 @@ void stop_ap_mode(struct adapter *padapter)
pmlmeext->bstart_bss = false;
/* reset and init security priv , this can refine with rtw_reset_securitypriv */
- _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
+ memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
@@ -1942,14 +1934,14 @@ void stop_ap_mode(struct adapter *padapter)
spin_lock_bh(&(pacl_node_q->lock));
phead = get_list_head(pacl_node_q);
plist = phead->next;
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
plist = plist->next;
if (paclnode->valid) {
paclnode->valid = false;
- rtw_list_delete(&paclnode->list);
+ list_del_init(&paclnode->list);
pacl_list->num--;
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_br_ext.c b/drivers/staging/rtl8188eu/core/rtw_br_ext.c
deleted file mode 100644
index f97f05f4165e..000000000000
--- a/drivers/staging/rtl8188eu/core/rtw_br_ext.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_BR_EXT_C_
-
-#include <linux/if_arp.h>
-#include <net/ip.h>
-#include <net/ipx.h>
-#include <linux/atalk.h>
-#include <linux/udp.h>
-#include <linux/if_pppox.h>
-
-#include <drv_types.h>
-#include "rtw_br_ext.h"
-#include <usb_osintf.h>
-#include <recv_osdep.h>
-
-#ifndef csum_ipv6_magic
-#include <net/ip6_checksum.h>
-#endif
-
-#include <linux/ipv6.h>
-#include <linux/icmpv6.h>
-#include <net/ndisc.h>
-#include <net/checksum.h>
-
-#define NAT25_IPV4 01
-#define NAT25_IPV6 02
-#define NAT25_IPX 03
-#define NAT25_APPLE 04
-#define NAT25_PPPOE 05
-
-#define RTL_RELAY_TAG_LEN (ETH_ALEN)
-#define TAG_HDR_LEN 4
-
-#define MAGIC_CODE 0x8186
-#define MAGIC_CODE_LEN 2
-#define WAIT_TIME_PPPOE 5 /* waiting time for pppoe server in sec */
-
-/*-----------------------------------------------------------------
- How database records network address:
- 0 1 2 3 4 5 6 7 8 9 10
- |----|----|----|----|----|----|----|----|----|----|----|
- IPv4 |type| | IP addr |
- IPX |type| Net addr | Node addr |
- IPX |type| Net addr |Sckt addr|
- Apple |type| Network |node|
- PPPoE |type| SID | AC MAC |
------------------------------------------------------------------*/
-
-
-/* Find a tag in pppoe frame and return the pointer */
-static inline unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
-{
- unsigned char *cur_ptr, *start_ptr;
- unsigned short tagLen, tagType;
-
- start_ptr = cur_ptr = (unsigned char *)ph->tag;
- while ((cur_ptr - start_ptr) < ntohs(ph->length)) {
- /* prevent un-alignment access */
- tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]);
- tagLen = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]);
- if (tagType == type)
- return cur_ptr;
- cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen;
- }
- return NULL;
-}
-
-
-static inline int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
-{
- struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
- int data_len;
-
- data_len = be16_to_cpu(tag->tag_len) + TAG_HDR_LEN;
- if (skb_tailroom(skb) < data_len) {
- _DEBUG_ERR("skb_tailroom() failed in add SID tag!\n");
- return -1;
- }
-
- skb_put(skb, data_len);
- /* have a room for new tag */
- memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length));
- ph->length = htons(ntohs(ph->length) + data_len);
- memcpy((unsigned char *)ph->tag, tag, data_len);
- return data_len;
-}
-
-static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
-{
- int tail_len;
- unsigned long end, tail;
-
- if ((src+len) > skb_tail_pointer(skb) || skb->len < len)
- return -1;
-
- tail = (unsigned long)skb_tail_pointer(skb);
- end = (unsigned long)src+len;
- if (tail < end)
- return -1;
-
- tail_len = (int)(tail-end);
- if (tail_len > 0)
- memmove(src, src+len, tail_len);
-
- skb_trim(skb, skb->len-len);
- return 0;
-}
-
-static inline unsigned long __nat25_timeout(struct adapter *priv)
-{
- unsigned long timeout;
-
- timeout = jiffies - NAT25_AGEING_TIME*HZ;
-
- return timeout;
-}
-
-
-static inline int __nat25_has_expired(struct adapter *priv,
- struct nat25_network_db_entry *fdb)
-{
- if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv)))
- return 1;
-
- return 0;
-}
-
-
-static inline void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr,
- unsigned int *ipAddr)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_IPV4;
- memcpy(networkAddr+7, (unsigned char *)ipAddr, 4);
-}
-
-
-static inline void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr,
- __be32 *ipxNetAddr, unsigned char *ipxNodeAddr)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_IPX;
- memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
- memcpy(networkAddr+5, ipxNodeAddr, 6);
-}
-
-
-static inline void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr,
- __be32 *ipxNetAddr, __be16 *ipxSocketAddr)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_IPX;
- memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
- memcpy(networkAddr+5, (unsigned char *)ipxSocketAddr, 2);
-}
-
-
-static inline void __nat25_generate_apple_network_addr(unsigned char *networkAddr,
- __be16 *network, unsigned char *node)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_APPLE;
- memcpy(networkAddr+1, (unsigned char *)network, 2);
- networkAddr[3] = *node;
-}
-
-static inline void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr,
- unsigned char *ac_mac, __be16 *sid)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_PPPOE;
- memcpy(networkAddr+1, (unsigned char *)sid, 2);
- memcpy(networkAddr+3, (unsigned char *)ac_mac, 6);
-}
-
-static void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr,
- __be32 *ipAddr)
-{
- memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
-
- networkAddr[0] = NAT25_IPV6;
- memcpy(networkAddr+1, (unsigned char *)ipAddr, 16);
-}
-
-static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b)
-{
- while (len > 0) {
- if (*data == tag && *(data+1) == len8b && len >= len8b*8)
- return data+2;
-
- len -= (*(data+1))*8;
- data += (*(data+1))*8;
- }
- return NULL;
-}
-
-static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac)
-{
- struct icmp6hdr *icmphdr = (struct icmp6hdr *)data;
- unsigned char *mac;
-
- if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) {
- if (len >= 8) {
- mac = scan_tlv(&data[8], len-8, 1, 1);
- if (mac) {
- _DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
- memcpy(mac, replace_mac, 6);
- return 1;
- }
- }
- } else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) {
- if (len >= 16) {
- mac = scan_tlv(&data[16], len-16, 1, 1);
- if (mac) {
- _DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
- memcpy(mac, replace_mac, 6);
- return 1;
- }
- }
- } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
- if (len >= 24) {
- mac = scan_tlv(&data[24], len-24, 1, 1);
- if (mac) {
- _DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
- memcpy(mac, replace_mac, 6);
- return 1;
- }
- }
- } else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
- if (len >= 24) {
- mac = scan_tlv(&data[24], len-24, 2, 1);
- if (mac) {
- _DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
- memcpy(mac, replace_mac, 6);
- return 1;
- }
- }
- } else if (icmphdr->icmp6_type == NDISC_REDIRECT) {
- if (len >= 40) {
- mac = scan_tlv(&data[40], len-40, 2, 1);
- if (mac) {
- _DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
- replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]);
- memcpy(mac, replace_mac, 6);
- return 1;
- }
- }
- }
- return 0;
-}
-
-static inline int __nat25_network_hash(unsigned char *networkAddr)
-{
- if (networkAddr[0] == NAT25_IPV4) {
- unsigned long x;
-
- x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
-
- return x & (NAT25_HASH_SIZE - 1);
- } else if (networkAddr[0] == NAT25_IPX) {
- unsigned long x;
-
- x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
- networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
-
- return x & (NAT25_HASH_SIZE - 1);
- } else if (networkAddr[0] == NAT25_APPLE) {
- unsigned long x;
-
- x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3];
-
- return x & (NAT25_HASH_SIZE - 1);
- } else if (networkAddr[0] == NAT25_PPPOE) {
- unsigned long x;
-
- x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8];
-
- return x & (NAT25_HASH_SIZE - 1);
- } else if (networkAddr[0] == NAT25_IPV6) {
- unsigned long x;
-
- x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
- networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^
- networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^
- networkAddr[16];
-
- return x & (NAT25_HASH_SIZE - 1);
- } else {
- unsigned long x = 0;
- int i;
-
- for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++)
- x ^= networkAddr[i];
-
- return x & (NAT25_HASH_SIZE - 1);
- }
-}
-
-static inline void __network_hash_link(struct adapter *priv,
- struct nat25_network_db_entry *ent, int hash)
-{
- /* Caller must spin_lock_bh already! */
- ent->next_hash = priv->nethash[hash];
- if (ent->next_hash != NULL)
- ent->next_hash->pprev_hash = &ent->next_hash;
- priv->nethash[hash] = ent;
- ent->pprev_hash = &priv->nethash[hash];
-}
-
-static inline void __network_hash_unlink(struct nat25_network_db_entry *ent)
-{
- /* Caller must spin_lock_bh already! */
- *(ent->pprev_hash) = ent->next_hash;
- if (ent->next_hash != NULL)
- ent->next_hash->pprev_hash = ent->pprev_hash;
- ent->next_hash = NULL;
- ent->pprev_hash = NULL;
-}
-
-static int __nat25_db_network_lookup_and_replace(struct adapter *priv,
- struct sk_buff *skb, unsigned char *networkAddr)
-{
- struct nat25_network_db_entry *db;
- spin_lock_bh(&priv->br_ext_lock);
-
- db = priv->nethash[__nat25_network_hash(networkAddr)];
- while (db != NULL) {
- if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
- if (!__nat25_has_expired(priv, db)) {
- /* replace the destination mac address */
- memcpy(skb->data, db->macAddr, ETH_ALEN);
- atomic_inc(&db->use_count);
-
- DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x%02x%02x%02x\n",
- db->macAddr[0],
- db->macAddr[1],
- db->macAddr[2],
- db->macAddr[3],
- db->macAddr[4],
- db->macAddr[5],
- db->networkAddr[0],
- db->networkAddr[1],
- db->networkAddr[2],
- db->networkAddr[3],
- db->networkAddr[4],
- db->networkAddr[5],
- db->networkAddr[6],
- db->networkAddr[7],
- db->networkAddr[8],
- db->networkAddr[9],
- db->networkAddr[10],
- db->networkAddr[11],
- db->networkAddr[12],
- db->networkAddr[13],
- db->networkAddr[14],
- db->networkAddr[15],
- db->networkAddr[16]);
- }
- spin_unlock_bh(&priv->br_ext_lock);
- return 1;
- }
- db = db->next_hash;
- }
- spin_unlock_bh(&priv->br_ext_lock);
- return 0;
-}
-
-static void __nat25_db_network_insert(struct adapter *priv,
- unsigned char *macAddr, unsigned char *networkAddr)
-{
- struct nat25_network_db_entry *db;
- int hash;
-
- spin_lock_bh(&priv->br_ext_lock);
- hash = __nat25_network_hash(networkAddr);
- db = priv->nethash[hash];
- while (db != NULL) {
- if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
- ether_addr_copy(db->macAddr, macAddr);
- db->ageing_timer = jiffies;
- spin_unlock_bh(&priv->br_ext_lock);
- return;
- }
- db = db->next_hash;
- }
- db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db));
- if (db == NULL) {
- spin_unlock_bh(&priv->br_ext_lock);
- return;
- }
- memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN);
- ether_addr_copy(db->macAddr, macAddr);
- atomic_set(&db->use_count, 1);
- db->ageing_timer = jiffies;
-
- __network_hash_link(priv, db, hash);
-
- spin_unlock_bh(&priv->br_ext_lock);
-}
-
-static void __nat25_db_print(struct adapter *priv)
-{
-}
-
-/*
- * NAT2.5 interface
- */
-
-void nat25_db_cleanup(struct adapter *priv)
-{
- int i;
-
- spin_lock_bh(&priv->br_ext_lock);
-
- for (i = 0; i < NAT25_HASH_SIZE; i++) {
- struct nat25_network_db_entry *f;
- f = priv->nethash[i];
- while (f != NULL) {
- struct nat25_network_db_entry *g;
-
- g = f->next_hash;
- if (priv->scdb_entry == f) {
- memset(priv->scdb_mac, 0, ETH_ALEN);
- memset(priv->scdb_ip, 0, 4);
- priv->scdb_entry = NULL;
- }
- __network_hash_unlink(f);
- kfree(f);
- f = g;
- }
- }
- spin_unlock_bh(&priv->br_ext_lock);
-}
-
-void nat25_db_expire(struct adapter *priv)
-{
- int i;
- spin_lock_bh(&priv->br_ext_lock);
-
- for (i = 0; i < NAT25_HASH_SIZE; i++) {
- struct nat25_network_db_entry *f;
- f = priv->nethash[i];
-
- while (f != NULL) {
- struct nat25_network_db_entry *g;
- g = f->next_hash;
-
- if (__nat25_has_expired(priv, f)) {
- if (atomic_dec_and_test(&f->use_count)) {
- if (priv->scdb_entry == f) {
- memset(priv->scdb_mac, 0, ETH_ALEN);
- memset(priv->scdb_ip, 0, 4);
- priv->scdb_entry = NULL;
- }
- __network_hash_unlink(f);
- kfree(f);
- }
- }
- f = g;
- }
- }
- spin_unlock_bh(&priv->br_ext_lock);
-}
-
-int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
-{
- unsigned short protocol;
- unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
- unsigned int tmp;
-
- if (skb == NULL)
- return -1;
-
- if ((method <= NAT25_MIN) || (method >= NAT25_MAX))
- return -1;
-
- protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN)));
-
- /*---------------------------------------------------*/
- /* Handle IP frame */
- /*---------------------------------------------------*/
- if (protocol == ETH_P_IP) {
- struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
-
- if (((unsigned char *)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) {
- DEBUG_WARN("NAT25: malformed IP packet !\n");
- return -1;
- }
-
- switch (method) {
- case NAT25_CHECK:
- return -1;
- case NAT25_INSERT:
- /* some multicast with source IP is all zero, maybe other case is illegal */
- /* in class A, B, C, host address is all zero or all one is illegal */
- if (iph->saddr == 0)
- return 0;
- tmp = be32_to_cpu(iph->saddr);
- DEBUG_INFO("NAT25: Insert IP, SA =%08x, DA =%08x\n", tmp, iph->daddr);
- __nat25_generate_ipv4_network_addr(networkAddr, &tmp);
- /* record source IP address and , source mac address into db */
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
-
- __nat25_db_print(priv);
- return 0;
- case NAT25_LOOKUP:
- DEBUG_INFO("NAT25: Lookup IP, SA =%08x, DA =%08x\n", iph->saddr, iph->daddr);
- tmp = be32_to_cpu(iph->daddr);
- __nat25_generate_ipv4_network_addr(networkAddr, &tmp);
-
- if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
- if (*((unsigned char *)&iph->daddr + 3) == 0xff) {
- /* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */
- DEBUG_INFO("NAT25: Set DA as broadcast\n");
- memset(skb->data, 0xff, ETH_ALEN);
- } else {
- /* forward unknown IP packet to upper TCP/IP */
- DEBUG_INFO("NAT25: Replace DA with BR's MAC\n");
- if ((*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0) {
- netdev_info(skb->dev,
- "Re-init netdev_br_init() due to br_mac == 0!\n");
- netdev_br_init(priv->pnetdev);
- }
- memcpy(skb->data, priv->br_mac, ETH_ALEN);
- }
- }
- return 0;
- default:
- return -1;
- }
- } else if (protocol == ETH_P_ARP) {
- /*---------------------------------------------------*/
- /* Handle ARP frame */
- /*---------------------------------------------------*/
- struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
- unsigned char *arp_ptr = (unsigned char *)(arp + 1);
- unsigned int *sender, *target;
-
- if (arp->ar_pro != __constant_htons(ETH_P_IP)) {
- DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro));
- return -1;
- }
-
- switch (method) {
- case NAT25_CHECK:
- return 0; /* skb_copy for all ARP frame */
- case NAT25_INSERT:
- DEBUG_INFO("NAT25: Insert ARP, MAC =%02x%02x%02x%02x%02x%02x\n", arp_ptr[0],
- arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]);
-
- /* change to ARP sender mac address to wlan STA address */
- memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN);
- arp_ptr += arp->ar_hln;
- sender = (unsigned int *)arp_ptr;
- __nat25_generate_ipv4_network_addr(networkAddr, sender);
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
- __nat25_db_print(priv);
- return 0;
- case NAT25_LOOKUP:
- DEBUG_INFO("NAT25: Lookup ARP\n");
-
- arp_ptr += arp->ar_hln;
- sender = (unsigned int *)arp_ptr;
- arp_ptr += (arp->ar_hln + arp->ar_pln);
- target = (unsigned int *)arp_ptr;
- __nat25_generate_ipv4_network_addr(networkAddr, target);
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
- /* change to ARP target mac address to Lookup result */
- arp_ptr = (unsigned char *)(arp + 1);
- arp_ptr += (arp->ar_hln + arp->ar_pln);
- memcpy(arp_ptr, skb->data, ETH_ALEN);
- return 0;
- default:
- return -1;
- }
- } else if ((protocol == ETH_P_IPX) ||
- (protocol <= ETH_FRAME_LEN)) {
- /*---------------------------------------------------*/
- /* Handle IPX and Apple Talk frame */
- /*---------------------------------------------------*/
- unsigned char ipx_header[2] = {0xFF, 0xFF};
- struct ipxhdr *ipx = NULL;
- struct elapaarp *ea = NULL;
- struct ddpehdr *ddp = NULL;
- unsigned char *framePtr = skb->data + ETH_HLEN;
-
- if (protocol == ETH_P_IPX) {
- DEBUG_INFO("NAT25: Protocol = IPX (Ethernet II)\n");
- ipx = (struct ipxhdr *)framePtr;
- } else if (protocol <= ETH_FRAME_LEN) {
- if (!memcmp(ipx_header, framePtr, 2)) {
- DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.3)\n");
- ipx = (struct ipxhdr *)framePtr;
- } else {
- unsigned char ipx_8022_type = 0xE0;
- unsigned char snap_8022_type = 0xAA;
-
- if (*framePtr == snap_8022_type) {
- unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */
- unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */
- unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */
-
- framePtr += 3; /* eliminate the 802.2 header */
-
- if (!memcmp(ipx_snap_id, framePtr, 5)) {
- framePtr += 5; /* eliminate the SNAP header */
-
- DEBUG_INFO("NAT25: Protocol = IPX (Ethernet SNAP)\n");
- ipx = (struct ipxhdr *)framePtr;
- } else if (!memcmp(aarp_snap_id, framePtr, 5)) {
- framePtr += 5; /* eliminate the SNAP header */
-
- ea = (struct elapaarp *)framePtr;
- } else if (!memcmp(ddp_snap_id, framePtr, 5)) {
- framePtr += 5; /* eliminate the SNAP header */
-
- ddp = (struct ddpehdr *)framePtr;
- } else {
- DEBUG_WARN("NAT25: Protocol = Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0],
- framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
- return -1;
- }
- } else if (*framePtr == ipx_8022_type) {
- framePtr += 3; /* eliminate the 802.2 header */
-
- if (!memcmp(ipx_header, framePtr, 2)) {
- DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.2)\n");
- ipx = (struct ipxhdr *)framePtr;
- } else {
- return -1;
- }
- } else {
- return -1;
- }
- }
- } else {
- return -1;
- }
-
- /* IPX */
- if (ipx != NULL) {
- switch (method) {
- case NAT25_CHECK:
- if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
- DEBUG_INFO("NAT25: Check IPX skb_copy\n");
- return 0;
- case NAT25_INSERT:
- DEBUG_INFO("NAT25: Insert IPX, Dest =%08x,%02x%02x%02x%02x%02x%02x,%04x Source =%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
- ipx->ipx_dest.net,
- ipx->ipx_dest.node[0],
- ipx->ipx_dest.node[1],
- ipx->ipx_dest.node[2],
- ipx->ipx_dest.node[3],
- ipx->ipx_dest.node[4],
- ipx->ipx_dest.node[5],
- ipx->ipx_dest.sock,
- ipx->ipx_source.net,
- ipx->ipx_source.node[0],
- ipx->ipx_source.node[1],
- ipx->ipx_source.node[2],
- ipx->ipx_source.node[3],
- ipx->ipx_source.node[4],
- ipx->ipx_source.node[5],
- ipx->ipx_source.sock);
-
- if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) {
- DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n");
-
- __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock);
-
- /* change IPX source node addr to wlan STA address */
- memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN);
- } else {
- __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node);
- }
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
- __nat25_db_print(priv);
- return 0;
- case NAT25_LOOKUP:
- if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) {
- DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n");
-
- __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock);
-
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
-
- /* replace IPX destination node addr with Lookup destination MAC addr */
- memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN);
- } else {
- __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node);
-
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
- }
- return 0;
- default:
- return -1;
- }
- } else if (ea != NULL) {
- /* Sanity check fields. */
- if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) {
- DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n");
- return -1;
- }
-
- switch (method) {
- case NAT25_CHECK:
- return 0;
- case NAT25_INSERT:
- /* change to AARP source mac address to wlan STA address */
- memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN);
-
- DEBUG_INFO("NAT25: Insert AARP, Source =%d,%d Destination =%d,%d\n",
- ea->pa_src_net,
- ea->pa_src_node,
- ea->pa_dst_net,
- ea->pa_dst_node);
-
- __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node);
-
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
-
- __nat25_db_print(priv);
- return 0;
- case NAT25_LOOKUP:
- DEBUG_INFO("NAT25: Lookup AARP, Source =%d,%d Destination =%d,%d\n",
- ea->pa_src_net,
- ea->pa_src_node,
- ea->pa_dst_net,
- ea->pa_dst_node);
-
- __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node);
-
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
-
- /* change to AARP destination mac address to Lookup result */
- memcpy(ea->hw_dst, skb->data, ETH_ALEN);
- return 0;
- default:
- return -1;
- }
- } else if (ddp != NULL) {
- switch (method) {
- case NAT25_CHECK:
- return -1;
- case NAT25_INSERT:
- DEBUG_INFO("NAT25: Insert DDP, Source =%d,%d Destination =%d,%d\n",
- ddp->deh_snet,
- ddp->deh_snode,
- ddp->deh_dnet,
- ddp->deh_dnode);
-
- __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode);
-
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
-
- __nat25_db_print(priv);
- return 0;
- case NAT25_LOOKUP:
- DEBUG_INFO("NAT25: Lookup DDP, Source =%d,%d Destination =%d,%d\n",
- ddp->deh_snet,
- ddp->deh_snode,
- ddp->deh_dnet,
- ddp->deh_dnode);
- __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode);
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
- return 0;
- default:
- return -1;
- }
- }
-
- return -1;
- } else if ((protocol == ETH_P_PPP_DISC) ||
- (protocol == ETH_P_PPP_SES)) {
- /*---------------------------------------------------*/
- /* Handle PPPoE frame */
- /*---------------------------------------------------*/
- struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
- __be16 *pMagic;
-
- switch (method) {
- case NAT25_CHECK:
- if (ph->sid == 0)
- return 0;
- return 1;
- case NAT25_INSERT:
- if (ph->sid == 0) { /* Discovery phase according to tag */
- if (ph->code == PADI_CODE || ph->code == PADR_CODE) {
- if (priv->ethBrExtInfo.addPPPoETag) {
- struct pppoe_tag *tag, *pOldTag;
- unsigned char tag_buf[40];
- int old_tag_len = 0;
-
- tag = (struct pppoe_tag *)tag_buf;
- pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
- if (pOldTag) { /* if SID existed, copy old value and delete it */
- old_tag_len = ntohs(pOldTag->tag_len);
- if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) {
- DEBUG_ERR("SID tag length too long!\n");
- return -1;
- }
-
- memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN,
- pOldTag->tag_data, old_tag_len);
-
- if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) {
- DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n");
- return -1;
- }
- ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len);
- }
-
- tag->tag_type = PTT_RELAY_SID;
- tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len);
-
- /* insert the magic_code+client mac in relay tag */
- pMagic = (__be16 *)tag->tag_data;
- *pMagic = htons(MAGIC_CODE);
- memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN);
-
- /* Add relay tag */
- if (__nat25_add_pppoe_tag(skb, tag) < 0)
- return -1;
-
- DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n",
- (ph->code == PADI_CODE ? "PADI" : "PADR"));
- } else { /* not add relay tag */
- if (priv->pppoe_connection_in_progress &&
- memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) {
- DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n");
- return -2;
- }
-
- if (priv->pppoe_connection_in_progress == 0)
- memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN);
-
- priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
- }
- } else {
- return -1;
- }
- } else { /* session phase */
- DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name);
-
- __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid));
-
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
-
- __nat25_db_print(priv);
-
- if (!priv->ethBrExtInfo.addPPPoETag &&
- priv->pppoe_connection_in_progress &&
- !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN))
- priv->pppoe_connection_in_progress = 0;
- }
- return 0;
- case NAT25_LOOKUP:
- if (ph->code == PADO_CODE || ph->code == PADS_CODE) {
- if (priv->ethBrExtInfo.addPPPoETag) {
- struct pppoe_tag *tag;
- unsigned char *ptr;
- unsigned short tagType, tagLen;
- int offset = 0;
-
- ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
- if (ptr == NULL) {
- DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n");
- return -1;
- }
-
- tag = (struct pppoe_tag *)ptr;
- tagType = (unsigned short)((ptr[0] << 8) + ptr[1]);
- tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]);
-
- if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) {
- DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen);
- return -1;
- }
-
- pMagic = (__be16 *)tag->tag_data;
- if (ntohs(*pMagic) != MAGIC_CODE) {
- DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n",
- (ph->code == PADO_CODE ? "PADO" : "PADS"));
- return -1;
- }
-
- memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN);
-
- if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN)
- offset = TAG_HDR_LEN;
-
- if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) {
- DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n");
- return -1;
- }
- ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset));
- if (offset > 0)
- tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN);
-
- DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n",
- (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name);
- } else { /* not add relay tag */
- if (!priv->pppoe_connection_in_progress) {
- DEBUG_ERR("Discard PPPoE packet due to no connection in progress!\n");
- return -1;
- }
- memcpy(skb->data, priv->pppoe_addr, ETH_ALEN);
- priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
- }
- } else {
- if (ph->sid != 0) {
- DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name);
- __nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid));
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
- __nat25_db_print(priv);
- } else {
- return -1;
- }
- }
- return 0;
- default:
- return -1;
- }
- } else if (protocol == 0x888e) {
- /*---------------------------------------------------*/
- /* Handle EAP frame */
- /*---------------------------------------------------*/
- switch (method) {
- case NAT25_CHECK:
- return -1;
- case NAT25_INSERT:
- return 0;
- case NAT25_LOOKUP:
- return 0;
- default:
- return -1;
- }
- } else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) {
- /*---------------------------------------------------*/
- /* Handle C-Media proprietary frame */
- /*---------------------------------------------------*/
- switch (method) {
- case NAT25_CHECK:
- return -1;
- case NAT25_INSERT:
- return 0;
- case NAT25_LOOKUP:
- return 0;
- default:
- return -1;
- }
- } else if (protocol == ETH_P_IPV6) {
- /*------------------------------------------------*/
- /* Handle IPV6 frame */
- /*------------------------------------------------*/
- struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
-
- if (sizeof(*iph) >= (skb->len - ETH_HLEN)) {
- DEBUG_WARN("NAT25: malformed IPv6 packet !\n");
- return -1;
- }
-
- switch (method) {
- case NAT25_CHECK:
- if (skb->data[0] & 1)
- return 0;
- return -1;
- case NAT25_INSERT:
- DEBUG_INFO("NAT25: Insert IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
- " DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
- iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
- iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
- iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
- iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
-
- if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) {
- __nat25_generate_ipv6_network_addr(networkAddr, (__be32 *)&iph->saddr);
- __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
- __nat25_db_print(priv);
-
- if (iph->nexthdr == IPPROTO_ICMPV6 &&
- skb->len > (ETH_HLEN + sizeof(*iph) + 4)) {
- if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph),
- skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) {
- struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph));
- hdr->icmp6_cksum = 0;
- hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr,
- be16_to_cpu(iph->payload_len),
- IPPROTO_ICMPV6,
- csum_partial((__u8 *)hdr,
- be16_to_cpu(iph->payload_len), 0));
- }
- }
- }
- return 0;
- case NAT25_LOOKUP:
- DEBUG_INFO("NAT25: Lookup IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x, DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
- iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3],
- iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7],
- iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3],
- iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]);
- __nat25_generate_ipv6_network_addr(networkAddr, (__be32 *)&iph->daddr);
- __nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
- return 0;
- default:
- return -1;
- }
- }
- return -1;
-}
-
-int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb)
-{
- if (!(skb->data[0] & 1)) {
- int is_vlan_tag = 0, i, retval = 0;
- unsigned short vlan_hdr = 0;
- unsigned short protocol;
-
- protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN)));
- if (protocol == ETH_P_8021Q) {
- is_vlan_tag = 1;
- vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2));
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2));
- skb_pull(skb, 4);
- }
-
- if (!priv->ethBrExtInfo.nat25_disable) {
- spin_lock_bh(&priv->br_ext_lock);
- /*
- * This function look up the destination network address from
- * the NAT2.5 database. Return value = -1 means that the
- * corresponding network protocol is NOT support.
- */
- if (!priv->ethBrExtInfo.nat25sc_disable &&
- (be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_IP) &&
- !memcmp(priv->scdb_ip, skb->data+ETH_HLEN+16, 4)) {
- memcpy(skb->data, priv->scdb_mac, ETH_ALEN);
-
- spin_unlock_bh(&priv->br_ext_lock);
- } else {
- spin_unlock_bh(&priv->br_ext_lock);
-
- retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
- }
- } else {
- if (((be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_IP) &&
- !memcmp(priv->br_ip, skb->data+ETH_HLEN+16, 4)) ||
- ((be16_to_cpu(*((__be16 *)(skb->data+ETH_ALEN*2))) == ETH_P_ARP) &&
- !memcmp(priv->br_ip, skb->data+ETH_HLEN+24, 4))) {
- /* for traffic to upper TCP/IP */
- retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
- }
- }
-
- if (is_vlan_tag) {
- skb_push(skb, 4);
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
- *((__be16 *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q);
- *((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr;
- }
-
- if (retval == -1) {
- /* DEBUG_ERR("NAT25: Lookup fail!\n"); */
- return -1;
- }
- }
-
- return 0;
-}
-
-#define SERVER_PORT 67
-#define CLIENT_PORT 68
-#define DHCP_MAGIC 0x63825363
-#define BROADCAST_FLAG 0x8000
-
-struct dhcpMessage {
- u_int8_t op;
- u_int8_t htype;
- u_int8_t hlen;
- u_int8_t hops;
- __be32 xid;
- __be16 secs;
- __be16 flags;
- __be32 ciaddr;
- __be32 yiaddr;
- __be32 siaddr;
- __be32 giaddr;
- u_int8_t chaddr[16];
- u_int8_t sname[64];
- u_int8_t file[128];
- __be32 cookie;
- u_int8_t options[308]; /* 312 - cookie */
-};
-
-void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb)
-{
- if (skb == NULL)
- return;
-
- if (!priv->ethBrExtInfo.dhcp_bcst_disable) {
- __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN));
-
- if (protocol == __constant_htons(ETH_P_IP)) { /* IP */
- struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN);
-
- if (iph->protocol == IPPROTO_UDP) { /* UDP */
- struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2));
-
- if ((udph->source == __constant_htons(CLIENT_PORT)) &&
- (udph->dest == __constant_htons(SERVER_PORT))) { /* DHCP request */
- struct dhcpMessage *dhcph =
- (struct dhcpMessage *)((size_t)udph + sizeof(struct udphdr));
- u32 cookie = be32_to_cpu((__be32)dhcph->cookie);
-
- if (cookie == DHCP_MAGIC) { /* match magic word */
- if (!(dhcph->flags & htons(BROADCAST_FLAG))) {
- /* if not broadcast */
- register int sum = 0;
-
- DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n");
- /* or BROADCAST flag */
- dhcph->flags |= htons(BROADCAST_FLAG);
- /* recalculate checksum */
- sum = ~(udph->check) & 0xffff;
- sum += be16_to_cpu(dhcph->flags);
- while (sum >> 16)
- sum = (sum & 0xffff) + (sum >> 16);
- udph->check = ~sum;
- }
- }
- }
- }
- }
- }
-}
-
-
-void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr,
- unsigned char *ipAddr)
-{
- unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
- struct nat25_network_db_entry *db;
- int hash;
-
- __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr);
- hash = __nat25_network_hash(networkAddr);
- db = priv->nethash[hash];
- while (db != NULL) {
- if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN))
- return (void *)db;
-
- db = db->next_hash;
- }
-
- return NULL;
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
index 1e0b8b49fc12..104b01fa0fad 100644
--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
@@ -22,9 +22,7 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
-#include <cmd_osdep.h>
#include <mlme_osdep.h>
-#include <rtw_br_ext.h>
#include <rtw_mlme_ext.h>
/*
@@ -32,91 +30,13 @@ Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
No irqsave is necessary.
*/
-int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
+int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
{
- int res = _SUCCESS;
-
-
sema_init(&(pcmdpriv->cmd_queue_sema), 0);
- /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */
sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0);
-
_rtw_init_queue(&(pcmdpriv->cmd_queue));
-
- /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
-
- pcmdpriv->cmd_seq = 1;
-
- pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
-
- if (pcmdpriv->cmd_allocated_buf == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
-
- pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
-
- if (pcmdpriv->rsp_allocated_buf == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3);
-
- pcmdpriv->cmd_issued_cnt = 0;
- pcmdpriv->cmd_done_cnt = 0;
- pcmdpriv->rsp_cnt = 0;
-exit:
- return res;
-}
-
-static void c2h_wk_callback(struct work_struct *work);
-
-int _rtw_init_evt_priv(struct evt_priv *pevtpriv)
-{
- int res = _SUCCESS;
-
-
- /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
- atomic_set(&pevtpriv->event_seq, 0);
- pevtpriv->evt_done_cnt = 0;
-
- INIT_WORK(&pevtpriv->c2h_wk, c2h_wk_callback);
- pevtpriv->c2h_wk_alive = false;
- pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1);
-
-
- return res;
-}
-
-void rtw_free_evt_priv(struct evt_priv *pevtpriv)
-{
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+rtw_free_evt_priv\n"));
-
- _cancel_workitem_sync(&pevtpriv->c2h_wk);
- while (pevtpriv->c2h_wk_alive)
- msleep(10);
-
- while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
- void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue);
- if (c2h != NULL && c2h != (void *)pevtpriv)
- kfree(c2h);
- }
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("-rtw_free_evt_priv\n"));
-
-}
-
-void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv)
-{
-
- if (pcmdpriv) {
- kfree(pcmdpriv->cmd_allocated_buf);
- kfree(pcmdpriv->rsp_allocated_buf);
- }
+ return _SUCCESS;
}
/*
@@ -129,7 +49,7 @@ ISR/Call-Back functions can't call this sub-function.
*/
-int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
+static int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
{
unsigned long irqL;
@@ -139,7 +59,7 @@ int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
spin_lock_irqsave(&queue->lock, irqL);
- rtw_list_insert_tail(&obj->list, &queue->queue);
+ list_add_tail(&obj->list, &queue->queue);
spin_unlock_irqrestore(&queue->lock, irqL);
@@ -149,18 +69,18 @@ exit:
return _SUCCESS;
}
-struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue)
+struct cmd_obj * rtw_dequeue_cmd(struct __queue *queue)
{
unsigned long irqL;
struct cmd_obj *obj;
spin_lock_irqsave(&queue->lock, irqL);
- if (rtw_is_list_empty(&(queue->queue))) {
+ if (list_empty(&(queue->queue))) {
obj = NULL;
} else {
obj = container_of((&queue->queue)->next, struct cmd_obj, list);
- rtw_list_delete(&obj->list);
+ list_del_init(&obj->list);
}
spin_unlock_irqrestore(&queue->lock, irqL);
@@ -169,26 +89,6 @@ struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue)
return obj;
}
-u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
-{
- u32 res;
- res = _rtw_init_cmd_priv(pcmdpriv);
- return res;
-}
-
-u32 rtw_init_evt_priv(struct evt_priv *pevtpriv)
-{
- int res;
- res = _rtw_init_evt_priv(pevtpriv);
- return res;
-}
-
-void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv)
-{
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_cmd_priv\n"));
- _rtw_free_cmd_priv(pcmdpriv);
-}
-
static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
{
u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
@@ -240,22 +140,6 @@ exit:
return res;
}
-struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
-{
- struct cmd_obj *cmd_obj;
-
-
- cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
-
- return cmd_obj;
-}
-
-void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv)
-{
- pcmdpriv->cmd_done_cnt++;
- /* up(&(pcmdpriv->cmd_done_sema)); */
-}
-
void rtw_free_cmd_obj(struct cmd_obj *pcmd)
{
@@ -280,16 +164,12 @@ int rtw_cmd_thread(void *context)
{
u8 ret;
struct cmd_obj *pcmd;
- u8 *pcmdbuf;
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 cmd_priv *pcmdpriv = &(padapter->cmdpriv);
-
- thread_enter("RTW_CMD_THREAD");
-
- pcmdbuf = pcmdpriv->cmd_buf;
+ allow_signal(SIGTERM);
pcmdpriv->cmdthd_running = true;
up(&pcmdpriv->terminate_cmdthread_sema);
@@ -314,7 +194,7 @@ _next:
break;
}
- pcmd = rtw_dequeue_cmd(pcmdpriv);
+ pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
if (!pcmd)
continue;
@@ -323,21 +203,13 @@ _next:
goto post_process;
}
- pcmdpriv->cmd_issued_cnt++;
-
- pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */
-
- memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
-
if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) {
cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
if (cmd_hdl) {
- ret = cmd_hdl(pcmd->padapter, pcmdbuf);
+ ret = cmd_hdl(pcmd->padapter, pcmd->parmbuf);
pcmd->res = ret;
}
-
- pcmdpriv->cmd_seq++;
} else {
pcmd->res = H2C_PARAMETERS_ERROR;
}
@@ -361,7 +233,8 @@ post_process:
rtw_free_cmd_obj(pcmd);
}
- flush_signals_thread();
+ if (signal_pending(current))
+ flush_signals(current);
goto _next;
}
@@ -369,7 +242,7 @@ post_process:
/* free all cmd_obj resources */
do {
- pcmd = rtw_dequeue_cmd(pcmdpriv);
+ pcmd = rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
if (pcmd == NULL)
break;
@@ -384,40 +257,6 @@ post_process:
complete_and_exit(NULL, 0);
}
-u8 rtw_setstandby_cmd(struct adapter *padapter, uint action)
-{
- struct cmd_obj *ph2c;
- struct usb_suspend_parm *psetusbsuspend;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- u8 ret = _SUCCESS;
-
-
- ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
- if (ph2c == NULL) {
- ret = _FAIL;
- goto exit;
- }
-
- psetusbsuspend = kzalloc(sizeof(struct usb_suspend_parm), GFP_KERNEL);
- if (psetusbsuspend == NULL) {
- kfree(ph2c);
- ret = _FAIL;
- goto exit;
- }
-
- psetusbsuspend->action = action;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend));
-
- ret = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-
- return ret;
-}
-
/*
rtw_sitesurvey_cmd(~)
### NOTE:#### (!!!!)
@@ -435,14 +274,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL)
return _FAIL;
- psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
+ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL);
if (psurveyPara == NULL) {
kfree(ph2c);
return _FAIL;
@@ -499,258 +335,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
return res;
}
-u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset)
-{
- struct cmd_obj *ph2c;
- struct setdatarate_parm *pbsetdataratepara;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pbsetdataratepara = (struct setdatarate_parm *)rtw_zmalloc(sizeof(struct setdatarate_parm));
- if (pbsetdataratepara == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
- pbsetdataratepara->mac_id = 5;
- memcpy(pbsetdataratepara->datarates, rateset, NumRates);
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
-
-
- return res;
-}
-
-u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset)
-{
- struct cmd_obj *ph2c;
- struct setbasicrate_parm *pssetbasicratepara;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- pssetbasicratepara = (struct setbasicrate_parm *)rtw_zmalloc(sizeof(struct setbasicrate_parm));
-
- if (pssetbasicratepara == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_);
-
- memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
-
-
- return res;
-}
-
-
-/*
-unsigned char rtw_setphy_cmd(unsigned char *adapter)
-
-1. be called only after rtw_update_registrypriv_dev_network(~) or mp testing program
-2. for AdHoc/Ap mode or mp mode?
-
-*/
-u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch)
-{
- struct cmd_obj *ph2c;
- struct setphy_parm *psetphypara;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- psetphypara = (struct setphy_parm *)rtw_zmalloc(sizeof(struct setphy_parm));
-
- if (psetphypara == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_);
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("CH =%d, modem =%d", ch, modem));
-
- psetphypara->modem = modem;
- psetphypara->rfchannel = ch;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val)
-{
- struct cmd_obj *ph2c;
- struct writeBB_parm *pwritebbparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- pwritebbparm = (struct writeBB_parm *)rtw_zmalloc(sizeof(struct writeBB_parm));
-
- if (pwritebbparm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg));
-
- pwritebbparm->offset = offset;
- pwritebbparm->value = val;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_getbbreg_cmd(struct adapter *padapter, u8 offset, u8 *pval)
-{
- struct cmd_obj *ph2c;
- struct readBB_parm *prdbbparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- prdbbparm = (struct readBB_parm *)rtw_zmalloc(sizeof(struct readBB_parm));
-
- if (prdbbparm == NULL) {
- kfree(ph2c);
- return _FAIL;
- }
-
- _rtw_init_listhead(&ph2c->list);
- ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg);
- ph2c->parmbuf = (unsigned char *)prdbbparm;
- ph2c->cmdsz = sizeof(struct readBB_parm);
- ph2c->rsp = pval;
- ph2c->rspsz = sizeof(struct readBB_rsp);
-
- prdbbparm->offset = offset;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_setrfreg_cmd(struct adapter *padapter, u8 offset, u32 val)
-{
- struct cmd_obj *ph2c;
- struct writeRF_parm *pwriterfparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- pwriterfparm = (struct writeRF_parm *)rtw_zmalloc(sizeof(struct writeRF_parm));
-
- if (pwriterfparm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
-
- pwriterfparm->offset = offset;
- pwriterfparm->value = val;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_getrfreg_cmd(struct adapter *padapter, u8 offset, u8 *pval)
-{
- struct cmd_obj *ph2c;
- struct readRF_parm *prdrfparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- prdrfparm = (struct readRF_parm *)rtw_zmalloc(sizeof(struct readRF_parm));
- if (prdrfparm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- _rtw_init_listhead(&ph2c->list);
- ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
- ph2c->parmbuf = (unsigned char *)prdrfparm;
- ph2c->cmdsz = sizeof(struct readRF_parm);
- ph2c->rsp = pval;
- ph2c->rspsz = sizeof(struct readRF_rsp);
-
- prdrfparm->offset = offset;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-
- return res;
-}
-
-void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd)
-{
-
- kfree(pcmd->parmbuf);
- kfree(pcmd);
-
- if (padapter->registrypriv.mp_mode == 1)
- padapter->mppriv.workparam.bcompleted = true;
-}
-
void rtw_readtssi_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd)
{
kfree(pcmd->parmbuf);
kfree(pcmd);
-
- if (padapter->registrypriv.mp_mode == 1)
- padapter->mppriv.workparam.bcompleted = true;
}
u8 rtw_createbss_cmd(struct adapter *padapter)
@@ -769,13 +358,13 @@ u8 rtw_createbss_cmd(struct adapter *padapter)
else
RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd == NULL) {
res = _FAIL;
goto exit;
}
- _rtw_init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _CreateBss_CMD_;
pcmd->parmbuf = (unsigned char *)pdev_network;
pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network);
@@ -789,34 +378,6 @@ exit:
return res;
}
-u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, unsigned int sz)
-{
- struct cmd_obj *pcmd;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (pcmd == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- _rtw_init_listhead(&pcmd->list);
- pcmd->cmdcode = GEN_CMD_CODE(_CreateBss);
- pcmd->parmbuf = pbss;
- pcmd->cmdsz = sz;
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
- res = rtw_enqueue_cmd(pcmdpriv, pcmd);
-
-exit:
-
-
- return res;
-}
-
u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
{
u8 res = _SUCCESS;
@@ -841,7 +402,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
else
RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid));
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd == NULL) {
res = _FAIL;
RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
@@ -879,7 +440,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
goto exit;
}
- _rtw_memset(psecnetwork, 0, t_len);
+ memset(psecnetwork, 0, t_len);
memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network));
@@ -945,7 +506,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */
- _rtw_init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */
pcmd->parmbuf = (unsigned char *)psecnetwork;
pcmd->rsp = NULL;
@@ -970,7 +531,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu
RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
/* prepare cmd parameter */
- param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param));
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
if (param == NULL) {
res = _FAIL;
goto exit;
@@ -979,7 +540,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu
if (enqueue) {
/* need enqueue, prepare cmd_obj and enqueue */
- cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj));
+ cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL);
if (cmdobj == NULL) {
res = _FAIL;
kfree(param);
@@ -1009,12 +570,12 @@ u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra n
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = false;
goto exit;
}
- psetop = (struct setopmode_parm *)rtw_zmalloc(sizeof(struct setopmode_parm));
+ psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL);
if (psetop == NULL) {
kfree(ph2c);
@@ -1046,20 +607,20 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key)
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- psetstakey_para = (struct set_stakey_parm *)rtw_zmalloc(sizeof(struct set_stakey_parm));
+ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
if (psetstakey_para == NULL) {
kfree(ph2c);
res = _FAIL;
goto exit;
}
- psetstakey_rsp = (struct set_stakey_rsp *)rtw_zmalloc(sizeof(struct set_stakey_rsp));
+ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL);
if (psetstakey_rsp == NULL) {
kfree(ph2c);
kfree(psetstakey_para);
@@ -1107,20 +668,20 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
if (!enqueue) {
clear_cam_entry(padapter, entry);
} else {
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- psetstakey_para = (struct set_stakey_parm *)rtw_zmalloc(sizeof(struct set_stakey_parm));
+ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC);
if (psetstakey_para == NULL) {
kfree(ph2c);
res = _FAIL;
goto exit;
}
- psetstakey_rsp = (struct set_stakey_rsp *)rtw_zmalloc(sizeof(struct set_stakey_rsp));
+ psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC);
if (psetstakey_rsp == NULL) {
kfree(ph2c);
kfree(psetstakey_para);
@@ -1146,113 +707,6 @@ exit:
return res;
}
-u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table)
-{
- struct cmd_obj *ph2c;
- struct setratable_parm *psetrttblparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- psetrttblparm = (struct setratable_parm *)rtw_zmalloc(sizeof(struct setratable_parm));
-
- if (psetrttblparm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
-
- memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm));
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval)
-{
- struct cmd_obj *ph2c;
- struct getratable_parm *pgetrttblparm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
- pgetrttblparm = (struct getratable_parm *)rtw_zmalloc(sizeof(struct getratable_parm));
-
- if (pgetrttblparm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- _rtw_init_listhead(&ph2c->list);
- ph2c->cmdcode = GEN_CMD_CODE(_GetRaTable);
- ph2c->parmbuf = (unsigned char *)pgetrttblparm;
- ph2c->cmdsz = sizeof(struct getratable_parm);
- ph2c->rsp = (u8 *)pval;
- ph2c->rspsz = sizeof(struct getratable_rsp);
-
- pgetrttblparm->rsvd = 0x0;
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-exit:
- return res;
-}
-
-u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr)
-{
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct cmd_obj *ph2c;
- struct set_assocsta_parm *psetassocsta_para;
- struct set_stakey_rsp *psetassocsta_rsp = NULL;
-
- u8 res = _SUCCESS;
-
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- psetassocsta_para = (struct set_assocsta_parm *)rtw_zmalloc(sizeof(struct set_assocsta_parm));
- if (psetassocsta_para == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- psetassocsta_rsp = (struct set_stakey_rsp *)rtw_zmalloc(sizeof(struct set_assocsta_rsp));
- if (psetassocsta_rsp == NULL) {
- kfree(ph2c);
- kfree(psetassocsta_para);
- return _FAIL;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
- ph2c->rsp = (u8 *)psetassocsta_rsp;
- ph2c->rspsz = sizeof(struct set_assocsta_rsp);
-
- ether_addr_copy(psetassocsta_para->addr, mac_addr);
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-
- return res;
-}
-
u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
{
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
@@ -1261,13 +715,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- paddbareq_parm = (struct addBaReq_parm *)rtw_zmalloc(sizeof(struct addBaReq_parm));
+ paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL);
if (paddbareq_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1298,13 +752,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1324,59 +778,6 @@ exit:
return res;
}
-u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue)
-{
- struct cmd_obj *pcmdobj;
- struct set_ch_parm *set_ch_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- u8 res = _SUCCESS;
-
-
- DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
- FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset);
-
- /* check input parameter */
-
- /* prepare cmd parameter */
- set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm));
- if (set_ch_parm == NULL) {
- res = _FAIL;
- goto exit;
- }
- set_ch_parm->ch = ch;
- set_ch_parm->bw = bw;
- set_ch_parm->ch_offset = ch_offset;
-
- if (enqueue) {
- /* need enqueue, prepare cmd_obj and enqueue */
- pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (pcmdobj == NULL) {
- kfree(set_ch_parm);
- res = _FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel));
- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
- } else {
- /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
- if (H2C_SUCCESS != set_ch_hdl(padapter, (u8 *)set_ch_parm))
- res = _FAIL;
-
- kfree(set_ch_parm);
- }
-
- /* do something based on res... */
-
-exit:
-
- DBG_88E(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res);
-
-
- return res;
-}
-
u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
{
struct cmd_obj *pcmdobj;
@@ -1395,7 +796,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
}
/* prepare cmd parameter */
- setChannelPlan_param = (struct SetChannelPlan_param *)rtw_zmalloc(sizeof(struct SetChannelPlan_param));
+ setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), GFP_KERNEL);
if (setChannelPlan_param == NULL) {
res = _FAIL;
goto exit;
@@ -1404,7 +805,7 @@ u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue)
if (enqueue) {
/* need enqueue, prepare cmd_obj and enqueue */
- pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmdobj == NULL) {
kfree(setChannelPlan_param);
res = _FAIL;
@@ -1431,46 +832,6 @@ exit:
return res;
}
-u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no)
-{
- struct cmd_obj *pcmdobj;
- struct SetChannelSwitch_param *setChannelSwitch_param;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-
- u8 res = _SUCCESS;
-
-
- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n"));
-
- pcmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (pcmdobj == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct SetChannelSwitch_param));
- if (setChannelSwitch_param == NULL) {
- kfree(pcmdobj);
- res = _FAIL;
- goto exit;
- }
-
- setChannelSwitch_param->new_ch_no = new_ch_no;
-
- init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch));
- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
-
-exit:
-
-
- return res;
-}
-
-u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option)
-{
- return _SUCCESS;
-}
-
static void traffic_status_watchdog(struct adapter *padapter)
{
u8 bEnterPS;
@@ -1542,8 +903,6 @@ static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
expire_timeout_chk(padapter);
#endif
- rtw_hal_sreset_xmit_status_check(padapter);
-
linked_status_chk(padapter);
traffic_status_watchdog(padapter);
@@ -1605,13 +964,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
u8 res = _SUCCESS;
if (enqueue) {
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1648,13 +1007,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1690,13 +1049,13 @@ u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue)
return res;
if (enqueue) {
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1718,52 +1077,6 @@ exit:
return res;
}
-static void power_saving_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
-{
- rtw_ps_processor(padapter);
-}
-
-#ifdef CONFIG_88EU_P2P
-u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return res;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
- if (pdrvextra_cmd_parm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID;
- pdrvextra_cmd_parm->type_size = intCmdType; /* As the command tppe. */
- pdrvextra_cmd_parm->pbuf = NULL; /* Must be NULL here */
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
-
- return res;
-}
-#endif /* CONFIG_88EU_P2P */
-
u8 rtw_ps_cmd(struct adapter *padapter)
{
struct cmd_obj *ppscmd;
@@ -1772,13 +1085,13 @@ u8 rtw_ps_cmd(struct adapter *padapter)
u8 res = _SUCCESS;
- ppscmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ppscmd == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ppscmd);
res = _FAIL;
@@ -1846,13 +1159,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter)
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL);
if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -1871,111 +1184,6 @@ exit:
}
#endif
-u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
- if (pdrvextra_cmd_parm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
- pdrvextra_cmd_parm->type_size = c2h_evt ? 16 : 0;
- pdrvextra_cmd_parm->pbuf = c2h_evt;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
-exit:
-
- return res;
-}
-
-static s32 c2h_evt_hdl(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter)
-{
- s32 ret = _FAIL;
- u8 buf[16];
-
- if (!c2h_evt) {
- /* No c2h event in cmd_obj, read c2h event before handling*/
- if (c2h_evt_read(adapter, buf) == _SUCCESS) {
- c2h_evt = (struct c2h_evt_hdr *)buf;
-
- if (filter && filter(c2h_evt->id) == false)
- goto exit;
-
- ret = rtw_hal_c2h_handler(adapter, c2h_evt);
- }
- } else {
- if (filter && filter(c2h_evt->id) == false)
- goto exit;
-
- ret = rtw_hal_c2h_handler(adapter, c2h_evt);
- }
-exit:
- return ret;
-}
-
-static void c2h_wk_callback(struct work_struct *work)
-{
- struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
- struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv);
- struct c2h_evt_hdr *c2h_evt;
- c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
-
- evtpriv->c2h_wk_alive = true;
-
- while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
- c2h_evt = (struct c2h_evt_hdr *)
- rtw_cbuf_pop(evtpriv->c2h_queue);
- if (c2h_evt != NULL)
- /* This C2H event is read, clear it */
- c2h_evt_clear(adapter);
- else {
- c2h_evt = (struct c2h_evt_hdr *)rtw_malloc(16);
- /* This C2H event is not read, read & clear now */
- if (c2h_evt != NULL &&
- c2h_evt_read(adapter, (u8 *)c2h_evt) != _SUCCESS)
- continue;
- }
-
- /* Special pointer to trigger c2h_evt_clear only */
- if ((void *)c2h_evt == (void *)evtpriv)
- continue;
-
- if (!c2h_evt_exist(c2h_evt)) {
- kfree(c2h_evt);
- continue;
- }
-
- if (ccx_id_filter(c2h_evt->id) == true) {
- /* Handle CCX report here */
- rtw_hal_c2h_handler(adapter, c2h_evt);
- kfree(c2h_evt);
- } else {
-#ifdef CONFIG_88EU_P2P
- /* Enqueue into cmd_thread for others */
- rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
-#endif
- }
- }
-
- evtpriv->c2h_wk_alive = false;
-}
-
u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
{
struct drvextra_cmd_parm *pdrvextra_cmd;
@@ -1990,7 +1198,7 @@ u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
break;
case POWER_SAVING_CTRL_WK_CID:
- power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
+ rtw_ps_processor(padapter);
break;
case LPS_CTRL_WK_CID:
lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
@@ -2001,26 +1209,11 @@ u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf)
case ANT_SELECT_WK_CID:
antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size);
break;
-#ifdef CONFIG_88EU_P2P
- case P2P_PS_WK_CID:
- p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size);
- break;
- case P2P_PROTO_WK_CID:
- /*
- * Commented by Albert 2011/07/01
- * I used the type_size as the type command
- */
- p2p_protocol_wk_hdl(padapter, pdrvextra_cmd->type_size);
- break;
-#endif
#ifdef CONFIG_88EU_AP_MODE
case CHECK_HIQ_WK_CID:
rtw_chk_hi_queue_hdl(padapter);
break;
#endif /* CONFIG_88EU_AP_MODE */
- case C2H_WK_CID:
- c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL);
- break;
default:
break;
}
@@ -2061,8 +1254,7 @@ void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
return;
- } else /* clear bridge database */
- nat25_db_cleanup(padapter);
+ }
/* free cmd */
rtw_free_cmd_obj(pcmd);
@@ -2088,7 +1280,6 @@ void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
{
- u8 timer_cancelled;
struct sta_info *psta = NULL;
struct wlan_network *pwlan = NULL;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -2101,7 +1292,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
_set_timer(&pmlmepriv->assoc_timer, 1);
}
- _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
+ del_timer_sync(&pmlmepriv->assoc_timer);
spin_lock_bh(&pmlmepriv->lock);
@@ -2128,7 +1319,7 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd)
}
pwlan->last_scanned = jiffies;
} else {
- rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
+ list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
}
pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork);
diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c
index 2beb2695e0f2..1f72f7d8097e 100644
--- a/drivers/staging/rtl8188eu/core/rtw_debug.c
+++ b/drivers/staging/rtl8188eu/core/rtw_debug.c
@@ -20,7 +20,7 @@
#define _RTW_DEBUG_C_
#include <rtw_debug.h>
-#include <rtw_version.h>
+#include <usb_ops_linux.h>
int proc_get_drv_version(char *page, char **start,
off_t offset, int count,
@@ -64,13 +64,13 @@ int proc_set_write_reg(struct file *file, const char __user *buffer,
}
switch (len) {
case 1:
- rtw_write8(padapter, addr, (u8)val);
+ usb_write8(padapter, addr, (u8)val);
break;
case 2:
- rtw_write16(padapter, addr, (u16)val);
+ usb_write16(padapter, addr, (u16)val);
break;
case 4:
- rtw_write32(padapter, addr, val);
+ usb_write32(padapter, addr, val);
break;
default:
DBG_88E("error write length =%d", len);
@@ -99,13 +99,13 @@ int proc_get_read_reg(char *page, char **start,
switch (proc_get_read_len) {
case 1:
- len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
+ len += snprintf(page + len, count - len, "usb_read8(0x%x)=0x%x\n", proc_get_read_addr, usb_read8(padapter, proc_get_read_addr));
break;
case 2:
- len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
+ len += snprintf(page + len, count - len, "usb_read16(0x%x)=0x%x\n", proc_get_read_addr, usb_read16(padapter, proc_get_read_addr));
break;
case 4:
- len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+ len += snprintf(page + len, count - len, "usb_read32(0x%x)=0x%x\n", proc_get_read_addr, usb_read32(padapter, proc_get_read_addr));
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
@@ -327,7 +327,7 @@ int proc_get_mac_reg_dump1(char *page, char **start,
for (i = 0x0; i < 0x300; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -350,7 +350,7 @@ int proc_get_mac_reg_dump2(char *page, char **start,
for (i = 0x300; i < 0x600; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -373,7 +373,7 @@ int proc_get_mac_reg_dump3(char *page, char **start,
for (i = 0x600; i < 0x800; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -395,7 +395,7 @@ int proc_get_bb_reg_dump1(char *page, char **start,
for (i = 0x800; i < 0xB00; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -416,7 +416,7 @@ int proc_get_bb_reg_dump2(char *page, char **start,
for (i = 0xB00; i < 0xE00; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -437,7 +437,7 @@ int proc_get_bb_reg_dump3(char *page, char **start,
for (i = 0xE00; i < 0x1000; i += 4) {
if (j%4 == 1)
len += snprintf(page + len, count - len, "0x%02x", i);
- len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+ len += snprintf(page + len, count - len, " 0x%08x ", usb_read32(padapter, i));
if ((j++)%4 == 0)
len += snprintf(page + len, count - len, "\n");
}
@@ -853,7 +853,7 @@ int proc_get_all_sta_info(char *page, char **start,
phead = &(pstapriv->sta_hash[i]);
plist = phead->next;
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, hash_list);
plist = plist->next;
diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c
index 40afe48a12ef..5b997b2b404a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_efuse.c
+++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c
@@ -22,849 +22,996 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_efuse.h>
+#include <usb_ops_linux.h>
+#include <rtl8188e_hal.h>
+#include <rtw_iol.h>
-
-
-/*------------------------Define local variable------------------------------*/
-u8 fakeEfuseBank;
-u32 fakeEfuseUsedBytes;
-u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
-u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
-u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
-
-u32 BTEfuseUsedBytes;
-u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
-u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
-u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
-
-u32 fakeBTEfuseUsedBytes;
-u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
-u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
-u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
-/*------------------------Define local variable------------------------------*/
-
-/* */
#define REG_EFUSE_CTRL 0x0030
#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
-/* */
-
-bool
-Efuse_Read1ByteFromFakeContent(
- struct adapter *pAdapter,
- u16 Offset,
- u8 *Value);
-bool
-Efuse_Read1ByteFromFakeContent(
- struct adapter *pAdapter,
- u16 Offset,
- u8 *Value)
-{
- if (Offset >= EFUSE_MAX_HW_SIZE)
- return false;
- if (fakeEfuseBank == 0)
- *Value = fakeEfuseContent[Offset];
- else
- *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
- return true;
-}
-static bool
-Efuse_Write1ByteToFakeContent(
- struct adapter *pAdapter,
- u16 Offset,
- u8 Value)
-{
- if (Offset >= EFUSE_MAX_HW_SIZE)
- return false;
- if (fakeEfuseBank == 0)
- fakeEfuseContent[Offset] = Value;
- else
- fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
- return true;
-}
+enum{
+ VOLTAGE_V25 = 0x03,
+ LDOE25_SHIFT = 28 ,
+ };
-/*-----------------------------------------------------------------------------
+/*
* Function: Efuse_PowerSwitch
*
* Overview: When we want to enable write operation, we should change to
* pwr on state. When we stop write, we should switch to 500k mode
* and disable LDO 2.5V.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/17/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-void
-Efuse_PowerSwitch(
+ */
+
+void Efuse_PowerSwitch(
struct adapter *pAdapter,
- u8 write,
+ u8 bWrite,
u8 PwrState)
{
- pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState);
-}
+ u8 tempval;
+ u16 tmpV16;
-/*-----------------------------------------------------------------------------
- * Function: efuse_GetCurrentSize
- *
- * Overview: Get current efuse size!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-u16
-Efuse_GetCurrentSize(
- struct adapter *pAdapter,
- u8 efuseType,
- bool pseudo)
-{
- u16 ret = 0;
+ if (PwrState) {
+ usb_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
- ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo);
+ /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
+ tmpV16 = usb_read16(pAdapter, REG_SYS_ISO_CTRL);
+ if (!(tmpV16 & PWC_EV12V)) {
+ tmpV16 |= PWC_EV12V;
+ usb_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
+ }
+ /* Reset: 0x0000h[28], default valid */
+ tmpV16 = usb_read16(pAdapter, REG_SYS_FUNC_EN);
+ if (!(tmpV16 & FEN_ELDR)) {
+ tmpV16 |= FEN_ELDR;
+ usb_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
+ }
- return ret;
-}
+ /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
+ tmpV16 = usb_read16(pAdapter, REG_SYS_CLKR);
+ if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
+ tmpV16 |= (LOADER_CLK_EN | ANA8M);
+ usb_write16(pAdapter, REG_SYS_CLKR, tmpV16);
+ }
-/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
-u8
-Efuse_CalculateWordCnts(u8 word_en)
-{
- u8 word_cnts = 0;
- if (!(word_en & BIT(0)))
- word_cnts++; /* 0 : write enable */
- if (!(word_en & BIT(1)))
- word_cnts++;
- if (!(word_en & BIT(2)))
- word_cnts++;
- if (!(word_en & BIT(3)))
- word_cnts++;
- return word_cnts;
+ if (bWrite) {
+ /* Enable LDO 2.5V before read/write action */
+ tempval = usb_read8(pAdapter, EFUSE_TEST+3);
+ tempval &= 0x0F;
+ tempval |= (VOLTAGE_V25 << 4);
+ usb_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80));
+ }
+ } else {
+ usb_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
+
+ if (bWrite) {
+ /* Disable LDO 2.5V after read/write action */
+ tempval = usb_read8(pAdapter, EFUSE_TEST+3);
+ usb_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F));
+ }
+ }
}
-/*
- * Description:
- * Execute E-Fuse read byte operation.
- * Referred from SD1 Richard.
- * Assumption:
- * 1. Boot from E-Fuse and successfully auto-load.
- * 2. PASSIVE_LEVEL (USB interface)
- * Created by Roger, 2008.10.21.
- */
-void
-ReadEFuseByte(
- struct adapter *Adapter,
- u16 _offset,
- u8 *pbuf,
- bool pseudo)
+static void
+efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
{
- u32 value32;
- u8 readbyte;
- u16 retry;
+ u8 *efuseTbl = NULL;
+ u8 rtemp8;
+ u16 eFuse_Addr = 0;
+ u8 offset, wren;
+ u16 i, j;
+ u16 **eFuseWord = NULL;
+ u16 efuse_utilized = 0;
+ u8 u1temp = 0;
+
+ efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
+ if (efuseTbl == NULL) {
+ DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
+ goto exit;
+ }
- if (pseudo) {
- Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
- return;
+ eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
+ if (eFuseWord == NULL) {
+ DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
+ goto exit;
}
- /* Write Address */
- rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
- readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
- rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
-
- /* Write bit 32 0 */
- readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
- rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
-
- /* Check bit 32 read-ready */
- retry = 0;
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
- while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
- retry++;
+ /* 0. Refresh efuse init map as all oxFF. */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
+ eFuseWord[i][j] = 0xFFFF;
+
+ /* */
+ /* 1. Read the first byte to check if efuse is empty!!! */
+ /* */
+ /* */
+ rtemp8 = *(phymap+eFuse_Addr);
+ if (rtemp8 != 0xFF) {
+ efuse_utilized++;
+ eFuse_Addr++;
+ } else {
+ DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8);
+ goto exit;
}
- /* 20100205 Joseph: Add delay suggested by SD1 Victor. */
- /* This fix the problem that Efuse read error in high temperature condition. */
- /* Designer says that there shall be some delay after ready bit is set, or the */
- /* result will always stay on last data we read. */
- udelay(50);
- value32 = rtw_read32(Adapter, EFUSE_CTRL);
+ /* */
+ /* 2. Read real efuse content. Filter PG header and every section data. */
+ /* */
+ while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ /* Check PG header for section num. */
+ if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */
+ u1temp = ((rtemp8 & 0xE0) >> 5);
+ rtemp8 = *(phymap+eFuse_Addr);
+ if ((rtemp8 & 0x0F) == 0x0F) {
+ eFuse_Addr++;
+ rtemp8 = *(phymap+eFuse_Addr);
+
+ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
+ eFuse_Addr++;
+ continue;
+ } else {
+ offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
+ wren = (rtemp8 & 0x0F);
+ eFuse_Addr++;
+ }
+ } else {
+ offset = ((rtemp8 >> 4) & 0x0f);
+ wren = (rtemp8 & 0x0f);
+ }
- *pbuf = (u8)(value32 & 0xff);
-}
+ if (offset < EFUSE_MAX_SECTION_88E) {
+ /* Get word enable value from PG header */
+ for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ /* Check word enable condition in the section */
+ if (!(wren & 0x01)) {
+ rtemp8 = *(phymap+eFuse_Addr);
+ eFuse_Addr++;
+ efuse_utilized++;
+ eFuseWord[offset][i] = (rtemp8 & 0xff);
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ rtemp8 = *(phymap+eFuse_Addr);
+ eFuse_Addr++;
+ efuse_utilized++;
+ eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
+
+ if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
+ break;
+ }
+ wren >>= 1;
+ }
+ }
+ /* Read next PG header */
+ rtemp8 = *(phymap+eFuse_Addr);
-/* Description:
- * 1. Execute E-Fuse read byte operation according as map offset and
- * save to E-Fuse table.
- * 2. Referred from SD1 Richard.
- * Assumption:
- * 1. Boot from E-Fuse and successfully auto-load.
- * 2. PASSIVE_LEVEL (USB interface)
- * Created by Roger, 2008.10.21.
- * 2008/12/12 MH
- * 1. Reorganize code flow and reserve bytes. and add description.
- * 2. Add efuse utilization collect.
- * 2008/12/22 MH
- * Read Efuse must check if we write section 1 data again!!!
- * Sec1 write addr must be after sec5.
- */
+ if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
+ efuse_utilized++;
+ eFuse_Addr++;
+ }
+ }
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
-{
- Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+ /* */
+ /* 3. Collect 16 sections and 4 word unit into Efuse map. */
+ /* */
+ for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
+ for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
+ efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff);
+ efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff);
+ }
+ }
+
+ /* */
+ /* 4. Copy from Efuse map to output pointer memory!!! */
+ /* */
+ for (i = 0; i < _size_byte; i++)
+ pbuf[i] = efuseTbl[_offset+i];
+
+ /* */
+ /* 5. Calculate Efuse utilization. */
+ /* */
+
+exit:
+ kfree(efuseTbl);
+
+ if (eFuseWord)
+ kfree(eFuseWord);
}
-void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
+static void efuse_read_phymap_from_txpktbuf(
+ struct adapter *adapter,
+ int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */
+ u8 *content, /* buffer to store efuse physical map */
+ u16 *size /* for efuse content: the max byte to read. will update to byte read */
)
{
- pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo);
-}
+ u16 dbg_addr = 0;
+ u32 start = 0, passing_time = 0;
+ u8 reg_0x143 = 0;
+ u32 lo32 = 0, hi32 = 0;
+ u16 len = 0, count = 0;
+ int i = 0;
+ u16 limit = *size;
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_Read1Byte
- *
- * Overview: Copy from WMAC fot EFUSE read 1 byte.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 09/23/2008 MHC Copy from WMAC.
- *
- *---------------------------------------------------------------------------*/
-u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
-{
- u8 data;
- u8 Bytetemp = {0x00};
- u8 temp = {0x00};
- u32 k = 0;
- u16 contentLen = 0;
-
- EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
-
- if (Address < contentLen) { /* E-fuse 512Byte */
- /* Write E-fuse Register address bit0~7 */
- temp = Address & 0xFF;
- rtw_write8(Adapter, EFUSE_CTRL+1, temp);
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
- /* Write E-fuse Register address bit8~9 */
- temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
- rtw_write8(Adapter, EFUSE_CTRL+2, temp);
-
- /* Write 0x30[31]= 0 */
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
- temp = Bytetemp & 0x7F;
- rtw_write8(Adapter, EFUSE_CTRL+3, temp);
-
- /* Wait Write-ready (0x30[31]= 1) */
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
- while (!(Bytetemp & 0x80)) {
- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
- k++;
- if (k == 1000) {
- k = 0;
- break;
- }
- }
- data = rtw_read8(Adapter, EFUSE_CTRL);
- return data;
- } else {
- return 0xFF;
- }
+ u8 *pos = content;
-} /* EFUSE_Read1Byte */
+ if (bcnhead < 0) /* if not valid */
+ bcnhead = usb_read8(adapter, REG_TDECTRL+1);
-/* 11/16/2008 MH Read one byte from real Efuse. */
-u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
-{
- u8 tmpidx = 0;
- u8 result;
+ DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
- if (pseudo) {
- result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
- return result;
- }
- /* -----------------e-fuse reg ctrl --------------------------------- */
- /* address */
- rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff));
- rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
- (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC));
+ usb_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
- rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */
+ dbg_addr = bcnhead*128/8; /* 8-bytes addressing */
- while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
- tmpidx++;
- if (tmpidx < 100) {
- *data = rtw_read8(pAdapter, EFUSE_CTRL);
- result = true;
- } else {
- *data = 0xff;
- result = false;
- }
- return result;
-}
+ while (1) {
+ usb_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr+i);
-/* 11/16/2008 MH Write one byte to reald Efuse. */
-u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
-{
- u8 tmpidx = 0;
- u8 result;
+ usb_write8(adapter, REG_TXPKTBUF_DBG, 0);
+ start = jiffies;
+ while (!(reg_0x143 = usb_read8(adapter, REG_TXPKTBUF_DBG)) &&
+ (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
+ DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, usb_read8(adapter, 0x106));
+ msleep(1);
+ }
- if (pseudo) {
- result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
- return result;
- }
+ lo32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_L);
+ hi32 = usb_read32(adapter, REG_PKTBUF_DBG_DATA_H);
- /* -----------------e-fuse reg ctrl --------------------------------- */
- /* address */
- rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
- rtw_write8(pAdapter, EFUSE_CTRL+2,
- (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) |
- (u8)((addr>>8) & 0x03));
- rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
+ if (i == 0) {
+ u8 lenc[2];
+ u16 lenbak, aaabak;
+ u16 aaa;
+ lenc[0] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L);
+ lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L+1);
- rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
+ aaabak = le16_to_cpup((__le16 *)lenc);
+ lenbak = le16_to_cpu(*((__le16 *)lenc));
+ aaa = le16_to_cpup((__le16 *)&lo32);
+ len = le16_to_cpu(*((__le16 *)&lo32));
- while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
- tmpidx++;
+ limit = (len-2 < limit) ? len-2 : limit;
- if (tmpidx < 100)
- result = true;
- else
- result = false;
+ DBG_88E("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak);
- return result;
-}
+ memcpy(pos, ((u8 *)&lo32)+2, (limit >= count+2) ? 2 : limit-count);
+ count += (limit >= count+2) ? 2 : limit-count;
+ pos = content+count;
-int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo)
-{
- int ret = 0;
+ } else {
+ memcpy(pos, ((u8 *)&lo32), (limit >= count+4) ? 4 : limit-count);
+ count += (limit >= count+4) ? 4 : limit-count;
+ pos = content+count;
+ }
- ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo);
+ if (limit > count && len-2 > count) {
+ memcpy(pos, (u8 *)&hi32, (limit >= count+4) ? 4 : limit-count);
+ count += (limit >= count+4) ? 4 : limit-count;
+ pos = content+count;
+ }
- return ret;
+ if (limit <= count || len-2 <= count)
+ break;
+ i++;
+ }
+ usb_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
+ DBG_88E("%s read count:%u\n", __func__, count);
+ *size = count;
}
-int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
+static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
{
- int ret;
-
- ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo);
-
- return ret;
+ s32 status = _FAIL;
+ u8 physical_map[512];
+ u16 size = 512;
+
+ usb_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
+ memset(physical_map, 0xFF, 512);
+ usb_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
+ status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
+ if (status == _SUCCESS)
+ efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
+ efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
+ return status;
}
-
-static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo)
+void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf)
{
- int ret;
- ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo);
+ if (rtw_IOL_applied(Adapter)) {
+ rtw_hal_power_on(Adapter);
+ iol_mode_enable(Adapter, 1);
+ iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
+ iol_mode_enable(Adapter, 0);
+ }
+ return;
+}
- return ret;
+/* Do not support BT */
+void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
+{
+ switch (type) {
+ case TYPE_EFUSE_MAX_SECTION:
+ {
+ u8 *pMax_section;
+ pMax_section = (u8 *)pOut;
+ *pMax_section = EFUSE_MAX_SECTION_88E;
+ }
+ break;
+ case TYPE_EFUSE_REAL_CONTENT_LEN:
+ {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_CONTENT_LEN_BANK:
+ {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
+ {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
+ {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ case TYPE_EFUSE_MAP_LEN:
+ {
+ u16 *pu2Tmp;
+ pu2Tmp = (u16 *)pOut;
+ *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
+ }
+ break;
+ case TYPE_EFUSE_PROTECT_BYTES_BANK:
+ {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
+ }
+ break;
+ default:
+ {
+ u8 *pu1Tmp;
+ pu1Tmp = (u8 *)pOut;
+ *pu1Tmp = 0;
+ }
+ break;
+ }
}
-/*-----------------------------------------------------------------------------
- * Function: efuse_WordEnableDataRead
- *
- * Overview: Read allowed word in current efuse section data.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Create Version 0.
- * 11/21/2008 MHC Fix Write bug when we only enable late word.
- *
- *---------------------------------------------------------------------------*/
-void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
+u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data)
{
- if (!(word_en&BIT(0))) {
- targetdata[0] = sourdata[0];
- targetdata[1] = sourdata[1];
+ u16 tmpaddr = 0;
+ u16 start_addr = efuse_addr;
+ u8 badworden = 0x0F;
+ u8 tmpdata[8];
+
+ memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
+
+ if (!(word_en&BIT0)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[0]);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[1]);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0]);
+ efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[1]);
+ if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
+ badworden &= (~BIT0);
}
- if (!(word_en&BIT(1))) {
- targetdata[2] = sourdata[2];
- targetdata[3] = sourdata[3];
+ if (!(word_en&BIT1)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[2]);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[3]);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2]);
+ efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[3]);
+ if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
+ badworden &= (~BIT1);
}
- if (!(word_en&BIT(2))) {
- targetdata[4] = sourdata[4];
- targetdata[5] = sourdata[5];
+ if (!(word_en&BIT2)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[4]);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[5]);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4]);
+ efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[5]);
+ if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
+ badworden &= (~BIT2);
}
- if (!(word_en&BIT(3))) {
- targetdata[6] = sourdata[6];
- targetdata[7] = sourdata[7];
+ if (!(word_en&BIT3)) {
+ tmpaddr = start_addr;
+ efuse_OneByteWrite(pAdapter, start_addr++, data[6]);
+ efuse_OneByteWrite(pAdapter, start_addr++, data[7]);
+
+ efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6]);
+ efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[7]);
+ if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
+ badworden &= (~BIT3);
}
+ return badworden;
}
-u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo)
+u16 Efuse_GetCurrentSize(struct adapter *pAdapter)
{
- u8 ret = 0;
+ int bContinual = true;
+ u16 efuse_addr = 0;
+ u8 hoffset = 0, hworden = 0;
+ u8 efuse_data, word_cnts = 0;
+
+ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
+
+ while (bContinual &&
+ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) &&
+ AVAILABLE_EFUSE_ADDR(efuse_addr)) {
+ if (efuse_data != 0xFF) {
+ if ((efuse_data&0x1F) == 0x0F) { /* extended header */
+ hoffset = efuse_data;
+ efuse_addr++;
+ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
+ if ((efuse_data & 0x0F) == 0x0F) {
+ efuse_addr++;
+ continue;
+ } else {
+ hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ hworden = efuse_data & 0x0F;
+ }
+ } else {
+ hoffset = (efuse_data>>4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ }
+ word_cnts = Efuse_CalculateWordCnts(hworden);
+ /* read next header */
+ efuse_addr = efuse_addr + (word_cnts*2)+1;
+ } else {
+ bContinual = false;
+ }
+ }
- ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo);
+ rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
- return ret;
+ return efuse_addr;
}
-static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value)
+int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data)
{
- return efuse_OneByteRead(padapter, address, value, false);
-}
+ u8 ReadState = PG_STATE_HEADER;
+ int bContinual = true;
+ int bDataEmpty = true;
+ u8 efuse_data, word_cnts = 0;
+ u16 efuse_addr = 0;
+ u8 hoffset = 0, hworden = 0;
+ u8 tmpidx = 0;
+ u8 tmpdata[8];
+ u8 max_section = 0;
+ u8 tmp_header = 0;
-static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value)
-{
- return efuse_OneByteWrite(padapter, address, *value, false);
+ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section);
+
+ if (data == NULL)
+ return false;
+ if (offset > max_section)
+ return false;
+
+ memset((void *)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
+ memset((void *)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
+
+ /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
+ /* Skip dummy parts to prevent unexpected data read from Efuse. */
+ /* By pass right now. 2009.02.19. */
+ while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
+ /* Header Read ------------- */
+ if (ReadState & PG_STATE_HEADER) {
+ if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) {
+ if (EXT_HEADER(efuse_data)) {
+ tmp_header = efuse_data;
+ efuse_addr++;
+ efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data);
+ if (!ALL_WORDS_DISABLED(efuse_data)) {
+ hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ hworden = efuse_data & 0x0F;
+ } else {
+ DBG_88E("Error, All words disabled\n");
+ efuse_addr++;
+ continue;
+ }
+ } else {
+ hoffset = (efuse_data>>4) & 0x0F;
+ hworden = efuse_data & 0x0F;
+ }
+ word_cnts = Efuse_CalculateWordCnts(hworden);
+ bDataEmpty = true;
+
+ if (hoffset == offset) {
+ for (tmpidx = 0; tmpidx < word_cnts*2; tmpidx++) {
+ if (efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx, &efuse_data)) {
+ tmpdata[tmpidx] = efuse_data;
+ if (efuse_data != 0xff)
+ bDataEmpty = false;
+ }
+ }
+ if (bDataEmpty == false) {
+ ReadState = PG_STATE_DATA;
+ } else {/* read next header */
+ efuse_addr = efuse_addr + (word_cnts*2)+1;
+ ReadState = PG_STATE_HEADER;
+ }
+ } else {/* read next header */
+ efuse_addr = efuse_addr + (word_cnts*2)+1;
+ ReadState = PG_STATE_HEADER;
+ }
+ } else {
+ bContinual = false;
+ }
+ } else if (ReadState & PG_STATE_DATA) {
+ /* Data section Read ------------- */
+ efuse_WordEnableDataRead(hworden, 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;
+ else
+ return true;
}
-/*
- * read/wirte raw efuse data
- */
-u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data)
+static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr)
{
- int i = 0;
- u16 real_content_len = 0, max_available_size = 0;
- u8 res = _FAIL;
- u8 (*rw8)(struct adapter *, u16, u8*);
+ u8 originaldata[8], badworden = 0;
+ u16 efuse_addr = *pAddr;
+ u32 PgWriteSuccess = 0;
+
+ memset((void *)originaldata, 0xff, 8);
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false);
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
+ if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata)) {
+ /* check if data exist */
+ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata);
- if (start_addr > real_content_len)
- return _FAIL;
+ if (badworden != 0xf) { /* write fail */
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata);
- if (write) {
- if ((start_addr + cnts) > max_available_size)
- return _FAIL;
- rw8 = &efuse_write8;
+ if (!PgWriteSuccess)
+ return false;
+ else
+ efuse_addr = Efuse_GetCurrentSize(pAdapter);
+ } else {
+ efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
+ }
} else {
- rw8 = &efuse_read8;
+ efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
}
+ *pAddr = efuse_addr;
+ return true;
+}
- Efuse_PowerSwitch(padapter, write, true);
-
- /* e-fuse one byte read / write */
- for (i = 0; i < cnts; i++) {
- if (start_addr >= real_content_len) {
- res = _FAIL;
- break;
- }
+static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
+{
+ bool bRet = false;
+ u16 efuse_addr = *pAddr, efuse_max_available_len = 0;
+ u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
+ u8 repeatcnt = 0;
- res = rw8(padapter, start_addr++, data++);
- if (_FAIL == res)
- break;
- }
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len);
- Efuse_PowerSwitch(padapter, write, false);
+ while (efuse_addr < efuse_max_available_len) {
+ pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
- return res;
-}
-/* */
-u16 efuse_GetMaxSize(struct adapter *padapter)
-{
- u16 max_size;
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false);
- return max_size;
-}
-/* */
-u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
-{
- Efuse_PowerSwitch(padapter, false, true);
- *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false);
- Efuse_PowerSwitch(padapter, false, false);
+ while (tmp_header == 0xFF) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+ return false;
- return _SUCCESS;
-}
-/* */
-u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
-{
- u16 mapLen = 0;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
+ }
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
+ /* to write ext_header */
+ if (tmp_header == pg_header) {
+ efuse_addr++;
+ pg_header_temp = pg_header;
+ pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
- if ((addr + cnts) > mapLen)
- return _FAIL;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
- Efuse_PowerSwitch(padapter, false, true);
+ while (tmp_header == 0xFF) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+ return false;
- efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
+ }
- Efuse_PowerSwitch(padapter, false, false);
+ if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
+ return false;
+ } else {
+ efuse_addr++;
+ continue;
+ }
+ } else if (pg_header != tmp_header) { /* offset PG fail */
+ struct pgpkt fixPkt;
+ fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
+ fixPkt.word_en = tmp_header & 0x0F;
+ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
+ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr))
+ return false;
+ } else {
+ bRet = true;
+ break;
+ }
+ } else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */
+ efuse_addr += 2;
+ continue;
+ }
+ }
- return _SUCCESS;
+ *pAddr = efuse_addr;
+ return bRet;
}
-u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
+static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
{
- u16 mapLen = 0;
+ bool bRet = false;
+ u8 pg_header = 0, tmp_header = 0;
+ u16 efuse_addr = *pAddr;
+ u8 repeatcnt = 0;
- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
+ pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
- if ((addr + cnts) > mapLen)
- return _FAIL;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
- Efuse_PowerSwitch(padapter, false, true);
+ while (tmp_header == 0xFF) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
+ return false;
+ efuse_OneByteWrite(pAdapter, efuse_addr, pg_header);
+ efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header);
+ }
- efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+ if (pg_header == tmp_header) {
+ bRet = true;
+ } else {
+ struct pgpkt fixPkt;
+ fixPkt.offset = (tmp_header>>4) & 0x0F;
+ fixPkt.word_en = tmp_header & 0x0F;
+ fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
+ if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr))
+ return false;
+ }
- Efuse_PowerSwitch(padapter, false, false);
+ *pAddr = efuse_addr;
+ return bRet;
+}
- return _SUCCESS;
+static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
+{
+ u16 efuse_addr = *pAddr;
+ u8 badworden = 0;
+ u32 PgWriteSuccess = 0;
+
+ badworden = 0x0f;
+ badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data);
+ if (badworden == 0x0F) {
+ /* write ok */
+ return true;
+ } else {
+ /* reorganize other pg packet */
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data);
+ if (!PgWriteSuccess)
+ return false;
+ else
+ return true;
+ }
}
-/* */
-u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
+
+static bool
+hal_EfusePgPacketWriteHeader(
+ struct adapter *pAdapter,
+ u8 efuseType,
+ u16 *pAddr,
+ struct pgpkt *pTargetPkt)
{
- u8 offset, word_en;
- u8 *map;
- u8 newdata[PGPKT_DATA_SIZE + 1];
- s32 i, idx;
- u8 ret = _SUCCESS;
- u16 mapLen = 0;
+ bool bRet = false;
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
+ if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
+ bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
+ else
+ bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt);
- if ((addr + cnts) > mapLen)
- return _FAIL;
+ return bRet;
+}
- map = rtw_zmalloc(mapLen);
- if (map == NULL)
- return _FAIL;
+static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
+ u8 *pWden)
+{
+ u8 match_word_en = 0x0F; /* default all words are disabled */
+
+ /* check if the same words are enabled both target and current PG packet */
+ if (((pTargetPkt->word_en & BIT0) == 0) &&
+ ((pCurPkt->word_en & BIT0) == 0))
+ match_word_en &= ~BIT0; /* enable word 0 */
+ if (((pTargetPkt->word_en & BIT1) == 0) &&
+ ((pCurPkt->word_en & BIT1) == 0))
+ match_word_en &= ~BIT1; /* enable word 1 */
+ if (((pTargetPkt->word_en & BIT2) == 0) &&
+ ((pCurPkt->word_en & BIT2) == 0))
+ match_word_en &= ~BIT2; /* enable word 2 */
+ if (((pTargetPkt->word_en & BIT3) == 0) &&
+ ((pCurPkt->word_en & BIT3) == 0))
+ match_word_en &= ~BIT3; /* enable word 3 */
+
+ *pWden = match_word_en;
+
+ if (match_word_en != 0xf)
+ return true;
+ else
+ return false;
+}
- ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
- if (ret == _FAIL)
- goto exit;
+static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr)
+{
+ bool bRet = false;
+ u8 i, efuse_data;
+
+ for (i = 0; i < (word_cnts*2); i++) {
+ if (efuse_OneByteRead(pAdapter, (startAddr+i), &efuse_data) && (efuse_data != 0xFF))
+ bRet = true;
+ }
+ return bRet;
+}
+
+static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt)
+{
+ bool bRet = false;
+ u8 i, efuse_data = 0, cur_header = 0;
+ u8 matched_wden = 0, badworden = 0;
+ u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
+ struct pgpkt curPkt;
- Efuse_PowerSwitch(padapter, true, true);
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len);
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max);
- offset = (addr >> 3);
- word_en = 0xF;
- _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
- i = addr & 0x7; /* index of one package */
- idx = 0; /* data index */
+ rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
+ startAddr %= EFUSE_REAL_CONTENT_LEN;
- if (i & 0x1) {
- /* odd start */
- if (data[idx] != map[addr+idx]) {
- word_en &= ~BIT(i >> 1);
- newdata[i-1] = map[addr+idx-1];
- newdata[i] = data[idx];
+ while (1) {
+ if (startAddr >= efuse_max_available_len) {
+ bRet = false;
+ break;
}
- i++;
- idx++;
- }
- do {
- for (; i < PGPKT_DATA_SIZE; i += 2) {
- if (cnts == idx)
- break;
- if ((cnts - idx) == 1) {
- if (data[idx] != map[addr+idx]) {
- word_en &= ~BIT(i >> 1);
- newdata[i] = data[idx];
- newdata[i+1] = map[addr+idx+1];
+
+ if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data) && (efuse_data != 0xFF)) {
+ if (EXT_HEADER(efuse_data)) {
+ cur_header = efuse_data;
+ startAddr++;
+ efuse_OneByteRead(pAdapter, startAddr, &efuse_data);
+ if (ALL_WORDS_DISABLED(efuse_data)) {
+ bRet = false;
+ break;
+ } else {
+ curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
+ curPkt.word_en = efuse_data & 0x0F;
}
- idx++;
- break;
} else {
- if ((data[idx] != map[addr+idx]) ||
- (data[idx+1] != map[addr+idx+1])) {
- word_en &= ~BIT(i >> 1);
- newdata[i] = data[idx];
- newdata[i+1] = data[idx + 1];
- }
- idx += 2;
+ cur_header = efuse_data;
+ curPkt.offset = (cur_header>>4) & 0x0F;
+ curPkt.word_en = cur_header & 0x0F;
}
- if (idx == cnts)
- break;
- }
-
- if (word_en != 0xF) {
- ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false);
- DBG_88E("offset=%x\n", offset);
- DBG_88E("word_en=%x\n", word_en);
-
- for (i = 0; i < PGPKT_DATA_SIZE; i++)
- DBG_88E("data=%x \t", newdata[i]);
- if (ret == _FAIL)
- break;
- }
- if (idx == cnts)
+ curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
+ /* if same header is found but no data followed */
+ /* write some part of data followed by the header. */
+ if ((curPkt.offset == pTargetPkt->offset) &&
+ (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1)) &&
+ wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
+ /* Here to write partial data */
+ badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data);
+ if (badworden != 0x0F) {
+ u32 PgWriteSuccess = 0;
+ /* if write fail on some words, write these bad words again */
+
+ PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data);
+
+ if (!PgWriteSuccess) {
+ bRet = false; /* write fail, return */
+ break;
+ }
+ }
+ /* partial write ok, update the target packet for later use */
+ for (i = 0; i < 4; i++) {
+ if ((matched_wden & (0x1<<i)) == 0) /* this word has been written */
+ pTargetPkt->word_en |= (0x1<<i); /* disable the word */
+ }
+ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+ }
+ /* read from next header */
+ startAddr = startAddr + (curPkt.word_cnts*2) + 1;
+ } else {
+ /* not used header, 0xff */
+ *pAddr = startAddr;
+ bRet = true;
break;
-
- offset++;
- i = 0;
- word_en = 0xF;
- _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
- } while (1);
-
- Efuse_PowerSwitch(padapter, true, false);
-exit:
- kfree(map);
- return ret;
+ }
+ }
+ return bRet;
}
-/* */
-u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
+static bool
+hal_EfusePgCheckAvailableAddr(
+ struct adapter *pAdapter,
+ u8 efuseType
+ )
{
- u8 offset, word_en;
- u8 *map;
- u8 newdata[PGPKT_DATA_SIZE + 1];
- s32 i, idx;
- u8 ret = _SUCCESS;
- u16 mapLen = 0;
+ u16 efuse_max_available_len = 0;
- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
+ /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
+ EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len);
- if ((addr + cnts) > mapLen)
- return _FAIL;
+ if (Efuse_GetCurrentSize(pAdapter) >= efuse_max_available_len)
+ return false;
+ return true;
+}
- map = rtw_zmalloc(mapLen);
- if (map == NULL)
- return _FAIL;
+static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt)
+{
+ memset((void *)pTargetPkt->data, 0xFF, sizeof(u8)*8);
+ pTargetPkt->offset = offset;
+ pTargetPkt->word_en = word_en;
+ efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
+ pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
+}
- ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map);
- if (ret == _FAIL)
- goto exit;
+bool Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData)
+{
+ struct pgpkt targetPkt;
+ u16 startAddr = 0;
+ u8 efuseType = EFUSE_WIFI;
- Efuse_PowerSwitch(padapter, true, true);
+ if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType))
+ return false;
- offset = (addr >> 3);
- word_en = 0xF;
- _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
- i = addr & 0x7; /* index of one package */
- idx = 0; /* data index */
+ hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
- if (i & 0x1) {
- /* odd start */
- if (data[idx] != map[addr+idx]) {
- word_en &= ~BIT(i >> 1);
- newdata[i-1] = map[addr+idx-1];
- newdata[i] = data[idx];
- }
- i++;
- idx++;
- }
- do {
- for (; i < PGPKT_DATA_SIZE; i += 2) {
- if (cnts == idx)
- break;
- if ((cnts - idx) == 1) {
- if (data[idx] != map[addr+idx]) {
- word_en &= ~BIT(i >> 1);
- newdata[i] = data[idx];
- newdata[i+1] = map[addr+idx+1];
- }
- idx++;
- break;
- } else {
- if ((data[idx] != map[addr+idx]) ||
- (data[idx+1] != map[addr+idx+1])) {
- word_en &= ~BIT(i >> 1);
- newdata[i] = data[idx];
- newdata[i+1] = data[idx + 1];
- }
- idx += 2;
- }
- if (idx == cnts)
- break;
- }
+ if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt))
+ return false;
- if (word_en != 0xF) {
- DBG_88E("%s: offset=%#X\n", __func__, offset);
- DBG_88E("%s: word_en=%#X\n", __func__, word_en);
- DBG_88E("%s: data=", __func__);
- for (i = 0; i < PGPKT_DATA_SIZE; i++)
- DBG_88E("0x%02X ", newdata[i]);
- DBG_88E("\n");
+ if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt))
+ return false;
- ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false);
- if (ret == _FAIL)
- break;
- }
+ if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt))
+ return false;
- if (idx == cnts)
- break;
+ return true;
+}
- offset++;
- i = 0;
- word_en = 0xF;
- _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
- } while (1);
+u8 Efuse_CalculateWordCnts(u8 word_en)
+{
+ u8 word_cnts = 0;
+ if (!(word_en & BIT(0)))
+ word_cnts++; /* 0 : write enable */
+ if (!(word_en & BIT(1)))
+ word_cnts++;
+ if (!(word_en & BIT(2)))
+ word_cnts++;
+ if (!(word_en & BIT(3)))
+ word_cnts++;
+ return word_cnts;
+}
- Efuse_PowerSwitch(padapter, true, false);
+u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data)
+{
+ u8 tmpidx = 0;
+ u8 result;
-exit:
+ usb_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff));
+ usb_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
+ (usb_read8(pAdapter, EFUSE_CTRL+2) & 0xFC));
- kfree(map);
+ usb_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */
- return ret;
+ while (!(0x80 & usb_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
+ tmpidx++;
+ if (tmpidx < 100) {
+ *data = usb_read8(pAdapter, EFUSE_CTRL);
+ result = true;
+ } else {
+ *data = 0xff;
+ result = false;
+ }
+ return result;
}
-/*-----------------------------------------------------------------------------
- * Function: efuse_ShadowRead1Byte
- * efuse_ShadowRead2Byte
- * efuse_ShadowRead4Byte
- *
- * Overview: Read from efuse init map by one/two/four bytes !!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void
-efuse_ShadowRead1Byte(
- struct adapter *pAdapter,
- u16 Offset,
- u8 *Value)
+u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data)
{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
+ u8 tmpidx = 0;
+ u8 result;
- *Value = pEEPROM->efuse_eeprom_data[Offset];
+ usb_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
+ usb_write8(pAdapter, EFUSE_CTRL+2,
+ (usb_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) |
+ (u8)((addr>>8) & 0x03));
+ usb_write8(pAdapter, EFUSE_CTRL, data);/* data */
-} /* EFUSE_ShadowRead1Byte */
+ usb_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */
-/* Read Two Bytes */
-static void
-efuse_ShadowRead2Byte(
- struct adapter *pAdapter,
- u16 Offset,
- u16 *Value)
-{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
+ while ((0x80 & usb_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100))
+ tmpidx++;
- *Value = pEEPROM->efuse_eeprom_data[Offset];
- *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
+ if (tmpidx < 100)
+ result = true;
+ else
+ result = false;
-} /* EFUSE_ShadowRead2Byte */
+ return result;
+}
-/* Read Four Bytes */
-static void
-efuse_ShadowRead4Byte(
- struct adapter *pAdapter,
- u16 Offset,
- u32 *Value)
+/*
+ * Overview: Read allowed word in current efuse section data.
+ */
+void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata)
{
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
-
- *Value = pEEPROM->efuse_eeprom_data[Offset];
- *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
- *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
- *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
-
-} /* efuse_ShadowRead4Byte */
+ 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];
+ }
+}
-/*-----------------------------------------------------------------------------
- * Function: Efuse_ReadAllMap
- *
+/*
* Overview: Read All Efuse content
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/11/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+ */
+static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse)
{
u16 mapLen = 0;
Efuse_PowerSwitch(pAdapter, false, true);
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
- efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+ efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse);
Efuse_PowerSwitch(pAdapter, false, false);
}
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowMapUpdate
- *
+/*
* Overview: Transfer current EFUSE content to shadow init and modify map.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/13/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+ */
void EFUSE_ShadowMapUpdate(
struct adapter *pAdapter,
- u8 efuseType,
- bool pseudo)
+ u8 efuseType)
{
struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
u16 mapLen = 0;
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
+ EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
if (pEEPROM->bautoload_fail_flag)
- _rtw_memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
+ memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
else
- Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
-} /* EFUSE_ShadowMapUpdate */
-
-/*-----------------------------------------------------------------------------
- * Function: EFUSE_ShadowRead
- *
- * Overview: Read from efuse init map !!!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/12/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value)
-{
- if (Type == 1)
- efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
- else if (Type == 2)
- efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
- else if (Type == 4)
- efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
-
-} /* EFUSE_ShadowRead */
+ Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data);
+}
diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
index 0552019d1cf7..755d3effd0a7 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
@@ -20,11 +20,11 @@
#define _IEEE80211_C
#include <drv_types.h>
+#include <osdep_intf.h>
#include <ieee80211.h>
#include <wifi.h>
#include <osdep_service.h>
#include <wlan_bssdef.h>
-#include <usb_osintf.h>
u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
u16 RTW_WPA_VERSION = 1;
@@ -206,8 +206,8 @@ inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl,
ie_data[0] = ttl;
ie_data[1] = flags;
- RTW_PUT_LE16((u8 *)&ie_data[2], reason);
- RTW_PUT_LE16((u8 *)&ie_data[4], precedence);
+ *(u16 *)(ie_data+2) = cpu_to_le16(reason);
+ *(u16 *)(ie_data+4) = cpu_to_le16(precedence);
return rtw_set_ie(buf, 0x118, 6, ie_data, buf_len);
}
@@ -334,7 +334,7 @@ exit:
void rtw_set_supported_rate(u8 *SupportedRates, uint mode)
{
- _rtw_memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
+ memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
switch (mode) {
case WIRELESS_11B:
@@ -551,7 +551,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis
/* pairwise_cipher */
if (left >= 2) {
- count = RTW_GET_LE16(pos);
+ count = get_unaligned_le16(pos);
pos += 2;
left -= 2;
@@ -619,7 +619,7 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi
/* pairwise_cipher */
if (left >= 2) {
- count = RTW_GET_LE16(pos);
+ count = get_unaligned_le16(pos);
pos += 2;
left -= 2;
@@ -807,8 +807,8 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id , u8 *buf_at
while (attr_ptr - wps_ie < wps_ielen) {
/* 4 = 2(Attribute ID) + 2(Length) */
- u16 attr_id = RTW_GET_BE16(attr_ptr);
- u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2);
+ u16 attr_id = get_unaligned_be16(attr_ptr);
+ u16 attr_data_len = get_unaligned_be16(attr_ptr + 2);
u16 attr_len = attr_data_len + 4;
if (attr_id == target_attr_id) {
@@ -957,7 +957,7 @@ enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len,
u8 *pos = start;
int unknown = 0;
- _rtw_memset(elems, 0, sizeof(*elems));
+ memset(elems, 0, sizeof(*elems));
while (left >= 2) {
u8 id, elen;
@@ -1067,41 +1067,18 @@ enum parse_res rtw_ieee802_11_parse_elems(u8 *start, uint len,
return unknown ? ParseUnknown : ParseOK;
}
-u8 key_char2num(u8 ch)
-{
- if ((ch >= '0') && (ch <= '9'))
- return ch - '0';
- else if ((ch >= 'a') && (ch <= 'f'))
- return ch - 'a' + 10;
- else if ((ch >= 'A') && (ch <= 'F'))
- return ch - 'A' + 10;
- else
- return 0xff;
-}
-
-u8 str_2char2num(u8 hch, u8 lch)
-{
- return (key_char2num(hch) * 10) + key_char2num(lch);
-}
-
-u8 key_2char2num(u8 hch, u8 lch)
-{
- return (key_char2num(hch) << 4) | key_char2num(lch);
-}
-
void rtw_macaddr_cfg(u8 *mac_addr)
{
u8 mac[ETH_ALEN];
+
if (mac_addr == NULL)
return;
- if (rtw_initmac) { /* Users specify the mac address */
- int jj, kk;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk + 1]);
+ if (rtw_initmac && mac_pton(rtw_initmac, mac)) {
+ /* Users specify the mac address */
memcpy(mac_addr, mac, ETH_ALEN);
- } else { /* Use the mac address stored in the Efuse */
+ } else {
+ /* Use the mac address stored in the Efuse */
memcpy(mac, mac_addr, ETH_ALEN);
}
@@ -1133,9 +1110,6 @@ void dump_ies(u8 *buf, u32 buf_len)
len = *(pos+1);
DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len);
- #ifdef CONFIG_88EU_P2P
- dump_p2p_ie(pos, len);
- #endif
dump_wps_ie(pos, len);
pos += (2 + len);
@@ -1156,217 +1130,13 @@ void dump_wps_ie(u8 *ie, u32 ie_len)
pos += 6;
while (pos-ie < ie_len) {
- id = RTW_GET_BE16(pos);
- len = RTW_GET_BE16(pos + 2);
+ id = get_unaligned_be16(pos);
+ len = get_unaligned_be16(pos + 2);
DBG_88E("%s ID:0x%04x, LEN:%u\n", __func__, id, len);
pos += (4+len);
}
}
-#ifdef CONFIG_88EU_P2P
-void dump_p2p_ie(u8 *ie, u32 ie_len)
-{
- u8 *pos = (u8 *)ie;
- u8 id;
- u16 len;
- u8 *p2p_ie;
- uint p2p_ielen;
-
- p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen);
- if (p2p_ie != ie || p2p_ielen == 0)
- return;
-
- pos += 6;
- while (pos-ie < ie_len) {
- id = *pos;
- len = RTW_GET_LE16(pos+1);
- DBG_88E("%s ID:%u, LEN:%u\n", __func__, id, len);
- pos += (3+len);
- }
-}
-
-/**
- * rtw_get_p2p_ie - Search P2P IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie
- * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE
- *
- * Returns: The address of the P2P IE found, or NULL
- */
-u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen)
-{
- uint cnt = 0;
- u8 *p2p_ie_ptr;
- u8 eid, p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09};
-
- if (p2p_ielen != NULL)
- *p2p_ielen = 0;
-
- while (cnt < in_len) {
- eid = in_ie[cnt];
- if ((in_len < 0) || (cnt > MAX_IE_SZ)) {
- dump_stack();
- return NULL;
- }
- if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&in_ie[cnt+2], p2p_oui, 4))) {
- p2p_ie_ptr = in_ie + cnt;
-
- if (p2p_ie != NULL)
- memcpy(p2p_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
- if (p2p_ielen != NULL)
- *p2p_ielen = in_ie[cnt + 1] + 2;
- return p2p_ie_ptr;
- } else {
- cnt += in_ie[cnt + 1] + 2; /* goto next */
- }
- }
- return NULL;
-}
-
-/**
- * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr
- * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute
- *
- * Returns: the address of the specific WPS attribute found, or NULL
- */
-u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id , u8 *buf_attr, u32 *len_attr)
-{
- u8 *attr_ptr = NULL;
- u8 *target_attr_ptr = NULL;
- u8 p2p_oui[4] = {0x50, 0x6F, 0x9A, 0x09};
-
- if (len_attr)
- *len_attr = 0;
-
- if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) ||
- (memcmp(p2p_ie + 2, p2p_oui , 4)))
- return attr_ptr;
-
- /* 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */
- attr_ptr = p2p_ie + 6; /* goto first attr */
-
- while (attr_ptr - p2p_ie < p2p_ielen) {
- /* 3 = 1(Attribute ID) + 2(Length) */
- u8 attr_id = *attr_ptr;
- u16 attr_data_len = RTW_GET_LE16(attr_ptr + 1);
- u16 attr_len = attr_data_len + 3;
-
- if (attr_id == target_attr_id) {
- target_attr_ptr = attr_ptr;
-
- if (buf_attr)
- memcpy(buf_attr, attr_ptr, attr_len);
- if (len_attr)
- *len_attr = attr_len;
- break;
- } else {
- attr_ptr += attr_len; /* goto next */
- }
- }
- return target_attr_ptr;
-}
-
-/**
- * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE
- * @p2p_ie: Address of P2P IE to search
- * @p2p_ielen: Length limit from p2p_ie
- * @target_attr_id: The attribute ID of P2P attribute to search
- * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content
- * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content
- *
- * Returns: the address of the specific P2P attribute content found, or NULL
- */
-u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id , u8 *buf_content, uint *len_content)
-{
- u8 *attr_ptr;
- u32 attr_len;
-
- if (len_content)
- *len_content = 0;
-
- attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len);
-
- if (attr_ptr && attr_len) {
- if (buf_content)
- memcpy(buf_content, attr_ptr+3, attr_len-3);
-
- if (len_content)
- *len_content = attr_len-3;
-
- return attr_ptr+3;
- }
-
- return NULL;
-}
-
-u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr)
-{
- u32 a_len;
-
- *pbuf = attr_id;
-
- /* u16*)(pbuf + 1) = cpu_to_le16(attr_len); */
- RTW_PUT_LE16(pbuf + 1, attr_len);
-
- if (pdata_attr)
- memcpy(pbuf + 3, pdata_attr, attr_len);
-
- a_len = attr_len + 3;
-
- return a_len;
-}
-
-static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id)
-{
- u8 *target_attr;
- u32 target_attr_len;
- uint ielen = ielen_ori;
-
- while (1) {
- target_attr = rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len);
- if (target_attr && target_attr_len) {
- u8 *next_attr = target_attr+target_attr_len;
- uint remain_len = ielen-(next_attr-ie);
-
- _rtw_memset(target_attr, 0, target_attr_len);
- memcpy(target_attr, next_attr, remain_len);
- _rtw_memset(target_attr+remain_len, 0, target_attr_len);
- *(ie+1) -= target_attr_len;
- ielen -= target_attr_len;
- } else {
- break;
- }
- }
- return ielen;
-}
-
-void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex, u8 attr_id)
-{
- u8 *p2p_ie;
- uint p2p_ielen, p2p_ielen_ori;
-
- p2p_ie = rtw_get_p2p_ie(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori);
- if (p2p_ie) {
- p2p_ielen = rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id);
- if (p2p_ielen != p2p_ielen_ori) {
- u8 *next_ie_ori = p2p_ie+p2p_ielen_ori;
- u8 *next_ie = p2p_ie+p2p_ielen;
- uint remain_len = bss_ex->IELength-(next_ie_ori-bss_ex->IEs);
-
- memcpy(next_ie, next_ie_ori, remain_len);
- _rtw_memset(next_ie+remain_len, 0, p2p_ielen_ori-p2p_ielen);
- bss_ex->IELength -= p2p_ielen_ori-p2p_ielen;
- }
- }
-}
-
-#endif /* CONFIG_88EU_P2P */
-
/* Baron adds to avoid FreeBSD warning */
int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c
deleted file mode 100644
index 7530532b3ff0..000000000000
--- a/drivers/staging/rtl8188eu/core/rtw_io.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-/*
-
-The purpose of rtw_io.c
-
-a. provides the API
-
-b. provides the protocol engine
-
-c. provides the software interface between caller and the hardware interface
-
-
-Compiler Flag Option:
-
-USB:
- a. USE_ASYNC_IRP: Both sync/async operations are provided.
-
-Only sync read/rtw_write_mem operations are provided.
-
-jackson@realtek.com.tw
-
-*/
-
-#define _RTW_IO_C_
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtw_io.h>
-#include <osdep_intf.h>
-#include <usb_ops.h>
-
-#define rtw_le16_to_cpu(val) le16_to_cpu(val)
-#define rtw_le32_to_cpu(val) le32_to_cpu(val)
-#define rtw_cpu_to_le16(val) cpu_to_le16(val)
-#define rtw_cpu_to_le32(val) cpu_to_le32(val)
-
-
-u8 _rtw_read8(struct adapter *adapter, u32 addr)
-{
- u8 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
-
- _read8 = pintfhdl->io_ops._read8;
- r_val = _read8(pintfhdl, addr);
- return r_val;
-}
-
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
-{
- u16 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
- _read16 = pintfhdl->io_ops._read16;
-
- r_val = _read16(pintfhdl, addr);
- return r_val;
-}
-
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
-{
- u32 r_val;
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
- _read32 = pintfhdl->io_ops._read32;
-
- r_val = _read32(pintfhdl, addr);
- return r_val;
-}
-
-int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int ret;
- _write8 = pintfhdl->io_ops._write8;
-
- ret = _write8(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-
-int _rtw_write16(struct adapter *adapter, u32 addr, u16 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int ret;
- _write16 = pintfhdl->io_ops._write16;
-
- ret = _write16(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-int _rtw_write32(struct adapter *adapter, u32 addr, u32 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
- int ret;
- _write32 = pintfhdl->io_ops._write32;
-
- ret = _write32(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-
-int _rtw_writeN(struct adapter *adapter, u32 addr , u32 length , u8 *pdata)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));
- int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
- int ret;
- _writeN = pintfhdl->io_ops._writeN;
-
- ret = _writeN(pintfhdl, addr, length, pdata);
-
- return RTW_STATUS_CODE(ret);
-}
-int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int ret;
- _write8_async = pintfhdl->io_ops._write8_async;
-
- ret = _write8_async(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-
-int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int ret;
-
- _write16_async = pintfhdl->io_ops._write16_async;
- ret = _write16_async(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-
-int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val)
-{
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
- int ret;
-
- _write32_async = pintfhdl->io_ops._write32_async;
- ret = _write32_async(pintfhdl, addr, val);
-
- return RTW_STATUS_CODE(ret);
-}
-
-void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
-{
- void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
- RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
- ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
- adapter->bDriverStopped, adapter->bSurpriseRemoved));
- return;
- }
- _read_mem = pintfhdl->io_ops._read_mem;
- _read_mem(pintfhdl, addr, cnt, pmem);
-}
-
-void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
-{
- void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
-
-
- _write_mem = pintfhdl->io_ops._write_mem;
-
- _write_mem(pintfhdl, addr, cnt, pmem);
-
-}
-
-void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
-{
- u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
-
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
- RT_TRACE(_module_rtl871x_io_c_, _drv_info_,
- ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)",
- adapter->bDriverStopped, adapter->bSurpriseRemoved));
- return;
- }
-
- _read_port = pintfhdl->io_ops._read_port;
-
- _read_port(pintfhdl, addr, cnt, pmem);
-
-}
-
-void _rtw_read_port_cancel(struct adapter *adapter)
-{
- void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
-
- _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
-
- if (_read_port_cancel)
- _read_port_cancel(pintfhdl);
-}
-
-u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
-{
- u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
- u32 ret = _SUCCESS;
-
-
- _write_port = pintfhdl->io_ops._write_port;
-
- ret = _write_port(pintfhdl, addr, cnt, pmem);
-
-
- return ret;
-}
-
-u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
-{
- int ret = _SUCCESS;
- struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
- struct submit_ctx sctx;
-
- rtw_sctx_init(&sctx, timeout_ms);
- pxmitbuf->sctx = &sctx;
-
- ret = _rtw_write_port(adapter, addr, cnt, pmem);
-
- if (ret == _SUCCESS)
- ret = rtw_sctx_wait(&sctx);
-
- return ret;
-}
-
-void _rtw_write_port_cancel(struct adapter *adapter)
-{
- void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
- struct io_priv *pio_priv = &adapter->iopriv;
- struct intf_hdl *pintfhdl = &(pio_priv->intf);
-
- _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
-
- if (_write_port_cancel)
- _write_port_cancel(pintfhdl);
-}
-
-int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops))
-{
- struct io_priv *piopriv = &padapter->iopriv;
- struct intf_hdl *pintf = &piopriv->intf;
-
- if (set_intf_ops == NULL)
- return _FAIL;
-
- piopriv->padapter = padapter;
- pintf->padapter = padapter;
- pintf->pintf_dev = adapter_to_dvobj(padapter);
-
- set_intf_ops(&pintf->io_ops);
-
- return _SUCCESS;
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
index f1398ab01d7b..fc280ce57d2c 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
@@ -25,9 +25,6 @@
#include <rtw_ioctl_set.h>
#include <hal_intf.h>
-#include <usb_osintf.h>
-#include <usb_ops.h>
-
extern void indicate_wx_scan_complete_event(struct adapter *padapter);
#define IS_MAC_ADDRESS_BROADCAST(addr) \
@@ -37,32 +34,6 @@ extern void indicate_wx_scan_complete_event(struct adapter *padapter);
(addr[4] == 0xff) && (addr[5] == 0xff)) ? true : false \
)
-u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid)
-{
- u8 i;
- u8 ret = true;
-
-
- if (ssid->SsidLength > 32) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
- ret = false;
- goto exit;
- }
-
- for (i = 0; i < ssid->SsidLength; i++) {
- /* wifi, printable ascii code must be supported */
- if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
- ret = false;
- break;
- }
- }
-
-exit:
-
- return ret;
-}
-
u8 rtw_do_join(struct adapter *padapter)
{
struct list_head *plist, *phead;
@@ -86,7 +57,7 @@ u8 rtw_do_join(struct adapter *padapter)
pmlmepriv->to_join = true;
- if (_rtw_queue_empty(queue)) {
+ if (list_empty(&queue->queue)) {
spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
@@ -127,7 +98,7 @@ u8 rtw_do_join(struct adapter *padapter)
pibss = padapter->registrypriv.dev_network.MacAddress;
- _rtw_memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
+ 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);
@@ -595,421 +566,6 @@ exit:
return ret;
}
-u8 rtw_set_802_11_remove_wep(struct adapter *padapter, u32 keyindex)
-{
- u8 ret = _SUCCESS;
-
- if (keyindex >= 0x80000000 || padapter == NULL) {
- ret = false;
- goto exit;
- } else {
- int res;
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
- if (keyindex < 4) {
- _rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
- res = rtw_set_key(padapter, psecuritypriv, keyindex, 0);
- psecuritypriv->dot11DefKeylen[keyindex] = 0;
- if (res == _FAIL)
- ret = _FAIL;
- } else {
- ret = _FAIL;
- }
- }
-exit:
-
- return ret;
-}
-
-u8 rtw_set_802_11_add_key(struct adapter *padapter, struct ndis_802_11_key *key)
-{
- uint encryptionalgo;
- u8 *pbssid;
- struct sta_info *stainfo;
- u8 bgroup = false;
- u8 bgrouptkey = false;/* can be removed later */
- u8 ret = _SUCCESS;
-
-
- if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)) {
- /* It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination, */
- /* it must fail the request and return NDIS_STATUS_INVALID_DATA. */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000)==0)[=%d]",
- (int)(key->KeyIndex & 0x80000000) == 0));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000)>0)[=%d]",
- (int)(key->KeyIndex & 0x40000000) > 0));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("rtw_set_802_11_add_key: key->KeyIndex=%d\n",
- (int)key->KeyIndex));
- ret = _FAIL;
- goto exit;
- }
-
- if (key->KeyIndex & 0x40000000) {
- /* Pairwise key */
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n"));
-
- pbssid = get_bssid(&padapter->mlmepriv);
- stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid);
-
- if ((stainfo != NULL) && (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("OID_802_11_ADD_KEY:(stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n"));
- encryptionalgo = stainfo->dot118021XPrivacy;
- } else {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: stainfo == NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!= dot11AuthAlgrthm_8021X)\n"));
- encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm;
- }
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_set_802_11_add_key: (encryptionalgo==%d)!\n",
- encryptionalgo));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm==%d)!\n",
- padapter->securitypriv.dot11PrivacyAlgrthm));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm==%d)!\n",
- padapter->securitypriv.dot11AuthAlgrthm));
-
- if ((stainfo != NULL))
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy==%d)!\n",
- stainfo->dot118021XPrivacy));
-
- if (key->KeyIndex & 0x000000FF) {
- /* The key index is specified in the lower 8 bits by values of zero to 255. */
- /* The key index should be set to zero for a Pairwise key, and the driver should fail with */
- /* NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, (" key->KeyIndex & 0x000000FF.\n"));
- ret = _FAIL;
- goto exit;
- }
-
- /* check BSSID */
- if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == true) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MacAddr_isBcst(key->BSSID)\n"));
- ret = false;
- goto exit;
- }
-
- /* Check key length for TKIP. */
- if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("TKIP KeyLength:0x%x != 32\n", key->KeyLength));
- ret = _FAIL;
- goto exit;
- }
-
- /* Check key length for AES. */
- if ((encryptionalgo == _AES_) && (key->KeyLength != 16)) {
- /* For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case. */
- if (key->KeyLength == 32) {
- key->KeyLength = 16;
- } else {
- ret = _FAIL;
- goto exit;
- }
- }
-
- /* Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko. */
- if ((encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_) &&
- (key->KeyLength != 5 && key->KeyLength != 13)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength));
- ret = _FAIL;
- goto exit;
- }
-
- bgroup = false;
-
- /* Check the pairwise key. Added by Annie, 2005-07-06. */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("[Pairwise Key set]\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key index: 0x%8x(0x%8x)\n", key->KeyIndex, (key->KeyIndex&0x3)));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key Length: %d\n", key->KeyLength));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n"));
-
- } else {
- /* Group key - KeyIndex(BIT30 == 0) */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ Group key +++++\n"));
-
-
- /* when add wep key through add key and didn't assigned encryption type before */
- if ((padapter->securitypriv.ndisauthtype <= 3) &&
- (padapter->securitypriv.dot118021XGrpPrivacy == 0)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("keylen =%d(Adapter->securitypriv.dot11PrivacyAlgrthm=%x )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n",
- key->KeyLength, padapter->securitypriv.dot11PrivacyAlgrthm,
- padapter->securitypriv.dot118021XGrpPrivacy));
- switch (key->KeyLength) {
- case 5:
- padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("Adapter->securitypriv.dot11PrivacyAlgrthm=%x key->KeyLength=%u\n",
- padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength));
- break;
- case 13:
- padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("Adapter->securitypriv.dot11PrivacyAlgrthm=%x key->KeyLength=%u\n",
- padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength));
- break;
- default:
- padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("Adapter->securitypriv.dot11PrivacyAlgrthm=%x key->KeyLength=%u\n",
- padapter->securitypriv.dot11PrivacyAlgrthm, key->KeyLength));
- break;
- }
-
- encryptionalgo = padapter->securitypriv.dot11PrivacyAlgrthm;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- (" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n",
- padapter->securitypriv.dot11PrivacyAlgrthm));
-
- } else {
- encryptionalgo = padapter->securitypriv.dot118021XGrpPrivacy;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("(Adapter->securitypriv.dot11PrivacyAlgrthm=%x)encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n",
- padapter->securitypriv.dot11PrivacyAlgrthm, encryptionalgo,
- padapter->securitypriv.dot118021XGrpPrivacy, key->KeyLength));
- }
-
- if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE) == true) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == false)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- (" IBSS but BSSID is not Broadcast Address.\n"));
- ret = _FAIL;
- goto exit;
- }
-
- /* Check key length for TKIP */
- if ((encryptionalgo == _TKIP_) && (key->KeyLength != 32)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- (" TKIP GTK KeyLength:%u != 32\n", key->KeyLength));
- ret = _FAIL;
- goto exit;
- } else if (encryptionalgo == _AES_ && (key->KeyLength != 16 && key->KeyLength != 32)) {
- /* Check key length for AES */
- /* For NDTEST, we allow keylen = 32 in this case. 2005.01.27, by rcnjko. */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n",
- key->KeyLength));
- ret = _FAIL;
- goto exit;
- }
-
- /* Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03. */
- if ((encryptionalgo == _AES_) && (key->KeyLength == 32)) {
- key->KeyLength = 16;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("AES key length changed: %u\n", key->KeyLength));
- }
-
- if (key->KeyIndex & 0x8000000) {/* error ??? 0x8000_0000 */
- bgrouptkey = true;
- }
-
- if ((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)) &&
- (check_fwstate(&padapter->mlmepriv, _FW_LINKED)))
- bgrouptkey = true;
- bgroup = true;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("[Group Key set]\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n")) ;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key index: 0x%8x(0x%8x)\n", key->KeyIndex, (key->KeyIndex&0x3)));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("key Length: %d\n", key->KeyLength)) ;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("------------------------------------------\n"));
- }
-
- /* If WEP encryption algorithm, just call rtw_set_802_11_add_wep(). */
- if ((padapter->securitypriv.dot11AuthAlgrthm != dot11AuthAlgrthm_8021X) &&
- (encryptionalgo == _WEP40_ || encryptionalgo == _WEP104_)) {
- u32 keyindex;
- u32 len = FIELD_OFFSET(struct ndis_802_11_key, KeyMaterial) + key->KeyLength;
- struct ndis_802_11_wep *wep = &padapter->securitypriv.ndiswep;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ WEP key +++++\n"));
-
- wep->Length = len;
- keyindex = key->KeyIndex&0x7fffffff;
- wep->KeyIndex = keyindex ;
- wep->KeyLength = key->KeyLength;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY:Before memcpy\n"));
-
- memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength);
- memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength);
-
- padapter->securitypriv.dot11DefKeylen[keyindex] = key->KeyLength;
- padapter->securitypriv.dot11PrivacyKeyIndex = keyindex;
-
- ret = rtw_set_802_11_add_wep(padapter, wep);
- goto exit;
- }
- if (key->KeyIndex & 0x20000000) {
- /* SetRSC */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n"));
- if (bgroup) {
- unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL;
- memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8);
- } else {
- unsigned long long keysrc = key->KeyRSC & 0x00FFFFFFFFFFFFULL;
- memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8);
- }
- }
-
- /* Indicate this key idx is used for TX */
- /* Save the key in KeyMaterial */
- if (bgroup) { /* Group transmit key */
- int res;
-
- if (bgrouptkey)
- padapter->securitypriv.dot118021XGrpKeyid = (u8)key->KeyIndex;
- if ((key->KeyIndex&0x3) == 0) {
- ret = _FAIL;
- goto exit;
- }
- _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
- _rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
- _rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
-
- if ((key->KeyIndex & 0x10000000)) {
- memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
- memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
- } else {
- memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
- memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],
- padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
- }
-
- /* set group key by index */
- memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength);
-
- key->KeyIndex = key->KeyIndex & 0x03;
-
- padapter->securitypriv.binstallGrpkey = true;
-
- padapter->securitypriv.bcheck_grpkey = false;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("reset group key"));
-
- res = rtw_set_key(padapter, &padapter->securitypriv, key->KeyIndex, 1);
-
- if (res == _FAIL)
- ret = _FAIL;
-
- goto exit;
-
- } else { /* Pairwise Key */
- u8 res;
-
- pbssid = get_bssid(&padapter->mlmepriv);
- stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid);
-
- if (stainfo != NULL) {
- _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16);/* clear keybuffer */
-
- memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16);
-
- if (encryptionalgo == _TKIP_) {
- padapter->securitypriv.busetkipkey = false;
-
- /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n========== _set_timer\n"));
-
- /* if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255] */
- if ((key->KeyIndex & 0x10000000)) {
- memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8);
- memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8);
-
- } else {
- memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8);
- memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8);
- }
- }
-
-
- /* Set key to CAM through H2C command */
- if (bgrouptkey) { /* never go to here */
- res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, false);
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n"));
- } else {
- res = rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, true);
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n"));
- }
- if (!res)
- ret = _FAIL;
- }
- }
-exit:
-
- return ret;
-}
-
-u8 rtw_set_802_11_remove_key(struct adapter *padapter, struct ndis_802_11_remove_key *key)
-{
- u8 *pbssid;
- struct sta_info *stainfo;
- u8 bgroup = (key->KeyIndex & 0x4000000) > 0 ? false : true;
- u8 keyIndex = (u8)key->KeyIndex & 0x03;
- u8 ret = _SUCCESS;
-
-
- if ((key->KeyIndex & 0xbffffffc) > 0) {
- ret = _FAIL;
- goto exit;
- }
-
- if (bgroup) {
- /* clear group key by index */
-
- _rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16);
-
- /* \todo Send a H2C Command to Firmware for removing this Key in CAM Entry. */
- } else {
- pbssid = get_bssid(&padapter->mlmepriv);
- stainfo = rtw_get_stainfo(&padapter->stapriv, pbssid);
- if (stainfo) {
- /* clear key by BSSID */
- _rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16);
-
- /* \todo Send a H2C Command to Firmware for disable this Key in CAM Entry. */
- } else {
- ret = _FAIL;
- goto exit;
- }
- }
-exit:
-
- return ret;
-}
-
/*
* rtw_get_cur_max_rate -
* @adapter: pointer to struct adapter structure
@@ -1078,36 +634,6 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
}
/*
-* rtw_set_scan_mode -
-* @adapter: pointer to struct adapter structure
-* @scan_mode:
-*
-* Return _SUCCESS or _FAIL
-*/
-int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode)
-{
- if (scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
- return _FAIL;
-
- adapter->mlmepriv.scan_mode = scan_mode;
-
- return _SUCCESS;
-}
-
-/*
-* rtw_set_channel_plan -
-* @adapter: pointer to struct adapter structure
-* @channel_plan:
-*
-* Return _SUCCESS or _FAIL
-*/
-int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan)
-{
- /* handle by cmd_thread to sync with scan operation */
- return rtw_set_chplan_cmd(adapter, channel_plan, 1);
-}
-
-/*
* rtw_set_country -
* @adapter: pointer to struct adapter structure
* @country_code: string of country code
@@ -1133,5 +659,5 @@ int rtw_set_country(struct adapter *adapter, const char *country_code)
else
DBG_88E("%s unknown country_code:%s\n", __func__, country_code);
- return rtw_set_channel_plan(adapter, channel_plan);
+ return rtw_set_chplan_cmd(adapter, channel_plan, 1);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c
index e6fdd32f9a3f..7796287be8f4 100644
--- a/drivers/staging/rtl8188eu/core/rtw_iol.c
+++ b/drivers/staging/rtl8188eu/core/rtw_iol.c
@@ -113,20 +113,6 @@ int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8
return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
}
-int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
-{
- struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
-
- cmd.address = cpu_to_le16(addr);
- cmd.data = cpu_to_le32(value);
-
- if (mask != 0xFFFF) {
- cmd.length = 12;
- cmd.mask = cpu_to_le32(mask);
- }
- return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
-}
-
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
{
struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c
index 87d6f063476b..384be22052e5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_led.c
+++ b/drivers/staging/rtl8188eu/core/rtw_led.c
@@ -88,8 +88,8 @@ void InitLed871x(struct adapter *padapter, struct LED_871x *pLed)
/* */
void DeInitLed871x(struct LED_871x *pLed)
{
- _cancel_workitem_sync(&(pLed->BlinkWorkItem));
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ cancel_work_sync(&(pLed->BlinkWorkItem));
+ del_timer_sync(&(pLed->BlinkTimer));
ResetLedStatus(pLed);
}
@@ -251,11 +251,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
@@ -273,11 +273,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
pLed->bLedLinkBlinkInProgress = true;
@@ -296,15 +296,15 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
if (IS_LED_WPS_BLINKING(pLed))
return;
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
pLed->bLedScanBlinkInProgress = true;
@@ -323,11 +323,11 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
return;
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
pLed->bLedBlinkInProgress = true;
@@ -344,19 +344,19 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
case LED_CTL_START_WPS_BOTTON:
if (!pLed->bLedWPSBlinkInProgress) {
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedScanBlinkInProgress = false;
}
pLed->bLedWPSBlinkInProgress = true;
@@ -370,23 +370,23 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
break;
case LED_CTL_STOP_WPS:
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedScanBlinkInProgress = false;
}
if (pLed->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
else
pLed->bLedWPSBlinkInProgress = true;
pLed->CurrLedState = LED_BLINK_WPS_STOP;
@@ -400,7 +400,7 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
break;
case LED_CTL_STOP_WPS_FAIL:
if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedWPSBlinkInProgress = false;
}
pLed->bLedNoLinkBlinkInProgress = true;
@@ -415,23 +415,23 @@ static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAct
pLed->CurrLedState = RTW_LED_OFF;
pLed->BlinkingLedState = RTW_LED_OFF;
if (pLed->bLedNoLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedNoLinkBlinkInProgress = false;
}
if (pLed->bLedLinkBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedLinkBlinkInProgress = false;
}
if (pLed->bLedBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedBlinkInProgress = false;
}
if (pLed->bLedWPSBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedWPSBlinkInProgress = false;
}
if (pLed->bLedScanBlinkInProgress) {
- _cancel_timer_ex(&(pLed->BlinkTimer));
+ del_timer_sync(&(pLed->BlinkTimer));
pLed->bLedScanBlinkInProgress = false;
}
SwLedOff(padapter, pLed);
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c
index 155282ef78fb..149c271e966d 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c
@@ -30,13 +30,12 @@
#include <wifi.h>
#include <wlan_bssdef.h>
#include <rtw_ioctl_set.h>
-#include <usb_osintf.h>
#include <linux/vmalloc.h>
extern unsigned char MCS_rate_2R[16];
extern unsigned char MCS_rate_1R[16];
-int _rtw_init_mlme_priv(struct adapter *padapter)
+int rtw_init_mlme_priv(struct adapter *padapter)
{
int i;
u8 *pbuf;
@@ -59,7 +58,7 @@ int _rtw_init_mlme_priv(struct adapter *padapter)
set_scanned_network_val(pmlmepriv, 0);
- _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
+ memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
pbuf = vzalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
@@ -72,9 +71,9 @@ int _rtw_init_mlme_priv(struct adapter *padapter)
pnetwork = (struct wlan_network *)pbuf;
for (i = 0; i < MAX_BSS_CNT; i++) {
- _rtw_init_listhead(&(pnetwork->list));
+ INIT_LIST_HEAD(&(pnetwork->list));
- rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
+ list_add_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
pnetwork++;
}
@@ -118,7 +117,7 @@ void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
}
#endif
-void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
+void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
{
rtw_free_mlme_priv_ie_data(pmlmepriv);
@@ -128,40 +127,6 @@ void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
}
}
-int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork)
-{
- if (pnetwork == NULL)
- goto exit;
-
- spin_lock_bh(&queue->lock);
-
- rtw_list_insert_tail(&pnetwork->list, &queue->queue);
-
- spin_unlock_bh(&queue->lock);
-
-exit:
- return _SUCCESS;
-}
-
-struct wlan_network *_rtw_dequeue_network(struct __queue *queue)
-{
- struct wlan_network *pnetwork;
-
- spin_lock_bh(&queue->lock);
-
- if (_rtw_queue_empty(queue)) {
- pnetwork = NULL;
- } else {
- pnetwork = container_of((&queue->queue)->next, struct wlan_network, list);
-
- rtw_list_delete(&(pnetwork->list));
- }
-
- spin_unlock_bh(&queue->lock);
-
- return pnetwork;
-}
-
struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *free_queue) */
{
struct wlan_network *pnetwork;
@@ -170,7 +135,7 @@ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *f
spin_lock_bh(&free_queue->lock);
- if (_rtw_queue_empty(free_queue) == true) {
+ if (list_empty(&free_queue->queue)) {
pnetwork = NULL;
goto exit;
}
@@ -178,7 +143,7 @@ struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv)/* _queue *f
pnetwork = container_of(plist , struct wlan_network, list);
- rtw_list_delete(&pnetwork->list);
+ list_del_init(&pnetwork->list);
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist));
pnetwork->network_type = 0;
@@ -195,7 +160,7 @@ exit:
return pnetwork;
}
-void _rtw_free_network(struct mlme_priv *pmlmepriv , struct wlan_network *pnetwork, u8 isfreeall)
+static void _rtw_free_network(struct mlme_priv *pmlmepriv , struct wlan_network *pnetwork, u8 isfreeall)
{
u32 curr_time, delta_time;
u32 lifetime = SCANQUEUE_LIFETIME;
@@ -216,8 +181,8 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv , struct wlan_network *pnetwo
return;
}
spin_lock_bh(&free_queue->lock);
- rtw_list_delete(&(pnetwork->list));
- rtw_list_insert_tail(&(pnetwork->list), &(free_queue->queue));
+ list_del_init(&(pnetwork->list));
+ list_add_tail(&(pnetwork->list), &(free_queue->queue));
pmlmepriv->num_of_scanned--;
spin_unlock_bh(&free_queue->lock);
}
@@ -230,8 +195,8 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *
return;
if (pnetwork->fixed)
return;
- rtw_list_delete(&(pnetwork->list));
- rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue));
+ list_del_init(&(pnetwork->list));
+ list_add_tail(&(pnetwork->list), get_list_head(free_queue));
pmlmepriv->num_of_scanned--;
}
@@ -240,7 +205,7 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *
Shall be calle under atomic context... to avoid possible racing condition...
*/
-struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
+struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
{
struct list_head *phead, *plist;
struct wlan_network *pnetwork = NULL;
@@ -266,7 +231,7 @@ exit:
}
-void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
+void rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
{
struct list_head *phead, *plist;
struct wlan_network *pnetwork;
@@ -278,7 +243,7 @@ void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall)
phead = get_list_head(scanned_queue);
plist = phead->next;
- while (rtw_end_of_queue_search(phead, plist) == false) {
+ while (phead != plist) {
pnetwork = container_of(plist, struct wlan_network, list);
plist = plist->next;
@@ -332,29 +297,11 @@ u16 rtw_get_capability(struct wlan_bssid_ex *bss)
return le16_to_cpu(val);
}
-u8 *rtw_get_timestampe_from_ie(u8 *ie)
-{
- return ie + 0;
-}
-
u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
{
return ie + 8;
}
-int rtw_init_mlme_priv(struct adapter *padapter)
-{
- int res;
- res = _rtw_init_mlme_priv(padapter);/* (pmlmepriv); */
- return res;
-}
-
-void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
-{
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("rtw_free_mlme_priv\n"));
- _rtw_free_mlme_priv(pmlmepriv);
-}
-
static struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv)
{
return _rtw_alloc_network(pmlmepriv);
@@ -366,24 +313,6 @@ static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
_rtw_free_network_nolock(pmlmepriv, pnetwork);
}
-
-void rtw_free_network_queue(struct adapter *dev, u8 isfreeall)
-{
- _rtw_free_network_queue(dev, isfreeall);
-}
-
-/*
- return the wlan_network with the matching addr
-
- Shall be calle under atomic context... to avoid possible racing condition...
-*/
-struct wlan_network *rtw_find_network(struct __queue *scanned_queue, u8 *addr)
-{
- struct wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
-
- return pnetwork;
-}
-
int rtw_is_same_ibss(struct adapter *adapter, struct wlan_network *pnetwork)
{
int ret = true;
@@ -438,7 +367,7 @@ struct wlan_network *rtw_get_oldest_wlan_network(struct __queue *scanned_queue)
plist = phead->next;
while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
+ if (phead == plist)
break;
pwlan = container_of(plist, struct wlan_network, list);
@@ -522,10 +451,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
phead = get_list_head(queue);
plist = phead->next;
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
+ while (phead != plist) {
pnetwork = container_of(plist, struct wlan_network, list);
if (is_same_network(&(pnetwork->network), target))
@@ -537,8 +463,8 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
}
/* If we didn't find a match, then get a new network slot to initialize
* with this beacon's information */
- if (rtw_end_of_queue_search(phead, plist) == true) {
- if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == true) {
+ if (phead == plist) {
+ if (list_empty(&(pmlmepriv->free_bss_pool.queue))) {
/* If there are no more slots, expire the oldest */
pnetwork = oldest;
@@ -575,7 +501,7 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
/* bss info not receiving from the right channel */
if (pnetwork->network.PhyInfo.SignalQuality == 101)
pnetwork->network.PhyInfo.SignalQuality = 0;
- rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
+ list_add_tail(&(pnetwork->list), &(queue->queue));
}
} else {
/* we have an entry and we are going to update it. But this entry may
@@ -601,9 +527,6 @@ exit:
static void rtw_add_network(struct adapter *adapter,
struct wlan_bssid_ex *pnetwork)
{
-#if defined(CONFIG_88EU_P2P)
- rtw_wlan_bssid_ex_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
-#endif
update_current_network(adapter, pnetwork);
rtw_update_scanned_network(adapter, pnetwork);
}
@@ -728,10 +651,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
- u8 timer_cancelled;
-
- _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
-
+ del_timer_sync(&pmlmepriv->scan_to_timer);
_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
} else {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("nic status=%x, survey done event comes too late!\n", get_fwstate(pmlmepriv)));
@@ -754,7 +674,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("switching to adhoc master\n"));
- _rtw_memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
+ 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);
@@ -798,14 +718,9 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
spin_unlock_bh(&pmlmepriv->lock);
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
- p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
-
rtw_os_xmit_schedule(adapter);
pmlmeext = &adapter->mlmeextpriv;
- if (pmlmeext->sitesurvey_res.bss_cnt == 0)
- rtw_hal_sreset_reset(adapter);
}
void rtw_dummy_event_callback(struct adapter *adapter , u8 *pbuf)
@@ -831,8 +746,8 @@ static void free_scanqueue(struct mlme_priv *pmlmepriv)
while (plist != phead) {
ptemp = plist->next;
- rtw_list_delete(plist);
- rtw_list_insert_tail(plist, &free_queue->queue);
+ list_del_init(plist);
+ list_add_tail(plist, &free_queue->queue);
plist = ptemp;
pmlmepriv->num_of_scanned--;
}
@@ -945,7 +860,6 @@ void rtw_indicate_disconnect(struct adapter *padapter)
rtw_led_control(padapter, LED_CTL_NO_LINK);
rtw_clear_scan_deny(padapter);
}
- p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
}
@@ -1002,11 +916,11 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str
padapter->securitypriv.bgrpkey_handshake = false;
psta->ieee8021x_blocked = true;
psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
- _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
- _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
- _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
- _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
- _rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
+ memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
+ memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
+ memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
+ memset((u8 *)&psta->dot11txpn, 0, sizeof(union pn48));
+ memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48));
}
/*
* Commented by Albert 2012/07/21
@@ -1108,7 +1022,6 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net
void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
{
- u8 timer_cancelled;
struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
struct sta_priv *pstapriv = &adapter->stapriv;
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
@@ -1201,7 +1114,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf)
}
/* s5. Cancle assoc_timer */
- _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
+ del_timer_sync(&pmlmepriv->assoc_timer);
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("Cancle assoc_timer\n"));
@@ -1421,7 +1334,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
memcpy(pdev_network, &tgt_network->network, get_wlan_bssid_ex_sz(&tgt_network->network));
- _rtw_memset(&pdev_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
+ 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);
@@ -1449,8 +1362,9 @@ void rtw_cpwm_event_callback(struct adapter *padapter, u8 *pbuf)
* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
* @adapter: pointer to struct adapter structure
*/
-void _rtw_join_timeout_handler (struct adapter *adapter)
+void _rtw_join_timeout_handler (void *function_context)
{
+ struct adapter *adapter = (struct adapter *)function_context;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
int do_join_r;
@@ -1490,8 +1404,9 @@ void _rtw_join_timeout_handler (struct adapter *adapter)
* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
* @adapter: pointer to struct adapter structure
*/
-void rtw_scan_timeout_handler (struct adapter *adapter)
+void rtw_scan_timeout_handler (void *function_context)
{
+ struct adapter *adapter = (struct adapter *)function_context;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
DBG_88E(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
@@ -1516,48 +1431,27 @@ static void rtw_auto_scan_handler(struct adapter *padapter)
}
}
-void rtw_dynamic_check_timer_handlder(struct adapter *adapter)
+void rtw_dynamic_check_timer_handlder(void *function_context)
{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct adapter *adapter = (struct adapter *)function_context;
struct registry_priv *pregistrypriv = &adapter->registrypriv;
if (!adapter)
- return;
+ goto exit;
if (!adapter->hw_init_completed)
- return;
+ goto exit;
if ((adapter->bDriverStopped) || (adapter->bSurpriseRemoved))
- return;
+ goto exit;
if (adapter->net_closed)
- return;
+ goto exit;
rtw_dynamic_chk_wk_cmd(adapter);
if (pregistrypriv->wifi_spec == 1) {
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-#endif
- {
- /* auto site survey */
- rtw_auto_scan_handler(adapter);
- }
- }
-
- rcu_read_lock();
-
- if (rcu_dereference(adapter->pnetdev->rx_handler_data) &&
- (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == true)) {
- /* expire NAT2.5 entry */
- nat25_db_expire(adapter);
-
- if (adapter->pppoe_connection_in_progress > 0)
- adapter->pppoe_connection_in_progress--;
-
- /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
- if (adapter->pppoe_connection_in_progress > 0)
- adapter->pppoe_connection_in_progress--;
+ /* auto site survey */
+ rtw_auto_scan_handler(adapter);
}
-
- rcu_read_unlock();
+exit:
+ _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
}
#define RTW_SCAN_RESULT_EXPIRE 2000
@@ -1635,7 +1529,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
phead = get_list_head(queue);
adapter = (struct adapter *)pmlmepriv->nic_hdl;
pmlmepriv->pscanned = phead->next;
- while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
+ while (phead != pmlmepriv->pscanned) {
pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
if (pnetwork == NULL) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("%s return _FAIL:(pnetwork==NULL)\n", __func__));
@@ -1689,26 +1583,26 @@ int rtw_set_auth(struct adapter *adapter, struct security_priv *psecuritypriv)
struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
int res = _SUCCESS;
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd == NULL) {
res = _FAIL; /* try again */
goto exit;
}
- psetauthparm = (struct setauth_parm *)rtw_zmalloc(sizeof(struct setauth_parm));
+ psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
if (psetauthparm == NULL) {
kfree(pcmd);
res = _FAIL;
goto exit;
}
- _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
+ memset(psetauthparm, 0, sizeof(struct setauth_parm));
psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
pcmd->cmdcode = _SetAuth_CMD_;
pcmd->parmbuf = (unsigned char *)psetauthparm;
pcmd->cmdsz = (sizeof(struct setauth_parm));
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- _rtw_init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
("after enqueue set_auth_cmd, auth_mode=%x\n",
psecuritypriv->dot11AuthAlgrthm));
@@ -1726,17 +1620,17 @@ int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, in
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
int res = _SUCCESS;
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd == NULL)
return _FAIL; /* try again */
- psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
+ psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
if (psetkeyparm == NULL) {
res = _FAIL;
goto err_free_cmd;
}
- _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
+ memset(psetkeyparm, 0, sizeof(struct setkey_parm));
if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
@@ -1789,7 +1683,7 @@ int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, in
pcmd->cmdsz = (sizeof(struct setkey_parm));
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- _rtw_init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
res = rtw_enqueue_cmd(pcmdpriv, pcmd);
return res;
@@ -2070,7 +1964,7 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
out_len = *pout_len;
- _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
+ memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |
IEEE80211_HT_CAP_SGI_20 |
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index f5b49f351a6a..5ba5099ec20d 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -256,7 +256,7 @@ static void init_mlme_ext_priv_value(struct adapter *padapter)
pmlmeinfo->enc_algo = _NO_PRIVACY_;
pmlmeinfo->authModeToggle = 0;
- _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
+ memset(pmlmeinfo->chg_txt, 0, 128);
pmlmeinfo->slotTime = SHORT_SLOT_TIME;
pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
@@ -328,7 +328,7 @@ static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_c
u8 b2_4GBand = false;
u8 Index2G = 0;
- _rtw_memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
+ memset(channel_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
DBG_88E("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
@@ -408,9 +408,8 @@ void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
return;
if (padapter->bDriverStopped) {
- _cancel_timer_ex(&pmlmeext->survey_timer);
- _cancel_timer_ex(&pmlmeext->link_timer);
- /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
+ del_timer_sync(&pmlmeext->survey_timer);
+ del_timer_sync(&pmlmeext->link_timer);
}
}
@@ -509,23 +508,6 @@ void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
#endif
}
-#ifdef CONFIG_88EU_P2P
-static u32 p2p_listen_state_process(struct adapter *padapter, unsigned char *da)
-{
- bool response = true;
-
- /* do nothing if the device name is empty */
- if (!padapter->wdinfo.device_name_len)
- response = false;
-
- if (response)
- issue_probersp_p2p(padapter, da);
-
- return _SUCCESS;
-}
-#endif /* CONFIG_88EU_P2P */
-
-
/****************************************************************************
Following are the callback functions for each subtype of the management frames
@@ -544,43 +526,6 @@ unsigned int OnProbeReq(struct adapter *padapter, struct recv_frame *precv_frame
uint len = precv_frame->len;
u8 is_valid_p2p_probereq = false;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 wifi_test_chk_rate = 1;
-
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
- !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) {
- /* mcs_rate = 0 -> CCK 1M rate */
- /* mcs_rate = 1 -> CCK 2M rate */
- /* mcs_rate = 2 -> CCK 5.5M rate */
- /* mcs_rate = 3 -> CCK 11M rate */
- /* In the P2P mode, the driver should not support the CCK rate */
-
- /* Commented by Kurt 2012/10/16 */
- /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
- if (wifi_test_chk_rate == 1) {
- is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
- if (is_valid_p2p_probereq) {
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
- /* FIXME */
- report_survey_event(padapter, precv_frame);
- p2p_listen_state_process(padapter, get_sa(pframe));
-
- return _SUCCESS;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- goto _continue;
- }
- }
- }
-
-_continue:
-#endif /* CONFIG_88EU_P2P */
-
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
return _SUCCESS;
@@ -612,48 +557,6 @@ _issue_probersp:
unsigned int OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 *pframe = precv_frame->rx_data;
-#endif
-
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
- if (pwdinfo->tx_prov_disc_info.benable) {
- if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- pwdinfo->tx_prov_disc_info.benable = false;
- issue_p2p_provision_request(padapter,
- pwdinfo->tx_prov_disc_info.ssid.Ssid,
- pwdinfo->tx_prov_disc_info.ssid.SsidLength,
- pwdinfo->tx_prov_disc_info.peerDevAddr);
- } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- pwdinfo->tx_prov_disc_info.benable = false;
- issue_p2p_provision_request(padapter, NULL, 0,
- pwdinfo->tx_prov_disc_info.peerDevAddr);
- }
- }
- }
- return _SUCCESS;
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
- if (pwdinfo->nego_req_info.benable) {
- DBG_88E("[%s] P2P State is GONEGO ING!\n", __func__);
- if (!memcmp(pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
- pwdinfo->nego_req_info.benable = false;
- issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
- }
- }
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
- if (pwdinfo->invitereq_info.benable) {
- DBG_88E("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__);
- if (!memcmp(pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN)) {
- pwdinfo->invitereq_info.benable = false;
- issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
- }
- }
- }
-#endif
-
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
report_survey_event(padapter, precv_frame);
@@ -718,7 +621,6 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
/* todo: the timer is used instead of the number of the beacon received */
if ((sta_rx_pkts(psta) & 0xf) == 0)
update_beacon_info(padapter, pframe, len, psta);
- process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
}
} else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
@@ -817,8 +719,8 @@ unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame)
pstat->auth_seq = 0;
} else {
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!rtw_is_list_empty(&pstat->asoc_list)) {
- rtw_list_delete(&pstat->asoc_list);
+ if (!list_empty(&pstat->asoc_list)) {
+ list_del_init(&pstat->asoc_list);
pstapriv->asoc_list_cnt--;
}
spin_unlock_bh(&pstapriv->asoc_list_lock);
@@ -829,8 +731,8 @@ unsigned int OnAuth(struct adapter *padapter, struct recv_frame *precv_frame)
}
spin_lock_bh(&pstapriv->auth_list_lock);
- if (rtw_is_list_empty(&pstat->auth_list)) {
- rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
+ if (list_empty(&pstat->auth_list)) {
+ list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
pstapriv->auth_list_cnt++;
}
spin_unlock_bh(&pstapriv->auth_list_lock);
@@ -914,7 +816,7 @@ auth_fail:
rtw_free_stainfo(padapter , pstat);
pstat = &stat;
- _rtw_memset((char *)pstat, '\0', sizeof(stat));
+ memset((char *)pstat, '\0', sizeof(stat));
pstat->auth_seq = 2;
memcpy(pstat->hwaddr, sa, 6);
@@ -1022,12 +924,6 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
struct sta_priv *pstapriv = &padapter->stapriv;
u8 *pframe = precv_frame->rx_data;
uint pkt_len = precv_frame->len;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 p2p_status_code = P2P_STATUS_SUCCESS;
- u8 *p2pie;
- u32 p2pielen = 0;
-#endif /* CONFIG_88EU_P2P */
if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
return _FAIL;
@@ -1054,7 +950,7 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
goto asoc_class2_error;
}
- capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
+ capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN);
left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
@@ -1146,7 +1042,7 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
pstat->wpa2_group_cipher = 0;
pstat->wpa_pairwise_cipher = 0;
pstat->wpa2_pairwise_cipher = 0;
- _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
+ memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
int group_cipher = 0, pairwise_cipher = 0;
@@ -1314,7 +1210,7 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
}
/* save HT capabilities in the sta object */
- _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
+ memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
pstat->flags |= WLAN_STA_HT;
@@ -1357,23 +1253,6 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
if (status != _STATS_SUCCESSFUL_)
goto OnAssocReqFail;
-#ifdef CONFIG_88EU_P2P
- pstat->is_p2p_device = false;
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen);
- if (p2pie) {
- pstat->is_p2p_device = true;
- p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
- if (p2p_status_code > 0) {
- pstat->p2p_status_code = p2p_status_code;
- status = _STATS_CAP_FAIL_;
- goto OnAssocReqFail;
- }
- }
- }
- pstat->p2p_status_code = p2p_status_code;
-#endif /* CONFIG_88EU_P2P */
-
/* TODO: identify_proprietary_vendor_ie(); */
/* Realtek proprietary IE */
/* identify if this is Broadcom sta */
@@ -1407,16 +1286,16 @@ unsigned int OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame
pstat->state |= WIFI_FW_ASSOC_SUCCESS;
spin_lock_bh(&pstapriv->auth_list_lock);
- if (!rtw_is_list_empty(&pstat->auth_list)) {
- rtw_list_delete(&pstat->auth_list);
+ if (!list_empty(&pstat->auth_list)) {
+ list_del_init(&pstat->auth_list);
pstapriv->auth_list_cnt--;
}
spin_unlock_bh(&pstapriv->auth_list_lock);
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (rtw_is_list_empty(&pstat->asoc_list)) {
+ if (list_empty(&pstat->asoc_list)) {
pstat->expire_to = pstapriv->expire_to;
- rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
+ list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
pstapriv->asoc_list_cnt++;
}
spin_unlock_bh(&pstapriv->asoc_list_lock);
@@ -1495,7 +1374,7 @@ unsigned int OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
return _SUCCESS;
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
/* status */
status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2));
@@ -1567,22 +1446,12 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
u8 *pframe = precv_frame->rx_data;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
/* check A3 */
if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
ETH_ALEN))
return _SUCCESS;
-#ifdef CONFIG_88EU_P2P
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
- _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
- _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
- }
-#endif /* CONFIG_88EU_P2P */
-
reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
DBG_88E("%s Reason code(%d)\n", __func__, reason);
@@ -1600,8 +1469,8 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
u8 updated = 0;
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!rtw_is_list_empty(&psta->asoc_list)) {
- rtw_list_delete(&psta->asoc_list);
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta(padapter, psta, false, reason);
}
@@ -1631,22 +1500,12 @@ unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
u8 *pframe = precv_frame->rx_data;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
/* check A3 */
if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
ETH_ALEN))
return _SUCCESS;
-#ifdef CONFIG_88EU_P2P
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
- _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
- _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
- }
-#endif /* CONFIG_88EU_P2P */
-
reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
DBG_88E("%s Reason code(%d)\n", __func__, reason);
@@ -1664,8 +1523,8 @@ unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame
u8 updated = 0;
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!rtw_is_list_empty(&psta->asoc_list)) {
- rtw_list_delete(&psta->asoc_list);
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta(padapter, psta, false, reason);
}
@@ -1789,7 +1648,7 @@ unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_fr
issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */
break;
case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
- status = RTW_GET_LE16(&frame_body[3]);
+ status = get_unaligned_le16(&frame_body[3]);
tid = ((frame_body[5] >> 2) & 0x7);
if (status == 0) { /* successful */
DBG_88E("agg_enable for TID=%d\n", tid);
@@ -1803,7 +1662,7 @@ unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_fr
if ((frame_body[3] & BIT(3)) == 0) {
psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
- reason_code = RTW_GET_LE16(&frame_body[4]);
+ reason_code = get_unaligned_le16(&frame_body[4]);
} else if ((frame_body[3] & BIT(3)) == BIT(3)) {
tid = (frame_body[3] >> 4) & 0x0F;
preorder_ctrl = &psta->recvreorder_ctrl[tid];
@@ -1820,2043 +1679,6 @@ unsigned int OnAction_back(struct adapter *padapter, struct recv_frame *precv_fr
return _SUCCESS;
}
-#ifdef CONFIG_88EU_P2P
-
-static int get_reg_classes_full_count(struct p2p_channels *channel_list)
-{
- int cnt = 0;
- int i;
-
- for (i = 0; i < channel_list->reg_classes; i++) {
- cnt += channel_list->reg_class[i].channels;
- }
-
- return cnt;
-}
-
-void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_REQ;
- u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
- u8 wpsielen = 0, p2pielen = 0;
- u16 len_channellist_attr = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- DBG_88E("[%s] In\n", __func__);
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
- pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
-
-
-
- /* WPS Section */
- wpsielen = 0;
- /* WPS OUI */
- *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Device Password ID */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
-
- if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
- else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
- else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
-
- wpsielen += 2;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110306 */
- /* According to the P2P Specification, the group negotiation request frame should contain 9 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Group Owner Intent */
- /* 3. Configuration Timeout */
- /* 4. Listen Channel */
- /* 5. Extended Listen Timing */
- /* 6. Intended P2P Interface Address */
- /* 7. Channel List */
- /* 8. P2P Device Info */
- /* 9. Operating Channel */
-
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
- else
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
-
- /* Group Owner Intent */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- /* Todo the tie breaker bit. */
- p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
-
-
- /* Listen Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
-
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
-
- /* Intended P2P Interface Address */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3
- + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
- + get_reg_classes_full_count(&pmlmeext->channel_list);
-
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
-
- {
- int i, j;
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
- }
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
-
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_RESP;
- u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
- u8 p2pielen = 0;
- uint wpsielen = 0;
- u16 wps_devicepassword_id = 0x0000;
- __be16 be_tmp;
- uint wps_devicepassword_id_len = 0;
- u16 len_channellist_attr = 0;
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- DBG_88E("[%s] In, result=%d\n", __func__, result);
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
- pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
-
- /* Commented by Albert 20110328 */
- /* Try to get the device password ID from the WPS IE of group negotiation request frame */
- /* WiFi Direct test plan 5.1.15 */
- rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
- rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
- wps_devicepassword_id = be16_to_cpu(be_tmp);
-
- _rtw_memset(wpsie, 0x00, 255);
- wpsielen = 0;
-
- /* WPS Section */
- wpsielen = 0;
- /* WPS OUI */
- *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Device Password ID */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
- else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
- else
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
- wpsielen += 2;
-
- /* Commented by Kurt 20120113 */
- /* If some device wants to do p2p handshake without sending prov_disc_req */
- /* We have to get peer_req_cm from here. */
- if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
- else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
- else
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
- }
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20100908 */
- /* According to the P2P Specification, the group negotiation response frame should contain 9 P2P attributes */
- /* 1. Status */
- /* 2. P2P Capability */
- /* 3. Group Owner Intent */
- /* 4. Configuration Timeout */
- /* 5. Operating Channel */
- /* 6. Intended P2P Interface Address */
- /* 7. Channel List */
- /* 8. Device Info */
- /* 9. Group ID (Only GO) */
-
-
- /* ToDo: */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = result;
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- /* Commented by Albert 2011/03/08 */
- /* According to the P2P specification */
- /* if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */
- p2pie[p2pielen++] = 0;
- } else {
- /* Be group owner or meet the error case */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
- }
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported) {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
- } else {
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
- }
-
- /* Group Owner Intent */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- if (pwdinfo->peer_intent & 0x01) {
- /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
- p2pie[p2pielen++] = (pwdinfo->intent << 1);
- } else {
- /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
- p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
- }
-
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
-
- /* Intended P2P Interface Address */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3
- + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
- + get_reg_classes_full_count(&pmlmeext->channel_list);
-
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
-
- {
- int i, j;
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
- }
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
-
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Group ID Attribute */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* p2P Device Address */
- memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
- p2pielen += pwdinfo->nego_ssidlen;
- }
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
- return;
-}
-
-static void issue_p2p_GO_confirm(struct adapter *padapter, u8 *raddr, u8 result)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_NEGO_CONF;
- u8 p2pie[255] = { 0x00 };
- u8 p2pielen = 0;
-
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- DBG_88E("[%s] In\n", __func__);
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
-
-
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110306 */
- /* According to the P2P Specification, the group negotiation request frame should contain 5 P2P attributes */
- /* 1. Status */
- /* 2. P2P Capability */
- /* 3. Operating Channel */
- /* 4. Channel List */
- /* 5. Group ID (if this WiFi is GO) */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = result;
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
- else
- p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
- p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
- } else {
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
- }
-
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(pwdinfo->channel_list_attr_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len);
- p2pielen += pwdinfo->channel_list_attr_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Group ID Attribute */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* p2P Device Address */
- memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
- p2pielen += pwdinfo->nego_ssidlen;
- }
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
- pattrib->last_txcmdsz = pattrib->pktlen;
- dump_mgntframe(padapter, pmgntframe);
- return;
-}
-
-void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_INVIT_REQ;
- u8 p2pie[255] = { 0x00 };
- u8 p2pielen = 0;
- u8 dialogToken = 3;
- u16 len_channellist_attr = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101011 */
- /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
- /* 1. Configuration Timeout */
- /* 2. Invitation Flags */
- /* 3. Operating Channel (Only GO) */
- /* 4. P2P Group BSSID (Should be included if I am the GO) */
- /* 5. Channel List */
- /* 6. P2P Group ID */
- /* 7. P2P Device Info */
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
-
- /* Invitation Flags */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
-
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51;
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
-
- if (!memcmp(myid(&padapter->eeprompriv),
- pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
- /* P2P Group BSSID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
- p2pielen += ETH_ALEN;
- }
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3
- + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
- + get_reg_classes_full_count(&pmlmeext->channel_list);
-
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
-
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
- {
- int i, j;
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
- }
-
-
- /* P2P Group ID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* SSID */
- memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
- p2pielen += pwdinfo->invitereq_info.ssidlen;
-
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_INVIT_RESP;
- u8 p2pie[255] = { 0x00 };
- u8 p2pielen = 0;
- u16 len_channellist_attr = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
- /* P2P IE Section. */
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101005 */
- /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
- /* 1. Status */
- /* 2. Configuration Timeout */
- /* 3. Operating Channel (Only GO) */
- /* 4. P2P Group BSSID (Only GO) */
- /* 5. Channel List */
-
- /* P2P Status */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_STATUS;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
- p2pielen += 2;
-
- /* Value: */
- /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
- /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
- /* DMP had to compare the MAC address to find out the profile. */
- /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
- /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
- /* to NB to rebuild the persistent group. */
- p2pie[p2pielen++] = status_code;
-
- /* Configuration Timeout */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
- p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
-
- if (status_code == P2P_STATUS_SUCCESS) {
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
- /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
- /* First one is operating channel attribute. */
- /* Second one is P2P Group BSSID attribute. */
-
- /* Operating Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
-
-
- /* P2P Group BSSID */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address for GO */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
- }
-
- /* Channel List */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
-
- /* Length: */
- /* Country String(3) */
- /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
- /* + number of channels in all classes */
- len_channellist_attr = 3
- + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
- + get_reg_classes_full_count(&pmlmeext->channel_list);
-
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Channel Entry List */
- {
- int i, j;
- for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
- /* Operating Class */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
-
- /* Number of Channels */
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
-
- /* Channel List */
- for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
- p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
- }
- }
- }
- }
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
-{
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u8 dialogToken = 1;
- u8 oui_subtype = P2P_PROVISION_DISC_REQ;
- u8 wpsie[100] = { 0x00 };
- u8 wpsielen = 0;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u32 p2pielen = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- DBG_88E("[%s] In\n", __func__);
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
- p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
-
- pframe += p2pielen;
- pattrib->pktlen += p2pielen;
-
- wpsielen = 0;
- /* WPS OUI */
- *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* Config Method */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
- wpsielen += 2;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-static u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
-{
- u8 i, match_result = 0;
-
- DBG_88E("[%s] peermac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
- peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
-
- for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
- DBG_88E("[%s] profileinfo_mac=%.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
- profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
- if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
- match_result = 1;
- DBG_88E("[%s] Match!\n", __func__);
- break;
- }
- }
- return match_result;
-}
-
-void issue_probersp_p2p(struct adapter *padapter, unsigned char *da)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- unsigned char *mac;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- u16 beacon_interval = 100;
- u16 capInfo = 0;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 wpsie[255] = { 0x00 };
- u32 wpsielen = 0, p2pielen = 0;
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- mac = myid(&(padapter->eeprompriv));
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-
- /* Use the device address for BSSID field. */
- memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(fctrl, WIFI_PROBERSP);
-
- pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = pattrib->hdrlen;
- pframe += pattrib->hdrlen;
-
- /* timestamp will be inserted by hardware */
- pframe += 8;
- pattrib->pktlen += 8;
-
- /* beacon interval: 2 bytes */
- memcpy(pframe, (unsigned char *)&beacon_interval, 2);
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* capability info: 2 bytes */
- /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
- capInfo |= cap_ShortPremble;
- capInfo |= cap_ShortSlot;
-
- memcpy(pframe, (unsigned char *)&capInfo, 2);
- pframe += 2;
- pattrib->pktlen += 2;
-
-
- /* SSID */
- pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
-
- /* supported rates... */
- /* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
-
- /* DS parameter set */
- pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
-
- /* Todo: WPS IE */
- /* Noted by Albert 20100907 */
- /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
-
- wpsielen = 0;
- /* WPS OUI */
- *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- /* WiFi Simple Config State */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
-
- /* Response Type */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
-
- /* UUID-E */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
- wpsielen += 0x10;
-
- /* Manufacturer */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "Realtek", 7);
- wpsielen += 7;
-
- /* Model Name */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "8188EU", 6);
- wpsielen += 6;
-
- /* Model Number */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = 0x31; /* character 1 */
-
- /* Serial Number */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
- wpsielen += ETH_ALEN;
-
- /* Primary Device Type */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
- wpsielen += 2;
-
- /* Value: */
- /* Category ID */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- wpsielen += 2;
-
- /* OUI */
- *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- wpsielen += 2;
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
- wpsielen += 2;
-
- /* Value: */
- if (pwdinfo->device_name_len) {
- memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
- wpsielen += pwdinfo->device_name_len;
- }
-
- /* Config Method */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
- wpsielen += 2;
-
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
-
- p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
- pframe += p2pielen;
- pattrib->pktlen += p2pielen;
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-static int _issue_probereq_p2p(struct adapter *padapter, u8 *da, int wait_ack)
-{
- int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- unsigned char *mac;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
- u16 wpsielen = 0, p2pielen = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- goto exit;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- mac = myid(&(padapter->eeprompriv));
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- if (da) {
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr3, da, ETH_ALEN);
- } else {
- if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
- /* This two flags will be set when this is only the P2P client mode. */
- memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
- } else {
- /* broadcast probe request frame */
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
- }
- }
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_PROBEREQ);
-
- pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
- pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
- else
- pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
-
- /* Use the OFDM rate in the P2P probe request frame. (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
-
-
- /* WPS IE */
- /* Noted by Albert 20110221 */
- /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
-
- wpsielen = 0;
- /* WPS OUI */
- *(__be32 *)(wpsie) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* WPS version */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
- wpsielen += 2;
-
- /* Value: */
- wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
-
- if (pmlmepriv->wps_probe_req_ie == NULL) {
- /* UUID-E */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
- wpsielen += 0x10;
-
- /* Config Method */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
- wpsielen += 2;
- }
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
- wpsielen += 2;
-
- /* Value: */
- memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
- wpsielen += pwdinfo->device_name_len;
-
- /* Primary Device Type */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
- wpsielen += 2;
-
- /* Value: */
- /* Category ID */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
- wpsielen += 2;
-
- /* OUI */
- *(__be32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
- wpsielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
- wpsielen += 2;
-
- /* Device Password ID */
- /* Type: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
- wpsielen += 2;
-
- /* Length: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
- wpsielen += 2;
-
- /* Value: */
- *(__be16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */
- wpsielen += 2;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110221 */
- /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
- /* 1. P2P Capability */
- /* 2. P2P Device ID if this probe request wants to find the specific P2P device */
- /* 3. Listen Channel */
- /* 4. Extended Listen Timing */
- /* 5. Operating Channel if this WiFi is working as the group owner now */
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
- /* Listen Channel */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */
-
-
- /* Extended Listen Timing */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Operating Channel (if this WiFi is working as the group owner now) */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
- p2pielen += 2;
-
- /* Value: */
- /* Country String */
- p2pie[p2pielen++] = 'X';
- p2pie[p2pielen++] = 'X';
-
- /* The third byte should be set to 0x04. */
- /* Described in the "Operating Channel Attribute" section. */
- p2pie[p2pielen++] = 0x04;
-
- /* Operating Class */
- p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
-
- /* Channel Number */
- p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
- }
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
-
- if (pmlmepriv->wps_probe_req_ie != NULL) {
- /* WPS IE */
- memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
- pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
- pframe += pmlmepriv->wps_probe_req_ie_len;
- }
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
-
- if (wait_ack) {
- ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
- } else {
- dump_mgntframe(padapter, pmgntframe);
- ret = _SUCCESS;
- }
-
-exit:
- return ret;
-}
-
-inline void issue_probereq_p2p(struct adapter *adapter, u8 *da)
-{
- _issue_probereq_p2p(adapter, da, false);
-}
-
-int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt, int wait_ms)
-{
- int ret;
- int i = 0;
- u32 start = jiffies;
-
- do {
- ret = _issue_probereq_p2p(adapter, da, wait_ms > 0 ? true : false);
-
- i++;
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
- break;
-
- if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
- msleep(wait_ms);
- } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
-
- if (ret != _FAIL) {
- ret = _SUCCESS;
- goto exit;
- }
-
- if (try_cnt && wait_ms) {
- if (da)
- DBG_88E(FUNC_ADPT_FMT" to %pM, ch:%u%s, %d/%d in %u ms\n",
- FUNC_ADPT_ARG(adapter), da, rtw_get_oper_ch(adapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
- else
- DBG_88E(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
- FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
- ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
- }
-exit:
- return ret;
-}
-
-#endif /* CONFIG_88EU_P2P */
-
static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
{
struct adapter *adapter = recv_frame->adapter;
@@ -3894,16 +1716,6 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
u8 *pframe = precv_frame->rx_data;
u8 *frame_body;
u8 dialogToken = 0;
-#ifdef CONFIG_88EU_P2P
- struct adapter *padapter = precv_frame->adapter;
- uint len = precv_frame->len;
- u8 *p2p_ie;
- u32 p2p_ielen;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 result = P2P_STATUS_SUCCESS;
- u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-#endif /* CONFIG_88EU_P2P */
-
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
dialogToken = frame_body[7];
@@ -3911,272 +1723,6 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
return _FAIL;
-#ifdef CONFIG_88EU_P2P
- _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
- /* Do nothing if the driver doesn't enable the P2P function. */
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
- return _SUCCESS;
-
- len -= sizeof(struct rtw_ieee80211_hdr_3addr);
-
- switch (frame_body[6]) { /* OUI Subtype */
- case P2P_GO_NEGO_REQ:
- DBG_88E("[%s] Got GO Nego Req Frame\n", __func__);
- _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
- /* Commented by Albert 20110526 */
- /* In this case, this means the previous nego fail doesn't be reset yet. */
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- /* Restore the previous p2p state */
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- DBG_88E("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo));
- }
-
- /* Commented by Kurt 20110902 */
- /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
- /* Commented by Kurt 20120113 */
- /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
- if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr,
- ETH_ALEN))
- memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
-
- result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
- issue_p2p_GO_response(padapter, GetAddr2Ptr(pframe), frame_body, len, result);
-
- /* Commented by Albert 20110718 */
- /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
- _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
- break;
- case P2P_GO_NEGO_RESP:
- DBG_88E("[%s] Got GO Nego Resp Frame\n", __func__);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
- /* Commented by Albert 20110425 */
- /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- pwdinfo->nego_req_info.benable = false;
- result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
- issue_p2p_GO_confirm(pwdinfo->padapter, GetAddr2Ptr(pframe), result);
- if (P2P_STATUS_SUCCESS == result) {
- if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
- pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
- pwdinfo->p2p_info.scan_op_ch_only = 1;
- _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
- }
- }
- /* Reset the dialog token for group negotiation frames. */
- pwdinfo->negotiation_dialog_token = 1;
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
- _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
- } else {
- DBG_88E("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__);
- }
- break;
- case P2P_GO_NEGO_CONF:
- DBG_88E("[%s] Got GO Nego Confirm Frame\n", __func__);
- result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
- if (P2P_STATUS_SUCCESS == result) {
- if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
- pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
- pwdinfo->p2p_info.scan_op_ch_only = 1;
- _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
- }
- }
- break;
- case P2P_INVIT_REQ:
- /* Added by Albert 2010/10/05 */
- /* Received the P2P Invite Request frame. */
-
- DBG_88E("[%s] Got invite request frame!\n", __func__);
- p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
- if (p2p_ie) {
- /* Parse the necessary information from the P2P Invitation Request frame. */
- /* For example: The MAC address of sending this P2P Invitation Request frame. */
- u32 attr_contentlen = 0;
- u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- struct group_id_info group_id;
- u8 invitation_flag = 0;
-
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
- if (attr_contentlen) {
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
- /* Commented by Albert 20120510 */
- /* Copy to the pwdinfo->p2p_peer_interface_addr. */
- /* So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */
- /* #> iwpriv wlan0 p2p_get peer_ifa */
- /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
-
- if (attr_contentlen) {
- DBG_88E("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
- pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
- pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
- pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
- }
-
- if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
- /* Re-invoke the persistent group. */
-
- _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
- if (attr_contentlen) {
- if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
- /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- status_code = P2P_STATUS_SUCCESS;
- } else {
- /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
- if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
- u8 operatingch_info[5] = { 0x00 };
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
- if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4])) {
- /* The operating channel is acceptable for this device. */
- pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
- _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- status_code = P2P_STATUS_SUCCESS;
- } else {
- /* The operating channel isn't supported by this device. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
- _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
- }
- } else {
- /* Commented by Albert 20121130 */
- /* Intel will use the different P2P IE to store the operating channel information */
- /* Workaround for Intel WiDi 3.5 */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- status_code = P2P_STATUS_SUCCESS;
- }
- } else {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
- status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
- }
- }
- } else {
- DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- } else {
- /* Received the invitation to join a P2P group. */
-
- _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *)&group_id, &attr_contentlen);
- if (attr_contentlen) {
- if (!memcmp(group_id.go_device_addr, myid(&padapter->eeprompriv), ETH_ALEN)) {
- /* In this case, the GO can't be myself. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- } else {
- /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
- /* Commented by Albert 2012/06/28 */
- /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
- /* The peer device address should be the destination address for the provisioning discovery request. */
- /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
- /* The peer interface address should be the address for WPS mac address */
- memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
- status_code = P2P_STATUS_SUCCESS;
- }
- } else {
- DBG_88E("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- }
- } else {
- DBG_88E("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__);
- status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
-
- DBG_88E("[%s] status_code = %d\n", __func__, status_code);
-
- pwdinfo->inviteresp_info.token = frame_body[7];
- issue_p2p_invitation_response(padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
- }
- break;
- case P2P_INVIT_RESP: {
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
-
- DBG_88E("[%s] Got invite response frame!\n", __func__);
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
- if (p2p_ie) {
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
-
- if (attr_contentlen == 1) {
- DBG_88E("[%s] Status = %d\n", __func__, attr_content);
- pwdinfo->invitereq_info.benable = false;
-
- if (attr_content == P2P_STATUS_SUCCESS) {
- if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv), ETH_ALEN)) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
- }
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
- _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
- break;
- }
- case P2P_DEVDISC_REQ:
- process_p2p_devdisc_req(pwdinfo, pframe, len);
- break;
- case P2P_DEVDISC_RESP:
- process_p2p_devdisc_resp(pwdinfo, pframe, len);
- break;
- case P2P_PROVISION_DISC_REQ:
- DBG_88E("[%s] Got Provisioning Discovery Request Frame\n", __func__);
- process_p2p_provdisc_req(pwdinfo, pframe, len);
- memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
-
- /* 20110902 Kurt */
- /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
- _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
- break;
- case P2P_PROVISION_DISC_RESP:
- /* Commented by Albert 20110707 */
- /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
- DBG_88E("[%s] Got Provisioning Discovery Response Frame\n", __func__);
- /* Commented by Albert 20110426 */
- /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
- process_p2p_provdisc_resp(pwdinfo, pframe);
- _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
- break;
- }
-#endif /* CONFIG_88EU_P2P */
-
return _SUCCESS;
}
@@ -4251,46 +1797,6 @@ unsigned int OnAction_wmm(struct adapter *padapter, struct recv_frame *precv_fra
unsigned int OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame)
{
-#ifdef CONFIG_88EU_P2P
- u8 *frame_body;
- u8 category, OUI_Subtype;
- u8 *pframe = precv_frame->rx_data;
- uint len = precv_frame->len;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
-
- DBG_88E("%s\n", __func__);
-
- /* check RA matches or not */
- if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
- return _SUCCESS;
-
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
-
- category = frame_body[0];
- if (category != RTW_WLAN_CATEGORY_P2P)
- return _SUCCESS;
-
- if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI)
- return _SUCCESS;
-
- len -= sizeof(struct rtw_ieee80211_hdr_3addr);
- OUI_Subtype = frame_body[5];
-
- switch (OUI_Subtype) {
- case P2P_NOTICE_OF_ABSENCE:
- break;
- case P2P_PRESENCE_REQUEST:
- process_p2p_presence_req(pwdinfo, pframe, len);
- break;
- case P2P_PRESENCE_RESPONSE:
- break;
- case P2P_GO_DISC_REQUEST:
- break;
- default:
- break;
- }
-#endif /* CONFIG_88EU_P2P */
return _SUCCESS;
}
@@ -4361,7 +1867,7 @@ void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattri
{
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- _rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
+ memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
pattrib->hdrlen = 24;
pattrib->nr_frags = 1;
@@ -4464,7 +1970,7 @@ static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
break;
}
case 2:
- _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
+ memset(&ssid_ie[2], 0, ssid_len_ori);
break;
default:
break;
@@ -4488,9 +1994,6 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL) {
@@ -4506,7 +2009,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
update_mgntframe_attrib(padapter, pattrib);
pattrib->qsel = 0x10;
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -4527,108 +2030,26 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
-#ifdef CONFIG_88EU_P2P
- /* for P2P : Primary Device Type & Device Name */
- u32 wpsielen = 0, insert_len = 0;
- u8 *wpsie = NULL;
- wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
- uint wps_offset, remainder_ielen;
- u8 *premainder_ie, *pframe_wscie;
-
- wps_offset = (uint)(wpsie - cur_network->IEs);
- premainder_ie = wpsie + wpsielen;
- remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
- pframe_wscie = pframe + wps_offset;
- memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
- pframe += (wps_offset + wpsielen);
- pattrib->pktlen += (wps_offset + wpsielen);
-
- /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
- /* Primary Device Type */
- /* Type: */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
- insert_len += 2;
-
- /* Length: */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
- insert_len += 2;
-
- /* Value: */
- /* Category ID */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- insert_len += 2;
-
- /* OUI */
- *(__be32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
- insert_len += 4;
-
- /* Sub Category ID */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- insert_len += 2;
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- insert_len += 2;
-
- /* Length: */
- *(__be16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
- insert_len += 2;
-
- /* Value: */
- memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
- insert_len += pwdinfo->device_name_len;
-
- /* update wsc ie length */
- *(pframe_wscie+1) = (wpsielen-2) + insert_len;
-
- /* pframe move to end */
- pframe += insert_len;
- pattrib->pktlen += insert_len;
-
- /* copy remainder_ie to pframe */
- memcpy(pframe, premainder_ie, remainder_ielen);
- pframe += remainder_ielen;
- pattrib->pktlen += remainder_ielen;
- } else
-#endif /* CONFIG_88EU_P2P */
- {
- int len_diff;
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
- len_diff = update_hidden_ssid(
- pframe+_BEACON_IE_OFFSET_
- , cur_network->IELength-_BEACON_IE_OFFSET_
- , pmlmeinfo->hidden_ssid_mode
+ int len_diff;
+ u8 *wps_ie;
+ uint wps_ielen;
+ u8 sr = 0;
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ len_diff = update_hidden_ssid(
+ pframe+_BEACON_IE_OFFSET_
+ , cur_network->IELength-_BEACON_IE_OFFSET_
+ , pmlmeinfo->hidden_ssid_mode
);
- pframe += (cur_network->IELength+len_diff);
- pattrib->pktlen += (cur_network->IELength+len_diff);
- }
-
- {
- u8 *wps_ie;
- uint wps_ielen;
- u8 sr = 0;
- wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
- pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
- if (wps_ie && wps_ielen > 0)
- rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
- if (sr != 0)
- set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
- else
- _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
- }
-
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- u32 len;
- len = build_beacon_p2p_ie(pwdinfo, pframe);
-
- pframe += len;
- pattrib->pktlen += len;
- }
-#endif /* CONFIG_88EU_P2P */
+ pframe += (cur_network->IELength+len_diff);
+ pattrib->pktlen += (cur_network->IELength+len_diff);
+ wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
+ pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
+ if (wps_ie && wps_ielen > 0)
+ rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
+ if (sr != 0)
+ set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
+ else
+ _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
goto _issue_bcn;
}
@@ -4718,9 +2139,6 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network);
unsigned int rate_len;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL) {
@@ -4732,7 +2150,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -4845,16 +2263,6 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p
/* todo:HT for adhoc */
}
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) {
- u32 len;
- len = build_probe_resp_p2p_ie(pwdinfo, pframe);
-
- pframe += len;
- pattrib->pktlen += len;
- }
-#endif /* CONFIG_88EU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe(padapter, pmgntframe);
@@ -4889,7 +2297,7 @@ static int _issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *ps
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5025,7 +2433,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5154,9 +2562,6 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
u8 *ie = pnetwork->IEs;
__le16 lestatus, leval;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
DBG_88E("%s\n", __func__);
@@ -5169,7 +2574,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5261,16 +2666,6 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
}
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device)) {
- u32 len;
-
- len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
-
- pframe += len;
- pattrib->pktlen += len;
- }
-#endif /* CONFIG_88EU_P2P */
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe(padapter, pmgntframe);
#endif
@@ -5294,11 +2689,6 @@ void issue_assocreq(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
int bssrate_len = 0, sta_bssrate_len = 0;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 p2pie[255] = { 0x00 };
- u16 p2pielen = 0;
-#endif /* CONFIG_88EU_P2P */
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
@@ -5308,7 +2698,7 @@ void issue_assocreq(struct adapter *padapter)
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5465,137 +2855,6 @@ void issue_assocreq(struct adapter *padapter)
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
-#ifdef CONFIG_88EU_P2P
-
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
- /* Should add the P2P IE in the association request frame. */
- /* P2P OUI */
-
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20101109 */
- /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Extended Listen Timing */
- /* 3. Device Info */
- /* Commented by Albert 20110516 */
- /* 4. P2P Interface */
-
- /* P2P Capability */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
- /* Extended Listen Timing */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
- p2pielen += 2;
-
- /* Device Info */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
- (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
- else
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- *(__be32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- *(__be16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- /* P2P Interface */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
-
- /* Length: */
- *(__le16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */
- p2pielen += ETH_ALEN;
-
- p2pie[p2pielen++] = 1; /* P2P Interface Address Count */
-
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */
- p2pielen += ETH_ALEN;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &pattrib->pktlen);
- }
-
-#endif /* CONFIG_88EU_P2P */
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe(padapter, pmgntframe);
@@ -5639,7 +2898,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
update_mgntframe_attrib(padapter, pattrib);
pattrib->retry_ctrl = false;
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5755,7 +3014,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
pattrib->ack_policy = 0;
pattrib->mdata = 0;
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5860,16 +3119,6 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
int ret = _FAIL;
__le16 le_tmp;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
-
-#ifdef CONFIG_88EU_P2P
- if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
- _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
- _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
- }
-#endif /* CONFIG_88EU_P2P */
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
if (pmgntframe == NULL)
@@ -5880,7 +3129,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
update_mgntframe_attrib(padapter, pattrib);
pattrib->retry_ctrl = false;
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -5982,7 +3231,7 @@ void issue_action_spct_ch_switch (struct adapter *padapter, u8 *ra, u8 new_ch, u
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -6052,7 +3301,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -6194,7 +3443,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
pattrib = &pmgntframe->attrib;
update_mgntframe_attrib(padapter, pattrib);
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+ memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
@@ -6228,7 +3477,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
/* */
- _rtw_memset(ICS, 0, sizeof(ICS));
+ memset(ICS, 0, sizeof(ICS));
if (pmlmepriv->num_sta_no_ht > 0) {
int i;
@@ -6237,14 +3486,11 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
phead = get_list_head(queue);
plist = phead->next;
- while (1) {
+ while (phead != plist) {
int len;
u8 *p;
struct wlan_bssid_ex *pbss_network;
- if (rtw_end_of_queue_search(phead, plist))
- break;
-
pnetwork = container_of(plist, struct wlan_network, list);
plist = plist->next;
@@ -6379,38 +3625,15 @@ void site_survey(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
u32 initialgain = 0;
+ struct rtw_ieee80211_channel *ch;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
- if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
- survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
- } else {
- survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
- }
- ScanType = SCAN_ACTIVE;
- } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
- /* Commented by Albert 2011/06/03 */
- /* The driver is in the find phase, it should go through the social channel. */
- int ch_set_idx;
- survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
- ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
- if (ch_set_idx >= 0)
- ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
- else
- ScanType = SCAN_ACTIVE;
- } else
-#endif /* CONFIG_88EU_P2P */
- {
- struct rtw_ieee80211_channel *ch;
- if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
- ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
- survey_channel = ch->hw_value;
- ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
- }
+ if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
+ ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
+ survey_channel = ch->hw_value;
+ ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
}
+
if (survey_channel != 0) {
/* PAUSE 4-AC Queue when site_survey */
/* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
@@ -6422,118 +3645,78 @@ void site_survey(struct adapter *padapter)
SelectChannel(padapter, survey_channel);
if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */
- #ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
- rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
- issue_probereq_p2p(padapter, NULL);
- issue_probereq_p2p(padapter, NULL);
- issue_probereq_p2p(padapter, NULL);
- } else
- #endif /* CONFIG_88EU_P2P */
- {
- int i;
- for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
- if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
- /* todo: to issue two probe req??? */
- issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
- /* msleep(SURVEY_TO>>1); */
- issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
- }
- }
-
- if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
+ int i;
+ for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
+ if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
/* todo: to issue two probe req??? */
- issue_probereq(padapter, NULL, NULL);
+ issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
/* msleep(SURVEY_TO>>1); */
- issue_probereq(padapter, NULL, NULL);
+ issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
}
}
+
+ if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
+ /* todo: to issue two probe req??? */
+ issue_probereq(padapter, NULL, NULL);
+ /* msleep(SURVEY_TO>>1); */
+ issue_probereq(padapter, NULL, NULL);
+ }
+
+ if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
+ /* todo: to issue two probe req??? */
+ issue_probereq(padapter, NULL, NULL);
+ /* msleep(SURVEY_TO>>1); */
+ issue_probereq(padapter, NULL, NULL);
+ }
}
set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
} else {
- /* channel number is 0 or this channel is not valid. */
-
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) {
- if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only)) {
- /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
- /* This will let the following flow to run the scanning end. */
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
- }
- }
- if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
- /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-
- initialgain = 0xff; /* restore RX GAIN */
- rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- /* turn on dynamic functions */
- Restore_DM_Func_Flag(padapter);
- /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
-
- _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)(pwdinfo->listen_dwell) * 100));
- } else
-#endif /* CONFIG_88EU_P2P */
- {
- /* 20100721:Interrupt scan operation here. */
- /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
- /* It compares the scan result and select better one to do connection. */
- if (rtw_hal_antdiv_before_linked(padapter)) {
- pmlmeext->sitesurvey_res.bss_cnt = 0;
- pmlmeext->sitesurvey_res.channel_idx = -1;
- pmlmeext->chan_scan_time = SURVEY_TO / 2;
- set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
- return;
- }
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-#endif /* CONFIG_88EU_P2P */
+ /* 20100721:Interrupt scan operation here. */
+ /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
+ /* It compares the scan result and select better one to do connection. */
+ if (rtw_hal_antdiv_before_linked(padapter)) {
+ pmlmeext->sitesurvey_res.bss_cnt = 0;
+ pmlmeext->sitesurvey_res.channel_idx = -1;
+ pmlmeext->chan_scan_time = SURVEY_TO / 2;
+ set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
+ return;
+ }
- pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
+ pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
- /* switch back to the original channel */
+ /* switch back to the original channel */
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- else
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-#endif /* CONFIG_88EU_P2P */
+ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
- /* flush 4-AC Queue after site_survey */
- /* val8 = 0; */
- /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
+ /* flush 4-AC Queue after site_survey */
+ /* val8 = 0; */
+ /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
- /* config MSR */
- Set_MSR(padapter, (pmlmeinfo->state & 0x3));
+ /* config MSR */
+ Set_MSR(padapter, (pmlmeinfo->state & 0x3));
- initialgain = 0xff; /* restore RX GAIN */
- rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- /* turn on dynamic functions */
- Restore_DM_Func_Flag(padapter);
- /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
+ initialgain = 0xff; /* restore RX GAIN */
+ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
+ /* turn on dynamic functions */
+ Restore_DM_Func_Flag(padapter);
+ /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
- if (is_client_associated_to_ap(padapter))
- issue_nulldata(padapter, NULL, 0, 3, 500);
+ if (is_client_associated_to_ap(padapter))
+ issue_nulldata(padapter, NULL, 0, 3, 500);
- val8 = 0; /* survey done */
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ val8 = 0; /* survey done */
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- report_surveydone_event(padapter);
+ report_surveydone_event(padapter);
- pmlmeext->chan_scan_time = SURVEY_TO;
- pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
+ pmlmeext->chan_scan_time = SURVEY_TO;
+ pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
- }
+ issue_action_BSSCoexistPacket(padapter);
+ issue_action_BSSCoexistPacket(padapter);
+ issue_action_BSSCoexistPacket(padapter);
}
return;
}
@@ -6557,7 +3740,7 @@ u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, st
if (len > MAX_IE_SZ)
return _FAIL;
- _rtw_memset(bssid, 0, sizeof(struct wlan_bssid_ex));
+ memset(bssid, 0, sizeof(struct wlan_bssid_ex));
subtype = GetFrameSubType(pframe);
@@ -6608,7 +3791,7 @@ u8 collect_bss_info(struct adapter *padapter, struct recv_frame *precv_frame, st
bssid->Ssid.SsidLength = 0;
}
- _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
+ memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
/* checking rate info... */
i = 0;
@@ -6816,7 +3999,7 @@ void start_clnt_auth(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
@@ -6847,7 +4030,7 @@ void start_clnt_assoc(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
@@ -6912,7 +4095,7 @@ static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid
p = ie;
ie += len;
- _rtw_memset(country, 0, 4);
+ memset(country, 0, 4);
memcpy(country, p, 3);
p += 3;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
@@ -6937,7 +4120,7 @@ static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid
memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
- _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
+ memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
chplan_new = pmlmeext->channel_set;
i = 0;
@@ -7058,18 +4241,18 @@ void report_survey_event(struct adapter *padapter,
pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd_obj == NULL)
return;
cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
- pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
+ pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
if (pevtcmd == NULL) {
kfree(pcmd_obj);
return;
}
- _rtw_init_listhead(&pcmd_obj->list);
+ INIT_LIST_HEAD(&pcmd_obj->list);
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
@@ -7110,18 +4293,18 @@ void report_surveydone_event(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd_obj == NULL)
return;
cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
- pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
+ pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
if (pevtcmd == NULL) {
kfree(pcmd_obj);
return;
}
- _rtw_init_listhead(&pcmd_obj->list);
+ INIT_LIST_HEAD(&pcmd_obj->list);
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
@@ -7156,18 +4339,18 @@ void report_join_res(struct adapter *padapter, int res)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd_obj == NULL)
return;
cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
- pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
+ pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
if (pevtcmd == NULL) {
kfree(pcmd_obj);
return;
}
- _rtw_init_listhead(&pcmd_obj->list);
+ INIT_LIST_HEAD(&pcmd_obj->list);
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
@@ -7209,18 +4392,18 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd_obj == NULL)
return;
cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
- pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
+ pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
if (pevtcmd == NULL) {
kfree(pcmd_obj);
return;
}
- _rtw_init_listhead(&pcmd_obj->list);
+ INIT_LIST_HEAD(&pcmd_obj->list);
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
@@ -7264,18 +4447,18 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd_obj == NULL)
return;
cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
- pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
+ pevtcmd = kzalloc(cmdsz, GFP_KERNEL);
if (pevtcmd == NULL) {
kfree(pcmd_obj);
return;
}
- _rtw_init_listhead(&pcmd_obj->list);
+ INIT_LIST_HEAD(&pcmd_obj->list);
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
pcmd_obj->cmdsz = cmdsz;
@@ -7494,7 +4677,7 @@ void mlmeext_sta_del_event_callback(struct adapter *padapter)
/* set MSR to no link state -> infra. mode */
Set_MSR(padapter, _HW_STATE_STATION_);
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
}
}
@@ -7549,8 +4732,6 @@ void linked_status_chk(struct adapter *padapter)
if (padapter->bRxRSSIDisplay)
_linked_rx_signal_strehgth_display(padapter);
- rtw_hal_sreset_linked_status_check(padapter);
-
if (is_client_associated_to_ap(padapter)) {
/* linked infrastructure client mode */
@@ -7561,9 +4742,6 @@ void linked_status_chk(struct adapter *padapter)
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
if (psta != NULL) {
bool is_p2p_enable = false;
- #ifdef CONFIG_88EU_P2P
- is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
- #endif
if (!chk_ap_is_alive(padapter, psta))
rx_chk = _FAIL;
@@ -7655,15 +4833,13 @@ void linked_status_chk(struct adapter *padapter)
}
}
-void survey_timer_hdl(struct adapter *padapter)
+void survey_timer_hdl(void *function_context)
{
+ struct adapter *padapter = (struct adapter *)function_context;
struct cmd_obj *ph2c;
struct sitesurvey_parm *psurveyPara;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif
/* issue rtw_sitesurvey_cmd */
if (pmlmeext->sitesurvey_res.state > SCAN_START) {
@@ -7671,31 +4847,18 @@ void survey_timer_hdl(struct adapter *padapter)
pmlmeext->sitesurvey_res.channel_idx++;
if (pmlmeext->scan_abort) {
- #ifdef CONFIG_88EU_P2P
- if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
- pmlmeext->sitesurvey_res.channel_idx = 3;
- DBG_88E("%s idx:%d, cnt:%u\n", __func__
- , pmlmeext->sitesurvey_res.channel_idx
- , pwdinfo->find_phase_state_exchange_cnt
- );
- } else
- #endif
- {
- pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
- DBG_88E("%s idx:%d\n", __func__
- , pmlmeext->sitesurvey_res.channel_idx
- );
- }
+ pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
+ DBG_88E("%s idx:%d\n", __func__
+ , pmlmeext->sitesurvey_res.channel_idx);
pmlmeext->scan_abort = false;/* reset */
}
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL)
goto exit_survey_timer_hdl;
- psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
+ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL);
if (psurveyPara == NULL) {
kfree(ph2c);
goto exit_survey_timer_hdl;
@@ -7710,8 +4873,9 @@ exit_survey_timer_hdl:
return;
}
-void link_timer_hdl(struct adapter *padapter)
+void link_timer_hdl(void *function_context)
{
+ struct adapter *padapter = (struct adapter *)function_context;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -7746,8 +4910,9 @@ void link_timer_hdl(struct adapter *padapter)
return;
}
-void addba_timer_hdl(struct sta_info *psta)
+void addba_timer_hdl(void *function_context)
{
+ struct sta_info *psta = (struct sta_info *)function_context;
struct ht_priv *phtpriv;
if (!psta)
@@ -7797,11 +4962,11 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
- struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
+ struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
/* u32 initialgain; */
- if (pparm->network.InfrastructureMode == Ndis802_11APMode) {
+ if (pparm->InfrastructureMode == Ndis802_11APMode) {
#ifdef CONFIG_88EU_AP_MODE
if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
@@ -7812,7 +4977,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
}
/* below is for ad-hoc master */
- if (pparm->network.InfrastructureMode == Ndis802_11IBSS) {
+ if (pparm->InfrastructureMode == Ndis802_11IBSS) {
rtw_joinbss_reset(padapter);
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
@@ -7834,7 +4999,7 @@ u8 createbss_hdl(struct adapter *padapter, u8 *pbuf)
/* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
/* cancel link timer */
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
/* clear CAM */
flush_all_cam_entry(padapter);
@@ -7861,7 +5026,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
- struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
+ struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
u32 i;
/* check already connecting to AP or not */
@@ -7874,7 +5039,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
/* clear CAM */
flush_all_cam_entry(padapter);
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
/* set MSR to nolink -> infra. mode */
Set_MSR(padapter, _HW_STATE_STATION_);
@@ -7883,7 +5048,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL);
}
- rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, false);
+ rtw_antenna_select_cmd(padapter, pparm->PhyInfo.Optimum_antenna, false);
rtw_joinbss_reset(padapter);
@@ -7960,7 +5125,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf)
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
/* cancel link timer */
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
start_clnt_join(padapter);
@@ -8004,7 +5169,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf)
flush_all_cam_entry(padapter);
- _cancel_timer_ex(&pmlmeext->link_timer);
+ del_timer_sync(&pmlmeext->link_timer);
rtw_free_uc_swdec_pending_queue(padapter);
@@ -8019,7 +5184,7 @@ static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_c
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
/* clear out first */
- _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
+ memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
/* acquire channels from in */
j = 0;
@@ -8062,10 +5227,6 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
u32 initialgain;
u32 i;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif
-
if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
/* for first time sitesurvey_cmd */
rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, NULL);
@@ -8111,14 +5272,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf)
Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
/* config the initial gain under scanning, need to write the BB registers */
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- initialgain = 0x1E;
- else
- initialgain = 0x28;
-#else /* CONFIG_88EU_P2P */
initialgain = 0x1E;
-#endif /* CONFIG_88EU_P2P */
rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
@@ -8265,7 +5419,7 @@ u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf)
u8 set_tx_beacon_cmd(struct adapter *padapter)
{
struct cmd_obj *ph2c;
- struct Tx_Beacon_param *ptxBeacon_parm;
+ struct wlan_bssid_ex *ptxBeacon_parm;
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -8273,25 +5427,25 @@ u8 set_tx_beacon_cmd(struct adapter *padapter)
int len_diff = 0;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param));
+ ptxBeacon_parm = kzalloc(sizeof(struct wlan_bssid_ex), GFP_KERNEL);
if (ptxBeacon_parm == NULL) {
kfree(ph2c);
res = _FAIL;
goto exit;
}
- memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
+ memcpy(ptxBeacon_parm, &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex));
- len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
- ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
+ len_diff = update_hidden_ssid(ptxBeacon_parm->IEs+_BEACON_IE_OFFSET_,
+ ptxBeacon_parm->IELength-_BEACON_IE_OFFSET_,
pmlmeinfo->hidden_ssid_mode);
- ptxBeacon_parm->network.IELength += len_diff;
+ ptxBeacon_parm->IELength += len_diff;
init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
@@ -8310,7 +5464,6 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
u16 evt_sz;
uint *peventbuf;
void (*event_callback)(struct adapter *dev, u8 *pbuf);
- struct evt_priv *pevt_priv = &(padapter->evtpriv);
peventbuf = (uint *)pbuf;
evt_sz = (u16)(*peventbuf&0xffff);
@@ -8331,29 +5484,18 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf)
goto _abort_event_;
}
- atomic_inc(&pevt_priv->event_seq);
-
peventbuf += 2;
if (peventbuf) {
event_callback = wlanevents[evt_code].event_callback;
event_callback(padapter, (u8 *)peventbuf);
- pevt_priv->evt_done_cnt++;
}
_abort_event_:
return H2C_SUCCESS;
}
-u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
-
- return H2C_SUCCESS;
-}
-
u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
{
if (send_beacon(padapter) == _FAIL) {
@@ -8379,12 +5521,12 @@ u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf)
xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
xmitframe_plist = xmitframe_phead->next;
- while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ while (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
psta_bmc->sleepq_len--;
if (psta_bmc->sleepq_len > 0)
@@ -8446,33 +5588,3 @@ u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf)
return H2C_SUCCESS;
}
-
-u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
- if (!pbuf)
- return H2C_PARAMETERS_ERROR;
- return H2C_SUCCESS;
-}
-
-u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
- return H2C_REJECTED;
-}
-
-/* TDLS_WRCR : write RCR DATA BIT */
-/* TDLS_SD_PTI : issue peer traffic indication */
-/* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
-/* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
-/* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
-/* TDLS_OFF_CH : first time set channel to off channel */
-/* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
-/* TDLS_P_OFF_CH : periodically go to off channel */
-/* TDLS_P_BASE_CH : periodically go back to base channel */
-/* TDLS_RS_RCR : restore RCR */
-/* TDLS_CKALV_PH1 : check alive timer phase1 */
-/* TDLS_CKALV_PH2 : check alive timer phase2 */
-/* TDLS_FREE_STA : free tdls sta */
-u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf)
-{
- return H2C_REJECTED;
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_mp.c b/drivers/staging/rtl8188eu/core/rtw_mp.c
deleted file mode 100644
index 17427a68b66c..000000000000
--- a/drivers/staging/rtl8188eu/core/rtw_mp.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_MP_C_
-
-#include <drv_types.h>
-
-#include "rtl8188e_hal.h"
-#include <linux/vmalloc.h>
-
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
-{
- u32 val = 0;
-
- switch (sz) {
- case 1:
- val = rtw_read8(padapter, addr);
- break;
- case 2:
- val = rtw_read16(padapter, addr);
- break;
- case 4:
- val = rtw_read32(padapter, addr);
- break;
- default:
- val = 0xffffffff;
- break;
- }
-
- return val;
-}
-
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz)
-{
- switch (sz) {
- case 1:
- rtw_write8(padapter, addr, (u8)val);
- break;
- case 2:
- rtw_write16(padapter, addr, (u16)val);
- break;
- case 4:
- rtw_write32(padapter, addr, val);
- break;
- default:
- break;
- }
-}
-
-u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
-{
- return rtw_hal_read_bbreg(padapter, addr, bitmask);
-}
-
-void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val)
-{
- rtw_hal_write_bbreg(padapter, addr, bitmask, val);
-}
-
-u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask)
-{
- return rtw_hal_read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask);
-}
-
-void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val)
-{
- rtw_hal_write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask, val);
-}
-
-u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr)
-{
- return _read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask);
-}
-
-void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val)
-{
- _write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask, val);
-}
-
-static void _init_mp_priv_(struct mp_priv *pmp_priv)
-{
- struct wlan_bssid_ex *pnetwork;
-
- _rtw_memset(pmp_priv, 0, sizeof(struct mp_priv));
-
- pmp_priv->mode = MP_OFF;
-
- pmp_priv->channel = 1;
- pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20;
- pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- pmp_priv->rateidx = MPT_RATE_1M;
- pmp_priv->txpoweridx = 0x2A;
-
- pmp_priv->antenna_tx = ANTENNA_A;
- pmp_priv->antenna_rx = ANTENNA_AB;
-
- pmp_priv->check_mp_pkt = 0;
-
- pmp_priv->tx_pktcount = 0;
-
- pmp_priv->rx_pktcount = 0;
- pmp_priv->rx_crcerrpktcount = 0;
-
- pmp_priv->network_macaddr[0] = 0x00;
- pmp_priv->network_macaddr[1] = 0xE0;
- pmp_priv->network_macaddr[2] = 0x4C;
- pmp_priv->network_macaddr[3] = 0x87;
- pmp_priv->network_macaddr[4] = 0x66;
- pmp_priv->network_macaddr[5] = 0x55;
-
- pnetwork = &pmp_priv->mp_network.network;
- memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN);
-
- pnetwork->Ssid.SsidLength = 8;
- memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength);
-}
-
-static void mp_init_xmit_attrib(struct mp_tx *pmptx, struct adapter *padapter)
-{
- struct pkt_attrib *pattrib;
- struct tx_desc *desc;
-
- /* init xmitframe attribute */
- pattrib = &pmptx->attrib;
- _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
- desc = &pmptx->desc;
- _rtw_memset(desc, 0, TXDESC_SIZE);
-
- pattrib->ether_type = 0x8712;
- _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
- pattrib->ack_policy = 0;
- pattrib->hdrlen = WLAN_HDR_A3_LEN;
- pattrib->subtype = WIFI_DATA;
- pattrib->priority = 0;
- pattrib->qsel = pattrib->priority;
- pattrib->nr_frags = 1;
- pattrib->encrypt = 0;
- pattrib->bswenc = false;
- pattrib->qos_en = false;
-}
-
-s32 init_mp_priv(struct adapter *padapter)
-{
- struct mp_priv *pmppriv = &padapter->mppriv;
-
- _init_mp_priv_(pmppriv);
- pmppriv->papdater = padapter;
-
- pmppriv->tx.stop = 1;
- mp_init_xmit_attrib(&pmppriv->tx, padapter);
-
- switch (padapter->registrypriv.rf_config) {
- case RF_1T1R:
- pmppriv->antenna_tx = ANTENNA_A;
- pmppriv->antenna_rx = ANTENNA_A;
- break;
- case RF_1T2R:
- default:
- pmppriv->antenna_tx = ANTENNA_A;
- pmppriv->antenna_rx = ANTENNA_AB;
- break;
- case RF_2T2R:
- case RF_2T2R_GREEN:
- pmppriv->antenna_tx = ANTENNA_AB;
- pmppriv->antenna_rx = ANTENNA_AB;
- break;
- case RF_2T4R:
- pmppriv->antenna_tx = ANTENNA_AB;
- pmppriv->antenna_rx = ANTENNA_ABCD;
- break;
- }
-
- return _SUCCESS;
-}
-
-void free_mp_priv(struct mp_priv *pmp_priv)
-{
- kfree(pmp_priv->pallocated_mp_xmitframe_buf);
- pmp_priv->pallocated_mp_xmitframe_buf = NULL;
- pmp_priv->pmp_xmtframe_buf = NULL;
-}
-
-#define PHY_IQCalibrate(a, b) PHY_IQCalibrate_8188E(a, b)
-#define PHY_LCCalibrate(a) PHY_LCCalibrate_8188E(a)
-#define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188E(a, b)
-
-s32 MPT_InitializeAdapter(struct adapter *pAdapter, u8 Channel)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- s32 rtStatus = _SUCCESS;
- struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
- struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv;
-
- /* HW Initialization for 8190 MPT. */
- /* SW Initialization for 8190 MP. */
- pMptCtx->bMptDrvUnload = false;
- pMptCtx->bMassProdTest = false;
- pMptCtx->bMptIndexEven = true; /* default gain index is -6.0db */
- pMptCtx->h2cReqNum = 0x0;
- /* Init mpt event. */
- /* init for BT MP */
-
- pMptCtx->bMptWorkItemInProgress = false;
- pMptCtx->CurrMptAct = NULL;
- /* */
-
- /* Don't accept any packets */
- rtw_write32(pAdapter, REG_RCR, 0);
-
- PHY_IQCalibrate(pAdapter, false);
- dm_CheckTXPowerTracking(&pHalData->odmpriv); /* trigger thermal meter */
- PHY_LCCalibrate(pAdapter);
-
- pMptCtx->backup0xc50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0);
- pMptCtx->backup0xc58 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0);
- pMptCtx->backup0xc30 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0);
- pMptCtx->backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
- pMptCtx->backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
-
- /* set ant to wifi side in mp mode */
- rtw_write16(pAdapter, 0x870, 0x300);
- rtw_write16(pAdapter, 0x860, 0x110);
-
- if (pAdapter->registrypriv.mp_mode == 1)
- pmlmepriv->fw_state = WIFI_MP_STATE;
-
- return rtStatus;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: MPT_DeInitAdapter()
- *
- * Overview: Extra DeInitialization for Mass Production Test.
- *
- * Input: struct adapter * pAdapter
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 05/08/2007 MHC Create Version 0.
- * 05/18/2007 MHC Add normal driver MPHalt code.
- *
- *---------------------------------------------------------------------------*/
-void MPT_DeInitAdapter(struct adapter *pAdapter)
-{
- struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
-
- pMptCtx->bMptDrvUnload = true;
-}
-
-static u8 mpt_ProStartTest(struct adapter *padapter)
-{
- struct mpt_context *pMptCtx = &padapter->mppriv.MptCtx;
-
- pMptCtx->bMassProdTest = true;
- pMptCtx->bStartContTx = false;
- pMptCtx->bCckContTx = false;
- pMptCtx->bOfdmContTx = false;
- pMptCtx->bSingleCarrier = false;
- pMptCtx->bCarrierSuppression = false;
- pMptCtx->bSingleTone = false;
-
- return _SUCCESS;
-}
-
-/*
- * General use
- */
-s32 SetPowerTracking(struct adapter *padapter, u8 enable)
-{
- Hal_SetPowerTracking(padapter, enable);
- return 0;
-}
-
-void GetPowerTracking(struct adapter *padapter, u8 *enable)
-{
- Hal_GetPowerTracking(padapter, enable);
-}
-
-static void disable_dm(struct adapter *padapter)
-{
- u8 v8;
-
- /* 3 1. disable firmware dynamic mechanism */
- /* disable Power Training, Rate Adaptive */
- v8 = rtw_read8(padapter, REG_BCN_CTRL);
- v8 &= ~EN_BCN_FUNCTION;
- rtw_write8(padapter, REG_BCN_CTRL, v8);
-
- /* 3 2. disable driver dynamic mechanism */
- /* disable Dynamic Initial Gain */
- /* disable High Power */
- /* disable Power Tracking */
- Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
-
- /* enable APK, LCK and IQK but disable power tracking */
- Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, true);
-}
-
-/* This function initializes the DUT to the MP test mode */
-s32 mp_start_test(struct adapter *padapter)
-{
- struct wlan_bssid_ex bssid;
- struct sta_info *psta;
- u32 length;
- u8 val8;
- s32 res = _SUCCESS;
- struct mp_priv *pmppriv = &padapter->mppriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *tgt_network = &pmlmepriv->cur_network;
-
- padapter->registrypriv.mp_mode = 1;
- pmppriv->bSetTxPower = 0; /* for manually set tx power */
-
- /* 3 disable dynamic mechanism */
- disable_dm(padapter);
-
- /* 3 0. update mp_priv */
-
- if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) {
- switch (GET_RF_TYPE(padapter)) {
- case RF_1T1R:
- pmppriv->antenna_tx = ANTENNA_A;
- pmppriv->antenna_rx = ANTENNA_A;
- break;
- case RF_1T2R:
- default:
- pmppriv->antenna_tx = ANTENNA_A;
- pmppriv->antenna_rx = ANTENNA_AB;
- break;
- case RF_2T2R:
- case RF_2T2R_GREEN:
- pmppriv->antenna_tx = ANTENNA_AB;
- pmppriv->antenna_rx = ANTENNA_AB;
- break;
- case RF_2T4R:
- pmppriv->antenna_tx = ANTENNA_AB;
- pmppriv->antenna_rx = ANTENNA_ABCD;
- break;
- }
- }
-
- mpt_ProStartTest(padapter);
-
- /* 3 1. initialize a new struct wlan_bssid_ex */
-/* _rtw_memset(&bssid, 0, sizeof(struct wlan_bssid_ex)); */
- memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
- bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc");
- memcpy(bssid.Ssid.Ssid, (u8 *)"mp_pseudo_adhoc", bssid.Ssid.SsidLength);
- bssid.InfrastructureMode = Ndis802_11IBSS;
- bssid.NetworkTypeInUse = Ndis802_11DS;
- bssid.IELength = 0;
-
- length = get_wlan_bssid_ex_sz(&bssid);
- if (length % 4)
- bssid.Length = ((length >> 2) + 1) << 2; /* round up to multiple of 4 bytes. */
- else
- bssid.Length = length;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
- goto end_of_mp_start_test;
-
- /* init mp_start_test status */
- if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
- rtw_disassoc_cmd(padapter, 500, true);
- rtw_indicate_disconnect(padapter);
- rtw_free_assoc_resources(padapter, 1);
- }
- pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
- if (padapter->registrypriv.mp_mode == 1)
- pmlmepriv->fw_state = WIFI_MP_STATE;
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
- /* 3 2. create a new psta for mp driver */
- /* clear psta in the cur_network, if any */
- psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
- if (psta)
- rtw_free_stainfo(padapter, psta);
-
- psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
- if (psta == NULL) {
- RT_TRACE(_module_mp_, _drv_err_, ("mp_start_test: Can't alloc sta_info!\n"));
- pmlmepriv->fw_state = pmppriv->prev_fw_state;
- res = _FAIL;
- goto end_of_mp_start_test;
- }
-
- /* 3 3. join pseudo AdHoc */
- tgt_network->join_res = 1;
- tgt_network->aid = 1;
- psta->aid = 1;
- memcpy(&tgt_network->network, &bssid, length);
-
- rtw_indicate_connect(padapter);
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
-end_of_mp_start_test:
-
- spin_unlock_bh(&pmlmepriv->lock);
-
- if (res == _SUCCESS) {
- /* set MSR to WIFI_FW_ADHOC_STATE */
- val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */
- val8 |= WIFI_FW_ADHOC_STATE;
- rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */
- }
- return res;
-}
-/* */
-/* This function change the DUT from the MP test mode into normal mode */
-void mp_stop_test(struct adapter *padapter)
-{
- struct mp_priv *pmppriv = &padapter->mppriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *tgt_network = &pmlmepriv->cur_network;
- struct sta_info *psta;
-
- if (pmppriv->mode == MP_ON) {
- pmppriv->bSetTxPower = 0;
- spin_lock_bh(&pmlmepriv->lock);
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)
- goto end_of_mp_stop_test;
-
- /* 3 1. disconnect pseudo AdHoc */
- rtw_indicate_disconnect(padapter);
-
- /* 3 2. clear psta used in mp test mode. */
- psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
- if (psta)
- rtw_free_stainfo(padapter, psta);
-
- /* 3 3. return to normal state (default:station mode) */
- pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE; */
-
- /* flush the cur_network */
- _rtw_memset(tgt_network, 0, sizeof(struct wlan_network));
-
- _clr_fwstate_(pmlmepriv, WIFI_MP_STATE);
-
-end_of_mp_stop_test:
-
- spin_unlock_bh(&pmlmepriv->lock);
- }
-}
-
-/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
-/*
- * SetChannel
- * Description
- * Use H2C command to change channel,
- * not only modify rf register, but also other setting need to be done.
- */
-void SetChannel(struct adapter *pAdapter)
-{
- Hal_SetChannel(pAdapter);
-}
-
-/*
- * Notice
- * Switch bandwitdth may change center frequency(channel)
- */
-void SetBandwidth(struct adapter *pAdapter)
-{
- Hal_SetBandwidth(pAdapter);
-}
-
-void SetAntenna(struct adapter *pAdapter)
-{
- Hal_SetAntenna(pAdapter);
-}
-
-void SetAntennaPathPower(struct adapter *pAdapter)
-{
- Hal_SetAntennaPathPower(pAdapter);
-}
-
-void SetTxPower(struct adapter *pAdapter)
-{
- Hal_SetTxPower(pAdapter);
- }
-
-void SetDataRate(struct adapter *pAdapter)
-{
- Hal_SetDataRate(pAdapter);
-}
-
-void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter , bool bMain)
-{
- PHY_SetRFPathSwitch(pAdapter, bMain);
-}
-
-s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther)
-{
- return Hal_SetThermalMeter(pAdapter, target_ther);
-}
-
-void GetThermalMeter(struct adapter *pAdapter, u8 *value)
-{
- Hal_GetThermalMeter(pAdapter, value);
-}
-
-void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart)
-{
- PhySetTxPowerLevel(pAdapter);
- Hal_SetSingleCarrierTx(pAdapter, bStart);
-}
-
-void SetSingleToneTx(struct adapter *pAdapter, u8 bStart)
-{
- PhySetTxPowerLevel(pAdapter);
- Hal_SetSingleToneTx(pAdapter, bStart);
-}
-
-void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart)
-{
- PhySetTxPowerLevel(pAdapter);
- Hal_SetCarrierSuppressionTx(pAdapter, bStart);
-}
-
-void SetContinuousTx(struct adapter *pAdapter, u8 bStart)
-{
- PhySetTxPowerLevel(pAdapter);
- Hal_SetContinuousTx(pAdapter, bStart);
-}
-
-
-void PhySetTxPowerLevel(struct adapter *pAdapter)
-{
- struct mp_priv *pmp_priv = &pAdapter->mppriv;
-
- if (pmp_priv->bSetTxPower == 0) /* for NO manually set power index */
- PHY_SetTxPowerLevel8188E(pAdapter, pmp_priv->channel);
-}
-
-/* */
-static void dump_mpframe(struct adapter *padapter, struct xmit_frame *pmpframe)
-{
- rtw_hal_mgnt_xmit(padapter, pmpframe);
-}
-
-static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv)
-{
- struct xmit_frame *pmpframe;
- struct xmit_buf *pxmitbuf;
-
- pmpframe = rtw_alloc_xmitframe(pxmitpriv);
- if (pmpframe == NULL)
- return NULL;
-
- pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
- if (pxmitbuf == NULL) {
- rtw_free_xmitframe(pxmitpriv, pmpframe);
- return NULL;
- }
-
- pmpframe->frame_tag = MP_FRAMETAG;
-
- pmpframe->pxmitbuf = pxmitbuf;
-
- pmpframe->buf_addr = pxmitbuf->pbuf;
-
- pxmitbuf->priv_data = pmpframe;
-
- return pmpframe;
-}
-
-static int mp_xmit_packet_thread(void *context)
-{
- struct xmit_frame *pxmitframe;
- struct mp_tx *pmptx;
- struct mp_priv *pmp_priv;
- struct xmit_priv *pxmitpriv;
- struct adapter *padapter;
-
- pmp_priv = (struct mp_priv *)context;
- pmptx = &pmp_priv->tx;
- padapter = pmp_priv->papdater;
- pxmitpriv = &(padapter->xmitpriv);
-
- thread_enter("RTW_MP_THREAD");
-
- /* DBG_88E("%s:pkTx Start\n", __func__); */
- while (1) {
- pxmitframe = alloc_mp_xmitframe(pxmitpriv);
- if (pxmitframe == NULL) {
- if (pmptx->stop ||
- padapter->bSurpriseRemoved ||
- padapter->bDriverStopped) {
- goto exit;
- } else {
- msleep(1);
- continue;
- }
- }
-
- memcpy((u8 *)(pxmitframe->buf_addr+TXDESC_OFFSET), pmptx->buf, pmptx->write_size);
- memcpy(&(pxmitframe->attrib), &(pmptx->attrib), sizeof(struct pkt_attrib));
-
- dump_mpframe(padapter, pxmitframe);
-
- pmptx->sended++;
- pmp_priv->tx_pktcount++;
-
- if (pmptx->stop ||
- padapter->bSurpriseRemoved ||
- padapter->bDriverStopped)
- goto exit;
- if ((pmptx->count != 0) &&
- (pmptx->count == pmptx->sended))
- goto exit;
-
- flush_signals_thread();
- }
-
-exit:
- kfree(pmptx->pallocated_buf);
- pmptx->pallocated_buf = NULL;
- pmptx->stop = 1;
-
- complete_and_exit(NULL, 0);
-}
-
-void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc)
-{
- struct mp_priv *pmp_priv = &padapter->mppriv;
- memcpy(ptxdesc, &(pmp_priv->tx.desc), TXDESC_SIZE);
-}
-
-void SetPacketTx(struct adapter *padapter)
-{
- u8 *ptr, *pkt_start, *pkt_end;
- u32 pkt_size;
- struct tx_desc *desc;
- struct rtw_ieee80211_hdr *hdr;
- u8 payload;
- s32 bmcast;
- struct pkt_attrib *pattrib;
- struct mp_priv *pmp_priv;
-
-
- pmp_priv = &padapter->mppriv;
- if (pmp_priv->tx.stop)
- return;
- pmp_priv->tx.sended = 0;
- pmp_priv->tx.stop = 0;
- pmp_priv->tx_pktcount = 0;
-
- /* 3 1. update_attrib() */
- pattrib = &pmp_priv->tx.attrib;
- memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- bmcast = IS_MCAST(pattrib->ra);
- if (bmcast) {
- pattrib->mac_id = 1;
- pattrib->psta = rtw_get_bcmc_stainfo(padapter);
- } else {
- pattrib->mac_id = 0;
- pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
- }
-
- pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
-
- /* 3 2. allocate xmit buffer */
- pkt_size = pattrib->last_txcmdsz;
-
- kfree(pmp_priv->tx.pallocated_buf);
- pmp_priv->tx.write_size = pkt_size;
- pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ;
- pmp_priv->tx.pallocated_buf = rtw_zmalloc(pmp_priv->tx.buf_size);
- if (pmp_priv->tx.pallocated_buf == NULL) {
- DBG_88E("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size);
- return;
- }
- pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ);
- ptr = pmp_priv->tx.buf;
-
- desc = &(pmp_priv->tx.desc);
- _rtw_memset(desc, 0, TXDESC_SIZE);
- pkt_start = ptr;
- pkt_end = pkt_start + pkt_size;
-
- /* 3 3. init TX descriptor */
- /* offset 0 */
- desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
- desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); /* packet size */
- desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); /* 32 bytes for TX Desc */
- if (bmcast)
- desc->txdw0 |= cpu_to_le32(BMC); /* broadcast packet */
-
- desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000);
- /* offset 4 */
- desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); /* CAM_ID(MAC_ID) */
- desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); /* Queue Select, TID */
-
- desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); /* Rate Adaptive ID */
- /* offset 8 */
- /* offset 12 */
-
- desc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0x0fff0000);
-
- /* offset 16 */
- desc->txdw4 |= cpu_to_le32(HW_SSN);
- desc->txdw4 |= cpu_to_le32(USERATE);
- desc->txdw4 |= cpu_to_le32(DISDATAFB);
-
- if (pmp_priv->preamble) {
- if (pmp_priv->rateidx <= MPT_RATE_54M)
- desc->txdw4 |= cpu_to_le32(DATA_SHORT); /* CCK Short Preamble */
- }
- if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40)
- desc->txdw4 |= cpu_to_le32(DATA_BW);
-
- /* offset 20 */
- desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F);
-
- if (pmp_priv->preamble) {
- if (pmp_priv->rateidx > MPT_RATE_54M)
- desc->txdw5 |= cpu_to_le32(SGI); /* MCS Short Guard Interval */
- }
- desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); /* retry limit enable */
- desc->txdw5 |= cpu_to_le32(0x00180000); /* DATA/RTS Rate Fallback Limit */
-
- /* 3 4. make wlan header, make_wlanhdr() */
- hdr = (struct rtw_ieee80211_hdr *)pkt_start;
- SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
- memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
- memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
- memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
-
- /* 3 5. make payload */
- ptr = pkt_start + pattrib->hdrlen;
-
- switch (pmp_priv->tx.payload) {
- case 0:
- payload = 0x00;
- break;
- case 1:
- payload = 0x5a;
- break;
- case 2:
- payload = 0xa5;
- break;
- case 3:
- payload = 0xff;
- break;
- default:
- payload = 0x00;
- break;
- }
-
- _rtw_memset(ptr, payload, pkt_end - ptr);
-
- /* 3 6. start thread */
- pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD");
- if (IS_ERR(pmp_priv->tx.PktTxThread))
- DBG_88E("Create PktTx Thread Fail !!!!!\n");
-}
-
-void SetPacketRx(struct adapter *pAdapter, u8 bStartRx)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
-
- if (bStartRx) {
- /* Accept CRC error and destination address */
- pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS;
-
- pHalData->ReceiveConfig |= ACRC32;
-
- rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
-
- /* Accept all data frames */
- rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF);
- } else {
- rtw_write32(pAdapter, REG_RCR, 0);
- }
-}
-
-void ResetPhyRxPktCount(struct adapter *pAdapter)
-{
- u32 i, phyrx_set = 0;
-
- for (i = 0; i <= 0xF; i++) {
- phyrx_set = 0;
- phyrx_set |= _RXERR_RPT_SEL(i); /* select */
- phyrx_set |= RXERR_RPT_RST; /* set counter to zero */
- rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
- }
-}
-
-static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
-{
- /* selection */
- u32 phyrx_set = 0, count = 0;
-
- phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
- rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
-
- /* Read packet count */
- count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
-
- return count;
-}
-
-u32 GetPhyRxPktReceived(struct adapter *pAdapter)
-{
- u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
-
- OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK);
- CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK);
- HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK);
-
- return OFDM_cnt + CCK_cnt + HT_cnt;
-}
-
-u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
-{
- u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
-
- OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL);
- CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL);
- HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL);
-
- return OFDM_cnt + CCK_cnt + HT_cnt;
-}
-
-/* reg 0x808[9:0]: FFT data x */
-/* reg 0x808[22]: 0 --> 1 to get 1 FFT data y */
-/* reg 0x8B4[15:0]: FFT data y report */
-static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
-{
- int psd_val;
-
-
- psd_val = rtw_read32(pAdapter, 0x808);
- psd_val &= 0xFFBFFC00;
- psd_val |= point;
-
- rtw_write32(pAdapter, 0x808, psd_val);
- mdelay(1);
- psd_val |= 0x00400000;
-
- rtw_write32(pAdapter, 0x808, psd_val);
- mdelay(1);
- psd_val = rtw_read32(pAdapter, 0x8B4);
-
- psd_val &= 0x0000FFFF;
-
- return psd_val;
-}
-
-/*
- *pts start_point_min stop_point_max
- * 128 64 64 + 128 = 192
- * 256 128 128 + 256 = 384
- * 512 256 256 + 512 = 768
- * 1024 512 512 + 1024 = 1536
- *
- */
-u32 mp_query_psd(struct adapter *pAdapter, u8 *data)
-{
- u32 i, psd_pts = 0, psd_start = 0, psd_stop = 0;
- u32 psd_data = 0;
- int ret;
-
- if (!netif_running(pAdapter->pnetdev)) {
- RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! interface not opened!\n"));
- return 0;
- }
-
- if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == false) {
- RT_TRACE(_module_mp_, _drv_warning_, ("mp_query_psd: Fail! not in MP mode!\n"));
- return 0;
- }
-
- if (strlen(data) == 0) { /* default value */
- psd_pts = 128;
- psd_start = 64;
- psd_stop = 128;
- } else {
- ret = sscanf(data, "pts =%d, start =%d, stop =%d",
- &psd_pts, &psd_start, &psd_stop);
- if (ret != 3)
- return 0;
- }
-
- _rtw_memset(data, '\0', sizeof(*data));
-
- i = psd_start;
- while (i < psd_stop) {
- if (i >= psd_pts) {
- psd_data = rtw_GetPSDData(pAdapter, i-psd_pts);
- } else {
- psd_data = rtw_GetPSDData(pAdapter, i);
- }
- sprintf(data, "%s%x ", data, psd_data);
- i++;
- }
-
- msleep(100);
- return strlen(data)+1;
-}
-
-void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv)
-{
- int i, res;
- struct adapter *padapter = pxmitpriv->adapter;
- struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
-
- u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
- u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
- if (padapter->registrypriv.mp_mode == 0) {
- max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
- num_xmit_extbuf = NR_XMIT_EXTBUFF;
- } else {
- max_xmit_extbuf_size = 20000;
- num_xmit_extbuf = 1;
- }
-
- pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
- for (i = 0; i < num_xmit_extbuf; i++) {
- rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
-
- pxmitbuf++;
- }
-
- if (pxmitpriv->pallocated_xmit_extbuf)
- vfree(pxmitpriv->pallocated_xmit_extbuf);
-
- if (padapter->registrypriv.mp_mode == 0) {
- max_xmit_extbuf_size = 20000;
- num_xmit_extbuf = 1;
- } else {
- max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
- num_xmit_extbuf = NR_XMIT_EXTBUFF;
- }
-
- /* Init xmit extension buff */
- _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
-
- pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
-
- if (pxmitpriv->pallocated_xmit_extbuf == NULL) {
- RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("alloc xmit_extbuf fail!\n"));
- res = _FAIL;
- goto exit;
- }
-
- pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
-
- pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
-
- for (i = 0; i < num_xmit_extbuf; i++) {
- _rtw_init_listhead(&pxmitbuf->list);
-
- pxmitbuf->priv_data = NULL;
- pxmitbuf->padapter = padapter;
- pxmitbuf->ext_tag = true;
-
- res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
- if (res == _FAIL) {
- res = _FAIL;
- goto exit;
- }
-
- rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
- pxmitbuf++;
- }
-
- pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
-
-exit:
- ;
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_mp_ioctl.c b/drivers/staging/rtl8188eu/core/rtw_mp_ioctl.c
deleted file mode 100644
index e783968b29ea..000000000000
--- a/drivers/staging/rtl8188eu/core/rtw_mp_ioctl.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_MP_IOCTL_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <mlme_osdep.h>
-
-/* include <rtw_mp.h> */
-#include <rtw_mp_ioctl.h>
-
-
-/* rtl8188eu_oid_rtl_seg_81_85 section start **************** */
-int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->information_buf_len < sizeof(u8))
- return NDIS_STATUS_INVALID_LENGTH;
-
- if (poid_par_priv->type_of_oid == SET_OID) {
- Adapter->registrypriv.wireless_mode = *(u8 *)poid_par_priv->information_buf;
- } else if (poid_par_priv->type_of_oid == QUERY_OID) {
- *(u8 *)poid_par_priv->information_buf = Adapter->registrypriv.wireless_mode;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- RT_TRACE(_module_mp_, _drv_info_, ("-query Wireless Mode=%d\n", Adapter->registrypriv.wireless_mode));
- } else {
- status = NDIS_STATUS_NOT_ACCEPTED;
- }
-
-
- return status;
-}
-/* rtl8188eu_oid_rtl_seg_81_87_80 section start **************** */
-int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct bb_reg_param *pbbreg;
- u16 offset;
- u32 value;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_write_bb_reg_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
- return NDIS_STATUS_INVALID_LENGTH;
-
- pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
-
- offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */
- if (offset < BB_REG_BASE_ADDR)
- offset |= BB_REG_BASE_ADDR;
-
- value = pbbreg->value;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_write_bb_reg_hdl: offset=0x%03X value=0x%08X\n",
- offset, value));
-
- _irqlevel_changed_(&oldirql, LOWER);
- write_bbreg(Adapter, offset, 0xFFFFFFFF, value);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct bb_reg_param *pbbreg;
- u16 offset;
- u32 value;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_read_bb_reg_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(struct bb_reg_param))
- return NDIS_STATUS_INVALID_LENGTH;
-
- pbbreg = (struct bb_reg_param *)(poid_par_priv->information_buf);
-
- offset = (u16)(pbbreg->offset) & 0xFFF; /* 0ffset :0x800~0xfff */
- if (offset < BB_REG_BASE_ADDR)
- offset |= BB_REG_BASE_ADDR;
-
- _irqlevel_changed_(&oldirql, LOWER);
- value = read_bbreg(Adapter, offset, 0xFFFFFFFF);
- _irqlevel_changed_(&oldirql, RAISE);
-
- pbbreg->value = value;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("-rtl8188eu_oid_rt_pro_read_bb_reg_hdl: offset=0x%03X value:0x%08X\n",
- offset, value));
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct rf_reg_param *pbbreg;
- u8 path;
- u8 offset;
- u32 value;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_write_rf_reg_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
- return NDIS_STATUS_INVALID_LENGTH;
-
- pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
-
- if (pbbreg->path >= MAX_RF_PATH_NUMS)
- return NDIS_STATUS_NOT_ACCEPTED;
- if (pbbreg->offset > 0xFF)
- return NDIS_STATUS_NOT_ACCEPTED;
- if (pbbreg->value > 0xFFFFF)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- path = (u8)pbbreg->path;
- offset = (u8)pbbreg->offset;
- value = pbbreg->value;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_write_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n",
- path, offset, value));
-
- _irqlevel_changed_(&oldirql, LOWER);
- write_rfreg(Adapter, path, offset, value);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct rf_reg_param *pbbreg;
- u8 path;
- u8 offset;
- u32 value;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
- int status = NDIS_STATUS_SUCCESS;
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_read_rf_reg_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(struct rf_reg_param))
- return NDIS_STATUS_INVALID_LENGTH;
-
- pbbreg = (struct rf_reg_param *)(poid_par_priv->information_buf);
-
- if (pbbreg->path >= MAX_RF_PATH_NUMS)
- return NDIS_STATUS_NOT_ACCEPTED;
- if (pbbreg->offset > 0xFF)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- path = (u8)pbbreg->path;
- offset = (u8)pbbreg->offset;
-
- _irqlevel_changed_(&oldirql, LOWER);
- value = read_rfreg(Adapter, path, offset);
- _irqlevel_changed_(&oldirql, RAISE);
-
- pbbreg->value = value;
-
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("-rtl8188eu_oid_rt_pro_read_rf_reg_hdl: path=%d offset=0x%02X value=0x%05X\n",
- path, offset, value));
-
-
- return status;
-}
-/* rtl8188eu_oid_rtl_seg_81_87_00 section end**************** */
-/* */
-
-/* rtl8188eu_oid_rtl_seg_81_80_00 section start **************** */
-/* */
-int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 ratevalue;/* 4 */
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("+rtl8188eu_oid_rt_pro_set_data_rate_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- ratevalue = *((u32 *)poid_par_priv->information_buf);/* 4 */
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_set_data_rate_hdl: data rate idx=%d\n", ratevalue));
- if (ratevalue >= MPT_RATE_LAST)
- return NDIS_STATUS_INVALID_DATA;
-
- Adapter->mppriv.rateidx = ratevalue;
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetDataRate(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 mode;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_start_test_hdl\n"));
-
- if (Adapter->registrypriv.mp_mode == 0)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- /* IQCalibrateBcut(Adapter); */
-
- mode = *((u32 *)poid_par_priv->information_buf);
- Adapter->mppriv.mode = mode;/* 1 for loopback */
-
- if (mp_start_test(Adapter) == _FAIL) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- goto exit;
- }
-
-exit:
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_notice_, ("-rtl8188eu_oid_rt_pro_start_test_hdl: mp_mode=%d\n", Adapter->mppriv.mode));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+Set OID_RT_PRO_STOP_TEST\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
- mp_stop_test(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_notice_, ("-Set OID_RT_PRO_STOP_TEST\n"));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 Channel;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl\n"));
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- if (poid_par_priv->type_of_oid == QUERY_OID) {
- *((u32 *)poid_par_priv->information_buf) = Adapter->mppriv.channel;
- return NDIS_STATUS_SUCCESS;
- }
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- Channel = *((u32 *)poid_par_priv->information_buf);
- RT_TRACE(_module_mp_, _drv_notice_, ("rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl: Channel=%d\n", Channel));
- if (Channel > 14)
- return NDIS_STATUS_NOT_ACCEPTED;
- Adapter->mppriv.channel = Channel;
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetChannel(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
-{
- u16 bandwidth;
- u16 channel_offset;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("+rtl8188eu_oid_rt_set_bandwidth_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- bandwidth = *((u32 *)poid_par_priv->information_buf);/* 4 */
- channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- if (bandwidth != HT_CHANNEL_WIDTH_40)
- bandwidth = HT_CHANNEL_WIDTH_20;
- padapter->mppriv.bandwidth = (u8)bandwidth;
- padapter->mppriv.prime_channel_offset = (u8)channel_offset;
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetBandwidth(padapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("-rtl8188eu_oid_rt_set_bandwidth_hdl: bandwidth=%d channel_offset=%d\n",
- bandwidth, channel_offset));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 antenna;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_set_antenna_bb_hdl\n"));
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- if (poid_par_priv->type_of_oid == SET_OID) {
- antenna = *(u32 *)poid_par_priv->information_buf;
-
- Adapter->mppriv.antenna_tx = (u16)((antenna & 0xFFFF0000) >> 16);
- Adapter->mppriv.antenna_rx = (u16)(antenna & 0x0000FFFF);
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_set_antenna_bb_hdl: tx_ant=0x%04x rx_ant=0x%04x\n",
- Adapter->mppriv.antenna_tx, Adapter->mppriv.antenna_rx));
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetAntenna(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
- } else {
- antenna = (Adapter->mppriv.antenna_tx << 16)|Adapter->mppriv.antenna_rx;
- *(u32 *)poid_par_priv->information_buf = antenna;
- }
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 tx_pwr_idx;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_, ("+rtl8188eu_oid_rt_pro_set_tx_power_control_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- tx_pwr_idx = *((u32 *)poid_par_priv->information_buf);
- if (tx_pwr_idx > MAX_TX_PWR_INDEX_N_MODE)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- Adapter->mppriv.txpoweridx = (u8)tx_pwr_idx;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_set_tx_power_control_hdl: idx=0x%2x\n",
- Adapter->mppriv.txpoweridx));
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetTxPower(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-
-/* */
-/* rtl8188eu_oid_rtl_seg_81_80_20 section start **************** */
-/* */
-int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
-
- if (poid_par_priv->information_buf_len == sizeof(u32)) {
- *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.tx_pktcount;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- } else {
- status = NDIS_STATUS_INVALID_LENGTH;
- }
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
- RT_TRACE(_module_mp_, _drv_alert_, ("===> rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl.\n"));
- if (poid_par_priv->information_buf_len == sizeof(u32)) {
- *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_pktcount;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- RT_TRACE(_module_mp_, _drv_alert_, ("recv_ok:%d\n", Adapter->mppriv.rx_pktcount));
- } else {
- status = NDIS_STATUS_INVALID_LENGTH;
- }
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
- RT_TRACE(_module_mp_, _drv_alert_, ("===> rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl.\n"));
- if (poid_par_priv->information_buf_len == sizeof(u32)) {
- *(u32 *)poid_par_priv->information_buf = Adapter->mppriv.rx_crcerrpktcount;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- RT_TRACE(_module_mp_, _drv_alert_, ("recv_err:%d\n", Adapter->mppriv.rx_crcerrpktcount));
- } else {
- status = NDIS_STATUS_INVALID_LENGTH;
- }
-
-
- return status;
-}
-/* */
-
-int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != SET_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
-
- RT_TRACE(_module_mp_, _drv_alert_, ("===> rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl.\n"));
- Adapter->mppriv.tx_pktcount = 0;
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != SET_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
-
- if (poid_par_priv->information_buf_len == sizeof(u32)) {
- Adapter->mppriv.rx_pktcount = 0;
- Adapter->mppriv.rx_crcerrpktcount = 0;
- } else {
- status = NDIS_STATUS_INVALID_LENGTH;
- }
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != SET_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
-
- _irqlevel_changed_(&oldirql, LOWER);
- ResetPhyRxPktCount(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_, ("+rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- _irqlevel_changed_(&oldirql, LOWER);
- *(u32 *)poid_par_priv->information_buf = GetPhyRxPktReceived(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-
- RT_TRACE(_module_mp_, _drv_notice_, ("-rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl: recv_ok=%d\n", *(u32 *)poid_par_priv->information_buf));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_, ("+rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
-
- if (poid_par_priv->information_buf_len != sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- _irqlevel_changed_(&oldirql, LOWER);
- *(u32 *)poid_par_priv->information_buf = GetPhyRxPktCRC32Error(Adapter);
- _irqlevel_changed_(&oldirql, RAISE);
-
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("-rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl: recv_err =%d\n",
- *(u32 *)poid_par_priv->information_buf));
-
-
- return status;
-}
-/* rtl8188eu_oid_rtl_seg_81_80_20 section end **************** */
-int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 bStartTest;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_set_continuous_tx_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- bStartTest = *((u32 *)poid_par_priv->information_buf);
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetContinuousTx(Adapter, (u8)bStartTest);
- if (bStartTest) {
- struct mp_priv *pmp_priv = &Adapter->mppriv;
- if (pmp_priv->tx.stop == 0) {
- pmp_priv->tx.stop = 1;
- DBG_88E("%s: pkt tx is running...\n", __func__);
- msleep(5);
- }
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = 1;
- SetPacketTx(Adapter);
- }
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 bStartTest;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_alert_, ("+rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- bStartTest = *((u32 *)poid_par_priv->information_buf);
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetSingleCarrierTx(Adapter, (u8)bStartTest);
- if (bStartTest) {
- struct mp_priv *pmp_priv = &Adapter->mppriv;
- if (pmp_priv->tx.stop == 0) {
- pmp_priv->tx.stop = 1;
- DBG_88E("%s: pkt tx is running...\n", __func__);
- msleep(5);
- }
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = 1;
- SetPacketTx(Adapter);
- }
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 bStartTest;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- bStartTest = *((u32 *)poid_par_priv->information_buf);
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetCarrierSuppressionTx(Adapter, (u8)bStartTest);
- if (bStartTest) {
- struct mp_priv *pmp_priv = &Adapter->mppriv;
- if (pmp_priv->tx.stop == 0) {
- pmp_priv->tx.stop = 1;
- DBG_88E("%s: pkt tx is running...\n", __func__);
- msleep(5);
- }
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = 1;
- SetPacketTx(Adapter);
- }
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv)
-{
- u32 bStartTest;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_alert_, ("+rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- bStartTest = *((u32 *)poid_par_priv->information_buf);
-
- _irqlevel_changed_(&oldirql, LOWER);
- SetSingleToneTx(Adapter, (u8)bStartTest);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
- int status = NDIS_STATUS_SUCCESS;
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
- rtw_hal_set_hwreg(Adapter, HW_VAR_TRIGGER_GPIO_0, NULL);
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* rtl8188eu_oid_rtl_seg_81_80_00 section end **************** */
-/* */
-int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct mp_rw_reg *RegRWStruct;
- u32 offset, width;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("+rtl8188eu_oid_rt_pro_read_register_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
- offset = RegRWStruct->offset;
- width = RegRWStruct->width;
-
- if (offset > 0xFFF)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- switch (width) {
- case 1:
- RegRWStruct->value = rtw_read8(Adapter, offset);
- break;
- case 2:
- RegRWStruct->value = rtw_read16(Adapter, offset);
- break;
- default:
- width = 4;
- RegRWStruct->value = rtw_read32(Adapter, offset);
- break;
- }
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_read_register_hdl: offset:0x%04X value:0x%X\n",
- offset, RegRWStruct->value));
-
- _irqlevel_changed_(&oldirql, RAISE);
-
- *poid_par_priv->bytes_rw = width;
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct mp_rw_reg *RegRWStruct;
- u32 offset, width, value;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *padapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("+rtl8188eu_oid_rt_pro_write_register_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- RegRWStruct = (struct mp_rw_reg *)poid_par_priv->information_buf;
- offset = RegRWStruct->offset;
- width = RegRWStruct->width;
- value = RegRWStruct->value;
-
- if (offset > 0xFFF)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- switch (RegRWStruct->width) {
- case 1:
- if (value > 0xFF) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
- rtw_write8(padapter, offset, (u8)value);
- break;
- case 2:
- if (value > 0xFFFF) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
- rtw_write16(padapter, offset, (u16)value);
- break;
- case 4:
- rtw_write32(padapter, offset, value);
- break;
- default:
- status = NDIS_STATUS_NOT_ACCEPTED;
- break;
- }
-
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("-rtl8188eu_oid_rt_pro_write_register_hdl: offset=0x%08X width=%d value=0x%X\n",
- offset, width, value));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-/* */
-int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-/* */
-int rtl8188eu_oid_rt_pro_write16_eeprom_hdl (struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
- int status = NDIS_STATUS_SUCCESS;
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+OID_RT_PRO_SET_DATA_RATE_EX\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- if (rtw_setdatarate_cmd(Adapter, poid_par_priv->information_buf) != _SUCCESS)
- status = NDIS_STATUS_NOT_ACCEPTED;
-
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- u8 thermal = 0;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_get_thermal_meter_hdl\n"));
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- _irqlevel_changed_(&oldirql, LOWER);
- GetThermalMeter(Adapter, &thermal);
- _irqlevel_changed_(&oldirql, RAISE);
-
- *(u32 *)poid_par_priv->information_buf = (u32)thermal;
- *poid_par_priv->bytes_rw = sizeof(u32);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
-
- if (poid_par_priv->information_buf_len < sizeof(u8))
- return NDIS_STATUS_INVALID_LENGTH;
-
- _irqlevel_changed_(&oldirql, LOWER);
- if (poid_par_priv->type_of_oid == SET_OID) {
- u8 enable;
-
- enable = *(u8 *)poid_par_priv->information_buf;
- RT_TRACE(_module_mp_, _drv_notice_,
- ("+rtl8188eu_oid_rt_pro_set_power_tracking_hdl: enable =%d\n", enable));
-
- SetPowerTracking(Adapter, enable);
- } else {
- GetPowerTracking(Adapter, (u8 *)poid_par_priv->information_buf);
- }
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-/* */
-int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-/* rtl8188eu_oid_rtl_seg_87_12_00 section start **************** */
-int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
-{
- return NDIS_STATUS_SUCCESS;
-}
-/* */
-int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct efuse_access_struct *pefuse;
- u8 *data;
- u16 addr = 0, cnts = 0, max_available_size = 0;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(struct efuse_access_struct))
- return NDIS_STATUS_INVALID_LENGTH;
-
- pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf;
- addr = pefuse->start_addr;
- cnts = pefuse->cnts;
- data = pefuse->data;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("+rtl8188eu_oid_rt_pro_read_efuse_hd: buf_len=%d addr=%d cnts=%d\n",
- poid_par_priv->information_buf_len, addr, cnts));
-
- EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
-
- if ((addr + cnts) > max_available_size) {
- RT_TRACE(_module_mp_, _drv_err_, ("!rtl8188eu_oid_rt_pro_read_efuse_hdl: parameter error!\n"));
- return NDIS_STATUS_NOT_ACCEPTED;
- }
-
- _irqlevel_changed_(&oldirql, LOWER);
- if (rtw_efuse_access(Adapter, false, addr, cnts, data) == _FAIL) {
- RT_TRACE(_module_mp_, _drv_err_, ("!rtl8188eu_oid_rt_pro_read_efuse_hdl: rtw_efuse_access FAIL!\n"));
- status = NDIS_STATUS_FAILURE;
- } else {
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- }
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct efuse_access_struct *pefuse;
- u8 *data;
- u16 addr = 0, cnts = 0, max_available_size = 0;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- pefuse = (struct efuse_access_struct *)poid_par_priv->information_buf;
- addr = pefuse->start_addr;
- cnts = pefuse->cnts;
- data = pefuse->data;
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("+rtl8188eu_oid_rt_pro_write_efuse_hdl: buf_len=%d addr=0x%04x cnts=%d\n",
- poid_par_priv->information_buf_len, addr, cnts));
-
- EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
-
- if ((addr + cnts) > max_available_size) {
- RT_TRACE(_module_mp_, _drv_err_, ("!rtl8188eu_oid_rt_pro_write_efuse_hdl: parameter error"));
- return NDIS_STATUS_NOT_ACCEPTED;
- }
-
- _irqlevel_changed_(&oldirql, LOWER);
- if (rtw_efuse_access(Adapter, true, addr, cnts, data) == _FAIL)
- status = NDIS_STATUS_FAILURE;
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct pgpkt *ppgpkt;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- *poid_par_priv->bytes_rw = 0;
-
- if (poid_par_priv->information_buf_len < sizeof(struct pgpkt *))
- return NDIS_STATUS_INVALID_LENGTH;
-
- ppgpkt = (struct pgpkt *)poid_par_priv->information_buf;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- if (poid_par_priv->type_of_oid == QUERY_OID) {
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl: Read offset=0x%x\n",\
- ppgpkt->offset));
-
- Efuse_PowerSwitch(Adapter, false, true);
- if (Efuse_PgPacketRead(Adapter, ppgpkt->offset, ppgpkt->data, false) == true)
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- else
- status = NDIS_STATUS_FAILURE;
- Efuse_PowerSwitch(Adapter, false, false);
- } else {
- RT_TRACE(_module_mp_, _drv_notice_,
- ("rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl: Write offset=0x%x word_en=0x%x\n",\
- ppgpkt->offset, ppgpkt->word_en));
-
- Efuse_PowerSwitch(Adapter, true, true);
- if (Efuse_PgPacketWrite(Adapter, ppgpkt->offset, ppgpkt->word_en, ppgpkt->data, false) == true)
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- else
- status = NDIS_STATUS_FAILURE;
- Efuse_PowerSwitch(Adapter, true, false);
- }
-
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("-rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl: status=0x%08X\n", status));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv)
-{
- u16 size;
- u8 ret;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- _irqlevel_changed_(&oldirql, LOWER);
- ret = efuse_GetCurrentSize(Adapter, &size);
- _irqlevel_changed_(&oldirql, RAISE);
- if (ret == _SUCCESS) {
- *(u32 *)poid_par_priv->information_buf = size;
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
- } else {
- status = NDIS_STATUS_FAILURE;
- }
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
-
-
- if (poid_par_priv->type_of_oid != QUERY_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(u32))
- return NDIS_STATUS_INVALID_LENGTH;
-
- *(u32 *)poid_par_priv->information_buf = efuse_GetMaxSize(Adapter);
- *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("-rtl8188eu_oid_rt_get_efuse_max_size_hdl: size=%d status=0x%08X\n",
- *(int *)poid_par_priv->information_buf, status));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status;
-
-
- RT_TRACE(_module_mp_, _drv_info_, ("+rtl8188eu_oid_rt_pro_efuse_hdl\n"));
-
- if (poid_par_priv->type_of_oid == QUERY_OID)
- status = rtl8188eu_oid_rt_pro_read_efuse_hdl(poid_par_priv);
- else
- status = rtl8188eu_oid_rt_pro_write_efuse_hdl(poid_par_priv);
-
- RT_TRACE(_module_mp_, _drv_info_, ("-rtl8188eu_oid_rt_pro_efuse_hdl: status=0x%08X\n", status));
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv)
-{
- u8 *data;
- int status = NDIS_STATUS_SUCCESS;
- struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
- u16 maplen = 0;
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_pro_efuse_map_hdl\n"));
-
- EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&maplen, false);
-
- *poid_par_priv->bytes_rw = 0;
-
- if (poid_par_priv->information_buf_len < maplen)
- return NDIS_STATUS_INVALID_LENGTH;
-
- data = (u8 *)poid_par_priv->information_buf;
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- if (poid_par_priv->type_of_oid == QUERY_OID) {
- RT_TRACE(_module_mp_, _drv_info_,
- ("rtl8188eu_oid_rt_pro_efuse_map_hdl: READ\n"));
-
- if (rtw_efuse_map_read(Adapter, 0, maplen, data) == _SUCCESS) {
- *poid_par_priv->bytes_rw = maplen;
- } else {
- RT_TRACE(_module_mp_, _drv_err_,
- ("rtl8188eu_oid_rt_pro_efuse_map_hdl: READ fail\n"));
- status = NDIS_STATUS_FAILURE;
- }
- } else {
- /* SET_OID */
- RT_TRACE(_module_mp_, _drv_info_,
- ("rtl8188eu_oid_rt_pro_efuse_map_hdl: WRITE\n"));
-
- if (rtw_efuse_map_write(Adapter, 0, maplen, data) == _SUCCESS) {
- *poid_par_priv->bytes_rw = maplen;
- } else {
- RT_TRACE(_module_mp_, _drv_err_,
- ("rtl8188eu_oid_rt_pro_efuse_map_hdl: WRITE fail\n"));
- status = NDIS_STATUS_FAILURE;
- }
- }
-
- _irqlevel_changed_(&oldirql, RAISE);
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("-rtl8188eu_oid_rt_pro_efuse_map_hdl: status=0x%08X\n", status));
-
-
- return status;
-}
-
-int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
- return status;
-}
-
-int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
-{
- u8 rx_pkt_type;
- int status = NDIS_STATUS_SUCCESS;
-
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+rtl8188eu_oid_rt_set_rx_packet_type_hdl\n"));
-
- if (poid_par_priv->type_of_oid != SET_OID)
- return NDIS_STATUS_NOT_ACCEPTED;
-
- if (poid_par_priv->information_buf_len < sizeof(u8))
- return NDIS_STATUS_INVALID_LENGTH;
-
- rx_pkt_type = *((u8 *)poid_par_priv->information_buf);/* 4 */
-
- RT_TRACE(_module_mp_, _drv_info_, ("rx_pkt_type: %x\n", rx_pkt_type));
-
- return status;
-}
-
-int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
-
-int rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
-{
- struct mp_xmit_parm *pparm;
- struct adapter *padapter;
- struct mp_priv *pmp_priv;
- struct pkt_attrib *pattrib;
-
- RT_TRACE(_module_mp_, _drv_notice_, ("+%s\n", __func__));
-
- pparm = (struct mp_xmit_parm *)poid_par_priv->information_buf;
- padapter = (struct adapter *)poid_par_priv->adapter_context;
- pmp_priv = &padapter->mppriv;
-
- if (poid_par_priv->type_of_oid == QUERY_OID) {
- pparm->enable = !pmp_priv->tx.stop;
- pparm->count = pmp_priv->tx.sended;
- } else {
- if (pparm->enable == 0) {
- pmp_priv->tx.stop = 1;
- } else if (pmp_priv->tx.stop == 1) {
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = pparm->count;
- pmp_priv->tx.payload = pparm->payload_type;
- pattrib = &pmp_priv->tx.attrib;
- pattrib->pktlen = pparm->length;
- memcpy(pattrib->dst, pparm->da, ETH_ALEN);
- SetPacketTx(padapter);
- } else {
- return NDIS_STATUS_FAILURE;
- }
- }
-
- return NDIS_STATUS_SUCCESS;
-}
-
-/* */
-int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv)
-{
- int status = NDIS_STATUS_SUCCESS;
-
-
- if (poid_par_priv->type_of_oid != SET_OID) {
- status = NDIS_STATUS_NOT_ACCEPTED;
- return status;
- }
-
- RT_TRACE(_module_mp_, _drv_info_,
- ("\n ===> Setrtl8188eu_oid_rt_set_power_down_hdl.\n"));
-
- _irqlevel_changed_(&oldirql, LOWER);
-
- /* CALL the power_down function */
- _irqlevel_changed_(&oldirql, RAISE);
-
-
- return status;
-}
-/* */
-int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv)
-{
- return 0;
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_p2p.c b/drivers/staging/rtl8188eu/core/rtw_p2p.c
deleted file mode 100644
index 0a15f8cf0d36..000000000000
--- a/drivers/staging/rtl8188eu/core/rtw_p2p.c
+++ /dev/null
@@ -1,2041 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_P2P_C_
-
-#include <drv_types.h>
-#include <rtw_p2p.h>
-#include <wifi.h>
-
-#ifdef CONFIG_88EU_P2P
-
-static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt)
-{
- int found = 0, i = 0;
-
- for (i = 0; i < ch_cnt; i++) {
- if (ch_list[i] == desired_ch) {
- found = 1;
- break;
- }
- }
- return found;
-}
-
-static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- struct list_head *phead, *plist;
- u32 len = 0;
- u16 attr_len = 0;
- u8 tmplen, *pdata_attr, *pstart, *pcur;
- struct sta_info *psta = NULL;
- struct adapter *padapter = pwdinfo->padapter;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- DBG_88E("%s\n", __func__);
-
- pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN);
-
- pstart = pdata_attr;
- pcur = pdata_attr;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- plist = phead->next;
-
- /* look up sta asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
- psta = container_of(plist, struct sta_info, asoc_list);
-
- plist = plist->next;
-
-
- if (psta->is_p2p_device) {
- tmplen = 0;
-
- pcur++;
-
- /* P2P device address */
- memcpy(pcur, psta->dev_addr, ETH_ALEN);
- pcur += ETH_ALEN;
-
- /* P2P interface address */
- memcpy(pcur, psta->hwaddr, ETH_ALEN);
- pcur += ETH_ALEN;
-
- *pcur = psta->dev_cap;
- pcur++;
-
- /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */
- RTW_PUT_BE16(pcur, psta->config_methods);
- pcur += 2;
-
- memcpy(pcur, psta->primary_dev_type, 8);
- pcur += 8;
-
- *pcur = psta->num_of_secdev_type;
- pcur++;
-
- memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8);
- pcur += psta->num_of_secdev_type*8;
-
- if (psta->dev_name_len > 0) {
- /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME);
- pcur += 2;
-
- /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */
- RTW_PUT_BE16(pcur, psta->dev_name_len);
- pcur += 2;
-
- memcpy(pcur, psta->dev_name, psta->dev_name_len);
- pcur += psta->dev_name_len;
- }
-
-
- tmplen = (u8)(pcur-pstart);
-
- *pstart = (tmplen-1);
-
- attr_len += tmplen;
-
- /* pstart += tmplen; */
- pstart = pcur;
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
-
- if (attr_len > 0)
- len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
-
- kfree(pdata_attr);
- return len;
-}
-
-static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_GO_DISC_REQUEST;
- u8 dialogToken = 0;
-
- DBG_88E("[%s]\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- /* Build P2P action frame header */
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
- /* there is no IE in this P2P action frame */
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_DEVDISC_RESP;
- u8 p2pie[8] = { 0x00 };
- u32 p2pielen = 0;
-
- DBG_88E("[%s]\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- /* Build P2P public action frame header */
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
-
- /* Build P2P IE */
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* P2P_ATTR_STATUS */
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-}
-
-static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr, u8 *frame_body, u16 config_method)
-{
- struct adapter *padapter = pwdinfo->padapter;
- unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = P2P_PUB_ACTION_ACTION;
- u8 dialogToken = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PROVISION_DISC_RESP;
- u8 wpsie[100] = { 0x00 };
- u8 wpsielen = 0;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
- wpsielen = 0;
- /* WPS OUI */
- RTW_PUT_BE32(wpsie, WPSOUI);
- wpsielen += 4;
-
- /* Config Method */
- /* Type: */
- RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
- wpsielen += 2;
-
- /* Length: */
- RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
- wpsielen += 2;
-
- /* Value: */
- RTW_PUT_BE16(wpsie + wpsielen, config_method);
- wpsielen += 2;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- __le16 *fctrl;
- struct adapter *padapter = pwdinfo->padapter;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- unsigned char category = RTW_WLAN_CATEGORY_P2P;/* P2P action frame */
- __be32 p2poui = cpu_to_be32(P2POUI);
- u8 oui_subtype = P2P_PRESENCE_RESPONSE;
- u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
- u8 noa_attr_content[32] = { 0x00 };
- u32 p2pielen = 0;
-
- DBG_88E("[%s]\n", __func__);
-
- pmgntframe = alloc_mgtxmitframe(pxmitpriv);
- if (pmgntframe == NULL)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- memcpy(pwlanhdr->addr1, da, ETH_ALEN);
- memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- /* Build P2P action frame header */
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&(p2poui), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
-
-
- /* Add P2P IE header */
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Add Status attribute in P2P IE */
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
-
- /* Add NoA attribute in P2P IE */
- noa_attr_content[0] = 0x1;/* index */
- noa_attr_content[1] = 0x0;/* CTWindow and OppPS Parameters */
-
- /* todo: Notice of Absence Descriptor(s) */
-
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
-
-
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen));
-
-
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-}
-
-u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
- u16 capability = 0;
- u32 len = 0, p2pielen = 0;
- __le16 le_tmp;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
-
- /* According to the P2P Specification, the beacon frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. P2P Device ID */
- /* 3. Notice of Absence (NOA) */
-
- /* P2P Capability ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- /* Be able to participate in additional P2P Groups and */
- /* support the P2P Invitation Procedure */
- /* Group Capability Bitmap, 1 byte */
- capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY;
- capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
- capability |= (P2P_GRPCAP_GROUP_FORMATION<<8);
-
- le_tmp = cpu_to_le16(capability);
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp);
-
- /* P2P Device ID ATTR */
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
-
- /* Notice of Absence ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
-
- pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
- return len;
-}
-
-u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20100907 */
- /* According to the P2P Specification, the probe response frame should contain 5 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Extended Listen Timing */
- /* 3. Notice of Absence (NOA) (Only GO needs this) */
- /* 4. Device Info */
- /* 5. Group Info (Only GO need this) */
-
- /* P2P Capability ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
- RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- p2pie[p2pielen] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
- p2pie[p2pielen] |= P2P_GRPCAP_GROUP_FORMATION;
-
- p2pielen++;
- } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
- }
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */
- RTW_PUT_LE16(p2pie + p2pielen, 0x0004);
- p2pielen += 2;
-
- /* Value: */
- /* Availability Period */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
- RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
- p2pielen += 2;
-
- /* Availability Interval */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
- RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
- p2pielen += 2;
-
-
- /* Notice of Absence ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
-
- /* Device Info ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
- RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */
- RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
- RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
- RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- /* Group Info ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
-
-
- pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
-
- return len;
-}
-
-u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
-{
- u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* Commented by Albert 20110301 */
- /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
- /* 1. P2P Capability */
- /* 2. Device Info */
- /* 3. Group ID (When joining an operating P2P Group) */
-
- /* P2P Capability ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
- RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
- p2pielen += 2;
-
- /* Value: */
- /* Device Capability Bitmap, 1 byte */
- p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
-
- /* Group Capability Bitmap, 1 byte */
- if (pwdinfo->persistent_supported)
- p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
- else
- p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
-
-
- /* Device Info ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
-
- /* Length: */
- /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
- /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
- RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- /* P2P Device Address */
- memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- /* Config Method */
- /* This field should be big endian. Noted by P2P specification. */
- if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) {
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC);
- } else {
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY);
- }
-
- p2pielen += 2;
-
- /* Primary Device Type */
- /* Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
-
- /* OUI */
- /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
- RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
- p2pielen += 4;
-
- /* Sub Category ID */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
-
- /* Number of Secondary Device Types */
- p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
-
- /* Device Name */
- /* Type: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
- RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
- p2pielen += 2;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
- RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
- p2pielen += pwdinfo->device_name_len;
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- /* Added by Albert 2011/05/19 */
- /* In this case, the pdev_raddr is the device address of the group owner. */
-
- /* P2P Group ID ATTR */
- /* Type: */
- p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
-
- /* Length: */
- /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */
- RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen);
- p2pielen += 2;
-
- /* Value: */
- memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN);
- p2pielen += ETH_ALEN;
-
- memcpy(p2pie + p2pielen, pssid, ussidlen);
- p2pielen += ussidlen;
- }
-
- pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
-
- return len;
-}
-
-
-u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
-{
- u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
- u32 len = 0, p2pielen = 0;
-
- /* P2P OUI */
- p2pielen = 0;
- p2pie[p2pielen++] = 0x50;
- p2pie[p2pielen++] = 0x6F;
- p2pie[p2pielen++] = 0x9A;
- p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
-
- /* According to the P2P Specification, the Association response frame should contain 2 P2P attributes */
- /* 1. Status */
- /* 2. Extended Listen Timing (optional) */
-
-
- /* Status ATTR */
- p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
-
-
- /* Extended Listen Timing ATTR */
- /* Type: */
- /* Length: */
- /* Value: */
-
- pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
-
- return len;
-}
-
-u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
-{
- u32 len = 0;
-
- return len;
-}
-
-u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *p;
- u32 ret = false;
- u8 *p2pie;
- u32 p2pielen = 0;
- int ssid_len = 0, rate_cnt = 0;
-
- p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
- len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
-
- if (rate_cnt <= 4) {
- int i, g_rate = 0;
-
- for (i = 0; i < rate_cnt; i++) {
- if (((*(p + 2 + i) & 0xff) != 0x02) &&
- ((*(p + 2 + i) & 0xff) != 0x04) &&
- ((*(p + 2 + i) & 0xff) != 0x0B) &&
- ((*(p + 2 + i) & 0xff) != 0x16))
- g_rate = 1;
- }
-
- if (g_rate == 0) {
- /* There is no OFDM rate included in SupportedRates IE of this probe request frame */
- /* The driver should response this probe request. */
- return ret;
- }
- } else {
- /* rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */
- /* We should proceed the following check for this probe request. */
- }
-
- /* Added comments by Albert 20100906 */
- /* There are several items we should check here. */
- /* 1. This probe request frame must contain the P2P IE. (Done) */
- /* 2. This probe request frame must contain the wildcard SSID. (Done) */
- /* 3. Wildcard BSSID. (Todo) */
- /* 4. Destination Address. (Done in mgt_dispatcher function) */
- /* 5. Requested Device Type in WSC IE. (Todo) */
- /* 6. Device ID attribute in P2P IE. (Todo) */
-
- p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
- len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
-
- ssid_len &= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen);
- if (p2pie) {
- if ((p != NULL) && !memcmp((void *)(p+2), (void *)pwdinfo->p2p_wildcard_ssid , 7)) {
- /* todo: */
- /* Check Requested Device Type attributes in WSC IE. */
- /* Check Device ID attribute in P2P IE */
-
- ret = true;
- } else if ((p != NULL) && (ssid_len == 0)) {
- ret = true;
- }
- } else {
- /* non -p2p device */
- }
- }
-
-
- return ret;
-}
-
-u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
-{
- u8 status_code = P2P_STATUS_SUCCESS;
- u8 *pbuf, *pattr_content = NULL;
- u32 attr_contentlen = 0;
- u16 cap_attr = 0;
- unsigned short frame_type, ie_offset = 0;
- u8 *ies;
- u32 ies_len;
- u8 *p2p_ie;
- u32 p2p_ielen = 0;
- __be16 be_tmp;
- __le16 le_tmp;
-
- if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
- return P2P_STATUS_FAIL_REQUEST_UNABLE;
-
- frame_type = GetFrameSubType(pframe);
- if (frame_type == WIFI_ASSOCREQ)
- ie_offset = _ASOCREQ_IE_OFFSET_;
- else /* WIFI_REASSOCREQ */
- ie_offset = _REASOCREQ_IE_OFFSET_;
-
- ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
- ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
-
- p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen);
-
- if (!p2p_ie) {
- DBG_88E("[%s] P2P IE not Found!!\n", __func__);
- status_code = P2P_STATUS_FAIL_INVALID_PARAM;
- } else {
- DBG_88E("[%s] P2P IE Found!!\n", __func__);
- }
-
- while (p2p_ie) {
- /* Check P2P Capability ATTR */
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) {
- DBG_88E("[%s] Got P2P Capability Attr!!\n", __func__);
- cap_attr = le16_to_cpu(le_tmp);
- psta->dev_cap = cap_attr&0xff;
- }
-
- /* Check Extended Listen Timing ATTR */
-
-
- /* Check P2P Device Info ATTR */
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) {
- DBG_88E("[%s] Got P2P DEVICE INFO Attr!!\n", __func__);
- pattr_content = rtw_zmalloc(attr_contentlen);
- pbuf = pattr_content;
- if (pattr_content) {
- u8 num_of_secdev_type;
- u16 dev_name_len;
-
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint *)&attr_contentlen);
-
- memcpy(psta->dev_addr, pattr_content, ETH_ALEN);/* P2P Device Address */
-
- pattr_content += ETH_ALEN;
-
- memcpy(&be_tmp, pattr_content, 2);/* Config Methods */
- psta->config_methods = be16_to_cpu(be_tmp);
-
- pattr_content += 2;
-
- memcpy(psta->primary_dev_type, pattr_content, 8);
-
- pattr_content += 8;
-
- num_of_secdev_type = *pattr_content;
- pattr_content += 1;
-
- if (num_of_secdev_type == 0) {
- psta->num_of_secdev_type = 0;
- } else {
- u32 len;
-
- psta->num_of_secdev_type = num_of_secdev_type;
-
- len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type*8)) ?
- (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8);
-
- memcpy(psta->secdev_types_list, pattr_content, len);
-
- pattr_content += (num_of_secdev_type*8);
- }
-
-
- psta->dev_name_len = 0;
- if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(__be16 *)pattr_content)) {
- dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content+2));
-
- psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len;
-
- memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len);
- }
- kfree(pbuf);
- }
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
- }
-
- return status_code;
-}
-
-u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *frame_body;
- u8 status, dialogToken;
- struct sta_info *psta = NULL;
- struct adapter *padapter = pwdinfo->padapter;
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 *p2p_ie;
- u32 p2p_ielen = 0;
-
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
-
- dialogToken = frame_body[7];
- status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
-
- p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
- if (p2p_ie) {
- u8 groupid[38] = { 0x00 };
- u8 dev_addr[ETH_ALEN] = { 0x00 };
- u32 attr_contentlen = 0;
-
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
- if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
- !memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len)) {
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) {
- struct list_head *phead, *plist;
-
- spin_lock_bh(&pstapriv->asoc_list_lock);
- phead = &pstapriv->asoc_list;
- plist = phead->next;
-
- /* look up sta asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
- psta = container_of(plist, struct sta_info, asoc_list);
-
- plist = plist->next;
-
- if (psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
- !memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) {
- /* issue GO Discoverability Request */
- issue_group_disc_req(pwdinfo, psta->hwaddr);
- status = P2P_STATUS_SUCCESS;
- break;
- } else {
- status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- }
- }
- spin_unlock_bh(&pstapriv->asoc_list_lock);
- } else {
- status = P2P_STATUS_FAIL_INVALID_PARAM;
- }
- } else {
- status = P2P_STATUS_FAIL_INVALID_PARAM;
- }
- }
- }
-
-
- /* issue Device Discoverability Response */
- issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
-
- return (status == P2P_STATUS_SUCCESS) ? true : false;
-}
-
-u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- return true;
-}
-
-u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *frame_body;
- u8 *wpsie;
- uint wps_ielen = 0, attr_contentlen = 0;
- u16 uconfig_method = 0;
- __be16 be_tmp;
-
- frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
-
- wpsie = rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
- if (wpsie) {
- if (rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen)) {
- uconfig_method = be16_to_cpu(be_tmp);
- switch (uconfig_method) {
- case WPS_CM_DISPLYA:
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
- break;
- case WPS_CM_LABEL:
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3);
- break;
- case WPS_CM_PUSH_BUTTON:
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
- break;
- case WPS_CM_KEYPAD:
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
- break;
- }
- issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
- }
- }
- DBG_88E("[%s] config method = %s\n", __func__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
- return true;
-}
-
-u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe)
-{
- return true;
-}
-
-static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
-{
- u8 i = 0, j = 0;
- u8 temp = 0;
- u8 ch_no = 0;
- ch_content += 3;
- ch_cnt -= 3;
-
- while (ch_cnt > 0) {
- ch_content += 1;
- ch_cnt -= 1;
- temp = *ch_content;
- for (i = 0 ; i < temp ; i++, j++)
- peer_ch_list[j] = *(ch_content + 1 + i);
- ch_content += (temp + 1);
- ch_cnt -= (temp + 1);
- ch_no += temp ;
- }
-
- return ch_no;
-}
-
-static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
-{
- int i = 0, j = 0, temp = 0;
- u8 ch_no = 0;
-
- for (i = 0; i < peer_ch_num; i++) {
- for (j = temp; j < pmlmeext->max_chan_nums; j++) {
- if (*(peer_ch_list + i) == pmlmeext->channel_set[j].ChannelNum) {
- ch_list_inclusioned[ch_no++] = *(peer_ch_list + i);
- temp = j;
- break;
- }
- }
- }
-
- return ch_no;
-}
-
-u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- struct adapter *padapter = pwdinfo->padapter;
- u8 result = P2P_STATUS_SUCCESS;
- u32 p2p_ielen = 0, wps_ielen = 0;
- u8 *ies;
- u32 ies_len;
- u8 *p2p_ie;
- u8 *wpsie;
- u16 wps_devicepassword_id = 0x0000;
- uint wps_devicepassword_id_len = 0;
- __be16 be_tmp;
-
- wpsie = rtw_get_wps_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
- if (wpsie) {
- /* Commented by Kurt 20120113 */
- /* If some device wants to do p2p handshake without sending prov_disc_req */
- /* We have to get peer_req_cm from here. */
- if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
- rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
- wps_devicepassword_id = be16_to_cpu(be_tmp);
-
- if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
- else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
- else
- memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
- }
- } else {
- DBG_88E("[%s] WPS IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- return result;
- }
-
- if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) {
- result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
- return result;
- }
-
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-
- if (!p2p_ie) {
- DBG_88E("[%s] P2P IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
-
- while (p2p_ie) {
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
- u8 ch_content[50] = { 0x00 };
- uint ch_cnt = 0;
- u8 peer_ch_list[50] = { 0x00 };
- u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
- u8 ch_num_inclusioned = 0;
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
-
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen)) {
- DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
- pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
-
- if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
- /* Try to match the tie breaker value */
- if (pwdinfo->intent == P2P_MAX_INTENT) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
- } else {
- if (attr_content & 0x01)
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- else
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Store the group id information. */
- memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
- }
- }
-
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
- if (attr_contentlen != ETH_ALEN)
- _rtw_memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- }
-
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt)) {
- peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
- ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
- if (ch_num_inclusioned == 0) {
- DBG_88E("[%s] No common channel in channel list!\n", __func__);
- result = P2P_STATUS_FAIL_NO_COMMON_CH;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
- ch_list_inclusioned, ch_num_inclusioned)) {
- u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
- attr_contentlen = 0;
-
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- peer_operating_ch = operatingch_info[4];
-
- if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
- ch_list_inclusioned, ch_num_inclusioned)) {
- /**
- * Change our operating channel as peer's for compatibility.
- */
- pwdinfo->operating_channel = peer_operating_ch;
- DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
- } else {
- /* Take first channel of ch_list_inclusioned as operating channel */
- pwdinfo->operating_channel = ch_list_inclusioned[0];
- DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
- }
- }
- }
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
- }
- return result;
-}
-
-u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- struct adapter *padapter = pwdinfo->padapter;
- u8 result = P2P_STATUS_SUCCESS;
- u32 p2p_ielen, wps_ielen;
- u8 *ies;
- u32 ies_len;
- u8 *p2p_ie;
-
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- /* Be able to know which one is the P2P GO and which one is P2P client. */
-
- if (rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) {
- } else {
- DBG_88E("[%s] WPS IE not Found!!\n", __func__);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
-
- p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
- if (!p2p_ie) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
- } else {
- u8 attr_content = 0x00;
- u32 attr_contentlen = 0;
- u8 operatingch_info[5] = { 0x00 };
- u8 groupid[38];
- u8 peer_ch_list[50] = { 0x00 };
- u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
- u8 ch_num_inclusioned = 0;
-
- while (p2p_ie) { /* Found the P2P IE. */
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
- if (attr_contentlen == 1) {
- DBG_88E("[%s] Status = %d\n", __func__, attr_content);
- if (attr_content == P2P_STATUS_SUCCESS) {
- /* Do nothing. */
- } else {
- if (P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content) {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
- } else {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- }
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = attr_content;
- break;
- }
- }
-
- /* Try to get the peer's interface address */
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
- if (attr_contentlen != ETH_ALEN)
- _rtw_memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- }
-
- /* Try to get the peer's intent and tie breaker value. */
- attr_content = 0x00;
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen)) {
- DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
- pwdinfo->peer_intent = attr_content; /* include both intent and tie breaker values. */
-
- if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
- /* Try to match the tie breaker value */
- if (pwdinfo->intent == P2P_MAX_INTENT) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- } else {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- if (attr_content & 0x01)
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- else
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- } else {
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- /* Store the group id information. */
- memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
- }
- }
-
- /* Try to get the operation channel information */
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
- DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
- pwdinfo->peer_operating_ch = operatingch_info[4];
- }
-
- /* Try to get the channel list information */
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) {
- DBG_88E("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len);
-
- peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
- ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
-
- if (ch_num_inclusioned == 0) {
- DBG_88E("[%s] No common channel in channel list!\n", __func__);
- result = P2P_STATUS_FAIL_NO_COMMON_CH;
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
- ch_list_inclusioned, ch_num_inclusioned)) {
- u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
- attr_contentlen = 0;
-
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
- peer_operating_ch = operatingch_info[4];
-
- if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
- ch_list_inclusioned, ch_num_inclusioned)) {
- /**
- * Change our operating channel as peer's for compatibility.
- */
- pwdinfo->operating_channel = peer_operating_ch;
- DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
- } else {
- /* Take first channel of ch_list_inclusioned as operating channel */
- pwdinfo->operating_channel = ch_list_inclusioned[0];
- DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
- }
- }
- }
- } else {
- DBG_88E("[%s] channel list attribute not found!\n", __func__);
- }
-
- /* Try to get the group id information if peer is GO */
- attr_contentlen = 0;
- _rtw_memset(groupid, 0x00, 38);
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
- memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
- }
- }
- return result;
-}
-
-u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *ies;
- u32 ies_len;
- u8 *p2p_ie;
- u32 p2p_ielen = 0;
- u8 result = P2P_STATUS_SUCCESS;
- ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
- ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
- while (p2p_ie) { /* Found the P2P IE. */
- u8 attr_content = 0x00, operatingch_info[5] = { 0x00 };
- u8 groupid[38] = { 0x00 };
- u32 attr_contentlen = 0;
-
- pwdinfo->negotiation_dialog_token = 1;
- rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
- if (attr_contentlen == 1) {
- DBG_88E("[%s] Status = %d\n", __func__, attr_content);
- result = attr_content;
-
- if (attr_content == P2P_STATUS_SUCCESS) {
- u8 bcancelled = 0;
-
- _cancel_timer(&pwdinfo->restore_p2p_state_timer, &bcancelled);
-
- /* Commented by Albert 20100911 */
- /* Todo: Need to handle the case which both Intents are the same. */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1)) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- } else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1)) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- } else {
- /* Have to compare the Tie Breaker */
- if (pwdinfo->peer_intent & 0x01)
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- else
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- }
- } else {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
- break;
- }
- }
-
- /* Try to get the group id information */
- attr_contentlen = 0;
- _rtw_memset(groupid, 0x00, 38);
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
- DBG_88E("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]));
- memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
- memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
- }
-
- attr_contentlen = 0;
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
- DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
- pwdinfo->peer_operating_ch = operatingch_info[4];
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
- }
- return result;
-}
-
-u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
-{
- u8 *frame_body;
- u8 dialogToken = 0;
- u8 status = P2P_STATUS_SUCCESS;
-
- frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
-
- dialogToken = frame_body[6];
-
- /* todo: check NoA attribute */
-
- issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
-
- return true;
-}
-
-static void find_phase_handler(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct ndis_802_11_ssid ssid;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-
- _rtw_memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid));
- memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
- ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
-
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
-
- spin_lock_bh(&pmlmepriv->lock);
- rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0);
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-void p2p_concurrent_handler(struct adapter *padapter);
-
-static void restore_p2p_state_handler(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
- /* In the P2P client mode, the driver should not switch back to its listen channel */
- /* because this P2P client should stay at the operating channel of P2P GO. */
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- }
-}
-
-static void pre_tx_invitereq_handler(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
- set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-static void pre_tx_provdisc_handler(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
- set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-static void pre_tx_negoreq_handler(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- u8 val8 = 1;
-
- set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
-}
-
-void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType)
-{
- switch (intCmdType) {
- case P2P_FIND_PHASE_WK:
- find_phase_handler(padapter);
- break;
- case P2P_RESTORE_STATE_WK:
- restore_p2p_state_handler(padapter);
- break;
- case P2P_PRE_TX_PROVDISC_PROCESS_WK:
- pre_tx_provdisc_handler(padapter);
- break;
- case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
- pre_tx_invitereq_handler(padapter);
- break;
- case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
- pre_tx_negoreq_handler(padapter);
- break;
- }
-
-}
-
-void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
-{
- u8 *ies;
- u32 ies_len;
- u8 *p2p_ie;
- u32 p2p_ielen = 0;
- u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };/* NoA length should be n*(13) + 2 */
- u32 attr_contentlen = 0;
-
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 find_p2p = false, find_p2p_ps = false;
- u8 noa_offset, noa_num, noa_index;
-
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
- if (IELength <= _BEACON_IE_OFFSET_)
- return;
-
- ies = IEs + _BEACON_IE_OFFSET_;
- ies_len = IELength - _BEACON_IE_OFFSET_;
-
- p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
-
- while (p2p_ie) {
- find_p2p = true;
- /* Get Notice of Absence IE. */
- if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) {
- find_p2p_ps = true;
- noa_index = noa_attr[0];
-
- if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
- (noa_index != pwdinfo->noa_index)) { /* if index change, driver should reconfigure related setting. */
- pwdinfo->noa_index = noa_index;
- pwdinfo->opp_ps = noa_attr[1] >> 7;
- pwdinfo->ctwindow = noa_attr[1] & 0x7F;
-
- noa_offset = 2;
- noa_num = 0;
- /* NoA length should be n*(13) + 2 */
- if (attr_contentlen > 2) {
- while (noa_offset < attr_contentlen) {
- /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */
- pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
- noa_offset += 1;
-
- memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
- noa_offset += 4;
-
- noa_num++;
- }
- }
- pwdinfo->noa_num = noa_num;
-
- if (pwdinfo->opp_ps == 1) {
- pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
- /* driver should wait LPS for entering CTWindow */
- if (padapter->pwrctrlpriv.bFwCurrentInPSMode)
- p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
- } else if (pwdinfo->noa_num > 0) {
- pwdinfo->p2p_ps_mode = P2P_PS_NOA;
- p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
- } else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
- p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
- }
- }
-
- break; /* find target, just break. */
- }
-
- /* Get the next P2P IE */
- p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
- }
-
- if (find_p2p) {
- if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && !find_p2p_ps)
- p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
- }
-
-}
-
-void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
-
- /* Pre action for p2p state */
- switch (p2p_ps_state) {
- case P2P_PS_DISABLE:
- pwdinfo->p2p_ps_state = p2p_ps_state;
-
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
-
- pwdinfo->noa_index = 0;
- pwdinfo->ctwindow = 0;
- pwdinfo->opp_ps = 0;
- pwdinfo->noa_num = 0;
- pwdinfo->p2p_ps_mode = P2P_PS_NONE;
- if (padapter->pwrctrlpriv.bFwCurrentInPSMode) {
- if (pwrpriv->smart_ps == 0) {
- pwrpriv->smart_ps = 2;
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
- }
- }
- break;
- case P2P_PS_ENABLE:
- if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
- pwdinfo->p2p_ps_state = p2p_ps_state;
-
- if (pwdinfo->ctwindow > 0) {
- if (pwrpriv->smart_ps != 0) {
- pwrpriv->smart_ps = 0;
- DBG_88E("%s(): Enter CTW, change SmartPS\n", __func__);
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
- }
- }
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
- }
- break;
- case P2P_PS_SCAN:
- case P2P_PS_SCAN_DONE:
- case P2P_PS_ALLSTASLEEP:
- if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
- pwdinfo->p2p_ps_state = p2p_ps_state;
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
- }
- break;
- default:
- break;
- }
-
-}
-
-u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
-{
- struct cmd_obj *ph2c;
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- u8 res = _SUCCESS;
-
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return res;
-
- if (enqueue) {
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
- if (ph2c == NULL) {
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
- if (pdrvextra_cmd_parm == NULL) {
- kfree(ph2c);
- res = _FAIL;
- goto exit;
- }
-
- pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
- pdrvextra_cmd_parm->type_size = p2p_ps_state;
- pdrvextra_cmd_parm->pbuf = NULL;
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
-
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
- } else {
- p2p_ps_wk_hdl(padapter, p2p_ps_state);
- }
-
-exit:
-
-
- return res;
-}
-
-static void reset_ch_sitesurvey_timer_process (void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- DBG_88E("[%s] In\n", __func__);
- /* Reset the operation channel information */
- pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
-}
-
-static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- DBG_88E("[%s] In\n", __func__);
- /* Reset the operation channel information */
- pwdinfo->p2p_info.operation_ch[0] = 0;
- pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-static void restore_p2p_state_timer_process (void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK);
-}
-
-static void pre_tx_scan_timer_process(void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- spin_lock_bh(&pmlmepriv->lock);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
- if (pwdinfo->tx_prov_disc_info.benable) { /* the provision discovery request frame is trigger to send or not */
- p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK);
- /* issue_probereq_p2p(adapter, NULL); */
- /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */
- }
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
- if (pwdinfo->nego_req_info.benable)
- p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK);
- } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
- if (pwdinfo->invitereq_info.benable)
- p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK);
- } else {
- DBG_88E("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo));
- }
-
- spin_unlock_bh(&pmlmepriv->lock);
-}
-
-static void find_phase_timer_process(void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
- struct wifidirect_info *pwdinfo = &adapter->wdinfo;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-
- adapter->wdinfo.find_phase_state_exchange_cnt++;
-
- p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK);
-}
-
-void reset_global_wifidirect_info(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo;
-
- pwdinfo = &padapter->wdinfo;
- pwdinfo->persistent_supported = 0;
- pwdinfo->session_available = true;
- pwdinfo->wfd_tdls_enable = 0;
- pwdinfo->wfd_tdls_weaksec = 0;
-}
-
-void rtw_init_wifidirect_timers(struct adapter *padapter)
-{
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- _init_timer(&pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter);
- _init_timer(&pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter);
- _init_timer(&pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter);
- _init_timer(&pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter);
- _init_timer(&pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter);
-}
-
-void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr)
-{
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- /*init device&interface address */
- if (dev_addr)
- memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
- if (iface_addr)
- memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
-#endif
-}
-
-void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
-{
- struct wifidirect_info *pwdinfo;
-
- pwdinfo = &padapter->wdinfo;
- pwdinfo->padapter = padapter;
-
- /* 1, 6, 11 are the social channel defined in the WiFi Direct specification. */
- pwdinfo->social_chan[0] = 1;
- pwdinfo->social_chan[1] = 6;
- pwdinfo->social_chan[2] = 11;
- pwdinfo->social_chan[3] = 0; /* channel 0 for scanning ending in site survey function. */
-
- /* Use the channel 11 as the listen channel */
- pwdinfo->listen_channel = 11;
-
- if (role == P2P_ROLE_DEVICE) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
- pwdinfo->intent = 1;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
- } else if (role == P2P_ROLE_CLIENT) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- pwdinfo->intent = 1;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- } else if (role == P2P_ROLE_GO) {
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
- pwdinfo->intent = 15;
- rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
- }
-
-/* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
- pwdinfo->support_rate[0] = 0x8c; /* 6(B) */
- pwdinfo->support_rate[1] = 0x92; /* 9(B) */
- pwdinfo->support_rate[2] = 0x18; /* 12 */
- pwdinfo->support_rate[3] = 0x24; /* 18 */
- pwdinfo->support_rate[4] = 0x30; /* 24 */
- pwdinfo->support_rate[5] = 0x48; /* 36 */
- pwdinfo->support_rate[6] = 0x60; /* 48 */
- pwdinfo->support_rate[7] = 0x6c; /* 54 */
-
- memcpy(pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7);
-
- _rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
- pwdinfo->device_name_len = 0;
-
- _rtw_memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info));
- pwdinfo->invitereq_info.token = 3; /* Token used for P2P invitation request frame. */
-
- _rtw_memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info));
- pwdinfo->inviteresp_info.token = 0;
-
- pwdinfo->profileindex = 0;
- _rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
-
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
-
- pwdinfo->listen_dwell = (u8) ((jiffies % 3) + 1);
-
- _rtw_memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info));
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
-
- _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
-
- pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
- pwdinfo->negotiation_dialog_token = 1;
-
- _rtw_memset(pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN);
- pwdinfo->nego_ssidlen = 0;
-
- pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
- pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
- pwdinfo->channel_list_attr_len = 0;
- _rtw_memset(pwdinfo->channel_list_attr, 0x00, 100);
-
- _rtw_memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4);
- _rtw_memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3);
- _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
- pwdinfo->wfd_tdls_enable = 0;
- _rtw_memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
- _rtw_memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN);
-
- pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
- pwdinfo->rx_invitereq_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */
- pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
- pwdinfo->p2p_info.operation_ch[0] = 0;
- pwdinfo->p2p_info.operation_ch[1] = 0; /* Used to indicate the scan end in site survey function */
- pwdinfo->p2p_info.scan_op_ch_only = 0;
-}
-
-int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
-{
- int ret = _SUCCESS;
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) {
- /* leave IPS/Autosuspend */
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = _FAIL;
- goto exit;
- }
-
- /* Added by Albert 2011/03/22 */
- /* In the P2P mode, the driver should not support the b mode. */
- /* So, the Tx packet shouldn't use the CCK rate */
- update_tx_basic_rate(padapter, WIRELESS_11AGN);
-
- /* Enable P2P function */
- init_wifidirect_info(padapter, role);
-
- rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, true);
- } else if (role == P2P_ROLE_DISABLE) {
- if (_FAIL == rtw_pwr_wakeup(padapter)) {
- ret = _FAIL;
- goto exit;
- }
-
- /* Disable P2P function */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- del_timer_sync(&pwdinfo->find_phase_timer);
- del_timer_sync(&pwdinfo->restore_p2p_state_timer);
- del_timer_sync(&pwdinfo->pre_tx_scan_timer);
- del_timer_sync(&pwdinfo->reset_ch_sitesurvey);
- del_timer_sync(&pwdinfo->reset_ch_sitesurvey2);
- reset_ch_sitesurvey_timer_process(padapter);
- reset_ch_sitesurvey_timer_process2(padapter);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
- rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
- _rtw_memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
- }
-
- rtw_hal_set_odm_var(padapter, HAL_ODM_P2P_STATE, NULL, false);
-
- /* Restore to initial setting. */
- update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
- }
-
-exit:
- return ret;
-}
-
-#else
-u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
-{
- return _FAIL;
-}
-
-void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
-{
-}
-
-#endif /* CONFIG_88EU_P2P */
diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
index 739e25041692..27ed83cca193 100644
--- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
@@ -22,8 +22,111 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <osdep_intf.h>
+#include <usb_ops_linux.h>
#include <linux/usb.h>
+static int rtw_hw_suspend(struct adapter *padapter)
+{
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct net_device *pnetdev = padapter->pnetdev;
+
+
+ if ((!padapter->bup) || (padapter->bDriverStopped) ||
+ (padapter->bSurpriseRemoved)) {
+ DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
+ padapter->bup, padapter->bDriverStopped,
+ padapter->bSurpriseRemoved);
+ goto error_exit;
+ }
+
+ /* system suspend */
+ LeaveAllPowerSaveMode(padapter);
+
+ DBG_88E("==> rtw_hw_suspend\n");
+ _enter_pwrlock(&pwrpriv->lock);
+ pwrpriv->bips_processing = true;
+ /* s1. */
+ if (pnetdev) {
+ netif_carrier_off(pnetdev);
+ netif_tx_stop_all_queues(pnetdev);
+ }
+
+ /* s2. */
+ rtw_disassoc_cmd(padapter, 500, false);
+
+ /* s2-2. indicate disconnect to os */
+ {
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ _clr_fwstate_(pmlmepriv, _FW_LINKED);
+
+ rtw_led_control(padapter, LED_CTL_NO_LINK);
+
+ rtw_os_indicate_disconnect(padapter);
+
+ /* donnot enqueue cmd */
+ rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0);
+ }
+ }
+ /* s2-3. */
+ rtw_free_assoc_resources(padapter, 1);
+
+ /* s2-4. */
+ rtw_free_network_queue(padapter, true);
+ rtw_ips_dev_unload(padapter);
+ pwrpriv->rf_pwrstate = rf_off;
+ pwrpriv->bips_processing = false;
+
+ _exit_pwrlock(&pwrpriv->lock);
+
+ return 0;
+
+error_exit:
+ DBG_88E("%s, failed\n", __func__);
+ return -1;
+}
+
+static int rtw_hw_resume(struct adapter *padapter)
+{
+ struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct net_device *pnetdev = padapter->pnetdev;
+
+
+ /* system resume */
+ DBG_88E("==> rtw_hw_resume\n");
+ _enter_pwrlock(&pwrpriv->lock);
+ pwrpriv->bips_processing = true;
+ rtw_reset_drv_sw(padapter);
+
+ if (pm_netdev_open(pnetdev, false) != 0) {
+ _exit_pwrlock(&pwrpriv->lock);
+ goto error_exit;
+ }
+
+ netif_device_attach(pnetdev);
+ netif_carrier_on(pnetdev);
+
+ if (!netif_queue_stopped(pnetdev))
+ netif_start_queue(pnetdev);
+ else
+ netif_wake_queue(pnetdev);
+
+ pwrpriv->bkeepfwalive = false;
+ pwrpriv->brfoffbyhw = false;
+
+ pwrpriv->rf_pwrstate = rf_on;
+ pwrpriv->bips_processing = false;
+
+ _exit_pwrlock(&pwrpriv->lock);
+
+
+ return 0;
+error_exit:
+ DBG_88E("%s, Open net dev failed\n", __func__);
+ return -1;
+}
+
void ips_enter(struct adapter *padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
@@ -100,7 +203,7 @@ int ips_leave(struct adapter *padapter)
}
}
- DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+ DBG_88E("==> ips_leave.....LED(0x%08x)...\n", usb_read32(padapter, 0x4c));
pwrpriv->bips_processing = false;
pwrpriv->bkeepfwalive = false;
@@ -114,12 +217,7 @@ int ips_leave(struct adapter *padapter)
static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
{
- struct adapter *buddy = adapter->pbuddy_adapter;
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
-#endif
-
bool ret = false;
if (time_after_eq(adapter->pwrctrlpriv.ips_deny_time, jiffies))
@@ -128,32 +226,9 @@ static bool rtw_pwr_unassociated_idle(struct adapter *adapter)
if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
check_fwstate(pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
check_fwstate(pmlmepriv, WIFI_AP_STATE) ||
- check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) ||
-#if defined(CONFIG_88EU_P2P)
- !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
-#else
- 0)
-#endif
+ check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE))
goto exit;
- /* consider buddy, if exist */
- if (buddy) {
- struct mlme_priv *b_pmlmepriv = &(buddy->mlmepriv);
- #ifdef CONFIG_88EU_P2P
- struct wifidirect_info *b_pwdinfo = &(buddy->wdinfo);
- #endif
-
- if (check_fwstate(b_pmlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
- check_fwstate(b_pmlmepriv, WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
- check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
- check_fwstate(b_pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) ||
-#if defined(CONFIG_88EU_P2P)
- !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE))
-#else
- 0)
-#endif
- goto exit;
- }
ret = true;
exit:
@@ -179,7 +254,6 @@ void rtw_ps_processor(struct adapter *padapter)
if (rfpwrstate == rf_off) {
pwrpriv->change_rfpwrstate = rf_off;
pwrpriv->brfoffbyhw = true;
- padapter->bCardDisableWOHSM = true;
rtw_hw_suspend(padapter);
} else {
pwrpriv->change_rfpwrstate = rf_on;
@@ -304,9 +378,6 @@ static u8 PS_RDY_CHECK(struct adapter *padapter)
void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_notice_,
("%s: PowerMode=%d Smart_PS=%d\n",
@@ -328,16 +399,6 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a
/* if (pwrpriv->pwr_mode == PS_MODE_ACTIVE) */
if (ps_mode == PS_MODE_ACTIVE) {
-#ifdef CONFIG_88EU_P2P
- if (pwdinfo->opp_ps == 0) {
- DBG_88E("rtw_set_ps_mode: Leave 802.11 power save\n");
- pwrpriv->pwr_mode = ps_mode;
- rtw_set_rpwm(padapter, PS_STATE_S4);
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
- pwrpriv->bFwCurrentInPSMode = false;
- }
- } else {
-#endif /* CONFIG_88EU_P2P */
if (PS_RDY_CHECK(padapter)) {
DBG_88E("%s: Enter 802.11 power save\n", __func__);
pwrpriv->bFwCurrentInPSMode = true;
@@ -345,13 +406,6 @@ void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_a
pwrpriv->smart_ps = smart_ps;
pwrpriv->bcn_ant_mode = bcn_ant_mode;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
-
-#ifdef CONFIG_88EU_P2P
- /* Set CTWindow after LPS */
- if (pwdinfo->opp_ps == 1)
- p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0);
-#endif /* CONFIG_88EU_P2P */
-
rtw_set_rpwm(padapter, PS_STATE_S2);
}
}
@@ -448,11 +502,8 @@ void LeaveAllPowerSaveMode(struct adapter *Adapter)
struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
u8 enqueue = 0;
- if (check_fwstate(pmlmepriv, _FW_LINKED)) { /* connect */
- p2p_ps_wk_cmd(Adapter, P2P_PS_DISABLE, enqueue);
-
+ if (check_fwstate(pmlmepriv, _FW_LINKED))
rtw_lps_ctrl_wk_cmd(Adapter, LPS_CTRL_LEAVE, enqueue);
- }
}
void rtw_init_pwrctrl_priv(struct adapter *padapter)
@@ -500,7 +551,7 @@ void rtw_init_pwrctrl_priv(struct adapter *padapter)
inline void rtw_set_ips_deny(struct adapter *padapter, u32 ms)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ms);
+ pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ms);
}
/*
@@ -517,9 +568,9 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
unsigned long expires;
int ret = _SUCCESS;
- expires = jiffies + rtw_ms_to_systime(ips_deffer_ms);
+ expires = jiffies + msecs_to_jiffies(ips_deffer_ms);
if (time_before(pwrpriv->ips_deny_time, expires))
- pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
+ pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
{
u32 start = jiffies;
@@ -573,9 +624,9 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal
}
exit:
- expires = jiffies + rtw_ms_to_systime(ips_deffer_ms);
+ expires = jiffies + msecs_to_jiffies(ips_deffer_ms);
if (time_before(pwrpriv->ips_deny_time, expires))
- pwrpriv->ips_deny_time = jiffies + rtw_ms_to_systime(ips_deffer_ms);
+ pwrpriv->ips_deny_time = jiffies + msecs_to_jiffies(ips_deffer_ms);
return ret;
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 0e73df5975b8..4d56dbad2a7d 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -23,7 +23,6 @@
#include <drv_types.h>
#include <recv_osdep.h>
#include <mlme_osdep.h>
-#include <usb_ops.h>
#include <wifi.h>
#include <linux/vmalloc.h>
@@ -47,7 +46,7 @@ void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS);
void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
{
- _rtw_memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv));
+ memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv));
spin_lock_init(&psta_recvpriv->lock);
@@ -83,9 +82,9 @@ int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
precvframe = (struct recv_frame *)precvpriv->precv_frame_buf;
for (i = 0; i < NR_RECVFRAME; i++) {
- _rtw_init_listhead(&(precvframe->list));
+ INIT_LIST_HEAD(&(precvframe->list));
- rtw_list_insert_tail(&(precvframe->list),
+ list_add_tail(&(precvframe->list),
&(precvpriv->free_recv_queue.queue));
res = rtw_os_recv_resource_alloc(padapter, precvframe);
@@ -132,7 +131,7 @@ struct recv_frame *_rtw_alloc_recvframe (struct __queue *pfree_recv_queue)
struct adapter *padapter;
struct recv_priv *precvpriv;
- if (_rtw_queue_empty(pfree_recv_queue)) {
+ if (list_empty(&pfree_recv_queue->queue)) {
hdr = NULL;
} else {
phead = get_list_head(pfree_recv_queue);
@@ -141,7 +140,7 @@ struct recv_frame *_rtw_alloc_recvframe (struct __queue *pfree_recv_queue)
hdr = container_of(plist, struct recv_frame, list);
- rtw_list_delete(&hdr->list);
+ list_del_init(&hdr->list);
padapter = hdr->adapter;
if (padapter != NULL) {
precvpriv = &padapter->recvpriv;
@@ -170,7 +169,7 @@ struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
void rtw_init_recvframe(struct recv_frame *precvframe, struct recv_priv *precvpriv)
{
/* Perry: This can be removed */
- _rtw_init_listhead(&precvframe->list);
+ INIT_LIST_HEAD(&precvframe->list);
precvframe->len = 0;
}
@@ -192,11 +191,11 @@ int rtw_free_recvframe(struct recv_frame *precvframe,
spin_lock_bh(&pfree_recv_queue->lock);
- rtw_list_delete(&(precvframe->list));
+ list_del_init(&(precvframe->list));
precvframe->len = 0;
- rtw_list_insert_tail(&(precvframe->list), get_list_head(pfree_recv_queue));
+ list_add_tail(&(precvframe->list), get_list_head(pfree_recv_queue));
if (padapter != NULL) {
if (pfree_recv_queue == &precvpriv->free_recv_queue)
@@ -215,8 +214,8 @@ int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
struct recv_priv *precvpriv = &padapter->recvpriv;
- rtw_list_delete(&(precvframe->list));
- rtw_list_insert_tail(&(precvframe->list), get_list_head(queue));
+ list_del_init(&(precvframe->list));
+ list_add_tail(&(precvframe->list), get_list_head(queue));
if (padapter != NULL) {
if (queue == &precvpriv->free_recv_queue)
@@ -256,7 +255,7 @@ void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfre
phead = get_list_head(pframequeue);
plist = phead->next;
- while (rtw_end_of_queue_search(phead, plist) == false) {
+ while (phead != plist) {
hdr = container_of(plist, struct recv_frame, list);
plist = plist->next;
@@ -790,10 +789,6 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
if (*psta == NULL) {
RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n"));
- if (adapter->registrypriv.mp_mode == 1) {
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
- adapter->mppriv.rx_pktloss++;
- }
ret = _FAIL;
goto exit;
}
@@ -1040,12 +1035,12 @@ static int validate_recv_ctrl_frame(struct adapter *padapter,
xmitframe_phead = get_list_head(&psta->sleep_q);
xmitframe_plist = xmitframe_phead->next;
- if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == false) {
+ if (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
psta->sleepq_len--;
@@ -1455,7 +1450,7 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter,
plist = phead->next;
pfhdr = container_of(plist, struct recv_frame, list);
prframe = (struct recv_frame *)pfhdr;
- rtw_list_delete(&(prframe->list));
+ list_del_init(&(prframe->list));
if (curfragnum != pfhdr->attrib.frag_num) {
/* the first fragment number must be 0 */
@@ -1472,7 +1467,7 @@ static struct recv_frame *recvframe_defrag(struct adapter *adapter,
plist = plist->next;
- while (rtw_end_of_queue_search(phead, plist) == false) {
+ while (phead != plist) {
pnfhdr = container_of(plist, struct recv_frame, list);
pnextrframe = (struct recv_frame *)pnfhdr;
@@ -1564,7 +1559,7 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter,
if (pdefrag_q != NULL) {
if (fragnum == 0) {
/* the first fragment */
- if (_rtw_queue_empty(pdefrag_q) == false) {
+ if (!list_empty(&pdefrag_q->queue)) {
/* free current defrag_q */
rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
}
@@ -1573,7 +1568,7 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter,
/* Then enqueue the 0~(n-1) fragment into the defrag_q */
phead = get_list_head(pdefrag_q);
- rtw_list_insert_tail(&pfhdr->list, phead);
+ list_add_tail(&pfhdr->list, phead);
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Enqueuq: ismfrag=%d, fragnum=%d\n", ismfrag, fragnum));
@@ -1591,7 +1586,7 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter,
/* enqueue the last fragment */
if (pdefrag_q != NULL) {
phead = get_list_head(pdefrag_q);
- rtw_list_insert_tail(&pfhdr->list, phead);
+ list_add_tail(&pfhdr->list, phead);
/* call recvframe_defrag to defrag */
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("defrag: ismfrag=%d, fragnum=%d\n", ismfrag, fragnum));
@@ -1645,7 +1640,7 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
while (a_len > ETH_HLEN) {
/* Offset 12 denote 2 mac address */
- nSubframe_Length = RTW_GET_BE16(pdata + 12);
+ nSubframe_Length = get_unaligned_be16(pdata + 12);
if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
DBG_88E("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
@@ -1700,7 +1695,7 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
for (i = 0; i < nr_subframes; i++) {
sub_skb = subframes[i];
/* convert hdr + possible LLC headers into Ethernet header */
- eth_type = RTW_GET_BE16(&sub_skb->data[6]);
+ eth_type = get_unaligned_be16(&sub_skb->data[6]);
if (sub_skb->len >= 8 &&
((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
@@ -1778,7 +1773,7 @@ static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl,
phead = get_list_head(ppending_recvframe_queue);
plist = phead->next;
- while (rtw_end_of_queue_search(phead, plist) == false) {
+ while (phead != plist) {
hdr = container_of(plist, struct recv_frame, list);
pnextattrib = &hdr->attrib;
@@ -1790,9 +1785,9 @@ static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl,
break;
}
- rtw_list_delete(&(prframe->list));
+ list_del_init(&(prframe->list));
- rtw_list_insert_tail(&(prframe->list), plist);
+ list_add_tail(&(prframe->list), plist);
return true;
}
@@ -1811,7 +1806,7 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor
/* Handling some condition for forced indicate case. */
if (bforced) {
- if (rtw_is_list_empty(phead))
+ if (list_empty(phead))
return true;
prhdr = container_of(plist, struct recv_frame, list);
@@ -1821,7 +1816,7 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor
/* Prepare indication list and indication. */
/* Check if there is any packet need indicate. */
- while (!rtw_is_list_empty(phead)) {
+ while (!list_empty(phead)) {
prhdr = container_of(plist, struct recv_frame, list);
prframe = (struct recv_frame *)prhdr;
pattrib = &prframe->attrib;
@@ -1831,7 +1826,7 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor
("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n",
preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu));
plist = plist->next;
- rtw_list_delete(&(prframe->list));
+ list_del_init(&(prframe->list));
if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num))
preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
@@ -2013,25 +2008,7 @@ static int recv_func_prehandle(struct adapter *padapter,
struct recv_frame *rframe)
{
int ret = _SUCCESS;
- struct rx_pkt_attrib *pattrib = &rframe->attrib;
struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (padapter->registrypriv.mp_mode == 1) {
- if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) { /* padapter->mppriv.check_mp_pkt == 0)) */
- if (pattrib->crc_err == 1)
- padapter->mppriv.rx_crcerrpktcount++;
- else
- padapter->mppriv.rx_pktcount++;
-
- if (check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE) == false) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("MP - Not in loopback mode , drop pkt\n"));
- ret = _FAIL;
- rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
- goto exit;
- }
- }
- }
/* check the frame crtl field and decache */
ret = validate_recv_frame(padapter, rframe);
@@ -2152,11 +2129,6 @@ s32 rtw_recv_entry(struct recv_frame *precvframe)
return ret;
_recv_entry_drop:
-
- if (padapter->registrypriv.mp_mode == 1)
- padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
-
-
return ret;
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c
index 05335959b543..f9096a512da5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -189,7 +189,7 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe)
arcfour_encrypt(&mycontext, payload+length, crc, 4);
pframe += pxmitpriv->frag_len;
- pframe = (u8 *)RND4((size_t)(pframe));
+ pframe = (u8 *) round_up((size_t)(pframe), 4);
}
}
}
@@ -628,7 +628,7 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe)
arcfour_encrypt(&mycontext, payload+length, crc, 4);
pframe += pxmitpriv->frag_len;
- pframe = (u8 *)RND4((size_t)(pframe));
+ pframe = (u8 *) round_up((size_t)(pframe), 4);
}
}
} else {
@@ -1081,13 +1081,13 @@ static int aes_cipher(u8 *key, uint hdrlen, u8 *pframe, uint plen)
frsubtype = frsubtype>>4;
- _rtw_memset((void *)mic_iv, 0, 16);
- _rtw_memset((void *)mic_header1, 0, 16);
- _rtw_memset((void *)mic_header2, 0, 16);
- _rtw_memset((void *)ctr_preload, 0, 16);
- _rtw_memset((void *)chain_buffer, 0, 16);
- _rtw_memset((void *)aes_out, 0, 16);
- _rtw_memset((void *)padded_buffer, 0, 16);
+ memset((void *)mic_iv, 0, 16);
+ memset((void *)mic_header1, 0, 16);
+ memset((void *)mic_header2, 0, 16);
+ memset((void *)ctr_preload, 0, 16);
+ memset((void *)chain_buffer, 0, 16);
+ memset((void *)aes_out, 0, 16);
+ memset((void *)padded_buffer, 0, 16);
if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN))
a4_exists = 0;
@@ -1242,7 +1242,7 @@ u32 rtw_aes_encrypt(struct adapter *padapter, u8 *pxmitframe)
aes_cipher(prwskey, pattrib->hdrlen, pframe, length);
pframe += pxmitpriv->frag_len;
- pframe = (u8 *)RND4((size_t)(pframe));
+ pframe = (u8 *) round_up((size_t)(pframe), 8);
}
}
} else{
@@ -1279,13 +1279,13 @@ static int aes_decipher(u8 *key, uint hdrlen,
uint frsubtype = GetFrameSubType(pframe);
frsubtype = frsubtype>>4;
- _rtw_memset((void *)mic_iv, 0, 16);
- _rtw_memset((void *)mic_header1, 0, 16);
- _rtw_memset((void *)mic_header2, 0, 16);
- _rtw_memset((void *)ctr_preload, 0, 16);
- _rtw_memset((void *)chain_buffer, 0, 16);
- _rtw_memset((void *)aes_out, 0, 16);
- _rtw_memset((void *)padded_buffer, 0, 16);
+ memset((void *)mic_iv, 0, 16);
+ memset((void *)mic_header1, 0, 16);
+ memset((void *)mic_header2, 0, 16);
+ memset((void *)ctr_preload, 0, 16);
+ memset((void *)chain_buffer, 0, 16);
+ memset((void *)aes_out, 0, 16);
+ memset((void *)padded_buffer, 0, 16);
/* start to decrypt the payload */
@@ -1679,28 +1679,3 @@ do { \
d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]; \
} while (0);
-
-/**
- * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
- * @key: 128-bit key for the hash operation
- * @data: Data buffer for which a MAC is determined
- * @data_len: Length of data buffer in bytes
- * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
- * Returns: 0 on success, -1 on failure
- *
- * This is a mode for using block cipher (AES in this case) for authentication.
- * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
- * (SP) 800-38B.
- */
-void rtw_use_tkipkey_handler(void *FunctionContext)
-{
- struct adapter *padapter = (struct adapter *)FunctionContext;
-
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("^^^rtw_use_tkipkey_handler ^^^\n"));
-
- padapter->securitypriv.busetkipkey = true;
-
- RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("^^^rtw_use_tkipkey_handler padapter->securitypriv.busetkipkey=%d^^^\n", padapter->securitypriv.busetkipkey));
-
-}
diff --git a/drivers/staging/rtl8188eu/core/rtw_sreset.c b/drivers/staging/rtl8188eu/core/rtw_sreset.c
index ee20d4ad004f..cd4e344e6ffd 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sreset.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sreset.c
@@ -19,27 +19,14 @@
******************************************************************************/
#include <rtw_sreset.h>
+#include <usb_ops_linux.h>
void sreset_init_value(struct adapter *padapter)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
- mutex_init(&psrtpriv->silentreset_mutex);
- psrtpriv->silent_reset_inprogress = false;
psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
- psrtpriv->last_tx_time = 0;
- psrtpriv->last_tx_complete_time = 0;
-}
-void sreset_reset_value(struct adapter *padapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- psrtpriv->silent_reset_inprogress = false;
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
- psrtpriv->last_tx_time = 0;
- psrtpriv->last_tx_complete_time = 0;
}
u8 sreset_get_wifi_status(struct adapter *padapter)
@@ -50,9 +37,7 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
u8 status = WIFI_STATUS_SUCCESS;
u32 val32 = 0;
- if (psrtpriv->silent_reset_inprogress)
- return status;
- val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+ val32 = usb_read32(padapter, REG_TXDMA_STATUS);
if (val32 == 0xeaeaeaea) {
psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
} else if (val32 != 0) {
diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index 2d0b60686a01..e1dc8fa82d38 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -29,11 +29,11 @@
static void _rtw_init_stainfo(struct sta_info *psta)
{
- _rtw_memset((u8 *)psta, 0, sizeof (struct sta_info));
+ memset((u8 *)psta, 0, sizeof (struct sta_info));
spin_lock_init(&psta->lock);
- _rtw_init_listhead(&psta->list);
- _rtw_init_listhead(&psta->hash_list);
+ INIT_LIST_HEAD(&psta->list);
+ INIT_LIST_HEAD(&psta->hash_list);
_rtw_init_queue(&psta->sleep_q);
psta->sleepq_len = 0;
@@ -42,9 +42,9 @@ static void _rtw_init_stainfo(struct sta_info *psta)
#ifdef CONFIG_88EU_AP_MODE
- _rtw_init_listhead(&psta->asoc_list);
+ INIT_LIST_HEAD(&psta->asoc_list);
- _rtw_init_listhead(&psta->auth_list);
+ INIT_LIST_HEAD(&psta->auth_list);
psta->expire_to = 0;
@@ -98,9 +98,9 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
for (i = 0; i < NUM_STA; i++) {
_rtw_init_stainfo(psta);
- _rtw_init_listhead(&(pstapriv->sta_hash[i]));
+ INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
- rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
+ list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
psta++;
}
@@ -110,8 +110,8 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
pstapriv->sta_dz_bitmap = 0;
pstapriv->tim_bitmap = 0;
- _rtw_init_listhead(&pstapriv->asoc_list);
- _rtw_init_listhead(&pstapriv->auth_list);
+ INIT_LIST_HEAD(&pstapriv->asoc_list);
+ INIT_LIST_HEAD(&pstapriv->auth_list);
spin_lock_init(&pstapriv->asoc_list_lock);
spin_lock_init(&pstapriv->auth_list_lock);
pstapriv->asoc_list_cnt = 0;
@@ -157,7 +157,7 @@ static void rtw_mfree_all_stainfo(struct sta_priv *pstapriv)
phead = get_list_head(&pstapriv->free_sta_queue);
plist = phead->next;
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info , list);
plist = plist->next;
}
@@ -185,7 +185,7 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
phead = &(pstapriv->sta_hash[index]);
plist = phead->next;
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
+ while (phead != plist) {
int i;
psta = container_of(plist, struct sta_info , hash_list);
plist = plist->next;
@@ -223,12 +223,12 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
spin_lock_bh(&(pfree_sta_queue->lock));
- if (_rtw_queue_empty(pfree_sta_queue) == true) {
+ if (list_empty(&pfree_sta_queue->queue)) {
spin_unlock_bh(&pfree_sta_queue->lock);
psta = NULL;
} else {
psta = container_of((&pfree_sta_queue->queue)->next, struct sta_info, list);
- rtw_list_delete(&(psta->list));
+ list_del_init(&(psta->list));
spin_unlock_bh(&pfree_sta_queue->lock);
_rtw_init_stainfo(psta);
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
@@ -243,7 +243,7 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
spin_lock_bh(&(pstapriv->sta_hash_lock));
- rtw_list_insert_tail(&psta->hash_list, phash_list);
+ list_add_tail(&psta->hash_list, phash_list);
pstapriv->asoc_sta_count++;
@@ -317,23 +317,23 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->be_q.tx_pending));
spin_unlock_bh(&pxmitpriv->lock);
- rtw_list_delete(&psta->hash_list);
+ list_del_init(&psta->hash_list);
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("\n free number_%d stainfo with hwaddr=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4], psta->hwaddr[5]));
pstapriv->asoc_sta_count--;
@@ -362,13 +362,13 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
phead = get_list_head(ppending_recvframe_queue);
plist = phead->next;
- while (!rtw_is_list_empty(phead)) {
+ while (!list_empty(phead)) {
prhdr = container_of(plist, struct recv_frame, list);
prframe = (struct recv_frame *)prhdr;
plist = plist->next;
- rtw_list_delete(&(prframe->list));
+ list_del_init(&(prframe->list));
rtw_free_recvframe(prframe, pfree_recv_queue);
}
@@ -382,8 +382,8 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
#ifdef CONFIG_88EU_AP_MODE
spin_lock_bh(&pstapriv->auth_list_lock);
- if (!rtw_is_list_empty(&psta->auth_list)) {
- rtw_list_delete(&psta->auth_list);
+ if (!list_empty(&psta->auth_list)) {
+ list_del_init(&psta->auth_list);
pstapriv->auth_list_cnt--;
}
spin_unlock_bh(&pstapriv->auth_list_lock);
@@ -413,7 +413,7 @@ u32 rtw_free_stainfo(struct adapter *padapter , struct sta_info *psta)
#endif /* CONFIG_88EU_AP_MODE */
spin_lock_bh(&(pfree_sta_queue->lock));
- rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
+ list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
spin_unlock_bh(&pfree_sta_queue->lock);
exit:
@@ -441,7 +441,7 @@ void rtw_free_all_stainfo(struct adapter *padapter)
phead = &(pstapriv->sta_hash[index]);
plist = phead->next;
- while ((!rtw_end_of_queue_search(phead, plist))) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info , hash_list);
plist = plist->next;
@@ -478,7 +478,7 @@ struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
phead = &(pstapriv->sta_hash[index]);
plist = phead->next;
- while ((!rtw_end_of_queue_search(phead, plist))) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, hash_list);
if ((!memcmp(psta->hwaddr, addr, ETH_ALEN)) == true) {
@@ -539,7 +539,7 @@ u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
spin_lock_bh(&(pacl_node_q->lock));
phead = get_list_head(pacl_node_q);
plist = phead->next;
- while ((!rtw_end_of_queue_search(phead, plist))) {
+ while (phead != plist) {
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
plist = plist->next;
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
index 6fb8caa94abb..33ccbbbd8ed6 100644
--- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
@@ -239,7 +239,7 @@ void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrat
{
unsigned char supportedrates[NumRates];
- _rtw_memset(supportedrates, 0, NumRates);
+ memset(supportedrates, 0, NumRates);
*bssrate_len = ratetbl2rateset(padapter, supportedrates);
memcpy(pbssrate, supportedrates, *bssrate_len);
}
@@ -541,7 +541,7 @@ void flush_all_cam_entry(struct adapter *padapter)
rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
- _rtw_memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
+ memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
}
int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
@@ -935,7 +935,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
return true;
}
- bssid = (struct wlan_bssid_ex *)rtw_zmalloc(sizeof(struct wlan_bssid_ex));
+ bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_KERNEL);
subtype = GetFrameSubType(pframe) >> 4;
@@ -1222,7 +1222,7 @@ unsigned int is_ap_in_wep(struct adapter *padapter)
}
}
-int wifirate2_ratetbl_inx(unsigned char rate)
+static int wifirate2_ratetbl_inx(unsigned char rate)
{
int inx = 0;
rate = rate & 0x7f;
@@ -1357,16 +1357,7 @@ void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
{
unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- /* Added by Albert 2011/03/22 */
- /* In the P2P mode, the driver should not support the b mode. */
- /* So, the Tx packet shouldn't use the CCK rate */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- return;
-#endif /* CONFIG_88EU_P2P */
- _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
+ memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
memcpy(supported_rates, rtw_basic_rate_cck, 4);
diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c
index 1413ec8ad3bf..639ace06a3d6 100644
--- a/drivers/staging/rtl8188eu/core/rtw_xmit.c
+++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c
@@ -23,8 +23,6 @@
#include <drv_types.h>
#include <wifi.h>
#include <osdep_intf.h>
-#include <usb_ops.h>
-#include <usb_osintf.h>
#include <linux/vmalloc.h>
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
@@ -32,21 +30,21 @@ static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
static void _init_txservq(struct tx_servq *ptxservq)
{
- _rtw_init_listhead(&ptxservq->tx_pending);
+ INIT_LIST_HEAD(&ptxservq->tx_pending);
_rtw_init_queue(&ptxservq->sta_pending);
ptxservq->qcnt = 0;
}
void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
{
- _rtw_memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv));
+ memset((unsigned char *)psta_xmitpriv, 0, sizeof (struct sta_xmit_priv));
spin_lock_init(&psta_xmitpriv->lock);
_init_txservq(&psta_xmitpriv->be_q);
_init_txservq(&psta_xmitpriv->bk_q);
_init_txservq(&psta_xmitpriv->vi_q);
_init_txservq(&psta_xmitpriv->vo_q);
- _rtw_init_listhead(&psta_xmitpriv->legacy_dz);
- _rtw_init_listhead(&psta_xmitpriv->apsd);
+ INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
+ INIT_LIST_HEAD(&psta_xmitpriv->apsd);
}
@@ -101,7 +99,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf;
for (i = 0; i < NR_XMITFRAME; i++) {
- _rtw_init_listhead(&(pxframe->list));
+ INIT_LIST_HEAD(&(pxframe->list));
pxframe->padapter = padapter;
pxframe->frame_tag = NULL_FRAMETAG;
@@ -111,7 +109,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxframe->buf_addr = NULL;
pxframe->pxmitbuf = NULL;
- rtw_list_insert_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
+ list_add_tail(&(pxframe->list), &(pxmitpriv->free_xmit_queue.queue));
pxframe++;
}
@@ -139,7 +137,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
for (i = 0; i < NR_XMITBUFF; i++) {
- _rtw_init_listhead(&pxmitbuf->list);
+ INIT_LIST_HEAD(&pxmitbuf->list);
pxmitbuf->priv_data = NULL;
pxmitbuf->padapter = padapter;
@@ -157,7 +155,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitbuf->flags = XMIT_VO_QUEUE;
- rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
+ list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue));
pxmitbuf++;
}
@@ -179,7 +177,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
for (i = 0; i < num_xmit_extbuf; i++) {
- _rtw_init_listhead(&pxmitbuf->list);
+ INIT_LIST_HEAD(&pxmitbuf->list);
pxmitbuf->priv_data = NULL;
pxmitbuf->padapter = padapter;
@@ -191,7 +189,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
goto exit;
}
- rtw_list_insert_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
+ list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmit_extbuf_queue.queue));
pxmitbuf++;
}
@@ -234,9 +232,6 @@ void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv)
u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
-
- rtw_hal_free_xmit_priv(padapter);
-
if (pxmitpriv->pxmit_frame_buf == NULL)
return;
@@ -696,7 +691,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
payload = pframe;
for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
- payload = (u8 *)RND4((size_t)(payload));
+ payload = (u8 *) round_up((size_t)(payload), 4);
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_,
("=== curfragnum=%d, pframe = 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x,!!!\n",
curfragnum, *payload, *(payload+1),
@@ -804,7 +799,7 @@ s32 rtw_make_wlanhdr (struct adapter *padapter , u8 *hdr, struct pkt_attrib *pat
}
}
- _rtw_memset(hdr, 0, WLANHDR_OFFSET);
+ memset(hdr, 0, WLANHDR_OFFSET);
SetFrameSubType(fctrl, pattrib->subtype);
@@ -905,10 +900,10 @@ s32 rtw_txframes_pending(struct adapter *padapter)
{
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- return ((_rtw_queue_empty(&pxmitpriv->be_pending) == false) ||
- (_rtw_queue_empty(&pxmitpriv->bk_pending) == false) ||
- (_rtw_queue_empty(&pxmitpriv->vi_pending) == false) ||
- (_rtw_queue_empty(&pxmitpriv->vo_pending) == false));
+ return (!list_empty(&pxmitpriv->be_pending.queue) ||
+ !list_empty(&pxmitpriv->bk_pending.queue) ||
+ !list_empty(&pxmitpriv->vi_pending.queue) ||
+ !list_empty(&pxmitpriv->vo_pending.queue));
}
s32 rtw_txframes_sta_ac_pending(struct adapter *padapter, struct pkt_attrib *pattrib)
@@ -1103,7 +1098,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct
addr = (size_t)(pframe);
- mem_start = (unsigned char *)RND4(addr) + hw_hdr_offset;
+ mem_start = (unsigned char *) round_up(addr, 4) + hw_hdr_offset;
memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
}
@@ -1226,7 +1221,7 @@ struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
spin_lock_irqsave(&pfree_queue->lock, irql);
- if (_rtw_queue_empty(pfree_queue) == true) {
+ if (list_empty(&pfree_queue->queue)) {
pxmitbuf = NULL;
} else {
phead = get_list_head(pfree_queue);
@@ -1235,7 +1230,7 @@ struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
pxmitbuf = container_of(plist, struct xmit_buf, list);
- rtw_list_delete(&(pxmitbuf->list));
+ list_del_init(&(pxmitbuf->list));
}
if (pxmitbuf != NULL) {
@@ -1267,9 +1262,9 @@ s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
spin_lock_irqsave(&pfree_queue->lock, irql);
- rtw_list_delete(&pxmitbuf->list);
+ list_del_init(&pxmitbuf->list);
- rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
+ list_add_tail(&(pxmitbuf->list), get_list_head(pfree_queue));
pxmitpriv->free_xmit_extbuf_cnt++;
spin_unlock_irqrestore(&pfree_queue->lock, irql);
@@ -1290,7 +1285,7 @@ struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
- if (_rtw_queue_empty(pfree_xmitbuf_queue) == true) {
+ if (list_empty(&pfree_xmitbuf_queue->queue)) {
pxmitbuf = NULL;
} else {
phead = get_list_head(pfree_xmitbuf_queue);
@@ -1299,7 +1294,7 @@ struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
pxmitbuf = container_of(plist, struct xmit_buf, list);
- rtw_list_delete(&(pxmitbuf->list));
+ list_del_init(&(pxmitbuf->list));
}
if (pxmitbuf != NULL) {
@@ -1334,9 +1329,9 @@ s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
} else {
spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irql);
- rtw_list_delete(&pxmitbuf->list);
+ list_del_init(&pxmitbuf->list);
- rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
+ list_add_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
pxmitpriv->free_xmitbuf_cnt++;
spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irql);
@@ -1373,7 +1368,7 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pf
spin_lock_bh(&pfree_xmit_queue->lock);
- if (_rtw_queue_empty(pfree_xmit_queue) == true) {
+ if (list_empty(&pfree_xmit_queue->queue)) {
RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_alloc_xmitframe:%d\n", pxmitpriv->free_xmitframe_cnt));
pxframe = NULL;
} else {
@@ -1383,7 +1378,7 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pf
pxframe = container_of(plist, struct xmit_frame, list);
- rtw_list_delete(&(pxframe->list));
+ list_del_init(&(pxframe->list));
}
if (pxframe != NULL) { /* default value setting */
@@ -1394,7 +1389,7 @@ struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pf
pxframe->buf_addr = NULL;
pxframe->pxmitbuf = NULL;
- _rtw_memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
+ memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
/* pxframe->attrib.psta = NULL; */
pxframe->frame_tag = DATA_FRAMETAG;
@@ -1426,14 +1421,14 @@ s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitfram
spin_lock_bh(&pfree_xmit_queue->lock);
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
if (pxmitframe->pkt) {
pndis_pkt = pxmitframe->pkt;
pxmitframe->pkt = NULL;
}
- rtw_list_insert_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
+ list_add_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
pxmitpriv->free_xmitframe_cnt++;
RT_TRACE(_module_rtl871x_xmit_c_, _drv_debug_, ("rtw_free_xmitframe():free_xmitframe_cnt=%d\n", pxmitpriv->free_xmitframe_cnt));
@@ -1460,7 +1455,7 @@ void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pfram
phead = get_list_head(pframequeue);
plist = phead->next;
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
pxmitframe = container_of(plist, struct xmit_frame, list);
plist = plist->next;
@@ -1491,12 +1486,12 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str
xmitframe_phead = get_list_head(pframe_queue);
xmitframe_plist = xmitframe_phead->next;
- if (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ if (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
ptxservq->qcnt--;
}
@@ -1532,7 +1527,7 @@ struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmi
sta_phead = get_list_head(phwxmit->sta_queue);
sta_plist = sta_phead->next;
- while (!rtw_end_of_queue_search(sta_phead, sta_plist)) {
+ while (sta_phead != sta_plist) {
ptxservq = container_of(sta_plist, struct tx_servq, tx_pending);
pframe_queue = &ptxservq->sta_pending;
@@ -1543,8 +1538,8 @@ struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmi
phwxmit->accnt--;
/* Remove sta node when there are no pending packets. */
- if (_rtw_queue_empty(pframe_queue)) /* must be done after get_next and before break */
- rtw_list_delete(&ptxservq->tx_pending);
+ if (list_empty(&pframe_queue->queue)) /* must be done after get_next and before break */
+ list_del_init(&ptxservq->tx_pending);
goto exit;
}
@@ -1622,10 +1617,10 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
- if (rtw_is_list_empty(&ptxservq->tx_pending))
- rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
+ if (list_empty(&ptxservq->tx_pending))
+ list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
- rtw_list_insert_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
+ list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
ptxservq->qcnt++;
phwxmits[ac_index].accnt++;
exit:
@@ -1641,7 +1636,7 @@ void rtw_alloc_hwxmits(struct adapter *padapter)
pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
- pxmitpriv->hwxmits = (struct hw_xmit *)rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
+ pxmitpriv->hwxmits = kzalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry, GFP_KERNEL);
hwxmits = pxmitpriv->hwxmits;
@@ -1676,127 +1671,6 @@ void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
phwxmit->accnt = 0;
}
-static int rtw_br_client_tx(struct adapter *padapter, struct sk_buff **pskb)
-{
- struct sk_buff *skb = *pskb;
- int res, is_vlan_tag = 0, i, do_nat25 = 1;
- unsigned short vlan_hdr = 0;
- void *br_port = NULL;
-
- rcu_read_lock();
- br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
- rcu_read_unlock();
- spin_lock_bh(&padapter->br_ext_lock);
- if (!(skb->data[0] & 1) && br_port &&
- memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
- *((__be16 *)(skb->data+MACADDRLEN*2)) != __constant_htons(ETH_P_8021Q) &&
- *((__be16 *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP) &&
- !memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN) && padapter->scdb_entry) {
- memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
- padapter->scdb_entry->ageing_timer = jiffies;
- spin_unlock_bh(&padapter->br_ext_lock);
- } else {
- if (*((__be16 *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_8021Q)) {
- is_vlan_tag = 1;
- vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
- skb_pull(skb, 4);
- }
- if (!memcmp(skb->data+MACADDRLEN, padapter->br_mac, MACADDRLEN) &&
- (*((__be16 *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)))
- memcpy(padapter->br_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
-
- if (*((__be16 *)(skb->data+MACADDRLEN*2)) == __constant_htons(ETH_P_IP)) {
- if (memcmp(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN)) {
- padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter,
- skb->data+MACADDRLEN, skb->data+WLAN_ETHHDR_LEN+12);
- if (padapter->scdb_entry) {
- memcpy(padapter->scdb_mac, skb->data+MACADDRLEN, MACADDRLEN);
- memcpy(padapter->scdb_ip, skb->data+WLAN_ETHHDR_LEN+12, 4);
- padapter->scdb_entry->ageing_timer = jiffies;
- do_nat25 = 0;
- }
- } else {
- if (padapter->scdb_entry) {
- padapter->scdb_entry->ageing_timer = jiffies;
- do_nat25 = 0;
- } else {
- memset(padapter->scdb_mac, 0, MACADDRLEN);
- memset(padapter->scdb_ip, 0, 4);
- }
- }
- }
- spin_unlock_bh(&padapter->br_ext_lock);
- if (do_nat25) {
- if (nat25_db_handle(padapter, skb, NAT25_CHECK) == 0) {
- struct sk_buff *newskb;
-
- if (is_vlan_tag) {
- skb_push(skb, 4);
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
- *((__be16 *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
- *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
- }
-
- newskb = skb_copy(skb, GFP_ATOMIC);
- if (newskb == NULL) {
- DEBUG_ERR("TX DROP: skb_copy fail!\n");
- return -1;
- }
- dev_kfree_skb_any(skb);
-
- *pskb = skb = newskb;
- if (is_vlan_tag) {
- vlan_hdr = *((unsigned short *)(skb->data+MACADDRLEN*2+2));
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+MACADDRLEN*2+2-i*2)) = *((unsigned short *)(skb->data+MACADDRLEN*2-2-i*2));
- skb_pull(skb, 4);
- }
- }
-
- if (skb_is_nonlinear(skb))
- DEBUG_ERR("%s(): skb_is_nonlinear!!\n", __func__);
-
- res = skb_linearize(skb);
- if (res < 0) {
- DEBUG_ERR("TX DROP: skb_linearize fail!\n");
- return -1;
- }
-
- res = nat25_db_handle(padapter, skb, NAT25_INSERT);
- if (res < 0) {
- if (res == -2) {
- DEBUG_ERR("TX DROP: nat25_db_handle fail!\n");
- return -1;
- }
- return 0;
- }
- }
-
- memcpy(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN);
-
- dhcp_flag_bcast(padapter, skb);
-
- if (is_vlan_tag) {
- skb_push(skb, 4);
- for (i = 0; i < 6; i++)
- *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
- *((__be16 *)(skb->data+MACADDRLEN*2)) = __constant_htons(ETH_P_8021Q);
- *((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
- }
- }
-
- /* check if SA is equal to our MAC */
- if (memcmp(skb->data+MACADDRLEN, GET_MY_HWADDR(padapter), MACADDRLEN)) {
- DEBUG_ERR("TX DROP: untransformed frame SA:%02X%02X%02X%02X%02X%02X!\n",
- skb->data[6], skb->data[7], skb->data[8], skb->data[9], skb->data[10], skb->data[11]);
- return -1;
- }
- return 0;
-}
-
u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
{
u32 addr;
@@ -1856,8 +1730,6 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
{
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_frame *pxmitframe = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- void *br_port = NULL;
s32 res;
pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
@@ -1867,18 +1739,6 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
return -1;
}
- rcu_read_lock();
- br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
- rcu_read_unlock();
-
- if (br_port && check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) {
- res = rtw_br_client_tx(padapter, ppkt);
- if (res == -1) {
- rtw_free_xmitframe(pxmitpriv, pxmitframe);
- return -1;
- }
- }
-
res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
if (res == _FAIL) {
@@ -1939,9 +1799,9 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
spin_lock_bh(&psta->sleep_q.lock);
if (pstapriv->sta_dz_bitmap) {/* if any one sta is in ps mode */
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
- rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
+ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
psta->sleepq_len++;
@@ -1964,9 +1824,9 @@ int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_fra
u8 wmmps_ac = 0;
if (pstapriv->sta_dz_bitmap&BIT(psta->aid)) {
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
- rtw_list_insert_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
+ list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
psta->sleepq_len++;
@@ -2023,7 +1883,7 @@ static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struc
phead = get_list_head(pframequeue);
plist = phead->next;
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
pxmitframe = container_of(plist, struct xmit_frame, list);
plist = plist->next;
@@ -2058,21 +1918,21 @@ void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
pstapriv->sta_dz_bitmap |= BIT(psta->aid);
dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->be_q.tx_pending));
dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
/* for BC/MC Frames */
pstaxmitpriv = &psta_bmc->sta_xmitpriv;
dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
- rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->be_q.tx_pending));
spin_unlock_bh(&pxmitpriv->lock);
}
@@ -2090,12 +1950,12 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
xmitframe_phead = get_list_head(&psta->sleep_q);
xmitframe_plist = xmitframe_phead->next;
- while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ while (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
switch (pxmitframe->attrib.priority) {
case 1:
@@ -2171,12 +2031,12 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
xmitframe_plist = xmitframe_phead->next;
- while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ while (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
psta_bmc->sleepq_len--;
if (psta_bmc->sleepq_len > 0)
@@ -2218,7 +2078,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
xmitframe_phead = get_list_head(&psta->sleep_q);
xmitframe_plist = xmitframe_phead->next;
- while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ while (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
@@ -2246,7 +2106,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst
if (!wmmps_ac)
continue;
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
psta->sleepq_len--;
psta->sleepq_ac_len--;
diff --git a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
index dea220b507ad..3c651d5c6824 100644
--- a/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c
@@ -358,19 +358,19 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0000000d;
break;
case 12:
- MaskFromReg = rtw_read32(adapt, REG_ARFR0);
+ MaskFromReg = usb_read32(adapt, REG_ARFR0);
pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
break;
case 13:
- MaskFromReg = rtw_read32(adapt, REG_ARFR1);
+ MaskFromReg = usb_read32(adapt, REG_ARFR1);
pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
break;
case 14:
- MaskFromReg = rtw_read32(adapt, REG_ARFR2);
+ MaskFromReg = usb_read32(adapt, REG_ARFR2);
pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
break;
case 15:
- MaskFromReg = rtw_read32(adapt, REG_ARFR3);
+ MaskFromReg = usb_read32(adapt, REG_ARFR3);
pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
break;
default:
@@ -670,7 +670,7 @@ void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime)
{
struct adapter *adapt = dm_odm->Adapter;
- rtw_write16(adapt, REG_TX_RPT_TIME, minRptTime);
+ usb_write16(adapt, REG_TX_RPT_TIME, minRptTime);
}
void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1)
diff --git a/drivers/staging/rtl8188eu/hal/HalPhyRf.c b/drivers/staging/rtl8188eu/hal/HalPhyRf.c
deleted file mode 100644
index 980f7da8ab3b..000000000000
--- a/drivers/staging/rtl8188eu/hal/HalPhyRf.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
- #include "odm_precomp.h"
-
-/* 3============================================================ */
-/* 3 IQ Calibration */
-/* 3============================================================ */
-
-void ODM_ResetIQKResult(struct odm_dm_struct *pDM_Odm)
-{
-}
-
-u8 ODM_GetRightChnlPlaceforIQK(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;
-}
diff --git a/drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
index 7c22658ed0f1..d2bcc1640522 100644
--- a/drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
@@ -1,5 +1,4 @@
-
-/******************************************************************************
+/*
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
@@ -15,39 +14,47 @@
* 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
+ */
#include "odm_precomp.h"
-/*---------------------------Define Local Constant---------------------------*/
/* 2010/04/25 MH Define the max tx power tracking tx agc power. */
#define ODM_TXPWRTRACK_MAX_IDX_88E 6
-/*---------------------------Define Local Constant---------------------------*/
-/* 3============================================================ */
+static u8 ODM_GetRightChnlPlaceforIQK(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;
+}
+
/* 3 Tx Power Tracking */
-/* 3============================================================ */
-/*-----------------------------------------------------------------------------
+/*
* Function: ODM_TxPwrTrackAdjust88E()
*
* Overview: 88E we can not write 0xc80/c94/c4c/ 0xa2x. Instead of write TX agc.
* No matter OFDM & CCK use the same method.
*
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
* Revised History:
* When Who Remark
* 04/23/2012 MHC Create Version 0.
* 04/23/2012 MHC Adjust TX agc directly not throughput BB digital.
*
- *---------------------------------------------------------------------------*/
+ */
void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/* 0 = OFDM, 1 = CCK */
u8 *pDirection, /* 1 = +(increase) 2 = -(decrease) */
u32 *pOutWriteVal /* Tx tracking CCK/OFDM BB swing index adjust */
@@ -96,23 +103,12 @@ void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *dm_odm, u8 Type,/* 0 = OFDM,
*pOutWriteVal = pwr_value | (pwr_value<<8) | (pwr_value<<16) | (pwr_value<<24);
} /* ODM_TxPwrTrackAdjust88E */
-/*-----------------------------------------------------------------------------
+/*
* Function: odm_TxPwrTrackSetPwr88E()
*
* Overview: 88E change all channel tx power accordign to flag.
* OFDM & CCK are all different.
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 04/23/2012 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
+ */
static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
{
if (dm_odm->BbSwingFlagOfdm || dm_odm->BbSwingFlagCck) {
@@ -123,7 +119,6 @@ static void odm_TxPwrTrackSetPwr88E(struct odm_dm_struct *dm_odm)
}
} /* odm_TxPwrTrackSetPwr88E */
-/* 091212 chiyokolin */
void
odm_TXPowerTrackingCallback_ThermalMeter_8188E(
struct adapter *Adapter
@@ -455,8 +450,6 @@ odm_TXPowerTrackingCallback_ThermalMeter_8188E(
}
if (delta_IQK >= 8) { /* Delta temperature is equal to or larger than 20 centigrade. */
- ODM_ResetIQKResult(dm_odm);
-
dm_odm->RFCalibrateInfo.ThermalValue_IQK = ThermalValue;
PHY_IQCalibrate_8188E(Adapter, false);
}
@@ -471,7 +464,6 @@ odm_TXPowerTrackingCallback_ThermalMeter_8188E(
/* 1 7. IQK */
#define MAX_TOLERANCE 5
-#define IQK_DELAY_TIME 1 /* ms */
static u8 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
phy_PathA_IQK_8188E(struct adapter *adapt, bool configPathB)
@@ -827,9 +819,9 @@ static void _PHY_SaveMACRegisters(
struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Save MAC parameters.\n"));
for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
- MACBackup[i] = rtw_read8(adapt, MACReg[i]);
+ MACBackup[i] = usb_read8(adapt, MACReg[i]);
}
- MACBackup[i] = rtw_read32(adapt, MACReg[i]);
+ MACBackup[i] = usb_read32(adapt, MACReg[i]);
}
static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
@@ -856,9 +848,9 @@ _PHY_ReloadMACRegisters(
ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("Reload MAC parameters !\n"));
for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
- rtw_write8(adapt, MACReg[i], (u8)MACBackup[i]);
+ usb_write8(adapt, MACReg[i], (u8)MACBackup[i]);
}
- rtw_write32(adapt, MACReg[i], MACBackup[i]);
+ usb_write32(adapt, MACReg[i], MACBackup[i]);
}
void
@@ -900,12 +892,12 @@ _PHY_MACSettingCalibration(
ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("MAC settings for Calibration.\n"));
- rtw_write8(adapt, MACReg[i], 0x3F);
+ usb_write8(adapt, MACReg[i], 0x3F);
for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) {
- rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i]&(~BIT3)));
+ usb_write8(adapt, MACReg[i], (u8)(MACBackup[i]&(~BIT3)));
}
- rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i]&(~BIT5)));
+ usb_write8(adapt, MACReg[i], (u8)(MACBackup[i]&(~BIT5)));
}
void
@@ -1213,12 +1205,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
/* Check continuous TX and Packet TX */
- tmpreg = rtw_read8(adapt, 0xd03);
+ tmpreg = usb_read8(adapt, 0xd03);
if ((tmpreg&0x70) != 0) /* Deal with contisuous TX case */
- rtw_write8(adapt, 0xd03, tmpreg&0x8F); /* disable all continuous TX */
+ usb_write8(adapt, 0xd03, tmpreg&0x8F); /* disable all continuous TX */
else /* Deal with Packet TX case */
- rtw_write8(adapt, REG_TXPAUSE, 0xFF); /* block all queues */
+ usb_write8(adapt, REG_TXPAUSE, 0xFF); /* block all queues */
if ((tmpreg&0x70) != 0) {
/* 1. Read original RF mode */
@@ -1250,7 +1242,7 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
if ((tmpreg&0x70) != 0) {
/* Deal with continuous TX case */
/* Path-A */
- rtw_write8(adapt, 0xd03, tmpreg);
+ usb_write8(adapt, 0xd03, tmpreg);
PHY_SetRFReg(adapt, RF_PATH_A, RF_AC, bMask12Bits, RF_Amode);
/* Path-B */
@@ -1258,7 +1250,7 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
PHY_SetRFReg(adapt, RF_PATH_B, RF_AC, bMask12Bits, RF_Bmode);
} else {
/* Deal with Packet TX case */
- rtw_write8(adapt, REG_TXPAUSE, 0x00);
+ usb_write8(adapt, REG_TXPAUSE, 0x00);
}
}
@@ -1266,7 +1258,6 @@ void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
- struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
s32 result[4][8]; /* last is final result */
u8 i, final_candidate, Indexforchannel;
bool pathaok, pathbok;
@@ -1286,11 +1277,6 @@ void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
return;
- if (*(dm_odm->mp_mode) == 1) {
- singletone = pMptCtx->bSingleTone;
- carrier_sup = pMptCtx->bCarrierSuppression;
- }
-
/* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
if (singletone || carrier_sup)
return;
@@ -1418,12 +1404,7 @@ void PHY_LCCalibrate_8188E(struct adapter *adapt)
u32 timeout = 2000, timecount = 0;
struct hal_data_8188e *pHalData = GET_HAL_DATA(adapt);
struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
- struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
- if (*(dm_odm->mp_mode) == 1) {
- singletone = pMptCtx->bSingleTone;
- carrier_sup = pMptCtx->bCarrierSuppression;
- }
if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
return;
/* 20120213<Kordan> Turn on when continuous Tx to pass lab testing. (required by Edlu) */
@@ -1454,8 +1435,8 @@ static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2
{
if (!adapt->hw_init_completed) {
u8 u1btmp;
- u1btmp = rtw_read8(adapt, REG_LEDCFG2) | BIT7;
- rtw_write8(adapt, REG_LEDCFG2, u1btmp);
+ u1btmp = usb_read8(adapt, REG_LEDCFG2) | BIT7;
+ usb_write8(adapt, REG_LEDCFG2, u1btmp);
PHY_SetBBReg(adapt, rFPGA0_XAB_RFParameter, BIT13, 0x01);
}
diff --git a/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
index 50f951390695..caca535ac17d 100644
--- a/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
@@ -35,6 +35,7 @@ Major Change History:
--*/
#include <HalPwrSeqCmd.h>
+#include <usb_ops_linux.h>
/* Description: */
/* This routine deals with the Power Configuration CMDs parsing
@@ -80,13 +81,13 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
/* Read the value from system register */
- value = rtw_read8(padapter, offset);
+ value = usb_read8(padapter, offset);
value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
/* Write the value back to system register */
- rtw_write8(padapter, offset, value);
+ usb_write8(padapter, offset, value);
break;
case PWR_CMD_POLLING:
RT_TRACE(_module_hal_init_c_ , _drv_info_, ("HalPwrSeqCmdParsing: PWR_CMD_POLLING\n"));
@@ -94,7 +95,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
poll_bit = false;
offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
do {
- value = rtw_read8(padapter, offset);
+ value = usb_read8(padapter, offset);
value &= GET_PWR_CFG_MASK(pwrcfgcmd);
if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
diff --git a/drivers/staging/rtl8188eu/hal/hal_com.c b/drivers/staging/rtl8188eu/hal/hal_com.c
index 829b900ee938..170e3de5eab4 100644
--- a/drivers/staging/rtl8188eu/hal/hal_com.c
+++ b/drivers/staging/rtl8188eu/hal/hal_com.c
@@ -319,63 +319,3 @@ void hal_init_macaddr(struct adapter *adapter)
rtw_hal_set_hwreg(adapter, HW_VAR_MAC_ADDR,
adapter->eeprompriv.mac_addr);
}
-
-/*
-* C2H event format:
-* Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
-* BITS [127:120] [119:16] [15:8] [7:4] [3:0]
-*/
-
-void c2h_evt_clear(struct adapter *adapter)
-{
- rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
-}
-
-s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
-{
- s32 ret = _FAIL;
- struct c2h_evt_hdr *c2h_evt;
- int i;
- u8 trigger;
-
- if (buf == NULL)
- goto exit;
-
- trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
-
- if (trigger == C2H_EVT_HOST_CLOSE)
- goto exit; /* Not ready */
- else if (trigger != C2H_EVT_FW_CLOSE)
- goto clear_evt; /* Not a valid value */
-
- c2h_evt = (struct c2h_evt_hdr *)buf;
-
- _rtw_memset(c2h_evt, 0, 16);
-
- *buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
- *(buf+1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
-
- RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read(): ",
- &c2h_evt , sizeof(c2h_evt));
-
- /* Read the content */
- for (i = 0; i < c2h_evt->plen; i++)
- c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
- sizeof(*c2h_evt) + i);
-
- RT_PRINT_DATA(_module_hal_init_c_, _drv_info_,
- "c2h_evt_read(): Command Content:\n",
- c2h_evt->payload, c2h_evt->plen);
-
- ret = _SUCCESS;
-
-clear_evt:
- /*
- * Clear event to notify FW we have read the command.
- * If this field isn't clear, the FW won't update the next
- * command message.
- */
- c2h_evt_clear(adapter);
-exit:
- return ret;
-}
diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c
index d0ac4a183335..2faa690f7e26 100644
--- a/drivers/staging/rtl8188eu/hal/hal_intf.c
+++ b/drivers/staging/rtl8188eu/hal/hal_intf.c
@@ -156,15 +156,6 @@ void rtw_hal_set_odm_var(struct adapter *adapt,
val1, set);
}
-void rtw_hal_get_odm_var(struct adapter *adapt,
- enum hal_odm_variable var, void *val1,
- bool set)
-{
- if (adapt->HalFunc.GetHalODMVarHandler)
- adapt->HalFunc.GetHalODMVarHandler(adapt, var,
- val1, set);
-}
-
void rtw_hal_enable_interrupt(struct adapter *adapt)
{
if (adapt->HalFunc.enable_interrupt)
@@ -223,12 +214,6 @@ s32 rtw_hal_init_xmit_priv(struct adapter *adapt)
return _FAIL;
}
-void rtw_hal_free_xmit_priv(struct adapter *adapt)
-{
- if (adapt->HalFunc.free_xmit_priv != NULL)
- adapt->HalFunc.free_xmit_priv(adapt);
-}
-
s32 rtw_hal_init_recv_priv(struct adapter *adapt)
{
if (adapt->HalFunc.init_recv_priv)
@@ -271,20 +256,6 @@ void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg,
rssi_level);
}
-/* Start specifical interface thread */
-void rtw_hal_start_thread(struct adapter *adapt)
-{
- if (adapt->HalFunc.run_thread)
- adapt->HalFunc.run_thread(adapt);
-}
-
-/* Start specifical interface thread */
-void rtw_hal_stop_thread(struct adapter *adapt)
-{
- if (adapt->HalFunc.cancel_thread)
- adapt->HalFunc.cancel_thread(adapt);
-}
-
u32 rtw_hal_read_bbreg(struct adapter *adapt, u32 regaddr, u32 bitmask)
{
u32 data = 0;
@@ -374,30 +345,6 @@ void rtw_hal_sreset_init(struct adapter *adapt)
adapt->HalFunc.sreset_init_value(adapt);
}
-void rtw_hal_sreset_reset(struct adapter *adapt)
-{
- if (adapt->HalFunc.silentreset)
- adapt->HalFunc.silentreset(adapt);
-}
-
-void rtw_hal_sreset_reset_value(struct adapter *adapt)
-{
- if (adapt->HalFunc.sreset_reset_value)
- adapt->HalFunc.sreset_reset_value(adapt);
-}
-
-void rtw_hal_sreset_xmit_status_check(struct adapter *adapt)
-{
- if (adapt->HalFunc.sreset_xmit_status_check)
- adapt->HalFunc.sreset_xmit_status_check(adapt);
-}
-
-void rtw_hal_sreset_linked_status_check(struct adapter *adapt)
-{
- if (adapt->HalFunc.sreset_linked_status_check)
- adapt->HalFunc.sreset_linked_status_check(adapt);
-}
-
u8 rtw_hal_sreset_get_wifi_status(struct adapter *adapt)
{
u8 status = 0;
@@ -428,17 +375,3 @@ void rtw_hal_reset_security_engine(struct adapter *adapter)
if (adapter->HalFunc.hal_reset_security_engine)
adapter->HalFunc.hal_reset_security_engine(adapter);
}
-
-s32 rtw_hal_c2h_handler(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt)
-{
- s32 ret = _FAIL;
-
- if (adapter->HalFunc.c2h_handler)
- ret = adapter->HalFunc.c2h_handler(adapter, c2h_evt);
- return ret;
-}
-
-c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter)
-{
- return adapter->HalFunc.c2h_id_filter_ccx;
-}
diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c
index 2a0ac4ab23d2..f8dcfdae0727 100644
--- a/drivers/staging/rtl8188eu/hal/odm.c
+++ b/drivers/staging/rtl8188eu/hal/odm.c
@@ -221,7 +221,6 @@ void ODM_DMWatchdog(struct odm_dm_struct *pDM_Odm)
ODM_TXPowerTrackingCheck(pDM_Odm);
odm_EdcaTurboCheck(pDM_Odm);
- odm_DynamicTxPower(pDM_Odm);
}
/* Init /.. Fixed HW value. Only init time. */
@@ -833,7 +832,7 @@ void ODM_Write_CCK_CCA_Thres(struct odm_dm_struct *pDM_Odm, u8 CurCCK_CCAThres)
struct adapter *adapt = pDM_Odm->Adapter;
if (pDM_DigTable->CurCCK_CCAThres != CurCCK_CCAThres) /* modify by Guo.Mingzhi 2012-01-03 */
- rtw_write8(adapt, ODM_REG_CCK_CCA_11N, CurCCK_CCAThres);
+ usb_write8(adapt, ODM_REG_CCK_CCA_11N, CurCCK_CCAThres);
pDM_DigTable->PreCCK_CCAThres = pDM_DigTable->CurCCK_CCAThres;
pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres;
}
@@ -1110,19 +1109,6 @@ void odm_DynamicTxPowerInit(struct odm_dm_struct *pDM_Odm)
pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
}
-void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm)
-{
- /* For AP/ADSL use struct rtl8192cd_priv * */
- /* For CE/NIC use struct adapter * */
-
- if (!(pDM_Odm->SupportAbility & ODM_BB_DYNAMIC_TXPWR))
- return;
-
- /* 2012/01/12 MH According to Luke's suggestion, only high power will support the feature. */
- if (!pDM_Odm->ExtPA)
- return;
-}
-
/* 3============================================================ */
/* 3 RSSI Monitor */
/* 3============================================================ */
@@ -1291,10 +1277,10 @@ void ODM_EdcaTurboInit(struct odm_dm_struct *pDM_Odm)
pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false;
Adapter->recvpriv.bIsAnyNonBEPkts = false;
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", rtw_read32(Adapter, ODM_EDCA_VO_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", rtw_read32(Adapter, ODM_EDCA_VI_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", rtw_read32(Adapter, ODM_EDCA_BE_PARAM)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", rtw_read32(Adapter, ODM_EDCA_BK_PARAM)));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VO PARAM: 0x%x\n", usb_read32(Adapter, ODM_EDCA_VO_PARAM)));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial VI PARAM: 0x%x\n", usb_read32(Adapter, ODM_EDCA_VI_PARAM)));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BE PARAM: 0x%x\n", usb_read32(Adapter, ODM_EDCA_BE_PARAM)));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("Orginial BK PARAM: 0x%x\n", usb_read32(Adapter, ODM_EDCA_BK_PARAM)));
} /* ODM_InitEdcaTurbo */
void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm)
@@ -1363,7 +1349,7 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
else
edca_param = EDCAParam[HT_IOT_PEER_UNKNOWN][trafficIndex];
- rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param);
+ usb_write32(Adapter, REG_EDCA_BE_PARAM, edca_param);
pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex;
}
@@ -1373,7 +1359,7 @@ void odm_EdcaTurboCheckCE(struct odm_dm_struct *pDM_Odm)
/* Turn Off EDCA turbo here. */
/* Restore original EDCA according to the declaration of AP. */
if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
- rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE);
+ usb_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE);
pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
}
}
diff --git a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c
index a9886122b459..4d4978bee51d 100644
--- a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c
+++ b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c
@@ -68,7 +68,7 @@ void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data)
{
struct adapter *adapt = pDM_Odm->Adapter;
- rtw_write8(adapt, Addr, Data);
+ usb_write8(adapt, Addr, Data);
ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigMACWithHeaderFile: [MAC_REG] %08X %08X\n", Addr, Data));
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 021e5879abcf..023a3d84ee8b 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -22,7 +22,6 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
-#include <cmd_osdep.h>
#include <mlme_osdep.h>
#include <rtw_ioctl_set.h>
@@ -41,7 +40,7 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
u8 valid;
do {
- valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
+ valid = usb_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
if (0 == valid)
read_down = true;
} while ((!read_down) && (retry_cnts--));
@@ -106,13 +105,13 @@ static s32 FillH2CCmd_88E(struct adapter *adapt, u8 ElementID, u32 CmdLen, u8 *p
/* Write Ext command */
msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num * RTL88E_EX_MESSAGE_BOX_SIZE);
for (cmd_idx = 0; cmd_idx < ext_cmd_len; cmd_idx++) {
- rtw_write8(adapt, msgbox_ex_addr+cmd_idx, *((u8 *)(&h2c_cmd_ex)+cmd_idx));
+ usb_write8(adapt, msgbox_ex_addr+cmd_idx, *((u8 *)(&h2c_cmd_ex)+cmd_idx));
}
}
/* Write command */
msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL88E_MESSAGE_BOX_SIZE);
for (cmd_idx = 0; cmd_idx < RTL88E_MESSAGE_BOX_SIZE; cmd_idx++) {
- rtw_write8(adapt, msgbox_addr+cmd_idx, *((u8 *)(&h2c_cmd)+cmd_idx));
+ usb_write8(adapt, msgbox_addr+cmd_idx, *((u8 *)(&h2c_cmd)+cmd_idx));
}
bcmd_down = true;
@@ -153,7 +152,7 @@ u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask)
if (haldata->fw_ractrl) {
__le32 lmask;
- _rtw_memset(buf, 0, 3);
+ memset(buf, 0, 3);
lmask = cpu_to_le32(mask);
memcpy(buf, &lmask, 3);
@@ -476,12 +475,6 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u
*pLength = pktlen;
}
-/* To check if reserved page content is destroyed by beacon because beacon is too large. */
-/* 2010.06.23. Added by tynli. */
-void CheckFwRsvdPageContent(struct adapter *Adapter)
-{
-}
-
/* */
/* Description: Fill the reserved packets that FW will use to RSVD page. */
/* Now we just send 4 types packet to rsvd page. */
@@ -509,7 +502,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
struct rsvdpage_loc RsvdPageLoc;
DBG_88E("%s\n", __func__);
- ReservedPagePacket = (u8 *)rtw_zmalloc(1000);
+ ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
if (ReservedPagePacket == NULL) {
DBG_88E("%s: alloc ReservedPagePacket fail!\n", __func__);
return;
@@ -615,18 +608,18 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
if (mstatus == 1) {
/* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */
/* Suggested by filen. Added by tynli. */
- rtw_write16(adapt, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
+ usb_write16(adapt, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
/* Do not set TSF again here or vWiFi beacon DMA INT will not work. */
/* Set REG_CR bit 8. DMA beacon by SW. */
haldata->RegCR_1 |= BIT0;
- rtw_write8(adapt, REG_CR+1, haldata->RegCR_1);
+ usb_write8(adapt, REG_CR+1, haldata->RegCR_1);
/* 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. */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL)&(~BIT(3)));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL)|BIT(4));
+ usb_write8(adapt, REG_BCN_CTRL, usb_read8(adapt, REG_BCN_CTRL)&(~BIT(3)));
+ usb_write8(adapt, REG_BCN_CTRL, usb_read8(adapt, REG_BCN_CTRL)|BIT(4));
if (haldata->RegFwHwTxQCtrl&BIT6) {
DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -634,7 +627,7 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
}
/* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl&(~BIT6)));
+ usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl&(~BIT6)));
haldata->RegFwHwTxQCtrl &= (~BIT6);
/* Clear beacon valid check bit. */
@@ -668,8 +661,8 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* */
/* Enable Bcn */
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL)|BIT(3));
- rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL)&(~BIT(4)));
+ usb_write8(adapt, REG_BCN_CTRL, usb_read8(adapt, REG_BCN_CTRL)|BIT(3));
+ usb_write8(adapt, REG_BCN_CTRL, usb_read8(adapt, REG_BCN_CTRL)&(~BIT(4)));
/* To make sure that if there exists an adapter which would like to send beacon. */
/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
@@ -677,7 +670,7 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* the beacon cannot be sent by HW. */
/* 2010.06.23. Added by tynli. */
if (bSendBeacon) {
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl|BIT6));
+ usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl|BIT6));
haldata->RegFwHwTxQCtrl |= BIT6;
}
@@ -690,78 +683,6 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
/* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */
/* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
haldata->RegCR_1 &= (~BIT0);
- rtw_write8(adapt, REG_CR+1, haldata->RegCR_1);
+ usb_write8(adapt, REG_CR+1, haldata->RegCR_1);
}
}
-
-void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state)
-{
-#ifdef CONFIG_88EU_P2P
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- struct wifidirect_info *pwdinfo = &(adapt->wdinfo);
- struct P2P_PS_Offload_t *p2p_ps_offload = &haldata->p2p_ps_offload;
- u8 i;
-
-
- switch (p2p_ps_state) {
- case P2P_PS_DISABLE:
- DBG_88E("P2P_PS_DISABLE\n");
- _rtw_memset(p2p_ps_offload, 0, 1);
- break;
- case P2P_PS_ENABLE:
- DBG_88E("P2P_PS_ENABLE\n");
- /* update CTWindow value. */
- if (pwdinfo->ctwindow > 0) {
- p2p_ps_offload->CTWindow_En = 1;
- rtw_write8(adapt, REG_P2P_CTWIN, pwdinfo->ctwindow);
- }
-
- /* hw only support 2 set of NoA */
- for (i = 0; i < pwdinfo->noa_num; i++) {
- /* To control the register setting for which NOA */
- rtw_write8(adapt, REG_NOA_DESC_SEL, (i << 4));
- if (i == 0)
- p2p_ps_offload->NoA0_En = 1;
- else
- p2p_ps_offload->NoA1_En = 1;
-
- /* config P2P NoA Descriptor Register */
- rtw_write32(adapt, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
- rtw_write32(adapt, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
- rtw_write32(adapt, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
- rtw_write8(adapt, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
- }
-
- if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {
- /* rst p2p circuit */
- rtw_write8(adapt, REG_DUAL_TSF_RST, BIT(4));
-
- p2p_ps_offload->Offload_En = 1;
-
- if (pwdinfo->role == 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:
- DBG_88E("P2P_PS_SCAN\n");
- p2p_ps_offload->discovery = 1;
- break;
- case P2P_PS_SCAN_DONE:
- DBG_88E("P2P_PS_SCAN_DONE\n");
- p2p_ps_offload->discovery = 0;
- pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
- break;
- default:
- break;
- }
-
- FillH2CCmd_88E(adapt, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload);
-#endif
-
-}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
index d5cd30bcb3c7..dab4c337a863 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_dm.c
@@ -36,10 +36,10 @@ static void dm_InitGPIOSetting(struct adapter *Adapter)
{
u8 tmp1byte;
- tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
+ tmp1byte = usb_read8(Adapter, REG_GPIO_MUXCFG);
tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
- rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
+ usb_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
}
/* */
@@ -53,7 +53,7 @@ static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
u8 cut_ver, fab_ver;
/* Init Value */
- _rtw_memset(dm_odm, 0, sizeof(*dm_odm));
+ memset(dm_odm, 0, sizeof(*dm_odm));
dm_odm->Adapter = Adapter;
@@ -198,7 +198,7 @@ void rtl8188e_init_dm_priv(struct adapter *Adapter)
struct dm_priv *pdmpriv = &hal_data->dmpriv;
struct odm_dm_struct *podmpriv = &hal_data->odmpriv;
- _rtw_memset(pdmpriv, 0, sizeof(struct dm_priv));
+ memset(pdmpriv, 0, sizeof(struct dm_priv));
Init_ODM_ComInfo_88E(Adapter);
ODM_InitDebugSetting(podmpriv);
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
index 5a22c6df4d06..fbf70f6a0151 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
@@ -28,16 +28,14 @@
#include <rtw_iol.h>
-#include <usb_ops.h>
-
-static void iol_mode_enable(struct adapter *padapter, u8 enable)
+void iol_mode_enable(struct adapter *padapter, u8 enable)
{
u8 reg_0xf0 = 0;
if (enable) {
/* Enable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
- rtw_write8(padapter, REG_SYS_CFG, reg_0xf0|SW_OFFLOAD_EN);
+ reg_0xf0 = usb_read8(padapter, REG_SYS_CFG);
+ usb_write8(padapter, REG_SYS_CFG, reg_0xf0|SW_OFFLOAD_EN);
if (!padapter->bFWReady) {
DBG_88E("bFWReady == false call reset 8051...\n");
@@ -46,28 +44,28 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
} else {
/* disable initial offload */
- reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
- rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
+ reg_0xf0 = usb_read8(padapter, REG_SYS_CFG);
+ usb_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
}
}
-static s32 iol_execute(struct adapter *padapter, u8 control)
+s32 iol_execute(struct adapter *padapter, u8 control)
{
s32 status = _FAIL;
u8 reg_0x88 = 0;
u32 start = 0, passing_time = 0;
control = control&0x0f;
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
- rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88|control);
+ reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0);
+ usb_write8(padapter, REG_HMEBOX_E0, reg_0x88|control);
start = jiffies;
- while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
+ while ((reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0)) & control &&
(passing_time = rtw_get_passing_time_ms(start)) < 1000) {
;
}
- reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+ reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0);
status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
if (reg_0x88 & control<<4)
status = _FAIL;
@@ -78,233 +76,12 @@ static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
{
s32 rst = _SUCCESS;
iol_mode_enable(padapter, 1);
- rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
+ usb_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
rst = iol_execute(padapter, CMD_INIT_LLT);
iol_mode_enable(padapter, 0);
return rst;
}
-static void
-efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
-{
- u8 *efuseTbl = NULL;
- u8 rtemp8;
- u16 eFuse_Addr = 0;
- u8 offset, wren;
- u16 i, j;
- u16 **eFuseWord = NULL;
- u16 efuse_utilized = 0;
- u8 u1temp = 0;
-
- efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
- if (efuseTbl == NULL) {
- DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
- goto exit;
- }
-
- eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
- if (eFuseWord == NULL) {
- DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
- goto exit;
- }
-
- /* 0. Refresh efuse init map as all oxFF. */
- for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
- for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
- eFuseWord[i][j] = 0xFFFF;
-
- /* */
- /* 1. Read the first byte to check if efuse is empty!!! */
- /* */
- /* */
- rtemp8 = *(phymap+eFuse_Addr);
- if (rtemp8 != 0xFF) {
- efuse_utilized++;
- eFuse_Addr++;
- } else {
- DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8);
- goto exit;
- }
-
- /* */
- /* 2. Read real efuse content. Filter PG header and every section data. */
- /* */
- while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
- /* Check PG header for section num. */
- if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */
- u1temp = ((rtemp8 & 0xE0) >> 5);
- rtemp8 = *(phymap+eFuse_Addr);
- if ((rtemp8 & 0x0F) == 0x0F) {
- eFuse_Addr++;
- rtemp8 = *(phymap+eFuse_Addr);
-
- if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
- 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_88E) {
- /* Get word enable value from PG header */
- for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
- /* Check word enable condition in the section */
- if (!(wren & 0x01)) {
- rtemp8 = *(phymap+eFuse_Addr);
- eFuse_Addr++;
- efuse_utilized++;
- eFuseWord[offset][i] = (rtemp8 & 0xff);
- if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
- break;
- rtemp8 = *(phymap+eFuse_Addr);
- eFuse_Addr++;
- efuse_utilized++;
- eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
-
- if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
- break;
- }
- wren >>= 1;
- }
- }
- /* Read next PG header */
- rtemp8 = *(phymap+eFuse_Addr);
-
- if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
- efuse_utilized++;
- eFuse_Addr++;
- }
- }
-
- /* */
- /* 3. Collect 16 sections and 4 word unit into Efuse map. */
- /* */
- for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
- for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
- efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff);
- efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff);
- }
- }
-
- /* */
- /* 4. Copy from Efuse map to output pointer memory!!! */
- /* */
- for (i = 0; i < _size_byte; i++)
- pbuf[i] = efuseTbl[_offset+i];
-
- /* */
- /* 5. Calculate Efuse utilization. */
- /* */
-
-exit:
- kfree(efuseTbl);
-
- if (eFuseWord)
- rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
-}
-
-static void efuse_read_phymap_from_txpktbuf(
- struct adapter *adapter,
- int bcnhead, /* beacon head, where FW store len(2-byte) and efuse physical map. */
- u8 *content, /* buffer to store efuse physical map */
- u16 *size /* for efuse content: the max byte to read. will update to byte read */
- )
-{
- u16 dbg_addr = 0;
- u32 start = 0, passing_time = 0;
- u8 reg_0x143 = 0;
- u32 lo32 = 0, hi32 = 0;
- u16 len = 0, count = 0;
- int i = 0;
- u16 limit = *size;
-
- u8 *pos = content;
-
- if (bcnhead < 0) /* if not valid */
- bcnhead = rtw_read8(adapter, REG_TDECTRL+1);
-
- DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
-
- rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
-
- dbg_addr = bcnhead*128/8; /* 8-bytes addressing */
-
- while (1) {
- rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr+i);
-
- rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
- start = jiffies;
- while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
- (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
- DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
- msleep(1);
- }
-
- lo32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L);
- hi32 = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H);
-
- if (i == 0) {
- u8 lenc[2];
- u16 lenbak, aaabak;
- u16 aaa;
- lenc[0] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L);
- lenc[1] = rtw_read8(adapter, REG_PKTBUF_DBG_DATA_L+1);
-
- aaabak = le16_to_cpup((__le16 *)lenc);
- lenbak = le16_to_cpu(*((__le16 *)lenc));
- aaa = le16_to_cpup((__le16 *)&lo32);
- len = le16_to_cpu(*((__le16 *)&lo32));
-
- limit = (len-2 < limit) ? len-2 : limit;
-
- DBG_88E("%s len:%u, lenbak:%u, aaa:%u, aaabak:%u\n", __func__, len, lenbak, aaa, aaabak);
-
- memcpy(pos, ((u8 *)&lo32)+2, (limit >= count+2) ? 2 : limit-count);
- count += (limit >= count+2) ? 2 : limit-count;
- pos = content+count;
-
- } else {
- memcpy(pos, ((u8 *)&lo32), (limit >= count+4) ? 4 : limit-count);
- count += (limit >= count+4) ? 4 : limit-count;
- pos = content+count;
- }
-
- if (limit > count && len-2 > count) {
- memcpy(pos, (u8 *)&hi32, (limit >= count+4) ? 4 : limit-count);
- count += (limit >= count+4) ? 4 : limit-count;
- pos = content+count;
- }
-
- if (limit <= count || len-2 <= count)
- break;
- i++;
- }
- rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
- DBG_88E("%s read count:%u\n", __func__, count);
- *size = count;
-}
-
-static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
-{
- s32 status = _FAIL;
- u8 physical_map[512];
- u16 size = 512;
-
- rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
- _rtw_memset(physical_map, 0xFF, 512);
- rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
- status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
- if (status == _SUCCESS)
- efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
- efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
- return status;
-}
s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
{
@@ -326,7 +103,7 @@ static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
{
s32 rst = _SUCCESS;
- rtw_write8(padapter, REG_TDECTRL+1, iocfg_bndy);
+ usb_write8(padapter, REG_TDECTRL+1, iocfg_bndy);
rst = iol_execute(padapter, CMD_IOCONFIG);
return rst;
}
@@ -357,7 +134,7 @@ static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_fram
iol_mode_enable(adapter, 0);
exit:
/* restore BCN_HEAD */
- rtw_write8(adapter, REG_TDECTRL+1, 0);
+ usb_write8(adapter, REG_TDECTRL+1, 0);
return ret;
}
@@ -369,19 +146,19 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
u8 *pbuf = vzalloc(data_len+10);
DBG_88E("###### %s ######\n", __func__);
- rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
+ usb_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
if (pbuf) {
for (addr = 0; addr < data_cnts; addr++) {
- rtw_write32(Adapter, 0x140, addr);
+ usb_write32(Adapter, 0x140, addr);
msleep(1);
loop = 0;
do {
- rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL)&BIT24);
+ rstatus = (reg_140 = usb_read32(Adapter, REG_PKTBUF_DBG_CTRL)&BIT24);
if (rstatus) {
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+ fifo_data = usb_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
memcpy(pbuf+(addr*8), &fifo_data, 4);
- fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+ fifo_data = usb_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
memcpy(pbuf+(addr*8+4), &fifo_data, 4);
}
msleep(1);
@@ -399,19 +176,19 @@ static void _FWDownloadEnable(struct adapter *padapter, bool enable)
if (enable) {
/* MCU firmware download enable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
- rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
+ tmp = usb_read8(padapter, REG_MCUFWDL);
+ usb_write8(padapter, REG_MCUFWDL, tmp | 0x01);
/* 8051 reset */
- tmp = rtw_read8(padapter, REG_MCUFWDL+2);
- rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
+ tmp = usb_read8(padapter, REG_MCUFWDL+2);
+ usb_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
} else {
/* MCU firmware download disable. */
- tmp = rtw_read8(padapter, REG_MCUFWDL);
- rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
+ tmp = usb_read8(padapter, REG_MCUFWDL);
+ usb_write8(padapter, REG_MCUFWDL, tmp&0xfe);
/* Reserved for fw extension. */
- rtw_write8(padapter, REG_MCUFWDL+1, 0x00);
+ usb_write8(padapter, REG_MCUFWDL+1, 0x00);
}
}
@@ -441,7 +218,7 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
}
for (i = 0; i < blockCount_p1; i++) {
- ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
+ ret = usb_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
if (ret == _FAIL)
goto exit;
}
@@ -460,7 +237,7 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
}
for (i = 0; i < blockCount_p2; i++) {
- ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
+ ret = usb_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
if (ret == _FAIL)
goto exit;
@@ -478,7 +255,7 @@ static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
(buffSize-offset), blockSize_p3, blockCount_p3));
for (i = 0; i < blockCount_p3; i++) {
- ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
+ ret = usb_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
if (ret == _FAIL)
goto exit;
@@ -494,8 +271,8 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
u8 value8;
u8 u8Page = (u8)(page & 0x07);
- value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page;
- rtw_write8(padapter, REG_MCUFWDL+2, value8);
+ value8 = (usb_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page;
+ usb_write8(padapter, REG_MCUFWDL+2, value8);
return _BlockWrite(padapter, buffer, size);
}
@@ -536,9 +313,9 @@ void _8051Reset88E(struct adapter *padapter)
{
u8 u1bTmp;
- u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
- rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
- rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));
+ u1bTmp = usb_read8(padapter, REG_SYS_FUNC_EN+1);
+ usb_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
+ usb_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));
DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
}
@@ -549,7 +326,7 @@ static s32 _FWFreeToGo(struct adapter *padapter)
/* polling CheckSum report */
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = usb_read32(padapter, REG_MCUFWDL);
if (value32 & FWDL_ChkSum_rpt)
break;
} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -560,17 +337,17 @@ static s32 _FWFreeToGo(struct adapter *padapter)
}
DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = usb_read32(padapter, REG_MCUFWDL);
value32 |= MCUFWDL_RDY;
value32 &= ~WINTINI_RDY;
- rtw_write32(padapter, REG_MCUFWDL, value32);
+ usb_write32(padapter, REG_MCUFWDL, value32);
_8051Reset88E(padapter);
/* polling for FW ready */
counter = 0;
do {
- value32 = rtw_read32(padapter, REG_MCUFWDL);
+ value32 = usb_read32(padapter, REG_MCUFWDL);
if (value32 & WINTINI_RDY) {
DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
return _SUCCESS;
@@ -666,8 +443,8 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
/* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
/* or it will cause download Fw fail. 2010.02.01. by tynli. */
- if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
- rtw_write8(padapter, REG_MCUFWDL, 0x00);
+ if (usb_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+ usb_write8(padapter, REG_MCUFWDL, 0x00);
_8051Reset88E(padapter);
}
@@ -675,7 +452,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
fwdl_start_time = jiffies;
while (1) {
/* reset the FWDL chksum */
- rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+ usb_write8(padapter, REG_MCUFWDL, usb_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
@@ -720,1021 +497,6 @@ static void rtl8188e_free_hal_data(struct adapter *padapter)
padapter->HalData = NULL;
}
-/* */
-/* Efuse related code */
-/* */
-enum{
- VOLTAGE_V25 = 0x03,
- LDOE25_SHIFT = 28 ,
- };
-
-static bool
-hal_EfusePgPacketWrite2ByteHeader(
- struct adapter *pAdapter,
- u8 efuseType,
- u16 *pAddr,
- struct pgpkt *pTargetPkt,
- bool bPseudoTest);
-static bool
-hal_EfusePgPacketWrite1ByteHeader(
- struct adapter *pAdapter,
- u8 efuseType,
- u16 *pAddr,
- struct pgpkt *pTargetPkt,
- bool bPseudoTest);
-static bool
-hal_EfusePgPacketWriteData(
- struct adapter *pAdapter,
- u8 efuseType,
- u16 *pAddr,
- struct pgpkt *pTargetPkt,
- bool bPseudoTest);
-
-static void
-hal_EfusePowerSwitch_RTL8188E(
- struct adapter *pAdapter,
- u8 bWrite,
- u8 PwrState)
-{
- u8 tempval;
- u16 tmpV16;
-
- if (PwrState) {
- rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
-
- /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
- if (!(tmpV16 & PWC_EV12V)) {
- tmpV16 |= PWC_EV12V;
- rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
- }
- /* Reset: 0x0000h[28], default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
- if (!(tmpV16 & FEN_ELDR)) {
- tmpV16 |= FEN_ELDR;
- rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
- }
-
- /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
- tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
- if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
- tmpV16 |= (LOADER_CLK_EN | ANA8M);
- rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
- }
-
- if (bWrite) {
- /* Enable LDO 2.5V before read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
- tempval &= 0x0F;
- tempval |= (VOLTAGE_V25 << 4);
- rtw_write8(pAdapter, EFUSE_TEST+3, (tempval | 0x80));
- }
- } else {
- rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
-
- if (bWrite) {
- /* Disable LDO 2.5V after read/write action */
- tempval = rtw_read8(pAdapter, EFUSE_TEST+3);
- rtw_write8(pAdapter, EFUSE_TEST+3, (tempval & 0x7F));
- }
- }
-}
-
-static void
-rtl8188e_EfusePowerSwitch(
- struct adapter *pAdapter,
- u8 bWrite,
- u8 PwrState)
-{
- hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
-}
-
-
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
- u16 _offset,
- u16 _size_byte,
- u8 *pbuf,
- bool bPseudoTest
- )
-{
- u8 *efuseTbl = NULL;
- u8 rtemp8[1];
- u16 eFuse_Addr = 0;
- u8 offset, wren;
- u16 i, j;
- u16 **eFuseWord = NULL;
- u16 efuse_utilized = 0;
- u8 u1temp = 0;
-
- /* */
- /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
- /* */
- if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/* total E-Fuse table is 512bytes */
- DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
- goto exit;
- }
-
- efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_88E);
- if (efuseTbl == NULL) {
- DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
- goto exit;
- }
-
- eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
- if (eFuseWord == NULL) {
- DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
- goto exit;
- }
-
- /* 0. Refresh efuse init map as all oxFF. */
- for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
- for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
- eFuseWord[i][j] = 0xFFFF;
-
- /* */
- /* 1. Read the first byte to check if efuse is empty!!! */
- /* */
- /* */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
- if (*rtemp8 != 0xFF) {
- efuse_utilized++;
- eFuse_Addr++;
- } else {
- DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
- goto exit;
- }
-
- /* */
- /* 2. Read real efuse content. Filter PG header and every section data. */
- /* */
- while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
- /* Check PG header for section num. */
- if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
- u1temp = ((*rtemp8 & 0xE0) >> 5);
-
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
-
- if ((*rtemp8 & 0x0F) == 0x0F) {
- eFuse_Addr++;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
-
- if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
- 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_88E) {
- /* Get word enable value from PG header */
-
- for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
- /* Check word enable condition in the section */
- if (!(wren & 0x01)) {
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
- eFuse_Addr++;
- efuse_utilized++;
- eFuseWord[offset][i] = (*rtemp8 & 0xff);
- if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
- break;
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
- eFuse_Addr++;
- efuse_utilized++;
- eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
- if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
- break;
- }
- wren >>= 1;
- }
- }
-
- /* Read next PG header */
- ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
-
- if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
- efuse_utilized++;
- eFuse_Addr++;
- }
- }
-
- /* 3. Collect 16 sections and 4 word unit into Efuse map. */
- for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
- for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
- efuseTbl[(i*8)+(j*2)] = (eFuseWord[i][j] & 0xff);
- efuseTbl[(i*8)+((j*2)+1)] = ((eFuseWord[i][j] >> 8) & 0xff);
- }
- }
-
- /* 4. Copy from Efuse map to output pointer memory!!! */
- for (i = 0; i < _size_byte; i++)
- pbuf[i] = efuseTbl[_offset+i];
-
- /* 5. Calculate Efuse utilization. */
- rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
-
-exit:
- kfree(efuseTbl);
-
- if (eFuseWord)
- rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
-}
-
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
-{
- if (!bPseudoTest) {
- int ret = _FAIL;
- if (rtw_IOL_applied(Adapter)) {
- rtw_hal_power_on(Adapter);
-
- iol_mode_enable(Adapter, 1);
- ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
- iol_mode_enable(Adapter, 0);
-
- if (_SUCCESS == ret)
- goto exit;
- }
- }
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-
-exit:
- return;
-}
-
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
-{
- Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-}
-
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
- u16 _offset, u16 _size_byte, u8 *pbuf,
- bool bPseudoTest)
-{
- if (bPseudoTest)
- ReadEFuse_Pseudo (Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
- else
- ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
-}
-
-/* Do not support BT */
-static void Hal_EFUSEGetEfuseDefinition88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
-{
- switch (type) {
- case TYPE_EFUSE_MAX_SECTION:
- {
- u8 *pMax_section;
- pMax_section = (u8 *)pOut;
- *pMax_section = EFUSE_MAX_SECTION_88E;
- }
- break;
- case TYPE_EFUSE_REAL_CONTENT_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_EFUSE_CONTENT_LEN_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_EFUSE_MAP_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
- }
- break;
- case TYPE_EFUSE_PROTECT_BYTES_BANK:
- {
- u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
- *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- default:
- {
- u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
- *pu1Tmp = 0;
- }
- break;
- }
-}
-
-static void Hal_EFUSEGetEfuseDefinition_Pseudo88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
-{
- switch (type) {
- case TYPE_EFUSE_MAX_SECTION:
- {
- u8 *pMax_section;
- pMax_section = (u8 *)pOut;
- *pMax_section = EFUSE_MAX_SECTION_88E;
- }
- break;
- case TYPE_EFUSE_REAL_CONTENT_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_EFUSE_CONTENT_LEN_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E-EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- case TYPE_EFUSE_MAP_LEN:
- {
- u16 *pu2Tmp;
- pu2Tmp = (u16 *)pOut;
- *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
- }
- break;
- case TYPE_EFUSE_PROTECT_BYTES_BANK:
- {
- u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
- *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
- }
- break;
- default:
- {
- u8 *pu1Tmp;
- pu1Tmp = (u8 *)pOut;
- *pu1Tmp = 0;
- }
- break;
- }
-}
-
-static void rtl8188e_EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest)
-{
- if (bPseudoTest)
- Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
- else
- Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
-}
-
-static u8 Hal_EfuseWordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
-{
- u16 tmpaddr = 0;
- u16 start_addr = efuse_addr;
- u8 badworden = 0x0F;
- u8 tmpdata[8];
-
- _rtw_memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
-
- if (!(word_en&BIT0)) {
- tmpaddr = start_addr;
- efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);
- efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);
-
- efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest);
- efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
- if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
- badworden &= (~BIT0);
- }
- if (!(word_en&BIT1)) {
- tmpaddr = start_addr;
- efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);
- efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);
-
- efuse_OneByteRead(pAdapter, tmpaddr , &tmpdata[2], bPseudoTest);
- efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
- if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
- badworden &= (~BIT1);
- }
- if (!(word_en&BIT2)) {
- tmpaddr = start_addr;
- efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);
- efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);
-
- efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest);
- efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
- if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
- badworden &= (~BIT2);
- }
- if (!(word_en&BIT3)) {
- tmpaddr = start_addr;
- efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);
- efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);
-
- efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest);
- efuse_OneByteRead(pAdapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
- if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
- badworden &= (~BIT3);
- }
- return badworden;
-}
-
-static u8 Hal_EfuseWordEnableDataWrite_Pseudo(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
-{
- u8 ret;
-
- ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
- return ret;
-}
-
-static u8 rtl8188e_Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
-{
- u8 ret = 0;
-
- if (bPseudoTest)
- ret = Hal_EfuseWordEnableDataWrite_Pseudo (pAdapter, efuse_addr, word_en, data, bPseudoTest);
- else
- ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
- return ret;
-}
-
-static u16 hal_EfuseGetCurrentSize_8188e(struct adapter *pAdapter, bool bPseudoTest)
-{
- int bContinual = true;
- u16 efuse_addr = 0;
- u8 hoffset = 0, hworden = 0;
- u8 efuse_data, word_cnts = 0;
-
- if (bPseudoTest)
- efuse_addr = (u16)(fakeEfuseUsedBytes);
- else
- rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
-
- while (bContinual &&
- efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) &&
- AVAILABLE_EFUSE_ADDR(efuse_addr)) {
- if (efuse_data != 0xFF) {
- if ((efuse_data&0x1F) == 0x0F) { /* extended header */
- hoffset = efuse_data;
- efuse_addr++;
- efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
- if ((efuse_data & 0x0F) == 0x0F) {
- efuse_addr++;
- continue;
- } else {
- hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
- hworden = efuse_data & 0x0F;
- }
- } else {
- hoffset = (efuse_data>>4) & 0x0F;
- hworden = efuse_data & 0x0F;
- }
- word_cnts = Efuse_CalculateWordCnts(hworden);
- /* read next header */
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- } else {
- bContinual = false;
- }
- }
-
- if (bPseudoTest)
- fakeEfuseUsedBytes = efuse_addr;
- else
- rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
-
- return efuse_addr;
-}
-
-static u16 Hal_EfuseGetCurrentSize_Pseudo(struct adapter *pAdapter, bool bPseudoTest)
-{
- u16 ret = 0;
-
- ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
- return ret;
-}
-
-static u16 rtl8188e_EfuseGetCurrentSize(struct adapter *pAdapter, u8 efuseType, bool bPseudoTest)
-{
- u16 ret = 0;
-
- if (bPseudoTest)
- ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
- else
- ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
- return ret;
-}
-
-static int hal_EfusePgPacketRead_8188e(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
-{
- u8 ReadState = PG_STATE_HEADER;
- int bContinual = true;
- int bDataEmpty = true;
- u8 efuse_data, word_cnts = 0;
- u16 efuse_addr = 0;
- u8 hoffset = 0, hworden = 0;
- u8 tmpidx = 0;
- u8 tmpdata[8];
- u8 max_section = 0;
- u8 tmp_header = 0;
-
- EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);
-
- if (data == NULL)
- return false;
- if (offset > max_section)
- return false;
-
- _rtw_memset((void *)data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
- _rtw_memset((void *)tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
-
- /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
- /* Skip dummy parts to prevent unexpected data read from Efuse. */
- /* By pass right now. 2009.02.19. */
- while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
- /* Header Read ------------- */
- if (ReadState & PG_STATE_HEADER) {
- if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
- if (EXT_HEADER(efuse_data)) {
- tmp_header = efuse_data;
- efuse_addr++;
- efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
- if (!ALL_WORDS_DISABLED(efuse_data)) {
- hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
- hworden = efuse_data & 0x0F;
- } else {
- DBG_88E("Error, All words disabled\n");
- efuse_addr++;
- continue;
- }
- } else {
- hoffset = (efuse_data>>4) & 0x0F;
- hworden = efuse_data & 0x0F;
- }
- word_cnts = Efuse_CalculateWordCnts(hworden);
- bDataEmpty = true;
-
- if (hoffset == offset) {
- for (tmpidx = 0; tmpidx < word_cnts*2; tmpidx++) {
- if (efuse_OneByteRead(pAdapter, efuse_addr+1+tmpidx, &efuse_data, bPseudoTest)) {
- tmpdata[tmpidx] = efuse_data;
- if (efuse_data != 0xff)
- bDataEmpty = false;
- }
- }
- if (bDataEmpty == false) {
- ReadState = PG_STATE_DATA;
- } else {/* read next header */
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- ReadState = PG_STATE_HEADER;
- }
- } else {/* read next header */
- efuse_addr = efuse_addr + (word_cnts*2)+1;
- ReadState = PG_STATE_HEADER;
- }
- } else {
- bContinual = false;
- }
- } else if (ReadState & PG_STATE_DATA) {
- /* Data section Read ------------- */
- efuse_WordEnableDataRead(hworden, 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;
- else
- return true;
-}
-
-static int Hal_EfusePgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
-{
- int ret;
-
- ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
- return ret;
-}
-
-static int Hal_EfusePgPacketRead_Pseudo(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
-{
- int ret;
-
- ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
- return ret;
-}
-
-static int rtl8188e_Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
-{
- int ret;
-
- if (bPseudoTest)
- ret = Hal_EfusePgPacketRead_Pseudo (pAdapter, offset, data, bPseudoTest);
- else
- ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
- return ret;
-}
-
-static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr, bool bPseudoTest)
-{
- u8 originaldata[8], badworden = 0;
- u16 efuse_addr = *pAddr;
- u32 PgWriteSuccess = 0;
-
- _rtw_memset((void *)originaldata, 0xff, 8);
-
- if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
- /* check if data exist */
- badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest);
-
- if (badworden != 0xf) { /* write fail */
- PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
-
- if (!PgWriteSuccess)
- return false;
- else
- efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
- } else {
- efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
- }
- } else {
- efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) + 1;
- }
- *pAddr = efuse_addr;
- return true;
-}
-
-static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
-{
- bool bRet = false;
- u16 efuse_addr = *pAddr, efuse_max_available_len = 0;
- u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
- u8 repeatcnt = 0;
-
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
-
- while (efuse_addr < efuse_max_available_len) {
- pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
-
- while (tmp_header == 0xFF) {
- if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
- return false;
-
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
- }
-
- /* to write ext_header */
- if (tmp_header == pg_header) {
- efuse_addr++;
- pg_header_temp = pg_header;
- pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
-
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
-
- while (tmp_header == 0xFF) {
- if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
- return false;
-
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
- }
-
- if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */
- if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
- return false;
- } else {
- efuse_addr++;
- continue;
- }
- } else if (pg_header != tmp_header) { /* offset PG fail */
- struct pgpkt fixPkt;
- fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
- fixPkt.word_en = tmp_header & 0x0F;
- fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
- if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
- return false;
- } else {
- bRet = true;
- break;
- }
- } else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */
- efuse_addr += 2;
- continue;
- }
- }
-
- *pAddr = efuse_addr;
- return bRet;
-}
-
-static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
-{
- bool bRet = false;
- u8 pg_header = 0, tmp_header = 0;
- u16 efuse_addr = *pAddr;
- u8 repeatcnt = 0;
-
- pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
-
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
-
- while (tmp_header == 0xFF) {
- if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
- return false;
- efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
- efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
- }
-
- if (pg_header == tmp_header) {
- bRet = true;
- } else {
- struct pgpkt fixPkt;
- fixPkt.offset = (tmp_header>>4) & 0x0F;
- fixPkt.word_en = tmp_header & 0x0F;
- fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
- if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
- return false;
- }
-
- *pAddr = efuse_addr;
- return bRet;
-}
-
-static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
-{
- u16 efuse_addr = *pAddr;
- u8 badworden = 0;
- u32 PgWriteSuccess = 0;
-
- badworden = 0x0f;
- badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
- if (badworden == 0x0F) {
- /* write ok */
- return true;
- } else {
- /* reorganize other pg packet */
- PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
- if (!PgWriteSuccess)
- return false;
- else
- return true;
- }
-}
-
-static bool
-hal_EfusePgPacketWriteHeader(
- struct adapter *pAdapter,
- u8 efuseType,
- u16 *pAddr,
- struct pgpkt *pTargetPkt,
- bool bPseudoTest)
-{
- bool bRet = false;
-
- if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
- bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
- else
- bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
-
- return bRet;
-}
-
-static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
- u8 *pWden)
-{
- u8 match_word_en = 0x0F; /* default all words are disabled */
-
- /* check if the same words are enabled both target and current PG packet */
- if (((pTargetPkt->word_en & BIT0) == 0) &&
- ((pCurPkt->word_en & BIT0) == 0))
- match_word_en &= ~BIT0; /* enable word 0 */
- if (((pTargetPkt->word_en & BIT1) == 0) &&
- ((pCurPkt->word_en & BIT1) == 0))
- match_word_en &= ~BIT1; /* enable word 1 */
- if (((pTargetPkt->word_en & BIT2) == 0) &&
- ((pCurPkt->word_en & BIT2) == 0))
- match_word_en &= ~BIT2; /* enable word 2 */
- if (((pTargetPkt->word_en & BIT3) == 0) &&
- ((pCurPkt->word_en & BIT3) == 0))
- match_word_en &= ~BIT3; /* enable word 3 */
-
- *pWden = match_word_en;
-
- if (match_word_en != 0xf)
- return true;
- else
- return false;
-}
-
-static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr, bool bPseudoTest)
-{
- bool bRet = false;
- u8 i, efuse_data;
-
- for (i = 0; i < (word_cnts*2); i++) {
- if (efuse_OneByteRead(pAdapter, (startAddr+i), &efuse_data, bPseudoTest) && (efuse_data != 0xFF))
- bRet = true;
- }
- return bRet;
-}
-
-static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
-{
- bool bRet = false;
- u8 i, efuse_data = 0, cur_header = 0;
- u8 matched_wden = 0, badworden = 0;
- u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
- struct pgpkt curPkt;
-
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
- EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest);
-
- if (efuseType == EFUSE_WIFI) {
- if (bPseudoTest) {
- startAddr = (u16)(fakeEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
- } else {
- rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
- startAddr %= EFUSE_REAL_CONTENT_LEN;
- }
- } else {
- if (bPseudoTest)
- startAddr = (u16)(fakeBTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
- else
- startAddr = (u16)(BTEfuseUsedBytes%EFUSE_REAL_CONTENT_LEN);
- }
-
- while (1) {
- if (startAddr >= efuse_max_available_len) {
- bRet = false;
- break;
- }
-
- if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
- if (EXT_HEADER(efuse_data)) {
- cur_header = efuse_data;
- startAddr++;
- efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
- if (ALL_WORDS_DISABLED(efuse_data)) {
- bRet = false;
- break;
- } else {
- curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
- curPkt.word_en = efuse_data & 0x0F;
- }
- } else {
- cur_header = efuse_data;
- curPkt.offset = (cur_header>>4) & 0x0F;
- curPkt.word_en = cur_header & 0x0F;
- }
-
- curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
- /* if same header is found but no data followed */
- /* write some part of data followed by the header. */
- if ((curPkt.offset == pTargetPkt->offset) &&
- (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr+1, bPseudoTest)) &&
- wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
- /* Here to write partial data */
- badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
- if (badworden != 0x0F) {
- u32 PgWriteSuccess = 0;
- /* if write fail on some words, write these bad words again */
-
- PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
-
- if (!PgWriteSuccess) {
- bRet = false; /* write fail, return */
- break;
- }
- }
- /* partial write ok, update the target packet for later use */
- for (i = 0; i < 4; i++) {
- if ((matched_wden & (0x1<<i)) == 0) /* this word has been written */
- pTargetPkt->word_en |= (0x1<<i); /* disable the word */
- }
- pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
- }
- /* read from next header */
- startAddr = startAddr + (curPkt.word_cnts*2) + 1;
- } else {
- /* not used header, 0xff */
- *pAddr = startAddr;
- bRet = true;
- break;
- }
- }
- return bRet;
-}
-
-static bool
-hal_EfusePgCheckAvailableAddr(
- struct adapter *pAdapter,
- u8 efuseType,
- bool bPseudoTest
- )
-{
- u16 efuse_max_available_len = 0;
-
- /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
- EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
-
- if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
- return false;
- return true;
-}
-
-static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt)
-{
- _rtw_memset((void *)pTargetPkt->data, 0xFF, sizeof(u8)*8);
- pTargetPkt->offset = offset;
- pTargetPkt->word_en = word_en;
- efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
- pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
-}
-
-static bool hal_EfusePgPacketWrite_8188e(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData, bool bPseudoTest)
-{
- struct pgpkt targetPkt;
- u16 startAddr = 0;
- u8 efuseType = EFUSE_WIFI;
-
- if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
- return false;
-
- hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
-
- if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
- return false;
-
- if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
- return false;
-
- if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
- return false;
-
- return true;
-}
-
-static int Hal_EfusePgPacketWrite_Pseudo(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
-{
- int ret;
-
- ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
- return ret;
-}
-
-static int Hal_EfusePgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
-{
- int ret = 0;
- ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
-
- return ret;
-}
-
-static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
-{
- int ret;
-
- if (bPseudoTest)
- ret = Hal_EfusePgPacketWrite_Pseudo (pAdapter, offset, word_en, data, bPseudoTest);
- else
- ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
- return ret;
-}
-
static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
{
u32 value32;
@@ -1743,7 +505,7 @@ static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
pHalData = GET_HAL_DATA(padapter);
- value32 = rtw_read32(padapter, REG_SYS_CFG);
+ value32 = usb_read32(padapter, REG_SYS_CFG);
ChipVersion.ICType = CHIP_8188E;
ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
@@ -1755,7 +517,6 @@ static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
ChipVersion.ROMVer = 0; /* ROM code version. */
- pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
dump_chip_info(ChipVersion);
@@ -1782,10 +543,6 @@ static void rtl8188e_read_chip_version(struct adapter *padapter)
ReadChipVersion8188E(padapter);
}
-static void rtl8188e_GetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
-{
-}
-
static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
{
struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
@@ -1815,27 +572,14 @@ static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable
}
}
-void rtl8188e_clone_haldata(struct adapter *dst_adapter, struct adapter *src_adapter)
-{
- memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
-}
-
-void rtl8188e_start_thread(struct adapter *padapter)
-{
-}
-
-void rtl8188e_stop_thread(struct adapter *padapter)
-{
-}
-
static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
{
if (enable) {
DBG_88E("Enable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
+ usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
} else {
DBG_88E("Disable notch filter\n");
- rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
+ usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
}
}
void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
@@ -1852,8 +596,6 @@ void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid;
- pHalFunc->run_thread = &rtl8188e_start_thread;
- pHalFunc->cancel_thread = &rtl8188e_stop_thread;
pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E;
pHalFunc->AntDivCompareHandler = &AntDivCompare8188E;
@@ -1862,23 +604,9 @@ void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
pHalFunc->read_rfreg = &rtl8188e_PHY_QueryRFReg;
pHalFunc->write_rfreg = &rtl8188e_PHY_SetRFReg;
- /* Efuse related function */
- pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
- pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
- pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
- pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
- pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
- pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
- pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
-
pHalFunc->sreset_init_value = &sreset_init_value;
- pHalFunc->sreset_reset_value = &sreset_reset_value;
- pHalFunc->silentreset = &rtl8188e_silentreset_for_specific_platform;
- pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
- pHalFunc->sreset_linked_status_check = &rtl8188e_sreset_linked_status_check;
pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
- pHalFunc->GetHalODMVarHandler = &rtl8188e_GetHalODMVar;
pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar;
pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
@@ -1891,7 +619,7 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
u8 size = 0;
u32 cr;
- cr = rtw_read16(padapter, REG_9346CR);
+ cr = usb_read16(padapter, REG_9346CR);
/* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
@@ -1912,11 +640,11 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
u16 LLTReg = REG_LLT_INIT;
- rtw_write32(padapter, LLTReg, value);
+ usb_write32(padapter, LLTReg, value);
/* polling */
do {
- value = rtw_read32(padapter, LLTReg);
+ value = usb_read32(padapter, LLTReg);
if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
break;
@@ -1977,13 +705,13 @@ Hal_InitPGData88E(struct adapter *padapter)
if (!pEEPROM->bautoload_fail_flag) { /* autoload OK. */
if (!is_boot_from_eeprom(padapter)) {
/* Read EFUSE real map to shadow. */
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
}
} else {/* autoload fail */
RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
/* update to default value 0xFF */
if (!is_boot_from_eeprom(padapter))
- EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+ EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
}
}
@@ -2012,7 +740,7 @@ static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G,
{
u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
- _rtw_memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
+ memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
if (AutoLoadFail) {
for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
@@ -2350,29 +1078,6 @@ void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool Aut
DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter);
}
-void Hal_InitChannelPlan(struct adapter *padapter)
-{
-}
-
-bool HalDetectPwrDownMode88E(struct adapter *Adapter)
-{
- u8 tmpvalue = 0;
- struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
- struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
-
- EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
-
- /* 2010/08/25 MH INF priority > PDN Efuse value. */
- if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
- pHalData->pwrdown = true;
- else
- pHalData->pwrdown = false;
-
- DBG_88E("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown);
-
- return pHalData->pwrdown;
-} /* HalDetectPwrDownMode */
-
/* This function is used only for 92C to set REG_BCN_CTRL(0x550) register. */
/* We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate */
/* the value of the register via atomic operation. */
@@ -2388,5 +1093,5 @@ void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits)
pHalData->RegBcnCtrlVal |= SetBits;
pHalData->RegBcnCtrlVal &= ~ClearBits;
- rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
+ usb_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c b/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c
deleted file mode 100644
index a4d057cf7db2..000000000000
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTL8188E_MP_C_
-
-#include <drv_types.h>
-#include <rtw_mp.h>
-#include <rtl8188e_hal.h>
-#include <rtl8188e_dm.h>
-
-s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct odm_dm_struct *pDM_Odm = &(pHalData->odmpriv);
-
- if (!netif_running(padapter->pnetdev)) {
- RT_TRACE(_module_mp_, _drv_warning_,
- ("SetPowerTracking! Fail: interface not opened!\n"));
- return _FAIL;
- }
-
- if (!check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE)) {
- RT_TRACE(_module_mp_, _drv_warning_,
- ("SetPowerTracking! Fail: not in MP mode!\n"));
- return _FAIL;
- }
-
- if (enable)
- pDM_Odm->RFCalibrateInfo.bTXPowerTracking = true;
- else
- pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = false;
-
- return _SUCCESS;
-}
-
-void Hal_GetPowerTracking(struct adapter *padapter, u8 *enable)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct odm_dm_struct *pDM_Odm = &(pHalData->odmpriv);
-
- *enable = pDM_Odm->RFCalibrateInfo.TxPowerTrackControl;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: mpt_SwitchRfSetting
- *
- * Overview: Change RF Setting when we siwthc channel/rate/BW for MP.
- *
- * Input: struct adapter * pAdapter
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 01/08/2009 MHC Suggestion from SD3 Willis for 92S series.
- * 01/09/2009 MHC Add CCK modification for 40MHZ. Suggestion from SD3.
- *
- *---------------------------------------------------------------------------*/
-void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter)
-{
- struct mp_priv *pmp = &pAdapter->mppriv;
-
- /* <20120525, Kordan> Dynamic mechanism for APK, asked by Dennis. */
- pmp->MptCtx.backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
- pmp->MptCtx.backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0);
- PHY_SetRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0, 0xD);
- PHY_SetRFReg(pAdapter, RF_PATH_B, RF_0x52, 0x000F0, 0xD);
-
- return;
-}
-/*---------------------------hal\rtl8192c\MPT_Phy.c---------------------------*/
-
-/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
-void Hal_MPT_CCKTxPowerAdjust(struct adapter *Adapter, bool bInCH14)
-{
- u32 TempVal = 0, TempVal2 = 0, TempVal3 = 0;
- u32 CurrCCKSwingVal = 0, CCKSwingIndex = 12;
- u8 i;
-
- /* get current cck swing value and check 0xa22 & 0xa23 later to match the table. */
- CurrCCKSwingVal = read_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord);
-
- if (!bInCH14) {
- /* Readback the current bb cck swing value and compare with the table to */
- /* get the current swing index */
- for (i = 0; i < CCK_TABLE_SIZE; i++) {
- if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch1_Ch13[i][0]) &&
- (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch1_Ch13[i][1])) {
- CCKSwingIndex = i;
- break;
- }
- }
-
- /* Write 0xa22 0xa23 */
- TempVal = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][0] +
- (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][1]<<8);
-
-
- /* Write 0xa24 ~ 0xa27 */
- TempVal2 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][2] +
- (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][3]<<8) +
- (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][4]<<16)+
- (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][5]<<24);
-
- /* Write 0xa28 0xa29 */
- TempVal3 = CCKSwingTable_Ch1_Ch13[CCKSwingIndex][6] +
- (CCKSwingTable_Ch1_Ch13[CCKSwingIndex][7]<<8);
- } else {
- for (i = 0; i < CCK_TABLE_SIZE; i++) {
- if (((CurrCCKSwingVal&0xff) == (u32)CCKSwingTable_Ch14[i][0]) &&
- (((CurrCCKSwingVal&0xff00)>>8) == (u32)CCKSwingTable_Ch14[i][1])) {
- CCKSwingIndex = i;
- break;
- }
- }
-
- /* Write 0xa22 0xa23 */
- TempVal = CCKSwingTable_Ch14[CCKSwingIndex][0] +
- (CCKSwingTable_Ch14[CCKSwingIndex][1]<<8);
-
- /* Write 0xa24 ~ 0xa27 */
- TempVal2 = CCKSwingTable_Ch14[CCKSwingIndex][2] +
- (CCKSwingTable_Ch14[CCKSwingIndex][3]<<8) +
- (CCKSwingTable_Ch14[CCKSwingIndex][4]<<16)+
- (CCKSwingTable_Ch14[CCKSwingIndex][5]<<24);
-
- /* Write 0xa28 0xa29 */
- TempVal3 = CCKSwingTable_Ch14[CCKSwingIndex][6] +
- (CCKSwingTable_Ch14[CCKSwingIndex][7]<<8);
- }
-
- write_bbreg(Adapter, rCCK0_TxFilter1, bMaskHWord, TempVal);
- write_bbreg(Adapter, rCCK0_TxFilter2, bMaskDWord, TempVal2);
- write_bbreg(Adapter, rCCK0_DebugPort, bMaskLWord, TempVal3);
-}
-
-void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
- struct odm_dm_struct *pDM_Odm = &(pHalData->odmpriv);
- s32 TempCCk;
- u8 CCK_index, CCK_index_old = 0;
- u8 Action = 0; /* 0: no action, 1: even->odd, 2:odd->even */
- s32 i = 0;
-
-
- if (!IS_92C_SERIAL(pHalData->VersionID))
- return;
- if (beven && !pMptCtx->bMptIndexEven) {
- /* odd->even */
- Action = 2;
- pMptCtx->bMptIndexEven = true;
- } else if (!beven && pMptCtx->bMptIndexEven) {
- /* even->odd */
- Action = 1;
- pMptCtx->bMptIndexEven = false;
- }
-
- if (Action != 0) {
- /* Query CCK default setting From 0xa24 */
- TempCCk = read_bbreg(pAdapter, rCCK0_TxFilter2, bMaskDWord) & bMaskCCK;
- for (i = 0; i < CCK_TABLE_SIZE; i++) {
- if (pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
- if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch14[i][2], 4)) {
- CCK_index_old = (u8)i;
- break;
- }
- } else {
- if (!memcmp((void *)&TempCCk, (void *)&CCKSwingTable_Ch1_Ch13[i][2], 4)) {
- CCK_index_old = (u8)i;
- break;
- }
- }
- }
-
- if (Action == 1)
- CCK_index = CCK_index_old - 1;
- else
- CCK_index = CCK_index_old + 1;
-
- if (CCK_index > 32)
- CCK_index = 32;
- /* Adjust CCK according to gain index */
- if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
- rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]);
- rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch1_Ch13[CCK_index][1]);
- rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch1_Ch13[CCK_index][2]);
- rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch1_Ch13[CCK_index][3]);
- rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch1_Ch13[CCK_index][4]);
- rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch1_Ch13[CCK_index][5]);
- rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch1_Ch13[CCK_index][6]);
- rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch1_Ch13[CCK_index][7]);
- } else {
- rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch14[CCK_index][0]);
- rtw_write8(pAdapter, 0xa23, CCKSwingTable_Ch14[CCK_index][1]);
- rtw_write8(pAdapter, 0xa24, CCKSwingTable_Ch14[CCK_index][2]);
- rtw_write8(pAdapter, 0xa25, CCKSwingTable_Ch14[CCK_index][3]);
- rtw_write8(pAdapter, 0xa26, CCKSwingTable_Ch14[CCK_index][4]);
- rtw_write8(pAdapter, 0xa27, CCKSwingTable_Ch14[CCK_index][5]);
- rtw_write8(pAdapter, 0xa28, CCKSwingTable_Ch14[CCK_index][6]);
- rtw_write8(pAdapter, 0xa29, CCKSwingTable_Ch14[CCK_index][7]);
- }
- }
-}
-/*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
-
-/*
- * SetChannel
- * Description
- * Use H2C command to change channel,
- * not only modify rf register, but also other setting need to be done.
- */
-void Hal_SetChannel(struct adapter *pAdapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- struct mp_priv *pmp = &pAdapter->mppriv;
- struct odm_dm_struct *pDM_Odm = &(pHalData->odmpriv);
- u8 eRFPath;
- u8 channel = pmp->channel;
-
- /* set RF channel register */
- for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
- _write_rfreg(pAdapter, eRFPath, ODM_CHANNEL, 0x3FF, channel);
- Hal_mpt_SwitchRfSetting(pAdapter);
-
- SelectChannel(pAdapter, channel);
-
- if (pHalData->CurrentChannel == 14 && !pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
- pDM_Odm->RFCalibrateInfo.bCCKinCH14 = true;
- Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14);
- } else if (pHalData->CurrentChannel != 14 && pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
- pDM_Odm->RFCalibrateInfo.bCCKinCH14 = false;
- Hal_MPT_CCKTxPowerAdjust(pAdapter, pDM_Odm->RFCalibrateInfo.bCCKinCH14);
- }
-}
-
-/*
- * Notice
- * Switch bandwitdth may change center frequency(channel)
- */
-void Hal_SetBandwidth(struct adapter *pAdapter)
-{
- struct mp_priv *pmp = &pAdapter->mppriv;
-
-
- SetBWMode(pAdapter, pmp->bandwidth, pmp->prime_channel_offset);
- Hal_mpt_SwitchRfSetting(pAdapter);
-}
-
-void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 *TxPower)
-{
- u32 tmpval = 0;
-
-
- /* rf-A cck tx power */
- write_bbreg(pAdapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, TxPower[RF_PATH_A]);
- tmpval = (TxPower[RF_PATH_A]<<16) | (TxPower[RF_PATH_A]<<8) | TxPower[RF_PATH_A];
- write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
-
- /* rf-B cck tx power */
- write_bbreg(pAdapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, TxPower[RF_PATH_B]);
- tmpval = (TxPower[RF_PATH_B]<<16) | (TxPower[RF_PATH_B]<<8) | TxPower[RF_PATH_B];
- write_bbreg(pAdapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
-
- RT_TRACE(_module_mp_, _drv_notice_,
- ("-SetCCKTxPower: A[0x%02x] B[0x%02x]\n",
- TxPower[RF_PATH_A], TxPower[RF_PATH_B]));
-}
-
-void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 *TxPower)
-{
- u32 TxAGC = 0;
- u8 tmpval = 0;
-
- /* HT Tx-rf(A) */
- tmpval = TxPower[RF_PATH_A];
- TxAGC = (tmpval<<24) | (tmpval<<16) | (tmpval<<8) | tmpval;
-
- write_bbreg(pAdapter, rTxAGC_A_Rate18_06, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_A_Rate54_24, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_A_Mcs03_Mcs00, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_A_Mcs07_Mcs04, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_A_Mcs11_Mcs08, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_A_Mcs15_Mcs12, bMaskDWord, TxAGC);
-
- /* HT Tx-rf(B) */
- tmpval = TxPower[RF_PATH_B];
- TxAGC = (tmpval<<24) | (tmpval<<16) | (tmpval<<8) | tmpval;
-
- write_bbreg(pAdapter, rTxAGC_B_Rate18_06, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_B_Rate54_24, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_B_Mcs03_Mcs00, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_B_Mcs07_Mcs04, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_B_Mcs11_Mcs08, bMaskDWord, TxAGC);
- write_bbreg(pAdapter, rTxAGC_B_Mcs15_Mcs12, bMaskDWord, TxAGC);
-}
-
-void Hal_SetAntennaPathPower(struct adapter *pAdapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- u8 TxPowerLevel[MAX_RF_PATH_NUMS];
- u8 rfPath;
-
- TxPowerLevel[RF_PATH_A] = pAdapter->mppriv.txpoweridx;
- TxPowerLevel[RF_PATH_B] = pAdapter->mppriv.txpoweridx_b;
-
- switch (pAdapter->mppriv.antenna_tx) {
- case ANTENNA_A:
- default:
- rfPath = RF_PATH_A;
- break;
- case ANTENNA_B:
- rfPath = RF_PATH_B;
- break;
- case ANTENNA_C:
- rfPath = RF_PATH_C;
- break;
- }
-
- switch (pHalData->rf_chip) {
- case RF_8225:
- case RF_8256:
- case RF_6052:
- Hal_SetCCKTxPower(pAdapter, TxPowerLevel);
- if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */
- Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath]%2 == 0);
- Hal_SetOFDMTxPower(pAdapter, TxPowerLevel);
- break;
- default:
- break;
- }
-}
-
-void Hal_SetTxPower(struct adapter *pAdapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- u8 TxPower = pAdapter->mppriv.txpoweridx;
- u8 TxPowerLevel[MAX_RF_PATH_NUMS];
- u8 rf, rfPath;
-
- for (rf = 0; rf < MAX_RF_PATH_NUMS; rf++)
- TxPowerLevel[rf] = TxPower;
-
- switch (pAdapter->mppriv.antenna_tx) {
- case ANTENNA_A:
- default:
- rfPath = RF_PATH_A;
- break;
- case ANTENNA_B:
- rfPath = RF_PATH_B;
- break;
- case ANTENNA_C:
- rfPath = RF_PATH_C;
- break;
- }
-
- switch (pHalData->rf_chip) {
- /* 2008/09/12 MH Test only !! We enable the TX power tracking for MP!!!!! */
- /* We should call normal driver API later!! */
- case RF_8225:
- case RF_8256:
- case RF_6052:
- Hal_SetCCKTxPower(pAdapter, TxPowerLevel);
- if (pAdapter->mppriv.rateidx < MPT_RATE_6M) /* CCK rate */
- Hal_MPT_CCKTxPowerAdjustbyIndex(pAdapter, TxPowerLevel[rfPath]%2 == 0);
- Hal_SetOFDMTxPower(pAdapter, TxPowerLevel);
- break;
- default:
- break;
- }
-}
-
-void Hal_SetDataRate(struct adapter *pAdapter)
-{
- Hal_mpt_SwitchRfSetting(pAdapter);
-}
-
-void Hal_SetAntenna(struct adapter *pAdapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
-
- struct ant_sel_ofdm *p_ofdm_tx; /* OFDM Tx register */
- struct ant_sel_cck *p_cck_txrx;
- u8 r_rx_antenna_ofdm = 0, r_ant_select_cck_val = 0;
- u8 chgTx = 0, chgRx = 0;
- u32 r_ant_select_ofdm_val = 0, r_ofdm_tx_en_val = 0;
-
-
- p_ofdm_tx = (struct ant_sel_ofdm *)&r_ant_select_ofdm_val;
- p_cck_txrx = (struct ant_sel_cck *)&r_ant_select_cck_val;
-
- p_ofdm_tx->r_ant_ht1 = 0x1;
- p_ofdm_tx->r_ant_ht2 = 0x2; /* Second TX RF path is A */
- p_ofdm_tx->r_ant_non_ht = 0x3; /* 0x1+0x2=0x3 */
-
- switch (pAdapter->mppriv.antenna_tx) {
- case ANTENNA_A:
- p_ofdm_tx->r_tx_antenna = 0x1;
- r_ofdm_tx_en_val = 0x1;
- p_ofdm_tx->r_ant_l = 0x1;
- p_ofdm_tx->r_ant_ht_s1 = 0x1;
- p_ofdm_tx->r_ant_non_ht_s1 = 0x1;
- p_cck_txrx->r_ccktx_enable = 0x8;
- chgTx = 1;
-
- /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1);
- r_ofdm_tx_en_val = 0x3;
-
- /* Power save */
-
- /* We need to close RFB by SW control */
- if (pHalData->rf_type == RF_2T2R) {
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 1);
- PHY_SetBBReg(pAdapter, rFPGA0_XB_RFInterfaceOE, BIT10, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 0);
- }
- break;
- case ANTENNA_B:
- p_ofdm_tx->r_tx_antenna = 0x2;
- r_ofdm_tx_en_val = 0x2;
- p_ofdm_tx->r_ant_l = 0x2;
- p_ofdm_tx->r_ant_ht_s1 = 0x2;
- p_ofdm_tx->r_ant_non_ht_s1 = 0x2;
- p_cck_txrx->r_ccktx_enable = 0x4;
- chgTx = 1;
- /* From SD3 Willis suggestion !!! Set RF A as standby */
- PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1);
- PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
-
- /* Power save */
- /* cosa r_ant_select_ofdm_val = 0x22222222; */
-
- /* 2008/10/31 MH From SD3 Willi's suggestion. We must read RF 1T table. */
- /* 2009/01/08 MH From Sd3 Willis. We need to close RFA by SW control */
- if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_1T2R) {
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 1);
- PHY_SetBBReg(pAdapter, rFPGA0_XA_RFInterfaceOE, BIT10, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
- }
- break;
- case ANTENNA_AB: /* For 8192S */
- p_ofdm_tx->r_tx_antenna = 0x3;
- r_ofdm_tx_en_val = 0x3;
- p_ofdm_tx->r_ant_l = 0x3;
- p_ofdm_tx->r_ant_ht_s1 = 0x3;
- p_ofdm_tx->r_ant_non_ht_s1 = 0x3;
- p_cck_txrx->r_ccktx_enable = 0xC;
- chgTx = 1;
-
- /* From SD3 Willis suggestion !!! Set RF B as standby */
- PHY_SetBBReg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2);
- PHY_SetBBReg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2);
-
- /* Disable Power save */
- /* cosa r_ant_select_ofdm_val = 0x3321333; */
- /* 2009/01/08 MH From Sd3 Willis. We need to enable RFA/B by SW control */
- if (pHalData->rf_type == RF_2T2R) {
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT10, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFInterfaceSW, BIT26, 0);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT1, 1);
- PHY_SetBBReg(pAdapter, rFPGA0_XAB_RFParameter, BIT17, 1);
- }
- break;
- default:
- break;
- }
-
- /* r_rx_antenna_ofdm, bit0=A, bit1=B, bit2=C, bit3=D */
- /* r_cckrx_enable : CCK default, 0=A, 1=B, 2=C, 3=D */
- /* r_cckrx_enable_2 : CCK option, 0=A, 1=B, 2=C, 3=D */
- switch (pAdapter->mppriv.antenna_rx) {
- case ANTENNA_A:
- r_rx_antenna_ofdm = 0x1; /* A */
- p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */
- p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */
- chgRx = 1;
- break;
- case ANTENNA_B:
- r_rx_antenna_ofdm = 0x2; /* B */
- p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */
- p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */
- chgRx = 1;
- break;
- case ANTENNA_AB:
- r_rx_antenna_ofdm = 0x3; /* AB */
- p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */
- p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */
- chgRx = 1;
- break;
- default:
- break;
- }
-
- if (chgTx && chgRx) {
- switch (pHalData->rf_chip) {
- case RF_8225:
- case RF_8256:
- case RF_6052:
- /* r_ant_sel_cck_val = r_ant_select_cck_val; */
- PHY_SetBBReg(pAdapter, rFPGA1_TxInfo, 0x7fffffff, r_ant_select_ofdm_val); /* OFDM Tx */
- PHY_SetBBReg(pAdapter, rFPGA0_TxInfo, 0x0000000f, r_ofdm_tx_en_val); /* OFDM Tx */
- PHY_SetBBReg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */
- PHY_SetBBReg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, r_rx_antenna_ofdm); /* OFDM Rx */
- PHY_SetBBReg(pAdapter, rCCK0_AFESetting, bMaskByte3, r_ant_select_cck_val); /* CCK TxRx */
-
- break;
- default:
- break;
- }
- }
-
- RT_TRACE(_module_mp_, _drv_notice_, ("-SwitchAntenna: finished\n"));
-}
-
-s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
-
-
- if (!netif_running(pAdapter->pnetdev)) {
- RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter! Fail: interface not opened!\n"));
- return _FAIL;
- }
-
- if (check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE) == false) {
- RT_TRACE(_module_mp_, _drv_warning_, ("SetThermalMeter: Fail! not in MP mode!\n"));
- return _FAIL;
- }
-
- target_ther &= 0xff;
- if (target_ther < 0x07)
- target_ther = 0x07;
- else if (target_ther > 0x1d)
- target_ther = 0x1d;
-
- pHalData->EEPROMThermalMeter = target_ther;
-
- return _SUCCESS;
-}
-
-void Hal_TriggerRFThermalMeter(struct adapter *pAdapter)
-{
- _write_rfreg(pAdapter, RF_PATH_A , RF_T_METER_88E , BIT17 | BIT16 , 0x03);
-}
-
-u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter)
-{
- u32 ThermalValue = 0;
-
- ThermalValue = _read_rfreg(pAdapter, RF_PATH_A, RF_T_METER_88E, 0xfc00);
- return (u8)ThermalValue;
-}
-
-void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value)
-{
- Hal_TriggerRFThermalMeter(pAdapter);
- msleep(1000);
- *value = Hal_ReadRFThermalMeter(pAdapter);
-}
-
-void Hal_SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart)
-{
- pAdapter->mppriv.MptCtx.bSingleCarrier = bStart;
- if (bStart) {
- /* Start Single Carrier. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleCarrierTx: test start\n"));
- /* 1. if OFDM block on? */
- if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
- write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */
-
- /* 2. set CCK test mode off, set to CCK normal mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable);
- /* 3. turn on scramble setting */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
- /* 4. Turn On Single Carrier Tx and turn off the other test modes. */
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
- /* for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
- } else {
- /* Stop Single Carrier. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleCarrierTx: test stop\n"));
-
- /* Turn off all test modes. */
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
- msleep(10);
-
- /* BB Reset */
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
-
- /* Stop for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
- }
-}
-
-
-void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
- bool is92C = IS_92C_SERIAL(pHalData->VersionID);
-
- u8 rfPath;
- u32 reg58 = 0x0;
- switch (pAdapter->mppriv.antenna_tx) {
- case ANTENNA_A:
- default:
- rfPath = RF_PATH_A;
- break;
- case ANTENNA_B:
- rfPath = RF_PATH_B;
- break;
- case ANTENNA_C:
- rfPath = RF_PATH_C;
- break;
- }
-
- pAdapter->mppriv.MptCtx.bSingleTone = bStart;
- if (bStart) {
- /* Start Single Tone. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleToneTx: test start\n"));
- /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */
- reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask);
- reg58 &= 0xFFFFFFF0;
- reg58 += 2;
- PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58);
- PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x0);
- PHY_SetBBReg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x0);
-
- if (is92C) {
- _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT19, 0x01);
- msleep(1);
- if (rfPath == RF_PATH_A)
- write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x10000); /* PAD all on. */
- else if (rfPath == RF_PATH_B)
- write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x10000); /* PAD all on. */
- write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */
- msleep(1);
- } else {
- write_rfreg(pAdapter, rfPath, 0x21, 0xd4000);
- msleep(1);
- write_rfreg(pAdapter, rfPath, 0x00, 0x2001f); /* PAD all on. */
- msleep(1);
- }
-
- /* for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
-
- } else {
- /* Stop Single Tone. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetSingleToneTx: test stop\n"));
-
- /* <20120326, Kordan> To amplify the power of tone for Xtal calibration. (asked by Edlu) */
- /* <20120326, Kordan> Only in single tone mode. (asked by Edlu) */
- reg58 = PHY_QueryRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask);
- reg58 &= 0xFFFFFFF0;
- PHY_SetRFReg(pAdapter, RF_PATH_A, LNA_Low_Gain_3, bRFRegOffsetMask, reg58);
- write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, 0x1);
- write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
- if (is92C) {
- _write_rfreg(pAdapter, RF_PATH_A, 0x21, BIT19, 0x00);
- msleep(1);
- write_rfreg(pAdapter, RF_PATH_A, 0x00, 0x32d75); /* PAD all on. */
- write_rfreg(pAdapter, RF_PATH_B, 0x00, 0x32d75); /* PAD all on. */
- msleep(1);
- } else {
- write_rfreg(pAdapter, rfPath, 0x21, 0x54000);
- msleep(1);
- write_rfreg(pAdapter, rfPath, 0x00, 0x30000); /* PAD all on. */
- msleep(1);
- }
-
- /* Stop for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
- }
-}
-
-
-
-void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart)
-{
- pAdapter->mppriv.MptCtx.bCarrierSuppression = bStart;
- if (bStart) {
- /* Start Carrier Suppression. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test start\n"));
- if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) {
- /* 1. if CCK block on? */
- if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn))
- write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */
-
- /* Turn Off All Test Mode */
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
-
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x0); /* turn off scramble setting */
-
- /* Set CCK Tx Test Rate */
- write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); /* Set FTxRate to 1Mbps */
- }
-
- /* for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
- } else {
- /* Stop Carrier Suppression. */
- RT_TRACE(_module_mp_, _drv_alert_, ("SetCarrierSuppressionTx: test stop\n"));
- if (pAdapter->mppriv.rateidx <= MPT_RATE_11M) {
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, 0x1); /* turn on scramble setting */
-
- /* BB Reset */
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
- }
-
- /* Stop for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
- }
-}
-
-void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart)
-{
- u32 cckrate;
-
- if (bStart) {
- RT_TRACE(_module_mp_, _drv_alert_,
- ("SetCCKContinuousTx: test start\n"));
-
- /* 1. if CCK block on? */
- if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn))
- write_bbreg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable);/* set CCK block on */
-
- /* Turn Off All Test Mode */
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
- /* Set CCK Tx Test Rate */
- cckrate = pAdapter->mppriv.rateidx;
- write_bbreg(pAdapter, rCCK0_System, bCCKTxRate, cckrate);
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); /* transmit mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */
-
- /* for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
- } else {
- RT_TRACE(_module_mp_, _drv_info_,
- ("SetCCKContinuousTx: test stop\n"));
-
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); /* normal mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable); /* turn on scramble setting */
-
- /* BB Reset */
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
-
- /* Stop for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
- }
-
- pAdapter->mppriv.MptCtx.bCckContTx = bStart;
- pAdapter->mppriv.MptCtx.bOfdmContTx = false;
-} /* mpt_StartCckContTx */
-
-void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart)
-{
- if (bStart) {
- RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test start\n"));
- /* 1. if OFDM block on? */
- if (!read_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn))
- write_bbreg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable);/* set OFDM block on */
-
- /* 2. set CCK test mode off, set to CCK normal mode */
- write_bbreg(pAdapter, rCCK0_System, bCCKBBMode, bDisable);
-
- /* 3. turn on scramble setting */
- write_bbreg(pAdapter, rCCK0_System, bCCKScramble, bEnable);
- /* 4. Turn On Continue Tx and turn off the other test modes. */
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
-
- /* for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000500);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000500);
-
- } else {
- RT_TRACE(_module_mp_, _drv_info_, ("SetOFDMContinuousTx: test stop\n"));
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable);
- write_bbreg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable);
- /* Delay 10 ms */
- msleep(10);
- /* BB Reset */
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x0);
- write_bbreg(pAdapter, rPMAC_Reset, bBBResetB, 0x1);
-
- /* Stop for dynamic set Power index. */
- write_bbreg(pAdapter, rFPGA0_XA_HSSIParameter1, bMaskDWord, 0x01000100);
- write_bbreg(pAdapter, rFPGA0_XB_HSSIParameter1, bMaskDWord, 0x01000100);
- }
-
- pAdapter->mppriv.MptCtx.bCckContTx = false;
- pAdapter->mppriv.MptCtx.bOfdmContTx = bStart;
-} /* mpt_StartOfdmContTx */
-
-void Hal_SetContinuousTx(struct adapter *pAdapter, u8 bStart)
-{
- RT_TRACE(_module_mp_, _drv_info_,
- ("SetContinuousTx: rate:%d\n", pAdapter->mppriv.rateidx));
-
- pAdapter->mppriv.MptCtx.bStartContTx = bStart;
- if (pAdapter->mppriv.rateidx <= MPT_RATE_11M)
- Hal_SetCCKContinuousTx(pAdapter, bStart);
- else if ((pAdapter->mppriv.rateidx >= MPT_RATE_6M) &&
- (pAdapter->mppriv.rateidx <= MPT_RATE_MCS15))
- Hal_SetOFDMContinuousTx(pAdapter, bStart);
-}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
index 941ff7467c3c..9f016a5401d8 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
@@ -94,7 +94,7 @@ rtl8188e_PHY_QueryBBReg(
{
u32 ReturnValue = 0, OriginalValue, BitShift;
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ OriginalValue = usb_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
ReturnValue = (OriginalValue & BitMask) >> BitShift;
return ReturnValue;
@@ -124,12 +124,12 @@ void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u3
u32 OriginalValue, BitShift;
if (BitMask != bMaskDWord) { /* if not "double word" write */
- OriginalValue = rtw_read32(Adapter, RegAddr);
+ OriginalValue = usb_read32(Adapter, RegAddr);
BitShift = phy_CalculateBitShift(BitMask);
Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
}
- rtw_write32(Adapter, RegAddr, Data);
+ usb_write32(Adapter, RegAddr, Data);
}
@@ -386,7 +386,7 @@ s32 PHY_MACConfig8188E(struct adapter *Adapter)
rtStatus = _FAIL;
/* 2010.07.13 AMPDU aggregation number B */
- rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM);
+ usb_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM);
return rtStatus;
}
@@ -603,14 +603,14 @@ PHY_BBConfig8188E(
/* Enable BB and RF */
- RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
- rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
+ RegVal = usb_read16(Adapter, REG_SYS_FUNC_EN);
+ usb_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1));
/* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
- rtw_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
+ usb_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB);
- rtw_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
+ usb_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB);
/* Config BB and AGC */
rtStatus = phy_BB8188E_Config_ParaFile(Adapter);
@@ -792,21 +792,21 @@ _PHY_SetBWMode92C(
/* 3<1>Set MAC register */
/* 3 */
- regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
- regRRSR_RSC = rtw_read8(Adapter, REG_RRSR+2);
+ regBwOpMode = usb_read8(Adapter, REG_BWOPMODE);
+ regRRSR_RSC = usb_read8(Adapter, REG_RRSR+2);
switch (pHalData->CurrentChannelBW) {
case HT_CHANNEL_WIDTH_20:
regBwOpMode |= BW_OPMODE_20MHZ;
/* 2007/02/07 Mark by Emily because we have not verify whether this register works */
- rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
+ usb_write8(Adapter, REG_BWOPMODE, regBwOpMode);
break;
case HT_CHANNEL_WIDTH_40:
regBwOpMode &= ~BW_OPMODE_20MHZ;
/* 2007/02/07 Mark by Emily because we have not verify whether this register works */
- rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
+ usb_write8(Adapter, REG_BWOPMODE, regBwOpMode);
regRRSR_RSC = (regRRSR_RSC&0x90) | (pHalData->nCur40MhzPrimeSC<<5);
- rtw_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
+ usb_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
break;
default:
break;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
index 52103da3e264..8ce9d0e4eeff 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
@@ -366,7 +366,7 @@ static void writeOFDMPowerReg88E(struct adapter *Adapter, u8 index, u32 *pValue)
writeVal = (writeVal > 8) ? (writeVal-8) : 0;
else
writeVal = (writeVal > 6) ? (writeVal-6) : 0;
- rtw_write8(Adapter, (u32)(regoffset+i), (u8)writeVal);
+ usb_write8(Adapter, (u32)(regoffset+i), (u8)writeVal);
}
}
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
index 43eb960e4e0b..53cf3baf46e0 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rxdesc.c
@@ -86,7 +86,7 @@ void update_recvframe_attrib_88e(struct recv_frame *precvframe,
report.rxdw5 = prxstat->rxdw5;
pattrib = &precvframe->attrib;
- _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
+ memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c b/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c
deleted file mode 100644
index 047b53482e67..000000000000
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_sreset.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTL8188E_SRESET_C_
-
-#include <rtl8188e_sreset.h>
-#include <rtl8188e_hal.h>
-
-void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter)
-{
-}
-
-void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
-{
- struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- unsigned long current_time;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- unsigned int diff_time;
- u32 txdma_status;
-
- txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
- if (txdma_status != 0x00) {
- DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
- rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
- rtl8188e_silentreset_for_specific_platform(padapter);
- }
- /* total xmit irp = 4 */
- current_time = jiffies;
- if (0 == pxmitpriv->free_xmitbuf_cnt) {
- diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_time);
-
- if (diff_time > 2000) {
- if (psrtpriv->last_tx_complete_time == 0) {
- psrtpriv->last_tx_complete_time = current_time;
- } else {
- diff_time = jiffies_to_msecs(current_time - psrtpriv->last_tx_complete_time);
- if (diff_time > 4000) {
- DBG_88E("%s tx hang\n", __func__);
- rtl8188e_silentreset_for_specific_platform(padapter);
- }
- }
- }
- }
-}
-
-void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
-{
- u32 rx_dma_status = 0;
- u8 fw_status = 0;
- rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
- if (rx_dma_status != 0x00) {
- DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
- rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
- }
- fw_status = rtw_read8(padapter, REG_FMETHR);
- if (fw_status != 0x00) {
- if (fw_status == 1)
- DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
- else if (fw_status == 2)
- DBG_88E("%s REG_FW_STATUS (0x%02x), Condition_No_Match !!\n", __func__, fw_status);
- }
-}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
index 77dce584f0db..81d691ddd6c6 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_led.c
@@ -22,6 +22,7 @@
#include <drv_types.h>
#include <rtl8188e_hal.h>
#include <rtl8188e_led.h>
+#include <usb_ops_linux.h>
/* LED object. */
@@ -34,8 +35,8 @@ void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
return;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */
+ LedCfg = usb_read8(padapter, REG_LEDCFG2);
+ usb_write8(padapter, REG_LEDCFG2, (LedCfg&0xf0)|BIT5|BIT6); /* SW control led0 on. */
pLed->bLedOn = true;
}
@@ -49,17 +50,17 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
goto exit;
- LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+ LedCfg = usb_read8(padapter, REG_LEDCFG2);/* 0x4E */
if (pHalData->bLedOpenDrain) {
/* Open-drain arrangement for controlling the LED) */
LedCfg &= 0x90; /* Set to software control. */
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3));
- LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+ usb_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3));
+ LedCfg = usb_read8(padapter, REG_MAC_PINMUX_CFG);
LedCfg &= 0xFE;
- rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
+ usb_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
} else {
- rtw_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT5|BIT6));
+ usb_write8(padapter, REG_LEDCFG2, (LedCfg|BIT3|BIT5|BIT6));
}
exit:
pLed->bLedOn = false;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
index 0f6222dab4a6..f25c87c63250 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c
@@ -23,7 +23,7 @@
#include <recv_osdep.h>
#include <mlme_osdep.h>
-#include <usb_ops.h>
+#include <usb_ops_linux.h>
#include <wifi.h>
#include <rtl8188e_hal.h>
@@ -41,13 +41,13 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter)
/* init recv_buf */
_rtw_init_queue(&precvpriv->free_recv_buf_queue);
- precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4);
+ precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_KERNEL);
if (precvpriv->pallocated_recv_buf == NULL) {
res = _FAIL;
RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n"));
goto exit;
}
- _rtw_memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF * sizeof(struct recv_buf) + 4);
+ memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF * sizeof(struct recv_buf) + 4);
precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_recv_buf), 4);
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
index 3476f8898330..3494ac697456 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
@@ -22,7 +22,7 @@
#include <drv_types.h>
#include <wifi.h>
#include <osdep_intf.h>
-#include <usb_ops.h>
+#include <usb_ops_linux.h>
#include <rtl8188e_hal.h>
s32 rtl8188eu_init_xmit_priv(struct adapter *adapt)
@@ -35,10 +35,6 @@ s32 rtl8188eu_init_xmit_priv(struct adapter *adapt)
return _SUCCESS;
}
-void rtl8188eu_free_xmit_priv(struct adapter *adapt)
-{
-}
-
static u8 urb_zero_packet_chk(struct adapter *adapt, int sz)
{
u8 set_tx_desc_offset;
@@ -72,7 +68,7 @@ void rtl8188e_fill_fake_txdesc(struct adapter *adapt, u8 *desc, u32 BufferLen, u
/* Clear all status */
ptxdesc = (struct tx_desc *)desc;
- _rtw_memset(desc, 0, TXDESC_SIZE);
+ memset(desc, 0, TXDESC_SIZE);
/* offset 0 */
ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */
@@ -196,7 +192,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
}
}
- _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
+ memset(ptxdesc, 0, sizeof(struct tx_desc));
/* 4 offset 0 */
ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
@@ -310,9 +306,6 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
} else if ((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) {
DBG_88E("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
- } else if (((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) &&
- (adapt->registrypriv.mp_mode == 1)) {
- fill_txdesc_for_mp(adapt, ptxdesc);
} else {
DBG_88E("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
@@ -397,7 +390,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
}
ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
- inner_ret = rtw_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
+ inner_ret = usb_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
rtw_count_tx_stats(adapt, pxmitframe, sz);
@@ -405,7 +398,7 @@ static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
mem_addr += w_sz;
- mem_addr = (u8 *)RND4(((size_t)(mem_addr)));
+ mem_addr = (u8 *) round_up((size_t)mem_addr, 4);
}
rtw_free_xmitframe(pxmitpriv, pxmitframe);
@@ -497,7 +490,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
pfirstframe = pxmitframe;
len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset*PACKET_OFFSET_SZ);
pbuf_tail = len;
- pbuf = _RND8(pbuf_tail);
+ pbuf = round_up(pbuf_tail, 8);
/* check pkt amount in one bulk */
desc_cnt = 0;
@@ -539,7 +532,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
xmitframe_phead = get_list_head(&ptxservq->sta_pending);
xmitframe_plist = xmitframe_phead->next;
- while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+ while (xmitframe_phead != xmitframe_plist) {
pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
xmitframe_plist = xmitframe_plist->next;
@@ -548,12 +541,12 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset*PACKET_OFFSET_SZ);
- if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) {
+ if (round_up(pbuf + len, 8) > MAX_XMITBUF_SZ) {
pxmitframe->agg_num = 1;
pxmitframe->pkt_offset = 1;
break;
}
- rtw_list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
ptxservq->qcnt--;
phwxmit->accnt--;
@@ -571,7 +564,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
/* handle pointer and stop condition */
pbuf_tail = pbuf + len;
- pbuf = _RND8(pbuf_tail);
+ pbuf = round_up(pbuf_tail, 8);
pfirstframe->agg_num++;
if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
@@ -587,8 +580,8 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
}
} /* end while (aggregate same priority and same DA(AP or STA) frames) */
- if (_rtw_queue_empty(&ptxservq->sta_pending) == true)
- rtw_list_delete(&ptxservq->tx_pending);
+ if (list_empty(&ptxservq->sta_pending.queue))
+ list_del_init(&ptxservq->tx_pending);
spin_unlock_bh(&pxmitpriv->lock);
if ((pfirstframe->attrib.ether_type != 0x0806) &&
@@ -608,7 +601,7 @@ s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitp
/* 3 4. write xmit buffer to USB FIFO */
ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
- rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
+ usb_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
/* 3 5. update statisitc */
pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c
index 141f85ae5618..e18393317bdc 100644
--- a/drivers/staging/rtl8188eu/hal/usb_halinit.c
+++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c
@@ -26,9 +26,7 @@
#include <rtl8188e_hal.h>
#include <rtl8188e_led.h>
#include <rtw_iol.h>
-#include <usb_ops.h>
#include <usb_hal.h>
-#include <usb_osintf.h>
#define HAL_MAC_ENABLE 1
#define HAL_BB_ENABLE 1
@@ -117,15 +115,15 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
/* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
- rtw_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
+ usb_write16(adapt, REG_CR, 0x00); /* suggseted by zhouzhou, by page, 20111230 */
/* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
- value16 = rtw_read16(adapt, REG_CR);
+ value16 = usb_read16(adapt, REG_CR);
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
/* for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
- rtw_write16(adapt, REG_CR, value16);
+ usb_write16(adapt, REG_CR, value16);
haldata->bMacPwrCtrlOn = true;
return _SUCCESS;
@@ -139,27 +137,27 @@ static void _InitInterrupt(struct adapter *Adapter)
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
/* HISR write one to clear */
- rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
+ usb_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
/* HIMR - */
imr = IMR_PSTIMEOUT_88E | IMR_TBDER_88E | IMR_CPWM_88E | IMR_CPWM2_88E;
- rtw_write32(Adapter, REG_HIMR_88E, imr);
+ usb_write32(Adapter, REG_HIMR_88E, imr);
haldata->IntrMask[0] = imr;
imr_ex = IMR_TXERR_88E | IMR_RXERR_88E | IMR_TXFOVW_88E | IMR_RXFOVW_88E;
- rtw_write32(Adapter, REG_HIMRE_88E, imr_ex);
+ usb_write32(Adapter, REG_HIMRE_88E, imr_ex);
haldata->IntrMask[1] = imr_ex;
/* REG_USB_SPECIAL_OPTION - BIT(4) */
/* 0; Use interrupt endpoint to upload interrupt pkt */
/* 1; Use bulk endpoint to upload interrupt pkt, */
- usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ usb_opt = usb_read8(Adapter, REG_USB_SPECIAL_OPTION);
if (!adapter_to_dvobj(Adapter)->ishighspeed)
usb_opt = usb_opt & (~INT_BULK_SEL);
else
usb_opt = usb_opt | (INT_BULK_SEL);
- rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt);
+ usb_write8(Adapter, REG_USB_SPECIAL_OPTION, usb_opt);
}
static void _InitQueueReservedPage(struct adapter *Adapter)
@@ -185,27 +183,27 @@ static void _InitQueueReservedPage(struct adapter *Adapter)
if (haldata->OutEpQueueSel & TX_SELE_NQ)
numNQ = 0x1C;
value8 = (u8)_NPQ(numNQ);
- rtw_write8(Adapter, REG_RQPN_NPQ, value8);
+ usb_write8(Adapter, REG_RQPN_NPQ, value8);
numPubQ = 0xA8 - numHQ - numLQ - numNQ;
/* TX DMA */
value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
- rtw_write32(Adapter, REG_RQPN, value32);
+ usb_write32(Adapter, REG_RQPN, value32);
} else {
- rtw_write16(Adapter, REG_RQPN_NPQ, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */
- rtw_write16(Adapter, REG_RQPN_NPQ, 0x0d);
- rtw_write32(Adapter, REG_RQPN, 0x808E000d);/* reserve 7 page for LPS */
+ usb_write16(Adapter, REG_RQPN_NPQ, 0x0000);/* Just follow MP Team,??? Georgia 03/28 */
+ usb_write16(Adapter, REG_RQPN_NPQ, 0x0d);
+ usb_write32(Adapter, REG_RQPN, 0x808E000d);/* reserve 7 page for LPS */
}
}
static void _InitTxBufferBoundary(struct adapter *Adapter, u8 txpktbuf_bndy)
{
- rtw_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
- rtw_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
- rtw_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
- rtw_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
- rtw_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
+ usb_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
+ usb_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
+ usb_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
+ usb_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
+ usb_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
}
static void _InitPageBoundary(struct adapter *Adapter)
@@ -214,20 +212,20 @@ static void _InitPageBoundary(struct adapter *Adapter)
/* */
u16 rxff_bndy = MAX_RX_DMA_BUFFER_SIZE_88E-1;
- rtw_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
+ usb_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
}
static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
u16 hiQ)
{
- u16 value16 = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+ u16 value16 = (usb_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
_TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
- rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
+ usb_write16(Adapter, REG_TRXDMA_CTRL, value16);
}
static void _InitNormalChipOneOutEpPriority(struct adapter *Adapter)
@@ -341,11 +339,11 @@ static void _InitNetworkType(struct adapter *Adapter)
{
u32 value32;
- value32 = rtw_read32(Adapter, REG_CR);
+ value32 = usb_read32(Adapter, REG_CR);
/* TODO: use the other function to set network type */
value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
- rtw_write32(Adapter, REG_CR, value32);
+ usb_write32(Adapter, REG_CR, value32);
}
static void _InitTransferPageSize(struct adapter *Adapter)
@@ -354,12 +352,12 @@ static void _InitTransferPageSize(struct adapter *Adapter)
u8 value8;
value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
- rtw_write8(Adapter, REG_PBP, value8);
+ usb_write8(Adapter, REG_PBP, value8);
}
static void _InitDriverInfoSize(struct adapter *Adapter, u8 drvInfoSize)
{
- rtw_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
+ usb_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
}
static void _InitWMACSetting(struct adapter *Adapter)
@@ -372,11 +370,11 @@ static void _InitWMACSetting(struct adapter *Adapter)
RCR_APP_MIC | RCR_APP_PHYSTS;
/* some REG_RCR will be modified later by phy_ConfigMACWithHeaderFile() */
- rtw_write32(Adapter, REG_RCR, haldata->ReceiveConfig);
+ usb_write32(Adapter, REG_RCR, haldata->ReceiveConfig);
/* Accept all multicast address */
- rtw_write32(Adapter, REG_MAR, 0xFFFFFFFF);
- rtw_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
+ usb_write32(Adapter, REG_MAR, 0xFFFFFFFF);
+ usb_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
}
static void _InitAdaptiveCtrl(struct adapter *Adapter)
@@ -385,64 +383,64 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
u32 value32;
/* Response Rate Set */
- value32 = rtw_read32(Adapter, REG_RRSR);
+ value32 = usb_read32(Adapter, REG_RRSR);
value32 &= ~RATE_BITMAP_ALL;
value32 |= RATE_RRSR_CCK_ONLY_1M;
- rtw_write32(Adapter, REG_RRSR, value32);
+ usb_write32(Adapter, REG_RRSR, value32);
/* CF-END Threshold */
/* SIFS (used in NAV) */
value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
- rtw_write16(Adapter, REG_SPEC_SIFS, value16);
+ usb_write16(Adapter, REG_SPEC_SIFS, value16);
/* Retry Limit */
value16 = _LRL(0x30) | _SRL(0x30);
- rtw_write16(Adapter, REG_RL, value16);
+ usb_write16(Adapter, REG_RL, value16);
}
static void _InitEDCA(struct adapter *Adapter)
{
/* Set Spec SIFS (used in NAV) */
- rtw_write16(Adapter, REG_SPEC_SIFS, 0x100a);
- rtw_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
+ usb_write16(Adapter, REG_SPEC_SIFS, 0x100a);
+ usb_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
/* Set SIFS for CCK */
- rtw_write16(Adapter, REG_SIFS_CTX, 0x100a);
+ usb_write16(Adapter, REG_SIFS_CTX, 0x100a);
/* Set SIFS for OFDM */
- rtw_write16(Adapter, REG_SIFS_TRX, 0x100a);
+ usb_write16(Adapter, REG_SIFS_TRX, 0x100a);
/* TXOP */
- rtw_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
- rtw_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
- rtw_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
- rtw_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
+ usb_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
+ usb_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
+ usb_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
+ usb_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
}
static void _InitRDGSetting(struct adapter *Adapter)
{
- rtw_write8(Adapter, REG_RD_CTRL, 0xFF);
- rtw_write16(Adapter, REG_RD_NAV_NXT, 0x200);
- rtw_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
+ usb_write8(Adapter, REG_RD_CTRL, 0xFF);
+ usb_write16(Adapter, REG_RD_NAV_NXT, 0x200);
+ usb_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
}
static void _InitRxSetting(struct adapter *Adapter)
{
- rtw_write32(Adapter, REG_MACID, 0x87654321);
- rtw_write32(Adapter, 0x0700, 0x87654321);
+ usb_write32(Adapter, REG_MACID, 0x87654321);
+ usb_write32(Adapter, 0x0700, 0x87654321);
}
static void _InitRetryFunction(struct adapter *Adapter)
{
u8 value8;
- value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
+ value8 = usb_read8(Adapter, REG_FWHW_TXQ_CTRL);
value8 |= EN_AMPDU_RTY_NEW;
- rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
+ usb_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
/* Set ACK timeout */
- rtw_write8(Adapter, REG_ACKTO, 0x40);
+ usb_write8(Adapter, REG_ACKTO, 0x40);
}
/*-----------------------------------------------------------------------------
@@ -469,11 +467,11 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
haldata->UsbTxAggMode = false;
if (haldata->UsbTxAggMode) {
- value32 = rtw_read32(Adapter, REG_TDECTRL);
+ value32 = usb_read32(Adapter, REG_TDECTRL);
value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
- rtw_write32(Adapter, REG_TDECTRL, value32);
+ usb_write32(Adapter, REG_TDECTRL, value32);
}
} /* usb_AggSettingTxUpdate */
@@ -501,8 +499,8 @@ usb_AggSettingRxUpdate(
u8 valueDMA;
u8 valueUSB;
- valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
- valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+ valueDMA = usb_read8(Adapter, REG_TRXDMA_CTRL);
+ valueUSB = usb_read8(Adapter, REG_USB_SPECIAL_OPTION);
switch (haldata->UsbRxAggMode) {
case USB_RX_AGG_DMA:
@@ -524,23 +522,23 @@ usb_AggSettingRxUpdate(
break;
}
- rtw_write8(Adapter, REG_TRXDMA_CTRL, valueDMA);
- rtw_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB);
+ usb_write8(Adapter, REG_TRXDMA_CTRL, valueDMA);
+ usb_write8(Adapter, REG_USB_SPECIAL_OPTION, valueUSB);
switch (haldata->UsbRxAggMode) {
case USB_RX_AGG_DMA:
- rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount);
- rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, haldata->UsbRxAggPageTimeout);
+ usb_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount);
+ usb_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, haldata->UsbRxAggPageTimeout);
break;
case USB_RX_AGG_USB:
- rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount);
- rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout);
+ usb_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount);
+ usb_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout);
break;
case USB_RX_AGG_MIX:
- rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount);
- rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */
- rtw_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount);
- rtw_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout);
+ usb_write8(Adapter, REG_RXDMA_AGG_PG_TH, haldata->UsbRxAggPageCount);
+ usb_write8(Adapter, REG_RXDMA_AGG_PG_TH+1, (haldata->UsbRxAggPageTimeout & 0x1F));/* 0x280[12:8] */
+ usb_write8(Adapter, REG_USB_AGG_TH, haldata->UsbRxAggBlockCount);
+ usb_write8(Adapter, REG_USB_AGG_TO, haldata->UsbRxAggBlockTimeout);
break;
case USB_RX_AGG_DISABLE:
default:
@@ -587,30 +585,30 @@ static void _InitBeaconParameters(struct adapter *Adapter)
{
struct hal_data_8188e *haldata = GET_HAL_DATA(Adapter);
- rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
+ usb_write16(Adapter, REG_BCN_CTRL, 0x1010);
/* TODO: Remove these magic number */
- rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */
- rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/* 5ms */
- rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); /* 2ms */
+ usb_write16(Adapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */
+ usb_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/* 5ms */
+ usb_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); /* 2ms */
/* Suggested by designer timchen. Change beacon AIFS to the largest number */
/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
- rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
+ usb_write16(Adapter, REG_BCNTCFG, 0x660F);
- haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
- haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
- haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL+2);
- haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT+2);
- haldata->RegCR_1 = rtw_read8(Adapter, REG_CR+1);
+ haldata->RegBcnCtrlVal = usb_read8(Adapter, REG_BCN_CTRL);
+ haldata->RegTxPause = usb_read8(Adapter, REG_TXPAUSE);
+ haldata->RegFwHwTxQCtrl = usb_read8(Adapter, REG_FWHW_TXQ_CTRL+2);
+ haldata->RegReg542 = usb_read8(Adapter, REG_TBTT_PROHIBIT+2);
+ haldata->RegCR_1 = usb_read8(Adapter, REG_CR+1);
}
static void _BeaconFunctionEnable(struct adapter *Adapter,
bool Enable, bool Linked)
{
- rtw_write8(Adapter, REG_BCN_CTRL, (BIT4 | BIT3 | BIT1));
+ usb_write8(Adapter, REG_BCN_CTRL, (BIT4 | BIT3 | BIT1));
- rtw_write8(Adapter, REG_RD_CTRL+1, 0x6F);
+ usb_write8(Adapter, REG_RD_CTRL+1, 0x6F);
}
/* Set CCK and OFDM Block "ON" */
@@ -633,7 +631,7 @@ static void _InitAntenna_Selection(struct adapter *Adapter)
return;
DBG_88E("==> %s ....\n", __func__);
- rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0)|BIT23);
+ usb_write32(Adapter, REG_LEDCFG0, usb_read32(Adapter, REG_LEDCFG0)|BIT23);
PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT13, 0x01);
if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -664,12 +662,12 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
enum rt_rf_power_state rfpowerstate = rf_off;
if (adapt->pwrctrlpriv.bHWPowerdown) {
- val8 = rtw_read8(adapt, REG_HSISR);
+ val8 = usb_read8(adapt, REG_HSISR);
DBG_88E("pwrdown, 0x5c(BIT7)=%02x\n", val8);
rfpowerstate = (val8 & BIT7) ? rf_off : rf_on;
} else { /* rf on/off */
- rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG)&~(BIT3));
- val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+ usb_write8(adapt, REG_MAC_PINMUX_CFG, usb_read8(adapt, REG_MAC_PINMUX_CFG)&~(BIT3));
+ val8 = usb_read8(adapt, REG_GPIO_IO_SEL);
DBG_88E("GPIO_IN=%02x\n", val8);
rfpowerstate = (val8 & BIT3) ? rf_on : rf_off;
}
@@ -823,26 +821,26 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
/* Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
/* Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
/* Enable MACTXEN/MACRXEN block */
- value16 = rtw_read16(Adapter, REG_CR);
+ value16 = usb_read16(Adapter, REG_CR);
value16 |= (MACTXEN | MACRXEN);
- rtw_write8(Adapter, REG_CR, value16);
+ usb_write8(Adapter, REG_CR, value16);
if (haldata->bRDGEnable)
_InitRDGSetting(Adapter);
/* Enable TX Report */
/* Enable Tx Report Timer */
- value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
- rtw_write8(Adapter, REG_TX_RPT_CTRL, (value8|BIT1|BIT0));
+ value8 = usb_read8(Adapter, REG_TX_RPT_CTRL);
+ usb_write8(Adapter, REG_TX_RPT_CTRL, (value8|BIT1|BIT0));
/* Set MAX RPT MACID */
- rtw_write8(Adapter, REG_TX_RPT_CTRL+1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
+ usb_write8(Adapter, REG_TX_RPT_CTRL+1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
/* Tx RPT Timer. Unit: 32us */
- rtw_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0);
+ usb_write16(Adapter, REG_TX_RPT_TIME, 0xCdf0);
- rtw_write8(Adapter, REG_EARLY_MODE_CONTROL, 0);
+ usb_write8(Adapter, REG_EARLY_MODE_CONTROL, 0);
- rtw_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
- rtw_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
+ usb_write16(Adapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
+ usb_write16(Adapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /* unit: 256us. 256ms */
/* Keep RfRegChnlVal for later use. */
haldata->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum rf_radio_path)0, RF_CHNLBW, bRFRegOffsetMask);
@@ -867,71 +865,66 @@ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MISC11);
/* Disable BAR, suggested by Scott */
/* 2010.04.09 add by hpfan */
/* */
- rtw_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
+ usb_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
/* HW SEQ CTRL */
/* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
- rtw_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
+ usb_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
if (pregistrypriv->wifi_spec)
- rtw_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
+ usb_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
/* Nav limit , suggest by scott */
- rtw_write8(Adapter, 0x652, 0x0);
+ usb_write8(Adapter, 0x652, 0x0);
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_HAL_DM);
rtl8188e_InitHalDm(Adapter);
- if (Adapter->registrypriv.mp_mode == 1) {
- Adapter->mppriv.channel = haldata->CurrentChannel;
- MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
- } else {
- /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
- /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
- /* call initstruct adapter. May cause some problem?? */
- /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */
- /* in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */
- /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */
- /* Added by tynli. 2010.03.30. */
- pwrctrlpriv->rf_pwrstate = rf_on;
+ /* 2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
+ /* and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
+ /* call initstruct adapter. May cause some problem?? */
+ /* Fix the bug that Hw/Sw radio off before S3/S4, the RF off action will not be executed */
+ /* in MgntActSet_RF_State() after wake up, because the value of haldata->eRFPowerState */
+ /* is the same as eRfOff, we should change it to eRfOn after we config RF parameters. */
+ /* Added by tynli. 2010.03.30. */
+ pwrctrlpriv->rf_pwrstate = rf_on;
- /* enable Tx report. */
- rtw_write8(Adapter, REG_FWHW_TXQ_CTRL+1, 0x0F);
+ /* enable Tx report. */
+ usb_write8(Adapter, REG_FWHW_TXQ_CTRL+1, 0x0F);
- /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
- rtw_write8(Adapter, REG_EARLY_MODE_CONTROL+3, 0x01);/* Pretx_en, for WEP/TKIP SEC */
+ /* Suggested by SD1 pisa. Added by tynli. 2011.10.21. */
+ usb_write8(Adapter, REG_EARLY_MODE_CONTROL+3, 0x01);/* Pretx_en, for WEP/TKIP SEC */
- /* tynli_test_tx_report. */
- rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
+ /* tynli_test_tx_report. */
+ usb_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
- /* enable tx DMA to drop the redundate data of packet */
- rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+ /* enable tx DMA to drop the redundate data of packet */
+ usb_write16(Adapter, REG_TXDMA_OFFSET_CHK, (usb_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
/* 2010/08/26 MH Merge from 8192CE. */
- if (pwrctrlpriv->rf_pwrstate == rf_on) {
- if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
+ if (pwrctrlpriv->rf_pwrstate == rf_on) {
+ if (haldata->odmpriv.RFCalibrateInfo.bIQKInitialized) {
PHY_IQCalibrate_8188E(Adapter, true);
- } else {
- PHY_IQCalibrate_8188E(Adapter, false);
- haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
- }
+ } else {
+ PHY_IQCalibrate_8188E(Adapter, false);
+ haldata->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
+ }
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_PW_TRACK);
- ODM_TXPowerTrackingCheck(&haldata->odmpriv);
+ ODM_TXPowerTrackingCheck(&haldata->odmpriv);
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_LCK);
PHY_LCCalibrate_8188E(Adapter);
- }
}
/* HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_INIT_PABIAS); */
/* _InitPABias(Adapter); */
- rtw_write8(Adapter, REG_USB_HRPWM, 0);
+ usb_write8(Adapter, REG_USB_HRPWM, 0);
/* ack for xmit mgmt frames. */
- rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
+ usb_write32(Adapter, REG_FWHW_TXQ_CTRL, usb_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
exit:
HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -950,52 +943,52 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CardDisableRTL8188EU\n"));
/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
- val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
- rtw_write8(Adapter, REG_TX_RPT_CTRL, val8&(~BIT1));
+ val8 = usb_read8(Adapter, REG_TX_RPT_CTRL);
+ usb_write8(Adapter, REG_TX_RPT_CTRL, val8&(~BIT1));
/* stop rx */
- rtw_write8(Adapter, REG_CR, 0x0);
+ usb_write8(Adapter, REG_CR, 0x0);
/* Run LPS WL RFOFF flow */
HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_LPS_ENTER_FLOW);
/* 2. 0x1F[7:0] = 0 turn off RF */
- val8 = rtw_read8(Adapter, REG_MCUFWDL);
+ val8 = usb_read8(Adapter, REG_MCUFWDL);
if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
/* Reset MCU 0x2[10]=0. */
- val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN+1);
+ val8 = usb_read8(Adapter, REG_SYS_FUNC_EN+1);
val8 &= ~BIT(2); /* 0x2[10], FEN_CPUEN */
- rtw_write8(Adapter, REG_SYS_FUNC_EN+1, val8);
+ usb_write8(Adapter, REG_SYS_FUNC_EN+1, val8);
}
/* reset MCU ready status */
- rtw_write8(Adapter, REG_MCUFWDL, 0);
+ usb_write8(Adapter, REG_MCUFWDL, 0);
/* YJ,add,111212 */
/* Disable 32k */
- val8 = rtw_read8(Adapter, REG_32K_CTRL);
- rtw_write8(Adapter, REG_32K_CTRL, val8&(~BIT0));
+ val8 = usb_read8(Adapter, REG_32K_CTRL);
+ usb_write8(Adapter, REG_32K_CTRL, val8&(~BIT0));
/* Card disable power action flow */
HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
/* Reset MCU IO Wrapper */
- val8 = rtw_read8(Adapter, REG_RSV_CTRL+1);
- rtw_write8(Adapter, REG_RSV_CTRL+1, (val8&(~BIT3)));
- val8 = rtw_read8(Adapter, REG_RSV_CTRL+1);
- rtw_write8(Adapter, REG_RSV_CTRL+1, val8|BIT3);
+ val8 = usb_read8(Adapter, REG_RSV_CTRL+1);
+ usb_write8(Adapter, REG_RSV_CTRL+1, (val8&(~BIT3)));
+ val8 = usb_read8(Adapter, REG_RSV_CTRL+1);
+ usb_write8(Adapter, REG_RSV_CTRL+1, val8|BIT3);
/* YJ,test add, 111207. For Power Consumption. */
- val8 = rtw_read8(Adapter, GPIO_IN);
- rtw_write8(Adapter, GPIO_OUT, val8);
- rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
-
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
- rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8<<4));
- val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL+1);
- rtw_write8(Adapter, REG_GPIO_IO_SEL+1, val8|0x0F);/* Reg0x43 */
- rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
+ val8 = usb_read8(Adapter, GPIO_IN);
+ usb_write8(Adapter, GPIO_OUT, val8);
+ usb_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
+
+ val8 = usb_read8(Adapter, REG_GPIO_IO_SEL);
+ usb_write8(Adapter, REG_GPIO_IO_SEL, (val8<<4));
+ val8 = usb_read8(Adapter, REG_GPIO_IO_SEL+1);
+ usb_write8(Adapter, REG_GPIO_IO_SEL+1, val8|0x0F);/* Reg0x43 */
+ usb_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
haldata->bMacPwrCtrlOn = false;
Adapter->bFWReady = false;
}
@@ -1005,8 +998,8 @@ static void rtl8192cu_hw_power_down(struct adapter *adapt)
/* Then enable power down control bit of register 0x04 BIT4 and BIT15 as 1. */
/* Enable register area 0x0-0xc. */
- rtw_write8(adapt, REG_RSV_CTRL, 0x0);
- rtw_write16(adapt, REG_APS_FSMCO, 0x8812);
+ usb_write8(adapt, REG_RSV_CTRL, 0x0);
+ usb_write16(adapt, REG_APS_FSMCO, 0x8812);
}
static u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
@@ -1014,8 +1007,8 @@ static u32 rtl8188eu_hal_deinit(struct adapter *Adapter)
DBG_88E("==> %s\n", __func__);
- rtw_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E);
- rtw_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E);
+ usb_write32(Adapter, REG_HIMR_88E, IMR_DISABLED_88E);
+ usb_write32(Adapter, REG_HIMRE_88E, IMR_DISABLED_88E);
DBG_88E("bkeepfwalive(%x)\n", Adapter->pwrctrlpriv.bkeepfwalive);
if (Adapter->pwrctrlpriv.bkeepfwalive) {
@@ -1037,12 +1030,7 @@ static unsigned int rtl8188eu_inirp_init(struct adapter *Adapter)
u8 i;
struct recv_buf *precvbuf;
uint status;
- struct intf_hdl *pintfhdl = &Adapter->iopriv.intf;
struct recv_priv *precvpriv = &(Adapter->recvpriv);
- u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
-
-
- _read_port = pintfhdl->io_ops._read_port;
status = _SUCCESS;
@@ -1054,7 +1042,7 @@ static unsigned int rtl8188eu_inirp_init(struct adapter *Adapter)
/* issue Rx irp to receive data */
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
- if (_read_port(pintfhdl, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf) == false) {
+ if (usb_read_port(Adapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf) == false) {
RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("usb_rx_init: usb_read_port error\n"));
status = _FAIL;
goto exit;
@@ -1076,7 +1064,7 @@ static unsigned int rtl8188eu_inirp_deinit(struct adapter *Adapter)
{
RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("\n ===> usb_rx_deinit\n"));
- rtw_read_port_cancel(Adapter);
+ usb_read_port_cancel(Adapter);
RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("\n <=== usb_rx_deinit\n"));
@@ -1155,10 +1143,6 @@ readAdapterInfo_8188EU(
Hal_EfuseParseBoardType88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
Hal_ReadThermalMeter_88E(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
- /* */
- /* The following part initialize some vars by PG info. */
- /* */
- Hal_InitChannelPlan(adapt);
}
static void _ReadPROMContent(
@@ -1169,7 +1153,7 @@ static void _ReadPROMContent(
u8 eeValue;
/* check system boot selection */
- eeValue = rtw_read8(Adapter, REG_9346CR);
+ eeValue = usb_read8(Adapter, REG_9346CR);
eeprom->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
eeprom->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
@@ -1187,7 +1171,7 @@ static void _ReadRFType(struct adapter *Adapter)
haldata->rf_chip = RF_6052;
}
-static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
+static void _ReadAdapterInfo8188EU(struct adapter *Adapter)
{
u32 start = jiffies;
@@ -1197,16 +1181,6 @@ static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
_ReadPROMContent(Adapter);
MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
-
- return _SUCCESS;
-}
-
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
-{
- /* Read EEPROM size before call any EEPROM function */
- Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
-
- _ReadAdapterInfo8188EU(Adapter);
}
#define GPIO_DEBUG_PORT_NUM 0
@@ -1221,11 +1195,11 @@ static void ResumeTxBeacon(struct adapter *adapt)
/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
/* which should be read from register to a global variable. */
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) | BIT6);
+ usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) | BIT6);
haldata->RegFwHwTxQCtrl |= BIT6;
- rtw_write8(adapt, REG_TBTT_PROHIBIT+1, 0xff);
+ usb_write8(adapt, REG_TBTT_PROHIBIT+1, 0xff);
haldata->RegReg542 |= BIT0;
- rtw_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542);
+ usb_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542);
}
static void StopTxBeacon(struct adapter *adapt)
@@ -1235,11 +1209,11 @@ static void StopTxBeacon(struct adapter *adapt)
/* 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value */
/* which should be read from register to a global variable. */
- rtw_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) & (~BIT6));
+ usb_write8(adapt, REG_FWHW_TXQ_CTRL+2, (haldata->RegFwHwTxQCtrl) & (~BIT6));
haldata->RegFwHwTxQCtrl &= (~BIT6);
- rtw_write8(adapt, REG_TBTT_PROHIBIT+1, 0x64);
+ usb_write8(adapt, REG_TBTT_PROHIBIT+1, 0x64);
haldata->RegReg542 &= ~(BIT0);
- rtw_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542);
+ usb_write8(adapt, REG_TBTT_PROHIBIT+2, haldata->RegReg542);
/* todo: CheckFwRsvdPageContent(Adapter); 2010.06.23. Added by tynli. */
}
@@ -1250,54 +1224,54 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
u8 mode = *((u8 *)val);
/* disable Port0 TSF update */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)|BIT(4));
/* set net_type */
- val8 = rtw_read8(Adapter, MSR)&0x0c;
+ val8 = usb_read8(Adapter, MSR)&0x0c;
val8 |= mode;
- rtw_write8(Adapter, MSR, val8);
+ usb_write8(Adapter, MSR, val8);
DBG_88E("%s()-%d mode = %d\n", __func__, __LINE__, mode);
if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
StopTxBeacon(Adapter);
- rtw_write8(Adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */
+ usb_write8(Adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */
} else if ((mode == _HW_STATE_ADHOC_)) {
ResumeTxBeacon(Adapter);
- rtw_write8(Adapter, REG_BCN_CTRL, 0x1a);
+ usb_write8(Adapter, REG_BCN_CTRL, 0x1a);
} else if (mode == _HW_STATE_AP_) {
ResumeTxBeacon(Adapter);
- rtw_write8(Adapter, REG_BCN_CTRL, 0x12);
+ usb_write8(Adapter, REG_BCN_CTRL, 0x12);
/* Set RCR */
- rtw_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
+ usb_write32(Adapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
/* enable to rx data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable to rx ps-poll */
- rtw_write16(Adapter, REG_RXFLTMAP1, 0x0400);
+ usb_write16(Adapter, REG_RXFLTMAP1, 0x0400);
/* Beacon Control related register for first time */
- rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
+ usb_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */
- rtw_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
- rtw_write16(Adapter, REG_BCNTCFG, 0x00);
- rtw_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
- rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
+ usb_write8(Adapter, REG_ATIMWND, 0x0a); /* 10ms */
+ usb_write16(Adapter, REG_BCNTCFG, 0x00);
+ usb_write16(Adapter, REG_TBTT_PROHIBIT, 0xff04);
+ usb_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
/* reset TSF */
- rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
+ usb_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
/* BIT3 - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
- rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+ usb_write8(Adapter, REG_MBID_NUM, usb_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
/* enable BCN0 Function for if1 */
/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
- rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | BIT(1)));
+ usb_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP|EN_BCN_FUNCTION | BIT(1)));
/* dis BCN1 ATIM WND if if2 is station */
- rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+ usb_write8(Adapter, REG_BCN_CTRL_1, usb_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
}
}
@@ -1309,7 +1283,7 @@ static void hw_var_set_macaddr(struct adapter *Adapter, u8 variable, u8 *val)
reg_macid = REG_MACID;
for (idx = 0; idx < 6; idx++)
- rtw_write8(Adapter, (reg_macid+idx), val[idx]);
+ usb_write8(Adapter, (reg_macid+idx), val[idx]);
}
static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1320,7 +1294,7 @@ static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val)
reg_bssid = REG_BSSID;
for (idx = 0; idx < 6; idx++)
- rtw_write8(Adapter, (reg_bssid+idx), val[idx]);
+ usb_write8(Adapter, (reg_bssid+idx), val[idx]);
}
static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1330,9 +1304,9 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
bcn_ctrl_reg = REG_BCN_CTRL;
if (*((u8 *)val))
- rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
+ usb_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
else
- rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+ usb_write8(Adapter, bcn_ctrl_reg, usb_read8(Adapter, bcn_ctrl_reg)&(~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
}
static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1346,18 +1320,18 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR)&0x0c;
+ val8 = usb_read8(Adapter, MSR)&0x0c;
val8 |= *((u8 *)val);
- rtw_write8(Adapter, MSR, val8);
+ usb_write8(Adapter, MSR, val8);
}
break;
case HW_VAR_MEDIA_STATUS1:
{
u8 val8;
- val8 = rtw_read8(Adapter, MSR) & 0x03;
+ val8 = usb_read8(Adapter, MSR) & 0x03;
val8 |= *((u8 *)val) << 2;
- rtw_write8(Adapter, MSR, val8);
+ usb_write8(Adapter, MSR, val8);
}
break;
case HW_VAR_SET_OPMODE:
@@ -1391,9 +1365,9 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
BrateCfg |= 0x01; /* default enable 1M ACK rate */
/* Set RRSR rate table. */
- rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
- rtw_write8(Adapter, REG_RRSR+1, (BrateCfg >> 8) & 0xff);
- rtw_write8(Adapter, REG_RRSR+2, rtw_read8(Adapter, REG_RRSR+2)&0xf0);
+ usb_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
+ usb_write8(Adapter, REG_RRSR+1, (BrateCfg >> 8) & 0xff);
+ usb_write8(Adapter, REG_RRSR+2, usb_read8(Adapter, REG_RRSR+2)&0xf0);
/* Set RTS initial rate */
while (BrateCfg > 0x1) {
@@ -1401,11 +1375,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
RateIndex++;
}
/* Ziv - Check */
- rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
+ usb_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
}
break;
case HW_VAR_TXPAUSE:
- rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
+ usb_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
break;
case HW_VAR_BCN_FUNC:
hw_var_set_bcn_func(Adapter, variable, val);
@@ -1422,13 +1396,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
StopTxBeacon(Adapter);
/* disable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(3)));
- rtw_write32(Adapter, REG_TSFTR, tsf);
- rtw_write32(Adapter, REG_TSFTR+4, tsf>>32);
+ usb_write32(Adapter, REG_TSFTR, tsf);
+ usb_write32(Adapter, REG_TSFTR+4, tsf>>32);
/* enable related TSF function */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(3));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)|BIT(3));
if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
ResumeTxBeacon(Adapter);
@@ -1436,39 +1410,39 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_CHECK_BSSID:
if (*((u8 *)val)) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
} else {
u32 val32;
- val32 = rtw_read32(Adapter, REG_RCR);
+ val32 = usb_read32(Adapter, REG_RCR);
val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
- rtw_write32(Adapter, REG_RCR, val32);
+ usb_write32(Adapter, REG_RCR, val32);
}
break;
case HW_VAR_MLME_DISCONNECT:
/* Set RCR to not to receive data frame when NO LINK state */
/* reject all data frames */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0x00);
/* reset TSF */
- rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
+ usb_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)|BIT(4));
break;
case HW_VAR_MLME_SITESURVEY:
if (*((u8 *)val)) { /* under sitesurvey */
/* config RCR to receive different BSSID & not to receive data frame */
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = usb_read32(Adapter, REG_RCR);
v &= ~(RCR_CBSSID_BCN);
- rtw_write32(Adapter, REG_RCR, v);
+ usb_write32(Adapter, REG_RCR, v);
/* reject all data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0x00);
/* disable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)|BIT(4));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)|BIT(4));
} else { /* sitesurvey done */
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -1476,24 +1450,24 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if ((is_client_associated_to_ap(Adapter)) ||
((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)) {
/* enable to rx data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
} else if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
}
if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
} else {
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = usb_read32(Adapter, REG_RCR);
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
- rtw_write32(Adapter, REG_RCR, v);
+ usb_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_BCN);
}
}
}
@@ -1506,14 +1480,14 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if (type == 0) { /* prepare to join */
/* enable to rx data frame.Accept all data frame */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
if (Adapter->in_cta_test) {
- u32 v = rtw_read32(Adapter, REG_RCR);
+ u32 v = usb_read32(Adapter, REG_RCR);
v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
- rtw_write32(Adapter, REG_RCR, v);
+ usb_write32(Adapter, REG_RCR, v);
} else {
- rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
+ usb_write32(Adapter, REG_RCR, usb_read32(Adapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
}
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -1522,20 +1496,20 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
RetryLimit = 0x7;
} else if (type == 1) {
/* joinbss_event call back when join res < 0 */
- rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
+ usb_write16(Adapter, REG_RXFLTMAP2, 0x00);
} else if (type == 2) {
/* sta add event call back */
/* enable update TSF */
- rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
+ usb_write8(Adapter, REG_BCN_CTRL, usb_read8(Adapter, REG_BCN_CTRL)&(~BIT(4)));
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
RetryLimit = 0x7;
}
- rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
+ usb_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
}
break;
case HW_VAR_BEACON_INTERVAL:
- rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
+ usb_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
break;
case HW_VAR_SLOT_TIME:
{
@@ -1543,7 +1517,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- rtw_write8(Adapter, REG_SLOT, val[0]);
+ usb_write8(Adapter, REG_SLOT, val[0]);
if (pmlmeinfo->WMM_enable == 0) {
if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
@@ -1554,20 +1528,20 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
/* <Roger_EXP> Temporary removed, 2008.06.20. */
- rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
- rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
+ usb_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
+ usb_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
+ usb_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
+ usb_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
}
}
break;
case HW_VAR_RESP_SIFS:
/* RESP_SIFS for CCK */
- rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */
- rtw_write8(Adapter, REG_R2T_SIFS+1, val[1]); /* SIFS_R2T_CCK(0x08) */
+ usb_write8(Adapter, REG_R2T_SIFS, val[0]); /* SIFS_T2T_CCK (0x08) */
+ usb_write8(Adapter, REG_R2T_SIFS+1, val[1]); /* SIFS_R2T_CCK(0x08) */
/* RESP_SIFS for OFDM */
- rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */
- rtw_write8(Adapter, REG_T2T_SIFS+1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
+ usb_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */
+ usb_write8(Adapter, REG_T2T_SIFS+1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
break;
case HW_VAR_ACK_PREAMBLE:
{
@@ -1578,11 +1552,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if (bShortPreamble)
regTmp |= 0x80;
- rtw_write8(Adapter, REG_RRSR+2, regTmp);
+ usb_write8(Adapter, REG_RRSR+2, regTmp);
}
break;
case HW_VAR_SEC_CFG:
- rtw_write8(Adapter, REG_SECCFG, *((u8 *)val));
+ usb_write8(Adapter, REG_SECCFG, *((u8 *)val));
break;
case HW_VAR_DM_FLAG:
podmpriv->SupportAbility = *((u8 *)val);
@@ -1622,41 +1596,41 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
ulCommand = ulCommand | CAM_POLLINIG|CAM_WRITE;
/* write content 0 is equall to mark invalid */
- rtw_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */
- rtw_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */
+ usb_write32(Adapter, WCAMI, ulContent); /* delay_ms(40); */
+ usb_write32(Adapter, RWCAM, ulCommand); /* delay_ms(40); */
}
}
break;
case HW_VAR_CAM_INVALID_ALL:
- rtw_write32(Adapter, RWCAM, BIT(31)|BIT(30));
+ usb_write32(Adapter, RWCAM, BIT(31)|BIT(30));
break;
case HW_VAR_CAM_WRITE:
{
u32 cmd;
u32 *cam_val = (u32 *)val;
- rtw_write32(Adapter, WCAMI, cam_val[0]);
+ usb_write32(Adapter, WCAMI, cam_val[0]);
cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
- rtw_write32(Adapter, RWCAM, cmd);
+ usb_write32(Adapter, RWCAM, cmd);
}
break;
case HW_VAR_AC_PARAM_VO:
- rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
+ usb_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
break;
case HW_VAR_AC_PARAM_VI:
- rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
+ usb_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
break;
case HW_VAR_AC_PARAM_BE:
haldata->AcParam_BE = ((u32 *)(val))[0];
- rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
+ usb_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
break;
case HW_VAR_AC_PARAM_BK:
- rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
+ usb_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
break;
case HW_VAR_ACM_CTRL:
{
u8 acm_ctrl = *((u8 *)val);
- u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+ u8 AcmCtrl = usb_read8(Adapter, REG_ACMHWCTRL);
if (acm_ctrl > 1)
AcmCtrl = AcmCtrl | 0x1;
@@ -1677,7 +1651,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
AcmCtrl &= (~AcmHw_BeqEn);
DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
- rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl);
+ usb_write8(Adapter, REG_ACMHWCTRL, AcmCtrl);
}
break;
case HW_VAR_AMPDU_MIN_SPACE:
@@ -1704,7 +1678,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
}
if (MinSpacingToSet < SecMinSpace)
MinSpacingToSet = SecMinSpace;
- rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+ usb_write8(Adapter, REG_AMPDU_MIN_SPACE, (usb_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
}
}
break;
@@ -1729,7 +1703,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
if ((pRegToSet[index] & 0x0f) > FactorToSet)
pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
- rtw_write8(Adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]);
+ usb_write8(Adapter, (REG_AGGLEN_LMT+index), pRegToSet[index]);
}
}
}
@@ -1739,7 +1713,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
u8 threshold = *((u8 *)val);
if (threshold == 0)
threshold = haldata->UsbRxAggPageCount;
- rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
+ usb_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
}
break;
case HW_VAR_SET_RPWM:
@@ -1761,14 +1735,6 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus);
}
break;
-#ifdef CONFIG_88EU_P2P
- case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
- {
- u8 p2p_ps_state = (*(u8 *)val);
- rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state);
- }
- break;
-#endif
case HW_VAR_INITIAL_GAIN:
{
struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
@@ -1813,24 +1779,24 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
u8 trycnt = 100;
/* pause tx */
- rtw_write8(Adapter, REG_TXPAUSE, 0xff);
+ usb_write8(Adapter, REG_TXPAUSE, 0xff);
/* keep sn */
- Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+ Adapter->xmitpriv.nqos_ssn = usb_read16(Adapter, REG_NQOS_SEQ);
if (!pwrpriv->bkeepfwalive) {
/* RX DMA stop */
- rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM)|RW_RELEASE_EN));
+ usb_write32(Adapter, REG_RXPKT_NUM, (usb_read32(Adapter, REG_RXPKT_NUM)|RW_RELEASE_EN));
do {
- if (!(rtw_read32(Adapter, REG_RXPKT_NUM)&RXDMA_IDLE))
+ if (!(usb_read32(Adapter, REG_RXPKT_NUM)&RXDMA_IDLE))
break;
} while (trycnt--);
if (trycnt == 0)
DBG_88E("Stop RX DMA failed......\n");
/* RQPN Load 0 */
- rtw_write16(Adapter, REG_RQPN_NPQ, 0x0);
- rtw_write32(Adapter, REG_RQPN, 0x80000000);
+ usb_write16(Adapter, REG_RQPN_NPQ, 0x0);
+ usb_write32(Adapter, REG_RQPN, 0x80000000);
mdelay(10);
}
}
@@ -1845,7 +1811,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
{
u8 maxMacid = *val;
DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid+1);
- rtw_write8(Adapter, REG_TX_RPT_CTRL+1, maxMacid+1);
+ usb_write8(Adapter, REG_TX_RPT_CTRL+1, maxMacid+1);
}
break;
case HW_VAR_H2C_MEDIA_STATUS_RPT:
@@ -1853,7 +1819,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
- rtw_write8(Adapter, REG_TDECTRL+2, rtw_read8(Adapter, REG_TDECTRL+2) | BIT0);
+ usb_write8(Adapter, REG_TDECTRL+2, usb_read8(Adapter, REG_TDECTRL+2) | BIT0);
break;
default:
break;
@@ -1869,11 +1835,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
case HW_VAR_BASIC_RATE:
*((u16 *)(val)) = haldata->BasicRateSet;
case HW_VAR_TXPAUSE:
- val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+ val[0] = usb_read8(Adapter, REG_TXPAUSE);
break;
case HW_VAR_BCN_VALID:
/* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
- val[0] = (BIT0 & rtw_read8(Adapter, REG_TDECTRL+2)) ? true : false;
+ val[0] = (BIT0 & usb_read8(Adapter, REG_TDECTRL+2)) ? true : false;
break;
case HW_VAR_DM_FLAG:
val[0] = podmpriv->SupportAbility;
@@ -1890,7 +1856,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
val[0] = true;
} else {
u32 valRCR;
- valRCR = rtw_read32(Adapter, REG_RCR);
+ valRCR = usb_read32(Adapter, REG_RCR);
valRCR &= 0x00070000;
if (valRCR)
val[0] = false;
@@ -1909,7 +1875,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
*val = haldata->bMacPwrCtrlOn;
break;
case HW_VAR_CHK_HI_QUEUE_EMPTY:
- *val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION)&0x0000ff00) == 0) ? true : false;
+ *val = ((usb_read32(Adapter, REG_HGQ_INFORMATION)&0x0000ff00) == 0) ? true : false;
break;
default:
break;
@@ -2047,7 +2013,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
} else if (dm_func == 6) {/* turn on all dynamic func */
if (!(podmpriv->SupportAbility & DYNAMIC_BB_DIG)) {
struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
- pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+ pDigTable->CurIGValue = usb_read8(Adapter, 0xc50);
}
podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
DBG_88E("==> Turn on all dynamic function...\n");
@@ -2177,29 +2143,29 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
/* reset TSF, enable update TSF, correcting TSF On Beacon */
/* BCN interval */
- rtw_write16(adapt, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
- rtw_write8(adapt, REG_ATIMWND, 0x02);/* 2ms */
+ usb_write16(adapt, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
+ usb_write8(adapt, REG_ATIMWND, 0x02);/* 2ms */
_InitBeaconParameters(adapt);
- rtw_write8(adapt, REG_SLOT, 0x09);
+ usb_write8(adapt, REG_SLOT, 0x09);
- value32 = rtw_read32(adapt, REG_TCR);
+ value32 = usb_read32(adapt, REG_TCR);
value32 &= ~TSFRST;
- rtw_write32(adapt, REG_TCR, value32);
+ usb_write32(adapt, REG_TCR, value32);
value32 |= TSFRST;
- rtw_write32(adapt, REG_TCR, value32);
+ usb_write32(adapt, REG_TCR, value32);
/* NOTE: Fix test chip's bug (about contention windows's randomness) */
- rtw_write8(adapt, REG_RXTSF_OFFSET_CCK, 0x50);
- rtw_write8(adapt, REG_RXTSF_OFFSET_OFDM, 0x50);
+ usb_write8(adapt, REG_RXTSF_OFFSET_CCK, 0x50);
+ usb_write8(adapt, REG_RXTSF_OFFSET_OFDM, 0x50);
_BeaconFunctionEnable(adapt, true, true);
ResumeTxBeacon(adapt);
- rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg)|BIT(1));
+ usb_write8(adapt, bcn_ctrl_reg, usb_read8(adapt, bcn_ctrl_reg)|BIT(1));
}
static void rtl8188eu_init_default_value(struct adapter *adapt)
@@ -2231,10 +2197,9 @@ void rtl8188eu_set_hal_ops(struct adapter *adapt)
struct hal_ops *halfunc = &adapt->HalFunc;
- adapt->HalData = rtw_zmalloc(sizeof(struct hal_data_8188e));
+ adapt->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL);
if (adapt->HalData == NULL)
DBG_88E("cant not alloc memory for HAL DATA\n");
- adapt->hal_data_sz = sizeof(struct hal_data_8188e);
halfunc->hal_power_on = rtl8188eu_InitPowerOn;
halfunc->hal_init = &rtl8188eu_hal_init;
@@ -2244,7 +2209,6 @@ void rtl8188eu_set_hal_ops(struct adapter *adapt)
halfunc->inirp_deinit = &rtl8188eu_inirp_deinit;
halfunc->init_xmit_priv = &rtl8188eu_init_xmit_priv;
- halfunc->free_xmit_priv = &rtl8188eu_free_xmit_priv;
halfunc->init_recv_priv = &rtl8188eu_init_recv_priv;
halfunc->free_recv_priv = &rtl8188eu_free_recv_priv;
@@ -2253,7 +2217,7 @@ void rtl8188eu_set_hal_ops(struct adapter *adapt)
halfunc->init_default_value = &rtl8188eu_init_default_value;
halfunc->intf_chip_configure = &rtl8188eu_interface_configure;
- halfunc->read_adapter_info = &ReadAdapterInfo8188EU;
+ halfunc->read_adapter_info = &_ReadAdapterInfo8188EU;
halfunc->SetHwRegHandler = &SetHwReg8188EU;
halfunc->GetHwRegHandler = &GetHwReg8188EU;
diff --git a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c b/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
deleted file mode 100644
index 3aadf560de00..000000000000
--- a/drivers/staging/rtl8188eu/hal/usb_ops_linux.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _HCI_OPS_OS_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <osdep_intf.h>
-#include <usb_ops.h>
-#include <recv_osdep.h>
-#include <rtl8188e_hal.h>
-
-static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
-{
- struct adapter *adapt = pintfhdl->padapter;
- struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
- struct usb_device *udev = dvobjpriv->pusbdev;
- unsigned int pipe;
- int status = 0;
- u8 reqtype;
- u8 *pIo_buf;
- int vendorreq_times = 0;
-
- if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usbctrl_vendorreq:(adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
- status = -EPERM;
- goto exit;
- }
-
- if (len > MAX_VENDOR_REQ_CMD_SIZE) {
- DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__);
- status = -EINVAL;
- goto exit;
- }
-
- _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL);
-
- /* Acquire IO memory for vendorreq */
- pIo_buf = dvobjpriv->usb_vendor_req_buf;
-
- if (pIo_buf == NULL) {
- DBG_88E("[%s] pIo_buf == NULL\n", __func__);
- status = -ENOMEM;
- goto release_mutex;
- }
-
- while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) {
- _rtw_memset(pIo_buf, 0, len);
-
- if (requesttype == 0x01) {
- pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
- reqtype = REALTEK_USB_VENQT_READ;
- } else {
- pipe = usb_sndctrlpipe(udev, 0);/* write_out */
- reqtype = REALTEK_USB_VENQT_WRITE;
- memcpy(pIo_buf, pdata, len);
- }
-
- status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (status == len) { /* Success this control transfer. */
- rtw_reset_continual_urb_error(dvobjpriv);
- if (requesttype == 0x01)
- memcpy(pdata, pIo_buf, len);
- } else { /* error cases */
- DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n",
- value, (requesttype == 0x01) ? "read" : "write",
- len, status, *(u32 *)pdata, vendorreq_times);
-
- if (status < 0) {
- if (status == (-ESHUTDOWN) || status == -ENODEV) {
- adapt->bSurpriseRemoved = true;
- } else {
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- haldata->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
- }
- } else { /* status != len && status >= 0 */
- if (status > 0) {
- if (requesttype == 0x01) {
- /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
- memcpy(pdata, pIo_buf, len);
- }
- }
- }
-
- if (rtw_inc_and_chk_continual_urb_error(dvobjpriv)) {
- adapt->bSurpriseRemoved = true;
- break;
- }
-
- }
-
- /* firmware download is checksumed, don't retry */
- if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len)
- break;
- }
-release_mutex:
- mutex_unlock(&dvobjpriv->usb_vendor_req_mutex);
-exit:
- return status;
-}
-
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 data = 0;
-
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 1;
-
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
-
-
- return data;
-
-}
-
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
- wvalue = (u16)(addr&0x0000ffff);
- len = 2;
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
-
- return (u16)(le32_to_cpu(data)&0xffff);
-}
-
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
-
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 4;
-
- usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
-
-
- return le32_to_cpu(data);
-}
-
-static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 data;
- int ret;
-
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
- wvalue = (u16)(addr&0x0000ffff);
- len = 1;
- data = val;
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
- return ret;
-}
-
-static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
- int ret;
-
-
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 2;
-
- data = cpu_to_le32(val & 0x0000ffff);
-
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
-
-
- return ret;
-}
-
-static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
- int ret;
-
-
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 4;
- data = cpu_to_le32(val);
-
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
-
-
- return ret;
-}
-
-static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
- int ret;
-
-
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = length;
- memcpy(buf, pdata, len);
-
- ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, buf, len, requesttype);
-
-
- return ret;
-}
-
-static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf)
-{
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
-
- if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) {
- DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len);
- return;
- }
-
- /* HISR */
- memcpy(&(haldata->IntArray[0]), &(pbuf[USB_INTR_CONTENT_HISR_OFFSET]), 4);
- memcpy(&(haldata->IntArray[1]), &(pbuf[USB_INTR_CONTENT_HISRE_OFFSET]), 4);
-
- /* C2H Event */
- if (pbuf[0] != 0)
- memcpy(&(haldata->C2hArray[0]), &(pbuf[USB_INTR_CONTENT_C2H_OFFSET]), 16);
-}
-
-static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
-{
- u8 *pbuf;
- u8 shift_sz = 0;
- u16 pkt_cnt;
- u32 pkt_offset, skb_len, alloc_sz;
- s32 transfer_len;
- struct recv_stat *prxstat;
- struct phy_stat *pphy_status = NULL;
- struct sk_buff *pkt_copy = NULL;
- struct recv_frame *precvframe = NULL;
- struct rx_pkt_attrib *pattrib = NULL;
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- struct recv_priv *precvpriv = &adapt->recvpriv;
- struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
-
- transfer_len = (s32)pskb->len;
- pbuf = pskb->data;
-
- prxstat = (struct recv_stat *)pbuf;
- pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
-
- do {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
- ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
- prxstat->rxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4));
-
- prxstat = (struct recv_stat *)pbuf;
-
- precvframe = rtw_alloc_recvframe(pfree_recv_queue);
- if (precvframe == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvbuf2recvframe: precvframe==NULL\n"));
- DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__);
- goto _exit_recvbuf2recvframe;
- }
-
- _rtw_init_listhead(&precvframe->list);
- precvframe->len = 0;
-
- update_recvframe_attrib_88e(precvframe, prxstat);
-
- pattrib = &precvframe->attrib;
-
- if ((pattrib->crc_err) || (pattrib->icv_err)) {
- DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err);
-
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
-
- if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX))
- pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
-
- pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
-
- if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recvbuf2recvframe: pkt_len<=0\n"));
- DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__);
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
-
- /* Modified by Albert 20101213 */
- /* For 8 bytes IP header alignment. */
- if (pattrib->qos) /* Qos data, wireless lan header length is 26 */
- shift_sz = 6;
- else
- shift_sz = 0;
-
- skb_len = pattrib->pkt_len;
-
- /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
- /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
- if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
- if (skb_len <= 1650)
- alloc_sz = 1664;
- else
- alloc_sz = skb_len + 14;
- } else {
- alloc_sz = skb_len;
- /* 6 is for IP header 8 bytes alignment in QoS packet case. */
- /* 8 is for skb->data 4 bytes alignment. */
- alloc_sz += 14;
- }
-
- pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz);
- if (pkt_copy) {
- pkt_copy->dev = adapt->pnetdev;
- precvframe->pkt = pkt_copy;
- precvframe->rx_head = pkt_copy->data;
- precvframe->rx_end = pkt_copy->data + alloc_sz;
- skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
- skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
- memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
- precvframe->rx_tail = pkt_copy->data;
- precvframe->rx_data = pkt_copy->data;
- } else {
- if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
- DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n");
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
- precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
- if (precvframe->pkt) {
- precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE;
- precvframe->rx_head = precvframe->rx_tail;
- precvframe->rx_data = precvframe->rx_tail;
- precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz;
- } else {
- DBG_88E("recvbuf2recvframe: skb_clone fail\n");
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
- }
-
- recvframe_put(precvframe, skb_len);
-
- switch (haldata->UsbRxAggMode) {
- case USB_RX_AGG_DMA:
- case USB_RX_AGG_MIX:
- pkt_offset = (u16)_RND128(pkt_offset);
- break;
- case USB_RX_AGG_USB:
- pkt_offset = (u16)_RND4(pkt_offset);
- break;
- case USB_RX_AGG_DISABLE:
- default:
- break;
- }
- if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
- if (pattrib->physt)
- update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status);
- if (rtw_recv_entry(precvframe) != _SUCCESS) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
- ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
- }
- } else {
- /* enqueue recvframe to txrtp queue */
- if (pattrib->pkt_rpt_type == TX_REPORT1) {
- /* CCX-TXRPT ack for xmit mgmt frames. */
- handle_txrpt_ccx_88e(adapt, precvframe->rx_data);
- } else if (pattrib->pkt_rpt_type == TX_REPORT2) {
- ODM_RA_TxRPT2Handle_8188E(
- &haldata->odmpriv,
- precvframe->rx_data,
- pattrib->pkt_len,
- pattrib->MacIDValidEntry[0],
- pattrib->MacIDValidEntry[1]
- );
- } else if (pattrib->pkt_rpt_type == HIS_REPORT) {
- interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->rx_data);
- }
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- }
- pkt_cnt--;
- transfer_len -= pkt_offset;
- pbuf += pkt_offset;
- precvframe = NULL;
- pkt_copy = NULL;
-
- if (transfer_len > 0 && pkt_cnt == 0)
- pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
-
- } while ((transfer_len > 0) && (pkt_cnt > 0));
-
-_exit_recvbuf2recvframe:
-
- return _SUCCESS;
-}
-
-void rtl8188eu_recv_tasklet(void *priv)
-{
- struct sk_buff *pskb;
- struct adapter *adapt = (struct adapter *)priv;
- struct recv_priv *precvpriv = &adapt->recvpriv;
-
- while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
- if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) {
- DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n");
- dev_kfree_skb_any(pskb);
- break;
- }
- recvbuf2recvframe(adapt, pskb);
- skb_reset_tail_pointer(pskb);
- pskb->len = 0;
- skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
- }
-}
-
-static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
-{
- struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
- struct adapter *adapt = (struct adapter *)precvbuf->adapter;
- struct recv_priv *precvpriv = &adapt->recvpriv;
-
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete!!!\n"));
-
- precvpriv->rx_pending_cnt--;
-
- if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
- adapt->bDriverStopped, adapt->bSurpriseRemoved));
-
- precvbuf->reuse = true;
- DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
- __func__, adapt->bDriverStopped,
- adapt->bSurpriseRemoved, adapt->bReadPortCancel);
- return;
- }
-
- if (purb->status == 0) { /* SUCCESS */
- if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
- precvbuf->reuse = true;
- rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
- DBG_88E("%s()-%d: RX Warning!\n", __func__, __LINE__);
- } else {
- rtw_reset_continual_urb_error(adapter_to_dvobj(adapt));
-
- skb_put(precvbuf->pskb, purb->actual_length);
- skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
-
- if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
- tasklet_schedule(&precvpriv->recv_tasklet);
-
- precvbuf->pskb = NULL;
- precvbuf->reuse = false;
- rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
- }
- } else {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete : purb->status(%d) != 0\n", purb->status));
-
- DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
- skb_put(precvbuf->pskb, purb->actual_length);
- precvbuf->pskb = NULL;
-
- if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt)))
- adapt->bSurpriseRemoved = true;
-
- switch (purb->status) {
- case -EINVAL:
- case -EPIPE:
- case -ENODEV:
- case -ESHUTDOWN:
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete:bSurpriseRemoved=true\n"));
- case -ENOENT:
- adapt->bDriverStopped = true;
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete:bDriverStopped=true\n"));
- break;
- case -EPROTO:
- case -EOVERFLOW:
- {
- struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
- haldata->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
- }
- precvbuf->reuse = true;
- rtw_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
- break;
- case -EINPROGRESS:
- DBG_88E("ERROR: URB IS IN PROGRESS!\n");
- break;
- default:
- break;
- }
- }
-}
-
-static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
-{
- struct urb *purb = NULL;
- struct recv_buf *precvbuf = (struct recv_buf *)rmem;
- struct adapter *adapter = pintfhdl->padapter;
- struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
- struct recv_priv *precvpriv = &adapter->recvpriv;
- struct usb_device *pusbd = pdvobj->pusbdev;
- int err;
- unsigned int pipe;
- size_t tmpaddr = 0;
- size_t alignment = 0;
- u32 ret = _SUCCESS;
-
-
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
- adapter->pwrctrlpriv.pnp_bstop_trx) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usb_read_port:(adapt->bDriverStopped ||adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
- return _FAIL;
- }
-
- if (!precvbuf) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usb_read_port:precvbuf==NULL\n"));
- return _FAIL;
- }
-
- if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
- precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
- if (NULL != precvbuf->pskb)
- precvbuf->reuse = true;
- }
-
- /* re-assign for linux based on skb */
- if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
- precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
- if (precvbuf->pskb == NULL) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
- DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
- return _FAIL;
- }
-
- tmpaddr = (size_t)precvbuf->pskb->data;
- alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
- skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
- } else { /* reuse skb */
- precvbuf->reuse = false;
- }
-
- precvpriv->rx_pending_cnt++;
-
- purb = precvbuf->purb;
-
- /* translate DMA FIFO addr to pipehandle */
- pipe = ffaddr2pipehdl(pdvobj, addr);
-
- usb_fill_bulk_urb(purb, pusbd, pipe,
- precvbuf->pskb->data,
- MAX_RECVBUF_SZ,
- usb_read_port_complete,
- precvbuf);/* context is precvbuf */
-
- err = usb_submit_urb(purb, GFP_ATOMIC);
- if ((err) && (err != (-EPERM))) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
- err, purb->status));
- DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
- err, purb->status);
- ret = _FAIL;
- }
-
- return ret;
-}
-
-void rtl8188eu_xmit_tasklet(void *priv)
-{
- int ret = false;
- struct adapter *adapt = (struct adapter *)priv;
- struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
-
- if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY))
- return;
-
- while (1) {
- if ((adapt->bDriverStopped) ||
- (adapt->bSurpriseRemoved) ||
- (adapt->bWritePortCancel)) {
- DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
- break;
- }
-
- ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL);
-
- if (!ret)
- break;
- }
-}
-
-void rtl8188eu_set_intf_ops(struct _io_ops *pops)
-{
- _rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops));
- pops->_read8 = &usb_read8;
- pops->_read16 = &usb_read16;
- pops->_read32 = &usb_read32;
- pops->_read_mem = &usb_read_mem;
- pops->_read_port = &usb_read_port;
- pops->_write8 = &usb_write8;
- pops->_write16 = &usb_write16;
- pops->_write32 = &usb_write32;
- pops->_writeN = &usb_writeN;
- pops->_write_mem = &usb_write_mem;
- pops->_write_port = &usb_write_port;
- pops->_read_port_cancel = &usb_read_port_cancel;
- pops->_write_port_cancel = &usb_write_port_cancel;
-}
diff --git a/drivers/staging/rtl8188eu/include/Hal8188EReg.h b/drivers/staging/rtl8188eu/include/Hal8188EReg.h
deleted file mode 100644
index d880b0cc803f..000000000000
--- a/drivers/staging/rtl8188eu/include/Hal8188EReg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-/* */
-/* File Name: Hal8188EReg.h */
-/* */
-/* Description: */
-/* */
-/* This file is for RTL8188E register definition. */
-/* */
-/* */
-/* */
-#ifndef __HAL_8188E_REG_H__
-#define __HAL_8188E_REG_H__
-
-/* */
-/* Register Definition */
-/* */
-#define TRX_ANTDIV_PATH 0x860
-#define RX_ANTDIV_PATH 0xb2c
-#define ODM_R_A_AGC_CORE1_8188E 0xc50
-
-
-/* */
-/* Bitmap Definition */
-/* */
-#define BIT_FA_RESET_8188E BIT0
-
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/HalPhyRf.h b/drivers/staging/rtl8188eu/include/HalPhyRf.h
deleted file mode 100644
index 1ec497100da1..000000000000
--- a/drivers/staging/rtl8188eu/include/HalPhyRf.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
- #ifndef __HAL_PHY_RF_H__
- #define __HAL_PHY_RF_H__
-
-#define ODM_TARGET_CHNL_NUM_2G_5G 59
-
-void ODM_ResetIQKResult(struct odm_dm_struct *pDM_Odm);
-
-u8 ODM_GetRightChnlPlaceforIQK(u8 chnl);
-
-#endif /* #ifndef __HAL_PHY_RF_H__ */
diff --git a/drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h b/drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h
index 287e9f9eae4a..90a26c119d97 100644
--- a/drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h
+++ b/drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h
@@ -25,7 +25,7 @@
#define IQK_DELAY_TIME_88E 10 /* ms */
#define index_mapping_NUM_88E 15
#define AVG_THERMAL_NUM_88E 4
-
+#define ODM_TARGET_CHNL_NUM_2G_5G 59
void ODM_TxPwrTrackAdjust88E(struct odm_dm_struct *pDM_Odm,
u8 Type, /* 0 = OFDM, 1 = CCK */
diff --git a/drivers/staging/rtl8188eu/include/cmd_osdep.h b/drivers/staging/rtl8188eu/include/cmd_osdep.h
deleted file mode 100644
index 5a8465e147b3..000000000000
--- a/drivers/staging/rtl8188eu/include/cmd_osdep.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef __CMD_OSDEP_H_
-#define __CMD_OSDEP_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-
-extern int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv);
-extern int _rtw_init_evt_priv(struct evt_priv *pevtpriv);
-extern void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv);
-extern int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj);
-extern struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue);
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h
index 10cc1a1bcab9..8f42d48243f0 100644
--- a/drivers/staging/rtl8188eu/include/drv_types.h
+++ b/drivers/staging/rtl8188eu/include/drv_types.h
@@ -40,7 +40,6 @@
#include <rtw_qos.h>
#include <rtw_security.h>
#include <rtw_pwrctrl.h>
-#include <rtw_io.h>
#include <rtw_eeprom.h>
#include <sta_info.h>
#include <rtw_mlme.h>
@@ -49,17 +48,7 @@
#include <rtw_event.h>
#include <rtw_led.h>
#include <rtw_mlme_ext.h>
-#include <rtw_p2p.h>
#include <rtw_ap.h>
-#include <rtw_mp.h>
-#include <rtw_br_ext.h>
-
-enum _NIC_VERSION {
- RTL8711_NIC,
- RTL8712_NIC,
- RTL8713_NIC,
- RTL8716_NIC
-};
#define SPEC_DEV_ID_NONE BIT(0)
#define SPEC_DEV_ID_DISABLE_HT BIT(1)
@@ -68,12 +57,6 @@ enum _NIC_VERSION {
#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4)
#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5)
-struct specific_device_id {
- u32 flags;
- u16 idVendor;
- u16 idProduct;
-};
-
struct registry_priv {
u8 chip_version;
u8 rfintfs;
@@ -165,7 +148,6 @@ struct rt_firmware {
struct dvobj_priv {
struct adapter *if1;
- struct adapter *if2;
struct rt_firmware firmware;
/* For 92D, DMDP have 2 interface. */
@@ -177,8 +159,6 @@ struct dvobj_priv {
int RtOutPipe[3];
u8 Queue2Pipe[HW_QUEUE_ENTRY];/* for out pipe mapping */
- u8 irq_alloc;
-
/*-------- below is for USB INTERFACE --------*/
u8 nr_endpoint;
@@ -186,17 +166,12 @@ struct dvobj_priv {
u8 RtNumInPipes;
u8 RtNumOutPipes;
int ep_num[5]; /* endpoint number */
- int RegUsbSS;
- struct semaphore usb_suspend_sema;
struct mutex usb_vendor_req_mutex;
- u8 *usb_alloc_vendor_req_buf;
u8 *usb_vendor_req_buf;
struct usb_interface *pusbintf;
struct usb_device *pusbdev;
-
- atomic_t continual_urb_error;
};
static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj)
@@ -206,37 +181,14 @@ static inline struct device *dvobj_to_dev(struct dvobj_priv *dvobj)
return &dvobj->pusbintf->dev;
};
-enum _IFACE_TYPE {
- IFACE_PORT0, /* mapping to port0 for C/D series chips */
- IFACE_PORT1, /* mapping to port1 for C/D series chip */
- MAX_IFACE_PORT,
-};
-
-enum _ADAPTER_TYPE {
- PRIMARY_ADAPTER,
- SECONDARY_ADAPTER,
- MAX_ADAPTER,
-};
-
-enum driver_state {
- DRIVER_NORMAL = 0,
- DRIVER_DISAPPEAR = 1,
- DRIVER_REPLACE_DONGLE = 2,
-};
-
struct adapter {
- int DriverState;/* for disable driver using module, use dongle toi
- * replace module. */
int pid[3];/* process id from UI, 0:wps, 1:hostapd, 2:dhcpcd */
- int bDongle;/* build-in module or external dongle */
u16 chip_type;
struct dvobj_priv *dvobj;
struct mlme_priv mlmepriv;
struct mlme_ext_priv mlmeextpriv;
struct cmd_priv cmdpriv;
- struct evt_priv evtpriv;
- struct io_priv iopriv;
struct xmit_priv xmitpriv;
struct recv_priv recvpriv;
struct sta_priv stapriv;
@@ -245,7 +197,6 @@ struct adapter {
struct pwrctrl_priv pwrctrlpriv;
struct eeprom_priv eeprompriv;
struct led_priv ledpriv;
- struct mp_priv mppriv;
#ifdef CONFIG_88EU_AP_MODE
struct hostapd_priv *phostapdpriv;
@@ -254,26 +205,15 @@ struct adapter {
struct wifidirect_info wdinfo;
void *HalData;
- u32 hal_data_sz;
struct hal_ops HalFunc;
s32 bDriverStopped;
s32 bSurpriseRemoved;
- s32 bCardDisableWOHSM;
-
- u32 IsrContent;
- u32 ImrContent;
- u8 EepromAddressSize;
u8 hw_init_completed;
- u8 bDriverIsGoingToUnload;
- u8 init_adpt_in_progress;
- u8 bHaltInProgress;
void *cmdThread;
void *evtThread;
- void *xmitThread;
- void *recvThread;
void (*intf_start)(struct adapter *adapter);
void (*intf_stop)(struct adapter *adapter);
struct net_device *pnetdev;
@@ -293,32 +233,16 @@ struct adapter {
int net_closed;
u8 bFWReady;
- u8 bBTFWReady;
u8 bReadPortCancel;
u8 bWritePortCancel;
u8 bRxRSSIDisplay;
/* The driver will show up the desired channel number
* when this flag is 1. */
u8 bNotifyChannelChange;
-#ifdef CONFIG_88EU_P2P
- /* The driver will show the current P2P status when the
- * upper application reads it. */
- u8 bShowGetP2PState;
-#endif
- struct adapter *pbuddy_adapter;
- struct mutex *hw_init_mutex;
+ struct mutex hw_init_mutex;
spinlock_t br_ext_lock;
- struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE];
- int pppoe_connection_in_progress;
- unsigned char pppoe_addr[MACADDRLEN];
- unsigned char scdb_mac[MACADDRLEN];
- unsigned char scdb_ip[4];
- struct nat25_network_db_entry *scdb_entry;
- unsigned char br_mac[MACADDRLEN];
- unsigned char br_ip[4];
- struct br_ext_info ethBrExtInfo;
u8 fix_rate;
diff --git a/drivers/staging/rtl8188eu/include/hal_com.h b/drivers/staging/rtl8188eu/include/hal_com.h
index 81c27090dd52..47715d949d54 100644
--- a/drivers/staging/rtl8188eu/include/hal_com.h
+++ b/drivers/staging/rtl8188eu/include/hal_com.h
@@ -166,8 +166,4 @@ void HalSetBrateCfg(struct adapter *Adapter, u8 *mBratesOS, u16 *pBrateCfg);
bool Hal_MappingOutPipe(struct adapter *pAdapter, u8 NumOutPipe);
void hal_init_macaddr(struct adapter *adapter);
-
-void c2h_evt_clear(struct adapter *adapter);
-s32 c2h_evt_read(struct adapter *adapter, u8 *buf);
-
#endif /* __HAL_COMMON_H__ */
diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h
index c59fccde39c5..56d5c50bb734 100644
--- a/drivers/staging/rtl8188eu/include/hal_intf.h
+++ b/drivers/staging/rtl8188eu/include/hal_intf.h
@@ -144,8 +144,6 @@ enum hal_intf_ps_func {
HAL_MAX_ID,
};
-typedef s32 (*c2h_id_filter)(u8 id);
-
struct hal_ops {
u32 (*hal_power_on)(struct adapter *padapter);
u32 (*hal_init)(struct adapter *padapter);
@@ -157,7 +155,6 @@ struct hal_ops {
u32 (*inirp_deinit)(struct adapter *padapter);
s32 (*init_xmit_priv)(struct adapter *padapter);
- void (*free_xmit_priv)(struct adapter *padapter);
s32 (*init_recv_priv)(struct adapter *padapter);
void (*free_recv_priv)(struct adapter *padapter);
@@ -197,9 +194,6 @@ struct hal_ops {
enum hal_def_variable eVariable,
void *pValue);
- void (*GetHalODMVarHandler)(struct adapter *padapter,
- enum hal_odm_variable eVariable,
- void *pValue1, bool bSet);
void (*SetHalODMVarHandler)(struct adapter *padapter,
enum hal_odm_variable eVariable,
void *pValue1, bool bSet);
@@ -210,8 +204,6 @@ struct hal_ops {
void (*Add_RateATid)(struct adapter *adapter, u32 bitmap, u8 arg,
u8 rssi_level);
- void (*run_thread)(struct adapter *adapter);
- void (*cancel_thread)(struct adapter *adapter);
u8 (*AntDivBeforeLinkHandler)(struct adapter *adapter);
void (*AntDivCompareHandler)(struct adapter *adapter,
@@ -233,29 +225,7 @@ struct hal_ops {
enum rf_radio_path eRFPath, u32 RegAddr,
u32 BitMask, u32 Data);
- void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
- u8 PwrState);
- void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
- u16 _size_byte, u8 *pbuf, bool bPseudoTest);
- void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
- u8 type, void *pOut, bool bPseudoTest);
- u16 (*EfuseGetCurrentSize)(struct adapter *padapter, u8 efuseType,
- bool bPseudoTest);
- int (*Efuse_PgPacketRead)(struct adapter *adapter, u8 offset,
- u8 *data, bool bPseudoTest);
- int (*Efuse_PgPacketWrite)(struct adapter *padapter, u8 offset,
- u8 word_en, u8 *data, bool bPseudoTest);
- u8 (*Efuse_WordEnableDataWrite)(struct adapter *padapter,
- u16 efuse_addr, u8 word_en,
- u8 *data, bool bPseudoTest);
- bool (*Efuse_PgPacketWrite_BT)(struct adapter *padapter, u8 offset,
- u8 word_en, u8 *data, bool test);
-
void (*sreset_init_value)(struct adapter *padapter);
- void (*sreset_reset_value)(struct adapter *padapter);
- void (*silentreset)(struct adapter *padapter);
- void (*sreset_xmit_status_check)(struct adapter *padapter);
- void (*sreset_linked_status_check) (struct adapter *padapter);
u8 (*sreset_get_wifi_status)(struct adapter *padapter);
int (*IOL_exec_cmds_sync)(struct adapter *padapter,
@@ -264,9 +234,6 @@ struct hal_ops {
void (*hal_notch_filter)(struct adapter *adapter, bool enable);
void (*hal_reset_security_engine)(struct adapter *adapter);
- s32 (*c2h_handler)(struct adapter *padapter,
- struct c2h_evt_hdr *c2h_evt);
- c2h_id_filter c2h_id_filter_ccx;
};
enum rt_eeprom_type {
@@ -317,9 +284,6 @@ u8 rtw_hal_get_def_var(struct adapter *padapter,
void rtw_hal_set_odm_var(struct adapter *padapter,
enum hal_odm_variable eVariable, void *pValue1,
bool bSet);
-void rtw_hal_get_odm_var(struct adapter *padapter,
- enum hal_odm_variable eVariable,
- void *pValue1, bool bSet);
void rtw_hal_enable_interrupt(struct adapter *padapter);
void rtw_hal_disable_interrupt(struct adapter *padapter);
@@ -332,7 +296,6 @@ s32 rtw_hal_mgnt_xmit(struct adapter *padapter,
struct xmit_frame *pmgntframe);
s32 rtw_hal_init_xmit_priv(struct adapter *padapter);
-void rtw_hal_free_xmit_priv(struct adapter *padapter);
s32 rtw_hal_init_recv_priv(struct adapter *padapter);
void rtw_hal_free_recv_priv(struct adapter *padapter);
@@ -341,8 +304,6 @@ void rtw_hal_update_ra_mask(struct adapter *padapter, u32 mac_id, u8 level);
void rtw_hal_add_ra_tid(struct adapter *adapt, u32 bitmap, u8 arg, u8 level);
void rtw_hal_clone_data(struct adapter *dst_adapt,
struct adapter *src_adapt);
-void rtw_hal_start_thread(struct adapter *padapter);
-void rtw_hal_stop_thread(struct adapter *padapter);
void rtw_hal_bcn_related_reg_setting(struct adapter *padapter);
@@ -368,10 +329,6 @@ void rtw_hal_antdiv_rssi_compared(struct adapter *padapter,
struct wlan_bssid_ex *src);
void rtw_hal_sreset_init(struct adapter *padapter);
-void rtw_hal_sreset_reset(struct adapter *padapter);
-void rtw_hal_sreset_reset_value(struct adapter *padapter);
-void rtw_hal_sreset_xmit_status_check(struct adapter *padapter);
-void rtw_hal_sreset_linked_status_check(struct adapter *padapter);
u8 rtw_hal_sreset_get_wifi_status(struct adapter *padapter);
int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame,
@@ -380,9 +337,6 @@ int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame,
void rtw_hal_notch_filter(struct adapter *adapter, bool enable);
void rtw_hal_reset_security_engine(struct adapter *adapter);
-s32 rtw_hal_c2h_handler(struct adapter *adapter,
- struct c2h_evt_hdr *c2h_evt);
-c2h_id_filter rtw_hal_c2h_id_filter_ccx(struct adapter *adapter);
void indicate_wx_scan_complete_event(struct adapter *padapter);
u8 rtw_do_join(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/ieee80211.h b/drivers/staging/rtl8188eu/include/ieee80211.h
index c4d38d14abf1..3299571e339f 100644
--- a/drivers/staging/rtl8188eu/include/ieee80211.h
+++ b/drivers/staging/rtl8188eu/include/ieee80211.h
@@ -1233,19 +1233,6 @@ u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
void dump_ies(u8 *buf, u32 buf_len);
void dump_wps_ie(u8 *ie, u32 ie_len);
-#ifdef CONFIG_88EU_P2P
-void dump_p2p_ie(u8 *ie, u32 ie_len);
-u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen);
-u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
- u8 *buf_attr, u32 *len_attr);
-u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id,
- u8 *buf_content, uint *len_content);
-u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len,
- u8 *pdata_attr);
-void rtw_wlan_bssid_ex_remove_p2p_attr(struct wlan_bssid_ex *bss_ex,
- u8 attr_id);
-#endif
-
uint rtw_get_rateset_len(u8 *rateset);
struct registry_priv;
diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h
index 2eb769b3f35d..0ab8254ce901 100644
--- a/drivers/staging/rtl8188eu/include/odm_precomp.h
+++ b/drivers/staging/rtl8188eu/include/odm_precomp.h
@@ -30,6 +30,7 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <hal_intf.h>
+#include <usb_ops_linux.h>
/* 2 OutSrc Header Files */
@@ -39,7 +40,6 @@
#include "odm_RegDefine11AC.h"
#include "odm_RegDefine11N.h"
-#include "HalPhyRf.h"
#include "HalPhyRf_8188e.h"/* for IQK,LCK,Power-tracking */
#include "Hal8188ERateAdaptive.h"/* for RA,Power training */
#include "rtl8188e_hal.h"
@@ -49,7 +49,6 @@
#include "HalHWImg8188E_MAC.h"
#include "HalHWImg8188E_RF.h"
#include "HalHWImg8188E_BB.h"
-#include "Hal8188EReg.h"
#include "odm_RegConfig8188E.h"
#include "odm_RTL8188E.h"
@@ -72,7 +71,6 @@ void odm_RefreshRateAdaptiveMaskMP(struct odm_dm_struct *pDM_Odm);
void odm_DynamicBBPowerSaving(struct odm_dm_struct *pDM_Odm);
void odm_SwAntDivChkAntSwitch(struct odm_dm_struct *pDM_Odm, u8 Step);
void odm_EdcaTurboCheck(struct odm_dm_struct *pDM_Odm);
-void odm_DynamicTxPower(struct odm_dm_struct *pDM_Odm);
void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm);
void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm);
void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm);
diff --git a/drivers/staging/rtl8188eu/include/osdep_intf.h b/drivers/staging/rtl8188eu/include/osdep_intf.h
index c4599c583b59..efa786887962 100644
--- a/drivers/staging/rtl8188eu/include/osdep_intf.h
+++ b/drivers/staging/rtl8188eu/include/osdep_intf.h
@@ -24,38 +24,8 @@
#include <osdep_service.h>
#include <drv_types.h>
-struct intf_priv {
- u8 *intf_dev;
- u32 max_iosz; /* USB2.0: 128, USB1.1: 64, SDIO:64 */
- u32 max_xmitsz; /* USB2.0: unlimited, SDIO:512 */
- u32 max_recvsz; /* USB2.0: unlimited, SDIO:512 */
-
- u8 *io_rwmem;
- u8 *allocated_io_rwmem;
- u32 io_wsz; /* unit: 4bytes */
- u32 io_rsz;/* unit: 4bytes */
- u8 intf_status;
-
- void (*_bus_io)(u8 *priv);
-
-/*
-Under Sync. IRP (SDIO/USB)
-A protection mechanism is necessary for the io_rwmem(read/write protocol)
-
-Under Async. IRP (SDIO/USB)
-The protection mechanism is through the pending queue.
-*/
- struct mutex ioctl_mutex;
- /* when in USB, IO is through interrupt in/out endpoints */
- struct usb_device *udev;
- struct urb *piorw_urb;
- u8 io_irp_cnt;
- u8 bio_irp_pending;
- struct semaphore io_retevt;
- struct timer_list io_timer;
- u8 bio_irp_timeout;
- u8 bio_timer_cancel;
-};
+extern char *rtw_initmac;
+extern int rtw_mc2u_disable;
u8 rtw_init_drv_sw(struct adapter *padapter);
u8 rtw_free_drv_sw(struct adapter *padapter);
@@ -73,11 +43,9 @@ u16 rtw_recv_select_queue(struct sk_buff *skb);
void rtw_proc_init_one(struct net_device *dev);
void rtw_proc_remove_one(struct net_device *dev);
+int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
void rtw_ips_dev_unload(struct adapter *padapter);
-
int rtw_ips_pwr_up(struct adapter *padapter);
void rtw_ips_pwr_down(struct adapter *padapter);
-int rtw_hw_suspend(struct adapter *padapter);
-int rtw_hw_resume(struct adapter *padapter);
#endif /* _OSDEP_INTF_H_ */
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index 3859acd358a6..fed9c86890b4 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -76,11 +76,6 @@ static inline int _enter_critical_mutex(struct mutex *pmutex,
return ret;
}
-static inline void rtw_list_delete(struct list_head *plist)
-{
- list_del_init(plist);
-}
-
static inline void _init_timer(struct timer_list *ptimer,
struct net_device *nic_hdl,
void *pfunc, void *cntx)
@@ -95,22 +90,11 @@ static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
mod_timer(ptimer , (jiffies+(delay_time*HZ/1000)));
}
-static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled)
-{
- del_timer_sync(ptimer);
- *bcancelled = true;/* true ==1; false==0 */
-}
-
#define RTW_TIMER_HDL_ARGS void *FunctionContext
#define RTW_TIMER_HDL_NAME(name) rtw_##name##_timer_hdl
#define RTW_DECLARE_TIMER_HDL(name) \
void RTW_TIMER_HDL_NAME(name)(RTW_TIMER_HDL_ARGS)
-static inline void _cancel_workitem_sync(struct work_struct *pwork)
-{
- cancel_work_sync(pwork);
-}
-
static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
{
return netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 0)) &&
@@ -119,9 +103,6 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3));
}
-#ifndef BIT
- #define BIT(x) (1 << (x))
-#endif
#define BIT0 0x00000001
#define BIT1 0x00000002
@@ -163,137 +144,17 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
extern int RTW_STATUS_CODE(int error_code);
-/* flags used for rtw_update_mem_stat() */
-enum {
- MEM_STAT_VIR_ALLOC_SUCCESS,
- MEM_STAT_VIR_ALLOC_FAIL,
- MEM_STAT_VIR_FREE,
- MEM_STAT_PHY_ALLOC_SUCCESS,
- MEM_STAT_PHY_ALLOC_FAIL,
- MEM_STAT_PHY_FREE,
- MEM_STAT_TX, /* used to distinguish TX/RX, asigned from caller */
- MEM_STAT_TX_ALLOC_SUCCESS,
- MEM_STAT_TX_ALLOC_FAIL,
- MEM_STAT_TX_FREE,
- MEM_STAT_RX, /* used to distinguish TX/RX, asigned from caller */
- MEM_STAT_RX_ALLOC_SUCCESS,
- MEM_STAT_RX_ALLOC_FAIL,
- MEM_STAT_RX_FREE
-};
-
-extern unsigned char MCS_rate_2R[16];
-extern unsigned char MCS_rate_1R[16];
-extern unsigned char RTW_WPA_OUI[];
-extern unsigned char WPA_TKIP_CIPHER[4];
-extern unsigned char RSN_TKIP_CIPHER[4];
-
#define rtw_update_mem_stat(flag, sz) do {} while (0)
-u8 *_rtw_zmalloc(u32 sz);
u8 *_rtw_malloc(u32 sz);
-void _rtw_mfree(u8 *pbuf, u32 sz);
#define rtw_malloc(sz) _rtw_malloc((sz))
-#define rtw_zmalloc(sz) _rtw_zmalloc((sz))
-#define rtw_mfree(pbuf, sz) _rtw_mfree((pbuf), (sz))
void *rtw_malloc2d(int h, int w, int size);
-void rtw_mfree2d(void *pbuf, int h, int w, int size);
-
-void _rtw_memcpy(void *dec, void *sour, u32 sz);
-void _rtw_memset(void *pbuf, int c, u32 sz);
-
-void _rtw_init_listhead(struct list_head *list);
-u32 rtw_is_list_empty(struct list_head *phead);
-void rtw_list_insert_head(struct list_head *plist, struct list_head *phead);
-void rtw_list_insert_tail(struct list_head *plist, struct list_head *phead);
-void rtw_list_delete(struct list_head *plist);
u32 _rtw_down_sema(struct semaphore *sema);
void _rtw_init_queue(struct __queue *pqueue);
-u32 _rtw_queue_empty(struct __queue *pqueue);
-u32 rtw_end_of_queue_search(struct list_head *queue,
- struct list_head *pelement);
-u32 rtw_systime_to_ms(u32 systime);
-u32 rtw_ms_to_systime(u32 ms);
s32 rtw_get_passing_time_ms(u32 start);
-s32 rtw_get_time_interval_ms(u32 start, u32 end);
-
-void rtw_sleep_schedulable(int ms);
-
-u32 rtw_atoi(u8 *s);
-
-static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
-{
- return del_timer_sync(ptimer);
-}
-
-static inline void thread_enter(char *name)
-{
- allow_signal(SIGTERM);
-}
-
-static inline void flush_signals_thread(void)
-{
- if (signal_pending(current))
- flush_signals(current);
-}
-
-#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r))
-#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0 : 1)) << 2)
-
-static inline u32 _RND4(u32 sz)
-{
- u32 val;
-
- val = ((sz >> 2) + ((sz & 3) ? 1 : 0)) << 2;
- return val;
-}
-
-static inline u32 _RND8(u32 sz)
-{
- u32 val;
-
- val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3;
- return val;
-}
-
-static inline u32 _RND128(u32 sz)
-{
- u32 val;
-
- val = ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7;
- return val;
-}
-
-static inline u32 _RND256(u32 sz)
-{
- u32 val;
-
- val = ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8;
- return val;
-}
-
-static inline u32 _RND512(u32 sz)
-{
- u32 val;
-
- val = ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9;
- return val;
-}
-
-static inline u32 bitshift(u32 bitmask)
-{
- u32 i;
-
- for (i = 0; i <= 31; i++)
- if (((bitmask>>i) & 0x1) == 1)
- break;
- return i;
-}
-
-/* limitation of path length */
-#define PATH_LENGTH_MAX PATH_MAX
struct rtw_netdev_priv_indicator {
void *priv;
@@ -301,7 +162,6 @@ struct rtw_netdev_priv_indicator {
};
struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
void *old_priv);
-struct net_device *rtw_alloc_etherdev(int sizeof_priv);
#define rtw_netdev_priv(netdev) \
(((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv)
@@ -319,50 +179,12 @@ void rtw_free_netdev(struct net_device *netdev);
#define rtw_signal_process(pid, sig) kill_pid(find_vpid((pid)), (sig), 1)
u64 rtw_modular64(u64 x, u64 y);
-u64 rtw_division64(u64 x, u64 y);
/* Macros for handling unaligned memory accesses */
-#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
-#define RTW_PUT_BE16(a, val) \
- do { \
- (a)[0] = ((u16) (val)) >> 8; \
- (a)[1] = ((u16) (val)) & 0xff; \
- } while (0)
-
-#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
-#define RTW_PUT_LE16(a, val) \
- do { \
- (a)[1] = ((u16) (val)) >> 8; \
- (a)[0] = ((u16) (val)) & 0xff; \
- } while (0)
-
#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
((u32) (a)[2]))
-#define RTW_PUT_BE32(a, val) \
- do { \
- (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
- (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
- (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
- (a)[3] = (u8) (((u32) (val)) & 0xff); \
- } while (0)
-
void rtw_buf_free(u8 **buf, u32 *buf_len);
void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len);
-
-struct rtw_cbuf {
- u32 write;
- u32 read;
- u32 size;
- void *bufs[0];
-};
-
-bool rtw_cbuf_full(struct rtw_cbuf *cbuf);
-bool rtw_cbuf_empty(struct rtw_cbuf *cbuf);
-bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf);
-void *rtw_cbuf_pop(struct rtw_cbuf *cbuf);
-struct rtw_cbuf *rtw_cbuf_alloc(u32 size);
-int wifirate2_ratetbl_inx(unsigned char rate);
-
#endif
diff --git a/drivers/staging/rtl8188eu/include/recv_osdep.h b/drivers/staging/rtl8188eu/include/recv_osdep.h
index a4fd95798f00..5aabd3984e58 100644
--- a/drivers/staging/rtl8188eu/include/recv_osdep.h
+++ b/drivers/staging/rtl8188eu/include/recv_osdep.h
@@ -43,10 +43,7 @@ int rtw_os_recv_resource_alloc(struct adapter *adapt,
int rtw_os_recvbuf_resource_alloc(struct adapter *adapt, struct recv_buf *buf);
-void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf);
-
void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl);
-int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb);
int _netdev_open(struct net_device *pnetdev);
int netdev_open(struct net_device *pnetdev);
int netdev_close(struct net_device *pnetdev);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
index b32bc28503d0..0e78e2a357bd 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
@@ -112,11 +112,6 @@ u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask);
void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg,
u8 rssi_level);
-#ifdef CONFIG_88EU_P2P
-void rtl8188e_set_p2p_ps_offload_cmd(struct adapter *adapt, u8 p2p_ps_state);
-#endif /* CONFIG_88EU_P2P */
-
-void CheckFwRsvdPageContent(struct adapter *adapt);
void rtl8188e_set_FwMediaStatus_cmd(struct adapter *adapt, __le16 mstatus_rpt);
#endif/* __RTL8188E_CMD_H__ */
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
index fe3b4545cdbb..fb206538392e 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
@@ -31,9 +31,8 @@
#include "rtl8188e_xmit.h"
#include "rtl8188e_cmd.h"
#include "Hal8188EPwrSeq.h"
-#include "rtl8188e_sreset.h"
#include "rtw_efuse.h"
-
+#include "rtw_sreset.h"
#include "odm_precomp.h"
/* Fw Array */
@@ -241,7 +240,6 @@ enum rt_regulator_mode {
struct hal_data_8188e {
struct HAL_VERSION VersionID;
- enum rt_multi_func MultiFunc; /* For multi-function consideration. */
enum rt_regulator_mode RegulatorMode; /* switching regulator or LDO */
u16 CustomerID;
@@ -387,10 +385,6 @@ struct hal_data_8188e {
u16 EfuseUsedBytes;
-#ifdef CONFIG_88EU_P2P
- struct P2P_PS_Offload_t p2p_ps_offload;
-#endif
-
/* Auto FSM to Turn On, include clock, isolation, power control
* for MAC only */
u8 bMacPwrCtrlOn;
@@ -456,19 +450,17 @@ void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo,
void Hal_ReadPowerSavingMode88E(struct adapter *pAdapter, u8 *hwinfo,
bool AutoLoadFail);
-bool HalDetectPwrDownMode88E(struct adapter *Adapter);
-
-void Hal_InitChannelPlan(struct adapter *padapter);
void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc);
/* register */
void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits);
-void rtl8188e_clone_haldata(struct adapter *dst, struct adapter *src);
void rtl8188e_start_thread(struct adapter *padapter);
void rtl8188e_stop_thread(struct adapter *padapter);
void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int len);
+s32 iol_execute(struct adapter *padapter, u8 control);
+void iol_mode_enable(struct adapter *padapter, u8 enable);
s32 rtl8188e_iol_efuse_patch(struct adapter *padapter);
void rtw_cancel_all_timer(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_sreset.h b/drivers/staging/rtl8188eu/include/rtl8188e_sreset.h
deleted file mode 100644
index a29e69519794..000000000000
--- a/drivers/staging/rtl8188eu/include/rtl8188e_sreset.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef _RTL8188E_SRESET_H_
-#define _RTL8188E_SRESET_H_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtw_sreset.h>
-
-void rtl8188e_silentreset_for_specific_platform(struct adapter *padapter);
-void rtl8188e_sreset_xmit_status_check(struct adapter *padapter);
-void rtl8188e_sreset_linked_status_check(struct adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
index cf7267a53659..0b96d42e290b 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_xmit.h
@@ -159,7 +159,6 @@ struct txrpt_ccx_88e {
void rtl8188e_fill_fake_txdesc(struct adapter *padapter, u8 *pDesc,
u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull);
s32 rtl8188eu_init_xmit_priv(struct adapter *padapter);
-void rtl8188eu_free_xmit_priv(struct adapter *padapter);
s32 rtl8188eu_hal_xmit(struct adapter *padapter, struct xmit_frame *frame);
s32 rtl8188eu_mgnt_xmit(struct adapter *padapter, struct xmit_frame *frame);
s32 rtl8188eu_xmit_buf_handler(struct adapter *padapter);
diff --git a/drivers/staging/rtl8188eu/include/rtw_br_ext.h b/drivers/staging/rtl8188eu/include/rtw_br_ext.h
deleted file mode 100644
index f21e7a4515d0..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_br_ext.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef _RTW_BR_EXT_H_
-#define _RTW_BR_EXT_H_
-
-#define MACADDRLEN 6
-#define _DEBUG_ERR DBG_88E
-#define _DEBUG_INFO DBG_88E
-#define DEBUG_WARN DBG_88E
-#define DEBUG_INFO DBG_88E
-#define DEBUG_ERR DBG_88E
-#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr)
-
-#define NAT25_HASH_BITS 4
-#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS)
-#define NAT25_AGEING_TIME 300
-
-#define MAX_NETWORK_ADDR_LEN 17
-
-struct nat25_network_db_entry {
- struct nat25_network_db_entry *next_hash;
- struct nat25_network_db_entry **pprev_hash;
- atomic_t use_count;
- unsigned char macAddr[6];
- unsigned long ageing_timer;
- unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
-};
-
-enum NAT25_METHOD {
- NAT25_MIN,
- NAT25_CHECK,
- NAT25_INSERT,
- NAT25_LOOKUP,
- NAT25_PARSE,
- NAT25_MAX
-};
-
-struct br_ext_info {
- unsigned int nat25_disable;
- unsigned int macclone_enable;
- unsigned int dhcp_bcst_disable;
- int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */
- unsigned char nat25_dmzMac[MACADDRLEN];
- unsigned int nat25sc_disable;
-};
-
-void nat25_db_cleanup(struct adapter *priv);
-
-#endif /* _RTW_BR_EXT_H_ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_cmd.h b/drivers/staging/rtl8188eu/include/rtw_cmd.h
index 66467f711a59..9e9f5f4af8f1 100644
--- a/drivers/staging/rtl8188eu/include/rtw_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtw_cmd.h
@@ -24,16 +24,11 @@
#include <rtw_rf.h>
#include <rtw_led.h>
-#define C2H_MEM_SZ (16*1024)
-
#include <osdep_service.h>
#include <ieee80211.h> /* <ieee80211/ieee80211.h> */
-#define FREE_CMDOBJ_SZ 128
-
#define MAX_CMDSZ 1024
#define MAX_RSPSZ 512
-#define MAX_EVTSZ 1024
#define CMDBUFF_ALIGN_SZ 512
@@ -52,32 +47,13 @@ struct cmd_priv {
struct semaphore cmd_queue_sema;
struct semaphore terminate_cmdthread_sema;
struct __queue cmd_queue;
- u8 cmd_seq;
- u8 *cmd_buf; /* shall be non-paged, and 4 bytes aligned */
- u8 *cmd_allocated_buf;
- u8 *rsp_buf; /* shall be non-paged, and 4 bytes aligned */
- u8 *rsp_allocated_buf;
- u32 cmd_issued_cnt;
- u32 cmd_done_cnt;
- u32 rsp_cnt;
u8 cmdthd_running;
struct adapter *padapter;
};
-struct evt_priv {
- struct work_struct c2h_wk;
- bool c2h_wk_alive;
- struct rtw_cbuf *c2h_queue;
- #define C2H_QUEUE_MAX_LEN 10
- atomic_t event_seq;
- u8 *evt_buf; /* shall be non-paged, and 4 bytes aligned */
- u8 *evt_allocated_buf;
- u32 evt_done_cnt;
-};
-
#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
do {\
- _rtw_init_listhead(&pcmd->list);\
+ INIT_LIST_HEAD(&pcmd->list);\
pcmd->cmdcode = code;\
pcmd->parmbuf = (u8 *)(pparm);\
pcmd->cmdsz = sizeof(*pparm);\
@@ -85,31 +61,13 @@ do {\
pcmd->rspsz = 0;\
} while (0)
-struct c2h_evt_hdr {
- u8 id:4;
- u8 plen:4;
- u8 seq;
- u8 payload[0];
-};
-
-#define c2h_evt_exist(c2h_evt) ((c2h_evt)->id || (c2h_evt)->plen)
-
u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj);
-struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv);
+struct cmd_obj *rtw_dequeue_cmd(struct __queue *queue);
void rtw_free_cmd_obj(struct cmd_obj *pcmd);
int rtw_cmd_thread(void *context);
-u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv);
-void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv);
-
-u32 rtw_init_evt_priv(struct evt_priv *pevtpriv);
-void rtw_free_evt_priv(struct evt_priv *pevtpriv);
-void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv);
-void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
-#ifdef CONFIG_88EU_P2P
-u8 p2p_protocol_wk_cmd(struct adapter *padapter, int intCmdType);
-#endif /* CONFIG_88EU_P2P */
+int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv);
enum rtw_drvextra_cmd_id {
NONE_WK_CID,
@@ -146,39 +104,6 @@ enum RFINTFS {
/*
Caller Mode: Infra, Ad-HoC(C)
-Notes: To enter USB suspend mode
-
-Command Mode
-
-*/
-struct usb_suspend_parm {
- u32 action;/* 1: sleep, 0:resume */
-};
-
-/*
-Caller Mode: Infra, Ad-HoC
-
-Notes: To join a known BSS.
-
-Command-Event Mode
-
-*/
-
-/*
-Caller Mode: Infra, Ad-Hoc
-
-Notes: To join the specified bss
-
-Command Event Mode
-
-*/
-struct joinbss_parm {
- struct wlan_bssid_ex network;
-};
-
-/*
-Caller Mode: Infra, Ad-HoC(C)
-
Notes: To disconnect the current associated BSS
Command Mode
@@ -188,17 +113,6 @@ struct disconnect_parm {
u32 deauth_timeout_ms;
};
-/*
-Caller Mode: AP, Ad-HoC(M)
-
-Notes: To create a BSS
-
-Command Mode
-*/
-struct createbss_parm {
- struct wlan_bssid_ex network;
-};
-
struct setopmode_parm {
u8 mode;
u8 rsvd[3];
@@ -329,160 +243,6 @@ struct setstapwrstate_parm {
};
/*
-Caller Mode: Any
-
-Notes: To setup the basic rate of RTL8711
-
-Command Mode
-
-*/
-struct setbasicrate_parm {
- u8 basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current basic rate
-
-Command-Rsp Mode
-
-*/
-struct getbasicrate_parm {
- u32 rsvd;
-};
-
-struct getbasicrate_rsp {
- u8 basicrates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To setup the data rate of RTL8711
-
-Command Mode
-
-*/
-struct setdatarate_parm {
- u8 mac_id;
- u8 datarates[NumRates];
-};
-
-/*
-Caller Mode: Any
-
-Notes: To read the current data rate
-
-Command-Rsp Mode
-
-*/
-struct getdatarate_parm {
- u32 rsvd;
-
-};
-struct getdatarate_rsp {
- u8 datarates[NumRates];
-};
-
-/*
-Caller Mode: Any
-AP: AP can use the info for the contents of beacon frame
-Infra: STA can use the info when sitesurveying
-Ad-HoC(M): Like AP
-Ad-HoC(C): Like STA
-
-Notes: To set the phy capability of the NIC
-
-Command Mode
-
-*/
-
-struct setphyinfo_parm {
- struct regulatory_class class_sets[NUM_REGULATORYS];
- u8 status;
-};
-
-struct getphyinfo_parm {
- u32 rsvd;
-};
-
-struct getphyinfo_rsp {
- struct regulatory_class class_sets[NUM_REGULATORYS];
- u8 status;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To set the channel/modem/band
-This command will be used when channel/modem/band is changed.
-
-Command Mode
-
-*/
-struct setphy_parm {
- u8 rfchannel;
- u8 modem;
-};
-
-/*
-Caller Mode: Any
-
-Notes: To get the current setting of channel/modem/band
-
-Command-Rsp Mode
-
-*/
-struct getphy_parm {
- u32 rsvd;
-
-};
-struct getphy_rsp {
- u8 rfchannel;
- u8 modem;
-};
-
-struct readBB_parm {
- u8 offset;
-};
-struct readBB_rsp {
- u8 value;
-};
-
-struct readTSSI_parm {
- u8 offset;
-};
-struct readTSSI_rsp {
- u8 value;
-};
-
-struct writeBB_parm {
- u8 offset;
- u8 value;
-};
-
-struct readRF_parm {
- u8 offset;
-};
-struct readRF_rsp {
- u32 value;
-};
-
-struct writeRF_parm {
- u32 offset;
- u32 value;
-};
-
-struct getrfintfs_parm {
- u8 rfintfs;
-};
-
-struct Tx_Beacon_param {
- struct wlan_bssid_ex network;
-};
-
-/*
Notes: This command is used for H2C/C2H loopback testing
mac[0] == 0
@@ -540,167 +300,6 @@ struct drvextra_cmd_parm {
unsigned char *pbuf;
};
-/*------------------- Below are used for RF/BB tunning ---------------------*/
-
-struct setantenna_parm {
- u8 tx_antset;
- u8 rx_antset;
- u8 tx_antenna;
- u8 rx_antenna;
-};
-
-struct enrateadaptive_parm {
- u32 en;
-};
-
-struct settxagctbl_parm {
- u32 txagc[MAX_RATES_LENGTH];
-};
-
-struct gettxagctbl_parm {
- u32 rsvd;
-};
-struct gettxagctbl_rsp {
- u32 txagc[MAX_RATES_LENGTH];
-};
-
-struct setagcctrl_parm {
- u32 agcctrl; /* 0: pure hw, 1: fw */
-};
-
-struct setssup_parm {
- u32 ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct getssup_parm {
- u32 rsvd;
-};
-
-struct getssup_rsp {
- u8 ss_ForceUp[MAX_RATES_LENGTH];
-};
-
-struct setssdlevel_parm {
- u8 ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct getssdlevel_parm {
- u32 rsvd;
-};
-
-struct getssdlevel_rsp {
- u8 ss_DLevel[MAX_RATES_LENGTH];
-};
-
-struct setssulevel_parm {
- u8 ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct getssulevel_parm {
- u32 rsvd;
-};
-
-struct getssulevel_rsp {
- u8 ss_ULevel[MAX_RATES_LENGTH];
-};
-
-struct setcountjudge_parm {
- u8 count_judge[MAX_RATES_LENGTH];
-};
-
-struct getcountjudge_parm {
- u32 rsvd;
-};
-
-struct getcountjudge_rsp {
- u8 count_judge[MAX_RATES_LENGTH];
-};
-
-struct setratable_parm {
- u8 ss_ForceUp[NumRates];
- u8 ss_ULevel[NumRates];
- u8 ss_DLevel[NumRates];
- u8 count_judge[NumRates];
-};
-
-struct getratable_parm {
- uint rsvd;
-};
-
-struct getratable_rsp {
- u8 ss_ForceUp[NumRates];
- u8 ss_ULevel[NumRates];
- u8 ss_DLevel[NumRates];
- u8 count_judge[NumRates];
-};
-
-/* to get TX,RX retry count */
-
-struct gettxretrycnt_parm {
- unsigned int rsvd;
-};
-
-struct gettxretrycnt_rsp {
- unsigned long tx_retrycnt;
-};
-
-struct getrxretrycnt_parm {
- unsigned int rsvd;
-};
-
-struct getrxretrycnt_rsp {
- unsigned long rx_retrycnt;
-};
-
-/* to get BCNOK,BCNERR count */
-struct getbcnokcnt_parm {
- unsigned int rsvd;
-};
-
-struct getbcnokcnt_rsp {
- unsigned long bcnokcnt;
-};
-
-struct getbcnerrcnt_parm {
- unsigned int rsvd;
-};
-
-struct getbcnerrcnt_rsp {
- unsigned long bcnerrcnt;
-};
-
-/* to get current TX power level */
-struct getcurtxpwrlevel_parm {
- unsigned int rsvd;
-};
-struct getcurtxpwrlevel_rspi {
- unsigned short tx_power;
-};
-
-struct setprobereqextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setassocreqextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setproberspextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
-struct setassocrspextraie_parm {
- unsigned char e_id;
- unsigned char ie_len;
- unsigned char ie[0];
-};
-
struct addBaReq_parm {
unsigned int tid;
u8 addr[ETH_ALEN];
@@ -718,22 +317,6 @@ struct SetChannelPlan_param {
u8 channel_plan;
};
-/*H2C Handler index: 60 */
-struct LedBlink_param {
- struct LED_871x *pLed;
-};
-
-/*H2C Handler index: 61 */
-struct SetChannelSwitch_param {
- u8 new_ch_no;
-};
-
-/*H2C Handler index: 62 */
-struct TDLSoption_param {
- u8 addr[ETH_ALEN];
- u8 option;
-};
-
#define GEN_CMD_CODE(cmd) cmd ## _CMD_
/*
@@ -747,26 +330,16 @@ Result:
*/
-#define H2C_RSP_OFFSET 512
-
#define H2C_SUCCESS 0x00
#define H2C_SUCCESS_RSP 0x01
-#define H2C_DUPLICATED 0x02
#define H2C_DROPPED 0x03
#define H2C_PARAMETERS_ERROR 0x04
#define H2C_REJECTED 0x05
-#define H2C_CMD_OVERFLOW 0x06
-#define H2C_RESERVED 0x07
-u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr);
-u8 rtw_setstandby_cmd(struct adapter *padapter, uint action);
u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
int ssid_num, struct rtw_ieee80211_channel *ch,
int ch_num);
u8 rtw_createbss_cmd(struct adapter *padapter);
-u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss,
- unsigned int sz);
-u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch);
u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key);
u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry,
u8 enqueue);
@@ -775,21 +348,6 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms,
bool enqueue);
u8 rtw_setopmode_cmd(struct adapter *padapter,
enum ndis_802_11_network_infra networktype);
-u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset);
-u8 rtw_setbasicrate_cmd(struct adapter *padapter, u8 *rateset);
-u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val);
-u8 rtw_setrfreg_cmd(struct adapter *padapter, u8 offset, u32 val);
-u8 rtw_getbbreg_cmd(struct adapter *padapter, u8 offset, u8 *pval);
-u8 rtw_getrfreg_cmd(struct adapter *padapter, u8 offset, u8 *pval);
-u8 rtw_setrfintfs_cmd(struct adapter *padapter, u8 mode);
-u8 rtw_setrttbl_cmd(struct adapter *padapter,
- struct setratable_parm *prate_table);
-u8 rtw_getrttbl_cmd(struct adapter *padapter, struct getratable_rsp *pval);
-
-u8 rtw_gettssi_cmd(struct adapter *padapter, u8 offset, u8 *pval);
-u8 rtw_setfwdig_cmd(struct adapter *padapter, u8 type);
-u8 rtw_setfwra_cmd(struct adapter *padapter, u8 type);
-
u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr);
u8 rtw_dynamic_chk_wk_cmd(struct adapter *adapter);
@@ -804,21 +362,13 @@ u8 rtw_ps_cmd(struct adapter *padapter);
u8 rtw_chk_hi_queue_cmd(struct adapter *padapter);
#endif
-u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset,
- u8 enqueue);
u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue);
-u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no);
-u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option);
-
-u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt);
-
u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf);
void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd);
void rtw_createbss_cmd_callback(struct adapter *adapt, struct cmd_obj *pcmd);
-void rtw_getbbrfreg_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
void rtw_readtssi_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
void rtw_setstaKey_cmdrsp_callback(struct adapter *adapt, struct cmd_obj *cmd);
@@ -831,158 +381,42 @@ struct _cmd_callback {
};
enum rtw_h2c_cmd {
- GEN_CMD_CODE(_Read_MACREG), /*0*/
- GEN_CMD_CODE(_Write_MACREG),
- GEN_CMD_CODE(_Read_BBREG),
- GEN_CMD_CODE(_Write_BBREG),
- GEN_CMD_CODE(_Read_RFREG),
- GEN_CMD_CODE(_Write_RFREG), /*5*/
- GEN_CMD_CODE(_Read_EEPROM),
- GEN_CMD_CODE(_Write_EEPROM),
- GEN_CMD_CODE(_Read_EFUSE),
- GEN_CMD_CODE(_Write_EFUSE),
-
- GEN_CMD_CODE(_Read_CAM), /*10*/
- GEN_CMD_CODE(_Write_CAM),
- GEN_CMD_CODE(_setBCNITV),
- GEN_CMD_CODE(_setMBIDCFG),
- GEN_CMD_CODE(_JoinBss), /*14*/
- GEN_CMD_CODE(_DisConnect), /*15*/
+ GEN_CMD_CODE(_JoinBss),
+ GEN_CMD_CODE(_DisConnect),
GEN_CMD_CODE(_CreateBss),
GEN_CMD_CODE(_SetOpMode),
- GEN_CMD_CODE(_SiteSurvey), /*18*/
+ GEN_CMD_CODE(_SiteSurvey),
GEN_CMD_CODE(_SetAuth),
-
- GEN_CMD_CODE(_SetKey), /*20*/
+ GEN_CMD_CODE(_SetKey),
GEN_CMD_CODE(_SetStaKey),
GEN_CMD_CODE(_SetAssocSta),
- GEN_CMD_CODE(_DelAssocSta),
- GEN_CMD_CODE(_SetStaPwrState),
- GEN_CMD_CODE(_SetBasicRate), /*25*/
- GEN_CMD_CODE(_GetBasicRate),
- GEN_CMD_CODE(_SetDataRate),
- GEN_CMD_CODE(_GetDataRate),
- GEN_CMD_CODE(_SetPhyInfo),
-
- GEN_CMD_CODE(_GetPhyInfo), /*30*/
- GEN_CMD_CODE(_SetPhy),
- GEN_CMD_CODE(_GetPhy),
- GEN_CMD_CODE(_readRssi),
- GEN_CMD_CODE(_readGain),
- GEN_CMD_CODE(_SetAtim), /*35*/
- GEN_CMD_CODE(_SetPwrMode),
- GEN_CMD_CODE(_JoinbssRpt),
- GEN_CMD_CODE(_SetRaTable),
- GEN_CMD_CODE(_GetRaTable),
-
- GEN_CMD_CODE(_GetCCXReport), /*40*/
- GEN_CMD_CODE(_GetDTMReport),
- GEN_CMD_CODE(_GetTXRateStatistics),
- GEN_CMD_CODE(_SetUsbSuspend),
- GEN_CMD_CODE(_SetH2cLbk),
- GEN_CMD_CODE(_AddBAReq), /*45*/
- GEN_CMD_CODE(_SetChannel), /*46*/
- GEN_CMD_CODE(_SetTxPower),
- GEN_CMD_CODE(_SwitchAntenna),
- GEN_CMD_CODE(_SetCrystalCap),
- GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/
-
- GEN_CMD_CODE(_SetSingleToneTx),/*51*/
- GEN_CMD_CODE(_SetCarrierSuppressionTx),
- GEN_CMD_CODE(_SetContinuousTx),
- GEN_CMD_CODE(_SwitchBandwidth), /*54*/
- GEN_CMD_CODE(_TX_Beacon), /*55*/
-
- GEN_CMD_CODE(_Set_MLME_EVT), /*56*/
- GEN_CMD_CODE(_Set_Drv_Extra), /*57*/
- GEN_CMD_CODE(_Set_H2C_MSG), /*58*/
-
- GEN_CMD_CODE(_SetChannelPlan), /*59*/
- GEN_CMD_CODE(_LedBlink), /*60*/
-
- GEN_CMD_CODE(_SetChannelSwitch), /*61*/
- GEN_CMD_CODE(_TDLS), /*62*/
+ GEN_CMD_CODE(_AddBAReq),
+ GEN_CMD_CODE(_SetChannel),
+ GEN_CMD_CODE(_TX_Beacon),
+ GEN_CMD_CODE(_Set_MLME_EVT),
+ GEN_CMD_CODE(_Set_Drv_Extra),
+ GEN_CMD_CODE(_SetChannelPlan),
MAX_H2CCMD
};
-#define _GetBBReg_CMD_ _Read_BBREG_CMD_
-#define _SetBBReg_CMD_ _Write_BBREG_CMD_
-#define _GetRFReg_CMD_ _Read_RFREG_CMD_
-#define _SetRFReg_CMD_ _Write_RFREG_CMD_
-
#ifdef _RTW_CMD_C_
static struct _cmd_callback rtw_cmd_callback[] = {
- {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/
- {GEN_CMD_CODE(_Write_MACREG), NULL},
- {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback},
- {GEN_CMD_CODE(_Write_BBREG), NULL},
- {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback},
- {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/
- {GEN_CMD_CODE(_Read_EEPROM), NULL},
- {GEN_CMD_CODE(_Write_EEPROM), NULL},
- {GEN_CMD_CODE(_Read_EFUSE), NULL},
- {GEN_CMD_CODE(_Write_EFUSE), NULL},
-
- {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/
- {GEN_CMD_CODE(_Write_CAM), NULL},
- {GEN_CMD_CODE(_setBCNITV), NULL},
- {GEN_CMD_CODE(_setMBIDCFG), NULL},
- {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/
- {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/
+ {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback},
+ {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback},
{GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback},
{GEN_CMD_CODE(_SetOpMode), NULL},
- {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/
+ {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback},
{GEN_CMD_CODE(_SetAuth), NULL},
-
- {GEN_CMD_CODE(_SetKey), NULL}, /*20*/
+ {GEN_CMD_CODE(_SetKey), NULL},
{GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback},
{GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback},
- {GEN_CMD_CODE(_DelAssocSta), NULL},
- {GEN_CMD_CODE(_SetStaPwrState), NULL},
- {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/
- {GEN_CMD_CODE(_GetBasicRate), NULL},
- {GEN_CMD_CODE(_SetDataRate), NULL},
- {GEN_CMD_CODE(_GetDataRate), NULL},
- {GEN_CMD_CODE(_SetPhyInfo), NULL},
-
- {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/
- {GEN_CMD_CODE(_SetPhy), NULL},
- {GEN_CMD_CODE(_GetPhy), NULL},
- {GEN_CMD_CODE(_readRssi), NULL},
- {GEN_CMD_CODE(_readGain), NULL},
- {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/
- {GEN_CMD_CODE(_SetPwrMode), NULL},
- {GEN_CMD_CODE(_JoinbssRpt), NULL},
- {GEN_CMD_CODE(_SetRaTable), NULL},
- {GEN_CMD_CODE(_GetRaTable), NULL},
-
- {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/
- {GEN_CMD_CODE(_GetDTMReport), NULL},
- {GEN_CMD_CODE(_GetTXRateStatistics), NULL},
- {GEN_CMD_CODE(_SetUsbSuspend), NULL},
- {GEN_CMD_CODE(_SetH2cLbk), NULL},
- {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/
- {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/
- {GEN_CMD_CODE(_SetTxPower), NULL},
- {GEN_CMD_CODE(_SwitchAntenna), NULL},
- {GEN_CMD_CODE(_SetCrystalCap), NULL},
- {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/
-
- {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/
- {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL},
- {GEN_CMD_CODE(_SetContinuousTx), NULL},
- {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/
- {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/
-
- {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/
- {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/
- {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/
- {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/
- {GEN_CMD_CODE(_LedBlink), NULL},/*60*/
-
- {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/
- {GEN_CMD_CODE(_TDLS), NULL},/*62*/
+ {GEN_CMD_CODE(_AddBAReq), NULL},
+ {GEN_CMD_CODE(_SetChannel), NULL},
+ {GEN_CMD_CODE(_TX_Beacon), NULL},
+ {GEN_CMD_CODE(_Set_MLME_EVT), NULL},
+ {GEN_CMD_CODE(_Set_Drv_Extra), NULL},
+ {GEN_CMD_CODE(_SetChannelPlan), NULL},
};
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h
index ae05141f5ddf..a38616e3cad2 100644
--- a/drivers/staging/rtl8188eu/include/rtw_debug.h
+++ b/drivers/staging/rtl8188eu/include/rtw_debug.h
@@ -23,7 +23,7 @@
#include <osdep_service.h>
#include <drv_types.h>
-
+#define DRIVERVERSION "v4.1.4_6773.20130222"
#define _drv_always_ 1
#define _drv_emerg_ 2
#define _drv_alert_ 3
diff --git a/drivers/staging/rtl8188eu/include/rtw_efuse.h b/drivers/staging/rtl8188eu/include/rtw_efuse.h
index df51355e0f32..720f9ea24d52 100644
--- a/drivers/staging/rtl8188eu/include/rtw_efuse.h
+++ b/drivers/staging/rtl8188eu/include/rtw_efuse.h
@@ -99,52 +99,21 @@ struct efuse_hal {
u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN];
};
-/*------------------------Export global variable----------------------------*/
-extern u8 fakeEfuseBank;
-extern u32 fakeEfuseUsedBytes;
-extern u8 fakeEfuseContent[];
-extern u8 fakeEfuseInitMap[];
-extern u8 fakeEfuseModifiedMap[];
-
-extern u32 BTEfuseUsedBytes;
-extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
-extern u8 BTEfuseInitMap[];
-extern u8 BTEfuseModifiedMap[];
-
-extern u32 fakeBTEfuseUsedBytes;
-extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
-extern u8 fakeBTEfuseInitMap[];
-extern u8 fakeBTEfuseModifiedMap[];
-/*------------------------Export global variable----------------------------*/
-
-u8 efuse_GetCurrentSize(struct adapter *adapter, u16 *size);
-u16 efuse_GetMaxSize(struct adapter *adapter);
-u8 rtw_efuse_access(struct adapter *adapter, u8 read, u16 start_addr,
- u16 cnts, u8 *data);
-u8 rtw_efuse_map_read(struct adapter *adapter, u16 addr, u16 cnts, u8 *data);
-u8 rtw_efuse_map_write(struct adapter *adapter, u16 addr, u16 cnts, u8 *data);
-u8 rtw_BT_efuse_map_read(struct adapter *adapter, u16 addr,
- u16 cnts, u8 *data);
-u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
- u16 cnts, u8 *data);
-u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
+u16 Efuse_GetCurrentSize(struct adapter *adapter);
u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
- void *out, bool bPseudoTest);
-u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
-u8 efuse_OneByteWrite(struct adapter *adapter, u16 addr, u8 data, bool test);
+ void *out);
+u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data);
+u8 efuse_OneByteWrite(struct adapter *adapter, u16 addr, u8 data);
+void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset,
+ u16 _size_byte, u8 *pbuf);
void Efuse_PowerSwitch(struct adapter *adapt, u8 bWrite, u8 PwrState);
-int Efuse_PgPacketRead(struct adapter *adapt, u8 offset, u8 *data, bool test);
-int Efuse_PgPacketWrite(struct adapter *adapter, u8 offset, u8 word, u8 *data,
- bool test);
+int Efuse_PgPacketRead(struct adapter *adapt, u8 offset, u8 *data);
+bool Efuse_PgPacketWrite(struct adapter *adapter, u8 offset, u8 word, u8 *data);
void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata);
u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
- u8 word_en, u8 *data, bool test);
-
-u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
-void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
+ u8 word_en, u8 *data);
+void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype);
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_io.h b/drivers/staging/rtl8188eu/include/rtw_io.h
deleted file mode 100644
index e8790f8f913e..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_io.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
-#ifndef _RTW_IO_H_
-#define _RTW_IO_H_
-
-#include <osdep_service.h>
-#include <osdep_intf.h>
-
-#include <asm/byteorder.h>
-#include <linux/semaphore.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-
-#include <linux/usb.h>
-#include <linux/usb/ch9.h>
-
-#define rtw_usb_buffer_alloc(dev, size, dma) \
- usb_alloc_coherent((dev), (size), (in_interrupt() ? \
- GFP_ATOMIC : GFP_KERNEL), (dma))
-#define rtw_usb_buffer_free(dev, size, addr, dma) \
- usb_free_coherent((dev), (size), (addr), (dma))
-
-#define NUM_IOREQ 8
-
-#define MAX_PROT_SZ (64-16)
-
-#define _IOREADY 0
-#define _IO_WAIT_COMPLETE 1
-#define _IO_WAIT_RSP 2
-
-/* IO COMMAND TYPE */
-#define _IOSZ_MASK_ (0x7F)
-#define _IO_WRITE_ BIT(7)
-#define _IO_FIXED_ BIT(8)
-#define _IO_BURST_ BIT(9)
-#define _IO_BYTE_ BIT(10)
-#define _IO_HW_ BIT(11)
-#define _IO_WORD_ BIT(12)
-#define _IO_SYNC_ BIT(13)
-#define _IO_CMDMASK_ (0x1F80)
-
-/*
- For prompt mode accessing, caller shall free io_req
- Otherwise, io_handler will free io_req
-*/
-
-/* IO STATUS TYPE */
-#define _IO_ERR_ BIT(2)
-#define _IO_SUCCESS_ BIT(1)
-#define _IO_DONE_ BIT(0)
-
-#define IO_RD32 (_IO_SYNC_ | _IO_WORD_)
-#define IO_RD16 (_IO_SYNC_ | _IO_HW_)
-#define IO_RD8 (_IO_SYNC_ | _IO_BYTE_)
-
-#define IO_RD32_ASYNC (_IO_WORD_)
-#define IO_RD16_ASYNC (_IO_HW_)
-#define IO_RD8_ASYNC (_IO_BYTE_)
-
-#define IO_WR32 (_IO_WRITE_ | _IO_SYNC_ | _IO_WORD_)
-#define IO_WR16 (_IO_WRITE_ | _IO_SYNC_ | _IO_HW_)
-#define IO_WR8 (_IO_WRITE_ | _IO_SYNC_ | _IO_BYTE_)
-
-#define IO_WR32_ASYNC (_IO_WRITE_ | _IO_WORD_)
-#define IO_WR16_ASYNC (_IO_WRITE_ | _IO_HW_)
-#define IO_WR8_ASYNC (_IO_WRITE_ | _IO_BYTE_)
-
-/*
- Only Sync. burst accessing is provided.
-*/
-
-#define IO_WR_BURST(x) \
- (_IO_WRITE_ | _IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_))
-#define IO_RD_BURST(x) \
- (_IO_SYNC_ | _IO_BURST_ | ((x) & _IOSZ_MASK_))
-
-/* below is for the intf_option bit defition... */
-
-#define _INTF_ASYNC_ BIT(0) /* support async io */
-
-struct intf_priv;
-struct intf_hdl;
-
-struct _io_ops {
- u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
- u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
- u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
- int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
- int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length,
- u8 *pdata);
- int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
- int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
- int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
- void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- u8 *pmem);
- void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- u8 *pmem);
- u32 (*_read_interrupt)(struct intf_hdl *pintfhdl, u32 addr);
- u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- u8 *pmem);
- u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt,
- u8 *pmem);
- u32 (*_write_scsi)(struct intf_hdl *pintfhdl, u32 cnt, u8 *pmem);
- void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
- void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
-};
-
-struct io_req {
- struct list_head list;
- u32 addr;
- u32 val;
- u32 command;
- u32 status;
- u8 *pbuf;
- struct semaphore sema;
-
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req, u8 *cnxt);
- u8 *cnxt;
-};
-
-struct intf_hdl {
- struct adapter *padapter;
- struct dvobj_priv *pintf_dev;
- struct _io_ops io_ops;
-};
-
-struct reg_protocol_rd {
-#ifdef __LITTLE_ENDIAN
- /* DW1 */
- u32 NumOfTrans:4;
- u32 Reserved1:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 ByteCount:7;
- u32 WriteEnable:1; /* 0:read, 1:write */
- u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */
- u32 BurstMode:1;
- u32 Byte1Access:1;
- u32 Byte2Access:1;
- u32 Byte4Access:1;
- u32 Reserved3:3;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
- /* DW4 */
- /* u32 Value; */
-#else
-/* DW1 */
- u32 Reserved1:4;
- u32 NumOfTrans:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 WriteEnable:1;
- u32 ByteCount:7;
- u32 Reserved3:3;
- u32 Byte4Access:1;
-
- u32 Byte2Access:1;
- u32 Byte1Access:1;
- u32 BurstMode:1;
- u32 FixOrContinuous:1;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
-
- /* DW4 */
-#endif
-};
-
-struct reg_protocol_wt {
-#ifdef __LITTLE_ENDIAN
- /* DW1 */
- u32 NumOfTrans:4;
- u32 Reserved1:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 ByteCount:7;
- u32 WriteEnable:1; /* 0:read, 1:write */
- u32 FixOrContinuous:1; /* 0:continuous, 1: Fix */
- u32 BurstMode:1;
- u32 Byte1Access:1;
- u32 Byte2Access:1;
- u32 Byte4Access:1;
- u32 Reserved3:3;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
- /* DW4 */
- u32 Value;
-#else
- /* DW1 */
- u32 Reserved1:4;
- u32 NumOfTrans:4;
- u32 Reserved2:24;
- /* DW2 */
- u32 WriteEnable:1;
- u32 ByteCount:7;
- u32 Reserved3:3;
- u32 Byte4Access:1;
- u32 Byte2Access:1;
- u32 Byte1Access:1;
- u32 BurstMode:1;
- u32 FixOrContinuous:1;
- u32 Reserved4:16;
- /* DW3 */
- u32 BusAddress;
- /* DW4 */
- u32 Value;
-#endif
-};
-
-/*
-Below is the data structure used by _io_handler
-*/
-
-struct io_priv {
- struct adapter *padapter;
- struct intf_hdl intf;
-};
-
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
-void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-void _rtw_read_port_cancel(struct adapter *adapter);
-
-int _rtw_write8(struct adapter *adapter, u32 addr, u8 val);
-int _rtw_write16(struct adapter *adapter, u32 addr, u16 val);
-int _rtw_write32(struct adapter *adapter, u32 addr, u32 val);
-int _rtw_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata);
-
-int _rtw_write8_async(struct adapter *adapter, u32 addr, u8 val);
-int _rtw_write16_async(struct adapter *adapter, u32 addr, u16 val);
-int _rtw_write32_async(struct adapter *adapter, u32 addr, u32 val);
-
-void _rtw_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
- u8 *pmem, int timeout_ms);
-void _rtw_write_port_cancel(struct adapter *adapter);
-
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
-#define rtw_read_mem(adapter, addr, cnt, mem) \
- _rtw_read_mem((adapter), (addr), (cnt), (mem))
-#define rtw_read_port(adapter, addr, cnt, mem) \
- _rtw_read_port((adapter), (addr), (cnt), (mem))
-#define rtw_read_port_cancel(adapter) _rtw_read_port_cancel((adapter))
-
-#define rtw_write8(adapter, addr, val) \
- _rtw_write8((adapter), (addr), (val))
-#define rtw_write16(adapter, addr, val) \
- _rtw_write16((adapter), (addr), (val))
-#define rtw_write32(adapter, addr, val) \
- _rtw_write32((adapter), (addr), (val))
-#define rtw_writeN(adapter, addr, length, data) \
- _rtw_writeN((adapter), (addr), (length), (data))
-#define rtw_write8_async(adapter, addr, val) \
- _rtw_write8_async((adapter), (addr), (val))
-#define rtw_write16_async(adapter, addr, val) \
- _rtw_write16_async((adapter), (addr), (val))
-#define rtw_write32_async(adapter, addr, val) \
- _rtw_write32_async((adapter), (addr), (val))
-#define rtw_write_mem(adapter, addr, cnt, mem) \
- _rtw_write_mem((adapter), (addr), (cnt), (mem))
-#define rtw_write_port(adapter, addr, cnt, mem) \
- _rtw_write_port((adapter), (addr), (cnt), (mem))
-#define rtw_write_port_and_wait(adapter, addr, cnt, mem, timeout_ms) \
- _rtw_write_port_and_wait((adapter), (addr), (cnt), (mem), (timeout_ms))
-#define rtw_write_port_cancel(adapter) _rtw_write_port_cancel((adapter))
-
-void rtw_write_scsi(struct adapter *adapter, u32 cnt, u8 *pmem);
-
-/* ioreq */
-void ioreq_read8(struct adapter *adapter, u32 addr, u8 *pval);
-void ioreq_read16(struct adapter *adapter, u32 addr, u16 *pval);
-void ioreq_read32(struct adapter *adapter, u32 addr, u32 *pval);
-void ioreq_write8(struct adapter *adapter, u32 addr, u8 val);
-void ioreq_write16(struct adapter *adapter, u32 addr, u16 val);
-void ioreq_write32(struct adapter *adapter, u32 addr, u32 val);
-
-uint async_read8(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-uint async_read16(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-uint async_read32(struct adapter *adapter, u32 addr, u8 *pbuff,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-
-void async_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-void async_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-
-void async_write8(struct adapter *adapter, u32 addr, u8 val,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-void async_write16(struct adapter *adapter, u32 addr, u16 val,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-void async_write32(struct adapter *adapter, u32 addr, u32 val,
- void (*_async_io_callback)(struct adapter *padater,
- struct io_req *pio_req,
- u8 *cnxt), u8 *cnxt);
-
-void async_write_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-void async_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
-
-int rtw_init_io_priv(struct adapter *padapter,
- void (*set_intf_ops)(struct _io_ops *pops));
-
-void dev_power_down(struct adapter *Adapter, u8 bpwrup);
-
-#endif /* _RTL8711_IO_H_ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h b/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h
index 187fe1f32478..fa9d655eaab9 100644
--- a/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h
+++ b/drivers/staging/rtl8188eu/include/rtw_ioctl_set.h
@@ -25,7 +25,6 @@
typedef u8 NDIS_802_11_PMKID_VALUE[16];
-u8 rtw_set_802_11_add_key(struct adapter *adapt, struct ndis_802_11_key *key);
u8 rtw_set_802_11_authentication_mode(struct adapter *adapt,
enum ndis_802_11_auth_mode authmode);
u8 rtw_set_802_11_bssid(struct adapter *adapter, u8 *bssid);
@@ -36,15 +35,8 @@ u8 rtw_set_802_11_bssid_list_scan(struct adapter *adapter,
int ssid_max_num);
u8 rtw_set_802_11_infrastructure_mode(struct adapter *adapter,
enum ndis_802_11_network_infra type);
-u8 rtw_set_802_11_remove_wep(struct adapter *adapter, u32 keyindex);
u8 rtw_set_802_11_ssid(struct adapter *adapt, struct ndis_802_11_ssid *ssid);
-u8 rtw_set_802_11_remove_key(struct adapter *adapt,
- struct ndis_802_11_remove_key *key);
-u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid);
u16 rtw_get_cur_max_rate(struct adapter *adapter);
-int rtw_set_scan_mode(struct adapter *adapter, enum rt_scan_type scan_mode);
-int rtw_set_channel_plan(struct adapter *adapter, u8 channel_plan);
int rtw_set_country(struct adapter *adapter, const char *country_code);
-int rtw_change_ifname(struct adapter *padapter, const char *ifname);
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h
index ec0c6cb12057..80bfd063dd8d 100644
--- a/drivers/staging/rtl8188eu/include/rtw_iol.h
+++ b/drivers/staging/rtl8188eu/include/rtw_iol.h
@@ -63,8 +63,6 @@ void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead,
int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr,
u8 value, u8 mask);
-int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr,
- u16 value, u16 mask);
int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr,
u32 value, u32 mask);
int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path,
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h
index 45c22efe93fe..8d83f7ceda76 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h
@@ -436,8 +436,6 @@ void indicate_wx_scan_complete_event(struct adapter *padapter);
void rtw_indicate_wx_assoc_event(struct adapter *padapter);
void rtw_indicate_wx_disassoc_event(struct adapter *padapter);
int event_thread(void *context);
-void rtw_join_timeout_handler(void *FunctionContext);
-void _rtw_scan_timeout_handler(void *FunctionContext);
void rtw_free_network_queue(struct adapter *adapter, u8 isfreeall);
int rtw_init_mlme_priv(struct adapter *adapter);
void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv);
@@ -553,47 +551,27 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter);
void rtw_get_encrypt_decrypt_from_registrypriv(struct adapter *adapter);
-void _rtw_join_timeout_handler(struct adapter *adapter);
-void rtw_scan_timeout_handler(struct adapter *adapter);
+void _rtw_join_timeout_handler(void *function_context);
+void rtw_scan_timeout_handler(void *function_context);
-void rtw_dynamic_check_timer_handlder(struct adapter *adapter);
+void rtw_dynamic_check_timer_handlder(void *function_context);
#define rtw_is_scan_deny(adapter) false
#define rtw_clear_scan_deny(adapter) do {} while (0)
#define rtw_set_scan_deny_timer_hdl(adapter) do {} while (0)
#define rtw_set_scan_deny(adapter, ms) do {} while (0)
-
-int _rtw_init_mlme_priv(struct adapter *padapter);
-
void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv);
-void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv);
-
-int _rtw_enqueue_network(struct __queue *queue, struct wlan_network *pnetwork);
-
-struct wlan_network *_rtw_dequeue_network(struct __queue *queue);
-
struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv);
-
-void _rtw_free_network(struct mlme_priv *pmlmepriv,
- struct wlan_network *pnetwork, u8 isfreeall);
void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
struct wlan_network *pnetwork);
-
-struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr);
-
-void _rtw_free_network_queue(struct adapter *padapter, u8 isfreeall);
-
int rtw_if_up(struct adapter *padapter);
-
u8 *rtw_get_capability_from_ie(u8 *ie);
-u8 *rtw_get_timestampe_from_ie(u8 *ie);
u8 *rtw_get_beacon_interval_from_ie(u8 *ie);
-
void rtw_joinbss_reset(struct adapter *padapter);
unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie,
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
index 09e2a3980ea7..d699ca19ef16 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
@@ -565,18 +565,6 @@ s32 dump_mgntframe_and_wait(struct adapter *padapter,
s32 dump_mgntframe_and_wait_ack(struct adapter *padapter,
struct xmit_frame *pmgntframe);
-#ifdef CONFIG_88EU_P2P
-void issue_probersp_p2p(struct adapter *padapter, unsigned char *da);
-void issue_p2p_provision_request(struct adapter *padapter, u8 *pssid,
- u8 ussidlen, u8 *pdev_raddr);
-void issue_p2p_GO_request(struct adapter *padapter, u8 *raddr);
-void issue_probereq_p2p(struct adapter *padapter, u8 *da);
-int issue_probereq_p2p_ex(struct adapter *adapter, u8 *da, int try_cnt,
- int wait_ms);
-void issue_p2p_invitation_response(struct adapter *padapter, u8 *raddr,
- u8 dialogToken, u8 success);
-void issue_p2p_invitation_request(struct adapter *padapter, u8 *raddr);
-#endif /* CONFIG_88EU_P2P */
void issue_beacon(struct adapter *padapter, int timeout_ms);
void issue_probersp(struct adapter *padapter, unsigned char *da,
u8 is_valid_p2p_probereq);
@@ -658,9 +646,9 @@ void mlmeext_sta_add_event_callback(struct adapter *padapter,
void linked_status_chk(struct adapter *padapter);
-void survey_timer_hdl (struct adapter *padapter);
-void link_timer_hdl (struct adapter *padapter);
-void addba_timer_hdl(struct sta_info *psta);
+void survey_timer_hdl (void *function_context);
+void link_timer_hdl (void *funtion_context);
+void addba_timer_hdl(void *function_context);
#define set_survey_timer(mlmeext, ms) \
do { \
@@ -720,78 +708,21 @@ u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf);
#ifdef _RTW_CMD_C_
static struct cmd_hdl wlancmds[] = {
- GEN_DRV_CMD_HANDLER(0, NULL) /*0*/
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_DRV_CMD_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*10*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/
+ GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), join_cmd_hdl)
GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl)
- GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl)
+ GEN_MLME_EXT_HANDLER(sizeof (struct wlan_bssid_ex), createbss_hdl)
GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl)
- GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm),
- sitesurvey_cmd_hdl) /*18*/
+ GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl)
GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl)
- GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/
+ GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl)
GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl)
GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/
- GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL)
- GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*40*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl)
- GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL) /*50*/
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(0, NULL)
- GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param),
- tx_beacon_hdl) /*55*/
-
- GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/
- GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/
-
- GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/
- GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param),
- set_chplan_hdl) /*59*/
- GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param),
- led_blink_hdl) /*60*/
-
- GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param),
- set_csa_hdl) /*61*/
- GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param),
- tdls_hdl) /*62*/
+ GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl)
+ GEN_MLME_EXT_HANDLER(sizeof(struct wlan_bssid_ex), tx_beacon_hdl)
+ GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl)
+ GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl)
+ GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl)
};
#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_mp.h b/drivers/staging/rtl8188eu/include/rtw_mp.h
deleted file mode 100644
index ffa299b8a6cb..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_mp.h
+++ /dev/null
@@ -1,495 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef _RTW_MP_H_
-#define _RTW_MP_H_
-
-/* 00 - Success */
-/* 11 - Error */
-#define STATUS_SUCCESS (0x00000000L)
-#define STATUS_PENDING (0x00000103L)
-
-#define STATUS_UNSUCCESSFUL (0xC0000001L)
-#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL)
-#define STATUS_NOT_SUPPORTED (0xC00000BBL)
-
-#define NDIS_STATUS_SUCCESS ((int)STATUS_SUCCESS)
-#define NDIS_STATUS_PENDING ((int)STATUS_PENDING)
-#define NDIS_STATUS_NOT_RECOGNIZED ((int)0x00010001L)
-#define NDIS_STATUS_NOT_COPIED ((int)0x00010002L)
-#define NDIS_STATUS_NOT_ACCEPTED ((int)0x00010003L)
-#define NDIS_STATUS_CALL_ACTIVE ((int)0x00010007L)
-
-#define NDIS_STATUS_FAILURE ((int)STATUS_UNSUCCESSFUL)
-#define NDIS_STATUS_RESOURCES ((int)STATUS_INSUFFICIENT_RESOURCES)
-#define NDIS_STATUS_CLOSING ((int)0xC0010002L)
-#define NDIS_STATUS_BAD_VERSION ((int)0xC0010004L)
-#define NDIS_STATUS_BAD_CHARACTERISTICS ((int)0xC0010005L)
-#define NDIS_STATUS_ADAPTER_NOT_FOUND ((int)0xC0010006L)
-#define NDIS_STATUS_OPEN_FAILED ((int)0xC0010007L)
-#define NDIS_STATUS_DEVICE_FAILED ((int)0xC0010008L)
-#define NDIS_STATUS_MULTICAST_FULL ((int)0xC0010009L)
-#define NDIS_STATUS_MULTICAST_EXISTS ((int)0xC001000AL)
-#define NDIS_STATUS_MULTICAST_NOT_FOUND ((int)0xC001000BL)
-#define NDIS_STATUS_REQUEST_ABORTED ((int)0xC001000CL)
-#define NDIS_STATUS_RESET_IN_PROGRESS ((int)0xC001000DL)
-#define NDIS_STATUS_CLOSING_INDICATING ((int)0xC001000EL)
-#define NDIS_STATUS_NOT_SUPPORTED ((int)STATUS_NOT_SUPPORTED)
-#define NDIS_STATUS_INVALID_PACKET ((int)0xC001000FL)
-#define NDIS_STATUS_OPEN_LIST_FULL ((int)0xC0010010L)
-#define NDIS_STATUS_ADAPTER_NOT_READY ((int)0xC0010011L)
-#define NDIS_STATUS_ADAPTER_NOT_OPEN ((int)0xC0010012L)
-#define NDIS_STATUS_NOT_INDICATING ((int)0xC0010013L)
-#define NDIS_STATUS_INVALID_LENGTH ((int)0xC0010014L)
-#define NDIS_STATUS_INVALID_DATA ((int)0xC0010015L)
-#define NDIS_STATUS_BUFFER_TOO_SHORT ((int)0xC0010016L)
-#define NDIS_STATUS_INVALID_OID ((int)0xC0010017L)
-#define NDIS_STATUS_ADAPTER_REMOVED ((int)0xC0010018L)
-#define NDIS_STATUS_UNSUPPORTED_MEDIA ((int)0xC0010019L)
-#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((int)0xC001001AL)
-#define NDIS_STATUS_FILE_NOT_FOUND ((int)0xC001001BL)
-#define NDIS_STATUS_ERROR_READING_FILE ((int)0xC001001CL)
-#define NDIS_STATUS_ALREADY_MAPPED ((int)0xC001001DL)
-#define NDIS_STATUS_RESOURCE_CONFLICT ((int)0xC001001EL)
-#define NDIS_STATUS_NO_CABLE ((int)0xC001001FL)
-
-#define NDIS_STATUS_INVALID_SAP ((int)0xC0010020L)
-#define NDIS_STATUS_SAP_IN_USE ((int)0xC0010021L)
-#define NDIS_STATUS_INVALID_ADDRESS ((int)0xC0010022L)
-#define NDIS_STATUS_VC_NOT_ACTIVATED ((int)0xC0010023L)
-#define NDIS_STATUS_DEST_OUT_OF_ORDER ((int)0xC0010024L) /*cause 27*/
-#define NDIS_STATUS_VC_NOT_AVAILABLE ((int)0xC0010025L) /*cause 35,45 */
-#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((int)0xC0010026L) /*cause 37*/
-#define NDIS_STATUS_INCOMPATABLE_QOS ((int)0xC0010027L) /*cause 49*/
-#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((int)0xC0010028L) /*cause 93*/
-#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((int)0xC0010029L) /*cause 3 */
-
-enum antenna_path {
- ANTENNA_NONE = 0x00,
- ANTENNA_D,
- ANTENNA_C,
- ANTENNA_CD,
- ANTENNA_B,
- ANTENNA_BD,
- ANTENNA_BC,
- ANTENNA_BCD,
- ANTENNA_A,
- ANTENNA_AD,
- ANTENNA_AC,
- ANTENNA_ACD,
- ANTENNA_AB,
- ANTENNA_ABD,
- ANTENNA_ABC,
- ANTENNA_ABCD
-};
-
-
-#define MAX_MP_XMITBUF_SZ 2048
-#define NR_MP_XMITFRAME 8
-
-struct mp_xmit_frame {
- struct list_head list;
- struct pkt_attrib attrib;
- struct sk_buff *pkt;
- int frame_tag;
- struct adapter *padapter;
- struct urb *pxmit_urb[8];
- /* insert urb, irp, and irpcnt info below... */
- u8 *mem_addr;
- u32 sz[8];
- u8 bpending[8];
- int ac_tag[8];
- int last[8];
- uint irpcnt;
- uint fragcnt;
- uint mem[(MAX_MP_XMITBUF_SZ >> 2)];
-};
-
-struct mp_wiparam {
- u32 bcompleted;
- u32 act_type;
- u32 io_offset;
- u32 io_value;
-};
-
-typedef void(*wi_act_func)(void *padapter);
-
-struct mp_tx {
- u8 stop;
- u32 count, sended;
- u8 payload;
- struct pkt_attrib attrib;
- struct tx_desc desc;
- u8 *pallocated_buf;
- u8 *buf;
- u32 buf_size, write_size;
- void *PktTxThread;
-};
-
-#include <Hal8188EPhyCfg.h>
-
-#define MP_MAX_LINES 1000
-#define MP_MAX_LINES_BYTES 256
-
-typedef void (*MPT_WORK_ITEM_HANDLER)(void *Adapter);
-
-struct mpt_context {
- /* Indicate if we have started Mass Production Test. */
- bool bMassProdTest;
-
- /* Indicate if the driver is unloading or unloaded. */
- bool bMptDrvUnload;
-
- struct semaphore MPh2c_Sema;
- struct timer_list MPh2c_timeout_timer;
-/* Event used to sync H2c for BT control */
-
- bool MptH2cRspEvent;
- bool MptBtC2hEvent;
- bool bMPh2c_timeout;
-
- /* 8190 PCI does not support NDIS_WORK_ITEM. */
- /* Work Item for Mass Production Test. */
- /* Event used to sync the case unloading driver and MptWorkItem
- * is still in progress. */
- /* Indicate a MptWorkItem is scheduled and not yet finished. */
- bool bMptWorkItemInProgress;
- /* An instance which implements function and context of MptWorkItem. */
- MPT_WORK_ITEM_HANDLER CurrMptAct;
-
- /* 1=Start, 0=Stop from UI. */
- u32 MptTestStart;
- /* _TEST_MODE, defined in MPT_Req2.h */
- u32 MptTestItem;
- /* Variable needed in each implementation of CurrMptAct. */
- u32 MptActType; /* Type of action performed in CurrMptAct. */
- /* The Offset of IO operation is depend of MptActType. */
- u32 MptIoOffset;
- /* The Value of IO operation is depend of MptActType. */
- u32 MptIoValue;
- /* The RfPath of IO operation is depend of MptActType. */
- u32 MptRfPath;
-
- enum wireless_mode MptWirelessModeToSw; /* Wireless mode to switch. */
- u8 MptChannelToSw; /* Channel to switch. */
- u8 MptInitGainToSet; /* Initial gain to set. */
- u32 MptBandWidth; /* bandwidth to switch. */
- u32 MptRateIndex; /* rate index. */
- /* Register value kept for Single Carrier Tx test. */
- u8 btMpCckTxPower;
- /* Register value kept for Single Carrier Tx test. */
- u8 btMpOfdmTxPower;
- /* For MP Tx Power index */
- u8 TxPwrLevel[2]; /* rf-A, rf-B */
-
- /* Content of RCR Regsiter for Mass Production Test. */
- u32 MptRCR;
- /* true if we only receive packets with specific pattern. */
- bool bMptFilterPattern;
- /* Rx OK count, statistics used in Mass Production Test. */
- u32 MptRxOkCnt;
- /* Rx CRC32 error count, statistics used in Mass Production Test. */
- u32 MptRxCrcErrCnt;
-
- bool bCckContTx; /* true if we are in CCK Continuous Tx test. */
- bool bOfdmContTx; /* true if we are in OFDM Continuous Tx test. */
- bool bStartContTx; /* true if we have start Continuous Tx test. */
- /* true if we are in Single Carrier Tx test. */
- bool bSingleCarrier;
- /* true if we are in Carrier Suppression Tx Test. */
- bool bCarrierSuppression;
- /* true if we are in Single Tone Tx test. */
- bool bSingleTone;
-
- /* ACK counter asked by K.Y.. */
- bool bMptEnableAckCounter;
- u32 MptAckCounter;
-
- u8 APK_bound[2]; /* for APK path A/path B */
- bool bMptIndexEven;
-
- u8 backup0xc50;
- u8 backup0xc58;
- u8 backup0xc30;
- u8 backup0x52_RF_A;
- u8 backup0x52_RF_B;
-
- u8 h2cReqNum;
- u8 c2hBuf[20];
-
- u8 btInBuf[100];
- u32 mptOutLen;
- u8 mptOutBuf[100];
-};
-
-enum {
- WRITE_REG = 1,
- READ_REG,
- WRITE_RF,
- READ_RF,
- MP_START,
- MP_STOP,
- MP_RATE,
- MP_CHANNEL,
- MP_BANDWIDTH,
- MP_TXPOWER,
- MP_ANT_TX,
- MP_ANT_RX,
- MP_CTX,
- MP_QUERY,
- MP_ARX,
- MP_PSD,
- MP_PWRTRK,
- MP_THER,
- MP_IOCTL,
- EFUSE_GET,
- EFUSE_SET,
- MP_RESET_STATS,
- MP_DUMP,
- MP_PHYPARA,
- MP_SetRFPathSwh,
- MP_QueryDrvStats,
- MP_SetBT,
- CTA_TEST,
- MP_NULL,
-};
-
-struct mp_priv {
- struct adapter *papdater;
-
- /* Testing Flag */
- /* 0 for normal type packet, 1 for loopback packet (16bytes TXCMD) */
- u32 mode;
-
- u32 prev_fw_state;
-
- /* OID cmd handler */
- struct mp_wiparam workparam;
-
- /* Tx Section */
- u8 TID;
- u32 tx_pktcount;
- struct mp_tx tx;
-
- /* Rx Section */
- u32 rx_pktcount;
- u32 rx_crcerrpktcount;
- u32 rx_pktloss;
-
- struct recv_stat rxstat;
-
- /* RF/BB relative */
- u8 channel;
- u8 bandwidth;
- u8 prime_channel_offset;
- u8 txpoweridx;
- u8 txpoweridx_b;
- u8 rateidx;
- u32 preamble;
- u32 CrystalCap;
-
- u16 antenna_tx;
- u16 antenna_rx;
-
- u8 check_mp_pkt;
-
- u8 bSetTxPower;
-
- struct wlan_network mp_network;
- unsigned char network_macaddr[ETH_ALEN];
-
- u8 *pallocated_mp_xmitframe_buf;
- u8 *pmp_xmtframe_buf;
- struct __queue free_mp_xmitqueue;
- u32 free_mp_xmitframe_cnt;
-
- struct mpt_context MptCtx;
-};
-
-struct iocmd_struct {
- u8 cmdclass;
- u16 value;
- u8 index;
-};
-
-struct rf_reg_param {
- u32 path;
- u32 offset;
- u32 value;
-};
-
-struct bb_reg_param {
- u32 offset;
- u32 value;
-};
-/* */
-
-#define LOWER true
-#define RAISE false
-
-/* Hardware Registers */
-#define BB_REG_BASE_ADDR 0x800
-
-/* MP variables */
-enum mp_mode_{
- MP_OFF,
- MP_ON,
- MP_ERR,
- MP_CONTINUOUS_TX,
- MP_SINGLE_CARRIER_TX,
- MP_CARRIER_SUPPRISSION_TX,
- MP_SINGLE_TONE_TX,
- MP_PACKET_TX,
- MP_PACKET_RX
-};
-
-#define MAX_RF_PATH_NUMS RF_PATH_MAX
-
-extern u8 mpdatarate[NumRates];
-
-/* MP set force data rate base on the definition. */
-enum mpt_rate_index {
- /* CCK rate. */
- MPT_RATE_1M, /* 0 */
- MPT_RATE_2M,
- MPT_RATE_55M,
- MPT_RATE_11M, /* 3 */
-
- /* OFDM rate. */
- MPT_RATE_6M, /* 4 */
- MPT_RATE_9M,
- MPT_RATE_12M,
- MPT_RATE_18M,
- MPT_RATE_24M,
- MPT_RATE_36M,
- MPT_RATE_48M,
- MPT_RATE_54M, /* 11 */
-
- /* HT rate. */
- MPT_RATE_MCS0, /* 12 */
- MPT_RATE_MCS1,
- MPT_RATE_MCS2,
- MPT_RATE_MCS3,
- MPT_RATE_MCS4,
- MPT_RATE_MCS5,
- MPT_RATE_MCS6,
- MPT_RATE_MCS7, /* 19 */
- MPT_RATE_MCS8,
- MPT_RATE_MCS9,
- MPT_RATE_MCS10,
- MPT_RATE_MCS11,
- MPT_RATE_MCS12,
- MPT_RATE_MCS13,
- MPT_RATE_MCS14,
- MPT_RATE_MCS15, /* 27 */
- MPT_RATE_LAST
-};
-
-#define MAX_TX_PWR_INDEX_N_MODE 64 /* 0x3F */
-
-enum power_mode {
- POWER_LOW = 0,
- POWER_NORMAL
-};
-
-#define RX_PKT_BROADCAST 1
-#define RX_PKT_DEST_ADDR 2
-#define RX_PKT_PHY_MATCH 3
-
-enum encry_ctrl_state {
- HW_CONTROL, /* hw encryption& decryption */
- SW_CONTROL, /* sw encryption& decryption */
- HW_ENCRY_SW_DECRY, /* hw encryption & sw decryption */
- SW_ENCRY_HW_DECRY /* sw encryption & hw decryption */
-};
-
-s32 init_mp_priv(struct adapter *padapter);
-void free_mp_priv(struct mp_priv *pmp_priv);
-s32 MPT_InitializeAdapter(struct adapter *padapter, u8 Channel);
-void MPT_DeInitAdapter(struct adapter *padapter);
-s32 mp_start_test(struct adapter *padapter);
-void mp_stop_test(struct adapter *padapter);
-
-u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
-void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
-
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
-u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
-void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
-u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr);
-void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val);
-
-void SetChannel(struct adapter *pAdapter);
-void SetBandwidth(struct adapter *pAdapter);
-void SetTxPower(struct adapter *pAdapter);
-void SetAntennaPathPower(struct adapter *pAdapter);
-void SetDataRate(struct adapter *pAdapter);
-
-void SetAntenna(struct adapter *pAdapter);
-
-s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther);
-void GetThermalMeter(struct adapter *pAdapter, u8 *value);
-
-void SetContinuousTx(struct adapter *pAdapter, u8 bStart);
-void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart);
-void SetSingleToneTx(struct adapter *pAdapter, u8 bStart);
-void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart);
-void PhySetTxPowerLevel(struct adapter *pAdapter);
-
-void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc);
-void SetPacketTx(struct adapter *padapter);
-void SetPacketRx(struct adapter *pAdapter, u8 bStartRx);
-
-void ResetPhyRxPktCount(struct adapter *pAdapter);
-u32 GetPhyRxPktReceived(struct adapter *pAdapter);
-u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter);
-
-s32 SetPowerTracking(struct adapter *padapter, u8 enable);
-void GetPowerTracking(struct adapter *padapter, u8 *enable);
-u32 mp_query_psd(struct adapter *pAdapter, u8 *data);
-void Hal_SetAntenna(struct adapter *pAdapter);
-void Hal_SetBandwidth(struct adapter *pAdapter);
-void Hal_SetTxPower(struct adapter *pAdapter);
-void Hal_SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart);
-void Hal_SetSingleToneTx(struct adapter *pAdapter, u8 bStart);
-void Hal_SetSingleCarrierTx (struct adapter *pAdapter, u8 bStart);
-void Hal_SetContinuousTx (struct adapter *pAdapter, u8 bStart);
-void Hal_SetBandwidth(struct adapter *pAdapter);
-void Hal_SetDataRate(struct adapter *pAdapter);
-void Hal_SetChannel(struct adapter *pAdapter);
-void Hal_SetAntennaPathPower(struct adapter *pAdapter);
-s32 Hal_SetThermalMeter(struct adapter *pAdapter, u8 target_ther);
-s32 Hal_SetPowerTracking(struct adapter *padapter, u8 enable);
-void Hal_GetPowerTracking(struct adapter *padapter, u8 *enable);
-void Hal_GetThermalMeter(struct adapter *pAdapter, u8 *value);
-void Hal_mpt_SwitchRfSetting(struct adapter *pAdapter);
-void Hal_MPT_CCKTxPowerAdjust(struct adapter *Adapter, bool bInCH14);
-void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven);
-void Hal_SetCCKTxPower(struct adapter *pAdapter, u8 *TxPower);
-void Hal_SetOFDMTxPower(struct adapter *pAdapter, u8 *TxPower);
-void Hal_TriggerRFThermalMeter(struct adapter *pAdapter);
-u8 Hal_ReadRFThermalMeter(struct adapter *pAdapter);
-void Hal_SetCCKContinuousTx(struct adapter *pAdapter, u8 bStart);
-void Hal_SetOFDMContinuousTx(struct adapter *pAdapter, u8 bStart);
-void Hal_ProSetCrystalCap (struct adapter *pAdapter , u32 CrystalCapVal);
-void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv);
-void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter , bool bMain);
-
-#endif /* _RTW_MP_H_ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_mp_ioctl.h b/drivers/staging/rtl8188eu/include/rtw_mp_ioctl.h
deleted file mode 100644
index 9388368a6b19..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_mp_ioctl.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef _RTW_MP_IOCTL_H_
-#define _RTW_MP_IOCTL_H_
-
-#include <drv_types.h>
-#include <mp_custom_oid.h>
-#include <rtw_ioctl.h>
-#include <rtw_ioctl_rtl.h>
-#include <rtw_efuse.h>
-#include <rtw_mp.h>
-
-/* */
-struct cfg_dbg_msg_struct {
- u32 DebugLevel;
- u32 DebugComponent_H32;
- u32 DebugComponent_L32;
-};
-
-struct mp_rw_reg {
- u32 offset;
- u32 width;
- u32 value;
-};
-
-struct efuse_access_struct {
- u16 start_addr;
- u16 cnts;
- u8 data[0];
-};
-
-struct burst_rw_reg {
- u32 offset;
- u32 len;
- u8 Data[256];
-};
-
-struct usb_vendor_req {
- u8 bRequest;
- u16 wValue;
- u16 wIndex;
- u16 wLength;
- u8 u8Dir;/* 0:OUT, 1:IN */
- u8 u8InData;
-};
-
-struct dr_variable_struct {
- u8 offset;
- u32 variable;
-};
-
-#define _irqlevel_changed_(a, b)
-
-/* rtl8188eu_oid_rtl_seg_81_80_00 */
-int rtl8188eu_oid_rt_pro_set_data_rate_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_start_test_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_stop_test_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_antenna_bb_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_tx_power_control_hdl(struct oid_par_priv *poid_par_priv);
-
-/* rtl8188eu_oid_rtl_seg_81_80_20 */
-int rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv);
-int rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl(struct oid_par_priv *par_priv);
-int rtl8188eu_oid_rt_pro_set_modulation_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_continuous_tx_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl(struct oid_par_priv *par_priv);
-int rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv *poid_par_priv);
-
-/* rtl8188eu_oid_rtl_seg_81_87 */
-int rtl8188eu_oid_rt_pro_write_bb_reg_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read_bb_reg_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
-
-/* rtl8188eu_oid_rtl_seg_81_85 */
-int rtl8188eu_oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv);
-
-/* rtl8188eu_oid_rtl_seg_87_11_00 */
-int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_burst_read_register_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_burst_write_register_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_wr_attrib_mem_hdl (struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv);
-/* rtl8188eu_oid_rtl_seg_87_11_20 */
-int rtl8188eu_oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read_tssi_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv *poid_par_priv);
-/* rtl8188eu_oid_rtl_seg_87_11_50 */
-int rtl8188eu_oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv);
-/* rtl8188eu_oid_rtl_seg_87_11_F0 */
-int rtl8188eu_oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv *poid_par_priv);
-
-/* rtl8188eu_oid_rtl_seg_87_12_00 */
-int rtl8188eu_oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_efuse_current_size_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl(struct oid_par_priv *par_priv);
-int rtl8188eu_oid_rt_set_power_down_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_get_power_mode_hdl(struct oid_par_priv *poid_par_priv);
-int rtl8188eu_oid_rt_pro_trigger_gpio_hdl(struct oid_par_priv *poid_par_priv);
-
-#ifdef _RTW_MP_IOCTL_C_
-
-static const struct oid_obj_priv rtl8188eu_oid_rtl_seg_81_80_00[] = {
- {1, &oid_null_function}, /* 0x00 OID_RT_PRO_RESET_DUT */
- {1, &rtl8188eu_oid_rt_pro_set_data_rate_hdl}, /* 0x01 */
- {1, &rtl8188eu_oid_rt_pro_start_test_hdl}, /* 0x02 */
- {1, &rtl8188eu_oid_rt_pro_stop_test_hdl}, /* 0x03 */
- {1, &oid_null_function}, /* 0x04 OID_RT_PRO_SET_PREAMBLE */
- {1, &oid_null_function}, /* 0x05 OID_RT_PRO_SET_SCRAMBLER */
- {1, &oid_null_function}, /* 0x06 OID_RT_PRO_SET_FILTER_BB */
- {1, &oid_null_function},/* 0x07 OID_RT_PRO_SET_MANUAL_DIVERSITY_BB */
- {1, &rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl}, /* 0x08 */
- {1, &oid_null_function},/* 0x09 OID_RT_PRO_SET_SLEEP_MODE_DIRECT_CALL */
- {1, &oid_null_function},/* 0x0A OID_RT_PRO_SET_WAKE_MODE_DIRECT_CALL */
- {1, &rtl8188eu_oid_rt_pro_set_continuous_tx_hdl}, /* 0x0B OID_RT_PRO_SET_TX_CONTINUOUS_DIRECT_CALL */
- {1, &rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl},/* 0x0C OID_RT_PRO_SET_SINGLE_CARRIER_TX_CONTINUOUS */
- {1, &oid_null_function}, /* 0x0D OID_RT_PRO_SET_TX_ANTENNA_BB */
- {1, &rtl8188eu_oid_rt_pro_set_antenna_bb_hdl}, /* 0x0E */
- {1, &oid_null_function}, /* 0x0F OID_RT_PRO_SET_CR_SCRAMBLER */
- {1, &oid_null_function}, /* 0x10 OID_RT_PRO_SET_CR_NEW_FILTER */
- {1, &rtl8188eu_oid_rt_pro_set_tx_power_control_hdl},/* 0x11 OID_RT_PRO_SET_TX_POWER_CONTROL */
- {1, &oid_null_function}, /* 0x12 OID_RT_PRO_SET_CR_TX_CONFIG */
- {1, &oid_null_function}, /* 0x13 OID_RT_PRO_GET_TX_POWER_CONTROL */
- {1, &oid_null_function}, /* 0x14 OID_RT_PRO_GET_CR_SIGNAL_QUALITY */
- {1, &oid_null_function}, /* 0x15 OID_RT_PRO_SET_CR_SETPOINT */
- {1, &oid_null_function}, /* 0x16 OID_RT_PRO_SET_INTEGRATOR */
- {1, &oid_null_function}, /* 0x17 OID_RT_PRO_SET_SIGNAL_QUALITY */
- {1, &oid_null_function}, /* 0x18 OID_RT_PRO_GET_INTEGRATOR */
- {1, &oid_null_function}, /* 0x19 OID_RT_PRO_GET_SIGNAL_QUALITY */
- {1, &oid_null_function}, /* 0x1A OID_RT_PRO_QUERY_EEPROM_TYPE */
- {1, &oid_null_function}, /* 0x1B OID_RT_PRO_WRITE_MAC_ADDRESS */
- {1, &oid_null_function}, /* 0x1C OID_RT_PRO_READ_MAC_ADDRESS */
- {1, &oid_null_function}, /* 0x1D OID_RT_PRO_WRITE_CIS_DATA */
- {1, &oid_null_function}, /* 0x1E OID_RT_PRO_READ_CIS_DATA */
- {1, &oid_null_function} /* 0x1F OID_RT_PRO_WRITE_POWER_CONTROL */
-};
-
-static const struct oid_obj_priv rtl8188eu_oid_rtl_seg_81_80_20[] = {
- {1, &oid_null_function}, /* 0x20 OID_RT_PRO_READ_POWER_CONTROL */
- {1, &oid_null_function}, /* 0x21 OID_RT_PRO_WRITE_EEPROM */
- {1, &oid_null_function}, /* 0x22 OID_RT_PRO_READ_EEPROM */
- {1, &rtl8188eu_oid_rt_pro_reset_tx_packet_sent_hdl}, /* 0x23 */
- {1, &rtl8188eu_oid_rt_pro_query_tx_packet_sent_hdl}, /* 0x24 */
- {1, &rtl8188eu_oid_rt_pro_reset_rx_packet_received_hdl}, /* 0x25 */
- {1, &rtl8188eu_oid_rt_pro_query_rx_packet_received_hdl}, /* 0x26 */
- {1, &rtl8188eu_oid_rt_pro_query_rx_packet_crc32_error_hdl}, /* 0x27 */
- {1, &oid_null_function}, /* 0x28 OID_RT_PRO_QUERY_CURRENT_ADDRESS */
- {1, &oid_null_function}, /* 0x29 OID_RT_PRO_QUERY_PERMANENT_ADDRESS */
- {1, &oid_null_function}, /* 0x2A OID_RT_PRO_SET_PHILIPS_RF_PARAMETERS */
- {1, &rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl},/* 0x2B OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX */
- {1, &oid_null_function}, /* 0x2C OID_RT_PRO_RECEIVE_PACKET */
- {1, &oid_null_function}, /* 0x2D OID_RT_PRO_WRITE_EEPROM_BYTE */
- {1, &oid_null_function}, /* 0x2E OID_RT_PRO_READ_EEPROM_BYTE */
- {1, &rtl8188eu_oid_rt_pro_set_modulation_hdl} /* 0x2F */
-};
-
-static const struct oid_obj_priv rtl8188eu_oid_rtl_seg_81_80_40[] = {
- {1, &oid_null_function}, /* 0x40 */
- {1, &oid_null_function}, /* 0x41 */
- {1, &oid_null_function}, /* 0x42 */
- {1, &rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl}, /* 0x43 */
- {1, &oid_null_function}, /* 0x44 */
- {1, &oid_null_function} /* 0x45 */
-};
-
-static const struct oid_obj_priv rtl8188eu_oid_rtl_seg_81_80_80[] = {
- {1, &oid_null_function}, /* 0x80 OID_RT_DRIVER_OPTION */
- {1, &oid_null_function}, /* 0x81 OID_RT_RF_OFF */
- {1, &oid_null_function} /* 0x82 OID_RT_AUTH_STATUS */
-};
-
-static const struct oid_obj_priv rtl8188eu_oid_rtl_seg_81_85[] = {
- {1, &rtl8188eu_oid_rt_wireless_mode_hdl} /* 0x00 OID_RT_WIRELESS_MODE */
-};
-
-#endif /* _RTL871X_MP_IOCTL_C_ */
-
-struct rwreg_param {
- u32 offset;
- u32 width;
- u32 value;
-};
-
-struct bbreg_param {
- u32 offset;
- u32 phymask;
- u32 value;
-};
-
-struct txpower_param {
- u32 pwr_index;
-};
-
-struct datarate_param {
- u32 rate_index;
-};
-
-struct rfintfs_parm {
- u32 rfintfs;
-};
-
-struct mp_xmit_parm {
- u8 enable;
- u32 count;
- u16 length;
- u8 payload_type;
- u8 da[ETH_ALEN];
-};
-
-struct mp_xmit_packet {
- u32 len;
- u32 mem[MAX_MP_XMITBUF_SZ >> 2];
-};
-
-struct psmode_param {
- u32 ps_mode;
- u32 smart_ps;
-};
-
-/* for OID_RT_PRO_READ16_EEPROM & OID_RT_PRO_WRITE16_EEPROM */
-struct eeprom_rw_param {
- u32 offset;
- u16 value;
-};
-
-struct mp_ioctl_handler {
- u32 paramsize;
- s32 (*handler)(struct oid_par_priv *poid_par_priv);
- u32 oid;
-};
-
-struct mp_ioctl_param{
- u32 subcode;
- u32 len;
- u8 data[0];
-};
-
-#define GEN_MP_IOCTL_SUBCODE(code) _MP_IOCTL_ ## code ## _CMD_
-
-enum RTL871X_MP_IOCTL_SUBCODE {
- GEN_MP_IOCTL_SUBCODE(MP_START), /*0*/
- GEN_MP_IOCTL_SUBCODE(MP_STOP),
- GEN_MP_IOCTL_SUBCODE(READ_REG),
- GEN_MP_IOCTL_SUBCODE(WRITE_REG),
- GEN_MP_IOCTL_SUBCODE(READ_BB_REG),
- GEN_MP_IOCTL_SUBCODE(WRITE_BB_REG), /*5*/
- GEN_MP_IOCTL_SUBCODE(READ_RF_REG),
- GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG),
- GEN_MP_IOCTL_SUBCODE(SET_CHANNEL),
- GEN_MP_IOCTL_SUBCODE(SET_TXPOWER),
- GEN_MP_IOCTL_SUBCODE(SET_DATARATE), /*10*/
- GEN_MP_IOCTL_SUBCODE(SET_BANDWIDTH),
- GEN_MP_IOCTL_SUBCODE(SET_ANTENNA),
- GEN_MP_IOCTL_SUBCODE(CNTU_TX),
- GEN_MP_IOCTL_SUBCODE(SC_TX),
- GEN_MP_IOCTL_SUBCODE(CS_TX), /*15*/
- GEN_MP_IOCTL_SUBCODE(ST_TX),
- GEN_MP_IOCTL_SUBCODE(IOCTL_XMIT_PACKET),
- GEN_MP_IOCTL_SUBCODE(SET_RX_PKT_TYPE),
- GEN_MP_IOCTL_SUBCODE(RESET_PHY_RX_PKT_CNT),
- GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_RECV), /*20*/
- GEN_MP_IOCTL_SUBCODE(GET_PHY_RX_PKT_ERROR),
- GEN_MP_IOCTL_SUBCODE(READ16_EEPROM),
- GEN_MP_IOCTL_SUBCODE(WRITE16_EEPROM),
- GEN_MP_IOCTL_SUBCODE(EFUSE),
- GEN_MP_IOCTL_SUBCODE(EFUSE_MAP), /*25*/
- GEN_MP_IOCTL_SUBCODE(GET_EFUSE_MAX_SIZE),
- GEN_MP_IOCTL_SUBCODE(GET_EFUSE_CURRENT_SIZE),
- GEN_MP_IOCTL_SUBCODE(GET_THERMAL_METER),
- GEN_MP_IOCTL_SUBCODE(SET_PTM),
- GEN_MP_IOCTL_SUBCODE(SET_POWER_DOWN), /*30*/
- GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO),
- GEN_MP_IOCTL_SUBCODE(SET_DM_BT), /*35*/
- GEN_MP_IOCTL_SUBCODE(DEL_BA), /*36*/
- GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS), /*37*/
- MAX_MP_IOCTL_SUBCODE,
-};
-
-s32 rtl8188eu_mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv);
-
-#define GEN_HANDLER(sz, hdl, oid) {sz, hdl, oid},
-
-#define EXT_MP_IOCTL_HANDLER(sz, subcode, oid) \
- {sz, rtl8188eu_mp_ioctl_##subcode##_hdl, oid},
-
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_p2p.h b/drivers/staging/rtl8188eu/include/rtw_p2p.h
deleted file mode 100644
index a3e3adc92b99..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_p2p.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef __RTW_P2P_H_
-#define __RTW_P2P_H_
-
-#include <drv_types.h>
-
-u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo,
- u8 *pbuf, u8 *pssid, u8 ussidlen,
- u8 *pdev_raddr);
-u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo,
- u8 *pbuf, u8 status_code);
-u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf);
-u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len, struct sta_info *psta);
-u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe);
-u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo,
- u8 *pframe, uint len);
-u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe,
- uint len);
-void p2p_protocol_wk_hdl(struct adapter *padapter, int intcmdtype);
-void process_p2p_ps_ie(struct adapter *padapter, u8 *ies, u32 ielength);
-void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state);
-u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue);
-void reset_global_wifidirect_info(struct adapter *padapter);
-int rtw_init_wifi_display_info(struct adapter *padapter);
-void rtw_init_wifidirect_timers(struct adapter *padapter);
-void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr,
- u8 *iface_addr);
-void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role);
-int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role);
-
-static inline void _rtw_p2p_set_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- if (wdinfo->p2p_state != state)
- wdinfo->p2p_state = state;
-}
-
-static inline void _rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- if (wdinfo->pre_p2p_state != state)
- wdinfo->pre_p2p_state = state;
-}
-
-static inline void _rtw_p2p_set_role(struct wifidirect_info *wdinfo,
- enum P2P_ROLE role)
-{
- if (wdinfo->role != role)
- wdinfo->role = role;
-}
-
-static inline int _rtw_p2p_state(struct wifidirect_info *wdinfo)
-{
- return wdinfo->p2p_state;
-}
-
-static inline int _rtw_p2p_pre_state(struct wifidirect_info *wdinfo)
-{
- return wdinfo->pre_p2p_state;
-}
-
-static inline int _rtw_p2p_role(struct wifidirect_info *wdinfo)
-{
- return wdinfo->role;
-}
-
-static inline bool _rtw_p2p_chk_state(struct wifidirect_info *wdinfo,
- enum P2P_STATE state)
-{
- return wdinfo->p2p_state == state;
-}
-
-static inline bool _rtw_p2p_chk_role(struct wifidirect_info *wdinfo,
- enum P2P_ROLE role)
-{
- return wdinfo->role == role;
-}
-
-#define rtw_p2p_set_state(wdinfo, state) _rtw_p2p_set_state(wdinfo, state)
-#define rtw_p2p_set_pre_state(wdinfo, state) \
- _rtw_p2p_set_pre_state(wdinfo, state)
-#define rtw_p2p_set_role(wdinfo, role) _rtw_p2p_set_role(wdinfo, role)
-
-#define rtw_p2p_state(wdinfo) _rtw_p2p_state(wdinfo)
-#define rtw_p2p_pre_state(wdinfo) _rtw_p2p_pre_state(wdinfo)
-#define rtw_p2p_role(wdinfo) _rtw_p2p_role(wdinfo)
-#define rtw_p2p_chk_state(wdinfo, state) _rtw_p2p_chk_state(wdinfo, state)
-#define rtw_p2p_chk_role(wdinfo, role) _rtw_p2p_chk_role(wdinfo, role)
-
-#define rtw_p2p_findphase_ex_set(wdinfo, value) \
- ((wdinfo)->find_phase_state_exchange_cnt = (value))
-
-/* is this find phase exchange for social channel scan? */
-#define rtw_p2p_findphase_ex_is_social(wdinfo) \
-((wdinfo)->find_phase_state_exchange_cnt >= P2P_FINDPHASE_EX_SOCIAL_FIRST)
-
-/* should we need find phase exchange anymore? */
-#define rtw_p2p_findphase_ex_is_needed(wdinfo) \
- ((wdinfo)->find_phase_state_exchange_cnt < P2P_FINDPHASE_EX_MAX && \
- (wdinfo)->find_phase_state_exchange_cnt != P2P_FINDPHASE_EX_NONE)
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h
index 937cad803d19..66d60aaf4ae8 100644
--- a/drivers/staging/rtl8188eu/include/rtw_security.h
+++ b/drivers/staging/rtl8188eu/include/rtw_security.h
@@ -378,6 +378,5 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe);
u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe);
u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe);
void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe);
-void rtw_use_tkipkey_handler(void *FunctionContext);
#endif /* __RTL871X_SECURITY_H_ */
diff --git a/drivers/staging/rtl8188eu/include/rtw_sreset.h b/drivers/staging/rtl8188eu/include/rtw_sreset.h
index 2a1244f75790..580e850511a7 100644
--- a/drivers/staging/rtl8188eu/include/rtw_sreset.h
+++ b/drivers/staging/rtl8188eu/include/rtw_sreset.h
@@ -24,11 +24,7 @@
#include <drv_types.h>
struct sreset_priv {
- struct mutex silentreset_mutex;
- u8 silent_reset_inprogress;
u8 Wifi_Error_Status;
- unsigned long last_tx_time;
- unsigned long last_tx_complete_time;
};
#include <rtl8188e_hal.h>
@@ -43,7 +39,6 @@ struct sreset_priv {
#define WIFI_IF_NOT_EXIST BIT6
void sreset_init_value(struct adapter *padapter);
-void sreset_reset_value(struct adapter *padapter);
u8 sreset_get_wifi_status(struct adapter *padapter);
void sreset_set_wifi_error_status(struct adapter *padapter, u32 status);
diff --git a/drivers/staging/rtl8188eu/include/rtw_version.h b/drivers/staging/rtl8188eu/include/rtw_version.h
deleted file mode 100644
index 6d2d52cbb3d3..000000000000
--- a/drivers/staging/rtl8188eu/include/rtw_version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define DRIVERVERSION "v4.1.4_6773.20130222"
diff --git a/drivers/staging/rtl8188eu/include/sta_info.h b/drivers/staging/rtl8188eu/include/sta_info.h
index 3e909db1d41a..9612490539b3 100644
--- a/drivers/staging/rtl8188eu/include/sta_info.h
+++ b/drivers/staging/rtl8188eu/include/sta_info.h
@@ -182,21 +182,6 @@ struct sta_info {
unsigned int sleepq_ac_len;
#endif /* CONFIG_88EU_AP_MODE */
-#ifdef CONFIG_88EU_P2P
- /* p2p priv data */
- u8 is_p2p_device;
- u8 p2p_status_code;
-
- /* p2p client info */
- u8 dev_addr[ETH_ALEN];
- u8 dev_cap;
- u16 config_methods;
- u8 primary_dev_type[8];
- u8 num_of_secdev_type;
- u8 secdev_types_list[32];/* 32/8 == 4; */
- u16 dev_name_len;
- u8 dev_name[32];
-#endif /* CONFIG_88EU_P2P */
u8 under_exist_checking;
u8 keep_alive_trycnt;
diff --git a/drivers/staging/rtl8188eu/include/usb_ops.h b/drivers/staging/rtl8188eu/include/usb_ops.h
deleted file mode 100644
index a290e0ff3060..000000000000
--- a/drivers/staging/rtl8188eu/include/usb_ops.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef __USB_OPS_H_
-#define __USB_OPS_H_
-
-#include <linux/version.h>
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <osdep_intf.h>
-
-#define REALTEK_USB_VENQT_READ 0xC0
-#define REALTEK_USB_VENQT_WRITE 0x40
-#define REALTEK_USB_VENQT_CMD_REQ 0x05
-#define REALTEK_USB_VENQT_CMD_IDX 0x00
-
-enum{
- VENDOR_WRITE = 0x00,
- VENDOR_READ = 0x01,
-};
-#define ALIGNMENT_UNIT 16
-#define MAX_VENDOR_REQ_CMD_SIZE 254 /* 8188cu SIE Support */
-#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE + ALIGNMENT_UNIT)
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12))
-#define rtw_usb_control_msg(dev, pipe, request, requesttype, \
- value, index, data, size, timeout_ms) \
- usb_control_msg((dev), (pipe), (request), (requesttype), (value),\
- (index), (data), (size), (timeout_ms))
-#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, actual_length, timeout_ms) \
- usb_bulk_msg((usb_dev), (pipe), (data), (len), \
- (actual_length), (timeout_ms))
-#else
-#define rtw_usb_control_msg(dev, pipe, request, requesttype, \
- value, index, data, size, timeout_ms) \
- usb_control_msg((dev), (pipe), (request), (requesttype), \
- (value), (index), (data), (size), \
- ((timeout_ms) == 0) || \
- ((timeout_ms)*HZ/1000 > 0) ? \
- ((timeout_ms)*HZ/1000) : 1)
-#define rtw_usb_bulk_msg(usb_dev, pipe, data, len, \
- actual_length, timeout_ms) \
- usb_bulk_msg((usb_dev), (pipe), (data), (len), (actual_length), \
- ((timeout_ms) == 0) || ((timeout_ms)*HZ/1000 > 0) ?\
- ((timeout_ms)*HZ/1000) : 1)
-#endif
-#include <usb_ops_linux.h>
-
-void rtl8188eu_set_hw_type(struct adapter *padapter);
-void rtl8188eu_set_intf_ops(struct _io_ops *pops);
-#define usb_set_intf_ops rtl8188eu_set_intf_ops
-
-/*
- * Increase and check if the continual_urb_error of this @param dvobjprivei
- * is larger than MAX_CONTINUAL_URB_ERR
- * @return true:
- * @return false:
- */
-static inline int rtw_inc_and_chk_continual_urb_error(struct dvobj_priv *dvobj)
-{
- int ret = false;
- int value;
- value = atomic_inc_return(&dvobj->continual_urb_error);
- if (value > MAX_CONTINUAL_URB_ERR) {
- DBG_88E("[dvobj:%p][ERROR] continual_urb_error:%d > %d\n",
- dvobj, value, MAX_CONTINUAL_URB_ERR);
- ret = true;
- }
- return ret;
-}
-
-/*
-* Set the continual_urb_error of this @param dvobjprive to 0
-*/
-static inline void rtw_reset_continual_urb_error(struct dvobj_priv *dvobj)
-{
- atomic_set(&dvobj->continual_urb_error, 0);
-}
-
-#define USB_HIGH_SPEED_BULK_SIZE 512
-#define USB_FULL_SPEED_BULK_SIZE 64
-
-static inline u8 rtw_usb_bulk_size_boundary(struct adapter *padapter,
- int buf_len)
-{
- u8 rst = true;
- struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
-
- if (pdvobjpriv->ishighspeed)
- rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE) ?
- true : false;
- else
- rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE) ?
- true : false;
- return rst;
-}
-
-#endif /* __USB_OPS_H_ */
diff --git a/drivers/staging/rtl8188eu/include/usb_ops_linux.h b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
index e5b758a81a5c..01b3810379ec 100644
--- a/drivers/staging/rtl8188eu/include/usb_ops_linux.h
+++ b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
@@ -29,6 +29,16 @@
#define RTW_USB_BULKOUT_TIME 5000/* ms */
+#define REALTEK_USB_VENQT_READ 0xC0
+#define REALTEK_USB_VENQT_WRITE 0x40
+
+#define ALIGNMENT_UNIT 16
+#define MAX_VENDOR_REQ_CMD_SIZE 254 /* 8188cu SIE Support */
+#define MAX_USB_IO_CTL_SIZE (MAX_VENDOR_REQ_CMD_SIZE + ALIGNMENT_UNIT)
+
+#define USB_HIGH_SPEED_BULK_SIZE 512
+#define USB_FULL_SPEED_BULK_SIZE 64
+
#define _usbctrl_vendorreq_async_callback(urb, regs) \
_usbctrl_vendorreq_async_callback(urb)
#define usb_bulkout_zero_complete(purb, regs) \
@@ -42,14 +52,36 @@
#define usb_read_interrupt_complete(purb, regs) \
usb_read_interrupt_complete(purb)
+static inline u8 rtw_usb_bulk_size_boundary(struct adapter *padapter,
+ int buf_len)
+{
+ u8 rst = true;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+
+ if (pdvobjpriv->ishighspeed)
+ rst = (0 == (buf_len) % USB_HIGH_SPEED_BULK_SIZE) ?
+ true : false;
+ else
+ rst = (0 == (buf_len) % USB_FULL_SPEED_BULK_SIZE) ?
+ true : false;
+ return rst;
+}
+
unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr);
-void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem);
-void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem);
+u8 usb_read8(struct adapter *adapter, u32 addr);
+u16 usb_read16(struct adapter *adapter, u32 addr);
+u32 usb_read32(struct adapter *adapter, u32 addr);
+
+u32 usb_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+void usb_read_port_cancel(struct adapter *adapter);
-void usb_read_port_cancel(struct intf_hdl *pintfhdl);
+int usb_write8(struct adapter *adapter, u32 addr, u8 val);
+int usb_write16(struct adapter *adapter, u32 addr, u16 val);
+int usb_write32(struct adapter *adapter, u32 addr, u32 val);
+int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata);
-u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem);
-void usb_write_port_cancel(struct intf_hdl *pintfhdl);
+u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
+void usb_write_port_cancel(struct adapter *adapter);
#endif
diff --git a/drivers/staging/rtl8188eu/include/usb_osintf.h b/drivers/staging/rtl8188eu/include/usb_osintf.h
deleted file mode 100644
index 9de99ca9799a..000000000000
--- a/drivers/staging/rtl8188eu/include/usb_osintf.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef __USB_OSINTF_H
-#define __USB_OSINTF_H
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <usb_vendor_req.h>
-
-extern char *rtw_initmac;
-extern int rtw_mc2u_disable;
-
-#define USBD_HALTED(Status) ((u32)(Status) >> 30 == 3)
-
-u8 usbvendorrequest(struct dvobj_priv *pdvobjpriv, enum bt_usb_request brequest,
- enum rt_usb_wvalue wvalue, u8 windex, void *data,
- u8 datalen, u8 isdirectionin);
-int pm_netdev_open(struct net_device *pnetdev, u8 bnormal);
-void netdev_br_init(struct net_device *netdev);
-void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb);
-void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr,
- unsigned char *ipAddr);
-void nat25_db_expire(struct adapter *priv);
-int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method);
-
-int rtw_resume_process(struct adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/usb_vendor_req.h b/drivers/staging/rtl8188eu/include/usb_vendor_req.h
deleted file mode 100644
index 7f26c8f2c78e..000000000000
--- a/drivers/staging/rtl8188eu/include/usb_vendor_req.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- * 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 Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#ifndef _USB_VENDOR_REQUEST_H_
-#define _USB_VENDOR_REQUEST_H_
-
-/* 4 Set/Get Register related wIndex/Data */
-#define RT_USB_RESET_MASK_OFF 0
-#define RT_USB_RESET_MASK_ON 1
-#define RT_USB_SLEEP_MASK_OFF 0
-#define RT_USB_SLEEP_MASK_ON 1
-#define RT_USB_LDO_ON 1
-#define RT_USB_LDO_OFF 0
-
-/* 4 Set/Get SYSCLK related wValue or Data */
-#define RT_USB_SYSCLK_32KHZ 0
-#define RT_USB_SYSCLK_40MHZ 1
-#define RT_USB_SYSCLK_60MHZ 2
-
-
-enum bt_usb_request {
- RT_USB_SET_REGISTER = 1,
- RT_USB_SET_SYSCLK = 2,
- RT_USB_GET_SYSCLK = 3,
- RT_USB_GET_REGISTER = 4
-};
-
-enum rt_usb_wvalue {
- RT_USB_RESET_MASK = 1,
- RT_USB_SLEEP_MASK = 2,
- RT_USB_USB_HRCPWM = 3,
- RT_USB_LDO = 4,
- RT_USB_BOOT_TYPE = 5
-};
-
-#endif
diff --git a/drivers/staging/rtl8188eu/include/wlan_bssdef.h b/drivers/staging/rtl8188eu/include/wlan_bssdef.h
index e70075d586d7..53b1bd8e9946 100644
--- a/drivers/staging/rtl8188eu/include/wlan_bssdef.h
+++ b/drivers/staging/rtl8188eu/include/wlan_bssdef.h
@@ -340,8 +340,4 @@ struct ndis_802_11_cap {
struct ndis_802_11_auth_encrypt AuthenticationEncryptionSupported[1];
};
-u8 key_2char2num(u8 hch, u8 lch);
-u8 key_char2num(u8 ch);
-u8 str_2char2num(u8 hch, u8 lch);
-
#endif /* ifndef WLAN_BSSDEF_H_ */
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index f04aaa375f0e..d598fec4abbf 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -28,14 +28,11 @@
#include <rtw_mlme_ext.h>
#include <rtw_ioctl.h>
#include <rtw_ioctl_set.h>
-#include <rtw_mp_ioctl.h>
-#include <usb_ops.h>
-#include <rtw_version.h>
#include <rtl8188e_hal.h>
-#include <rtw_mp.h>
#include <rtw_iol.h>
#include <linux/vmalloc.h>
+#include "osdep_intf.h"
#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
@@ -56,48 +53,6 @@
#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
#define WEXT_CSCAN_TYPE_SECTION 'T'
-static struct mp_ioctl_handler mp_ioctl_hdl[] = {
-/*0*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST)
-
- GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER)
- GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER)
- GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG)
-/*5*/ GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG)
- GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY)
- GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY)
-
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL)
- GEN_HANDLER(sizeof(struct txpower_param), rtl8188eu_oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL)
-/*10*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB)
-
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX)
-/*15*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX)
-
- EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0)
-
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE)
- GEN_HANDLER(0, rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT)
-/*20*/ GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR)
-
- GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0)
- GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0)
- GEN_HANDLER(sizeof(struct efuse_access_struct), rtl8188eu_oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE)
-/*25*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE)
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE)
-
- GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER)
- GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING)
-/*30*/ GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN)
-/*31*/ GEN_HANDLER(0, rtl8188eu_oid_rt_pro_trigger_gpio_hdl, 0)
-};
-
static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
48000000, 54000000};
@@ -107,49 +62,11 @@ static const char * const iw_operation_mode[] = {
"Secondary", "Monitor"
};
-static int hex2num_i(char c)
-{
- if (c >= '0' && c <= '9')
- return c - '0';
- if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- return -1;
-}
-
-/**
- * hwaddr_aton - Convert ASCII string to MAC address
- * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
- * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
- * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
- */
-static int hwaddr_aton_i(const char *txt, u8 *addr)
-{
- int i;
-
- for (i = 0; i < 6; i++) {
- int a, b;
-
- a = hex2num_i(*txt++);
- if (a < 0)
- return -1;
- b = hex2num_i(*txt++);
- if (b < 0)
- return -1;
- *addr++ = (a << 4) | b;
- if (i < 5 && *txt++ != ':')
- return -1;
- }
-
- return 0;
-}
-
void indicate_wx_scan_complete_event(struct adapter *padapter)
{
union iwreq_data wrqu;
- _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
+ memset(&wrqu, 0, sizeof(union iwreq_data));
wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
}
@@ -158,7 +75,7 @@ void rtw_indicate_wx_assoc_event(struct adapter *padapter)
union iwreq_data wrqu;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
+ memset(&wrqu, 0, sizeof(union iwreq_data));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
@@ -172,10 +89,10 @@ void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
{
union iwreq_data wrqu;
- _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
+ memset(&wrqu, 0, sizeof(union iwreq_data));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n");
wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
@@ -198,35 +115,6 @@ static char *translate_scan(struct adapter *padapter,
u8 bw_40MHz = 0, short_GI = 0;
u16 mcs_rate = 0;
u8 ss, sq;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- u32 blnGotP2PIE = false;
-
- /* User is doing the P2P device discovery */
- /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
- /* If not, the driver should ignore this AP and go to the next AP. */
-
- /* Verifying the SSID */
- if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
- u32 p2pielen = 0;
-
- if (pnetwork->network.Reserved[0] == 2) {/* Probe Request */
- /* Verifying the P2P IE */
- if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen))
- blnGotP2PIE = true;
- } else {/* Beacon or Probe Respones */
- /* Verifying the P2P IE */
- if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))
- blnGotP2PIE = true;
- }
- }
-
- if (!blnGotP2PIE)
- return start;
- }
-#endif /* CONFIG_88EU_P2P */
/* AP MAC address */
iwe.cmd = SIOCGIWAP;
@@ -358,33 +246,33 @@ static char *translate_scan(struct adapter *padapter,
if (wpa_len > 0) {
p = buf;
- _rtw_memset(buf, 0, MAX_WPA_IE_LEN);
+ memset(buf, 0, MAX_WPA_IE_LEN);
p += sprintf(p, "wpa_ie=");
for (i = 0; i < wpa_len; i++)
p += sprintf(p, "%02x", wpa_ie[i]);
- _rtw_memset(&iwe, 0, sizeof(iwe));
+ memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = strlen(buf);
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- _rtw_memset(&iwe, 0, sizeof(iwe));
+ memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = wpa_len;
start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
}
if (rsn_len > 0) {
p = buf;
- _rtw_memset(buf, 0, MAX_WPA_IE_LEN);
+ memset(buf, 0, MAX_WPA_IE_LEN);
p += sprintf(p, "rsn_ie=");
for (i = 0; i < rsn_len; i++)
p += sprintf(p, "%02x", rsn_ie[i]);
- _rtw_memset(&iwe, 0, sizeof(iwe));
+ memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = strlen(buf);
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- _rtw_memset(&iwe, 0, sizeof(iwe));
+ memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = rsn_len;
start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
@@ -469,9 +357,6 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_88EU_P2P */
param->u.crypt.err = 0;
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
@@ -520,7 +405,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
goto exit;
}
- _rtw_memset(pwep, 0, wep_total_len);
+ memset(pwep, 0, wep_total_len);
pwep->KeyLength = wep_key_len;
pwep->Length = wep_total_len;
if (wep_key_len == 13) {
@@ -589,10 +474,6 @@ 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);
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
- rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
-#endif /* CONFIG_88EU_P2P */
}
}
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
@@ -621,9 +502,6 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
u8 *buf = NULL;
int group_cipher = 0, pairwise_cipher = 0;
int ret = 0;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_88EU_P2P */
if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
@@ -634,7 +512,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
}
if (ielen) {
- buf = rtw_zmalloc(ielen);
+ buf = kzalloc(ielen, GFP_KERNEL);
if (buf == NULL) {
ret = -ENOMEM;
goto exit;
@@ -729,10 +607,6 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
-#ifdef CONFIG_88EU_P2P
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
- rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
-#endif /* CONFIG_88EU_P2P */
cnt += buf[cnt+1]+2;
break;
} else {
@@ -955,14 +829,14 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
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. */
- _rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
+ memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
psecuritypriv->PMKIDList[j].bUsed = false;
break;
}
}
} else if (pPMK->cmd == IW_PMKSA_FLUSH) {
DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
- _rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
+ memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
psecuritypriv->PMKIDIndex = 0;
ret = true;
}
@@ -993,7 +867,7 @@ static int rtw_wx_get_range(struct net_device *dev,
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd));
wrqu->data.length = sizeof(*range);
- _rtw_memset(range, 0, sizeof(*range));
+ memset(range, 0, sizeof(*range));
/* Let's try to keep this struct in the same order as in
* linux/include/wireless.h
@@ -1113,10 +987,7 @@ static int rtw_wx_set_wap(struct net_device *dev,
phead = get_list_head(queue);
pmlmepriv->pscanned = phead->next;
- while (1) {
- if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == true)
- break;
-
+ while (phead != pmlmepriv->pscanned) {
pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
pmlmepriv->pscanned = pmlmepriv->pscanned->next;
@@ -1159,7 +1030,7 @@ static int rtw_wx_get_wap(struct net_device *dev,
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
+ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
@@ -1168,7 +1039,7 @@ static int rtw_wx_get_wap(struct net_device *dev,
((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true))
memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
else
- _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
+ memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
return 0;
}
@@ -1213,9 +1084,6 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif /* CONFIG_88EU_P2P */
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
if (padapter->registrypriv.mp_mode == 1) {
@@ -1262,16 +1130,7 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
/* the pmlmepriv->scan_interval is always equal to 3. */
/* So, the wpa_supplicant won't find out the WPS SoftAP. */
-#ifdef CONFIG_88EU_P2P
- if (pwdinfo->p2p_state != P2P_STATE_NONE) {
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
- rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
- rtw_free_network_queue(padapter, true);
- }
-#endif /* CONFIG_88EU_P2P */
-
- _rtw_memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
+ memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
if (wrqu->data.length == sizeof(struct iw_scan_req)) {
struct iw_scan_req *req = (struct iw_scan_req *)extra;
@@ -1365,9 +1224,6 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
u32 cnt = 0;
u32 wait_for_surveydone;
int wait_status;
-#ifdef CONFIG_88EU_P2P
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
-#endif /* CONFIG_88EU_P2P */
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
@@ -1376,19 +1232,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
goto exit;
}
-#ifdef CONFIG_88EU_P2P
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- /* P2P is enabled */
- wait_for_surveydone = 200;
- } else {
- /* P2P is disabled */
- wait_for_surveydone = 100;
- }
-#else
- {
- wait_for_surveydone = 100;
- }
-#endif /* CONFIG_88EU_P2P */
+ wait_for_surveydone = 100;
wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
@@ -1404,10 +1248,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
phead = get_list_head(queue);
plist = phead->next;
- while (1) {
- if (rtw_end_of_queue_search(phead, plist))
- break;
-
+ while (phead != plist) {
if ((stop - ev) < SCAN_ITEM_SIZE) {
ret = -E2BIG;
break;
@@ -1482,7 +1323,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
if (wrqu->essid.length != 33)
DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length);
- _rtw_memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
+ memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
ndis_ssid.SsidLength = len;
memcpy(ndis_ssid.Ssid, extra, len);
src_ssid = ndis_ssid.Ssid;
@@ -1492,14 +1333,7 @@ static int rtw_wx_set_essid(struct net_device *dev,
phead = get_list_head(queue);
pmlmepriv->pscanned = phead->next;
- while (1) {
- if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == true) {
- 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"));
-
- break;
- }
-
+ while (phead != pmlmepriv->pscanned) {
pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
pmlmepriv->pscanned = pmlmepriv->pscanned->next;
@@ -1584,7 +1418,6 @@ static int rtw_wx_set_rate(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
int i, ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
u8 datarates[NumRates];
u32 target_rate = wrqu->bitrate.value;
u32 fixed = wrqu->bitrate.fixed;
@@ -1657,12 +1490,6 @@ set_rate:
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i]));
}
- if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("rtw_wx_set_rate Fail!!!\n"));
- ret = -1;
- }
-
-
return ret;
}
@@ -1787,7 +1614,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
- _rtw_memset(&wep, 0, sizeof(struct ndis_802_11_wep));
+ memset(&wep, 0, sizeof(struct ndis_802_11_wep));
key = erq->flags & IW_ENCODE_INDEX;
@@ -2076,10 +1903,10 @@ static int rtw_wx_set_enc_ext(struct net_device *dev,
if (param == NULL)
return -1;
- _rtw_memset(param, 0, param_len);
+ memset(param, 0, param_len);
param->cmd = IEEE_CMD_SET_ENCRYPTION;
- _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
+ memset(param->sta_addr, 0xff, ETH_ALEN);
switch (pext->alg) {
case IW_ENCODE_ALG_NONE:
@@ -2144,2487 +1971,12 @@ static int rtw_wx_get_nick(struct net_device *dev,
return 0;
}
-static int rtw_wx_read32(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter;
- struct iw_point *p;
- u16 len;
- u32 addr;
- u32 data32;
- u32 bytes;
- u8 *ptmp;
- int rv;
- int ret = 0;
-
- padapter = (struct adapter *)rtw_netdev_priv(dev);
- p = &wrqu->data;
- len = p->length;
- ptmp = (u8 *)rtw_malloc(len);
- if (NULL == ptmp)
- return -ENOMEM;
-
- if (copy_from_user(ptmp, p->pointer, len)) {
- ret = -EFAULT;
- goto exit;
- }
-
- bytes = 0;
- addr = 0;
- rv = sscanf(ptmp, "%d,%x", &bytes, &addr);
- if (rv != 2) {
- ret = -EINVAL;
- goto exit;
- }
-
- switch (bytes) {
- case 1:
- data32 = rtw_read8(padapter, addr);
- sprintf(extra, "0x%02X", data32);
- break;
- case 2:
- data32 = rtw_read16(padapter, addr);
- sprintf(extra, "0x%04X", data32);
- break;
- case 4:
- data32 = rtw_read32(padapter, addr);
- sprintf(extra, "0x%08X", data32);
- break;
- default:
- DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
- ret = -EINVAL;
- goto exit;
- }
- DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
-
-exit:
- kfree(ptmp);
- return ret;
-}
-
-static int rtw_wx_write32(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- int rv;
-
- u32 addr;
- u32 data32;
- u32 bytes;
-
- bytes = 0;
- addr = 0;
- data32 = 0;
- rv = sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
- if (rv != 3)
- return -EINVAL;
-
- switch (bytes) {
- case 1:
- rtw_write8(padapter, addr, (u8)data32);
- DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32);
- break;
- case 2:
- rtw_write16(padapter, addr, (u16)data32);
- DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32);
- break;
- case 4:
- rtw_write32(padapter, addr, data32);
- DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32);
- break;
- default:
- DBG_88E(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rtw_wx_read_rf(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u32 path, addr, data32;
-
- path = *(u32 *)extra;
- addr = *((u32 *)extra + 1);
- data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
- /*
- * IMPORTANT!!
- * Only when wireless private ioctl is at odd order,
- * "extra" would be copied to user space.
- */
- sprintf(extra, "0x%05x", data32);
-
- return 0;
-}
-
-static int rtw_wx_write_rf(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u32 path, addr, data32;
-
- path = *(u32 *)extra;
- addr = *((u32 *)extra + 1);
- data32 = *((u32 *)extra + 2);
- rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
-
- return 0;
-}
-
-static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- return -1;
-}
-
static int dummy(struct net_device *dev, struct iw_request_info *a,
union iwreq_data *wrqu, char *b)
{
return -1;
}
-static int rtw_wx_set_channel_plan(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 channel_plan_req = (u8) (*((int *)wrqu));
-
- if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1))
- DBG_88E("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
- else
- return -EPERM;
-
- return 0;
-}
-
-static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- return 0;
-}
-
-static int rtw_wx_get_sensitivity(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *buf)
-{
- return 0;
-}
-
-static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return 0;
-}
-
-/*
- * For all data larger than 16 octets, we need to use a
- * pointer to memory allocated in user space.
- */
-static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return 0;
-}
-
-static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 len)
-{
- struct mp_rw_reg *RegRWStruct;
- struct rf_reg_param *prfreg;
- u8 path;
- u8 offset;
- u32 value;
-
- DBG_88E("%s\n", __func__);
-
- switch (id) {
- case GEN_MP_IOCTL_SUBCODE(MP_START):
- DBG_88E("871x_driver is only for normal mode, can't enter mp mode\n");
- break;
- case GEN_MP_IOCTL_SUBCODE(READ_REG):
- RegRWStruct = (struct mp_rw_reg *)pdata;
- switch (RegRWStruct->width) {
- case 1:
- RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
- break;
- case 2:
- RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
- break;
- case 4:
- RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
- break;
- default:
- break;
- }
-
- break;
- case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
- RegRWStruct = (struct mp_rw_reg *)pdata;
- switch (RegRWStruct->width) {
- case 1:
- rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
- break;
- case 2:
- rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
- break;
- case 4:
- rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
- break;
- default:
- break;
- }
-
- break;
- case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
-
- prfreg = (struct rf_reg_param *)pdata;
-
- path = (u8)prfreg->path;
- offset = (u8)prfreg->offset;
-
- value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
-
- prfreg->value = value;
-
- break;
- case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
-
- prfreg = (struct rf_reg_param *)pdata;
-
- path = (u8)prfreg->path;
- offset = (u8)prfreg->offset;
- value = prfreg->value;
-
- rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
-
- break;
- case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
- DBG_88E("==> trigger gpio 0\n");
- rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, NULL);
- break;
- case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
- *pdata = rtw_hal_sreset_get_wifi_status(padapter);
- break;
- default:
- break;
- }
-}
-
-static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- u32 BytesRead, BytesWritten, BytesNeeded;
- struct oid_par_priv oid_par;
- struct mp_ioctl_handler *phandler;
- struct mp_ioctl_param *poidparam;
- uint status = 0;
- u16 len;
- u8 *pparmbuf = NULL, bset;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct iw_point *p = &wrqu->data;
-
- if ((!p->length) || (!p->pointer)) {
- ret = -EINVAL;
- goto _rtw_mp_ioctl_hdl_exit;
- }
- pparmbuf = NULL;
- bset = (u8)(p->flags & 0xFFFF);
- len = p->length;
- pparmbuf = (u8 *)rtw_malloc(len);
- if (pparmbuf == NULL) {
- ret = -ENOMEM;
- goto _rtw_mp_ioctl_hdl_exit;
- }
-
- if (copy_from_user(pparmbuf, p->pointer, len)) {
- ret = -EFAULT;
- goto _rtw_mp_ioctl_hdl_exit;
- }
-
- poidparam = (struct mp_ioctl_param *)pparmbuf;
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
- ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
- poidparam->subcode, poidparam->len, len));
-
- if (poidparam->subcode >= ARRAY_SIZE(mp_ioctl_hdl)) {
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
- ret = -EINVAL;
- goto _rtw_mp_ioctl_hdl_exit;
- }
-
- if (padapter->registrypriv.mp_mode == 1) {
- phandler = mp_ioctl_hdl + poidparam->subcode;
-
- if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
- RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
- ("no matching drvext param size %d vs %d\r\n",
- poidparam->len, phandler->paramsize));
- ret = -EINVAL;
- goto _rtw_mp_ioctl_hdl_exit;
- }
-
- if (phandler->handler) {
- oid_par.adapter_context = padapter;
- oid_par.oid = phandler->oid;
- oid_par.information_buf = poidparam->data;
- oid_par.information_buf_len = poidparam->len;
- oid_par.dbg = 0;
-
- BytesWritten = 0;
- BytesNeeded = 0;
-
- if (bset) {
- oid_par.bytes_rw = &BytesRead;
- oid_par.bytes_needed = &BytesNeeded;
- oid_par.type_of_oid = SET_OID;
- } else {
- oid_par.bytes_rw = &BytesWritten;
- oid_par.bytes_needed = &BytesNeeded;
- oid_par.type_of_oid = QUERY_OID;
- }
-
- status = phandler->handler(&oid_par);
- } else {
- DBG_88E("rtw_mp_ioctl_hdl(): err!, subcode =%d, oid =%d, handler =%p\n",
- poidparam->subcode, phandler->oid, phandler->handler);
- ret = -EFAULT;
- goto _rtw_mp_ioctl_hdl_exit;
- }
- } else {
- rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
- }
-
- if (bset == 0x00) {/* query info */
- if (copy_to_user(p->pointer, pparmbuf, len))
- ret = -EFAULT;
- }
-
- if (status) {
- ret = -EFAULT;
- goto _rtw_mp_ioctl_hdl_exit;
- }
-
-_rtw_mp_ioctl_hdl_exit:
-
- kfree(pparmbuf);
- return ret;
-}
-
-static int rtw_get_ap_info(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- u32 cnt = 0, wpa_ielen;
- struct list_head *plist, *phead;
- unsigned char *pbuf;
- u8 bssid[ETH_ALEN];
- char data[32];
- struct wlan_network *pnetwork = NULL;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct iw_point *pdata = &wrqu->data;
-
- DBG_88E("+rtw_get_aplist_info\n");
-
- if ((padapter->bDriverStopped) || (pdata == NULL)) {
- ret = -EINVAL;
- goto exit;
- }
-
- while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) {
- msleep(30);
- cnt++;
- if (cnt > 100)
- break;
- }
- pdata->flags = 0;
- if (pdata->length >= 32) {
- if (copy_from_user(data, pdata->pointer, 32)) {
- ret = -EINVAL;
- goto exit;
- }
- } else {
- ret = -EINVAL;
- goto exit;
- }
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
-
- if (hwaddr_aton_i(data, bssid)) {
- DBG_88E("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 */
- DBG_88E("BSSID:%pM\n", (bssid));
-
- pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
- 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)) {
- pdata->flags = 2;
- break;
- }
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (pdata->length >= 34) {
- if (copy_to_user(pdata->pointer+32, (u8 *)&pdata->flags, 1)) {
- ret = -EINVAL;
- goto exit;
- }
- }
-
-exit:
-
- return ret;
-}
-
-static int rtw_set_pid(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
- int *pdata = (int *)wrqu;
- int selector;
-
- if ((padapter->bDriverStopped) || (pdata == NULL)) {
- ret = -EINVAL;
- goto exit;
- }
-
- selector = *pdata;
- if (selector < 3 && selector >= 0) {
- padapter->pid[selector] = *(pdata+1);
- ui_pid[selector] = *(pdata+1);
- DBG_88E("%s set pid[%d] =%d\n", __func__, selector, padapter->pid[selector]);
- } else {
- DBG_88E("%s selector %d error\n", __func__, selector);
- }
-exit:
- return ret;
-}
-
-static int rtw_wps_start(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct iw_point *pdata = &wrqu->data;
- u32 u32wps_start = 0;
-
- if ((padapter->bDriverStopped) || (pdata == NULL)) {
- ret = -EINVAL;
- goto exit;
- }
-
- ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
- if (ret) {
- ret = -EINVAL;
- goto exit;
- }
-
- if (u32wps_start == 0)
- u32wps_start = *extra;
-
- DBG_88E("[%s] wps_start = %d\n", __func__, u32wps_start);
-
- if (u32wps_start == 1) /* WPS Start */
- rtw_led_control(padapter, LED_CTL_START_WPS);
- else if (u32wps_start == 2) /* WPS Stop because of wps success */
- rtw_led_control(padapter, LED_CTL_STOP_WPS);
- else if (u32wps_start == 3) /* WPS Stop because of wps fail */
- rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
-
-exit:
- return ret;
-}
-
-#ifdef CONFIG_88EU_P2P
-static int rtw_wext_p2p_enable(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
-
- if (*extra == '0')
- init_role = P2P_ROLE_DISABLE;
- else if (*extra == '1')
- init_role = P2P_ROLE_DEVICE;
- else if (*extra == '2')
- init_role = P2P_ROLE_CLIENT;
- else if (*extra == '3')
- init_role = P2P_ROLE_GO;
-
- if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
- ret = -EFAULT;
- goto exit;
- }
-
- /* set channel/bandwidth */
- if (init_role != P2P_ROLE_DISABLE) {
- u8 channel, ch_offset;
- u16 bwmode;
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
- /* Stay at the listen state and wait for discovery. */
- channel = pwdinfo->listen_channel;
- pwdinfo->operating_channel = pwdinfo->listen_channel;
- ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- bwmode = HT_CHANNEL_WIDTH_20;
- } else {
- pwdinfo->operating_channel = pmlmeext->cur_channel;
-
- channel = pwdinfo->operating_channel;
- ch_offset = pmlmeext->cur_ch_offset;
- bwmode = pmlmeext->cur_bwmode;
- }
-
- set_channel_bwmode(padapter, channel, ch_offset, bwmode);
- }
-
-exit:
- return ret;
-}
-
-static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] ssid = %s, len = %zu\n", __func__, extra, strlen(extra));
- memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
- pwdinfo->nego_ssidlen = strlen(extra);
-
- return ret;
-}
-
-static int rtw_p2p_set_intent(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 intent = pwdinfo->intent;
-
- switch (wrqu->data.length) {
- case 1:
- intent = extra[0] - '0';
- break;
- case 2:
- intent = str_2char2num(extra[0], extra[1]);
- break;
- }
- if (intent <= 15)
- pwdinfo->intent = intent;
- else
- ret = -1;
- DBG_88E("[%s] intent = %d\n", __func__, intent);
- return ret;
-}
-
-static int rtw_p2p_set_listen_ch(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */
-
- switch (wrqu->data.length) {
- case 1:
- listen_ch = extra[0] - '0';
- break;
- case 2:
- listen_ch = str_2char2num(extra[0], extra[1]);
- break;
- }
-
- if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
- pwdinfo->listen_channel = listen_ch;
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- } else {
- ret = -1;
- }
-
- DBG_88E("[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel);
-
- return ret;
-}
-
-static int rtw_p2p_set_op_ch(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-/* Commented by Albert 20110524 */
-/* This function is used to set the operating channel if the driver will become the group owner */
-
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */
-
- switch (wrqu->data.length) {
- case 1:
- op_ch = extra[0] - '0';
- break;
- case 2:
- op_ch = str_2char2num(extra[0], extra[1]);
- break;
- }
-
- if (op_ch > 0)
- pwdinfo->operating_channel = op_ch;
- else
- ret = -1;
-
- DBG_88E("[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel);
-
- return ret;
-}
-
-static int rtw_p2p_profilefound(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- /* Comment by Albert 2010/10/13 */
- /* Input data format: */
- /* Ex: 0 */
- /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
- /* 0 => Reflush the profile record list. */
- /* 1 => Add the profile list */
- /* XX:XX:XX:XX:XX:XX => peer's MAC Address (ex: 00:E0:4C:00:00:01) */
- /* YY => SSID Length */
- /* SSID => SSID for persistence group */
-
- DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1);
-
- /* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- if (extra[0] == '0') {
- /* Remove all the profile information of wifidirect_info structure. */
- _rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
- pwdinfo->profileindex = 0;
- } else {
- if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) {
- ret = -1;
- } else {
- int jj, kk;
-
- /* Add this profile information into pwdinfo->profileinfo */
- /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
- for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
- pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
- pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0');
- memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen);
- pwdinfo->profileindex++;
- }
- }
- }
-
- return ret;
-}
-
-static int rtw_p2p_setDN(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] %s %d\n", __func__, extra, wrqu->data.length - 1);
- _rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
- memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
- pwdinfo->device_name_len = wrqu->data.length - 1;
-
- return ret;
-}
-
-static int rtw_p2p_get_status(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- if (padapter->bShowGetP2PState)
- DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
- pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
- pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
-
- /* Commented by Albert 2010/10/12 */
- /* Because of the output size limitation, I had removed the "Role" information. */
- /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
- sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
- wrqu->data.length = strlen(extra);
-
- return ret;
-}
-
-/* Commented by Albert 20110520 */
-/* This function will return the config method description */
-/* This config method description will show us which config method the remote P2P device is intended to use */
-/* by sending the provisioning discovery request frame. */
-
-static int rtw_p2p_get_req_cm(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_role(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
- pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
- pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
-
- sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
- rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
- pwdinfo->p2p_peer_interface_addr);
- sprintf(extra, "\nMAC %pM",
- pwdinfo->p2p_peer_interface_addr);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
- rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
- pwdinfo->rx_prov_disc_info.peerDevAddr);
- sprintf(extra, "\n%pM",
- pwdinfo->rx_prov_disc_info.peerDevAddr);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n",
- __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
- pwdinfo->p2p_peer_device_addr);
- sprintf(extra, "\nMAC %pM",
- pwdinfo->p2p_peer_device_addr);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_groupid(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
- pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
- pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
- pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
- pwdinfo->groupid_info.ssid);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_op_ch(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
-
- sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
- wrqu->data.length = strlen(extra);
- return ret;
-}
-
-static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- u8 peerMACStr[17] = {0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- u8 blnMatch = 0;
- u16 attr_content = 0;
- uint attr_contentlen = 0;
- /* 6 is the string "wpsCM=", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
- u8 attr_content_str[6 + 17] = {0x00};
-
- /* Commented by Albert 20110727 */
- /* The input data is the MAC address which the application wants to know its WPS config method. */
- /* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
- /* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
- if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17))
- return -EFAULT;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- u8 *wpsie;
- uint wpsie_len = 0;
- __be16 be_tmp;
-
- /* The mac address is matched. */
- wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
- if (wpsie) {
- rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *) &be_tmp, &attr_contentlen);
- if (attr_contentlen) {
- attr_content = be16_to_cpu(be_tmp);
- sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
- blnMatch = 1;
- }
- }
- break;
- }
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (!blnMatch)
- sprintf(attr_content_str, "\n\nM=0000");
-
- if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
- return -EFAULT;
- return ret;
-}
-
-static int rtw_p2p_get_go_device_address(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- u8 peerMACStr[17] = {0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- u8 blnMatch = 0;
- u8 *p2pie;
- uint p2pielen = 0, attr_contentlen = 0;
- u8 attr_content[100] = {0x00};
- u8 go_devadd_str[17 + 12] = {};
-
- /* Commented by Albert 20121209 */
- /* The input data is the GO's interface address which the application wants to know its device address. */
- /* Format: iwpriv wlanx p2p_get2 go_devadd = 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
- if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17))
- return -EFAULT;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- /* Commented by Albert 2011/05/18 */
- /* Match the device address located in the P2P IE */
- /* This is for the case that the P2P device address is not the same as the P2P interface address. */
-
- p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
- if (p2pie) {
- while (p2pie) {
- /* The P2P Device ID attribute is included in the Beacon frame. */
- /* The P2P Device Info attribute is included in the probe response frame. */
-
- _rtw_memset(attr_content, 0x00, 100);
- if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device ID attribute of Beacon first */
- blnMatch = 1;
- break;
- } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device Info attribute of probe response */
- blnMatch = 1;
- break;
- }
-
- /* Get the next P2P IE */
- p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
- }
- }
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (!blnMatch)
- snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=NULL");
- else
- snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
- attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
-
- if (copy_to_user(wrqu->data.pointer, go_devadd_str, sizeof(go_devadd_str)))
- return -EFAULT;
- return ret;
-}
-
-static int rtw_p2p_get_device_type(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- u8 peerMACStr[17] = {0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- u8 blnMatch = 0;
- u8 dev_type[8] = {0x00};
- uint dev_type_len = 0;
- u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
-
- /* Commented by Albert 20121209 */
- /* The input data is the MAC address which the application wants to know its device type. */
- /* Such user interface could know the device type. */
- /* Format: iwpriv wlanx p2p_get2 dev_type = 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
- if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17))
- return -EFAULT;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- u8 *wpsie;
- uint wpsie_len = 0;
-
- /* The mac address is matched. */
-
- wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12],
- pnetwork->network.IELength - 12,
- NULL, &wpsie_len);
- if (wpsie) {
- rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
- if (dev_type_len) {
- u16 type = 0;
- __be16 be_tmp;
-
- memcpy(&be_tmp, dev_type, 2);
- type = be16_to_cpu(be_tmp);
- sprintf(dev_type_str, "\n\nN=%.2d", type);
- blnMatch = 1;
- }
- }
- break;
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (!blnMatch)
- sprintf(dev_type_str, "\n\nN=00");
-
- if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
- return -EFAULT;
- }
-
- return ret;
-}
-
-static int rtw_p2p_get_device_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- u8 peerMACStr[17] = {0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- u8 blnMatch = 0;
- u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
- uint dev_len = 0;
- u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN=", we have to clear it at wrqu->data.pointer */
-
- /* Commented by Albert 20121225 */
- /* The input data is the MAC address which the application wants to know its device name. */
- /* Such user interface could show peer device's device name instead of ssid. */
- /* Format: iwpriv wlanx p2p_get2 devN = 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
- if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17))
- return -EFAULT;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- u8 *wpsie;
- uint wpsie_len = 0;
-
- /* The mac address is matched. */
- wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
- if (wpsie) {
- rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
- if (dev_len) {
- sprintf(dev_name_str, "\n\nN=%s", dev_name);
- blnMatch = 1;
- }
- }
- break;
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (!blnMatch)
- sprintf(dev_name_str, "\n\nN=0000");
-
- if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
- return -EFAULT;
- return ret;
-}
-
-static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- u8 peerMACStr[17] = {0x00};
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- u8 blnMatch = 0;
- u8 *p2pie;
- uint p2pielen = 0, attr_contentlen = 0;
- u8 attr_content[2] = {0x00};
-
- u8 inv_proc_str[17 + 8] = {0x00};
- /* +8 is for the str "InvProc=", we have to clear it at wrqu->data.pointer */
-
- /* Commented by Ouden 20121226 */
- /* The application wants to know P2P initiation procedure is supported or not. */
- /* Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
- if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17))
- return -EFAULT;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- /* Commented by Albert 20121226 */
- /* Match the device address located in the P2P IE */
- /* This is for the case that the P2P device address is not the same as the P2P interface address. */
-
- p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
- if (p2pie) {
- while (p2pie) {
- if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
- /* Handle the P2P capability attribute */
- blnMatch = 1;
- break;
- }
-
- /* Get the next P2P IE */
- p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
- }
- }
- }
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (!blnMatch) {
- sprintf(inv_proc_str, "\nIP=-1");
- } else {
- if (attr_content[0] & 0x20)
- sprintf(inv_proc_str, "\nIP=1");
- else
- sprintf(inv_proc_str, "\nIP=0");
- }
- if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
- return -EFAULT;
- return ret;
-}
-
-static int rtw_p2p_connect(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- uint uintPeerChannel = 0;
-
- /* Commented by Albert 20110304 */
- /* The input data contains two informations. */
- /* 1. First information is the MAC address which wants to formate with */
- /* 2. Second information is the WPS PINCode or "pbc" string for push button method */
- /* Format: 00:E0:4C:00:00:05 */
- /* Format: 00:E0:4C:00:00:05 */
-
- DBG_88E("[%s] data = %s\n", __func__, extra);
-
- if (pwdinfo->p2p_state == P2P_STATE_NONE) {
- DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
- return ret;
- }
-
- if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
- return -1;
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
- if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
- uintPeerChannel = pnetwork->network.Configuration.DSConfig;
- break;
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (uintPeerChannel) {
- _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
- _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
-
- pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
- memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
- pwdinfo->nego_req_info.benable = true;
-
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
- /* Restore to the listen state if the current p2p state is not nego OK */
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
- }
-
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
-
- DBG_88E("[%s] Start PreTx Procedure!\n", __func__);
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
- _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
- } else {
- DBG_88E("[%s] Not Found in Scanning Queue~\n", __func__);
- ret = -1;
- }
- return ret;
-}
-
-static int rtw_p2p_invite_req(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- int jj, kk;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- uint uintPeerChannel = 0;
- u8 attr_content[50] = {0x00};
- u8 *p2pie;
- uint p2pielen = 0, attr_contentlen = 0;
- struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
-
- /* The input data contains two informations. */
- /* 1. First information is the P2P device address which you want to send to. */
- /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
- /* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
- /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
-
- DBG_88E("[%s] data = %s\n", __func__, extra);
-
- if (wrqu->data.length <= 37) {
- DBG_88E("[%s] Wrong format!\n", __func__);
- return ret;
- }
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
- return ret;
- } else {
- /* Reset the content of struct tx_invite_req_info */
- pinvite_req_info->benable = false;
- _rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
- _rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
- pinvite_req_info->ssidlen = 0x00;
- pinvite_req_info->operating_ch = pwdinfo->operating_channel;
- _rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
- pinvite_req_info->token = 3;
- }
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
-
- /* Commented by Albert 2011/05/18 */
- /* Match the device address located in the P2P IE */
- /* This is for the case that the P2P device address is not the same as the P2P interface address. */
-
- p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
- if (p2pie) {
- /* The P2P Device ID attribute is included in the Beacon frame. */
- /* The P2P Device Info attribute is included in the probe response frame. */
-
- if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device ID attribute of Beacon first */
- if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
- uintPeerChannel = pnetwork->network.Configuration.DSConfig;
- break;
- }
- } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device Info attribute of probe response */
- if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
- uintPeerChannel = pnetwork->network.Configuration.DSConfig;
- break;
- }
- }
- }
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (uintPeerChannel) {
- /* Store the GO's bssid */
- for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
- pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
- /* Store the GO's ssid */
- pinvite_req_info->ssidlen = wrqu->data.length - 36;
- memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);
- pinvite_req_info->benable = true;
- pinvite_req_info->peer_ch = uintPeerChannel;
-
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
-
- set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
- _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
- } else {
- DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
- }
- return ret;
-}
-
-static int rtw_p2p_set_persistent(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- /* The input data is 0 or 1 */
- /* 0: disable persistent group functionality */
- /* 1: enable persistent group founctionality */
-
- DBG_88E("[%s] data = %s\n", __func__, extra);
-
- if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
- return ret;
- } else {
- if (extra[0] == '0') /* Disable the persistent group function. */
- pwdinfo->persistent_supported = false;
- else if (extra[0] == '1') /* Enable the persistent group function. */
- pwdinfo->persistent_supported = true;
- else
- pwdinfo->persistent_supported = false;
- }
- pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported);
- return ret;
-}
-
-static int rtw_p2p_prov_disc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
- u8 peerMAC[ETH_ALEN] = {0x00};
- int jj, kk;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct list_head *plist, *phead;
- struct __queue *queue = &(pmlmepriv->scanned_queue);
- struct wlan_network *pnetwork = NULL;
- uint uintPeerChannel = 0;
- u8 attr_content[100] = {0x00};
- u8 *p2pie;
- uint p2pielen = 0, attr_contentlen = 0;
-
- /* The input data contains two informations. */
- /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
- /* 2. Second information is the WPS configuration method which wants to discovery */
- /* Format: 00:E0:4C:00:00:05_display */
- /* Format: 00:E0:4C:00:00:05_keypad */
- /* Format: 00:E0:4C:00:00:05_pbc */
- /* Format: 00:E0:4C:00:00:05_label */
-
- DBG_88E("[%s] data = %s\n", __func__, extra);
-
- if (pwdinfo->p2p_state == P2P_STATE_NONE) {
- DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
- return ret;
- } else {
- /* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
- _rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
- _rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
- _rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid));
- pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
- pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
- pwdinfo->tx_prov_disc_info.benable = false;
- }
-
- for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
- peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
-
- if (!memcmp(&extra[18], "display", 7)) {
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
- } else if (!memcmp(&extra[18], "keypad", 7)) {
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
- } else if (!memcmp(&extra[18], "pbc", 3)) {
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
- } else if (!memcmp(&extra[18], "label", 5)) {
- pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
- } else {
- DBG_88E("[%s] Unknown WPS config methodn", __func__);
- return ret;
- }
-
- spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- while (1) {
- if (rtw_end_of_queue_search(phead, plist) == true)
- break;
-
- if (uintPeerChannel != 0)
- break;
-
- pnetwork = container_of(plist, struct wlan_network, list);
-
- /* Commented by Albert 2011/05/18 */
- /* Match the device address located in the P2P IE */
- /* This is for the case that the P2P device address is not the same as the P2P interface address. */
-
- p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
- if (p2pie) {
- while (p2pie) {
- /* The P2P Device ID attribute is included in the Beacon frame. */
- /* The P2P Device Info attribute is included in the probe response frame. */
-
- if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device ID attribute of Beacon first */
- if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
- uintPeerChannel = pnetwork->network.Configuration.DSConfig;
- break;
- }
- } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
- /* Handle the P2P Device Info attribute of probe response */
- if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
- uintPeerChannel = pnetwork->network.Configuration.DSConfig;
- break;
- }
- }
-
- /* Get the next P2P IE */
- p2pie = rtw_get_p2p_ie(p2pie+p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
- }
- }
-
- plist = plist->next;
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
- if (uintPeerChannel) {
- DBG_88E("[%s] peer channel: %d!\n", __func__, uintPeerChannel);
- memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
- memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
- pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;
- pwdinfo->tx_prov_disc_info.benable = true;
- rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
-
- if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
- memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
- } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
- memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
- pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
- }
-
- set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
-
- _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
-
- _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
- } else {
- DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
- }
- return ret;
-}
-
-/* This function is used to inform the driver the user had specified the pin code value or pbc */
-/* to application. */
-
-static int rtw_p2p_got_wpsinfo(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-
- DBG_88E("[%s] data = %s\n", __func__, extra);
- /* Added by Albert 20110328 */
- /* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
- /* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
- /* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
- /* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
-
- if (*extra == '0')
- pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
- else if (*extra == '1')
- pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
- else if (*extra == '2')
- pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
- else if (*extra == '3')
- pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
- else
- pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
- return ret;
-}
-
-#endif /* CONFIG_88EU_P2P */
-
-static int rtw_p2p_set(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-
-#ifdef CONFIG_88EU_P2P
- DBG_88E("[%s] extra = %s\n", __func__, extra);
- if (!memcmp(extra, "enable=", 7)) {
- rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "setDN=", 6)) {
- wrqu->data.length -= 6;
- rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "profilefound=", 13)) {
- wrqu->data.length -= 13;
- rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
- } else if (!memcmp(extra, "prov_disc=", 10)) {
- wrqu->data.length -= 10;
- rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
- } else if (!memcmp(extra, "nego=", 5)) {
- wrqu->data.length -= 5;
- rtw_p2p_connect(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "intent=", 7)) {
- /* Commented by Albert 2011/03/23 */
- /* The wrqu->data.length will include the null character */
- /* So, we will decrease 7 + 1 */
- wrqu->data.length -= 8;
- rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "ssid=", 5)) {
- wrqu->data.length -= 5;
- rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "got_wpsinfo=", 12)) {
- wrqu->data.length -= 12;
- rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
- } else if (!memcmp(extra, "listen_ch=", 10)) {
- /* Commented by Albert 2011/05/24 */
- /* The wrqu->data.length will include the null character */
- /* So, we will decrease (10 + 1) */
- wrqu->data.length -= 11;
- rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
- } else if (!memcmp(extra, "op_ch=", 6)) {
- /* Commented by Albert 2011/05/24 */
- /* The wrqu->data.length will include the null character */
- /* So, we will decrease (6 + 1) */
- wrqu->data.length -= 7;
- rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "invite=", 7)) {
- wrqu->data.length -= 8;
- rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "persistent=", 11)) {
- wrqu->data.length -= 11;
- rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
- }
-#endif /* CONFIG_88EU_P2P */
-
- return ret;
-}
-
-static int rtw_p2p_get(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-
-#ifdef CONFIG_88EU_P2P
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
- if (padapter->bShowGetP2PState)
- DBG_88E("[%s] extra = %s\n", __func__,
- (char __user *)wrqu->data.pointer);
- if (!memcmp((__force const char *)wrqu->data.pointer,
- "status", 6)) {
- rtw_p2p_get_status(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "role", 4)) {
- rtw_p2p_get_role(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "peer_ifa", 8)) {
- rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "req_cm", 6)) {
- rtw_p2p_get_req_cm(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "peer_deva", 9)) {
- /* Get the P2P device address when receiving the provision discovery request frame. */
- rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "group_id", 8)) {
- rtw_p2p_get_groupid(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "peer_deva_inv", 13)) {
- /* Get the P2P device address when receiving the P2P Invitation request frame. */
- rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
- } else if (!memcmp((__force const char *)wrqu->data.pointer,
- "op_ch", 5)) {
- rtw_p2p_get_op_ch(dev, info, wrqu, extra);
- }
-#endif /* CONFIG_88EU_P2P */
- return ret;
-}
-
-static int rtw_p2p_get2(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
-
-#ifdef CONFIG_88EU_P2P
- DBG_88E("[%s] extra = %s\n", __func__,
- (char __user *)wrqu->data.pointer);
- if (!memcmp(extra, "wpsCM =", 6)) {
- wrqu->data.length -= 6;
- rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "devN =", 5)) {
- wrqu->data.length -= 5;
- rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "dev_type =", 9)) {
- wrqu->data.length -= 9;
- rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]);
- } else if (!memcmp(extra, "go_devadd =", 10)) {
- wrqu->data.length -= 10;
- rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]);
- } else if (!memcmp(extra, "InvProc =", 8)) {
- wrqu->data.length -= 8;
- rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]);
- }
-
-#endif /* CONFIG_88EU_P2P */
-
- return ret;
-}
-
-static int rtw_cta_test_start(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- DBG_88E("%s %s\n", __func__, extra);
- if (!strcmp(extra, "1"))
- padapter->in_cta_test = 1;
- else
- padapter->in_cta_test = 0;
-
- if (padapter->in_cta_test) {
- u32 v = rtw_read32(padapter, REG_RCR);
- v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* RCR_ADF */
- rtw_write32(padapter, REG_RCR, v);
- DBG_88E("enable RCR_ADF\n");
- } else {
- u32 v = rtw_read32(padapter, REG_RCR);
- v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/* RCR_ADF */
- rtw_write32(padapter, REG_RCR, v);
- DBG_88E("disable RCR_ADF\n");
- }
- return ret;
-}
-
-static int rtw_rereg_nd_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
- struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
- char new_ifname[IFNAMSIZ];
-
- if (rereg_priv->old_ifname[0] == 0) {
- char *reg_ifname;
- reg_ifname = padapter->registrypriv.if2name;
-
- strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
- rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
- }
-
- if (wrqu->data.length > IFNAMSIZ)
- return -EFAULT;
-
- if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
- return -EFAULT;
-
- if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
- return ret;
-
- DBG_88E("%s new_ifname:%s\n", __func__, new_ifname);
- ret = rtw_change_ifname(padapter, new_ifname);
- if (0 != ret)
- goto exit;
-
- if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
- padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
- rtw_hal_sw_led_init(padapter);
- rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
- }
-
- strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
- rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
-
- if (!memcmp(new_ifname, "disable%d", 9)) {
- DBG_88E("%s disable\n", __func__);
- /* free network queue for Android's timming issue */
- rtw_free_network_queue(padapter, true);
-
- /* close led */
- rtw_led_control(padapter, LED_CTL_POWER_OFF);
- rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
- padapter->ledpriv.bRegUseLed = false;
- rtw_hal_sw_led_deinit(padapter);
-
- /* the interface is being "disabled", we can do deeper IPS */
- rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
- rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
- }
-exit:
- return ret;
-}
-
-static void mac_reg_dump(struct adapter *padapter)
-{
- int i, j = 1;
- pr_info("\n ======= MAC REG =======\n");
- for (i = 0x0; i < 0x300; i += 4) {
- if (j%4 == 1)
- pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
- if ((j++)%4 == 0)
- pr_info("\n");
- }
- for (i = 0x400; i < 0x800; i += 4) {
- if (j%4 == 1)
- pr_info("0x%02x", i);
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
- if ((j++)%4 == 0)
- pr_info("\n");
- }
-}
-
-static void bb_reg_dump(struct adapter *padapter)
-{
- int i, j = 1;
- pr_info("\n ======= BB REG =======\n");
- for (i = 0x800; i < 0x1000; i += 4) {
- if (j%4 == 1)
- pr_info("0x%02x", i);
-
- pr_info(" 0x%08x ", rtw_read32(padapter, i));
- if ((j++)%4 == 0)
- pr_info("\n");
- }
-}
-
-static void rf_reg_dump(struct adapter *padapter)
-{
- int i, j = 1, path;
- u32 value;
- u8 rf_type, path_nums = 0;
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
-
- pr_info("\n ======= RF REG =======\n");
- if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type))
- path_nums = 1;
- else
- path_nums = 2;
-
- for (path = 0; path < path_nums; path++) {
- pr_info("\nRF_Path(%x)\n", path);
- for (i = 0; i < 0x100; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- pr_info("0x%02x ", i);
- pr_info(" 0x%08x ", value);
- if ((j++)%4 == 0)
- pr_info("\n");
- }
- }
-}
-
-static int rtw_dbg_port(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- u8 major_cmd, minor_cmd;
- u16 arg;
- s32 extra_arg;
- u32 *pdata, val32;
- struct sta_info *psta;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct wlan_network *cur_network = &(pmlmepriv->cur_network);
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- pdata = (u32 *)&wrqu->data;
-
- val32 = *pdata;
- arg = (u16)(val32 & 0x0000ffff);
- major_cmd = (u8)(val32 >> 24);
- minor_cmd = (u8)((val32 >> 16) & 0x00ff);
-
- extra_arg = *(pdata+1);
-
- switch (major_cmd) {
- case 0x70:/* read_reg */
- switch (minor_cmd) {
- case 1:
- DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
- break;
- case 2:
- DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
- break;
- case 4:
- DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
- break;
- }
- break;
- case 0x71:/* write_reg */
- switch (minor_cmd) {
- case 1:
- rtw_write8(padapter, arg, extra_arg);
- DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
- break;
- case 2:
- rtw_write16(padapter, arg, extra_arg);
- DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
- break;
- case 4:
- rtw_write32(padapter, arg, extra_arg);
- DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
- break;
- }
- break;
- case 0x72:/* read_bb */
- DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
- break;
- case 0x73:/* write_bb */
- rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
- DBG_88E("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
- break;
- case 0x74:/* read_rf */
- DBG_88E("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
- break;
- case 0x75:/* write_rf */
- rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
- DBG_88E("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
- break;
-
- case 0x76:
- switch (minor_cmd) {
- case 0x00: /* normal mode, */
- padapter->recvpriv.is_signal_dbg = 0;
- break;
- case 0x01: /* dbg mode */
- padapter->recvpriv.is_signal_dbg = 1;
- extra_arg = extra_arg > 100 ? 100 : extra_arg;
- extra_arg = extra_arg < 0 ? 0 : extra_arg;
- padapter->recvpriv.signal_strength_dbg = extra_arg;
- break;
- }
- break;
- case 0x78: /* IOL test */
- switch (minor_cmd) {
- case 0x04: /* LLT table initialization test */
- {
- u8 page_boundary = 0xf9;
- struct xmit_frame *xmit_frame;
-
- xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
- if (xmit_frame == NULL) {
- ret = -ENOMEM;
- break;
- }
-
- rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
-
- if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
- ret = -EPERM;
- }
- break;
- case 0x05: /* blink LED test */
- {
- u16 reg = 0x4c;
- u32 blink_num = 50;
- u32 blink_delay_ms = 200;
- int i;
- struct xmit_frame *xmit_frame;
-
- xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
- if (xmit_frame == NULL) {
- ret = -ENOMEM;
- break;
- }
-
- for (i = 0; i < blink_num; i++) {
- rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
- rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
- rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
- rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
- }
- if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200, 0))
- ret = -EPERM;
- }
- break;
-
- case 0x06: /* continuous write byte test */
- {
- u16 reg = arg;
- u16 start_value = 0;
- u32 write_num = extra_arg;
- int i;
- u8 final;
- struct xmit_frame *xmit_frame;
-
- xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
- if (xmit_frame == NULL) {
- ret = -ENOMEM;
- break;
- }
-
- for (i = 0; i < write_num; i++)
- rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value, 0xFF);
- if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
- ret = -EPERM;
-
- final = rtw_read8(padapter, reg);
- if (start_value+write_num-1 == final)
- DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
- else
- DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
- }
- break;
-
- case 0x07: /* continuous write word test */
- {
- u16 reg = arg;
- u16 start_value = 200;
- u32 write_num = extra_arg;
-
- int i;
- u16 final;
- struct xmit_frame *xmit_frame;
-
- xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
- if (xmit_frame == NULL) {
- ret = -ENOMEM;
- break;
- }
-
- for (i = 0; i < write_num; i++)
- rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value, 0xFFFF);
- if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
- ret = -EPERM;
-
- final = rtw_read16(padapter, reg);
- if (start_value+write_num-1 == final)
- DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
- else
- DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
- }
- break;
- case 0x08: /* continuous write dword test */
- {
- u16 reg = arg;
- u32 start_value = 0x110000c7;
- u32 write_num = extra_arg;
-
- int i;
- u32 final;
- struct xmit_frame *xmit_frame;
-
- xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
- if (xmit_frame == NULL) {
- ret = -ENOMEM;
- break;
- }
-
- for (i = 0; i < write_num; i++)
- rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value, 0xFFFFFFFF);
- if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
- ret = -EPERM;
-
- final = rtw_read32(padapter, reg);
- if (start_value+write_num-1 == final)
- DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
- reg, write_num, start_value, final);
- else
- DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n",
- reg, write_num, start_value, final);
- }
- break;
- }
- break;
- case 0x79:
- {
- /*
- * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
- * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
- */
- u8 value = extra_arg & 0x0f;
- u8 sign = minor_cmd;
- u16 write_value = 0;
-
- DBG_88E("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
-
- if (sign)
- value = value | 0x10;
-
- write_value = value | (value << 5);
- rtw_write16(padapter, 0x6d9, write_value);
- }
- break;
- case 0x7a:
- receive_disconnect(padapter, pmlmeinfo->network.MacAddress
- , WLAN_REASON_EXPIRATION_CHK);
- break;
- case 0x7F:
- switch (minor_cmd) {
- case 0x0:
- DBG_88E("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
- break;
- case 0x01:
- DBG_88E("auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n",
- psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
- psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
- break;
- case 0x02:
- DBG_88E("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state);
- break;
- case 0x03:
- DBG_88E("qos_option =%d\n", pmlmepriv->qospriv.qos_option);
- DBG_88E("ht_option =%d\n", pmlmepriv->htpriv.ht_option);
- break;
- case 0x04:
- DBG_88E("cur_ch =%d\n", pmlmeext->cur_channel);
- DBG_88E("cur_bw =%d\n", pmlmeext->cur_bwmode);
- DBG_88E("cur_ch_off =%d\n", pmlmeext->cur_ch_offset);
- break;
- case 0x05:
- psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
- if (psta) {
- int i;
- struct recv_reorder_ctrl *preorder_ctrl;
-
- DBG_88E("SSID =%s\n", cur_network->network.Ssid.Ssid);
- DBG_88E("sta's macaddr: %pM\n", psta->hwaddr);
- DBG_88E("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
- DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
- DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
- DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
- DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
- DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
- DBG_88E("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++) {
- preorder_ctrl = &psta->recvreorder_ctrl[i];
- if (preorder_ctrl->enable)
- DBG_88E("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
- }
- } else {
- DBG_88E("can't get sta's macaddr, cur_network's macaddr:%pM\n", (cur_network->network.MacAddress));
- }
- break;
- case 0x06:
- {
- u32 ODMFlag;
- rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
- DBG_88E("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg);
- ODMFlag = (u32)(0x0f&arg);
- DBG_88E("(A)DMFlag = 0x%x\n", ODMFlag);
- rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
- }
- break;
- case 0x07:
- DBG_88E("bSurpriseRemoved =%d, bDriverStopped =%d\n",
- padapter->bSurpriseRemoved, padapter->bDriverStopped);
- break;
- case 0x08:
- {
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- DBG_88E("free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d, free_xmit_extbuf_cnt =%d\n",
- pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt);
- DBG_88E("rx_urb_pending_cn =%d\n", precvpriv->rx_pending_cnt);
- }
- break;
- case 0x09:
- {
- int i, j;
- struct list_head *plist, *phead;
- struct recv_reorder_ctrl *preorder_ctrl;
-
-#ifdef CONFIG_88EU_AP_MODE
- DBG_88E("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
-#endif
- spin_lock_bh(&pstapriv->sta_hash_lock);
-
- for (i = 0; i < NUM_STA; i++) {
- phead = &(pstapriv->sta_hash[i]);
- plist = phead->next;
-
- while ((rtw_end_of_queue_search(phead, plist)) == false) {
- psta = container_of(plist, struct sta_info, hash_list);
-
- plist = plist->next;
-
- if (extra_arg == psta->aid) {
- DBG_88E("sta's macaddr:%pM\n", (psta->hwaddr));
- DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
- DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
- DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
- DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
- DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
- DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
-
-#ifdef CONFIG_88EU_AP_MODE
- DBG_88E("capability = 0x%x\n", psta->capability);
- DBG_88E("flags = 0x%x\n", psta->flags);
- DBG_88E("wpa_psk = 0x%x\n", psta->wpa_psk);
- DBG_88E("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher);
- DBG_88E("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher);
- DBG_88E("qos_info = 0x%x\n", psta->qos_info);
-#endif
- DBG_88E("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy);
-
- for (j = 0; j < 16; j++) {
- preorder_ctrl = &psta->recvreorder_ctrl[j];
- if (preorder_ctrl->enable)
- DBG_88E("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
- }
- }
- }
- }
- spin_unlock_bh(&pstapriv->sta_hash_lock);
- }
- break;
- case 0x0c:/* dump rx/tx packet */
- if (arg == 0) {
- DBG_88E("dump rx packet (%d)\n", extra_arg);
- rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
- } else if (arg == 1) {
- DBG_88E("dump tx packet (%d)\n", extra_arg);
- rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
- }
- break;
- case 0x0f:
- if (extra_arg == 0) {
- DBG_88E("###### silent reset test.......#####\n");
- rtw_hal_sreset_reset(padapter);
- }
- break;
- case 0x15:
- {
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- DBG_88E("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
- }
- break;
- case 0x10:/* driver version display */
- DBG_88E("rtw driver version =%s\n", DRIVERVERSION);
- break;
- case 0x11:
- DBG_88E("turn %s Rx RSSI display function\n", (extra_arg == 1) ? "on" : "off");
- padapter->bRxRSSIDisplay = extra_arg;
- rtw_hal_set_def_var(padapter, HW_DEF_FA_CNT_DUMP, &extra_arg);
- break;
- case 0x12: /* set rx_stbc */
- {
- 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)
- break;
- if (extra_arg >= 0 && extra_arg <= 3) {
- pregpriv->rx_stbc = extra_arg;
- DBG_88E("set rx_stbc =%d\n", pregpriv->rx_stbc);
- } else {
- DBG_88E("get rx_stbc =%d\n", pregpriv->rx_stbc);
- }
- }
- break;
- case 0x13: /* set ampdu_enable */
- {
- 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)
- break;
- if (extra_arg >= 0 && extra_arg < 3) {
- pregpriv->ampdu_enable = extra_arg;
- DBG_88E("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
- } else {
- DBG_88E("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
- }
- }
- break;
- case 0x14: /* get wifi_spec */
- {
- struct registry_priv *pregpriv = &padapter->registrypriv;
- DBG_88E("get wifi_spec =%d\n", pregpriv->wifi_spec);
- }
- break;
- case 0x16:
- if (arg == 0xff) {
- pr_info("ODM_COMP_DIG\t\tBIT0\n");
- pr_info("ODM_COMP_RA_MASK\t\tBIT1\n");
- pr_info("ODM_COMP_DYNAMIC_TXPWR\tBIT2\n");
- pr_info("ODM_COMP_FA_CNT\t\tBIT3\n");
- pr_info("ODM_COMP_RSSI_MONITOR\tBIT4\n");
- pr_info("ODM_COMP_CCK_PD\t\tBIT5\n");
- pr_info("ODM_COMP_ANT_DIV\t\tBIT6\n");
- pr_info("ODM_COMP_PWR_SAVE\t\tBIT7\n");
- pr_info("ODM_COMP_PWR_TRAIN\tBIT8\n");
- pr_info("ODM_COMP_RATE_ADAPTIVE\tBIT9\n");
- pr_info("ODM_COMP_PATH_DIV\t\tBIT10\n");
- pr_info("ODM_COMP_PSD \tBIT11\n");
- pr_info("ODM_COMP_DYNAMIC_PRICCA\tBIT12\n");
- pr_info("ODM_COMP_RXHP\t\tBIT13\n");
- pr_info("ODM_COMP_EDCA_TURBO\tBIT16\n");
- pr_info("ODM_COMP_EARLY_MODE\tBIT17\n");
- pr_info("ODM_COMP_TX_PWR_TRACK\tBIT24\n");
- pr_info("ODM_COMP_RX_GAIN_TRACK\tBIT25\n");
- pr_info("ODM_COMP_CALIBRATION\tBIT26\n");
- rtw_hal_get_def_var(padapter, HW_DEF_ODM_DBG_FLAG, &extra_arg);
- } else {
- rtw_hal_set_def_var(padapter, HW_DEF_ODM_DBG_FLAG, &extra_arg);
- }
- break;
- case 0x23:
- DBG_88E("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
- padapter->bNotifyChannelChange = extra_arg;
- break;
- case 0x24:
-#ifdef CONFIG_88EU_P2P
- DBG_88E("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
- padapter->bShowGetP2PState = extra_arg;
-#endif /* CONFIG_88EU_P2P */
- break;
- case 0xaa:
- if (extra_arg > 0x13)
- extra_arg = 0xFF;
- DBG_88E("chang data rate to :0x%02x\n", extra_arg);
- padapter->fix_rate = extra_arg;
- break;
- case 0xdd:/* registers dump, 0 for mac reg, 1 for bb reg, 2 for rf reg */
- if (extra_arg == 0)
- mac_reg_dump(padapter);
- else if (extra_arg == 1)
- bb_reg_dump(padapter);
- else if (extra_arg == 2)
- rf_reg_dump(padapter);
- break;
- case 0xee:/* turn on/off dynamic funcs */
- {
- u32 odm_flag;
-
- if (0xf == extra_arg) {
- rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
- DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
- DBG_88E("extra_arg = 0 - disable all dynamic func\n");
- DBG_88E("extra_arg = 1 - disable DIG- BIT(0)\n");
- DBG_88E("extra_arg = 2 - disable High power - BIT(1)\n");
- DBG_88E("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
- DBG_88E("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
- DBG_88E("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
- DBG_88E("extra_arg = 6 - enable all dynamic func\n");
- } else {
- /* extra_arg = 0 - disable all dynamic func
- extra_arg = 1 - disable DIG
- extra_arg = 2 - disable tx power tracking
- extra_arg = 3 - turn on all dynamic func
- */
- rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
- rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
- DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
- }
- }
- break;
-
- case 0xfd:
- rtw_write8(padapter, 0xc50, arg);
- DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
- rtw_write8(padapter, 0xc58, arg);
- DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
- break;
- case 0xfe:
- DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
- DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
- break;
- case 0xff:
- DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
- DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
- DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
- DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
- DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
-
- DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
-
- DBG_88E("\n");
-
- DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
- DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
-
- DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
-
- DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
-
- DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
- DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
-
- DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
- DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
- DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
- DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
- break;
- }
- break;
- default:
- DBG_88E("error dbg cmd!\n");
- break;
- }
- return ret;
-}
-
static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
{
uint ret = 0;
@@ -4766,13 +2118,13 @@ static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
- ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (ph2c == NULL) {
res = _FAIL;
goto exit;
}
- psetstakey_para = (struct set_stakey_parm *)rtw_zmalloc(sizeof(struct set_stakey_parm));
+ psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
if (psetstakey_para == NULL) {
kfree(ph2c);
res = _FAIL;
@@ -4804,19 +2156,19 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
DBG_88E("%s\n", __func__);
- pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (pcmd == NULL) {
res = _FAIL;
goto exit;
}
- psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
+ psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
if (psetkeyparm == NULL) {
kfree(pcmd);
res = _FAIL;
goto exit;
}
- _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
+ memset(psetkeyparm, 0, sizeof(struct setkey_parm));
psetkeyparm->keyid = (u8)keyid;
@@ -4846,7 +2198,7 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- _rtw_init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
res = rtw_enqueue_cmd(pcmdpriv, pcmd);
@@ -4931,7 +2283,7 @@ static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param,
goto exit;
}
- _rtw_memset(pwep, 0, wep_total_len);
+ memset(pwep, 0, wep_total_len);
pwep->KeyLength = wep_key_len;
pwep->Length = wep_total_len;
@@ -5221,8 +2573,8 @@ static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
if (psta) {
spin_lock_bh(&pstapriv->asoc_list_lock);
- if (!rtw_is_list_empty(&psta->asoc_list)) {
- rtw_list_delete(&psta->asoc_list);
+ if (!list_empty(&psta->asoc_list)) {
+ list_del_init(&psta->asoc_list);
pstapriv->asoc_list_cnt--;
updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
}
@@ -5664,1927 +3016,6 @@ FREE_EXT:
return ret;
}
-static int rtw_pm_set(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- unsigned mode = 0;
- struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
- DBG_88E("[%s] extra = %s\n", __func__, extra);
-
- if (!memcmp(extra, "lps =", 4)) {
- ret = sscanf(extra+4, "%u", &mode);
- if (ret != 1)
- return -EINVAL;
- ret = rtw_pm_set_lps(padapter, mode);
- } else if (!memcmp(extra, "ips =", 4)) {
- ret = sscanf(extra+4, "%u", &mode);
- if (ret != 1)
- return -EINVAL;
- ret = rtw_pm_set_ips(padapter, mode);
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static int rtw_mp_efuse_get(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wdata, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
- struct hal_data_8188e *haldata = GET_HAL_DATA(padapter);
- struct efuse_hal *pEfuseHal;
- struct iw_point *wrqu;
-
- u8 *PROMContent = pEEPROM->efuse_eeprom_data;
- u8 ips_mode = 0, lps_mode = 0;
- struct pwrctrl_priv *pwrctrlpriv;
- u8 *data = NULL;
- u8 *rawdata = NULL;
- char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL};
- u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
- u16 max_available_size = 0, raw_cursize = 0, raw_maxsize = 0;
- int err;
- u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
-
- wrqu = (struct iw_point *)wdata;
- pwrctrlpriv = &padapter->pwrctrlpriv;
- pEfuseHal = &haldata->EfuseHal;
-
- err = 0;
- data = _rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
- if (data == NULL) {
- err = -ENOMEM;
- goto exit;
- }
- rawdata = _rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
- if (rawdata == NULL) {
- err = -ENOMEM;
- goto exit;
- }
-
- if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
- err = -EFAULT;
- goto exit;
- }
- lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
- rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
-
- ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
- rtw_pm_set_ips(padapter, IPS_NONE);
-
- pch = extra;
- DBG_88E("%s: in =%s\n", __func__, extra);
-
- i = 0;
- /* mac 16 "00e04c871200" rmap, 00, 2 */
- while ((token = strsep(&pch, ",")) != NULL) {
- if (i > 2)
- break;
- tmp[i] = token;
- i++;
- }
- padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */
-
- if (strcmp(tmp[0], "status") == 0) {
- sprintf(extra, "Load File efuse =%s, Load File MAC =%s", (pEEPROM->bloadfile_fail_flag ? "FAIL" : "OK"), (pEEPROM->bloadmac_fail_flag ? "FAIL" : "OK"));
-
- goto exit;
- } else if (strcmp(tmp[0], "filemap") == 0) {
- mapLen = EFUSE_MAP_SIZE;
-
- sprintf(extra, "\n");
- for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
- sprintf(extra, "%s0x%02x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "realmap") == 0) {
- mapLen = EFUSE_MAP_SIZE;
- if (rtw_efuse_map_read(padapter, 0, mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) {
- DBG_88E("%s: read realmap Fail!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- sprintf(extra, "\n");
- for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
- sprintf(extra, "%s0x%02x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "rmap") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- DBG_88E("%s: rmap Fail!! Parameters error!\n", __func__);
- err = -EINVAL;
- goto exit;
- }
-
- /* rmap addr cnts */
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- DBG_88E("%s: addr =%x\n", __func__, addr);
-
- cnts = simple_strtoul(tmp[2], &ptmp, 10);
- if (cnts == 0) {
- DBG_88E("%s: rmap Fail!! cnts error!\n", __func__);
- err = -EINVAL;
- goto exit;
- }
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr + cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EINVAL;
- goto exit;
- }
-
- if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_read error!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- *extra = 0;
- for (i = 0; i < cnts; i++)
- sprintf(extra, "%s0x%02X ", extra, data[i]);
- } else if (strcmp(tmp[0], "realraw") == 0) {
- addr = 0;
- mapLen = EFUSE_MAX_SIZE;
- if (rtw_efuse_access(padapter, false, addr, mapLen, rawdata) == _FAIL) {
- DBG_88E("%s: rtw_efuse_access Fail!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- sprintf(extra, "\n");
- for (i = 0; i < mapLen; i++) {
- sprintf(extra, "%s%02X", extra, rawdata[i]);
-
- if ((i & 0xF) == 0xF)
- sprintf(extra, "%s\n", extra);
- else if ((i & 0x7) == 0x7)
- sprintf(extra, "%s\t", extra);
- else
- sprintf(extra, "%s ", extra);
- }
- } else if (strcmp(tmp[0], "mac") == 0) {
- cnts = 6;
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr + cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_read error!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- *extra = 0;
- for (i = 0; i < cnts; i++) {
- sprintf(extra, "%s%02X", extra, data[i]);
- if (i != (cnts-1))
- sprintf(extra, "%s:", extra);
- }
- } else if (strcmp(tmp[0], "vidpid") == 0) {
- cnts = 4;
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr + cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
- if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
- DBG_88E("%s: rtw_efuse_access error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- *extra = 0;
- for (i = 0; i < cnts; i++) {
- sprintf(extra, "%s0x%02X", extra, data[i]);
- if (i != (cnts-1))
- sprintf(extra, "%s,", extra);
- }
- } else if (strcmp(tmp[0], "ableraw") == 0) {
- efuse_GetCurrentSize(padapter, &raw_cursize);
- raw_maxsize = efuse_GetMaxSize(padapter);
- sprintf(extra, "[available raw size] = %d bytes", raw_maxsize-raw_cursize);
- } else if (strcmp(tmp[0], "btfmap") == 0) {
- mapLen = EFUSE_BT_MAX_MAP_LEN;
- if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
- DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- sprintf(extra, "\n");
- for (i = 0; i < 512; i += 16) {
- /* set 512 because the iwpriv's extra size have limit 0x7FF */
- sprintf(extra, "%s0x%03x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "btbmap") == 0) {
- mapLen = EFUSE_BT_MAX_MAP_LEN;
- if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
- DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- sprintf(extra, "\n");
- for (i = 512; i < 1024; i += 16) {
- sprintf(extra, "%s0x%03x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "btrmap") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- /* rmap addr cnts */
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
-
- cnts = simple_strtoul(tmp[2], &ptmp, 10);
- if (cnts == 0) {
- DBG_88E("%s: btrmap Fail!! cnts error!\n", __func__);
- err = -EINVAL;
- goto exit;
- }
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr + cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
- DBG_88E("%s: rtw_BT_efuse_map_read error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
-
- *extra = 0;
- for (i = 0; i < cnts; i++)
- sprintf(extra, "%s 0x%02X ", extra, data[i]);
- } else if (strcmp(tmp[0], "btffake") == 0) {
- sprintf(extra, "\n");
- for (i = 0; i < 512; i += 16) {
- sprintf(extra, "%s0x%03x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "btbfake") == 0) {
- sprintf(extra, "\n");
- for (i = 512; i < 1024; i += 16) {
- sprintf(extra, "%s0x%03x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else if (strcmp(tmp[0], "wlrfkmap") == 0) {
- sprintf(extra, "\n");
- for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
- sprintf(extra, "%s0x%02x\t", extra, i);
- for (j = 0; j < 8; j++)
- sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\t", extra);
- for (; j < 16; j++)
- sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
- sprintf(extra, "%s\n", extra);
- }
- } else {
- sprintf(extra, "Command not found!");
- }
-
-exit:
- kfree(data);
- kfree(rawdata);
- if (!err)
- wrqu->length = strlen(extra);
-
- rtw_pm_set_ips(padapter, ips_mode);
- rtw_pm_set_lps(padapter, lps_mode);
- padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
- return err;
-}
-
-static int rtw_mp_efuse_set(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wdata, char *extra)
-{
- struct adapter *padapter;
- struct pwrctrl_priv *pwrctrlpriv;
- struct hal_data_8188e *haldata;
- struct efuse_hal *pEfuseHal;
-
- u8 ips_mode = 0, lps_mode = 0;
- u32 i, jj, kk;
- u8 *setdata = NULL;
- u8 *ShadowMapBT = NULL;
- u8 *ShadowMapWiFi = NULL;
- u8 *setrawdata = NULL;
- char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL};
- u16 addr = 0, cnts = 0, max_available_size = 0;
- int err;
-
- padapter = rtw_netdev_priv(dev);
- pwrctrlpriv = &padapter->pwrctrlpriv;
- haldata = GET_HAL_DATA(padapter);
- pEfuseHal = &haldata->EfuseHal;
- err = 0;
- setdata = _rtw_zmalloc(1024);
- if (setdata == NULL) {
- err = -ENOMEM;
- goto exit;
- }
- ShadowMapBT = _rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
- if (ShadowMapBT == NULL) {
- err = -ENOMEM;
- goto exit;
- }
- ShadowMapWiFi = _rtw_malloc(EFUSE_MAP_SIZE);
- if (ShadowMapWiFi == NULL) {
- err = -ENOMEM;
- goto exit;
- }
- setrawdata = _rtw_malloc(EFUSE_MAX_SIZE);
- if (setrawdata == NULL) {
- err = -ENOMEM;
- goto exit;
- }
-
- lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
- rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
-
- ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
- rtw_pm_set_ips(padapter, IPS_NONE);
-
- pch = extra;
- DBG_88E("%s: in =%s\n", __func__, extra);
-
- i = 0;
- while ((token = strsep(&pch, ",")) != NULL) {
- if (i > 2)
- break;
- tmp[i] = token;
- i++;
- }
-
- /* tmp[0],[1],[2] */
- /* wmap, addr, 00e04c871200 */
- if (strcmp(tmp[0], "wmap") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- addr &= 0xFFF;
-
- cnts = strlen(tmp[2]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: map data =%s\n", __func__, tmp[2]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
- /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
- if ((addr+cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "wraw") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- addr &= 0xFFF;
-
- cnts = strlen(tmp[2]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: raw data =%s\n", __func__, tmp[2]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
-
- if (rtw_efuse_access(padapter, true, addr, cnts, setrawdata) == _FAIL) {
- DBG_88E("%s: rtw_efuse_access error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "mac") == 0) {
- if (tmp[1] == NULL) {
- err = -EINVAL;
- goto exit;
- }
-
- /* mac, 00e04c871200 */
- addr = EEPROM_MAC_ADDR_88EU;
- cnts = strlen(tmp[1]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
- if (cnts > 6) {
- DBG_88E("%s: error data for mac addr =\"%s\"\n", __func__, tmp[1]);
- err = -EFAULT;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: MAC address =%s\n", __func__, tmp[1]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
- /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
- if ((addr+cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "vidpid") == 0) {
- if (tmp[1] == NULL) {
- err = -EINVAL;
- goto exit;
- }
-
- /* pidvid, da0b7881 */
- addr = EEPROM_VID_88EE;
- cnts = strlen(tmp[1]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: VID/PID =%s\n", __func__, tmp[1]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr+cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "btwmap") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- addr &= 0xFFF;
-
- cnts = strlen(tmp[2]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: BT data =%s\n", __func__, tmp[2]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if ((addr+cnts) > max_available_size) {
- DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
- DBG_88E("%s: rtw_BT_efuse_map_write error!!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "btwfake") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- addr &= 0xFFF;
-
- cnts = strlen(tmp[2]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: BT tmp data =%s\n", __func__, tmp[2]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- pEfuseHal->fakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
- } else if (strcmp(tmp[0], "btdumpfake") == 0) {
- if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
- DBG_88E("%s: BT read all map success\n", __func__);
- } else {
- DBG_88E("%s: BT read all map Fail!\n", __func__);
- err = -EFAULT;
- }
- } else if (strcmp(tmp[0], "wldumpfake") == 0) {
- if (rtw_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
- DBG_88E("%s: BT read all map success\n", __func__);
- } else {
- DBG_88E("%s: BT read all map Fail\n", __func__);
- err = -EFAULT;
- }
- } else if (strcmp(tmp[0], "btfk2map") == 0) {
- memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
-
- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if (max_available_size < 1) {
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
- DBG_88E("%s: rtw_BT_efuse_map_write error!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "wlfk2map") == 0) {
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if (max_available_size < 1) {
- err = -EFAULT;
- goto exit;
- }
-
- if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
- DBG_88E("%s: rtw_efuse_map_write error!\n", __func__);
- err = -EFAULT;
- goto exit;
- }
- } else if (strcmp(tmp[0], "wlwfake") == 0) {
- if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
- err = -EINVAL;
- goto exit;
- }
-
- addr = simple_strtoul(tmp[1], &ptmp, 16);
- addr &= 0xFFF;
-
- cnts = strlen(tmp[2]);
- if (cnts%2) {
- err = -EINVAL;
- goto exit;
- }
- cnts /= 2;
- if (cnts == 0) {
- err = -EINVAL;
- goto exit;
- }
-
- DBG_88E("%s: addr = 0x%X\n", __func__, addr);
- DBG_88E("%s: cnts =%d\n", __func__, cnts);
- DBG_88E("%s: map tmp data =%s\n", __func__, tmp[2]);
-
- for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
- pEfuseHal->fakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
- }
-
-exit:
- kfree(setdata);
- kfree(ShadowMapBT);
- kfree(ShadowMapWiFi);
- kfree(setrawdata);
-
- rtw_pm_set_ips(padapter, ips_mode);
- rtw_pm_set_lps(padapter, lps_mode);
-
- return err;
-}
-
-/*
- * Input Format: %s,%d,%d
- * %s is width, could be
- * "b" for 1 byte
- * "w" for WORD (2 bytes)
- * "dw" for DWORD (4 bytes)
- * 1st %d is address(offset)
- * 2st %d is data to write
- */
-static int rtw_mp_write_reg(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- char *pch, *pnext, *ptmp;
- char *width_str;
- char width;
- u32 addr, data;
- int ret;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- pch = extra;
- pnext = strpbrk(pch, ",.-");
- if (pnext == NULL)
- return -EINVAL;
- *pnext = 0;
- width_str = pch;
-
- pch = pnext + 1;
- pnext = strpbrk(pch, ",.-");
- if (pnext == NULL)
- return -EINVAL;
- *pnext = 0;
- addr = simple_strtoul(pch, &ptmp, 16);
- if (addr > 0x3FFF)
- return -EINVAL;
-
- pch = pnext + 1;
- if ((pch - extra) >= wrqu->length)
- return -EINVAL;
- data = simple_strtoul(pch, &ptmp, 16);
-
- ret = 0;
- width = width_str[0];
- switch (width) {
- case 'b':
- /* 1 byte */
- if (data > 0xFF) {
- ret = -EINVAL;
- break;
- }
- rtw_write8(padapter, addr, data);
- break;
- case 'w':
- /* 2 bytes */
- if (data > 0xFFFF) {
- ret = -EINVAL;
- break;
- }
- rtw_write16(padapter, addr, data);
- break;
- case 'd':
- /* 4 bytes */
- rtw_write32(padapter, addr, data);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/*
- * Input Format: %s,%d
- * %s is width, could be
- * "b" for 1 byte
- * "w" for WORD (2 bytes)
- * "dw" for DWORD (4 bytes)
- * %d is address(offset)
- *
- * Return:
- * %d for data readed
- */
-static int rtw_mp_read_reg(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- char *pch, *pnext, *ptmp;
- char *width_str;
- char width;
- char data[20], tmp[20];
- u32 addr;
- u32 ret, i = 0, j = 0, strtout = 0;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- _rtw_memset(data, 0, 20);
- _rtw_memset(tmp, 0, 20);
- _rtw_memset(extra, 0, wrqu->length);
-
- pch = input;
- pnext = strpbrk(pch, ",.-");
- if (pnext == NULL) {
- kfree(input);
- return -EINVAL;
- }
- *pnext = 0;
- width_str = pch;
-
- pch = pnext + 1;
- if ((pch - input) >= wrqu->length) {
- kfree(input);
- return -EINVAL;
- }
- kfree(input);
- addr = simple_strtoul(pch, &ptmp, 16);
- if (addr > 0x3FFF)
- return -EINVAL;
-
- ret = 0;
- width = width_str[0];
- switch (width) {
- case 'b':
- /* 1 byte */
- sprintf(extra, "%d\n", rtw_read8(padapter, addr));
- wrqu->length = strlen(extra);
- break;
- case 'w':
- /* 2 bytes */
- sprintf(data, "%04x\n", rtw_read16(padapter, addr));
- for (i = 0; i <= strlen(data); i++) {
- if (i%2 == 0) {
- tmp[j] = ' ';
- j++;
- }
- if (data[i] != '\0')
- tmp[j] = data[i];
- j++;
- }
- pch = tmp;
- DBG_88E("pch =%s", pch);
-
- while (*pch != '\0') {
- pnext = strpbrk(pch, " ");
- if (!pnext)
- break;
-
- pnext++;
- if (*pnext != '\0') {
- strtout = simple_strtoul(pnext, &ptmp, 16);
- sprintf(extra, "%s %d", extra, strtout);
- } else {
- break;
- }
- pch = pnext;
- }
- wrqu->length = 6;
- break;
- case 'd':
- /* 4 bytes */
- sprintf(data, "%08x", rtw_read32(padapter, addr));
- /* add read data format blank */
- for (i = 0; i <= strlen(data); i++) {
- if (i%2 == 0) {
- tmp[j] = ' ';
- j++;
- }
- if (data[i] != '\0')
- tmp[j] = data[i];
-
- j++;
- }
- pch = tmp;
- DBG_88E("pch =%s", pch);
-
- while (*pch != '\0') {
- pnext = strpbrk(pch, " ");
- if (!pnext)
- break;
- pnext++;
- if (*pnext != '\0') {
- strtout = simple_strtoul(pnext, &ptmp, 16);
- sprintf(extra, "%s %d", extra, strtout);
- } else {
- break;
- }
- pch = pnext;
- }
- wrqu->length = strlen(extra);
- break;
- default:
- wrqu->length = 0;
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/*
- * Input Format: %d,%x,%x
- * %d is RF path, should be smaller than MAX_RF_PATH_NUMS
- * 1st %x is address(offset)
- * 2st %x is data to write
- */
- static int rtw_mp_write_rf(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 path, addr, data;
- int ret;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data);
- if (ret < 3)
- return -EINVAL;
-
- if (path >= MAX_RF_PATH_NUMS)
- return -EINVAL;
- if (addr > 0xFF)
- return -EINVAL;
- if (data > 0xFFFFF)
- return -EINVAL;
-
- _rtw_memset(extra, 0, wrqu->length);
-
- write_rfreg(padapter, path, addr, data);
-
- sprintf(extra, "write_rf completed\n");
- wrqu->length = strlen(extra);
-
- return 0;
-}
-
-/*
- * Input Format: %d,%x
- * %d is RF path, should be smaller than MAX_RF_PATH_NUMS
- * %x is address(offset)
- *
- * Return:
- * %d for data readed
- */
-static int rtw_mp_read_rf(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- char *pch, *pnext, *ptmp;
- char data[20], tmp[20];
- u32 path, addr;
- u32 ret, i = 0, j = 0, strtou = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- ret = sscanf(input, "%d,%x", &path, &addr);
- kfree(input);
- if (ret < 2)
- return -EINVAL;
-
- if (path >= MAX_RF_PATH_NUMS)
- return -EINVAL;
- if (addr > 0xFF)
- return -EINVAL;
-
- _rtw_memset(extra, 0, wrqu->length);
-
- sprintf(data, "%08x", read_rfreg(padapter, path, addr));
- /* add read data format blank */
- for (i = 0; i <= strlen(data); i++) {
- if (i%2 == 0) {
- tmp[j] = ' ';
- j++;
- }
- tmp[j] = data[i];
- j++;
- }
- pch = tmp;
- DBG_88E("pch =%s", pch);
-
- while (*pch != '\0') {
- pnext = strpbrk(pch, " ");
- pnext++;
- if (*pnext != '\0') {
- strtou = simple_strtoul(pnext, &ptmp, 16);
- sprintf(extra, "%s %d", extra, strtou);
- } else {
- break;
- }
- pch = pnext;
- }
- wrqu->length = strlen(extra);
- return 0;
-}
-
-static int rtw_mp_start(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (padapter->registrypriv.mp_mode == 0) {
- padapter->registrypriv.mp_mode = 1;
-
- rtw_pm_set_ips(padapter, IPS_NONE);
- LeaveAllPowerSaveMode(padapter);
-
- MPT_InitializeAdapter(padapter, 1);
- }
- if (padapter->registrypriv.mp_mode == 0)
- return -EPERM;
- if (padapter->mppriv.mode == MP_OFF) {
- if (mp_start_test(padapter) == _FAIL)
- return -EPERM;
- padapter->mppriv.mode = MP_ON;
- }
- return 0;
-}
-
-static int rtw_mp_stop(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (padapter->registrypriv.mp_mode == 1) {
- MPT_DeInitAdapter(padapter);
- padapter->registrypriv.mp_mode = 0;
- }
-
- if (padapter->mppriv.mode != MP_OFF) {
- mp_stop_test(padapter);
- padapter->mppriv.mode = MP_OFF;
- }
-
- return 0;
-}
-
-extern int wifirate2_ratetbl_inx(unsigned char rate);
-
-static int rtw_mp_rate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 rate = MPT_RATE_1M;
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- rate = rtw_atoi(input);
- sprintf(extra, "Set data rate to %d", rate);
- kfree(input);
- if (rate <= 0x7f)
- rate = wifirate2_ratetbl_inx((u8)rate);
- else
- rate = (rate-0x80+MPT_RATE_MCS0);
-
- if (rate >= MPT_RATE_LAST)
- return -EINVAL;
-
- padapter->mppriv.rateidx = rate;
- Hal_SetDataRate(padapter);
-
- wrqu->length = strlen(extra) + 1;
- return 0;
-}
-
-static int rtw_mp_channel(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- u32 channel = 1;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- channel = rtw_atoi(input);
- sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel, channel);
-
- padapter->mppriv.channel = channel;
- Hal_SetChannel(padapter);
-
- wrqu->length = strlen(extra) + 1;
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_bandwidth(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 bandwidth = 0, sg = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
- int rv;
-
- rv = sscanf(extra, "40M =%d, shortGI =%d", &bandwidth, &sg);
- if (rv != 2)
- return -EINVAL;
-
- if (bandwidth != HT_CHANNEL_WIDTH_40)
- bandwidth = HT_CHANNEL_WIDTH_20;
-
- padapter->mppriv.bandwidth = (u8)bandwidth;
- padapter->mppriv.preamble = sg;
-
- SetBandwidth(padapter);
-
- return 0;
-}
-
-static int rtw_mp_txpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 idx_a = 0, idx_b = 0;
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- struct adapter *padapter = rtw_netdev_priv(dev);
- int rv;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- rv = sscanf(input, "patha =%d, pathb =%d", &idx_a, &idx_b);
- if (rv != 2) {
- kfree(input);
- return -EINVAL;
- }
-
- sprintf(extra, "Set power level path_A:%d path_B:%d", idx_a, idx_b);
- padapter->mppriv.txpoweridx = (u8)idx_a;
- padapter->mppriv.txpoweridx_b = (u8)idx_b;
- padapter->mppriv.bSetTxPower = 1;
- Hal_SetAntennaPathPower(padapter);
-
- wrqu->length = strlen(extra) + 1;
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_ant_tx(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u8 i;
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- u16 antenna = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
-
- sprintf(extra, "switch Tx antenna to %s", input);
-
- for (i = 0; i < strlen(input); i++) {
- switch (input[i]) {
- case 'a':
- antenna |= ANTENNA_A;
- break;
- case 'b':
- antenna |= ANTENNA_B;
- break;
- }
- }
- padapter->mppriv.antenna_tx = antenna;
-
- Hal_SetAntenna(padapter);
-
- wrqu->length = strlen(extra) + 1;
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_ant_rx(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u8 i;
- u16 antenna = 0;
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- _rtw_memset(extra, 0, wrqu->length);
-
- sprintf(extra, "switch Rx antenna to %s", input);
-
- for (i = 0; i < strlen(input); i++) {
- switch (input[i]) {
- case 'a':
- antenna |= ANTENNA_A;
- break;
- case 'b':
- antenna |= ANTENNA_B;
- break;
- }
- }
-
- padapter->mppriv.antenna_rx = antenna;
- Hal_SetAntenna(padapter);
- wrqu->length = strlen(extra);
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_ctx(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1;
- u32 bStartTest = 1;
- u32 count = 0;
- int rv;
- struct mp_priv *pmp_priv;
- struct pkt_attrib *pattrib;
-
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- pmp_priv = &padapter->mppriv;
-
- if (copy_from_user(extra, wrqu->pointer, wrqu->length))
- return -EFAULT;
-
- DBG_88E("%s: in =%s\n", __func__, extra);
-
- countPkTx = strncmp(extra, "count=", 6); /* strncmp true is 0 */
- cotuTx = strncmp(extra, "background", 20);
- CarrSprTx = strncmp(extra, "background, cs", 20);
- scTx = strncmp(extra, "background, sc", 20);
- sgleTx = strncmp(extra, "background, stone", 20);
- pkTx = strncmp(extra, "background, pkt", 20);
- stop = strncmp(extra, "stop", 4);
- rv = sscanf(extra, "count =%d, pkt", &count);
- if (rv != 2)
- return -EINVAL;
-
- _rtw_memset(extra, '\0', sizeof(*extra));
-
- if (stop == 0) {
- bStartTest = 0; /* To set Stop */
- pmp_priv->tx.stop = 1;
- sprintf(extra, "Stop continuous Tx");
- } else {
- bStartTest = 1;
- if (pmp_priv->mode != MP_ON) {
- if (pmp_priv->tx.stop != 1) {
- DBG_88E("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode);
- return -EFAULT;
- }
- }
- }
-
- if (pkTx == 0 || countPkTx == 0)
- pmp_priv->mode = MP_PACKET_TX;
- if (sgleTx == 0)
- pmp_priv->mode = MP_SINGLE_TONE_TX;
- if (cotuTx == 0)
- pmp_priv->mode = MP_CONTINUOUS_TX;
- if (CarrSprTx == 0)
- pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
- if (scTx == 0)
- pmp_priv->mode = MP_SINGLE_CARRIER_TX;
-
- switch (pmp_priv->mode) {
- case MP_PACKET_TX:
- if (bStartTest == 0) {
- pmp_priv->tx.stop = 1;
- pmp_priv->mode = MP_ON;
- sprintf(extra, "Stop continuous Tx");
- } else if (pmp_priv->tx.stop == 1) {
- sprintf(extra, "Start continuous DA = ffffffffffff len = 1500 count =%u,\n", count);
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = count;
- pmp_priv->tx.payload = 2;
- pattrib = &pmp_priv->tx.attrib;
- pattrib->pktlen = 1500;
- _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
- SetPacketTx(padapter);
- } else {
- return -EFAULT;
- }
- wrqu->length = strlen(extra);
- return 0;
- case MP_SINGLE_TONE_TX:
- if (bStartTest != 0)
- sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
- Hal_SetSingleToneTx(padapter, (u8)bStartTest);
- break;
- case MP_CONTINUOUS_TX:
- if (bStartTest != 0)
- sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
- Hal_SetContinuousTx(padapter, (u8)bStartTest);
- break;
- case MP_CARRIER_SUPPRISSION_TX:
- if (bStartTest != 0) {
- if (pmp_priv->rateidx <= MPT_RATE_11M) {
- sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
- Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest);
- } else {
- sprintf(extra, "Specify carrier suppression but not CCK rate");
- }
- }
- break;
- case MP_SINGLE_CARRIER_TX:
- if (bStartTest != 0)
- sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
- Hal_SetSingleCarrierTx(padapter, (u8)bStartTest);
- break;
- default:
- sprintf(extra, "Error! Continuous-Tx is not on-going.");
- return -EFAULT;
- }
-
- if (bStartTest == 1 && pmp_priv->mode != MP_ON) {
- struct mp_priv *pmp_priv = &padapter->mppriv;
- if (pmp_priv->tx.stop == 0) {
- pmp_priv->tx.stop = 1;
- msleep(5);
- }
- pmp_priv->tx.stop = 0;
- pmp_priv->tx.count = 1;
- SetPacketTx(padapter);
- } else {
- pmp_priv->mode = MP_ON;
- }
-
- wrqu->length = strlen(extra);
- return 0;
-}
-
-static int rtw_mp_arx(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u8 bStartRx = 0, bStopRx = 0, bQueryPhy;
- u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (!input)
- return -ENOMEM;
-
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
- DBG_88E("%s: %s\n", __func__, input);
-
- bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */
- bStopRx = (strncmp(input, "stop", 4) == 0) ? 1 : 0; /* strncmp true is 0 */
- bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp true is 0 */
-
- if (bStartRx) {
- sprintf(extra, "start");
- SetPacketRx(padapter, bStartRx);
- } else if (bStopRx) {
- SetPacketRx(padapter, 0);
- sprintf(extra, "Received packet OK:%d CRC error:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount);
- } else if (bQueryPhy) {
- /*
- OFDM FA
- RegCF0[15:0]
- RegCF2[31:16]
- RegDA0[31:16]
- RegDA4[15:0]
- RegDA4[31:16]
- RegDA8[15:0]
- CCK FA
- (RegA5B<<8) | RegA5C
- */
- cckok = read_bbreg(padapter, 0xf88, 0xffffffff);
- cckcrc = read_bbreg(padapter, 0xf84, 0xffffffff);
- ofdmok = read_bbreg(padapter, 0xf94, 0x0000FFFF);
- ofdmcrc = read_bbreg(padapter, 0xf94, 0xFFFF0000);
- htok = read_bbreg(padapter, 0xf90, 0x0000FFFF);
- htcrc = read_bbreg(padapter, 0xf90, 0xFFFF0000);
-
- OFDM_FA = read_bbreg(padapter, 0xcf0, 0x0000FFFF);
- OFDM_FA = read_bbreg(padapter, 0xcf2, 0xFFFF0000);
- OFDM_FA = read_bbreg(padapter, 0xda0, 0xFFFF0000);
- OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
- OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
- OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
- CCK_FA = (rtw_read8(padapter, 0xa5b)<<8) | (rtw_read8(padapter, 0xa5c));
-
- sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok+ofdmok+htok, cckcrc+ofdmcrc+htcrc, OFDM_FA+CCK_FA);
- }
- wrqu->length = strlen(extra) + 1;
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_trx_query(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 txok, txfail, rxok, rxfail;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- txok = padapter->mppriv.tx.sended;
- txfail = 0;
- rxok = padapter->mppriv.rx_pktcount;
- rxfail = padapter->mppriv.rx_crcerrpktcount;
-
- _rtw_memset(extra, '\0', 128);
-
- sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ", txok, txfail, rxok, rxfail);
-
- wrqu->length = strlen(extra)+1;
-
- return 0;
-}
-
-static int rtw_mp_pwrtrk(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u8 enable;
- u32 thermal;
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- int ret = 0;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- ret = -EFAULT;
- goto exit;
- }
- _rtw_memset(extra, 0, wrqu->length);
-
- enable = 1;
- if (wrqu->length > 1) {/* not empty string */
- if (strncmp(input, "stop", 4) == 0) {
- enable = 0;
- sprintf(extra, "mp tx power tracking stop");
- } else if (sscanf(input, "ther =%d", &thermal)) {
- ret = Hal_SetThermalMeter(padapter, (u8)thermal);
- if (ret == _FAIL) {
- ret = -EPERM;
- goto exit;
- }
- sprintf(extra, "mp tx power tracking start, target value =%d ok ", thermal);
- } else {
- ret = -EINVAL;
- goto exit;
- }
- }
-
- ret = Hal_SetPowerTracking(padapter, enable);
- if (ret == _FAIL) {
- ret = -EPERM;
- goto exit;
- }
-
- wrqu->length = strlen(extra);
-
-exit:
- kfree(input);
- return ret;
-}
-
-static int rtw_mp_psd(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
-
- strcpy(extra, input);
-
- wrqu->length = mp_query_psd(padapter, extra);
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_thermal(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u8 val;
- u16 bwrite = 1;
- u16 addr = EEPROM_THERMAL_METER_88E;
-
- u16 cnt = 1;
- u16 max_available_size = 0;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (copy_from_user(extra, wrqu->pointer, wrqu->length))
- return -EFAULT;
-
- bwrite = strncmp(extra, "write", 6); /* strncmp true is 0 */
-
- Hal_GetThermalMeter(padapter, &val);
-
- if (bwrite == 0) {
- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
- if (2 > max_available_size) {
- DBG_88E("no available efuse!\n");
- return -EFAULT;
- }
- if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) {
- DBG_88E("rtw_efuse_map_write error\n");
- return -EFAULT;
- } else {
- sprintf(extra, " efuse write ok :%d", val);
- }
- } else {
- sprintf(extra, "%d", val);
- }
- wrqu->length = strlen(extra);
-
- return 0;
-}
-
-static int rtw_mp_reset_stats(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- struct mp_priv *pmp_priv;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- pmp_priv = &padapter->mppriv;
-
- pmp_priv->tx.sended = 0;
- pmp_priv->tx_pktcount = 0;
- pmp_priv->rx_pktcount = 0;
- pmp_priv->rx_crcerrpktcount = 0;
-
- /* reset phy counter */
- write_bbreg(padapter, 0xf14, BIT16, 0x1);
- msleep(10);
- write_bbreg(padapter, 0xf14, BIT16, 0x0);
-
- return 0;
-}
-
-static int rtw_mp_dump(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- u32 value;
- u8 rf_type, path_nums = 0;
- u32 i, j = 1, path;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (strncmp(extra, "all", 4) == 0) {
- DBG_88E("\n ======= MAC REG =======\n");
- for (i = 0x0; i < 0x300; i += 4) {
- if (j%4 == 1)
- DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
- if ((j++)%4 == 0)
- DBG_88E("\n");
- }
- for (i = 0x400; i < 0x1000; i += 4) {
- if (j%4 == 1)
- DBG_88E("0x%02x", i);
- DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
- if ((j++)%4 == 0)
- DBG_88E("\n");
- }
-
- j = 1;
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
-
- DBG_88E("\n ======= RF REG =======\n");
- if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type))
- path_nums = 1;
- else
- path_nums = 2;
-
- for (path = 0; path < path_nums; path++) {
- for (i = 0; i < 0x34; i++) {
- value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
- if (j%4 == 1)
- DBG_88E("0x%02x ", i);
- DBG_88E(" 0x%08x ", value);
- if ((j++)%4 == 0)
- DBG_88E("\n");
- }
- }
- }
- return 0;
-}
-
-static int rtw_mp_phypara(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrqu, char *extra)
-{
- char *input = kmalloc(wrqu->length, GFP_KERNEL);
- u32 valxcap;
- int rv;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
- kfree(input);
- return -EFAULT;
- }
-
- DBG_88E("%s:iwpriv in =%s\n", __func__, input);
-
- rv = sscanf(input, "xcap =%d", &valxcap);
- if (rv != 1) {
- kfree(input);
- return -EINVAL;
- }
-
- kfree(input);
- return 0;
-}
-
-static int rtw_mp_SetRFPath(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->data.length, GFP_KERNEL);
- u8 bMain = 1, bTurnoff = 1;
- int ret = 0;
-
- if (!input)
- return -ENOMEM;
- if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) {
- ret = -EFAULT;
- goto exit;
- }
- DBG_88E("%s:iwpriv in =%s\n", __func__, input);
-
- bMain = strncmp(input, "1", 2); /* strncmp true is 0 */
- bTurnoff = strncmp(input, "0", 3); /* strncmp true is 0 */
-
- if (bMain == 0) {
- MP_PHY_SetRFPathSwitch(padapter, true);
- DBG_88E("%s:PHY_SetRFPathSwitch = true\n", __func__);
- } else if (bTurnoff == 0) {
- MP_PHY_SetRFPathSwitch(padapter, false);
- DBG_88E("%s:PHY_SetRFPathSwitch = false\n", __func__);
- }
-
-exit:
- kfree(input);
- return ret;
-}
-
-static int rtw_mp_QueryDrv(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct adapter *padapter = rtw_netdev_priv(dev);
- char *input = kmalloc(wrqu->data.length, GFP_KERNEL);
- u8 qAutoLoad = 1;
- struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
- int ret = 0;
-
- if (!input)
- return -ENOMEM;
-
- if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length)) {
- ret = -EFAULT;
- goto exit;
- }
- DBG_88E("%s:iwpriv in =%s\n", __func__, input);
-
- qAutoLoad = strncmp(input, "autoload", 8); /* strncmp true is 0 */
-
- if (qAutoLoad == 0) {
- DBG_88E("%s:qAutoLoad\n", __func__);
-
- if (pEEPROM->bautoload_fail_flag)
- sprintf(extra, "fail");
- else
- sprintf(extra, "ok");
- }
- wrqu->data.length = strlen(extra) + 1;
-
-exit:
- kfree(input);
- return ret;
-}
-
-static int rtw_mp_set(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wdata, char *extra)
-{
- struct iw_point *wrqu = (struct iw_point *)wdata;
- u32 subcmd = wrqu->flags;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (padapter == NULL)
- return -ENETDOWN;
-
- if (extra == NULL) {
- wrqu->length = 0;
- return -EIO;
- }
-
- switch (subcmd) {
- case MP_START:
- DBG_88E("set case mp_start\n");
- rtw_mp_start(dev, info, wrqu, extra);
- break;
- case MP_STOP:
- DBG_88E("set case mp_stop\n");
- rtw_mp_stop(dev, info, wrqu, extra);
- break;
- case MP_BANDWIDTH:
- DBG_88E("set case mp_bandwidth\n");
- rtw_mp_bandwidth(dev, info, wrqu, extra);
- break;
- case MP_RESET_STATS:
- DBG_88E("set case MP_RESET_STATS\n");
- rtw_mp_reset_stats(dev, info, wrqu, extra);
- break;
- case MP_SetRFPathSwh:
- DBG_88E("set MP_SetRFPathSwitch\n");
- rtw_mp_SetRFPath(dev, info, wdata, extra);
- break;
- case CTA_TEST:
- DBG_88E("set CTA_TEST\n");
- rtw_cta_test_start(dev, info, wdata, extra);
- break;
- }
-
- return 0;
-}
-
-static int rtw_mp_get(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wdata, char *extra)
-{
- struct iw_point *wrqu = (struct iw_point *)wdata;
- u32 subcmd = wrqu->flags;
- struct adapter *padapter = rtw_netdev_priv(dev);
-
- if (padapter == NULL)
- return -ENETDOWN;
- if (extra == NULL) {
- wrqu->length = 0;
- return -EIO;
- }
-
- switch (subcmd) {
- case WRITE_REG:
- rtw_mp_write_reg(dev, info, wrqu, extra);
- break;
- case WRITE_RF:
- rtw_mp_write_rf(dev, info, wrqu, extra);
- break;
- case MP_PHYPARA:
- DBG_88E("mp_get MP_PHYPARA\n");
- rtw_mp_phypara(dev, info, wrqu, extra);
- break;
- case MP_CHANNEL:
- DBG_88E("set case mp_channel\n");
- rtw_mp_channel(dev, info, wrqu, extra);
- break;
- case READ_REG:
- DBG_88E("mp_get READ_REG\n");
- rtw_mp_read_reg(dev, info, wrqu, extra);
- break;
- case READ_RF:
- DBG_88E("mp_get READ_RF\n");
- rtw_mp_read_rf(dev, info, wrqu, extra);
- break;
- case MP_RATE:
- DBG_88E("set case mp_rate\n");
- rtw_mp_rate(dev, info, wrqu, extra);
- break;
- case MP_TXPOWER:
- DBG_88E("set case MP_TXPOWER\n");
- rtw_mp_txpower(dev, info, wrqu, extra);
- break;
- case MP_ANT_TX:
- DBG_88E("set case MP_ANT_TX\n");
- rtw_mp_ant_tx(dev, info, wrqu, extra);
- break;
- case MP_ANT_RX:
- DBG_88E("set case MP_ANT_RX\n");
- rtw_mp_ant_rx(dev, info, wrqu, extra);
- break;
- case MP_QUERY:
- rtw_mp_trx_query(dev, info, wrqu, extra);
- break;
- case MP_CTX:
- DBG_88E("set case MP_CTX\n");
- rtw_mp_ctx(dev, info, wrqu, extra);
- break;
- case MP_ARX:
- DBG_88E("set case MP_ARX\n");
- rtw_mp_arx(dev, info, wrqu, extra);
- break;
- case EFUSE_GET:
- DBG_88E("efuse get EFUSE_GET\n");
- rtw_mp_efuse_get(dev, info, wdata, extra);
- break;
- case MP_DUMP:
- DBG_88E("set case MP_DUMP\n");
- rtw_mp_dump(dev, info, wrqu, extra);
- break;
- case MP_PSD:
- DBG_88E("set case MP_PSD\n");
- rtw_mp_psd(dev, info, wrqu, extra);
- break;
- case MP_THER:
- DBG_88E("set case MP_THER\n");
- rtw_mp_thermal(dev, info, wrqu, extra);
- break;
- case MP_QueryDrvStats:
- DBG_88E("mp_get MP_QueryDrvStats\n");
- rtw_mp_QueryDrv (dev, info, wdata, extra);
- break;
- case MP_PWRTRK:
- DBG_88E("set case MP_PWRTRK\n");
- rtw_mp_pwrtrk(dev, info, wrqu, extra);
- break;
- case EFUSE_SET:
- DBG_88E("set case efuse set\n");
- rtw_mp_efuse_set(dev, info, wdata, extra);
- break;
- }
-
- msleep(10); /* delay 5ms for sending pkt before exit adb shell operation */
- return 0;
-}
-
-static int rtw_tdls(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return 0;
-}
-
-static int rtw_tdls_get(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return 0;
-}
-
-static int rtw_test(
- struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- u32 len;
- u8 *pbuf, *pch;
- char *ptmp;
- u8 *delim = ",";
-
- DBG_88E("+%s\n", __func__);
- len = wrqu->data.length;
-
- pbuf = (u8 *)rtw_zmalloc(len);
- if (pbuf == NULL) {
- DBG_88E("%s: no memory!\n", __func__);
- return -ENOMEM;
- }
-
- if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
- kfree(pbuf);
- DBG_88E("%s: copy from user fail!\n", __func__);
- return -EFAULT;
- }
- DBG_88E("%s: string =\"%s\"\n", __func__, pbuf);
-
- ptmp = (char *)pbuf;
- pch = strsep(&ptmp, delim);
- if ((pch == NULL) || (strlen(pch) == 0)) {
- kfree(pbuf);
- DBG_88E("%s: parameter error(level 1)!\n", __func__);
- return -EFAULT;
- }
- kfree(pbuf);
- return 0;
-}
-
static iw_handler rtw_handlers[] = {
NULL, /* SIOCSIWCOMMIT */
rtw_wx_get_name, /* SIOCGIWNAME */
@@ -7644,175 +3075,6 @@ static iw_handler rtw_handlers[] = {
NULL, /*---hole---*/
};
-static const struct iw_priv_args rtw_private_args[] = {
- {
- SIOCIWFIRSTPRIV + 0x0,
- IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
- },
- {
- SIOCIWFIRSTPRIV + 0x1,
- IW_PRIV_TYPE_CHAR | 0x7FF,
- IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
- },
- {
- SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
- },
- {
- SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
- },
- {
- SIOCIWFIRSTPRIV + 0x4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
- },
- {
- SIOCIWFIRSTPRIV + 0x5,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
- },
- {
- SIOCIWFIRSTPRIV + 0x6,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
- },
- {
- SIOCIWFIRSTPRIV + 0x7,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
- },
- {
- SIOCIWFIRSTPRIV + 0x8,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
- },
- {
- SIOCIWFIRSTPRIV + 0x9,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
- },
-
- {
- SIOCIWFIRSTPRIV + 0xA,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
- },
-
- {
- SIOCIWFIRSTPRIV + 0xB,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
- },
- {
- SIOCIWFIRSTPRIV + 0xC,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
- },
- {
- SIOCIWFIRSTPRIV + 0xD,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
- },
- {
- SIOCIWFIRSTPRIV + 0x10,
- IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set"
- },
- {
- SIOCIWFIRSTPRIV + 0x11,
- IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get"
- },
- {
- SIOCIWFIRSTPRIV + 0x12,
- IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2"
- },
- {SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 128, 0, "NULL"},
- {
- SIOCIWFIRSTPRIV + 0x14,
- IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
- },
- {
- SIOCIWFIRSTPRIV + 0x15,
- IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "tdls_get"
- },
- {
- SIOCIWFIRSTPRIV + 0x16,
- IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
- },
-
- {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"},
-
- {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
- {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
- {SIOCIWFIRSTPRIV + 0x1D, IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
- },
-
- {SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0, ""}, /* set */
- {SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},/* get */
-/* --- sub-ioctls definitions --- */
-
- {MP_START, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start"}, /* set */
- {MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara"},/* get */
- {MP_STOP, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop"}, /* set */
- {MP_CHANNEL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel"},/* get */
- {MP_BANDWIDTH, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, /* set */
- {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},/* get */
- {MP_RESET_STATS, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
- {MP_QUERY, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_query"}, /* get */
- {READ_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg"},
- {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},
- {READ_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf"},
- {MP_PSD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
- {MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump"},
- {MP_TXPOWER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
- {MP_ANT_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
- {MP_ANT_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
- {WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg"},
- {WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf"},
- {MP_CTX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
- {MP_ARX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
- {MP_THER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
- {EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set"},
- {EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
- {MP_PWRTRK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
- {MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery"},
- {MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, /* mp_ioctl */
- {MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath"},
- {CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
-};
-
-static iw_handler rtw_private_handler[] = {
-rtw_wx_write32, /* 0x00 */
-rtw_wx_read32, /* 0x01 */
-rtw_drvext_hdl, /* 0x02 */
-rtw_mp_ioctl_hdl, /* 0x03 */
-
-/* for MM DTV platform */
- rtw_get_ap_info, /* 0x04 */
-
- rtw_set_pid, /* 0x05 */
- rtw_wps_start, /* 0x06 */
-
- rtw_wx_get_sensitivity, /* 0x07 */
- rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */
- rtw_wx_set_mtk_wps_ie, /* 0x09 */
-
-/* Set Channel depend on the country code */
- rtw_wx_set_channel_plan, /* 0x0A */
-
- rtw_dbg_port, /* 0x0B */
- rtw_wx_write_rf, /* 0x0C */
- rtw_wx_read_rf, /* 0x0D */
-
- rtw_mp_set, /* 0x0E */
- rtw_mp_get, /* 0x0F */
- rtw_p2p_set, /* 0x10 */
- rtw_p2p_get, /* 0x11 */
- rtw_p2p_get2, /* 0x12 */
-
- NULL, /* 0x13 */
- rtw_tdls, /* 0x14 */
- rtw_tdls_get, /* 0x15 */
-
- rtw_pm_set, /* 0x16 */
- rtw_wx_priv_null, /* 0x17 */
- rtw_rereg_nd_name, /* 0x18 */
- rtw_wx_priv_null, /* 0x19 */
-
- rtw_mp_efuse_set, /* 0x1A */
- rtw_mp_efuse_get, /* 0x1B */
- NULL, /* 0x1C is reserved for hostapd */
- rtw_test, /* 0x1D */
-};
-
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
{
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
@@ -7841,347 +3103,9 @@ static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
struct iw_handler_def rtw_handlers_def = {
.standard = rtw_handlers,
.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
- .private = rtw_private_handler,
- .private_args = (struct iw_priv_args *)rtw_private_args,
- .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
- .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
.get_wireless_stats = rtw_get_wireless_stats,
};
-/* copy from net/wireless/wext.c start */
-/* ---------------------------------------------------------------- */
-/*
- * Calculate size of private arguments
- */
-static const char iw_priv_type_size[] = {
- 0, /* IW_PRIV_TYPE_NONE */
- 1, /* IW_PRIV_TYPE_BYTE */
- 1, /* IW_PRIV_TYPE_CHAR */
- 0, /* Not defined */
- sizeof(__u32), /* IW_PRIV_TYPE_INT */
- sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
- sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
- 0, /* Not defined */
-};
-
-static int get_priv_size(__u16 args)
-{
- int num = args & IW_PRIV_SIZE_MASK;
- int type = (args & IW_PRIV_TYPE_MASK) >> 12;
-
- return num * iw_priv_type_size[type];
-}
-/* copy from net/wireless/wext.c end */
-
-static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
-{
- int err = 0;
- u8 *input = NULL;
- u32 input_len = 0;
- const char delim[] = " ";
- u8 *output = NULL;
- u32 output_len = 0;
- u32 count = 0;
- u8 *buffer = NULL;
- u32 buffer_len = 0;
- char *ptr = NULL;
- u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
- u32 cmdlen;
- s32 len;
- u8 *extra = NULL;
- u32 extra_size = 0;
- int rv;
-
- s32 k;
- const iw_handler *priv; /* Private ioctl */
- const struct iw_priv_args *priv_args; /* Private ioctl description */
- u32 num_priv_args; /* Number of descriptions */
- iw_handler handler;
- int temp;
- int subcmd = 0; /* sub-ioctl index */
- int offset = 0; /* Space for sub-ioctl index */
-
- union iwreq_data wdata;
-
- memcpy(&wdata, wrq_data, sizeof(wdata));
-
- input_len = wdata.data.length;
- input = rtw_zmalloc(input_len);
- if (NULL == input)
- return -ENOMEM;
- if (copy_from_user(input, wdata.data.pointer, input_len)) {
- err = -EFAULT;
- goto exit;
- }
- ptr = input;
- len = input_len;
-
- rv = sscanf(ptr, "%16s", cmdname);
- if (rv != 1) {
- err = -EINVAL;
- goto exit;
- }
- cmdlen = strlen(cmdname);
- DBG_88E("%s: cmd =%s\n", __func__, cmdname);
-
- /* skip command string */
- if (cmdlen > 0)
- cmdlen += 1; /* skip one space */
- ptr += cmdlen;
- len -= cmdlen;
- DBG_88E("%s: parameters =%s\n", __func__, ptr);
-
- priv = rtw_private_handler;
- priv_args = rtw_private_args;
- num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
-
- if (num_priv_args == 0) {
- err = -EOPNOTSUPP;
- goto exit;
- }
-
- /* Search the correct ioctl */
- k = -1;
- while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
-
- /* If not found... */
- if (k == num_priv_args) {
- err = -EOPNOTSUPP;
- goto exit;
- }
-
- /* Watch out for sub-ioctls ! */
- if (priv_args[k].cmd < SIOCDEVPRIVATE) {
- int j = -1;
-
- /* Find the matching *real* ioctl */
- while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
- (priv_args[j].set_args != priv_args[k].set_args) ||
- (priv_args[j].get_args != priv_args[k].get_args)));
-
- /* If not found... */
- if (j == num_priv_args) {
- err = -EINVAL;
- goto exit;
- }
-
- /* Save sub-ioctl number */
- subcmd = priv_args[k].cmd;
- /* Reserve one int (simplify alignment issues) */
- offset = sizeof(__u32);
- /* Use real ioctl definition from now on */
- k = j;
- }
-
- buffer = rtw_zmalloc(4096);
- if (NULL == buffer) {
- err = -ENOMEM;
- goto exit;
- }
-
- /* 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)) {
- u8 *str;
-
- switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
- case IW_PRIV_TYPE_BYTE:
- /* Fetch args */
- count = 0;
- do {
- str = strsep(&ptr, delim);
- if (NULL == str)
- break;
- sscanf(str, "%i", &temp);
- buffer[count++] = (u8)temp;
- } while (1);
- buffer_len = count;
- /* Number of args to fetch */
- wdata.data.length = count;
- if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
- wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
- break;
- case IW_PRIV_TYPE_INT:
- /* Fetch args */
- count = 0;
- do {
- str = strsep(&ptr, delim);
- if (NULL == str)
- break;
- sscanf(str, "%i", &temp);
- ((s32 *)buffer)[count++] = (s32)temp;
- } while (1);
- buffer_len = count * sizeof(s32);
- /* Number of args to fetch */
- wdata.data.length = count;
- if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
- wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
- break;
- case IW_PRIV_TYPE_CHAR:
- 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))
- wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
-
- /* Fetch string */
- memcpy(buffer, ptr, wdata.data.length);
- } else {
- wdata.data.length = 1;
- buffer[0] = '\0';
- }
- buffer_len = wdata.data.length;
- break;
- default:
- DBG_88E("%s: Not yet implemented...\n", __func__);
- err = -1;
- goto exit;
- }
-
- if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
- (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
- DBG_88E("%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;
- }
- } 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)) {
- /* First case : all SET args fit within wrq */
- if (offset)
- wdata.mode = subcmd;
- memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
- } 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)) {
- /* Second case : no SET args, GET args fit within wrq */
- if (offset)
- wdata.mode = subcmd;
- } 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;
- goto exit;
- }
- wdata.data.flags = subcmd;
- }
- }
-
- kfree(input);
- input = NULL;
-
- extra_size = 0;
- if (IW_IS_SET(priv_args[k].cmd)) {
- /* Size of set arguments */
- extra_size = get_priv_size(priv_args[k].set_args);
-
- /* Does it fits in iwr ? */
- if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
- ((extra_size + offset) <= IFNAMSIZ))
- extra_size = 0;
- } else {
- /* Size of get arguments */
- extra_size = get_priv_size(priv_args[k].get_args);
-
- /* Does it fits in iwr ? */
- if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
- (extra_size <= IFNAMSIZ))
- extra_size = 0;
- }
-
- if (extra_size == 0) {
- extra = (u8 *)&wdata;
- kfree(buffer);
- buffer = NULL;
- } else {
- extra = buffer;
- }
-
- handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
- err = handler(dev, NULL, &wdata, extra);
-
- /* 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)) {
- int j;
- int n = 0; /* number of args */
- u8 str[20] = {0};
-
- /* Check where is the returned data */
- if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
- (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
- n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
- else
- n = wdata.data.length;
-
- output = rtw_zmalloc(4096);
- if (NULL == output) {
- err = -ENOMEM;
- goto exit;
- }
- switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
- case IW_PRIV_TYPE_BYTE:
- /* Display args */
- for (j = 0; j < n; j++) {
- sprintf(str, "%d ", extra[j]);
- len = strlen(str);
- output_len = strlen(output);
- if ((output_len + len + 1) > 4096) {
- err = -E2BIG;
- goto exit;
- }
- memcpy(output+output_len, str, len);
- }
- break;
- case IW_PRIV_TYPE_INT:
- /* Display args */
- for (j = 0; j < n; j++) {
- sprintf(str, "%d ", ((__s32 *)extra)[j]);
- len = strlen(str);
- output_len = strlen(output);
- if ((output_len + len + 1) > 4096) {
- err = -E2BIG;
- goto exit;
- }
- memcpy(output+output_len, str, len);
- }
- break;
- case IW_PRIV_TYPE_CHAR:
- /* Display args */
- memcpy(output, extra, n);
- break;
- default:
- DBG_88E("%s: Not yet implemented...\n", __func__);
- err = -1;
- goto exit;
- }
-
- output_len = strlen(output) + 1;
- wrq_data->data.length = output_len;
- if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
- err = -EFAULT;
- goto exit;
- }
- } else {
- /* if args to set */
- wrq_data->data.length = 0;
- }
-
-exit:
- kfree(input);
- kfree(buffer);
- kfree(output);
- return err;
-}
-
#include <rtw_android.h>
int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
@@ -8197,9 +3121,6 @@ int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
break;
#endif /* CONFIG_88EU_AP_MODE */
- case SIOCDEVPRIVATE:
- ret = rtw_ioctl_wext_private(dev, &wrq->u);
- break;
case (SIOCDEVPRIVATE+1):
ret = rtw_android_priv_cmd(dev, rq, cmd);
break;
diff --git a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
index 0624378efd6f..1b892c424cb8 100644
--- a/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/mlme_linux.c
@@ -25,38 +25,13 @@
#include <drv_types.h>
#include <mlme_osdep.h>
-void rtw_join_timeout_handler (void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
-
- _rtw_join_timeout_handler(adapter);
-}
-
-
-void _rtw_scan_timeout_handler (void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
-
- rtw_scan_timeout_handler(adapter);
-}
-
-static void _dynamic_check_timer_handlder(void *FunctionContext)
-{
- struct adapter *adapter = (struct adapter *)FunctionContext;
-
- if (adapter->registrypriv.mp_mode == 1)
- return;
- rtw_dynamic_check_timer_handlder(adapter);
- _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
-}
-
void rtw_init_mlme_timer(struct adapter *padapter)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter);
- _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
- _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter);
+ _init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, _rtw_join_timeout_handler, padapter);
+ _init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, rtw_scan_timeout_handler, padapter);
+ _init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, rtw_dynamic_check_timer_handlder, padapter);
}
void rtw_os_indicate_connect(struct adapter *adapter)
@@ -85,12 +60,12 @@ void rtw_reset_securitypriv(struct adapter *adapter)
/* We have to backup the PMK information for WiFi PMK Caching test item. */
/* Backup the btkip_countermeasure information. */
/* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */
- _rtw_memset(&backup_pmkid[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
+ memset(&backup_pmkid[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
memcpy(&backup_pmkid[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
backup_index = adapter->securitypriv.PMKIDIndex;
backup_counter = adapter->securitypriv.btkip_countermeasure;
backup_time = adapter->securitypriv.btkip_countermeasure_time;
- _rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv));
+ memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv));
/* Restore the PMK information to securitypriv structure for the following connection. */
memcpy(&adapter->securitypriv.PMKIDList[0],
@@ -137,7 +112,7 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
buff = rtw_malloc(IW_CUSTOM_MAX);
if (!buff)
return;
- _rtw_memset(buff, 0, IW_CUSTOM_MAX);
+ memset(buff, 0, IW_CUSTOM_MAX);
p = buff;
p += sprintf(p, "ASSOCINFO(ReqIEs =");
len = sec_ie[1]+2;
@@ -145,7 +120,7 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
for (i = 0; i < len; i++)
p += sprintf(p, "%02x", sec_ie[i]);
p += sprintf(p, ")");
- _rtw_memset(&wrqu, 0, sizeof(wrqu));
+ memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = p-buff;
wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ?
wrqu.data.length : IW_CUSTOM_MAX;
@@ -154,36 +129,17 @@ void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie)
}
}
-static void _survey_timer_hdl(void *FunctionContext)
-{
- struct adapter *padapter = (struct adapter *)FunctionContext;
-
- survey_timer_hdl(padapter);
-}
-
-static void _link_timer_hdl(void *FunctionContext)
-{
- struct adapter *padapter = (struct adapter *)FunctionContext;
- link_timer_hdl(padapter);
-}
-
-static void _addba_timer_hdl(void *FunctionContext)
-{
- struct sta_info *psta = (struct sta_info *)FunctionContext;
- addba_timer_hdl(psta);
-}
-
void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta)
{
- _init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
+ _init_timer(&psta->addba_retry_timer, padapter->pnetdev, addba_timer_hdl, psta);
}
void init_mlme_ext_timer(struct adapter *padapter)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
- _init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
+ _init_timer(&pmlmeext->survey_timer, padapter->pnetdev, survey_timer_hdl, padapter);
+ _init_timer(&pmlmeext->link_timer, padapter->pnetdev, link_timer_hdl, padapter);
}
#ifdef CONFIG_88EU_AP_MODE
diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
index 0e0c32d46431..c7a44ab33d64 100644
--- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
@@ -20,23 +20,20 @@
#define _OS_INTFS_C_
#include <osdep_service.h>
+#include <osdep_intf.h>
#include <drv_types.h>
#include <xmit_osdep.h>
#include <recv_osdep.h>
#include <hal_intf.h>
#include <rtw_ioctl.h>
-#include <rtw_version.h>
-#include <usb_osintf.h>
#include <usb_hal.h>
-#include <rtw_br_ext.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek Wireless Lan Driver");
MODULE_AUTHOR("Realtek Semiconductor Corp.");
MODULE_VERSION(DRIVERVERSION);
-#define CONFIG_BR_EXT_BRNAME "br0"
#define RTW_NOTCH_FILTER 0 /* 0:Disable, 1:Enable, */
/* module param defaults */
@@ -69,8 +66,6 @@ static int rtw_short_retry_lmt = 7;
static int rtw_busy_thresh = 40;
static int rtw_ack_policy = NORMAL_ACK;
-static int rtw_mp_mode;
-
static int rtw_software_encrypt;
static int rtw_software_decrypt;
@@ -130,7 +125,6 @@ module_param(rtw_rfintfs, int, 0644);
module_param(rtw_lbkmode, int, 0644);
module_param(rtw_network_mode, int, 0644);
module_param(rtw_channel, int, 0644);
-module_param(rtw_mp_mode, int, 0644);
module_param(rtw_wmm_enable, int, 0644);
module_param(rtw_vrtl_carrier_sense, int, 0644);
module_param(rtw_vcs_type, int, 0644);
@@ -548,7 +542,7 @@ static uint loadparam(struct adapter *padapter, struct net_device *pnetdev)
registry_par->short_retry_lmt = (u8)rtw_short_retry_lmt;
registry_par->busy_thresh = (u16)rtw_busy_thresh;
registry_par->ack_policy = (u8)rtw_ack_policy;
- registry_par->mp_mode = (u8)rtw_mp_mode;
+ registry_par->mp_mode = 0;
registry_par->software_encrypt = (u8)rtw_software_encrypt;
registry_par->software_decrypt = (u8)rtw_software_decrypt;
registry_par->acm_method = (u8)rtw_acm_method;
@@ -713,14 +707,12 @@ static const struct device_type wlan_type = {
struct net_device *rtw_init_netdev(struct adapter *old_padapter)
{
struct adapter *padapter;
- struct net_device *pnetdev;
+ struct net_device *pnetdev = NULL;
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+init_net_dev\n"));
if (old_padapter != NULL)
pnetdev = rtw_alloc_etherdev_with_old_priv(sizeof(struct adapter), (void *)old_padapter);
- else
- pnetdev = rtw_alloc_etherdev(sizeof(struct adapter));
if (!pnetdev)
return NULL;
@@ -751,7 +743,6 @@ u32 rtw_start_drv_threads(struct adapter *padapter)
else
_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); /* wait for cmd_thread to run */
- rtw_hal_start_thread(padapter);
return _status;
}
@@ -764,7 +755,6 @@ void rtw_stop_drv_threads(struct adapter *padapter)
if (padapter->cmdThread)
_rtw_down_sema(&padapter->cmdpriv.terminate_cmdthread_sema);
- rtw_hal_stop_thread(padapter);
}
static u8 rtw_init_default_value(struct adapter *padapter)
@@ -812,9 +802,6 @@ static u8 rtw_init_default_value(struct adapter *padapter)
padapter->bWritePortCancel = false;
padapter->bRxRSSIDisplay = 0;
padapter->bNotifyChannelChange = 0;
-#ifdef CONFIG_88EU_P2P
- padapter->bShowGetP2PState = 1;
-#endif
return ret;
}
@@ -837,8 +824,7 @@ u8 rtw_reset_drv_sw(struct adapter *padapter)
pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING);
-
- rtw_hal_sreset_reset_value(padapter);
+ rtw_hal_sreset_init(padapter);
pwrctrlpriv->pwr_state_check_cnts = 0;
/* mlmeextpriv */
@@ -864,24 +850,12 @@ u8 rtw_init_drv_sw(struct adapter *padapter)
padapter->cmdpriv.padapter = padapter;
- if ((rtw_init_evt_priv(&padapter->evtpriv)) == _FAIL) {
- RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init evt_priv\n"));
- ret8 = _FAIL;
- goto exit;
- }
-
if (rtw_init_mlme_priv(padapter) == _FAIL) {
RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_priv\n"));
ret8 = _FAIL;
goto exit;
}
-#ifdef CONFIG_88EU_P2P
- rtw_init_wifidirect_timers(padapter);
- init_wifidirect_info(padapter, P2P_ROLE_DISABLE);
- reset_global_wifidirect_info(padapter);
-#endif /* CONFIG_88EU_P2P */
-
if (init_mlme_ext_priv(padapter) == _FAIL) {
RT_TRACE(_module_os_intfs_c_, _drv_err_, ("\n Can't init mlme_ext_priv\n"));
ret8 = _FAIL;
@@ -912,9 +886,6 @@ u8 rtw_init_drv_sw(struct adapter *padapter)
rtw_init_pwrctrl_priv(padapter);
- if (init_mp_priv(padapter) == _FAIL)
- DBG_88E("%s: initialize MP private data Fail!\n", __func__);
-
ret8 = rtw_init_default_value(padapter);
rtw_hal_dm_init(padapter);
@@ -935,49 +906,30 @@ void rtw_cancel_all_timer(struct adapter *padapter)
{
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+rtw_cancel_all_timer\n"));
- _cancel_timer_ex(&padapter->mlmepriv.assoc_timer);
+ del_timer_sync(&padapter->mlmepriv.assoc_timer);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel association timer complete!\n"));
- _cancel_timer_ex(&padapter->mlmepriv.scan_to_timer);
+ del_timer_sync(&padapter->mlmepriv.scan_to_timer);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel scan_to_timer!\n"));
- _cancel_timer_ex(&padapter->mlmepriv.dynamic_chk_timer);
+ del_timer_sync(&padapter->mlmepriv.dynamic_chk_timer);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel dynamic_chk_timer!\n"));
/* cancel sw led timer */
rtw_hal_sw_led_deinit(padapter);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("rtw_cancel_all_timer:cancel DeInitSwLeds!\n"));
- _cancel_timer_ex(&padapter->pwrctrlpriv.pwr_state_check_timer);
+ del_timer_sync(&padapter->pwrctrlpriv.pwr_state_check_timer);
- _cancel_timer_ex(&padapter->recvpriv.signal_stat_timer);
+ del_timer_sync(&padapter->recvpriv.signal_stat_timer);
}
u8 rtw_free_drv_sw(struct adapter *padapter)
{
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("==>rtw_free_drv_sw"));
- /* we can call rtw_p2p_enable here, but: */
- /* 1. rtw_p2p_enable may have IO operation */
- /* 2. rtw_p2p_enable is bundled with wext interface */
- #ifdef CONFIG_88EU_P2P
- {
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
- _cancel_timer_ex(&pwdinfo->find_phase_timer);
- _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
- _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer);
- rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
- }
- }
- #endif
-
free_mlme_ext_priv(&padapter->mlmeextpriv);
- rtw_free_cmd_priv(&padapter->cmdpriv);
-
- rtw_free_evt_priv(&padapter->evtpriv);
-
rtw_free_mlme_priv(&padapter->mlmepriv);
_rtw_free_xmit_priv(&padapter->xmitpriv);
@@ -995,40 +947,13 @@ u8 rtw_free_drv_sw(struct adapter *padapter)
padapter->rereg_nd_name_priv.old_pnetdev = NULL;
}
- /* clear pbuddystruct adapter to avoid access wrong pointer. */
- if (padapter->pbuddy_adapter != NULL)
- padapter->pbuddy_adapter->pbuddy_adapter = NULL;
+ mutex_destroy(&padapter->hw_init_mutex);
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw\n"));
return _SUCCESS;
}
-void netdev_br_init(struct net_device *netdev)
-{
- struct adapter *adapter = (struct adapter *)rtw_netdev_priv(netdev);
-
- rcu_read_lock();
-
- if (rcu_dereference(adapter->pnetdev->rx_handler_data)) {
- struct net_device *br_netdev;
- struct net *devnet = NULL;
-
- devnet = dev_net(netdev);
- br_netdev = dev_get_by_name(devnet, CONFIG_BR_EXT_BRNAME);
- if (br_netdev) {
- memcpy(adapter->br_mac, br_netdev->dev_addr, ETH_ALEN);
- dev_put(br_netdev);
- } else {
- pr_info("%s()-%d: dev_get_by_name(%s) failed!",
- __func__, __LINE__, CONFIG_BR_EXT_BRNAME);
- }
- }
- adapter->ethBrExtInfo.addPPPoETag = 1;
-
- rcu_read_unlock();
-}
-
int _netdev_open(struct net_device *pnetdev)
{
uint status;
@@ -1046,7 +971,6 @@ int _netdev_open(struct net_device *pnetdev)
if (!padapter->bup) {
padapter->bDriverStopped = false;
padapter->bSurpriseRemoved = false;
- padapter->bCardDisableWOHSM = false;
status = rtw_hal_init(padapter);
if (status == _FAIL) {
@@ -1086,8 +1010,6 @@ int _netdev_open(struct net_device *pnetdev)
else
netif_tx_wake_all_queues(pnetdev);
- netdev_br_init(pnetdev);
-
netdev_open_normal_process:
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - dev_open\n"));
DBG_88E("-88eu_drv - drv_open, bup =%d\n", padapter->bup);
@@ -1107,9 +1029,9 @@ int netdev_open(struct net_device *pnetdev)
int ret;
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
- _enter_critical_mutex(padapter->hw_init_mutex, NULL);
+ _enter_critical_mutex(&padapter->hw_init_mutex, NULL);
ret = _netdev_open(pnetdev);
- mutex_unlock(padapter->hw_init_mutex);
+ mutex_unlock(&padapter->hw_init_mutex);
return ret;
}
@@ -1121,7 +1043,6 @@ static int ips_netdrv_open(struct adapter *padapter)
padapter->bDriverStopped = false;
padapter->bSurpriseRemoved = false;
- padapter->bCardDisableWOHSM = false;
status = rtw_hal_init(padapter);
if (status == _FAIL) {
@@ -1164,13 +1085,11 @@ void rtw_ips_pwr_down(struct adapter *padapter)
u32 start_time = jiffies;
DBG_88E("===> rtw_ips_pwr_down...................\n");
- padapter->bCardDisableWOHSM = true;
padapter->net_closed = true;
rtw_led_control(padapter, LED_CTL_POWER_OFF);
rtw_ips_dev_unload(padapter);
- padapter->bCardDisableWOHSM = false;
DBG_88E("<=== rtw_ips_pwr_down..................... in %dms\n", rtw_get_passing_time_ms(start_time));
}
@@ -1235,12 +1154,6 @@ int netdev_close(struct net_device *pnetdev)
rtw_led_control(padapter, LED_CTL_POWER_OFF);
}
- nat25_db_cleanup(padapter);
-
-#ifdef CONFIG_88EU_P2P
- rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);
-#endif /* CONFIG_88EU_P2P */
-
kfree(dvobj->firmware.szFwBuffer);
dvobj->firmware.szFwBuffer = NULL;
diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
index 2579a404a766..8af4a8d24cce 100644
--- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c
+++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
@@ -22,6 +22,7 @@
#define _OSDEP_SERVICE_C_
#include <osdep_service.h>
+#include <osdep_intf.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <linux/vmalloc.h>
@@ -38,23 +39,6 @@ inline int RTW_STATUS_CODE(int error_code)
return _FAIL;
}
-u32 rtw_atoi(u8 *s)
-{
- int num = 0, flag = 0;
- int i;
- for (i = 0; i <= strlen(s); i++) {
- if (s[i] >= '0' && s[i] <= '9')
- num = num * 10 + s[i] - '0';
- else if (s[0] == '-' && i == 0)
- flag = 1;
- else
- break;
- }
- if (flag == 1)
- num = num * -1;
- return num;
-}
-
u8 *_rtw_malloc(u32 sz)
{
u8 *pbuf = NULL;
@@ -63,20 +47,11 @@ u8 *_rtw_malloc(u32 sz)
return pbuf;
}
-u8 *_rtw_zmalloc(u32 sz)
-{
- u8 *pbuf = _rtw_malloc(sz);
-
- if (pbuf != NULL)
- memset(pbuf, 0, sz);
- return pbuf;
-}
-
void *rtw_malloc2d(int h, int w, int size)
{
int j;
- void **a = (void **)rtw_zmalloc(h*sizeof(void *) + h*w*size);
+ void **a = (void **)kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL);
if (a == NULL) {
pr_info("%s: alloc memory fail!\n", __func__);
return NULL;
@@ -88,48 +63,6 @@ void *rtw_malloc2d(int h, int w, int size)
return a;
}
-void rtw_mfree2d(void *pbuf, int h, int w, int size)
-{
- kfree(pbuf);
-}
-
-void _rtw_memset(void *pbuf, int c, u32 sz)
-{
- memset(pbuf, c, sz);
-}
-
-void _rtw_init_listhead(struct list_head *list)
-{
- INIT_LIST_HEAD(list);
-}
-
-/*
-For the following list_xxx operations,
-caller must guarantee the atomic context.
-Otherwise, there will be racing condition.
-*/
-u32 rtw_is_list_empty(struct list_head *phead)
-{
- if (list_empty(phead))
- return true;
- else
- return false;
-}
-
-void rtw_list_insert_head(struct list_head *plist, struct list_head *phead)
-{
- list_add(plist, phead);
-}
-
-void rtw_list_insert_tail(struct list_head *plist, struct list_head *phead)
-{
- list_add_tail(plist, phead);
-}
-
-/*
-Caller must check if the list is empty before calling rtw_list_delete
-*/
-
u32 _rtw_down_sema(struct semaphore *sema)
{
if (down_interruptible(sema))
@@ -140,58 +73,16 @@ u32 _rtw_down_sema(struct semaphore *sema)
void _rtw_init_queue(struct __queue *pqueue)
{
- _rtw_init_listhead(&(pqueue->queue));
+ INIT_LIST_HEAD(&(pqueue->queue));
spin_lock_init(&(pqueue->lock));
}
-u32 _rtw_queue_empty(struct __queue *pqueue)
-{
- return rtw_is_list_empty(&(pqueue->queue));
-}
-
-u32 rtw_end_of_queue_search(struct list_head *head, struct list_head *plist)
-{
- if (head == plist)
- return true;
- else
- return false;
-}
-
-inline u32 rtw_systime_to_ms(u32 systime)
-{
- return systime * 1000 / HZ;
-}
-
-inline u32 rtw_ms_to_systime(u32 ms)
-{
- return ms * HZ / 1000;
-}
-
/* the input parameter start must be in jiffies */
inline s32 rtw_get_passing_time_ms(u32 start)
{
- return rtw_systime_to_ms(jiffies-start);
+ return jiffies_to_msecs(jiffies-start);
}
-inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
-{
- return rtw_systime_to_ms(end-start);
-}
-
-void rtw_sleep_schedulable(int ms)
-{
- u32 delta;
-
- delta = (ms * HZ)/1000;/* ms) */
- if (delta == 0)
- delta = 1;/* 1 ms */
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(delta) != 0)
- return;
-}
-
-#define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
-
struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv,
void *old_priv)
{
@@ -210,29 +101,6 @@ RETURN:
return pnetdev;
}
-struct net_device *rtw_alloc_etherdev(int sizeof_priv)
-{
- struct net_device *pnetdev;
- struct rtw_netdev_priv_indicator *pnpi;
-
- pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
- if (!pnetdev)
- goto RETURN;
-
- pnpi = netdev_priv(pnetdev);
-
- pnpi->priv = vzalloc(sizeof_priv);
- if (!pnpi->priv) {
- free_netdev(pnetdev);
- pnetdev = NULL;
- goto RETURN;
- }
-
- pnpi->sizeof_priv = sizeof_priv;
-RETURN:
- return pnetdev;
-}
-
void rtw_free_netdev(struct net_device *netdev)
{
struct rtw_netdev_priv_indicator *pnpi;
@@ -252,72 +120,11 @@ RETURN:
return;
}
-int rtw_change_ifname(struct adapter *padapter, const char *ifname)
-{
- struct net_device *pnetdev;
- struct net_device *cur_pnetdev;
- struct rereg_nd_name_data *rereg_priv;
- int ret;
-
- if (!padapter)
- goto error;
-
- cur_pnetdev = padapter->pnetdev;
- rereg_priv = &padapter->rereg_nd_name_priv;
-
- /* free the old_pnetdev */
- if (rereg_priv->old_pnetdev) {
- free_netdev(rereg_priv->old_pnetdev);
- rereg_priv->old_pnetdev = NULL;
- }
-
- if (!rtnl_is_locked())
- unregister_netdev(cur_pnetdev);
- else
- unregister_netdevice(cur_pnetdev);
-
- rtw_proc_remove_one(cur_pnetdev);
-
- rereg_priv->old_pnetdev = cur_pnetdev;
-
- pnetdev = rtw_init_netdev(padapter);
- if (!pnetdev) {
- ret = -1;
- goto error;
- }
-
- SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
-
- rtw_init_netdev_name(pnetdev, ifname);
-
- memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
-
- if (!rtnl_is_locked())
- ret = register_netdev(pnetdev);
- else
- ret = register_netdevice(pnetdev);
- if (ret != 0) {
- RT_TRACE(_module_hci_intfs_c_, _drv_err_,
- ("register_netdev() failed\n"));
- goto error;
- }
- rtw_proc_init_one(pnetdev);
- return 0;
-error:
- return -1;
-}
-
u64 rtw_modular64(u64 x, u64 y)
{
return do_div(x, y);
}
-u64 rtw_division64(u64 x, u64 y)
-{
- do_div(x, y);
- return x;
-}
-
void rtw_buf_free(u8 **buf, u32 *buf_len)
{
*buf_len = 0;
@@ -356,89 +163,3 @@ keep_ori:
/* free ori */
kfree(ori);
}
-
-
-/**
- * rtw_cbuf_full - test if cbuf is full
- * @cbuf: pointer of struct rtw_cbuf
- *
- * Returns: true if cbuf is full
- */
-inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
-{
- return (cbuf->write == cbuf->read-1) ? true : false;
-}
-
-/**
- * rtw_cbuf_empty - test if cbuf is empty
- * @cbuf: pointer of struct rtw_cbuf
- *
- * Returns: true if cbuf is empty
- */
-inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
-{
- return (cbuf->write == cbuf->read) ? true : false;
-}
-
-/**
- * rtw_cbuf_push - push a pointer into cbuf
- * @cbuf: pointer of struct rtw_cbuf
- * @buf: pointer to push in
- *
- * Lock free operation, be careful of the use scheme
- * Returns: true push success
- */
-bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
-{
- if (rtw_cbuf_full(cbuf))
- return _FAIL;
-
- if (0)
- DBG_88E("%s on %u\n", __func__, cbuf->write);
- cbuf->bufs[cbuf->write] = buf;
- cbuf->write = (cbuf->write+1)%cbuf->size;
-
- return _SUCCESS;
-}
-
-/**
- * rtw_cbuf_pop - pop a pointer from cbuf
- * @cbuf: pointer of struct rtw_cbuf
- *
- * Lock free operation, be careful of the use scheme
- * Returns: pointer popped out
- */
-void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
-{
- void *buf;
- if (rtw_cbuf_empty(cbuf))
- return NULL;
-
- if (0)
- DBG_88E("%s on %u\n", __func__, cbuf->read);
- buf = cbuf->bufs[cbuf->read];
- cbuf->read = (cbuf->read+1)%cbuf->size;
-
- return buf;
-}
-
-/**
- * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
- * @size: size of pointer
- *
- * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
- */
-struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
-{
- struct rtw_cbuf *cbuf;
-
- cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) +
- sizeof(void *)*size);
-
- if (cbuf) {
- cbuf->write = 0;
- cbuf->read = 0;
- cbuf->size = size;
- }
- return cbuf;
-}
diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
index c0fa8fdb9d92..05427c489b3f 100644
--- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
@@ -26,7 +26,7 @@
#include <recv_osdep.h>
#include <osdep_intf.h>
-#include <usb_ops.h>
+#include <usb_ops_linux.h>
/* alloc os related resource in struct recv_frame */
int rtw_os_recv_resource_alloc(struct adapter *padapter,
@@ -73,7 +73,7 @@ void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
}
}
- _rtw_memset(&ev, 0x00, sizeof(ev));
+ memset(&ev, 0x00, sizeof(ev));
if (bgroup)
ev.flags |= IW_MICFAILURE_GROUP;
else
@@ -81,7 +81,7 @@ void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
ev.src_addr.sa_family = ARPHRD_ETHER;
memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
- _rtw_memset(&wrqu, 0x00, sizeof(wrqu));
+ memset(&wrqu, 0x00, sizeof(wrqu));
wrqu.data.length = sizeof(ev);
wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE,
&wrqu, (char *)&ev);
@@ -191,29 +191,9 @@ _recv_indicatepkt_drop:
return _FAIL;
}
-void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf)
-{
- struct recv_priv *precvpriv = &padapter->recvpriv;
-
- /* free skb in recv_buf */
- dev_kfree_skb_any(precvbuf->pskb);
- precvbuf->pskb = NULL;
- precvbuf->reuse = false;
- rtw_read_port(padapter, precvpriv->ff_hwaddr, 0,
- (unsigned char *)precvbuf);
-}
-
-static void _rtw_reordering_ctrl_timeout_handler(void *func_context)
-{
- struct recv_reorder_ctrl *preorder_ctrl;
-
- preorder_ctrl = (struct recv_reorder_ctrl *)func_context;
- rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
-}
-
void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
{
struct adapter *padapter = preorder_ctrl->padapter;
- _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl);
+ _init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, rtw_reordering_ctrl_timeout_handler, preorder_ctrl);
}
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index 7526b989dcbf..b8676ac77b0c 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -24,27 +24,16 @@
#include <recv_osdep.h>
#include <xmit_osdep.h>
#include <hal_intf.h>
-#include <rtw_version.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <osdep_intf.h>
-#include <usb_vendor_req.h>
-#include <usb_ops.h>
-#include <usb_osintf.h>
+#include <usb_ops_linux.h>
#include <usb_hal.h>
#include <rtw_ioctl.h>
int ui_pid[3] = {0, 0, 0};
-static int rtw_suspend(struct usb_interface *intf, pm_message_t message);
-static int rtw_resume(struct usb_interface *intf);
-
-
-static int rtw_drv_init(struct usb_interface *pusb_intf, const struct usb_device_id *pdid);
-static void rtw_dev_remove(struct usb_interface *pusb_intf);
-
-
#define USB_VENDER_ID_REALTEK 0x0bda
/* DID_USB_v916_20130116 */
@@ -62,50 +51,6 @@ static struct usb_device_id rtw_usb_id_tbl[] = {
MODULE_DEVICE_TABLE(usb, rtw_usb_id_tbl);
-struct rtw_usb_drv {
- struct usb_driver usbdrv;
- int drv_registered;
- struct mutex hw_init_mutex;
-};
-
-static struct rtw_usb_drv rtl8188e_usb_drv = {
- .usbdrv.name = "r8188eu",
- .usbdrv.probe = rtw_drv_init,
- .usbdrv.disconnect = rtw_dev_remove,
- .usbdrv.id_table = rtw_usb_id_tbl,
- .usbdrv.suspend = rtw_suspend,
- .usbdrv.resume = rtw_resume,
- .usbdrv.reset_resume = rtw_resume,
-};
-
-static struct rtw_usb_drv *usb_drv = &rtl8188e_usb_drv;
-
-static u8 rtw_init_intf_priv(struct dvobj_priv *dvobj)
-{
- u8 rst = _SUCCESS;
-
- mutex_init(&dvobj->usb_vendor_req_mutex);
-
- dvobj->usb_alloc_vendor_req_buf = rtw_zmalloc(MAX_USB_IO_CTL_SIZE);
- if (dvobj->usb_alloc_vendor_req_buf == NULL) {
- DBG_88E("alloc usb_vendor_req_buf failed...\n");
- rst = _FAIL;
- goto exit;
- }
- dvobj->usb_vendor_req_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(dvobj->usb_alloc_vendor_req_buf), ALIGNMENT_UNIT);
-exit:
- return rst;
-}
-
-static u8 rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
-{
- u8 rst = _SUCCESS;
-
- kfree(dvobj->usb_alloc_vendor_req_buf);
- mutex_destroy(&dvobj->usb_vendor_req_mutex);
- return rst;
-}
-
static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
{
int i;
@@ -120,7 +65,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
struct usb_device *pusbd;
- pdvobjpriv = (struct dvobj_priv *)rtw_zmalloc(sizeof(*pdvobjpriv));
+ pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
if (pdvobjpriv == NULL)
goto exit;
@@ -169,11 +114,11 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
else
pdvobjpriv->ishighspeed = false;
- if (rtw_init_intf_priv(pdvobjpriv) == _FAIL)
- goto free_dvobj;
+ mutex_init(&pdvobjpriv->usb_vendor_req_mutex);
+ pdvobjpriv->usb_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE, GFP_KERNEL);
- sema_init(&(pdvobjpriv->usb_suspend_sema), 0);
- rtw_reset_continual_urb_error(pdvobjpriv);
+ if (!pdvobjpriv->usb_vendor_req_buf)
+ goto free_dvobj;
usb_get_dev(pusbd);
@@ -211,7 +156,9 @@ static void usb_dvobj_deinit(struct usb_interface *usb_intf)
usb_reset_device(interface_to_usbdev(usb_intf));
}
}
- rtw_deinit_intf_priv(dvobj);
+
+ kfree(dvobj->usb_vendor_req_buf);
+ mutex_destroy(&dvobj->usb_vendor_req_mutex);
kfree(dvobj);
}
@@ -244,7 +191,7 @@ static void usb_intf_stop(struct adapter *padapter)
rtw_hal_inirp_deinit(padapter);
/* cancel out irp */
- rtw_write_port_cancel(padapter);
+ usb_write_port_cancel(padapter);
/* todo:cancel other irps */
@@ -284,108 +231,6 @@ static void rtw_dev_unload(struct adapter *padapter)
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
}
-int rtw_hw_suspend(struct adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct net_device *pnetdev = padapter->pnetdev;
-
-
- if ((!padapter->bup) || (padapter->bDriverStopped) ||
- (padapter->bSurpriseRemoved)) {
- DBG_88E("padapter->bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n",
- padapter->bup, padapter->bDriverStopped,
- padapter->bSurpriseRemoved);
- goto error_exit;
- }
-
- /* system suspend */
- LeaveAllPowerSaveMode(padapter);
-
- DBG_88E("==> rtw_hw_suspend\n");
- _enter_pwrlock(&pwrpriv->lock);
- pwrpriv->bips_processing = true;
- /* s1. */
- if (pnetdev) {
- netif_carrier_off(pnetdev);
- netif_tx_stop_all_queues(pnetdev);
- }
-
- /* s2. */
- rtw_disassoc_cmd(padapter, 500, false);
-
- /* s2-2. indicate disconnect to os */
- {
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- _clr_fwstate_(pmlmepriv, _FW_LINKED);
-
- rtw_led_control(padapter, LED_CTL_NO_LINK);
-
- rtw_os_indicate_disconnect(padapter);
-
- /* donnot enqueue cmd */
- rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0);
- }
- }
- /* s2-3. */
- rtw_free_assoc_resources(padapter, 1);
-
- /* s2-4. */
- rtw_free_network_queue(padapter, true);
- rtw_ips_dev_unload(padapter);
- pwrpriv->rf_pwrstate = rf_off;
- pwrpriv->bips_processing = false;
-
- _exit_pwrlock(&pwrpriv->lock);
-
- return 0;
-
-error_exit:
- DBG_88E("%s, failed\n", __func__);
- return -1;
-}
-
-int rtw_hw_resume(struct adapter *padapter)
-{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct net_device *pnetdev = padapter->pnetdev;
-
-
- /* system resume */
- DBG_88E("==> rtw_hw_resume\n");
- _enter_pwrlock(&pwrpriv->lock);
- pwrpriv->bips_processing = true;
- rtw_reset_drv_sw(padapter);
-
- if (pm_netdev_open(pnetdev, false) != 0) {
- _exit_pwrlock(&pwrpriv->lock);
- goto error_exit;
- }
-
- netif_device_attach(pnetdev);
- netif_carrier_on(pnetdev);
-
- if (!netif_queue_stopped(pnetdev))
- netif_start_queue(pnetdev);
- else
- netif_wake_queue(pnetdev);
-
- pwrpriv->bkeepfwalive = false;
- pwrpriv->brfoffbyhw = false;
-
- pwrpriv->rf_pwrstate = rf_on;
- pwrpriv->bips_processing = false;
-
- _exit_pwrlock(&pwrpriv->lock);
-
-
- return 0;
-error_exit:
- DBG_88E("%s, Open net dev failed\n", __func__);
- return -1;
-}
-
static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
{
struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
@@ -456,21 +301,7 @@ exit:
return ret;
}
-static int rtw_resume(struct usb_interface *pusb_intf)
-{
- struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
- struct adapter *padapter = dvobj->if1;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- int ret = 0;
-
- if (pwrpriv->bInternalAutoSuspend)
- ret = rtw_resume_process(padapter);
- else
- ret = rtw_resume_process(padapter);
- return ret;
-}
-
-int rtw_resume_process(struct adapter *padapter)
+static int rtw_resume_process(struct adapter *padapter)
{
struct net_device *pnetdev;
struct pwrctrl_priv *pwrpriv = NULL;
@@ -517,6 +348,14 @@ exit:
return ret;
}
+static int rtw_resume(struct usb_interface *pusb_intf)
+{
+ struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
+ struct adapter *padapter = dvobj->if1;
+
+ return rtw_resume_process(padapter);
+}
+
/*
* drv_init() - a device potentially for us
*
@@ -539,7 +378,7 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
dvobj->if1 = padapter;
padapter->bDriverStopped = true;
- padapter->hw_init_mutex = &usb_drv->hw_init_mutex;
+ mutex_init(&padapter->hw_init_mutex);
padapter->chip_type = RTL8188E;
pnetdev = rtw_init_netdev(padapter);
@@ -554,9 +393,6 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
padapter->intf_start = &usb_intf_start;
padapter->intf_stop = &usb_intf_stop;
- /* step init_io_priv */
- rtw_init_io_priv(padapter, usb_set_intf_ops);
-
/* step read_chip_version */
rtw_hal_read_chip_version(padapter);
@@ -592,10 +428,6 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
/* alloc dev name after read efuse. */
rtw_init_netdev_name(pnetdev, padapter->registrypriv.ifname);
rtw_macaddr_cfg(padapter->eeprompriv.mac_addr);
-#ifdef CONFIG_88EU_P2P
- rtw_init_wifidirect_addrs(padapter, padapter->eeprompriv.mac_addr,
- padapter->eeprompriv.mac_addr);
-#endif
memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
DBG_88E("MAC Address from pnetdev->dev_addr = %pM\n",
pnetdev->dev_addr);
@@ -642,12 +474,10 @@ static void rtw_usb_if1_deinit(struct adapter *if1)
free_mlme_ap_info(if1);
#endif
- if (if1->DriverState != DRIVER_DISAPPEAR) {
- if (pnetdev) {
- /* will call netdev_close() */
- unregister_netdev(pnetdev);
- rtw_proc_remove_one(pnetdev);
- }
+ if (pnetdev) {
+ /* will call netdev_close() */
+ unregister_netdev(pnetdev);
+ rtw_proc_remove_one(pnetdev);
}
rtw_cancel_all_timer(if1);
@@ -710,7 +540,7 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf)
DBG_88E("+rtw_dev_remove\n");
RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+dev_remove()\n"));
- if (usb_drv->drv_registered)
+ if (!pusb_intf->unregistering)
padapter->bSurpriseRemoved = true;
rtw_pm_set_ips(padapter, IPS_NONE);
@@ -728,29 +558,14 @@ static void rtw_dev_remove(struct usb_interface *pusb_intf)
return;
}
-static int __init rtw_drv_entry(void)
-{
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_entry\n"));
-
- DBG_88E(DRV_NAME " driver version=%s\n", DRIVERVERSION);
-
- mutex_init(&usb_drv->hw_init_mutex);
-
- usb_drv->drv_registered = true;
- return usb_register(&usb_drv->usbdrv);
-}
-
-static void __exit rtw_drv_halt(void)
-{
- RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("+rtw_drv_halt\n"));
- DBG_88E("+rtw_drv_halt\n");
-
- usb_drv->drv_registered = false;
- usb_deregister(&usb_drv->usbdrv);
-
- mutex_destroy(&usb_drv->hw_init_mutex);
- DBG_88E("-rtw_drv_halt\n");
-}
+static struct usb_driver rtl8188e_usb_drv = {
+ .name = "r8188eu",
+ .probe = rtw_drv_init,
+ .disconnect = rtw_dev_remove,
+ .id_table = rtw_usb_id_tbl,
+ .suspend = rtw_suspend,
+ .resume = rtw_resume,
+ .reset_resume = rtw_resume,
+};
-module_init(rtw_drv_entry);
-module_exit(rtw_drv_halt);
+module_usb_driver(rtl8188e_usb_drv)
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
index ba2a8ab80d77..ba1e178fb510 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
@@ -19,9 +19,197 @@
#define _USB_OPS_LINUX_C_
#include <drv_types.h>
-#include <usb_ops_linux.h>
+#include <recv_osdep.h>
#include <rtw_sreset.h>
+static void interrupt_handler_8188eu(struct adapter *adapt, u16 pkt_len, u8 *pbuf)
+{
+ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+
+ if (pkt_len != INTERRUPT_MSG_FORMAT_LEN) {
+ DBG_88E("%s Invalid interrupt content length (%d)!\n", __func__, pkt_len);
+ return;
+ }
+
+ /* HISR */
+ memcpy(&(haldata->IntArray[0]), &(pbuf[USB_INTR_CONTENT_HISR_OFFSET]), 4);
+ memcpy(&(haldata->IntArray[1]), &(pbuf[USB_INTR_CONTENT_HISRE_OFFSET]), 4);
+
+ /* C2H Event */
+ if (pbuf[0] != 0)
+ memcpy(&(haldata->C2hArray[0]), &(pbuf[USB_INTR_CONTENT_C2H_OFFSET]), 16);
+}
+
+static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
+{
+ u8 *pbuf;
+ u8 shift_sz = 0;
+ u16 pkt_cnt;
+ u32 pkt_offset, skb_len, alloc_sz;
+ s32 transfer_len;
+ struct recv_stat *prxstat;
+ struct phy_stat *pphy_status = NULL;
+ struct sk_buff *pkt_copy = NULL;
+ struct recv_frame *precvframe = NULL;
+ struct rx_pkt_attrib *pattrib = NULL;
+ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ struct recv_priv *precvpriv = &adapt->recvpriv;
+ struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
+
+ transfer_len = (s32)pskb->len;
+ pbuf = pskb->data;
+
+ prxstat = (struct recv_stat *)pbuf;
+ pkt_cnt = (le32_to_cpu(prxstat->rxdw2) >> 16) & 0xff;
+
+ do {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
+ ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
+ prxstat->rxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4));
+
+ prxstat = (struct recv_stat *)pbuf;
+
+ precvframe = rtw_alloc_recvframe(pfree_recv_queue);
+ if (precvframe == NULL) {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvbuf2recvframe: precvframe==NULL\n"));
+ DBG_88E("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __func__, __LINE__);
+ goto _exit_recvbuf2recvframe;
+ }
+
+ INIT_LIST_HEAD(&precvframe->list);
+ precvframe->len = 0;
+
+ update_recvframe_attrib_88e(precvframe, prxstat);
+
+ pattrib = &precvframe->attrib;
+
+ if ((pattrib->crc_err) || (pattrib->icv_err)) {
+ DBG_88E("%s: RX Warning! crc_err=%d icv_err=%d, skip!\n", __func__, pattrib->crc_err, pattrib->icv_err);
+
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+
+ if ((pattrib->physt) && (pattrib->pkt_rpt_type == NORMAL_RX))
+ pphy_status = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
+
+ pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
+
+ if ((pattrib->pkt_len <= 0) || (pkt_offset > transfer_len)) {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recvbuf2recvframe: pkt_len<=0\n"));
+ DBG_88E("%s()-%d: RX Warning!,pkt_len<=0 or pkt_offset> transfoer_len\n", __func__, __LINE__);
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+
+ /* Modified by Albert 20101213 */
+ /* For 8 bytes IP header alignment. */
+ if (pattrib->qos) /* Qos data, wireless lan header length is 26 */
+ shift_sz = 6;
+ else
+ shift_sz = 0;
+
+ skb_len = pattrib->pkt_len;
+
+ /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
+ /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
+ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
+ if (skb_len <= 1650)
+ alloc_sz = 1664;
+ else
+ alloc_sz = skb_len + 14;
+ } else {
+ alloc_sz = skb_len;
+ /* 6 is for IP header 8 bytes alignment in QoS packet case. */
+ /* 8 is for skb->data 4 bytes alignment. */
+ alloc_sz += 14;
+ }
+
+ pkt_copy = netdev_alloc_skb(adapt->pnetdev, alloc_sz);
+ if (pkt_copy) {
+ pkt_copy->dev = adapt->pnetdev;
+ precvframe->pkt = pkt_copy;
+ precvframe->rx_head = pkt_copy->data;
+ precvframe->rx_end = pkt_copy->data + alloc_sz;
+ skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
+ skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
+ memcpy(pkt_copy->data, (pbuf + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
+ precvframe->rx_tail = pkt_copy->data;
+ precvframe->rx_data = pkt_copy->data;
+ } else {
+ if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
+ DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n");
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+ precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
+ if (precvframe->pkt) {
+ precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE;
+ precvframe->rx_head = precvframe->rx_tail;
+ precvframe->rx_data = precvframe->rx_tail;
+ precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz;
+ } else {
+ DBG_88E("recvbuf2recvframe: skb_clone fail\n");
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
+ }
+ }
+
+ recvframe_put(precvframe, skb_len);
+
+ switch (haldata->UsbRxAggMode) {
+ case USB_RX_AGG_DMA:
+ case USB_RX_AGG_MIX:
+ pkt_offset = (u16) round_up(pkt_offset, 128);
+ break;
+ case USB_RX_AGG_USB:
+ pkt_offset = (u16) round_up(pkt_offset, 4);
+ break;
+ case USB_RX_AGG_DISABLE:
+ default:
+ break;
+ }
+ if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */
+ if (pattrib->physt)
+ update_recvframe_phyinfo_88e(precvframe, (struct phy_stat *)pphy_status);
+ if (rtw_recv_entry(precvframe) != _SUCCESS) {
+ RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
+ ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
+ }
+ } else {
+ /* enqueue recvframe to txrtp queue */
+ if (pattrib->pkt_rpt_type == TX_REPORT1) {
+ /* CCX-TXRPT ack for xmit mgmt frames. */
+ handle_txrpt_ccx_88e(adapt, precvframe->rx_data);
+ } else if (pattrib->pkt_rpt_type == TX_REPORT2) {
+ ODM_RA_TxRPT2Handle_8188E(
+ &haldata->odmpriv,
+ precvframe->rx_data,
+ pattrib->pkt_len,
+ pattrib->MacIDValidEntry[0],
+ pattrib->MacIDValidEntry[1]
+ );
+ } else if (pattrib->pkt_rpt_type == HIS_REPORT) {
+ interrupt_handler_8188eu(adapt, pattrib->pkt_len, precvframe->rx_data);
+ }
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ }
+ pkt_cnt--;
+ transfer_len -= pkt_offset;
+ pbuf += pkt_offset;
+ precvframe = NULL;
+ pkt_copy = NULL;
+
+ if (transfer_len > 0 && pkt_cnt == 0)
+ pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
+
+ } while ((transfer_len > 0) && (pkt_cnt > 0));
+
+_exit_recvbuf2recvframe:
+
+ return _SUCCESS;
+}
+
unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
{
unsigned int pipe = 0, ep_num = 0;
@@ -39,19 +227,309 @@ unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
return pipe;
}
-void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
+static int usbctrl_vendorreq(struct adapter *adapt, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
+{
+ struct dvobj_priv *dvobjpriv = adapter_to_dvobj(adapt);
+ struct usb_device *udev = dvobjpriv->pusbdev;
+ unsigned int pipe;
+ int status = 0;
+ u8 reqtype;
+ u8 *pIo_buf;
+ int vendorreq_times = 0;
+
+ if ((adapt->bSurpriseRemoved) || (adapt->pwrctrlpriv.pnp_bstop_trx)) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usbctrl_vendorreq:(adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
+ status = -EPERM;
+ goto exit;
+ }
+
+ if (len > MAX_VENDOR_REQ_CMD_SIZE) {
+ DBG_88E("[%s] Buffer len error ,vendor request failed\n", __func__);
+ status = -EINVAL;
+ goto exit;
+ }
+
+ _enter_critical_mutex(&dvobjpriv->usb_vendor_req_mutex, NULL);
+
+ /* Acquire IO memory for vendorreq */
+ pIo_buf = dvobjpriv->usb_vendor_req_buf;
+
+ if (pIo_buf == NULL) {
+ DBG_88E("[%s] pIo_buf == NULL\n", __func__);
+ status = -ENOMEM;
+ goto release_mutex;
+ }
+
+ while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) {
+ memset(pIo_buf, 0, len);
+
+ if (requesttype == 0x01) {
+ pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
+ reqtype = REALTEK_USB_VENQT_READ;
+ } else {
+ pipe = usb_sndctrlpipe(udev, 0);/* write_out */
+ reqtype = REALTEK_USB_VENQT_WRITE;
+ memcpy(pIo_buf, pdata, len);
+ }
+
+ status = usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
+
+ if (status == len) { /* Success this control transfer. */
+ if (requesttype == 0x01)
+ memcpy(pdata, pIo_buf, len);
+ } else { /* error cases */
+ DBG_88E("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n",
+ value, (requesttype == 0x01) ? "read" : "write",
+ len, status, *(u32 *)pdata, vendorreq_times);
+
+ if (status < 0) {
+ if (status == (-ESHUTDOWN) || status == -ENODEV) {
+ adapt->bSurpriseRemoved = true;
+ } else {
+ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ haldata->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
+ }
+ } else { /* status != len && status >= 0 */
+ if (status > 0) {
+ if (requesttype == 0x01) {
+ /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
+ memcpy(pdata, pIo_buf, len);
+ }
+ }
+ }
+
+ }
+
+ /* firmware download is checksumed, don't retry */
+ if ((value >= FW_8188E_START_ADDRESS && value <= FW_8188E_END_ADDRESS) || status == len)
+ break;
+ }
+release_mutex:
+ mutex_unlock(&dvobjpriv->usb_vendor_req_mutex);
+exit:
+ return status;
+}
+
+u8 usb_read8(struct adapter *adapter, u32 addr)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 data = 0;
+
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 1;
+
+ usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+
+
+ return data;
+
+}
+
+u16 usb_read16(struct adapter *adapter, u32 addr)
{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data;
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 2;
+ usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+
+ return (u16)(le32_to_cpu(data)&0xffff);
}
-void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+u32 usb_read32(struct adapter *adapter, u32 addr)
{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data;
+
+
+ request = 0x05;
+ requesttype = 0x01;/* read_in */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 4;
+
+ usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+
+
+ return le32_to_cpu(data);
}
-void usb_read_port_cancel(struct intf_hdl *pintfhdl)
+static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
+{
+ struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
+ struct adapter *adapt = (struct adapter *)precvbuf->adapter;
+ struct recv_priv *precvpriv = &adapt->recvpriv;
+
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete!!!\n"));
+
+ precvpriv->rx_pending_cnt--;
+
+ if (adapt->bSurpriseRemoved || adapt->bDriverStopped || adapt->bReadPortCancel) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+ ("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
+ adapt->bDriverStopped, adapt->bSurpriseRemoved));
+
+ precvbuf->reuse = true;
+ DBG_88E("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
+ __func__, adapt->bDriverStopped,
+ adapt->bSurpriseRemoved, adapt->bReadPortCancel);
+ return;
+ }
+
+ if (purb->status == 0) { /* SUCCESS */
+ if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+ ("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
+ precvbuf->reuse = true;
+ usb_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
+ DBG_88E("%s()-%d: RX Warning!\n", __func__, __LINE__);
+ } else {
+ skb_put(precvbuf->pskb, purb->actual_length);
+ skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
+
+ if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
+ tasklet_schedule(&precvpriv->recv_tasklet);
+
+ precvbuf->pskb = NULL;
+ precvbuf->reuse = false;
+ usb_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
+ }
+ } else {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete : purb->status(%d) != 0\n", purb->status));
+
+ DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
+ skb_put(precvbuf->pskb, purb->actual_length);
+ precvbuf->pskb = NULL;
+
+ switch (purb->status) {
+ case -EINVAL:
+ case -EPIPE:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ adapt->bSurpriseRemoved = true;
+ case -ENOENT:
+ adapt->bDriverStopped = true;
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete:bDriverStopped=true\n"));
+ break;
+ case -EPROTO:
+ case -EOVERFLOW:
+ {
+ struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
+ haldata->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
+ }
+ precvbuf->reuse = true;
+ usb_read_port(adapt, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
+ break;
+ case -EINPROGRESS:
+ DBG_88E("ERROR: URB IS IN PROGRESS!\n");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+u32 usb_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *rmem)
+{
+ struct urb *purb = NULL;
+ struct recv_buf *precvbuf = (struct recv_buf *)rmem;
+ struct dvobj_priv *pdvobj = adapter_to_dvobj(adapter);
+ struct recv_priv *precvpriv = &adapter->recvpriv;
+ struct usb_device *pusbd = pdvobj->pusbdev;
+ int err;
+ unsigned int pipe;
+ size_t tmpaddr = 0;
+ size_t alignment = 0;
+ u32 ret = _SUCCESS;
+
+
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
+ adapter->pwrctrlpriv.pnp_bstop_trx) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+ ("usb_read_port:(adapt->bDriverStopped ||adapt->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
+ return _FAIL;
+ }
+
+ if (!precvbuf) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+ ("usb_read_port:precvbuf==NULL\n"));
+ return _FAIL;
+ }
+
+ if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
+ precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
+ if (NULL != precvbuf->pskb)
+ precvbuf->reuse = true;
+ }
+
+ /* re-assign for linux based on skb */
+ if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
+ precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+ if (precvbuf->pskb == NULL) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
+ DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
+ return _FAIL;
+ }
+
+ tmpaddr = (size_t)precvbuf->pskb->data;
+ alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+ skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+ } else { /* reuse skb */
+ precvbuf->reuse = false;
+ }
+
+ precvpriv->rx_pending_cnt++;
+
+ purb = precvbuf->purb;
+
+ /* translate DMA FIFO addr to pipehandle */
+ pipe = ffaddr2pipehdl(pdvobj, addr);
+
+ usb_fill_bulk_urb(purb, pusbd, pipe,
+ precvbuf->pskb->data,
+ MAX_RECVBUF_SZ,
+ usb_read_port_complete,
+ precvbuf);/* context is precvbuf */
+
+ err = usb_submit_urb(purb, GFP_ATOMIC);
+ if ((err) && (err != (-EPERM))) {
+ RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+ ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
+ err, purb->status));
+ DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
+ err, purb->status);
+ ret = _FAIL;
+ }
+
+ return ret;
+}
+
+void usb_read_port_cancel(struct adapter *padapter)
{
int i;
struct recv_buf *precvbuf;
- struct adapter *padapter = pintfhdl->padapter;
precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
DBG_88E("%s\n", __func__);
@@ -66,13 +544,109 @@ void usb_read_port_cancel(struct intf_hdl *pintfhdl)
}
}
+int usb_write8(struct adapter *adapter, u32 addr, u8 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 data;
+ int ret;
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 1;
+ data = val;
+ ret = usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+ return ret;
+}
+
+int usb_write16(struct adapter *adapter, u32 addr, u16 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data;
+ int ret;
+
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 2;
+
+ data = cpu_to_le32(val & 0x0000ffff);
+
+ ret = usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+
+
+ return ret;
+}
+
+int usb_write32(struct adapter *adapter, u32 addr, u32 val)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ __le32 data;
+ int ret;
+
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr&0x0000ffff);
+ len = 4;
+ data = cpu_to_le32(val);
+
+ ret = usbctrl_vendorreq(adapter, request, wvalue, index, &data, len, requesttype);
+
+
+ return ret;
+}
+
+int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata)
+{
+ u8 request;
+ u8 requesttype;
+ u16 wvalue;
+ u16 index;
+ u16 len;
+ u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
+ int ret;
+
+
+ request = 0x05;
+ requesttype = 0x00;/* write_out */
+ index = 0;/* n/a */
+
+ wvalue = (u16)(addr&0x0000ffff);
+ len = length;
+ memcpy(buf, pdata, len);
+
+ ret = usbctrl_vendorreq(adapter, request, wvalue, index, buf, len, requesttype);
+
+
+ return RTW_STATUS_CODE(ret);
+}
+
+
+
static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
{
struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
struct adapter *padapter = pxmitbuf->padapter;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct hal_data_8188e *haldata;
-
switch (pxmitbuf->flags) {
case VO_QUEUE_INX:
@@ -137,9 +711,6 @@ static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
}
}
- haldata = GET_HAL_DATA(padapter);
- haldata->srestpriv.last_tx_complete_time = jiffies;
-
check_completion:
rtw_sctx_done_err(&pxmitbuf->sctx,
purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
@@ -150,14 +721,13 @@ check_completion:
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
}
-u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
+u32 usb_write_port(struct adapter *padapter, u32 addr, u32 cnt, u8 *wmem)
{
unsigned long irqL;
unsigned int pipe;
int status;
u32 ret = _FAIL;
struct urb *purb = NULL;
- struct adapter *padapter = (struct adapter *)pintfhdl->padapter;
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
@@ -216,11 +786,7 @@ u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
pxmitbuf);/* context is pxmitbuf */
status = usb_submit_urb(purb, GFP_ATOMIC);
- if (!status) {
- struct hal_data_8188e *haldata = GET_HAL_DATA(padapter);
-
- haldata->srestpriv.last_tx_time = jiffies;
- } else {
+ if (status) {
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
DBG_88E("usb_write_port, status =%d\n", status);
RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_write_port(): usb_submit_urb, status =%x\n", status));
@@ -247,10 +813,9 @@ exit:
return ret;
}
-void usb_write_port_cancel(struct intf_hdl *pintfhdl)
+void usb_write_port_cancel(struct adapter *padapter)
{
int i, j;
- struct adapter *padapter = pintfhdl->padapter;
struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
DBG_88E("%s\n", __func__);
@@ -274,3 +839,46 @@ void usb_write_port_cancel(struct intf_hdl *pintfhdl)
pxmitbuf++;
}
}
+
+void rtl8188eu_recv_tasklet(void *priv)
+{
+ struct sk_buff *pskb;
+ struct adapter *adapt = (struct adapter *)priv;
+ struct recv_priv *precvpriv = &adapt->recvpriv;
+
+ while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
+ if ((adapt->bDriverStopped) || (adapt->bSurpriseRemoved)) {
+ DBG_88E("recv_tasklet => bDriverStopped or bSurpriseRemoved\n");
+ dev_kfree_skb_any(pskb);
+ break;
+ }
+ recvbuf2recvframe(adapt, pskb);
+ skb_reset_tail_pointer(pskb);
+ pskb->len = 0;
+ skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
+ }
+}
+
+void rtl8188eu_xmit_tasklet(void *priv)
+{
+ int ret = false;
+ struct adapter *adapt = (struct adapter *)priv;
+ struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
+
+ if (check_fwstate(&adapt->mlmepriv, _FW_UNDER_SURVEY))
+ return;
+
+ while (1) {
+ if ((adapt->bDriverStopped) ||
+ (adapt->bSurpriseRemoved) ||
+ (adapt->bWritePortCancel)) {
+ DBG_88E("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
+ break;
+ }
+
+ ret = rtl8188eu_xmitframe_complete(adapt, pxmitpriv, NULL);
+
+ if (!ret)
+ break;
+ }
+}
diff --git a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
index 400356831c5e..0ce47b07ef86 100644
--- a/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/xmit_linux.c
@@ -26,7 +26,6 @@
#include <mlme_osdep.h>
#include <xmit_osdep.h>
#include <osdep_intf.h>
-#include <usb_osintf.h>
uint rtw_remainder_len(struct pkt_file *pfile)
{
@@ -80,7 +79,7 @@ int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitb
{
int i;
- pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
+ pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL);
if (pxmitbuf->pallocated_buf == NULL)
return _FAIL;
@@ -184,7 +183,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
plist = phead->next;
/* free sta asoc_queue */
- while (!rtw_end_of_queue_search(phead, plist)) {
+ while (phead != plist) {
psta = container_of(plist, struct sta_info, asoc_list);
plist = plist->next;
diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c
index 53da61072992..bfcc935d48de 100644
--- a/drivers/staging/rtl8192e/dot11d.c
+++ b/drivers/staging/rtl8192e/dot11d.c
@@ -133,12 +133,12 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3);
for (i = 0; i < NumTriples; i++) {
if (MaxChnlNum >= pTriple->FirstChnl) {
- printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+ netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
return;
}
if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl +
pTriple->NumChnls)) {
- printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+ netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
return;
}
@@ -165,7 +165,7 @@ u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel)
u8 MaxTxPwrInDbm = 255;
if (MAX_CHANNEL_NUMBER < Channel) {
- printk(KERN_INFO "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+ netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
return MaxTxPwrInDbm;
}
if (pDot11dInfo->channel_map[Channel])
@@ -204,7 +204,7 @@ int ToLegalChannel(struct rtllib_device *dev, u8 channel)
}
if (MAX_CHANNEL_NUMBER < channel) {
- printk(KERN_ERR "%s(): Invalid Channel\n", __func__);
+ netdev_err(dev->dev, "%s(): Invalid Channel\n", __func__);
return default_chn;
}
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
index 136909eff6d5..ba95149fa42e 100644
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ b/drivers/staging/rtl8192e/rtllib_module.c
@@ -111,7 +111,7 @@ struct net_device *alloc_rtllib(int sizeof_priv)
dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
if (!dev) {
RTLLIB_ERROR("Unable to network device.\n");
- goto failed;
+ return NULL;
}
ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
@@ -180,8 +180,7 @@ struct net_device *alloc_rtllib(int sizeof_priv)
return dev;
failed:
- if (dev)
- free_netdev(dev);
+ free_netdev(dev);
return NULL;
}
EXPORT_SYMBOL(alloc_rtllib);
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
index 60de54cc601f..7db3e7445428 100644
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/drivers/staging/rtl8192e/rtllib_rx.c
@@ -1496,7 +1496,8 @@ int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb,
return ret;
rx_dropped:
- ieee->stats.rx_dropped++;
+ if (ieee)
+ ieee->stats.rx_dropped++;
return 0;
}
EXPORT_SYMBOL(rtllib_rx);
diff --git a/drivers/staging/rtl8192ee/Kconfig b/drivers/staging/rtl8192ee/Kconfig
index beb07ac24e80..8d77f28399d3 100644
--- a/drivers/staging/rtl8192ee/Kconfig
+++ b/drivers/staging/rtl8192ee/Kconfig
@@ -7,7 +7,6 @@ config R8192EE
select EEPROM_93CX6
select CRYPTO
select FW_LOADER
- default N
---help---
This is the driver for Realtek RTL8192EE 802.11 PCIe
wireless network adapters.
diff --git a/drivers/staging/rtl8192ee/base.c b/drivers/staging/rtl8192ee/base.c
index 64ade216a153..f7c3c8bf71a5 100644
--- a/drivers/staging/rtl8192ee/base.c
+++ b/drivers/staging/rtl8192ee/base.c
@@ -469,7 +469,7 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
rtl92e_easy_concurrent_retrytimer_callback, (unsigned long)hw);
/* <2> work queue */
rtlpriv->works.hw = hw;
- rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
+ rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
(void *)rtl92e_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
@@ -826,8 +826,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw,
u8 hw_rate;
u16 map = le16_to_cpu(sta->vht_cap.vht_mcs.tx_mcs_map);
- if ((get_rf_type(rtlphy) == RF_2T2R) &&
- (map & 0x000c) != 0x000c0) {
+ if (get_rf_type(rtlphy) == RF_2T2R) {
if ((map & 0x000c) >> 2 == IEEE80211_VHT_MCS_SUPPORT_0_7)
hw_rate =
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS7];
diff --git a/drivers/staging/rtl8192ee/base.h b/drivers/staging/rtl8192ee/base.h
index c7929a7b02fd..1d6e5a76ce3e 100644
--- a/drivers/staging/rtl8192ee/base.h
+++ b/drivers/staging/rtl8192ee/base.h
@@ -132,13 +132,13 @@ u8 rtl92e_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb,
void rtl92e_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
void rtl92e_watch_dog_timer_callback(unsigned long data);
int rtl92e_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int rtl92e_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
int rtl92e_tx_agg_oper(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid);
int rtl92e_rx_agg_start(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta, u16 tid);
+ struct ieee80211_sta *sta, u16 tid);
int rtl92e_rx_agg_stop(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid);
void rtl92e_watchdog_wq_callback(void *data);
diff --git a/drivers/staging/rtl8192ee/btcoexist/halbtc8821a2ant.c b/drivers/staging/rtl8192ee/btcoexist/halbtc8821a2ant.c
index 7fb590739014..244d5599e0dc 100644
--- a/drivers/staging/rtl8192ee/btcoexist/halbtc8821a2ant.c
+++ b/drivers/staging/rtl8192ee/btcoexist/halbtc8821a2ant.c
@@ -2488,7 +2488,7 @@ static void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
} else {
sw_mechanism1(btcoexist, true, false, false, false);
sw_mechanism2(btcoexist, false, false, false, 0x18);
- };
+ }
} else {
/* fw mechanism */
if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
diff --git a/drivers/staging/rtl8192ee/btcoexist/halbtcoutsrc.h b/drivers/staging/rtl8192ee/btcoexist/halbtcoutsrc.h
index c0a4286430a5..1231b16205f2 100644
--- a/drivers/staging/rtl8192ee/btcoexist/halbtcoutsrc.h
+++ b/drivers/staging/rtl8192ee/btcoexist/halbtcoutsrc.h
@@ -94,7 +94,7 @@ extern u32 btc_92edbg_type[];
#define CL_SPRINTF snprintf
-#define CL_PRINTF printk
+#define CL_PRINTF(buf) printk("%s", buf)
#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
do { \
diff --git a/drivers/staging/rtl8192ee/pci.c b/drivers/staging/rtl8192ee/pci.c
index 3fe9b7ba01d6..f3abbcc9f3ba 100644
--- a/drivers/staging/rtl8192ee/pci.c
+++ b/drivers/staging/rtl8192ee/pci.c
@@ -892,7 +892,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
}
/* handle command packet here */
- if (rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {
+ if (rtlpriv->cfg->ops->rx_command_packet(hw, &stats, skb)) {
dev_kfree_skb_any(skb);
goto end;
}
diff --git a/drivers/staging/rtl8192ee/rtl8192ee/trx.c b/drivers/staging/rtl8192ee/rtl8192ee/trx.c
index c930f52ec8c8..1190c8bdb0d3 100644
--- a/drivers/staging/rtl8192ee/rtl8192ee/trx.c
+++ b/drivers/staging/rtl8192ee/rtl8192ee/trx.c
@@ -1263,13 +1263,13 @@ bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index)
}
u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw,
- struct rtl_stats status,
+ const struct rtl_stats *status,
struct sk_buff *skb)
{
u32 result = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
- switch (status.packet_report_type) {
+ switch (status->packet_report_type) {
case NORMAL_RX:
result = 0;
break;
diff --git a/drivers/staging/rtl8192ee/rtl8192ee/trx.h b/drivers/staging/rtl8192ee/rtl8192ee/trx.h
index c2cd5813a2b9..e04ee7e6d9b2 100644
--- a/drivers/staging/rtl8192ee/rtl8192ee/trx.h
+++ b/drivers/staging/rtl8192ee/rtl8192ee/trx.h
@@ -872,6 +872,6 @@ void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool b_firstseg, bool b_lastseg,
struct sk_buff *skb);
u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw,
- struct rtl_stats status,
+ const struct rtl_stats *status,
struct sk_buff *skb);
#endif
diff --git a/drivers/staging/rtl8192ee/wifi.h b/drivers/staging/rtl8192ee/wifi.h
index 96fa261a70a5..a37176af845e 100644
--- a/drivers/staging/rtl8192ee/wifi.h
+++ b/drivers/staging/rtl8192ee/wifi.h
@@ -1946,7 +1946,7 @@ struct rtl_hal_ops {
u32 cmd_len, u8 *p_cmdbuffer);
bool (*get_btc_status)(void);
u32 (*rx_command_packet)(struct ieee80211_hw *hw,
- struct rtl_stats status, struct sk_buff *skb);
+ 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);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
index e0aa069fe9b1..1040bab9702a 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -2238,7 +2238,7 @@ static inline void *ieee80211_priv(struct net_device *dev)
return ((struct ieee80211_device *)netdev_priv(dev))->priv;
}
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -2254,7 +2254,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
{
/*
* It is possible for both access points and our device to support
@@ -2280,7 +2280,7 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
return 0;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = IEEE80211_3ADDR_LEN;
@@ -2564,12 +2564,12 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
extern const long ieee80211_wlan_frequencies[];
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
{
ieee->scans++;
}
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
{
return ieee->scans;
}
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index d9a8299c48eb..73410ccfb1ec 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -352,7 +352,6 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
hdr = (struct ieee80211_hdr_4addr *) skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
if (ieee->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
@@ -362,7 +361,6 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
}
return -1;
}
-#endif
atomic_inc(&crypt->refcnt);
res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
index 029a97651797..7f9e655f9eb8 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -191,20 +191,20 @@ int ieee80211_encrypt_fragment(
printk("=========>%s(), crypt is null\n", __func__);
return -1;
}
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct ieee80211_hdr *header;
if (ieee->tkip_countermeasures &&
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr *) frag->data;
if (net_ratelimit()) {
+ struct ieee80211_hdr_3addrqos *header;
+
+ header = (struct ieee80211_hdr_3addrqos *)frag->data;
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to %pM\n",
ieee->dev->name, header->addr1);
}
return -1;
}
-#endif
+
/* To encrypt, frame format is:
* IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c
index fb8a7a8ac64c..97d9b3f49114 100644
--- a/drivers/staging/rtl8192u/r8180_93cx6.c
+++ b/drivers/staging/rtl8192u/r8180_93cx6.c
@@ -103,7 +103,7 @@ u32 eprom_read(struct net_device *dev, u32 addr)
u32 ret;
ret = 0;
- //enable EPROM programming
+ /* enable EPROM programming */
write_nic_byte_E(dev, EPROM_CMD,
(EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
force_pci_posting(dev);
@@ -133,13 +133,16 @@ u32 eprom_read(struct net_device *dev, u32 addr)
eprom_send_bits_string(dev, read_cmd, 3);
eprom_send_bits_string(dev, addr_str, addr_len);
- //keep chip pin D to low state while reading.
- //I'm unsure if it is necessary, but anyway shouldn't hurt
+ /*
+ * keep chip pin D to low state while reading.
+ * I'm unsure if it is necessary, but anyway shouldn't hurt
+ */
eprom_w(dev, 0);
for (i = 0; i < 16; i++) {
- //eeprom needs a clk cycle between writing opcode&adr
- //and reading data. (eeprom outs a dummy 0)
+ /* eeprom needs a clk cycle between writing opcode&adr
+ * and reading data. (eeprom outs a dummy 0)
+ */
eprom_ck_cycle(dev);
ret |= (eprom_r(dev)<<(15-i));
}
@@ -147,7 +150,7 @@ u32 eprom_read(struct net_device *dev, u32 addr)
eprom_cs(dev, 0);
eprom_ck_cycle(dev);
- //disable EPROM programming
+ /* disable EPROM programming */
write_nic_byte_E(dev, EPROM_CMD,
(EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
return ret;
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h
index ee55dbffe32c..b840348eb5e3 100644
--- a/drivers/staging/rtl8192u/r8180_93cx6.h
+++ b/drivers/staging/rtl8192u/r8180_93cx6.h
@@ -3,11 +3,14 @@
Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
Released under the terms of GPL (General Public Licence)
- Parts of this driver are based on the GPL part of the official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
+ Parts of this driver are based on the GPL part of the
+ official realtek driver
+ Parts of this driver are based on the rtl8180 driver skeleton
+ from Patric Schenke & Andres Salomon
Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
- We want to thank the Authors of such projects and the Ndiswrapper project Authors.
+ We want to thank the Authors of such projects and the Ndiswrapper
+ project Authors.
*/
/*This files contains card eeprom (93c46 or 93c56) programming routines*/
@@ -37,4 +40,4 @@
#define EPROM_TXPW1 0x3d
-u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
+u32 eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c
index 08e1bc90555a..43ed76806c61 100644
--- a/drivers/staging/rtl8192u/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.c
@@ -23,62 +23,64 @@
* Return: NONE
* Note: 8226 support both 20M and 40 MHz
*---------------------------------------------------------------------------*/
-void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M
+void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth)
{
u8 eRFPath;
struct r8192_priv *priv = ieee80211_priv(dev);
- //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
- for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
- {
+ /* for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath;
+ * eRFPath++)
+ */
+ for (eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++) {
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
continue;
- switch (Bandwidth)
- {
- case HT_CHANNEL_WIDTH_20:
- if(priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
- {
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
-
- //cosa add for sd3's request 01/23/2008
- rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
- }
- else
- {
+ switch (Bandwidth) {
+ case HT_CHANNEL_WIDTH_20:
+ if (priv->card_8192_version == VERSION_819xU_A
+ || priv->card_8192_version
+ == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
+ rtl8192_phy_SetRFReg(dev,
+ (RF90_RADIO_PATH_E)eRFPath,
+ 0x0b, bMask12Bits, 0x100); /* phy para:1ba */
+ rtl8192_phy_SetRFReg(dev,
+ (RF90_RADIO_PATH_E)eRFPath,
+ 0x2c, bMask12Bits, 0x3d7);
+ rtl8192_phy_SetRFReg(dev,
+ (RF90_RADIO_PATH_E)eRFPath,
+ 0x0e, bMask12Bits, 0x021);
+
+ /* cosa add for sd3's request 01/23/2008
+ */
+ rtl8192_phy_SetRFReg(dev,
+ (RF90_RADIO_PATH_E)eRFPath,
+ 0x14, bMask12Bits, 0x5ab);
+ } else {
RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
- }
-
+ }
break;
- case HT_CHANNEL_WIDTH_20_40:
- if(priv->card_8192_version == VERSION_819xU_A ||priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
- {
+ case HT_CHANNEL_WIDTH_20_40:
+ if (priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B) { /* 8256 D-cut, E-cut, xiong: consider it later! */
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3df);
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0a1);
//cosa add for sd3's request 01/23/2008
- if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
+ if (priv->chan == 3 || priv->chan == 9)
+ //I need to set priv->chan whenever current channel changes
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b);
else
rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
- }
- else
- {
+ } else {
RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
- }
-
-
+ }
break;
- default:
- RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth);
+ default:
+ RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n", Bandwidth);
break;
}
}
- return;
}
/*--------------------------------------------------------------------------
* Overview: Interface to config 8256
@@ -95,8 +97,6 @@ void PHY_RF8256_Config(struct net_device *dev)
priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
// Config BB and RF
phy_RF8256_Config_ParaFile(dev);
-
- return;
}
/*--------------------------------------------------------------------------
* Overview: Interface to config 8256
@@ -122,8 +122,7 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
//3//-----------------------------------------------------------------
//3// <2> Initialize RF
//3//-----------------------------------------------------------------
- for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
- {
+ for (eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath < priv->NumTotalRFPath; eRFPath++) {
if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
continue;
@@ -133,13 +132,12 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
// pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
/*----Store original RFENV control type----*/
- switch (eRFPath)
- {
+ switch (eRFPath) {
case RF90_PATH_A:
case RF90_PATH_C:
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
break;
- case RF90_PATH_B :
+ case RF90_PATH_B:
case RF90_PATH_D:
u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
break;
@@ -159,8 +157,7 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
/*----Check RF block (for FPGA platform only)----*/
// TODO: this function should be removed on ASIC , Emily 2007.2.2
- if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath))
- {
+ if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath)) {
RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
goto phy_RF8256_Config_ParaFile_Fail;
}
@@ -168,39 +165,34 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
RetryTimes = ConstRetryTimes;
RF3_Final_Value = 0;
/*----Initialize RF fom connfiguration file----*/
- switch (eRFPath)
- {
+ switch (eRFPath) {
case RF90_PATH_A:
- while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
- {
- ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+ while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
+ ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_B:
- while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
- {
- ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+ while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
+ ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_C:
- while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
- {
- ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+ while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
+ ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
}
break;
case RF90_PATH_D:
- while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
- {
- ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+ while (RF3_Final_Value != RegValueToBeCheck && RetryTimes != 0) {
+ ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, (RF90_RADIO_PATH_E)eRFPath);
RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
RetryTimes--;
@@ -209,50 +201,48 @@ void phy_RF8256_Config_ParaFile(struct net_device *dev)
}
/*----Restore RFENV control type----*/;
- switch (eRFPath)
- {
+ switch (eRFPath) {
case RF90_PATH_A:
case RF90_PATH_C:
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
break;
- case RF90_PATH_B :
+ case RF90_PATH_B:
case RF90_PATH_D:
rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
break;
}
- if(ret){
+ if (ret) {
RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
goto phy_RF8256_Config_ParaFile_Fail;
}
}
- RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
- return ;
+ RT_TRACE(COMP_PHY, "PHY Initialization Success\n");
+ return;
phy_RF8256_Config_ParaFile_Fail:
- RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
- return ;
+ RT_TRACE(COMP_ERR, "PHY Initialization failed\n");
}
void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel)
{
- u32 TxAGC=0;
+ u32 TxAGC = 0;
struct r8192_priv *priv = ieee80211_priv(dev);
//modified by vivi, 20080109
TxAGC = powerlevel;
- if(priv->bDynamicTxLowPower == TRUE) //cosa 05/22/2008 for scan
- {
- if(priv->CustomerID == RT_CID_819x_Netcore)
+ if (priv->bDynamicTxLowPower == TRUE) {
+ //cosa 05/22/2008 for scan
+ if (priv->CustomerID == RT_CID_819x_Netcore)
TxAGC = 0x22;
else
TxAGC += priv->CckPwEnl;
}
- if(TxAGC > 0x24)
+ if (TxAGC > 0x24)
TxAGC = 0x24;
rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
}
@@ -268,43 +258,42 @@ void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel)
u8 byte0, byte1, byte2, byte3;
powerBase0 = powerlevel + priv->TxPowerDiff; //OFDM rates
- powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
+ powerBase0 = (powerBase0<<24) | (powerBase0<<16) | (powerBase0<<8) | powerBase0;
powerBase1 = powerlevel; //MCS rates
- powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
+ powerBase1 = (powerBase1<<24) | (powerBase1<<16) | (powerBase1<<8) | powerBase1;
- for(index=0; index<6; index++)
- {
- writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
+ for (index = 0; index < 6; index++) {
+ writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index < 2)?powerBase0:powerBase1);
byte0 = (u8)(writeVal & 0x7f);
byte1 = (u8)((writeVal & 0x7f00)>>8);
byte2 = (u8)((writeVal & 0x7f0000)>>16);
byte3 = (u8)((writeVal & 0x7f000000)>>24);
- if(byte0 > 0x24) // Max power index = 0x24
+
+ if (byte0 > 0x24)
+ /* Max power index = 0x24 */
byte0 = 0x24;
- if(byte1 > 0x24)
+ if (byte1 > 0x24)
byte1 = 0x24;
- if(byte2 > 0x24)
+ if (byte2 > 0x24)
byte2 = 0x24;
- if(byte3 > 0x24)
+ if (byte3 > 0x24)
byte3 = 0x24;
//for tx power track
- if(index == 3)
- {
- writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+ if (index == 3) {
+ writeVal_tmp = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0;
priv->Pwr_Track = writeVal_tmp;
}
- if(priv->bDynamicTxHighPower == TRUE) //Add by Jacken 2008/03/06
- {
- // Emily, 20080613. Set low tx power for both MCS and legacy OFDM
+ if (priv->bDynamicTxHighPower == TRUE) {
+ /*Add by Jacken 2008/03/06
+ *Emily, 20080613. Set low tx power for both MCS and legacy OFDM
+ */
writeVal = 0x03030303;
- }
- else
- {
- writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
- }
- rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
+ } else {
+ writeVal = (byte3<<24) | (byte2<<16) | (byte1<<8) | byte0;
+ }
+ rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
}
return;
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index 24272c51bc9d..76403864644c 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -166,17 +166,17 @@ typedef struct _CHANNEL_LIST {
} CHANNEL_LIST, *PCHANNEL_LIST;
static CHANNEL_LIST ChannelPlan[] = {
- {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC
- {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
- {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel.
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC
- {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 24}, //FCC
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, //IC
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, //ETSI
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //Spain. Change to ETSI.
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //France. Change to ETSI.
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, //MKK //MKK
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},//MKK1
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, //Israel.
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, // For 11a , TELEC
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, //MIC
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
};
static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv *priv)
@@ -905,7 +905,8 @@ inline u16 ieeerate2rtlrate(int rate)
static u16 rtl_rate[] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
inline u16 rtl8192_rate2rate(short rate)
{
- if (rate > 11) return 0;
+ if (rate > 11)
+ return 0;
return rtl_rate[rate];
}
@@ -1114,7 +1115,7 @@ struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv
tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
- if (tcb_desc->bAMPDUEnable) {//AMPDU enabled
+ if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */
tx_fwinfo->AllowAggregation = 1;
/* DWORD 1 */
tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
@@ -1236,12 +1237,11 @@ u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
static void rtl8192_tx_isr(struct urb *tx_urb)
{
struct sk_buff *skb = (struct sk_buff *)tx_urb->context;
- struct net_device *dev = NULL;
+ struct net_device *dev = (struct net_device *)(skb->cb);
struct r8192_priv *priv = NULL;
cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
u8 queue_index = tcb_desc->queue_index;
- memcpy(&dev, (struct net_device *)(skb->cb), sizeof(struct net_device *));
priv = ieee80211_priv(dev);
if (tcb_desc->queue_index != TXCMD_QUEUE) {
@@ -1330,35 +1330,83 @@ static void rtl8192_config_rate(struct net_device *dev, u16 *rate_config)
for (i = 0; i < net->rates_len; i++) {
basic_rate = net->rates[i]&0x7f;
switch (basic_rate) {
- case MGN_1M: *rate_config |= RRSR_1M; break;
- case MGN_2M: *rate_config |= RRSR_2M; break;
- case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
- case MGN_11M: *rate_config |= RRSR_11M; break;
- case MGN_6M: *rate_config |= RRSR_6M; break;
- case MGN_9M: *rate_config |= RRSR_9M; break;
- case MGN_12M: *rate_config |= RRSR_12M; break;
- case MGN_18M: *rate_config |= RRSR_18M; break;
- case MGN_24M: *rate_config |= RRSR_24M; break;
- case MGN_36M: *rate_config |= RRSR_36M; break;
- case MGN_48M: *rate_config |= RRSR_48M; break;
- case MGN_54M: *rate_config |= RRSR_54M; break;
+ case MGN_1M:
+ *rate_config |= RRSR_1M;
+ break;
+ case MGN_2M:
+ *rate_config |= RRSR_2M;
+ break;
+ case MGN_5_5M:
+ *rate_config |= RRSR_5_5M;
+ break;
+ case MGN_11M:
+ *rate_config |= RRSR_11M;
+ break;
+ case MGN_6M:
+ *rate_config |= RRSR_6M;
+ break;
+ case MGN_9M:
+ *rate_config |= RRSR_9M;
+ break;
+ case MGN_12M:
+ *rate_config |= RRSR_12M;
+ break;
+ case MGN_18M:
+ *rate_config |= RRSR_18M;
+ break;
+ case MGN_24M:
+ *rate_config |= RRSR_24M;
+ break;
+ case MGN_36M:
+ *rate_config |= RRSR_36M;
+ break;
+ case MGN_48M:
+ *rate_config |= RRSR_48M;
+ break;
+ case MGN_54M:
+ *rate_config |= RRSR_54M;
+ break;
}
}
for (i = 0; i < net->rates_ex_len; i++) {
basic_rate = net->rates_ex[i]&0x7f;
switch (basic_rate) {
- case MGN_1M: *rate_config |= RRSR_1M; break;
- case MGN_2M: *rate_config |= RRSR_2M; break;
- case MGN_5_5M: *rate_config |= RRSR_5_5M; break;
- case MGN_11M: *rate_config |= RRSR_11M; break;
- case MGN_6M: *rate_config |= RRSR_6M; break;
- case MGN_9M: *rate_config |= RRSR_9M; break;
- case MGN_12M: *rate_config |= RRSR_12M; break;
- case MGN_18M: *rate_config |= RRSR_18M; break;
- case MGN_24M: *rate_config |= RRSR_24M; break;
- case MGN_36M: *rate_config |= RRSR_36M; break;
- case MGN_48M: *rate_config |= RRSR_48M; break;
- case MGN_54M: *rate_config |= RRSR_54M; break;
+ case MGN_1M:
+ *rate_config |= RRSR_1M;
+ break;
+ case MGN_2M:
+ *rate_config |= RRSR_2M;
+ break;
+ case MGN_5_5M:
+ *rate_config |= RRSR_5_5M;
+ break;
+ case MGN_11M:
+ *rate_config |= RRSR_11M;
+ break;
+ case MGN_6M:
+ *rate_config |= RRSR_6M;
+ break;
+ case MGN_9M:
+ *rate_config |= RRSR_9M;
+ break;
+ case MGN_12M:
+ *rate_config |= RRSR_12M;
+ break;
+ case MGN_18M:
+ *rate_config |= RRSR_18M;
+ break;
+ case MGN_24M:
+ *rate_config |= RRSR_24M;
+ break;
+ case MGN_36M:
+ *rate_config |= RRSR_36M;
+ break;
+ case MGN_48M:
+ *rate_config |= RRSR_48M;
+ break;
+ case MGN_54M:
+ *rate_config |= RRSR_54M;
+ break;
}
}
}
@@ -1380,7 +1428,7 @@ static void rtl8192_update_cap(struct net_device *dev, u16 cap)
if (net->mode & (IEEE_G|IEEE_N_24G)) {
u8 slot_time = 0;
- if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) //short slot time
+ if ((cap & WLAN_CAPABILITY_SHORT_SLOT) && (!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) /* short slot time */
slot_time = SHORT_SLOT_TIME;
else //long slot time
slot_time = NON_SHORT_SLOT_TIME;
@@ -1399,7 +1447,7 @@ static void rtl8192_net_update(struct net_device *dev)
net = &priv->ieee80211->current_network;
rtl8192_config_rate(dev, &rate_config);
- priv->basic_rate = rate_config &= 0x15f;
+ priv->basic_rate = rate_config & 0x15f;
write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]);
write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
@@ -1432,7 +1480,8 @@ inline u8 rtl8192_IsWirelessBMode(u16 rate)
{
if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
return 1;
- else return 0;
+ else
+ return 0;
}
u16 N_DBPSOfRate(u16 DataRate);
@@ -1445,11 +1494,11 @@ u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
u16 Ceiling;
if (rtl8192_IsWirelessBMode(DataRate)) {
- if (bManagementFrame || !bShortPreamble || DataRate == 10) // long preamble
+ if (bManagementFrame || !bShortPreamble || DataRate == 10) /* long preamble */
FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
else // Short preamble
FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
- if ((FrameLength*8 % (DataRate/10)) != 0) //Get the Ceilling
+ if ((FrameLength*8 % (DataRate/10)) != 0) /* Get the Ceilling */
FrameTime++;
} else { //802.11g DSSS-OFDM PLCP length field calculation.
N_DBPS = N_DBPSOfRate(DataRate);
@@ -1617,39 +1666,98 @@ static u8 MRateToHwRate8190Pci(u8 rate)
u8 ret = DESC90_RATE1M;
switch (rate) {
- case MGN_1M: ret = DESC90_RATE1M; break;
- case MGN_2M: ret = DESC90_RATE2M; break;
- case MGN_5_5M: ret = DESC90_RATE5_5M; break;
- case MGN_11M: ret = DESC90_RATE11M; break;
- case MGN_6M: ret = DESC90_RATE6M; break;
- case MGN_9M: ret = DESC90_RATE9M; break;
- case MGN_12M: ret = DESC90_RATE12M; break;
- case MGN_18M: ret = DESC90_RATE18M; break;
- case MGN_24M: ret = DESC90_RATE24M; break;
- case MGN_36M: ret = DESC90_RATE36M; break;
- case MGN_48M: ret = DESC90_RATE48M; break;
- case MGN_54M: ret = DESC90_RATE54M; break;
-
- // HT rate since here
- case MGN_MCS0: ret = DESC90_RATEMCS0; break;
- case MGN_MCS1: ret = DESC90_RATEMCS1; break;
- case MGN_MCS2: ret = DESC90_RATEMCS2; break;
- case MGN_MCS3: ret = DESC90_RATEMCS3; break;
- case MGN_MCS4: ret = DESC90_RATEMCS4; break;
- case MGN_MCS5: ret = DESC90_RATEMCS5; break;
- case MGN_MCS6: ret = DESC90_RATEMCS6; break;
- case MGN_MCS7: ret = DESC90_RATEMCS7; break;
- case MGN_MCS8: ret = DESC90_RATEMCS8; break;
- case MGN_MCS9: ret = DESC90_RATEMCS9; break;
- case MGN_MCS10: ret = DESC90_RATEMCS10; break;
- case MGN_MCS11: ret = DESC90_RATEMCS11; break;
- case MGN_MCS12: ret = DESC90_RATEMCS12; break;
- case MGN_MCS13: ret = DESC90_RATEMCS13; break;
- case MGN_MCS14: ret = DESC90_RATEMCS14; break;
- case MGN_MCS15: ret = DESC90_RATEMCS15; break;
- case (0x80|0x20): ret = DESC90_RATEMCS32; break;
-
- default: break;
+ case MGN_1M:
+ ret = DESC90_RATE1M;
+ break;
+ case MGN_2M:
+ ret = DESC90_RATE2M;
+ break;
+ case MGN_5_5M:
+ ret = DESC90_RATE5_5M;
+ break;
+ case MGN_11M:
+ ret = DESC90_RATE11M;
+ break;
+ case MGN_6M:
+ ret = DESC90_RATE6M;
+ break;
+ case MGN_9M:
+ ret = DESC90_RATE9M;
+ break;
+ case MGN_12M:
+ ret = DESC90_RATE12M;
+ break;
+ case MGN_18M:
+ ret = DESC90_RATE18M;
+ break;
+ case MGN_24M:
+ ret = DESC90_RATE24M;
+ break;
+ case MGN_36M:
+ ret = DESC90_RATE36M;
+ break;
+ case MGN_48M:
+ ret = DESC90_RATE48M;
+ break;
+ case MGN_54M:
+ ret = DESC90_RATE54M;
+ break;
+
+ // HT rate since here
+ case MGN_MCS0:
+ ret = DESC90_RATEMCS0;
+ break;
+ case MGN_MCS1:
+ ret = DESC90_RATEMCS1;
+ break;
+ case MGN_MCS2:
+ ret = DESC90_RATEMCS2;
+ break;
+ case MGN_MCS3:
+ ret = DESC90_RATEMCS3;
+ break;
+ case MGN_MCS4:
+ ret = DESC90_RATEMCS4;
+ break;
+ case MGN_MCS5:
+ ret = DESC90_RATEMCS5;
+ break;
+ case MGN_MCS6:
+ ret = DESC90_RATEMCS6;
+ break;
+ case MGN_MCS7:
+ ret = DESC90_RATEMCS7;
+ break;
+ case MGN_MCS8:
+ ret = DESC90_RATEMCS8;
+ break;
+ case MGN_MCS9:
+ ret = DESC90_RATEMCS9;
+ break;
+ case MGN_MCS10:
+ ret = DESC90_RATEMCS10;
+ break;
+ case MGN_MCS11:
+ ret = DESC90_RATEMCS11;
+ break;
+ case MGN_MCS12:
+ ret = DESC90_RATEMCS12;
+ break;
+ case MGN_MCS13:
+ ret = DESC90_RATEMCS13;
+ break;
+ case MGN_MCS14:
+ ret = DESC90_RATEMCS14;
+ break;
+ case MGN_MCS15:
+ ret = DESC90_RATEMCS15;
+ break;
+ case (0x80|0x20):
+ ret = DESC90_RATEMCS32;
+ break;
+
+ default:
+ break;
}
return ret;
}
@@ -1712,7 +1820,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
- if (tcb_desc->bAMPDUEnable) {//AMPDU enabled
+ if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */
tx_fwinfo->AllowAggregation = 1;
/* DWORD 1 */
tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
@@ -2198,7 +2306,7 @@ void rtl8192_update_ratr_table(struct net_device *dev)
break;
case IEEE_N_24G:
case IEEE_N_5G:
- if (ieee->pHTInfo->PeerMimoPs == 0) {//MIMO_PS_STATIC
+ if (ieee->pHTInfo->PeerMimoPs == 0) { /* MIMO_PS_STATIC */
ratr_value &= 0x0007F007;
} else {
if (priv->rf_type == RF_1T2R)
@@ -2355,7 +2463,6 @@ static void rtl8192_init_priv_variable(struct net_device *dev)
priv->ieee80211->FwRWRF = 0; //we don't use FW read/write RF until stable firmware is available.
priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
- priv->ieee80211->iw_mode = IW_MODE_INFRA;
priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
@@ -2582,7 +2689,7 @@ static void rtl8192_read_eeprom_info(struct net_device *dev)
else
priv->EEPROM_Def_Ver = 1;
RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
- if (priv->EEPROM_Def_Ver == 0) { //old eeprom definition
+ if (priv->EEPROM_Def_Ver == 0) { /* old eeprom definition */
int i;
if (bLoad_From_EEPOM)
priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
@@ -2993,13 +3100,13 @@ static bool rtl8192_adapter_start(struct net_device *dev)
//
#ifdef TO_DO_LIST
if (Adapter->ResetProgress == RESET_TYPE_NORESET) {
- if (pMgntInfo->RegRfOff == TRUE) { // User disable RF via registry.
+ if (pMgntInfo->RegRfOff == TRUE) { /* User disable RF via registry. */
RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
// Those actions will be discard in MgntActSet_RF_State because of the same state
for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++)
PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
- } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep.
+ } else if (pMgntInfo->RfOffReason > RF_CHANGE_BY_PS) { /* H/W or S/W RF OFF before sleep. */
RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
} else {
@@ -3525,7 +3632,7 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
}
if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET &&
(priv->bForcedSilentReset ||
- (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { // This is control by OID set in Pomelo
+ (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_SILENT)))) { /* This is control by OID set in Pomelo */
RT_TRACE(COMP_RESET, "%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n", __func__, priv->force_reset, priv->ResetProgress, priv->bForcedSilentReset, priv->bDisableNormalResetCheck, ResetType);
rtl819x_ifsilentreset(dev);
}
@@ -3586,7 +3693,8 @@ int rtl8192_up(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
- if (priv->up == 1) return -1;
+ if (priv->up == 1)
+ return -1;
return _rtl8192_up(dev);
}
@@ -3612,7 +3720,8 @@ int rtl8192_down(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
int i;
- if (priv->up == 0) return -1;
+ if (priv->up == 0)
+ return -1;
priv->up = 0;
priv->ieee80211->ieee_up = 0;
@@ -3650,7 +3759,8 @@ void rtl8192_commit(struct net_device *dev)
{
struct r8192_priv *priv = ieee80211_priv(dev);
int reset_status = 0;
- if (priv->up == 0) return;
+ if (priv->up == 0)
+ return;
priv->up = 0;
rtl8192_cancel_deferred_work(priv);
@@ -3803,49 +3913,107 @@ static u8 HwRateToMRate90(bool bIsHT, u8 rate)
if (!bIsHT) {
switch (rate) {
- case DESC90_RATE1M: ret_rate = MGN_1M; break;
- case DESC90_RATE2M: ret_rate = MGN_2M; break;
- case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break;
- case DESC90_RATE11M: ret_rate = MGN_11M; break;
- case DESC90_RATE6M: ret_rate = MGN_6M; break;
- case DESC90_RATE9M: ret_rate = MGN_9M; break;
- case DESC90_RATE12M: ret_rate = MGN_12M; break;
- case DESC90_RATE18M: ret_rate = MGN_18M; break;
- case DESC90_RATE24M: ret_rate = MGN_24M; break;
- case DESC90_RATE36M: ret_rate = MGN_36M; break;
- case DESC90_RATE48M: ret_rate = MGN_48M; break;
- case DESC90_RATE54M: ret_rate = MGN_54M; break;
+ case DESC90_RATE1M:
+ ret_rate = MGN_1M;
+ break;
+ case DESC90_RATE2M:
+ ret_rate = MGN_2M;
+ break;
+ case DESC90_RATE5_5M:
+ ret_rate = MGN_5_5M;
+ break;
+ case DESC90_RATE11M:
+ ret_rate = MGN_11M;
+ break;
+ case DESC90_RATE6M:
+ ret_rate = MGN_6M;
+ break;
+ case DESC90_RATE9M:
+ ret_rate = MGN_9M;
+ break;
+ case DESC90_RATE12M:
+ ret_rate = MGN_12M;
+ break;
+ case DESC90_RATE18M:
+ ret_rate = MGN_18M;
+ break;
+ case DESC90_RATE24M:
+ ret_rate = MGN_24M;
+ break;
+ case DESC90_RATE36M:
+ ret_rate = MGN_36M;
+ break;
+ case DESC90_RATE48M:
+ ret_rate = MGN_48M;
+ break;
+ case DESC90_RATE54M:
+ ret_rate = MGN_54M;
+ break;
- default:
- ret_rate = 0xff;
- RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
- break;
+ default:
+ ret_rate = 0xff;
+ RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+ break;
}
} else {
switch (rate) {
- case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break;
- case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break;
- case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break;
- case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break;
- case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break;
- case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break;
- case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break;
- case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break;
- case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break;
- case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break;
- case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break;
- case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break;
- case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break;
- case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break;
- case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break;
- case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break;
- case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break;
+ case DESC90_RATEMCS0:
+ ret_rate = MGN_MCS0;
+ break;
+ case DESC90_RATEMCS1:
+ ret_rate = MGN_MCS1;
+ break;
+ case DESC90_RATEMCS2:
+ ret_rate = MGN_MCS2;
+ break;
+ case DESC90_RATEMCS3:
+ ret_rate = MGN_MCS3;
+ break;
+ case DESC90_RATEMCS4:
+ ret_rate = MGN_MCS4;
+ break;
+ case DESC90_RATEMCS5:
+ ret_rate = MGN_MCS5;
+ break;
+ case DESC90_RATEMCS6:
+ ret_rate = MGN_MCS6;
+ break;
+ case DESC90_RATEMCS7:
+ ret_rate = MGN_MCS7;
+ break;
+ case DESC90_RATEMCS8:
+ ret_rate = MGN_MCS8;
+ break;
+ case DESC90_RATEMCS9:
+ ret_rate = MGN_MCS9;
+ break;
+ case DESC90_RATEMCS10:
+ ret_rate = MGN_MCS10;
+ break;
+ case DESC90_RATEMCS11:
+ ret_rate = MGN_MCS11;
+ break;
+ case DESC90_RATEMCS12:
+ ret_rate = MGN_MCS12;
+ break;
+ case DESC90_RATEMCS13:
+ ret_rate = MGN_MCS13;
+ break;
+ case DESC90_RATEMCS14:
+ ret_rate = MGN_MCS14;
+ break;
+ case DESC90_RATEMCS15:
+ ret_rate = MGN_MCS15;
+ break;
+ case DESC90_RATEMCS32:
+ ret_rate = (0x80|0x20);
+ break;
- default:
- ret_rate = 0xff;
- RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
- break;
+ default:
+ ret_rate = 0xff;
+ RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+ break;
}
}
@@ -4022,7 +4190,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
- if (priv->undecorated_smoothed_pwdb < 0) // initialize
+ if (priv->undecorated_smoothed_pwdb < 0) /* initialize */
priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
if (pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) {
priv->undecorated_smoothed_pwdb =
@@ -4064,9 +4232,9 @@ static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer,
// <2> Showed on UI for engineering
if (pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) {
- for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { // 2 spatial stream
+ for (nspatial_stream = 0; nspatial_stream < 2; nspatial_stream++) { /* 2 spatial stream */
if (pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) {
- if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
+ if (priv->stats.rx_evm_percentage[nspatial_stream] == 0) /* initialize */
priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
priv->stats.rx_evm_percentage[nspatial_stream] =
((priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
@@ -4361,7 +4529,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
rx_evmX /= 2; //dbm
evm = rtl819x_evm_dbtopercentage(rx_evmX);
- if (i == 0) // Fill value in RFD, Get the first spatial stream only
+ if (i == 0) /* Fill value in RFD, Get the first spatial stream only */
pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
}
@@ -4370,7 +4538,7 @@ static void rtl8192_query_rxphystatus(struct r8192_priv *priv,
/* record rx statistics for debug */
rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
- if (pdrvinfo->BW) //40M channel
+ if (pdrvinfo->BW) /* 40M channel */
priv->stats.received_bwtype[1+prxsc->rxsc]++;
else //20M channel
priv->stats.received_bwtype[0]++;
@@ -4491,41 +4659,99 @@ UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
//
// CCK rate
//
- case MGN_1M: rateIndex = 0; break;
- case MGN_2M: rateIndex = 1; break;
- case MGN_5_5M: rateIndex = 2; break;
- case MGN_11M: rateIndex = 3; break;
+ case MGN_1M:
+ rateIndex = 0;
+ break;
+ case MGN_2M:
+ rateIndex = 1;
+ break;
+ case MGN_5_5M:
+ rateIndex = 2;
+ break;
+ case MGN_11M:
+ rateIndex = 3;
+ break;
//
// Legacy OFDM rate
//
- case MGN_6M: rateIndex = 4; break;
- case MGN_9M: rateIndex = 5; break;
- case MGN_12M: rateIndex = 6; break;
- case MGN_18M: rateIndex = 7; break;
- case MGN_24M: rateIndex = 8; break;
- case MGN_36M: rateIndex = 9; break;
- case MGN_48M: rateIndex = 10; break;
- case MGN_54M: rateIndex = 11; break;
+ case MGN_6M:
+ rateIndex = 4;
+ break;
+ case MGN_9M:
+ rateIndex = 5;
+ break;
+ case MGN_12M:
+ rateIndex = 6;
+ break;
+ case MGN_18M:
+ rateIndex = 7;
+ break;
+ case MGN_24M:
+ rateIndex = 8;
+ break;
+ case MGN_36M:
+ rateIndex = 9;
+ break;
+ case MGN_48M:
+ rateIndex = 10;
+ break;
+ case MGN_54M:
+ rateIndex = 11;
+ break;
//
// 11n High throughput rate
//
- case MGN_MCS0: rateIndex = 12; break;
- case MGN_MCS1: rateIndex = 13; break;
- case MGN_MCS2: rateIndex = 14; break;
- case MGN_MCS3: rateIndex = 15; break;
- case MGN_MCS4: rateIndex = 16; break;
- case MGN_MCS5: rateIndex = 17; break;
- case MGN_MCS6: rateIndex = 18; break;
- case MGN_MCS7: rateIndex = 19; break;
- case MGN_MCS8: rateIndex = 20; break;
- case MGN_MCS9: rateIndex = 21; break;
- case MGN_MCS10: rateIndex = 22; break;
- case MGN_MCS11: rateIndex = 23; break;
- case MGN_MCS12: rateIndex = 24; break;
- case MGN_MCS13: rateIndex = 25; break;
- case MGN_MCS14: rateIndex = 26; break;
- case MGN_MCS15: rateIndex = 27; break;
- default: rateIndex = 28; break;
+ case MGN_MCS0:
+ rateIndex = 12;
+ break;
+ case MGN_MCS1:
+ rateIndex = 13;
+ break;
+ case MGN_MCS2:
+ rateIndex = 14;
+ break;
+ case MGN_MCS3:
+ rateIndex = 15;
+ break;
+ case MGN_MCS4:
+ rateIndex = 16;
+ break;
+ case MGN_MCS5:
+ rateIndex = 17;
+ break;
+ case MGN_MCS6:
+ rateIndex = 18;
+ break;
+ case MGN_MCS7:
+ rateIndex = 19;
+ break;
+ case MGN_MCS8:
+ rateIndex = 20;
+ break;
+ case MGN_MCS9:
+ rateIndex = 21;
+ break;
+ case MGN_MCS10:
+ rateIndex = 22;
+ break;
+ case MGN_MCS11:
+ rateIndex = 23;
+ break;
+ case MGN_MCS12:
+ rateIndex = 24;
+ break;
+ case MGN_MCS13:
+ rateIndex = 25;
+ break;
+ case MGN_MCS14:
+ rateIndex = 26;
+ break;
+ case MGN_MCS15:
+ rateIndex = 27;
+ break;
+ default:
+ rateIndex = 28;
+ break;
}
priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
priv->stats.received_rate_histogram[0][rateIndex]++; //total
@@ -5146,7 +5372,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev)
ieee->hwsec_active = 1;
- if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { //add hwsec_support flag to totol control hw_sec on/off
+ if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { /* add hwsec_support flag to totol control hw_sec on/off */
ieee->hwsec_active = 0;
SECR_value &= ~SCR_RxDecEnable;
}
@@ -5178,14 +5404,14 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
TargetCommand = i+CAM_CONTENT_COUNT*EntryNo;
TargetCommand |= BIT31|BIT16;
- if (i == 0) { //MAC|Config
+ if (i == 0) { /* MAC|Config */
TargetContent = (u32)(*(MacAddr+0)) << 16|
(u32)(*(MacAddr+1)) << 24|
(u32)usConfig;
write_nic_dword(dev, WCAMI, TargetContent);
write_nic_dword(dev, RWCAM, TargetCommand);
- } else if (i == 1) { //MAC
+ } else if (i == 1) { /* MAC */
TargetContent = (u32)(*(MacAddr+2)) |
(u32)(*(MacAddr+3)) << 8|
(u32)(*(MacAddr+4)) << 16|
diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c
index 675a12d6aa8c..6808e872296e 100644
--- a/drivers/staging/rtl8192u/r8192U_wx.c
+++ b/drivers/staging/rtl8192u/r8192U_wx.c
@@ -57,6 +57,7 @@ static int r8192_wx_get_rate(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+
return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
}
@@ -100,6 +101,7 @@ static int r8192_wx_get_rts(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+
return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
}
@@ -124,6 +126,7 @@ static int r8192_wx_get_power(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+
return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
}
@@ -180,8 +183,8 @@ static int r8192_wx_set_crcmon(struct net_device *dev,
priv->crcmon ? "accepted" : "rejected");
if (prev != priv->crcmon && priv->up) {
- //rtl8180_down(dev);
- //rtl8180_up(dev);
+ /* rtl8180_down(dev); */
+ /* rtl8180_up(dev); */
}
up(&priv->wx_sem);
@@ -194,6 +197,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
{
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
@@ -249,15 +253,15 @@ static int rtl8180_wx_get_range(struct net_device *dev,
/* ~5 Mb/s real (802.11b) */
range->throughput = 5 * 1000 * 1000;
- // TODO: Not used in 802.11b?
-// range->min_nwid; /* Minimal NWID we are able to set */
- // TODO: Not used in 802.11b?
-// range->max_nwid; /* Maximal NWID we are able to set */
+ /* TODO: Not used in 802.11b? */
+ /* range->min_nwid; */ /* Minimal NWID we are able to set */
+ /* TODO: Not used in 802.11b? */
+ /* range->max_nwid; */ /* Maximal NWID we are able to set */
/* Old Frequency (backward compat - moved lower ) */
-// range->old_num_channels;
-// range->old_num_frequency;
-// range->old_freq[6]; /* Filler to keep "version" at the same offset */
+ /* range->old_num_channels; */
+ /* range->old_num_frequency; */
+ /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
if (priv->rf_set_sens != NULL)
range->sensitivity = priv->max_sens; /* signal level threshold range */
@@ -292,26 +296,26 @@ static int rtl8180_wx_get_range(struct net_device *dev,
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 16;
-// range->retry_capa; /* What retry options are supported */
-// range->retry_flags; /* How to decode max/min retry limit */
-// range->r_time_flags; /* How to decode max/min retry life */
-// range->min_retry; /* Minimal number of retries */
-// range->max_retry; /* Maximal number of retries */
-// range->min_r_time; /* Minimal retry lifetime */
-// range->max_r_time; /* Maximal retry lifetime */
+ /* range->retry_capa; */ /* What retry options are supported */
+ /* range->retry_flags; */ /* How to decode max/min retry limit */
+ /* range->r_time_flags; */ /* How to decode max/min retry life */
+ /* range->min_retry; */ /* Minimal number of retries */
+ /* range->max_retry; */ /* Maximal number of retries */
+ /* range->min_r_time; */ /* Minimal retry lifetime */
+ /* range->max_r_time; */ /* Maximal retry lifetime */
for (i = 0, val = 0; i < 14; i++) {
- // Include only legal frequencies for some countries
+ /* Include only legal frequencies for some countries */
if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
range->freq[val].i = i + 1;
range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
range->freq[val].e = 1;
val++;
} else {
- // FIXME: do we need to set anything for channels
- // we don't use ?
+ /* FIXME: do we need to set anything for channels */
+ /* we don't use ? */
}
if (val == IW_MAX_FREQUENCIES)
@@ -341,10 +345,8 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
struct iw_scan_req *req = (struct iw_scan_req *)b;
if (req->essid_len) {
- //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
ieee->current_network.ssid_len = req->essid_len;
memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
- //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
}
}
@@ -386,6 +388,7 @@ static int r8192_wx_set_essid(struct net_device *dev,
{
struct r8192_priv *priv = ieee80211_priv(dev);
int ret;
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
@@ -434,6 +437,7 @@ static int r8192_wx_get_name(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+
return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
}
@@ -480,7 +484,7 @@ static int r8192_wx_set_wap(struct net_device *dev,
int ret;
struct r8192_priv *priv = ieee80211_priv(dev);
-// struct sockaddr *temp = (struct sockaddr *)awrq;
+ /* struct sockaddr *temp = (struct sockaddr *)awrq; */
down(&priv->wx_sem);
ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
@@ -518,12 +522,9 @@ static int r8192_wx_set_enc(struct net_device *dev,
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee80211;
int ret;
-
- //u32 TargetContent;
u32 hwkey[4] = {0, 0, 0, 0};
u8 mask = 0xff;
u32 key_idx = 0;
- //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
@@ -542,7 +543,7 @@ static int r8192_wx_set_enc(struct net_device *dev,
- //sometimes, the length is zero while we do not type key value
+ /* sometimes, the length is zero while we do not type key value */
if (wrqu->encoding.length != 0) {
for (i = 0; i < 4; i++) {
@@ -584,12 +585,12 @@ static int r8192_wx_set_enc(struct net_device *dev,
EnableHWSecurityConfig8192(dev);
setKey(dev,
- key_idx, //EntryNo
- key_idx, //KeyIndex
- KEY_TYPE_WEP40, //KeyType
+ key_idx, /* EntryNo */
+ key_idx, /* KeyIndex */
+ KEY_TYPE_WEP40, /* KeyType */
zero_addr[key_idx],
- 0, //DefaultKey
- hwkey); //KeyContent
+ 0, /* DefaultKey */
+ hwkey); /* KeyContent */
}
@@ -598,12 +599,12 @@ static int r8192_wx_set_enc(struct net_device *dev,
EnableHWSecurityConfig8192(dev);
setKey(dev,
- key_idx, //EntryNo
- key_idx, //KeyIndex
- KEY_TYPE_WEP104, //KeyType
+ key_idx, /* EntryNo */
+ key_idx, /* KeyIndex */
+ KEY_TYPE_WEP104, /* KeyType */
zero_addr[key_idx],
- 0, //DefaultKey
- hwkey); //KeyContent
+ 0, /* DefaultKey */
+ hwkey); /* KeyContent */
} else {
printk("wrong type in WEP, not WEP40 and WEP104\n");
@@ -669,14 +670,6 @@ static int r8192_wx_set_retry(struct net_device *dev,
*/
rtl8192_commit(dev);
- /*
- if(priv->up){
- rtl8180_rtx_disable(dev);
- rtl8180_rx_enable(dev);
- rtl8180_tx_enable(dev);
-
- }
- */
exit:
up(&priv->wx_sem);
@@ -703,7 +696,6 @@ static int r8192_wx_get_retry(struct net_device *dev,
wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
wrqu->retry.value = priv->retry_data;
}
- //printk("returning %d",wrqu->retry.value);
return 0;
@@ -714,6 +706,7 @@ static int r8192_wx_get_sens(struct net_device *dev,
union iwreq_data *wrqu, char *extra)
{
struct r8192_priv *priv = ieee80211_priv(dev);
+
if (priv->rf_set_sens == NULL)
return -1; /* we have not this support for this radio */
wrqu->sens.value = priv->sens;
@@ -727,10 +720,9 @@ static int r8192_wx_set_sens(struct net_device *dev,
{
struct r8192_priv *priv = ieee80211_priv(dev);
-
short err = 0;
+
down(&priv->wx_sem);
- //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
if (priv->rf_set_sens == NULL) {
err = -1; /* we have not this support for this radio */
goto exit;
@@ -746,7 +738,7 @@ exit:
return err;
}
-//hw security need to reorganized.
+/* hw security need to reorganized. */
static int r8192_wx_set_enc_ext(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
@@ -754,7 +746,6 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
int ret = 0;
struct r8192_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee80211;
- //printk("===>%s()\n", __func__);
down(&priv->wx_sem);
@@ -768,10 +759,10 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
struct iw_point *encoding = &wrqu->encoding;
u8 idx = 0, alg = 0, group = 0;
if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
- //none is not allowed to use hwsec WB 2008.07.01
+ /* none is not allowed to use hwsec WB 2008.07.01 */
goto end_hw_sec;
- // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
+ /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx)
@@ -784,34 +775,34 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
ieee->pairwise_key_type = alg;
EnableHWSecurityConfig8192(dev);
}
- memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
+ memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
setKey(dev,
- idx,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- zero, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
+ idx, /* EntryNao */
+ idx, /* KeyIndex */
+ alg, /* KeyType */
+ zero, /* MacAddr */
+ 0, /* DefaultKey */
+ key); /* KeyContent */
} else if (group) {
ieee->group_key_type = alg;
setKey(dev,
- idx,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- broadcast_addr, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
- } else {//pairwise key
+ idx, /* EntryNo */
+ idx, /* KeyIndex */
+ alg, /* KeyType */
+ broadcast_addr, /* MacAddr */
+ 0, /* DefaultKey */
+ key); /* KeyContent */
+ } else { /* pairwise key */
setKey(dev,
- 4,//EntryNo
- idx, //KeyIndex
- alg, //KeyType
- (u8 *)ieee->ap_mac_addr, //MacAddr
- 0, //DefaultKey
- key); //KeyContent
+ 4, /* EntryNo */
+ idx, /* KeyIndex */
+ alg, /* KeyType */
+ (u8 *)ieee->ap_mac_addr,/* MacAddr */
+ 0, /* DefaultKey */
+ key); /* KeyContent */
}
@@ -828,8 +819,8 @@ static int r8192_wx_set_auth(struct net_device *dev,
union iwreq_data *data, char *extra)
{
int ret = 0;
- //printk("====>%s()\n", __func__);
struct r8192_priv *priv = ieee80211_priv(dev);
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
up(&priv->wx_sem);
@@ -840,10 +831,10 @@ static int r8192_wx_set_mlme(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
- //printk("====>%s()\n", __func__);
int ret = 0;
struct r8192_priv *priv = ieee80211_priv(dev);
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
@@ -855,13 +846,12 @@ static int r8192_wx_set_gen_ie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
- //printk("====>%s(), len:%d\n", __func__, data->length);
int ret = 0;
struct r8192_priv *priv = ieee80211_priv(dev);
+
down(&priv->wx_sem);
ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
up(&priv->wx_sem);
- //printk("<======%s(), ret:%d\n", __func__, ret);
return ret;
@@ -923,13 +913,13 @@ static iw_handler r8192_wx_handlers[] = {
r8192_wx_get_power, /* SIOCGIWPOWER */
NULL, /*---hole---*/
NULL, /*---hole---*/
- r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
+ r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
NULL, /* SIOCSIWGENIE */
- r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
- NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
+ r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
+ NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
- NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
+ NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
NULL, /* SIOCSIWPMKSA */
NULL, /*---hole---*/
@@ -962,14 +952,9 @@ static const struct iw_priv_args r8192_private_args[] = {
static iw_handler r8192_private_handler[] = {
-// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
- r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
-// r8192_wx_set_forceassociate,
-// r8192_wx_set_beaconinterval,
-// r8192_wx_set_monitor_type,
+ r8192_wx_set_crcmon,
r8192_wx_set_scan_type,
r8192_wx_set_rawtx,
- //r8192_wx_null,
r8192_wx_force_reset,
};
@@ -981,6 +966,7 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
int tmp_level = 0;
int tmp_qual = 0;
int tmp_noise = 0;
+
if (ieee->state < IEEE80211_LINKED) {
wstats->qual.qual = 0;
wstats->qual.level = 0;
@@ -992,12 +978,11 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
tmp_level = (&ieee->current_network)->stats.rssi;
tmp_qual = (&ieee->current_network)->stats.signal;
tmp_noise = (&ieee->current_network)->stats.noise;
- //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
wstats->qual.level = tmp_level;
wstats->qual.qual = tmp_qual;
wstats->qual.noise = tmp_noise;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
+ wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
return wstats;
}
diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c
index 02554c981203..e9c15fe8ded5 100644
--- a/drivers/staging/rtl8192u/r819xU_phy.c
+++ b/drivers/staging/rtl8192u/r819xU_phy.c
@@ -101,7 +101,6 @@ void rtl8192_setBBreg(struct net_device *dev, u32 reg_addr, u32 bitmask,
} else {
write_nic_dword(dev, reg_addr, data);
}
- return;
}
/******************************************************************************
@@ -281,7 +280,6 @@ static void rtl8192_phy_RFSerialWrite(struct net_device *dev,
priv->RfReg0Value[eRFPath] << 16);
}
}
- return;
}
/******************************************************************************
@@ -332,7 +330,6 @@ void rtl8192_phy_SetRFReg(struct net_device *dev, RF90_RADIO_PATH_E eRFPath,
rtl8192_phy_RFSerialWrite(dev, eRFPath, reg_addr, data);
}
}
- return;
}
/******************************************************************************
@@ -513,7 +510,6 @@ void rtl8192_phy_configmac(struct net_device *dev)
rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1],
pdwArray[i+2]);
}
- return;
}
/******************************************************************************
@@ -559,7 +555,6 @@ void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType)
rtl819XAGCTAB_Array[i+1]);
}
}
- return;
}
/******************************************************************************
@@ -846,7 +841,6 @@ static void rtl8192_BB_Config_ParaFile(struct net_device *dev)
priv->bCckHighPower = (u8)rtl8192_QueryBBReg(dev,
rFPGA0_XA_HSSIParameter2,
0x200);
- return;
}
/******************************************************************************
@@ -864,7 +858,6 @@ void rtl8192_BBConfig(struct net_device *dev)
* implemented, so use file first.
* FIXME: should implement it for hardcode? */
rtl8192_BB_Config_ParaFile(dev);
- return;
}
@@ -912,8 +905,6 @@ void rtl8192_phy_getTxPower(struct net_device *dev)
/* Read SIFS (save the value read fome MACPHY_REG.txt) */
read_nic_word(dev, SIFS, &priv->SifsTime);
-
- return;
}
/******************************************************************************
@@ -942,7 +933,6 @@ void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel)
__func__);
break;
}
- return;
}
/******************************************************************************
@@ -956,14 +946,13 @@ void rtl8192_phy_RFConfig(struct net_device *dev)
struct r8192_priv *priv = ieee80211_priv(dev);
switch (priv->rf_chip) {
- case RF_8256:
- PHY_RF8256_Config(dev);
- break;
- default:
- RT_TRACE(COMP_ERR, "error chip id\n");
- break;
+ case RF_8256:
+ PHY_RF8256_Config(dev);
+ break;
+ default:
+ RT_TRACE(COMP_ERR, "error chip id\n");
+ break;
}
- return;
}
/******************************************************************************
@@ -974,7 +963,6 @@ void rtl8192_phy_RFConfig(struct net_device *dev)
******************************************************************************/
void rtl8192_phy_updateInitGain(struct net_device *dev)
{
- return;
}
/******************************************************************************
@@ -1094,7 +1082,6 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
RT_TRACE(COMP_ERR, "unknown rf chip ID in %s()\n", __func__);
break;
}
- return;
}
/******************************************************************************
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index 3362e5e32bcc..3d0a98b6d8e5 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -160,7 +160,6 @@ struct _adapter {
s32 bSurpriseRemoved;
u32 IsrContent;
u32 ImrContent;
- bool fw_found;
u8 EepromAddressSize;
u8 hw_init_completed;
struct task_struct *cmdThread;
@@ -174,7 +173,7 @@ struct _adapter {
struct net_device_stats stats;
struct iw_statistics iwstats;
int pid; /*process id from UI*/
- _workitem wkFilterRxFF0;
+ struct work_struct wkFilterRxFF0;
u8 blnEnableRxFF0Filter;
spinlock_t lockRxFF0Filter;
const struct firmware *fw;
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
index 36de7e478f32..0556de3b8904 100644
--- a/drivers/staging/rtl8712/hal_init.c
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -50,13 +50,11 @@ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
struct usb_device *udev = padapter->dvobjpriv.pusbdev;
struct usb_interface *pusb_intf = padapter->pusb_intf;
dev_err(&udev->dev, "r8712u: Firmware request failed\n");
- padapter->fw_found = false;
usb_put_dev(udev);
usb_set_intfdata(pusb_intf, NULL);
return;
}
padapter->fw = firmware;
- padapter->fw_found = true;
/* firmware available - start netdev */
register_netdev(padapter->pnetdev);
}
diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h
index da4000e49da6..8269be80437a 100644
--- a/drivers/staging/rtl8712/ieee80211.h
+++ b/drivers/staging/rtl8712/ieee80211.h
@@ -734,7 +734,7 @@ enum ieee80211_state {
#define IEEE_G (1<<2)
#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
{
/* Single white space is for Linksys APs */
if (essid_len == 1 && essid[0] == ' ')
@@ -748,7 +748,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
return 1;
}
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
{
int hdrlen = 24;
diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c
index 377efb88676f..354bd03e700f 100644
--- a/drivers/staging/rtl8712/mlme_linux.c
+++ b/drivers/staging/rtl8712/mlme_linux.c
@@ -44,18 +44,21 @@ static void sitesurvey_ctrl_handler(void *FunctionContext)
static void join_timeout_handler (void *FunctionContext)
{
struct _adapter *adapter = (struct _adapter *)FunctionContext;
+
_r8712_join_timeout_handler(adapter);
}
static void _scan_timeout_handler (void *FunctionContext)
{
struct _adapter *adapter = (struct _adapter *)FunctionContext;
+
r8712_scan_timeout_handler(adapter);
}
static void dhcp_timeout_handler (void *FunctionContext)
{
struct _adapter *adapter = (struct _adapter *)FunctionContext;
+
_r8712_dhcp_timeout_handler(adapter);
}
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
index 6bd08213cb70..13debb59ad97 100644
--- a/drivers/staging/rtl8712/os_intfs.c
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -345,8 +345,7 @@ u8 r8712_free_drv_sw(struct _adapter *padapter)
r8712_free_mlme_priv(&padapter->mlmepriv);
r8712_free_io_queue(padapter);
_free_xmit_priv(&padapter->xmitpriv);
- if (padapter->fw_found)
- _r8712_free_sta_priv(&padapter->stapriv);
+ _r8712_free_sta_priv(&padapter->stapriv);
_r8712_free_recv_priv(&padapter->recvpriv);
mp871xdeinit(padapter);
if (pnetdev)
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index 09e156199e7f..d7a357b8d2d1 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -50,32 +50,16 @@ struct __queue {
#define _pkt struct sk_buff
#define _buffer unsigned char
#define thread_exit() complete_and_exit(NULL, 0)
-#define _workitem struct work_struct
#define _init_queue(pqueue) \
do { \
- _init_listhead(&((pqueue)->queue)); \
+ INIT_LIST_HEAD(&((pqueue)->queue)); \
spin_lock_init(&((pqueue)->lock)); \
} while (0)
-static inline struct list_head *get_next(struct list_head *list)
-{
- return list->next;
-}
-
-static inline struct list_head *get_list_head(struct __queue *queue)
-{
- return &(queue->queue);
-}
-
#define LIST_CONTAINOR(ptr, type, member) \
((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
-static inline void list_delete(struct list_head *plist)
-{
- list_del_init(plist);
-}
-
static inline void _init_timer(struct timer_list *ptimer,
struct net_device *padapter,
void *pfunc, void *cntx)
@@ -96,39 +80,10 @@ static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled)
*bcancelled = true; /*true ==1; false==0*/
}
-static inline void _init_workitem(_workitem *pwork, void *pfunc, void *cntx)
-{
- INIT_WORK(pwork, pfunc);
-}
-
-static inline void _set_workitem(_workitem *pwork)
-{
- schedule_work(pwork);
-}
-
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
-/*
-For the following list_xxx operations,
-caller must guarantee the atomic context.
-Otherwise, there will be racing condition.
-*/
-static inline u32 is_list_empty(struct list_head *phead)
-{
- if (list_empty(phead))
- return true;
- else
- return false;
-}
-
-static inline void list_insert_tail(struct list_head *plist,
- struct list_head *phead)
-{
- list_add_tail(plist, phead);
-}
-
static inline u32 _down_sema(struct semaphore *sema)
{
if (down_interruptible(sema))
@@ -137,16 +92,6 @@ static inline u32 _down_sema(struct semaphore *sema)
return _SUCCESS;
}
-static inline void _init_listhead(struct list_head *list)
-{
- INIT_LIST_HEAD(list);
-}
-
-static inline u32 _queue_empty(struct __queue *pqueue)
-{
- return is_list_empty(&(pqueue->queue));
-}
-
static inline u32 end_of_queue_search(struct list_head *head,
struct list_head *plist)
{
@@ -173,36 +118,11 @@ static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
return del_timer(ptimer);
}
-static inline void thread_enter(void *context)
-{
- allow_signal(SIGTERM);
-}
-
static inline void flush_signals_thread(void)
{
if (signal_pending(current))
flush_signals(current);
}
-static inline u32 _RND8(u32 sz)
-{
- return ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3;
-}
-
-static inline u32 _RND128(u32 sz)
-{
- return ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7;
-}
-
-static inline u32 _RND256(u32 sz)
-{
- return ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8;
-}
-
-static inline u32 _RND512(u32 sz)
-{
- return ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9;
-}
-
#endif
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c
index 8ca7d7e68dca..ab0c7eb248d3 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -326,7 +326,7 @@ int r8712_cmd_thread(void *context)
struct _adapter *padapter = (struct _adapter *)context;
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
- thread_enter(padapter);
+ allow_signal(SIGTERM);
while (1) {
if ((_down_sema(&(pcmdpriv->cmd_queue_sema))) == _FAIL)
break;
@@ -351,7 +351,7 @@ _next:
&padapter->dvobjpriv;
u8 blnPending = 0;
pcmdpriv->cmd_issued_cnt++;
- cmdsz = _RND8((pcmd->cmdsz)); /* _RND8 */
+ cmdsz = round_up(pcmd->cmdsz, 8);
wr_sz = TXDESC_SIZE + 8 + cmdsz;
pdesc->txdw0 |= cpu_to_le32((wr_sz-TXDESC_SIZE) &
0x0000ffff);
@@ -410,7 +410,7 @@ _next:
}
}
r8712_free_cmd_obj(pcmd);
- if (_queue_empty(&(pcmdpriv->cmd_queue))) {
+ if (list_empty(&pcmdpriv->cmd_queue.queue)) {
r8712_unregister_cmd_alive(padapter);
continue;
} else
diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c
index 6cb1a0af5177..56e8add30a20 100644
--- a/drivers/staging/rtl8712/rtl8712_led.c
+++ b/drivers/staging/rtl8712/rtl8712_led.c
@@ -98,7 +98,7 @@ static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
pLed->BlinkTimes = 0;
pLed->BlinkingLedState = LED_UNKNOWN;
_init_timer(&(pLed->BlinkTimer), nic, BlinkTimerCallback, pLed);
- _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
+ INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
}
/*
@@ -827,7 +827,7 @@ static void BlinkTimerCallback(unsigned long data)
if ((pLed->padapter->bSurpriseRemoved == true) ||
(pLed->padapter->bDriverStopped == true))
return;
- _set_workitem(&(pLed->BlinkWorkItem));
+ schedule_work(&pLed->BlinkWorkItem);
}
/* Description:
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
index 1f700171af13..df1e498e98b6 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.c
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -66,14 +66,14 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter)
((addr_t) (precvpriv->pallocated_recv_buf) & 3);
precvbuf = (struct recv_buf *)precvpriv->precv_buf;
for (i = 0; i < NR_RECVBUFF; i++) {
- _init_listhead(&precvbuf->list);
+ INIT_LIST_HEAD(&precvbuf->list);
spin_lock_init(&precvbuf->recvbuf_lock);
res = r8712_os_recvbuf_resource_alloc(padapter, precvbuf);
if (res == _FAIL)
break;
precvbuf->ref_cnt = 0;
precvbuf->adapter = padapter;
- list_insert_tail(&precvbuf->list,
+ list_add_tail(&precvbuf->list,
&(precvpriv->free_recv_buf_queue.queue));
precvbuf++;
}
@@ -145,9 +145,8 @@ int r8712_free_recvframe(union recv_frame *precvframe,
precvframe->u.hdr.pkt = NULL;
}
spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
- list_delete(&(precvframe->u.hdr.list));
- list_insert_tail(&(precvframe->u.hdr.list),
- get_list_head(pfree_recv_queue));
+ list_del_init(&(precvframe->u.hdr.list));
+ list_add_tail(&(precvframe->u.hdr.list), &pfree_recv_queue->queue);
if (padapter != NULL) {
if (pfree_recv_queue == &precvpriv->free_recv_queue)
precvpriv->free_recvframe_cnt++;
@@ -208,10 +207,10 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter,
struct __queue *pfree_recv_queue;
pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
- phead = get_list_head(defrag_q);
- plist = get_next(phead);
+ phead = &defrag_q->queue;
+ plist = phead->next;
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
- list_delete(&prframe->u.list);
+ list_del_init(&prframe->u.list);
pfhdr = &prframe->u.hdr;
curfragnum = 0;
if (curfragnum != pfhdr->attrib.frag_num) {
@@ -222,8 +221,8 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter,
return NULL;
}
curfragnum++;
- plist = get_list_head(defrag_q);
- plist = get_next(plist);
+ plist = &defrag_q->queue;
+ plist = plist->next;
data = get_recvframe_data(prframe);
while (end_of_queue_search(phead, plist) == false) {
pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
@@ -247,7 +246,7 @@ static union recv_frame *recvframe_defrag(struct _adapter *adapter,
memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
recvframe_put(prframe, pnfhdr->len);
pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
- plist = get_next(plist);
+ plist = plist->next;
}
/* free the defrag_q queue and return the prframe */
r8712_free_recvframe_queue(defrag_q, pfree_recv_queue);
@@ -289,15 +288,15 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
if (pdefrag_q != NULL) {
if (fragnum == 0) {
/*the first fragment*/
- if (_queue_empty(pdefrag_q) == false) {
+ if (!list_empty(&pdefrag_q->queue)) {
/*free current defrag_q */
r8712_free_recvframe_queue(pdefrag_q,
pfree_recv_queue);
}
}
/* Then enqueue the 0~(n-1) fragment to the defrag_q */
- phead = get_list_head(pdefrag_q);
- list_insert_tail(&pfhdr->list, phead);
+ phead = &pdefrag_q->queue;
+ list_add_tail(&pfhdr->list, phead);
prtnframe = NULL;
} else {
/* can't find this ta's defrag_queue, so free this
@@ -311,8 +310,8 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
/* the last fragment frame
* enqueue the last fragment */
if (pdefrag_q != NULL) {
- phead = get_list_head(pdefrag_q);
- list_insert_tail(&pfhdr->list, phead);
+ phead = &pdefrag_q->queue;
+ list_add_tail(&pfhdr->list, phead);
/*call recvframe_defrag to defrag*/
precv_frame = recvframe_defrag(padapter, pdefrag_q);
prtnframe = precv_frame;
@@ -499,20 +498,20 @@ static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl,
&preorder_ctrl->pending_recvframe_queue;
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
- phead = get_list_head(ppending_recvframe_queue);
- plist = get_next(phead);
+ phead = &ppending_recvframe_queue->queue;
+ plist = phead->next;
while (end_of_queue_search(phead, plist) == false) {
pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
pnextattrib = &pnextrframe->u.hdr.attrib;
if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
- plist = get_next(plist);
+ plist = plist->next;
else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
return false;
else
break;
}
- list_delete(&(prframe->u.hdr.list));
- list_insert_tail(&(prframe->u.hdr.list), plist);
+ list_del_init(&(prframe->u.hdr.list));
+ list_add_tail(&(prframe->u.hdr.list), plist);
return true;
}
@@ -528,11 +527,11 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter,
struct __queue *ppending_recvframe_queue =
&preorder_ctrl->pending_recvframe_queue;
- phead = get_list_head(ppending_recvframe_queue);
- plist = get_next(phead);
+ phead = &ppending_recvframe_queue->queue;
+ plist = phead->next;
/* Handling some condition for forced indicate case.*/
if (bforced == true) {
- if (is_list_empty(phead))
+ if (list_empty(phead))
return true;
else {
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
@@ -542,12 +541,12 @@ int r8712_recv_indicatepkts_in_order(struct _adapter *padapter,
}
/* Prepare indication list and indication.
* Check if there is any packet need indicate. */
- while (!is_list_empty(phead)) {
+ while (!list_empty(phead)) {
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
pattrib = &prframe->u.hdr.attrib;
if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
- plist = get_next(plist);
- list_delete(&(prframe->u.hdr.list));
+ plist = plist->next;
+ list_del_init(&(prframe->u.hdr.list));
if (SN_EQUAL(preorder_ctrl->indicate_seq,
pattrib->seq_num))
preorder_ctrl->indicate_seq =
@@ -1061,11 +1060,11 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
precvframe = r8712_alloc_recvframe(pfree_recv_queue);
if (precvframe == NULL)
goto _exit_recvbuf2recvframe;
- _init_listhead(&precvframe->u.hdr.list);
+ INIT_LIST_HEAD(&precvframe->u.hdr.list);
precvframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf*/
precvframe->u.hdr.len = 0;
tmp_len = pkt_len + drvinfo_sz + RXDESC_SIZE;
- pkt_offset = (u16)_RND128(tmp_len);
+ pkt_offset = (u16)round_up(tmp_len, 128);
/* for first fragment packet, driver need allocate 1536 +
* drvinfo_sz + RXDESC_SIZE to defrag packet. */
if ((mf == 1) && (frag == 0))
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c
index 4e3f09420c1e..4ebedb4005cf 100644
--- a/drivers/staging/rtl8712/rtl8712_xmit.c
+++ b/drivers/staging/rtl8712/rtl8712_xmit.c
@@ -166,12 +166,12 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv,
struct list_head *xmitframe_plist, *xmitframe_phead;
struct xmit_frame *pxmitframe = NULL;
- xmitframe_phead = get_list_head(pframe_queue);
- xmitframe_plist = get_next(xmitframe_phead);
+ xmitframe_phead = &pframe_queue->queue;
+ xmitframe_plist = xmitframe_phead->next;
if ((end_of_queue_search(xmitframe_phead, xmitframe_plist)) == false) {
pxmitframe = LIST_CONTAINOR(xmitframe_plist,
struct xmit_frame, list);
- list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
ptxservq->qcnt--;
phwxmit->txcmdcnt++;
}
@@ -210,8 +210,8 @@ static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv,
spin_lock_irqsave(&pxmitpriv->lock, irqL0);
for (i = 0; i < entry; i++) {
phwxmit = phwxmit_i + inx[i];
- sta_phead = get_list_head(phwxmit->sta_queue);
- sta_plist = get_next(sta_phead);
+ sta_phead = &phwxmit->sta_queue->queue;
+ sta_plist = sta_phead->next;
while ((end_of_queue_search(sta_phead, sta_plist)) == false) {
ptxservq = LIST_CONTAINOR(sta_plist, struct tx_servq,
tx_pending);
@@ -222,11 +222,13 @@ static struct xmit_frame *dequeue_xframe_ex(struct xmit_priv *pxmitpriv,
phwxmit->accnt--;
goto exit_dequeue_xframe_ex;
}
- sta_plist = get_next(sta_plist);
+ sta_plist = sta_plist->next;
/*Remove sta node when there are no pending packets.*/
- if (_queue_empty(pframe_queue)) {
- /*must be done after get_next and before break*/
- list_delete(&ptxservq->tx_pending);
+ if (list_empty(&pframe_queue->queue)) {
+ /* must be done after sta_plist->next
+ * and before break
+ */
+ list_del_init(&ptxservq->tx_pending);
}
}
}
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c
index 7a252200e902..d9c1561e3272 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.c
+++ b/drivers/staging/rtl8712/rtl871x_cmd.c
@@ -126,7 +126,7 @@ static sint _enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
if (obj == NULL)
return _SUCCESS;
spin_lock_irqsave(&queue->lock, irqL);
- list_insert_tail(&obj->list, &queue->queue);
+ list_add_tail(&obj->list, &queue->queue);
spin_unlock_irqrestore(&queue->lock, irqL);
return _SUCCESS;
}
@@ -137,12 +137,12 @@ static struct cmd_obj *_dequeue_cmd(struct __queue *queue)
struct cmd_obj *obj;
spin_lock_irqsave(&(queue->lock), irqL);
- if (is_list_empty(&(queue->queue)))
+ if (list_empty(&(queue->queue)))
obj = NULL;
else {
- obj = LIST_CONTAINOR(get_next(&(queue->queue)),
+ obj = LIST_CONTAINOR(queue->queue.next,
struct cmd_obj, list);
- list_delete(&obj->list);
+ list_del_init(&obj->list);
}
spin_unlock_irqrestore(&(queue->lock), irqL);
return obj;
@@ -190,7 +190,7 @@ u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
return _FAIL;
queue = &pcmdpriv->cmd_queue;
spin_lock_irqsave(&queue->lock, irqL);
- list_insert_tail(&obj->list, &queue->queue);
+ list_add_tail(&obj->list, &queue->queue);
spin_unlock_irqrestore(&queue->lock, irqL);
up(&pcmdpriv->cmd_queue_sema);
return _SUCCESS;
@@ -227,10 +227,10 @@ u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psurveyPara = kmalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
+ psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC);
if (psurveyPara == NULL) {
kfree((unsigned char *) ph2c);
return _FAIL;
@@ -259,11 +259,10 @@ u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset)
struct setdatarate_parm *pbsetdataratepara;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pbsetdataratepara = kmalloc(sizeof(struct setdatarate_parm),
- GFP_ATOMIC);
+ pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC);
if (pbsetdataratepara == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -282,11 +281,10 @@ u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan)
struct SetChannelPlan_param *psetchplanpara;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetchplanpara = kmalloc(sizeof(struct SetChannelPlan_param),
- GFP_ATOMIC);
+ psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC);
if (psetchplanpara == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -304,11 +302,10 @@ u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset)
struct setbasicrate_parm *pssetbasicratepara;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pssetbasicratepara = kmalloc(sizeof(struct setbasicrate_parm),
- GFP_ATOMIC);
+ pssetbasicratepara = kmalloc(sizeof(*pssetbasicratepara), GFP_ATOMIC);
if (pssetbasicratepara == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -327,10 +324,10 @@ u8 r8712_setptm_cmd(struct _adapter *padapter, u8 type)
struct writePTM_parm *pwriteptmparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pwriteptmparm = kmalloc(sizeof(struct writePTM_parm), GFP_ATOMIC);
+ pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC);
if (pwriteptmparm == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -347,10 +344,10 @@ u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type)
struct writePTM_parm *pwriteptmparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pwriteptmparm = kmalloc(sizeof(struct writePTM_parm), GFP_ATOMIC);
+ pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC);
if (pwriteptmparm == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -367,10 +364,10 @@ u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type)
struct writePTM_parm *pwriteptmparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pwriteptmparm = kmalloc(sizeof(struct writePTM_parm), GFP_ATOMIC);
+ pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC);
if (pwriteptmparm == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -387,10 +384,10 @@ u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val)
struct writeRF_parm *pwriterfparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pwriterfparm = kmalloc(sizeof(struct writeRF_parm), GFP_ATOMIC);
+ pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC);
if (pwriterfparm == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -408,15 +405,15 @@ u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval)
struct readRF_parm *prdrfparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- prdrfparm = kmalloc(sizeof(struct readRF_parm), GFP_ATOMIC);
+ prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC);
if (prdrfparm == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
}
- _init_listhead(&ph2c->list);
+ INIT_LIST_HEAD(&ph2c->list);
ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
ph2c->parmbuf = (unsigned char *)prdrfparm;
ph2c->cmdsz = sizeof(struct readRF_parm);
@@ -452,10 +449,10 @@ u8 r8712_createbss_cmd(struct _adapter *padapter)
&padapter->registrypriv.dev_network;
padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
- pcmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
if (pcmd == NULL)
return _FAIL;
- _init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _CreateBss_CMD_;
pcmd->parmbuf = (unsigned char *)pdev_network;
pcmd->cmdsz = r8712_get_ndis_wlan_bssid_ex_sz((
@@ -486,7 +483,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
network.InfrastructureMode;
padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
- pcmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
if (pcmd == NULL)
return _FAIL;
t_len = sizeof(u32) + 6 * sizeof(unsigned char) + 2 +
@@ -609,7 +606,7 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
psecnetwork->InfrastructureMode);
psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
#endif
- _init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
pcmd->cmdcode = _JoinBss_CMD_;
pcmd->parmbuf = (unsigned char *)psecnetwork;
pcmd->rsp = NULL;
@@ -624,10 +621,10 @@ u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */
struct disconnect_parm *pdisconnect;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pdisconnect_cmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC);
if (pdisconnect_cmd == NULL)
return _FAIL;
- pdisconnect = kmalloc(sizeof(struct disconnect_parm), GFP_ATOMIC);
+ pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC);
if (pdisconnect == NULL) {
kfree((u8 *)pdisconnect_cmd);
return _FAIL;
@@ -646,10 +643,10 @@ u8 r8712_setopmode_cmd(struct _adapter *padapter,
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetop = kmalloc(sizeof(struct setopmode_parm), GFP_ATOMIC);
+ psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC);
if (psetop == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -670,15 +667,15 @@ u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key)
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct sta_info *sta = (struct sta_info *)psta;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetstakey_para = kmalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC);
+ psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC);
if (psetstakey_para == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
}
- psetstakey_rsp = kmalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC);
+ psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC);
if (psetstakey_rsp == NULL) {
kfree((u8 *) ph2c);
kfree((u8 *) psetstakey_para);
@@ -710,10 +707,10 @@ u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode)
struct setrfintfs_parm *psetrfintfsparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetrfintfsparm = kmalloc(sizeof(struct setrfintfs_parm), GFP_ATOMIC);
+ psetrfintfsparm = kmalloc(sizeof(*psetrfintfsparm), GFP_ATOMIC);
if (psetrfintfsparm == NULL) {
kfree((unsigned char *) ph2c);
return _FAIL;
@@ -732,10 +729,10 @@ u8 r8712_setrttbl_cmd(struct _adapter *padapter,
struct setratable_parm *psetrttblparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetrttblparm = kmalloc(sizeof(struct setratable_parm), GFP_ATOMIC);
+ psetrttblparm = kmalloc(sizeof(*psetrttblparm), GFP_ATOMIC);
if (psetrttblparm == NULL) {
kfree((unsigned char *)ph2c);
return _FAIL;
@@ -753,15 +750,15 @@ u8 r8712_gettssi_cmd(struct _adapter *padapter, u8 offset, u8 *pval)
struct cmd_obj *ph2c;
struct readTSSI_parm *prdtssiparm;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- prdtssiparm = kmalloc(sizeof(struct readTSSI_parm), GFP_ATOMIC);
+ prdtssiparm = kmalloc(sizeof(*prdtssiparm), GFP_ATOMIC);
if (prdtssiparm == NULL) {
kfree((unsigned char *) ph2c);
return _FAIL;
}
- _init_listhead(&ph2c->list);
+ INIT_LIST_HEAD(&ph2c->list);
ph2c->cmdcode = GEN_CMD_CODE(_ReadTSSI);
ph2c->parmbuf = (unsigned char *)prdtssiparm;
ph2c->cmdsz = sizeof(struct readTSSI_parm);
@@ -779,11 +776,10 @@ u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr)
struct cmd_obj *ph2c;
struct SetMacAddr_param *psetMacAddr_para;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetMacAddr_para = kmalloc(sizeof(struct SetMacAddr_param),
- GFP_ATOMIC);
+ psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC);
if (psetMacAddr_para == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
@@ -802,17 +798,15 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr)
struct set_assocsta_parm *psetassocsta_para;
struct set_assocsta_rsp *psetassocsta_rsp = NULL;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- psetassocsta_para = kmalloc(sizeof(struct set_assocsta_parm),
- GFP_ATOMIC);
+ psetassocsta_para = kmalloc(sizeof(*psetassocsta_para), GFP_ATOMIC);
if (psetassocsta_para == NULL) {
kfree((u8 *) ph2c);
return _FAIL;
}
- psetassocsta_rsp = kmalloc(sizeof(struct set_assocsta_rsp),
- GFP_ATOMIC);
+ psetassocsta_rsp = kmalloc(sizeof(*psetassocsta_rsp), GFP_ATOMIC);
if (psetassocsta_rsp == NULL) {
kfree((u8 *)ph2c);
kfree((u8 *)psetassocsta_para);
@@ -832,10 +826,10 @@ u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid)
struct cmd_obj *ph2c;
struct addBaReq_parm *paddbareq_parm;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- paddbareq_parm = kmalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
+ paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC);
if (paddbareq_parm == NULL) {
kfree((unsigned char *)ph2c);
return _FAIL;
@@ -853,10 +847,10 @@ u8 r8712_wdg_wk_cmd(struct _adapter *padapter)
struct drvint_cmd_parm *pdrvintcmd_param;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- pdrvintcmd_param = kmalloc(sizeof(struct drvint_cmd_parm), GFP_ATOMIC);
+ pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC);
if (pdrvintcmd_param == NULL) {
kfree((unsigned char *)ph2c);
return _FAIL;
@@ -962,7 +956,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
goto createbss_cmd_fail;
pwlan->last_scanned = jiffies;
} else
- list_insert_tail(&(pwlan->list),
+ list_add_tail(&(pwlan->list),
&pmlmepriv->scanned_queue.queue);
pnetwork->Length = r8712_get_ndis_wlan_bssid_ex_sz(pnetwork);
memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
@@ -1027,10 +1021,10 @@ u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl,
struct DisconnectCtrlEx_param *param;
struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
- ph2c = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
if (ph2c == NULL)
return _FAIL;
- param = kzalloc(sizeof(struct DisconnectCtrlEx_param), GFP_ATOMIC);
+ param = kzalloc(sizeof(*param), GFP_ATOMIC);
if (param == NULL) {
kfree((unsigned char *) ph2c);
return _FAIL;
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h
index 0ce79b1c4ee2..cb8225b94cf1 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.h
+++ b/drivers/staging/rtl8712/rtl871x_cmd.h
@@ -83,7 +83,7 @@ struct evt_priv {
#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \
do {\
- _init_listhead(&pcmd->list);\
+ INIT_LIST_HEAD(&pcmd->list);\
pcmd->cmdcode = code;\
pcmd->parmbuf = (u8 *)(pparm);\
pcmd->cmdsz = sizeof(*pparm);\
diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c
index 37a841a14889..8858687e87fe 100644
--- a/drivers/staging/rtl8712/rtl871x_io.c
+++ b/drivers/staging/rtl8712/rtl871x_io.c
@@ -112,12 +112,12 @@ uint r8712_alloc_io_queue(struct _adapter *adapter)
struct io_queue *pio_queue;
struct io_req *pio_req;
- pio_queue = kmalloc(sizeof(struct io_queue), GFP_ATOMIC);
+ pio_queue = kmalloc(sizeof(*pio_queue), GFP_ATOMIC);
if (pio_queue == NULL)
goto alloc_io_queue_fail;
- _init_listhead(&pio_queue->free_ioreqs);
- _init_listhead(&pio_queue->processing);
- _init_listhead(&pio_queue->pending);
+ INIT_LIST_HEAD(&pio_queue->free_ioreqs);
+ INIT_LIST_HEAD(&pio_queue->processing);
+ INIT_LIST_HEAD(&pio_queue->pending);
spin_lock_init(&pio_queue->lock);
pio_queue->pallocated_free_ioreqs_buf = kmalloc(NUM_IOREQ *
(sizeof(struct io_req)) + 4,
@@ -131,8 +131,8 @@ uint r8712_alloc_io_queue(struct _adapter *adapter)
& 3);
pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf);
for (i = 0; i < NUM_IOREQ; i++) {
- _init_listhead(&pio_req->list);
- list_insert_tail(&pio_req->list, &pio_queue->free_ioreqs);
+ INIT_LIST_HEAD(&pio_req->list);
+ list_add_tail(&pio_req->list, &pio_queue->free_ioreqs);
pio_req++;
}
if ((register_intf_hdl((u8 *)adapter, &(pio_queue->intf))) == _FAIL)
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index e147c4bfe124..e1e95cf48302 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -1078,14 +1078,14 @@ static int r8711_wx_set_wap(struct net_device *dev,
return -EINVAL;
authmode = padapter->securitypriv.ndisauthtype;
spin_lock_irqsave(&queue->lock, irqL);
- phead = get_list_head(queue);
- pmlmepriv->pscanned = get_next(phead);
+ phead = &queue->queue;
+ pmlmepriv->pscanned = phead->next;
while (1) {
if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
break;
pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
struct wlan_network, list);
- pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ pmlmepriv->pscanned = pmlmepriv->pscanned->next;
dst_bssid = pnetwork->network.MacAddress;
if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
r8712_set_802_11_infrastructure_mode(padapter,
@@ -1227,8 +1227,8 @@ static int r8711_wx_get_scan(struct net_device *dev,
break;
}
spin_lock_irqsave(&queue->lock, irqL);
- phead = get_list_head(queue);
- plist = get_next(phead);
+ phead = &queue->queue;
+ plist = phead->next;
while (1) {
if (end_of_queue_search(phead, plist) == true)
break;
@@ -1238,7 +1238,7 @@ static int r8711_wx_get_scan(struct net_device *dev,
}
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
ev = translate_scan(padapter, a, pnetwork, ev, stop);
- plist = get_next(plist);
+ plist = plist->next;
}
spin_unlock_irqrestore(&queue->lock, irqL);
wrqu->data.length = ev - extra;
@@ -1286,14 +1286,14 @@ static int r8711_wx_set_essid(struct net_device *dev,
ndis_ssid.SsidLength = len;
memcpy(ndis_ssid.Ssid, extra, len);
src_ssid = ndis_ssid.Ssid;
- phead = get_list_head(queue);
- pmlmepriv->pscanned = get_next(phead);
+ phead = &queue->queue;
+ pmlmepriv->pscanned = phead->next;
while (1) {
if (end_of_queue_search(phead, pmlmepriv->pscanned))
break;
pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
struct wlan_network, list);
- pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ pmlmepriv->pscanned = pmlmepriv->pscanned->next;
dst_ssid = pnetwork->network.Ssid.Ssid;
if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
&& (pnetwork->network.Ssid.SsidLength ==
@@ -1459,17 +1459,12 @@ static int r8711_wx_get_rate(struct net_device *dev,
RTL8712_RF_2T2R == rf_type)
max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
270) : ((short_GI) ? 144 : 130);
- else if (mcs_rate & 0x0080) /* MCS7 */
- max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
- 135) : ((short_GI) ? 72 : 65);
else /* default MCS7 */
max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
135) : ((short_GI) ? 72 : 65);
max_rate *= 2; /* Mbps/2 */
- wrqu->bitrate.value = max_rate * 500000;
- } else {
- wrqu->bitrate.value = max_rate * 500000;
}
+ wrqu->bitrate.value = max_rate * 500000;
} else
return -ENOLINK;
return 0;
@@ -2007,8 +2002,8 @@ static int r871x_get_ap_info(struct net_device *dev,
} else
return -EINVAL;
spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
- phead = get_list_head(queue);
- plist = get_next(phead);
+ phead = &queue->queue;
+ plist = phead->next;
while (1) {
if (end_of_queue_search(phead, plist) == true)
break;
@@ -2036,7 +2031,7 @@ static int r871x_get_ap_info(struct net_device *dev,
break;
}
}
- plist = get_next(plist);
+ plist = plist->next;
}
spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
if (pdata->length >= 34) {
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
index 53a7c8c1bb40..9d47eb472837 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c
@@ -62,8 +62,8 @@ static u8 do_join(struct _adapter *padapter)
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct __queue *queue = &(pmlmepriv->scanned_queue);
- phead = get_list_head(queue);
- plist = get_next(phead);
+ phead = &queue->queue;
+ plist = phead->next;
pmlmepriv->cur_network.join_res = -2;
pmlmepriv->fw_state |= _FW_UNDER_LINKING;
pmlmepriv->pscanned = plist;
@@ -71,7 +71,7 @@ static u8 do_join(struct _adapter *padapter)
/* adhoc mode will start with an empty queue, but skip checking */
if (!check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) &&
- _queue_empty(queue)) {
+ list_empty(&queue->queue)) {
if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
/* when set_ssid/set_bssid for do_join(), but scanning queue
diff --git a/drivers/staging/rtl8712/rtl871x_led.h b/drivers/staging/rtl8712/rtl871x_led.h
index 1a90c7f4d8f3..eb612053a3dd 100644
--- a/drivers/staging/rtl8712/rtl871x_led.h
+++ b/drivers/staging/rtl8712/rtl871x_led.h
@@ -99,7 +99,7 @@ struct LED_871x {
* either LED_ON or OFF.*/
struct timer_list BlinkTimer; /* Timer object for led blinking.*/
- _workitem BlinkWorkItem; /* Workitem used by BlinkTimer */
+ struct work_struct BlinkWorkItem; /* Workitem used by BlinkTimer */
};
struct led_priv {
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index 02339e100014..7b7fdec58b38 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -69,8 +69,8 @@ static sint _init_mlme_priv(struct _adapter *padapter)
pmlmepriv->free_bss_buf = pbuf;
pnetwork = (struct wlan_network *)pbuf;
for (i = 0; i < MAX_BSS_CNT; i++) {
- _init_listhead(&(pnetwork->list));
- list_insert_tail(&(pnetwork->list),
+ INIT_LIST_HEAD(&(pnetwork->list));
+ list_add_tail(&(pnetwork->list),
&(pmlmepriv->free_bss_pool.queue));
pnetwork++;
}
@@ -89,12 +89,12 @@ struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
struct __queue *free_queue = &pmlmepriv->free_bss_pool;
struct list_head *plist = NULL;
- if (_queue_empty(free_queue) == true)
+ if (list_empty(&free_queue->queue))
return NULL;
spin_lock_irqsave(&free_queue->lock, irqL);
- plist = get_next(&(free_queue->queue));
+ plist = free_queue->queue.next;
pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
- list_delete(&pnetwork->list);
+ list_del_init(&pnetwork->list);
pnetwork->last_scanned = jiffies;
pmlmepriv->num_of_scanned++;
spin_unlock_irqrestore(&free_queue->lock, irqL);
@@ -117,8 +117,8 @@ static void _free_network(struct mlme_priv *pmlmepriv,
if (delta_time < SCANQUEUE_LIFETIME)
return;
spin_lock_irqsave(&free_queue->lock, irqL);
- list_delete(&pnetwork->list);
- list_insert_tail(&pnetwork->list, &free_queue->queue);
+ list_del_init(&pnetwork->list);
+ list_add_tail(&pnetwork->list, &free_queue->queue);
pmlmepriv->num_of_scanned--;
spin_unlock_irqrestore(&free_queue->lock, irqL);
}
@@ -132,8 +132,8 @@ static void _free_network_nolock(struct mlme_priv *pmlmepriv,
return;
if (pnetwork->fixed == true)
return;
- list_delete(&pnetwork->list);
- list_insert_tail(&pnetwork->list, get_list_head(free_queue));
+ list_del_init(&pnetwork->list);
+ list_add_tail(&pnetwork->list, &free_queue->queue);
pmlmepriv->num_of_scanned--;
}
@@ -153,11 +153,11 @@ static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue,
if (is_zero_ether_addr(addr))
return NULL;
spin_lock_irqsave(&scanned_queue->lock, irqL);
- phead = get_list_head(scanned_queue);
- plist = get_next(phead);
+ phead = &scanned_queue->queue;
+ plist = phead->next;
while (plist != phead) {
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
- plist = get_next(plist);
+ plist = plist->next;
if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
break;
}
@@ -174,11 +174,11 @@ static void _free_network_queue(struct _adapter *padapter)
struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
spin_lock_irqsave(&scanned_queue->lock, irqL);
- phead = get_list_head(scanned_queue);
- plist = get_next(phead);
+ phead = &scanned_queue->queue;
+ plist = phead->next;
while (end_of_queue_search(phead, plist) == false) {
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
- plist = get_next(plist);
+ plist = plist->next;
_free_network(pmlmepriv, pnetwork);
}
spin_unlock_irqrestore(&scanned_queue->lock, irqL);
@@ -315,8 +315,8 @@ struct wlan_network *r8712_get_oldest_wlan_network(
struct wlan_network *pwlan = NULL;
struct wlan_network *oldest = NULL;
- phead = get_list_head(scanned_queue);
- plist = get_next(phead);
+ phead = &scanned_queue->queue;
+ plist = phead->next;
while (1) {
if (end_of_queue_search(phead, plist) == true)
break;
@@ -327,7 +327,7 @@ struct wlan_network *r8712_get_oldest_wlan_network(
(unsigned long)pwlan->last_scanned))
oldest = pwlan;
}
- plist = get_next(plist);
+ plist = plist->next;
}
return oldest;
}
@@ -398,8 +398,8 @@ static void update_scanned_network(struct _adapter *adapter,
struct wlan_network *pnetwork = NULL;
struct wlan_network *oldest = NULL;
- phead = get_list_head(queue);
- plist = get_next(phead);
+ phead = &queue->queue;
+ plist = phead->next;
while (1) {
if (end_of_queue_search(phead, plist) == true)
@@ -413,14 +413,14 @@ static void update_scanned_network(struct _adapter *adapter,
(unsigned long)pnetwork->last_scanned))
oldest = pnetwork;
- plist = get_next(plist);
+ plist = plist->next;
}
/* If we didn't find a match, then get a new network slot to initialize
* with this beacon's information */
if (end_of_queue_search(phead, plist) == true) {
- if (_queue_empty(&pmlmepriv->free_bss_pool) == true) {
+ if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
/* If there are no more slots, expire the oldest */
pnetwork = oldest;
target->Rssi = (pnetwork->network.Rssi +
@@ -437,7 +437,7 @@ static void update_scanned_network(struct _adapter *adapter,
bssid_ex_sz = r8712_get_ndis_wlan_bssid_ex_sz(target);
target->Length = bssid_ex_sz;
memcpy(&pnetwork->network, target, bssid_ex_sz);
- list_insert_tail(&pnetwork->list, &queue->queue);
+ list_add_tail(&pnetwork->list, &queue->queue);
}
} else {
/* we have an entry and we are going to update it. But
@@ -1138,8 +1138,8 @@ int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
adapter = (struct _adapter *)pmlmepriv->nic_hdl;
queue = &pmlmepriv->scanned_queue;
- phead = get_list_head(queue);
- pmlmepriv->pscanned = get_next(phead);
+ phead = &queue->queue;
+ pmlmepriv->pscanned = phead->next;
while (1) {
if (end_of_queue_search(phead, pmlmepriv->pscanned) == true) {
if ((pmlmepriv->assoc_by_rssi == true) &&
@@ -1153,7 +1153,7 @@ int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
struct wlan_network, list);
if (pnetwork == NULL)
return _FAIL;
- pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
+ pmlmepriv->pscanned = pmlmepriv->pscanned->next;
if (pmlmepriv->assoc_by_bssid == true) {
dst_ssid = pnetwork->network.MacAddress;
src_ssid = pmlmepriv->assoc_bssid;
@@ -1212,11 +1212,11 @@ sint r8712_set_auth(struct _adapter *adapter,
struct cmd_obj *pcmd;
struct setauth_parm *psetauthparm;
- pcmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
if (pcmd == NULL)
return _FAIL;
- psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_ATOMIC);
+ psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC);
if (psetauthparm == NULL) {
kfree((unsigned char *)pcmd);
return _FAIL;
@@ -1227,7 +1227,7 @@ sint r8712_set_auth(struct _adapter *adapter,
pcmd->cmdsz = sizeof(struct setauth_parm);
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- _init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
r8712_enqueue_cmd(pcmdpriv, pcmd);
return _SUCCESS;
}
@@ -1242,10 +1242,10 @@ sint r8712_set_key(struct _adapter *adapter,
u8 keylen;
sint ret = _SUCCESS;
- pcmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
if (pcmd == NULL)
return _FAIL;
- psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_ATOMIC);
+ psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC);
if (psetkeyparm == NULL) {
ret = _FAIL;
goto err_free_cmd;
@@ -1299,7 +1299,7 @@ sint r8712_set_key(struct _adapter *adapter,
pcmd->cmdsz = (sizeof(struct setkey_parm));
pcmd->rsp = NULL;
pcmd->rspsz = 0;
- _init_listhead(&pcmd->list);
+ INIT_LIST_HEAD(&pcmd->list);
r8712_enqueue_cmd(pcmdpriv, pcmd);
return ret;
diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c
index 389062fe8eaf..aae77f0ea98f 100644
--- a/drivers/staging/rtl8712/rtl871x_mp.c
+++ b/drivers/staging/rtl8712/rtl871x_mp.c
@@ -65,8 +65,8 @@ static int init_mp_priv(struct mp_priv *pmp_priv)
((addr_t)(pmp_priv->pallocated_mp_xmitframe_buf) & 3);
pmp_xmitframe = (struct mp_xmit_frame *)pmp_priv->pmp_xmtframe_buf;
for (i = 0; i < NR_MP_XMITFRAME; i++) {
- _init_listhead(&(pmp_xmitframe->list));
- list_insert_tail(&(pmp_xmitframe->list),
+ INIT_LIST_HEAD(&(pmp_xmitframe->list));
+ list_add_tail(&(pmp_xmitframe->list),
&(pmp_priv->free_mp_xmitqueue.queue));
pmp_xmitframe->pkt = NULL;
pmp_xmitframe->frame_tag = MP_FRAMETAG;
@@ -281,10 +281,10 @@ void r8712_SetChannel(struct _adapter *pAdapter)
struct SetChannel_parm *pparm = NULL;
u16 code = GEN_CMD_CODE(_SetChannel);
- pcmd = kmalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
if (pcmd == NULL)
return;
- pparm = kmalloc(sizeof(struct SetChannel_parm), GFP_ATOMIC);
+ pparm = kmalloc(sizeof(*pparm), GFP_ATOMIC);
if (pparm == NULL) {
kfree(pcmd);
return;
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
index 9fd2ec7596cc..89ce527940fe 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -83,7 +83,7 @@ void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, uint smart_ps)
pwrpriv->bSleep = false;
pwrpriv->pwr_mode = ps_mode;
pwrpriv->smart_ps = smart_ps;
- _set_workitem(&(pwrpriv->SetPSModeWorkItem));
+ schedule_work(&pwrpriv->SetPSModeWorkItem);
}
}
@@ -133,7 +133,7 @@ static void _rpwm_check_handler (struct _adapter *padapter)
padapter->bSurpriseRemoved == true)
return;
if (pwrpriv->cpwm != pwrpriv->rpwm)
- _set_workitem(&(pwrpriv->rpwm_workitem));
+ schedule_work(&pwrpriv->rpwm_workitem);
}
static void SetPSModeWorkItemCallback(struct work_struct *work)
@@ -184,10 +184,8 @@ void r8712_init_pwrctrl_priv(struct _adapter *padapter)
pwrctrlpriv->tog = 0x80;
/* clear RPWM to ensure driver and fw back to initial state. */
r8712_write8(padapter, 0x1025FE58, 0);
- _init_workitem(&(pwrctrlpriv->SetPSModeWorkItem),
- SetPSModeWorkItemCallback, padapter);
- _init_workitem(&(pwrctrlpriv->rpwm_workitem),
- rpwm_workitem_callback, padapter);
+ INIT_WORK(&pwrctrlpriv->SetPSModeWorkItem, SetPSModeWorkItemCallback);
+ INIT_WORK(&pwrctrlpriv->rpwm_workitem, rpwm_workitem_callback);
_init_timer(&(pwrctrlpriv->rpwm_check_timer),
padapter->pnetdev, rpwm_check_handler, (u8 *)padapter);
}
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
index 70ff924fba04..0526ba077bfc 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -107,8 +107,8 @@ struct pwrctrl_priv {
uint ImrContent; /* used to store original imr. */
uint bSleep; /* sleep -> active is different from active -> sleep. */
- _workitem SetPSModeWorkItem;
- _workitem rpwm_workitem;
+ struct work_struct SetPSModeWorkItem;
+ struct work_struct rpwm_workitem;
struct timer_list rpwm_check_timer;
u8 rpwm_retry;
uint bSetPSModeWorkItemInProgress;
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index eb775872c93c..a3889d18d089 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -86,8 +86,8 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv,
(RXFRAME_ALIGN_SZ-1));
precvframe = (union recv_frame *)precvpriv->precv_frame_buf;
for (i = 0; i < NR_RECVFRAME; i++) {
- _init_listhead(&(precvframe->u.list));
- list_insert_tail(&(precvframe->u.list),
+ INIT_LIST_HEAD(&(precvframe->u.list));
+ list_add_tail(&(precvframe->u.list),
&(precvpriv->free_recv_queue.queue));
r8712_os_recv_resource_alloc(padapter, precvframe);
precvframe->u.hdr.adapter = padapter;
@@ -112,13 +112,13 @@ union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue)
struct recv_priv *precvpriv;
spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
- if (_queue_empty(pfree_recv_queue) == true)
+ if (list_empty(&pfree_recv_queue->queue))
precvframe = NULL;
else {
- phead = get_list_head(pfree_recv_queue);
- plist = get_next(phead);
+ phead = &pfree_recv_queue->queue;
+ plist = phead->next;
precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
- list_delete(&precvframe->u.hdr.list);
+ list_del_init(&precvframe->u.hdr.list);
padapter = precvframe->u.hdr.adapter;
if (padapter != NULL) {
precvpriv = &padapter->recvpriv;
@@ -145,11 +145,11 @@ void r8712_free_recvframe_queue(struct __queue *pframequeue,
struct list_head *plist, *phead;
spin_lock(&pframequeue->lock);
- phead = get_list_head(pframequeue);
- plist = get_next(phead);
+ phead = &pframequeue->queue;
+ plist = phead->next;
while (end_of_queue_search(phead, plist) == false) {
precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
- plist = get_next(plist);
+ plist = plist->next;
r8712_free_recvframe(precvframe, pfree_recv_queue);
}
spin_unlock(&pframequeue->lock);
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 6c649842abd7..e769bb5c5fb8 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -38,12 +38,12 @@ static void _init_stainfo(struct sta_info *psta)
{
memset((u8 *)psta, 0, sizeof(struct sta_info));
spin_lock_init(&psta->lock);
- _init_listhead(&psta->list);
- _init_listhead(&psta->hash_list);
+ INIT_LIST_HEAD(&psta->list);
+ INIT_LIST_HEAD(&psta->hash_list);
_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
_r8712_init_sta_recv_priv(&psta->sta_recvpriv);
- _init_listhead(&psta->asoc_list);
- _init_listhead(&psta->auth_list);
+ INIT_LIST_HEAD(&psta->asoc_list);
+ INIT_LIST_HEAD(&psta->auth_list);
}
u32 _r8712_init_sta_priv(struct sta_priv *pstapriv)
@@ -65,13 +65,12 @@ u32 _r8712_init_sta_priv(struct sta_priv *pstapriv)
psta = (struct sta_info *)(pstapriv->pstainfo_buf);
for (i = 0; i < NUM_STA; i++) {
_init_stainfo(psta);
- _init_listhead(&(pstapriv->sta_hash[i]));
- list_insert_tail(&psta->list,
- get_list_head(&pstapriv->free_sta_queue));
+ INIT_LIST_HEAD(&(pstapriv->sta_hash[i]));
+ list_add_tail(&psta->list, &pstapriv->free_sta_queue.queue);
psta++;
}
- _init_listhead(&pstapriv->asoc_list);
- _init_listhead(&pstapriv->auth_list);
+ INIT_LIST_HEAD(&pstapriv->asoc_list);
+ INIT_LIST_HEAD(&pstapriv->auth_list);
return _SUCCESS;
}
@@ -83,11 +82,11 @@ static void mfree_all_stainfo(struct sta_priv *pstapriv)
struct sta_info *psta = NULL;
spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
- phead = get_list_head(&pstapriv->free_sta_queue);
- plist = get_next(phead);
+ phead = &pstapriv->free_sta_queue.queue;
+ plist = phead->next;
while ((end_of_queue_search(phead, plist)) == false) {
psta = LIST_CONTAINOR(plist, struct sta_info, list);
- plist = get_next(plist);
+ plist = plist->next;
}
spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
@@ -122,12 +121,12 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
pfree_sta_queue = &pstapriv->free_sta_queue;
spin_lock_irqsave(&(pfree_sta_queue->lock), flags);
- if (_queue_empty(pfree_sta_queue) == true)
+ if (list_empty(&pfree_sta_queue->queue))
psta = NULL;
else {
- psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue),
+ psta = LIST_CONTAINOR(pfree_sta_queue->queue.next,
struct sta_info, list);
- list_delete(&(psta->list));
+ list_del_init(&(psta->list));
tmp_aid = psta->aid;
_init_stainfo(psta);
memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
@@ -137,7 +136,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
goto exit;
}
phash_list = &(pstapriv->sta_hash[index]);
- list_insert_tail(&psta->hash_list, phash_list);
+ list_add_tail(&psta->hash_list, phash_list);
pstapriv->asoc_sta_count++;
/* For the SMC router, the sequence number of first packet of WPS handshake
@@ -181,21 +180,21 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta)
pstaxmitpriv = &psta->sta_xmitpriv;
spin_lock_irqsave(&(pxmitpriv->vo_pending.lock), irqL0);
r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
- list_delete(&(pstaxmitpriv->vo_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vo_q.tx_pending));
spin_unlock_irqrestore(&(pxmitpriv->vo_pending.lock), irqL0);
spin_lock_irqsave(&(pxmitpriv->vi_pending.lock), irqL0);
r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
- list_delete(&(pstaxmitpriv->vi_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->vi_q.tx_pending));
spin_unlock_irqrestore(&(pxmitpriv->vi_pending.lock), irqL0);
spin_lock_irqsave(&(pxmitpriv->bk_pending.lock), irqL0);
r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
- list_delete(&(pstaxmitpriv->bk_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->bk_q.tx_pending));
spin_unlock_irqrestore(&(pxmitpriv->bk_pending.lock), irqL0);
spin_lock_irqsave(&(pxmitpriv->be_pending.lock), irqL0);
r8712_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
- list_delete(&(pstaxmitpriv->be_q.tx_pending));
+ list_del_init(&(pstaxmitpriv->be_q.tx_pending));
spin_unlock_irqrestore(&(pxmitpriv->be_pending.lock), irqL0);
- list_delete(&psta->hash_list);
+ list_del_init(&psta->hash_list);
pstapriv->asoc_sta_count--;
/* re-init sta_info; 20061114 */
_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
@@ -208,7 +207,7 @@ void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta)
}
spin_lock(&(pfree_sta_queue->lock));
/* insert into free_sta_queue; 20061114 */
- list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
+ list_add_tail(&psta->list, &pfree_sta_queue->queue);
spin_unlock(&(pfree_sta_queue->lock));
}
@@ -227,11 +226,11 @@ void r8712_free_all_stainfo(struct _adapter *padapter)
spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
for (index = 0; index < NUM_STA; index++) {
phead = &(pstapriv->sta_hash[index]);
- plist = get_next(phead);
+ plist = phead->next;
while ((end_of_queue_search(phead, plist)) == false) {
psta = LIST_CONTAINOR(plist,
struct sta_info, hash_list);
- plist = get_next(plist);
+ plist = plist->next;
if (pbcmc_stainfo != psta)
r8712_free_stainfo(padapter , psta);
}
@@ -252,7 +251,7 @@ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
index = wifi_mac_hash(hwaddr);
spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
phead = &(pstapriv->sta_hash[index]);
- plist = get_next(phead);
+ plist = phead->next;
while ((end_of_queue_search(phead, plist)) == false) {
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
if ((!memcmp(psta->hwaddr, hwaddr, ETH_ALEN))) {
@@ -260,7 +259,7 @@ struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
break;
}
psta = NULL;
- plist = get_next(plist);
+ plist = plist->next;
}
spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
return psta;
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 230681a8042f..b985edc158b9 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -43,7 +43,7 @@ static void free_hwxmits(struct _adapter *padapter);
static void _init_txservq(struct tx_servq *ptxservq)
{
- _init_listhead(&ptxservq->tx_pending);
+ INIT_LIST_HEAD(&ptxservq->tx_pending);
_init_queue(&ptxservq->sta_pending);
ptxservq->qcnt = 0;
}
@@ -57,8 +57,8 @@ void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
_init_txservq(&psta_xmitpriv->bk_q);
_init_txservq(&psta_xmitpriv->vi_q);
_init_txservq(&psta_xmitpriv->vo_q);
- _init_listhead(&psta_xmitpriv->legacy_dz);
- _init_listhead(&psta_xmitpriv->apsd);
+ INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
+ INIT_LIST_HEAD(&psta_xmitpriv->apsd);
}
sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
@@ -97,13 +97,13 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
for (i = 0; i < NR_XMITFRAME; i++) {
- _init_listhead(&(pxframe->list));
+ INIT_LIST_HEAD(&(pxframe->list));
pxframe->padapter = padapter;
pxframe->frame_tag = DATA_FRAMETAG;
pxframe->pkt = NULL;
pxframe->buf_addr = NULL;
pxframe->pxmitbuf = NULL;
- list_insert_tail(&(pxframe->list),
+ list_add_tail(&(pxframe->list),
&(pxmitpriv->free_xmit_queue.queue));
pxframe++;
}
@@ -134,7 +134,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
for (i = 0; i < NR_XMITBUFF; i++) {
- _init_listhead(&pxmitbuf->list);
+ INIT_LIST_HEAD(&pxmitbuf->list);
pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ,
GFP_ATOMIC);
if (pxmitbuf->pallocated_buf == NULL)
@@ -143,12 +143,12 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
((addr_t) (pxmitbuf->pallocated_buf) &
(XMITBUF_ALIGN_SZ - 1));
r8712_xmit_resource_alloc(padapter, pxmitbuf);
- list_insert_tail(&pxmitbuf->list,
+ list_add_tail(&pxmitbuf->list,
&(pxmitpriv->free_xmitbuf_queue.queue));
pxmitbuf++;
}
pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
- _init_workitem(&padapter->wkFilterRxFF0, r8712_SetFilter, padapter);
+ INIT_WORK(&padapter->wkFilterRxFF0, r8712_SetFilter);
alloc_hwxmits(padapter);
init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
tasklet_init(&pxmitpriv->xmit_tasklet,
@@ -744,13 +744,13 @@ struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
- if (_queue_empty(pfree_xmitbuf_queue) == true)
+ if (list_empty(&pfree_xmitbuf_queue->queue))
pxmitbuf = NULL;
else {
- phead = get_list_head(pfree_xmitbuf_queue);
- plist = get_next(phead);
+ phead = &pfree_xmitbuf_queue->queue;
+ plist = phead->next;
pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
- list_delete(&(pxmitbuf->list));
+ list_del_init(&(pxmitbuf->list));
}
if (pxmitbuf != NULL)
pxmitpriv->free_xmitbuf_cnt--;
@@ -766,8 +766,8 @@ int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
if (pxmitbuf == NULL)
return _FAIL;
spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
- list_delete(&pxmitbuf->list);
- list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
+ list_del_init(&pxmitbuf->list);
+ list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
pxmitpriv->free_xmitbuf_cnt++;
spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
return _SUCCESS;
@@ -798,13 +798,13 @@ struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
- if (_queue_empty(pfree_xmit_queue) == true)
+ if (list_empty(&pfree_xmit_queue->queue))
pxframe = NULL;
else {
- phead = get_list_head(pfree_xmit_queue);
- plist = get_next(phead);
+ phead = &pfree_xmit_queue->queue;
+ plist = phead->next;
pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
- list_delete(&(pxframe->list));
+ list_del_init(&(pxframe->list));
}
if (pxframe != NULL) {
pxmitpriv->free_xmitframe_cnt--;
@@ -828,12 +828,12 @@ void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
if (pxmitframe == NULL)
return;
spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
- list_delete(&pxmitframe->list);
+ list_del_init(&pxmitframe->list);
if (pxmitframe->pkt) {
pndis_pkt = pxmitframe->pkt;
pxmitframe->pkt = NULL;
}
- list_insert_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
+ list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
pxmitpriv->free_xmitframe_cnt++;
spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
if (netif_queue_stopped(padapter->pnetdev))
@@ -857,11 +857,11 @@ void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
struct xmit_frame *pxmitframe;
spin_lock_irqsave(&(pframequeue->lock), irqL);
- phead = get_list_head(pframequeue);
- plist = get_next(phead);
+ phead = &pframequeue->queue;
+ plist = phead->next;
while (end_of_queue_search(phead, plist) == false) {
pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
- plist = get_next(plist);
+ plist = plist->next;
r8712_free_xmitframe(pxmitpriv, pxmitframe);
}
spin_unlock_irqrestore(&(pframequeue->lock), irqL);
@@ -939,11 +939,9 @@ sint r8712_xmit_classifier(struct _adapter *padapter,
ptxservq = get_sta_pending(padapter, &pstapending,
psta, pattrib->priority);
spin_lock_irqsave(&pstapending->lock, irqL0);
- if (is_list_empty(&ptxservq->tx_pending))
- list_insert_tail(&ptxservq->tx_pending,
- get_list_head(pstapending));
- list_insert_tail(&pxmitframe->list,
- get_list_head(&ptxservq->sta_pending));
+ if (list_empty(&ptxservq->tx_pending))
+ list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
+ list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
ptxservq->qcnt++;
spin_unlock_irqrestore(&pstapending->lock, irqL0);
return _SUCCESS;
@@ -1005,7 +1003,7 @@ static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
for (i = 0; i < entry; i++, phwxmit++) {
spin_lock_init(&phwxmit->xmit_lock);
- _init_listhead(&phwxmit->pending);
+ INIT_LIST_HEAD(&phwxmit->pending);
phwxmit->txcmdcnt = 0;
phwxmit->accnt = 0;
}
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h
index ee906987735a..a9633c3f73d0 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.h
+++ b/drivers/staging/rtl8712/rtl871x_xmit.h
@@ -233,9 +233,9 @@ struct xmit_priv {
u8 hwxmit_entry;
u8 txirp_cnt;
struct tasklet_struct xmit_tasklet;
- _workitem xmit_pipe4_reset_wi;
- _workitem xmit_pipe6_reset_wi;
- _workitem xmit_piped_reset_wi;
+ struct work_struct xmit_pipe4_reset_wi;
+ struct work_struct xmit_pipe6_reset_wi;
+ struct work_struct xmit_piped_reset_wi;
/*per AC pending irp*/
int beq_cnt;
int bkq_cnt;
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index ba743542babc..beff69b3ff0c 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -607,31 +607,29 @@ error:
static void r871xu_dev_remove(struct usb_interface *pusb_intf)
{
struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
- struct _adapter *padapter = netdev_priv(pnetdev);
struct usb_device *udev = interface_to_usbdev(pusb_intf);
- usb_set_intfdata(pusb_intf, NULL);
- if (padapter->fw_found)
+ if (pnetdev) {
+ struct _adapter *padapter = netdev_priv(pnetdev);
+
+ usb_set_intfdata(pusb_intf, NULL);
release_firmware(padapter->fw);
- /* never exit with a firmware callback pending */
- wait_for_completion(&padapter->rtl8712_fw_ready);
- if (drvpriv.drv_registered == true)
- padapter->bSurpriseRemoved = true;
- if (pnetdev != NULL) {
- /* will call netdev_close() */
- unregister_netdev(pnetdev);
- }
- flush_scheduled_work();
- udelay(1);
- /*Stop driver mlme relation timer */
- if (padapter->fw_found)
+ /* never exit with a firmware callback pending */
+ wait_for_completion(&padapter->rtl8712_fw_ready);
+ if (drvpriv.drv_registered == true)
+ padapter->bSurpriseRemoved = true;
+ unregister_netdev(pnetdev); /* will call netdev_close() */
+ flush_scheduled_work();
+ udelay(1);
+ /* Stop driver mlme relation timer */
r8712_stop_drv_timers(padapter);
- r871x_dev_unload(padapter);
- r8712_free_drv_sw(padapter);
- usb_set_intfdata(pusb_intf, NULL);
- /* decrease the reference count of the usb device structure
- * when disconnect */
- usb_put_dev(udev);
+ r871x_dev_unload(padapter);
+ r8712_free_drv_sw(padapter);
+
+ /* decrease the reference count of the usb device structure
+ * when disconnect */
+ usb_put_dev(udev);
+ }
/* If we didn't unplug usb dongle and remove/insert module, driver
* fails on sitesurvey for the first time when device is up.
* Reset usb port for sitesurvey fail issue. */
diff --git a/drivers/staging/rtl8723au/Makefile b/drivers/staging/rtl8723au/Makefile
index a6316af94b79..a9aae2163639 100644
--- a/drivers/staging/rtl8723au/Makefile
+++ b/drivers/staging/rtl8723au/Makefile
@@ -1,7 +1,6 @@
r8723au-y := \
core/rtw_cmd.o \
core/rtw_efuse.o \
- core/rtw_ioctl_set.o \
core/rtw_ieee80211.o \
core/rtw_led.o \
core/rtw_mlme.o \
@@ -53,4 +52,5 @@ r8723au-$(CONFIG_8723AU_AP_MODE) += core/rtw_ap.o
obj-$(CONFIG_R8723AU) := r8723au.o
-ccflags-y += -Wtype-limits -D__CHECK_ENDIAN__ -I$(src)/include
+ccflags-y += $(call cc-option,-Wtype-limits,)
+ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/include
diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c
index c8700b38386d..4d2880abf4ee 100644
--- a/drivers/staging/rtl8723au/core/rtw_ap.c
+++ b/drivers/staging/rtl8723au/core/rtw_ap.c
@@ -24,7 +24,6 @@
extern unsigned char WMM_OUI23A[];
extern unsigned char WPS_OUI23A[];
extern unsigned char P2P_OUI23A[];
-extern unsigned char WFD_OUI23A[];
void init_mlme_ap_info23a(struct rtw_adapter *padapter)
{
@@ -53,7 +52,7 @@ void free_mlme_ap_info23a(struct rtw_adapter *padapter)
rtw_sta_flush23a(padapter);
- pmlmeinfo->state = _HW_STATE_NOLINK_;
+ pmlmeinfo->state = MSR_NOLINK;
/* free_assoc_sta_resources */
rtw_free_all_stainfo23a(padapter);
@@ -78,8 +77,8 @@ static void update_BCNTIM(struct rtw_adapter *padapter)
tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
- p = rtw_get_ie23a(pie + _FIXED_IE_LENGTH_, WLAN_EID_TIM, &tim_ielen,
- pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
+ p = rtw_get_ie23a(pie, WLAN_EID_TIM, &tim_ielen,
+ pnetwork_mlmeext->IELength);
if (p != NULL && tim_ielen>0) {
tim_ielen += 2;
@@ -94,20 +93,18 @@ static void update_BCNTIM(struct rtw_adapter *padapter)
} else {
tim_ielen = 0;
- /* calulate head_len */
- offset = _FIXED_IE_LENGTH_;
+ /* calculate head_len */
+ offset = 0;
/* get ssid_ie len */
- p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, WLAN_EID_SSID,
- &tmp_len, (pnetwork_mlmeext->IELength -
- _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(pie, WLAN_EID_SSID,
+ &tmp_len, pnetwork_mlmeext->IELength);
if (p != NULL)
offset += tmp_len+2;
/* get supported rates len */
- p = rtw_get_ie23a(pie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES,
- &tmp_len, (pnetwork_mlmeext->IELength -
- _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(pie, WLAN_EID_SUPP_RATES,
+ &tmp_len, pnetwork_mlmeext->IELength);
if (p != NULL)
offset += tmp_len+2;
@@ -138,7 +135,7 @@ static void update_BCNTIM(struct rtw_adapter *padapter)
*dst_ie++= tim_ielen;
*dst_ie++= 0;/* DTIM count */
- *dst_ie++= 1;/* DTIM peroid */
+ *dst_ie++= 1;/* DTIM period */
if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
*dst_ie++ = BIT(0);/* bitmap ctrl */
@@ -246,7 +243,7 @@ void expire_timeout_chk23a(struct rtw_adapter *padapter)
if (psta->state & WIFI_SLEEP_STATE) {
if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
- /* to check if alive by another methods if staion is at ps mode. */
+ /* to check if alive by another methods if station is at ps mode. */
psta->expire_to = pstapriv->expire_to;
psta->state |= WIFI_STA_ALIVE_CHK_STATE;
@@ -623,15 +620,18 @@ static void update_hw_ht_param(struct rtw_adapter *padapter)
AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
AMPDU_para [4:2]:Min MPDU Start Spacing
*/
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
+ max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
- min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
+ min_MPDU_spacing = (pmlmeinfo->ht_cap.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
/* Config SM Power Save setting */
- pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
+ pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
+ IEEE80211_HT_CAP_SM_PS) >> 2;
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
}
@@ -649,10 +649,9 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
- struct HT_info_element *pht_info = NULL;
- int bcn_fixed_size;
+ struct ieee80211_ht_operation *pht_info = NULL;
- bcn_interval = (u16)pnetwork->BeaconPeriod;
+ bcn_interval = (u16)pnetwork->beacon_interval;
cur_channel = pnetwork->DSConfig;
cur_bwmode = HT_CHANNEL_WIDTH_20;;
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
@@ -660,7 +659,10 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
/* check if there is wps ie, */
/* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
/* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
- if (NULL == rtw_get_wps_ie23a(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
+ if (NULL == cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ pnetwork->IEs,
+ pnetwork->IELength))
pmlmeext->bstart_bss = true;
/* todo: update wmm, ht cap */
@@ -686,7 +688,7 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
}
/* set MSR to AP_Mode */
- Set_MSR23a(padapter, _HW_STATE_AP_);
+ rtl8723a_set_media_status(padapter, MSR_AP);
/* Set BSSID REG */
hw_var_set_bssid(padapter, pnetwork->MacAddress);
@@ -722,25 +724,24 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
DYNAMIC_ALL_FUNC_ENABLE);
}
/* set channel, bwmode */
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- pnetwork->IEs + bcn_fixed_size,
- pnetwork->IELength - bcn_fixed_size);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pnetwork->IEs,
+ pnetwork->IELength);
if (p && p[1]) {
- pht_info = (struct HT_info_element *)(p + 2);
+ pht_info = (struct ieee80211_ht_operation *)(p + 2);
- if (pregpriv->cbw40_enable && pht_info->infos[0] & BIT(2)) {
+ if (pregpriv->cbw40_enable && pht_info->ht_param &
+ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
/* switch to the 40M Hz mode */
cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pht_info->infos[0] & 0x3) {
- case 1:
+ switch (pht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
/* pmlmeext->cur_ch_offset =
HAL_PRIME_CHNL_OFFSET_LOWER; */
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
break;
- case 3:
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
break;
default:
@@ -763,8 +764,8 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
/* update cur_wireless_mode */
update_wireless_mode23a(padapter);
- /* udpate capability after cur_wireless_mode updated */
- update_capinfo23a(padapter, rtw_get_capability23a(pnetwork));
+ /* update capability after cur_wireless_mode updated */
+ update_capinfo23a(padapter, pnetwork->capability);
/* let pnetwork_mlmeext == pnetwork_mlme. */
memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
@@ -781,16 +782,15 @@ static void start_bss_network(struct rtw_adapter *padapter, u8 *pbuf)
update_bmc_sta(padapter);
}
-int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
- unsigned int len)
+int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
+ struct ieee80211_mgmt *mgmt, unsigned int len)
{
int ret = _SUCCESS;
u8 *p;
u8 *pHT_caps_ie = NULL;
u8 *pHT_info_ie = NULL;
struct sta_info *psta = NULL;
- __le16 *pbeacon;
- u16 cap, ht_cap = false;
+ u16 ht_cap = false;
uint ie_len = 0;
int group_cipher, pairwise_cipher;
u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
@@ -801,7 +801,8 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *pbss_network = &pmlmepriv->cur_network.network;
u8 *ie = pbss_network->IEs;
-
+ u8 *pbuf = mgmt->u.beacon.variable;
+ len -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
/* SSID */
/* Supported rates */
/* DS Params */
@@ -835,27 +836,18 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
memcpy(pbss_network->MacAddress, myid(&padapter->eeprompriv), ETH_ALEN);
- /* beacon interval */
- /* ie + 8; 8: TimeStamp, 2: Beacon Interval 2:Capability */
- pbeacon = rtw_get_beacon_interval23a_from_ie(ie);
- pbss_network->BeaconPeriod = get_unaligned_le16(pbeacon);
-
- /* capability */
- cap = get_unaligned_le16(ie);
-
/* SSID */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_SSID, &ie_len,
- (pbss_network->IELength -_BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_SSID, &ie_len, pbss_network->IELength);
if (p && ie_len > 0) {
memset(&pbss_network->Ssid, 0, sizeof(struct cfg80211_ssid));
memcpy(pbss_network->Ssid.ssid, (p + 2), ie_len);
pbss_network->Ssid.ssid_len = ie_len;
}
- /* chnnel */
+ /* channel */
channel = 0;
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_DS_PARAMS, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_DS_PARAMS, &ie_len,
+ pbss_network->IELength);
if (p && ie_len > 0)
channel = *(p + 2);
@@ -863,16 +855,16 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
/* get supported rates */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_SUPP_RATES, &ie_len,
+ pbss_network->IELength);
if (p) {
memcpy(supportRate, p+2, ie_len);
supportRateNum = ie_len;
}
/* get ext_supported rates */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES,
- &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
+ p = rtw_get_ie23a(ie, WLAN_EID_EXT_SUPP_RATES,
+ &ie_len, pbss_network->IELength);
if (p) {
memcpy(supportRate+supportRateNum, p+2, ie_len);
supportRateNum += ie_len;
@@ -884,13 +876,13 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
rtw_set_supported_rate23a(pbss_network->SupportedRates, network_type);
/* parsing ERP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &ie_len,
+ pbss_network->IELength);
if (p && ie_len > 0)
ERP_IE_handler23a(padapter, p);
/* update privacy/security */
- if (cap & BIT(4))
+ if (pbss_network->capability & BIT(4))
pbss_network->Privacy = 1;
else
pbss_network->Privacy = 0;
@@ -901,8 +893,8 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
group_cipher = 0; pairwise_cipher = 0;
psecuritypriv->wpa2_group_cipher = 0;
psecuritypriv->wpa2_pairwise_cipher = 0;
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_RSN, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_RSN, &ie_len,
+ pbss_network->IELength);
if (p && ie_len > 0) {
if (rtw_parse_wpa2_ie23a(p, ie_len+2, &group_cipher,
&pairwise_cipher, NULL) == _SUCCESS) {
@@ -922,10 +914,9 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
pairwise_cipher = 0;
psecuritypriv->wpa_group_cipher = 0;
psecuritypriv->wpa_pairwise_cipher = 0;
- for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) {
+ for (p = ie; ;p += (ie_len + 2)) {
p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_ -
- (ie_len + 2)));
+ pbss_network->IELength - (ie_len + 2));
if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) {
if (rtw_parse_wpa_ie23a(p, ie_len+2, &group_cipher,
&pairwise_cipher, NULL) == _SUCCESS) {
@@ -950,10 +941,10 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
ie_len = 0;
pmlmepriv->qos_option = 0;
if (pregistrypriv->wmm_enable) {
- for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2)) {
+ for (p = ie; ;p += (ie_len + 2)) {
p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
(pbss_network->IELength -
- _BEACON_IE_OFFSET_ - (ie_len + 2)));
+ (ie_len + 2)));
if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
pmlmepriv->qos_option = 1;
@@ -973,8 +964,8 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
}
}
/* parsing HT_CAP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_CAPABILITY, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_HT_CAPABILITY, &ie_len,
+ pbss_network->IELength);
if (p && ie_len > 0) {
u8 rf_type;
@@ -1005,8 +996,8 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf,
}
/* parsing HT_INFO_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_OPERATION, &ie_len,
- (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_HT_OPERATION, &ie_len,
+ pbss_network->IELength);
if (p && ie_len > 0)
pHT_info_ie = p;
@@ -1179,7 +1170,7 @@ static void update_bcn_erpinfo_ie(struct rtw_adapter *padapter)
return;
/* parsing ERP_IE */
- p = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, WLAN_EID_ERP_INFO, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
+ p = rtw_get_ie23a(ie, WLAN_EID_ERP_INFO, &len, pnetwork->IELength);
if (p && len > 0) {
if (pmlmepriv->num_sta_non_erp == 1)
p[2] |= WLAN_ERP_NON_ERP_PRESENT |
@@ -1224,54 +1215,9 @@ static void update_bcn_wmm_ie(struct rtw_adapter *padapter)
static void update_bcn_wps_ie(struct rtw_adapter *padapter)
{
- u8 *pwps_ie = NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie = NULL;
- uint wps_ielen = 0, wps_offset, remainder_ielen;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
- unsigned char *ie = pnetwork->IEs;
- u32 ielen = pnetwork->IELength;
-
DBG_8723A("%s\n", __func__);
- pwps_ie_src = pmlmepriv->wps_beacon_ie;
- if (pwps_ie_src == NULL)
- return;
-
- pwps_ie = rtw_get_wps_ie23a(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
-
- if (pwps_ie == NULL || wps_ielen == 0)
- return;
-
- wps_offset = (uint)(pwps_ie-ie);
-
- premainder_ie = pwps_ie + wps_ielen;
-
- remainder_ielen = ielen - wps_offset - wps_ielen;
-
- if (remainder_ielen > 0) {
- pbackup_remainder_ie = kmalloc(remainder_ielen, GFP_ATOMIC);
- if (pbackup_remainder_ie)
- memcpy(pbackup_remainder_ie, premainder_ie,
- remainder_ielen);
- }
-
- wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
- if ((wps_offset+wps_ielen+2+remainder_ielen)<= MAX_IE_SZ)
- {
- memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
- pwps_ie += (wps_ielen+2);
-
- if (pbackup_remainder_ie)
- memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
-
- /* update IELength */
- pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
- }
-
- if (pbackup_remainder_ie)
- kfree(pbackup_remainder_ie);
+ return;
}
static void update_bcn_p2p_ie(struct rtw_adapter *padapter)
@@ -1359,7 +1305,7 @@ void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
/*
op_mode
-Set to 0 (HT pure) under the followign conditions
+Set to 0 (HT pure) under the following conditions
- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
Set to 1 (HT non-member protection) if there may be non-HT STAs
@@ -1376,7 +1322,7 @@ static int rtw_ht_operation_update(struct rtw_adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
- if (pmlmepriv->htpriv.ht_option == true)
+ if (pmlmepriv->htpriv.ht_option)
return 0;
/* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
@@ -1441,7 +1387,7 @@ static int rtw_ht_operation_update(struct rtw_adapter *padapter)
void associated_clients_update23a(struct rtw_adapter *padapter, u8 updated)
{
- /* update associcated stations cap. */
+ /* update associated stations cap. */
if (updated == true)
{
struct list_head *phead, *plist, *ptmp;
@@ -1612,7 +1558,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info
psta->no_ht_set = 1;
pmlmepriv->num_sta_no_ht++;
}
- if (pmlmepriv->htpriv.ht_option == true) {
+ if (pmlmepriv->htpriv.ht_option) {
DBG_8723A("%s STA " MAC_FMT
" - no HT, num of non-HT stations %d\n",
__func__, MAC_ARG(psta->hwaddr),
@@ -1626,7 +1572,7 @@ void bss_cap_update_on_sta_join23a(struct rtw_adapter *padapter, struct sta_info
update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
}
- /* update associcated stations cap. */
+ /* update associated stations cap. */
associated_clients_update23a(padapter, beacon_updated);
DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
@@ -1695,7 +1641,7 @@ u8 bss_cap_update_on_sta_leave23a(struct rtw_adapter *padapter, struct sta_info
update_beacon23a(padapter, WLAN_EID_HT_OPERATION, NULL, true);
}
- /* update associcated stations cap. */
+ /* update associated stations cap. */
DBG_8723A("%s, updated =%d\n", __func__, beacon_updated);
@@ -1757,7 +1703,7 @@ int rtw_ap_inform_ch_switch23a (struct rtw_adapter *padapter, u8 new_ch, u8 ch_o
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) != MSR_AP)
return ret;
DBG_8723A("%s(%s): with ch:%u, offset:%u\n", __func__,
@@ -1794,7 +1740,7 @@ int rtw_sta_flush23a(struct rtw_adapter *padapter)
DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) != MSR_AP)
return ret;
spin_lock_bh(&pstapriv->asoc_list_lock);
@@ -1850,7 +1796,7 @@ void sta_info_update23a(struct rtw_adapter *padapter, struct sta_info *psta)
psta->htpriv.ht_option = false;
}
- if (pmlmepriv->htpriv.ht_option == false)
+ if (!pmlmepriv->htpriv.ht_option)
psta->htpriv.ht_option = false;
update_sta_info23a_apmode23a(padapter, psta);
@@ -1957,13 +1903,6 @@ void start_ap_mode23a(struct rtw_adapter *padapter)
for (i = 0; i<NUM_STA; i++)
pstapriv->sta_aid[i] = NULL;
- pmlmepriv->wps_beacon_ie = NULL;
- pmlmepriv->wps_probe_resp_ie = NULL;
- pmlmepriv->wps_assoc_resp_ie = NULL;
-
- pmlmepriv->p2p_beacon_ie = NULL;
- pmlmepriv->p2p_probe_resp_ie = NULL;
-
/* for ACL */
INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
pacl_list->num = 0;
diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c
index 1696cb8b17cb..7241a5a8731c 100644
--- a/drivers/staging/rtl8723au/core/rtw_cmd.c
+++ b/drivers/staging/rtl8723au/core/rtw_cmd.c
@@ -203,22 +203,9 @@ void rtw_free_evt_priv23a(struct evt_priv *pevtpriv)
static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
{
- struct drvextra_cmd_parm *pdrvextra_cmd_parm;
/* set to true to allow enqueuing cmd when hw_init_completed is false */
u8 bAllow = false;
- /* To decide allow or not */
- if (pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect &&
- !pcmdpriv->padapter->registrypriv.usbss_enable) {
- if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) {
- pdrvextra_cmd_parm =
- (struct drvextra_cmd_parm *)cmd_obj->parmbuf;
- if (pdrvextra_cmd_parm->ec_id ==
- POWER_SAVING_CTRL_WK_CID)
- bAllow = true;
- }
- }
-
if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
bAllow = true;
@@ -322,7 +309,7 @@ post_process:
pcmd_callback, pcmd->cmdcode));
rtw_free_cmd_obj23a(pcmd);
} else {
- /* need conider that free cmd_obj in
+ /* need consider that free cmd_obj in
rtw_cmd_callback */
pcmd_callback(pcmd->padapter, pcmd);
}
@@ -464,7 +451,6 @@ exit:
int rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
struct wlan_network *pnetwork)
{
- u8 *auth;
int res = _SUCCESS;
struct wlan_bssid_ex *psecnetwork;
struct cmd_obj *pcmd;
@@ -516,9 +502,7 @@ int rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
psecnetwork = &psecuritypriv->sec_bss;
if (!psecnetwork) {
- if (pcmd)
- kfree(pcmd);
-
+ kfree(pcmd);
res = _FAIL;
RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_,
@@ -532,18 +516,6 @@ int rtw_joinbss_cmd23a(struct rtw_adapter *padapter,
memcpy(psecnetwork, &pnetwork->network,
get_wlan_bssid_ex_sz(&pnetwork->network));
- auth = &psecuritypriv->authenticator_ie[0];
- psecuritypriv->authenticator_ie[0] =
- (unsigned char)psecnetwork->IELength;
-
- if ((psecnetwork->IELength-12) < (256-1)) {
- memcpy(&psecuritypriv->authenticator_ie[1],
- &psecnetwork->IEs[12], psecnetwork->IELength - 12);
- } else {
- memcpy(&psecuritypriv->authenticator_ie[1],
- &psecnetwork->IEs[12], 256 - 1);
- }
-
psecnetwork->IELength = 0;
/* Added by Albert 2009/02/18 */
/* If the the driver wants to use the bssid to create the
@@ -751,7 +723,7 @@ int rtw_setstakey_cmd23a(struct rtw_adapter *padapter, u8 *psta, u8 unicast_key)
&psecuritypriv->dot118021XGrpKey[idx].skey, 16);
}
- /* jeff: set this becasue at least sw key is ready */
+ /* jeff: set this because at least sw key is ready */
padapter->securitypriv.busetkipkey = 1;
res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
@@ -1126,11 +1098,6 @@ exit:
return res;
}
-static void power_saving_wk_hdl(struct rtw_adapter *padapter, u8 *pbuf, int sz)
-{
- rtw_ps_processor23a(padapter);
-}
-
int rtw_ps_cmd23a(struct rtw_adapter*padapter)
{
struct cmd_obj *ppscmd;
@@ -1345,8 +1312,7 @@ int rtw_drvextra_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
pdrvextra_cmd->type_size);
break;
case POWER_SAVING_CTRL_WK_CID:
- power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf,
- pdrvextra_cmd->type_size);
+ rtw_ps_processor23a(padapter);
break;
case LPS_CTRL_WK_CID:
lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c
index cc063cbc49bb..fe092c5defa6 100644
--- a/drivers/staging/rtl8723au/core/rtw_efuse.c
+++ b/drivers/staging/rtl8723au/core/rtw_efuse.c
@@ -59,7 +59,7 @@ static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
/* 1.2V Power: From VDDON with Power
- Cut(0x0000h[15]), defualt valid */
+ Cut(0x0000h[15]), default valid */
tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL);
if (!(tmpV16 & PWC_EV12V)) {
tmpV16 |= PWC_EV12V;
@@ -100,22 +100,6 @@ static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
}
}
-/*-----------------------------------------------------------------------------
- * Function: efuse_GetCurrentSize23a
- *
- * Overview: Get current efuse size!!!
- *
- * Input: NONE
- *
- * Output: NONE
- *
- * Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 11/16/2008 MHC Create Version 0.
- *
- *---------------------------------------------------------------------------*/
u16
Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
{
@@ -144,7 +128,7 @@ Efuse_CalculateWordCnts23a(u8 word_en)
/* */
/* Description: */
/* Execute E-Fuse read byte operation. */
-/* Refered from SD1 Richard. */
+/* Referred from SD1 Richard. */
/* */
/* Assumption: */
/* 1. Boot from E-Fuse and successfully auto-load. */
@@ -521,7 +505,7 @@ static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
}
/*
- * read/wirte raw efuse data
+ * read/write raw efuse data
*/
int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
u16 cnts, u8 *data)
@@ -576,15 +560,6 @@ u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
return max_size;
}
/* */
-int efuse_GetCurrentSize23a(struct rtw_adapter *padapter, u16 *size)
-{
- Efuse_PowerSwitch(padapter, false, true);
- *size = Efuse_GetCurrentSize23a(padapter, EFUSE_WIFI);
- Efuse_PowerSwitch(padapter, false, false);
-
- return _SUCCESS;
-}
-/* */
int rtw_efuse_map_read23a(struct rtw_adapter *padapter,
u16 addr, u16 cnts, u8 *data)
{
diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
index adb86a54bdb2..23e666244f4e 100644
--- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
@@ -33,7 +33,6 @@ u8 WPA_CIPHER_SUITE_WRAP23A[] = { 0x00, 0x50, 0xf2, 3 };
u8 WPA_CIPHER_SUITE_CCMP23A[] = { 0x00, 0x50, 0xf2, 4 };
u8 WPA_CIPHER_SUITE_WEP10423A[] = { 0x00, 0x50, 0xf2, 5 };
-u16 RSN_VERSION_BSD23A = 1;
u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X23A[] = { 0x00, 0x0f, 0xac, 1 };
u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[] = { 0x00, 0x0f, 0xac, 2 };
u8 RSN_CIPHER_SUITE_NONE23A[] = { 0x00, 0x0f, 0xac, 0 };
@@ -124,14 +123,6 @@ int rtw_check_network_type23a(unsigned char *rate, int ratelen, int channel)
}
}
-u8 *rtw_set_fixed_ie23a(unsigned char *pbuf, unsigned int len,
- unsigned char *source, unsigned int *frlen)
-{
- memcpy((void *)pbuf, (void *)source, len);
- *frlen = *frlen + len;
- return pbuf + len;
-}
-
/* rtw_set_ie23a will update frame length */
u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen)
{
@@ -161,14 +152,12 @@ inline u8 *rtw_set_ie23a_ch_switch (u8 *buf, u32 *buf_len, u8 ch_switch_mode,
inline u8 hal_ch_offset_to_secondary_ch_offset23a(u8 ch_offset)
{
- if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
- return SCN;
- else if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
- return SCB;
+ if (ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
+ return IEEE80211_HT_PARAM_CHA_SEC_BELOW;
else if (ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
- return SCA;
+ return IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- return SCN;
+ return IEEE80211_HT_PARAM_CHA_SEC_NONE;
}
inline u8 *rtw_set_ie23a_secondary_ch_offset(u8 *buf, u32 *buf_len,
@@ -261,7 +250,7 @@ u8 *rtw_get_ie23a_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len,
* rtw_ies_remove_ie23a - Find matching IEs and remove
* @ies: Address of IEs to search
* @ies_len: Pointer of length of ies, will update to new length
- * @offset: The offset to start scarch
+ * @offset: The offset to start search
* @eid: Element ID to match
* @oui: OUI to match
* @oui_len: OUI length
@@ -361,32 +350,19 @@ int rtw_generate_ie23a(struct registry_priv *pregistrypriv)
int sz = 0, rateLen;
struct wlan_bssid_ex* pdev_network = &pregistrypriv->dev_network;
u8* ie = pdev_network->IEs;
+ u16 cap;
+ pdev_network->tsf = 0;
-
- /* timestamp will be inserted by hardware */
- sz += 8;
- ie += sz;
-
- /* beacon interval : 2bytes */
- /* BCN_INTERVAL; */
- *(u16*)ie = cpu_to_le16(pdev_network->BeaconPeriod);
- sz += 2;
- ie += 2;
-
- /* capability info */
- *(u16*)ie = 0;
-
- *(u16*)ie |= cpu_to_le16(WLAN_CAPABILITY_IBSS);
+ cap = WLAN_CAPABILITY_IBSS;
if (pregistrypriv->preamble == PREAMBLE_SHORT)
- *(u16*)ie |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
+ cap |= WLAN_CAPABILITY_SHORT_PREAMBLE;
if (pdev_network->Privacy)
- *(u16*)ie |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
+ cap |= WLAN_CAPABILITY_PRIVACY;
- sz += 2;
- ie += 2;
+ pdev_network->capability = cap;
/* SSID */
ie = rtw_set_ie23a(ie, WLAN_EID_SSID, pdev_network->Ssid.ssid_len,
@@ -436,7 +412,7 @@ int rtw_generate_ie23a(struct registry_priv *pregistrypriv)
return sz;
}
-int rtw_get_wpa_cipher_suite23a(const u8 *s)
+static int rtw_get_wpa_cipher_suite(const u8 *s)
{
if (!memcmp(s, WPA_CIPHER_SUITE_NONE23A, WPA_SELECTOR_LEN))
return WPA_CIPHER_NONE;
@@ -452,7 +428,7 @@ int rtw_get_wpa_cipher_suite23a(const u8 *s)
return 0;
}
-int rtw_get_wpa2_cipher_suite23a(const u8 *s)
+static int rtw_get_wpa2_cipher_suite(const u8 *s)
{
if (!memcmp(s, RSN_CIPHER_SUITE_NONE23A, RSN_SELECTOR_LEN))
return WPA_CIPHER_NONE;
@@ -490,7 +466,7 @@ int rtw_parse_wpa_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int
/* group_cipher */
if (left >= WPA_SELECTOR_LEN) {
- *group_cipher = rtw_get_wpa_cipher_suite23a(pos);
+ *group_cipher = rtw_get_wpa_cipher_suite(pos);
pos += WPA_SELECTOR_LEN;
left -= WPA_SELECTOR_LEN;
@@ -518,7 +494,7 @@ int rtw_parse_wpa_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int
}
for (i = 0; i < count; i++) {
- *pairwise_cipher |= rtw_get_wpa_cipher_suite23a(pos);
+ *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
pos += WPA_SELECTOR_LEN;
left -= WPA_SELECTOR_LEN;
@@ -557,7 +533,7 @@ int rtw_parse_wpa2_ie23a(const u8* rsn_ie, int rsn_ie_len, int *group_cipher,
return _FAIL;
}
- if (*rsn_ie != _WPA2_IE_ID_ || *(rsn_ie+1) != (u8)(rsn_ie_len - 2)) {
+ if (*rsn_ie != WLAN_EID_RSN || *(rsn_ie+1) != (u8)(rsn_ie_len - 2)) {
return _FAIL;
}
@@ -567,7 +543,7 @@ int rtw_parse_wpa2_ie23a(const u8* rsn_ie, int rsn_ie_len, int *group_cipher,
/* group_cipher */
if (left >= RSN_SELECTOR_LEN) {
- *group_cipher = rtw_get_wpa2_cipher_suite23a(pos);
+ *group_cipher = rtw_get_wpa2_cipher_suite(pos);
pos += RSN_SELECTOR_LEN;
left -= RSN_SELECTOR_LEN;
@@ -594,7 +570,7 @@ int rtw_parse_wpa2_ie23a(const u8* rsn_ie, int rsn_ie_len, int *group_cipher,
}
for (i = 0; i < count; i++) {
- *pairwise_cipher |= rtw_get_wpa2_cipher_suite23a(pos);
+ *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
pos += RSN_SELECTOR_LEN;
left -= RSN_SELECTOR_LEN;
@@ -621,130 +597,6 @@ int rtw_parse_wpa2_ie23a(const u8* rsn_ie, int rsn_ie_len, int *group_cipher,
return ret;
}
-int rtw_get_sec_ie23a(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
- u8 *wpa_ie, u16 *wpa_len)
-{
- u8 authmode, sec_idx, i;
- uint cnt;
-
-
- /* Search required WPA or WPA2 IE and copy to sec_ie[ ] */
-
- cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
-
- sec_idx = 0;
-
- while(cnt < in_len) {
- authmode = in_ie[cnt];
-
- if ((authmode == WLAN_EID_VENDOR_SPECIFIC) &&
- !memcmp(&in_ie[cnt+2], RTW_WPA_OUI23A_TYPE, 4)) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("\n rtw_get_wpa_ie23a: sec_idx =%d "
- "in_ie[cnt+1]+2 =%d\n",
- sec_idx, in_ie[cnt + 1] + 2));
-
- if (wpa_ie) {
- memcpy(wpa_ie, &in_ie[cnt], in_ie[cnt+1]+2);
-
- for (i = 0; i < (in_ie[cnt + 1] + 2); i = i + 8) {
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_info_,
- ("\n %2x,%2x,%2x,%2x,%2x,%2x,"
- "%2x,%2x\n", wpa_ie[i],
- wpa_ie[i + 1], wpa_ie[i + 2],
- wpa_ie[i + 3], wpa_ie[i + 4],
- wpa_ie[i + 5], wpa_ie[i + 6],
- wpa_ie[i + 7]));
- }
- }
-
- *wpa_len = in_ie[cnt + 1] + 2;
- cnt += in_ie[cnt + 1] + 2; /* get next */
- } else {
- if (authmode == _WPA2_IE_ID_) {
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("\n get_rsn_ie: sec_idx =%d in_ie"
- "[cnt+1]+2 =%d\n", sec_idx,
- in_ie[cnt + 1] + 2));
-
- if (rsn_ie) {
- memcpy(rsn_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
- for (i = 0; i < (in_ie[cnt + 1] + 2); i = i + 8) {
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_info_,
- ("\n %2x,%2x,%2x,%2x,%2x,%2x,"
- "%2x,%2x\n", rsn_ie[i],
- rsn_ie[i + 1], rsn_ie[i + 2],
- rsn_ie[i + 3], rsn_ie[i + 4],
- rsn_ie[i + 5], rsn_ie[i + 6],
- rsn_ie[i + 7]));
- }
- }
-
- *rsn_len = in_ie[cnt + 1] + 2;
- cnt += in_ie[cnt + 1] + 2; /* get next */
- } else {
- cnt += in_ie[cnt + 1] + 2; /* get next */
- }
- }
- }
-
-
-
- return *rsn_len + *wpa_len;
-}
-
-/**
- * rtw_get_wps_ie23a - Search WPS IE from a series of IEs
- * @in_ie: Address of IEs to search
- * @in_len: Length limit from in_ie
- * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the
- * buf starting from wps_ie
- * @wps_ielen: If not NULL and WPS IE is found, will set to the length of
- * the entire WPS IE
- *
- * Returns: The address of the WPS IE found, or NULL
- */
-u8 *rtw_get_wps_ie23a(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
-{
- uint cnt;
- u8 *wpsie_ptr = NULL;
- u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
-
- if (wps_ielen)
- *wps_ielen = 0;
-
- if (!in_ie || in_len <= 0)
- return wpsie_ptr;
-
- cnt = 0;
-
- while (cnt < in_len) {
- eid = in_ie[cnt];
-
- if (eid == WLAN_EID_VENDOR_SPECIFIC &&
- !memcmp(&in_ie[cnt+2], wps_oui, 4)) {
- wpsie_ptr = &in_ie[cnt];
-
- if (wps_ie)
- memcpy(wps_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
- if (wps_ielen)
- *wps_ielen = in_ie[cnt + 1] + 2;
-
- cnt += in_ie[cnt + 1] + 2;
-
- break;
- } else {
- cnt += in_ie[cnt + 1] + 2; /* goto next */
- }
- }
-
- return wpsie_ptr;
-}
-
/**
* rtw_get_wps_attr23a - Search a specific WPS attribute from a given WPS IE
* @wps_ie: Address of WPS IE to search
@@ -757,11 +609,11 @@ u8 *rtw_get_wps_ie23a(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
*
* Returns: the address of the specific WPS attribute found, or NULL
*/
-u8 *rtw_get_wps_attr23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
- u8 *buf_attr, u32 *len_attr)
+const u8 *rtw_get_wps_attr23a(const u8 *wps_ie, uint wps_ielen,
+ u16 target_attr_id, u8 *buf_attr, u32 *len_attr)
{
- u8 *attr_ptr = NULL;
- u8 * target_attr_ptr = NULL;
+ const u8 *attr_ptr = NULL;
+ const u8 *target_attr_ptr = NULL;
u8 wps_oui[4] = {0x00, 0x50, 0xF2, 0x04};
if (len_attr)
@@ -813,15 +665,12 @@ u8 *rtw_get_wps_attr23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
*
* Returns: the address of the specific WPS attribute content found, or NULL
*/
-u8 *rtw_get_wps_attr_content23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
- u8 *buf_content, uint *len_content)
+const u8 *rtw_get_wps_attr_content23a(const u8 *wps_ie, uint wps_ielen,
+ u16 target_attr_id, u8 *buf_content)
{
- u8 *attr_ptr;
+ const u8 *attr_ptr;
u32 attr_len;
- if (len_content)
- *len_content = 0;
-
attr_ptr = rtw_get_wps_attr23a(wps_ie, wps_ielen, target_attr_id,
NULL, &attr_len);
@@ -829,9 +678,6 @@ u8 *rtw_get_wps_attr_content23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id,
if (buf_content)
memcpy(buf_content, attr_ptr + 4, attr_len - 4);
- if (len_content)
- *len_content = attr_len - 4;
-
return attr_ptr + 4;
}
@@ -843,13 +689,11 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork)
const u8 *pbuf;
int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
int ret = _FAIL;
- int r, offset, plen;
+ int r, plen;
char *pie;
- offset = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u);
- pie = &pnetwork->network.IEs[offset];
- plen = pnetwork->network.IELength - offset;
+ pie = pnetwork->network.IEs;
+ plen = pnetwork->network.IELength;
pbuf = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA, pie, plen);
@@ -903,166 +747,112 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork)
void rtw_get_bcn_info23a(struct wlan_network *pnetwork)
{
- unsigned short cap;
u8 bencrypt = 0;
- /* u8 wpa_ie[255], rsn_ie[255]; */
- u16 wpa_len = 0, rsn_len = 0;
- struct HT_info_element *pht_info;
- struct ieee80211_ht_cap *pht_cap;
+ int pie_len;
+ u8 *pie;
const u8 *p;
- cap = get_unaligned_le16(
- rtw_get_capability23a_from_ie(pnetwork->network.IEs));
- if (cap & WLAN_CAPABILITY_PRIVACY) {
+ if (pnetwork->network.capability & WLAN_CAPABILITY_PRIVACY) {
bencrypt = 1;
pnetwork->network.Privacy = 1;
} else
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
- rtw_get_sec_ie23a(pnetwork->network.IEs, pnetwork->network.IELength,
- NULL, &rsn_len, NULL, &wpa_len);
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: ssid =%s\n", pnetwork->network.Ssid.ssid));
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: wpa_len =%d rsn_len =%d\n",
- wpa_len, rsn_len));
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: ssid =%s\n", pnetwork->network.Ssid.ssid));
- RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: wpa_len =%d rsn_len =%d\n",
- wpa_len, rsn_len));
+ ("%s: ssid =%s\n", __func__, pnetwork->network.Ssid.ssid));
+
+ pie = pnetwork->network.IEs;
+ pie_len = pnetwork->network.IELength;
- if (rsn_len > 0)
+ p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
+ if (p && p[1]) {
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA2;
- else if (wpa_len > 0)
+ } else if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ pie, pie_len)) {
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WPA;
- else {
+ } else {
if (bencrypt)
pnetwork->BcnInfo.encryp_protocol = ENCRYP_PROTOCOL_WEP;
}
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: pnetwork->encryp_protocol is %x\n",
+ ("%s: pnetwork->encryp_protocol is %x\n", __func__,
pnetwork->BcnInfo.encryp_protocol));
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
- ("rtw_get_bcn_info23a: pnetwork->encryp_protocol is %x\n",
+ ("%s: pnetwork->encryp_protocol is %x\n", __func__,
pnetwork->BcnInfo.encryp_protocol));
rtw_get_cipher_info(pnetwork);
/* get bwmode and ch_offset */
- /* parsing HT_CAP_IE */
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- pnetwork->network.IEs + _FIXED_IE_LENGTH_,
- pnetwork->network.IELength - _FIXED_IE_LENGTH_);
- if (p && p[1] > 0) {
- pht_cap = (struct ieee80211_ht_cap *)(p + 2);
- pnetwork->BcnInfo.ht_cap_info = pht_cap->cap_info;
- } else
- pnetwork->BcnInfo.ht_cap_info = 0;
-
- /* parsing HT_INFO_IE */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- pnetwork->network.IEs + _FIXED_IE_LENGTH_,
- pnetwork->network.IELength - _FIXED_IE_LENGTH_);
- if (p && p[1] > 0) {
- pht_info = (struct HT_info_element *)(p + 2);
- pnetwork->BcnInfo.ht_info_infos_0 = pht_info->infos[0];
- } else
- pnetwork->BcnInfo.ht_info_infos_0 = 0;
}
/* show MCS rate, unit: 100Kbps */
u16 rtw_mcs_rate23a(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40,
- unsigned char * MCS_rate)
+ struct ieee80211_mcs_info *mcs)
{
u16 max_rate = 0;
if (rf_type == RF_1T1R) {
- if (MCS_rate[0] & BIT(7))
+ if (mcs->rx_mask[0] & BIT(7))
max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):
((short_GI_20)?722:650);
- else if (MCS_rate[0] & BIT(6))
+ else if (mcs->rx_mask[0] & BIT(6))
max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):
((short_GI_20)?650:585);
- else if (MCS_rate[0] & BIT(5))
+ else if (mcs->rx_mask[0] & BIT(5))
max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):
((short_GI_20)?578:520);
- else if (MCS_rate[0] & BIT(4))
+ else if (mcs->rx_mask[0] & BIT(4))
max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):
((short_GI_20)?433:390);
- else if (MCS_rate[0] & BIT(3))
+ else if (mcs->rx_mask[0] & BIT(3))
max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):
((short_GI_20)?289:260);
- else if (MCS_rate[0] & BIT(2))
+ else if (mcs->rx_mask[0] & BIT(2))
max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):
((short_GI_20)?217:195);
- else if (MCS_rate[0] & BIT(1))
+ else if (mcs->rx_mask[0] & BIT(1))
max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):
((short_GI_20)?144:130);
- else if (MCS_rate[0] & BIT(0))
+ else if (mcs->rx_mask[0] & BIT(0))
max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):
((short_GI_20)?72:65);
} else {
- if (MCS_rate[1]) {
- if (MCS_rate[1] & BIT(7))
+ if (mcs->rx_mask[1]) {
+ if (mcs->rx_mask[1] & BIT(7))
max_rate = (bw_40MHz) ? ((short_GI_40)?3000:2700):((short_GI_20)?1444:1300);
- else if (MCS_rate[1] & BIT(6))
+ else if (mcs->rx_mask[1] & BIT(6))
max_rate = (bw_40MHz) ? ((short_GI_40)?2700:2430):((short_GI_20)?1300:1170);
- else if (MCS_rate[1] & BIT(5))
+ else if (mcs->rx_mask[1] & BIT(5))
max_rate = (bw_40MHz) ? ((short_GI_40)?2400:2160):((short_GI_20)?1156:1040);
- else if (MCS_rate[1] & BIT(4))
+ else if (mcs->rx_mask[1] & BIT(4))
max_rate = (bw_40MHz) ? ((short_GI_40)?1800:1620):((short_GI_20)?867:780);
- else if (MCS_rate[1] & BIT(3))
+ else if (mcs->rx_mask[1] & BIT(3))
max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
- else if (MCS_rate[1] & BIT(2))
+ else if (mcs->rx_mask[1] & BIT(2))
max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
- else if (MCS_rate[1] & BIT(1))
+ else if (mcs->rx_mask[1] & BIT(1))
max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
- else if (MCS_rate[1] & BIT(0))
+ else if (mcs->rx_mask[1] & BIT(0))
max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
} else {
- if (MCS_rate[0] & BIT(7))
+ if (mcs->rx_mask[0] & BIT(7))
max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650);
- else if (MCS_rate[0] & BIT(6))
+ else if (mcs->rx_mask[0] & BIT(6))
max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585);
- else if (MCS_rate[0] & BIT(5))
+ else if (mcs->rx_mask[0] & BIT(5))
max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
- else if (MCS_rate[0] & BIT(4))
+ else if (mcs->rx_mask[0] & BIT(4))
max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
- else if (MCS_rate[0] & BIT(3))
+ else if (mcs->rx_mask[0] & BIT(3))
max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
- else if (MCS_rate[0] & BIT(2))
+ else if (mcs->rx_mask[0] & BIT(2))
max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195);
- else if (MCS_rate[0] & BIT(1))
+ else if (mcs->rx_mask[0] & BIT(1))
max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
- else if (MCS_rate[0] & BIT(0))
+ else if (mcs->rx_mask[0] & BIT(0))
max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65);
}
}
return max_rate;
}
-
-static const char *_action_public_str23a[] = {
- "ACT_PUB_BSSCOEXIST",
- "ACT_PUB_DSE_ENABLE",
- "ACT_PUB_DSE_DEENABLE",
- "ACT_PUB_DSE_REG_LOCATION",
- "ACT_PUB_EXT_CHL_SWITCH",
- "ACT_PUB_DSE_MSR_REQ",
- "ACT_PUB_DSE_MSR_RPRT",
- "ACT_PUB_MP",
- "ACT_PUB_DSE_PWR_CONSTRAINT",
- "ACT_PUB_VENDOR",
- "ACT_PUB_GAS_INITIAL_REQ",
- "ACT_PUB_GAS_INITIAL_RSP",
- "ACT_PUB_GAS_COMEBACK_REQ",
- "ACT_PUB_GAS_COMEBACK_RSP",
- "ACT_PUB_TDLS_DISCOVERY_RSP",
- "ACT_PUB_LOCATION_TRACK",
- "ACT_PUB_RSVD",
-};
-
-const char *action_public_str23a(u8 action)
-{
- action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action;
- return _action_public_str23a[action];
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_ioctl_set.c b/drivers/staging/rtl8723au/core/rtw_ioctl_set.c
deleted file mode 100644
index cf897c723f4a..000000000000
--- a/drivers/staging/rtl8723au/core/rtw_ioctl_set.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- ******************************************************************************/
-#define _RTW_IOCTL_SET_C_
-
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <rtw_ioctl_set.h>
-#include <hal_intf.h>
-
-#include <usb_ops.h>
-#include <linux/ieee80211.h>
-
-int rtw_do_join23a(struct rtw_adapter *padapter)
-{
- struct list_head *plist, *phead;
- u8* pibss = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- int ret = _SUCCESS;
-
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
- phead = get_list_head(queue);
- plist = phead->next;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("\n rtw_do_join23a: phead = %p; plist = %p\n\n\n",
- phead, plist));
-
- pmlmepriv->cur_network.join_res = -2;
-
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
- pmlmepriv->to_join = true;
-
- if (list_empty(&queue->queue)) {
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
- /* when set_ssid/set_bssid for rtw_do_join23a(), but
- scanning queue is empty */
- /* we try to issue sitesurvey firstly */
-
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false ||
- padapter->mlmepriv.to_roaming > 0) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("rtw_do_join23a(): site survey if scanned_queue "
- "is empty\n."));
- /* submit site_survey23a_cmd */
- ret = rtw_sitesurvey_cmd23a(padapter,
- &pmlmepriv->assoc_ssid, 1,
- NULL, 0);
- if (ret != _SUCCESS) {
- pmlmepriv->to_join = false;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_do_join23a(): site survey return "
- "error\n."));
- }
- } else {
- pmlmepriv->to_join = false;
- ret = _FAIL;
- }
-
- goto exit;
- } else {
- int select_ret;
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
- select_ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
- if (select_ret == _SUCCESS) {
- pmlmepriv->to_join = false;
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
- } else {
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- struct wlan_bssid_ex *pdev_network;
- /* submit createbss_cmd to change to a
- ADHOC_MASTER */
-
- /* pmlmepriv->lock has been acquired by
- caller... */
- pdev_network =
- &padapter->registrypriv.dev_network;
-
- pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
-
- pibss = padapter->registrypriv.dev_network.MacAddress;
-
- memcpy(&pdev_network->Ssid,
- &pmlmepriv->assoc_ssid,
- sizeof(struct cfg80211_ssid));
-
- rtw_update_registrypriv_dev_network23a(padapter);
-
- rtw_generate_random_ibss23a(pibss);
-
- if (rtw_createbss_cmd23a(padapter) != _SUCCESS) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_,
- _drv_err_,
- ("***Error =>do_goin: rtw_creat"
- "ebss_cmd status FAIL***\n"));
- ret = false;
- goto exit;
- }
-
- pmlmepriv->to_join = false;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_,
- _drv_info_,
- ("***Error => rtw_select_and_join_from"
- "_scanned_queue FAIL under STA_Mode"
- "***\n "));
- } else {
- /* can't associate ; reset under-linking */
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
- /* when set_ssid/set_bssid for rtw_do_join23a(),
- but there are no desired bss in scanning
- queue */
- /* we try to issue sitesurvey firstly */
- if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==
- false || padapter->mlmepriv.to_roaming > 0){
- /* DBG_8723A("rtw_do_join23a() when no "
- "desired bss in scanning queue\n");
- */
- ret = rtw_sitesurvey_cmd23a(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
- if (ret != _SUCCESS) {
- pmlmepriv->to_join = false;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
- }
- } else {
- ret = _FAIL;
- pmlmepriv->to_join = false;
- }
- }
- }
- }
-
-exit:
-
- return ret;
-}
-
-int rtw_set_802_11_ssid23a(struct rtw_adapter* padapter,
- struct cfg80211_ssid *ssid)
-{
- int status = _SUCCESS;
- u32 cur_time = 0;
-
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wlan_network *pnetwork = &pmlmepriv->cur_network;
-
-
-
- DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
- ssid->ssid, get_fwstate(pmlmepriv));
-
- if (padapter->hw_init_completed == false) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("set_ssid: hw_init_completed == false =>exit!!!\n"));
- status = _FAIL;
- goto exit;
- }
-
- spin_lock_bh(&pmlmepriv->lock);
-
- DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- goto handle_tkip_countermeasure;
- else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
- goto release_mlme_lock;
-
- if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
-
- if ((pmlmepriv->assoc_ssid.ssid_len == ssid->ssid_len) &&
- !memcmp(&pmlmepriv->assoc_ssid.ssid, ssid->ssid,
- ssid->ssid_len)) {
- if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("Set SSID is the same ssid, fw_state = 0x%08x\n",
- get_fwstate(pmlmepriv)));
-
- if (rtw_is_same_ibss23a(padapter, pnetwork) == false)
- {
- /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
- rtw_disassoc_cmd23a(padapter, 0, true);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_indicate_disconnect23a(padapter);
-
- rtw_free_assoc_resources23a(padapter, 1);
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- }
- } else {
- goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
- }
- } else {
- rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_JOINBSS, 1);
- }
- } else {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("Set SSID not the same ssid\n"));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("set_ssid =[%s] len = 0x%x\n", ssid->ssid,
- (unsigned int)ssid->ssid_len));
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("assoc_ssid =[%s] len = 0x%x\n",
- pmlmepriv->assoc_ssid.ssid,
- (unsigned int)pmlmepriv->assoc_ssid.ssid_len));
-
- rtw_disassoc_cmd23a(padapter, 0, true);
-
- if (check_fwstate(pmlmepriv, _FW_LINKED))
- rtw_indicate_disconnect23a(padapter);
-
- rtw_free_assoc_resources23a(padapter, 1);
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
- _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
- set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
- }
- }
- }
-
-handle_tkip_countermeasure:
-
- if (padapter->securitypriv.btkip_countermeasure == true) {
- cur_time = jiffies;
-
- if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ)
- {
- padapter->securitypriv.btkip_countermeasure = false;
- padapter->securitypriv.btkip_countermeasure_time = 0;
- }
- else
- {
- status = _FAIL;
- goto release_mlme_lock;
- }
- }
-
- memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct cfg80211_ssid));
- pmlmepriv->assoc_by_bssid = false;
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- pmlmepriv->to_join = true;
- else
- status = rtw_do_join23a(padapter);
-
-release_mlme_lock:
- spin_unlock_bh(&pmlmepriv->lock);
-
-exit:
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("-rtw_set_802_11_ssid23a: status =%d\n", status));
-
-
-
- return status;
-}
-
-int rtw_set_802_11_bssid23a_list_scan(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid,
- int ssid_max_num)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- int res = _SUCCESS;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("+rtw_set_802_11_bssid23a_list_scan(), fw_state =%x\n",
- get_fwstate(pmlmepriv)));
-
- if (!padapter) {
- res = _FAIL;
- goto exit;
- }
- if (padapter->hw_init_completed == false) {
- res = _FAIL;
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n === rtw_set_802_11_bssid23a_list_scan:"
- "hw_init_completed == false ===\n"));
- goto exit;
- }
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ||
- (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)) {
- /* Scan or linking is in progress, do nothing. */
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("rtw_set_802_11_bssid23a_list_scan fail since fw_state "
- "= %x\n", get_fwstate(pmlmepriv)));
-
- if (check_fwstate(pmlmepriv,
- (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n"));
- } else {
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
- ("\n###pmlmepriv->sitesurveyctrl.traffic_"
- "busy == true\n"));
- }
- } else {
- if (rtw_is_scan_deny(padapter)) {
- DBG_8723A("%s(%s): scan deny\n",
- __func__, padapter->pnetdev->name);
- return _SUCCESS;
- }
-
- spin_lock_bh(&pmlmepriv->lock);
-
- res = rtw_sitesurvey_cmd23a(padapter, pssid, ssid_max_num,
- NULL, 0);
-
- spin_unlock_bh(&pmlmepriv->lock);
- }
-exit:
- return res;
-}
-
-int rtw_set_802_11_authentication_mode23a(struct rtw_adapter* padapter,
- enum ndis_802_11_auth_mode authmode)
-{
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- int res;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("set_802_11_auth.mode(): mode =%x\n", authmode));
-
- psecuritypriv->ndisauthtype = authmode;
-
- RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
- ("rtw_set_802_11_authentication_mode23a:"
- "psecuritypriv->ndisauthtype =%d",
- psecuritypriv->ndisauthtype));
-
- if (psecuritypriv->ndisauthtype > 3)
- psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
-
- res = rtw_set_auth23a(padapter, psecuritypriv);
-
- return res;
-}
-
-/*
-* rtw_get_cur_max_rate23a -
-* @adapter: pointer to _adapter structure
-*
-* Return 0 or 100Kbps
-*/
-u16 rtw_get_cur_max_rate23a(struct rtw_adapter *adapter)
-{
- int i = 0;
- const u8 *p;
- u16 rate = 0, max_rate = 0;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct registry_priv *pregistrypriv = &adapter->registrypriv;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
- struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
- struct ieee80211_ht_cap *pht_capie;
- u8 rf_type = 0;
- u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
- u16 mcs_rate = 0;
-
- if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
- !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
- return 0;
-
- if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- &pcur_bss->IEs[12],
- pcur_bss->IELength - 12);
- if (p && p[1] > 0) {
- pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-
- memcpy(&mcs_rate, &pht_capie->mcs, 2);
-
- /* bw_40MHz = (pht_capie->cap_info&
- IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */
- /* cur_bwmod is updated by beacon, pmlmeinfo is
- updated by association response */
- bw_40MHz = (pmlmeext->cur_bwmode &&
- (IEEE80211_HT_PARAM_CHAN_WIDTH_ANY &
- pmlmeinfo->HT_info.infos[0])) ? 1:0;
-
- /* short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP
- _SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; */
- short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
- short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
-
- rf_type = rtl8723a_get_rf_type(adapter);
- max_rate = rtw_mcs_rate23a(rf_type, bw_40MHz &
- pregistrypriv->cbw40_enable,
- short_GI_20, short_GI_40,
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
- );
- }
- } else {
- while ((pcur_bss->SupportedRates[i] != 0) &&
- (pcur_bss->SupportedRates[i] != 0xFF)) {
- rate = pcur_bss->SupportedRates[i] & 0x7F;
- if (rate>max_rate)
- max_rate = rate;
- i++;
- }
-
- max_rate = max_rate * 10 / 2;
- }
-
- return max_rate;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme.c b/drivers/staging/rtl8723au/core/rtw_mlme.c
index 7170258d2601..c475b79bbf1d 100644
--- a/drivers/staging/rtl8723au/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723au/core/rtw_mlme.c
@@ -24,12 +24,15 @@
#include <linux/ieee80211.h>
#include <wifi.h>
#include <wlan_bssdef.h>
-#include <rtw_ioctl_set.h>
#include <rtw_sreset.h>
+static struct wlan_network *
+rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
+static int rtw_do_join(struct rtw_adapter *padapter);
+
static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
(unsigned long)padapter);
@@ -84,36 +87,8 @@ void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
#ifdef CONFIG_8723AU_AP_MODE
kfree(pmlmepriv->assoc_req);
kfree(pmlmepriv->assoc_rsp);
- rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie,
- &pmlmepriv->wps_beacon_ie_len);
rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie,
&pmlmepriv->wps_probe_req_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie,
- &pmlmepriv->wps_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie,
- &pmlmepriv->wps_assoc_resp_ie_len);
-
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie,
- &pmlmepriv->p2p_beacon_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie,
- &pmlmepriv->p2p_probe_req_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie,
- &pmlmepriv->p2p_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie,
- &pmlmepriv->p2p_go_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie,
- &pmlmepriv->p2p_assoc_req_ie_len);
-
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie,
- &pmlmepriv->wfd_beacon_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie,
- &pmlmepriv->wfd_probe_req_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie,
- &pmlmepriv->wfd_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie,
- &pmlmepriv->wfd_go_probe_resp_ie_len);
- rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie,
- &pmlmepriv->wfd_assoc_req_ie_len);
#endif
}
@@ -125,7 +100,7 @@ void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
rtw23a_free_mlme_priv_ie_data(pmlmepriv);
}
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, int gfp)
+struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
{
struct wlan_network *pnetwork;
@@ -159,7 +134,7 @@ static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
/*
return the wlan_network with the matching addr
- Shall be calle under atomic context... to avoid possible racing condition...
+ Shall be called under atomic context... to avoid possible racing condition...
*/
struct wlan_network *
rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
@@ -277,7 +252,7 @@ static void _rtw_roaming(struct rtw_adapter *padapter,
pmlmepriv->assoc_by_bssid = false;
while (1) {
- do_join_r = rtw_do_join23a(padapter);
+ do_join_r = rtw_do_join(padapter);
if (do_join_r == _SUCCESS)
break;
else {
@@ -309,35 +284,16 @@ void rtw23a_roaming(struct rtw_adapter *padapter,
spin_unlock_bh(&pmlmepriv->lock);
}
-__le16 *rtw_get_capability23a_from_ie(u8 *ie)
-{
- return (__le16 *)(ie + 8 + 2);
-}
-
-u16 rtw_get_capability23a(struct wlan_bssid_ex *bss)
-{
- u16 val;
-
- memcpy(&val, rtw_get_capability23a_from_ie(bss->IEs), 2);
-
- return le16_to_cpu(val);
-}
-
-__le16 *rtw_get_beacon_interval23a_from_ie(u8 *ie)
-{
- return (__le16 *)(ie + 8);
-}
-
static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
struct wlan_network *pnetwork)
{
_rtw_free_network23a(pmlmepriv, pnetwork);
}
-int rtw_is_same_ibss23a(struct rtw_adapter *adapter,
- struct wlan_network *pnetwork)
+bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
+ struct wlan_network *pnetwork)
{
- int ret = true;
+ int ret;
struct security_priv *psecuritypriv = &adapter->securitypriv;
if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
@@ -363,17 +319,16 @@ int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
{
u16 s_cap, d_cap;
- s_cap = get_unaligned_le16(rtw_get_capability23a_from_ie(src->IEs));
- d_cap = get_unaligned_le16(rtw_get_capability23a_from_ie(dst->IEs));
+ s_cap = src->capability;
+ d_cap = dst->capability;
return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
/* (src->DSConfig == dst->DSConfig) && */
ether_addr_equal(src->MacAddress, dst->MacAddress) &&
- ((!memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len))) &&
- ((s_cap & WLAN_CAPABILITY_IBSS) ==
- (d_cap & WLAN_CAPABILITY_IBSS)) &&
- ((s_cap & WLAN_CAPABILITY_ESS) ==
- (d_cap & WLAN_CAPABILITY_ESS)));
+ !memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
+ (s_cap & WLAN_CAPABILITY_IBSS) ==
+ (d_cap & WLAN_CAPABILITY_IBSS) &&
+ (s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
}
struct wlan_network *
@@ -440,7 +395,7 @@ void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
(u32)dst->PhyInfo.SignalQuality * 4) / 5;
rssi_final = src->Rssi+dst->Rssi * 4 / 5;
} else {
- /* bss info not receving from the right channel, use
+ /* bss info not receiving from the right channel, use
the original RX signal infos */
ss_final = dst->PhyInfo.SignalStrength;
sq_final = dst->PhyInfo.SignalQuality;
@@ -469,16 +424,11 @@ static void update_current_network(struct rtw_adapter *adapter,
if (check_fwstate(pmlmepriv, _FW_LINKED) &&
is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
- int bcn_size;
update_network23a(&pmlmepriv->cur_network.network,
pnetwork,adapter, true);
- bcn_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
rtw_update_protection23a(adapter,
- pmlmepriv->cur_network.network.IEs +
- bcn_size,
+ pmlmepriv->cur_network.network.IEs,
pmlmepriv->cur_network.network.IELength);
}
}
@@ -488,8 +438,8 @@ static void update_current_network(struct rtw_adapter *adapter,
Caller must hold pmlmepriv->lock first.
*/
-void rtw_update_scanned_network23a(struct rtw_adapter *adapter,
- struct wlan_bssid_ex *target)
+static void rtw_update_scanned_network(struct rtw_adapter *adapter,
+ struct wlan_bssid_ex *target)
{
struct list_head *plist, *phead;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
@@ -540,7 +490,7 @@ void rtw_update_scanned_network23a(struct rtw_adapter *adapter,
pnetwork->aid = 0;
pnetwork->join_res = 0;
- /* bss info not receving from the right channel */
+ /* bss info not receiving from the right channel */
if (pnetwork->network.PhyInfo.SignalQuality == 101)
pnetwork->network.PhyInfo.SignalQuality = 0;
} else {
@@ -572,7 +522,7 @@ static void rtw_add_network(struct rtw_adapter *adapter,
struct wlan_bssid_ex *pnetwork)
{
update_current_network(adapter, pnetwork);
- rtw_update_scanned_network23a(adapter, pnetwork);
+ rtw_update_scanned_network(adapter, pnetwork);
}
/* select the desired network based on the capability of the (i)bss. */
@@ -588,19 +538,16 @@ static int rtw_is_desired_network(struct rtw_adapter *adapter,
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
u32 desired_encmode;
u32 privacy;
-
- /* u8 wps_ie[512]; */
- uint wps_ielen;
-
int bselected = true;
desired_encmode = psecuritypriv->ndisencryptstatus;
privacy = pnetwork->network.Privacy;
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
- if (rtw_get_wps_ie23a(pnetwork->network.IEs + _FIXED_IE_LENGTH_,
- pnetwork->network.IELength -
- _FIXED_IE_LENGTH_, NULL, &wps_ielen))
+ if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+ pnetwork->network.IEs,
+ pnetwork->network.IELength))
return true;
else
return false;
@@ -612,8 +559,7 @@ static int rtw_is_desired_network(struct rtw_adapter *adapter,
bselected = false;
}
- if (desired_encmode != Ndis802_11EncryptionDisabled &&
- privacy == 0) {
+ if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
DBG_8723A("desired_encmode: %d, privacy: %d\n",
desired_encmode, privacy);
bselected = false;
@@ -640,9 +586,10 @@ void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
{
u32 len;
struct wlan_bssid_ex *pnetwork;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct survey_event *survey = (struct survey_event *)pbuf;
- pnetwork = (struct wlan_bssid_ex *)pbuf;
+ pnetwork = survey->bss;
RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,
("rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid));
@@ -665,15 +612,22 @@ void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
pnetwork->MacAddress)) {
struct wlan_network* ibss_wlan;
- memcpy(pmlmepriv->cur_network.network.IEs,
- pnetwork->IEs, 8);
+ pmlmepriv->cur_network.network.beacon_interval =
+ pnetwork->beacon_interval;
+ pmlmepriv->cur_network.network.capability =
+ pnetwork->capability;
+ pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
ibss_wlan = rtw_find_network23a(
&pmlmepriv->scanned_queue,
pnetwork->MacAddress);
if (ibss_wlan) {
- memcpy(ibss_wlan->network.IEs,
- pnetwork->IEs, 8);
+ pmlmepriv->cur_network.network.beacon_interval =
+ ibss_wlan->network.beacon_interval;
+ pmlmepriv->cur_network.network.capability =
+ ibss_wlan->network.capability;
+ pmlmepriv->cur_network.network.tsf =
+ ibss_wlan->network.tsf;
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
goto exit;
}
@@ -693,16 +647,18 @@ exit:
spin_unlock_bh(&pmlmepriv->lock);
+ kfree(survey->bss);
+ survey->bss = NULL;
+
return;
}
void
rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
{
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct wlan_bssid_ex *pdev_network;
- u8 *pibss;
+ int ret;
spin_lock_bh(&pmlmepriv->lock);
@@ -729,63 +685,17 @@ rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
rtw_set_signal_stat_timer(&adapter->recvpriv);
if (pmlmepriv->to_join == true) {
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
-
- if (rtw_select_and_join_from_scanned_queue23a(
- pmlmepriv) == _SUCCESS) {
- mod_timer(&pmlmepriv->assoc_timer,
- jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
- } else {
- pdev_network = &adapter->registrypriv.dev_network;
- pibss = adapter->registrypriv.dev_network.MacAddress;
-
- _clr_fwstate_(pmlmepriv,
- _FW_UNDER_SURVEY);
-
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_err_,
- ("switching to adhoc "
- "master\n"));
-
- memset(&pdev_network->Ssid, 0,
- sizeof(struct cfg80211_ssid));
- memcpy(&pdev_network->Ssid,
- &pmlmepriv->assoc_ssid,
- sizeof(struct cfg80211_ssid));
-
- rtw_update_registrypriv_dev_network23a(
- adapter);
- rtw_generate_random_ibss23a(pibss);
-
- pmlmepriv->fw_state =
- WIFI_ADHOC_MASTER_STATE;
-
- if (rtw_createbss_cmd23a(adapter) !=
- _SUCCESS)
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_err_,
- ("Error =>rtw_createbss_cmd23a"
- " status FAIL\n"));
-
- pmlmepriv->to_join = false;
- }
- }
+ ret = rtw_select_and_join_from_scanned_queue23a(
+ pmlmepriv);
+ if (ret != _SUCCESS)
+ rtw_do_join_adhoc(adapter);
} else {
- int ret;
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->to_join = false;
ret = rtw_select_and_join_from_scanned_queue23a(
pmlmepriv);
- if (ret == _SUCCESS) {
- unsigned long e;
- e = msecs_to_jiffies(MAX_JOIN_TIMEOUT);
- mod_timer(&pmlmepriv->assoc_timer, jiffies + e);
- } else if (ret == 2) {/* there is no need to wait */
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
- rtw_indicate_connect23a(adapter);
- } else {
+ if (ret != _SUCCESS) {
DBG_8723A("try_to_join, but select scanning "
"queue fail, to_roaming:%d\n",
adapter->mlmepriv.to_roaming);
@@ -830,9 +740,9 @@ static void free_scanqueue(struct mlme_priv *pmlmepriv)
phead = get_list_head(scan_queue);
list_for_each_safe(plist, ptemp, phead) {
- list_del_init(plist);
pnetwork = container_of(plist, struct wlan_network, list);
- kfree(pnetwork);
+ pnetwork->fixed = false;
+ _rtw_free_network23a(pmlmepriv, pnetwork);
}
spin_unlock_bh(&scan_queue->lock);
@@ -938,7 +848,7 @@ void rtw_indicate_connect23a(struct rtw_adapter *padapter)
*/
void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
("+rtw_indicate_disconnect23a\n"));
@@ -1046,7 +956,7 @@ rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
/* Commented by Albert 2012/07/21 */
/* When doing the WPS, the wps_ie_len won't equal to 0 */
/* And the Wi-Fi driver shouldn't allow the data packet
- to be tramsmitted. */
+ to be transmitted. */
if (padapter->securitypriv.wps_ie_len != 0) {
psta->ieee8021x_blocked = true;
padapter->securitypriv.wps_ie_len = 0;
@@ -1054,7 +964,7 @@ rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
/* for A-MPDU Rx reordering buffer control for bmc_sta &
* sta_info */
- /* if A-MPDU Rx is enabled, reseting
+ /* if A-MPDU Rx is enabled, resetting
rx_ordering_ctrl wstart_b(indicate_seq) to default
value = 0xffff */
/* todo: check if AP can send A-MPDU packets */
@@ -1098,7 +1008,6 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_network *cur_network = &pmlmepriv->cur_network;
- int bcn_size;
DBG_8723A("%s\n", __func__);
@@ -1114,6 +1023,10 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
MAX_IE_SZ);
+ cur_network->network.capability = ptarget_wlan->network.capability;
+ cur_network->network.beacon_interval =
+ ptarget_wlan->network.beacon_interval;
+ cur_network->network.tsf = ptarget_wlan->network.tsf;
cur_network->aid = pnetwork->join_res;
rtw_set_signal_stat_timer(&padapter->recvpriv);
@@ -1151,11 +1064,8 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
break;
}
- bcn_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
- rtw_update_protection23a(padapter, cur_network->network.IEs +
- bcn_size, cur_network->network.IELength);
+ rtw_update_protection23a(padapter, cur_network->network.IEs,
+ cur_network->network.IELength);
rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
cur_network->network.IELength);
@@ -1163,7 +1073,7 @@ rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
/*
* Notes:
- * the fucntion could be > passive_level (the same context as Rx tasklet)
+ * the function could be > passive_level (the same context as Rx tasklet)
* pnetwork : returns from rtw23a_joinbss_event_cb
* ptarget_wlan: found from scanned_queue
* if join_res > 0, for (fw_state==WIFI_STATION_STATE),
@@ -1188,8 +1098,6 @@ void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
("joinbss event call back received with res=%d\n",
pnetwork->join_res));
- rtw_get_encrypt_decrypt_from_registrypriv23a(adapter);
-
if (pmlmepriv->assoc_ssid.ssid_len == 0) {
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
("@@@@@ joinbss event call back for Any SSid\n"));
@@ -1429,7 +1337,6 @@ void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
struct sta_info *psta;
struct wlan_network* pwlan;
struct wlan_bssid_ex *pdev_network;
- u8 *pibss;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct stadel_event *pstadel = (struct stadel_event *)pbuf;
struct sta_priv *pstapriv = &adapter->stapriv;
@@ -1500,32 +1407,11 @@ void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
/* re-create ibss */
pdev_network = &adapter->registrypriv.dev_network;
- pibss = adapter->registrypriv.dev_network.MacAddress;
memcpy(pdev_network, &tgt_network->network,
get_wlan_bssid_ex_sz(&tgt_network->network));
- memset(&pdev_network->Ssid, 0,
- sizeof(struct cfg80211_ssid));
- memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
- sizeof(struct cfg80211_ssid));
-
- rtw_update_registrypriv_dev_network23a(adapter);
-
- rtw_generate_random_ibss23a(pibss);
-
- if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
- set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
- _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
- }
-
- if (rtw_createbss_cmd23a(adapter) != _SUCCESS) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_,
- _drv_err_,
- ("***Error =>stadel_event_callback: "
- "rtw_createbss_cmd23a status "
- "FAIL***\n"));
- }
+ rtw_do_join_adhoc(adapter);
}
}
@@ -1533,18 +1419,18 @@ void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
}
/*
-* rtw23a_join_to_handler - Timeout/faliure handler for CMD JoinBss
+* rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
* @adapter: pointer to _adapter structure
*/
void rtw23a_join_to_handler (unsigned long data)
{
struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
int do_join_r;
DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
- if (adapter->bDriverStopped ||adapter->bSurpriseRemoved)
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
return;
spin_lock_bh(&pmlmepriv->lock);
@@ -1556,7 +1442,7 @@ void rtw23a_join_to_handler (unsigned long data)
if (adapter->mlmepriv.to_roaming != 0) {
/* try another */
DBG_8723A("%s try another roaming\n", __func__);
- do_join_r = rtw_do_join23a(adapter);
+ do_join_r = rtw_do_join(adapter);
if (do_join_r != _SUCCESS) {
DBG_8723A("%s roaming do_join return "
"%d\n", __func__ , do_join_r);
@@ -1584,13 +1470,13 @@ void rtw23a_join_to_handler (unsigned long data)
}
/*
-* rtw_scan_timeout_handler23a - Timeout/Faliure handler for CMD SiteSurvey
+* rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
* @data: pointer to _adapter structure
*/
void rtw_scan_timeout_handler23a(unsigned long data)
{
struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
get_fwstate(pmlmepriv));
@@ -1604,26 +1490,9 @@ void rtw_scan_timeout_handler23a(unsigned long data)
rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
}
-static void rtw_auto_scan_handler(struct rtw_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- /* auto site survey per 60sec */
- if (pmlmepriv->scan_interval > 0) {
- pmlmepriv->scan_interval--;
- if (pmlmepriv->scan_interval == 0) {
- DBG_8723A("%s\n", __func__);
- rtw_set_802_11_bssid23a_list_scan(padapter, NULL, 0);
- /* 30*2 sec = 60sec */
- pmlmepriv->scan_interval = SCAN_INTERVAL;
- }
- }
-}
-
void rtw_dynamic_check_timer_handler(unsigned long data)
{
struct rtw_adapter *adapter = (struct rtw_adapter *)data;
- struct registry_priv *pregistrypriv = &adapter->registrypriv;
if (adapter->hw_init_completed == false)
goto out;
@@ -1637,10 +1506,6 @@ void rtw_dynamic_check_timer_handler(unsigned long data)
rtw_dynamic_chk_wk_cmd23a(adapter);
- if (pregistrypriv->wifi_spec == 1) {
- /* auto site survey */
- rtw_auto_scan_handler(adapter);
- }
out:
mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
jiffies + msecs_to_jiffies(2000));
@@ -1755,32 +1620,134 @@ pmlmepriv->lock
*/
-int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
+static int rtw_do_join(struct rtw_adapter *padapter)
{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int ret;
- struct list_head *phead, *plist, *ptmp;
- struct rtw_adapter *adapter;
+
+ pmlmepriv->cur_network.join_res = -2;
+
+ set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
+
+ pmlmepriv->to_join = true;
+
+ ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
+ if (ret == _SUCCESS) {
+ pmlmepriv->to_join = false;
+ } else {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ /* switch to ADHOC_MASTER */
+ ret = rtw_do_join_adhoc(padapter);
+ if (ret != _SUCCESS)
+ goto exit;
+ } else {
+ /* can't associate ; reset under-linking */
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+
+ ret = _FAIL;
+ pmlmepriv->to_join = false;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static struct wlan_network *
+rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
+{
+ struct wlan_network *pnetwork, *candidate = NULL;
struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- struct wlan_network *pnetwork;
- struct wlan_network *candidate = NULL;
+ struct list_head *phead, *plist, *ptmp;
spin_lock_bh(&pmlmepriv->scanned_queue.lock);
phead = get_list_head(queue);
- adapter = pmlmepriv->nic_hdl;
list_for_each_safe(plist, ptmp, phead) {
pnetwork = container_of(plist, struct wlan_network, list);
if (!pnetwork) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
- ("%s return _FAIL:(pnetwork == NULL)\n",
+ ("%s: return _FAIL:(pnetwork == NULL)\n",
__func__));
- ret = _FAIL;
goto exit;
}
rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
}
+exit:
+ spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
+ return candidate;
+}
+
+
+int rtw_do_join_adhoc(struct rtw_adapter *adapter)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct wlan_bssid_ex *pdev_network;
+ u8 *ibss;
+ int ret;
+
+ pdev_network = &adapter->registrypriv.dev_network;
+ ibss = adapter->registrypriv.dev_network.MacAddress;
+
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
+
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ ("switching to adhoc master\n"));
+
+ memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
+ sizeof(struct cfg80211_ssid));
+
+ rtw_update_registrypriv_dev_network23a(adapter);
+ rtw_generate_random_ibss23a(ibss);
+
+ pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
+
+ ret = rtw_createbss_cmd23a(adapter);
+ if (ret != _SUCCESS) {
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
+ ("Error =>rtw_createbss_cmd23a status FAIL\n"));
+ } else {
+ pmlmepriv->to_join = false;
+ }
+
+ return ret;
+}
+
+int rtw_do_join_network(struct rtw_adapter *adapter,
+ struct wlan_network *candidate)
+{
+ int ret;
+
+ /* check for situation of _FW_LINKED */
+ if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
+ DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
+
+ rtw_disassoc_cmd23a(adapter, 0, true);
+ rtw_indicate_disconnect23a(adapter);
+ rtw_free_assoc_resources23a(adapter, 0);
+ }
+ set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
+
+ ret = rtw_joinbss_cmd23a(adapter, candidate);
+
+ if (ret == _SUCCESS)
+ mod_timer(&adapter->mlmepriv.assoc_timer,
+ jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
+
+ return ret;
+}
+
+int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
+{
+ struct rtw_adapter *adapter;
+ struct wlan_network *candidate = NULL;
+ int ret;
+
+ adapter = pmlmepriv->nic_hdl;
+
+ candidate = rtw_select_candidate_from_queue(pmlmepriv);
if (!candidate) {
DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
ret = _FAIL;
@@ -1792,21 +1759,9 @@ int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
candidate->network.DSConfig);
}
- /* check for situation of _FW_LINKED */
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!!!\n",
- __func__);
-
- rtw_disassoc_cmd23a(adapter, 0, true);
- rtw_indicate_disconnect23a(adapter);
- rtw_free_assoc_resources23a(adapter, 0);
- }
- set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
- ret = rtw_joinbss_cmd23a(adapter, candidate);
+ ret = rtw_do_join_network(adapter, candidate);
exit:
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
-
return ret;
}
@@ -1818,7 +1773,7 @@ int rtw_set_auth23a(struct rtw_adapter * adapter,
struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
int res = _SUCCESS;
- pcmd = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
+ pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
if (!pcmd) {
res = _FAIL; /* try again */
goto exit;
@@ -1954,33 +1909,25 @@ exit:
/* adjust IEs for rtw_joinbss_cmd23a in WMM */
int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint initial_out_len)
+ u8 *out_ie, uint in_len, uint initial_out_len)
{
- unsigned int ielength = 0;
- unsigned int i, j;
+ int ielength;
+ const u8 *p;
- i = 12; /* after the fixed IE */
- while (i < in_len) {
- ielength = initial_out_len;
+ ielength = initial_out_len;
- /* WMM element ID and OUI */
- if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
- in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
- in_ie[i + 5] == 0x02 && i+5 < in_len) {
+ p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WMM,
+ in_ie, in_len);
- /* Append WMM IE to the last index of out_ie */
- for (j = i; j < i + 9; j++) {
- out_ie[ielength] = in_ie[j];
- ielength++;
- }
- out_ie[initial_out_len + 1] = 0x07;
- out_ie[initial_out_len + 6] = 0x00;
- out_ie[initial_out_len + 8] = 0x00;
+ if (p && p[1]) {
+ memcpy(out_ie + initial_out_len, p, 9);
- break;
- }
+ out_ie[initial_out_len + 1] = 7;
+ out_ie[initial_out_len + 6] = 0;
+ out_ie[initial_out_len + 8] = 0;
- i += (in_ie[i + 1] + 2); /* to the next IE element */
+ ielength += 9;
}
return ielength;
@@ -2037,7 +1984,7 @@ static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
{
struct security_priv *psecuritypriv = &Adapter->securitypriv;
- if (ie[13] <= 20) {
+ if (ie[1] <= 20) {
/* The RSN IE didn't include the PMK ID,
append the PMK information */
ie[ie_len] = 1;
@@ -2048,7 +1995,7 @@ static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
&psecuritypriv->PMKIDList[iEntry].PMKID, 16);
ie_len += 16;
- ie[13] += 18;/* PMKID length = 2+16 */
+ ie[1] += 18;/* PMKID length = 2+16 */
}
return ie_len;
}
@@ -2068,15 +2015,13 @@ int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
("+rtw_restruct_sec_ie23a: ndisauthmode=%d "
"ndissecuritytype=%d\n", ndisauthmode, ndissecuritytype));
- /* copy fixed ie only */
- memcpy(out_ie, in_ie, 12);
- ielength = 12;
+ ielength = 0;
if (ndisauthmode == Ndis802_11AuthModeWPA ||
ndisauthmode == Ndis802_11AuthModeWPAPSK)
authmode = WLAN_EID_VENDOR_SPECIFIC;
if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
ndisauthmode == Ndis802_11AuthModeWPA2PSK)
- authmode = _WPA2_IE_ID_;
+ authmode = WLAN_EID_RSN;
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
memcpy(out_ie + ielength, psecuritypriv->wps_ie,
@@ -2084,7 +2029,7 @@ int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
ielength += psecuritypriv->wps_ie_len;
} else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
- authmode == _WPA2_IE_ID_) {
+ authmode == WLAN_EID_RSN) {
/* copy RSN or SSN */
memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
psecuritypriv->supplicant_ie[1] + 2);
@@ -2095,7 +2040,7 @@ int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
if (iEntry < 0)
return ielength;
else {
- if (authmode == _WPA2_IE_ID_)
+ if (authmode == WLAN_EID_RSN)
ielength = rtw_append_pmkid(adapter, iEntry,
out_ie, ielength);
}
@@ -2115,7 +2060,7 @@ void rtw_init_registrypriv_dev_network23a(struct rtw_adapter* adapter)
memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
sizeof(struct cfg80211_ssid));
- pdev_network->BeaconPeriod = 100;
+ pdev_network->beacon_interval = 100;
}
void rtw_update_registrypriv_dev_network23a(struct rtw_adapter* adapter)
@@ -2157,12 +2102,7 @@ void rtw_update_registrypriv_dev_network23a(struct rtw_adapter* adapter)
/* pdev_network->IELength = cpu_to_le32(sz); */
}
-void rtw_get_encrypt_decrypt_from_registrypriv23a(struct rtw_adapter* adapter)
-{
-
-}
-
-/* the fucntion is at passive_level */
+/* the function is at passive_level */
void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
{
u8 threshold;
@@ -2191,30 +2131,31 @@ void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
}
-/* the fucntion is >= passive_level */
-unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint *pout_len)
+/* the function is >= passive_level */
+bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint *pout_len)
{
u32 out_len;
int max_rx_ampdu_factor;
unsigned char *pframe;
const u8 *p;
struct ieee80211_ht_cap ht_capie;
- unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
phtpriv->ht_option = false;
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie + 12, in_len -12);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
if (p && p[1] > 0) {
u32 rx_packet_offset, max_recvbuf_sz;
if (pmlmepriv->qos_option == 0) {
out_len = *pout_len;
pframe = rtw_set_ie23a(out_ie + out_len,
- WLAN_EID_VENDOR_SPECIFIC,
- _WMM_IE_Length_, WMM_IE, pout_len);
+ WLAN_EID_VENDOR_SPECIFIC,
+ sizeof(WMM_IE), WMM_IE,
+ pout_len);
pmlmepriv->qos_option = 1;
}
@@ -2250,9 +2191,8 @@ unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
phtpriv->ht_option = true;
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie + 12,
- in_len -12);
- if (p && (p[1] == sizeof(struct ieee80211_ht_addt_info))) {
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
+ if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
out_len = *pout_len;
pframe = rtw_set_ie23a(out_ie + out_len,
WLAN_EID_HT_OPERATION,
@@ -2263,19 +2203,18 @@ unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
return phtpriv->ht_option;
}
-/* the fucntion is > passive_level (in critical_section) */
+/* the function is > passive_level (in critical_section) */
void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
{
u8 max_ampdu_sz;
const u8 *p;
struct ieee80211_ht_cap *pht_capie;
- struct ieee80211_ht_addt_info *pht_addtinfo;
+ struct ieee80211_ht_operation *pht_addtinfo;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- int bcn_fixed_size;
if (!phtpriv->ht_option)
return;
@@ -2285,16 +2224,8 @@ void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
DBG_8723A("+rtw_update_ht_cap23a()\n");
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
- /* Adjust pie + ie_len for our searches */
- pie += bcn_fixed_size;
- ie_len -= bcn_fixed_size;
-
/* maybe needs check if ap supports rx ampdu. */
- if (phtpriv->ampdu_enable == false &&
- pregistrypriv->ampdu_enable == 1) {
+ if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
if (pregistrypriv->wifi_spec == 1)
phtpriv->ampdu_enable = false;
else
@@ -2317,35 +2248,38 @@ void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
if (p && p[1] > 0) {
- pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
+ pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
/* todo: */
}
/* update cur_bwmode & cur_ch_offset */
if (pregistrypriv->cbw40_enable &&
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1) &&
- pmlmeinfo->HT_info.infos[0] & BIT(2)) {
+ pmlmeinfo->ht_cap.cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+ pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
int i;
u8 rf_type;
rf_type = rtl8723a_get_rf_type(padapter);
/* update the MCS rates */
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
if (rf_type == RF_1T1R || rf_type == RF_1T2R)
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R23A[i];
+ pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
+ MCS_rate_1R23A[i];
else
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R23A[i];
+ pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
+ MCS_rate_2R23A[i];
}
- /* switch to the 40M Hz mode accoring to the AP */
+ /* switch to the 40M Hz mode according to the AP */
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
- {
- case HT_EXTCHNL_OFFSET_UPPER:
+ switch (pmlmeinfo->HT_info.ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
break;
- case HT_EXTCHNL_OFFSET_LOWER:
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
break;
@@ -2359,15 +2293,18 @@ void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
/* */
/* Config SM Power Save setting */
/* */
- pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &
- 0x0C) >> 2;
+ pmlmeinfo->SM_PS =
+ (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
+ IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
/* */
/* Config current HT Protection mode. */
/* */
- pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
+ pmlmeinfo->HT_protection =
+ le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
+ IEEE80211_HT_OP_MODE_PROTECTION;
}
void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
@@ -2405,7 +2342,7 @@ void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
phtpriv = &psta->htpriv;
- if (phtpriv->ht_option == true && phtpriv->ampdu_enable == true) {
+ if (phtpriv->ht_option && phtpriv->ampdu_enable) {
issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
index e1b28a234259..c5fdcb89dacd 100644
--- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
@@ -61,6 +61,8 @@ static void start_clnt_assoc(struct rtw_adapter *padapter);
static void start_clnt_auth(struct rtw_adapter *padapter);
static void start_clnt_join(struct rtw_adapter *padapter);
static void start_create_ibss(struct rtw_adapter *padapter);
+static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame);
#ifdef CONFIG_8723AU_AP_MODE
static int OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame);
@@ -107,12 +109,12 @@ static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
OUI definitions for the vendor specific IE
***************************************************/
unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
-unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
-unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
-unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
+unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
+unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
+unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
-unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
+unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
+unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
@@ -120,49 +122,87 @@ static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
MCS rate definitions
*********************************************************/
unsigned char MCS_rate_2R23A[16] = {
- 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
unsigned char MCS_rate_1R23A[16] = {
- 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+ 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
/********************************************************
ChannelPlan definitions
*********************************************************/
-static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
- {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
- {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
+static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
+ /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
+ /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
+ /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
+ /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
+ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
+ /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
+ {{10, 11, 12, 13}, 4},
+ /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
+ {{}, 0},
};
-static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
- {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
- {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
- {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
- {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
- {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
- {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
- {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
- {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
-
- /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
- {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
- {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
- {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
+static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
+ /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
+ {{}, 0},
+ /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 136, 140}, 19},
+ /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
+ /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
+ /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
+ /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
+ {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
+ /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
+ /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
+ /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
+ {{149, 153, 157, 161, 165}, 5},
+ /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
+ {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
+ /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 136, 140, 149, 153, 157, 161, 165}, 20},
+ /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 149, 153, 157, 161, 165}, 20},
+ /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 120, 124, 128, 132, 136, 140}, 19},
+ /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
+ {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
+ /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
+ {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
+ /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
+ {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
+ 153, 157, 161, 165}, 15},
+ /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
+ {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
+
+ /* Driver self defined for old channel plan Compatible,
+ Remember to modify if have new channel plan definition ===== */
+ /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
+ {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
+ 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
+ /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
+ {{36, 40, 44, 48}, 4},
+ /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
+ {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
};
-static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
+static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
/* 0x00 ~ 0x1F , Old Define ===== */
{0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
{0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
@@ -233,7 +273,8 @@ static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
{0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
};
-static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
+static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
+{0x03, 0x02}; /* use the conbination for max channel numbers */
static void dummy_event_callback(struct rtw_adapter *adapter, const u8 *pbuf)
{
@@ -250,8 +291,7 @@ static struct fwevent wlanevents[] =
{0, NULL},
{0, NULL},
{0, &rtw_survey_event_cb23a}, /*8*/
- {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a}, /*9*/
-
+ {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a},
{0, &rtw23a_joinbss_event_cb}, /*10*/
{sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
{sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
@@ -309,7 +349,7 @@ Following are the initialization functions for WiFi MLME
int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
@@ -318,7 +358,7 @@ int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
unsigned char mixed_datarate[NumRates] = {
_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
@@ -353,7 +393,7 @@ static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
pmlmeext->sitesurvey_res.bss_cnt = 0;
pmlmeext->scan_abort = false;
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
pmlmeinfo->reauth_count = 0;
pmlmeinfo->reassoc_count = 0;
pmlmeinfo->link_count = 0;
@@ -391,8 +431,8 @@ static int has_channel(struct rt_channel_info *channel_set,
static void init_channel_list(struct rtw_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 },
@@ -526,7 +566,7 @@ static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
{
- int res = _SUCCESS;
+ int res = _SUCCESS;
struct registry_priv* pregistrypriv = &padapter->registrypriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -751,7 +791,6 @@ OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
struct sta_priv *pstapriv = &padapter->stapriv;
struct sk_buff *skb = precv_frame->pkt;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- u8 *pframe = skb->data;
int pkt_len = skb->len;
struct wlan_bssid_ex *pbss;
int ret = _SUCCESS;
@@ -788,16 +827,11 @@ OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
/* we should update current network before auth,
or some IE is wrong */
- pbss = (struct wlan_bssid_ex *)
- kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
+ pbss = collect_bss_info(padapter, precv_frame);
if (pbss) {
- if (collect_bss_info23a(padapter, precv_frame, pbss) ==
- _SUCCESS) {
- update_network23a(
- &pmlmepriv->cur_network.network, pbss,
- padapter, true);
- rtw_get_bcn_info23a(&pmlmepriv->cur_network);
- }
+ update_network23a(&pmlmepriv->cur_network.network, pbss,
+ padapter, true);
+ rtw_get_bcn_info23a(&pmlmepriv->cur_network);
kfree(pbss);
}
@@ -815,12 +849,12 @@ OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
return _SUCCESS;
}
- if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
+ if (((pmlmeinfo->state & 0x03) == MSR_AP) &&
(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
if (psta) {
ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
- if (!ret) {
+ if (ret != _SUCCESS) {
DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
"disconnect now\n");
receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
@@ -831,11 +865,11 @@ OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
the number of the beacon received */
if ((sta_rx_pkts(psta) & 0xf) == 0) {
/* DBG_8723A("update_bcn_info\n"); */
- update_beacon23a_info(padapter, pframe,
+ update_beacon23a_info(padapter, mgmt,
pkt_len, psta);
}
}
- } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
+ } else if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
if (psta) {
/* update WMM, ERP in the beacon */
@@ -843,7 +877,7 @@ OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
number of the beacon received */
if ((sta_rx_pkts(psta) & 0xf) == 0) {
/* DBG_8723A("update_bcn_info\n"); */
- update_beacon23a_info(padapter, pframe,
+ update_beacon23a_info(padapter, mgmt,
pkt_len, psta);
}
} else {
@@ -891,7 +925,7 @@ OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
u16 auth_mode, seq, algorithm;
int status, len = skb->len;
- if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) != MSR_AP)
return _FAIL;
DBG_8723A("+OnAuth23a\n");
@@ -1053,7 +1087,7 @@ auth_fail:
pstat = &stat;
memset((char *)pstat, '\0', sizeof(stat));
pstat->auth_seq = 2;
- memcpy(pstat->hwaddr, sa, 6);
+ ether_addr_copy(pstat->hwaddr, sa);
issue_auth(padapter, pstat, (unsigned short)status);
@@ -1170,11 +1204,11 @@ static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
/* Microsoft/Wi-Fi information elements are further typed and
* subtyped */
switch (pos[3]) {
- case 1:
+ case WLAN_OUI_TYPE_MICROSOFT_WPA:
/* Microsoft OUI (00:50:F2) with OUI Type 1:
* real WPA information element */
break;
- case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
+ case WLAN_OUI_TYPE_MICROSOFT_WMM:
if (elen < 5) {
DBG_8723A("short WME information element "
"ignored (len =%i)\n", elen);
@@ -1193,7 +1227,7 @@ static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
return -EINVAL;
}
break;
- case 4:
+ case WLAN_OUI_TYPE_MICROSOFT_WPS:
/* Wi-Fi Protected Setup (WPS) IE */
break;
default:
@@ -1255,6 +1289,7 @@ static int rtw_validate_frame_ies(const u8 *start, uint len)
case WLAN_EID_CHALLENGE:
case WLAN_EID_ERP_INFO:
case WLAN_EID_EXT_SUPP_RATES:
+ break;
case WLAN_EID_VENDOR_SPECIFIC:
if (rtw_validate_vendor_specific_ies(pos, elen))
unknown++;
@@ -1292,7 +1327,6 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
u16 capab_info, listen_interval;
struct sta_info *pstat;
unsigned char reassoc;
- unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
int i, wpa_ie_len, left;
unsigned char supportRate[16];
int supportRateNum;
@@ -1310,7 +1344,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
uint pkt_len = skb->len;
int r;
- if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) != MSR_AP)
return _FAIL;
left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
@@ -1500,31 +1534,6 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
"Association Request - possible WPS use\n");
pstat->flags |= WLAN_STA_MAYBE_WPS;
}
-
- /* AP support WPA/RSN, and sta is going to do WPS, but AP
- is not ready */
- /* that the selected registrar of AP is _FLASE */
- if (psecuritypriv->wpa_psk > 0 &&
- pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)) {
- if (pmlmepriv->wps_beacon_ie) {
- u8 selected_registrar = 0;
-
- rtw_get_wps_attr_content23a(
- pmlmepriv->wps_beacon_ie,
- pmlmepriv->wps_beacon_ie_len,
- WPS_ATTR_SELECTED_REGISTRAR,
- &selected_registrar, NULL);
-
- if (!selected_registrar) {
- DBG_8723A("selected_registrar is false,"
- "or AP is not ready to do "
- "WPS\n");
-
- status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
- goto OnAssocReq23aFail;
- }
- }
- }
} else {
int copy_len;
@@ -1567,47 +1576,46 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
for (;;) {
left = end - p;
- p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p, left);
+ p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WMM,
+ p, left);
if (p) {
- if (!memcmp(p + 2, WMM_IE, 6)) {
- pstat->flags |= WLAN_STA_WME;
+ pstat->flags |= WLAN_STA_WME;
- pstat->qos_option = 1;
- pstat->qos_info = *(p + 8);
+ pstat->qos_option = 1;
+ pstat->qos_info = *(p + 8);
- pstat->max_sp_len =
- (pstat->qos_info >> 5) & 0x3;
+ pstat->max_sp_len =
+ (pstat->qos_info >> 5) & 0x3;
- if ((pstat->qos_info & 0xf) != 0xf)
- pstat->has_legacy_ac = true;
- else
- pstat->has_legacy_ac = false;
-
- if (pstat->qos_info & 0xf) {
- if (pstat->qos_info & BIT(0))
- pstat->uapsd_vo = BIT(0)|BIT(1);
- else
- pstat->uapsd_vo = 0;
+ if ((pstat->qos_info & 0xf) != 0xf)
+ pstat->has_legacy_ac = true;
+ else
+ pstat->has_legacy_ac = false;
- if (pstat->qos_info & BIT(1))
- pstat->uapsd_vi = BIT(0)|BIT(1);
- else
- pstat->uapsd_vi = 0;
+ if (pstat->qos_info & 0xf) {
+ if (pstat->qos_info & BIT(0))
+ pstat->uapsd_vo = BIT(0)|BIT(1);
+ else
+ pstat->uapsd_vo = 0;
- if (pstat->qos_info & BIT(2))
- pstat->uapsd_bk = BIT(0)|BIT(1);
- else
- pstat->uapsd_bk = 0;
+ if (pstat->qos_info & BIT(1))
+ pstat->uapsd_vi = BIT(0)|BIT(1);
+ else
+ pstat->uapsd_vi = 0;
- if (pstat->qos_info & BIT(3))
- pstat->uapsd_be = BIT(0)|BIT(1);
- else
- pstat->uapsd_be = 0;
+ if (pstat->qos_info & BIT(2))
+ pstat->uapsd_bk = BIT(0)|BIT(1);
+ else
+ pstat->uapsd_bk = 0;
- }
+ if (pstat->qos_info & BIT(3))
+ pstat->uapsd_be = BIT(0)|BIT(1);
+ else
+ pstat->uapsd_be = 0;
- break;
}
+ break;
} else {
break;
}
@@ -1629,7 +1637,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
} else
pstat->flags &= ~WLAN_STA_HT;
- if (pmlmepriv->htpriv.ht_option == false && pstat->flags & WLAN_STA_HT){
+ if (!pmlmepriv->htpriv.ht_option && pstat->flags & WLAN_STA_HT){
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto OnAssocReq23aFail;
}
@@ -1768,11 +1776,12 @@ OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sk_buff *skb = precv_frame->pkt;
struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
- int res, i;
+ int res;
unsigned short status;
- u8 *p;
+ const u8 *p, *pie;
u8 *pframe = skb->data;
int pkt_len = skb->len;
+ int pielen;
DBG_8723A("%s\n", __func__);
@@ -1792,7 +1801,7 @@ OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
if (status > 0) {
DBG_8723A("assoc reject, status code: %d\n", status);
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
res = -4;
goto report_assoc_result;
}
@@ -1806,38 +1815,45 @@ OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
/* AID */
res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
- /* following are moved to join event callback function */
- /* to handle HT, WMM, rate adaptive, update MAC reg */
- /* for not to handle the synchronous IO in the tasklet */
- for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
- i < pkt_len;) {
- p = pframe + i;
-
- switch (p[0])
- {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (!memcmp(p + 2, WMM_PARA_OUI23A, 6))/* WMM */
- WMM_param_handler23a(padapter, p);
- break;
-
- case WLAN_EID_HT_CAPABILITY: /* HT caps */
- HT_caps_handler23a(padapter, p);
+ pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+ pielen = pkt_len -
+ offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ pmgmt->u.assoc_resp.variable, pielen);
+ if (p && p[1])
+ HT_caps_handler23a(padapter, p);
+
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ pmgmt->u.assoc_resp.variable, pielen);
+ if (p && p[1])
+ HT_info_handler23a(padapter, p);
+
+ p = cfg80211_find_ie(WLAN_EID_ERP_INFO,
+ pmgmt->u.assoc_resp.variable, pielen);
+ if (p && p[1])
+ ERP_IE_handler23a(padapter, p);
+
+ pie = pframe + offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+ while (true) {
+ p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WMM,
+ pie, pframe + pkt_len - pie);
+ if (!p)
break;
- case WLAN_EID_HT_OPERATION: /* HT info */
- HT_info_handler23a(padapter, p);
+ pie = p + p[1] + 2;
+ /* if this IE is too short, try the next */
+ if (p[1] <= 4)
+ continue;
+ /* if this IE is WMM params, we found what we wanted */
+ if (p[6] == 1)
break;
-
- case WLAN_EID_ERP_INFO:
- ERP_IE_handler23a(padapter, p);
-
- default:
- break;
- }
-
- i += (p[1] + 2);
}
+ if (p && p[1])
+ WMM_param_handler23a(padapter, p);
+
pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
@@ -1920,7 +1936,7 @@ OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
static int
OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
{
- unsigned short reason;
+ unsigned short reason;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -2017,7 +2033,7 @@ static int OnAction23a_back23a(struct rtw_adapter *padapter,
DBG_8723A("%s\n", __func__);
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) != MSR_AP)
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
return _SUCCESS;
@@ -2090,136 +2106,32 @@ static int OnAction23a_back23a(struct rtw_adapter *padapter,
return _SUCCESS;
}
-static int rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
-{
- struct rtw_adapter *adapter = recv_frame->adapter;
- struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
- struct sk_buff *skb = recv_frame->pkt;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- u16 seq_ctrl;
-
- seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
- (recv_frame->attrib.frag_num & 0xf);
-
- if (ieee80211_has_retry(hdr->frame_control)) {
- if (token >= 0) {
- if ((seq_ctrl == mlmeext->action_public_rxseq) &&
- (token == mlmeext->action_public_dialog_token)) {
- DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
- "rxseq = 0x%x, token:%d\n", __func__,
- adapter->pnetdev->name, seq_ctrl,
- mlmeext->action_public_rxseq, token);
- return _FAIL;
- }
- } else {
- if (seq_ctrl == mlmeext->action_public_rxseq) {
- DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
- "rxseq = 0x%x\n", __func__,
- adapter->pnetdev->name, seq_ctrl,
- mlmeext->action_public_rxseq);
- return _FAIL;
- }
- }
- }
-
- mlmeext->action_public_rxseq = seq_ctrl;
-
- if (token >= 0)
- mlmeext->action_public_dialog_token = token;
-
- return _SUCCESS;
-}
-
-static int on_action_public23a_p2p(struct recv_frame *precv_frame)
-{
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- u8 *frame_body;
- u8 dialogToken = 0;
-
- frame_body = (unsigned char *)
- (pframe + sizeof(struct ieee80211_hdr_3addr));
-
- dialogToken = frame_body[7];
-
- if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
- return _FAIL;
-
- return _SUCCESS;
-}
-
-static int on_action_public23a_vendor(struct recv_frame *precv_frame)
-{
- unsigned int ret = _FAIL;
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
-
- if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
- ret = on_action_public23a_p2p(precv_frame);
- }
-
- return ret;
-}
-
-static unsigned int
-on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
-{
- unsigned int ret = _FAIL;
- struct sk_buff *skb = precv_frame->pkt;
- u8 *pframe = skb->data;
- uint frame_len = skb->len;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
- u8 token;
- struct rtw_adapter *adapter = precv_frame->adapter;
- int cnt = 0;
- char msg[64];
-
- token = frame_body[2];
-
- if (rtw_action_public_decache(precv_frame, token) == _FAIL)
- goto exit;
-
- cnt += sprintf((msg+cnt), "%s(token:%u)",
- action_public_str23a(action), token);
- rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
-
- ret = _SUCCESS;
-
-exit:
- return ret;
-}
-
static int on_action_public23a(struct rtw_adapter *padapter,
struct recv_frame *precv_frame)
{
- int ret = _FAIL;
struct sk_buff *skb = precv_frame->pkt;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
u8 *pframe = skb->data;
- u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
- u8 category, action;
+ int freq, channel;
/* check RA matches or not */
if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
- goto exit;
+ return _FAIL;
- category = frame_body[0];
- if (category != WLAN_CATEGORY_PUBLIC)
- goto exit;
+ channel = rtw_get_oper_ch23a(padapter);
- action = frame_body[1];
- switch (action) {
- case ACT_PUBLIC_VENDOR:
- ret = on_action_public23a_vendor(precv_frame);
- break;
- default:
- ret = on_action_public23a_default(precv_frame, action);
- break;
- }
+ if (channel <= RTW_CH_MAX_2G_CHANNEL)
+ freq = ieee80211_channel_to_frequency(channel,
+ IEEE80211_BAND_2GHZ);
+ else
+ freq = ieee80211_channel_to_frequency(channel,
+ IEEE80211_BAND_5GHZ);
-exit:
- return ret;
+ if (cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pframe,
+ skb->len, 0, GFP_ATOMIC))
+ return _SUCCESS;
+
+ return _FAIL;
}
static int
@@ -2301,7 +2213,7 @@ exit:
/****************************************************************************
-Following are some TX fuctions for WiFi MLME
+Following are some TX functions for WiFi MLME
*****************************************************************************/
@@ -2452,7 +2364,7 @@ void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
unsigned int rate_len;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -2460,8 +2372,7 @@ void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- u8 *wps_ie;
- u32 wps_ielen;
+ const u8 *wps_ie;
u8 sr = 0;
int len_diff;
@@ -2484,39 +2395,48 @@ void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_BEACON);
- pwlanhdr->seq_ctrl = 0;
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+ mgmt->seq_ctrl = 0;
- ether_addr_copy(pwlanhdr->addr1, bc_addr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
+ ether_addr_copy(mgmt->da, bc_addr);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
+ /* timestamp will be inserted by hardware */
+
+ put_unaligned_le16(cur_network->beacon_interval,
+ &mgmt->u.beacon.beacon_int);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
+ put_unaligned_le16(cur_network->capability,
+ &mgmt->u.beacon.capab_info);
+
+ pframe = mgmt->u.beacon.variable;
+ pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+
+ if ((pmlmeinfo->state & 0x03) == MSR_AP) {
+ u8 *iebuf;
+ int buflen;
/* DBG_8723A("ie len =%d\n", cur_network->IELength); */
memcpy(pframe, cur_network->IEs, cur_network->IELength);
- len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
- cur_network->IELength -
- _BEACON_IE_OFFSET_,
+ len_diff = update_hidden_ssid(pframe, cur_network->IELength,
pmlmeinfo->hidden_ssid_mode);
pframe += (cur_network->IELength+len_diff);
pattrib->pktlen += (cur_network->IELength+len_diff);
- wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
- sizeof (struct ieee80211_hdr_3addr) +
- _BEACON_IE_OFFSET_, pattrib->pktlen -
- sizeof (struct ieee80211_hdr_3addr) -
- _BEACON_IE_OFFSET_, NULL,
- &wps_ielen);
- if (wps_ie && wps_ielen > 0) {
- rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
+ iebuf = mgmt->u.beacon.variable;
+ buflen = pattrib->pktlen -
+ offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ iebuf, buflen);
+
+ if (wps_ie && wps_ie[1] > 0) {
+ rtw_get_wps_attr_content23a(wps_ie, wps_ie[1],
WPS_ATTR_SELECTED_REGISTRAR,
- (u8*)&sr, NULL);
+ (u8*)&sr);
}
if (sr != 0)
set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
@@ -2526,28 +2446,6 @@ void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
goto _issue_bcn;
}
- /* below for ad-hoc mode */
-
- /* timestamp will be inserted by hardware */
- pframe += 8;
- pattrib->pktlen += 8;
-
- /* beacon interval: 2 bytes */
-
- memcpy(pframe, (unsigned char *)
- rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
-
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* capability info: 2 bytes */
-
- memcpy(pframe, (unsigned char *)
- rtw_get_capability23a_from_ie(cur_network->IEs), 2);
-
- pframe += 2;
- pattrib->pktlen += 2;
-
/* SSID */
pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
cur_network->Ssid.ssid_len,
@@ -2563,7 +2461,7 @@ void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
&cur_network->DSConfig, &pattrib->pktlen);
- /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
+ /* if ((pmlmeinfo->state&0x03) == MSR_ADHOC) */
{
u8 erpinfo = 0;
u32 ATIMWindow;
@@ -2616,18 +2514,15 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
unsigned char *mac, *bssid;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
#ifdef CONFIG_8723AU_AP_MODE
- u8 *pwps_ie;
- uint wps_ielen;
+ const u8 *pwps_ie;
u8 *ssid_ie;
int ssid_ielen;
int ssid_ielen_diff;
u8 buf[MAX_IE_SZ];
- u8 *ies;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
#endif
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -2636,6 +2531,9 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
/* DBG_8723A("%s\n", __func__); */
+ if (cur_network->IELength > MAX_IE_SZ)
+ return;
+
pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
if (!pmgntframe) {
DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
@@ -2649,81 +2547,52 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
mac = myid(&padapter->eeprompriv);
bssid = cur_network->MacAddress;
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr2, mac);
- ether_addr_copy(pwlanhdr->addr3, bssid);
+ ether_addr_copy(mgmt->da, da);
+ ether_addr_copy(mgmt->sa, mac);
+ ether_addr_copy(mgmt->bssid, bssid);
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = pattrib->hdrlen;
- pframe += pattrib->hdrlen;
- if (cur_network->IELength > MAX_IE_SZ)
- return;
+ /* timestamp will be inserted by hardware */
+ put_unaligned_le16(cur_network->beacon_interval,
+ &mgmt->u.probe_resp.beacon_int);
+
+ put_unaligned_le16(cur_network->capability,
+ &mgmt->u.probe_resp.capab_info);
+
+ pframe = mgmt->u.probe_resp.variable;
+ pattrib->pktlen =
+ offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+
+ /* below for ad-hoc mode */
#ifdef CONFIG_8723AU_AP_MODE
- if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
- pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
- _FIXED_IE_LENGTH_,
- cur_network->IELength -
- _FIXED_IE_LENGTH_, NULL,
- &wps_ielen);
-
- /* inerset & update wps_probe_resp_ie */
- if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
- uint wps_offset, remainder_ielen;
- u8 *premainder_ie;
-
- wps_offset = (uint)(pwps_ie - cur_network->IEs);
-
- premainder_ie = pwps_ie + wps_ielen;
-
- remainder_ielen = cur_network->IELength - wps_offset -
- wps_ielen;
-
- memcpy(pframe, cur_network->IEs, wps_offset);
- pframe += wps_offset;
- pattrib->pktlen += wps_offset;
-
- /* to get ie data len */
- wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
- if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
- memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
- wps_ielen+2);
- pframe += wps_ielen+2;
- pattrib->pktlen += wps_ielen+2;
- }
+ if ((pmlmeinfo->state & 0x03) == MSR_AP) {
+ pwps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ cur_network->IEs,
+ cur_network->IELength);
- if (wps_offset + wps_ielen + 2 + remainder_ielen <=
- MAX_IE_SZ) {
- memcpy(pframe, premainder_ie, remainder_ielen);
- pframe += remainder_ielen;
- pattrib->pktlen += remainder_ielen;
- }
- } else {
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
- pframe += cur_network->IELength;
- pattrib->pktlen += cur_network->IELength;
- }
+ memcpy(pframe, cur_network->IEs, cur_network->IELength);
+ pframe += cur_network->IELength;
+ pattrib->pktlen += cur_network->IELength;
/* retrieve SSID IE from cur_network->Ssid */
- ies = pmgntframe->buf_addr + TXDESC_OFFSET +
- sizeof(struct ieee80211_hdr_3addr);
- ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
- &ssid_ielen,
- pframe - ies - _FIXED_IE_LENGTH_);
+ ssid_ie = rtw_get_ie23a(mgmt->u.probe_resp.variable,
+ WLAN_EID_SSID, &ssid_ielen,
+ pframe - mgmt->u.probe_resp.variable);
ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
@@ -2752,29 +2621,6 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
} else
#endif
{
-
- /* timestamp will be inserted by hardware */
- pframe += 8;
- pattrib->pktlen += 8;
-
- /* beacon interval: 2 bytes */
-
- memcpy(pframe, (unsigned char *)
- rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
-
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* capability info: 2 bytes */
-
- memcpy(pframe, (unsigned char *)
- rtw_get_capability23a_from_ie(cur_network->IEs), 2);
-
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* below for ad-hoc mode */
-
/* SSID */
pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
cur_network->Ssid.ssid_len,
@@ -2793,7 +2639,7 @@ static void issue_probersp(struct rtw_adapter *padapter, unsigned char *da,
(unsigned char *)&cur_network->DSConfig,
&pattrib->pktlen);
- if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
+ if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
u8 erpinfo = 0;
u32 ATIMWindow;
/* IBSS Parameter Set... */
@@ -2829,17 +2675,17 @@ static int _issue_probereq(struct rtw_adapter *padapter,
struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
{
int ret = _FAIL;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
- unsigned char *mac;
- unsigned char bssrate[NumRates];
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ unsigned char *pframe;
+ struct ieee80211_hdr *pwlanhdr;
+ unsigned char *mac;
+ unsigned char bssrate[NumRates];
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- int bssrate_len = 0;
- u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ int bssrate_len = 0;
+ u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
("+%s\n", __func__));
@@ -2985,9 +2831,9 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
unsigned int val32;
- unsigned short val16;
+ u16 auth_algo;
int use_shared_key = 0;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -3004,23 +2850,21 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_AUTH);
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.auth.variable);
if (psta) { /* for AP mode */
#ifdef CONFIG_8723AU_AP_MODE
-
- ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
+ unsigned short val16;
+ ether_addr_copy(mgmt->da, psta->hwaddr);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, myid(&padapter->eeprompriv));
/* setting auth algo number */
val16 = (u16)psta->authalg;
@@ -3028,29 +2872,19 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
if (status != WLAN_STATUS_SUCCESS)
val16 = 0;
- if (val16) {
- val16 = cpu_to_le16(val16);
+ if (val16)
use_shared_key = 1;
- }
- pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ mgmt->u.auth.auth_alg = cpu_to_le16(val16);
/* setting auth seq number */
- val16 = (u16)psta->auth_seq;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ mgmt->u.auth.auth_transaction =
+ cpu_to_le16((u16)psta->auth_seq);
/* setting status code... */
- val16 = status;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ mgmt->u.auth.status_code = cpu_to_le16(status);
+ pframe = mgmt->u.auth.variable;
/* added challenging text... */
if ((psta->auth_seq == 2) &&
(psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
@@ -3058,19 +2892,21 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
psta->chg_txt, &pattrib->pktlen);
#endif
} else {
- ether_addr_copy(pwlanhdr->addr1,
- get_my_bssid23a(&pmlmeinfo->network));
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3,
+ struct ieee80211_mgmt *iv_mgmt;
+
+ ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid,
get_my_bssid23a(&pmlmeinfo->network));
/* setting auth algo number */
/* 0:OPEN System, 1:Shared key */
- val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
- if (val16) {
- val16 = cpu_to_le16(val16);
+ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
use_shared_key = 1;
- }
+ auth_algo = WLAN_AUTH_SHARED_KEY;
+ } else
+ auth_algo = WLAN_AUTH_OPEN;
+
/* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
(pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
pmlmeinfo->auth_seq); */
@@ -3079,35 +2915,32 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
if ((pmlmeinfo->auth_seq == 3) &&
(pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
(use_shared_key == 1)) {
+ u32 *piv = (u32 *)&mgmt->u.auth;
+
+ iv_mgmt = (struct ieee80211_mgmt *)(pframe + 4);
/* DBG_8723A("==> iv(%d), key_index(%d)\n",
pmlmeinfo->iv, pmlmeinfo->key_index); */
- val32 = ((pmlmeinfo->iv++) |
- (pmlmeinfo->key_index << 30));
- val32 = cpu_to_le32(val32);
- pframe = rtw_set_fixed_ie23a(pframe, 4,
- (unsigned char *)&val32,
- &pattrib->pktlen);
+ val32 = (pmlmeinfo->iv & 0x3fffffff) |
+ (pmlmeinfo->key_index << 30);
+ pmlmeinfo->iv++;
+ put_unaligned_le32(val32, piv);
+
+ pattrib->pktlen += 4;
pattrib->iv_len = IEEE80211_WEP_IV_LEN;
- }
+ } else
+ iv_mgmt = mgmt;
- pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ iv_mgmt->u.auth.auth_alg = cpu_to_le16(auth_algo);
/* setting auth seq number */
- val16 = pmlmeinfo->auth_seq;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ iv_mgmt->u.auth.auth_transaction =
+ cpu_to_le16(pmlmeinfo->auth_seq);
/* setting status code... */
- val16 = status;
- val16 = cpu_to_le16(val16);
- pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
- (unsigned char *)&val16,
- &pattrib->pktlen);
+ iv_mgmt->u.auth.status_code = cpu_to_le16(status);
+
+ pframe = iv_mgmt->u.auth.variable;
/* then checking to see if sending challenging text... */
if ((pmlmeinfo->auth_seq == 3) &&
@@ -3117,7 +2950,7 @@ static void issue_auth(struct rtw_adapter *padapter, struct sta_info *psta,
pmlmeinfo->chg_txt,
&pattrib->pktlen);
- pwlanhdr->frame_control |=
+ mgmt->frame_control |=
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
@@ -3144,10 +2977,9 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
struct sta_info *pstat, u16 pkt_type)
{
struct xmit_frame *pmgntframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- unsigned short val;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -3169,37 +3001,27 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | pkt_type);
- ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->da, pstat->hwaddr);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen += pattrib->hdrlen;
- pframe += pattrib->hdrlen;
+ pattrib->pktlen =
+ offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
- /* capability */
- val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
+ mgmt->u.assoc_resp.capab_info = cpu_to_le16(pnetwork->capability);
+ mgmt->u.assoc_resp.status_code = cpu_to_le16(status);
+ mgmt->u.assoc_resp.aid = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
- pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
- (unsigned char *)&val, &pattrib->pktlen);
-
- status = cpu_to_le16(status);
- pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
- (unsigned char *)&status,
- &pattrib->pktlen);
-
- val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
- pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
- &pattrib->pktlen);
+ pframe = mgmt->u.assoc_resp.variable;
if (pstat->bssratelen <= 8) {
pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
@@ -3216,9 +3038,8 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
/* FILL HT CAP INFO IE */
/* p = hostapd_eid_ht_capabilities_info(hapd, p); */
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- ie + _BEACON_IE_OFFSET_,
- pnetwork->IELength -_BEACON_IE_OFFSET_);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ie,
+ pnetwork->IELength);
if (p && p[1]) {
memcpy(pframe, p, p[1] + 2);
pframe += (p[1] + 2);
@@ -3227,9 +3048,8 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
/* FILL HT ADD INFO IE */
/* p = hostapd_eid_ht_operation(hapd, p); */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- ie + _BEACON_IE_OFFSET_,
- pnetwork->IELength - _BEACON_IE_OFFSET_);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie,
+ pnetwork->IELength);
if (p && p[1] > 0) {
memcpy(pframe, p, p[1] + 2);
pframe += (p[1] + 2);
@@ -3243,10 +3063,9 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
0x01, 0x01};
int ie_len = 0;
- for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
+ for (p = ie; ; p += (ie_len + 2)) {
p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
- pnetwork->IELength -
- _BEACON_IE_OFFSET_ - (ie_len + 2));
+ pnetwork->IELength - (ie_len + 2));
if (p)
ie_len = p[1];
else
@@ -3269,16 +3088,6 @@ static void issue_assocrsp(struct rtw_adapter *padapter, unsigned short status,
REALTEK_96B_IE, &pattrib->pktlen);
}
- /* add WPS IE ie for wps 2.0 */
- if (pmlmepriv->wps_assoc_resp_ie &&
- pmlmepriv->wps_assoc_resp_ie_len > 0) {
- memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
- pmlmepriv->wps_assoc_resp_ie_len);
-
- pframe += pmlmepriv->wps_assoc_resp_ie_len;
- pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
- }
-
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
@@ -3292,7 +3101,7 @@ static void issue_assocreq(struct rtw_adapter *padapter)
struct pkt_attrib *pattrib;
unsigned char *pframe;
const u8 *p;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
unsigned int i, j, index = 0;
unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
struct registry_priv *pregpriv = &padapter->registrypriv;
@@ -3300,7 +3109,7 @@ static void issue_assocreq(struct rtw_adapter *padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- int bssrate_len = 0, sta_bssrate_len = 0, pie_len, bcn_fixed_size;
+ int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
u8 *pie;
pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
@@ -3314,34 +3123,26 @@ static void issue_assocreq(struct rtw_adapter *padapter)
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ASSOC_REQ);
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);
- ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->da, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
/* caps */
- memcpy(pframe,
- rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
-
- pframe += 2;
- pattrib->pktlen += 2;
-
- /* listen interval */
+ put_unaligned_le16(pmlmeinfo->network.capability,
+ &mgmt->u.assoc_req.capab_info);
/* todo: listen interval for power saving */
- put_unaligned_le16(3, pframe);
- pframe += 2;
- pattrib->pktlen += 2;
+ put_unaligned_le16(3, &mgmt->u.assoc_req.listen_interval);
+
+ pframe = mgmt->u.assoc_req.variable;
+ pattrib->pktlen = offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
/* SSID */
pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
@@ -3416,11 +3217,9 @@ static void issue_assocreq(struct rtw_adapter *padapter)
bssrate_len, bssrate, &pattrib->pktlen);
/* RSN */
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
- pie = pmlmeinfo->network.IEs + bcn_fixed_size;
- pie_len = pmlmeinfo->network.IELength - bcn_fixed_size;
+ pie = pmlmeinfo->network.IEs;
+ pie_len = pmlmeinfo->network.IELength;
p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
if (p)
@@ -3428,23 +3227,26 @@ static void issue_assocreq(struct rtw_adapter *padapter)
&pattrib->pktlen);
/* HT caps */
- if (padapter->mlmepriv.htpriv.ht_option == true) {
+ if (padapter->mlmepriv.htpriv.ht_option) {
p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
if (p && !is_ap_in_tkip23a(padapter)) {
- memcpy(&pmlmeinfo->HT_caps, p + 2,
- sizeof(struct HT_caps_element));
+ struct ieee80211_ht_cap *cap = &pmlmeinfo->ht_cap;
+
+ memcpy(cap, p + 2, sizeof(struct ieee80211_ht_cap));
/* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
if (pregpriv->cbw40_enable == 0) {
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
+ cap->cap_info &= ~cpu_to_le16(
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40);
} else {
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
+ cap->cap_info |= cpu_to_le16(
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40);
}
/* todo: disable SM power save mode */
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
- 0x000c;
+ cap->cap_info |= cpu_to_le16(IEEE80211_HT_CAP_SM_PS);
rf_type = rtl8723a_get_rf_type(padapter);
/* switch (pregpriv->rf_config) */
@@ -3452,9 +3254,9 @@ static void issue_assocreq(struct rtw_adapter *padapter)
case RF_1T1R:
/* RX STBC One spatial stream */
if (pregpriv->rx_stbc)
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
+ cap->cap_info |= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
- memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
+ memcpy(&cap->mcs, MCS_rate_1R23A, 16);
break;
case RF_2T2R:
@@ -3473,29 +3275,29 @@ static void issue_assocreq(struct rtw_adapter *padapter)
pregpriv->wifi_spec == 1) {
DBG_8723A("declare supporting RX "
"STBC\n");
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
+ /* RX STBC two spatial stream */
+ cap->cap_info |= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
}
- memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
+ memcpy(&cap->mcs, MCS_rate_2R23A, 16);
break;
}
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
- cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
if (rtl8723a_BT_coexist(padapter) &&
rtl8723a_BT_using_antenna_1(padapter)) {
/* set to 8K */
- pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
-/* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
+ cap->ampdu_params_info &=
+ ~IEEE80211_HT_AMPDU_PARM_FACTOR;
+/* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
}
pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
- p[1], (u8 *)&pmlmeinfo->HT_caps,
+ p[1], (u8 *)&pmlmeinfo->ht_cap,
&pattrib->pktlen);
}
}
/* vendor specific IE, such as WPA, WMM, WPS */
- for (i = bcn_fixed_size; i < pmlmeinfo->network.IELength;) {
+ for (i = 0; i < pmlmeinfo->network.IELength;) {
p = pmlmeinfo->network.IEs + i;
switch (p[0]) {
@@ -3541,7 +3343,7 @@ exit:
kfree(pmlmepriv->assoc_req);
pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
if (pmlmepriv->assoc_req) {
- memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
+ memcpy(pmlmepriv->assoc_req, mgmt, pattrib->pktlen);
pmlmepriv->assoc_req_len = pattrib->pktlen;
}
} else
@@ -3550,7 +3352,7 @@ exit:
return;
}
-/* when wait_ack is ture, this function shoule be called at process context */
+/* when wait_ack is true, this function should be called at process context */
static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
unsigned int power_mode, int wait_ack)
{
@@ -3589,9 +3391,9 @@ static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_NULLFUNC);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) == MSR_AP)
pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
- else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
+ else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
if (power_mode)
@@ -3621,7 +3423,7 @@ exit:
return ret;
}
-/* when wait_ms >0 , this function shoule be called at process context */
+/* when wait_ms >0 , this function should be called at process context */
/* da == NULL for station mode */
int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
unsigned int power_mode, int try_cnt, int wait_ms)
@@ -3632,7 +3434,7 @@ int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- /* da == NULL, assum it's null data for sta to ap*/
+ /* da == NULL, assume it's null data for sta to ap*/
if (da == NULL)
da = get_my_bssid23a(&pmlmeinfo->network);
@@ -3674,7 +3476,7 @@ exit:
return ret;
}
-/* when wait_ack is ture, this function shoule be called at process context */
+/* when wait_ack is true, this function should be called at process context */
static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
unsigned char *da, u16 tid, int wait_ack)
{
@@ -3711,9 +3513,9 @@ static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_NULLFUNC);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) == MSR_AP)
pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
- else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
+ else if ((pmlmeinfo->state&0x03) == MSR_INFRA)
pwlanhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_TODS);
if (pattrib->mdata)
@@ -3749,7 +3551,7 @@ exit:
return ret;
}
-/* when wait_ms >0 , this function shoule be called at process context */
+/* when wait_ms >0 , this function should be called at process context */
/* da == NULL for station mode */
int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
u16 tid, int try_cnt, int wait_ms)
@@ -3760,7 +3562,7 @@ int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- /* da == NULL, assum it's null data for sta to ap*/
+ /* da == NULL, assume it's null data for sta to ap*/
if (da == NULL)
da = get_my_bssid23a(&pmlmeinfo->network);
@@ -3806,8 +3608,7 @@ static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
{
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -3826,27 +3627,21 @@ static int _issue_deauth(struct rtw_adapter *padapter, unsigned char *da,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_DEAUTH);
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
- ether_addr_copy(pwlanhdr->addr1, da);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->da, da);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 2;
- reason = cpu_to_le16(reason);
- pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
- (unsigned char *)&reason,
- &pattrib->pktlen);
+ mgmt->u.deauth.reason_code = cpu_to_le16(reason);
pattrib->last_txcmdsz = pattrib->pktlen;
@@ -3919,10 +3714,9 @@ void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
unsigned char *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- u8 category, action;
DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
@@ -3937,29 +3731,24 @@ void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
- ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
- ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
+ ether_addr_copy(mgmt->da, ra); /* RA */
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv)); /* TA */
+ ether_addr_copy(mgmt->bssid, ra); /* DA = RA */
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- /* category, action */
- category = WLAN_CATEGORY_SPECTRUM_MGMT;
- action = WLAN_ACTION_SPCT_CHL_SWITCH;
+ mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
+ mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
+ pframe = mgmt->u.action.u.chan_switch.variable;
+ pattrib->pktlen = offsetof(struct ieee80211_mgmt,
+ u.action.u.chan_switch.variable);
pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
new_ch, 0);
@@ -3975,17 +3764,15 @@ void issue_action_BA23a(struct rtw_adapter *padapter,
const unsigned char *raddr,
unsigned char action, unsigned short status)
{
- u8 category = WLAN_CATEGORY_BACK;
u16 start_seq;
u16 BA_para_set;
- u16 reason_code;
u16 BA_timeout_value;
u16 BA_starting_seqctrl;
+ u16 BA_para;
int max_rx_ampdu_factor;
struct xmit_frame *pmgntframe;
struct pkt_attrib *pattrib;
- u8 *pframe;
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -3994,8 +3781,7 @@ void issue_action_BA23a(struct rtw_adapter *padapter,
struct registry_priv *pregpriv = &padapter->registrypriv;
u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
- DBG_8723A("%s, category =%d, action =%d, status =%d\n",
- __func__, category, action, status);
+ DBG_8723A("%s, action =%d, status =%d\n", __func__, action, status);
pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
if (!pmgntframe)
@@ -4007,40 +3793,36 @@ void issue_action_BA23a(struct rtw_adapter *padapter,
memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET);
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
+ mgmt->frame_control =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
- /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
- ether_addr_copy(pwlanhdr->addr1, raddr);
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt->da, raddr);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(&pmlmeinfo->network));
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt->seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
+ mgmt->u.action.category = WLAN_CATEGORY_BACK;
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
+ pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr) + 1;
status = cpu_to_le16(status);
- if (category != 3)
- goto out;
+ switch (action) {
+ case WLAN_ACTION_ADDBA_REQ:
+ pattrib->pktlen += sizeof(mgmt->u.action.u.addba_req);
+
+ mgmt->u.action.u.addba_req.action_code = action;
- switch (action)
- {
- case 0: /* ADDBA req */
do {
pmlmeinfo->dialogToken++;
} while (pmlmeinfo->dialogToken == 0);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
- &pattrib->pktlen);
+
+ mgmt->u.action.u.addba_req.dialog_token =
+ pmlmeinfo->dialogToken;
if (rtl8723a_BT_coexist(padapter) &&
rtl8723a_BT_using_antenna_1(padapter) &&
@@ -4061,51 +3843,60 @@ void issue_action_BA23a(struct rtw_adapter *padapter,
/* immediate ack & 64 buffer size */
BA_para_set = (0x1002 | ((status & 0xf) << 2));
}
- BA_para_set = cpu_to_le16(BA_para_set);
- pframe = rtw_set_fixed_ie23a(pframe, 2,
- (unsigned char *)&BA_para_set,
- &pattrib->pktlen);
+
+ put_unaligned_le16(BA_para_set,
+ &mgmt->u.action.u.addba_req.capab);
BA_timeout_value = 5000;/* 5ms */
BA_timeout_value = cpu_to_le16(BA_timeout_value);
- pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
- &BA_timeout_value,
- &pattrib->pktlen);
+ put_unaligned_le16(BA_timeout_value,
+ &mgmt->u.action.u.addba_req.timeout);
+
+ psta = rtw_get_stainfo23a(pstapriv, raddr);
+ if (psta) {
+ int idx;
- /* if ((psta = rtw_get_stainfo23a(pstapriv,
- pmlmeinfo->network.MacAddress)) != NULL) */
- if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
- start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
+ idx = status & 0x07;
+ start_seq =
+ (psta->sta_xmitpriv.txseq_tid[idx] & 0xfff) + 1;
DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
- start_seq, status & 0x07);
+ start_seq, idx);
- psta->BA_starting_seqctrl[status & 0x07] = start_seq;
+ psta->BA_starting_seqctrl[idx] = start_seq;
BA_starting_seqctrl = start_seq << 4;
- }
+ } else
+ BA_starting_seqctrl = 0;
+
+ put_unaligned_le16(BA_starting_seqctrl,
+ &mgmt->u.action.u.addba_req.start_seq_num);
- BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
- pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
break;
- case 1: /* ADDBA rsp */
- pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 2,
- (unsigned char *)&status,
- &pattrib->pktlen);
+ case WLAN_ACTION_ADDBA_RESP:
+ pattrib->pktlen += sizeof(mgmt->u.action.u.addba_resp);
+
+ mgmt->u.action.u.addba_resp.action_code = action;
+ mgmt->u.action.u.addba_resp.dialog_token =
+ pmlmeinfo->ADDBA_req.dialog_token;
+ put_unaligned_le16(status,
+ &mgmt->u.action.u.addba_resp.status);
+
GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
&max_rx_ampdu_factor);
+
+ BA_para = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f;
if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
- BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
+ BA_para_set = BA_para | 0x1000; /* 64 buffer size */
else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
- BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
+ BA_para_set = BA_para | 0x0800; /* 32 buffer size */
else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
- BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
+ BA_para_set = BA_para | 0x0400; /* 16 buffer size */
else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
- BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
+ BA_para_set = BA_para | 0x0200; /* 8 buffer size */
else
- BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
+ BA_para_set = BA_para | 0x1000; /* 64 buffer size */
if (rtl8723a_BT_coexist(padapter) &&
rtl8723a_BT_using_antenna_1(padapter) &&
@@ -4118,169 +3909,33 @@ void issue_action_BA23a(struct rtw_adapter *padapter,
}
if (pregpriv->ampdu_amsdu == 0)/* disabled */
- BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
+ BA_para_set &= ~BIT(0);
else if (pregpriv->ampdu_amsdu == 1)/* enabled */
- BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
- else /* auto */
- BA_para_set = cpu_to_le16(BA_para_set);
-
- pframe = rtw_set_fixed_ie23a(pframe, 2,
- (unsigned char *)&BA_para_set,
- &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
- break;
- case 2:/* DELBA */
- BA_para_set = (status & 0x1F) << 3;
- BA_para_set = cpu_to_le16(BA_para_set);
- pframe = rtw_set_fixed_ie23a(pframe, 2,
- (unsigned char *)&BA_para_set,
- &pattrib->pktlen);
-
- reason_code = 37;/* Requested from peer STA as it does not
- want to use the mechanism */
- reason_code = cpu_to_le16(reason_code);
- pframe = rtw_set_fixed_ie23a(pframe, 2,
- (unsigned char *)&reason_code,
- &pattrib->pktlen);
- break;
- default:
- break;
- }
-
-out:
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe23a(padapter, pmgntframe);
-}
-
-static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
-{
- struct list_head *plist, *phead, *ptmp;
- unsigned char category, action;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- u8 *pframe;
- struct ieee80211_hdr *pwlanhdr;
- struct wlan_network *pnetwork;
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct rtw_queue *queue = &pmlmepriv->scanned_queue;
- u8 InfoContent[16] = {0};
- u8 ICS[8][15];
- int i;
-
- if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
- pmlmepriv->num_sta_no_ht == 0)
- return;
-
- if (pmlmeinfo->bwmode_updated)
- return;
-
- DBG_8723A("%s\n", __func__);
-
- category = WLAN_CATEGORY_PUBLIC;
- action = ACT_PUBLIC_BSSCOEXIST;
-
- pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
- if (!pmgntframe)
- return;
-
- /* update attribute */
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib23a(padapter, pattrib);
-
- memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
- pwlanhdr = (struct ieee80211_hdr *)pframe;
-
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
-
- ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
- ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
-
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
- pmlmeext->mgnt_seq++;
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
-
- pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
- pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
-
- if (pmlmepriv->num_FortyMHzIntolerant > 0) {
- u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
-
- pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
- &iedata, &pattrib->pktlen);
- }
-
- if (pmlmepriv->num_sta_no_ht <= 0)
- goto out;
-
- memset(ICS, 0, sizeof(ICS));
-
- spin_lock_bh(&pmlmepriv->scanned_queue.lock);
-
- phead = get_list_head(queue);
- plist = phead->next;
-
- list_for_each_safe(plist, ptmp, phead) {
- const u8 *p;
- struct wlan_bssid_ex *pbss_network;
-
- pnetwork = container_of(plist, struct wlan_network, list);
+ BA_para_set |= BIT(0);
- pbss_network = &pnetwork->network;
+ put_unaligned_le16(BA_para_set,
+ &mgmt->u.action.u.addba_resp.capab);
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- pbss_network->IEs + _FIXED_IE_LENGTH_,
- pbss_network->IELength -_FIXED_IE_LENGTH_);
- if (!p || !p[1]) { /* non-HT */
- if (pbss_network->DSConfig <= 0 ||
- pbss_network->DSConfig > 14)
- continue;
-
- ICS[0][pbss_network->DSConfig] = 1;
-
- if (ICS[0][0] == 0)
- ICS[0][0] = 1;
- }
-
- }
-
- spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
+ put_unaligned_le16(pmlmeinfo->ADDBA_req.BA_timeout_value,
+ &mgmt->u.action.u.addba_resp.timeout);
- for (i = 0; i < 8;i++) {
- if (ICS[i][0] == 1) {
- int j, k = 0;
-
- InfoContent[k] = i;
- /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
- k++;
+ pattrib->pktlen += 8;
+ break;
+ case WLAN_ACTION_DELBA:
+ pattrib->pktlen += sizeof(mgmt->u.action.u.delba);
- for (j = 1; j <= 14; j++) {
- if (ICS[i][j] == 1) {
- if (k < 16) {
- /* channel number */
- InfoContent[k] = j;
- k++;
- }
- }
- }
+ mgmt->u.action.u.delba.action_code = action;
+ BA_para_set = (status & 0x1F) << 3;
+ mgmt->u.action.u.delba.params = cpu_to_le16(BA_para_set);
+ mgmt->u.action.u.delba.reason_code =
+ cpu_to_le16(WLAN_REASON_QSTA_NOT_USE);
- pframe = rtw_set_ie23a(pframe,
- EID_BSSIntolerantChlReport, k,
- InfoContent, &pattrib->pktlen);
- }
+ pattrib->pktlen += 5;
+ break;
+ default:
+ break;
}
-out:
pattrib->last_txcmdsz = pattrib->pktlen;
dump_mgntframe23a(padapter, pmgntframe);
@@ -4291,11 +3946,11 @@ int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta = NULL;
/* struct recv_reorder_ctrl *preorder_ctrl; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u16 tid;
- if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state&0x03) != MSR_AP)
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
return _SUCCESS;
@@ -4328,8 +3983,8 @@ int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
int send_beacon23a(struct rtw_adapter *padapter)
{
- bool bxmitok;
- int issue = 0;
+ bool bxmitok;
+ int issue = 0;
int poll = 0;
unsigned long start = jiffies;
unsigned int passing_time;
@@ -4368,7 +4023,7 @@ int send_beacon23a(struct rtw_adapter *padapter)
/****************************************************************************
-Following are some utitity fuctions for WiFi MLME
+Following are some utitity functions for WiFi MLME
*****************************************************************************/
@@ -4377,9 +4032,10 @@ bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
int i = 0;
u8 Channel_5G[45] = {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};
+ 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};
for (i = 0; i < sizeof(Channel_5G); i++)
if (channel == Channel_5G[i])
return true;
@@ -4390,7 +4046,7 @@ static void rtw_site_survey(struct rtw_adapter *padapter)
{
unsigned char survey_channel = 0;
enum rt_scan_type ScanType = SCAN_PASSIVE;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct rtw_ieee80211_channel *ch;
@@ -4446,7 +4102,7 @@ static void rtw_site_survey(struct rtw_adapter *padapter)
/* val8 = 0; */
/* config MSR */
- Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
+ rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
/* restore RX GAIN */
rtl8723a_set_initial_gain(padapter, 0xff);
@@ -4462,66 +4118,81 @@ static void rtw_site_survey(struct rtw_adapter *padapter)
pmlmeext->chan_scan_time = SURVEY_TO;
pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
-
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
- issue_action_BSSCoexistPacket(padapter);
}
return;
}
/* collect bss info from Beacon and Probe request/response frames. */
-int collect_bss_info23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame,
- struct wlan_bssid_ex *bssid)
+static struct wlan_bssid_ex *collect_bss_info(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame)
{
- int i;
- const u8 *p;
struct sk_buff *skb = precv_frame->pkt;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
- unsigned int length;
- u8 ie_offset;
struct registry_priv *pregistrypriv = &padapter->registrypriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u16 capab_info;
-
- length = skb->len - sizeof(struct ieee80211_hdr_3addr);
+ struct wlan_bssid_ex *bssid;
+ const u8 *p;
+ u8 *pie;
+ unsigned int length;
+ int i;
- if (length > MAX_IE_SZ) {
- /* DBG_8723A("IE too long for survey event\n"); */
- return _FAIL;
- }
+ length = skb->len;
- memset(bssid, 0, sizeof(struct wlan_bssid_ex));
+ bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
+ if (!bssid)
+ return NULL;
if (ieee80211_is_beacon(mgmt->frame_control)) {
+ length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ pie = mgmt->u.beacon.variable;
bssid->reserved = 1;
- ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
- capab_info = mgmt->u.beacon.capab_info;
- } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
- ie_offset = offsetof(struct ieee80211_mgmt,
- u.probe_req.variable);
+ bssid->capability =
+ get_unaligned_le16(&mgmt->u.beacon.capab_info);
+ bssid->beacon_interval =
+ get_unaligned_le16(&mgmt->u.beacon.beacon_int);
+ bssid->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
+ } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
+ length -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
+ pie = mgmt->u.probe_req.variable;
bssid->reserved = 2;
- capab_info = 0;
+ bssid->capability = 0;
+ bssid->beacon_interval =
+ padapter->registrypriv.dev_network.beacon_interval;
+ bssid->tsf = 0;
} else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
- ie_offset = offsetof(struct ieee80211_mgmt,
- u.probe_resp.variable);
+ length -=
+ offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+ pie = mgmt->u.probe_resp.variable;
bssid->reserved = 3;
- capab_info = mgmt->u.probe_resp.capab_info;
+ bssid->capability =
+ get_unaligned_le16(&mgmt->u.probe_resp.capab_info);
+ bssid->beacon_interval =
+ get_unaligned_le16(&mgmt->u.probe_resp.beacon_int);
+ bssid->tsf = get_unaligned_le64(&mgmt->u.probe_resp.timestamp);
} else {
+ length -= offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ pie = mgmt->u.beacon.variable;
bssid->reserved = 0;
- ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
- capab_info = mgmt->u.beacon.capab_info;
+ bssid->capability =
+ get_unaligned_le16(&mgmt->u.beacon.capab_info);
+ bssid->beacon_interval =
+ padapter->registrypriv.dev_network.beacon_interval;
+ bssid->tsf = 0;
+ }
+
+ if (length > MAX_IE_SZ) {
+ /* DBG_8723A("IE too long for survey event\n"); */
+ kfree(bssid);
+ return NULL;
}
- ie_offset -= offsetof(struct ieee80211_mgmt, u);
bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
/* below is to copy the information element */
bssid->IELength = length;
- memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
+ memcpy(bssid->IEs, pie, bssid->IELength);
/* get the signal strength */
/* in dBM.raw data */
@@ -4532,55 +4203,47 @@ int collect_bss_info23a(struct rtw_adapter *padapter,
precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
/* checking SSID */
- p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs, bssid->IELength);
if (!p) {
DBG_8723A("marc: cannot find SSID for survey event\n");
- return _FAIL;
+ goto fail;
}
if (p[1] > IEEE80211_MAX_SSID_LEN) {
DBG_8723A("%s()-%d: IE too long (%d) for survey "
"event\n", __func__, __LINE__, p[1]);
- return _FAIL;
+ goto fail;
}
memcpy(bssid->Ssid.ssid, p + 2, p[1]);
bssid->Ssid.ssid_len = p[1];
- memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
-
/* checking rate info... */
i = 0;
- p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs, bssid->IELength);
if (p) {
if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
DBG_8723A("%s()-%d: IE too long (%d) for survey "
"event\n", __func__, __LINE__, p[1]);
- return _FAIL;
+ goto fail;
}
memcpy(bssid->SupportedRates, p + 2, p[1]);
i = p[1];
}
- p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs,
+ bssid->IELength);
if (p) {
if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
DBG_8723A("%s()-%d: IE too long (%d) for survey "
"event\n", __func__, __LINE__, p[1]);
- return _FAIL;
+ goto fail;
}
memcpy(bssid->SupportedRates + i, p + 2, p[1]);
}
- if (bssid->IELength < 12)
- return _FAIL;
-
/* Checking for DSConfig */
- p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs, bssid->IELength);
bssid->DSConfig = 0;
@@ -4588,13 +4251,12 @@ int collect_bss_info23a(struct rtw_adapter *padapter,
bssid->DSConfig = p[2];
} else {/* In 5G, some ap do not have DSSET IE */
/* checking HT info for channel */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
- bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, bssid->IEs,
+ bssid->IELength);
if (p) {
- struct HT_info_element *HT_info =
- (struct HT_info_element *)(p + 2);
- bssid->DSConfig = HT_info->primary_channel;
+ struct ieee80211_ht_operation *HT_info =
+ (struct ieee80211_ht_operation *)(p + 2);
+ bssid->DSConfig = HT_info->primary_chan;
} else /* use current channel */
bssid->DSConfig = rtw_get_oper_ch23a(padapter);
}
@@ -4604,13 +4266,10 @@ int collect_bss_info23a(struct rtw_adapter *padapter,
bssid->ifmode = NL80211_IFTYPE_STATION;
ether_addr_copy(bssid->MacAddress, mgmt->sa);
bssid->Privacy = 1;
- return _SUCCESS;
+ return bssid;
}
- bssid->BeaconPeriod = get_unaligned_le16(
- rtw_get_beacon_interval23a_from_ie(bssid->IEs));
-
- if (capab_info & BIT(0)) {
+ if (bssid->capability & WLAN_CAPABILITY_ESS) {
bssid->ifmode = NL80211_IFTYPE_STATION;
ether_addr_copy(bssid->MacAddress, mgmt->sa);
} else {
@@ -4618,7 +4277,7 @@ int collect_bss_info23a(struct rtw_adapter *padapter,
ether_addr_copy(bssid->MacAddress, mgmt->bssid);
}
- if (capab_info & BIT(4))
+ if (bssid->capability & WLAN_CAPABILITY_PRIVACY)
bssid->Privacy = 1;
else
bssid->Privacy = 0;
@@ -4630,41 +4289,44 @@ int collect_bss_info23a(struct rtw_adapter *padapter,
pmlmeinfo->bwmode_updated == false) {
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
- bssid->IEs + ie_offset,
- bssid->IELength - ie_offset);
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, bssid->IEs,
+ bssid->IELength);
if (p && p[1] > 0) {
- struct HT_caps_element *pHT_caps;
- pHT_caps = (struct HT_caps_element *)(p + 2);
+ struct ieee80211_ht_cap *pHT_caps;
+ pHT_caps = (struct ieee80211_ht_cap *)(p + 2);
- if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
+ if (pHT_caps->cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT))
pmlmepriv->num_FortyMHzIntolerant++;
} else
pmlmepriv->num_sta_no_ht++;
}
- /* mark bss info receving from nearby channel as SignalQuality 101 */
+ /* mark bss info receiving from nearby channel as SignalQuality 101 */
if (bssid->DSConfig != rtw_get_oper_ch23a(padapter))
bssid->PhyInfo.SignalQuality = 101;
- return _SUCCESS;
+ return bssid;
+fail:
+ kfree (bssid);
+ return NULL;
}
static void start_create_ibss(struct rtw_adapter* padapter)
{
- unsigned short caps;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ unsigned short caps;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
- pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
+ pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
/* update wireless mode */
update_wireless_mode23a(padapter);
- /* udpate capability */
- caps = rtw_get_capability23a(pnetwork);
+ /* update capability */
+ caps = pnetwork->capability;
update_capinfo23a(padapter, caps);
if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc master */
rtl8723a_set_sec_cfg(padapter, 0xcf);
@@ -4675,20 +4337,17 @@ static void start_create_ibss(struct rtw_adapter* padapter)
rtl8723a_SetBeaconRelatedRegisters(padapter);
- /* set msr to WIFI_FW_ADHOC_STATE */
- pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
- Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
+ /* set msr to MSR_ADHOC */
+ pmlmeinfo->state = MSR_ADHOC;
+ rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
/* issue beacon */
- if (send_beacon23a(padapter) == _FAIL)
- {
+ if (send_beacon23a(padapter) == _FAIL) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
report_join_res23a(padapter, -1);
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
- }
- else
- {
+ pmlmeinfo->state = MSR_NOLINK;
+ } else {
hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
hw_var_set_mlme_join(padapter, 0);
@@ -4705,27 +4364,27 @@ static void start_create_ibss(struct rtw_adapter* padapter)
static void start_clnt_join(struct rtw_adapter* padapter)
{
- unsigned short caps;
- u8 val8;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ unsigned short caps;
+ u8 val8;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
int beacon_timeout;
pmlmeext->cur_channel = (u8)pnetwork->DSConfig;
- pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
+ pmlmeinfo->bcn_interval = pnetwork->beacon_interval;
/* update wireless mode */
update_wireless_mode23a(padapter);
- /* udpate capability */
- caps = rtw_get_capability23a(pnetwork);
+ /* update capability */
+ caps = pnetwork->capability;
update_capinfo23a(padapter, caps);
if (caps & WLAN_CAPABILITY_ESS) {
/* switch channel */
set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
- Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
+ rtl8723a_set_media_status(padapter, MSR_INFRA);
val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
0xcc: 0xcf;
@@ -4741,9 +4400,9 @@ static void start_clnt_join(struct rtw_adapter* padapter)
set_link_timer(pmlmeext, beacon_timeout);
mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
- pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
+ pmlmeinfo->state = WIFI_FW_AUTH_NULL | MSR_INFRA;
} else if (caps & WLAN_CAPABILITY_IBSS) { /* adhoc client */
- Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
+ rtl8723a_set_media_status(padapter, MSR_ADHOC);
rtl8723a_set_sec_cfg(padapter, 0xcf);
@@ -4752,7 +4411,7 @@ static void start_clnt_join(struct rtw_adapter* padapter)
rtl8723a_SetBeaconRelatedRegisters(padapter);
- pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
+ pmlmeinfo->state = MSR_ADHOC;
report_join_res23a(padapter, 1);
}
@@ -4765,7 +4424,7 @@ static void start_clnt_join(struct rtw_adapter* padapter)
static void start_clnt_auth(struct rtw_adapter* padapter)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
del_timer_sync(&pmlmeext->link_timer);
@@ -4783,8 +4442,10 @@ static void start_clnt_auth(struct rtw_adapter* padapter)
/* AP may: 1)not response auth or 2)deauth us after link is complete */
/* issue deauth before issuing auth to deal with the situation */
/* Commented by Albert 2012/07/21 */
- /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
- issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
+ /* For the Win8 P2P connection, it will be hard to have a
+ successful connection if this Wi-Fi doesn't connect to it. */
+ issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress,
+ WLAN_REASON_DEAUTH_LEAVING);
DBG_8723A_LEVEL(_drv_always_, "start auth\n");
issue_auth(padapter, NULL, 0);
@@ -4794,7 +4455,7 @@ static void start_clnt_auth(struct rtw_adapter* padapter)
static void start_clnt_assoc(struct rtw_adapter* padapter)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
del_timer_sync(&pmlmeext->link_timer);
@@ -4810,7 +4471,7 @@ static void start_clnt_assoc(struct rtw_adapter* padapter)
int receive_disconnect23a(struct rtw_adapter *padapter,
unsigned char *MacAddr, unsigned short reason)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* check A3 */
@@ -4819,17 +4480,17 @@ int receive_disconnect23a(struct rtw_adapter *padapter,
DBG_8723A("%s\n", __func__);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
+ if ((pmlmeinfo->state&0x03) == MSR_INFRA)
{
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
{
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
report_del_sta_event23a(padapter, MacAddr, reason);
}
else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
{
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
report_join_res23a(padapter, -2);
}
}
@@ -4860,9 +4521,8 @@ static void process_80211d(struct rtw_adapter *padapter,
u8 noc; /* number of channel */
u8 j, k;
- ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
- bssid->IEs + _FIXED_IE_LENGTH_,
- bssid->IELength - _FIXED_IE_LENGTH_);
+ ie = cfg80211_find_ie(WLAN_EID_COUNTRY, bssid->IEs,
+ bssid->IELength);
if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
return;
@@ -5068,12 +4728,13 @@ Following are the functions to report events
*****************************************************************************/
-void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
+void report_survey_event23a(struct rtw_adapter *padapter,
+ struct recv_frame *precv_frame)
{
struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
+ u8 *pevtcmd;
u32 cmdsz;
- struct survey_event *psurvey_evt;
+ struct survey_event *psurvey_evt;
struct C2HEvent_Header *pc2h_evt_hdr;
struct mlme_ext_priv *pmlmeext;
struct cmd_priv *pcmdpriv;
@@ -5084,8 +4745,7 @@ void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *pre
pmlmeext = &padapter->mlmeextpriv;
pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!pcmd_obj)
return;
@@ -5110,13 +4770,14 @@ void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *pre
psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
- if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
+ psurvey_evt->bss = collect_bss_info(padapter, precv_frame);
+ if (!psurvey_evt->bss) {
kfree(pcmd_obj);
kfree(pevtcmd);
return;
}
- process_80211d(padapter, &psurvey_evt->bss);
+ process_80211d(padapter, psurvey_evt->bss);
rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
@@ -5128,15 +4789,14 @@ void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *pre
void report_surveydone_event23a(struct rtw_adapter *padapter)
{
struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
+ u8 *pevtcmd;
u32 cmdsz;
struct surveydone_event *psurveydone_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct C2HEvent_Header *pc2h_evt_hdr;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!pcmd_obj)
return;
@@ -5172,7 +4832,7 @@ void report_surveydone_event23a(struct rtw_adapter *padapter)
void report_join_res23a(struct rtw_adapter *padapter, int res)
{
struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
+ u8 *pevtcmd;
u32 cmdsz;
struct joinbss_event *pjoinbss_evt;
struct C2HEvent_Header *pc2h_evt_hdr;
@@ -5180,8 +4840,7 @@ void report_join_res23a(struct rtw_adapter *padapter, int res)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!pcmd_obj)
return;
@@ -5218,20 +4877,20 @@ void report_join_res23a(struct rtw_adapter *padapter, int res)
return;
}
-void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
+void report_del_sta_event23a(struct rtw_adapter *padapter,
+ unsigned char* MacAddr, unsigned short reason)
{
struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
+ u8 *pevtcmd;
u32 cmdsz;
struct sta_info *psta;
- int mac_id;
- struct stadel_event *pdel_sta_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ int mac_id;
+ struct stadel_event *pdel_sta_evt;
+ struct C2HEvent_Header *pc2h_evt_hdr;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!pcmd_obj)
return;
@@ -5274,18 +4933,18 @@ void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAdd
return;
}
-void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
+void report_add_sta_event23a(struct rtw_adapter *padapter,
+ unsigned char* MacAddr, int cam_idx)
{
struct cmd_obj *pcmd_obj;
- u8 *pevtcmd;
+ u8 *pevtcmd;
u32 cmdsz;
- struct stassoc_event *padd_sta_evt;
- struct C2HEvent_Header *pc2h_evt_hdr;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct stassoc_event *padd_sta_evt;
+ struct C2HEvent_Header *pc2h_evt_hdr;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!pcmd_obj)
return;
@@ -5329,8 +4988,8 @@ Following are the event callback functions
void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* ERP */
VCS_update23a(padapter, psta);
@@ -5342,7 +5001,7 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
- if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
+ if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
psta->htpriv.sgi = true;
psta->qos_option = true;
@@ -5371,13 +5030,14 @@ void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
psta->state = _FW_LINKED;
}
-void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
+void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter,
+ int join_res)
{
- struct sta_info *psta, *psta_bmc;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct sta_info *psta, *psta_bmc;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
- struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_priv *pstapriv = &padapter->stapriv;
if (join_res < 0) {
hw_var_set_mlme_join(padapter, 1);
@@ -5390,7 +5050,7 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_re
goto exit_mlmeext_joinbss_event_callback23a;
}
- if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
+ if ((pmlmeinfo->state&0x03) == MSR_ADHOC)
{
/* for bc/mc */
psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
@@ -5413,7 +5073,7 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_re
/* BCN interval */
rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
- /* udpate capability */
+ /* update capability */
update_capinfo23a(padapter, pmlmeinfo->capability);
/* WMM, Update EDCA param */
@@ -5440,7 +5100,7 @@ void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_re
hw_var_set_mlme_join(padapter, 2);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
+ if ((pmlmeinfo->state&0x03) == MSR_INFRA) {
/* correcting TSF */
rtw_correct_TSF(padapter);
@@ -5453,14 +5113,15 @@ exit_mlmeext_joinbss_event_callback23a:
DBG_8723A("=>%s\n", __func__);
}
-void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
+void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter,
+ struct sta_info *psta)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
DBG_8723A("%s\n", __func__);
- if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
+ if ((pmlmeinfo->state & 0x03) == MSR_ADHOC) {
/* adhoc master or sta_count>1 */
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
{
@@ -5473,7 +5134,7 @@ void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_
if (send_beacon23a(padapter) != _SUCCESS) {
pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
- pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
+ pmlmeinfo->state ^= MSR_ADHOC;
return;
}
@@ -5518,10 +5179,10 @@ void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
flush_all_cam_entry23a(padapter);
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
/* set MSR to no link state -> infra. mode */
- Set_MSR23a(padapter, _HW_STATE_STATION_);
+ rtl8723a_set_media_status(padapter, MSR_INFRA);
del_timer_sync(&pmlmeext->link_timer);
}
@@ -5551,8 +5212,6 @@ void linked_status_chk23a(struct rtw_adapter *padapter)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct sta_priv *pstapriv = &padapter->stapriv;
- rtl8723a_sreset_linked_status_check(padapter);
-
if (is_client_associated_to_ap23a(padapter)) {
/* linked infrastructure client mode */
@@ -5699,13 +5358,12 @@ static void survey_timer_hdl(unsigned long data)
pmlmeext->scan_abort = false;/* reset */
}
- ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
- GFP_ATOMIC);
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!ph2c)
goto exit_survey_timer_hdl;
- psurveyPara = (struct sitesurvey_parm*)
- kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
+ psurveyPara = kzalloc(sizeof(struct sitesurvey_parm),
+ GFP_ATOMIC);
if (!psurveyPara) {
kfree(ph2c);
goto exit_survey_timer_hdl;
@@ -5726,13 +5384,13 @@ static void link_timer_hdl(unsigned long data)
/* static unsigned int rx_pkt = 0; */
/* static u64 tx_cnt = 0; */
/* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
/* struct sta_priv *pstapriv = &padapter->stapriv; */
if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
DBG_8723A("link_timer_hdl:no beacon while connecting\n");
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
report_join_res23a(padapter, -3);
} else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
/* re-auth timer */
@@ -5757,7 +5415,7 @@ static void link_timer_hdl(unsigned long data)
} else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
/* re-assoc timer */
if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
report_join_res23a(padapter, -2);
return;
}
@@ -5773,14 +5431,14 @@ static void link_timer_hdl(unsigned long data)
static void addba_timer_hdl(unsigned long data)
{
struct sta_info *psta = (struct sta_info *)data;
- struct ht_priv *phtpriv;
+ struct ht_priv *phtpriv;
if (!psta)
return;
phtpriv = &psta->htpriv;
- if (phtpriv->ht_option == true && phtpriv->ampdu_enable == true) {
+ if (phtpriv->ht_option && phtpriv->ampdu_enable) {
if (phtpriv->candidate_tid_bitmap)
phtpriv->candidate_tid_bitmap = 0x0;
}
@@ -5794,7 +5452,7 @@ void init_addba_retry_timer23a(struct sta_info *psta)
void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
(unsigned long)padapter);
@@ -5818,22 +5476,22 @@ int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
switch (psetop->mode) {
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
- pmlmeinfo->state = WIFI_FW_AP_STATE;
- type = _HW_STATE_AP_;
+ pmlmeinfo->state = MSR_AP;
+ type = MSR_AP;
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
/* clear state */
pmlmeinfo->state &= ~(BIT(0)|BIT(1));
/* set to STATION_STATE */
- pmlmeinfo->state |= WIFI_FW_STATION_STATE;
- type = _HW_STATE_STATION_;
+ pmlmeinfo->state |= MSR_INFRA;
+ type = MSR_INFRA;
break;
case NL80211_IFTYPE_ADHOC:
- type = _HW_STATE_ADHOC_;
+ type = MSR_ADHOC;
break;
default:
- type = _HW_STATE_NOLINK_;
+ type = MSR_NOLINK;
break;
}
@@ -5845,7 +5503,7 @@ int setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
@@ -5854,7 +5512,7 @@ int createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
if (pparm->ifmode == NL80211_IFTYPE_AP ||
pparm->ifmode == NL80211_IFTYPE_P2P_GO) {
#ifdef CONFIG_8723AU_AP_MODE
- if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
+ if (pmlmeinfo->state == MSR_AP) {
/* todo: */
return H2C_SUCCESS;
}
@@ -5903,20 +5561,19 @@ int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
- struct HT_info_element *pht_info;
+ struct ieee80211_ht_operation *pht_info;
u32 i;
- int bcn_fixed_size;
u8 *p;
/* u32 initialgain; */
/* u32 acparm; */
/* check already connecting to AP or not */
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
- if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
+ if (pmlmeinfo->state & MSR_INFRA)
issue_deauth_ex(padapter, pnetwork->MacAddress,
WLAN_REASON_DEAUTH_LEAVING, 5, 100);
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
/* clear CAM */
flush_all_cam_entry23a(padapter);
@@ -5924,8 +5581,7 @@ int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
del_timer_sync(&pmlmeext->link_timer);
/* set MSR to nolink -> infra. mode */
- /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
- Set_MSR23a(padapter, _HW_STATE_STATION_);
+ rtl8723a_set_media_status(padapter, MSR_INFRA);
hw_var_set_mlme_disconnect(padapter);
}
@@ -5951,10 +5607,7 @@ int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
/* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
pnetwork->IELength); */
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
- for (i = bcn_fixed_size; i < pnetwork->IELength;) {
+ for (i = 0; i < pnetwork->IELength;) {
p = pnetwork->IEs + i;
switch (p[0]) {
@@ -5972,20 +5625,21 @@ int join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
/* spec case only for cisco's ap because cisco's ap
* issue assoc rsp using mcs rate @40MHz or @20MHz */
- pht_info = (struct HT_info_element *)(p + 2);
+ pht_info = (struct ieee80211_ht_operation *)(p + 2);
- if ((pregpriv->cbw40_enable) &&
- (pht_info->infos[0] & BIT(2))) {
+ if (pregpriv->cbw40_enable &&
+ (pht_info->ht_param &
+ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
/* switch to the 40M Hz mode according to AP */
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pht_info->infos[0] & 0x3)
- {
- case 1:
+ switch (pht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
pmlmeext->cur_ch_offset =
HAL_PRIME_CHNL_OFFSET_LOWER;
break;
- case 3:
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
pmlmeext->cur_ch_offset =
HAL_PRIME_CHNL_OFFSET_UPPER;
break;
@@ -6033,7 +5687,7 @@ int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
- /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
+ /* pmlmeinfo->state = MSR_NOLINK; */
hw_var_set_mlme_disconnect(padapter);
hw_var_set_bssid(padapter, null_addr);
@@ -6041,14 +5695,14 @@ int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
/* restore to initial setting. */
update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
- if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE ||
- (pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
+ if ((pmlmeinfo->state & 0x03) == MSR_ADHOC ||
+ (pmlmeinfo->state & 0x03) == MSR_AP)
rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
/* set MSR to no link state -> infra. mode */
- Set_MSR23a(padapter, _HW_STATE_STATION_);
+ rtl8723a_set_media_status(padapter, MSR_INFRA);
- pmlmeinfo->state = WIFI_FW_NULL_STATE;
+ pmlmeinfo->state = MSR_NOLINK;
/* switch to the 20M Hz mode after disconnect */
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
@@ -6063,7 +5717,7 @@ int disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
rtw_free_uc_swdec_pending_queue23a(padapter);
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
static int
@@ -6074,7 +5728,7 @@ rtw_scan_ch_decision(struct rtw_adapter *padapter,
int i, j;
int scan_ch_num = 0;
int set_idx;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
/* clear out first */
memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
@@ -6150,7 +5804,8 @@ int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
if (pparm->ssid[i].ssid_len) {
memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
- pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
+ pparm->ssid[i].ssid,
+ IEEE80211_MAX_SSID_LEN);
pmlmeext->sitesurvey_res.ssid[i].ssid_len =
pparm->ssid[i].ssid_len;
} else {
@@ -6196,7 +5851,7 @@ int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
rtl8723a_odm_support_ability_clr(padapter,
DYNAMIC_FUNC_DISABLE);
- /* config the initial gain under scaning, need to
+ /* config the initial gain under scanning, need to
write the BB registers */
if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
initialgain = 0x30;
@@ -6206,7 +5861,7 @@ int sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
rtl8723a_set_initial_gain(padapter, initialgain);
/* set MSR to no link state */
- Set_MSR23a(padapter, _HW_STATE_NOLINK_);
+ rtl8723a_set_media_status(padapter, MSR_NOLINK);
rtl8723a_mlme_sitesurvey(padapter, 1);
@@ -6227,7 +5882,7 @@ int setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
if (pparm->mode < 4)
pmlmeinfo->auth_algo = pparm->mode;
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
int setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
@@ -6282,7 +5937,7 @@ int set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 "
"WEP104-5 TKIP-2 AES-4) camid:%d\n",
pparm->algorithm, cam_id);
- if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ if ((pmlmeinfo->state & 0x03) == MSR_AP) {
struct sta_info *psta;
struct sta_priv *pstapriv = &padapter->stapriv;
@@ -6352,11 +6007,11 @@ int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
if (!psta)
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
pmlmeinfo->HT_enable) ||
- (pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
+ (pmlmeinfo->state & 0x03) == MSR_AP) {
issue_action_BA23a(padapter, pparm->addr,
WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
mod_timer(&psta->addba_retry_timer,
@@ -6364,27 +6019,26 @@ int add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
} else
psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
int set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
{
struct cmd_obj *ph2c;
- struct Tx_Beacon_param *ptxBeacon_parm;
+ struct Tx_Beacon_param *ptxBeacon_parm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u8 res = _SUCCESS;
int len_diff = 0;
- ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (!ph2c) {
res = _FAIL;
goto exit;
}
- ptxBeacon_parm = (struct Tx_Beacon_param *)
- kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
+ ptxBeacon_parm = kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
if (!ptxBeacon_parm) {
kfree(ph2c);
res = _FAIL;
@@ -6394,10 +6048,9 @@ int set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
sizeof(struct wlan_bssid_ex));
- len_diff = update_hidden_ssid(
- ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
- ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
- pmlmeinfo->hidden_ssid_mode);
+ len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs,
+ ptxBeacon_parm->network.IELength,
+ pmlmeinfo->hidden_ssid_mode);
ptxBeacon_parm->network.IELength += len_diff;
init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm,
@@ -6512,7 +6165,7 @@ int tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
const struct set_ch_parm *set_ch_parm;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!pbuf)
return H2C_PARAMETERS_ERROR;
@@ -6530,13 +6183,13 @@ int set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
set_channel_bwmode23a(padapter, set_ch_parm->ch,
set_ch_parm->ch_offset, set_ch_parm->bw);
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
const struct SetChannelPlan_param *setChannelPlan_param;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!pbuf)
return H2C_PARAMETERS_ERROR;
@@ -6549,7 +6202,7 @@ int set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
init_channel_list(padapter, pmlmeext->channel_set,
pmlmeext->max_chan_nums, &pmlmeext->channel_list);
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
@@ -6561,12 +6214,12 @@ int led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
ledBlink_param = (struct LedBlink_param *)pbuf;
- return H2C_SUCCESS;
+ return H2C_SUCCESS;
}
int set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
{
- return H2C_REJECTED;
+ return H2C_REJECTED;
}
/* TDLS_WRCR : write RCR DATA BIT */
diff --git a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c
index dbd01b652e02..d5fa26ab38a6 100644
--- a/drivers/staging/rtl8723au/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8723au/core/rtw_pwrctrl.c
@@ -114,7 +114,6 @@ int ips_leave23a(struct rtw_adapter * padapter)
static bool rtw_pwr_unassociated_idle(struct rtw_adapter *adapter)
{
- struct rtw_adapter *buddy = adapter->pbuddy_adapter;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
struct xmit_priv *pxmit_priv = &adapter->xmitpriv;
@@ -130,21 +129,6 @@ static bool rtw_pwr_unassociated_idle(struct rtw_adapter *adapter)
goto exit;
}
- /* consider buddy, if exist */
- if (buddy) {
- struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv;
-
- if (check_fwstate(b_pmlmepriv,
- WIFI_ASOC_STATE|WIFI_SITE_MONITOR) ||
- check_fwstate(b_pmlmepriv,
- WIFI_UNDER_LINKING|WIFI_UNDER_WPS) ||
- check_fwstate(b_pmlmepriv, WIFI_AP_STATE) ||
- check_fwstate(b_pmlmepriv,
- WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE)) {
- goto exit;
- }
- }
-
if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF ||
pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) {
DBG_8723A_LEVEL(_drv_always_,
@@ -166,35 +150,12 @@ void rtw_ps_processor23a(struct rtw_adapter*padapter)
{
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- enum rt_rf_power_state rfpwrstate;
pwrpriv->ps_processing = true;
if (pwrpriv->bips_processing == true)
goto exit;
- if (padapter->pwrctrlpriv.bHWPwrPindetect) {
- rfpwrstate = RfOnOffDetect23a(padapter);
- DBG_8723A("@@@@- #2 %s ==> rfstate:%s\n", __func__,
- (rfpwrstate == rf_on)?"rf_on":"rf_off");
-
- if (rfpwrstate!= pwrpriv->rf_pwrstate) {
- if (rfpwrstate == rf_off) {
- pwrpriv->change_rfpwrstate = rf_off;
- pwrpriv->brfoffbyhw = true;
- padapter->bCardDisableWOHSM = true;
- rtw_hw_suspend23a(padapter);
- } else {
- pwrpriv->change_rfpwrstate = rf_on;
- rtw_hw_resume23a(padapter);
- }
- DBG_8723A("current rf_pwrstate(%s)\n",
- (pwrpriv->rf_pwrstate == rf_off) ?
- "rf_off":"rf_on");
- }
- pwrpriv->pwr_state_check_cnts ++;
- }
-
if (pwrpriv->ips_mode_req == IPS_NONE)
goto exit;
@@ -515,7 +476,7 @@ inline void rtw_set_ips_deny23a(struct rtw_adapter *padapter, u32 ms)
/*
* rtw_pwr_wakeup - Wake the NIC up from: 1)IPS. 2)USB autosuspend
* @adapter: pointer to _adapter structure
-* @ips_deffer_ms: the ms wiil prevent from falling into IPS after wakeup
+* @ips_deffer_ms: the ms will prevent from falling into IPS after wakeup
* Return _SUCCESS or _FAIL
*/
@@ -631,19 +592,16 @@ int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode)
{
struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
- if (mode == IPS_NORMAL || mode == IPS_LEVEL_2) {
- rtw_ips_mode_req(pwrctrlpriv, mode);
- DBG_8723A("%s %s\n", __func__,
- mode == IPS_NORMAL?"IPS_NORMAL":"IPS_LEVEL_2");
- return 0;
- } else if (mode == IPS_NONE) {
- rtw_ips_mode_req(pwrctrlpriv, mode);
+ if (mode != IPS_NORMAL && mode != IPS_LEVEL_2 && mode != IPS_NONE)
+ return -EINVAL;
+
+ pwrctrlpriv->ips_mode_req = mode;
+ if (mode == IPS_NONE) {
DBG_8723A("%s %s\n", __func__, "IPS_NONE");
if (padapter->bSurpriseRemoved == 0 &&
rtw_pwr_wakeup(padapter) == _FAIL)
return -EFAULT;
- } else
- return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/staging/rtl8723au/core/rtw_recv.c b/drivers/staging/rtl8723au/core/rtw_recv.c
index 690970efc22f..a9f8183349ab 100644
--- a/drivers/staging/rtl8723au/core/rtw_recv.c
+++ b/drivers/staging/rtl8723au/core/rtw_recv.c
@@ -1185,7 +1185,7 @@ static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
/* DBG_8723A("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
/* update_BCNTIM(padapter); */
update_beacon23a(padapter, WLAN_EID_TIM,
NULL, false);
@@ -1217,7 +1217,7 @@ static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
/* update_BCNTIM(padapter); */
update_beacon23a(padapter, WLAN_EID_TIM,
NULL, false);
@@ -2363,7 +2363,7 @@ void rtw_signal_stat_timer_hdl23a(unsigned long data)
recvpriv->signal_strength_data.avg_val;
num_signal_strength =
recvpriv->signal_strength_data.total_num;
- /* after avg_vals are accquired, we can re-stat */
+ /* after avg_vals are acquired, we can re-stat */
/* the signal values */
recvpriv->signal_strength_data.update_req = 1;
}
@@ -2372,7 +2372,7 @@ void rtw_signal_stat_timer_hdl23a(unsigned long data)
/* update_req is clear, means we got rx */
avg_signal_qual = recvpriv->signal_qual_data.avg_val;
num_signal_qual = recvpriv->signal_qual_data.total_num;
- /* after avg_vals are accquired, we can re-stat */
+ /* after avg_vals are acquired, we can re-stat */
/*the signal values */
recvpriv->signal_qual_data.update_req = 1;
}
diff --git a/drivers/staging/rtl8723au/core/rtw_sreset.c b/drivers/staging/rtl8723au/core/rtw_sreset.c
index 18a42a27b488..9a79e11f7ffc 100644
--- a/drivers/staging/rtl8723au/core/rtw_sreset.c
+++ b/drivers/staging/rtl8723au/core/rtw_sreset.c
@@ -23,7 +23,6 @@ void rtw_sreset_init(struct rtw_adapter *padapter)
mutex_init(&psrtpriv->silentreset_mutex);
psrtpriv->silent_reset_inprogress = false;
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
}
@@ -34,54 +33,10 @@ void rtw_sreset_reset_value(struct rtw_adapter *padapter)
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
psrtpriv->silent_reset_inprogress = false;
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
psrtpriv->last_tx_time = 0;
psrtpriv->last_tx_complete_time = 0;
}
-u8 rtw_sreset_get_wifi_status(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
- u8 status = WIFI_STATUS_SUCCESS;
- u32 val32 = 0;
-
- if (psrtpriv->silent_reset_inprogress)
- return status;
- val32 = rtl8723au_read32(padapter, REG_TXDMA_STATUS);
- if (val32 == 0xeaeaeaea) {
- psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
- } else if (val32 != 0) {
- DBG_8723A("txdmastatu(%x)\n", val32);
- psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
- }
-
- if (WIFI_STATUS_SUCCESS != psrtpriv->Wifi_Error_Status) {
- DBG_8723A("==>%s error_status(0x%x)\n", __func__, psrtpriv->Wifi_Error_Status);
- status = (psrtpriv->Wifi_Error_Status &~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL));
- }
- DBG_8723A("==> %s wifi_status(0x%x)\n", __func__, status);
-
- /* status restore */
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
-
- return status;
-}
-
-void sreset_set_wifi_error_status23a(struct rtw_adapter *padapter, u32 status)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->srestpriv.Wifi_Error_Status = status;
-}
-
-void sreset_set_trigger_point(struct rtw_adapter *padapter, s32 tgp)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
- pHalData->srestpriv.dbg_trigger_point = tgp;
-}
-
bool rtw_sreset_inprogress(struct rtw_adapter *padapter)
{
struct rtw_adapter *primary_adapter = GET_PRIMARY_ADAPTER(padapter);
@@ -148,7 +103,7 @@ static void sreset_restore_network_station(struct rtw_adapter *padapter)
hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
hw_var_set_mlme_join(padapter, 0);
- Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
+ rtl8723a_set_media_status(padapter, pmlmeinfo->state & 0x3);
mlmeext_joinbss_event_callback23a(padapter, 1);
/* restore Sequence No. */
@@ -242,8 +197,6 @@ void rtw_sreset_reset(struct rtw_adapter *active_adapter)
DBG_8723A("%s\n", __func__);
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
-
mutex_lock(&psrtpriv->silentreset_mutex);
psrtpriv->silent_reset_inprogress = true;
pwrpriv->change_rfpwrstate = rf_off;
diff --git a/drivers/staging/rtl8723au/core/rtw_sta_mgt.c b/drivers/staging/rtl8723au/core/rtw_sta_mgt.c
index 14a82bea826f..d17998da8600 100644
--- a/drivers/staging/rtl8723au/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8723au/core/rtw_sta_mgt.c
@@ -22,9 +22,11 @@
#include <sta_info.h>
#include <rtl8723a_hal.h>
+static const u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
static void _rtw_init_stainfo(struct sta_info *psta)
{
- memset((u8 *)psta, 0, sizeof (struct sta_info));
+ memset((u8 *)psta, 0, sizeof(struct sta_info));
spin_lock_init(&psta->lock);
INIT_LIST_HEAD(&psta->list);
INIT_LIST_HEAD(&psta->hash_list);
@@ -69,8 +71,10 @@ int _rtw_init_sta_priv23a(struct sta_priv *pstapriv)
pstapriv->auth_list_cnt = 0;
pstapriv->auth_to = 3; /* 3*2 = 6 sec */
pstapriv->assoc_to = 3;
- /* pstapriv->expire_to = 900; 900*2 = 1800 sec = 30 min, expire after no any traffic. */
- /* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min, expire after no any traffic. */
+ /* pstapriv->expire_to = 900; 900*2 = 1800 sec = 30 min,
+ expire after no any traffic. */
+ /* pstapriv->expire_to = 30; 30*2 = 60 sec = 1 min,
+ expire after no any traffic. */
pstapriv->expire_to = 3; /* 3*2 = 6 sec */
pstapriv->max_num_sta = NUM_STA;
#endif
@@ -92,6 +96,7 @@ int _rtw_free_sta_priv23a(struct sta_priv *pstapriv)
list_for_each_safe(plist, ptmp, phead) {
int i;
+
psta = container_of(plist, struct sta_info,
hash_list);
for (i = 0; i < 16 ; i++) {
@@ -107,7 +112,7 @@ int _rtw_free_sta_priv23a(struct sta_priv *pstapriv)
}
struct sta_info *
-rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr, gfp_t gfp)
+rtw_alloc_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr, gfp_t gfp)
{
struct list_head *phash_list;
struct sta_info *psta;
@@ -126,7 +131,7 @@ rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr, gfp_t gfp)
psta->padapter = pstapriv->padapter;
- memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
+ ether_addr_copy(psta->hwaddr, hwaddr);
index = wifi_mac_hash(hwaddr);
@@ -142,14 +147,17 @@ rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr, gfp_t gfp)
list_add_tail(&psta->hash_list, phash_list);
- pstapriv->asoc_sta_count ++ ;
+ pstapriv->asoc_sta_count++;
-/* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
-/* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
+/* For the SMC router, the sequence number of first packet of WPS
+ handshake will be 0. */
+/* In this case, this packet will be dropped by recv_decache function
+ if we use the 0x00 as the default value for tid_rxseq variable. */
/* So, we initialize the tid_rxseq variable as the 0xffff. */
for (i = 0; i < 16; i++)
- memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
+ memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
+ &wRxSeqInitialValue, 2);
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
("alloc number_%d stainfo with hwaddr = %pM\n",
@@ -240,8 +248,12 @@ int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
spin_unlock_bh(&pxmitpriv->lock);
list_del_init(&psta->hash_list);
- RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n", pstapriv->asoc_sta_count, psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4], psta->hwaddr[5]));
- pstapriv->asoc_sta_count --;
+ RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
+ ("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
+ pstapriv->asoc_sta_count, psta->hwaddr[0],
+ psta->hwaddr[1], psta->hwaddr[2], psta->hwaddr[3],
+ psta->hwaddr[4], psta->hwaddr[5]));
+ pstapriv->asoc_sta_count--;
/* re-init sta_info; 20061114 will be init in alloc_stainfo */
/* _rtw_init_sta_xmit_priv23a(&psta->sta_xmitpriv); */
@@ -249,7 +261,8 @@ int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
del_timer_sync(&psta->addba_retry_timer);
- /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
+ /* for A-MPDU Rx reordering buffer control,
+ cancel reordering_ctrl_timer */
for (i = 0; i < 16; i++) {
struct list_head *phead, *plist;
struct recv_frame *prframe;
@@ -259,7 +272,8 @@ int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
- ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
+ ppending_recvframe_queue =
+ &preorder_ctrl->pending_recvframe_queue;
spin_lock_bh(&ppending_recvframe_queue->lock);
phead = get_list_head(ppending_recvframe_queue);
@@ -299,7 +313,7 @@ int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta)
pstapriv->sta_dz_bitmap &= ~CHKBIT(psta->aid);
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
- if ((psta->aid >0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
+ if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
pstapriv->sta_aid[psta->aid - 1] = NULL;
psta->aid = 0;
}
@@ -316,7 +330,7 @@ void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
struct list_head *plist, *phead, *ptmp;
struct sta_info *psta;
struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info* pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
+ struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo23a(padapter);
s32 index;
if (pstapriv->asoc_sta_count == 1)
@@ -330,7 +344,7 @@ void rtw_free_all_stainfo23a(struct rtw_adapter *padapter)
list_for_each_safe(plist, ptmp, phead) {
psta = container_of(plist, struct sta_info, hash_list);
- if (pbcmc_stainfo!= psta)
+ if (pbcmc_stainfo != psta)
rtw_free_stainfo23a(padapter, psta);
}
}
@@ -344,7 +358,6 @@ struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
struct sta_info *psta = NULL;
u32 index;
const u8 *addr;
- u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
if (hwaddr == NULL)
return NULL;
@@ -363,25 +376,24 @@ struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr)
list_for_each(plist, phead) {
psta = container_of(plist, struct sta_info, hash_list);
- if (!memcmp(psta->hwaddr, addr, ETH_ALEN)) {
- /* if found the matched address */
+ /* if found the matched address */
+ if (ether_addr_equal(psta->hwaddr, addr))
break;
- }
+
psta = NULL;
}
spin_unlock_bh(&pstapriv->sta_hash_lock);
return psta;
}
-int rtw_init_bcmc_stainfo23a(struct rtw_adapter* padapter)
+int rtw_init_bcmc_stainfo23a(struct rtw_adapter *padapter)
{
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info *psta;
struct tx_servq *ptxservq;
int res = _SUCCESS;
- unsigned char bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- psta = rtw_alloc_stainfo23a(pstapriv, bcast_addr, GFP_KERNEL);
+ psta = rtw_alloc_stainfo23a(pstapriv, bc_addr, GFP_KERNEL);
if (psta == NULL) {
res = _FAIL;
RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
@@ -399,9 +411,8 @@ struct sta_info *rtw_get_bcmc_stainfo23a(struct rtw_adapter *padapter)
{
struct sta_info *psta;
struct sta_priv *pstapriv = &padapter->stapriv;
- u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- psta = rtw_get_stainfo23a(pstapriv, bc_addr);
+ psta = rtw_get_stainfo23a(pstapriv, bc_addr);
return psta;
}
@@ -422,7 +433,7 @@ bool rtw_access_ctrl23a(struct rtw_adapter *padapter, u8 *mac_addr)
list_for_each(plist, phead) {
paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
- if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
+ if (ether_addr_equal(paclnode->addr, mac_addr)) {
if (paclnode->valid) {
match = true;
break;
diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
index 579a4a8c8276..32f360301c77 100644
--- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
@@ -18,6 +18,7 @@
#include <drv_types.h>
#include <linux/ieee80211.h>
#include <wifi.h>
+#include <rtl8723a_spec.h>
static unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
static unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
@@ -293,11 +294,6 @@ void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen)
}
}
-void Set_MSR23a(struct rtw_adapter *padapter, u8 type)
-{
- rtl8723a_set_media_status(padapter, type);
-}
-
inline u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter)
{
return adapter_to_dvobj(adapter)->oper_channel;
@@ -360,10 +356,6 @@ void set_channel_bwmode23a(struct rtw_adapter *padapter, unsigned char channel,
{
u8 center_ch;
- if (padapter->bNotifyChannelChange)
- DBG_8723A("[%s] ch = %d, offset = %d, bwmode = %d\n",
- __func__, channel, channel_offset, bwmode);
-
if (bwmode == HT_CHANNEL_WIDTH_20 ||
channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) {
/* SelectChannel23a(padapter, channel); */
@@ -399,14 +391,6 @@ inline u8 *get_my_bssid23a(struct wlan_bssid_ex *pnetwork)
return pnetwork->MacAddress;
}
-u16 get_beacon_interval23a(struct wlan_bssid_ex *bss)
-{
- unsigned short val;
- memcpy(&val, rtw_get_beacon_interval23a_from_ie(bss->IEs), 2);
-
- return le16_to_cpu(val);
-}
-
bool is_client_associated_to_ap23a(struct rtw_adapter *padapter)
{
struct mlme_ext_priv *pmlmeext;
@@ -419,7 +403,7 @@ bool is_client_associated_to_ap23a(struct rtw_adapter *padapter)
pmlmeinfo = &pmlmeext->mlmext_info;
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
- (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
+ (pmlmeinfo->state & 0x03) == MSR_INFRA)
return true;
else
return false;
@@ -431,7 +415,7 @@ bool is_client_associated_to_ibss23a(struct rtw_adapter *padapter)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS &&
- (pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)
+ (pmlmeinfo->state & 0x03) == MSR_ADHOC)
return true;
else
return false;
@@ -461,11 +445,6 @@ unsigned int decide_wait_for_beacon_timeout23a(unsigned int bcn_interval)
return bcn_interval << 2;
}
-void invalidate_cam_all23a(struct rtw_adapter *padapter)
-{
- rtl8723a_cam_invalid_all(padapter);
-}
-
void clear_cam_entry23a(struct rtw_adapter *padapter, u8 entry)
{
unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@@ -499,12 +478,12 @@ void flush_all_cam_entry23a(struct rtw_adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- rtl8723a_cam_invalid_all(padapter);
+ rtl8723a_cam_invalidate_all(padapter);
memset(pmlmeinfo->FW_sta_info, 0, sizeof(pmlmeinfo->FW_sta_info));
}
-int WMM_param_handler23a(struct rtw_adapter *padapter, u8 *p)
+int WMM_param_handler23a(struct rtw_adapter *padapter, const u8 *p)
{
/* struct registry_priv *pregpriv = &padapter->registrypriv; */
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
@@ -633,9 +612,9 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter)
return;
}
-static void bwmode_update_check(struct rtw_adapter *padapter, u8 *p)
+static void bwmode_update_check(struct rtw_adapter *padapter, const u8 *p)
{
- struct HT_info_element *pHT_info;
+ struct ieee80211_ht_operation *pHT_info;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -648,19 +627,20 @@ static void bwmode_update_check(struct rtw_adapter *padapter, u8 *p)
return;
if (!phtpriv->ht_option)
return;
- if (p[1] > sizeof(struct HT_info_element))
+ if (p[1] != sizeof(struct ieee80211_ht_operation))
return;
- pHT_info = (struct HT_info_element *)(p + 2);
+ pHT_info = (struct ieee80211_ht_operation *)(p + 2);
- if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) {
+ if ((pHT_info->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) &&
+ pregistrypriv->cbw40_enable) {
new_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pHT_info->infos[0] & 0x3) {
- case 1:
+ switch (pHT_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET){
+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
break;
- case 3:
+ case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
break;
default:
@@ -711,7 +691,7 @@ static void bwmode_update_check(struct rtw_adapter *padapter, u8 *p)
}
}
-void HT_caps_handler23a(struct rtw_adapter *padapter, u8 *p)
+void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p)
{
unsigned int i;
u8 rf_type;
@@ -720,60 +700,60 @@ void HT_caps_handler23a(struct rtw_adapter *padapter, u8 *p)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
+ struct ieee80211_ht_cap *cap;
+ u8 *dstcap;
if (!p)
return;
- if (phtpriv->ht_option == false)
+ if (!phtpriv->ht_option)
return;
pmlmeinfo->HT_caps_enable = 1;
+ cap = &pmlmeinfo->ht_cap;
+ dstcap = (u8 *)cap;
for (i = 0; i < p[1]; i++) {
if (i != 2) {
- /* Commented by Albert 2010/07/12 */
- /* Got the endian issue here. */
- pmlmeinfo->HT_caps.u.HT_cap[i] &= p[i + 2];
+ dstcap[i] &= p[i + 2];
} else {
/* modify from fw by Thomas 2010/11/17 */
- if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (p[i + 2] & 0x3))
- max_AMPDU_len = p[i + 2] & 0x3;
+ if ((cap->ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR) >
+ (p[i + 2] & IEEE80211_HT_AMPDU_PARM_FACTOR))
+ max_AMPDU_len = p[i + 2] &
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
else
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3;
-
- if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (p[i + 2] & 0x1c))
- min_MPDU_spacing = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c;
+ max_AMPDU_len = cap->ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
+
+ if ((cap->ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY) >
+ (p[i + 2] & IEEE80211_HT_AMPDU_PARM_DENSITY))
+ min_MPDU_spacing = cap->ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY;
else
- min_MPDU_spacing = p[i + 2] & 0x1c;
+ min_MPDU_spacing = p[i + 2] &
+ IEEE80211_HT_AMPDU_PARM_DENSITY;
- pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para =
+ cap->ampdu_params_info =
max_AMPDU_len | min_MPDU_spacing;
}
}
- /* Commented by Albert 2010/07/12 */
- /* Have to handle the endian issue after copying. */
- /* HT_ext_caps didn't be used yet. */
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
- le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
- pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps =
- le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_ext_caps);
-
rf_type = rtl8723a_get_rf_type(padapter);
/* update the MCS rates */
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
if (rf_type == RF_1T1R || rf_type == RF_1T2R)
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &=
- MCS_rate_1R23A[i];
+ cap->mcs.rx_mask[i] &= MCS_rate_1R23A[i];
else
- pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &=
- MCS_rate_2R23A[i];
+ cap->mcs.rx_mask[i] &= MCS_rate_2R23A[i];
}
return;
}
-void HT_info_handler23a(struct rtw_adapter *padapter, u8 *p)
+void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -783,10 +763,10 @@ void HT_info_handler23a(struct rtw_adapter *padapter, u8 *p)
if (!p)
return;
- if (phtpriv->ht_option == false)
+ if (!phtpriv->ht_option)
return;
- if (p[1] > sizeof(struct HT_info_element))
+ if (p[1] != sizeof(struct ieee80211_ht_operation))
return;
pmlmeinfo->HT_info_enable = 1;
@@ -818,16 +798,18 @@ void HTOnAssocRsp23a(struct rtw_adapter *padapter)
AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
AMPDU_para [4:2]:Min MPDU Start Spacing
*/
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
+ max_AMPDU_len = pmlmeinfo->ht_cap.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
min_MPDU_spacing =
- (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
+ (pmlmeinfo->ht_cap.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
rtl8723a_set_ampdu_min_space(padapter, min_MPDU_spacing);
rtl8723a_set_ampdu_factor(padapter, max_AMPDU_len);
}
-void ERP_IE_handler23a(struct rtw_adapter *padapter, u8 *p)
+void ERP_IE_handler23a(struct rtw_adapter *padapter, const u8 *p)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -881,110 +863,48 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
struct ieee80211_mgmt *mgmt, u32 pkt_len)
{
struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
- struct HT_info_element *pht_info;
- struct ieee80211_ht_cap *pht_cap;
- struct wlan_bssid_ex *bssid;
+ struct ieee80211_ht_operation *pht_info;
unsigned short val16;
- u16 wpa_len = 0, rsn_len = 0;
- u8 encryp_protocol;
+ u8 crypto, bcn_channel;
int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0, r;
- u32 bcn_channel;
- unsigned short ht_cap_info;
- unsigned char ht_info_infos_0;
- int len, pie_len, ie_offset;
- const u8 *p;
- u8 *pie;
+ int pie_len, ssid_len, privacy;
+ const u8 *p, *ssid;
if (is_client_associated_to_ap23a(Adapter) == false)
- return true;
+ return _SUCCESS;
if (unlikely(!ieee80211_is_beacon(mgmt->frame_control))) {
printk(KERN_WARNING "%s: received a non beacon frame!\n",
__func__);
- return false;
- }
-
- len = pkt_len - sizeof(struct ieee80211_hdr_3addr);
-
- if (len > MAX_IE_SZ) {
- DBG_8723A("%s IE too long for survey event\n", __func__);
return _FAIL;
}
- if (memcmp(cur_network->network.MacAddress, mgmt->bssid, 6)) {
- DBG_8723A("Oops: rtw_check_network_encrypt linked but recv "
- "other bssid bcn\n" MAC_FMT MAC_FMT,
- MAC_ARG(mgmt->bssid),
+ if (!ether_addr_equal(cur_network->network.MacAddress, mgmt->bssid)) {
+ DBG_8723A("%s: linked but recv other bssid bcn"
+ MAC_FMT MAC_FMT "\n", __func__, MAC_ARG(mgmt->bssid),
MAC_ARG(cur_network->network.MacAddress));
- return true;
- }
-
- bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
- if (!bssid)
return _FAIL;
-
- bssid->reserved = 1;
-
- bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + len;
-
- /* below is to copy the information element */
- bssid->IELength = len;
- memcpy(bssid->IEs, &mgmt->u, len);
+ }
/* check bw and channel offset */
/* parsing HT_CAP_IE */
- ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u);
- pie = bssid->IEs + ie_offset;
- pie_len = pkt_len - ie_offset;
-
- p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
- if (p && p[1] > 0) {
- pht_cap = (struct ieee80211_ht_cap *)(p + 2);
- ht_cap_info = pht_cap->cap_info;
- } else {
- pht_cap = NULL;
- ht_cap_info = 0;
- }
-
- /* parsing HT_INFO_IE */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, pie_len);
- if (p && p[1] > 0) {
- pht_info = (struct HT_info_element *)(p + 2);
- ht_info_infos_0 = pht_info->infos[0];
- } else {
- pht_info = NULL;
- ht_info_infos_0 = 0;
- }
-
- if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
- ((ht_info_infos_0 & 0x03) !=
- (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
- DBG_8723A("%s bcn now: ht_cap_info:%x ht_info_infos_0:%x\n",
- __func__, ht_cap_info, ht_info_infos_0);
- DBG_8723A("%s bcn link: ht_cap_info:%x ht_info_infos_0:%x\n",
- __func__, cur_network->BcnInfo.ht_cap_info,
- cur_network->BcnInfo.ht_info_infos_0);
- DBG_8723A("%s bw mode change, disconnect\n", __func__);
- /* bcn_info_update */
- cur_network->BcnInfo.ht_cap_info = ht_cap_info;
- cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
- /* to do : need to check that whether modify related
- register of BB or not */
- }
+ pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
/* Checking for channel */
- p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, pie, pie_len);
+ p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, mgmt->u.beacon.variable,
+ pie_len);
if (p)
bcn_channel = p[2];
else {
/* In 5G, some ap do not have DSSET IE checking HT
info for channel */
- p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, pie_len);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+ mgmt->u.beacon.variable, pie_len);
- if (pht_info)
- bcn_channel = pht_info->primary_channel;
- else { /* we don't find channel IE, so don't check it */
+ if (p && p[1] > 0) {
+ pht_info = (struct ieee80211_ht_operation *)(p + 2);
+ bcn_channel = pht_info->primary_chan;
+ } else { /* we don't find channel IE, so don't check it */
DBG_8723A("Oops: %s we don't find channel IE, so don't "
"check it\n", __func__);
bcn_channel = Adapter->mlmeextpriv.cur_channel;
@@ -998,76 +918,65 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
}
/* checking SSID */
- p = cfg80211_find_ie(WLAN_EID_SSID, pie, pie_len);
+ p = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.beacon.variable, pie_len);
if (p && p[1]) {
- memcpy(bssid->Ssid.ssid, p + 2, p[1]);
- bssid->Ssid.ssid_len = p[1];
+ ssid = p + 2;
+ ssid_len = p[1];
} else {
DBG_8723A("%s marc: cannot find SSID for survey event\n",
__func__);
- bssid->Ssid.ssid_len = 0;
- bssid->Ssid.ssid[0] = '\0';
+ ssid = NULL;
+ ssid_len = 0;
}
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d "
"cur_network->network.Ssid.Ssid:%s len:%d\n", __func__,
- bssid->Ssid.ssid, bssid->Ssid.ssid_len,
- cur_network->network.Ssid.ssid,
+ ssid, ssid_len, cur_network->network.Ssid.ssid,
cur_network->network.Ssid.ssid_len));
- if (memcmp(bssid->Ssid.ssid, cur_network->network.Ssid.ssid, 32) ||
- bssid->Ssid.ssid_len != cur_network->network.Ssid.ssid_len) {
- if (bssid->Ssid.ssid[0] != '\0' &&
- bssid->Ssid.ssid_len != 0) { /* not hidden ssid */
- DBG_8723A("%s(), SSID is not match return FAIL\n",
- __func__);
- goto _mismatch;
- }
+ if (ssid_len != cur_network->network.Ssid.ssid_len || ssid_len > 32 ||
+ (ssid_len &&
+ memcmp(ssid, cur_network->network.Ssid.ssid, ssid_len))) {
+ DBG_8723A("%s(), SSID is not match return FAIL\n", __func__);
+ goto _mismatch;
}
/* check encryption info */
- val16 = rtw_get_capability23a(bssid);
+ val16 = le16_to_cpu(mgmt->u.beacon.capab_info);
- if (val16 & BIT(4))
- bssid->Privacy = 1;
+ if (val16 & WLAN_CAPABILITY_PRIVACY)
+ privacy = 1;
else
- bssid->Privacy = 0;
+ privacy = 0;
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
("%s(): cur_network->network.Privacy is %d, bssid.Privacy "
- "is %d\n", __func__, cur_network->network.Privacy,
- bssid->Privacy));
- if (cur_network->network.Privacy != bssid->Privacy) {
+ "is %d\n", __func__, cur_network->network.Privacy, privacy));
+ if (cur_network->network.Privacy != privacy) {
DBG_8723A("%s(), privacy is not match return FAIL\n", __func__);
goto _mismatch;
}
- rtw_get_sec_ie23a(bssid->IEs, bssid->IELength, NULL, &rsn_len, NULL,
- &wpa_len);
-
- if (rsn_len > 0)
- encryp_protocol = ENCRYP_PROTOCOL_WPA2;
- else if (wpa_len > 0)
- encryp_protocol = ENCRYP_PROTOCOL_WPA;
- else {
- if (bssid->Privacy)
- encryp_protocol = ENCRYP_PROTOCOL_WEP;
- else
- encryp_protocol = ENCRYP_PROTOCOL_OPENSYS;
- }
-
- if (cur_network->BcnInfo.encryp_protocol != encryp_protocol) {
- DBG_8723A("%s(): enctyp is not match, return FAIL\n", __func__);
- goto _mismatch;
- }
-
- if (encryp_protocol == ENCRYP_PROTOCOL_WPA ||
- encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
+ p = cfg80211_find_ie(WLAN_EID_RSN, mgmt->u.beacon.variable, pie_len);
+ if (p && p[1]) {
+ crypto = ENCRYP_PROTOCOL_WPA2;
+ if (p && p[1]) {
+ r = rtw_parse_wpa2_ie23a(p, p[1] + 2, &group_cipher,
+ &pairwise_cipher, &is_8021x);
+ if (r == _SUCCESS)
+ RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
+ ("%s pnetwork->pairwise_cipher: %d, "
+ "pnetwork->group_cipher: %d, is_802x "
+ ": %d\n", __func__, pairwise_cipher,
+ group_cipher, is_8021x));
+ }
+ } else {
p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA,
- pie, pie_len);
- if (p && p[1] > 0) {
+ mgmt->u.beacon.variable, pie_len);
+ if (p && p[1]) {
+ crypto = ENCRYP_PROTOCOL_WPA;
r = rtw_parse_wpa_ie23a(p, p[1] + 2, &group_cipher,
&pairwise_cipher, &is_8021x);
if (r == _SUCCESS)
@@ -1077,24 +986,19 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
"%d\n", __func__, pairwise_cipher,
group_cipher, is_8021x));
} else {
- p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
-
- if (p && p[1] > 0) {
- r = rtw_parse_wpa2_ie23a(p, p[1] + 2,
- &group_cipher,
- &pairwise_cipher,
- &is_8021x);
- if (r == _SUCCESS)
- RT_TRACE(_module_rtl871x_mlme_c_,
- _drv_info_,
- ("%s pnetwork->pairwise_cipher"
- ": %d, pnetwork->group_cipher"
- " is %d, is_802x is %d\n",
- __func__, pairwise_cipher,
- group_cipher, is_8021x));
- }
+ if (privacy)
+ crypto = ENCRYP_PROTOCOL_WEP;
+ else
+ crypto = ENCRYP_PROTOCOL_OPENSYS;
}
+ }
+ if (cur_network->BcnInfo.encryp_protocol != crypto) {
+ DBG_8723A("%s(): encryption mismatch, return FAIL\n", __func__);
+ goto _mismatch;
+ }
+
+ if (crypto == ENCRYP_PROTOCOL_WPA || crypto == ENCRYP_PROTOCOL_WPA2) {
RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
("%s cur_network->group_cipher is %d: %d\n", __func__,
cur_network->BcnInfo.group_cipher, group_cipher));
@@ -1116,41 +1020,31 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
}
}
- kfree(bssid);
return _SUCCESS;
_mismatch:
- kfree(bssid);
return _FAIL;
}
-void update_beacon23a_info(struct rtw_adapter *padapter, u8 *pframe,
+void update_beacon23a_info(struct rtw_adapter *padapter,
+ struct ieee80211_mgmt *mgmt,
uint pkt_len, struct sta_info *psta)
{
- unsigned int i;
unsigned int len;
- u8 *p;
+ const u8 *p;
- len = pkt_len -
- (_BEACON_IE_OFFSET_ + sizeof(struct ieee80211_hdr_3addr));
+ len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
- for (i = 0; i < len;) {
- p = (u8 *)(pframe + (_BEACON_IE_OFFSET_ + sizeof(struct ieee80211_hdr_3addr)) + i);
+ p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, mgmt->u.beacon.variable,
+ len);
+ if (p)
+ bwmode_update_check(padapter, p);
- switch (p[0]) {
- case WLAN_EID_HT_OPERATION: /* HT info */
- /* HT_info_handler23a(padapter, pIE); */
- bwmode_update_check(padapter, p);
- break;
- case WLAN_EID_ERP_INFO:
- ERP_IE_handler23a(padapter, p);
- VCS_update23a(padapter, psta);
- break;
- default:
- break;
- }
- i += (p[1] + 2);
+ p = cfg80211_find_ie(WLAN_EID_ERP_INFO, mgmt->u.beacon.variable, len);
+ if (p) {
+ ERP_IE_handler23a(padapter, p);
+ VCS_update23a(padapter, psta);
}
}
@@ -1161,13 +1055,9 @@ bool is_ap_in_tkip23a(struct rtw_adapter *padapter)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
const u8 *p;
- int bcn_fixed_size;
-
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
- if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
- for (i = bcn_fixed_size; i < pmlmeinfo->network.IELength;) {
+ if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
+ for (i = 0; i < pmlmeinfo->network.IELength;) {
p = pmlmeinfo->network.IEs + i;
switch (p[0]) {
@@ -1196,13 +1086,9 @@ bool should_forbid_n_rate23a(struct rtw_adapter * padapter)
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *cur_network = &pmlmepriv->cur_network.network;
const u8 *p;
- int bcn_fixed_size;
-
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
- if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
- for (i = bcn_fixed_size; i < cur_network->IELength;) {
+ if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
+ for (i = 0; i < cur_network->IELength;) {
p = cur_network->IEs + i;
switch (p[0]) {
@@ -1239,13 +1125,9 @@ bool is_ap_in_wep23a(struct rtw_adapter *padapter)
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
const u8 *p;
- int bcn_fixed_size;
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
- if (rtw_get_capability23a(cur_network) & WLAN_CAPABILITY_PRIVACY) {
- for (i = bcn_fixed_size; i < pmlmeinfo->network.IELength;) {
+ if (cur_network->capability & WLAN_CAPABILITY_PRIVACY) {
+ for (i = 0; i < pmlmeinfo->network.IELength;) {
p = pmlmeinfo->network.IEs + i;
switch (p[0]) {
@@ -1340,18 +1222,18 @@ unsigned int update_supported_rate23a(unsigned char *ptn, unsigned int ptn_sz)
return mask;
}
-unsigned int update_MSC_rate23a(struct HT_caps_element *pHT_caps)
+unsigned int update_MSC_rate23a(struct ieee80211_ht_cap *pHT_caps)
{
unsigned int mask = 0;
- mask = pHT_caps->u.HT_cap_element.MCS_rate[0] << 12 |
- pHT_caps->u.HT_cap_element.MCS_rate[1] << 20;
+ mask = pHT_caps->mcs.rx_mask[0] << 12 |
+ pHT_caps->mcs.rx_mask[1] << 20;
return mask;
}
int support_short_GI23a(struct rtw_adapter *padapter,
- struct HT_caps_element *pHT_caps)
+ struct ieee80211_ht_cap *pHT_caps)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
@@ -1363,7 +1245,7 @@ int support_short_GI23a(struct rtw_adapter *padapter,
return _FAIL;
bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40)? 6: 5;
- if (pHT_caps->u.HT_cap_element.HT_caps_info & (0x1 << bit_offset))
+ if (pHT_caps->cap_info & cpu_to_le16(0x1 << bit_offset))
return _SUCCESS;
else
return _FAIL;
@@ -1425,17 +1307,14 @@ void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 wirelessmode)
unsigned char check_assoc_AP23a(u8 *pframe, uint len)
{
- int i, bcn_fixed_size;
+ int i;
u8 epigram_vendor_flag;
u8 ralink_vendor_flag;
const u8 *p;
epigram_vendor_flag = 0;
ralink_vendor_flag = 0;
- bcn_fixed_size = offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
-
- for (i = bcn_fixed_size; i < len;) {
+ for (i = 0; i < len;) {
p = pframe + i;
switch (p[0]) {
@@ -1678,28 +1557,3 @@ void process_addba_req23a(struct rtw_adapter *padapter,
true : false;
}
}
-
-static struct rtw_adapter *pbuddy_padapter;
-
-int rtw_handle_dualmac23a(struct rtw_adapter *adapter, bool init)
-{
- int status = _SUCCESS;
-
- if (init) {
- if (pbuddy_padapter == NULL) {
- pbuddy_padapter = adapter;
- DBG_8723A("%s(): pbuddy_padapter == NULL, "
- "Set pbuddy_padapter\n", __func__);
- } else {
- adapter->pbuddy_adapter = pbuddy_padapter;
- pbuddy_padapter->pbuddy_adapter = adapter;
- /* clear global value */
- pbuddy_padapter = NULL;
- DBG_8723A("%s(): pbuddy_padapter exist, "
- "Exchange Information\n", __func__);
- }
- } else
- pbuddy_padapter = NULL;
-
- return status;
-}
diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c
index b917526f570a..d83af877ad6f 100644
--- a/drivers/staging/rtl8723au/core/rtw_xmit.c
+++ b/drivers/staging/rtl8723au/core/rtw_xmit.c
@@ -1197,7 +1197,7 @@ int rtw_xmitframe_coalesce23a(struct rtw_adapter *padapter, struct sk_buff *skb,
mpdu_len -= pattrib->icv_len;
if (bmcst)
- /* don't do fragment to broadcat/multicast packets */
+ /* don't do fragment to broadcast/multicast packets */
mem_sz = min_t(s32, data_len, pattrib->pktlen);
else
mem_sz = min_t(s32, data_len, mpdu_len);
@@ -2011,7 +2011,7 @@ int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter, struct x
/* DBG_8723A("enqueue, sq_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
- /* tx bc/mc packets after upate bcn */
+ /* tx bc/mc packets after update bcn */
update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
/* spin_unlock_bh(&psta->sleep_q.lock); */
@@ -2068,7 +2068,7 @@ int xmitframe_enqueue_for_sleeping_sta23a(struct rtw_adapter *padapter, struct x
pstapriv->tim_bitmap |= CHKBIT(psta->aid);
if (psta->sleepq_len == 1) {
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
update_beacon23a(padapter, WLAN_EID_TIM,
NULL, false);
}
@@ -2227,7 +2227,7 @@ void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
if (psta->sleepq_len == 0) {
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
update_mask = BIT(0);
if (psta->state&WIFI_SLEEP_STATE)
@@ -2274,7 +2274,7 @@ void wakeup_sta_to_xmit23a(struct rtw_adapter *padapter, struct sta_info *psta)
pstapriv->tim_bitmap &= ~BIT(0);
pstapriv->sta_dz_bitmap &= ~BIT(0);
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
/* update_BCNTIM(padapter); */
update_mask |= BIT(1);
}
@@ -2348,7 +2348,7 @@ void xmit_delivery_enabled_frames23a(struct rtw_adapter *padapter,
(wmmps_ac)) {
pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
- /* upate BCN for TIM IE */
+ /* update BCN for TIM IE */
update_beacon23a(padapter, WLAN_EID_TIM, NULL, false);
}
}
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c
index 294e6a6c60db..9d4f6bed4269 100644
--- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c
+++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c
@@ -564,163 +564,3 @@ void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm)
}
}
}
-
-/******************************************************************************
-* PHY_REG_PG.TXT
-******************************************************************************/
-
-static u32 Array_PHY_REG_PG_8723A[] = {
- 0xE00, 0xFFFFFFFF, 0x0A0C0C0C,
- 0xE04, 0xFFFFFFFF, 0x02040608,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x0A0C0D0E,
- 0xE14, 0xFFFFFFFF, 0x02040608,
- 0xE18, 0xFFFFFFFF, 0x0A0C0D0E,
- 0xE1C, 0xFFFFFFFF, 0x02040608,
- 0x830, 0xFFFFFFFF, 0x0A0C0C0C,
- 0x834, 0xFFFFFFFF, 0x02040608,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x0A0C0D0E,
- 0x848, 0xFFFFFFFF, 0x02040608,
- 0x84C, 0xFFFFFFFF, 0x0A0C0D0E,
- 0x868, 0xFFFFFFFF, 0x02040608,
- 0xE00, 0xFFFFFFFF, 0x00000000,
- 0xE04, 0xFFFFFFFF, 0x00000000,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x00000000,
- 0xE14, 0xFFFFFFFF, 0x00000000,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x00000000,
- 0x834, 0xFFFFFFFF, 0x00000000,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x00000000,
- 0x848, 0xFFFFFFFF, 0x00000000,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
- 0xE00, 0xFFFFFFFF, 0x04040404,
- 0xE04, 0xFFFFFFFF, 0x00020204,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x06060606,
- 0xE14, 0xFFFFFFFF, 0x00020406,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x04040404,
- 0x834, 0xFFFFFFFF, 0x00020204,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x06060606,
- 0x848, 0xFFFFFFFF, 0x00020406,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
- 0xE00, 0xFFFFFFFF, 0x00000000,
- 0xE04, 0xFFFFFFFF, 0x00000000,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x00000000,
- 0xE14, 0xFFFFFFFF, 0x00000000,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x00000000,
- 0x834, 0xFFFFFFFF, 0x00000000,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x00000000,
- 0x848, 0xFFFFFFFF, 0x00000000,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
- 0xE00, 0xFFFFFFFF, 0x00000000,
- 0xE04, 0xFFFFFFFF, 0x00000000,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x00000000,
- 0xE14, 0xFFFFFFFF, 0x00000000,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x00000000,
- 0x834, 0xFFFFFFFF, 0x00000000,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x00000000,
- 0x848, 0xFFFFFFFF, 0x00000000,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
- 0xE00, 0xFFFFFFFF, 0x04040404,
- 0xE04, 0xFFFFFFFF, 0x00020204,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x00000000,
- 0xE14, 0xFFFFFFFF, 0x00000000,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x04040404,
- 0x834, 0xFFFFFFFF, 0x00020204,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x00000000,
- 0x848, 0xFFFFFFFF, 0x00000000,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
- 0xE00, 0xFFFFFFFF, 0x00000000,
- 0xE04, 0xFFFFFFFF, 0x00000000,
- 0xE08, 0x0000FF00, 0x00000000,
- 0x86C, 0xFFFFFF00, 0x00000000,
- 0xE10, 0xFFFFFFFF, 0x00000000,
- 0xE14, 0xFFFFFFFF, 0x00000000,
- 0xE18, 0xFFFFFFFF, 0x00000000,
- 0xE1C, 0xFFFFFFFF, 0x00000000,
- 0x830, 0xFFFFFFFF, 0x00000000,
- 0x834, 0xFFFFFFFF, 0x00000000,
- 0x838, 0xFFFFFF00, 0x00000000,
- 0x86C, 0x000000FF, 0x00000000,
- 0x83C, 0xFFFFFFFF, 0x00000000,
- 0x848, 0xFFFFFFFF, 0x00000000,
- 0x84C, 0xFFFFFFFF, 0x00000000,
- 0x868, 0xFFFFFFFF, 0x00000000,
-};
-
-void ODM_ReadAndConfig_PHY_REG_PG_8723A(struct dm_odm_t *pDM_Odm)
-{
- u32 hex = 0;
- u32 i = 0;
- u8 platform = 0x04;
- u8 interfaceValue = pDM_Odm->SupportInterface;
- u8 board = pDM_Odm->BoardType;
- u32 ArrayLen = sizeof(Array_PHY_REG_PG_8723A)/sizeof(u32);
- u32 *Array = Array_PHY_REG_PG_8723A;
-
- hex += board;
- hex += interfaceValue << 8;
- hex += platform << 16;
- hex += 0xFF000000;
- for (i = 0; i < ArrayLen; i += 3) {
- u32 v1 = Array[i];
- u32 v2 = Array[i+1];
- u32 v3 = Array[i+2];
-
- /* this line is a line of pure_body */
- if (v1 < 0xCDCDCDCD) {
- odm_ConfigBB_PHY_REG_PG_8723A(pDM_Odm, v1, v2, v3);
- continue;
- } else { /* this line is the start of branch */
- if (!CheckCondition(Array[i], hex)) {
- /* don't need the hw_body */
- i += 2; /* skip the pair of expression */
- v1 = Array[i];
- v2 = Array[i+1];
- v3 = Array[i+2];
- while (v2 != 0xDEAD) {
- i += 3;
- v1 = Array[i];
- v2 = Array[i+1];
- v3 = Array[i+1];
- }
- }
- }
- }
-}
diff --git a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c
index 0f2ae05c8eae..00480f5fcdab 100644
--- a/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c
+++ b/drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c
@@ -230,7 +230,7 @@ void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm)
/* This (offset, data) pair meets the condition. */
if (v1 < 0xCDCDCDCD) {
- odm_ConfigRF_RadioA_8723A(pDM_Odm, v1, v2);
+ odm_ConfigRFReg_8723A(pDM_Odm, v1, v2, RF_PATH_A, v1);
continue;
} else {
if (!CheckCondition(Array[i], hex)) {
@@ -247,7 +247,8 @@ void ODM_ReadAndConfig_RadioA_1T_8723A(struct dm_odm_t *pDM_Odm)
while (v2 != 0xDEAD &&
v2 != 0xCDEF &&
v2 != 0xCDCD && i < ArrayLen - 2) {
- odm_ConfigRF_RadioA_8723A(pDM_Odm, v1, v2);
+ odm_ConfigRFReg_8723A(pDM_Odm, v1, v2,
+ RF_PATH_A, v1);
READ_NEXT_PAIR(v1, v2, i);
}
diff --git a/drivers/staging/rtl8723au/hal/hal_com.c b/drivers/staging/rtl8723au/hal/hal_com.c
index 9fba04945152..8f299ec89bb9 100644
--- a/drivers/staging/rtl8723au/hal/hal_com.c
+++ b/drivers/staging/rtl8723au/hal/hal_com.c
@@ -567,8 +567,8 @@ void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag)
pmlmeinfo = &pmlmeext->mlmext_info;
if ((is_client_associated_to_ap23a(padapter) == true) ||
- ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
- ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
+ ((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
+ ((pmlmeinfo->state & 0x03) == MSR_AP)) {
/* enable to rx data frame */
rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
@@ -669,16 +669,16 @@ void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex)
("rtl8723a_cam_empty_entry(): WRITE A4: %lx \n",
ulContent));*/
/* delay_ms(40); */
- rtl8723au_write32(padapter, RWCAM, ulCommand);
+ rtl8723au_write32(padapter, REG_CAMCMD, ulCommand);
/* RT_TRACE(COMP_SEC, DBG_LOUD,
("rtl8723a_cam_empty_entry(): WRITE A0: %lx \n",
ulCommand));*/
}
}
-void rtl8723a_cam_invalid_all(struct rtw_adapter *padapter)
+void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter)
{
- rtl8723au_write32(padapter, RWCAM, BIT(31) | BIT(30));
+ rtl8723au_write32(padapter, REG_CAMCMD, CAM_POLLINIG | BIT(30));
}
void rtl8723a_cam_write(struct rtw_adapter *padapter,
@@ -708,7 +708,7 @@ void rtl8723a_cam_write(struct rtw_adapter *padapter,
rtl8723au_write32(padapter, WCAMI, val);
cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
- rtl8723au_write32(padapter, RWCAM, cmd);
+ rtl8723au_write32(padapter, REG_CAMCMD, cmd);
/* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
}
@@ -818,24 +818,6 @@ void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val)
rtl8723au_write8(padapter, REG_RXDMA_AGG_PG_TH, val);
}
-void rtl8723a_set_nav_upper(struct rtw_adapter *padapter, u32 usNavUpper)
-{
- if (usNavUpper > HAL_8723A_NAV_UPPER_UNIT * 0xFF) {
- RT_TRACE(_module_hal_init_c_, _drv_notice_,
- ("The setting value (0x%08X us) of NAV_UPPER "
- "is larger than (%d * 0xFF)!!!\n",
- usNavUpper, HAL_8723A_NAV_UPPER_UNIT));
- return;
- }
-
- /* The value of ((usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) /
- HAL_8723A_NAV_UPPER_UNIT) */
- /* is getting the upper integer. */
- usNavUpper = (usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) /
- HAL_8723A_NAV_UPPER_UNIT;
- rtl8723au_write8(padapter, REG_NAV_UPPER, (u8) usNavUpper);
-}
-
void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain)
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
@@ -867,12 +849,10 @@ void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- if (val == DYNAMIC_ALL_FUNC_ENABLE) {
- pHalData->dmpriv.DMFlag = pHalData->dmpriv.InitDMFlag;
+ if (val == DYNAMIC_ALL_FUNC_ENABLE)
pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
- } else {
+ else
pHalData->odmpriv.SupportAbility |= val;
- }
}
void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val)
diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c
index e15ebfe1881b..1c0f106d5996 100644
--- a/drivers/staging/rtl8723au/hal/odm.c
+++ b/drivers/staging/rtl8723au/hal/odm.c
@@ -166,12 +166,10 @@ u8 CCKSwingTable_Ch1423A[CCK_TABLE_SIZE][8] = {
/* START------------COMMON INFO RELATED--------------- */
void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm);
-void odm_CommonInfoSelfUpdate23a(struct dm_odm_t *pDM_Odm);
+static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData);
void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm);
-void odm_CmnInfoHook_Debug23a(struct dm_odm_t *pDM_Odm);
-
void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm);
/* START---------------DIG--------------------------- */
@@ -179,7 +177,7 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm);
void odm_DIG23aInit(struct dm_odm_t *pDM_Odm);
-void odm_DIG23a(struct dm_odm_t *pDM_Odm);
+void odm_DIG23a(struct rtw_adapter *adapter);
void odm_CCKPacketDetectionThresh23a(struct dm_odm_t *pDM_Odm);
/* END---------------DIG--------------------------- */
@@ -210,18 +208,6 @@ void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm);
void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm);
void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
-void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm);
-
-void odm_SwAntDivInit_NIC(struct dm_odm_t *pDM_Odm);
-
-void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step);
-
-void odm_SwAntDivChkAntSwitchNIC(struct dm_odm_t *pDM_Odm,
- u8 Step
- );
-
-void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data);
-
void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm);
void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
@@ -238,16 +224,12 @@ void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm);
void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm);
-void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
-void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm);
-
-void odm_EdcaTurboCheck23aCE23a(struct dm_odm_t *pDM_Odm);
+static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
+static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm);
#define RxDefaultAnt1 0x65a9
#define RxDefaultAnt2 0x569a
-void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm);
-
bool odm_StaDefAntSel(struct dm_odm_t *pDM_Odm,
u32 OFDM_Ant1_Cnt,
u32 OFDM_Ant2_Cnt,
@@ -261,8 +243,6 @@ void odm_SetRxIdleAnt(struct dm_odm_t *pDM_Odm,
bool bDualPath
);
-void odm_HwAntDiv23a(struct dm_odm_t *pDM_Odm);
-
/* 3 Export Interface */
/* 2011/09/21 MH Add to describe different team necessary resource allocate?? */
@@ -274,29 +254,24 @@ void ODM23a_DMInit(struct dm_odm_t *pDM_Odm)
odm_DIG23aInit(pDM_Odm);
odm_RateAdaptiveMaskInit23a(pDM_Odm);
- if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) {
- odm23a_DynBBPSInit(pDM_Odm);
- odm_DynamicTxPower23aInit(pDM_Odm);
- odm_TXPowerTrackingInit23a(pDM_Odm);
- ODM_EdcaTurboInit23a(pDM_Odm);
- if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) ||
- (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) ||
- (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV))
- odm_InitHybridAntDiv23a(pDM_Odm);
- else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV)
- odm_SwAntDivInit(pDM_Odm);
- }
+ odm23a_DynBBPSInit(pDM_Odm);
+ odm_DynamicTxPower23aInit(pDM_Odm);
+ odm_TXPowerTrackingInit23a(pDM_Odm);
+ ODM_EdcaTurboInit23a(pDM_Odm);
}
/* 2011/09/20 MH This is the entry pointer for all team to execute HW out source DM. */
/* You can not add any dummy function here, be care, you can only use DM structure */
/* to perform any new ODM_DM. */
-void ODM_DMWatchdog23a(struct dm_odm_t *pDM_Odm)
+void ODM_DMWatchdog23a(struct rtw_adapter *adapter)
{
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
+ struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
+ struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
+
/* 2012.05.03 Luke: For all IC series */
- odm_CmnInfoHook_Debug23a(pDM_Odm);
odm_CmnInfoUpdate_Debug23a(pDM_Odm);
- odm_CommonInfoSelfUpdate23a(pDM_Odm);
+ odm_CommonInfoSelfUpdate(pHalData);
odm_FalseAlarmCounterStatistics23a(pDM_Odm);
odm_RSSIMonitorCheck23a(pDM_Odm);
@@ -304,33 +279,25 @@ void ODM_DMWatchdog23a(struct dm_odm_t *pDM_Odm)
/* NeilChen--2012--08--24-- */
/* Fix Leave LPS issue */
if ((pDM_Odm->Adapter->pwrctrlpriv.pwr_mode != PS_MODE_ACTIVE) &&/* in LPS mode */
- (pDM_Odm->SupportICType & (ODM_RTL8723A))) {
+ (pDM_Odm->SupportICType & ODM_RTL8723A)) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("----Step1: odm_DIG23a is in LPS mode\n"));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("---Step2: 8723AS is in LPS mode\n"));
odm_DIG23abyRSSI_LPS(pDM_Odm);
} else {
- odm_DIG23a(pDM_Odm);
+ odm_DIG23a(adapter);
}
odm_CCKPacketDetectionThresh23a(pDM_Odm);
- if (*(pDM_Odm->pbPowerSaving))
+ if (pwrctrlpriv->bpower_saving)
return;
odm_RefreshRateAdaptiveMask23a(pDM_Odm);
odm_DynamicBBPowerSaving23a(pDM_Odm);
- if ((pDM_Odm->AntDivType == CG_TRX_HW_ANTDIV) ||
- (pDM_Odm->AntDivType == CGCS_RX_HW_ANTDIV) ||
- (pDM_Odm->AntDivType == CG_TRX_SMART_ANTDIV))
- odm_HwAntDiv23a(pDM_Odm);
- else if (pDM_Odm->AntDivType == CGCS_RX_SW_ANTDIV)
- odm_SwAntDivChkAntSwitch(pDM_Odm, SWAW_STEP_PEAK);
-
- if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) {
- ODM_TXPowerTrackingCheck23a(pDM_Odm);
- odm_EdcaTurboCheck23a(pDM_Odm);
- }
+
+ ODM_TXPowerTrackingCheck23a(pDM_Odm);
+ odm_EdcaTurboCheck23a(pDM_Odm);
odm_dtc(pDM_Odm);
}
@@ -350,9 +317,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm,
/* */
switch (CmnInfo) {
/* Fixed ODM value. */
- case ODM_CMNINFO_ABILITY:
- pDM_Odm->SupportAbility = (u32)Value;
- break;
case ODM_CMNINFO_PLATFORM:
break;
case ODM_CMNINFO_INTERFACE:
@@ -373,9 +337,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm,
case ODM_CMNINFO_RF_TYPE:
pDM_Odm->RFType = (u8)Value;
break;
- case ODM_CMNINFO_RF_ANTENNA_TYPE:
- pDM_Odm->AntDivType = (u8)Value;
- break;
case ODM_CMNINFO_BOARD_TYPE:
pDM_Odm->BoardType = (u8)Value;
break;
@@ -416,81 +377,6 @@ void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm,
}
-void ODM23a_CmnInfoHook(struct dm_odm_t *pDM_Odm,
- enum odm_cmninfo CmnInfo,
- void *pValue
- )
-{
- /* Hook call by reference pointer. */
- switch (CmnInfo) {
- /* Dynamic call by reference pointer. */
- case ODM_CMNINFO_MAC_PHY_MODE:
- pDM_Odm->pMacPhyMode = (u8 *)pValue;
- break;
- case ODM_CMNINFO_TX_UNI:
- pDM_Odm->pNumTxBytesUnicast = (u64 *)pValue;
- break;
- case ODM_CMNINFO_RX_UNI:
- pDM_Odm->pNumRxBytesUnicast = (u64 *)pValue;
- break;
- case ODM_CMNINFO_WM_MODE:
- pDM_Odm->pWirelessMode = (u8 *)pValue;
- break;
- case ODM_CMNINFO_BAND:
- pDM_Odm->pBandType = (u8 *)pValue;
- break;
- case ODM_CMNINFO_SEC_CHNL_OFFSET:
- pDM_Odm->pSecChOffset = (u8 *)pValue;
- break;
- case ODM_CMNINFO_SEC_MODE:
- pDM_Odm->pSecurity = (u8 *)pValue;
- break;
- case ODM_CMNINFO_BW:
- pDM_Odm->pBandWidth = (u8 *)pValue;
- break;
- case ODM_CMNINFO_CHNL:
- pDM_Odm->pChannel = (u8 *)pValue;
- break;
- case ODM_CMNINFO_DMSP_GET_VALUE:
- pDM_Odm->pbGetValueFromOtherMac = (bool *)pValue;
- break;
- case ODM_CMNINFO_BUDDY_ADAPTOR:
- pDM_Odm->pBuddyAdapter = (struct rtw_adapter **)pValue;
- break;
- case ODM_CMNINFO_DMSP_IS_MASTER:
- pDM_Odm->pbMasterOfDMSP = (bool *)pValue;
- break;
- case ODM_CMNINFO_SCAN:
- pDM_Odm->pbScanInProcess = (bool *)pValue;
- break;
- case ODM_CMNINFO_POWER_SAVING:
- pDM_Odm->pbPowerSaving = (bool *)pValue;
- break;
- case ODM_CMNINFO_ONE_PATH_CCA:
- pDM_Odm->pOnePathCCA = (u8 *)pValue;
- break;
- case ODM_CMNINFO_DRV_STOP:
- pDM_Odm->pbDriverStopped = (bool *)pValue;
- break;
- case ODM_CMNINFO_PNP_IN:
- pDM_Odm->pbDriverIsGoingToPnpSetPowerSleep = (bool *)pValue;
- break;
- case ODM_CMNINFO_INIT_ON:
- pDM_Odm->pinit_adpt_in_progress = (bool *)pValue;
- break;
- case ODM_CMNINFO_ANT_TEST:
- pDM_Odm->pAntennaTest = (u8 *)pValue;
- break;
- case ODM_CMNINFO_NET_CLOSED:
- pDM_Odm->pbNet_closed = (bool *)pValue;
- break;
- /* To remove the compiler warning, must add an empty default statement to handle the other values. */
- default:
- /* do nothing */
- break;
- }
-}
-
void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo,
u16 Index, void *pValue)
{
@@ -512,9 +398,6 @@ void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value)
{
/* This init variable may be changed in run time. */
switch (CmnInfo) {
- case ODM_CMNINFO_ABILITY:
- pDM_Odm->SupportAbility = (u32)Value;
- break;
case ODM_CMNINFO_RF_TYPE:
pDM_Odm->RFType = (u8)Value;
break;
@@ -549,32 +432,33 @@ void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value)
void odm_CommonInfoSelfInit23a(struct dm_odm_t *pDM_Odm
)
{
- pDM_Odm->bCckHighPower = (bool) ODM_GetBBReg(pDM_Odm, 0x824, BIT(9));
- pDM_Odm->RFPathRxEnable = (u8) ODM_GetBBReg(pDM_Odm, 0xc04, 0x0F);
- if (pDM_Odm->SupportICType & (ODM_RTL8723A))
- pDM_Odm->AntDivType = CGCS_RX_SW_ANTDIV;
+ pDM_Odm->bCckHighPower =
+ (bool) ODM_GetBBReg(pDM_Odm, rFPGA0_XA_HSSIParameter2, BIT(9));
+ pDM_Odm->RFPathRxEnable =
+ (u8) ODM_GetBBReg(pDM_Odm, rOFDM0_TRxPathEnable, 0x0F);
ODM_InitDebugSetting23a(pDM_Odm);
}
-void odm_CommonInfoSelfUpdate23a(struct dm_odm_t *pDM_Odm)
+static void odm_CommonInfoSelfUpdate(struct hal_data_8723a *pHalData)
{
+ struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
+ struct sta_info *pEntry;
u8 EntryCnt = 0;
u8 i;
- struct sta_info *pEntry;
- if (*(pDM_Odm->pBandWidth) == ODM_BW40M) {
- if (*(pDM_Odm->pSecChOffset) == 1)
- pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) - 2;
- else if (*(pDM_Odm->pSecChOffset) == 2)
- pDM_Odm->ControlChannel = *(pDM_Odm->pChannel) + 2;
+ if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) {
+ if (pHalData->nCur40MhzPrimeSC == 1)
+ pDM_Odm->ControlChannel = pHalData->CurrentChannel - 2;
+ else if (pHalData->nCur40MhzPrimeSC == 2)
+ pDM_Odm->ControlChannel = pHalData->CurrentChannel + 2;
} else {
- pDM_Odm->ControlChannel = *(pDM_Odm->pChannel);
+ pDM_Odm->ControlChannel = pHalData->CurrentChannel;
}
for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
pEntry = pDM_Odm->pODM_StaInfo[i];
- if (IS_STA_VALID(pEntry))
+ if (pEntry)
EntryCnt++;
}
if (EntryCnt == 1)
@@ -603,21 +487,6 @@ void odm_CmnInfoInit_Debug23a(struct dm_odm_t *pDM_Odm)
}
-void odm_CmnInfoHook_Debug23a(struct dm_odm_t *pDM_Odm)
-{
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoHook_Debug23a ==>\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumTxBytesUnicast =%llu\n", *(pDM_Odm->pNumTxBytesUnicast)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pNumRxBytesUnicast =%llu\n", *(pDM_Odm->pNumRxBytesUnicast)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pWirelessMode = 0x%x\n", *(pDM_Odm->pWirelessMode)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecChOffset =%d\n", *(pDM_Odm->pSecChOffset)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pSecurity =%d\n", *(pDM_Odm->pSecurity)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pBandWidth =%d\n", *(pDM_Odm->pBandWidth)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pChannel =%d\n", *(pDM_Odm->pChannel)));
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbScanInProcess =%d\n", *(pDM_Odm->pbScanInProcess)));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("pbPowerSaving =%d\n", *(pDM_Odm->pbPowerSaving)));
-}
-
void odm_CmnInfoUpdate_Debug23a(struct dm_odm_t *pDM_Odm)
{
ODM_RT_TRACE(pDM_Odm, ODM_COMP_COMMON, ODM_DBG_LOUD, ("odm_CmnInfoUpdate_Debug23a ==>\n"));
@@ -655,7 +524,7 @@ void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm)
u8 bFwCurrentInPSMode = false;
u8 CurrentIGI = pDM_Odm->RSSI_Min;
- if (!(pDM_Odm->SupportICType & (ODM_RTL8723A)))
+ if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
return;
CurrentIGI = CurrentIGI+RSSI_OFFSET_DIG;
@@ -723,15 +592,12 @@ void odm_DIG23aInit(struct dm_odm_t *pDM_Odm)
pDM_DigTable->DIG_Dynamic_MIN_1 = DM_DIG_MIN_NIC;
pDM_DigTable->bMediaConnect_0 = false;
pDM_DigTable->bMediaConnect_1 = false;
-
- /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */
- pDM_Odm->bDMInitialGainEnable = true;
-
}
-void odm_DIG23a(struct dm_odm_t *pDM_Odm)
+void odm_DIG23a(struct rtw_adapter *adapter)
{
-
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(adapter);
+ struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
struct dig_t *pDM_DigTable = &pDM_Odm->DM_DigTable;
struct false_alarm_stats *pFalseAlmCnt = &pDM_Odm->FalseAlmCnt;
u8 DIG_Dynamic_MIN;
@@ -748,23 +614,17 @@ void odm_DIG23a(struct dm_odm_t *pDM_Odm)
return;
}
- if (*(pDM_Odm->pbScanInProcess)) {
+ if (adapter->mlmepriv.bScanInProcess) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: In Scan Progress \n"));
return;
}
- /* add by Neil Chen to avoid PSD is processing */
- if (!pDM_Odm->bDMInitialGainEnable) {
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG23a() Return: PSD is Processing \n"));
- return;
- }
-
DIG_Dynamic_MIN = pDM_DigTable->DIG_Dynamic_MIN_0;
FirstConnect = (pDM_Odm->bLinked) && (!pDM_DigTable->bMediaConnect_0);
FirstDisConnect = (!pDM_Odm->bLinked) && (pDM_DigTable->bMediaConnect_0);
/* 1 Boundary Decision */
- if ((pDM_Odm->SupportICType & (ODM_RTL8723A)) &&
+ if ((pDM_Odm->SupportICType & ODM_RTL8723A) &&
((pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) || pDM_Odm->ExtLNA)) {
dm_dig_max = DM_DIG_MAX_NIC_HP;
dm_dig_min = DM_DIG_MIN_NIC_HP;
@@ -777,7 +637,7 @@ void odm_DIG23a(struct dm_odm_t *pDM_Odm)
if (pDM_Odm->bLinked) {
/* 2 8723A Series, offset need to be 10 */
- if (pDM_Odm->SupportICType == (ODM_RTL8723A)) {
+ if (pDM_Odm->SupportICType == ODM_RTL8723A) {
/* 2 Upper Bound */
if ((pDM_Odm->RSSI_Min + 10) > DM_DIG_MAX_NIC)
pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
@@ -925,32 +785,36 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
if (!(pDM_Odm->SupportAbility & ODM_BB_FA_CNT))
return;
- if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) {
- /* hold ofdm counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */
-
- ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord);
- FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
- FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
- ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord);
- FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
- FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
- ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord);
- FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
- FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
- ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord);
- FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
-
- FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail +
- FalseAlmCnt->Cnt_Rate_Illegal +
- FalseAlmCnt->Cnt_Crc8_fail +
- FalseAlmCnt->Cnt_Mcs_fail +
- FalseAlmCnt->Cnt_Fast_Fsync +
- FalseAlmCnt->Cnt_SB_Search_fail;
- /* hold cck counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
- ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
+ /* hold ofdm counter */
+ /* hold page C counter */
+ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
+ /* hold page D counter */
+ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
+ ret_value =
+ ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE1_11N, bMaskDWord);
+ FalseAlmCnt->Cnt_Fast_Fsync = (ret_value&0xffff);
+ FalseAlmCnt->Cnt_SB_Search_fail = ((ret_value&0xffff0000)>>16);
+ ret_value =
+ ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord);
+ FalseAlmCnt->Cnt_OFDM_CCA = (ret_value&0xffff);
+ FalseAlmCnt->Cnt_Parity_Fail = ((ret_value&0xffff0000)>>16);
+ ret_value =
+ ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord);
+ FalseAlmCnt->Cnt_Rate_Illegal = (ret_value&0xffff);
+ FalseAlmCnt->Cnt_Crc8_fail = ((ret_value&0xffff0000)>>16);
+ ret_value =
+ ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_TYPE4_11N, bMaskDWord);
+ FalseAlmCnt->Cnt_Mcs_fail = (ret_value&0xffff);
+
+ FalseAlmCnt->Cnt_Ofdm_fail = FalseAlmCnt->Cnt_Parity_Fail +
+ FalseAlmCnt->Cnt_Rate_Illegal +
+ FalseAlmCnt->Cnt_Crc8_fail +
+ FalseAlmCnt->Cnt_Mcs_fail +
+ FalseAlmCnt->Cnt_Fast_Fsync +
+ FalseAlmCnt->Cnt_SB_Search_fail;
+ /* hold cck counter */
+ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
+ ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_LSB_11N, bMaskByte0);
FalseAlmCnt->Cnt_Cck_fail = ret_value;
@@ -958,7 +822,8 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8;
ret_value = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_CCA_CNT_11N, bMaskDWord);
- FalseAlmCnt->Cnt_CCK_CCA = ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
+ FalseAlmCnt->Cnt_CCK_CCA =
+ ((ret_value&0xFF)<<8) | ((ret_value&0xFF00)>>8);
FalseAlmCnt->Cnt_all = (FalseAlmCnt->Cnt_Fast_Fsync +
FalseAlmCnt->Cnt_SB_Search_fail +
@@ -968,7 +833,8 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
FalseAlmCnt->Cnt_Mcs_fail +
FalseAlmCnt->Cnt_Cck_fail);
- FalseAlmCnt->Cnt_CCA_all = FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
+ FalseAlmCnt->Cnt_CCA_all =
+ FalseAlmCnt->Cnt_OFDM_CCA + FalseAlmCnt->Cnt_CCK_CCA;
if (pDM_Odm->SupportICType >= ODM_RTL8723A) {
/* reset false alarm counter registers */
@@ -977,8 +843,10 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
/* update ofdm counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); /* update page C counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); /* update page D counter */
+ /* update page C counter */
+ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
+ /* update page D counter */
+ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
/* reset CCK CCA counter */
ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11N,
@@ -992,26 +860,20 @@ void odm_FalseAlarmCounterStatistics23a(struct dm_odm_t *pDM_Odm)
BIT(15) | BIT(14), 2);
}
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Enter odm_FalseAlarmCounterStatistics23a\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
- FalseAlmCnt->Cnt_Fast_Fsync, FalseAlmCnt->Cnt_SB_Search_fail));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
- FalseAlmCnt->Cnt_Parity_Fail, FalseAlmCnt->Cnt_Rate_Illegal));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
- FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail));
- } else { /* FOR ODM_IC_11AC_SERIES */
- /* read OFDM FA counter */
- FalseAlmCnt->Cnt_Ofdm_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_OFDM_FA_11AC, bMaskLWord);
- FalseAlmCnt->Cnt_Cck_fail = ODM_GetBBReg(pDM_Odm, ODM_REG_CCK_FA_11AC, bMaskLWord);
- FalseAlmCnt->Cnt_all = FalseAlmCnt->Cnt_Ofdm_fail + FalseAlmCnt->Cnt_Cck_fail;
-
- /* reset OFDM FA coutner */
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
- ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
- /* reset CCK FA counter */
- ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
- ODM_SetBBReg(pDM_Odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
- }
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
+ ("Enter odm_FalseAlarmCounterStatistics23a\n"));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
+ ("Cnt_Fast_Fsync =%d, Cnt_SB_Search_fail =%d\n",
+ FalseAlmCnt->Cnt_Fast_Fsync,
+ FalseAlmCnt->Cnt_SB_Search_fail));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
+ ("Cnt_Parity_Fail =%d, Cnt_Rate_Illegal =%d\n",
+ FalseAlmCnt->Cnt_Parity_Fail,
+ FalseAlmCnt->Cnt_Rate_Illegal));
+ ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD,
+ ("Cnt_Crc8_fail =%d, Cnt_Mcs_fail =%d\n",
+ FalseAlmCnt->Cnt_Crc8_fail, FalseAlmCnt->Cnt_Mcs_fail));
+
ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Cck_fail =%d\n", FalseAlmCnt->Cnt_Cck_fail));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Cnt_Ofdm_fail =%d\n", FalseAlmCnt->Cnt_Ofdm_fail));
ODM_RT_TRACE(pDM_Odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("Total False Alarm =%d\n", FalseAlmCnt->Cnt_all));
@@ -1207,18 +1069,16 @@ void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm)
pOdmRA->LowRSSIThresh = 20;
}
-u32 ODM_Get_Rate_Bitmap23a(struct dm_odm_t *pDM_Odm,
- u32 macid,
- u32 ra_mask,
- u8 rssi_level)
+u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid,
+ u32 ra_mask, u8 rssi_level)
{
+ struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
struct sta_info *pEntry;
u32 rate_bitmap = 0x0fffffff;
u8 WirelessMode;
- /* u8 WirelessMode =*(pDM_Odm->pWirelessMode); */
pEntry = pDM_Odm->pODM_StaInfo[macid];
- if (!IS_STA_VALID(pEntry))
+ if (!pEntry)
return ra_mask;
WirelessMode = pEntry->wireless_mode;
@@ -1252,7 +1112,8 @@ u32 ODM_Get_Rate_Bitmap23a(struct dm_odm_t *pDM_Odm,
} else if (rssi_level == DM_RATR_STA_MIDDLE) {
rate_bitmap = 0x000ff000;
} else {
- if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
+ if (pHalData->CurrentChannelBW ==
+ HT_CHANNEL_WIDTH_40)
rate_bitmap = 0x000ff015;
else
rate_bitmap = 0x000ff005;
@@ -1263,7 +1124,8 @@ u32 ODM_Get_Rate_Bitmap23a(struct dm_odm_t *pDM_Odm,
} else if (rssi_level == DM_RATR_STA_MIDDLE) {
rate_bitmap = 0x0f8ff000;
} else {
- if (*(pDM_Odm->pBandWidth) == ODM_BW40M)
+ if (pHalData->CurrentChannelBW ==
+ HT_CHANNEL_WIDTH_40)
rate_bitmap = 0x0f8ff015;
else
rate_bitmap = 0x0f8ff005;
@@ -1340,7 +1202,7 @@ void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm)
for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
struct sta_info *pstat = pDM_Odm->pODM_StaInfo[i];
- if (IS_STA_VALID(pstat)) {
+ if (pstat) {
if (ODM_RAStateCheck23a(pDM_Odm, pstat->rssi_stat.UndecoratedSmoothedPWDB, false, &pstat->rssi_level)) {
ODM_RT_TRACE(pDM_Odm, ODM_COMP_RA_MASK, ODM_DBG_LOUD,
("RSSI:%d, RSSI_LEVEL:%d\n",
@@ -1482,7 +1344,7 @@ void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm)
for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
psta = pDM_Odm->pODM_StaInfo[i];
- if (IS_STA_VALID(psta)) {
+ if (psta) {
if (psta->rssi_stat.UndecoratedSmoothedPWDB < tmpEntryMinPWDB)
tmpEntryMinPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
@@ -1568,52 +1430,8 @@ void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm)
{
}
-/* antenna mapping info */
-/* 1: right-side antenna */
-/* 2/0: left-side antenna */
-/* PpDM_SWAT_Table->CCK_Ant1_Cnt /OFDM_Ant1_Cnt: for right-side antenna: Ant:1 RxDefaultAnt1 */
-/* PpDM_SWAT_Table->CCK_Ant2_Cnt /OFDM_Ant2_Cnt: for left-side antenna: Ant:0 RxDefaultAnt2 */
-/* We select left antenna as default antenna in initial process, modify it as needed */
-/* */
-
-/* 3 ============================================================ */
-/* 3 SW Antenna Diversity */
-/* 3 ============================================================ */
-void odm_SwAntDivInit(struct dm_odm_t *pDM_Odm)
-{
-}
-
-void ODM_SwAntDivChkPerPktRssi(struct dm_odm_t *pDM_Odm, u8 StationID,
- struct phy_info *pPhyInfo)
-{
-}
-
-void odm_SwAntDivChkAntSwitch(struct dm_odm_t *pDM_Odm, u8 Step)
-{
-}
-
-void ODM_SwAntDivRestAfterLink(struct dm_odm_t *pDM_Odm)
-{
-}
-
-void odm_SwAntDivChkAntSwitchCallback23a(unsigned long data)
-{
-}
-
-/* 3 ============================================================ */
-/* 3 SW Antenna Diversity */
-/* 3 ============================================================ */
-
-void odm_InitHybridAntDiv23a(struct dm_odm_t *pDM_Odm)
-{
-}
-
-void odm_HwAntDiv23a(struct dm_odm_t *pDM_Odm)
-{
-}
-
/* EDCA Turbo */
-void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
+static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
{
struct rtw_adapter *Adapter = pDM_Odm->Adapter;
@@ -1628,40 +1446,31 @@ void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
} /* ODM_InitEdcaTurbo */
-void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm)
+static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm)
{
+ struct rtw_adapter *Adapter = pDM_Odm->Adapter;
+ struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
+ struct xmit_priv *pxmitpriv = &Adapter->xmitpriv;
+ struct recv_priv *precvpriv = &Adapter->recvpriv;
+ struct registry_priv *pregpriv = &Adapter->registrypriv;
+ struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ u32 trafficIndex;
+ u32 edca_param;
+ u64 cur_tx_bytes = 0;
+ u64 cur_rx_bytes = 0;
+ u8 bbtchange = false;
+
/* For AP/ADSL use struct rtl8723a_priv * */
/* For CE/NIC use struct rtw_adapter * */
/* 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. */
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("odm_EdcaTurboCheck23a ========================>\n"));
if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO))
return;
- odm_EdcaTurboCheck23aCE23a(pDM_Odm);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD, ("<======================== odm_EdcaTurboCheck23a\n"));
-
-} /* odm_CheckEdcaTurbo */
-
-void odm_EdcaTurboCheck23aCE23a(struct dm_odm_t *pDM_Odm)
-{
- struct rtw_adapter *Adapter = pDM_Odm->Adapter;
-
- u32 trafficIndex;
- u32 edca_param;
- u64 cur_tx_bytes = 0;
- u64 cur_rx_bytes = 0;
- u8 bbtchange = false;
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct xmit_priv *pxmitpriv = &Adapter->xmitpriv;
- struct recv_priv *precvpriv = &Adapter->recvpriv;
- struct registry_priv *pregpriv = &Adapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
-
if ((pregpriv->wifi_spec == 1))/* (pmlmeinfo->HT_enable == 0)) */
goto dm_CheckEdcaTurbo_EXIT;
@@ -1836,7 +1645,7 @@ bool ODM_SingleDualAntennaDetection(struct dm_odm_t *pDM_Odm, u8 mode)
rSleep, rPMPD_ANAEN,
rFPGA0_XCD_SwitchControl, rBlue_Tooth};
- if (!(pDM_Odm->SupportICType & (ODM_RTL8723A)))
+ if (!(pDM_Odm->SupportICType & ODM_RTL8723A))
return bResult;
if (!(pDM_Odm->SupportAbility&ODM_BB_ANT_DIV))
diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
index 82b1b8348898..29d844d66cae 100644
--- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c
+++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
@@ -19,11 +19,6 @@
#include "odm_precomp.h"
-#define READ_AND_CONFIG READ_AND_CONFIG_MP
-
-#define READ_AND_CONFIG_MP(ic, txt) (ODM_ReadAndConfig##txt##ic(pDM_Odm))
-#define READ_AND_CONFIG_TC(ic, txt) (ODM_ReadAndConfig_TC##txt##ic(pDM_Odm))
-
static u8 odm_QueryRxPwrPercentage(s8 AntPower)
{
if ((AntPower <= -100) || (AntPower >= 20))
@@ -296,7 +291,7 @@ static void odm_Process_RSSIForDM(struct dm_odm_t *pDM_Odm,
return;
pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID];
- if (!IS_STA_VALID(pEntry))
+ if (!pEntry)
return;
if ((!pPktinfo->bPacketMatchBSSID))
return;
@@ -404,13 +399,8 @@ static void ODM_PhyStatusQuery23a_92CSeries(struct dm_odm_t *pDM_Odm,
{
odm_RxPhyStatus92CSeries_Parsing(pDM_Odm, pPhyInfo,
pPhyStatus, pPktinfo);
- if (pDM_Odm->RSSI_test) {
- /* Select the packets to do RSSI checking for antenna switching. */
- if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon)
- ODM_SwAntDivChkPerPktRssi(pDM_Odm, pPktinfo->StationID, pPhyInfo);
- } else {
- odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo);
- }
+
+ odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo);
}
void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo,
@@ -418,55 +408,3 @@ void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo,
{
ODM_PhyStatusQuery23a_92CSeries(pDM_Odm, pPhyInfo, pPhyStatus, pPktinfo);
}
-
-/* For future use. */
-void ODM_MacStatusQuery23a(struct dm_odm_t *pDM_Odm, u8 *pMacStatus, u8 MacID,
- bool bPacketMatchBSSID, bool bPacketToSelf,
- bool bPacketBeacon)
-{
- /* 2011/10/19 Driver team will handle in the future. */
-
-}
-
-int ODM_ConfigRFWithHeaderFile23a(struct dm_odm_t *pDM_Odm,
- enum RF_RADIO_PATH Content,
- enum RF_RADIO_PATH eRFPath)
-{
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===>ODM_ConfigRFWithHeaderFile23a\n"));
- if (pDM_Odm->SupportICType == ODM_RTL8723A) {
- if (eRFPath == RF_PATH_A)
- READ_AND_CONFIG_MP(8723A, _RadioA_1T_);
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- (" ===> ODM_ConfigRFWithHeaderFile23a() Radio_A:Rtl8723RadioA_1TArray\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- (" ===> ODM_ConfigRFWithHeaderFile23a() Radio_B:Rtl8723RadioB_1TArray\n"));
- }
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE,
- ("ODM_ConfigRFWithHeaderFile23a: Radio No %x\n", eRFPath));
- return _SUCCESS;
-}
-
-int ODM_ConfigBBWithHeaderFile23a(struct dm_odm_t *pDM_Odm,
- enum odm_bb_config_type ConfigType)
-{
- if (pDM_Odm->SupportICType == ODM_RTL8723A) {
- if (ConfigType == CONFIG_BB_PHY_REG)
- READ_AND_CONFIG_MP(8723A, _PHY_REG_1T_);
- else if (ConfigType == CONFIG_BB_AGC_TAB)
- READ_AND_CONFIG_MP(8723A, _AGC_TAB_1T_);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- (" ===> phy_ConfigBBWithHeaderFile() phy:Rtl8723AGCTAB_1TArray\n"));
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- (" ===> phy_ConfigBBWithHeaderFile() agc:Rtl8723PHY_REG_1TArray\n"));
- }
- return _SUCCESS;
-}
-
-int ODM_ConfigMACWithHeaderFile23a(struct dm_odm_t *pDM_Odm)
-{
- if (pDM_Odm->SupportICType == ODM_RTL8723A)
- READ_AND_CONFIG_MP(8723A, _MAC_REG_);
- return _SUCCESS;
-}
diff --git a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c
index d076e14f36b9..88e0126e855a 100644
--- a/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c
+++ b/drivers/staging/rtl8723au/hal/odm_RegConfig8723A.c
@@ -43,36 +43,6 @@ odm_ConfigRFReg_8723A(
}
}
-void odm_ConfigRF_RadioA_8723A(struct dm_odm_t *pDM_Odm,
- u32 Addr,
- u32 Data
- )
-{
- u32 content = 0x1000; /* RF_Content: radioa_txt */
- u32 maskforPhySet = (u32)(content&0xE000);
-
- odm_ConfigRFReg_8723A(pDM_Odm, Addr, Data, RF_PATH_A,
- Addr|maskforPhySet);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> ODM_ConfigRFWithHeaderFile23a: [RadioA] %08X %08X\n",
- Addr, Data));
-}
-
-void odm_ConfigRF_RadioB_8723A(struct dm_odm_t *pDM_Odm,
- u32 Addr,
- u32 Data
- )
-{
- u32 content = 0x1001; /* RF_Content: radiob_txt */
- u32 maskforPhySet = (u32)(content&0xE000);
-
- odm_ConfigRFReg_8723A(pDM_Odm, Addr, Data, RF_PATH_B,
- Addr|maskforPhySet);
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> ODM_ConfigRFWithHeaderFile23a: [RadioB] %08X %08X\n",
- Addr, Data));
-}
-
void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm,
u32 Addr,
u8 Data
@@ -102,34 +72,6 @@ odm_ConfigBB_AGC_8723A(
}
void
-odm_ConfigBB_PHY_REG_PG_8723A(
- struct dm_odm_t *pDM_Odm,
- u32 Addr,
- u32 Bitmask,
- u32 Data
- )
-{
- if (Addr == 0xfe)
- msleep(50);
- else if (Addr == 0xfd)
- mdelay(5);
- else if (Addr == 0xfc)
- mdelay(1);
- else if (Addr == 0xfb)
- udelay(50);
- else if (Addr == 0xfa)
- udelay(5);
- else if (Addr == 0xf9)
- udelay(1);
- /* TODO: ODM_StorePwrIndexDiffRateOffset(...) */
- /* storePwrIndexDiffRateOffset(Adapter, Addr, Bitmask, Data); */
-
- ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
- ("===> ODM_ConfigBBWithHeaderFile23a: [PHY_REG] %08X %08X %08X\n",
- Addr, Bitmask, Data));
-}
-
-void
odm_ConfigBB_PHY_8723A(
struct dm_odm_t *pDM_Odm,
u32 Addr,
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
index c00105389090..9054a987f06b 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
@@ -14,7 +14,6 @@
******************************************************************************/
#include <drv_types.h>
#include <rtl8723a_hal.h>
-#include <rtw_ioctl_set.h>
#include <usb_ops_linux.h>
#define DIS_PS_RX_BCN
@@ -5871,8 +5870,8 @@ btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter)
mask = update_supported_rate23a(cur_network->SupportedRates,
supportRateNum);
mask |= (pmlmeinfo->HT_enable) ?
- update_MSC_rate23a(&pmlmeinfo->HT_caps):0;
- if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
+ update_MSC_rate23a(&pmlmeinfo->ht_cap):0;
+ if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
shortGIrate = true;
break;
case 1:/* for broadcast/multicast */
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c
index e8737916c7ba..271c33d6ca5a 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_cmd.c
@@ -18,7 +18,6 @@
#include <drv_types.h>
#include <recv_osdep.h>
#include <mlme_osdep.h>
-#include <rtw_ioctl_set.h>
#include <rtl8723a_hal.h>
#include <usb_ops_linux.h>
@@ -152,7 +151,8 @@ void rtl8723a_add_rateatid(struct rtw_adapter *pAdapter, u32 bitmap, u8 arg, u8
bitmap &= 0x0fffffff;
if (rssi_level != DM_RATR_STA_INIT)
- bitmap = ODM_Get_Rate_Bitmap23a(&pHalData->odmpriv, macid, bitmap, rssi_level);
+ bitmap = ODM_Get_Rate_Bitmap23a(pHalData, macid, bitmap,
+ rssi_level);
bitmap |= ((raid<<28)&0xf0000000);
@@ -201,57 +201,45 @@ void rtl8723a_set_FwPwrMode_cmd(struct rtw_adapter *padapter, u8 Mode)
}
-static void ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength)
+static void
+ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLength)
{
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
u32 rate_len, pktlen;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- int bcn_fixed_size;
/* DBG_8723A("%s\n", __func__); */
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
- pwlanhdr->frame_control =
+ mgmt->frame_control =
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
- memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
- memcpy(pwlanhdr->addr3, get_my_bssid23a(cur_network), ETH_ALEN);
+ ether_addr_copy(mgmt->da, bc_addr);
+ ether_addr_copy(mgmt->sa, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt->bssid, get_my_bssid23a(cur_network));
/* A Beacon frame shouldn't have fragment bits set */
- pwlanhdr->seq_ctrl = 0;
-
- pframe += sizeof(struct ieee80211_hdr_3addr);
- pktlen = sizeof (struct ieee80211_hdr_3addr);
+ mgmt->seq_ctrl = 0;
/* timestamp will be inserted by hardware */
- pframe += 8;
- pktlen += 8;
-
- /* beacon interval: 2 bytes */
- memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval23a_from_ie(cur_network->IEs)), 2);
-
- pframe += 2;
- pktlen += 2;
- /* capability info: 2 bytes */
- memcpy(pframe, (unsigned char *)(rtw_get_capability23a_from_ie(cur_network->IEs)), 2);
+ put_unaligned_le16(cur_network->beacon_interval,
+ &mgmt->u.beacon.beacon_int);
- pframe += 2;
- pktlen += 2;
+ put_unaligned_le16(cur_network->capability,
+ &mgmt->u.beacon.capab_info);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
- bcn_fixed_size =
- offsetof(struct ieee80211_mgmt, u.beacon.variable) -
- offsetof(struct ieee80211_mgmt, u.beacon);
+ pframe = mgmt->u.beacon.variable;
+ pktlen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ if ((pmlmeinfo->state&0x03) == MSR_AP) {
/* DBG_8723A("ie len =%d\n", cur_network->IELength); */
- pktlen += cur_network->IELength - bcn_fixed_size;
- memcpy(pframe, cur_network->IEs + bcn_fixed_size, pktlen);
+ pktlen += cur_network->IELength;
+ memcpy(pframe, cur_network->IEs, pktlen);
goto _ConstructBeacon;
}
@@ -272,7 +260,7 @@ static void ConstructBeacon(struct rtw_adapter *padapter, u8 *pframe, u32 *pLeng
pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
&cur_network->DSConfig, &pktlen);
- if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
+ if ((pmlmeinfo->state&0x03) == MSR_ADHOC) {
u32 ATIMWindow;
/* IBSS Parameter Set... */
/* ATIMWindow = cur->ATIMWindow; */
@@ -406,7 +394,7 @@ ConstructNullFunctionData(struct rtw_adapter *padapter, u8 *pframe,
static void ConstructProbeRsp(struct rtw_adapter *padapter, u8 *pframe,
u32 *pLength, u8 *StaAddr, bool bHideSSID)
{
- struct ieee80211_hdr *pwlanhdr;
+ struct ieee80211_mgmt *mgmt;
u8 *mac, *bssid;
u32 pktlen;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -415,38 +403,39 @@ static void ConstructProbeRsp(struct rtw_adapter *padapter, u8 *pframe,
/* DBG_8723A("%s\n", __func__); */
- pwlanhdr = (struct ieee80211_hdr *)pframe;
+ mgmt = (struct ieee80211_mgmt *)pframe;
mac = myid(&padapter->eeprompriv);
bssid = cur_network->MacAddress;
- pwlanhdr->frame_control =
+ mgmt->frame_control =
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
- pwlanhdr->seq_ctrl = 0;
+ mgmt->seq_ctrl = 0;
- memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
- memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
- memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
+ memcpy(mgmt->da, StaAddr, ETH_ALEN);
+ memcpy(mgmt->sa, mac, ETH_ALEN);
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
- pktlen = sizeof(struct ieee80211_hdr_3addr);
- pframe += pktlen;
+ put_unaligned_le64(cur_network->tsf,
+ &mgmt->u.probe_resp.timestamp);
+ put_unaligned_le16(cur_network->beacon_interval,
+ &mgmt->u.probe_resp.beacon_int);
+ put_unaligned_le16(cur_network->capability,
+ &mgmt->u.probe_resp.capab_info);
+
+ pktlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
if (cur_network->IELength > MAX_IE_SZ)
return;
- memcpy(pframe, cur_network->IEs, cur_network->IELength);
- pframe += cur_network->IELength;
- pktlen += cur_network->IELength;
+ memcpy(mgmt->u.probe_resp.variable, cur_network->IEs,
+ cur_network->IELength);
+ pktlen += (cur_network->IELength);
*pLength = pktlen;
}
-/* To check if reserved page content is destroyed by beacon beacuse beacon is too large. */
-void CheckFwRsvdPageContent23a(struct rtw_adapter *Adapter)
-{
-}
-
/* */
/* Description: Fill the reserved packets that FW will use to RSVD page. */
/* Now we just send 4 types packet to rsvd page. */
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c
index ac47a9711086..fa826b068d11 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_dm.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_dm.c
@@ -34,10 +34,6 @@
/* Global var */
/* */
-static void dm_CheckStatistics(struct rtw_adapter *Adapter)
-{
-}
-
static void dm_CheckPbcGPIO(struct rtw_adapter *padapter)
{
u8 tmp1byte;
@@ -86,16 +82,15 @@ static void dm_CheckPbcGPIO(struct rtw_adapter *padapter)
/* Initialize GPIO setting registers */
/* functions */
-static void Init_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
-{
+void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter)
+{
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
+ struct dm_priv *pdmpriv = &pHalData->dmpriv;
struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
- u8 cut_ver, fab_ver;
+ u8 cut_ver, fab_ver;
- /* */
- /* Init Value */
- /* */
+ memset(pdmpriv, 0, sizeof(struct dm_priv));
memset(pDM_Odm, 0, sizeof(*pDM_Odm));
pDM_Odm->Adapter = Adapter;
@@ -137,9 +132,6 @@ static void Init_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
{
- struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
- struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
- struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
struct dm_priv *pdmpriv = &pHalData->dmpriv;
@@ -155,28 +147,7 @@ static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
ODM_RF_TX_PWR_TRACK |
ODM_RF_CALIBRATION;
/* Pointer reference */
-
- ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
-
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_UNI,
- &Adapter->xmitpriv.tx_bytes);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_UNI,
- &Adapter->recvpriv.rx_bytes);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_WM_MODE,
- &pmlmeext->cur_wireless_mode);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET,
- &pHalData->nCur40MhzPrimeSC);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_MODE,
- &Adapter->securitypriv.dot11PrivacyAlgrthm);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BW,
- &pHalData->CurrentChannelBW);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_CHNL,
- &pHalData->CurrentChannel);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed);
-
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess);
- ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_POWER_SAVING,
- &pwrctrlpriv->bpower_saving);
+ rtl8723a_odm_support_ability_set(Adapter, DYNAMIC_ALL_FUNC_ENABLE);
for (i = 0; i < NUM_STA; i++)
ODM_CmnInfoPtrArrayHook23a(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
@@ -189,14 +160,6 @@ void rtl8723a_InitHalDm(struct rtw_adapter *Adapter)
struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
u8 i;
- pdmpriv->DM_Type = DM_Type_ByDriver;
- pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
-
-#ifdef CONFIG_8723AU_BT_COEXIST
- pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
-#endif
- pdmpriv->InitDMFlag = pdmpriv->DMFlag;
-
Update_ODM_ComInfo_8723a(Adapter);
ODM23a_DMInit(pDM_Odm);
/* Save REG_INIDATA_RATE_SEL value for TXDESC. */
@@ -211,6 +174,7 @@ rtl8723a_HalDmWatchDog(
{
bool bFwCurrentInPSMode = false;
bool bFwPSAwake = true;
+ u8 bLinked = false;
u8 hw_init_completed = false;
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
struct dm_priv *pdmpriv = &pHalData->dmpriv;
@@ -223,10 +187,7 @@ rtl8723a_HalDmWatchDog(
bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
bFwPSAwake = rtl8723a_get_fwlps_rf_on(Adapter);
- if ((hw_init_completed) && ((!bFwCurrentInPSMode) && bFwPSAwake)) {
- /* Calculate Tx/Rx statistics. */
- dm_CheckStatistics(Adapter);
-
+ if (!bFwCurrentInPSMode && bFwPSAwake) {
/* Read REG_INIDATA_RATE_SEL value for TXDESC. */
if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) {
pdmpriv->INIDATA_RATE[0] = rtl8723au_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f;
@@ -238,16 +199,11 @@ rtl8723a_HalDmWatchDog(
}
/* ODM */
- if (hw_init_completed == true) {
- u8 bLinked = false;
+ if (rtw_linked_check(Adapter))
+ bLinked = true;
- if (rtw_linked_check(Adapter))
- bLinked = true;
-
- ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK,
- bLinked);
- ODM_DMWatchdog23a(&pHalData->odmpriv);
- }
+ ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK, bLinked);
+ ODM_DMWatchdog23a(Adapter);
skip_dm:
@@ -255,16 +211,3 @@ skip_dm:
/* Check Hardware Radio ON/OFF or not */
dm_CheckPbcGPIO(Adapter);
}
-
-void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
- memset(pdmpriv, 0, sizeof(struct dm_priv));
- Init_ODM_ComInfo_8723a(Adapter);
-}
-
-void rtl8723a_deinit_dm_priv(struct rtw_adapter *Adapter)
-{
-}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
index 46f5abcbaeeb..8523908d5e5f 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c
@@ -49,93 +49,14 @@ static void _FWDownloadEnable(struct rtw_adapter *padapter, bool enable)
static int _BlockWrite(struct rtw_adapter *padapter, void *buffer, u32 buffSize)
{
- int ret = _SUCCESS;
- /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */
- u32 blockSize_p1 = 4;
- /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
- u32 blockSize_p2 = 8;
- /* Phase #3 : Use 1-byte, the remnant of FW image. */
- u32 blockSize_p3 = 1;
- u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
- u32 remainSize_p1 = 0, remainSize_p2 = 0;
- u8 *bufferPtr = (u8 *) buffer;
- u32 i = 0, offset = 0;
-
- blockSize_p1 = 254;
+ int ret;
- /* 3 Phase #1 */
- blockCount_p1 = buffSize / blockSize_p1;
- remainSize_p1 = buffSize % blockSize_p1;
-
- if (blockCount_p1) {
- RT_TRACE(_module_hal_init_c_, _drv_notice_,
- ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) "
- "blockCount_p1(%d) remainSize_p1(%d)\n",
- buffSize, blockSize_p1, blockCount_p1,
- remainSize_p1));
- }
-
- for (i = 0; i < blockCount_p1; i++) {
- ret = rtl8723au_writeN(padapter, (FW_8723A_START_ADDRESS +
- i * blockSize_p1),
- blockSize_p1,
- (bufferPtr + i * blockSize_p1));
- if (ret == _FAIL)
- goto exit;
- }
-
- /* 3 Phase #2 */
- if (remainSize_p1) {
- offset = blockCount_p1 * blockSize_p1;
-
- blockCount_p2 = remainSize_p1 / blockSize_p2;
- remainSize_p2 = remainSize_p1 % blockSize_p2;
-
- if (blockCount_p2) {
- RT_TRACE(_module_hal_init_c_, _drv_notice_,
- ("_BlockWrite: [P2] buffSize_p2(%d) "
- "blockSize_p2(%d) blockCount_p2(%d) "
- "remainSize_p2(%d)\n",
- (buffSize - offset), blockSize_p2,
- blockCount_p2, remainSize_p2));
- }
-
- for (i = 0; i < blockCount_p2; i++) {
- ret = rtl8723au_writeN(padapter,
- (FW_8723A_START_ADDRESS +
- offset + i * blockSize_p2),
- blockSize_p2,
- (bufferPtr + offset +
- i * blockSize_p2));
-
- if (ret == _FAIL)
- goto exit;
- }
- }
-
- /* 3 Phase #3 */
- if (remainSize_p2) {
- offset = (blockCount_p1 * blockSize_p1) +
- (blockCount_p2 * blockSize_p2);
-
- blockCount_p3 = remainSize_p2 / blockSize_p3;
-
- RT_TRACE(_module_hal_init_c_, _drv_notice_,
- ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) "
- "blockCount_p3(%d)\n",
- (buffSize - offset), blockSize_p3, blockCount_p3));
-
- for (i = 0; i < blockCount_p3; i++) {
- ret = rtl8723au_write8(padapter,
- (FW_8723A_START_ADDRESS + offset + i),
- *(bufferPtr + offset + i));
+ if (buffSize > MAX_PAGE_SIZE)
+ return _FAIL;
- if (ret == _FAIL)
- goto exit;
- }
- }
+ ret = rtl8723au_writeN(padapter, FW_8723A_START_ADDRESS,
+ buffSize, buffer);
-exit:
return ret;
}
@@ -961,28 +882,18 @@ void rtl8723a_read_chip_version(struct rtw_adapter *padapter)
/* */
void SetBcnCtrlReg23a(struct rtw_adapter *padapter, u8 SetBits, u8 ClearBits)
{
- struct hal_data_8723a *pHalData;
- u32 addr;
- u8 *pRegBcnCtrlVal;
-
- pHalData = GET_HAL_DATA(padapter);
- pRegBcnCtrlVal = (u8 *)&pHalData->RegBcnCtrlVal;
-
- addr = REG_BCN_CTRL;
+ u8 val8;
- *pRegBcnCtrlVal = rtl8723au_read8(padapter, addr);
- *pRegBcnCtrlVal |= SetBits;
- *pRegBcnCtrlVal &= ~ClearBits;
+ val8 = rtl8723au_read8(padapter, REG_BCN_CTRL);
+ val8 |= SetBits;
+ val8 &= ~ClearBits;
- rtl8723au_write8(padapter, addr, *pRegBcnCtrlVal);
+ rtl8723au_write8(padapter, REG_BCN_CTRL, val8);
}
void rtl8723a_InitBeaconParameters(struct rtw_adapter *padapter)
{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
-
rtl8723au_write16(padapter, REG_BCN_CTRL, 0x1010);
- pHalData->RegBcnCtrlVal = 0x1010;
/* TODO: Remove these magic number */
rtl8723au_write16(padapter, REG_TBTT_PROHIBIT, 0x6404); /* ms */
@@ -1034,8 +945,6 @@ static void StopTxBeacon(struct rtw_adapter *padapter)
rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 1, 0x64);
pHalData->RegReg542 &= ~BIT(0);
rtl8723au_write8(padapter, REG_TBTT_PROHIBIT + 2, pHalData->RegReg542);
-
- CheckFwRsvdPageContent23a(padapter); /* 2010.06.23. Added by tynli. */
}
static void _BeaconFunctionEnable(struct rtw_adapter *padapter, u8 Enable,
@@ -2381,18 +2290,18 @@ void hw_var_set_opmode(struct rtw_adapter *padapter, u8 mode)
{
u8 val8;
- if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
+ if (mode == MSR_INFRA || mode == MSR_NOLINK) {
StopTxBeacon(padapter);
/* disable atim wnd */
val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM;
SetBcnCtrlReg23a(padapter, val8, ~val8);
- } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_) */) {
+ } else if (mode == MSR_ADHOC) {
ResumeTxBeacon(padapter);
val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB;
SetBcnCtrlReg23a(padapter, val8, ~val8);
- } else if (mode == _HW_STATE_AP_) {
+ } else if (mode == MSR_AP) {
/* add NULL Data and BT NULL Data Packets to FW RSVD Page */
rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
@@ -2474,8 +2383,8 @@ void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
do_div(pmlmeext->TSFValue,
(pmlmeinfo->bcn_interval * 1024)) - 1024; /* us */
- if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
- ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
+ if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
+ ((pmlmeinfo->state & 0x03) == MSR_AP)) {
/* pHalData->RegTxPause |= STOP_BCNQ;BIT(6) */
/* rtl8723au_write8(padapter, REG_TXPAUSE,
(rtl8723au_read8(Adapter, REG_TXPAUSE)|BIT(6))); */
@@ -2493,8 +2402,8 @@ void hw_var_set_correct_tsf(struct rtw_adapter *padapter)
/* enable related TSF function */
SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION, 0);
- if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
- ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
+ if (((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
+ ((pmlmeinfo->state & 0x03) == MSR_AP))
ResumeTxBeacon(padapter);
}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
index d23525e664fb..3d4d7ec27509 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
@@ -425,8 +425,7 @@ int PHY_MACConfig8723A(struct rtw_adapter *Adapter)
/* */
/* Config MAC */
/* */
- if (ODM_ConfigMACWithHeaderFile23a(&pHalData->odmpriv) == _FAIL)
- rtStatus = _FAIL;
+ ODM_ReadAndConfig_MAC_REG_8723A(&pHalData->odmpriv);
/* 2010.07.13 AMPDU aggregation number 9 */
/* rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */
@@ -753,11 +752,7 @@ phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
/* 1. Read PHY_REG.TXT BB INIT!! */
/* We will seperate as 88C / 92C according to chip version */
/* */
- if (ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv,
- CONFIG_BB_PHY_REG) == _FAIL)
- rtStatus = _FAIL;
- if (rtStatus != _SUCCESS)
- goto phy_BB8190_Config_ParaFile_Fail;
+ ODM_ReadAndConfig_PHY_REG_1T_8723A(&pHalData->odmpriv);
/* */
/* 20100318 Joseph: Config 2T2R to 1T2R if necessary. */
@@ -784,9 +779,7 @@ phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
/* */
/* 3. BB AGC table Initialization */
/* */
- if (ODM_ConfigBBWithHeaderFile23a(&pHalData->odmpriv,
- CONFIG_BB_AGC_TAB) == _FAIL)
- rtStatus = _FAIL;
+ ODM_ReadAndConfig_AGC_TAB_1T_8723A(&pHalData->odmpriv);
phy_BB8190_Config_ParaFile_Fail:
@@ -846,18 +839,6 @@ PHY_BBConfig8723A(struct rtw_adapter *Adapter)
return rtStatus;
}
-int
-PHY_RFConfig8723A(struct rtw_adapter *Adapter)
-{
- int rtStatus = _SUCCESS;
-
- /* */
- /* RF config */
- /* */
- rtStatus = PHY_RF6052_Config8723A(Adapter);
- return rtStatus;
-}
-
static void getTxPowerIndex(struct rtw_adapter *Adapter,
u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel)
{
@@ -1098,9 +1079,6 @@ static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
u32 param1, param2;
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
- if (Adapter->bNotifyChannelChange)
- DBG_8723A("[%s] ch = %d\n", __func__, channel);
-
/* s1. pre common command - CmdID_SetTxPowerLevel */
PHY_SetTxPowerLevel8723A(Adapter, channel);
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c
index c30bd232bf62..2dc0886e5f90 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_rf6052.c
@@ -455,20 +455,9 @@ static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter)
/*----Initialize RF fom connfiguration file----*/
switch (eRFPath) {
case RF_PATH_A:
- if (ODM_ConfigRFWithHeaderFile23a(&pHalData->odmpriv,
- (enum RF_RADIO_PATH)
- eRFPath,
- (enum RF_RADIO_PATH)
- eRFPath) == _FAIL)
- rtStatus = _FAIL;
+ ODM_ReadAndConfig_RadioA_1T_8723A(&pHalData->odmpriv);
break;
case RF_PATH_B:
- if (ODM_ConfigRFWithHeaderFile23a(&pHalData->odmpriv,
- (enum RF_RADIO_PATH)
- eRFPath,
- (enum RF_RADIO_PATH)
- eRFPath) == _FAIL)
- rtStatus = _FAIL;
break;
}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c b/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c
index 0680e29a5528..3c46294b8788 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_sreset.c
@@ -46,29 +46,10 @@ void rtl8723a_sreset_xmit_status_check(struct rtw_adapter *padapter)
} else {
diff_time = jiffies_to_msecs(jiffies - psrtpriv->last_tx_complete_time);
if (diff_time > 4000) {
- /* padapter->Wifi_Error_Status = WIFI_TX_HANG; */
DBG_8723A("%s tx hang\n", __func__);
rtw_sreset_reset(padapter);
}
}
}
}
-
- if (psrtpriv->dbg_trigger_point == SRESET_TGP_XMIT_STATUS) {
- psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
- rtw_sreset_reset(padapter);
- return;
- }
-}
-
-void rtl8723a_sreset_linked_status_check(struct rtw_adapter *padapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- if (psrtpriv->dbg_trigger_point == SRESET_TGP_LINK_STATUS) {
- psrtpriv->dbg_trigger_point = SRESET_TGP_NULL;
- rtw_sreset_reset(padapter);
- return;
- }
}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c
index d7612ccc47e9..6ea2f9efef64 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_xmit.c
@@ -18,27 +18,6 @@
#include <drv_types.h>
#include <rtl8723a_hal.h>
-void dump_txrpt_ccx_8723a(void *buf)
-{
- struct txrpt_ccx_8723a *txrpt_ccx = buf;
-
- DBG_8723A("%s:\n"
- "tag1:%u, rsvd:%u, int_bt:%u, int_tri:%u, int_ccx:%u\n"
- "mac_id:%u, pkt_drop:%u, pkt_ok:%u, bmc:%u\n"
- "retry_cnt:%u, lifetime_over:%u, retry_over:%u\n"
- "ccx_qtime:%u\n"
- "final_data_rate:0x%02x\n"
- "qsel:%u, sw:0x%03x\n"
- , __func__
- , txrpt_ccx->tag1, txrpt_ccx->rsvd, txrpt_ccx->int_bt, txrpt_ccx->int_tri, txrpt_ccx->int_ccx
- , txrpt_ccx->mac_id, txrpt_ccx->pkt_drop, txrpt_ccx->pkt_ok, txrpt_ccx->bmc
- , txrpt_ccx->retry_cnt, txrpt_ccx->lifetime_over, txrpt_ccx->retry_over
- , txrpt_ccx_qtime_8723a(txrpt_ccx)
- , txrpt_ccx->final_data_rate
- , txrpt_ccx->qsel, txrpt_ccx_sw_8723a(txrpt_ccx)
- );
-}
-
void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf)
{
struct txrpt_ccx_8723a *txrpt_ccx = buf;
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c
index 6a7fb28e03da..b49bf33184de 100644
--- a/drivers/staging/rtl8723au/hal/usb_halinit.c
+++ b/drivers/staging/rtl8723au/hal/usb_halinit.c
@@ -338,17 +338,6 @@ static void _InitQueuePriority(struct rtw_adapter *Adapter)
_InitNormalChipQueuePriority(Adapter);
}
-static void _InitNetworkType(struct rtw_adapter *Adapter)
-{
- u32 value32;
-
- value32 = rtl8723au_read32(Adapter, REG_CR);
-
- /* TODO: use the other function to set network type */
- value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
- rtl8723au_write32(Adapter, REG_CR, value32);
-}
-
static void _InitTransferPageSize(struct rtw_adapter *Adapter)
{
/* Tx page size is always 128. */
@@ -484,62 +473,6 @@ static void _InitRetryFunction(struct rtw_adapter *Adapter)
rtl8723au_write8(Adapter, REG_ACKTO, 0x40);
}
-/*-----------------------------------------------------------------------------
- * Function: usb_AggSettingTxUpdate()
- *
- * Overview: Seperate TX/RX parameters update independent for TP
- * detection and dynamic TX/RX aggreagtion parameters update.
- *
- * Input: struct rtw_adapter *
- *
- * Output/Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 12/10/2010 MHC Seperate to smaller function.
- *
- *---------------------------------------------------------------------------*/
-static void usb_AggSettingTxUpdate(struct rtw_adapter *Adapter)
-{
-} /* usb_AggSettingTxUpdate */
-
-/*-----------------------------------------------------------------------------
- * Function: usb_AggSettingRxUpdate()
- *
- * Overview: Seperate TX/RX parameters update independent for TP
- * detection and dynamic TX/RX aggreagtion parameters update.
- *
- * Input: struct rtw_adapter *
- *
- * Output/Return: NONE
- *
- * Revised History:
- * When Who Remark
- * 12/10/2010 MHC Seperate to smaller function.
- *
- *---------------------------------------------------------------------------*/
-static void usb_AggSettingRxUpdate(struct rtw_adapter *Adapter)
-{
-} /* usb_AggSettingRxUpdate */
-
-static void InitUsbAggregationSetting(struct rtw_adapter *Adapter)
-{
- struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
-
- /* Tx aggregation setting */
- usb_AggSettingTxUpdate(Adapter);
-
- /* Rx aggregation setting */
- usb_AggSettingRxUpdate(Adapter);
-
- /* 201/12/10 MH Add for USB agg mode dynamic switch. */
- pHalData->UsbRxHighSpeedMode = false;
-}
-
-static void _InitOperationMode(struct rtw_adapter *Adapter)
-{
-}
-
static void _InitRFType(struct rtw_adapter *Adapter)
{
struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
@@ -584,24 +517,19 @@ enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter)
u8 val8;
enum rt_rf_power_state rfpowerstate = rf_off;
- if (pAdapter->pwrctrlpriv.bHWPowerdown) {
- val8 = rtl8723au_read8(pAdapter, REG_HSISR);
- DBG_8723A("pwrdown, 0x5c(BIT7) =%02x\n", val8);
- rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
- } else { /* rf on/off */
- rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
- rtl8723au_read8(pAdapter, REG_MAC_PINMUX_CFG) &
- ~BIT(3));
- val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
- DBG_8723A("GPIO_IN =%02x\n", val8);
- rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
- }
+ rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
+ rtl8723au_read8(pAdapter,
+ REG_MAC_PINMUX_CFG) & ~BIT(3));
+ val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
+ DBG_8723A("GPIO_IN =%02x\n", val8);
+ rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
+
return rfpowerstate;
-} /* HalDetectPwrDownMode */
+}
void _ps_open_RF23a(struct rtw_adapter *padapter);
-static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
+int rtl8723au_hal_init(struct rtw_adapter *Adapter)
{
u8 val8 = 0;
u32 boundary;
@@ -612,6 +540,8 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
unsigned long init_start_time = jiffies;
+ Adapter->hw_init_completed = false;
+
if (Adapter->pwrctrlpriv.bkeepfwalive) {
_ps_open_RF23a(Adapter);
@@ -718,9 +648,9 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
/* Add for tx power by rate fine tune. We need to call the function after BB config. */
/* Because the tx power by rate table is inited in BB config. */
- status = PHY_RFConfig8723A(Adapter);
+ status = PHY_RF6052_Config8723A(Adapter);
if (status == _FAIL) {
- DBG_8723A("PHY_RFConfig8723A fault !!\n");
+ DBG_8723A("PHY_RF6052_Config8723A failed!!\n");
goto exit;
}
@@ -756,14 +686,12 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
_InitInterrupt(Adapter);
hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
- _InitNetworkType(Adapter);/* set msr */
+ rtl8723a_set_media_status(Adapter, MSR_INFRA);
_InitWMACSetting(Adapter);
_InitAdaptiveCtrl(Adapter);
_InitEDCA(Adapter);
_InitRateFallback(Adapter);
_InitRetryFunction(Adapter);
- InitUsbAggregationSetting(Adapter);
- _InitOperationMode(Adapter);/* todo */
rtl8723a_InitBeaconParameters(Adapter);
_InitHWLed(Adapter);
@@ -771,7 +699,7 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
_BBTurnOnBlock(Adapter);
/* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
- invalidate_cam_all23a(Adapter);
+ rtl8723a_cam_invalidate_all(Adapter);
/* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */
PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel);
@@ -849,7 +777,9 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
rtl8723a_InitHalDm(Adapter);
- rtl8723a_set_nav_upper(Adapter, WiFiNavUpperUs);
+ val8 = ((WiFiNavUpperUs + HAL_8723A_NAV_UPPER_UNIT - 1) /
+ HAL_8723A_NAV_UPPER_UNIT);
+ rtl8723au_write8(Adapter, REG_NAV_UPPER, val8);
/* 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
if (((rtl8723au_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) !=
@@ -863,6 +793,13 @@ static int rtl8723au_hal_init(struct rtw_adapter *Adapter)
rtl8723au_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
exit:
+ if (status == _SUCCESS) {
+ Adapter->hw_init_completed = true;
+
+ if (Adapter->registrypriv.notch_filter == 1)
+ rtl8723a_notch_filter(Adapter, 1);
+ }
+
DBG_8723A("%s in %dms\n", __func__,
jiffies_to_msecs(jiffies - init_start_time));
return status;
@@ -1172,7 +1109,7 @@ static void CardDisableRTL8723U(struct rtw_adapter *Adapter)
rtl8723au_write8(Adapter, REG_RSV_CTRL, 0x0e);
}
-static int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
+int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
{
DBG_8723A("==> %s\n", __func__);
@@ -1185,6 +1122,8 @@ static int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
/* IC. Accord to johnny's opinion, only RU need the support. */
CardDisableRTL8723U(padapter);
+ padapter->hw_init_completed = false;
+
return _SUCCESS;
}
@@ -1532,9 +1471,9 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter,
mask = update_supported_rate23a(cur_network->SupportedRates,
supportRateNum);
mask |= (pmlmeinfo->HT_enable) ?
- update_MSC_rate23a(&pmlmeinfo->HT_caps) : 0;
+ update_MSC_rate23a(&pmlmeinfo->ht_cap) : 0;
- if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
+ if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
shortGIrate = true;
break;
@@ -1569,8 +1508,8 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter,
/* mask &= 0x0fffffff; */
rate_bitmap = 0x0fffffff;
- rate_bitmap = ODM_Get_Rate_Bitmap23a(&pHalData->odmpriv,
- mac_id, mask, rssi_level);
+ rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask,
+ rssi_level);
DBG_8723A("%s => mac_id:%d, networkType:0x%02x, "
"mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
__func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
@@ -1610,40 +1549,3 @@ void rtl8723a_update_ramask(struct rtw_adapter *padapter,
/* set correct initial date rate for each mac_id */
pdmpriv->INIDATA_RATE[mac_id] = init_rate;
}
-
-int rtw_hal_init23a(struct rtw_adapter *padapter)
-{
- int status;
-
- padapter->hw_init_completed = false;
-
- status = rtl8723au_hal_init(padapter);
-
- if (status == _SUCCESS) {
- padapter->hw_init_completed = true;
-
- if (padapter->registrypriv.notch_filter == 1)
- rtl8723a_notch_filter(padapter, 1);
- } else {
- padapter->hw_init_completed = false;
- DBG_8723A("rtw_hal_init23a: hal__init fail\n");
- }
-
- RT_TRACE(_module_hal_init_c_, _drv_err_,
- ("-rtl871x_hal_init:status = 0x%x\n", status));
-
- return status;
-}
-
-int rtw_hal_deinit23a(struct rtw_adapter *padapter)
-{
- int status;
-
- status = rtl8723au_hal_deinit(padapter);
-
- if (status == _SUCCESS)
- padapter->hw_init_completed = false;
- else
- DBG_8723A("\n rtw_hal_deinit23a: hal_init fail\n");
- return status;
-}
diff --git a/drivers/staging/rtl8723au/hal/usb_ops_linux.c b/drivers/staging/rtl8723au/hal/usb_ops_linux.c
index 8e9e61c74bd0..c1b04c13c392 100644
--- a/drivers/staging/rtl8723au/hal/usb_ops_linux.c
+++ b/drivers/staging/rtl8723au/hal/usb_ops_linux.c
@@ -22,278 +22,149 @@
#include <rtl8723a_hal.h>
#include <rtl8723a_recv.h>
-static int usbctrl_vendorreq(struct rtw_adapter *padapter, u8 request,
- u16 value, u16 index, void *pdata, u16 len,
- u8 requesttype)
+u8 rtl8723au_read8(struct rtw_adapter *padapter, u16 addr)
{
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
struct usb_device *udev = pdvobjpriv->pusbdev;
-
- unsigned int pipe;
- int status = 0;
- u8 reqtype;
- u8 *pIo_buf;
- int vendorreq_times = 0;
-
- if (padapter->bSurpriseRemoved || padapter->pwrctrlpriv.pnp_bstop_trx) {
- RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usbctrl_vendorreq:(padapter->bSurpriseRemoved||"
- "adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
- status = -EPERM;
- goto exit;
- }
-
- if (len > MAX_VENDOR_REQ_CMD_SIZE) {
- DBG_8723A("[%s] Buffer len error , vendor request failed\n",
- __func__);
- status = -EINVAL;
- goto exit;
- }
+ int len;
+ u8 data;
mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
+ addr, 0, &pdvobjpriv->usb_buf.val8, sizeof(data),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- /* Acquire IO memory for vendorreq */
- pIo_buf = pdvobjpriv->usb_vendor_req_buf;
-
- if (pIo_buf == NULL) {
- DBG_8723A("[%s] pIo_buf == NULL \n", __func__);
- status = -ENOMEM;
- goto release_mutex;
- }
-
- while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) {
- memset(pIo_buf, 0, len);
-
- if (requesttype == 0x01) {
- pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
- reqtype = REALTEK_USB_VENQT_READ;
- } else {
- pipe = usb_sndctrlpipe(udev, 0);/* write_out */
- reqtype = REALTEK_USB_VENQT_WRITE;
- memcpy(pIo_buf, pdata, len);
- }
-
- status = usb_control_msg(udev, pipe, request, reqtype,
- value, index, pIo_buf, len,
- RTW_USB_CONTROL_MSG_TIMEOUT);
-
- if (status == len) { /* Success this control transfer. */
- rtw_reset_continual_urb_error(pdvobjpriv);
- if (requesttype == 0x01) {
- /* For Control read transfer, we have to copy
- * the read data from pIo_buf to pdata.
- */
- memcpy(pdata, pIo_buf, len);
- }
- } else { /* error cases */
- DBG_8723A("reg 0x%x, usb %s %u fail, status:%d value ="
- " 0x%x, vendorreq_times:%d\n",
- value, (requesttype == 0x01) ?
- "read" : "write",
- len, status, *(u32 *)pdata, vendorreq_times);
-
- if (status < 0) {
- if (status == -ESHUTDOWN || status == -ENODEV)
- padapter->bSurpriseRemoved = true;
- else {
- struct hal_data_8723a *pHalData;
- pHalData = GET_HAL_DATA(padapter);
- pHalData->srestpriv.Wifi_Error_Status =
- USB_VEN_REQ_CMD_FAIL;
- }
- } else { /* status != len && status >= 0 */
- if (status > 0) {
- if (requesttype == 0x01) {
- /*
- * For Control read transfer,
- * we have to copy the read
- * data from pIo_buf to pdata.
- */
- memcpy(pdata, pIo_buf, len);
- }
- }
- }
-
- if (rtw_inc_and_chk_continual_urb_error(pdvobjpriv)) {
- padapter->bSurpriseRemoved = true;
- break;
- }
- }
-
- /* firmware download is checksumed, don't retry */
- if ((value >= FW_8723A_START_ADDRESS &&
- value <= FW_8723A_END_ADDRESS) || status == len)
- break;
- }
-
-release_mutex:
+ data = pdvobjpriv->usb_buf.val8;
mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
-exit:
- return status;
-}
-
-u8 rtl8723au_read8(struct rtw_adapter *padapter, u32 addr)
-{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 data = 0;
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 1;
-
- usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
return data;
}
-u16 rtl8723au_read16(struct rtw_adapter *padapter, u32 addr)
+u16 rtl8723au_read16(struct rtw_adapter *padapter, u16 addr)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le16 data;
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+ int len;
+ u16 data;
- wvalue = (u16)(addr&0x0000ffff);
- len = 2;
+ mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
+ addr, 0, &pdvobjpriv->usb_buf.val16, sizeof(data),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
+ data = le16_to_cpu(pdvobjpriv->usb_buf.val16);
+ mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
- return le16_to_cpu(data);
+ return data;
}
-u32 rtl8723au_read32(struct rtw_adapter *padapter, u32 addr)
+u32 rtl8723au_read32(struct rtw_adapter *padapter, u16 addr)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
-
- request = 0x05;
- requesttype = 0x01;/* read_in */
- index = 0;/* n/a */
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
+ int len;
+ u32 data;
- wvalue = (u16)(addr&0x0000ffff);
- len = 4;
+ mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ,
+ addr, 0, &pdvobjpriv->usb_buf.val32, sizeof(data),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
+ data = le32_to_cpu(pdvobjpriv->usb_buf.val32);
+ mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
- return le32_to_cpu(data);
+ return data;
}
-int rtl8723au_write8(struct rtw_adapter *padapter, u32 addr, u8 val)
+int rtl8723au_write8(struct rtw_adapter *padapter, u16 addr, u8 val)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 data;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
int ret;
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = 1;
+ mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ pdvobjpriv->usb_buf.val8 = val;
- data = val;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ,
+ REALTEK_USB_VENQT_WRITE,
+ addr, 0, &pdvobjpriv->usb_buf.val8, sizeof(val),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
+ if (ret != sizeof(val))
+ ret = _FAIL;
+ else
+ ret = _SUCCESS;
+ mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
return ret;
}
-int rtl8723au_write16(struct rtw_adapter *padapter, u32 addr, u16 val)
+int rtl8723au_write16(struct rtw_adapter *padapter, u16 addr, u16 val)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le16 data;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
int ret;
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
+ mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ pdvobjpriv->usb_buf.val16 = cpu_to_le16(val);
- wvalue = (u16)(addr&0x0000ffff);
- len = 2;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ,
+ REALTEK_USB_VENQT_WRITE,
+ addr, 0, &pdvobjpriv->usb_buf.val16, sizeof(val),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- data = cpu_to_le16(val);
+ if (ret != sizeof(val))
+ ret = _FAIL;
+ else
+ ret = _SUCCESS;
- ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
+ mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
return ret;
}
-int rtl8723au_write32(struct rtw_adapter *padapter, u32 addr, u32 val)
+int rtl8723au_write32(struct rtw_adapter *padapter, u16 addr, u32 val)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- __le32 data;
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
int ret;
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
+ mutex_lock(&pdvobjpriv->usb_vendor_req_mutex);
+ pdvobjpriv->usb_buf.val32 = cpu_to_le32(val);
- wvalue = (u16)(addr&0x0000ffff);
- len = 4;
- data = cpu_to_le32(val);
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ,
+ REALTEK_USB_VENQT_WRITE,
+ addr, 0, &pdvobjpriv->usb_buf.val32, sizeof(val),
+ RTW_USB_CONTROL_MSG_TIMEOUT);
- ret = usbctrl_vendorreq(padapter, request, wvalue, index, &data,
- len, requesttype);
+ if (ret != sizeof(val))
+ ret = _FAIL;
+ else
+ ret = _SUCCESS;
+ mutex_unlock(&pdvobjpriv->usb_vendor_req_mutex);
return ret;
}
-int rtl8723au_writeN(struct rtw_adapter *padapter,
- u32 addr, u32 length, u8 *pdata)
+int rtl8723au_writeN(struct rtw_adapter *padapter, u16 addr, u16 len, u8 *buf)
{
- u8 request;
- u8 requesttype;
- u16 wvalue;
- u16 index;
- u16 len;
- u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
+ struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
+ struct usb_device *udev = pdvobjpriv->pusbdev;
int ret;
- request = 0x05;
- requesttype = 0x00;/* write_out */
- index = 0;/* n/a */
-
- wvalue = (u16)(addr&0x0000ffff);
- len = length;
- memcpy(buf, pdata, len);
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ REALTEK_USB_VENQT_CMD_REQ,
+ REALTEK_USB_VENQT_WRITE,
+ addr, 0, buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
- ret = usbctrl_vendorreq(padapter, request, wvalue, index, buf,
- len, requesttype);
-
- return ret;
+ if (ret != len)
+ return _FAIL;
+ return _SUCCESS;
}
/*
@@ -647,7 +518,6 @@ static void usb_read_port_complete(struct urb *purb)
struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
struct rtw_adapter *padapter = (struct rtw_adapter *)precvbuf->adapter;
struct recv_priv *precvpriv = &padapter->recvpriv;
- struct hal_data_8723a *pHalData;
RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
("usb_read_port_complete!!!\n"));
@@ -726,9 +596,6 @@ static void usb_read_port_complete(struct urb *purb)
break;
case -EPROTO:
case -EOVERFLOW:
- pHalData = GET_HAL_DATA(padapter);
- pHalData->srestpriv.Wifi_Error_Status =
- USB_READ_PORT_FAIL;
rtl8723au_read_port(padapter, RECV_BULK_IN_ADDR, 0,
precvbuf);
break;
@@ -754,12 +621,10 @@ int rtl8723au_read_port(struct rtw_adapter *adapter, u32 addr, u32 cnt,
struct recv_priv *precvpriv = &adapter->recvpriv;
struct usb_device *pusbd = pdvobj->pusbdev;
- if (adapter->bDriverStopped || adapter->bSurpriseRemoved ||
- adapter->pwrctrlpriv.pnp_bstop_trx) {
+ if (adapter->bDriverStopped || adapter->bSurpriseRemoved) {
RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
("usb_read_port:(padapter->bDriverStopped ||"
- "padapter->bSurpriseRemoved ||adapter->"
- "pwrctrlpriv.pnp_bstop_trx)!!!\n"));
+ "padapter->bSurpriseRemoved)!!!\n"));
return _FAIL;
}
diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
index 299598b53876..688f20412bca 100644
--- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
+++ b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
@@ -224,7 +224,6 @@ SetAntennaConfig92C(struct rtw_adapter *Adapter, u8 DefaultAnt);
/* MAC/BB/RF HAL config */
int PHY_BBConfig8723A(struct rtw_adapter *Adapter);
-int PHY_RFConfig8723A(struct rtw_adapter *Adapter);
s32 PHY_MACConfig8723A(struct rtw_adapter *padapter);
#endif
diff --git a/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h b/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h
index e99833cc7929..127609404652 100644
--- a/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h
+++ b/drivers/staging/rtl8723au/include/HalHWImg8723A_BB.h
@@ -35,10 +35,4 @@ void ODM_ReadAndConfig_PHY_REG_1T_8723A(struct dm_odm_t *pDM_Odm);
void ODM_ReadAndConfig_PHY_REG_MP_8723A(struct dm_odm_t *pDM_Odm);
-/******************************************************************************
-* PHY_REG_PG.TXT
-******************************************************************************/
-
-void ODM_ReadAndConfig_PHY_REG_PG_8723A(struct dm_odm_t *pDM_Odm);
-
#endif /* end of HWIMG_SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/drv_types.h b/drivers/staging/rtl8723au/include/drv_types.h
index a94857df2def..9870f87bdc70 100644
--- a/drivers/staging/rtl8723au/include/drv_types.h
+++ b/drivers/staging/rtl8723au/include/drv_types.h
@@ -111,7 +111,6 @@ struct registry_priv {
u8 antdiv_cfg;
u8 antdiv_type;
- u8 usbss_enable;/* 0:disable,1:enable */
u8 hwpdn_mode;/* 0:disable,1:enable,2:decide by EFUSE config */
u8 hwpwrp_detect;/* 0:disable,1:enable */
@@ -177,10 +176,13 @@ struct dvobj_priv {
u8 RtNumOutPipes;
int ep_num[5]; /* endpoint number */
- struct mutex usb_vendor_req_mutex;
+ struct mutex usb_vendor_req_mutex;
- u8 *usb_alloc_vendor_req_buf;
- u8 *usb_vendor_req_buf;
+ union {
+ __le32 val32;
+ __le16 val16;
+ u8 val8;
+ } usb_buf;
struct usb_interface *pusbintf;
struct usb_device *pusbdev;
@@ -257,9 +259,6 @@ struct rtw_adapter {
u8 bFWReady;
u8 bReadPortCancel;
u8 bWritePortCancel;
- /* The driver will show the desired chan nor when this flag is 1. */
- u8 bNotifyChannelChange;
- struct rtw_adapter *pbuddy_adapter;
/* extend to support multi interface */
/* IFACE_ID0 is equals to PRIMARY_ADAPTER */
@@ -269,8 +268,6 @@ struct rtw_adapter {
#define adapter_to_dvobj(adapter) (adapter->dvobj)
-int rtw_handle_dualmac23a(struct rtw_adapter *adapter, bool init);
-
static inline u8 *myid(struct eeprom_priv *peepriv)
{
return peepriv->mac_addr;
diff --git a/drivers/staging/rtl8723au/include/hal_com.h b/drivers/staging/rtl8723au/include/hal_com.h
index 4a161e26c8dc..7c31865e9865 100644
--- a/drivers/staging/rtl8723au/include/hal_com.h
+++ b/drivers/staging/rtl8723au/include/hal_com.h
@@ -182,7 +182,7 @@ void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime);
void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble);
void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec);
void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex);
-void rtl8723a_cam_invalid_all(struct rtw_adapter *padapter);
+void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter);
void rtl8723a_cam_write(struct rtw_adapter *padapter,
u8 entry, u16 ctrl, const u8 *mac, const u8 *key);
void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter);
@@ -197,7 +197,6 @@ void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi);
void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be);
void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk);
void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val);
-void rtl8723a_set_nav_upper(struct rtw_adapter *padapter, u32 usNavUpper);
void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain);
void rtl8723a_odm_support_ability_write(struct rtw_adapter *padapter, u32 val);
diff --git a/drivers/staging/rtl8723au/include/hal_intf.h b/drivers/staging/rtl8723au/include/hal_intf.h
index 04223b5c047d..404acb52352d 100644
--- a/drivers/staging/rtl8723au/include/hal_intf.h
+++ b/drivers/staging/rtl8723au/include/hal_intf.h
@@ -101,10 +101,9 @@ enum hardware_type {
void rtw_hal_def_value_init23a(struct rtw_adapter *padapter);
int pm_netdev_open23a(struct net_device *pnetdev, u8 bnormal);
-int rtw_resume_process23a(struct rtw_adapter *padapter);
-int rtw_hal_init23a(struct rtw_adapter *padapter);
-int rtw_hal_deinit23a(struct rtw_adapter *padapter);
+int rtl8723au_hal_init(struct rtw_adapter *padapter);
+int rtl8723au_hal_deinit(struct rtw_adapter *padapter);
void rtw_hal_stop(struct rtw_adapter *padapter);
void rtw_hal_update_ra_mask23a(struct sta_info *psta, u8 rssi_level);
diff --git a/drivers/staging/rtl8723au/include/ieee80211.h b/drivers/staging/rtl8723au/include/ieee80211.h
index 69c0f5c94fcc..e9f465f0bc2c 100644
--- a/drivers/staging/rtl8723au/include/ieee80211.h
+++ b/drivers/staging/rtl8723au/include/ieee80211.h
@@ -27,8 +27,6 @@
#endif
-#define MGMT_QUEUE_NUM 5
-
#ifdef CONFIG_8723AU_AP_MODE
/* STA flags */
@@ -50,12 +48,6 @@
#endif
-#define IEEE_CMD_SET_WPA_PARAM 1
-#define IEEE_CMD_SET_WPA_IE 2
-#define IEEE_CMD_SET_ENCRYPTION 3
-
-#define IEEE_CRYPT_ALG_NAME_LEN 16
-
#define WPA_CIPHER_NONE BIT(0)
#define WPA_CIPHER_WEP40 BIT(1)
#define WPA_CIPHER_WEP104 BIT(2)
@@ -81,7 +73,6 @@ extern u8 WPA_CIPHER_SUITE_WEP10423A[];
#define RSN_HEADER_LEN 4
#define RSN_SELECTOR_LEN 4
-extern u16 RSN_VERSION_BSD23A;
extern u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X23A[];
extern u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X23A[];
extern u8 RSN_CIPHER_SUITE_NONE23A[];
@@ -154,50 +145,6 @@ enum NETWORK_TYPE
#define IsSupportedTxMCS(NetType) (NetType & (WIRELESS_11_24N|WIRELESS_11_5N) ? true : false)
-struct ieee_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 name;
- u32 value;
- } wpa_param;
- struct {
- u32 len;
- u8 reserved[32];
- u8 data[0];
- } wpa_ie;
- struct{
- int command;
- int reason_code;
- } mlme;
- struct {
- u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
- u8 set_tx;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
-#ifdef CONFIG_8723AU_AP_MODE
- struct {
- u16 aid;
- u16 capability;
- int flags;
- u8 tx_supp_rates[16];
- struct ieee80211_ht_cap ht_cap;
- } add_sta;
- struct {
- u8 reserved[2];/* for set max_num_sta */
- u8 buf[0];
- } bcn_ie;
-#endif
-
- } u;
-};
-
-
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
@@ -221,20 +168,10 @@ struct ieee80211_snap_hdr {
#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-#define WLAN_FC_GET_TYPE(fc) (fc & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) (fc & IEEE80211_FCTL_STYPE)
-
-#define WLAN_QC_GET_TID(qc) (qc & 0x0f)
-
-#define WLAN_GET_SEQ_FRAG(seq) (seq & RTW_IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq) (seq & RTW_IEEE80211_SCTL_SEQ)
-
-
#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534
#define WLAN_REASON_EXPIRATION_CHK 65535
-
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
@@ -305,7 +242,6 @@ struct ieee80211_snap_hdr {
#define IEEE80211_OFDM_SHIFT_MASK_A 4
#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
@@ -315,14 +251,13 @@ struct ieee80211_snap_hdr {
#define MAX_RATES_LENGTH 12
#define MAX_RATES_EX_LENGTH 16
#define MAX_CHANNEL_NUMBER 161
+#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
#define MAX_WPA_IE_LEN 256
-#define MAX_WPS_IE_LEN 512
+#define MAX_WPS_IE_LEN 256
#define MAX_P2P_IE_LEN 256
#define MAX_WFD_IE_LEN 128
-#define IW_ESSID_MAX_SIZE 32
-
/*
join_res:
-1: authentication fail
@@ -335,26 +270,6 @@ join_res:
#define MAXTID 16
-enum _PUBLIC_ACTION{
- ACT_PUBLIC_BSSCOEXIST = 0, /* 20/40 BSS Coexistence */
- ACT_PUBLIC_DSE_ENABLE = 1,
- ACT_PUBLIC_DSE_DEENABLE = 2,
- ACT_PUBLIC_DSE_REG_LOCATION = 3,
- ACT_PUBLIC_EXT_CHL_SWITCH = 4,
- ACT_PUBLIC_DSE_MSR_REQ = 5,
- ACT_PUBLIC_DSE_MSR_RPRT = 6,
- ACT_PUBLIC_MP = 7, /* Measurement Pilot */
- ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8,
- ACT_PUBLIC_VENDOR = 9, /* for WIFI_DIRECT */
- ACT_PUBLIC_GAS_INITIAL_REQ = 10,
- ACT_PUBLIC_GAS_INITIAL_RSP = 11,
- ACT_PUBLIC_GAS_COMEBACK_REQ = 12,
- ACT_PUBLIC_GAS_COMEBACK_RSP = 13,
- ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14,
- ACT_PUBLIC_LOCATION_TRACK = 15,
- ACT_PUBLIC_MAX
-};
-
#define WME_OUI_TYPE 2
#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0
#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1
@@ -407,14 +322,8 @@ struct rtw_ieee80211_channel {
/*, (channel)->orig_mag*/ \
/*, (channel)->orig_mpwr*/ \
-u8 *rtw_set_fixed_ie23a(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen);
u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen);
-enum secondary_ch_offset {
- SCN = 0, /* no secondary channel */
- SCA = 1, /* secondary channel above */
- SCB = 3, /* secondary channel below */
-};
u8 hal_ch_offset_to_secondary_ch_offset23a(u8 ch_offset);
u8 *rtw_set_ie23a_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode, u8 new_ch, u8 ch_switch_cnt);
u8 *rtw_set_ie23a_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset);
@@ -425,16 +334,11 @@ int rtw_ies_remove_ie23a(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u
void rtw_set_supported_rate23a(u8* SupportedRates, uint mode) ;
-int rtw_get_wpa_cipher_suite23a(const u8 *s);
-int rtw_get_wpa2_cipher_suite23a(const u8 *s);
int rtw_parse_wpa_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
int rtw_parse_wpa2_ie23a(const u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x);
-int rtw_get_sec_ie23a(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len);
-
-u8 *rtw_get_wps_ie23a(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen);
-u8 *rtw_get_wps_attr23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr);
-u8 *rtw_get_wps_attr_content23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content);
+const u8 *rtw_get_wps_attr23a(const u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr);
+const u8 *rtw_get_wps_attr_content23a(const u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content);
uint rtw_get_rateset_len23a(u8 *rateset);
@@ -448,8 +352,7 @@ int rtw_check_network_type23a(unsigned char *rate, int ratelen, int channel);
void rtw_get_bcn_info23a(struct wlan_network *pnetwork);
-u16 rtw_mcs_rate23a(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char * MCS_rate);
-
-const char *action_public_str23a(u8 action);
+u16 rtw_mcs_rate23a(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40,
+ struct ieee80211_mcs_info *mcs);
#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8723au/include/ioctl_cfg80211.h b/drivers/staging/rtl8723au/include/ioctl_cfg80211.h
index 63e921f921d3..3a4ead54f948 100644
--- a/drivers/staging/rtl8723au/include/ioctl_cfg80211.h
+++ b/drivers/staging/rtl8723au/include/ioctl_cfg80211.h
@@ -61,9 +61,6 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
unsigned char *da, unsigned short reason);
#endif /* CONFIG_8723AU_AP_MODE */
-void rtw_cfg80211_rx_action(struct rtw_adapter *adapter, u8 *frame,
- uint frame_len, const char*msg);
-
bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter);
#endif /* __IOCTL_CFG80211_H__ */
diff --git a/drivers/staging/rtl8723au/include/odm.h b/drivers/staging/rtl8723au/include/odm.h
index 183d8ff1ab9b..68ff7bbc6ad1 100644
--- a/drivers/staging/rtl8723au/include/odm.h
+++ b/drivers/staging/rtl8723au/include/odm.h
@@ -125,7 +125,6 @@ struct dig_t {
bool bMediaConnect_0;
bool bMediaConnect_1;
- u32 AntDiv_RSSI_max;
u32 RSSI_max;
};
@@ -300,7 +299,6 @@ enum odm_cmninfo {
/* */
ODM_CMNINFO_PLATFORM = 0,
- ODM_CMNINFO_ABILITY, /* enum odm_ability */
ODM_CMNINFO_INTERFACE, /* enum odm_interface_def */
ODM_CMNINFO_MP_TEST_CHIP,
ODM_CMNINFO_IC_TYPE, /* enum odm_ic_type_def */
@@ -320,27 +318,6 @@ enum odm_cmninfo {
/* */
/* Dynamic value: */
/* */
- ODM_CMNINFO_MAC_PHY_MODE, /* enum odm_mac_phy_mode */
- ODM_CMNINFO_TX_UNI,
- ODM_CMNINFO_RX_UNI,
- ODM_CMNINFO_WM_MODE, /* enum odm_wireless_mode */
- ODM_CMNINFO_BAND, /* enum odm_band_type */
- ODM_CMNINFO_SEC_CHNL_OFFSET, /* enum odm_sec_chnl_offset */
- ODM_CMNINFO_SEC_MODE, /* enum odm_security */
- ODM_CMNINFO_BW, /* enum odm_band_width */
- ODM_CMNINFO_CHNL,
-
- 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, /* enum odm_cca_path */
- ODM_CMNINFO_DRV_STOP,
- ODM_CMNINFO_PNP_IN,
- ODM_CMNINFO_INIT_ON,
- ODM_CMNINFO_ANT_TEST,
- ODM_CMNINFO_NET_CLOSED,
ODM_CMNINFO_MP_MODE,
ODM_CMNINFO_WIFI_DIRECT,
@@ -415,10 +392,6 @@ enum odm_ic_type_def {
ODM_RTL8821 = BIT(6),
};
-#define ODM_IC_11N_SERIES \
- (ODM_RTL8192S|ODM_RTL8192C|ODM_RTL8192D|ODM_RTL8723A|ODM_RTL8188E)
-#define ODM_IC_11AC_SERIES (ODM_RTL8812)
-
/* ODM_CMNINFO_CUT_VER */
enum odm_cut_version {
ODM_CUT_A = 1,
@@ -516,15 +489,6 @@ enum odm_sec_chnl_offset {
ODM_ABOVE = 2
};
-/* ODM_CMNINFO_BW */
-enum odm_band_width {
- ODM_BW20M = 0,
- ODM_BW40M = 1,
- ODM_BW80M = 2,
- ODM_BW160M = 3,
- ODM_BW10M = 4,
-};
-
/* ODM_CMNINFO_CHNL */
/* ODM_CMNINFO_BOARD_TYPE */
@@ -705,7 +669,6 @@ struct dm_odm_t {
bool bDualMacSmartConcurrent;
u32 BK_SupportAbility;
- u8 AntDivType;
/* HOOK BEFORE REG INIT----------- */
/* */
@@ -717,37 +680,6 @@ struct dm_odm_t {
bool bool_temp;
struct rtw_adapter *PADAPTER_temp;
- /* MAC PHY Mode SMSP/DMSP/DMDP = 0/1/2 */
- u8 *pMacPhyMode;
- /* TX Unicast byte count */
- u64 *pNumTxBytesUnicast;
- /* RX Unicast byte count */
- u64 *pNumRxBytesUnicast;
- /* Wireless mode B/G/A/N = BIT0/BIT1/BIT2/BIT3 */
- u8 *pWirelessMode; /* enum odm_wireless_mode */
- /* Frequence band 2.4G/5G = 0/1 */
- u8 *pBandType;
- /* Secondary channel offset don't_care/below/above = 0/1/2 */
- u8 *pSecChOffset;
- /* Security mode Open/WEP/AES/TKIP = 0/1/2/3 */
- u8 *pSecurity;
- /* BW info 20M/40M/80M = 0/1/2 */
- u8 *pBandWidth;
- /* Central channel location Ch1/Ch2/.... */
- u8 *pChannel; /* central channel number */
- /* Common info for 92D DMSP */
-
- bool *pbGetValueFromOtherMac;
- struct rtw_adapter **pBuddyAdapter;
- bool *pbMasterOfDMSP; /* MAC0: master, MAC1: slave */
- /* Common info for Status */
- bool *pbScanInProcess;
- bool *pbPowerSaving;
- /* CCA Path 2-path/path-A/path-B = 0/1/2; using enum odm_cca_path. */
- u8 *pOnePathCCA;
- /* pMgntInfo->AntennaTest */
- u8 *pAntennaTest;
- bool *pbNet_closed;
/* POINTER REFERENCE----------- */
/* */
/* CALL BY VALUE------------- */
@@ -804,7 +736,6 @@ struct dm_odm_t {
struct false_alarm_stats FalseAlmCnt;
struct false_alarm_stats FlaseAlmCntBuddyAdapter;
struct sw_ant_sw DM_SWAT_Table;
- bool RSSI_test;
struct edca_turbo DM_EDCA_Table;
u32 WMMEDCA_BE;
@@ -813,16 +744,10 @@ struct dm_odm_t {
/* ================================================== */
/* */
- /* common */
- bool *pbDriverStopped;
- bool *pbDriverIsGoingToPnpSetPowerSleep;
- bool *pinit_adpt_in_progress;
-
/* PSD */
bool bUserAssignLevel;
u8 RSSI_BT; /* come from BT */
bool bPSDinProcess;
- bool bDMInitialGainEnable;
/* for rate adaptive, in fact, 88c/92c fw will handle this */
u8 bUseRAMask;
@@ -855,14 +780,6 @@ enum odm_rf_content {
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,
-};
-
/* Status code */
enum rt_status {
RT_STATUS_SUCCESS,
@@ -1013,10 +930,6 @@ extern u8 CCKSwingTable_Ch1423A [CCK_TABLE_SIZE][8];
-/* */
-/* check Sta pointer valid or not */
-/* */
-#define IS_STA_VALID(pSta) (pSta)
/* 20100514 Joseph: Add definition for antenna switching test after link. */
/* This indicates two different the steps. */
/* In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. */
@@ -1025,6 +938,8 @@ extern u8 CCKSwingTable_Ch1423A [CCK_TABLE_SIZE][8];
#define SWAW_STEP_PEAK 0
#define SWAW_STEP_DETERMINE 1
+struct hal_data_8723a;
+
void ODM_Write_DIG23a(struct dm_odm_t *pDM_Odm, u8 CurrentIGI);
void ODM_Write_CCK_CCA_Thres23a(struct dm_odm_t *pDM_Odm, u8 CurCCK_CCAThres);
@@ -1034,9 +949,6 @@ void ODM_SetAntenna(struct dm_odm_t *pDM_Odm, u8 Antenna);
#define dm_RF_Saving ODM_RF_Saving23a
void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal);
-#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink
-void ODM_SwAntDivRestAfterLink(struct dm_odm_t *pDM_Odm);
-
#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck23a
void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
@@ -1044,27 +956,21 @@ bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
u8 *pRATRState);
-#define dm_SWAW_RSSI_Check ODM_SwAntDivChkPerPktRssi
-void ODM_SwAntDivChkPerPktRssi(struct dm_odm_t *pDM_Odm, u8 StationID,
- struct phy_info *pPhyInfo);
-
u32 ConvertTo_dB23a(u32 Value);
u32 GetPSDData(struct dm_odm_t *pDM_Odm, unsigned int point, u8 initial_gain_psd);
void odm_DIG23abyRSSI_LPS(struct dm_odm_t *pDM_Odm);
-u32 ODM_Get_Rate_Bitmap23a(struct dm_odm_t *pDM_Odm, u32 macid, u32 ra_mask, u8 rssi_level);
+u32 ODM_Get_Rate_Bitmap23a(struct hal_data_8723a *pHalData, u32 macid, u32 ra_mask, u8 rssi_level);
void ODM23a_DMInit(struct dm_odm_t *pDM_Odm);
-void ODM_DMWatchdog23a(struct dm_odm_t *pDM_Odm); /* For common use in the future */
+void ODM_DMWatchdog23a(struct rtw_adapter *adapter);
void ODM_CmnInfoInit23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, u32 Value);
-void ODM23a_CmnInfoHook(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, void *pValue);
-
void ODM_CmnInfoPtrArrayHook23a(struct dm_odm_t *pDM_Odm, enum odm_cmninfo CmnInfo, u16 Index, void *pValue);
void ODM_CmnInfoUpdate23a(struct dm_odm_t *pDM_Odm, u32 CmnInfo, u64 Value);
diff --git a/drivers/staging/rtl8723au/include/odm_HWConfig.h b/drivers/staging/rtl8723au/include/odm_HWConfig.h
index 6b98e05d0460..78021a8cf8f9 100644
--- a/drivers/staging/rtl8723au/include/odm_HWConfig.h
+++ b/drivers/staging/rtl8723au/include/odm_HWConfig.h
@@ -152,21 +152,4 @@ ODM_PhyStatusQuery23a(
struct odm_packet_info *pPktinfo
);
-void ODM_MacStatusQuery23a(struct dm_odm_t *pDM_Odm,
- u8 *pMacStatus,
- u8 MacID,
- bool bPacketMatchBSSID,
- bool bPacketToSelf,
- bool bPacketBeacon
-);
-
-int ODM_ConfigRFWithHeaderFile23a(struct dm_odm_t *pDM_Odm,
- enum RF_RADIO_PATH Content,
- enum RF_RADIO_PATH eRFPath);
-
-int ODM_ConfigBBWithHeaderFile23a(struct dm_odm_t *pDM_Odm,
- enum odm_bb_config_type ConfigType);
-
-int ODM_ConfigMACWithHeaderFile23a(struct dm_odm_t *pDM_Odm);
-
#endif
diff --git a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h
index 4ea579b2e8bd..a6cfb6df4cf7 100644
--- a/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h
+++ b/drivers/staging/rtl8723au/include/odm_RegConfig8723A.h
@@ -18,17 +18,11 @@
void odm_ConfigRFReg_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Data,
enum RF_RADIO_PATH RF_PATH, u32 RegAddr);
-void odm_ConfigRF_RadioA_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Data);
-
-void odm_ConfigRF_RadioB_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Data);
-
void odm_ConfigMAC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u8 Data);
void odm_ConfigBB_AGC_8723A(struct dm_odm_t *pDM_Odm, u32 Addr,
u32 Bitmask, u32 Data);
-void odm_ConfigBB_PHY_REG_PG_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data);
-
void odm_ConfigBB_PHY_8723A(struct dm_odm_t *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data);
#endif /* end of SUPPORT */
diff --git a/drivers/staging/rtl8723au/include/odm_RegDefine11AC.h b/drivers/staging/rtl8723au/include/odm_RegDefine11AC.h
deleted file mode 100644
index 77b7acec5ea8..000000000000
--- a/drivers/staging/rtl8723au/include/odm_RegDefine11AC.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- ******************************************************************************/
-
-#ifndef __ODM_REGDEFINE11AC_H__
-#define __ODM_REGDEFINE11AC_H__
-
-/* 2 RF REG LIST */
-
-
-
-/* 2 BB REG LIST */
-/* PAGE 8 */
-/* PAGE 9 */
-#define ODM_REG_OFDM_FA_RST_11AC 0x9A4
-/* 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 C */
-#define ODM_REG_IGI_A_11AC 0xC50
-/* PAGE E */
-#define ODM_REG_IGI_B_11AC 0xE50
-/* PAGE F */
-#define ODM_REG_OFDM_FA_11AC 0xF48
-
-
-/* 2 MAC REG LIST */
-
-
-
-
-/* DIG Related */
-#define ODM_BIT_IGI_11AC 0xFFFFFFFF
-
-
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/odm_interface.h b/drivers/staging/rtl8723au/include/odm_interface.h
index c260d6bd8ff5..ea35070b744f 100644
--- a/drivers/staging/rtl8723au/include/odm_interface.h
+++ b/drivers/staging/rtl8723au/include/odm_interface.h
@@ -33,17 +33,16 @@ ODM_REG(DIG,_pDM_Odm)
#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) \
+#define _cat(_name, _func) \
+ ( \
+ _func##_11N(_name) \
)
/* _name: name of register or bit. */
/* Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" */
/* gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", depends on SupportICType. */
-#define ODM_REG(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _reg)
-#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _bit)
+#define ODM_REG(_name, _pDM_Odm) _cat(_name, _reg)
+#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _bit)
/* */
/* 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. */
diff --git a/drivers/staging/rtl8723au/include/odm_precomp.h b/drivers/staging/rtl8723au/include/odm_precomp.h
index 69de888d884c..fb793c8ba7f8 100644
--- a/drivers/staging/rtl8723au/include/odm_precomp.h
+++ b/drivers/staging/rtl8723au/include/odm_precomp.h
@@ -32,7 +32,6 @@
#include "odm.h"
#include "odm_HWConfig.h"
#include "odm_debug.h"
-#include "odm_RegDefine11AC.h"
#include "odm_RegDefine11N.h"
#include "HalDMOutSrc8723A.h" /* for IQK,LCK,Power-tracking */
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_cmd.h b/drivers/staging/rtl8723au/include/rtl8723a_cmd.h
index 900baccc3c24..014c02edded6 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_cmd.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_cmd.h
@@ -153,6 +153,6 @@ int rtl8723a_set_rssi_cmd(struct rtw_adapter *padapter, u8 *param);
int rtl8723a_set_raid_cmd(struct rtw_adapter *padapter, u32 mask, u8 arg);
void rtl8723a_add_rateatid(struct rtw_adapter *padapter, u32 bitmap, u8 arg, u8 rssi_level);
-void CheckFwRsvdPageContent23a(struct rtw_adapter *padapter);
+int FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_dm.h b/drivers/staging/rtl8723au/include/rtl8723a_dm.h
index ccac672c9c04..18112225e53f 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_dm.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_dm.h
@@ -39,9 +39,6 @@ enum{
/* duplicate code,will move to ODM ######### */
struct dm_priv
{
- u8 DM_Type;
- u8 DMFlag;
- u8 InitDMFlag;
u32 InitODMFlag;
/* Upper and Lower Signal threshold for Rate Adaptive*/
@@ -134,7 +131,6 @@ struct dm_priv
/* */
void rtl8723a_init_dm_priv(struct rtw_adapter *padapter);
-void rtl8723a_deinit_dm_priv(struct rtw_adapter *padapter);
void rtl8723a_InitHalDm(struct rtw_adapter *padapter);
void rtl8723a_HalDmWatchDog(struct rtw_adapter *padapter);
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_hal.h b/drivers/staging/rtl8723au/include/rtl8723a_hal.h
index 344b7085f877..3b0b06d6e41e 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_hal.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_hal.h
@@ -315,7 +315,6 @@ struct hal_data_8723a {
u8 framesync;
u32 framesyncC34;
u8 framesyncMonitor;
- u8 DefaultInitialGain[4];
u8 pwrGroupCnt;
u32 MCSTxPowerLevelOriginalOffset[7][16];
u32 CCKTxPowerLevelOriginalOffset;
@@ -356,7 +355,6 @@ struct hal_data_8723a {
u8 fw_ractrl;
u8 RegTxPause;
/* Beacon function related global variable. */
- u32 RegBcnCtrlVal;
u8 RegFwHwTxQCtrl;
u8 RegReg542;
@@ -384,9 +382,6 @@ struct hal_data_8723a {
u8 OutEpQueueSel;
u8 OutEpNumber;
- /* 2010/12/10 MH Add for USB aggreation mode dynamic shceme. */
- bool UsbRxHighSpeedMode;
-
/* 2010/11/22 MH Add for slim combo debug mode selective. */
/* This is used for fix the drawback of CU TSMC-A/UMC-A cut. HW auto suspend ability. Close BT clock. */
bool SlimComboDbg;
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_spec.h b/drivers/staging/rtl8723au/include/rtl8723a_spec.h
index b5d7123f7873..59b545b642b4 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_spec.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_spec.h
@@ -454,8 +454,6 @@
/* */
/* 9. Security Control Registers (Offset: ) */
/* */
- /* IN 8190 Data Sheet is called CAMcmd */
-#define RWCAM REG_CAMCMD
/* Software write CAM input content */
#define WCAMI REG_CAMWRITE
/* Software read/write CAM config */
@@ -1323,14 +1321,6 @@ Current IOREG MAP
#define ENSWBCN BIT(8)
#define ENSEC BIT(9)
-/* Network type */
-#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
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_sreset.h b/drivers/staging/rtl8723au/include/rtl8723a_sreset.h
index 82af6a2704ed..6197910a4a53 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_sreset.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_sreset.h
@@ -20,6 +20,5 @@
#include <rtw_sreset.h>
void rtl8723a_sreset_xmit_status_check(struct rtw_adapter *padapter);
-void rtl8723a_sreset_linked_status_check(struct rtw_adapter *padapter);
#endif
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h b/drivers/staging/rtl8723au/include/rtl8723a_xmit.h
index 79883d7b867d..815560c6e1d7 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_xmit.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_xmit.h
@@ -211,7 +211,6 @@ struct txrpt_ccx_8723a {
#define txrpt_ccx_sw_8723a(txrpt_ccx) ((txrpt_ccx)->sw0 + ((txrpt_ccx)->sw1<<8))
#define txrpt_ccx_qtime_8723a(txrpt_ccx) ((txrpt_ccx)->ccx_qtime0+((txrpt_ccx)->ccx_qtime1<<8))
-void dump_txrpt_ccx_8723a(void *buf);
void handle_txrpt_ccx_8723a(struct rtw_adapter *adapter, void *buf);
void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem);
void rtl8723a_fill_fake_txdesc(struct rtw_adapter *padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull);
diff --git a/drivers/staging/rtl8723au/include/rtw_ap.h b/drivers/staging/rtl8723au/include/rtw_ap.h
index 8d9be5a36eae..9f8d235c992f 100644
--- a/drivers/staging/rtl8723au/include/rtw_ap.h
+++ b/drivers/staging/rtl8723au/include/rtw_ap.h
@@ -32,7 +32,8 @@ void update_beacon23a(struct rtw_adapter *padapter, u8 ie_id, u8 *oui, u8 tx);
void add_RATid23a(struct rtw_adapter *padapter, struct sta_info *psta, u8 rssi_level);
void expire_timeout_chk23a(struct rtw_adapter *padapter);
void update_sta_info23a_apmode23a(struct rtw_adapter *padapter, struct sta_info *psta);
-int rtw_check_beacon_data23a(struct rtw_adapter *padapter, u8 *pbuf, unsigned int len);
+int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
+ struct ieee80211_mgmt *mgmt, unsigned int len);
void rtw_ap_restore_network(struct rtw_adapter *padapter);
void rtw_set_macaddr_acl23a(struct rtw_adapter *padapter, int mode);
int rtw_acl_add_sta23a(struct rtw_adapter *padapter, u8 *addr);
diff --git a/drivers/staging/rtl8723au/include/rtw_debug.h b/drivers/staging/rtl8723au/include/rtw_debug.h
index a69d6e215b8b..b6b01732a725 100644
--- a/drivers/staging/rtl8723au/include/rtw_debug.h
+++ b/drivers/staging/rtl8723au/include/rtw_debug.h
@@ -146,7 +146,7 @@
#define DBG_8723A_LEVEL(_level, fmt, arg...) \
do { \
if (_level <= GlobalDebugLevel23A) \
- pr_info(DRIVER_PREFIX"ERROR " fmt, ##arg);\
+ pr_info(DRIVER_PREFIX fmt, ##arg);\
} while (0)
#define DBG_8723A(...) \
diff --git a/drivers/staging/rtl8723au/include/rtw_event.h b/drivers/staging/rtl8723au/include/rtw_event.h
index 807cc83bc710..4557aeccc604 100644
--- a/drivers/staging/rtl8723au/include/rtw_event.h
+++ b/drivers/staging/rtl8723au/include/rtw_event.h
@@ -22,7 +22,7 @@
Used to report a bss has been scanned
*/
struct survey_event {
- struct wlan_bssid_ex bss;
+ struct wlan_bssid_ex *bss;
};
/*
diff --git a/drivers/staging/rtl8723au/include/rtw_ht.h b/drivers/staging/rtl8723au/include/rtw_ht.h
index 86ce86b6b69b..cfc947daf08b 100644
--- a/drivers/staging/rtl8723au/include/rtw_ht.h
+++ b/drivers/staging/rtl8723au/include/rtw_ht.h
@@ -21,8 +21,8 @@
struct ht_priv
{
- u32 ht_option;
- u32 ampdu_enable;/* for enable Tx A-MPDU */
+ bool ht_option;
+ bool ampdu_enable;/* for enable Tx A-MPDU */
/* u8 baddbareq_issued[16]; */
u32 tx_amsdu_enable;/* for enable Tx A-MSDU */
u32 tx_amdsu_maxlen; /* 1: 8k, 0:4k ; default:8k, for tx */
diff --git a/drivers/staging/rtl8723au/include/rtw_ioctl_set.h b/drivers/staging/rtl8723au/include/rtw_ioctl_set.h
deleted file mode 100644
index 040543bff1b2..000000000000
--- a/drivers/staging/rtl8723au/include/rtw_ioctl_set.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/******************************************************************************
- *
- * 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.
- *
- ******************************************************************************/
-#ifndef __RTW_IOCTL_SET_H_
-#define __RTW_IOCTL_SET_H_
-
-#include <drv_types.h>
-
-int rtw_set_802_11_authentication_mode23a(struct rtw_adapter *pdapter,
- enum ndis_802_11_auth_mode authmode);
-int rtw_set_802_11_bssid23a_list_scan(struct rtw_adapter *padapter,
- struct cfg80211_ssid *pssid,
- int ssid_max_num);
-int rtw_set_802_11_ssid23a(struct rtw_adapter * padapter,
- struct cfg80211_ssid * ssid);
-
-u16 rtw_get_cur_max_rate23a(struct rtw_adapter *adapter);
-s32 FillH2CCmd(struct rtw_adapter *padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
-int rtw_do_join23a(struct rtw_adapter *padapter);
-
-#endif
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme.h b/drivers/staging/rtl8723au/include/rtw_mlme.h
index 4d327ba775b0..2ff01eb8fc0c 100644
--- a/drivers/staging/rtl8723au/include/rtw_mlme.h
+++ b/drivers/staging/rtl8723au/include/rtw_mlme.h
@@ -163,24 +163,6 @@ struct mlme_priv {
u32 assoc_req_len;
u32 assoc_rsp_len;
u8 *assoc_rsp;
- u32 wps_assoc_resp_ie_len;
- u8 *wps_assoc_resp_ie;
- u8 *wps_probe_resp_ie;
- u32 wps_probe_resp_ie_len;
- u8 *wps_beacon_ie;
- u32 wps_beacon_ie_len;
- u32 p2p_go_probe_resp_ie_len; /* for GO */
- u32 p2p_assoc_req_ie_len;
- u8 *p2p_beacon_ie;
- u8 *p2p_probe_req_ie;
- u8 *p2p_probe_resp_ie;
- u8 *p2p_go_probe_resp_ie; /* for GO */
- u8 *p2p_assoc_req_ie;
- u32 p2p_beacon_ie_len;
- u32 p2p_probe_req_ie_len;
- u32 p2p_probe_resp_ie_len;
- u8 *wfd_assoc_req_ie;
- u32 wfd_assoc_req_ie_len;
#ifdef CONFIG_8723AU_AP_MODE
/* Number of associated Non-ERP stations (i.e., stations using 802.11b
@@ -213,16 +195,6 @@ struct mlme_priv {
u8 update_bcn;
#endif /* ifdef CONFIG_8723AU_AP_MODE */
-
- u8 *wfd_beacon_ie;
- u8 *wfd_probe_req_ie;
- u8 *wfd_probe_resp_ie;
- u8 *wfd_go_probe_resp_ie; /* for GO */
-
- u32 wfd_beacon_ie_len;
- u32 wfd_probe_req_ie_len;
- u32 wfd_probe_resp_ie_len;
- u32 wfd_go_probe_resp_ie_len; /* for GO */
};
void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf);
@@ -240,6 +212,9 @@ int rtw_init_mlme_priv23a(struct rtw_adapter *adapter);
void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv);
+int rtw_do_join_adhoc(struct rtw_adapter *adapter);
+int rtw_do_join_network(struct rtw_adapter *adapter,
+ struct wlan_network *candidate);
int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv);
int rtw_set_key23a(struct rtw_adapter *adapter,
struct security_priv *psecuritypriv, int keyid, u8 set_tx);
@@ -307,9 +282,6 @@ static inline void clr_fwstate_ex(struct mlme_priv *pmlmepriv, int state)
spin_unlock_bh(&pmlmepriv->lock);
}
-u16 rtw_get_capability23a(struct wlan_bssid_ex *bss);
-void rtw_update_scanned_network23a(struct rtw_adapter *adapter,
- struct wlan_bssid_ex *target);
void rtw_disconnect_hdl23a_under_linked(struct rtw_adapter *adapter,
struct sta_info *psta, u8 free_assoc);
void rtw_generate_random_ibss23a(u8 *pibss);
@@ -330,8 +302,6 @@ void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter);
void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter);
-void rtw_get_encrypt_decrypt_from_registrypriv23a(struct rtw_adapter *adapter);
-
void rtw_scan_timeout_handler23a(unsigned long data);
void rtw_dynamic_check_timer_handler(unsigned long data);
@@ -344,27 +314,23 @@ void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv);
void _rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv);
-struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, int gfp);
+struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp);
int rtw_if_up23a(struct rtw_adapter *padapter);
int rtw_linked_check(struct rtw_adapter *padapter);
-__le16 *rtw_get_capability23a_from_ie(u8 *ie);
-__le16 *rtw_get_beacon_interval23a_from_ie(u8 *ie);
-
-
void rtw_joinbss_reset23a(struct rtw_adapter *padapter);
-unsigned int rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
- u8 *out_ie, uint in_len, uint *pout_len);
+bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
+ u8 *out_ie, uint in_len, uint *pout_len);
void rtw_update_ht_cap23a(struct rtw_adapter *padapter,
u8 *pie, uint ie_len);
void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
struct xmit_frame *pxmitframe);
-int rtw_is_same_ibss23a(struct rtw_adapter *adapter,
- struct wlan_network *pnetwork);
+bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
+ struct wlan_network *pnetwork);
int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst);
void rtw23a_roaming(struct rtw_adapter *adapter,
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
index badbce09559d..2e32c832fd21 100644
--- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
@@ -282,16 +282,6 @@ struct ss_res
struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
};
-/* define AP_MODE 0x0C */
-/* define STATION_MODE 0x08 */
-/* define AD_HOC_MODE 0x04 */
-/* define NO_LINK_MODE 0x00 */
-
-#define WIFI_FW_NULL_STATE _HW_STATE_NOLINK_
-#define WIFI_FW_STATION_STATE _HW_STATE_STATION_
-#define WIFI_FW_AP_STATE _HW_STATE_AP_
-#define WIFI_FW_ADHOC_STATE _HW_STATE_ADHOC_
-
#define WIFI_FW_AUTH_NULL 0x00000100
#define WIFI_FW_AUTH_STATE 0x00000200
#define WIFI_FW_AUTH_SUCCESS 0x00000400
@@ -366,8 +356,8 @@ struct mlme_ext_info
struct ADDBA_request ADDBA_req;
struct WMM_para_element WMM_param;
- struct HT_caps_element HT_caps;
- struct HT_info_element HT_info;
+ struct ieee80211_ht_cap ht_cap;
+ struct ieee80211_ht_operation HT_info;
struct wlan_bssid_ex network;/* join network or bss_network, if in ap mode, it is the same to cur_network.network */
struct FW_Sta_Info FW_sta_info[NUM_STA];
};
@@ -471,8 +461,6 @@ void get_rate_set23a(struct rtw_adapter *padapter, unsigned char *pbssrate,
void UpdateBrateTbl23a(struct rtw_adapter *padapter,u8 *mBratesOS);
void Update23aTblForSoftAP(u8 *bssrateset, u32 bssratelen);
-void Set_MSR23a(struct rtw_adapter *padapter, u8 type);
-
u8 rtw_get_oper_ch23a(struct rtw_adapter *adapter);
void rtw_set_oper_ch23a(struct rtw_adapter *adapter, u8 ch);
u8 rtw_get_oper_bw23a(struct rtw_adapter *adapter);
@@ -495,14 +483,10 @@ void flush_all_cam_entry23a(struct rtw_adapter *padapter);
bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel);
-int collect_bss_info23a(struct rtw_adapter *padapter,
- struct recv_frame *precv_frame,
- struct wlan_bssid_ex *bssid);
void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
struct rtw_adapter *padapter, bool update_ie);
u8 *get_my_bssid23a(struct wlan_bssid_ex *pnetwork);
-u16 get_beacon_interval23a(struct wlan_bssid_ex *bss);
bool is_client_associated_to_ap23a(struct rtw_adapter *padapter);
bool is_client_associated_to_ibss23a(struct rtw_adapter *padapter);
@@ -510,18 +494,19 @@ bool is_IBSS_empty23a(struct rtw_adapter *padapter);
unsigned char check_assoc_AP23a(u8 *pframe, uint len);
-int WMM_param_handler23a(struct rtw_adapter *padapter, u8 *p);
+int WMM_param_handler23a(struct rtw_adapter *padapter, const u8 *p);
void WMMOnAssocRsp23a(struct rtw_adapter *padapter);
-void HT_caps_handler23a(struct rtw_adapter *padapter, u8 *p);
-void HT_info_handler23a(struct rtw_adapter *padapter, u8 *p);
+void HT_caps_handler23a(struct rtw_adapter *padapter, const u8 *p);
+void HT_info_handler23a(struct rtw_adapter *padapter, const u8 *p);
void HTOnAssocRsp23a(struct rtw_adapter *padapter);
-void ERP_IE_handler23a(struct rtw_adapter *padapter, u8 *p);
+void ERP_IE_handler23a(struct rtw_adapter *padapter, const u8 *p);
void VCS_update23a(struct rtw_adapter *padapter, struct sta_info *psta);
-void update_beacon23a_info(struct rtw_adapter *padapter, u8 *pframe, uint len,
- struct sta_info *psta);
+void update_beacon23a_info(struct rtw_adapter *padapter,
+ struct ieee80211_mgmt *mgmt, uint len,
+ struct sta_info *psta);
int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
struct ieee80211_mgmt *mgmt, u32 packet_len);
void update_IOT_info23a(struct rtw_adapter *padapter);
@@ -536,7 +521,7 @@ int update_sta_support_rate23a(struct rtw_adapter *padapter, u8* pvar_ie,
void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta);
unsigned int update_basic_rate23a(unsigned char *ptn, unsigned int ptn_sz);
unsigned int update_supported_rate23a(unsigned char *ptn, unsigned int ptn_sz);
-unsigned int update_MSC_rate23a(struct HT_caps_element *pHT_caps);
+unsigned int update_MSC_rate23a(struct ieee80211_ht_cap *ht_cap);
void Update_RA_Entry23a(struct rtw_adapter *padapter, struct sta_info *psta);
void set_sta_rate23a(struct rtw_adapter *padapter, struct sta_info *psta);
@@ -545,7 +530,7 @@ int receive_disconnect23a(struct rtw_adapter *padapter,
unsigned char get_highest_rate_idx23a(u32 mask);
int support_short_GI23a(struct rtw_adapter *padapter,
- struct HT_caps_element *pHT_caps);
+ struct ieee80211_ht_cap *ht_cap);
bool is_ap_in_tkip23a(struct rtw_adapter *padapter);
bool is_ap_in_wep23a(struct rtw_adapter *padapter);
bool should_forbid_n_rate23a(struct rtw_adapter *padapter);
diff --git a/drivers/staging/rtl8723au/include/rtw_pwrctrl.h b/drivers/staging/rtl8723au/include/rtw_pwrctrl.h
index a458af978145..599fed9b365d 100644
--- a/drivers/staging/rtl8723au/include/rtw_pwrctrl.h
+++ b/drivers/staging/rtl8723au/include/rtw_pwrctrl.h
@@ -155,18 +155,14 @@ struct pwrctrl_priv {
* read from HCPWM 2. driver lowers power level
*/
volatile u8 tog; /* toggling */
- volatile u8 cpwm_tog; /* toggling */
u8 pwr_mode;
u8 smart_ps;
u8 bcn_ant_mode;
- u32 alives;
- struct work_struct cpwm_event;
u8 bpower_saving;
u8 reg_rfoff;
- u8 reg_pdnmode; /* powerdown mode */
u32 rfoff_reason;
/* RF OFF Level */
@@ -188,8 +184,6 @@ struct pwrctrl_priv {
u8 bFwCurrentInPSMode;
unsigned long DelayLPSLastTimeStamp;
u8 btcoex_rfon;
- s32 pnp_current_pwr_state;
- u8 pnp_bstop_trx;
u8 bInSuspend;
#ifdef CONFIG_8723AU_BT_COEXIST
@@ -201,25 +195,13 @@ struct pwrctrl_priv {
int pwr_state_check_interval;
u8 pwr_state_check_cnts;
- int ps_flag;
-
enum rt_rf_power_state rf_pwrstate;/* cur power state */
enum rt_rf_power_state change_rfpwrstate;
- u8 wepkeymask;
- u8 bHWPowerdown;/* if support hw power down */
- u8 bHWPwrPindetect;
u8 bkeepfwalive;
- u8 brfoffbyhw;
unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT];
};
-#define rtw_get_ips_mode_req(pwrctrlpriv) \
- ((pwrctrlpriv)->ips_mode_req)
-
-#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \
- ((pwrctrlpriv)->ips_mode_req = (ips_mode))
-
#define RTW_PWR_STATE_CHK_INTERVAL 2000
#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \
@@ -253,8 +235,6 @@ int _rtw_pwr_wakeup23a(struct rtw_adapter *padapter, u32 ips_deffer_ms,
const char *caller);
#define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup23a(adapter, \
RTW_PWR_STATE_CHK_INTERVAL, __func__)
-#define rtw_pwr_wakeup_ex(adapter, ips_deffer_ms) \
- _rtw_pwr_wakeup23a(adapter, ips_deffer_ms, __func__)
int rtw_pm_set_ips23a(struct rtw_adapter *padapter, u8 mode);
int rtw_pm_set_lps23a(struct rtw_adapter *padapter, u8 mode);
diff --git a/drivers/staging/rtl8723au/include/rtw_rf.h b/drivers/staging/rtl8723au/include/rtw_rf.h
index 91a0a22a2709..a7de714137b8 100644
--- a/drivers/staging/rtl8723au/include/rtw_rf.h
+++ b/drivers/staging/rtl8723au/include/rtw_rf.h
@@ -89,17 +89,6 @@ enum ht_channel_width {
HT_CHANNEL_WIDTH_10 = 4,
};
-/* */
-/* Represent Extention Channel Offset in HT Capabilities */
-/* This is available only in 40Mhz mode. */
-/* */
-enum {
- HT_EXTCHNL_OFFSET_NO_EXT = 0,
- HT_EXTCHNL_OFFSET_UPPER = 1,
- HT_EXTCHNL_OFFSET_NO_DEF = 2,
- HT_EXTCHNL_OFFSET_LOWER = 3,
-};
-
/* 2007/11/15 MH Define different RF type. */
enum {
RF_1T2R = 0,
diff --git a/drivers/staging/rtl8723au/include/rtw_security.h b/drivers/staging/rtl8723au/include/rtw_security.h
index 8b8433365e32..624a9d788e45 100644
--- a/drivers/staging/rtl8723au/include/rtw_security.h
+++ b/drivers/staging/rtl8723au/include/rtw_security.h
@@ -23,8 +23,6 @@
#define is_wep_enc(alg) (alg == WLAN_CIPHER_SUITE_WEP40 || \
alg == WLAN_CIPHER_SUITE_WEP104)
-#define _WPA2_IE_ID_ 0x30
-
#define SHA256_MAC_LEN 32
#define AES_BLOCK_SIZE 16
#define AES_PRIV_SIZE (4 * 44)
@@ -145,7 +143,6 @@ struct security_priv {
u8 assoc_info[600];
u8 szofcapability[256]; /* for wpa2 usage */
u8 oidassociation[512]; /* for wpa/wpa2 usage */
- u8 authenticator_ie[256]; /* store ap security information element */
u8 supplicant_ie[256]; /* store sta security information element */
/* for tkip countermeasure */
diff --git a/drivers/staging/rtl8723au/include/rtw_sreset.h b/drivers/staging/rtl8723au/include/rtw_sreset.h
index 77cc7941b546..60fa8296e1ff 100644
--- a/drivers/staging/rtl8723au/include/rtw_sreset.h
+++ b/drivers/staging/rtl8723au/include/rtw_sreset.h
@@ -18,38 +18,18 @@
#include <osdep_service.h>
#include <drv_types.h>
-enum {
- SRESET_TGP_NULL = 0,
- SRESET_TGP_XMIT_STATUS = 1,
- SRESET_TGP_LINK_STATUS = 2,
-};
-
struct sreset_priv {
struct mutex silentreset_mutex;
u8 silent_reset_inprogress;
- u8 Wifi_Error_Status;
unsigned long last_tx_time;
unsigned long last_tx_complete_time;
-
- s32 dbg_trigger_point;
};
#include <rtl8723a_hal.h>
-#define WIFI_STATUS_SUCCESS 0
-#define USB_VEN_REQ_CMD_FAIL BIT(0)
-#define USB_READ_PORT_FAIL BIT(1)
-#define USB_WRITE_PORT_FAIL BIT(2)
-#define WIFI_MAC_TXDMA_ERROR BIT(3)
-#define WIFI_TX_HANG BIT(4)
-#define WIFI_RX_HANG BIT(5)
-#define WIFI_IF_NOT_EXIST BIT(6)
-
void rtw_sreset_init(struct rtw_adapter *padapter);
void rtw_sreset_reset_value(struct rtw_adapter *padapter);
-u8 rtw_sreset_get_wifi_status(struct rtw_adapter *padapter);
bool rtw_sreset_inprogress(struct rtw_adapter *padapter);
-void sreset_set_wifi_error_status23a(struct rtw_adapter *padapter, u32 status);
void sreset_set_trigger_point(struct rtw_adapter *padapter, s32 tgp);
void rtw_sreset_reset(struct rtw_adapter *active_adapter);
diff --git a/drivers/staging/rtl8723au/include/sta_info.h b/drivers/staging/rtl8723au/include/sta_info.h
index d1939a67390c..c756b4f7f5d5 100644
--- a/drivers/staging/rtl8723au/include/sta_info.h
+++ b/drivers/staging/rtl8723au/include/sta_info.h
@@ -362,7 +362,7 @@ static inline u32 wifi_mac_hash(const u8 *mac)
int _rtw_init_sta_priv23a(struct sta_priv *pstapriv);
int _rtw_free_sta_priv23a(struct sta_priv *pstapriv);
-struct sta_info *rtw_alloc_stainfo23a(struct sta_priv *pstapriv, u8 *hwaddr, gfp_t gfp);
+struct sta_info *rtw_alloc_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr, gfp_t gfp);
int rtw_free_stainfo23a(struct rtw_adapter *padapter, struct sta_info *psta);
void rtw_free_all_stainfo23a(struct rtw_adapter *padapter);
struct sta_info *rtw_get_stainfo23a(struct sta_priv *pstapriv, const u8 *hwaddr);
diff --git a/drivers/staging/rtl8723au/include/usb_ops_linux.h b/drivers/staging/rtl8723au/include/usb_ops_linux.h
index e540a4bad087..bf68bbb41f9c 100644
--- a/drivers/staging/rtl8723au/include/usb_ops_linux.h
+++ b/drivers/staging/rtl8723au/include/usb_ops_linux.h
@@ -29,13 +29,13 @@ int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
void rtl8723au_write_port_cancel(struct rtw_adapter *padapter);
int rtl8723au_read_interrupt(struct rtw_adapter *adapter, u32 addr);
-u8 rtl8723au_read8(struct rtw_adapter *padapter, u32 addr);
-u16 rtl8723au_read16(struct rtw_adapter *padapter, u32 addr);
-u32 rtl8723au_read32(struct rtw_adapter *padapter, u32 addr);
-int rtl8723au_write8(struct rtw_adapter *padapter, u32 addr, u8 val);
-int rtl8723au_write16(struct rtw_adapter *padapter, u32 addr, u16 val);
-int rtl8723au_write32(struct rtw_adapter *padapter, u32 addr, u32 val);
+u8 rtl8723au_read8(struct rtw_adapter *padapter, u16 addr);
+u16 rtl8723au_read16(struct rtw_adapter *padapter, u16 addr);
+u32 rtl8723au_read32(struct rtw_adapter *padapter, u16 addr);
+int rtl8723au_write8(struct rtw_adapter *padapter, u16 addr, u8 val);
+int rtl8723au_write16(struct rtw_adapter *padapter, u16 addr, u16 val);
+int rtl8723au_write32(struct rtw_adapter *padapter, u16 addr, u32 val);
int rtl8723au_writeN(struct rtw_adapter *padapter,
- u32 addr, u32 length, u8 *pdata);
+ u16 addr, u16 length, u8 *pdata);
#endif
diff --git a/drivers/staging/rtl8723au/include/wifi.h b/drivers/staging/rtl8723au/include/wifi.h
index cccea6a50b3a..fd3da3b5cf31 100644
--- a/drivers/staging/rtl8723au/include/wifi.h
+++ b/drivers/staging/rtl8723au/include/wifi.h
@@ -15,87 +15,16 @@
#ifndef _WIFI_H_
#define _WIFI_H_
-#define P80211CAPTURE_VERSION 0x80211001
-
/* This value is tested by WiFi 11n Test Plan 5.2.3.
* This test verifies the WLAN NIC can update the NAV through sending
* the CTS with large duration.
*/
#define WiFiNavUpperUs 30000 /* 30 ms */
-#define _ASOCREQ_IE_OFFSET_ 4 /* excluding wlan_hdr */
-#define _ASOCRSP_IE_OFFSET_ 6
-#define _REASOCREQ_IE_OFFSET_ 10
-#define _REASOCRSP_IE_OFFSET_ 6
-#define _PROBEREQ_IE_OFFSET_ 0
-#define _PROBERSP_IE_OFFSET_ 12
-#define _AUTH_IE_OFFSET_ 6
-#define _DEAUTH_IE_OFFSET_ 0
-#define _BEACON_IE_OFFSET_ 12
-#define _PUBLIC_ACTION_IE_OFFSET_ 8
-
-#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_
-
-
-#define EID_BSSIntolerantChlReport 73
-
-/* ---------------------------------------------------------------------------
- Below is the fixed elements...
------------------------------------------------------------------------------*/
-#define _AUTH_ALGM_NUM_ 2
-#define _AUTH_SEQ_NUM_ 2
-#define _BEACON_ITERVAL_ 2
-#define _CAPABILITY_ 2
-#define _CURRENT_APADDR_ 6
-#define _LISTEN_INTERVAL_ 2
-#define _ASOC_ID_ 2
-#define _STATUS_CODE_ 2
-#define _TIMESTAMP_ 8
-
-/*-----------------------------------------------------------------------------
- Below is the definition for WMM
-------------------------------------------------------------------------------*/
-#define _WMM_IE_Length_ 7 /* for WMM STA */
-#define _WMM_Para_Element_Length_ 24
-
-
/*-----------------------------------------------------------------------------
Below is the definition for 802.11n
------------------------------------------------------------------------------*/
-/* struct rtw_ieee80211_ht_cap - HT additional information
- *
- * This structure refers to "HT information element" as
- * described in 802.11n draft section 7.3.2.53
- */
-struct ieee80211_ht_addt_info {
- unsigned char control_chan;
- unsigned char ht_param;
- unsigned short operation_mode;
- unsigned short stbc_param;
- unsigned char basic_set[16];
-} __packed;
-
-struct HT_caps_element {
- union {
- struct {
- unsigned short HT_caps_info;
- unsigned char AMPDU_para;
- unsigned char MCS_rate[16];
- unsigned short HT_ext_caps;
- unsigned int Beamforming_caps;
- unsigned char ASEL_caps;
- } HT_cap_element;
- unsigned char HT_cap[26];
- } u;
-} __packed;
-
-struct HT_info_element {
- unsigned char primary_channel;
- unsigned char infos[5];
- unsigned char MCS_rate[16];
-} __packed;
-
struct AC_param {
unsigned char ACI_AIFSN;
unsigned char CW;
diff --git a/drivers/staging/rtl8723au/include/wlan_bssdef.h b/drivers/staging/rtl8723au/include/wlan_bssdef.h
index 664015d049e8..96e8074a7c18 100644
--- a/drivers/staging/rtl8723au/include/wlan_bssdef.h
+++ b/drivers/staging/rtl8723au/include/wlan_bssdef.h
@@ -83,8 +83,6 @@ struct wlan_bcn_info {
int is_8021x;
/* bwmode 20/40 and ch_offset UP/LOW */
- unsigned short ht_cap_info;
- unsigned char ht_info_infos_0;
};
struct wlan_bssid_ex {
@@ -94,7 +92,9 @@ struct wlan_bssid_ex {
struct cfg80211_ssid Ssid;
u32 Privacy;
long Rssi;/* in dBM, raw data , get from PHY) */
- u16 BeaconPeriod; /* units are Kusec */
+ u16 beacon_interval;
+ u16 capability;
+ u64 tsf;
u32 ATIMWindow; /* units are Kusec */
u32 DSConfig; /* Frequency, units are kHz */
enum nl80211_iftype ifmode;
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
index f0839f6a9345..93dc844a10b3 100644
--- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
@@ -16,7 +16,6 @@
#include <osdep_service.h>
#include <drv_types.h>
-#include <rtw_ioctl_set.h>
#include <xmit_osdep.h>
#include "ioctl_cfg80211.h"
@@ -26,8 +25,6 @@
#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 /* ms */
#define RTW_MAX_NUM_PMKIDS 4
-#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
-
static const u32 rtw_cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP40,
WLAN_CIPHER_SUITE_WEP104,
@@ -242,37 +239,21 @@ rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
};
-#define MAX_BSSINFO_LEN 1000
static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
struct wlan_network *pnetwork)
{
int ret = 0;
struct ieee80211_channel *notify_channel;
struct cfg80211_bss *bss;
- /* struct ieee80211_supported_band *band; */
u16 channel;
u32 freq;
- u64 notify_timestamp;
- u16 notify_capability;
- u16 notify_interval;
u8 *notify_ie;
size_t notify_ielen;
s32 notify_signal;
- u8 buf[MAX_BSSINFO_LEN], *pbuf;
- size_t len;
- struct ieee80211_hdr *pwlanhdr;
struct wireless_dev *wdev = padapter->rtw_wdev;
struct wiphy *wiphy = wdev->wiphy;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- /* DBG_8723A("%s\n", __func__); */
-
- if (pnetwork->network.IELength > MAX_IE_SZ) {
- DBG_8723A("%s IE Length too long > %d byte\n", __func__,
- MAX_IE_SZ);
- goto exit;
- }
-
channel = pnetwork->network.DSConfig;
if (channel <= RTW_CH_MAX_2G_CHANNEL)
freq = ieee80211_channel_to_frequency(channel,
@@ -283,17 +264,8 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
notify_channel = ieee80211_get_channel(wiphy, freq);
- notify_timestamp = jiffies_to_msecs(jiffies) * 1000; /* uSec */
-
- notify_interval =
- get_unaligned_le16(
- rtw_get_beacon_interval23a_from_ie(pnetwork->network.IEs));
- notify_capability =
- get_unaligned_le16(
- rtw_get_capability23a_from_ie(pnetwork->network.IEs));
-
- notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
- notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
+ notify_ie = pnetwork->network.IEs;
+ notify_ielen = pnetwork->network.IELength;
/* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM:
* signal strength in mBm (100*dBm)
@@ -305,35 +277,14 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
} else {
notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */
}
- pbuf = buf;
-
- pwlanhdr = (struct ieee80211_hdr *)pbuf;
-
- pwlanhdr->seq_ctrl = 0;
-
- if (pnetwork->network.reserved == 1) { /* WIFI_BEACON */
- eth_broadcast_addr(pwlanhdr->addr1);
- pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_BEACON);
- } else {
- ether_addr_copy(pwlanhdr->addr1, myid(&padapter->eeprompriv));
- pwlanhdr->frame_control =
- cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
- }
-
- ether_addr_copy(pwlanhdr->addr2, pnetwork->network.MacAddress);
- ether_addr_copy(pwlanhdr->addr3, pnetwork->network.MacAddress);
- pbuf += sizeof(struct ieee80211_hdr_3addr);
- len = sizeof(struct ieee80211_hdr_3addr);
-
- memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
- len += pnetwork->network.IELength;
-
- bss = cfg80211_inform_bss_frame(wiphy, notify_channel,
- (struct ieee80211_mgmt *)buf, len,
- notify_signal, GFP_ATOMIC);
+ bss = cfg80211_inform_bss(wiphy, notify_channel,
+ pnetwork->network.MacAddress,
+ pnetwork->network.tsf,
+ pnetwork->network.capability,
+ pnetwork->network.beacon_interval,
+ notify_ie, notify_ielen,
+ notify_signal, GFP_ATOMIC);
if (unlikely(!bss)) {
DBG_8723A("rtw_cfg80211_inform_bss error\n");
@@ -342,7 +293,6 @@ static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
cfg80211_put_bss(wiphy, bss);
-exit:
return ret;
}
@@ -467,10 +417,9 @@ exit:
return res;
}
-static int set_group_key(struct rtw_adapter *padapter, u8 *key, u32 alg,
- u8 keyid)
+static int set_group_key(struct rtw_adapter *padapter, struct key_params *parms,
+ u32 alg, u8 keyid)
{
- u8 keylen;
struct cmd_obj *pcmd;
struct setkey_parm *psetkeyparm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
@@ -503,20 +452,7 @@ static int set_group_key(struct rtw_adapter *padapter, u8 *key, u32 alg,
psetkeyparm->set_tx = 1;
- switch (alg) {
- case WLAN_CIPHER_SUITE_WEP40:
- keylen = 5;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- keylen = 13;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- case WLAN_CIPHER_SUITE_CCMP:
- default:
- keylen = 16;
- }
-
- memcpy(&psetkeyparm->key[0], key, keylen);
+ memcpy(&psetkeyparm->key, parms->key, parms->key_len);
pcmd->cmdcode = _SetKey_CMD_;
pcmd->parmbuf = (u8 *) psetkeyparm;
@@ -530,58 +466,21 @@ exit:
return res;
}
-static int set_wep_key(struct rtw_adapter *padapter, u8 *key, u16 keylen,
- u8 keyid)
-{
- u32 alg;
-
- switch (keylen) {
- case 5:
- alg = WLAN_CIPHER_SUITE_WEP40;
- break;
- case 13:
- alg = WLAN_CIPHER_SUITE_WEP104;
- break;
- default:
- alg = 0;
- }
-
- return set_group_key(padapter, key, alg, keyid);
-}
-
-static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
- struct ieee_param *param,
- u32 param_len)
+static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, u8 key_index,
+ int set_tx, const u8 *sta_addr,
+ struct key_params *keyparms)
{
int ret = 0;
- u16 wep_key_len;
- u8 wep_key_idx;
+ int key_len;
struct sta_info *psta = NULL, *pbcmc_sta = NULL;
struct rtw_adapter *padapter = netdev_priv(dev);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
struct sta_priv *pstapriv = &padapter->stapriv;
DBG_8723A("%s\n", __func__);
- param->u.crypt.err = 0;
- param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
- /* 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) {
- ret = -EINVAL;
- goto exit;
- }
-
- if (is_broadcast_ether_addr(param->sta_addr)) {
- if (param->u.crypt.idx >= WEP_KEYS) {
- ret = -EINVAL;
- goto exit;
- }
- } else {
- psta = rtw_get_stainfo23a(pstapriv, param->sta_addr);
+ if (!is_broadcast_ether_addr(sta_addr)) {
+ psta = rtw_get_stainfo23a(pstapriv, sta_addr);
if (!psta) {
/* ret = -EINVAL; */
DBG_8723A("rtw_set_encryption(), sta has already "
@@ -590,32 +489,14 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
}
}
- if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
- /* todo:clear default encryption keys */
-
- DBG_8723A("clear default encryption keys, keyid =%d\n",
- param->u.crypt.idx);
-
- goto exit;
- }
+ key_len = keyparms->key_len;
- if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
+ if (!psta && (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ keyparms->cipher == WLAN_CIPHER_SUITE_WEP104)) {
DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
- wep_key_idx = param->u.crypt.idx;
- wep_key_len = param->u.crypt.key_len;
-
DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n",
- wep_key_idx, wep_key_len);
-
- if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
- ret = -EINVAL;
- goto exit;
- }
-
- if (wep_key_len > 0) {
- wep_key_len = wep_key_len <= 5 ? 5 : 13;
- }
+ key_index, key_len);
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
/* wep default key has not been set, so use
@@ -623,100 +504,84 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
psecuritypriv->ndisencryptstatus =
Ndis802_11Encryption1Enabled;
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
+ psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher;
+ psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher;
- if (wep_key_len == 13) {
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
- }
-
- psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+ psecuritypriv->dot11PrivacyKeyIndex = key_index;
}
- memcpy(&psecuritypriv->wep_key[wep_key_idx].key,
- param->u.crypt.key, wep_key_len);
+ memcpy(&psecuritypriv->wep_key[key_index].key,
+ keyparms->key, key_len);
- psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len;
+ psecuritypriv->wep_key[key_index].keylen = key_len;
- set_wep_key(padapter, param->u.crypt.key, wep_key_len,
- wep_key_idx);
+ set_group_key(padapter, keyparms, keyparms->cipher, key_index);
goto exit;
-
}
- if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */
- if (param->u.crypt.set_tx == 0) { /* group key */
- if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ if (!psta) { /* group key */
+ if (set_tx == 0) { /* group key */
+ if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
DBG_8723A("%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 = WLAN_CIPHER_SUITE_WEP40;
- if (param->u.crypt.key_len == 13) {
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_WEP104;
- }
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key, key_len);
- } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+ psecuritypriv->dot118021XGrpPrivacy =
+ keyparms->cipher;
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
DBG_8723A("%s, set group_key, TKIP\n",
__func__);
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP;
+ psecuritypriv->dot118021XGrpPrivacy =
+ WLAN_CIPHER_SUITE_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));
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
- /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
/* set mic key */
memcpy(psecuritypriv->
- dot118021XGrptxmickey[param->u.crypt.
- idx].skey,
- &param->u.crypt.key[16], 8);
+ dot118021XGrptxmickey[key_index].skey,
+ &keyparms->key[16], 8);
memcpy(psecuritypriv->
- dot118021XGrprxmickey[param->u.crypt.
- idx].skey,
- &param->u.crypt.key[24], 8);
+ dot118021XGrprxmickey[key_index].skey,
+ &keyparms->key[24], 8);
psecuritypriv->busetkipkey = 1;
- } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
- DBG_8723A("%s, set group_key, CCMP\n",
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
+ DBG_8723A("%s, set group_key, CCMP\n",
__func__);
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP;
+ psecuritypriv->dot118021XGrpPrivacy =
+ WLAN_CIPHER_SUITE_CCMP;
memcpy(psecuritypriv->
- dot118021XGrpKey[param->u.crypt.idx].
- skey, param->u.crypt.key,
- (param->u.crypt.key_len >
- 16 ? 16 : param->u.crypt.key_len));
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
} else {
DBG_8723A("%s, set group_key, none\n",
__func__);
- psecuritypriv->dot118021XGrpPrivacy =
- 0;
+ psecuritypriv->dot118021XGrpPrivacy = 0;
}
- psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
+ psecuritypriv->dot118021XGrpKeyid = key_index;
psecuritypriv->binstallGrpkey = 1;
psecuritypriv->dot11PrivacyAlgrthm =
psecuritypriv->dot118021XGrpPrivacy;
- set_group_key(padapter, param->u.crypt.key,
+ set_group_key(padapter, keyparms,
psecuritypriv->dot118021XGrpPrivacy,
- param->u.crypt.idx);
+ key_index);
pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
if (pbcmc_sta) {
@@ -732,140 +597,110 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
goto exit;
}
- if (psecuritypriv->dot11AuthAlgrthm ==
- dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
- if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
- if (param->u.crypt.set_tx == 1) {
- /* pairwise key */
- memcpy(psta->dot118021x_UncstKey.skey,
- param->u.crypt.key,
- (param->u.crypt.key_len >
- 16 ? 16 : param->u.crypt.key_len));
+ if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) {
+ /* psk/802_1x */
+ if (set_tx == 1) {
+ /* pairwise key */
+ memcpy(psta->dot118021x_UncstKey.skey,
+ keyparms->key, (key_len > 16 ? 16 : key_len));
- if (!strcmp(param->u.crypt.alg, "WEP")) {
- DBG_8723A("%s, set pairwise key, WEP\n",
- __func__);
+ if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
+ DBG_8723A("%s, set pairwise key, WEP\n",
+ __func__);
- psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_WEP40;
- if (param->u.crypt.key_len == 13) {
- psta->dot118021XPrivacy =
- WLAN_CIPHER_SUITE_WEP104;
- }
- } else if (!strcmp(param->u.crypt.alg, "TKIP")) {
- DBG_8723A("%s, set pairwise key, "
- "TKIP\n", __func__);
+ psecuritypriv->dot118021XGrpPrivacy =
+ keyparms->cipher;
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ DBG_8723A("%s, set pairwise key, TKIP\n",
+ __func__);
- psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_TKIP;
+ psta->dot118021XPrivacy =
+ WLAN_CIPHER_SUITE_TKIP;
- /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
- /* set mic key */
- memcpy(psta->dot11tkiptxmickey.skey,
- &param->u.crypt.key[16], 8);
- memcpy(psta->dot11tkiprxmickey.skey,
- &param->u.crypt.key[24], 8);
+ /* set mic key */
+ memcpy(psta->dot11tkiptxmickey.skey,
+ &keyparms->key[16], 8);
+ memcpy(psta->dot11tkiprxmickey.skey,
+ &keyparms->key[24], 8);
- psecuritypriv->busetkipkey = 1;
+ psecuritypriv->busetkipkey = 1;
- } else if (!strcmp(param->u.crypt.alg, "CCMP")) {
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
+ DBG_8723A("%s, set pairwise key, CCMP\n",
+ __func__);
- DBG_8723A("%s, set pairwise key, "
- "CCMP\n", __func__);
+ psta->dot118021XPrivacy =
+ WLAN_CIPHER_SUITE_CCMP;
+ } else {
+ DBG_8723A("%s, set pairwise key, none\n",
+ __func__);
- psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_CCMP;
- } else {
- DBG_8723A("%s, set pairwise key, "
- "none\n", __func__);
+ psta->dot118021XPrivacy = 0;
+ }
- psta->dot118021XPrivacy = 0;
- }
+ set_pairwise_key(padapter, psta);
- set_pairwise_key(padapter, psta);
-
- psta->ieee8021x_blocked = false;
-
- psta->bpairwise_key_installed = true;
- } else { /* group key??? */
- if (!strcmp(param->u.crypt.alg, "WEP")) {
- 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 =
- WLAN_CIPHER_SUITE_WEP40;
- if (param->u.crypt.key_len == 13) {
- psecuritypriv->
- dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_WEP104;
- }
- } else if (!strcmp(param->u.crypt.alg, "TKIP")) {
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_TKIP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[param->u.crypt.
- idx].skey,
- param->u.crypt.key,
- (param->u.crypt.key_len >
- 16 ? 16 : param->u.crypt.
- key_len));
-
- /* DEBUG_ERR("set key length :param->u"
- ".crypt.key_len =%d\n",
- param->u.crypt.key_len); */
- /* set mic key */
- memcpy(psecuritypriv->
- dot118021XGrptxmickey[param->u.
- crypt.idx].
- skey, &param->u.crypt.key[16],
- 8);
- memcpy(psecuritypriv->
- dot118021XGrprxmickey[param->u.
- crypt.idx].
- skey, &param->u.crypt.key[24],
- 8);
-
- psecuritypriv->busetkipkey = 1;
-
- } else if (!strcmp(param->u.crypt.alg, "CCMP")) {
- psecuritypriv->dot118021XGrpPrivacy =
- WLAN_CIPHER_SUITE_CCMP;
-
- memcpy(psecuritypriv->
- dot118021XGrpKey[param->u.crypt.
- idx].skey,
- param->u.crypt.key,
- (param->u.crypt.key_len >
- 16 ? 16 : param->u.crypt.
- key_len));
- } else {
- psecuritypriv->dot118021XGrpPrivacy =
- 0;
- }
+ psta->ieee8021x_blocked = false;
- psecuritypriv->dot118021XGrpKeyid =
- param->u.crypt.idx;
+ psta->bpairwise_key_installed = true;
+ } else { /* group key??? */
+ if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
+ memcpy(psecuritypriv->
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key, key_len);
- psecuritypriv->binstallGrpkey = 1;
+ psecuritypriv->dot118021XGrpPrivacy =
+ keyparms->cipher;
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_TKIP) {
+ psecuritypriv->dot118021XGrpPrivacy =
+ WLAN_CIPHER_SUITE_TKIP;
- psecuritypriv->dot11PrivacyAlgrthm =
- psecuritypriv->dot118021XGrpPrivacy;
+ memcpy(psecuritypriv->
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
+
+ /* set mic key */
+ memcpy(psecuritypriv->
+ dot118021XGrptxmickey[key_index].skey,
+ &keyparms->key[16], 8);
+ memcpy(psecuritypriv->
+ dot118021XGrprxmickey[key_index].skey,
+ &keyparms->key[24], 8);
- set_group_key(padapter, param->u.crypt.key,
- psecuritypriv->
- dot118021XGrpPrivacy,
- param->u.crypt.idx);
+ psecuritypriv->busetkipkey = 1;
+ } else if (keyparms->cipher == WLAN_CIPHER_SUITE_CCMP) {
+ psecuritypriv->dot118021XGrpPrivacy =
+ WLAN_CIPHER_SUITE_CCMP;
- pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
- if (pbcmc_sta) {
- /* rx will use bmc_sta's
- dot118021XPrivacy */
- pbcmc_sta->ieee8021x_blocked = false;
- pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
- }
+ memcpy(psecuritypriv->
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
+ } else {
+ psecuritypriv->dot118021XGrpPrivacy = 0;
+ }
+
+ psecuritypriv->dot118021XGrpKeyid = key_index;
+
+ psecuritypriv->binstallGrpkey = 1;
+
+ psecuritypriv->dot11PrivacyAlgrthm =
+ psecuritypriv->dot118021XGrpPrivacy;
+
+ set_group_key(padapter, keyparms,
+ psecuritypriv->dot118021XGrpPrivacy,
+ key_index);
+
+ pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
+ if (pbcmc_sta) {
+ /* rx will use bmc_sta's
+ dot118021XPrivacy */
+ pbcmc_sta->ieee8021x_blocked = false;
+ pbcmc_sta->dot118021XPrivacy =
+ psecuritypriv->dot118021XGrpPrivacy;
}
}
}
@@ -873,80 +708,47 @@ static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
exit:
return ret;
-
}
#endif
-static int rtw_cfg80211_set_encryption(struct net_device *dev,
- struct ieee_param *param, u32 param_len)
+static int rtw_cfg80211_set_encryption(struct net_device *dev, u8 key_index,
+ int set_tx, const u8 *sta_addr,
+ struct key_params *keyparms)
{
int ret = 0;
- u32 wep_key_idx;
- u16 wep_key_len;
+ int key_len;
struct rtw_adapter *padapter = netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
DBG_8723A("%s\n", __func__);
- param->u.crypt.err = 0;
- param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
- if (param_len <
- (u32) ((u8 *) param->u.crypt.key - (u8 *) param) +
- param->u.crypt.key_len) {
- ret = -EINVAL;
- goto exit;
- }
-
- if (is_broadcast_ether_addr(param->sta_addr)) {
- if (param->u.crypt.idx >= WEP_KEYS) {
- ret = -EINVAL;
- goto exit;
- }
- } else {
- ret = -EINVAL;
- goto exit;
- }
+ key_len = keyparms->key_len;
- if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+ if (keyparms->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+ keyparms->cipher == WLAN_CIPHER_SUITE_WEP104) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
("wpa_set_encryption, crypt.alg = WEP\n"));
DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
- wep_key_idx = param->u.crypt.idx;
- wep_key_len = param->u.crypt.key_len;
-
- if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) {
- ret = -EINVAL;
- goto exit;
- }
-
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
/* wep default key has not been set, so use this
key index as default key. */
- wep_key_len = wep_key_len <= 5 ? 5 : 13;
-
psecuritypriv->ndisencryptstatus =
Ndis802_11Encryption1Enabled;
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
-
- if (wep_key_len == 13) {
- psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
- psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
- }
+ psecuritypriv->dot11PrivacyAlgrthm = keyparms->cipher;
+ psecuritypriv->dot118021XGrpPrivacy = keyparms->cipher;
- psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
+ psecuritypriv->dot11PrivacyKeyIndex = key_index;
}
- memcpy(&psecuritypriv->wep_key[wep_key_idx].key,
- param->u.crypt.key, wep_key_len);
+ memcpy(&psecuritypriv->wep_key[key_index].key,
+ keyparms->key, key_len);
- psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len;
+ psecuritypriv->wep_key[key_index].keylen = key_len;
- rtw_set_key23a(padapter, psecuritypriv, wep_key_idx, 0);
+ rtw_set_key23a(padapter, psecuritypriv, key_index, 0);
goto exit;
}
@@ -966,7 +768,8 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev,
} else {
/* Jeff: don't disable ieee8021x_blocked
while clearing key */
- if (strcmp(param->u.crypt.alg, "none") != 0)
+ if (keyparms->cipher != IW_AUTH_CIPHER_NONE &&
+ keyparms->cipher != 0)
psta->ieee8021x_blocked = false;
if ((padapter->securitypriv.ndisencryptstatus ==
@@ -978,27 +781,23 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev,
dot11PrivacyAlgrthm;
}
- if (param->u.crypt.set_tx == 1) {
+ if (set_tx == 1) {
/* pairwise key */
- DBG_8723A("%s, : param->u.crypt.set_tx"
- " == 1\n", __func__);
+ DBG_8723A("%s, : set_tx == 1\n",
+ __func__);
memcpy(psta->dot118021x_UncstKey.skey,
- param->u.crypt.key,
- (param->u.crypt.key_len >
- 16 ? 16 : param->u.crypt.
- key_len));
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
- if (strcmp(param->u.crypt.alg,
- "TKIP") == 0) {
+ if (keyparms->cipher ==
+ WLAN_CIPHER_SUITE_TKIP) {
memcpy(psta->dot11tkiptxmickey.
skey,
- &param->u.crypt.key[16],
- 8);
+ &keyparms->key[16], 8);
memcpy(psta->dot11tkiprxmickey.
skey,
- &param->u.crypt.key[24],
- 8);
+ &keyparms->key[24], 8);
padapter->securitypriv.
busetkipkey = 0;
@@ -1010,36 +809,26 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev,
true);
} else { /* group key */
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));
+ dot118021XGrpKey[key_index].skey,
+ keyparms->key,
+ (key_len > 16 ? 16 : key_len));
memcpy(padapter->securitypriv.
- dot118021XGrptxmickey[param->u.
- crypt.idx].
- skey, &param->u.crypt.key[16],
- 8);
+ dot118021XGrptxmickey[key_index].
+ skey, &keyparms->key[16], 8);
memcpy(padapter->securitypriv.
- dot118021XGrprxmickey[param->u.
- crypt.idx].
- skey, &param->u.crypt.key[24],
- 8);
+ dot118021XGrprxmickey[key_index].
+ skey, &keyparms->key[24], 8);
padapter->securitypriv.binstallGrpkey =
1;
- /* DEBUG_ERR((" param->u.crypt.key_len"
- "=%d\n", param->u.crypt.key_len)); */
DBG_8723A
(" ~~~~set sta key:groupkey\n");
padapter->securitypriv.
- dot118021XGrpKeyid =
- param->u.crypt.idx;
+ dot118021XGrpKeyid = key_index;
rtw_set_key23a(padapter,
&padapter->securitypriv,
- param->u.crypt.idx, 1);
+ key_index, 1);
}
}
@@ -1047,7 +836,8 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev,
if (pbcmc_sta) {
/* Jeff: don't disable ieee8021x_blocked
while clearing key */
- if (strcmp(param->u.crypt.alg, "none") != 0)
+ if (keyparms->cipher != IW_AUTH_CIPHER_NONE &&
+ keyparms->cipher != 0)
pbcmc_sta->ieee8021x_blocked = false;
if ((padapter->securitypriv.ndisencryptstatus ==
@@ -1076,13 +866,11 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_index, bool pairwise,
const u8 *mac_addr, struct key_params *params)
{
- char *alg_name;
- u32 param_len;
- struct ieee_param *param;
- int ret = 0;
+ int set_tx, ret = 0;
struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 sta_addr[ETH_ALEN];
DBG_8723A("%s(%s): adding key for %pM\n", __func__, ndev->name,
mac_addr);
@@ -1092,64 +880,48 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
DBG_8723A("key_index =%d\n", key_index);
DBG_8723A("pairwise =%d\n", pairwise);
- param_len = sizeof(struct ieee_param) + params->key_len;
- param = kzalloc(param_len, GFP_KERNEL);
- if (!param)
- return -ENOMEM;
-
- param->cmd = IEEE_CMD_SET_ENCRYPTION;
- eth_broadcast_addr(param->sta_addr);
-
switch (params->cipher) {
case IW_AUTH_CIPHER_NONE:
- /* todo: remove key */
- /* remove = 1; */
- alg_name = "none";
- break;
case WLAN_CIPHER_SUITE_WEP40:
+ if (params->key_len != WLAN_KEY_LEN_WEP40) {
+ ret = -EINVAL;
+ goto exit;
+ }
case WLAN_CIPHER_SUITE_WEP104:
- alg_name = "WEP";
- break;
+ if (params->key_len != WLAN_KEY_LEN_WEP104) {
+ ret = -EINVAL;
+ goto exit;
+ }
case WLAN_CIPHER_SUITE_TKIP:
- alg_name = "TKIP";
- break;
case WLAN_CIPHER_SUITE_CCMP:
- alg_name = "CCMP";
break;
-
default:
ret = -ENOTSUPP;
- goto addkey_end;
+ goto exit;
}
- strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
-
- if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
- param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
- } else {
- param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
+ if (key_index >= WEP_KEYS || params->key_len < 0) {
+ ret = -EINVAL;
+ goto exit;
}
- /* param->u.crypt.idx = key_index - 1; */
- param->u.crypt.idx = key_index;
-
- if (params->seq_len && params->seq) {
- memcpy(param->u.crypt.seq, params->seq, params->seq_len);
- }
+ eth_broadcast_addr(sta_addr);
- if (params->key_len && params->key) {
- param->u.crypt.key_len = params->key_len;
- memcpy(param->u.crypt.key, params->key, params->key_len);
- }
+ if (!mac_addr || is_broadcast_ether_addr(mac_addr))
+ set_tx = 0; /* for wpa/wpa2 group key */
+ else
+ set_tx = 1; /* for wpa/wpa2 pairwise key */
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
- ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
+ ret = rtw_cfg80211_set_encryption(ndev, key_index, set_tx,
+ sta_addr, params);
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
#ifdef CONFIG_8723AU_AP_MODE
if (mac_addr)
- ether_addr_copy(param->sta_addr, mac_addr);
+ ether_addr_copy(sta_addr, mac_addr);
- ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
+ ret = rtw_cfg80211_ap_set_encryption(ndev, key_index, set_tx,
+ sta_addr, params);
#endif
} else {
DBG_8723A("error! fw_state = 0x%x, iftype =%d\n",
@@ -1157,9 +929,7 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
}
-addkey_end:
- kfree(param);
-
+exit:
return ret;
}
@@ -1225,6 +995,63 @@ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
return 0;
}
+static u16 rtw_get_cur_max_rate(struct rtw_adapter *adapter)
+{
+ int i = 0;
+ const u8 *p;
+ u16 rate = 0, max_rate = 0;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct registry_priv *pregistrypriv = &adapter->registrypriv;
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
+ struct ieee80211_ht_cap *pht_capie;
+ u8 rf_type = 0;
+ u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
+ u16 mcs_rate = 0;
+
+ p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
+ pcur_bss->IEs, pcur_bss->IELength);
+ if (p && p[1] > 0) {
+ pht_capie = (struct ieee80211_ht_cap *)(p + 2);
+
+ memcpy(&mcs_rate, &pht_capie->mcs, 2);
+
+ /* bw_40MHz = (pht_capie->cap_info&
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1:0; */
+ /* cur_bwmod is updated by beacon, pmlmeinfo is
+ updated by association response */
+ bw_40MHz = (pmlmeext->cur_bwmode &&
+ (pmlmeinfo->HT_info.ht_param &
+ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) ? 1:0;
+
+ /* short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP
+ _SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1 : 0; */
+ short_GI_20 = (pmlmeinfo->ht_cap.cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_SGI_20)) ? 1:0;
+ short_GI_40 = (pmlmeinfo->ht_cap.cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) ? 1:0;
+
+ rf_type = rtl8723a_get_rf_type(adapter);
+ max_rate = rtw_mcs_rate23a(rf_type, bw_40MHz &
+ pregistrypriv->cbw40_enable,
+ short_GI_20, short_GI_40,
+ &pmlmeinfo->ht_cap.mcs);
+ } else {
+ while (pcur_bss->SupportedRates[i] != 0 &&
+ pcur_bss->SupportedRates[i] != 0xFF) {
+ rate = pcur_bss->SupportedRates[i] & 0x7F;
+ if (rate>max_rate)
+ max_rate = rate;
+ i++;
+ }
+
+ max_rate = max_rate * 10 / 2;
+ }
+
+ return max_rate;
+}
+
static int cfg80211_rtw_get_station(struct wiphy *wiphy,
struct net_device *ndev,
const u8 *mac, struct station_info *sinfo)
@@ -1269,7 +1096,7 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy,
signal_strength);
sinfo->filled |= STATION_INFO_TX_BITRATE;
- sinfo->txrate.legacy = rtw_get_cur_max_rate23a(padapter);
+ sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
sinfo->filled |= STATION_INFO_RX_PACKETS;
sinfo->rx_packets = sta_rx_data_pkts(psta);
@@ -1479,16 +1306,17 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
char *buf, int len)
{
int ret = 0;
- uint wps_ielen = 0;
- u8 *wps_ie;
+ const u8 *wps_ie;
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
DBG_8723A("%s, ielen =%d\n", __func__, len);
if (len > 0) {
- wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
+ wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ buf, len);
if (wps_ie) {
- DBG_8723A("probe_req_wps_ielen =%d\n", wps_ielen);
+ DBG_8723A("probe_req_wps_ielen =%d\n", wps_ie[1]);
if (pmlmepriv->wps_probe_req_ie) {
pmlmepriv->wps_probe_req_ie_len = 0;
@@ -1496,15 +1324,14 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
pmlmepriv->wps_probe_req_ie = NULL;
}
- pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie,
- wps_ielen,
+ pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ie[1],
GFP_KERNEL);
if (pmlmepriv->wps_probe_req_ie == NULL) {
DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
__func__, __LINE__);
return -EINVAL;
}
- pmlmepriv->wps_probe_req_ie_len = wps_ielen;
+ pmlmepriv->wps_probe_req_ie_len = wps_ie[1];
}
}
@@ -1751,7 +1578,7 @@ static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
size_t ielen)
{
- u8 *buf = NULL;
+ const u8 *wps_ie;
int group_cipher = 0, pairwise_cipher = 0;
int ret = 0;
const u8 *pwpa, *pwpa2;
@@ -1767,19 +1594,14 @@ static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
ret = -EINVAL;
goto exit;
}
- buf = kmemdup(pie, ielen, GFP_KERNEL);
- if (buf == NULL) {
- ret = -ENOMEM;
- goto exit;
- }
/* dump */
DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
for (i = 0; i < ielen; i = i + 8)
- DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
- buf[i], buf[i + 1],
- buf[i + 2], buf[i + 3], buf[i + 4],
- buf[i + 5], buf[i + 6], buf[i + 7]);
+ DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x "
+ "0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
+ pie[i], pie[i + 1], pie[i + 2], pie[i + 3],
+ pie[i + 4], pie[i + 5], pie[i + 6], pie[i + 7]);
if (ielen < RSN_HEADER_LEN) {
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
("Ie len too short %d\n", (int)ielen));
@@ -1789,7 +1611,7 @@ static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WPA,
- buf, ielen);
+ pie, ielen);
if (pwpa && pwpa[1] > 0) {
if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher,
&pairwise_cipher, NULL) == _SUCCESS) {
@@ -1804,7 +1626,7 @@ static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
}
}
- pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, buf, ielen);
+ pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, pie, ielen);
if (pwpa2 && pwpa2[1] > 0) {
if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher,
&pairwise_cipher, NULL) == _SUCCESS) {
@@ -1882,22 +1704,17 @@ static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
break;
}
- { /* handle wps_ie */
- uint wps_ielen;
- u8 *wps_ie;
-
- wps_ie = rtw_get_wps_ie23a(buf, ielen, NULL, &wps_ielen);
- if (wps_ie && wps_ielen > 0) {
- DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen);
- padapter->securitypriv.wps_ie_len =
- wps_ielen <
- MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
- memcpy(padapter->securitypriv.wps_ie, wps_ie,
- padapter->securitypriv.wps_ie_len);
- set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
- } else {
- _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
- }
+ wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ pie, ielen);
+ if (wps_ie && wps_ie[1] > 0) {
+ DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ie[1]);
+ padapter->securitypriv.wps_ie_len = wps_ie[1];
+ memcpy(padapter->securitypriv.wps_ie, wps_ie,
+ padapter->securitypriv.wps_ie_len);
+ set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
+ } else {
+ _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
}
/* TKIP and AES disallow multicast packets until installing group key */
@@ -1917,7 +1734,6 @@ static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
padapter->securitypriv.ndisauthtype));
exit:
- kfree(buf);
if (ret)
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
return ret;
@@ -1937,12 +1753,12 @@ static int rtw_cfg80211_add_wep(struct rtw_adapter *padapter,
}
switch (wep->keylen) {
- case 5:
+ case WLAN_KEY_LEN_WEP40:
psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
("%s:wep->KeyLength = 5\n", __func__));
break;
- case 13:
+ case WLAN_KEY_LEN_WEP104:
psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
("%s:wep->KeyLength = 13\n", __func__));
@@ -1987,18 +1803,162 @@ exit:
return res;
}
+static int rtw_set_ssid(struct rtw_adapter *padapter,
+ struct wlan_network *newnetwork)
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wlan_network *pnetwork = &pmlmepriv->cur_network;
+ int status = _SUCCESS;
+ u32 cur_time = 0;
+
+ DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
+ newnetwork->network.Ssid.ssid, get_fwstate(pmlmepriv));
+
+ if (padapter->hw_init_completed == false) {
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
+ ("set_ssid: hw_init_completed == false =>exit!!!\n"));
+ status = _FAIL;
+ goto exit;
+ }
+
+ spin_lock_bh(&pmlmepriv->lock);
+
+ DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
+ goto handle_tkip_countermeasure;
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+ ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
+
+ if (pmlmepriv->assoc_ssid.ssid_len ==
+ newnetwork->network.Ssid.ssid_len &&
+ !memcmp(&pmlmepriv->assoc_ssid.ssid,
+ newnetwork->network.Ssid.ssid,
+ newnetwork->network.Ssid.ssid_len)) {
+ if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
+ RT_TRACE(_module_rtl871x_ioctl_set_c_,
+ _drv_err_, ("New SSID is same SSID, "
+ "fw_state = 0x%08x\n",
+ get_fwstate(pmlmepriv)));
+
+ if (rtw_is_same_ibss23a(padapter, pnetwork)) {
+ /*
+ * it means driver is in
+ * WIFI_ADHOC_MASTER_STATE, we needn't
+ * create bss again.
+ */
+ goto release_mlme_lock;
+ }
+
+ /*
+ * if in WIFI_ADHOC_MASTER_STATE |
+ * WIFI_ADHOC_STATE, create bss or
+ * rejoin again
+ */
+ rtw_disassoc_cmd23a(padapter, 0, true);
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED))
+ rtw_indicate_disconnect23a(padapter);
+
+ rtw_free_assoc_resources23a(padapter, 1);
+
+ if (check_fwstate(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE)) {
+ _clr_fwstate_(pmlmepriv,
+ WIFI_ADHOC_MASTER_STATE);
+ set_fwstate(pmlmepriv,
+ WIFI_ADHOC_STATE);
+ }
+ } else {
+ rtw_lps_ctrl_wk_cmd23a(padapter,
+ LPS_CTRL_JOINBSS, 1);
+ }
+ } else {
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+ ("Set SSID not the same ssid\n"));
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+ ("set_ssid =[%s] len = 0x%x\n",
+ newnetwork->network.Ssid.ssid,
+ newnetwork->network.Ssid.ssid_len));
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
+ ("assoc_ssid =[%s] len = 0x%x\n",
+ pmlmepriv->assoc_ssid.ssid,
+ pmlmepriv->assoc_ssid.ssid_len));
+
+ rtw_disassoc_cmd23a(padapter, 0, true);
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED))
+ rtw_indicate_disconnect23a(padapter);
+
+ rtw_free_assoc_resources23a(padapter, 1);
+
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
+ _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
+ set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
+ }
+ }
+ }
+
+handle_tkip_countermeasure:
+
+ if (padapter->securitypriv.btkip_countermeasure == true) {
+ cur_time = jiffies;
+
+ if ((cur_time -
+ padapter->securitypriv.btkip_countermeasure_time) >
+ 60 * HZ) {
+ padapter->securitypriv.btkip_countermeasure = false;
+ padapter->securitypriv.btkip_countermeasure_time = 0;
+ } else {
+ status = _FAIL;
+ goto release_mlme_lock;
+ }
+ }
+
+ memcpy(&pmlmepriv->assoc_ssid, &newnetwork->network.Ssid,
+ sizeof(struct cfg80211_ssid));
+
+ pmlmepriv->assoc_by_bssid = false;
+
+ pmlmepriv->to_join = true;
+
+ if (!check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
+ pmlmepriv->cur_network.join_res = -2;
+
+ status = rtw_do_join_network(padapter, newnetwork);
+ if (status == _SUCCESS) {
+ pmlmepriv->to_join = false;
+ } else {
+ if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
+ /* switch to ADHOC_MASTER */
+ status = rtw_do_join_adhoc(padapter);
+ if (status != _SUCCESS)
+ goto release_mlme_lock;
+ } else {
+ /* can't associate ; reset under-linking */
+ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
+ status = _FAIL;
+ pmlmepriv->to_join = false;
+ }
+ }
+ }
+release_mlme_lock:
+ spin_unlock_bh(&pmlmepriv->lock);
+
+exit:
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
+ ("-%s: status =%d\n", __func__, status));
+
+ return status;
+}
+
static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
int ret = 0;
struct list_head *phead, *plist, *ptmp;
struct wlan_network *pnetwork = NULL;
- enum ndis_802_11_auth_mode authmode;
- struct cfg80211_ssid ndis_ssid;
- u8 *dst_ssid;
- u8 *src_ssid;
- u8 *dst_bssid;
- const u8 *src_bssid;
/* u8 matched_by_bssid = false; */
/* u8 matched_by_ssid = false; */
u8 matched = false;
@@ -2021,21 +1981,13 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
- if (!sme->ssid || !sme->ssid_len) {
+ if (!sme->ssid || !sme->ssid_len ||
+ sme->ssid_len > IEEE80211_MAX_SSID_LEN) {
ret = -EINVAL;
goto exit;
}
- if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
- ret = -E2BIG;
- goto exit;
- }
-
- memset(&ndis_ssid, 0, sizeof(struct cfg80211_ssid));
- ndis_ssid.ssid_len = sme->ssid_len;
- memcpy(ndis_ssid.ssid, sme->ssid, sme->ssid_len);
-
- DBG_8723A("ssid =%s, len =%zu\n", ndis_ssid.ssid, sme->ssid_len);
+ DBG_8723A("ssid =%s, len =%zu\n", sme->ssid, sme->ssid_len);
if (sme->bssid)
DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid));
@@ -2057,9 +2009,6 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
list_for_each_safe(plist, ptmp, phead) {
pnetwork = container_of(plist, struct wlan_network, list);
- dst_ssid = pnetwork->network.Ssid.ssid;
- dst_bssid = pnetwork->network.MacAddress;
-
if (sme->bssid) {
if (!ether_addr_equal(pnetwork->network.MacAddress,
sme->bssid))
@@ -2074,28 +2023,19 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
}
if (sme->bssid) {
- src_bssid = sme->bssid;
-
- if (ether_addr_equal(dst_bssid, src_bssid)) {
+ if (ether_addr_equal(pnetwork->network.MacAddress,
+ sme->bssid)) {
DBG_8723A("matched by bssid\n");
- ndis_ssid.ssid_len =
- pnetwork->network.Ssid.ssid_len;
- memcpy(ndis_ssid.ssid,
- pnetwork->network.Ssid.ssid,
- pnetwork->network.Ssid.ssid_len);
-
matched = true;
break;
}
-
} else if (sme->ssid && sme->ssid_len) {
- src_ssid = ndis_ssid.ssid;
-
- if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_len)) &&
- (pnetwork->network.Ssid.ssid_len ==
- ndis_ssid.ssid_len)) {
+ if (!memcmp(pnetwork->network.Ssid.ssid,
+ sme->ssid, sme->ssid_len) &&
+ pnetwork->network.Ssid.ssid_len == sme->ssid_len) {
DBG_8723A("matched by ssid\n");
+
matched = true;
break;
}
@@ -2104,7 +2044,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
spin_unlock_bh(&queue->lock);
- if (!matched || (pnetwork == NULL)) {
+ if (!matched || !pnetwork) {
ret = -ENOENT;
DBG_8723A("connect, matched == false, goto exit\n");
goto exit;
@@ -2122,9 +2062,8 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
- ret =
- rtw_cfg80211_set_wpa_version(psecuritypriv,
- sme->crypto.wpa_versions);
+ ret = rtw_cfg80211_set_wpa_version(psecuritypriv,
+ sme->crypto.wpa_versions);
if (ret < 0)
goto exit;
@@ -2195,7 +2134,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
ret = rtw_cfg80211_set_cipher(psecuritypriv,
sme->crypto.cipher_group, false);
if (ret < 0)
- return ret;
+ goto exit;
if (sme->crypto.n_akm_suites) {
ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
@@ -2204,14 +2143,19 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
- authmode = psecuritypriv->ndisauthtype;
- rtw_set_802_11_authentication_mode23a(padapter, authmode);
+ if (psecuritypriv->ndisauthtype > 3)
+ psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
+
+ if (rtw_set_auth23a(padapter, psecuritypriv) != _SUCCESS) {
+ ret = -EBUSY;
+ goto exit;
+ }
/* rtw_set_802_11_encryption_mode(padapter,
padapter->securitypriv.ndisencryptstatus); */
- if (rtw_set_802_11_ssid23a(padapter, &ndis_ssid) == false) {
- ret = -1;
+ if (rtw_set_ssid(padapter, pnetwork) != _SUCCESS) {
+ ret = -EBUSY;
goto exit;
}
@@ -2411,16 +2355,18 @@ void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
{
struct station_info sinfo;
u8 ie_offset;
+
if (ieee80211_is_assoc_req(hdr->frame_control))
- ie_offset = _ASOCREQ_IE_OFFSET_;
+ ie_offset = offsetof(struct ieee80211_mgmt,
+ u.assoc_req.variable);
else /* WIFI_REASSOCREQ */
- ie_offset = _REASOCREQ_IE_OFFSET_;
+ ie_offset = offsetof(struct ieee80211_mgmt,
+ u.reassoc_req.variable);
sinfo.filled = 0;
sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
- sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
- sinfo.assoc_req_ies_len =
- frame_len - WLAN_HDR_A3_LEN - ie_offset;
+ sinfo.assoc_req_ies = pmgmt_frame + ie_offset;
+ sinfo.assoc_req_ies_len = frame_len - ie_offset;
cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
}
#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
@@ -2443,17 +2389,15 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
{
s32 freq;
int channel;
- u8 *pmgmt_frame;
uint frame_len;
- struct ieee80211_hdr *pwlanhdr;
- u8 mgmt_buf[128];
+ struct ieee80211_mgmt mgmt;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
struct net_device *ndev = padapter->pnetdev;
DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
- memset(mgmt_buf, 0, 128);
+ memset(&mgmt, 0, sizeof(struct ieee80211_mgmt));
#if defined(RTW_USE_CFG80211_STA_EVENT)
cfg80211_del_sta(ndev, da, GFP_ATOMIC);
@@ -2466,29 +2410,21 @@ void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
freq = ieee80211_channel_to_frequency(channel,
IEEE80211_BAND_5GHZ);
- pmgmt_frame = mgmt_buf;
- pwlanhdr = (struct ieee80211_hdr *)pmgmt_frame;
-
- pwlanhdr->frame_control =
+ mgmt.frame_control =
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
- ether_addr_copy(pwlanhdr->addr1, myid(&padapter->eeprompriv));
- ether_addr_copy(pwlanhdr->addr2, da);
- ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
+ ether_addr_copy(mgmt.da, myid(&padapter->eeprompriv));
+ ether_addr_copy(mgmt.sa, da);
+ ether_addr_copy(mgmt.bssid, get_my_bssid23a(&pmlmeinfo->network));
- pwlanhdr->seq_ctrl =
- cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
+ mgmt.seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
pmlmeext->mgnt_seq++;
- pmgmt_frame += sizeof(struct ieee80211_hdr_3addr);
- frame_len = sizeof(struct ieee80211_hdr_3addr);
+ mgmt.u.disassoc.reason_code = cpu_to_le16(reason);
- reason = cpu_to_le16(reason);
- pmgmt_frame = rtw_set_fixed_ie23a(pmgmt_frame,
- WLAN_REASON_PREV_AUTH_NOT_VALID,
- (unsigned char *)&reason, &frame_len);
+ frame_len = sizeof(struct ieee80211_hdr_3addr) + 2;
- cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, mgmt_buf, frame_len,
+ cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len,
0, GFP_ATOMIC);
#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
}
@@ -2597,11 +2533,8 @@ static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
MAC_ARG(mgmt->da), __func__, ndev->name);
category = mgmt->u.action.category;
action = mgmt->u.action.u.wme_action.action_code;
- if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
- DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
- else
- DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category,
- action);
+ DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
+ category, action);
/* starting alloc mgmt frame to dump it */
pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
@@ -2801,9 +2734,12 @@ static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
size_t head_len, const u8 *tail, size_t tail_len)
{
int ret = 0;
- u8 *pbuf = NULL;
- uint len, wps_ielen = 0;
+ u8 *pbuf;
+ uint len, ielen, wps_ielen = 0;
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct wlan_bssid_ex *bss = &pmlmepriv->cur_network.network;
+ const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)head;
+ struct ieee80211_mgmt *tmpmgmt;
/* struct sta_priv *pstapriv = &padapter->stapriv; */
DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
@@ -2812,31 +2748,38 @@ static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
return -EINVAL;
- if (head_len < 24)
+ if (head_len < offsetof(struct ieee80211_mgmt, u.beacon.variable))
return -EINVAL;
pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
if (!pbuf)
return -ENOMEM;
- /* 24 = beacon header len. */
- memcpy(pbuf, (void *)head + 24, head_len - 24);
- memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
+ tmpmgmt = (struct ieee80211_mgmt *)pbuf;
+
+ bss->beacon_interval = get_unaligned_le16(&mgmt->u.beacon.beacon_int);
+ bss->capability = get_unaligned_le16(&mgmt->u.beacon.capab_info);
+ bss->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
- len = head_len + tail_len - 24;
+ /* 24 = beacon header len. */
+ memcpy(pbuf, (void *)head, head_len);
+ memcpy(pbuf + head_len, (void *)tail, tail_len);
+ len = head_len + tail_len;
+ ielen = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
/* check wps ie if inclued */
- if (rtw_get_wps_ie23a
- (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
- &wps_ielen))
+ if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPS,
+ tmpmgmt->u.beacon.variable, ielen))
DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
/* pbss_network->IEs will not include p2p_ie, wfd ie */
- rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
+ rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4);
- rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
+ rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4);
- if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) {
+ len = ielen + offsetof(struct ieee80211_mgmt, u.beacon.variable);
+ if (rtw_check_beacon_data23a(adapter, tmpmgmt, len) == _SUCCESS) {
ret = 0;
} else {
ret = -EINVAL;
@@ -3014,34 +2957,6 @@ static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
}
#endif /* CONFIG_8723AU_AP_MODE */
-void rtw_cfg80211_rx_action(struct rtw_adapter *adapter, u8 *frame,
- uint frame_len, const char *msg)
-{
- struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *)frame;
- s32 freq;
- int channel;
-
- channel = rtw_get_oper_ch23a(adapter);
-
- DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
- if (msg)
- DBG_8723A("RTW_Rx:%s\n", msg);
- else
- DBG_8723A("RTW_Rx:category(%u), action(%u)\n",
- hdr->u.action.category,
- hdr->u.action.u.wme_action.action_code);
-
- if (channel <= RTW_CH_MAX_2G_CHANNEL)
- freq = ieee80211_channel_to_frequency(channel,
- IEEE80211_BAND_2GHZ);
- else
- freq = ieee80211_channel_to_frequency(channel,
- IEEE80211_BAND_5GHZ);
-
- cfg80211_rx_mgmt(adapter->rtw_wdev, freq, 0, frame, frame_len,
- 0, GFP_ATOMIC);
-}
-
static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
const u8 *buf, size_t len)
{
@@ -3148,11 +3063,7 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
MAC_ARG(hdr->da));
category = hdr->u.action.category;
action = hdr->u.action.u.wme_action.action_code;
- if (category == WLAN_CATEGORY_PUBLIC)
- DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
- else
- DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
- category, action);
+ DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
do {
dump_cnt++;
diff --git a/drivers/staging/rtl8723au/os_dep/mlme_linux.c b/drivers/staging/rtl8723au/os_dep/mlme_linux.c
index ac618fb8b762..ca24369f1208 100644
--- a/drivers/staging/rtl8723au/os_dep/mlme_linux.c
+++ b/drivers/staging/rtl8723au/os_dep/mlme_linux.c
@@ -18,7 +18,6 @@
#include <osdep_service.h>
#include <drv_types.h>
#include <mlme_osdep.h>
-#include <rtw_ioctl_set.h>
static struct rt_pmkid_list backupPMKIDList[NUM_PMKID_CACHE];
diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c
index 1fb34386a4e5..b34eaec9dd48 100644
--- a/drivers/staging/rtl8723au/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c
@@ -425,7 +425,6 @@ static int rtw_init_default_value(struct rtw_adapter *padapter)
/* misc. */
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
- padapter->bNotifyChannelChange = 0;
return ret;
}
@@ -558,8 +557,6 @@ void rtw_cancel_all_timer23a(struct rtw_adapter *padapter)
("%s:cancel set_scan_deny_timer!\n", __func__));
del_timer_sync(&padapter->recvpriv.signal_stat_timer);
- /* cancel dm timer */
- rtl8723a_deinit_dm_priv(padapter);
}
int rtw_free_drv_sw23a(struct rtw_adapter *padapter)
@@ -584,11 +581,6 @@ int rtw_free_drv_sw23a(struct rtw_adapter *padapter)
kfree(padapter->HalData);
padapter->HalData = NULL;
- RT_TRACE(_module_os_intfs_c_, _drv_info_, ("<== rtw_free_drv_sw23a\n"));
-
- /* clear pbuddy_adapter to avoid access wrong pointer. */
- if (padapter->pbuddy_adapter != NULL)
- padapter->pbuddy_adapter->pbuddy_adapter = NULL;
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-rtw_free_drv_sw23a\n"));
return _SUCCESS;
}
@@ -668,17 +660,13 @@ int netdev_open23a(struct net_device *pnetdev)
mutex_lock(&adapter_to_dvobj(padapter)->hw_init_mutex);
pwrctrlpriv = &padapter->pwrctrlpriv;
- if (pwrctrlpriv->ps_flag) {
- padapter->net_closed = false;
- goto netdev_open23a_normal_process;
- }
if (!padapter->bup) {
padapter->bDriverStopped = false;
padapter->bSurpriseRemoved = false;
padapter->bCardDisableWOHSM = false;
- status = rtw_hal_init23a(padapter);
+ status = rtl8723au_hal_init(padapter);
if (status == _FAIL) {
RT_TRACE(_module_os_intfs_c_, _drv_err_,
("rtl871x_hal_init(): Can't init h/w!\n"));
@@ -716,7 +704,6 @@ int netdev_open23a(struct net_device *pnetdev)
else
netif_tx_wake_all_queues(pnetdev);
-netdev_open23a_normal_process:
RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-871x_drv - dev_open\n"));
DBG_8723A("-871x_drv - drv_open, bup =%d\n", padapter->bup);
exit:
@@ -748,7 +735,7 @@ static int ips_netdrv_open(struct rtw_adapter *padapter)
padapter->bSurpriseRemoved = false;
padapter->bCardDisableWOHSM = false;
- status = rtw_hal_init23a(padapter);
+ status = rtl8723au_hal_init(padapter);
if (status == _FAIL) {
RT_TRACE(_module_os_intfs_c_, _drv_err_,
("ips_netdrv_open(): Can't init h/w!\n"));
@@ -813,7 +800,7 @@ void rtw_ips_dev_unload23a(struct rtw_adapter *padapter)
/* s5. */
if (!padapter->bSurpriseRemoved)
- rtw_hal_deinit23a(padapter);
+ rtl8723au_hal_deinit(padapter);
}
int pm_netdev_open23a(struct net_device *pnetdev, u8 bnormal)
diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c
index 8b25c1aa2025..865743ecd855 100644
--- a/drivers/staging/rtl8723au/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c
@@ -59,79 +59,38 @@ static struct usb_driver rtl8723a_usb_drv = {
static struct usb_driver *usb_drv = &rtl8723a_usb_drv;
-static inline int RT_usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
-}
-
-static inline int RT_usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
-}
-
-static inline int RT_usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT;
-}
-
-static inline int RT_usb_endpoint_xfer_bulk(const struct usb_endpoint_descriptor *epd)
-{
- return (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK;
-}
-
static inline int RT_usb_endpoint_is_bulk_in(const struct usb_endpoint_descriptor *epd)
{
- return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_in(epd);
+ return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd);
}
static inline int RT_usb_endpoint_is_bulk_out(const struct usb_endpoint_descriptor *epd)
{
- return RT_usb_endpoint_xfer_bulk(epd) && RT_usb_endpoint_dir_out(epd);
+ return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd);
}
static inline int RT_usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
{
- return RT_usb_endpoint_xfer_int(epd) && RT_usb_endpoint_dir_in(epd);
-}
-
-static inline int RT_usb_endpoint_num(const struct usb_endpoint_descriptor *epd)
-{
- return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd);
}
static int rtw_init_intf_priv(struct dvobj_priv *dvobj)
{
- int rst = _SUCCESS;
-
mutex_init(&dvobj->usb_vendor_req_mutex);
- dvobj->usb_alloc_vendor_req_buf = kzalloc(MAX_USB_IO_CTL_SIZE,
- GFP_KERNEL);
- if (dvobj->usb_alloc_vendor_req_buf == NULL) {
- DBG_8723A("alloc usb_vendor_req_buf failed...\n");
- rst = _FAIL;
- goto exit;
- }
- dvobj->usb_vendor_req_buf =
- PTR_ALIGN(dvobj->usb_alloc_vendor_req_buf, ALIGNMENT_UNIT);
-exit:
- return rst;
+
+ return _SUCCESS;
}
static int rtw_deinit_intf_priv(struct dvobj_priv *dvobj)
{
- int rst = _SUCCESS;
-
- kfree(dvobj->usb_alloc_vendor_req_buf);
-
mutex_destroy(&dvobj->usb_vendor_req_mutex);
- return rst;
+ return _SUCCESS;
}
static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
{
struct dvobj_priv *pdvobjpriv;
- struct usb_device_descriptor *pdev_desc;
struct usb_host_config *phost_conf;
struct usb_config_descriptor *pconf_desc;
struct usb_host_interface *phost_iface;
@@ -159,8 +118,6 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
pdvobjpriv->RtNumInPipes = 0;
pdvobjpriv->RtNumOutPipes = 0;
- pdev_desc = &pusbd->descriptor;
-
phost_conf = pusbd->actconfig;
pconf_desc = &phost_conf->desc;
@@ -188,25 +145,25 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
if (RT_usb_endpoint_is_bulk_in(pendp_desc)) {
DBG_8723A("RT_usb_endpoint_is_bulk_in = %x\n",
- RT_usb_endpoint_num(pendp_desc));
+ usb_endpoint_num(pendp_desc));
pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
- RT_usb_endpoint_num(pendp_desc);
+ usb_endpoint_num(pendp_desc);
pdvobjpriv->RtNumInPipes++;
} else if (RT_usb_endpoint_is_int_in(pendp_desc)) {
DBG_8723A("RT_usb_endpoint_is_int_in = %x, Interval = %x\n",
- RT_usb_endpoint_num(pendp_desc),
+ usb_endpoint_num(pendp_desc),
pendp_desc->bInterval);
pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
- RT_usb_endpoint_num(pendp_desc);
+ usb_endpoint_num(pendp_desc);
pdvobjpriv->RtNumInPipes++;
} else if (RT_usb_endpoint_is_bulk_out(pendp_desc)) {
DBG_8723A("RT_usb_endpoint_is_bulk_out = %x\n",
- RT_usb_endpoint_num(pendp_desc));
+ usb_endpoint_num(pendp_desc));
pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
- RT_usb_endpoint_num(pendp_desc);
+ usb_endpoint_num(pendp_desc);
pdvobjpriv->RtNumOutPipes++;
}
- pdvobjpriv->ep_num[i] = RT_usb_endpoint_num(pendp_desc);
+ pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
}
}
DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n",
@@ -318,7 +275,7 @@ static void rtw_dev_unload(struct rtw_adapter *padapter)
/* s5. */
if (!padapter->bSurpriseRemoved) {
- rtw_hal_deinit23a(padapter);
+ rtl8723au_hal_deinit(padapter);
padapter->bSurpriseRemoved = true;
}
padapter->bup = false;
@@ -416,7 +373,6 @@ int rtw_hw_resume23a(struct rtw_adapter *padapter)
netif_tx_wake_all_queues(pnetdev);
pwrpriv->bkeepfwalive = false;
- pwrpriv->brfoffbyhw = false;
pwrpriv->rf_pwrstate = rf_on;
pwrpriv->bips_processing = false;
@@ -504,15 +460,6 @@ static int rtw_resume(struct usb_interface *pusb_intf)
{
struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
struct rtw_adapter *padapter = dvobj->if1;
- int ret;
-
- ret = rtw_resume_process23a(padapter);
-
- return ret;
-}
-
-int rtw_resume_process23a(struct rtw_adapter *padapter)
-{
struct net_device *pnetdev;
struct pwrctrl_priv *pwrpriv = NULL;
int ret = -1;
@@ -530,8 +477,10 @@ int rtw_resume_process23a(struct rtw_adapter *padapter)
pwrpriv->bkeepfwalive = false;
DBG_8723A("bkeepfwalive(%x)\n", pwrpriv->bkeepfwalive);
- if (pm_netdev_open23a(pnetdev, true) != 0)
+ if (pm_netdev_open23a(pnetdev, true) != 0) {
+ up(&pwrpriv->lock);
goto exit;
+ }
netif_device_attach(pnetdev);
netif_carrier_on(pnetdev);
@@ -572,7 +521,7 @@ static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
pnetdev = rtw_init_netdev23a(padapter);
if (!pnetdev)
- goto handle_dualmac;
+ goto free_adapter;
padapter = netdev_priv(pnetdev);
padapter->dvobj = dvobj;
@@ -583,13 +532,10 @@ static struct rtw_adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
rtl8723au_set_hw_type(padapter);
- if (rtw_handle_dualmac23a(padapter, 1) != _SUCCESS)
- goto free_adapter;
-
SET_NETDEV_DEV(pnetdev, dvobj_to_dev(dvobj));
if (rtw_wdev_alloc(padapter, dvobj_to_dev(dvobj)))
- goto handle_dualmac;
+ goto free_adapter;
/* step 2. allocate HalData */
padapter->HalData = kzalloc(sizeof(struct hal_data_8723a), GFP_KERNEL);
@@ -650,9 +596,6 @@ free_wdev:
rtw_wdev_unregister(padapter->rtw_wdev);
rtw_wdev_free(padapter->rtw_wdev);
}
-handle_dualmac:
- if (status != _SUCCESS)
- rtw_handle_dualmac23a(padapter, 0);
free_adapter:
if (status != _SUCCESS) {
if (pnetdev)
@@ -684,8 +627,6 @@ static void rtw_usb_if1_deinit(struct rtw_adapter *if1)
DBG_8723A("+r871xu_dev_remove, hw_init_completed =%d\n",
if1->hw_init_completed);
- rtw_handle_dualmac23a(if1, 0);
-
if (if1->rtw_wdev) {
rtw_wdev_unregister(if1->rtw_wdev);
rtw_wdev_free(if1->rtw_wdev);
diff --git a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c
index d081449318c2..a3349ac57bae 100644
--- a/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8723au/os_dep/usb_ops_linux.c
@@ -96,8 +96,6 @@ static void usb_write_port23a_complete(struct urb *purb)
DBG_8723A("###=> urb_write_port_complete status(%d)\n",
purb->status);
if (purb->status == -EPIPE || purb->status == -EPROTO) {
- sreset_set_wifi_error_status23a(padapter,
- USB_WRITE_PORT_FAIL);
} else if (purb->status == -EINPROGRESS) {
RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
("usb_write_port23a_complete: EINPROGESS\n"));
@@ -155,12 +153,10 @@ int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("+usb_write_port23a\n"));
- if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
- padapter->pwrctrlpriv.pnp_bstop_trx) {
+ if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
- ("usb_write_port23a:( padapter->bDriverStopped || "
- "padapter->bSurpriseRemoved || "
- "adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
+ ("%s:(padapter->bDriverStopped || "
+ "padapter->bSurpriseRemoved)!!!\n", __func__));
rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
goto exit;
}
diff --git a/drivers/staging/rtl8821ae/Kconfig b/drivers/staging/rtl8821ae/Kconfig
index abccc9dabd65..1a89b25647ed 100644
--- a/drivers/staging/rtl8821ae/Kconfig
+++ b/drivers/staging/rtl8821ae/Kconfig
@@ -6,6 +6,5 @@ config R8821AE
select WEXT_PRIV
select EEPROM_93CX6
select CRYPTO
- default N
---help---
If built as a module, it will be called r8821ae.ko.
diff --git a/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c
index 5a54bb10698c..cf8c38292cd8 100644
--- a/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c
+++ b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c
@@ -1670,7 +1670,7 @@ halbtc8812a1ant_TdmaDurationAdjustForAcl(
if (dn <= 0)
dn = 0;
- if(up >= n) // if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration
+ if(up >= n) // Google translated: if consecutive n-2 seconds retry count is 0, width-modulated WiFi duration
{
wait_count = 0;
n = 3;
@@ -1688,14 +1688,14 @@ halbtc8812a1ant_TdmaDurationAdjustForAcl(
if (up <= 0)
up = 0;
- if (dn == 2) // if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration
+ if (dn == 2) // Google translated: if 2 consecutive two seconds retry count <3, then tune narrow WiFi duration
{
if (wait_count <= 2)
- m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+ m++; // Google translated: Avoid been back and forth in the two level
else
m = 1;
- if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration.
+ if ( m >= 20) // Google translated: m max = 20 'Max 120 seconds recheck whether to adjust WiFi duration.
m = 20;
n = 3*m;
@@ -1706,14 +1706,14 @@ halbtc8812a1ant_TdmaDurationAdjustForAcl(
BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
}
}
- else //retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration
+ else // Google translated: retry count> 3, as long as a second retry count> 3, then tune narrow WiFi duration
{
if (wait_count == 1)
- m++; // ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^
+ m++; // Google translated: Avoid been back and forth in the two level
else
m = 1;
- if ( m >= 20) //m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration.
+ if ( m >= 20) // Google translated: m max = 20 'Max 120 seconds recheck whether to adjust WiFi duration.
m = 20;
n = 3*m;
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h
index 416d3ddaed33..f10bf1be69fe 100644
--- a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h
@@ -151,7 +151,7 @@ void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
- u8 *tmpBuf,u8 length);
+ u8 *tmpBuf, u8 length);
void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
u8 type);
void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist);
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h b/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h
index 787798e76217..fd233cc85a5b 100644
--- a/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h
@@ -88,7 +88,7 @@ extern u32 btc_dbg_type[];
#define CL_SPRINTF snprintf
-#define CL_PRINTF printk
+#define CL_PRINTF(buf) printk("%s", buf)
#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
do { \
diff --git a/drivers/staging/rtl8821ae/cam.c b/drivers/staging/rtl8821ae/cam.c
index 3bc6b3d06514..6185ea42deb1 100644
--- a/drivers/staging/rtl8821ae/cam.c
+++ b/drivers/staging/rtl8821ae/cam.c
@@ -152,7 +152,6 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
return 1;
}
-//EXPORT_SYMBOL(rtl_cam_add_one_entry);
int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
u8 *mac_addr, u32 ul_key_id)
@@ -176,7 +175,6 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
return 0;
}
-//EXPORT_SYMBOL(rtl_cam_delete_one_entry);
void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
{
@@ -186,7 +184,6 @@ void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
ul_command = BIT(31) | BIT(30);
rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
}
-//EXPORT_SYMBOL(rtl_cam_reset_all_entry);
void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
{
@@ -227,7 +224,6 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
RT_TRACE(COMP_SEC, DBG_DMESG,
("rtl_cam_mark_invalid(): WRITE A0: %x \n", ul_command));
}
-//EXPORT_SYMBOL(rtl_cam_mark_invalid);
void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
{
@@ -281,7 +277,6 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
}
}
-//EXPORT_SYMBOL(rtl_cam_empty_entry);
u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
{
@@ -316,7 +311,6 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
}
return TOTAL_CAM_ENTRY;
}
-//EXPORT_SYMBOL(rtl_cam_get_free_entry);
void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
{
@@ -349,4 +343,3 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
}
return;
}
-//EXPORT_SYMBOL(rtl_cam_del_entry);
diff --git a/drivers/staging/rtl8821ae/pci.c b/drivers/staging/rtl8821ae/pci.c
index e194ffe58acc..f9847d1fbdeb 100644
--- a/drivers/staging/rtl8821ae/pci.c
+++ b/drivers/staging/rtl8821ae/pci.c
@@ -861,7 +861,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
break;
}
- rtlpriv->cfg->ops->rx_command_packet_handler(hw, status, skb);
+ rtlpriv->cfg->ops->rx_command_packet_handler(hw, &status, skb);
/*
*NOTICE This can not be use for mac80211,
diff --git a/drivers/staging/rtl8821ae/ps.c b/drivers/staging/rtl8821ae/ps.c
index 5a9bbf025e25..db9a02fdb640 100644
--- a/drivers/staging/rtl8821ae/ps.c
+++ b/drivers/staging/rtl8821ae/ps.c
@@ -699,7 +699,8 @@ void rtl_swlps_wq_callback(void *data)
}
-void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, unsigned int len)
+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 = (void *)data;
@@ -799,7 +800,8 @@ void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, unsigned int len)
}
}
-void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, unsigned int len)
+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 = (void *)data;
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c b/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c
index 7b1d113505fb..f885ca77344b 100644
--- a/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c
+++ b/drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c
@@ -1706,20 +1706,6 @@ void rtl8821ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw)
rtlpcipriv->btcoexist.current_state &=~ BT_COEX_STATE_BT_INQ_PAGE;
}
}
-
-#if 0
- if (hal_coex_8821ae.b_c2h_bt_inquiry_page) {
- hal_coex_8821ae.b_c2h_bt_inquiry_page++;
- // bt inquiry or page is started.
- } if(hal_coex_8821ae.b_c2h_bt_inquiry_page) {
- rtlpcipriv->btcoexist.current_state |= BT_COEX_STATE_BT_INQ_PAGE;
- if(hal_coex_8821ae.bt_inquiry_page_cnt >= 4)
- hal_coex_8821ae.bt_inquiry_page_cnt = 0;
- hal_coex_8821ae.bt_inquiry_page_cnt++;
- } else {
- rtlpcipriv->btcoexist.current_state &=~ BT_COEX_STATE_BT_INQ_PAGE;
- }
-#endif
}
void rtl8821ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw)
@@ -2059,8 +2045,7 @@ void rtl_8821ae_c2h_command_handle(struct ieee80211_hw *hw)
break;
}
- if(ptmp_buf)
- kfree(ptmp_buf);
+ kfree(ptmp_buf);
rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE);
}
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/hw.c b/drivers/staging/rtl8821ae/rtl8821ae/hw.c
index 1b8583b689d4..1aa16612e248 100644
--- a/drivers/staging/rtl8821ae/rtl8821ae/hw.c
+++ b/drivers/staging/rtl8821ae/rtl8821ae/hw.c
@@ -1623,7 +1623,7 @@ static int _rtl8821ae_set_media_status(struct ieee80211_hw *hw,
rtl_write_byte(rtlpriv, (MSR), bt_msr);
rtlpriv->cfg->ops->led_control(hw, ledaction);
- if ((bt_msr & ~0xfc) == MSR_AP)
+ if ((bt_msr & MSR_MASK) == MSR_AP)
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
else
rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/reg.h b/drivers/staging/rtl8821ae/rtl8821ae/reg.h
index beffb4243b1e..4cb3ca95f773 100644
--- a/drivers/staging/rtl8821ae/rtl8821ae/reg.h
+++ b/drivers/staging/rtl8821ae/rtl8821ae/reg.h
@@ -431,6 +431,7 @@
#define MSR_ADHOC 0x01
#define MSR_INFRA 0x02
#define MSR_AP 0x03
+#define MSR_MASK 0x03
#define RRSR_RSC_OFFSET 21
#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/staging/rtl8821ae/rtl8821ae/sw.c b/drivers/staging/rtl8821ae/rtl8821ae/sw.c
index 26212755f88e..115002f98e2d 100644
--- a/drivers/staging/rtl8821ae/rtl8821ae/sw.c
+++ b/drivers/staging/rtl8821ae/rtl8821ae/sw.c
@@ -227,14 +227,14 @@ void rtl8821ae_deinit_sw_vars(struct ieee80211_hw *hw)
static u32 rtl8812ae_rx_command_packet_handler(
struct ieee80211_hw *hw,
- struct rtl_stats status,
+ const struct rtl_stats *status,
struct sk_buff *skb
)
{
u32 result = 0;
struct rtl_priv *rtlpriv = rtl_priv(hw);
- switch (status.packet_report_type) {
+ switch (status->packet_report_type) {
case NORMAL_RX:
result = 0;
break;
diff --git a/drivers/staging/rtl8821ae/wifi.h b/drivers/staging/rtl8821ae/wifi.h
index e8250dad613b..218cd44fbc64 100644
--- a/drivers/staging/rtl8821ae/wifi.h
+++ b/drivers/staging/rtl8821ae/wifi.h
@@ -1853,7 +1853,7 @@ struct rtl_hal_ops {
u32 cmd_len, u8 *p_cmdbuffer);
bool (*get_btc_status)(void);
u32 (*rx_command_packet_handler)(struct ieee80211_hw *hw,
- struct rtl_stats status,
+ const struct rtl_stats *status,
struct sk_buff *skb);
};
diff --git a/drivers/staging/rts5208/debug.h b/drivers/staging/rts5208/debug.h
deleted file mode 100644
index 5ba8a3a0fbdc..000000000000
--- a/drivers/staging/rts5208/debug.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Driver for Realtek PCI-Express card reader
- * Header file
- *
- * Copyright(c) 2009-2013 Realtek Semiconductor Corp. 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, 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/>.
- *
- * Author:
- * Wei WANG (wei_wang@realsil.com.cn)
- * Micky Ching (micky_ching@realsil.com.cn)
- */
-
-#ifndef __REALTEK_RTSX_DEBUG_H
-#define __REALTEK_RTSX_DEBUG_H
-
-#include <linux/kernel.h>
-
-#define RTSX_STOR "rts5208: "
-
-#ifdef CONFIG_RTS5208_DEBUG
-#define RTSX_DEBUGP(x...) pr_debug(RTSX_STOR x)
-#define RTSX_DEBUGPN(x...) pr_debug(x)
-#define RTSX_DEBUGPX(x...) printk(x)
-#define RTSX_DEBUG(x) x
-#else
-#define RTSX_DEBUGP(x...)
-#define RTSX_DEBUGPN(x...)
-#define RTSX_DEBUGPX(x...)
-#define RTSX_DEBUG(x)
-#endif
-
-#endif /* __REALTEK_RTSX_DEBUG_H */
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index d22916a4b9d8..390b1f83ebc2 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -57,7 +57,7 @@ static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode,
int retval;
u8 *ptr;
- RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc);
+ dev_dbg(rtsx_dev(chip), "%s: tpc = 0x%x\n", __func__, tpc);
rtsx_init_cmd(chip);
@@ -204,7 +204,7 @@ static int ms_write_bytes(struct rtsx_chip *chip,
u8 val = 0;
rtsx_read_register(chip, MS_TRANS_CFG, &val);
- RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val);
+ dev_dbg(rtsx_dev(chip), "MS_TRANS_CFG: 0x%02x\n", val);
rtsx_clear_ms_error(chip);
@@ -304,7 +304,7 @@ static int ms_read_bytes(struct rtsx_chip *chip,
data[i] = ptr[i];
if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) {
- RTSX_DEBUGP("Read format progress:\n");
+ dev_dbg(rtsx_dev(chip), "Read format progress:\n");
RTSX_DUMP(ptr, cnt);
}
@@ -507,8 +507,8 @@ static int ms_prepare_reset(struct rtsx_chip *chip)
oc_mask = SD_OC_NOW | SD_OC_EVER;
if (chip->ocp_stat & oc_mask) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
- chip->ocp_stat);
+ dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",
+ chip->ocp_stat);
TRACE_RET(chip, STATUS_FAIL);
}
#endif
@@ -557,7 +557,7 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
TRACE_RET(chip, STATUS_FAIL);
RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val);
- RTSX_DEBUGP("Type register: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "Type register: 0x%x\n", val);
if (val != 0x01) {
if (val != 0x02)
ms_card->check_ms_flow = 1;
@@ -566,14 +566,14 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
}
RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val);
- RTSX_DEBUGP("Category register: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "Category register: 0x%x\n", val);
if (val != 0) {
ms_card->check_ms_flow = 1;
TRACE_RET(chip, STATUS_FAIL);
}
RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val);
- RTSX_DEBUGP("Class register: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "Class register: 0x%x\n", val);
if (val == 0) {
RTSX_READ_REG(chip, PPBUF_BASE2, &val);
if (val & WRT_PRTCT)
@@ -591,7 +591,7 @@ static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus)
ms_card->ms_type |= TYPE_MSPRO;
RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val);
- RTSX_DEBUGP("IF Mode register: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "IF Mode register: 0x%x\n", val);
if (val == 0) {
ms_card->ms_type &= 0x0F;
} else if (val == 7) {
@@ -924,7 +924,7 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
((u32)buf[cur_addr_off + 5] << 16) |
((u32)buf[cur_addr_off + 6] << 8) |
buf[cur_addr_off + 7];
- RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "sys_info_addr = 0x%x, sys_info_size = 0x%x\n",
sys_info_addr, sys_info_size);
if (sys_info_size != 96) {
kfree(buf);
@@ -959,7 +959,7 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
((u32)buf[cur_addr_off + 5] << 16) |
((u32)buf[cur_addr_off + 6] << 8) |
buf[cur_addr_off + 7];
- RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "model_name_addr = 0x%x, model_name_size = 0x%x\n",
model_name_addr, model_name_size);
if (model_name_size != 48) {
kfree(buf);
@@ -1000,24 +1000,25 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
((u32)buf[sys_info_addr + 33] << 16) |
((u32)buf[sys_info_addr + 34] << 8) |
buf[sys_info_addr + 35];
- RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "xc_total_blk = 0x%x, xc_blk_size = 0x%x\n",
xc_total_blk, xc_blk_size);
} else {
total_blk = ((u16)buf[sys_info_addr + 6] << 8) |
buf[sys_info_addr + 7];
blk_size = ((u16)buf[sys_info_addr + 2] << 8) |
buf[sys_info_addr + 3];
- RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n",
total_blk, blk_size);
}
#else
total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7];
blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3];
- RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size);
+ dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n",
+ total_blk, blk_size);
#endif
- RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n",
- class_code, device_type, sub_class);
+ dev_dbg(rtsx_dev(chip), "class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n",
+ class_code, device_type, sub_class);
memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96);
#ifdef SUPPORT_PCGL_1P18
@@ -1051,7 +1052,7 @@ static int ms_read_attribute_info(struct rtsx_chip *chip)
if (sub_class & 0xC0)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n",
class_code, device_type, sub_class);
#ifdef SUPPORT_MSXC
@@ -1115,8 +1116,10 @@ Retry:
if (change_power_class && CHK_MSXC(ms_card)) {
u8 power_class_en = chip->ms_power_class_en;
- RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en);
- RTSX_DEBUGP("change_power_class = %d\n", change_power_class);
+ dev_dbg(rtsx_dev(chip), "power_class_en = 0x%x\n",
+ power_class_en);
+ dev_dbg(rtsx_dev(chip), "change_power_class = %d\n",
+ change_power_class);
if (change_power_class)
power_class_en &= (1 << (change_power_class - 1));
@@ -1126,7 +1129,7 @@ Retry:
if (power_class_en) {
u8 power_class_mode =
(ms_card->raw_sys_info[46] & 0x18) >> 3;
- RTSX_DEBUGP("power_class_mode = 0x%x",
+ dev_dbg(rtsx_dev(chip), "power_class_mode = 0x%x",
power_class_mode);
if (change_power_class > power_class_mode)
change_power_class = power_class_mode;
@@ -1559,9 +1562,10 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
int retval, rty_cnt, uncorrect_flag = 0;
u8 extra[MS_EXTRA_SIZE], val, i, j, data[16];
- RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Copy page from 0x%x to 0x%x, logical block is 0x%x\n",
old_blk, new_blk, log_blk);
- RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page);
+ dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d\n",
+ start_page, end_page);
retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE);
if (retval != STATUS_SUCCESS)
@@ -1638,7 +1642,7 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
retval = ms_read_status_reg(chip);
if (retval != STATUS_SUCCESS) {
uncorrect_flag = 1;
- RTSX_DEBUGP("Uncorrectable error\n");
+ dev_dbg(rtsx_dev(chip), "Uncorrectable error\n");
} else {
uncorrect_flag = 0;
}
@@ -1658,7 +1662,8 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
ms_write_extra_data(chip, old_blk, i,
extra, MS_EXTRA_SIZE);
- RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]);
+ dev_dbg(rtsx_dev(chip), "page %d : extra[0] = 0x%x\n",
+ i, extra[0]);
MS_SET_BAD_BLOCK_FLG(ms_card);
ms_set_page_status(log_blk, setPS_Error,
@@ -1853,7 +1858,7 @@ RE_SEARCH:
}
if (i == (MAX_DEFECTIVE_BLOCK + 2)) {
- RTSX_DEBUGP("No boot block found!");
+ dev_dbg(rtsx_dev(chip), "No boot block found!");
TRACE_RET(chip, STATUS_FAIL);
}
@@ -1907,7 +1912,7 @@ RE_SEARCH:
ptr = rtsx_get_cmd_data(chip);
- RTSX_DEBUGP("Boot block data:\n");
+ dev_dbg(rtsx_dev(chip), "Boot block data:\n");
RTSX_DUMP(ptr, 16);
/* Block ID error
@@ -2009,7 +2014,8 @@ static int ms_init_l2p_tbl(struct rtsx_chip *chip)
u8 val1, val2;
ms_card->segment_cnt = ms_card->total_block >> 9;
- RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt);
+ dev_dbg(rtsx_dev(chip), "ms_card->segment_cnt = %d\n",
+ ms_card->segment_cnt);
size = ms_card->segment_cnt * sizeof(struct zone_entry);
ms_card->segment = vzalloc(size);
@@ -2046,8 +2052,8 @@ static int ms_init_l2p_tbl(struct rtsx_chip *chip)
ms_card->segment[i].set_index = 0;
ms_card->segment[i].unused_blk_cnt = 0;
- RTSX_DEBUGP("defective block count of segment %d is %d\n",
- i, ms_card->segment[i].disable_count);
+ dev_dbg(rtsx_dev(chip), "defective block count of segment %d is %d\n",
+ i, ms_card->segment[i].disable_count);
}
return STATUS_SUCCESS;
@@ -2184,7 +2190,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
u16 start, end, phy_blk, log_blk, tmp_blk;
u8 extra[MS_EXTRA_SIZE], us1, us2;
- RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no);
+ dev_dbg(rtsx_dev(chip), "ms_build_l2p_tbl: %d\n", seg_no);
if (ms_card->segment == NULL) {
retval = ms_init_l2p_tbl(chip);
@@ -2193,7 +2199,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
}
if (ms_card->segment[seg_no].build_flag) {
- RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no);
+ dev_dbg(rtsx_dev(chip), "l2p table of segment %d has been built\n",
+ seg_no);
return STATUS_SUCCESS;
}
@@ -2244,7 +2251,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
retval = ms_read_extra_data(chip, phy_blk, 0,
extra, MS_EXTRA_SIZE);
if (retval != STATUS_SUCCESS) {
- RTSX_DEBUGP("read extra data fail\n");
+ dev_dbg(rtsx_dev(chip), "read extra data fail\n");
ms_set_bad_block(chip, phy_blk);
continue;
}
@@ -2311,7 +2318,8 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
segment->build_flag = 1;
- RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt);
+ dev_dbg(rtsx_dev(chip), "unused block count: %d\n",
+ segment->unused_blk_cnt);
/* Logical Address Confirmation Process */
if (seg_no == ms_card->segment_cnt - 1) {
@@ -2357,7 +2365,7 @@ static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no)
for (log_blk = 0; log_blk < 494; log_blk++) {
tmp_blk = segment->l2p_table[log_blk];
if (tmp_blk < ms_card->boot_block) {
- RTSX_DEBUGP("Boot block is not the first normal block.\n");
+ dev_dbg(rtsx_dev(chip), "Boot block is not the first normal block.\n");
if (chip->card_wp & MS_CARD)
break;
@@ -2435,7 +2443,7 @@ int reset_ms_card(struct rtsx_chip *chip)
TRACE_RET(chip, STATUS_FAIL);
}
- RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type);
+ dev_dbg(rtsx_dev(chip), "ms_card->ms_type = 0x%x\n", ms_card->ms_type);
return STATUS_SUCCESS;
}
@@ -2473,8 +2481,6 @@ void mspro_stop_seq_mode(struct rtsx_chip *chip)
struct ms_info *ms_card = &(chip->ms_card);
int retval;
- RTSX_DEBUGP("--%s--\n", __func__);
-
if (ms_card->seq_mode) {
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
@@ -2493,8 +2499,6 @@ static inline int ms_auto_tune_clock(struct rtsx_chip *chip)
struct ms_info *ms_card = &(chip->ms_card);
int retval;
- RTSX_DEBUGP("--%s--\n", __func__);
-
if (chip->asic_code) {
if (ms_card->ms_clock > 30)
ms_card->ms_clock -= 20;
@@ -2618,7 +2622,7 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) {
chip->rw_need_retry = 0;
- RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit mspro_rw_multi_sector\n");
TRACE_RET(chip, STATUS_FAIL);
}
@@ -2626,7 +2630,7 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb,
ms_send_cmd(chip, PRO_STOP, WAIT_INT);
if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) {
- RTSX_DEBUGP("MSPro CRC error, tune clock!\n");
+ dev_dbg(rtsx_dev(chip), "MSPro CRC error, tune clock!\n");
chip->rw_need_retry = 1;
ms_auto_tune_clock(chip);
}
@@ -2653,7 +2657,7 @@ static int mspro_read_format_progress(struct rtsx_chip *chip,
u8 cnt, tmp;
u8 data[8];
- RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n",
+ dev_dbg(rtsx_dev(chip), "mspro_read_format_progress, short_data_len = %d\n",
short_data_len);
retval = ms_switch_clock(chip);
@@ -2701,8 +2705,8 @@ static int mspro_read_format_progress(struct rtsx_chip *chip,
cur_progress = (data[4] << 24) | (data[5] << 16) |
(data[6] << 8) | data[7];
- RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n",
- total_progress, cur_progress);
+ dev_dbg(rtsx_dev(chip), "total_progress = %d, cur_progress = %d\n",
+ total_progress, cur_progress);
if (total_progress == 0) {
ms_card->progress = 0;
@@ -2711,7 +2715,7 @@ static int mspro_read_format_progress(struct rtsx_chip *chip,
do_div(ulltmp, total_progress);
ms_card->progress = (u16)ulltmp;
}
- RTSX_DEBUGP("progress = %d\n", ms_card->progress);
+ dev_dbg(rtsx_dev(chip), "progress = %d\n", ms_card->progress);
for (i = 0; i < 5000; i++) {
retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp);
@@ -2783,8 +2787,6 @@ int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip,
u8 buf[8], tmp;
u16 para;
- RTSX_DEBUGP("--%s--\n", __func__);
-
retval = ms_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
@@ -3405,7 +3407,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
}
}
- RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
seg_no, old_blk, new_blk);
while (total_sec_cnt) {
@@ -3416,8 +3418,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
page_cnt = end_page - start_page;
- RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n",
- start_page, end_page, page_cnt);
+ dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d, page_cnt = %d\n",
+ start_page, end_page, page_cnt);
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
retval = ms_read_multiple_pages(chip,
@@ -3492,7 +3494,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip,
}
}
- RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n",
seg_no, old_blk, new_blk);
start_page = 0;
@@ -3664,8 +3666,6 @@ static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type,
int retval;
u8 buf[6];
- RTSX_DEBUGP("--%s--\n", __func__);
-
if (type == 0)
retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1);
else
@@ -3697,8 +3697,6 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 buf1[32], buf2[12];
- RTSX_DEBUGP("--%s--\n", __func__);
-
if (scsi_bufflen(srb) < 12) {
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD);
TRACE_RET(chip, STATUS_FAIL);
@@ -3743,8 +3741,6 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 *buf = NULL;
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -3796,8 +3792,6 @@ int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 buf[32];
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -3872,8 +3866,6 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 buf1[32], buf2[36];
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -3929,8 +3921,6 @@ int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 buf[32];
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -3977,8 +3967,6 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 *buf = NULL;
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -4032,8 +4020,6 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip)
unsigned int lun = SCSI_LUN(srb);
u8 *buf = NULL;
- RTSX_DEBUGP("--%s--\n", __func__);
-
ms_cleanup_work(chip);
retval = ms_switch_clock(chip);
@@ -4133,7 +4119,7 @@ void ms_cleanup_work(struct rtsx_chip *chip)
if (CHK_MSPRO(ms_card)) {
if (ms_card->seq_mode) {
- RTSX_DEBUGP("MS Pro: stop transmission\n");
+ dev_dbg(rtsx_dev(chip), "MS Pro: stop transmission\n");
mspro_stop_seq_mode(chip);
ms_card->cleanup_counter = 0;
}
@@ -4144,7 +4130,7 @@ void ms_cleanup_work(struct rtsx_chip *chip)
}
#ifdef MS_DELAY_WRITE
else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) {
- RTSX_DEBUGP("MS: delay write\n");
+ dev_dbg(rtsx_dev(chip), "MS: delay write\n");
ms_delay_write(chip);
ms_card->cleanup_counter = 0;
}
@@ -4182,8 +4168,6 @@ int release_ms_card(struct rtsx_chip *chip)
struct ms_info *ms_card = &(chip->ms_card);
int retval;
- RTSX_DEBUGP("release_ms_card\n");
-
#ifdef MS_DELAY_WRITE
ms_card->delay_write.delay_write_flag = 0;
#endif
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
index c0a0e6010372..e7a6ba2002ae 100644
--- a/drivers/staging/rts5208/rtsx.c
+++ b/drivers/staging/rts5208/rtsx.c
@@ -20,8 +20,6 @@
* Micky Ching (micky_ching@realsil.com.cn)
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/blkdev.h>
#include <linux/kthread.h>
#include <linux/sched.h>
@@ -465,20 +463,20 @@ static int rtsx_control_thread(void *__dev)
else if (chip->srb->device->id) {
dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n",
chip->srb->device->id,
- chip->srb->device->lun);
+ (u8)chip->srb->device->lun);
chip->srb->result = DID_BAD_TARGET << 16;
}
else if (chip->srb->device->lun > chip->max_lun) {
dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n",
chip->srb->device->id,
- chip->srb->device->lun);
+ (u8)chip->srb->device->lun);
chip->srb->result = DID_BAD_TARGET << 16;
}
/* we've got a command, let's do it! */
else {
- RTSX_DEBUG(scsi_show_command(chip->srb));
+ scsi_show_command(chip);
rtsx_invoke_transport(chip->srb, chip);
}
@@ -864,7 +862,7 @@ static int rtsx_probe(struct pci_dev *pci,
int err = 0;
struct task_struct *th;
- RTSX_DEBUGP("Realtek PCI-E card reader detected\n");
+ dev_dbg(&pci->dev, "Realtek PCI-E card reader detected\n");
err = pci_enable_device(pci);
if (err < 0) {
diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h
index 37eab56ee02e..9e6ecb7457b5 100644
--- a/drivers/staging/rts5208/rtsx.h
+++ b/drivers/staging/rts5208/rtsx.h
@@ -46,7 +46,6 @@
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
-#include "debug.h"
#include "trace.h"
#include "general.h"
diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c
index 01aeb01bebe5..b4595ab3f02b 100644
--- a/drivers/staging/rts5208/rtsx_card.c
+++ b/drivers/staging/rts5208/rtsx_card.c
@@ -102,7 +102,8 @@ void try_to_switch_sdio_ctrl(struct rtsx_chip *chip)
rtsx_read_register(chip, 0xFF34, &reg1);
rtsx_read_register(chip, 0xFF38, &reg2);
- RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2);
+ dev_dbg(rtsx_dev(chip), "reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n",
+ reg1, reg2);
if ((reg1 & 0xC0) && (reg2 & 0xC0)) {
chip->sd_int = 1;
rtsx_write_register(chip, SDIO_CTRL, 0xFF,
@@ -137,14 +138,14 @@ void dynamic_configure_sdio_aspm(struct rtsx_chip *chip)
if (chip->sdio_idle) {
if (!chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO enter ASPM!\n");
+ dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n");
rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC,
0x30 | (chip->aspm_level[1] << 2));
chip->sdio_aspm = 1;
}
} else {
if (chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO exit ASPM!\n");
+ dev_dbg(rtsx_dev(chip), "SDIO exit ASPM!\n");
rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30);
chip->sdio_aspm = 0;
}
@@ -156,8 +157,8 @@ void do_reset_sd_card(struct rtsx_chip *chip)
{
int retval;
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->sd_reset_counter, chip->card2lun[SD_CARD]);
+ dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__,
+ chip->sd_reset_counter, chip->card2lun[SD_CARD]);
if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) {
clear_bit(SD_NR, &(chip->need_reset));
@@ -210,8 +211,8 @@ void do_reset_xd_card(struct rtsx_chip *chip)
{
int retval;
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->xd_reset_counter, chip->card2lun[XD_CARD]);
+ dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__,
+ chip->xd_reset_counter, chip->card2lun[XD_CARD]);
if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) {
clear_bit(XD_NR, &(chip->need_reset));
@@ -258,8 +259,8 @@ void do_reset_ms_card(struct rtsx_chip *chip)
{
int retval;
- RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
- chip->ms_reset_counter, chip->card2lun[MS_CARD]);
+ dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__,
+ chip->ms_reset_counter, chip->card2lun[MS_CARD]);
if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) {
clear_bit(MS_NR, &(chip->need_reset));
@@ -531,7 +532,7 @@ void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset,
void rtsx_init_cards(struct rtsx_chip *chip)
{
if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
- RTSX_DEBUGP("Reset chip in polling thread!\n");
+ dev_dbg(rtsx_dev(chip), "Reset chip in polling thread!\n");
rtsx_reset_chip(chip);
RTSX_CLR_DELINK(chip);
}
@@ -555,8 +556,8 @@ void rtsx_init_cards(struct rtsx_chip *chip)
if (!(chip->card_exist & MS_CARD))
clear_bit(MS_NR, &(chip->need_release));
- RTSX_DEBUGP("chip->need_release = 0x%x\n",
- (unsigned int)(chip->need_release));
+ dev_dbg(rtsx_dev(chip), "chip->need_release = 0x%x\n",
+ (unsigned int)(chip->need_release));
#ifdef SUPPORT_OCP
if (chip->need_release) {
@@ -612,22 +613,23 @@ void rtsx_init_cards(struct rtsx_chip *chip)
release_ms_card(chip);
}
- RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist);
+ dev_dbg(rtsx_dev(chip), "chip->card_exist = 0x%x\n",
+ chip->card_exist);
if (!chip->card_exist)
turn_off_led(chip, LED_GPIO);
}
if (chip->need_reset) {
- RTSX_DEBUGP("chip->need_reset = 0x%x\n",
- (unsigned int)(chip->need_reset));
+ dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x\n",
+ (unsigned int)(chip->need_reset));
rtsx_reset_cards(chip);
}
if (chip->need_reinit) {
- RTSX_DEBUGP("chip->need_reinit = 0x%x\n",
- (unsigned int)(chip->need_reinit));
+ dev_dbg(rtsx_dev(chip), "chip->need_reinit = 0x%x\n",
+ (unsigned int)(chip->need_reinit));
rtsx_reinit_cards(chip, 0);
}
@@ -652,8 +654,8 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
max_N = 120;
max_div = CLK_DIV_4;
- RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n",
- clk, chip->cur_clk);
+ dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n",
+ clk, chip->cur_clk);
if ((clk <= 2) || (N > max_N))
TRACE_RET(chip, STATUS_FAIL);
@@ -667,7 +669,7 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
N = (N + 2) * 2 - 2;
div++;
}
- RTSX_DEBUGP("N = %d, div = %d\n", N, div);
+ dev_dbg(rtsx_dev(chip), "N = %d, div = %d\n", N, div);
if (chip->ssc_en) {
ssc_depth = 0x01;
@@ -678,7 +680,7 @@ int switch_ssc_clock(struct rtsx_chip *chip, int clk)
ssc_depth_mask = 0x03;
- RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth);
+ dev_dbg(rtsx_dev(chip), "ssc_depth = %d\n", ssc_depth);
rtsx_init_cmd(chip);
rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
@@ -716,77 +718,78 @@ int switch_normal_clock(struct rtsx_chip *chip, int clk)
switch (clk) {
case CLK_20:
- RTSX_DEBUGP("Switch clock to 20MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 20MHz\n");
sel = SSC_80;
div = CLK_DIV_4;
mcu_cnt = 7;
break;
case CLK_30:
- RTSX_DEBUGP("Switch clock to 30MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 30MHz\n");
sel = SSC_120;
div = CLK_DIV_4;
mcu_cnt = 7;
break;
case CLK_40:
- RTSX_DEBUGP("Switch clock to 40MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 40MHz\n");
sel = SSC_80;
div = CLK_DIV_2;
mcu_cnt = 7;
break;
case CLK_50:
- RTSX_DEBUGP("Switch clock to 50MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 50MHz\n");
sel = SSC_100;
div = CLK_DIV_2;
mcu_cnt = 6;
break;
case CLK_60:
- RTSX_DEBUGP("Switch clock to 60MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 60MHz\n");
sel = SSC_120;
div = CLK_DIV_2;
mcu_cnt = 6;
break;
case CLK_80:
- RTSX_DEBUGP("Switch clock to 80MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 80MHz\n");
sel = SSC_80;
div = CLK_DIV_1;
mcu_cnt = 5;
break;
case CLK_100:
- RTSX_DEBUGP("Switch clock to 100MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 100MHz\n");
sel = SSC_100;
div = CLK_DIV_1;
mcu_cnt = 5;
break;
case CLK_120:
- RTSX_DEBUGP("Switch clock to 120MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 120MHz\n");
sel = SSC_120;
div = CLK_DIV_1;
mcu_cnt = 5;
break;
case CLK_150:
- RTSX_DEBUGP("Switch clock to 150MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 150MHz\n");
sel = SSC_150;
div = CLK_DIV_1;
mcu_cnt = 4;
break;
case CLK_200:
- RTSX_DEBUGP("Switch clock to 200MHz\n");
+ dev_dbg(rtsx_dev(chip), "Switch clock to 200MHz\n");
sel = SSC_200;
div = CLK_DIV_1;
mcu_cnt = 4;
break;
default:
- RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk);
+ dev_dbg(rtsx_dev(chip), "Try to switch to an illegal clock (%d)\n",
+ clk);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -946,7 +949,7 @@ int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
TRACE_RET(chip, STATUS_FAIL);
if (!chip->rw_need_retry) {
- RTSX_DEBUGP("RW fail, but no need to retry\n");
+ dev_dbg(rtsx_dev(chip), "RW fail, but no need to retry\n");
break;
}
} else {
@@ -954,7 +957,7 @@ int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
break;
}
- RTSX_DEBUGP("Retry RW, (i = %d)\n", i);
+ dev_dbg(rtsx_dev(chip), "Retry RW, (i = %d)\n", i);
}
return retval;
@@ -1063,7 +1066,7 @@ int detect_card_cd(struct rtsx_chip *chip, int card)
} else if (card == XD_CARD) {
card_cd = XD_EXIST;
} else {
- RTSX_DEBUGP("Wrong card type: 0x%x\n", card);
+ dev_dbg(rtsx_dev(chip), "Wrong card type: 0x%x\n", card);
TRACE_RET(chip, STATUS_FAIL);
}
diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h
index 4528b619f6b3..b19239e106f9 100644
--- a/drivers/staging/rts5208/rtsx_card.h
+++ b/drivers/staging/rts5208/rtsx_card.h
@@ -24,7 +24,6 @@
#ifndef __REALTEK_RTSX_CARD_H
#define __REALTEK_RTSX_CARD_H
-#include "debug.h"
#include "rtsx.h"
#include "rtsx_chip.h"
#include "rtsx_transport.h"
diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c
index 7907e931a355..fe98309b7de6 100644
--- a/drivers/staging/rts5208/rtsx_chip.c
+++ b/drivers/staging/rts5208/rtsx_chip.c
@@ -88,7 +88,8 @@ void rtsx_enable_bus_int(struct rtsx_chip *chip)
#ifndef DISABLE_CARD_INT
for (i = 0; i <= chip->max_lun; i++) {
- RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]);
+ dev_dbg(rtsx_dev(chip), "lun2card[%d] = 0x%02x\n",
+ i, chip->lun2card[i]);
if (chip->lun2card[i] & XD_CARD)
reg |= XD_INT_EN;
@@ -112,7 +113,7 @@ void rtsx_enable_bus_int(struct rtsx_chip *chip)
/* Enable Bus Interrupt */
rtsx_writel(chip, RTSX_BIER, reg);
- RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg);
+ dev_dbg(rtsx_dev(chip), "RTSX_BIER: 0x%08x\n", reg);
}
void rtsx_disable_bus_int(struct rtsx_chip *chip)
@@ -168,9 +169,12 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
if (chip->sdio_in_charge)
sw_bypass_sd = 1;
}
- RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge);
- RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load);
- RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd);
+ dev_dbg(rtsx_dev(chip), "chip->sdio_in_charge = %d\n",
+ chip->sdio_in_charge);
+ dev_dbg(rtsx_dev(chip), "chip->driver_first_load = %d\n",
+ chip->driver_first_load);
+ dev_dbg(rtsx_dev(chip), "sw_bypass_sd = %d\n",
+ sw_bypass_sd);
if (sw_bypass_sd) {
u8 cd_toggle_mask = 0;
@@ -189,7 +193,7 @@ static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip)
chip->need_reset |= SD_CARD;
} else {
- RTSX_DEBUGP("Chip inserted with SDIO!\n");
+ dev_dbg(rtsx_dev(chip), "Chip inserted with SDIO!\n");
if (chip->asic_code) {
retval = sd_pull_ctl_enable(chip);
@@ -418,7 +422,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
if (chip->hw_bypass_sd)
goto NextCard;
- RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "In %s, chip->int_reg = 0x%x\n", __func__,
chip->int_reg);
if (chip->int_reg & SD_EXIST) {
#ifdef HW_AUTO_SWITCH_SD_BUS
@@ -427,7 +431,7 @@ int rtsx_reset_chip(struct rtsx_chip *chip)
else
retval = rtsx_pre_handle_sdio_new(chip);
- RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n",
+ dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (rtsx_reset_chip)\n",
(unsigned int)(chip->need_reset));
#else /* HW_AUTO_SWITCH_SD_BUS */
retval = rtsx_pre_handle_sdio_old(chip);
@@ -449,7 +453,7 @@ NextCard:
if (chip->int_reg & CARD_EXIST)
RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB);
- RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "In %s, chip->need_reset = 0x%x\n", __func__,
(unsigned int)(chip->need_reset));
RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00);
@@ -543,7 +547,8 @@ static int rts5208_init(struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg);
+ dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n",
+ reg);
chip->ic_version = (reg >> 4) & 0x07;
if (reg & PHY_DEBUG_MODE)
chip->phy_debug_mode = 1;
@@ -557,7 +562,7 @@ static int rts5208_init(struct rtsx_chip *chip)
}
RTSX_READ_REG(chip, PDINFO, &val);
- RTSX_DEBUGP("PDINFO: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val);
if (val & AUX_PWR_DETECTED)
chip->aux_pwr_exist = 1;
else
@@ -603,14 +608,14 @@ static int rts5288_init(struct rtsx_chip *chip)
chip->phy_debug_mode = 0;
RTSX_READ_REG(chip, PDINFO, &val);
- RTSX_DEBUGP("PDINFO: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val);
if (val & AUX_PWR_DETECTED)
chip->aux_pwr_exist = 1;
else
chip->aux_pwr_exist = 0;
RTSX_READ_REG(chip, CARD_SHARE_MODE, &val);
- RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val);
if (val & 0x04)
chip->baro_pkg = QFN;
else
@@ -627,7 +632,7 @@ static int rts5288_init(struct rtsx_chip *chip)
TRACE_RET(chip, STATUS_FAIL);
max_func = (u8)((lval >> 29) & 0x07);
- RTSX_DEBUGP("Max function number: %d\n", max_func);
+ dev_dbg(rtsx_dev(chip), "Max function number: %d\n", max_func);
if (max_func == 0x02)
SET_SDIO_EXIST(chip);
else
@@ -658,8 +663,8 @@ int rtsx_init_chip(struct rtsx_chip *chip)
int retval;
unsigned int i;
- RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n",
- chip->vendor_id, chip->product_id);
+ dev_dbg(rtsx_dev(chip), "Vendor ID: 0x%04x, Product ID: 0x%04x\n",
+ chip->vendor_id, chip->product_id);
chip->ic_version = 0;
@@ -702,12 +707,14 @@ int rtsx_init_chip(struct rtsx_chip *chip)
if (!check_sd_speed_prior(chip->sd_speed_prior))
chip->sd_speed_prior = 0x01040203;
- RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior);
+ dev_dbg(rtsx_dev(chip), "sd_speed_prior = 0x%08x\n",
+ chip->sd_speed_prior);
if (!check_sd_current_prior(chip->sd_current_prior))
chip->sd_current_prior = 0x00010203;
- RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior);
+ dev_dbg(rtsx_dev(chip), "sd_current_prior = 0x%08x\n",
+ chip->sd_current_prior);
if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0))
chip->sd_ddr_tx_phase = 0;
@@ -718,7 +725,8 @@ int rtsx_init_chip(struct rtsx_chip *chip)
RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0);
wait_timeout(200);
RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07);
- RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting);
+ dev_dbg(rtsx_dev(chip), "chip->use_hw_setting = %d\n",
+ chip->use_hw_setting);
if (CHECK_PID(chip, 0x5208)) {
retval = rts5208_init(chip);
@@ -735,17 +743,23 @@ int rtsx_init_chip(struct rtsx_chip *chip)
if (chip->ss_en == 2)
chip->ss_en = 0;
- RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code);
- RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version);
- RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode);
- RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist);
- RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist);
- RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd);
- RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en);
- RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode);
- RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en);
- RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en);
- RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg);
+ dev_dbg(rtsx_dev(chip), "chip->asic_code = %d\n", chip->asic_code);
+ dev_dbg(rtsx_dev(chip), "chip->ic_version = 0x%x\n", chip->ic_version);
+ dev_dbg(rtsx_dev(chip), "chip->phy_debug_mode = %d\n",
+ chip->phy_debug_mode);
+ dev_dbg(rtsx_dev(chip), "chip->aux_pwr_exist = %d\n",
+ chip->aux_pwr_exist);
+ dev_dbg(rtsx_dev(chip), "chip->sdio_func_exist = %d\n",
+ chip->sdio_func_exist);
+ dev_dbg(rtsx_dev(chip), "chip->hw_bypass_sd = %d\n",
+ chip->hw_bypass_sd);
+ dev_dbg(rtsx_dev(chip), "chip->aspm_l0s_l1_en = %d\n",
+ chip->aspm_l0s_l1_en);
+ dev_dbg(rtsx_dev(chip), "chip->lun_mode = %d\n", chip->lun_mode);
+ dev_dbg(rtsx_dev(chip), "chip->auto_delink_en = %d\n",
+ chip->auto_delink_en);
+ dev_dbg(rtsx_dev(chip), "chip->ss_en = %d\n", chip->ss_en);
+ dev_dbg(rtsx_dev(chip), "chip->baro_pkg = %d\n", chip->baro_pkg);
if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
chip->card2lun[SD_CARD] = 0;
@@ -832,8 +846,8 @@ static void rtsx_monitor_aspm_config(struct rtsx_chip *chip)
if (maybe_support_aspm)
chip->aspm_l0s_l1_en = 0x03;
- RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n",
- chip->aspm_level[0], chip->aspm_level[1]);
+ dev_dbg(rtsx_dev(chip), "aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n",
+ chip->aspm_level[0], chip->aspm_level[1]);
if (chip->aspm_l0s_l1_en) {
chip->aspm_enabled = 1;
@@ -943,7 +957,7 @@ void rtsx_polling_func(struct rtsx_chip *chip)
dynamic_configure_sdio_aspm(chip);
} else {
if (!chip->sdio_aspm) {
- RTSX_DEBUGP("SDIO enter ASPM!\n");
+ dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n");
rtsx_write_register(chip,
ASPM_FORCE_CTL, 0xFC,
0x30 | (chip->aspm_level[1] << 2));
@@ -958,7 +972,7 @@ void rtsx_polling_func(struct rtsx_chip *chip)
chip->idle_counter++;
} else {
if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) {
- RTSX_DEBUGP("Idle state!\n");
+ dev_dbg(rtsx_dev(chip), "Idle state!\n");
rtsx_set_stat(chip, RTSX_STAT_IDLE);
#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK)
@@ -996,12 +1010,10 @@ void rtsx_polling_func(struct rtsx_chip *chip)
#ifdef SUPPORT_OCP
if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
-#ifdef CONFIG_RTS5208_DEBUG
if (chip->ocp_stat &
(SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER))
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",
chip->ocp_stat);
-#endif
if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
if (chip->card_exist & SD_CARD) {
@@ -1021,7 +1033,7 @@ void rtsx_polling_func(struct rtsx_chip *chip)
}
} else {
if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",
chip->ocp_stat);
if (chip->card_exist & SD_CARD) {
rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN,
@@ -1060,7 +1072,7 @@ Delink_Stage:
rtsx_set_phy_reg_bit(chip, 0x1C, 2);
if (chip->card_exist) {
- RTSX_DEBUGP("False card inserted, do force delink\n");
+ dev_dbg(rtsx_dev(chip), "False card inserted, do force delink\n");
if (enter_L1)
rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
@@ -1074,7 +1086,7 @@ Delink_Stage:
chip->auto_delink_cnt = delink_stage3_cnt + 1;
} else {
- RTSX_DEBUGP("No card inserted, do delink\n");
+ dev_dbg(rtsx_dev(chip), "No card inserted, do delink\n");
if (enter_L1)
rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1);
@@ -1088,7 +1100,7 @@ Delink_Stage:
}
if (chip->auto_delink_cnt == delink_stage2_cnt) {
- RTSX_DEBUGP("Try to do force delink\n");
+ dev_dbg(rtsx_dev(chip), "Try to do force delink\n");
if (enter_L1)
rtsx_exit_L1(chip);
@@ -1129,7 +1141,7 @@ void rtsx_stop_cmd(struct rtsx_chip *chip, int card)
int addr = RTSX_HCBAR + i * 4;
u32 reg;
reg = rtsx_readl(chip, addr);
- RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg);
+ dev_dbg(rtsx_dev(chip), "BAR (0x%02x): 0x%08x\n", addr, reg);
}
rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD);
rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA);
@@ -1138,7 +1150,7 @@ void rtsx_stop_cmd(struct rtsx_chip *chip, int card)
u16 addr = 0xFE20 + (u16)i;
u8 val;
rtsx_read_register(chip, addr, &val);
- RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val);
+ dev_dbg(rtsx_dev(chip), "0x%04X: 0x%02x\n", addr, val);
}
rtsx_write_register(chip, DMACTL, 0x80, 0x80);
@@ -1267,8 +1279,6 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
int dw_len, i, j;
int retval;
- RTSX_DEBUGP("%s\n", __func__);
-
if (!buf)
TRACE_RET(chip, STATUS_NOMEM);
@@ -1277,7 +1287,7 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
else
dw_len = (len + offset) / 4;
- RTSX_DEBUGP("dw_len = %d\n", dw_len);
+ dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len);
data = vzalloc(dw_len * 4);
if (!data)
@@ -1327,14 +1337,12 @@ int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf,
int dw_len, i, j;
int retval;
- RTSX_DEBUGP("%s\n", __func__);
-
if ((len + offset) % 4)
dw_len = (len + offset) / 4 + 1;
else
dw_len = (len + offset) / 4;
- RTSX_DEBUGP("dw_len = %d\n", dw_len);
+ dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len);
data = vmalloc(dw_len * 4);
if (!data)
@@ -1455,7 +1463,7 @@ int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val)
continue;
tmp &= (~(u8)(1 << i));
- RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr);
+ dev_dbg(rtsx_dev(chip), "Write 0x%x to 0x%x\n", tmp, addr);
RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp);
RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr);
@@ -1520,9 +1528,9 @@ int rtsx_check_link_ready(struct rtsx_chip *chip)
RTSX_READ_REG(chip, IRQSTAT0, &val);
- RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "IRQSTAT0: 0x%x\n", val);
if (val & LINK_RDY_INT) {
- RTSX_DEBUGP("Delinked!\n");
+ dev_dbg(rtsx_dev(chip), "Delinked!\n");
rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
return STATUS_FAIL;
}
@@ -1534,7 +1542,8 @@ static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate)
{
u32 ultmp;
- RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate);
+ dev_dbg(rtsx_dev(chip), "%04x set pm_dstate to %d\n",
+ chip->product_id, dstate);
if (CHK_SDIO_EXIST(chip)) {
u8 func_no;
@@ -1545,8 +1554,8 @@ static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate)
func_no = 1;
rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp);
- RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no,
- ultmp);
+ dev_dbg(rtsx_dev(chip), "pm_dstate of function %d: 0x%x\n",
+ (int)func_no, ultmp);
rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate);
}
@@ -1567,7 +1576,7 @@ void rtsx_exit_L1(struct rtsx_chip *chip)
void rtsx_enter_ss(struct rtsx_chip *chip)
{
- RTSX_DEBUGP("Enter Selective Suspend State!\n");
+ dev_dbg(rtsx_dev(chip), "Enter Selective Suspend State!\n");
rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT);
@@ -1604,7 +1613,7 @@ void rtsx_enter_ss(struct rtsx_chip *chip)
void rtsx_exit_ss(struct rtsx_chip *chip)
{
- RTSX_DEBUGP("Exit Selective Suspend State!\n");
+ dev_dbg(rtsx_dev(chip), "Exit Selective Suspend State!\n");
rtsx_exit_L1(chip);
@@ -1719,7 +1728,7 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat)
{
int retval;
- RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat);
+ dev_dbg(rtsx_dev(chip), "%s, pm_stat = %d\n", __func__, pm_stat);
rtsx_set_stat(chip, RTSX_STAT_SUSPEND);
@@ -1752,14 +1761,14 @@ void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat)
}
if (pm_stat == PM_S1) {
- RTSX_DEBUGP("Host enter S1\n");
+ dev_dbg(rtsx_dev(chip), "Host enter S1\n");
rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03,
HOST_ENTER_S1);
} else if (pm_stat == PM_S3) {
if (chip->s3_pwr_off_delay > 0)
wait_timeout(chip->s3_pwr_off_delay);
- RTSX_DEBUGP("Host enter S3\n");
+ dev_dbg(rtsx_dev(chip), "Host enter S3\n");
rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03,
HOST_ENTER_S3);
}
@@ -1778,7 +1787,7 @@ void rtsx_enable_aspm(struct rtsx_chip *chip)
{
if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
if (!chip->aspm_enabled) {
- RTSX_DEBUGP("Try to enable ASPM\n");
+ dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n");
chip->aspm_enabled = 1;
if (chip->asic_code && CHECK_PID(chip, 0x5208))
@@ -1813,7 +1822,7 @@ void rtsx_disable_aspm(struct rtsx_chip *chip)
if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) {
if (chip->aspm_enabled) {
- RTSX_DEBUGP("Try to disable ASPM\n");
+ dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n");
chip->aspm_enabled = 0;
if (chip->asic_code && CHECK_PID(chip, 0x5208))
diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h
index c25efcc3f3aa..feac98661cec 100644
--- a/drivers/staging/rts5208/rtsx_chip.h
+++ b/drivers/staging/rts5208/rtsx_chip.h
@@ -920,6 +920,11 @@ struct rtsx_chip {
u32 sd_ctl;
};
+static inline struct device *rtsx_dev(const struct rtsx_chip *chip)
+{
+ return &chip->rtsx->pci->dev;
+}
+
#define rtsx_set_stat(chip, stat) \
do { \
if ((stat) != RTSX_STAT_IDLE) { \
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
index bbfa665c5c99..5f5f512714e5 100644
--- a/drivers/staging/rts5208/rtsx_scsi.c
+++ b/drivers/staging/rts5208/rtsx_scsi.c
@@ -35,8 +35,9 @@
#include "ms.h"
#include "spi.h"
-void scsi_show_command(struct scsi_cmnd *srb)
+void scsi_show_command(struct rtsx_chip *chip)
{
+ struct scsi_cmnd *srb = chip->srb;
char *what = NULL;
int i, unknown_cmd = 0;
@@ -314,13 +315,13 @@ void scsi_show_command(struct scsi_cmnd *srb)
}
if (srb->cmnd[0] != TEST_UNIT_READY)
- RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
+ dev_dbg(rtsx_dev(chip), "Command %s (%d bytes)\n",
+ what, srb->cmd_len);
if (unknown_cmd) {
- RTSX_DEBUGP("");
for (i = 0; i < srb->cmd_len && i < 16; i++)
- RTSX_DEBUGPN(" %02x", srb->cmnd[i]);
- RTSX_DEBUGPN("\n");
+ dev_dbg(rtsx_dev(chip), " %02x", srb->cmnd[i]);
+ dev_dbg(rtsx_dev(chip), "\n");
}
}
@@ -883,14 +884,14 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip)
/* Accessing to any card is forbidden
* until the erase procedure of SD is completed
*/
- RTSX_DEBUGP("SD card being erased!\n");
+ dev_dbg(rtsx_dev(chip), "SD card being erased!\n");
set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN);
TRACE_RET(chip, TRANSPORT_FAILED);
}
if (get_lun_card(chip, lun) == SD_CARD) {
if (sd_card->sd_lock_status & SD_LOCKED) {
- RTSX_DEBUGP("SD card locked!\n");
+ dev_dbg(rtsx_dev(chip), "SD card locked!\n");
set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_READ_FORBIDDEN);
TRACE_RET(chip, TRANSPORT_FAILED);
@@ -935,7 +936,7 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip)
}
if (chip->rw_fail_cnt[lun] == 3) {
- RTSX_DEBUGP("read/write fail three times in succession\n");
+ dev_dbg(rtsx_dev(chip), "read/write fail three times in succession\n");
if (srb->sc_data_direction == DMA_FROM_DEVICE)
set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR);
@@ -947,7 +948,7 @@ static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip)
if (srb->sc_data_direction == DMA_TO_DEVICE) {
if (check_card_wp(chip, lun)) {
- RTSX_DEBUGP("Write protected card!\n");
+ dev_dbg(rtsx_dev(chip), "Write protected card!\n");
set_sense_type(chip, lun,
SENSE_TYPE_MEDIA_WRITE_PROTECT);
TRACE_RET(chip, TRANSPORT_FAILED);
@@ -1380,7 +1381,7 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip)
*(ptr++) = (u8)(msg_cnt >> 16);
*(ptr++) = (u8)(msg_cnt >> 8);
*(ptr++) = (u8)msg_cnt;
- RTSX_DEBUGP("Trace message count is %d\n", msg_cnt);
+ dev_dbg(rtsx_dev(chip), "Trace message count is %d\n", msg_cnt);
for (i = 1; i <= msg_cnt; i++) {
int j, idx;
@@ -1432,7 +1433,7 @@ static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip)
addr = srb->cmnd[4];
val = rtsx_readl(chip, addr);
- RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val);
+ dev_dbg(rtsx_dev(chip), "Host register (0x%x): 0x%x\n", addr, val);
buf[0] = (u8)(val >> 24);
buf[1] = (u8)(val >> 16);
@@ -1595,9 +1596,9 @@ static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip)
len = min_t(u16, len, scsi_bufflen(srb));
if (srb->sc_data_direction == DMA_FROM_DEVICE)
- RTSX_DEBUGP("Read from device\n");
+ dev_dbg(rtsx_dev(chip), "Read from device\n");
else
- RTSX_DEBUGP("Write to device\n");
+ dev_dbg(rtsx_dev(chip), "Write to device\n");
retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len,
scsi_sg_count(srb), srb->sc_data_direction, 1000);
@@ -1731,7 +1732,7 @@ static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
status[0x17] = 0x00;
}
- RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]);
+ dev_dbg(rtsx_dev(chip), "status[0x17] = 0x%x\n", status[0x17]);
#endif
status[0x18] = 0x8A;
@@ -2312,8 +2313,8 @@ static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
- RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func,
- addr, len);
+ dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x, len = %d\n",
+ __func__, func, addr, len);
if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
func_max = 1;
@@ -2366,7 +2367,8 @@ static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip)
addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7];
- RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr);
+ dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x\n",
+ __func__, func, addr);
if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip))
func_max = 1;
@@ -3030,8 +3032,6 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
int retval;
u8 key_format;
- RTSX_DEBUGP("--%s--\n", __func__);
-
rtsx_disable_aspm(chip);
if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
@@ -3062,7 +3062,7 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
}
key_format = srb->cmnd[10] & 0x3F;
- RTSX_DEBUGP("key_format = 0x%x\n", key_format);
+ dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format);
switch (key_format) {
case KF_GET_LOC_EKB:
@@ -3131,8 +3131,6 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
int retval;
u8 key_format;
- RTSX_DEBUGP("--%s--\n", __func__);
-
rtsx_disable_aspm(chip);
if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) {
@@ -3167,7 +3165,7 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip)
}
key_format = srb->cmnd[10] & 0x3F;
- RTSX_DEBUGP("key_format = 0x%x\n", key_format);
+ dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format);
switch (key_format) {
case KF_SET_LEAF_ID:
diff --git a/drivers/staging/rts5208/rtsx_scsi.h b/drivers/staging/rts5208/rtsx_scsi.h
index d1750570dd38..03dd76d6c859 100644
--- a/drivers/staging/rts5208/rtsx_scsi.h
+++ b/drivers/staging/rts5208/rtsx_scsi.h
@@ -133,7 +133,7 @@
#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10
#endif
-void scsi_show_command(struct scsi_cmnd *srb);
+void scsi_show_command(struct rtsx_chip *chip);
void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type);
void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code,
u8 sense_key, u32 info, u8 asc, u8 ascq,
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
index 694d3834962c..0a67dca72dff 100644
--- a/drivers/staging/rts5208/rtsx_transport.c
+++ b/drivers/staging/rts5208/rtsx_transport.c
@@ -29,7 +29,6 @@
#include "rtsx_transport.h"
#include "rtsx_chip.h"
#include "rtsx_card.h"
-#include "debug.h"
/***********************************************************************
* Scatter-gather transfer buffer access routines
@@ -170,14 +169,14 @@ void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip)
* short-circuit all other processing
*/
if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
- RTSX_DEBUGP("-- command was aborted\n");
+ dev_dbg(rtsx_dev(chip), "-- command was aborted\n");
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
/* if there is a transport error, reset and don't auto-sense */
if (result == TRANSPORT_ERROR) {
- RTSX_DEBUGP("-- transport indicates error, resetting\n");
+ dev_dbg(rtsx_dev(chip), "-- transport indicates error, resetting\n");
srb->result = DID_ERROR << 16;
goto Handle_Errors;
}
@@ -274,7 +273,8 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
TRACE_GOTO(chip, finish_send_cmd);
}
@@ -386,9 +386,10 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
addr = sg_dma_address(sg_ptr);
len = sg_dma_len(sg_ptr);
- RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
- (unsigned int)addr, len);
- RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset);
+ dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n",
+ (unsigned int)addr, len);
+ dev_dbg(rtsx_dev(chip), "*index = %d, *offset = %d\n",
+ *index, *offset);
addr += *offset;
@@ -415,7 +416,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
sg_ptr = sg_next(sg_ptr);
}
- RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
+ dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi);
val |= (u32)(dir & 0x01) << 29;
val |= ADMA_MODE;
@@ -432,8 +433,10 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
goto out;
}
@@ -454,8 +457,10 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
goto out;
}
@@ -542,8 +547,8 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
unsigned int len = sg_dma_len(sg_ptr);
u8 option;
- RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n",
- (unsigned int)addr, len);
+ dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n",
+ (unsigned int)addr, len);
if (j == (sg_cnt - 1))
option = SG_VALID | SG_END | SG_TRANS_DATA;
@@ -555,7 +560,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
sg_ptr = sg_next(sg_ptr);
}
- RTSX_DEBUGP("SG table count = %d\n", chip->sgi);
+ dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi);
val |= (u32)(dir & 0x01) << 29;
val |= ADMA_MODE;
@@ -572,8 +577,10 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
goto out;
}
@@ -597,8 +604,10 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
goto out;
}
@@ -681,8 +690,10 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, timeout * HZ / 1000);
if (timeleft <= 0) {
- RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__);
- RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg);
+ dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
+ chip->int_reg);
err = -ETIMEDOUT;
goto out;
}
@@ -742,7 +753,7 @@ int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
{
int err = 0;
- RTSX_DEBUGP("use_sg = %d\n", use_sg);
+ dev_dbg(rtsx_dev(chip), "use_sg = %d\n", use_sg);
/* don't transfer data during abort processing */
if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
index c7c1f5410430..c79bea808698 100644
--- a/drivers/staging/rts5208/sd.c
+++ b/drivers/staging/rts5208/sd.c
@@ -133,7 +133,7 @@ static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
sd_clr_err_code(chip);
- RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg);
if (rsp_type == SD_RSP_TYPE_R1b)
timeout = 3000;
@@ -177,10 +177,10 @@ RTY_SEND_CMD:
u8 val;
rtsx_read_register(chip, REG_SD_STAT1, &val);
- RTSX_DEBUGP("SD_STAT1: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_STAT1: 0x%x\n", val);
rtsx_read_register(chip, REG_SD_CFG3, &val);
- RTSX_DEBUGP("SD_CFG3: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_CFG3: 0x%x\n", val);
if (retval == -ETIMEDOUT) {
if (rsp_type & SD_WAIT_BUSY_END) {
@@ -241,15 +241,18 @@ RTY_SEND_CMD:
if (ptr[1] & 0x7F)
#endif
{
- RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]);
+ dev_dbg(rtsx_dev(chip), "ptr[1]: 0x%02x\n",
+ ptr[1]);
TRACE_RET(chip, STATUS_FAIL);
}
if (ptr[2] & 0xFF) {
- RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]);
+ dev_dbg(rtsx_dev(chip), "ptr[2]: 0x%02x\n",
+ ptr[2]);
TRACE_RET(chip, STATUS_FAIL);
}
if (ptr[3] & 0x80) {
- RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]);
+ dev_dbg(rtsx_dev(chip), "ptr[3]: 0x%02x\n",
+ ptr[3]);
TRACE_RET(chip, STATUS_FAIL);
}
if (ptr[3] & 0x01)
@@ -285,7 +288,7 @@ static int sd_read_data(struct rtsx_chip *chip,
rtsx_init_cmd(chip);
if (cmd_len) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40);
for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++)
rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i,
0xFF, cmd[i]);
@@ -359,7 +362,7 @@ static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode,
rtsx_init_cmd(chip);
if (cmd_len) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40);
for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) {
rtsx_add_cmd(chip, WRITE_REG_CMD,
REG_SD_CMD0 + i, 0xFF, cmd[i]);
@@ -423,11 +426,11 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp)
memcpy(sd_card->raw_csd, rsp + 1, 15);
- RTSX_DEBUGP("CSD Response:\n");
+ dev_dbg(rtsx_dev(chip), "CSD Response:\n");
RTSX_DUMP(sd_card->raw_csd, 16);
csd_ver = (rsp[1] & 0xc0) >> 6;
- RTSX_DEBUGP("csd_ver = %d\n", csd_ver);
+ dev_dbg(rtsx_dev(chip), "csd_ver = %d\n", csd_ver);
trans_speed = rsp[4];
if ((trans_speed & 0x07) == 0x02) {
@@ -494,7 +497,7 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp)
if (rsp[15] & 0x30)
chip->card_wp |= SD_CARD;
- RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]);
+ dev_dbg(rtsx_dev(chip), "CSD WP Status: 0x%x\n", rsp[15]);
}
return STATUS_SUCCESS;
@@ -654,7 +657,7 @@ static int sd_update_lock_status(struct rtsx_chip *chip)
else
sd_card->sd_lock_status &= ~SD_LOCKED;
- RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "sd_card->sd_lock_status = 0x%x\n",
sd_card->sd_lock_status);
if (rsp[1] & 0x01)
@@ -754,7 +757,7 @@ static int sd_voltage_switch(struct rtsx_chip *chip)
SD_DAT1_STATUS | SD_DAT0_STATUS)) !=
(SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS |
SD_DAT1_STATUS | SD_DAT0_STATUS)) {
- RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat);
+ dev_dbg(rtsx_dev(chip), "SD_BUS_STAT: 0x%x\n", stat);
rtsx_write_register(chip, SD_BUS_STAT,
SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0);
@@ -788,8 +791,8 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
int retval;
int ddr_rx = 0;
- RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n",
- sample_point, tune_dir);
+ dev_dbg(rtsx_dev(chip), "sd_change_phase (sample_point = %d, tune_dir = %d)\n",
+ sample_point, tune_dir);
if (tune_dir == TUNE_RX) {
SD_VP_CTL = SD_VPRX_CTL;
@@ -811,9 +814,9 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
} else {
#ifdef CONFIG_RTS5208_DEBUG
rtsx_read_register(chip, SD_VP_CTL, &val);
- RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val);
rtsx_read_register(chip, SD_DCMPS_CTL, &val);
- RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val);
#endif
if (ddr_rx) {
@@ -862,11 +865,10 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir)
Fail:
#ifdef CONFIG_RTS5208_DEBUG
rtsx_read_register(chip, SD_VP_CTL, &val);
- RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val);
rtsx_read_register(chip, SD_DCMPS_CTL, &val);
- RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val);
#endif
-
rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0);
rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0);
wait_timeout(10);
@@ -1026,8 +1028,8 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode,
int retval;
u8 cmd[5], buf[64];
- RTSX_DEBUGP("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), "sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n",
+ mode, func_group, func_to_switch);
cmd[0] = 0x40 | SWITCH;
cmd[1] = mode;
@@ -1066,16 +1068,21 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode,
sd_card->func_group3_mask = buf[0x09];
sd_card->func_group4_mask = buf[0x07];
- RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]);
- RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]);
- RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]);
- RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]);
+ dev_dbg(rtsx_dev(chip), "func_group1_mask = 0x%02x\n",
+ buf[0x0D]);
+ dev_dbg(rtsx_dev(chip), "func_group2_mask = 0x%02x\n",
+ buf[0x0B]);
+ dev_dbg(rtsx_dev(chip), "func_group3_mask = 0x%02x\n",
+ buf[0x09]);
+ dev_dbg(rtsx_dev(chip), "func_group4_mask = 0x%02x\n",
+ buf[0x07]);
} else {
/* Maximum current consumption, check whether current is
* acceptable; bit[511:496] = 0x0000 means some error happened.
*/
u16 cc = ((u16)buf[0] << 8) | buf[1];
- RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc);
+ dev_dbg(rtsx_dev(chip), "Maximum current consumption: %dmA\n",
+ cc);
if ((cc == 0) || (cc > 800))
TRACE_RET(chip, STATUS_FAIL);
@@ -1136,7 +1143,7 @@ static int sd_check_switch(struct rtsx_chip *chip,
RTSX_READ_REG(chip, SD_STAT1, &stat);
if (stat & SD_CRC16_ERR) {
- RTSX_DEBUGP("SD CRC16 error when switching mode\n");
+ dev_dbg(rtsx_dev(chip), "SD CRC16 error when switching mode\n");
TRACE_RET(chip, STATUS_FAIL);
}
}
@@ -1207,14 +1214,15 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
break;
}
- RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch);
+ dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_1: func_to_switch = 0x%02x",
+ func_to_switch);
#ifdef SUPPORT_SD_LOCK
if ((sd_card->sd_lock_status & SD_SDR_RST)
&& (DDR50_SUPPORT == func_to_switch)
&& (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) {
func_to_switch = SDR50_SUPPORT;
- RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n");
+ dev_dbg(rtsx_dev(chip), "Using SDR50 instead of DDR50 for SD Lock\n");
}
#endif
@@ -1295,7 +1303,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
break;
}
- RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch);
+ dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_4: func_to_switch = 0x%02x",
+ func_to_switch);
if (func_to_switch <= CURRENT_LIMIT_800) {
retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch,
@@ -1304,7 +1313,8 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width)
if (sd_check_err_code(chip, SD_NO_CARD))
TRACE_RET(chip, STATUS_FAIL);
}
- RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval);
+ dev_dbg(rtsx_dev(chip), "Switch current limit finished! (%d)\n",
+ retval);
}
if (CHK_SD_DDR50(sd_card))
@@ -1327,7 +1337,7 @@ static int sd_wait_data_idle(struct rtsx_chip *chip)
}
udelay(100);
}
- RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val);
+ dev_dbg(rtsx_dev(chip), "SD_DATA_STATE: 0x%02x\n", val);
return retval;
}
@@ -1369,7 +1379,7 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("sd ddr tuning rx\n");
+ dev_dbg(rtsx_dev(chip), "sd ddr tuning rx\n");
retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr,
SD_RSP_TYPE_R1, NULL, 0);
@@ -1411,7 +1421,7 @@ static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("mmc ddr tuning rx\n");
+ dev_dbg(rtsx_dev(chip), "mmc ddr tuning rx\n");
cmd[0] = 0x40 | SEND_EXT_CSD;
cmd[1] = 0;
@@ -1552,7 +1562,7 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map,
}
if (cont_path_cnt == 0) {
- RTSX_DEBUGP("No continuous phase path\n");
+ dev_dbg(rtsx_dev(chip), "No continuous phase path\n");
goto Search_Finish;
} else {
int idx = cont_path_cnt - 1;
@@ -1581,11 +1591,12 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map,
final_path_idx = i;
}
- RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start);
- RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end);
- RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len);
- RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid);
- RTSX_DEBUGP("\n");
+ dev_dbg(rtsx_dev(chip), "path[%d].start = %d\n",
+ i, path[i].start);
+ dev_dbg(rtsx_dev(chip), "path[%d].end = %d\n", i, path[i].end);
+ dev_dbg(rtsx_dev(chip), "path[%d].len = %d\n", i, path[i].len);
+ dev_dbg(rtsx_dev(chip), "path[%d].mid = %d\n", i, path[i].mid);
+ dev_dbg(rtsx_dev(chip), "\n");
}
if (tune_dir == TUNE_TX) {
@@ -1619,7 +1630,7 @@ static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map,
}
Search_Finish:
- RTSX_DEBUGP("Final chosen phase: %d\n", final_phase);
+ dev_dbg(rtsx_dev(chip), "Final chosen phase: %d\n", final_phase);
return final_phase;
}
@@ -1661,10 +1672,10 @@ static int sd_tuning_rx(struct rtsx_chip *chip)
phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
for (i = 0; i < 3; i++)
- RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i,
- raw_phase_map[i]);
+ dev_dbg(rtsx_dev(chip), "RX raw_phase_map[%d] = 0x%08x\n",
+ i, raw_phase_map[i]);
- RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map);
+ dev_dbg(rtsx_dev(chip), "RX phase_map = 0x%08x\n", phase_map);
final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX);
if (final_phase == 0xFF)
@@ -1711,7 +1722,8 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0);
- RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map);
+ dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase_map = 0x%08x\n",
+ phase_map);
final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
if (final_phase == 0xFF)
@@ -1721,7 +1733,8 @@ static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase);
+ dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase: %d\n",
+ (int)final_phase);
return STATUS_SUCCESS;
}
@@ -1766,10 +1779,10 @@ static int sd_tuning_tx(struct rtsx_chip *chip)
phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2];
for (i = 0; i < 3; i++)
- RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n",
+ dev_dbg(rtsx_dev(chip), "TX raw_phase_map[%d] = 0x%08x\n",
i, raw_phase_map[i]);
- RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map);
+ dev_dbg(rtsx_dev(chip), "TX phase_map = 0x%08x\n", phase_map);
final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX);
if (final_phase == 0xFF)
@@ -2022,7 +2035,7 @@ static int sd_init_power(struct rtsx_chip *chip)
#ifdef SUPPORT_OCP
if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",
chip->ocp_stat);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -2105,11 +2118,11 @@ static int sd_check_wp_state(struct rtsx_chip *chip)
TRACE_RET(chip, STATUS_FAIL);
}
- RTSX_DEBUGP("ACMD13:\n");
+ dev_dbg(rtsx_dev(chip), "ACMD13:\n");
RTSX_DUMP(buf, 64);
sd_card_type = ((u16)buf[2] << 8) | buf[3];
- RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type);
+ dev_dbg(rtsx_dev(chip), "sd_card_type = 0x%04x\n", sd_card_type);
if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) {
/* ROM card or OTP */
chip->card_wp |= SD_CARD;
@@ -2171,7 +2184,8 @@ Switch_Fail:
if (retval == STATUS_SUCCESS) {
int func_num = (rsp[1] >> 4) & 0x07;
if (func_num) {
- RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num);
+ dev_dbg(rtsx_dev(chip), "SD_IO card (Function number: %d)!\n",
+ func_num);
chip->sd_io = 1;
TRACE_RET(chip, STATUS_FAIL);
}
@@ -2184,7 +2198,7 @@ Switch_Fail:
sd_dummy_clock(chip);
}
- RTSX_DEBUGP("Normal card!\n");
+ dev_dbg(rtsx_dev(chip), "Normal card!\n");
}
/* Start Initialization Process of SD Card */
@@ -2260,7 +2274,7 @@ RTY_SD_RST:
CLR_SD_HCXC(sd_card);
support_1v8 = 0;
}
- RTSX_DEBUGP("support_1v8 = %d\n", support_1v8);
+ dev_dbg(rtsx_dev(chip), "support_1v8 = %d\n", support_1v8);
if (support_1v8) {
retval = sd_voltage_switch(chip);
@@ -2508,7 +2522,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, SWITCH_ERR);
- RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", BUSTEST_R);
rtsx_init_cmd(chip);
@@ -2547,8 +2561,8 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
ptr = rtsx_get_cmd_data(chip) + 1;
if (width == MMC_8BIT_BUS) {
- RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0],
- ptr[1]);
+ dev_dbg(rtsx_dev(chip), "BUSTEST_R [8bits]: 0x%02x 0x%02x\n",
+ ptr[0], ptr[1]);
if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) {
u8 rsp[5];
u32 arg;
@@ -2565,7 +2579,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width)
return SWITCH_SUCCESS;
}
} else {
- RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]);
+ dev_dbg(rtsx_dev(chip), "BUSTEST_R [4bits]: 0x%02x\n", ptr[0]);
if (ptr[0] == 0xA5) {
u8 rsp[5];
u32 arg;
@@ -2595,7 +2609,7 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr)
CLR_MMC_HS(sd_card);
- RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", SEND_EXT_CSD);
rtsx_init_cmd(chip);
@@ -2951,7 +2965,7 @@ int reset_sd_card(struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type);
+ dev_dbg(rtsx_dev(chip), "sd_card->sd_type = 0x%x\n", sd_card->sd_type);
return STATUS_SUCCESS;
}
@@ -2999,7 +3013,7 @@ static int reset_mmc_only(struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "In reset_mmc_only, sd_card->sd_type = 0x%x\n",
sd_card->sd_type);
return STATUS_SUCCESS;
@@ -3116,11 +3130,13 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
int retval;
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt,
- (sector_cnt > 1) ? "sectors" : "sector", start_sector);
+ dev_dbg(rtsx_dev(chip), "sd_rw: Read %d %s from 0x%x\n",
+ sector_cnt, (sector_cnt > 1) ? "sectors" : "sector",
+ start_sector);
} else {
- RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt,
- (sector_cnt > 1) ? "sectors" : "sector", start_sector);
+ dev_dbg(rtsx_dev(chip), "sd_rw: Write %d %s to 0x%x\n",
+ sector_cnt, (sector_cnt > 1) ? "sectors" : "sector",
+ start_sector);
}
sd_card->cleanup_counter = 0;
@@ -3236,7 +3252,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
rtsx_send_cmd_no_wait(chip);
} else {
if (srb->sc_data_direction == DMA_FROM_DEVICE) {
- RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK);
+ dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n",
+ READ_MULTIPLE_BLOCK);
rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF,
0x40 | READ_MULTIPLE_BLOCK);
rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF,
@@ -3327,7 +3344,7 @@ 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;
- RTSX_DEBUGP("No card exist, exit sd_rw\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n");
TRACE_RET(chip, STATUS_FAIL);
}
@@ -3341,7 +3358,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector,
}
if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) {
- RTSX_DEBUGP("SD CRC error, tune clock!\n");
+ dev_dbg(rtsx_dev(chip), "SD CRC error, tune clock!\n");
sd_set_err_code(chip, SD_CRC_ERR);
TRACE_GOTO(chip, RW_FAIL);
}
@@ -3365,7 +3382,7 @@ RW_FAIL:
if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) {
chip->rw_need_retry = 0;
- RTSX_DEBUGP("No card exist, exit sd_rw\n");
+ dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n");
TRACE_RET(chip, STATUS_FAIL);
}
@@ -3406,7 +3423,7 @@ int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx,
int stat_idx = 0;
int rty_cnt = 0;
- RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx);
+ dev_dbg(rtsx_dev(chip), "EXT SD/MMC CMD %d\n", cmd_idx);
if (rsp_type == SD_RSP_TYPE_R1b)
timeout = 3000;
@@ -3558,8 +3575,8 @@ int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type)
memcpy(rsp, rtsx_get_cmd_data(chip), min_len);
- RTSX_DEBUGP("min_len = %d\n", min_len);
- RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "min_len = %d\n", min_len);
+ dev_dbg(rtsx_dev(chip), "Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n",
rsp[0], rsp[1], rsp[2], rsp[3]);
}
@@ -3847,7 +3864,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
} else {
bus_width = SD_BUS_WIDTH_4;
}
- RTSX_DEBUGP("bus_width = %d\n", bus_width);
+ dev_dbg(rtsx_dev(chip), "bus_width = %d\n", bus_width);
#else
bus_width = SD_BUS_WIDTH_4;
#endif
@@ -4247,7 +4264,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
retval = sd_update_lock_status(chip);
if (retval != STATUS_SUCCESS) {
- RTSX_DEBUGP("Lock command fail!\n");
+ dev_dbg(rtsx_dev(chip), "Lock command fail!\n");
lock_cmd_fail = 1;
}
}
@@ -4298,7 +4315,8 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
#ifdef SUPPORT_SD_LOCK
if (cmd_idx == LOCK_UNLOCK) {
if (!lock_cmd_fail) {
- RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type);
+ dev_dbg(rtsx_dev(chip), "lock_cmd_type = 0x%x\n",
+ lock_cmd_type);
if (lock_cmd_type & SD_CLR_PWD)
sd_card->sd_lock_status &= ~SD_PWD_EXIST;
@@ -4306,8 +4324,8 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip)
sd_card->sd_lock_status |= SD_PWD_EXIST;
}
- RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n",
- sd_lock_state, sd_card->sd_lock_status);
+ dev_dbg(rtsx_dev(chip), "sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n",
+ sd_lock_state, sd_card->sd_lock_status);
if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) {
sd_card->sd_lock_notify = 1;
if (sd_lock_state) {
@@ -4382,9 +4400,10 @@ int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip)
}
rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb);
- RTSX_DEBUGP("Response length: %d\n", data_len);
- RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", sd_card->rsp[0],
- sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]);
+ dev_dbg(rtsx_dev(chip), "Response length: %d\n", data_len);
+ dev_dbg(rtsx_dev(chip), "Response: 0x%x 0x%x 0x%x 0x%x\n",
+ sd_card->rsp[0], sd_card->rsp[1],
+ sd_card->rsp[2], sd_card->rsp[3]);
scsi_set_resid(srb, 0);
return TRANSPORT_GOOD;
@@ -4459,7 +4478,7 @@ void sd_cleanup_work(struct rtsx_chip *chip)
struct sd_info *sd_card = &(chip->sd_card);
if (sd_card->seq_mode) {
- RTSX_DEBUGP("SD: stop transmission\n");
+ dev_dbg(rtsx_dev(chip), "SD: stop transmission\n");
sd_stop_seq_mode(chip);
sd_card->cleanup_counter = 0;
}
@@ -4500,8 +4519,6 @@ int release_sd_card(struct rtsx_chip *chip)
struct sd_info *sd_card = &(chip->sd_card);
int retval;
- RTSX_DEBUGP("release_sd_card\n");
-
chip->card_ready &= ~SD_CARD;
chip->card_fail &= ~SD_CARD;
chip->card_wp &= ~SD_CARD;
diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c
index 312b9f9c6456..29f4a80844fa 100644
--- a/drivers/staging/rts5208/spi.c
+++ b/drivers/staging/rts5208/spi.c
@@ -409,7 +409,8 @@ int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
struct spi_info *spi = &(chip->spi);
- RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code);
+ dev_dbg(rtsx_dev(chip), "spi_get_status: err_code = 0x%x\n",
+ spi->err_code);
rtsx_stor_set_xfer_buf(&(spi->err_code),
min_t(int, scsi_bufflen(srb), 1), srb);
scsi_set_resid(srb, scsi_bufflen(srb) - 1);
@@ -431,8 +432,8 @@ 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];
- RTSX_DEBUGP("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), "spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
+ spi->spi_clock, spi->clk_div, spi->write_en);
return STATUS_SUCCESS;
}
diff --git a/drivers/staging/rts5208/trace.h b/drivers/staging/rts5208/trace.h
index 0f177fbaaf1f..fbb304a54acc 100644
--- a/drivers/staging/rts5208/trace.h
+++ b/drivers/staging/rts5208/trace.h
@@ -49,7 +49,8 @@ static inline char *filename(char *path)
#define TRACE_RET(chip, ret) \
do { \
char *_file = filename(__FILE__); \
- RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
+ dev_dbg(rtsx_dev(chip), "[%s][%s]:[%d]\n", _file, \
+ __func__, __LINE__); \
(chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
@@ -65,7 +66,8 @@ static inline char *filename(char *path)
#define TRACE_GOTO(chip, label) \
do { \
char *_file = filename(__FILE__); \
- RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \
+ dev_dbg(rtsx_dev(chip), "[%s][%s]:[%d]\n", _file, \
+ __func__, __LINE__); \
(chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \
strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \
strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \
@@ -84,8 +86,8 @@ static inline char *filename(char *path)
#ifdef CONFIG_RTS5208_DEBUG
#define RTSX_DUMP(buf, buf_len) \
- print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \
- 16, 1, (buf), (buf_len), false)
+ print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": ", \
+ DUMP_PREFIX_NONE, 16, 1, (buf), (buf_len), false)
#else
#define RTSX_DUMP(buf, buf_len)
#endif
diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c
index 6aef53d14e31..0d029fe92b40 100644
--- a/drivers/staging/rts5208/xd.c
+++ b/drivers/staging/rts5208/xd.c
@@ -253,13 +253,13 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit);
RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte);
- RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n",
ecc_bit, ecc_byte);
if (ecc_byte < buf_len) {
- RTSX_DEBUGP("Before correct: 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n",
buf[ecc_byte]);
buf[ecc_byte] ^= (1 << ecc_bit);
- RTSX_DEBUGP("After correct: 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n",
buf[ecc_byte]);
}
}
@@ -275,13 +275,13 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf,
RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit);
RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte);
- RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n",
ecc_bit, ecc_byte);
if (ecc_byte < buf_len) {
- RTSX_DEBUGP("Before correct: 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n",
buf[ecc_byte]);
buf[ecc_byte] ^= (1 << ecc_bit);
- RTSX_DEBUGP("After correct: 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n",
buf[ecc_byte]);
}
}
@@ -449,7 +449,7 @@ static int reset_xd(struct rtsx_chip *chip)
#ifdef SUPPORT_OCP
wait_timeout(50);
if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
- RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n",
chip->ocp_stat);
TRACE_RET(chip, STATUS_FAIL);
}
@@ -507,7 +507,8 @@ static int reset_xd(struct rtsx_chip *chip)
ptr = rtsx_get_cmd_data(chip) + 1;
- RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]);
+ dev_dbg(rtsx_dev(chip), "XD_DAT: 0x%x, XD_CTL: 0x%x\n",
+ ptr[0], ptr[1]);
if (((ptr[0] & READY_FLAG) != READY_STATE) ||
!(ptr[1] & XD_RDY))
@@ -517,7 +518,7 @@ static int reset_xd(struct rtsx_chip *chip)
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "READ_ID: 0x%x 0x%x 0x%x 0x%x\n",
id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
xd_card->device_code = id_buf[1];
@@ -618,8 +619,8 @@ static int reset_xd(struct rtsx_chip *chip)
retval = xd_read_id(chip, READ_xD_ID, id_buf, 4);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
- RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n",
- id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
+ dev_dbg(rtsx_dev(chip), "READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n",
+ id_buf[0], id_buf[1], id_buf[2], id_buf[3]);
if (id_buf[2] != XD_ID_CODE)
TRACE_RET(chip, STATUS_FAIL);
@@ -682,7 +683,7 @@ static int reset_xd(struct rtsx_chip *chip)
break;
}
- RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block);
+ dev_dbg(rtsx_dev(chip), "CIS block: 0x%x\n", xd_card->cis_block);
if (xd_card->cis_block == 0xFFFF)
TRACE_RET(chip, STATUS_FAIL);
@@ -735,13 +736,14 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip)
struct xd_info *xd_card = &(chip->xd_card);
int size, i;
- RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt);
+ dev_dbg(rtsx_dev(chip), "xd_init_l2p_tbl: zone_cnt = %d\n",
+ xd_card->zone_cnt);
if (xd_card->zone_cnt < 1)
TRACE_RET(chip, STATUS_FAIL);
size = xd_card->zone_cnt * sizeof(struct zone_entry);
- RTSX_DEBUGP("Buffer size for l2p table is %d\n", size);
+ dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size);
xd_card->zone = vmalloc(size);
if (!xd_card->zone)
@@ -761,8 +763,6 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip)
static inline void free_zone(struct zone_entry *zone)
{
- RTSX_DEBUGP("free_zone\n");
-
if (!zone)
return;
@@ -788,7 +788,7 @@ static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
zone_no = (int)phy_blk >> 10;
if (zone_no >= xd_card->zone_cnt) {
- RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",
+ dev_dbg(rtsx_dev(chip), "Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n",
zone_no, xd_card->zone_cnt);
return;
}
@@ -802,11 +802,12 @@ static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk)
if ((zone->set_index >= XD_FREE_TABLE_CNT)
|| (zone->set_index < 0)) {
free_zone(zone);
- RTSX_DEBUGP("Set unused block fail, invalid set_index\n");
+ dev_dbg(rtsx_dev(chip), "Set unused block fail, invalid set_index\n");
return;
}
- RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index);
+ dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n",
+ zone->set_index);
zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff);
if (zone->set_index >= XD_FREE_TABLE_CNT)
@@ -821,7 +822,7 @@ static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)
u32 phy_blk;
if (zone_no >= xd_card->zone_cnt) {
- RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",
+ dev_dbg(rtsx_dev(chip), "Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n",
zone_no, xd_card->zone_cnt);
return BLK_NOT_FOUND;
}
@@ -830,16 +831,17 @@ static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no)
if ((zone->unused_blk_cnt == 0) ||
(zone->set_index == zone->get_index)) {
free_zone(zone);
- RTSX_DEBUGP("Get unused block fail, no unused block available\n");
+ dev_dbg(rtsx_dev(chip), "Get unused block fail, no unused block available\n");
return BLK_NOT_FOUND;
}
if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) {
free_zone(zone);
- RTSX_DEBUGP("Get unused block fail, invalid get_index\n");
+ dev_dbg(rtsx_dev(chip), "Get unused block fail, invalid get_index\n");
return BLK_NOT_FOUND;
}
- RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index);
+ dev_dbg(rtsx_dev(chip), "Get unused block from index %d\n",
+ zone->get_index);
phy_blk = zone->free_table[zone->get_index];
zone->free_table[zone->get_index++] = 0xFFFF;
@@ -875,20 +877,20 @@ 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) {
- RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n");
+ dev_dbg(rtsx_dev(chip), "In xd_get_l2p_tbl, delay write fail!\n");
return BLK_NOT_FOUND;
}
#endif
if (zone->unused_blk_cnt <= 0) {
- RTSX_DEBUGP("No unused block!\n");
+ dev_dbg(rtsx_dev(chip), "No unused block!\n");
return BLK_NOT_FOUND;
}
for (i = 0; i < zone->unused_blk_cnt; i++) {
phy_blk = xd_get_unused_block(chip, zone_no);
if (phy_blk == BLK_NOT_FOUND) {
- RTSX_DEBUGP("No unused block available!\n");
+ dev_dbg(rtsx_dev(chip), "No unused block available!\n");
return BLK_NOT_FOUND;
}
@@ -898,7 +900,7 @@ static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off)
break;
}
if (i >= zone->unused_blk_cnt) {
- RTSX_DEBUGP("No good unused block available!\n");
+ dev_dbg(rtsx_dev(chip), "No good unused block available!\n");
return BLK_NOT_FOUND;
}
@@ -946,7 +948,7 @@ static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk)
u32 page_addr;
u8 reg = 0;
- RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk);
+ dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk);
if (phy_blk == BLK_NOT_FOUND)
TRACE_RET(chip, STATUS_FAIL);
@@ -998,7 +1000,7 @@ static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk,
u32 page_addr;
u8 reg = 0;
- RTSX_DEBUGP("Init block 0x%x\n", phy_blk);
+ dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk);
if (start_page > end_page)
TRACE_RET(chip, STATUS_FAIL);
@@ -1052,7 +1054,7 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
u8 i, reg = 0;
int retval;
- RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n",
+ dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n",
old_blk, new_blk);
if (start_page > end_page)
@@ -1112,7 +1114,8 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk,
XD_BLOCK_STATUS, 0xFF,
XD_GBLK);
XD_SET_BAD_OLDBLK(xd_card);
- RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk);
+ dev_dbg(rtsx_dev(chip), "old block 0x%x ecc error\n",
+ old_blk);
}
} else {
xd_set_err_code(chip, XD_TO_ERROR);
@@ -1245,7 +1248,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];
- RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no);
+ dev_dbg(rtsx_dev(chip), "xd_build_l2p_tbl: %d\n", zone_no);
if (xd_card->zone == NULL) {
retval = xd_init_l2p_tbl(chip);
@@ -1254,7 +1257,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
}
if (xd_card->zone[zone_no].build_flag) {
- RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no);
+ dev_dbg(rtsx_dev(chip), "l2p table of zone %d has been built\n",
+ zone_no);
return STATUS_SUCCESS;
}
@@ -1292,7 +1296,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
max_logoff = 999;
}
- RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end);
+ dev_dbg(rtsx_dev(chip), "start block 0x%x, end block 0x%x\n",
+ start, end);
zone->set_index = zone->get_index = 0;
zone->unused_blk_cnt = 0;
@@ -1306,12 +1311,12 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
continue;
if (redunt[BLOCK_STATUS] != 0xFF) {
- RTSX_DEBUGP("bad block\n");
+ dev_dbg(rtsx_dev(chip), "bad block\n");
continue;
}
if (xd_check_data_blank(redunt)) {
- RTSX_DEBUGP("blank block\n");
+ dev_dbg(rtsx_dev(chip), "blank block\n");
xd_set_unused_block(chip, i);
continue;
}
@@ -1397,8 +1402,10 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no)
i++;
}
- RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i);
- RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt);
+ dev_dbg(rtsx_dev(chip), "Block count %d, invalid L2P entry %d\n",
+ end, i);
+ dev_dbg(rtsx_dev(chip), "Total unused block: %d\n",
+ zone->unused_blk_cnt);
if ((zone->unused_blk_cnt - i) < 1)
chip->card_wp |= XD_CARD;
@@ -1566,8 +1573,8 @@ static int xd_finish_write(struct rtsx_chip *chip,
int retval, zone_no;
u16 log_off;
- RTSX_DEBUGP("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), "xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
+ old_blk, new_blk, log_blk);
if (page_off > xd_card->page_off)
TRACE_RET(chip, STATUS_FAIL);
@@ -1621,7 +1628,7 @@ static int xd_prepare_write(struct rtsx_chip *chip,
{
int retval;
- RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",
+ dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n",
__func__, old_blk, new_blk, log_blk, (int)page_off);
if (page_off) {
@@ -1645,8 +1652,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk,
u16 log_off;
u8 page_cnt, reg_val;
- RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
- __func__, old_blk, new_blk, log_blk);
+ dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n",
+ __func__, old_blk, new_blk, log_blk);
if (start_page > end_page)
TRACE_RET(chip, STATUS_FAIL);
@@ -1740,7 +1747,7 @@ int xd_delay_write(struct rtsx_chip *chip)
int retval;
if (delay_write->delay_write_flag) {
- RTSX_DEBUGP("xd_delay_write\n");
+ dev_dbg(rtsx_dev(chip), "xd_delay_write\n");
retval = xd_switch_clock(chip);
if (retval != STATUS_SUCCESS)
TRACE_RET(chip, STATUS_FAIL);
@@ -1777,7 +1784,8 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
xd_card->cleanup_counter = 0;
- RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb));
+ dev_dbg(rtsx_dev(chip), "xd_rw: scsi_sg_count = %d\n",
+ scsi_sg_count(srb));
ptr = (u8 *)scsi_sglist(srb);
@@ -1887,7 +1895,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip,
}
}
- RTSX_DEBUGP("old_blk = 0x%x\n", old_blk);
+ dev_dbg(rtsx_dev(chip), "old_blk = 0x%x\n", old_blk);
while (total_sec_cnt) {
if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) {
@@ -2029,7 +2037,7 @@ void xd_cleanup_work(struct rtsx_chip *chip)
struct xd_info *xd_card = &(chip->xd_card);
if (xd_card->delay_write.delay_write_flag) {
- RTSX_DEBUGP("xD: delay write\n");
+ dev_dbg(rtsx_dev(chip), "xD: delay write\n");
xd_delay_write(chip);
xd_card->cleanup_counter = 0;
}
@@ -2070,8 +2078,6 @@ int release_xd_card(struct rtsx_chip *chip)
struct xd_info *xd_card = &(chip->xd_card);
int retval;
- RTSX_DEBUGP("release_xd_card\n");
-
chip->card_ready &= ~XD_CARD;
chip->card_fail &= ~XD_CARD;
chip->card_wp &= ~XD_CARD;
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig
deleted file mode 100644
index aab945a316ea..000000000000
--- a/drivers/staging/sep/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config DX_SEP
- tristate "Discretix SEP driver"
- depends on PCI && CRYPTO
- help
- Discretix SEP driver; used for the security processor subsystem
- on board the Intel Mobile Internet Device and adds SEP availability
- to the kernel crypto infrastructure
-
- The driver's name is sep_driver.
-
- If unsure, select N.
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile
deleted file mode 100644
index e48a7959289e..000000000000
--- a/drivers/staging/sep/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ccflags-y += -I$(srctree)/$(src)
-obj-$(CONFIG_DX_SEP) += sep_driver.o
-sep_driver-objs := sep_crypto.o sep_main.o
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO
deleted file mode 100644
index 3524d0cf84ba..000000000000
--- a/drivers/staging/sep/TODO
+++ /dev/null
@@ -1,3 +0,0 @@
-Todo's so far (from Alan Cox)
-- Clean up unused ioctls
-- Clean up unused fields in ioctl structures
diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c
deleted file mode 100644
index 415f8ec5276b..000000000000
--- a/drivers/staging/sep/sep_crypto.c
+++ /dev/null
@@ -1,3962 +0,0 @@
-/*
- *
- * sep_crypto.c - Crypto interface structures
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2010 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- * 2010.09.14 Upgrade to Medfield
- * 2011.02.22 Enable Kernel Crypto
- *
- */
-
-/* #define DEBUG */
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/pci.h>
-#include <linux/pm_runtime.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/workqueue.h>
-#include <linux/crypto.h>
-#include <crypto/internal/hash.h>
-#include <crypto/scatterwalk.h>
-#include <crypto/sha.h>
-#include <crypto/md5.h>
-#include <crypto/aes.h>
-#include <crypto/des.h>
-#include <crypto/hash.h>
-#include "sep_driver_hw_defs.h"
-#include "sep_driver_config.h"
-#include "sep_driver_api.h"
-#include "sep_dev.h"
-#include "sep_crypto.h"
-
-#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
-
-/* Globals for queuing */
-static spinlock_t queue_lock;
-static struct crypto_queue sep_queue;
-
-/* Declare of dequeuer */
-static void sep_dequeuer(void *data);
-
-/* TESTING */
-/**
- * sep_do_callback
- * @work: pointer to work_struct
- * This is what is called by the queue; it is generic so that it
- * can be used by any type of operation as each different callback
- * function can use the data parameter in its own way
- */
-static void sep_do_callback(struct work_struct *work)
-{
- struct sep_work_struct *sep_work = container_of(work,
- struct sep_work_struct, work);
-
- if (sep_work != NULL) {
- (sep_work->callback)(sep_work->data);
- kfree(sep_work);
- } else {
- pr_debug("sep crypto: do callback - NULL container\n");
- }
-}
-
-/**
- * sep_submit_work
- * @work_queue: pointer to struct_workqueue
- * @funct: pointer to function to execute
- * @data: pointer to data; function will know
- * how to use it
- * This is a generic API to submit something to
- * the queue. The callback function will depend
- * on what operation is to be done
- */
-static int sep_submit_work(struct workqueue_struct *work_queue,
- void (*funct)(void *),
- void *data)
-{
- struct sep_work_struct *sep_work;
- int result;
-
- sep_work = kmalloc(sizeof(struct sep_work_struct), GFP_ATOMIC);
-
- if (sep_work == NULL) {
- pr_debug("sep crypto: cant allocate work structure\n");
- return -ENOMEM;
- }
-
- sep_work->callback = funct;
- sep_work->data = data;
- INIT_WORK(&sep_work->work, sep_do_callback);
- result = queue_work(work_queue, &sep_work->work);
- if (!result) {
- pr_debug("sep_crypto: queue_work failed\n");
- return -EINVAL;
- }
- return 0;
-}
-
-/**
- * sep_alloc_sg_buf -
- * @sep: pointer to struct sep_device
- * @size: total size of area
- * @block_size: minimum size of chunks
- * each page is minimum or modulo this size
- * @returns: pointer to struct scatterlist for new
- * buffer
- **/
-static struct scatterlist *sep_alloc_sg_buf(
- struct sep_device *sep,
- size_t size,
- size_t block_size)
-{
- u32 nbr_pages;
- u32 ct1;
- void *buf;
- size_t current_size;
- size_t real_page_size;
-
- struct scatterlist *sg, *sg_temp;
-
- if (size == 0)
- return NULL;
-
- dev_dbg(&sep->pdev->dev, "sep alloc sg buf\n");
-
- current_size = 0;
- nbr_pages = 0;
- real_page_size = PAGE_SIZE - (PAGE_SIZE % block_size);
- /**
- * The size of each page must be modulo of the operation
- * block size; increment by the modified page size until
- * the total size is reached, then you have the number of
- * pages
- */
- while (current_size < size) {
- current_size += real_page_size;
- nbr_pages += 1;
- }
-
- sg = kmalloc_array(nbr_pages, sizeof(struct scatterlist), GFP_ATOMIC);
- if (!sg)
- return NULL;
-
- sg_init_table(sg, nbr_pages);
-
- current_size = 0;
- sg_temp = sg;
- for (ct1 = 0; ct1 < nbr_pages; ct1 += 1) {
- buf = (void *)get_zeroed_page(GFP_ATOMIC);
- if (!buf) {
- dev_warn(&sep->pdev->dev,
- "Cannot allocate page for new buffer\n");
- kfree(sg);
- return NULL;
- }
-
- sg_set_buf(sg_temp, buf, real_page_size);
- if ((size - current_size) > real_page_size) {
- sg_temp->length = real_page_size;
- current_size += real_page_size;
- } else {
- sg_temp->length = (size - current_size);
- current_size = size;
- }
- sg_temp = sg_next(sg);
- }
- return sg;
-}
-
-/**
- * sep_free_sg_buf -
- * @sg: pointer to struct scatterlist; points to area to free
- */
-static void sep_free_sg_buf(struct scatterlist *sg)
-{
- struct scatterlist *sg_temp = sg;
- while (sg_temp) {
- free_page((unsigned long)sg_virt(sg_temp));
- sg_temp = sg_next(sg_temp);
- }
- kfree(sg);
-}
-
-/**
- * sep_copy_sg -
- * @sep: pointer to struct sep_device
- * @sg_src: pointer to struct scatterlist for source
- * @sg_dst: pointer to struct scatterlist for destination
- * @size: size (in bytes) of data to copy
- *
- * Copy data from one scatterlist to another; both must
- * be the same size
- */
-static void sep_copy_sg(
- struct sep_device *sep,
- struct scatterlist *sg_src,
- struct scatterlist *sg_dst,
- size_t size)
-{
- u32 seg_size;
- u32 in_offset, out_offset;
-
- u32 count = 0;
- struct scatterlist *sg_src_tmp = sg_src;
- struct scatterlist *sg_dst_tmp = sg_dst;
- in_offset = 0;
- out_offset = 0;
-
- dev_dbg(&sep->pdev->dev, "sep copy sg\n");
-
- if ((sg_src == NULL) || (sg_dst == NULL) || (size == 0))
- return;
-
- dev_dbg(&sep->pdev->dev, "sep copy sg not null\n");
-
- while (count < size) {
- if ((sg_src_tmp->length - in_offset) >
- (sg_dst_tmp->length - out_offset))
- seg_size = sg_dst_tmp->length - out_offset;
- else
- seg_size = sg_src_tmp->length - in_offset;
-
- if (seg_size > (size - count))
- seg_size = (size = count);
-
- memcpy(sg_virt(sg_dst_tmp) + out_offset,
- sg_virt(sg_src_tmp) + in_offset,
- seg_size);
-
- in_offset += seg_size;
- out_offset += seg_size;
- count += seg_size;
-
- if (in_offset >= sg_src_tmp->length) {
- sg_src_tmp = sg_next(sg_src_tmp);
- in_offset = 0;
- }
-
- if (out_offset >= sg_dst_tmp->length) {
- sg_dst_tmp = sg_next(sg_dst_tmp);
- out_offset = 0;
- }
- }
-}
-
-/**
- * sep_oddball_pages -
- * @sep: pointer to struct sep_device
- * @sg: pointer to struct scatterlist - buffer to check
- * @size: total data size
- * @blocksize: minimum block size; must be multiples of this size
- * @to_copy: 1 means do copy, 0 means do not copy
- * @new_sg: pointer to location to put pointer to new sg area
- * @returns: 1 if new scatterlist is needed; 0 if not needed;
- * error value if operation failed
- *
- * The SEP device requires all pages to be multiples of the
- * minimum block size appropriate for the operation
- * This function check all pages; if any are oddball sizes
- * (not multiple of block sizes), it creates a new scatterlist.
- * If the to_copy parameter is set to 1, then a scatter list
- * copy is performed. The pointer to the new scatterlist is
- * put into the address supplied by the new_sg parameter; if
- * no new scatterlist is needed, then a NULL is put into
- * the location at new_sg.
- *
- */
-static int sep_oddball_pages(
- struct sep_device *sep,
- struct scatterlist *sg,
- size_t data_size,
- u32 block_size,
- struct scatterlist **new_sg,
- u32 do_copy)
-{
- struct scatterlist *sg_temp;
- u32 flag;
- u32 nbr_pages, page_count;
-
- dev_dbg(&sep->pdev->dev, "sep oddball\n");
- if ((sg == NULL) || (data_size == 0) || (data_size < block_size))
- return 0;
-
- dev_dbg(&sep->pdev->dev, "sep oddball not null\n");
- flag = 0;
- nbr_pages = 0;
- page_count = 0;
- sg_temp = sg;
-
- while (sg_temp) {
- nbr_pages += 1;
- sg_temp = sg_next(sg_temp);
- }
-
- sg_temp = sg;
- while ((sg_temp) && (flag == 0)) {
- page_count += 1;
- if (sg_temp->length % block_size)
- flag = 1;
- else
- sg_temp = sg_next(sg_temp);
- }
-
- /* Do not process if last (or only) page is oddball */
- if (nbr_pages == page_count)
- flag = 0;
-
- if (flag) {
- dev_dbg(&sep->pdev->dev, "sep oddball processing\n");
- *new_sg = sep_alloc_sg_buf(sep, data_size, block_size);
- if (*new_sg == NULL) {
- dev_warn(&sep->pdev->dev, "cannot allocate new sg\n");
- return -ENOMEM;
- }
-
- if (do_copy)
- sep_copy_sg(sep, sg, *new_sg, data_size);
-
- return 1;
- } else {
- return 0;
- }
-}
-
-/**
- * sep_copy_offset_sg -
- * @sep: pointer to struct sep_device;
- * @sg: pointer to struct scatterlist
- * @offset: offset into scatterlist memory
- * @dst: place to put data
- * @len: length of data
- * @returns: number of bytes copies
- *
- * This copies data from scatterlist buffer
- * offset from beginning - it is needed for
- * handling tail data in hash
- */
-static size_t sep_copy_offset_sg(
- struct sep_device *sep,
- struct scatterlist *sg,
- u32 offset,
- void *dst,
- u32 len)
-{
- size_t page_start;
- size_t page_end;
- size_t offset_within_page;
- size_t length_within_page;
- size_t length_remaining;
- size_t current_offset;
-
- /* Find which page is beginning of segment */
- page_start = 0;
- page_end = sg->length;
- while ((sg) && (offset > page_end)) {
- page_start += sg->length;
- sg = sg_next(sg);
- if (sg)
- page_end += sg->length;
- }
-
- if (sg == NULL)
- return -ENOMEM;
-
- offset_within_page = offset - page_start;
- if ((sg->length - offset_within_page) >= len) {
- /* All within this page */
- memcpy(dst, sg_virt(sg) + offset_within_page, len);
- return len;
- } else {
- /* Scattered multiple pages */
- current_offset = 0;
- length_remaining = len;
- while ((sg) && (current_offset < len)) {
- length_within_page = sg->length - offset_within_page;
- if (length_within_page >= length_remaining) {
- memcpy(dst+current_offset,
- sg_virt(sg) + offset_within_page,
- length_remaining);
- length_remaining = 0;
- current_offset = len;
- } else {
- memcpy(dst+current_offset,
- sg_virt(sg) + offset_within_page,
- length_within_page);
- length_remaining -= length_within_page;
- current_offset += length_within_page;
- offset_within_page = 0;
- sg = sg_next(sg);
- }
- }
-
- if (sg == NULL)
- return -ENOMEM;
- }
- return len;
-}
-
-/**
- * partial_overlap -
- * @src_ptr: source pointer
- * @dst_ptr: destination pointer
- * @nbytes: number of bytes
- * @returns: 0 for success; -1 for failure
- * We cannot have any partial overlap. Total overlap
- * where src is the same as dst is okay
- */
-static int partial_overlap(void *src_ptr, void *dst_ptr, u32 nbytes)
-{
- /* Check for partial overlap */
- if (src_ptr != dst_ptr) {
- if (src_ptr < dst_ptr) {
- if ((src_ptr + nbytes) > dst_ptr)
- return -EINVAL;
- } else {
- if ((dst_ptr + nbytes) > src_ptr)
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-/* Debug - prints only if DEBUG is defined */
-static void sep_dump_ivs(struct ablkcipher_request *req, char *reason)
-
- {
- unsigned char *cptr;
- struct sep_aes_internal_context *aes_internal;
- struct sep_des_internal_context *des_internal;
- int ct1;
-
- struct this_task_ctx *ta_ctx;
- struct crypto_ablkcipher *tfm;
- struct sep_system_ctx *sctx;
-
- ta_ctx = ablkcipher_request_ctx(req);
- tfm = crypto_ablkcipher_reqtfm(req);
- sctx = crypto_ablkcipher_ctx(tfm);
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "IV DUMP - %s\n", reason);
- if ((ta_ctx->current_request == DES_CBC) &&
- (ta_ctx->des_opmode == SEP_DES_CBC)) {
-
- des_internal = (struct sep_des_internal_context *)
- sctx->des_private_ctx.ctx_buf;
- /* print vendor */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep - vendor iv for DES\n");
- cptr = (unsigned char *)des_internal->iv_context;
- for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "%02x\n", *(cptr + ct1));
-
- /* print walk */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep - walk from kernel crypto iv for DES\n");
- cptr = (unsigned char *)ta_ctx->walk.iv;
- for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "%02x\n", *(cptr + ct1));
- } else if ((ta_ctx->current_request == AES_CBC) &&
- (ta_ctx->aes_opmode == SEP_AES_CBC)) {
-
- aes_internal = (struct sep_aes_internal_context *)
- sctx->aes_private_ctx.cbuff;
- /* print vendor */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep - vendor iv for AES\n");
- cptr = (unsigned char *)aes_internal->aes_ctx_iv;
- for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "%02x\n", *(cptr + ct1));
-
- /* print walk */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep - walk from kernel crypto iv for AES\n");
- cptr = (unsigned char *)ta_ctx->walk.iv;
- for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "%02x\n", *(cptr + ct1));
- }
-}
-
-/**
- * RFC2451: Weak key check
- * Returns: 1 (weak), 0 (not weak)
- */
-static int sep_weak_key(const u8 *key, unsigned int keylen)
-{
- static const u8 parity[] = {
- 8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8,
- 0, 8, 8, 0, 8, 0, 0, 8, 8,
- 0, 0, 8, 0, 8, 8, 3,
- 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
- 8, 0, 0, 8, 0, 8, 8, 0, 0,
- 8, 8, 0, 8, 0, 0, 8,
- 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
- 8, 0, 0, 8, 0, 8, 8, 0, 0,
- 8, 8, 0, 8, 0, 0, 8,
- 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
- 0, 8, 8, 0, 8, 0, 0, 8, 8,
- 0, 0, 8, 0, 8, 8, 0,
- 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
- 8, 0, 0, 8, 0, 8, 8, 0, 0,
- 8, 8, 0, 8, 0, 0, 8,
- 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
- 0, 8, 8, 0, 8, 0, 0, 8, 8,
- 0, 0, 8, 0, 8, 8, 0,
- 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
- 0, 8, 8, 0, 8, 0, 0, 8, 8,
- 0, 0, 8, 0, 8, 8, 0,
- 4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
- 8, 5, 0, 8, 0, 8, 8, 0, 0,
- 8, 8, 0, 8, 0, 6, 8,
- };
-
- u32 n, w;
-
- n = parity[key[0]]; n <<= 4;
- n |= parity[key[1]]; n <<= 4;
- n |= parity[key[2]]; n <<= 4;
- n |= parity[key[3]]; n <<= 4;
- n |= parity[key[4]]; n <<= 4;
- n |= parity[key[5]]; n <<= 4;
- n |= parity[key[6]]; n <<= 4;
- n |= parity[key[7]];
- w = 0x88888888L;
-
- /* 1 in 10^10 keys passes this test */
- if (!((n - (w >> 3)) & w)) {
- if (n < 0x41415151) {
- if (n < 0x31312121) {
- if (n < 0x14141515) {
- /* 01 01 01 01 01 01 01 01 */
- if (n == 0x11111111)
- goto weak;
- /* 01 1F 01 1F 01 0E 01 0E */
- if (n == 0x13131212)
- goto weak;
- } else {
- /* 01 E0 01 E0 01 F1 01 F1 */
- if (n == 0x14141515)
- goto weak;
- /* 01 FE 01 FE 01 FE 01 FE */
- if (n == 0x16161616)
- goto weak;
- }
- } else {
- if (n < 0x34342525) {
- /* 1F 01 1F 01 0E 01 0E 01 */
- if (n == 0x31312121)
- goto weak;
- /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
- if (n == 0x33332222)
- goto weak;
- } else {
- /* 1F E0 1F E0 0E F1 0E F1 */
- if (n == 0x34342525)
- goto weak;
- /* 1F FE 1F FE 0E FE 0E FE */
- if (n == 0x36362626)
- goto weak;
- }
- }
- } else {
- if (n < 0x61616161) {
- if (n < 0x44445555) {
- /* E0 01 E0 01 F1 01 F1 01 */
- if (n == 0x41415151)
- goto weak;
- /* E0 1F E0 1F F1 0E F1 0E */
- if (n == 0x43435252)
- goto weak;
- } else {
- /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
- if (n == 0x44445555)
- goto weak;
- /* E0 FE E0 FE F1 FE F1 FE */
- if (n == 0x46465656)
- goto weak;
- }
- } else {
- if (n < 0x64646565) {
- /* FE 01 FE 01 FE 01 FE 01 */
- if (n == 0x61616161)
- goto weak;
- /* FE 1F FE 1F FE 0E FE 0E */
- if (n == 0x63636262)
- goto weak;
- } else {
- /* FE E0 FE E0 FE F1 FE F1 */
- if (n == 0x64646565)
- goto weak;
- /* FE FE FE FE FE FE FE FE */
- if (n == 0x66666666)
- goto weak;
- }
- }
- }
- }
- return 0;
-weak:
- return 1;
-}
-/**
- * sep_sg_nents
- */
-static u32 sep_sg_nents(struct scatterlist *sg)
-{
- u32 ct1 = 0;
-
- while (sg) {
- ct1 += 1;
- sg = sg_next(sg);
- }
-
- return ct1;
-}
-
-/**
- * sep_start_msg -
- * @ta_ctx: pointer to struct this_task_ctx
- * @returns: offset to place for the next word in the message
- * Set up pointer in message pool for new message
- */
-static u32 sep_start_msg(struct this_task_ctx *ta_ctx)
-{
- u32 *word_ptr;
-
- ta_ctx->msg_len_words = 2;
- ta_ctx->msgptr = ta_ctx->msg;
- memset(ta_ctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
- ta_ctx->msgptr += sizeof(u32) * 2;
- word_ptr = (u32 *)ta_ctx->msgptr;
- *word_ptr = SEP_START_MSG_TOKEN;
- return sizeof(u32) * 2;
-}
-
-/**
- * sep_end_msg -
- * @ta_ctx: pointer to struct this_task_ctx
- * @messages_offset: current message offset
- * Returns: 0 for success; <0 otherwise
- * End message; set length and CRC; and
- * send interrupt to the SEP
- */
-static void sep_end_msg(struct this_task_ctx *ta_ctx, u32 msg_offset)
-{
- u32 *word_ptr;
- /* Msg size goes into msg after token */
- ta_ctx->msg_len_words = msg_offset / sizeof(u32) + 1;
- word_ptr = (u32 *)ta_ctx->msgptr;
- word_ptr += 1;
- *word_ptr = ta_ctx->msg_len_words;
-
- /* CRC (currently 0) goes at end of msg */
- word_ptr = (u32 *)(ta_ctx->msgptr + msg_offset);
- *word_ptr = 0;
-}
-
-/**
- * sep_start_inbound_msg -
- * @ta_ctx: pointer to struct this_task_ctx
- * @msg_offset: offset to place for the next word in the message
- * @returns: 0 for success; error value for failure
- * Set up pointer in message pool for inbound message
- */
-static u32 sep_start_inbound_msg(struct this_task_ctx *ta_ctx, u32 *msg_offset)
-{
- u32 *word_ptr;
- u32 token;
- u32 error = SEP_OK;
-
- *msg_offset = sizeof(u32) * 2;
- word_ptr = (u32 *)ta_ctx->msgptr;
- token = *word_ptr;
- ta_ctx->msg_len_words = *(word_ptr + 1);
-
- if (token != SEP_START_MSG_TOKEN) {
- error = SEP_INVALID_START;
- goto end_function;
- }
-
-end_function:
-
- return error;
-}
-
-/**
- * sep_write_msg -
- * @ta_ctx: pointer to struct this_task_ctx
- * @in_addr: pointer to start of parameter
- * @size: size of parameter to copy (in bytes)
- * @max_size: size to move up offset; SEP mesg is in word sizes
- * @msg_offset: pointer to current offset (is updated)
- * @byte_array: flag ti indicate whether endian must be changed
- * Copies data into the message area from caller
- */
-static void sep_write_msg(struct this_task_ctx *ta_ctx, void *in_addr,
- u32 size, u32 max_size, u32 *msg_offset, u32 byte_array)
-{
- u32 *word_ptr;
- void *void_ptr;
-
- void_ptr = ta_ctx->msgptr + *msg_offset;
- word_ptr = (u32 *)void_ptr;
- memcpy(void_ptr, in_addr, size);
- *msg_offset += max_size;
-
- /* Do we need to manipulate endian? */
- if (byte_array) {
- u32 i;
-
- for (i = 0; i < ((size + 3) / 4); i += 1)
- *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i));
- }
-}
-
-/**
- * sep_make_header
- * @ta_ctx: pointer to struct this_task_ctx
- * @msg_offset: pointer to current offset (is updated)
- * @op_code: op code to put into message
- * Puts op code into message and updates offset
- */
-static void sep_make_header(struct this_task_ctx *ta_ctx, u32 *msg_offset,
- u32 op_code)
-{
- u32 *word_ptr;
-
- *msg_offset = sep_start_msg(ta_ctx);
- word_ptr = (u32 *)(ta_ctx->msgptr + *msg_offset);
- *word_ptr = op_code;
- *msg_offset += sizeof(u32);
-}
-
-
-
-/**
- * sep_read_msg -
- * @ta_ctx: pointer to struct this_task_ctx
- * @in_addr: pointer to start of parameter
- * @size: size of parameter to copy (in bytes)
- * @max_size: size to move up offset; SEP mesg is in word sizes
- * @msg_offset: pointer to current offset (is updated)
- * @byte_array: flag ti indicate whether endian must be changed
- * Copies data out of the message area to caller
- */
-static void sep_read_msg(struct this_task_ctx *ta_ctx, void *in_addr,
- u32 size, u32 max_size, u32 *msg_offset, u32 byte_array)
-{
- u32 *word_ptr;
- void *void_ptr;
-
- void_ptr = ta_ctx->msgptr + *msg_offset;
- word_ptr = (u32 *)void_ptr;
-
- /* Do we need to manipulate endian? */
- if (byte_array) {
- u32 i;
-
- for (i = 0; i < ((size + 3) / 4); i += 1)
- *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i));
- }
-
- memcpy(in_addr, void_ptr, size);
- *msg_offset += max_size;
-}
-
-/**
- * sep_verify_op -
- * @ta_ctx: pointer to struct this_task_ctx
- * @op_code: expected op_code
- * @msg_offset: pointer to current offset (is updated)
- * @returns: 0 for success; error for failure
- */
-static u32 sep_verify_op(struct this_task_ctx *ta_ctx, u32 op_code,
- u32 *msg_offset)
-{
- u32 error;
- u32 in_ary[2];
-
- struct sep_device *sep = ta_ctx->sep_used;
-
- dev_dbg(&sep->pdev->dev, "dumping return message\n");
- error = sep_start_inbound_msg(ta_ctx, msg_offset);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "sep_start_inbound_msg error\n");
- return error;
- }
-
- sep_read_msg(ta_ctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2,
- msg_offset, 0);
-
- if (in_ary[0] != op_code) {
- dev_warn(&sep->pdev->dev,
- "sep got back wrong opcode\n");
- dev_warn(&sep->pdev->dev,
- "got back %x; expected %x\n",
- in_ary[0], op_code);
- return SEP_WRONG_OPCODE;
- }
-
- if (in_ary[1] != SEP_OK) {
- dev_warn(&sep->pdev->dev,
- "sep execution error\n");
- dev_warn(&sep->pdev->dev,
- "got back %x; expected %x\n",
- in_ary[1], SEP_OK);
- return in_ary[0];
- }
-
-return 0;
-}
-
-/**
- * sep_read_context -
- * @ta_ctx: pointer to struct this_task_ctx
- * @msg_offset: point to current place in SEP msg; is updated
- * @dst: pointer to place to put the context
- * @len: size of the context structure (differs for crypro/hash)
- * This function reads the context from the msg area
- * There is a special way the vendor needs to have the maximum
- * length calculated so that the msg_offset is updated properly;
- * it skips over some words in the msg area depending on the size
- * of the context
- */
-static void sep_read_context(struct this_task_ctx *ta_ctx, u32 *msg_offset,
- void *dst, u32 len)
-{
- u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32);
-
- sep_read_msg(ta_ctx, dst, len, max_length, msg_offset, 0);
-}
-
-/**
- * sep_write_context -
- * @ta_ctx: pointer to struct this_task_ctx
- * @msg_offset: point to current place in SEP msg; is updated
- * @src: pointer to the current context
- * @len: size of the context structure (differs for crypro/hash)
- * This function writes the context to the msg area
- * There is a special way the vendor needs to have the maximum
- * length calculated so that the msg_offset is updated properly;
- * it skips over some words in the msg area depending on the size
- * of the context
- */
-static void sep_write_context(struct this_task_ctx *ta_ctx, u32 *msg_offset,
- void *src, u32 len)
-{
- u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32);
-
- sep_write_msg(ta_ctx, src, len, max_length, msg_offset, 0);
-}
-
-/**
- * sep_clear_out -
- * @ta_ctx: pointer to struct this_task_ctx
- * Clear out crypto related values in sep device structure
- * to enable device to be used by anyone; either kernel
- * crypto or userspace app via middleware
- */
-static void sep_clear_out(struct this_task_ctx *ta_ctx)
-{
- if (ta_ctx->src_sg_hold) {
- sep_free_sg_buf(ta_ctx->src_sg_hold);
- ta_ctx->src_sg_hold = NULL;
- }
-
- if (ta_ctx->dst_sg_hold) {
- sep_free_sg_buf(ta_ctx->dst_sg_hold);
- ta_ctx->dst_sg_hold = NULL;
- }
-
- ta_ctx->src_sg = NULL;
- ta_ctx->dst_sg = NULL;
-
- sep_free_dma_table_data_handler(ta_ctx->sep_used, &ta_ctx->dma_ctx);
-
- if (ta_ctx->i_own_sep) {
- /**
- * The following unlocks the sep and makes it available
- * to any other application
- * First, null out crypto entries in sep before releasing it
- */
- ta_ctx->sep_used->current_hash_req = NULL;
- ta_ctx->sep_used->current_cypher_req = NULL;
- ta_ctx->sep_used->current_request = 0;
- ta_ctx->sep_used->current_hash_stage = 0;
- ta_ctx->sep_used->ta_ctx = NULL;
- ta_ctx->sep_used->in_kernel = 0;
-
- ta_ctx->call_status.status = 0;
-
- /* Remove anything confidential */
- memset(ta_ctx->sep_used->shared_addr, 0,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- sep_queue_status_remove(ta_ctx->sep_used, &ta_ctx->queue_elem);
-
-#ifdef SEP_ENABLE_RUNTIME_PM
- ta_ctx->sep_used->in_use = 0;
- pm_runtime_mark_last_busy(&ta_ctx->sep_used->pdev->dev);
- pm_runtime_put_autosuspend(&ta_ctx->sep_used->pdev->dev);
-#endif
-
- clear_bit(SEP_WORKING_LOCK_BIT,
- &ta_ctx->sep_used->in_use_flags);
- ta_ctx->sep_used->pid_doing_transaction = 0;
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "[PID%d] waking up next transaction\n",
- current->pid);
-
- clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
- &ta_ctx->sep_used->in_use_flags);
- wake_up(&ta_ctx->sep_used->event_transactions);
-
- ta_ctx->i_own_sep = 0;
- }
-}
-
-/**
- * Release crypto infrastructure from EINPROGRESS and
- * clear sep_dev so that SEP is available to anyone
- */
-static void sep_crypto_release(struct sep_system_ctx *sctx,
- struct this_task_ctx *ta_ctx, u32 error)
-{
- struct ahash_request *hash_req = ta_ctx->current_hash_req;
- struct ablkcipher_request *cypher_req =
- ta_ctx->current_cypher_req;
- struct sep_device *sep = ta_ctx->sep_used;
-
- sep_clear_out(ta_ctx);
-
- /**
- * This may not yet exist depending when we
- * chose to bail out. If it does exist, set
- * it to 1
- */
- if (ta_ctx->are_we_done_yet != NULL)
- *ta_ctx->are_we_done_yet = 1;
-
- if (cypher_req != NULL) {
- if ((sctx->key_sent == 1) ||
- ((error != 0) && (error != -EINPROGRESS))) {
- if (cypher_req->base.complete == NULL) {
- dev_dbg(&sep->pdev->dev,
- "release is null for cypher!");
- } else {
- cypher_req->base.complete(
- &cypher_req->base, error);
- }
- }
- }
-
- if (hash_req != NULL) {
- if (hash_req->base.complete == NULL) {
- dev_dbg(&sep->pdev->dev,
- "release is null for hash!");
- } else {
- hash_req->base.complete(
- &hash_req->base, error);
- }
- }
-}
-
-/**
- * This is where we grab the sep itself and tell it to do something.
- * It will sleep if the sep is currently busy
- * and it will return 0 if sep is now ours; error value if there
- * were problems
- */
-static int sep_crypto_take_sep(struct this_task_ctx *ta_ctx)
-{
- struct sep_device *sep = ta_ctx->sep_used;
- int result;
- struct sep_msgarea_hdr *my_msg_header;
-
- my_msg_header = (struct sep_msgarea_hdr *)ta_ctx->msg;
-
- /* add to status queue */
- ta_ctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode,
- ta_ctx->nbytes, current->pid,
- current->comm, sizeof(current->comm));
-
- if (!ta_ctx->queue_elem) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] updating queue status error\n", current->pid);
- return -EINVAL;
- }
-
- /* get the device; this can sleep */
- result = sep_wait_transaction(sep);
- if (result)
- return result;
-
- if (sep_dev->power_save_setup == 1)
- pm_runtime_get_sync(&sep_dev->pdev->dev);
-
- /* Copy in the message */
- memcpy(sep->shared_addr, ta_ctx->msg,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- /* Copy in the dcb information if there is any */
- if (ta_ctx->dcb_region) {
- result = sep_activate_dcb_dmatables_context(sep,
- &ta_ctx->dcb_region, &ta_ctx->dmatables_region,
- ta_ctx->dma_ctx);
- if (result)
- return result;
- }
-
- /* Mark the device so we know how to finish the job in the tasklet */
- if (ta_ctx->current_hash_req)
- sep->current_hash_req = ta_ctx->current_hash_req;
- else
- sep->current_cypher_req = ta_ctx->current_cypher_req;
-
- sep->current_request = ta_ctx->current_request;
- sep->current_hash_stage = ta_ctx->current_hash_stage;
- sep->ta_ctx = ta_ctx;
- sep->in_kernel = 1;
- ta_ctx->i_own_sep = 1;
-
- /* need to set bit first to avoid race condition with interrupt */
- set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &ta_ctx->call_status.status);
-
- result = sep_send_command_handler(sep);
-
- dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n",
- current->pid);
-
- if (!result)
- dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n",
- current->pid);
- else {
- dev_dbg(&sep->pdev->dev, "[PID%d]: cant send command\n",
- current->pid);
- clear_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &ta_ctx->call_status.status);
- }
-
- return result;
-}
-
-/**
- * This function sets things up for a crypto data block process
- * This does all preparation, but does not try to grab the
- * sep
- * @req: pointer to struct ablkcipher_request
- * returns: 0 if all went well, non zero if error
- */
-static int sep_crypto_block_data(struct ablkcipher_request *req)
-{
-
- int int_error;
- u32 msg_offset;
- static u32 msg[10];
- void *src_ptr;
- void *dst_ptr;
-
- static char small_buf[100];
- ssize_t copy_result;
- int result;
-
- struct scatterlist *new_sg;
- struct this_task_ctx *ta_ctx;
- struct crypto_ablkcipher *tfm;
- struct sep_system_ctx *sctx;
-
- struct sep_des_internal_context *des_internal;
- struct sep_aes_internal_context *aes_internal;
-
- ta_ctx = ablkcipher_request_ctx(req);
- tfm = crypto_ablkcipher_reqtfm(req);
- sctx = crypto_ablkcipher_ctx(tfm);
-
- /* start the walk on scatterlists */
- ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep crypto block data size of %x\n",
- req->nbytes);
-
- int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
- if (int_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
- int_error);
- return -ENOMEM;
- }
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "crypto block: src is %lx dst is %lx\n",
- (unsigned long)req->src, (unsigned long)req->dst);
-
- /* Make sure all pages are even block */
- int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
- req->nbytes, ta_ctx->walk.blocksize, &new_sg, 1);
-
- if (int_error < 0) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page error\n");
- return int_error;
- } else if (int_error == 1) {
- ta_ctx->src_sg = new_sg;
- ta_ctx->src_sg_hold = new_sg;
- } else {
- ta_ctx->src_sg = req->src;
- ta_ctx->src_sg_hold = NULL;
- }
-
- int_error = sep_oddball_pages(ta_ctx->sep_used, req->dst,
- req->nbytes, ta_ctx->walk.blocksize, &new_sg, 0);
-
- if (int_error < 0) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
- int_error);
- return int_error;
- } else if (int_error == 1) {
- ta_ctx->dst_sg = new_sg;
- ta_ctx->dst_sg_hold = new_sg;
- } else {
- ta_ctx->dst_sg = req->dst;
- ta_ctx->dst_sg_hold = NULL;
- }
-
- /* set nbytes for queue status */
- ta_ctx->nbytes = req->nbytes;
-
- /* Key already done; this is for data */
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending data\n");
-
- /* check for valid data and proper spacing */
- src_ptr = sg_virt(ta_ctx->src_sg);
- dst_ptr = sg_virt(ta_ctx->dst_sg);
-
- if (!src_ptr || !dst_ptr ||
- (ta_ctx->current_cypher_req->nbytes %
- crypto_ablkcipher_blocksize(tfm))) {
-
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "cipher block size odd\n");
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "cipher block size is %x\n",
- crypto_ablkcipher_blocksize(tfm));
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "cipher data size is %x\n",
- ta_ctx->current_cypher_req->nbytes);
- return -EINVAL;
- }
-
- if (partial_overlap(src_ptr, dst_ptr,
- ta_ctx->current_cypher_req->nbytes)) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "block partial overlap\n");
- return -EINVAL;
- }
-
- /* Put together the message */
- sep_make_header(ta_ctx, &msg_offset, ta_ctx->block_opcode);
-
- /* If des, and size is 1 block, put directly in msg */
- if ((ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) &&
- (req->nbytes == crypto_ablkcipher_blocksize(tfm))) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "writing out one block des\n");
-
- copy_result = sg_copy_to_buffer(
- ta_ctx->src_sg, sep_sg_nents(ta_ctx->src_sg),
- small_buf, crypto_ablkcipher_blocksize(tfm));
-
- if (copy_result != crypto_ablkcipher_blocksize(tfm)) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "des block copy failed\n");
- return -ENOMEM;
- }
-
- /* Put data into message */
- sep_write_msg(ta_ctx, small_buf,
- crypto_ablkcipher_blocksize(tfm),
- crypto_ablkcipher_blocksize(tfm) * 2,
- &msg_offset, 1);
-
- /* Put size into message */
- sep_write_msg(ta_ctx, &req->nbytes,
- sizeof(u32), sizeof(u32), &msg_offset, 0);
- } else {
- /* Otherwise, fill out dma tables */
- ta_ctx->dcb_input_data.app_in_address = src_ptr;
- ta_ctx->dcb_input_data.data_in_size = req->nbytes;
- ta_ctx->dcb_input_data.app_out_address = dst_ptr;
- ta_ctx->dcb_input_data.block_size =
- crypto_ablkcipher_blocksize(tfm);
- ta_ctx->dcb_input_data.tail_block_size = 0;
- ta_ctx->dcb_input_data.is_applet = 0;
- ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
- ta_ctx->dcb_input_data.dst_sg = ta_ctx->dst_sg;
-
- result = sep_create_dcb_dmatables_context_kernel(
- ta_ctx->sep_used,
- &ta_ctx->dcb_region,
- &ta_ctx->dmatables_region,
- &ta_ctx->dma_ctx,
- &ta_ctx->dcb_input_data,
- 1);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "crypto dma table create failed\n");
- return -EINVAL;
- }
-
- /* Portion of msg is nulled (no data) */
- msg[0] = (u32)0;
- msg[1] = (u32)0;
- msg[2] = (u32)0;
- msg[3] = (u32)0;
- msg[4] = (u32)0;
- sep_write_msg(ta_ctx, (void *)msg, sizeof(u32) * 5,
- sizeof(u32) * 5, &msg_offset, 0);
- }
-
- /**
- * Before we write the message, we need to overwrite the
- * vendor's IV with the one from our own ablkcipher walk
- * iv because this is needed for dm-crypt
- */
- sep_dump_ivs(req, "sending data block to sep\n");
- if ((ta_ctx->current_request == DES_CBC) &&
- (ta_ctx->des_opmode == SEP_DES_CBC)) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "overwrite vendor iv on DES\n");
- des_internal = (struct sep_des_internal_context *)
- sctx->des_private_ctx.ctx_buf;
- memcpy((void *)des_internal->iv_context,
- ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
- } else if ((ta_ctx->current_request == AES_CBC) &&
- (ta_ctx->aes_opmode == SEP_AES_CBC)) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "overwrite vendor iv on AES\n");
- aes_internal = (struct sep_aes_internal_context *)
- sctx->aes_private_ctx.cbuff;
- memcpy((void *)aes_internal->aes_ctx_iv,
- ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
- }
-
- /* Write context into message */
- if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
- sep_write_context(ta_ctx, &msg_offset,
- &sctx->des_private_ctx,
- sizeof(struct sep_des_private_context));
- } else {
- sep_write_context(ta_ctx, &msg_offset,
- &sctx->aes_private_ctx,
- sizeof(struct sep_aes_private_context));
- }
-
- /* conclude message */
- sep_end_msg(ta_ctx, msg_offset);
-
- /* Parent (caller) is now ready to tell the sep to do ahead */
- return 0;
-}
-
-
-/**
- * This function sets things up for a crypto key submit process
- * This does all preparation, but does not try to grab the
- * sep
- * @req: pointer to struct ablkcipher_request
- * returns: 0 if all went well, non zero if error
- */
-static int sep_crypto_send_key(struct ablkcipher_request *req)
-{
-
- int int_error;
- u32 msg_offset;
- static u32 msg[10];
-
- u32 max_length;
- struct this_task_ctx *ta_ctx;
- struct crypto_ablkcipher *tfm;
- struct sep_system_ctx *sctx;
-
- ta_ctx = ablkcipher_request_ctx(req);
- tfm = crypto_ablkcipher_reqtfm(req);
- sctx = crypto_ablkcipher_ctx(tfm);
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending key\n");
-
- /* start the walk on scatterlists */
- ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep crypto block data size of %x\n", req->nbytes);
-
- int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
- if (int_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
- int_error);
- return -ENOMEM;
- }
-
- /* check iv */
- if ((ta_ctx->current_request == DES_CBC) &&
- (ta_ctx->des_opmode == SEP_DES_CBC)) {
- if (!ta_ctx->walk.iv) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
- return -EINVAL;
- }
-
- memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
- }
-
- if ((ta_ctx->current_request == AES_CBC) &&
- (ta_ctx->aes_opmode == SEP_AES_CBC)) {
- if (!ta_ctx->walk.iv) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
- return -EINVAL;
- }
-
- memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
- }
-
- /* put together message to SEP */
- /* Start with op code */
- sep_make_header(ta_ctx, &msg_offset, ta_ctx->init_opcode);
-
- /* now deal with IV */
- if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
- if (ta_ctx->des_opmode == SEP_DES_CBC) {
- sep_write_msg(ta_ctx, ta_ctx->iv,
- SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4,
- &msg_offset, 1);
- } else {
- /* Skip if ECB */
- msg_offset += 4 * sizeof(u32);
- }
- } else {
- max_length = ((SEP_AES_IV_SIZE_BYTES + 3) /
- sizeof(u32)) * sizeof(u32);
- if (ta_ctx->aes_opmode == SEP_AES_CBC) {
- sep_write_msg(ta_ctx, ta_ctx->iv,
- SEP_AES_IV_SIZE_BYTES, max_length,
- &msg_offset, 1);
- } else {
- /* Skip if ECB */
- msg_offset += max_length;
- }
- }
-
- /* load the key */
- if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
- sep_write_msg(ta_ctx, (void *)&sctx->key.des.key1,
- sizeof(u32) * 8, sizeof(u32) * 8,
- &msg_offset, 1);
-
- msg[0] = (u32)sctx->des_nbr_keys;
- msg[1] = (u32)ta_ctx->des_encmode;
- msg[2] = (u32)ta_ctx->des_opmode;
-
- sep_write_msg(ta_ctx, (void *)msg,
- sizeof(u32) * 3, sizeof(u32) * 3,
- &msg_offset, 0);
- } else {
- sep_write_msg(ta_ctx, (void *)&sctx->key.aes,
- sctx->keylen,
- SEP_AES_MAX_KEY_SIZE_BYTES,
- &msg_offset, 1);
-
- msg[0] = (u32)sctx->aes_key_size;
- msg[1] = (u32)ta_ctx->aes_encmode;
- msg[2] = (u32)ta_ctx->aes_opmode;
- msg[3] = (u32)0; /* Secret key is not used */
- sep_write_msg(ta_ctx, (void *)msg,
- sizeof(u32) * 4, sizeof(u32) * 4,
- &msg_offset, 0);
- }
-
- /* conclude message */
- sep_end_msg(ta_ctx, msg_offset);
-
- /* Parent (caller) is now ready to tell the sep to do ahead */
- return 0;
-}
-
-
-/* This needs to be run as a work queue as it can be put asleep */
-static void sep_crypto_block(void *data)
-{
- unsigned long end_time;
-
- int result;
-
- struct ablkcipher_request *req;
- struct this_task_ctx *ta_ctx;
- struct crypto_ablkcipher *tfm;
- struct sep_system_ctx *sctx;
- int are_we_done_yet;
-
- req = (struct ablkcipher_request *)data;
- ta_ctx = ablkcipher_request_ctx(req);
- tfm = crypto_ablkcipher_reqtfm(req);
- sctx = crypto_ablkcipher_ctx(tfm);
-
- ta_ctx->are_we_done_yet = &are_we_done_yet;
-
- pr_debug("sep_crypto_block\n");
- pr_debug("tfm is %p sctx is %p ta_ctx is %p\n",
- tfm, sctx, ta_ctx);
- pr_debug("key_sent is %d\n", sctx->key_sent);
-
- /* do we need to send the key */
- if (sctx->key_sent == 0) {
- are_we_done_yet = 0;
- result = sep_crypto_send_key(req); /* prep to send key */
- if (result != 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "could not prep key %x\n", result);
- sep_crypto_release(sctx, ta_ctx, result);
- return;
- }
-
- result = sep_crypto_take_sep(ta_ctx);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_crypto_take_sep for key send failed\n");
- sep_crypto_release(sctx, ta_ctx, result);
- return;
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) &&
- (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "Send key job never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
- /* Set the key sent variable so this can be skipped later */
- sctx->key_sent = 1;
- }
-
- /* Key sent (or maybe not if we did not have to), now send block */
- are_we_done_yet = 0;
-
- result = sep_crypto_block_data(req);
-
- if (result != 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "could prep not send block %x\n", result);
- sep_crypto_release(sctx, ta_ctx, result);
- return;
- }
-
- result = sep_crypto_take_sep(ta_ctx);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_crypto_take_sep for block send failed\n");
- sep_crypto_release(sctx, ta_ctx, result);
- return;
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "Send block job never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
- /* That's it; entire thing done, get out of queue */
-
- pr_debug("crypto_block leaving\n");
- pr_debug("tfm is %p sctx is %p ta_ctx is %p\n", tfm, sctx, ta_ctx);
-}
-
-/**
- * Post operation (after interrupt) for crypto block
- */
-static u32 crypto_post_op(struct sep_device *sep)
-{
- /* HERE */
- u32 u32_error;
- u32 msg_offset;
-
- ssize_t copy_result;
- static char small_buf[100];
-
- struct ablkcipher_request *req;
- struct this_task_ctx *ta_ctx;
- struct sep_system_ctx *sctx;
- struct crypto_ablkcipher *tfm;
-
- struct sep_des_internal_context *des_internal;
- struct sep_aes_internal_context *aes_internal;
-
- if (!sep->current_cypher_req)
- return -EINVAL;
-
- /* hold req since we need to submit work after clearing sep */
- req = sep->current_cypher_req;
-
- ta_ctx = ablkcipher_request_ctx(sep->current_cypher_req);
- tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req);
- sctx = crypto_ablkcipher_ctx(tfm);
-
- pr_debug("crypto_post op\n");
- pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
- sctx->key_sent, tfm, sctx, ta_ctx);
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op\n");
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op message dump\n");
-
- /* first bring msg from shared area to local area */
- memcpy(ta_ctx->msg, sep->shared_addr,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- /* Is this the result of performing init (key to SEP */
- if (sctx->key_sent == 0) {
-
- /* Did SEP do it okay */
- u32_error = sep_verify_op(ta_ctx, ta_ctx->init_opcode,
- &msg_offset);
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "aes init error %x\n", u32_error);
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* Read Context */
- if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->des_private_ctx,
- sizeof(struct sep_des_private_context));
- } else {
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->aes_private_ctx,
- sizeof(struct sep_aes_private_context));
- }
-
- sep_dump_ivs(req, "after sending key to sep\n");
-
- /* key sent went okay; release sep, and set are_we_done_yet */
- sctx->key_sent = 1;
- sep_crypto_release(sctx, ta_ctx, -EINPROGRESS);
-
- } else {
-
- /**
- * This is the result of a block request
- */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "crypto_post_op block response\n");
-
- u32_error = sep_verify_op(ta_ctx, ta_ctx->block_opcode,
- &msg_offset);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep block error %x\n", u32_error);
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return -EINVAL;
- }
-
- if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "post op for DES\n");
-
- /* special case for 1 block des */
- if (sep->current_cypher_req->nbytes ==
- crypto_ablkcipher_blocksize(tfm)) {
-
- sep_read_msg(ta_ctx, small_buf,
- crypto_ablkcipher_blocksize(tfm),
- crypto_ablkcipher_blocksize(tfm) * 2,
- &msg_offset, 1);
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "reading in block des\n");
-
- copy_result = sg_copy_from_buffer(
- ta_ctx->dst_sg,
- sep_sg_nents(ta_ctx->dst_sg),
- small_buf,
- crypto_ablkcipher_blocksize(tfm));
-
- if (copy_result !=
- crypto_ablkcipher_blocksize(tfm)) {
-
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "des block copy failed\n");
- sep_crypto_release(sctx, ta_ctx,
- -ENOMEM);
- return -ENOMEM;
- }
- }
-
- /* Read Context */
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->des_private_ctx,
- sizeof(struct sep_des_private_context));
- } else {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "post op for AES\n");
-
- /* Skip the MAC Output */
- msg_offset += (sizeof(u32) * 4);
-
- /* Read Context */
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->aes_private_ctx,
- sizeof(struct sep_aes_private_context));
- }
-
- /* Copy to correct sg if this block had oddball pages */
- if (ta_ctx->dst_sg_hold)
- sep_copy_sg(ta_ctx->sep_used,
- ta_ctx->dst_sg,
- ta_ctx->current_cypher_req->dst,
- ta_ctx->current_cypher_req->nbytes);
-
- /**
- * Copy the iv's back to the walk.iv
- * This is required for dm_crypt
- */
- sep_dump_ivs(req, "got data block from sep\n");
- if ((ta_ctx->current_request == DES_CBC) &&
- (ta_ctx->des_opmode == SEP_DES_CBC)) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "returning result iv to walk on DES\n");
- des_internal = (struct sep_des_internal_context *)
- sctx->des_private_ctx.ctx_buf;
- memcpy(ta_ctx->walk.iv,
- (void *)des_internal->iv_context,
- crypto_ablkcipher_ivsize(tfm));
- } else if ((ta_ctx->current_request == AES_CBC) &&
- (ta_ctx->aes_opmode == SEP_AES_CBC)) {
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "returning result iv to walk on AES\n");
- aes_internal = (struct sep_aes_internal_context *)
- sctx->aes_private_ctx.cbuff;
- memcpy(ta_ctx->walk.iv,
- (void *)aes_internal->aes_ctx_iv,
- crypto_ablkcipher_ivsize(tfm));
- }
-
- /* finished, release everything */
- sep_crypto_release(sctx, ta_ctx, 0);
- }
- pr_debug("crypto_post_op done\n");
- pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
- sctx->key_sent, tfm, sctx, ta_ctx);
-
- return 0;
-}
-
-static u32 hash_init_post_op(struct sep_device *sep)
-{
- u32 u32_error;
- u32 msg_offset;
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
- struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash init post op\n");
-
- /* first bring msg from shared area to local area */
- memcpy(ta_ctx->msg, sep->shared_addr,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- u32_error = sep_verify_op(ta_ctx, SEP_HASH_INIT_OPCODE,
- &msg_offset);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
- u32_error);
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* Read Context */
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->hash_private_ctx,
- sizeof(struct sep_hash_private_context));
-
- /* Signal to crypto infrastructure and clear out */
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash init post op done\n");
- sep_crypto_release(sctx, ta_ctx, 0);
- return 0;
-}
-
-static u32 hash_update_post_op(struct sep_device *sep)
-{
- u32 u32_error;
- u32 msg_offset;
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
- struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash update post op\n");
-
- /* first bring msg from shared area to local area */
- memcpy(ta_ctx->msg, sep->shared_addr,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- u32_error = sep_verify_op(ta_ctx, SEP_HASH_UPDATE_OPCODE,
- &msg_offset);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
- u32_error);
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* Read Context */
- sep_read_context(ta_ctx, &msg_offset,
- &sctx->hash_private_ctx,
- sizeof(struct sep_hash_private_context));
-
- /**
- * Following is only for finup; if we just completed the
- * data portion of finup, we now need to kick off the
- * finish portion of finup.
- */
-
- if (ta_ctx->sep_used->current_hash_stage == HASH_FINUP_DATA) {
-
- /* first reset stage to HASH_FINUP_FINISH */
- ta_ctx->sep_used->current_hash_stage = HASH_FINUP_FINISH;
-
- /* now enqueue the finish operation */
- spin_lock_irq(&queue_lock);
- u32_error = crypto_enqueue_request(&sep_queue,
- &ta_ctx->sep_used->current_hash_req->base);
- spin_unlock_irq(&queue_lock);
-
- if ((u32_error != 0) && (u32_error != -EINPROGRESS)) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "spe cypher post op cant queue\n");
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* schedule the data send */
- u32_error = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "cant submit work sep_crypto_block\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return -EINVAL;
- }
- }
-
- /* Signal to crypto infrastructure and clear out */
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash update post op done\n");
- sep_crypto_release(sctx, ta_ctx, 0);
- return 0;
-}
-
-static u32 hash_final_post_op(struct sep_device *sep)
-{
- int max_length;
- u32 u32_error;
- u32 msg_offset;
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
- struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash final post op\n");
-
- /* first bring msg from shared area to local area */
- memcpy(ta_ctx->msg, sep->shared_addr,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- u32_error = sep_verify_op(ta_ctx, SEP_HASH_FINISH_OPCODE,
- &msg_offset);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev, "hash finish error %x\n",
- u32_error);
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* Grab the result */
- if (ta_ctx->current_hash_req->result == NULL) {
- /* Oops, null buffer; error out here */
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "hash finish null buffer\n");
- sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
- return -ENOMEM;
- }
-
- max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
- sizeof(u32)) * sizeof(u32);
-
- sep_read_msg(ta_ctx,
- ta_ctx->current_hash_req->result,
- crypto_ahash_digestsize(tfm), max_length,
- &msg_offset, 0);
-
- /* Signal to crypto infrastructure and clear out */
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash finish post op done\n");
- sep_crypto_release(sctx, ta_ctx, 0);
- return 0;
-}
-
-static u32 hash_digest_post_op(struct sep_device *sep)
-{
- int max_length;
- u32 u32_error;
- u32 msg_offset;
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
- struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
- struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash digest post op\n");
-
- /* first bring msg from shared area to local area */
- memcpy(ta_ctx->msg, sep->shared_addr,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- u32_error = sep_verify_op(ta_ctx, SEP_HASH_SINGLE_OPCODE,
- &msg_offset);
-
- if (u32_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "hash digest finish error %x\n", u32_error);
-
- sep_crypto_release(sctx, ta_ctx, u32_error);
- return u32_error;
- }
-
- /* Grab the result */
- if (ta_ctx->current_hash_req->result == NULL) {
- /* Oops, null buffer; error out here */
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "hash digest finish null buffer\n");
- sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
- return -ENOMEM;
- }
-
- max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
- sizeof(u32)) * sizeof(u32);
-
- sep_read_msg(ta_ctx,
- ta_ctx->current_hash_req->result,
- crypto_ahash_digestsize(tfm), max_length,
- &msg_offset, 0);
-
- /* Signal to crypto infrastructure and clear out */
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash digest finish post op done\n");
-
- sep_crypto_release(sctx, ta_ctx, 0);
- return 0;
-}
-
-/**
- * The sep_finish function is the function that is scheduled (via tasklet)
- * by the interrupt service routine when the SEP sends and interrupt
- * This is only called by the interrupt handler as a tasklet.
- */
-static void sep_finish(unsigned long data)
-{
- struct sep_device *sep_dev;
- int res;
-
- res = 0;
-
- if (data == 0) {
- pr_debug("sep_finish called with null data\n");
- return;
- }
-
- sep_dev = (struct sep_device *)data;
- if (sep_dev == NULL) {
- pr_debug("sep_finish; sep_dev is NULL\n");
- return;
- }
-
- if (sep_dev->in_kernel == (u32)0) {
- dev_warn(&sep_dev->pdev->dev,
- "sep_finish; not in kernel operation\n");
- return;
- }
-
- /* Did we really do a sep command prior to this? */
- if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &sep_dev->ta_ctx->call_status.status)) {
-
- dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n",
- current->pid);
- return;
- }
-
- if (sep_dev->send_ct != sep_dev->reply_ct) {
- dev_warn(&sep_dev->pdev->dev,
- "[PID%d] poll; no message came back\n",
- current->pid);
- return;
- }
-
- /* Check for error (In case time ran out) */
- if ((res != 0x0) && (res != 0x8)) {
- dev_warn(&sep_dev->pdev->dev,
- "[PID%d] poll; poll error GPR3 is %x\n",
- current->pid, res);
- return;
- }
-
- /* What kind of interrupt from sep was this? */
- res = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-
- dev_dbg(&sep_dev->pdev->dev, "[PID%d] GPR2 at crypto finish is %x\n",
- current->pid, res);
-
- /* Print request? */
- if ((res >> 30) & 0x1) {
- dev_dbg(&sep_dev->pdev->dev, "[PID%d] sep print req\n",
- current->pid);
- dev_dbg(&sep_dev->pdev->dev, "[PID%d] contents: %s\n",
- current->pid,
- (char *)(sep_dev->shared_addr +
- SEP_DRIVER_PRINTF_OFFSET_IN_BYTES));
- return;
- }
-
- /* Request for daemon (not currently in POR)? */
- if (res >> 31) {
- dev_dbg(&sep_dev->pdev->dev,
- "[PID%d] sep request; ignoring\n",
- current->pid);
- return;
- }
-
- /* If we got here, then we have a replay to a sep command */
-
- dev_dbg(&sep_dev->pdev->dev,
- "[PID%d] sep reply to command; processing request: %x\n",
- current->pid, sep_dev->current_request);
-
- switch (sep_dev->current_request) {
- case AES_CBC:
- case AES_ECB:
- case DES_CBC:
- case DES_ECB:
- res = crypto_post_op(sep_dev);
- break;
- case SHA1:
- case MD5:
- case SHA224:
- case SHA256:
- switch (sep_dev->current_hash_stage) {
- case HASH_INIT:
- res = hash_init_post_op(sep_dev);
- break;
- case HASH_UPDATE:
- case HASH_FINUP_DATA:
- res = hash_update_post_op(sep_dev);
- break;
- case HASH_FINUP_FINISH:
- case HASH_FINISH:
- res = hash_final_post_op(sep_dev);
- break;
- case HASH_DIGEST:
- res = hash_digest_post_op(sep_dev);
- break;
- default:
- pr_debug("sep - invalid stage for hash finish\n");
- }
- break;
- default:
- pr_debug("sep - invalid request for finish\n");
- }
-
- if (res)
- pr_debug("sep - finish returned error %x\n", res);
-}
-
-static int sep_hash_cra_init(struct crypto_tfm *tfm)
- {
- const char *alg_name = crypto_tfm_alg_name(tfm);
-
- pr_debug("sep_hash_cra_init name is %s\n", alg_name);
-
- crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
- sizeof(struct this_task_ctx));
- return 0;
- }
-
-static void sep_hash_cra_exit(struct crypto_tfm *tfm)
-{
- pr_debug("sep_hash_cra_exit\n");
-}
-
-static void sep_hash_init(void *data)
-{
- u32 msg_offset;
- int result;
- struct ahash_request *req;
- struct crypto_ahash *tfm;
- struct this_task_ctx *ta_ctx;
- struct sep_system_ctx *sctx;
- unsigned long end_time;
- int are_we_done_yet;
-
- req = (struct ahash_request *)data;
- tfm = crypto_ahash_reqtfm(req);
- sctx = crypto_ahash_ctx(tfm);
- ta_ctx = ahash_request_ctx(req);
- ta_ctx->sep_used = sep_dev;
-
- ta_ctx->are_we_done_yet = &are_we_done_yet;
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_init\n");
- ta_ctx->current_hash_stage = HASH_INIT;
- /* opcode and mode */
- sep_make_header(ta_ctx, &msg_offset, SEP_HASH_INIT_OPCODE);
- sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
- sizeof(u32), sizeof(u32), &msg_offset, 0);
- sep_end_msg(ta_ctx, msg_offset);
-
- are_we_done_yet = 0;
- result = sep_crypto_take_sep(ta_ctx);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_init take sep failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash init never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
-}
-
-static void sep_hash_update(void *data)
-{
- int int_error;
- u32 msg_offset;
- u32 len;
- struct sep_hash_internal_context *int_ctx;
- u32 block_size;
- u32 head_len;
- u32 tail_len;
- int are_we_done_yet;
-
- static u32 msg[10];
- static char small_buf[100];
- void *src_ptr;
- struct scatterlist *new_sg;
- ssize_t copy_result;
- struct ahash_request *req;
- struct crypto_ahash *tfm;
- struct this_task_ctx *ta_ctx;
- struct sep_system_ctx *sctx;
- unsigned long end_time;
-
- req = (struct ahash_request *)data;
- tfm = crypto_ahash_reqtfm(req);
- sctx = crypto_ahash_ctx(tfm);
- ta_ctx = ahash_request_ctx(req);
- ta_ctx->sep_used = sep_dev;
-
- ta_ctx->are_we_done_yet = &are_we_done_yet;
-
- /* length for queue status */
- ta_ctx->nbytes = req->nbytes;
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_update\n");
- ta_ctx->current_hash_stage = HASH_UPDATE;
- len = req->nbytes;
-
- block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
- tail_len = req->nbytes % block_size;
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", len);
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
-
- /* Compute header/tail sizes */
- int_ctx = (struct sep_hash_internal_context *)&sctx->
- hash_private_ctx.internal_context;
- head_len = (block_size - int_ctx->prev_update_bytes) % block_size;
- tail_len = (req->nbytes - head_len) % block_size;
-
- /* Make sure all pages are an even block */
- int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
- req->nbytes,
- block_size, &new_sg, 1);
-
- if (int_error < 0) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "oddball pages error in crash update\n");
- sep_crypto_release(sctx, ta_ctx, -ENOMEM);
- return;
- } else if (int_error == 1) {
- ta_ctx->src_sg = new_sg;
- ta_ctx->src_sg_hold = new_sg;
- } else {
- ta_ctx->src_sg = req->src;
- ta_ctx->src_sg_hold = NULL;
- }
-
- src_ptr = sg_virt(ta_ctx->src_sg);
-
- if ((!req->nbytes) || (!ta_ctx->src_sg)) {
- /* null data */
- src_ptr = NULL;
- }
-
- ta_ctx->dcb_input_data.app_in_address = src_ptr;
- ta_ctx->dcb_input_data.data_in_size =
- req->nbytes - (head_len + tail_len);
- ta_ctx->dcb_input_data.app_out_address = NULL;
- ta_ctx->dcb_input_data.block_size = block_size;
- ta_ctx->dcb_input_data.tail_block_size = 0;
- ta_ctx->dcb_input_data.is_applet = 0;
- ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
- ta_ctx->dcb_input_data.dst_sg = NULL;
-
- int_error = sep_create_dcb_dmatables_context_kernel(
- ta_ctx->sep_used,
- &ta_ctx->dcb_region,
- &ta_ctx->dmatables_region,
- &ta_ctx->dma_ctx,
- &ta_ctx->dcb_input_data,
- 1);
- if (int_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "hash update dma table create failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
- /* Construct message to SEP */
- sep_make_header(ta_ctx, &msg_offset, SEP_HASH_UPDATE_OPCODE);
-
- msg[0] = (u32)0;
- msg[1] = (u32)0;
- msg[2] = (u32)0;
-
- sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
- &msg_offset, 0);
-
- /* Handle remainders */
-
- /* Head */
- sep_write_msg(ta_ctx, &head_len, sizeof(u32),
- sizeof(u32), &msg_offset, 0);
-
- if (head_len) {
- copy_result = sg_copy_to_buffer(
- req->src,
- sep_sg_nents(ta_ctx->src_sg),
- small_buf, head_len);
-
- if (copy_result != head_len) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sg head copy failure in hash block\n");
- sep_crypto_release(sctx, ta_ctx, -ENOMEM);
- return;
- }
-
- sep_write_msg(ta_ctx, small_buf, head_len,
- sizeof(u32) * 32, &msg_offset, 1);
- } else {
- msg_offset += sizeof(u32) * 32;
- }
-
- /* Tail */
- sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
- sizeof(u32), &msg_offset, 0);
-
- if (tail_len) {
- copy_result = sep_copy_offset_sg(
- ta_ctx->sep_used,
- ta_ctx->src_sg,
- req->nbytes - tail_len,
- small_buf, tail_len);
-
- if (copy_result != tail_len) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sg tail copy failure in hash block\n");
- sep_crypto_release(sctx, ta_ctx, -ENOMEM);
- return;
- }
-
- sep_write_msg(ta_ctx, small_buf, tail_len,
- sizeof(u32) * 32, &msg_offset, 1);
- } else {
- msg_offset += sizeof(u32) * 32;
- }
-
- /* Context */
- sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
- sizeof(struct sep_hash_private_context));
-
- sep_end_msg(ta_ctx, msg_offset);
- are_we_done_yet = 0;
- int_error = sep_crypto_take_sep(ta_ctx);
- if (int_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_update take sep failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash update never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
-}
-
-static void sep_hash_final(void *data)
-{
- u32 msg_offset;
- struct ahash_request *req;
- struct crypto_ahash *tfm;
- struct this_task_ctx *ta_ctx;
- struct sep_system_ctx *sctx;
- int result;
- unsigned long end_time;
- int are_we_done_yet;
-
- req = (struct ahash_request *)data;
- tfm = crypto_ahash_reqtfm(req);
- sctx = crypto_ahash_ctx(tfm);
- ta_ctx = ahash_request_ctx(req);
- ta_ctx->sep_used = sep_dev;
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_final\n");
- ta_ctx->current_hash_stage = HASH_FINISH;
-
- ta_ctx->are_we_done_yet = &are_we_done_yet;
-
- /* opcode and mode */
- sep_make_header(ta_ctx, &msg_offset, SEP_HASH_FINISH_OPCODE);
-
- /* Context */
- sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
- sizeof(struct sep_hash_private_context));
-
- sep_end_msg(ta_ctx, msg_offset);
- are_we_done_yet = 0;
- result = sep_crypto_take_sep(ta_ctx);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_final take sep failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash final job never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
-}
-
-static void sep_hash_digest(void *data)
-{
- int int_error;
- u32 msg_offset;
- u32 block_size;
- u32 msg[10];
- size_t copy_result;
- int result;
- int are_we_done_yet;
- u32 tail_len;
- static char small_buf[100];
- struct scatterlist *new_sg;
- void *src_ptr;
-
- struct ahash_request *req;
- struct crypto_ahash *tfm;
- struct this_task_ctx *ta_ctx;
- struct sep_system_ctx *sctx;
- unsigned long end_time;
-
- req = (struct ahash_request *)data;
- tfm = crypto_ahash_reqtfm(req);
- sctx = crypto_ahash_ctx(tfm);
- ta_ctx = ahash_request_ctx(req);
- ta_ctx->sep_used = sep_dev;
-
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_digest\n");
- ta_ctx->current_hash_stage = HASH_DIGEST;
-
- ta_ctx->are_we_done_yet = &are_we_done_yet;
-
- /* length for queue status */
- ta_ctx->nbytes = req->nbytes;
-
- block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
- tail_len = req->nbytes % block_size;
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", req->nbytes);
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
- dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
-
- /* Make sure all pages are an even block */
- int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
- req->nbytes,
- block_size, &new_sg, 1);
-
- if (int_error < 0) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "oddball pages error in crash update\n");
- sep_crypto_release(sctx, ta_ctx, -ENOMEM);
- return;
- } else if (int_error == 1) {
- ta_ctx->src_sg = new_sg;
- ta_ctx->src_sg_hold = new_sg;
- } else {
- ta_ctx->src_sg = req->src;
- ta_ctx->src_sg_hold = NULL;
- }
-
- src_ptr = sg_virt(ta_ctx->src_sg);
-
- if ((!req->nbytes) || (!ta_ctx->src_sg)) {
- /* null data */
- src_ptr = NULL;
- }
-
- ta_ctx->dcb_input_data.app_in_address = src_ptr;
- ta_ctx->dcb_input_data.data_in_size = req->nbytes - tail_len;
- ta_ctx->dcb_input_data.app_out_address = NULL;
- ta_ctx->dcb_input_data.block_size = block_size;
- ta_ctx->dcb_input_data.tail_block_size = 0;
- ta_ctx->dcb_input_data.is_applet = 0;
- ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
- ta_ctx->dcb_input_data.dst_sg = NULL;
-
- int_error = sep_create_dcb_dmatables_context_kernel(
- ta_ctx->sep_used,
- &ta_ctx->dcb_region,
- &ta_ctx->dmatables_region,
- &ta_ctx->dma_ctx,
- &ta_ctx->dcb_input_data,
- 1);
- if (int_error) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "hash update dma table create failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
- /* Construct message to SEP */
- sep_make_header(ta_ctx, &msg_offset, SEP_HASH_SINGLE_OPCODE);
- sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
- sizeof(u32), sizeof(u32), &msg_offset, 0);
-
- msg[0] = (u32)0;
- msg[1] = (u32)0;
- msg[2] = (u32)0;
-
- sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
- &msg_offset, 0);
-
- /* Tail */
- sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
- sizeof(u32), &msg_offset, 0);
-
- if (tail_len) {
- copy_result = sep_copy_offset_sg(
- ta_ctx->sep_used,
- ta_ctx->src_sg,
- req->nbytes - tail_len,
- small_buf, tail_len);
-
- if (copy_result != tail_len) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sg tail copy failure in hash block\n");
- sep_crypto_release(sctx, ta_ctx, -ENOMEM);
- return;
- }
-
- sep_write_msg(ta_ctx, small_buf, tail_len,
- sizeof(u32) * 32, &msg_offset, 1);
- } else {
- msg_offset += sizeof(u32) * 32;
- }
-
- sep_end_msg(ta_ctx, msg_offset);
-
- are_we_done_yet = 0;
- result = sep_crypto_take_sep(ta_ctx);
- if (result) {
- dev_warn(&ta_ctx->sep_used->pdev->dev,
- "sep_hash_digest take sep failed\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- }
-
- /* now we sit and wait up to a fixed time for completion */
- end_time = jiffies + (WAIT_TIME * HZ);
- while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
- schedule();
-
- /* Done waiting; still not done yet? */
- if (are_we_done_yet == 0) {
- dev_dbg(&ta_ctx->sep_used->pdev->dev,
- "hash digest job never got done\n");
- sep_crypto_release(sctx, ta_ctx, -EINVAL);
- return;
- }
-
-}
-
-/**
- * This is what is called by each of the API's provided
- * in the kernel crypto descriptors. It is run in a process
- * context using the kernel workqueues. Therefore it can
- * be put to sleep.
- */
-static void sep_dequeuer(void *data)
-{
- struct crypto_queue *this_queue;
- struct crypto_async_request *async_req;
- struct crypto_async_request *backlog;
- struct ablkcipher_request *cypher_req;
- struct ahash_request *hash_req;
- struct sep_system_ctx *sctx;
- struct crypto_ahash *hash_tfm;
- struct this_task_ctx *ta_ctx;
-
-
- this_queue = (struct crypto_queue *)data;
-
- spin_lock_irq(&queue_lock);
- backlog = crypto_get_backlog(this_queue);
- async_req = crypto_dequeue_request(this_queue);
- spin_unlock_irq(&queue_lock);
-
- if (!async_req) {
- pr_debug("sep crypto queue is empty\n");
- return;
- }
-
- if (backlog) {
- pr_debug("sep crypto backlog set\n");
- if (backlog->complete)
- backlog->complete(backlog, -EINPROGRESS);
- backlog = NULL;
- }
-
- if (!async_req->tfm) {
- pr_debug("sep crypto queue null tfm\n");
- return;
- }
-
- if (!async_req->tfm->__crt_alg) {
- pr_debug("sep crypto queue null __crt_alg\n");
- return;
- }
-
- if (!async_req->tfm->__crt_alg->cra_type) {
- pr_debug("sep crypto queue null cra_type\n");
- return;
- }
-
- /* we have stuff in the queue */
- if (async_req->tfm->__crt_alg->cra_type !=
- &crypto_ahash_type) {
- /* This is for a cypher */
- pr_debug("sep crypto queue doing cipher\n");
- cypher_req = container_of(async_req,
- struct ablkcipher_request,
- base);
- if (!cypher_req) {
- pr_debug("sep crypto queue null cypher_req\n");
- return;
- }
-
- sep_crypto_block((void *)cypher_req);
- return;
- } else {
- /* This is a hash */
- pr_debug("sep crypto queue doing hash\n");
- /**
- * This is a bit more complex than cipher; we
- * need to figure out what type of operation
- */
- hash_req = ahash_request_cast(async_req);
- if (!hash_req) {
- pr_debug("sep crypto queue null hash_req\n");
- return;
- }
-
- hash_tfm = crypto_ahash_reqtfm(hash_req);
- if (!hash_tfm) {
- pr_debug("sep crypto queue null hash_tfm\n");
- return;
- }
-
-
- sctx = crypto_ahash_ctx(hash_tfm);
- if (!sctx) {
- pr_debug("sep crypto queue null sctx\n");
- return;
- }
-
- ta_ctx = ahash_request_ctx(hash_req);
-
- if (ta_ctx->current_hash_stage == HASH_INIT) {
- pr_debug("sep crypto queue hash init\n");
- sep_hash_init((void *)hash_req);
- return;
- } else if (ta_ctx->current_hash_stage == HASH_UPDATE) {
- pr_debug("sep crypto queue hash update\n");
- sep_hash_update((void *)hash_req);
- return;
- } else if (ta_ctx->current_hash_stage == HASH_FINISH) {
- pr_debug("sep crypto queue hash final\n");
- sep_hash_final((void *)hash_req);
- return;
- } else if (ta_ctx->current_hash_stage == HASH_DIGEST) {
- pr_debug("sep crypto queue hash digest\n");
- sep_hash_digest((void *)hash_req);
- return;
- } else if (ta_ctx->current_hash_stage == HASH_FINUP_DATA) {
- pr_debug("sep crypto queue hash digest\n");
- sep_hash_update((void *)hash_req);
- return;
- } else if (ta_ctx->current_hash_stage == HASH_FINUP_FINISH) {
- pr_debug("sep crypto queue hash digest\n");
- sep_hash_final((void *)hash_req);
- return;
- } else {
- pr_debug("sep crypto queue hash oops nothing\n");
- return;
- }
- }
-}
-
-static int sep_sha1_init(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha1 init\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA1;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA1;
- ta_ctx->current_hash_stage = HASH_INIT;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha1_update(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha1 update\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA1;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA1;
- ta_ctx->current_hash_stage = HASH_UPDATE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha1_final(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha1 final\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA1;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA1;
- ta_ctx->current_hash_stage = HASH_FINISH;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha1_digest(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha1 digest\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA1;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA1;
- ta_ctx->current_hash_stage = HASH_DIGEST;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha1_finup(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha1 finup\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA1;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA1;
- ta_ctx->current_hash_stage = HASH_FINUP_DATA;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_md5_init(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing md5 init\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = MD5;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_MD5;
- ta_ctx->current_hash_stage = HASH_INIT;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_md5_update(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing md5 update\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = MD5;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_MD5;
- ta_ctx->current_hash_stage = HASH_UPDATE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_md5_final(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing md5 final\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = MD5;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_MD5;
- ta_ctx->current_hash_stage = HASH_FINISH;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_md5_digest(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing md5 digest\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = MD5;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_MD5;
- ta_ctx->current_hash_stage = HASH_DIGEST;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_md5_finup(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing md5 finup\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = MD5;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_MD5;
- ta_ctx->current_hash_stage = HASH_FINUP_DATA;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha224_init(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha224 init\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA224;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA224;
- ta_ctx->current_hash_stage = HASH_INIT;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha224_update(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha224 update\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA224;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA224;
- ta_ctx->current_hash_stage = HASH_UPDATE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha224_final(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha224 final\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA224;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA224;
- ta_ctx->current_hash_stage = HASH_FINISH;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha224_digest(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha224 digest\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA224;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA224;
- ta_ctx->current_hash_stage = HASH_DIGEST;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha224_finup(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha224 finup\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA224;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA224;
- ta_ctx->current_hash_stage = HASH_FINUP_DATA;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha256_init(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha256 init\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA256;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA256;
- ta_ctx->current_hash_stage = HASH_INIT;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha256_update(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha256 update\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA256;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA256;
- ta_ctx->current_hash_stage = HASH_UPDATE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha256_final(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
- pr_debug("sep - doing sha256 final\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA256;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA256;
- ta_ctx->current_hash_stage = HASH_FINISH;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha256_digest(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha256 digest\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA256;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA256;
- ta_ctx->current_hash_stage = HASH_DIGEST;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_sha256_finup(struct ahash_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
-
- pr_debug("sep - doing sha256 finup\n");
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = SHA256;
- ta_ctx->current_hash_req = req;
- ta_ctx->current_cypher_req = NULL;
- ta_ctx->hash_opmode = SEP_HASH_SHA256;
- ta_ctx->current_hash_stage = HASH_FINUP_DATA;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_crypto_init(struct crypto_tfm *tfm)
-{
- const char *alg_name = crypto_tfm_alg_name(tfm);
-
- if (alg_name == NULL)
- pr_debug("sep_crypto_init alg is NULL\n");
- else
- pr_debug("sep_crypto_init alg is %s\n", alg_name);
-
- tfm->crt_ablkcipher.reqsize = sizeof(struct this_task_ctx);
- return 0;
-}
-
-static void sep_crypto_exit(struct crypto_tfm *tfm)
-{
- pr_debug("sep_crypto_exit\n");
-}
-
-static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
- unsigned int keylen)
-{
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm);
-
- pr_debug("sep aes setkey\n");
-
- pr_debug("tfm is %p sctx is %p\n", tfm, sctx);
- switch (keylen) {
- case SEP_AES_KEY_128_SIZE:
- sctx->aes_key_size = AES_128;
- break;
- case SEP_AES_KEY_192_SIZE:
- sctx->aes_key_size = AES_192;
- break;
- case SEP_AES_KEY_256_SIZE:
- sctx->aes_key_size = AES_256;
- break;
- case SEP_AES_KEY_512_SIZE:
- sctx->aes_key_size = AES_512;
- break;
- default:
- pr_debug("invalid sep aes key size %x\n",
- keylen);
- return -EINVAL;
- }
-
- memset(&sctx->key.aes, 0, sizeof(u32) *
- SEP_AES_MAX_KEY_SIZE_WORDS);
- memcpy(&sctx->key.aes, key, keylen);
- sctx->keylen = keylen;
- /* Indicate to encrypt/decrypt function to send key to SEP */
- sctx->key_sent = 0;
-
- return 0;
-}
-
-static int sep_aes_ecb_encrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing aes ecb encrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = AES_ECB;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
- ta_ctx->aes_opmode = SEP_AES_ECB;
- ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_aes_ecb_decrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing aes ecb decrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = AES_ECB;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->aes_encmode = SEP_AES_DECRYPT;
- ta_ctx->aes_opmode = SEP_AES_ECB;
- ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_aes_cbc_encrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
- crypto_ablkcipher_reqtfm(req));
-
- pr_debug("sep - doing aes cbc encrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
- crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = AES_CBC;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
- ta_ctx->aes_opmode = SEP_AES_CBC;
- ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_aes_cbc_decrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
- crypto_ablkcipher_reqtfm(req));
-
- pr_debug("sep - doing aes cbc decrypt\n");
-
- pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
- crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = AES_CBC;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->aes_encmode = SEP_AES_DECRYPT;
- ta_ctx->aes_opmode = SEP_AES_CBC;
- ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
- unsigned int keylen)
-{
- struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm);
- struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm);
- u32 *flags = &ctfm->crt_flags;
-
- pr_debug("sep des setkey\n");
-
- switch (keylen) {
- case DES_KEY_SIZE:
- sctx->des_nbr_keys = DES_KEY_1;
- break;
- case DES_KEY_SIZE * 2:
- sctx->des_nbr_keys = DES_KEY_2;
- break;
- case DES_KEY_SIZE * 3:
- sctx->des_nbr_keys = DES_KEY_3;
- break;
- default:
- pr_debug("invalid key size %x\n",
- keylen);
- return -EINVAL;
- }
-
- if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) &&
- (sep_weak_key(key, keylen))) {
-
- *flags |= CRYPTO_TFM_RES_WEAK_KEY;
- pr_debug("weak key\n");
- return -EINVAL;
- }
-
- memset(&sctx->key.des, 0, sizeof(struct sep_des_key));
- memcpy(&sctx->key.des.key1, key, keylen);
- sctx->keylen = keylen;
- /* Indicate to encrypt/decrypt function to send key to SEP */
- sctx->key_sent = 0;
-
- return 0;
-}
-
-static int sep_des_ebc_encrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing des ecb encrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = DES_ECB;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->des_encmode = SEP_DES_ENCRYPT;
- ta_ctx->des_opmode = SEP_DES_ECB;
- ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_des_ebc_decrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing des ecb decrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = DES_ECB;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->des_encmode = SEP_DES_DECRYPT;
- ta_ctx->des_opmode = SEP_DES_ECB;
- ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_des_cbc_encrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing des cbc encrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = DES_CBC;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->des_encmode = SEP_DES_ENCRYPT;
- ta_ctx->des_opmode = SEP_DES_CBC;
- ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static int sep_des_cbc_decrypt(struct ablkcipher_request *req)
-{
- int error;
- int error1;
- struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
-
- pr_debug("sep - doing des ecb decrypt\n");
-
- /* Clear out task context */
- memset(ta_ctx, 0, sizeof(struct this_task_ctx));
-
- ta_ctx->sep_used = sep_dev;
- ta_ctx->current_request = DES_CBC;
- ta_ctx->current_hash_req = NULL;
- ta_ctx->current_cypher_req = req;
- ta_ctx->des_encmode = SEP_DES_DECRYPT;
- ta_ctx->des_opmode = SEP_DES_CBC;
- ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
- ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
-
- /* lock necessary so that only one entity touches the queues */
- spin_lock_irq(&queue_lock);
- error = crypto_enqueue_request(&sep_queue, &req->base);
-
- if ((error != 0) && (error != -EINPROGRESS))
- pr_debug(" sep - crypto enqueue failed: %x\n",
- error);
- error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
- sep_dequeuer, (void *)&sep_queue);
- if (error1)
- pr_debug(" sep - workqueue submit failed: %x\n",
- error1);
- spin_unlock_irq(&queue_lock);
- /* We return result of crypto enqueue */
- return error;
-}
-
-static struct ahash_alg hash_algs[] = {
-{
- .init = sep_sha1_init,
- .update = sep_sha1_update,
- .final = sep_sha1_final,
- .digest = sep_sha1_digest,
- .finup = sep_sha1_finup,
- .halg = {
- .digestsize = SHA1_DIGEST_SIZE,
- .base = {
- .cra_name = "sha1",
- .cra_driver_name = "sha1-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_AHASH |
- CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA1_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- .cra_init = sep_hash_cra_init,
- .cra_exit = sep_hash_cra_exit,
- }
- }
-},
-{
- .init = sep_md5_init,
- .update = sep_md5_update,
- .final = sep_md5_final,
- .digest = sep_md5_digest,
- .finup = sep_md5_finup,
- .halg = {
- .digestsize = MD5_DIGEST_SIZE,
- .base = {
- .cra_name = "md5",
- .cra_driver_name = "md5-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_AHASH |
- CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA1_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- .cra_init = sep_hash_cra_init,
- .cra_exit = sep_hash_cra_exit,
- }
- }
-},
-{
- .init = sep_sha224_init,
- .update = sep_sha224_update,
- .final = sep_sha224_final,
- .digest = sep_sha224_digest,
- .finup = sep_sha224_finup,
- .halg = {
- .digestsize = SHA224_DIGEST_SIZE,
- .base = {
- .cra_name = "sha224",
- .cra_driver_name = "sha224-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_AHASH |
- CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA224_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- .cra_init = sep_hash_cra_init,
- .cra_exit = sep_hash_cra_exit,
- }
- }
-},
-{
- .init = sep_sha256_init,
- .update = sep_sha256_update,
- .final = sep_sha256_final,
- .digest = sep_sha256_digest,
- .finup = sep_sha256_finup,
- .halg = {
- .digestsize = SHA256_DIGEST_SIZE,
- .base = {
- .cra_name = "sha256",
- .cra_driver_name = "sha256-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_AHASH |
- CRYPTO_ALG_ASYNC,
- .cra_blocksize = SHA256_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_module = THIS_MODULE,
- .cra_init = sep_hash_cra_init,
- .cra_exit = sep_hash_cra_exit,
- }
- }
-}
-};
-
-static struct crypto_alg crypto_algs[] = {
-{
- .cra_name = "ecb(aes)",
- .cra_driver_name = "ecb-aes-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = AES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
- .setkey = sep_aes_setkey,
- .encrypt = sep_aes_ecb_encrypt,
- .decrypt = sep_aes_ecb_decrypt,
- }
-},
-{
- .cra_name = "cbc(aes)",
- .cra_driver_name = "cbc-aes-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = AES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
- .setkey = sep_aes_setkey,
- .encrypt = sep_aes_cbc_encrypt,
- .ivsize = AES_BLOCK_SIZE,
- .decrypt = sep_aes_cbc_decrypt,
- }
-},
-{
- .cra_name = "ebc(des)",
- .cra_driver_name = "ebc-des-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = DES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = DES_KEY_SIZE,
- .max_keysize = DES_KEY_SIZE,
- .setkey = sep_des_setkey,
- .encrypt = sep_des_ebc_encrypt,
- .decrypt = sep_des_ebc_decrypt,
- }
-},
-{
- .cra_name = "cbc(des)",
- .cra_driver_name = "cbc-des-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = DES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = DES_KEY_SIZE,
- .max_keysize = DES_KEY_SIZE,
- .setkey = sep_des_setkey,
- .encrypt = sep_des_cbc_encrypt,
- .ivsize = DES_BLOCK_SIZE,
- .decrypt = sep_des_cbc_decrypt,
- }
-},
-{
- .cra_name = "ebc(des3-ede)",
- .cra_driver_name = "ebc-des3-ede-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = DES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = DES3_EDE_KEY_SIZE,
- .max_keysize = DES3_EDE_KEY_SIZE,
- .setkey = sep_des_setkey,
- .encrypt = sep_des_ebc_encrypt,
- .decrypt = sep_des_ebc_decrypt,
- }
-},
-{
- .cra_name = "cbc(des3-ede)",
- .cra_driver_name = "cbc-des3--ede-sep",
- .cra_priority = 100,
- .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
- .cra_blocksize = DES_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct sep_system_ctx),
- .cra_alignmask = 0,
- .cra_type = &crypto_ablkcipher_type,
- .cra_module = THIS_MODULE,
- .cra_init = sep_crypto_init,
- .cra_exit = sep_crypto_exit,
- .cra_u.ablkcipher = {
- .min_keysize = DES3_EDE_KEY_SIZE,
- .max_keysize = DES3_EDE_KEY_SIZE,
- .setkey = sep_des_setkey,
- .encrypt = sep_des_cbc_encrypt,
- .decrypt = sep_des_cbc_decrypt,
- }
-}
-};
-
-int sep_crypto_setup(void)
-{
- int err, i, j, k;
-
- tasklet_init(&sep_dev->finish_tasklet, sep_finish,
- (unsigned long)sep_dev);
-
- crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH);
-
- sep_dev->workqueue = create_singlethread_workqueue(
- "sep_crypto_workqueue");
- if (!sep_dev->workqueue) {
- dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n");
- return -ENOMEM;
- }
-
- spin_lock_init(&queue_lock);
-
- err = 0;
- for (i = 0; i < ARRAY_SIZE(hash_algs); i++) {
- err = crypto_register_ahash(&hash_algs[i]);
- if (err)
- goto err_algs;
- }
-
- err = 0;
- for (j = 0; j < ARRAY_SIZE(crypto_algs); j++) {
- err = crypto_register_alg(&crypto_algs[j]);
- if (err)
- goto err_crypto_algs;
- }
-
- return err;
-
-err_algs:
- for (k = 0; k < i; k++)
- crypto_unregister_ahash(&hash_algs[k]);
- destroy_workqueue(sep_dev->workqueue);
- return err;
-
-err_crypto_algs:
- for (k = 0; k < j; k++)
- crypto_unregister_alg(&crypto_algs[k]);
- goto err_algs;
-}
-
-void sep_crypto_takedown(void)
-{
-
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hash_algs); i++)
- crypto_unregister_ahash(&hash_algs[i]);
- for (i = 0; i < ARRAY_SIZE(crypto_algs); i++)
- crypto_unregister_alg(&crypto_algs[i]);
-
- destroy_workqueue(sep_dev->workqueue);
- tasklet_kill(&sep_dev->finish_tasklet);
-}
-
-#endif
diff --git a/drivers/staging/sep/sep_crypto.h b/drivers/staging/sep/sep_crypto.h
deleted file mode 100644
index 155c3c9b87c2..000000000000
--- a/drivers/staging/sep/sep_crypto.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- *
- * sep_crypto.h - Crypto interface structures
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2010 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- * 2011.02.22 Enable Kernel Crypto
- *
- */
-
-/* Constants for SEP (from vendor) */
-#define SEP_START_MSG_TOKEN 0x02558808
-
-#define SEP_DES_IV_SIZE_WORDS 2
-#define SEP_DES_IV_SIZE_BYTES (SEP_DES_IV_SIZE_WORDS * \
- sizeof(u32))
-#define SEP_DES_KEY_SIZE_WORDS 2
-#define SEP_DES_KEY_SIZE_BYTES (SEP_DES_KEY_SIZE_WORDS * \
- sizeof(u32))
-#define SEP_DES_BLOCK_SIZE 8
-#define SEP_DES_DUMMY_SIZE 16
-
-#define SEP_DES_INIT_OPCODE 0x10
-#define SEP_DES_BLOCK_OPCODE 0x11
-
-#define SEP_AES_BLOCK_SIZE_WORDS 4
-#define SEP_AES_BLOCK_SIZE_BYTES \
- (SEP_AES_BLOCK_SIZE_WORDS * sizeof(u32))
-
-#define SEP_AES_DUMMY_BLOCK_SIZE 16
-#define SEP_AES_IV_SIZE_WORDS SEP_AES_BLOCK_SIZE_WORDS
-#define SEP_AES_IV_SIZE_BYTES \
- (SEP_AES_IV_SIZE_WORDS * sizeof(u32))
-
-#define SEP_AES_KEY_128_SIZE 16
-#define SEP_AES_KEY_192_SIZE 24
-#define SEP_AES_KEY_256_SIZE 32
-#define SEP_AES_KEY_512_SIZE 64
-#define SEP_AES_MAX_KEY_SIZE_WORDS 16
-#define SEP_AES_MAX_KEY_SIZE_BYTES \
- (SEP_AES_MAX_KEY_SIZE_WORDS * sizeof(u32))
-
-#define SEP_AES_WRAP_MIN_SIZE 8
-#define SEP_AES_WRAP_MAX_SIZE 0x10000000
-
-#define SEP_AES_WRAP_BLOCK_SIZE_WORDS 2
-#define SEP_AES_WRAP_BLOCK_SIZE_BYTES \
- (SEP_AES_WRAP_BLOCK_SIZE_WORDS * sizeof(u32))
-
-#define SEP_AES_SECRET_RKEK1 0x1
-#define SEP_AES_SECRET_RKEK2 0x2
-
-#define SEP_AES_INIT_OPCODE 0x2
-#define SEP_AES_BLOCK_OPCODE 0x3
-#define SEP_AES_FINISH_OPCODE 0x4
-#define SEP_AES_WRAP_OPCODE 0x6
-#define SEP_AES_UNWRAP_OPCODE 0x7
-#define SEP_AES_XTS_FINISH_OPCODE 0x8
-
-#define SEP_HASH_RESULT_SIZE_WORDS 16
-#define SEP_MD5_DIGEST_SIZE_WORDS 4
-#define SEP_MD5_DIGEST_SIZE_BYTES \
- (SEP_MD5_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA1_DIGEST_SIZE_WORDS 5
-#define SEP_SHA1_DIGEST_SIZE_BYTES \
- (SEP_SHA1_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA224_DIGEST_SIZE_WORDS 7
-#define SEP_SHA224_DIGEST_SIZE_BYTES \
- (SEP_SHA224_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA256_DIGEST_SIZE_WORDS 8
-#define SEP_SHA256_DIGEST_SIZE_BYTES \
- (SEP_SHA256_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA384_DIGEST_SIZE_WORDS 12
-#define SEP_SHA384_DIGEST_SIZE_BYTES \
- (SEP_SHA384_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA512_DIGEST_SIZE_WORDS 16
-#define SEP_SHA512_DIGEST_SIZE_BYTES \
- (SEP_SHA512_DIGEST_SIZE_WORDS * sizeof(u32))
-#define SEP_HASH_BLOCK_SIZE_WORDS 16
-#define SEP_HASH_BLOCK_SIZE_BYTES \
- (SEP_HASH_BLOCK_SIZE_WORDS * sizeof(u32))
-#define SEP_SHA2_BLOCK_SIZE_WORDS 32
-#define SEP_SHA2_BLOCK_SIZE_BYTES \
- (SEP_SHA2_BLOCK_SIZE_WORDS * sizeof(u32))
-
-#define SEP_HASH_INIT_OPCODE 0x20
-#define SEP_HASH_UPDATE_OPCODE 0x21
-#define SEP_HASH_FINISH_OPCODE 0x22
-#define SEP_HASH_SINGLE_OPCODE 0x23
-
-#define SEP_HOST_ERROR 0x0b000000
-#define SEP_OK 0x0
-#define SEP_INVALID_START (SEP_HOST_ERROR + 0x3)
-#define SEP_WRONG_OPCODE (SEP_HOST_ERROR + 0x1)
-
-#define SEP_TRANSACTION_WAIT_TIME 5
-
-#define SEP_QUEUE_LENGTH 2
-/* Macros */
-#ifndef __LITTLE_ENDIAN
-#define CHG_ENDIAN(val) \
- (((val) >> 24) | \
- (((val) & 0x00FF0000) >> 8) | \
- (((val) & 0x0000FF00) << 8) | \
- (((val) & 0x000000FF) << 24))
-#else
-#define CHG_ENDIAN(val) val
-#endif
-/* Enums for SEP (from vendor) */
-enum des_numkey {
- DES_KEY_1 = 1,
- DES_KEY_2 = 2,
- DES_KEY_3 = 3,
- SEP_NUMKEY_OPTIONS,
- SEP_NUMKEY_LAST = 0x7fffffff,
-};
-
-enum des_enc_mode {
- SEP_DES_ENCRYPT = 0,
- SEP_DES_DECRYPT = 1,
- SEP_DES_ENC_OPTIONS,
- SEP_DES_ENC_LAST = 0x7fffffff,
-};
-
-enum des_op_mode {
- SEP_DES_ECB = 0,
- SEP_DES_CBC = 1,
- SEP_OP_OPTIONS,
- SEP_OP_LAST = 0x7fffffff,
-};
-
-enum aes_keysize {
- AES_128 = 0,
- AES_192 = 1,
- AES_256 = 2,
- AES_512 = 3,
- AES_SIZE_OPTIONS,
- AEA_SIZE_LAST = 0x7FFFFFFF,
-};
-
-enum aes_enc_mode {
- SEP_AES_ENCRYPT = 0,
- SEP_AES_DECRYPT = 1,
- SEP_AES_ENC_OPTIONS,
- SEP_AES_ENC_LAST = 0x7FFFFFFF,
-};
-
-enum aes_op_mode {
- SEP_AES_ECB = 0,
- SEP_AES_CBC = 1,
- SEP_AES_MAC = 2,
- SEP_AES_CTR = 3,
- SEP_AES_XCBC = 4,
- SEP_AES_CMAC = 5,
- SEP_AES_XTS = 6,
- SEP_AES_OP_OPTIONS,
- SEP_AES_OP_LAST = 0x7FFFFFFF,
-};
-
-enum hash_op_mode {
- SEP_HASH_SHA1 = 0,
- SEP_HASH_SHA224 = 1,
- SEP_HASH_SHA256 = 2,
- SEP_HASH_SHA384 = 3,
- SEP_HASH_SHA512 = 4,
- SEP_HASH_MD5 = 5,
- SEP_HASH_OPTIONS,
- SEP_HASH_LAST_MODE = 0x7FFFFFFF,
-};
-
-/* Structures for SEP (from vendor) */
-struct sep_des_internal_key {
- u32 key1[SEP_DES_KEY_SIZE_WORDS];
- u32 key2[SEP_DES_KEY_SIZE_WORDS];
- u32 key3[SEP_DES_KEY_SIZE_WORDS];
-};
-
-struct sep_des_internal_context {
- u32 iv_context[SEP_DES_IV_SIZE_WORDS];
- struct sep_des_internal_key context_key;
- enum des_numkey nbr_keys;
- enum des_enc_mode encryption;
- enum des_op_mode operation;
- u8 dummy_block[SEP_DES_DUMMY_SIZE];
-};
-
-struct sep_des_private_context {
- u32 valid_tag;
- u32 iv;
- u8 ctx_buf[sizeof(struct sep_des_internal_context)];
-};
-
-/* This is the structure passed to SEP via msg area */
-struct sep_des_key {
- u32 key1[SEP_DES_KEY_SIZE_WORDS];
- u32 key2[SEP_DES_KEY_SIZE_WORDS];
- u32 key3[SEP_DES_KEY_SIZE_WORDS];
- u32 pad[SEP_DES_KEY_SIZE_WORDS];
-};
-
-struct sep_aes_internal_context {
- u32 aes_ctx_iv[SEP_AES_IV_SIZE_WORDS];
- u32 aes_ctx_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
- enum aes_keysize keysize;
- enum aes_enc_mode encmode;
- enum aes_op_mode opmode;
- u8 secret_key;
- u32 no_add_blocks;
- u32 last_block_size;
- u32 last_block[SEP_AES_BLOCK_SIZE_WORDS];
- u32 prev_iv[SEP_AES_BLOCK_SIZE_WORDS];
- u32 remaining_size;
- union {
- struct {
- u32 dkey1[SEP_AES_BLOCK_SIZE_WORDS];
- u32 dkey2[SEP_AES_BLOCK_SIZE_WORDS];
- u32 dkey3[SEP_AES_BLOCK_SIZE_WORDS];
- } cmac_data;
- struct {
- u32 xts_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
- u32 temp1[SEP_AES_BLOCK_SIZE_WORDS];
- u32 temp2[SEP_AES_BLOCK_SIZE_WORDS];
- } xtx_data;
- } s_data;
- u8 dummy_block[SEP_AES_DUMMY_BLOCK_SIZE];
-};
-
-struct sep_aes_private_context {
- u32 valid_tag;
- u32 aes_iv;
- u32 op_mode;
- u8 cbuff[sizeof(struct sep_aes_internal_context)];
-};
-
-struct sep_hash_internal_context {
- u32 hash_result[SEP_HASH_RESULT_SIZE_WORDS];
- enum hash_op_mode hash_opmode;
- u32 previous_data[SEP_SHA2_BLOCK_SIZE_WORDS];
- u16 prev_update_bytes;
- u32 total_proc_128bit[4];
- u16 op_mode_block_size;
- u8 dummy_aes_block[SEP_AES_DUMMY_BLOCK_SIZE];
-};
-
-struct sep_hash_private_context {
- u32 valid_tag;
- u32 iv;
- u8 internal_context[sizeof(struct sep_hash_internal_context)];
-};
-
-union key_t {
- struct sep_des_key des;
- u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS];
-};
-
-/* Context structures for crypto API */
-/**
- * Structure for this current task context
- * This same structure is used for both hash
- * and crypt in order to reduce duplicate code
- * for stuff that is done for both hash operations
- * and crypto operations. We cannot trust that the
- * system context is not pulled out from under
- * us during operation to operation, so all
- * critical stuff such as data pointers must
- * be in in a context that is exclusive for this
- * particular task at hand.
- */
-struct this_task_ctx {
- struct sep_device *sep_used;
- u32 done;
- unsigned char iv[100];
- enum des_enc_mode des_encmode;
- enum des_op_mode des_opmode;
- enum aes_enc_mode aes_encmode;
- enum aes_op_mode aes_opmode;
- u32 init_opcode;
- u32 block_opcode;
- size_t data_length;
- size_t ivlen;
- struct ablkcipher_walk walk;
- int i_own_sep; /* Do I have custody of the sep? */
- struct sep_call_status call_status;
- struct build_dcb_struct_kernel dcb_input_data;
- struct sep_dma_context *dma_ctx;
- void *dmatables_region;
- size_t nbytes;
- struct sep_dcblock *dcb_region;
- struct sep_queue_info *queue_elem;
- int msg_len_words;
- unsigned char msg[SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES];
- void *msgptr;
- struct scatterlist *src_sg;
- struct scatterlist *dst_sg;
- struct scatterlist *src_sg_hold;
- struct scatterlist *dst_sg_hold;
- struct ahash_request *current_hash_req;
- struct ablkcipher_request *current_cypher_req;
- enum type_of_request current_request;
- int digest_size_words;
- int digest_size_bytes;
- int block_size_words;
- int block_size_bytes;
- enum hash_op_mode hash_opmode;
- enum hash_stage current_hash_stage;
- /**
- * Not that this is a pointer. The are_we_done_yet variable is
- * allocated by the task function. This way, even if the kernel
- * crypto infrastructure has grabbed the task structure out from
- * under us, the task function can still see this variable.
- */
- int *are_we_done_yet;
- unsigned long end_time;
- };
-
-struct sep_system_ctx {
- union key_t key;
- size_t keylen;
- int key_sent;
- enum des_numkey des_nbr_keys;
- enum aes_keysize aes_key_size;
- unsigned long end_time;
- struct sep_des_private_context des_private_ctx;
- struct sep_aes_private_context aes_private_ctx;
- struct sep_hash_private_context hash_private_ctx;
- };
-
-/* work queue structures */
-struct sep_work_struct {
- struct work_struct work;
- void (*callback)(void *);
- void *data;
- };
-
-/* Functions */
-int sep_crypto_setup(void);
-void sep_crypto_takedown(void);
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h
deleted file mode 100644
index bf56c06662fd..000000000000
--- a/drivers/staging/sep/sep_dev.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef __SEP_DEV_H__
-#define __SEP_DEV_H__
-
-/*
- *
- * sep_dev.h - Security Processor Device Structures
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES
- * 2010.09.14 upgrade to Medfield
- * 2011.02.22 enable kernel crypto
- */
-
-struct sep_device {
- /* pointer to pci dev */
- struct pci_dev *pdev;
-
- /* character device file */
- struct cdev sep_cdev;
-
- /* devices (using misc dev) */
- struct miscdevice miscdev_sep;
-
- /* major / minor numbers of device */
- dev_t sep_devno;
- /* guards command sent counter */
- spinlock_t snd_rply_lck;
- /* guards driver memory usage in fastcall if */
- struct semaphore sep_doublebuf;
-
- /* flags to indicate use and lock status of sep */
- u32 pid_doing_transaction;
- unsigned long in_use_flags;
-
- /* address of the shared memory allocated during init for SEP driver
- (coherent alloc) */
- dma_addr_t shared_bus;
- size_t shared_size;
- void *shared_addr;
-
- /* start address of the access to the SEP registers from driver */
- dma_addr_t reg_physical_addr;
- dma_addr_t reg_physical_end;
- void __iomem *reg_addr;
-
- /* wait queue heads of the driver */
- wait_queue_head_t event_interrupt;
- wait_queue_head_t event_transactions;
-
- struct list_head sep_queue_status;
- u32 sep_queue_num;
- spinlock_t sep_queue_lock;
-
- /* Is this in use? */
- u32 in_use;
-
- /* indicates whether power save is set up */
- u32 power_save_setup;
-
- /* Power state */
- u32 power_state;
-
- /* transaction counter that coordinates the
- transactions between SEP and HOST */
- unsigned long send_ct;
- /* counter for the messages from sep */
- unsigned long reply_ct;
-
- /* The following are used for kernel crypto client requests */
- u32 in_kernel; /* Set for kernel client request */
- struct tasklet_struct finish_tasklet;
- enum type_of_request current_request;
- enum hash_stage current_hash_stage;
- struct ahash_request *current_hash_req;
- struct ablkcipher_request *current_cypher_req;
- struct this_task_ctx *ta_ctx;
- struct workqueue_struct *workqueue;
-};
-
-extern struct sep_device *sep_dev;
-
-/**
- * SEP message header for a transaction
- * @reserved: reserved memory (two words)
- * @token: SEP message token
- * @msg_len: message length
- * @opcpde: message opcode
- */
-struct sep_msgarea_hdr {
- u32 reserved[2];
- u32 token;
- u32 msg_len;
- u32 opcode;
-};
-
-/**
- * sep_queue_data - data to be maintained in status queue for a transaction
- * @opcode : transaction opcode
- * @size : message size
- * @pid: owner process
- * @name: owner process name
- */
-struct sep_queue_data {
- u32 opcode;
- u32 size;
- s32 pid;
- u8 name[TASK_COMM_LEN];
-};
-
-/** sep_queue_info - maintains status info of all transactions
- * @list: head of list
- * @sep_queue_data : data for transaction
- */
-struct sep_queue_info {
- struct list_head list;
- struct sep_queue_data data;
-};
-
-static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
-{
- void __iomem *addr = dev->reg_addr + reg;
- writel(value, addr);
-}
-
-static inline u32 sep_read_reg(struct sep_device *dev, int reg)
-{
- void __iomem *addr = dev->reg_addr + reg;
- return readl(addr);
-}
-
-/* wait for SRAM write complete(indirect write */
-static inline void sep_wait_sram_write(struct sep_device *dev)
-{
- u32 reg_val;
-
- do {
- reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
- } while (!(reg_val & 1));
-}
-
-
-#endif
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h
deleted file mode 100644
index 7ee1c3bf17d7..000000000000
--- a/drivers/staging/sep/sep_driver_api.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *
- * sep_driver_api.h - Security Processor Driver api definitions
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2010.09.14 Upgrade to Medfield
- * 2011.02.22 Enable kernel crypto
- *
- */
-
-#ifndef __SEP_DRIVER_API_H__
-#define __SEP_DRIVER_API_H__
-
-/* Type of request from device */
-#define SEP_DRIVER_SRC_REPLY 1
-#define SEP_DRIVER_SRC_REQ 2
-#define SEP_DRIVER_SRC_PRINTF 3
-
-/* Power state */
-#define SEP_DRIVER_POWERON 1
-#define SEP_DRIVER_POWEROFF 2
-
-/* Following enums are used only for kernel crypto api */
-enum type_of_request {
- NO_REQUEST,
- AES_CBC,
- AES_ECB,
- DES_CBC,
- DES_ECB,
- DES3_ECB,
- DES3_CBC,
- SHA1,
- MD5,
- SHA224,
- SHA256
- };
-
-enum hash_stage {
- HASH_INIT,
- HASH_UPDATE,
- HASH_FINISH,
- HASH_DIGEST,
- HASH_FINUP_DATA,
- HASH_FINUP_FINISH
-};
-
-/*
- structure that represents DCB
-*/
-struct sep_dcblock {
- /* physical address of the first input mlli */
- u32 input_mlli_address;
- /* num of entries in the first input mlli */
- u32 input_mlli_num_entries;
- /* size of data in the first input mlli */
- u32 input_mlli_data_size;
- /* physical address of the first output mlli */
- u32 output_mlli_address;
- /* num of entries in the first output mlli */
- u32 output_mlli_num_entries;
- /* size of data in the first output mlli */
- u32 output_mlli_data_size;
- /* pointer to the output virtual tail */
- aligned_u64 out_vr_tail_pt;
- /* size of tail data */
- u32 tail_data_size;
- /* input tail data array */
- u8 tail_data[68];
-};
-
-/*
- command structure for building dcb block (currently for ext app only)
-*/
-struct build_dcb_struct {
- /* address value of the data in */
- aligned_u64 app_in_address;
- /* size of data in */
- u32 data_in_size;
- /* address of the data out */
- aligned_u64 app_out_address;
- /* the size of the block of the operation - if needed,
- every table will be modulo this parameter */
- u32 block_size;
- /* the size of the block of the operation - if needed,
- every table will be modulo this parameter */
- u32 tail_block_size;
-
- /* which application calls the driver DX or applet */
- u32 is_applet;
-};
-
-/*
- command structure for building dcb block for kernel crypto
-*/
-struct build_dcb_struct_kernel {
- /* address value of the data in */
- void *app_in_address;
- /* size of data in */
- ssize_t data_in_size;
- /* address of the data out */
- void *app_out_address;
- /* the size of the block of the operation - if needed,
- every table will be modulo this parameter */
- u32 block_size;
- /* the size of the block of the operation - if needed,
- every table will be modulo this parameter */
- u32 tail_block_size;
-
- /* which application calls the driver DX or applet */
- u32 is_applet;
-
- struct scatterlist *src_sg;
- struct scatterlist *dst_sg;
-};
-
-/**
- * @struct sep_dma_map
- *
- * Structure that contains all information needed for mapping the user pages
- * or kernel buffers for dma operations
- *
- *
- */
-struct sep_dma_map {
- /* mapped dma address */
- dma_addr_t dma_addr;
- /* size of the mapped data */
- size_t size;
-};
-
-struct sep_dma_resource {
- /* array of pointers to the pages that represent
- input data for the synchronic DMA action */
- struct page **in_page_array;
-
- /* array of pointers to the pages that represent out
- data for the synchronic DMA action */
- struct page **out_page_array;
-
- /* number of pages in the sep_in_page_array */
- u32 in_num_pages;
-
- /* number of pages in the sep_out_page_array */
- u32 out_num_pages;
-
- /* map array of the input data */
- struct sep_dma_map *in_map_array;
-
- /* map array of the output data */
- struct sep_dma_map *out_map_array;
-
- /* number of entries of the input mapp array */
- u32 in_map_num_entries;
-
- /* number of entries of the output mapp array */
- u32 out_map_num_entries;
-
- /* Scatter list for kernel operations */
- struct scatterlist *src_sg;
- struct scatterlist *dst_sg;
-};
-
-
-/* command struct for translating rar handle to bus address
- and setting it at predefined location */
-struct rar_hndl_to_bus_struct {
-
- /* rar handle */
- aligned_u64 rar_handle;
-};
-
-/*
- structure that represent one entry in the DMA LLI table
-*/
-struct sep_lli_entry {
- /* physical address */
- u32 bus_address;
-
- /* block size */
- u32 block_size;
-};
-
-/*
- * header format for each fastcall write operation
- */
-struct sep_fastcall_hdr {
- u32 magic;
- u32 secure_dma;
- u32 msg_len;
- u32 num_dcbs;
-};
-
-/*
- * structure used in file pointer's private data field
- * to track the status of the calls to the various
- * driver interface
- */
-struct sep_call_status {
- unsigned long status;
-};
-
-/*
- * format of dma context buffer used to store all DMA-related
- * context information of a particular transaction
- */
-struct sep_dma_context {
- /* number of data control blocks */
- u32 nr_dcb_creat;
- /* number of the lli tables created in the current transaction */
- u32 num_lli_tables_created;
- /* size of currently allocated dma tables region */
- u32 dmatables_len;
- /* size of input data */
- u32 input_data_len;
- /* secure dma use (for imr memory restricted area in output) */
- bool secure_dma;
- struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS];
- /* Scatter gather for kernel crypto */
- struct scatterlist *src_sg;
- struct scatterlist *dst_sg;
-};
-
-/*
- * format for file pointer's private_data field
- */
-struct sep_private_data {
- struct sep_queue_info *my_queue_elem;
- struct sep_device *device;
- struct sep_call_status call_status;
- struct sep_dma_context *dma_ctx;
-};
-
-
-/* Functions used by sep_crypto */
-
-/**
- * sep_queue_status_remove - Removes transaction from status queue
- * @sep: SEP device
- * @sep_queue_info: pointer to status queue
- *
- * This function will removes information about transaction from the queue.
- */
-void sep_queue_status_remove(struct sep_device *sep,
- struct sep_queue_info **queue_elem);
-/**
- * sep_queue_status_add - Adds transaction to status queue
- * @sep: SEP device
- * @opcode: transaction opcode
- * @size: input data size
- * @pid: pid of current process
- * @name: current process name
- * @name_len: length of name (current process)
- *
- * This function adds information about about transaction started to the status
- * queue.
- */
-struct sep_queue_info *sep_queue_status_add(
- struct sep_device *sep,
- u32 opcode,
- u32 size,
- u32 pid,
- u8 *name, size_t name_len);
-
-/**
- * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context
- * for kernel crypto
- * @sep: SEP device
- * @dcb_region: DCB region buf to create for current transaction
- * @dmatables_region: MLLI/DMA tables buf to create for current transaction
- * @dma_ctx: DMA context buf to create for current transaction
- * @user_dcb_args: User arguments for DCB/MLLI creation
- * @num_dcbs: Number of DCBs to create
- */
-int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep,
- struct sep_dcblock **dcb_region,
- void **dmatables_region,
- struct sep_dma_context **dma_ctx,
- const struct build_dcb_struct_kernel *dcb_data,
- const u32 num_dcbs);
-
-/**
- * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables
- * contexts into use
- * @sep: SEP device
- * @dcb_region: DCB region copy
- * @dmatables_region: MLLI/DMA tables copy
- * @dma_ctx: DMA context for current transaction
- */
-ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep,
- struct sep_dcblock **dcb_region,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx);
-
-/**
- * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
- * @app_in_address: unsigned long; for data buffer in (user space)
- * @app_out_address: unsigned long; for data buffer out (user space)
- * @data_in_size: u32; for size of data
- * @block_size: u32; for block size
- * @tail_block_size: u32; for size of tail block
- * @isapplet: bool; to indicate external app
- * @is_kva: bool; kernel buffer; only used for kernel crypto module
- * @secure_dma; indicates whether this is secure_dma using IMR
- *
- * This function prepares the linked DMA tables and puts the
- * address for the linked list of tables inta a DCB (data control
- * block) the address of which is known by the SEP hardware
- * Note that all bus addresses that are passed to the SEP
- * are in 32 bit format; the SEP is a 32 bit device
- */
-int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
- unsigned long app_in_address,
- unsigned long app_out_address,
- u32 data_in_size,
- u32 block_size,
- u32 tail_block_size,
- bool isapplet,
- bool is_kva,
- bool secure_dma,
- struct sep_dcblock *dcb_region,
- void **dmatables_region,
- struct sep_dma_context **dma_ctx,
- struct scatterlist *src_sg,
- struct scatterlist *dst_sg);
-
-/**
- * sep_free_dma_table_data_handler - free DMA table
- * @sep: pointer to struct sep_device
- * @dma_ctx: dma context
- *
- * Handles the request to free DMA table for synchronic actions
- */
-int sep_free_dma_table_data_handler(struct sep_device *sep,
- struct sep_dma_context **dma_ctx);
-/**
- * sep_send_command_handler - kick off a command
- * @sep: SEP being signalled
- *
- * This function raises interrupt to SEP that signals that is has a new
- * command from the host
- *
- * Note that this function does fall under the ioctl lock
- */
-int sep_send_command_handler(struct sep_device *sep);
-
-/**
- * sep_wait_transaction - Used for synchronizing transactions
- * @sep: SEP device
- */
-int sep_wait_transaction(struct sep_device *sep);
-
-/**
- * IOCTL command defines
- */
-/* magic number 1 of the sep IOCTL command */
-#define SEP_IOC_MAGIC_NUMBER 's'
-
-/* sends interrupt to sep that message is ready */
-#define SEP_IOCSENDSEPCOMMAND \
- _IO(SEP_IOC_MAGIC_NUMBER, 0)
-
-/* end transaction command */
-#define SEP_IOCENDTRANSACTION \
- _IO(SEP_IOC_MAGIC_NUMBER, 15)
-
-#define SEP_IOCPREPAREDCB \
- _IOW(SEP_IOC_MAGIC_NUMBER, 35, struct build_dcb_struct)
-
-#define SEP_IOCFREEDCB \
- _IO(SEP_IOC_MAGIC_NUMBER, 36)
-
-struct sep_device;
-
-#define SEP_IOCPREPAREDCB_SECURE_DMA \
- _IOW(SEP_IOC_MAGIC_NUMBER, 38, struct build_dcb_struct)
-
-#define SEP_IOCFREEDCB_SECURE_DMA \
- _IO(SEP_IOC_MAGIC_NUMBER, 39)
-
-#endif
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h
deleted file mode 100644
index 4b6e30743634..000000000000
--- a/drivers/staging/sep/sep_driver_config.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- *
- * sep_driver_config.h - Security Processor Driver configuration
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2010.06.26 Upgrade to Medfield
- * 2011.02.22 Enable kernel crypto
- *
- */
-
-#ifndef __SEP_DRIVER_CONFIG_H__
-#define __SEP_DRIVER_CONFIG_H__
-
-
-/*--------------------------------------
- DRIVER CONFIGURATION FLAGS
- -------------------------------------*/
-
-/* if flag is on , then the driver is running in polling and
- not interrupt mode */
-#define SEP_DRIVER_POLLING_MODE 0
-
-/* flag which defines if the shared area address should be
- reconfigured (send to SEP anew) during init of the driver */
-#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0
-
-/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
-#define SEP_DRIVER_ARM_DEBUG_MODE 0
-
-/* Critical message area contents for sanity checking */
-#define SEP_START_MSG_TOKEN 0x02558808
-/*-------------------------------------------
- INTERNAL DATA CONFIGURATION
- -------------------------------------------*/
-
-/* flag for the input array */
-#define SEP_DRIVER_IN_FLAG 0
-
-/* flag for output array */
-#define SEP_DRIVER_OUT_FLAG 1
-
-/* maximum number of entries in one LLI tables */
-#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 31
-
-/* minimum data size of the MLLI table */
-#define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16
-
-/* flag that signifies tah the lock is
-currently held by the process (struct file) */
-#define SEP_DRIVER_OWN_LOCK_FLAG 1
-
-/* flag that signifies tah the lock is currently NOT
-held by the process (struct file) */
-#define SEP_DRIVER_DISOWN_LOCK_FLAG 0
-
-/* indicates whether driver has mapped/unmapped shared area */
-#define SEP_REQUEST_DAEMON_MAPPED 1
-#define SEP_REQUEST_DAEMON_UNMAPPED 0
-
-/*--------------------------------------------------------
- SHARED AREA memory total size is 36K
- it is divided is following:
-
- SHARED_MESSAGE_AREA 8K }
- }
- STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K)
- }
- DATA_POOL_AREA 12K }
-
- SYNCHRONIC_DMA_TABLES_AREA 29K
-
- placeholder until drver changes
- FLOW_DMA_TABLES_AREA 4K
-
- SYSTEM_MEMORY_AREA 3k
-
- SYSTEM_MEMORY total size is 3k
- it is divided as following:
-
- TIME_MEMORY_AREA 8B
------------------------------------------------------------*/
-
-#define SEP_DEV_NAME "sep_sec_driver"
-#define SEP_DEV_SINGLETON "sep_sec_singleton_driver"
-#define SEP_DEV_DAEMON "sep_req_daemon_driver"
-
-
-/*
- the minimum length of the message - includes 2 reserved fields
- at the start, then token, message size and opcode fields. all dwords
-*/
-#define SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES (5*sizeof(u32))
-
-/*
- the maximum length of the message - the rest of the message shared
- area will be dedicated to the dma lli tables
-*/
-#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024)
-
-/* the size of the message shared area in pages */
-#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024)
-
-/* the size of the data pool static area in pages */
-#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024)
-
-/* the size of the data pool shared area size in pages */
-#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (16 * 1024)
-
-/* the size of the message shared area in pages */
-#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 29)
-
-/* Placeholder until driver changes */
-#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4)
-
-/* system data (time, caller id etc') pool */
-#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES (1024 * 3)
-
-/* Offset of the sep printf buffer in the message area */
-#define SEP_DRIVER_PRINTF_OFFSET_IN_BYTES (5888)
-
-/* the size in bytes of the time memory */
-#define SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES 8
-
-/* the size in bytes of the RAR parameters memory */
-#define SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES 8
-
-/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and
- DATA POOL areas. area must be module 4k */
-#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 28)
-
-/*-----------------------------------------------
- offsets of the areas starting from the shared area start address
-*/
-
-/* message area offset */
-#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0
-
-/* static pool area offset */
-#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
-
-/* data pool area offset */
-#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
-
-/* synchronic dma tables area offset */
-#define SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES \
- (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
-
-/* system memory offset in bytes */
-#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
- (SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + \
- SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)
-
-/* offset of the time area */
-#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
- (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
-
-/* offset of the RAR area */
-#define SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES \
- (SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES + \
- SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES)
-
-/* offset of the caller id area */
-#define SEP_CALLER_ID_OFFSET_BYTES \
- (SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES + \
- SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES)
-
-/* offset of the DCB area */
-#define SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES \
- (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES + \
- 0x400)
-
-/* offset of the ext cache area */
-#define SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES \
- SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES
-
-/* offset of the allocation data pointer area */
-#define SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES \
- (SEP_CALLER_ID_OFFSET_BYTES + \
- SEP_CALLER_ID_HASH_SIZE_IN_BYTES)
-
-/* the token that defines the start of time address */
-#define SEP_TIME_VAL_TOKEN 0x12345678
-
-#define FAKE_RAR_SIZE (1024*1024) /* used only for mfld */
-/* DEBUG LEVEL MASKS */
-
-/* size of the caller id hash (sha2) */
-#define SEP_CALLER_ID_HASH_SIZE_IN_BYTES 32
-
-/* size of the caller id hash (sha2) in 32 bit words */
-#define SEP_CALLER_ID_HASH_SIZE_IN_WORDS 8
-
-/* maximum number of entries in the caller id table */
-#define SEP_CALLER_ID_TABLE_NUM_ENTRIES 20
-
-/* maximum number of symmetric operation (that require DMA resource)
- per one message */
-#define SEP_MAX_NUM_SYNC_DMA_OPS 16
-
-/* the token that defines the start of time address */
-#define SEP_RAR_VAL_TOKEN 0xABABABAB
-
-/* ioctl error that should be returned when trying
- to realloc the cache/resident second time */
-#define SEP_ALREADY_INITIALIZED_ERR 12
-
-/* bit that locks access to the shared area */
-#define SEP_TRANSACTION_STARTED_LOCK_BIT 0
-
-/* bit that lock access to the poll - after send_command */
-#define SEP_WORKING_LOCK_BIT 1
-
-/* the token that defines the static pool address address */
-#define SEP_STATIC_POOL_VAL_TOKEN 0xABBAABBA
-
-/* the token that defines the data pool pointers address */
-#define SEP_DATA_POOL_POINTERS_VAL_TOKEN 0xEDDEEDDE
-
-/* the token that defines the data pool pointers address */
-#define SEP_EXT_CACHE_ADDR_VAL_TOKEN 0xBABABABA
-
-/* Time limit for SEP to finish */
-#define WAIT_TIME 10
-
-/* Delay for pm runtime suspend (reduces pm thrashing with bursty traffic */
-#define SUSPEND_DELAY 10
-
-/* Number of delays to wait until scu boots after runtime resume */
-#define SCU_DELAY_MAX 50
-
-/* Delay for each iteration (usec) wait for scu boots after runtime resume */
-#define SCU_DELAY_ITERATION 10
-
-
-/*
- * Bits used in struct sep_call_status to check that
- * driver's APIs are called in valid order
- */
-
-/* Bit offset which indicates status of sep_write() */
-#define SEP_FASTCALL_WRITE_DONE_OFFSET 0
-
-/* Bit offset which indicates status of sep_mmap() */
-#define SEP_LEGACY_MMAP_DONE_OFFSET 1
-
-/* Bit offset which indicates status of the SEP_IOCSENDSEPCOMMAND ioctl */
-#define SEP_LEGACY_SENDMSG_DONE_OFFSET 2
-
-/* Bit offset which indicates status of sep_poll() */
-#define SEP_LEGACY_POLL_DONE_OFFSET 3
-
-/* Bit offset which indicates status of the SEP_IOCENDTRANSACTION ioctl */
-#define SEP_LEGACY_ENDTRANSACTION_DONE_OFFSET 4
-
-/*
- * Used to limit number of concurrent processes
- * allowed to allocate dynamic buffers in fastcall
- * interface.
- */
-#define SEP_DOUBLEBUF_USERS_LIMIT 3
-
-/* Identifier for valid fastcall header */
-#define SEP_FC_MAGIC 0xFFAACCAA
-
-/*
- * Used for enabling driver runtime power management.
- * Useful for enabling/disabling it during performance
- * testing
- */
-#define SEP_ENABLE_RUNTIME_PM
-
-#endif /* SEP DRIVER CONFIG */
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h
deleted file mode 100644
index a6a448170382..000000000000
--- a/drivers/staging/sep/sep_driver_hw_defs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * sep_driver_hw_defs.h - Security Processor Driver hardware definitions
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2010.09.20 Upgrade to Medfield
- * 2011.02.22 Enable kernel crypto
- *
- */
-
-#ifndef SEP_DRIVER_HW_DEFS__H
-#define SEP_DRIVER_HW_DEFS__H
-
-/*----------------------- */
-/* HW Registers Defines. */
-/* */
-/*---------------------- -*/
-
-
-/* cf registers */
-#define HW_HOST_IRR_REG_ADDR 0x0A00UL
-#define HW_HOST_IMR_REG_ADDR 0x0A04UL
-#define HW_HOST_ICR_REG_ADDR 0x0A08UL
-#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL
-#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL
-#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL
-#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL
-#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL
-#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL
-#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL
-#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL
-#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL
-
-#endif /* ifndef HW_DEFS */
diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c
deleted file mode 100644
index 75ca15e86a27..000000000000
--- a/drivers/staging/sep/sep_main.c
+++ /dev/null
@@ -1,4452 +0,0 @@
-/*
- *
- * sep_main.c - Security Processor Driver main group of functions
- *
- * Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
- * Contributions(c) 2009-2011 Discretix. 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; version 2 of the License.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- * Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- * 2010.09.14 Upgrade to Medfield
- * 2011.01.21 Move to sep_main.c to allow for sep_crypto.c
- * 2011.02.22 Enable kernel crypto operation
- *
- * Please note that this driver is based on information in the Discretix
- * CryptoCell 5.2 Driver Implementation Guide; the Discretix CryptoCell 5.2
- * Integration Intel Medfield appendix; the Discretix CryptoCell 5.2
- * Linux Driver Integration Guide; and the Discretix CryptoCell 5.2 System
- * Overview and Integration Guide.
- */
-/* #define DEBUG */
-/* #define SEP_PERF_DEBUG */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/pci.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/current.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <asm/cacheflush.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/async.h>
-#include <linux/crypto.h>
-#include <crypto/internal/hash.h>
-#include <crypto/scatterwalk.h>
-#include <crypto/sha.h>
-#include <crypto/md5.h>
-#include <crypto/aes.h>
-#include <crypto/des.h>
-#include <crypto/hash.h>
-
-#include "sep_driver_hw_defs.h"
-#include "sep_driver_config.h"
-#include "sep_driver_api.h"
-#include "sep_dev.h"
-#include "sep_crypto.h"
-
-#define CREATE_TRACE_POINTS
-#include "sep_trace_events.h"
-
-/*
- * Let's not spend cycles iterating over message
- * area contents if debugging not enabled
- */
-#ifdef DEBUG
-#define sep_dump_message(sep) _sep_dump_message(sep)
-#else
-#define sep_dump_message(sep)
-#endif
-
-/**
- * Currently, there is only one SEP device per platform;
- * In event platforms in the future have more than one SEP
- * device, this will be a linked list
- */
-
-struct sep_device *sep_dev;
-
-/**
- * sep_queue_status_remove - Removes transaction from status queue
- * @sep: SEP device
- * @sep_queue_info: pointer to status queue
- *
- * This function will remove information about transaction from the queue.
- */
-void sep_queue_status_remove(struct sep_device *sep,
- struct sep_queue_info **queue_elem)
-{
- unsigned long lck_flags;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove\n",
- current->pid);
-
- if (!queue_elem || !(*queue_elem)) {
- dev_dbg(&sep->pdev->dev, "PID%d %s null\n",
- current->pid, __func__);
- return;
- }
-
- spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
- list_del(&(*queue_elem)->list);
- sep->sep_queue_num--;
- spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
-
- kfree(*queue_elem);
- *queue_elem = NULL;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove return\n",
- current->pid);
- return;
-}
-
-/**
- * sep_queue_status_add - Adds transaction to status queue
- * @sep: SEP device
- * @opcode: transaction opcode
- * @size: input data size
- * @pid: pid of current process
- * @name: current process name
- * @name_len: length of name (current process)
- *
- * This function adds information about about transaction started to the status
- * queue.
- */
-struct sep_queue_info *sep_queue_status_add(
- struct sep_device *sep,
- u32 opcode,
- u32 size,
- u32 pid,
- u8 *name, size_t name_len)
-{
- unsigned long lck_flags;
- struct sep_queue_info *my_elem = NULL;
-
- my_elem = kzalloc(sizeof(struct sep_queue_info), GFP_KERNEL);
-
- if (!my_elem)
- return NULL;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] kzalloc ok\n", current->pid);
-
- my_elem->data.opcode = opcode;
- my_elem->data.size = size;
- my_elem->data.pid = pid;
-
- if (name_len > TASK_COMM_LEN)
- name_len = TASK_COMM_LEN;
-
- memcpy(&my_elem->data.name, name, name_len);
-
- spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
-
- list_add_tail(&my_elem->list, &sep->sep_queue_status);
- sep->sep_queue_num++;
-
- spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
-
- return my_elem;
-}
-
-/**
- * sep_allocate_dmatables_region - Allocates buf for the MLLI/DMA tables
- * @sep: SEP device
- * @dmatables_region: Destination pointer for the buffer
- * @dma_ctx: DMA context for the transaction
- * @table_count: Number of MLLI/DMA tables to create
- * The buffer created will not work as-is for DMA operations,
- * it needs to be copied over to the appropriate place in the
- * shared area.
- */
-static int sep_allocate_dmatables_region(struct sep_device *sep,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx,
- const u32 table_count)
-{
- const size_t new_len =
- SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1;
-
- void *tmp_region = NULL;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] dma_ctx = 0x%p\n",
- current->pid, dma_ctx);
- dev_dbg(&sep->pdev->dev, "[PID%d] dmatables_region = 0x%p\n",
- current->pid, dmatables_region);
-
- if (!dma_ctx || !dmatables_region) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] dma context/region uninitialized\n",
- current->pid);
- return -EINVAL;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08zX\n",
- current->pid, new_len);
- dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid,
- dma_ctx->dmatables_len);
- tmp_region = kzalloc(new_len + dma_ctx->dmatables_len, GFP_KERNEL);
- if (!tmp_region)
- return -ENOMEM;
-
- /* Were there any previous tables that need to be preserved ? */
- if (*dmatables_region) {
- memcpy(tmp_region, *dmatables_region, dma_ctx->dmatables_len);
- kfree(*dmatables_region);
- *dmatables_region = NULL;
- }
-
- *dmatables_region = tmp_region;
-
- dma_ctx->dmatables_len += new_len;
-
- return 0;
-}
-
-/**
- * sep_wait_transaction - Used for synchronizing transactions
- * @sep: SEP device
- */
-int sep_wait_transaction(struct sep_device *sep)
-{
- int error = 0;
- DEFINE_WAIT(wait);
-
- if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
- &sep->in_use_flags)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] no transactions, returning\n",
- current->pid);
- goto end_function_setpid;
- }
-
- /*
- * Looping needed even for exclusive waitq entries
- * due to process wakeup latencies, previous process
- * might have already created another transaction.
- */
- for (;;) {
- /*
- * Exclusive waitq entry, so that only one process is
- * woken up from the queue at a time.
- */
- prepare_to_wait_exclusive(&sep->event_transactions,
- &wait,
- TASK_INTERRUPTIBLE);
- if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
- &sep->in_use_flags)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] no transactions, breaking\n",
- current->pid);
- break;
- }
- dev_dbg(&sep->pdev->dev,
- "[PID%d] transactions ongoing, sleeping\n",
- current->pid);
- schedule();
- dev_dbg(&sep->pdev->dev, "[PID%d] woken up\n", current->pid);
-
- if (signal_pending(current)) {
- dev_dbg(&sep->pdev->dev, "[PID%d] received signal\n",
- current->pid);
- error = -EINTR;
- goto end_function;
- }
- }
-end_function_setpid:
- /*
- * The pid_doing_transaction indicates that this process
- * now owns the facilities to perform a transaction with
- * the SEP. While this process is performing a transaction,
- * no other process who has the SEP device open can perform
- * any transactions. This method allows more than one process
- * to have the device open at any given time, which provides
- * finer granularity for device utilization by multiple
- * processes.
- */
- /* Only one process is able to progress here at a time */
- sep->pid_doing_transaction = current->pid;
-
-end_function:
- finish_wait(&sep->event_transactions, &wait);
-
- return error;
-}
-
-/**
- * sep_check_transaction_owner - Checks if current process owns transaction
- * @sep: SEP device
- */
-static inline int sep_check_transaction_owner(struct sep_device *sep)
-{
- dev_dbg(&sep->pdev->dev, "[PID%d] transaction pid = %d\n",
- current->pid,
- sep->pid_doing_transaction);
-
- if ((sep->pid_doing_transaction == 0) ||
- (current->pid != sep->pid_doing_transaction)) {
- return -EACCES;
- }
-
- /* We own the transaction */
- return 0;
-}
-
-#ifdef DEBUG
-
-/**
- * sep_dump_message - dump the message that is pending
- * @sep: SEP device
- * This will only print dump if DEBUG is set; it does
- * follow kernel debug print enabling
- */
-static void _sep_dump_message(struct sep_device *sep)
-{
- int count;
-
- u32 *p = sep->shared_addr;
-
- for (count = 0; count < 10 * 4; count += 4)
- dev_dbg(&sep->pdev->dev,
- "[PID%d] Word %d of the message is %x\n",
- current->pid, count/4, *p++);
-}
-
-#endif
-
-/**
- * sep_map_and_alloc_shared_area -allocate shared block
- * @sep: security processor
- * @size: size of shared area
- */
-static int sep_map_and_alloc_shared_area(struct sep_device *sep)
-{
- sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev,
- sep->shared_size,
- &sep->shared_bus, GFP_KERNEL);
-
- if (!sep->shared_addr) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] shared memory dma_alloc_coherent failed\n",
- current->pid);
- return -ENOMEM;
- }
- dev_dbg(&sep->pdev->dev,
- "[PID%d] shared_addr %zx bytes @%p (bus %llx)\n",
- current->pid,
- sep->shared_size, sep->shared_addr,
- (unsigned long long)sep->shared_bus);
- return 0;
-}
-
-/**
- * sep_unmap_and_free_shared_area - free shared block
- * @sep: security processor
- */
-static void sep_unmap_and_free_shared_area(struct sep_device *sep)
-{
- dma_free_coherent(&sep->pdev->dev, sep->shared_size,
- sep->shared_addr, sep->shared_bus);
-}
-
-#ifdef DEBUG
-
-/**
- * sep_shared_bus_to_virt - convert bus/virt addresses
- * @sep: pointer to struct sep_device
- * @bus_address: address to convert
- *
- * Returns virtual address inside the shared area according
- * to the bus address.
- */
-static void *sep_shared_bus_to_virt(struct sep_device *sep,
- dma_addr_t bus_address)
-{
- return sep->shared_addr + (bus_address - sep->shared_bus);
-}
-
-#endif
-
-/**
- * sep_open - device open method
- * @inode: inode of SEP device
- * @filp: file handle to SEP device
- *
- * Open method for the SEP device. Called when userspace opens
- * the SEP device node.
- *
- * Returns zero on success otherwise an error code.
- */
-static int sep_open(struct inode *inode, struct file *filp)
-{
- struct sep_device *sep;
- struct sep_private_data *priv;
-
- dev_dbg(&sep_dev->pdev->dev, "[PID%d] open\n", current->pid);
-
- if (filp->f_flags & O_NONBLOCK)
- return -ENOTSUPP;
-
- /*
- * Get the SEP device structure and use it for the
- * private_data field in filp for other methods
- */
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- sep = sep_dev;
- priv->device = sep;
- filp->private_data = priv;
-
- dev_dbg(&sep_dev->pdev->dev, "[PID%d] priv is 0x%p\n",
- current->pid, priv);
-
- /* Anyone can open; locking takes place at transaction level */
- return 0;
-}
-
-/**
- * sep_free_dma_table_data_handler - free DMA table
- * @sep: pointer to struct sep_device
- * @dma_ctx: dma context
- *
- * Handles the request to free DMA table for synchronic actions
- */
-int sep_free_dma_table_data_handler(struct sep_device *sep,
- struct sep_dma_context **dma_ctx)
-{
- int count;
- int dcb_counter;
- /* Pointer to the current dma_resource struct */
- struct sep_dma_resource *dma;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] sep_free_dma_table_data_handler\n",
- current->pid);
-
- if (!dma_ctx || !(*dma_ctx)) {
- /* No context or context already freed */
- dev_dbg(&sep->pdev->dev,
- "[PID%d] no DMA context or context already freed\n",
- current->pid);
-
- return 0;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] (*dma_ctx)->nr_dcb_creat 0x%x\n",
- current->pid,
- (*dma_ctx)->nr_dcb_creat);
-
- for (dcb_counter = 0;
- dcb_counter < (*dma_ctx)->nr_dcb_creat; dcb_counter++) {
- dma = &(*dma_ctx)->dma_res_arr[dcb_counter];
-
- /* Unmap and free input map array */
- if (dma->in_map_array) {
- for (count = 0; count < dma->in_num_pages; count++) {
- dma_unmap_page(&sep->pdev->dev,
- dma->in_map_array[count].dma_addr,
- dma->in_map_array[count].size,
- DMA_TO_DEVICE);
- }
- kfree(dma->in_map_array);
- }
-
- /**
- * Output is handled different. If
- * this was a secure dma into restricted memory,
- * then we skip this step altogether as restricted
- * memory is not available to the o/s at all.
- */
- if (!(*dma_ctx)->secure_dma && dma->out_map_array) {
-
- for (count = 0; count < dma->out_num_pages; count++) {
- dma_unmap_page(&sep->pdev->dev,
- dma->out_map_array[count].dma_addr,
- dma->out_map_array[count].size,
- DMA_FROM_DEVICE);
- }
- kfree(dma->out_map_array);
- }
-
- /* Free page cache for output */
- if (dma->in_page_array) {
- for (count = 0; count < dma->in_num_pages; count++) {
- flush_dcache_page(dma->in_page_array[count]);
- page_cache_release(dma->in_page_array[count]);
- }
- kfree(dma->in_page_array);
- }
-
- /* Again, we do this only for non secure dma */
- if (!(*dma_ctx)->secure_dma && dma->out_page_array) {
-
- for (count = 0; count < dma->out_num_pages; count++) {
- if (!PageReserved(dma->out_page_array[count]))
-
- SetPageDirty(dma->
- out_page_array[count]);
-
- flush_dcache_page(dma->out_page_array[count]);
- page_cache_release(dma->out_page_array[count]);
- }
- kfree(dma->out_page_array);
- }
-
- /**
- * Note that here we use in_map_num_entries because we
- * don't have a page array; the page array is generated
- * only in the lock_user_pages, which is not called
- * for kernel crypto, which is what the sg (scatter gather
- * is used for exclusively)
- */
- if (dma->src_sg) {
- dma_unmap_sg(&sep->pdev->dev, dma->src_sg,
- dma->in_map_num_entries, DMA_TO_DEVICE);
- dma->src_sg = NULL;
- }
-
- if (dma->dst_sg) {
- dma_unmap_sg(&sep->pdev->dev, dma->dst_sg,
- dma->in_map_num_entries, DMA_FROM_DEVICE);
- dma->dst_sg = NULL;
- }
-
- /* Reset all the values */
- dma->in_page_array = NULL;
- dma->out_page_array = NULL;
- dma->in_num_pages = 0;
- dma->out_num_pages = 0;
- dma->in_map_array = NULL;
- dma->out_map_array = NULL;
- dma->in_map_num_entries = 0;
- dma->out_map_num_entries = 0;
- }
-
- (*dma_ctx)->nr_dcb_creat = 0;
- (*dma_ctx)->num_lli_tables_created = 0;
-
- kfree(*dma_ctx);
- *dma_ctx = NULL;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] sep_free_dma_table_data_handler end\n",
- current->pid);
-
- return 0;
-}
-
-/**
- * sep_end_transaction_handler - end transaction
- * @sep: pointer to struct sep_device
- * @dma_ctx: DMA context
- * @call_status: Call status
- *
- * This API handles the end transaction request.
- */
-static int sep_end_transaction_handler(struct sep_device *sep,
- struct sep_dma_context **dma_ctx,
- struct sep_call_status *call_status,
- struct sep_queue_info **my_queue_elem)
-{
- dev_dbg(&sep->pdev->dev, "[PID%d] ending transaction\n", current->pid);
-
- /*
- * Extraneous transaction clearing would mess up PM
- * device usage counters and SEP would get suspended
- * just before we send a command to SEP in the next
- * transaction
- * */
- if (sep_check_transaction_owner(sep)) {
- dev_dbg(&sep->pdev->dev, "[PID%d] not transaction owner\n",
- current->pid);
- return 0;
- }
-
- /* Update queue status */
- sep_queue_status_remove(sep, my_queue_elem);
-
- /* Check that all the DMA resources were freed */
- if (dma_ctx)
- sep_free_dma_table_data_handler(sep, dma_ctx);
-
- /* Reset call status for next transaction */
- if (call_status)
- call_status->status = 0;
-
- /* Clear the message area to avoid next transaction reading
- * sensitive results from previous transaction */
- memset(sep->shared_addr, 0,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- /* start suspend delay */
-#ifdef SEP_ENABLE_RUNTIME_PM
- if (sep->in_use) {
- sep->in_use = 0;
- pm_runtime_mark_last_busy(&sep->pdev->dev);
- pm_runtime_put_autosuspend(&sep->pdev->dev);
- }
-#endif
-
- clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags);
- sep->pid_doing_transaction = 0;
-
- /* Now it's safe for next process to proceed */
- dev_dbg(&sep->pdev->dev, "[PID%d] waking up next transaction\n",
- current->pid);
- clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, &sep->in_use_flags);
- wake_up(&sep->event_transactions);
-
- return 0;
-}
-
-
-/**
- * sep_release - close a SEP device
- * @inode: inode of SEP device
- * @filp: file handle being closed
- *
- * Called on the final close of a SEP device.
- */
-static int sep_release(struct inode *inode, struct file *filp)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
- struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] release\n", current->pid);
-
- sep_end_transaction_handler(sep, dma_ctx, call_status,
- my_queue_elem);
-
- kfree(filp->private_data);
-
- return 0;
-}
-
-/**
- * sep_mmap - maps the shared area to user space
- * @filp: pointer to struct file
- * @vma: pointer to vm_area_struct
- *
- * Called on an mmap of our space via the normal SEP device
- */
-static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
- dma_addr_t bus_addr;
- unsigned long error = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_mmap\n", current->pid);
-
- /* Set the transaction busy (own the device) */
- /*
- * Problem for multithreaded applications is that here we're
- * possibly going to sleep while holding a write lock on
- * current->mm->mmap_sem, which will cause deadlock for ongoing
- * transaction trying to create DMA tables
- */
- error = sep_wait_transaction(sep);
- if (error)
- /* Interrupted by signal, don't clear transaction */
- goto end_function;
-
- /* Clear the message area to avoid next transaction reading
- * sensitive results from previous transaction */
- memset(sep->shared_addr, 0,
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
-
- /*
- * Check that the size of the mapped range is as the size of the message
- * shared area
- */
- if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
- error = -EINVAL;
- goto end_function_with_error;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] shared_addr is %p\n",
- current->pid, sep->shared_addr);
-
- /* Get bus address */
- bus_addr = sep->shared_bus;
-
- if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- dev_dbg(&sep->pdev->dev, "[PID%d] remap_pfn_range failed\n",
- current->pid);
- error = -EAGAIN;
- goto end_function_with_error;
- }
-
- /* Update call status */
- set_bit(SEP_LEGACY_MMAP_DONE_OFFSET, &call_status->status);
-
- goto end_function;
-
-end_function_with_error:
- /* Clear our transaction */
- sep_end_transaction_handler(sep, NULL, call_status,
- my_queue_elem);
-
-end_function:
- return error;
-}
-
-/**
- * sep_poll - poll handler
- * @filp: pointer to struct file
- * @wait: pointer to poll_table
- *
- * Called by the OS when the kernel is asked to do a poll on
- * a SEP file handle.
- */
-static unsigned int sep_poll(struct file *filp, poll_table *wait)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- u32 mask = 0;
- u32 retval = 0;
- u32 retval2 = 0;
- unsigned long lock_irq_flag;
-
- /* Am I the process that owns the transaction? */
- if (sep_check_transaction_owner(sep)) {
- dev_dbg(&sep->pdev->dev, "[PID%d] poll pid not owner\n",
- current->pid);
- mask = POLLERR;
- goto end_function;
- }
-
- /* Check if send command or send_reply were activated previously */
- if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &call_status->status)) {
- dev_warn(&sep->pdev->dev, "[PID%d] sendmsg not called\n",
- current->pid);
- mask = POLLERR;
- goto end_function;
- }
-
-
- /* Add the event to the polling wait table */
- dev_dbg(&sep->pdev->dev, "[PID%d] poll: calling wait sep_event\n",
- current->pid);
-
- poll_wait(filp, &sep->event_interrupt, wait);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll: send_ct is %lx reply ct is %lx\n",
- current->pid, sep->send_ct, sep->reply_ct);
-
- /* Check if error occurred during poll */
- retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- if ((retval2 != 0x0) && (retval2 != 0x8)) {
- dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n",
- current->pid, retval2);
- mask |= POLLERR;
- goto end_function;
- }
-
- spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
-
- if (sep->send_ct == sep->reply_ct) {
- spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
- retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll: data ready check (GPR2) %x\n",
- current->pid, retval);
-
- /* Check if printf request */
- if ((retval >> 30) & 0x1) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll: SEP printf request\n",
- current->pid);
- goto end_function;
- }
-
- /* Check if the this is SEP reply or request */
- if (retval >> 31) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll: SEP request\n",
- current->pid);
- } else {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll: normal return\n",
- current->pid);
- sep_dump_message(sep);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll; SEP reply POLLIN|POLLRDNORM\n",
- current->pid);
- mask |= POLLIN | POLLRDNORM;
- }
- set_bit(SEP_LEGACY_POLL_DONE_OFFSET, &call_status->status);
- } else {
- spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] poll; no reply; returning mask of 0\n",
- current->pid);
- mask = 0;
- }
-
-end_function:
- return mask;
-}
-
-/**
- * sep_time_address - address in SEP memory of time
- * @sep: SEP device we want the address from
- *
- * Return the address of the two dwords in memory used for time
- * setting.
- */
-static u32 *sep_time_address(struct sep_device *sep)
-{
- return sep->shared_addr +
- SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
-}
-
-/**
- * sep_set_time - set the SEP time
- * @sep: the SEP we are setting the time for
- *
- * Calculates time and sets it at the predefined address.
- * Called with the SEP mutex held.
- */
-static unsigned long sep_set_time(struct sep_device *sep)
-{
- struct timeval time;
- u32 *time_addr; /* Address of time as seen by the kernel */
-
-
- do_gettimeofday(&time);
-
- /* Set value in the SYSTEM MEMORY offset */
- time_addr = sep_time_address(sep);
-
- time_addr[0] = SEP_TIME_VAL_TOKEN;
- time_addr[1] = time.tv_sec;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] time.tv_sec is %lu\n",
- current->pid, time.tv_sec);
- dev_dbg(&sep->pdev->dev, "[PID%d] time_addr is %p\n",
- current->pid, time_addr);
- dev_dbg(&sep->pdev->dev, "[PID%d] sep->shared_addr is %p\n",
- current->pid, sep->shared_addr);
-
- return time.tv_sec;
-}
-
-/**
- * sep_send_command_handler - kick off a command
- * @sep: SEP being signalled
- *
- * This function raises interrupt to SEP that signals that is has a new
- * command from the host
- *
- * Note that this function does fall under the ioctl lock
- */
-int sep_send_command_handler(struct sep_device *sep)
-{
- unsigned long lock_irq_flag;
- u32 *msg_pool;
- int error = 0;
-
- /* Basic sanity check; set msg pool to start of shared area */
- msg_pool = (u32 *)sep->shared_addr;
- msg_pool += 2;
-
- /* Look for start msg token */
- if (*msg_pool != SEP_START_MSG_TOKEN) {
- dev_warn(&sep->pdev->dev, "start message token not present\n");
- error = -EPROTO;
- goto end_function;
- }
-
- /* Do we have a reasonable size? */
- msg_pool += 1;
- if ((*msg_pool < 2) ||
- (*msg_pool > SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES)) {
-
- dev_warn(&sep->pdev->dev, "invalid message size\n");
- error = -EPROTO;
- goto end_function;
- }
-
- /* Does the command look reasonable? */
- msg_pool += 1;
- if (*msg_pool < 2) {
- dev_warn(&sep->pdev->dev, "invalid message opcode\n");
- error = -EPROTO;
- goto end_function;
- }
-
-#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM)
- dev_dbg(&sep->pdev->dev, "[PID%d] before pm sync status 0x%X\n",
- current->pid,
- sep->pdev->dev.power.runtime_status);
- sep->in_use = 1; /* device is about to be used */
- pm_runtime_get_sync(&sep->pdev->dev);
-#endif
-
- if (test_and_set_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags)) {
- error = -EPROTO;
- goto end_function;
- }
- sep->in_use = 1; /* device is about to be used */
- sep_set_time(sep);
-
- sep_dump_message(sep);
-
- /* Update counter */
- spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
- sep->send_ct++;
- spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] sep_send_command_handler send_ct %lx reply_ct %lx\n",
- current->pid, sep->send_ct, sep->reply_ct);
-
- /* Send interrupt to SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
-
-end_function:
- return error;
-}
-
-/**
- * sep_crypto_dma -
- * @sep: pointer to struct sep_device
- * @sg: pointer to struct scatterlist
- * @direction:
- * @dma_maps: pointer to place a pointer to array of dma maps
- * This is filled in; anything previous there will be lost
- * The structure for dma maps is sep_dma_map
- * @returns number of dma maps on success; negative on error
- *
- * This creates the dma table from the scatterlist
- * It is used only for kernel crypto as it works with scatterlists
- * representation of data buffers
- *
- */
-static int sep_crypto_dma(
- struct sep_device *sep,
- struct scatterlist *sg,
- struct sep_dma_map **dma_maps,
- enum dma_data_direction direction)
-{
- struct scatterlist *temp_sg;
-
- u32 count_segment;
- u32 count_mapped;
- struct sep_dma_map *sep_dma;
- int ct1;
-
- if (sg->length == 0)
- return 0;
-
- /* Count the segments */
- temp_sg = sg;
- count_segment = 0;
- while (temp_sg) {
- count_segment += 1;
- temp_sg = scatterwalk_sg_next(temp_sg);
- }
- dev_dbg(&sep->pdev->dev,
- "There are (hex) %x segments in sg\n", count_segment);
-
- /* DMA map segments */
- count_mapped = dma_map_sg(&sep->pdev->dev, sg,
- count_segment, direction);
-
- dev_dbg(&sep->pdev->dev,
- "There are (hex) %x maps in sg\n", count_mapped);
-
- if (count_mapped == 0) {
- dev_dbg(&sep->pdev->dev, "Cannot dma_map_sg\n");
- return -ENOMEM;
- }
-
- sep_dma = kmalloc(sizeof(struct sep_dma_map) *
- count_mapped, GFP_ATOMIC);
-
- if (sep_dma == NULL) {
- dev_dbg(&sep->pdev->dev, "Cannot allocate dma_maps\n");
- return -ENOMEM;
- }
-
- for_each_sg(sg, temp_sg, count_mapped, ct1) {
- sep_dma[ct1].dma_addr = sg_dma_address(temp_sg);
- sep_dma[ct1].size = sg_dma_len(temp_sg);
- dev_dbg(&sep->pdev->dev, "(all hex) map %x dma %lx len %lx\n",
- ct1, (unsigned long)sep_dma[ct1].dma_addr,
- (unsigned long)sep_dma[ct1].size);
- }
-
- *dma_maps = sep_dma;
- return count_mapped;
-
-}
-
-/**
- * sep_crypto_lli -
- * @sep: pointer to struct sep_device
- * @sg: pointer to struct scatterlist
- * @data_size: total data size
- * @direction:
- * @dma_maps: pointer to place a pointer to array of dma maps
- * This is filled in; anything previous there will be lost
- * The structure for dma maps is sep_dma_map
- * @lli_maps: pointer to place a pointer to array of lli maps
- * This is filled in; anything previous there will be lost
- * The structure for dma maps is sep_dma_map
- * @returns number of dma maps on success; negative on error
- *
- * This creates the LLI table from the scatterlist
- * It is only used for kernel crypto as it works exclusively
- * with scatterlists (struct scatterlist) representation of
- * data buffers
- */
-static int sep_crypto_lli(
- struct sep_device *sep,
- struct scatterlist *sg,
- struct sep_dma_map **maps,
- struct sep_lli_entry **llis,
- u32 data_size,
- enum dma_data_direction direction)
-{
-
- int ct1;
- struct sep_lli_entry *sep_lli;
- struct sep_dma_map *sep_map;
-
- int nbr_ents;
-
- nbr_ents = sep_crypto_dma(sep, sg, maps, direction);
- if (nbr_ents <= 0) {
- dev_dbg(&sep->pdev->dev, "crypto_dma failed %x\n",
- nbr_ents);
- return nbr_ents;
- }
-
- sep_map = *maps;
-
- sep_lli = kmalloc(sizeof(struct sep_lli_entry) * nbr_ents, GFP_ATOMIC);
-
- if (sep_lli == NULL) {
- dev_dbg(&sep->pdev->dev, "Cannot allocate lli_maps\n");
-
- kfree(*maps);
- *maps = NULL;
- return -ENOMEM;
- }
-
- for (ct1 = 0; ct1 < nbr_ents; ct1 += 1) {
- sep_lli[ct1].bus_address = (u32)sep_map[ct1].dma_addr;
-
- /* Maximum for page is total data size */
- if (sep_map[ct1].size > data_size)
- sep_map[ct1].size = data_size;
-
- sep_lli[ct1].block_size = (u32)sep_map[ct1].size;
- }
-
- *llis = sep_lli;
- return nbr_ents;
-}
-
-/**
- * sep_lock_kernel_pages - map kernel pages for DMA
- * @sep: pointer to struct sep_device
- * @kernel_virt_addr: address of data buffer in kernel
- * @data_size: size of data
- * @lli_array_ptr: lli array
- * @in_out_flag: input into device or output from device
- *
- * This function locks all the physical pages of the kernel virtual buffer
- * and construct a basic lli array, where each entry holds the physical
- * page address and the size that application data holds in this page
- * This function is used only during kernel crypto mod calls from within
- * the kernel (when ioctl is not used)
- *
- * This is used only for kernel crypto. Kernel pages
- * are handled differently as they are done via
- * scatter gather lists (struct scatterlist)
- */
-static int sep_lock_kernel_pages(struct sep_device *sep,
- unsigned long kernel_virt_addr,
- u32 data_size,
- struct sep_lli_entry **lli_array_ptr,
- int in_out_flag,
- struct sep_dma_context *dma_ctx)
-
-{
- u32 num_pages;
- struct scatterlist *sg;
-
- /* Array of lli */
- struct sep_lli_entry *lli_array;
- /* Map array */
- struct sep_dma_map *map_array;
-
- enum dma_data_direction direction;
-
- lli_array = NULL;
- map_array = NULL;
-
- if (in_out_flag == SEP_DRIVER_IN_FLAG) {
- direction = DMA_TO_DEVICE;
- sg = dma_ctx->src_sg;
- } else {
- direction = DMA_FROM_DEVICE;
- sg = dma_ctx->dst_sg;
- }
-
- num_pages = sep_crypto_lli(sep, sg, &map_array, &lli_array,
- data_size, direction);
-
- if (num_pages <= 0) {
- dev_dbg(&sep->pdev->dev, "sep_crypto_lli returned error %x\n",
- num_pages);
- return -ENOMEM;
- }
-
- /* Put mapped kernel sg into kernel resource array */
-
- /* Set output params according to the in_out flag */
- if (in_out_flag == SEP_DRIVER_IN_FLAG) {
- *lli_array_ptr = lli_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array =
- NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array =
- map_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg =
- dma_ctx->src_sg;
- } else {
- *lli_array_ptr = lli_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array =
- NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array =
- map_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
- out_map_num_entries = num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg =
- dma_ctx->dst_sg;
- }
-
- return 0;
-}
-
-/**
- * sep_lock_user_pages - lock and map user pages for DMA
- * @sep: pointer to struct sep_device
- * @app_virt_addr: user memory data buffer
- * @data_size: size of data buffer
- * @lli_array_ptr: lli array
- * @in_out_flag: input or output to device
- *
- * This function locks all the physical pages of the application
- * virtual buffer and construct a basic lli array, where each entry
- * holds the physical page address and the size that application
- * data holds in this physical pages
- */
-static int sep_lock_user_pages(struct sep_device *sep,
- u32 app_virt_addr,
- u32 data_size,
- struct sep_lli_entry **lli_array_ptr,
- int in_out_flag,
- struct sep_dma_context *dma_ctx)
-
-{
- int error = 0;
- u32 count;
- int result;
- /* The the page of the end address of the user space buffer */
- u32 end_page;
- /* The page of the start address of the user space buffer */
- u32 start_page;
- /* The range in pages */
- u32 num_pages;
- /* Array of pointers to page */
- struct page **page_array;
- /* Array of lli */
- struct sep_lli_entry *lli_array;
- /* Map array */
- struct sep_dma_map *map_array;
-
- /* Set start and end pages and num pages */
- end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
- start_page = app_virt_addr >> PAGE_SHIFT;
- num_pages = end_page - start_page + 1;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lock user pages app_virt_addr is %x\n",
- current->pid, app_virt_addr);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n",
- current->pid, data_size);
- dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n",
- current->pid, start_page);
- dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n",
- current->pid, end_page);
- dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n",
- current->pid, num_pages);
-
- /* Allocate array of pages structure pointers */
- page_array = kmalloc_array(num_pages, sizeof(struct page *),
- GFP_ATOMIC);
- if (!page_array) {
- error = -ENOMEM;
- goto end_function;
- }
-
- map_array = kmalloc_array(num_pages, sizeof(struct sep_dma_map),
- GFP_ATOMIC);
- if (!map_array) {
- error = -ENOMEM;
- goto end_function_with_error1;
- }
-
- lli_array = kmalloc_array(num_pages, sizeof(struct sep_lli_entry),
- GFP_ATOMIC);
- if (!lli_array) {
- error = -ENOMEM;
- goto end_function_with_error2;
- }
-
- /* Convert the application virtual address into a set of physical */
- result = get_user_pages_fast(app_virt_addr, num_pages,
- ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), page_array);
-
- /* Check the number of pages locked - if not all then exit with error */
- if (result != num_pages) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] not all pages locked by get_user_pages, result 0x%X, num_pages 0x%X\n",
- current->pid, result, num_pages);
- error = -ENOMEM;
- goto end_function_with_error3;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] get_user_pages succeeded\n",
- current->pid);
-
- /*
- * Fill the array using page array data and
- * map the pages - this action will also flush the cache as needed
- */
- for (count = 0; count < num_pages; count++) {
- /* Fill the map array */
- map_array[count].dma_addr =
- dma_map_page(&sep->pdev->dev, page_array[count],
- 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
-
- map_array[count].size = PAGE_SIZE;
-
- /* Fill the lli array entry */
- lli_array[count].bus_address = (u32)map_array[count].dma_addr;
- lli_array[count].block_size = PAGE_SIZE;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is (hex) %x\n",
- current->pid, count,
- (unsigned long)lli_array[count].bus_address,
- count, lli_array[count].block_size);
- }
-
- /* Check the offset for the first page */
- lli_array[0].bus_address =
- lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));
-
- /* Check that not all the data is in the first page only */
- if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
- lli_array[0].block_size = data_size;
- else
- lli_array[0].block_size =
- PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] After check if page 0 has all data\n",
- current->pid);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_array[0].bus_address is (hex) %08lx, lli_array[0].block_size is (hex) %x\n",
- current->pid,
- (unsigned long)lli_array[0].bus_address,
- lli_array[0].block_size);
-
-
- /* Check the size of the last page */
- if (num_pages > 1) {
- lli_array[num_pages - 1].block_size =
- (app_virt_addr + data_size) & (~PAGE_MASK);
- if (lli_array[num_pages - 1].block_size == 0)
- lli_array[num_pages - 1].block_size = PAGE_SIZE;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] After last page size adjustment\n",
- current->pid);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_array[%x].bus_address is (hex) %08lx, lli_array[%x].block_size is (hex) %x\n",
- current->pid,
- num_pages - 1,
- (unsigned long)lli_array[num_pages - 1].bus_address,
- num_pages - 1,
- lli_array[num_pages - 1].block_size);
- }
-
- /* Set output params according to the in_out flag */
- if (in_out_flag == SEP_DRIVER_IN_FLAG) {
- *lli_array_ptr = lli_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array =
- page_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array =
- map_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = NULL;
- } else {
- *lli_array_ptr = lli_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages =
- num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array =
- page_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array =
- map_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
- out_map_num_entries = num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = NULL;
- }
- goto end_function;
-
-end_function_with_error3:
- /* Free lli array */
- kfree(lli_array);
-
-end_function_with_error2:
- kfree(map_array);
-
-end_function_with_error1:
- /* Free page array */
- kfree(page_array);
-
-end_function:
- return error;
-}
-
-/**
- * sep_lli_table_secure_dma - get lli array for IMR addresses
- * @sep: pointer to struct sep_device
- * @app_virt_addr: user memory data buffer
- * @data_size: size of data buffer
- * @lli_array_ptr: lli array
- * @in_out_flag: not used
- * @dma_ctx: pointer to struct sep_dma_context
- *
- * This function creates lli tables for outputting data to
- * IMR memory, which is memory that cannot be accessed by the
- * the x86 processor.
- */
-static int sep_lli_table_secure_dma(struct sep_device *sep,
- u32 app_virt_addr,
- u32 data_size,
- struct sep_lli_entry **lli_array_ptr,
- int in_out_flag,
- struct sep_dma_context *dma_ctx)
-
-{
- u32 count;
- /* The the page of the end address of the user space buffer */
- u32 end_page;
- /* The page of the start address of the user space buffer */
- u32 start_page;
- /* The range in pages */
- u32 num_pages;
- /* Array of lli */
- struct sep_lli_entry *lli_array;
-
- /* Set start and end pages and num pages */
- end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
- start_page = app_virt_addr >> PAGE_SHIFT;
- num_pages = end_page - start_page + 1;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lock user pages app_virt_addr is %x\n",
- current->pid, app_virt_addr);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n",
- current->pid, data_size);
- dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n",
- current->pid, start_page);
- dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n",
- current->pid, end_page);
- dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n",
- current->pid, num_pages);
-
- lli_array = kmalloc_array(num_pages, sizeof(struct sep_lli_entry),
- GFP_ATOMIC);
- if (!lli_array)
- return -ENOMEM;
-
- /*
- * Fill the lli_array
- */
- start_page = start_page << PAGE_SHIFT;
- for (count = 0; count < num_pages; count++) {
- /* Fill the lli array entry */
- lli_array[count].bus_address = start_page;
- lli_array[count].block_size = PAGE_SIZE;
-
- start_page += PAGE_SIZE;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is (hex) %x\n",
- current->pid,
- count, (unsigned long)lli_array[count].bus_address,
- count, lli_array[count].block_size);
- }
-
- /* Check the offset for the first page */
- lli_array[0].bus_address =
- lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));
-
- /* Check that not all the data is in the first page only */
- if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
- lli_array[0].block_size = data_size;
- else
- lli_array[0].block_size =
- PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] After check if page 0 has all data\n"
- "lli_array[0].bus_address is (hex) %08lx, lli_array[0].block_size is (hex) %x\n",
- current->pid,
- (unsigned long)lli_array[0].bus_address,
- lli_array[0].block_size);
-
- /* Check the size of the last page */
- if (num_pages > 1) {
- lli_array[num_pages - 1].block_size =
- (app_virt_addr + data_size) & (~PAGE_MASK);
- if (lli_array[num_pages - 1].block_size == 0)
- lli_array[num_pages - 1].block_size = PAGE_SIZE;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] After last page size adjustment\n"
- "lli_array[%x].bus_address is (hex) %08lx, lli_array[%x].block_size is (hex) %x\n",
- current->pid, num_pages - 1,
- (unsigned long)lli_array[num_pages - 1].bus_address,
- num_pages - 1,
- lli_array[num_pages - 1].block_size);
- }
- *lli_array_ptr = lli_array;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = num_pages;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_num_entries = 0;
-
- return 0;
-}
-
-/**
- * sep_calculate_lli_table_max_size - size the LLI table
- * @sep: pointer to struct sep_device
- * @lli_in_array_ptr
- * @num_array_entries
- * @last_table_flag
- *
- * This function calculates the size of data that can be inserted into
- * the lli table from this array, such that either the table is full
- * (all entries are entered), or there are no more entries in the
- * lli array
- */
-static u32 sep_calculate_lli_table_max_size(struct sep_device *sep,
- struct sep_lli_entry *lli_in_array_ptr,
- u32 num_array_entries,
- u32 *last_table_flag)
-{
- u32 counter;
- /* Table data size */
- u32 table_data_size = 0;
- /* Data size for the next table */
- u32 next_table_data_size;
-
- *last_table_flag = 0;
-
- /*
- * Calculate the data in the out lli table till we fill the whole
- * table or till the data has ended
- */
- for (counter = 0;
- (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) &&
- (counter < num_array_entries); counter++)
- table_data_size += lli_in_array_ptr[counter].block_size;
-
- /*
- * Check if we reached the last entry,
- * meaning this ia the last table to build,
- * and no need to check the block alignment
- */
- if (counter == num_array_entries) {
- /* Set the last table flag */
- *last_table_flag = 1;
- goto end_function;
- }
-
- /*
- * Calculate the data size of the next table.
- * Stop if no entries left or if data size is more the DMA restriction
- */
- next_table_data_size = 0;
- for (; counter < num_array_entries; counter++) {
- next_table_data_size += lli_in_array_ptr[counter].block_size;
- if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
- break;
- }
-
- /*
- * Check if the next table data size is less then DMA rstriction.
- * if it is - recalculate the current table size, so that the next
- * table data size will be adaquete for DMA
- */
- if (next_table_data_size &&
- next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
-
- table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE -
- next_table_data_size);
-
-end_function:
- return table_data_size;
-}
-
-/**
- * sep_build_lli_table - build an lli array for the given table
- * @sep: pointer to struct sep_device
- * @lli_array_ptr: pointer to lli array
- * @lli_table_ptr: pointer to lli table
- * @num_processed_entries_ptr: pointer to number of entries
- * @num_table_entries_ptr: pointer to number of tables
- * @table_data_size: total data size
- *
- * Builds an lli table from the lli_array according to
- * the given size of data
- */
-static void sep_build_lli_table(struct sep_device *sep,
- struct sep_lli_entry *lli_array_ptr,
- struct sep_lli_entry *lli_table_ptr,
- u32 *num_processed_entries_ptr,
- u32 *num_table_entries_ptr,
- u32 table_data_size)
-{
- /* Current table data size */
- u32 curr_table_data_size;
- /* Counter of lli array entry */
- u32 array_counter;
-
- /* Init current table data size and lli array entry counter */
- curr_table_data_size = 0;
- array_counter = 0;
- *num_table_entries_ptr = 1;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] build lli table table_data_size: (hex) %x\n",
- current->pid, table_data_size);
-
- /* Fill the table till table size reaches the needed amount */
- while (curr_table_data_size < table_data_size) {
- /* Update the number of entries in table */
- (*num_table_entries_ptr)++;
-
- lli_table_ptr->bus_address =
- cpu_to_le32(lli_array_ptr[array_counter].bus_address);
-
- lli_table_ptr->block_size =
- cpu_to_le32(lli_array_ptr[array_counter].block_size);
-
- curr_table_data_size += lli_array_ptr[array_counter].block_size;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr is %p\n",
- current->pid, lli_table_ptr);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr->bus_address: %08lx\n",
- current->pid,
- (unsigned long)lli_table_ptr->bus_address);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr->block_size is (hex) %x\n",
- current->pid, lli_table_ptr->block_size);
-
- /* Check for overflow of the table data */
- if (curr_table_data_size > table_data_size) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] curr_table_data_size too large\n",
- current->pid);
-
- /* Update the size of block in the table */
- lli_table_ptr->block_size =
- cpu_to_le32(lli_table_ptr->block_size) -
- (curr_table_data_size - table_data_size);
-
- /* Update the physical address in the lli array */
- lli_array_ptr[array_counter].bus_address +=
- cpu_to_le32(lli_table_ptr->block_size);
-
- /* Update the block size left in the lli array */
- lli_array_ptr[array_counter].block_size =
- (curr_table_data_size - table_data_size);
- } else
- /* Advance to the next entry in the lli_array */
- array_counter++;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr->bus_address is %08lx\n",
- current->pid,
- (unsigned long)lli_table_ptr->bus_address);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr->block_size is (hex) %x\n",
- current->pid,
- lli_table_ptr->block_size);
-
- /* Move to the next entry in table */
- lli_table_ptr++;
- }
-
- /* Set the info entry to default */
- lli_table_ptr->bus_address = 0xffffffff;
- lli_table_ptr->block_size = 0;
-
- /* Set the output parameter */
- *num_processed_entries_ptr += array_counter;
-
-}
-
-/**
- * sep_shared_area_virt_to_bus - map shared area to bus address
- * @sep: pointer to struct sep_device
- * @virt_address: virtual address to convert
- *
- * This functions returns the physical address inside shared area according
- * to the virtual address. It can be either on the external RAM device
- * (ioremapped), or on the system RAM
- * This implementation is for the external RAM
- */
-static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep,
- void *virt_address)
-{
- dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys v %p\n",
- current->pid, virt_address);
- dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys p %08lx\n",
- current->pid,
- (unsigned long)
- sep->shared_bus + (virt_address - sep->shared_addr));
-
- return sep->shared_bus + (size_t)(virt_address - sep->shared_addr);
-}
-
-/**
- * sep_shared_area_bus_to_virt - map shared area bus address to kernel
- * @sep: pointer to struct sep_device
- * @bus_address: bus address to convert
- *
- * This functions returns the virtual address inside shared area
- * according to the physical address. It can be either on the
- * external RAM device (ioremapped), or on the system RAM
- * This implementation is for the external RAM
- */
-static void *sep_shared_area_bus_to_virt(struct sep_device *sep,
- dma_addr_t bus_address)
-{
- dev_dbg(&sep->pdev->dev, "[PID%d] shared bus to virt b=%lx v=%lx\n",
- current->pid,
- (unsigned long)bus_address, (unsigned long)(sep->shared_addr +
- (size_t)(bus_address - sep->shared_bus)));
-
- return sep->shared_addr + (size_t)(bus_address - sep->shared_bus);
-}
-
-/**
- * sep_debug_print_lli_tables - dump LLI table
- * @sep: pointer to struct sep_device
- * @lli_table_ptr: pointer to sep_lli_entry
- * @num_table_entries: number of entries
- * @table_data_size: total data size
- *
- * Walk the the list of the print created tables and print all the data
- */
-static void sep_debug_print_lli_tables(struct sep_device *sep,
- struct sep_lli_entry *lli_table_ptr,
- unsigned long num_table_entries,
- unsigned long table_data_size)
-{
-#ifdef DEBUG
- unsigned long table_count = 1;
- unsigned long entries_count = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables start\n",
- current->pid);
- if (num_table_entries == 0) {
- dev_dbg(&sep->pdev->dev, "[PID%d] no table to print\n",
- current->pid);
- return;
- }
-
- while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli table %08lx, table_data_size is (hex) %lx\n",
- current->pid, table_count, table_data_size);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] num_table_entries is (hex) %lx\n",
- current->pid, num_table_entries);
-
- /* Print entries of the table (without info entry) */
- for (entries_count = 0; entries_count < num_table_entries;
- entries_count++, lli_table_ptr++) {
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] lli_table_ptr address is %08lx\n",
- current->pid,
- (unsigned long) lli_table_ptr);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] phys address is %08lx block size is (hex) %x\n",
- current->pid,
- (unsigned long)lli_table_ptr->bus_address,
- lli_table_ptr->block_size);
- }
-
- /* Point to the info entry */
- lli_table_ptr--;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] phys lli_table_ptr->block_size is (hex) %x\n",
- current->pid,
- lli_table_ptr->block_size);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] phys lli_table_ptr->physical_address is %08lx\n",
- current->pid,
- (unsigned long)lli_table_ptr->bus_address);
-
-
- table_data_size = lli_table_ptr->block_size & 0xffffff;
- num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] phys table_data_size is (hex) %lx num_table_entries is %lx bus_address is%lx\n",
- current->pid,
- table_data_size,
- num_table_entries,
- (unsigned long)lli_table_ptr->bus_address);
-
- if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff)
- lli_table_ptr = (struct sep_lli_entry *)
- sep_shared_bus_to_virt(sep,
- (unsigned long)lli_table_ptr->bus_address);
-
- table_count++;
- }
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n",
- current->pid);
-#endif
-}
-
-
-/**
- * sep_prepare_empty_lli_table - create a blank LLI table
- * @sep: pointer to struct sep_device
- * @lli_table_addr_ptr: pointer to lli table
- * @num_entries_ptr: pointer to number of entries
- * @table_data_size_ptr: point to table data size
- * @dmatables_region: Optional buffer for DMA tables
- * @dma_ctx: DMA context
- *
- * This function creates empty lli tables when there is no data
- */
-static void sep_prepare_empty_lli_table(struct sep_device *sep,
- dma_addr_t *lli_table_addr_ptr,
- u32 *num_entries_ptr,
- u32 *table_data_size_ptr,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx)
-{
- struct sep_lli_entry *lli_table_ptr;
-
- /* Find the area for new table */
- lli_table_ptr =
- (struct sep_lli_entry *)(sep->shared_addr +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
- if (dmatables_region && *dmatables_region)
- lli_table_ptr = *dmatables_region;
-
- lli_table_ptr->bus_address = 0;
- lli_table_ptr->block_size = 0;
-
- lli_table_ptr++;
- lli_table_ptr->bus_address = 0xFFFFFFFF;
- lli_table_ptr->block_size = 0;
-
- /* Set the output parameter value */
- *lli_table_addr_ptr = sep->shared_bus +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- dma_ctx->num_lli_tables_created *
- sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* Set the num of entries and table data size for empty table */
- *num_entries_ptr = 2;
- *table_data_size_ptr = 0;
-
- /* Update the number of created tables */
- dma_ctx->num_lli_tables_created++;
-}
-
-/**
- * sep_prepare_input_dma_table - prepare input DMA mappings
- * @sep: pointer to struct sep_device
- * @data_size:
- * @block_size:
- * @lli_table_ptr:
- * @num_entries_ptr:
- * @table_data_size_ptr:
- * @is_kva: set for kernel data (kernel crypt io call)
- *
- * This function prepares only input DMA table for synchronic symmetric
- * operations (HASH)
- * Note that all bus addresses that are passed to the SEP
- * are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_prepare_input_dma_table(struct sep_device *sep,
- unsigned long app_virt_addr,
- u32 data_size,
- u32 block_size,
- dma_addr_t *lli_table_ptr,
- u32 *num_entries_ptr,
- u32 *table_data_size_ptr,
- bool is_kva,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx
-)
-{
- int error = 0;
- /* Pointer to the info entry of the table - the last entry */
- struct sep_lli_entry *info_entry_ptr;
- /* Array of pointers to page */
- struct sep_lli_entry *lli_array_ptr;
- /* Points to the first entry to be processed in the lli_in_array */
- u32 current_entry = 0;
- /* Num entries in the virtual buffer */
- u32 sep_lli_entries = 0;
- /* Lli table pointer */
- struct sep_lli_entry *in_lli_table_ptr;
- /* The total data in one table */
- u32 table_data_size = 0;
- /* Flag for last table */
- u32 last_table_flag = 0;
- /* Number of entries in lli table */
- u32 num_entries_in_table = 0;
- /* Next table address */
- void *lli_table_alloc_addr = NULL;
- void *dma_lli_table_alloc_addr = NULL;
- void *dma_in_lli_table_ptr = NULL;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] prepare intput dma tbl data size: (hex) %x\n",
- current->pid, data_size);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] block_size is (hex) %x\n",
- current->pid, block_size);
-
- /* Initialize the pages pointers */
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = 0;
-
- /* Set the kernel address for first table to be allocated */
- lli_table_alloc_addr = (void *)(sep->shared_addr +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
- if (data_size == 0) {
- if (dmatables_region) {
- error = sep_allocate_dmatables_region(sep,
- dmatables_region,
- dma_ctx,
- 1);
- if (error)
- return error;
- }
- /* Special case - create meptu table - 2 entries, zero data */
- sep_prepare_empty_lli_table(sep, lli_table_ptr,
- num_entries_ptr, table_data_size_ptr,
- dmatables_region, dma_ctx);
- goto update_dcb_counter;
- }
-
- /* Check if the pages are in Kernel Virtual Address layout */
- if (is_kva)
- error = sep_lock_kernel_pages(sep, app_virt_addr,
- data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG,
- dma_ctx);
- else
- /*
- * Lock the pages of the user buffer
- * and translate them to pages
- */
- error = sep_lock_user_pages(sep, app_virt_addr,
- data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG,
- dma_ctx);
-
- if (error)
- goto end_function;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output sep_in_num_pages is (hex) %x\n",
- current->pid,
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages);
-
- current_entry = 0;
- info_entry_ptr = NULL;
-
- sep_lli_entries =
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages;
-
- dma_lli_table_alloc_addr = lli_table_alloc_addr;
- if (dmatables_region) {
- error = sep_allocate_dmatables_region(sep,
- dmatables_region,
- dma_ctx,
- sep_lli_entries);
- if (error)
- goto end_function_error;
- lli_table_alloc_addr = *dmatables_region;
- }
-
- /* Loop till all the entries in in array are processed */
- while (current_entry < sep_lli_entries) {
-
- /* Set the new input and output tables */
- in_lli_table_ptr =
- (struct sep_lli_entry *)lli_table_alloc_addr;
- dma_in_lli_table_ptr =
- (struct sep_lli_entry *)dma_lli_table_alloc_addr;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
- dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- if (dma_lli_table_alloc_addr >
- ((void *)sep->shared_addr +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
-
- error = -ENOMEM;
- goto end_function_error;
-
- }
-
- /* Update the number of created tables */
- dma_ctx->num_lli_tables_created++;
-
- /* Calculate the maximum size of data for input table */
- table_data_size = sep_calculate_lli_table_max_size(sep,
- &lli_array_ptr[current_entry],
- (sep_lli_entries - current_entry),
- &last_table_flag);
-
- /*
- * If this is not the last table -
- * then align it to the block size
- */
- if (!last_table_flag)
- table_data_size =
- (table_data_size / block_size) * block_size;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output table_data_size is (hex) %x\n",
- current->pid,
- table_data_size);
-
- /* Construct input lli table */
- sep_build_lli_table(sep, &lli_array_ptr[current_entry],
- in_lli_table_ptr,
- &current_entry, &num_entries_in_table, table_data_size);
-
- if (info_entry_ptr == NULL) {
-
- /* Set the output parameters to physical addresses */
- *lli_table_ptr = sep_shared_area_virt_to_bus(sep,
- dma_in_lli_table_ptr);
- *num_entries_ptr = num_entries_in_table;
- *table_data_size_ptr = table_data_size;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output lli_table_in_ptr is %08lx\n",
- current->pid,
- (unsigned long)*lli_table_ptr);
-
- } else {
- /* Update the info entry of the previous in table */
- info_entry_ptr->bus_address =
- sep_shared_area_virt_to_bus(sep,
- dma_in_lli_table_ptr);
- info_entry_ptr->block_size =
- ((num_entries_in_table) << 24) |
- (table_data_size);
- }
- /* Save the pointer to the info entry of the current tables */
- info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
- }
- /* Print input tables */
- if (!dmatables_region) {
- sep_debug_print_lli_tables(sep, (struct sep_lli_entry *)
- sep_shared_area_bus_to_virt(sep, *lli_table_ptr),
- *num_entries_ptr, *table_data_size_ptr);
- }
-
- /* The array of the pages */
- kfree(lli_array_ptr);
-
-update_dcb_counter:
- /* Update DCB counter */
- dma_ctx->nr_dcb_creat++;
- goto end_function;
-
-end_function_error:
- /* Free all the allocated resources */
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL;
- kfree(lli_array_ptr);
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
-
-end_function:
- return error;
-
-}
-
-/**
- * sep_construct_dma_tables_from_lli - prepare AES/DES mappings
- * @sep: pointer to struct sep_device
- * @lli_in_array:
- * @sep_in_lli_entries:
- * @lli_out_array:
- * @sep_out_lli_entries
- * @block_size
- * @lli_table_in_ptr
- * @lli_table_out_ptr
- * @in_num_entries_ptr
- * @out_num_entries_ptr
- * @table_data_size_ptr
- *
- * This function creates the input and output DMA tables for
- * symmetric operations (AES/DES) according to the block
- * size from LLI arays
- * Note that all bus addresses that are passed to the SEP
- * are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_construct_dma_tables_from_lli(
- struct sep_device *sep,
- struct sep_lli_entry *lli_in_array,
- u32 sep_in_lli_entries,
- struct sep_lli_entry *lli_out_array,
- u32 sep_out_lli_entries,
- u32 block_size,
- dma_addr_t *lli_table_in_ptr,
- dma_addr_t *lli_table_out_ptr,
- u32 *in_num_entries_ptr,
- u32 *out_num_entries_ptr,
- u32 *table_data_size_ptr,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx)
-{
- /* Points to the area where next lli table can be allocated */
- void *lli_table_alloc_addr = NULL;
- /*
- * Points to the area in shared region where next lli table
- * can be allocated
- */
- void *dma_lli_table_alloc_addr = NULL;
- /* Input lli table in dmatables_region or shared region */
- struct sep_lli_entry *in_lli_table_ptr = NULL;
- /* Input lli table location in the shared region */
- struct sep_lli_entry *dma_in_lli_table_ptr = NULL;
- /* Output lli table in dmatables_region or shared region */
- struct sep_lli_entry *out_lli_table_ptr = NULL;
- /* Output lli table location in the shared region */
- struct sep_lli_entry *dma_out_lli_table_ptr = NULL;
- /* Pointer to the info entry of the table - the last entry */
- struct sep_lli_entry *info_in_entry_ptr = NULL;
- /* Pointer to the info entry of the table - the last entry */
- struct sep_lli_entry *info_out_entry_ptr = NULL;
- /* Points to the first entry to be processed in the lli_in_array */
- u32 current_in_entry = 0;
- /* Points to the first entry to be processed in the lli_out_array */
- u32 current_out_entry = 0;
- /* Max size of the input table */
- u32 in_table_data_size = 0;
- /* Max size of the output table */
- u32 out_table_data_size = 0;
- /* Flag te signifies if this is the last tables build */
- u32 last_table_flag = 0;
- /* The data size that should be in table */
- u32 table_data_size = 0;
- /* Number of entries in the input table */
- u32 num_entries_in_table = 0;
- /* Number of entries in the output table */
- u32 num_entries_out_table = 0;
-
- if (!dma_ctx) {
- dev_warn(&sep->pdev->dev, "DMA context uninitialized\n");
- return -EINVAL;
- }
-
- /* Initiate to point after the message area */
- lli_table_alloc_addr = (void *)(sep->shared_addr +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- (dma_ctx->num_lli_tables_created *
- (sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP)));
- dma_lli_table_alloc_addr = lli_table_alloc_addr;
-
- if (dmatables_region) {
- /* 2 for both in+out table */
- if (sep_allocate_dmatables_region(sep,
- dmatables_region,
- dma_ctx,
- 2*sep_in_lli_entries))
- return -ENOMEM;
- lli_table_alloc_addr = *dmatables_region;
- }
-
- /* Loop till all the entries in in array are not processed */
- while (current_in_entry < sep_in_lli_entries) {
- /* Set the new input and output tables */
- in_lli_table_ptr =
- (struct sep_lli_entry *)lli_table_alloc_addr;
- dma_in_lli_table_ptr =
- (struct sep_lli_entry *)dma_lli_table_alloc_addr;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
- dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* Set the first output tables */
- out_lli_table_ptr =
- (struct sep_lli_entry *)lli_table_alloc_addr;
- dma_out_lli_table_ptr =
- (struct sep_lli_entry *)dma_lli_table_alloc_addr;
-
- /* Check if the DMA table area limit was overrun */
- if ((dma_lli_table_alloc_addr + sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) >
- ((void *)sep->shared_addr +
- SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
- SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
-
- dev_warn(&sep->pdev->dev, "dma table limit overrun\n");
- return -ENOMEM;
- }
-
- /* Update the number of the lli tables created */
- dma_ctx->num_lli_tables_created += 2;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
- dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
- SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* Calculate the maximum size of data for input table */
- in_table_data_size =
- sep_calculate_lli_table_max_size(sep,
- &lli_in_array[current_in_entry],
- (sep_in_lli_entries - current_in_entry),
- &last_table_flag);
-
- /* Calculate the maximum size of data for output table */
- out_table_data_size =
- sep_calculate_lli_table_max_size(sep,
- &lli_out_array[current_out_entry],
- (sep_out_lli_entries - current_out_entry),
- &last_table_flag);
-
- if (!last_table_flag) {
- in_table_data_size = (in_table_data_size /
- block_size) * block_size;
- out_table_data_size = (out_table_data_size /
- block_size) * block_size;
- }
-
- table_data_size = in_table_data_size;
- if (table_data_size > out_table_data_size)
- table_data_size = out_table_data_size;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] construct tables from lli in_table_data_size is (hex) %x\n",
- current->pid, in_table_data_size);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] construct tables from lli out_table_data_size is (hex) %x\n",
- current->pid, out_table_data_size);
-
- /* Construct input lli table */
- sep_build_lli_table(sep, &lli_in_array[current_in_entry],
- in_lli_table_ptr,
- &current_in_entry,
- &num_entries_in_table,
- table_data_size);
-
- /* Construct output lli table */
- sep_build_lli_table(sep, &lli_out_array[current_out_entry],
- out_lli_table_ptr,
- &current_out_entry,
- &num_entries_out_table,
- table_data_size);
-
- /* If info entry is null - this is the first table built */
- if (info_in_entry_ptr == NULL || info_out_entry_ptr == NULL) {
- /* Set the output parameters to physical addresses */
- *lli_table_in_ptr =
- sep_shared_area_virt_to_bus(sep, dma_in_lli_table_ptr);
-
- *in_num_entries_ptr = num_entries_in_table;
-
- *lli_table_out_ptr =
- sep_shared_area_virt_to_bus(sep,
- dma_out_lli_table_ptr);
-
- *out_num_entries_ptr = num_entries_out_table;
- *table_data_size_ptr = table_data_size;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output lli_table_in_ptr is %08lx\n",
- current->pid,
- (unsigned long)*lli_table_in_ptr);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output lli_table_out_ptr is %08lx\n",
- current->pid,
- (unsigned long)*lli_table_out_ptr);
- } else {
- /* Update the info entry of the previous in table */
- info_in_entry_ptr->bus_address =
- sep_shared_area_virt_to_bus(sep,
- dma_in_lli_table_ptr);
-
- info_in_entry_ptr->block_size =
- ((num_entries_in_table) << 24) |
- (table_data_size);
-
- /* Update the info entry of the previous in table */
- info_out_entry_ptr->bus_address =
- sep_shared_area_virt_to_bus(sep,
- dma_out_lli_table_ptr);
-
- info_out_entry_ptr->block_size =
- ((num_entries_out_table) << 24) |
- (table_data_size);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output lli_table_in_ptr:%08lx %08x\n",
- current->pid,
- (unsigned long)info_in_entry_ptr->bus_address,
- info_in_entry_ptr->block_size);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output lli_table_out_ptr: %08lx %08x\n",
- current->pid,
- (unsigned long)info_out_entry_ptr->bus_address,
- info_out_entry_ptr->block_size);
- }
-
- /* Save the pointer to the info entry of the current tables */
- info_in_entry_ptr = in_lli_table_ptr +
- num_entries_in_table - 1;
- info_out_entry_ptr = out_lli_table_ptr +
- num_entries_out_table - 1;
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output num_entries_out_table is %x\n",
- current->pid,
- (u32)num_entries_out_table);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output info_in_entry_ptr is %lx\n",
- current->pid,
- (unsigned long)info_in_entry_ptr);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] output info_out_entry_ptr is %lx\n",
- current->pid,
- (unsigned long)info_out_entry_ptr);
- }
-
- /* Print input tables */
- if (!dmatables_region) {
- sep_debug_print_lli_tables(
- sep,
- (struct sep_lli_entry *)
- sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr),
- *in_num_entries_ptr,
- *table_data_size_ptr);
- }
-
- /* Print output tables */
- if (!dmatables_region) {
- sep_debug_print_lli_tables(
- sep,
- (struct sep_lli_entry *)
- sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr),
- *out_num_entries_ptr,
- *table_data_size_ptr);
- }
-
- return 0;
-}
-
-/**
- * sep_prepare_input_output_dma_table - prepare DMA I/O table
- * @app_virt_in_addr:
- * @app_virt_out_addr:
- * @data_size:
- * @block_size:
- * @lli_table_in_ptr:
- * @lli_table_out_ptr:
- * @in_num_entries_ptr:
- * @out_num_entries_ptr:
- * @table_data_size_ptr:
- * @is_kva: set for kernel data; used only for kernel crypto module
- *
- * This function builds input and output DMA tables for synchronic
- * symmetric operations (AES, DES, HASH). It also checks that each table
- * is of the modular block size
- * Note that all bus addresses that are passed to the SEP
- * are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_prepare_input_output_dma_table(struct sep_device *sep,
- unsigned long app_virt_in_addr,
- unsigned long app_virt_out_addr,
- u32 data_size,
- u32 block_size,
- dma_addr_t *lli_table_in_ptr,
- dma_addr_t *lli_table_out_ptr,
- u32 *in_num_entries_ptr,
- u32 *out_num_entries_ptr,
- u32 *table_data_size_ptr,
- bool is_kva,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx)
-
-{
- int error = 0;
- /* Array of pointers of page */
- struct sep_lli_entry *lli_in_array;
- /* Array of pointers of page */
- struct sep_lli_entry *lli_out_array;
-
- if (!dma_ctx) {
- error = -EINVAL;
- goto end_function;
- }
-
- if (data_size == 0) {
- /* Prepare empty table for input and output */
- if (dmatables_region) {
- error = sep_allocate_dmatables_region(
- sep,
- dmatables_region,
- dma_ctx,
- 2);
- if (error)
- goto end_function;
- }
- sep_prepare_empty_lli_table(sep, lli_table_in_ptr,
- in_num_entries_ptr, table_data_size_ptr,
- dmatables_region, dma_ctx);
-
- sep_prepare_empty_lli_table(sep, lli_table_out_ptr,
- out_num_entries_ptr, table_data_size_ptr,
- dmatables_region, dma_ctx);
-
- goto update_dcb_counter;
- }
-
- /* Initialize the pages pointers */
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
-
- /* Lock the pages of the buffer and translate them to pages */
- if (is_kva) {
- dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel input pages\n",
- current->pid);
- error = sep_lock_kernel_pages(sep, app_virt_in_addr,
- data_size, &lli_in_array, SEP_DRIVER_IN_FLAG,
- dma_ctx);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] sep_lock_kernel_pages for input virtual buffer failed\n",
- current->pid);
-
- goto end_function;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel output pages\n",
- current->pid);
- error = sep_lock_kernel_pages(sep, app_virt_out_addr,
- data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG,
- dma_ctx);
-
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] sep_lock_kernel_pages for output virtual buffer failed\n",
- current->pid);
-
- goto end_function_free_lli_in;
- }
-
- }
-
- else {
- dev_dbg(&sep->pdev->dev, "[PID%d] Locking user input pages\n",
- current->pid);
- error = sep_lock_user_pages(sep, app_virt_in_addr,
- data_size, &lli_in_array, SEP_DRIVER_IN_FLAG,
- dma_ctx);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] sep_lock_user_pages for input virtual buffer failed\n",
- current->pid);
-
- goto end_function;
- }
-
- if (dma_ctx->secure_dma) {
- /* secure_dma requires use of non accessible memory */
- dev_dbg(&sep->pdev->dev, "[PID%d] in secure_dma\n",
- current->pid);
- error = sep_lli_table_secure_dma(sep,
- app_virt_out_addr, data_size, &lli_out_array,
- SEP_DRIVER_OUT_FLAG, dma_ctx);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] secure dma table setup for output virtual buffer failed\n",
- current->pid);
-
- goto end_function_free_lli_in;
- }
- } else {
- /* For normal, non-secure dma */
- dev_dbg(&sep->pdev->dev, "[PID%d] not in secure_dma\n",
- current->pid);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] Locking user output pages\n",
- current->pid);
-
- error = sep_lock_user_pages(sep, app_virt_out_addr,
- data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG,
- dma_ctx);
-
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] sep_lock_user_pages for output virtual buffer failed\n",
- current->pid);
-
- goto end_function_free_lli_in;
- }
- }
- }
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] After lock; prep input output dma table sep_in_num_pages is (hex) %x\n",
- current->pid,
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_out_num_pages is (hex) %x\n",
- current->pid,
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is (hex) %x\n",
- current->pid, SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
- /* Call the function that creates table from the lli arrays */
- dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n",
- current->pid);
- error = sep_construct_dma_tables_from_lli(
- sep, lli_in_array,
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
- in_num_pages,
- lli_out_array,
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
- out_num_pages,
- block_size, lli_table_in_ptr, lli_table_out_ptr,
- in_num_entries_ptr, out_num_entries_ptr,
- table_data_size_ptr, dmatables_region, dma_ctx);
-
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] sep_construct_dma_tables_from_lli failed\n",
- current->pid);
- goto end_function_with_error;
- }
-
- kfree(lli_out_array);
- kfree(lli_in_array);
-
-update_dcb_counter:
- /* Update DCB counter */
- dma_ctx->nr_dcb_creat++;
-
- goto end_function;
-
-end_function_with_error:
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL;
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
- kfree(lli_out_array);
-
-
-end_function_free_lli_in:
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL;
- kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array);
- dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
- kfree(lli_in_array);
-
-end_function:
-
- return error;
-
-}
-
-/**
- * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
- * @app_in_address: unsigned long; for data buffer in (user space)
- * @app_out_address: unsigned long; for data buffer out (user space)
- * @data_in_size: u32; for size of data
- * @block_size: u32; for block size
- * @tail_block_size: u32; for size of tail block
- * @isapplet: bool; to indicate external app
- * @is_kva: bool; kernel buffer; only used for kernel crypto module
- * @secure_dma; indicates whether this is secure_dma using IMR
- *
- * This function prepares the linked DMA tables and puts the
- * address for the linked list of tables inta a DCB (data control
- * block) the address of which is known by the SEP hardware
- * Note that all bus addresses that are passed to the SEP
- * are in 32 bit format; the SEP is a 32 bit device
- */
-int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
- unsigned long app_in_address,
- unsigned long app_out_address,
- u32 data_in_size,
- u32 block_size,
- u32 tail_block_size,
- bool isapplet,
- bool is_kva,
- bool secure_dma,
- struct sep_dcblock *dcb_region,
- void **dmatables_region,
- struct sep_dma_context **dma_ctx,
- struct scatterlist *src_sg,
- struct scatterlist *dst_sg)
-{
- int error = 0;
- /* Size of tail */
- u32 tail_size = 0;
- /* Address of the created DCB table */
- struct sep_dcblock *dcb_table_ptr = NULL;
- /* The physical address of the first input DMA table */
- dma_addr_t in_first_mlli_address = 0;
- /* Number of entries in the first input DMA table */
- u32 in_first_num_entries = 0;
- /* The physical address of the first output DMA table */
- dma_addr_t out_first_mlli_address = 0;
- /* Number of entries in the first output DMA table */
- u32 out_first_num_entries = 0;
- /* Data in the first input/output table */
- u32 first_data_size = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] app_in_address %lx\n",
- current->pid, app_in_address);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] app_out_address %lx\n",
- current->pid, app_out_address);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] data_in_size %x\n",
- current->pid, data_in_size);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] block_size %x\n",
- current->pid, block_size);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] tail_block_size %x\n",
- current->pid, tail_block_size);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] isapplet %x\n",
- current->pid, isapplet);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] is_kva %x\n",
- current->pid, is_kva);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] src_sg %p\n",
- current->pid, src_sg);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] dst_sg %p\n",
- current->pid, dst_sg);
-
- if (!dma_ctx) {
- dev_warn(&sep->pdev->dev, "[PID%d] no DMA context pointer\n",
- current->pid);
- error = -EINVAL;
- goto end_function;
- }
-
- if (*dma_ctx) {
- /* In case there are multiple DCBs for this transaction */
- dev_dbg(&sep->pdev->dev, "[PID%d] DMA context already set\n",
- current->pid);
- } else {
- *dma_ctx = kzalloc(sizeof(**dma_ctx), GFP_KERNEL);
- if (!(*dma_ctx)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] Not enough memory for DMA context\n",
- current->pid);
- error = -ENOMEM;
- goto end_function;
- }
- dev_dbg(&sep->pdev->dev,
- "[PID%d] Created DMA context addr at 0x%p\n",
- current->pid, *dma_ctx);
- }
-
- (*dma_ctx)->secure_dma = secure_dma;
-
- /* these are for kernel crypto only */
- (*dma_ctx)->src_sg = src_sg;
- (*dma_ctx)->dst_sg = dst_sg;
-
- if ((*dma_ctx)->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) {
- /* No more DCBs to allocate */
- dev_dbg(&sep->pdev->dev, "[PID%d] no more DCBs available\n",
- current->pid);
- error = -ENOSPC;
- goto end_function_error;
- }
-
- /* Allocate new DCB */
- if (dcb_region) {
- dcb_table_ptr = dcb_region;
- } else {
- dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr +
- SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES +
- ((*dma_ctx)->nr_dcb_creat *
- sizeof(struct sep_dcblock)));
- }
-
- /* Set the default values in the DCB */
- dcb_table_ptr->input_mlli_address = 0;
- dcb_table_ptr->input_mlli_num_entries = 0;
- dcb_table_ptr->input_mlli_data_size = 0;
- dcb_table_ptr->output_mlli_address = 0;
- dcb_table_ptr->output_mlli_num_entries = 0;
- dcb_table_ptr->output_mlli_data_size = 0;
- dcb_table_ptr->tail_data_size = 0;
- dcb_table_ptr->out_vr_tail_pt = 0;
-
- if (isapplet) {
-
- /* Check if there is enough data for DMA operation */
- if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) {
- if (is_kva) {
- error = -ENODEV;
- goto end_function_error;
- } else {
- if (copy_from_user(dcb_table_ptr->tail_data,
- (void __user *)app_in_address,
- data_in_size)) {
- error = -EFAULT;
- goto end_function_error;
- }
- }
-
- dcb_table_ptr->tail_data_size = data_in_size;
-
- /* Set the output user-space address for mem2mem op */
- if (app_out_address)
- dcb_table_ptr->out_vr_tail_pt =
- (aligned_u64)app_out_address;
-
- /*
- * Update both data length parameters in order to avoid
- * second data copy and allow building of empty mlli
- * tables
- */
- tail_size = 0x0;
- data_in_size = 0x0;
-
- } else {
- if (!app_out_address) {
- tail_size = data_in_size % block_size;
- if (!tail_size) {
- if (tail_block_size == block_size)
- tail_size = block_size;
- }
- } else {
- tail_size = 0;
- }
- }
- if (tail_size) {
- if (tail_size > sizeof(dcb_table_ptr->tail_data))
- return -EINVAL;
- if (is_kva) {
- error = -ENODEV;
- goto end_function_error;
- } else {
- /* We have tail data - copy it to DCB */
- if (copy_from_user(dcb_table_ptr->tail_data,
- (void __user *)(app_in_address +
- data_in_size - tail_size), tail_size)) {
- error = -EFAULT;
- goto end_function_error;
- }
- }
- if (app_out_address)
- /*
- * Calculate the output address
- * according to tail data size
- */
- dcb_table_ptr->out_vr_tail_pt =
- (aligned_u64)app_out_address +
- data_in_size - tail_size;
-
- /* Save the real tail data size */
- dcb_table_ptr->tail_data_size = tail_size;
- /*
- * Update the data size without the tail
- * data size AKA data for the dma
- */
- data_in_size = (data_in_size - tail_size);
- }
- }
- /* Check if we need to build only input table or input/output */
- if (app_out_address) {
- /* Prepare input/output tables */
- error = sep_prepare_input_output_dma_table(sep,
- app_in_address,
- app_out_address,
- data_in_size,
- block_size,
- &in_first_mlli_address,
- &out_first_mlli_address,
- &in_first_num_entries,
- &out_first_num_entries,
- &first_data_size,
- is_kva,
- dmatables_region,
- *dma_ctx);
- } else {
- /* Prepare input tables */
- error = sep_prepare_input_dma_table(sep,
- app_in_address,
- data_in_size,
- block_size,
- &in_first_mlli_address,
- &in_first_num_entries,
- &first_data_size,
- is_kva,
- dmatables_region,
- *dma_ctx);
- }
-
- if (error) {
- dev_warn(&sep->pdev->dev,
- "prepare DMA table call failed from prepare DCB call\n");
- goto end_function_error;
- }
-
- /* Set the DCB values */
- dcb_table_ptr->input_mlli_address = in_first_mlli_address;
- dcb_table_ptr->input_mlli_num_entries = in_first_num_entries;
- dcb_table_ptr->input_mlli_data_size = first_data_size;
- dcb_table_ptr->output_mlli_address = out_first_mlli_address;
- dcb_table_ptr->output_mlli_num_entries = out_first_num_entries;
- dcb_table_ptr->output_mlli_data_size = first_data_size;
-
- goto end_function;
-
-end_function_error:
- kfree(*dma_ctx);
- *dma_ctx = NULL;
-
-end_function:
- return error;
-
-}
-
-
-/**
- * sep_free_dma_tables_and_dcb - free DMA tables and DCBs
- * @sep: pointer to struct sep_device
- * @isapplet: indicates external application (used for kernel access)
- * @is_kva: indicates kernel addresses (only used for kernel crypto)
- *
- * This function frees the DMA tables and DCB
- */
-static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
- bool is_kva, struct sep_dma_context **dma_ctx)
-{
- struct sep_dcblock *dcb_table_ptr;
- unsigned long pt_hold;
- void *tail_pt;
-
- int i = 0;
- int error = 0;
- int error_temp = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n",
- current->pid);
- if (!dma_ctx || !*dma_ctx) /* nothing to be done here*/
- return 0;
-
- if (!(*dma_ctx)->secure_dma && isapplet) {
- dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n",
- current->pid);
-
- /* Tail stuff is only for non secure_dma */
- /* Set pointer to first DCB table */
- dcb_table_ptr = (struct sep_dcblock *)
- (sep->shared_addr +
- SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES);
-
- /**
- * Go over each DCB and see if
- * tail pointer must be updated
- */
- for (i = 0; i < (*dma_ctx)->nr_dcb_creat;
- i++, dcb_table_ptr++) {
- if (dcb_table_ptr->out_vr_tail_pt) {
- pt_hold = (unsigned long)dcb_table_ptr->
- out_vr_tail_pt;
- tail_pt = (void *)pt_hold;
- if (is_kva) {
- error = -ENODEV;
- break;
- } else {
- error_temp = copy_to_user(
- (void __user *)tail_pt,
- dcb_table_ptr->tail_data,
- dcb_table_ptr->tail_data_size);
- }
- if (error_temp) {
- /* Release the DMA resource */
- error = -EFAULT;
- break;
- }
- }
- }
- }
-
- /* Free the output pages, if any */
- sep_free_dma_table_data_handler(sep, dma_ctx);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb end\n",
- current->pid);
-
- return error;
-}
-
-/**
- * sep_prepare_dcb_handler - prepare a control block
- * @sep: pointer to struct sep_device
- * @arg: pointer to user parameters
- * @secure_dma: indicate whether we are using secure_dma on IMR
- *
- * This function will retrieve the RAR buffer physical addresses, type
- * & size corresponding to the RAR handles provided in the buffers vector.
- */
-static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg,
- bool secure_dma,
- struct sep_dma_context **dma_ctx)
-{
- int error;
- /* Command arguments */
- static struct build_dcb_struct command_args;
-
- /* Get the command arguments */
- if (copy_from_user(&command_args, (void __user *)arg,
- sizeof(struct build_dcb_struct))) {
- error = -EFAULT;
- goto end_function;
- }
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] prep dcb handler app_in_address is %08llx\n",
- current->pid, command_args.app_in_address);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] app_out_address is %08llx\n",
- current->pid, command_args.app_out_address);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] data_size is %x\n",
- current->pid, command_args.data_in_size);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] block_size is %x\n",
- current->pid, command_args.block_size);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] tail block_size is %x\n",
- current->pid, command_args.tail_block_size);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] is_applet is %x\n",
- current->pid, command_args.is_applet);
-
- if (!command_args.app_in_address) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] null app_in_address\n", current->pid);
- error = -EINVAL;
- goto end_function;
- }
-
- error = sep_prepare_input_output_dma_table_in_dcb(sep,
- (unsigned long)command_args.app_in_address,
- (unsigned long)command_args.app_out_address,
- command_args.data_in_size, command_args.block_size,
- command_args.tail_block_size,
- command_args.is_applet, false,
- secure_dma, NULL, NULL, dma_ctx, NULL, NULL);
-
-end_function:
- return error;
-
-}
-
-/**
- * sep_free_dcb_handler - free control block resources
- * @sep: pointer to struct sep_device
- *
- * This function frees the DCB resources and updates the needed
- * user-space buffers.
- */
-static int sep_free_dcb_handler(struct sep_device *sep,
- struct sep_dma_context **dma_ctx)
-{
- if (!dma_ctx || !(*dma_ctx)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] no dma context defined, nothing to free\n",
- current->pid);
- return -EINVAL;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n",
- current->pid,
- (*dma_ctx)->nr_dcb_creat);
-
- return sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx);
-}
-
-/**
- * sep_ioctl - ioctl handler for sep device
- * @filp: pointer to struct file
- * @cmd: command
- * @arg: pointer to argument structure
- *
- * Implement the ioctl methods available on the SEP device.
- */
-static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
- struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
- int error = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] ioctl cmd 0x%x\n",
- current->pid, cmd);
- dev_dbg(&sep->pdev->dev, "[PID%d] dma context addr 0x%p\n",
- current->pid, *dma_ctx);
-
- /* Make sure we own this device */
- error = sep_check_transaction_owner(sep);
- if (error) {
- dev_dbg(&sep->pdev->dev, "[PID%d] ioctl pid is not owner\n",
- current->pid);
- goto end_function;
- }
-
- /* Check that sep_mmap has been called before */
- if (0 == test_bit(SEP_LEGACY_MMAP_DONE_OFFSET,
- &call_status->status)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] mmap not called\n", current->pid);
- error = -EPROTO;
- goto end_function;
- }
-
- /* Check that the command is for SEP device */
- if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) {
- error = -ENOTTY;
- goto end_function;
- }
-
- switch (cmd) {
- case SEP_IOCSENDSEPCOMMAND:
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCSENDSEPCOMMAND start\n",
- current->pid);
- if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &call_status->status)) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] send msg already done\n",
- current->pid);
- error = -EPROTO;
- goto end_function;
- }
- /* Send command to SEP */
- error = sep_send_command_handler(sep);
- if (!error)
- set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &call_status->status);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCSENDSEPCOMMAND end\n",
- current->pid);
- break;
- case SEP_IOCENDTRANSACTION:
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCENDTRANSACTION start\n",
- current->pid);
- error = sep_end_transaction_handler(sep, dma_ctx, call_status,
- my_queue_elem);
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCENDTRANSACTION end\n",
- current->pid);
- break;
- case SEP_IOCPREPAREDCB:
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCPREPAREDCB start\n",
- current->pid);
- /* fall-through */
- case SEP_IOCPREPAREDCB_SECURE_DMA:
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCPREPAREDCB_SECURE_DMA start\n",
- current->pid);
- if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
- &call_status->status)) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] dcb prep needed before send msg\n",
- current->pid);
- error = -EPROTO;
- goto end_function;
- }
-
- if (!arg) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] dcb null arg\n", current->pid);
- error = -EINVAL;
- goto end_function;
- }
-
- if (cmd == SEP_IOCPREPAREDCB) {
- /* No secure dma */
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCPREPAREDCB (no secure_dma)\n",
- current->pid);
-
- error = sep_prepare_dcb_handler(sep, arg, false,
- dma_ctx);
- } else {
- /* Secure dma */
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOC_POC (with secure_dma)\n",
- current->pid);
-
- error = sep_prepare_dcb_handler(sep, arg, true,
- dma_ctx);
- }
- dev_dbg(&sep->pdev->dev, "[PID%d] dcb's end\n",
- current->pid);
- break;
- case SEP_IOCFREEDCB:
- dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB start\n",
- current->pid);
- case SEP_IOCFREEDCB_SECURE_DMA:
- dev_dbg(&sep->pdev->dev,
- "[PID%d] SEP_IOCFREEDCB_SECURE_DMA start\n",
- current->pid);
- error = sep_free_dcb_handler(sep, dma_ctx);
- dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB end\n",
- current->pid);
- break;
- default:
- error = -ENOTTY;
- dev_dbg(&sep->pdev->dev, "[PID%d] default end\n",
- current->pid);
- break;
- }
-
-end_function:
- dev_dbg(&sep->pdev->dev, "[PID%d] ioctl end\n", current->pid);
-
- return error;
-}
-
-/**
- * sep_inthandler - interrupt handler for sep device
- * @irq: interrupt
- * @dev_id: device id
- */
-static irqreturn_t sep_inthandler(int irq, void *dev_id)
-{
- unsigned long lock_irq_flag;
- u32 reg_val, reg_val2 = 0;
- struct sep_device *sep = dev_id;
- irqreturn_t int_error = IRQ_HANDLED;
-
- /* Are we in power save? */
-#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM)
- if (sep->pdev->dev.power.runtime_status != RPM_ACTIVE) {
- dev_dbg(&sep->pdev->dev, "interrupt during pwr save\n");
- return IRQ_NONE;
- }
-#endif
-
- if (test_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags) == 0) {
- dev_dbg(&sep->pdev->dev, "interrupt while nobody using sep\n");
- return IRQ_NONE;
- }
-
- /* Read the IRR register to check if this is SEP interrupt */
- reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
-
- dev_dbg(&sep->pdev->dev, "sep int: IRR REG val: %x\n", reg_val);
-
- if (reg_val & (0x1 << 13)) {
-
- /* Lock and update the counter of reply messages */
- spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
- sep->reply_ct++;
- spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
-
- dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n",
- sep->send_ct, sep->reply_ct);
-
- /* Is this a kernel client request */
- if (sep->in_kernel) {
- tasklet_schedule(&sep->finish_tasklet);
- goto finished_interrupt;
- }
-
- /* Is this printf or daemon request? */
- reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- dev_dbg(&sep->pdev->dev,
- "SEP Interrupt - GPR2 is %08x\n", reg_val2);
-
- clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags);
-
- if ((reg_val2 >> 30) & 0x1) {
- dev_dbg(&sep->pdev->dev, "int: printf request\n");
- } else if (reg_val2 >> 31) {
- dev_dbg(&sep->pdev->dev, "int: daemon request\n");
- } else {
- dev_dbg(&sep->pdev->dev, "int: SEP reply\n");
- wake_up(&sep->event_interrupt);
- }
- } else {
- dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n");
- int_error = IRQ_NONE;
- }
-
-finished_interrupt:
-
- if (int_error == IRQ_HANDLED)
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
-
- return int_error;
-}
-
-/**
- * sep_reconfig_shared_area - reconfigure shared area
- * @sep: pointer to struct sep_device
- *
- * Reconfig the shared area between HOST and SEP - needed in case
- * the DX_CC_Init function was called before OS loading.
- */
-static int sep_reconfig_shared_area(struct sep_device *sep)
-{
- int ret_val;
-
- /* use to limit waiting for SEP */
- unsigned long end_time;
-
- /* Send the new SHARED MESSAGE AREA to the SEP */
- dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n",
- (unsigned long long)sep->shared_bus);
-
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
-
- /* Poll for SEP response */
- ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
-
- end_time = jiffies + (WAIT_TIME * HZ);
-
- while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) &&
- (ret_val != sep->shared_bus))
- ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
-
- /* Check the return value (register) */
- if (ret_val != sep->shared_bus) {
- dev_warn(&sep->pdev->dev, "could not reconfig shared area\n");
- dev_warn(&sep->pdev->dev, "result was %x\n", ret_val);
- ret_val = -ENOMEM;
- } else
- ret_val = 0;
-
- dev_dbg(&sep->pdev->dev, "reconfig shared area end\n");
-
- return ret_val;
-}
-
-/**
- * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables
- * contexts into use
- * @sep: SEP device
- * @dcb_region: DCB region copy
- * @dmatables_region: MLLI/DMA tables copy
- * @dma_ctx: DMA context for current transaction
- */
-ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep,
- struct sep_dcblock **dcb_region,
- void **dmatables_region,
- struct sep_dma_context *dma_ctx)
-{
- void *dmaregion_free_start = NULL;
- void *dmaregion_free_end = NULL;
- void *dcbregion_free_start = NULL;
- void *dcbregion_free_end = NULL;
- ssize_t error = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] activating dcb/dma region\n",
- current->pid);
-
- if (1 > dma_ctx->nr_dcb_creat) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid number of dcbs to activate 0x%08X\n",
- current->pid, dma_ctx->nr_dcb_creat);
- error = -EINVAL;
- goto end_function;
- }
-
- dmaregion_free_start = sep->shared_addr
- + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES;
- dmaregion_free_end = dmaregion_free_start
- + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1;
-
- if (dmaregion_free_start
- + dma_ctx->dmatables_len > dmaregion_free_end) {
- error = -ENOMEM;
- goto end_function;
- }
- memcpy(dmaregion_free_start,
- *dmatables_region,
- dma_ctx->dmatables_len);
- /* Free MLLI table copy */
- kfree(*dmatables_region);
- *dmatables_region = NULL;
-
- /* Copy thread's DCB table copy to DCB table region */
- dcbregion_free_start = sep->shared_addr +
- SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES;
- dcbregion_free_end = dcbregion_free_start +
- (SEP_MAX_NUM_SYNC_DMA_OPS *
- sizeof(struct sep_dcblock)) - 1;
-
- if (dcbregion_free_start
- + (dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock))
- > dcbregion_free_end) {
- error = -ENOMEM;
- goto end_function;
- }
-
- memcpy(dcbregion_free_start,
- *dcb_region,
- dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock));
-
- /* Print the tables */
- dev_dbg(&sep->pdev->dev, "activate: input table\n");
- sep_debug_print_lli_tables(sep,
- (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep,
- (*dcb_region)->input_mlli_address),
- (*dcb_region)->input_mlli_num_entries,
- (*dcb_region)->input_mlli_data_size);
-
- dev_dbg(&sep->pdev->dev, "activate: output table\n");
- sep_debug_print_lli_tables(sep,
- (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep,
- (*dcb_region)->output_mlli_address),
- (*dcb_region)->output_mlli_num_entries,
- (*dcb_region)->output_mlli_data_size);
-
- dev_dbg(&sep->pdev->dev,
- "[PID%d] printing activated tables\n", current->pid);
-
-end_function:
- kfree(*dmatables_region);
- *dmatables_region = NULL;
-
- kfree(*dcb_region);
- *dcb_region = NULL;
-
- return error;
-}
-
-/**
- * sep_create_dcb_dmatables_context - Creates DCB & MLLI/DMA table context
- * @sep: SEP device
- * @dcb_region: DCB region buf to create for current transaction
- * @dmatables_region: MLLI/DMA tables buf to create for current transaction
- * @dma_ctx: DMA context buf to create for current transaction
- * @user_dcb_args: User arguments for DCB/MLLI creation
- * @num_dcbs: Number of DCBs to create
- * @secure_dma: Indicate use of IMR restricted memory secure dma
- */
-static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep,
- struct sep_dcblock **dcb_region,
- void **dmatables_region,
- struct sep_dma_context **dma_ctx,
- const struct build_dcb_struct __user *user_dcb_args,
- const u32 num_dcbs, bool secure_dma)
-{
- int error = 0;
- int i = 0;
- struct build_dcb_struct *dcb_args = NULL;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n",
- current->pid);
-
- if (!dcb_region || !dma_ctx || !dmatables_region || !user_dcb_args) {
- error = -EINVAL;
- goto end_function;
- }
-
- if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid number of dcbs 0x%08X\n",
- current->pid, num_dcbs);
- error = -EINVAL;
- goto end_function;
- }
-
- dcb_args = kcalloc(num_dcbs, sizeof(struct build_dcb_struct),
- GFP_KERNEL);
- if (!dcb_args) {
- error = -ENOMEM;
- goto end_function;
- }
-
- if (copy_from_user(dcb_args,
- user_dcb_args,
- num_dcbs * sizeof(struct build_dcb_struct))) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* Allocate thread-specific memory for DCB */
- *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock),
- GFP_KERNEL);
- if (!(*dcb_region)) {
- error = -ENOMEM;
- goto end_function;
- }
-
- /* Prepare DCB and MLLI table into the allocated regions */
- for (i = 0; i < num_dcbs; i++) {
- error = sep_prepare_input_output_dma_table_in_dcb(sep,
- (unsigned long)dcb_args[i].app_in_address,
- (unsigned long)dcb_args[i].app_out_address,
- dcb_args[i].data_in_size,
- dcb_args[i].block_size,
- dcb_args[i].tail_block_size,
- dcb_args[i].is_applet,
- false, secure_dma,
- *dcb_region, dmatables_region,
- dma_ctx,
- NULL,
- NULL);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] dma table creation failed\n",
- current->pid);
- goto end_function;
- }
-
- if (dcb_args[i].app_in_address != 0)
- (*dma_ctx)->input_data_len += dcb_args[i].data_in_size;
- }
-
-end_function:
- kfree(dcb_args);
- return error;
-
-}
-
-/**
- * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context
- * for kernel crypto
- * @sep: SEP device
- * @dcb_region: DCB region buf to create for current transaction
- * @dmatables_region: MLLI/DMA tables buf to create for current transaction
- * @dma_ctx: DMA context buf to create for current transaction
- * @user_dcb_args: User arguments for DCB/MLLI creation
- * @num_dcbs: Number of DCBs to create
- * This does that same thing as sep_create_dcb_dmatables_context
- * except that it is used only for the kernel crypto operation. It is
- * separate because there is no user data involved; the dcb data structure
- * is specific for kernel crypto (build_dcb_struct_kernel)
- */
-int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep,
- struct sep_dcblock **dcb_region,
- void **dmatables_region,
- struct sep_dma_context **dma_ctx,
- const struct build_dcb_struct_kernel *dcb_data,
- const u32 num_dcbs)
-{
- int error = 0;
- int i = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n",
- current->pid);
-
- if (!dcb_region || !dma_ctx || !dmatables_region || !dcb_data) {
- error = -EINVAL;
- goto end_function;
- }
-
- if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid number of dcbs 0x%08X\n",
- current->pid, num_dcbs);
- error = -EINVAL;
- goto end_function;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] num_dcbs is %d\n",
- current->pid, num_dcbs);
-
- /* Allocate thread-specific memory for DCB */
- *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock),
- GFP_KERNEL);
- if (!(*dcb_region)) {
- error = -ENOMEM;
- goto end_function;
- }
-
- /* Prepare DCB and MLLI table into the allocated regions */
- for (i = 0; i < num_dcbs; i++) {
- error = sep_prepare_input_output_dma_table_in_dcb(sep,
- (unsigned long)dcb_data->app_in_address,
- (unsigned long)dcb_data->app_out_address,
- dcb_data->data_in_size,
- dcb_data->block_size,
- dcb_data->tail_block_size,
- dcb_data->is_applet,
- true,
- false,
- *dcb_region, dmatables_region,
- dma_ctx,
- dcb_data->src_sg,
- dcb_data->dst_sg);
- if (error) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] dma table creation failed\n",
- current->pid);
- goto end_function;
- }
- }
-
-end_function:
- return error;
-
-}
-
-/**
- * sep_activate_msgarea_context - Takes the message area context into use
- * @sep: SEP device
- * @msg_region: Message area context buf
- * @msg_len: Message area context buffer size
- */
-static ssize_t sep_activate_msgarea_context(struct sep_device *sep,
- void **msg_region,
- const size_t msg_len)
-{
- dev_dbg(&sep->pdev->dev, "[PID%d] activating msg region\n",
- current->pid);
-
- if (!msg_region || !(*msg_region) ||
- SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid act msgarea len 0x%08zX\n",
- current->pid, msg_len);
- return -EINVAL;
- }
-
- memcpy(sep->shared_addr, *msg_region, msg_len);
-
- return 0;
-}
-
-/**
- * sep_create_msgarea_context - Creates message area context
- * @sep: SEP device
- * @msg_region: Msg area region buf to create for current transaction
- * @msg_user: Content for msg area region from user
- * @msg_len: Message area size
- */
-static ssize_t sep_create_msgarea_context(struct sep_device *sep,
- void **msg_region,
- const void __user *msg_user,
- const size_t msg_len)
-{
- int error = 0;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] creating msg region\n",
- current->pid);
-
- if (!msg_region ||
- !msg_user ||
- SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len ||
- SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid creat msgarea len 0x%08zX\n",
- current->pid, msg_len);
- error = -EINVAL;
- goto end_function;
- }
-
- /* Allocate thread-specific memory for message buffer */
- *msg_region = kzalloc(msg_len, GFP_KERNEL);
- if (!(*msg_region)) {
- error = -ENOMEM;
- goto end_function;
- }
-
- /* Copy input data to write() to allocated message buffer */
- if (copy_from_user(*msg_region, msg_user, msg_len)) {
- error = -EFAULT;
- goto end_function;
- }
-
-end_function:
- if (error && msg_region) {
- kfree(*msg_region);
- *msg_region = NULL;
- }
-
- return error;
-}
-
-
-/**
- * sep_read - Returns results of an operation for fastcall interface
- * @filp: File pointer
- * @buf_user: User buffer for storing results
- * @count_user: User buffer size
- * @offset: File offset, not supported
- *
- * The implementation does not support reading in chunks, all data must be
- * consumed during a single read system call.
- */
-static ssize_t sep_read(struct file *filp,
- char __user *buf_user, size_t count_user,
- loff_t *offset)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
- struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
- ssize_t error = 0, error_tmp = 0;
-
- /* Am I the process that owns the transaction? */
- error = sep_check_transaction_owner(sep);
- if (error) {
- dev_dbg(&sep->pdev->dev, "[PID%d] read pid is not owner\n",
- current->pid);
- goto end_function;
- }
-
- /* Checks that user has called necessary apis */
- if (0 == test_bit(SEP_FASTCALL_WRITE_DONE_OFFSET,
- &call_status->status)) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] fastcall write not called\n",
- current->pid);
- error = -EPROTO;
- goto end_function_error;
- }
-
- if (!buf_user) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] null user buffer\n",
- current->pid);
- error = -EINVAL;
- goto end_function_error;
- }
-
-
- /* Wait for SEP to finish */
- wait_event(sep->event_interrupt,
- test_bit(SEP_WORKING_LOCK_BIT,
- &sep->in_use_flags) == 0);
-
- sep_dump_message(sep);
-
- dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08zX\n",
- current->pid, count_user);
-
- /* In case user has allocated bigger buffer */
- if (count_user > SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
- count_user = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES;
-
- if (copy_to_user(buf_user, sep->shared_addr, count_user)) {
- error = -EFAULT;
- goto end_function_error;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] read succeeded\n", current->pid);
- error = count_user;
-
-end_function_error:
- /* Copy possible tail data to user and free DCB and MLLIs */
- error_tmp = sep_free_dcb_handler(sep, dma_ctx);
- if (error_tmp)
- dev_warn(&sep->pdev->dev, "[PID%d] dcb free failed\n",
- current->pid);
-
- /* End the transaction, wakeup pending ones */
- error_tmp = sep_end_transaction_handler(sep, dma_ctx, call_status,
- my_queue_elem);
- if (error_tmp)
- dev_warn(&sep->pdev->dev,
- "[PID%d] ending transaction failed\n",
- current->pid);
-
-end_function:
- return error;
-}
-
-/**
- * sep_fastcall_args_get - Gets fastcall params from user
- * sep: SEP device
- * @args: Parameters buffer
- * @buf_user: User buffer for operation parameters
- * @count_user: User buffer size
- */
-static inline ssize_t sep_fastcall_args_get(struct sep_device *sep,
- struct sep_fastcall_hdr *args,
- const char __user *buf_user,
- const size_t count_user)
-{
- ssize_t error = 0;
- size_t actual_count = 0;
-
- if (!buf_user) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] null user buffer\n",
- current->pid);
- error = -EINVAL;
- goto end_function;
- }
-
- if (count_user < sizeof(struct sep_fastcall_hdr)) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] too small message size 0x%08zX\n",
- current->pid, count_user);
- error = -EINVAL;
- goto end_function;
- }
-
-
- if (copy_from_user(args, buf_user, sizeof(struct sep_fastcall_hdr))) {
- error = -EFAULT;
- goto end_function;
- }
-
- if (SEP_FC_MAGIC != args->magic) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid fastcall magic 0x%08X\n",
- current->pid, args->magic);
- error = -EINVAL;
- goto end_function;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr num of DCBs 0x%08X\n",
- current->pid, args->num_dcbs);
- dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr msg len 0x%08X\n",
- current->pid, args->msg_len);
-
- if (SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < args->msg_len ||
- SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > args->msg_len) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] invalid message length\n",
- current->pid);
- error = -EINVAL;
- goto end_function;
- }
-
- actual_count = sizeof(struct sep_fastcall_hdr)
- + args->msg_len
- + (args->num_dcbs * sizeof(struct build_dcb_struct));
-
- if (actual_count != count_user) {
- dev_warn(&sep->pdev->dev,
- "[PID%d] inconsistent message sizes 0x%08zX vs 0x%08zX\n",
- current->pid, actual_count, count_user);
- error = -EMSGSIZE;
- goto end_function;
- }
-
-end_function:
- return error;
-}
-
-/**
- * sep_write - Starts an operation for fastcall interface
- * @filp: File pointer
- * @buf_user: User buffer for operation parameters
- * @count_user: User buffer size
- * @offset: File offset, not supported
- *
- * The implementation does not support writing in chunks,
- * all data must be given during a single write system call.
- */
-static ssize_t sep_write(struct file *filp,
- const char __user *buf_user, size_t count_user,
- loff_t *offset)
-{
- struct sep_private_data * const private_data = filp->private_data;
- struct sep_call_status *call_status = &private_data->call_status;
- struct sep_device *sep = private_data->device;
- struct sep_dma_context *dma_ctx = NULL;
- struct sep_fastcall_hdr call_hdr = {0};
- void *msg_region = NULL;
- void *dmatables_region = NULL;
- struct sep_dcblock *dcb_region = NULL;
- ssize_t error = 0;
- struct sep_queue_info *my_queue_elem = NULL;
- bool my_secure_dma; /* are we using secure_dma (IMR)? */
-
- dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n",
- current->pid, sep);
- dev_dbg(&sep->pdev->dev, "[PID%d] private_data is 0x%p\n",
- current->pid, private_data);
-
- error = sep_fastcall_args_get(sep, &call_hdr, buf_user, count_user);
- if (error)
- goto end_function;
-
- buf_user += sizeof(struct sep_fastcall_hdr);
-
- if (call_hdr.secure_dma == 0)
- my_secure_dma = false;
- else
- my_secure_dma = true;
-
- /*
- * Controlling driver memory usage by limiting amount of
- * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number
- * of threads can progress further at a time
- */
- dev_dbg(&sep->pdev->dev,
- "[PID%d] waiting for double buffering region access\n",
- current->pid);
- error = down_interruptible(&sep->sep_doublebuf);
- dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region start\n",
- current->pid);
- if (error) {
- /* Signal received */
- goto end_function_error;
- }
-
-
- /*
- * Prepare contents of the shared area regions for
- * the operation into temporary buffers
- */
- if (0 < call_hdr.num_dcbs) {
- error = sep_create_dcb_dmatables_context(sep,
- &dcb_region,
- &dmatables_region,
- &dma_ctx,
- (const struct build_dcb_struct __user *)
- buf_user,
- call_hdr.num_dcbs, my_secure_dma);
- if (error)
- goto end_function_error_doublebuf;
-
- buf_user += call_hdr.num_dcbs * sizeof(struct build_dcb_struct);
- }
-
- error = sep_create_msgarea_context(sep,
- &msg_region,
- buf_user,
- call_hdr.msg_len);
- if (error)
- goto end_function_error_doublebuf;
-
- dev_dbg(&sep->pdev->dev, "[PID%d] updating queue status\n",
- current->pid);
- my_queue_elem = sep_queue_status_add(sep,
- ((struct sep_msgarea_hdr *)msg_region)->opcode,
- (dma_ctx) ? dma_ctx->input_data_len : 0,
- current->pid,
- current->comm, sizeof(current->comm));
-
- if (!my_queue_elem) {
- dev_dbg(&sep->pdev->dev,
- "[PID%d] updating queue status error\n", current->pid);
- error = -ENOMEM;
- goto end_function_error_doublebuf;
- }
-
- /* Wait until current process gets the transaction */
- error = sep_wait_transaction(sep);
-
- if (error) {
- /* Interrupted by signal, don't clear transaction */
- dev_dbg(&sep->pdev->dev, "[PID%d] interrupted by signal\n",
- current->pid);
- sep_queue_status_remove(sep, &my_queue_elem);
- goto end_function_error_doublebuf;
- }
-
- dev_dbg(&sep->pdev->dev, "[PID%d] saving queue element\n",
- current->pid);
- private_data->my_queue_elem = my_queue_elem;
-
- /* Activate shared area regions for the transaction */
- error = sep_activate_msgarea_context(sep, &msg_region,
- call_hdr.msg_len);
- if (error)
- goto end_function_error_clear_transact;
-
- sep_dump_message(sep);
-
- if (0 < call_hdr.num_dcbs) {
- error = sep_activate_dcb_dmatables_context(sep,
- &dcb_region,
- &dmatables_region,
- dma_ctx);
- if (error)
- goto end_function_error_clear_transact;
- }
-
- /* Send command to SEP */
- error = sep_send_command_handler(sep);
- if (error)
- goto end_function_error_clear_transact;
-
- /* Store DMA context for the transaction */
- private_data->dma_ctx = dma_ctx;
- /* Update call status */
- set_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, &call_status->status);
- error = count_user;
-
- up(&sep->sep_doublebuf);
- dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n",
- current->pid);
-
- goto end_function;
-
-end_function_error_clear_transact:
- sep_end_transaction_handler(sep, &dma_ctx, call_status,
- &private_data->my_queue_elem);
-
-end_function_error_doublebuf:
- up(&sep->sep_doublebuf);
- dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n",
- current->pid);
-
-end_function_error:
- if (dma_ctx)
- sep_free_dma_table_data_handler(sep, &dma_ctx);
-
-end_function:
- kfree(dcb_region);
- kfree(dmatables_region);
- kfree(msg_region);
-
- return error;
-}
-/**
- * sep_seek - Handler for seek system call
- * @filp: File pointer
- * @offset: File offset
- * @origin: Options for offset
- *
- * Fastcall interface does not support seeking, all reads
- * and writes are from/to offset zero
- */
-static loff_t sep_seek(struct file *filp, loff_t offset, int origin)
-{
- return -ENOSYS;
-}
-
-
-
-/**
- * sep_file_operations - file operation on sep device
- * @sep_ioctl: ioctl handler from user space call
- * @sep_poll: poll handler
- * @sep_open: handles sep device open request
- * @sep_release:handles sep device release request
- * @sep_mmap: handles memory mapping requests
- * @sep_read: handles read request on sep device
- * @sep_write: handles write request on sep device
- * @sep_seek: handles seek request on sep device
- */
-static const struct file_operations sep_file_operations = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = sep_ioctl,
- .poll = sep_poll,
- .open = sep_open,
- .release = sep_release,
- .mmap = sep_mmap,
- .read = sep_read,
- .write = sep_write,
- .llseek = sep_seek,
-};
-
-/**
- * sep_sysfs_read - read sysfs entry per gives arguments
- * @filp: file pointer
- * @kobj: kobject pointer
- * @attr: binary file attributes
- * @buf: read to this buffer
- * @pos: offset to read
- * @count: amount of data to read
- *
- * This function is to read sysfs entries for sep driver per given arguments.
- */
-static ssize_t
-sep_sysfs_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t pos, size_t count)
-{
- unsigned long lck_flags;
- size_t nleft = count;
- struct sep_device *sep = sep_dev;
- struct sep_queue_info *queue_elem = NULL;
- u32 queue_num = 0;
- u32 i = 1;
-
- spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
-
- queue_num = sep->sep_queue_num;
- if (queue_num > SEP_DOUBLEBUF_USERS_LIMIT)
- queue_num = SEP_DOUBLEBUF_USERS_LIMIT;
-
-
- if (count < sizeof(queue_num)
- + (queue_num * sizeof(struct sep_queue_data))) {
- spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
- return -EINVAL;
- }
-
- memcpy(buf, &queue_num, sizeof(queue_num));
- buf += sizeof(queue_num);
- nleft -= sizeof(queue_num);
-
- list_for_each_entry(queue_elem, &sep->sep_queue_status, list) {
- if (i++ > queue_num)
- break;
-
- memcpy(buf, &queue_elem->data, sizeof(queue_elem->data));
- nleft -= sizeof(queue_elem->data);
- buf += sizeof(queue_elem->data);
- }
- spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
-
- return count - nleft;
-}
-
-/**
- * bin_attributes - defines attributes for queue_status
- * @attr: attributes (name & permissions)
- * @read: function pointer to read this file
- * @size: maxinum size of binary attribute
- */
-static const struct bin_attribute queue_status = {
- .attr = {.name = "queue_status", .mode = 0444},
- .read = sep_sysfs_read,
- .size = sizeof(u32)
- + (SEP_DOUBLEBUF_USERS_LIMIT * sizeof(struct sep_queue_data)),
-};
-
-/**
- * sep_register_driver_with_fs - register misc devices
- * @sep: pointer to struct sep_device
- *
- * This function registers the driver with the file system
- */
-static int sep_register_driver_with_fs(struct sep_device *sep)
-{
- int ret_val;
-
- sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR;
- sep->miscdev_sep.name = SEP_DEV_NAME;
- sep->miscdev_sep.fops = &sep_file_operations;
-
- ret_val = misc_register(&sep->miscdev_sep);
- if (ret_val) {
- dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n",
- ret_val);
- return ret_val;
- }
-
- ret_val = device_create_bin_file(sep->miscdev_sep.this_device,
- &queue_status);
- if (ret_val) {
- dev_warn(&sep->pdev->dev, "sysfs attribute1 fails for SEP %x\n",
- ret_val);
- misc_deregister(&sep->miscdev_sep);
- return ret_val;
- }
-
- return ret_val;
-}
-
-
-/**
- *sep_probe - probe a matching PCI device
- *@pdev: pci_device
- *@ent: pci_device_id
- *
- *Attempt to set up and configure a SEP device that has been
- *discovered by the PCI layer. Allocates all required resources.
- */
-static int sep_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int error = 0;
- struct sep_device *sep = NULL;
-
- if (sep_dev != NULL) {
- dev_dbg(&pdev->dev, "only one SEP supported.\n");
- return -EBUSY;
- }
-
- /* Enable the device */
- error = pci_enable_device(pdev);
- if (error) {
- dev_warn(&pdev->dev, "error enabling pci device\n");
- goto end_function;
- }
-
- /* Allocate the sep_device structure for this device */
- sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC);
- if (sep_dev == NULL) {
- error = -ENOMEM;
- goto end_function_disable_device;
- }
-
- /*
- * We're going to use another variable for actually
- * working with the device; this way, if we have
- * multiple devices in the future, it would be easier
- * to make appropriate changes
- */
- sep = sep_dev;
-
- sep->pdev = pci_dev_get(pdev);
-
- init_waitqueue_head(&sep->event_transactions);
- init_waitqueue_head(&sep->event_interrupt);
- spin_lock_init(&sep->snd_rply_lck);
- spin_lock_init(&sep->sep_queue_lock);
- sema_init(&sep->sep_doublebuf, SEP_DOUBLEBUF_USERS_LIMIT);
-
- INIT_LIST_HEAD(&sep->sep_queue_status);
-
- dev_dbg(&sep->pdev->dev,
- "sep probe: PCI obtained, device being prepared\n");
-
- /* Set up our register area */
- sep->reg_physical_addr = pci_resource_start(sep->pdev, 0);
- if (!sep->reg_physical_addr) {
- dev_warn(&sep->pdev->dev, "Error getting register start\n");
- error = -ENODEV;
- goto end_function_free_sep_dev;
- }
-
- sep->reg_physical_end = pci_resource_end(sep->pdev, 0);
- if (!sep->reg_physical_end) {
- dev_warn(&sep->pdev->dev, "Error getting register end\n");
- error = -ENODEV;
- goto end_function_free_sep_dev;
- }
-
- sep->reg_addr = ioremap_nocache(sep->reg_physical_addr,
- (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1));
- if (!sep->reg_addr) {
- dev_warn(&sep->pdev->dev, "Error getting register virtual\n");
- error = -ENODEV;
- goto end_function_free_sep_dev;
- }
-
- dev_dbg(&sep->pdev->dev,
- "Register area start %llx end %llx virtual %p\n",
- (unsigned long long)sep->reg_physical_addr,
- (unsigned long long)sep->reg_physical_end,
- sep->reg_addr);
-
- /* Allocate the shared area */
- sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
- SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES +
- SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES +
- SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES +
- SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
-
- if (sep_map_and_alloc_shared_area(sep)) {
- error = -ENOMEM;
- /* Allocation failed */
- goto end_function_error;
- }
-
- /* Clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
- /* Set the IMR register - open only GPR 2 */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
- /* Read send/receive counters from SEP */
- sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- sep->reply_ct &= 0x3FFFFFFF;
- sep->send_ct = sep->reply_ct;
-
- /* Get the interrupt line */
- error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED,
- "sep_driver", sep);
-
- if (error)
- goto end_function_deallocate_sep_shared_area;
-
- /* The new chip requires a shared area reconfigure */
- error = sep_reconfig_shared_area(sep);
- if (error)
- goto end_function_free_irq;
-
- sep->in_use = 1;
-
- /* Finally magic up the device nodes */
- /* Register driver with the fs */
- error = sep_register_driver_with_fs(sep);
-
- if (error) {
- dev_err(&sep->pdev->dev, "error registering dev file\n");
- goto end_function_free_irq;
- }
-
- sep->in_use = 0; /* through touching the device */
-#ifdef SEP_ENABLE_RUNTIME_PM
- pm_runtime_put_noidle(&sep->pdev->dev);
- pm_runtime_allow(&sep->pdev->dev);
- pm_runtime_set_autosuspend_delay(&sep->pdev->dev,
- SUSPEND_DELAY);
- pm_runtime_use_autosuspend(&sep->pdev->dev);
- pm_runtime_mark_last_busy(&sep->pdev->dev);
- sep->power_save_setup = 1;
-#endif
- /* register kernel crypto driver */
-#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
- error = sep_crypto_setup();
- if (error) {
- dev_err(&sep->pdev->dev, "crypto setup failed\n");
- goto end_function_free_irq;
- }
-#endif
- goto end_function;
-
-end_function_free_irq:
- free_irq(pdev->irq, sep);
-
-end_function_deallocate_sep_shared_area:
- /* De-allocate shared area */
- sep_unmap_and_free_shared_area(sep);
-
-end_function_error:
- iounmap(sep->reg_addr);
-
-end_function_free_sep_dev:
- pci_dev_put(sep_dev->pdev);
- kfree(sep_dev);
- sep_dev = NULL;
-
-end_function_disable_device:
- pci_disable_device(pdev);
-
-end_function:
- return error;
-}
-
-/**
- * sep_remove - handles removing device from pci subsystem
- * @pdev: pointer to pci device
- *
- * This function will handle removing our sep device from pci subsystem on exit
- * or unloading this module. It should free up all used resources, and unmap if
- * any memory regions mapped.
- */
-static void sep_remove(struct pci_dev *pdev)
-{
- struct sep_device *sep = sep_dev;
-
- /* Unregister from fs */
- misc_deregister(&sep->miscdev_sep);
-
- /* Unregister from kernel crypto */
-#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
- sep_crypto_takedown();
-#endif
- /* Free the irq */
- free_irq(sep->pdev->irq, sep);
-
- /* Free the shared area */
- sep_unmap_and_free_shared_area(sep_dev);
- iounmap(sep_dev->reg_addr);
-
-#ifdef SEP_ENABLE_RUNTIME_PM
- if (sep->in_use) {
- sep->in_use = 0;
- pm_runtime_forbid(&sep->pdev->dev);
- pm_runtime_get_noresume(&sep->pdev->dev);
- }
-#endif
- pci_dev_put(sep_dev->pdev);
- kfree(sep_dev);
- sep_dev = NULL;
-}
-
-/* Initialize struct pci_device_id for our driver */
-static const struct pci_device_id sep_pci_id_tbl[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0826)},
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08e9)},
- {0}
-};
-
-/* Export our pci_device_id structure to user space */
-MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
-
-#ifdef SEP_ENABLE_RUNTIME_PM
-
-/**
- * sep_pm_resume - rsume routine while waking up from S3 state
- * @dev: pointer to sep device
- *
- * This function is to be used to wake up sep driver while system awakes from S3
- * state i.e. suspend to ram. The RAM in intact.
- * Notes - revisit with more understanding of pm, ICR/IMR & counters.
- */
-static int sep_pci_resume(struct device *dev)
-{
- struct sep_device *sep = sep_dev;
-
- dev_dbg(&sep->pdev->dev, "pci resume called\n");
-
- if (sep->power_state == SEP_DRIVER_POWERON)
- return 0;
-
- /* Clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
- /* Set the IMR register - open only GPR 2 */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
- /* Read send/receive counters from SEP */
- sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- sep->reply_ct &= 0x3FFFFFFF;
- sep->send_ct = sep->reply_ct;
-
- sep->power_state = SEP_DRIVER_POWERON;
-
- return 0;
-}
-
-/**
- * sep_pm_suspend - suspend routine while going to S3 state
- * @dev: pointer to sep device
- *
- * This function is to be used to suspend sep driver while system goes to S3
- * state i.e. suspend to ram. The RAM in intact and ON during this suspend.
- * Notes - revisit with more understanding of pm, ICR/IMR
- */
-static int sep_pci_suspend(struct device *dev)
-{
- struct sep_device *sep = sep_dev;
-
- dev_dbg(&sep->pdev->dev, "pci suspend called\n");
- if (sep->in_use == 1)
- return -EAGAIN;
-
- sep->power_state = SEP_DRIVER_POWEROFF;
-
- /* Clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
- /* Set the IMR to block all */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0xFFFFFFFF);
-
- return 0;
-}
-
-/**
- * sep_pm_runtime_resume - runtime resume routine
- * @dev: pointer to sep device
- *
- * Notes - revisit with more understanding of pm, ICR/IMR & counters
- */
-static int sep_pm_runtime_resume(struct device *dev)
-{
-
- u32 retval2;
- u32 delay_count;
- struct sep_device *sep = sep_dev;
-
- dev_dbg(&sep->pdev->dev, "pm runtime resume called\n");
-
- /**
- * Wait until the SCU boot is ready
- * This is done by iterating SCU_DELAY_ITERATION (10
- * microseconds each) up to SCU_DELAY_MAX (50) times.
- * This bit can be set in a random time that is less
- * than 500 microseconds after each power resume
- */
- retval2 = 0;
- delay_count = 0;
- while ((!retval2) && (delay_count < SCU_DELAY_MAX)) {
- retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- retval2 &= 0x00000008;
- if (!retval2) {
- udelay(SCU_DELAY_ITERATION);
- delay_count += 1;
- }
- }
-
- if (!retval2) {
- dev_warn(&sep->pdev->dev, "scu boot bit not set at resume\n");
- return -EINVAL;
- }
-
- /* Clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
- /* Set the IMR register - open only GPR 2 */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
- /* Read send/receive counters from SEP */
- sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- sep->reply_ct &= 0x3FFFFFFF;
- sep->send_ct = sep->reply_ct;
-
- return 0;
-}
-
-/**
- * sep_pm_runtime_suspend - runtime suspend routine
- * @dev: pointer to sep device
- *
- * Notes - revisit with more understanding of pm
- */
-static int sep_pm_runtime_suspend(struct device *dev)
-{
- struct sep_device *sep = sep_dev;
-
- dev_dbg(&sep->pdev->dev, "pm runtime suspend called\n");
-
- /* Clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
- return 0;
-}
-
-/**
- * sep_pm - power management for sep driver
- * @sep_pm_runtime_resume: resume- no communication with cpu & main memory
- * @sep_pm_runtime_suspend: suspend- no communication with cpu & main memory
- * @sep_pci_suspend: suspend - main memory is still ON
- * @sep_pci_resume: resume - main memory is still ON
- */
-static const struct dev_pm_ops sep_pm = {
- .runtime_resume = sep_pm_runtime_resume,
- .runtime_suspend = sep_pm_runtime_suspend,
- .resume = sep_pci_resume,
- .suspend = sep_pci_suspend,
-};
-#endif /* SEP_ENABLE_RUNTIME_PM */
-
-/**
- * sep_pci_driver - registers this device with pci subsystem
- * @name: name identifier for this driver
- * @sep_pci_id_tbl: pointer to struct pci_device_id table
- * @sep_probe: pointer to probe function in PCI driver
- * @sep_remove: pointer to remove function in PCI driver
- */
-static struct pci_driver sep_pci_driver = {
-#ifdef SEP_ENABLE_RUNTIME_PM
- .driver = {
- .pm = &sep_pm,
- },
-#endif
- .name = "sep_sec_driver",
- .id_table = sep_pci_id_tbl,
- .probe = sep_probe,
- .remove = sep_remove
-};
-
-module_pci_driver(sep_pci_driver);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_trace_events.h b/drivers/staging/sep/sep_trace_events.h
deleted file mode 100644
index 74f4c9a2b5be..000000000000
--- a/drivers/staging/sep/sep_trace_events.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * If TRACE_SYSTEM is defined, that will be the directory created
- * in the ftrace directory under /sys/kernel/debug/tracing/events/<system>
- *
- * The define_trace.h below will also look for a file name of
- * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here.
- * In this case, it would look for sample.h
- *
- * If the header name will be different than the system name
- * (as in this case), then you can override the header name that
- * define_trace.h will look up by defining TRACE_INCLUDE_FILE
- *
- * This file is called trace-events-sample.h but we want the system
- * to be called "sample". Therefore we must define the name of this
- * file:
- *
- * #define TRACE_INCLUDE_FILE trace-events-sample
- *
- * As we do an the bottom of this file.
- *
- * Notice that TRACE_SYSTEM should be defined outside of #if
- * protection, just like TRACE_INCLUDE_FILE.
- */
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM sep
-
-/*
- * Notice that this file is not protected like a normal header.
- * We also must allow for rereading of this file. The
- *
- * || defined(TRACE_HEADER_MULTI_READ)
- *
- * serves this purpose.
- */
-#if !defined(_TRACE_SEP_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_SEP_EVENTS_H
-
-#ifdef SEP_PERF_DEBUG
-#define SEP_TRACE_FUNC_IN() trace_sep_func_start(__func__, 0)
-#define SEP_TRACE_FUNC_OUT(branch) trace_sep_func_end(__func__, branch)
-#define SEP_TRACE_EVENT(branch) trace_sep_misc_event(__func__, branch)
-#else
-#define SEP_TRACE_FUNC_IN()
-#define SEP_TRACE_FUNC_OUT(branch)
-#define SEP_TRACE_EVENT(branch)
-#endif
-
-
-/*
- * All trace headers should include tracepoint.h, until we finally
- * make it into a standard header.
- */
-#include <linux/tracepoint.h>
-
-/*
- * Since use str*cpy in header file, better to include string.h, directly.
- */
-#include <linux/string.h>
-
-/*
- * The TRACE_EVENT macro is broken up into 5 parts.
- *
- * name: name of the trace point. This is also how to enable the tracepoint.
- * A function called trace_foo_bar() will be created.
- *
- * proto: the prototype of the function trace_foo_bar()
- * Here it is trace_foo_bar(char *foo, int bar).
- *
- * args: must match the arguments in the prototype.
- * Here it is simply "foo, bar".
- *
- * struct: This defines the way the data will be stored in the ring buffer.
- * There are currently two types of elements. __field and __array.
- * a __field is broken up into (type, name). Where type can be any
- * type but an array.
- * For an array. there are three fields. (type, name, size). The
- * type of elements in the array, the name of the field and the size
- * of the array.
- *
- * __array( char, foo, 10) is the same as saying char foo[10].
- *
- * fast_assign: This is a C like function that is used to store the items
- * into the ring buffer.
- *
- * printk: This is a way to print out the data in pretty print. This is
- * useful if the system crashes and you are logging via a serial line,
- * the data can be printed to the console using this "printk" method.
- *
- * Note, that for both the assign and the printk, __entry is the handler
- * to the data structure in the ring buffer, and is defined by the
- * TP_STRUCT__entry.
- */
-TRACE_EVENT(sep_func_start,
-
- TP_PROTO(const char *name, int branch),
-
- TP_ARGS(name, branch),
-
- TP_STRUCT__entry(
- __array(char, name, 20)
- __field(int, branch)
- ),
-
- TP_fast_assign(
- strlcpy(__entry->name, name, 20);
- __entry->branch = branch;
- ),
-
- TP_printk("func_start %s %d", __entry->name, __entry->branch)
-);
-
-TRACE_EVENT(sep_func_end,
-
- TP_PROTO(const char *name, int branch),
-
- TP_ARGS(name, branch),
-
- TP_STRUCT__entry(
- __array(char, name, 20)
- __field(int, branch)
- ),
-
- TP_fast_assign(
- strlcpy(__entry->name, name, 20);
- __entry->branch = branch;
- ),
-
- TP_printk("func_end %s %d", __entry->name, __entry->branch)
-);
-
-TRACE_EVENT(sep_misc_event,
-
- TP_PROTO(const char *name, int branch),
-
- TP_ARGS(name, branch),
-
- TP_STRUCT__entry(
- __array(char, name, 20)
- __field(int, branch)
- ),
-
- TP_fast_assign(
- strlcpy(__entry->name, name, 20);
- __entry->branch = branch;
- ),
-
- TP_printk("misc_event %s %d", __entry->name, __entry->branch)
-);
-
-
-#endif
-
-/***** NOTICE! The #if protection ends here. *****/
-
-
-/*
- * There are several ways I could have done this. If I left out the
- * TRACE_INCLUDE_PATH, then it would default to the kernel source
- * include/trace/events directory.
- *
- * I could specify a path from the define_trace.h file back to this
- * file.
- *
- * #define TRACE_INCLUDE_PATH ../../samples/trace_events
- *
- * But the safest and easiest way to simply make it use the directory
- * that the file is in is to add in the Makefile:
- *
- * CFLAGS_trace-events-sample.o := -I$(src)
- *
- * This will make sure the current path is part of the include
- * structure for our file so that define_trace.h can find it.
- *
- * I could have made only the top level directory the include:
- *
- * CFLAGS_trace-events-sample.o := -I$(PWD)
- *
- * And then let the path to this directory be the TRACE_INCLUDE_PATH:
- *
- * #define TRACE_INCLUDE_PATH samples/trace_events
- *
- * But then if something defines "samples" or "trace_events" as a macro
- * then we could risk that being converted too, and give us an unexpected
- * result.
- */
-#undef TRACE_INCLUDE_PATH
-#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_PATH .
-/*
- * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal
- */
-#define TRACE_INCLUDE_FILE sep_trace_events
-#include <trace/define_trace.h>
diff --git a/drivers/staging/serqt_usb2/Kconfig b/drivers/staging/serqt_usb2/Kconfig
deleted file mode 100644
index f4fed40e23dd..000000000000
--- a/drivers/staging/serqt_usb2/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config USB_SERIAL_QUATECH2
- tristate "USB Quatech ESU-100 8 Port Serial Driver"
- depends on USB_SERIAL
- help
- Say Y here if you want to use the Quatech ESU-100 8 port usb to
- serial adapter.
-
- To compile this driver as a module, choose M here: the
- module will be called serqt_usb2.
diff --git a/drivers/staging/serqt_usb2/Makefile b/drivers/staging/serqt_usb2/Makefile
deleted file mode 100644
index 21578617f7e8..000000000000
--- a/drivers/staging/serqt_usb2/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2.o
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
deleted file mode 100644
index 998c3845421d..000000000000
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ /dev/null
@@ -1,1528 +0,0 @@
-/*
- * This code was developed for the Quatech USB line for linux, it used
- * much of the code developed by Greg Kroah-Hartman for USB serial devices
- *
- */
-
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/serial.h>
-#include <linux/usb.h>
-#include <linux/usb/serial.h>
-#include <linux/uaccess.h>
-
-/* Version Information */
-#define DRIVER_VERSION "v2.14"
-#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
-#define DRIVER_DESC "Quatech USB to Serial Driver"
-
-#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */
-#define QUATECH_SSU200 0xC030 /* SSU200 */
-#define QUATECH_DSU100 0xC040 /* DSU100 */
-#define QUATECH_DSU200 0xC050 /* DSU200 */
-#define QUATECH_QSU100 0xC060 /* QSU100 */
-#define QUATECH_QSU200 0xC070 /* QSU200 */
-#define QUATECH_ESU100A 0xC080 /* ESU100A */
-#define QUATECH_ESU100B 0xC081 /* ESU100B */
-#define QUATECH_ESU200A 0xC0A0 /* ESU200A */
-#define QUATECH_ESU200B 0xC0A1 /* ESU200B */
-#define QUATECH_HSU100A 0xC090 /* HSU100A */
-#define QUATECH_HSU100B 0xC091 /* HSU100B */
-#define QUATECH_HSU100C 0xC092 /* HSU100C */
-#define QUATECH_HSU100D 0xC093 /* HSU100D */
-#define QUATECH_HSU200A 0xC0B0 /* HSU200A */
-#define QUATECH_HSU200B 0xC0B1 /* HSU200B */
-#define QUATECH_HSU200C 0xC0B2 /* HSU200C */
-#define QUATECH_HSU200D 0xC0B3 /* HSU200D */
-
-#define QT_SET_GET_DEVICE 0xc2
-#define QT_OPEN_CLOSE_CHANNEL 0xca
-#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
-#define QT_SET_ATF 0xcd
-#define QT_GET_SET_REGISTER 0xc0
-#define QT_GET_SET_UART 0xc1
-#define QT_HW_FLOW_CONTROL_MASK 0xc5
-#define QT_SW_FLOW_CONTROL_MASK 0xc6
-#define QT_SW_FLOW_CONTROL_DISABLE 0xc7
-#define QT_BREAK_CONTROL 0xc8
-
-#define USBD_TRANSFER_DIRECTION_IN 0xc0
-#define USBD_TRANSFER_DIRECTION_OUT 0x40
-
-#define MAX_BAUD_RATE 460800
-#define MAX_BAUD_REMAINDER 4608
-
-#define DIV_LATCH_LS 0x00
-#define XMT_HOLD_REGISTER 0x00
-#define XVR_BUFFER_REGISTER 0x00
-#define DIV_LATCH_MS 0x01
-#define FIFO_CONTROL_REGISTER 0x02
-#define LINE_CONTROL_REGISTER 0x03
-#define MODEM_CONTROL_REGISTER 0x04
-#define LINE_STATUS_REGISTER 0x05
-#define MODEM_STATUS_REGISTER 0x06
-
-#define SERIAL_MCR_DTR 0x01
-#define SERIAL_MCR_RTS 0x02
-#define SERIAL_MCR_LOOP 0x10
-
-#define SERIAL_MSR_CTS 0x10
-#define SERIAL_MSR_CD 0x80
-#define SERIAL_MSR_RI 0x40
-#define SERIAL_MSR_DSR 0x20
-#define SERIAL_MSR_MASK 0xf0
-
-#define SERIAL_8_DATA 0x03
-#define SERIAL_7_DATA 0x02
-#define SERIAL_6_DATA 0x01
-#define SERIAL_5_DATA 0x00
-
-#define SERIAL_ODD_PARITY 0X08
-#define SERIAL_EVEN_PARITY 0X18
-#define SERIAL_TWO_STOPB 0x04
-#define SERIAL_ONE_STOPB 0x00
-
-#define DEFAULT_DIVISOR 0x30 /* gives 9600 baud rate */
-#define DEFAULT_LCR SERIAL_8_DATA /* 8, none , 1 */
-
-#define FULLPWRBIT 0x00000080
-#define NEXT_BOARD_POWER_BIT 0x00000004
-
-#define SERIAL_LSR_OE 0x02
-#define SERIAL_LSR_PE 0x04
-#define SERIAL_LSR_FE 0x08
-#define SERIAL_LSR_BI 0x10
-
-#define SERIAL_MSR_CTS 0x10
-#define SERIAL_MSR_CD 0x80
-#define SERIAL_MSR_RI 0x40
-#define SERIAL_MSR_DSR 0x20
-#define SERIAL_MSR_MASK 0xf0
-
-#define PREFUFF_LEVEL_CONSERVATIVE 128
-#define ATC_DISABLED 0x0
-
-#define RR_BITS 0x03 /* for clearing clock bits */
-#define DUPMODE_BITS 0xc0
-#define CLKS_X4 0x02
-
-#define LOOPMODE_BITS 0x41 /* LOOP1 = b6, LOOP0 = b0 (PORT B) */
-#define ALL_LOOPBACK 0x01
-#define MODEM_CTRL 0x40
-#define RS232_MODE 0x00
-
-static const struct usb_device_id id_table[] = {
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU200)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU100)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU200)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100A)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100B)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU200A)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU200B)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100A)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100B)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100C)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU100D)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200A)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200B)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200C)},
- {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200D)},
- {} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-struct qt_get_device_data {
- __u8 porta;
- __u8 portb;
- __u8 portc;
-};
-
-struct qt_open_channel_data {
- __u8 line_status;
- __u8 modem_status;
-};
-
-struct quatech_port {
- int port_num; /* number of the port */
- struct urb *write_urb; /* write URB for this port */
- struct urb *read_urb; /* read URB for this port */
- struct urb *int_urb;
-
- __u8 shadow_lcr; /* last LCR value received */
- __u8 shadow_mcr; /* last MCR value received */
- __u8 shadow_msr; /* last MSR value received */
- __u8 shadow_lsr; /* last LSR value received */
- char open_ports;
-
- /* Used for TIOCMIWAIT */
- wait_queue_head_t msr_wait;
- char prev_status, diff_status;
-
- wait_queue_head_t wait;
-
- struct async_icount icount;
-
- struct usb_serial_port *port; /* owner of this object */
- struct qt_get_device_data device_data;
- struct mutex lock;
- bool read_urb_busy;
- int rx_holding;
- int read_bulk_stopped;
- char close_pending;
-};
-
-static int port_paranoia_check(struct usb_serial_port *port,
- const char *function)
-{
- if (!port) {
- pr_debug("%s - port == NULL", function);
- return -1;
- }
- if (!port->serial) {
- pr_debug("%s - port->serial == NULL\n", function);
- return -1;
- }
-
- return 0;
-}
-
-static int serial_paranoia_check(struct usb_serial *serial,
- const char *function)
-{
- if (!serial) {
- pr_debug("%s - serial == NULL\n", function);
- return -1;
- }
-
- if (!serial->type) {
- pr_debug("%s - serial->type == NULL!", function);
- return -1;
- }
-
- return 0;
-}
-
-static inline struct quatech_port *qt_get_port_private(struct usb_serial_port
- *port)
-{
- return (struct quatech_port *)usb_get_serial_port_data(port);
-}
-
-static inline void qt_set_port_private(struct usb_serial_port *port,
- struct quatech_port *data)
-{
- usb_set_serial_port_data(port, (void *)data);
-}
-
-static struct usb_serial *get_usb_serial(struct usb_serial_port *port,
- const char *function)
-{
- /* if no port was specified, or it fails a paranoia check */
- if (!port ||
- port_paranoia_check(port, function) ||
- serial_paranoia_check(port->serial, function)) {
- /*
- * then say that we dont have a valid usb_serial thing,
- * which will end up genrating -ENODEV return values
- */
- return NULL;
- }
-
- return port->serial;
-}
-
-static void process_line_status(struct quatech_port *qt_port,
- unsigned char line_status)
-{
-
- qt_port->shadow_lsr =
- line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
- SERIAL_LSR_BI);
-}
-
-static void process_modem_status(struct quatech_port *qt_port,
- unsigned char modem_status)
-{
-
- qt_port->shadow_msr = modem_status;
- wake_up_interruptible(&qt_port->wait);
-}
-
-static void process_rx_char(struct usb_serial_port *port, unsigned char data)
-{
- struct urb *urb = port->read_urb;
- if (urb->actual_length)
- tty_insert_flip_char(&port->port, data, TTY_NORMAL);
-}
-
-static void qt_write_bulk_callback(struct urb *urb)
-{
- int status;
- struct quatech_port *quatech_port;
-
- status = urb->status;
-
- if (status) {
- dev_dbg(&urb->dev->dev,
- "nonzero write bulk status received:%d\n", status);
- return;
- }
-
- quatech_port = urb->context;
-
- tty_port_tty_wakeup(&quatech_port->port->port);
-}
-
-static void qt_interrupt_callback(struct urb *urb)
-{
- /* FIXME */
-}
-
-static void qt_status_change_check(struct urb *urb,
- struct quatech_port *qt_port,
- struct usb_serial_port *port)
-{
- int flag, i;
- unsigned char *data = urb->transfer_buffer;
- unsigned int rx_count = urb->actual_length;
-
- for (i = 0; i < rx_count; ++i) {
- /* Look ahead code here */
- if ((i <= (rx_count - 3)) && (data[i] == 0x1b)
- && (data[i + 1] == 0x1b)) {
- flag = 0;
- switch (data[i + 2]) {
- case 0x00:
- if (i > (rx_count - 4)) {
- dev_dbg(&port->dev,
- "Illegal escape seuences in received data\n");
- break;
- }
-
- process_line_status(qt_port, data[i + 3]);
-
- i += 3;
- flag = 1;
- break;
-
- case 0x01:
- if (i > (rx_count - 4)) {
- dev_dbg(&port->dev,
- "Illegal escape seuences in received data\n");
- break;
- }
-
- process_modem_status(qt_port, data[i + 3]);
-
- i += 3;
- flag = 1;
- break;
-
- case 0xff:
- dev_dbg(&port->dev, "No status sequence.\n");
-
- process_rx_char(port, data[i]);
- process_rx_char(port, data[i + 1]);
-
- i += 2;
- break;
- }
- if (flag == 1)
- continue;
- }
-
- if (urb->actual_length)
- tty_insert_flip_char(&port->port, data[i], TTY_NORMAL);
-
- }
- tty_flip_buffer_push(&port->port);
-}
-
-static void qt_read_bulk_callback(struct urb *urb)
-{
-
- struct usb_serial_port *port = urb->context;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port = qt_get_port_private(port);
- int result;
-
- if (urb->status) {
- qt_port->read_bulk_stopped = 1;
- dev_dbg(&urb->dev->dev,
- "%s - nonzero write bulk status received: %d\n",
- __func__, urb->status);
- return;
- }
-
- dev_dbg(&port->dev,
- "%s - port->rx_holding = %d\n", __func__, qt_port->rx_holding);
-
- if (port_paranoia_check(port, __func__) != 0) {
- qt_port->read_bulk_stopped = 1;
- return;
- }
-
- if (!serial)
- return;
-
- if (qt_port->close_pending == 1) {
- /* Were closing , stop reading */
- dev_dbg(&port->dev,
- "%s - (qt_port->close_pending == 1\n", __func__);
- qt_port->read_bulk_stopped = 1;
- return;
- }
-
- /*
- * rx_holding is asserted by throttle, if we assert it, we're not
- * receiving any more characters and let the box handle the flow
- * control
- */
- if (qt_port->rx_holding == 1) {
- qt_port->read_bulk_stopped = 1;
- return;
- }
-
- if (urb->status) {
- qt_port->read_bulk_stopped = 1;
-
- dev_dbg(&port->dev,
- "%s - nonzero read bulk status received: %d\n",
- __func__, urb->status);
- return;
- }
-
- if (urb->actual_length)
- qt_status_change_check(urb, qt_port, port);
-
- /* Continue trying to always read */
- usb_fill_bulk_urb(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer,
- port->read_urb->transfer_buffer_length,
- qt_read_bulk_callback, port);
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
- if (result)
- dev_dbg(&port->dev,
- "%s - failed resubmitting read urb, error %d",
- __func__, result);
- else {
- if (urb->actual_length) {
- tty_flip_buffer_push(&port->port);
- tty_schedule_flip(&port->port);
- }
- }
-
- schedule_work(&port->work);
-}
-
-/*
- * qt_get_device
- * Issue a GET_DEVICE vendor-specific request on the default control pipe If
- * successful, fills in the qt_get_device_data structure pointed to by
- * device_data, otherwise return a negative error number of the problem.
- */
-
-static int qt_get_device(struct usb_serial *serial,
- struct qt_get_device_data *device_data)
-{
- int result;
- unsigned char *transfer_buffer;
-
- transfer_buffer =
- kmalloc(sizeof(struct qt_get_device_data), GFP_KERNEL);
- if (!transfer_buffer)
- return -ENOMEM;
-
- result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- QT_SET_GET_DEVICE, 0xc0, 0, 0,
- transfer_buffer,
- sizeof(struct qt_get_device_data), 300);
- if (result > 0)
- memcpy(device_data, transfer_buffer,
- sizeof(struct qt_get_device_data));
- kfree(transfer_buffer);
-
- return result;
-}
-
-/****************************************************************************
- * box_set_prebuffer_level
- TELLS BOX WHEN TO ASSERT FLOW CONTROL
- ****************************************************************************/
-static int box_set_prebuffer_level(struct usb_serial *serial)
-{
- int result;
- __u16 buffer_length;
-
- buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
- result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_GET_SET_PREBUF_TRIG_LVL, 0x40,
- buffer_length, 0, NULL, 0, 300);
- return result;
-}
-
-/****************************************************************************
- * box_set_atc
- TELLS BOX WHEN TO ASSERT automatic transmitter control
- ****************************************************************************/
-static int box_set_atc(struct usb_serial *serial, __u16 n_mode)
-{
- int result;
- __u16 buffer_length;
-
- buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_SET_ATF, 0x40, n_mode, 0, NULL, 0, 300);
-
- return result;
-}
-
-/**
- * qt_set_device
- * Issue a SET_DEVICE vendor-specific request on the default control pipe If
- * successful returns the number of bytes written, otherwise it returns a
- * negative error number of the problem.
- */
-static int qt_set_device(struct usb_serial *serial,
- struct qt_get_device_data *device_data)
-{
- int result;
- __u16 length;
- __u16 port_settings;
-
- port_settings = ((__u16) (device_data->portb));
- port_settings = (port_settings << 8);
- port_settings += ((__u16) (device_data->porta));
-
- length = sizeof(struct qt_get_device_data);
-
- result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_SET_GET_DEVICE, 0x40, port_settings,
- 0, NULL, 0, 300);
- return result;
-}
-
-static int qt_open_channel(struct usb_serial *serial, __u16 uart_num,
- struct qt_open_channel_data *pdevice_data)
-{
- int result;
-
- result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- QT_OPEN_CLOSE_CHANNEL,
- USBD_TRANSFER_DIRECTION_IN, 1, uart_num,
- pdevice_data,
- sizeof(struct qt_open_channel_data), 300);
-
- return result;
-
-}
-
-static int qt_close_channel(struct usb_serial *serial, __u16 uart_num)
-{
- int result;
-
- result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- QT_OPEN_CLOSE_CHANNEL,
- USBD_TRANSFER_DIRECTION_OUT, 0, uart_num,
- NULL, 0, 300);
-
- return result;
-
-}
-
-/****************************************************************************
-* box_get_register
-* issuse a GET_REGISTER vendor-spcific request on the default control pipe
-* If successful, fills in the p_value with the register value asked for
-****************************************************************************/
-static int box_get_register(struct usb_serial *serial, unsigned short uart_num,
- unsigned short register_num, __u8 *p_value)
-{
- int result;
- __u16 current_length;
-
- current_length = sizeof(struct qt_get_device_data);
-
- result =
- usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
- QT_GET_SET_REGISTER, 0xC0, register_num,
- uart_num, (void *)p_value, sizeof(*p_value), 300);
-
- return result;
-}
-
-/****************************************************************************
-* box_set_register
-* issuse a GET_REGISTER vendor-spcific request on the default control pipe
-* If successful, fills in the p_value with the register value asked for
-****************************************************************************/
-static int box_set_register(struct usb_serial *serial, unsigned short uart_num,
- unsigned short register_num, unsigned short value)
-{
- int result;
- unsigned short reg_and_byte;
-
- reg_and_byte = value;
- reg_and_byte = reg_and_byte << 8;
- reg_and_byte = reg_and_byte + register_num;
-
-/*
- result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_GET_SET_REGISTER, 0xC0, register_num,
- uart_num, NULL, 0, 300);
-*/
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_GET_SET_REGISTER, 0x40, reg_and_byte, uart_num,
- NULL, 0, 300);
-
- return result;
-}
-
-/*
- * qt_setuart
- * issues a SET_UART vendor-specific request on the default control pipe
- * If successful sets baud rate divisor and LCR value
- */
-static int qt_setuart(struct usb_serial *serial, unsigned short uart_num,
- unsigned short default_divisor, unsigned char default_lcr)
-{
- int result;
- unsigned short uart_num_and_lcr;
-
- uart_num_and_lcr = (default_lcr << 8) + uart_num;
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_GET_SET_UART, 0x40, default_divisor,
- uart_num_and_lcr, NULL, 0, 300);
-
- return result;
-}
-
-static int box_set_hw_flow_ctrl(struct usb_serial *serial, unsigned int index,
- int b_set)
-{
- __u8 mcr = 0;
- __u8 msr = 0, mout_value = 0;
- unsigned int status;
-
- if (b_set == 1) {
- /* flow control, box will clear RTS line to prevent remote */
- mcr = SERIAL_MCR_RTS;
- } /* device from xmitting more chars */
- else {
- /* no flow control to remote device */
- mcr = 0;
-
- }
- mout_value = mcr << 8;
-
- if (b_set == 1) {
- /* flow control, box will inhibit xmit data if CTS line is
- * asserted */
- msr = SERIAL_MSR_CTS;
- } else {
- /* Box will not inhimbe xmit data due to CTS line */
- msr = 0;
- }
- mout_value |= msr;
-
- status =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_HW_FLOW_CONTROL_MASK, 0x40, mout_value,
- index, NULL, 0, 300);
- return status;
-
-}
-
-static int box_set_sw_flow_ctrl(struct usb_serial *serial, __u16 index,
- unsigned char stop_char, unsigned char start_char)
-{
- __u16 n_sw_flow_out;
- int result;
-
- n_sw_flow_out = start_char << 8;
- n_sw_flow_out = (unsigned short)stop_char;
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_SW_FLOW_CONTROL_MASK, 0x40, n_sw_flow_out,
- index, NULL, 0, 300);
- return result;
-
-}
-
-static int box_disable_sw_flow_ctrl(struct usb_serial *serial, __u16 index)
-{
- int result;
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, index,
- NULL, 0, 300);
- return result;
-
-}
-
-static int qt_startup(struct usb_serial *serial)
-{
- struct device *dev = &serial->dev->dev;
- struct usb_serial_port *port;
- struct quatech_port *qt_port;
- struct qt_get_device_data device_data;
- int i;
- int status;
-
- /* Now setup per port private data */
- for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- qt_port = kzalloc(sizeof(*qt_port), GFP_KERNEL);
- if (!qt_port) {
- for (--i; i >= 0; i--) {
- port = serial->port[i];
- kfree(usb_get_serial_port_data(port));
- usb_set_serial_port_data(port, NULL);
- }
- return -ENOMEM;
- }
- mutex_init(&qt_port->lock);
-
- usb_set_serial_port_data(port, qt_port);
-
- }
-
- status = qt_get_device(serial, &device_data);
- if (status < 0)
- goto startup_error;
-
- dev_dbg(dev, "device_data.portb = 0x%x\n", device_data.portb);
-
- device_data.portb &= ~FULLPWRBIT;
- dev_dbg(dev, "Changing device_data.portb to 0x%x\n", device_data.portb);
-
- status = qt_set_device(serial, &device_data);
- if (status < 0) {
- dev_dbg(dev, "qt_set_device failed\n");
- goto startup_error;
- }
-
- status = qt_get_device(serial, &device_data);
- if (status < 0) {
- dev_dbg(dev, "qt_get_device failed\n");
- goto startup_error;
- }
-
- switch (le16_to_cpu(serial->dev->descriptor.idProduct)) {
- case QUATECH_DSU100:
- case QUATECH_QSU100:
- case QUATECH_ESU100A:
- case QUATECH_ESU100B:
- case QUATECH_HSU100A:
- case QUATECH_HSU100B:
- case QUATECH_HSU100C:
- case QUATECH_HSU100D:
- device_data.porta &= ~(RR_BITS | DUPMODE_BITS);
- device_data.porta |= CLKS_X4;
- device_data.portb &= ~(LOOPMODE_BITS);
- device_data.portb |= RS232_MODE;
- break;
-
- case QUATECH_SSU200:
- case QUATECH_DSU200:
- case QUATECH_QSU200:
- case QUATECH_ESU200A:
- case QUATECH_ESU200B:
- case QUATECH_HSU200A:
- case QUATECH_HSU200B:
- case QUATECH_HSU200C:
- case QUATECH_HSU200D:
- device_data.porta &= ~(RR_BITS | DUPMODE_BITS);
- device_data.porta |= CLKS_X4;
- device_data.portb &= ~(LOOPMODE_BITS);
- device_data.portb |= ALL_LOOPBACK;
- break;
- default:
- device_data.porta &= ~(RR_BITS | DUPMODE_BITS);
- device_data.porta |= CLKS_X4;
- device_data.portb &= ~(LOOPMODE_BITS);
- device_data.portb |= RS232_MODE;
- break;
-
- }
-
- status = box_set_prebuffer_level(serial); /* sets to
- * default value
- */
- if (status < 0) {
- dev_dbg(dev, "box_set_prebuffer_level failed\n");
- goto startup_error;
- }
-
- status = box_set_atc(serial, ATC_DISABLED);
- if (status < 0) {
- dev_dbg(dev, "box_set_atc failed\n");
- goto startup_error;
- }
-
- dev_dbg(dev, "device_data.portb = 0x%x\n", device_data.portb);
-
- device_data.portb |= NEXT_BOARD_POWER_BIT;
- dev_dbg(dev, "Changing device_data.portb to 0x%x\n", device_data.portb);
-
- status = qt_set_device(serial, &device_data);
- if (status < 0) {
- dev_dbg(dev, "qt_set_device failed\n");
- goto startup_error;
- }
-
- return 0;
-
-startup_error:
- for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- qt_port = qt_get_port_private(port);
- kfree(qt_port);
- usb_set_serial_port_data(port, NULL);
- }
-
- return -EIO;
-}
-
-static void qt_release(struct usb_serial *serial)
-{
- struct usb_serial_port *port;
- struct quatech_port *qt_port;
- int i;
-
- for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- if (!port)
- continue;
-
- qt_port = usb_get_serial_port_data(port);
- kfree(qt_port);
- usb_set_serial_port_data(port, NULL);
- }
-
-}
-
-static void qt_submit_urb_from_open(struct usb_serial *serial,
- struct usb_serial_port *port)
-{
- int result;
- struct usb_serial_port *port0 = serial->port[0];
-
- /* set up interrupt urb */
- usb_fill_int_urb(port0->interrupt_in_urb,
- serial->dev,
- usb_rcvintpipe(serial->dev,
- port0->interrupt_in_endpointAddress),
- port0->interrupt_in_buffer,
- port0->interrupt_in_urb->transfer_buffer_length,
- qt_interrupt_callback, serial,
- port0->interrupt_in_urb->interval);
-
- result = usb_submit_urb(port0->interrupt_in_urb,
- GFP_KERNEL);
- if (result) {
- dev_err(&port->dev,
- "%s - Error %d submitting interrupt urb\n",
- __func__, result);
- }
-}
-
-static int qt_open(struct tty_struct *tty,
- struct usb_serial_port *port)
-{
- struct usb_serial *serial;
- struct quatech_port *quatech_port;
- struct quatech_port *port0;
- struct qt_open_channel_data channel_data;
-
- int result;
-
- if (port_paranoia_check(port, __func__))
- return -ENODEV;
-
- serial = port->serial;
-
- if (serial_paranoia_check(serial, __func__))
- return -ENODEV;
-
- quatech_port = qt_get_port_private(port);
- port0 = qt_get_port_private(serial->port[0]);
-
- if (quatech_port == NULL || port0 == NULL)
- return -ENODEV;
-
- usb_clear_halt(serial->dev, port->write_urb->pipe);
- usb_clear_halt(serial->dev, port->read_urb->pipe);
- port0->open_ports++;
-
- result = qt_get_device(serial, &port0->device_data);
-
- /* Port specific setups */
- result = qt_open_channel(serial, port->port_number, &channel_data);
- if (result < 0) {
- dev_dbg(&port->dev, "qt_open_channel failed\n");
- return result;
- }
- dev_dbg(&port->dev, "qt_open_channel completed.\n");
-
-/* FIXME: are these needed? Does it even do anything useful? */
- quatech_port->shadow_lsr = channel_data.line_status &
- (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
-
- quatech_port->shadow_msr = channel_data.modem_status &
- (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
-
- /* Set Baud rate to default and turn off (default)flow control here */
- result = qt_setuart(serial, port->port_number, DEFAULT_DIVISOR,
- DEFAULT_LCR);
- if (result < 0) {
- dev_dbg(&port->dev, "qt_setuart failed\n");
- return result;
- }
- dev_dbg(&port->dev, "qt_setuart completed.\n");
-
- /*
- * Put this here to make it responsive to stty and defaults set by
- * the tty layer
- */
-
- /* Check to see if we've set up our endpoint info yet */
- if (port0->open_ports == 1) {
- if (serial->port[0]->interrupt_in_buffer == NULL)
- qt_submit_urb_from_open(serial, port);
- }
-
- dev_dbg(&port->dev, "minor number is %d\n", port->minor);
- dev_dbg(&port->dev,
- "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress);
- dev_dbg(&port->dev,
- "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress);
- dev_dbg(&port->dev, "Interrupt endpoint is %d\n",
- port->interrupt_in_endpointAddress);
- dev_dbg(&port->dev, "port's number in the device is %d\n",
- quatech_port->port_num);
- quatech_port->read_urb = port->read_urb;
-
- /* set up our bulk in urb */
-
- usb_fill_bulk_urb(quatech_port->read_urb,
- serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
- port->bulk_in_buffer,
- quatech_port->read_urb->transfer_buffer_length,
- qt_read_bulk_callback, quatech_port);
-
- dev_dbg(&port->dev, "qt_open: bulkin endpoint is %d\n",
- port->bulk_in_endpointAddress);
- quatech_port->read_urb_busy = true;
- result = usb_submit_urb(quatech_port->read_urb, GFP_KERNEL);
- if (result) {
- dev_err(&port->dev,
- "%s - Error %d submitting control urb\n",
- __func__, result);
- quatech_port->read_urb_busy = false;
- }
-
- /* initialize our wait queues */
- init_waitqueue_head(&quatech_port->wait);
- init_waitqueue_head(&quatech_port->msr_wait);
-
- /* initialize our icount structure */
- memset(&(quatech_port->icount), 0x00, sizeof(quatech_port->icount));
-
- return 0;
-
-}
-
-static int qt_chars_in_buffer(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial;
- int chars = 0;
-
- serial = get_usb_serial(port, __func__);
-
- if (serial->num_bulk_out) {
- if (port->write_urb->status == -EINPROGRESS)
- chars = port->write_urb->transfer_buffer_length;
- }
-
- return chars;
-}
-
-static void qt_block_until_empty(struct tty_struct *tty,
- struct quatech_port *qt_port)
-{
- int timeout = HZ / 10;
- int wait = 30;
-
- /* returns if we get a signal, an error, or the buffer is empty */
- while (wait_event_interruptible_timeout(qt_port->wait,
- qt_chars_in_buffer(tty) <= 0,
- timeout) == 0) {
- wait--;
- if (wait == 0) {
- dev_dbg(&qt_port->port->dev, "%s - TIMEOUT", __func__);
- return;
- } else {
- wait = 30;
- }
- }
-}
-
-static void qt_close(struct usb_serial_port *port)
-{
- struct usb_serial *serial = port->serial;
- struct tty_struct *tty = tty_port_tty_get(&port->port);
- unsigned int index = port->port_number;
- struct quatech_port *qt_port = qt_get_port_private(port);
- struct quatech_port *port0 = qt_get_port_private(serial->port[0]);
-
- /* shutdown any bulk reads that might be going on */
- if (serial->num_bulk_out)
- usb_unlink_urb(port->write_urb);
- if (serial->num_bulk_in)
- usb_unlink_urb(port->read_urb);
-
- /* wait up to for transmitter to empty */
- if (serial->dev)
- qt_block_until_empty(tty, qt_port);
- tty_kref_put(tty);
-
- /* Close uart channel */
- if (qt_close_channel(serial, index) < 0)
- dev_dbg(&port->dev, "%s - qt_close_channel failed.\n",
- __func__);
-
- port0->open_ports--;
-
- dev_dbg(&port->dev, "qt_num_open_ports in close%d\n",
- port0->open_ports);
-
- if (port0->open_ports == 0) {
- if (serial->port[0]->interrupt_in_urb) {
- dev_dbg(&port->dev, "Shutdown interrupt_in_urb\n");
- usb_kill_urb(serial->port[0]->interrupt_in_urb);
- }
-
- }
-
- if (qt_port->write_urb) {
- /* if this urb had a transfer buffer already (old tx) free it */
- kfree(qt_port->write_urb->transfer_buffer);
- usb_free_urb(qt_port->write_urb);
- }
-
-}
-
-static int qt_write(struct tty_struct *tty, struct usb_serial_port *port,
- const unsigned char *buf, int count)
-{
- int result;
- struct usb_serial *serial = get_usb_serial(port, __func__);
-
- if (serial == NULL)
- return -ENODEV;
-
- if (count == 0) {
- dev_dbg(&port->dev,
- "%s - write request of 0 bytes\n", __func__);
- return 0;
- }
-
- /* only do something if we have a bulk out endpoint */
- if (serial->num_bulk_out) {
- if (port->write_urb->status == -EINPROGRESS) {
- dev_dbg(&port->dev, "%s - already writing\n", __func__);
- return 0;
- }
-
- count =
- (count > port->bulk_out_size) ? port->bulk_out_size : count;
- memcpy(port->write_urb->transfer_buffer, buf, count);
-
- /* set up our urb */
-
- usb_fill_bulk_urb(port->write_urb, serial->dev,
- usb_sndbulkpipe(serial->dev,
- port->
- bulk_out_endpointAddress),
- port->write_urb->transfer_buffer, count,
- qt_write_bulk_callback, port);
-
- /* send the data out the bulk port */
- result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
- if (result)
- dev_dbg(&port->dev,
- "%s - failed submitting write urb, error %d\n",
- __func__, result);
- else
- result = count;
-
- return result;
- }
-
- /* no bulk out, so return 0 bytes written */
- return 0;
-}
-
-static int qt_write_room(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial;
- struct quatech_port *qt_port;
-
- int retval = -EINVAL;
-
- if (port_paranoia_check(port, __func__))
- return -1;
-
- serial = get_usb_serial(port, __func__);
-
- if (!serial)
- return -ENODEV;
-
- qt_port = qt_get_port_private(port);
-
- mutex_lock(&qt_port->lock);
-
- if (serial->num_bulk_out) {
- if (port->write_urb->status != -EINPROGRESS)
- retval = port->bulk_out_size;
- }
-
- mutex_unlock(&qt_port->lock);
- return retval;
-
-}
-
-static int qt_ioctl(struct tty_struct *tty,
- unsigned int cmd, unsigned long arg)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct quatech_port *qt_port = qt_get_port_private(port);
- unsigned int index;
-
- dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd);
-
- index = port->port_number;
-
- if (cmd == TIOCMIWAIT) {
- while (qt_port != NULL) {
-#if 0
- /* this never wakes up */
- interruptible_sleep_on(&qt_port->msr_wait);
-#endif
- if (signal_pending(current))
- return -ERESTARTSYS;
- else {
- char diff = qt_port->diff_status;
-
- if (diff == 0)
- return -EIO; /* no change => error */
-
- /* Consume all events */
- qt_port->diff_status = 0;
-
- if (((arg & TIOCM_RNG)
- && (diff & SERIAL_MSR_RI))
- || ((arg & TIOCM_DSR)
- && (diff & SERIAL_MSR_DSR))
- || ((arg & TIOCM_CD)
- && (diff & SERIAL_MSR_CD))
- || ((arg & TIOCM_CTS)
- && (diff & SERIAL_MSR_CTS))) {
- return 0;
- }
- }
- }
- return 0;
- }
-
- dev_dbg(&port->dev, "%s -No ioctl for that one.\n", __func__);
- return -ENOIOCTLCMD;
-}
-
-static void qt_set_termios(struct tty_struct *tty,
- struct usb_serial_port *port,
- struct ktermios *old_termios)
-{
- struct ktermios *termios = &tty->termios;
- unsigned char new_lcr = 0;
- unsigned int cflag = termios->c_cflag;
- unsigned int index;
- int baud, divisor, remainder;
- int status;
-
- index = port->port_number;
-
- switch (cflag & CSIZE) {
- case CS5:
- new_lcr |= SERIAL_5_DATA;
- break;
- case CS6:
- new_lcr |= SERIAL_6_DATA;
- break;
- case CS7:
- new_lcr |= SERIAL_7_DATA;
- break;
- default:
- termios->c_cflag &= ~CSIZE;
- termios->c_cflag |= CS8;
- case CS8:
- new_lcr |= SERIAL_8_DATA;
- break;
- }
-
- /* Parity stuff */
- if (cflag & PARENB) {
- if (cflag & PARODD)
- new_lcr |= SERIAL_ODD_PARITY;
- else
- new_lcr |= SERIAL_EVEN_PARITY;
- }
- if (cflag & CSTOPB)
- new_lcr |= SERIAL_TWO_STOPB;
- else
- new_lcr |= SERIAL_ONE_STOPB;
-
- dev_dbg(&port->dev, "%s - 4\n", __func__);
-
- /* Thats the LCR stuff, go ahead and set it */
- baud = tty_get_baud_rate(tty);
- if (!baud)
- /* pick a default, any default... */
- baud = 9600;
-
- dev_dbg(&port->dev, "%s - got baud = %d\n", __func__, baud);
-
- divisor = MAX_BAUD_RATE / baud;
- remainder = MAX_BAUD_RATE % baud;
- /* Round to nearest divisor */
- if (((remainder * 2) >= baud) && (baud != 110))
- divisor++;
-
- /*
- * Set Baud rate to default and turn off (default)flow control here
- */
- status =
- qt_setuart(port->serial, index, (unsigned short)divisor, new_lcr);
- if (status < 0) {
- dev_dbg(&port->dev, "qt_setuart failed\n");
- return;
- }
-
- /* Now determine flow control */
- if (cflag & CRTSCTS) {
- dev_dbg(&port->dev, "%s - Enabling HW flow control\n",
- __func__);
-
- /* Enable RTS/CTS flow control */
- status = box_set_hw_flow_ctrl(port->serial, index, 1);
-
- if (status < 0) {
- dev_dbg(&port->dev, "box_set_hw_flow_ctrl failed\n");
- return;
- }
- } else {
- /* Disable RTS/CTS flow control */
- dev_dbg(&port->dev,
- "%s - disabling HW flow control\n", __func__);
-
- status = box_set_hw_flow_ctrl(port->serial, index, 0);
- if (status < 0) {
- dev_dbg(&port->dev, "box_set_hw_flow_ctrl failed\n");
- return;
- }
-
- }
-
- /* if we are implementing XON/XOFF, set the start and stop character in
- * the device */
- if (I_IXOFF(tty) || I_IXON(tty)) {
- unsigned char stop_char = STOP_CHAR(tty);
- unsigned char start_char = START_CHAR(tty);
-
- status = box_set_sw_flow_ctrl(port->serial, index, stop_char,
- start_char);
- if (status < 0)
- dev_dbg(&port->dev,
- "box_set_sw_flow_ctrl (enabled) failed\n");
-
- } else {
- /* disable SW flow control */
- status = box_disable_sw_flow_ctrl(port->serial, index);
- if (status < 0)
- dev_dbg(&port->dev,
- "box_set_sw_flow_ctrl (diabling) failed\n");
-
- }
- termios->c_cflag &= ~CMSPAR;
- /* FIXME:
- Error cases should be returning the actual bits changed only
- */
-}
-
-static void qt_break(struct tty_struct *tty, int break_state)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port;
- u16 index, onoff;
- unsigned int result;
-
- index = port->port_number;
-
- qt_port = qt_get_port_private(port);
-
- if (break_state == -1)
- onoff = 1;
- else
- onoff = 0;
-
- mutex_lock(&qt_port->lock);
-
- result =
- usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
- QT_BREAK_CONTROL, 0x40, onoff, index, NULL, 0, 300);
-
- mutex_unlock(&qt_port->lock);
-}
-
-static inline int qt_real_tiocmget(struct tty_struct *tty,
- struct usb_serial_port *port,
- struct usb_serial *serial)
-{
-
- u8 mcr;
- u8 msr;
- unsigned int result = 0;
- int status;
- unsigned int index;
-
- index = port->port_number;
- status =
- box_get_register(port->serial, index, MODEM_CONTROL_REGISTER, &mcr);
- if (status >= 0) {
- status =
- box_get_register(port->serial, index,
- MODEM_STATUS_REGISTER, &msr);
-
- }
-
- if (status >= 0) {
- result = ((mcr & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
- /* DTR IS SET */
- | ((mcr & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
- /* RTS IS SET */
- | ((msr & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
- /* CTS is set */
- | ((msr & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
- /* Carrier detect is set */
- | ((msr & SERIAL_MSR_RI) ? TIOCM_RI : 0)
- /* Ring indicator set */
- | ((msr & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
- /* DSR is set */
- return result;
-
- } else
- return -ESPIPE;
-}
-
-static inline int qt_real_tiocmset(struct tty_struct *tty,
- struct usb_serial_port *port,
- struct usb_serial *serial,
- unsigned int value)
-{
-
- u8 mcr;
- int status;
- unsigned int index;
-
- index = port->port_number;
- status =
- box_get_register(port->serial, index, MODEM_CONTROL_REGISTER, &mcr);
- if (status < 0)
- return -ESPIPE;
-
- /*
- * Turn off the RTS and DTR and loopback and then only turn on what was
- * asked for
- */
- mcr &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
- if (value & TIOCM_RTS)
- mcr |= SERIAL_MCR_RTS;
- if (value & TIOCM_DTR)
- mcr |= SERIAL_MCR_DTR;
- if (value & TIOCM_LOOP)
- mcr |= SERIAL_MCR_LOOP;
-
- status =
- box_set_register(port->serial, index, MODEM_CONTROL_REGISTER, mcr);
- if (status < 0)
- return -ESPIPE;
- else
- return 0;
-}
-
-static int qt_tiocmget(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port = qt_get_port_private(port);
- int retval;
-
- if (!serial)
- return -ENODEV;
-
- mutex_lock(&qt_port->lock);
- retval = qt_real_tiocmget(tty, port, serial);
- mutex_unlock(&qt_port->lock);
- return retval;
-}
-
-static int qt_tiocmset(struct tty_struct *tty,
- unsigned int set, unsigned int clear)
-{
-
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port = qt_get_port_private(port);
- int retval;
-
- if (!serial)
- return -ENODEV;
-
- mutex_lock(&qt_port->lock);
- retval = qt_real_tiocmset(tty, port, serial, set);
- mutex_unlock(&qt_port->lock);
- return retval;
-}
-
-static void qt_throttle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port;
-
- if (!serial)
- return;
-
- qt_port = qt_get_port_private(port);
-
- mutex_lock(&qt_port->lock);
-
- /* pass on to the driver specific version of this function */
- qt_port->rx_holding = 1;
-
- mutex_unlock(&qt_port->lock);
-}
-
-static void qt_submit_urb_from_unthrottle(struct usb_serial_port *port,
- struct usb_serial *serial)
-{
- int result;
-
- /* Start reading from the device */
- usb_fill_bulk_urb(port->read_urb, serial->dev,
- usb_rcvbulkpipe(serial->dev,
- port->bulk_in_endpointAddress),
- port->read_urb->transfer_buffer,
- port->read_urb->transfer_buffer_length,
- qt_read_bulk_callback, port);
-
- result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-
- if (result)
- dev_err(&port->dev,
- "%s - failed restarting read urb, error %d\n",
- __func__, result);
-}
-
-static void qt_unthrottle(struct tty_struct *tty)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct usb_serial *serial = get_usb_serial(port, __func__);
- struct quatech_port *qt_port;
-
- if (!serial)
- return;
-
- qt_port = qt_get_port_private(port);
-
- mutex_lock(&qt_port->lock);
-
- if (qt_port->rx_holding == 1) {
- dev_dbg(&port->dev, "%s -qt_port->rx_holding == 1\n", __func__);
-
- qt_port->rx_holding = 0;
- dev_dbg(&port->dev, "%s - qt_port->rx_holding = 0\n", __func__);
-
- /* if we have a bulk endpoint, start it up */
- if ((serial->num_bulk_in) && (qt_port->read_bulk_stopped == 1))
- qt_submit_urb_from_unthrottle(port, serial);
- }
- mutex_unlock(&qt_port->lock);
-}
-
-static int qt_calc_num_ports(struct usb_serial *serial)
-{
- int num_ports;
-
- num_ports =
- (serial->interface->cur_altsetting->desc.bNumEndpoints - 1) / 2;
-
- return num_ports;
-}
-
-static struct usb_serial_driver quatech_device = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "serqt",
- },
- .description = DRIVER_DESC,
- .id_table = id_table,
- .num_ports = 8,
- .open = qt_open,
- .close = qt_close,
- .write = qt_write,
- .write_room = qt_write_room,
- .chars_in_buffer = qt_chars_in_buffer,
- .throttle = qt_throttle,
- .unthrottle = qt_unthrottle,
- .calc_num_ports = qt_calc_num_ports,
- .ioctl = qt_ioctl,
- .set_termios = qt_set_termios,
- .break_ctl = qt_break,
- .tiocmget = qt_tiocmget,
- .tiocmset = qt_tiocmset,
- .attach = qt_startup,
- .release = qt_release,
-};
-
-static struct usb_serial_driver * const serial_drivers[] = {
- &quatech_device, NULL
-};
-
-module_usb_serial_driver(serial_drivers, id_table);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/silicom/Kconfig b/drivers/staging/silicom/Kconfig
deleted file mode 100644
index 6651bd819bc8..000000000000
--- a/drivers/staging/silicom/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Silicom device configuration
-#
-
-config NET_VENDOR_SILICOM
- bool "Silicom devices"
- default y
- depends on PCI && NETDEVICES
- ---help---
- If you have a network card (Ethernet) belonging to this class,
- say Y.
-
- Note that the answer to this question does not directly affect
- the kernel: saying N will just case the configurator to skip all
- the questions regarding Silicom chipsets. If you say Y, you will be asked
- for your specific chipset/driver in the following questions.
-
-if NET_VENDOR_SILICOM
-
-config SBYPASS
- tristate "Silicom BypassCTL library support"
- depends on PCI
- depends on m
- ---help---
- If you have a network (Ethernet) controller of this type, say Y
-
- To compile this driver as a module, choose M here. The module
- will be called bypass.
-
-config BPCTL
- tristate "Silicom BypassCTL net support"
- depends on PCI
- depends on m
- select SBYPASS
- select MII
- ---help---
- If you have a network (Ethernet) controller of this type, say Y
- or M and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called bpctl_mod.
-
-
-endif # NET_VENDOR_SILICOM
diff --git a/drivers/staging/silicom/Makefile b/drivers/staging/silicom/Makefile
deleted file mode 100644
index ca8359481c48..000000000000
--- a/drivers/staging/silicom/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for the Bypass network device drivers.
-#
-
-obj-$(CONFIG_BPCTL) += bpctl_mod.o
-obj-$(CONFIG_SBYPASS) += bypasslib/
diff --git a/drivers/staging/silicom/README b/drivers/staging/silicom/README
deleted file mode 100644
index ae970b37fdc6..000000000000
--- a/drivers/staging/silicom/README
+++ /dev/null
@@ -1,14 +0,0 @@
-
-Theory of Operation:
-
-The Silicom Bypass Network Interface Cards (NICs) are network cards with paired ports (2 or 4).
-The pairs either act as a "wire" allowing the network packets to pass or insert the device in
-between the two ports. When paired with the on-board hardware watchdog or other failsafe,
-they provide high availability for the network in the face of software outages or maintenance.
-
-The software requirements are for a kernel level driver that interfaces with the bypass and watchdog,
-as well as for control software. User control can be either the provided standalone executable
-(/bin/bpctl) or the API exposed by the Silicom library.
-
-
-
diff --git a/drivers/staging/silicom/TODO b/drivers/staging/silicom/TODO
deleted file mode 100644
index 09d07b0ea9c0..000000000000
--- a/drivers/staging/silicom/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-TODO:
- - checkpatch.pl cleanups
- - locking audit
- - single module with all functionality
- - userland
- - fix monolithic build.
-
-
diff --git a/drivers/staging/silicom/bits.h b/drivers/staging/silicom/bits.h
deleted file mode 100644
index 8c411d0d4ecd..000000000000
--- a/drivers/staging/silicom/bits.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************************/
-/* */
-/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom */
-/* 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, located in the file LICENSE. */
-/* */
-/* History: */
-/* 02/25/00 Hav Khauv Initial version. */
-/******************************************************************************/
-
-#ifndef BITS_H
-#define BITS_H
-
-/******************************************************************************/
-/* Bit Mask definitions */
-/******************************************************************************/
-
-#define BIT_NONE 0x00
-#define BIT_0 0x01
-#define BIT_1 0x02
-#define BIT_2 0x04
-#define BIT_3 0x08
-#define BIT_4 0x10
-#define BIT_5 0x20
-#define BIT_6 0x40
-#define BIT_7 0x80
-#define BIT_8 0x0100
-#define BIT_9 0x0200
-#define BIT_10 0x0400
-#define BIT_11 0x0800
-#define BIT_12 0x1000
-#define BIT_13 0x2000
-#define BIT_14 0x4000
-#define BIT_15 0x8000
-#define BIT_16 0x010000
-#define BIT_17 0x020000
-#define BIT_18 0x040000
-#define BIT_19 0x080000
-#define BIT_20 0x100000
-#define BIT_21 0x200000
-#define BIT_22 0x400000
-#define BIT_23 0x800000
-#define BIT_24 0x01000000
-#define BIT_25 0x02000000
-#define BIT_26 0x04000000
-#define BIT_27 0x08000000
-#define BIT_28 0x10000000
-#define BIT_29 0x20000000
-#define BIT_30 0x40000000
-#define BIT_31 0x80000000
-
-#endif /* BITS_H */
diff --git a/drivers/staging/silicom/bp_ioctl.h b/drivers/staging/silicom/bp_ioctl.h
deleted file mode 100644
index 57de34a69e8e..000000000000
--- a/drivers/staging/silicom/bp_ioctl.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/******************************************************************************/
-/* */
-/* Silicom Bypass Control Utility, Copyright (c) 2005-2007 Silicom */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/******************************************************************************/
-
-#ifndef BP_IOCTL_H
-#define BP_IOCTL_H
-
-#define BP_CAP 0x01 /* BIT_0 */
-#define BP_STATUS_CAP 0x02
-#define BP_STATUS_CHANGE_CAP 0x04
-#define SW_CTL_CAP 0x08
-#define BP_DIS_CAP 0x10
-#define BP_DIS_STATUS_CAP 0x20
-#define STD_NIC_CAP 0x40
-#define BP_PWOFF_ON_CAP 0x80
-#define BP_PWOFF_OFF_CAP 0x0100
-#define BP_PWOFF_CTL_CAP 0x0200
-#define BP_PWUP_ON_CAP 0x0400
-#define BP_PWUP_OFF_CAP 0x0800
-#define BP_PWUP_CTL_CAP 0x1000
-#define WD_CTL_CAP 0x2000
-#define WD_STATUS_CAP 0x4000
-#define WD_TIMEOUT_CAP 0x8000
-#define TX_CTL_CAP 0x10000
-#define TX_STATUS_CAP 0x20000
-#define TAP_CAP 0x40000
-#define TAP_STATUS_CAP 0x80000
-#define TAP_STATUS_CHANGE_CAP 0x100000
-#define TAP_DIS_CAP 0x200000
-#define TAP_DIS_STATUS_CAP 0x400000
-#define TAP_PWUP_ON_CAP 0x800000
-#define TAP_PWUP_OFF_CAP 0x1000000
-#define TAP_PWUP_CTL_CAP 0x2000000
-#define NIC_CAP_NEG 0x4000000
-#define TPL_CAP 0x8000000
-#define DISC_CAP 0x10000000
-#define DISC_DIS_CAP 0x20000000
-#define DISC_PWUP_CTL_CAP 0x40000000
-
-#define TPL2_CAP_EX 0x01
-#define DISC_PORT_CAP_EX 0x02
-
-#define WD_MIN_TIME_MASK(val) (val & 0xf)
-#define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5)
-#define WDT_STEP_TIME 0x10 /* BIT_4 */
-
-#define WD_MIN_TIME_GET(desc) (desc & 0xf)
-#define WD_STEP_COUNT_GET(desc) ((desc>>5) & 0xf)
-
-typedef enum {
- IF_SCAN,
- GET_DEV_NUM,
- IS_BYPASS,
- GET_BYPASS_SLAVE,
- GET_BYPASS_CAPS,
- GET_WD_SET_CAPS,
- SET_BYPASS,
- GET_BYPASS,
- GET_BYPASS_CHANGE,
- SET_BYPASS_WD,
- GET_BYPASS_WD,
- GET_WD_EXPIRE_TIME,
- RESET_BYPASS_WD_TIMER,
- SET_DIS_BYPASS,
- GET_DIS_BYPASS,
- SET_BYPASS_PWOFF,
- GET_BYPASS_PWOFF,
- SET_BYPASS_PWUP,
- GET_BYPASS_PWUP,
- SET_STD_NIC,
- GET_STD_NIC,
- SET_TX,
- GET_TX,
- SET_TAP,
- GET_TAP,
- GET_TAP_CHANGE,
- SET_DIS_TAP,
- GET_DIS_TAP,
- SET_TAP_PWUP,
- GET_TAP_PWUP,
- SET_WD_EXP_MODE,
- GET_WD_EXP_MODE,
- SET_WD_AUTORESET,
- GET_WD_AUTORESET,
- SET_TPL,
- GET_TPL,
- SET_DISC,
- GET_DISC,
- GET_DISC_CHANGE,
- SET_DIS_DISC,
- GET_DIS_DISC,
- SET_DISC_PWUP,
- GET_DISC_PWUP,
- GET_BYPASS_INFO = 100,
- GET_BP_WAIT_AT_PWUP,
- SET_BP_WAIT_AT_PWUP,
- GET_BP_HW_RESET,
- SET_BP_HW_RESET,
- SET_DISC_PORT,
- GET_DISC_PORT,
- SET_DISC_PORT_PWUP,
- GET_DISC_PORT_PWUP,
- SET_BP_FORCE_LINK,
- GET_BP_FORCE_LINK,
-#ifdef BP_SELF_TEST
- SET_BP_SELF_TEST = 200,
- GET_BP_SELF_TEST,
-#endif
-
-} CMND_TYPE_SD;
-
-/*
-* The major device number. We can't rely on dynamic
-* registration any more, because ioctls need to know
-* it.
-*/
-
-#define MAGIC_NUM 'J'
-
-/* for passing single values */
-struct bpctl_cmd {
- int status;
- int data[8];
- int in_param[8];
- int out_param[8];
-};
-
-#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd)
-
-#define DEVICE_NAME "bpctl"
-
-#endif
diff --git a/drivers/staging/silicom/bp_mod.h b/drivers/staging/silicom/bp_mod.h
deleted file mode 100644
index 82b4963e97b6..000000000000
--- a/drivers/staging/silicom/bp_mod.h
+++ /dev/null
@@ -1,711 +0,0 @@
-/******************************************************************************/
-/* */
-/* Bypass Control utility, Copyright (c) 2005 Silicom */
-/* */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/* bp_mod.h */
-/* */
-/******************************************************************************/
-
-#ifndef BP_MOD_H
-#define BP_MOD_H
-#include "bits.h"
-
-#define usec_delay(x) udelay(x)
-#ifndef msec_delay_bp
-#define msec_delay_bp(x) \
-do { \
- int i; \
- if (1) { \
- for (i = 0; i < 1000; i++) { \
- udelay(x); \
- } \
- } else { \
- msleep(x); \
- } \
-} while (0)
-
-#endif
-
-#include <linux/param.h>
-
-#ifndef jiffies_to_msecs
-#define jiffies_to_msecs(x) _kc_jiffies_to_msecs(x)
-static inline unsigned int jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= 1000 && !(1000 % HZ)
- return (1000 / HZ) * j;
-#elif HZ > 1000 && !(HZ % 1000)
- return (j + (HZ / 1000) - 1) / (HZ / 1000);
-#else
- return (j * 1000) / HZ;
-#endif
-}
-#endif
-
-#define SILICOM_VID 0x1374
-#define SILICOM_SVID 0x1374
-
-#define SILICOM_PXG2BPFI_SSID 0x0026
-#define SILICOM_PXG2BPFILX_SSID 0x0027
-#define SILICOM_PXGBPI_SSID 0x0028
-#define SILICOM_PXGBPIG_SSID 0x0029
-#define SILICOM_PXG2TBFI_SSID 0x002a
-#define SILICOM_PXG4BPI_SSID 0x002c
-#define SILICOM_PXG4BPFI_SSID 0x002d
-#define SILICOM_PXG4BPFILX_SSID 0x002e
-#define SILICOM_PXG2BPFIL_SSID 0x002F
-#define SILICOM_PXG2BPFILLX_SSID 0x0030
-#define SILICOM_PEG4BPI_SSID 0x0031
-#define SILICOM_PEG2BPI_SSID 0x0037
-#define SILICOM_PEG4BPIN_SSID 0x0038
-#define SILICOM_PEG2BPFI_SSID 0x0039
-#define SILICOM_PEG2BPFILX_SSID 0x003A
-#define SILICOM_PMCXG2BPFI_SSID 0x003B
-#define NOKIA_PMCXG2BPFIN_SSID 0x0510
-#define NOKIA_PMCXG2BPIN_SSID 0x0513
-#define NOKIA_PMCXG4BPIN_SSID 0x0514
-#define NOKIA_PMCXG2BPFIN_SVID 0x13B8
-#define NOKIA_PMCXG2BPIN2_SSID 0x0515
-#define NOKIA_PMCXG4BPIN2_SSID 0x0516
-#define SILICOM_PMCX2BPI_SSID 0x041
-#define SILICOM_PMCX4BPI_SSID 0x042
-#define SILICOM_PXG2BISC1_SSID 0x003d
-#define SILICOM_PEG2TBFI_SSID 0x003E
-#define SILICOM_PXG2TBI_SSID 0x003f
-#define SILICOM_PXG4BPFID_SSID 0x0043
-#define SILICOM_PEG4BPFI_SSID 0x0040
-#define SILICOM_PEG4BPIPT_SSID 0x0044
-#define SILICOM_PXG6BPI_SSID 0x0045
-#define SILICOM_PEG4BPIL_SSID 0x0046
-#define SILICOM_PEG2BPI5_SSID 0x0052
-#define SILICOM_PEG6BPI_SSID 0x0053
-#define SILICOM_PEG4BPFI5_SSID 0x0050
-#define SILICOM_PEG4BPFI5LX_SSID 0x0051
-#define SILICOM_PEG2BISC6_SSID 0x54
-
-#define SILICOM_PEG6BPIFC_SSID 0x55
-
-#define SILICOM_PEG2BPFI5_SSID 0x0056
-#define SILICOM_PEG2BPFI5LX_SSID 0x0057
-
-#define SILICOM_PXEG4BPFI_SSID 0x0058
-
-#define SILICOM_PEG2BPFID_SSID 0x0047
-#define SILICOM_PEG2BPFIDLX_SSID 0x004C
-#define SILICOM_MEG2BPFILN_SSID 0x0048
-#define SILICOM_MEG2BPFINX_SSID 0x0049
-#define SILICOM_PEG4BPFILX_SSID 0x004A
-#define SILICOM_MHIO8AD_SSID 0x004F
-
-#define SILICOM_MEG2BPFILXLN_SSID 0x004b
-#define SILICOM_PEG2BPIX1_SSID 0x004d
-#define SILICOM_MEG2BPFILXNX_SSID 0x004e
-
-#define SILICOM_PE10G2BPISR_SSID 0x0102
-#define SILICOM_PE10G2BPILR_SSID 0x0103
-#define SILICOM_PE10G2BPICX4_SSID 0x0101
-
-#define SILICOM_XE10G2BPILR_SSID 0x0163
-#define SILICOM_XE10G2BPISR_SSID 0x0162
-#define SILICOM_XE10G2BPICX4_SSID 0x0161
-#define SILICOM_XE10G2BPIT_SSID 0x0160
-
-#define SILICOM_PE10GDBISR_SSID 0x0181
-#define SILICOM_PE10GDBILR_SSID 0x0182
-
-#define SILICOM_PE210G2DBi9SR_SSID 0x0188
-#define SILICOM_PE210G2DBi9SRRB_SSID 0x0188
-#define SILICOM_PE210G2DBi9LR_SSID 0x0189
-#define SILICOM_PE210G2DBi9LRRB_SSID 0x0189
-#define SILICOM_PE310G4DBi940SR_SSID 0x018C
-
-#define SILICOM_PE310G4BPi9T_SSID 0x130
-#define SILICOM_PE310G4BPi9SR_SSID 0x132
-#define SILICOM_PE310G4BPi9LR_SSID 0x133
-
-#define NOKIA_XE10G2BPIXR_SVID 0x13B8
-#define NOKIA_XE10G2BPIXR_SSID 0x051C
-
-#define INTEL_PEG4BPII_PID 0x10A0
-#define INTEL_PEG4BPFII_PID 0x10A1
-#define INTEL_PEG4BPII_SSID 0x11A0
-#define INTEL_PEG4BPFII_SSID 0x11A1
-
-#define INTEL_PEG4BPIIO_SSID 0x10A0
-#define INTEL_PEG4BPIIO_PID 0x105e
-
-#define BROADCOM_VID 0x14e4
-#define BROADCOM_PE10G2_PID 0x164e
-
-#define SILICOM_PE10G2BPTCX4_SSID 0x0141
-#define SILICOM_PE10G2BPTSR_SSID 0x0142
-#define SILICOM_PE10G2BPTLR_SSID 0x0143
-#define SILICOM_PE10G2BPTT_SSID 0x0140
-
-#define SILICOM_PEG4BPI6_SSID 0x0320
-#define SILICOM_PEG4BPFI6_SSID 0x0321
-#define SILICOM_PEG4BPFI6LX_SSID 0x0322
-#define SILICOM_PEG4BPFI6ZX_SSID 0x0323
-
-#define SILICOM_PEG2BPI6_SSID 0x0300
-#define SILICOM_PEG2BPFI6_SSID 0x0301
-#define SILICOM_PEG2BPFI6LX_SSID 0x0302
-#define SILICOM_PEG2BPFI6ZX_SSID 0x0303
-#define SILICOM_PEG2BPFI6FLXM_SSID 0x0304
-
-#define SILICOM_PEG2DBI6_SSID 0x0308
-#define SILICOM_PEG2DBFI6_SSID 0x0309
-#define SILICOM_PEG2DBFI6LX_SSID 0x030A
-#define SILICOM_PEG2DBFI6ZX_SSID 0x030B
-
-#define SILICOM_MEG2BPI6_SSID 0x0310
-#define SILICOM_XEG2BPI6_SSID 0x0318
-#define SILICOM_PEG4BPI6FC_SSID 0x0328
-#define SILICOM_PEG4BPFI6FC_SSID 0x0329
-#define SILICOM_PEG4BPFI6FCLX_SSID 0x032A
-#define SILICOM_PEG4BPFI6FCZX_SSID 0x032B
-
-#define SILICOM_PEG6BPI6_SSID 0x0340
-
-#define SILICOM_PEG2BPI6SC6_SSID 0x0360
-
-#define SILICOM_MEG2BPI6_SSID 0x0310
-#define SILICOM_XEG2BPI6_SSID 0x0318
-#define SILICOM_MEG4BPI6_SSID 0x0330
-
-#define SILICOM_PE2G4BPi80L_SSID 0x0380
-
-#define SILICOM_M6E2G8BPi80A_SSID 0x0474
-
-#define SILICOM_PE2G4BPi35_SSID 0x03d8
-
-#define SILICOM_PE2G4BPFi80_SSID 0x0381
-#define SILICOM_PE2G4BPFi80LX_SSID 0x0382
-#define SILICOM_PE2G4BPFi80ZX_SSID 0x0383
-
-#define SILICOM_PE2G4BPi80_SSID 0x0388
-
-#define SILICOM_PE2G2BPi80_SSID 0x0390
-#define SILICOM_PE2G2BPFi80_SSID 0x0391
-#define SILICOM_PE2G2BPFi80LX_SSID 0x0392
-#define SILICOM_PE2G2BPFi80ZX_SSID 0x0393
-
-#define SILICOM_PE2G4BPi35L_SSID 0x03D0
-#define SILICOM_PE2G4BPFi35_SSID 0x03D1
-#define SILICOM_PE2G4BPFi35LX_SSID 0x03D2
-#define SILICOM_PE2G4BPFi35ZX_SSID 0x03D3
-
-#define SILICOM_PE2G2BPi35_SSID 0x03c0
-#define SILICOM_PAC1200BPi35_SSID 0x03cc
-#define SILICOM_PE2G2BPFi35_SSID 0x03C1
-#define SILICOM_PE2G2BPFi35LX_SSID 0x03C2
-#define SILICOM_PE2G2BPFi35ZX_SSID 0x03C3
-
-#define SILICOM_PE2G6BPi35_SSID 0x03E0
-#define SILICOM_PE2G6BPi35CX_SSID 0x0AA0
-
-#define INTEL_PE210G2SPI9_SSID 0x00C
-
-#define SILICOM_M1EG2BPI6_SSID 0x400
-
-#define SILICOM_M1EG2BPFI6_SSID 0x0401
-#define SILICOM_M1EG2BPFI6LX_SSID 0x0402
-#define SILICOM_M1EG2BPFI6ZX_SSID 0x0403
-
-#define SILICOM_M1EG4BPI6_SSID 0x0420
-
-#define SILICOM_M1EG4BPFI6_SSID 0x0421
-#define SILICOM_M1EG4BPFI6LX_SSID 0x0422
-#define SILICOM_M1EG4BPFI6ZX_SSID 0x0423
-
-#define SILICOM_M1EG6BPI6_SSID 0x0440
-
-#define SILICOM_M1E2G4BPi80_SSID 0x0460
-#define SILICOM_M1E2G4BPFi80_SSID 0x0461
-#define SILICOM_M1E2G4BPFi80LX_SSID 0x0462
-#define SILICOM_M1E2G4BPFi80ZX_SSID 0x0463
-
-#define SILICOM_M6E2G8BPi80_SSID 0x0470
-#define SILICOM_PE210G2BPi40_SSID 0x01a0
-
-#define PEG540_IF_SERIES(pid) \
- ((pid == SILICOM_PE210G2BPi40_SSID))
-
-#define OLD_IF_SERIES(pid)\
- ((pid == SILICOM_PXG2BPFI_SSID) || \
- (pid == SILICOM_PXG2BPFILX_SSID))
-
-#define P2BPFI_IF_SERIES(pid) \
- ((pid == SILICOM_PXG2BPFI_SSID) || \
- (pid == SILICOM_PXG2BPFILX_SSID) || \
- (pid == SILICOM_PEG2BPFI_SSID) || \
- (pid == SILICOM_PEG2BPFID_SSID) || \
- (pid == SILICOM_PEG2BPFIDLX_SSID) || \
- (pid == SILICOM_MEG2BPFILN_SSID) || \
- (pid == SILICOM_MEG2BPFINX_SSID) || \
- (pid == SILICOM_PEG4BPFILX_SSID) || \
- (pid == SILICOM_PEG4BPFI_SSID) || \
- (pid == SILICOM_PXEG4BPFI_SSID) || \
- (pid == SILICOM_PXG4BPFID_SSID) || \
- (pid == SILICOM_PEG2TBFI_SSID) || \
- (pid == SILICOM_PE10G2BPISR_SSID) || \
- (pid == SILICOM_PE10G2BPILR_SSID) || \
- (pid == SILICOM_PEG2BPFILX_SSID) || \
- (pid == SILICOM_PMCXG2BPFI_SSID) || \
- (pid == SILICOM_MHIO8AD_SSID) || \
- (pid == SILICOM_PEG4BPFI5LX_SSID) || \
- (pid == SILICOM_PEG4BPFI5_SSID) || \
- (pid == SILICOM_PEG4BPFI6FC_SSID) || \
- (pid == SILICOM_PEG4BPFI6FCLX_SSID) || \
- (pid == SILICOM_PEG4BPFI6FCZX_SSID) || \
- (pid == NOKIA_PMCXG2BPFIN_SSID) || \
- (pid == SILICOM_MEG2BPFILXLN_SSID) || \
- (pid == SILICOM_MEG2BPFILXNX_SSID) || \
- (pid == SILICOM_XE10G2BPIT_SSID) || \
- (pid == SILICOM_XE10G2BPICX4_SSID) || \
- (pid == SILICOM_XE10G2BPISR_SSID) || \
- (pid == NOKIA_XE10G2BPIXR_SSID) || \
- (pid == SILICOM_PE10GDBISR_SSID) || \
- (pid == SILICOM_PE10GDBILR_SSID) || \
- (pid == SILICOM_XE10G2BPILR_SSID))
-
-#define INTEL_IF_SERIES(pid) \
- ((pid == INTEL_PEG4BPII_SSID) || \
- (pid == INTEL_PEG4BPIIO_SSID) || \
- (pid == INTEL_PEG4BPFII_SSID))
-
-#define NOKIA_SERIES(pid) \
- ((pid == NOKIA_PMCXG2BPIN_SSID) || \
- (pid == NOKIA_PMCXG4BPIN_SSID) || \
- (pid == SILICOM_PMCX4BPI_SSID) || \
- (pid == NOKIA_PMCXG2BPFIN_SSID) || \
- (pid == SILICOM_PMCXG2BPFI_SSID) || \
- (pid == NOKIA_PMCXG2BPIN2_SSID) || \
- (pid == NOKIA_PMCXG4BPIN2_SSID) || \
- (pid == SILICOM_PMCX2BPI_SSID))
-
-#define DISCF_IF_SERIES(pid) \
- (pid == SILICOM_PEG2TBFI_SSID)
-
-#define PEGF_IF_SERIES(pid) \
- ((pid == SILICOM_PEG2BPFI_SSID) || \
- (pid == SILICOM_PEG2BPFID_SSID) || \
- (pid == SILICOM_PEG2BPFIDLX_SSID) || \
- (pid == SILICOM_PEG2BPFILX_SSID) || \
- (pid == SILICOM_PEG4BPFI_SSID) || \
- (pid == SILICOM_PXEG4BPFI_SSID) || \
- (pid == SILICOM_MEG2BPFILN_SSID) || \
- (pid == SILICOM_MEG2BPFINX_SSID) || \
- (pid == SILICOM_PEG4BPFILX_SSID) || \
- (pid == SILICOM_PEG2TBFI_SSID) || \
- (pid == SILICOM_MEG2BPFILXLN_SSID) || \
- (pid == SILICOM_MEG2BPFILXNX_SSID))
-
-#define TPL_IF_SERIES(pid) \
- ((pid == SILICOM_PXG2BPFIL_SSID) || \
- (pid == SILICOM_PXG2BPFILLX_SSID) || \
- (pid == SILICOM_PXG2TBFI_SSID) || \
- (pid == SILICOM_PXG4BPFID_SSID) || \
- (pid == SILICOM_PXG4BPFI_SSID))
-
-#define BP10G_IF_SERIES(pid) \
- ((pid == SILICOM_PE10G2BPISR_SSID) || \
- (pid == SILICOM_PE10G2BPICX4_SSID) || \
- (pid == SILICOM_PE10G2BPILR_SSID) || \
- (pid == SILICOM_XE10G2BPIT_SSID) || \
- (pid == SILICOM_XE10G2BPICX4_SSID) || \
- (pid == SILICOM_XE10G2BPISR_SSID) || \
- (pid == NOKIA_XE10G2BPIXR_SSID) || \
- (pid == SILICOM_PE10GDBISR_SSID) || \
- (pid == SILICOM_PE10GDBILR_SSID) || \
- (pid == SILICOM_XE10G2BPILR_SSID))
-
-#define BP10GB_IF_SERIES(pid) \
- ((pid == SILICOM_PE10G2BPTCX4_SSID) || \
- (pid == SILICOM_PE10G2BPTSR_SSID) || \
- (pid == SILICOM_PE10G2BPTLR_SSID) || \
- (pid == SILICOM_PE10G2BPTT_SSID))
-
-#define BP10G_CX4_SERIES(pid) \
- (pid == SILICOM_PE10G2BPICX4_SSID)
-
-#define BP10GB_CX4_SERIES(pid) \
- (pid == SILICOM_PE10G2BPTCX4_SSID)
-
-#define SILICOM_M2EG2BPFI6_SSID 0x0501
-#define SILICOM_M2EG2BPFI6LX_SSID 0x0502
-#define SILICOM_M2EG2BPFI6ZX_SSID 0x0503
-#define SILICOM_M2EG4BPI6_SSID 0x0520
-
-#define SILICOM_M2EG4BPFI6_SSID 0x0521
-#define SILICOM_M2EG4BPFI6LX_SSID 0x0522
-#define SILICOM_M2EG4BPFI6ZX_SSID 0x0523
-
-#define SILICOM_M2EG6BPI6_SSID 0x0540
-
-#define SILICOM_M1E10G2BPI9CX4_SSID 0x481
-#define SILICOM_M1E10G2BPI9SR_SSID 0x482
-#define SILICOM_M1E10G2BPI9LR_SSID 0x483
-#define SILICOM_M1E10G2BPI9T_SSID 0x480
-
-#define SILICOM_M2E10G2BPI9CX4_SSID 0x581
-#define SILICOM_M2E10G2BPI9SR_SSID 0x582
-#define SILICOM_M2E10G2BPI9LR_SSID 0x583
-#define SILICOM_M2E10G2BPI9T_SSID 0x580
-
-#define SILICOM_PE210G2BPI9CX4_SSID 0x121
-#define SILICOM_PE210G2BPI9SR_SSID 0x122
-#define SILICOM_PE210G2BPI9LR_SSID 0x123
-#define SILICOM_PE210G2BPI9T_SSID 0x120
-
-#define DBI_IF_SERIES(pid) \
- ((pid == SILICOM_PE10GDBISR_SSID) || \
- (pid == SILICOM_PE10GDBILR_SSID) || \
- (pid == SILICOM_XE10G2BPILR_SSID) || \
- (pid == SILICOM_PE210G2DBi9LR_SSID))
-
-#define PEGF5_IF_SERIES(pid) \
- ((pid == SILICOM_PEG2BPFI5_SSID) || \
- (pid == SILICOM_PEG2BPFI5LX_SSID) || \
- (pid == SILICOM_PEG4BPFI6_SSID) || \
- (pid == SILICOM_PEG4BPFI6LX_SSID) || \
- (pid == SILICOM_PEG4BPFI6ZX_SSID) || \
- (pid == SILICOM_PEG2BPFI6_SSID) || \
- (pid == SILICOM_PEG2BPFI6LX_SSID) || \
- (pid == SILICOM_PEG2BPFI6ZX_SSID) || \
- (pid == SILICOM_PEG2BPFI6FLXM_SSID) || \
- (pid == SILICOM_PEG2DBFI6_SSID) || \
- (pid == SILICOM_PEG2DBFI6LX_SSID) || \
- (pid == SILICOM_PEG2DBFI6ZX_SSID) || \
- (pid == SILICOM_PEG4BPI6FC_SSID) || \
- (pid == SILICOM_PEG4BPFI6FCLX_SSID) || \
- (pid == SILICOM_PEG4BPI6FC_SSID) || \
- (pid == SILICOM_M1EG2BPFI6_SSID) || \
- (pid == SILICOM_M1EG2BPFI6LX_SSID) || \
- (pid == SILICOM_M1EG2BPFI6ZX_SSID) || \
- (pid == SILICOM_M1EG4BPFI6_SSID) || \
- (pid == SILICOM_M1EG4BPFI6LX_SSID) || \
- (pid == SILICOM_M1EG4BPFI6ZX_SSID) || \
- (pid == SILICOM_M2EG2BPFI6_SSID) || \
- (pid == SILICOM_M2EG2BPFI6LX_SSID) || \
- (pid == SILICOM_M2EG2BPFI6ZX_SSID) || \
- (pid == SILICOM_M2EG4BPFI6_SSID) || \
- (pid == SILICOM_M2EG4BPFI6LX_SSID) || \
- (pid == SILICOM_M2EG4BPFI6ZX_SSID) || \
- (pid == SILICOM_PEG4BPFI6FCZX_SSID))
-
-#define PEG5_IF_SERIES(pid) \
- ((pid == SILICOM_PEG4BPI6_SSID) || \
- (pid == SILICOM_PEG2BPI6_SSID) || \
- (pid == SILICOM_PEG4BPI6FC_SSID) || \
- (pid == SILICOM_PEG6BPI6_SSID) || \
- (pid == SILICOM_PEG2BPI6SC6_SSID) || \
- (pid == SILICOM_MEG2BPI6_SSID) || \
- (pid == SILICOM_XEG2BPI6_SSID) || \
- (pid == SILICOM_MEG4BPI6_SSID) || \
- (pid == SILICOM_M1EG2BPI6_SSID) || \
- (pid == SILICOM_M1EG4BPI6_SSID) || \
- (pid == SILICOM_M1EG6BPI6_SSID) || \
- (pid == SILICOM_PEG6BPI_SSID) || \
- (pid == SILICOM_PEG4BPIL_SSID) || \
- (pid == SILICOM_PEG2BISC6_SSID) || \
- (pid == SILICOM_PEG2BPI5_SSID))
-
-#define PEG80_IF_SERIES(pid) \
- ((pid == SILICOM_M1E2G4BPi80_SSID) || \
- (pid == SILICOM_M6E2G8BPi80_SSID) || \
- (pid == SILICOM_PE2G4BPi80L_SSID) || \
- (pid == SILICOM_M6E2G8BPi80A_SSID) || \
- (pid == SILICOM_PE2G2BPi35_SSID) || \
- (pid == SILICOM_PAC1200BPi35_SSID) || \
- (pid == SILICOM_PE2G4BPi35_SSID) || \
- (pid == SILICOM_PE2G4BPi35L_SSID) || \
- (pid == SILICOM_PE2G6BPi35_SSID) || \
- (pid == SILICOM_PE2G2BPi80_SSID) || \
- (pid == SILICOM_PE2G4BPi80_SSID) || \
- (pid == SILICOM_PE2G4BPFi80_SSID) || \
- (pid == SILICOM_PE2G4BPFi80LX_SSID) || \
- (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G2BPFi80_SSID) || \
- (pid == SILICOM_PE2G2BPFi80LX_SSID) || \
- (pid == SILICOM_PE2G2BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G2BPFi35_SSID) || \
- (pid == SILICOM_PE2G2BPFi35LX_SSID) || \
- (pid == SILICOM_PE2G2BPFi35ZX_SSID) || \
- (pid == SILICOM_PE2G4BPFi35_SSID) || \
- (pid == SILICOM_PE2G4BPFi35LX_SSID) || \
- (pid == SILICOM_PE2G4BPFi35ZX_SSID))
-
-#define PEGF80_IF_SERIES(pid) \
- ((pid == SILICOM_PE2G4BPFi80_SSID) || \
- (pid == SILICOM_PE2G4BPFi80LX_SSID) || \
- (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G4BPFi80ZX_SSID) || \
- (pid == SILICOM_M1E2G4BPFi80_SSID) || \
- (pid == SILICOM_M1E2G4BPFi80LX_SSID) || \
- (pid == SILICOM_M1E2G4BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G2BPFi80_SSID) || \
- (pid == SILICOM_PE2G2BPFi80LX_SSID) || \
- (pid == SILICOM_PE2G2BPFi80ZX_SSID) || \
- (pid == SILICOM_PE2G2BPFi35_SSID) || \
- (pid == SILICOM_PE2G2BPFi35LX_SSID) || \
- (pid == SILICOM_PE2G2BPFi35ZX_SSID) || \
- (pid == SILICOM_PE2G4BPFi35_SSID) || \
- (pid == SILICOM_PE2G4BPFi35LX_SSID) || \
- (pid == SILICOM_PE2G4BPFi35ZX_SSID))
-
-#define BP10G9_IF_SERIES(pid) \
- ((pid == INTEL_PE210G2SPI9_SSID) || \
- (pid == SILICOM_M1E10G2BPI9CX4_SSID) || \
- (pid == SILICOM_M1E10G2BPI9SR_SSID) || \
- (pid == SILICOM_M1E10G2BPI9LR_SSID) || \
- (pid == SILICOM_M1E10G2BPI9T_SSID) || \
- (pid == SILICOM_M2E10G2BPI9CX4_SSID) || \
- (pid == SILICOM_M2E10G2BPI9SR_SSID) || \
- (pid == SILICOM_M2E10G2BPI9LR_SSID) || \
- (pid == SILICOM_M2E10G2BPI9T_SSID) || \
- (pid == SILICOM_PE210G2BPI9CX4_SSID) || \
- (pid == SILICOM_PE210G2BPI9SR_SSID) || \
- (pid == SILICOM_PE210G2BPI9LR_SSID) || \
- (pid == SILICOM_PE210G2DBi9SR_SSID) || \
- (pid == SILICOM_PE210G2DBi9SRRB_SSID) || \
- (pid == SILICOM_PE210G2DBi9LR_SSID) || \
- (pid == SILICOM_PE210G2DBi9LRRB_SSID) || \
- (pid == SILICOM_PE310G4DBi940SR_SSID) || \
- (pid == SILICOM_PEG2BISC6_SSID) || \
- (pid == SILICOM_PE310G4BPi9T_SSID) || \
- (pid == SILICOM_PE310G4BPi9SR_SSID) || \
- (pid == SILICOM_PE310G4BPi9LR_SSID) || \
- (pid == SILICOM_PE210G2BPI9T_SSID))
-
-/*******************************************************/
-/* 1G INTERFACE ****************************************/
-/*******************************************************/
-
-/* Intel Registers */
-#define BPCTLI_CTRL 0x00000
-#define BPCTLI_CTRL_SWDPIO0 0x00400000
-#define BPCTLI_CTRL_SWDPIN0 0x00040000
-
-#define BPCTLI_CTRL_EXT 0x00018 /* Extended Device Control - RW */
-#define BPCTLI_STATUS 0x00008 /* Device Status - RO */
-
-/* HW related */
-#define BPCTLI_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW
- * Defineable Pin 6
- */
-#define BPCTLI_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW
- * Defineable Pin 7
- */
-#define BPCTLI_CTRL_SDP0_DATA 0x00040000 /* SWDPIN 0 value */
-#define BPCTLI_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6
- * 0=in 1=out
- */
-#define BPCTLI_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7
- * 0=in 1=out
- */
-#define BPCTLI_CTRL_SDP0_DIR 0x00400000 /* SDP0 Input or output */
-#define BPCTLI_CTRL_SWDPIN1 0x00080000
-#define BPCTLI_CTRL_SDP1_DIR 0x00800000
-
-#define BPCTLI_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
-
-#define BPCTLI_CTRL_SDP0_SHIFT 18
-#define BPCTLI_CTRL_EXT_SDP6_SHIFT 6
-
-#define BPCTLI_STATUS_TBIMODE 0x00000020
-#define BPCTLI_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
-#define BPCTLI_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-
-#define BPCTLI_CTRL_EXT_MCLK_DIR BPCTLI_CTRL_EXT_SDP7_DIR
-#define BPCTLI_CTRL_EXT_MCLK_DATA BPCTLI_CTRL_EXT_SDP7_DATA
-#define BPCTLI_CTRL_EXT_MDIO_DIR BPCTLI_CTRL_EXT_SDP6_DIR
-#define BPCTLI_CTRL_EXT_MDIO_DATA BPCTLI_CTRL_EXT_SDP6_DATA
-
-#define BPCTLI_CTRL_EXT_MCLK_DIR5 BPCTLI_CTRL_SDP1_DIR
-#define BPCTLI_CTRL_EXT_MCLK_DATA5 BPCTLI_CTRL_SWDPIN1
-#define BPCTLI_CTRL_EXT_MCLK_DIR80 BPCTLI_CTRL_EXT_SDP6_DIR
-#define BPCTLI_CTRL_EXT_MCLK_DATA80 BPCTLI_CTRL_EXT_SDP6_DATA
-#define BPCTLI_CTRL_EXT_MDIO_DIR5 BPCTLI_CTRL_SWDPIO0
-#define BPCTLI_CTRL_EXT_MDIO_DATA5 BPCTLI_CTRL_SWDPIN0
-#define BPCTLI_CTRL_EXT_MDIO_DIR80 BPCTLI_CTRL_SWDPIO0
-#define BPCTLI_CTRL_EXT_MDIO_DATA80 BPCTLI_CTRL_SWDPIN0
-
-#define BPCTL_WRITE_REG(a, reg, value) \
- (writel((value), (void *)(((a)->mem_map) + BPCTLI_##reg)))
-
-#define BPCTL_READ_REG(a, reg) ( \
- readl((void *)((a)->mem_map) + BPCTLI_##reg))
-
-#define BPCTL_WRITE_FLUSH(a) BPCTL_READ_REG(a, STATUS)
-
-#define BPCTL_BP_WRITE_REG(a, reg, value) ({ \
- BPCTL_WRITE_REG(a, reg, value); \
- BPCTL_WRITE_FLUSH(a); })
-
-/**************************************************************/
-/************** 82575 Interface********************************/
-/**************************************************************/
-
-#define BPCTLI_MII_CR_POWER_DOWN 0x0800
-#define BPCTLI_PHY_CONTROL 0x00 /* Control Register */
-#define BPCTLI_MDIC 0x00020 /* MDI Control - RW */
-#define BPCTLI_IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
-#define BPCTLI_MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-
-#define BPCTLI_MDIC_DATA_MASK 0x0000FFFF
-#define BPCTLI_MDIC_REG_MASK 0x001F0000
-#define BPCTLI_MDIC_REG_SHIFT 16
-#define BPCTLI_MDIC_PHY_MASK 0x03E00000
-#define BPCTLI_MDIC_PHY_SHIFT 21
-#define BPCTLI_MDIC_OP_WRITE 0x04000000
-#define BPCTLI_MDIC_OP_READ 0x08000000
-#define BPCTLI_MDIC_READY 0x10000000
-#define BPCTLI_MDIC_INT_EN 0x20000000
-#define BPCTLI_MDIC_ERROR 0x40000000
-
-#define BPCTLI_SWFW_PHY0_SM 0x02
-#define BPCTLI_SWFW_PHY1_SM 0x04
-
-#define BPCTLI_SW_FW_SYNC 0x05B5C /* Software-Firmware
- * Synchronization - RW
- */
-
-#define BPCTLI_SWSM 0x05B50 /* SW Semaphore */
-#define BPCTLI_FWSM 0x05B54 /* FW Semaphore */
-
-#define BPCTLI_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-#define BPCTLI_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-#define BPCTLI_MAX_PHY_MULTI_PAGE_REG 0xF
-#define BPCTLI_GEN_POLL_TIMEOUT 640
-
-/********************************************************/
-
-/********************************************************/
-/* 10G INTERFACE ****************************************/
-/********************************************************/
-
-#define BP10G_I2CCTL 0x28
-
-/* I2CCTL Bit Masks */
-#define BP10G_I2C_CLK_IN 0x00000001
-#define BP10G_I2C_CLK_OUT 0x00000002
-#define BP10G_I2C_DATA_IN 0x00000004
-#define BP10G_I2C_DATA_OUT 0x00000008
-
-#define BP10G_ESDP 0x20
-
-#define BP10G_SDP0_DIR 0x100
-#define BP10G_SDP1_DIR 0x200
-#define BP10G_SDP3_DIR 0x800
-#define BP10G_SDP4_DIR BIT_12
-#define BP10G_SDP5_DIR 0x2000
-#define BP10G_SDP0_DATA 0x001
-#define BP10G_SDP1_DATA 0x002
-#define BP10G_SDP3_DATA 0x008
-#define BP10G_SDP4_DATA 0x010
-#define BP10G_SDP5_DATA 0x020
-
-#define BP10G_SDP2_DIR 0x400
-#define BP10G_SDP2_DATA 0x4
-
-#define BP10G_EODSDP 0x28
-
-#define BP10G_SDP6_DATA_IN 0x001
-#define BP10G_SDP6_DATA_OUT 0x002
-
-#define BP10G_SDP7_DATA_IN 0x004
-#define BP10G_SDP7_DATA_OUT 0x008
-
-#define BP10G_MCLK_DATA_OUT BP10G_SDP7_DATA_OUT
-#define BP10G_MDIO_DATA_OUT BP10G_SDP6_DATA_OUT
-#define BP10G_MDIO_DATA_IN BP10G_SDP6_DATA_IN
-
-#define BP10G_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP3_DATA
-#define BP10G_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP3_DATA
-
-/*#define BP10G_MCLK_DATA_OUT9 BP10G_I2C_CLK_OUT
-#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT*/
-
- /*#define BP10G_MCLK_DATA_OUT9*/
- /*BP10G_I2C_DATA_OUT */
-#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT /*BP10G_I2C_CLK_OUT */
-
-/* VIA EOSDP ! */
-#define BP10G_MCLK_DATA_OUT9 BP10G_SDP4_DATA
-#define BP10G_MCLK_DIR_OUT9 BP10G_SDP4_DIR
-
-/*#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN*/
-
-#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN /*BP10G_I2C_CLK_IN */
-
-#define BP540_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP0_DATA
-#define BP540_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP0_DIR
-#define BP540_MCLK_DATA BP10G_SDP2_DATA
-#define BP540_MCLK_DIR BP10G_SDP2_DIR
-
-#define BP10G_WRITE_REG(a, reg, value) \
- (writel((value), (void *)(((a)->mem_map) + BP10G_##reg)))
-
-#define BP10G_READ_REG(a, reg) ( \
- readl((void *)((a)->mem_map) + BP10G_##reg))
-
-/*****BROADCOM*******************************************/
-
-#define BP10GB_MISC_REG_GPIO 0xa490
-#define BP10GB_GPIO3_P0 BIT_3
-#define BP10GB_GPIO3_P1 BIT_7
-
-#define BP10GB_GPIO3_SET_P0 BIT_11
-#define BP10GB_GPIO3_CLR_P0 BIT_19
-#define BP10GB_GPIO3_OE_P0 BIT_27
-
-#define BP10GB_GPIO3_SET_P1 BIT_15
-#define BP10GB_GPIO3_CLR_P1 BIT_23
-#define BP10GB_GPIO3_OE_P1 BIT_31
-
-#define BP10GB_GPIO0_P1 0x10
-#define BP10GB_GPIO0_P0 0x1
-#define BP10GB_GPIO0_CLR_P0 0x10000
-#define BP10GB_GPIO0_CLR_P1 0x100000
-#define BP10GB_GPIO0_SET_P0 0x100
-#define BP10GB_GPIO0_SET_P1 0x1000
-
-#define BP10GB_GPIO0_OE_P1 0x10000000
-#define BP10GB_GPIO0_OE_P0 0x1000000
-
-#define BP10GB_MISC_REG_SPIO 0xa4fc
-#define BP10GB_GPIO4_OE BIT_28
-#define BP10GB_GPIO5_OE BIT_29
-#define BP10GB_GPIO4_CLR BIT_20
-#define BP10GB_GPIO5_CLR BIT_21
-#define BP10GB_GPIO4_SET BIT_12
-#define BP10GB_GPIO5_SET BIT_13
-#define BP10GB_GPIO4 BIT_4
-#define BP10GB_GPIO5 BIT_5
-
-#define BP10GB_MCLK_DIR BP10GB_GPIO5_OE
-#define BP10GB_MDIO_DIR BP10GB_GPIO4_OE
-
-#define BP10GB_MCLK_DATA BP10GB_GPIO5
-#define BP10GB_MDIO_DATA BP10GB_GPIO4
-
-#define BP10GB_MCLK_SET BP10GB_GPIO5_SET
-#define BP10GB_MDIO_SET BP10GB_GPIO4_SET
-
-#define BP10GB_MCLK_CLR BP10GB_GPIO5_CLR
-#define BP10GB_MDIO_CLR BP10GB_GPIO4_CLR
-
-#define BP10GB_WRITE_REG(a, reg, value) \
- (writel((value), (void *)(((a)->mem_map) + BP10GB_##reg)))
-
-#define BP10GB_READ_REG(a, reg) ( \
- readl((void *)((a)->mem_map) + BP10GB_##reg))
-
-#endif
diff --git a/drivers/staging/silicom/bpctl_mod.c b/drivers/staging/silicom/bpctl_mod.c
deleted file mode 100644
index 765fce84d9dd..000000000000
--- a/drivers/staging/silicom/bpctl_mod.c
+++ /dev/null
@@ -1,7530 +0,0 @@
-/******************************************************************************/
-/* */
-/* Bypass Control utility, Copyright (c) 2005-2011 Silicom */
-/* */
-/* 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, located in the file LICENSE. */
-/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved. */
-/* */
-/* */
-/******************************************************************************/
-
-#include <linux/kernel.h> /* We're doing kernel work */
-#include <linux/module.h> /* Specifically, a module */
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/rcupdate.h>
-#include <linux/etherdevice.h>
-
-#include <linux/uaccess.h> /* for get_user and put_user */
-#include <linux/sched.h>
-#include <linux/ethtool.h>
-#include <linux/proc_fs.h>
-
-#include "bp_ioctl.h"
-#include "bp_mod.h"
-#include "bypass.h"
-#include "libbp_sd.h"
-
-#define SUCCESS 0
-#define BP_MOD_VER "9.0.4"
-#define BP_MOD_DESCR "Silicom Bypass-SD Control driver"
-#define BP_SYNC_FLAG 1
-
-static int major_num;
-
-MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(BP_MOD_DESCR);
-MODULE_VERSION(BP_MOD_VER);
-static spinlock_t bpvm_lock;
-
-#define unlock_bpctl() \
- up(&bpctl_sema);
-
-/* Media Types */
-enum bp_media_type {
- BP_COPPER = 0,
- BP_FIBER,
- BP_CX4,
- BP_NONE,
-};
-
-struct bypass_pfs_sd {
- char dir_name[32];
- struct proc_dir_entry *bypass_entry;
-};
-
-struct bpctl_dev {
- char *name;
- char *desc;
- struct pci_dev *pdev; /* PCI device */
- struct net_device *ndev; /* net device */
- unsigned long mem_map;
- uint8_t bus;
- uint8_t slot;
- uint8_t func;
- u_int32_t device;
- u_int32_t vendor;
- u_int32_t subvendor;
- u_int32_t subdevice;
- int ifindex;
- uint32_t bp_caps;
- uint32_t bp_caps_ex;
- uint8_t bp_fw_ver;
- int bp_ext_ver;
- int wdt_status;
- unsigned long bypass_wdt_on_time;
- uint32_t bypass_timer_interval;
- struct timer_list bp_timer;
- uint32_t reset_time;
- uint8_t bp_status_un;
- atomic_t wdt_busy;
- enum bp_media_type media_type;
- int bp_tpl_flag;
- struct timer_list bp_tpl_timer;
- spinlock_t bypass_wr_lock;
- int bp_10g;
- int bp_10gb;
- int bp_fiber5;
- int bp_10g9;
- int bp_i80;
- int bp_540;
- int (*hard_start_xmit_save) (struct sk_buff *skb,
- struct net_device *dev);
- const struct net_device_ops *old_ops;
- struct net_device_ops new_ops;
- int bp_self_test_flag;
- char *bp_tx_data;
- struct bypass_pfs_sd bypass_pfs_set;
-
-};
-
-static struct bpctl_dev *bpctl_dev_arr;
-
-static struct semaphore bpctl_sema;
-static int device_num;
-
-static int get_dev_idx(int ifindex);
-static struct bpctl_dev *get_master_port_fn(struct bpctl_dev *pbpctl_dev);
-static int disc_status(struct bpctl_dev *pbpctl_dev);
-static int bypass_status(struct bpctl_dev *pbpctl_dev);
-static int wdt_timer(struct bpctl_dev *pbpctl_dev, int *time_left);
-static struct bpctl_dev *get_status_port_fn(struct bpctl_dev *pbpctl_dev);
-static void if_scan_init(void);
-
-static int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block);
-static int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block);
-
-static int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
-static int get_dev_idx_bsf(int bus, int slot, int func);
-
-static int bp_get_dev_idx_bsf(struct net_device *dev, int *index)
-{
- struct ethtool_drvinfo drvinfo = {0};
- char *buf;
- int bus, slot, func;
-
- if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
- dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
- else
- return -EOPNOTSUPP;
-
- if (!strcmp(drvinfo.bus_info, "N/A"))
- return -ENODATA;
-
- buf = strchr(drvinfo.bus_info, ':');
- if (!buf)
- return -EINVAL;
- buf++;
- if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
- return -EINVAL;
-
- *index = get_dev_idx_bsf(bus, slot, func);
- return 0;
-}
-
-static int bp_device_event(struct notifier_block *unused,
- unsigned long event, void *ptr)
-{
- struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m;
- int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
-
- /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
- /* return NOTIFY_DONE; */
- if (!dev)
- return NOTIFY_DONE;
-
- if (event == NETDEV_REGISTER) {
- int idx_dev;
-
- if (bp_get_dev_idx_bsf(dev, &idx_dev))
- return NOTIFY_DONE;
-
- if (idx_dev == -1)
- return NOTIFY_DONE;
-
- bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
- bpctl_dev_arr[idx_dev].ndev = dev;
-
- bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]);
- bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]);
- return NOTIFY_DONE;
- }
- if (event == NETDEV_UNREGISTER) {
- int idx_dev = 0;
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL)
- && (idx_dev < device_num)); idx_dev++) {
- if (bpctl_dev_arr[idx_dev].ndev == dev) {
- bypass_proc_remove_dev_sd(&bpctl_dev_arr
- [idx_dev]);
- bpctl_dev_arr[idx_dev].ndev = NULL;
-
- return NOTIFY_DONE;
-
- }
-
- }
- return NOTIFY_DONE;
- }
- if (event == NETDEV_CHANGENAME) {
- int idx_dev = 0;
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL)
- && (idx_dev < device_num)); idx_dev++) {
- if (bpctl_dev_arr[idx_dev].ndev == dev) {
- bypass_proc_remove_dev_sd(&bpctl_dev_arr
- [idx_dev]);
- bypass_proc_create_dev_sd(&bpctl_dev_arr
- [idx_dev]);
-
- return NOTIFY_DONE;
-
- }
-
- }
- return NOTIFY_DONE;
-
- }
-
- switch (event) {
-
- case NETDEV_CHANGE:{
- if (netif_carrier_ok(dev))
- return NOTIFY_DONE;
-
- dev_num = get_dev_idx(dev->ifindex);
- if (dev_num == -1)
- return NOTIFY_DONE;
-
- pbpctl_dev = &bpctl_dev_arr[dev_num];
- if (!pbpctl_dev)
- return NOTIFY_DONE;
-
- if ((is_bypass_fn(pbpctl_dev)) == 1)
- pbpctl_dev_m = pbpctl_dev;
- else
- pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
- if (!pbpctl_dev_m)
- return NOTIFY_DONE;
- ret = bypass_status(pbpctl_dev_m);
- if (ret == 1)
- printk("bpmod: %s is in the Bypass mode now",
- dev->name);
- ret_d = disc_status(pbpctl_dev_m);
- if (ret_d == 1)
- printk
- ("bpmod: %s is in the Disconnect mode now",
- dev->name);
- if (ret || ret_d) {
- wdt_timer(pbpctl_dev_m, &time_left);
- if (time_left == -1)
- printk("; WDT has expired");
- printk(".\n");
-
- }
- return NOTIFY_DONE;
-
- }
-
- default:
- return NOTIFY_DONE;
-
- }
- return NOTIFY_DONE;
-
-}
-
-static struct notifier_block bp_notifier_block = {
- .notifier_call = bp_device_event,
-};
-
-static int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
-int wdt_time_left(struct bpctl_dev *pbpctl_dev);
-
-static void write_pulse(struct bpctl_dev *pbpctl_dev,
- unsigned int ctrl_ext,
- unsigned char value, unsigned char len)
-{
- unsigned char ctrl_val = 0;
- unsigned int i = len;
- unsigned int ctrl = 0;
- struct bpctl_dev *pbpctl_dev_c = NULL;
-
- if (pbpctl_dev->bp_i80)
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- if (pbpctl_dev->bp_540)
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
-
- if (pbpctl_dev->bp_10g9) {
- pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_c)
- return;
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
- }
-
- while (i--) {
- ctrl_val = (value >> i) & 0x1;
- if (ctrl_val) {
- if (pbpctl_dev->bp_10g9) {
-
- /* To start management : MCLK 1, MDIO 1, output */
- /* DATA 1 CLK 1 */
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- ctrl_ext |
- BP10G_MDIO_DATA_OUT9);
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DATA_OUT9 |
- BP10G_MCLK_DIR_OUT9));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80
- |
- BPCTLI_CTRL_EXT_MDIO_DATA80));
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (ctrl |
- BPCTLI_CTRL_EXT_MCLK_DIR80
- |
- BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |
- BP540_MDIO_DIR
- |
- BP540_MDIO_DATA
- |
- BP540_MCLK_DIR
- |
- BP540_MCLK_DATA));
-
- } else if (pbpctl_dev->bp_10gb) {
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_SET |
- BP10GB_MCLK_SET) &
- ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_DIR |
- BP10GB_MDIO_CLR |
- BP10GB_MCLK_CLR));
-
- } else if (!pbpctl_dev->bp_10g)
- /* To start management : MCLK 1, MDIO 1, output */
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR |
- BPCTLI_CTRL_EXT_MDIO_DIR |
- BPCTLI_CTRL_EXT_MDIO_DATA |
- BPCTLI_CTRL_EXT_MCLK_DATA));
- else {
-
- /* To start management : MCLK 1, MDIO 1, output*/
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext | BP10G_MCLK_DATA_OUT
- | BP10G_MDIO_DATA_OUT));
-
- }
-
- usec_delay(PULSE_TIME);
- if (pbpctl_dev->bp_10g9) {
-
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~(BP10G_MCLK_DATA_OUT9))); */
- /* DATA 1 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- ctrl_ext |
- BP10G_MDIO_DATA_OUT9);
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DIR_OUT9) &
- ~BP10G_MCLK_DATA_OUT9);
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5 |
- BPCTLI_CTRL_EXT_MDIO_DIR5 |
- BPCTLI_CTRL_EXT_MDIO_DATA5)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80
- |
- BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl |
- BPCTLI_CTRL_EXT_MCLK_DIR80)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA80)));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (ctrl | BP540_MDIO_DIR |
- BP540_MDIO_DATA |
- BP540_MCLK_DIR) &
- ~(BP540_MCLK_DATA));
-
- } else if (pbpctl_dev->bp_10gb) {
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_SET |
- BP10GB_MCLK_CLR) &
- ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_DIR |
- BP10GB_MDIO_CLR |
- BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g)
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR |
- BPCTLI_CTRL_EXT_MDIO_DIR |
- BPCTLI_CTRL_EXT_MDIO_DATA)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- ((ctrl_ext |
- BP10G_MDIO_DATA_OUT) &
- ~(BP10G_MCLK_DATA_OUT)));
- }
-
- usec_delay(PULSE_TIME);
-
- } else {
- if (pbpctl_dev->bp_10g9) {
- /* DATA 0 CLK 1 */
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext &
- ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DATA_OUT9 |
- BP10G_MCLK_DIR_OUT9));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5 |
- BPCTLI_CTRL_EXT_MDIO_DIR5 |
- BPCTLI_CTRL_EXT_MCLK_DATA5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA80)));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl |
- BPCTLI_CTRL_EXT_MCLK_DIR80 |
- BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP540_MCLK_DIR |
- BP540_MCLK_DATA |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR |
- BP10GB_MCLK_SET) &
- ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET |
- BP10GB_MCLK_CLR));
-
- } else if (!pbpctl_dev->bp_10g)
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR |
- BPCTLI_CTRL_EXT_MDIO_DIR |
- BPCTLI_CTRL_EXT_MCLK_DATA)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- ((ctrl_ext |
- BP10G_MCLK_DATA_OUT) &
- ~BP10G_MDIO_DATA_OUT));
-
- }
- usec_delay(PULSE_TIME);
- if (pbpctl_dev->bp_10g9) {
- /* DATA 0 CLK 0 */
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext &
- ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5 |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~(BPCTLI_CTRL_EXT_MCLK_DATA5
- |
- BPCTLI_CTRL_EXT_MDIO_DATA5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl |
- BPCTLI_CTRL_EXT_MCLK_DIR80)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA80)));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP540_MCLK_DIR |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
- } else if (pbpctl_dev->bp_10gb) {
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR |
- BP10GB_MCLK_CLR) &
- ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET |
- BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR |
- BPCTLI_CTRL_EXT_MDIO_DIR) &
- ~(BPCTLI_CTRL_EXT_MCLK_DATA
- |
- BPCTLI_CTRL_EXT_MDIO_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT |
- BP10G_MDIO_DATA_OUT)));
- }
-
- usec_delay(PULSE_TIME);
- }
-
- }
-}
-
-static int read_pulse(struct bpctl_dev *pbpctl_dev, unsigned int ctrl_ext,
- unsigned char len)
-{
- unsigned char ctrl_val = 0;
- unsigned int i = len;
- unsigned int ctrl = 0;
- struct bpctl_dev *pbpctl_dev_c = NULL;
-
- if (pbpctl_dev->bp_i80)
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- if (pbpctl_dev->bp_540)
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- if (pbpctl_dev->bp_10g9) {
- pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_c)
- return -1;
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
- }
-
-
- while (i--) {
- if (pbpctl_dev->bp_10g9) {
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~BP10G_MCLK_DATA_OUT9)); */
- /* DATA ? CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl_ext &
- ~BPCTLI_CTRL_EXT_MDIO_DIR80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80)
- & ~(BPCTLI_CTRL_EXT_MCLK_DATA80)));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP540_MCLK_DIR) &
- ~(BP540_MDIO_DIR | BP540_MCLK_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_DIR |
- BP10GB_MCLK_CLR) & ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_CLR |
- BP10GB_MDIO_SET |
- BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */
- /* printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */
-
- }
-
- usec_delay(PULSE_TIME);
- if (pbpctl_dev->bp_10g9) {
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
- /* DATA ? CLK 1 */
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DATA_OUT9 |
- BP10G_MCLK_DIR_OUT9));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl_ext &
- ~(BPCTLI_CTRL_EXT_MDIO_DIR80)));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
- BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP540_MCLK_DIR |
- BP540_MCLK_DATA) &
- ~(BP540_MDIO_DIR)));
-
- } else if (pbpctl_dev->bp_10gb) {
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_DIR |
- BP10GB_MCLK_SET) & ~(BP10GB_MCLK_DIR |
- BP10GB_MDIO_CLR |
- BP10GB_MDIO_SET |
- BP10GB_MCLK_CLR));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext | BP10G_MCLK_DATA_OUT |
- BP10G_MDIO_DATA_OUT));
-
- }
-
- if (pbpctl_dev->bp_10g9)
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
- else if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_i80))
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- else if (pbpctl_dev->bp_540)
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
- else if (pbpctl_dev->bp_10gb)
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
- else if (!pbpctl_dev->bp_10g)
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- else
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
-
- usec_delay(PULSE_TIME);
- if (pbpctl_dev->bp_10g9) {
- if (ctrl_ext & BP10G_MDIO_DATA_IN9)
- ctrl_val |= 1 << i;
-
- } else if (pbpctl_dev->bp_fiber5) {
- if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA5)
- ctrl_val |= 1 << i;
- } else if (pbpctl_dev->bp_i80) {
- if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA80)
- ctrl_val |= 1 << i;
- } else if (pbpctl_dev->bp_540) {
- if (ctrl_ext & BP540_MDIO_DATA)
- ctrl_val |= 1 << i;
- } else if (pbpctl_dev->bp_10gb) {
- if (ctrl_ext & BP10GB_MDIO_DATA)
- ctrl_val |= 1 << i;
-
- } else if (!pbpctl_dev->bp_10g) {
-
- if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA)
- ctrl_val |= 1 << i;
- } else {
-
- if (ctrl_ext & BP10G_MDIO_DATA_IN)
- ctrl_val |= 1 << i;
- }
-
- }
-
- return ctrl_val;
-}
-
-static void write_reg(struct bpctl_dev *pbpctl_dev, unsigned char value,
- unsigned char addr)
-{
- uint32_t ctrl_ext = 0, ctrl = 0;
- struct bpctl_dev *pbpctl_dev_c = NULL;
- unsigned long flags;
-
- if (pbpctl_dev->bp_10g9) {
- pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_c)
- return;
- }
- if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
- (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER))
- wdt_time_left(pbpctl_dev);
-
-#ifdef BP_SYNC_FLAG
- spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 1);
-#endif
- if (pbpctl_dev->bp_10g9) {
-
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
- /* DATA 0 CLK 0 */
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- ctrl = ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
- BP540_MDIO_DIR |
- BP540_MCLK_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g) {
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- } else {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
- }
- usec_delay(CMND_INTERVAL);
-
- /*send sync cmd */
- write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
- /*send wr cmd */
- write_pulse(pbpctl_dev, ctrl_ext, WR_CMD_VAL, WR_CMD_LEN);
- write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
-
- /*write data */
- write_pulse(pbpctl_dev, ctrl_ext, value, WR_DATA_LEN);
- if (pbpctl_dev->bp_10g9) {
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- /* DATA 0 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
- BP540_MDIO_DIR |
- BP540_MCLK_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
- } else if (pbpctl_dev->bp_10gb) {
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g)
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- else {
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-
- }
-
- usec_delay(CMND_INTERVAL * 4);
-
- if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
- (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER) && (addr == CMND_REG_ADDR))
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 0);
-#endif
-
-}
-
-static void write_data(struct bpctl_dev *pbpctl_dev, unsigned char value)
-{
- write_reg(pbpctl_dev, value, CMND_REG_ADDR);
-}
-
-static int read_reg(struct bpctl_dev *pbpctl_dev, unsigned char addr)
-{
- uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0;
- struct bpctl_dev *pbpctl_dev_c = NULL;
-
-#ifdef BP_SYNC_FLAG
- unsigned long flags;
-
- spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 1);
-#endif
- if (pbpctl_dev->bp_10g9) {
- pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_c)
- return -1;
- }
-
- if (pbpctl_dev->bp_10g9) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
-
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- /* DATA 0 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
- } else if (pbpctl_dev->bp_540) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
-
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-#if 0
-
- /*BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, (ctrl_ext | BP10GB_MCLK_DIR | BP10GB_MDIO_DIR|
- BP10GB_MCLK_CLR|BP10GB_MDIO_CLR));
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
- printk("1reg=%x\n", ctrl_ext); */
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, ((ctrl_ext |
- BP10GB_MCLK_SET |
- BP10GB_MDIO_CLR))
- & ~(BP10GB_MCLK_CLR | BP10GB_MDIO_SET |
- BP10GB_MCLK_DIR | BP10GB_MDIO_DIR));
-
- /* bnx2x_set_spio(pbpctl_dev, 5, MISC_REGISTERS_SPIO_OUTPUT_LOW);
- bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_OUTPUT_LOW);
- bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_INPUT_HI_Z); */
-
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
-
- printk("2reg=%x\n", ctrl_ext);
-
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 0);
-#endif
-
- return 0;
-
-#endif
-
- } else if (!pbpctl_dev->bp_10g) {
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- } else {
-
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-
- }
-
- usec_delay(CMND_INTERVAL);
-
- /*send sync cmd */
- write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
- /*send rd cmd */
- write_pulse(pbpctl_dev, ctrl_ext, RD_CMD_VAL, RD_CMD_LEN);
- /*send addr */
- write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
- /*read data */
- /* zero */
- if (pbpctl_dev->bp_10g9) {
- /* DATA 0 CLK 1 */
- /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext | BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DATA_OUT9 |
- BP10G_MCLK_DIR_OUT9));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DATA5)));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl_ext &
- ~(BPCTLI_CTRL_EXT_MDIO_DATA80 |
- BPCTLI_CTRL_EXT_MDIO_DIR80)));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
- BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (((ctrl | BP540_MDIO_DIR | BP540_MCLK_DIR |
- BP540_MCLK_DATA) & ~BP540_MDIO_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_DIR | BP10GB_MCLK_SET)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_SET |
- BP10GB_MDIO_CLR | BP10GB_MCLK_CLR));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext | BP10G_MCLK_DATA_OUT |
- BP10G_MDIO_DATA_OUT));
-
-
- }
- usec_delay(PULSE_TIME);
-
- ctrl_value = read_pulse(pbpctl_dev, ctrl_ext, RD_DATA_LEN);
-
- if (pbpctl_dev->bp_10g9) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
-
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- /* DATA 0 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- } else {
-
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-
- }
-
- usec_delay(CMND_INTERVAL * 4);
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 0);
-#endif
-
- return ctrl_value;
-}
-
-static int wdt_pulse(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0, ctrl = 0;
- struct bpctl_dev *pbpctl_dev_c = NULL;
-
-#ifdef BP_SYNC_FLAG
- unsigned long flags;
-
- spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
-#else
-
- if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
- return -1;
-#endif
- if (pbpctl_dev->bp_10g9) {
- pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_c)
- return -1;
- }
-
- if (pbpctl_dev->bp_10g9) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
- ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
-
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- /* DATA 0 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
- } else if (pbpctl_dev->bp_540) {
- ctrl_ext = ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g) {
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)));
- } else {
-
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-
- }
- if (pbpctl_dev->bp_10g9) {
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */
- /* DATA 0 CLK 1 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- (ctrl | BP10G_MCLK_DATA_OUT9 |
- BP10G_MCLK_DIR_OUT9));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5
- |
- BPCTLI_CTRL_EXT_MCLK_DATA5)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
- BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
- BP540_MDIO_DIR |
- BP540_MCLK_DIR |
- BP540_MCLK_DATA) &
- ~BP540_MDIO_DATA));
-
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
-
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_SET)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_CLR));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR
- |
- BPCTLI_CTRL_EXT_MCLK_DATA)
- &
- ~
- (BPCTLI_CTRL_EXT_MDIO_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- ((ctrl_ext | BP10G_MCLK_DATA_OUT) &
- ~BP10G_MDIO_DATA_OUT));
-
- }
-
- usec_delay(WDT_INTERVAL);
- if (pbpctl_dev->bp_10g9) {
- /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
- /* DATA 0 CLK 0 */
- BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
- (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
- BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
- ((ctrl | BP10G_MCLK_DIR_OUT9) &
- ~(BP10G_MCLK_DATA_OUT9)));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR5
- |
- BPCTLI_CTRL_EXT_MDIO_DIR5)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA5
- |
- BPCTLI_CTRL_EXT_MDIO_DATA5)));
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MDIO_DIR80)
- &
- ~BPCTLI_CTRL_EXT_MDIO_DATA80));
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
- ~BPCTLI_CTRL_EXT_MCLK_DATA80));
-
- } else if (pbpctl_dev->bp_540) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
- BP540_MDIO_DIR) &
- ~(BP540_MDIO_DATA |
- BP540_MCLK_DATA)));
-
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
- (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
- & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
- BP10GB_MDIO_SET | BP10GB_MCLK_SET));
-
- } else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA
- |
- BPCTLI_CTRL_EXT_MDIO_DATA)));
- else {
-
- BP10G_WRITE_REG(pbpctl_dev, EODSDP,
- (ctrl_ext &
- ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
- }
- if ((pbpctl_dev->wdt_status == WDT_STATUS_EN))
- /*&& (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#endif
- usec_delay(CMND_INTERVAL * 4);
- return 0;
-}
-
-static void data_pulse(struct bpctl_dev *pbpctl_dev, unsigned char value)
-{
-
- uint32_t ctrl_ext = 0;
-#ifdef BP_SYNC_FLAG
- unsigned long flags;
-#endif
- wdt_time_left(pbpctl_dev);
-#ifdef BP_SYNC_FLAG
- spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 1);
-#endif
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP7_DIR) &
- ~(BPCTLI_CTRL_EXT_SDP6_DATA |
- BPCTLI_CTRL_EXT_SDP7_DATA)));
-
- usec_delay(INIT_CMND_INTERVAL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP7_DIR |
- BPCTLI_CTRL_EXT_SDP6_DATA) &
- ~
- (BPCTLI_CTRL_EXT_SDP7_DATA)));
- usec_delay(INIT_CMND_INTERVAL);
-
- while (value) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP7_DIR |
- BPCTLI_CTRL_EXT_SDP6_DATA |
- BPCTLI_CTRL_EXT_SDP7_DATA);
- usec_delay(PULSE_INTERVAL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR
- |
- BPCTLI_CTRL_EXT_SDP7_DIR
- |
- BPCTLI_CTRL_EXT_SDP6_DATA)
- &
- ~BPCTLI_CTRL_EXT_SDP7_DATA));
- usec_delay(PULSE_INTERVAL);
- value--;
-
- }
- usec_delay(INIT_CMND_INTERVAL - PULSE_INTERVAL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP7_DIR) &
- ~(BPCTLI_CTRL_EXT_SDP6_DATA |
- BPCTLI_CTRL_EXT_SDP7_DATA)));
- usec_delay(WDT_TIME_CNT);
- if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#else
- atomic_set(&pbpctl_dev->wdt_busy, 0);
-#endif
-
-}
-
-static int send_wdt_pulse(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
-#ifdef BP_SYNC_FLAG
- unsigned long flags;
-
- spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
-#else
-
- if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
- return -1;
-#endif
- wdt_time_left(pbpctl_dev);
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */
- BPCTLI_CTRL_EXT_SDP7_DIR |
- BPCTLI_CTRL_EXT_SDP7_DATA);
- usec_delay(PULSE_INTERVAL);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */
- BPCTLI_CTRL_EXT_SDP7_DIR) &
- ~BPCTLI_CTRL_EXT_SDP7_DATA));
-
- usec_delay(PULSE_INTERVAL);
- if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-#ifdef BP_SYNC_FLAG
- spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
-#endif
-
- return 0;
-}
-
-static void send_bypass_clear_pulse(struct bpctl_dev *pbpctl_dev,
- unsigned int value)
-{
- uint32_t ctrl_ext = 0;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */
- BPCTLI_CTRL_EXT_SDP6_DIR) &
- ~BPCTLI_CTRL_EXT_SDP6_DATA));
-
- usec_delay(PULSE_INTERVAL);
- while (value) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP6_DATA);
- usec_delay(PULSE_INTERVAL);
- value--;
- }
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */
- BPCTLI_CTRL_EXT_SDP6_DIR) &
- ~BPCTLI_CTRL_EXT_SDP6_DATA));
- usec_delay(PULSE_INTERVAL);
-}
-
-/* #endif OLD_FW */
-#ifdef BYPASS_DEBUG
-
-int pulse_set_fn(struct bpctl_dev *pbpctl_dev, unsigned int counter)
-{
- uint32_t ctrl_ext = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
-
- pbpctl_dev->bypass_wdt_status = 0;
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
- } else {
- wdt_time_left(pbpctl_dev);
- if (pbpctl_dev->wdt_status == WDT_STATUS_EN) {
- pbpctl_dev->wdt_status = 0;
- data_pulse(pbpctl_dev, counter);
- pbpctl_dev->wdt_status = WDT_STATUS_EN;
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-
- } else
- data_pulse(pbpctl_dev, counter);
- }
-
- return 0;
-}
-
-int zero_set_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- printk("zero_set");
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
-
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_MCLK_DIR)
- &
- ~
- (BPCTLI_CTRL_EXT_MCLK_DATA
- |
- BPCTLI_CTRL_EXT_MDIO_DIR
- |
- BPCTLI_CTRL_EXT_MDIO_DATA)));
-
- }
- return 0;
-}
-
-int pulse_get2_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0, ctrl_value = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- printk("pulse_get_fn\n");
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- ctrl_value = read_pulse_2(pbpctl_dev, ctrl_ext);
- printk("read:%d\n", ctrl_value);
- }
- return ctrl_value;
-}
-
-int pulse_get1_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0, ctrl_value = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
-
- printk("pulse_get_fn\n");
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- ctrl_value = read_pulse_1(pbpctl_dev, ctrl_ext);
- printk("read:%d\n", ctrl_value);
- }
- return ctrl_value;
-}
-
-int gpio6_set_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP6_DATA);
- return 0;
-}
-
-int gpio7_set_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
- BPCTLI_CTRL_EXT_SDP7_DIR |
- BPCTLI_CTRL_EXT_SDP7_DATA);
- return 0;
-}
-
-int gpio7_clear_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP7_DIR) &
- ~BPCTLI_CTRL_EXT_SDP7_DATA));
- return 0;
-}
-
-int gpio6_clear_fn(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
- BPCTLI_CTRL_EXT_SDP6_DIR) &
- ~BPCTLI_CTRL_EXT_SDP6_DATA));
- return 0;
-}
-#endif /*BYPASS_DEBUG */
-
-static struct bpctl_dev *lookup_port(struct bpctl_dev *dev)
-{
- struct bpctl_dev *p;
- int n;
-
- for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) {
- if (p->bus == dev->bus
- && p->slot == dev->slot
- && p->func == (dev->func ^ 1))
- return p;
- }
- return NULL;
-}
-
-static struct bpctl_dev *get_status_port_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev) {
- if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2)
- return lookup_port(pbpctl_dev);
- }
- return NULL;
-}
-
-static struct bpctl_dev *get_master_port_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev) {
- if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3)
- return lookup_port(pbpctl_dev);
- }
- return NULL;
-}
-
-/**************************************/
-/**************INTEL API***************/
-/**************************************/
-
-static void write_data_port_int(struct bpctl_dev *pbpctl_dev,
- unsigned char ctrl_value)
-{
- uint32_t value;
-
- value = BPCTL_READ_REG(pbpctl_dev, CTRL);
-/* Make SDP0 Pin Directonality to Output */
- value |= BPCTLI_CTRL_SDP0_DIR;
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value);
-
- value &= ~BPCTLI_CTRL_SDP0_DATA;
- value |= ((ctrl_value & 0x1) << BPCTLI_CTRL_SDP0_SHIFT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value);
-
- value = (BPCTL_READ_REG(pbpctl_dev, CTRL_EXT));
-/* Make SDP2 Pin Directonality to Output */
- value |= BPCTLI_CTRL_EXT_SDP6_DIR;
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
-
- value &= ~BPCTLI_CTRL_EXT_SDP6_DATA;
- value |= (((ctrl_value & 0x2) >> 1) << BPCTLI_CTRL_EXT_SDP6_SHIFT);
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
-
-}
-
-static int write_data_int(struct bpctl_dev *pbpctl_dev, unsigned char value)
-{
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return -1;
- atomic_set(&pbpctl_dev->wdt_busy, 1);
- write_data_port_int(pbpctl_dev, value & 0x3);
- write_data_port_int(pbpctl_dev_b, ((value & 0xc) >> 2));
- atomic_set(&pbpctl_dev->wdt_busy, 0);
-
- return 0;
-}
-
-static int wdt_pulse_int(struct bpctl_dev *pbpctl_dev)
-{
-
- if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
- return -1;
-
- if ((write_data_int(pbpctl_dev, RESET_WDT_INT)) < 0)
- return -1;
- msec_delay_bp(CMND_INTERVAL_INT);
- if ((write_data_int(pbpctl_dev, CMND_OFF_INT)) < 0)
- return -1;
- msec_delay_bp(CMND_INTERVAL_INT);
-
- if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
- pbpctl_dev->bypass_wdt_on_time = jiffies;
-
- return 0;
-}
-
-/*************************************/
-/************* COMMANDS **************/
-/*************************************/
-
-/* CMND_ON 0x4 (100)*/
-static int cmnd_on(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- return 0;
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
- write_data(pbpctl_dev, CMND_ON);
- else
- data_pulse(pbpctl_dev, CMND_ON);
- ret = 0;
- }
- return ret;
-}
-
-/* CMND_OFF 0x2 (10)*/
-static int cmnd_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, CMND_OFF_INT);
- msec_delay_bp(CMND_INTERVAL_INT);
- } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
- write_data(pbpctl_dev, CMND_OFF);
- else
- data_pulse(pbpctl_dev, CMND_OFF);
- ret = 0;
- }
- return ret;
-}
-
-/* BYPASS_ON (0xa)*/
-static int bypass_on(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & BP_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, BYPASS_ON_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- pbpctl_dev->bp_status_un = 0;
- } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- write_data(pbpctl_dev, BYPASS_ON);
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
- msec_delay_bp(LATCH_DELAY);
- } else
- data_pulse(pbpctl_dev, BYPASS_ON);
- ret = 0;
- }
- return ret;
-}
-
-/* BYPASS_OFF (0x8 111)*/
-static int bypass_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & BP_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- pbpctl_dev->bp_status_un = 0;
- } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- write_data(pbpctl_dev, BYPASS_OFF);
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
- msec_delay_bp(LATCH_DELAY);
- } else
- data_pulse(pbpctl_dev, BYPASS_OFF);
- ret = 0;
- }
- return ret;
-}
-
-/* TAP_OFF (0x9)*/
-static int tap_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if ((pbpctl_dev->bp_caps & TAP_CAP)
- && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
- write_data(pbpctl_dev, TAP_OFF);
- msec_delay_bp(LATCH_DELAY);
- ret = 0;
- }
- return ret;
-}
-
-/* TAP_ON (0xb)*/
-static int tap_on(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if ((pbpctl_dev->bp_caps & TAP_CAP)
- && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
- write_data(pbpctl_dev, TAP_ON);
- msec_delay_bp(LATCH_DELAY);
- ret = 0;
- }
- return ret;
-}
-
-/* DISC_OFF (0x9)*/
-static int disc_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
- write_data(pbpctl_dev, DISC_OFF);
- msec_delay_bp(LATCH_DELAY);
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-/* DISC_ON (0xb)*/
-static int disc_on(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
- write_data(pbpctl_dev, /*DISC_ON */ 0x85);
- msec_delay_bp(LATCH_DELAY);
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-/*TWO_PORT_LINK_HW_EN (0xe)*/
-static int tpl_hw_on(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0, ctrl = 0;
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
- cmnd_on(pbpctl_dev);
- write_data(pbpctl_dev, TPL2_ON);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- cmnd_off(pbpctl_dev);
- return ret;
- }
-
- if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
- ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
- BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
- ((ctrl | BPCTLI_CTRL_SWDPIO0) &
- ~BPCTLI_CTRL_SWDPIN0));
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-/*TWO_PORT_LINK_HW_DIS (0xc)*/
-static int tpl_hw_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0, ctrl = 0;
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
- if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
- cmnd_on(pbpctl_dev);
- write_data(pbpctl_dev, TPL2_OFF);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- cmnd_off(pbpctl_dev);
- return ret;
- }
- if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
- ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
- BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
- (ctrl | BPCTLI_CTRL_SWDPIO0 |
- BPCTLI_CTRL_SWDPIN0));
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-/* WDT_OFF (0x6 110)*/
-static int wdt_off(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- bypass_off(pbpctl_dev);
- else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
- write_data(pbpctl_dev, WDT_OFF);
- else
- data_pulse(pbpctl_dev, WDT_OFF);
- pbpctl_dev->wdt_status = WDT_STATUS_DIS;
- ret = 0;
- }
- return ret;
-}
-
-/* WDT_ON (0x10)*/
-
-/***Global***/
-static unsigned int
- wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 };
-
-static int wdt_on(struct bpctl_dev *pbpctl_dev, unsigned int timeout)
-{
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- unsigned int pulse = 0, temp_value = 0, temp_cnt = 0;
- pbpctl_dev->wdt_status = 0;
-
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- for (; wdt_val_array[temp_cnt]; temp_cnt++)
- if (timeout <= wdt_val_array[temp_cnt])
- break;
-
- if (!wdt_val_array[temp_cnt])
- temp_cnt--;
-
- timeout = wdt_val_array[temp_cnt];
- temp_cnt += 0x7;
-
- write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- pbpctl_dev->bp_status_un = 0;
- write_data_int(pbpctl_dev, temp_cnt);
- pbpctl_dev->bypass_wdt_on_time = jiffies;
- msec_delay_bp(CMND_INTERVAL_INT);
- pbpctl_dev->bypass_timer_interval = timeout;
- } else {
- timeout =
- (timeout <
- TIMEOUT_UNIT ? TIMEOUT_UNIT : (timeout >
- WDT_TIMEOUT_MAX ?
- WDT_TIMEOUT_MAX :
- timeout));
- temp_value = timeout / 100;
- while ((temp_value >>= 1))
- temp_cnt++;
- if (timeout > ((1 << temp_cnt) * 100))
- temp_cnt++;
- pbpctl_dev->bypass_wdt_on_time = jiffies;
- pulse = (WDT_ON | temp_cnt);
- if (pbpctl_dev->bp_ext_ver == OLD_IF_VER)
- data_pulse(pbpctl_dev, pulse);
- else
- write_data(pbpctl_dev, pulse);
- pbpctl_dev->bypass_timer_interval =
- (1 << temp_cnt) * 100;
- }
- pbpctl_dev->wdt_status = WDT_STATUS_EN;
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-static void bp75_put_hw_semaphore_generic(struct bpctl_dev *pbpctl_dev)
-{
- u32 swsm;
-
- swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
-
- swsm &= ~(BPCTLI_SWSM_SMBI | BPCTLI_SWSM_SWESMBI);
-
- BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm);
-}
-
-static s32 bp75_get_hw_semaphore_generic(struct bpctl_dev *pbpctl_dev)
-{
- u32 swsm;
- s32 ret_val = 0;
- s32 timeout = 8192 + 1;
- s32 i = 0;
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
- if (!(swsm & BPCTLI_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == timeout) {
- printk
- ("bpctl_mod: Driver can't access device - SMBI bit is set.\n");
- ret_val = -1;
- goto out;
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
- BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm | BPCTLI_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (BPCTL_READ_REG(pbpctl_dev, SWSM) & BPCTLI_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- bp75_put_hw_semaphore_generic(pbpctl_dev);
- printk("bpctl_mod: Driver can't access the NVM\n");
- ret_val = -1;
- goto out;
- }
-
- out:
- return ret_val;
-}
-
-static void bp75_release_phy(struct bpctl_dev *pbpctl_dev)
-{
- u16 mask = BPCTLI_SWFW_PHY0_SM;
- u32 swfw_sync;
- s32 ret_val;
-
- if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
- mask = BPCTLI_SWFW_PHY1_SM;
-
- do
- ret_val = bp75_get_hw_semaphore_generic(pbpctl_dev);
- while (ret_val != 0);
-
- swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
- swfw_sync &= ~mask;
- BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
-
- bp75_put_hw_semaphore_generic(pbpctl_dev);
-}
-
-static s32 bp75_acquire_phy(struct bpctl_dev *pbpctl_dev)
-{
- u16 mask = BPCTLI_SWFW_PHY0_SM;
- u32 swfw_sync;
- u32 swmask;
- u32 fwmask;
- s32 ret_val = 0;
- s32 i = 0, timeout = 200;
-
- if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
- mask = BPCTLI_SWFW_PHY1_SM;
-
- swmask = mask;
- fwmask = mask << 16;
-
- while (i < timeout) {
- if (bp75_get_hw_semaphore_generic(pbpctl_dev)) {
- ret_val = -1;
- goto out;
- }
-
- swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- bp75_put_hw_semaphore_generic(pbpctl_dev);
- mdelay(5);
- i++;
- }
-
- if (i == timeout) {
- printk
- ("bpctl_mod: Driver can't access resource, SW_FW_SYNC timeout.\n");
- ret_val = -1;
- goto out;
- }
-
- swfw_sync |= swmask;
- BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
-
- bp75_put_hw_semaphore_generic(pbpctl_dev);
-
- out:
- return ret_val;
-}
-
-static s32 bp75_read_phy_reg_mdic(struct bpctl_dev *pbpctl_dev, u32 offset,
- u16 *data)
-{
- u32 i, mdic = 0;
- s32 ret_val = 0;
- u32 phy_addr = 1;
-
- mdic = ((offset << BPCTLI_MDIC_REG_SHIFT) |
- (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_READ));
-
- BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
-
- for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
- usec_delay(50);
- mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
- if (mdic & BPCTLI_MDIC_READY)
- break;
- }
- if (!(mdic & BPCTLI_MDIC_READY)) {
- printk("bpctl_mod: MDI Read did not complete\n");
- ret_val = -1;
- goto out;
- }
- if (mdic & BPCTLI_MDIC_ERROR) {
- printk("bpctl_mod: MDI Error\n");
- ret_val = -1;
- goto out;
- }
- *data = (u16) mdic;
-
- out:
- return ret_val;
-}
-
-static s32 bp75_write_phy_reg_mdic(struct bpctl_dev *pbpctl_dev, u32 offset,
- u16 data)
-{
- u32 i, mdic = 0;
- s32 ret_val = 0;
- u32 phy_addr = 1;
-
- mdic = (((u32) data) |
- (offset << BPCTLI_MDIC_REG_SHIFT) |
- (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_WRITE));
-
- BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
-
- for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
- usec_delay(50);
- mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
- if (mdic & BPCTLI_MDIC_READY)
- break;
- }
- if (!(mdic & BPCTLI_MDIC_READY)) {
- printk("bpctl_mod: MDI Write did not complete\n");
- ret_val = -1;
- goto out;
- }
- if (mdic & BPCTLI_MDIC_ERROR) {
- printk("bpctl_mod: MDI Error\n");
- ret_val = -1;
- goto out;
- }
-
- out:
- return ret_val;
-}
-
-static s32 bp75_read_phy_reg(struct bpctl_dev *pbpctl_dev, u32 offset, u16 *data)
-{
- s32 ret_val = 0;
-
- ret_val = bp75_acquire_phy(pbpctl_dev);
- if (ret_val)
- goto out;
-
- if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
- ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
- BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
- (u16) offset);
- if (ret_val)
- goto release;
- }
-
- ret_val =
- bp75_read_phy_reg_mdic(pbpctl_dev,
- BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
-
- release:
- bp75_release_phy(pbpctl_dev);
- out:
- return ret_val;
-}
-
-static s32 bp75_write_phy_reg(struct bpctl_dev *pbpctl_dev, u32 offset, u16 data)
-{
- s32 ret_val = 0;
-
- ret_val = bp75_acquire_phy(pbpctl_dev);
- if (ret_val)
- goto out;
-
- if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
- ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
- BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
- (u16) offset);
- if (ret_val)
- goto release;
- }
-
- ret_val =
- bp75_write_phy_reg_mdic(pbpctl_dev,
- BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
-
- release:
- bp75_release_phy(pbpctl_dev);
-
- out:
- return ret_val;
-}
-
-/* SET_TX (non-Bypass command :)) */
-static int set_tx(struct bpctl_dev *pbpctl_dev, int tx_state)
-{
- int ret = 0, ctrl = 0;
- struct bpctl_dev *pbpctl_dev_m;
-
- if ((is_bypass_fn(pbpctl_dev)) == 1)
- pbpctl_dev_m = pbpctl_dev;
- else
- pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_m == NULL)
- return BP_NOT_CAP;
- if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
- if (!tx_state) {
- if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (ctrl | BP10G_SDP1_DIR |
- BP10G_SDP1_DATA));
-
- } else {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl | BPCTLI_CTRL_SDP1_DIR
- | BPCTLI_CTRL_SWDPIN1));
- }
- } else {
- if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP10G_SDP1_DIR) &
- ~BP10G_SDP1_DATA));
- } else {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl |
- BPCTLI_CTRL_SDP1_DIR) &
- ~BPCTLI_CTRL_SWDPIN1));
- }
- return ret;
-
- }
- } else if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
- if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
- if (tx_state) {
- uint16_t mii_reg;
- ret = bp75_read_phy_reg(pbpctl_dev,
- BPCTLI_PHY_CONTROL,
- &mii_reg);
- if (!ret) {
- if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) {
- ret =
- bp75_write_phy_reg
- (pbpctl_dev,
- BPCTLI_PHY_CONTROL,
- mii_reg &
- ~BPCTLI_MII_CR_POWER_DOWN);
- }
- }
- } else {
- uint16_t mii_reg;
- ret = bp75_read_phy_reg(pbpctl_dev,
- BPCTLI_PHY_CONTROL,
- &mii_reg);
- if (!ret) {
-
- mii_reg |= BPCTLI_MII_CR_POWER_DOWN;
- ret = bp75_write_phy_reg(pbpctl_dev,
- BPCTLI_PHY_CONTROL,
- mii_reg);
- }
- }
-
- }
- if (pbpctl_dev->bp_fiber5)
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- else if (pbpctl_dev->bp_10gb)
- ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
- else if (!pbpctl_dev->bp_10g)
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
- else
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
-
- if (!tx_state)
- if (pbpctl_dev->bp_10g9) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (ctrl | BP10G_SDP3_DATA |
- BP10G_SDP3_DIR));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- (ctrl |
- BPCTLI_CTRL_EXT_SDP6_DIR |
- BPCTLI_CTRL_EXT_SDP6_DATA));
-
- } else if (pbpctl_dev->bp_10gb) {
- if ((pbpctl_dev->func == 1)
- || (pbpctl_dev->func == 3))
- BP10GB_WRITE_REG(pbpctl_dev,
- MISC_REG_GPIO,
- (ctrl |
- BP10GB_GPIO0_SET_P1) &
- ~(BP10GB_GPIO0_CLR_P1 |
- BP10GB_GPIO0_OE_P1));
- else
- BP10GB_WRITE_REG(pbpctl_dev,
- MISC_REG_GPIO,
- (ctrl |
- BP10GB_GPIO0_OE_P0 |
- BP10GB_GPIO0_SET_P0));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl | BPCTLI_CTRL_SDP1_DIR
- | BPCTLI_CTRL_SWDPIN1));
-
- } else if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (ctrl | BP10G_SDP1_DIR |
- BP10G_SDP1_DATA));
-
- }
-
- else if (!pbpctl_dev->bp_10g)
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl | BPCTLI_CTRL_SWDPIO0 |
- BPCTLI_CTRL_SWDPIN0));
-
- else
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- (ctrl | BP10G_SDP0_DATA |
- BP10G_SDP0_DIR));
-
- else {
- if (pbpctl_dev->bp_10g9) {
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP10G_SDP3_DIR) &
- ~BP10G_SDP3_DATA));
-
- } else if (pbpctl_dev->bp_fiber5) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
- ((ctrl |
- BPCTLI_CTRL_EXT_SDP6_DIR) &
- ~BPCTLI_CTRL_EXT_SDP6_DATA));
-
- } else if (pbpctl_dev->bp_10gb) {
- if ((bpctl_dev_arr->func == 1)
- || (bpctl_dev_arr->func == 3))
- BP10GB_WRITE_REG(pbpctl_dev,
- MISC_REG_GPIO,
- (ctrl |
- BP10GB_GPIO0_CLR_P1) &
- ~(BP10GB_GPIO0_SET_P1 |
- BP10GB_GPIO0_OE_P1));
- else
- BP10GB_WRITE_REG(pbpctl_dev,
- MISC_REG_GPIO,
- (ctrl |
- BP10GB_GPIO0_OE_P0 |
- BP10GB_GPIO0_CLR_P0));
-
- } else if (pbpctl_dev->bp_i80) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl |
- BPCTLI_CTRL_SDP1_DIR) &
- ~BPCTLI_CTRL_SWDPIN1));
- } else if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP10G_SDP1_DIR) &
- ~BP10G_SDP1_DATA));
- }
-
- else if (!pbpctl_dev->bp_10g) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- ((ctrl | BPCTLI_CTRL_SWDPIO0)
- & ~BPCTLI_CTRL_SWDPIN0));
- if (!PEGF_IF_SERIES(pbpctl_dev->subdevice)) {
- BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
- (ctrl &
- ~
- (BPCTLI_CTRL_SDP0_DATA
- |
- BPCTLI_CTRL_SDP0_DIR)));
- }
- } else
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP10G_SDP0_DIR) &
- ~BP10G_SDP0_DATA));
-
- }
-
- } else
- ret = BP_NOT_CAP;
- return ret;
-
-}
-
-/* SET_FORCE_LINK (non-Bypass command :)) */
-static int set_bp_force_link(struct bpctl_dev *pbpctl_dev, int tx_state)
-{
- int ret = 0, ctrl = 0;
-
- if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
-
- if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
-
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
- if (!tx_state)
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ctrl & ~BP10G_SDP1_DIR);
- else
- BP10G_WRITE_REG(pbpctl_dev, ESDP,
- ((ctrl | BP10G_SDP1_DIR) &
- ~BP10G_SDP1_DATA));
- return ret;
- }
-
- }
- return BP_NOT_CAP;
-}
-
-/*RESET_CONT 0x20 */
-static int reset_cont(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- return BP_NOT_CAP;
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
- write_data(pbpctl_dev, RESET_CONT);
- else
- data_pulse(pbpctl_dev, RESET_CONT);
- ret = 0;
- }
- return ret;
-}
-
-/*DIS_BYPASS_CAP 0x22 */
-static int dis_bypass_cap(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- } else {
- write_data(pbpctl_dev, BYPASS_OFF);
- msec_delay_bp(LATCH_DELAY);
- write_data(pbpctl_dev, DIS_BYPASS_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/*EN_BYPASS_CAP 0x24 */
-static int en_bypass_cap(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- } else {
- write_data(pbpctl_dev, EN_BYPASS_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/* BYPASS_STATE_PWRON 0x26*/
-static int bypass_state_pwron(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
- write_data(pbpctl_dev, BYPASS_STATE_PWRON);
- if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
- msec_delay_bp(DFLT_PWRON_DELAY);
- else
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/* NORMAL_STATE_PWRON 0x28*/
-static int normal_state_pwron(struct bpctl_dev *pbpctl_dev)
-{
- if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)
- || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) {
- write_data(pbpctl_dev, NORMAL_STATE_PWRON);
- if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
- msec_delay_bp(DFLT_PWRON_DELAY);
- else
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/* BYPASS_STATE_PWROFF 0x27*/
-static int bypass_state_pwroff(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP) {
- write_data(pbpctl_dev, BYPASS_STATE_PWROFF);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/* NORMAL_STATE_PWROFF 0x29*/
-static int normal_state_pwroff(struct bpctl_dev *pbpctl_dev)
-{
- if ((pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) {
- write_data(pbpctl_dev, NORMAL_STATE_PWROFF);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/*TAP_STATE_PWRON 0x2a*/
-static int tap_state_pwron(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
- write_data(pbpctl_dev, TAP_STATE_PWRON);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/*DIS_TAP_CAP 0x2c*/
-static int dis_tap_cap(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
- write_data(pbpctl_dev, DIS_TAP_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/*EN_TAP_CAP 0x2e*/
-static int en_tap_cap(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
- write_data(pbpctl_dev, EN_TAP_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-/*DISC_STATE_PWRON 0x2a*/
-static int disc_state_pwron(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- write_data(pbpctl_dev, DISC_STATE_PWRON);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-/*DIS_DISC_CAP 0x2c*/
-static int dis_disc_cap(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- write_data(pbpctl_dev, DIS_DISC_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-/*EN_TAP_CAP 0x2e*/
-static int en_disc_cap(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- write_data(pbpctl_dev, EN_DISC_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-static int std_nic_on(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
-
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- pbpctl_dev->bp_status_un = 0;
- return BP_OK;
- }
-
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- write_data(pbpctl_dev, STD_NIC_ON);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return BP_OK;
-
- }
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- wdt_off(pbpctl_dev);
-
- if (pbpctl_dev->bp_caps & BP_CAP) {
- write_data(pbpctl_dev, BYPASS_OFF);
- msec_delay_bp(LATCH_DELAY);
- }
-
- if (pbpctl_dev->bp_caps & TAP_CAP) {
- write_data(pbpctl_dev, TAP_OFF);
- msec_delay_bp(LATCH_DELAY);
- }
-
- write_data(pbpctl_dev, NORMAL_STATE_PWRON);
- if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
- msec_delay_bp(DFLT_PWRON_DELAY);
- else
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
-
- if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
- write_data(pbpctl_dev, DIS_BYPASS_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
-
- if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
- write_data(pbpctl_dev, DIS_TAP_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
-
- }
- return 0;
- }
- }
- return BP_NOT_CAP;
-}
-
-static int std_nic_off(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
- msec_delay_bp(BYPASS_DELAY_INT);
- return BP_OK;
- }
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- write_data(pbpctl_dev, STD_NIC_OFF);
- msec_delay_bp(BYPASS_CAP_DELAY);
- return BP_OK;
-
- }
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
-
- if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
- write_data(pbpctl_dev, TAP_STATE_PWRON);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
- }
-
- if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
- write_data(pbpctl_dev, BYPASS_STATE_PWRON);
- if (pbpctl_dev->bp_ext_ver > PXG2BPI_VER)
- msec_delay_bp(LATCH_DELAY +
- EEPROM_WR_DELAY);
- else
- msec_delay_bp(DFLT_PWRON_DELAY);
- }
-
- if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
- write_data(pbpctl_dev, EN_TAP_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
- if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
- write_data(pbpctl_dev, EN_DISC_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
-
- if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
- write_data(pbpctl_dev, EN_BYPASS_CAP);
- msec_delay_bp(BYPASS_CAP_DELAY);
- }
-
- return 0;
- }
- }
- return BP_NOT_CAP;
-}
-
-int wdt_time_left(struct bpctl_dev *pbpctl_dev)
-{
-
- /* unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; */
- unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time =
- pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0;
- int time_left = 0;
-
- switch (pbpctl_dev->wdt_status) {
- case WDT_STATUS_DIS:
- time_left = 0;
- break;
- case WDT_STATUS_EN:
- delta_time =
- (curr_time >=
- wdt_on_time) ? (curr_time - wdt_on_time) : (~wdt_on_time +
- curr_time);
- delta_time_msec = jiffies_to_msecs(delta_time);
- time_left = pbpctl_dev->bypass_timer_interval - delta_time_msec;
- if (time_left < 0) {
- time_left = -1;
- pbpctl_dev->wdt_status = WDT_STATUS_EXP;
- }
- break;
- case WDT_STATUS_EXP:
- time_left = -1;
- break;
- }
-
- return time_left;
-}
-
-static int wdt_timer(struct bpctl_dev *pbpctl_dev, int *time_left)
-{
- int ret = 0;
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- {
- if (pbpctl_dev->wdt_status == WDT_STATUS_UNKNOWN)
- ret = BP_NOT_CAP;
- else
- *time_left = wdt_time_left(pbpctl_dev);
- }
-
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-static int wdt_timer_reload(struct bpctl_dev *pbpctl_dev)
-{
-
- int ret = 0;
-
- if ((pbpctl_dev->bp_caps & WD_CTL_CAP) &&
- (pbpctl_dev->wdt_status != WDT_STATUS_UNKNOWN)) {
- if (pbpctl_dev->wdt_status == WDT_STATUS_DIS)
- return 0;
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
- ret = wdt_pulse(pbpctl_dev);
- else if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- ret = wdt_pulse_int(pbpctl_dev);
- else
- ret = send_wdt_pulse(pbpctl_dev);
- /* if (ret==-1)
- mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/
- return 1;
- }
- return BP_NOT_CAP;
-}
-
-static void wd_reset_timer(unsigned long param)
-{
- struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) param;
-#ifdef BP_SELF_TEST
- struct sk_buff *skb_tmp;
-#endif
-
- if ((pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) &&
- ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)) {
- mod_timer(&pbpctl_dev->bp_timer, jiffies + 1);
- return;
- }
-#ifdef BP_SELF_TEST
-
- if (pbpctl_dev->bp_self_test_flag == 1) {
- skb_tmp = dev_alloc_skb(BPTEST_DATA_LEN + 2);
- if ((skb_tmp) && (pbpctl_dev->ndev) && (pbpctl_dev->bp_tx_data)) {
- memcpy(skb_put(skb_tmp, BPTEST_DATA_LEN),
- pbpctl_dev->bp_tx_data, BPTEST_DATA_LEN);
- skb_tmp->dev = pbpctl_dev->ndev;
- skb_tmp->protocol =
- eth_type_trans(skb_tmp, pbpctl_dev->ndev);
- skb_tmp->ip_summed = CHECKSUM_UNNECESSARY;
- netif_receive_skb(skb_tmp);
- goto bp_timer_reload;
- return;
- }
- }
-#endif
-
- wdt_timer_reload(pbpctl_dev);
-#ifdef BP_SELF_TEST
- bp_timer_reload:
-#endif
- if (pbpctl_dev->reset_time) {
- mod_timer(&pbpctl_dev->bp_timer,
- jiffies + (HZ * pbpctl_dev->reset_time) / 1000);
- }
-}
-
-/*WAIT_AT_PWRUP 0x80 */
-static int bp_wait_at_pwup_en(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- write_data(pbpctl_dev, BP_WAIT_AT_PWUP_EN);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
-
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-/*DIS_WAIT_AT_PWRUP 0x81 */
-static int bp_wait_at_pwup_dis(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
-
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- write_data(pbpctl_dev, BP_WAIT_AT_PWUP_DIS);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
-
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-/*EN_HW_RESET 0x82 */
-
-static int bp_hw_reset_en(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- write_data(pbpctl_dev, BP_HW_RESET_EN);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
-
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-/*DIS_HW_RESET 0x83 */
-
-static int bp_hw_reset_dis(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- write_data(pbpctl_dev, BP_HW_RESET_DIS);
- msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
-
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-
-static int wdt_exp_mode(struct bpctl_dev *pbpctl_dev, int mode)
-{
- uint32_t status_reg = 0, status_reg1 = 0;
-
- if ((pbpctl_dev->bp_caps & (TAP_STATUS_CAP | DISC_CAP)) &&
- (pbpctl_dev->bp_caps & BP_CAP)) {
- if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
-
- if ((pbpctl_dev->bp_ext_ver >= 0x8) &&
- (mode == 2) && (pbpctl_dev->bp_caps & DISC_CAP)) {
- status_reg1 =
- read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
- if (!(status_reg1 & WDTE_DISC_BPN_MASK))
- write_reg(pbpctl_dev,
- status_reg1 |
- WDTE_DISC_BPN_MASK,
- STATUS_DISC_REG_ADDR);
- return BP_OK;
- }
- }
- status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
-
- if ((mode == 0) && (pbpctl_dev->bp_caps & BP_CAP)) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- status_reg1 =
- read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
- if (status_reg1 & WDTE_DISC_BPN_MASK)
- write_reg(pbpctl_dev,
- status_reg1 &
- ~WDTE_DISC_BPN_MASK,
- STATUS_DISC_REG_ADDR);
- }
- if (status_reg & WDTE_TAP_BPN_MASK)
- write_reg(pbpctl_dev,
- status_reg & ~WDTE_TAP_BPN_MASK,
- STATUS_TAP_REG_ADDR);
- return BP_OK;
-
- } else if ((mode == 1) && (pbpctl_dev->bp_caps & TAP_CAP)) {
- if (!(status_reg & WDTE_TAP_BPN_MASK))
- write_reg(pbpctl_dev,
- status_reg | WDTE_TAP_BPN_MASK,
- STATUS_TAP_REG_ADDR);
- /*else return BP_NOT_CAP; */
- return BP_OK;
- }
-
- }
- return BP_NOT_CAP;
-}
-
-static int bypass_fw_ver(struct bpctl_dev *pbpctl_dev)
-{
- if (is_bypass_fn(pbpctl_dev))
- return read_reg(pbpctl_dev, VER_REG_ADDR);
- else
- return BP_NOT_CAP;
-}
-
-static int bypass_sign_check(struct bpctl_dev *pbpctl_dev)
-{
-
- if (is_bypass_fn(pbpctl_dev))
- return (((read_reg(pbpctl_dev, PIC_SIGN_REG_ADDR)) ==
- PIC_SIGN_VALUE) ? 1 : 0);
- else
- return BP_NOT_CAP;
-}
-
-static int tx_status(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl = 0;
- struct bpctl_dev *pbpctl_dev_m;
-
- if ((is_bypass_fn(pbpctl_dev)) == 1)
- pbpctl_dev_m = pbpctl_dev;
- else
- pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_m == NULL)
- return BP_NOT_CAP;
- if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
-
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
- if (pbpctl_dev->bp_i80)
- return ((ctrl & BPCTLI_CTRL_SWDPIN1) != 0 ? 0 : 1);
- if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
-
- return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
- }
-
- }
-
- if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
- if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
- uint16_t mii_reg;
- if (!
- (bp75_read_phy_reg
- (pbpctl_dev, BPCTLI_PHY_CONTROL, &mii_reg))) {
- if (mii_reg & BPCTLI_MII_CR_POWER_DOWN)
- return 0;
-
- else
- return 1;
- }
- return -1;
- }
-
- if (pbpctl_dev->bp_10g9) {
- return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
- BP10G_SDP3_DATA) != 0 ? 0 : 1);
-
- } else if (pbpctl_dev->bp_fiber5) {
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- if (ctrl & BPCTLI_CTRL_EXT_SDP6_DATA)
- return 0;
- return 1;
- } else if (pbpctl_dev->bp_10gb) {
- ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
- (ctrl | BP10GB_GPIO0_OE_P1) &
- ~(BP10GB_GPIO0_SET_P1 |
- BP10GB_GPIO0_CLR_P1));
-
- if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
- return (((BP10GB_READ_REG
- (pbpctl_dev,
- MISC_REG_GPIO)) & BP10GB_GPIO0_P1) !=
- 0 ? 0 : 1);
- else
- return (((BP10GB_READ_REG
- (pbpctl_dev,
- MISC_REG_GPIO)) & BP10GB_GPIO0_P0) !=
- 0 ? 0 : 1);
- }
-
- if (!pbpctl_dev->bp_10g) {
-
- ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
- if (pbpctl_dev->bp_i80)
- return ((ctrl & BPCTLI_CTRL_SWDPIN1) !=
- 0 ? 0 : 1);
- if (pbpctl_dev->bp_540) {
- ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
-
- return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
- }
-
- return ((ctrl & BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
- } else
- return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
- BP10G_SDP0_DATA) != 0 ? 0 : 1);
-
- }
- return BP_NOT_CAP;
-}
-
-static int bp_force_link_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
-
- if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
- return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
- BP10G_SDP1_DIR) != 0 ? 1 : 0);
-
- }
- }
- return BP_NOT_CAP;
-}
-
-static int bypass_from_last_read(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t ctrl_ext = 0;
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
- BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL_EXT,
- (ctrl_ext & ~BPCTLI_CTRL_EXT_SDP7_DIR));
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
- if (ctrl_ext & BPCTLI_CTRL_EXT_SDP7_DATA)
- return 0;
- return 1;
- } else
- return BP_NOT_CAP;
-}
-
-static int bypass_status_clear(struct bpctl_dev *pbpctl_dev)
-{
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
- send_bypass_clear_pulse(pbpctl_dev_b, 1);
- return 0;
- } else
- return BP_NOT_CAP;
-}
-
-static int bypass_flag_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if ((pbpctl_dev->bp_caps & BP_CAP)) {
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
- BYPASS_FLAG_MASK) ==
- BYPASS_FLAG_MASK) ? 1 : 0);
- }
- }
- return BP_NOT_CAP;
-}
-
-static int bypass_flag_status_clear(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & BP_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- uint32_t status_reg = 0;
- status_reg = read_reg(pbpctl_dev, STATUS_REG_ADDR);
- write_reg(pbpctl_dev, status_reg & ~BYPASS_FLAG_MASK,
- STATUS_REG_ADDR);
- return 0;
- }
- }
- return BP_NOT_CAP;
-}
-
-static int bypass_change_status(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & BP_STATUS_CHANGE_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- ret = bypass_flag_status(pbpctl_dev);
- bypass_flag_status_clear(pbpctl_dev);
- } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- ret = bypass_flag_status(pbpctl_dev);
- bypass_flag_status_clear(pbpctl_dev);
- } else {
- ret = bypass_from_last_read(pbpctl_dev);
- bypass_status_clear(pbpctl_dev);
- }
- }
- return ret;
-}
-
-static int bypass_status(struct bpctl_dev *pbpctl_dev)
-{
- u32 ctrl_ext = 0;
-
- if (pbpctl_dev->bp_caps & BP_CAP) {
-
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
-
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
-
- if (!pbpctl_dev->bp_status_un)
- return (((BPCTL_READ_REG
- (pbpctl_dev_b,
- CTRL_EXT)) &
- BPCTLI_CTRL_EXT_SDP7_DATA) !=
- 0 ? 1 : 0);
- else
- return BP_NOT_CAP;
- }
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
-
- if (pbpctl_dev->bp_10g9) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
- BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
- (ctrl_ext | BP10G_I2C_CLK_OUT));
- return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
- BP10G_I2C_CLK_IN) != 0 ? 0 : 1);
-
- } else if (pbpctl_dev->bp_540) {
- return (((BP10G_READ_REG(pbpctl_dev_b, ESDP)) &
- BP10G_SDP0_DATA) != 0 ? 0 : 1);
- }
-
- else if ((pbpctl_dev->bp_fiber5)
- || (pbpctl_dev->bp_i80)) {
- return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
- BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext =
- BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
- (ctrl_ext | BP10GB_GPIO3_OE_P0)
- & ~(BP10GB_GPIO3_SET_P0 |
- BP10GB_GPIO3_CLR_P0));
-
- return (((BP10GB_READ_REG
- (pbpctl_dev,
- MISC_REG_GPIO)) & BP10GB_GPIO3_P0) !=
- 0 ? 0 : 1);
- }
-
- else if (!pbpctl_dev->bp_10g)
- return (((BPCTL_READ_REG
- (pbpctl_dev_b,
- CTRL_EXT)) &
- BPCTLI_CTRL_EXT_SDP7_DATA) !=
- 0 ? 0 : 1);
-
- else {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
- (ctrl_ext |
- BP10G_SDP7_DATA_OUT));
- return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
- BP10G_SDP7_DATA_IN) != 0 ? 0 : 1);
- }
-
- } else if (pbpctl_dev->media_type == BP_COPPER) {
-
- return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
- BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
- } else {
- if ((bypass_status_clear(pbpctl_dev)) >= 0)
- return bypass_from_last_read(pbpctl_dev);
- }
-
- }
- return BP_NOT_CAP;
-}
-
-static int default_pwron_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- return ((((read_reg
- (pbpctl_dev,
- STATUS_REG_ADDR)) & DFLT_PWRON_MASK)
- == DFLT_PWRON_MASK) ? 0 : 1);
- }
- } /*else if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
- (pbpctl_dev->bp_caps&BP_PWUP_ON_CAP))
- return 1; */
- }
- return BP_NOT_CAP;
-}
-
-static int default_pwroff_status(struct bpctl_dev *pbpctl_dev)
-{
-
- /*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
- (pbpctl_dev->bp_caps&BP_PWOFF_ON_CAP))
- return 1; */
- if ((pbpctl_dev->bp_caps & SW_CTL_CAP)
- && (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) {
- return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
- DFLT_PWROFF_MASK) == DFLT_PWROFF_MASK) ? 0 : 1);
- }
- return BP_NOT_CAP;
-}
-
-static int dis_bypass_cap_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
- DIS_BYPASS_CAP_MASK) ==
- DIS_BYPASS_CAP_MASK) ? 1 : 0);
- }
- }
- return BP_NOT_CAP;
-}
-
-static int wdt_programmed(struct bpctl_dev *pbpctl_dev, int *timeout)
-{
- int ret = 0;
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
- WDT_EN_MASK) {
- u8 wdt_val;
- wdt_val = read_reg(pbpctl_dev, WDT_REG_ADDR);
- *timeout = (1 << wdt_val) * 100;
- } else
- *timeout = 0;
- } else {
- int curr_wdt_status = pbpctl_dev->wdt_status;
- if (curr_wdt_status == WDT_STATUS_UNKNOWN)
- *timeout = -1;
- else
- *timeout =
- curr_wdt_status ==
- 0 ? 0 : pbpctl_dev->bypass_timer_interval;
- }
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-static int normal_support(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
- ret =
- ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
- NORMAL_UNSUPPORT_MASK) ==
- NORMAL_UNSUPPORT_MASK) ? 0 : 1);
- } else
- ret = 1;
- }
- return ret;
-}
-
-static int get_bp_prod_caps(struct bpctl_dev *pbpctl_dev)
-{
- if ((pbpctl_dev->bp_caps & SW_CTL_CAP) &&
- (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER))
- return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
- return BP_NOT_CAP;
-
-}
-
-static int tap_flag_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
- return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
- TAP_FLAG_MASK) == TAP_FLAG_MASK) ? 1 : 0);
-
- }
- return BP_NOT_CAP;
-}
-
-static int tap_flag_status_clear(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t status_reg = 0;
-
- if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
- status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
- write_reg(pbpctl_dev, status_reg & ~TAP_FLAG_MASK,
- STATUS_TAP_REG_ADDR);
- return 0;
- }
- }
- return BP_NOT_CAP;
-}
-
-static int tap_change_status(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
- if (pbpctl_dev->bp_caps & TAP_CAP) {
- if (pbpctl_dev->bp_caps & BP_CAP) {
- ret = tap_flag_status(pbpctl_dev);
- tap_flag_status_clear(pbpctl_dev);
- } else {
- ret = bypass_from_last_read(pbpctl_dev);
- bypass_status_clear(pbpctl_dev);
- }
- }
- }
- return ret;
-}
-
-static int tap_status(struct bpctl_dev *pbpctl_dev)
-{
- u32 ctrl_ext = 0;
-
- if (pbpctl_dev->bp_caps & TAP_CAP) {
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
-
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- if (!pbpctl_dev->bp_10g)
- return (((BPCTL_READ_REG
- (pbpctl_dev_b,
- CTRL_EXT)) &
- BPCTLI_CTRL_EXT_SDP6_DATA) !=
- 0 ? 0 : 1);
- else {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
- (ctrl_ext |
- BP10G_SDP6_DATA_OUT));
- return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
- BP10G_SDP6_DATA_IN) != 0 ? 0 : 1);
- }
-
- } else if (pbpctl_dev->media_type == BP_COPPER)
- return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) &
- BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
- else {
- if ((bypass_status_clear(pbpctl_dev)) >= 0)
- return bypass_from_last_read(pbpctl_dev);
- }
-
- }
- return BP_NOT_CAP;
-}
-
-static int default_pwron_tap_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
- return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
- DFLT_PWRON_TAP_MASK) ==
- DFLT_PWRON_TAP_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int dis_tap_cap_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
- return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
- DIS_TAP_CAP_MASK) ==
- DIS_TAP_CAP_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int disc_flag_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & DISC_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8)
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- DISC_FLAG_MASK) == DISC_FLAG_MASK) ? 1 : 0);
-
- }
- return BP_NOT_CAP;
-}
-
-static int disc_flag_status_clear(struct bpctl_dev *pbpctl_dev)
-{
- uint32_t status_reg = 0;
-
- if (pbpctl_dev->bp_caps & DISC_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- status_reg = read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
- write_reg(pbpctl_dev, status_reg & ~DISC_FLAG_MASK,
- STATUS_DISC_REG_ADDR);
- return BP_OK;
- }
- }
- return BP_NOT_CAP;
-}
-
-static int disc_change_status(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (pbpctl_dev->bp_caps & DISC_CAP) {
- ret = disc_flag_status(pbpctl_dev);
- disc_flag_status_clear(pbpctl_dev);
- return ret;
- }
- return BP_NOT_CAP;
-}
-
-static int disc_off_status(struct bpctl_dev *pbpctl_dev)
-{
- struct bpctl_dev *pbpctl_dev_b = NULL;
- u32 ctrl_ext = 0;
-
- if (pbpctl_dev->bp_caps & DISC_CAP) {
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return BP_NOT_CAP;
- if (DISCF_IF_SERIES(pbpctl_dev->subdevice))
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
-
- if (pbpctl_dev->bp_i80) {
- return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) &
- BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0);
-
- }
- if (pbpctl_dev->bp_540) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP);
- return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
- BP10G_SDP2_DATA) != 0 ? 1 : 0);
-
- }
- if (pbpctl_dev->media_type == BP_COPPER) {
-
-#if 0
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
-#endif
- if (!pbpctl_dev->bp_10g)
- return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
- BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
- else
- return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
- BP10G_SDP1_DATA) != 0 ? 1 : 0);
-
- } else {
-
- if (pbpctl_dev->bp_10g9) {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
- BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
- (ctrl_ext |
- BP10G_I2C_DATA_OUT));
- return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
- BP10G_I2C_DATA_IN) != 0 ? 1 : 0);
-
- } else if (pbpctl_dev->bp_fiber5) {
- return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
- BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
- } else if (pbpctl_dev->bp_10gb) {
- ctrl_ext =
- BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
- BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
- (ctrl_ext | BP10GB_GPIO3_OE_P1)
- & ~(BP10GB_GPIO3_SET_P1 |
- BP10GB_GPIO3_CLR_P1));
-
- return (((BP10GB_READ_REG
- (pbpctl_dev,
- MISC_REG_GPIO)) & BP10GB_GPIO3_P1) !=
- 0 ? 1 : 0);
- }
- if (!pbpctl_dev->bp_10g) {
-
- return (((BPCTL_READ_REG
- (pbpctl_dev_b,
- CTRL_EXT)) &
- BPCTLI_CTRL_EXT_SDP6_DATA) !=
- 0 ? 1 : 0);
- } else {
- ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
- BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
- (ctrl_ext |
- BP10G_SDP6_DATA_OUT));
- return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP))
- & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0);
- }
-
- }
- }
- return BP_NOT_CAP;
-}
-
-static int disc_status(struct bpctl_dev *pbpctl_dev)
-{
- int ctrl = 0;
-
- if (pbpctl_dev->bp_caps & DISC_CAP) {
- ctrl = disc_off_status(pbpctl_dev);
- if (ctrl < 0)
- return ctrl;
- return ((ctrl == 0) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int default_pwron_disc_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8)
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- DFLT_PWRON_DISC_MASK) ==
- DFLT_PWRON_DISC_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int dis_disc_cap_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & DIS_DISC_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8)
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- DIS_DISC_CAP_MASK) ==
- DIS_DISC_CAP_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int wdt_exp_mode_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER)
- return 0; /* bypass mode */
- else if (pbpctl_dev->bp_ext_ver == PXG2TBPI_VER)
- return 1; /* tap mode */
- else if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
- if (pbpctl_dev->bp_ext_ver >= 0x8) {
- if (((read_reg
- (pbpctl_dev,
- STATUS_DISC_REG_ADDR)) &
- WDTE_DISC_BPN_MASK) == WDTE_DISC_BPN_MASK)
- return 2;
- }
- return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
- WDTE_TAP_BPN_MASK) ==
- WDTE_TAP_BPN_MASK) ? 1 : 0);
- }
- }
- return BP_NOT_CAP;
-}
-
-static int tpl2_flag_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- TPL2_FLAG_MASK) == TPL2_FLAG_MASK) ? 1 : 0);
-
- }
- return BP_NOT_CAP;
-}
-
-static int bp_wait_at_pwup_status(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- if (pbpctl_dev->bp_ext_ver >= 0x8)
- return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
- WAIT_AT_PWUP_MASK) ==
- WAIT_AT_PWUP_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-static int bp_hw_reset_status(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
-
- if (pbpctl_dev->bp_ext_ver >= 0x8)
- return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
- EN_HW_RESET_MASK) ==
- EN_HW_RESET_MASK) ? 1 : 0);
- }
- return BP_NOT_CAP;
-}
-
-
-static int std_nic_status(struct bpctl_dev *pbpctl_dev)
-{
- int status_val = 0;
-
- if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- return BP_NOT_CAP;
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
- STD_NIC_ON_MASK) == STD_NIC_ON_MASK) ? 1 : 0);
- }
-
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- if (pbpctl_dev->bp_caps & BP_CAP) {
- status_val =
- read_reg(pbpctl_dev, STATUS_REG_ADDR);
- if (((!(status_val & WDT_EN_MASK))
- && ((status_val & STD_NIC_MASK) ==
- STD_NIC_MASK)))
- status_val = 1;
- else
- return 0;
- }
- if (pbpctl_dev->bp_caps & TAP_CAP) {
- status_val =
- read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
- if ((status_val & STD_NIC_TAP_MASK) ==
- STD_NIC_TAP_MASK)
- status_val = 1;
- else
- return 0;
- }
- if (pbpctl_dev->bp_caps & TAP_CAP) {
- if ((disc_off_status(pbpctl_dev)))
- status_val = 1;
- else
- return 0;
- }
-
- return status_val;
- }
- }
- return BP_NOT_CAP;
-}
-
-/******************************************************/
-/**************SW_INIT*********************************/
-/******************************************************/
-static void bypass_caps_init(struct bpctl_dev *pbpctl_dev)
-{
- u_int32_t ctrl_ext = 0;
- struct bpctl_dev *pbpctl_dev_m = NULL;
-
-#ifdef BYPASS_DEBUG
- int ret = 0;
-
- if (!(INTEL_IF_SERIES(adapter->bp_device_block.subdevice))) {
- ret = read_reg(pbpctl_dev, VER_REG_ADDR);
- printk("VER_REG reg1=%x\n", ret);
- ret = read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
- printk("PRODUCT_CAP reg=%x\n", ret);
- ret = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
- printk("STATUS_TAP reg1=%x\n", ret);
- ret = read_reg(pbpctl_dev, 0x7);
- printk("SIG_REG reg1=%x\n", ret);
- ret = read_reg(pbpctl_dev, STATUS_REG_ADDR);
- printk("STATUS_REG_ADDR=%x\n", ret);
- ret = read_reg(pbpctl_dev, WDT_REG_ADDR);
- printk("WDT_REG_ADDR=%x\n", ret);
- ret = read_reg(pbpctl_dev, TMRL_REG_ADDR);
- printk("TMRL_REG_ADDR=%x\n", ret);
- ret = read_reg(pbpctl_dev, TMRH_REG_ADDR);
- printk("TMRH_REG_ADDR=%x\n", ret);
- }
-#endif
- if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_10g9)) {
- pbpctl_dev->media_type = BP_FIBER;
- } else if (pbpctl_dev->bp_10gb) {
- if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->media_type = BP_CX4;
- else
- pbpctl_dev->media_type = BP_FIBER;
-
- }
-
- else if (pbpctl_dev->bp_540)
- pbpctl_dev->media_type = BP_NONE;
- else if (!pbpctl_dev->bp_10g) {
-
- ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
- if ((ctrl_ext & BPCTLI_CTRL_EXT_LINK_MODE_MASK) == 0x0)
- pbpctl_dev->media_type = BP_COPPER;
- else
- pbpctl_dev->media_type = BP_FIBER;
-
- } else {
- if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->media_type = BP_CX4;
- else
- pbpctl_dev->media_type = BP_FIBER;
- }
-
- if (is_bypass_fn(pbpctl_dev)) {
-
- pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP;
- if (pbpctl_dev->media_type == BP_FIBER)
- pbpctl_dev->bp_caps |=
- (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP);
-
- if (TPL_IF_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->bp_caps |= TPL_CAP;
-
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
- pbpctl_dev->bp_caps |=
- (BP_CAP | BP_STATUS_CAP | SW_CTL_CAP |
- BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWOFF_OFF_CAP
- | WD_CTL_CAP | WD_STATUS_CAP | STD_NIC_CAP |
- WD_TIMEOUT_CAP);
-
- pbpctl_dev->bp_ext_ver = OLD_IF_VER;
- return;
- }
-
- if ((pbpctl_dev->bp_fw_ver == 0xff) &&
- OLD_IF_SERIES(pbpctl_dev->subdevice)) {
-
- pbpctl_dev->bp_caps |=
- (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
- SW_CTL_CAP | BP_PWUP_ON_CAP | WD_CTL_CAP |
- WD_STATUS_CAP | WD_TIMEOUT_CAP);
-
- pbpctl_dev->bp_ext_ver = OLD_IF_VER;
- return;
- }
-
- else {
- switch (pbpctl_dev->bp_fw_ver) {
- case BP_FW_VER_A0:
- case BP_FW_VER_A1:{
- pbpctl_dev->bp_ext_ver =
- (pbpctl_dev->
- bp_fw_ver & EXT_VER_MASK);
- break;
- }
- default:{
- if ((bypass_sign_check(pbpctl_dev)) !=
- 1) {
- pbpctl_dev->bp_caps = 0;
- return;
- }
- pbpctl_dev->bp_ext_ver =
- (pbpctl_dev->
- bp_fw_ver & EXT_VER_MASK);
- }
- }
- }
-
- if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
- pbpctl_dev->bp_caps |=
- (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
- SW_CTL_CAP | BP_DIS_CAP | BP_DIS_STATUS_CAP |
- BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP
- | WD_CTL_CAP | STD_NIC_CAP | WD_STATUS_CAP |
- WD_TIMEOUT_CAP);
- else if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
- int cap_reg;
-
- pbpctl_dev->bp_caps |=
- (SW_CTL_CAP | WD_CTL_CAP | WD_STATUS_CAP |
- WD_TIMEOUT_CAP);
- cap_reg = get_bp_prod_caps(pbpctl_dev);
-
- if ((cap_reg & NORMAL_UNSUPPORT_MASK) ==
- NORMAL_UNSUPPORT_MASK)
- pbpctl_dev->bp_caps |= NIC_CAP_NEG;
- else
- pbpctl_dev->bp_caps |= STD_NIC_CAP;
-
- if ((normal_support(pbpctl_dev)) == 1)
-
- pbpctl_dev->bp_caps |= STD_NIC_CAP;
-
- else
- pbpctl_dev->bp_caps |= NIC_CAP_NEG;
- if ((cap_reg & BYPASS_SUPPORT_MASK) ==
- BYPASS_SUPPORT_MASK) {
- pbpctl_dev->bp_caps |=
- (BP_CAP | BP_STATUS_CAP |
- BP_STATUS_CHANGE_CAP | BP_DIS_CAP |
- BP_DIS_STATUS_CAP | BP_PWUP_ON_CAP |
- BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP);
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER7)
- pbpctl_dev->bp_caps |=
- BP_PWOFF_ON_CAP | BP_PWOFF_OFF_CAP |
- BP_PWOFF_CTL_CAP;
- }
- if ((cap_reg & TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) {
- pbpctl_dev->bp_caps |=
- (TAP_CAP | TAP_STATUS_CAP |
- TAP_STATUS_CHANGE_CAP | TAP_DIS_CAP |
- TAP_DIS_STATUS_CAP | TAP_PWUP_ON_CAP |
- TAP_PWUP_OFF_CAP | TAP_PWUP_CTL_CAP);
- }
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
- if ((cap_reg & DISC_SUPPORT_MASK) ==
- DISC_SUPPORT_MASK)
- pbpctl_dev->bp_caps |=
- (DISC_CAP | DISC_DIS_CAP |
- DISC_PWUP_CTL_CAP);
- if ((cap_reg & TPL2_SUPPORT_MASK) ==
- TPL2_SUPPORT_MASK) {
- pbpctl_dev->bp_caps_ex |= TPL2_CAP_EX;
- pbpctl_dev->bp_caps |= TPL_CAP;
- pbpctl_dev->bp_tpl_flag =
- tpl2_flag_status(pbpctl_dev);
- }
-
- }
-
- if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER9) {
- if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
- DISC_PORT_SUPPORT_MASK) {
- pbpctl_dev->bp_caps_ex |=
- DISC_PORT_CAP_EX;
- pbpctl_dev->bp_caps |=
- (TX_CTL_CAP | TX_STATUS_CAP);
- }
-
- }
-
- }
- if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
- if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
- WDT_EN_MASK)
- pbpctl_dev->wdt_status = WDT_STATUS_EN;
- else
- pbpctl_dev->wdt_status = WDT_STATUS_DIS;
- }
-
- } else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice)) ||
- (PEGF5_IF_SERIES(pbpctl_dev->subdevice)) ||
- (PEGF80_IF_SERIES(pbpctl_dev->subdevice)) ||
- (BP10G9_IF_SERIES(pbpctl_dev->subdevice))) {
- pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
- }
- if ((pbpctl_dev->subdevice & 0xa00) == 0xa00)
- pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
- if (PEG5_IF_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
-
- if (BP10GB_IF_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP);
-
- pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_m != NULL) {
- int cap_reg = 0;
- if (pbpctl_dev_m->bp_ext_ver >= 0x9) {
- cap_reg = get_bp_prod_caps(pbpctl_dev_m);
- if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
- DISC_PORT_SUPPORT_MASK)
- pbpctl_dev->bp_caps |=
- (TX_CTL_CAP | TX_STATUS_CAP);
- pbpctl_dev->bp_caps_ex |= DISC_PORT_CAP_EX;
- }
- }
-}
-
-static void remove_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
-{
-#ifdef BP_SELF_TEST
- struct bpctl_dev *pbpctl_dev_sl = NULL;
-#endif
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
-
- del_timer_sync(&pbpctl_dev->bp_timer);
-#ifdef BP_SELF_TEST
- pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
- if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) {
- if ((pbpctl_dev_sl->ndev->netdev_ops)
- && (pbpctl_dev_sl->old_ops)) {
- rtnl_lock();
- pbpctl_dev_sl->ndev->netdev_ops =
- pbpctl_dev_sl->old_ops;
- pbpctl_dev_sl->old_ops = NULL;
-
- rtnl_unlock();
-
- }
-
- }
-#endif
- }
-
-}
-
-static int init_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- init_timer(&pbpctl_dev->bp_timer);
- pbpctl_dev->bp_timer.function = &wd_reset_timer;
- pbpctl_dev->bp_timer.data = (unsigned long)pbpctl_dev;
- return 1;
- }
- return BP_NOT_CAP;
-}
-
-#ifdef BP_SELF_TEST
-int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct bpctl_dev *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
- int idx_dev = 0;
- struct ethhdr *eth = (struct ethhdr *)skb->data;
-
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].ndev != NULL) && (idx_dev < device_num));
- idx_dev++) {
- if (bpctl_dev_arr[idx_dev].ndev == dev) {
- pbpctl_dev = &bpctl_dev_arr[idx_dev];
- break;
- }
- }
- if (!pbpctl_dev)
- return 1;
- if ((htons(ETH_P_BPTEST) == eth->h_proto)) {
-
- pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_m) {
-
- if (bypass_status(pbpctl_dev_m)) {
- cmnd_on(pbpctl_dev_m);
- bypass_off(pbpctl_dev_m);
- cmnd_off(pbpctl_dev_m);
- }
- wdt_timer_reload(pbpctl_dev_m);
- }
- dev_kfree_skb_irq(skb);
- return 0;
- }
- return pbpctl_dev->hard_start_xmit_save(skb, dev);
-}
-#endif
-
-static int set_bypass_wd_auto(struct bpctl_dev *pbpctl_dev, unsigned int param)
-{
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- if (pbpctl_dev->reset_time != param) {
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- pbpctl_dev->reset_time =
- (param <
- WDT_AUTO_MIN_INT) ? WDT_AUTO_MIN_INT :
- param;
- else
- pbpctl_dev->reset_time = param;
- if (param)
- mod_timer(&pbpctl_dev->bp_timer, jiffies);
- }
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-static int get_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
-{
- if (pbpctl_dev->bp_caps & WD_CTL_CAP)
- return pbpctl_dev->reset_time;
-
- return BP_NOT_CAP;
-}
-
-#ifdef BP_SELF_TEST
-
-int set_bp_self_test(struct bpctl_dev *pbpctl_dev, unsigned int param)
-{
- struct bpctl_dev *pbpctl_dev_sl = NULL;
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1;
- pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
-
- if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) {
- rtnl_lock();
- if (pbpctl_dev->bp_self_test_flag == 1) {
-
- pbpctl_dev_sl->old_ops =
- pbpctl_dev_sl->ndev->netdev_ops;
- pbpctl_dev_sl->new_ops =
- *pbpctl_dev_sl->old_ops;
- pbpctl_dev_sl->new_ops.ndo_start_xmit =
- bp_hard_start_xmit;
- pbpctl_dev_sl->ndev->netdev_ops =
- &pbpctl_dev_sl->new_ops;
-
- } else if (pbpctl_dev_sl->old_ops) {
- pbpctl_dev_sl->ndev->netdev_ops =
- pbpctl_dev_sl->old_ops;
- pbpctl_dev_sl->old_ops = NULL;
- }
- rtnl_unlock();
- }
-
- set_bypass_wd_auto(pbpctl_dev, param);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-int get_bp_self_test(struct bpctl_dev *pbpctl_dev)
-{
-
- if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
- if (pbpctl_dev->bp_self_test_flag == 1)
- return pbpctl_dev->reset_time;
- else
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-#endif
-
-/**************************************************************/
-/************************* API ********************************/
-/**************************************************************/
-
-int is_bypass_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0);
-}
-
-static int set_bypass_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
-{
- int ret = 0;
-
- if (!(pbpctl_dev->bp_caps & BP_CAP))
- return BP_NOT_CAP;
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (!bypass_mode)
- ret = bypass_off(pbpctl_dev);
- else
- ret = bypass_on(pbpctl_dev);
- cmnd_off(pbpctl_dev);
-
- return ret;
-}
-
-static int get_bypass_fn(struct bpctl_dev *pbpctl_dev)
-{
- return bypass_status(pbpctl_dev);
-}
-
-static int get_bypass_change_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return bypass_change_status(pbpctl_dev);
-}
-
-static int set_dis_bypass_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (!(pbpctl_dev->bp_caps & BP_DIS_CAP))
- return BP_NOT_CAP;
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (dis_param)
- ret = dis_bypass_cap(pbpctl_dev);
- else
- ret = en_bypass_cap(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
-}
-
-static int get_dis_bypass_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return dis_bypass_cap_status(pbpctl_dev);
-}
-
-static int set_bypass_pwoff_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP))
- return BP_NOT_CAP;
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (bypass_mode)
- ret = bypass_state_pwroff(pbpctl_dev);
- else
- ret = normal_state_pwroff(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
-}
-
-static int get_bypass_pwoff_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return default_pwroff_status(pbpctl_dev);
-}
-
-static int set_bypass_pwup_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP))
- return BP_NOT_CAP;
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (bypass_mode)
- ret = bypass_state_pwron(pbpctl_dev);
- else
- ret = normal_state_pwron(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
-}
-
-static int get_bypass_pwup_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return default_pwron_status(pbpctl_dev);
-}
-
-static int set_bypass_wd_fn(struct bpctl_dev *pbpctl_dev, int timeout)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (!(pbpctl_dev->bp_caps & WD_CTL_CAP))
- return BP_NOT_CAP;
-
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (!timeout)
- ret = wdt_off(pbpctl_dev);
- else {
- wdt_on(pbpctl_dev, timeout);
- ret = pbpctl_dev->bypass_timer_interval;
- }
- cmnd_off(pbpctl_dev);
- return ret;
-}
-
-static int get_bypass_wd_fn(struct bpctl_dev *pbpctl_dev, int *timeout)
-{
- if (!pbpctl_dev)
- return -1;
-
- return wdt_programmed(pbpctl_dev, timeout);
-}
-
-static int get_wd_expire_time_fn(struct bpctl_dev *pbpctl_dev, int *time_left)
-{
- if (!pbpctl_dev)
- return -1;
-
- return wdt_timer(pbpctl_dev, time_left);
-}
-
-static int reset_bypass_wd_timer_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return wdt_timer_reload(pbpctl_dev);
-}
-
-static int get_wd_set_caps_fn(struct bpctl_dev *pbpctl_dev)
-{
- int bp_status = 0;
- unsigned int step_value = TIMEOUT_MAX_STEP + 1, bit_cnt = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
- return BP_NOT_CAP;
-
- while ((step_value >>= 1))
- bit_cnt++;
-
- if (is_bypass_fn(pbpctl_dev)) {
- bp_status =
- WD_STEP_COUNT_MASK(bit_cnt) | WDT_STEP_TIME |
- WD_MIN_TIME_MASK(TIMEOUT_UNIT / 100);
- } else
- return -1;
-
- return bp_status;
-}
-
-static int set_std_nic_fn(struct bpctl_dev *pbpctl_dev, int nic_mode)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if (!(pbpctl_dev->bp_caps & STD_NIC_CAP))
- return BP_NOT_CAP;
-
- ret = cmnd_on(pbpctl_dev);
- if (ret < 0)
- return ret;
- if (nic_mode)
- ret = std_nic_on(pbpctl_dev);
- else
- ret = std_nic_off(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
-}
-
-static int get_std_nic_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return std_nic_status(pbpctl_dev);
-}
-
-static int set_tap_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
-{
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & TAP_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (!tap_mode)
- tap_off(pbpctl_dev);
- else
- tap_on(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-static int get_tap_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return tap_status(pbpctl_dev);
-}
-
-static int set_tap_pwup_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)
- && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (tap_mode)
- ret = tap_state_pwron(pbpctl_dev);
- else
- ret = normal_state_pwron(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-static int get_tap_pwup_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ret = default_pwron_tap_status(pbpctl_dev);
- if (ret < 0)
- return ret;
- return ((ret == 0) ? 1 : 0);
-}
-
-static int get_tap_change_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return tap_change_status(pbpctl_dev);
-}
-
-static int set_dis_tap_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & TAP_DIS_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (dis_param)
- ret = dis_tap_cap(pbpctl_dev);
- else
- ret = en_tap_cap(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
- } else
- return BP_NOT_CAP;
-}
-
-static int get_dis_tap_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return dis_tap_cap_status(pbpctl_dev);
-}
-
-static int set_disc_fn(struct bpctl_dev *pbpctl_dev, int disc_mode)
-{
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & DISC_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (!disc_mode)
- disc_off(pbpctl_dev);
- else
- disc_on(pbpctl_dev);
- cmnd_off(pbpctl_dev);
-
- return BP_OK;
- }
- return BP_NOT_CAP;
-}
-
-static int get_disc_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ret = disc_status(pbpctl_dev);
-
- return ret;
-}
-
-static int set_disc_pwup_fn(struct bpctl_dev *pbpctl_dev, int disc_mode)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP)
- && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (disc_mode)
- ret = disc_state_pwron(pbpctl_dev);
- else
- ret = normal_state_pwron(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- } else
- ret = BP_NOT_CAP;
- return ret;
-}
-
-static int get_disc_pwup_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ret = default_pwron_disc_status(pbpctl_dev);
- return (ret == 0 ? 1 : (ret < 0 ? BP_NOT_CAP : 0));
-}
-
-static int get_disc_change_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ret = disc_change_status(pbpctl_dev);
- return ret;
-}
-
-static int set_dis_disc_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & DISC_DIS_CAP)
- && ((cmnd_on(pbpctl_dev)) >= 0)) {
- if (dis_param)
- ret = dis_disc_cap(pbpctl_dev);
- else
- ret = en_disc_cap(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- return ret;
- } else
- return BP_NOT_CAP;
-}
-
-static int get_dis_disc_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- ret = dis_disc_cap_status(pbpctl_dev);
-
- return ret;
-}
-
-static int get_wd_exp_mode_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return wdt_exp_mode_status(pbpctl_dev);
-}
-
-static int set_wd_exp_mode_fn(struct bpctl_dev *pbpctl_dev, int param)
-{
- if (!pbpctl_dev)
- return -1;
-
- return wdt_exp_mode(pbpctl_dev, param);
-}
-
-static int set_tx_fn(struct bpctl_dev *pbpctl_dev, int tx_state)
-{
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & TPL_CAP) &&
- (pbpctl_dev->bp_caps & SW_CTL_CAP)) {
- if ((pbpctl_dev->bp_tpl_flag))
- return BP_NOT_CAP;
- } else {
- pbpctl_dev_b = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_b &&
- (pbpctl_dev_b->bp_caps & TPL_CAP) &&
- (pbpctl_dev_b->bp_tpl_flag))
- return BP_NOT_CAP;
- }
- return set_tx(pbpctl_dev, tx_state);
-}
-
-static int set_bp_force_link_fn(int dev_num, int tx_state)
-{
- static struct bpctl_dev *bpctl_dev_curr;
-
- if ((dev_num < 0) || (dev_num > device_num)
- || (bpctl_dev_arr[dev_num].pdev == NULL))
- return -1;
- bpctl_dev_curr = &bpctl_dev_arr[dev_num];
-
- return set_bp_force_link(bpctl_dev_curr, tx_state);
-}
-
-static int set_wd_autoreset_fn(struct bpctl_dev *pbpctl_dev, int param)
-{
- if (!pbpctl_dev)
- return -1;
-
- return set_bypass_wd_auto(pbpctl_dev, param);
-}
-
-static int get_wd_autoreset_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return get_bypass_wd_auto(pbpctl_dev);
-}
-
-#ifdef BP_SELF_TEST
-int set_bp_self_test_fn(struct bpctl_dev *pbpctl_dev, int param)
-{
- if (!pbpctl_dev)
- return -1;
-
- return set_bp_self_test(pbpctl_dev, param);
-}
-
-int get_bp_self_test_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return get_bp_self_test(pbpctl_dev);
-}
-
-#endif
-
-static int get_bypass_caps_fn(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- return pbpctl_dev->bp_caps;
-
-}
-
-static int get_bypass_slave_fn(struct bpctl_dev *pbpctl_dev,
- struct bpctl_dev **pbpctl_dev_out)
-{
- int idx_dev = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) {
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL)
- && (idx_dev < device_num)); idx_dev++) {
- if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)
- && (bpctl_dev_arr[idx_dev].slot ==
- pbpctl_dev->slot)) {
- if ((pbpctl_dev->func == 0)
- && (bpctl_dev_arr[idx_dev].func == 1)) {
- *pbpctl_dev_out =
- &bpctl_dev_arr[idx_dev];
- return 1;
- }
- if ((pbpctl_dev->func == 2) &&
- (bpctl_dev_arr[idx_dev].func == 3)) {
- *pbpctl_dev_out =
- &bpctl_dev_arr[idx_dev];
- return 1;
- }
- }
- }
- return -1;
- } else
- return 0;
-}
-
-static int is_bypass(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2))
- return 1;
- else
- return 0;
-}
-
-static int get_tx_fn(struct bpctl_dev *pbpctl_dev)
-{
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- if (!pbpctl_dev)
- return -1;
-
- if ((pbpctl_dev->bp_caps & TPL_CAP) &&
- (pbpctl_dev->bp_caps & SW_CTL_CAP)) {
- if ((pbpctl_dev->bp_tpl_flag))
- return BP_NOT_CAP;
- } else {
- pbpctl_dev_b = get_master_port_fn(pbpctl_dev);
- if (pbpctl_dev_b &&
- (pbpctl_dev_b->bp_caps & TPL_CAP) &&
- (pbpctl_dev_b->bp_tpl_flag))
- return BP_NOT_CAP;
- }
- return tx_status(pbpctl_dev);
-}
-
-static int get_bp_force_link_fn(int dev_num)
-{
- static struct bpctl_dev *bpctl_dev_curr;
-
- if ((dev_num < 0) || (dev_num > device_num)
- || (bpctl_dev_arr[dev_num].pdev == NULL))
- return -1;
- bpctl_dev_curr = &bpctl_dev_arr[dev_num];
-
- return bp_force_link_status(bpctl_dev_curr);
-}
-
-static int get_bypass_link_status(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->media_type == BP_FIBER)
- return ((BPCTL_READ_REG(pbpctl_dev, CTRL) &
- BPCTLI_CTRL_SWDPIN1));
- else
- return ((BPCTL_READ_REG(pbpctl_dev, STATUS) &
- BPCTLI_STATUS_LU));
-
-}
-
-static void bp_tpl_timer_fn(unsigned long param)
-{
- struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) param;
- uint32_t link1, link2;
- struct bpctl_dev *pbpctl_dev_b = NULL;
-
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (!pbpctl_dev_b)
- return;
-
- if (!pbpctl_dev->bp_tpl_flag) {
- set_tx(pbpctl_dev_b, 1);
- set_tx(pbpctl_dev, 1);
- return;
- }
- link1 = get_bypass_link_status(pbpctl_dev);
-
- link2 = get_bypass_link_status(pbpctl_dev_b);
- if ((link1) && (tx_status(pbpctl_dev))) {
- if ((!link2) && (tx_status(pbpctl_dev_b)))
- set_tx(pbpctl_dev, 0);
- else if (!tx_status(pbpctl_dev_b))
- set_tx(pbpctl_dev_b, 1);
- } else if ((!link1) && (tx_status(pbpctl_dev))) {
- if ((link2) && (tx_status(pbpctl_dev_b)))
- set_tx(pbpctl_dev_b, 0);
- } else if ((link1) && (!tx_status(pbpctl_dev))) {
- if ((link2) && (tx_status(pbpctl_dev_b)))
- set_tx(pbpctl_dev, 1);
- } else if ((!link1) && (!tx_status(pbpctl_dev))) {
- if ((link2) && (tx_status(pbpctl_dev_b)))
- set_tx(pbpctl_dev, 1);
- }
-
- mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ);
-}
-
-static void remove_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev)
-{
- struct bpctl_dev *pbpctl_dev_b;
- if (!pbpctl_dev)
- return;
-
- if (pbpctl_dev->bp_caps & TPL_CAP) {
- del_timer_sync(&pbpctl_dev->bp_tpl_timer);
- pbpctl_dev->bp_tpl_flag = 0;
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (pbpctl_dev_b)
- set_tx(pbpctl_dev_b, 1);
- set_tx(pbpctl_dev, 1);
- }
- return;
-}
-
-static int init_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev)
-{
- if (!pbpctl_dev)
- return -1;
- if (pbpctl_dev->bp_caps & TPL_CAP) {
- init_timer(&pbpctl_dev->bp_tpl_timer);
- pbpctl_dev->bp_tpl_timer.function = &bp_tpl_timer_fn;
- pbpctl_dev->bp_tpl_timer.data = (unsigned long)pbpctl_dev;
- return BP_OK;
- }
- return BP_NOT_CAP;
-}
-
-static int set_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev, unsigned int param)
-{
- if (!pbpctl_dev)
- return -1;
- if (pbpctl_dev->bp_caps & TPL_CAP) {
- if ((param) && (!pbpctl_dev->bp_tpl_flag)) {
- pbpctl_dev->bp_tpl_flag = param;
- mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + 1);
- return BP_OK;
- }
- if ((!param) && (pbpctl_dev->bp_tpl_flag))
- remove_bypass_tpl_auto(pbpctl_dev);
-
- return BP_OK;
- }
- return BP_NOT_CAP;
-}
-
-static int set_tpl_fn(struct bpctl_dev *pbpctl_dev, int tpl_mode)
-{
-
- struct bpctl_dev *pbpctl_dev_b;
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_caps & TPL_CAP) {
- if (tpl_mode) {
- pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
- if (pbpctl_dev_b)
- set_tx(pbpctl_dev_b, 1);
- set_tx(pbpctl_dev, 1);
- }
- if ((TPL_IF_SERIES(pbpctl_dev->subdevice)) ||
- (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)) {
- pbpctl_dev->bp_tpl_flag = tpl_mode;
- if (!tpl_mode)
- tpl_hw_off(pbpctl_dev);
- else
- tpl_hw_on(pbpctl_dev);
- } else
- set_bypass_tpl_auto(pbpctl_dev, tpl_mode);
- return 0;
- }
- return BP_NOT_CAP;
-}
-
-static int get_tpl_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = BP_NOT_CAP;
-
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_caps & TPL_CAP) {
- if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)
- return tpl2_flag_status(pbpctl_dev);
- ret = pbpctl_dev->bp_tpl_flag;
- }
- return ret;
-}
-
-static int set_bp_wait_at_pwup_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
-{
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- /* bp_lock(pbp_device_block); */
- cmnd_on(pbpctl_dev);
- if (!tap_mode)
- bp_wait_at_pwup_dis(pbpctl_dev);
- else
- bp_wait_at_pwup_en(pbpctl_dev);
- cmnd_off(pbpctl_dev);
-
- /* bp_unlock(pbp_device_block); */
- return BP_OK;
- }
- return BP_NOT_CAP;
-}
-
-static int get_bp_wait_at_pwup_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- /* bp_lock(pbp_device_block); */
- ret = bp_wait_at_pwup_status(pbpctl_dev);
- /* bp_unlock(pbp_device_block); */
-
- return ret;
-}
-
-static int set_bp_hw_reset_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
-{
- if (!pbpctl_dev)
- return -1;
-
- if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
- /* bp_lock(pbp_device_block); */
- cmnd_on(pbpctl_dev);
-
- if (!tap_mode)
- bp_hw_reset_dis(pbpctl_dev);
- else
- bp_hw_reset_en(pbpctl_dev);
- cmnd_off(pbpctl_dev);
- /* bp_unlock(pbp_device_block); */
- return BP_OK;
- }
- return BP_NOT_CAP;
-}
-
-static int get_bp_hw_reset_fn(struct bpctl_dev *pbpctl_dev)
-{
- int ret = 0;
-
- if (!pbpctl_dev)
- return -1;
-
- /* bp_lock(pbp_device_block); */
- ret = bp_hw_reset_status(pbpctl_dev);
-
- /* bp_unlock(pbp_device_block); */
-
- return ret;
-}
-
-
-static int get_bypass_info_fn(struct bpctl_dev *pbpctl_dev, char *dev_name,
- char *add_param)
-{
- if (!pbpctl_dev)
- return -1;
- if (!is_bypass_fn(pbpctl_dev))
- return -1;
- strcpy(dev_name, pbpctl_dev->name);
- *add_param = pbpctl_dev->bp_fw_ver;
- return 0;
-}
-
-static int get_dev_idx_bsf(int bus, int slot, int func)
-{
- int idx_dev = 0;
-
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
- idx_dev++) {
- if ((bus == bpctl_dev_arr[idx_dev].bus)
- && (slot == bpctl_dev_arr[idx_dev].slot)
- && (func == bpctl_dev_arr[idx_dev].func))
-
- return idx_dev;
- }
- return -1;
-}
-
-static int get_dev_idx(int ifindex)
-{
- int idx_dev = 0;
-
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
- idx_dev++) {
- if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
- return idx_dev;
- }
-
- return -1;
-}
-
-static struct bpctl_dev *get_dev_idx_p(int ifindex)
-{
- int idx_dev = 0;
-
- for (idx_dev = 0;
- ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
- idx_dev++) {
- if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
- return &bpctl_dev_arr[idx_dev];
- }
-
- return NULL;
-}
-
-static void if_scan_init(void)
-{
- struct net_device *dev;
-
- /* rcu_read_lock(); */
- /* rtnl_lock(); */
- /* rcu_read_lock(); */
-
- for_each_netdev(&init_net, dev) {
- int idx_dev;
-
- if (bp_get_dev_idx_bsf(dev, &idx_dev))
- continue;
-
- if (idx_dev == -1)
- continue;
-
- bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
- bpctl_dev_arr[idx_dev].ndev = dev;
- }
- /* rtnl_unlock(); */
- /* rcu_read_unlock(); */
-}
-
-static long device_ioctl(struct file *file, /* see include/linux/fs.h */
- unsigned int ioctl_num, /* number and param for ioctl */
- unsigned long ioctl_param)
-{
- struct bpctl_cmd bpctl_cmd;
- int dev_idx = 0;
- struct bpctl_dev *pbpctl_dev_out;
- void __user *argp = (void __user *)ioctl_param;
- int ret = 0;
- unsigned long flags;
-
- static struct bpctl_dev *pbpctl_dev;
-
- /* lock_kernel(); */
- if (down_interruptible(&bpctl_sema))
- return -ERESTARTSYS;
- /* local_irq_save(flags); */
- /* if(!spin_trylock_irqsave(&bpvm_lock)){
- local_irq_restore(flags);
- unlock_bpctl();
- unlock_kernel();
- return -1;
- } */
- /* spin_lock_irqsave(&bpvm_lock, flags); */
-
-/*
-* Switch according to the ioctl called
-*/
- if (ioctl_num == IOCTL_TX_MSG(IF_SCAN)) {
- if_scan_init();
- ret = SUCCESS;
- goto bp_exit;
- }
- if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) {
-
- ret = -EFAULT;
- goto bp_exit;
- }
-
- if (ioctl_num == IOCTL_TX_MSG(GET_DEV_NUM)) {
- bpctl_cmd.out_param[0] = device_num;
- if (copy_to_user
- (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
- ret = -EFAULT;
- goto bp_exit;
- }
- ret = SUCCESS;
- goto bp_exit;
-
- }
- /* lock_bpctl(); */
- /* preempt_disable(); */
- local_irq_save(flags);
- if (!spin_trylock(&bpvm_lock)) {
- local_irq_restore(flags);
- unlock_bpctl();
- return -1;
- }
-
-/* preempt_disable();
- rcu_read_lock();
- spin_lock_irqsave(&bpvm_lock, flags);
-*/
- if ((bpctl_cmd.in_param[5]) ||
- (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7]))
- dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5],
- bpctl_cmd.in_param[6],
- bpctl_cmd.in_param[7]);
- else if (bpctl_cmd.in_param[1] == 0)
- dev_idx = bpctl_cmd.in_param[0];
- else
- dev_idx = get_dev_idx(bpctl_cmd.in_param[1]);
-
- if (dev_idx < 0 || dev_idx > device_num) {
- /* unlock_bpctl();
- preempt_enable(); */
- ret = -EOPNOTSUPP;
- /* preempt_enable();
- rcu_read_unlock(); */
- spin_unlock_irqrestore(&bpvm_lock, flags);
- goto bp_exit;
- }
-
- bpctl_cmd.out_param[0] = bpctl_dev_arr[dev_idx].bus;
- bpctl_cmd.out_param[1] = bpctl_dev_arr[dev_idx].slot;
- bpctl_cmd.out_param[2] = bpctl_dev_arr[dev_idx].func;
- bpctl_cmd.out_param[3] = bpctl_dev_arr[dev_idx].ifindex;
-
- if ((bpctl_dev_arr[dev_idx].bp_10gb)
- && (!(bpctl_dev_arr[dev_idx].ifindex))) {
- printk("Please load network driver for %s adapter!\n",
- bpctl_dev_arr[dev_idx].name);
- bpctl_cmd.status = -1;
- ret = SUCCESS;
- /* preempt_enable(); */
- /* rcu_read_unlock(); */
- spin_unlock_irqrestore(&bpvm_lock, flags);
- goto bp_exit;
-
- }
- if ((bpctl_dev_arr[dev_idx].bp_10gb) && (bpctl_dev_arr[dev_idx].ndev)) {
- if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
- if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
- printk
- ("Please bring up network interfaces for %s adapter!\n",
- bpctl_dev_arr[dev_idx].name);
- bpctl_cmd.status = -1;
- ret = SUCCESS;
- /* preempt_enable(); */
- /* rcu_read_unlock(); */
- spin_unlock_irqrestore(&bpvm_lock, flags);
- goto bp_exit;
- }
-
- }
- }
-
- if ((dev_idx < 0) || (dev_idx > device_num)
- || (bpctl_dev_arr[dev_idx].pdev == NULL)) {
- bpctl_cmd.status = -1;
- goto bpcmd_exit;
- }
-
- pbpctl_dev = &bpctl_dev_arr[dev_idx];
-
- switch (ioctl_num) {
- case IOCTL_TX_MSG(SET_BYPASS_PWOFF):
- bpctl_cmd.status =
- set_bypass_pwoff_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_PWOFF):
- bpctl_cmd.status = get_bypass_pwoff_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_BYPASS_PWUP):
- bpctl_cmd.status =
- set_bypass_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_PWUP):
- bpctl_cmd.status = get_bypass_pwup_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_BYPASS_WD):
- bpctl_cmd.status =
- set_bypass_wd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_WD):
- bpctl_cmd.status =
- get_bypass_wd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0]));
- break;
-
- case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME):
- bpctl_cmd.status =
- get_wd_expire_time_fn(pbpctl_dev,
- (int *)&(bpctl_cmd.data[0]));
- break;
-
- case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER):
- bpctl_cmd.status = reset_bypass_wd_timer_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(GET_WD_SET_CAPS):
- bpctl_cmd.status = get_wd_set_caps_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_STD_NIC):
- bpctl_cmd.status =
- set_std_nic_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_STD_NIC):
- bpctl_cmd.status = get_std_nic_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_TAP):
- bpctl_cmd.status =
- set_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_TAP):
- bpctl_cmd.status = get_tap_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(GET_TAP_CHANGE):
- bpctl_cmd.status = get_tap_change_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_DIS_TAP):
- bpctl_cmd.status =
- set_dis_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_DIS_TAP):
- bpctl_cmd.status = get_dis_tap_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_TAP_PWUP):
- bpctl_cmd.status =
- set_tap_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_TAP_PWUP):
- bpctl_cmd.status = get_tap_pwup_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_WD_EXP_MODE):
- bpctl_cmd.status =
- set_wd_exp_mode_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_WD_EXP_MODE):
- bpctl_cmd.status = get_wd_exp_mode_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(GET_DIS_BYPASS):
- bpctl_cmd.status = get_dis_bypass_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_DIS_BYPASS):
- bpctl_cmd.status =
- set_dis_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_CHANGE):
- bpctl_cmd.status = get_bypass_change_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS):
- bpctl_cmd.status = get_bypass_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_BYPASS):
- bpctl_cmd.status =
- set_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_CAPS):
- bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev);
- /*preempt_enable(); */
- /*rcu_read_unlock();*/
- spin_unlock_irqrestore(&bpvm_lock, flags);
- if (copy_to_user
- (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
- /*unlock_bpctl(); */
- /*preempt_enable(); */
- ret = -EFAULT;
- goto bp_exit;
- }
- goto bp_exit;
-
- case IOCTL_TX_MSG(GET_BYPASS_SLAVE):
- bpctl_cmd.status =
- get_bypass_slave_fn(pbpctl_dev, &pbpctl_dev_out);
- if (bpctl_cmd.status == 1) {
- bpctl_cmd.out_param[4] = pbpctl_dev_out->bus;
- bpctl_cmd.out_param[5] = pbpctl_dev_out->slot;
- bpctl_cmd.out_param[6] = pbpctl_dev_out->func;
- bpctl_cmd.out_param[7] = pbpctl_dev_out->ifindex;
- }
- break;
-
- case IOCTL_TX_MSG(IS_BYPASS):
- bpctl_cmd.status = is_bypass(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_TX):
- bpctl_cmd.status = set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
- case IOCTL_TX_MSG(GET_TX):
- bpctl_cmd.status = get_tx_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_WD_AUTORESET):
- bpctl_cmd.status =
- set_wd_autoreset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
-
- break;
- case IOCTL_TX_MSG(GET_WD_AUTORESET):
-
- bpctl_cmd.status = get_wd_autoreset_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_DISC):
- bpctl_cmd.status =
- set_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
- case IOCTL_TX_MSG(GET_DISC):
- bpctl_cmd.status = get_disc_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(GET_DISC_CHANGE):
- bpctl_cmd.status = get_disc_change_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_DIS_DISC):
- bpctl_cmd.status =
- set_dis_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
- case IOCTL_TX_MSG(GET_DIS_DISC):
- bpctl_cmd.status = get_dis_disc_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_DISC_PWUP):
- bpctl_cmd.status =
- set_disc_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
- case IOCTL_TX_MSG(GET_DISC_PWUP):
- bpctl_cmd.status = get_disc_pwup_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(GET_BYPASS_INFO):
-
- bpctl_cmd.status =
- get_bypass_info_fn(pbpctl_dev, (char *)&bpctl_cmd.data,
- (char *)&bpctl_cmd.out_param[4]);
- break;
-
- case IOCTL_TX_MSG(SET_TPL):
- bpctl_cmd.status =
- set_tpl_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_TPL):
- bpctl_cmd.status = get_tpl_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP):
- bpctl_cmd.status =
- set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP):
- bpctl_cmd.status = get_bp_wait_at_pwup_fn(pbpctl_dev);
- break;
- case IOCTL_TX_MSG(SET_BP_HW_RESET):
- bpctl_cmd.status =
- set_bp_hw_reset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BP_HW_RESET):
- bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev);
- break;
-#ifdef BP_SELF_TEST
- case IOCTL_TX_MSG(SET_BP_SELF_TEST):
- bpctl_cmd.status =
- set_bp_self_test_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
-
- break;
- case IOCTL_TX_MSG(GET_BP_SELF_TEST):
- bpctl_cmd.status = get_bp_self_test_fn(pbpctl_dev);
- break;
-
-#endif
-#if 0
- case IOCTL_TX_MSG(SET_DISC_PORT):
- bpctl_cmd.status =
- set_disc_port_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_DISC_PORT):
- bpctl_cmd.status = get_disc_port_fn(pbpctl_dev);
- break;
-
- case IOCTL_TX_MSG(SET_DISC_PORT_PWUP):
- bpctl_cmd.status =
- set_disc_port_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_DISC_PORT_PWUP):
- bpctl_cmd.status = get_disc_port_pwup_fn(pbpctl_dev);
- break;
-#endif
- case IOCTL_TX_MSG(SET_BP_FORCE_LINK):
- bpctl_cmd.status =
- set_bp_force_link_fn(dev_idx, bpctl_cmd.in_param[2]);
- break;
-
- case IOCTL_TX_MSG(GET_BP_FORCE_LINK):
- bpctl_cmd.status = get_bp_force_link_fn(dev_idx);
- break;
-
- default:
- /* unlock_bpctl(); */
-
- ret = -EOPNOTSUPP;
- /* preempt_enable(); */
- /* rcu_read_unlock();*/
- spin_unlock_irqrestore(&bpvm_lock, flags);
- goto bp_exit;
- }
- /* unlock_bpctl(); */
- /* preempt_enable(); */
- bpcmd_exit:
- /* rcu_read_unlock(); */
- spin_unlock_irqrestore(&bpvm_lock, flags);
- if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd)))
- ret = -EFAULT;
- ret = SUCCESS;
- bp_exit:
- /* unlock_kernel(); */
- /* spin_unlock_irqrestore(&bpvm_lock, flags); */
- unlock_bpctl();
- /* unlock_kernel(); */
- return ret;
-}
-
-static const struct file_operations Fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = device_ioctl,
-};
-
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend, dev) \
- .vendor = (vend), .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif
-
-#define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\
- PCI_DEVICE(SILICOM_VID, device_id)}
-
-enum board_type {
- PXG2BPFI,
- PXG2BPFIL,
- PXG2BPFILX,
- PXG2BPFILLX,
- PXGBPI,
- PXGBPIG,
- PXG2TBFI,
- PXG4BPI,
- PXG4BPFI,
- PEG4BPI,
- PEG2BPI,
- PEG4BPIN,
- PEG2BPFI,
- PEG2BPFILX,
- PMCXG2BPFI,
- PMCXG2BPFIN,
- PEG4BPII,
- PEG4BPFII,
- PXG4BPFILX,
- PMCXG2BPIN,
- PMCXG4BPIN,
- PXG2BISC1,
- PEG2TBFI,
- PXG2TBI,
- PXG4BPFID,
- PEG4BPFI,
- PEG4BPIPT,
- PXG6BPI,
- PEG4BPIL,
- PMCXG2BPIN2,
- PMCXG4BPIN2,
- PMCX2BPI,
- PEG2BPFID,
- PEG2BPFIDLX,
- PMCX4BPI,
- MEG2BPFILN,
- MEG2BPFINX,
- PEG4BPFILX,
- PE10G2BPISR,
- PE10G2BPILR,
- MHIO8AD,
- PE10G2BPICX4,
- PEG2BPI5,
- PEG6BPI,
- PEG4BPFI5,
- PEG4BPFI5LX,
- MEG2BPFILXLN,
- PEG2BPIX1,
- MEG2BPFILXNX,
- XE10G2BPIT,
- XE10G2BPICX4,
- XE10G2BPISR,
- XE10G2BPILR,
- PEG4BPIIO,
- XE10G2BPIXR,
- PE10GDBISR,
- PE10GDBILR,
- PEG2BISC6,
- PEG6BPIFC,
- PE10G2BPTCX4,
- PE10G2BPTSR,
- PE10G2BPTLR,
- PE10G2BPTT,
- PEG4BPI6,
- PEG4BPFI6,
- PEG4BPFI6LX,
- PEG4BPFI6ZX,
- PEG2BPI6,
- PEG2BPFI6,
- PEG2BPFI6LX,
- PEG2BPFI6ZX,
- PEG2BPFI6FLXM,
- PEG4BPI6FC,
- PEG4BPFI6FC,
- PEG4BPFI6FCLX,
- PEG4BPFI6FCZX,
- PEG6BPI6,
- PEG2BPI6SC6,
- MEG2BPI6,
- XEG2BPI6,
- MEG4BPI6,
- PEG2BPFI5,
- PEG2BPFI5LX,
- PXEG4BPFI,
- M1EG2BPI6,
- M1EG2BPFI6,
- M1EG2BPFI6LX,
- M1EG2BPFI6ZX,
- M1EG4BPI6,
- M1EG4BPFI6,
- M1EG4BPFI6LX,
- M1EG4BPFI6ZX,
- M1EG6BPI6,
- M1E2G4BPi80,
- M1E2G4BPFi80,
- M1E2G4BPFi80LX,
- M1E2G4BPFi80ZX,
- PE210G2SPI9,
- M1E10G2BPI9CX4,
- M1E10G2BPI9SR,
- M1E10G2BPI9LR,
- M1E10G2BPI9T,
- PE210G2BPI9CX4,
- PE210G2BPI9SR,
- PE210G2BPI9LR,
- PE210G2BPI9T,
- M2EG2BPFI6,
- M2EG2BPFI6LX,
- M2EG2BPFI6ZX,
- M2EG4BPI6,
- M2EG4BPFI6,
- M2EG4BPFI6LX,
- M2EG4BPFI6ZX,
- M2EG6BPI6,
- PEG2DBI6,
- PEG2DBFI6,
- PEG2DBFI6LX,
- PEG2DBFI6ZX,
- PE2G4BPi80,
- PE2G4BPFi80,
- PE2G4BPFi80LX,
- PE2G4BPFi80ZX,
- PE2G4BPi80L,
- M6E2G8BPi80A,
-
- PE2G2BPi35,
- PAC1200BPi35,
- PE2G2BPFi35,
- PE2G2BPFi35LX,
- PE2G2BPFi35ZX,
- PE2G4BPi35,
- PE2G4BPi35L,
- PE2G4BPFi35,
- PE2G4BPFi35LX,
- PE2G4BPFi35ZX,
-
- PE2G6BPi35,
- PE2G6BPi35CX,
-
- PE2G2BPi80,
- PE2G2BPFi80,
- PE2G2BPFi80LX,
- PE2G2BPFi80ZX,
- M2E10G2BPI9CX4,
- M2E10G2BPI9SR,
- M2E10G2BPI9LR,
- M2E10G2BPI9T,
- M6E2G8BPi80,
- PE210G2DBi9SR,
- PE210G2DBi9SRRB,
- PE210G2DBi9LR,
- PE210G2DBi9LRRB,
- PE310G4DBi940SR,
- PE310G4BPi9T,
- PE310G4BPi9SR,
- PE310G4BPi9LR,
- PE210G2BPi40,
-};
-
-struct bpmod_info {
- unsigned int vendor;
- unsigned int device;
- unsigned int subvendor;
- unsigned int subdevice;
- unsigned int index;
- char *bp_name;
-
-};
-
-struct {
- char *name;
-} dev_desc[] = {
- {"Silicom Bypass PXG2BPFI-SD series adapter"},
- {"Silicom Bypass PXG2BPFIL-SD series adapter"},
- {"Silicom Bypass PXG2BPFILX-SD series adapter"},
- {"Silicom Bypass PXG2BPFILLX-SD series adapter"},
- {"Silicom Bypass PXG2BPI-SD series adapter"},
- {"Silicom Bypass PXG2BPIG-SD series adapter"},
- {"Silicom Bypass PXG2TBFI-SD series adapter"},
- {"Silicom Bypass PXG4BPI-SD series adapter"},
- {"Silicom Bypass PXG4BPFI-SD series adapter"},
- {"Silicom Bypass PEG4BPI-SD series adapter"},
- {"Silicom Bypass PEG2BPI-SD series adapter"},
- {"Silicom Bypass PEG4BPIN-SD series adapter"},
- {"Silicom Bypass PEG2BPFI-SD series adapter"},
- {"Silicom Bypass PEG2BPFI-LX-SD series adapter"},
- {"Silicom Bypass PMCX2BPFI-SD series adapter"},
- {"Silicom Bypass PMCX2BPFI-N series adapter"},
- {"Intel Bypass PEG2BPII series adapter"},
- {"Intel Bypass PEG2BPFII series adapter"},
- {"Silicom Bypass PXG4BPFILX-SD series adapter"},
- {"Silicom Bypass PMCX2BPI-N series adapter"},
- {"Silicom Bypass PMCX4BPI-N series adapter"},
- {"Silicom Bypass PXG2BISC1-SD series adapter"},
- {"Silicom Bypass PEG2TBFI-SD series adapter"},
- {"Silicom Bypass PXG2TBI-SD series adapter"},
- {"Silicom Bypass PXG4BPFID-SD series adapter"},
- {"Silicom Bypass PEG4BPFI-SD series adapter"},
- {"Silicom Bypass PEG4BPIPT-SD series adapter"},
- {"Silicom Bypass PXG6BPI-SD series adapter"},
- {"Silicom Bypass PEG4BPIL-SD series adapter"},
- {"Silicom Bypass PMCX2BPI-N2 series adapter"},
- {"Silicom Bypass PMCX4BPI-N2 series adapter"},
- {"Silicom Bypass PMCX2BPI-SD series adapter"},
- {"Silicom Bypass PEG2BPFID-SD series adapter"},
- {"Silicom Bypass PEG2BPFIDLX-SD series adapter"},
- {"Silicom Bypass PMCX4BPI-SD series adapter"},
- {"Silicom Bypass MEG2BPFILN-SD series adapter"},
- {"Silicom Bypass MEG2BPFINX-SD series adapter"},
- {"Silicom Bypass PEG4BPFILX-SD series adapter"},
- {"Silicom Bypass PE10G2BPISR-SD series adapter"},
- {"Silicom Bypass PE10G2BPILR-SD series adapter"},
- {"Silicom Bypass MHIO8AD-SD series adapter"},
- {"Silicom Bypass PE10G2BPICX4-SD series adapter"},
- {"Silicom Bypass PEG2BPI5-SD series adapter"},
- {"Silicom Bypass PEG6BPI5-SD series adapter"},
- {"Silicom Bypass PEG4BPFI5-SD series adapter"},
- {"Silicom Bypass PEG4BPFI5LX-SD series adapter"},
- {"Silicom Bypass MEG2BPFILXLN-SD series adapter"},
- {"Silicom Bypass PEG2BPIX1-SD series adapter"},
- {"Silicom Bypass MEG2BPFILXNX-SD series adapter"},
- {"Silicom Bypass XE10G2BPIT-SD series adapter"},
- {"Silicom Bypass XE10G2BPICX4-SD series adapter"},
- {"Silicom Bypass XE10G2BPISR-SD series adapter"},
- {"Silicom Bypass XE10G2BPILR-SD series adapter"},
- {"Intel Bypass PEG2BPFII0 series adapter"},
- {"Silicom Bypass XE10G2BPIXR series adapter"},
- {"Silicom Bypass PE10G2DBISR series adapter"},
- {"Silicom Bypass PEG2BI5SC6 series adapter"},
- {"Silicom Bypass PEG6BPI5FC series adapter"},
-
- {"Silicom Bypass PE10G2BPTCX4 series adapter"},
- {"Silicom Bypass PE10G2BPTSR series adapter"},
- {"Silicom Bypass PE10G2BPTLR series adapter"},
- {"Silicom Bypass PE10G2BPTT series adapter"},
- {"Silicom Bypass PEG4BPI6 series adapter"},
- {"Silicom Bypass PEG4BPFI6 series adapter"},
- {"Silicom Bypass PEG4BPFI6LX series adapter"},
- {"Silicom Bypass PEG4BPFI6ZX series adapter"},
- {"Silicom Bypass PEG2BPI6 series adapter"},
- {"Silicom Bypass PEG2BPFI6 series adapter"},
- {"Silicom Bypass PEG2BPFI6LX series adapter"},
- {"Silicom Bypass PEG2BPFI6ZX series adapter"},
- {"Silicom Bypass PEG2BPFI6FLXM series adapter"},
- {"Silicom Bypass PEG4BPI6FC series adapter"},
- {"Silicom Bypass PEG4BPFI6FC series adapter"},
- {"Silicom Bypass PEG4BPFI6FCLX series adapter"},
- {"Silicom Bypass PEG4BPFI6FCZX series adapter"},
- {"Silicom Bypass PEG6BPI6 series adapter"},
- {"Silicom Bypass PEG2BPI6SC6 series adapter"},
- {"Silicom Bypass MEG2BPI6 series adapter"},
- {"Silicom Bypass XEG2BPI6 series adapter"},
- {"Silicom Bypass MEG4BPI6 series adapter"},
- {"Silicom Bypass PEG2BPFI5-SD series adapter"},
- {"Silicom Bypass PEG2BPFI5LX-SD series adapter"},
- {"Silicom Bypass PXEG4BPFI-SD series adapter"},
- {"Silicom Bypass MxEG2BPI6 series adapter"},
- {"Silicom Bypass MxEG2BPFI6 series adapter"},
- {"Silicom Bypass MxEG2BPFI6LX series adapter"},
- {"Silicom Bypass MxEG2BPFI6ZX series adapter"},
- {"Silicom Bypass MxEG4BPI6 series adapter"},
- {"Silicom Bypass MxEG4BPFI6 series adapter"},
- {"Silicom Bypass MxEG4BPFI6LX series adapter"},
- {"Silicom Bypass MxEG4BPFI6ZX series adapter"},
- {"Silicom Bypass MxEG6BPI6 series adapter"},
- {"Silicom Bypass MxE2G4BPi80 series adapter"},
- {"Silicom Bypass MxE2G4BPFi80 series adapter"},
- {"Silicom Bypass MxE2G4BPFi80LX series adapter"},
- {"Silicom Bypass MxE2G4BPFi80ZX series adapter"},
-
- {"Silicom Bypass PE210G2SPI9 series adapter"},
-
- {"Silicom Bypass MxE210G2BPI9CX4 series adapter"},
- {"Silicom Bypass MxE210G2BPI9SR series adapter"},
- {"Silicom Bypass MxE210G2BPI9LR series adapter"},
- {"Silicom Bypass MxE210G2BPI9T series adapter"},
-
- {"Silicom Bypass PE210G2BPI9CX4 series adapter"},
- {"Silicom Bypass PE210G2BPI9SR series adapter"},
- {"Silicom Bypass PE210G2BPI9LR series adapter"},
- {"Silicom Bypass PE210G2BPI9T series adapter"},
-
- {"Silicom Bypass M2EG2BPFI6 series adapter"},
- {"Silicom Bypass M2EG2BPFI6LX series adapter"},
- {"Silicom Bypass M2EG2BPFI6ZX series adapter"},
- {"Silicom Bypass M2EG4BPI6 series adapter"},
- {"Silicom Bypass M2EG4BPFI6 series adapter"},
- {"Silicom Bypass M2EG4BPFI6LX series adapter"},
- {"Silicom Bypass M2EG4BPFI6ZX series adapter"},
- {"Silicom Bypass M2EG6BPI6 series adapter"},
-
- {"Silicom Bypass PEG2DBI6 series adapter"},
- {"Silicom Bypass PEG2DBFI6 series adapter"},
- {"Silicom Bypass PEG2DBFI6LX series adapter"},
- {"Silicom Bypass PEG2DBFI6ZX series adapter"},
-
- {"Silicom Bypass PE2G4BPi80 series adapter"},
- {"Silicom Bypass PE2G4BPFi80 series adapter"},
- {"Silicom Bypass PE2G4BPFi80LX series adapter"},
- {"Silicom Bypass PE2G4BPFi80ZX series adapter"},
-
- {"Silicom Bypass PE2G4BPi80L series adapter"},
- {"Silicom Bypass MxE2G8BPi80A series adapter"},
-
- {"Silicom Bypass PE2G2BPi35 series adapter"},
- {"Silicom Bypass PAC1200BPi35 series adapter"},
- {"Silicom Bypass PE2G2BPFi35 series adapter"},
- {"Silicom Bypass PE2G2BPFi35LX series adapter"},
- {"Silicom Bypass PE2G2BPFi35ZX series adapter"},
-
- {"Silicom Bypass PE2G4BPi35 series adapter"},
- {"Silicom Bypass PE2G4BPi35L series adapter"},
- {"Silicom Bypass PE2G4BPFi35 series adapter"},
- {"Silicom Bypass PE2G4BPFi35LX series adapter"},
- {"Silicom Bypass PE2G4BPFi35ZX series adapter"},
-
- {"Silicom Bypass PE2G6BPi35 series adapter"},
- {"Silicom Bypass PE2G6BPi35CX series adapter"},
-
- {"Silicom Bypass PE2G2BPi80 series adapter"},
- {"Silicom Bypass PE2G2BPFi80 series adapter"},
- {"Silicom Bypass PE2G2BPFi80LX series adapter"},
- {"Silicom Bypass PE2G2BPFi80ZX series adapter"},
-
- {"Silicom Bypass M2E10G2BPI9CX4 series adapter"},
- {"Silicom Bypass M2E10G2BPI9SR series adapter"},
- {"Silicom Bypass M2E10G2BPI9LR series adapter"},
- {"Silicom Bypass M2E10G2BPI9T series adapter"},
- {"Silicom Bypass MxE2G8BPi80 series adapter"},
- {"Silicom Bypass PE210G2DBi9SR series adapter"},
- {"Silicom Bypass PE210G2DBi9SRRB series adapter"},
- {"Silicom Bypass PE210G2DBi9LR series adapter"},
- {"Silicom Bypass PE210G2DBi9LRRB series adapter"},
- {"Silicom Bypass PE310G4DBi9-SR series adapter"},
- {"Silicom Bypass PE310G4BPi9T series adapter"},
- {"Silicom Bypass PE310G4BPi9SR series adapter"},
- {"Silicom Bypass PE310G4BPi9LR series adapter"},
- {"Silicom Bypass PE210G2BPi40T series adapter"},
- {0},
-};
-
-static struct bpmod_info tx_ctl_pci_tbl[] = {
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI,
- "PXG2BPFI-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL,
- "PXG2BPFIL-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX,
- "PXG2BPFILX-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX,
- "PXG2BPFILLXSD"},
- {0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI,
- "PXG2BPI-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG,
- "PXG2BPIG-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI,
- "PXG2TBFI-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
- "PXG4BPI-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
- "PXG4BPFI-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX,
- "PXG4BPFILX-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI,
- "PEXG4BPI-SD"},
- {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI,
- "PEG2BPI-SD"},
- {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN,
- "PEG4BPI-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI,
- "PEG2BPFI-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX,
- "PEG2BPFILX-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI,
- "PMCX2BPFI-SD"},
- {0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID,
- PMCXG2BPFIN, "PMCX2BPFI-N"},
- {0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII,
- "PEG4BPII"},
- {0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO,
- "PEG4BPII0"},
- {0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII,
- "PEG4BPFII"},
- {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID,
- PMCXG2BPIN, "PMCX2BPI-N"},
- {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID,
- PMCXG4BPIN, "PMCX4BPI-N"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
- "PXG2BISC1-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI,
- "PEG2TBFI-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
- "PXG2TBI-SD"},
- {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID,
- "PXG4BPFID-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
- "PEG4BPFI-SD"},
- {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT,
- "PEG4BPIPT-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI,
- "PXG6BPI-SD"},
- {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"},
- {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID,
- PMCXG2BPIN2, "PMCX2BPI-N2"},
- {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID,
- PMCXG4BPIN2, "PMCX4BPI-N2"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI,
- "PMCX2BPI-SD"},
- {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI,
- "PMCX4BPI-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID,
- "PEG2BPFID-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX,
- "PEG2BPFIDLXSD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN,
- "MEG2BPFILN-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX,
- "MEG2BPFINX-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX,
- "PEG4BPFILX-SD"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID,
- PE10G2BPISR, "PE10G2BPISR"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID,
- PE10G2BPILR, "PE10G2BPILR"},
- {0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD,
- "MHIO8AD-SD"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID,
- PE10G2BPISR, "PE10G2BPICX4"},
- {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"},
- {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"},
- {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID,
- PEG4BPFI5, "PEG4BPFI5"},
- {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN,
- "MEG2BPFILXLN"},
- {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1,
- "PEG2BPIX1-SD"},
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX,
- "MEG2BPFILXNX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT,
- "XE10G2BPIT"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID,
- XE10G2BPICX4, "XE10G2BPICX4"},
- {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR,
- "XE10G2BPISR"},
- {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR,
- "XE10G2BPILR"},
- {0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID,
- XE10G2BPIXR, "XE10G2BPIXR"},
- {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR,
- "PE10G2DBISR"},
- {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR,
- "PE10G2DBILR"},
- {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"},
- {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"},
-
- {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
- SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"},
- {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
- SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"},
- {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
- SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"},
- {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
- SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"},
-
- /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */
-
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"},
- {0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM,
- "PEG2BPFI6FLXM"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX,
- "PEG4BPFI6FCLX"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX,
- "PEG4BPFI6FCZX"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6,
- "PEG6BPI62SC6"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"},
-
- {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID,
- PEG2BPFI5, "PEG2BPFI5"},
- {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"},
-
- {0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI,
- "PXEG4BPFI-SD"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX,
- "MxEG2BPFI6LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX,
- "MxEG2BPFI6ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX,
- "MxEG4BPFI6LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX,
- "MxEG4BPFI6ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80,
- "MxE2G4BPFi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX,
- "MxE2G4BPFi80LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX,
- "MxE2G4BPFi80ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX,
- "M2EG2BPFI6LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX,
- "M2EG2BPFI6ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX,
- "M2EG4BPFI6LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX,
- "M2EG4BPFI6ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"},
-
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"},
- {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"},
-
- {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"},
- {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
- {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"},
-
- {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"},
- {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"},
- {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX,
- "PE2G4BPFi80LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX,
- "PE2G4BPFi80ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A,
- "MxE2G8BPi80A"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35,
- "PAC1200BPi35"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX,
- "PE2G2BPFi35LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX,
- "PE2G2BPFi35ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX,
- "PE2G4BPFi35LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX,
- "PE2G4BPFi35ZX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"},
-
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX,
- "PE2G6BPi35CX"},
-
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX,
- "PE2G2BPFi80LX"},
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80ZX,
- "PE2G2BPFi80ZX"},
-
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
- {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
-
-#if 0
- {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9,
- "PE210G2SPI9"},
-#endif
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4,
- "MxE210G2BPI9CX4"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9SR,
- "MxE210G2BPI9SR"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9LR,
- "MxE210G2BPI9LR"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T,
- "MxE210G2BPI9T"},
-
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M2E10G2BPI9CX4,
- "M2E10G2BPI9CX4"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9SR,
- "M2E10G2BPI9SR"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9LR,
- "M2E10G2BPI9LR"},
- {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID */ , M2E10G2BPI9T,
- "M2E10G2BPI9T"},
-
- {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9CX4_SSID,
- PE210G2BPI9CX4, "PE210G2BPI9CX4"},
- {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID,
- PE210G2BPI9SR, "PE210G2BPI9SR"},
- {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID,
- PE210G2BPI9LR, "PE210G2BPI9LR"},
- {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T,
- "PE210G2BPI9T"},
-
-#if 0
- {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
- "PXG4BPI-SD"},
-
- {0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
- "PXG4BPFI-SD"},
-
- {0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
- "PXG2TBI-SD"},
-
- {0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
- "PXG2BISC1-SD"},
-
- {0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
- "PEG4BPFI-SD"},
-
-#ifdef BP_SELF_TEST
- {0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"},
-#endif
-#endif
- {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"},
- {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ ,
- SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40,
- "PE210G2BPi40T"},
-
- /* required last entry */
- {0,}
-};
-
-static void find_fw(struct bpctl_dev *dev)
-{
- unsigned long mmio_start, mmio_len;
- struct pci_dev *pdev1 = dev->pdev;
-
- if ((OLD_IF_SERIES(dev->subdevice)) ||
- (INTEL_IF_SERIES(dev->subdevice)))
- dev->bp_fw_ver = 0xff;
- else
- dev->bp_fw_ver = bypass_fw_ver(dev);
-
- if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) {
- int cnt = 100;
- while (cnt--) {
- iounmap((void *)dev->mem_map);
- mmio_start = pci_resource_start(pdev1, 0);
- mmio_len = pci_resource_len(pdev1, 0);
-
- dev->mem_map = (unsigned long)
- ioremap(mmio_start, mmio_len);
-
- dev->bp_fw_ver = bypass_fw_ver(dev);
- if (dev->bp_fw_ver == 0xa8)
- break;
- }
- }
- /* dev->bp_fw_ver=0xa8; */
- printk("firmware version: 0x%x\n", dev->bp_fw_ver);
-}
-
-static int init_one(struct bpctl_dev *dev, struct bpmod_info *info, struct pci_dev *pdev1)
-{
- unsigned long mmio_start, mmio_len;
-
- dev->pdev = pdev1;
- mmio_start = pci_resource_start(pdev1, 0);
- mmio_len = pci_resource_len(pdev1, 0);
-
- dev->desc = dev_desc[info->index].name;
- dev->name = info->bp_name;
- dev->device = info->device;
- dev->vendor = info->vendor;
- dev->subdevice = info->subdevice;
- dev->subvendor = info->subvendor;
- dev->func = PCI_FUNC(pdev1->devfn);
- dev->slot = PCI_SLOT(pdev1->devfn);
- dev->bus = pdev1->bus->number;
- dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len);
-#ifdef BP_SYNC_FLAG
- spin_lock_init(&dev->bypass_wr_lock);
-#endif
- if (BP10G9_IF_SERIES(dev->subdevice))
- dev->bp_10g9 = 1;
- if (BP10G_IF_SERIES(dev->subdevice))
- dev->bp_10g = 1;
- if (PEG540_IF_SERIES(dev->subdevice))
- dev->bp_540 = 1;
- if (PEGF5_IF_SERIES(dev->subdevice))
- dev->bp_fiber5 = 1;
- if (PEG80_IF_SERIES(dev->subdevice))
- dev->bp_i80 = 1;
- if (PEGF80_IF_SERIES(dev->subdevice))
- dev->bp_i80 = 1;
- if ((dev->subdevice & 0xa00) == 0xa00)
- dev->bp_i80 = 1;
- if (BP10GB_IF_SERIES(dev->subdevice)) {
- if (dev->ifindex == 0) {
- unregister_chrdev(major_num, DEVICE_NAME);
- printk("Please load network driver for %s adapter!\n",
- dev->name);
- return -1;
- }
-
- if (dev->ndev && !(dev->ndev->flags & IFF_UP)) {
- unregister_chrdev(major_num, DEVICE_NAME);
- printk("Please bring up network interfaces for %s adapter!\n",
- dev->name);
- return -1;
- }
- dev->bp_10gb = 1;
- }
-
- if (!dev->bp_10g9) {
- if (is_bypass_fn(dev)) {
- printk(KERN_INFO "%s found, ",
- dev->name);
- find_fw(dev);
- }
- dev->wdt_status = WDT_STATUS_UNKNOWN;
- dev->reset_time = 0;
- atomic_set(&dev->wdt_busy, 0);
- dev->bp_status_un = 1;
-
- bypass_caps_init(dev);
-
- init_bypass_wd_auto(dev);
- init_bypass_tpl_auto(dev);
- if (NOKIA_SERIES(dev->subdevice))
- reset_cont(dev);
- }
-#ifdef BP_SELF_TEST
- dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL);
- if (dev->bp_tx_data) {
- memset(dev->bp_tx_data, 0xff, 6);
- memset(dev->bp_tx_data + 6, 0x0, 1);
- memset(dev->bp_tx_data + 7, 0xaa, 5);
- *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST);
- } else
- printk("bp_ctl: Memory allocation error!\n");
-#endif
- return 0;
-}
-
-/*
-* Initialize the module - Register the character device
-*/
-
-static int __init bypass_init_module(void)
-{
- int ret_val, idx, idx_dev = 0;
- struct pci_dev *pdev1 = NULL;
- struct bpctl_dev *dev;
-
- printk(BP_MOD_DESCR " v" BP_MOD_VER "\n");
- ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops);
- if (ret_val < 0) {
- printk("%s failed with %d\n", DEVICE_NAME, ret_val);
- return ret_val;
- }
- major_num = ret_val; /* dynamic */
- for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
- while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
- tx_ctl_pci_tbl[idx].device,
- tx_ctl_pci_tbl[idx].subvendor,
- tx_ctl_pci_tbl[idx].subdevice,
- pdev1))) {
-
- device_num++;
- }
- }
- if (!device_num) {
- printk("No such device\n");
- unregister_chrdev(major_num, DEVICE_NAME);
- return -1;
- }
-
- bpctl_dev_arr = kmalloc((device_num) * sizeof(struct bpctl_dev), GFP_KERNEL);
-
- if (!bpctl_dev_arr) {
- printk("Allocation error\n");
- unregister_chrdev(major_num, DEVICE_NAME);
- return -1;
- }
- memset(bpctl_dev_arr, 0, ((device_num) * sizeof(struct bpctl_dev)));
-
- pdev1 = NULL;
- dev = bpctl_dev_arr;
- for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
- while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
- tx_ctl_pci_tbl[idx].device,
- tx_ctl_pci_tbl[idx].subvendor,
- tx_ctl_pci_tbl[idx].subdevice,
- pdev1))) {
- if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0)
- return -1;
- dev++;
- }
- }
- if_scan_init();
-
- sema_init(&bpctl_sema, 1);
- spin_lock_init(&bpvm_lock);
-
- for (idx_dev = 0, dev = bpctl_dev_arr;
- idx_dev < device_num && dev->pdev;
- idx_dev++, dev++) {
- if (dev->bp_10g9) {
- if (is_bypass_fn(dev)) {
- printk(KERN_INFO "%s found, ", dev->name);
- dev->bp_fw_ver = bypass_fw_ver(dev);
- printk("firmware version: 0x%x\n",
- dev->bp_fw_ver);
- }
- dev->wdt_status = WDT_STATUS_UNKNOWN;
- dev->reset_time = 0;
- atomic_set(&dev->wdt_busy, 0);
- dev->bp_status_un = 1;
-
- bypass_caps_init(dev);
-
- init_bypass_wd_auto(dev);
- init_bypass_tpl_auto(dev);
- }
- }
-
- register_netdevice_notifier(&bp_notifier_block);
- return 0;
-}
-
-/*
-* Cleanup - unregister the appropriate file from /proc
-*/
-static void __exit bypass_cleanup_module(void)
-{
- int i;
-
- unregister_netdevice_notifier(&bp_notifier_block);
-
- for (i = 0; i < device_num; i++) {
- /* unsigned long flags; */
- remove_bypass_wd_auto(&bpctl_dev_arr[i]);
- bpctl_dev_arr[i].reset_time = 0;
-
- remove_bypass_tpl_auto(&bpctl_dev_arr[i]);
- }
-
- /* unmap all devices */
- for (i = 0; i < device_num; i++) {
-#ifdef BP_SELF_TEST
- kfree(bpctl_dev_arr[i].bp_tx_data);
-#endif
- iounmap((void *)(bpctl_dev_arr[i].mem_map));
- }
-
- /* free all devices space */
- kfree(bpctl_dev_arr);
-
-/*
-* Unregister the device
-*/
- unregister_chrdev(major_num, DEVICE_NAME);
-}
-
-module_init(bypass_init_module);
-module_exit(bypass_cleanup_module);
-
-int is_bypass_sd(int ifindex)
-{
- return is_bypass(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(is_bypass_sd);
-
-int set_bypass_sd(int ifindex, int bypass_mode)
-{
-
- return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode);
-}
-EXPORT_SYMBOL(set_bypass_sd);
-
-int get_bypass_sd(int ifindex)
-{
-
- return get_bypass_fn(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(get_bypass_sd);
-
-int get_bypass_change_sd(int ifindex)
-{
-
- return get_bypass_change_fn(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(get_bypass_change_sd);
-
-int set_dis_bypass_sd(int ifindex, int dis_param)
-{
- return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param);
-}
-EXPORT_SYMBOL(set_dis_bypass_sd);
-
-int get_dis_bypass_sd(int ifindex)
-{
-
- return get_dis_bypass_fn(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(get_dis_bypass_sd);
-
-int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
-{
- return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode);
-
-}
-EXPORT_SYMBOL(set_bypass_pwoff_sd);
-
-int get_bypass_pwoff_sd(int ifindex)
-{
- return get_bypass_pwoff_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bypass_pwoff_sd);
-
-int set_bypass_pwup_sd(int ifindex, int bypass_mode)
-{
- return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode);
-
-}
-EXPORT_SYMBOL(set_bypass_pwup_sd);
-
-int get_bypass_pwup_sd(int ifindex)
-{
- return get_bypass_pwup_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bypass_pwup_sd);
-
-int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set)
-{
- if ((is_bypass(get_dev_idx_p(if_index))) <= 0)
- return BP_NOT_CAP;
- *ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout);
- return 0;
-}
-EXPORT_SYMBOL(set_bypass_wd_sd);
-
-int get_bypass_wd_sd(int ifindex, int *timeout)
-{
- return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout);
-
-}
-EXPORT_SYMBOL(get_bypass_wd_sd);
-
-int get_wd_expire_time_sd(int ifindex, int *time_left)
-{
- return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left);
-}
-EXPORT_SYMBOL(get_wd_expire_time_sd);
-
-int reset_bypass_wd_timer_sd(int ifindex)
-{
- return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(reset_bypass_wd_timer_sd);
-
-int get_wd_set_caps_sd(int ifindex)
-{
- return get_wd_set_caps_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_wd_set_caps_sd);
-
-int set_std_nic_sd(int ifindex, int nic_mode)
-{
- return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode);
-
-}
-EXPORT_SYMBOL(set_std_nic_sd);
-
-int get_std_nic_sd(int ifindex)
-{
- return get_std_nic_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_std_nic_sd);
-
-int set_tap_sd(int ifindex, int tap_mode)
-{
- return set_tap_fn(get_dev_idx_p(ifindex), tap_mode);
-
-}
-EXPORT_SYMBOL(set_tap_sd);
-
-int get_tap_sd(int ifindex)
-{
- return get_tap_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_tap_sd);
-
-int set_tap_pwup_sd(int ifindex, int tap_mode)
-{
- return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode);
-
-}
-EXPORT_SYMBOL(set_tap_pwup_sd);
-
-int get_tap_pwup_sd(int ifindex)
-{
- return get_tap_pwup_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_tap_pwup_sd);
-
-int get_tap_change_sd(int ifindex)
-{
- return get_tap_change_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_tap_change_sd);
-
-int set_dis_tap_sd(int ifindex, int dis_param)
-{
- return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param);
-
-}
-EXPORT_SYMBOL(set_dis_tap_sd);
-
-int get_dis_tap_sd(int ifindex)
-{
- return get_dis_tap_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_dis_tap_sd);
-
-int set_bp_disc_sd(int ifindex, int disc_mode)
-{
- return set_disc_fn(get_dev_idx_p(ifindex), disc_mode);
-
-}
-EXPORT_SYMBOL(set_bp_disc_sd);
-
-int get_bp_disc_sd(int ifindex)
-{
- return get_disc_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bp_disc_sd);
-
-int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
-{
- return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode);
-
-}
-EXPORT_SYMBOL(set_bp_disc_pwup_sd);
-
-int get_bp_disc_pwup_sd(int ifindex)
-{
- return get_disc_pwup_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bp_disc_pwup_sd);
-
-int get_bp_disc_change_sd(int ifindex)
-{
- return get_disc_change_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bp_disc_change_sd);
-
-int set_bp_dis_disc_sd(int ifindex, int dis_param)
-{
- return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param);
-
-}
-EXPORT_SYMBOL(set_bp_dis_disc_sd);
-
-int get_bp_dis_disc_sd(int ifindex)
-{
- return get_dis_disc_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bp_dis_disc_sd);
-
-int get_wd_exp_mode_sd(int ifindex)
-{
- return get_wd_exp_mode_fn(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(get_wd_exp_mode_sd);
-
-int set_wd_exp_mode_sd(int ifindex, int param)
-{
- return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param);
-
-}
-EXPORT_SYMBOL(set_wd_exp_mode_sd);
-
-int set_tx_sd(int ifindex, int tx_state)
-{
- return set_tx_fn(get_dev_idx_p(ifindex), tx_state);
-
-}
-EXPORT_SYMBOL(set_tx_sd);
-
-int set_tpl_sd(int ifindex, int tpl_state)
-{
- return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state);
-
-}
-EXPORT_SYMBOL(set_tpl_sd);
-
-int set_bp_hw_reset_sd(int ifindex, int status)
-{
- return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status);
-
-}
-EXPORT_SYMBOL(set_bp_hw_reset_sd);
-
-int set_wd_autoreset_sd(int ifindex, int param)
-{
- return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param);
-
-}
-EXPORT_SYMBOL(set_wd_autoreset_sd);
-
-int get_wd_autoreset_sd(int ifindex)
-{
- return get_wd_autoreset_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_wd_autoreset_sd);
-
-int get_bypass_caps_sd(int ifindex)
-{
- return get_bypass_caps_fn(get_dev_idx_p(ifindex));
-}
-EXPORT_SYMBOL(get_bypass_caps_sd);
-
-int get_bypass_slave_sd(int ifindex)
-{
- struct bpctl_dev *pbpctl_dev_out;
- int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
-
- if (ret == 1)
- return pbpctl_dev_out->ifindex;
- return -1;
-
-}
-EXPORT_SYMBOL(get_bypass_slave_sd);
-
-int get_tx_sd(int ifindex)
-{
- return get_tx_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_tx_sd);
-
-int get_tpl_sd(int ifindex)
-{
- return get_tpl_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_tpl_sd);
-
-int get_bp_hw_reset_sd(int ifindex)
-{
- return get_bp_hw_reset_fn(get_dev_idx_p(ifindex));
-
-}
-EXPORT_SYMBOL(get_bp_hw_reset_sd);
-
-int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
-{
- return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver);
-}
-EXPORT_SYMBOL(get_bypass_info_sd);
-
-int bp_if_scan_sd(void)
-{
- if_scan_init();
- return 0;
-}
-EXPORT_SYMBOL(bp_if_scan_sd);
-
-#define BP_PROC_DIR "bypass"
-
-static struct proc_dir_entry *bp_procfs_dir;
-
-static int procfs_add(char *proc_name, const struct file_operations *fops,
- struct bpctl_dev *dev)
-{
- struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set;
-
- if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
- return -1;
- return 0;
-}
-
-#define RO_FOPS(name) \
-static int name##_open(struct inode *inode, struct file *file) \
-{ \
- return single_open(file, show_##name, PDE_DATA(inode));\
-} \
-static const struct file_operations name##_ops = { \
- .open = name##_open, \
- .read = seq_read, \
- .llseek = seq_lseek, \
- .release = single_release, \
-};
-
-#define RW_FOPS(name) \
-static int name##_open(struct inode *inode, struct file *file) \
-{ \
- return single_open(file, show_##name, PDE_DATA(inode));\
-} \
-static const struct file_operations name##_ops = { \
- .open = name##_open, \
- .read = seq_read, \
- .write = name##_write, \
- .llseek = seq_lseek, \
- .release = single_release, \
-};
-
-static int show_bypass_info(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
-
- seq_printf(m, "Name\t\t\t%s\n", dev->name);
- seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver);
- return 0;
-}
-RO_FOPS(bypass_info)
-
-static int show_bypass_slave(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- struct bpctl_dev *slave = get_status_port_fn(dev);
-
- if (!slave)
- slave = dev;
- if (!slave)
- seq_puts(m, "fail\n");
- else if (slave->ndev)
- seq_printf(m, "%s\n", slave->ndev->name);
- return 0;
-}
-RO_FOPS(bypass_slave)
-
-static int show_bypass_caps(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bypass_caps_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "-1\n");
- else
- seq_printf(m, "0x%x\n", ret);
- return 0;
-}
-RO_FOPS(bypass_caps)
-
-static int show_wd_set_caps(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_wd_set_caps_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "-1\n");
- else
- seq_printf(m, "0x%x\n", ret);
- return 0;
-}
-RO_FOPS(wd_set_caps)
-
-static int user_on_off(const void __user *buffer, size_t count)
-{
-
- char kbuf[256];
- int length = 0;
-
- if (count > (sizeof(kbuf) - 1))
- return -1;
-
- if (copy_from_user(&kbuf, buffer, count))
- return -1;
-
- kbuf[count] = '\0';
- length = strlen(kbuf);
- if (kbuf[length - 1] == '\n')
- kbuf[--length] = '\0';
-
- if (strcmp(kbuf, "on") == 0)
- return 1;
- if (strcmp(kbuf, "off") == 0)
- return 0;
- return 0;
-}
-
-static ssize_t bypass_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int bypass_param = user_on_off(buffer, count);
-
- if (bypass_param < 0)
- return -1;
-
- set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
- return count;
-}
-static int show_bypass(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bypass_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(bypass)
-
-static ssize_t tap_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -1;
-
- set_tap_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_tap(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_tap_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(tap)
-
-static ssize_t disc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -1;
-
- set_disc_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_disc(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_disc_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(disc)
-
-static int show_bypass_change(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bypass_change_fn(dev);
-
- if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "fail\n");
- return 0;
-}
-RO_FOPS(bypass_change)
-
-static int show_tap_change(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_tap_change_fn(dev);
-
- if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "fail\n");
- return 0;
-}
-RO_FOPS(tap_change)
-
-static int show_disc_change(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_disc_change_fn(dev);
-
- if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "fail\n");
- return 0;
-}
-RO_FOPS(disc_change)
-
-static ssize_t bypass_wd_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct bpctl_dev *dev = PDE_DATA(file_inode(file));
- int timeout;
- int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
-
- if (ret)
- return ret;
- set_bypass_wd_fn(dev, timeout);
- return count;
-}
-static int show_bypass_wd(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = 0, timeout = 0;
-
- ret = get_bypass_wd_fn(dev, &timeout);
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (timeout == -1)
- seq_puts(m, "unknown\n");
- else if (timeout == 0)
- seq_puts(m, "disable\n");
- else
- seq_printf(m, "%d\n", timeout);
- return 0;
-}
-RW_FOPS(bypass_wd)
-
-static int show_wd_expire_time(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = 0, timeout = 0;
-
- ret = get_wd_expire_time_fn(dev, &timeout);
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (timeout == -1)
- seq_puts(m, "expire\n");
- else if (timeout == 0)
- seq_puts(m, "disable\n");
- else
- seq_printf(m, "%d\n", timeout);
- return 0;
-}
-RO_FOPS(wd_expire_time)
-
-static ssize_t tpl_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct bpctl_dev *dev = PDE_DATA(file_inode(file));
- int tpl_param = user_on_off(buffer, count);
-
- if (tpl_param < 0)
- return -1;
-
- set_tpl_fn(dev, tpl_param);
- return count;
-}
-static int show_tpl(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_tpl_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(tpl)
-
-#ifdef PMC_FIX_FLAG
-static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct bpctl_dev *dev = PDE_DATA(file_inode(file));
- int tpl_param = user_on_off(buffer, count);
-
- if (tpl_param < 0)
- return -1;
-
- set_bp_wait_at_pwup_fn(dev, tpl_param);
- return count;
-}
-static int show_wait_at_pwup(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bp_wait_at_pwup_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(wait_at_pwup)
-
-static ssize_t hw_reset_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- struct bpctl_dev *dev = PDE_DATA(file_inode(file));
- int tpl_param = user_on_off(buffer, count);
-
- if (tpl_param < 0)
- return -1;
-
- set_bp_hw_reset_fn(dev, tpl_param);
- return count;
-}
-static int show_hw_reset(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bp_hw_reset_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 1)
- seq_puts(m, "on\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- return 0;
-}
-RW_FOPS(hw_reset)
-
-#endif /*PMC_WAIT_FLAG */
-
-static int show_reset_bypass_wd(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = reset_bypass_wd_timer_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "disable\n");
- else if (ret == 1)
- seq_puts(m, "success\n");
- return 0;
-}
-RO_FOPS(reset_bypass_wd)
-
-static ssize_t dis_bypass_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int bypass_param = user_on_off(buffer, count);
-
- if (bypass_param < 0)
- return -EINVAL;
-
- set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
- return count;
-}
-static int show_dis_bypass(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_dis_bypass_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(dis_bypass)
-
-static ssize_t dis_tap_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -EINVAL;
-
- set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_dis_tap(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_dis_tap_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(dis_tap)
-
-static ssize_t dis_disc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -EINVAL;
-
- set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_dis_disc(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_dis_disc_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(dis_disc)
-
-static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int bypass_param = user_on_off(buffer, count);
-
- if (bypass_param < 0)
- return -EINVAL;
-
- set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param);
- return count;
-}
-static int show_bypass_pwup(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bypass_pwup_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(bypass_pwup)
-
-static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int bypass_param = user_on_off(buffer, count);
-
- if (bypass_param < 0)
- return -EINVAL;
-
- set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param);
- return count;
-}
-static int show_bypass_pwoff(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_bypass_pwoff_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(bypass_pwoff)
-
-static ssize_t tap_pwup_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -EINVAL;
-
- set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_tap_pwup(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_tap_pwup_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(tap_pwup)
-
-static ssize_t disc_pwup_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int tap_param = user_on_off(buffer, count);
-
- if (tap_param < 0)
- return -EINVAL;
-
- set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
- return count;
-}
-static int show_disc_pwup(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_disc_pwup_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(disc_pwup)
-
-static ssize_t std_nic_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int bypass_param = user_on_off(buffer, count);
-
- if (bypass_param < 0)
- return -EINVAL;
-
- set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param);
- return count;
-}
-static int show_std_nic(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_std_nic_fn(dev);
-
- if (ret == BP_NOT_CAP)
- seq_puts(m, "fail\n");
- else if (ret == 0)
- seq_puts(m, "off\n");
- else
- seq_puts(m, "on\n");
- return 0;
-}
-RW_FOPS(std_nic)
-
-static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- char kbuf[256];
- int bypass_param = 0, length = 0;
-
- if (count > (sizeof(kbuf) - 1))
- return -1;
-
- if (copy_from_user(&kbuf, buffer, count))
- return -1;
-
- kbuf[count] = '\0';
- length = strlen(kbuf);
- if (kbuf[length - 1] == '\n')
- kbuf[--length] = '\0';
-
- if (strcmp(kbuf, "tap") == 0)
- bypass_param = 1;
- else if (strcmp(kbuf, "bypass") == 0)
- bypass_param = 0;
- else if (strcmp(kbuf, "disc") == 0)
- bypass_param = 2;
-
- set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param);
-
- return count;
-}
-static int show_wd_exp_mode(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_wd_exp_mode_fn(dev);
-
- if (ret == 1)
- seq_puts(m, "tap\n");
- else if (ret == 0)
- seq_puts(m, "bypass\n");
- else if (ret == 2)
- seq_puts(m, "disc\n");
- else
- seq_puts(m, "fail\n");
- return 0;
-}
-RW_FOPS(wd_exp_mode)
-
-static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- int timeout;
- int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
-
- if (ret)
- return ret;
- set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout);
- return count;
-}
-static int show_wd_autoreset(struct seq_file *m, void *v)
-{
- struct bpctl_dev *dev = m->private;
- int ret = get_wd_autoreset_fn(dev);
-
- if (ret >= 0)
- seq_printf(m, "%d\n", ret);
- else
- seq_puts(m, "fail\n");
- return 0;
-}
-RW_FOPS(wd_autoreset)
-
-static int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block)
-{
- struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
- static struct proc_dir_entry *procfs_dir;
- int ret = 0;
-
- if (!pbp_device_block->ndev)
- return -1;
- sprintf(current_pfs->dir_name, "bypass_%s",
- pbp_device_block->ndev->name);
-
- if (!bp_procfs_dir)
- return -1;
-
- /* create device proc dir */
- procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir);
- if (!procfs_dir) {
- printk(KERN_DEBUG "Could not create procfs directory %s\n",
- current_pfs->dir_name);
- return -1;
- }
- current_pfs->bypass_entry = procfs_dir;
-
-#define ENTRY(x) (ret |= procfs_add(#x, &x##_ops, pbp_device_block))
-
- ENTRY(bypass_info);
- if (pbp_device_block->bp_caps & SW_CTL_CAP) {
- /* Create set param proc's */
- ENTRY(bypass_slave);
- ENTRY(bypass_caps);
- ENTRY(wd_set_caps);
- ENTRY(bypass_wd);
- ENTRY(wd_expire_time);
- ENTRY(reset_bypass_wd);
- ENTRY(std_nic);
- if (pbp_device_block->bp_caps & BP_CAP) {
- ENTRY(bypass);
- ENTRY(dis_bypass);
- ENTRY(bypass_pwup);
- ENTRY(bypass_pwoff);
- ENTRY(bypass_change);
- }
- if (pbp_device_block->bp_caps & TAP_CAP) {
- ENTRY(tap);
- ENTRY(dis_tap);
- ENTRY(tap_pwup);
- ENTRY(tap_change);
- }
- if (pbp_device_block->bp_caps & DISC_CAP) {
- ENTRY(disc);
- ENTRY(dis_disc);
- ENTRY(disc_pwup);
- ENTRY(disc_change);
- }
-
- ENTRY(wd_exp_mode);
- ENTRY(wd_autoreset);
- ENTRY(tpl);
-#ifdef PMC_FIX_FLAG
- ENTRY(wait_at_pwup);
- ENTRY(hw_reset);
-#endif
- }
-#undef ENTRY
- if (ret < 0)
- printk(KERN_DEBUG "Create proc entry failed\n");
-
- return ret;
-}
-
-static int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block)
-{
- struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
-
- remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir);
- current_pfs->bypass_entry = NULL;
- return 0;
-}
diff --git a/drivers/staging/silicom/bypass.h b/drivers/staging/silicom/bypass.h
deleted file mode 100644
index 08fa7a0fc8d8..000000000000
--- a/drivers/staging/silicom/bypass.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/******************************************************************************/
-/* */
-/* Bypass Control utility, Copyright (c) 2005 Silicom */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/******************************************************************************/
-
-#ifndef BYPASS_H
-#define BYPASS_H
-
-/* Bypass related */
-
-#define SYNC_CMD_VAL 2 /* 10b */
-#define SYNC_CMD_LEN 2
-
-#define WR_CMD_VAL 2 /* 10b */
-#define WR_CMD_LEN 2
-
-#define RD_CMD_VAL 1 /* 10b */
-#define RD_CMD_LEN 2
-
-#define ADDR_CMD_LEN 4
-
-#define WR_DATA_LEN 8
-#define RD_DATA_LEN 8
-
-#define PIC_SIGN_REG_ADDR 0x7
-#define PIC_SIGN_VALUE 0xcd
-
-#define STATUS_REG_ADDR 0
-#define WDT_EN_MASK 0x01 /* BIT_0 */
-#define CMND_EN_MASK 0x02 /* BIT_1 */
-#define DIS_BYPASS_CAP_MASK 0x04 /* BIT_2 Bypass Cap is disable*/
-#define DFLT_PWRON_MASK 0x08 /* BIT_3 */
-#define BYPASS_OFF_MASK 0x10 /* BIT_4 */
-#define BYPASS_FLAG_MASK 0x20 /* BIT_5 */
-#define STD_NIC_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK)
-#define WD_EXP_FLAG_MASK 0x40 /* BIT_6 */
-#define DFLT_PWROFF_MASK 0x80 /* BIT_7 */
-#define STD_NIC_PWOFF_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK | DFLT_PWROFF_MASK)
-
-#define PRODUCT_CAP_REG_ADDR 0x5
-#define BYPASS_SUPPORT_MASK 0x01 /* BIT_0 */
-#define TAP_SUPPORT_MASK 0x02 /* BIT_1 */
-#define NORMAL_UNSUPPORT_MASK 0x04 /* BIT_2 */
-#define DISC_SUPPORT_MASK 0x08 /* BIT_3 */
-#define TPL2_SUPPORT_MASK 0x10 /* BIT_4 */
-#define DISC_PORT_SUPPORT_MASK 0x20 /* BIT_5 */
-
-#define STATUS_TAP_REG_ADDR 0x6
-#define WDTE_TAP_BPN_MASK 0x01 /* BIT_1 1 when wdt expired -> TAP, 0 - Bypass */
-#define DIS_TAP_CAP_MASK 0x04 /* BIT_2 TAP Cap is disable*/
-#define DFLT_PWRON_TAP_MASK 0x08 /* BIT_3 */
-#define TAP_OFF_MASK 0x10 /* BIT_4 */
-#define TAP_FLAG_MASK 0x20 /* BIT_5 */
-#define TX_DISA_MASK 0x40
-#define TX_DISB_MASK 0x80
-
-#define STD_NIC_TAP_MASK (DIS_TAP_CAP_MASK | TAP_OFF_MASK | DFLT_PWRON_TAP_MASK)
-
-#define STATUS_DISC_REG_ADDR 13
-#define WDTE_DISC_BPN_MASK 0x01 /* BIT_0 1 when wdt expired -> TAP, 0 - Bypass */
-#define STD_NIC_ON_MASK 0x02 /* BIT_1 */
-#define DIS_DISC_CAP_MASK 0x04 /* BIT_2 TAP Cap is disable*/
-#define DFLT_PWRON_DISC_MASK 0x08 /* BIT_3 */
-#define DISC_OFF_MASK 0x10 /* BIT_4 */
-#define DISC_FLAG_MASK 0x20 /* BIT_5 */
-#define TPL2_FLAG_MASK 0x40 /* BIT_6 */
-#define STD_NIC_DISC_MASK DIS_DISC_CAP_MASK
-
-#define CONT_CONFIG_REG_ADDR 12
-#define EN_HW_RESET_MASK 0x2 /* BIT_1 */
-#define WAIT_AT_PWUP_MASK 0x1 /* BIT_0 */
-
-#define VER_REG_ADDR 0x1
-#define BP_FW_VER_A0 0xa0
-#define BP_FW_VER_A1 0xa1
-
-#define INT_VER_MASK 0xf0
-#define EXT_VER_MASK 0xf
-/* */
-#define PXG2BPI_VER 0x0
-#define PXG2TBPI_VER 0x1
-#define PXE2TBPI_VER 0x2
-#define PXG4BPFI_VER 0x4
-#define BP_FW_EXT_VER7 0x6
-#define BP_FW_EXT_VER8 0x8
-#define BP_FW_EXT_VER9 0x9
-
-#define OLD_IF_VER -1
-
-#define CMND_REG_ADDR 10 /* 1010b */
-#define WDT_REG_ADDR 4
-#define TMRL_REG_ADDR 2
-#define TMRH_REG_ADDR 3
-
-/* NEW_FW */
-#define WDT_INTERVAL 1 /* 5 //8 */
-#define WDT_CMND_INTERVAL 200 /* 50 */
-#define CMND_INTERVAL 200 /* 100 usec */
-#define PULSE_TIME 100
-
-/* OLD_FW */
-#define INIT_CMND_INTERVAL 40
-#define PULSE_INTERVAL 5
-#define WDT_TIME_CNT 3
-
-/* Intel Commands */
-
-#define CMND_OFF_INT 0xf
-#define PWROFF_BYPASS_ON_INT 0x5
-#define BYPASS_ON_INT 0x6
-#define DIS_BYPASS_CAP_INT 0x4
-#define RESET_WDT_INT 0x1
-
-/* Intel timing */
-
-#define BYPASS_DELAY_INT 4 /* msec */
-#define CMND_INTERVAL_INT 2 /* msec */
-
-/* Silicom Commands */
-#define CMND_ON 0x4
-#define CMND_OFF 0x2
-#define BYPASS_ON 0xa
-#define BYPASS_OFF 0x8
-#define PORT_LINK_EN 0xe
-#define PORT_LINK_DIS 0xc
-#define WDT_ON 0x10 /* 0x1f (11111) - max */
-#define TIMEOUT_UNIT 100
-#define TIMEOUT_MAX_STEP 15
-#define WDT_TIMEOUT_MIN 100 /* msec */
-#define WDT_TIMEOUT_MAX 3276800 /* msec */
-#define WDT_AUTO_MIN_INT 500
-#define WDT_TIMEOUT_DEF WDT_TIMEOUT_MIN
-#define WDT_OFF 0x6
-#define WDT_RELOAD 0x9
-#define RESET_CONT 0x20
-#define DIS_BYPASS_CAP 0x22
-#define EN_BYPASS_CAP 0x24
-#define BYPASS_STATE_PWRON 0x26
-#define NORMAL_STATE_PWRON 0x28
-#define BYPASS_STATE_PWROFF 0x27
-#define NORMAL_STATE_PWROFF 0x29
-#define TAP_ON 0xb
-#define TAP_OFF 0x9
-#define TAP_STATE_PWRON 0x2a
-#define DIS_TAP_CAP 0x2c
-#define EN_TAP_CAP 0x2e
-#define STD_NIC_OFF 0x86
-#define STD_NIC_ON 0x84
-#define DISC_ON 0x85
-#define DISC_OFF 0x8a
-#define DISC_STATE_PWRON 0x87
-#define DIS_DISC_CAP 0x88
-#define EN_DISC_CAP 0x89
-#define TPL2_ON 0x8c
-#define TPL2_OFF 0x8b
-#define BP_WAIT_AT_PWUP_EN 0x80
-#define BP_WAIT_AT_PWUP_DIS 0x81
-#define BP_HW_RESET_EN 0x82
-#define BP_HW_RESET_DIS 0x83
-
-#define TX_DISA 0x8d
-#define TX_DISB 0x8e
-#define TX_ENA 0xA0
-#define TX_ENB 0xA1
-
-#define TX_DISA_PWRUP 0xA2
-#define TX_DISB_PWRUP 0xA3
-#define TX_ENA_PWRUP 0xA4
-#define TX_ENB_PWRUP 0xA5
-
-#define BYPASS_CAP_DELAY 21 /* msec */
-#define DFLT_PWRON_DELAY 10 /* msec */
-#define LATCH_DELAY 13 /* msec */
-#define EEPROM_WR_DELAY 8 /* msec */
-
-#define BP_LINK_MON_DELAY 4 /* sec */
-
-#define BP_FW_EXT_VER0 0xa0
-#define BP_FW_EXT_VER1 0xa1
-#define BP_FW_EXT_VER2 0xb1
-
-#define BP_OK 0
-#define BP_NOT_CAP -1
-#define WDT_STATUS_EXP -2
-#define WDT_STATUS_UNKNOWN -1
-#define WDT_STATUS_EN 1
-#define WDT_STATUS_DIS 0
-
-#ifdef BP_SELF_TEST
-#define ETH_P_BPTEST 0xabba
-
-#define BPTEST_DATA_LEN 60
-#endif
-
-#endif /* BYPASS_H */
diff --git a/drivers/staging/silicom/bypasslib/Makefile b/drivers/staging/silicom/bypasslib/Makefile
deleted file mode 100644
index 80e8b9bc9357..000000000000
--- a/drivers/staging/silicom/bypasslib/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for the Bypass network device drivers.
-#
-
-obj-$(CONFIG_SBYPASS) += bypass.o
-
diff --git a/drivers/staging/silicom/bypasslib/bp_ioctl.h b/drivers/staging/silicom/bypasslib/bp_ioctl.h
deleted file mode 100644
index a13932af733b..000000000000
--- a/drivers/staging/silicom/bypasslib/bp_ioctl.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/******************************************************************************/
-/* */
-/* bypass library, Copyright (c) 2004-2006 Silicom, Ltd */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/* */
-/******************************************************************************/
-
-#ifndef BP_IOCTL_H
-#define BP_IOCTL_H
-
-#define BP_CAP 0x01 /* BIT_0 */
-#define BP_STATUS_CAP 0x02 /* BIT_1 */
-#define BP_STATUS_CHANGE_CAP 0x04 /* BIT_2 */
-#define SW_CTL_CAP 0x08 /* BIT_3 */
-#define BP_DIS_CAP 0x10 /* BIT_4 */
-#define BP_DIS_STATUS_CAP 0x20 /* BIT_5 */
-#define STD_NIC_CAP 0x40 /* BIT_6 */
-#define BP_PWOFF_ON_CAP 0x80 /* BIT_7 */
-#define BP_PWOFF_OFF_CAP 0x0100 /* BIT_8 */
-#define BP_PWOFF_CTL_CAP 0x0200 /* BIT_9 */
-#define BP_PWUP_ON_CAP 0x0400 /* BIT_10 */
-#define BP_PWUP_OFF_CAP 0x0800 /* BIT_11 */
-#define BP_PWUP_CTL_CAP 0x1000 /* BIT_12 */
-#define WD_CTL_CAP 0x2000 /* BIT_13 */
-#define WD_STATUS_CAP 0x4000 /* BIT_14 */
-#define WD_TIMEOUT_CAP 0x8000 /* BIT_15 */
-#define TX_CTL_CAP 0x10000 /* BIT_16 */
-#define TX_STATUS_CAP 0x20000 /* BIT_17 */
-#define TAP_CAP 0x40000 /* BIT_18 */
-#define TAP_STATUS_CAP 0x80000 /* BIT_19 */
-#define TAP_STATUS_CHANGE_CAP 0x100000 /* BIT_20 */
-#define TAP_DIS_CAP 0x200000 /* BIT_21 */
-#define TAP_DIS_STATUS_CAP 0x400000 /* BIT_22 */
-#define TAP_PWUP_ON_CAP 0x800000 /* BIT_23 */
-#define TAP_PWUP_OFF_CAP 0x1000000 /* BIT 24 */
-#define TAP_PWUP_CTL_CAP 0x2000000 /* BIT 25 */
-#define NIC_CAP_NEG 0x4000000 /* BIT 26 */
-#define TPL_CAP 0x8000000 /* BIT 27 */
-#define DISC_CAP 0x10000000 /* BIT 28 */
-#define DISC_DIS_CAP 0x20000000 /* BIT 29 */
-#define DISC_PWUP_CTL_CAP 0x40000000 /* BIT 30 */
-
-#define WD_MIN_TIME_MASK(val) (val & 0xf)
-#define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5)
-#define WDT_STEP_TIME 0x10 /* BIT_4 */
-
-#define WD_MIN_TIME_GET(desc) (desc & 0xf)
-#define WD_STEP_COUNT_GET(desc) ((desc>>5) & 0xf)
-
-enum {
- IS_BYPASS = 1,
- GET_BYPASS_SLAVE,
- GET_BYPASS_CAPS,
- GET_WD_SET_CAPS,
- SET_BYPASS,
- GET_BYPASS,
- GET_BYPASS_CHANGE,
- SET_BYPASS_WD,
- GET_BYPASS_WD,
- GET_WD_EXPIRE_TIME,
- RESET_BYPASS_WD_TIMER,
- SET_DIS_BYPASS,
- GET_DIS_BYPASS,
- SET_BYPASS_PWOFF,
- GET_BYPASS_PWOFF,
- SET_BYPASS_PWUP,
- GET_BYPASS_PWUP,
- SET_STD_NIC,
- GET_STD_NIC,
- SET_TX,
- GET_TX,
- SET_TAP,
- GET_TAP,
- GET_TAP_CHANGE,
- SET_DIS_TAP,
- GET_DIS_TAP,
- SET_TAP_PWUP,
- GET_TAP_PWUP,
- SET_WD_EXP_MODE,
- GET_WD_EXP_MODE,
- SET_WD_AUTORESET,
- GET_WD_AUTORESET,
- SET_TPL,
- GET_TPL,
- SET_DISC,
- GET_DISC,
- GET_DISC_CHANGE,
- SET_DIS_DISC,
- GET_DIS_DISC,
- SET_DISC_PWUP,
- GET_DISC_PWUP,
-
- GET_BYPASS_INFO = 100,
- GET_BP_WAIT_AT_PWUP,
- SET_BP_WAIT_AT_PWUP,
- GET_BP_HW_RESET,
- SET_BP_HW_RESET,
-};
-
-enum {
- IF_SCAN_SD,
- GET_DEV_NUM_SD,
- IS_BYPASS_SD,
- GET_BYPASS_SLAVE_SD,
- GET_BYPASS_CAPS_SD,
- GET_WD_SET_CAPS_SD,
- SET_BYPASS_SD,
- GET_BYPASS_SD,
- GET_BYPASS_CHANGE_SD,
- SET_BYPASS_WD_SD,
- GET_BYPASS_WD_SD,
- GET_WD_EXPIRE_TIME_SD,
- RESET_BYPASS_WD_TIMER_SD,
- SET_DIS_BYPASS_SD,
- GET_DIS_BYPASS_SD,
- SET_BYPASS_PWOFF_SD,
- GET_BYPASS_PWOFF_SD,
- SET_BYPASS_PWUP_SD,
- GET_BYPASS_PWUP_SD,
- SET_STD_NIC_SD,
- GET_STD_NIC_SD,
- SET_TX_SD,
- GET_TX_SD,
- SET_TAP_SD,
- GET_TAP_SD,
- GET_TAP_CHANGE_SD,
- SET_DIS_TAP_SD,
- GET_DIS_TAP_SD,
- SET_TAP_PWUP_SD,
- GET_TAP_PWUP_SD,
- SET_WD_EXP_MODE_SD,
- GET_WD_EXP_MODE_SD,
- SET_WD_AUTORESET_SD,
- GET_WD_AUTORESET_SD,
- SET_TPL_SD,
- GET_TPL_SD,
- SET_DISC_SD,
- GET_DISC_SD,
- GET_DISC_CHANGE_SD,
- SET_DIS_DISC_SD,
- GET_DIS_DISC_SD,
- SET_DISC_PWUP_SD,
- GET_DISC_PWUP_SD,
-
- GET_BYPASS_INFO_SD = 100,
- GET_BP_WAIT_AT_PWUP_SD,
- SET_BP_WAIT_AT_PWUP_SD,
- GET_BP_HW_RESET_SD,
- SET_BP_HW_RESET_SD,
-
-};
-
-#define SIOCGIFBYPASS (SIOCDEVPRIVATE+10)
-
-struct bp_info {
- char prod_name[14];
- unsigned char fw_ver;
-};
-
-/* for passing single values */
-struct if_bypass {
- char if_name[IFNAMSIZ];
- int cmd;
- int data;
-};
-struct if_bypass_info {
- char if_name[IFNAMSIZ];
- char cmd;
- struct bp_info bp_info;
-};
-
-/*
-* The major device number. We can't rely on dynamic
-* registration any more, because ioctls need to know
-* it.
-*/
-
-#define MAGIC_NUM 'J'
-
-/* for passing single values */
-struct bpctl_cmd {
- int status;
- int data[8];
- int in_param[8];
- int out_param[8];
-};
-
-#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd)
-
-#define DEVICE_NAME "bpctl"
-
-#endif
diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h
deleted file mode 100644
index c5c75c4fe055..000000000000
--- a/drivers/staging/silicom/bypasslib/bplibk.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/******************************************************************************/
-/* */
-/* bypass library, Copyright (c) 2004 Silicom, Ltd */
-/* */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/* bplib.h */
-/* */
-/******************************************************************************/
-#ifndef BYPASS_H
-#define BYPASS_H
-
-#include "bp_ioctl.h"
-#include "libbp_sd.h"
-
-#define IF_NAME "eth"
-#define SILICOM_VID 0x1374
-#define SILICOM_BP_PID_MIN 0x24
-#define SILICOM_BP_PID_MAX 0x5f
-#define INTEL_PEG4BPII_PID 0x10a0
-#define INTEL_PEG4BPFII_PID 0x10a1
-
-#define PEGII_IF_SERIES(vid, pid) \
- ((vid == 0x8086) && \
- ((pid == INTEL_PEG4BPII_PID) || \
- (pid == INTEL_PEG4BPFII_PID)))
-
-#ifdef BP_VENDOR_SUPPORT
-char *bp_desc_array[] = { "e1000bp", "e1000bpe", "slcm5700",
- "bnx2xbp", "ixgbp", "ixgbpe", NULL };
-#endif
-
-#endif
diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c
deleted file mode 100644
index 8e714a8ea3a0..000000000000
--- a/drivers/staging/silicom/bypasslib/bypass.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/******************************************************************************/
-/* */
-/* bypass library, Copyright (c) 2004-2007 Silicom, Ltd */
-/* */
-/* 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, located in the file LICENSE. */
-/* */
-/* */
-/* bypass.c */
-/* */
-/******************************************************************************/
-
-#if defined(CONFIG_SMP) && !defined(__SMP__)
-#define __SMP__
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <asm/unistd.h>
-
-#include <linux/sched.h>
-#include <linux/wait.h>
-
-#include <linux/netdevice.h> /* struct device, and other headers */
-#include <linux/kernel_stat.h>
-#include <linux/pci.h>
-#include <linux/rtnetlink.h>
-#include <linux/ethtool.h>
-
-#include <net/net_namespace.h>
-
-#include "bplibk.h"
-
-#define MOD_NAME "bypass"
-
-#define VERSION "\n"MOD_NAME" version 9.0.4\n"
-
-MODULE_AUTHOR("www.silicom.co.il");
-
-MODULE_LICENSE("GPL");
-
-static int do_cmd(struct net_device *dev, struct ifreq *ifr, int cmd, int *data)
-{
- int ret = -1;
- struct if_bypass *bypass_cb;
-
- bypass_cb = (struct if_bypass *)ifr;
- bypass_cb->cmd = cmd;
- bypass_cb->data = *data;
-
- if (dev->netdev_ops && dev->netdev_ops->ndo_do_ioctl) {
- ret = dev->netdev_ops->ndo_do_ioctl(dev, ifr, SIOCGIFBYPASS);
- *data = bypass_cb->data;
- }
-
- return ret;
-}
-
-static int doit(int cmd, int if_index, int *data)
-{
- struct ifreq ifr;
- int ret = -1;
- struct net_device *dev;
- struct net_device *n;
-
- for_each_netdev_safe(&init_net, dev, n) {
- if (dev->ifindex == if_index) {
- ret = do_cmd(dev, &ifr, cmd, data);
- if (ret < 0)
- ret = -1;
- }
- }
-
- return ret;
-}
-
-#define bp_symbol_get(fn_name) symbol_get(fn_name)
-#define bp_symbol_put(fn_name) symbol_put(fn_name)
-
-#define SET_BPLIB_INT_FN(fn_name, arg_type, arg, ret) \
-({ int (*fn_ex)(arg_type) = NULL; \
- fn_ex = bp_symbol_get(fn_name##_sd); \
- if (fn_ex) { \
- ret = fn_ex(arg); \
- bp_symbol_put(fn_name##_sd); \
- } else { \
- ret = -1; \
- } \
-})
-
-#define SET_BPLIB_INT_FN2(fn_name, arg_type, arg, arg_type1, arg1, ret)\
-({ int (*fn_ex)(arg_type, arg_type1) = NULL; \
- fn_ex = bp_symbol_get(fn_name##_sd); \
- if (fn_ex) { \
- ret = fn_ex(arg, arg1); \
- bp_symbol_put(fn_name##_sd); \
- } else { \
- ret = -1; \
- } \
-})
-
-#define SET_BPLIB_INT_FN3(fn_name, arg_type, arg, arg_type1, arg1, \
- arg_type2, arg2, ret) \
-({ int (*fn_ex)(arg_type, arg_type1, arg_type2) = NULL; \
- fn_ex = bp_symbol_get(fn_name##_sd); \
- if (fn_ex) { \
- ret = fn_ex(arg, arg1, arg2); \
- bp_symbol_put(fn_name##_sd); \
- } else { \
- ret = -1; \
- } \
-})
-
-#define DO_BPLIB_GET_ARG_FN(fn_name, ioctl_val, if_index) \
-({ int data, ret = 0; \
- if (is_dev_sd(if_index)) { \
- SET_BPLIB_INT_FN(fn_name, int, if_index, ret); \
- return ret; \
- } \
- return doit(ioctl_val, if_index, &data); \
-})
-
-#define DO_BPLIB_SET_ARG_FN(fn_name, ioctl_val, if_index, arg) \
-({ int data, ret = 0; \
- if (is_dev_sd(if_index)) { \
- SET_BPLIB_INT_FN2(fn_name, int, if_index, int, \
- arg, ret); \
- return ret; \
- } \
- data = arg; \
- return doit(ioctl_val, if_index, &data); \
-})
-
-static int is_dev_sd(int if_index)
-{
- int ret = 0;
-
- SET_BPLIB_INT_FN(is_bypass, int, if_index, ret);
- return ret >= 0 ? 1 : 0;
-}
-
-static int is_bypass_dev(int if_index)
-{
- struct pci_dev *pdev = NULL;
- struct net_device *dev = NULL;
- struct ifreq ifr;
- int ret = 0;
- int data = 0;
-
- while ((pdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
- dev = pci_get_drvdata(pdev);
- if ((dev != NULL) && (dev->ifindex == if_index)) {
- if ((pdev->vendor == SILICOM_VID) &&
- (pdev->device >= SILICOM_BP_PID_MIN) &&
- (pdev->device <= SILICOM_BP_PID_MAX)) {
- goto send_cmd;
- }
-#if defined(BP_VENDOR_SUPPORT) && defined(ETHTOOL_GDRVINFO)
- else {
- struct ethtool_drvinfo info;
- const struct ethtool_ops *ops =
- dev->ethtool_ops;
- int k = 0;
-
- if (ops->get_drvinfo) {
- memset(&info, 0, sizeof(info));
- info.cmd = ETHTOOL_GDRVINFO;
- ops->get_drvinfo(dev, &info);
- for (; bp_desc_array[k]; k++)
- if (!(strcmp(bp_desc_array[k],
- info.driver)))
- goto send_cmd;
-
- }
-
- }
-#endif
- return -1;
- }
- }
- send_cmd:
- ret = do_cmd(dev, &ifr, IS_BYPASS, &data);
- return ret < 0 ? -1 : ret;
-}
-
-static int is_bypass(int if_index)
-{
- int ret = 0;
-
- SET_BPLIB_INT_FN(is_bypass, int, if_index, ret);
-
- if (ret < 0)
- return is_bypass_dev(if_index);
- return ret;
-}
-EXPORT_SYMBOL(is_bypass);
-
-static int get_bypass_slave(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass_slave, GET_BYPASS_SLAVE, if_index);
-}
-EXPORT_SYMBOL(get_bypass_slave);
-
-static int get_bypass_caps(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass_caps, GET_BYPASS_CAPS, if_index);
-}
-EXPORT_SYMBOL(get_bypass_caps);
-
-static int get_wd_set_caps(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_wd_set_caps, GET_WD_SET_CAPS, if_index);
-}
-EXPORT_SYMBOL(get_wd_set_caps);
-
-static int set_bypass(int if_index, int bypass_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_bypass, SET_BYPASS, if_index, bypass_mode);
-}
-EXPORT_SYMBOL(set_bypass);
-
-static int get_bypass(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass, GET_BYPASS, if_index);
-}
-EXPORT_SYMBOL(get_bypass);
-
-static int get_bypass_change(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass_change, GET_BYPASS_CHANGE, if_index);
-}
-EXPORT_SYMBOL(get_bypass_change);
-
-static int set_dis_bypass(int if_index, int dis_bypass)
-{
- DO_BPLIB_SET_ARG_FN(set_dis_bypass, SET_DIS_BYPASS, if_index,
- dis_bypass);
-}
-EXPORT_SYMBOL(set_dis_bypass);
-
-static int get_dis_bypass(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_dis_bypass, GET_DIS_BYPASS, if_index);
-}
-EXPORT_SYMBOL(get_dis_bypass);
-
-static int set_bypass_pwoff(int if_index, int bypass_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_bypass_pwoff, SET_BYPASS_PWOFF, if_index,
- bypass_mode);
-}
-EXPORT_SYMBOL(set_bypass_pwoff);
-
-static int get_bypass_pwoff(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass_pwoff, GET_BYPASS_PWOFF, if_index);
-}
-EXPORT_SYMBOL(get_bypass_pwoff);
-
-static int set_bypass_pwup(int if_index, int bypass_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_bypass_pwup, SET_BYPASS_PWUP, if_index,
- bypass_mode);
-}
-EXPORT_SYMBOL(set_bypass_pwup);
-
-static int get_bypass_pwup(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bypass_pwup, GET_BYPASS_PWUP, if_index);
-}
-EXPORT_SYMBOL(get_bypass_pwup);
-
-static int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set)
-{
- int data = ms_timeout;
- int ret = 0;
-
- if (is_dev_sd(if_index)) {
- SET_BPLIB_INT_FN3(set_bypass_wd, int, if_index, int, ms_timeout,
- int *, ms_timeout_set, ret);
- } else {
- ret = doit(SET_BYPASS_WD, if_index, &data);
- if (ret > 0) {
- *ms_timeout_set = ret;
- ret = 0;
- }
- }
- return ret;
-}
-EXPORT_SYMBOL(set_bypass_wd);
-
-static int get_bypass_wd(int if_index, int *ms_timeout_set)
-{
- int *data = ms_timeout_set;
- int ret = 0;
-
- if (is_dev_sd(if_index))
- SET_BPLIB_INT_FN2(get_bypass_wd, int, if_index, int *,
- ms_timeout_set, ret);
- else
- ret = doit(GET_BYPASS_WD, if_index, data);
- return ret;
-}
-EXPORT_SYMBOL(get_bypass_wd);
-
-static int get_wd_expire_time(int if_index, int *ms_time_left)
-{
- int *data = ms_time_left, ret = 0;
-
- if (is_dev_sd(if_index)) {
- SET_BPLIB_INT_FN2(get_wd_expire_time, int, if_index, int *,
- ms_time_left, ret);
- } else {
- ret = doit(GET_WD_EXPIRE_TIME, if_index, data);
- if ((ret == 0) && (*data != 0))
- ret = 1;
- }
- return ret;
-}
-EXPORT_SYMBOL(get_wd_expire_time);
-
-static int reset_bypass_wd_timer(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(reset_bypass_wd_timer, RESET_BYPASS_WD_TIMER,
- if_index);
-}
-EXPORT_SYMBOL(reset_bypass_wd_timer);
-
-static int set_std_nic(int if_index, int bypass_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_std_nic, SET_STD_NIC, if_index, bypass_mode);
-}
-EXPORT_SYMBOL(set_std_nic);
-
-static int get_std_nic(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_std_nic, GET_STD_NIC, if_index);
-}
-EXPORT_SYMBOL(get_std_nic);
-
-static int set_tx(int if_index, int tx_state)
-{
- DO_BPLIB_SET_ARG_FN(set_tx, SET_TX, if_index, tx_state);
-}
-EXPORT_SYMBOL(set_tx);
-
-static int get_tx(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tx, GET_TX, if_index);
-}
-EXPORT_SYMBOL(get_tx);
-
-static int set_tap(int if_index, int tap_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_tap, SET_TAP, if_index, tap_mode);
-}
-EXPORT_SYMBOL(set_tap);
-
-static int get_tap(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tap, GET_TAP, if_index);
-}
-EXPORT_SYMBOL(get_tap);
-
-static int get_tap_change(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tap_change, GET_TAP_CHANGE, if_index);
-}
-EXPORT_SYMBOL(get_tap_change);
-
-static int set_dis_tap(int if_index, int dis_tap)
-{
- DO_BPLIB_SET_ARG_FN(set_dis_tap, SET_DIS_TAP, if_index, dis_tap);
-}
-EXPORT_SYMBOL(set_dis_tap);
-
-static int get_dis_tap(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_dis_tap, GET_DIS_TAP, if_index);
-}
-EXPORT_SYMBOL(get_dis_tap);
-
-static int set_tap_pwup(int if_index, int tap_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_tap_pwup, SET_TAP_PWUP, if_index, tap_mode);
-}
-EXPORT_SYMBOL(set_tap_pwup);
-
-static int get_tap_pwup(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tap_pwup, GET_TAP_PWUP, if_index);
-}
-EXPORT_SYMBOL(get_tap_pwup);
-
-static int set_bp_disc(int if_index, int disc_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_bp_disc, SET_DISC, if_index, disc_mode);
-}
-EXPORT_SYMBOL(set_bp_disc);
-
-static int get_bp_disc(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bp_disc, GET_DISC, if_index);
-}
-EXPORT_SYMBOL(get_bp_disc);
-
-static int get_bp_disc_change(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bp_disc_change, GET_DISC_CHANGE, if_index);
-}
-EXPORT_SYMBOL(get_bp_disc_change);
-
-static int set_bp_dis_disc(int if_index, int dis_disc)
-{
- DO_BPLIB_SET_ARG_FN(set_bp_dis_disc, SET_DIS_DISC, if_index, dis_disc);
-}
-EXPORT_SYMBOL(set_bp_dis_disc);
-
-static int get_bp_dis_disc(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bp_dis_disc, GET_DIS_DISC, if_index);
-}
-EXPORT_SYMBOL(get_bp_dis_disc);
-
-static int set_bp_disc_pwup(int if_index, int disc_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_bp_disc_pwup, SET_DISC_PWUP, if_index,
- disc_mode);
-}
-EXPORT_SYMBOL(set_bp_disc_pwup);
-
-static int get_bp_disc_pwup(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_bp_disc_pwup, GET_DISC_PWUP, if_index);
-}
-EXPORT_SYMBOL(get_bp_disc_pwup);
-
-static int set_wd_exp_mode(int if_index, int mode)
-{
- DO_BPLIB_SET_ARG_FN(set_wd_exp_mode, SET_WD_EXP_MODE, if_index, mode);
-}
-EXPORT_SYMBOL(set_wd_exp_mode);
-
-static int get_wd_exp_mode(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_wd_exp_mode, GET_WD_EXP_MODE, if_index);
-}
-EXPORT_SYMBOL(get_wd_exp_mode);
-
-static int set_wd_autoreset(int if_index, int time)
-{
- DO_BPLIB_SET_ARG_FN(set_wd_autoreset, SET_WD_AUTORESET, if_index, time);
-}
-EXPORT_SYMBOL(set_wd_autoreset);
-
-static int get_wd_autoreset(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_wd_autoreset, GET_WD_AUTORESET, if_index);
-}
-EXPORT_SYMBOL(get_wd_autoreset);
-
-static int set_tpl(int if_index, int tpl_mode)
-{
- DO_BPLIB_SET_ARG_FN(set_tpl, SET_TPL, if_index, tpl_mode);
-}
-EXPORT_SYMBOL(set_tpl);
-
-static int get_tpl(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tpl, GET_TPL, if_index);
-}
-EXPORT_SYMBOL(get_tpl);
-
-static int set_bp_hw_reset(int if_index, int mode)
-{
- DO_BPLIB_SET_ARG_FN(set_tpl, SET_BP_HW_RESET, if_index, mode);
-}
-EXPORT_SYMBOL(set_bp_hw_reset);
-
-static int get_bp_hw_reset(int if_index)
-{
- DO_BPLIB_GET_ARG_FN(get_tpl, GET_BP_HW_RESET, if_index);
-}
-EXPORT_SYMBOL(get_bp_hw_reset);
-
-static int get_bypass_info(int if_index, struct bp_info *bp_info)
-{
- int ret = 0;
-
- if (is_dev_sd(if_index)) {
- SET_BPLIB_INT_FN2(get_bypass_info, int, if_index,
- struct bp_info *, bp_info, ret);
- } else {
- struct net_device *dev;
- struct net_device *n;
-
- for_each_netdev_safe(&init_net, dev, n) {
- if (dev->ifindex == if_index) {
- struct if_bypass_info *bypass_cb;
- struct ifreq ifr;
-
- memset(&ifr, 0, sizeof(ifr));
- bypass_cb = (struct if_bypass_info *)&ifr;
- bypass_cb->cmd = GET_BYPASS_INFO;
-
- if (dev->netdev_ops &&
- dev->netdev_ops->ndo_do_ioctl)
- ret = dev->netdev_ops->ndo_do_ioctl(dev,
- &ifr, SIOCGIFBYPASS);
- else
- ret = -1;
- if (ret == 0)
- memcpy(bp_info, &bypass_cb->bp_info,
- sizeof(struct bp_info));
- ret = ret < 0 ? -1 : 0;
- break;
- }
- }
- }
- return ret;
-}
-EXPORT_SYMBOL(get_bypass_info);
-
-static int __init init_lib_module(void)
-{
- printk(VERSION);
- return 0;
-}
-
-static void __exit cleanup_lib_module(void)
-{
-}
-
-module_init(init_lib_module);
-module_exit(cleanup_lib_module);
diff --git a/drivers/staging/silicom/bypasslib/libbp_sd.h b/drivers/staging/silicom/bypasslib/libbp_sd.h
deleted file mode 100644
index cac4b0b2ed78..000000000000
--- a/drivers/staging/silicom/bypasslib/libbp_sd.h
+++ /dev/null
@@ -1,532 +0,0 @@
-/******************************************************************************/
-/* */
-/* bypass library, Copyright (c) 2004 Silicom, Ltd */
-/* 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, located in the file LICENSE. */
-/* */
-/* Ver 1.0.0 */
-/* */
-/* libbypass.h */
-/* */
-/******************************************************************************/
-
-/**
- * is_bypass - check if device is a Bypass controlling device
- * @if_index: network device index
- *
- * Output:
- * 1 - if device is bypass controlling device,
- * 0 - if device is bypass slave device
- * -1 - device not support Bypass
- **/
-int is_bypass_sd(int if_index);
-
-/**
- * get_bypass_slave - get second port participate in the Bypass pair
- * @if_index: network device index
- *
- * Output:
- * network device index of the slave device
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_slave_sd(int if_index);
-
-/**
- * get_bypass_caps - get second port participate in the Bypass pair
- * @if_index: network device index
- *
- * Output:
- * flags word on success;flag word is a 32-bit mask word with each bit defines
- * different capability as described bellow.
- * Value of 1 for supporting this feature. 0 for not supporting this feature.
- * -1 - on failure (if the device is not capable of the operation or not a
- * Bypass device)
- * Bit feature description
- *
- * 0 BP_CAP The interface is Bypass capable in general
- *
- * 1 BP_STATUS_CAP The interface can report of the current Bypass
- * mode
- *
- * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass
- * mode from the last time the mode was defined
- *
- * 3 SW_CTL_CAP The interface is Software controlled capable for
- * bypass/non bypass modes.
- *
- * 4 BP_DIS_CAP The interface is capable of disabling the Bypass
- * mode at all times. This mode will retain its
- * mode even during power loss and also after power
- * recovery. This will overcome on any bypass
- * operation due to watchdog timeout or set bypass
- * command.
- *
- * 5 BP_DIS_STATUS_CAP The interface can report of the current
- * DIS_BP_CAP
- *
- * 6 STD_NIC_CAP The interface is capable to be configured to
- * operate as standard, non Bypass, NIC interface
- * (have direct connection to interfaces at all
- * power modes)
- *
- * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off
- * state
- *
- * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at
- * power off state without effecting all the other
- * states of operation
- *
- * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off
- * state can be controlled by software without
- * effecting any other state
- *
- *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power
- * is turned on (until the system take control of
- * the bypass functionality)
- *
- *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode
- * when power is turned on (until the system take
- * control of the bypass functionality)
- *
- *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can
- * be controlled by software
- *
- *13 WD_CTL_CAP The interface has watchdog capabilities to turn
- * to Bypass mode when not reset for defined period
- * of time.
- *
- *14 WD_STATUS_CAP The interface can report on the watchdog status
- * (Active/inactive)
- *
- *15 WD_TIMEOUT_CAP The interface can report the time left till
- * watchdog triggers to Bypass mode.
- *
- *16-31 RESERVED
- *
- * **/
-int get_bypass_caps_sd(int if_index);
-
-/**
- * get_wd_set_caps - Obtain watchdog timer setting capabilities
- * @if_index: network device index
- *
- * Output:
- *
- * Set of numbers defining the various parameters of the watchdog capable
- * to be set to as described bellow.
- * -1 - on failure (device not support Bypass or it's a slave device)
- *
- * Bit feature description
- *
- * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units
- *
- * 4 WD_STEP_TIME The steps of the WD timer in
- * 0 - for linear steps (WD_MIN_TIME * X)
- * 1 - for multiply by 2 from previous step
- * (WD_MIN_TIME * 2^X)
- *
- * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X
- * (X bit available for defining the value)
- *
- *
- *
- **/
-int get_wd_set_caps_sd(int if_index);
-
-/**
- * set_bypass - set Bypass state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode (1=on, 0=off)
- * Output:
- * 0 - on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int set_bypass_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass - Get Bypass mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_sd(int if_index);
-
-/**
- * get_bypass_change - Get change of Bypass mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_change_sd(int if_index);
-
-/**
- * set_dis_bypass - Set Disable Bypass mode
- * @if_index: network device index of the controlling device
- * @dis_bypass: disable bypass(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int set_dis_bypass_sd(int if_index, int dis_bypass);
-
-/**
- * get_dis_bypass - Get Disable Bypass mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal Bypass mode/ Disable bypass)
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int get_dis_bypass_sd(int if_index);
-
-/**
- * set_bypass_pwoff - Set Bypass mode at power-off state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int set_bypass_pwoff_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass_pwoff - Get Bypass mode state at power-off state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable bypass at power off state / normal Bypass mode)
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int get_bypass_pwoff_sd(int if_index);
-
-/**
- * set_bypass_pwup - Set Bypass mode at power-up state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int set_bypass_pwup_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass_pwup - Get Bypass mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable bypass at power up state / normal Bypass mode)
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int get_bypass_pwup_sd(int if_index);
-
-/**
- * set_bypass_wd - Set watchdog state
- * @if_index: network device index of the controlling device
- * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog
- * timer
- * @ms_timeout_set(output): requested timeout (in ms units), that the adapter
- * supports and will be used by the watchdog
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set);
-
-/**
- * get_bypass_wd - Get watchdog state
- * @if_index: network device index of the controlling device
- * @ms_timeout (output): WDT timeout (in ms units),
- * -1 for unknown wdt status
- * 0 if WDT is disabled
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int get_bypass_wd_sd(int if_index, int *ms_timeout_set);
-
-/**
- * get_wd_expire_time - Get watchdog expire
- * @if_index: network device index of the controlling device
- * @ms_time_left (output): time left till watchdog time expire,
- * -1 if WDT has expired
- * 0 if WDT is disabled
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device or unknown wdt status)
- **/
-int get_wd_expire_time_sd(int if_index, int *ms_time_left);
-
-/**
- * reset_bypass_wd_timer - Reset watchdog timer
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 1 - on success
- * 0 - watchdog is not configured
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device or unknown wdt status)
- **/
-int reset_bypass_wd_timer_sd(int if_index);
-
-/**
- * set_std_nic - Standard NIC mode of operation
- * @if_index: network device index of the controlling device
- * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode)
- *
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int set_std_nic_sd(int if_index, int nic_mode);
-
-/**
- * get_std_nic - Get Standard NIC mode setting
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 0/1 (Default Bypass mode / Standard NIC mode) on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass or it's a slave device)
- **/
-int get_std_nic_sd(int if_index);
-
-/**
- * set_tx - set transmitter enable/disable
- * @if_index: network device index of the controlling device
- * @tx_state: 0/1 (Transmit Disable / Transmit Enable)
- *
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation )
- **/
-int set_tx_sd(int if_index, int tx_state);
-
-/**
- * get_std_nic - get transmitter state (disable / enable)
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 0/1 (ransmit Disable / Transmit Enable) on success
- * -1 - on failure (device is not capable of the operation or device not support
- * Bypass)
- **/
-int get_tx_sd(int if_index);
-
-/**
- * set_tap - set TAP state
- * @if_index: network device index of the controlling device
- * @tap_mode: 1 tap mode , 0 normal nic mode
- * Output:
- * 0 - on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int set_tap_sd(int if_index, int tap_mode);
-
-/**
- * get_tap - Get TAP mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int get_tap_sd(int if_index);
-
-/**
- * get_tap_change - Get change of TAP mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int get_tap_change_sd(int if_index);
-
-/**
- * set_dis_tap - Set Disable TAP mode
- * @if_index: network device index of the controlling device
- * @dis_tap: disable tap(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not support
- * TAP or it's a slave device)
- **/
-int set_dis_tap_sd(int if_index, int dis_tap);
-
-/**
- * get_dis_tap - Get Disable TAP mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal TAP mode/ Disable TAP)
- * -1 - on failure (device is not capable of the operation or device not support
- * TAP or it's a slave device)
- **/
-int get_dis_tap_sd(int if_index);
-
-/**
- * set_tap_pwup - Set TAP mode at power-up state
- * @if_index: network device index of the controlling device
- * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not
- * support TAP or it's a slave device)
- **/
-int set_tap_pwup_sd(int if_index, int tap_mode);
-
-/**
- * get_tap_pwup - Get TAP mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable TAP at power up state / normal TAP mode)
- * -1 - on failure (device is not capable of the operation or device not
- * support TAP or it's a slave device)
- **/
-int get_tap_pwup_sd(int if_index);
-
-/**
- * set_bp_disc - set Disconnect state
- * @if_index: network device index of the controlling device
- * @tap_mode: 1 disc mode , 0 non-disc mode
- * Output:
- * 0 - on success
- * -1 - on failure (device not support Disconnect or it's a slave device)
- **/
-int set_bp_disc_sd(int if_index, int disc_mode);
-
-/**
- * get_bp_disc - Get Disconnect mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Disconnect or it's a slave device)
- **/
-int get_bp_disc_sd(int if_index);
-
-/**
- * get_bp_disc_change - Get change of Disconnect mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Disconnect or it's a slave device)
- **/
-int get_bp_disc_change_sd(int if_index);
-
-/**
- * set_bp_dis_disc - Set Disable Disconnect mode
- * @if_index: network device index of the controlling device
- * @dis_tap: disable tap(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable ofthe operation or device not
- * support Disconnect or it's a slave device)
- **/
-int set_bp_dis_disc_sd(int if_index, int dis_disc);
-
-/**
- * get_dis_tap - Get Disable Disconnect mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal Disconnect mode/ Disable Disconnect)
- * -1 - on failure (device is not capable of the operation or device not
- * support Disconnect or it's a slave device)
- **/
-int get_bp_dis_disc_sd(int if_index);
-
-/**
- * set_bp_disc_pwup - Set Disconnect mode at power-up state
- * @if_index: network device index of the controlling device
- * @disc_mode: tap mode setting at power up state (1=Disc en, 0=Disc Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation or device not
- * support Disconnect or it's a slave device)
- **/
-int set_bp_disc_pwup_sd(int if_index, int disc_mode);
-
-/**
- * get_bp_disc_pwup - Get Disconnect mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable Disconnect at power up state / normal Disconnect
- * mode)
- * -1 - on failure (device is not capable of the operation or device not
- * support TAP or it's a slave device)
- **/
-int get_bp_disc_pwup_sd(int if_index);
-
-/**
- * set_wd_exp_mode - Set adapter state when WDT expired.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 0 - on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int set_wd_exp_mode_sd(int if_index, int bypass_mode);
-
-/**
- * get_wd_exp_mode - Get adapter state when WDT expired.
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (bypass/tap) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_wd_exp_mode_sd(int if_index);
-
-/**
- * set_wd_autoreset - reset WDT periodically.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 1 - on success
- * -1 - on failure (device is not capable of the operation or device not
- * support Bypass or it's a slave device or unknown wdt
- * status)
- **/
-int set_wd_autoreset_sd(int if_index, int time);
-
-/**
- * set_wd_autoreset - reset WDT periodically.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 1 - on success
- * -1 - on failure (device is not capable of the operation or device not
- * support Bypass or it's a slave device or unknown wdt
- * status)
- **/
-int get_wd_autoreset_sd(int if_index);
-
-/**
- * set_tpl - set TPL state
- * @if_index: network device index of the controlling device
- * @tpl_mode: 1 tpl mode , 0 normal nic mode
- * Output:
- * 0 - on success
- * -1 - on failure (device not support TPL)
- **/
-int set_tpl_sd(int if_index, int tpl_mode);
-
-/**
- * get_tpl - Get TPL mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support TPL or it's a slave device)
- **/
-int get_tpl_sd(int if_index);
-
-int get_bypass_info_sd(int if_index, struct bp_info *bp_info);
-int bp_if_scan_sd(void);
-/*int get_dev_num_sd(void);*/
diff --git a/drivers/staging/silicom/libbp_sd.h b/drivers/staging/silicom/libbp_sd.h
deleted file mode 100644
index 065277f81c78..000000000000
--- a/drivers/staging/silicom/libbp_sd.h
+++ /dev/null
@@ -1,550 +0,0 @@
-/******************************************************************************/
-/* */
-/* bypass library, Copyright (c) 2004 Silicom, Ltd */
-/* 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, located in the file LICENSE. */
-/* */
-/* Ver 1.0.0 */
-/* */
-/* libbypass.h */
-/* */
-/******************************************************************************/
-
-#define BP_CAP 0x01 /* BIT_0 */
-#define BP_STATUS_CAP 0x02
-#define BP_STATUS_CHANGE_CAP 0x04
-#define SW_CTL_CAP 0x08
-#define BP_DIS_CAP 0x10
-#define BP_DIS_STATUS_CAP 0x20
-#define STD_NIC_CAP 0x40
-#define BP_PWOFF_ON_CAP 0x80
-#define BP_PWOFF_OFF_CAP 0x0100
-#define BP_PWOFF_CTL_CAP 0x0200
-#define BP_PWUP_ON_CAP 0x0400
-#define BP_PWUP_OFF_CAP 0x0800
-#define BP_PWUP_CTL_CAP 0x1000
-#define WD_CTL_CAP 0x2000
-#define WD_STATUS_CAP 0x4000
-#define WD_TIMEOUT_CAP 0x8000
-#define TX_CTL_CAP 0x10000
-#define TX_STATUS_CAP 0x20000
-#define TAP_CAP 0x40000
-#define TAP_STATUS_CAP 0x80000
-#define TAP_STATUS_CHANGE_CAP 0x100000
-#define TAP_DIS_CAP 0x200000
-#define TAP_DIS_STATUS_CAP 0x400000
-#define TAP_PWUP_ON_CAP 0x800000
-#define TAP_PWUP_OFF_CAP 0x1000000
-#define TAP_PWUP_CTL_CAP 0x2000000
-#define NIC_CAP_NEG 0x4000000 /* BIT 26 */
-
-#define WD_MIN_TIME_GET(desc) (desc & 0xf)
-#define WDT_STEP_TIME 0x10
-
-struct bp_info {
- char prod_name[14];
- unsigned char fw_ver;
-};
-
-/**
- * is_bypass - check if device is a Bypass controlling device
- * @if_index: network device index
- *
- * Output:
- * 1 - if device is bypass controlling device,
- * 0 - if device is bypass slave device
- * -1 - device not support Bypass
- **/
-int is_bypass_sd(int if_index);
-
-/**
- * get_bypass_slave - get second port participate in the Bypass pair
- * @if_index: network device index
- *
- * Output:
- * network device index of the slave device
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_slave_sd(int if_index);
-
-/**
- * get_bypass_caps - get second port participate in the Bypass pair
- * @if_index: network device index
- *
- * Output:
- * flags word on success;flag word is a 32-bit mask word with each bit defines different
- * capability as described bellow.
- * Value of 1 for supporting this feature. 0 for not supporting this feature.
- * -1 - on failure (if the device is not capable of the operation or not a Bypass device)
- * Bit feature description
- *
- * 0 BP_CAP The interface is Bypass capable in general
- *
- * 1 BP_STATUS_CAP The interface can report of the current Bypass mode
- *
- * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from
- * the last time the mode was defined
- *
- * 3 SW_CTL_CAP The interface is Software controlled capable for bypass/non bypass modes.
- *
- * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times.
- * This mode will retain its mode even during power loss and also after
- * power recovery. This will overcome on any bypass operation due to
- * watchdog timeout or set bypass command.
- *
- * 5 BP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP
- *
- * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass,
- * NIC interface (have direct connection to interfaces at all power modes)
- *
- * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off state
- *
- * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without
- * effecting all the other states of operation
- *
- * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by
- * software without effecting any other state
- *
- *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on
- * (until the system take control of the bypass functionality)
- *
- *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on
- * (until the system take control of the bypass functionality)
- *
- *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be controlled by software
- *
- *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset
- * for defined period of time.
- *
- *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive)
- *
- *15 WD_TIMEOUT_CAP The interface can report the time left till watchdog triggers to Bypass mode.
- *
- *16-31 RESERVED
- *
- * **/
-int get_bypass_caps_sd(int if_index);
-
-/**
- * get_wd_set_caps - Obtain watchdog timer setting capabilities
- * @if_index: network device index
- *
- * Output:
- *
- * Set of numbers defining the various parameters of the watchdog capable
- * to be set to as described bellow.
- * -1 - on failure (device not support Bypass or it's a slave device)
- *
- * Bit feature description
- *
- * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units
- *
- * 4 WD_STEP_TIME The steps of the WD timer in
- * 0 - for linear steps (WD_MIN_TIME * X)
- * 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X)
- *
- * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X
- * (X bit available for defining the value)
- *
- *
- *
- **/
-int get_wd_set_caps_sd(int if_index);
-
-/**
- * set_bypass - set Bypass state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode (1=on, 0=off)
- * Output:
- * 0 - on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int set_bypass_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass - Get Bypass mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_sd(int if_index);
-
-/**
- * get_bypass_change - Get change of Bypass mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_bypass_change_sd(int if_index);
-
-/**
- * set_dis_bypass - Set Disable Bypass mode
- * @if_index: network device index of the controlling device
- * @dis_bypass: disable bypass(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int set_dis_bypass_sd(int if_index, int dis_bypass);
-
-/**
- * get_dis_bypass - Get Disable Bypass mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal Bypass mode/ Disable bypass)
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int get_dis_bypass_sd(int if_index);
-
-/**
- * set_bypass_pwoff - Set Bypass mode at power-off state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int set_bypass_pwoff_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass_pwoff - Get Bypass mode state at power-off state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable bypass at power off state / normal Bypass mode)
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int get_bypass_pwoff_sd(int if_index);
-
-/**
- * set_bypass_pwup - Set Bypass mode at power-up state
- * @if_index: network device index of the controlling device
- * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int set_bypass_pwup_sd(int if_index, int bypass_mode);
-
-/**
- * get_bypass_pwup - Get Bypass mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable bypass at power up state / normal Bypass mode)
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int get_bypass_pwup_sd(int if_index);
-
-/**
- * set_bypass_wd - Set watchdog state
- * @if_index: network device index of the controlling device
- * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer
- * @ms_timeout_set(output): requested timeout (in ms units),
- * that the adapter supports and will be used by the watchdog
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set);
-
-/**
- * get_bypass_wd - Get watchdog state
- * @if_index: network device index of the controlling device
- * @ms_timeout (output): WDT timeout (in ms units),
- * -1 for unknown wdt status
- * 0 if WDT is disabled
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int get_bypass_wd_sd(int if_index, int *ms_timeout_set);
-
-/**
- * get_wd_expire_time - Get watchdog expire
- * @if_index: network device index of the controlling device
- * @ms_time_left (output): time left till watchdog time expire,
- * -1 if WDT has expired
- * 0 if WDT is disabled
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device or unknown wdt status)
- **/
-int get_wd_expire_time_sd(int if_index, int *ms_time_left);
-
-/**
- * reset_bypass_wd_timer - Reset watchdog timer
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 1 - on success
- * 0 - watchdog is not configured
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device or unknown wdt status)
- **/
-int reset_bypass_wd_timer_sd(int if_index);
-
-/**
- * set_std_nic - Standard NIC mode of operation
- * @if_index: network device index of the controlling device
- * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode)
- *
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int set_std_nic_sd(int if_index, int nic_mode);
-
-/**
- * get_std_nic - Get Standard NIC mode setting
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 0/1 (Default Bypass mode / Standard NIC mode) on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device)
- **/
-int get_std_nic_sd(int if_index);
-
-/**
- * set_tx - set transmitter enable/disable
- * @if_index: network device index of the controlling device
- * @tx_state: 0/1 (Transmit Disable / Transmit Enable)
- *
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation )
- **/
-int set_tx_sd(int if_index, int tx_state);
-
-/**
- * get_tx - get transmitter state (disable / enable)
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 0/1 (ransmit Disable / Transmit Enable) on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass)
- **/
-int get_tx_sd(int if_index);
-
-/**
- * set_tpl - set TPL enable/disable
- * @if_index: network device index of the controlling device
- * @tx_state: 0/1 (TPL Disable / TPL Enable)
- *
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation )
- **/
-int set_tpl_sd(int if_index, int tpl_state);
-
-/**
- * get_tpl - get TPL state (disable / enable)
- * @if_index: network device index of the controlling device
- *
- * Output:
- * 0/1 (TPL Disable / TPL Enable) on success
- * -1 - on failure (device is not capable of the operation)
- **/
-int get_tpl_sd(int if_index);
-
-int get_bp_hw_reset_sd(int if_index);
-
-int set_bp_hw_reset_sd(int if_index, int status);
-
-/**
- * set_tap - set TAP state
- * @if_index: network device index of the controlling device
- * @tap_mode: 1 tap mode , 0 normal nic mode
- * Output:
- * 0 - on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int set_tap_sd(int if_index, int tap_mode);
-
-/**
- * get_tap - Get TAP mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int get_tap_sd(int if_index);
-
-/**
- * get_tap_change - Get change of TAP mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support TAP or it's a slave device)
- **/
-int get_tap_change_sd(int if_index);
-
-/**
- * set_dis_tap - Set Disable TAP mode
- * @if_index: network device index of the controlling device
- * @dis_tap: disable tap(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support TAP
- * or it's a slave device)
- **/
-int set_dis_tap_sd(int if_index, int dis_tap);
-
-/**
- * get_dis_tap - Get Disable TAP mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal TAP mode/ Disable TAP)
- * -1 - on failure (device is not capable of the operation ordevice not support TAP
- * or it's a slave device)
- **/
-int get_dis_tap_sd(int if_index);
-
-/**
- * set_tap_pwup - Set TAP mode at power-up state
- * @if_index: network device index of the controlling device
- * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support TAP
- * or it's a slave device)
- **/
-int set_tap_pwup_sd(int if_index, int tap_mode);
-
-/**
- * get_tap_pwup - Get TAP mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable TAP at power up state / normal TAP mode)
- * -1 - on failure (device is not capable of the operation ordevice not support TAP
- * or it's a slave device)
- **/
-int get_tap_pwup_sd(int if_index);
-
-/**
- * set_wd_exp_mode - Set adapter state when WDT expired.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 0 - on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int set_wd_exp_mode_sd(int if_index, int bypass_mode);
-
-/**
- * get_wd_exp_mode - Get adapter state when WDT expired.
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (bypass/tap) on success
- * -1 - on failure (device not support Bypass or it's a slave device)
- **/
-int get_wd_exp_mode_sd(int if_index);
-
-/**
- * set_wd_autoreset - reset WDT periodically.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 1 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device or unknown wdt status)
- **/
-int set_wd_autoreset_sd(int if_index, int time);
-
-/**
- * set_wd_autoreset - reset WDT periodically.
- * @if_index: network device index of the controlling device
- * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode)
- * Output:
- * 1 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support Bypass
- * or it's a slave device or unknown wdt status)
- **/
-int get_wd_autoreset_sd(int if_index);
-/**
- * set_disc - set DISC state
- * @if_index: network device index of the controlling device
- * @tap_mode: 1 DISC mode , 0 normal nic mode
- * Output:
- * 0 - on success
- * -1 - on failure (device not support disconnect or it's a slave device)
- **/
-int set_bp_disc_sd(int if_index, int disc_mode);
-
-/**
- * get_disc - Get disc mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support disconnect or it's a slave device)
- **/
-int get_bp_disc_sd(int if_index);
-
-/**
- * get_disc_change - Get change of DISC mode state from last status check
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - (off/on) on success
- * -1 - on failure (device not support disconnect or it's a slave device)
- **/
-int get_bp_disc_change_sd(int if_index);
-
-/**
- * set_dis_disc - Set Disable DISC mode
- * @if_index: network device index of the controlling device
- * @dis_disc: disable disconnect(1=dis, 0=en)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support DISC
- * or it's a slave device)
- **/
-int set_bp_dis_disc_sd(int if_index, int dis_disc);
-
-/**
- * get_dis_disc - Get Disable DISC mode state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (normal DISC mode/ Disable DISC)
- * -1 - on failure (device is not capable of the operation ordevice not support TAP
- * or it's a slave device)
- **/
-int get_bp_dis_disc_sd(int if_index);
-
-/**
- * set_disc_pwup - Set DISC mode at power-up state
- * @if_index: network device index of the controlling device
- * @disc_mode: DISC mode setting at power up state (1= en, 0= Dis)
- * Output:
- * 0 - on success
- * -1 - on failure (device is not capable of the operation ordevice not support DISC
- * or it's a slave device)
- **/
-int set_bp_disc_pwup_sd(int if_index, int disc_mode);
-
-/**
- * get_disc_pwup - Get DISC mode state at power-up state
- * @if_index: network device index of the controlling device
- * Output:
- * 0/1 - on success (Disable DISC at power up state / normal DISC mode)
- * -1 - on failure (device is not capable of the operation ordevice not support DISC
- * or it's a slave device)
- **/
-int get_bp_disc_pwup_sd(int if_index);
-
-int get_bypass_info_sd(int if_index, struct bp_info *bp_info);
-int bp_if_scan_sd(void);
-/*int get_dev_num_sd(void);*/
diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h
index a03703deeaf8..d9dc1d5ed551 100644
--- a/drivers/staging/skein/skein_iv.h
+++ b/drivers/staging/skein/skein_iv.h
@@ -20,7 +20,7 @@
#define MK_64 SKEIN_MK_64
/* blkSize = 256 bits. hashSize = 128 bits */
-const u64 SKEIN_256_IV_128[] = {
+static const u64 SKEIN_256_IV_128[] = {
MK_64(0xE1111906, 0x964D7260),
MK_64(0x883DAAA7, 0x7C8D811C),
MK_64(0x10080DF4, 0x91960F7A),
@@ -28,7 +28,7 @@ const u64 SKEIN_256_IV_128[] = {
};
/* blkSize = 256 bits. hashSize = 160 bits */
-const u64 SKEIN_256_IV_160[] = {
+static const u64 SKEIN_256_IV_160[] = {
MK_64(0x14202314, 0x72825E98),
MK_64(0x2AC4E9A2, 0x5A77E590),
MK_64(0xD47A5856, 0x8838D63E),
@@ -36,7 +36,7 @@ const u64 SKEIN_256_IV_160[] = {
};
/* blkSize = 256 bits. hashSize = 224 bits */
-const u64 SKEIN_256_IV_224[] = {
+static const u64 SKEIN_256_IV_224[] = {
MK_64(0xC6098A8C, 0x9AE5EA0B),
MK_64(0x876D5686, 0x08C5191C),
MK_64(0x99CB88D7, 0xD7F53884),
@@ -44,7 +44,7 @@ const u64 SKEIN_256_IV_224[] = {
};
/* blkSize = 256 bits. hashSize = 256 bits */
-const u64 SKEIN_256_IV_256[] = {
+static const u64 SKEIN_256_IV_256[] = {
MK_64(0xFC9DA860, 0xD048B449),
MK_64(0x2FCA6647, 0x9FA7D833),
MK_64(0xB33BC389, 0x6656840F),
@@ -52,7 +52,7 @@ const u64 SKEIN_256_IV_256[] = {
};
/* blkSize = 512 bits. hashSize = 128 bits */
-const u64 SKEIN_512_IV_128[] = {
+static const u64 SKEIN_512_IV_128[] = {
MK_64(0xA8BC7BF3, 0x6FBF9F52),
MK_64(0x1E9872CE, 0xBD1AF0AA),
MK_64(0x309B1790, 0xB32190D3),
@@ -64,7 +64,7 @@ const u64 SKEIN_512_IV_128[] = {
};
/* blkSize = 512 bits. hashSize = 160 bits */
-const u64 SKEIN_512_IV_160[] = {
+static const u64 SKEIN_512_IV_160[] = {
MK_64(0x28B81A2A, 0xE013BD91),
MK_64(0xC2F11668, 0xB5BDF78F),
MK_64(0x1760D8F3, 0xF6A56F12),
@@ -76,7 +76,7 @@ const u64 SKEIN_512_IV_160[] = {
};
/* blkSize = 512 bits. hashSize = 224 bits */
-const u64 SKEIN_512_IV_224[] = {
+static const u64 SKEIN_512_IV_224[] = {
MK_64(0xCCD06162, 0x48677224),
MK_64(0xCBA65CF3, 0xA92339EF),
MK_64(0x8CCD69D6, 0x52FF4B64),
@@ -88,7 +88,7 @@ const u64 SKEIN_512_IV_224[] = {
};
/* blkSize = 512 bits. hashSize = 256 bits */
-const u64 SKEIN_512_IV_256[] = {
+static const u64 SKEIN_512_IV_256[] = {
MK_64(0xCCD044A1, 0x2FDB3E13),
MK_64(0xE8359030, 0x1A79A9EB),
MK_64(0x55AEA061, 0x4F816E6F),
@@ -100,7 +100,7 @@ const u64 SKEIN_512_IV_256[] = {
};
/* blkSize = 512 bits. hashSize = 384 bits */
-const u64 SKEIN_512_IV_384[] = {
+static const u64 SKEIN_512_IV_384[] = {
MK_64(0xA3F6C6BF, 0x3A75EF5F),
MK_64(0xB0FEF9CC, 0xFD84FAA4),
MK_64(0x9D77DD66, 0x3D770CFE),
@@ -112,7 +112,7 @@ const u64 SKEIN_512_IV_384[] = {
};
/* blkSize = 512 bits. hashSize = 512 bits */
-const u64 SKEIN_512_IV_512[] = {
+static const u64 SKEIN_512_IV_512[] = {
MK_64(0x4903ADFF, 0x749C51CE),
MK_64(0x0D95DE39, 0x9746DF03),
MK_64(0x8FD19341, 0x27C79BCE),
@@ -124,7 +124,7 @@ const u64 SKEIN_512_IV_512[] = {
};
/* blkSize = 1024 bits. hashSize = 384 bits */
-const u64 SKEIN_1024_IV_384[] = {
+static const u64 SKEIN_1024_IV_384[] = {
MK_64(0x5102B6B8, 0xC1894A35),
MK_64(0xFEEBC9E3, 0xFE8AF11A),
MK_64(0x0C807F06, 0xE32BED71),
@@ -144,7 +144,7 @@ const u64 SKEIN_1024_IV_384[] = {
};
/* blkSize = 1024 bits. hashSize = 512 bits */
-const u64 SKEIN_1024_IV_512[] = {
+static const u64 SKEIN_1024_IV_512[] = {
MK_64(0xCAEC0E5D, 0x7C1B1B18),
MK_64(0xA01B0E04, 0x5F03E802),
MK_64(0x33840451, 0xED912885),
@@ -164,7 +164,7 @@ const u64 SKEIN_1024_IV_512[] = {
};
/* blkSize = 1024 bits. hashSize = 1024 bits */
-const u64 SKEIN_1024_IV_1024[] = {
+static const u64 SKEIN_1024_IV_1024[] = {
MK_64(0xD593DA07, 0x41E72355),
MK_64(0x15B5E511, 0xAC73E00C),
MK_64(0x5180E5AE, 0xBAF2C4F0),
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index 48841e7c2f74..50ece291fc6a 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -740,9 +740,9 @@ static bool slic_mac_filter(struct adapter *adapter,
if (opts & MAC_BCAST) {
adapter->rcv_broadcasts++;
return true;
- } else {
- return false;
}
+
+ return false;
}
if (is_multicast_ether_addr(ether_frame->ether_dhost)) {
@@ -763,10 +763,11 @@ static bool slic_mac_filter(struct adapter *adapter,
}
mcaddr = mcaddr->next;
}
- return false;
- } else {
+
return false;
}
+
+ return false;
}
if (opts & MAC_DIRECTED) {
adapter->rcv_unicasts++;
@@ -2714,9 +2715,10 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
dev_err(&adapter->pcidev->dev,
"Failed to allocate DMA memory for EEPROM.\n");
return -ENOMEM;
- } else {
- memset(peeprom, 0, sizeof(struct slic_eeprom));
}
+
+ memset(peeprom, 0, sizeof(struct slic_eeprom));
+
slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
mdelay(1);
pshmem = (struct slic_shmem *)(unsigned long)
@@ -2751,11 +2753,11 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
slic_upr_request_complete(adapter, 0);
break;
- } else {
- adapter->pshmem->isr = 0;
- slic_reg32_write(&slic_regs->slic_isr,
- 0, FLUSH);
}
+
+ adapter->pshmem->isr = 0;
+ slic_reg32_write(&slic_regs->slic_isr,
+ 0, FLUSH);
} else {
mdelay(1);
i++;
diff --git a/drivers/staging/speakup/TODO b/drivers/staging/speakup/TODO
index c3612e4b8ac8..3094799cf6a0 100644
--- a/drivers/staging/speakup/TODO
+++ b/drivers/staging/speakup/TODO
@@ -1,6 +1,6 @@
Speakup project home: http://www.linux-speakup.org
-Mailing List: speakup@braille.uwo.ca
+Mailing List: speakup@linux-speakup.org
Speakup is a kernel based screen review package for the linux operating
system. It allows blind users to interact with applications on the
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 7de79d59a4cd..0cd3cdba8644 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -2067,7 +2067,7 @@ speakup_key(struct vc_data *vc, int shift_state, int keycode, u_short keysym,
if (up_flag)
goto out;
if (last_keycode == keycode &&
- last_spk_jiffy + MAX_DELAY > jiffies) {
+ time_after(last_spk_jiffy + MAX_DELAY, jiffies)) {
spk_close_press = 1;
offset = spk_shift_table[shift_info + 32];
/* double press? */
diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c
index af848686be71..c07c9670eef4 100644
--- a/drivers/staging/speakup/speakup_dectlk.c
+++ b/drivers/staging/speakup/speakup_dectlk.c
@@ -267,7 +267,7 @@ static void do_catch_up(struct spk_synth *synth)
else if (ch <= SPACE) {
if (!in_escape && strchr(",.!?;:", last))
spk_serial_out(PROCSPEECH);
- if (jiffies >= jiff_max) {
+ if (time_after_eq(jiffies, jiff_max)) {
if (!in_escape)
spk_serial_out(PROCSPEECH);
spin_lock_irqsave(&speakup_info.spinlock,
diff --git a/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS b/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS
deleted file mode 100644
index 86f578727f91..000000000000
--- a/drivers/staging/tidspbridge/Documentation/CONTRIBUTORS
+++ /dev/null
@@ -1,45 +0,0 @@
-TI DSP/Bridge Driver - Contributors File
-
-The DSP/Bridge project wish to thank all of its contributors, current bridge
-driver is the result of the work of all of them. If any name is accidentally
-omitted, let us know by sending a mail to omar.ramirez@ti.com or
-x095840@ti.com.
-
-Please keep the following list in alphabetical order.
-
- Suman Anna
- Sripal Bagadia
- Felipe Balbi
- Ohad Ben-Cohen
- Phil Carmody
- Deepak Chitriki
- Felipe Contreras
- Hiroshi Doyu
- Seth Forshee
- Ivan Gomez Castellanos
- Mark Grosen
- Ramesh Gupta G
- Fernando Guzman Lugo
- Axel Haslam
- Janet Head
- Shivananda Hebbar
- Hari Kanigeri
- Tony Lindgren
- Antonio Luna
- Hari Nagalla
- Nishanth Menon
- Ameya Palande
- Vijay Pasam
- Gilbert Pitney
- Omar Ramirez Luna
- Ernesto Ramos
- Chris Ring
- Larry Schiefer
- Rebecca Schultz Zavin
- Bhavin Shah
- Andy Shevchenko
- Jeff Taylor
- Roman Tereshonkov
- Armando Uribe de Leon
- Nischal Varide
- Wenbiao Wang
diff --git a/drivers/staging/tidspbridge/Documentation/README b/drivers/staging/tidspbridge/Documentation/README
deleted file mode 100644
index df6d371161e0..000000000000
--- a/drivers/staging/tidspbridge/Documentation/README
+++ /dev/null
@@ -1,70 +0,0 @@
- Linux DSP/BIOS Bridge release
-
-DSP/BIOS Bridge overview
-========================
-
-DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more
-attached DSPs. The GPP is considered the master or "host" processor, and the
-attached DSPs are processing resources that can be utilized by applications
-and drivers running on the GPP.
-
-The abstraction that DSP/BIOS Bridge supplies, is a direct link between a GPP
-program and a DSP task. This communication link is partitioned into two
-types of sub-links: messaging (short, fixed-length packets) and data
-streaming (multiple, large buffers). Each sub-link operates independently,
-and features in-order delivery of data, meaning that messages are delivered
-in the order they were submitted to the message link, and stream buffers are
-delivered in the order they were submitted to the stream link.
-
-In addition, a GPP client can specify what inputs and outputs a DSP task
-uses. DSP tasks typically use message objects for passing control and status
-information and stream objects for efficient streaming of real-time data.
-
-GPP Software Architecture
-=========================
-
-A GPP application communicates with its associated DSP task running on the
-DSP subsystem using the DSP/BIOS Bridge API. For example, a GPP audio
-application can use the API to pass messages to a DSP task that is managing
-data flowing from analog-to-digital converters (ADCs) to digital-to-analog
-converters (DACs).
-
-From the perspective of the GPP OS, the DSP is treated as just another
-peripheral device. Most high level GPP OS typically support a device driver
-model, whereby applications can safely access and share a hardware peripheral
-through standard driver interfaces. Therefore, to allow multiple GPP
-applications to share access to the DSP, the GPP side of DSP/BIOS Bridge
-implements a device driver for the DSP.
-
-Since driver interfaces are not always standard across GPP OS, and to provide
-some level of interoperability of application code using DSP/BIOS Bridge
-between GPP OS, DSP/BIOS Bridge provides a standard library of APIs which
-wrap calls into the device driver. So, rather than calling GPP OS specific
-driver interfaces, applications (and even other device drivers) can use the
-standard API library directly.
-
-DSP Software Architecture
-=========================
-
-For DSP/BIOS, DSP/BIOS Bridge adds a device-independent streaming I/O (STRM)
-interface, a messaging interface (NODE), and a Resource Manager (RM) Server.
-The RM Server runs as a task of DSP/BIOS and is subservient to commands
-and queries from the GPP. It executes commands to start and stop DSP signal
-processing nodes in response to GPP programs making requests through the
-(GPP-side) API.
-
-DSP tasks started by the RM Server are similar to any other DSP task with two
-important differences: they must follow a specific task model consisting of
-three C-callable functions (node create, execute, and delete), with specific
-sets of arguments, and they have a pre-defined task environment established
-by the RM Server.
-
-Tasks started by the RM Server communicate using the STRM and NODE interfaces
-and act as servers for their corresponding GPP clients, performing signal
-processing functions as requested by messages sent by their GPP client.
-Typically, a DSP task moves data from source devices to sink devices using
-device independent I/O streams, performing application-specific processing
-and transformations on the data while it is moved. For example, an audio
-task might perform audio decompression (ADPCM, MPEG, CELP) on data received
-from a GPP audio driver and then send the decompressed linear samples to a
-digital-to-analog converter.
diff --git a/drivers/staging/tidspbridge/Documentation/error-codes b/drivers/staging/tidspbridge/Documentation/error-codes
deleted file mode 100644
index ad73cba058eb..000000000000
--- a/drivers/staging/tidspbridge/Documentation/error-codes
+++ /dev/null
@@ -1,157 +0,0 @@
- DSP/Bridge Error Code Guide
-
-
-Success code is always taken as 0, except for one case where a success status
-different than 0 can be possible, this is when enumerating a series of dsp
-objects, if the enumeration doesn't have any more objects it is considered as a
-successful case. In this case a positive ENODATA is returned (TODO: Change to
-avoid this case).
-
-Error codes are returned as a negative 1, if an specific code is expected, it
-can be propagated to user space by reading errno symbol defined in errno.h, for
-specific details on the implementation a copy of the standard used should be
-read first.
-
-The error codes used by this driver are:
-
-[EPERM]
- General driver failure.
-
- According to the use case the following might apply:
- - Device is in 'sleep/suspend' mode due to DPM.
- - User cannot mark end of stream on an input channel.
- - Requested operation is invalid for the node type.
- - Invalid alignment for the node messaging buffer.
- - The specified direction is invalid for the stream.
- - Invalid stream mode.
-
-[ENOENT]
- The specified object or file was not found.
-
-[ESRCH]
- A shared memory buffer contained in a message or stream could not be mapped
- to the GPP client process's virtual space.
-
-[EIO]
- Driver interface I/O error.
-
- or:
- - Unable to plug channel ISR for configured IRQ.
- - No free I/O request packets are available.
-
-[ENXIO]
- Unable to find a named section in DSP executable or a non-existent memory
- segment identifier was specified.
-
-[EBADF]
- General error for file handling:
-
- - Unable to open file.
- - Unable to read file.
- - An error occurred while parsing the DSP executable file.
-
-[ENOMEM]
- A memory allocation failure occurred.
-
-[EACCES]
- - Unable to read content of DCD data section; this is typically caused by
- improperly configured nodes.
- - Unable to decode DCD data section content; this is typically caused by
- changes to DSP/BIOS Bridge data structures.
- - Unable to get pointer to DCD data section; this is typically caused by
- improperly configured UUIDs.
- - Unable to load file containing DCD data section; this is typically
- caused by a missing COFF file.
- - The specified COFF file does not contain a valid node registration
- section.
-
-[EFAULT]
- Invalid pointer or handler.
-
-[EEXIST]
- Attempted to create a channel manager when one already exists.
-
-[EINVAL]
- Invalid argument.
-
-[ESPIPE]
- Symbol not found in the COFF file. DSPNode_Create will return this if
- the iAlg function table for an xDAIS socket is not found in the COFF file.
- In this case, force the symbol to be linked into the COFF file.
- DSPNode_Create, DSPNode_Execute, and DSPNode_Delete will return this if
- the create, execute, or delete phase function, respectively, could not be
- found in the COFF file.
-
- - No symbol table is loaded/found for this board.
- - Unable to initialize the ZL COFF parsing module.
-
-[EPIPE]
- I/O is currently pending.
-
- - End of stream was already requested on this output channel.
-
-[EDOM]
- A parameter is specified outside its valid range.
-
-[ENOSYS]
- The indicated operation is not supported.
-
-[EIDRM]
- During enumeration a change in the number or properties of the objects
- has occurred.
-
-[ECHRNG]
- Attempt to created channel manager with too many channels or channel ID out
- of range.
-
-[EBADR]
- The state of the specified object is incorrect for the requested operation.
-
- - Invalid segment ID.
-
-[ENODATA]
- Unable to retrieve resource information from the registry.
-
- - No more registry values.
-
-[ETIME]
- A timeout occurred before the requested operation could complete.
-
-[ENOSR]
- A stream has been issued the maximum number of buffers allowed in the
- stream at once; buffers must be reclaimed from the stream before any more
- can be issued.
-
- - No free channels are available.
-
-[EILSEQ]
- Error occurred in a dynamic loader library function.
-
-[EISCONN]
- The Specified Connection already exists.
-
-[ENOTCONN]
- Nodes not connected.
-
-[ETIMEDOUT]
- Timeout occurred waiting for a response from the hardware.
-
- - Wait for flush operation on an output channel timed out.
-
-[ECONNREFUSED]
- No more connections can be made for this node.
-
-[EALREADY]
- Channel is already in use.
-
-[EREMOTEIO]
- dwTimeOut parameter was CHNL_IOCNOWAIT, yet no I/O completions were
- queued.
-
-[ECANCELED]
- I/O has been cancelled on this channel.
-
-[ENOKEY]
- Invalid subkey parameter.
-
- - UUID not found in registry.
diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig
deleted file mode 100644
index b5e74e9de6bd..000000000000
--- a/drivers/staging/tidspbridge/Kconfig
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# DSP Bridge Driver Support
-#
-
-menuconfig TIDSPBRIDGE
- tristate "DSP Bridge driver"
- depends on ARCH_OMAP3 && !ARCH_MULTIPLATFORM && BROKEN
- select MAILBOX
- select OMAP2PLUS_MBOX
- help
- DSP/BIOS Bridge is designed for platforms that contain a GPP and
- one or more attached DSPs. The GPP is considered the master or
- "host" processor, and the attached DSPs are processing resources
- that can be utilized by applications and drivers running on the GPP.
-
- This driver depends on OMAP Mailbox (OMAP_MBOX_FWK).
-
-config TIDSPBRIDGE_DVFS
- bool "Enable Bridge Dynamic Voltage and Frequency Scaling (DVFS)"
- depends on TIDSPBRIDGE && CPU_FREQ
- help
- DVFS allows DSP Bridge to initiate the operating point change to
- scale the chip voltage and frequency in order to match the
- performance and power consumption to the current processing
- requirements.
-
-config TIDSPBRIDGE_MEMPOOL_SIZE
- hex "Physical memory pool size (Byte)"
- depends on TIDSPBRIDGE
- default 0x600000
- help
- Allocate specified size of memory at booting time to avoid allocation
- failure under heavy memory fragmentation after some use time.
-
-config TIDSPBRIDGE_RECOVERY
- bool "Recovery Support"
- depends on TIDSPBRIDGE
- default y
- help
- In case of DSP fatal error, BRIDGE driver will try to
- recover itself.
-
-config TIDSPBRIDGE_CACHE_LINE_CHECK
- bool "Check buffers to be 128 byte aligned"
- depends on TIDSPBRIDGE
- help
- When the DSP processes data, the DSP cache controller loads 128-Byte
- chunks (lines) from SDRAM and writes the data back in 128-Byte chunks.
- If a DMM buffer does not start and end on a 128-Byte boundary, the data
- preceding the start address (SA) from the 128-Byte boundary to the SA
- and the data at addresses trailing the end address (EA) from the EA to
- the next 128-Byte boundary will be loaded and written back as well.
- This can lead to heap corruption. Say Y, to enforce the check for 128
- byte alignment, buffers failing this check will be rejected.
-
-config TIDSPBRIDGE_NTFY_PWRERR
- bool "Notify power errors"
- depends on TIDSPBRIDGE
- help
- Enable notifications to registered clients on the event of power error
- trying to suspend bridge driver. Say Y, to signal this event as a fatal
- error, this will require a bridge restart to recover.
-
-config TIDSPBRIDGE_BACKTRACE
- bool "Dump backtraces on fatal errors"
- depends on TIDSPBRIDGE
- help
- Enable useful information to backtrace fatal errors. Say Y if you
- want to dump information for testing purposes.
diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
deleted file mode 100644
index adb21c53f747..000000000000
--- a/drivers/staging/tidspbridge/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge.o
-
-libgen = gen/gh.o
-libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
- core/tiomap3430_pwr.o core/tiomap_io.o \
- core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o
-libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \
- pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
-librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
- rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \
- rmgr/nldr.o rmgr/drv_interface.o
-libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
- dynload/tramp.o
-libhw = hw/hw_mmu.o
-
-tidspbridge-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
- $(libdload) $(libhw)
-
-#Machine dependent
-ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \
- -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \
- -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS
-
-ccflags-y += -Idrivers/staging/tidspbridge/include
-ccflags-y += -Idrivers/staging/tidspbridge/services
-ccflags-y += -Idrivers/staging/tidspbridge/core
-ccflags-y += -Idrivers/staging/tidspbridge/pmgr
-ccflags-y += -Idrivers/staging/tidspbridge/rmgr
-ccflags-y += -Idrivers/staging/tidspbridge/dynload
-ccflags-y += -Idrivers/staging/tidspbridge/hw
-ccflags-y += -Iarch/arm
-
diff --git a/drivers/staging/tidspbridge/TODO b/drivers/staging/tidspbridge/TODO
deleted file mode 100644
index 1c51e2dc7b56..000000000000
--- a/drivers/staging/tidspbridge/TODO
+++ /dev/null
@@ -1,18 +0,0 @@
-* Migrate to (and if necessary, extend) existing upstream code such as
- iommu, wdt, mcbsp, gptimers
-* Decouple hardware-specific code (e.g. bridge_brd_start/stop/delete/monitor)
-* DOFF binary loader: consider pushing to user space. at the very least
- eliminate the direct filesystem access
-* Eliminate general services and libraries - use or extend existing kernel
- libraries instead (e.g. gcf/lcm in nldr.c, global helpers in gen/)
-* Eliminate direct manipulation of OMAP_SYSC_BASE
-* Eliminate DSP_SUCCEEDED macros and their imposed redundant indentations
- (adopt the kernel way of checking for return values)
-* Audit interfaces exposed to user space
-* Audit and clean up header files folder
-* Use kernel coding style
-* checkpatch.pl fixes
-* allocate ext_mem_pool from consistent memory instead of using ioremap
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
-and Omar Ramirez Luna <omar.ramirez@ti.com>.
diff --git a/drivers/staging/tidspbridge/core/_cmm.h b/drivers/staging/tidspbridge/core/_cmm.h
deleted file mode 100644
index 7660bef6ebb3..000000000000
--- a/drivers/staging/tidspbridge/core/_cmm.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * _cmm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private header file defining CMM manager objects and defines needed
- * by IO manager to register shared memory regions when DSP base image
- * is loaded(bridge_io_on_loaded).
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _CMM_
-#define _CMM_
-
-/*
- * These target side symbols define the beginning and ending addresses
- * of the section of shared memory used for shared memory manager CMM.
- * They are defined in the *cfg.cmd file by cdb code.
- */
-#define SHM0_SHARED_BASE_SYM "_SHM0_BEG"
-#define SHM0_SHARED_END_SYM "_SHM0_END"
-#define SHM0_SHARED_RESERVED_BASE_SYM "_SHM0_RSVDSTRT"
-
-/*
- * Shared Memory Region #0(SHMSEG0) is used in the following way:
- *
- * |(_SHM0_BEG) | (_SHM0_RSVDSTRT) | (_SHM0_END)
- * V V V
- * ------------------------------------------------------------
- * | DSP-side allocations | GPP-side allocations |
- * ------------------------------------------------------------
- *
- *
- */
-
-#endif /* _CMM_ */
diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h
deleted file mode 100644
index 025d34320e7e..000000000000
--- a/drivers/staging/tidspbridge/core/_deh.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * _deh.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private header for DEH module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- * Copyright (C) 2010 Felipe Contreras
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _DEH_
-#define _DEH_
-
-#include <dspbridge/ntfy.h>
-#include <dspbridge/dspdefs.h>
-
-/* DEH Manager: only one created per board: */
-struct deh_mgr {
- struct bridge_dev_context *bridge_context; /* Bridge context. */
- struct ntfy_object *ntfy_obj; /* NTFY object */
-
- /* MMU Fault DPC */
- struct tasklet_struct dpc_tasklet;
-};
-
-#endif /* _DEH_ */
diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h
deleted file mode 100644
index f6e58e3f3b48..000000000000
--- a/drivers/staging/tidspbridge/core/_msg_sm.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * _msg_sm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private header file defining msg_ctrl manager objects and defines needed
- * by IO manager.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _MSG_SM_
-#define _MSG_SM_
-
-#include <linux/list.h>
-#include <dspbridge/msgdefs.h>
-
-/*
- * These target side symbols define the beginning and ending addresses
- * of the section of shared memory used for messages. They are
- * defined in the *cfg.cmd file by cdb code.
- */
-#define MSG_SHARED_BUFFER_BASE_SYM "_MSG_BEG"
-#define MSG_SHARED_BUFFER_LIMIT_SYM "_MSG_END"
-
-#ifndef _CHNL_WORDSIZE
-#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */
-#endif
-
-/*
- * ======== msg_ctrl ========
- * There is a control structure for messages to the DSP, and a control
- * structure for messages from the DSP. The shared memory region for
- * transferring messages is partitioned as follows:
- *
- * ----------------------------------------------------------
- * |Control | Messages from DSP | Control | Messages to DSP |
- * ----------------------------------------------------------
- *
- * msg_ctrl control structure for messages to the DSP is used in the following
- * way:
- *
- * buf_empty - This flag is set to FALSE by the GPP after it has output
- * messages for the DSP. The DSP host driver sets it to
- * TRUE after it has copied the messages.
- * post_swi - Set to 1 by the GPP after it has written the messages,
- * set the size, and set buf_empty to FALSE.
- * The DSP Host driver uses SWI_andn of the post_swi field
- * when a host interrupt occurs. The host driver clears
- * this after posting the SWI.
- * size - Number of messages to be read by the DSP.
- *
- * For messages from the DSP:
- * buf_empty - This flag is set to FALSE by the DSP after it has output
- * messages for the GPP. The DPC on the GPP sets it to
- * TRUE after it has copied the messages.
- * post_swi - Set to 1 the DPC on the GPP after copying the messages.
- * size - Number of messages to be read by the GPP.
- */
-struct msg_ctrl {
- u32 buf_empty; /* to/from DSP buffer is empty */
- u32 post_swi; /* Set to "1" to post msg_ctrl SWI */
- u32 size; /* Number of messages to/from the DSP */
- u32 resvd;
-};
-
-/*
- * ======== msg_mgr ========
- * The msg_mgr maintains a list of all MSG_QUEUEs. Each NODE object can
- * have msg_queue to hold all messages that come up from the corresponding
- * node on the DSP. The msg_mgr also has a shared queue of messages
- * ready to go to the DSP.
- */
-struct msg_mgr {
- /* The first field must match that in msgobj.h */
-
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
-
- struct io_mgr *iomgr; /* IO manager */
- struct list_head queue_list; /* List of MSG_QUEUEs */
- spinlock_t msg_mgr_lock; /* For critical sections */
- /* Signalled when MsgFrame is available */
- struct sync_object *sync_event;
- struct list_head msg_free_list; /* Free MsgFrames ready to be filled */
- struct list_head msg_used_list; /* MsgFrames ready to go to DSP */
- u32 msgs_pending; /* # of queued messages to go to DSP */
- u32 max_msgs; /* Max # of msgs that fit in buffer */
- msg_onexit on_exit; /* called when RMS_EXIT is received */
-};
-
-/*
- * ======== msg_queue ========
- * Each NODE has a msg_queue for receiving messages from the
- * corresponding node on the DSP. The msg_queue object maintains a list
- * of messages that have been sent to the host, but not yet read (MSG_Get),
- * and a list of free frames that can be filled when new messages arrive
- * from the DSP.
- * The msg_queue's hSynEvent gets posted when a message is ready.
- */
-struct msg_queue {
- struct list_head list_elem;
- struct msg_mgr *msg_mgr;
- u32 max_msgs; /* Node message depth */
- u32 msgq_id; /* Node environment pointer */
- struct list_head msg_free_list; /* Free MsgFrames ready to be filled */
- /* Filled MsgFramess waiting to be read */
- struct list_head msg_used_list;
- void *arg; /* Handle passed to mgr on_exit callback */
- struct sync_object *sync_event; /* Signalled when message is ready */
- struct sync_object *sync_done; /* For synchronizing cleanup */
- struct sync_object *sync_done_ack; /* For synchronizing cleanup */
- struct ntfy_object *ntfy_obj; /* For notification of message ready */
- bool done; /* TRUE <==> deleting the object */
- u32 io_msg_pend; /* Number of pending MSG_get/put calls */
-};
-
-/*
- * ======== msg_dspmsg ========
- */
-struct msg_dspmsg {
- struct dsp_msg msg;
- u32 msgq_id; /* Identifies the node the message goes to */
-};
-
-/*
- * ======== msg_frame ========
- */
-struct msg_frame {
- struct list_head list_elem;
- struct msg_dspmsg msg_data;
-};
-
-#endif /* _MSG_SM_ */
diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h
deleted file mode 100644
index 65971b784b78..000000000000
--- a/drivers/staging/tidspbridge/core/_tiomap.h
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * _tiomap.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Definitions and types private to this Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _TIOMAP_
-#define _TIOMAP_
-
-/*
- * XXX These powerdomain.h/clockdomain.h includes are wrong and should
- * be removed. No driver should call pwrdm_* or clkdm_* functions
- * directly; they should rely on OMAP core code to do this.
- */
-#include <mach-omap2/powerdomain.h>
-#include <mach-omap2/clockdomain.h>
-/*
- * XXX These mach-omap2/ includes are wrong and should be removed. No
- * driver should read or write to PRM/CM registers directly; they
- * should rely on OMAP core code to do this.
- */
-#include <mach-omap2/cm3xxx.h>
-#include <mach-omap2/prm-regbits-34xx.h>
-#include <mach-omap2/cm-regbits-34xx.h>
-#include <dspbridge/devdefs.h>
-#include <hw_defs.h>
-#include <dspbridge/dspioctl.h> /* for bridge_ioctl_extproc defn */
-#include <dspbridge/sync.h>
-#include <dspbridge/clk.h>
-
-struct map_l4_peripheral {
- u32 phys_addr;
- u32 dsp_virt_addr;
-};
-
-#define ARM_MAILBOX_START 0xfffcf000
-#define ARM_MAILBOX_LENGTH 0x800
-
-/* New Registers in OMAP3.1 */
-
-#define TESTBLOCK_ID_START 0xfffed400
-#define TESTBLOCK_ID_LENGTH 0xff
-
-/* ID Returned by OMAP1510 */
-#define TBC_ID_VALUE 0xB47002F
-
-#define SPACE_LENGTH 0x2000
-#define API_CLKM_DPLL_DMA 0xfffec000
-#define ARM_INTERRUPT_OFFSET 0xb00
-
-#define BIOS24XX
-
-#define L4_PERIPHERAL_NULL 0x0
-#define DSPVA_PERIPHERAL_NULL 0x0
-
-#define MAX_LOCK_TLB_ENTRIES 15
-
-#define L4_PERIPHERAL_PRM 0x48306000 /*PRM L4 Peripheral */
-#define DSPVA_PERIPHERAL_PRM 0x1181e000
-#define L4_PERIPHERAL_SCM 0x48002000 /*SCM L4 Peripheral */
-#define DSPVA_PERIPHERAL_SCM 0x1181f000
-#define L4_PERIPHERAL_MMU 0x5D000000 /*MMU L4 Peripheral */
-#define DSPVA_PERIPHERAL_MMU 0x11820000
-#define L4_PERIPHERAL_CM 0x48004000 /* Core L4, Clock Management */
-#define DSPVA_PERIPHERAL_CM 0x1181c000
-#define L4_PERIPHERAL_PER 0x48005000 /* PER */
-#define DSPVA_PERIPHERAL_PER 0x1181d000
-
-#define L4_PERIPHERAL_GPIO1 0x48310000
-#define DSPVA_PERIPHERAL_GPIO1 0x11809000
-#define L4_PERIPHERAL_GPIO2 0x49050000
-#define DSPVA_PERIPHERAL_GPIO2 0x1180a000
-#define L4_PERIPHERAL_GPIO3 0x49052000
-#define DSPVA_PERIPHERAL_GPIO3 0x1180b000
-#define L4_PERIPHERAL_GPIO4 0x49054000
-#define DSPVA_PERIPHERAL_GPIO4 0x1180c000
-#define L4_PERIPHERAL_GPIO5 0x49056000
-#define DSPVA_PERIPHERAL_GPIO5 0x1180d000
-
-#define L4_PERIPHERAL_IVA2WDT 0x49030000
-#define DSPVA_PERIPHERAL_IVA2WDT 0x1180e000
-
-#define L4_PERIPHERAL_DISPLAY 0x48050000
-#define DSPVA_PERIPHERAL_DISPLAY 0x1180f000
-
-#define L4_PERIPHERAL_SSI 0x48058000
-#define DSPVA_PERIPHERAL_SSI 0x11804000
-#define L4_PERIPHERAL_GDD 0x48059000
-#define DSPVA_PERIPHERAL_GDD 0x11805000
-#define L4_PERIPHERAL_SS1 0x4805a000
-#define DSPVA_PERIPHERAL_SS1 0x11806000
-#define L4_PERIPHERAL_SS2 0x4805b000
-#define DSPVA_PERIPHERAL_SS2 0x11807000
-
-#define L4_PERIPHERAL_CAMERA 0x480BC000
-#define DSPVA_PERIPHERAL_CAMERA 0x11819000
-
-#define L4_PERIPHERAL_SDMA 0x48056000
-#define DSPVA_PERIPHERAL_SDMA 0x11810000 /* 0x1181d000 conflict w/ PER */
-
-#define L4_PERIPHERAL_UART1 0x4806a000
-#define DSPVA_PERIPHERAL_UART1 0x11811000
-#define L4_PERIPHERAL_UART2 0x4806c000
-#define DSPVA_PERIPHERAL_UART2 0x11812000
-#define L4_PERIPHERAL_UART3 0x49020000
-#define DSPVA_PERIPHERAL_UART3 0x11813000
-
-#define L4_PERIPHERAL_MCBSP1 0x48074000
-#define DSPVA_PERIPHERAL_MCBSP1 0x11814000
-#define L4_PERIPHERAL_MCBSP2 0x49022000
-#define DSPVA_PERIPHERAL_MCBSP2 0x11815000
-#define L4_PERIPHERAL_MCBSP3 0x49024000
-#define DSPVA_PERIPHERAL_MCBSP3 0x11816000
-#define L4_PERIPHERAL_MCBSP4 0x49026000
-#define DSPVA_PERIPHERAL_MCBSP4 0x11817000
-#define L4_PERIPHERAL_MCBSP5 0x48096000
-#define DSPVA_PERIPHERAL_MCBSP5 0x11818000
-
-#define L4_PERIPHERAL_GPTIMER5 0x49038000
-#define DSPVA_PERIPHERAL_GPTIMER5 0x11800000
-#define L4_PERIPHERAL_GPTIMER6 0x4903a000
-#define DSPVA_PERIPHERAL_GPTIMER6 0x11801000
-#define L4_PERIPHERAL_GPTIMER7 0x4903c000
-#define DSPVA_PERIPHERAL_GPTIMER7 0x11802000
-#define L4_PERIPHERAL_GPTIMER8 0x4903e000
-#define DSPVA_PERIPHERAL_GPTIMER8 0x11803000
-
-#define L4_PERIPHERAL_SPI1 0x48098000
-#define DSPVA_PERIPHERAL_SPI1 0x1181a000
-#define L4_PERIPHERAL_SPI2 0x4809a000
-#define DSPVA_PERIPHERAL_SPI2 0x1181b000
-
-#define L4_PERIPHERAL_MBOX 0x48094000
-#define DSPVA_PERIPHERAL_MBOX 0x11808000
-
-#define PM_GRPSEL_BASE 0x48307000
-#define DSPVA_GRPSEL_BASE 0x11821000
-
-#define L4_PERIPHERAL_SIDETONE_MCBSP2 0x49028000
-#define DSPVA_PERIPHERAL_SIDETONE_MCBSP2 0x11824000
-#define L4_PERIPHERAL_SIDETONE_MCBSP3 0x4902a000
-#define DSPVA_PERIPHERAL_SIDETONE_MCBSP3 0x11825000
-
-/* define a static array with L4 mappings */
-static const struct map_l4_peripheral l4_peripheral_table[] = {
- {L4_PERIPHERAL_MBOX, DSPVA_PERIPHERAL_MBOX},
- {L4_PERIPHERAL_SCM, DSPVA_PERIPHERAL_SCM},
- {L4_PERIPHERAL_MMU, DSPVA_PERIPHERAL_MMU},
- {L4_PERIPHERAL_GPTIMER5, DSPVA_PERIPHERAL_GPTIMER5},
- {L4_PERIPHERAL_GPTIMER6, DSPVA_PERIPHERAL_GPTIMER6},
- {L4_PERIPHERAL_GPTIMER7, DSPVA_PERIPHERAL_GPTIMER7},
- {L4_PERIPHERAL_GPTIMER8, DSPVA_PERIPHERAL_GPTIMER8},
- {L4_PERIPHERAL_GPIO1, DSPVA_PERIPHERAL_GPIO1},
- {L4_PERIPHERAL_GPIO2, DSPVA_PERIPHERAL_GPIO2},
- {L4_PERIPHERAL_GPIO3, DSPVA_PERIPHERAL_GPIO3},
- {L4_PERIPHERAL_GPIO4, DSPVA_PERIPHERAL_GPIO4},
- {L4_PERIPHERAL_GPIO5, DSPVA_PERIPHERAL_GPIO5},
- {L4_PERIPHERAL_IVA2WDT, DSPVA_PERIPHERAL_IVA2WDT},
- {L4_PERIPHERAL_DISPLAY, DSPVA_PERIPHERAL_DISPLAY},
- {L4_PERIPHERAL_SSI, DSPVA_PERIPHERAL_SSI},
- {L4_PERIPHERAL_GDD, DSPVA_PERIPHERAL_GDD},
- {L4_PERIPHERAL_SS1, DSPVA_PERIPHERAL_SS1},
- {L4_PERIPHERAL_SS2, DSPVA_PERIPHERAL_SS2},
- {L4_PERIPHERAL_UART1, DSPVA_PERIPHERAL_UART1},
- {L4_PERIPHERAL_UART2, DSPVA_PERIPHERAL_UART2},
- {L4_PERIPHERAL_UART3, DSPVA_PERIPHERAL_UART3},
- {L4_PERIPHERAL_MCBSP1, DSPVA_PERIPHERAL_MCBSP1},
- {L4_PERIPHERAL_MCBSP2, DSPVA_PERIPHERAL_MCBSP2},
- {L4_PERIPHERAL_MCBSP3, DSPVA_PERIPHERAL_MCBSP3},
- {L4_PERIPHERAL_MCBSP4, DSPVA_PERIPHERAL_MCBSP4},
- {L4_PERIPHERAL_MCBSP5, DSPVA_PERIPHERAL_MCBSP5},
- {L4_PERIPHERAL_CAMERA, DSPVA_PERIPHERAL_CAMERA},
- {L4_PERIPHERAL_SPI1, DSPVA_PERIPHERAL_SPI1},
- {L4_PERIPHERAL_SPI2, DSPVA_PERIPHERAL_SPI2},
- {L4_PERIPHERAL_PRM, DSPVA_PERIPHERAL_PRM},
- {L4_PERIPHERAL_CM, DSPVA_PERIPHERAL_CM},
- {L4_PERIPHERAL_PER, DSPVA_PERIPHERAL_PER},
- {PM_GRPSEL_BASE, DSPVA_GRPSEL_BASE},
- {L4_PERIPHERAL_SIDETONE_MCBSP2, DSPVA_PERIPHERAL_SIDETONE_MCBSP2},
- {L4_PERIPHERAL_SIDETONE_MCBSP3, DSPVA_PERIPHERAL_SIDETONE_MCBSP3},
- {L4_PERIPHERAL_NULL, DSPVA_PERIPHERAL_NULL}
-};
-
-/*
- * 15 10 0
- * ---------------------------------
- * |0|0|1|0|0|0|c|c|c|i|i|i|i|i|i|i|
- * ---------------------------------
- * | (class) | (module specific) |
- *
- * where c -> Externel Clock Command: Clk & Autoidle Disable/Enable
- * i -> External Clock ID Timers 5,6,7,8, McBSP1,2 and WDT3
- */
-
-/* MBX_PM_CLK_IDMASK: DSP External clock id mask. */
-#define MBX_PM_CLK_IDMASK 0x7F
-
-/* MBX_PM_CLK_CMDSHIFT: DSP External clock command shift. */
-#define MBX_PM_CLK_CMDSHIFT 7
-
-/* MBX_PM_CLK_CMDMASK: DSP External clock command mask. */
-#define MBX_PM_CLK_CMDMASK 7
-
-/* MBX_PM_MAX_RESOURCES: CORE 1 Clock resources. */
-#define MBX_CORE1_RESOURCES 7
-
-/* MBX_PM_MAX_RESOURCES: CORE 2 Clock Resources. */
-#define MBX_CORE2_RESOURCES 1
-
-/* MBX_PM_MAX_RESOURCES: TOTAL Clock Resources. */
-#define MBX_PM_MAX_RESOURCES 11
-
-/* Power Management Commands */
-#define BPWR_DISABLE_CLOCK 0
-#define BPWR_ENABLE_CLOCK 1
-
-/* OMAP242x specific resources */
-enum bpwr_ext_clock_id {
- BPWR_GP_TIMER5 = 0x10,
- BPWR_GP_TIMER6,
- BPWR_GP_TIMER7,
- BPWR_GP_TIMER8,
- BPWR_WD_TIMER3,
- BPWR_MCBSP1,
- BPWR_MCBSP2,
- BPWR_MCBSP3,
- BPWR_MCBSP4,
- BPWR_MCBSP5,
- BPWR_SSI = 0x20
-};
-
-static const u32 bpwr_clkid[] = {
- (u32) BPWR_GP_TIMER5,
- (u32) BPWR_GP_TIMER6,
- (u32) BPWR_GP_TIMER7,
- (u32) BPWR_GP_TIMER8,
- (u32) BPWR_WD_TIMER3,
- (u32) BPWR_MCBSP1,
- (u32) BPWR_MCBSP2,
- (u32) BPWR_MCBSP3,
- (u32) BPWR_MCBSP4,
- (u32) BPWR_MCBSP5,
- (u32) BPWR_SSI
-};
-
-struct bpwr_clk_t {
- u32 clk_id;
- enum dsp_clk_id clk;
-};
-
-static const struct bpwr_clk_t bpwr_clks[] = {
- {(u32) BPWR_GP_TIMER5, DSP_CLK_GPT5},
- {(u32) BPWR_GP_TIMER6, DSP_CLK_GPT6},
- {(u32) BPWR_GP_TIMER7, DSP_CLK_GPT7},
- {(u32) BPWR_GP_TIMER8, DSP_CLK_GPT8},
- {(u32) BPWR_WD_TIMER3, DSP_CLK_WDT3},
- {(u32) BPWR_MCBSP1, DSP_CLK_MCBSP1},
- {(u32) BPWR_MCBSP2, DSP_CLK_MCBSP2},
- {(u32) BPWR_MCBSP3, DSP_CLK_MCBSP3},
- {(u32) BPWR_MCBSP4, DSP_CLK_MCBSP4},
- {(u32) BPWR_MCBSP5, DSP_CLK_MCBSP5},
- {(u32) BPWR_SSI, DSP_CLK_SSI}
-};
-
-/* Interrupt Register Offsets */
-#define INTH_IT_REG_OFFSET 0x00 /* Interrupt register offset */
-#define INTH_MASK_IT_REG_OFFSET 0x04 /* Mask Interrupt reg offset */
-
-#define DSP_MAILBOX1_INT 10
-/*
- * Bit definition of Interrupt Level Registers
- */
-
-/* Mail Box defines */
-#define MB_ARM2DSP1_REG_OFFSET 0x00
-
-#define MB_ARM2DSP1B_REG_OFFSET 0x04
-
-#define MB_DSP2ARM1B_REG_OFFSET 0x0C
-
-#define MB_ARM2DSP1_FLAG_REG_OFFSET 0x18
-
-#define MB_ARM2DSP_FLAG 0x0001
-
-#define MBOX_ARM2DSP HW_MBOX_ID0
-#define MBOX_DSP2ARM HW_MBOX_ID1
-#define MBOX_ARM HW_MBOX_U0_ARM
-#define MBOX_DSP HW_MBOX_U1_DSP1
-
-#define ENABLE true
-#define DISABLE false
-
-#define HIGH_LEVEL true
-#define LOW_LEVEL false
-
-/* Macro's */
-#define CLEAR_BIT(reg, mask) (reg &= ~mask)
-#define SET_BIT(reg, mask) (reg |= mask)
-
-#define SET_GROUP_BITS16(reg, position, width, value) \
- do {\
- reg &= ~((0xFFFF >> (16 - (width))) << (position)); \
- reg |= ((value & (0xFFFF >> (16 - (width)))) << (position)); \
- } while (0);
-
-#define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index)))
-
-/* This Bridge driver's device context: */
-struct bridge_dev_context {
- struct dev_object *dev_obj; /* Handle to Bridge device object. */
- u32 dsp_base_addr; /* Arm's API to DSP virt base addr */
- /*
- * DSP External memory prog address as seen virtually by the OS on
- * the host side.
- */
- u32 dsp_ext_base_addr; /* See the comment above */
- u32 api_reg_base; /* API mem map'd registers */
- void __iomem *dsp_mmu_base; /* DSP MMU Mapped registers */
- u32 api_clk_base; /* CLK Registers */
- u32 dsp_clk_m2_base; /* DSP Clock Module m2 */
- u32 public_rhea; /* Pub Rhea */
- u32 int_addr; /* MB INTR reg */
- u32 tc_endianism; /* TC Endianism register */
- u32 test_base; /* DSP MMU Mapped registers */
- u32 self_loop; /* Pointer to the selfloop */
- u32 dsp_start_add; /* API Boot vector */
- u32 internal_size; /* Internal memory size */
-
- struct omap_mbox *mbox; /* Mail box handle */
-
- struct cfg_hostres *resources; /* Host Resources */
-
- /*
- * Processor specific info is set when prog loaded and read from DCD.
- * [See bridge_dev_ctrl()] PROC info contains DSP-MMU TLB entries.
- */
- /* DMMU TLB entries */
- struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB];
- u32 brd_state; /* Last known board state. */
-
- /* TC Settings */
- bool tc_word_swap_on; /* Traffic Controller Word Swap */
- struct pg_table_attrs *pt_attrs;
- u32 dsp_per_clks;
-};
-
-/*
- * If dsp_debug is true, do not branch to the DSP entry
- * point and wait for DSP to boot.
- */
-extern s32 dsp_debug;
-
-/*
- * ======== sm_interrupt_dsp ========
- * Purpose:
- * Set interrupt value & send an interrupt to the DSP processor(s).
- * This is typically used when mailbox interrupt mechanisms allow data
- * to be associated with interrupt such as for OMAP's CMD/DATA regs.
- * Parameters:
- * dev_context: Handle to Bridge driver defined device info.
- * mb_val: Value associated with interrupt(e.g. mailbox value).
- * Returns:
- * 0: Interrupt sent;
- * else: Unable to send interrupt.
- * Requires:
- * Ensures:
- */
-int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val);
-
-#endif /* _TIOMAP_ */
diff --git a/drivers/staging/tidspbridge/core/_tiomap_pwr.h b/drivers/staging/tidspbridge/core/_tiomap_pwr.h
deleted file mode 100644
index 7bbd3802c15f..000000000000
--- a/drivers/staging/tidspbridge/core/_tiomap_pwr.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * _tiomap_pwr.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Definitions and types for the DSP wake/sleep routines.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _TIOMAP_PWR_
-#define _TIOMAP_PWR_
-
-#ifdef CONFIG_PM
-extern s32 dsp_test_sleepstate;
-#endif
-
-extern struct mailbox_context mboxsetting;
-
-/*
- * ======== wake_dsp =========
- * Wakes up the DSP from DeepSleep
- */
-extern int wake_dsp(struct bridge_dev_context *dev_context,
- void *pargs);
-
-/*
- * ======== sleep_dsp =========
- * Places the DSP in DeepSleep.
- */
-extern int sleep_dsp(struct bridge_dev_context *dev_context,
- u32 dw_cmd, void *pargs);
-/*
- * ========interrupt_dsp========
- * Sends an interrupt to DSP unconditionally.
- */
-extern void interrupt_dsp(struct bridge_dev_context *dev_context,
- u16 mb_val);
-
-/*
- * ======== wake_dsp =========
- * Wakes up the DSP from DeepSleep
- */
-extern int dsp_peripheral_clk_ctrl(struct bridge_dev_context
- *dev_context, void *pargs);
-/*
- * ======== handle_hibernation_from_dsp ========
- * Handle Hibernation requested from DSP
- */
-int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context);
-/*
- * ======== post_scale_dsp ========
- * Handle Post Scale notification to DSP
- */
-int post_scale_dsp(struct bridge_dev_context *dev_context,
- void *pargs);
-/*
- * ======== pre_scale_dsp ========
- * Handle Pre Scale notification to DSP
- */
-int pre_scale_dsp(struct bridge_dev_context *dev_context,
- void *pargs);
-/*
- * ======== handle_constraints_set ========
- * Handle constraints request from DSP
- */
-int handle_constraints_set(struct bridge_dev_context *dev_context,
- void *pargs);
-
-/*
- * ======== dsp_clk_wakeup_event_ctrl ========
- * This function sets the group selction bits for while
- * enabling/disabling.
- */
-void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable);
-
-#endif /* _TIOMAP_PWR_ */
diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c
deleted file mode 100644
index 16fa3462fbbe..000000000000
--- a/drivers/staging/tidspbridge/core/chnl_sm.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * chnl_sm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implements upper edge functions for Bridge driver channel module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * The lower edge functions must be implemented by the Bridge driver
- * writer, and are declared in chnl_sm.h.
- *
- * Care is taken in this code to prevent simultaneous access to channel
- * queues from
- * 1. Threads.
- * 2. io_dpc(), scheduled from the io_isr() as an event.
- *
- * This is done primarily by:
- * - Semaphores.
- * - state flags in the channel object; and
- * - ensuring the IO_Dispatch() routine, which is called from both
- * CHNL_AddIOReq() and the DPC(if implemented), is not re-entered.
- *
- * Channel Invariant:
- * There is an important invariant condition which must be maintained per
- * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of
- * which may cause timeouts and/or failure of function sync_wait_on_event.
- * This invariant condition is:
- *
- * list_empty(&pchnl->io_completions) ==> pchnl->sync_event is reset
- * and
- * !list_empty(&pchnl->io_completions) ==> pchnl->sync_event is set.
- */
-
-#include <linux/types.h>
-
-/* ----------------------------------- OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdefs.h>
-#include <dspbridge/dspchnl.h>
-#include "_tiomap.h"
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/io_sm.h>
-
-/* ----------------------------------- Define for This */
-#define USERMODE_ADDR PAGE_OFFSET
-
-#define MAILBOX_IRQ INT_MAIL_MPU_IRQ
-
-/* ----------------------------------- Function Prototypes */
-static int create_chirp_list(struct list_head *list, u32 chirps);
-
-static void free_chirp_list(struct list_head *list);
-
-static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
- u32 *chnl);
-
-/*
- * ======== bridge_chnl_add_io_req ========
- * Enqueue an I/O request for data transfer on a channel to the DSP.
- * The direction (mode) is specified in the channel object. Note the DSP
- * address is specified for channels opened in direct I/O mode.
- */
-int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf,
- u32 byte_size, u32 buf_size,
- u32 dw_dsp_addr, u32 dw_arg)
-{
- int status = 0;
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
- struct chnl_irp *chnl_packet_obj = NULL;
- struct bridge_dev_context *dev_ctxt;
- struct dev_object *dev_obj;
- u8 dw_state;
- bool is_eos;
- struct chnl_mgr *chnl_mgr_obj;
- u8 *host_sys_buf = NULL;
- bool sched_dpc = false;
- u16 mb_val = 0;
-
- is_eos = (byte_size == 0);
-
- /* Validate args */
- if (!host_buf || !pchnl)
- return -EFAULT;
-
- if (is_eos && CHNL_IS_INPUT(pchnl->chnl_mode))
- return -EPERM;
-
- /*
- * Check the channel state: only queue chirp if channel state
- * allows it.
- */
- dw_state = pchnl->state;
- if (dw_state != CHNL_STATEREADY) {
- if (dw_state & CHNL_STATECANCEL)
- return -ECANCELED;
- if ((dw_state & CHNL_STATEEOS) &&
- CHNL_IS_OUTPUT(pchnl->chnl_mode))
- return -EPIPE;
- /* No other possible states left */
- }
-
- dev_obj = dev_get_first();
- dev_get_bridge_context(dev_obj, &dev_ctxt);
- if (!dev_ctxt)
- return -EFAULT;
-
- if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1 && host_buf) {
- if (!(host_buf < (void *)USERMODE_ADDR)) {
- host_sys_buf = host_buf;
- goto func_cont;
- }
- /* if addr in user mode, then copy to kernel space */
- host_sys_buf = kmalloc(buf_size, GFP_KERNEL);
- if (host_sys_buf == NULL)
- return -ENOMEM;
-
- if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
- status = copy_from_user(host_sys_buf, host_buf,
- buf_size);
- if (status) {
- kfree(host_sys_buf);
- host_sys_buf = NULL;
- return -EFAULT;
- }
- }
- }
-func_cont:
- /* Mailbox IRQ is disabled to avoid race condition with DMA/ZCPY
- * channels. DPCCS is held to avoid race conditions with PCPY channels.
- * If DPC is scheduled in process context (iosm_schedule) and any
- * non-mailbox interrupt occurs, that DPC will run and break CS. Hence
- * we disable ALL DPCs. We will try to disable ONLY IO DPC later. */
- chnl_mgr_obj = pchnl->chnl_mgr_obj;
- spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
- omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
- if (pchnl->chnl_type == CHNL_PCPY) {
- /* This is a processor-copy channel. */
- if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
- /* Check buffer size on output channels for fit. */
- if (byte_size > io_buf_size(
- pchnl->chnl_mgr_obj->iomgr)) {
- status = -EINVAL;
- goto out;
- }
- }
- }
-
- /* Get a free chirp: */
- if (list_empty(&pchnl->free_packets_list)) {
- status = -EIO;
- goto out;
- }
- chnl_packet_obj = list_first_entry(&pchnl->free_packets_list,
- struct chnl_irp, link);
- list_del(&chnl_packet_obj->link);
-
- /* Enqueue the chirp on the chnl's IORequest queue: */
- chnl_packet_obj->host_user_buf = chnl_packet_obj->host_sys_buf =
- host_buf;
- if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)
- chnl_packet_obj->host_sys_buf = host_sys_buf;
-
- /*
- * Note: for dma chans dw_dsp_addr contains dsp address
- * of SM buffer.
- */
- /* DSP address */
- chnl_packet_obj->dsp_tx_addr = dw_dsp_addr / chnl_mgr_obj->word_size;
- chnl_packet_obj->byte_size = byte_size;
- chnl_packet_obj->buf_size = buf_size;
- /* Only valid for output channel */
- chnl_packet_obj->arg = dw_arg;
- chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS :
- CHNL_IOCSTATCOMPLETE);
- list_add_tail(&chnl_packet_obj->link, &pchnl->io_requests);
- pchnl->cio_reqs++;
- /*
- * If end of stream, update the channel state to prevent
- * more IOR's.
- */
- if (is_eos)
- pchnl->state |= CHNL_STATEEOS;
-
- /* Request IO from the DSP */
- io_request_chnl(chnl_mgr_obj->iomgr, pchnl,
- (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT :
- IO_OUTPUT), &mb_val);
- sched_dpc = true;
-out:
- omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX);
- spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
- if (mb_val != 0)
- sm_interrupt_dsp(dev_ctxt, mb_val);
-
- /* Schedule a DPC, to do the actual data transfer */
- if (sched_dpc)
- iosm_schedule(chnl_mgr_obj->iomgr);
-
- return status;
-}
-
-/*
- * ======== bridge_chnl_cancel_io ========
- * Return all I/O requests to the client which have not yet been
- * transferred. The channel's I/O completion object is
- * signalled, and all the I/O requests are queued as IOC's, with the
- * status field set to CHNL_IOCSTATCANCEL.
- * This call is typically used in abort situations, and is a prelude to
- * chnl_close();
- */
-int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
-{
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
- u32 chnl_id = -1;
- s8 chnl_mode;
- struct chnl_irp *chirp, *tmp;
- struct chnl_mgr *chnl_mgr_obj = NULL;
-
- /* Check args: */
- if (!pchnl || !pchnl->chnl_mgr_obj)
- return -EFAULT;
-
- chnl_id = pchnl->chnl_id;
- chnl_mode = pchnl->chnl_mode;
- chnl_mgr_obj = pchnl->chnl_mgr_obj;
-
- /* Mark this channel as cancelled, to prevent further IORequests or
- * IORequests or dispatching. */
- spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
-
- pchnl->state |= CHNL_STATECANCEL;
-
- if (list_empty(&pchnl->io_requests)) {
- spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
- return 0;
- }
-
- if (pchnl->chnl_type == CHNL_PCPY) {
- /* Indicate we have no more buffers available for transfer: */
- if (CHNL_IS_INPUT(pchnl->chnl_mode)) {
- io_cancel_chnl(chnl_mgr_obj->iomgr, chnl_id);
- } else {
- /* Record that we no longer have output buffers
- * available: */
- chnl_mgr_obj->output_mask &= ~(1 << chnl_id);
- }
- }
- /* Move all IOR's to IOC queue: */
- list_for_each_entry_safe(chirp, tmp, &pchnl->io_requests, link) {
- list_del(&chirp->link);
- chirp->byte_size = 0;
- chirp->status |= CHNL_IOCSTATCANCEL;
- list_add_tail(&chirp->link, &pchnl->io_completions);
- pchnl->cio_cs++;
- pchnl->cio_reqs--;
- }
-
- spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
-
- return 0;
-}
-
-/*
- * ======== bridge_chnl_close ========
- * Purpose:
- * Ensures all pending I/O on this channel is cancelled, discards all
- * queued I/O completion notifications, then frees the resources allocated
- * for this channel, and makes the corresponding logical channel id
- * available for subsequent use.
- */
-int bridge_chnl_close(struct chnl_object *chnl_obj)
-{
- int status;
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
-
- /* Check args: */
- if (!pchnl)
- return -EFAULT;
- /* Cancel IO: this ensures no further IO requests or notifications */
- status = bridge_chnl_cancel_io(chnl_obj);
- if (status)
- return status;
- /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */
- /* Free the slot in the channel manager: */
- pchnl->chnl_mgr_obj->channels[pchnl->chnl_id] = NULL;
- spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
- pchnl->chnl_mgr_obj->open_channels -= 1;
- spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
- if (pchnl->ntfy_obj) {
- ntfy_delete(pchnl->ntfy_obj);
- kfree(pchnl->ntfy_obj);
- pchnl->ntfy_obj = NULL;
- }
- /* Reset channel event: (NOTE: user_event freed in user context) */
- if (pchnl->sync_event) {
- sync_reset_event(pchnl->sync_event);
- kfree(pchnl->sync_event);
- pchnl->sync_event = NULL;
- }
- /* Free I/O request and I/O completion queues: */
- free_chirp_list(&pchnl->io_completions);
- pchnl->cio_cs = 0;
-
- free_chirp_list(&pchnl->io_requests);
- pchnl->cio_reqs = 0;
-
- free_chirp_list(&pchnl->free_packets_list);
-
- /* Release channel object. */
- kfree(pchnl);
-
- return status;
-}
-
-/*
- * ======== bridge_chnl_create ========
- * Create a channel manager object, responsible for opening new channels
- * and closing old ones for a given board.
- */
-int bridge_chnl_create(struct chnl_mgr **channel_mgr,
- struct dev_object *hdev_obj,
- const struct chnl_mgrattrs *mgr_attrts)
-{
- int status = 0;
- struct chnl_mgr *chnl_mgr_obj = NULL;
- u8 max_channels;
-
- /* Allocate channel manager object */
- chnl_mgr_obj = kzalloc(sizeof(struct chnl_mgr), GFP_KERNEL);
- if (chnl_mgr_obj) {
- /*
- * The max_channels attr must equal the # of supported chnls for
- * each transport(# chnls for PCPY = DDMA = ZCPY): i.e.
- * mgr_attrts->max_channels = CHNL_MAXCHANNELS =
- * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS.
- */
- max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY;
- /* Create array of channels */
- chnl_mgr_obj->channels = kzalloc(sizeof(struct chnl_object *)
- * max_channels, GFP_KERNEL);
- if (chnl_mgr_obj->channels) {
- /* Initialize chnl_mgr object */
- chnl_mgr_obj->type = CHNL_TYPESM;
- chnl_mgr_obj->word_size = mgr_attrts->word_size;
- /* Total # chnls supported */
- chnl_mgr_obj->max_channels = max_channels;
- chnl_mgr_obj->open_channels = 0;
- chnl_mgr_obj->output_mask = 0;
- chnl_mgr_obj->last_output = 0;
- chnl_mgr_obj->dev_obj = hdev_obj;
- spin_lock_init(&chnl_mgr_obj->chnl_mgr_lock);
- } else {
- status = -ENOMEM;
- }
- } else {
- status = -ENOMEM;
- }
-
- if (status) {
- bridge_chnl_destroy(chnl_mgr_obj);
- *channel_mgr = NULL;
- } else {
- /* Return channel manager object to caller... */
- *channel_mgr = chnl_mgr_obj;
- }
- return status;
-}
-
-/*
- * ======== bridge_chnl_destroy ========
- * Purpose:
- * Close all open channels, and destroy the channel manager.
- */
-int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr)
-{
- int status = 0;
- struct chnl_mgr *chnl_mgr_obj = hchnl_mgr;
- u32 chnl_id;
-
- if (hchnl_mgr) {
- /* Close all open channels: */
- for (chnl_id = 0; chnl_id < chnl_mgr_obj->max_channels;
- chnl_id++) {
- status =
- bridge_chnl_close(chnl_mgr_obj->channels
- [chnl_id]);
- if (status)
- dev_dbg(bridge, "%s: Error status 0x%x\n",
- __func__, status);
- }
-
- /* Free channel manager object: */
- kfree(chnl_mgr_obj->channels);
-
- /* Set hchnl_mgr to NULL in device object. */
- dev_set_chnl_mgr(chnl_mgr_obj->dev_obj, NULL);
- /* Free this Chnl Mgr object: */
- kfree(hchnl_mgr);
- } else {
- status = -EFAULT;
- }
- return status;
-}
-
-/*
- * ======== bridge_chnl_flush_io ========
- * purpose:
- * Flushes all the outstanding data requests on a channel.
- */
-int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout)
-{
- int status = 0;
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
- s8 chnl_mode = -1;
- struct chnl_mgr *chnl_mgr_obj;
- struct chnl_ioc chnl_ioc_obj;
- /* Check args: */
- if (pchnl) {
- if ((timeout == CHNL_IOCNOWAIT)
- && CHNL_IS_OUTPUT(pchnl->chnl_mode)) {
- status = -EINVAL;
- } else {
- chnl_mode = pchnl->chnl_mode;
- chnl_mgr_obj = pchnl->chnl_mgr_obj;
- }
- } else {
- status = -EFAULT;
- }
- if (!status) {
- /* Note: Currently, if another thread continues to add IO
- * requests to this channel, this function will continue to
- * flush all such queued IO requests. */
- if (CHNL_IS_OUTPUT(chnl_mode)
- && (pchnl->chnl_type == CHNL_PCPY)) {
- /* Wait for IO completions, up to the specified
- * timeout: */
- while (!list_empty(&pchnl->io_requests) && !status) {
- status = bridge_chnl_get_ioc(chnl_obj,
- timeout, &chnl_ioc_obj);
- if (status)
- continue;
-
- if (chnl_ioc_obj.status & CHNL_IOCSTATTIMEOUT)
- status = -ETIMEDOUT;
-
- }
- } else {
- status = bridge_chnl_cancel_io(chnl_obj);
- /* Now, leave the channel in the ready state: */
- pchnl->state &= ~CHNL_STATECANCEL;
- }
- }
- return status;
-}
-
-/*
- * ======== bridge_chnl_get_info ========
- * Purpose:
- * Retrieve information related to a channel.
- */
-int bridge_chnl_get_info(struct chnl_object *chnl_obj,
- struct chnl_info *channel_info)
-{
- int status = 0;
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
- if (channel_info != NULL) {
- if (pchnl) {
- /* Return the requested information: */
- channel_info->chnl_mgr = pchnl->chnl_mgr_obj;
- channel_info->event_obj = pchnl->user_event;
- channel_info->cnhl_id = pchnl->chnl_id;
- channel_info->mode = pchnl->chnl_mode;
- channel_info->bytes_tx = pchnl->bytes_moved;
- channel_info->process = pchnl->process;
- channel_info->sync_event = pchnl->sync_event;
- channel_info->cio_cs = pchnl->cio_cs;
- channel_info->cio_reqs = pchnl->cio_reqs;
- channel_info->state = pchnl->state;
- } else {
- status = -EFAULT;
- }
- } else {
- status = -EFAULT;
- }
- return status;
-}
-
-/*
- * ======== bridge_chnl_get_ioc ========
- * Optionally wait for I/O completion on a channel. Dequeue an I/O
- * completion record, which contains information about the completed
- * I/O request.
- * Note: Ensures Channel Invariant (see notes above).
- */
-int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
- struct chnl_ioc *chan_ioc)
-{
- int status = 0;
- struct chnl_object *pchnl = (struct chnl_object *)chnl_obj;
- struct chnl_irp *chnl_packet_obj;
- int stat_sync;
- bool dequeue_ioc = true;
- struct chnl_ioc ioc = { NULL, 0, 0, 0, 0 };
- u8 *host_sys_buf = NULL;
- struct bridge_dev_context *dev_ctxt;
- struct dev_object *dev_obj;
-
- /* Check args: */
- if (!chan_ioc || !pchnl) {
- status = -EFAULT;
- } else if (timeout == CHNL_IOCNOWAIT) {
- if (list_empty(&pchnl->io_completions))
- status = -EREMOTEIO;
-
- }
-
- dev_obj = dev_get_first();
- dev_get_bridge_context(dev_obj, &dev_ctxt);
- if (!dev_ctxt)
- status = -EFAULT;
-
- if (status)
- goto func_end;
-
- ioc.status = CHNL_IOCSTATCOMPLETE;
- if (timeout !=
- CHNL_IOCNOWAIT && list_empty(&pchnl->io_completions)) {
- if (timeout == CHNL_IOCINFINITE)
- timeout = SYNC_INFINITE;
-
- stat_sync = sync_wait_on_event(pchnl->sync_event, timeout);
- if (stat_sync == -ETIME) {
- /* No response from DSP */
- ioc.status |= CHNL_IOCSTATTIMEOUT;
- dequeue_ioc = false;
- } else if (stat_sync == -EPERM) {
- /* This can occur when the user mode thread is
- * aborted (^C), or when _VWIN32_WaitSingleObject()
- * fails due to unknown causes. */
- /* Even though Wait failed, there may be something in
- * the Q: */
- if (list_empty(&pchnl->io_completions)) {
- ioc.status |= CHNL_IOCSTATCANCEL;
- dequeue_ioc = false;
- }
- }
- }
- /* See comment in AddIOReq */
- spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
- omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
- if (dequeue_ioc) {
- /* Dequeue IOC and set chan_ioc; */
- chnl_packet_obj = list_first_entry(&pchnl->io_completions,
- struct chnl_irp, link);
- list_del(&chnl_packet_obj->link);
- /* Update chan_ioc from channel state and chirp: */
- pchnl->cio_cs--;
- /*
- * If this is a zero-copy channel, then set IOC's pbuf
- * to the DSP's address. This DSP address will get
- * translated to user's virtual addr later.
- */
- host_sys_buf = chnl_packet_obj->host_sys_buf;
- ioc.buf = chnl_packet_obj->host_user_buf;
- ioc.byte_size = chnl_packet_obj->byte_size;
- ioc.buf_size = chnl_packet_obj->buf_size;
- ioc.arg = chnl_packet_obj->arg;
- ioc.status |= chnl_packet_obj->status;
- /* Place the used chirp on the free list: */
- list_add_tail(&chnl_packet_obj->link,
- &pchnl->free_packets_list);
- } else {
- ioc.buf = NULL;
- ioc.byte_size = 0;
- ioc.arg = 0;
- ioc.buf_size = 0;
- }
- /* Ensure invariant: If any IOC's are queued for this channel... */
- if (!list_empty(&pchnl->io_completions)) {
- /* Since DSPStream_Reclaim() does not take a timeout
- * parameter, we pass the stream's timeout value to
- * bridge_chnl_get_ioc. We cannot determine whether or not
- * we have waited in user mode. Since the stream's timeout
- * value may be non-zero, we still have to set the event.
- * Therefore, this optimization is taken out.
- *
- * if (timeout == CHNL_IOCNOWAIT) {
- * ... ensure event is set..
- * sync_set_event(pchnl->sync_event);
- * } */
- sync_set_event(pchnl->sync_event);
- } else {
- /* else, if list is empty, ensure event is reset. */
- sync_reset_event(pchnl->sync_event);
- }
- omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX);
- spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock);
- if (dequeue_ioc
- && (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)) {
- if (!(ioc.buf < (void *)USERMODE_ADDR))
- goto func_cont;
-
- /* If the addr is in user mode, then copy it */
- if (!host_sys_buf || !ioc.buf) {
- status = -EFAULT;
- goto func_cont;
- }
- if (!CHNL_IS_INPUT(pchnl->chnl_mode))
- goto func_cont1;
-
- /*host_user_buf */
- status = copy_to_user(ioc.buf, host_sys_buf, ioc.byte_size);
- if (status) {
- if (current->flags & PF_EXITING)
- status = 0;
- }
- if (status)
- status = -EFAULT;
-func_cont1:
- kfree(host_sys_buf);
- }
-func_cont:
- /* Update User's IOC block: */
- *chan_ioc = ioc;
-func_end:
- return status;
-}
-
-/*
- * ======== bridge_chnl_get_mgr_info ========
- * Retrieve information related to the channel manager.
- */
-int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id,
- struct chnl_mgrinfo *mgr_info)
-{
- struct chnl_mgr *chnl_mgr_obj = (struct chnl_mgr *)hchnl_mgr;
-
- if (!mgr_info || !hchnl_mgr)
- return -EFAULT;
-
- if (ch_id > CHNL_MAXCHANNELS)
- return -ECHRNG;
-
- /* Return the requested information: */
- mgr_info->chnl_obj = chnl_mgr_obj->channels[ch_id];
- mgr_info->open_channels = chnl_mgr_obj->open_channels;
- mgr_info->type = chnl_mgr_obj->type;
- /* total # of chnls */
- mgr_info->max_channels = chnl_mgr_obj->max_channels;
-
- return 0;
-}
-
-/*
- * ======== bridge_chnl_idle ========
- * Idles a particular channel.
- */
-int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout,
- bool flush_data)
-{
- s8 chnl_mode;
- struct chnl_mgr *chnl_mgr_obj;
- int status = 0;
-
- chnl_mode = chnl_obj->chnl_mode;
- chnl_mgr_obj = chnl_obj->chnl_mgr_obj;
-
- if (CHNL_IS_OUTPUT(chnl_mode) && !flush_data) {
- /* Wait for IO completions, up to the specified timeout: */
- status = bridge_chnl_flush_io(chnl_obj, timeout);
- } else {
- status = bridge_chnl_cancel_io(chnl_obj);
-
- /* Reset the byte count and put channel back in ready state. */
- chnl_obj->bytes_moved = 0;
- chnl_obj->state &= ~CHNL_STATECANCEL;
- }
-
- return status;
-}
-
-/*
- * ======== bridge_chnl_open ========
- * Open a new half-duplex channel to the DSP board.
- */
-int bridge_chnl_open(struct chnl_object **chnl,
- struct chnl_mgr *hchnl_mgr, s8 chnl_mode,
- u32 ch_id, const struct chnl_attr *pattrs)
-{
- int status = 0;
- struct chnl_mgr *chnl_mgr_obj = hchnl_mgr;
- struct chnl_object *pchnl = NULL;
- struct sync_object *sync_event = NULL;
-
- *chnl = NULL;
-
- /* Validate Args: */
- if (!pattrs->uio_reqs)
- return -EINVAL;
-
- if (!hchnl_mgr)
- return -EFAULT;
-
- if (ch_id != CHNL_PICKFREE) {
- if (ch_id >= chnl_mgr_obj->max_channels)
- return -ECHRNG;
- if (chnl_mgr_obj->channels[ch_id] != NULL)
- return -EALREADY;
- } else {
- /* Check for free channel */
- status = search_free_channel(chnl_mgr_obj, &ch_id);
- if (status)
- return status;
- }
-
-
- /* Create channel object: */
- pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL);
- if (!pchnl)
- return -ENOMEM;
-
- /* Protect queues from io_dpc: */
- pchnl->state = CHNL_STATECANCEL;
-
- /* Allocate initial IOR and IOC queues: */
- status = create_chirp_list(&pchnl->free_packets_list,
- pattrs->uio_reqs);
- if (status)
- goto out_err;
-
- INIT_LIST_HEAD(&pchnl->io_requests);
- INIT_LIST_HEAD(&pchnl->io_completions);
-
- pchnl->chnl_packets = pattrs->uio_reqs;
- pchnl->cio_cs = 0;
- pchnl->cio_reqs = 0;
-
- sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
- if (!sync_event) {
- status = -ENOMEM;
- goto out_err;
- }
- sync_init_event(sync_event);
-
- pchnl->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
- if (!pchnl->ntfy_obj) {
- status = -ENOMEM;
- goto out_err;
- }
- ntfy_init(pchnl->ntfy_obj);
-
- /* Initialize CHNL object fields: */
- pchnl->chnl_mgr_obj = chnl_mgr_obj;
- pchnl->chnl_id = ch_id;
- pchnl->chnl_mode = chnl_mode;
- pchnl->user_event = sync_event;
- pchnl->sync_event = sync_event;
- /* Get the process handle */
- pchnl->process = current->tgid;
- pchnl->cb_arg = 0;
- pchnl->bytes_moved = 0;
- /* Default to proc-copy */
- pchnl->chnl_type = CHNL_PCPY;
-
- /* Insert channel object in channel manager: */
- chnl_mgr_obj->channels[pchnl->chnl_id] = pchnl;
- spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock);
- chnl_mgr_obj->open_channels++;
- spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
- /* Return result... */
- pchnl->state = CHNL_STATEREADY;
- *chnl = pchnl;
-
- return status;
-
-out_err:
- /* Free memory */
- free_chirp_list(&pchnl->io_completions);
- free_chirp_list(&pchnl->io_requests);
- free_chirp_list(&pchnl->free_packets_list);
-
- kfree(sync_event);
-
- if (pchnl->ntfy_obj) {
- ntfy_delete(pchnl->ntfy_obj);
- kfree(pchnl->ntfy_obj);
- pchnl->ntfy_obj = NULL;
- }
- kfree(pchnl);
-
- return status;
-}
-
-/*
- * ======== bridge_chnl_register_notify ========
- * Registers for events on a particular channel.
- */
-int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
- u32 event_mask, u32 notify_type,
- struct dsp_notification *hnotification)
-{
- int status = 0;
-
-
- if (event_mask)
- status = ntfy_register(chnl_obj->ntfy_obj, hnotification,
- event_mask, notify_type);
- else
- status = ntfy_unregister(chnl_obj->ntfy_obj, hnotification);
-
- return status;
-}
-
-/*
- * ======== create_chirp_list ========
- * Purpose:
- * Initialize a queue of channel I/O Request/Completion packets.
- * Parameters:
- * list: Pointer to a list_head
- * chirps: Number of Chirps to allocate.
- * Returns:
- * 0 if successful, error code otherwise.
- * Requires:
- * Ensures:
- */
-static int create_chirp_list(struct list_head *list, u32 chirps)
-{
- struct chnl_irp *chirp;
- u32 i;
-
- INIT_LIST_HEAD(list);
-
- /* Make N chirps and place on queue. */
- for (i = 0; i < chirps; i++) {
- chirp = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL);
- if (!chirp)
- break;
- list_add_tail(&chirp->link, list);
- }
-
- /* If we couldn't allocate all chirps, free those allocated: */
- if (i != chirps) {
- free_chirp_list(list);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*
- * ======== free_chirp_list ========
- * Purpose:
- * Free the queue of Chirps.
- */
-static void free_chirp_list(struct list_head *chirp_list)
-{
- struct chnl_irp *chirp, *tmp;
-
- list_for_each_entry_safe(chirp, tmp, chirp_list, link) {
- list_del(&chirp->link);
- kfree(chirp);
- }
-}
-
-/*
- * ======== search_free_channel ========
- * Search for a free channel slot in the array of channel pointers.
- */
-static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
- u32 *chnl)
-{
- int status = -ENOSR;
- u32 i;
-
- for (i = 0; i < chnl_mgr_obj->max_channels; i++) {
- if (chnl_mgr_obj->channels[i] == NULL) {
- status = 0;
- *chnl = i;
- break;
- }
- }
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c
deleted file mode 100644
index a1aca4416ca7..000000000000
--- a/drivers/staging/tidspbridge/core/dsp-clock.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * clk.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Clock and Timer services.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#define L4_34XX_BASE 0x48000000
-
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-#include <plat/dmtimer.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/dev.h>
-#include "_tiomap.h"
-
-/* ----------------------------------- This */
-#include <dspbridge/clk.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-
-#define OMAP_SSI_OFFSET 0x58000
-#define OMAP_SSI_SIZE 0x1000
-#define OMAP_SSI_SYSCONFIG_OFFSET 0x10
-
-#define SSI_AUTOIDLE (1 << 0)
-#define SSI_SIDLE_SMARTIDLE (2 << 3)
-#define SSI_MIDLE_NOIDLE (1 << 12)
-
-/* Clk types requested by the dsp */
-#define IVA2_CLK 0
-#define GPT_CLK 1
-#define WDT_CLK 2
-#define MCBSP_CLK 3
-#define SSI_CLK 4
-
-/* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */
-#define DMT_ID(id) ((id) + 4)
-#define DM_TIMER_CLOCKS 4
-
-/* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */
-#define MCBSP_ID(id) ((id) - 6)
-
-static struct omap_dm_timer *timer[4];
-
-struct clk *iva2_clk;
-
-struct dsp_ssi {
- struct clk *sst_fck;
- struct clk *ssr_fck;
- struct clk *ick;
-};
-
-static struct dsp_ssi ssi;
-
-static u32 dsp_clocks;
-
-static inline u32 is_dsp_clk_active(u32 clk, u8 id)
-{
- return clk & (1 << id);
-}
-
-static inline void set_dsp_clk_active(u32 *clk, u8 id)
-{
- *clk |= (1 << id);
-}
-
-static inline void set_dsp_clk_inactive(u32 *clk, u8 id)
-{
- *clk &= ~(1 << id);
-}
-
-static s8 get_clk_type(u8 id)
-{
- s8 type;
-
- if (id == DSP_CLK_IVA2)
- type = IVA2_CLK;
- else if (id <= DSP_CLK_GPT8)
- type = GPT_CLK;
- else if (id == DSP_CLK_WDT3)
- type = WDT_CLK;
- else if (id <= DSP_CLK_MCBSP5)
- type = MCBSP_CLK;
- else if (id == DSP_CLK_SSI)
- type = SSI_CLK;
- else
- type = -1;
-
- return type;
-}
-
-/*
- * ======== dsp_clk_exit ========
- * Purpose:
- * Cleanup CLK module.
- */
-void dsp_clk_exit(void)
-{
- int i;
-
- dsp_clock_disable_all(dsp_clocks);
-
- for (i = 0; i < DM_TIMER_CLOCKS; i++)
- omap_dm_timer_free(timer[i]);
-
- clk_unprepare(iva2_clk);
- clk_put(iva2_clk);
- clk_unprepare(ssi.sst_fck);
- clk_put(ssi.sst_fck);
- clk_unprepare(ssi.ssr_fck);
- clk_put(ssi.ssr_fck);
- clk_unprepare(ssi.ick);
- clk_put(ssi.ick);
-}
-
-/*
- * ======== dsp_clk_init ========
- * Purpose:
- * Initialize CLK module.
- */
-void dsp_clk_init(void)
-{
- static struct platform_device dspbridge_device;
- int i, id;
-
- dspbridge_device.dev.bus = &platform_bus_type;
-
- for (i = 0, id = 5; i < DM_TIMER_CLOCKS; i++, id++)
- timer[i] = omap_dm_timer_request_specific(id);
-
- iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck");
- if (IS_ERR(iva2_clk))
- dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk);
- else
- clk_prepare(iva2_clk);
-
- ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck");
- ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck");
- ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick");
-
- if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) {
- dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n",
- ssi.sst_fck, ssi.ssr_fck, ssi.ick);
- } else {
- clk_prepare(ssi.sst_fck);
- clk_prepare(ssi.ssr_fck);
- clk_prepare(ssi.ick);
- }
-}
-
-/**
- * dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout
- * @clk_id: GP Timer clock id.
- * @load: Overflow value.
- *
- * Sets an overflow interrupt for the desired GPT waiting for a timeout
- * of 5 msecs for the interrupt to occur.
- */
-void dsp_gpt_wait_overflow(short int clk_id, unsigned int load)
-{
- struct omap_dm_timer *gpt = timer[clk_id - 1];
- unsigned long timeout;
-
- if (!gpt)
- return;
-
- /* Enable overflow interrupt */
- omap_dm_timer_set_int_enable(gpt, OMAP_TIMER_INT_OVERFLOW);
-
- /*
- * Set counter value to overflow counter after
- * one tick and start timer.
- */
- omap_dm_timer_set_load_start(gpt, 0, load);
-
- /* Wait 80us for timer to overflow */
- udelay(80);
-
- timeout = msecs_to_jiffies(5);
- /* Check interrupt status and wait for interrupt */
- while (!(omap_dm_timer_read_status(gpt) & OMAP_TIMER_INT_OVERFLOW)) {
- if (time_is_after_jiffies(timeout)) {
- pr_err("%s: GPTimer interrupt failed\n", __func__);
- break;
- }
- }
-}
-
-/*
- * ======== dsp_clk_enable ========
- * Purpose:
- * Enable Clock .
- *
- */
-int dsp_clk_enable(enum dsp_clk_id clk_id)
-{
- int status = 0;
-
- if (is_dsp_clk_active(dsp_clocks, clk_id)) {
- dev_err(bridge, "WARN: clock id %d already enabled\n", clk_id);
- goto out;
- }
-
- switch (get_clk_type(clk_id)) {
- case IVA2_CLK:
- clk_enable(iva2_clk);
- break;
- case GPT_CLK:
- status = omap_dm_timer_start(timer[clk_id - 1]);
- break;
-#ifdef CONFIG_SND_OMAP_SOC_MCBSP
- case MCBSP_CLK:
- omap_mcbsp_request(MCBSP_ID(clk_id));
- omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PAD_SRC);
- break;
-#endif
- case WDT_CLK:
- dev_err(bridge, "ERROR: DSP requested to enable WDT3 clk\n");
- break;
- case SSI_CLK:
- clk_enable(ssi.sst_fck);
- clk_enable(ssi.ssr_fck);
- clk_enable(ssi.ick);
-
- /*
- * The SSI module need to configured not to have the Forced
- * idle for master interface. If it is set to forced idle,
- * the SSI module is transitioning to standby thereby causing
- * the client in the DSP hang waiting for the SSI module to
- * be active after enabling the clocks
- */
- ssi_clk_prepare(true);
- break;
- default:
- dev_err(bridge, "Invalid clock id for enable\n");
- status = -EPERM;
- }
-
- if (!status)
- set_dsp_clk_active(&dsp_clocks, clk_id);
-
-out:
- return status;
-}
-
-/**
- * dsp_clock_enable_all - Enable clocks used by the DSP
- * @dev_context Driver's device context strucure
- *
- * This function enables all the peripheral clocks that were requested by DSP.
- */
-u32 dsp_clock_enable_all(u32 dsp_per_clocks)
-{
- u32 clk_id;
- u32 status = -EPERM;
-
- for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
- if (is_dsp_clk_active(dsp_per_clocks, clk_id))
- status = dsp_clk_enable(clk_id);
- }
-
- return status;
-}
-
-/*
- * ======== dsp_clk_disable ========
- * Purpose:
- * Disable the clock.
- *
- */
-int dsp_clk_disable(enum dsp_clk_id clk_id)
-{
- int status = 0;
-
- if (!is_dsp_clk_active(dsp_clocks, clk_id)) {
- dev_err(bridge, "ERR: clock id %d already disabled\n", clk_id);
- goto out;
- }
-
- switch (get_clk_type(clk_id)) {
- case IVA2_CLK:
- clk_disable(iva2_clk);
- break;
- case GPT_CLK:
- status = omap_dm_timer_stop(timer[clk_id - 1]);
- break;
-#ifdef CONFIG_SND_OMAP_SOC_MCBSP
- case MCBSP_CLK:
- omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PRCM_SRC);
- omap_mcbsp_free(MCBSP_ID(clk_id));
- break;
-#endif
- case WDT_CLK:
- dev_err(bridge, "ERROR: DSP requested to disable WDT3 clk\n");
- break;
- case SSI_CLK:
- ssi_clk_prepare(false);
- ssi_clk_prepare(false);
- clk_disable(ssi.sst_fck);
- clk_disable(ssi.ssr_fck);
- clk_disable(ssi.ick);
- break;
- default:
- dev_err(bridge, "Invalid clock id for disable\n");
- status = -EPERM;
- }
-
- if (!status)
- set_dsp_clk_inactive(&dsp_clocks, clk_id);
-
-out:
- return status;
-}
-
-/**
- * dsp_clock_disable_all - Disable all active clocks
- * @dev_context Driver's device context structure
- *
- * This function disables all the peripheral clocks that were enabled by DSP.
- * It is meant to be called only when DSP is entering hibernation or when DSP
- * is in error state.
- */
-u32 dsp_clock_disable_all(u32 dsp_per_clocks)
-{
- u32 clk_id;
- u32 status = -EPERM;
-
- for (clk_id = 0; clk_id < DSP_CLK_NOT_DEFINED; clk_id++) {
- if (is_dsp_clk_active(dsp_per_clocks, clk_id))
- status = dsp_clk_disable(clk_id);
- }
-
- return status;
-}
-
-u32 dsp_clk_get_iva2_rate(void)
-{
- u32 clk_speed_khz;
-
- clk_speed_khz = clk_get_rate(iva2_clk);
- clk_speed_khz /= 1000;
- dev_dbg(bridge, "%s: clk speed Khz = %d\n", __func__, clk_speed_khz);
-
- return clk_speed_khz;
-}
-
-void ssi_clk_prepare(bool FLAG)
-{
- void __iomem *ssi_base;
- unsigned int value;
-
- ssi_base = ioremap(L4_34XX_BASE + OMAP_SSI_OFFSET, OMAP_SSI_SIZE);
- if (!ssi_base) {
- pr_err("%s: error, SSI not configured\n", __func__);
- return;
- }
-
- if (FLAG) {
- /* Set Autoidle, SIDLEMode to smart idle, and MIDLEmode to
- * no idle
- */
- value = SSI_AUTOIDLE | SSI_SIDLE_SMARTIDLE | SSI_MIDLE_NOIDLE;
- } else {
- /* Set Autoidle, SIDLEMode to forced idle, and MIDLEmode to
- * forced idle
- */
- value = SSI_AUTOIDLE;
- }
-
- __raw_writel(value, ssi_base + OMAP_SSI_SYSCONFIG_OFFSET);
- iounmap(ssi_base);
-}
-
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
deleted file mode 100644
index c2829aa7780f..000000000000
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ /dev/null
@@ -1,2245 +0,0 @@
-/*
- * io_sm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * IO dispatcher for a shared memory channel driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Channel Invariant:
- * There is an important invariant condition which must be maintained per
- * channel outside of bridge_chnl_get_ioc() and IO_Dispatch(), violation of
- * which may cause timeouts and/or failure of the sync_wait_on_event
- * function.
- */
-#include <linux/types.h>
-#include <linux/list.h>
-
-/* Host OS */
-#include <dspbridge/host_os.h>
-#include <linux/workqueue.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* Services Layer */
-#include <dspbridge/ntfy.h>
-#include <dspbridge/sync.h>
-
-/* Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
-/* Bridge Driver */
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/dspio.h>
-#include <dspbridge/dspioctl.h>
-#include <dspbridge/wdt.h>
-#include <_tiomap.h>
-#include <tiomap_io.h>
-#include <_tiomap_pwr.h>
-
-/* Platform Manager */
-#include <dspbridge/cod.h>
-#include <dspbridge/node.h>
-#include <dspbridge/dev.h>
-
-/* Others */
-#include <dspbridge/rms_sh.h>
-#include <dspbridge/mgr.h>
-#include <dspbridge/drv.h>
-#include "_cmm.h"
-#include "module_list.h"
-
-/* This */
-#include <dspbridge/io_sm.h>
-#include "_msg_sm.h"
-
-/* Defines, Data Structures, Typedefs */
-#define OUTPUTNOTREADY 0xffff
-#define NOTENABLED 0xffff /* Channel(s) not enabled */
-
-#define EXTEND "_EXT_END"
-
-#define SWAP_WORD(x) (x)
-#define UL_PAGE_ALIGN_SIZE 0x10000 /* Page Align Size */
-
-#define MAX_PM_REQS 32
-
-#define MMU_FAULT_HEAD1 0xa5a5a5a5
-#define MMU_FAULT_HEAD2 0x96969696
-#define POLL_MAX 1000
-#define MAX_MMU_DBGBUFF 10240
-
-/* IO Manager: only one created per board */
-struct io_mgr {
- /* These four fields must be the first fields in a io_mgr_ struct */
- /* Bridge device context */
- struct bridge_dev_context *bridge_context;
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
- struct dev_object *dev_obj; /* Device this board represents */
-
- /* These fields initialized in bridge_io_create() */
- struct chnl_mgr *chnl_mgr;
- struct shm *shared_mem; /* Shared Memory control */
- u8 *input; /* Address of input channel */
- u8 *output; /* Address of output channel */
- struct msg_mgr *msg_mgr; /* Message manager */
- /* Msg control for from DSP messages */
- struct msg_ctrl *msg_input_ctrl;
- /* Msg control for to DSP messages */
- struct msg_ctrl *msg_output_ctrl;
- u8 *msg_input; /* Address of input messages */
- u8 *msg_output; /* Address of output messages */
- u32 sm_buf_size; /* Size of a shared memory I/O channel */
- bool shared_irq; /* Is this IRQ shared? */
- u32 word_size; /* Size in bytes of DSP word */
- u16 intr_val; /* Interrupt value */
- /* Private extnd proc info; mmu setup */
- struct mgr_processorextinfo ext_proc_info;
- struct cmm_object *cmm_mgr; /* Shared Mem Mngr */
- struct work_struct io_workq; /* workqueue */
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
- u32 trace_buffer_begin; /* Trace message start address */
- u32 trace_buffer_end; /* Trace message end address */
- u32 trace_buffer_current; /* Trace message current address */
- u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */
- u8 *msg;
- u32 gpp_va;
- u32 dsp_va;
-#endif
- /* IO Dpc */
- u32 dpc_req; /* Number of requested DPC's. */
- u32 dpc_sched; /* Number of executed DPC's. */
- struct tasklet_struct dpc_tasklet;
- spinlock_t dpc_lock;
-
-};
-
-struct shm_symbol_val {
- u32 shm_base;
- u32 shm_lim;
- u32 msg_base;
- u32 msg_lim;
- u32 shm0_end;
- u32 dyn_ext;
- u32 ext_end;
-};
-
-/* Function Prototypes */
-static void io_dispatch_pm(struct io_mgr *pio_mgr);
-static void notify_chnl_complete(struct chnl_object *pchnl,
- struct chnl_irp *chnl_packet_obj);
-static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
- u8 io_mode);
-static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
- u8 io_mode);
-static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
-static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr);
-static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
- struct chnl_object *pchnl, u32 mask);
-
-/* Bus Addr (cached kernel) */
-static int register_shm_segs(struct io_mgr *hio_mgr,
- struct cod_manager *cod_man,
- u32 dw_gpp_base_pa);
-
-static inline void set_chnl_free(struct shm *sm, u32 chnl)
-{
- sm->host_free_mask &= ~(1 << chnl);
-}
-
-static inline void set_chnl_busy(struct shm *sm, u32 chnl)
-{
- sm->host_free_mask |= 1 << chnl;
-}
-
-
-/*
- * ======== bridge_io_create ========
- * Create an IO manager object.
- */
-int bridge_io_create(struct io_mgr **io_man,
- struct dev_object *hdev_obj,
- const struct io_attrs *mgr_attrts)
-{
- struct io_mgr *pio_mgr = NULL;
- struct bridge_dev_context *hbridge_context = NULL;
- struct cfg_devnode *dev_node_obj;
- struct chnl_mgr *hchnl_mgr;
- u8 dev_type;
-
- /* Check requirements */
- if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
- return -EFAULT;
-
- *io_man = NULL;
-
- dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
- if (!hchnl_mgr || hchnl_mgr->iomgr)
- return -EFAULT;
-
- /*
- * Message manager will be created when a file is loaded, since
- * size of message buffer in shared memory is configurable in
- * the base image.
- */
- dev_get_bridge_context(hdev_obj, &hbridge_context);
- if (!hbridge_context)
- return -EFAULT;
-
- dev_get_dev_type(hdev_obj, &dev_type);
-
- /* Allocate IO manager object */
- pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
- if (!pio_mgr)
- return -ENOMEM;
-
- /* Initialize chnl_mgr object */
- pio_mgr->chnl_mgr = hchnl_mgr;
- pio_mgr->word_size = mgr_attrts->word_size;
-
- if (dev_type == DSP_UNIT) {
- /* Create an IO DPC */
- tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr);
-
- /* Initialize DPC counters */
- pio_mgr->dpc_req = 0;
- pio_mgr->dpc_sched = 0;
-
- spin_lock_init(&pio_mgr->dpc_lock);
-
- if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
- bridge_io_destroy(pio_mgr);
- return -EIO;
- }
- }
-
- pio_mgr->bridge_context = hbridge_context;
- pio_mgr->shared_irq = mgr_attrts->irq_shared;
- if (dsp_wdt_init()) {
- bridge_io_destroy(pio_mgr);
- return -EPERM;
- }
-
- /* Return IO manager object to caller... */
- hchnl_mgr->iomgr = pio_mgr;
- *io_man = pio_mgr;
-
- return 0;
-}
-
-/*
- * ======== bridge_io_destroy ========
- * Purpose:
- * Disable interrupts, destroy the IO manager.
- */
-int bridge_io_destroy(struct io_mgr *hio_mgr)
-{
- int status = 0;
- if (hio_mgr) {
- /* Free IO DPC object */
- tasklet_kill(&hio_mgr->dpc_tasklet);
-
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
- kfree(hio_mgr->msg);
-#endif
- dsp_wdt_exit();
- /* Free this IO manager object */
- kfree(hio_mgr);
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
-
-struct shm_symbol_val *_get_shm_symbol_values(struct io_mgr *hio_mgr)
-{
- struct shm_symbol_val *s;
- struct cod_manager *cod_man;
- int status;
-
- s = kzalloc(sizeof(*s), GFP_KERNEL);
- if (!s)
- return ERR_PTR(-ENOMEM);
-
- status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man);
- if (status)
- goto free_symbol;
-
- /* Get start and length of channel part of shared memory */
- status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_BASE_SYM,
- &s->shm_base);
- if (status)
- goto free_symbol;
-
- status = cod_get_sym_value(cod_man, CHNL_SHARED_BUFFER_LIMIT_SYM,
- &s->shm_lim);
- if (status)
- goto free_symbol;
-
- if (s->shm_lim <= s->shm_base) {
- status = -EINVAL;
- goto free_symbol;
- }
-
- /* Get start and length of message part of shared memory */
- status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_BASE_SYM,
- &s->msg_base);
- if (status)
- goto free_symbol;
-
- status = cod_get_sym_value(cod_man, MSG_SHARED_BUFFER_LIMIT_SYM,
- &s->msg_lim);
- if (status)
- goto free_symbol;
-
- if (s->msg_lim <= s->msg_base) {
- status = -EINVAL;
- goto free_symbol;
- }
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- status = cod_get_sym_value(cod_man, DSP_TRACESEC_END, &s->shm0_end);
-#else
- status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM, &s->shm0_end);
-#endif
- if (status)
- goto free_symbol;
-
- status = cod_get_sym_value(cod_man, DYNEXTBASE, &s->dyn_ext);
- if (status)
- goto free_symbol;
-
- status = cod_get_sym_value(cod_man, EXTEND, &s->ext_end);
- if (status)
- goto free_symbol;
-
- return s;
-
-free_symbol:
- kfree(s);
- return ERR_PTR(status);
-}
-
-/*
- * ======== bridge_io_on_loaded ========
- * Purpose:
- * Called when a new program is loaded to get shared memory buffer
- * parameters from COFF file. ulSharedBufferBase and ulSharedBufferLimit
- * are in DSP address units.
- */
-int bridge_io_on_loaded(struct io_mgr *hio_mgr)
-{
- struct bridge_dev_context *dc = hio_mgr->bridge_context;
- struct cfg_hostres *cfg_res = dc->resources;
- struct bridge_ioctl_extproc *eproc;
- struct cod_manager *cod_man;
- struct chnl_mgr *hchnl_mgr;
- struct msg_mgr *hmsg_mgr;
- struct shm_symbol_val *s;
- int status;
- u8 num_procs;
- s32 ndx;
- u32 i;
- u32 mem_sz, msg_sz, pad_sz, shm_sz, shm_base_offs;
- u32 seg0_sz, seg1_sz;
- u32 pa, va, da;
- u32 pa_curr, va_curr, da_curr;
- u32 bytes;
- u32 all_bits = 0;
- u32 page_size[] = {
- HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
- HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
- };
- u32 map_attrs = DSP_MAPLITTLEENDIAN | DSP_MAPPHYSICALADDR |
- DSP_MAPELEMSIZE32 | DSP_MAPDONOTLOCK;
-
- status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man);
- if (status)
- return status;
-
- hchnl_mgr = hio_mgr->chnl_mgr;
-
- /* The message manager is destroyed when the board is stopped */
- dev_get_msg_mgr(hio_mgr->dev_obj, &hio_mgr->msg_mgr);
- hmsg_mgr = hio_mgr->msg_mgr;
- if (!hchnl_mgr || !hmsg_mgr)
- return -EFAULT;
-
- if (hio_mgr->shared_mem)
- hio_mgr->shared_mem = NULL;
-
- s = _get_shm_symbol_values(hio_mgr);
- if (IS_ERR(s))
- return PTR_ERR(s);
-
- /* Get total length in bytes */
- shm_sz = (s->shm_lim - s->shm_base + 1) * hio_mgr->word_size;
-
- /* Calculate size of a PROCCOPY shared memory region */
- dev_dbg(bridge, "%s: (proc)proccopy shmmem size: 0x%x bytes\n",
- __func__, shm_sz - sizeof(struct shm));
-
- /* Length (bytes) of messaging part of shared memory */
- msg_sz = (s->msg_lim - s->msg_base + 1) * hio_mgr->word_size;
-
- /* Total length (bytes) of shared memory: chnl + msg */
- mem_sz = shm_sz + msg_sz;
-
- /* Get memory reserved in host resources */
- (void)mgr_enum_processor_info(0,
- (struct dsp_processorinfo *)
- &hio_mgr->ext_proc_info,
- sizeof(struct mgr_processorextinfo),
- &num_procs);
-
- /* IO supports only one DSP for now */
- if (num_procs != 1) {
- status = -EINVAL;
- goto free_symbol;
- }
-
- /* The first MMU TLB entry(TLB_0) in DCD is ShmBase */
- pa = cfg_res->mem_phys[1];
- va = cfg_res->mem_base[1];
-
- /* This is the virtual uncached ioremapped address!!! */
- /* Why can't we directly take the DSPVA from the symbols? */
- da = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt;
- seg0_sz = (s->shm0_end - da) * hio_mgr->word_size;
- seg1_sz = (s->ext_end - s->dyn_ext) * hio_mgr->word_size;
-
- /* 4K align */
- seg1_sz = (seg1_sz + 0xFFF) & (~0xFFFUL);
-
- /* 64K align */
- seg0_sz = (seg0_sz + 0xFFFF) & (~0xFFFFUL);
-
- pad_sz = UL_PAGE_ALIGN_SIZE - ((pa + seg1_sz) % UL_PAGE_ALIGN_SIZE);
- if (pad_sz == UL_PAGE_ALIGN_SIZE)
- pad_sz = 0x0;
-
- dev_dbg(bridge, "%s: pa %x, va %x, da %x\n", __func__, pa, va, da);
- dev_dbg(bridge,
- "shm0_end %x, dyn_ext %x, ext_end %x, seg0_sz %x seg1_sz %x\n",
- s->shm0_end, s->dyn_ext, s->ext_end, seg0_sz, seg1_sz);
-
- if ((seg0_sz + seg1_sz + pad_sz) > cfg_res->mem_length[1]) {
- pr_err("%s: shm Error, reserved 0x%x required 0x%x\n",
- __func__, cfg_res->mem_length[1],
- seg0_sz + seg1_sz + pad_sz);
- status = -ENOMEM;
- goto free_symbol;
- }
-
- pa_curr = pa;
- va_curr = s->dyn_ext * hio_mgr->word_size;
- da_curr = va;
- bytes = seg1_sz;
-
- /*
- * Try to fit into TLB entries. If not possible, push them to page
- * tables. It is quite possible that if sections are not on
- * bigger page boundary, we may end up making several small pages.
- * So, push them onto page tables, if that is the case.
- */
- while (bytes) {
- /*
- * To find the max. page size with which both PA & VA are
- * aligned.
- */
- all_bits = pa_curr | va_curr;
- dev_dbg(bridge,
- "seg all_bits %x, pa_curr %x, va_curr %x, bytes %x\n",
- all_bits, pa_curr, va_curr, bytes);
-
- for (i = 0; i < 4; i++) {
- if ((bytes >= page_size[i]) &&
- ((all_bits & (page_size[i] - 1)) == 0)) {
- status = hio_mgr->intf_fxns->brd_mem_map(dc,
- pa_curr, va_curr,
- page_size[i], map_attrs,
- NULL);
- if (status)
- goto free_symbol;
-
- pa_curr += page_size[i];
- va_curr += page_size[i];
- da_curr += page_size[i];
- bytes -= page_size[i];
- /*
- * Don't try smaller sizes. Hopefully we have
- * reached an address aligned to a bigger page
- * size.
- */
- break;
- }
- }
- }
-
- pa_curr += pad_sz;
- va_curr += pad_sz;
- da_curr += pad_sz;
- bytes = seg0_sz;
- va_curr = da * hio_mgr->word_size;
-
- eproc = kzalloc(sizeof(*eproc) * BRDIOCTL_NUMOFMMUTLB, GFP_KERNEL);
- if (!eproc) {
- status = -ENOMEM;
- goto free_symbol;
- }
-
- ndx = 0;
- /* Configure the TLB entries for the next cacheable segment */
- while (bytes) {
- /*
- * To find the max. page size with which both PA & VA are
- * aligned.
- */
- all_bits = pa_curr | va_curr;
- dev_dbg(bridge,
- "seg1 all_bits %x, pa_curr %x, va_curr %x, bytes %x\n",
- all_bits, pa_curr, va_curr, bytes);
-
- for (i = 0; i < 4; i++) {
- if (!(bytes >= page_size[i]) ||
- !((all_bits & (page_size[i] - 1)) == 0))
- continue;
-
- if (ndx >= MAX_LOCK_TLB_ENTRIES) {
- status = hio_mgr->intf_fxns->brd_mem_map(dc,
- pa_curr, va_curr,
- page_size[i], map_attrs,
- NULL);
- dev_dbg(bridge,
- "PTE pa %x va %x dsp_va %x sz %x\n",
- eproc[ndx].gpp_pa,
- eproc[ndx].gpp_va,
- eproc[ndx].dsp_va *
- hio_mgr->word_size, page_size[i]);
- if (status)
- goto free_eproc;
- }
-
- /* This is the physical address written to DSP MMU */
- eproc[ndx].gpp_pa = pa_curr;
-
- /*
- * This is the virtual uncached ioremapped
- * address!!!
- */
- eproc[ndx].gpp_va = da_curr;
- eproc[ndx].dsp_va = va_curr / hio_mgr->word_size;
- eproc[ndx].size = page_size[i];
- eproc[ndx].endianism = HW_LITTLE_ENDIAN;
- eproc[ndx].elem_size = HW_ELEM_SIZE16BIT;
- eproc[ndx].mixed_mode = HW_MMU_CPUES;
- dev_dbg(bridge, "%s: tlb pa %x va %x dsp_va %x sz %x\n",
- __func__, eproc[ndx].gpp_pa,
- eproc[ndx].gpp_va,
- eproc[ndx].dsp_va * hio_mgr->word_size,
- page_size[i]);
- ndx++;
-
- pa_curr += page_size[i];
- va_curr += page_size[i];
- da_curr += page_size[i];
- bytes -= page_size[i];
- /*
- * Don't try smaller sizes. Hopefully we have reached
- * an address aligned to a bigger page size.
- */
- break;
- }
- }
-
- /*
- * Copy remaining entries from CDB. All entries are 1 MB and
- * should not conflict with shm entries on MPU or DSP side.
- */
- for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) {
- struct mgr_processorextinfo *ep = &hio_mgr->ext_proc_info;
- u32 word_sz = hio_mgr->word_size;
-
- if (ep->ty_tlb[i].gpp_phys == 0)
- continue;
-
- if ((ep->ty_tlb[i].gpp_phys > pa - 0x100000 &&
- ep->ty_tlb[i].gpp_phys <= pa + seg0_sz) ||
- (ep->ty_tlb[i].dsp_virt > da - 0x100000 / word_sz &&
- ep->ty_tlb[i].dsp_virt <= da + seg0_sz / word_sz)) {
- dev_dbg(bridge,
- "err cdb%d pa %x da %x shm pa %x da %x sz %x\n",
- i, ep->ty_tlb[i].gpp_phys,
- ep->ty_tlb[i].dsp_virt, pa, da, seg0_sz);
- status = -EPERM;
- goto free_eproc;
- }
-
- if (ndx >= MAX_LOCK_TLB_ENTRIES) {
- status = hio_mgr->intf_fxns->brd_mem_map(dc,
- ep->ty_tlb[i].gpp_phys,
- ep->ty_tlb[i].dsp_virt,
- 0x100000, map_attrs, NULL);
- if (status)
- goto free_eproc;
- }
-
- eproc[ndx].dsp_va = ep->ty_tlb[i].dsp_virt;
- eproc[ndx].gpp_pa = ep->ty_tlb[i].gpp_phys;
- eproc[ndx].gpp_va = 0;
-
- /* 1 MB */
- eproc[ndx].size = 0x100000;
- dev_dbg(bridge, "shm MMU entry pa %x da 0x%x\n",
- eproc[ndx].gpp_pa, eproc[ndx].dsp_va);
- ndx++;
- }
-
- /* Map the L4 peripherals */
- i = 0;
- while (l4_peripheral_table[i].phys_addr) {
- status = hio_mgr->intf_fxns->brd_mem_map(dc,
- l4_peripheral_table[i].phys_addr,
- l4_peripheral_table[i].dsp_virt_addr,
- HW_PAGE_SIZE4KB, map_attrs, NULL);
- if (status)
- goto free_eproc;
- i++;
- }
-
- for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) {
- eproc[i].dsp_va = 0;
- eproc[i].gpp_pa = 0;
- eproc[i].gpp_va = 0;
- eproc[i].size = 0;
- }
-
- /*
- * Set the shm physical address entry (grayed out in CDB file)
- * to the virtual uncached ioremapped address of shm reserved
- * on MPU.
- */
- hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys =
- (va + seg1_sz + pad_sz);
-
- /*
- * Need shm Phys addr. IO supports only one DSP for now:
- * num_procs = 1.
- */
- if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys)
- return -EFAULT;
-
- if (eproc[0].dsp_va > s->shm_base)
- return -EPERM;
-
- /* shm_base may not be at ul_dsp_va address */
- shm_base_offs = (s->shm_base - eproc[0].dsp_va) *
- hio_mgr->word_size;
- /*
- * bridge_dev_ctrl() will set dev context dsp-mmu info. In
- * bridge_brd_start() the MMU will be re-programed with MMU
- * DSPVa-GPPPa pair info while DSP is in a known
- * (reset) state.
- */
- status = hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context,
- BRDIOCTL_SETMMUCONFIG, eproc);
- if (status)
- goto free_eproc;
-
- s->shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys;
- s->shm_base += shm_base_offs;
- s->shm_base = (u32) MEM_LINEAR_ADDRESS((void *)s->shm_base,
- mem_sz);
- if (!s->shm_base) {
- status = -EFAULT;
- goto free_eproc;
- }
-
- /* Register SM */
- status = register_shm_segs(hio_mgr, cod_man, eproc[0].gpp_pa);
-
- hio_mgr->shared_mem = (struct shm *)s->shm_base;
- hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm);
- hio_mgr->output = hio_mgr->input + (shm_sz -
- sizeof(struct shm)) / 2;
- hio_mgr->sm_buf_size = hio_mgr->output - hio_mgr->input;
-
- /* Set up Shared memory addresses for messaging */
- hio_mgr->msg_input_ctrl =
- (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem + shm_sz);
- hio_mgr->msg_input =
- (u8 *) hio_mgr->msg_input_ctrl + sizeof(struct msg_ctrl);
- hio_mgr->msg_output_ctrl =
- (struct msg_ctrl *)((u8 *) hio_mgr->msg_input_ctrl +
- msg_sz / 2);
- hio_mgr->msg_output =
- (u8 *) hio_mgr->msg_output_ctrl + sizeof(struct msg_ctrl);
- hmsg_mgr->max_msgs =
- ((u8 *) hio_mgr->msg_output_ctrl - hio_mgr->msg_input) /
- sizeof(struct msg_dspmsg);
-
- dev_dbg(bridge, "IO MGR shm details: shared_mem %p, input %p, "
- "output %p, msg_input_ctrl %p, msg_input %p, "
- "msg_output_ctrl %p, msg_output %p\n",
- (u8 *) hio_mgr->shared_mem, hio_mgr->input,
- hio_mgr->output, (u8 *) hio_mgr->msg_input_ctrl,
- hio_mgr->msg_input, (u8 *) hio_mgr->msg_output_ctrl,
- hio_mgr->msg_output);
- dev_dbg(bridge, "(proc) Mas msgs in shared memory: 0x%x\n",
- hmsg_mgr->max_msgs);
- memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm));
-
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
- /* Get the start address of trace buffer */
- status = cod_get_sym_value(cod_man, SYS_PUTCBEG,
- &hio_mgr->trace_buffer_begin);
- if (status)
- goto free_eproc;
-
- hio_mgr->gpp_read_pointer =
- hio_mgr->trace_buffer_begin =
- (va + seg1_sz + pad_sz) +
- (hio_mgr->trace_buffer_begin - da);
-
- /* Get the end address of trace buffer */
- status = cod_get_sym_value(cod_man, SYS_PUTCEND,
- &hio_mgr->trace_buffer_end);
- if (status)
- goto free_eproc;
-
- hio_mgr->trace_buffer_end =
- (va + seg1_sz + pad_sz) +
- (hio_mgr->trace_buffer_end - da);
-
- /* Get the current address of DSP write pointer */
- status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT,
- &hio_mgr->trace_buffer_current);
- if (status)
- goto free_eproc;
-
- hio_mgr->trace_buffer_current =
- (va + seg1_sz + pad_sz) +
- (hio_mgr->trace_buffer_current - da);
-
- /* Calculate the size of trace buffer */
- kfree(hio_mgr->msg);
- hio_mgr->msg = kmalloc(((hio_mgr->trace_buffer_end -
- hio_mgr->trace_buffer_begin) *
- hio_mgr->word_size) + 2, GFP_KERNEL);
- if (!hio_mgr->msg) {
- status = -ENOMEM;
- goto free_eproc;
- }
-
- hio_mgr->dsp_va = da;
- hio_mgr->gpp_va = (va + seg1_sz + pad_sz);
-#endif
-
-free_eproc:
- kfree(eproc);
-free_symbol:
- kfree(s);
-
- return status;
-}
-
-/*
- * ======== io_buf_size ========
- * Size of shared memory I/O channel.
- */
-u32 io_buf_size(struct io_mgr *hio_mgr)
-{
- if (hio_mgr)
- return hio_mgr->sm_buf_size;
- else
- return 0;
-}
-
-/*
- * ======== io_cancel_chnl ========
- * Cancel IO on a given PCPY channel.
- */
-void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl)
-{
- struct io_mgr *pio_mgr = (struct io_mgr *)hio_mgr;
- struct shm *sm;
-
- if (!hio_mgr)
- goto func_end;
- sm = hio_mgr->shared_mem;
-
- /* Inform DSP that we have no more buffers on this channel */
- set_chnl_free(sm, chnl);
-
- sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS);
-func_end:
- return;
-}
-
-
-/*
- * ======== io_dispatch_pm ========
- * Performs I/O dispatch on PM related messages from DSP
- */
-static void io_dispatch_pm(struct io_mgr *pio_mgr)
-{
- int status;
- u32 parg[2];
-
- /* Perform Power message processing here */
- parg[0] = pio_mgr->intr_val;
-
- /* Send the command to the Bridge clk/pwr manager to handle */
- if (parg[0] == MBX_PM_HIBERNATE_EN) {
- dev_dbg(bridge, "PM: Hibernate command\n");
- status = pio_mgr->intf_fxns->
- dev_cntrl(pio_mgr->bridge_context,
- BRDIOCTL_PWR_HIBERNATE, parg);
- if (status)
- pr_err("%s: hibernate cmd failed 0x%x\n",
- __func__, status);
- } else if (parg[0] == MBX_PM_OPP_REQ) {
- parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt;
- dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]);
- status = pio_mgr->intf_fxns->
- dev_cntrl(pio_mgr->bridge_context,
- BRDIOCTL_CONSTRAINT_REQUEST, parg);
- if (status)
- dev_dbg(bridge, "PM: Failed to set constraint "
- "= 0x%x\n", parg[1]);
- } else {
- dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n",
- parg[0]);
- status = pio_mgr->intf_fxns->
- dev_cntrl(pio_mgr->bridge_context,
- BRDIOCTL_CLK_CTRL, parg);
- if (status)
- dev_dbg(bridge, "PM: Failed to ctrl the DSP clk"
- "= 0x%x\n", *parg);
- }
-}
-
-/*
- * ======== io_dpc ========
- * Deferred procedure call for shared memory channel driver ISR. Carries
- * out the dispatch of I/O as a non-preemptible event. It can only be
- * pre-empted by an ISR.
- */
-void io_dpc(unsigned long ref_data)
-{
- struct io_mgr *pio_mgr = (struct io_mgr *)ref_data;
- struct chnl_mgr *chnl_mgr_obj;
- struct msg_mgr *msg_mgr_obj;
- struct deh_mgr *hdeh_mgr;
- u32 requested;
- u32 serviced;
-
- if (!pio_mgr)
- goto func_end;
- chnl_mgr_obj = pio_mgr->chnl_mgr;
- dev_get_msg_mgr(pio_mgr->dev_obj, &msg_mgr_obj);
- dev_get_deh_mgr(pio_mgr->dev_obj, &hdeh_mgr);
- if (!chnl_mgr_obj)
- goto func_end;
-
- requested = pio_mgr->dpc_req;
- serviced = pio_mgr->dpc_sched;
-
- if (serviced == requested)
- goto func_end;
-
- /* Process pending DPC's */
- do {
- /* Check value of interrupt reg to ensure it's a valid error */
- if ((pio_mgr->intr_val > DEH_BASE) &&
- (pio_mgr->intr_val < DEH_LIMIT)) {
- /* Notify DSP/BIOS exception */
- if (hdeh_mgr) {
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- print_dsp_debug_trace(pio_mgr);
-#endif
- bridge_deh_notify(hdeh_mgr, DSP_SYSERROR,
- pio_mgr->intr_val);
- }
- }
- /* Proc-copy channel dispatch */
- input_chnl(pio_mgr, NULL, IO_SERVICE);
- output_chnl(pio_mgr, NULL, IO_SERVICE);
-
-#ifdef CHNL_MESSAGES
- if (msg_mgr_obj) {
- /* Perform I/O dispatch on message queues */
- input_msg(pio_mgr, msg_mgr_obj);
- output_msg(pio_mgr, msg_mgr_obj);
- }
-
-#endif
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) {
- /* Notify DSP Trace message */
- print_dsp_debug_trace(pio_mgr);
- }
-#endif
- serviced++;
- } while (serviced != requested);
- pio_mgr->dpc_sched = requested;
-func_end:
- return;
-}
-
-/*
- * ======== io_mbox_msg ========
- * Main interrupt handler for the shared memory IO manager.
- * Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then
- * schedules a DPC to dispatch I/O.
- */
-int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg)
-{
- struct io_mgr *pio_mgr;
- struct dev_object *dev_obj;
- unsigned long flags;
-
- dev_obj = dev_get_first();
- dev_get_io_mgr(dev_obj, &pio_mgr);
-
- if (!pio_mgr)
- return NOTIFY_BAD;
-
- pio_mgr->intr_val = (u16)((u32)msg);
- if (pio_mgr->intr_val & MBX_PM_CLASS)
- io_dispatch_pm(pio_mgr);
-
- if (pio_mgr->intr_val == MBX_DEH_RESET) {
- pio_mgr->intr_val = 0;
- } else {
- spin_lock_irqsave(&pio_mgr->dpc_lock, flags);
- pio_mgr->dpc_req++;
- spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags);
- tasklet_schedule(&pio_mgr->dpc_tasklet);
- }
- return NOTIFY_OK;
-}
-
-/*
- * ======== io_request_chnl ========
- * Purpose:
- * Request channel I/O from the DSP. Sets flags in shared memory, then
- * interrupts the DSP.
- */
-void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl,
- u8 io_mode, u16 *mbx_val)
-{
- struct chnl_mgr *chnl_mgr_obj;
- struct shm *sm;
-
- if (!pchnl || !mbx_val)
- goto func_end;
- chnl_mgr_obj = io_manager->chnl_mgr;
- sm = io_manager->shared_mem;
- if (io_mode == IO_INPUT) {
- /* Indicate to the DSP we have a buffer available for input */
- set_chnl_busy(sm, pchnl->chnl_id);
- *mbx_val = MBX_PCPY_CLASS;
- } else if (io_mode == IO_OUTPUT) {
- /*
- * Record the fact that we have a buffer available for
- * output.
- */
- chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id);
- } else {
- }
-func_end:
- return;
-}
-
-/*
- * ======== iosm_schedule ========
- * Schedule DPC for IO.
- */
-void iosm_schedule(struct io_mgr *io_manager)
-{
- unsigned long flags;
-
- if (!io_manager)
- return;
-
- /* Increment count of DPC's pending. */
- spin_lock_irqsave(&io_manager->dpc_lock, flags);
- io_manager->dpc_req++;
- spin_unlock_irqrestore(&io_manager->dpc_lock, flags);
-
- /* Schedule DPC */
- tasklet_schedule(&io_manager->dpc_tasklet);
-}
-
-/*
- * ======== find_ready_output ========
- * Search for a host output channel which is ready to send. If this is
- * called as a result of servicing the DPC, then implement a round
- * robin search; otherwise, this was called by a client thread (via
- * IO_Dispatch()), so just start searching from the current channel id.
- */
-static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj,
- struct chnl_object *pchnl, u32 mask)
-{
- u32 ret = OUTPUTNOTREADY;
- u32 id, start_id;
- u32 shift;
-
- id = (pchnl !=
- NULL ? pchnl->chnl_id : (chnl_mgr_obj->last_output + 1));
- id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
- if (id >= CHNL_MAXCHANNELS)
- goto func_end;
- if (mask) {
- shift = (1 << id);
- start_id = id;
- do {
- if (mask & shift) {
- ret = id;
- if (pchnl == NULL)
- chnl_mgr_obj->last_output = id;
- break;
- }
- id = id + 1;
- id = ((id == CHNL_MAXCHANNELS) ? 0 : id);
- shift = (1 << id);
- } while (id != start_id);
- }
-func_end:
- return ret;
-}
-
-/*
- * ======== input_chnl ========
- * Dispatch a buffer on an input channel.
- */
-static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
- u8 io_mode)
-{
- struct chnl_mgr *chnl_mgr_obj;
- struct shm *sm;
- u32 chnl_id;
- u32 bytes;
- struct chnl_irp *chnl_packet_obj = NULL;
- u32 dw_arg;
- bool clear_chnl = false;
- bool notify_client = false;
-
- sm = pio_mgr->shared_mem;
- chnl_mgr_obj = pio_mgr->chnl_mgr;
-
- /* Attempt to perform input */
- if (!sm->input_full)
- goto func_end;
-
- bytes = sm->input_size * chnl_mgr_obj->word_size;
- chnl_id = sm->input_id;
- dw_arg = sm->arg;
- if (chnl_id >= CHNL_MAXCHANNELS) {
- /* Shouldn't be here: would indicate corrupted shm. */
- goto func_end;
- }
- pchnl = chnl_mgr_obj->channels[chnl_id];
- if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) {
- if ((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY) {
- /* Get the I/O request, and attempt a transfer */
- if (!list_empty(&pchnl->io_requests)) {
- if (!pchnl->cio_reqs)
- goto func_end;
-
- chnl_packet_obj = list_first_entry(
- &pchnl->io_requests,
- struct chnl_irp, link);
- list_del(&chnl_packet_obj->link);
- pchnl->cio_reqs--;
-
- /*
- * Ensure we don't overflow the client's
- * buffer.
- */
- bytes = min(bytes, chnl_packet_obj->byte_size);
- memcpy(chnl_packet_obj->host_sys_buf,
- pio_mgr->input, bytes);
- pchnl->bytes_moved += bytes;
- chnl_packet_obj->byte_size = bytes;
- chnl_packet_obj->arg = dw_arg;
- chnl_packet_obj->status = CHNL_IOCSTATCOMPLETE;
-
- if (bytes == 0) {
- /*
- * This assertion fails if the DSP
- * sends EOS more than once on this
- * channel.
- */
- if (pchnl->state & CHNL_STATEEOS)
- goto func_end;
- /*
- * Zero bytes indicates EOS. Update
- * IOC status for this chirp, and also
- * the channel state.
- */
- chnl_packet_obj->status |=
- CHNL_IOCSTATEOS;
- pchnl->state |= CHNL_STATEEOS;
- /*
- * Notify that end of stream has
- * occurred.
- */
- ntfy_notify(pchnl->ntfy_obj,
- DSP_STREAMDONE);
- }
- /* Tell DSP if no more I/O buffers available */
- if (list_empty(&pchnl->io_requests))
- set_chnl_free(sm, pchnl->chnl_id);
- clear_chnl = true;
- notify_client = true;
- } else {
- /*
- * Input full for this channel, but we have no
- * buffers available. The channel must be
- * "idling". Clear out the physical input
- * channel.
- */
- clear_chnl = true;
- }
- } else {
- /* Input channel cancelled: clear input channel */
- clear_chnl = true;
- }
- } else {
- /* DPC fired after host closed channel: clear input channel */
- clear_chnl = true;
- }
- if (clear_chnl) {
- /* Indicate to the DSP we have read the input */
- sm->input_full = 0;
- sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS);
- }
- if (notify_client) {
- /* Notify client with IO completion record */
- notify_chnl_complete(pchnl, chnl_packet_obj);
- }
-func_end:
- return;
-}
-
-/*
- * ======== input_msg ========
- * Copies messages from shared memory to the message queues.
- */
-static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
-{
- u32 num_msgs;
- u32 i;
- u8 *msg_input;
- struct msg_queue *msg_queue_obj;
- struct msg_frame *pmsg;
- struct msg_dspmsg msg;
- struct msg_ctrl *msg_ctr_obj;
- u32 input_empty;
- u32 addr;
-
- msg_ctr_obj = pio_mgr->msg_input_ctrl;
- /* Get the number of input messages to be read */
- input_empty = msg_ctr_obj->buf_empty;
- num_msgs = msg_ctr_obj->size;
- if (input_empty)
- return;
-
- msg_input = pio_mgr->msg_input;
- for (i = 0; i < num_msgs; i++) {
- /* Read the next message */
- addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.cmd);
- msg.msg.cmd =
- read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
- addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg1);
- msg.msg.arg1 =
- read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
- addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg2);
- msg.msg.arg2 =
- read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
- addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id);
- msg.msgq_id =
- read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr);
- msg_input += sizeof(struct msg_dspmsg);
-
- /* Determine which queue to put the message in */
- dev_dbg(bridge, "input msg: cmd=0x%x arg1=0x%x "
- "arg2=0x%x msgq_id=0x%x\n", msg.msg.cmd,
- msg.msg.arg1, msg.msg.arg2, msg.msgq_id);
- /*
- * Interrupt may occur before shared memory and message
- * input locations have been set up. If all nodes were
- * cleaned up, hmsg_mgr->max_msgs should be 0.
- */
- list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list,
- list_elem) {
- if (msg.msgq_id != msg_queue_obj->msgq_id)
- continue;
- /* Found it */
- if (msg.msg.cmd == RMS_EXITACK) {
- /*
- * Call the node exit notification.
- * The exit message does not get
- * queued.
- */
- (*hmsg_mgr->on_exit)(msg_queue_obj->arg,
- msg.msg.arg1);
- break;
- }
- /*
- * Not an exit acknowledgement, queue
- * the message.
- */
- if (list_empty(&msg_queue_obj->msg_free_list)) {
- /*
- * No free frame to copy the
- * message into.
- */
- pr_err("%s: no free msg frames,"
- " discarding msg\n",
- __func__);
- break;
- }
-
- pmsg = list_first_entry(&msg_queue_obj->msg_free_list,
- struct msg_frame, list_elem);
- list_del(&pmsg->list_elem);
- pmsg->msg_data = msg;
- list_add_tail(&pmsg->list_elem,
- &msg_queue_obj->msg_used_list);
- ntfy_notify(msg_queue_obj->ntfy_obj,
- DSP_NODEMESSAGEREADY);
- sync_set_event(msg_queue_obj->sync_event);
- }
- }
- /* Set the post SWI flag */
- if (num_msgs > 0) {
- /* Tell the DSP we've read the messages */
- msg_ctr_obj->buf_empty = true;
- msg_ctr_obj->post_swi = true;
- sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS);
- }
-}
-
-/*
- * ======== notify_chnl_complete ========
- * Purpose:
- * Signal the channel event, notifying the client that I/O has completed.
- */
-static void notify_chnl_complete(struct chnl_object *pchnl,
- struct chnl_irp *chnl_packet_obj)
-{
- bool signal_event;
-
- if (!pchnl || !pchnl->sync_event || !chnl_packet_obj)
- goto func_end;
-
- /*
- * Note: we signal the channel event only if the queue of IO
- * completions is empty. If it is not empty, the event is sure to be
- * signalled by the only IO completion list consumer:
- * bridge_chnl_get_ioc().
- */
- signal_event = list_empty(&pchnl->io_completions);
- /* Enqueue the IO completion info for the client */
- list_add_tail(&chnl_packet_obj->link, &pchnl->io_completions);
- pchnl->cio_cs++;
-
- if (pchnl->cio_cs > pchnl->chnl_packets)
- goto func_end;
- /* Signal the channel event (if not already set) that IO is complete */
- if (signal_event)
- sync_set_event(pchnl->sync_event);
-
- /* Notify that IO is complete */
- ntfy_notify(pchnl->ntfy_obj, DSP_STREAMIOCOMPLETION);
-func_end:
- return;
-}
-
-/*
- * ======== output_chnl ========
- * Purpose:
- * Dispatch a buffer on an output channel.
- */
-static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
- u8 io_mode)
-{
- struct chnl_mgr *chnl_mgr_obj;
- struct shm *sm;
- u32 chnl_id;
- struct chnl_irp *chnl_packet_obj;
- u32 dw_dsp_f_mask;
-
- chnl_mgr_obj = pio_mgr->chnl_mgr;
- sm = pio_mgr->shared_mem;
- /* Attempt to perform output */
- if (sm->output_full)
- goto func_end;
-
- if (pchnl && !((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY))
- goto func_end;
-
- /* Look to see if both a PC and DSP output channel are ready */
- dw_dsp_f_mask = sm->dsp_free_mask;
- chnl_id =
- find_ready_output(chnl_mgr_obj, pchnl,
- (chnl_mgr_obj->output_mask & dw_dsp_f_mask));
- if (chnl_id == OUTPUTNOTREADY)
- goto func_end;
-
- pchnl = chnl_mgr_obj->channels[chnl_id];
- if (!pchnl || list_empty(&pchnl->io_requests)) {
- /* Shouldn't get here */
- goto func_end;
- }
-
- if (!pchnl->cio_reqs)
- goto func_end;
-
- /* Get the I/O request, and attempt a transfer */
- chnl_packet_obj = list_first_entry(&pchnl->io_requests,
- struct chnl_irp, link);
- list_del(&chnl_packet_obj->link);
-
- pchnl->cio_reqs--;
-
- /* Record fact that no more I/O buffers available */
- if (list_empty(&pchnl->io_requests))
- chnl_mgr_obj->output_mask &= ~(1 << chnl_id);
-
- /* Transfer buffer to DSP side */
- chnl_packet_obj->byte_size = min(pio_mgr->sm_buf_size,
- chnl_packet_obj->byte_size);
- memcpy(pio_mgr->output, chnl_packet_obj->host_sys_buf,
- chnl_packet_obj->byte_size);
- pchnl->bytes_moved += chnl_packet_obj->byte_size;
- /* Write all 32 bits of arg */
- sm->arg = chnl_packet_obj->arg;
-#if _CHNL_WORDSIZE == 2
- /* Access can be different SM access word size (e.g. 16/32 bit words) */
- sm->output_id = (u16) chnl_id;
- sm->output_size = (u16) (chnl_packet_obj->byte_size +
- chnl_mgr_obj->word_size - 1) /
- (u16) chnl_mgr_obj->word_size;
-#else
- sm->output_id = chnl_id;
- sm->output_size = (chnl_packet_obj->byte_size +
- chnl_mgr_obj->word_size - 1) / chnl_mgr_obj->word_size;
-#endif
- sm->output_full = 1;
- /* Indicate to the DSP we have written the output */
- sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS);
- /* Notify client with IO completion record (keep EOS) */
- chnl_packet_obj->status &= CHNL_IOCSTATEOS;
- notify_chnl_complete(pchnl, chnl_packet_obj);
- /* Notify if stream is done. */
- if (chnl_packet_obj->status & CHNL_IOCSTATEOS)
- ntfy_notify(pchnl->ntfy_obj, DSP_STREAMDONE);
-
-func_end:
- return;
-}
-
-/*
- * ======== output_msg ========
- * Copies messages from the message queues to the shared memory.
- */
-static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr)
-{
- u32 num_msgs = 0;
- u32 i;
- struct msg_dspmsg *msg_output;
- struct msg_frame *pmsg;
- struct msg_ctrl *msg_ctr_obj;
- u32 val;
- u32 addr;
-
- msg_ctr_obj = pio_mgr->msg_output_ctrl;
-
- /* Check if output has been cleared */
- if (!msg_ctr_obj->buf_empty)
- return;
-
- num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ?
- hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending;
- msg_output = (struct msg_dspmsg *) pio_mgr->msg_output;
-
- /* Copy num_msgs messages into shared memory */
- for (i = 0; i < num_msgs; i++) {
- if (list_empty(&hmsg_mgr->msg_used_list))
- continue;
-
- pmsg = list_first_entry(&hmsg_mgr->msg_used_list,
- struct msg_frame, list_elem);
- list_del(&pmsg->list_elem);
-
- val = (pmsg->msg_data).msgq_id;
- addr = (u32) &msg_output->msgq_id;
- write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
-
- val = (pmsg->msg_data).msg.cmd;
- addr = (u32) &msg_output->msg.cmd;
- write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
-
- val = (pmsg->msg_data).msg.arg1;
- addr = (u32) &msg_output->msg.arg1;
- write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
-
- val = (pmsg->msg_data).msg.arg2;
- addr = (u32) &msg_output->msg.arg2;
- write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val);
-
- msg_output++;
- list_add_tail(&pmsg->list_elem, &hmsg_mgr->msg_free_list);
- sync_set_event(hmsg_mgr->sync_event);
- }
-
- if (num_msgs > 0) {
- hmsg_mgr->msgs_pending -= num_msgs;
-#if _CHNL_WORDSIZE == 2
- /*
- * Access can be different SM access word size
- * (e.g. 16/32 bit words)
- */
- msg_ctr_obj->size = (u16) num_msgs;
-#else
- msg_ctr_obj->size = num_msgs;
-#endif
- msg_ctr_obj->buf_empty = false;
- /* Set the post SWI flag */
- msg_ctr_obj->post_swi = true;
- /* Tell the DSP we have written the output. */
- sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS);
- }
-}
-
-/*
- * ======== register_shm_segs ========
- * purpose:
- * Registers GPP SM segment with CMM.
- */
-static int register_shm_segs(struct io_mgr *hio_mgr,
- struct cod_manager *cod_man,
- u32 dw_gpp_base_pa)
-{
- int status = 0;
- u32 ul_shm0_base = 0;
- u32 shm0_end = 0;
- u32 ul_shm0_rsrvd_start = 0;
- u32 ul_rsrvd_size = 0;
- u32 ul_gpp_phys;
- u32 ul_dsp_virt;
- u32 ul_shm_seg_id0 = 0;
- u32 dw_offset, dw_gpp_base_va, ul_dsp_size;
-
- /*
- * Read address and size info for first SM region.
- * Get start of 1st SM Heap region.
- */
- status =
- cod_get_sym_value(cod_man, SHM0_SHARED_BASE_SYM, &ul_shm0_base);
- if (ul_shm0_base == 0) {
- status = -EPERM;
- goto func_end;
- }
- /* Get end of 1st SM Heap region */
- if (!status) {
- /* Get start and length of message part of shared memory */
- status = cod_get_sym_value(cod_man, SHM0_SHARED_END_SYM,
- &shm0_end);
- if (shm0_end == 0) {
- status = -EPERM;
- goto func_end;
- }
- }
- /* Start of Gpp reserved region */
- if (!status) {
- /* Get start and length of message part of shared memory */
- status =
- cod_get_sym_value(cod_man, SHM0_SHARED_RESERVED_BASE_SYM,
- &ul_shm0_rsrvd_start);
- if (ul_shm0_rsrvd_start == 0) {
- status = -EPERM;
- goto func_end;
- }
- }
- /* Register with CMM */
- if (!status) {
- status = dev_get_cmm_mgr(hio_mgr->dev_obj, &hio_mgr->cmm_mgr);
- if (!status) {
- status = cmm_un_register_gppsm_seg(hio_mgr->cmm_mgr,
- CMM_ALLSEGMENTS);
- }
- }
- /* Register new SM region(s) */
- if (!status && (shm0_end - ul_shm0_base) > 0) {
- /* Calc size (bytes) of SM the GPP can alloc from */
- ul_rsrvd_size =
- (shm0_end - ul_shm0_rsrvd_start + 1) * hio_mgr->word_size;
- if (ul_rsrvd_size <= 0) {
- status = -EPERM;
- goto func_end;
- }
- /* Calc size of SM DSP can alloc from */
- ul_dsp_size =
- (ul_shm0_rsrvd_start - ul_shm0_base) * hio_mgr->word_size;
- if (ul_dsp_size <= 0) {
- status = -EPERM;
- goto func_end;
- }
- /* First TLB entry reserved for Bridge SM use. */
- ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys;
- /* Get size in bytes */
- ul_dsp_virt =
- hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt *
- hio_mgr->word_size;
- /*
- * Calc byte offset used to convert GPP phys <-> DSP byte
- * address.
- */
- if (dw_gpp_base_pa > ul_dsp_virt)
- dw_offset = dw_gpp_base_pa - ul_dsp_virt;
- else
- dw_offset = ul_dsp_virt - dw_gpp_base_pa;
-
- if (ul_shm0_rsrvd_start * hio_mgr->word_size < ul_dsp_virt) {
- status = -EPERM;
- goto func_end;
- }
- /*
- * Calc Gpp phys base of SM region.
- * This is actually uncached kernel virtual address.
- */
- dw_gpp_base_va =
- ul_gpp_phys + ul_shm0_rsrvd_start * hio_mgr->word_size -
- ul_dsp_virt;
- /*
- * Calc Gpp phys base of SM region.
- * This is the physical address.
- */
- dw_gpp_base_pa =
- dw_gpp_base_pa + ul_shm0_rsrvd_start * hio_mgr->word_size -
- ul_dsp_virt;
- /* Register SM Segment 0. */
- status =
- cmm_register_gppsm_seg(hio_mgr->cmm_mgr, dw_gpp_base_pa,
- ul_rsrvd_size, dw_offset,
- (dw_gpp_base_pa >
- ul_dsp_virt) ? CMM_ADDTODSPPA :
- CMM_SUBFROMDSPPA,
- (u32) (ul_shm0_base *
- hio_mgr->word_size),
- ul_dsp_size, &ul_shm_seg_id0,
- dw_gpp_base_va);
- /* First SM region is seg_id = 1 */
- if (ul_shm_seg_id0 != 1)
- status = -EPERM;
- }
-func_end:
- return status;
-}
-
-/* ZCPY IO routines. */
-/*
- * ======== IO_SHMcontrol ========
- * Sets the requested shm setting.
- */
-int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 i;
- struct dspbridge_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- switch (desc) {
- case SHM_CURROPP:
- /* Update the shared memory with requested OPP information */
- if (pargs != NULL)
- hio_mgr->shared_mem->opp_table_struct.curr_opp_pt =
- *(u32 *) pargs;
- else
- return -EPERM;
- break;
- case SHM_OPPINFO:
- /*
- * Update the shared memory with the voltage, frequency,
- * min and max frequency values for an OPP.
- */
- for (i = 0; i <= dsp_max_opps; i++) {
- hio_mgr->shared_mem->opp_table_struct.opp_point[i].
- voltage = vdd1_dsp_freq[i][0];
- dev_dbg(bridge, "OPP-shm: voltage: %d\n",
- vdd1_dsp_freq[i][0]);
- hio_mgr->shared_mem->opp_table_struct.
- opp_point[i].frequency = vdd1_dsp_freq[i][1];
- dev_dbg(bridge, "OPP-shm: frequency: %d\n",
- vdd1_dsp_freq[i][1]);
- hio_mgr->shared_mem->opp_table_struct.opp_point[i].
- min_freq = vdd1_dsp_freq[i][2];
- dev_dbg(bridge, "OPP-shm: min freq: %d\n",
- vdd1_dsp_freq[i][2]);
- hio_mgr->shared_mem->opp_table_struct.opp_point[i].
- max_freq = vdd1_dsp_freq[i][3];
- dev_dbg(bridge, "OPP-shm: max freq: %d\n",
- vdd1_dsp_freq[i][3]);
- }
- hio_mgr->shared_mem->opp_table_struct.num_opp_pts =
- dsp_max_opps;
- dev_dbg(bridge, "OPP-shm: max OPP number: %d\n", dsp_max_opps);
- /* Update the current OPP number */
- if (pdata->dsp_get_opp)
- i = (*pdata->dsp_get_opp) ();
- hio_mgr->shared_mem->opp_table_struct.curr_opp_pt = i;
- dev_dbg(bridge, "OPP-shm: value programmed = %d\n", i);
- break;
- case SHM_GETOPP:
- /* Get the OPP that DSP has requested */
- *(u32 *) pargs = hio_mgr->shared_mem->opp_request.rqst_opp_pt;
- break;
- default:
- break;
- }
-#endif
- return 0;
-}
-
-/*
- * ======== bridge_io_get_proc_load ========
- * Gets the Processor's Load information
- */
-int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
- struct dsp_procloadstat *proc_lstat)
-{
- if (!hio_mgr->shared_mem)
- return -EFAULT;
-
- proc_lstat->curr_load =
- hio_mgr->shared_mem->load_mon_info.curr_dsp_load;
- proc_lstat->predicted_load =
- hio_mgr->shared_mem->load_mon_info.pred_dsp_load;
- proc_lstat->curr_dsp_freq =
- hio_mgr->shared_mem->load_mon_info.curr_dsp_freq;
- proc_lstat->predicted_freq =
- hio_mgr->shared_mem->load_mon_info.pred_dsp_freq;
-
- dev_dbg(bridge, "Curr Load = %d, Pred Load = %d, Curr Freq = %d, "
- "Pred Freq = %d\n", proc_lstat->curr_load,
- proc_lstat->predicted_load, proc_lstat->curr_dsp_freq,
- proc_lstat->predicted_freq);
- return 0;
-}
-
-
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
-void print_dsp_debug_trace(struct io_mgr *hio_mgr)
-{
- u32 ul_new_message_length = 0, ul_gpp_cur_pointer;
-
- while (true) {
- /* Get the DSP current pointer */
- ul_gpp_cur_pointer =
- *(u32 *) (hio_mgr->trace_buffer_current);
- ul_gpp_cur_pointer =
- hio_mgr->gpp_va + (ul_gpp_cur_pointer -
- hio_mgr->dsp_va);
-
- /* No new debug messages available yet */
- if (ul_gpp_cur_pointer == hio_mgr->gpp_read_pointer) {
- break;
- } else if (ul_gpp_cur_pointer > hio_mgr->gpp_read_pointer) {
- /* Continuous data */
- ul_new_message_length =
- ul_gpp_cur_pointer - hio_mgr->gpp_read_pointer;
-
- memcpy(hio_mgr->msg,
- (char *)hio_mgr->gpp_read_pointer,
- ul_new_message_length);
- hio_mgr->msg[ul_new_message_length] = '\0';
- /*
- * Advance the GPP trace pointer to DSP current
- * pointer.
- */
- hio_mgr->gpp_read_pointer += ul_new_message_length;
- /* Print the trace messages */
- pr_info("DSPTrace: %s\n", hio_mgr->msg);
- } else if (ul_gpp_cur_pointer < hio_mgr->gpp_read_pointer) {
- /* Handle trace buffer wraparound */
- memcpy(hio_mgr->msg,
- (char *)hio_mgr->gpp_read_pointer,
- hio_mgr->trace_buffer_end -
- hio_mgr->gpp_read_pointer);
- ul_new_message_length =
- ul_gpp_cur_pointer - hio_mgr->trace_buffer_begin;
- memcpy(&hio_mgr->msg[hio_mgr->trace_buffer_end -
- hio_mgr->gpp_read_pointer],
- (char *)hio_mgr->trace_buffer_begin,
- ul_new_message_length);
- hio_mgr->msg[hio_mgr->trace_buffer_end -
- hio_mgr->gpp_read_pointer +
- ul_new_message_length] = '\0';
- /*
- * Advance the GPP trace pointer to DSP current
- * pointer.
- */
- hio_mgr->gpp_read_pointer =
- hio_mgr->trace_buffer_begin +
- ul_new_message_length;
- /* Print the trace messages */
- pr_info("DSPTrace: %s\n", hio_mgr->msg);
- }
- }
-}
-#endif
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/*
- * ======== print_dsp_trace_buffer ========
- * Prints the trace buffer returned from the DSP (if DBG_Trace is enabled).
- * Parameters:
- * hdeh_mgr: Handle to DEH manager object
- * number of extra carriage returns to generate.
- * Returns:
- * 0: Success.
- * -ENOMEM: Unable to allocate memory.
- * Requires:
- * hdeh_mgr muse be valid. Checked in bridge_deh_notify.
- */
-int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context)
-{
- int status = 0;
- struct cod_manager *cod_mgr;
- u32 ul_trace_end;
- u32 ul_trace_begin;
- u32 trace_cur_pos;
- u32 ul_num_bytes = 0;
- u32 ul_num_words = 0;
- u32 ul_word_size = 2;
- char *psz_buf;
- char *str_beg;
- char *trace_end;
- char *buf_end;
- char *new_line;
-
- struct bridge_dev_context *pbridge_context = hbridge_context;
- struct bridge_drv_interface *intf_fxns;
- struct dev_object *dev_obj = (struct dev_object *)
- pbridge_context->dev_obj;
-
- status = dev_get_cod_mgr(dev_obj, &cod_mgr);
-
- if (cod_mgr) {
- /* Look for SYS_PUTCBEG/SYS_PUTCEND */
- status =
- cod_get_sym_value(cod_mgr, COD_TRACEBEG, &ul_trace_begin);
- } else {
- status = -EFAULT;
- }
- if (!status)
- status =
- cod_get_sym_value(cod_mgr, COD_TRACEEND, &ul_trace_end);
-
- if (!status)
- /* trace_cur_pos will hold the address of a DSP pointer */
- status = cod_get_sym_value(cod_mgr, COD_TRACECURPOS,
- &trace_cur_pos);
-
- if (status)
- goto func_end;
-
- ul_num_bytes = (ul_trace_end - ul_trace_begin);
-
- ul_num_words = ul_num_bytes * ul_word_size;
- status = dev_get_intf_fxns(dev_obj, &intf_fxns);
-
- if (status)
- goto func_end;
-
- psz_buf = kzalloc(ul_num_bytes + 2, GFP_ATOMIC);
- if (psz_buf != NULL) {
- /* Read trace buffer data */
- status = (*intf_fxns->brd_read)(pbridge_context,
- (u8 *)psz_buf, (u32)ul_trace_begin,
- ul_num_bytes, 0);
-
- if (status)
- goto func_end;
-
- /* Pack and do newline conversion */
- pr_debug("PrintDspTraceBuffer: "
- "before pack and unpack.\n");
- pr_debug("%s: DSP Trace Buffer Begin:\n"
- "=======================\n%s\n",
- __func__, psz_buf);
-
- /* Read the value at the DSP address in trace_cur_pos. */
- status = (*intf_fxns->brd_read)(pbridge_context,
- (u8 *)&trace_cur_pos, (u32)trace_cur_pos,
- 4, 0);
- if (status)
- goto func_end;
- /* Pack and do newline conversion */
- pr_info("DSP Trace Buffer Begin:\n"
- "=======================\n%s\n",
- psz_buf);
-
-
- /* convert to offset */
- trace_cur_pos = trace_cur_pos - ul_trace_begin;
-
- if (ul_num_bytes) {
- /*
- * The buffer is not full, find the end of the
- * data -- buf_end will be >= pszBuf after
- * while.
- */
- buf_end = &psz_buf[ul_num_bytes+1];
- /* DSP print position */
- trace_end = &psz_buf[trace_cur_pos];
-
- /*
- * Search buffer for a new_line and replace it
- * with '\0', then print as string.
- * Continue until end of buffer is reached.
- */
- str_beg = trace_end;
- ul_num_bytes = buf_end - str_beg;
-
- while (str_beg < buf_end) {
- new_line = strnchr(str_beg, ul_num_bytes,
- '\n');
- if (new_line && new_line < buf_end) {
- *new_line = 0;
- pr_debug("%s\n", str_beg);
- str_beg = ++new_line;
- ul_num_bytes = buf_end - str_beg;
- } else {
- /*
- * Assume buffer empty if it contains
- * a zero
- */
- if (*str_beg != '\0') {
- str_beg[ul_num_bytes] = 0;
- pr_debug("%s\n", str_beg);
- }
- str_beg = buf_end;
- ul_num_bytes = 0;
- }
- }
- /*
- * Search buffer for a nNewLine and replace it
- * with '\0', then print as string.
- * Continue until buffer is exhausted.
- */
- str_beg = psz_buf;
- ul_num_bytes = trace_end - str_beg;
-
- while (str_beg < trace_end) {
- new_line = strnchr(str_beg, ul_num_bytes, '\n');
- if (new_line != NULL && new_line < trace_end) {
- *new_line = 0;
- pr_debug("%s\n", str_beg);
- str_beg = ++new_line;
- ul_num_bytes = trace_end - str_beg;
- } else {
- /*
- * Assume buffer empty if it contains
- * a zero
- */
- if (*str_beg != '\0') {
- str_beg[ul_num_bytes] = 0;
- pr_debug("%s\n", str_beg);
- }
- str_beg = trace_end;
- ul_num_bytes = 0;
- }
- }
- }
- pr_info("\n=======================\n"
- "DSP Trace Buffer End:\n");
- kfree(psz_buf);
- } else {
- status = -ENOMEM;
- }
-func_end:
- if (status)
- dev_dbg(bridge, "%s Failed, status 0x%x\n", __func__, status);
- return status;
-}
-
-/**
- * dump_dsp_stack() - This function dumps the data on the DSP stack.
- * @bridge_context: Bridge driver's device context pointer.
- *
- */
-int dump_dsp_stack(struct bridge_dev_context *bridge_context)
-{
- int status = 0;
- struct cod_manager *code_mgr;
- struct node_mgr *node_mgr;
- u32 trace_begin;
- char name[256];
- struct {
- u32 head[2];
- u32 size;
- } mmu_fault_dbg_info;
- u32 *buffer;
- u32 *buffer_beg;
- u32 *buffer_end;
- u32 exc_type;
- u32 dyn_ext_base;
- u32 i;
- u32 offset_output;
- u32 total_size;
- u32 poll_cnt;
- const char *dsp_regs[] = {"EFR", "IERR", "ITSR", "NTSR",
- "IRP", "NRP", "AMR", "SSR",
- "ILC", "RILC", "IER", "CSR"};
- const char *exec_ctxt[] = {"Task", "SWI", "HWI", "Unknown"};
- struct bridge_drv_interface *intf_fxns;
- struct dev_object *dev_object = bridge_context->dev_obj;
-
- status = dev_get_cod_mgr(dev_object, &code_mgr);
- if (!code_mgr) {
- pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
- status = -EFAULT;
- }
-
- if (!status) {
- status = dev_get_node_manager(dev_object, &node_mgr);
- if (!node_mgr) {
- pr_debug("%s: Failed on dev_get_node_manager.\n",
- __func__);
- status = -EFAULT;
- }
- }
-
- if (!status) {
- /* Look for SYS_PUTCBEG/SYS_PUTCEND: */
- status =
- cod_get_sym_value(code_mgr, COD_TRACEBEG, &trace_begin);
- pr_debug("%s: trace_begin Value 0x%x\n",
- __func__, trace_begin);
- if (status)
- pr_debug("%s: Failed on cod_get_sym_value.\n",
- __func__);
- }
- if (!status)
- status = dev_get_intf_fxns(dev_object, &intf_fxns);
- /*
- * Check for the "magic number" in the trace buffer. If it has
- * yet to appear then poll the trace buffer to wait for it. Its
- * appearance signals that the DSP has finished dumping its state.
- */
- mmu_fault_dbg_info.head[0] = 0;
- mmu_fault_dbg_info.head[1] = 0;
- if (!status) {
- poll_cnt = 0;
- while ((mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 ||
- mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) &&
- poll_cnt < POLL_MAX) {
-
- /* Read DSP dump size from the DSP trace buffer... */
- status = (*intf_fxns->brd_read)(bridge_context,
- (u8 *)&mmu_fault_dbg_info, (u32)trace_begin,
- sizeof(mmu_fault_dbg_info), 0);
-
- if (status)
- break;
-
- poll_cnt++;
- }
-
- if (mmu_fault_dbg_info.head[0] != MMU_FAULT_HEAD1 &&
- mmu_fault_dbg_info.head[1] != MMU_FAULT_HEAD2) {
- status = -ETIME;
- pr_err("%s:No DSP MMU-Fault information available.\n",
- __func__);
- }
- }
-
- if (!status) {
- total_size = mmu_fault_dbg_info.size;
- /* Limit the size in case DSP went crazy */
- if (total_size > MAX_MMU_DBGBUFF)
- total_size = MAX_MMU_DBGBUFF;
-
- buffer = kzalloc(total_size, GFP_ATOMIC);
- if (!buffer) {
- status = -ENOMEM;
- pr_debug("%s: Failed to "
- "allocate stack dump buffer.\n", __func__);
- goto func_end;
- }
-
- buffer_beg = buffer;
- buffer_end = buffer + total_size / 4;
-
- /* Read bytes from the DSP trace buffer... */
- status = (*intf_fxns->brd_read)(bridge_context,
- (u8 *)buffer, (u32)trace_begin,
- total_size, 0);
- if (status) {
- pr_debug("%s: Failed to Read Trace Buffer.\n",
- __func__);
- goto func_end;
- }
-
- pr_err("\nAproximate Crash Position:\n"
- "--------------------------\n");
-
- exc_type = buffer[3];
- if (!exc_type)
- i = buffer[79]; /* IRP */
- else
- i = buffer[80]; /* NRP */
-
- status =
- cod_get_sym_value(code_mgr, DYNEXTBASE, &dyn_ext_base);
- if (status) {
- status = -EFAULT;
- goto func_end;
- }
-
- if ((i > dyn_ext_base) && (node_find_addr(node_mgr, i,
- 0x1000, &offset_output, name) == 0))
- pr_err("0x%-8x [\"%s\" + 0x%x]\n", i, name,
- i - offset_output);
- else
- pr_err("0x%-8x [Unable to match to a symbol.]\n", i);
-
- buffer += 4;
-
- pr_err("\nExecution Info:\n"
- "---------------\n");
-
- if (*buffer < ARRAY_SIZE(exec_ctxt)) {
- pr_err("Execution context \t%s\n",
- exec_ctxt[*buffer++]);
- } else {
- pr_err("Execution context corrupt\n");
- kfree(buffer_beg);
- return -EFAULT;
- }
- pr_err("Task Handle\t\t0x%x\n", *buffer++);
- pr_err("Stack Pointer\t\t0x%x\n", *buffer++);
- pr_err("Stack Top\t\t0x%x\n", *buffer++);
- pr_err("Stack Bottom\t\t0x%x\n", *buffer++);
- pr_err("Stack Size\t\t0x%x\n", *buffer++);
- pr_err("Stack Size In Use\t0x%x\n", *buffer++);
-
- pr_err("\nCPU Registers\n"
- "---------------\n");
-
- for (i = 0; i < 32; i++) {
- if (i == 4 || i == 6 || i == 8)
- pr_err("A%d 0x%-8x [Function Argument %d]\n",
- i, *buffer++, i-3);
- else if (i == 15)
- pr_err("A15 0x%-8x [Frame Pointer]\n",
- *buffer++);
- else
- pr_err("A%d 0x%x\n", i, *buffer++);
- }
-
- pr_err("\nB0 0x%x\n", *buffer++);
- pr_err("B1 0x%x\n", *buffer++);
- pr_err("B2 0x%x\n", *buffer++);
-
- if ((*buffer > dyn_ext_base) && (node_find_addr(node_mgr,
- *buffer, 0x1000, &offset_output, name) == 0))
-
- pr_err("B3 0x%-8x [Function Return Pointer:"
- " \"%s\" + 0x%x]\n", *buffer, name,
- *buffer - offset_output);
- else
- pr_err("B3 0x%-8x [Function Return Pointer:"
- "Unable to match to a symbol.]\n", *buffer);
-
- buffer++;
-
- for (i = 4; i < 32; i++) {
- if (i == 4 || i == 6 || i == 8)
- pr_err("B%d 0x%-8x [Function Argument %d]\n",
- i, *buffer++, i-2);
- else if (i == 14)
- pr_err("B14 0x%-8x [Data Page Pointer]\n",
- *buffer++);
- else
- pr_err("B%d 0x%x\n", i, *buffer++);
- }
-
- pr_err("\n");
-
- for (i = 0; i < ARRAY_SIZE(dsp_regs); i++)
- pr_err("%s 0x%x\n", dsp_regs[i], *buffer++);
-
- pr_err("\nStack:\n"
- "------\n");
-
- for (i = 0; buffer < buffer_end; i++, buffer++) {
- if ((*buffer > dyn_ext_base) && (
- node_find_addr(node_mgr, *buffer , 0x600,
- &offset_output, name) == 0))
- pr_err("[%d] 0x%-8x [\"%s\" + 0x%x]\n",
- i, *buffer, name,
- *buffer - offset_output);
- else
- pr_err("[%d] 0x%x\n", i, *buffer);
- }
- kfree(buffer_beg);
- }
-func_end:
- return status;
-}
-
-/**
- * dump_dl_modules() - This functions dumps the _DLModules loaded in DSP side
- * @bridge_context: Bridge driver's device context pointer.
- *
- */
-void dump_dl_modules(struct bridge_dev_context *bridge_context)
-{
- struct cod_manager *code_mgr;
- struct bridge_drv_interface *intf_fxns;
- struct bridge_dev_context *bridge_ctxt = bridge_context;
- struct dev_object *dev_object = bridge_ctxt->dev_obj;
- struct modules_header modules_hdr;
- struct dll_module *module_struct = NULL;
- u32 module_dsp_addr;
- u32 module_size;
- u32 module_struct_size = 0;
- u32 sect_ndx;
- char *sect_str;
- int status = 0;
-
- status = dev_get_intf_fxns(dev_object, &intf_fxns);
- if (status) {
- pr_debug("%s: Failed on dev_get_intf_fxns.\n", __func__);
- goto func_end;
- }
-
- status = dev_get_cod_mgr(dev_object, &code_mgr);
- if (!code_mgr) {
- pr_debug("%s: Failed on dev_get_cod_mgr.\n", __func__);
- status = -EFAULT;
- goto func_end;
- }
-
- /* Lookup the address of the modules_header structure */
- status = cod_get_sym_value(code_mgr, "_DLModules", &module_dsp_addr);
- if (status) {
- pr_debug("%s: Failed on cod_get_sym_value for _DLModules.\n",
- __func__);
- goto func_end;
- }
-
- pr_debug("%s: _DLModules at 0x%x\n", __func__, module_dsp_addr);
-
- /* Copy the modules_header structure from DSP memory. */
- status = (*intf_fxns->brd_read)(bridge_context, (u8 *) &modules_hdr,
- (u32) module_dsp_addr, sizeof(modules_hdr), 0);
-
- if (status) {
- pr_debug("%s: Failed failed to read modules header.\n",
- __func__);
- goto func_end;
- }
-
- module_dsp_addr = modules_hdr.first_module;
- module_size = modules_hdr.first_module_size;
-
- pr_debug("%s: dll_module_header 0x%x %d\n", __func__, module_dsp_addr,
- module_size);
-
- pr_err("\nDynamically Loaded Modules:\n"
- "---------------------------\n");
-
- /* For each dll_module structure in the list... */
- while (module_size) {
- /*
- * Allocate/re-allocate memory to hold the dll_module
- * structure. The memory is re-allocated only if the existing
- * allocation is too small.
- */
- if (module_size > module_struct_size) {
- kfree(module_struct);
- module_struct = kzalloc(module_size+128, GFP_ATOMIC);
- module_struct_size = module_size+128;
- pr_debug("%s: allocated module struct %p %d\n",
- __func__, module_struct, module_struct_size);
- if (!module_struct)
- goto func_end;
- }
- /* Copy the dll_module structure from DSP memory */
- status = (*intf_fxns->brd_read)(bridge_context,
- (u8 *)module_struct, module_dsp_addr, module_size, 0);
-
- if (status) {
- pr_debug(
- "%s: Failed to read dll_module struct for 0x%x.\n",
- __func__, module_dsp_addr);
- break;
- }
-
- /* Update info regarding the _next_ module in the list. */
- module_dsp_addr = module_struct->next_module;
- module_size = module_struct->next_module_size;
-
- pr_debug("%s: next module 0x%x %d, this module num sects %d\n",
- __func__, module_dsp_addr, module_size,
- module_struct->num_sects);
-
- /*
- * The section name strings start immediately following
- * the array of dll_sect structures.
- */
- sect_str = (char *) &module_struct->
- sects[module_struct->num_sects];
- pr_err("%s\n", sect_str);
-
- /*
- * Advance to the first section name string.
- * Each string follows the one before.
- */
- sect_str += strlen(sect_str) + 1;
-
- /* Access each dll_sect structure and its name string. */
- for (sect_ndx = 0;
- sect_ndx < module_struct->num_sects; sect_ndx++) {
- pr_err(" Section: 0x%x ",
- module_struct->sects[sect_ndx].sect_load_adr);
-
- if (((u32) sect_str - (u32) module_struct) <
- module_struct_size) {
- pr_err("%s\n", sect_str);
- /* Each string follows the one before. */
- sect_str += strlen(sect_str)+1;
- } else {
- pr_err("<string error>\n");
- pr_debug("%s: section name sting address "
- "is invalid %p\n", __func__, sect_str);
- }
- }
- }
-func_end:
- kfree(module_struct);
-}
-#endif
diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c
deleted file mode 100644
index 7b517eb827fe..000000000000
--- a/drivers/staging/tidspbridge/core/msg_sm.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * msg_sm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implements upper edge functions for Bridge message module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/io_sm.h>
-
-/* ----------------------------------- This */
-#include <_msg_sm.h>
-#include <dspbridge/dspmsg.h>
-
-/* ----------------------------------- Function Prototypes */
-static int add_new_msg(struct list_head *msg_list);
-static void delete_msg_mgr(struct msg_mgr *hmsg_mgr);
-static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp);
-static void free_msg_list(struct list_head *msg_list);
-
-/*
- * ======== bridge_msg_create ========
- * Create an object to manage message queues. Only one of these objects
- * can exist per device object.
- */
-int bridge_msg_create(struct msg_mgr **msg_man,
- struct dev_object *hdev_obj,
- msg_onexit msg_callback)
-{
- struct msg_mgr *msg_mgr_obj;
- struct io_mgr *hio_mgr;
- int status = 0;
-
- if (!msg_man || !msg_callback || !hdev_obj)
- return -EFAULT;
-
- dev_get_io_mgr(hdev_obj, &hio_mgr);
- if (!hio_mgr)
- return -EFAULT;
-
- *msg_man = NULL;
- /* Allocate msg_ctrl manager object */
- msg_mgr_obj = kzalloc(sizeof(struct msg_mgr), GFP_KERNEL);
- if (!msg_mgr_obj)
- return -ENOMEM;
-
- msg_mgr_obj->on_exit = msg_callback;
- msg_mgr_obj->iomgr = hio_mgr;
- /* List of MSG_QUEUEs */
- INIT_LIST_HEAD(&msg_mgr_obj->queue_list);
- /*
- * Queues of message frames for messages to the DSP. Message
- * frames will only be added to the free queue when a
- * msg_queue object is created.
- */
- INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list);
- INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list);
- spin_lock_init(&msg_mgr_obj->msg_mgr_lock);
-
- /*
- * Create an event to be used by bridge_msg_put() in waiting
- * for an available free frame from the message manager.
- */
- msg_mgr_obj->sync_event =
- kzalloc(sizeof(struct sync_object), GFP_KERNEL);
- if (!msg_mgr_obj->sync_event) {
- kfree(msg_mgr_obj);
- return -ENOMEM;
- }
- sync_init_event(msg_mgr_obj->sync_event);
-
- *msg_man = msg_mgr_obj;
-
- return status;
-}
-
-/*
- * ======== bridge_msg_create_queue ========
- * Create a msg_queue for sending/receiving messages to/from a node
- * on the DSP.
- */
-int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue **msgq,
- u32 msgq_id, u32 max_msgs, void *arg)
-{
- u32 i;
- u32 num_allocated = 0;
- struct msg_queue *msg_q;
- int status = 0;
-
- if (!hmsg_mgr || msgq == NULL)
- return -EFAULT;
-
- *msgq = NULL;
- /* Allocate msg_queue object */
- msg_q = kzalloc(sizeof(struct msg_queue), GFP_KERNEL);
- if (!msg_q)
- return -ENOMEM;
-
- msg_q->max_msgs = max_msgs;
- msg_q->msg_mgr = hmsg_mgr;
- msg_q->arg = arg; /* Node handle */
- msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */
- /* Queues of Message frames for messages from the DSP */
- INIT_LIST_HEAD(&msg_q->msg_free_list);
- INIT_LIST_HEAD(&msg_q->msg_used_list);
-
- /* Create event that will be signalled when a message from
- * the DSP is available. */
- msg_q->sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
- if (!msg_q->sync_event) {
- status = -ENOMEM;
- goto out_err;
-
- }
- sync_init_event(msg_q->sync_event);
-
- /* Create a notification list for message ready notification. */
- msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
- if (!msg_q->ntfy_obj) {
- status = -ENOMEM;
- goto out_err;
- }
- ntfy_init(msg_q->ntfy_obj);
-
- /* Create events that will be used to synchronize cleanup
- * when the object is deleted. sync_done will be set to
- * unblock threads in MSG_Put() or MSG_Get(). sync_done_ack
- * will be set by the unblocked thread to signal that it
- * is unblocked and will no longer reference the object. */
- msg_q->sync_done = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
- if (!msg_q->sync_done) {
- status = -ENOMEM;
- goto out_err;
- }
- sync_init_event(msg_q->sync_done);
-
- msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object), GFP_KERNEL);
- if (!msg_q->sync_done_ack) {
- status = -ENOMEM;
- goto out_err;
- }
- sync_init_event(msg_q->sync_done_ack);
-
- /* Enter critical section */
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
- /* Initialize message frames and put in appropriate queues */
- for (i = 0; i < max_msgs && !status; i++) {
- status = add_new_msg(&hmsg_mgr->msg_free_list);
- if (!status) {
- num_allocated++;
- status = add_new_msg(&msg_q->msg_free_list);
- }
- }
- if (status) {
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- goto out_err;
- }
-
- list_add_tail(&msg_q->list_elem, &hmsg_mgr->queue_list);
- *msgq = msg_q;
- /* Signal that free frames are now available */
- if (!list_empty(&hmsg_mgr->msg_free_list))
- sync_set_event(hmsg_mgr->sync_event);
-
- /* Exit critical section */
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-
- return 0;
-out_err:
- delete_msg_queue(msg_q, num_allocated);
- return status;
-}
-
-/*
- * ======== bridge_msg_delete ========
- * Delete a msg_ctrl manager allocated in bridge_msg_create().
- */
-void bridge_msg_delete(struct msg_mgr *hmsg_mgr)
-{
- delete_msg_mgr(hmsg_mgr);
-}
-
-/*
- * ======== bridge_msg_delete_queue ========
- * Delete a msg_ctrl queue allocated in bridge_msg_create_queue.
- */
-void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj)
-{
- struct msg_mgr *hmsg_mgr;
- u32 io_msg_pend;
-
- if (!msg_queue_obj || !msg_queue_obj->msg_mgr)
- return;
-
- hmsg_mgr = msg_queue_obj->msg_mgr;
- msg_queue_obj->done = true;
- /* Unblock all threads blocked in MSG_Get() or MSG_Put(). */
- io_msg_pend = msg_queue_obj->io_msg_pend;
- while (io_msg_pend) {
- /* Unblock thread */
- sync_set_event(msg_queue_obj->sync_done);
- /* Wait for acknowledgement */
- sync_wait_on_event(msg_queue_obj->sync_done_ack, SYNC_INFINITE);
- io_msg_pend = msg_queue_obj->io_msg_pend;
- }
- /* Remove message queue from hmsg_mgr->queue_list */
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
- list_del(&msg_queue_obj->list_elem);
- /* Free the message queue object */
- delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs);
- if (list_empty(&hmsg_mgr->msg_free_list))
- sync_reset_event(hmsg_mgr->sync_event);
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-}
-
-/*
- * ======== bridge_msg_get ========
- * Get a message from a msg_ctrl queue.
- */
-int bridge_msg_get(struct msg_queue *msg_queue_obj,
- struct dsp_msg *pmsg, u32 utimeout)
-{
- struct msg_frame *msg_frame_obj;
- struct msg_mgr *hmsg_mgr;
- struct sync_object *syncs[2];
- u32 index;
- int status = 0;
-
- if (!msg_queue_obj || pmsg == NULL)
- return -ENOMEM;
-
- hmsg_mgr = msg_queue_obj->msg_mgr;
-
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
- /* If a message is already there, get it */
- if (!list_empty(&msg_queue_obj->msg_used_list)) {
- msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
- struct msg_frame, list_elem);
- list_del(&msg_frame_obj->list_elem);
- *pmsg = msg_frame_obj->msg_data.msg;
- list_add_tail(&msg_frame_obj->list_elem,
- &msg_queue_obj->msg_free_list);
- if (list_empty(&msg_queue_obj->msg_used_list))
- sync_reset_event(msg_queue_obj->sync_event);
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- return 0;
- }
-
- if (msg_queue_obj->done) {
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- return -EPERM;
- }
- msg_queue_obj->io_msg_pend++;
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-
- /*
- * Wait til message is available, timeout, or done. We don't
- * have to schedule the DPC, since the DSP will send messages
- * when they are available.
- */
- syncs[0] = msg_queue_obj->sync_event;
- syncs[1] = msg_queue_obj->sync_done;
- status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index);
-
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
- if (msg_queue_obj->done) {
- msg_queue_obj->io_msg_pend--;
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- /*
- * Signal that we're not going to access msg_queue_obj
- * anymore, so it can be deleted.
- */
- sync_set_event(msg_queue_obj->sync_done_ack);
- return -EPERM;
- }
- if (!status && !list_empty(&msg_queue_obj->msg_used_list)) {
- /* Get msg from used list */
- msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list,
- struct msg_frame, list_elem);
- list_del(&msg_frame_obj->list_elem);
- /* Copy message into pmsg and put frame on the free list */
- *pmsg = msg_frame_obj->msg_data.msg;
- list_add_tail(&msg_frame_obj->list_elem,
- &msg_queue_obj->msg_free_list);
- }
- msg_queue_obj->io_msg_pend--;
- /* Reset the event if there are still queued messages */
- if (!list_empty(&msg_queue_obj->msg_used_list))
- sync_set_event(msg_queue_obj->sync_event);
-
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-
- return status;
-}
-
-/*
- * ======== bridge_msg_put ========
- * Put a message onto a msg_ctrl queue.
- */
-int bridge_msg_put(struct msg_queue *msg_queue_obj,
- const struct dsp_msg *pmsg, u32 utimeout)
-{
- struct msg_frame *msg_frame_obj;
- struct msg_mgr *hmsg_mgr;
- struct sync_object *syncs[2];
- u32 index;
- int status;
-
- if (!msg_queue_obj || !pmsg || !msg_queue_obj->msg_mgr)
- return -EFAULT;
-
- hmsg_mgr = msg_queue_obj->msg_mgr;
-
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
-
- /* If a message frame is available, use it */
- if (!list_empty(&hmsg_mgr->msg_free_list)) {
- msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
- struct msg_frame, list_elem);
- list_del(&msg_frame_obj->list_elem);
- msg_frame_obj->msg_data.msg = *pmsg;
- msg_frame_obj->msg_data.msgq_id =
- msg_queue_obj->msgq_id;
- list_add_tail(&msg_frame_obj->list_elem,
- &hmsg_mgr->msg_used_list);
- hmsg_mgr->msgs_pending++;
-
- if (list_empty(&hmsg_mgr->msg_free_list))
- sync_reset_event(hmsg_mgr->sync_event);
-
- /* Release critical section before scheduling DPC */
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- /* Schedule a DPC, to do the actual data transfer: */
- iosm_schedule(hmsg_mgr->iomgr);
- return 0;
- }
-
- if (msg_queue_obj->done) {
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- return -EPERM;
- }
- msg_queue_obj->io_msg_pend++;
-
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-
- /* Wait til a free message frame is available, timeout, or done */
- syncs[0] = hmsg_mgr->sync_event;
- syncs[1] = msg_queue_obj->sync_done;
- status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index);
- if (status)
- return status;
-
- /* Enter critical section */
- spin_lock_bh(&hmsg_mgr->msg_mgr_lock);
- if (msg_queue_obj->done) {
- msg_queue_obj->io_msg_pend--;
- /* Exit critical section */
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- /*
- * Signal that we're not going to access msg_queue_obj
- * anymore, so it can be deleted.
- */
- sync_set_event(msg_queue_obj->sync_done_ack);
- return -EPERM;
- }
-
- if (list_empty(&hmsg_mgr->msg_free_list)) {
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
- return -EFAULT;
- }
-
- /* Get msg from free list */
- msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list,
- struct msg_frame, list_elem);
- /*
- * Copy message into pmsg and put frame on the
- * used list.
- */
- list_del(&msg_frame_obj->list_elem);
- msg_frame_obj->msg_data.msg = *pmsg;
- msg_frame_obj->msg_data.msgq_id = msg_queue_obj->msgq_id;
- list_add_tail(&msg_frame_obj->list_elem, &hmsg_mgr->msg_used_list);
- hmsg_mgr->msgs_pending++;
- /*
- * Schedule a DPC, to do the actual
- * data transfer.
- */
- iosm_schedule(hmsg_mgr->iomgr);
-
- msg_queue_obj->io_msg_pend--;
- /* Reset event if there are still frames available */
- if (!list_empty(&hmsg_mgr->msg_free_list))
- sync_set_event(hmsg_mgr->sync_event);
-
- /* Exit critical section */
- spin_unlock_bh(&hmsg_mgr->msg_mgr_lock);
-
- return 0;
-}
-
-/*
- * ======== bridge_msg_register_notify ========
- */
-int bridge_msg_register_notify(struct msg_queue *msg_queue_obj,
- u32 event_mask, u32 notify_type,
- struct dsp_notification *hnotification)
-{
- int status = 0;
-
- if (!msg_queue_obj || !hnotification) {
- status = -ENOMEM;
- goto func_end;
- }
-
- if (!(event_mask == DSP_NODEMESSAGEREADY || event_mask == 0)) {
- status = -EPERM;
- goto func_end;
- }
-
- if (notify_type != DSP_SIGNALEVENT) {
- status = -EBADR;
- goto func_end;
- }
-
- if (event_mask)
- status = ntfy_register(msg_queue_obj->ntfy_obj, hnotification,
- event_mask, notify_type);
- else
- status = ntfy_unregister(msg_queue_obj->ntfy_obj,
- hnotification);
-
- if (status == -EINVAL) {
- /* Not registered. Ok, since we couldn't have known. Node
- * notifications are split between node state change handled
- * by NODE, and message ready handled by msg_ctrl. */
- status = 0;
- }
-func_end:
- return status;
-}
-
-/*
- * ======== bridge_msg_set_queue_id ========
- */
-void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id)
-{
- /*
- * A message queue must be created when a node is allocated,
- * so that node_register_notify() can be called before the node
- * is created. Since we don't know the node environment until the
- * node is created, we need this function to set msg_queue_obj->msgq_id
- * to the node environment, after the node is created.
- */
- if (msg_queue_obj)
- msg_queue_obj->msgq_id = msgq_id;
-}
-
-/*
- * ======== add_new_msg ========
- * Must be called in message manager critical section.
- */
-static int add_new_msg(struct list_head *msg_list)
-{
- struct msg_frame *pmsg;
-
- pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC);
- if (!pmsg)
- return -ENOMEM;
-
- list_add_tail(&pmsg->list_elem, msg_list);
-
- return 0;
-}
-
-/*
- * ======== delete_msg_mgr ========
- */
-static void delete_msg_mgr(struct msg_mgr *hmsg_mgr)
-{
- if (!hmsg_mgr)
- return;
-
- /* FIXME: free elements from queue_list? */
- free_msg_list(&hmsg_mgr->msg_free_list);
- free_msg_list(&hmsg_mgr->msg_used_list);
- kfree(hmsg_mgr->sync_event);
- kfree(hmsg_mgr);
-}
-
-/*
- * ======== delete_msg_queue ========
- */
-static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp)
-{
- struct msg_mgr *hmsg_mgr;
- struct msg_frame *pmsg, *tmp;
- u32 i;
-
- if (!msg_queue_obj || !msg_queue_obj->msg_mgr)
- return;
-
- hmsg_mgr = msg_queue_obj->msg_mgr;
-
- /* Pull off num_to_dsp message frames from Msg manager and free */
- i = 0;
- list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list,
- list_elem) {
- list_del(&pmsg->list_elem);
- kfree(pmsg);
- if (i++ >= num_to_dsp)
- break;
- }
-
- free_msg_list(&msg_queue_obj->msg_free_list);
- free_msg_list(&msg_queue_obj->msg_used_list);
-
- if (msg_queue_obj->ntfy_obj) {
- ntfy_delete(msg_queue_obj->ntfy_obj);
- kfree(msg_queue_obj->ntfy_obj);
- }
-
- kfree(msg_queue_obj->sync_event);
- kfree(msg_queue_obj->sync_done);
- kfree(msg_queue_obj->sync_done_ack);
-
- kfree(msg_queue_obj);
-}
-
-/*
- * ======== free_msg_list ========
- */
-static void free_msg_list(struct list_head *msg_list)
-{
- struct msg_frame *pmsg, *tmp;
-
- if (!msg_list)
- return;
-
- list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) {
- list_del(&pmsg->list_elem);
- kfree(pmsg);
- }
-}
diff --git a/drivers/staging/tidspbridge/core/sync.c b/drivers/staging/tidspbridge/core/sync.c
deleted file mode 100644
index 743ff09d82d2..000000000000
--- a/drivers/staging/tidspbridge/core/sync.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * sync.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Synchronization services.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/sync.h>
-#include <dspbridge/ntfy.h>
-
-DEFINE_SPINLOCK(sync_lock);
-
-/**
- * sync_set_event() - set or signal and specified event
- * @event: Event to be set..
- *
- * set the @event, if there is an thread waiting for the event
- * it will be waken up, this function only wakes one thread.
- */
-
-void sync_set_event(struct sync_object *event)
-{
- spin_lock_bh(&sync_lock);
- complete(&event->comp);
- if (event->multi_comp)
- complete(event->multi_comp);
- spin_unlock_bh(&sync_lock);
-}
-
-/**
- * sync_wait_on_multiple_events() - waits for multiple events to be set.
- * @events: Array of events to wait for them.
- * @count: number of elements of the array.
- * @timeout timeout on waiting for the evetns.
- * @pu_index index of the event set.
- *
- * These functions will wait until any of the array element is set or until
- * timeout. In case of success the function will return 0 and
- * @pu_index will store the index of the array element set or in case
- * of timeout the function will return -ETIME or in case of
- * interrupting by a signal it will return -EPERM.
- */
-
-int sync_wait_on_multiple_events(struct sync_object **events,
- unsigned count, unsigned timeout,
- unsigned *index)
-{
- unsigned i;
- int status = -EPERM;
- struct completion m_comp;
-
- init_completion(&m_comp);
-
- if (SYNC_INFINITE == timeout)
- timeout = MAX_SCHEDULE_TIMEOUT;
-
- spin_lock_bh(&sync_lock);
- for (i = 0; i < count; i++) {
- if (completion_done(&events[i]->comp)) {
- reinit_completion(&events[i]->comp);
- *index = i;
- spin_unlock_bh(&sync_lock);
- status = 0;
- goto func_end;
- }
- }
-
- for (i = 0; i < count; i++)
- events[i]->multi_comp = &m_comp;
-
- spin_unlock_bh(&sync_lock);
-
- if (!wait_for_completion_interruptible_timeout(&m_comp,
- msecs_to_jiffies(timeout)))
- status = -ETIME;
-
- spin_lock_bh(&sync_lock);
- for (i = 0; i < count; i++) {
- if (completion_done(&events[i]->comp)) {
- reinit_completion(&events[i]->comp);
- *index = i;
- status = 0;
- }
- events[i]->multi_comp = NULL;
- }
- spin_unlock_bh(&sync_lock);
-func_end:
- return status;
-}
-
-/**
- * dsp_notifier_event() - callback function to nofity events
- * @this: pointer to itself struct notifier_block
- * @event: event to be notified.
- * @data: Currently not used.
- *
- */
-int dsp_notifier_event(struct notifier_block *this, unsigned long event,
- void *data)
-{
- struct ntfy_event *ne = container_of(this, struct ntfy_event,
- noti_block);
- if (ne->event & event)
- sync_set_event(&ne->sync_obj);
- return NOTIFY_OK;
-}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
deleted file mode 100644
index 8945b4e3a2a6..000000000000
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ /dev/null
@@ -1,1811 +0,0 @@
-/*
- * tiomap.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Processor Manager Driver for TI OMAP3430 EVM.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/platform_data/dsp-omap.h>
-
-#include <linux/types.h>
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-#include <linux/mm.h>
-#include <linux/mmzone.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/drv.h>
-#include <dspbridge/sync.h>
-
-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
-/* ----------------------------------- Link Driver */
-#include <dspbridge/dspdefs.h>
-#include <dspbridge/dspchnl.h>
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/dspio.h>
-#include <dspbridge/dspmsg.h>
-#include <dspbridge/pwr.h>
-#include <dspbridge/io_sm.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/dspapi.h>
-#include <dspbridge/dmm.h>
-#include <dspbridge/wdt.h>
-
-/* ----------------------------------- Local */
-#include "_tiomap.h"
-#include "_tiomap_pwr.h"
-#include "tiomap_io.h"
-
-/* Offset in shared mem to write to in order to synchronize start with DSP */
-#define SHMSYNCOFFSET 4 /* GPP byte offset */
-
-#define BUFFERSIZE 1024
-
-#define TIHELEN_ACKTIMEOUT 10000
-
-#define MMU_SECTION_ADDR_MASK 0xFFF00000
-#define MMU_SSECTION_ADDR_MASK 0xFF000000
-#define MMU_LARGE_PAGE_MASK 0xFFFF0000
-#define MMU_SMALL_PAGE_MASK 0xFFFFF000
-#define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00
-#define PAGES_II_LVL_TABLE 512
-#define PHYS_TO_PAGE(phys) pfn_to_page((phys) >> PAGE_SHIFT)
-
-/* IVA Boot modes */
-#define DIRECT 0
-#define IDLE 1
-
-/* Forward Declarations: */
-static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt);
-static int bridge_brd_read(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff,
- u32 dsp_addr, u32 ul_num_bytes,
- u32 mem_type);
-static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
- u32 dsp_addr);
-static int bridge_brd_status(struct bridge_dev_context *dev_ctxt,
- int *board_state);
-static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt);
-static int bridge_brd_write(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff,
- u32 dsp_addr, u32 ul_num_bytes,
- u32 mem_type);
-static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt,
- u32 brd_state);
-static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
- u32 dsp_dest_addr, u32 dsp_src_addr,
- u32 ul_num_bytes, u32 mem_type);
-static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type);
-static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes, u32 ul_map_attr,
- struct page **mapped_pages);
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes);
-static int bridge_dev_create(struct bridge_dev_context
- **dev_cntxt,
- struct dev_object *hdev_obj,
- struct cfg_hostres *config_param);
-static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
- u32 dw_cmd, void *pargs);
-static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt);
-static u32 user_va2_pa(struct mm_struct *mm, u32 address);
-static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
- u32 va, u32 size,
- struct hw_mmu_map_attrs_t *map_attrs);
-static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
- u32 size, struct hw_mmu_map_attrs_t *attrs);
-static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes,
- struct hw_mmu_map_attrs_t *hw_attrs);
-
-bool wait_for_start(struct bridge_dev_context *dev_context,
- void __iomem *sync_addr);
-
-/* ----------------------------------- Globals */
-
-/* Attributes of L2 page tables for DSP MMU */
-struct page_info {
- u32 num_entries; /* Number of valid PTEs in the L2 PT */
-};
-
-/* Attributes used to manage the DSP MMU page tables */
-struct pg_table_attrs {
- spinlock_t pg_lock; /* Critical section object handle */
-
- u32 l1_base_pa; /* Physical address of the L1 PT */
- u32 l1_base_va; /* Virtual address of the L1 PT */
- u32 l1_size; /* Size of the L1 PT */
- u32 l1_tbl_alloc_pa;
- /* Physical address of Allocated mem for L1 table. May not be aligned */
- u32 l1_tbl_alloc_va;
- /* Virtual address of Allocated mem for L1 table. May not be aligned */
- u32 l1_tbl_alloc_sz;
- /* Size of consistent memory allocated for L1 table.
- * May not be aligned */
-
- u32 l2_base_pa; /* Physical address of the L2 PT */
- u32 l2_base_va; /* Virtual address of the L2 PT */
- u32 l2_size; /* Size of the L2 PT */
- u32 l2_tbl_alloc_pa;
- /* Physical address of Allocated mem for L2 table. May not be aligned */
- u32 l2_tbl_alloc_va;
- /* Virtual address of Allocated mem for L2 table. May not be aligned */
- u32 l2_tbl_alloc_sz;
- /* Size of consistent memory allocated for L2 table.
- * May not be aligned */
-
- u32 l2_num_pages; /* Number of allocated L2 PT */
- /* Array [l2_num_pages] of L2 PT info structs */
- struct page_info *pg_info;
-};
-
-/*
- * This Bridge driver's function interface table.
- */
-static struct bridge_drv_interface drv_interface_fxns = {
- /* Bridge API ver. for which this bridge driver is built. */
- BRD_API_MAJOR_VERSION,
- BRD_API_MINOR_VERSION,
- bridge_dev_create,
- bridge_dev_destroy,
- bridge_dev_ctrl,
- bridge_brd_monitor,
- bridge_brd_start,
- bridge_brd_stop,
- bridge_brd_status,
- bridge_brd_read,
- bridge_brd_write,
- bridge_brd_set_state,
- bridge_brd_mem_copy,
- bridge_brd_mem_write,
- bridge_brd_mem_map,
- bridge_brd_mem_un_map,
- /* The following CHNL functions are provided by chnl_io.lib: */
- bridge_chnl_create,
- bridge_chnl_destroy,
- bridge_chnl_open,
- bridge_chnl_close,
- bridge_chnl_add_io_req,
- bridge_chnl_get_ioc,
- bridge_chnl_cancel_io,
- bridge_chnl_flush_io,
- bridge_chnl_get_info,
- bridge_chnl_get_mgr_info,
- bridge_chnl_idle,
- bridge_chnl_register_notify,
- /* The following IO functions are provided by chnl_io.lib: */
- bridge_io_create,
- bridge_io_destroy,
- bridge_io_on_loaded,
- bridge_io_get_proc_load,
- /* The following msg_ctrl functions are provided by chnl_io.lib: */
- bridge_msg_create,
- bridge_msg_create_queue,
- bridge_msg_delete,
- bridge_msg_delete_queue,
- bridge_msg_get,
- bridge_msg_put,
- bridge_msg_register_notify,
- bridge_msg_set_queue_id,
-};
-
-static struct notifier_block dsp_mbox_notifier = {
- .notifier_call = io_mbox_msg,
-};
-
-static inline void flush_all(struct bridge_dev_context *dev_context)
-{
- if (dev_context->brd_state == BRD_DSP_HIBERNATION ||
- dev_context->brd_state == BRD_HIBERNATION)
- wake_dsp(dev_context, NULL);
-
- hw_mmu_tlb_flush_all(dev_context->dsp_mmu_base);
-}
-
-static void bad_page_dump(u32 pa, struct page *pg)
-{
- pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa);
- pr_emerg("Bad page state in process '%s'\n"
- "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
- "Backtrace:\n",
- current->comm, pg, (int)(2 * sizeof(unsigned long)),
- (unsigned long)pg->flags, pg->mapping,
- page_mapcount(pg), page_count(pg));
- dump_stack();
-}
-
-/*
- * ======== bridge_drv_entry ========
- * purpose:
- * Bridge Driver entry point.
- */
-void bridge_drv_entry(struct bridge_drv_interface **drv_intf,
- const char *driver_file_name)
-{
- if (strcmp(driver_file_name, "UMA") == 0)
- *drv_intf = &drv_interface_fxns;
- else
- dev_dbg(bridge, "%s Unknown Bridge file name", __func__);
-
-}
-
-/*
- * ======== bridge_brd_monitor ========
- * purpose:
- * This bridge_brd_monitor puts DSP into a Loadable state.
- * i.e Application can load and start the device.
- *
- * Preconditions:
- * Device in 'OFF' state.
- */
-static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt)
-{
- struct bridge_dev_context *dev_context = dev_ctxt;
- u32 temp;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- temp = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- if (!(temp & 0x02)) {
- /* IVA2 is not in ON state */
- /* Read and set PM_PWSTCTRL_IVA2 to ON */
- (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
- PWRDM_POWER_ON, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
- /* Set the SW supervised state transition */
- (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP,
- OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
-
- /* Wait until the state has moved to ON */
- while (*pdata->dsp_prm_read(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST)&
- OMAP_INTRANSITION_MASK);
- /* Disable Automatic transition */
- (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO,
- OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
- }
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
- dsp_clk_enable(DSP_CLK_IVA2);
-
- /* set the device state to IDLE */
- dev_context->brd_state = BRD_IDLE;
-
- return 0;
-}
-
-/*
- * ======== bridge_brd_read ========
- * purpose:
- * Reads buffers for DSP memory.
- */
-static int bridge_brd_read(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- u32 offset;
- u32 dsp_base_addr = dev_ctxt->dsp_base_addr;
-
- if (dsp_addr < dev_context->dsp_start_add) {
- status = -EPERM;
- return status;
- }
- /* change here to account for the 3 bands of the DSP internal memory */
- if ((dsp_addr - dev_context->dsp_start_add) <
- dev_context->internal_size) {
- offset = dsp_addr - dev_context->dsp_start_add;
- } else {
- status = read_ext_dsp_data(dev_context, host_buff, dsp_addr,
- ul_num_bytes, mem_type);
- return status;
- }
- /* copy the data from DSP memory */
- memcpy(host_buff, (void *)(dsp_base_addr + offset), ul_num_bytes);
- return status;
-}
-
-/*
- * ======== bridge_brd_set_state ========
- * purpose:
- * This routine updates the Board status.
- */
-static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt,
- u32 brd_state)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
-
- dev_context->brd_state = brd_state;
- return status;
-}
-
-/*
- * ======== bridge_brd_start ========
- * purpose:
- * Initializes DSP MMU and Starts DSP.
- *
- * Preconditions:
- * a) DSP domain is 'ACTIVE'.
- * b) DSP_RST1 is asserted.
- * b) DSP_RST2 is released.
- */
-static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
- u32 dsp_addr)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- void __iomem *sync_addr;
- u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */
- u32 ul_shm_base_virt; /* Dsp Virt SM base addr */
- u32 ul_tlb_base_virt; /* Base of MMU TLB entry */
- u32 shm_sync_pa;
- /* Offset of shm_base_virt from tlb_base_virt */
- u32 ul_shm_offset_virt;
- s32 entry_ndx;
- s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */
- struct cfg_hostres *resources = NULL;
- u32 temp;
- u32 ul_dsp_clk_rate;
- u32 ul_dsp_clk_addr;
- u32 ul_bios_gp_timer;
- u32 clk_cmd;
- struct io_mgr *hio_mgr;
- u32 ul_load_monitor_timer;
- u32 wdt_en = 0;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- /* The device context contains all the mmu setup info from when the
- * last dsp base image was loaded. The first entry is always
- * SHMMEM base. */
- /* Get SHM_BEG - convert to byte address */
- (void)dev_get_symbol(dev_context->dev_obj, SHMBASENAME,
- &ul_shm_base_virt);
- ul_shm_base_virt *= DSPWORDSIZE;
- /* DSP Virtual address */
- ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va;
- ul_shm_offset_virt =
- ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE);
- /* Kernel logical address */
- ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt;
-
- /* SHM physical sync address */
- shm_sync_pa = dev_context->atlb_entry[0].gpp_pa + ul_shm_offset_virt +
- SHMSYNCOFFSET;
-
- /* 2nd wd is used as sync field */
- sync_addr = ioremap(shm_sync_pa, SZ_32);
- if (!sync_addr)
- return -ENOMEM;
-
- /* Write a signature into the shm base + offset; this will
- * get cleared when the DSP program starts. */
- if ((ul_shm_base_virt == 0) || (ul_shm_base == 0)) {
- pr_err("%s: Illegal SM base\n", __func__);
- status = -EPERM;
- } else
- __raw_writel(0xffffffff, sync_addr);
-
- if (!status) {
- resources = dev_context->resources;
- if (!resources)
- status = -EPERM;
-
- /* Assert RST1 i.e only the RST only for DSP megacell */
- if (!status) {
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK,
- OMAP3430_RST1_IVA2_MASK,
- OMAP3430_IVA2_MOD,
- OMAP2_RM_RSTCTRL);
-
- /* Mask address with 1K for compatibility */
- pdata->set_bootaddr(dsp_addr &
- OMAP3_IVA2_BOOTADDR_MASK);
- pdata->set_bootmode(dsp_debug ? IDLE : DIRECT);
- }
- }
- if (!status) {
- /* Reset and Unreset the RST2, so that BOOTADDR is copied to
- * IVA2 SYSC register */
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK,
- OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD,
- OMAP2_RM_RSTCTRL);
- udelay(100);
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
- udelay(100);
-
- /* Disbale the DSP MMU */
- hw_mmu_disable(resources->dmmu_base);
- /* Disable TWL */
- hw_mmu_twl_disable(resources->dmmu_base);
-
- /* Only make TLB entry if both addresses are non-zero */
- for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB;
- entry_ndx++) {
- struct bridge_ioctl_extproc *e =
- &dev_context->atlb_entry[entry_ndx];
- struct hw_mmu_map_attrs_t map_attrs = {
- .endianism = e->endianism,
- .element_size = e->elem_size,
- .mixed_size = e->mixed_mode,
- };
-
- if (!e->gpp_pa || !e->dsp_va)
- continue;
-
- dev_dbg(bridge,
- "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x",
- itmp_entry_ndx,
- e->gpp_pa,
- e->dsp_va,
- e->size);
-
- hw_mmu_tlb_add(dev_context->dsp_mmu_base,
- e->gpp_pa,
- e->dsp_va,
- e->size,
- itmp_entry_ndx,
- &map_attrs, 1, 1);
-
- itmp_entry_ndx++;
- }
- }
-
- /* Lock the above TLB entries and get the BIOS and load monitor timer
- * information */
- if (!status) {
- hw_mmu_num_locked_set(resources->dmmu_base, itmp_entry_ndx);
- hw_mmu_victim_num_set(resources->dmmu_base, itmp_entry_ndx);
- hw_mmu_ttb_set(resources->dmmu_base,
- dev_context->pt_attrs->l1_base_pa);
- hw_mmu_twl_enable(resources->dmmu_base);
- /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */
-
- temp = __raw_readl((resources->dmmu_base) + 0x10);
- temp = (temp & 0xFFFFFFEF) | 0x11;
- __raw_writel(temp, (resources->dmmu_base) + 0x10);
-
- /* Let the DSP MMU run */
- hw_mmu_enable(resources->dmmu_base);
-
- /* Enable the BIOS clock */
- (void)dev_get_symbol(dev_context->dev_obj,
- BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer);
- (void)dev_get_symbol(dev_context->dev_obj,
- BRIDGEINIT_LOADMON_GPTIMER,
- &ul_load_monitor_timer);
- }
-
- if (!status) {
- if (ul_load_monitor_timer != 0xFFFF) {
- clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
- ul_load_monitor_timer;
- dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
- } else {
- dev_dbg(bridge, "Not able to get the symbol for Load "
- "Monitor Timer\n");
- }
- }
-
- if (!status) {
- if (ul_bios_gp_timer != 0xFFFF) {
- clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) |
- ul_bios_gp_timer;
- dsp_peripheral_clk_ctrl(dev_context, &clk_cmd);
- } else {
- dev_dbg(bridge,
- "Not able to get the symbol for BIOS Timer\n");
- }
- }
-
- if (!status) {
- /* Set the DSP clock rate */
- (void)dev_get_symbol(dev_context->dev_obj,
- "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr);
- /*Set Autoidle Mode for IVA2 PLL */
- (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
- OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL);
-
- if ((unsigned int *)ul_dsp_clk_addr != NULL) {
- /* Get the clock rate */
- ul_dsp_clk_rate = dsp_clk_get_iva2_rate();
- dev_dbg(bridge, "%s: DSP clock rate (KHZ): 0x%x \n",
- __func__, ul_dsp_clk_rate);
- (void)bridge_brd_write(dev_context,
- (u8 *) &ul_dsp_clk_rate,
- ul_dsp_clk_addr, sizeof(u32), 0);
- }
- /*
- * Enable Mailbox events and also drain any pending
- * stale messages.
- */
- dev_context->mbox = omap_mbox_get("dsp", &dsp_mbox_notifier);
- if (IS_ERR(dev_context->mbox)) {
- dev_context->mbox = NULL;
- pr_err("%s: Failed to get dsp mailbox handle\n",
- __func__);
- status = -EPERM;
- }
-
- }
- if (!status) {
-/*PM_IVA2GRPSEL_PER = 0xC0;*/
- temp = readl(resources->per_pm_base + 0xA8);
- temp = (temp & 0xFFFFFF30) | 0xC0;
- writel(temp, resources->per_pm_base + 0xA8);
-
-/*PM_MPUGRPSEL_PER &= 0xFFFFFF3F; */
- temp = readl(resources->per_pm_base + 0xA4);
- temp = (temp & 0xFFFFFF3F);
- writel(temp, resources->per_pm_base + 0xA4);
-/*CM_SLEEPDEP_PER |= 0x04; */
- temp = readl(resources->per_base + 0x44);
- temp = (temp & 0xFFFFFFFB) | 0x04;
- writel(temp, resources->per_base + 0x44);
-
-/*CM_CLKSTCTRL_IVA2 = 0x00000003 -To Allow automatic transitions */
- (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_ENABLE_AUTO,
- OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
-
- /* Let DSP go */
- dev_dbg(bridge, "%s Unreset\n", __func__);
- /* Enable DSP MMU Interrupts */
- hw_mmu_event_enable(resources->dmmu_base,
- HW_MMU_ALL_INTERRUPTS);
- /* release the RST1, DSP starts executing now .. */
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-
- dev_dbg(bridge, "Waiting for Sync @ 0x%x\n", *(u32 *)sync_addr);
- dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr);
- if (dsp_debug)
- while (__raw_readw(sync_addr))
- ;
-
- /* Wait for DSP to clear word in shared memory */
- /* Read the Location */
- if (!wait_for_start(dev_context, sync_addr))
- status = -ETIMEDOUT;
-
- dev_get_symbol(dev_context->dev_obj, "_WDT_enable", &wdt_en);
- if (wdt_en) {
- /* Start wdt */
- dsp_wdt_sm_set((void *)ul_shm_base);
- dsp_wdt_enable(true);
- }
-
- status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
- if (hio_mgr) {
- io_sh_msetting(hio_mgr, SHM_OPPINFO, NULL);
- /* Write the synchronization bit to indicate the
- * completion of OPP table update to DSP
- */
- __raw_writel(0XCAFECAFE, sync_addr);
-
- /* update board state */
- dev_context->brd_state = BRD_RUNNING;
- /* (void)chnlsm_enable_interrupt(dev_context); */
- } else {
- dev_context->brd_state = BRD_UNKNOWN;
- }
- }
-
- iounmap(sync_addr);
-
- return status;
-}
-
-/*
- * ======== bridge_brd_stop ========
- * purpose:
- * Puts DSP in self loop.
- *
- * Preconditions :
- * a) None
- */
-static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- struct pg_table_attrs *pt_attrs;
- u32 dsp_pwr_state;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- if (dev_context->brd_state == BRD_STOPPED)
- return status;
-
- /* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode,
- * before turning off the clocks.. This is to ensure that there are no
- * pending L3 or other transactons from IVA2 */
- dsp_pwr_state = (*pdata->dsp_prm_read)
- (OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) & OMAP_POWERSTATEST_MASK;
- if (dsp_pwr_state != PWRDM_POWER_OFF) {
- (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
- sm_interrupt_dsp(dev_context, MBX_PM_DSPIDLE);
- mdelay(10);
-
- /* IVA2 is not in OFF state */
- /* Set PM_PWSTCTRL_IVA2 to OFF */
- (*pdata->dsp_prm_rmw_bits)(OMAP_POWERSTATEST_MASK,
- PWRDM_POWER_OFF, OMAP3430_IVA2_MOD, OMAP2_PM_PWSTCTRL);
- /* Set the SW supervised state transition for Sleep */
- (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_FORCE_SLEEP,
- OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
- }
- udelay(10);
- /* Release the Ext Base virtual Address as the next DSP Program
- * may have a different load address */
- if (dev_context->dsp_ext_base_addr)
- dev_context->dsp_ext_base_addr = 0;
-
- dev_context->brd_state = BRD_STOPPED; /* update board state */
-
- dsp_wdt_enable(false);
-
- /* This is a good place to clear the MMU page tables as well */
- if (dev_context->pt_attrs) {
- pt_attrs = dev_context->pt_attrs;
- memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size);
- memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size);
- memset((u8 *) pt_attrs->pg_info, 0x00,
- (pt_attrs->l2_num_pages * sizeof(struct page_info)));
- }
- /* Disable the mailbox interrupts */
- if (dev_context->mbox) {
- omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
- omap_mbox_put(dev_context->mbox, &dsp_mbox_notifier);
- dev_context->mbox = NULL;
- }
- /* Reset IVA2 clocks*/
- (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK |
- OMAP3430_RST2_IVA2_MASK | OMAP3430_RST3_IVA2_MASK,
- OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
-
- dsp_clock_disable_all(dev_context->dsp_per_clks);
- dsp_clk_disable(DSP_CLK_IVA2);
-
- return status;
-}
-
-/*
- * ======== bridge_brd_status ========
- * Returns the board status.
- */
-static int bridge_brd_status(struct bridge_dev_context *dev_ctxt,
- int *board_state)
-{
- struct bridge_dev_context *dev_context = dev_ctxt;
- *board_state = dev_context->brd_state;
- return 0;
-}
-
-/*
- * ======== bridge_brd_write ========
- * Copies the buffers to DSP internal or external memory.
- */
-static int bridge_brd_write(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
-
- if (dsp_addr < dev_context->dsp_start_add) {
- status = -EPERM;
- return status;
- }
- if ((dsp_addr - dev_context->dsp_start_add) <
- dev_context->internal_size) {
- status = write_dsp_data(dev_ctxt, host_buff, dsp_addr,
- ul_num_bytes, mem_type);
- } else {
- status = write_ext_dsp_data(dev_context, host_buff, dsp_addr,
- ul_num_bytes, mem_type, false);
- }
-
- return status;
-}
-
-/*
- * ======== bridge_dev_create ========
- * Creates a driver object. Puts DSP in self loop.
- */
-static int bridge_dev_create(struct bridge_dev_context
- **dev_cntxt,
- struct dev_object *hdev_obj,
- struct cfg_hostres *config_param)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = NULL;
- s32 entry_ndx;
- struct cfg_hostres *resources = config_param;
- struct pg_table_attrs *pt_attrs;
- u32 pg_tbl_pa;
- u32 pg_tbl_va;
- u32 align_size;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /* Allocate and initialize a data structure to contain the bridge driver
- * state, which becomes the context for later calls into this driver */
- dev_context = kzalloc(sizeof(struct bridge_dev_context), GFP_KERNEL);
- if (!dev_context) {
- status = -ENOMEM;
- goto func_end;
- }
-
- dev_context->dsp_start_add = (u32) OMAP_GEM_BASE;
- dev_context->self_loop = (u32) NULL;
- dev_context->dsp_per_clks = 0;
- dev_context->internal_size = OMAP_DSP_SIZE;
- /* Clear dev context MMU table entries.
- * These get set on bridge_io_on_loaded() call after program loaded. */
- for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) {
- dev_context->atlb_entry[entry_ndx].gpp_pa =
- dev_context->atlb_entry[entry_ndx].dsp_va = 0;
- }
- dev_context->dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *)
- (config_param->
- mem_base
- [3]),
- config_param->
- mem_length
- [3]);
- if (!dev_context->dsp_base_addr)
- status = -EPERM;
-
- pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL);
- if (pt_attrs != NULL) {
- pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */
- align_size = pt_attrs->l1_size;
- /* Align sizes are expected to be power of 2 */
- /* we like to get aligned on L1 table size */
- pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size,
- align_size, &pg_tbl_pa);
-
- /* Check if the PA is aligned for us */
- if ((pg_tbl_pa) & (align_size - 1)) {
- /* PA not aligned to page table size ,
- * try with more allocation and align */
- mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa,
- pt_attrs->l1_size);
- /* we like to get aligned on L1 table size */
- pg_tbl_va =
- (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2,
- align_size, &pg_tbl_pa);
- /* We should be able to get aligned table now */
- pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2;
- /* Align the PA to the next 'align' boundary */
- pt_attrs->l1_base_pa =
- ((pg_tbl_pa) +
- (align_size - 1)) & (~(align_size - 1));
- pt_attrs->l1_base_va =
- pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa);
- } else {
- /* We got aligned PA, cool */
- pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l1_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size;
- pt_attrs->l1_base_pa = pg_tbl_pa;
- pt_attrs->l1_base_va = pg_tbl_va;
- }
- if (pt_attrs->l1_base_va)
- memset((u8 *) pt_attrs->l1_base_va, 0x00,
- pt_attrs->l1_size);
-
- /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM +
- * L4 pages */
- pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6);
- pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE *
- pt_attrs->l2_num_pages;
- align_size = 4; /* Make it u32 aligned */
- /* we like to get aligned on L1 table size */
- pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size,
- align_size, &pg_tbl_pa);
- pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa;
- pt_attrs->l2_tbl_alloc_va = pg_tbl_va;
- pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size;
- pt_attrs->l2_base_pa = pg_tbl_pa;
- pt_attrs->l2_base_va = pg_tbl_va;
-
- if (pt_attrs->l2_base_va)
- memset((u8 *) pt_attrs->l2_base_va, 0x00,
- pt_attrs->l2_size);
-
- pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages *
- sizeof(struct page_info), GFP_KERNEL);
- dev_dbg(bridge,
- "L1 pa %x, va %x, size %x\n L2 pa %x, va "
- "%x, size %x\n", pt_attrs->l1_base_pa,
- pt_attrs->l1_base_va, pt_attrs->l1_size,
- pt_attrs->l2_base_pa, pt_attrs->l2_base_va,
- pt_attrs->l2_size);
- dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n",
- pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info);
- }
- if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) &&
- (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL))
- dev_context->pt_attrs = pt_attrs;
- else
- status = -ENOMEM;
-
- if (!status) {
- spin_lock_init(&pt_attrs->pg_lock);
- dev_context->tc_word_swap_on = drv_datap->tc_wordswapon;
-
- /* Set the Clock Divisor for the DSP module */
- udelay(5);
- /* MMU address is obtained from the host
- * resources struct */
- dev_context->dsp_mmu_base = resources->dmmu_base;
- }
- if (!status) {
- dev_context->dev_obj = hdev_obj;
- /* Store current board state. */
- dev_context->brd_state = BRD_UNKNOWN;
- dev_context->resources = resources;
- dsp_clk_enable(DSP_CLK_IVA2);
- bridge_brd_stop(dev_context);
- /* Return ptr to our device state to the DSP API for storage */
- *dev_cntxt = dev_context;
- } else {
- if (pt_attrs != NULL) {
- kfree(pt_attrs->pg_info);
-
- if (pt_attrs->l2_tbl_alloc_va) {
- mem_free_phys_mem((void *)
- pt_attrs->l2_tbl_alloc_va,
- pt_attrs->l2_tbl_alloc_pa,
- pt_attrs->l2_tbl_alloc_sz);
- }
- if (pt_attrs->l1_tbl_alloc_va) {
- mem_free_phys_mem((void *)
- pt_attrs->l1_tbl_alloc_va,
- pt_attrs->l1_tbl_alloc_pa,
- pt_attrs->l1_tbl_alloc_sz);
- }
- }
- kfree(pt_attrs);
- kfree(dev_context);
- }
-func_end:
- return status;
-}
-
-/*
- * ======== bridge_dev_ctrl ========
- * Receives device specific commands.
- */
-static int bridge_dev_ctrl(struct bridge_dev_context *dev_context,
- u32 dw_cmd, void *pargs)
-{
- int status = 0;
- struct bridge_ioctl_extproc *pa_ext_proc =
- (struct bridge_ioctl_extproc *)pargs;
- s32 ndx;
-
- switch (dw_cmd) {
- case BRDIOCTL_CHNLREAD:
- break;
- case BRDIOCTL_CHNLWRITE:
- break;
- case BRDIOCTL_SETMMUCONFIG:
- /* store away dsp-mmu setup values for later use */
- for (ndx = 0; ndx < BRDIOCTL_NUMOFMMUTLB; ndx++, pa_ext_proc++)
- dev_context->atlb_entry[ndx] = *pa_ext_proc;
- break;
- case BRDIOCTL_DEEPSLEEP:
- case BRDIOCTL_EMERGENCYSLEEP:
- /* Currently only DSP Idle is supported Need to update for
- * later releases */
- status = sleep_dsp(dev_context, PWR_DEEPSLEEP, pargs);
- break;
- case BRDIOCTL_WAKEUP:
- status = wake_dsp(dev_context, pargs);
- break;
- case BRDIOCTL_CLK_CTRL:
- status = 0;
- /* Looking For Baseport Fix for Clocks */
- status = dsp_peripheral_clk_ctrl(dev_context, pargs);
- break;
- case BRDIOCTL_PWR_HIBERNATE:
- status = handle_hibernation_from_dsp(dev_context);
- break;
- case BRDIOCTL_PRESCALE_NOTIFY:
- status = pre_scale_dsp(dev_context, pargs);
- break;
- case BRDIOCTL_POSTSCALE_NOTIFY:
- status = post_scale_dsp(dev_context, pargs);
- break;
- case BRDIOCTL_CONSTRAINT_REQUEST:
- status = handle_constraints_set(dev_context, pargs);
- break;
- default:
- status = -EPERM;
- break;
- }
- return status;
-}
-
-/*
- * ======== bridge_dev_destroy ========
- * Destroys the driver object.
- */
-static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt)
-{
- struct pg_table_attrs *pt_attrs;
- int status = 0;
- struct bridge_dev_context *dev_context = (struct bridge_dev_context *)
- dev_ctxt;
- struct cfg_hostres *host_res;
- u32 shm_size;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /* It should never happen */
- if (!dev_ctxt)
- return -EFAULT;
-
- /* first put the device to stop state */
- bridge_brd_stop(dev_context);
- if (dev_context->pt_attrs) {
- pt_attrs = dev_context->pt_attrs;
- kfree(pt_attrs->pg_info);
-
- if (pt_attrs->l2_tbl_alloc_va) {
- mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va,
- pt_attrs->l2_tbl_alloc_pa,
- pt_attrs->l2_tbl_alloc_sz);
- }
- if (pt_attrs->l1_tbl_alloc_va) {
- mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va,
- pt_attrs->l1_tbl_alloc_pa,
- pt_attrs->l1_tbl_alloc_sz);
- }
- kfree(pt_attrs);
-
- }
-
- if (dev_context->resources) {
- host_res = dev_context->resources;
- shm_size = drv_datap->shm_size;
- if (shm_size >= 0x10000) {
- if ((host_res->mem_base[1]) &&
- (host_res->mem_phys[1])) {
- mem_free_phys_mem((void *)
- host_res->mem_base
- [1],
- host_res->mem_phys
- [1], shm_size);
- }
- } else {
- dev_dbg(bridge, "%s: Error getting shm size "
- "from registry: %x. Not calling "
- "mem_free_phys_mem\n", __func__,
- status);
- }
- host_res->mem_base[1] = 0;
- host_res->mem_phys[1] = 0;
-
- if (host_res->mem_base[0])
- iounmap((void *)host_res->mem_base[0]);
- if (host_res->mem_base[2])
- iounmap((void *)host_res->mem_base[2]);
- if (host_res->mem_base[3])
- iounmap((void *)host_res->mem_base[3]);
- if (host_res->mem_base[4])
- iounmap((void *)host_res->mem_base[4]);
- if (host_res->dmmu_base)
- iounmap(host_res->dmmu_base);
- if (host_res->per_base)
- iounmap(host_res->per_base);
- if (host_res->per_pm_base)
- iounmap((void *)host_res->per_pm_base);
- if (host_res->core_pm_base)
- iounmap((void *)host_res->core_pm_base);
-
- host_res->mem_base[0] = (u32) NULL;
- host_res->mem_base[2] = (u32) NULL;
- host_res->mem_base[3] = (u32) NULL;
- host_res->mem_base[4] = (u32) NULL;
- host_res->dmmu_base = NULL;
-
- kfree(host_res);
- }
-
- /* Free the driver's device context: */
- kfree(drv_datap->base_img);
- kfree((void *)dev_ctxt);
- return status;
-}
-
-static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt,
- u32 dsp_dest_addr, u32 dsp_src_addr,
- u32 ul_num_bytes, u32 mem_type)
-{
- int status = 0;
- u32 src_addr = dsp_src_addr;
- u32 dest_addr = dsp_dest_addr;
- u32 copy_bytes = 0;
- u32 total_bytes = ul_num_bytes;
- u8 host_buf[BUFFERSIZE];
- struct bridge_dev_context *dev_context = dev_ctxt;
- while (total_bytes > 0 && !status) {
- copy_bytes =
- total_bytes > BUFFERSIZE ? BUFFERSIZE : total_bytes;
- /* Read from External memory */
- status = read_ext_dsp_data(dev_ctxt, host_buf, src_addr,
- copy_bytes, mem_type);
- if (!status) {
- if (dest_addr < (dev_context->dsp_start_add +
- dev_context->internal_size)) {
- /* Write to Internal memory */
- status = write_dsp_data(dev_ctxt, host_buf,
- dest_addr, copy_bytes,
- mem_type);
- } else {
- /* Write to External memory */
- status =
- write_ext_dsp_data(dev_ctxt, host_buf,
- dest_addr, copy_bytes,
- mem_type, false);
- }
- }
- total_bytes -= copy_bytes;
- src_addr += copy_bytes;
- dest_addr += copy_bytes;
- }
- return status;
-}
-
-/* Mem Write does not halt the DSP to write unlike bridge_brd_write */
-static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- u32 ul_remain_bytes = 0;
- u32 ul_bytes = 0;
- ul_remain_bytes = ul_num_bytes;
- while (ul_remain_bytes > 0 && !status) {
- ul_bytes =
- ul_remain_bytes > BUFFERSIZE ? BUFFERSIZE : ul_remain_bytes;
- if (dsp_addr < (dev_context->dsp_start_add +
- dev_context->internal_size)) {
- status =
- write_dsp_data(dev_ctxt, host_buff, dsp_addr,
- ul_bytes, mem_type);
- } else {
- status = write_ext_dsp_data(dev_ctxt, host_buff,
- dsp_addr, ul_bytes,
- mem_type, true);
- }
- ul_remain_bytes -= ul_bytes;
- dsp_addr += ul_bytes;
- host_buff = host_buff + ul_bytes;
- }
- return status;
-}
-
-/*
- * ======== bridge_brd_mem_map ========
- * This function maps MPU buffer to the DSP address space. It performs
- * linear to physical address translation if required. It translates each
- * page since linear addresses can be physically non-contiguous
- * All address & size arguments are assumed to be page aligned (in proc.c)
- *
- * TODO: Disable MMU while updating the page tables (but that'll stall DSP)
- */
-static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes, u32 ul_map_attr,
- struct page **mapped_pages)
-{
- u32 attrs;
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- struct hw_mmu_map_attrs_t hw_attrs;
- struct vm_area_struct *vma;
- struct mm_struct *mm = current->mm;
- u32 write = 0;
- u32 num_usr_pgs = 0;
- struct page *mapped_page, *pg;
- s32 pg_num;
- u32 va = virt_addr;
- struct task_struct *curr_task = current;
- u32 pg_i = 0;
- u32 mpu_addr, pa;
-
- dev_dbg(bridge,
- "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n",
- __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes,
- ul_map_attr);
- if (ul_num_bytes == 0)
- return -EINVAL;
-
- if (ul_map_attr & DSP_MAP_DIR_MASK) {
- attrs = ul_map_attr;
- } else {
- /* Assign default attributes */
- attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16);
- }
- /* Take mapping properties */
- if (attrs & DSP_MAPBIGENDIAN)
- hw_attrs.endianism = HW_BIG_ENDIAN;
- else
- hw_attrs.endianism = HW_LITTLE_ENDIAN;
-
- hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t)
- ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2);
- /* Ignore element_size if mixed_size is enabled */
- if (hw_attrs.mixed_size == 0) {
- if (attrs & DSP_MAPELEMSIZE8) {
- /* Size is 8 bit */
- hw_attrs.element_size = HW_ELEM_SIZE8BIT;
- } else if (attrs & DSP_MAPELEMSIZE16) {
- /* Size is 16 bit */
- hw_attrs.element_size = HW_ELEM_SIZE16BIT;
- } else if (attrs & DSP_MAPELEMSIZE32) {
- /* Size is 32 bit */
- hw_attrs.element_size = HW_ELEM_SIZE32BIT;
- } else if (attrs & DSP_MAPELEMSIZE64) {
- /* Size is 64 bit */
- hw_attrs.element_size = HW_ELEM_SIZE64BIT;
- } else {
- /*
- * Mixedsize isn't enabled, so size can't be
- * zero here
- */
- return -EINVAL;
- }
- }
- if (attrs & DSP_MAPDONOTLOCK)
- hw_attrs.donotlockmpupage = 1;
- else
- hw_attrs.donotlockmpupage = 0;
-
- if (attrs & DSP_MAPVMALLOCADDR) {
- return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr,
- ul_num_bytes, &hw_attrs);
- }
- /*
- * Do OS-specific user-va to pa translation.
- * Combine physically contiguous regions to reduce TLBs.
- * Pass the translated pa to pte_update.
- */
- if ((attrs & DSP_MAPPHYSICALADDR)) {
- status = pte_update(dev_context, ul_mpu_addr, virt_addr,
- ul_num_bytes, &hw_attrs);
- goto func_cont;
- }
-
- /*
- * Important Note: ul_mpu_addr is mapped from user application process
- * to current process - it must lie completely within the current
- * virtual memory address space in order to be of use to us here!
- */
- down_read(&mm->mmap_sem);
- vma = find_vma(mm, ul_mpu_addr);
- if (vma)
- dev_dbg(bridge,
- "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, "
- "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
- ul_num_bytes, vma->vm_start, vma->vm_end,
- vma->vm_flags);
-
- /*
- * It is observed that under some circumstances, the user buffer is
- * spread across several VMAs. So loop through and check if the entire
- * user buffer is covered
- */
- while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) {
- /* jump to the next VMA region */
- vma = find_vma(mm, vma->vm_end + 1);
- dev_dbg(bridge,
- "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, "
- "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr,
- ul_num_bytes, vma->vm_start, vma->vm_end,
- vma->vm_flags);
- }
- if (!vma) {
- pr_err("%s: Failed to get VMA region for 0x%x (%d)\n",
- __func__, ul_mpu_addr, ul_num_bytes);
- status = -EINVAL;
- up_read(&mm->mmap_sem);
- goto func_cont;
- }
-
- if (vma->vm_flags & VM_IO) {
- num_usr_pgs = ul_num_bytes / PG_SIZE4K;
- mpu_addr = ul_mpu_addr;
-
- /* Get the physical addresses for user buffer */
- for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
- pa = user_va2_pa(mm, mpu_addr);
- if (!pa) {
- status = -EPERM;
- pr_err("DSPBRIDGE: VM_IO mapping physical"
- "address is invalid\n");
- break;
- }
- if (pfn_valid(__phys_to_pfn(pa))) {
- pg = PHYS_TO_PAGE(pa);
- get_page(pg);
- if (page_count(pg) < 1) {
- pr_err("Bad page in VM_IO buffer\n");
- bad_page_dump(pa, pg);
- }
- }
- status = pte_set(dev_context->pt_attrs, pa,
- va, HW_PAGE_SIZE4KB, &hw_attrs);
- if (status)
- break;
-
- va += HW_PAGE_SIZE4KB;
- mpu_addr += HW_PAGE_SIZE4KB;
- pa += HW_PAGE_SIZE4KB;
- }
- } else {
- num_usr_pgs = ul_num_bytes / PG_SIZE4K;
- if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
- write = 1;
-
- for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) {
- pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1,
- write, 1, &mapped_page, NULL);
- if (pg_num > 0) {
- if (page_count(mapped_page) < 1) {
- pr_err("Bad page count after doing"
- "get_user_pages on"
- "user buffer\n");
- bad_page_dump(page_to_phys(mapped_page),
- mapped_page);
- }
- status = pte_set(dev_context->pt_attrs,
- page_to_phys(mapped_page), va,
- HW_PAGE_SIZE4KB, &hw_attrs);
- if (status)
- break;
-
- if (mapped_pages)
- mapped_pages[pg_i] = mapped_page;
-
- va += HW_PAGE_SIZE4KB;
- ul_mpu_addr += HW_PAGE_SIZE4KB;
- } else {
- pr_err("DSPBRIDGE: get_user_pages FAILED,"
- "MPU addr = 0x%x,"
- "vma->vm_flags = 0x%lx,"
- "get_user_pages Err"
- "Value = %d, Buffer"
- "size=0x%x\n", ul_mpu_addr,
- vma->vm_flags, pg_num, ul_num_bytes);
- status = -EPERM;
- break;
- }
- }
- }
- up_read(&mm->mmap_sem);
-func_cont:
- if (status) {
- /*
- * Roll out the mapped pages incase it failed in middle of
- * mapping
- */
- if (pg_i) {
- bridge_brd_mem_un_map(dev_context, virt_addr,
- (pg_i * PG_SIZE4K));
- }
- status = -EPERM;
- }
- /*
- * In any case, flush the TLB
- * This is called from here instead from pte_update to avoid unnecessary
- * repetition while mapping non-contiguous physical regions of a virtual
- * region
- */
- flush_all(dev_context);
- dev_dbg(bridge, "%s status %x\n", __func__, status);
- return status;
-}
-
-/*
- * ======== bridge_brd_mem_un_map ========
- * Invalidate the PTEs for the DSP VA block to be unmapped.
- *
- * PTEs of a mapped memory block are contiguous in any page table
- * So, instead of looking up the PTE address for every 4K block,
- * we clear consecutive PTEs until we unmap all the bytes
- */
-static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes)
-{
- u32 l1_base_va;
- u32 l2_base_va;
- u32 l2_base_pa;
- u32 l2_page_num;
- u32 pte_val;
- u32 pte_size;
- u32 pte_count;
- u32 pte_addr_l1;
- u32 pte_addr_l2 = 0;
- u32 rem_bytes;
- u32 rem_bytes_l2;
- u32 va_curr;
- struct page *pg = NULL;
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- struct pg_table_attrs *pt = dev_context->pt_attrs;
- u32 temp;
- u32 paddr;
- u32 numof4k_pages = 0;
-
- va_curr = virt_addr;
- rem_bytes = ul_num_bytes;
- rem_bytes_l2 = 0;
- l1_base_va = pt->l1_base_va;
- pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
- dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, "
- "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr,
- ul_num_bytes, l1_base_va, pte_addr_l1);
-
- while (rem_bytes && !status) {
- u32 va_curr_orig = va_curr;
- /* Find whether the L1 PTE points to a valid L2 PT */
- pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr);
- pte_val = *(u32 *) pte_addr_l1;
- pte_size = hw_mmu_pte_size_l1(pte_val);
-
- if (pte_size != HW_MMU_COARSE_PAGE_SIZE)
- goto skip_coarse_page;
-
- /*
- * Get the L2 PA from the L1 PTE, and find
- * corresponding L2 VA
- */
- l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
- l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
- l2_page_num =
- (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
- /*
- * Find the L2 PTE address from which we will start
- * clearing, the number of PTEs to be cleared on this
- * page, and the size of VA space that needs to be
- * cleared on this L2 page
- */
- pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr);
- pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1);
- pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32);
- if (rem_bytes < (pte_count * PG_SIZE4K))
- pte_count = rem_bytes / PG_SIZE4K;
- rem_bytes_l2 = pte_count * PG_SIZE4K;
-
- /*
- * Unmap the VA space on this L2 PT. A quicker way
- * would be to clear pte_count entries starting from
- * pte_addr_l2. However, below code checks that we don't
- * clear invalid entries or less than 64KB for a 64KB
- * entry. Similar checking is done for L1 PTEs too
- * below
- */
- while (rem_bytes_l2 && !status) {
- pte_val = *(u32 *) pte_addr_l2;
- pte_size = hw_mmu_pte_size_l2(pte_val);
- /* va_curr aligned to pte_size? */
- if (pte_size == 0 || rem_bytes_l2 < pte_size ||
- va_curr & (pte_size - 1)) {
- status = -EPERM;
- break;
- }
-
- /* Collect Physical addresses from VA */
- paddr = (pte_val & ~(pte_size - 1));
- if (pte_size == HW_PAGE_SIZE64KB)
- numof4k_pages = 16;
- else
- numof4k_pages = 1;
- temp = 0;
- while (temp++ < numof4k_pages) {
- if (!pfn_valid(__phys_to_pfn(paddr))) {
- paddr += HW_PAGE_SIZE4KB;
- continue;
- }
- pg = PHYS_TO_PAGE(paddr);
- if (page_count(pg) < 1) {
- pr_info("DSPBRIDGE: UNMAP function: "
- "COUNT 0 FOR PA 0x%x, size = "
- "0x%x\n", paddr, ul_num_bytes);
- bad_page_dump(paddr, pg);
- } else {
- set_page_dirty(pg);
- page_cache_release(pg);
- }
- paddr += HW_PAGE_SIZE4KB;
- }
- if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) {
- status = -EPERM;
- goto EXIT_LOOP;
- }
-
- status = 0;
- rem_bytes_l2 -= pte_size;
- va_curr += pte_size;
- pte_addr_l2 += (pte_size >> 12) * sizeof(u32);
- }
- spin_lock(&pt->pg_lock);
- if (rem_bytes_l2 == 0) {
- pt->pg_info[l2_page_num].num_entries -= pte_count;
- if (pt->pg_info[l2_page_num].num_entries == 0) {
- /*
- * Clear the L1 PTE pointing to the L2 PT
- */
- if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig,
- HW_MMU_COARSE_PAGE_SIZE))
- status = 0;
- else {
- status = -EPERM;
- spin_unlock(&pt->pg_lock);
- goto EXIT_LOOP;
- }
- }
- rem_bytes -= pte_count * PG_SIZE4K;
- } else
- status = -EPERM;
-
- spin_unlock(&pt->pg_lock);
- continue;
-skip_coarse_page:
- /* va_curr aligned to pte_size? */
- /* pte_size = 1 MB or 16 MB */
- if (pte_size == 0 || rem_bytes < pte_size ||
- va_curr & (pte_size - 1)) {
- status = -EPERM;
- break;
- }
-
- if (pte_size == HW_PAGE_SIZE1MB)
- numof4k_pages = 256;
- else
- numof4k_pages = 4096;
- temp = 0;
- /* Collect Physical addresses from VA */
- paddr = (pte_val & ~(pte_size - 1));
- while (temp++ < numof4k_pages) {
- if (pfn_valid(__phys_to_pfn(paddr))) {
- pg = PHYS_TO_PAGE(paddr);
- if (page_count(pg) < 1) {
- pr_info("DSPBRIDGE: UNMAP function: "
- "COUNT 0 FOR PA 0x%x, size = "
- "0x%x\n", paddr, ul_num_bytes);
- bad_page_dump(paddr, pg);
- } else {
- set_page_dirty(pg);
- page_cache_release(pg);
- }
- }
- paddr += HW_PAGE_SIZE4KB;
- }
- if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) {
- status = 0;
- rem_bytes -= pte_size;
- va_curr += pte_size;
- } else {
- status = -EPERM;
- goto EXIT_LOOP;
- }
- }
- /*
- * It is better to flush the TLB here, so that any stale old entries
- * get flushed
- */
-EXIT_LOOP:
- flush_all(dev_context);
- dev_dbg(bridge,
- "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x,"
- " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1,
- pte_addr_l2, rem_bytes, rem_bytes_l2, status);
- return status;
-}
-
-/*
- * ======== user_va2_pa ========
- * Purpose:
- * This function walks through the page tables to convert a userland
- * virtual address to physical address
- */
-static u32 user_va2_pa(struct mm_struct *mm, u32 address)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *ptep, pte;
-
- pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || pgd_bad(*pgd))
- return 0;
-
- pud = pud_offset(pgd, address);
- if (pud_none(*pud) || pud_bad(*pud))
- return 0;
-
- pmd = pmd_offset(pud, address);
- if (pmd_none(*pmd) || pmd_bad(*pmd))
- return 0;
-
- ptep = pte_offset_map(pmd, address);
- if (ptep) {
- pte = *ptep;
- if (pte_present(pte))
- return pte & PAGE_MASK;
- }
-
- return 0;
-}
-
-/*
- * ======== pte_update ========
- * This function calculates the optimum page-aligned addresses and sizes
- * Caller must pass page-aligned values
- */
-static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa,
- u32 va, u32 size,
- struct hw_mmu_map_attrs_t *map_attrs)
-{
- u32 i;
- u32 all_bits;
- u32 pa_curr = pa;
- u32 va_curr = va;
- u32 num_bytes = size;
- struct bridge_dev_context *dev_context = dev_ctxt;
- int status = 0;
- u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB,
- HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB
- };
-
- while (num_bytes && !status) {
- /* To find the max. page size with which both PA & VA are
- * aligned */
- all_bits = pa_curr | va_curr;
-
- for (i = 0; i < 4; i++) {
- if ((num_bytes >= page_size[i]) && ((all_bits &
- (page_size[i] -
- 1)) == 0)) {
- status =
- pte_set(dev_context->pt_attrs, pa_curr,
- va_curr, page_size[i], map_attrs);
- pa_curr += page_size[i];
- va_curr += page_size[i];
- num_bytes -= page_size[i];
- /* Don't try smaller sizes. Hopefully we have
- * reached an address aligned to a bigger page
- * size */
- break;
- }
- }
- }
-
- return status;
-}
-
-/*
- * ======== pte_set ========
- * This function calculates PTE address (MPU virtual) to be updated
- * It also manages the L2 page tables
- */
-static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va,
- u32 size, struct hw_mmu_map_attrs_t *attrs)
-{
- u32 i;
- u32 pte_val;
- u32 pte_addr_l1;
- u32 pte_size;
- /* Base address of the PT that will be updated */
- u32 pg_tbl_va;
- u32 l1_base_va;
- /* Compiler warns that the next three variables might be used
- * uninitialized in this function. Doesn't seem so. Working around,
- * anyways. */
- u32 l2_base_va = 0;
- u32 l2_base_pa = 0;
- u32 l2_page_num = 0;
- int status = 0;
-
- l1_base_va = pt->l1_base_va;
- pg_tbl_va = l1_base_va;
- if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) {
- /* Find whether the L1 PTE points to a valid L2 PT */
- pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va);
- if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) {
- pte_val = *(u32 *) pte_addr_l1;
- pte_size = hw_mmu_pte_size_l1(pte_val);
- } else {
- return -EPERM;
- }
- spin_lock(&pt->pg_lock);
- if (pte_size == HW_MMU_COARSE_PAGE_SIZE) {
- /* Get the L2 PA from the L1 PTE, and find
- * corresponding L2 VA */
- l2_base_pa = hw_mmu_pte_coarse_l1(pte_val);
- l2_base_va =
- l2_base_pa - pt->l2_base_pa + pt->l2_base_va;
- l2_page_num =
- (l2_base_pa -
- pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE;
- } else if (pte_size == 0) {
- /* L1 PTE is invalid. Allocate a L2 PT and
- * point the L1 PTE to it */
- /* Find a free L2 PT. */
- for (i = 0; (i < pt->l2_num_pages) &&
- (pt->pg_info[i].num_entries != 0); i++)
- ;
- if (i < pt->l2_num_pages) {
- l2_page_num = i;
- l2_base_pa = pt->l2_base_pa + (l2_page_num *
- HW_MMU_COARSE_PAGE_SIZE);
- l2_base_va = pt->l2_base_va + (l2_page_num *
- HW_MMU_COARSE_PAGE_SIZE);
- /* Endianness attributes are ignored for
- * HW_MMU_COARSE_PAGE_SIZE */
- status =
- hw_mmu_pte_set(l1_base_va, l2_base_pa, va,
- HW_MMU_COARSE_PAGE_SIZE,
- attrs);
- } else {
- status = -ENOMEM;
- }
- } else {
- /* Found valid L1 PTE of another size.
- * Should not overwrite it. */
- status = -EPERM;
- }
- if (!status) {
- pg_tbl_va = l2_base_va;
- if (size == HW_PAGE_SIZE64KB)
- pt->pg_info[l2_page_num].num_entries += 16;
- else
- pt->pg_info[l2_page_num].num_entries++;
- dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum "
- "%x, num_entries %x\n", l2_base_va,
- l2_base_pa, l2_page_num,
- pt->pg_info[l2_page_num].num_entries);
- }
- spin_unlock(&pt->pg_lock);
- }
- if (!status) {
- dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n",
- pg_tbl_va, pa, va, size);
- dev_dbg(bridge, "PTE: endianism %x, element_size %x, "
- "mixed_size %x\n", attrs->endianism,
- attrs->element_size, attrs->mixed_size);
- status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs);
- }
-
- return status;
-}
-
-/* Memory map kernel VA -- memory allocated with vmalloc */
-static int mem_map_vmalloc(struct bridge_dev_context *dev_context,
- u32 ul_mpu_addr, u32 virt_addr,
- u32 ul_num_bytes,
- struct hw_mmu_map_attrs_t *hw_attrs)
-{
- int status = 0;
- struct page *page[1];
- u32 i;
- u32 pa_curr;
- u32 pa_next;
- u32 va_curr;
- u32 size_curr;
- u32 num_pages;
- u32 pa;
- u32 num_of4k_pages;
- u32 temp = 0;
-
- /*
- * Do Kernel va to pa translation.
- * Combine physically contiguous regions to reduce TLBs.
- * Pass the translated pa to pte_update.
- */
- num_pages = ul_num_bytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */
- i = 0;
- va_curr = ul_mpu_addr;
- page[0] = vmalloc_to_page((void *)va_curr);
- pa_next = page_to_phys(page[0]);
- while (!status && (i < num_pages)) {
- /*
- * Reuse pa_next from the previous iteration to avoid
- * an extra va2pa call
- */
- pa_curr = pa_next;
- size_curr = PAGE_SIZE;
- /*
- * If the next page is physically contiguous,
- * map it with the current one by increasing
- * the size of the region to be mapped
- */
- while (++i < num_pages) {
- page[0] =
- vmalloc_to_page((void *)(va_curr + size_curr));
- pa_next = page_to_phys(page[0]);
-
- if (pa_next == (pa_curr + size_curr))
- size_curr += PAGE_SIZE;
- else
- break;
-
- }
- if (pa_next == 0) {
- status = -ENOMEM;
- break;
- }
- pa = pa_curr;
- num_of4k_pages = size_curr / HW_PAGE_SIZE4KB;
- while (temp++ < num_of4k_pages) {
- get_page(PHYS_TO_PAGE(pa));
- pa += HW_PAGE_SIZE4KB;
- }
- status = pte_update(dev_context, pa_curr, virt_addr +
- (va_curr - ul_mpu_addr), size_curr,
- hw_attrs);
- va_curr += size_curr;
- }
- /*
- * In any case, flush the TLB
- * This is called from here instead from pte_update to avoid unnecessary
- * repetition while mapping non-contiguous physical regions of a virtual
- * region
- */
- flush_all(dev_context);
- dev_dbg(bridge, "%s status %x\n", __func__, status);
- return status;
-}
-
-/*
- * ======== wait_for_start ========
- * Wait for the singal from DSP that it has started, or time out.
- */
-bool wait_for_start(struct bridge_dev_context *dev_context,
- void __iomem *sync_addr)
-{
- u16 timeout = TIHELEN_ACKTIMEOUT;
-
- /* Wait for response from board */
- while (__raw_readw(sync_addr) && --timeout)
- udelay(10);
-
- /* If timed out: return false */
- if (!timeout) {
- pr_err("%s: Timed out waiting DSP to Start\n", __func__);
- return false;
- }
- return true;
-}
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
deleted file mode 100644
index 657104f37f7d..000000000000
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * tiomap_pwr.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation of DSP wake/sleep routines.
- *
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-#include <linux/platform_data/dsp-omap.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/io_sm.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/brddefs.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/io.h>
-
-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
-#include <dspbridge/pwr.h>
-
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/wdt.h>
-
-/* ----------------------------------- specific to this file */
-#include "_tiomap.h"
-#include "_tiomap_pwr.h"
-#include <mach-omap2/prm-regbits-34xx.h>
-#include <mach-omap2/cm-regbits-34xx.h>
-
-#define PWRSTST_TIMEOUT 200
-
-/*
- * ======== handle_constraints_set ========
- * Sets new DSP constraint
- */
-int handle_constraints_set(struct bridge_dev_context *dev_context,
- void *pargs)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 *constraint_val;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- constraint_val = (u32 *) (pargs);
- /* Read the target value requested by DSP */
- dev_dbg(bridge, "OPP: %s opp requested = 0x%x\n", __func__,
- (u32) *(constraint_val + 1));
-
- /* Set the new opp value */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) ((u32) *(constraint_val + 1));
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return 0;
-}
-
-/*
- * ======== handle_hibernation_from_dsp ========
- * Handle Hibernation requested from DSP
- */
-int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context)
-{
- int status = 0;
-#ifdef CONFIG_PM
- u16 timeout = PWRSTST_TIMEOUT / 10;
- u32 pwr_state;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 opplevel;
- struct io_mgr *hio_mgr;
-#endif
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- /* Wait for DSP to move into OFF state */
- while ((pwr_state != PWRDM_POWER_OFF) && --timeout) {
- if (msleep_interruptible(10)) {
- pr_err("Waiting for DSP OFF mode interrupted\n");
- return -EPERM;
- }
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
- OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- }
- if (timeout == 0) {
- pr_err("%s: Timed out waiting for DSP off mode\n", __func__);
- status = -ETIMEDOUT;
- return status;
- } else {
-
- /* Save mailbox settings */
- omap_mbox_save_ctx(dev_context->mbox);
-
- /* Turn off DSP Peripheral clocks and DSP Load monitor timer */
- status = dsp_clock_disable_all(dev_context->dsp_per_clks);
-
- /* Disable wdt on hibernation. */
- dsp_wdt_enable(false);
-
- if (!status) {
- /* Update the Bridger Driver state */
- dev_context->brd_state = BRD_DSP_HIBERNATION;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- status =
- dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
- if (!hio_mgr) {
- status = DSP_EHANDLE;
- return status;
- }
- io_sh_msetting(hio_mgr, SHM_GETOPP, &opplevel);
-
- /*
- * Set the OPP to low level before moving to OFF
- * mode
- */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) (VDD1_OPP1);
- status = 0;
-#endif /* CONFIG_TIDSPBRIDGE_DVFS */
- }
- }
-#endif
- return status;
-}
-
-/*
- * ======== sleep_dsp ========
- * Put DSP in low power consuming state.
- */
-int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd,
- void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_PM
-#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
- struct deh_mgr *hdeh_mgr;
-#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
- u16 timeout = PWRSTST_TIMEOUT / 10;
- u32 pwr_state, target_pwr_state;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- /* Check if sleep code is valid */
- if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP))
- return -EINVAL;
-
- switch (dev_context->brd_state) {
- case BRD_RUNNING:
- omap_mbox_save_ctx(dev_context->mbox);
- if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
- dev_dbg(bridge, "PM: %s - sent hibernate cmd to DSP\n",
- __func__);
- target_pwr_state = PWRDM_POWER_OFF;
- } else {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPRETENTION);
- target_pwr_state = PWRDM_POWER_RET;
- }
- break;
- case BRD_RETENTION:
- omap_mbox_save_ctx(dev_context->mbox);
- if (dsp_test_sleepstate == PWRDM_POWER_OFF) {
- sm_interrupt_dsp(dev_context, MBX_PM_DSPHIBERNATE);
- target_pwr_state = PWRDM_POWER_OFF;
- } else
- return 0;
- break;
- case BRD_HIBERNATION:
- case BRD_DSP_HIBERNATION:
- /* Already in Hibernation, so just return */
- dev_dbg(bridge, "PM: %s - DSP already in hibernation\n",
- __func__);
- return 0;
- case BRD_STOPPED:
- dev_dbg(bridge, "PM: %s - Board in STOP state\n", __func__);
- return 0;
- default:
- dev_dbg(bridge, "PM: %s - Bridge in Illegal state\n", __func__);
- return -EPERM;
- }
-
- /* Get the PRCM DSP power domain status */
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD, OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
-
- /* Wait for DSP to move into target power state */
- while ((pwr_state != target_pwr_state) && --timeout) {
- if (msleep_interruptible(10)) {
- pr_err("Waiting for DSP to Suspend interrupted\n");
- return -EPERM;
- }
- pwr_state = (*pdata->dsp_prm_read)(OMAP3430_IVA2_MOD,
- OMAP2_PM_PWSTST) &
- OMAP_POWERSTATEST_MASK;
- }
-
- if (!timeout) {
- pr_err("%s: Timed out waiting for DSP off mode, state %x\n",
- __func__, pwr_state);
-#ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR
- dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr);
- bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0);
-#endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */
- return -ETIMEDOUT;
- } else {
- /* Update the Bridger Driver state */
- if (dsp_test_sleepstate == PWRDM_POWER_OFF)
- dev_context->brd_state = BRD_HIBERNATION;
- else
- dev_context->brd_state = BRD_RETENTION;
-
- /* Disable wdt on hibernation. */
- dsp_wdt_enable(false);
-
- /* Turn off DSP Peripheral clocks */
- status = dsp_clock_disable_all(dev_context->dsp_per_clks);
- if (status)
- return status;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- else if (target_pwr_state == PWRDM_POWER_OFF) {
- /*
- * Set the OPP to low level before moving to OFF mode
- */
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) (VDD1_OPP1);
- }
-#endif /* CONFIG_TIDSPBRIDGE_DVFS */
- }
-#endif /* CONFIG_PM */
- return status;
-}
-
-/*
- * ======== wake_dsp ========
- * Wake up DSP from sleep.
- */
-int wake_dsp(struct bridge_dev_context *dev_context, void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_PM
-
- /* Check the board state, if it is not 'SLEEP' then return */
- if (dev_context->brd_state == BRD_RUNNING ||
- dev_context->brd_state == BRD_STOPPED) {
- /* The Device is in 'RET' or 'OFF' state and Bridge state is not
- * 'SLEEP', this means state inconsistency, so return */
- return 0;
- }
-
- /* Send a wakeup message to DSP */
- sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP);
-
- /* Set the device state to RUNNIG */
- dev_context->brd_state = BRD_RUNNING;
-#endif /* CONFIG_PM */
- return status;
-}
-
-/*
- * ======== dsp_peripheral_clk_ctrl ========
- * Enable/Disable the DSP peripheral clocks as needed..
- */
-int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context,
- void *pargs)
-{
- u32 ext_clk = 0;
- u32 ext_clk_id = 0;
- u32 ext_clk_cmd = 0;
- u32 clk_id_index = MBX_PM_MAX_RESOURCES;
- u32 tmp_index;
- u32 dsp_per_clks_before;
- int status = 0;
-
- dsp_per_clks_before = dev_context->dsp_per_clks;
-
- ext_clk = (u32) *((u32 *) pargs);
- ext_clk_id = ext_clk & MBX_PM_CLK_IDMASK;
-
- /* process the power message -- TODO, keep it in a separate function */
- for (tmp_index = 0; tmp_index < MBX_PM_MAX_RESOURCES; tmp_index++) {
- if (ext_clk_id == bpwr_clkid[tmp_index]) {
- clk_id_index = tmp_index;
- break;
- }
- }
- /* TODO -- Assert may be a too hard restriction here.. May be we should
- * just return with failure when the CLK ID does not match */
- if (clk_id_index == MBX_PM_MAX_RESOURCES) {
- /* return with a more meaningfull error code */
- return -EPERM;
- }
- ext_clk_cmd = (ext_clk >> MBX_PM_CLK_CMDSHIFT) & MBX_PM_CLK_CMDMASK;
- switch (ext_clk_cmd) {
- case BPWR_DISABLE_CLOCK:
- status = dsp_clk_disable(bpwr_clks[clk_id_index].clk);
- dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id,
- false);
- if (!status) {
- (dev_context->dsp_per_clks) &=
- (~((u32) (1 << bpwr_clks[clk_id_index].clk)));
- }
- break;
- case BPWR_ENABLE_CLOCK:
- status = dsp_clk_enable(bpwr_clks[clk_id_index].clk);
- dsp_clk_wakeup_event_ctrl(bpwr_clks[clk_id_index].clk_id, true);
- if (!status)
- (dev_context->dsp_per_clks) |=
- (1 << bpwr_clks[clk_id_index].clk);
- break;
- default:
- dev_dbg(bridge, "%s: Unsupported CMD\n", __func__);
- /* unsupported cmd */
- /* TODO -- provide support for AUTOIDLE Enable/Disable
- * commands */
- }
- return status;
-}
-
-/*
- * ========pre_scale_dsp========
- * Sends prescale notification to DSP
- *
- */
-int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 level;
- u32 voltage_domain;
-
- voltage_domain = *((u32 *) pargs);
- level = *((u32 *) pargs + 1);
-
- dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
- __func__, voltage_domain, level);
- if ((dev_context->brd_state == BRD_HIBERNATION) ||
- (dev_context->brd_state == BRD_RETENTION) ||
- (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
- dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n");
- return 0;
- } else if (dev_context->brd_state == BRD_RUNNING) {
- /* Send a prenotification to DSP */
- dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__);
- sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY);
- return 0;
- } else {
- return -EPERM;
- }
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return 0;
-}
-
-/*
- * ========post_scale_dsp========
- * Sends postscale notification to DSP
- *
- */
-int post_scale_dsp(struct bridge_dev_context *dev_context,
- void *pargs)
-{
- int status = 0;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 level;
- u32 voltage_domain;
- struct io_mgr *hio_mgr;
-
- status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr);
- if (!hio_mgr)
- return -EFAULT;
-
- voltage_domain = *((u32 *) pargs);
- level = *((u32 *) pargs + 1);
- dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n",
- __func__, voltage_domain, level);
- if ((dev_context->brd_state == BRD_HIBERNATION) ||
- (dev_context->brd_state == BRD_RETENTION) ||
- (dev_context->brd_state == BRD_DSP_HIBERNATION)) {
- /* Update the OPP value in shared memory */
- io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
- dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n",
- __func__);
- } else if (dev_context->brd_state == BRD_RUNNING) {
- /* Update the OPP value in shared memory */
- io_sh_msetting(hio_mgr, SHM_CURROPP, &level);
- /* Send a post notification to DSP */
- sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_POSTNOTIFY);
- dev_dbg(bridge,
- "OPP: %s wrote to shm. Sent post notification to DSP\n",
- __func__);
- } else {
- status = -EPERM;
- }
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
- return status;
-}
-
-void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable)
-{
- struct cfg_hostres *resources;
- int status = 0;
- u32 iva2_grpsel;
- u32 mpu_grpsel;
- struct dev_object *hdev_object = NULL;
- struct bridge_dev_context *bridge_context = NULL;
-
- hdev_object = (struct dev_object *)drv_get_first_dev_object();
- if (!hdev_object)
- return;
-
- status = dev_get_bridge_context(hdev_object, &bridge_context);
- if (!bridge_context)
- return;
-
- resources = bridge_context->resources;
- if (!resources)
- return;
-
- switch (clock_id) {
- case BPWR_GP_TIMER5:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER6:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER7:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_GP_TIMER8:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP1:
- iva2_grpsel = readl(resources->core_pm_base + 0xA8);
- mpu_grpsel = readl(resources->core_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK;
- }
- writel(iva2_grpsel, resources->core_pm_base + 0xA8);
- writel(mpu_grpsel, resources->core_pm_base + 0xA4);
- break;
- case BPWR_MCBSP2:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP3:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP4:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- case BPWR_MCBSP5:
- iva2_grpsel = readl(resources->per_pm_base + 0xA8);
- mpu_grpsel = readl(resources->per_pm_base + 0xA4);
- if (enable) {
- iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
- mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
- } else {
- mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK;
- iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK;
- }
- writel(iva2_grpsel, resources->per_pm_base + 0xA8);
- writel(mpu_grpsel, resources->per_pm_base + 0xA4);
- break;
- }
-}
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
deleted file mode 100644
index f53ed98d18c1..000000000000
--- a/drivers/staging/tidspbridge/core/tiomap_io.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * tiomap_io.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation for the io read/write routines.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/platform_data/dsp-omap.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/drv.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/wdt.h>
-
-/* ----------------------------------- specific to this file */
-#include "_tiomap.h"
-#include "_tiomap_pwr.h"
-#include "tiomap_io.h"
-
-static u32 ul_ext_base;
-static u32 ul_ext_end;
-
-static u32 shm0_end;
-static u32 ul_dyn_ext_base;
-static u32 ul_trace_sec_beg;
-static u32 ul_trace_sec_end;
-static u32 ul_shm_base_virt;
-
-bool symbols_reloaded = true;
-
-/*
- * ======== read_ext_dsp_data ========
- * Copies DSP external memory buffers to the host side buffers.
- */
-int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type)
-{
- int status = 0;
- struct bridge_dev_context *dev_context = dev_ctxt;
- u32 offset;
- u32 ul_tlb_base_virt = 0;
- u32 ul_shm_offset_virt = 0;
- u32 dw_ext_prog_virt_mem;
- u32 dw_base_addr = dev_context->dsp_ext_base_addr;
- bool trace_read = false;
-
- if (!ul_shm_base_virt) {
- status = dev_get_symbol(dev_context->dev_obj,
- SHMBASENAME, &ul_shm_base_virt);
- }
-
- /* Check if it is a read of Trace section */
- if (!status && !ul_trace_sec_beg) {
- status = dev_get_symbol(dev_context->dev_obj,
- DSP_TRACESEC_BEG, &ul_trace_sec_beg);
- }
-
- if (!status && !ul_trace_sec_end) {
- status = dev_get_symbol(dev_context->dev_obj,
- DSP_TRACESEC_END, &ul_trace_sec_end);
- }
-
- if (!status) {
- if ((dsp_addr <= ul_trace_sec_end) &&
- (dsp_addr >= ul_trace_sec_beg))
- trace_read = true;
- }
-
- /* If reading from TRACE, force remap/unmap */
- if (trace_read && dw_base_addr) {
- dw_base_addr = 0;
- dev_context->dsp_ext_base_addr = 0;
- }
-
- if (!dw_base_addr) {
- /* Initialize ul_ext_base and ul_ext_end */
- ul_ext_base = 0;
- ul_ext_end = 0;
-
- /* Get DYNEXT_BEG, EXT_BEG and EXT_END. */
- if (!status && !ul_dyn_ext_base) {
- status = dev_get_symbol(dev_context->dev_obj,
- DYNEXTBASE, &ul_dyn_ext_base);
- }
-
- if (!status) {
- status = dev_get_symbol(dev_context->dev_obj,
- EXTBASE, &ul_ext_base);
- }
-
- if (!status) {
- status = dev_get_symbol(dev_context->dev_obj,
- EXTEND, &ul_ext_end);
- }
-
- /* Trace buffer is right after the shm SEG0,
- * so set the base address to SHMBASE */
- if (trace_read) {
- ul_ext_base = ul_shm_base_virt;
- ul_ext_end = ul_trace_sec_end;
- }
-
-
- if (ul_ext_end < ul_ext_base)
- status = -EPERM;
-
- if (!status) {
- ul_tlb_base_virt =
- dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
- dw_ext_prog_virt_mem =
- dev_context->atlb_entry[0].gpp_va;
-
- if (!trace_read) {
- ul_shm_offset_virt =
- ul_shm_base_virt - ul_tlb_base_virt;
- ul_shm_offset_virt +=
- PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base +
- 1, HW_PAGE_SIZE64KB);
- dw_ext_prog_virt_mem -= ul_shm_offset_virt;
- dw_ext_prog_virt_mem +=
- (ul_ext_base - ul_dyn_ext_base);
- dev_context->dsp_ext_base_addr =
- dw_ext_prog_virt_mem;
-
- /*
- * This dsp_ext_base_addr will get cleared
- * only when the board is stopped.
- */
- if (!dev_context->dsp_ext_base_addr)
- status = -EPERM;
- }
-
- dw_base_addr = dw_ext_prog_virt_mem;
- }
- }
-
- if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
- status = -EPERM;
-
- offset = dsp_addr - ul_ext_base;
-
- if (!status)
- memcpy(host_buff, (u8 *) dw_base_addr + offset, ul_num_bytes);
-
- return status;
-}
-
-/*
- * ======== write_dsp_data ========
- * purpose:
- * Copies buffers to the DSP internal/external memory.
- */
-int write_dsp_data(struct bridge_dev_context *dev_context,
- u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes,
- u32 mem_type)
-{
- u32 offset;
- u32 dw_base_addr = dev_context->dsp_base_addr;
- struct cfg_hostres *resources = dev_context->resources;
- int status = 0;
- u32 base1, base2, base3;
- base1 = OMAP_DSP_MEM1_SIZE;
- base2 = OMAP_DSP_MEM2_BASE - OMAP_DSP_MEM1_BASE;
- base3 = OMAP_DSP_MEM3_BASE - OMAP_DSP_MEM1_BASE;
-
- if (!resources)
- return -EPERM;
-
- offset = dsp_addr - dev_context->dsp_start_add;
- if (offset < base1) {
- dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[2],
- resources->mem_length[2]);
- } else if (offset > base1 && offset < base2 + OMAP_DSP_MEM2_SIZE) {
- dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[3],
- resources->mem_length[3]);
- offset = offset - base2;
- } else if (offset >= base2 + OMAP_DSP_MEM2_SIZE &&
- offset < base3 + OMAP_DSP_MEM3_SIZE) {
- dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[4],
- resources->mem_length[4]);
- offset = offset - base3;
- } else {
- return -EPERM;
- }
- if (ul_num_bytes)
- memcpy((u8 *) (dw_base_addr + offset), host_buff, ul_num_bytes);
- else
- *((u32 *) host_buff) = dw_base_addr + offset;
-
- return status;
-}
-
-/*
- * ======== write_ext_dsp_data ========
- * purpose:
- * Copies buffers to the external memory.
- *
- */
-int write_ext_dsp_data(struct bridge_dev_context *dev_context,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type,
- bool dynamic_load)
-{
- u32 dw_base_addr = dev_context->dsp_ext_base_addr;
- u32 dw_offset = 0;
- u8 temp_byte1, temp_byte2;
- u8 remain_byte[4];
- s32 i;
- int ret = 0;
- u32 dw_ext_prog_virt_mem;
- u32 ul_tlb_base_virt = 0;
- u32 ul_shm_offset_virt = 0;
- struct cfg_hostres *host_res = dev_context->resources;
- bool trace_load = false;
- temp_byte1 = 0x0;
- temp_byte2 = 0x0;
-
- if (symbols_reloaded) {
- /* Check if it is a load to Trace section */
- ret = dev_get_symbol(dev_context->dev_obj,
- DSP_TRACESEC_BEG, &ul_trace_sec_beg);
- if (!ret)
- ret = dev_get_symbol(dev_context->dev_obj,
- DSP_TRACESEC_END,
- &ul_trace_sec_end);
- }
- if (!ret) {
- if ((dsp_addr <= ul_trace_sec_end) &&
- (dsp_addr >= ul_trace_sec_beg))
- trace_load = true;
- }
-
- /* If dynamic, force remap/unmap */
- if ((dynamic_load || trace_load) && dw_base_addr) {
- dw_base_addr = 0;
- MEM_UNMAP_LINEAR_ADDRESS((void *)
- dev_context->dsp_ext_base_addr);
- dev_context->dsp_ext_base_addr = 0x0;
- }
- if (!dw_base_addr) {
- if (symbols_reloaded)
- /* Get SHM_BEG EXT_BEG and EXT_END. */
- ret = dev_get_symbol(dev_context->dev_obj,
- SHMBASENAME, &ul_shm_base_virt);
- if (dynamic_load) {
- if (!ret) {
- if (symbols_reloaded)
- ret =
- dev_get_symbol
- (dev_context->dev_obj, DYNEXTBASE,
- &ul_ext_base);
- }
- if (!ret) {
- /* DR OMAPS00013235 : DLModules array may be
- * in EXTMEM. It is expected that DYNEXTMEM and
- * EXTMEM are contiguous, so checking for the
- * upper bound at EXTEND should be Ok. */
- if (symbols_reloaded)
- ret =
- dev_get_symbol
- (dev_context->dev_obj, EXTEND,
- &ul_ext_end);
- }
- } else {
- if (symbols_reloaded) {
- if (!ret)
- ret =
- dev_get_symbol
- (dev_context->dev_obj, EXTBASE,
- &ul_ext_base);
- if (!ret)
- ret =
- dev_get_symbol
- (dev_context->dev_obj, EXTEND,
- &ul_ext_end);
- }
- }
- /* Trace buffer it right after the shm SEG0, so set the
- * base address to SHMBASE */
- if (trace_load)
- ul_ext_base = ul_shm_base_virt;
-
- if (ul_ext_end < ul_ext_base)
- ret = -EPERM;
-
- if (!ret) {
- ul_tlb_base_virt =
- dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
-
- if (symbols_reloaded) {
- ret = dev_get_symbol
- (dev_context->dev_obj,
- DSP_TRACESEC_END, &shm0_end);
- if (!ret) {
- ret =
- dev_get_symbol
- (dev_context->dev_obj, DYNEXTBASE,
- &ul_dyn_ext_base);
- }
- }
- ul_shm_offset_virt =
- ul_shm_base_virt - ul_tlb_base_virt;
- if (trace_load) {
- dw_ext_prog_virt_mem =
- dev_context->atlb_entry[0].gpp_va;
- } else {
- dw_ext_prog_virt_mem = host_res->mem_base[1];
- dw_ext_prog_virt_mem +=
- (ul_ext_base - ul_dyn_ext_base);
- }
-
- dev_context->dsp_ext_base_addr =
- (u32) MEM_LINEAR_ADDRESS((void *)
- dw_ext_prog_virt_mem,
- ul_ext_end - ul_ext_base);
- dw_base_addr += dev_context->dsp_ext_base_addr;
- /* This dsp_ext_base_addr will get cleared only when
- * the board is stopped. */
- if (!dev_context->dsp_ext_base_addr)
- ret = -EPERM;
- }
- }
- if (!dw_base_addr || !ul_ext_base || !ul_ext_end)
- ret = -EPERM;
-
- if (!ret) {
- for (i = 0; i < 4; i++)
- remain_byte[i] = 0x0;
-
- dw_offset = dsp_addr - ul_ext_base;
- /* Also make sure the dsp_addr is < ul_ext_end */
- if (dsp_addr > ul_ext_end || dw_offset > dsp_addr)
- ret = -EPERM;
- }
- if (!ret) {
- if (ul_num_bytes)
- memcpy((u8 *) dw_base_addr + dw_offset, host_buff,
- ul_num_bytes);
- else
- *((u32 *) host_buff) = dw_base_addr + dw_offset;
- }
- /* Unmap here to force remap for other Ext loads */
- if ((dynamic_load || trace_load) && dev_context->dsp_ext_base_addr) {
- MEM_UNMAP_LINEAR_ADDRESS((void *)
- dev_context->dsp_ext_base_addr);
- dev_context->dsp_ext_base_addr = 0x0;
- }
- symbols_reloaded = false;
- return ret;
-}
-
-int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val)
-{
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- u32 opplevel = 0;
-#endif
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
- struct cfg_hostres *resources = dev_context->resources;
- int status = 0;
- u32 temp;
-
- if (!dev_context->mbox)
- return 0;
-
- if (!resources)
- return -EPERM;
-
- if (dev_context->brd_state == BRD_DSP_HIBERNATION ||
- dev_context->brd_state == BRD_HIBERNATION) {
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- if (pdata->dsp_get_opp)
- opplevel = (*pdata->dsp_get_opp) ();
- if (opplevel == VDD1_OPP1) {
- if (pdata->dsp_set_min_opp)
- (*pdata->dsp_set_min_opp) (VDD1_OPP2);
- }
-#endif
- /* Restart the peripheral clocks */
- dsp_clock_enable_all(dev_context->dsp_per_clks);
- dsp_wdt_enable(true);
-
- /*
- * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
- * in CM_AUTOIDLE_PLL_IVA2 register
- */
- (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
- OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL);
-
- /*
- * 7:4 IVA2_DPLL_FREQSEL - IVA2 internal frq set to
- * 0.75 MHz - 1.0 MHz
- * 2:0 EN_IVA2_DPLL - Enable IVA2 DPLL in lock mode
- */
- (*pdata->dsp_cm_rmw_bits)(OMAP3430_IVA2_DPLL_FREQSEL_MASK |
- OMAP3430_EN_IVA2_DPLL_MASK,
- 0x3 << OMAP3430_IVA2_DPLL_FREQSEL_SHIFT |
- 0x7 << OMAP3430_EN_IVA2_DPLL_SHIFT,
- OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
-
- /* Restore mailbox settings */
- omap_mbox_restore_ctx(dev_context->mbox);
-
- /* Access MMU SYS CONFIG register to generate a short wakeup */
- temp = readl(resources->dmmu_base + 0x10);
-
- dev_context->brd_state = BRD_RUNNING;
- } else if (dev_context->brd_state == BRD_RETENTION) {
- /* Restart the peripheral clocks */
- dsp_clock_enable_all(dev_context->dsp_per_clks);
- }
-
- status = omap_mbox_msg_send(dev_context->mbox, mb_val);
-
- if (status) {
- pr_err("omap_mbox_msg_send Fail and status = %d\n", status);
- status = -EPERM;
- }
-
- return 0;
-}
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.h b/drivers/staging/tidspbridge/core/tiomap_io.h
deleted file mode 100644
index a3f19c7b79f3..000000000000
--- a/drivers/staging/tidspbridge/core/tiomap_io.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * tiomap_io.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Definitions, types and function prototypes for the io (r/w external mem).
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _TIOMAP_IO_
-#define _TIOMAP_IO_
-
-/*
- * Symbol that defines beginning of shared memory.
- * For OMAP (Helen) this is the DSP Virtual base address of SDRAM.
- * This will be used to program DSP MMU to map DSP Virt to GPP phys.
- * (see dspMmuTlbEntry()).
- */
-#define SHMBASENAME "SHM_BEG"
-#define EXTBASE "EXT_BEG"
-#define EXTEND "_EXT_END"
-#define DYNEXTBASE "_DYNEXT_BEG"
-#define DYNEXTEND "_DYNEXT_END"
-#define IVAEXTMEMBASE "_IVAEXTMEM_BEG"
-#define IVAEXTMEMEND "_IVAEXTMEM_END"
-
-#define DSP_TRACESEC_BEG "_BRIDGE_TRACE_BEG"
-#define DSP_TRACESEC_END "_BRIDGE_TRACE_END"
-
-#define SYS_PUTCBEG "_SYS_PUTCBEG"
-#define SYS_PUTCEND "_SYS_PUTCEND"
-#define BRIDGE_SYS_PUTC_CURRENT "_BRIDGE_SYS_PUTC_current"
-
-#define WORDSWAP_ENABLE 0x3 /* Enable word swap */
-
-/*
- * ======== read_ext_dsp_data ========
- * Reads it from DSP External memory. The external memory for the DSP
- * is configured by the combination of DSP MMU and shm Memory manager in the CDB
- */
-extern int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type);
-
-/*
- * ======== write_dsp_data ========
- */
-extern int write_dsp_data(struct bridge_dev_context *dev_context,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type);
-
-/*
- * ======== write_ext_dsp_data ========
- * Writes to the DSP External memory for external program.
- * The ext mem for progra is configured by the combination of DSP MMU and
- * shm Memory manager in the CDB
- */
-extern int write_ext_dsp_data(struct bridge_dev_context *dev_context,
- u8 *host_buff, u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type,
- bool dynamic_load);
-
-/*
- * ======== write_ext32_bit_dsp_data ========
- * Writes 32 bit data to the external memory
- */
-extern inline void write_ext32_bit_dsp_data(const
- struct bridge_dev_context *dev_context,
- u32 dsp_addr, u32 val)
-{
- *(u32 *) dsp_addr = ((dev_context->tc_word_swap_on) ? (((val << 16) &
- 0xFFFF0000) |
- ((val >> 16) &
- 0x0000FFFF)) :
- val);
-}
-
-/*
- * ======== read_ext32_bit_dsp_data ========
- * Reads 32 bit data from the external memory
- */
-extern inline u32 read_ext32_bit_dsp_data(const struct bridge_dev_context
- *dev_context, u32 dsp_addr)
-{
- u32 ret;
- ret = *(u32 *) dsp_addr;
-
- ret = ((dev_context->tc_word_swap_on) ? (((ret << 16)
- & 0xFFFF0000) | ((ret >> 16) &
- 0x0000FFFF))
- : ret);
- return ret;
-}
-
-#endif /* _TIOMAP_IO_ */
diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c
deleted file mode 100644
index e68f0ba8e12b..000000000000
--- a/drivers/staging/tidspbridge/core/ue_deh.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * ue_deh.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implements upper edge DSP exception handling (DEH) functions.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- * Copyright (C) 2010 Felipe Contreras
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/dev.h>
-#include "_tiomap.h"
-#include "_deh.h"
-
-#include <dspbridge/io_sm.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/wdt.h>
-
-static u32 fault_addr;
-
-static void mmu_fault_dpc(unsigned long data)
-{
- struct deh_mgr *deh = (void *)data;
-
- if (!deh)
- return;
-
- bridge_deh_notify(deh, DSP_MMUFAULT, 0);
-}
-
-static irqreturn_t mmu_fault_isr(int irq, void *data)
-{
- struct deh_mgr *deh = data;
- struct cfg_hostres *resources;
- u32 event;
-
- if (!deh)
- return IRQ_HANDLED;
-
- resources = deh->bridge_context->resources;
- if (!resources) {
- dev_dbg(bridge, "%s: Failed to get Host Resources\n",
- __func__);
- return IRQ_HANDLED;
- }
-
- hw_mmu_event_status(resources->dmmu_base, &event);
- if (event == HW_MMU_TRANSLATION_FAULT) {
- hw_mmu_fault_addr_read(resources->dmmu_base, &fault_addr);
- dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__,
- event, fault_addr);
- /*
- * Schedule a DPC directly. In the future, it may be
- * necessary to check if DSP MMU fault is intended for
- * Bridge.
- */
- tasklet_schedule(&deh->dpc_tasklet);
-
- /* Disable the MMU events, else once we clear it will
- * start to raise INTs again */
- hw_mmu_event_disable(resources->dmmu_base,
- HW_MMU_TRANSLATION_FAULT);
- } else {
- hw_mmu_event_disable(resources->dmmu_base,
- HW_MMU_ALL_INTERRUPTS);
- }
- return IRQ_HANDLED;
-}
-
-int bridge_deh_create(struct deh_mgr **ret_deh,
- struct dev_object *hdev_obj)
-{
- int status;
- struct deh_mgr *deh;
- struct bridge_dev_context *hbridge_context = NULL;
-
- /* Message manager will be created when a file is loaded, since
- * size of message buffer in shared memory is configurable in
- * the base image. */
- /* Get Bridge context info. */
- dev_get_bridge_context(hdev_obj, &hbridge_context);
- /* Allocate IO manager object: */
- deh = kzalloc(sizeof(*deh), GFP_KERNEL);
- if (!deh) {
- status = -ENOMEM;
- goto err;
- }
-
- /* Create an NTFY object to manage notifications */
- deh->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
- if (!deh->ntfy_obj) {
- status = -ENOMEM;
- goto err;
- }
- ntfy_init(deh->ntfy_obj);
-
- /* Create a MMUfault DPC */
- tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh);
-
- /* Fill in context structure */
- deh->bridge_context = hbridge_context;
-
- /* Install ISR function for DSP MMU fault */
- status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0,
- "DspBridge\tiommu fault", deh);
- if (status < 0)
- goto err;
-
- *ret_deh = deh;
- return 0;
-
-err:
- bridge_deh_destroy(deh);
- *ret_deh = NULL;
- return status;
-}
-
-int bridge_deh_destroy(struct deh_mgr *deh)
-{
- if (!deh)
- return -EFAULT;
-
- /* If notification object exists, delete it */
- if (deh->ntfy_obj) {
- ntfy_delete(deh->ntfy_obj);
- kfree(deh->ntfy_obj);
- }
- /* Disable DSP MMU fault */
- free_irq(INT_DSP_MMU_IRQ, deh);
-
- /* Free DPC object */
- tasklet_kill(&deh->dpc_tasklet);
-
- /* Deallocate the DEH manager object */
- kfree(deh);
-
- return 0;
-}
-
-int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask,
- u32 notify_type,
- struct dsp_notification *hnotification)
-{
- if (!deh)
- return -EFAULT;
-
- if (event_mask)
- return ntfy_register(deh->ntfy_obj, hnotification,
- event_mask, notify_type);
- else
- return ntfy_unregister(deh->ntfy_obj, hnotification);
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-static void mmu_fault_print_stack(struct bridge_dev_context *dev_context)
-{
- struct cfg_hostres *resources;
- struct hw_mmu_map_attrs_t map_attrs = {
- .endianism = HW_LITTLE_ENDIAN,
- .element_size = HW_ELEM_SIZE16BIT,
- .mixed_size = HW_MMU_CPUES,
- };
- void *dummy_va_addr;
-
- resources = dev_context->resources;
- dummy_va_addr = (void *)__get_free_page(GFP_ATOMIC);
-
- /*
- * Before acking the MMU fault, let's make sure MMU can only
- * access entry #0. Then add a new entry so that the DSP OS
- * can continue in order to dump the stack.
- */
- hw_mmu_twl_disable(resources->dmmu_base);
- hw_mmu_tlb_flush_all(resources->dmmu_base);
-
- hw_mmu_tlb_add(resources->dmmu_base,
- virt_to_phys(dummy_va_addr), fault_addr,
- HW_PAGE_SIZE4KB, 1,
- &map_attrs, HW_SET, HW_SET);
-
- dsp_clk_enable(DSP_CLK_GPT8);
-
- dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
-
- /* Clear MMU interrupt */
- hw_mmu_event_ack(resources->dmmu_base,
- HW_MMU_TRANSLATION_FAULT);
- dump_dsp_stack(dev_context);
- dsp_clk_disable(DSP_CLK_GPT8);
-
- hw_mmu_disable(resources->dmmu_base);
- free_page((unsigned long)dummy_va_addr);
-}
-#endif
-
-static inline const char *event_to_string(int event)
-{
- switch (event) {
- case DSP_SYSERROR: return "DSP_SYSERROR"; break;
- case DSP_MMUFAULT: return "DSP_MMUFAULT"; break;
- case DSP_PWRERROR: return "DSP_PWRERROR"; break;
- case DSP_WDTOVERFLOW: return "DSP_WDTOVERFLOW"; break;
- default: return "unknown event"; break;
- }
-}
-
-void bridge_deh_notify(struct deh_mgr *deh, int event, int info)
-{
- struct bridge_dev_context *dev_context;
- const char *str = event_to_string(event);
-
- if (!deh)
- return;
-
- dev_dbg(bridge, "%s: device exception", __func__);
- dev_context = deh->bridge_context;
-
- switch (event) {
- case DSP_SYSERROR:
- dev_err(bridge, "%s: %s, info=0x%x", __func__,
- str, info);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- dump_dl_modules(dev_context);
- dump_dsp_stack(dev_context);
-#endif
- break;
- case DSP_MMUFAULT:
- dev_err(bridge, "%s: %s, addr=0x%x", __func__,
- str, fault_addr);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
- print_dsp_trace_buffer(dev_context);
- dump_dl_modules(dev_context);
- mmu_fault_print_stack(dev_context);
-#endif
- break;
- default:
- dev_err(bridge, "%s: %s", __func__, str);
- break;
- }
-
- /* Filter subsequent notifications when an error occurs */
- if (dev_context->brd_state != BRD_ERROR) {
- ntfy_notify(deh->ntfy_obj, event);
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- bridge_recover_schedule();
-#endif
- }
-
- /* Set the Board state as ERROR */
- dev_context->brd_state = BRD_ERROR;
- /* Disable all the clocks that were enabled by DSP */
- dsp_clock_disable_all(dev_context->dsp_per_clks);
- /*
- * Avoid the subsequent WDT if it happens once,
- * also if fatal error occurs.
- */
- dsp_wdt_enable(false);
-}
diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c
deleted file mode 100644
index c7ee467f0f12..000000000000
--- a/drivers/staging/tidspbridge/core/wdt.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * wdt.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * IO dispatcher for a shared memory channel driver.
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/_chnl_sm.h>
-#include <dspbridge/wdt.h>
-#include <dspbridge/host_os.h>
-
-
-#define OMAP34XX_WDT3_BASE (0x49000000 + 0x30000)
-#define INT_34XX_WDT3_IRQ (36 + NR_IRQS)
-
-static struct dsp_wdt_setting dsp_wdt;
-
-void dsp_wdt_dpc(unsigned long data)
-{
- struct deh_mgr *deh_mgr;
- dev_get_deh_mgr(dev_get_first(), &deh_mgr);
- if (deh_mgr)
- bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
-}
-
-irqreturn_t dsp_wdt_isr(int irq, void *data)
-{
- u32 value;
- /* ack wdt3 interrupt */
- value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
- __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
-
- tasklet_schedule(&dsp_wdt.wdt3_tasklet);
- return IRQ_HANDLED;
-}
-
-int dsp_wdt_init(void)
-{
- int ret = 0;
-
- dsp_wdt.sm_wdt = NULL;
- dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K);
- if (!dsp_wdt.reg_base)
- return -ENOMEM;
-
- tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
-
- dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
-
- if (!IS_ERR(dsp_wdt.fclk)) {
- clk_prepare(dsp_wdt.fclk);
-
- dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
- if (IS_ERR(dsp_wdt.iclk)) {
- clk_put(dsp_wdt.fclk);
- dsp_wdt.fclk = NULL;
- ret = -EFAULT;
- } else {
- clk_prepare(dsp_wdt.iclk);
- }
- } else
- ret = -EFAULT;
-
- if (!ret)
- ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
- "dsp_wdt", &dsp_wdt);
-
- /* Disable at this moment, it will be enabled when DSP starts */
- if (!ret)
- disable_irq(INT_34XX_WDT3_IRQ);
-
- return ret;
-}
-
-void dsp_wdt_sm_set(void *data)
-{
- dsp_wdt.sm_wdt = data;
- dsp_wdt.sm_wdt->wdt_overflow = 5; /* in seconds */
-}
-
-
-void dsp_wdt_exit(void)
-{
- free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
- tasklet_kill(&dsp_wdt.wdt3_tasklet);
-
- if (dsp_wdt.fclk) {
- clk_unprepare(dsp_wdt.fclk);
- clk_put(dsp_wdt.fclk);
- }
- if (dsp_wdt.iclk) {
- clk_unprepare(dsp_wdt.iclk);
- clk_put(dsp_wdt.iclk);
- }
-
- dsp_wdt.fclk = NULL;
- dsp_wdt.iclk = NULL;
- dsp_wdt.sm_wdt = NULL;
-
- if (dsp_wdt.reg_base)
- iounmap(dsp_wdt.reg_base);
- dsp_wdt.reg_base = NULL;
-}
-
-void dsp_wdt_enable(bool enable)
-{
- u32 tmp;
- static bool wdt_enable;
-
- if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
- return;
-
- wdt_enable = enable;
-
- if (enable) {
- clk_enable(dsp_wdt.fclk);
- clk_enable(dsp_wdt.iclk);
- dsp_wdt.sm_wdt->wdt_setclocks = 1;
- tmp = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
- __raw_writel(tmp, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
- enable_irq(INT_34XX_WDT3_IRQ);
- } else {
- disable_irq(INT_34XX_WDT3_IRQ);
- dsp_wdt.sm_wdt->wdt_setclocks = 0;
- clk_disable(dsp_wdt.iclk);
- clk_disable(dsp_wdt.fclk);
- }
-}
diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c
deleted file mode 100644
index 9d54744805b8..000000000000
--- a/drivers/staging/tidspbridge/dynload/cload.c
+++ /dev/null
@@ -1,1952 +0,0 @@
-/*
- * cload.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/slab.h>
-
-#include "header.h"
-
-#include "module_list.h"
-#define LINKER_MODULES_HEADER ("_" MODULES_HEADER)
-
-/*
- * forward references
- */
-static void dload_symbols(struct dload_state *dlthis);
-static void dload_data(struct dload_state *dlthis);
-static void allocate_sections(struct dload_state *dlthis);
-static void string_table_free(struct dload_state *dlthis);
-static void symbol_table_free(struct dload_state *dlthis);
-static void section_table_free(struct dload_state *dlthis);
-static void init_module_handle(struct dload_state *dlthis);
-#if BITS_PER_AU > BITS_PER_BYTE
-static char *unpack_name(struct dload_state *dlthis, u32 soffset);
-#endif
-
-static const char cinitname[] = { ".cinit" };
-static const char loader_dllview_root[] = { "?DLModules?" };
-
-/*
- * Error strings
- */
-static const char readstrm[] = { "Error reading %s from input stream" };
-static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" };
-static const char tgtalloc[] = {
- "Target memory allocate failed, section %s size " FMT_UI32 };
-static const char initfail[] = { "%s to target address " FMT_UI32 " failed" };
-static const char dlvwrite[] = { "Write to DLLview list failed" };
-static const char iconnect[] = { "Connect call to init interface failed" };
-static const char err_checksum[] = { "Checksum failed on %s" };
-
-/*************************************************************************
- * Procedure dload_error
- *
- * Parameters:
- * errtxt description of the error, printf style
- * ... additional information
- *
- * Effect:
- * Reports or records the error as appropriate.
- *********************************************************************** */
-void dload_error(struct dload_state *dlthis, const char *errtxt, ...)
-{
- va_list args;
-
- va_start(args, errtxt);
- dlthis->mysym->error_report(dlthis->mysym, errtxt, args);
- va_end(args);
- dlthis->dload_errcount += 1;
-
-} /* dload_error */
-
-#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb)
-
-/*************************************************************************
- * Procedure dload_syms_error
- *
- * Parameters:
- * errtxt description of the error, printf style
- * ... additional information
- *
- * Effect:
- * Reports or records the error as appropriate.
- *********************************************************************** */
-void dload_syms_error(struct dynamic_loader_sym *syms, const char *errtxt, ...)
-{
- va_list args;
-
- va_start(args, errtxt);
- syms->error_report(syms, errtxt, args);
- va_end(args);
-}
-
-/*************************************************************************
- * Procedure dynamic_load_module
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- * init Target-side memory initialization
- * options Option flags DLOAD_*
- * mhandle A module handle for use with Dynamic_Unload
- *
- * Effect:
- * The module image is read using *module. Target storage for the new
- * image is
- * obtained from *alloc. Symbols defined and referenced by the module are
- * managed using *syms. The image is then relocated and references
- * resolved as necessary, and the resulting executable bits are placed
- * into target memory using *init.
- *
- * Returns:
- * On a successful load, a module handle is placed in *mhandle,
- * and zero is returned. On error, the number of errors detected is
- * returned. Individual errors are reported during the load process
- * using syms->error_report().
- ********************************************************************** */
-int dynamic_load_module(struct dynamic_loader_stream *module,
- struct dynamic_loader_sym *syms,
- struct dynamic_loader_allocate *alloc,
- struct dynamic_loader_initialize *init,
- unsigned options, void **mhandle)
-{
- register unsigned *dp, sz;
- struct dload_state dl_state; /* internal state for this call */
-
- /* blast our internal state */
- dp = (unsigned *)&dl_state;
- for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
- *dp++ = 0;
-
- /* Enable _only_ BSS initialization if enabled by user */
- if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
- dl_state.myoptions = DLOAD_INITBSS;
-
- /* Check that mandatory arguments are present */
- if (!module || !syms) {
- dload_error(&dl_state, "Required parameter is NULL");
- } else {
- dl_state.strm = module;
- dl_state.mysym = syms;
- dload_headers(&dl_state);
- if (!dl_state.dload_errcount)
- dload_strings(&dl_state, false);
- if (!dl_state.dload_errcount)
- dload_sections(&dl_state);
-
- if (init && !dl_state.dload_errcount) {
- if (init->connect(init)) {
- dl_state.myio = init;
- dl_state.myalloc = alloc;
- /* do now, before reducing symbols */
- allocate_sections(&dl_state);
- } else
- dload_error(&dl_state, iconnect);
- }
-
- if (!dl_state.dload_errcount) {
- /* fix up entry point address */
- unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
- if (sref < dl_state.allocated_secn_count)
- dl_state.dfile_hdr.df_entrypt +=
- dl_state.ldr_sections[sref].run_addr;
-
- dload_symbols(&dl_state);
- }
-
- if (init && !dl_state.dload_errcount)
- dload_data(&dl_state);
-
- init_module_handle(&dl_state);
-
- /* dl_state.myio is init or 0 at this point. */
- if (dl_state.myio) {
- if ((!dl_state.dload_errcount) &&
- (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) &&
- (!init->execute(init,
- dl_state.dfile_hdr.df_entrypt)))
- dload_error(&dl_state, "Init->Execute Failed");
- init->release(init);
- }
-
- symbol_table_free(&dl_state);
- section_table_free(&dl_state);
- string_table_free(&dl_state);
- dload_tramp_cleanup(&dl_state);
-
- if (dl_state.dload_errcount) {
- dynamic_unload_module(dl_state.myhandle, syms, alloc,
- init);
- dl_state.myhandle = NULL;
- }
- }
-
- if (mhandle)
- *mhandle = dl_state.myhandle; /* give back the handle */
-
- return dl_state.dload_errcount;
-} /* DLOAD_File */
-
-/*************************************************************************
- * Procedure dynamic_open_module
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- * init Target-side memory initialization
- * options Option flags DLOAD_*
- * mhandle A module handle for use with Dynamic_Unload
- *
- * Effect:
- * The module image is read using *module. Target storage for the new
- * image is
- * obtained from *alloc. Symbols defined and referenced by the module are
- * managed using *syms. The image is then relocated and references
- * resolved as necessary, and the resulting executable bits are placed
- * into target memory using *init.
- *
- * Returns:
- * On a successful load, a module handle is placed in *mhandle,
- * and zero is returned. On error, the number of errors detected is
- * returned. Individual errors are reported during the load process
- * using syms->error_report().
- ********************************************************************** */
-int
-dynamic_open_module(struct dynamic_loader_stream *module,
- struct dynamic_loader_sym *syms,
- struct dynamic_loader_allocate *alloc,
- struct dynamic_loader_initialize *init,
- unsigned options, void **mhandle)
-{
- register unsigned *dp, sz;
- struct dload_state dl_state; /* internal state for this call */
-
- /* blast our internal state */
- dp = (unsigned *)&dl_state;
- for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
- *dp++ = 0;
-
- /* Enable _only_ BSS initialization if enabled by user */
- if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
- dl_state.myoptions = DLOAD_INITBSS;
-
- /* Check that mandatory arguments are present */
- if (!module || !syms) {
- dload_error(&dl_state, "Required parameter is NULL");
- } else {
- dl_state.strm = module;
- dl_state.mysym = syms;
- dload_headers(&dl_state);
- if (!dl_state.dload_errcount)
- dload_strings(&dl_state, false);
- if (!dl_state.dload_errcount)
- dload_sections(&dl_state);
-
- if (init && !dl_state.dload_errcount) {
- if (init->connect(init)) {
- dl_state.myio = init;
- dl_state.myalloc = alloc;
- /* do now, before reducing symbols */
- allocate_sections(&dl_state);
- } else
- dload_error(&dl_state, iconnect);
- }
-
- if (!dl_state.dload_errcount) {
- /* fix up entry point address */
- unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
- if (sref < dl_state.allocated_secn_count)
- dl_state.dfile_hdr.df_entrypt +=
- dl_state.ldr_sections[sref].run_addr;
-
- dload_symbols(&dl_state);
- }
-
- init_module_handle(&dl_state);
-
- /* dl_state.myio is either 0 or init at this point. */
- if (dl_state.myio) {
- if ((!dl_state.dload_errcount) &&
- (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) &&
- (!init->execute(init,
- dl_state.dfile_hdr.df_entrypt)))
- dload_error(&dl_state, "Init->Execute Failed");
- init->release(init);
- }
-
- symbol_table_free(&dl_state);
- section_table_free(&dl_state);
- string_table_free(&dl_state);
-
- if (dl_state.dload_errcount) {
- dynamic_unload_module(dl_state.myhandle, syms, alloc,
- init);
- dl_state.myhandle = NULL;
- }
- }
-
- if (mhandle)
- *mhandle = dl_state.myhandle; /* give back the handle */
-
- return dl_state.dload_errcount;
-} /* DLOAD_File */
-
-/*************************************************************************
- * Procedure dload_headers
- *
- * Parameters:
- * none
- *
- * Effect:
- * Loads the DOFF header and verify record. Deals with any byte-order
- * issues and checks them for validity.
- *********************************************************************** */
-#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \
- sizeof(struct doff_verify_rec_t))
-
-void dload_headers(struct dload_state *dlthis)
-{
- u32 map;
-
- /* Read the header and the verify record as one. If we don't get it
- all, we're done */
- if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr,
- COMBINED_HEADER_SIZE) !=
- COMBINED_HEADER_SIZE) {
- DL_ERROR(readstrm, "File Headers");
- return;
- }
- /*
- * Verify that we have the byte order of the file correct.
- * If not, must fix it before we can continue
- */
- map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle);
- if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) {
- /* input is either byte-shuffled or bad */
- if ((map & 0xFCFCFCFC) == 0) { /* no obviously bogus bits */
- dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE,
- map);
- }
- if (dlthis->dfile_hdr.df_byte_reshuffle !=
- BYTE_RESHUFFLE_VALUE) {
- /* didn't fix the problem, the byte swap map is bad */
- dload_error(dlthis,
- "Bad byte swap map " FMT_UI32 " in header",
- dlthis->dfile_hdr.df_byte_reshuffle);
- return;
- }
- dlthis->reorder_map = map; /* keep map for future use */
- }
-
- /*
- * Verify checksum of header and verify record
- */
- if (~dload_checksum(&dlthis->dfile_hdr,
- sizeof(struct doff_filehdr_t)) ||
- ~dload_checksum(&dlthis->verify,
- sizeof(struct doff_verify_rec_t))) {
- DL_ERROR(err_checksum, "header or verify record");
- return;
- }
-#if HOST_ENDIANNESS
- dlthis->dfile_hdr.df_byte_reshuffle = map; /* put back for later */
-#endif
-
- /* Check for valid target ID */
- if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) &&
- -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) {
- dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x",
- dlthis->dfile_hdr.df_target_id, TARGET_ID);
- return;
- }
- /* Check for valid file format */
- if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) {
- dload_error(dlthis, "Bad DOFF version 0x%x",
- dlthis->dfile_hdr.df_doff_version);
- return;
- }
-
- /*
- * Apply reasonableness checks to count fields
- */
- if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) {
- dload_error(dlthis, "Excessive string table size " FMT_UI32,
- dlthis->dfile_hdr.df_strtab_size);
- return;
- }
- if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) {
- dload_error(dlthis, "Excessive section count 0x%x",
- dlthis->dfile_hdr.df_no_scns);
- return;
- }
-#ifndef TARGET_ENDIANNESS
- /*
- * Check that endianness does not disagree with explicit specification
- */
- if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) &
- dlthis->myoptions & ENDIANNESS_MASK) {
- dload_error(dlthis,
- "Input endianness disagrees with specified option");
- return;
- }
- dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG;
-#endif
-
-} /* dload_headers */
-
-/* COFF Section Processing
- *
- * COFF sections are read in and retained intact. Each record is embedded
- * in a new structure that records the updated load and
- * run addresses of the section */
-
-static const char secn_errid[] = { "section" };
-
-/*************************************************************************
- * Procedure dload_sections
- *
- * Parameters:
- * none
- *
- * Effect:
- * Loads the section records into an internal table.
- *********************************************************************** */
-void dload_sections(struct dload_state *dlthis)
-{
- s16 siz;
- struct doff_scnhdr_t *shp;
- unsigned nsecs = dlthis->dfile_hdr.df_no_scns;
-
- /* allocate space for the DOFF section records */
- siz = nsecs * sizeof(struct doff_scnhdr_t);
- shp =
- (struct doff_scnhdr_t *)dlthis->mysym->dload_allocate(dlthis->mysym,
- siz);
- if (!shp) { /* not enough storage */
- DL_ERROR(err_alloc, siz);
- return;
- }
- dlthis->sect_hdrs = shp;
-
- /* read in the section records */
- if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) {
- DL_ERROR(readstrm, secn_errid);
- return;
- }
-
- /* if we need to fix up byte order, do it now */
- if (dlthis->reorder_map)
- dload_reorder(shp, siz, dlthis->reorder_map);
-
- /* check for validity */
- if (~dload_checksum(dlthis->sect_hdrs, siz) !=
- dlthis->verify.dv_scn_rec_checksum) {
- DL_ERROR(err_checksum, secn_errid);
- return;
- }
-
-} /* dload_sections */
-
-/*****************************************************************************
- * Procedure allocate_sections
- *
- * Parameters:
- * alloc target memory allocator class
- *
- * Effect:
- * Assigns new (target) addresses for sections
- **************************************************************************** */
-static void allocate_sections(struct dload_state *dlthis)
-{
- u16 curr_sect, nsecs, siz;
- struct doff_scnhdr_t *shp;
- struct ldr_section_info *asecs;
- struct my_handle *hndl;
- nsecs = dlthis->dfile_hdr.df_no_scns;
- if (!nsecs)
- return;
- if ((dlthis->myalloc == NULL) &&
- (dlthis->dfile_hdr.df_target_scns > 0)) {
- DL_ERROR("Arg 3 (alloc) required but NULL", 0);
- return;
- }
- /*
- * allocate space for the module handle, which we will keep for unload
- * purposes include an additional section store for an auto-generated
- * trampoline section in case we need it.
- */
- siz = (dlthis->dfile_hdr.df_target_scns + 1) *
- sizeof(struct ldr_section_info) + MY_HANDLE_SIZE;
-
- hndl =
- (struct my_handle *)dlthis->mysym->dload_allocate(dlthis->mysym,
- siz);
- if (!hndl) { /* not enough storage */
- DL_ERROR(err_alloc, siz);
- return;
- }
- /* initialize the handle header */
- hndl->dm.next = hndl->dm.prev = hndl; /* circular list */
- hndl->dm.root = NULL;
- hndl->dm.dbthis = 0;
- dlthis->myhandle = hndl; /* save away for return */
- /* pointer to the section list of allocated sections */
- dlthis->ldr_sections = asecs = hndl->secns;
- /* * Insert names into all sections, make copies of
- the sections we allocate */
- shp = dlthis->sect_hdrs;
- for (curr_sect = 0; curr_sect < nsecs; curr_sect++) {
- u32 soffset = shp->ds_offset;
-#if BITS_PER_AU <= BITS_PER_BYTE
- /* attempt to insert the name of this section */
- if (soffset < dlthis->dfile_hdr.df_strtab_size)
- ((struct ldr_section_info *)shp)->name =
- dlthis->str_head + soffset;
- else {
- dload_error(dlthis, "Bad name offset in section %d",
- curr_sect);
- ((struct ldr_section_info *)shp)->name = NULL;
- }
-#endif
- /* allocate target storage for sections that require it */
- if (ds_needs_allocation(shp)) {
- *asecs = *(struct ldr_section_info *)shp;
- asecs->context = 0; /* zero the context field */
-#if BITS_PER_AU > BITS_PER_BYTE
- asecs->name = unpack_name(dlthis, soffset);
- dlthis->debug_string_size = soffset + dlthis->temp_len;
-#else
- dlthis->debug_string_size = soffset;
-#endif
- if (dlthis->myalloc != NULL) {
- if (!dlthis->myalloc->
- dload_allocate(dlthis->myalloc, asecs,
- ds_alignment(asecs->type))) {
- dload_error(dlthis, tgtalloc,
- asecs->name, asecs->size);
- return;
- }
- }
- /* keep address deltas in original section table */
- shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr;
- shp->ds_paddr = asecs->run_addr - shp->ds_paddr;
- dlthis->allocated_secn_count += 1;
- } /* allocate target storage */
- shp += 1;
- asecs += 1;
- }
-#if BITS_PER_AU <= BITS_PER_BYTE
- dlthis->debug_string_size +=
- strlen(dlthis->str_head + dlthis->debug_string_size) + 1;
-#endif
-} /* allocate sections */
-
-/*************************************************************************
- * Procedure section_table_free
- *
- * Parameters:
- * none
- *
- * Effect:
- * Frees any state used by the symbol table.
- *
- * WARNING:
- * This routine is not allowed to declare errors!
- *********************************************************************** */
-static void section_table_free(struct dload_state *dlthis)
-{
- struct doff_scnhdr_t *shp;
-
- shp = dlthis->sect_hdrs;
- if (shp)
- dlthis->mysym->dload_deallocate(dlthis->mysym, shp);
-
-} /* section_table_free */
-
-/*************************************************************************
- * Procedure dload_strings
- *
- * Parameters:
- * sec_names_only If true only read in the "section names"
- * portion of the string table
- *
- * Effect:
- * Loads the DOFF string table into memory. DOFF keeps all strings in a
- * big unsorted array. We just read that array into memory in bulk.
- *********************************************************************** */
-static const char stringtbl[] = { "string table" };
-
-void dload_strings(struct dload_state *dlthis, bool sec_names_only)
-{
- u32 ssiz;
- char *strbuf;
-
- if (sec_names_only) {
- ssiz = BYTE_TO_HOST(DOFF_ALIGN
- (dlthis->dfile_hdr.df_scn_name_size));
- } else {
- ssiz = BYTE_TO_HOST(DOFF_ALIGN
- (dlthis->dfile_hdr.df_strtab_size));
- }
- if (ssiz == 0)
- return;
-
- /* get some memory for the string table */
-#if BITS_PER_AU > BITS_PER_BYTE
- strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz +
- dlthis->dfile_hdr.
- df_max_str_len);
-#else
- strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz);
-#endif
- if (strbuf == NULL) {
- DL_ERROR(err_alloc, ssiz);
- return;
- }
- dlthis->str_head = strbuf;
-#if BITS_PER_AU > BITS_PER_BYTE
- dlthis->str_temp = strbuf + ssiz;
-#endif
- /* read in the strings and verify them */
- if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf,
- ssiz)) != ssiz) {
- DL_ERROR(readstrm, stringtbl);
- }
- /* if we need to fix up byte order, do it now */
-#ifndef _BIG_ENDIAN
- if (dlthis->reorder_map)
- dload_reorder(strbuf, ssiz, dlthis->reorder_map);
-
- if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) !=
- dlthis->verify.dv_str_tab_checksum)) {
- DL_ERROR(err_checksum, stringtbl);
- }
-#else
- if (dlthis->dfile_hdr.df_byte_reshuffle !=
- HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
- /* put strings in big-endian order, not in PC order */
- dload_reorder(strbuf, ssiz,
- HOST_BYTE_ORDER(dlthis->
- dfile_hdr.df_byte_reshuffle));
- }
- if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) !=
- dlthis->verify.dv_str_tab_checksum)) {
- DL_ERROR(err_checksum, stringtbl);
- }
-#endif
-} /* dload_strings */
-
-/*************************************************************************
- * Procedure string_table_free
- *
- * Parameters:
- * none
- *
- * Effect:
- * Frees any state used by the string table.
- *
- * WARNING:
- * This routine is not allowed to declare errors!
- ************************************************************************ */
-static void string_table_free(struct dload_state *dlthis)
-{
- if (dlthis->str_head)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- dlthis->str_head);
-
-} /* string_table_free */
-
-/*
- * Symbol Table Maintenance Functions
- *
- * COFF symbols are read by dload_symbols(), which is called after
- * sections have been allocated. Symbols which might be used in
- * relocation (ie, not debug info) are retained in an internal temporary
- * compressed table (type local_symbol). A particular symbol is recovered
- * by index by calling dload_find_symbol(). dload_find_symbol
- * reconstructs a more explicit representation (type SLOTVEC) which is
- * used by reloc.c
- */
-/* real size of debug header */
-#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect))
-
-static const char sym_errid[] = { "symbol" };
-
-/**************************************************************************
- * Procedure dload_symbols
- *
- * Parameters:
- * none
- *
- * Effect:
- * Reads in symbols and retains ones that might be needed for relocation
- * purposes.
- *********************************************************************** */
-/* size of symbol buffer no bigger than target data buffer, to limit stack
- * usage */
-#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\
- sizeof(struct doff_syment_t))
-
-static void dload_symbols(struct dload_state *dlthis)
-{
- u32 sym_count, siz, dsiz, symbols_left;
- u32 checks;
- struct local_symbol *sp;
- struct dynload_symbol *symp;
- struct dynload_symbol *newsym;
- struct doff_syment_t *my_sym_buf;
-
- sym_count = dlthis->dfile_hdr.df_no_syms;
- if (sym_count == 0)
- return;
-
- /*
- * We keep a local symbol table for all of the symbols in the input.
- * This table contains only section & value info, as we do not have
- * to do any name processing for locals. We reuse this storage
- * as a temporary for .dllview record construction.
- * Allocate storage for the whole table. Add 1 to the section count
- * in case a trampoline section is auto-generated as well as the
- * size of the trampoline section name so DLLView doesn't get lost.
- */
-
- siz = sym_count * sizeof(struct local_symbol);
- dsiz = DBG_HDR_SIZE +
- (sizeof(struct dll_sect) * dlthis->allocated_secn_count) +
- BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1);
- if (dsiz > siz)
- siz = dsiz; /* larger of symbols and .dllview temp */
- sp = (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
- siz);
- if (!sp) {
- DL_ERROR(err_alloc, siz);
- return;
- }
- dlthis->local_symtab = sp;
- /* Read the symbols in the input, store them in the table, and post any
- * globals to the global symbol table. In the process, externals
- become defined from the global symbol table */
- checks = dlthis->verify.dv_sym_tab_checksum;
- symbols_left = sym_count;
-
- my_sym_buf = kzalloc(sizeof(*my_sym_buf) * MY_SYM_BUF_SIZ, GFP_KERNEL);
- if (!my_sym_buf)
- return;
-
- do { /* read all symbols */
- char *sname;
- u32 val;
- s32 delta;
- struct doff_syment_t *input_sym;
- unsigned syms_in_buf;
-
- input_sym = my_sym_buf;
- syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ?
- MY_SYM_BUF_SIZ : symbols_left;
- siz = syms_in_buf * sizeof(struct doff_syment_t);
- if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) !=
- siz) {
- DL_ERROR(readstrm, sym_errid);
- goto free_sym_buf;
- }
- if (dlthis->reorder_map)
- dload_reorder(input_sym, siz, dlthis->reorder_map);
-
- checks += dload_checksum(input_sym, siz);
- do { /* process symbols in buffer */
- symbols_left -= 1;
- /* attempt to derive the name of this symbol */
- sname = NULL;
- if (input_sym->dn_offset > 0) {
-#if BITS_PER_AU <= BITS_PER_BYTE
- if ((u32) input_sym->dn_offset <
- dlthis->dfile_hdr.df_strtab_size)
- sname = dlthis->str_head +
- BYTE_TO_HOST(input_sym->dn_offset);
- else
- dload_error(dlthis,
- "Bad name offset in symbol "
- " %d", symbols_left);
-#else
- sname = unpack_name(dlthis,
- input_sym->dn_offset);
-#endif
- }
- val = input_sym->dn_value;
- delta = 0;
- sp->sclass = input_sym->dn_sclass;
- sp->secnn = input_sym->dn_scnum;
- /* if this is an undefined symbol,
- * define it (or fail) now */
- if (sp->secnn == DN_UNDEF) {
- /* pointless for static undefined */
- if (input_sym->dn_sclass != DN_EXT)
- goto loop_cont;
-
- /* try to define symbol from previously
- * loaded images */
- symp = dlthis->mysym->find_matching_symbol
- (dlthis->mysym, sname);
- if (!symp) {
- DL_ERROR
- ("Undefined external symbol %s",
- sname);
- goto loop_cont;
- }
- val = delta = symp->value;
-#ifdef ENABLE_TRAMP_DEBUG
- dload_syms_error(dlthis->mysym,
- "===> ext sym [%s] at %x",
- sname, val);
-#endif
-
- goto loop_cont;
- }
- /* symbol defined by this module */
- if (sp->secnn > 0) {
- /* symbol references a section */
- if ((unsigned)sp->secnn <=
- dlthis->allocated_secn_count) {
- /* section was allocated */
- struct doff_scnhdr_t *srefp =
- &dlthis->sect_hdrs[sp->secnn - 1];
-
- if (input_sym->dn_sclass ==
- DN_STATLAB ||
- input_sym->dn_sclass == DN_EXTLAB) {
- /* load */
- delta = srefp->ds_vaddr;
- } else {
- /* run */
- delta = srefp->ds_paddr;
- }
- val += delta;
- }
- goto loop_itr;
- }
- /* This symbol is an absolute symbol */
- if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) ||
- (sp->sclass ==
- DN_EXTLAB))) {
- symp =
- dlthis->mysym->find_matching_symbol(dlthis->
- mysym,
- sname);
- if (!symp)
- goto loop_itr;
- /* This absolute symbol is already defined. */
- if (symp->value == input_sym->dn_value) {
- /* If symbol values are equal, continue
- * but don't add to the global symbol
- * table */
- sp->value = val;
- sp->delta = delta;
- sp += 1;
- input_sym += 1;
- continue;
- } else {
- /* If symbol values are not equal,
- * return with redefinition error */
- DL_ERROR("Absolute symbol %s is "
- "defined multiple times with "
- "different values", sname);
- goto free_sym_buf;
- }
- }
-loop_itr:
- /* if this is a global symbol, post it to the
- * global table */
- if (input_sym->dn_sclass == DN_EXT ||
- input_sym->dn_sclass == DN_EXTLAB) {
- /* Keep this global symbol for subsequent
- * modules. Don't complain on error, to allow
- * symbol API to suppress global symbols */
- if (!sname)
- goto loop_cont;
-
- newsym = dlthis->mysym->add_to_symbol_table
- (dlthis->mysym, sname,
- (unsigned)dlthis->myhandle);
- if (newsym)
- newsym->value = val;
-
- } /* global */
-loop_cont:
- sp->value = val;
- sp->delta = delta;
- sp += 1;
- input_sym += 1;
- } while ((syms_in_buf -= 1) > 0); /* process sym in buf */
- } while (symbols_left > 0); /* read all symbols */
- if (~checks)
- dload_error(dlthis, "Checksum of symbols failed");
-
-free_sym_buf:
- kfree(my_sym_buf);
- return;
-} /* dload_symbols */
-
-/*****************************************************************************
- * Procedure symbol_table_free
- *
- * Parameters:
- * none
- *
- * Effect:
- * Frees any state used by the symbol table.
- *
- * WARNING:
- * This routine is not allowed to declare errors!
- **************************************************************************** */
-static void symbol_table_free(struct dload_state *dlthis)
-{
- if (dlthis->local_symtab) {
- if (dlthis->dload_errcount) { /* blow off our symbols */
- dlthis->mysym->purge_symbol_table(dlthis->mysym,
- (unsigned)
- dlthis->myhandle);
- }
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- dlthis->local_symtab);
- }
-} /* symbol_table_free */
-
-/* .cinit Processing
- *
- * The dynamic loader does .cinit interpretation. cload_cinit()
- * acts as a special write-to-target function, in that it takes relocated
- * data from the normal data flow, and interprets it as .cinit actions.
- * Because the normal data flow does not necessarily process the whole
- * .cinit section in one buffer, cload_cinit() must be prepared to
- * interpret the data piecemeal. A state machine is used for this
- * purpose.
- */
-
-/* The following are only for use by reloc.c and things it calls */
-static const struct ldr_section_info cinit_info_init = { cinitname, 0, 0,
- (ldr_addr)-1, 0, DLOAD_BSS, 0
-};
-
-/*************************************************************************
- * Procedure cload_cinit
- *
- * Parameters:
- * ipacket Pointer to data packet to be loaded
- *
- * Effect:
- * Interprets the data in the buffer as .cinit data, and performs the
- * appropriate initializations.
- *********************************************************************** */
-static void cload_cinit(struct dload_state *dlthis,
- struct image_packet_t *ipacket)
-{
-#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16
- s32 init_count, left;
-#else
- s16 init_count, left;
-#endif
- unsigned char *pktp = ipacket->img_data;
- unsigned char *pktend = pktp + BYTE_TO_HOST_ROUND(ipacket->packet_size);
- int temp;
- ldr_addr atmp;
- struct ldr_section_info cinit_info;
-
- /* PROCESS ALL THE INITIALIZATION RECORDS THE BUFFER. */
- while (true) {
- left = pktend - pktp;
- switch (dlthis->cinit_state) {
- case CI_COUNT: /* count field */
- if (left < TDATA_TO_HOST(CINIT_COUNT))
- goto loopexit;
- temp = dload_unpack(dlthis, (tgt_au_t *) pktp,
- CINIT_COUNT * TDATA_AU_BITS, 0,
- ROP_SGN);
- pktp += TDATA_TO_HOST(CINIT_COUNT);
- /* negative signifies BSS table, zero means done */
- if (temp <= 0) {
- dlthis->cinit_state = CI_DONE;
- break;
- }
- dlthis->cinit_count = temp;
- dlthis->cinit_state = CI_ADDRESS;
- break;
-#if CINIT_ALIGN < CINIT_ADDRESS
- case CI_PARTADDRESS:
- pktp -= TDATA_TO_HOST(CINIT_ALIGN);
- /* back up pointer into space courtesy of caller */
- *(uint16_t *) pktp = dlthis->cinit_addr;
- /* stuff in saved bits !! FALL THRU !! */
-#endif
- case CI_ADDRESS: /* Address field for a copy packet */
- if (left < TDATA_TO_HOST(CINIT_ADDRESS)) {
-#if CINIT_ALIGN < CINIT_ADDRESS
- if (left == TDATA_TO_HOST(CINIT_ALIGN)) {
- /* address broken into halves */
- dlthis->cinit_addr = *(uint16_t *) pktp;
- /* remember 1st half */
- dlthis->cinit_state = CI_PARTADDRESS;
- left = 0;
- }
-#endif
- goto loopexit;
- }
- atmp = dload_unpack(dlthis, (tgt_au_t *) pktp,
- CINIT_ADDRESS * TDATA_AU_BITS, 0,
- ROP_UNS);
- pktp += TDATA_TO_HOST(CINIT_ADDRESS);
-#if CINIT_PAGE_BITS > 0
- dlthis->cinit_page = atmp &
- ((1 << CINIT_PAGE_BITS) - 1);
- atmp >>= CINIT_PAGE_BITS;
-#else
- dlthis->cinit_page = CINIT_DEFAULT_PAGE;
-#endif
- dlthis->cinit_addr = atmp;
- dlthis->cinit_state = CI_COPY;
- break;
- case CI_COPY: /* copy bits to the target */
- init_count = HOST_TO_TDATA(left);
- if (init_count > dlthis->cinit_count)
- init_count = dlthis->cinit_count;
- if (init_count == 0)
- goto loopexit; /* get more bits */
- cinit_info = cinit_info_init;
- cinit_info.page = dlthis->cinit_page;
- if (!dlthis->myio->writemem(dlthis->myio, pktp,
- TDATA_TO_TADDR
- (dlthis->cinit_addr),
- &cinit_info,
- TDATA_TO_HOST(init_count))) {
- dload_error(dlthis, initfail, "write",
- dlthis->cinit_addr);
- }
- dlthis->cinit_count -= init_count;
- if (dlthis->cinit_count <= 0) {
- dlthis->cinit_state = CI_COUNT;
- init_count = (init_count + CINIT_ALIGN - 1) &
- -CINIT_ALIGN;
- /* align to next init */
- }
- pktp += TDATA_TO_HOST(init_count);
- dlthis->cinit_addr += init_count;
- break;
- case CI_DONE: /* no more .cinit to do */
- return;
- } /* switch (cinit_state) */
- } /* while */
-
-loopexit:
- if (left > 0) {
- dload_error(dlthis, "%d bytes left over in cinit packet", left);
- dlthis->cinit_state = CI_DONE; /* left over bytes are bad */
- }
-} /* cload_cinit */
-
-/* Functions to interface to reloc.c
- *
- * reloc.c is the relocation module borrowed from the linker, with
- * minimal (we hope) changes for our purposes. cload_sect_data() invokes
- * this module on a section to relocate and load the image data for that
- * section. The actual read and write actions are supplied by the global
- * routines below.
- */
-
-/************************************************************************
- * Procedure relocate_packet
- *
- * Parameters:
- * ipacket Pointer to an image packet to relocate
- *
- * Effect:
- * Performs the required relocations on the packet. Returns a checksum
- * of the relocation operations.
- *********************************************************************** */
-#define MY_RELOC_BUF_SIZ 8
-/* careful! exists at the same time as the image buffer */
-static int relocate_packet(struct dload_state *dlthis,
- struct image_packet_t *ipacket,
- u32 *checks, bool *tramps_generated)
-{
- u32 rnum;
- *tramps_generated = false;
-
- rnum = ipacket->num_relocs;
- do { /* all relocs */
- unsigned rinbuf;
- int siz;
- struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ];
- rp = rrec;
- rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum;
- siz = rinbuf * sizeof(struct reloc_record_t);
- if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) {
- DL_ERROR(readstrm, "relocation");
- return 0;
- }
- /* reorder the bytes if need be */
- if (dlthis->reorder_map)
- dload_reorder(rp, siz, dlthis->reorder_map);
-
- *checks += dload_checksum(rp, siz);
- do {
- /* perform the relocation operation */
- dload_relocate(dlthis, (tgt_au_t *) ipacket->img_data,
- rp, tramps_generated, false);
- rp += 1;
- rnum -= 1;
- } while ((rinbuf -= 1) > 0);
- } while (rnum > 0); /* all relocs */
- /* If trampoline(s) were generated, we need to do an update of the
- * trampoline copy of the packet since a 2nd phase relo will be done
- * later. */
- if (*tramps_generated == true) {
- dload_tramp_pkt_udpate(dlthis,
- (dlthis->image_secn -
- dlthis->ldr_sections),
- dlthis->image_offset, ipacket);
- }
-
- return 1;
-} /* dload_read_reloc */
-
-#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
-
-/* VERY dangerous */
-static const char imagepak[] = { "image packet" };
-
-struct img_buffer {
- struct image_packet_t ipacket;
- u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
-};
-
-/*************************************************************************
- * Procedure dload_data
- *
- * Parameters:
- * none
- *
- * Effect:
- * Read image data from input file, relocate it, and download it to the
- * target.
- *********************************************************************** */
-static void dload_data(struct dload_state *dlthis)
-{
- u16 curr_sect;
- struct doff_scnhdr_t *sptr = dlthis->sect_hdrs;
- struct ldr_section_info *lptr = dlthis->ldr_sections;
- struct img_buffer *ibuf;
- u8 *dest;
-
- /* Indicates whether CINIT processing has occurred */
- bool cinit_processed = false;
-
- ibuf = kzalloc(sizeof(*ibuf), GFP_KERNEL);
- if (!ibuf)
- return;
-
- /* Loop through the sections and load them one at a time.
- */
- for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns;
- curr_sect += 1) {
- if (ds_needs_download(sptr)) {
- s32 nip;
- ldr_addr image_offset = 0;
- /* set relocation info for this section */
- if (curr_sect < dlthis->allocated_secn_count)
- dlthis->delta_runaddr = sptr->ds_paddr;
- else {
- lptr = (struct ldr_section_info *)sptr;
- dlthis->delta_runaddr = 0;
- }
- dlthis->image_secn = lptr;
-#if BITS_PER_AU > BITS_PER_BYTE
- lptr->name = unpack_name(dlthis, sptr->ds_offset);
-#endif
- nip = sptr->ds_nipacks;
- while ((nip -= 1) >= 0) { /* process packets */
-
- s32 ipsize;
- u32 checks;
- bool tramp_generated = false;
-
- /* get the fixed header bits */
- if (dlthis->strm->read_buffer(dlthis->strm,
- &ibuf->ipacket,
- IPH_SIZE) !=
- IPH_SIZE) {
- DL_ERROR(readstrm, imagepak);
- goto free_ibuf;
- }
- /* reorder the header if need be */
- if (dlthis->reorder_map) {
- dload_reorder(&ibuf->ipacket, IPH_SIZE,
- dlthis->reorder_map);
- }
- /* now read the rest of the packet */
- ipsize =
- BYTE_TO_HOST(DOFF_ALIGN
- (ibuf->ipacket.packet_size));
- if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
- DL_ERROR("Bad image packet size %d",
- ipsize);
- goto free_ibuf;
- }
- dest = ibuf->bufr;
- /* End of determination */
-
- if (dlthis->strm->read_buffer(dlthis->strm,
- ibuf->bufr,
- ipsize) !=
- ipsize) {
- DL_ERROR(readstrm, imagepak);
- goto free_ibuf;
- }
- ibuf->ipacket.img_data = dest;
-
- /* reorder the bytes if need be */
-#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
- if (dlthis->reorder_map) {
- dload_reorder(dest, ipsize,
- dlthis->reorder_map);
- }
- checks = dload_checksum(dest, ipsize);
-#else
- if (dlthis->dfile_hdr.df_byte_reshuffle !=
- TARGET_ORDER(REORDER_MAP
- (BYTE_RESHUFFLE_VALUE))) {
- /* put image bytes in big-endian order,
- * not PC order */
- dload_reorder(dest, ipsize,
- TARGET_ORDER
- (dlthis->dfile_hdr.
- df_byte_reshuffle));
- }
-#if TARGET_AU_BITS > 8
- checks = dload_reverse_checksum16(dest, ipsize);
-#else
- checks = dload_reverse_checksum(dest, ipsize);
-#endif
-#endif
-
- checks += dload_checksum(&ibuf->ipacket,
- IPH_SIZE);
- /* relocate the image bits as needed */
- if (ibuf->ipacket.num_relocs) {
- dlthis->image_offset = image_offset;
- if (!relocate_packet(dlthis,
- &ibuf->ipacket,
- &checks,
- &tramp_generated))
- goto free_ibuf; /* error */
- }
- if (~checks)
- DL_ERROR(err_checksum, imagepak);
- /* Only write the result to the target if no
- * trampoline was generated. Otherwise it
- *will be done during trampoline finalize. */
-
- if (tramp_generated == false) {
-
- /* stuff the result into target
- * memory */
- if (dload_check_type(sptr,
- DLOAD_CINIT)) {
- cload_cinit(dlthis,
- &ibuf->ipacket);
- cinit_processed = true;
- } else {
- /* FIXME */
- if (!dlthis->myio->
- writemem(dlthis->
- myio,
- ibuf->bufr,
- lptr->
- load_addr +
- image_offset,
- lptr,
- BYTE_TO_HOST
- (ibuf->
- ipacket.
- packet_size))) {
- DL_ERROR
- ("Write to "
- FMT_UI32
- " failed",
- lptr->
- load_addr +
- image_offset);
- }
- }
- }
- image_offset +=
- BYTE_TO_TADDR(ibuf->ipacket.packet_size);
- } /* process packets */
- /* if this is a BSS section, we may want to fill it */
- if (!dload_check_type(sptr, DLOAD_BSS))
- goto loop_cont;
-
- if (!(dlthis->myoptions & DLOAD_INITBSS))
- goto loop_cont;
-
- if (cinit_processed) {
- /* Don't clear BSS after load-time
- * initialization */
- DL_ERROR
- ("Zero-initialization at " FMT_UI32
- " after " "load-time initialization!",
- lptr->load_addr);
- goto loop_cont;
- }
- /* fill the .bss area */
- dlthis->myio->fillmem(dlthis->myio,
- TADDR_TO_HOST(lptr->load_addr),
- lptr, TADDR_TO_HOST(lptr->size),
- DLOAD_FILL_BSS);
- goto loop_cont;
- }
- /* if DS_DOWNLOAD_MASK */
- /* If not loading, but BSS, zero initialize */
- if (!dload_check_type(sptr, DLOAD_BSS))
- goto loop_cont;
-
- if (!(dlthis->myoptions & DLOAD_INITBSS))
- goto loop_cont;
-
- if (curr_sect >= dlthis->allocated_secn_count)
- lptr = (struct ldr_section_info *)sptr;
-
- if (cinit_processed) {
- /*Don't clear BSS after load-time initialization */
- DL_ERROR("Zero-initialization at " FMT_UI32
- " attempted after "
- "load-time initialization!", lptr->load_addr);
- goto loop_cont;
- }
- /* fill the .bss area */
- dlthis->myio->fillmem(dlthis->myio,
- TADDR_TO_HOST(lptr->load_addr), lptr,
- TADDR_TO_HOST(lptr->size),
- DLOAD_FILL_BSS);
-loop_cont:
- sptr += 1;
- lptr += 1;
- } /* load sections */
-
- /* Finalize any trampolines that were created during the load */
- if (dload_tramp_finalize(dlthis) == 0) {
- DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32
- ") failed", dlthis->tramp.tramp_sect_next_addr);
- }
-free_ibuf:
- kfree(ibuf);
- return;
-} /* dload_data */
-
-/*************************************************************************
- * Procedure dload_reorder
- *
- * Parameters:
- * data 32-bit aligned pointer to data to be byte-swapped
- * dsiz size of the data to be reordered in sizeof() units.
- * map 32-bit map defining how to reorder the data. Value
- * must be REORDER_MAP() of some permutation
- * of 0x00 01 02 03
- *
- * Effect:
- * Re-arranges the bytes in each word according to the map specified.
- *
- *********************************************************************** */
-/* mask for byte shift count */
-#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE)
-
-void dload_reorder(void *data, int dsiz, unsigned int map)
-{
- register u32 tmp, tmap, datv;
- u32 *dp = (u32 *) data;
-
- map <<= LOG_BITS_PER_BYTE; /* align map with SHIFT_COUNT_MASK */
- do {
- tmp = 0;
- datv = *dp;
- tmap = map;
- do {
- tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK);
- tmap >>= BITS_PER_BYTE;
- } while (datv >>= BITS_PER_BYTE);
- *dp++ = tmp;
- } while ((dsiz -= sizeof(u32)) > 0);
-} /* dload_reorder */
-
-/*************************************************************************
- * Procedure dload_checksum
- *
- * Parameters:
- * data 32-bit aligned pointer to data to be checksummed
- * siz size of the data to be checksummed in sizeof() units.
- *
- * Effect:
- * Returns a checksum of the specified block
- *
- *********************************************************************** */
-u32 dload_checksum(void *data, unsigned siz)
-{
- u32 sum;
- u32 *dp;
- int left;
-
- sum = 0;
- dp = (u32 *) data;
- for (left = siz; left > 0; left -= sizeof(u32))
- sum += *dp++;
- return sum;
-} /* dload_checksum */
-
-#if HOST_ENDIANNESS
-/*************************************************************************
- * Procedure dload_reverse_checksum
- *
- * Parameters:
- * data 32-bit aligned pointer to data to be checksummed
- * siz size of the data to be checksummed in sizeof() units.
- *
- * Effect:
- * Returns a checksum of the specified block, which is assumed to be bytes
- * in big-endian order.
- *
- * Notes:
- * In a big-endian host, things like the string table are stored as bytes
- * in host order. But dllcreate always checksums in little-endian order.
- * It is most efficient to just handle the difference a word at a time.
- *
- ********************************************************************** */
-u32 dload_reverse_checksum(void *data, unsigned siz)
-{
- u32 sum, temp;
- u32 *dp;
- int left;
-
- sum = 0;
- dp = (u32 *) data;
-
- for (left = siz; left > 0; left -= sizeof(u32)) {
- temp = *dp++;
- sum += temp << BITS_PER_BYTE * 3;
- sum += temp >> BITS_PER_BYTE * 3;
- sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE);
- sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE;
- }
-
- return sum;
-} /* dload_reverse_checksum */
-
-#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
-u32 dload_reverse_checksum16(void *data, unsigned siz)
-{
- uint_fast32_t sum, temp;
- u32 *dp;
- int left;
-
- sum = 0;
- dp = (u32 *) data;
-
- for (left = siz; left > 0; left -= sizeof(u32)) {
- temp = *dp++;
- sum += temp << BITS_PER_BYTE * 2;
- sum += temp >> BITS_PER_BYTE * 2;
- }
-
- return sum;
-} /* dload_reverse_checksum16 */
-#endif
-#endif
-
-/*************************************************************************
- * Procedure swap_words
- *
- * Parameters:
- * data 32-bit aligned pointer to data to be swapped
- * siz size of the data to be swapped.
- * bitmap Bit map of how to swap each 32-bit word; 1 => 2 shorts,
- * 0 => 1 long
- *
- * Effect:
- * Swaps the specified data according to the specified map
- *
- *********************************************************************** */
-static void swap_words(void *data, unsigned siz, unsigned bitmap)
-{
- register int i;
-#if TARGET_AU_BITS < 16
- register u16 *sp;
-#endif
- register u32 *lp;
-
- siz /= sizeof(u16);
-
-#if TARGET_AU_BITS < 16
- /* pass 1: do all the bytes */
- i = siz;
- sp = (u16 *) data;
- do {
- register u16 tmp;
- tmp = *sp;
- *sp++ = SWAP16BY8(tmp);
- } while ((i -= 1) > 0);
-#endif
-
-#if TARGET_AU_BITS < 32
- /* pass 2: fixup the 32-bit words */
- i = siz >> 1;
- lp = (u32 *) data;
- do {
- if ((bitmap & 1) == 0) {
- register u32 tmp;
- tmp = *lp;
- *lp = SWAP32BY16(tmp);
- }
- lp += 1;
- bitmap >>= 1;
- } while ((i -= 1) > 0);
-#endif
-} /* swap_words */
-
-/*************************************************************************
- * Procedure copy_tgt_strings
- *
- * Parameters:
- * dstp Destination address. Assumed to be 32-bit aligned
- * srcp Source address. Assumed to be 32-bit aligned
- * charcount Number of characters to copy.
- *
- * Effect:
- * Copies strings from the source (which is in usual .dof file order on
- * the loading processor) to the destination buffer (which should be in proper
- * target addressable unit order). Makes sure the last string in the
- * buffer is NULL terminated (for safety).
- * Returns the first unused destination address.
- *********************************************************************** */
-static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount)
-{
- register tgt_au_t *src = (tgt_au_t *) srcp;
- register tgt_au_t *dst = (tgt_au_t *) dstp;
- register int cnt = charcount;
- do {
-#if TARGET_AU_BITS <= BITS_PER_AU
- /* byte-swapping issues may exist for strings on target */
- *dst++ = *src++;
-#else
- *dst++ = *src++;
-#endif
- } while ((cnt -= (sizeof(tgt_au_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0);
- /*apply force to make sure that the string table has null terminator */
-#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE)
- dst[-1] = 0;
-#else
- /* little endian */
- dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1;
-#endif
- return (char *)dst;
-} /* copy_tgt_strings */
-
-/*************************************************************************
- * Procedure init_module_handle
- *
- * Parameters:
- * none
- *
- * Effect:
- * Initializes the module handle we use to enable unloading, and installs
- * the debug information required by the target.
- *
- * Notes:
- * The handle returned from dynamic_load_module needs to encapsulate all the
- * allocations done for the module, and enable them plus the modules symbols to
- * be deallocated.
- *
- *********************************************************************** */
-#ifndef _BIG_ENDIAN
-static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0,
- (ldr_addr)-1, DBG_LIST_PAGE, DLOAD_DATA, 0
-};
-#else
-static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0,
- (ldr_addr)-1, DLOAD_DATA, DBG_LIST_PAGE, 0
-};
-#endif
-static void init_module_handle(struct dload_state *dlthis)
-{
- struct my_handle *hndl;
- u16 curr_sect;
- struct ldr_section_info *asecs;
- struct dll_module *dbmod;
- struct dll_sect *dbsec;
- struct dbg_mirror_root *mlist;
- register char *cp;
- struct modules_header mhdr;
- struct ldr_section_info dllview_info;
- struct dynload_symbol *debug_mirror_sym;
- hndl = dlthis->myhandle;
- if (!hndl)
- return; /* must be errors detected, so forget it */
-
- /* Store the section count */
- hndl->secn_count = dlthis->allocated_secn_count;
-
- /* If a trampoline section was created, add it in */
- if (dlthis->tramp.tramp_sect_next_addr != 0)
- hndl->secn_count += 1;
-
- hndl->secn_count = hndl->secn_count << 1;
-
- hndl->secn_count = dlthis->allocated_secn_count << 1;
-#ifndef TARGET_ENDIANNESS
- if (dlthis->big_e_target)
- hndl->secn_count += 1; /* flag for big-endian */
-#endif
- if (dlthis->dload_errcount)
- return; /* abandon if errors detected */
- /* Locate the symbol that names the header for the CCS debug list
- of modules. If not found, we just don't generate the debug record.
- If found, we create our modules list. We make sure to create the
- loader_dllview_root even if there is no relocation info to record,
- just to try to put both symbols in the same symbol table and
- module. */
- debug_mirror_sym = dlthis->mysym->find_matching_symbol(dlthis->mysym,
- loader_dllview_root);
- if (!debug_mirror_sym) {
- struct dynload_symbol *dlmodsym;
- struct dbg_mirror_root *mlst;
-
- /* our root symbol is not yet present;
- check if we have DLModules defined */
- dlmodsym = dlthis->mysym->find_matching_symbol(dlthis->mysym,
- LINKER_MODULES_HEADER);
- if (!dlmodsym)
- return; /* no DLModules list so no debug info */
- /* if we have DLModules defined, construct our header */
- mlst = (struct dbg_mirror_root *)
- dlthis->mysym->dload_allocate(dlthis->mysym,
- sizeof(struct
- dbg_mirror_root));
- if (!mlst) {
- DL_ERROR(err_alloc, sizeof(struct dbg_mirror_root));
- return;
- }
- mlst->next = NULL;
- mlst->changes = 0;
- mlst->refcount = 0;
- mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value);
- /* add our root symbol */
- debug_mirror_sym = dlthis->mysym->add_to_symbol_table
- (dlthis->mysym, loader_dllview_root,
- (unsigned)dlthis->myhandle);
- if (!debug_mirror_sym) {
- /* failed, recover memory */
- dlthis->mysym->dload_deallocate(dlthis->mysym, mlst);
- return;
- }
- debug_mirror_sym->value = (u32) mlst;
- }
- /* First create the DLLview record and stuff it into the buffer.
- Then write it to the DSP. Record pertinent locations in our hndl,
- and add it to the per-processor list of handles with debug info. */
-#ifndef DEBUG_HEADER_IN_LOADER
- mlist = (struct dbg_mirror_root *)debug_mirror_sym->value;
- if (!mlist)
- return;
-#else
- mlist = (struct dbg_mirror_root *)&debug_list_header;
-#endif
- hndl->dm.root = mlist; /* set pointer to root into our handle */
- if (!dlthis->allocated_secn_count)
- return; /* no load addresses to be recorded */
- /* reuse temporary symbol storage */
- dbmod = (struct dll_module *)dlthis->local_symtab;
- /* Create the DLLview record in the memory we retain for our handle */
- dbmod->num_sects = dlthis->allocated_secn_count;
- dbmod->timestamp = dlthis->verify.dv_timdat;
- dbmod->version = INIT_VERSION;
- dbmod->verification = VERIFICATION;
- asecs = dlthis->ldr_sections;
- dbsec = dbmod->sects;
- for (curr_sect = dlthis->allocated_secn_count;
- curr_sect > 0; curr_sect -= 1) {
- dbsec->sect_load_adr = asecs->load_addr;
- dbsec->sect_run_adr = asecs->run_addr;
- dbsec += 1;
- asecs += 1;
- }
-
- /* If a trampoline section was created go ahead and add its info */
- if (dlthis->tramp.tramp_sect_next_addr != 0) {
- dbmod->num_sects++;
- dbsec->sect_load_adr = asecs->load_addr;
- dbsec->sect_run_adr = asecs->run_addr;
- dbsec++;
- asecs++;
- }
-
- /* now cram in the names */
- cp = copy_tgt_strings(dbsec, dlthis->str_head,
- dlthis->debug_string_size);
-
- /* If a trampoline section was created, add its name so DLLView
- * can show the user the section info. */
- if (dlthis->tramp.tramp_sect_next_addr != 0) {
- cp = copy_tgt_strings(cp,
- dlthis->tramp.final_string_table,
- strlen(dlthis->tramp.final_string_table) +
- 1);
- }
-
- /* round off the size of the debug record, and remember same */
- hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod);
- *cp = 0; /* strictly to make our test harness happy */
- dllview_info = dllview_info_init;
- dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
- /* Initialize memory context to default heap */
- dllview_info.context = 0;
- hndl->dm.context = 0;
- /* fill in next pointer and size */
- if (mlist->next) {
- dbmod->next_module = TADDR_TO_TDATA(mlist->next->dm.dbthis);
- dbmod->next_module_size = mlist->next->dm.dbsiz;
- } else {
- dbmod->next_module_size = 0;
- dbmod->next_module = 0;
- }
- /* allocate memory for on-DSP DLLview debug record */
- if (!dlthis->myalloc)
- return;
- if (!dlthis->myalloc->dload_allocate(dlthis->myalloc, &dllview_info,
- HOST_TO_TADDR(sizeof(u32)))) {
- return;
- }
- /* Store load address of .dllview section */
- hndl->dm.dbthis = dllview_info.load_addr;
- /* Store memory context (segid) in which .dllview section
- * was allocated */
- hndl->dm.context = dllview_info.context;
- mlist->refcount += 1;
- /* swap bytes in the entire debug record, but not the string table */
- if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
- swap_words(dbmod, (char *)dbsec - (char *)dbmod,
- DLL_MODULE_BITMAP);
- }
- /* Update the DLLview list on the DSP write new record */
- if (!dlthis->myio->writemem(dlthis->myio, dbmod,
- dllview_info.load_addr, &dllview_info,
- TADDR_TO_HOST(dllview_info.size))) {
- return;
- }
- /* write new header */
- mhdr.first_module_size = hndl->dm.dbsiz;
- mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr);
- /* swap bytes in the module header, if needed */
- if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
- swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
- MODULES_HEADER_BITMAP);
- }
- dllview_info = dllview_info_init;
- if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis,
- &dllview_info,
- sizeof(struct modules_header) -
- sizeof(u16))) {
- return;
- }
- /* Add the module handle to this processor's list
- of handles with debug info */
- hndl->dm.next = mlist->next;
- if (hndl->dm.next)
- hndl->dm.next->dm.prev = hndl;
- hndl->dm.prev = (struct my_handle *)mlist;
- mlist->next = hndl; /* insert after root */
-} /* init_module_handle */
-
-/*************************************************************************
- * Procedure dynamic_unload_module
- *
- * Parameters:
- * mhandle A module handle from dynamic_load_module
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- *
- * Effect:
- * The module specified by mhandle is unloaded. Unloading causes all
- * target memory to be deallocated, all symbols defined by the module to
- * be purged, and any host-side storage used by the dynamic loader for
- * this module to be released.
- *
- * Returns:
- * Zero for success. On error, the number of errors detected is returned.
- * Individual errors are reported using syms->error_report().
- *********************************************************************** */
-int dynamic_unload_module(void *mhandle,
- struct dynamic_loader_sym *syms,
- struct dynamic_loader_allocate *alloc,
- struct dynamic_loader_initialize *init)
-{
- s16 curr_sect;
- struct ldr_section_info *asecs;
- struct my_handle *hndl;
- struct dbg_mirror_root *root;
- unsigned errcount = 0;
- struct ldr_section_info dllview_info = dllview_info_init;
- struct modules_header mhdr;
-
- hndl = (struct my_handle *)mhandle;
- if (!hndl)
- return 0; /* if handle is null, nothing to do */
- /* Clear out the module symbols
- * Note that if this is the module that defined MODULES_HEADER
- (the head of the target debug list)
- * then this operation will blow away that symbol.
- It will therefore be impossible for subsequent
- * operations to add entries to this un-referenceable list. */
- if (!syms)
- return 1;
- syms->purge_symbol_table(syms, (unsigned)hndl);
- /* Deallocate target memory for sections
- * NOTE: The trampoline section, if created, gets deleted here, too */
-
- asecs = hndl->secns;
- if (alloc)
- for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0;
- curr_sect -= 1) {
- asecs->name = NULL;
- alloc->dload_deallocate(alloc, asecs++);
- }
- root = hndl->dm.root;
- if (!root) {
- /* there is a debug list containing this module */
- goto func_end;
- }
- if (!hndl->dm.dbthis) { /* target-side dllview record exists */
- goto loop_end;
- }
- /* Retrieve memory context in which .dllview was allocated */
- dllview_info.context = hndl->dm.context;
- if (hndl->dm.prev == hndl)
- goto exitunltgt;
-
- /* target-side dllview record is in list */
- /* dequeue this record from our GPP-side mirror list */
- hndl->dm.prev->dm.next = hndl->dm.next;
- if (hndl->dm.next)
- hndl->dm.next->dm.prev = hndl->dm.prev;
- /* Update next_module of previous entry in target list
- * We are using mhdr here as a surrogate for either a
- struct modules_header or a dll_module */
- if (hndl->dm.next) {
- mhdr.first_module = TADDR_TO_TDATA(hndl->dm.next->dm.dbthis);
- mhdr.first_module_size = hndl->dm.next->dm.dbsiz;
- } else {
- mhdr.first_module = 0;
- mhdr.first_module_size = 0;
- }
- if (!init)
- goto exitunltgt;
-
- if (!init->connect(init)) {
- dload_syms_error(syms, iconnect);
- errcount += 1;
- goto exitunltgt;
- }
- /* swap bytes in the module header, if needed */
- if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) {
- swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
- MODULES_HEADER_BITMAP);
- }
- if (!init->writemem(init, &mhdr, hndl->dm.prev->dm.dbthis,
- &dllview_info, sizeof(struct modules_header) -
- sizeof(mhdr.update_flag))) {
- dload_syms_error(syms, dlvwrite);
- errcount += 1;
- }
- /* update change counter */
- root->changes += 1;
- if (!init->writemem(init, &(root->changes),
- root->dbthis + HOST_TO_TADDR
- (sizeof(mhdr.first_module) +
- sizeof(mhdr.first_module_size)),
- &dllview_info, sizeof(mhdr.update_flag))) {
- dload_syms_error(syms, dlvwrite);
- errcount += 1;
- }
- init->release(init);
-exitunltgt:
- /* release target storage */
- dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
- dllview_info.load_addr = hndl->dm.dbthis;
- if (alloc)
- alloc->dload_deallocate(alloc, &dllview_info);
- root->refcount -= 1;
- /* target-side dllview record exists */
-loop_end:
-#ifndef DEBUG_HEADER_IN_LOADER
- if (root->refcount <= 0) {
- /* if all references gone, blow off the header */
- /* our root symbol may be gone due to the Purge above,
- but if not, do not destroy the root */
- if (syms->find_matching_symbol
- (syms, loader_dllview_root) == NULL)
- syms->dload_deallocate(syms, root);
- }
-#endif
-func_end:
- /* there is a debug list containing this module */
- syms->dload_deallocate(syms, mhandle); /* release our storage */
- return errcount;
-} /* dynamic_unload_module */
-
-#if BITS_PER_AU > BITS_PER_BYTE
-/*************************************************************************
- * Procedure unpack_name
- *
- * Parameters:
- * soffset Byte offset into the string table
- *
- * Effect:
- * Returns a pointer to the string specified by the offset supplied, or
- * NULL for error.
- *
- *********************************************************************** */
-static char *unpack_name(struct dload_state *dlthis, u32 soffset)
-{
- u8 tmp, *src;
- char *dst;
-
- if (soffset >= dlthis->dfile_hdr.df_strtab_size) {
- dload_error(dlthis, "Bad string table offset " FMT_UI32,
- soffset);
- return NULL;
- }
- src = (uint_least8_t *) dlthis->str_head +
- (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
- dst = dlthis->str_temp;
- if (soffset & 1)
- *dst++ = *src++; /* only 1 character in first word */
- do {
- tmp = *src++;
- *dst = (tmp >> BITS_PER_BYTE);
- if (!(*dst++))
- break;
- } while ((*dst++ = tmp & BYTE_MASK));
- dlthis->temp_len = dst - dlthis->str_temp;
- /* squirrel away length including terminating null */
- return dlthis->str_temp;
-} /* unpack_name */
-#endif
diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h
deleted file mode 100644
index b9d079b96190..000000000000
--- a/drivers/staging/tidspbridge/dynload/dload_internal.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * dload_internal.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _DLOAD_INTERNAL_
-#define _DLOAD_INTERNAL_
-
-#include <linux/types.h>
-
-/*
- * Internal state definitions for the dynamic loader
- */
-
-/* type used for relocation intermediate results */
-typedef s32 rvalue;
-
-/* unsigned version of same; must have at least as many bits */
-typedef u32 urvalue;
-
-/*
- * Dynamic loader configuration constants
- */
-/* error issued if input has more sections than this limit */
-#define REASONABLE_SECTION_LIMIT 100
-
-/* (Addressable unit) value used to clear BSS section */
-#define DLOAD_FILL_BSS 0
-
-/*
- * Reorder maps explained (?)
- *
- * The doff file format defines a 32-bit pattern used to determine the
- * byte order of an image being read. That value is
- * BYTE_RESHUFFLE_VALUE == 0x00010203
- * For purposes of the reorder routine, we would rather have the all-is-OK
- * for 32-bits pattern be 0x03020100. This first macro makes the
- * translation from doff file header value to MAP value: */
-#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
-/* This translation is made in dload_headers. Thereafter, the all-is-OK
- * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
- * But sadly, not all bits of the doff file are 32-bit integers.
- * The notable exceptions are strings and image bits.
- * Strings obey host byte order: */
-#if defined(_BIG_ENDIAN)
-#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
-#else
-#define HOST_BYTE_ORDER(cookedmap) (cookedmap)
-#endif
-/* Target bits consist of target AUs (could be bytes, or 16-bits,
- * or 32-bits) stored as an array in host order. A target order
- * map is defined by: */
-#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
-#define TARGET_ORDER(cookedmap) (cookedmap)
-#elif TARGET_AU_BITS > 8
-#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
-#else
-#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
-#endif
-
-/* forward declaration for handle returned by dynamic loader */
-struct my_handle;
-
-/*
- * a list of module handles, which mirrors the debug list on the target
- */
-struct dbg_mirror_root {
- /* must be same as dbg_mirror_list; __DLModules address on target */
- u32 dbthis;
- struct my_handle *next; /* must be same as dbg_mirror_list */
- u16 changes; /* change counter */
- u16 refcount; /* number of modules referencing this root */
-};
-
-struct dbg_mirror_list {
- u32 dbthis;
- struct my_handle *next, *prev;
- struct dbg_mirror_root *root;
- u16 dbsiz;
- u32 context; /* Save context for .dllview memory allocation */
-};
-
-#define VARIABLE_SIZE 1
-/*
- * the structure we actually return as an opaque module handle
- */
-struct my_handle {
- struct dbg_mirror_list dm; /* !!! must be first !!! */
- /* sections following << 1, LSB is set for big-endian target */
- u16 secn_count;
- struct ldr_section_info secns[VARIABLE_SIZE];
-};
-#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
- sizeof(struct ldr_section_info))
-/* real size of my_handle */
-
-/*
- * reduced symbol structure used for symbols during relocation
- */
-struct local_symbol {
- s32 value; /* Relocated symbol value */
- s32 delta; /* Original value in input file */
- s16 secnn; /* section number */
- s16 sclass; /* symbol class */
-};
-
-/*
- * Trampoline data structures
- */
-#define TRAMP_NO_GEN_AVAIL 65535
-#define TRAMP_SYM_PREFIX "__$dbTR__"
-#define TRAMP_SECT_NAME ".dbTR"
-/* MUST MATCH THE LENGTH ABOVE!! */
-#define TRAMP_SYM_PREFIX_LEN 9
-/* Includes NULL termination */
-#define TRAMP_SYM_HEX_ASCII_LEN 9
-
-#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\
- (unsigned long)(&((type *)0)->field)))
-#ifndef FIELD_OFFSET
-#define FIELD_OFFSET(type, field) ((unsigned long)(&((type *)0)->field))
-#endif
-
-/*
- The trampoline code for the target is located in a table called
- "tramp_gen_info" with is indexed by looking up the index in the table
- "tramp_map". The tramp_map index is acquired using the target
- HASH_FUNC on the relocation type that caused the trampoline. Each
- trampoline code table entry MUST follow this format:
-
- |----------------------------------------------|
- | tramp_gen_code_hdr |
- |----------------------------------------------|
- | Trampoline image code |
- | (the raw instruction code for the target) |
- |----------------------------------------------|
- | Relocation entries for the image code |
- |----------------------------------------------|
-
- This is very similar to how image data is laid out in the DOFF file
- itself.
- */
-struct tramp_gen_code_hdr {
- u32 tramp_code_size; /* in BYTES */
- u32 num_relos;
- u32 relo_offset; /* in BYTES */
-};
-
-struct tramp_img_pkt {
- struct tramp_img_pkt *next; /* MUST BE FIRST */
- u32 base;
- struct tramp_gen_code_hdr hdr;
- u8 payload[VARIABLE_SIZE];
-};
-
-struct tramp_img_dup_relo {
- struct tramp_img_dup_relo *next;
- struct reloc_record_t relo;
-};
-
-struct tramp_img_dup_pkt {
- struct tramp_img_dup_pkt *next; /* MUST BE FIRST */
- s16 secnn;
- u32 offset;
- struct image_packet_t img_pkt;
- struct tramp_img_dup_relo *relo_chain;
-
- /* PAYLOAD OF IMG PKT FOLLOWS */
-};
-
-struct tramp_sym {
- struct tramp_sym *next; /* MUST BE FIRST */
- u32 index;
- u32 str_index;
- struct local_symbol sym_info;
-};
-
-struct tramp_string {
- struct tramp_string *next; /* MUST BE FIRST */
- u32 index;
- char str[VARIABLE_SIZE]; /* NULL terminated */
-};
-
-struct tramp_info {
- u32 tramp_sect_next_addr;
- struct ldr_section_info sect_info;
-
- struct tramp_sym *symbol_head;
- struct tramp_sym *symbol_tail;
- u32 tramp_sym_next_index;
- struct local_symbol *final_sym_table;
-
- struct tramp_string *string_head;
- struct tramp_string *string_tail;
- u32 tramp_string_next_index;
- u32 tramp_string_size;
- char *final_string_table;
-
- struct tramp_img_pkt *tramp_pkts;
- struct tramp_img_dup_pkt *dup_pkts;
-};
-
-/*
- * States of the .cinit state machine
- */
-enum cinit_mode {
- CI_COUNT = 0, /* expecting a count */
- CI_ADDRESS, /* expecting an address */
-#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */
- CI_PARTADDRESS, /* have only part of the address */
-#endif
- CI_COPY, /* in the middle of copying data */
- CI_DONE /* end of .cinit table */
-};
-
-/*
- * The internal state of the dynamic loader, which is passed around as
- * an object
- */
-struct dload_state {
- struct dynamic_loader_stream *strm; /* The module input stream */
- struct dynamic_loader_sym *mysym; /* Symbols for this session */
- /* target memory allocator */
- struct dynamic_loader_allocate *myalloc;
- struct dynamic_loader_initialize *myio; /* target memory initializer */
- unsigned myoptions; /* Options parameter dynamic_load_module */
-
- char *str_head; /* Pointer to string table */
-#if BITS_PER_AU > BITS_PER_BYTE
- char *str_temp; /* Pointer to temporary buffer for strings */
- /* big enough to hold longest string */
- unsigned temp_len; /* length of last temporary string */
- char *xstrings; /* Pointer to buffer for expanded */
- /* strings for sec names */
-#endif
- /* Total size of strings for DLLView section names */
- unsigned debug_string_size;
- /* Pointer to parallel section info for allocated sections only */
- struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */
- struct ldr_section_info *ldr_sections;
-#if TMS32060
- /* The address of the start of the .bss section */
- ldr_addr bss_run_base;
-#endif
- struct local_symbol *local_symtab; /* Relocation symbol table */
-
- /* pointer to DL section info for the section being relocated */
- struct ldr_section_info *image_secn;
- /* change in run address for current section during relocation */
- ldr_addr delta_runaddr;
- ldr_addr image_offset; /* offset of current packet in section */
- enum cinit_mode cinit_state; /* current state of cload_cinit() */
- int cinit_count; /* the current count */
- ldr_addr cinit_addr; /* the current address */
- s16 cinit_page; /* the current page */
- /* Handle to be returned by dynamic_load_module */
- struct my_handle *myhandle;
- unsigned dload_errcount; /* Total # of errors reported so far */
- /* Number of target sections that require allocation and relocation */
- unsigned allocated_secn_count;
-#ifndef TARGET_ENDIANNESS
- int big_e_target; /* Target data in big-endian format */
-#endif
- /* map for reordering bytes, 0 if not needed */
- u32 reorder_map;
- struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */
- struct doff_verify_rec_t verify; /* Verify record */
-
- struct tramp_info tramp; /* Trampoline data, if needed */
-
- int relstkidx; /* index into relocation value stack */
- /* relocation value stack used in relexp.c */
- rvalue relstk[STATIC_EXPR_STK_SIZE];
-
-};
-
-#ifdef TARGET_ENDIANNESS
-#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
-#else
-#define TARGET_BIG_ENDIAN (dlthis->big_e_target)
-#endif
-
-/*
- * Exports from cload.c to rest of the world
- */
-extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
-extern void dload_syms_error(struct dynamic_loader_sym *syms,
- const char *errtxt, ...);
-extern void dload_headers(struct dload_state *dlthis);
-extern void dload_strings(struct dload_state *dlthis, bool sec_names_only);
-extern void dload_sections(struct dload_state *dlthis);
-extern void dload_reorder(void *data, int dsiz, u32 map);
-extern u32 dload_checksum(void *data, unsigned siz);
-
-#if HOST_ENDIANNESS
-extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
-#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
-extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
-#endif
-#endif
-
-/*
- * exported by reloc.c
- */
-extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data,
- struct reloc_record_t *rp, bool *tramps_generated,
- bool second_pass);
-
-extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data,
- int fieldsz, int offset, unsigned sgn);
-
-extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data,
- int fieldsz, int offset, unsigned sgn);
-
-/*
- * exported by tramp.c
- */
-extern bool dload_tramp_avail(struct dload_state *dlthis,
- struct reloc_record_t *rp);
-
-int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
- u32 image_offset, struct image_packet_t *ipacket,
- struct reloc_record_t *rp);
-
-extern int dload_tramp_pkt_udpate(struct dload_state *dlthis,
- s16 secnn, u32 image_offset,
- struct image_packet_t *ipacket);
-
-extern int dload_tramp_finalize(struct dload_state *dlthis);
-
-extern void dload_tramp_cleanup(struct dload_state *dlthis);
-
-#endif /* _DLOAD_INTERNAL_ */
diff --git a/drivers/staging/tidspbridge/dynload/doff.h b/drivers/staging/tidspbridge/dynload/doff.h
deleted file mode 100644
index a7c3145746ee..000000000000
--- a/drivers/staging/tidspbridge/dynload/doff.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * doff.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Structures & definitions used for dynamically loaded modules file format.
- * This format is a reformatted version of COFF. It optimizes the layout for
- * the dynamic loader.
- *
- * .dof files, when viewed as a sequence of 32-bit integers, look the same
- * on big-endian and little-endian machines.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _DOFF_H
-#define _DOFF_H
-
-
-#define BYTE_RESHUFFLE_VALUE 0x00010203
-
-/* DOFF file header containing fields categorizing the remainder of the file */
-struct doff_filehdr_t {
-
- /* string table size, including filename, in bytes */
- u32 df_strtab_size;
-
- /* entry point if one exists */
- u32 df_entrypt;
-
- /* identifies byte ordering of file;
- * always set to BYTE_RESHUFFLE_VALUE */
- u32 df_byte_reshuffle;
-
- /* Size of the string table up to and including the last section name */
- /* Size includes the name of the COFF file also */
- u32 df_scn_name_size;
-
-#ifndef _BIG_ENDIAN
- /* number of symbols */
- u16 df_no_syms;
-
- /* length in bytes of the longest string, including terminating NULL */
- /* excludes the name of the file */
- u16 df_max_str_len;
-
- /* total number of sections including no-load ones */
- u16 df_no_scns;
-
- /* number of sections containing target code allocated or downloaded */
- u16 df_target_scns;
-
- /* unique id for dll file format & version */
- u16 df_doff_version;
-
- /* identifies ISA */
- u16 df_target_id;
-
- /* useful file flags */
- u16 df_flags;
-
- /* section reference for entry point, N_UNDEF for none, */
- /* N_ABS for absolute address */
- s16 df_entry_secn;
-#else
- /* length of the longest string, including terminating NULL */
- u16 df_max_str_len;
-
- /* number of symbols */
- u16 df_no_syms;
-
- /* number of sections containing target code allocated or downloaded */
- u16 df_target_scns;
-
- /* total number of sections including no-load ones */
- u16 df_no_scns;
-
- /* identifies ISA */
- u16 df_target_id;
-
- /* unique id for dll file format & version */
- u16 df_doff_version;
-
- /* section reference for entry point, N_UNDEF for none, */
- /* N_ABS for absolute address */
- s16 df_entry_secn;
-
- /* useful file flags */
- u16 df_flags;
-#endif
- /* checksum for file header record */
- u32 df_checksum;
-
-};
-
-/* flags in the df_flags field */
-#define DF_LITTLE 0x100
-#define DF_BIG 0x200
-#define DF_BYTE_ORDER (DF_LITTLE | DF_BIG)
-
-/* Supported processors */
-#define TMS470_ID 0x97
-#define LEAD_ID 0x98
-#define TMS32060_ID 0x99
-#define LEAD3_ID 0x9c
-
-/* Primary processor for loading */
-#if TMS32060
-#define TARGET_ID TMS32060_ID
-#endif
-
-/* Verification record containing values used to test integrity of the bits */
-struct doff_verify_rec_t {
-
- /* time and date stamp */
- u32 dv_timdat;
-
- /* checksum for all section records */
- u32 dv_scn_rec_checksum;
-
- /* checksum for string table */
- u32 dv_str_tab_checksum;
-
- /* checksum for symbol table */
- u32 dv_sym_tab_checksum;
-
- /* checksum for verification record */
- u32 dv_verify_rec_checksum;
-
-};
-
-/* String table is an array of null-terminated strings. The first entry is
- * the filename, which is added by DLLcreate. No new structure definitions
- * are required.
- */
-
-/* Section Records including information on the corresponding image packets */
-/*
- * !!WARNING!!
- *
- * This structure is expected to match in form ldr_section_info in
- * dynamic_loader.h
- */
-
-struct doff_scnhdr_t {
-
- s32 ds_offset; /* offset into string table of name */
- s32 ds_paddr; /* RUN address, in target AU */
- s32 ds_vaddr; /* LOAD address, in target AU */
- s32 ds_size; /* section size, in target AU */
-#ifndef _BIG_ENDIAN
- u16 ds_page; /* memory page id */
- u16 ds_flags; /* section flags */
-#else
- u16 ds_flags; /* section flags */
- u16 ds_page; /* memory page id */
-#endif
- u32 ds_first_pkt_offset;
- /* Absolute byte offset into the file */
- /* where the first image record resides */
-
- s32 ds_nipacks; /* number of image packets */
-
-};
-
-/* Symbol table entry */
-struct doff_syment_t {
-
- s32 dn_offset; /* offset into string table of name */
- s32 dn_value; /* value of symbol */
-#ifndef _BIG_ENDIAN
- s16 dn_scnum; /* section number */
- s16 dn_sclass; /* storage class */
-#else
- s16 dn_sclass; /* storage class */
- s16 dn_scnum; /* section number, 1-based */
-#endif
-
-};
-
-/* special values for dn_scnum */
-#define DN_UNDEF 0 /* undefined symbol */
-#define DN_ABS (-1) /* value of symbol is absolute */
-/* special values for dn_sclass */
-#define DN_EXT 2
-#define DN_STATLAB 20
-#define DN_EXTLAB 21
-
-/* Default value of image bits in packet */
-/* Configurable by user on the command line */
-#define IMAGE_PACKET_SIZE 1024
-
-/* An image packet contains a chunk of data from a section along with */
-/* information necessary for its processing. */
-struct image_packet_t {
-
- s32 num_relocs; /* number of relocations for */
- /* this packet */
-
- s32 packet_size; /* number of bytes in array */
- /* "bits" occupied by */
- /* valid data. Could be */
- /* < IMAGE_PACKET_SIZE to */
- /* prevent splitting a */
- /* relocation across packets. */
- /* Last packet of a section */
- /* will most likely contain */
- /* < IMAGE_PACKET_SIZE bytes */
- /* of valid data */
-
- s32 img_chksum; /* Checksum for image packet */
- /* and the corresponding */
- /* relocation records */
-
- u8 *img_data; /* Actual data in section */
-
-};
-
-/* The relocation structure definition matches the COFF version. Offsets */
-/* however are relative to the image packet base not the section base. */
-struct reloc_record_t {
-
- s32 vaddr;
-
- /* expressed in target AUs */
-
- union {
- struct {
-#ifndef _BIG_ENDIAN
- u8 _offset; /* bit offset of rel fld */
- u8 _fieldsz; /* size of rel fld */
- u8 _wordsz; /* # bytes containing rel fld */
- u8 _dum1;
- u16 _dum2;
- u16 _type;
-#else
- unsigned _dum1:8;
- unsigned _wordsz:8; /* # bytes containing rel fld */
- unsigned _fieldsz:8; /* size of rel fld */
- unsigned _offset:8; /* bit offset of rel fld */
- u16 _type;
- u16 _dum2;
-#endif
- } _r_field;
-
- struct {
- u32 _spc; /* image packet relative PC */
-#ifndef _BIG_ENDIAN
- u16 _dum;
- u16 _type; /* relocation type */
-#else
- u16 _type; /* relocation type */
- u16 _dum;
-#endif
- } _r_spc;
-
- struct {
- u32 _uval; /* constant value */
-#ifndef _BIG_ENDIAN
- u16 _dum;
- u16 _type; /* relocation type */
-#else
- u16 _type; /* relocation type */
- u16 _dum;
-#endif
- } _r_uval;
-
- struct {
- s32 _symndx; /* 32-bit sym tbl index */
-#ifndef _BIG_ENDIAN
- u16 _disp; /* extra addr encode data */
- u16 _type; /* relocation type */
-#else
- u16 _type; /* relocation type */
- u16 _disp; /* extra addr encode data */
-#endif
- } _r_sym;
- } _u_reloc;
-
-};
-
-/* abbreviations for convenience */
-#ifndef TYPE
-#define TYPE _u_reloc._r_sym._type
-#define UVAL _u_reloc._r_uval._uval
-#define SYMNDX _u_reloc._r_sym._symndx
-#define OFFSET _u_reloc._r_field._offset
-#define FIELDSZ _u_reloc._r_field._fieldsz
-#define WORDSZ _u_reloc._r_field._wordsz
-#define R_DISP _u_reloc._r_sym._disp
-#endif
-
-/**************************************************************************** */
-/* */
-/* Important DOFF macros used for file processing */
-/* */
-/**************************************************************************** */
-
-/* DOFF Versions */
-#define DOFF0 0
-
-/* Return the address/size >= to addr that is at a 32-bit boundary */
-/* This assumes that a byte is 8 bits */
-#define DOFF_ALIGN(addr) (((addr) + 3) & ~3UL)
-
-/**************************************************************************** */
-/* */
-/* The DOFF section header flags field is laid out as follows: */
-/* */
-/* Bits 0-3 : Section Type */
-/* Bit 4 : Set when section requires target memory to be allocated by DL */
-/* Bit 5 : Set when section requires downloading */
-/* Bits 8-11: Alignment, same as COFF */
-/* */
-/**************************************************************************** */
-
-/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */
-#define DS_SECTION_TYPE_MASK 0xF
-/* DS_ALLOCATE indicates whether a section needs space on the target */
-#define DS_ALLOCATE_MASK 0x10
-/* DS_DOWNLOAD indicates that the loader needs to copy bits */
-#define DS_DOWNLOAD_MASK 0x20
-/* Section alignment requirement in AUs */
-#define DS_ALIGNMENT_SHIFT 8
-
-static inline bool dload_check_type(struct doff_scnhdr_t *sptr, u32 flag)
-{
- return (sptr->ds_flags & DS_SECTION_TYPE_MASK) == flag;
-}
-static inline bool ds_needs_allocation(struct doff_scnhdr_t *sptr)
-{
- return sptr->ds_flags & DS_ALLOCATE_MASK;
-}
-
-static inline bool ds_needs_download(struct doff_scnhdr_t *sptr)
-{
- return sptr->ds_flags & DS_DOWNLOAD_MASK;
-}
-
-static inline int ds_alignment(u16 ds_flags)
-{
- return 1 << ((ds_flags >> DS_ALIGNMENT_SHIFT) & DS_SECTION_TYPE_MASK);
-}
-
-
-#endif /* _DOFF_H */
diff --git a/drivers/staging/tidspbridge/dynload/getsection.c b/drivers/staging/tidspbridge/dynload/getsection.c
deleted file mode 100644
index e0b37714dd65..000000000000
--- a/drivers/staging/tidspbridge/dynload/getsection.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * getsection.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <dspbridge/getsection.h>
-#include "header.h"
-
-/*
- * Error strings
- */
-static const char readstrm[] = { "Error reading %s from input stream" };
-static const char seek[] = { "Set file position to %d failed" };
-static const char isiz[] = { "Bad image packet size %d" };
-static const char err_checksum[] = { "Checksum failed on %s" };
-
-static const char err_reloc[] = { "dload_get_section unable to read"
- "sections containing relocation entries"
-};
-
-#if BITS_PER_AU > BITS_PER_BYTE
-static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" };
-static const char stbl[] = { "Bad string table offset " FMT_UI32 };
-#endif
-
-/************************************************************** */
-/********************* SUPPORT FUNCTIONS ********************** */
-/************************************************************** */
-
-#if BITS_PER_AU > BITS_PER_BYTE
-/**************************************************************************
- * Procedure unpack_sec_name
- *
- * Parameters:
- * dlthis Handle from dload_module_open for this module
- * soffset Byte offset into the string table
- * dst Place to store the expanded string
- *
- * Effect:
- * Stores a string from the string table into the destination, expanding
- * it in the process. Returns a pointer just past the end of the stored
- * string on success, or NULL on failure.
- *
- ************************************************************************ */
-static char *unpack_sec_name(struct dload_state *dlthis, u32 soffset, char *dst)
-{
- u8 tmp, *src;
-
- if (soffset >= dlthis->dfile_hdr.df_scn_name_size) {
- dload_error(dlthis, stbl, soffset);
- return NULL;
- }
- src = (u8 *) dlthis->str_head +
- (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
- if (soffset & 1)
- *dst++ = *src++; /* only 1 character in first word */
- do {
- tmp = *src++;
- *dst = (tmp >> BITS_PER_BYTE)
- if (!(*dst++))
- break;
- } while ((*dst++ = tmp & BYTE_MASK));
-
- return dst;
-}
-
-/**************************************************************************
- * Procedure expand_sec_names
- *
- * Parameters:
- * dlthis Handle from dload_module_open for this module
- *
- * Effect:
- * Allocates a buffer, unpacks and copies strings from string table into it.
- * Stores a pointer to the buffer into a state variable.
- ************************************************************************* */
-static void expand_sec_names(struct dload_state *dlthis)
-{
- char *xstrings, *curr, *next;
- u32 xsize;
- u16 sec;
- struct ldr_section_info *shp;
- /* assume worst-case size requirement */
- xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns;
- xstrings = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, xsize);
- if (xstrings == NULL) {
- dload_error(dlthis, err_alloc, xsize);
- return;
- }
- dlthis->xstrings = xstrings;
- /* For each sec, copy and expand its name */
- curr = xstrings;
- for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
- shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
- next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr);
- if (next == NULL)
- break; /* error */
- shp->name = curr;
- curr = next;
- }
-}
-
-#endif
-
-/************************************************************** */
-/********************* EXPORTED FUNCTIONS ********************* */
-/************************************************************** */
-
-/**************************************************************************
- * Procedure dload_module_open
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side malloc/free and error reporting functions.
- * Other methods are unused.
- *
- * Effect:
- * Reads header information from a dynamic loader module using the
- specified
- * stream object, and returns a handle for the module information. This
- * handle may be used in subsequent query calls to obtain information
- * contained in the module.
- *
- * Returns:
- * NULL if an error is encountered, otherwise a module handle for use
- * in subsequent operations.
- ************************************************************************* */
-void *dload_module_open(struct dynamic_loader_stream *module,
- struct dynamic_loader_sym *syms)
-{
- struct dload_state *dlthis; /* internal state for this call */
- unsigned *dp, sz;
- u32 sec_start;
-#if BITS_PER_AU <= BITS_PER_BYTE
- u16 sec;
-#endif
-
- /* Check that mandatory arguments are present */
- if (!module || !syms) {
- if (syms != NULL)
- dload_syms_error(syms, "Required parameter is NULL");
-
- return NULL;
- }
-
- dlthis = (struct dload_state *)
- syms->dload_allocate(syms, sizeof(struct dload_state));
- if (!dlthis) {
- /* not enough storage */
- dload_syms_error(syms, "Can't allocate module info");
- return NULL;
- }
-
- /* clear our internal state */
- dp = (unsigned *)dlthis;
- for (sz = sizeof(struct dload_state) / sizeof(unsigned);
- sz > 0; sz -= 1)
- *dp++ = 0;
-
- dlthis->strm = module;
- dlthis->mysym = syms;
-
- /* read in the doff image and store in our state variable */
- dload_headers(dlthis);
-
- if (!dlthis->dload_errcount)
- dload_strings(dlthis, true);
-
- /* skip ahead past the unread portion of the string table */
- sec_start = sizeof(struct doff_filehdr_t) +
- sizeof(struct doff_verify_rec_t) +
- BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size));
-
- if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) {
- dload_error(dlthis, seek, sec_start);
- return NULL;
- }
-
- if (!dlthis->dload_errcount)
- dload_sections(dlthis);
-
- if (dlthis->dload_errcount) {
- dload_module_close(dlthis); /* errors, blow off our state */
- dlthis = NULL;
- return NULL;
- }
-#if BITS_PER_AU > BITS_PER_BYTE
- /* Expand all section names from the string table into the */
- /* state variable, and convert section names from a relative */
- /* string table offset to a pointers to the expanded string. */
- expand_sec_names(dlthis);
-#else
- /* Convert section names from a relative string table offset */
- /* to a pointer into the string table. */
- for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
- struct ldr_section_info *shp =
- (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
- shp->name = dlthis->str_head + *(u32 *) &shp->name;
- }
-#endif
-
- return dlthis;
-}
-
-/***************************************************************************
- * Procedure dload_get_section_info
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- * section_name Pointer to the string name of the section desired
- * section_info Address of a section info structure pointer to be
- * initialized
- *
- * Effect:
- * Finds the specified section in the module information, and initializes
- * the provided struct ldr_section_info pointer.
- *
- * Returns:
- * true for success, false for section not found
- ************************************************************************* */
-int dload_get_section_info(void *minfo, const char *section_name,
- const struct ldr_section_info **const section_info)
-{
- struct dload_state *dlthis;
- struct ldr_section_info *shp;
- u16 sec;
-
- dlthis = (struct dload_state *)minfo;
- if (!dlthis)
- return false;
-
- for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
- shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec];
- if (strcmp(section_name, shp->name) == 0) {
- *section_info = shp;
- return true;
- }
- }
-
- return false;
-}
-
-#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
-
-/**************************************************************************
- * Procedure dload_get_section
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- * section_info Pointer to a section info structure for the desired
- * section
- * section_data Buffer to contain the section initialized data
- *
- * Effect:
- * Copies the initialized data for the specified section into the
- * supplied buffer.
- *
- * Returns:
- * true for success, false for section not found
- ************************************************************************* */
-int dload_get_section(void *minfo,
- const struct ldr_section_info *section_info,
- void *section_data)
-{
- struct dload_state *dlthis;
- u32 pos;
- struct doff_scnhdr_t *sptr = NULL;
- s32 nip;
- struct image_packet_t ipacket;
- s32 ipsize;
- u32 checks;
- s8 *dest = (s8 *) section_data;
-
- dlthis = (struct dload_state *)minfo;
- if (!dlthis)
- return false;
- sptr = (struct doff_scnhdr_t *)section_info;
- if (sptr == NULL)
- return false;
-
- /* skip ahead to the start of the first packet */
- pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset));
- if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) {
- dload_error(dlthis, seek, pos);
- return false;
- }
-
- nip = sptr->ds_nipacks;
- while ((nip -= 1) >= 0) { /* for each packet */
- /* get the fixed header bits */
- if (dlthis->strm->read_buffer(dlthis->strm, &ipacket,
- IPH_SIZE) != IPH_SIZE) {
- dload_error(dlthis, readstrm, "image packet");
- return false;
- }
- /* reorder the header if need be */
- if (dlthis->reorder_map)
- dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map);
-
- /* Now read the packet image bits. Note: round the size up to
- * the next multiple of 4 bytes; this is what checksum
- * routines want. */
- ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.packet_size));
- if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
- dload_error(dlthis, isiz, ipsize);
- return false;
- }
- if (dlthis->strm->read_buffer
- (dlthis->strm, dest, ipsize) != ipsize) {
- dload_error(dlthis, readstrm, "image packet");
- return false;
- }
- /* reorder the bytes if need be */
-#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
- if (dlthis->reorder_map)
- dload_reorder(dest, ipsize, dlthis->reorder_map);
-
- checks = dload_checksum(dest, ipsize);
-#else
- if (dlthis->dfile_hdr.df_byte_reshuffle !=
- TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
- /* put image bytes in big-endian order, not PC order */
- dload_reorder(dest, ipsize,
- TARGET_ORDER(dlthis->
- dfile_hdr.df_byte_reshuffle));
- }
-#if TARGET_AU_BITS > 8
- checks = dload_reverse_checksum16(dest, ipsize);
-#else
- checks = dload_reverse_checksum(dest, ipsize);
-#endif
-#endif
- checks += dload_checksum(&ipacket, IPH_SIZE);
-
- /* NYI: unable to handle relocation entries here. Reloc
- * entries referring to fields that span the packet boundaries
- * may result in packets of sizes that are not multiple of
- * 4 bytes. Our checksum implementation works on 32-bit words
- * only. */
- if (ipacket.num_relocs != 0) {
- dload_error(dlthis, err_reloc, ipsize);
- return false;
- }
-
- if (~checks) {
- dload_error(dlthis, err_checksum, "image packet");
- return false;
- }
-
- /*Advance destination ptr by the size of the just-read packet */
- dest += ipsize;
- }
-
- return true;
-}
-
-/***************************************************************************
- * Procedure dload_module_close
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- *
- * Effect:
- * Releases any storage associated with the module handle. On return,
- * the module handle is invalid.
- *
- * Returns:
- * Zero for success. On error, the number of errors detected is returned.
- * Individual errors are reported using syms->error_report(), where syms was
- * an argument to dload_module_open
- ************************************************************************* */
-void dload_module_close(void *minfo)
-{
- struct dload_state *dlthis;
-
- dlthis = (struct dload_state *)minfo;
- if (!dlthis)
- return;
-
- if (dlthis->str_head)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- dlthis->str_head);
-
- if (dlthis->sect_hdrs)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- dlthis->sect_hdrs);
-
-#if BITS_PER_AU > BITS_PER_BYTE
- if (dlthis->xstrings)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- dlthis->xstrings);
-
-#endif
-
- dlthis->mysym->dload_deallocate(dlthis->mysym, dlthis);
-}
diff --git a/drivers/staging/tidspbridge/dynload/header.h b/drivers/staging/tidspbridge/dynload/header.h
deleted file mode 100644
index 5b50a15a343e..000000000000
--- a/drivers/staging/tidspbridge/dynload/header.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * header.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/string.h>
-#define DL_STRCMP strcmp
-
-/* maximum parenthesis nesting in relocation stack expressions */
-#define STATIC_EXPR_STK_SIZE 10
-
-#include <linux/types.h>
-
-#include "doff.h"
-#include <dspbridge/dynamic_loader.h>
-#include "params.h"
-#include "dload_internal.h"
-#include "reloc_table.h"
-
-/*
- * Plausibility limits
- *
- * These limits are imposed upon the input DOFF file as a check for validity.
- * They are hard limits, in that the load will fail if they are exceeded.
- * The numbers selected are arbitrary, in that the loader implementation does
- * not require these limits.
- */
-
-/* maximum number of bytes in string table */
-#define MAX_REASONABLE_STRINGTAB (0x100000)
-/* maximum number of code,data,etc. sections */
-#define MAX_REASONABLE_SECTIONS (200)
-/* maximum number of linker symbols */
-#define MAX_REASONABLE_SYMBOLS (100000)
-
-/* shift count to align F_BIG with DLOAD_LITTLE */
-#define ALIGN_COFF_ENDIANNESS 7
-#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS)
diff --git a/drivers/staging/tidspbridge/dynload/module_list.h b/drivers/staging/tidspbridge/dynload/module_list.h
deleted file mode 100644
index a216bb131a40..000000000000
--- a/drivers/staging/tidspbridge/dynload/module_list.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * dspbridge/mpu_driver/src/dynload/module_list.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * This C header file gives the layout of the data structure created by the
- * dynamic loader to describe the set of modules loaded into the DSP.
- *
- * Linked List Structure:
- * ----------------------
- * The data structure defined here is a singly-linked list. The list
- * represents the set of modules which are currently loaded in the DSP memory.
- * The first entry in the list is a header record which contains a flag
- * representing the state of the list. The rest of the entries in the list
- * are module records.
- *
- * Global symbol _DLModules designates the first record in the list (i.e. the
- * header record). This symbol must be defined in any program that wishes to
- * use DLLview plug-in.
- *
- * String Representation:
- * ----------------------
- * The string names of the module and its sections are stored in a block of
- * memory which follows the module record itself. The strings are ordered:
- * module name first, followed by section names in order from the first
- * section to the last. String names are tightly packed arrays of 8-bit
- * characters (two characters per 16-bit word on the C55x). Strings are
- * zero-byte-terminated.
- *
- * Creating and updating the list:
- * -------------------------------
- * Upon loading a new module into the DSP memory the dynamic loader inserts a
- * new module record as the first module record in the list. The fields of
- * this module record are initialized to reflect the properties of the module.
- * The dynamic loader does NOT increment the flag/counter in the list's header
- * record.
- *
- * Upon unloading a module from the DSP memory the dynamic loader removes the
- * module's record from this list. The dynamic loader also increments the
- * flag/counter in the list's header record to indicate that the list has been
- * changed.
- */
-
-#ifndef _MODULE_LIST_H_
-#define _MODULE_LIST_H_
-
-#include <linux/types.h>
-
-/* Global pointer to the modules_header structure */
-#define MODULES_HEADER "_DLModules"
-#define MODULES_HEADER_NO_UNDERSCORE "DLModules"
-
-/* Initial version number */
-#define INIT_VERSION 1
-
-/* Verification number -- to be recorded in each module record */
-#define VERIFICATION 0x79
-
-/* forward declarations */
-struct dll_module;
-struct dll_sect;
-
-/* the first entry in the list is the modules_header record;
- * its address is contained in the global _DLModules pointer */
-struct modules_header {
-
- /*
- * Address of the first dll_module record in the list or NULL.
- * Note: for C55x this is a word address (C55x data is
- * word-addressable)
- */
- u32 first_module;
-
- /* Combined storage size (in target addressable units) of the
- * dll_module record which follows this header record, or zero
- * if the list is empty. This size includes the module's string table.
- * Note: for C55x the unit is a 16-bit word */
- u16 first_module_size;
-
- /* Counter is incremented whenever a module record is removed from
- * the list */
- u16 update_flag;
-
-};
-
-/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are:
- * 0 => a 32-bit value, 1 => 2 16-bit values */
-/* swapping bitmap for type modules_header */
-#define MODULES_HEADER_BITMAP 0x2
-
-/* information recorded about each section in a module */
-struct dll_sect {
-
- /* Load-time address of the section.
- * Note: for C55x this is a byte address for program sections, and
- * a word address for data sections. C55x program memory is
- * byte-addressable, while data memory is word-addressable. */
- u32 sect_load_adr;
-
- /* Run-time address of the section.
- * Note 1: for C55x this is a byte address for program sections, and
- * a word address for data sections.
- * Note 2: for C55x two most significant bits of this field indicate
- * the section type: '00' for a code section, '11' for a data section
- * (C55 addresses are really only 24-bits wide). */
- u32 sect_run_adr;
-
-};
-
-/* the rest of the entries in the list are module records */
-struct dll_module {
-
- /* Address of the next dll_module record in the list, or 0 if this is
- * the last record in the list.
- * Note: for C55x this is a word address (C55x data is
- * word-addressable) */
- u32 next_module;
-
- /* Combined storage size (in target addressable units) of the
- * dll_module record which follows this one, or zero if this is the
- * last record in the list. This size includes the module's string
- * table.
- * Note: for C55x the unit is a 16-bit word. */
- u16 next_module_size;
-
- /* version number of the tooling; set to INIT_VERSION for Phase 1 */
- u16 version;
-
- /* the verification word; set to VERIFICATION */
- u16 verification;
-
- /* Number of sections in the sects array */
- u16 num_sects;
-
- /* Module's "unique" id; copy of the timestamp from the host
- * COFF file */
- u32 timestamp;
-
- /* Array of num_sects elements of the module's section records */
- struct dll_sect sects[1];
-};
-
-/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are:
- * 0 => a 32-bit value, 1 => 2 16-bit values */
-#define DLL_MODULE_BITMAP 0x6 /* swapping bitmap for type dll_module */
-
-#endif /* _MODULE_LIST_H_ */
diff --git a/drivers/staging/tidspbridge/dynload/params.h b/drivers/staging/tidspbridge/dynload/params.h
deleted file mode 100644
index d797fcd3b662..000000000000
--- a/drivers/staging/tidspbridge/dynload/params.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * params.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This file defines host and target properties for all machines
- * supported by the dynamic loader. To be tedious...
- *
- * host: the machine on which the dynamic loader runs
- * target: the machine that the dynamic loader is loading
- *
- * Host and target may or may not be the same, depending upon the particular
- * use.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/******************************************************************************
- *
- * Host Properties
- *
- **************************************************************************** */
-
-#define BITS_PER_BYTE 8 /* bits in the standard PC/SUN byte */
-#define LOG_BITS_PER_BYTE 3 /* log base 2 of same */
-#define BYTE_MASK ((1U<<BITS_PER_BYTE)-1)
-
-#if defined(__TMS320C55X__) || defined(_TMS320C5XX)
-#define BITS_PER_AU 16
-#define LOG_BITS_PER_AU 4
- /* use this print string in error messages for uint32_t */
-#define FMT_UI32 "0x%lx"
-#define FMT8_UI32 "%08lx" /* same but no 0x, fixed width field */
-#else
-/* bits in the smallest addressable data storage unit */
-#define BITS_PER_AU 8
-/* log base 2 of the same; useful for shift counts */
-#define LOG_BITS_PER_AU 3
-#define FMT_UI32 "0x%x"
-#define FMT8_UI32 "%08x"
-#endif
-
-/* generic fastest method for swapping bytes and shorts */
-#define SWAP32BY16(zz) (((zz) << 16) | ((zz) >> 16))
-#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8))
-
-/* !! don't be tempted to insert type definitions here; use <stdint.h> !! */
-
-/******************************************************************************
- *
- * Target Properties
- *
- **************************************************************************** */
-
-/*-------------------------------------------------------------------------- */
-/* TMS320C6x Target Specific Parameters (byte-addressable) */
-/*-------------------------------------------------------------------------- */
-#if TMS32060
-#define MEMORG 0x0L /* Size of configured memory */
-#define MEMSIZE 0x0L /* (full address space) */
-
-#define CINIT_ALIGN 8 /* alignment of cinit record in TDATA AUs */
-#define CINIT_COUNT 4 /* width of count field in TDATA AUs */
-#define CINIT_ADDRESS 4 /* width of address field in TDATA AUs */
-#define CINIT_PAGE_BITS 0 /* Number of LSBs of address that
- * are page number */
-
-#define LENIENT_SIGNED_RELEXPS 0 /* DOES SIGNED ALLOW MAX UNSIGNED */
-
-#undef TARGET_ENDIANNESS /* may be big or little endian */
-
-/* align a target address to a word boundary */
-#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4)
-#endif
-
-/*--------------------------------------------------------------------------
- *
- * DEFAULT SETTINGS and DERIVED PROPERTIES
- *
- * This section establishes defaults for values not specified above
- *-------------------------------------------------------------------------- */
-#ifndef TARGET_AU_BITS
-#define TARGET_AU_BITS 8 /* width of the target addressable unit */
-#define LOG_TARGET_AU_BITS 3 /* log2 of same */
-#endif
-
-#ifndef CINIT_DEFAULT_PAGE
-#define CINIT_DEFAULT_PAGE 0 /* default .cinit page number */
-#endif
-
-#ifndef DATA_RUN2LOAD
-#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */
-#endif
-
-#ifndef DBG_LIST_PAGE
-#define DBG_LIST_PAGE 0 /* page number for .dllview section */
-#endif
-
-#ifndef TARGET_WORD_ALIGN
-/* align a target address to a word boundary */
-#define TARGET_WORD_ALIGN(zz) (zz)
-#endif
-
-#ifndef TDATA_TO_TADDR
-#define TDATA_TO_TADDR(zz) (zz) /* target data address to target AU address */
-#define TADDR_TO_TDATA(zz) (zz) /* target AU address to target data address */
-#define TDATA_AU_BITS TARGET_AU_BITS /* bits per data AU */
-#define LOG_TDATA_AU_BITS LOG_TARGET_AU_BITS
-#endif
-
-/*
- *
- * Useful properties and conversions derived from the above
- *
- */
-
-/*
- * Conversions between host and target addresses
- */
-#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS
-/* translate target addressable unit to host address */
-#define TADDR_TO_HOST(x) (x)
-/* translate host address to target addressable unit */
-#define HOST_TO_TADDR(x) (x)
-#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS
-#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
-#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
-#else
-#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
-#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
-#endif
-
-#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS
-/* translate target addressable unit to host address */
-#define TDATA_TO_HOST(x) (x)
-/* translate host address to target addressable unit */
-#define HOST_TO_TDATA(x) (x)
-/* translate host address to target addressable unit, round up */
-#define HOST_TO_TDATA_ROUND(x) (x)
-/* byte offset to host offset, rounded up for TDATA size */
-#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
-#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS
-#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
-#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
-#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
-#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
-#else
-#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
-#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
-#define HOST_TO_TDATA_ROUND(x) (((x) +\
- (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\
- (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
-#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\
- (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\
- -(TDATA_AU_BITS/BITS_PER_AU))
-#endif
-
-/*
- * Input in DOFF format is always expresed in bytes, regardless of loading host
- * so we wind up converting from bytes to target and host units even when the
- * host is not a byte machine.
- */
-#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE
-#define BYTE_TO_HOST(x) (x)
-#define BYTE_TO_HOST_ROUND(x) (x)
-#define HOST_TO_BYTE(x) (x)
-#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE
-#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
-#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\
- (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
-#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
-#else
-/* lets not try to deal with sub-8-bit byte machines */
-#endif
-
-#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE
-/* translate target addressable unit to byte address */
-#define TADDR_TO_BYTE(x) (x)
-/* translate byte address to target addressable unit */
-#define BYTE_TO_TADDR(x) (x)
-#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE
-#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
-#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
-#else
-/* lets not try to deal with sub-8-bit byte machines */
-#endif
-
-#ifdef _BIG_ENDIAN
-#define HOST_ENDIANNESS 1
-#else
-#define HOST_ENDIANNESS 0
-#endif
-
-#ifdef TARGET_ENDIANNESS
-#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS)
-#elif HOST_ENDIANNESS
-#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend))
-#else
-#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend)
-#endif
-
-/* the unit in which we process target image data */
-#if TARGET_AU_BITS <= 8
-typedef u8 tgt_au_t;
-#elif TARGET_AU_BITS <= 16
-typedef u16 tgt_au_t;
-#else
-typedef u32 tgt_au_t;
-#endif
-
-/* size of that unit */
-#if TARGET_AU_BITS < BITS_PER_AU
-#define TGTAU_BITS BITS_PER_AU
-#define LOG_TGTAU_BITS LOG_BITS_PER_AU
-#else
-#define TGTAU_BITS TARGET_AU_BITS
-#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS
-#endif
diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c
deleted file mode 100644
index 463abdb6392f..000000000000
--- a/drivers/staging/tidspbridge/dynload/reloc.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * reloc.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "header.h"
-
-#if TMS32060
-/* the magic symbol for the start of BSS */
-static const char bsssymbol[] = { ".bss" };
-#endif
-
-#if TMS32060
-#include "reloc_table_c6000.c"
-#endif
-
-#if TMS32060
-/* From coff.h - ignore these relocation operations */
-#define R_C60ALIGN 0x76 /* C60: Alignment info for compressor */
-#define R_C60FPHEAD 0x77 /* C60: Explicit assembly directive */
-#define R_C60NOCMP 0x100 /* C60: Don't compress this code scn */
-#endif
-
-/**************************************************************************
- * Procedure dload_unpack
- *
- * Parameters:
- * data pointer to storage unit containing lowest host address of
- * image data
- * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU
- * offset Offset from LSB, 0 <= offset < BITS_PER_AU
- * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
- *
- * Effect:
- * Extracts the specified field and returns it.
- ************************************************************************* */
-rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz,
- int offset, unsigned sgn)
-{
- register rvalue objval;
- register int shift, direction;
- register tgt_au_t *dp = data;
-
- fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */
- /* * collect up enough bits to contain the desired field */
- if (TARGET_BIG_ENDIAN) {
- dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
- direction = -1;
- } else
- direction = 1;
- objval = *dp >> offset;
- shift = TGTAU_BITS - offset;
- while (shift <= fieldsz) {
- dp += direction;
- objval += (rvalue) *dp << shift;
- shift += TGTAU_BITS;
- }
-
- /* * sign or zero extend the value appropriately */
- if (sgn == ROP_UNS)
- objval &= (2 << fieldsz) - 1;
- else {
- shift = sizeof(rvalue) * BITS_PER_AU - 1 - fieldsz;
- objval = (objval << shift) >> shift;
- }
-
- return objval;
-
-} /* dload_unpack */
-
-/**************************************************************************
- * Procedure dload_repack
- *
- * Parameters:
- * val Value to insert
- * data Pointer to storage unit containing lowest host address of
- * image data
- * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU
- * offset Offset from LSB, 0 <= offset < BITS_PER_AU
- * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
- *
- * Effect:
- * Stuffs the specified value in the specified field. Returns 0 for
- * success
- * or 1 if the value will not fit in the specified field according to the
- * specified signedness rule.
- ************************************************************************* */
-static const unsigned char ovf_limit[] = { 1, 2, 2 };
-
-int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data,
- int fieldsz, int offset, unsigned sgn)
-{
- register urvalue objval, mask;
- register int shift, direction;
- register tgt_au_t *dp = data;
-
- fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */
- /* clip the bits */
- mask = (2UL << fieldsz) - 1;
- objval = (val & mask);
- /* * store the bits through the specified mask */
- if (TARGET_BIG_ENDIAN) {
- dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
- direction = -1;
- } else
- direction = 1;
-
- /* insert LSBs */
- *dp = (*dp & ~(mask << offset)) + (objval << offset);
- shift = TGTAU_BITS - offset;
- /* align mask and objval with AU boundary */
- objval >>= shift;
- mask >>= shift;
-
- while (mask) {
- dp += direction;
- *dp = (*dp & ~mask) + objval;
- objval >>= TGTAU_BITS;
- mask >>= TGTAU_BITS;
- }
-
- /*
- * check for overflow
- */
- if (sgn) {
- unsigned tmp = (val >> fieldsz) + (sgn & 0x1);
- if (tmp > ovf_limit[sgn - 1])
- return 1;
- }
- return 0;
-
-} /* dload_repack */
-
-/* lookup table for the scaling amount in a C6x instruction */
-#if TMS32060
-#define SCALE_BITS 4 /* there are 4 bits in the scale field */
-#define SCALE_MASK 0x7 /* we really only use the bottom 3 bits */
-static const u8 c60_scale[SCALE_MASK + 1] = {
- 1, 0, 0, 0, 1, 1, 2, 2
-};
-#endif
-
-/**************************************************************************
- * Procedure dload_relocate
- *
- * Parameters:
- * data Pointer to base of image data
- * rp Pointer to relocation operation
- *
- * Effect:
- * Performs the specified relocation operation
- ************************************************************************* */
-void dload_relocate(struct dload_state *dlthis, tgt_au_t *data,
- struct reloc_record_t *rp, bool *tramps_generated,
- bool second_pass)
-{
- rvalue val, reloc_amt, orig_val = 0;
- unsigned int fieldsz = 0;
- unsigned int offset = 0;
- unsigned int reloc_info = 0;
- unsigned int reloc_action = 0;
- register int rx = 0;
- rvalue *stackp = NULL;
- int top;
- struct local_symbol *svp = NULL;
-#ifdef RFV_SCALE
- unsigned int scale = 0;
-#endif
- struct image_packet_t *img_pkt = NULL;
-
- /* The image packet data struct is only used during first pass
- * relocation in the event that a trampoline is needed. 2nd pass
- * relocation doesn't guarantee that data is coming from an
- * image_packet_t structure. See cload.c, dload_data for how img_data is
- * set. If that changes this needs to be updated!!! */
- if (second_pass == false)
- img_pkt = (struct image_packet_t *)((u8 *) data -
- sizeof(struct
- image_packet_t));
-
- rx = HASH_FUNC(rp->TYPE);
- while (rop_map1[rx] != rp->TYPE) {
- rx = HASH_L(rop_map2[rx]);
- if (rx < 0) {
-#if TMS32060
- switch (rp->TYPE) {
- case R_C60ALIGN:
- case R_C60NOCMP:
- case R_C60FPHEAD:
- /* Ignore these reloc types and return */
- break;
- default:
- /* Unknown reloc type, print error and return */
- dload_error(dlthis, "Bad coff operator 0x%x",
- rp->TYPE);
- }
-#else
- dload_error(dlthis, "Bad coff operator 0x%x", rp->TYPE);
-#endif
- return;
- }
- }
- rx = HASH_I(rop_map2[rx]);
- if ((rx < (sizeof(rop_action) / sizeof(u16)))
- && (rx < (sizeof(rop_info) / sizeof(u16))) && (rx > 0)) {
- reloc_action = rop_action[rx];
- reloc_info = rop_info[rx];
- } else {
- dload_error(dlthis, "Buffer Overflow - Array Index Out "
- "of Bounds");
- }
-
- /* Compute the relocation amount for the referenced symbol, if any */
- reloc_amt = rp->UVAL;
- if (RFV_SYM(reloc_info)) { /* relocation uses a symbol reference */
- /* If this is first pass, use the module local symbol table,
- * else use the trampoline symbol table. */
- if (second_pass == false) {
- if ((u32) rp->SYMNDX < dlthis->dfile_hdr.df_no_syms) {
- /* real symbol reference */
- svp = &dlthis->local_symtab[rp->SYMNDX];
- reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
- svp->delta : svp->value;
- }
- /* reloc references current section */
- else if (rp->SYMNDX == -1) {
- reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
- dlthis->delta_runaddr :
- dlthis->image_secn->run_addr;
- }
- }
- }
- /* relocation uses a symbol reference */
- /* Handle stack adjustment */
- val = 0;
- top = RFV_STK(reloc_info);
- if (top) {
- top += dlthis->relstkidx - RSTK_UOP;
- if (top >= STATIC_EXPR_STK_SIZE) {
- dload_error(dlthis,
- "Expression stack overflow in %s at offset "
- FMT_UI32, dlthis->image_secn->name,
- rp->vaddr + dlthis->image_offset);
- return;
- }
- val = dlthis->relstk[dlthis->relstkidx];
- dlthis->relstkidx = top;
- stackp = &dlthis->relstk[top];
- }
- /* Derive field position and size, if we need them */
- if (reloc_info & ROP_RW) { /* read or write action in our future */
- fieldsz = RFV_WIDTH(reloc_action);
- if (fieldsz) { /* field info from table */
- offset = RFV_POSN(reloc_action);
- if (TARGET_BIG_ENDIAN)
- /* make sure vaddr is the lowest target
- * address containing bits */
- rp->vaddr += RFV_BIGOFF(reloc_info);
- } else { /* field info from relocation op */
- fieldsz = rp->FIELDSZ;
- offset = rp->OFFSET;
- if (TARGET_BIG_ENDIAN)
- /* make sure vaddr is the lowest target
- address containing bits */
- rp->vaddr += (rp->WORDSZ - offset - fieldsz)
- >> LOG_TARGET_AU_BITS;
- }
- data = (tgt_au_t *) ((char *)data + TADDR_TO_HOST(rp->vaddr));
- /* compute lowest host location of referenced data */
-#if BITS_PER_AU > TARGET_AU_BITS
- /* conversion from target address to host address may lose
- address bits; add loss to offset */
- if (TARGET_BIG_ENDIAN) {
- offset += -((rp->vaddr << LOG_TARGET_AU_BITS) +
- offset + fieldsz) &
- (BITS_PER_AU - TARGET_AU_BITS);
- } else {
- offset += (rp->vaddr << LOG_TARGET_AU_BITS) &
- (BITS_PER_AU - 1);
- }
-#endif
-#ifdef RFV_SCALE
- scale = RFV_SCALE(reloc_info);
-#endif
- }
- /* read the object value from the current image, if so ordered */
- if (reloc_info & ROP_R) {
- /* relocation reads current image value */
- val = dload_unpack(dlthis, data, fieldsz, offset,
- RFV_SIGN(reloc_info));
- /* Save off the original value in case the relo overflows and
- * we can trampoline it. */
- orig_val = val;
-
-#ifdef RFV_SCALE
- val <<= scale;
-#endif
- }
- /* perform the necessary arithmetic */
- switch (RFV_ACTION(reloc_action)) { /* relocation actions */
- case RACT_VAL:
- break;
- case RACT_ASGN:
- val = reloc_amt;
- break;
- case RACT_ADD:
- val += reloc_amt;
- break;
- case RACT_PCR:
- /*-----------------------------------------------------------
- * Handle special cases of jumping from absolute sections
- * (special reloc type) or to absolute destination
- * (symndx == -1). In either case, set the appropriate
- * relocation amount to 0.
- *----------------------------------------------------------- */
- if (rp->SYMNDX == -1)
- reloc_amt = 0;
- val += reloc_amt - dlthis->delta_runaddr;
- break;
- case RACT_ADDISP:
- val += rp->R_DISP + reloc_amt;
- break;
- case RACT_ASGPC:
- val = dlthis->image_secn->run_addr + reloc_amt;
- break;
- case RACT_PLUS:
- if (stackp != NULL)
- val += *stackp;
- break;
- case RACT_SUB:
- if (stackp != NULL)
- val = *stackp - val;
- break;
- case RACT_NEG:
- val = -val;
- break;
- case RACT_MPY:
- if (stackp != NULL)
- val *= *stackp;
- break;
- case RACT_DIV:
- if (stackp != NULL)
- val = *stackp / val;
- break;
- case RACT_MOD:
- if (stackp != NULL)
- val = *stackp % val;
- break;
- case RACT_SR:
- if (val >= sizeof(rvalue) * BITS_PER_AU)
- val = 0;
- else if (stackp != NULL)
- val = (urvalue) *stackp >> val;
- break;
- case RACT_ASR:
- if (val >= sizeof(rvalue) * BITS_PER_AU)
- val = sizeof(rvalue) * BITS_PER_AU - 1;
- else if (stackp != NULL)
- val = *stackp >> val;
- break;
- case RACT_SL:
- if (val >= sizeof(rvalue) * BITS_PER_AU)
- val = 0;
- else if (stackp != NULL)
- val = *stackp << val;
- break;
- case RACT_AND:
- if (stackp != NULL)
- val &= *stackp;
- break;
- case RACT_OR:
- if (stackp != NULL)
- val |= *stackp;
- break;
- case RACT_XOR:
- if (stackp != NULL)
- val ^= *stackp;
- break;
- case RACT_NOT:
- val = ~val;
- break;
-#if TMS32060
- case RACT_C6SECT:
- /* actually needed address of secn containing symbol */
- if (svp != NULL) {
- if (rp->SYMNDX >= 0)
- if (svp->secnn > 0)
- reloc_amt = dlthis->ldr_sections
- [svp->secnn - 1].run_addr;
- }
- /* !!! FALL THRU !!! */
- case RACT_C6BASE:
- if (dlthis->bss_run_base == 0) {
- struct dynload_symbol *symp;
- symp = dlthis->mysym->find_matching_symbol
- (dlthis->mysym, bsssymbol);
- /* lookup value of global BSS base */
- if (symp)
- dlthis->bss_run_base = symp->value;
- else
- dload_error(dlthis,
- "Global BSS base referenced in %s "
- "offset" FMT_UI32 " but not "
- "defined",
- dlthis->image_secn->name,
- rp->vaddr + dlthis->image_offset);
- }
- reloc_amt -= dlthis->bss_run_base;
- /* !!! FALL THRU !!! */
- case RACT_C6DSPL:
- /* scale factor determined by 3 LSBs of field */
- scale = c60_scale[val & SCALE_MASK];
- offset += SCALE_BITS;
- fieldsz -= SCALE_BITS;
- val >>= SCALE_BITS; /* ignore the scale field hereafter */
- val <<= scale;
- val += reloc_amt; /* do the usual relocation */
- if (((1 << scale) - 1) & val)
- dload_error(dlthis,
- "Unaligned reference in %s offset "
- FMT_UI32, dlthis->image_secn->name,
- rp->vaddr + dlthis->image_offset);
- break;
-#endif
- } /* relocation actions */
- /* * Put back result as required */
- if (reloc_info & ROP_W) { /* relocation writes image value */
-#ifdef RFV_SCALE
- val >>= scale;
-#endif
- if (dload_repack(dlthis, val, data, fieldsz, offset,
- RFV_SIGN(reloc_info))) {
- /* Check to see if this relo can be trampolined,
- * but only in first phase relocation. 2nd phase
- * relocation cannot trampoline. */
- if ((second_pass == false) &&
- (dload_tramp_avail(dlthis, rp) == true)) {
-
- /* Before generating the trampoline, restore
- * the value to its original so the 2nd pass
- * relo will work. */
- dload_repack(dlthis, orig_val, data, fieldsz,
- offset, RFV_SIGN(reloc_info));
- if (!dload_tramp_generate(dlthis,
- (dlthis->image_secn -
- dlthis->ldr_sections),
- dlthis->image_offset,
- img_pkt, rp)) {
- dload_error(dlthis,
- "Failed to "
- "generate trampoline for "
- "bit overflow");
- dload_error(dlthis,
- "Relocation val " FMT_UI32
- " overflows %d bits in %s "
- "offset " FMT_UI32, val,
- fieldsz,
- dlthis->image_secn->name,
- dlthis->image_offset +
- rp->vaddr);
- } else
- *tramps_generated = true;
- } else {
- dload_error(dlthis, "Relocation value "
- FMT_UI32 " overflows %d bits in %s"
- " offset " FMT_UI32, val, fieldsz,
- dlthis->image_secn->name,
- dlthis->image_offset + rp->vaddr);
- }
- }
- } else if (top)
- *stackp = val;
-} /* reloc_value */
diff --git a/drivers/staging/tidspbridge/dynload/reloc_table.h b/drivers/staging/tidspbridge/dynload/reloc_table.h
deleted file mode 100644
index 6aab03d4668d..000000000000
--- a/drivers/staging/tidspbridge/dynload/reloc_table.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * reloc_table.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _RELOC_TABLE_H_
-#define _RELOC_TABLE_H_
-/*
- * Table of relocation operator properties
- */
-#include <linux/types.h>
-
-/* How does this relocation operation access the program image? */
-#define ROP_N 0 /* does not access image */
-#define ROP_R 1 /* read from image */
-#define ROP_W 2 /* write to image */
-#define ROP_RW 3 /* read from and write to image */
-
-/* For program image access, what are the overflow rules for the bit field? */
-/* Beware! Procedure repack depends on this encoding */
-#define ROP_ANY 0 /* no overflow ever, just truncate the value */
-#define ROP_SGN 1 /* signed field */
-#define ROP_UNS 2 /* unsigned field */
-#define ROP_MAX 3 /* allow maximum range of either signed or unsigned */
-
-/* How does the relocation operation use the symbol reference */
-#define ROP_IGN 0 /* no symbol is referenced */
-#define ROP_LIT 0 /* use rp->UVAL literal field */
-#define ROP_SYM 1 /* symbol value is used in relocation */
-#define ROP_SYMD 2 /* delta value vs last link is used */
-
-/* How does the reloc op use the stack? */
-#define RSTK_N 0 /* Does not use */
-#define RSTK_POP 1 /* Does a POP */
-#define RSTK_UOP 2 /* Unary op, stack position unaffected */
-#define RSTK_PSH 3 /* Does a push */
-
-/*
- * Computational actions performed by the dynamic loader
- */
-enum dload_actions {
- /* don't alter the current val (from stack or mem fetch) */
- RACT_VAL,
- /* set value to reference amount (from symbol reference) */
- RACT_ASGN,
- RACT_ADD, /* add reference to value */
- RACT_PCR, /* add reference minus PC delta to value */
- RACT_ADDISP, /* add reference plus R_DISP */
- RACT_ASGPC, /* set value to section addr plus reference */
-
- RACT_PLUS, /* stack + */
- RACT_SUB, /* stack - */
- RACT_NEG, /* stack unary - */
-
- RACT_MPY, /* stack * */
- RACT_DIV, /* stack / */
- RACT_MOD, /* stack % */
-
- RACT_SR, /* stack unsigned >> */
- RACT_ASR, /* stack signed >> */
- RACT_SL, /* stack << */
- RACT_AND, /* stack & */
- RACT_OR, /* stack | */
- RACT_XOR, /* stack ^ */
- RACT_NOT, /* stack ~ */
- RACT_C6SECT, /* for C60 R_SECT op */
- RACT_C6BASE, /* for C60 R_BASE op */
- RACT_C6DSPL, /* for C60 scaled 15-bit displacement */
- RACT_PCR23T /* for ARM Thumb long branch */
-};
-
-/*
- * macros used to extract values
- */
-#define RFV_POSN(aaa) ((aaa) & 0xF)
-#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F)
-#define RFV_ACTION(aaa) ((aaa) >> 10)
-
-#define RFV_SIGN(iii) (((iii) >> 2) & 0x3)
-#define RFV_SYM(iii) (((iii) >> 4) & 0x3)
-#define RFV_STK(iii) (((iii) >> 6) & 0x3)
-#define RFV_ACCS(iii) ((iii) & 0x3)
-
-#if (TMS32060)
-#define RFV_SCALE(iii) ((iii) >> 11)
-#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7)
-#else
-#define RFV_BIGOFF(iii) ((iii) >> 8)
-#endif
-
-#endif /* _RELOC_TABLE_H_ */
diff --git a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c b/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c
deleted file mode 100644
index a28bc0442491..000000000000
--- a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * reloc_table_c6000.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* Tables generated for c6000 */
-
-#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63)
-#define HASH_L(zz) ((zz) >> 8)
-#define HASH_I(zz) ((zz) & 0xFF)
-
-static const u16 rop_map1[] = {
- 0,
- 1,
- 2,
- 20,
- 4,
- 5,
- 6,
- 15,
- 80,
- 81,
- 82,
- 83,
- 84,
- 85,
- 86,
- 87,
- 17,
- 18,
- 19,
- 21,
- 16,
- 16394,
- 16404,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 32,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 40,
- 112,
- 113,
- 65535,
- 16384,
- 16385,
- 16386,
- 16387,
- 16388,
- 16389,
- 16390,
- 16391,
- 16392,
- 16393,
- 16395,
- 16396,
- 16397,
- 16398,
- 16399,
- 16400,
- 16401,
- 16402,
- 16403,
- 16405,
- 16406,
- 65535,
- 65535,
- 65535
-};
-
-static const s16 rop_map2[] = {
- -256,
- -255,
- -254,
- -245,
- -253,
- -252,
- -251,
- -250,
- -241,
- -240,
- -239,
- -238,
- -237,
- -236,
- 1813,
- 5142,
- -248,
- -247,
- 778,
- -244,
- -249,
- -221,
- -211,
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- -243,
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- -242,
- -233,
- -232,
- -1,
- -231,
- -230,
- -229,
- -228,
- -227,
- -226,
- -225,
- -224,
- -223,
- 5410,
- -220,
- -219,
- -218,
- -217,
- -216,
- -215,
- -214,
- -213,
- 5676,
- -210,
- -209,
- -1,
- -1,
- -1
-};
-
-static const u16 rop_action[] = {
- 2560,
- 2304,
- 2304,
- 2432,
- 2432,
- 2560,
- 2176,
- 2304,
- 2560,
- 3200,
- 3328,
- 3584,
- 3456,
- 2304,
- 4208,
- 20788,
- 21812,
- 3415,
- 3245,
- 2311,
- 4359,
- 19764,
- 2311,
- 3191,
- 3280,
- 6656,
- 7680,
- 8704,
- 9728,
- 10752,
- 11776,
- 12800,
- 13824,
- 14848,
- 15872,
- 16896,
- 17920,
- 18944,
- 0,
- 0,
- 0,
- 0,
- 1536,
- 1536,
- 1536,
- 5632,
- 512,
- 0
-};
-
-static const u16 rop_info[] = {
- 0,
- 35,
- 35,
- 35,
- 35,
- 35,
- 35,
- 35,
- 35,
- 39,
- 39,
- 39,
- 39,
- 35,
- 34,
- 283,
- 299,
- 4135,
- 4391,
- 291,
- 33059,
- 283,
- 295,
- 4647,
- 4135,
- 64,
- 64,
- 128,
- 64,
- 64,
- 64,
- 64,
- 64,
- 64,
- 64,
- 64,
- 64,
- 128,
- 201,
- 197,
- 74,
- 70,
- 208,
- 196,
- 200,
- 192,
- 192,
- 66
-};
diff --git a/drivers/staging/tidspbridge/dynload/tramp.c b/drivers/staging/tidspbridge/dynload/tramp.c
deleted file mode 100644
index 5f0431305fbb..000000000000
--- a/drivers/staging/tidspbridge/dynload/tramp.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/*
- * tramp.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "header.h"
-
-#if TMS32060
-#include "tramp_table_c6000.c"
-#endif
-
-#define MAX_RELOS_PER_PASS 4
-
-/*
- * Function: priv_tramp_sect_tgt_alloc
- * Description: Allocate target memory for the trampoline section. The
- * target mem size is easily obtained as the next available address.
- */
-static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis)
-{
- int ret_val = 0;
- struct ldr_section_info *sect_info;
-
- /* Populate the trampoline loader section and allocate it on the
- * target. The section name is ALWAYS the first string in the final
- * string table for trampolines. The trampoline section is always
- * 1 beyond the total number of allocated sections. */
- sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count];
-
- sect_info->name = dlthis->tramp.final_string_table;
- sect_info->size = dlthis->tramp.tramp_sect_next_addr;
- sect_info->context = 0;
- sect_info->type =
- (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK;
- sect_info->page = 0;
- sect_info->run_addr = 0;
- sect_info->load_addr = 0;
- ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc,
- sect_info,
- ds_alignment
- (sect_info->type));
-
- if (ret_val == 0)
- dload_error(dlthis, "Failed to allocate target memory for"
- " trampoline");
-
- return ret_val;
-}
-
-/*
- * Function: priv_h2a
- * Description: Helper function to convert a hex value to its ASCII
- * representation. Used for trampoline symbol name generation.
- */
-static u8 priv_h2a(u8 value)
-{
- if (value > 0xF)
- return 0xFF;
-
- if (value <= 9)
- value += 0x30;
- else
- value += 0x37;
-
- return value;
-}
-
-/*
- * Function: priv_tramp_sym_gen_name
- * Description: Generate a trampoline symbol name (ASCII) using the value
- * of the symbol. This places the new name into the user buffer.
- * The name is fixed in length and of the form: __$dbTR__xxxxxxxx
- * (where "xxxxxxxx" is the hex value).
- */
-static void priv_tramp_sym_gen_name(u32 value, char *dst)
-{
- u32 i;
- char *prefix = TRAMP_SYM_PREFIX;
- char *dst_local = dst;
- u8 tmp;
-
- /* Clear out the destination, including the ending NULL */
- for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++)
- *(dst_local + i) = 0;
-
- /* Copy the prefix to start */
- for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) {
- *dst_local = *(prefix + i);
- dst_local++;
- }
-
- /* Now convert the value passed in to a string equiv of the hex */
- for (i = 0; i < sizeof(value); i++) {
-#ifndef _BIG_ENDIAN
- tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i);
- *dst_local = priv_h2a((tmp & 0xF0) >> 4);
- dst_local++;
- *dst_local = priv_h2a(tmp & 0x0F);
- dst_local++;
-#else
- tmp = *(((u8 *) &value) + i);
- *dst_local = priv_h2a((tmp & 0xF0) >> 4);
- dst_local++;
- *dst_local = priv_h2a(tmp & 0x0F);
- dst_local++;
-#endif
- }
-
- /* NULL terminate */
- *dst_local = 0;
-}
-
-/*
- * Function: priv_tramp_string_create
- * Description: Create a new string specific to the trampoline loading and add
- * it to the trampoline string list. This list contains the
- * trampoline section name and trampoline point symbols.
- */
-static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis,
- u32 str_len, char *str)
-{
- struct tramp_string *new_string = NULL;
- u32 i;
-
- /* Create a new string object with the specified size. */
- new_string =
- (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym,
- (sizeof
- (struct
- tramp_string)
- + str_len +
- 1));
- if (new_string != NULL) {
- /* Clear the string first. This ensures the ending NULL is
- * present and the optimizer won't touch it. */
- for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1);
- i++)
- *((u8 *) new_string + i) = 0;
-
- /* Add this string to our virtual table by assigning it the
- * next index and pushing it to the tail of the list. */
- new_string->index = dlthis->tramp.tramp_string_next_index;
- dlthis->tramp.tramp_string_next_index++;
- dlthis->tramp.tramp_string_size += str_len + 1;
-
- new_string->next = NULL;
- if (dlthis->tramp.string_head == NULL)
- dlthis->tramp.string_head = new_string;
- else
- dlthis->tramp.string_tail->next = new_string;
-
- dlthis->tramp.string_tail = new_string;
-
- /* Copy the string over to the new object */
- for (i = 0; i < str_len; i++)
- new_string->str[i] = str[i];
- }
-
- return new_string;
-}
-
-/*
- * Function: priv_tramp_string_find
- * Description: Walk the trampoline string list and find a match for the
- * provided string. If not match is found, NULL is returned.
- */
-static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis,
- char *str)
-{
- struct tramp_string *cur_str = NULL;
- struct tramp_string *ret_val = NULL;
- u32 i;
- u32 str_len = strlen(str);
-
- for (cur_str = dlthis->tramp.string_head;
- (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) {
- /* If the string lengths aren't equal, don't bother
- * comparing */
- if (str_len != strlen(cur_str->str))
- continue;
-
- /* Walk the strings until one of them ends */
- for (i = 0; i < str_len; i++) {
- /* If they don't match in the current position then
- * break out now, no sense in continuing to look at
- * this string. */
- if (str[i] != cur_str->str[i])
- break;
- }
-
- if (i == str_len)
- ret_val = cur_str;
- }
-
- return ret_val;
-}
-
-/*
- * Function: priv_string_tbl_finalize
- * Description: Flatten the trampoline string list into a table of NULL
- * terminated strings. This is the same format of string table
- * as used by the COFF/DOFF file.
- */
-static int priv_string_tbl_finalize(struct dload_state *dlthis)
-{
- int ret_val = 0;
- struct tramp_string *cur_string;
- char *cur_loc;
- char *tmp;
-
- /* Allocate enough space for all strings that have been created. The
- * table is simply all strings concatenated together will NULL
- * endings. */
- dlthis->tramp.final_string_table =
- (char *)dlthis->mysym->dload_allocate(dlthis->mysym,
- dlthis->tramp.
- tramp_string_size);
- if (dlthis->tramp.final_string_table != NULL) {
- /* We got our buffer, walk the list and release the nodes as*
- * we go */
- cur_loc = dlthis->tramp.final_string_table;
- cur_string = dlthis->tramp.string_head;
- while (cur_string != NULL) {
- /* Move the head/tail pointers */
- dlthis->tramp.string_head = cur_string->next;
- if (dlthis->tramp.string_tail == cur_string)
- dlthis->tramp.string_tail = NULL;
-
- /* Copy the string contents */
- for (tmp = cur_string->str;
- *tmp != '\0'; tmp++, cur_loc++)
- *cur_loc = *tmp;
-
- /* Pick up the NULL termination since it was missed by
- * breaking using it to end the above loop. */
- *cur_loc = '\0';
- cur_loc++;
-
- /* Free the string node, we don't need it any more. */
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- cur_string);
-
- /* Move our pointer to the next one */
- cur_string = dlthis->tramp.string_head;
- }
-
- /* Update our return value to success */
- ret_val = 1;
- } else
- dload_error(dlthis, "Failed to allocate trampoline "
- "string table");
-
- return ret_val;
-}
-
-/*
- * Function: priv_tramp_sect_alloc
- * Description: Virtually allocate space from the trampoline section. This
- * function returns the next offset within the trampoline section
- * that is available and moved the next available offset by the
- * requested size. NO TARGET ALLOCATION IS DONE AT THIS TIME.
- */
-static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size)
-{
- u32 ret_val;
-
- /* If the next available address is 0, this is our first allocation.
- * Create a section name string to go into the string table . */
- if (dlthis->tramp.tramp_sect_next_addr == 0) {
- dload_syms_error(dlthis->mysym, "*** WARNING *** created "
- "dynamic TRAMPOLINE section for module %s",
- dlthis->str_head);
- }
-
- /* Reserve space for the new trampoline */
- ret_val = dlthis->tramp.tramp_sect_next_addr;
- dlthis->tramp.tramp_sect_next_addr += tramp_size;
- return ret_val;
-}
-
-/*
- * Function: priv_tramp_sym_create
- * Description: Allocate and create a new trampoline specific symbol and add
- * it to the trampoline symbol list. These symbols will include
- * trampoline points as well as the external symbols they
- * reference.
- */
-static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis,
- u32 str_index,
- struct local_symbol *tmp_sym)
-{
- struct tramp_sym *new_sym = NULL;
- u32 i;
-
- /* Allocate new space for the symbol in the symbol table. */
- new_sym =
- (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym,
- sizeof(struct tramp_sym));
- if (new_sym != NULL) {
- for (i = 0; i != sizeof(struct tramp_sym); i++)
- *((char *)new_sym + i) = 0;
-
- /* Assign this symbol the next symbol index for easier
- * reference later during relocation. */
- new_sym->index = dlthis->tramp.tramp_sym_next_index;
- dlthis->tramp.tramp_sym_next_index++;
-
- /* Populate the symbol information. At this point any
- * trampoline symbols will be the offset location, not the
- * final. Copy over the symbol info to start, then be sure to
- * get the string index from the trampoline string table. */
- new_sym->sym_info = *tmp_sym;
- new_sym->str_index = str_index;
-
- /* Push the new symbol to the tail of the symbol table list */
- new_sym->next = NULL;
- if (dlthis->tramp.symbol_head == NULL)
- dlthis->tramp.symbol_head = new_sym;
- else
- dlthis->tramp.symbol_tail->next = new_sym;
-
- dlthis->tramp.symbol_tail = new_sym;
- }
-
- return new_sym;
-}
-
-/*
- * Function: priv_tramp_sym_get
- * Description: Search for the symbol with the matching string index (from
- * the trampoline string table) and return the trampoline
- * symbol object, if found. Otherwise return NULL.
- */
-static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis,
- u32 string_index)
-{
- struct tramp_sym *sym_found = NULL;
-
- /* Walk the symbol table list and search vs. the string index */
- for (sym_found = dlthis->tramp.symbol_head;
- sym_found != NULL; sym_found = sym_found->next) {
- if (sym_found->str_index == string_index)
- break;
- }
-
- return sym_found;
-}
-
-/*
- * Function: priv_tramp_sym_find
- * Description: Search for a trampoline symbol based on the string name of
- * the symbol. Return the symbol object, if found, otherwise
- * return NULL.
- */
-static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis,
- char *string)
-{
- struct tramp_sym *sym_found = NULL;
- struct tramp_string *str_found = NULL;
-
- /* First, search for the string, then search for the sym based on the
- string index. */
- str_found = priv_tramp_string_find(dlthis, string);
- if (str_found != NULL)
- sym_found = priv_tramp_sym_get(dlthis, str_found->index);
-
- return sym_found;
-}
-
-/*
- * Function: priv_tramp_sym_finalize
- * Description: Allocate a flat symbol table for the trampoline section,
- * put each trampoline symbol into the table, adjust the
- * symbol value based on the section address on the target and
- * free the trampoline symbol list nodes.
- */
-static int priv_tramp_sym_finalize(struct dload_state *dlthis)
-{
- int ret_val = 0;
- struct tramp_sym *cur_sym;
- struct ldr_section_info *tramp_sect =
- &dlthis->ldr_sections[dlthis->allocated_secn_count];
- struct local_symbol *new_sym;
-
- /* Allocate a table to hold a flattened version of all symbols
- * created. */
- dlthis->tramp.final_sym_table =
- (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym,
- (sizeof(struct local_symbol) * dlthis->tramp.
- tramp_sym_next_index));
- if (dlthis->tramp.final_sym_table != NULL) {
- /* Walk the list of all symbols, copy it over to the flattened
- * table. After it has been copied, the node can be freed as
- * it is no longer needed. */
- new_sym = dlthis->tramp.final_sym_table;
- cur_sym = dlthis->tramp.symbol_head;
- while (cur_sym != NULL) {
- /* Pop it off the list */
- dlthis->tramp.symbol_head = cur_sym->next;
- if (cur_sym == dlthis->tramp.symbol_tail)
- dlthis->tramp.symbol_tail = NULL;
-
- /* Copy the symbol contents into the flat table */
- *new_sym = cur_sym->sym_info;
-
- /* Now finalize the symbol. If it is in the tramp
- * section, we need to adjust for the section start.
- * If it is external then we don't need to adjust at
- * all.
- * NOTE: THIS CODE ASSUMES THAT THE TRAMPOLINE IS
- * REFERENCED LIKE A CALL TO AN EXTERNAL SO VALUE AND
- * DELTA ARE THE SAME. SEE THE FUNCTION dload_symbols
- * WHERE DN_UNDEF IS HANDLED FOR MORE REFERENCE. */
- if (new_sym->secnn < 0) {
- new_sym->value += tramp_sect->load_addr;
- new_sym->delta = new_sym->value;
- }
-
- /* Let go of the symbol node */
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
-
- /* Move to the next node */
- cur_sym = dlthis->tramp.symbol_head;
- new_sym++;
- }
-
- ret_val = 1;
- } else
- dload_error(dlthis, "Failed to alloc trampoline sym table");
-
- return ret_val;
-}
-
-/*
- * Function: priv_tgt_img_gen
- * Description: Allocate storage for and copy the target specific image data
- * and fix up its relocations for the new external symbol. If
- * a trampoline image packet was successfully created it is added
- * to the trampoline list.
- */
-static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base,
- u32 gen_index, struct tramp_sym *new_ext_sym)
-{
- struct tramp_img_pkt *new_img_pkt = NULL;
- u32 i;
- u32 pkt_size = tramp_img_pkt_size_get();
- u8 *gen_tbl_entry;
- u8 *pkt_data;
- struct reloc_record_t *cur_relo;
- int ret_val = 0;
-
- /* Allocate a new image packet and set it up. */
- new_img_pkt =
- (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym,
- pkt_size);
- if (new_img_pkt != NULL) {
- /* Save the base, this is where it goes in the section */
- new_img_pkt->base = base;
-
- /* Copy over the image data and relos from the target table */
- pkt_data = (u8 *) &new_img_pkt->hdr;
- gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index];
- for (i = 0; i < pkt_size; i++) {
- *pkt_data = *gen_tbl_entry;
- pkt_data++;
- gen_tbl_entry++;
- }
-
- /* Update the relocations to point to the external symbol */
- cur_relo =
- (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr +
- new_img_pkt->hdr.relo_offset);
- for (i = 0; i < new_img_pkt->hdr.num_relos; i++)
- cur_relo[i].SYMNDX = new_ext_sym->index;
-
- /* Add it to the trampoline list. */
- new_img_pkt->next = dlthis->tramp.tramp_pkts;
- dlthis->tramp.tramp_pkts = new_img_pkt;
-
- ret_val = 1;
- }
-
- return ret_val;
-}
-
-/*
- * Function: priv_pkt_relo
- * Description: Take the provided image data and the collection of relocations
- * for it and perform the relocations. Note that all relocations
- * at this stage are considered SECOND PASS since the original
- * image has already been processed in the first pass. This means
- * TRAMPOLINES ARE TREATED AS 2ND PASS even though this is really
- * the first (and only) relocation that will be performed on them.
- */
-static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t *data,
- struct reloc_record_t *rp[], u32 relo_count)
-{
- int ret_val = 1;
- u32 i;
- bool tmp;
-
- /* Walk through all of the relos and process them. This function is
- * the equivalent of relocate_packet() from cload.c, but specialized
- * for trampolines and 2nd phase relocations. */
- for (i = 0; i < relo_count; i++)
- dload_relocate(dlthis, data, rp[i], &tmp, true);
-
- return ret_val;
-}
-
-/*
- * Function: priv_tramp_pkt_finalize
- * Description: Walk the list of all trampoline packets and finalize them.
- * Each trampoline image packet will be relocated now that the
- * trampoline section has been allocated on the target. Once
- * all of the relocations are done the trampoline image data
- * is written into target memory and the trampoline packet
- * is freed: it is no longer needed after this point.
- */
-static int priv_tramp_pkt_finalize(struct dload_state *dlthis)
-{
- int ret_val = 1;
- struct tramp_img_pkt *cur_pkt = NULL;
- struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
- u32 relos_done;
- u32 i;
- struct reloc_record_t *cur_relo;
- struct ldr_section_info *sect_info =
- &dlthis->ldr_sections[dlthis->allocated_secn_count];
-
- /* Walk the list of trampoline packets and relocate each packet. This
- * function is the trampoline equivalent of dload_data() from
- * cload.c. */
- cur_pkt = dlthis->tramp.tramp_pkts;
- while ((ret_val != 0) && (cur_pkt != NULL)) {
- /* Remove the pkt from the list */
- dlthis->tramp.tramp_pkts = cur_pkt->next;
-
- /* Setup section and image offset information for the relo */
- dlthis->image_secn = sect_info;
- dlthis->image_offset = cur_pkt->base;
- dlthis->delta_runaddr = sect_info->run_addr;
-
- /* Walk through all relos for the packet */
- relos_done = 0;
- cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr +
- cur_pkt->hdr.relo_offset);
- while (relos_done < cur_pkt->hdr.num_relos) {
-#ifdef ENABLE_TRAMP_DEBUG
- dload_syms_error(dlthis->mysym,
- "===> Trampoline %x branches to %x",
- sect_info->run_addr +
- dlthis->image_offset,
- dlthis->
- tramp.final_sym_table[cur_relo->
- SYMNDX].value);
-#endif
-
- for (i = 0;
- ((i < MAX_RELOS_PER_PASS) &&
- ((i + relos_done) < cur_pkt->hdr.num_relos)); i++)
- relos[i] = cur_relo + i;
-
- /* Do the actual relo */
- ret_val = priv_pkt_relo(dlthis,
- (tgt_au_t *) &cur_pkt->payload,
- relos, i);
- if (ret_val == 0) {
- dload_error(dlthis,
- "Relocation of trampoline pkt at %x"
- " failed", cur_pkt->base +
- sect_info->run_addr);
- break;
- }
-
- relos_done += i;
- cur_relo += i;
- }
-
- /* Make sure we didn't hit a problem */
- if (ret_val != 0) {
- /* Relos are done for the packet, write it to the
- * target */
- ret_val = dlthis->myio->writemem(dlthis->myio,
- &cur_pkt->payload,
- sect_info->load_addr +
- cur_pkt->base,
- sect_info,
- BYTE_TO_HOST
- (cur_pkt->hdr.
- tramp_code_size));
- if (ret_val == 0) {
- dload_error(dlthis,
- "Write to " FMT_UI32 " failed",
- sect_info->load_addr +
- cur_pkt->base);
- }
-
- /* Done with the pkt, let it go */
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
-
- /* Get the next packet to process */
- cur_pkt = dlthis->tramp.tramp_pkts;
- }
- }
-
- return ret_val;
-}
-
-/*
- * Function: priv_dup_pkt_finalize
- * Description: Walk the list of duplicate image packets and finalize them.
- * Each duplicate packet will be relocated again for the
- * relocations that previously failed and have been adjusted
- * to point at a trampoline. Once all relocations for a packet
- * have been done, write the packet into target memory. The
- * duplicate packet and its relocation chain are all freed
- * after use here as they are no longer needed after this.
- */
-static int priv_dup_pkt_finalize(struct dload_state *dlthis)
-{
- int ret_val = 1;
- struct tramp_img_dup_pkt *cur_pkt;
- struct tramp_img_dup_relo *cur_relo;
- struct reloc_record_t *relos[MAX_RELOS_PER_PASS];
- struct doff_scnhdr_t *sect_hdr = NULL;
- s32 i;
-
- /* Similar to the trampoline pkt finalize, this function walks each dup
- * pkt that was generated and performs all relocations that were
- * deferred to a 2nd pass. This is the equivalent of dload_data() from
- * cload.c, but does not need the additional reorder and checksum
- * processing as it has already been done. */
- cur_pkt = dlthis->tramp.dup_pkts;
- while ((ret_val != 0) && (cur_pkt != NULL)) {
- /* Remove the node from the list, we'll be freeing it
- * shortly */
- dlthis->tramp.dup_pkts = cur_pkt->next;
-
- /* Setup the section and image offset for relocation */
- dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn];
- dlthis->image_offset = cur_pkt->offset;
-
- /* In order to get the delta run address, we need to reference
- * the original section header. It's a bit ugly, but needed
- * for relo. */
- i = (s32) (dlthis->image_secn - dlthis->ldr_sections);
- sect_hdr = dlthis->sect_hdrs + i;
- dlthis->delta_runaddr = sect_hdr->ds_paddr;
-
- /* Walk all relos in the chain and process each. */
- cur_relo = cur_pkt->relo_chain;
- while (cur_relo != NULL) {
- /* Process them a chunk at a time to be efficient */
- for (i = 0; (i < MAX_RELOS_PER_PASS)
- && (cur_relo != NULL);
- i++, cur_relo = cur_relo->next) {
- relos[i] = &cur_relo->relo;
- cur_pkt->relo_chain = cur_relo->next;
- }
-
- /* Do the actual relo */
- ret_val = priv_pkt_relo(dlthis,
- cur_pkt->img_pkt.img_data,
- relos, i);
- if (ret_val == 0) {
- dload_error(dlthis,
- "Relocation of dup pkt at %x"
- " failed", cur_pkt->offset +
- dlthis->image_secn->run_addr);
- break;
- }
-
- /* Release all of these relos, we're done with them */
- while (i > 0) {
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- GET_CONTAINER
- (relos[i - 1],
- struct tramp_img_dup_relo,
- relo));
- i--;
- }
-
- /* DO NOT ADVANCE cur_relo, IT IS ALREADY READY TO
- * GO! */
- }
-
- /* Done with all relos. Make sure we didn't have a problem and
- * write it out to the target */
- if (ret_val != 0) {
- ret_val = dlthis->myio->writemem(dlthis->myio,
- cur_pkt->img_pkt.
- img_data,
- dlthis->image_secn->
- load_addr +
- cur_pkt->offset,
- dlthis->image_secn,
- BYTE_TO_HOST
- (cur_pkt->img_pkt.
- packet_size));
- if (ret_val == 0) {
- dload_error(dlthis,
- "Write to " FMT_UI32 " failed",
- dlthis->image_secn->load_addr +
- cur_pkt->offset);
- }
-
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt);
-
- /* Advance to the next packet */
- cur_pkt = dlthis->tramp.dup_pkts;
- }
- }
-
- return ret_val;
-}
-
-/*
- * Function: priv_dup_find
- * Description: Walk the list of existing duplicate packets and find a
- * match based on the section number and image offset. Return
- * the duplicate packet if found, otherwise NULL.
- */
-static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis,
- s16 secnn, u32 image_offset)
-{
- struct tramp_img_dup_pkt *cur_pkt = NULL;
-
- for (cur_pkt = dlthis->tramp.dup_pkts;
- cur_pkt != NULL; cur_pkt = cur_pkt->next) {
- if ((cur_pkt->secnn == secnn) &&
- (cur_pkt->offset == image_offset)) {
- /* Found a match, break out */
- break;
- }
- }
-
- return cur_pkt;
-}
-
-/*
- * Function: priv_img_pkt_dup
- * Description: Duplicate the original image packet. If this is the first
- * time this image packet has been seen (based on section number
- * and image offset), create a new duplicate packet and add it
- * to the dup packet list. If not, just get the existing one and
- * update it with the current packet contents (since relocation
- * on the packet is still ongoing in first pass.) Create a
- * duplicate of the provided relocation, but update it to point
- * to the new trampoline symbol. Add the new relocation dup to
- * the dup packet's relo chain for 2nd pass relocation later.
- */
-static int priv_img_pkt_dup(struct dload_state *dlthis,
- s16 secnn, u32 image_offset,
- struct image_packet_t *ipacket,
- struct reloc_record_t *rp,
- struct tramp_sym *new_tramp_sym)
-{
- struct tramp_img_dup_pkt *dup_pkt = NULL;
- u32 new_dup_size;
- s32 i;
- int ret_val = 0;
- struct tramp_img_dup_relo *dup_relo = NULL;
-
- /* Determine if this image packet is already being tracked in the
- dup list for other trampolines. */
- dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
-
- if (dup_pkt == NULL) {
- /* This image packet does not exist in our tracking, so create
- * a new one and add it to the head of the list. */
- new_dup_size = sizeof(struct tramp_img_dup_pkt) +
- ipacket->packet_size;
-
- dup_pkt = (struct tramp_img_dup_pkt *)
- dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size);
- if (dup_pkt != NULL) {
- /* Save off the section and offset information */
- dup_pkt->secnn = secnn;
- dup_pkt->offset = image_offset;
- dup_pkt->relo_chain = NULL;
-
- /* Copy the original packet content */
- dup_pkt->img_pkt = *ipacket;
- dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1);
- for (i = 0; i < ipacket->packet_size; i++)
- *(dup_pkt->img_pkt.img_data + i) =
- *(ipacket->img_data + i);
-
- /* Add the packet to the dup list */
- dup_pkt->next = dlthis->tramp.dup_pkts;
- dlthis->tramp.dup_pkts = dup_pkt;
- } else
- dload_error(dlthis, "Failed to create dup packet!");
- } else {
- /* The image packet contents could have changed since
- * trampoline detection happens during relocation of the image
- * packets. So, we need to update the image packet contents
- * before adding relo information. */
- for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
- *(dup_pkt->img_pkt.img_data + i) =
- *(ipacket->img_data + i);
- }
-
- /* Since the previous code may have allocated a new dup packet for us,
- double check that we actually have one. */
- if (dup_pkt != NULL) {
- /* Allocate a new node for the relo chain. Each image packet
- * can potentially have multiple relocations that cause a
- * trampoline to be generated. So, we keep them in a chain,
- * order is not important. */
- dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym,
- sizeof(struct tramp_img_dup_relo));
- if (dup_relo != NULL) {
- /* Copy the relo contents, adjust for the new
- * trampoline and add it to the list. */
- dup_relo->relo = *rp;
- dup_relo->relo.SYMNDX = new_tramp_sym->index;
-
- dup_relo->next = dup_pkt->relo_chain;
- dup_pkt->relo_chain = dup_relo;
-
- /* That's it, we're done. Make sure we update our
- * return value to be success since everything finished
- * ok */
- ret_val = 1;
- } else
- dload_error(dlthis, "Unable to alloc dup relo");
- }
-
- return ret_val;
-}
-
-/*
- * Function: dload_tramp_avail
- * Description: Check to see if the target supports a trampoline for this type
- * of relocation. Return true if it does, otherwise false.
- */
-bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp)
-{
- bool ret_val = false;
- u16 map_index;
- u16 gen_index;
-
- /* Check type hash vs. target tramp table */
- map_index = HASH_FUNC(rp->TYPE);
- gen_index = tramp_map[map_index];
- if (gen_index != TRAMP_NO_GEN_AVAIL)
- ret_val = true;
-
- return ret_val;
-}
-
-/*
- * Function: dload_tramp_generate
- * Description: Create a new trampoline for the provided image packet and
- * relocation causing problems. This will create the trampoline
- * as well as duplicate/update the image packet and relocation
- * causing the problem, which will be relo'd again during
- * finalization.
- */
-int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
- u32 image_offset, struct image_packet_t *ipacket,
- struct reloc_record_t *rp)
-{
- u16 map_index;
- u16 gen_index;
- int ret_val = 1;
- char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN];
- struct local_symbol *ref_sym;
- struct tramp_sym *new_tramp_sym;
- struct tramp_sym *new_ext_sym;
- struct tramp_string *new_tramp_str;
- u32 new_tramp_base;
- struct local_symbol tmp_sym;
- struct local_symbol ext_tmp_sym;
-
- /* Hash the relo type to get our generator information */
- map_index = HASH_FUNC(rp->TYPE);
- gen_index = tramp_map[map_index];
- if (gen_index != TRAMP_NO_GEN_AVAIL) {
- /* If this is the first trampoline, create the section name in
- * our string table for debug help later. */
- if (dlthis->tramp.string_head == NULL) {
- priv_tramp_string_create(dlthis,
- strlen(TRAMP_SECT_NAME),
- TRAMP_SECT_NAME);
- }
-#ifdef ENABLE_TRAMP_DEBUG
- dload_syms_error(dlthis->mysym,
- "Trampoline at img loc %x, references %x",
- dlthis->ldr_sections[secnn].run_addr +
- image_offset + rp->vaddr,
- dlthis->local_symtab[rp->SYMNDX].value);
-#endif
-
- /* Generate the trampoline string, check if already defined.
- * If the relo symbol index is -1, it means we need the section
- * info for relo later. To do this we'll dummy up a symbol
- * with the section delta and run addresses. */
- if (rp->SYMNDX == -1) {
- ext_tmp_sym.value =
- dlthis->ldr_sections[secnn].run_addr;
- ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr;
- ref_sym = &ext_tmp_sym;
- } else
- ref_sym = &(dlthis->local_symtab[rp->SYMNDX]);
-
- priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str);
- new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str);
- if (new_tramp_sym == NULL) {
- /* If tramp string not defined, create it and a new
- * string, and symbol for it as well as the original
- * symbol which caused the trampoline. */
- new_tramp_str = priv_tramp_string_create(dlthis,
- strlen
- (tramp_sym_str),
- tramp_sym_str);
- if (new_tramp_str == NULL) {
- dload_error(dlthis, "Failed to create new "
- "trampoline string\n");
- ret_val = 0;
- } else {
- /* Allocate tramp section space for the new
- * tramp from the target */
- new_tramp_base = priv_tramp_sect_alloc(dlthis,
- tramp_size_get());
-
- /* We have a string, create the new symbol and
- * duplicate the external. */
- tmp_sym.value = new_tramp_base;
- tmp_sym.delta = 0;
- tmp_sym.secnn = -1;
- tmp_sym.sclass = 0;
- new_tramp_sym = priv_tramp_sym_create(dlthis,
- new_tramp_str->
- index,
- &tmp_sym);
-
- new_ext_sym = priv_tramp_sym_create(dlthis, -1,
- ref_sym);
-
- if ((new_tramp_sym != NULL) &&
- (new_ext_sym != NULL)) {
- /* Call the image generator to get the
- * new image data and fix up its
- * relocations for the external
- * symbol. */
- ret_val = priv_tgt_img_gen(dlthis,
- new_tramp_base,
- gen_index,
- new_ext_sym);
-
- /* Add generated image data to tramp
- * image list */
- if (ret_val != 1) {
- dload_error(dlthis, "Failed to "
- "create img pkt for"
- " trampoline\n");
- }
- } else {
- dload_error(dlthis, "Failed to create "
- "new tramp syms "
- "(%8.8X, %8.8X)\n",
- new_tramp_sym, new_ext_sym);
- ret_val = 0;
- }
- }
- }
-
- /* Duplicate the image data and relo record that caused the
- * tramp, including update the relo data to point to the tramp
- * symbol. */
- if (ret_val == 1) {
- ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset,
- ipacket, rp, new_tramp_sym);
- if (ret_val != 1) {
- dload_error(dlthis, "Failed to create dup of "
- "original img pkt\n");
- }
- }
- }
-
- return ret_val;
-}
-
-/*
- * Function: dload_tramp_pkt_update
- * Description: Update the duplicate copy of this image packet, which the
- * trampoline layer is already tracking. This call is critical
- * to make if trampolines were generated anywhere within the
- * packet and first pass relo continued on the remainder. The
- * trampoline layer needs the updates image data so when 2nd
- * pass relo is done during finalize the image packet can be
- * written to the target since all relo is done.
- */
-int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn,
- u32 image_offset, struct image_packet_t *ipacket)
-{
- struct tramp_img_dup_pkt *dup_pkt = NULL;
- s32 i;
- int ret_val = 0;
-
- /* Find the image packet in question, the caller needs us to update it
- since a trampoline was previously generated. */
- dup_pkt = priv_dup_find(dlthis, secnn, image_offset);
- if (dup_pkt != NULL) {
- for (i = 0; i < dup_pkt->img_pkt.packet_size; i++)
- *(dup_pkt->img_pkt.img_data + i) =
- *(ipacket->img_data + i);
-
- ret_val = 1;
- } else {
- dload_error(dlthis,
- "Unable to find existing DUP pkt for %x, offset %x",
- secnn, image_offset);
-
- }
-
- return ret_val;
-}
-
-/*
- * Function: dload_tramp_finalize
- * Description: If any trampolines were created, finalize everything on the
- * target by allocating the trampoline section on the target,
- * finalizing the trampoline symbols, finalizing the trampoline
- * packets (write the new section to target memory) and finalize
- * the duplicate packets by doing 2nd pass relo over them.
- */
-int dload_tramp_finalize(struct dload_state *dlthis)
-{
- int ret_val = 1;
-
- if (dlthis->tramp.tramp_sect_next_addr != 0) {
- /* Finalize strings into a flat table. This is needed so it
- * can be added to the debug string table later. */
- ret_val = priv_string_tbl_finalize(dlthis);
-
- /* Do target allocation for section BEFORE finalizing
- * symbols. */
- if (ret_val != 0)
- ret_val = priv_tramp_sect_tgt_alloc(dlthis);
-
- /* Finalize symbols with their correct target information and
- * flatten */
- if (ret_val != 0)
- ret_val = priv_tramp_sym_finalize(dlthis);
-
- /* Finalize all trampoline packets. This performs the
- * relocation on the packets as well as writing them to target
- * memory. */
- if (ret_val != 0)
- ret_val = priv_tramp_pkt_finalize(dlthis);
-
- /* Perform a 2nd pass relocation on the dup list. */
- if (ret_val != 0)
- ret_val = priv_dup_pkt_finalize(dlthis);
- }
-
- return ret_val;
-}
-
-/*
- * Function: dload_tramp_cleanup
- * Description: Release all temporary resources used in the trampoline layer.
- * Note that the target memory which may have been allocated and
- * written to store the trampolines is NOT RELEASED HERE since it
- * is potentially still in use. It is automatically released
- * when the module is unloaded.
- */
-void dload_tramp_cleanup(struct dload_state *dlthis)
-{
- struct tramp_info *tramp = &dlthis->tramp;
- struct tramp_sym *cur_sym;
- struct tramp_string *cur_string;
- struct tramp_img_pkt *cur_tramp_pkt;
- struct tramp_img_dup_pkt *cur_dup_pkt;
- struct tramp_img_dup_relo *cur_dup_relo;
-
- /* If there were no tramps generated, just return */
- if (tramp->tramp_sect_next_addr == 0)
- return;
-
- /* Destroy all tramp information */
- for (cur_sym = tramp->symbol_head;
- cur_sym != NULL; cur_sym = tramp->symbol_head) {
- tramp->symbol_head = cur_sym->next;
- if (tramp->symbol_tail == cur_sym)
- tramp->symbol_tail = NULL;
-
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym);
- }
-
- if (tramp->final_sym_table != NULL)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- tramp->final_sym_table);
-
- for (cur_string = tramp->string_head;
- cur_string != NULL; cur_string = tramp->string_head) {
- tramp->string_head = cur_string->next;
- if (tramp->string_tail == cur_string)
- tramp->string_tail = NULL;
-
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string);
- }
-
- if (tramp->final_string_table != NULL)
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- tramp->final_string_table);
-
- for (cur_tramp_pkt = tramp->tramp_pkts;
- cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) {
- tramp->tramp_pkts = cur_tramp_pkt->next;
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt);
- }
-
- for (cur_dup_pkt = tramp->dup_pkts;
- cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) {
- tramp->dup_pkts = cur_dup_pkt->next;
-
- for (cur_dup_relo = cur_dup_pkt->relo_chain;
- cur_dup_relo != NULL;
- cur_dup_relo = cur_dup_pkt->relo_chain) {
- cur_dup_pkt->relo_chain = cur_dup_relo->next;
- dlthis->mysym->dload_deallocate(dlthis->mysym,
- cur_dup_relo);
- }
-
- dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt);
- }
-}
diff --git a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c b/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c
deleted file mode 100644
index 09cc64f213c0..000000000000
--- a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * tramp_table_c6000.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "dload_internal.h"
-
-/* These are defined in coff.h, but may not be available on all platforms
- so we'll go ahead and define them here. */
-#ifndef R_C60LO16
-#define R_C60LO16 0x54 /* C60: MVK Low Half Register */
-#define R_C60HI16 0x55 /* C60: MVKH/MVKLH High Half Register */
-#endif
-
-#define C6X_TRAMP_WORD_COUNT 8
-#define C6X_TRAMP_MAX_RELOS 8
-
-/* THIS HASH FUNCTION MUST MATCH THE ONE reloc_table_c6000.c */
-#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63)
-
-/* THIS MUST MATCH reloc_record_t FOR A SYMBOL BASED RELO */
-struct c6000_relo_record {
- s32 vaddr;
- s32 symndx;
-#ifndef _BIG_ENDIAN
- u16 disp;
- u16 type;
-#else
- u16 type;
- u16 disp;
-#endif
-};
-
-struct c6000_gen_code {
- struct tramp_gen_code_hdr hdr;
- u32 tramp_instrs[C6X_TRAMP_WORD_COUNT];
- struct c6000_relo_record relos[C6X_TRAMP_MAX_RELOS];
-};
-
-/* Hash mapping for relos that can cause trampolines. */
-static const u16 tramp_map[] = {
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 0,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535,
- 65535
-};
-
-static const struct c6000_gen_code tramp_gen_info[] = {
- /* Tramp caused by R_C60PCR21 */
- {
- /* Header - 8 instructions, 2 relos */
- {
- sizeof(u32) * C6X_TRAMP_WORD_COUNT,
- 2,
- FIELD_OFFSET(struct c6000_gen_code, relos)
- },
-
- /* Trampoline instructions */
- {
- 0x053C54F7, /* STW.D2T2 B10, *sp--[2] */
- 0x0500002A, /* || MVK.S2 <blank>, B10 */
- 0x0500006A, /* MVKH.S2 <blank>, B10 */
- 0x00280362, /* B.S2 B10 */
- 0x053C52E6, /* LDW.D2T2 *++sp[2], B10 */
- 0x00006000, /* NOP 4 */
- 0x00000000, /* NOP */
- 0x00000000 /* NOP */
- },
-
- /* Relocations */
- {
- {4, 0, 0, R_C60LO16},
- {8, 0, 0, R_C60HI16},
- {0, 0, 0, 0x0000},
- {0, 0, 0, 0x0000},
- {0, 0, 0, 0x0000},
- {0, 0, 0, 0x0000},
- {0, 0, 0, 0x0000},
- {0, 0, 0, 0x0000}
- }
- }
-};
-
-/* TARGET SPECIFIC FUNCTIONS THAT MUST BE DEFINED */
-static u32 tramp_size_get(void)
-{
- return sizeof(u32) * C6X_TRAMP_WORD_COUNT;
-}
-
-static u32 tramp_img_pkt_size_get(void)
-{
- return sizeof(struct c6000_gen_code);
-}
diff --git a/drivers/staging/tidspbridge/gen/gh.c b/drivers/staging/tidspbridge/gen/gh.c
deleted file mode 100644
index 936470cb608e..000000000000
--- a/drivers/staging/tidspbridge/gen/gh.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * gh.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/err.h>
-#include <linux/hashtable.h>
-#include <linux/slab.h>
-
-struct gh_node {
- struct hlist_node hl;
- u8 data[0];
-};
-
-#define GH_HASH_ORDER 8
-
-struct gh_t_hash_tab {
- u32 val_size;
- DECLARE_HASHTABLE(hash_table, GH_HASH_ORDER);
- u32 (*hash)(const void *key);
- bool (*match)(const void *key, const void *value);
- void (*delete)(void *key);
-};
-
-/*
- * ======== gh_create ========
- */
-
-struct gh_t_hash_tab *gh_create(u32 val_size, u32 (*hash)(const void *),
- bool (*match)(const void *, const void *),
- void (*delete)(void *))
-{
- struct gh_t_hash_tab *hash_tab;
-
- hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL);
- if (!hash_tab)
- return ERR_PTR(-ENOMEM);
-
- hash_init(hash_tab->hash_table);
-
- hash_tab->val_size = val_size;
- hash_tab->hash = hash;
- hash_tab->match = match;
- hash_tab->delete = delete;
-
- return hash_tab;
-}
-
-/*
- * ======== gh_delete ========
- */
-void gh_delete(struct gh_t_hash_tab *hash_tab)
-{
- struct gh_node *n;
- struct hlist_node *tmp;
- u32 i;
-
- if (hash_tab) {
- hash_for_each_safe(hash_tab->hash_table, i, tmp, n, hl) {
- hash_del(&n->hl);
- if (hash_tab->delete)
- hash_tab->delete(n->data);
- kfree(n);
- }
-
- kfree(hash_tab);
- }
-}
-
-/*
- * ======== gh_find ========
- */
-
-void *gh_find(struct gh_t_hash_tab *hash_tab, const void *key)
-{
- struct gh_node *n;
- u32 key_hash = hash_tab->hash(key);
-
- hash_for_each_possible(hash_tab->hash_table, n, hl, key_hash) {
- if (hash_tab->match(key, n->data))
- return n->data;
- }
-
- return ERR_PTR(-ENODATA);
-}
-
-/*
- * ======== gh_insert ========
- */
-
-void *gh_insert(struct gh_t_hash_tab *hash_tab, const void *key,
- const void *value)
-{
- struct gh_node *n;
-
- n = kmalloc(sizeof(struct gh_node) + hash_tab->val_size,
- GFP_KERNEL);
-
- if (!n)
- return ERR_PTR(-ENOMEM);
-
- INIT_HLIST_NODE(&n->hl);
- hash_add(hash_tab->hash_table, &n->hl, hash_tab->hash(key));
- memcpy(n->data, value, hash_tab->val_size);
-
- return n->data;
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/**
- * gh_iterate() - This function goes through all the elements in the hash table
- * looking for the dsp symbols.
- * @hash_tab: Hash table
- * @callback: pointer to callback function
- * @user_data: User data, contains the find_symbol_context pointer
- *
- */
-void gh_iterate(struct gh_t_hash_tab *hash_tab,
- void (*callback)(void *, void *), void *user_data)
-{
- struct gh_node *n;
- u32 i;
-
- if (!hash_tab)
- return;
-
- hash_for_each(hash_tab->hash_table, i, n, hl)
- callback(&n->data, user_data);
-}
-#endif
diff --git a/drivers/staging/tidspbridge/hw/EasiGlobal.h b/drivers/staging/tidspbridge/hw/EasiGlobal.h
deleted file mode 100644
index e48d7f67c60a..000000000000
--- a/drivers/staging/tidspbridge/hw/EasiGlobal.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * EasiGlobal.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _EASIGLOBAL_H
-#define _EASIGLOBAL_H
-#include <linux/types.h>
-
-/*
- * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE
- *
- * DESCRIPTION: Defines used to describe register types for EASI-checker tests.
- */
-
-#define READ_ONLY 1
-#define WRITE_ONLY 2
-#define READ_WRITE 3
-
-/*
- * MACRO: _DEBUG_LEVEL1_EASI
- *
- * DESCRIPTION: A MACRO which can be used to indicate that a particular beach
- * register access function was called.
- *
- * NOTE: We currently dont use this functionality.
- */
-#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0)
-
-#endif /* _EASIGLOBAL_H */
diff --git a/drivers/staging/tidspbridge/hw/MMUAccInt.h b/drivers/staging/tidspbridge/hw/MMUAccInt.h
deleted file mode 100644
index 1cefca321d71..000000000000
--- a/drivers/staging/tidspbridge/hw/MMUAccInt.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * MMUAccInt.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _MMU_ACC_INT_H
-#define _MMU_ACC_INT_H
-
-/* Mappings of level 1 EASI function numbers to function names */
-
-#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3)
-#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32 (MMU_BASE_EASIL1 + 17)
-#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32 (MMU_BASE_EASIL1 + 39)
-#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 51)
-#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102)
-#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103)
-#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156)
-#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174)
-#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 180)
-#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 190)
-#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32 (MMU_BASE_EASIL1 + 194)
-#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 198)
-#define EASIL1_MMUMMU_LOCK_READ_REGISTER32 (MMU_BASE_EASIL1 + 203)
-#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 204)
-#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32 (MMU_BASE_EASIL1 + 205)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211)
-#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32 (MMU_BASE_EASIL1 + 212)
-#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32 (MMU_BASE_EASIL1 + 213)
-#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 214)
-#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 226)
-#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268)
-#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 322)
-
-/* Register offset address definitions */
-#define MMU_MMU_SYSCONFIG_OFFSET 0x10
-#define MMU_MMU_IRQSTATUS_OFFSET 0x18
-#define MMU_MMU_IRQENABLE_OFFSET 0x1c
-#define MMU_MMU_WALKING_ST_OFFSET 0x40
-#define MMU_MMU_CNTL_OFFSET 0x44
-#define MMU_MMU_FAULT_AD_OFFSET 0x48
-#define MMU_MMU_TTB_OFFSET 0x4c
-#define MMU_MMU_LOCK_OFFSET 0x50
-#define MMU_MMU_LD_TLB_OFFSET 0x54
-#define MMU_MMU_CAM_OFFSET 0x58
-#define MMU_MMU_RAM_OFFSET 0x5c
-#define MMU_MMU_GFLUSH_OFFSET 0x60
-#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64
-/* Bitfield mask and offset declarations */
-#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK 0x18
-#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET 3
-#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK 0x1
-#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET 0
-#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1
-#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET 0
-#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4
-#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2
-#define MMU_MMU_CNTL_MMU_ENABLE_MASK 0x2
-#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET 1
-#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00
-#define MMU_MMU_LOCK_BASE_VALUE_OFFSET 10
-#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK 0x3f0
-#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET 4
-
-#endif /* _MMU_ACC_INT_H */
diff --git a/drivers/staging/tidspbridge/hw/MMURegAcM.h b/drivers/staging/tidspbridge/hw/MMURegAcM.h
deleted file mode 100644
index ab1a16da731c..000000000000
--- a/drivers/staging/tidspbridge/hw/MMURegAcM.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * MMURegAcM.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _MMU_REG_ACM_H
-#define _MMU_REG_ACM_H
-
-#include <linux/io.h>
-#include <EasiGlobal.h>
-
-#include "MMUAccInt.h"
-
-#if defined(USE_LEVEL_1_MACROS)
-
-#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET))
-
-#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\
- data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\
- new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\
- new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\
- data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\
- new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\
- new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\
- __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET))
-
-#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET))
-
-#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\
- & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\
- MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET))
-
-#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\
- MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\
- MMU_MMU_CNTL_TWL_ENABLE_OFFSET))
-
-#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CNTL_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\
- data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\
- new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\
- new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CNTL_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\
- data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\
- new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\
- new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET))
-
-#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_TTB_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_LOCK_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET))
-
-#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
- MMU_MMU_LOCK_BASE_VALUE_MASK) >>\
- MMU_MMU_LOCK_BASE_VALUE_OFFSET))
-
-#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\
- data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\
- new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\
- new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\
- (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\
- MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\
- MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET))
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LOCK_OFFSET;\
- register u32 data = __raw_readl((base_address)+offset);\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\
- data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\
- new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\
- new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\
- new_value |= data;\
- __raw_writel(new_value, base_address+offset);\
-}
-
-#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\
- (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\
- (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\
- MMU_MMU_LOCK_CURRENT_VICTIM_MASK)))
-
-#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\
- (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\
- __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET))
-
-#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_LD_TLB_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_CAM_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_RAM_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\
-{\
- const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\
- register u32 new_value = (value);\
- _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\
- __raw_writel(new_value, (base_address)+offset);\
-}
-
-#endif /* USE_LEVEL_1_MACROS */
-
-#endif /* _MMU_REG_ACM_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_defs.h b/drivers/staging/tidspbridge/hw/hw_defs.h
deleted file mode 100644
index d5266d4c163f..000000000000
--- a/drivers/staging/tidspbridge/hw/hw_defs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * hw_defs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global HW definitions
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _HW_DEFS_H
-#define _HW_DEFS_H
-
-/* Page size */
-#define HW_PAGE_SIZE4KB 0x1000
-#define HW_PAGE_SIZE64KB 0x10000
-#define HW_PAGE_SIZE1MB 0x100000
-#define HW_PAGE_SIZE16MB 0x1000000
-
-/* hw_status: return type for HW API */
-typedef long hw_status;
-
-/* Macro used to set and clear any bit */
-#define HW_CLEAR 0
-#define HW_SET 1
-
-/* hw_endianism_t: Enumerated Type used to specify the endianism
- * Do NOT change these values. They are used as bit fields. */
-enum hw_endianism_t {
- HW_LITTLE_ENDIAN,
- HW_BIG_ENDIAN
-};
-
-/* hw_element_size_t: Enumerated Type used to specify the element size
- * Do NOT change these values. They are used as bit fields. */
-enum hw_element_size_t {
- HW_ELEM_SIZE8BIT,
- HW_ELEM_SIZE16BIT,
- HW_ELEM_SIZE32BIT,
- HW_ELEM_SIZE64BIT
-};
-
-/* hw_idle_mode_t: Enumerated Type used to specify Idle modes */
-enum hw_idle_mode_t {
- HW_FORCE_IDLE,
- HW_NO_IDLE,
- HW_SMART_IDLE
-};
-
-#endif /* _HW_DEFS_H */
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.c b/drivers/staging/tidspbridge/hw/hw_mmu.c
deleted file mode 100644
index 50244a474178..000000000000
--- a/drivers/staging/tidspbridge/hw/hw_mmu.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * hw_mmu.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * API definitions to setup MMU TLB and PTE
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/io.h>
-#include "MMURegAcM.h"
-#include <hw_defs.h>
-#include <hw_mmu.h>
-#include <linux/types.h>
-#include <linux/err.h>
-
-#define MMU_BASE_VAL_MASK 0xFC00
-#define MMU_PAGE_MAX 3
-#define MMU_ELEMENTSIZE_MAX 3
-#define MMU_ADDR_MASK 0xFFFFF000
-#define MMU_TTB_MASK 0xFFFFC000
-#define MMU_SECTION_ADDR_MASK 0xFFF00000
-#define MMU_SSECTION_ADDR_MASK 0xFF000000
-#define MMU_PAGE_TABLE_MASK 0xFFFFFC00
-#define MMU_LARGE_PAGE_MASK 0xFFFF0000
-#define MMU_SMALL_PAGE_MASK 0xFFFFF000
-
-#define MMU_LOAD_TLB 0x00000001
-#define MMU_GFLUSH 0x60
-
-/*
- * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS)
- */
-enum hw_mmu_page_size_t {
- HW_MMU_SECTION,
- HW_MMU_LARGE_PAGE,
- HW_MMU_SMALL_PAGE,
- HW_MMU_SUPERSECTION
-};
-
-/*
- * FUNCTION : mmu_set_cam_entry
- *
- * INPUTS:
- *
- * Identifier : base_address
- * Type : void __iomem *
- * Description : Base Address of instance of MMU module
- *
- * Identifier : page_sz
- * TypE : const u32
- * Description : It indicates the page size
- *
- * Identifier : preserved_bit
- * Type : const u32
- * Description : It indicates the TLB entry is preserved entry
- * or not
- *
- * Identifier : valid_bit
- * Type : const u32
- * Description : It indicates the TLB entry is valid entry or not
- *
- *
- * Identifier : virtual_addr_tag
- * Type : const u32
- * Description : virtual Address
- *
- * RETURNS:
- *
- * Type : hw_status
- * Description : 0 -- No errors occurred
- * RET_BAD_NULL_PARAM -- A Pointer Parameter
- * was set to NULL
- * RET_PARAM_OUT_OF_RANGE -- Input Parameter out
- * of Range
- *
- * PURPOSE: : Set MMU_CAM reg
- *
- * METHOD: : Check the Input parameters and set the CAM entry.
- */
-static hw_status mmu_set_cam_entry(void __iomem *base_address,
- const u32 page_sz,
- const u32 preserved_bit,
- const u32 valid_bit,
- const u32 virtual_addr_tag);
-
-/*
- * FUNCTION : mmu_set_ram_entry
- *
- * INPUTS:
- *
- * Identifier : base_address
- * Type : void __iomem *
- * Description : Base Address of instance of MMU module
- *
- * Identifier : physical_addr
- * Type : const u32
- * Description : Physical Address to which the corresponding
- * virtual Address shouldpoint
- *
- * Identifier : endianism
- * Type : hw_endianism_t
- * Description : endianism for the given page
- *
- * Identifier : element_size
- * Type : hw_element_size_t
- * Description : The element size ( 8,16, 32 or 64 bit)
- *
- * Identifier : mixed_size
- * Type : hw_mmu_mixed_size_t
- * Description : Element Size to follow CPU or TLB
- *
- * RETURNS:
- *
- * Type : hw_status
- * Description : 0 -- No errors occurred
- * RET_BAD_NULL_PARAM -- A Pointer Parameter
- * was set to NULL
- * RET_PARAM_OUT_OF_RANGE -- Input Parameter
- * out of Range
- *
- * PURPOSE: : Set MMU_CAM reg
- *
- * METHOD: : Check the Input parameters and set the RAM entry.
- */
-static hw_status mmu_set_ram_entry(void __iomem *base_address,
- const u32 physical_addr,
- enum hw_endianism_t endianism,
- enum hw_element_size_t element_size,
- enum hw_mmu_mixed_size_t mixed_size);
-
-/* HW FUNCTIONS */
-
-hw_status hw_mmu_enable(void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET);
-
- return status;
-}
-
-hw_status hw_mmu_disable(void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR);
-
- return status;
-}
-
-hw_status hw_mmu_num_locked_set(void __iomem *base_address,
- u32 num_locked_entries)
-{
- hw_status status = 0;
-
- MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries);
-
- return status;
-}
-
-hw_status hw_mmu_victim_num_set(void __iomem *base_address,
- u32 victim_entry_num)
-{
- hw_status status = 0;
-
- MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num);
-
- return status;
-}
-
-hw_status hw_mmu_event_ack(void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
-
- MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_disable(void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
- u32 irq_reg;
-
- irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
-
- MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_enable(void __iomem *base_address, u32 irq_mask)
-{
- hw_status status = 0;
- u32 irq_reg;
-
- irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
-
- MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask);
-
- return status;
-}
-
-hw_status hw_mmu_event_status(void __iomem *base_address, u32 *irq_mask)
-{
- hw_status status = 0;
-
- *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address);
-
- return status;
-}
-
-hw_status hw_mmu_fault_addr_read(void __iomem *base_address, u32 *addr)
-{
- hw_status status = 0;
-
- /* read values from register */
- *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address);
-
- return status;
-}
-
-hw_status hw_mmu_ttb_set(void __iomem *base_address, u32 ttb_phys_addr)
-{
- hw_status status = 0;
- u32 load_ttb;
-
- load_ttb = ttb_phys_addr & ~0x7FUL;
- /* write values to register */
- MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb);
-
- return status;
-}
-
-hw_status hw_mmu_twl_enable(void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET);
-
- return status;
-}
-
-hw_status hw_mmu_twl_disable(void __iomem *base_address)
-{
- hw_status status = 0;
-
- MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR);
-
- return status;
-}
-
-hw_status hw_mmu_tlb_add(void __iomem *base_address,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- u32 entry_num,
- struct hw_mmu_map_attrs_t *map_attrs,
- s8 preserved_bit, s8 valid_bit)
-{
- hw_status status = 0;
- u32 lock_reg;
- u32 virtual_addr_tag;
- enum hw_mmu_page_size_t mmu_pg_size;
-
- /*Check the input Parameters */
- switch (page_sz) {
- case HW_PAGE_SIZE4KB:
- mmu_pg_size = HW_MMU_SMALL_PAGE;
- break;
-
- case HW_PAGE_SIZE64KB:
- mmu_pg_size = HW_MMU_LARGE_PAGE;
- break;
-
- case HW_PAGE_SIZE1MB:
- mmu_pg_size = HW_MMU_SECTION;
- break;
-
- case HW_PAGE_SIZE16MB:
- mmu_pg_size = HW_MMU_SUPERSECTION;
- break;
-
- default:
- return -EINVAL;
- }
-
- lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address);
-
- /* Generate the 20-bit tag from virtual address */
- virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12);
-
- /* Write the fields in the CAM Entry Register */
- mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit,
- virtual_addr_tag);
-
- /* Write the different fields of the RAM Entry Register */
- /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */
- mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism,
- map_attrs->element_size, map_attrs->mixed_size);
-
- /* Update the MMU Lock Register */
- /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
- MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num);
-
- /* Enable loading of an entry in TLB by writing 1
- into LD_TLB_REG register */
- MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB);
-
- MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg);
-
- return status;
-}
-
-hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs)
-{
- hw_status status = 0;
- u32 pte_addr, pte_val;
- s32 num_entries = 1;
-
- switch (page_sz) {
- case HW_PAGE_SIZE4KB:
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_SMALL_PAGE_MASK);
- pte_val =
- ((physical_addr & MMU_SMALL_PAGE_MASK) |
- (map_attrs->endianism << 9) | (map_attrs->
- element_size << 4) |
- (map_attrs->mixed_size << 11) | 2);
- break;
-
- case HW_PAGE_SIZE64KB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_LARGE_PAGE_MASK);
- pte_val =
- ((physical_addr & MMU_LARGE_PAGE_MASK) |
- (map_attrs->endianism << 9) | (map_attrs->
- element_size << 4) |
- (map_attrs->mixed_size << 11) | 1);
- break;
-
- case HW_PAGE_SIZE1MB:
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SECTION_ADDR_MASK);
- pte_val =
- ((((physical_addr & MMU_SECTION_ADDR_MASK) |
- (map_attrs->endianism << 15) | (map_attrs->
- element_size << 10) |
- (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2);
- break;
-
- case HW_PAGE_SIZE16MB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SSECTION_ADDR_MASK);
- pte_val =
- (((physical_addr & MMU_SSECTION_ADDR_MASK) |
- (map_attrs->endianism << 15) | (map_attrs->
- element_size << 10) |
- (map_attrs->mixed_size << 17)
- ) | 0x40000 | 0x2);
- break;
-
- case HW_MMU_COARSE_PAGE_SIZE:
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SECTION_ADDR_MASK);
- pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1;
- break;
-
- default:
- return -EINVAL;
- }
-
- while (--num_entries >= 0)
- ((u32 *) pte_addr)[num_entries] = pte_val;
-
- return status;
-}
-
-hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size)
-{
- hw_status status = 0;
- u32 pte_addr;
- s32 num_entries = 1;
-
- switch (page_size) {
- case HW_PAGE_SIZE4KB:
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_SMALL_PAGE_MASK);
- break;
-
- case HW_PAGE_SIZE64KB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
- virtual_addr &
- MMU_LARGE_PAGE_MASK);
- break;
-
- case HW_PAGE_SIZE1MB:
- case HW_MMU_COARSE_PAGE_SIZE:
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SECTION_ADDR_MASK);
- break;
-
- case HW_PAGE_SIZE16MB:
- num_entries = 16;
- pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
- virtual_addr &
- MMU_SSECTION_ADDR_MASK);
- break;
-
- default:
- return -EINVAL;
- }
-
- while (--num_entries >= 0)
- ((u32 *) pte_addr)[num_entries] = 0;
-
- return status;
-}
-
-/* mmu_set_cam_entry */
-static hw_status mmu_set_cam_entry(void __iomem *base_address,
- const u32 page_sz,
- const u32 preserved_bit,
- const u32 valid_bit,
- const u32 virtual_addr_tag)
-{
- hw_status status = 0;
- u32 mmu_cam_reg;
-
- mmu_cam_reg = (virtual_addr_tag << 12);
- mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) |
- (preserved_bit << 3);
-
- /* write values to register */
- MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg);
-
- return status;
-}
-
-/* mmu_set_ram_entry */
-static hw_status mmu_set_ram_entry(void __iomem *base_address,
- const u32 physical_addr,
- enum hw_endianism_t endianism,
- enum hw_element_size_t element_size,
- enum hw_mmu_mixed_size_t mixed_size)
-{
- hw_status status = 0;
- u32 mmu_ram_reg;
-
- mmu_ram_reg = (physical_addr & MMU_ADDR_MASK);
- mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) |
- (mixed_size << 6));
-
- /* write values to register */
- MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg);
-
- return status;
-
-}
-
-void hw_mmu_tlb_flush_all(void __iomem *base)
-{
- __raw_writel(1, base + MMU_GFLUSH);
-}
diff --git a/drivers/staging/tidspbridge/hw/hw_mmu.h b/drivers/staging/tidspbridge/hw/hw_mmu.h
deleted file mode 100644
index 1c50bb36edfe..000000000000
--- a/drivers/staging/tidspbridge/hw/hw_mmu.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * hw_mmu.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * MMU types and API declarations
- *
- * Copyright (C) 2007 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _HW_MMU_H
-#define _HW_MMU_H
-
-#include <linux/types.h>
-
-/* Bitmasks for interrupt sources */
-#define HW_MMU_TRANSLATION_FAULT 0x2
-#define HW_MMU_ALL_INTERRUPTS 0x1F
-
-#define HW_MMU_COARSE_PAGE_SIZE 0x400
-
-/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow
- CPU/TLB Element size */
-enum hw_mmu_mixed_size_t {
- HW_MMU_TLBES,
- HW_MMU_CPUES
-};
-
-/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */
-struct hw_mmu_map_attrs_t {
- enum hw_endianism_t endianism;
- enum hw_element_size_t element_size;
- enum hw_mmu_mixed_size_t mixed_size;
- bool donotlockmpupage;
-};
-
-extern hw_status hw_mmu_enable(void __iomem *base_address);
-
-extern hw_status hw_mmu_disable(void __iomem *base_address);
-
-extern hw_status hw_mmu_num_locked_set(void __iomem *base_address,
- u32 num_locked_entries);
-
-extern hw_status hw_mmu_victim_num_set(void __iomem *base_address,
- u32 victim_entry_num);
-
-/* For MMU faults */
-extern hw_status hw_mmu_event_ack(void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_disable(void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_enable(void __iomem *base_address,
- u32 irq_mask);
-
-extern hw_status hw_mmu_event_status(void __iomem *base_address,
- u32 *irq_mask);
-
-extern hw_status hw_mmu_fault_addr_read(void __iomem *base_address,
- u32 *addr);
-
-/* Set the TT base address */
-extern hw_status hw_mmu_ttb_set(void __iomem *base_address,
- u32 ttb_phys_addr);
-
-extern hw_status hw_mmu_twl_enable(void __iomem *base_address);
-
-extern hw_status hw_mmu_twl_disable(void __iomem *base_address);
-
-extern hw_status hw_mmu_tlb_add(void __iomem *base_address,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- u32 entry_num,
- struct hw_mmu_map_attrs_t *map_attrs,
- s8 preserved_bit, s8 valid_bit);
-
-/* For PTEs */
-extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
- u32 physical_addr,
- u32 virtual_addr,
- u32 page_sz,
- struct hw_mmu_map_attrs_t *map_attrs);
-
-extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va,
- u32 virtual_addr, u32 page_size);
-
-void hw_mmu_tlb_flush_all(void __iomem *base);
-
-static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va)
-{
- u32 pte_addr;
- u32 va31_to20;
-
- va31_to20 = va >> (20 - 2); /* Left-shift by 2 here itself */
- va31_to20 &= 0xFFFFFFFCUL;
- pte_addr = l1_base + va31_to20;
-
- return pte_addr;
-}
-
-static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va)
-{
- u32 pte_addr;
-
- pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC);
-
- return pte_addr;
-}
-
-static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val)
-{
- u32 pte_coarse;
-
- pte_coarse = pte_val & 0xFFFFFC00;
-
- return pte_coarse;
-}
-
-static inline u32 hw_mmu_pte_size_l1(u32 pte_val)
-{
- u32 pte_size = 0;
-
- if ((pte_val & 0x3) == 0x1) {
- /* Points to L2 PT */
- pte_size = HW_MMU_COARSE_PAGE_SIZE;
- }
-
- if ((pte_val & 0x3) == 0x2) {
- if (pte_val & (1 << 18))
- pte_size = HW_PAGE_SIZE16MB;
- else
- pte_size = HW_PAGE_SIZE1MB;
- }
-
- return pte_size;
-}
-
-static inline u32 hw_mmu_pte_size_l2(u32 pte_val)
-{
- u32 pte_size = 0;
-
- if (pte_val & 0x2)
- pte_size = HW_PAGE_SIZE4KB;
- else if (pte_val & 0x1)
- pte_size = HW_PAGE_SIZE64KB;
-
- return pte_size;
-}
-
-#endif /* _HW_MMU_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h
deleted file mode 100644
index cc95a18f1db9..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * _chnl_sm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private header file defining channel manager and channel objects for
- * a shared memory channel driver.
- *
- * Shared between the modules implementing the shared memory channel class
- * library.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _CHNL_SM_
-#define _CHNL_SM_
-
-#include <dspbridge/dspapi.h>
-#include <dspbridge/dspdefs.h>
-
-#include <linux/list.h>
-#include <dspbridge/ntfy.h>
-
-/*
- * These target side symbols define the beginning and ending addresses
- * of shared memory buffer. They are defined in the *cfg.cmd file by
- * cdb code.
- */
-#define CHNL_SHARED_BUFFER_BASE_SYM "_SHM_BEG"
-#define CHNL_SHARED_BUFFER_LIMIT_SYM "_SHM_END"
-#define BRIDGEINIT_BIOSGPTIMER "_BRIDGEINIT_BIOSGPTIMER"
-#define BRIDGEINIT_LOADMON_GPTIMER "_BRIDGEINIT_LOADMON_GPTIMER"
-
-#ifndef _CHNL_WORDSIZE
-#define _CHNL_WORDSIZE 4 /* default _CHNL_WORDSIZE is 2 bytes/word */
-#endif
-
-#define MAXOPPS 16
-
-/* Shared memory config options */
-#define SHM_CURROPP 0 /* Set current OPP in shm */
-#define SHM_OPPINFO 1 /* Set dsp voltage and freq table values */
-#define SHM_GETOPP 2 /* Get opp requested by DSP */
-
-struct opp_table_entry {
- u32 voltage;
- u32 frequency;
- u32 min_freq;
- u32 max_freq;
-};
-
-struct opp_struct {
- u32 curr_opp_pt;
- u32 num_opp_pts;
- struct opp_table_entry opp_point[MAXOPPS];
-};
-
-/* Request to MPU */
-struct opp_rqst_struct {
- u32 rqst_dsp_freq;
- u32 rqst_opp_pt;
-};
-
-/* Info to MPU */
-struct load_mon_struct {
- u32 curr_dsp_load;
- u32 curr_dsp_freq;
- u32 pred_dsp_load;
- u32 pred_dsp_freq;
-};
-
-/* Structure in shared between DSP and PC for communication. */
-struct shm {
- u32 dsp_free_mask; /* Written by DSP, read by PC. */
- u32 host_free_mask; /* Written by PC, read by DSP */
-
- u32 input_full; /* Input channel has unread data. */
- u32 input_id; /* Channel for which input is available. */
- u32 input_size; /* Size of data block (in DSP words). */
-
- u32 output_full; /* Output channel has unread data. */
- u32 output_id; /* Channel for which output is available. */
- u32 output_size; /* Size of data block (in DSP words). */
-
- u32 arg; /* Arg for Issue/Reclaim (23 bits for 55x). */
- u32 resvd; /* Keep structure size even for 32-bit DSPs */
-
- /* Operating Point structure */
- struct opp_struct opp_table_struct;
- /* Operating Point Request structure */
- struct opp_rqst_struct opp_request;
- /* load monitor information structure */
- struct load_mon_struct load_mon_info;
- /* Flag for WDT enable/disable F/I clocks */
- u32 wdt_setclocks;
- u32 wdt_overflow; /* WDT overflow time */
- char dummy[176]; /* padding to 256 byte boundary */
- u32 shm_dbg_var[64]; /* shared memory debug variables */
-};
-
- /* Channel Manager: only one created per board: */
-struct chnl_mgr {
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
- struct io_mgr *iomgr; /* IO manager */
- /* Device this board represents */
- struct dev_object *dev_obj;
-
- /* These fields initialized in bridge_chnl_create(): */
- u32 output_mask; /* Host output channels w/ full buffers */
- u32 last_output; /* Last output channel fired from DPC */
- /* Critical section object handle */
- spinlock_t chnl_mgr_lock;
- u32 word_size; /* Size in bytes of DSP word */
- u8 max_channels; /* Total number of channels */
- u8 open_channels; /* Total number of open channels */
- struct chnl_object **channels; /* Array of channels */
- u8 type; /* Type of channel class library */
- /* If no shm syms, return for CHNL_Open */
- int chnl_open_status;
-};
-
-/*
- * Channel: up to CHNL_MAXCHANNELS per board or if DSP-DMA supported then
- * up to CHNL_MAXCHANNELS + CHNL_MAXDDMACHNLS per board.
- */
-struct chnl_object {
- /* Pointer back to channel manager */
- struct chnl_mgr *chnl_mgr_obj;
- u32 chnl_id; /* Channel id */
- u8 state; /* Current channel state */
- s8 chnl_mode; /* Chnl mode and attributes */
- /* Chnl I/O completion event (user mode) */
- void *user_event;
- /* Abstract synchronization object */
- struct sync_object *sync_event;
- u32 process; /* Process which created this channel */
- u32 cb_arg; /* Argument to use with callback */
- struct list_head io_requests; /* List of IOR's to driver */
- s32 cio_cs; /* Number of IOC's in queue */
- s32 cio_reqs; /* Number of IORequests in queue */
- s32 chnl_packets; /* Initial number of free Irps */
- /* List of IOC's from driver */
- struct list_head io_completions;
- struct list_head free_packets_list; /* List of free Irps */
- struct ntfy_object *ntfy_obj;
- u32 bytes_moved; /* Total number of bytes transferred */
-
- /* For DSP-DMA */
-
- /* Type of chnl transport:CHNL_[PCPY][DDMA] */
- u32 chnl_type;
-};
-
-/* I/O Request/completion packet: */
-struct chnl_irp {
- struct list_head link; /* Link to next CHIRP in queue. */
- /* Buffer to be filled/emptied. (User) */
- u8 *host_user_buf;
- /* Buffer to be filled/emptied. (System) */
- u8 *host_sys_buf;
- u32 arg; /* Issue/Reclaim argument. */
- u32 dsp_tx_addr; /* Transfer address on DSP side. */
- u32 byte_size; /* Bytes transferred. */
- u32 buf_size; /* Actual buffer size when allocated. */
- u32 status; /* Status of IO completion. */
-};
-
-#endif /* _CHNL_SM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h b/drivers/staging/tidspbridge/include/dspbridge/brddefs.h
deleted file mode 100644
index 725d7b37414c..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * brddefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global BRD constants and types, shared between DSP API and Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef BRDDEFS_
-#define BRDDEFS_
-
-/* platform status values */
-#define BRD_STOPPED 0x0 /* No Monitor Loaded, Not running. */
-#define BRD_IDLE 0x1 /* Monitor Loaded, but suspended. */
-#define BRD_RUNNING 0x2 /* Monitor loaded, and executing. */
-#define BRD_UNKNOWN 0x3 /* Board state is indeterminate. */
-#define BRD_LOADED 0x5
-#define BRD_SLEEP_TRANSITION 0x6 /* Sleep transition in progress */
-#define BRD_HIBERNATION 0x7 /* MPU initiated hibernation */
-#define BRD_RETENTION 0x8 /* Retention mode */
-#define BRD_DSP_HIBERNATION 0x9 /* DSP initiated hibernation */
-#define BRD_ERROR 0xA /* Board state is Error */
-
-/* BRD Object */
-struct brd_object;
-
-#endif /* BRDDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
deleted file mode 100644
index b32c75673ab4..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * cfgdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global CFG constants and types, shared between DSP API and Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CFGDEFS_
-#define CFGDEFS_
-
-/* Host Resources: */
-#define CFG_MAXMEMREGISTERS 9
-
-/* IRQ flag */
-#define CFG_IRQSHARED 0x01 /* IRQ can be shared */
-
-/* A platform-related device handle: */
-struct cfg_devnode;
-
-/*
- * Host resource structure.
- */
-struct cfg_hostres {
- u32 num_mem_windows; /* Set to default */
- /* This is the base.memory */
- u32 mem_base[CFG_MAXMEMREGISTERS]; /* shm virtual address */
- u32 mem_length[CFG_MAXMEMREGISTERS]; /* Length of the Base */
- u32 mem_phys[CFG_MAXMEMREGISTERS]; /* shm Physical address */
- u8 birq_registers; /* IRQ Number */
- u8 birq_attrib; /* IRQ Attribute */
- u32 offset_for_monitor; /* The Shared memory starts from
- * mem_base + this offset */
- /*
- * Info needed by NODE for allocating channels to communicate with RMS:
- * chnl_offset: Offset of RMS channels. Lower channels are
- * reserved.
- * chnl_buf_size: Size of channel buffer to send to RMS
- * num_chnls: Total number of channels
- * (including reserved).
- */
- u32 chnl_offset;
- u32 chnl_buf_size;
- u32 num_chnls;
- void __iomem *per_base;
- void __iomem *per_pm_base;
- void __iomem *core_pm_base;
- void __iomem *dmmu_base;
-};
-
-#endif /* CFGDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnl.h b/drivers/staging/tidspbridge/include/dspbridge/chnl.h
deleted file mode 100644
index 9b018b1f9bf3..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/chnl.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * chnl.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP API channel interface: multiplexes data streams through the single
- * physical link managed by a Bridge driver.
- *
- * See DSP API chnl.h for more details.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CHNL_
-#define CHNL_
-
-#include <dspbridge/chnlpriv.h>
-
-/*
- * ======== chnl_create ========
- * Purpose:
- * Create a channel manager object, responsible for opening new channels
- * and closing old ones for a given board.
- * Parameters:
- * channel_mgr: Location to store a channel manager object on output.
- * hdev_obj: Handle to a device object.
- * mgr_attrts: Channel manager attributes.
- * mgr_attrts->max_channels: Max channels
- * mgr_attrts->birq: Channel's I/O IRQ number.
- * mgr_attrts->irq_shared: TRUE if the IRQ is shareable.
- * mgr_attrts->word_size: DSP Word size in equivalent PC bytes..
- * Returns:
- * 0: Success;
- * -EFAULT: hdev_obj is invalid.
- * -EINVAL: max_channels is 0.
- * Invalid DSP word size (must be > 0).
- * Invalid base address for DSP communications.
- * -ENOMEM: Insufficient memory for requested resources.
- * -EIO: Unable to plug channel ISR for configured IRQ.
- * -ECHRNG: This manager cannot handle this many channels.
- * -EEXIST: Channel manager already exists for this device.
- * Requires:
- * channel_mgr != NULL.
- * mgr_attrts != NULL.
- * Ensures:
- * 0: Subsequent calls to chnl_create() for the same
- * board without an intervening call to
- * chnl_destroy() will fail.
- */
-extern int chnl_create(struct chnl_mgr **channel_mgr,
- struct dev_object *hdev_obj,
- const struct chnl_mgrattrs *mgr_attrts);
-
-/*
- * ======== chnl_destroy ========
- * Purpose:
- * Close all open channels, and destroy the channel manager.
- * Parameters:
- * hchnl_mgr: Channel manager object.
- * Returns:
- * 0: Success.
- * -EFAULT: hchnl_mgr was invalid.
- * Requires:
- * Ensures:
- * 0: Cancels I/O on each open channel.
- * Closes each open channel.
- * chnl_create may subsequently be called for the
- * same board.
- */
-extern int chnl_destroy(struct chnl_mgr *hchnl_mgr);
-
-#endif /* CHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h
deleted file mode 100644
index cb67c309b6ca..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * chnldefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * System-wide channel objects and constants.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CHNLDEFS_
-#define CHNLDEFS_
-
-/* Channel id option. */
-#define CHNL_PICKFREE (~0UL) /* Let manager pick a free channel. */
-
-/* Channel modes */
-#define CHNL_MODETODSP 0 /* Data streaming to the DSP. */
-#define CHNL_MODEFROMDSP 1 /* Data streaming from the DSP. */
-
-/* GetIOCompletion flags */
-#define CHNL_IOCINFINITE 0xffffffff /* Wait forever for IO completion. */
-#define CHNL_IOCNOWAIT 0x0 /* Dequeue an IOC, if available. */
-
-/* IO Completion Record status: */
-#define CHNL_IOCSTATCOMPLETE 0x0000 /* IO Completed. */
-#define CHNL_IOCSTATCANCEL 0x0002 /* IO was cancelled */
-#define CHNL_IOCSTATTIMEOUT 0x0008 /* Wait for IOC timed out. */
-#define CHNL_IOCSTATEOS 0x8000 /* End Of Stream reached. */
-
-/* Macros for checking I/O Completion status: */
-#define CHNL_IS_IO_COMPLETE(ioc) (!(ioc.status & ~CHNL_IOCSTATEOS))
-#define CHNL_IS_IO_CANCELLED(ioc) (ioc.status & CHNL_IOCSTATCANCEL)
-#define CHNL_IS_TIMED_OUT(ioc) (ioc.status & CHNL_IOCSTATTIMEOUT)
-
-/* Channel attributes: */
-struct chnl_attr {
- u32 uio_reqs; /* Max # of preallocated I/O requests. */
- void *event_obj; /* User supplied auto-reset event object. */
- char *str_event_name; /* Ptr to name of user event object. */
- void *reserved1; /* Reserved for future use. */
- u32 reserved2; /* Reserved for future use. */
-
-};
-
-/* I/O completion record: */
-struct chnl_ioc {
- void *buf; /* Buffer to be filled/emptied. */
- u32 byte_size; /* Bytes transferred. */
- u32 buf_size; /* Actual buffer size in bytes */
- u32 status; /* Status of IO completion. */
- u32 arg; /* User argument associated with buf. */
-};
-
-#endif /* CHNLDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h
deleted file mode 100644
index 4114c79e2466..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * chnlpriv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private channel header shared between DSPSYS, DSPAPI and
- * Bridge driver modules.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CHNLPRIV_
-#define CHNLPRIV_
-
-#include <dspbridge/chnldefs.h>
-#include <dspbridge/devdefs.h>
-#include <dspbridge/sync.h>
-
-/* Channel manager limits: */
-#define CHNL_MAXCHANNELS 32 /* Max channels available per transport */
-
-/*
- * Trans port channel Id definitions:(must match dsp-side).
- *
- * For CHNL_MAXCHANNELS = 16:
- *
- * ChnlIds:
- * 0-15 (PCPY) - transport 0)
- * 16-31 (DDMA) - transport 1)
- * 32-47 (ZCPY) - transport 2)
- */
-#define CHNL_PCPY 0 /* Proc-copy transport 0 */
-
-/* Higher level channel states: */
-#define CHNL_STATEREADY 0 /* Channel ready for I/O. */
-#define CHNL_STATECANCEL 1 /* I/O was cancelled. */
-#define CHNL_STATEEOS 2 /* End Of Stream reached. */
-
-/* Macros for checking mode: */
-#define CHNL_IS_INPUT(mode) (mode & CHNL_MODEFROMDSP)
-#define CHNL_IS_OUTPUT(mode) (!CHNL_IS_INPUT(mode))
-
-/* Types of channel class libraries: */
-#define CHNL_TYPESM 1 /* Shared memory driver. */
-
-/* Channel info. */
-struct chnl_info {
- struct chnl_mgr *chnl_mgr; /* Owning channel manager. */
- u32 cnhl_id; /* Channel ID. */
- void *event_obj; /* Channel I/O completion event. */
- /*Abstraction of I/O completion event. */
- struct sync_object *sync_event;
- s8 mode; /* Channel mode. */
- u8 state; /* Current channel state. */
- u32 bytes_tx; /* Total bytes transferred. */
- u32 cio_cs; /* Number of IOCs in queue. */
- u32 cio_reqs; /* Number of IO Requests in queue. */
- u32 process; /* Process owning this channel. */
-};
-
-/* Channel manager info: */
-struct chnl_mgrinfo {
- u8 type; /* Type of channel class library. */
- /* Channel handle, given the channel id. */
- struct chnl_object *chnl_obj;
- u8 open_channels; /* Number of open channels. */
- u8 max_channels; /* total # of chnls supported */
-};
-
-/* Channel Manager Attrs: */
-struct chnl_mgrattrs {
- /* Max number of channels this manager can use. */
- u8 max_channels;
- u32 word_size; /* DSP Word size. */
-};
-
-#endif /* CHNLPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/clk.h b/drivers/staging/tidspbridge/include/dspbridge/clk.h
deleted file mode 100644
index 685341c50693..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/clk.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * clk.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Provides Clock functions.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _CLK_H
-#define _CLK_H
-
-enum dsp_clk_id {
- DSP_CLK_IVA2 = 0,
- DSP_CLK_GPT5,
- DSP_CLK_GPT6,
- DSP_CLK_GPT7,
- DSP_CLK_GPT8,
- DSP_CLK_WDT3,
- DSP_CLK_MCBSP1,
- DSP_CLK_MCBSP2,
- DSP_CLK_MCBSP3,
- DSP_CLK_MCBSP4,
- DSP_CLK_MCBSP5,
- DSP_CLK_SSI,
- DSP_CLK_NOT_DEFINED
-};
-
-/*
- * ======== dsp_clk_exit ========
- * Purpose:
- * Discontinue usage of module; free resources when reference count
- * reaches 0.
- * Parameters:
- * Returns:
- * Requires:
- * CLK initialized.
- * Ensures:
- * Resources used by module are freed when cRef reaches zero.
- */
-extern void dsp_clk_exit(void);
-
-/*
- * ======== dsp_clk_init ========
- * Purpose:
- * Initializes private state of CLK module.
- * Parameters:
- * Returns:
- * TRUE if initialized; FALSE if error occurred.
- * Requires:
- * Ensures:
- * CLK initialized.
- */
-extern void dsp_clk_init(void);
-
-void dsp_gpt_wait_overflow(short int clk_id, unsigned int load);
-
-/*
- * ======== dsp_clk_enable ========
- * Purpose:
- * Enables the clock requested.
- * Parameters:
- * Returns:
- * 0: Success.
- * -EPERM: Error occurred while enabling the clock.
- * Requires:
- * Ensures:
- */
-extern int dsp_clk_enable(enum dsp_clk_id clk_id);
-
-u32 dsp_clock_enable_all(u32 dsp_per_clocks);
-
-/*
- * ======== dsp_clk_disable ========
- * Purpose:
- * Disables the clock requested.
- * Parameters:
- * Returns:
- * 0: Success.
- * -EPERM: Error occurred while disabling the clock.
- * Requires:
- * Ensures:
- */
-extern int dsp_clk_disable(enum dsp_clk_id clk_id);
-
-extern u32 dsp_clk_get_iva2_rate(void);
-
-u32 dsp_clock_disable_all(u32 dsp_per_clocks);
-
-extern void ssi_clk_prepare(bool FLAG);
-
-#endif /* _SYNC_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmm.h b/drivers/staging/tidspbridge/include/dspbridge/cmm.h
deleted file mode 100644
index 2adf9ecdf07f..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/cmm.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * cmm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Communication Memory Management(CMM) module provides shared memory
- * management services for DSP/BIOS Bridge data streaming and messaging.
- * Multiple shared memory segments can be registered with CMM. Memory is
- * coelesced back to the appropriate pool when a buffer is freed.
- *
- * The CMM_Xlator[xxx] functions are used for node messaging and data
- * streaming address translation to perform zero-copy inter-processor
- * data transfer(GPP<->DSP). A "translator" object is created for a node or
- * stream object that contains per thread virtual address information. This
- * translator info is used at runtime to perform SM address translation
- * to/from the DSP address space.
- *
- * Notes:
- * cmm_xlator_alloc_buf - Used by Node and Stream modules for SM address
- * translation.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CMM_
-#define CMM_
-
-#include <dspbridge/devdefs.h>
-
-#include <dspbridge/cmmdefs.h>
-#include <dspbridge/host_os.h>
-
-/*
- * ======== cmm_calloc_buf ========
- * Purpose:
- * Allocate memory buffers that can be used for data streaming or
- * messaging.
- * Parameters:
- * hcmm_mgr: Cmm Mgr handle.
- * usize: Number of bytes to allocate.
- * pattr: Attributes of memory to allocate.
- * pp_buf_va: Address of where to place VA.
- * Returns:
- * Pointer to a zero'd block of SM memory;
- * NULL if memory couldn't be allocated,
- * or if byte_size == 0,
- * Requires:
- * Valid hcmm_mgr.
- * CMM initialized.
- * Ensures:
- * The returned pointer, if not NULL, points to a valid memory block of
- * the size requested.
- *
- */
-extern void *cmm_calloc_buf(struct cmm_object *hcmm_mgr,
- u32 usize, struct cmm_attrs *pattrs,
- void **pp_buf_va);
-
-/*
- * ======== cmm_create ========
- * Purpose:
- * Create a communication memory manager object.
- * Parameters:
- * ph_cmm_mgr: Location to store a communication manager handle on
- * output.
- * hdev_obj: Handle to a device object.
- * mgr_attrts: Comm mem manager attributes.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EPERM: Failed to initialize critical sect sync object.
- *
- * Requires:
- * ph_cmm_mgr != NULL.
- * mgr_attrts->min_block_size >= 4 bytes.
- * Ensures:
- *
- */
-extern int cmm_create(struct cmm_object **ph_cmm_mgr,
- struct dev_object *hdev_obj,
- const struct cmm_mgrattrs *mgr_attrts);
-
-/*
- * ======== cmm_destroy ========
- * Purpose:
- * Destroy the communication memory manager object.
- * Parameters:
- * hcmm_mgr: Cmm Mgr handle.
- * force: Force deallocation of all cmm memory immediately if set TRUE.
- * If FALSE, and outstanding allocations will return -EPERM
- * status.
- * Returns:
- * 0: CMM object & resources deleted.
- * -EPERM: Unable to free CMM object due to outstanding allocation.
- * -EFAULT: Unable to free CMM due to bad handle.
- * Requires:
- * CMM is initialized.
- * hcmm_mgr != NULL.
- * Ensures:
- * Memory resources used by Cmm Mgr are freed.
- */
-extern int cmm_destroy(struct cmm_object *hcmm_mgr, bool force);
-
-/*
- * ======== cmm_free_buf ========
- * Purpose:
- * Free the given buffer.
- * Parameters:
- * hcmm_mgr: Cmm Mgr handle.
- * pbuf: Pointer to memory allocated by cmm_calloc_buf().
- * ul_seg_id: SM segment Id used in CMM_Calloc() attrs.
- * Set to 0 to use default segment.
- * Returns:
- * 0
- * -EPERM
- * Requires:
- * CMM initialized.
- * buf_pa != NULL
- * Ensures:
- *
- */
-extern int cmm_free_buf(struct cmm_object *hcmm_mgr,
- void *buf_pa, u32 ul_seg_id);
-
-/*
- * ======== cmm_get_handle ========
- * Purpose:
- * Return the handle to the cmm mgr for the given device obj.
- * Parameters:
- * hprocessor: Handle to a Processor.
- * ph_cmm_mgr: Location to store the shared memory mgr handle on
- * output.
- *
- * Returns:
- * 0: Cmm Mgr opaque handle returned.
- * -EFAULT: Invalid handle.
- * Requires:
- * ph_cmm_mgr != NULL
- * hdev_obj != NULL
- * Ensures:
- */
-extern int cmm_get_handle(void *hprocessor,
- struct cmm_object **ph_cmm_mgr);
-
-/*
- * ======== cmm_get_info ========
- * Purpose:
- * Return the current SM and VM utilization information.
- * Parameters:
- * hcmm_mgr: Handle to a Cmm Mgr.
- * cmm_info_obj: Location to store the Cmm information on output.
- *
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid handle.
- * -EINVAL Invalid input argument.
- * Requires:
- * Ensures:
- *
- */
-extern int cmm_get_info(struct cmm_object *hcmm_mgr,
- struct cmm_info *cmm_info_obj);
-
-/*
- * ======== cmm_register_gppsm_seg ========
- * Purpose:
- * Register a block of SM with the CMM.
- * Parameters:
- * hcmm_mgr: Handle to a Cmm Mgr.
- * lpGPPBasePA: GPP Base Physical address.
- * ul_size: Size in GPP bytes.
- * dsp_addr_offset GPP PA to DSP PA Offset.
- * c_factor: Add offset if CMM_ADDTODSPPA, sub if CMM_SUBFROMDSPPA.
- * dw_dsp_base: DSP virtual base byte address.
- * ul_dsp_size: Size of DSP segment in bytes.
- * sgmt_id: Address to store segment Id.
- *
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hcmm_mgr handle.
- * -EINVAL: Invalid input argument.
- * -EPERM: Unable to register.
- * - On success *sgmt_id is a valid SM segment ID.
- * Requires:
- * ul_size > 0
- * sgmt_id != NULL
- * dw_gpp_base_pa != 0
- * c_factor = CMM_ADDTODSPPA || c_factor = CMM_SUBFROMDSPPA
- * Ensures:
- *
- */
-extern int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
- unsigned int dw_gpp_base_pa,
- u32 ul_size,
- u32 dsp_addr_offset,
- s8 c_factor,
- unsigned int dw_dsp_base,
- u32 ul_dsp_size,
- u32 *sgmt_id, u32 gpp_base_va);
-
-/*
- * ======== cmm_un_register_gppsm_seg ========
- * Purpose:
- * Unregister the given memory segment that was previously registered
- * by cmm_register_gppsm_seg.
- * Parameters:
- * hcmm_mgr: Handle to a Cmm Mgr.
- * ul_seg_id Segment identifier returned by cmm_register_gppsm_seg.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid handle.
- * -EINVAL: Invalid ul_seg_id.
- * -EPERM: Unable to unregister for unknown reason.
- * Requires:
- * Ensures:
- *
- */
-extern int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
- u32 ul_seg_id);
-
-/*
- * ======== cmm_xlator_alloc_buf ========
- * Purpose:
- * Allocate the specified SM buffer and create a local memory descriptor.
- * Place on the descriptor on the translator's HaQ (Host Alloc'd Queue).
- * Parameters:
- * xlator: Handle to a Xlator object.
- * va_buf: Virtual address ptr(client context)
- * pa_size: Size of SM memory to allocate.
- * Returns:
- * Ptr to valid physical address(Pa) of pa_size bytes, NULL if failed.
- * Requires:
- * va_buf != 0.
- * pa_size != 0.
- * Ensures:
- *
- */
-extern void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator,
- void *va_buf, u32 pa_size);
-
-/*
- * ======== cmm_xlator_create ========
- * Purpose:
- * Create a translator(xlator) object used for process specific Va<->Pa
- * address translation. Node messaging and streams use this to perform
- * inter-processor(GPP<->DSP) zero-copy data transfer.
- * Parameters:
- * xlator: Address to place handle to a new Xlator handle.
- * hcmm_mgr: Handle to Cmm Mgr associated with this translator.
- * xlator_attrs: Translator attributes used for the client NODE or STREAM.
- * Returns:
- * 0: Success.
- * -EINVAL: Bad input Attrs.
- * -ENOMEM: Insufficient memory(local) for requested resources.
- * Requires:
- * xlator != NULL
- * hcmm_mgr != NULL
- * xlator_attrs != NULL
- * Ensures:
- *
- */
-extern int cmm_xlator_create(struct cmm_xlatorobject **xlator,
- struct cmm_object *hcmm_mgr,
- struct cmm_xlatorattrs *xlator_attrs);
-
-/*
- * ======== cmm_xlator_free_buf ========
- * Purpose:
- * Free SM buffer and descriptor.
- * Does not free client process VM.
- * Parameters:
- * xlator: handle to translator.
- * buf_va Virtual address of PA to free.
- * Returns:
- * 0: Success.
- * -EFAULT: Bad translator handle.
- * Requires:
- * Ensures:
- *
- */
-extern int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator,
- void *buf_va);
-
-/*
- * ======== cmm_xlator_info ========
- * Purpose:
- * Set/Get process specific "translator" address info.
- * This is used to perform fast virtual address translation
- * for shared memory buffers between the GPP and DSP.
- * Parameters:
- * xlator: handle to translator.
- * paddr: Virtual base address of segment.
- * ul_size: Size in bytes.
- * segm_id: Segment identifier of SM segment(s)
- * set_info Set xlator fields if TRUE, else return base addr
- * Returns:
- * 0: Success.
- * -EFAULT: Bad translator handle.
- * Requires:
- * (paddr != NULL)
- * (ul_size > 0)
- * Ensures:
- *
- */
-extern int cmm_xlator_info(struct cmm_xlatorobject *xlator,
- u8 **paddr,
- u32 ul_size, u32 segm_id, bool set_info);
-
-/*
- * ======== cmm_xlator_translate ========
- * Purpose:
- * Perform address translation VA<->PA for the specified stream or
- * message shared memory buffer.
- * Parameters:
- * xlator: handle to translator.
- * paddr address of buffer to translate.
- * xtype Type of address xlation. CMM_PA2VA or CMM_VA2PA.
- * Returns:
- * Valid address on success, else NULL.
- * Requires:
- * paddr != NULL
- * xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA)
- * Ensures:
- *
- */
-extern void *cmm_xlator_translate(struct cmm_xlatorobject *xlator,
- void *paddr, enum cmm_xlatetype xtype);
-
-#endif /* CMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h
deleted file mode 100644
index a264fa69a4fc..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * cmmdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global MEM constants and types.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CMMDEFS_
-#define CMMDEFS_
-
-
-/* Cmm attributes used in cmm_create() */
-struct cmm_mgrattrs {
- /* Minimum SM allocation; default 32 bytes. */
- u32 min_block_size;
-};
-
-/* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */
-struct cmm_attrs {
- u32 seg_id; /* 1,2... are SM segments. 0 is not. */
- u32 alignment; /* 0,1,2,4....min_block_size */
-};
-
-/*
- * DSPPa to GPPPa Conversion Factor.
- *
- * For typical platforms:
- * converted Address = PaDSP + ( c_factor * addressToConvert).
- */
-#define CMM_SUBFROMDSPPA -1
-#define CMM_ADDTODSPPA 1
-
-#define CMM_ALLSEGMENTS 0xFFFFFF /* All SegIds */
-#define CMM_MAXGPPSEGS 1 /* Maximum # of SM segs */
-
-/*
- * SMSEGs are SM segments the DSP allocates from.
- *
- * This info is used by the GPP to xlate DSP allocated PAs.
- */
-
-struct cmm_seginfo {
- u32 seg_base_pa; /* Start Phys address of SM segment */
- /* Total size in bytes of segment: DSP+GPP */
- u32 total_seg_size;
- u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */
- u32 gpp_size; /* Size of Gpp SM seg in bytes */
- u32 dsp_base_va; /* DSP virt base byte address */
- u32 dsp_size; /* DSP seg size in bytes */
- /* # of current GPP allocations from this segment */
- u32 in_use_cnt;
- u32 seg_base_va; /* Start Virt address of SM seg */
-
-};
-
-/* CMM useful information */
-struct cmm_info {
- /* # of SM segments registered with this Cmm. */
- u32 num_gppsm_segs;
- /* Total # of allocations outstanding for CMM */
- u32 total_in_use_cnt;
- /* Min SM block size allocation from cmm_create() */
- u32 min_block_size;
- /* Info per registered SM segment. */
- struct cmm_seginfo seg_info[CMM_MAXGPPSEGS];
-};
-
-/* XlatorCreate attributes */
-struct cmm_xlatorattrs {
- u32 seg_id; /* segment Id used for SM allocations */
- u32 dsp_bufs; /* # of DSP-side bufs */
- u32 dsp_buf_size; /* size of DSP-side bufs in GPP bytes */
- /* Vm base address alloc'd in client process context */
- void *vm_base;
- /* vm_size must be >= (dwMaxNumBufs * dwMaxSize) */
- u32 vm_size;
-};
-
-/*
- * Cmm translation types. Use to map SM addresses to process context.
- */
-enum cmm_xlatetype {
- CMM_VA2PA = 0, /* Virtual to GPP physical address xlation */
- CMM_PA2VA = 1, /* GPP Physical to virtual */
- CMM_VA2DSPPA = 2, /* Va to DSP Pa */
- CMM_PA2DSPPA = 3, /* GPP Pa to DSP Pa */
- CMM_DSPPA2PA = 4, /* DSP Pa to GPP Pa */
-};
-
-struct cmm_object;
-struct cmm_xlatorobject;
-
-#endif /* CMMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h
deleted file mode 100644
index ba2005d02422..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/cod.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * cod.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Code management module for DSPs. This module provides an interface
- * interface for loading both static and dynamic code objects onto DSP
- * systems.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef COD_
-#define COD_
-
-#include <dspbridge/dblldefs.h>
-
-#define COD_MAXPATHLENGTH 255
-#define COD_TRACEBEG "SYS_PUTCBEG"
-#define COD_TRACEEND "SYS_PUTCEND"
-#define COD_TRACECURPOS "BRIDGE_SYS_PUTC_current"
-
-#define COD_NOLOAD DBLL_NOLOAD
-#define COD_SYMB DBLL_SYMB
-
-/* COD code manager handle */
-struct cod_manager;
-
-/* COD library handle */
-struct cod_libraryobj;
-
-/*
- * Function prototypes for writing memory to a DSP system, allocating
- * and freeing DSP memory.
- */
-typedef u32(*cod_writefxn) (void *priv_ref, u32 dsp_add,
- void *pbuf, u32 ul_num_bytes, u32 mem_space);
-
-/*
- * ======== cod_close ========
- * Purpose:
- * Close a library opened with cod_open().
- * Parameters:
- * lib - Library handle returned by cod_open().
- * Returns:
- * None.
- * Requires:
- * COD module initialized.
- * valid lib.
- * Ensures:
- *
- */
-extern void cod_close(struct cod_libraryobj *lib);
-
-/*
- * ======== cod_create ========
- * Purpose:
- * Create an object to manage code on a DSP system. This object can be
- * used to load an initial program image with arguments that can later
- * be expanded with dynamically loaded object files.
- * Symbol table information is managed by this object and can be retrieved
- * using the cod_get_sym_value() function.
- * Parameters:
- * manager: created manager object
- * str_zl_file: ZL DLL filename, of length < COD_MAXPATHLENGTH.
- * Returns:
- * 0: Success.
- * -ESPIPE: ZL_Create failed.
- * -ENOSYS: attrs was not NULL. We don't yet support
- * non default values of attrs.
- * Requires:
- * COD module initialized.
- * str_zl_file != NULL
- * Ensures:
- */
-extern int cod_create(struct cod_manager **mgr,
- char *str_zl_file);
-
-/*
- * ======== cod_delete ========
- * Purpose:
- * Delete a code manager object.
- * Parameters:
- * cod_mgr_obj: handle of manager to be deleted
- * Returns:
- * None.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * Ensures:
- */
-extern void cod_delete(struct cod_manager *cod_mgr_obj);
-
-/*
- * ======== cod_get_base_lib ========
- * Purpose:
- * Get handle to the base image DBL library.
- * Parameters:
- * cod_mgr_obj: handle of manager to be deleted
- * plib: location to store library handle on output.
- * Returns:
- * 0: Success.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * plib != NULL.
- * Ensures:
- */
-extern int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
- struct dbll_library_obj **plib);
-
-/*
- * ======== cod_get_base_name ========
- * Purpose:
- * Get the name of the base image DBL library.
- * Parameters:
- * cod_mgr_obj: handle of manager to be deleted
- * sz_name: location to store library name on output.
- * usize: size of name buffer.
- * Returns:
- * 0: Success.
- * -EPERM: Buffer too small.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * sz_name != NULL.
- * Ensures:
- */
-extern int cod_get_base_name(struct cod_manager *cod_mgr_obj,
- char *sz_name, u32 usize);
-
-/*
- * ======== cod_get_entry ========
- * Purpose:
- * Retrieve the entry point of a loaded DSP program image
- * Parameters:
- * cod_mgr_obj: handle of manager to be deleted
- * entry_pt: pointer to location for entry point
- * Returns:
- * 0: Success.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * entry_pt != NULL.
- * Ensures:
- */
-extern int cod_get_entry(struct cod_manager *cod_mgr_obj,
- u32 *entry_pt);
-
-/*
- * ======== cod_get_loader ========
- * Purpose:
- * Get handle to the DBL loader.
- * Parameters:
- * cod_mgr_obj: handle of manager to be deleted
- * loader: location to store loader handle on output.
- * Returns:
- * 0: Success.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * loader != NULL.
- * Ensures:
- */
-extern int cod_get_loader(struct cod_manager *cod_mgr_obj,
- struct dbll_tar_obj **loader);
-
-/*
- * ======== cod_get_section ========
- * Purpose:
- * Retrieve the starting address and length of a section in the COFF file
- * given the section name.
- * Parameters:
- * lib Library handle returned from cod_open().
- * str_sect: name of the section, with or without leading "."
- * addr: Location to store address.
- * len: Location to store length.
- * Returns:
- * 0: Success
- * -ESPIPE: Symbols could not be found or have not been loaded onto
- * the board.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * str_sect != NULL;
- * addr != NULL;
- * len != NULL;
- * Ensures:
- * 0: *addr and *len contain the address and length of the
- * section.
- * else: *addr == 0 and *len == 0;
- *
- */
-extern int cod_get_section(struct cod_libraryobj *lib,
- char *str_sect,
- u32 *addr, u32 *len);
-
-/*
- * ======== cod_get_sym_value ========
- * Purpose:
- * Retrieve the value for the specified symbol. The symbol is first
- * searched for literally and then, if not found, searched for as a
- * C symbol.
- * Parameters:
- * lib: library handle returned from cod_open().
- * pstrSymbol: name of the symbol
- * value: value of the symbol
- * Returns:
- * 0: Success.
- * -ESPIPE: Symbols could not be found or have not been loaded onto
- * the board.
- * Requires:
- * COD module initialized.
- * Valid cod_mgr_obj.
- * str_sym != NULL.
- * pul_value != NULL.
- * Ensures:
- */
-extern int cod_get_sym_value(struct cod_manager *cod_mgr_obj,
- char *str_sym, u32 * pul_value);
-
-/*
- * ======== cod_load_base ========
- * Purpose:
- * Load the initial program image, optionally with command-line arguments,
- * on the DSP system managed by the supplied handle. The program to be
- * loaded must be the first element of the args array and must be a fully
- * qualified pathname.
- * Parameters:
- * hmgr: manager to load the code with
- * num_argc: number of arguments in the args array
- * args: array of strings for arguments to DSP program
- * write_fxn: board-specific function to write data to DSP system
- * arb: arbitrary pointer to be passed as first arg to write_fxn
- * envp: array of environment strings for DSP exec.
- * Returns:
- * 0: Success.
- * -EBADF: Failed to open target code.
- * Requires:
- * COD module initialized.
- * hmgr is valid.
- * num_argc > 0.
- * args != NULL.
- * args[0] != NULL.
- * pfn_write != NULL.
- * Ensures:
- */
-extern int cod_load_base(struct cod_manager *cod_mgr_obj,
- u32 num_argc, char *args[],
- cod_writefxn pfn_write, void *arb,
- char *envp[]);
-
-/*
- * ======== cod_open ========
- * Purpose:
- * Open a library for reading sections. Does not load or set the base.
- * Parameters:
- * hmgr: manager to load the code with
- * sz_coff_path: Coff file to open.
- * flags: COD_NOLOAD (don't load symbols) or COD_SYMB (load
- * symbols).
- * lib_obj: Handle returned that can be used in calls to cod_close
- * and cod_get_section.
- * Returns:
- * S_OK: Success.
- * -EBADF: Failed to open target code.
- * Requires:
- * COD module initialized.
- * hmgr is valid.
- * flags == COD_NOLOAD || flags == COD_SYMB.
- * sz_coff_path != NULL.
- * Ensures:
- */
-extern int cod_open(struct cod_manager *hmgr,
- char *sz_coff_path,
- u32 flags, struct cod_libraryobj **lib_obj);
-
-/*
- * ======== cod_open_base ========
- * Purpose:
- * Open base image for reading sections. Does not load the base.
- * Parameters:
- * hmgr: manager to load the code with
- * sz_coff_path: Coff file to open.
- * flags: Specifies whether to load symbols.
- * Returns:
- * 0: Success.
- * -EBADF: Failed to open target code.
- * Requires:
- * COD module initialized.
- * hmgr is valid.
- * sz_coff_path != NULL.
- * Ensures:
- */
-extern int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
- dbll_flags flags);
-
-/*
- * ======== cod_read_section ========
- * Purpose:
- * Retrieve the content of a code section given the section name.
- * Parameters:
- * cod_mgr_obj - manager in which to search for the symbol
- * str_sect - name of the section, with or without leading "."
- * str_content - buffer to store content of the section.
- * Returns:
- * 0: on success, error code on failure
- * -ESPIPE: Symbols have not been loaded onto the board.
- * Requires:
- * COD module initialized.
- * valid cod_mgr_obj.
- * str_sect != NULL;
- * str_content != NULL;
- * Ensures:
- * 0: *str_content stores the content of the named section.
- */
-extern int cod_read_section(struct cod_libraryobj *lib,
- char *str_sect,
- char *str_content, u32 content_size);
-
-#endif /* COD_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h
deleted file mode 100644
index 7cc3e12686e8..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dbdcd.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * dbdcd.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Defines the DSP/BIOS Bridge Configuration Database (DCD) API.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBDCD_
-#define DBDCD_
-
-#include <dspbridge/dbdcddef.h>
-#include <dspbridge/host_os.h>
-#include <dspbridge/nldrdefs.h>
-
-/*
- * ======== dcd_auto_register ========
- * Purpose:
- * This function automatically registers DCD objects specified in a
- * special COFF section called ".dcd_register"
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * sz_coff_path: Pointer to name of COFF file containing DCD
- * objects to be registered.
- * Returns:
- * 0: Success.
- * -EACCES: Unable to find auto-registration/read/load section.
- * -EFAULT: Invalid DCD_HMANAGER handle..
- * Requires:
- * DCD initialized.
- * Ensures:
- * Note:
- * Due to the DCD database construction, it is essential for a DCD-enabled
- * COFF file to contain the right COFF sections, especially
- * ".dcd_register", which is used for auto registration.
- */
-extern int dcd_auto_register(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path);
-
-/*
- * ======== dcd_auto_unregister ========
- * Purpose:
- * This function automatically unregisters DCD objects specified in a
- * special COFF section called ".dcd_register"
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * sz_coff_path: Pointer to name of COFF file containing
- * DCD objects to be unregistered.
- * Returns:
- * 0: Success.
- * -EACCES: Unable to find auto-registration/read/load section.
- * -EFAULT: Invalid DCD_HMANAGER handle..
- * Requires:
- * DCD initialized.
- * Ensures:
- * Note:
- * Due to the DCD database construction, it is essential for a DCD-enabled
- * COFF file to contain the right COFF sections, especially
- * ".dcd_register", which is used for auto unregistration.
- */
-extern int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path);
-
-/*
- * ======== dcd_create_manager ========
- * Purpose:
- * This function creates a DCD module manager.
- * Parameters:
- * sz_zl_dll_name: Pointer to a DLL name string.
- * dcd_mgr: A pointer to a DCD manager handle.
- * Returns:
- * 0: Success.
- * -ENOMEM: Unable to allocate memory for DCD manager handle.
- * -EPERM: General failure.
- * Requires:
- * DCD initialized.
- * sz_zl_dll_name is non-NULL.
- * dcd_mgr is non-NULL.
- * Ensures:
- * A DCD manager handle is created.
- */
-extern int dcd_create_manager(char *sz_zl_dll_name,
- struct dcd_manager **dcd_mgr);
-
-/*
- * ======== dcd_destroy_manager ========
- * Purpose:
- * This function destroys a DCD module manager.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid DCD manager handle.
- * Requires:
- * DCD initialized.
- * Ensures:
- */
-extern int dcd_destroy_manager(struct dcd_manager *hdcd_mgr);
-
-/*
- * ======== dcd_enumerate_object ========
- * Purpose:
- * This function enumerates currently visible DSP/BIOS Bridge objects
- * and returns the UUID and type of each enumerated object.
- * Parameters:
- * index: The object enumeration index.
- * obj_type: Type of object to enumerate.
- * uuid_obj: Pointer to a dsp_uuid object.
- * Returns:
- * 0: Success.
- * -EPERM: Unable to enumerate through the DCD database.
- * ENODATA: Enumeration completed. This is not an error code.
- * Requires:
- * DCD initialized.
- * uuid_obj is a valid pointer.
- * Ensures:
- * Details:
- * This function can be used in conjunction with dcd_get_object_def to
- * retrieve object properties.
- */
-extern int dcd_enumerate_object(s32 index,
- enum dsp_dcdobjtype obj_type,
- struct dsp_uuid *uuid_obj);
-
-/*
- * ======== dcd_exit ========
- * Purpose:
- * This function cleans up the DCD module.
- * Parameters:
- * Returns:
- * Requires:
- * DCD initialized.
- * Ensures:
- */
-extern void dcd_exit(void);
-
-/*
- * ======== dcd_get_dep_libs ========
- * Purpose:
- * Given the uuid of a library and size of array of uuids, this function
- * fills the array with the uuids of all dependent libraries of the input
- * library.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * uuid_obj: Pointer to a dsp_uuid for a library.
- * num_libs: Size of uuid array (number of library uuids).
- * dep_lib_uuids: Array of dependent library uuids to be filled in.
- * prstnt_dep_libs: Array indicating if corresponding lib is persistent.
- * phase: phase to obtain correct input library
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failure.
- * -EACCES: Failure to read section containing library info.
- * -EPERM: General failure.
- * Requires:
- * DCD initialized.
- * Valid hdcd_mgr.
- * uuid_obj != NULL
- * dep_lib_uuids != NULL.
- * Ensures:
- */
-extern int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 num_libs,
- struct dsp_uuid *dep_lib_uuids,
- bool *prstnt_dep_libs,
- enum nldr_phase phase);
-
-/*
- * ======== dcd_get_num_dep_libs ========
- * Purpose:
- * Given the uuid of a library, determine its number of dependent
- * libraries.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * uuid_obj: Pointer to a dsp_uuid for a library.
- * num_libs: Size of uuid array (number of library uuids).
- * num_pers_libs: number of persistent dependent library.
- * phase: Phase to obtain correct input library
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failure.
- * -EACCES: Failure to read section containing library info.
- * -EPERM: General failure.
- * Requires:
- * DCD initialized.
- * Valid hdcd_mgr.
- * uuid_obj != NULL
- * num_libs != NULL.
- * Ensures:
- */
-extern int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 *num_libs,
- u16 *num_pers_libs,
- enum nldr_phase phase);
-
-/*
- * ======== dcd_get_library_name ========
- * Purpose:
- * This function returns the name of a (dynamic) library for a given
- * UUID.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * uuid_obj: Pointer to a dsp_uuid that represents a unique DSP/BIOS
- * Bridge object.
- * str_lib_name: Buffer to hold library name.
- * buff_size: Contains buffer size. Set to string size on output.
- * phase: Which phase to load
- * phase_split: Are phases in multiple libraries
- * Returns:
- * 0: Success.
- * -EPERM: General failure.
- * Requires:
- * DCD initialized.
- * Valid hdcd_mgr.
- * str_lib_name != NULL.
- * uuid_obj != NULL
- * buff_size != NULL.
- * Ensures:
- */
-extern int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- char *str_lib_name,
- u32 *buff_size,
- enum nldr_phase phase,
- bool *phase_split);
-
-/*
- * ======== dcd_get_object_def ========
- * Purpose:
- * This function returns the properties/attributes of a DSP/BIOS Bridge
- * object.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * uuid_obj: Pointer to a dsp_uuid that represents a unique
- * DSP/BIOS Bridge object.
- * obj_type: The type of DSP/BIOS Bridge object to be
- * referenced (node, processor, etc).
- * obj_def: Pointer to an object definition structure. A
- * union of various possible DCD object types.
- * Returns:
- * 0: Success.
- * -EACCES: Unable to access/read/parse/load content of object code
- * section.
- * -EPERM: General failure.
- * -EFAULT: Invalid DCD_HMANAGER handle.
- * Requires:
- * DCD initialized.
- * obj_uuid is non-NULL.
- * obj_def is non-NULL.
- * Ensures:
- */
-extern int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *obj_uuid,
- enum dsp_dcdobjtype obj_type,
- struct dcd_genericobj *obj_def);
-
-/*
- * ======== dcd_get_objects ========
- * Purpose:
- * This function finds all DCD objects specified in a special
- * COFF section called ".dcd_register", and for each object,
- * call a "register" function. The "register" function may perform
- * various actions, such as 1) register nodes in the node database, 2)
- * unregister nodes from the node database, and 3) add overlay nodes.
- * Parameters:
- * hdcd_mgr: A DCD manager handle.
- * sz_coff_path: Pointer to name of COFF file containing DCD
- * objects.
- * register_fxn: Callback fxn to be applied on each located
- * DCD object.
- * handle: Handle to pass to callback.
- * Returns:
- * 0: Success.
- * -EACCES: Unable to access/read/parse/load content of object code
- * section.
- * -EFAULT: Invalid DCD_HMANAGER handle..
- * Requires:
- * DCD initialized.
- * Ensures:
- * Note:
- * Due to the DCD database construction, it is essential for a DCD-enabled
- * COFF file to contain the right COFF sections, especially
- * ".dcd_register", which is used for auto registration.
- */
-extern int dcd_get_objects(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path,
- dcd_registerfxn register_fxn, void *handle);
-
-/*
- * ======== dcd_init ========
- * Purpose:
- * This function initializes DCD.
- * Parameters:
- * Returns:
- * FALSE: Initialization failed.
- * TRUE: Initialization succeeded.
- * Requires:
- * Ensures:
- * DCD initialized.
- */
-extern bool dcd_init(void);
-
-/*
- * ======== dcd_register_object ========
- * Purpose:
- * This function registers a DSP/BIOS Bridge object in the DCD database.
- * Parameters:
- * uuid_obj: Pointer to a dsp_uuid that identifies a DSP/BIOS
- * Bridge object.
- * obj_type: Type of object.
- * psz_path_name: Path to the object's COFF file.
- * Returns:
- * 0: Success.
- * -EPERM: Failed to register object.
- * Requires:
- * DCD initialized.
- * uuid_obj and szPathName are non-NULL values.
- * obj_type is a valid type value.
- * Ensures:
- */
-extern int dcd_register_object(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type,
- char *psz_path_name);
-
-/*
- * ======== dcd_unregister_object ========
- * Purpose:
- * This function de-registers a valid DSP/BIOS Bridge object from the DCD
- * database.
- * Parameters:
- * uuid_obj: Pointer to a dsp_uuid that identifies a DSP/BIOS Bridge
- * object.
- * obj_type: Type of object.
- * Returns:
- * 0: Success.
- * -EPERM: Unable to de-register the specified object.
- * Requires:
- * DCD initialized.
- * uuid_obj is a non-NULL value.
- * obj_type is a valid type value.
- * Ensures:
- */
-extern int dcd_unregister_object(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type);
-
-#endif /* _DBDCD_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h
deleted file mode 100644
index bc201b329033..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * dbdcddef.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DCD (DSP/BIOS Bridge Configuration Database) constants and types.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBDCDDEF_
-#define DBDCDDEF_
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/mgrpriv.h> /* for mgr_processorextinfo */
-
-/*
- * The following defines are critical elements for the DCD module:
- *
- * - DCD_REGKEY enables DCD functions to locate registered DCD objects.
- * - DCD_REGISTER_SECTION identifies the COFF section where the UUID of
- * registered DCD objects are stored.
- */
-#define DCD_REGKEY "Software\\TexasInstruments\\DspBridge\\DCD"
-#define DCD_REGISTER_SECTION ".dcd_register"
-
-#define DCD_MAXPATHLENGTH 255
-
-/* DCD Manager Object */
-struct dcd_manager;
-
-struct dcd_key_elem {
- struct list_head link; /* Make it linked to a list */
- char name[DCD_MAXPATHLENGTH]; /* Name of a given value entry */
- char *path; /* Pointer to the actual data */
-};
-
-/* DCD Node Properties */
-struct dcd_nodeprops {
- struct dsp_ndbprops ndb_props;
- u32 msg_segid;
- u32 msg_notify_type;
- char *str_create_phase_fxn;
- char *str_delete_phase_fxn;
- char *str_execute_phase_fxn;
- char *str_i_alg_name;
-
- /* Dynamic load properties */
- u16 load_type; /* Static, dynamic, overlay */
- u32 data_mem_seg_mask; /* Data memory requirements */
- u32 code_mem_seg_mask; /* Code memory requirements */
-};
-
-/* DCD Generic Object Type */
-struct dcd_genericobj {
- union dcd_obj {
- struct dcd_nodeprops node_obj; /* node object. */
- /* processor object. */
- struct dsp_processorinfo proc_info;
- /* extended proc object (private) */
- struct mgr_processorextinfo ext_proc_obj;
- } obj_data;
-};
-
-/* DCD Internal Callback Type */
-typedef int(*dcd_registerfxn) (struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type,
- void *handle);
-
-#endif /* DBDCDDEF_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h
deleted file mode 100644
index c8f464505efc..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * dbdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global definitions and constants for DSP/BIOS Bridge.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBDEFS_
-#define DBDEFS_
-
-#include <linux/types.h>
-
-#include <dspbridge/rms_sh.h> /* Types shared between GPP and DSP */
-
-#define PG_SIZE4K 4096
-#define PG_MASK(pg_size) (~((pg_size)-1))
-#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size))
-#define PG_ALIGN_HIGH(addr, pg_size) (((addr)+(pg_size)-1) & PG_MASK(pg_size))
-
-/* API return value and calling convention */
-#define DBAPI int
-
-/* Maximum length of node name, used in dsp_ndbprops */
-#define DSP_MAXNAMELEN 32
-
-/* notify_type values for the RegisterNotify() functions. */
-#define DSP_SIGNALEVENT 0x00000001
-
-/* Types of events for processors */
-#define DSP_PROCESSORSTATECHANGE 0x00000001
-#define DSP_PROCESSORATTACH 0x00000002
-#define DSP_PROCESSORDETACH 0x00000004
-#define DSP_PROCESSORRESTART 0x00000008
-
-/* DSP exception events (DSP/BIOS and DSP MMU fault) */
-#define DSP_MMUFAULT 0x00000010
-#define DSP_SYSERROR 0x00000020
-#define DSP_EXCEPTIONABORT 0x00000300
-#define DSP_PWRERROR 0x00000080
-#define DSP_WDTOVERFLOW 0x00000040
-
-/* IVA exception events (IVA MMU fault) */
-#define IVA_MMUFAULT 0x00000040
-/* Types of events for nodes */
-#define DSP_NODESTATECHANGE 0x00000100
-#define DSP_NODEMESSAGEREADY 0x00000200
-
-/* Types of events for streams */
-#define DSP_STREAMDONE 0x00001000
-#define DSP_STREAMIOCOMPLETION 0x00002000
-
-/* Handle definition representing the GPP node in DSPNode_Connect() calls */
-#define DSP_HGPPNODE 0xFFFFFFFF
-
-/* Node directions used in DSPNode_Connect() */
-#define DSP_TONODE 1
-#define DSP_FROMNODE 2
-
-/* Define Node Minimum and Maximum Priorities */
-#define DSP_NODE_MIN_PRIORITY 1
-#define DSP_NODE_MAX_PRIORITY 15
-
-/* msg_ctrl contains SM buffer description */
-#define DSP_RMSBUFDESC RMS_BUFDESC
-
-/* Processor ID numbers */
-#define DSP_UNIT 0
-#define IVA_UNIT 1
-
-#define DSPWORD unsigned char
-#define DSPWORDSIZE sizeof(DSPWORD)
-
-#define MAX_PROFILES 16
-
-/* DSP chip type */
-#define DSPTYPE64 0x99
-
-/* Handy Macros */
-#define VALID_PROC_EVENT (DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH | \
- DSP_PROCESSORDETACH | DSP_PROCESSORRESTART | DSP_NODESTATECHANGE | \
- DSP_STREAMDONE | DSP_STREAMIOCOMPLETION | DSP_MMUFAULT | \
- DSP_SYSERROR | DSP_WDTOVERFLOW | DSP_PWRERROR)
-
-static inline bool is_valid_proc_event(u32 x)
-{
- return (x == 0 || (x & VALID_PROC_EVENT && !(x & ~VALID_PROC_EVENT)));
-}
-
-/* The Node UUID structure */
-struct dsp_uuid {
- u32 data1;
- u16 data2;
- u16 data3;
- u8 data4;
- u8 data5;
- u8 data6[6];
-};
-
-/* DCD types */
-enum dsp_dcdobjtype {
- DSP_DCDNODETYPE,
- DSP_DCDPROCESSORTYPE,
- DSP_DCDLIBRARYTYPE,
- DSP_DCDCREATELIBTYPE,
- DSP_DCDEXECUTELIBTYPE,
- DSP_DCDDELETELIBTYPE,
- /* DSP_DCDMAXOBJTYPE is meant to be the last DCD object type */
- DSP_DCDMAXOBJTYPE
-};
-
-/* Processor states */
-enum dsp_procstate {
- PROC_STOPPED,
- PROC_LOADED,
- PROC_RUNNING,
- PROC_ERROR
-};
-
-/*
- * Node types: Message node, task node, xDAIS socket node, and
- * device node. _NODE_GPP is used when defining a stream connection
- * between a task or socket node and the GPP.
- *
- */
-enum node_type {
- NODE_DEVICE,
- NODE_TASK,
- NODE_DAISSOCKET,
- NODE_MESSAGE,
- NODE_GPP
-};
-
-/*
- * ======== node_state ========
- * Internal node states.
- */
-enum node_state {
- NODE_ALLOCATED,
- NODE_CREATED,
- NODE_RUNNING,
- NODE_PAUSED,
- NODE_DONE,
- NODE_CREATING,
- NODE_STARTING,
- NODE_PAUSING,
- NODE_TERMINATING,
- NODE_DELETING,
-};
-
-/* Stream states */
-enum dsp_streamstate {
- STREAM_IDLE,
- STREAM_READY,
- STREAM_PENDING,
- STREAM_DONE
-};
-
-/* Stream connect types */
-enum dsp_connecttype {
- CONNECTTYPE_NODEOUTPUT,
- CONNECTTYPE_GPPOUTPUT,
- CONNECTTYPE_NODEINPUT,
- CONNECTTYPE_GPPINPUT
-};
-
-/* Stream mode types */
-enum dsp_strmmode {
- STRMMODE_PROCCOPY, /* Processor(s) copy stream data payloads */
- STRMMODE_ZEROCOPY, /* Strm buffer ptrs swapped no data copied */
- STRMMODE_LDMA, /* Local DMA : OMAP's System-DMA device */
- STRMMODE_RDMA /* Remote DMA: OMAP's DSP-DMA device */
-};
-
-/* Resource Types */
-enum dsp_resourceinfotype {
- DSP_RESOURCE_DYNDARAM = 0,
- DSP_RESOURCE_DYNSARAM,
- DSP_RESOURCE_DYNEXTERNAL,
- DSP_RESOURCE_DYNSRAM,
- DSP_RESOURCE_PROCLOAD
-};
-
-/* Memory Segment Types */
-enum dsp_memtype {
- DSP_DYNDARAM = 0,
- DSP_DYNSARAM,
- DSP_DYNEXTERNAL,
- DSP_DYNSRAM
-};
-
-/* Memory Flush Types */
-enum dsp_flushtype {
- PROC_INVALIDATE_MEM = 0,
- PROC_WRITEBACK_MEM,
- PROC_WRITEBACK_INVALIDATE_MEM,
-};
-
-/* Memory Segment Status Values */
-struct dsp_memstat {
- u32 size;
- u32 total_free_size;
- u32 len_max_free_block;
- u32 num_free_blocks;
- u32 num_alloc_blocks;
-};
-
-/* Processor Load information Values */
-struct dsp_procloadstat {
- u32 curr_load;
- u32 predicted_load;
- u32 curr_dsp_freq;
- u32 predicted_freq;
-};
-
-/* Attributes for STRM connections between nodes */
-struct dsp_strmattr {
- u32 seg_id; /* Memory segment on DSP to allocate buffers */
- u32 buf_size; /* Buffer size (DSP words) */
- u32 num_bufs; /* Number of buffers */
- u32 buf_alignment; /* Buffer alignment */
- u32 timeout; /* Timeout for blocking STRM calls */
- enum dsp_strmmode strm_mode; /* mode of stream when opened */
- /* DMA chnl id if dsp_strmmode is LDMA or RDMA */
- u32 dma_chnl_id;
- u32 dma_priority; /* DMA channel priority 0=lowest, >0=high */
-};
-
-/* The dsp_cbdata structure */
-struct dsp_cbdata {
- u32 cb_data;
- u8 node_data[1];
-};
-
-/* The dsp_msg structure */
-struct dsp_msg {
- u32 cmd;
- u32 arg1;
- u32 arg2;
-};
-
-/* The dsp_resourcereqmts structure for node's resource requirements */
-struct dsp_resourcereqmts {
- u32 cb_struct;
- u32 static_data_size;
- u32 global_data_size;
- u32 program_mem_size;
- u32 wc_execution_time;
- u32 wc_period;
- u32 wc_deadline;
- u32 avg_exection_time;
- u32 minimum_period;
-};
-
-/*
- * The dsp_streamconnect structure describes a stream connection
- * between two nodes, or between a node and the GPP
- */
-struct dsp_streamconnect {
- u32 cb_struct;
- enum dsp_connecttype connect_type;
- u32 this_node_stream_index;
- void *connected_node;
- struct dsp_uuid ui_connected_node_id;
- u32 connected_node_stream_index;
-};
-
-struct dsp_nodeprofs {
- u32 heap_size;
-};
-
-/* The dsp_ndbprops structure reports the attributes of a node */
-struct dsp_ndbprops {
- u32 cb_struct;
- struct dsp_uuid ui_node_id;
- char ac_name[DSP_MAXNAMELEN];
- enum node_type ntype;
- u32 cache_on_gpp;
- struct dsp_resourcereqmts dsp_resource_reqmts;
- s32 prio;
- u32 stack_size;
- u32 sys_stack_size;
- u32 stack_seg;
- u32 message_depth;
- u32 num_input_streams;
- u32 num_output_streams;
- u32 timeout;
- u32 count_profiles; /* Number of supported profiles */
- /* Array of profiles */
- struct dsp_nodeprofs node_profiles[MAX_PROFILES];
- u32 stack_seg_name; /* Stack Segment Name */
-};
-
- /* The dsp_nodeattrin structure describes the attributes of a
- * node client */
-struct dsp_nodeattrin {
- u32 cb_struct;
- s32 prio;
- u32 timeout;
- u32 profile_id;
- /* Reserved, for Bridge Internal use only */
- u32 heap_size;
- void *pgpp_virt_addr; /* Reserved, for Bridge Internal use only */
-};
-
- /* The dsp_nodeinfo structure is used to retrieve information
- * about a node */
-struct dsp_nodeinfo {
- u32 cb_struct;
- struct dsp_ndbprops nb_node_database_props;
- u32 execution_priority;
- enum node_state ns_execution_state;
- void *device_owner;
- u32 number_streams;
- struct dsp_streamconnect sc_stream_connection[16];
- u32 node_env;
-};
-
- /* The dsp_nodeattr structure describes the attributes of a node */
-struct dsp_nodeattr {
- u32 cb_struct;
- struct dsp_nodeattrin in_node_attr_in;
- u32 node_attr_inputs;
- u32 node_attr_outputs;
- struct dsp_nodeinfo node_info;
-};
-
-/*
- * Notification type: either the name of an opened event, or an event or
- * window handle.
- */
-struct dsp_notification {
- char *name;
- void *handle;
-};
-
-/* The dsp_processorattrin structure describes the attributes of a processor */
-struct dsp_processorattrin {
- u32 cb_struct;
- u32 timeout;
-};
-/*
- * The dsp_processorinfo structure describes basic capabilities of a
- * DSP processor
- */
-struct dsp_processorinfo {
- u32 cb_struct;
- int processor_family;
- int processor_type;
- u32 clock_rate;
- u32 internal_mem_size;
- u32 external_mem_size;
- u32 processor_id;
- int ty_running_rtos;
- s32 node_min_priority;
- s32 node_max_priority;
-};
-
-/* Error information of last DSP exception signalled to the GPP */
-struct dsp_errorinfo {
- u32 err_mask;
- u32 val1;
- u32 val2;
- u32 val3;
-};
-
-/* The dsp_processorstate structure describes the state of a DSP processor */
-struct dsp_processorstate {
- u32 cb_struct;
- enum dsp_procstate proc_state;
-};
-
-/*
- * The dsp_resourceinfo structure is used to retrieve information about a
- * processor's resources
- */
-struct dsp_resourceinfo {
- u32 cb_struct;
- enum dsp_resourceinfotype resource_type;
- union {
- u32 resource;
- struct dsp_memstat mem_stat;
- struct dsp_procloadstat proc_load_stat;
- } result;
-};
-
-/*
- * The dsp_streamattrin structure describes the attributes of a stream,
- * including segment and alignment of data buffers allocated with
- * DSPStream_AllocateBuffers(), if applicable
- */
-struct dsp_streamattrin {
- u32 cb_struct;
- u32 timeout;
- u32 segment_id;
- u32 buf_alignment;
- u32 num_bufs;
- enum dsp_strmmode strm_mode;
- u32 dma_chnl_id;
- u32 dma_priority;
-};
-
-/* The dsp_bufferattr structure describes the attributes of a data buffer */
-struct dsp_bufferattr {
- u32 cb_struct;
- u32 segment_id;
- u32 buf_alignment;
-};
-
-/*
- * The dsp_streaminfo structure is used to retrieve information
- * about a stream.
- */
-struct dsp_streaminfo {
- u32 cb_struct;
- u32 number_bufs_allowed;
- u32 number_bufs_in_stream;
- u32 number_bytes;
- void *sync_object_handle;
- enum dsp_streamstate ss_stream_state;
-};
-
-/* DMM MAP attributes
-It is a bit mask with each bit value indicating a specific attribute
-bit 0 - GPP address type (user virtual=0, physical=1)
-bit 1 - MMU Endianism (Big Endian=1, Little Endian=0)
-bit 2 - MMU mixed page attribute (Mixed/ CPUES=1, TLBES =0)
-bit 3 - MMU element size = 8bit (valid only for non mixed page entries)
-bit 4 - MMU element size = 16bit (valid only for non mixed page entries)
-bit 5 - MMU element size = 32bit (valid only for non mixed page entries)
-bit 6 - MMU element size = 64bit (valid only for non mixed page entries)
-
-bit 14 - Input (read only) buffer
-bit 15 - Output (writeable) buffer
-*/
-
-/* Types of mapping attributes */
-
-/* MPU address is virtual and needs to be translated to physical addr */
-#define DSP_MAPVIRTUALADDR 0x00000000
-#define DSP_MAPPHYSICALADDR 0x00000001
-
-/* Mapped data is big endian */
-#define DSP_MAPBIGENDIAN 0x00000002
-#define DSP_MAPLITTLEENDIAN 0x00000000
-
-/* Element size is based on DSP r/w access size */
-#define DSP_MAPMIXEDELEMSIZE 0x00000004
-
-/*
- * Element size for MMU mapping (8, 16, 32, or 64 bit)
- * Ignored if DSP_MAPMIXEDELEMSIZE enabled
- */
-#define DSP_MAPELEMSIZE8 0x00000008
-#define DSP_MAPELEMSIZE16 0x00000010
-#define DSP_MAPELEMSIZE32 0x00000020
-#define DSP_MAPELEMSIZE64 0x00000040
-
-#define DSP_MAPVMALLOCADDR 0x00000080
-
-#define DSP_MAPDONOTLOCK 0x00000100
-
-#define DSP_MAP_DIR_MASK 0x3FFF
-
-#define GEM_CACHE_LINE_SIZE 128
-#define GEM_L1P_PREFETCH_SIZE 128
-
-/*
- * Definitions from dbreg.h
- */
-
-#define DSPPROCTYPE_C64 6410
-#define IVAPROCTYPE_ARM7 470
-
-/* Max registry path length. Also the max registry value length. */
-#define MAXREGPATHLENGTH 255
-
-#endif /* DBDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbll.h b/drivers/staging/tidspbridge/include/dspbridge/dbll.h
deleted file mode 100644
index 46a9e0027ea5..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dbll.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * dbll.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Dynamic load library module interface. Function header
- * comments are in the file dblldefs.h.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBLL_
-#define DBLL_
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/dblldefs.h>
-
-extern bool symbols_reloaded;
-
-extern void dbll_close(struct dbll_library_obj *zl_lib);
-extern int dbll_create(struct dbll_tar_obj **target_obj,
- struct dbll_attrs *pattrs);
-extern void dbll_delete(struct dbll_tar_obj *target);
-extern void dbll_exit(void);
-extern bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val);
-extern void dbll_get_attrs(struct dbll_tar_obj *target,
- struct dbll_attrs *pattrs);
-extern bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val);
-extern int dbll_get_sect(struct dbll_library_obj *lib, char *name,
- u32 *paddr, u32 *psize);
-extern bool dbll_init(void);
-extern int dbll_load(struct dbll_library_obj *lib,
- dbll_flags flags,
- struct dbll_attrs *attrs, u32 * entry);
-extern int dbll_open(struct dbll_tar_obj *target, char *file,
- dbll_flags flags,
- struct dbll_library_obj **lib_obj);
-extern int dbll_read_sect(struct dbll_library_obj *lib,
- char *name, char *buf, u32 size);
-extern void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
- u32 offset_range, u32 *sym_addr_output, char *name_output);
-#endif
-
-#endif /* DBLL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h
deleted file mode 100644
index 30e0aa0540de..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * dblldefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBLLDEFS_
-#define DBLLDEFS_
-
-/*
- * Bit masks for dbl_flags.
- */
-#define DBLL_NOLOAD 0x0 /* Don't load symbols, code, or data */
-#define DBLL_SYMB 0x1 /* load symbols */
-#define DBLL_CODE 0x2 /* load code */
-#define DBLL_DATA 0x4 /* load data */
-#define DBLL_DYNAMIC 0x8 /* dynamic load */
-#define DBLL_BSS 0x20 /* Unitialized section */
-
-#define DBLL_MAXPATHLENGTH 255
-
-/*
- * ======== DBLL_Target ========
- *
- */
-struct dbll_tar_obj;
-
-/*
- * ======== dbll_flags ========
- * Specifies whether to load code, data, or symbols
- */
-typedef s32 dbll_flags;
-
-/*
- * ======== DBLL_Library ========
- *
- */
-struct dbll_library_obj;
-
-/*
- * ======== dbll_sect_info ========
- * For collecting info on overlay sections
- */
-struct dbll_sect_info {
- const char *name; /* name of section */
- u32 sect_run_addr; /* run address of section */
- u32 sect_load_addr; /* load address of section */
- u32 size; /* size of section (target MAUs) */
- dbll_flags type; /* Code, data, or BSS */
-};
-
-/*
- * ======== dbll_sym_val ========
- * (Needed for dynamic load library)
- */
-struct dbll_sym_val {
- u32 value;
-};
-
-/*
- * ======== dbll_alloc_fxn ========
- * Allocate memory function. Allocate or reserve (if reserved == TRUE)
- * "size" bytes of memory from segment "space" and return the address in
- * *dsp_address (or starting at *dsp_address if reserve == TRUE). Returns 0 on
- * success, or an error code on failure.
- */
-typedef s32(*dbll_alloc_fxn) (void *hdl, s32 space, u32 size, u32 align,
- u32 *dsp_address, s32 seg_id, s32 req,
- bool reserved);
-
-/*
- * ======== dbll_close_fxn ========
- */
-typedef s32(*dbll_f_close_fxn) (void *);
-
-/*
- * ======== dbll_free_fxn ========
- * Free memory function. Free, or unreserve (if reserved == TRUE) "size"
- * bytes of memory from segment "space"
- */
-typedef bool(*dbll_free_fxn) (void *hdl, u32 addr, s32 space, u32 size,
- bool reserved);
-
-/*
- * ======== dbll_f_open_fxn ========
- */
-typedef void *(*dbll_f_open_fxn) (const char *, const char *);
-
-/*
- * ======== dbll_log_write_fxn ========
- * Function to call when writing data from a section, to log the info.
- * Can be NULL if no logging is required.
- */
-typedef int(*dbll_log_write_fxn) (void *handle,
- struct dbll_sect_info *sect, u32 addr,
- u32 bytes);
-
-/*
- * ======== dbll_read_fxn ========
- */
-typedef s32(*dbll_read_fxn) (void *, size_t, size_t, void *);
-
-/*
- * ======== dbll_seek_fxn ========
- */
-typedef s32(*dbll_seek_fxn) (void *, long, int);
-
-/*
- * ======== dbll_sym_lookup ========
- * Symbol lookup function - Find the symbol name and return its value.
- *
- * Parameters:
- * handle - Opaque handle
- * parg - Opaque argument.
- * name - Name of symbol to lookup.
- * sym - Location to store address of symbol structure.
- *
- * Returns:
- * TRUE: Success (symbol was found).
- * FALSE: Failed to find symbol.
- */
-typedef bool(*dbll_sym_lookup) (void *handle, void *parg, void *rmm_handle,
- const char *name, struct dbll_sym_val ** sym);
-
-/*
- * ======== dbll_tell_fxn ========
- */
-typedef s32(*dbll_tell_fxn) (void *);
-
-/*
- * ======== dbll_write_fxn ========
- * Write memory function. Write "n" HOST bytes of memory to segment "mtype"
- * starting at address "dsp_address" from the buffer "buf". The buffer is
- * formatted as an array of words appropriate for the DSP.
- */
-typedef s32(*dbll_write_fxn) (void *hdl, u32 dsp_address, void *buf,
- u32 n, s32 mtype);
-
-/*
- * ======== dbll_attrs ========
- */
-struct dbll_attrs {
- dbll_alloc_fxn alloc;
- dbll_free_fxn free;
- void *rmm_handle; /* Handle to pass to alloc, free functions */
- dbll_write_fxn write;
- void *input_params; /* Handle to pass to write, cinit function */
- bool base_image;
- dbll_log_write_fxn log_write;
- void *log_write_handle;
-
- /* Symbol matching function and handle to pass to it */
- dbll_sym_lookup sym_lookup;
- void *sym_handle;
- void *sym_arg;
-
- /*
- * These file manipulation functions should be compatible with the
- * "C" run time library functions of the same name.
- */
- s32(*fread) (void *, size_t, size_t, void *);
- s32(*fseek) (void *, long, int);
- s32(*ftell) (void *);
- s32(*fclose) (void *);
- void *(*fopen) (const char *, const char *);
-};
-
-/*
- * ======== dbll_close ========
- * Close library opened with dbll_open.
- * Parameters:
- * lib - Handle returned from dbll_open().
- * Returns:
- * Requires:
- * DBL initialized.
- * Valid lib.
- * Ensures:
- */
-typedef void (*dbll_close_fxn) (struct dbll_library_obj *library);
-
-/*
- * ======== dbll_create ========
- * Create a target object, specifying the alloc, free, and write functions.
- * Parameters:
- * target_obj - Location to store target handle on output.
- * pattrs - Attributes.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failed.
- * Requires:
- * DBL initialized.
- * pattrs != NULL.
- * target_obj != NULL;
- * Ensures:
- * Success: *target_obj != NULL.
- * Failure: *target_obj == NULL.
- */
-typedef int(*dbll_create_fxn) (struct dbll_tar_obj **target_obj,
- struct dbll_attrs *attrs);
-
-/*
- * ======== dbll_delete ========
- * Delete target object and free resources for any loaded libraries.
- * Parameters:
- * target - Handle returned from DBLL_Create().
- * Returns:
- * Requires:
- * DBL initialized.
- * Valid target.
- * Ensures:
- */
-typedef void (*dbll_delete_fxn) (struct dbll_tar_obj *target);
-
-/*
- * ======== dbll_exit ========
- * Discontinue use of DBL module.
- * Parameters:
- * Returns:
- * Requires:
- * refs > 0.
- * Ensures:
- * refs >= 0.
- */
-typedef void (*dbll_exit_fxn) (void);
-
-/*
- * ======== dbll_get_addr ========
- * Get address of name in the specified library.
- * Parameters:
- * lib - Handle returned from dbll_open().
- * name - Name of symbol
- * sym_val - Location to store symbol address on output.
- * Returns:
- * TRUE: Success.
- * FALSE: Symbol not found.
- * Requires:
- * DBL initialized.
- * Valid library.
- * name != NULL.
- * sym_val != NULL.
- * Ensures:
- */
-typedef bool(*dbll_get_addr_fxn) (struct dbll_library_obj *lib, char *name,
- struct dbll_sym_val **sym_val);
-
-/*
- * ======== dbll_get_attrs ========
- * Retrieve the attributes of the target.
- * Parameters:
- * target - Handle returned from DBLL_Create().
- * pattrs - Location to store attributes on output.
- * Returns:
- * Requires:
- * DBL initialized.
- * Valid target.
- * pattrs != NULL.
- * Ensures:
- */
-typedef void (*dbll_get_attrs_fxn) (struct dbll_tar_obj *target,
- struct dbll_attrs *attrs);
-
-/*
- * ======== dbll_get_c_addr ========
- * Get address of "C" name on the specified library.
- * Parameters:
- * lib - Handle returned from dbll_open().
- * name - Name of symbol
- * sym_val - Location to store symbol address on output.
- * Returns:
- * TRUE: Success.
- * FALSE: Symbol not found.
- * Requires:
- * DBL initialized.
- * Valid target.
- * name != NULL.
- * sym_val != NULL.
- * Ensures:
- */
-typedef bool(*dbll_get_c_addr_fxn) (struct dbll_library_obj *lib, char *name,
- struct dbll_sym_val **sym_val);
-
-/*
- * ======== dbll_get_sect ========
- * Get address and size of a named section.
- * Parameters:
- * lib - Library handle returned from dbll_open().
- * name - Name of section.
- * paddr - Location to store section address on output.
- * psize - Location to store section size on output.
- * Returns:
- * 0: Success.
- * -ENXIO: Section not found.
- * Requires:
- * DBL initialized.
- * Valid lib.
- * name != NULL.
- * paddr != NULL;
- * psize != NULL.
- * Ensures:
- */
-typedef int(*dbll_get_sect_fxn) (struct dbll_library_obj *lib,
- char *name, u32 * addr, u32 * size);
-
-/*
- * ======== dbll_init ========
- * Initialize DBL module.
- * Parameters:
- * Returns:
- * TRUE: Success.
- * FALSE: Failure.
- * Requires:
- * refs >= 0.
- * Ensures:
- * Success: refs > 0.
- * Failure: refs >= 0.
- */
-typedef bool(*dbll_init_fxn) (void);
-
-/*
- * ======== dbll_load ========
- * Load library onto the target.
- *
- * Parameters:
- * lib - Library handle returned from dbll_open().
- * flags - Load code, data and/or symbols.
- * attrs - May contain alloc, free, and write function.
- * entry_pt - Location to store program entry on output.
- * Returns:
- * 0: Success.
- * -EBADF: File read failed.
- * -EILSEQ: Failure in dynamic loader library.
- * Requires:
- * DBL initialized.
- * Valid lib.
- * entry != NULL.
- * Ensures:
- */
-typedef int(*dbll_load_fxn) (struct dbll_library_obj *lib,
- dbll_flags flags,
- struct dbll_attrs *attrs, u32 *entry);
-/*
- * ======== dbll_open ========
- * dbll_open() returns a library handle that can be used to load/unload
- * the symbols/code/data via dbll_load()/dbll_unload().
- * Parameters:
- * target - Handle returned from dbll_create().
- * file - Name of file to open.
- * flags - If flags & DBLL_SYMB, load symbols.
- * lib_obj - Location to store library handle on output.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failure.
- * -EBADF: File open/read failure.
- * Unable to determine target type.
- * Requires:
- * DBL initialized.
- * Valid target.
- * file != NULL.
- * lib_obj != NULL.
- * dbll_attrs fopen function non-NULL.
- * Ensures:
- * Success: Valid *lib_obj.
- * Failure: *lib_obj == NULL.
- */
-typedef int(*dbll_open_fxn) (struct dbll_tar_obj *target, char *file,
- dbll_flags flags,
- struct dbll_library_obj **lib_obj);
-
-/*
- * ======== dbll_read_sect ========
- * Read COFF section into a character buffer.
- * Parameters:
- * lib - Library handle returned from dbll_open().
- * name - Name of section.
- * pbuf - Buffer to write section contents into.
- * size - Buffer size
- * Returns:
- * 0: Success.
- * -ENXIO: Named section does not exists.
- * Requires:
- * DBL initialized.
- * Valid lib.
- * name != NULL.
- * pbuf != NULL.
- * size != 0.
- * Ensures:
- */
-typedef int(*dbll_read_sect_fxn) (struct dbll_library_obj *lib,
- char *name, char *content,
- u32 cont_size);
-/*
- * ======== dbll_unload ========
- * Unload library loaded with dbll_load().
- * Parameters:
- * lib - Handle returned from dbll_open().
- * attrs - Contains free() function and handle to pass to it.
- * Returns:
- * Requires:
- * DBL initialized.
- * Valid lib.
- * Ensures:
- */
-typedef void (*dbll_unload_fxn) (struct dbll_library_obj *library,
- struct dbll_attrs *attrs);
-struct dbll_fxns {
- dbll_close_fxn close_fxn;
- dbll_create_fxn create_fxn;
- dbll_delete_fxn delete_fxn;
- dbll_exit_fxn exit_fxn;
- dbll_get_attrs_fxn get_attrs_fxn;
- dbll_get_addr_fxn get_addr_fxn;
- dbll_get_c_addr_fxn get_c_addr_fxn;
- dbll_get_sect_fxn get_sect_fxn;
- dbll_init_fxn init_fxn;
- dbll_load_fxn load_fxn;
- dbll_open_fxn open_fxn;
- dbll_read_sect_fxn read_sect_fxn;
- dbll_unload_fxn unload_fxn;
-};
-
-#endif /* DBLDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h
deleted file mode 100644
index fa2d79ef6cc8..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dev.h
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * dev.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Bridge Bridge driver device operations.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DEV_
-#define DEV_
-
-/* ----------------------------------- Module Dependent Headers */
-#include <dspbridge/chnldefs.h>
-#include <dspbridge/cmm.h>
-#include <dspbridge/cod.h>
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/nodedefs.h>
-#include <dspbridge/disp.h>
-#include <dspbridge/dspdefs.h>
-#include <dspbridge/dmm.h>
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/devdefs.h>
-
-/*
- * ======== dev_brd_write_fxn ========
- * Purpose:
- * Exported function to be used as the COD write function. This function
- * is passed a handle to a DEV_hObject by ZL in arb, then calls the
- * device's bridge_brd_write() function.
- * Parameters:
- * arb: Handle to a Device Object.
- * dev_ctxt: Handle to Bridge driver defined device info.
- * dsp_addr: Address on DSP board (Destination).
- * host_buf: Pointer to host buffer (Source).
- * ul_num_bytes: Number of bytes to transfer.
- * mem_type: Memory space on DSP to which to transfer.
- * Returns:
- * Number of bytes written. Returns 0 if the DEV_hObject passed in via
- * arb is invalid.
- * Requires:
- * DEV Initialized.
- * host_buf != NULL
- * Ensures:
- */
-extern u32 dev_brd_write_fxn(void *arb,
- u32 dsp_add,
- void *host_buf, u32 ul_num_bytes, u32 mem_space);
-
-/*
- * ======== dev_create_device ========
- * Purpose:
- * Called by the operating system to load the Bridge Driver for a
- * 'Bridge device.
- * Parameters:
- * device_obj: Ptr to location to receive the device object handle.
- * driver_file_name: Name of Bridge driver PE DLL file to load. If the
- * absolute path is not provided, the file is loaded
- * through 'Bridge's module search path.
- * host_config: Host configuration information, to be passed down
- * to the Bridge driver when bridge_dev_create() is called.
- * pDspConfig: DSP resources, to be passed down to the Bridge driver
- * when bridge_dev_create() is called.
- * dev_node_obj: Platform specific device node.
- * Returns:
- * 0: Module is loaded, device object has been created
- * -ENOMEM: Insufficient memory to create needed resources.
- * -EPERM: Unable to find Bridge driver entry point function.
- * -ESPIPE: Unable to load ZL DLL.
- * Requires:
- * DEV Initialized.
- * device_obj != NULL.
- * driver_file_name != NULL.
- * host_config != NULL.
- * pDspConfig != NULL.
- * Ensures:
- * 0: *device_obj will contain handle to the new device object.
- * Otherwise, does not create the device object, ensures the Bridge driver
- * module is unloaded, and sets *device_obj to NULL.
- */
-extern int dev_create_device(struct dev_object
- **device_obj,
- const char *driver_file_name,
- struct cfg_devnode *dev_node_obj);
-
-/*
- * ======== dev_create2 ========
- * Purpose:
- * After successful loading of the image from api_init_complete2
- * (PROC Auto_Start) or proc_load this fxn is called. This creates
- * the Node Manager and updates the DEV Object.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device().
- * Returns:
- * 0: Successful Creation of Node Manager
- * -EPERM: Some Error Occurred.
- * Requires:
- * DEV Initialized
- * Valid hdev_obj
- * Ensures:
- * 0 and hdev_obj->node_mgr != NULL
- * else hdev_obj->node_mgr == NULL
- */
-extern int dev_create2(struct dev_object *hdev_obj);
-
-/*
- * ======== dev_destroy2 ========
- * Purpose:
- * Destroys the Node manager for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device().
- * Returns:
- * 0: Successful Creation of Node Manager
- * -EPERM: Some Error Occurred.
- * Requires:
- * DEV Initialized
- * Valid hdev_obj
- * Ensures:
- * 0 and hdev_obj->node_mgr == NULL
- * else -EPERM.
- */
-extern int dev_destroy2(struct dev_object *hdev_obj);
-
-/*
- * ======== dev_destroy_device ========
- * Purpose:
- * Destroys the channel manager for this device, if any, calls
- * bridge_dev_destroy(), and then attempts to unload the Bridge module.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * -EPERM: The Bridge driver failed it's bridge_dev_destroy() function.
- * Requires:
- * DEV Initialized.
- * Ensures:
- */
-extern int dev_destroy_device(struct dev_object
- *hdev_obj);
-
-/*
- * ======== dev_get_chnl_mgr ========
- * Purpose:
- * Retrieve the handle to the channel manager created for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *mgr contains a handle to a channel manager object,
- * or NULL.
- * else: *mgr is NULL.
- */
-extern int dev_get_chnl_mgr(struct dev_object *hdev_obj,
- struct chnl_mgr **mgr);
-
-/*
- * ======== dev_get_cmm_mgr ========
- * Purpose:
- * Retrieve the handle to the shared memory manager created for this
- * device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *mgr contains a handle to a channel manager object,
- * or NULL.
- * else: *mgr is NULL.
- */
-extern int dev_get_cmm_mgr(struct dev_object *hdev_obj,
- struct cmm_object **mgr);
-
-/*
- * ======== dev_get_dmm_mgr ========
- * Purpose:
- * Retrieve the handle to the dynamic memory manager created for this
- * device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *mgr contains a handle to a channel manager object,
- * or NULL.
- * else: *mgr is NULL.
- */
-extern int dev_get_dmm_mgr(struct dev_object *hdev_obj,
- struct dmm_object **mgr);
-
-/*
- * ======== dev_get_cod_mgr ========
- * Purpose:
- * Retrieve the COD manager create for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *cod_mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * cod_mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *cod_mgr contains a handle to a COD manager object.
- * else: *cod_mgr is NULL.
- */
-extern int dev_get_cod_mgr(struct dev_object *hdev_obj,
- struct cod_manager **cod_mgr);
-
-/*
- * ======== dev_get_deh_mgr ========
- * Purpose:
- * Retrieve the DEH manager created for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device().
- * *deh_manager: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * deh_manager != NULL.
- * DEH Initialized.
- * Ensures:
- * 0: *deh_manager contains a handle to a DEH manager object.
- * else: *deh_manager is NULL.
- */
-extern int dev_get_deh_mgr(struct dev_object *hdev_obj,
- struct deh_mgr **deh_manager);
-
-/*
- * ======== dev_get_dev_node ========
- * Purpose:
- * Retrieve the platform specific device ID for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * dev_nde: Ptr to location to get the device node handle.
- * Returns:
- * 0: Returns a DEVNODE in *dev_node_obj.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * dev_nde != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *dev_nde contains a platform specific device ID;
- * else: *dev_nde is NULL.
- */
-extern int dev_get_dev_node(struct dev_object *hdev_obj,
- struct cfg_devnode **dev_nde);
-
-/*
- * ======== dev_get_dev_type ========
- * Purpose:
- * Retrieve the platform specific device ID for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * dev_nde: Ptr to location to get the device node handle.
- * Returns:
- * 0: Success
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * dev_nde != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *dev_nde contains a platform specific device ID;
- * else: *dev_nde is NULL.
- */
-extern int dev_get_dev_type(struct dev_object *device_obj,
- u8 *dev_type);
-
-/*
- * ======== dev_get_first ========
- * Purpose:
- * Retrieve the first Device Object handle from an internal linked list of
- * of DEV_OBJECTs maintained by DEV.
- * Parameters:
- * Returns:
- * NULL if there are no device objects stored; else
- * a valid DEV_HOBJECT.
- * Requires:
- * No calls to dev_create_device or dev_destroy_device (which my modify the
- * internal device object list) may occur between calls to dev_get_first
- * and dev_get_next.
- * Ensures:
- * The DEV_HOBJECT returned is valid.
- * A subsequent call to dev_get_next will return the next device object in
- * the list.
- */
-extern struct dev_object *dev_get_first(void);
-
-/*
- * ======== dev_get_intf_fxns ========
- * Purpose:
- * Retrieve the Bridge driver interface function structure for the
- * loaded Bridge driver.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *if_fxns: Ptr to location to store fxn interface.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * if_fxns != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *if_fxns contains a pointer to the Bridge
- * driver interface;
- * else: *if_fxns is NULL.
- */
-extern int dev_get_intf_fxns(struct dev_object *hdev_obj,
- struct bridge_drv_interface **if_fxns);
-
-/*
- * ======== dev_get_io_mgr ========
- * Purpose:
- * Retrieve the handle to the IO manager created for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * *mgr: Ptr to location to store handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * mgr != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *mgr contains a handle to an IO manager object.
- * else: *mgr is NULL.
- */
-extern int dev_get_io_mgr(struct dev_object *hdev_obj,
- struct io_mgr **mgr);
-
-/*
- * ======== dev_get_next ========
- * Purpose:
- * Retrieve the next Device Object handle from an internal linked list of
- * of DEV_OBJECTs maintained by DEV, after having previously called
- * dev_get_first() and zero or more dev_get_next
- * Parameters:
- * hdev_obj: Handle to the device object returned from a previous
- * call to dev_get_first() or dev_get_next().
- * Returns:
- * NULL if there are no further device objects on the list or hdev_obj
- * was invalid;
- * else the next valid DEV_HOBJECT in the list.
- * Requires:
- * No calls to dev_create_device or dev_destroy_device (which my modify the
- * internal device object list) may occur between calls to dev_get_first
- * and dev_get_next.
- * Ensures:
- * The DEV_HOBJECT returned is valid.
- * A subsequent call to dev_get_next will return the next device object in
- * the list.
- */
-extern struct dev_object *dev_get_next(struct dev_object
- *hdev_obj);
-
-/*
- * ========= dev_get_msg_mgr ========
- * Purpose:
- * Retrieve the msg_ctrl Manager Handle from the DevObject.
- * Parameters:
- * hdev_obj: Handle to the Dev Object
- * msg_man: Location where msg_ctrl Manager handle will be returned.
- * Returns:
- * Requires:
- * DEV Initialized.
- * Valid hdev_obj.
- * node_man != NULL.
- * Ensures:
- */
-extern void dev_get_msg_mgr(struct dev_object *hdev_obj,
- struct msg_mgr **msg_man);
-
-/*
- * ========= dev_get_node_manager ========
- * Purpose:
- * Retrieve the Node Manager Handle from the DevObject. It is an
- * accessor function
- * Parameters:
- * hdev_obj: Handle to the Dev Object
- * node_man: Location where Handle to the Node Manager will be
- * returned..
- * Returns:
- * 0: Success
- * -EFAULT: Invalid Dev Object handle.
- * Requires:
- * DEV Initialized.
- * node_man is not null
- * Ensures:
- * 0: *node_man contains a handle to a Node manager object.
- * else: *node_man is NULL.
- */
-extern int dev_get_node_manager(struct dev_object
- *hdev_obj,
- struct node_mgr **node_man);
-
-/*
- * ======== dev_get_symbol ========
- * Purpose:
- * Get the value of a symbol in the currently loaded program.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * str_sym: Name of symbol to look up.
- * pul_value: Ptr to symbol value.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * -ESPIPE: Symbols couldn not be found or have not been loaded onto
- * the board.
- * Requires:
- * str_sym != NULL.
- * pul_value != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *pul_value contains the symbol value;
- */
-extern int dev_get_symbol(struct dev_object *hdev_obj,
- const char *str_sym, u32 * pul_value);
-
-/*
- * ======== dev_get_bridge_context ========
- * Purpose:
- * Retrieve the Bridge Context handle, as returned by the
- * bridge_dev_create fxn.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device()
- * *phbridge_context: Ptr to location to store context handle.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * phbridge_context != NULL.
- * DEV Initialized.
- * Ensures:
- * 0: *phbridge_context contains context handle;
- * else: *phbridge_context is NULL;
- */
-extern int dev_get_bridge_context(struct dev_object *hdev_obj,
- struct bridge_dev_context
- **phbridge_context);
-
-/*
- * ======== dev_insert_proc_object ========
- * Purpose:
- * Inserts the Processor Object into the List of PROC Objects
- * kept in the DEV Object
- * Parameters:
- * proc_obj: Handle to the Proc Object
- * hdev_obj Handle to the Dev Object
- * bAttachedNew Specifies if there are already processors attached
- * Returns:
- * 0: Successfully inserted into the list
- * Requires:
- * proc_obj is not NULL
- * hdev_obj is a valid handle to the DEV.
- * DEV Initialized.
- * List(of Proc object in Dev) Exists.
- * Ensures:
- * 0 & the PROC Object is inserted and the list is not empty
- * Details:
- * If the List of Proc Object is empty bAttachedNew is TRUE, it indicated
- * this is the first Processor attaching.
- * If it is False, there are already processors attached.
- */
-extern int dev_insert_proc_object(struct dev_object
- *hdev_obj,
- u32 proc_obj,
- bool *already_attached);
-
-/*
- * ======== dev_remove_proc_object ========
- * Purpose:
- * Search for and remove a Proc object from the given list maintained
- * by the DEV
- * Parameters:
- * p_proc_object: Ptr to ProcObject to insert.
- * dev_obj: Ptr to Dev Object where the list is.
- * already_attached: Ptr to return the bool
- * Returns:
- * 0: If successful.
- * -EPERM Failure to Remove the PROC Object from the list
- * Requires:
- * DevObject is Valid
- * proc_obj != 0
- * dev_obj->proc_list != NULL
- * !LST_IS_EMPTY(dev_obj->proc_list)
- * already_attached !=NULL
- * Ensures:
- * Details:
- * List will be deleted when the DEV is destroyed.
- *
- */
-extern int dev_remove_proc_object(struct dev_object
- *hdev_obj, u32 proc_obj);
-
-/*
- * ======== dev_notify_clients ========
- * Purpose:
- * Notify all clients of this device of a change in device status.
- * Clients may include multiple users of BRD, as well as CHNL.
- * This function is asychronous, and may be called by a timer event
- * set up by a watchdog timer.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device().
- * ret: A status word, most likely a BRD_STATUS.
- * Returns:
- * 0: All registered clients were asynchronously notified.
- * -EINVAL: Invalid hdev_obj.
- * Requires:
- * DEV Initialized.
- * Ensures:
- * 0: Notifications are queued by the operating system to be
- * delivered to clients. This function does not ensure that
- * the notifications will ever be delivered.
- */
-extern int dev_notify_clients(struct dev_object *hdev_obj, u32 ret);
-
-/*
- * ======== dev_remove_device ========
- * Purpose:
- * Destroys the Device Object created by dev_start_device.
- * Parameters:
- * dev_node_obj: Device node as it is know to OS.
- * Returns:
- * 0: If success;
- * <error code> Otherwise.
- * Requires:
- * Ensures:
- */
-extern int dev_remove_device(struct cfg_devnode *dev_node_obj);
-
-/*
- * ======== dev_set_chnl_mgr ========
- * Purpose:
- * Set the channel manager for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with
- * dev_create_device().
- * hmgr: Handle to a channel manager, or NULL.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * DEV Initialized.
- * Ensures:
- */
-extern int dev_set_chnl_mgr(struct dev_object *hdev_obj,
- struct chnl_mgr *hmgr);
-
-/*
- * ======== dev_set_msg_mgr ========
- * Purpose:
- * Set the Message manager for this device.
- * Parameters:
- * hdev_obj: Handle to device object created with dev_create_device().
- * hmgr: Handle to a message manager, or NULL.
- * Returns:
- * Requires:
- * DEV Initialized.
- * Ensures:
- */
-extern void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr);
-
-/*
- * ======== dev_start_device ========
- * Purpose:
- * Initializes the new device with bridge environment. This involves
- * querying CM for allocated resources, querying the registry for
- * necessary dsp resources (requested in the INF file), and using this
- * information to create a bridge device object.
- * Parameters:
- * dev_node_obj: Device node as it is know to OS.
- * Returns:
- * 0: If success;
- * <error code> Otherwise.
- * Requires:
- * DEV initialized.
- * Ensures:
- */
-extern int dev_start_device(struct cfg_devnode *dev_node_obj);
-
-#endif /* DEV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/devdefs.h b/drivers/staging/tidspbridge/include/dspbridge/devdefs.h
deleted file mode 100644
index a2f9241ff139..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/devdefs.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * devdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Definition of common include typedef between dspdefs.h and dev.h. Required
- * to break circular dependency between Bridge driver and DEV include files.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DEVDEFS_
-#define DEVDEFS_
-
-/* Bridge Device Object */
-struct dev_object;
-
-#endif /* DEVDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/disp.h b/drivers/staging/tidspbridge/include/dspbridge/disp.h
deleted file mode 100644
index 39d3cea9ca8b..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/disp.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * disp.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Node Dispatcher.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DISP_
-#define DISP_
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/nodedefs.h>
-#include <dspbridge/nodepriv.h>
-
-struct disp_object;
-
-/* Node Dispatcher attributes */
-struct disp_attr {
- u32 chnl_offset; /* Offset of channel ids reserved for RMS */
- /* Size of buffer for sending data to RMS */
- u32 chnl_buf_size;
- int proc_family; /* eg, 5000 */
- int proc_type; /* eg, 5510 */
- void *reserved1; /* Reserved for future use. */
- u32 reserved2; /* Reserved for future use. */
-};
-
-
-/*
- * ======== disp_create ========
- * Create a NODE Dispatcher object. This object handles the creation,
- * deletion, and execution of nodes on the DSP target, through communication
- * with the Resource Manager Server running on the target. Each NODE
- * Manager object should have exactly one NODE Dispatcher.
- *
- * Parameters:
- * dispatch_obj: Location to store node dispatcher object on output.
- * hdev_obj: Device for this processor.
- * disp_attrs: Node dispatcher attributes.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EPERM: Unable to create dispatcher.
- * Requires:
- * disp_attrs != NULL.
- * hdev_obj != NULL.
- * dispatch_obj != NULL.
- * Ensures:
- * 0: IS_VALID(*dispatch_obj).
- * error: *dispatch_obj == NULL.
- */
-extern int disp_create(struct disp_object **dispatch_obj,
- struct dev_object *hdev_obj,
- const struct disp_attr *disp_attrs);
-
-/*
- * ======== disp_delete ========
- * Delete the NODE Dispatcher.
- *
- * Parameters:
- * disp_obj: Node Dispatcher object.
- * Returns:
- * Requires:
- * Valid disp_obj.
- * Ensures:
- * disp_obj is invalid.
- */
-extern void disp_delete(struct disp_object *disp_obj);
-
-/*
- * ======== disp_node_change_priority ========
- * Change the priority of a node currently running on the target.
- *
- * Parameters:
- * disp_obj: Node Dispatcher object.
- * hnode: Node object representing a node currently
- * allocated or running on the DSP.
- * ulFxnAddress: Address of RMS function for changing priority.
- * node_env: Address of node's environment structure.
- * prio: New priority level to set node's priority to.
- * Returns:
- * 0: Success.
- * -ETIME: A timeout occurred before the DSP responded.
- * Requires:
- * Valid disp_obj.
- * hnode != NULL.
- * Ensures:
- */
-extern int disp_node_change_priority(struct disp_object
- *disp_obj,
- struct node_object *hnode,
- u32 rms_fxn,
- nodeenv node_env, s32 prio);
-
-/*
- * ======== disp_node_create ========
- * Create a node on the DSP by remotely calling the node's create function.
- *
- * Parameters:
- * disp_obj: Node Dispatcher object.
- * hnode: Node handle obtained from node_allocate().
- * ul_fxn_addr: Address or RMS create node function.
- * ul_create_fxn: Address of node's create function.
- * pargs: Arguments to pass to RMS node create function.
- * node_env: Location to store node environment pointer on
- * output.
- * Returns:
- * 0: Success.
- * -ETIME: A timeout occurred before the DSP responded.
- * -EPERM: A failure occurred, unable to create node.
- * Requires:
- * Valid disp_obj.
- * pargs != NULL.
- * hnode != NULL.
- * node_env != NULL.
- * node_get_type(hnode) != NODE_DEVICE.
- * Ensures:
- */
-extern int disp_node_create(struct disp_object *disp_obj,
- struct node_object *hnode,
- u32 rms_fxn,
- u32 ul_create_fxn,
- const struct node_createargs
- *pargs, nodeenv *node_env);
-
-/*
- * ======== disp_node_delete ========
- * Delete a node on the DSP by remotely calling the node's delete function.
- *
- * Parameters:
- * disp_obj: Node Dispatcher object.
- * hnode: Node object representing a node currently
- * loaded on the DSP.
- * ul_fxn_addr: Address or RMS delete node function.
- * ul_delete_fxn: Address of node's delete function.
- * node_env: Address of node's environment structure.
- * Returns:
- * 0: Success.
- * -ETIME: A timeout occurred before the DSP responded.
- * Requires:
- * Valid disp_obj.
- * hnode != NULL.
- * Ensures:
- */
-extern int disp_node_delete(struct disp_object *disp_obj,
- struct node_object *hnode,
- u32 rms_fxn,
- u32 ul_delete_fxn, nodeenv node_env);
-
-/*
- * ======== disp_node_run ========
- * Start execution of a node's execute phase, or resume execution of a node
- * that has been suspended (via DISP_NodePause()) on the DSP.
- *
- * Parameters:
- * disp_obj: Node Dispatcher object.
- * hnode: Node object representing a node to be executed
- * on the DSP.
- * ul_fxn_addr: Address or RMS node execute function.
- * ul_execute_fxn: Address of node's execute function.
- * node_env: Address of node's environment structure.
- * Returns:
- * 0: Success.
- * -ETIME: A timeout occurred before the DSP responded.
- * Requires:
- * Valid disp_obj.
- * hnode != NULL.
- * Ensures:
- */
-extern int disp_node_run(struct disp_object *disp_obj,
- struct node_object *hnode,
- u32 rms_fxn,
- u32 ul_execute_fxn, nodeenv node_env);
-
-#endif /* DISP_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/drivers/staging/tidspbridge/include/dspbridge/dmm.h
deleted file mode 100644
index c3487be8fcf5..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dmm.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * dmm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address
- * space that can be directly mapped to any MPU buffer or memory region.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DMM_
-#define DMM_
-
-#include <dspbridge/dbdefs.h>
-
-struct dmm_object;
-
-/* DMM attributes used in dmm_create() */
-struct dmm_mgrattrs {
- u32 reserved;
-};
-
-#define DMMPOOLSIZE 0x4000000
-
-/*
- * ======== dmm_get_handle ========
- * Purpose:
- * Return the dynamic memory manager object for this device.
- * This is typically called from the client process.
- */
-
-extern int dmm_get_handle(void *hprocessor,
- struct dmm_object **dmm_manager);
-
-extern int dmm_reserve_memory(struct dmm_object *dmm_mgr,
- u32 size, u32 *prsv_addr);
-
-extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr,
- u32 rsv_addr);
-
-extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr,
- u32 size);
-
-extern int dmm_un_map_memory(struct dmm_object *dmm_mgr,
- u32 addr, u32 *psize);
-
-extern int dmm_destroy(struct dmm_object *dmm_mgr);
-
-extern int dmm_delete_tables(struct dmm_object *dmm_mgr);
-
-extern int dmm_create(struct dmm_object **dmm_manager,
- struct dev_object *hdev_obj,
- const struct dmm_mgrattrs *mgr_attrts);
-
-extern int dmm_create_tables(struct dmm_object *dmm_mgr,
- u32 addr, u32 size);
-
-#ifdef DSP_DMM_DEBUG
-u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr);
-#endif
-
-#endif /* DMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h
deleted file mode 100644
index b0c7708321b2..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/drv.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * drv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DRV Resource allocation module. Driver Object gets Created
- * at the time of Loading. It holds the List of Device Objects
- * in the system.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DRV_
-#define DRV_
-
-#include <dspbridge/devdefs.h>
-
-#include <linux/idr.h>
-
-/* Bridge Driver Object */
-struct drv_object;
-
-/* Provide the DSP Internal memory windows that can be accessed from L3 address
- * space */
-
-#define OMAP_GEM_BASE 0x107F8000
-#define OMAP_DSP_SIZE 0x00720000
-
-/* MEM1 is L2 RAM + L2 Cache space */
-#define OMAP_DSP_MEM1_BASE 0x5C7F8000
-#define OMAP_DSP_MEM1_SIZE 0x18000
-
-/* MEM2 is L1P RAM/CACHE space */
-#define OMAP_DSP_MEM2_BASE 0x5CE00000
-#define OMAP_DSP_MEM2_SIZE 0x8000
-
-/* MEM3 is L1D RAM/CACHE space */
-#define OMAP_DSP_MEM3_BASE 0x5CF04000
-#define OMAP_DSP_MEM3_SIZE 0x14000
-
-#define OMAP_PER_CM_BASE 0x48005000
-#define OMAP_PER_CM_SIZE 0x1000
-
-#define OMAP_PER_PRM_BASE 0x48307000
-#define OMAP_PER_PRM_SIZE 0x1000
-
-#define OMAP_CORE_PRM_BASE 0x48306A00
-#define OMAP_CORE_PRM_SIZE 0x1000
-
-#define OMAP_DMMU_BASE 0x5D000000
-#define OMAP_DMMU_SIZE 0x1000
-
-/* GPP PROCESS CLEANUP Data structures */
-
-/* New structure (member of process context) abstracts NODE resource info */
-struct node_res_object {
- void *node;
- s32 node_allocated; /* Node status */
- s32 heap_allocated; /* Heap status */
- s32 streams_allocated; /* Streams status */
- int id;
-};
-
-/* used to cache dma mapping information */
-struct bridge_dma_map_info {
- /* direction of DMA in action, or DMA_NONE */
- enum dma_data_direction dir;
- /* number of elements requested by us */
- int num_pages;
- /* number of elements returned from dma_map_sg */
- int sg_num;
- /* list of buffers used in this DMA action */
- struct scatterlist *sg;
-};
-
-/* Used for DMM mapped memory accounting */
-struct dmm_map_object {
- struct list_head link;
- u32 dsp_addr;
- u32 mpu_addr;
- u32 size;
- u32 num_usr_pgs;
- struct page **pages;
- struct bridge_dma_map_info dma_info;
-};
-
-/* Used for DMM reserved memory accounting */
-struct dmm_rsv_object {
- struct list_head link;
- u32 dsp_reserved_addr;
-};
-
-/* New structure (member of process context) abstracts stream resource info */
-struct strm_res_object {
- s32 stream_allocated; /* Stream status */
- void *stream;
- u32 num_bufs;
- u32 dir;
- int id;
-};
-
-/* Overall Bridge process resource usage state */
-enum gpp_proc_res_state {
- PROC_RES_ALLOCATED,
- PROC_RES_FREED
-};
-
-/* Bridge Data */
-struct drv_data {
- char *base_img;
- s32 shm_size;
- int tc_wordswapon;
- void *drv_object;
- void *dev_object;
- void *mgr_object;
-};
-
-/* Process Context */
-struct process_context {
- /* Process State */
- enum gpp_proc_res_state res_state;
-
- /* Handle to Processor */
- void *processor;
-
- /* DSP Node resources */
- struct idr *node_id;
-
- /* DMM mapped memory resources */
- struct list_head dmm_map_list;
- spinlock_t dmm_map_lock;
-
- /* DMM reserved memory resources */
- struct list_head dmm_rsv_list;
- spinlock_t dmm_rsv_lock;
-
- /* Stream resources */
- struct idr *stream_id;
-};
-
-/*
- * ======== drv_create ========
- * Purpose:
- * Creates the Driver Object. This is done during the driver loading.
- * There is only one Driver Object in the DSP/BIOS Bridge.
- * Parameters:
- * drv_obj: Location to store created DRV Object handle.
- * Returns:
- * 0: Success
- * -ENOMEM: Failed in Memory allocation
- * -EPERM: General Failure
- * Requires:
- * DRV Initialized (refs > 0 )
- * drv_obj != NULL.
- * Ensures:
- * 0: - *drv_obj is a valid DRV interface to the device.
- * - List of DevObject Created and Initialized.
- * - List of dev_node String created and initialized.
- * - Registry is updated with the DRV Object.
- * !0: DRV Object not created
- * Details:
- * There is one Driver Object for the Driver representing
- * the driver itself. It contains the list of device
- * Objects and the list of Device Extensions in the system.
- * Also it can hold other necessary
- * information in its storage area.
- */
-extern int drv_create(struct drv_object **drv_obj);
-
-/*
- * ======== drv_destroy ========
- * Purpose:
- * destroys the Dev Object list, DrvExt list
- * and destroy the DRV object
- * Called upon driver unLoading.or unsuccessful loading of the driver.
- * Parameters:
- * driver_obj: Handle to Driver object .
- * Returns:
- * 0: Success.
- * -EPERM: Failed to destroy DRV Object
- * Requires:
- * DRV Initialized (cRegs > 0 )
- * hdrv_obj is not NULL and a valid DRV handle .
- * List of DevObject is Empty.
- * List of DrvExt is Empty
- * Ensures:
- * 0: - DRV Object destroyed and hdrv_obj is not a valid
- * DRV handle.
- * - Registry is updated with "0" as the DRV Object.
- */
-extern int drv_destroy(struct drv_object *driver_obj);
-
-/*
- * ======== drv_get_first_dev_object ========
- * Purpose:
- * Returns the Ptr to the FirstDev Object in the List
- * Parameters:
- * Requires:
- * DRV Initialized
- * Returns:
- * dw_dev_object: Ptr to the First Dev Object as a u32
- * 0 if it fails to retrieve the First Dev Object
- * Ensures:
- */
-extern u32 drv_get_first_dev_object(void);
-
-/*
- * ======== drv_get_first_dev_extension ========
- * Purpose:
- * Returns the Ptr to the First Device Extension in the List
- * Parameters:
- * Requires:
- * DRV Initialized
- * Returns:
- * dw_dev_extension: Ptr to the First Device Extension as a u32
- * 0: Failed to Get the Device Extension
- * Ensures:
- */
-extern u32 drv_get_first_dev_extension(void);
-
-/*
- * ======== drv_get_dev_object ========
- * Purpose:
- * Given a index, returns a handle to DevObject from the list
- * Parameters:
- * hdrv_obj: Handle to the Manager
- * device_obj: Location to store the Dev Handle
- * Requires:
- * DRV Initialized
- * index >= 0
- * hdrv_obj is not NULL and Valid DRV Object
- * device_obj is not NULL
- * Device Object List not Empty
- * Returns:
- * 0: Success
- * -EPERM: Failed to Get the Dev Object
- * Ensures:
- * 0: *device_obj != NULL
- * -EPERM: *device_obj = NULL
- */
-extern int drv_get_dev_object(u32 index,
- struct drv_object *hdrv_obj,
- struct dev_object **device_obj);
-
-/*
- * ======== drv_get_next_dev_object ========
- * Purpose:
- * Returns the Ptr to the Next Device Object from the the List
- * Parameters:
- * hdev_obj: Handle to the Device Object
- * Requires:
- * DRV Initialized
- * hdev_obj != 0
- * Returns:
- * dw_dev_object: Ptr to the Next Dev Object as a u32
- * 0: If it fail to get the next Dev Object.
- * Ensures:
- */
-extern u32 drv_get_next_dev_object(u32 hdev_obj);
-
-/*
- * ======== drv_get_next_dev_extension ========
- * Purpose:
- * Returns the Ptr to the Next Device Extension from the the List
- * Parameters:
- * dev_extension: Handle to the Device Extension
- * Requires:
- * DRV Initialized
- * dev_extension != 0.
- * Returns:
- * dw_dev_extension: Ptr to the Next Dev Extension
- * 0: If it fail to Get the next Dev Extension
- * Ensures:
- */
-extern u32 drv_get_next_dev_extension(u32 dev_extension);
-
-/*
- * ======== drv_insert_dev_object ========
- * Purpose:
- * Insert a DeviceObject into the list of Driver object.
- * Parameters:
- * driver_obj: Handle to DrvObject
- * hdev_obj: Handle to DeviceObject to insert.
- * Returns:
- * 0: If successful.
- * -EPERM: General Failure:
- * Requires:
- * hdrv_obj != NULL and Valid DRV Handle.
- * hdev_obj != NULL.
- * Ensures:
- * 0: Device Object is inserted and the List is not empty.
- */
-extern int drv_insert_dev_object(struct drv_object *driver_obj,
- struct dev_object *hdev_obj);
-
-/*
- * ======== drv_remove_dev_object ========
- * Purpose:
- * Search for and remove a Device object from the given list of Device Obj
- * objects.
- * Parameters:
- * driver_obj: Handle to DrvObject
- * hdev_obj: Handle to DevObject to Remove
- * Returns:
- * 0: Success.
- * -EPERM: Unable to find dev_obj.
- * Requires:
- * hdrv_obj != NULL and a Valid DRV Handle.
- * hdev_obj != NULL.
- * List exists and is not empty.
- * Ensures:
- * List either does not exist (NULL), or is not empty if it does exist.
- */
-extern int drv_remove_dev_object(struct drv_object *driver_obj,
- struct dev_object *hdev_obj);
-
-/*
- * ======== drv_request_resources ========
- * Purpose:
- * Assigns the Resources or Releases them.
- * Parameters:
- * dw_context: Path to the driver Registry Key.
- * dev_node_strg: Ptr to dev_node String stored in the Device Ext.
- * Returns:
- * TRUE if success; FALSE otherwise.
- * Requires:
- * Ensures:
- * The Resources are assigned based on Bus type.
- * The hardware is initialized. Resource information is
- * gathered from the Registry(ISA, PCMCIA)or scanned(PCI)
- * Resource structure is stored in the registry which will be
- * later used by the CFG module.
- */
-extern int drv_request_resources(u32 dw_context,
- u32 *dev_node_strg);
-
-/*
- * ======== drv_release_resources ========
- * Purpose:
- * Assigns the Resources or Releases them.
- * Parameters:
- * dw_context: Path to the driver Registry Key.
- * hdrv_obj: Handle to the Driver Object.
- * Returns:
- * TRUE if success; FALSE otherwise.
- * Requires:
- * Ensures:
- * The Resources are released based on Bus type.
- * Resource structure is deleted from the registry
- */
-extern int drv_release_resources(u32 dw_context,
- struct drv_object *hdrv_obj);
-
-/**
- * drv_request_bridge_res_dsp() - Reserves shared memory for bridge.
- * @phost_resources: pointer to host resources.
- */
-int drv_request_bridge_res_dsp(void **phost_resources);
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-void bridge_recover_schedule(void);
-#endif
-
-/*
- * ======== mem_ext_phys_pool_init ========
- * Purpose:
- * Uses the physical memory chunk passed for internal consistent memory
- * allocations.
- * physical address based on the page frame address.
- * Parameters:
- * pool_phys_base starting address of the physical memory pool.
- * pool_size size of the physical memory pool.
- * Returns:
- * none.
- * Requires:
- * - MEM initialized.
- * - valid physical address for the base and size > 0
- */
-extern void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size);
-
-/*
- * ======== mem_ext_phys_pool_release ========
- */
-extern void mem_ext_phys_pool_release(void);
-
-/* ======== mem_alloc_phys_mem ========
- * Purpose:
- * Allocate physically contiguous, uncached memory
- * Parameters:
- * byte_size: Number of bytes to allocate.
- * align_mask: Alignment Mask.
- * physical_address: Physical address of allocated memory.
- * Returns:
- * Pointer to a block of memory;
- * NULL if memory couldn't be allocated, or if byte_size == 0.
- * Requires:
- * MEM initialized.
- * Ensures:
- * The returned pointer, if not NULL, points to a valid memory block of
- * the size requested. Returned physical address refers to physical
- * location of memory.
- */
-extern void *mem_alloc_phys_mem(u32 byte_size,
- u32 align_mask, u32 *physical_address);
-
-/*
- * ======== mem_free_phys_mem ========
- * Purpose:
- * Free the given block of physically contiguous memory.
- * Parameters:
- * virtual_address: Pointer to virtual memory region allocated
- * by mem_alloc_phys_mem().
- * physical_address: Pointer to physical memory region allocated
- * by mem_alloc_phys_mem().
- * byte_size: Size of the memory region allocated by mem_alloc_phys_mem().
- * Returns:
- * Requires:
- * MEM initialized.
- * virtual_address is a valid memory address returned by
- * mem_alloc_phys_mem()
- * Ensures:
- * virtual_address is no longer a valid pointer to memory.
- */
-extern void mem_free_phys_mem(void *virtual_address,
- u32 physical_address, u32 byte_size);
-
-/*
- * ======== MEM_LINEAR_ADDRESS ========
- * Purpose:
- * Get the linear address corresponding to the given physical address.
- * Parameters:
- * phys_addr: Physical address to be mapped.
- * byte_size: Number of bytes in physical range to map.
- * Returns:
- * The corresponding linear address, or NULL if unsuccessful.
- * Requires:
- * MEM initialized.
- * Ensures:
- * Notes:
- * If valid linear address is returned, be sure to call
- * MEM_UNMAP_LINEAR_ADDRESS().
- */
-#define MEM_LINEAR_ADDRESS(phy_addr, byte_size) phy_addr
-
-/*
- * ======== MEM_UNMAP_LINEAR_ADDRESS ========
- * Purpose:
- * Unmap the linear address mapped in MEM_LINEAR_ADDRESS.
- * Parameters:
- * base_addr: Ptr to mapped memory (as returned by MEM_LINEAR_ADDRESS()).
- * Returns:
- * Requires:
- * - MEM initialized.
- * - base_addr is a valid linear address mapped in MEM_LINEAR_ADDRESS.
- * Ensures:
- * - base_addr no longer points to a valid linear address.
- */
-#define MEM_UNMAP_LINEAR_ADDRESS(base_addr) {}
-
-#endif /* DRV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h
deleted file mode 100644
index 6ff808297c10..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * dspapi-ioctl.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Contains structures and commands that are used for interaction
- * between the DDSP API and Bridge driver.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPAPIIOCTL_
-#define DSPAPIIOCTL_
-
-#include <dspbridge/cmm.h>
-#include <dspbridge/strmdefs.h>
-#include <dspbridge/dbdcd.h>
-
-union trapped_args {
-
- /* MGR Module */
- struct {
- u32 node_id;
- struct dsp_ndbprops __user *ndb_props;
- u32 ndb_props_size;
- u32 __user *num_nodes;
- } args_mgr_enumnode_info;
-
- struct {
- u32 processor_id;
- struct dsp_processorinfo __user *processor_info;
- u32 processor_info_size;
- u32 __user *num_procs;
- } args_mgr_enumproc_info;
-
- struct {
- struct dsp_uuid *uuid_obj;
- enum dsp_dcdobjtype obj_type;
- char *sz_path_name;
- } args_mgr_registerobject;
-
- struct {
- struct dsp_uuid *uuid_obj;
- enum dsp_dcdobjtype obj_type;
- } args_mgr_unregisterobject;
-
- struct {
- struct dsp_notification __user *__user *anotifications;
- u32 count;
- u32 __user *index;
- u32 timeout;
- } args_mgr_wait;
-
- /* PROC Module */
- struct {
- u32 processor_id;
- struct dsp_processorattrin __user *attr_in;
- void *__user *ph_processor;
- } args_proc_attach;
-
- struct {
- void *processor;
- u32 cmd;
- struct dsp_cbdata __user *args;
- } args_proc_ctrl;
-
- struct {
- void *processor;
- } args_proc_detach;
-
- struct {
- void *processor;
- void *__user *node_tab;
- u32 node_tab_size;
- u32 __user *num_nodes;
- u32 __user *allocated;
- } args_proc_enumnode_info;
-
- struct {
- void *processor;
- u32 resource_type;
- struct dsp_resourceinfo *resource_info;
- u32 resource_info_size;
- } args_proc_enumresources;
-
- struct {
- void *processor;
- struct dsp_processorstate __user *proc_state_obj;
- u32 state_info_size;
- } args_proc_getstate;
-
- struct {
- void *processor;
- u8 __user *buf;
- u8 __user *size;
- u32 max_size;
- } args_proc_gettrace;
-
- struct {
- void *processor;
- s32 argc_index;
- char __user *__user *user_args;
- char *__user *user_envp;
- } args_proc_load;
-
- struct {
- void *processor;
- u32 event_mask;
- u32 notify_type;
- struct dsp_notification __user *notification;
- } args_proc_register_notify;
-
- struct {
- void *processor;
- u32 size;
- void *__user *rsv_addr;
- } args_proc_rsvmem;
-
- struct {
- void *processor;
- u32 size;
- void *rsv_addr;
- } args_proc_unrsvmem;
-
- struct {
- void *processor;
- void *mpu_addr;
- u32 size;
- void *req_addr;
- void *__user *map_addr;
- u32 map_attr;
- } args_proc_mapmem;
-
- struct {
- void *processor;
- u32 size;
- void *map_addr;
- } args_proc_unmapmem;
-
- struct {
- void *processor;
- void *mpu_addr;
- u32 size;
- u32 dir;
- } args_proc_dma;
-
- struct {
- void *processor;
- void *mpu_addr;
- u32 size;
- u32 flags;
- } args_proc_flushmemory;
-
- struct {
- void *processor;
- void *mpu_addr;
- u32 size;
- } args_proc_invalidatememory;
-
- /* NODE Module */
- struct {
- void *processor;
- struct dsp_uuid __user *node_id_ptr;
- struct dsp_cbdata __user *args;
- struct dsp_nodeattrin __user *attr_in;
- void *__user *node;
- } args_node_allocate;
-
- struct {
- void *node;
- u32 size;
- struct dsp_bufferattr __user *attr;
- u8 *__user *buffer;
- } args_node_allocmsgbuf;
-
- struct {
- void *node;
- s32 prio;
- } args_node_changepriority;
-
- struct {
- void *node;
- u32 stream_id;
- void *other_node;
- u32 other_stream;
- struct dsp_strmattr __user *attrs;
- struct dsp_cbdata __user *conn_param;
- } args_node_connect;
-
- struct {
- void *node;
- } args_node_create;
-
- struct {
- void *node;
- } args_node_delete;
-
- struct {
- void *node;
- struct dsp_bufferattr __user *attr;
- u8 *buffer;
- } args_node_freemsgbuf;
-
- struct {
- void *node;
- struct dsp_nodeattr __user *attr;
- u32 attr_size;
- } args_node_getattr;
-
- struct {
- void *node;
- struct dsp_msg __user *message;
- u32 timeout;
- } args_node_getmessage;
-
- struct {
- void *node;
- } args_node_pause;
-
- struct {
- void *node;
- struct dsp_msg __user *message;
- u32 timeout;
- } args_node_putmessage;
-
- struct {
- void *node;
- u32 event_mask;
- u32 notify_type;
- struct dsp_notification __user *notification;
- } args_node_registernotify;
-
- struct {
- void *node;
- } args_node_run;
-
- struct {
- void *node;
- int __user *status;
- } args_node_terminate;
-
- struct {
- void *processor;
- struct dsp_uuid __user *node_id_ptr;
- struct dsp_ndbprops __user *node_props;
- } args_node_getuuidprops;
-
- /* STRM module */
-
- struct {
- void *stream;
- u32 size;
- u8 *__user *ap_buffer;
- u32 num_bufs;
- } args_strm_allocatebuffer;
-
- struct {
- void *stream;
- } args_strm_close;
-
- struct {
- void *stream;
- u8 *__user *ap_buffer;
- u32 num_bufs;
- } args_strm_freebuffer;
-
- struct {
- void *stream;
- void **event;
- } args_strm_geteventhandle;
-
- struct {
- void *stream;
- struct stream_info __user *stream_info;
- u32 stream_info_size;
- } args_strm_getinfo;
-
- struct {
- void *stream;
- bool flush_flag;
- } args_strm_idle;
-
- struct {
- void *stream;
- u8 *buffer;
- u32 bytes;
- u32 buf_size;
- u32 arg;
- } args_strm_issue;
-
- struct {
- void *node;
- u32 direction;
- u32 index;
- struct strm_attr __user *attr_in;
- void *__user *stream;
- } args_strm_open;
-
- struct {
- void *stream;
- u8 *__user *buf_ptr;
- u32 __user *bytes;
- u32 __user *buf_size_ptr;
- u32 __user *arg;
- } args_strm_reclaim;
-
- struct {
- void *stream;
- u32 event_mask;
- u32 notify_type;
- struct dsp_notification __user *notification;
- } args_strm_registernotify;
-
- struct {
- void *__user *stream_tab;
- u32 strm_num;
- u32 __user *mask;
- u32 timeout;
- } args_strm_select;
-
- /* CMM Module */
- struct {
- struct cmm_object *cmm_mgr;
- u32 size;
- struct cmm_attrs *attrs;
- void **buf_va;
- } args_cmm_allocbuf;
-
- struct {
- struct cmm_object *cmm_mgr;
- void *buf_pa;
- u32 seg_id;
- } args_cmm_freebuf;
-
- struct {
- void *processor;
- struct cmm_object *__user *cmm_mgr;
- } args_cmm_gethandle;
-
- struct {
- struct cmm_object *cmm_mgr;
- struct cmm_info __user *cmm_info_obj;
- } args_cmm_getinfo;
-
- /* UTIL module */
- struct {
- s32 util_argc;
- char **argv;
- } args_util_testdll;
-};
-
-/*
- * Dspbridge Ioctl numbering scheme
- *
- * 7 0
- * ---------------------------------
- * | Module | Ioctl Number |
- * ---------------------------------
- * | x | x | x | 0 | 0 | 0 | 0 | 0 |
- * ---------------------------------
- */
-
-/* Ioctl driver identifier */
-#define DB 0xDB
-
-/*
- * Following are used to distinguish between module ioctls, this is needed
- * in case new ioctls are introduced.
- */
-#define DB_MODULE_MASK 0xE0
-#define DB_IOC_MASK 0x1F
-
-/* Ioctl module masks */
-#define DB_MGR 0x0
-#define DB_PROC 0x20
-#define DB_NODE 0x40
-#define DB_STRM 0x60
-#define DB_CMM 0x80
-
-#define DB_MODULE_SHIFT 5
-
-/* Used to calculate the ioctl per dspbridge module */
-#define DB_IOC(module, num) \
- (((module) & DB_MODULE_MASK) | ((num) & DB_IOC_MASK))
-/* Used to get dspbridge ioctl module */
-#define DB_GET_MODULE(cmd) ((cmd) & DB_MODULE_MASK)
-/* Used to get dspbridge ioctl number */
-#define DB_GET_IOC(cmd) ((cmd) & DB_IOC_MASK)
-
-/* TODO: Remove deprecated and not implemented */
-
-/* MGR Module */
-#define MGR_ENUMNODE_INFO _IOWR(DB, DB_IOC(DB_MGR, 0), unsigned long)
-#define MGR_ENUMPROC_INFO _IOWR(DB, DB_IOC(DB_MGR, 1), unsigned long)
-#define MGR_REGISTEROBJECT _IOWR(DB, DB_IOC(DB_MGR, 2), unsigned long)
-#define MGR_UNREGISTEROBJECT _IOWR(DB, DB_IOC(DB_MGR, 3), unsigned long)
-#define MGR_WAIT _IOWR(DB, DB_IOC(DB_MGR, 4), unsigned long)
-/* MGR_GET_PROC_RES Deprecated */
-#define MGR_GET_PROC_RES _IOR(DB, DB_IOC(DB_MGR, 5), unsigned long)
-
-/* PROC Module */
-#define PROC_ATTACH _IOWR(DB, DB_IOC(DB_PROC, 0), unsigned long)
-#define PROC_CTRL _IOR(DB, DB_IOC(DB_PROC, 1), unsigned long)
-/* PROC_DETACH Deprecated */
-#define PROC_DETACH _IOR(DB, DB_IOC(DB_PROC, 2), unsigned long)
-#define PROC_ENUMNODE _IOWR(DB, DB_IOC(DB_PROC, 3), unsigned long)
-#define PROC_ENUMRESOURCES _IOWR(DB, DB_IOC(DB_PROC, 4), unsigned long)
-#define PROC_GET_STATE _IOWR(DB, DB_IOC(DB_PROC, 5), unsigned long)
-#define PROC_GET_TRACE _IOWR(DB, DB_IOC(DB_PROC, 6), unsigned long)
-#define PROC_LOAD _IOW(DB, DB_IOC(DB_PROC, 7), unsigned long)
-#define PROC_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_PROC, 8), unsigned long)
-#define PROC_START _IOW(DB, DB_IOC(DB_PROC, 9), unsigned long)
-#define PROC_RSVMEM _IOWR(DB, DB_IOC(DB_PROC, 10), unsigned long)
-#define PROC_UNRSVMEM _IOW(DB, DB_IOC(DB_PROC, 11), unsigned long)
-#define PROC_MAPMEM _IOWR(DB, DB_IOC(DB_PROC, 12), unsigned long)
-#define PROC_UNMAPMEM _IOR(DB, DB_IOC(DB_PROC, 13), unsigned long)
-#define PROC_FLUSHMEMORY _IOW(DB, DB_IOC(DB_PROC, 14), unsigned long)
-#define PROC_STOP _IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long)
-#define PROC_INVALIDATEMEMORY _IOW(DB, DB_IOC(DB_PROC, 16), unsigned long)
-#define PROC_BEGINDMA _IOW(DB, DB_IOC(DB_PROC, 17), unsigned long)
-#define PROC_ENDDMA _IOW(DB, DB_IOC(DB_PROC, 18), unsigned long)
-
-/* NODE Module */
-#define NODE_ALLOCATE _IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long)
-#define NODE_ALLOCMSGBUF _IOWR(DB, DB_IOC(DB_NODE, 1), unsigned long)
-#define NODE_CHANGEPRIORITY _IOW(DB, DB_IOC(DB_NODE, 2), unsigned long)
-#define NODE_CONNECT _IOW(DB, DB_IOC(DB_NODE, 3), unsigned long)
-#define NODE_CREATE _IOW(DB, DB_IOC(DB_NODE, 4), unsigned long)
-#define NODE_DELETE _IOW(DB, DB_IOC(DB_NODE, 5), unsigned long)
-#define NODE_FREEMSGBUF _IOW(DB, DB_IOC(DB_NODE, 6), unsigned long)
-#define NODE_GETATTR _IOWR(DB, DB_IOC(DB_NODE, 7), unsigned long)
-#define NODE_GETMESSAGE _IOWR(DB, DB_IOC(DB_NODE, 8), unsigned long)
-#define NODE_PAUSE _IOW(DB, DB_IOC(DB_NODE, 9), unsigned long)
-#define NODE_PUTMESSAGE _IOW(DB, DB_IOC(DB_NODE, 10), unsigned long)
-#define NODE_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_NODE, 11), unsigned long)
-#define NODE_RUN _IOW(DB, DB_IOC(DB_NODE, 12), unsigned long)
-#define NODE_TERMINATE _IOWR(DB, DB_IOC(DB_NODE, 13), unsigned long)
-#define NODE_GETUUIDPROPS _IOWR(DB, DB_IOC(DB_NODE, 14), unsigned long)
-
-/* STRM Module */
-#define STRM_ALLOCATEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 0), unsigned long)
-#define STRM_CLOSE _IOW(DB, DB_IOC(DB_STRM, 1), unsigned long)
-#define STRM_FREEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 2), unsigned long)
-#define STRM_GETEVENTHANDLE _IO(DB, DB_IOC(DB_STRM, 3)) /* Not Impl'd */
-#define STRM_GETINFO _IOWR(DB, DB_IOC(DB_STRM, 4), unsigned long)
-#define STRM_IDLE _IOW(DB, DB_IOC(DB_STRM, 5), unsigned long)
-#define STRM_ISSUE _IOW(DB, DB_IOC(DB_STRM, 6), unsigned long)
-#define STRM_OPEN _IOWR(DB, DB_IOC(DB_STRM, 7), unsigned long)
-#define STRM_RECLAIM _IOWR(DB, DB_IOC(DB_STRM, 8), unsigned long)
-#define STRM_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_STRM, 9), unsigned long)
-#define STRM_SELECT _IOWR(DB, DB_IOC(DB_STRM, 10), unsigned long)
-
-/* CMM Module */
-#define CMM_ALLOCBUF _IO(DB, DB_IOC(DB_CMM, 0)) /* Not Impl'd */
-#define CMM_FREEBUF _IO(DB, DB_IOC(DB_CMM, 1)) /* Not Impl'd */
-#define CMM_GETHANDLE _IOR(DB, DB_IOC(DB_CMM, 2), unsigned long)
-#define CMM_GETINFO _IOR(DB, DB_IOC(DB_CMM, 3), unsigned long)
-
-#endif /* DSPAPIIOCTL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi.h
deleted file mode 100644
index c99c68738b0f..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspapi.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * dspapi.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Includes the wrapper functions called directly by the
- * DeviceIOControl interface.
- *
- * Notes:
- * Bridge services exported to Bridge driver are initialized by the DSPAPI on
- * behalf of the Bridge driver. Bridge driver must not call module Init/Exit
- * functions.
- *
- * To ensure Bridge driver binary compatibility across different platforms,
- * for the same processor, a Bridge driver must restrict its usage of system
- * services to those exported by the DSPAPI library.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPAPI_
-#define DSPAPI_
-
-#include <dspbridge/dspapi-ioctl.h>
-
-/* This BRD API Library Version: */
-#define BRD_API_MAJOR_VERSION (u32)8 /* .8x - Alpha, .9x - Beta, 1.x FCS */
-#define BRD_API_MINOR_VERSION (u32)0
-
-/*
- * ======== api_call_dev_ioctl ========
- * Purpose:
- * Call the (wrapper) function for the corresponding API IOCTL.
- * Parameters:
- * cmd: IOCTL id, base 0.
- * args: Argument structure.
- * result:
- * Returns:
- * 0 if command called; -EINVAL if command not in IOCTL
- * table.
- * Requires:
- * Ensures:
- */
-extern int api_call_dev_ioctl(unsigned int cmd,
- union trapped_args *args,
- u32 *result, void *pr_ctxt);
-
-/*
- * ======== api_init ========
- * Purpose:
- * Initialize modules used by Bridge API.
- * This procedure is called when the driver is loaded.
- * Parameters:
- * Returns:
- * TRUE if success; FALSE otherwise.
- * Requires:
- * Ensures:
- */
-extern bool api_init(void);
-
-/*
- * ======== api_init_complete2 ========
- * Purpose:
- * Perform any required bridge initialization which cannot
- * be performed in api_init() or dev_start_device() due
- * to the fact that some services are not yet
- * completely initialized.
- * Parameters:
- * Returns:
- * 0: Allow this device to load
- * -EPERM: Failure.
- * Requires:
- * Bridge API initialized.
- * Ensures:
- */
-extern int api_init_complete2(void);
-
-/*
- * ======== api_exit ========
- * Purpose:
- * Exit all modules initialized in api_init(void).
- * This procedure is called when the driver is unloaded.
- * Parameters:
- * Returns:
- * Requires:
- * api_init(void) was previously called.
- * Ensures:
- * Resources acquired in api_init(void) are freed.
- */
-extern void api_exit(void);
-
-/* MGR wrapper functions */
-extern u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt);
-extern u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt);
-extern u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt);
-extern u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt);
-extern u32 mgrwrap_wait_for_bridge_events(union trapped_args *args,
- void *pr_ctxt);
-
-extern u32 mgrwrap_get_process_resources_info(union trapped_args *args,
- void *pr_ctxt);
-
-/* CPRC (Processor) wrapper Functions */
-extern u32 procwrap_attach(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_detach(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_load(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_start(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_map(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_stop(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt);
-extern u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt);
-
-/* NODE wrapper functions */
-extern u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_create(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_run(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt);
-extern u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt);
-
-/* STRM wrapper functions */
-extern u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_close(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_get_event_handle(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_open(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt);
-extern u32 strmwrap_select(union trapped_args *args, void *pr_ctxt);
-
-extern u32 cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt);
-extern u32 cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt);
-extern u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt);
-extern u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt);
-
-#endif /* DSPAPI_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h b/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h
deleted file mode 100644
index 7146a5057e29..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspchnl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * dspchnl.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Declares the upper edge channel class library functions required by
- * all Bridge driver / DSP API driver interface tables. These functions are
- * implemented by every class of Bridge channel library.
- *
- * Notes:
- * The function comment headers reside in dspdefs.h.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPCHNL_
-#define DSPCHNL_
-
-extern int bridge_chnl_create(struct chnl_mgr **channel_mgr,
- struct dev_object *hdev_obj,
- const struct chnl_mgrattrs
- *mgr_attrts);
-
-extern int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr);
-
-extern int bridge_chnl_open(struct chnl_object **chnl,
- struct chnl_mgr *hchnl_mgr,
- s8 chnl_mode,
- u32 ch_id,
- const struct chnl_attr
- *pattrs);
-
-extern int bridge_chnl_close(struct chnl_object *chnl_obj);
-
-extern int bridge_chnl_add_io_req(struct chnl_object *chnl_obj,
- void *host_buf,
- u32 byte_size, u32 buf_size,
- u32 dw_dsp_addr, u32 dw_arg);
-
-extern int bridge_chnl_get_ioc(struct chnl_object *chnl_obj,
- u32 timeout, struct chnl_ioc *chan_ioc);
-
-extern int bridge_chnl_cancel_io(struct chnl_object *chnl_obj);
-
-extern int bridge_chnl_flush_io(struct chnl_object *chnl_obj,
- u32 timeout);
-
-extern int bridge_chnl_get_info(struct chnl_object *chnl_obj,
- struct chnl_info *channel_info);
-
-extern int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr,
- u32 ch_id, struct chnl_mgrinfo
- *mgr_info);
-
-extern int bridge_chnl_idle(struct chnl_object *chnl_obj,
- u32 timeout, bool flush_data);
-
-extern int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
- u32 event_mask,
- u32 notify_type,
- struct dsp_notification
- *hnotification);
-
-#endif /* DSPCHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
deleted file mode 100644
index ed32bf383132..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
- * dspdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Bridge driver entry point and interface function declarations.
- *
- * Notes:
- * The DSP API obtains it's function interface to
- * the Bridge driver via a call to bridge_drv_entry().
- *
- * Bridge services exported to Bridge drivers are initialized by the
- * DSP API on behalf of the Bridge driver.
- *
- * Bridge function DBC Requires and Ensures are also made by the DSP API on
- * behalf of the Bridge driver, to simplify the Bridge driver code.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPDEFS_
-#define DSPDEFS_
-
-#include <dspbridge/brddefs.h>
-#include <dspbridge/cfgdefs.h>
-#include <dspbridge/chnlpriv.h>
-#include <dspbridge/dspdeh.h>
-#include <dspbridge/devdefs.h>
-#include <dspbridge/io.h>
-#include <dspbridge/msgdefs.h>
-
-/* Handle to Bridge driver's private device context. */
-struct bridge_dev_context;
-
-/*--------------------------------------------------------------------------- */
-/* BRIDGE DRIVER FUNCTION TYPES */
-/*--------------------------------------------------------------------------- */
-
-/*
- * ======== bridge_brd_monitor ========
- * Purpose:
- * Bring the board to the BRD_IDLE (monitor) state.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device context.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL
- * Ensures:
- * 0: Board is in BRD_IDLE state;
- * else: Board state is indeterminate.
- */
-typedef int(*fxn_brd_monitor) (struct bridge_dev_context *dev_ctxt);
-
-/*
- * ======== fxn_brd_setstate ========
- * Purpose:
- * Sets the Bridge driver state
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * brd_state: Board state
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * brd_state <= BRD_LASTSTATE.
- * Ensures:
- * brd_state <= BRD_LASTSTATE.
- * Update the Board state to the specified state.
- */
-typedef int(*fxn_brd_setstate) (struct bridge_dev_context
- * dev_ctxt, u32 brd_state);
-
-/*
- * ======== bridge_brd_start ========
- * Purpose:
- * Bring board to the BRD_RUNNING (start) state.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device context.
- * dsp_addr: DSP address at which to start execution.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL
- * Board is in monitor (BRD_IDLE) state.
- * Ensures:
- * 0: Board is in BRD_RUNNING state.
- * Interrupts to the PC are enabled.
- * else: Board state is indeterminate.
- */
-typedef int(*fxn_brd_start) (struct bridge_dev_context
- * dev_ctxt, u32 dsp_addr);
-
-/*
- * ======== bridge_brd_mem_copy ========
- * Purpose:
- * Copy memory from one DSP address to another
- * Parameters:
- * dev_context: Pointer to context handle
- * dsp_dest_addr: DSP address to copy to
- * dsp_src_addr: DSP address to copy from
- * ul_num_bytes: Number of bytes to copy
- * mem_type: What section of memory to copy to
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_context != NULL
- * Ensures:
- * 0: Board is in BRD_RUNNING state.
- * Interrupts to the PC are enabled.
- * else: Board state is indeterminate.
- */
-typedef int(*fxn_brd_memcopy) (struct bridge_dev_context
- * dev_ctxt,
- u32 dsp_dest_addr,
- u32 dsp_src_addr,
- u32 ul_num_bytes, u32 mem_type);
-/*
- * ======== bridge_brd_mem_write ========
- * Purpose:
- * Write a block of host memory into a DSP address, into a given memory
- * space. Unlike bridge_brd_write, this API does reset the DSP
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * dsp_addr: Address on DSP board (Destination).
- * host_buf: Pointer to host buffer (Source).
- * ul_num_bytes: Number of bytes to transfer.
- * mem_type: Memory space on DSP to which to transfer.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * host_buf != NULL.
- * Ensures:
- */
-typedef int(*fxn_brd_memwrite) (struct bridge_dev_context
- * dev_ctxt,
- u8 *host_buf,
- u32 dsp_addr, u32 ul_num_bytes,
- u32 mem_type);
-
-/*
- * ======== bridge_brd_mem_map ========
- * Purpose:
- * Map a MPU memory region to a DSP/IVA memory space
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * ul_mpu_addr: MPU memory region start address.
- * virt_addr: DSP/IVA memory region u8 address.
- * ul_num_bytes: Number of bytes to map.
- * map_attrs: Mapping attributes (e.g. endianness).
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * Ensures:
- */
-typedef int(*fxn_brd_memmap) (struct bridge_dev_context
- * dev_ctxt, u32 ul_mpu_addr,
- u32 virt_addr, u32 ul_num_bytes,
- u32 map_attr,
- struct page **mapped_pages);
-
-/*
- * ======== bridge_brd_mem_un_map ========
- * Purpose:
- * UnMap an MPU memory region from DSP/IVA memory space
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * virt_addr: DSP/IVA memory region u8 address.
- * ul_num_bytes: Number of bytes to unmap.
- * Returns:
- * 0: Success.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * Ensures:
- */
-typedef int(*fxn_brd_memunmap) (struct bridge_dev_context
- * dev_ctxt,
- u32 virt_addr, u32 ul_num_bytes);
-
-/*
- * ======== bridge_brd_stop ========
- * Purpose:
- * Bring board to the BRD_STOPPED state.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device context.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL
- * Ensures:
- * 0: Board is in BRD_STOPPED (stop) state;
- * Interrupts to the PC are disabled.
- * else: Board state is indeterminate.
- */
-typedef int(*fxn_brd_stop) (struct bridge_dev_context *dev_ctxt);
-
-/*
- * ======== bridge_brd_status ========
- * Purpose:
- * Report the current state of the board.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device context.
- * board_state: Ptr to BRD status variable.
- * Returns:
- * 0:
- * Requires:
- * board_state != NULL;
- * dev_ctxt != NULL
- * Ensures:
- * *board_state is one of
- * {BRD_STOPPED, BRD_IDLE, BRD_RUNNING, BRD_UNKNOWN};
- */
-typedef int(*fxn_brd_status) (struct bridge_dev_context *dev_ctxt,
- int *board_state);
-
-/*
- * ======== bridge_brd_read ========
- * Purpose:
- * Read a block of DSP memory, from a given memory space, into a host
- * buffer.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * host_buf: Pointer to host buffer (Destination).
- * dsp_addr: Address on DSP board (Source).
- * ul_num_bytes: Number of bytes to transfer.
- * mem_type: Memory space on DSP from which to transfer.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * host_buf != NULL.
- * Ensures:
- * Will not write more than ul_num_bytes bytes into host_buf.
- */
-typedef int(*fxn_brd_read) (struct bridge_dev_context *dev_ctxt,
- u8 *host_buf,
- u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type);
-
-/*
- * ======== bridge_brd_write ========
- * Purpose:
- * Write a block of host memory into a DSP address, into a given memory
- * space.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * dsp_addr: Address on DSP board (Destination).
- * host_buf: Pointer to host buffer (Source).
- * ul_num_bytes: Number of bytes to transfer.
- * mem_type: Memory space on DSP to which to transfer.
- * Returns:
- * 0: Success.
- * -ETIMEDOUT: Timeout occurred waiting for a response from hardware.
- * -EPERM: Other, unspecified error.
- * Requires:
- * dev_ctxt != NULL;
- * host_buf != NULL.
- * Ensures:
- */
-typedef int(*fxn_brd_write) (struct bridge_dev_context *dev_ctxt,
- u8 *host_buf,
- u32 dsp_addr,
- u32 ul_num_bytes, u32 mem_type);
-
-/*
- * ======== bridge_chnl_create ========
- * Purpose:
- * Create a channel manager object, responsible for opening new channels
- * and closing old ones for a given 'Bridge board.
- * Parameters:
- * channel_mgr: Location to store a channel manager object on output.
- * hdev_obj: Handle to a device object.
- * mgr_attrts: Channel manager attributes.
- * mgr_attrts->max_channels: Max channels
- * mgr_attrts->birq: Channel's I/O IRQ number.
- * mgr_attrts->irq_shared: TRUE if the IRQ is shareable.
- * mgr_attrts->word_size: DSP Word size in equivalent PC bytes..
- * mgr_attrts->shm_base: Base physical address of shared memory, if any.
- * mgr_attrts->sm_length: Bytes of shared memory block.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EIO: Unable to plug ISR for given IRQ.
- * -EFAULT: Couldn't map physical address to a virtual one.
- * Requires:
- * channel_mgr != NULL.
- * mgr_attrts != NULL
- * mgr_attrts field are all valid:
- * 0 < max_channels <= CHNL_MAXCHANNELS.
- * birq <= 15.
- * word_size > 0.
- * hdev_obj != NULL
- * No channel manager exists for this board.
- * Ensures:
- */
-typedef int(*fxn_chnl_create) (struct chnl_mgr
- **channel_mgr,
- struct dev_object
- * hdev_obj,
- const struct
- chnl_mgrattrs * mgr_attrts);
-
-/*
- * ======== bridge_chnl_destroy ========
- * Purpose:
- * Close all open channels, and destroy the channel manager.
- * Parameters:
- * hchnl_mgr: Channel manager object.
- * Returns:
- * 0: Success.
- * -EFAULT: hchnl_mgr was invalid.
- * Requires:
- * Ensures:
- * 0: Cancels I/O on each open channel. Closes each open channel.
- * chnl_create may subsequently be called for the same device.
- */
-typedef int(*fxn_chnl_destroy) (struct chnl_mgr *hchnl_mgr);
-/*
- * ======== bridge_deh_notify ========
- * Purpose:
- * When notified of DSP error, take appropriate action.
- * Parameters:
- * hdeh_mgr: Handle to DEH manager object.
- * evnt_mask: Indicate the type of exception
- * error_info: Error information
- * Returns:
- *
- * Requires:
- * hdeh_mgr != NULL;
- * evnt_mask with a valid exception
- * Ensures:
- */
-typedef void (*fxn_deh_notify) (struct deh_mgr *hdeh_mgr,
- u32 evnt_mask, u32 error_info);
-
-/*
- * ======== bridge_chnl_open ========
- * Purpose:
- * Open a new half-duplex channel to the DSP board.
- * Parameters:
- * chnl: Location to store a channel object handle.
- * hchnl_mgr: Handle to channel manager, as returned by
- * CHNL_GetMgr().
- * chnl_mode: One of {CHNL_MODETODSP, CHNL_MODEFROMDSP} specifies
- * direction of data transfer.
- * ch_id: If CHNL_PICKFREE is specified, the channel manager will
- * select a free channel id (default);
- * otherwise this field specifies the id of the channel.
- * pattrs: Channel attributes. Attribute fields are as follows:
- * pattrs->uio_reqs: Specifies the maximum number of I/O requests which can
- * be pending at any given time. All request packets are
- * preallocated when the channel is opened.
- * pattrs->event_obj: This field allows the user to supply an auto reset
- * event object for channel I/O completion notifications.
- * It is the responsibility of the user to destroy this
- * object AFTER closing the channel.
- * This channel event object can be retrieved using
- * CHNL_GetEventHandle().
- * pattrs->hReserved: The kernel mode handle of this event object.
- *
- * Returns:
- * 0: Success.
- * -EFAULT: hchnl_mgr is invalid.
- * -ENOMEM: Insufficient memory for requested resources.
- * -EINVAL: Invalid number of IOReqs.
- * -ENOSR: No free channels available.
- * -ECHRNG: Channel ID is out of range.
- * -EALREADY: Channel is in use.
- * -EIO: No free IO request packets available for
- * queuing.
- * Requires:
- * chnl != NULL.
- * pattrs != NULL.
- * pattrs->event_obj is a valid event handle.
- * pattrs->hReserved is the kernel mode handle for pattrs->event_obj.
- * Ensures:
- * 0: *chnl is a valid channel.
- * else: *chnl is set to NULL if (chnl != NULL);
- */
-typedef int(*fxn_chnl_open) (struct chnl_object
- **chnl,
- struct chnl_mgr *hchnl_mgr,
- s8 chnl_mode,
- u32 ch_id,
- const struct
- chnl_attr * pattrs);
-
-/*
- * ======== bridge_chnl_close ========
- * Purpose:
- * Ensures all pending I/O on this channel is cancelled, discards all
- * queued I/O completion notifications, then frees the resources allocated
- * for this channel, and makes the corresponding logical channel id
- * available for subsequent use.
- * Parameters:
- * chnl_obj: Handle to a channel object.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid chnl_obj.
- * Requires:
- * No thread must be blocked on this channel's I/O completion event.
- * Ensures:
- * 0: chnl_obj is no longer valid.
- */
-typedef int(*fxn_chnl_close) (struct chnl_object *chnl_obj);
-
-/*
- * ======== bridge_chnl_add_io_req ========
- * Purpose:
- * Enqueue an I/O request for data transfer on a channel to the DSP.
- * The direction (mode) is specified in the channel object. Note the DSP
- * address is specified for channels opened in direct I/O mode.
- * Parameters:
- * chnl_obj: Channel object handle.
- * host_buf: Host buffer address source.
- * byte_size: Number of PC bytes to transfer. A zero value indicates
- * that this buffer is the last in the output channel.
- * A zero value is invalid for an input channel.
- *! buf_size: Actual buffer size in host bytes.
- * dw_dsp_addr: DSP address for transfer. (Currently ignored).
- * dw_arg: A user argument that travels with the buffer.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid chnl_obj or host_buf.
- * -EPERM: User cannot mark EOS on an input channel.
- * -ECANCELED: I/O has been cancelled on this channel. No further
- * I/O is allowed.
- * -EPIPE: End of stream was already marked on a previous
- * IORequest on this channel. No further I/O is expected.
- * -EINVAL: Buffer submitted to this output channel is larger than
- * the size of the physical shared memory output window.
- * Requires:
- * Ensures:
- * 0: The buffer will be transferred if the channel is ready;
- * otherwise, will be queued for transfer when the channel becomes
- * ready. In any case, notifications of I/O completion are
- * asynchronous.
- * If byte_size is 0 for an output channel, subsequent CHNL_AddIOReq's
- * on this channel will fail with error code -EPIPE. The
- * corresponding IOC for this I/O request will have its status flag
- * set to CHNL_IOCSTATEOS.
- */
-typedef int(*fxn_chnl_addioreq) (struct chnl_object
- * chnl_obj,
- void *host_buf,
- u32 byte_size,
- u32 buf_size,
- u32 dw_dsp_addr, u32 dw_arg);
-
-/*
- * ======== bridge_chnl_get_ioc ========
- * Purpose:
- * Dequeue an I/O completion record, which contains information about the
- * completed I/O request.
- * Parameters:
- * chnl_obj: Channel object handle.
- * timeout: A value of CHNL_IOCNOWAIT will simply dequeue the
- * first available IOC.
- * chan_ioc: On output, contains host buffer address, bytes
- * transferred, and status of I/O completion.
- * chan_ioc->status: See chnldefs.h.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid chnl_obj or chan_ioc.
- * -EREMOTEIO: CHNL_IOCNOWAIT was specified as the timeout parameter
- * yet no I/O completions were queued.
- * Requires:
- * timeout == CHNL_IOCNOWAIT.
- * Ensures:
- * 0: if there are any remaining IOC's queued before this call
- * returns, the channel event object will be left in a signalled
- * state.
- */
-typedef int(*fxn_chnl_getioc) (struct chnl_object *chnl_obj,
- u32 timeout,
- struct chnl_ioc *chan_ioc);
-
-/*
- * ======== bridge_chnl_cancel_io ========
- * Purpose:
- * Return all I/O requests to the client which have not yet been
- * transferred. The channel's I/O completion object is
- * signalled, and all the I/O requests are queued as IOC's, with the
- * status field set to CHNL_IOCSTATCANCEL.
- * This call is typically used in abort situations, and is a prelude to
- * chnl_close();
- * Parameters:
- * chnl_obj: Channel object handle.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid chnl_obj.
- * Requires:
- * Ensures:
- * Subsequent I/O requests to this channel will not be accepted.
- */
-typedef int(*fxn_chnl_cancelio) (struct chnl_object *chnl_obj);
-
-/*
- * ======== bridge_chnl_flush_io ========
- * Purpose:
- * For an output stream (to the DSP), indicates if any IO requests are in
- * the output request queue. For input streams (from the DSP), will
- * cancel all pending IO requests.
- * Parameters:
- * chnl_obj: Channel object handle.
- * timeout: Timeout value for flush operation.
- * Returns:
- * 0: Success;
- * S_CHNLIOREQUEST: Returned if any IORequests are in the output queue.
- * -EFAULT: Invalid chnl_obj.
- * Requires:
- * Ensures:
- * 0: No I/O requests will be pending on this channel.
- */
-typedef int(*fxn_chnl_flushio) (struct chnl_object *chnl_obj,
- u32 timeout);
-
-/*
- * ======== bridge_chnl_get_info ========
- * Purpose:
- * Retrieve information related to a channel.
- * Parameters:
- * chnl_obj: Handle to a valid channel object, or NULL.
- * channel_info: Location to store channel info.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid chnl_obj or channel_info.
- * Requires:
- * Ensures:
- * 0: channel_info points to a filled in chnl_info struct,
- * if (channel_info != NULL).
- */
-typedef int(*fxn_chnl_getinfo) (struct chnl_object *chnl_obj,
- struct chnl_info *channel_info);
-
-/*
- * ======== bridge_chnl_get_mgr_info ========
- * Purpose:
- * Retrieve information related to the channel manager.
- * Parameters:
- * hchnl_mgr: Handle to a valid channel manager, or NULL.
- * ch_id: Channel ID.
- * mgr_info: Location to store channel manager info.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid hchnl_mgr or mgr_info.
- * -ECHRNG: Invalid channel ID.
- * Requires:
- * Ensures:
- * 0: mgr_info points to a filled in chnl_mgrinfo
- * struct, if (mgr_info != NULL).
- */
-typedef int(*fxn_chnl_getmgrinfo) (struct chnl_mgr
- * hchnl_mgr,
- u32 ch_id,
- struct chnl_mgrinfo *mgr_info);
-
-/*
- * ======== bridge_chnl_idle ========
- * Purpose:
- * Idle a channel. If this is an input channel, or if this is an output
- * channel and flush_data is TRUE, all currently enqueued buffers will be
- * dequeued (data discarded for output channel).
- * If this is an output channel and flush_data is FALSE, this function
- * will block until all currently buffered data is output, or the timeout
- * specified has been reached.
- *
- * Parameters:
- * chnl_obj: Channel object handle.
- * timeout: If output channel and flush_data is FALSE, timeout value
- * to wait for buffers to be output. (Not used for
- * input channel).
- * flush_data: If output channel and flush_data is TRUE, discard any
- * currently buffered data. If FALSE, wait for currently
- * buffered data to be output, or timeout, whichever
- * occurs first. flush_data is ignored for input channel.
- * Returns:
- * 0: Success;
- * -EFAULT: Invalid chnl_obj.
- * -ETIMEDOUT: Timeout occurred before channel could be idled.
- * Requires:
- * Ensures:
- */
-typedef int(*fxn_chnl_idle) (struct chnl_object *chnl_obj,
- u32 timeout, bool flush_data);
-
-/*
- * ======== bridge_chnl_register_notify ========
- * Purpose:
- * Register for notification of events on a channel.
- * Parameters:
- * chnl_obj: Channel object handle.
- * event_mask: Type of events to be notified about: IO completion
- * (DSP_STREAMIOCOMPLETION) or end of stream
- * (DSP_STREAMDONE).
- * notify_type: DSP_SIGNALEVENT.
- * hnotification: Handle of a dsp_notification object.
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory.
- * -EINVAL: event_mask is 0 and hnotification was not
- * previously registered.
- * -EFAULT: NULL hnotification, hnotification event name
- * too long, or hnotification event name NULL.
- * Requires:
- * Valid chnl_obj.
- * hnotification != NULL.
- * (event_mask & ~(DSP_STREAMIOCOMPLETION | DSP_STREAMDONE)) == 0.
- * notify_type == DSP_SIGNALEVENT.
- * Ensures:
- */
-typedef int(*fxn_chnl_registernotify)
- (struct chnl_object *chnl_obj,
- u32 event_mask, u32 notify_type, struct dsp_notification *hnotification);
-
-/*
- * ======== bridge_dev_create ========
- * Purpose:
- * Complete creation of the device object for this board.
- * Parameters:
- * device_ctx: Ptr to location to store a Bridge device context.
- * hdev_obj: Handle to a Device Object, created and managed by DSP API.
- * config_param: Ptr to configuration parameters provided by the
- * Configuration Manager during device loading.
- * pDspConfig: DSP resources, as specified in the registry key for this
- * device.
- * Returns:
- * 0: Success.
- * -ENOMEM: Unable to allocate memory for device context.
- * Requires:
- * device_ctx != NULL;
- * hdev_obj != NULL;
- * config_param != NULL;
- * pDspConfig != NULL;
- * Fields in config_param and pDspConfig contain valid values.
- * Ensures:
- * 0: All Bridge driver specific DSP resource and other
- * board context has been allocated.
- * -ENOMEM: Bridge failed to allocate resources.
- * Any acquired resources have been freed. The DSP API
- * will not call bridge_dev_destroy() if
- * bridge_dev_create() fails.
- * Details:
- * Called during the CONFIGMG's Device_Init phase. Based on host and
- * DSP configuration information, create a board context, a handle to
- * which is passed into other Bridge BRD and CHNL functions. The
- * board context contains state information for the device. Since the
- * addresses of all pointer parameters may be invalid when this
- * function returns, they must not be stored into the device context
- * structure.
- */
-typedef int(*fxn_dev_create) (struct bridge_dev_context
- **device_ctx,
- struct dev_object
- * hdev_obj,
- struct cfg_hostres
- * config_param);
-
-/*
- * ======== bridge_dev_ctrl ========
- * Purpose:
- * Bridge driver specific interface.
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device info.
- * dw_cmd: Bridge driver defined command code.
- * pargs: Pointer to an arbitrary argument structure.
- * Returns:
- * 0 or -EPERM. Actual command error codes should be passed back in
- * the pargs structure, and are defined by the Bridge driver implementor.
- * Requires:
- * All calls are currently assumed to be synchronous. There are no
- * IOCTL completion routines provided.
- * Ensures:
- */
-typedef int(*fxn_dev_ctrl) (struct bridge_dev_context *dev_ctxt,
- u32 dw_cmd, void *pargs);
-
-/*
- * ======== bridge_dev_destroy ========
- * Purpose:
- * Deallocate Bridge device extension structures and all other resources
- * acquired by the Bridge driver.
- * No calls to other Bridge driver functions may subsequently
- * occur, except for bridge_dev_create().
- * Parameters:
- * dev_ctxt: Handle to Bridge driver defined device information.
- * Returns:
- * 0: Success.
- * -EPERM: Failed to release a resource previously acquired.
- * Requires:
- * dev_ctxt != NULL;
- * Ensures:
- * 0: Device context is freed.
- */
-typedef int(*fxn_dev_destroy) (struct bridge_dev_context *dev_ctxt);
-
-/*
- * ======== bridge_io_create ========
- * Purpose:
- * Create an object that manages I/O between CHNL and msg_ctrl.
- * Parameters:
- * io_man: Location to store IO manager on output.
- * hchnl_mgr: Handle to channel manager.
- * hmsg_mgr: Handle to message manager.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failure.
- * -EPERM: Creation failed.
- * Requires:
- * hdev_obj != NULL;
- * Channel manager already created;
- * Message manager already created;
- * mgr_attrts != NULL;
- * io_man != NULL;
- * Ensures:
- */
-typedef int(*fxn_io_create) (struct io_mgr **io_man,
- struct dev_object *hdev_obj,
- const struct io_attrs *mgr_attrts);
-
-/*
- * ======== bridge_io_destroy ========
- * Purpose:
- * Destroy object created in bridge_io_create.
- * Parameters:
- * hio_mgr: IO Manager.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failure.
- * -EPERM: Creation failed.
- * Requires:
- * Valid hio_mgr;
- * Ensures:
- */
-typedef int(*fxn_io_destroy) (struct io_mgr *hio_mgr);
-
-/*
- * ======== bridge_io_on_loaded ========
- * Purpose:
- * Called whenever a program is loaded to update internal data. For
- * example, if shared memory is used, this function would update the
- * shared memory location and address.
- * Parameters:
- * hio_mgr: IO Manager.
- * Returns:
- * 0: Success.
- * -EPERM: Internal failure occurred.
- * Requires:
- * Valid hio_mgr;
- * Ensures:
- */
-typedef int(*fxn_io_onloaded) (struct io_mgr *hio_mgr);
-
-/*
- * ======== fxn_io_getprocload ========
- * Purpose:
- * Called to get the Processor's current and predicted load
- * Parameters:
- * hio_mgr: IO Manager.
- * proc_load_stat Processor Load statistics
- * Returns:
- * 0: Success.
- * -EPERM: Internal failure occurred.
- * Requires:
- * Valid hio_mgr;
- * Ensures:
- */
-typedef int(*fxn_io_getprocload) (struct io_mgr *hio_mgr,
- struct dsp_procloadstat *
- proc_load_stat);
-
-/*
- * ======== bridge_msg_create ========
- * Purpose:
- * Create an object to manage message queues. Only one of these objects
- * can exist per device object.
- * Parameters:
- * msg_man: Location to store msg_ctrl manager on output.
- * hdev_obj: Handle to a device object.
- * msg_callback: Called whenever an RMS_EXIT message is received.
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory.
- * Requires:
- * msg_man != NULL.
- * msg_callback != NULL.
- * hdev_obj != NULL.
- * Ensures:
- */
-typedef int(*fxn_msg_create)
- (struct msg_mgr **msg_man,
- struct dev_object *hdev_obj, msg_onexit msg_callback);
-
-/*
- * ======== bridge_msg_create_queue ========
- * Purpose:
- * Create a msg_ctrl queue for sending or receiving messages from a Message
- * node on the DSP.
- * Parameters:
- * hmsg_mgr: msg_ctrl queue manager handle returned from
- * bridge_msg_create.
- * msgq: Location to store msg_ctrl queue on output.
- * msgq_id: Identifier for messages (node environment pointer).
- * max_msgs: Max number of simultaneous messages for the node.
- * h: Handle passed to hmsg_mgr->msg_callback().
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory.
- * Requires:
- * msgq != NULL.
- * h != NULL.
- * max_msgs > 0.
- * Ensures:
- * msgq !=NULL <==> 0.
- */
-typedef int(*fxn_msg_createqueue)
- (struct msg_mgr *hmsg_mgr,
- struct msg_queue **msgq, u32 msgq_id, u32 max_msgs, void *h);
-
-/*
- * ======== bridge_msg_delete ========
- * Purpose:
- * Delete a msg_ctrl manager allocated in bridge_msg_create().
- * Parameters:
- * hmsg_mgr: Handle returned from bridge_msg_create().
- * Returns:
- * Requires:
- * Valid hmsg_mgr.
- * Ensures:
- */
-typedef void (*fxn_msg_delete) (struct msg_mgr *hmsg_mgr);
-
-/*
- * ======== bridge_msg_delete_queue ========
- * Purpose:
- * Delete a msg_ctrl queue allocated in bridge_msg_create_queue.
- * Parameters:
- * msg_queue_obj: Handle to msg_ctrl queue returned from
- * bridge_msg_create_queue.
- * Returns:
- * Requires:
- * Valid msg_queue_obj.
- * Ensures:
- */
-typedef void (*fxn_msg_deletequeue) (struct msg_queue *msg_queue_obj);
-
-/*
- * ======== bridge_msg_get ========
- * Purpose:
- * Get a message from a msg_ctrl queue.
- * Parameters:
- * msg_queue_obj: Handle to msg_ctrl queue returned from
- * bridge_msg_create_queue.
- * pmsg: Location to copy message into.
- * utimeout: Timeout to wait for a message.
- * Returns:
- * 0: Success.
- * -ETIME: Timeout occurred.
- * -EPERM: No frames available for message (max_msgs too
- * small).
- * Requires:
- * Valid msg_queue_obj.
- * pmsg != NULL.
- * Ensures:
- */
-typedef int(*fxn_msg_get) (struct msg_queue *msg_queue_obj,
- struct dsp_msg *pmsg, u32 utimeout);
-
-/*
- * ======== bridge_msg_put ========
- * Purpose:
- * Put a message onto a msg_ctrl queue.
- * Parameters:
- * msg_queue_obj: Handle to msg_ctrl queue returned from
- * bridge_msg_create_queue.
- * pmsg: Pointer to message.
- * utimeout: Timeout to wait for a message.
- * Returns:
- * 0: Success.
- * -ETIME: Timeout occurred.
- * -EPERM: No frames available for message (max_msgs too
- * small).
- * Requires:
- * Valid msg_queue_obj.
- * pmsg != NULL.
- * Ensures:
- */
-typedef int(*fxn_msg_put) (struct msg_queue *msg_queue_obj,
- const struct dsp_msg *pmsg, u32 utimeout);
-
-/*
- * ======== bridge_msg_register_notify ========
- * Purpose:
- * Register notification for when a message is ready.
- * Parameters:
- * msg_queue_obj: Handle to msg_ctrl queue returned from
- * bridge_msg_create_queue.
- * event_mask: Type of events to be notified about: Must be
- * DSP_NODEMESSAGEREADY, or 0 to unregister.
- * notify_type: DSP_SIGNALEVENT.
- * hnotification: Handle of notification object.
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory.
- * Requires:
- * Valid msg_queue_obj.
- * hnotification != NULL.
- * notify_type == DSP_SIGNALEVENT.
- * event_mask == DSP_NODEMESSAGEREADY || event_mask == 0.
- * Ensures:
- */
-typedef int(*fxn_msg_registernotify)
- (struct msg_queue *msg_queue_obj,
- u32 event_mask, u32 notify_type, struct dsp_notification *hnotification);
-
-/*
- * ======== bridge_msg_set_queue_id ========
- * Purpose:
- * Set message queue id to node environment. Allows bridge_msg_create_queue
- * to be called in node_allocate, before the node environment is known.
- * Parameters:
- * msg_queue_obj: Handle to msg_ctrl queue returned from
- * bridge_msg_create_queue.
- * msgq_id: Node environment pointer.
- * Returns:
- * Requires:
- * Valid msg_queue_obj.
- * msgq_id != 0.
- * Ensures:
- */
-typedef void (*fxn_msg_setqueueid) (struct msg_queue *msg_queue_obj,
- u32 msgq_id);
-
-/*
- * Bridge Driver interface function table.
- *
- * The information in this table is filled in by the specific Bridge driver,
- * and copied into the DSP API's own space. If any interface
- * function field is set to a value of NULL, then the DSP API will
- * consider that function not implemented, and return the error code
- * -ENOSYS when a Bridge driver client attempts to call that function.
- *
- * This function table contains DSP API version numbers, which are used by the
- * Bridge driver loader to help ensure backwards compatility between older
- * Bridge drivers and newer DSP API. These must be set to
- * BRD_API_MAJOR_VERSION and BRD_API_MINOR_VERSION, respectively.
- *
- * A Bridge driver need not export a CHNL interface. In this case, *all* of
- * the bridge_chnl_* entries must be set to NULL.
- */
-struct bridge_drv_interface {
- u32 brd_api_major_version; /* Set to BRD_API_MAJOR_VERSION. */
- u32 brd_api_minor_version; /* Set to BRD_API_MINOR_VERSION. */
- fxn_dev_create dev_create; /* Create device context */
- fxn_dev_destroy dev_destroy; /* Destroy device context */
- fxn_dev_ctrl dev_cntrl; /* Optional vendor interface */
- fxn_brd_monitor brd_monitor; /* Load and/or start monitor */
- fxn_brd_start brd_start; /* Start DSP program. */
- fxn_brd_stop brd_stop; /* Stop/reset board. */
- fxn_brd_status brd_status; /* Get current board status. */
- fxn_brd_read brd_read; /* Read board memory */
- fxn_brd_write brd_write; /* Write board memory. */
- fxn_brd_setstate brd_set_state; /* Sets the Board State */
- fxn_brd_memcopy brd_mem_copy; /* Copies DSP Memory */
- fxn_brd_memwrite brd_mem_write; /* Write DSP Memory w/o halt */
- fxn_brd_memmap brd_mem_map; /* Maps MPU mem to DSP mem */
- fxn_brd_memunmap brd_mem_un_map; /* Unmaps MPU mem to DSP mem */
- fxn_chnl_create chnl_create; /* Create channel manager. */
- fxn_chnl_destroy chnl_destroy; /* Destroy channel manager. */
- fxn_chnl_open chnl_open; /* Create a new channel. */
- fxn_chnl_close chnl_close; /* Close a channel. */
- fxn_chnl_addioreq chnl_add_io_req; /* Req I/O on a channel. */
- fxn_chnl_getioc chnl_get_ioc; /* Wait for I/O completion. */
- fxn_chnl_cancelio chnl_cancel_io; /* Cancl I/O on a channel. */
- fxn_chnl_flushio chnl_flush_io; /* Flush I/O. */
- fxn_chnl_getinfo chnl_get_info; /* Get channel specific info */
- /* Get channel manager info. */
- fxn_chnl_getmgrinfo chnl_get_mgr_info;
- fxn_chnl_idle chnl_idle; /* Idle the channel */
- /* Register for notif. */
- fxn_chnl_registernotify chnl_register_notify;
- fxn_io_create io_create; /* Create IO manager */
- fxn_io_destroy io_destroy; /* Destroy IO manager */
- fxn_io_onloaded io_on_loaded; /* Notify of program loaded */
- /* Get Processor's current and predicted load */
- fxn_io_getprocload io_get_proc_load;
- fxn_msg_create msg_create; /* Create message manager */
- /* Create message queue */
- fxn_msg_createqueue msg_create_queue;
- fxn_msg_delete msg_delete; /* Delete message manager */
- /* Delete message queue */
- fxn_msg_deletequeue msg_delete_queue;
- fxn_msg_get msg_get; /* Get a message */
- fxn_msg_put msg_put; /* Send a message */
- /* Register for notif. */
- fxn_msg_registernotify msg_register_notify;
- /* Set message queue id */
- fxn_msg_setqueueid msg_set_queue_id;
-};
-
-/*
- * ======== bridge_drv_entry ========
- * Purpose:
- * Registers Bridge driver functions with the DSP API. Called only once
- * by the DSP API. The caller will first check DSP API version
- * compatibility, and then copy the interface functions into its own
- * memory space.
- * Parameters:
- * drv_intf Pointer to a location to receive a pointer to the
- * Bridge driver interface.
- * Returns:
- * Requires:
- * The code segment this function resides in must expect to be discarded
- * after completion.
- * Ensures:
- * drv_intf pointer initialized to Bridge driver's function
- * interface. No system resources are acquired by this function.
- * Details:
- * Called during the Device_Init phase.
- */
-void bridge_drv_entry(struct bridge_drv_interface **drv_intf,
- const char *driver_file_name);
-
-#endif /* DSPDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h b/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h
deleted file mode 100644
index d258ab6a41d1..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdeh.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * dspdeh.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Defines upper edge DEH functions required by all Bridge driver/DSP API
- * interface tables.
- *
- * Notes:
- * Function comment headers reside with the function typedefs in dspdefs.h.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- * Copyright (C) 2010 Felipe Contreras
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPDEH_
-#define DSPDEH_
-
-struct deh_mgr;
-struct dev_object;
-struct dsp_notification;
-
-int bridge_deh_create(struct deh_mgr **ret_deh,
- struct dev_object *hdev_obj);
-
-int bridge_deh_destroy(struct deh_mgr *deh);
-
-int bridge_deh_register_notify(struct deh_mgr *deh,
- u32 event_mask,
- u32 notify_type,
- struct dsp_notification *hnotification);
-
-void bridge_deh_notify(struct deh_mgr *deh, int event, int info);
-
-#endif /* DSPDEH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h b/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h
deleted file mode 100644
index 7adf1e705314..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * dspdrv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This is the Stream Interface for the DSp API.
- * All Device operations are performed via DeviceIOControl.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if !defined _DSPDRV_H_
-#define _DSPDRV_H_
-
-/*
- * ======== dsp_deinit ========
- * Purpose:
- * This function is called by Device Manager to de-initialize a device.
- * This function is not called by applications.
- * Parameters:
- * device_context:Handle to the device context. The XXX_Init function
- * creates and returns this identifier.
- * Returns:
- * TRUE indicates the device successfully de-initialized. Otherwise it
- * returns FALSE.
- * Requires:
- * device_context!= NULL. For a built in device this should never
- * get called.
- * Ensures:
- */
-extern bool dsp_deinit(u32 device_context);
-
-/*
- * ======== dsp_init ========
- * Purpose:
- * This function is called by Device Manager to initialize a device.
- * This function is not called by applications
- * Parameters:
- * dw_context: Specifies a pointer to a string containing the registry
- * path to the active key for the stream interface driver.
- * HKEY_LOCAL_MACHINE\Drivers\Active
- * Returns:
- * Returns a handle to the device context created. This is the our actual
- * Device Object representing the DSP Device instance.
- * Requires:
- * Ensures:
- * Succeeded: device context > 0
- * Failed: device Context = 0
- */
-extern u32 dsp_init(u32 *init_status);
-
-#endif
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspio.h b/drivers/staging/tidspbridge/include/dspbridge/dspio.h
deleted file mode 100644
index 66b64fadf197..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspio.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * dspio.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Declares the upper edge IO functions required by all Bridge driver /DSP API
- * interface tables.
- *
- * Notes:
- * Function comment headers reside in dspdefs.h.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPIO_
-#define DSPIO_
-
-#include <dspbridge/devdefs.h>
-#include <dspbridge/io.h>
-
-
-extern int bridge_io_create(struct io_mgr **io_man,
- struct dev_object *hdev_obj,
- const struct io_attrs *mgr_attrts);
-
-extern int bridge_io_destroy(struct io_mgr *hio_mgr);
-
-extern int bridge_io_on_loaded(struct io_mgr *hio_mgr);
-
-extern int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
- struct dsp_procloadstat *proc_lstat);
-
-#endif /* DSPIO_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
deleted file mode 100644
index 0fcda1978921..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * dspioctl.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Bridge driver BRD_IOCtl reserved command definitions.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPIOCTL_
-#define DSPIOCTL_
-
-/* ------------------------------------ Hardware Abstraction Layer */
-#include <hw_defs.h>
-#include <hw_mmu.h>
-
-/*
- * Any IOCTLS at or above this value are reserved for standard Bridge driver
- * interfaces.
- */
-#define BRDIOCTL_RESERVEDBASE 0x8000
-
-#define BRDIOCTL_CHNLREAD (BRDIOCTL_RESERVEDBASE + 0x10)
-#define BRDIOCTL_CHNLWRITE (BRDIOCTL_RESERVEDBASE + 0x20)
-/* DMMU */
-#define BRDIOCTL_SETMMUCONFIG (BRDIOCTL_RESERVEDBASE + 0x60)
-/* PWR */
-#define BRDIOCTL_PWRCONTROL (BRDIOCTL_RESERVEDBASE + 0x70)
-
-/* attention, modifiers:
- * Some of these control enumerations are made visible to user for power
- * control, so any changes to this list, should also be updated in the user
- * header file 'dbdefs.h' ***/
-/* These ioctls are reserved for PWR power commands for the DSP */
-#define BRDIOCTL_DEEPSLEEP (BRDIOCTL_PWRCONTROL + 0x0)
-#define BRDIOCTL_EMERGENCYSLEEP (BRDIOCTL_PWRCONTROL + 0x1)
-#define BRDIOCTL_WAKEUP (BRDIOCTL_PWRCONTROL + 0x2)
-#define BRDIOCTL_CLK_CTRL (BRDIOCTL_PWRCONTROL + 0x7)
-/* DSP Initiated Hibernate */
-#define BRDIOCTL_PWR_HIBERNATE (BRDIOCTL_PWRCONTROL + 0x8)
-#define BRDIOCTL_PRESCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0x9)
-#define BRDIOCTL_POSTSCALE_NOTIFY (BRDIOCTL_PWRCONTROL + 0xA)
-#define BRDIOCTL_CONSTRAINT_REQUEST (BRDIOCTL_PWRCONTROL + 0xB)
-
-/* Number of actual DSP-MMU TLB entries */
-#define BRDIOCTL_NUMOFMMUTLB 32
-
-struct bridge_ioctl_extproc {
- u32 dsp_va; /* DSP virtual address */
- u32 gpp_pa; /* GPP physical address */
- /* GPP virtual address. __va does not work for ioremapped addresses */
- u32 gpp_va;
- u32 size; /* Size of the mapped memory in bytes */
- enum hw_endianism_t endianism;
- enum hw_mmu_mixed_size_t mixed_mode;
- enum hw_element_size_t elem_size;
-};
-
-#endif /* DSPIOCTL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h b/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h
deleted file mode 100644
index d4bd458bc8be..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dspmsg.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * dspmsg.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Declares the upper edge message class library functions required by
- * all Bridge driver / DSP API interface tables. These functions are
- * implemented by every class of Bridge driver channel library.
- *
- * Notes:
- * Function comment headers reside in dspdefs.h.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DSPMSG_
-#define DSPMSG_
-
-#include <dspbridge/msgdefs.h>
-
-extern int bridge_msg_create(struct msg_mgr **msg_man,
- struct dev_object *hdev_obj,
- msg_onexit msg_callback);
-
-extern int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr,
- struct msg_queue **msgq,
- u32 msgq_id, u32 max_msgs, void *arg);
-
-extern void bridge_msg_delete(struct msg_mgr *hmsg_mgr);
-
-extern void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj);
-
-extern int bridge_msg_get(struct msg_queue *msg_queue_obj,
- struct dsp_msg *pmsg, u32 utimeout);
-
-extern int bridge_msg_put(struct msg_queue *msg_queue_obj,
- const struct dsp_msg *pmsg, u32 utimeout);
-
-extern int bridge_msg_register_notify(struct msg_queue *msg_queue_obj,
- u32 event_mask,
- u32 notify_type,
- struct dsp_notification
- *hnotification);
-
-extern void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj,
- u32 msgq_id);
-
-#endif /* DSPMSG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h b/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h
deleted file mode 100644
index 052d27ee8b1a..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * dynamic_loader.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _DYNAMIC_LOADER_H_
-#define _DYNAMIC_LOADER_H_
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-/*
- * Dynamic Loader
- *
- * The function of the dynamic loader is to load a "module" containing
- * instructions for a "target" processor into that processor. In the process
- * it assigns memory for the module, resolves symbol references made by the
- * module, and remembers symbols defined by the module.
- *
- * The dynamic loader is parameterized for a particular system by 4 classes
- * that supply the module and system specific functions it requires
- */
- /* The read functions for the module image to be loaded */
-struct dynamic_loader_stream;
-
- /* This class defines "host" symbol and support functions */
-struct dynamic_loader_sym;
-
- /* This class defines the allocator for "target" memory */
-struct dynamic_loader_allocate;
-
- /* This class defines the copy-into-target-memory functions */
-struct dynamic_loader_initialize;
-
-/*
- * Option flags to modify the behavior of module loading
- */
-#define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */
-
-/*****************************************************************************
- * Procedure dynamic_load_module
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- * init Target-side memory initialization, or NULL for symbol read only
- * options Option flags DLOAD_*
- * mhandle A module handle for use with Dynamic_Unload
- *
- * Effect:
- * The module image is read using *module. Target storage for the new image is
- * obtained from *alloc. Symbols defined and referenced by the module are
- * managed using *syms. The image is then relocated and references resolved
- * as necessary, and the resulting executable bits are placed into target memory
- * using *init.
- *
- * Returns:
- * On a successful load, a module handle is placed in *mhandle, and zero is
- * returned. On error, the number of errors detected is returned. Individual
- * errors are reported during the load process using syms->error_report().
- **************************************************************************** */
-extern int dynamic_load_module(
- /* the source for the module image */
- struct dynamic_loader_stream *module,
- /* host support for symbols and storage */
- struct dynamic_loader_sym *syms,
- /* the target memory allocator */
- struct dynamic_loader_allocate *alloc,
- /* the target memory initializer */
- struct dynamic_loader_initialize *init,
- unsigned options, /* option flags */
- /* the returned module handle */
- void **mhandle);
-
-/*****************************************************************************
- * Procedure dynamic_open_module
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- * init Target-side memory initialization, or NULL for symbol read only
- * options Option flags DLOAD_*
- * mhandle A module handle for use with Dynamic_Unload
- *
- * Effect:
- * The module image is read using *module. Target storage for the new image is
- * obtained from *alloc. Symbols defined and referenced by the module are
- * managed using *syms. The image is then relocated and references resolved
- * as necessary, and the resulting executable bits are placed into target memory
- * using *init.
- *
- * Returns:
- * On a successful load, a module handle is placed in *mhandle, and zero is
- * returned. On error, the number of errors detected is returned. Individual
- * errors are reported during the load process using syms->error_report().
- **************************************************************************** */
-extern int dynamic_open_module(
- /* the source for the module image */
- struct dynamic_loader_stream *module,
- /* host support for symbols and storage */
- struct dynamic_loader_sym *syms,
- /* the target memory allocator */
- struct dynamic_loader_allocate *alloc,
- /* the target memory initializer */
- struct dynamic_loader_initialize *init,
- unsigned options, /* option flags */
- /* the returned module handle */
- void **mhandle);
-
-/*****************************************************************************
- * Procedure dynamic_unload_module
- *
- * Parameters:
- * mhandle A module handle from dynamic_load_module
- * syms Host-side symbol table and malloc/free functions
- * alloc Target-side memory allocation
- *
- * Effect:
- * The module specified by mhandle is unloaded. Unloading causes all
- * target memory to be deallocated, all symbols defined by the module to
- * be purged, and any host-side storage used by the dynamic loader for
- * this module to be released.
- *
- * Returns:
- * Zero for success. On error, the number of errors detected is returned.
- * Individual errors are reported using syms->error_report().
- **************************************************************************** */
-extern int dynamic_unload_module(void *mhandle, /* the module
- * handle */
- /* host support for symbols and
- * storage */
- struct dynamic_loader_sym *syms,
- /* the target memory allocator */
- struct dynamic_loader_allocate *alloc,
- /* the target memory initializer */
- struct dynamic_loader_initialize *init);
-
-/*****************************************************************************
- *****************************************************************************
- * A class used by the dynamic loader for input of the module image
- *****************************************************************************
- **************************************************************************** */
-struct dynamic_loader_stream {
-/* public: */
- /*************************************************************************
- * read_buffer
- *
- * PARAMETERS :
- * buffer Pointer to the buffer to fill
- * bufsiz Amount of data desired in sizeof() units
- *
- * EFFECT :
- * Reads the specified amount of data from the module input stream
- * into the specified buffer. Returns the amount of data read in sizeof()
- * units (which if less than the specification, represents an error).
- *
- * NOTES:
- * In release 1 increments the file position by the number of bytes read
- *
- ************************************************************************ */
- int (*read_buffer) (struct dynamic_loader_stream *thisptr,
- void *buffer, unsigned bufsiz);
-
- /*************************************************************************
- * set_file_posn (release 1 only)
- *
- * PARAMETERS :
- * posn Desired file position relative to start of file in sizeof() units.
- *
- * EFFECT :
- * Adjusts the internal state of the stream object so that the next
- * read_buffer call will begin to read at the specified offset from
- * the beginning of the input module. Returns 0 for success, non-zero
- * for failure.
- *
- ************************************************************************ */
- int (*set_file_posn) (struct dynamic_loader_stream *thisptr,
- /* to be eliminated in release 2 */
- unsigned int posn);
-
-};
-
-/*****************************************************************************
- *****************************************************************************
- * A class used by the dynamic loader for symbol table support and
- * miscellaneous host-side functions
- *****************************************************************************
- **************************************************************************** */
-
-typedef u32 ldr_addr;
-
-/*
- * the structure of a symbol known to the dynamic loader
- */
-struct dynload_symbol {
- ldr_addr value;
-};
-
-struct dynamic_loader_sym {
-/* public: */
- /*************************************************************************
- * find_matching_symbol
- *
- * PARAMETERS :
- * name The name of the desired symbol
- *
- * EFFECT :
- * Locates a symbol matching the name specified. A pointer to the
- * symbol is returned if it exists; 0 is returned if no such symbol is
- * found.
- *
- ************************************************************************ */
- struct dynload_symbol *(*find_matching_symbol)
- (struct dynamic_loader_sym *thisptr, const char *name);
-
- /*************************************************************************
- * add_to_symbol_table
- *
- * PARAMETERS :
- * nname Pointer to the name of the new symbol
- * moduleid An opaque module id assigned by the dynamic loader
- *
- * EFFECT :
- * The new symbol is added to the table. A pointer to the symbol is
- * returned, or NULL is returned for failure.
- *
- * NOTES:
- * It is permissible for this function to return NULL; the effect is that
- * the named symbol will not be available to resolve references in
- * subsequent loads. Returning NULL will not cause the current load
- * to fail.
- ************************************************************************ */
- struct dynload_symbol *(*add_to_symbol_table)
- (struct dynamic_loader_sym *
- thisptr, const char *nname, unsigned moduleid);
-
- /*************************************************************************
- * purge_symbol_table
- *
- * PARAMETERS :
- * moduleid An opaque module id assigned by the dynamic loader
- *
- * EFFECT :
- * Each symbol in the symbol table whose moduleid matches the argument
- * is removed from the table.
- ************************************************************************ */
- void (*purge_symbol_table) (struct dynamic_loader_sym *thisptr,
- unsigned moduleid);
-
- /*************************************************************************
- * dload_allocate
- *
- * PARAMETERS :
- * memsiz size of desired memory in sizeof() units
- *
- * EFFECT :
- * Returns a pointer to some "host" memory for use by the dynamic
- * loader, or NULL for failure.
- * This function is serves as a replaceable form of "malloc" to
- * allow the user to configure the memory usage of the dynamic loader.
- ************************************************************************ */
- void *(*dload_allocate) (struct dynamic_loader_sym *thisptr,
- unsigned memsiz);
-
- /*************************************************************************
- * dload_deallocate
- *
- * PARAMETERS :
- * memptr pointer to previously allocated memory
- *
- * EFFECT :
- * Releases the previously allocated "host" memory.
- ************************************************************************ */
- void (*dload_deallocate) (struct dynamic_loader_sym *thisptr,
- void *memptr);
-
- /*************************************************************************
- * error_report
- *
- * PARAMETERS :
- * errstr pointer to an error string
- * args additional arguments
- *
- * EFFECT :
- * This function provides an error reporting interface for the dynamic
- * loader. The error string and arguments are designed as for the
- * library function vprintf.
- ************************************************************************ */
- void (*error_report) (struct dynamic_loader_sym *thisptr,
- const char *errstr, va_list args);
-
-}; /* class dynamic_loader_sym */
-
-/*****************************************************************************
- *****************************************************************************
- * A class used by the dynamic loader to allocate and deallocate target memory.
- *****************************************************************************
- **************************************************************************** */
-
-struct ldr_section_info {
- /* Name of the memory section assigned at build time */
- const char *name;
- ldr_addr run_addr; /* execution address of the section */
- ldr_addr load_addr; /* load address of the section */
- ldr_addr size; /* size of the section in addressable units */
-#ifndef _BIG_ENDIAN
- u16 page; /* memory page or view */
- u16 type; /* one of the section types below */
-#else
- u16 type; /* one of the section types below */
- u16 page; /* memory page or view */
-#endif
- /* a context field for use by dynamic_loader_allocate;
- * ignored but maintained by the dynamic loader */
- u32 context;
-};
-
-/* use this macro to extract type of section from ldr_section_info.type field */
-#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF)
-
-/* type of section to be allocated */
-#define DLOAD_TEXT 0
-#define DLOAD_DATA 1
-#define DLOAD_BSS 2
- /* internal use only, run-time cinit will be of type DLOAD_DATA */
-#define DLOAD_CINIT 3
-
-struct dynamic_loader_allocate {
-/* public: */
-
- /*************************************************************************
- * Function allocate
- *
- * Parameters:
- * info A pointer to an information block for the section
- * align The alignment of the storage in target AUs
- *
- * Effect:
- * Allocates target memory for the specified section and fills in the
- * load_addr and run_addr fields of the section info structure. Returns TRUE
- * for success, FALSE for failure.
- *
- * Notes:
- * Frequently load_addr and run_addr are the same, but if they are not
- * load_addr is used with dynamic_loader_initialize, and run_addr is
- * used for almost all relocations. This function should always initialize
- * both fields.
- ************************************************************************ */
- int (*dload_allocate) (struct dynamic_loader_allocate *thisptr,
- struct ldr_section_info *info, unsigned align);
-
- /*************************************************************************
- * Function deallocate
- *
- * Parameters:
- * info A pointer to an information block for the section
- *
- * Effect:
- * Releases the target memory previously allocated.
- *
- * Notes:
- * The content of the info->name field is undefined on call to this function.
- ************************************************************************ */
- void (*dload_deallocate) (struct dynamic_loader_allocate *thisptr,
- struct ldr_section_info *info);
-
-}; /* class dynamic_loader_allocate */
-
-/*****************************************************************************
- *****************************************************************************
- * A class used by the dynamic loader to load data into a target. This class
- * provides the interface-specific functions needed to load data.
- *****************************************************************************
- **************************************************************************** */
-
-struct dynamic_loader_initialize {
-/* public: */
- /*************************************************************************
- * Function connect
- *
- * Parameters:
- * none
- *
- * Effect:
- * Connect to the initialization interface. Returns TRUE for success,
- * FALSE for failure.
- *
- * Notes:
- * This function is called prior to use of any other functions in
- * this interface.
- ************************************************************************ */
- int (*connect) (struct dynamic_loader_initialize *thisptr);
-
- /*************************************************************************
- * Function readmem
- *
- * Parameters:
- * bufr Pointer to a word-aligned buffer for the result
- * locn Target address of first data element
- * info Section info for the section in which the address resides
- * bytsiz Size of the data to be read in sizeof() units
- *
- * Effect:
- * Fills the specified buffer with data from the target. Returns TRUE for
- * success, FALSE for failure.
- ************************************************************************ */
- int (*readmem) (struct dynamic_loader_initialize *thisptr,
- void *bufr,
- ldr_addr locn,
- struct ldr_section_info *info, unsigned bytsiz);
-
- /*************************************************************************
- * Function writemem
- *
- * Parameters:
- * bufr Pointer to a word-aligned buffer of data
- * locn Target address of first data element to be written
- * info Section info for the section in which the address resides
- * bytsiz Size of the data to be written in sizeof() units
- *
- * Effect:
- * Writes the specified buffer to the target. Returns TRUE for success,
- * FALSE for failure.
- ************************************************************************ */
- int (*writemem) (struct dynamic_loader_initialize *thisptr,
- void *bufr,
- ldr_addr locn,
- struct ldr_section_info *info, unsigned bytsiz);
-
- /*************************************************************************
- * Function fillmem
- *
- * Parameters:
- * locn Target address of first data element to be written
- * info Section info for the section in which the address resides
- * bytsiz Size of the data to be written in sizeof() units
- * val Value to be written in each byte
- * Effect:
- * Fills the specified area of target memory. Returns TRUE for success,
- * FALSE for failure.
- ************************************************************************ */
- int (*fillmem) (struct dynamic_loader_initialize *thisptr,
- ldr_addr locn, struct ldr_section_info *info,
- unsigned bytsiz, unsigned val);
-
- /*************************************************************************
- * Function execute
- *
- * Parameters:
- * start Starting address
- *
- * Effect:
- * The target code at the specified starting address is executed.
- *
- * Notes:
- * This function is called at the end of the dynamic load process
- * if the input module has specified a starting address.
- ************************************************************************ */
- int (*execute) (struct dynamic_loader_initialize *thisptr,
- ldr_addr start);
-
- /*************************************************************************
- * Function release
- *
- * Parameters:
- * none
- *
- * Effect:
- * Releases the connection to the load interface.
- *
- * Notes:
- * This function is called at the end of the dynamic load process.
- ************************************************************************ */
- void (*release) (struct dynamic_loader_initialize *thisptr);
-
-}; /* class dynamic_loader_initialize */
-
-#endif /* _DYNAMIC_LOADER_H_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/getsection.h b/drivers/staging/tidspbridge/include/dspbridge/getsection.h
deleted file mode 100644
index 626063dd9dfe..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/getsection.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * getsection.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This file provides an API add-on to the dynamic loader that allows the user
- * to query section information and extract section data from dynamic load
- * modules.
- *
- * Notes:
- * Functions in this API assume that the supplied dynamic_loader_stream
- * object supports the set_file_posn method.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _GETSECTION_H_
-#define _GETSECTION_H_
-
-#include "dynamic_loader.h"
-
-/*
- * Procedure dload_module_open
- *
- * Parameters:
- * module The input stream that supplies the module image
- * syms Host-side malloc/free and error reporting functions.
- * Other methods are unused.
- *
- * Effect:
- * Reads header information from a dynamic loader module using the specified
- * stream object, and returns a handle for the module information. This
- * handle may be used in subsequent query calls to obtain information
- * contained in the module.
- *
- * Returns:
- * NULL if an error is encountered, otherwise a module handle for use
- * in subsequent operations.
- */
-extern void *dload_module_open(struct dynamic_loader_stream
- *module, struct dynamic_loader_sym
- *syms);
-
-/*
- * Procedure dload_get_section_info
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- * section_name Pointer to the string name of the section desired
- * section_info Address of a section info structure pointer to be initialized
- *
- * Effect:
- * Finds the specified section in the module information, and fills in
- * the provided ldr_section_info structure.
- *
- * Returns:
- * TRUE for success, FALSE for section not found
- */
-extern int dload_get_section_info(void *minfo,
- const char *section_name,
- const struct ldr_section_info
- **const section_info);
-
-/*
- * Procedure dload_get_section
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- * section_info Pointer to a section info structure for the desired section
- * section_data Buffer to contain the section initialized data
- *
- * Effect:
- * Copies the initialized data for the specified section into the
- * supplied buffer.
- *
- * Returns:
- * TRUE for success, FALSE for section not found
- */
-extern int dload_get_section(void *minfo,
- const struct ldr_section_info *section_info,
- void *section_data);
-
-/*
- * Procedure dload_module_close
- *
- * Parameters:
- * minfo Handle from dload_module_open for this module
- *
- * Effect:
- * Releases any storage associated with the module handle. On return,
- * the module handle is invalid.
- *
- * Returns:
- * Zero for success. On error, the number of errors detected is returned.
- * Individual errors are reported using syms->error_report(), where syms was
- * an argument to dload_module_open
- */
-extern void dload_module_close(void *minfo);
-
-#endif /* _GETSECTION_H_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/gh.h b/drivers/staging/tidspbridge/include/dspbridge/gh.h
deleted file mode 100644
index e4303b4bf5fd..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/gh.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * gh.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef GH_
-#define GH_
-#include <dspbridge/host_os.h>
-
-extern struct gh_t_hash_tab *gh_create(u32 val_size,
- u32 (*hash)(const void *), bool (*match)(const void *,
- const void *), void (*delete) (void *));
-extern void gh_delete(struct gh_t_hash_tab *hash_tab);
-extern void *gh_find(struct gh_t_hash_tab *hash_tab, const void *key);
-extern void *gh_insert(struct gh_t_hash_tab *hash_tab, const void *key,
- const void *value);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-void gh_iterate(struct gh_t_hash_tab *hash_tab,
- void (*callback)(void *, void *), void *user_data);
-#endif
-#endif /* GH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h
deleted file mode 100644
index d1441db469fc..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * host_os.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _HOST_OS_H_
-#define _HOST_OS_H_
-
-#include <linux/atomic.h>
-#include <linux/semaphore.h>
-#include <linux/uaccess.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/syscalls.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stddef.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/file.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/vmalloc.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/omap-mailbox.h>
-#include <linux/pagemap.h>
-#include <asm/cacheflush.h>
-#include <linux/dma-mapping.h>
-
-/* TODO -- Remove, once omap-iommu is used */
-#define INT_DSP_MMU_IRQ (28 + NR_IRQS)
-
-#define PRCM_VDD1 1
-
-extern struct platform_device *omap_dspbridge_dev;
-extern struct device *bridge;
-
-#endif
diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h
deleted file mode 100644
index 750571856908..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/io.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * io.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The io module manages IO between CHNL and msg_ctrl.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef IO_
-#define IO_
-
-#include <dspbridge/cfgdefs.h>
-#include <dspbridge/devdefs.h>
-
-/* IO Objects: */
-struct io_mgr;
-
-/* IO manager attributes: */
-struct io_attrs {
- u8 birq; /* Channel's I/O IRQ number. */
- bool irq_shared; /* TRUE if the IRQ is shareable. */
- u32 word_size; /* DSP Word size. */
- u32 shm_base; /* Physical base address of shared memory. */
- u32 sm_length; /* Size (in bytes) of shared memory. */
-};
-
-
-/*
- * ======== io_create ========
- * Purpose:
- * Create an IO manager object, responsible for managing IO between
- * CHNL and msg_ctrl.
- * Parameters:
- * channel_mgr: Location to store a channel manager object on
- * output.
- * hdev_obj: Handle to a device object.
- * mgr_attrts: IO manager attributes.
- * mgr_attrts->birq: I/O IRQ number.
- * mgr_attrts->irq_shared: TRUE if the IRQ is shareable.
- * mgr_attrts->word_size: DSP Word size in equivalent PC bytes..
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EIO: Unable to plug channel ISR for configured IRQ.
- * -EINVAL: Invalid DSP word size (must be > 0).
- * Invalid base address for DSP communications.
- * Requires:
- * io_man != NULL.
- * mgr_attrts != NULL.
- * Ensures:
- */
-extern int io_create(struct io_mgr **io_man,
- struct dev_object *hdev_obj,
- const struct io_attrs *mgr_attrts);
-
-/*
- * ======== io_destroy ========
- * Purpose:
- * Destroy the IO manager.
- * Parameters:
- * hio_mgr: IOmanager object.
- * Returns:
- * 0: Success.
- * -EFAULT: hio_mgr was invalid.
- * Requires:
- * Ensures:
- */
-extern int io_destroy(struct io_mgr *hio_mgr);
-
-#endif /* CHNL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
deleted file mode 100644
index 903ff12b14de..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * io_sm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * IO dispatcher for a shared memory channel driver.
- * Also, includes macros to simulate shm via port io calls.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef IOSM_
-#define IOSM_
-
-#include <dspbridge/_chnl_sm.h>
-#include <dspbridge/host_os.h>
-
-#include <dspbridge/io.h>
-#include <dspbridge/mbx_sh.h> /* shared mailbox codes */
-
-/* Magic code used to determine if DSP signaled exception. */
-#define DEH_BASE MBX_DEH_BASE
-#define DEH_LIMIT MBX_DEH_LIMIT
-
-#define IO_INPUT 0
-#define IO_OUTPUT 1
-#define IO_SERVICE 2
-
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
-/* The maximum number of OPPs that are supported */
-extern s32 dsp_max_opps;
-/* The Vdd1 opp table information */
-extern u32 vdd1_dsp_freq[6][4];
-#endif
-
-/*
- * ======== io_cancel_chnl ========
- * Purpose:
- * Cancel IO on a given channel.
- * Parameters:
- * hio_mgr: IO Manager.
- * chnl: Index of channel to cancel IO on.
- * Returns:
- * Requires:
- * Valid hio_mgr.
- * Ensures:
- */
-extern void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl);
-
-/*
- * ======== io_dpc ========
- * Purpose:
- * Deferred procedure call for shared memory channel driver ISR. Carries
- * out the dispatch of I/O.
- * Parameters:
- * ref_data: Pointer to reference data registered via a call to
- * DPC_Create().
- * Returns:
- * Requires:
- * Must not block.
- * Must not acquire resources.
- * All data touched must be locked in memory if running in kernel mode.
- * Ensures:
- * Non-preemptible (but interruptible).
- */
-extern void io_dpc(unsigned long ref_data);
-
-/*
- * ======== io_mbox_msg ========
- * Purpose:
- * Main message handler for the shared memory Bridge channel manager.
- * Determine if this message is ours, then schedules a DPC to
- * dispatch I/O.
- * Parameters:
- * self: Pointer to its own notifier_block struct.
- * len: Length of message.
- * msg: Message code received.
- * Returns:
- * NOTIFY_OK if handled; NOTIFY_BAD otherwise.
- */
-int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg);
-
-/*
- * ======== io_request_chnl ========
- * Purpose:
- * Request I/O from the DSP. Sets flags in shared memory, then interrupts
- * the DSP.
- * Parameters:
- * hio_mgr: IO manager handle.
- * pchnl: Ptr to the channel requesting I/O.
- * io_mode: Mode of channel: {IO_INPUT | IO_OUTPUT}.
- * Returns:
- * Requires:
- * pchnl != NULL
- * Ensures:
- */
-extern void io_request_chnl(struct io_mgr *io_manager,
- struct chnl_object *pchnl,
- u8 io_mode, u16 *mbx_val);
-
-/*
- * ======== iosm_schedule ========
- * Purpose:
- * Schedule DPC for IO.
- * Parameters:
- * pio_mgr: Ptr to a I/O manager.
- * Returns:
- * Requires:
- * pchnl != NULL
- * Ensures:
- */
-extern void iosm_schedule(struct io_mgr *io_manager);
-
-/*
- * ======== io_sh_msetting ========
- * Purpose:
- * Sets the shared memory setting
- * Parameters:
- * hio_mgr: Handle to a I/O manager.
- * desc: Shared memory type
- * pargs: Ptr to shm setting
- * Returns:
- * Requires:
- * hio_mgr != NULL
- * pargs != NULL
- * Ensures:
- */
-extern int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs);
-
-/*
- * Misc functions for the CHNL_IO shared memory library:
- */
-
-/* Maximum channel bufsize that can be used. */
-extern u32 io_buf_size(struct io_mgr *hio_mgr);
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/*
- * ========print_dsp_trace_buffer ========
- * Print DSP tracebuffer.
- */
-extern int print_dsp_trace_buffer(struct bridge_dev_context
- *hbridge_context);
-
-int dump_dsp_stack(struct bridge_dev_context *bridge_context);
-
-void dump_dl_modules(struct bridge_dev_context *bridge_context);
-
-void print_dsp_debug_trace(struct io_mgr *hio_mgr);
-#endif
-
-#endif /* IOSM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h
deleted file mode 100644
index d4cb3948baba..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * mbx_sh.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Definitions for shared mailbox cmd/data values.(used on both
- * the GPP and DSP sides).
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * Bridge usage of OMAP mailbox 1 is determined by the "class" of the
- * mailbox interrupt's cmd value received. The class value are defined
- * as a bit (10 thru 15) being set.
- *
- * Note: Only 16 bits of each is used. Other 16 bit data reg available.
- *
- * 16 bit Mbx bit defns:
- *
- * A). Exception/Error handling (Module DEH) : class = 0.
- *
- * 15 10 0
- * ---------------------------------
- * |0|0|0|0|0|0|x|x|x|x|x|x|x|x|x|x|
- * ---------------------------------
- * | (class) | (module specific) |
- *
- *
- * B: DSP-DMA link driver channels (DDMA) : class = 1.
- *
- * 15 10 0
- * ---------------------------------
- * |0|0|0|0|0|1|b|b|b|b|b|c|c|c|c|c|
- * ---------------------------------
- * | (class) | (module specific) |
- *
- * where b -> buffer index (32 DDMA buffers/chnl max)
- * c -> channel Id (32 DDMA chnls max)
- *
- *
- * C: Proc-copy link driver channels (PCPY) : class = 2.
- *
- * 15 10 0
- * ---------------------------------
- * |0|0|0|0|1|0|x|x|x|x|x|x|x|x|x|x|
- * ---------------------------------
- * | (class) | (module specific) |
- *
- *
- * D: Zero-copy link driver channels (DDZC) : class = 4.
- *
- * 15 10 0
- * ---------------------------------
- * |0|0|0|1|0|0|x|x|x|x|x|c|c|c|c|c|
- * ---------------------------------
- * | (class) | (module specific) |
- *
- * where x -> not used
- * c -> channel Id (32 ZCPY chnls max)
- *
- *
- * E: Power management : class = 8.
- *
- * 15 10 0
- * ---------------------------------
- * |0|0|1|0|0|0|x|x|x|x|x|c|c|c|c|c|
-
- * 0010 00xx xxxc cccc
- * 0010 00nn pppp qqqq
- * nn:
- * 00 = reserved
- * 01 = pwr state change
- * 10 = opp pre-change
- * 11 = opp post-change
- *
- * if nn = pwr state change:
- * pppp = don't care
- * qqqq:
- * 0010 = hibernate
- * 0010 0001 0000 0010
- * 0110 = retention
- * 0010 0001 0000 0110
- * others reserved
- *
- * if nn = opp pre-change:
- * pppp = current opp
- * qqqq = next opp
- *
- * if nn = opp post-change:
- * pppp = prev opp
- * qqqq = current opp
- *
- * ---------------------------------
- * | (class) | (module specific) |
- *
- * where x -> not used
- * c -> Power management command
- *
- */
-
-#ifndef _MBX_SH_H
-#define _MBX_SH_H
-
-#define MBX_PCPY_CLASS 0x0800 /* PROC-COPY " */
-#define MBX_PM_CLASS 0x2000 /* Power Management */
-#define MBX_DBG_CLASS 0x4000 /* For debugging purpose */
-
-/*
- * Exception Handler codes
- * Magic code used to determine if DSP signaled exception.
- */
-#define MBX_DEH_BASE 0x0
-#define MBX_DEH_USERS_BASE 0x100 /* 256 */
-#define MBX_DEH_LIMIT 0x3FF /* 1023 */
-#define MBX_DEH_RESET 0x101 /* DSP RESET (DEH) */
-
-/*
- * Link driver command/status codes.
- */
-
-/* Power Management Commands */
-#define MBX_PM_DSPIDLE (MBX_PM_CLASS + 0x0)
-#define MBX_PM_DSPWAKEUP (MBX_PM_CLASS + 0x1)
-#define MBX_PM_EMERGENCYSLEEP (MBX_PM_CLASS + 0x2)
-#define MBX_PM_SETPOINT_PRENOTIFY (MBX_PM_CLASS + 0x6)
-#define MBX_PM_SETPOINT_POSTNOTIFY (MBX_PM_CLASS + 0x7)
-#define MBX_PM_DSPRETENTION (MBX_PM_CLASS + 0x8)
-#define MBX_PM_DSPHIBERNATE (MBX_PM_CLASS + 0x9)
-#define MBX_PM_HIBERNATE_EN (MBX_PM_CLASS + 0xA)
-#define MBX_PM_OPP_REQ (MBX_PM_CLASS + 0xB)
-
-/* Bridge Debug Commands */
-#define MBX_DBG_SYSPRINTF (MBX_DBG_CLASS + 0x0)
-
-#endif /* _MBX_SH_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/memdefs.h b/drivers/staging/tidspbridge/include/dspbridge/memdefs.h
deleted file mode 100644
index 78d2c5d0045b..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/memdefs.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * memdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global MEM constants and types, shared between Bridge driver and DSP API.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MEMDEFS_
-#define MEMDEFS_
-
-/*
- * MEM_VIRTUALSEGID is used by Node & Strm to access virtual address space in
- * the correct client process context.
- */
-#define MEM_SETVIRTUALSEGID 0x10000000
-#define MEM_GETVIRTUALSEGID 0x20000000
-#define MEM_MASKVIRTUALSEGID (MEM_SETVIRTUALSEGID | MEM_GETVIRTUALSEGID)
-
-#endif /* MEMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgr.h b/drivers/staging/tidspbridge/include/dspbridge/mgr.h
deleted file mode 100644
index 47b0318430e1..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/mgr.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * mgr.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This is the DSP API RM module interface.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MGR_
-#define MGR_
-
-#include <dspbridge/mgrpriv.h>
-
-#define MAX_EVENTS 32
-
-/*
- * ======== mgr_wait_for_bridge_events ========
- * Purpose:
- * Block on any Bridge event(s)
- * Parameters:
- * anotifications : array of pointers to notification objects.
- * count : number of elements in above array
- * pu_index : index of signaled event object
- * utimeout : timeout interval in milliseocnds
- * Returns:
- * 0 : Success.
- * -ETIME : Wait timed out. *pu_index is undetermined.
- * Details:
- */
-
-int mgr_wait_for_bridge_events(struct dsp_notification
- **anotifications,
- u32 count, u32 *pu_index,
- u32 utimeout);
-
-/*
- * ======== mgr_create ========
- * Purpose:
- * Creates the Manager Object. This is done during the driver loading.
- * There is only one Manager Object in the DSP/BIOS Bridge.
- * Parameters:
- * mgr_obj: Location to store created MGR Object handle.
- * dev_node_obj: Device object as known to the system.
- * Returns:
- * 0: Success
- * -ENOMEM: Failed to Create the Object
- * -EPERM: General Failure
- * Requires:
- * MGR Initialized (refs > 0 )
- * mgr_obj != NULL.
- * Ensures:
- * 0: *mgr_obj is a valid MGR interface to the device.
- * MGR Object stores the DCD Manager Handle.
- * MGR Object stored in the Regsitry.
- * !0: MGR Object not created
- * Details:
- * DCD Dll is loaded and MGR Object stores the handle of the DLL.
- */
-extern int mgr_create(struct mgr_object **mgr_obj,
- struct cfg_devnode *dev_node_obj);
-
-/*
- * ======== mgr_destroy ========
- * Purpose:
- * Destroys the MGR object. Called upon driver unloading.
- * Parameters:
- * hmgr_obj: Handle to Manager object .
- * Returns:
- * 0: Success.
- * DCD Manager freed; MGR Object destroyed;
- * MGR Object deleted from the Registry.
- * -EPERM: Failed to destroy MGR Object
- * Requires:
- * MGR Initialized (refs > 0 )
- * hmgr_obj is a valid MGR handle .
- * Ensures:
- * 0: MGR Object destroyed and hmgr_obj is Invalid MGR
- * Handle.
- */
-extern int mgr_destroy(struct mgr_object *hmgr_obj);
-
-/*
- * ======== mgr_enum_node_info ========
- * Purpose:
- * Enumerate and get configuration information about nodes configured
- * in the node database.
- * Parameters:
- * node_id: The node index (base 0).
- * pndb_props: Ptr to the dsp_ndbprops structure for output.
- * undb_props_size: Size of the dsp_ndbprops structure.
- * pu_num_nodes: Location where the number of nodes configured
- * in the database will be returned.
- * Returns:
- * 0: Success.
- * -EINVAL: Parameter node_id is > than the number of nodes.
- * configutred in the system
- * -EIDRM: During Enumeration there has been a change in
- * the number of nodes configured or in the
- * the properties of the enumerated nodes.
- * -EPERM: Failed to querry the Node Data Base
- * Requires:
- * pNDBPROPS is not null
- * undb_props_size >= sizeof(dsp_ndbprops)
- * pu_num_nodes is not null
- * MGR Initialized (refs > 0 )
- * Ensures:
- * SUCCESS on successful retreival of data and *pu_num_nodes > 0 OR
- * DSP_FAILED && *pu_num_nodes == 0.
- * Details:
- */
-extern int mgr_enum_node_info(u32 node_id,
- struct dsp_ndbprops *pndb_props,
- u32 undb_props_size,
- u32 *pu_num_nodes);
-
-/*
- * ======== mgr_enum_processor_info ========
- * Purpose:
- * Enumerate and get configuration information about available DSP
- * processors
- * Parameters:
- * processor_id: The processor index (zero-based).
- * processor_info: Ptr to the dsp_processorinfo structure .
- * processor_info_size: Size of dsp_processorinfo structure.
- * pu_num_procs: Location where the number of DSPs configured
- * in the database will be returned
- * Returns:
- * 0: Success.
- * -EINVAL: Parameter processor_id is > than the number of
- * DSP Processors in the system.
- * -EPERM: Failed to querry the Node Data Base
- * Requires:
- * processor_info is not null
- * pu_num_procs is not null
- * processor_info_size >= sizeof(dsp_processorinfo)
- * MGR Initialized (refs > 0 )
- * Ensures:
- * SUCCESS on successful retreival of data and *pu_num_procs > 0 OR
- * DSP_FAILED && *pu_num_procs == 0.
- * Details:
- */
-extern int mgr_enum_processor_info(u32 processor_id,
- struct dsp_processorinfo
- *processor_info,
- u32 processor_info_size,
- u8 *pu_num_procs);
-/*
- * ======== mgr_exit ========
- * Purpose:
- * Decrement reference count, and free resources when reference count is
- * 0.
- * Parameters:
- * Returns:
- * Requires:
- * MGR is initialized.
- * Ensures:
- * When reference count == 0, MGR's private resources are freed.
- */
-extern void mgr_exit(void);
-
-/*
- * ======== mgr_get_dcd_handle ========
- * Purpose:
- * Retrieves the MGR handle. Accessor Function
- * Parameters:
- * mgr_handle: Handle to the Manager Object
- * dcd_handle: Ptr to receive the DCD Handle.
- * Returns:
- * 0: Success
- * -EPERM: Failure to get the Handle
- * Requires:
- * MGR is initialized.
- * dcd_handle != NULL
- * Ensures:
- * 0 and *dcd_handle != NULL ||
- * -EPERM and *dcd_handle == NULL
- */
-extern int mgr_get_dcd_handle(struct mgr_object
- *mgr_handle, u32 *dcd_handle);
-
-/*
- * ======== mgr_init ========
- * Purpose:
- * Initialize MGR's private state, keeping a reference count on each
- * call. Initializes the DCD.
- * Parameters:
- * Returns:
- * TRUE if initialized; FALSE if error occurred.
- * Requires:
- * Ensures:
- * TRUE: A requirement for the other public MGR functions.
- */
-extern bool mgr_init(void);
-
-#endif /* MGR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h
deleted file mode 100644
index 3a4e337c040d..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * mgrpriv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global MGR constants and types, shared by PROC, MGR, and DSP API.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MGRPRIV_
-#define MGRPRIV_
-
-/*
- * OMAP1510 specific
- */
-#define MGR_MAXTLBENTRIES 32
-
-/* RM MGR Object */
-struct mgr_object;
-
-struct mgr_tlbentry {
- u32 dsp_virt; /* DSP virtual address */
- u32 gpp_phys; /* GPP physical address */
-};
-
-/*
- * The DSP_PROCESSOREXTINFO structure describes additional extended
- * capabilities of a DSP processor not exposed to user.
- */
-struct mgr_processorextinfo {
- struct dsp_processorinfo ty_basic; /* user processor info */
- /* private dsp mmu entries */
- struct mgr_tlbentry ty_tlb[MGR_MAXTLBENTRIES];
-};
-
-#endif /* MGRPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/msg.h b/drivers/staging/tidspbridge/include/dspbridge/msg.h
deleted file mode 100644
index 2c8712c933fc..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/msg.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * msg.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge msg_ctrl Module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MSG_
-#define MSG_
-
-#include <dspbridge/devdefs.h>
-#include <dspbridge/msgdefs.h>
-
-/*
- * ======== msg_create ========
- * Purpose:
- * Create an object to manage message queues. Only one of these objects
- * can exist per device object. The msg_ctrl manager must be created before
- * the IO Manager.
- * Parameters:
- * msg_man: Location to store msg_ctrl manager handle on output.
- * hdev_obj: The device object.
- * msg_callback: Called whenever an RMS_EXIT message is received.
- * Returns:
- * Requires:
- * msg_man != NULL.
- * hdev_obj != NULL.
- * msg_callback != NULL.
- * Ensures:
- */
-extern int msg_create(struct msg_mgr **msg_man,
- struct dev_object *hdev_obj,
- msg_onexit msg_callback);
-
-/*
- * ======== msg_delete ========
- * Purpose:
- * Delete a msg_ctrl manager allocated in msg_create().
- * Parameters:
- * hmsg_mgr: Handle returned from msg_create().
- * Returns:
- * Requires:
- * Valid hmsg_mgr.
- * Ensures:
- */
-extern void msg_delete(struct msg_mgr *hmsg_mgr);
-
-#endif /* MSG_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h
deleted file mode 100644
index 80a3fa1a8a33..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/msgdefs.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * msgdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global msg_ctrl constants and types.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MSGDEFS_
-#define MSGDEFS_
-
-/* msg_ctrl Objects: */
-struct msg_mgr;
-struct msg_queue;
-
-/* Function prototype for callback to be called on RMS_EXIT message received */
-typedef void (*msg_onexit) (void *h, s32 node_status);
-
-#endif /* MSGDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldr.h b/drivers/staging/tidspbridge/include/dspbridge/nldr.h
deleted file mode 100644
index c5e48ca6c548..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/nldr.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * nldr.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge dynamic loader interface.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/dbdcddef.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/rmm.h>
-#include <dspbridge/nldrdefs.h>
-
-#ifndef NLDR_
-#define NLDR_
-
-extern int nldr_allocate(struct nldr_object *nldr_obj,
- void *priv_ref, const struct dcd_nodeprops
- *node_props,
- struct nldr_nodeobject **nldr_nodeobj,
- bool *pf_phase_split);
-
-extern int nldr_create(struct nldr_object **nldr,
- struct dev_object *hdev_obj,
- const struct nldr_attrs *pattrs);
-
-extern void nldr_delete(struct nldr_object *nldr_obj);
-
-extern int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
- char *str_fxn, u32 * addr);
-
-extern int nldr_get_rmm_manager(struct nldr_object *nldr,
- struct rmm_target_obj **rmm_mgr);
-
-extern int nldr_load(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-extern int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
- u32 offset_range, void *offset_output, char *sym_name);
-#endif
-
-#endif /* NLDR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h
deleted file mode 100644
index 7e3c7f58b496..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * nldrdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global Dynamic + static/overlay Node loader (NLDR) constants and types.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef NLDRDEFS_
-#define NLDRDEFS_
-
-#include <dspbridge/dbdcddef.h>
-#include <dspbridge/devdefs.h>
-
-#define NLDR_MAXPATHLENGTH 255
-/* NLDR Objects: */
-struct nldr_object;
-struct nldr_nodeobject;
-
-/*
- * ======== nldr_loadtype ========
- * Load types for a node. Must match values in node.h55.
- */
-enum nldr_loadtype {
- NLDR_STATICLOAD, /* Linked in base image, not overlay */
- NLDR_DYNAMICLOAD, /* Dynamically loaded node */
- NLDR_OVLYLOAD /* Linked in base image, overlay node */
-};
-
-/*
- * ======== nldr_ovlyfxn ========
- * Causes code or data to be copied from load address to run address. This
- * is the "cod_writefxn" that gets passed to the DBLL_Library and is used as
- * the ZL write function.
- *
- * Parameters:
- * priv_ref: Handle to identify the node.
- * dsp_run_addr: Run address of code or data.
- * dsp_load_addr: Load address of code or data.
- * ul_num_bytes: Number of (GPP) bytes to copy.
- * mem_space: RMS_CODE or RMS_DATA.
- * Returns:
- * ul_num_bytes: Success.
- * 0: Failure.
- * Requires:
- * Ensures:
- */
-typedef u32(*nldr_ovlyfxn) (void *priv_ref, u32 dsp_run_addr,
- u32 dsp_load_addr, u32 ul_num_bytes, u32 mem_space);
-
-/*
- * ======== nldr_writefxn ========
- * Write memory function. Used for dynamic load writes.
- * Parameters:
- * priv_ref: Handle to identify the node.
- * dsp_add: Address of code or data.
- * pbuf: Code or data to be written
- * ul_num_bytes: Number of (GPP) bytes to write.
- * mem_space: DBLL_DATA or DBLL_CODE.
- * Returns:
- * ul_num_bytes: Success.
- * 0: Failure.
- * Requires:
- * Ensures:
- */
-typedef u32(*nldr_writefxn) (void *priv_ref,
- u32 dsp_add, void *pbuf,
- u32 ul_num_bytes, u32 mem_space);
-
-/*
- * ======== nldr_attrs ========
- * Attributes passed to nldr_create function.
- */
-struct nldr_attrs {
- nldr_ovlyfxn ovly;
- nldr_writefxn write;
- u16 dsp_word_size;
- u16 dsp_mau_size;
-};
-
-/*
- * ======== nldr_phase ========
- * Indicates node create, delete, or execute phase function.
- */
-enum nldr_phase {
- NLDR_CREATE,
- NLDR_DELETE,
- NLDR_EXECUTE,
- NLDR_NOPHASE
-};
-
-/*
- * Typedefs of loader functions imported from a DLL, or defined in a
- * function table.
- */
-
-/*
- * ======== nldr_allocate ========
- * Allocate resources to manage the loading of a node on the DSP.
- *
- * Parameters:
- * nldr_obj: Handle of loader that will load the node.
- * priv_ref: Handle to identify the node.
- * node_props: Pointer to a dcd_nodeprops for the node.
- * nldr_nodeobj: Location to store node handle on output. This handle
- * will be passed to nldr_load/nldr_unload.
- * pf_phase_split: pointer to int variable referenced in node.c
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory on GPP.
- * Requires:
- * Valid nldr_obj.
- * node_props != NULL.
- * nldr_nodeobj != NULL.
- * Ensures:
- * 0: IsValidNode(*nldr_nodeobj).
- * error: *nldr_nodeobj == NULL.
- */
-typedef int(*nldr_allocatefxn) (struct nldr_object *nldr_obj,
- void *priv_ref,
- const struct dcd_nodeprops
- * node_props,
- struct nldr_nodeobject
- **nldr_nodeobj,
- bool *pf_phase_split);
-
-/*
- * ======== nldr_create ========
- * Create a loader object. This object handles the loading and unloading of
- * create, delete, and execute phase functions of nodes on the DSP target.
- *
- * Parameters:
- * nldr: Location to store loader handle on output.
- * hdev_obj: Device for this processor.
- * pattrs: Loader attributes.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * Requires:
- * nldr != NULL.
- * hdev_obj != NULL.
- * pattrs != NULL.
- * Ensures:
- * 0: Valid *nldr.
- * error: *nldr == NULL.
- */
-typedef int(*nldr_createfxn) (struct nldr_object **nldr,
- struct dev_object *hdev_obj,
- const struct nldr_attrs *pattrs);
-
-/*
- * ======== nldr_delete ========
- * Delete the NLDR loader.
- *
- * Parameters:
- * nldr_obj: Node manager object.
- * Returns:
- * Requires:
- * Valid nldr_obj.
- * Ensures:
- * nldr_obj invalid
- */
-typedef void (*nldr_deletefxn) (struct nldr_object *nldr_obj);
-
-/*
- * ======== NLDR_Free ========
- * Free resources allocated in nldr_allocate.
- *
- * Parameters:
- * nldr_node_obj: Handle returned from nldr_allocate().
- * Returns:
- * Requires:
- * Valid nldr_node_obj.
- * Ensures:
- */
-typedef void (*nldr_freefxn) (struct nldr_nodeobject *nldr_node_obj);
-
-/*
- * ======== nldr_get_fxn_addr ========
- * Get address of create, delete, or execute phase function of a node on
- * the DSP.
- *
- * Parameters:
- * nldr_node_obj: Handle returned from nldr_allocate().
- * str_fxn: Name of function.
- * addr: Location to store function address.
- * Returns:
- * 0: Success.
- * -ESPIPE: Address of function not found.
- * Requires:
- * Valid nldr_node_obj.
- * addr != NULL;
- * str_fxn != NULL;
- * Ensures:
- */
-typedef int(*nldr_getfxnaddrfxn) (struct nldr_nodeobject
- * nldr_node_obj,
- char *str_fxn, u32 * addr);
-
-/*
- * ======== nldr_load ========
- * Load create, delete, or execute phase function of a node on the DSP.
- *
- * Parameters:
- * nldr_node_obj: Handle returned from nldr_allocate().
- * phase: Type of function to load (create, delete, or execute).
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory on GPP.
- * -ENXIO: Can't overlay phase because overlay memory
- * is already in use.
- * -EILSEQ: Failure in dynamic loader library.
- * Requires:
- * Valid nldr_node_obj.
- * Ensures:
- */
-typedef int(*nldr_loadfxn) (struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-
-/*
- * ======== nldr_unload ========
- * Unload create, delete, or execute phase function of a node on the DSP.
- *
- * Parameters:
- * nldr_node_obj: Handle returned from nldr_allocate().
- * phase: Node function to unload (create, delete, or execute).
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory on GPP.
- * Requires:
- * Valid nldr_node_obj.
- * Ensures:
- */
-typedef int(*nldr_unloadfxn) (struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-
-/*
- * ======== node_ldr_fxns ========
- */
-struct node_ldr_fxns {
- nldr_allocatefxn allocate;
- nldr_createfxn create;
- nldr_deletefxn delete;
- nldr_getfxnaddrfxn get_fxn_addr;
- nldr_loadfxn load;
- nldr_unloadfxn unload;
-};
-
-#endif /* NLDRDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h
deleted file mode 100644
index 68ed74a86c95..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/node.h
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * node.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Node Manager.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef NODE_
-#define NODE_
-
-#include <dspbridge/procpriv.h>
-
-#include <dspbridge/nodedefs.h>
-#include <dspbridge/disp.h>
-#include <dspbridge/nldrdefs.h>
-#include <dspbridge/drv.h>
-
-/*
- * ======== node_allocate ========
- * Purpose:
- * Allocate GPP resources to manage a node on the DSP.
- * Parameters:
- * hprocessor: Handle of processor that is allocating the node.
- * node_uuid: Pointer to a dsp_uuid for the node.
- * pargs: Optional arguments to be passed to the node.
- * attr_in: Optional pointer to node attributes (priority,
- * timeout...)
- * noderes: Location to store node resource info.
- * Returns:
- * 0: Success.
- * -ENOMEM: Insufficient memory on GPP.
- * -ENOKEY: Node UUID has not been registered.
- * -ESPIPE: iAlg functions not found for a DAIS node.
- * -EDOM: attr_in != NULL and attr_in->prio out of
- * range.
- * -EPERM: A failure occurred, unable to allocate node.
- * -EBADR: Proccessor is not in the running state.
- * Requires:
- * hprocessor != NULL.
- * node_uuid != NULL.
- * noderes != NULL.
- * Ensures:
- * 0: IsValidNode(*ph_node).
- * error: *noderes == NULL.
- */
-extern int node_allocate(struct proc_object *hprocessor,
- const struct dsp_uuid *node_uuid,
- const struct dsp_cbdata
- *pargs, const struct dsp_nodeattrin
- *attr_in,
- struct node_res_object **noderes,
- struct process_context *pr_ctxt);
-
-/*
- * ======== node_alloc_msg_buf ========
- * Purpose:
- * Allocate and Prepare a buffer whose descriptor will be passed to a
- * Node within a (dsp_msg)message
- * Parameters:
- * hnode: The node handle.
- * usize: The size of the buffer to be allocated.
- * pattr: Pointer to a dsp_bufferattr structure.
- * pbuffer: Location to store the address of the allocated
- * buffer on output.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid node handle.
- * -ENOMEM: Insufficent memory.
- * -EPERM: General Failure.
- * -EINVAL: Invalid Size.
- * Requires:
- * pbuffer != NULL.
- * Ensures:
- */
-extern int node_alloc_msg_buf(struct node_object *hnode,
- u32 usize, struct dsp_bufferattr
- *pattr, u8 **pbuffer);
-
-/*
- * ======== node_change_priority ========
- * Purpose:
- * Change the priority of an allocated node.
- * Parameters:
- * hnode: Node handle returned from node_allocate.
- * prio: New priority level to set node's priority to.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EDOM: prio is out of range.
- * -EPERM: The specified node is not a task node.
- * Unable to change node's runtime priority level.
- * -EBADR: Node is not in the NODE_ALLOCATED, NODE_PAUSED,
- * or NODE_RUNNING state.
- * -ETIME: A timeout occurred before the DSP responded.
- * Requires:
- * Ensures:
- * 0 && (Node's current priority == prio)
- */
-extern int node_change_priority(struct node_object *hnode, s32 prio);
-
-/*
- * ======== node_connect ========
- * Purpose:
- * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the
- * case that the connection is being made between a node on the DSP and
- * the GPP, one of the node handles (either node1 or node2) must be
- * the constant NODE_HGPPNODE.
- * Parameters:
- * node1: Handle of first node to connect to second node. If
- * this is a connection from the GPP to node2, node1
- * must be the constant NODE_HGPPNODE. Otherwise, node1
- * must be a node handle returned from a successful call
- * to Node_Allocate().
- * node2: Handle of second node. Must be either NODE_HGPPNODE
- * if this is a connection from DSP node to GPP, or a
- * node handle returned from a successful call to
- * node_allocate().
- * stream1: Output stream index on first node, to be connected
- * to second node's input stream. Value must range from
- * 0 <= stream1 < number of output streams.
- * stream2: Input stream index on second node. Value must range
- * from 0 <= stream2 < number of input streams.
- * pattrs: Stream attributes (NULL ==> use defaults).
- * conn_param: A pointer to a dsp_cbdata structure that defines
- * connection parameter for device nodes to pass to DSP
- * side.
- * If the value of this parameter is NULL, then this API
- * behaves like DSPNode_Connect. This parameter will have
- * length of the string and the null terminated string in
- * dsp_cbdata struct. This can be extended in future tp
- * pass binary data.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid node1 or node2.
- * -ENOMEM: Insufficient host memory.
- * -EINVAL: A stream index parameter is invalid.
- * -EISCONN: A connection already exists for one of the
- * indices stream1 or stream2.
- * -EBADR: Either node1 or node2 is not in the
- * NODE_ALLOCATED state.
- * -ECONNREFUSED: No more connections available.
- * -EPERM: Attempt to make an illegal connection (eg,
- * Device node to device node, or device node to
- * GPP), the two nodes are on different DSPs.
- * Requires:
- * Ensures:
- */
-extern int node_connect(struct node_object *node1,
- u32 stream1,
- struct node_object *node2,
- u32 stream2,
- struct dsp_strmattr *pattrs,
- struct dsp_cbdata
- *conn_param);
-
-/*
- * ======== node_create ========
- * Purpose:
- * Create a node on the DSP by remotely calling the node's create
- * function. If necessary, load code that contains the node's create
- * function.
- * Parameters:
- * hnode: Node handle returned from node_allocate().
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -ESPIPE: Create function not found in the COFF file.
- * -EBADR: Node is not in the NODE_ALLOCATED state.
- * -ENOMEM: Memory allocation failure on the DSP.
- * -ETIME: A timeout occurred before the DSP responded.
- * -EPERM: A failure occurred, unable to create node.
- * Requires:
- * Ensures:
- */
-extern int node_create(struct node_object *hnode);
-
-/*
- * ======== node_create_mgr ========
- * Purpose:
- * Create a NODE Manager object. This object handles the creation,
- * deletion, and execution of nodes on the DSP target. The NODE Manager
- * also maintains a pipe map of used and available node connections.
- * Each DEV object should have exactly one NODE Manager object.
- *
- * Parameters:
- * node_man: Location to store node manager handle on output.
- * hdev_obj: Device for this processor.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EPERM: General failure.
- * Requires:
- * node_man != NULL.
- * hdev_obj != NULL.
- * Ensures:
- * 0: Valide *node_man.
- * error: *node_man == NULL.
- */
-extern int node_create_mgr(struct node_mgr **node_man,
- struct dev_object *hdev_obj);
-
-/*
- * ======== node_delete ========
- * Purpose:
- * Delete resources allocated in node_allocate(). If the node was
- * created, delete the node on the DSP by remotely calling the node's
- * delete function. Loads the node's delete function if necessary.
- * GPP side resources are freed after node's delete function returns.
- * Parameters:
- * noderes: Node resource info handle returned from
- * node_allocate().
- * pr_ctxt: Pointer to process context data.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -ETIME: A timeout occurred before the DSP responded.
- * -EPERM: A failure occurred in deleting the node.
- * -ESPIPE: Delete function not found in the COFF file.
- * Requires:
- * Ensures:
- * 0: hnode is invalid.
- */
-extern int node_delete(struct node_res_object *noderes,
- struct process_context *pr_ctxt);
-
-/*
- * ======== node_delete_mgr ========
- * Purpose:
- * Delete the NODE Manager.
- * Parameters:
- * hnode_mgr: Node manager object.
- * Returns:
- * 0: Success.
- * Requires:
- * Valid hnode_mgr.
- * Ensures:
- */
-extern int node_delete_mgr(struct node_mgr *hnode_mgr);
-
-/*
- * ======== node_enum_nodes ========
- * Purpose:
- * Enumerate the nodes currently allocated for the DSP.
- * Parameters:
- * hnode_mgr: Node manager returned from node_create_mgr().
- * node_tab: Array to copy node handles into.
- * node_tab_size: Number of handles that can be written to node_tab.
- * pu_num_nodes: Location where number of node handles written to
- * node_tab will be written.
- * pu_allocated: Location to write total number of allocated nodes.
- * Returns:
- * 0: Success.
- * -EINVAL: node_tab is too small to hold all node handles.
- * Requires:
- * Valid hnode_mgr.
- * node_tab != NULL || node_tab_size == 0.
- * pu_num_nodes != NULL.
- * pu_allocated != NULL.
- * Ensures:
- * - (-EINVAL && *pu_num_nodes == 0)
- * - || (0 && *pu_num_nodes <= node_tab_size) &&
- * (*pu_allocated == *pu_num_nodes)
- */
-extern int node_enum_nodes(struct node_mgr *hnode_mgr,
- void **node_tab,
- u32 node_tab_size,
- u32 *pu_num_nodes,
- u32 *pu_allocated);
-
-/*
- * ======== node_free_msg_buf ========
- * Purpose:
- * Free a message buffer previously allocated with node_alloc_msg_buf.
- * Parameters:
- * hnode: The node handle.
- * pbuffer: (Address) Buffer allocated by node_alloc_msg_buf.
- * pattr: Same buffer attributes passed to node_alloc_msg_buf.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid node handle.
- * -EPERM: Failure to free the buffer.
- * Requires:
- * pbuffer != NULL.
- * Ensures:
- */
-extern int node_free_msg_buf(struct node_object *hnode,
- u8 *pbuffer,
- struct dsp_bufferattr
- *pattr);
-
-/*
- * ======== node_get_attr ========
- * Purpose:
- * Copy the current attributes of the specified node into a dsp_nodeattr
- * structure.
- * Parameters:
- * hnode: Node object allocated from node_allocate().
- * pattr: Pointer to dsp_nodeattr structure to copy node's
- * attributes.
- * attr_size: Size of pattr.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * Requires:
- * pattr != NULL.
- * Ensures:
- * 0: *pattrs contains the node's current attributes.
- */
-extern int node_get_attr(struct node_object *hnode,
- struct dsp_nodeattr *pattr, u32 attr_size);
-
-/*
- * ======== node_get_message ========
- * Purpose:
- * Retrieve a message from a node on the DSP. The node must be either a
- * message node, task node, or XDAIS socket node.
- * If a message is not available, this function will block until a
- * message is available, or the node's timeout value is reached.
- * Parameters:
- * hnode: Node handle returned from node_allocate().
- * message: Pointer to dsp_msg structure to copy the
- * message into.
- * utimeout: Timeout in milliseconds to wait for message.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: Cannot retrieve messages from this type of node.
- * Error occurred while trying to retrieve a message.
- * -ETIME: Timeout occurred and no message is available.
- * Requires:
- * message != NULL.
- * Ensures:
- */
-extern int node_get_message(struct node_object *hnode,
- struct dsp_msg *message, u32 utimeout);
-
-/*
- * ======== node_get_nldr_obj ========
- * Purpose:
- * Retrieve the Nldr manager
- * Parameters:
- * hnode_mgr: Node Manager
- * nldr_ovlyobj: Pointer to a Nldr manager handle
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * Ensures:
- */
-extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
- struct nldr_object **nldr_ovlyobj);
-
-/*
- * ======== node_on_exit ========
- * Purpose:
- * Gets called when RMS_EXIT is received for a node. PROC needs to pass
- * this function as a parameter to msg_create(). This function then gets
- * called by the Bridge driver when an exit message for a node is received.
- * Parameters:
- * hnode: Handle of the node that the exit message is for.
- * node_status: Return status of the node's execute phase.
- * Returns:
- * Ensures:
- */
-void node_on_exit(struct node_object *hnode, s32 node_status);
-
-/*
- * ======== node_pause ========
- * Purpose:
- * Suspend execution of a node currently running on the DSP.
- * Parameters:
- * hnode: Node object representing a node currently
- * running on the DSP.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: Node is not a task or socket node.
- * Failed to pause node.
- * -ETIME: A timeout occurred before the DSP responded.
- * DSP_EWRONGSTSATE: Node is not in NODE_RUNNING state.
- * Requires:
- * Ensures:
- */
-extern int node_pause(struct node_object *hnode);
-
-/*
- * ======== node_put_message ========
- * Purpose:
- * Send a message to a message node, task node, or XDAIS socket node.
- * This function will block until the message stream can accommodate
- * the message, or a timeout occurs. The message will be copied, so Msg
- * can be re-used immediately after return.
- * Parameters:
- * hnode: Node handle returned by node_allocate().
- * pmsg: Location of message to be sent to the node.
- * utimeout: Timeout in msecs to wait.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: Messages can't be sent to this type of node.
- * Unable to send message.
- * -ETIME: Timeout occurred before message could be set.
- * -EBADR: Node is in invalid state for sending messages.
- * Requires:
- * pmsg != NULL.
- * Ensures:
- */
-extern int node_put_message(struct node_object *hnode,
- const struct dsp_msg *pmsg, u32 utimeout);
-
-/*
- * ======== node_register_notify ========
- * Purpose:
- * Register to be notified on specific events for this node.
- * Parameters:
- * hnode: Node handle returned by node_allocate().
- * event_mask: Mask of types of events to be notified about.
- * notify_type: Type of notification to be sent.
- * hnotification: Handle to be used for notification.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -ENOMEM: Insufficient memory on GPP.
- * -EINVAL: event_mask is invalid.
- * -ENOSYS: Notification type specified by notify_type is not
- * supported.
- * Requires:
- * hnotification != NULL.
- * Ensures:
- */
-extern int node_register_notify(struct node_object *hnode,
- u32 event_mask, u32 notify_type,
- struct dsp_notification
- *hnotification);
-
-/*
- * ======== node_run ========
- * Purpose:
- * Start execution of a node's execute phase, or resume execution of
- * a node that has been suspended (via node_pause()) on the DSP. Load
- * the node's execute function if necessary.
- * Parameters:
- * hnode: Node object representing a node currently
- * running on the DSP.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: hnode doesn't represent a message, task or dais socket node.
- * Unable to start or resume execution.
- * -ETIME: A timeout occurred before the DSP responded.
- * DSP_EWRONGSTSATE: Node is not in NODE_PAUSED or NODE_CREATED state.
- * -ESPIPE: Execute function not found in the COFF file.
- * Requires:
- * Ensures:
- */
-extern int node_run(struct node_object *hnode);
-
-/*
- * ======== node_terminate ========
- * Purpose:
- * Signal a node running on the DSP that it should exit its execute
- * phase function.
- * Parameters:
- * hnode: Node object representing a node currently
- * running on the DSP.
- * pstatus: Location to store execute-phase function return
- * value.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -ETIME: A timeout occurred before the DSP responded.
- * -EPERM: Type of node specified cannot be terminated.
- * Unable to terminate the node.
- * -EBADR: Operation not valid for the current node state.
- * Requires:
- * pstatus != NULL.
- * Ensures:
- */
-extern int node_terminate(struct node_object *hnode,
- int *pstatus);
-
-/*
- * ======== node_get_uuid_props ========
- * Purpose:
- * Fetch Node properties given the UUID
- * Parameters:
- *
- */
-extern int node_get_uuid_props(void *hprocessor,
- const struct dsp_uuid *node_uuid,
- struct dsp_ndbprops
- *node_props);
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/**
- * node_find_addr() - Find the closest symbol to the given address.
- *
- * @node_mgr: Node manager handle
- * @sym_addr: Given address to find the closest symbol
- * @offset_range: offset range to look fo the closest symbol
- * @sym_addr_output: Symbol Output address
- * @sym_name: String with the symbol name of the closest symbol
- *
- * This function finds the closest symbol to the address where a MMU
- * Fault occurred on the DSP side.
- */
-int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
- u32 offset_range, void *sym_addr_output,
- char *sym_name);
-
-enum node_state node_get_state(void *hnode);
-#endif
-
-#endif /* NODE_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h b/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h
deleted file mode 100644
index fb9623d8a79a..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/nodedefs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * nodedefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global NODE constants and types, shared by PROCESSOR, NODE, and DISP.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef NODEDEFS_
-#define NODEDEFS_
-
-#define NODE_SUSPENDEDPRI -1
-
-/* NODE Objects: */
-struct node_mgr;
-struct node_object;
-
-#endif /* NODEDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h
deleted file mode 100644
index d5b54bb81e8e..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * nodepriv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Private node header shared by NODE and DISP.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef NODEPRIV_
-#define NODEPRIV_
-
-#include <dspbridge/strmdefs.h>
-#include <dspbridge/nodedefs.h>
-#include <dspbridge/nldrdefs.h>
-
-/* DSP address of node environment structure */
-typedef u32 nodeenv;
-
-/*
- * Node create structures
- */
-
-/* Message node */
-struct node_msgargs {
- u32 max_msgs; /* Max # of simultaneous messages for node */
- u32 seg_id; /* Segment for allocating message buffers */
- u32 notify_type; /* Notify type (SEM_post, SWI_post, etc.) */
- u32 arg_length; /* Length in 32-bit words of arg data block */
- u8 *pdata; /* Argument data for node */
-};
-
-struct node_strmdef {
- u32 buf_size; /* Size of buffers for SIO stream */
- u32 num_bufs; /* max # of buffers in SIO stream at once */
- u32 seg_id; /* Memory segment id to allocate buffers */
- u32 timeout; /* Timeout for blocking SIO calls */
- u32 buf_alignment; /* Buffer alignment */
- char *sz_device; /* Device name for stream */
-};
-
-/* Task node */
-struct node_taskargs {
- struct node_msgargs node_msg_args;
- s32 prio;
- u32 stack_size;
- u32 sys_stack_size;
- u32 stack_seg;
- u32 dsp_heap_res_addr; /* DSP virtual heap address */
- u32 dsp_heap_addr; /* DSP virtual heap address */
- u32 heap_size; /* Heap size */
- u32 gpp_heap_addr; /* GPP virtual heap address */
- u32 profile_id; /* Profile ID */
- u32 num_inputs;
- u32 num_outputs;
- u32 dais_arg; /* Address of iAlg object */
- struct node_strmdef *strm_in_def;
- struct node_strmdef *strm_out_def;
-};
-
-/*
- * ======== node_createargs ========
- */
-struct node_createargs {
- union {
- struct node_msgargs node_msg_args;
- struct node_taskargs task_arg_obj;
- } asa;
-};
-
-/*
- * ======== node_get_channel_id ========
- * Purpose:
- * Get the channel index reserved for a stream connection between the
- * host and a node. This index is reserved when node_connect() is called
- * to connect the node with the host. This index should be passed to
- * the CHNL_Open function when the stream is actually opened.
- * Parameters:
- * hnode: Node object allocated from node_allocate().
- * dir: Input (DSP_TONODE) or output (DSP_FROMNODE).
- * index: Stream index.
- * chan_id: Location to store channel index.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: Not a task or DAIS socket node.
- * -EINVAL: The node's stream corresponding to index and dir
- * is not a stream to or from the host.
- * Requires:
- * Valid dir.
- * chan_id != NULL.
- * Ensures:
- */
-extern int node_get_channel_id(struct node_object *hnode,
- u32 dir, u32 index, u32 *chan_id);
-
-/*
- * ======== node_get_strm_mgr ========
- * Purpose:
- * Get the STRM manager for a node.
- * Parameters:
- * hnode: Node allocated with node_allocate().
- * strm_man: Location to store STRM manager on output.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * Requires:
- * strm_man != NULL.
- * Ensures:
- */
-extern int node_get_strm_mgr(struct node_object *hnode,
- struct strm_mgr **strm_man);
-
-/*
- * ======== node_get_timeout ========
- * Purpose:
- * Get the timeout value of a node.
- * Parameters:
- * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE.
- * Returns:
- * Node's timeout value.
- * Requires:
- * Valid hnode.
- * Ensures:
- */
-extern u32 node_get_timeout(struct node_object *hnode);
-
-/*
- * ======== node_get_type ========
- * Purpose:
- * Get the type (device, message, task, or XDAIS socket) of a node.
- * Parameters:
- * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE.
- * Returns:
- * Node type: NODE_DEVICE, NODE_TASK, NODE_XDAIS, or NODE_GPP.
- * Requires:
- * Valid hnode.
- * Ensures:
- */
-extern enum node_type node_get_type(struct node_object *hnode);
-
-/*
- * ======== get_node_info ========
- * Purpose:
- * Get node information without holding semaphore.
- * Parameters:
- * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE.
- * Returns:
- * Node info: priority, device owner, no. of streams, execution state
- * NDB properties.
- * Requires:
- * Valid hnode.
- * Ensures:
- */
-extern void get_node_info(struct node_object *hnode,
- struct dsp_nodeinfo *node_info);
-
-/*
- * ======== node_get_load_type ========
- * Purpose:
- * Get the load type (dynamic, overlay, static) of a node.
- * Parameters:
- * hnode: Node allocated with node_allocate(), or DSP_HGPPNODE.
- * Returns:
- * Node type: NLDR_DYNAMICLOAD, NLDR_OVLYLOAD, NLDR_STATICLOAD
- * Requires:
- * Valid hnode.
- * Ensures:
- */
-extern enum nldr_loadtype node_get_load_type(struct node_object *hnode);
-
-#endif /* NODEPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h b/drivers/staging/tidspbridge/include/dspbridge/ntfy.h
deleted file mode 100644
index 6bb94d20e99a..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/ntfy.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * ntfy.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Manage lists of notification events.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef NTFY_
-#define NTFY_
-
-#include <dspbridge/host_os.h>
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/sync.h>
-
-/**
- * ntfy_object - head structure to nofify dspbridge events
- * @head: List of notify objects
- * @ntfy_lock: lock for list access.
- *
- */
-struct ntfy_object {
- struct raw_notifier_head head;/* List of notifier objects */
- spinlock_t ntfy_lock; /* For critical sections */
-};
-
-/**
- * ntfy_event - structure store specify event to be notified
- * @noti_block: List of notify objects
- * @event: event that it respond
- * @type: event type (only DSP_SIGNALEVENT supported)
- * @sync_obj: sync_event used to set the event
- *
- */
-struct ntfy_event {
- struct notifier_block noti_block;
- u32 event; /* Events to be notified about */
- u32 type; /* Type of notification to be sent */
- struct sync_object sync_obj;
-};
-
-
-/**
- * dsp_notifier_event() - callback function to nofity events
- * @this: pointer to itself struct notifier_block
- * @event: event to be notified.
- * @data: Currently not used.
- *
- */
-int dsp_notifier_event(struct notifier_block *this, unsigned long event,
- void *data);
-
-/**
- * ntfy_init() - Set the initial state of the ntfy_object structure.
- * @no: pointer to ntfy_object structure.
- *
- * This function sets the initial state of the ntfy_object in order it
- * can be used by the other ntfy functions.
- */
-
-static inline void ntfy_init(struct ntfy_object *no)
-{
- spin_lock_init(&no->ntfy_lock);
- RAW_INIT_NOTIFIER_HEAD(&no->head);
-}
-
-/**
- * ntfy_delete() - delete list of nofy events registered.
- * @ntfy_obj: Pointer to the ntfy object structure.
- *
- * This function is used to remove all the notify events registered.
- * unregister function is not needed in this function, to unregister
- * a ntfy_event please look at ntfy_register function.
- *
- */
-static inline void ntfy_delete(struct ntfy_object *ntfy_obj)
-{
- struct ntfy_event *ne;
- struct notifier_block *nb;
-
- spin_lock_bh(&ntfy_obj->ntfy_lock);
- nb = ntfy_obj->head.head;
- while (nb) {
- ne = container_of(nb, struct ntfy_event, noti_block);
- nb = nb->next;
- kfree(ne);
- }
- spin_unlock_bh(&ntfy_obj->ntfy_lock);
-}
-
-/**
- * ntfy_notify() - nofity all event register for an specific event.
- * @ntfy_obj: Pointer to the ntfy_object structure.
- * @event: event to be notified.
- *
- * This function traverses all the ntfy events registers and
- * set the event with mach with @event.
- */
-static inline void ntfy_notify(struct ntfy_object *ntfy_obj, u32 event)
-{
- spin_lock_bh(&ntfy_obj->ntfy_lock);
- raw_notifier_call_chain(&ntfy_obj->head, event, NULL);
- spin_unlock_bh(&ntfy_obj->ntfy_lock);
-}
-
-
-
-/**
- * ntfy_init() - Create and initialize a ntfy_event structure.
- * @event: event that the ntfy event will respond
- * @type event type (only DSP_SIGNALEVENT supported)
- *
- * This function create a ntfy_event element and sets the event it will
- * respond the ntfy_event in order it can be used by the other ntfy functions.
- * In case of success it will return a pointer to the ntfy_event struct
- * created. Otherwise it will return NULL;
- */
-
-static inline struct ntfy_event *ntfy_event_create(u32 event, u32 type)
-{
- struct ntfy_event *ne;
- ne = kmalloc(sizeof(struct ntfy_event), GFP_KERNEL);
- if (ne) {
- sync_init_event(&ne->sync_obj);
- ne->noti_block.notifier_call = dsp_notifier_event;
- ne->event = event;
- ne->type = type;
- }
- return ne;
-}
-
-/**
- * ntfy_register() - register new ntfy_event into a given ntfy_object
- * @ntfy_obj: Pointer to the ntfy_object structure.
- * @noti: Pointer to the handle to be returned to the user space.
- * @event event that the ntfy event will respond
- * @type event type (only DSP_SIGNALEVENT supported)
- *
- * This function register a new ntfy_event into the ntfy_object list,
- * which will respond to the @event passed.
- * This function will return 0 in case of error.
- * -EFAULT in case of bad pointers and
- * DSP_EMemory in case of no memory to create ntfy_event.
- */
-static inline int ntfy_register(struct ntfy_object *ntfy_obj,
- struct dsp_notification *noti,
- u32 event, u32 type)
-{
- struct ntfy_event *ne;
- int status = 0;
-
- if (!noti || !ntfy_obj) {
- status = -EFAULT;
- goto func_end;
- }
- if (!event) {
- status = -EINVAL;
- goto func_end;
- }
- ne = ntfy_event_create(event, type);
- if (!ne) {
- status = -ENOMEM;
- goto func_end;
- }
- noti->handle = &ne->sync_obj;
-
- spin_lock_bh(&ntfy_obj->ntfy_lock);
- raw_notifier_chain_register(&ntfy_obj->head, &ne->noti_block);
- spin_unlock_bh(&ntfy_obj->ntfy_lock);
-func_end:
- return status;
-}
-
-/**
- * ntfy_unregister() - unregister a ntfy_event from a given ntfy_object
- * @ntfy_obj: Pointer to the ntfy_object structure.
- * @noti: Pointer to the event that will be removed.
- *
- * This function unregister a ntfy_event from the ntfy_object list,
- * @noti contains the event which is wanted to be removed.
- * This function will return 0 in case of error.
- * -EFAULT in case of bad pointers and
- * DSP_EMemory in case of no memory to create ntfy_event.
- */
-static inline int ntfy_unregister(struct ntfy_object *ntfy_obj,
- struct dsp_notification *noti)
-{
- int status = 0;
- struct ntfy_event *ne;
-
- if (!noti || !ntfy_obj) {
- status = -EFAULT;
- goto func_end;
- }
-
- ne = container_of((struct sync_object *)noti, struct ntfy_event,
- sync_obj);
- spin_lock_bh(&ntfy_obj->ntfy_lock);
- raw_notifier_chain_unregister(&ntfy_obj->head,
- &ne->noti_block);
- kfree(ne);
- spin_unlock_bh(&ntfy_obj->ntfy_lock);
-func_end:
- return status;
-}
-
-#endif /* NTFY_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h
deleted file mode 100644
index 64c2457aae95..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/proc.h
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * proc.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This is the DSP API RM module interface.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef PROC_
-#define PROC_
-
-#include <dspbridge/cfgdefs.h>
-#include <dspbridge/devdefs.h>
-#include <dspbridge/drv.h>
-
-/*
- * ======== proc_attach ========
- * Purpose:
- * Prepare for communication with a particular DSP processor, and return
- * a handle to the processor object. The PROC Object gets created
- * Parameters:
- * processor_id : The processor index (zero-based).
- * hmgr_obj : Handle to the Manager Object
- * attr_in : Ptr to the dsp_processorattrin structure.
- * A NULL value means use default values.
- * ph_processor : Ptr to location to store processor handle.
- * Returns:
- * 0 : Success.
- * -EPERM : General failure.
- * -EFAULT : Invalid processor handle.
- * 0: Success; Processor already attached.
- * Requires:
- * ph_processor != NULL.
- * PROC Initialized.
- * Ensures:
- * -EPERM, and *ph_processor == NULL, OR
- * Success and *ph_processor is a Valid Processor handle OR
- * 0 and *ph_processor is a Valid Processor.
- * Details:
- * When attr_in is NULL, the default timeout value is 10 seconds.
- */
-extern int proc_attach(u32 processor_id,
- const struct dsp_processorattrin
- *attr_in, void **ph_processor,
- struct process_context *pr_ctxt);
-
-/*
- * ======== proc_auto_start =========
- * Purpose:
- * A Particular device gets loaded with the default image
- * if the AutoStart flag is set.
- * Parameters:
- * hdev_obj : Handle to the Device
- * Returns:
- * 0 : On Successful Loading
- * -ENOENT : No DSP exec file found.
- * -EPERM : General Failure
- * Requires:
- * hdev_obj != NULL.
- * dev_node_obj != NULL.
- * PROC Initialized.
- * Ensures:
- */
-extern int proc_auto_start(struct cfg_devnode *dev_node_obj,
- struct dev_object *hdev_obj);
-
-/*
- * ======== proc_ctrl ========
- * Purpose:
- * Pass control information to the GPP device driver managing the DSP
- * processor. This will be an OEM-only function, and not part of the
- * 'Bridge application developer's API.
- * Parameters:
- * hprocessor : The processor handle.
- * dw_cmd : Private driver IOCTL cmd ID.
- * pargs : Ptr to an driver defined argument structure.
- * Returns:
- * 0 : SUCCESS
- * -EFAULT : Invalid processor handle.
- * -ETIME: A Timeout Occurred before the Control information
- * could be sent.
- * -EPERM : General Failure.
- * Requires:
- * PROC Initialized.
- * Ensures
- * Details:
- * This function Calls bridge_dev_ctrl.
- */
-extern int proc_ctrl(void *hprocessor,
- u32 dw_cmd, struct dsp_cbdata *arg);
-
-/*
- * ======== proc_detach ========
- * Purpose:
- * Close a DSP processor and de-allocate all (GPP) resources reserved
- * for it. The Processor Object is deleted.
- * Parameters:
- * pr_ctxt : The processor handle.
- * Returns:
- * 0 : Success.
- * -EFAULT : InValid Handle.
- * -EPERM : General failure.
- * Requires:
- * PROC Initialized.
- * Ensures:
- * PROC Object is destroyed.
- */
-extern int proc_detach(struct process_context *pr_ctxt);
-
-/*
- * ======== proc_enum_nodes ========
- * Purpose:
- * Enumerate the nodes currently allocated on a processor.
- * Parameters:
- * hprocessor : The processor handle.
- * node_tab : The first Location of an array allocated for node
- * handles.
- * node_tab_size: The number of (DSP_HNODE) handles that can be held
- * to the memory the client has allocated for node_tab
- * pu_num_nodes : Location where DSPProcessor_EnumNodes will return
- * the number of valid handles written to node_tab
- * pu_allocated : Location where DSPProcessor_EnumNodes will return
- * the number of nodes that are allocated on the DSP.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EINVAL : The amount of memory allocated for node_tab is
- * insufficent. That is the number of nodes actually
- * allocated on the DSP is greater than the value
- * specified for node_tab_size.
- * -EPERM : Unable to get Resource Information.
- * Details:
- * Requires
- * pu_num_nodes is not NULL.
- * pu_allocated is not NULL.
- * node_tab is not NULL.
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_enum_nodes(void *hprocessor,
- void **node_tab,
- u32 node_tab_size,
- u32 *pu_num_nodes,
- u32 *pu_allocated);
-
-/*
- * ======== proc_get_resource_info ========
- * Purpose:
- * Enumerate the resources currently available on a processor.
- * Parameters:
- * hprocessor : The processor handle.
- * resource_type: Type of resource .
- * resource_info: Ptr to the dsp_resourceinfo structure.
- * resource_info_size: Size of the structure.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EBADR: The processor is not in the PROC_RUNNING state.
- * -ETIME: A timeout occurred before the DSP responded to the
- * querry.
- * -EPERM : Unable to get Resource Information
- * Requires:
- * resource_info is not NULL.
- * Parameter resource_type is Valid.[TBD]
- * resource_info_size is >= sizeof dsp_resourceinfo struct.
- * PROC Initialized.
- * Ensures:
- * Details:
- * This function currently returns
- * -ENOSYS, and does not write any data to the resource_info struct.
- */
-extern int proc_get_resource_info(void *hprocessor,
- u32 resource_type,
- struct dsp_resourceinfo
- *resource_info,
- u32 resource_info_size);
-
-/*
- * ======== proc_get_dev_object =========
- * Purpose:
- * Returns the DEV Hanlde for a given Processor handle
- * Parameters:
- * hprocessor : Processor Handle
- * device_obj : Location to store the DEV Handle.
- * Returns:
- * 0 : Success; *device_obj has Dev handle
- * -EPERM : Failure; *device_obj is zero.
- * Requires:
- * device_obj is not NULL
- * PROC Initialized.
- * Ensures:
- * 0 : *device_obj is not NULL
- * -EPERM : *device_obj is NULL.
- */
-extern int proc_get_dev_object(void *hprocessor,
- struct dev_object **device_obj);
-
-/*
- * ======== proc_get_state ========
- * Purpose:
- * Report the state of the specified DSP processor.
- * Parameters:
- * hprocessor : The processor handle.
- * proc_state_obj : Ptr to location to store the dsp_processorstate
- * structure.
- * state_info_size: Size of dsp_processorstate.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure while querying processor state.
- * Requires:
- * proc_state_obj is not NULL
- * state_info_size is >= than the size of dsp_processorstate structure.
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_get_state(void *hprocessor, struct dsp_processorstate
- *proc_state_obj, u32 state_info_size);
-
-/*
- * ======== PROC_GetProcessorID ========
- * Purpose:
- * Report the state of the specified DSP processor.
- * Parameters:
- * hprocessor : The processor handle.
- * proc_id : Processor ID
- *
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure while querying processor state.
- * Requires:
- * proc_state_obj is not NULL
- * state_info_size is >= than the size of dsp_processorstate structure.
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_get_processor_id(void *proc, u32 * proc_id);
-
-/*
- * ======== proc_get_trace ========
- * Purpose:
- * Retrieve the trace buffer from the specified DSP processor.
- * Parameters:
- * hprocessor : The processor handle.
- * pbuf : Ptr to buffer to hold trace output.
- * max_size : Maximum size of the output buffer.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure while retrieving processor trace
- * Buffer.
- * Requires:
- * pbuf is not NULL
- * max_size is > 0.
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size);
-
-/*
- * ======== proc_load ========
- * Purpose:
- * Reset a processor and load a new base program image.
- * This will be an OEM-only function.
- * Parameters:
- * hprocessor: The processor handle.
- * argc_index: The number of Arguments(strings)in the aArgV[]
- * user_args: An Array of Arguments(Unicode Strings)
- * user_envp: An Array of Environment settings(Unicode Strings)
- * Returns:
- * 0: Success.
- * -ENOENT: The DSP Executable was not found.
- * -EFAULT: Invalid processor handle.
- * -EPERM : Unable to Load the Processor
- * Requires:
- * user_args is not NULL
- * argc_index is > 0
- * PROC Initialized.
- * Ensures:
- * Success and ProcState == PROC_LOADED
- * or DSP_FAILED status.
- * Details:
- * Does not implement access rights to control which GPP application
- * can load the processor.
- */
-extern int proc_load(void *hprocessor,
- const s32 argc_index, const char **user_args,
- const char **user_envp);
-
-/*
- * ======== proc_register_notify ========
- * Purpose:
- * Register to be notified of specific processor events
- * Parameters:
- * hprocessor : The processor handle.
- * event_mask : Mask of types of events to be notified about.
- * notify_type : Type of notification to be sent.
- * hnotification: Handle to be used for notification.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle or hnotification.
- * -EINVAL : Parameter event_mask is Invalid
- * DSP_ENOTIMP : The notification type specified in uNotifyMask
- * is not supported.
- * -EPERM : Unable to register for notification.
- * Requires:
- * hnotification is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_register_notify(void *hprocessor,
- u32 event_mask, u32 notify_type,
- struct dsp_notification
- *hnotification);
-
-/*
- * ======== proc_notify_clients ========
- * Purpose:
- * Notify the Processor Clients
- * Parameters:
- * proc : The processor handle.
- * events : Event to be notified about.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : Failure to Set or Reset the Event
- * Requires:
- * events is Supported or Valid type of Event
- * proc is a valid handle
- * PROC Initialized.
- * Ensures:
- */
-extern int proc_notify_clients(void *proc, u32 events);
-
-/*
- * ======== proc_notify_all_clients ========
- * Purpose:
- * Notify the Processor Clients
- * Parameters:
- * proc : The processor handle.
- * events : Event to be notified about.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : Failure to Set or Reset the Event
- * Requires:
- * events is Supported or Valid type of Event
- * proc is a valid handle
- * PROC Initialized.
- * Ensures:
- * Details:
- * NODE And STRM would use this function to notify their clients
- * about the state changes in NODE or STRM.
- */
-extern int proc_notify_all_clients(void *proc, u32 events);
-
-/*
- * ======== proc_start ========
- * Purpose:
- * Start a processor running.
- * Processor must be in PROC_LOADED state.
- * This will be an OEM-only function, and not part of the 'Bridge
- * application developer's API.
- * Parameters:
- * hprocessor : The processor handle.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EBADR: Processor is not in PROC_LOADED state.
- * -EPERM : Unable to start the processor.
- * Requires:
- * PROC Initialized.
- * Ensures:
- * Success and ProcState == PROC_RUNNING or DSP_FAILED status.
- * Details:
- */
-extern int proc_start(void *hprocessor);
-
-/*
- * ======== proc_stop ========
- * Purpose:
- * Start a processor running.
- * Processor must be in PROC_LOADED state.
- * This will be an OEM-only function, and not part of the 'Bridge
- * application developer's API.
- * Parameters:
- * hprocessor : The processor handle.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EBADR: Processor is not in PROC_LOADED state.
- * -EPERM : Unable to start the processor.
- * Requires:
- * PROC Initialized.
- * Ensures:
- * Success and ProcState == PROC_RUNNING or DSP_FAILED status.
- * Details:
- */
-extern int proc_stop(void *hprocessor);
-
-/*
- * ======== proc_end_dma ========
- * Purpose:
- * Begin a DMA transfer
- * Parameters:
- * hprocessor : The processor handle.
- * pmpu_addr : Buffer start address
- * ul_size : Buffer size
- * dir : The direction of the transfer
- * Requires:
- * Memory was previously mapped.
- */
-extern int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
- enum dma_data_direction dir);
-/*
- * ======== proc_begin_dma ========
- * Purpose:
- * Begin a DMA transfer
- * Parameters:
- * hprocessor : The processor handle.
- * pmpu_addr : Buffer start address
- * ul_size : Buffer size
- * dir : The direction of the transfer
- * Requires:
- * Memory was previously mapped.
- */
-extern int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
- enum dma_data_direction dir);
-
-/*
- * ======== proc_flush_memory ========
- * Purpose:
- * Flushes a buffer from the MPU data cache.
- * Parameters:
- * hprocessor : The processor handle.
- * pmpu_addr : Buffer start address
- * ul_size : Buffer size
- * ul_flags : Reserved.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * Requires:
- * PROC Initialized.
- * Ensures:
- * Details:
- * All the arguments are currently ignored.
- */
-extern int proc_flush_memory(void *hprocessor,
- void *pmpu_addr, u32 ul_size, u32 ul_flags);
-
-/*
- * ======== proc_invalidate_memory ========
- * Purpose:
- * Invalidates a buffer from the MPU data cache.
- * Parameters:
- * hprocessor : The processor handle.
- * pmpu_addr : Buffer start address
- * ul_size : Buffer size
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * Requires:
- * PROC Initialized.
- * Ensures:
- * Details:
- * All the arguments are currently ignored.
- */
-extern int proc_invalidate_memory(void *hprocessor,
- void *pmpu_addr, u32 ul_size);
-
-/*
- * ======== proc_map ========
- * Purpose:
- * Maps a MPU buffer to DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * pmpu_addr : Starting address of the memory region to map.
- * ul_size : Size of the memory region to map.
- * req_addr : Requested DSP start address. Offset-adjusted actual
- * mapped address is in the last argument.
- * pp_map_addr : Ptr to DSP side mapped u8 address.
- * ul_map_attr : Optional endianness attributes, virt to phys flag.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOMEM : MPU side memory allocation error.
- * -ENOENT : Cannot find a reserved region starting with this
- * : address.
- * Requires:
- * pmpu_addr is not NULL
- * ul_size is not zero
- * pp_map_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_map(void *hprocessor,
- void *pmpu_addr,
- u32 ul_size,
- void *req_addr,
- void **pp_map_addr, u32 ul_map_attr,
- struct process_context *pr_ctxt);
-
-/*
- * ======== proc_reserve_memory ========
- * Purpose:
- * Reserve a virtually contiguous region of DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * ul_size : Size of the address space to reserve.
- * pp_rsv_addr : Ptr to DSP side reserved u8 address.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOMEM : Cannot reserve chunk of this size.
- * Requires:
- * pp_rsv_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_reserve_memory(void *hprocessor,
- u32 ul_size, void **pp_rsv_addr,
- struct process_context *pr_ctxt);
-
-/*
- * ======== proc_un_map ========
- * Purpose:
- * Removes a MPU buffer mapping from the DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * map_addr : Starting address of the mapped memory region.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOENT : Cannot find a mapped region starting with this
- * : address.
- * Requires:
- * map_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_un_map(void *hprocessor, void *map_addr,
- struct process_context *pr_ctxt);
-
-/*
- * ======== proc_un_reserve_memory ========
- * Purpose:
- * Frees a previously reserved region of DSP address space.
- * Parameters:
- * hprocessor : The processor handle.
- * prsv_addr : Ptr to DSP side reservedBYTE address.
- * Returns:
- * 0 : Success.
- * -EFAULT : Invalid processor handle.
- * -EPERM : General failure.
- * -ENOENT : Cannot find a reserved region starting with this
- * : address.
- * Requires:
- * prsv_addr is not NULL
- * PROC Initialized.
- * Ensures:
- * Details:
- */
-extern int proc_un_reserve_memory(void *hprocessor,
- void *prsv_addr,
- struct process_context *pr_ctxt);
-
-#endif /* PROC_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/procpriv.h b/drivers/staging/tidspbridge/include/dspbridge/procpriv.h
deleted file mode 100644
index 77d1f0ef95c3..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/procpriv.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * procpriv.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global PROC constants and types, shared by PROC, MGR and DSP API.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef PROCPRIV_
-#define PROCPRIV_
-
-/* RM PROC Object */
-struct proc_object;
-
-#endif /* PROCPRIV_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr.h b/drivers/staging/tidspbridge/include/dspbridge/pwr.h
deleted file mode 100644
index 0fb066488da9..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/pwr.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * pwr.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef PWR_
-#define PWR_
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/mbx_sh.h>
-
-/* valid sleep command codes that can be sent by GPP via mailbox: */
-#define PWR_DEEPSLEEP MBX_PM_DSPIDLE
-#define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP
-#define PWR_WAKEUP MBX_PM_DSPWAKEUP
-
-
-/*
- * ======== pwr_sleep_dsp ========
- * Signal the DSP to go to sleep.
- *
- * Parameters:
- * sleep_code: New sleep state for DSP. (Initially, valid codes
- * are PWR_DEEPSLEEP or PWR_EMERGENCYDEEPSLEEP; both of
- * these codes will simply put the DSP in deep sleep.)
- *
- * timeout: Maximum time (msec) that PWR should wait for
- * confirmation that the DSP sleep state has been
- * reached. If PWR should simply send the command to
- * the DSP to go to sleep and then return (i.e.,
- * asynchrounous sleep), the timeout should be
- * specified as zero.
- *
- * Returns:
- * 0: Success.
- * 0: Success, but the DSP was already asleep.
- * -EINVAL: The specified sleep_code is not supported.
- * -ETIME: A timeout occurred while waiting for DSP sleep
- * confirmation.
- * -EPERM: General failure, unable to send sleep command to
- * the DSP.
- */
-extern int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout);
-
-/*
- * ======== pwr_wake_dsp ========
- * Signal the DSP to wake from sleep.
- *
- * Parameters:
- * timeout: Maximum time (msec) that PWR should wait for
- * confirmation that the DSP is awake. If PWR should
- * simply send a command to the DSP to wake and then
- * return (i.e., asynchrounous wake), timeout should
- * be specified as zero.
- *
- * Returns:
- * 0: Success.
- * 0: Success, but the DSP was already awake.
- * -ETIME: A timeout occurred while waiting for wake
- * confirmation.
- * -EPERM: General failure, unable to send wake command to
- * the DSP.
- */
-extern int pwr_wake_dsp(const u32 timeout);
-
-/*
- * ======== pwr_pm_pre_scale ========
- * Prescale notification to DSP.
- *
- * Parameters:
- * voltage_domain: The voltage domain for which notification is sent
- * level: The level of voltage domain
- *
- * Returns:
- * 0: Success.
- * 0: Success, but the DSP was already awake.
- * -ETIME: A timeout occurred while waiting for wake
- * confirmation.
- * -EPERM: General failure, unable to send wake command to
- * the DSP.
- */
-extern int pwr_pm_pre_scale(u16 voltage_domain, u32 level);
-
-/*
- * ======== pwr_pm_post_scale ========
- * PostScale notification to DSP.
- *
- * Parameters:
- * voltage_domain: The voltage domain for which notification is sent
- * level: The level of voltage domain
- *
- * Returns:
- * 0: Success.
- * 0: Success, but the DSP was already awake.
- * -ETIME: A timeout occurred while waiting for wake
- * confirmation.
- * -EPERM: General failure, unable to send wake command to
- * the DSP.
- */
-extern int pwr_pm_post_scale(u16 voltage_domain, u32 level);
-
-#endif /* PWR_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
deleted file mode 100644
index 8c9c902a0432..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * resourcecleanup.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <dspbridge/nodepriv.h>
-#include <dspbridge/drv.h>
-
-extern int drv_remove_all_dmm_res_elements(void *process_ctxt);
-
-extern int drv_remove_all_node_res_elements(void *process_ctxt);
-
-extern int drv_remove_all_resources(void *process_ctxt);
-
-extern int drv_insert_node_res_element(void *hnode, void *node_resource,
- void *process_ctxt);
-
-extern void drv_proc_node_update_heap_status(void *node_resource, s32 status);
-
-extern void drv_proc_node_update_status(void *node_resource, s32 status);
-
-extern int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources);
-
-extern int drv_proc_insert_strm_res_element(void *stream_obj,
- void *strm_res,
- void *process_ctxt);
-
-extern int drv_remove_all_strm_res_elements(void *process_ctxt);
-
-extern enum node_state node_get_state(void *hnode);
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmm.h b/drivers/staging/tidspbridge/include/dspbridge/rmm.h
deleted file mode 100644
index f7a4dc8ecb4f..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/rmm.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * rmm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This memory manager provides general heap management and arbitrary
- * alignment for any number of memory segments, and management of overlay
- * memory.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef RMM_
-#define RMM_
-
-/*
- * ======== rmm_addr ========
- * DSP address + segid
- */
-struct rmm_addr {
- u32 addr;
- s32 segid;
-};
-
-/*
- * ======== rmm_segment ========
- * Memory segment on the DSP available for remote allocations.
- */
-struct rmm_segment {
- u32 base; /* Base of the segment */
- u32 length; /* Size of the segment (target MAUs) */
- s32 space; /* Code or data */
- u32 number; /* Number of Allocated Blocks */
-};
-
-/*
- * ======== RMM_Target ========
- */
-struct rmm_target_obj;
-
-/*
- * ======== rmm_alloc ========
- *
- * rmm_alloc is used to remotely allocate or reserve memory on the DSP.
- *
- * Parameters:
- * target - Target returned from rmm_create().
- * segid - Memory segment to allocate from.
- * size - Size (target MAUS) to allocate.
- * align - alignment.
- * dsp_address - If reserve is FALSE, the location to store allocated
- * address on output, otherwise, the DSP address to
- * reserve.
- * reserve - If TRUE, reserve the memory specified by dsp_address.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation on GPP failed.
- * -ENXIO: Cannot "allocate" overlay memory because it's
- * already in use.
- * Requires:
- * RMM initialized.
- * Valid target.
- * dsp_address != NULL.
- * size > 0
- * reserve || target->num_segs > 0.
- * Ensures:
- */
-extern int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size,
- u32 align, u32 *dsp_address, bool reserve);
-
-/*
- * ======== rmm_create ========
- * Create a target object with memory segments for remote allocation. If
- * seg_tab == NULL or num_segs == 0, memory can only be reserved through
- * rmm_alloc().
- *
- * Parameters:
- * target_obj: - Location to store target on output.
- * seg_tab: - Table of memory segments.
- * num_segs: - Number of memory segments.
- * Returns:
- * 0: Success.
- * -ENOMEM: Memory allocation failed.
- * Requires:
- * RMM initialized.
- * target_obj != NULL.
- * num_segs == 0 || seg_tab != NULL.
- * Ensures:
- * Success: Valid *target_obj.
- * Failure: *target_obj == NULL.
- */
-extern int rmm_create(struct rmm_target_obj **target_obj,
- struct rmm_segment seg_tab[], u32 num_segs);
-
-/*
- * ======== rmm_delete ========
- * Delete target allocated in rmm_create().
- *
- * Parameters:
- * target - Target returned from rmm_create().
- * Returns:
- * Requires:
- * RMM initialized.
- * Valid target.
- * Ensures:
- */
-extern void rmm_delete(struct rmm_target_obj *target);
-
-/*
- * ======== rmm_free ========
- * Free or unreserve memory allocated through rmm_alloc().
- *
- * Parameters:
- * target: - Target returned from rmm_create().
- * segid: - Segment of memory to free.
- * dsp_address: - Address to free or unreserve.
- * size: - Size of memory to free or unreserve.
- * reserved: - TRUE if memory was reserved only, otherwise FALSE.
- * Returns:
- * Requires:
- * RMM initialized.
- * Valid target.
- * reserved || segid < target->num_segs.
- * reserve || [dsp_address, dsp_address + size] is a valid memory range.
- * Ensures:
- */
-extern bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr,
- u32 size, bool reserved);
-
-/*
- * ======== rmm_stat ========
- * Obtain memory segment status
- *
- * Parameters:
- * segid: Segment ID of the dynamic loading segment.
- * mem_stat_buf: Pointer to allocated buffer into which memory stats are
- * placed.
- * Returns:
- * TRUE: Success.
- * FALSE: Failure.
- * Requires:
- * segid < target->num_segs
- * Ensures:
- */
-extern bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid,
- struct dsp_memstat *mem_stat_buf);
-
-#endif /* RMM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h b/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h
deleted file mode 100644
index ba7f47845673..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * rms_sh.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Resource Manager Server shared definitions (used on both
- * GPP and DSP sides).
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef RMS_SH_
-#define RMS_SH_
-
-#include <dspbridge/rmstypes.h>
-
-/* Memory Types: */
-#define RMS_CODE 0 /* Program space */
-#define RMS_DATA 1 /* Data space */
-
-/* RM Server Command and Response Buffer Sizes: */
-#define RMS_COMMANDBUFSIZE 256 /* Size of command buffer */
-
-/* Pre-Defined Command/Response Codes: */
-#define RMS_EXIT 0x80000000 /* GPP->Node: shutdown */
-#define RMS_EXITACK 0x40000000 /* Node->GPP: ack shutdown */
-#define RMS_BUFDESC 0x20000000 /* Arg1 SM buf, Arg2 SM size */
-#define RMS_KILLTASK 0x10000000 /* GPP->Node: Kill Task */
-
-/* RM Server RPC Command Structure: */
-struct rms_command {
- rms_word fxn; /* Server function address */
- rms_word arg1; /* First argument */
- rms_word arg2; /* Second argument */
- rms_word data; /* Function-specific data array */
-};
-
-/*
- * The rms_strm_def structure defines the parameters for both input and output
- * streams, and is passed to a node's create function.
- */
-struct rms_strm_def {
- rms_word bufsize; /* Buffer size (in DSP words) */
- rms_word nbufs; /* Max number of bufs in stream */
- rms_word segid; /* Segment to allocate buffers */
- rms_word align; /* Alignment for allocated buffers */
- rms_word timeout; /* Timeout (msec) for blocking calls */
- char name[1]; /* Device Name (terminated by '\0') */
-};
-
-/* Message node create args structure: */
-struct rms_msg_args {
- rms_word max_msgs; /* Max # simultaneous msgs to node */
- rms_word segid; /* Mem segment for NODE_allocMsgBuf */
- rms_word notify_type; /* Type of message notification */
- rms_word arg_length; /* Length (in DSP chars) of arg data */
- rms_word arg_data; /* Arg data for node */
-};
-
-/* Partial task create args structure */
-struct rms_more_task_args {
- rms_word priority; /* Task's runtime priority level */
- rms_word stack_size; /* Task's stack size */
- rms_word sysstack_size; /* Task's system stack size (55x) */
- rms_word stack_seg; /* Memory segment for task's stack */
- rms_word heap_addr; /* base address of the node memory heap in
- * external memory (DSP virtual address) */
- rms_word heap_size; /* size in MAUs of the node memory heap in
- * external memory */
- rms_word misc; /* Misc field. Not used for 'normal'
- * task nodes; for xDAIS socket nodes
- * specifies the IALG_Fxn pointer.
- */
- /* # input STRM definition structures */
- rms_word num_input_streams;
-};
-
-#endif /* RMS_SH_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h b/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h
deleted file mode 100644
index 83c0f1d9619e..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/rmstypes.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * rmstypes.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Resource Manager Server shared data type definitions.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef RMSTYPES_
-#define RMSTYPES_
-#include <linux/types.h>
-typedef u32 rms_word;
-
-#endif /* RMSTYPES_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/strm.h b/drivers/staging/tidspbridge/include/dspbridge/strm.h
deleted file mode 100644
index 97aee4c63d24..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/strm.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * strm.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSPBridge Stream Manager.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef STRM_
-#define STRM_
-
-#include <dspbridge/dev.h>
-
-#include <dspbridge/strmdefs.h>
-#include <dspbridge/proc.h>
-
-/*
- * ======== strm_allocate_buffer ========
- * Purpose:
- * Allocate data buffer(s) for use with a stream.
- * Parameter:
- * strmres: Stream resource info handle returned from strm_open().
- * usize: Size (GPP bytes) of the buffer(s).
- * num_bufs: Number of buffers to allocate.
- * ap_buffer: Array to hold buffer addresses.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -ENOMEM: Insufficient memory.
- * -EPERM: Failure occurred, unable to allocate buffers.
- * -EINVAL: usize must be > 0 bytes.
- * Requires:
- * ap_buffer != NULL.
- * Ensures:
- */
-extern int strm_allocate_buffer(struct strm_res_object *strmres,
- u32 usize,
- u8 **ap_buffer,
- u32 num_bufs,
- struct process_context *pr_ctxt);
-
-/*
- * ======== strm_close ========
- * Purpose:
- * Close a stream opened with strm_open().
- * Parameter:
- * strmres: Stream resource info handle returned from strm_open().
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -EPIPE: Some data buffers issued to the stream have not
- * been reclaimed.
- * -EPERM: Failure to close stream.
- * Requires:
- * Ensures:
- */
-extern int strm_close(struct strm_res_object *strmres,
- struct process_context *pr_ctxt);
-
-/*
- * ======== strm_create ========
- * Purpose:
- * Create a STRM manager object. This object holds information about the
- * device needed to open streams.
- * Parameters:
- * strm_man: Location to store handle to STRM manager object on
- * output.
- * dev_obj: Device for this processor.
- * Returns:
- * 0: Success;
- * -ENOMEM: Insufficient memory for requested resources.
- * -EPERM: General failure.
- * Requires:
- * strm_man != NULL.
- * dev_obj != NULL.
- * Ensures:
- * 0: Valid *strm_man.
- * error: *strm_man == NULL.
- */
-extern int strm_create(struct strm_mgr **strm_man,
- struct dev_object *dev_obj);
-
-/*
- * ======== strm_delete ========
- * Purpose:
- * Delete the STRM Object.
- * Parameters:
- * strm_mgr_obj: Handle to STRM manager object from strm_create.
- * Returns:
- * Requires:
- * Valid strm_mgr_obj.
- * Ensures:
- * strm_mgr_obj is not valid.
- */
-extern void strm_delete(struct strm_mgr *strm_mgr_obj);
-
-/*
- * ======== strm_free_buffer ========
- * Purpose:
- * Free buffer(s) allocated with strm_allocate_buffer.
- * Parameter:
- * strmres: Stream resource info handle returned from strm_open().
- * ap_buffer: Array containing buffer addresses.
- * num_bufs: Number of buffers to be freed.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream handle.
- * -EPERM: Failure occurred, unable to free buffers.
- * Requires:
- * ap_buffer != NULL.
- * Ensures:
- */
-extern int strm_free_buffer(struct strm_res_object *strmres,
- u8 **ap_buffer, u32 num_bufs,
- struct process_context *pr_ctxt);
-
-/*
- * ======== strm_get_info ========
- * Purpose:
- * Get information about a stream. User's dsp_streaminfo is contained
- * in stream_info struct. stream_info also contains Bridge private info.
- * Parameters:
- * stream_obj: Stream handle returned from strm_open().
- * stream_info: Location to store stream info on output.
- * uSteamInfoSize: Size of user's dsp_streaminfo structure.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -EINVAL: stream_info_size < sizeof(dsp_streaminfo).
- * -EPERM: Unable to get stream info.
- * Requires:
- * stream_info != NULL.
- * Ensures:
- */
-extern int strm_get_info(struct strm_object *stream_obj,
- struct stream_info *stream_info,
- u32 stream_info_size);
-
-/*
- * ======== strm_idle ========
- * Purpose:
- * Idle a stream and optionally flush output data buffers.
- * If this is an output stream and flush_data is TRUE, all data currently
- * enqueued will be discarded.
- * If this is an output stream and flush_data is FALSE, this function
- * will block until all currently buffered data is output, or the timeout
- * specified has been reached.
- * After a successful call to strm_idle(), all buffers can immediately
- * be reclaimed.
- * Parameters:
- * stream_obj: Stream handle returned from strm_open().
- * flush_data: If TRUE, discard output buffers.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -ETIME: A timeout occurred before the stream could be idled.
- * -EPERM: Unable to idle stream.
- * Requires:
- * Ensures:
- */
-extern int strm_idle(struct strm_object *stream_obj, bool flush_data);
-
-/*
- * ======== strm_issue ========
- * Purpose:
- * Send a buffer of data to a stream.
- * Parameters:
- * stream_obj: Stream handle returned from strm_open().
- * pbuf: Pointer to buffer of data to be sent to the stream.
- * ul_bytes: Number of bytes of data in the buffer.
- * ul_buf_size: Actual buffer size in bytes.
- * dw_arg: A user argument that travels with the buffer.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -ENOSR: The stream is full.
- * -EPERM: Failure occurred, unable to issue buffer.
- * Requires:
-* pbuf != NULL.
- * Ensures:
- */
-extern int strm_issue(struct strm_object *stream_obj, u8 * pbuf,
- u32 ul_bytes, u32 ul_buf_size, u32 dw_arg);
-
-/*
- * ======== strm_open ========
- * Purpose:
- * Open a stream for sending/receiving data buffers to/from a task of
- * DAIS socket node on the DSP.
- * Parameters:
- * hnode: Node handle returned from node_allocate().
- * dir: DSP_TONODE or DSP_FROMNODE.
- * index: Stream index.
- * pattr: Pointer to structure containing attributes to be
- * applied to stream. Cannot be NULL.
- * strmres: Location to store stream resource info handle on output.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hnode.
- * -EPERM: Invalid direction.
- * hnode is not a task or DAIS socket node.
- * Unable to open stream.
- * -EINVAL: Invalid index.
- * Requires:
- * strmres != NULL.
- * pattr != NULL.
- * Ensures:
- * 0: *strmres is valid.
- * error: *strmres == NULL.
- */
-extern int strm_open(struct node_object *hnode, u32 dir,
- u32 index, struct strm_attr *pattr,
- struct strm_res_object **strmres,
- struct process_context *pr_ctxt);
-
-/*
- * ======== strm_reclaim ========
- * Purpose:
- * Request a buffer back from a stream.
- * Parameters:
- * stream_obj: Stream handle returned from strm_open().
- * buf_ptr: Location to store pointer to reclaimed buffer.
- * nbytes: Location where number of bytes of data in the
- * buffer will be written.
- * buff_size: Location where actual buffer size will be written.
- * pdw_arg: Location where user argument that travels with
- * the buffer will be written.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -ETIME: A timeout occurred before a buffer could be
- * retrieved.
- * -EPERM: Failure occurred, unable to reclaim buffer.
- * Requires:
- * buf_ptr != NULL.
- * nbytes != NULL.
- * pdw_arg != NULL.
- * Ensures:
- */
-extern int strm_reclaim(struct strm_object *stream_obj,
- u8 **buf_ptr, u32 * nbytes,
- u32 *buff_size, u32 *pdw_arg);
-
-/*
- * ======== strm_register_notify ========
- * Purpose:
- * Register to be notified on specific events for this stream.
- * Parameters:
- * stream_obj: Stream handle returned by strm_open().
- * event_mask: Mask of types of events to be notified about.
- * notify_type: Type of notification to be sent.
- * hnotification: Handle to be used for notification.
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid stream_obj.
- * -ENOMEM: Insufficient memory on GPP.
- * -EINVAL: event_mask is invalid.
- * -ENOSYS: Notification type specified by notify_type is not
- * supported.
- * Requires:
- * hnotification != NULL.
- * Ensures:
- */
-extern int strm_register_notify(struct strm_object *stream_obj,
- u32 event_mask, u32 notify_type,
- struct dsp_notification
- *hnotification);
-
-/*
- * ======== strm_select ========
- * Purpose:
- * Select a ready stream.
- * Parameters:
- * strm_tab: Array of stream handles returned from strm_open().
- * strms: Number of stream handles in array.
- * pmask: Location to store mask of ready streams on output.
- * utimeout: Timeout value (milliseconds).
- * Returns:
- * 0: Success.
- * -EDOM: strms out of range.
-
- * -EFAULT: Invalid stream handle in array.
- * -ETIME: A timeout occurred before a stream became ready.
- * -EPERM: Failure occurred, unable to select a stream.
- * Requires:
- * strm_tab != NULL.
- * strms > 0.
- * pmask != NULL.
- * Ensures:
- * 0: *pmask != 0 || utimeout == 0.
- * Error: *pmask == 0.
- */
-extern int strm_select(struct strm_object **strm_tab,
- u32 strms, u32 *pmask, u32 utimeout);
-
-#endif /* STRM_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h
deleted file mode 100644
index 4f90e6ba69ef..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * strmdefs.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Global STRM constants and types.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef STRMDEFS_
-#define STRMDEFS_
-
-struct strm_mgr;
-
-struct strm_object;
-
-struct strm_attr {
- void *user_event;
- char *str_event_name;
- void *virt_base; /* Process virtual base address of
- * mapped SM */
- u32 virt_size; /* Size of virtual space in bytes */
- struct dsp_streamattrin *stream_attr_in;
-};
-
-struct stream_info {
- enum dsp_strmmode strm_mode; /* transport mode of
- * stream(DMA, ZEROCOPY..) */
- u32 segment_id; /* Segment strm allocs from. 0 is local mem */
- void *virt_base; /* " " Stream'process virt base */
- struct dsp_streaminfo *user_strm; /* User's stream information
- * returned */
-};
-
-#endif /* STRMDEFS_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h
deleted file mode 100644
index fc19b9707087..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/sync.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * sync.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Provide synchronization services.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef _SYNC_H
-#define _SYNC_H
-
-#include <dspbridge/dbdefs.h>
-#include <dspbridge/host_os.h>
-
-
-/* Special timeout value indicating an infinite wait: */
-#define SYNC_INFINITE 0xffffffff
-
-/**
- * struct sync_object - the basic sync_object structure
- * @comp: use to signal events
- * @multi_comp: use to signal multiple events.
- *
- */
-struct sync_object{
- struct completion comp;
- struct completion *multi_comp;
-};
-
-/**
- * sync_init_event() - set initial state for a sync_event element
- * @event: event to be initialized.
- *
- * Set the initial state for a sync_event element.
- */
-
-static inline void sync_init_event(struct sync_object *event)
-{
- init_completion(&event->comp);
- event->multi_comp = NULL;
-}
-
-/**
- * sync_reset_event() - reset a sync_event element
- * @event: event to be reset.
- *
- * This function reset to the initial state to @event.
- */
-
-static inline void sync_reset_event(struct sync_object *event)
-{
- reinit_completion(&event->comp);
- event->multi_comp = NULL;
-}
-
-/**
- * sync_set_event() - set or signal and specified event
- * @event: Event to be set..
- *
- * set the @event, if there is an thread waiting for the event
- * it will be waken up, this function only wakes one thread.
- */
-
-void sync_set_event(struct sync_object *event);
-
-/**
- * sync_wait_on_event() - waits for a event to be set.
- * @event: events to wait for it.
- * @timeout timeout on waiting for the evetn.
- *
- * This function will wait until @event is set or until timeout. In case of
- * success the function will return 0 and
- * in case of timeout the function will return -ETIME
- * in case of signal the function will return -ERESTARTSYS
- */
-
-static inline int sync_wait_on_event(struct sync_object *event,
- unsigned timeout)
-{
- int res;
-
- res = wait_for_completion_interruptible_timeout(&event->comp,
- msecs_to_jiffies(timeout));
- if (!res)
- res = -ETIME;
- else if (res > 0)
- res = 0;
-
- return res;
-}
-
-/**
- * sync_wait_on_multiple_events() - waits for multiple events to be set.
- * @events: Array of events to wait for them.
- * @count: number of elements of the array.
- * @timeout timeout on waiting for the evetns.
- * @pu_index index of the event set.
- *
- * This function will wait until any of the array element is set or until
- * timeout. In case of success the function will return 0 and
- * @pu_index will store the index of the array element set and in case
- * of timeout the function will return -ETIME.
- */
-
-int sync_wait_on_multiple_events(struct sync_object **events,
- unsigned count, unsigned timeout,
- unsigned *index);
-
-#endif /* _SYNC_H */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h b/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h
deleted file mode 100644
index b4951a1381e7..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/uuidutil.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * uuidutil.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This file contains the specification of UUID helper functions.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef UUIDUTIL_
-#define UUIDUTIL_
-
-#define MAXUUIDLEN 37
-
-#endif /* UUIDUTIL_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/wdt.h b/drivers/staging/tidspbridge/include/dspbridge/wdt.h
deleted file mode 100644
index 36193db2e9a3..000000000000
--- a/drivers/staging/tidspbridge/include/dspbridge/wdt.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * wdt.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * IO dispatcher for a shared memory channel driver.
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef __DSP_WDT3_H_
-#define __DSP_WDT3_H_
-
-/* WDT defines */
-#define OMAP3_WDT3_ISR_OFFSET 0x0018
-
-
-/**
- * struct dsp_wdt_setting - the basic dsp_wdt_setting structure
- * @reg_base: pointer to the base of the wdt registers
- * @sm_wdt: pointer to flags in shared memory
- * @wdt3_tasklet tasklet to manage wdt event
- * @fclk handle to wdt3 functional clock
- * @iclk handle to wdt3 interface clock
- *
- * This struct is used in the function to manage wdt3.
- */
-
-struct dsp_wdt_setting {
- void __iomem *reg_base;
- struct shm *sm_wdt;
- struct tasklet_struct wdt3_tasklet;
- struct clk *fclk;
- struct clk *iclk;
-};
-
-/**
- * dsp_wdt_init() - initialize wdt3 module.
- *
- * This function initialize to wdt3 module, so that
- * other wdt3 function can be used.
- */
-int dsp_wdt_init(void);
-
-/**
- * dsp_wdt_exit() - initialize wdt3 module.
- *
- * This function frees all resources allocated for wdt3 module.
- */
-void dsp_wdt_exit(void);
-
-/**
- * dsp_wdt_enable() - enable/disable wdt3
- * @enable: bool value to enable/disable wdt3
- *
- * This function enables or disables wdt3 base on @enable value.
- *
- */
-void dsp_wdt_enable(bool enable);
-
-/**
- * dsp_wdt_sm_set() - store pointer to the share memory
- * @data: pointer to dspbridge share memory
- *
- * This function is used to pass a valid pointer to share memory,
- * so that the flags can be set in order DSP side can read them.
- *
- */
-void dsp_wdt_sm_set(void *data);
-
-#endif
-
diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c
deleted file mode 100644
index 4bd8686f2355..000000000000
--- a/drivers/staging/tidspbridge/pmgr/chnl.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * chnl.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP API channel interface: multiplexes data streams through the single
- * physical link managed by a Bridge Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/proc.h>
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/chnlpriv.h>
-#include <chnlobj.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/chnl.h>
-
-/*
- * ======== chnl_create ========
- * Purpose:
- * Create a channel manager object, responsible for opening new channels
- * and closing old ones for a given 'Bridge board.
- */
-int chnl_create(struct chnl_mgr **channel_mgr,
- struct dev_object *hdev_obj,
- const struct chnl_mgrattrs *mgr_attrts)
-{
- int status;
- struct chnl_mgr *hchnl_mgr;
- struct chnl_mgr_ *chnl_mgr_obj = NULL;
-
- *channel_mgr = NULL;
-
- /* Validate args: */
- if ((0 < mgr_attrts->max_channels) &&
- (mgr_attrts->max_channels <= CHNL_MAXCHANNELS))
- status = 0;
- else if (mgr_attrts->max_channels == 0)
- status = -EINVAL;
- else
- status = -ECHRNG;
-
- if (mgr_attrts->word_size == 0)
- status = -EINVAL;
-
- if (!status) {
- status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
- if (!status && hchnl_mgr != NULL)
- status = -EEXIST;
-
- }
-
- if (!status) {
- struct bridge_drv_interface *intf_fxns;
- dev_get_intf_fxns(hdev_obj, &intf_fxns);
- /* Let Bridge channel module finish the create: */
- status = (*intf_fxns->chnl_create) (&hchnl_mgr, hdev_obj,
- mgr_attrts);
- if (!status) {
- /* Fill in DSP API channel module's fields of the
- * chnl_mgr structure */
- chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
- chnl_mgr_obj->intf_fxns = intf_fxns;
- /* Finally, return the new channel manager handle: */
- *channel_mgr = hchnl_mgr;
- }
- }
-
- return status;
-}
-
-/*
- * ======== chnl_destroy ========
- * Purpose:
- * Close all open channels, and destroy the channel manager.
- */
-int chnl_destroy(struct chnl_mgr *hchnl_mgr)
-{
- struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
- struct bridge_drv_interface *intf_fxns;
- int status;
-
- if (chnl_mgr_obj) {
- intf_fxns = chnl_mgr_obj->intf_fxns;
- /* Let Bridge channel module destroy the chnl_mgr: */
- status = (*intf_fxns->chnl_destroy) (hchnl_mgr);
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/pmgr/chnlobj.h b/drivers/staging/tidspbridge/pmgr/chnlobj.h
deleted file mode 100644
index 6795e0aa8fd6..000000000000
--- a/drivers/staging/tidspbridge/pmgr/chnlobj.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * chnlobj.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Structure subcomponents of channel class library channel objects which
- * are exposed to DSP API from Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef CHNLOBJ_
-#define CHNLOBJ_
-
-#include <dspbridge/chnldefs.h>
-#include <dspbridge/dspdefs.h>
-
-/*
- * This struct is the first field in a chnl_mgr struct. Other. implementation
- * specific fields follow this structure in memory.
- */
-struct chnl_mgr_ {
- /* These must be the first fields in a chnl_mgr struct: */
-
- /* Function interface to Bridge driver. */
- struct bridge_drv_interface *intf_fxns;
-};
-
-/*
- * This struct is the first field in a chnl_object struct. Other,
- * implementation specific fields follow this structure in memory.
- */
-struct chnl_object_ {
- /* These must be the first fields in a chnl_object struct: */
- struct chnl_mgr_ *chnl_mgr_obj; /* Pointer back to channel manager. */
-};
-
-#endif /* CHNLOBJ_ */
diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c
deleted file mode 100644
index f961e0ec9da8..000000000000
--- a/drivers/staging/tidspbridge/pmgr/cmm.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * cmm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Communication(Shared) Memory Management(CMM) module provides
- * shared memory management services for DSP/BIOS Bridge data streaming
- * and messaging.
- *
- * Multiple shared memory segments can be registered with CMM.
- * Each registered SM segment is represented by a SM "allocator" that
- * describes a block of physically contiguous shared memory used for
- * future allocations by CMM.
- *
- * Memory is coalesced back to the appropriate heap when a buffer is
- * freed.
- *
- * Notes:
- * Va: Virtual address.
- * Pa: Physical or kernel system address.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-#include <linux/list.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/proc.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/cmm.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define NEXT_PA(pnode) (pnode->pa + pnode->size)
-
-/* Other bus/platform translations */
-#define DSPPA2GPPPA(base, x, y) ((x)+(y))
-#define GPPPA2DSPPA(base, x, y) ((x)-(y))
-
-/*
- * Allocators define a block of contiguous memory used for future allocations.
- *
- * sma - shared memory allocator.
- * vma - virtual memory allocator.(not used).
- */
-struct cmm_allocator { /* sma */
- unsigned int shm_base; /* Start of physical SM block */
- u32 sm_size; /* Size of SM block in bytes */
- unsigned int vm_base; /* Start of VM block. (Dev driver
- * context for 'sma') */
- u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this
- * SM space */
- s8 c_factor; /* DSPPa to GPPPa Conversion Factor */
- unsigned int dsp_base; /* DSP virt base byte address */
- u32 dsp_size; /* DSP seg size in bytes */
- struct cmm_object *cmm_mgr; /* back ref to parent mgr */
- /* node list of available memory */
- struct list_head free_list;
- /* node list of memory in use */
- struct list_head in_use_list;
-};
-
-struct cmm_xlator { /* Pa<->Va translator object */
- /* CMM object this translator associated */
- struct cmm_object *cmm_mgr;
- /*
- * Client process virtual base address that corresponds to phys SM
- * base address for translator's seg_id.
- * Only 1 segment ID currently supported.
- */
- unsigned int virt_base; /* virtual base address */
- u32 virt_size; /* size of virt space in bytes */
- u32 seg_id; /* Segment Id */
-};
-
-/* CMM Mgr */
-struct cmm_object {
- /*
- * Cmm Lock is used to serialize access mem manager for multi-threads.
- */
- struct mutex cmm_lock; /* Lock to access cmm mgr */
- struct list_head node_free_list; /* Free list of memory nodes */
- u32 min_block_size; /* Min SM block; default 16 bytes */
- u32 page_size; /* Memory Page size (1k/4k) */
- /* GPP SM segment ptrs */
- struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS];
-};
-
-/* Default CMM Mgr attributes */
-static struct cmm_mgrattrs cmm_dfltmgrattrs = {
- /* min_block_size, min block size(bytes) allocated by cmm mgr */
- 16
-};
-
-/* Default allocation attributes */
-static struct cmm_attrs cmm_dfltalctattrs = {
- 1 /* seg_id, default segment Id for allocator */
-};
-
-/* Address translator default attrs */
-static struct cmm_xlatorattrs cmm_dfltxlatorattrs = {
- /* seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */
- 1,
- 0, /* dsp_bufs */
- 0, /* dsp_buf_size */
- NULL, /* vm_base */
- 0, /* vm_size */
-};
-
-/* SM node representing a block of memory. */
-struct cmm_mnode {
- struct list_head link; /* must be 1st element */
- u32 pa; /* Phys addr */
- u32 va; /* Virtual address in device process context */
- u32 size; /* SM block size in bytes */
- u32 client_proc; /* Process that allocated this mem block */
-};
-
-/* ----------------------------------- Function Prototypes */
-static void add_to_free_list(struct cmm_allocator *allocator,
- struct cmm_mnode *pnode);
-static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj,
- u32 ul_seg_id);
-static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator,
- u32 usize);
-static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
- u32 dw_va, u32 ul_size);
-/* get available slot for new allocator */
-static s32 get_slot(struct cmm_object *cmm_mgr_obj);
-static void un_register_gppsm_seg(struct cmm_allocator *psma);
-
-/*
- * ======== cmm_calloc_buf ========
- * Purpose:
- * Allocate a SM buffer, zero contents, and return the physical address
- * and optional driver context virtual address(pp_buf_va).
- *
- * The freelist is sorted in increasing size order. Get the first
- * block that satifies the request and sort the remaining back on
- * the freelist; if large enough. The kept block is placed on the
- * inUseList.
- */
-void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize,
- struct cmm_attrs *pattrs, void **pp_buf_va)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- void *buf_pa = NULL;
- struct cmm_mnode *pnode = NULL;
- struct cmm_mnode *new_node = NULL;
- struct cmm_allocator *allocator = NULL;
- u32 delta_size;
- u8 *pbyte = NULL;
- s32 cnt;
-
- if (pattrs == NULL)
- pattrs = &cmm_dfltalctattrs;
-
- if (pp_buf_va != NULL)
- *pp_buf_va = NULL;
-
- if (cmm_mgr_obj && (usize != 0)) {
- if (pattrs->seg_id > 0) {
- /* SegId > 0 is SM */
- /* get the allocator object for this segment id */
- allocator =
- get_allocator(cmm_mgr_obj, pattrs->seg_id);
- /* keep block size a multiple of min_block_size */
- usize =
- ((usize - 1) & ~(cmm_mgr_obj->min_block_size -
- 1))
- + cmm_mgr_obj->min_block_size;
- mutex_lock(&cmm_mgr_obj->cmm_lock);
- pnode = get_free_block(allocator, usize);
- }
- if (pnode) {
- delta_size = (pnode->size - usize);
- if (delta_size >= cmm_mgr_obj->min_block_size) {
- /* create a new block with the leftovers and
- * add to freelist */
- new_node =
- get_node(cmm_mgr_obj, pnode->pa + usize,
- pnode->va + usize,
- (u32) delta_size);
- /* leftovers go free */
- add_to_free_list(allocator, new_node);
- /* adjust our node's size */
- pnode->size = usize;
- }
- /* Tag node with client process requesting allocation
- * We'll need to free up a process's alloc'd SM if the
- * client process goes away.
- */
- /* Return TGID instead of process handle */
- pnode->client_proc = current->tgid;
-
- /* put our node on InUse list */
- list_add_tail(&pnode->link, &allocator->in_use_list);
- buf_pa = (void *)pnode->pa; /* physical address */
- /* clear mem */
- pbyte = (u8 *) pnode->va;
- for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++)
- *pbyte = 0;
-
- if (pp_buf_va != NULL) {
- /* Virtual address */
- *pp_buf_va = (void *)pnode->va;
- }
- }
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
- }
- return buf_pa;
-}
-
-/*
- * ======== cmm_create ========
- * Purpose:
- * Create a communication memory manager object.
- */
-int cmm_create(struct cmm_object **ph_cmm_mgr,
- struct dev_object *hdev_obj,
- const struct cmm_mgrattrs *mgr_attrts)
-{
- struct cmm_object *cmm_obj = NULL;
- int status = 0;
-
- *ph_cmm_mgr = NULL;
- /* create, zero, and tag a cmm mgr object */
- cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL);
- if (!cmm_obj)
- return -ENOMEM;
-
- if (mgr_attrts == NULL)
- mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */
-
- /* save away smallest block allocation for this cmm mgr */
- cmm_obj->min_block_size = mgr_attrts->min_block_size;
- cmm_obj->page_size = PAGE_SIZE;
-
- /* create node free list */
- INIT_LIST_HEAD(&cmm_obj->node_free_list);
- mutex_init(&cmm_obj->cmm_lock);
- *ph_cmm_mgr = cmm_obj;
-
- return status;
-}
-
-/*
- * ======== cmm_destroy ========
- * Purpose:
- * Release the communication memory manager resources.
- */
-int cmm_destroy(struct cmm_object *hcmm_mgr, bool force)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- struct cmm_info temp_info;
- int status = 0;
- s32 slot_seg;
- struct cmm_mnode *node, *tmp;
-
- if (!hcmm_mgr) {
- status = -EFAULT;
- return status;
- }
- mutex_lock(&cmm_mgr_obj->cmm_lock);
- /* If not force then fail if outstanding allocations exist */
- if (!force) {
- /* Check for outstanding memory allocations */
- status = cmm_get_info(hcmm_mgr, &temp_info);
- if (!status) {
- if (temp_info.total_in_use_cnt > 0) {
- /* outstanding allocations */
- status = -EPERM;
- }
- }
- }
- if (!status) {
- /* UnRegister SM allocator */
- for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) {
- if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] != NULL) {
- un_register_gppsm_seg
- (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg]);
- /* Set slot to NULL for future reuse */
- cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = NULL;
- }
- }
- }
- list_for_each_entry_safe(node, tmp, &cmm_mgr_obj->node_free_list,
- link) {
- list_del(&node->link);
- kfree(node);
- }
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
- if (!status) {
- /* delete CS & cmm mgr object */
- mutex_destroy(&cmm_mgr_obj->cmm_lock);
- kfree(cmm_mgr_obj);
- }
- return status;
-}
-
-/*
- * ======== cmm_free_buf ========
- * Purpose:
- * Free the given buffer.
- */
-int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- int status = -EFAULT;
- struct cmm_mnode *curr, *tmp;
- struct cmm_allocator *allocator;
- struct cmm_attrs *pattrs;
-
- if (ul_seg_id == 0) {
- pattrs = &cmm_dfltalctattrs;
- ul_seg_id = pattrs->seg_id;
- }
- if (!hcmm_mgr || !(ul_seg_id > 0)) {
- status = -EFAULT;
- return status;
- }
-
- allocator = get_allocator(cmm_mgr_obj, ul_seg_id);
- if (!allocator)
- return status;
-
- mutex_lock(&cmm_mgr_obj->cmm_lock);
- list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, link) {
- if (curr->pa == (u32) buf_pa) {
- list_del(&curr->link);
- add_to_free_list(allocator, curr);
- status = 0;
- break;
- }
- }
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
-
- return status;
-}
-
-/*
- * ======== cmm_get_handle ========
- * Purpose:
- * Return the communication memory manager object for this device.
- * This is typically called from the client process.
- */
-int cmm_get_handle(void *hprocessor, struct cmm_object **ph_cmm_mgr)
-{
- int status = 0;
- struct dev_object *hdev_obj;
-
- if (hprocessor != NULL)
- status = proc_get_dev_object(hprocessor, &hdev_obj);
- else
- hdev_obj = dev_get_first(); /* default */
-
- if (!status)
- status = dev_get_cmm_mgr(hdev_obj, ph_cmm_mgr);
-
- return status;
-}
-
-/*
- * ======== cmm_get_info ========
- * Purpose:
- * Return the current memory utilization information.
- */
-int cmm_get_info(struct cmm_object *hcmm_mgr,
- struct cmm_info *cmm_info_obj)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- u32 ul_seg;
- int status = 0;
- struct cmm_allocator *altr;
- struct cmm_mnode *curr;
-
- if (!hcmm_mgr) {
- status = -EFAULT;
- return status;
- }
- mutex_lock(&cmm_mgr_obj->cmm_lock);
- cmm_info_obj->num_gppsm_segs = 0; /* # of SM segments */
- /* Total # of outstanding alloc */
- cmm_info_obj->total_in_use_cnt = 0;
- /* min block size */
- cmm_info_obj->min_block_size = cmm_mgr_obj->min_block_size;
- /* check SM memory segments */
- for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) {
- /* get the allocator object for this segment id */
- altr = get_allocator(cmm_mgr_obj, ul_seg);
- if (!altr)
- continue;
- cmm_info_obj->num_gppsm_segs++;
- cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa =
- altr->shm_base - altr->dsp_size;
- cmm_info_obj->seg_info[ul_seg - 1].total_seg_size =
- altr->dsp_size + altr->sm_size;
- cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa =
- altr->shm_base;
- cmm_info_obj->seg_info[ul_seg - 1].gpp_size =
- altr->sm_size;
- cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va =
- altr->dsp_base;
- cmm_info_obj->seg_info[ul_seg - 1].dsp_size =
- altr->dsp_size;
- cmm_info_obj->seg_info[ul_seg - 1].seg_base_va =
- altr->vm_base - altr->dsp_size;
- cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt = 0;
-
- list_for_each_entry(curr, &altr->in_use_list, link) {
- cmm_info_obj->total_in_use_cnt++;
- cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt++;
- }
- }
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
- return status;
-}
-
-/*
- * ======== cmm_register_gppsm_seg ========
- * Purpose:
- * Register a block of SM with the CMM to be used for later GPP SM
- * allocations.
- */
-int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
- u32 dw_gpp_base_pa, u32 ul_size,
- u32 dsp_addr_offset, s8 c_factor,
- u32 dw_dsp_base, u32 ul_dsp_size,
- u32 *sgmt_id, u32 gpp_base_va)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- struct cmm_allocator *psma = NULL;
- int status = 0;
- struct cmm_mnode *new_node;
- s32 slot_seg;
-
- dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n",
- __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset,
- dw_dsp_base, ul_dsp_size, gpp_base_va);
-
- if (!hcmm_mgr)
- return -EFAULT;
-
- /* make sure we have room for another allocator */
- mutex_lock(&cmm_mgr_obj->cmm_lock);
-
- slot_seg = get_slot(cmm_mgr_obj);
- if (slot_seg < 0) {
- status = -EPERM;
- goto func_end;
- }
-
- /* Check if input ul_size is big enough to alloc at least one block */
- if (ul_size < cmm_mgr_obj->min_block_size) {
- status = -EINVAL;
- goto func_end;
- }
-
- /* create, zero, and tag an SM allocator object */
- psma = kzalloc(sizeof(struct cmm_allocator), GFP_KERNEL);
- if (!psma) {
- status = -ENOMEM;
- goto func_end;
- }
-
- psma->cmm_mgr = hcmm_mgr; /* ref to parent */
- psma->shm_base = dw_gpp_base_pa; /* SM Base phys */
- psma->sm_size = ul_size; /* SM segment size in bytes */
- psma->vm_base = gpp_base_va;
- psma->dsp_phys_addr_offset = dsp_addr_offset;
- psma->c_factor = c_factor;
- psma->dsp_base = dw_dsp_base;
- psma->dsp_size = ul_dsp_size;
- if (psma->vm_base == 0) {
- status = -EPERM;
- goto func_end;
- }
- /* return the actual segment identifier */
- *sgmt_id = (u32) slot_seg + 1;
-
- INIT_LIST_HEAD(&psma->free_list);
- INIT_LIST_HEAD(&psma->in_use_list);
-
- /* Get a mem node for this hunk-o-memory */
- new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa,
- psma->vm_base, ul_size);
- /* Place node on the SM allocator's free list */
- if (new_node) {
- list_add_tail(&new_node->link, &psma->free_list);
- } else {
- status = -ENOMEM;
- goto func_end;
- }
- /* make entry */
- cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = psma;
-
-func_end:
- /* Cleanup allocator */
- if (status && psma)
- un_register_gppsm_seg(psma);
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
-
- return status;
-}
-
-/*
- * ======== cmm_un_register_gppsm_seg ========
- * Purpose:
- * UnRegister GPP SM segments with the CMM.
- */
-int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
- u32 ul_seg_id)
-{
- struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr;
- int status = 0;
- struct cmm_allocator *psma;
- u32 ul_id = ul_seg_id;
-
- if (!hcmm_mgr)
- return -EFAULT;
-
- if (ul_seg_id == CMM_ALLSEGMENTS)
- ul_id = 1;
-
- if ((ul_id <= 0) || (ul_id > CMM_MAXGPPSEGS))
- return -EINVAL;
-
- /*
- * FIXME: CMM_MAXGPPSEGS == 1. why use a while cycle? Seems to me like
- * the ul_seg_id is not needed here. It must be always 1.
- */
- while (ul_id <= CMM_MAXGPPSEGS) {
- mutex_lock(&cmm_mgr_obj->cmm_lock);
- /* slot = seg_id-1 */
- psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1];
- if (psma != NULL) {
- un_register_gppsm_seg(psma);
- /* Set alctr ptr to NULL for future reuse */
- cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1] = NULL;
- } else if (ul_seg_id != CMM_ALLSEGMENTS) {
- status = -EPERM;
- }
- mutex_unlock(&cmm_mgr_obj->cmm_lock);
- if (ul_seg_id != CMM_ALLSEGMENTS)
- break;
-
- ul_id++;
- } /* end while */
- return status;
-}
-
-/*
- * ======== un_register_gppsm_seg ========
- * Purpose:
- * UnRegister the SM allocator by freeing all its resources and
- * nulling cmm mgr table entry.
- * Note:
- * This routine is always called within cmm lock crit sect.
- */
-static void un_register_gppsm_seg(struct cmm_allocator *psma)
-{
- struct cmm_mnode *curr, *tmp;
-
- /* free nodes on free list */
- list_for_each_entry_safe(curr, tmp, &psma->free_list, link) {
- list_del(&curr->link);
- kfree(curr);
- }
-
- /* free nodes on InUse list */
- list_for_each_entry_safe(curr, tmp, &psma->in_use_list, link) {
- list_del(&curr->link);
- kfree(curr);
- }
-
- if ((void *)psma->vm_base != NULL)
- MEM_UNMAP_LINEAR_ADDRESS((void *)psma->vm_base);
-
- /* Free allocator itself */
- kfree(psma);
-}
-
-/*
- * ======== get_slot ========
- * Purpose:
- * An available slot # is returned. Returns negative on failure.
- */
-static s32 get_slot(struct cmm_object *cmm_mgr_obj)
-{
- s32 slot_seg = -1; /* neg on failure */
- /* get first available slot in cmm mgr SMSegTab[] */
- for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) {
- if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL)
- break;
-
- }
- if (slot_seg == CMM_MAXGPPSEGS)
- slot_seg = -1; /* failed */
-
- return slot_seg;
-}
-
-/*
- * ======== get_node ========
- * Purpose:
- * Get a memory node from freelist or create a new one.
- */
-static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
- u32 dw_va, u32 ul_size)
-{
- struct cmm_mnode *pnode;
-
- /* Check cmm mgr's node freelist */
- if (list_empty(&cmm_mgr_obj->node_free_list)) {
- pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL);
- if (!pnode)
- return NULL;
- } else {
- /* surely a valid element */
- pnode = list_first_entry(&cmm_mgr_obj->node_free_list,
- struct cmm_mnode, link);
- list_del_init(&pnode->link);
- }
-
- pnode->pa = dw_pa;
- pnode->va = dw_va;
- pnode->size = ul_size;
-
- return pnode;
-}
-
-/*
- * ======== delete_node ========
- * Purpose:
- * Put a memory node on the cmm nodelist for later use.
- * Doesn't actually delete the node. Heap thrashing friendly.
- */
-static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode)
-{
- list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list);
-}
-
-/*
- * ====== get_free_block ========
- * Purpose:
- * Scan the free block list and return the first block that satisfies
- * the size.
- */
-static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator,
- u32 usize)
-{
- struct cmm_mnode *node, *tmp;
-
- if (!allocator)
- return NULL;
-
- list_for_each_entry_safe(node, tmp, &allocator->free_list, link) {
- if (usize <= node->size) {
- list_del(&node->link);
- return node;
- }
- }
-
- return NULL;
-}
-
-/*
- * ======== add_to_free_list ========
- * Purpose:
- * Coalesce node into the freelist in ascending size order.
- */
-static void add_to_free_list(struct cmm_allocator *allocator,
- struct cmm_mnode *node)
-{
- struct cmm_mnode *curr;
-
- if (!node) {
- pr_err("%s: failed - node is NULL\n", __func__);
- return;
- }
-
- list_for_each_entry(curr, &allocator->free_list, link) {
- if (NEXT_PA(curr) == node->pa) {
- curr->size += node->size;
- delete_node(allocator->cmm_mgr, node);
- return;
- }
- if (curr->pa == NEXT_PA(node)) {
- curr->pa = node->pa;
- curr->va = node->va;
- curr->size += node->size;
- delete_node(allocator->cmm_mgr, node);
- return;
- }
- }
- list_for_each_entry(curr, &allocator->free_list, link) {
- if (curr->size >= node->size) {
- list_add_tail(&node->link, &curr->link);
- return;
- }
- }
- list_add_tail(&node->link, &allocator->free_list);
-}
-
-/*
- * ======== get_allocator ========
- * Purpose:
- * Return the allocator for the given SM Segid.
- * SegIds: 1,2,3..max.
- */
-static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj,
- u32 ul_seg_id)
-{
- return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1];
-}
-
-/*
- * The CMM_Xlator[xxx] routines below are used by Node and Stream
- * to perform SM address translation to the client process address space.
- * A "translator" object is created by a node/stream for each SM seg used.
- */
-
-/*
- * ======== cmm_xlator_create ========
- * Purpose:
- * Create an address translator object.
- */
-int cmm_xlator_create(struct cmm_xlatorobject **xlator,
- struct cmm_object *hcmm_mgr,
- struct cmm_xlatorattrs *xlator_attrs)
-{
- struct cmm_xlator *xlator_object = NULL;
- int status = 0;
-
- *xlator = NULL;
- if (xlator_attrs == NULL)
- xlator_attrs = &cmm_dfltxlatorattrs; /* set defaults */
-
- xlator_object = kzalloc(sizeof(struct cmm_xlator), GFP_KERNEL);
- if (xlator_object != NULL) {
- xlator_object->cmm_mgr = hcmm_mgr; /* ref back to CMM */
- /* SM seg_id */
- xlator_object->seg_id = xlator_attrs->seg_id;
- } else {
- status = -ENOMEM;
- }
- if (!status)
- *xlator = (struct cmm_xlatorobject *)xlator_object;
-
- return status;
-}
-
-/*
- * ======== cmm_xlator_alloc_buf ========
- */
-void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf,
- u32 pa_size)
-{
- struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
- void *pbuf = NULL;
- void *tmp_va_buff;
- struct cmm_attrs attrs;
-
- if (xlator_obj) {
- attrs.seg_id = xlator_obj->seg_id;
- __raw_writel(0, va_buf);
- /* Alloc SM */
- pbuf =
- cmm_calloc_buf(xlator_obj->cmm_mgr, pa_size, &attrs, NULL);
- if (pbuf) {
- /* convert to translator(node/strm) process Virtual
- * address */
- tmp_va_buff = cmm_xlator_translate(xlator,
- pbuf, CMM_PA2VA);
- __raw_writel((u32)tmp_va_buff, va_buf);
- }
- }
- return pbuf;
-}
-
-/*
- * ======== cmm_xlator_free_buf ========
- * Purpose:
- * Free the given SM buffer and descriptor.
- * Does not free virtual memory.
- */
-int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va)
-{
- struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
- int status = -EPERM;
- void *buf_pa = NULL;
-
- if (xlator_obj) {
- /* convert Va to Pa so we can free it. */
- buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA);
- if (buf_pa) {
- status = cmm_free_buf(xlator_obj->cmm_mgr, buf_pa,
- xlator_obj->seg_id);
- if (status) {
- /* Uh oh, this shouldn't happen. Descriptor
- * gone! */
- pr_err("%s, line %d: Assertion failed\n",
- __FILE__, __LINE__);
- }
- }
- }
- return status;
-}
-
-/*
- * ======== cmm_xlator_info ========
- * Purpose:
- * Set/Get translator info.
- */
-int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 **paddr,
- u32 ul_size, u32 segm_id, bool set_info)
-{
- struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
- int status = 0;
-
- if (xlator_obj) {
- if (set_info) {
- /* set translators virtual address range */
- xlator_obj->virt_base = (u32) *paddr;
- xlator_obj->virt_size = ul_size;
- } else { /* return virt base address */
- *paddr = (u8 *) xlator_obj->virt_base;
- }
- } else {
- status = -EFAULT;
- }
- return status;
-}
-
-/*
- * ======== cmm_xlator_translate ========
- */
-void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr,
- enum cmm_xlatetype xtype)
-{
- u32 dw_addr_xlate = 0;
- struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
- struct cmm_object *cmm_mgr_obj = NULL;
- struct cmm_allocator *allocator = NULL;
- u32 dw_offset = 0;
-
- if (!xlator_obj)
- goto loop_cont;
-
- cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr;
- /* get this translator's default SM allocator */
- allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1];
- if (!allocator)
- goto loop_cont;
-
- if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_VA2PA) ||
- (xtype == CMM_PA2VA)) {
- if (xtype == CMM_PA2VA) {
- /* Gpp Va = Va Base + offset */
- dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base -
- allocator->
- dsp_size);
- dw_addr_xlate = xlator_obj->virt_base + dw_offset;
- /* Check if translated Va base is in range */
- if ((dw_addr_xlate < xlator_obj->virt_base) ||
- (dw_addr_xlate >=
- (xlator_obj->virt_base +
- xlator_obj->virt_size))) {
- dw_addr_xlate = 0; /* bad address */
- }
- } else {
- /* Gpp PA = Gpp Base + offset */
- dw_offset =
- (u8 *) paddr - (u8 *) xlator_obj->virt_base;
- dw_addr_xlate =
- allocator->shm_base - allocator->dsp_size +
- dw_offset;
- }
- } else {
- dw_addr_xlate = (u32) paddr;
- }
- /*Now convert address to proper target physical address if needed */
- if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_PA2DSPPA)) {
- /* Got Gpp Pa now, convert to DSP Pa */
- dw_addr_xlate =
- GPPPA2DSPPA((allocator->shm_base - allocator->dsp_size),
- dw_addr_xlate,
- allocator->dsp_phys_addr_offset *
- allocator->c_factor);
- } else if (xtype == CMM_DSPPA2PA) {
- /* Got DSP Pa, convert to GPP Pa */
- dw_addr_xlate =
- DSPPA2GPPPA(allocator->shm_base - allocator->dsp_size,
- dw_addr_xlate,
- allocator->dsp_phys_addr_offset *
- allocator->c_factor);
- }
-loop_cont:
- return (void *)dw_addr_xlate;
-}
diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c
deleted file mode 100644
index 6c29379baf60..000000000000
--- a/drivers/staging/tidspbridge/pmgr/cod.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * cod.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This module implements DSP code management for the DSP/BIOS Bridge
- * environment. It is mostly a thin wrapper.
- *
- * This module provides an interface for loading both static and
- * dynamic code objects onto DSP systems.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-/* Include appropriate loader header file */
-#include <dspbridge/dbll.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/cod.h>
-
-/*
- * ======== cod_manager ========
- */
-struct cod_manager {
- struct dbll_tar_obj *target;
- struct dbll_library_obj *base_lib;
- bool loaded; /* Base library loaded? */
- u32 entry;
- struct dbll_fxns fxns;
- struct dbll_attrs attrs;
- char sz_zl_file[COD_MAXPATHLENGTH];
-};
-
-/*
- * ======== cod_libraryobj ========
- */
-struct cod_libraryobj {
- struct dbll_library_obj *dbll_lib;
- struct cod_manager *cod_mgr;
-};
-
-static struct dbll_fxns ldr_fxns = {
- (dbll_close_fxn) dbll_close,
- (dbll_create_fxn) dbll_create,
- (dbll_delete_fxn) dbll_delete,
- (dbll_exit_fxn) dbll_exit,
- (dbll_get_attrs_fxn) dbll_get_attrs,
- (dbll_get_addr_fxn) dbll_get_addr,
- (dbll_get_c_addr_fxn) dbll_get_c_addr,
- (dbll_get_sect_fxn) dbll_get_sect,
- (dbll_init_fxn) dbll_init,
- (dbll_load_fxn) dbll_load,
- (dbll_open_fxn) dbll_open,
- (dbll_read_sect_fxn) dbll_read_sect,
- (dbll_unload_fxn) dbll_unload,
-};
-
-static bool no_op(void);
-
-/*
- * File operations (originally were under kfile.c)
- */
-static s32 cod_f_close(struct file *filp)
-{
- /* Check for valid handle */
- if (!filp)
- return -EFAULT;
-
- filp_close(filp, NULL);
-
- /* we can't use 0 here */
- return 0;
-}
-
-static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode)
-{
- mm_segment_t fs;
- struct file *filp;
-
- fs = get_fs();
- set_fs(get_ds());
-
- /* ignore given mode and open file as read-only */
- filp = filp_open(psz_file_name, O_RDONLY, 0);
-
- if (IS_ERR(filp))
- filp = NULL;
-
- set_fs(fs);
-
- return filp;
-}
-
-static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count,
- struct file *filp)
-{
- /* check for valid file handle */
- if (!filp)
- return -EFAULT;
-
- if ((size > 0) && (count > 0) && pbuffer) {
- u32 dw_bytes_read;
- mm_segment_t fs;
-
- /* read from file */
- fs = get_fs();
- set_fs(get_ds());
- dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count,
- &(filp->f_pos));
- set_fs(fs);
-
- if (!dw_bytes_read)
- return -EBADF;
-
- return dw_bytes_read / size;
- }
-
- return -EINVAL;
-}
-
-static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin)
-{
- loff_t dw_cur_pos;
-
- /* check for valid file handle */
- if (!filp)
- return -EFAULT;
-
- /* based on the origin flag, move the internal pointer */
- dw_cur_pos = filp->f_op->llseek(filp, offset, origin);
-
- if ((s32) dw_cur_pos < 0)
- return -EPERM;
-
- /* we can't use 0 here */
- return 0;
-}
-
-static s32 cod_f_tell(struct file *filp)
-{
- loff_t dw_cur_pos;
-
- if (!filp)
- return -EFAULT;
-
- /* Get current position */
- dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);
-
- if ((s32) dw_cur_pos < 0)
- return -EPERM;
-
- return dw_cur_pos;
-}
-
-/*
- * ======== cod_close ========
- */
-void cod_close(struct cod_libraryobj *lib)
-{
- struct cod_manager *hmgr;
-
- hmgr = lib->cod_mgr;
- hmgr->fxns.close_fxn(lib->dbll_lib);
-
- kfree(lib);
-}
-
-/*
- * ======== cod_create ========
- * Purpose:
- * Create an object to manage code on a DSP system.
- * This object can be used to load an initial program image with
- * arguments that can later be expanded with
- * dynamically loaded object files.
- *
- */
-int cod_create(struct cod_manager **mgr, char *str_zl_file)
-{
- struct cod_manager *mgr_new;
- struct dbll_attrs zl_attrs;
- int status = 0;
-
- /* assume failure */
- *mgr = NULL;
-
- mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
- if (mgr_new == NULL)
- return -ENOMEM;
-
- /* Set up loader functions */
- mgr_new->fxns = ldr_fxns;
-
- /* initialize the ZL module */
- mgr_new->fxns.init_fxn();
-
- zl_attrs.alloc = (dbll_alloc_fxn) no_op;
- zl_attrs.free = (dbll_free_fxn) no_op;
- zl_attrs.fread = (dbll_read_fxn) cod_f_read;
- zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
- zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
- zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
- zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
- zl_attrs.sym_lookup = NULL;
- zl_attrs.base_image = true;
- zl_attrs.log_write = NULL;
- zl_attrs.log_write_handle = NULL;
- zl_attrs.write = NULL;
- zl_attrs.rmm_handle = NULL;
- zl_attrs.input_params = NULL;
- zl_attrs.sym_handle = NULL;
- zl_attrs.sym_arg = NULL;
-
- mgr_new->attrs = zl_attrs;
-
- status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);
-
- if (status) {
- cod_delete(mgr_new);
- return -ESPIPE;
- }
-
- /* return the new manager */
- *mgr = mgr_new;
-
- return 0;
-}
-
-/*
- * ======== cod_delete ========
- * Purpose:
- * Delete a code manager object.
- */
-void cod_delete(struct cod_manager *cod_mgr_obj)
-{
- if (cod_mgr_obj->base_lib) {
- if (cod_mgr_obj->loaded)
- cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
- &cod_mgr_obj->attrs);
-
- cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
- }
- if (cod_mgr_obj->target) {
- cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target);
- cod_mgr_obj->fxns.exit_fxn();
- }
- kfree(cod_mgr_obj);
-}
-
-/*
- * ======== cod_get_base_lib ========
- * Purpose:
- * Get handle to the base image DBL library.
- */
-int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
- struct dbll_library_obj **plib)
-{
- int status = 0;
-
- *plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
-
- return status;
-}
-
-/*
- * ======== cod_get_base_name ========
- */
-int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
- u32 usize)
-{
- int status = 0;
-
- if (usize <= COD_MAXPATHLENGTH)
- strlcpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
- else
- status = -EPERM;
-
- return status;
-}
-
-/*
- * ======== cod_get_entry ========
- * Purpose:
- * Retrieve the entry point of a loaded DSP program image
- *
- */
-int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
-{
- *entry_pt = cod_mgr_obj->entry;
-
- return 0;
-}
-
-/*
- * ======== cod_get_loader ========
- * Purpose:
- * Get handle to the DBLL loader.
- */
-int cod_get_loader(struct cod_manager *cod_mgr_obj,
- struct dbll_tar_obj **loader)
-{
- int status = 0;
-
- *loader = (struct dbll_tar_obj *)cod_mgr_obj->target;
-
- return status;
-}
-
-/*
- * ======== cod_get_section ========
- * Purpose:
- * Retrieve the starting address and length of a section in the COFF file
- * given the section name.
- */
-int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
- u32 *addr, u32 *len)
-{
- struct cod_manager *cod_mgr_obj;
- int status = 0;
-
- *addr = 0;
- *len = 0;
- if (lib != NULL) {
- cod_mgr_obj = lib->cod_mgr;
- status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect,
- addr, len);
- } else {
- status = -ESPIPE;
- }
-
- return status;
-}
-
-/*
- * ======== cod_get_sym_value ========
- * Purpose:
- * Retrieve the value for the specified symbol. The symbol is first
- * searched for literally and then, if not found, searched for as a
- * C symbol.
- *
- */
-int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
- u32 *pul_value)
-{
- struct dbll_sym_val *dbll_sym;
-
- dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
- __func__, cod_mgr_obj, str_sym, pul_value);
- if (cod_mgr_obj->base_lib) {
- if (!cod_mgr_obj->fxns.
- get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) {
- if (!cod_mgr_obj->fxns.
- get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym,
- &dbll_sym))
- return -ESPIPE;
- }
- } else {
- return -ESPIPE;
- }
-
- *pul_value = dbll_sym->value;
-
- return 0;
-}
-
-/*
- * ======== cod_load_base ========
- * Purpose:
- * Load the initial program image, optionally with command-line arguments,
- * on the DSP system managed by the supplied handle. The program to be
- * loaded must be the first element of the args array and must be a fully
- * qualified pathname.
- * Details:
- * if num_argc doesn't match the number of arguments in the args array, the
- * args array is searched for a NULL terminating entry, and argc is
- * recalculated to reflect this. In this way, we can support NULL
- * terminating args arrays, if num_argc is very large.
- */
-int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
- cod_writefxn pfn_write, void *arb, char *envp[])
-{
- dbll_flags flags;
- struct dbll_attrs save_attrs;
- struct dbll_attrs new_attrs;
- int status;
- u32 i;
-
- /*
- * Make sure every argv[] stated in argc has a value, or change argc to
- * reflect true number in NULL terminated argv array.
- */
- for (i = 0; i < num_argc; i++) {
- if (args[i] == NULL) {
- num_argc = i;
- break;
- }
- }
-
- /* set the write function for this operation */
- cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs);
-
- new_attrs = save_attrs;
- new_attrs.write = (dbll_write_fxn) pfn_write;
- new_attrs.input_params = arb;
- new_attrs.alloc = (dbll_alloc_fxn) no_op;
- new_attrs.free = (dbll_free_fxn) no_op;
- new_attrs.log_write = NULL;
- new_attrs.log_write_handle = NULL;
-
- /* Load the image */
- flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
- status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags,
- &new_attrs,
- &cod_mgr_obj->entry);
- if (status)
- cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
-
- if (!status)
- cod_mgr_obj->loaded = true;
- else
- cod_mgr_obj->base_lib = NULL;
-
- return status;
-}
-
-/*
- * ======== cod_open ========
- * Open library for reading sections.
- */
-int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
- u32 flags, struct cod_libraryobj **lib_obj)
-{
- int status = 0;
- struct cod_libraryobj *lib = NULL;
-
- *lib_obj = NULL;
-
- lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
- if (lib == NULL)
- status = -ENOMEM;
-
- if (!status) {
- lib->cod_mgr = hmgr;
- status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags,
- &lib->dbll_lib);
- if (!status)
- *lib_obj = lib;
- }
-
- if (status)
- pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n",
- __func__, status, sz_coff_path, flags);
- return status;
-}
-
-/*
- * ======== cod_open_base ========
- * Purpose:
- * Open base image for reading sections.
- */
-int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
- dbll_flags flags)
-{
- int status = 0;
- struct dbll_library_obj *lib;
-
- /* if we previously opened a base image, close it now */
- if (hmgr->base_lib) {
- if (hmgr->loaded) {
- hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
- hmgr->loaded = false;
- }
- hmgr->fxns.close_fxn(hmgr->base_lib);
- hmgr->base_lib = NULL;
- }
- status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib);
- if (!status) {
- /* hang onto the library for subsequent sym table usage */
- hmgr->base_lib = lib;
- strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1);
- hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
- }
-
- if (status)
- pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__,
- status, sz_coff_path);
- return status;
-}
-
-/*
- * ======== cod_read_section ========
- * Purpose:
- * Retrieve the content of a code section given the section name.
- */
-int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
- char *str_content, u32 content_size)
-{
- int status = 0;
-
- if (lib != NULL)
- status =
- lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
- str_content, content_size);
- else
- status = -ESPIPE;
-
- return status;
-}
-
-/*
- * ======== no_op ========
- * Purpose:
- * No Operation.
- *
- */
-static bool no_op(void)
-{
- return true;
-}
diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c
deleted file mode 100644
index 8e21d1e47c9c..000000000000
--- a/drivers/staging/tidspbridge/pmgr/dbll.c
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * dbll.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-#include <dspbridge/gh.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-
-/* Dynamic loader library interface */
-#include <dspbridge/dynamic_loader.h>
-#include <dspbridge/getsection.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dbll.h>
-#include <dspbridge/rmm.h>
-
-/* Max buffer length */
-#define MAXEXPR 128
-
-#define DOFF_ALIGN(x) (((x) + 3) & ~3UL)
-
-/*
- * ======== struct dbll_tar_obj* ========
- * A target may have one or more libraries of symbols/code/data loaded
- * onto it, where a library is simply the symbols/code/data contained
- * in a DOFF file.
- */
-/*
- * ======== dbll_tar_obj ========
- */
-struct dbll_tar_obj {
- struct dbll_attrs attrs;
- struct dbll_library_obj *head; /* List of all opened libraries */
-};
-
-/*
- * The following 4 typedefs are "super classes" of the dynamic loader
- * library types used in dynamic loader functions (dynamic_loader.h).
- */
-/*
- * ======== dbll_stream ========
- * Contains dynamic_loader_stream
- */
-struct dbll_stream {
- struct dynamic_loader_stream dl_stream;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== ldr_symbol ========
- */
-struct ldr_symbol {
- struct dynamic_loader_sym dl_symbol;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== dbll_alloc ========
- */
-struct dbll_alloc {
- struct dynamic_loader_allocate dl_alloc;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== dbll_init_obj ========
- */
-struct dbll_init_obj {
- struct dynamic_loader_initialize dl_init;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== DBLL_Library ========
- * A library handle is returned by DBLL_Open() and is passed to dbll_load()
- * to load symbols/code/data, and to dbll_unload(), to remove the
- * symbols/code/data loaded by dbll_load().
- */
-
-/*
- * ======== dbll_library_obj ========
- */
-struct dbll_library_obj {
- struct dbll_library_obj *next; /* Next library in target's list */
- struct dbll_library_obj *prev; /* Previous in the list */
- struct dbll_tar_obj *target_obj; /* target for this library */
-
- /* Objects needed by dynamic loader */
- struct dbll_stream stream;
- struct ldr_symbol symbol;
- struct dbll_alloc allocate;
- struct dbll_init_obj init;
- void *dload_mod_obj;
-
- char *file_name; /* COFF file name */
- void *fp; /* Opaque file handle */
- u32 entry; /* Entry point */
- void *desc; /* desc of DOFF file loaded */
- u32 open_ref; /* Number of times opened */
- u32 load_ref; /* Number of times loaded */
- struct gh_t_hash_tab *sym_tab; /* Hash table of symbols */
- u32 pos;
-};
-
-/*
- * ======== dbll_symbol ========
- */
-struct dbll_symbol {
- struct dbll_sym_val value;
- char *name;
-};
-
-static void dof_close(struct dbll_library_obj *zl_lib);
-static int dof_open(struct dbll_library_obj *zl_lib);
-static s32 no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
- ldr_addr locn, struct ldr_section_info *info,
- unsigned bytsize);
-
-/*
- * Functions called by dynamic loader
- *
- */
-/* dynamic_loader_stream */
-static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
- unsigned bufsize);
-static int dbll_set_file_posn(struct dynamic_loader_stream *this,
- unsigned int pos);
-/* dynamic_loader_sym */
-static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
- const char *name);
-static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned module_id);
-static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned moduleid);
-static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
- unsigned module_id);
-static void *allocate(struct dynamic_loader_sym *this, unsigned memsize);
-static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr);
-static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
- va_list args);
-/* dynamic_loader_allocate */
-static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info, unsigned align);
-static void rmm_dealloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info);
-
-/* dynamic_loader_initialize */
-static int connect(struct dynamic_loader_initialize *this);
-static int read_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned bytes);
-static int write_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned nbytes);
-static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
- struct ldr_section_info *info, unsigned bytes,
- unsigned val);
-static int execute(struct dynamic_loader_initialize *this, ldr_addr start);
-static void release(struct dynamic_loader_initialize *this);
-
-/* symbol table hash functions */
-static u32 name_hash(const void *key);
-static bool name_match(const void *key, const void *sp);
-static void sym_delete(void *value);
-
-/* Symbol Redefinition */
-static int redefined_symbol;
-static int gbl_search = 1;
-
-/*
- * ======== dbll_close ========
- */
-void dbll_close(struct dbll_library_obj *zl_lib)
-{
- struct dbll_tar_obj *zl_target;
-
- zl_target = zl_lib->target_obj;
- zl_lib->open_ref--;
- if (zl_lib->open_ref == 0) {
- /* Remove library from list */
- if (zl_target->head == zl_lib)
- zl_target->head = zl_lib->next;
-
- if (zl_lib->prev)
- (zl_lib->prev)->next = zl_lib->next;
-
- if (zl_lib->next)
- (zl_lib->next)->prev = zl_lib->prev;
-
- /* Free DOF resources */
- dof_close(zl_lib);
- kfree(zl_lib->file_name);
-
- /* remove symbols from symbol table */
- if (zl_lib->sym_tab)
- gh_delete(zl_lib->sym_tab);
-
- /* remove the library object itself */
- kfree(zl_lib);
- zl_lib = NULL;
- }
-}
-
-/*
- * ======== dbll_create ========
- */
-int dbll_create(struct dbll_tar_obj **target_obj,
- struct dbll_attrs *pattrs)
-{
- struct dbll_tar_obj *pzl_target;
- int status = 0;
-
- /* Allocate DBL target object */
- pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL);
- if (target_obj != NULL) {
- if (pzl_target == NULL) {
- *target_obj = NULL;
- status = -ENOMEM;
- } else {
- pzl_target->attrs = *pattrs;
- *target_obj = (struct dbll_tar_obj *)pzl_target;
- }
- }
-
- return status;
-}
-
-/*
- * ======== dbll_delete ========
- */
-void dbll_delete(struct dbll_tar_obj *target)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
-
- kfree(zl_target);
-
-}
-
-/*
- * ======== dbll_exit ========
- * Discontinue usage of DBL module.
- */
-void dbll_exit(void)
-{
- /* do nothing */
-}
-
-/*
- * ======== dbll_get_addr ========
- * Get address of name in the specified library.
- */
-bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val)
-{
- struct dbll_symbol *sym;
-
- sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name);
- if (IS_ERR(sym))
- return false;
-
- *sym_val = &sym->value;
-
- dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p\n",
- __func__, zl_lib, name, sym_val);
- return true;
-}
-
-/*
- * ======== dbll_get_attrs ========
- * Retrieve the attributes of the target.
- */
-void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
-
- if ((pattrs != NULL) && (zl_target != NULL))
- *pattrs = zl_target->attrs;
-
-}
-
-/*
- * ======== dbll_get_c_addr ========
- * Get address of a "C" name in the specified library.
- */
-bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val)
-{
- struct dbll_symbol *sym;
- char cname[MAXEXPR + 1];
-
- cname[0] = '_';
-
- strncpy(cname + 1, name, sizeof(cname) - 2);
- cname[MAXEXPR] = '\0'; /* insure '\0' string termination */
-
- /* Check for C name, if not found */
- sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, cname);
- if (IS_ERR(sym))
- return false;
-
- *sym_val = &sym->value;
-
- return true;
-}
-
-/*
- * ======== dbll_get_sect ========
- * Get the base address and size (in bytes) of a COFF section.
- */
-int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
- u32 *psize)
-{
- u32 byte_size;
- bool opened_doff = false;
- const struct ldr_section_info *sect = NULL;
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- int status = 0;
-
- /* If DOFF file is not open, we open it. */
- if (zl_lib != NULL) {
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- } else {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- zl_lib->pos,
- SEEK_SET);
- }
- } else {
- status = -EFAULT;
- }
- if (!status) {
- byte_size = 1;
- if (dload_get_section_info(zl_lib->desc, name, &sect)) {
- *paddr = sect->load_addr;
- *psize = sect->size * byte_size;
- /* Make sure size is even for good swap */
- if (*psize % 2)
- (*psize)++;
-
- /* Align size */
- *psize = DOFF_ALIGN(*psize);
- } else {
- status = -ENXIO;
- }
- }
- if (opened_doff) {
- dof_close(zl_lib);
- opened_doff = false;
- }
-
- dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n",
- __func__, lib, name, paddr, psize, status);
-
- return status;
-}
-
-/*
- * ======== dbll_init ========
- */
-bool dbll_init(void)
-{
- /* do nothing */
-
- return true;
-}
-
-/*
- * ======== dbll_load ========
- */
-int dbll_load(struct dbll_library_obj *lib, dbll_flags flags,
- struct dbll_attrs *attrs, u32 *entry)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- struct dbll_tar_obj *dbzl;
- bool got_symbols = true;
- s32 err;
- int status = 0;
- bool opened_doff = false;
-
- /*
- * Load if not already loaded.
- */
- if (zl_lib->load_ref == 0 || !(flags & DBLL_DYNAMIC)) {
- dbzl = zl_lib->target_obj;
- dbzl->attrs = *attrs;
- /* Create a hash table for symbols if not already created */
- if (zl_lib->sym_tab == NULL) {
- got_symbols = false;
- zl_lib->sym_tab = gh_create(sizeof(struct dbll_symbol),
- name_hash,
- name_match, sym_delete);
- if (IS_ERR(zl_lib->sym_tab)) {
- status = PTR_ERR(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- }
-
- }
- /*
- * Set up objects needed by the dynamic loader
- */
- /* Stream */
- zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
- zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
- zl_lib->stream.lib = zl_lib;
- /* Symbol */
- zl_lib->symbol.dl_symbol.find_matching_symbol =
- dbll_find_symbol;
- if (got_symbols) {
- zl_lib->symbol.dl_symbol.add_to_symbol_table =
- find_in_symbol_table;
- } else {
- zl_lib->symbol.dl_symbol.add_to_symbol_table =
- dbll_add_to_symbol_table;
- }
- zl_lib->symbol.dl_symbol.purge_symbol_table =
- dbll_purge_symbol_table;
- zl_lib->symbol.dl_symbol.dload_allocate = allocate;
- zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
- zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
- zl_lib->symbol.lib = zl_lib;
- /* Allocate */
- zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
- zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
- zl_lib->allocate.lib = zl_lib;
- /* Init */
- zl_lib->init.dl_init.connect = connect;
- zl_lib->init.dl_init.readmem = read_mem;
- zl_lib->init.dl_init.writemem = write_mem;
- zl_lib->init.dl_init.fillmem = fill_mem;
- zl_lib->init.dl_init.execute = execute;
- zl_lib->init.dl_init.release = release;
- zl_lib->init.lib = zl_lib;
- /* If COFF file is not open, we open it. */
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- }
- if (!status) {
- zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell))
- (zl_lib->fp);
- /* Reset file cursor */
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- (long)0,
- SEEK_SET);
- symbols_reloaded = true;
- /* The 5th argument, DLOAD_INITBSS, tells the DLL
- * module to zero-init all BSS sections. In general,
- * this is not necessary and also increases load time.
- * We may want to make this configurable by the user */
- err = dynamic_load_module(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init,
- DLOAD_INITBSS,
- &zl_lib->dload_mod_obj);
-
- if (err != 0) {
- status = -EILSEQ;
- } else if (redefined_symbol) {
- zl_lib->load_ref++;
- dbll_unload(zl_lib, (struct dbll_attrs *)attrs);
- redefined_symbol = false;
- status = -EILSEQ;
- } else {
- *entry = zl_lib->entry;
- }
- }
- }
- if (!status)
- zl_lib->load_ref++;
-
- /* Clean up DOFF resources */
- if (opened_doff)
- dof_close(zl_lib);
-
- dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n",
- __func__, lib, flags, entry, status);
-
- return status;
-}
-
-/*
- * ======== dbll_open ========
- */
-int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags,
- struct dbll_library_obj **lib_obj)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
- struct dbll_library_obj *zl_lib = NULL;
- s32 err;
- int status = 0;
-
- zl_lib = zl_target->head;
- while (zl_lib != NULL) {
- if (strcmp(zl_lib->file_name, file) == 0) {
- /* Library is already opened */
- zl_lib->open_ref++;
- break;
- }
- zl_lib = zl_lib->next;
- }
- if (zl_lib == NULL) {
- /* Allocate DBL library object */
- zl_lib = kzalloc(sizeof(struct dbll_library_obj), GFP_KERNEL);
- if (zl_lib == NULL) {
- status = -ENOMEM;
- } else {
- zl_lib->pos = 0;
- /* Increment ref count to allow close on failure
- * later on */
- zl_lib->open_ref++;
- zl_lib->target_obj = zl_target;
- /* Keep a copy of the file name */
- zl_lib->file_name = kzalloc(strlen(file) + 1,
- GFP_KERNEL);
- if (zl_lib->file_name == NULL) {
- status = -ENOMEM;
- } else {
- strncpy(zl_lib->file_name, file,
- strlen(file) + 1);
- }
- zl_lib->sym_tab = NULL;
- }
- }
- /*
- * Set up objects needed by the dynamic loader
- */
- if (status)
- goto func_cont;
-
- /* Stream */
- zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
- zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
- zl_lib->stream.lib = zl_lib;
- /* Symbol */
- zl_lib->symbol.dl_symbol.add_to_symbol_table = dbll_add_to_symbol_table;
- zl_lib->symbol.dl_symbol.find_matching_symbol = dbll_find_symbol;
- zl_lib->symbol.dl_symbol.purge_symbol_table = dbll_purge_symbol_table;
- zl_lib->symbol.dl_symbol.dload_allocate = allocate;
- zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
- zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
- zl_lib->symbol.lib = zl_lib;
- /* Allocate */
- zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
- zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
- zl_lib->allocate.lib = zl_lib;
- /* Init */
- zl_lib->init.dl_init.connect = connect;
- zl_lib->init.dl_init.readmem = read_mem;
- zl_lib->init.dl_init.writemem = write_mem;
- zl_lib->init.dl_init.fillmem = fill_mem;
- zl_lib->init.dl_init.execute = execute;
- zl_lib->init.dl_init.release = release;
- zl_lib->init.lib = zl_lib;
- if (!status && zl_lib->fp == NULL)
- status = dof_open(zl_lib);
-
- zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp);
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET);
- /* Create a hash table for symbols if flag is set */
- if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB))
- goto func_cont;
-
- zl_lib->sym_tab =
- gh_create(sizeof(struct dbll_symbol), name_hash, name_match,
- sym_delete);
- if (IS_ERR(zl_lib->sym_tab)) {
- status = PTR_ERR(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- } else {
- /* Do a fake load to get symbols - set write func to no_op */
- zl_lib->init.dl_init.writemem = no_op;
- err = dynamic_open_module(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init, 0,
- &zl_lib->dload_mod_obj);
- if (err != 0) {
- status = -EILSEQ;
- } else {
- /* Now that we have the symbol table, we can unload */
- err = dynamic_unload_module(zl_lib->dload_mod_obj,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init);
- if (err != 0)
- status = -EILSEQ;
-
- zl_lib->dload_mod_obj = NULL;
- }
- }
-func_cont:
- if (!status) {
- if (zl_lib->open_ref == 1) {
- /* First time opened - insert in list */
- if (zl_target->head)
- (zl_target->head)->prev = zl_lib;
-
- zl_lib->prev = NULL;
- zl_lib->next = zl_target->head;
- zl_target->head = zl_lib;
- }
- *lib_obj = (struct dbll_library_obj *)zl_lib;
- } else {
- *lib_obj = NULL;
- if (zl_lib != NULL)
- dbll_close((struct dbll_library_obj *)zl_lib);
-
- }
-
- dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n",
- __func__, target, file, lib_obj, status);
-
- return status;
-}
-
-/*
- * ======== dbll_read_sect ========
- * Get the content of a COFF section.
- */
-int dbll_read_sect(struct dbll_library_obj *lib, char *name,
- char *buf, u32 size)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- bool opened_doff = false;
- u32 byte_size; /* size of bytes */
- u32 ul_sect_size; /* size of section */
- const struct ldr_section_info *sect = NULL;
- int status = 0;
-
- /* If DOFF file is not open, we open it. */
- if (zl_lib != NULL) {
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- } else {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- zl_lib->pos,
- SEEK_SET);
- }
- } else {
- status = -EFAULT;
- }
- if (status)
- goto func_cont;
-
- byte_size = 1;
- if (!dload_get_section_info(zl_lib->desc, name, &sect)) {
- status = -ENXIO;
- goto func_cont;
- }
- /*
- * Ensure the supplied buffer size is sufficient to store
- * the section buf to be read.
- */
- ul_sect_size = sect->size * byte_size;
- /* Make sure size is even for good swap */
- if (ul_sect_size % 2)
- ul_sect_size++;
-
- /* Align size */
- ul_sect_size = DOFF_ALIGN(ul_sect_size);
- if (ul_sect_size > size) {
- status = -EPERM;
- } else {
- if (!dload_get_section(zl_lib->desc, sect, buf))
- status = -EBADF;
-
- }
-func_cont:
- if (opened_doff) {
- dof_close(zl_lib);
- opened_doff = false;
- }
-
- dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n",
- __func__, lib, name, buf, size, status);
- return status;
-}
-
-/*
- * ======== dbll_unload ========
- */
-void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- s32 err = 0;
-
- dev_dbg(bridge, "%s: lib: %p\n", __func__, lib);
- zl_lib->load_ref--;
- /* Unload only if reference count is 0 */
- if (zl_lib->load_ref != 0)
- return;
-
- zl_lib->target_obj->attrs = *attrs;
- if (zl_lib->dload_mod_obj) {
- err = dynamic_unload_module(zl_lib->dload_mod_obj,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init);
- if (err != 0)
- dev_dbg(bridge, "%s: failed: 0x%x\n", __func__, err);
- }
- /* remove symbols from symbol table */
- if (zl_lib->sym_tab != NULL) {
- gh_delete(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- }
- /* delete DOFF desc since it holds *lots* of host OS
- * resources */
- dof_close(zl_lib);
-}
-
-/*
- * ======== dof_close ========
- */
-static void dof_close(struct dbll_library_obj *zl_lib)
-{
- if (zl_lib->desc) {
- dload_module_close(zl_lib->desc);
- zl_lib->desc = NULL;
- }
- /* close file */
- if (zl_lib->fp) {
- (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
- zl_lib->fp = NULL;
- }
-}
-
-/*
- * ======== dof_open ========
- */
-static int dof_open(struct dbll_library_obj *zl_lib)
-{
- void *open = *(zl_lib->target_obj->attrs.fopen);
- int status = 0;
-
- /* First open the file for the dynamic loader, then open COF */
- zl_lib->fp =
- (void *)((dbll_f_open_fxn) (open)) (zl_lib->file_name, "rb");
-
- /* Open DOFF module */
- if (zl_lib->fp && zl_lib->desc == NULL) {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0,
- SEEK_SET);
- zl_lib->desc =
- dload_module_open(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol);
- if (zl_lib->desc == NULL) {
- (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
- zl_lib->fp = NULL;
- status = -EBADF;
- }
- } else {
- status = -EBADF;
- }
-
- return status;
-}
-
-/*
- * ======== name_hash ========
- */
-static u32 name_hash(const void *key)
-{
- u32 hash;
- const char *name = key;
-
- hash = 0;
-
- while (*name) {
- hash <<= 1;
- hash ^= *name++;
- }
-
- return hash;
-}
-
-/*
- * ======== name_match ========
- */
-static bool name_match(const void *key, const void *sp)
-{
- if ((key != NULL) && (sp != NULL)) {
- if (strcmp(key, ((struct dbll_symbol *)sp)->name) == 0)
- return true;
- }
- return false;
-}
-
-/*
- * ======== no_op ========
- */
-static int no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
- ldr_addr locn, struct ldr_section_info *info, unsigned bytsize)
-{
- return 1;
-}
-
-/*
- * ======== sym_delete ========
- */
-static void sym_delete(void *value)
-{
- struct dbll_symbol *sp = (struct dbll_symbol *)value;
-
- kfree(sp->name);
-}
-
-/*
- * Dynamic Loader Functions
- */
-
-/* dynamic_loader_stream */
-/*
- * ======== dbll_read_buffer ========
- */
-static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
- unsigned bufsize)
-{
- struct dbll_stream *pstream = (struct dbll_stream *)this;
- struct dbll_library_obj *lib;
- int bytes_read = 0;
-
- lib = pstream->lib;
- if (lib != NULL) {
- bytes_read =
- (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize,
- lib->fp);
- }
- return bytes_read;
-}
-
-/*
- * ======== dbll_set_file_posn ========
- */
-static int dbll_set_file_posn(struct dynamic_loader_stream *this,
- unsigned int pos)
-{
- struct dbll_stream *pstream = (struct dbll_stream *)this;
- struct dbll_library_obj *lib;
- int status = 0; /* Success */
-
- lib = pstream->lib;
- if (lib != NULL) {
- status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos,
- SEEK_SET);
- }
-
- return status;
-}
-
-/* dynamic_loader_sym */
-
-/*
- * ======== dbll_find_symbol ========
- */
-static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
- const char *name)
-{
- struct dynload_symbol *ret_sym;
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dbll_sym_val *dbll_sym = NULL;
- bool status = false; /* Symbol not found yet */
-
- lib = ldr_sym->lib;
- if (lib != NULL) {
- if (lib->target_obj->attrs.sym_lookup) {
- /* Check current lib + base lib + dep lib +
- * persistent lib */
- status = (*(lib->target_obj->attrs.sym_lookup))
- (lib->target_obj->attrs.sym_handle,
- lib->target_obj->attrs.sym_arg,
- lib->target_obj->attrs.rmm_handle, name,
- &dbll_sym);
- } else {
- /* Just check current lib for symbol */
- status = dbll_get_addr((struct dbll_library_obj *)lib,
- (char *)name, &dbll_sym);
- if (!status) {
- status = dbll_get_c_addr(
- (struct dbll_library_obj *)
- lib, (char *)name,
- &dbll_sym);
- }
- }
- }
-
- if (!status && gbl_search)
- dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name);
-
- ret_sym = (struct dynload_symbol *)dbll_sym;
- return ret_sym;
-}
-
-/*
- * ======== find_in_symbol_table ========
- */
-static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned moduleid)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dbll_symbol *sym;
-
- lib = ldr_sym->lib;
- sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name);
-
- if (IS_ERR(sym))
- return NULL;
-
- return (struct dynload_symbol *)&sym->value;
-}
-
-/*
- * ======== dbll_add_to_symbol_table ========
- */
-static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned module_id)
-{
- struct dbll_symbol *sym_ptr = NULL;
- struct dbll_symbol symbol;
- struct dynload_symbol *dbll_sym = NULL;
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dynload_symbol *ret;
-
- lib = ldr_sym->lib;
-
- /* Check to see if symbol is already defined in symbol table */
- if (!(lib->target_obj->attrs.base_image)) {
- gbl_search = false;
- dbll_sym = dbll_find_symbol(this, name);
- gbl_search = true;
- if (dbll_sym) {
- redefined_symbol = true;
- dev_dbg(bridge, "%s already defined in symbol table\n",
- name);
- return NULL;
- }
- }
- /* Allocate string to copy symbol name */
- symbol.name = kzalloc(strlen((char *const)name) + 1, GFP_KERNEL);
- if (symbol.name == NULL)
- return NULL;
-
- if (symbol.name != NULL) {
- /* Just copy name (value will be filled in by dynamic loader) */
- strncpy(symbol.name, (char *const)name,
- strlen((char *const)name) + 1);
-
- /* Add symbol to symbol table */
- sym_ptr =
- (struct dbll_symbol *)gh_insert(lib->sym_tab, (void *)name,
- (void *)&symbol);
- if (IS_ERR(sym_ptr)) {
- kfree(symbol.name);
- sym_ptr = NULL;
- }
-
- }
- if (sym_ptr != NULL)
- ret = (struct dynload_symbol *)&sym_ptr->value;
- else
- ret = NULL;
-
- return ret;
-}
-
-/*
- * ======== dbll_purge_symbol_table ========
- */
-static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
- unsigned module_id)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
-
- lib = ldr_sym->lib;
- /* May not need to do anything */
-}
-
-/*
- * ======== allocate ========
- */
-static void *allocate(struct dynamic_loader_sym *this, unsigned memsize)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- void *buf;
-
- lib = ldr_sym->lib;
-
- buf = kzalloc(memsize, GFP_KERNEL);
-
- return buf;
-}
-
-/*
- * ======== deallocate ========
- */
-static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
-
- lib = ldr_sym->lib;
-
- kfree(mem_ptr);
-}
-
-/*
- * ======== dbll_err_report ========
- */
-static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
- va_list args)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- char temp_buf[MAXEXPR];
-
- lib = ldr_sym->lib;
- vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args);
- dev_dbg(bridge, "%s\n", temp_buf);
-}
-
-/* dynamic_loader_allocate */
-
-/*
- * ======== dbll_rmm_alloc ========
- */
-static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info, unsigned align)
-{
- struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
- struct dbll_library_obj *lib;
- int status = 0;
- u32 mem_sect_type;
- struct rmm_addr rmm_addr_obj;
- s32 ret = true;
- unsigned stype = DLOAD_SECTION_TYPE(info->type);
- char *token = NULL;
- char *sz_sec_last_token = NULL;
- char *sz_last_token = NULL;
- char *sz_sect_name = NULL;
- char *psz_cur;
- s32 token_len = 0;
- s32 seg_id = -1;
- s32 req = -1;
- s32 count = 0;
- u32 alloc_size = 0;
- u32 run_addr_flag = 0;
-
- lib = dbll_alloc_obj->lib;
-
- mem_sect_type =
- (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
- DLOAD_BSS) ? DBLL_BSS :
- DBLL_DATA;
-
- /* Attempt to extract the segment ID and requirement information from
- the name of the section */
- token_len = strlen((char *)(info->name)) + 1;
-
- sz_sect_name = kzalloc(token_len, GFP_KERNEL);
- sz_last_token = kzalloc(token_len, GFP_KERNEL);
- sz_sec_last_token = kzalloc(token_len, GFP_KERNEL);
-
- if (sz_sect_name == NULL || sz_sec_last_token == NULL ||
- sz_last_token == NULL) {
- status = -ENOMEM;
- goto func_cont;
- }
- strncpy(sz_sect_name, (char *)(info->name), token_len);
- psz_cur = sz_sect_name;
- while ((token = strsep(&psz_cur, ":")) && *token != '\0') {
- strncpy(sz_sec_last_token, sz_last_token,
- strlen(sz_last_token) + 1);
- strncpy(sz_last_token, token, strlen(token) + 1);
- token = strsep(&psz_cur, ":");
- count++; /* optimizes processing */
- }
- /* If token is 0 or 1, and sz_sec_last_token is DYN_DARAM or DYN_SARAM,
- or DYN_EXTERNAL, then mem granularity information is present
- within the section name - only process if there are at least three
- tokens within the section name (just a minor optimization) */
- if (count >= 3) {
- status = kstrtos32(sz_last_token, 10, &req);
- if (status)
- goto func_cont;
- }
-
- if ((req == 0) || (req == 1)) {
- if (strcmp(sz_sec_last_token, "DYN_DARAM") == 0) {
- seg_id = 0;
- } else {
- if (strcmp(sz_sec_last_token, "DYN_SARAM") == 0) {
- seg_id = 1;
- } else {
- if (strcmp(sz_sec_last_token,
- "DYN_EXTERNAL") == 0)
- seg_id = 2;
- }
- }
- }
-func_cont:
- kfree(sz_sect_name);
- sz_sect_name = NULL;
- kfree(sz_last_token);
- sz_last_token = NULL;
- kfree(sz_sec_last_token);
- sz_sec_last_token = NULL;
-
- if (mem_sect_type == DBLL_CODE)
- alloc_size = info->size + GEM_L1P_PREFETCH_SIZE;
- else
- alloc_size = info->size;
-
- if (info->load_addr != info->run_addr)
- run_addr_flag = 1;
- /* TODO - ideally, we can pass the alignment requirement also
- * from here */
- if (lib != NULL) {
- status =
- (lib->target_obj->attrs.alloc) (lib->target_obj->attrs.
- rmm_handle, mem_sect_type,
- alloc_size, align,
- (u32 *) &rmm_addr_obj,
- seg_id, req, false);
- }
- if (status) {
- ret = false;
- } else {
- /* RMM gives word address. Need to convert to byte address */
- info->load_addr = rmm_addr_obj.addr * DSPWORDSIZE;
- if (!run_addr_flag)
- info->run_addr = info->load_addr;
- info->context = (u32) rmm_addr_obj.segid;
- dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n",
- __func__, info->name, info->load_addr / DSPWORDSIZE,
- info->size / DSPWORDSIZE, info->run_addr,
- info->load_addr);
- }
- return ret;
-}
-
-/*
- * ======== rmm_dealloc ========
- */
-static void rmm_dealloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info)
-{
- struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
- struct dbll_library_obj *lib;
- u32 segid;
- int status = 0;
- unsigned stype = DLOAD_SECTION_TYPE(info->type);
- u32 mem_sect_type;
- u32 free_size = 0;
-
- mem_sect_type =
- (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
- DLOAD_BSS) ? DBLL_BSS :
- DBLL_DATA;
- lib = dbll_alloc_obj->lib;
- /* segid was set by alloc function */
- segid = (u32) info->context;
- if (mem_sect_type == DBLL_CODE)
- free_size = info->size + GEM_L1P_PREFETCH_SIZE;
- else
- free_size = info->size;
- if (lib != NULL) {
- status =
- (lib->target_obj->attrs.free) (lib->target_obj->attrs.
- sym_handle, segid,
- info->load_addr /
- DSPWORDSIZE, free_size,
- false);
- }
-}
-
-/* dynamic_loader_initialize */
-/*
- * ======== connect ========
- */
-static int connect(struct dynamic_loader_initialize *this)
-{
- return true;
-}
-
-/*
- * ======== read_mem ========
- * This function does not need to be implemented.
- */
-static int read_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned nbytes)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- int bytes_read = 0;
-
- lib = init_obj->lib;
- /* Need bridge_brd_read function */
- return bytes_read;
-}
-
-/*
- * ======== write_mem ========
- */
-static int write_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned bytes)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- struct dbll_tar_obj *target_obj;
- struct dbll_sect_info sect_info;
- u32 mem_sect_type;
- bool ret = true;
-
- lib = init_obj->lib;
- if (!lib)
- return false;
-
- target_obj = lib->target_obj;
-
- mem_sect_type =
- (DLOAD_SECTION_TYPE(info->type) ==
- DLOAD_TEXT) ? DBLL_CODE : DBLL_DATA;
- if (target_obj && target_obj->attrs.write) {
- ret =
- (*target_obj->attrs.write) (target_obj->attrs.input_params,
- addr, buf, bytes,
- mem_sect_type);
-
- if (target_obj->attrs.log_write) {
- sect_info.name = info->name;
- sect_info.sect_run_addr = info->run_addr;
- sect_info.sect_load_addr = info->load_addr;
- sect_info.size = info->size;
- sect_info.type = mem_sect_type;
- /* Pass the information about what we've written to
- * another module */
- (*target_obj->attrs.log_write) (target_obj->attrs.
- log_write_handle,
- &sect_info, addr,
- bytes);
- }
- }
- return ret;
-}
-
-/*
- * ======== fill_mem ========
- * Fill bytes of memory at a given address with a given value by
- * writing from a buffer containing the given value. Write in
- * sets of MAXEXPR (128) bytes to avoid large stack buffer issues.
- */
-static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
- struct ldr_section_info *info, unsigned bytes, unsigned val)
-{
- bool ret = true;
- char *pbuf;
- struct dbll_library_obj *lib;
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
-
- lib = init_obj->lib;
- pbuf = NULL;
- /* Pass the NULL pointer to write_mem to get the start address of Shared
- memory. This is a trick to just get the start address, there is no
- writing taking place with this Writemem
- */
- if ((lib->target_obj->attrs.write) != (dbll_write_fxn) no_op)
- write_mem(this, &pbuf, addr, info, 0);
- if (pbuf)
- memset(pbuf, val, bytes);
-
- return ret;
-}
-
-/*
- * ======== execute ========
- */
-static int execute(struct dynamic_loader_initialize *this, ldr_addr start)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- bool ret = true;
-
- lib = init_obj->lib;
- /* Save entry point */
- if (lib != NULL)
- lib->entry = (u32) start;
-
- return ret;
-}
-
-/*
- * ======== release ========
- */
-static void release(struct dynamic_loader_initialize *this)
-{
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/**
- * find_symbol_context - Basic symbol context structure
- * @address: Symbol Address
- * @offset_range: Offset range where the search for the DSP symbol
- * started.
- * @cur_best_offset: Best offset to start looking for the DSP symbol
- * @sym_addr: Address of the DSP symbol
- * @name: Symbol name
- *
- */
-struct find_symbol_context {
- /* input */
- u32 address;
- u32 offset_range;
- /* state */
- u32 cur_best_offset;
- /* output */
- u32 sym_addr;
- char name[120];
-};
-
-/**
- * find_symbol_callback() - Validates symbol address and copies the symbol name
- * to the user data.
- * @elem: dsp library context
- * @user_data: Find symbol context
- *
- */
-void find_symbol_callback(void *elem, void *user_data)
-{
- struct dbll_symbol *symbol = elem;
- struct find_symbol_context *context = user_data;
- u32 symbol_addr = symbol->value.value;
- u32 offset = context->address - symbol_addr;
-
- /*
- * Address given should be greater than symbol address,
- * symbol address should be within specified range
- * and the offset should be better than previous one
- */
- if (context->address >= symbol_addr && symbol_addr < (u32)-1 &&
- offset < context->cur_best_offset) {
- context->cur_best_offset = offset;
- context->sym_addr = symbol_addr;
- strlcpy(context->name, symbol->name, sizeof(context->name));
- }
-
- return;
-}
-
-/**
- * dbll_find_dsp_symbol() - This function retrieves the dsp symbol from the dsp binary.
- * @zl_lib: DSP binary obj library pointer
- * @address: Given address to find the dsp symbol
- * @offset_range: offset range to look for dsp symbol
- * @sym_addr_output: Symbol Output address
- * @name_output: String with the dsp symbol
- *
- * This function retrieves the dsp symbol from the dsp binary.
- */
-bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
- u32 offset_range, u32 *sym_addr_output,
- char *name_output)
-{
- bool status = false;
- struct find_symbol_context context;
-
- context.address = address;
- context.offset_range = offset_range;
- context.cur_best_offset = offset_range;
- context.sym_addr = 0;
- context.name[0] = '\0';
-
- gh_iterate(zl_lib->sym_tab, find_symbol_callback, &context);
-
- if (context.name[0]) {
- status = true;
- strcpy(name_output, context.name);
- *sym_addr_output = context.sym_addr;
- }
-
- return status;
-}
-#endif
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
deleted file mode 100644
index 616dc1f63070..000000000000
--- a/drivers/staging/tidspbridge/pmgr/dev.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * dev.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation of Bridge Bridge driver device operations.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-#include <linux/list.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/cod.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/proc.h>
-#include <dspbridge/dmm.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/mgr.h>
-#include <dspbridge/node.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/dspapi.h> /* DSP API version info. */
-
-#include <dspbridge/chnl.h>
-#include <dspbridge/io.h>
-#include <dspbridge/msg.h>
-#include <dspbridge/cmm.h>
-#include <dspbridge/dspdeh.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-
-#define MAKEVERSION(major, minor) (major * 10 + minor)
-#define BRD_API_VERSION MAKEVERSION(BRD_API_MAJOR_VERSION, \
- BRD_API_MINOR_VERSION)
-
-/* The Bridge device object: */
-struct dev_object {
- struct list_head link; /* Link to next dev_object. */
- u8 dev_type; /* Device Type */
- struct cfg_devnode *dev_node_obj; /* Platform specific dev id */
- /* Bridge Context Handle */
- struct bridge_dev_context *bridge_context;
- /* Function interface to Bridge driver. */
- struct bridge_drv_interface bridge_interface;
- struct brd_object *lock_owner; /* Client with exclusive access. */
- struct cod_manager *cod_mgr; /* Code manager handle. */
- struct chnl_mgr *chnl_mgr; /* Channel manager. */
- struct deh_mgr *deh_mgr; /* DEH manager. */
- struct msg_mgr *msg_mgr; /* Message manager. */
- struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */
- struct cmm_object *cmm_mgr; /* SM memory manager. */
- struct dmm_object *dmm_mgr; /* Dynamic memory manager. */
- u32 word_size; /* DSP word size: quick access. */
- struct drv_object *drv_obj; /* Driver Object */
- /* List of Processors attached to this device */
- struct list_head proc_list;
- struct node_mgr *node_mgr;
-};
-
-struct drv_ext {
- struct list_head link;
- char sz_string[MAXREGPATHLENGTH];
-};
-
-/* ----------------------------------- Function Prototypes */
-static int fxn_not_implemented(int arg, ...);
-static int init_cod_mgr(struct dev_object *dev_obj);
-static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
- struct bridge_drv_interface *intf_fxns);
-/*
- * ======== dev_brd_write_fxn ========
- * Purpose:
- * Exported function to be used as the COD write function. This function
- * is passed a handle to a DEV_hObject, then calls the
- * device's bridge_brd_write() function.
- */
-u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf,
- u32 ul_num_bytes, u32 mem_space)
-{
- struct dev_object *dev_obj = (struct dev_object *)arb;
- u32 ul_written = 0;
- int status;
-
- if (dev_obj) {
- /* Require of BrdWrite() */
- status = (*dev_obj->bridge_interface.brd_write) (
- dev_obj->bridge_context, host_buf,
- dsp_add, ul_num_bytes, mem_space);
- /* Special case of getting the address only */
- if (ul_num_bytes == 0)
- ul_num_bytes = 1;
- if (!status)
- ul_written = ul_num_bytes;
-
- }
- return ul_written;
-}
-
-/*
- * ======== dev_create_device ========
- * Purpose:
- * Called by the operating system to load the PM Bridge Driver for a
- * PM board (device).
- */
-int dev_create_device(struct dev_object **device_obj,
- const char *driver_file_name,
- struct cfg_devnode *dev_node_obj)
-{
- struct cfg_hostres *host_res;
- struct bridge_drv_interface *drv_fxns = NULL;
- struct dev_object *dev_obj = NULL;
- struct chnl_mgrattrs mgr_attrs;
- struct io_attrs io_mgr_attrs;
- u32 num_windows;
- struct drv_object *hdrv_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- int status = 0;
-
- status = drv_request_bridge_res_dsp((void *)&host_res);
-
- if (status) {
- dev_dbg(bridge, "%s: Failed to reserve bridge resources\n",
- __func__);
- goto leave;
- }
-
- /* Get the Bridge driver interface functions */
- bridge_drv_entry(&drv_fxns, driver_file_name);
-
- /* Retrieve the Object handle from the driver data */
- if (drv_datap && drv_datap->drv_object) {
- hdrv_obj = drv_datap->drv_object;
- } else {
- status = -EPERM;
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- /* Create the device object, and pass a handle to the Bridge driver for
- * storage. */
- if (!status) {
- dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL);
- if (dev_obj) {
- /* Fill out the rest of the Dev Object structure: */
- dev_obj->dev_node_obj = dev_node_obj;
- dev_obj->cod_mgr = NULL;
- dev_obj->chnl_mgr = NULL;
- dev_obj->deh_mgr = NULL;
- dev_obj->lock_owner = NULL;
- dev_obj->word_size = DSPWORDSIZE;
- dev_obj->drv_obj = hdrv_obj;
- dev_obj->dev_type = DSP_UNIT;
- /* Store this Bridge's interface functions, based on its
- * version. */
- store_interface_fxns(drv_fxns,
- &dev_obj->bridge_interface);
-
- /* Call fxn_dev_create() to get the Bridge's device
- * context handle. */
- status = (dev_obj->bridge_interface.dev_create)
- (&dev_obj->bridge_context, dev_obj,
- host_res);
- } else {
- status = -ENOMEM;
- }
- }
- /* Attempt to create the COD manager for this device: */
- if (!status)
- status = init_cod_mgr(dev_obj);
-
- /* Attempt to create the channel manager for this device: */
- if (!status) {
- mgr_attrs.max_channels = CHNL_MAXCHANNELS;
- io_mgr_attrs.birq = host_res->birq_registers;
- io_mgr_attrs.irq_shared =
- (host_res->birq_attrib & CFG_IRQSHARED);
- io_mgr_attrs.word_size = DSPWORDSIZE;
- mgr_attrs.word_size = DSPWORDSIZE;
- num_windows = host_res->num_mem_windows;
- if (num_windows) {
- /* Assume last memory window is for CHNL */
- io_mgr_attrs.shm_base = host_res->mem_base[1] +
- host_res->offset_for_monitor;
- io_mgr_attrs.sm_length =
- host_res->mem_length[1] -
- host_res->offset_for_monitor;
- } else {
- io_mgr_attrs.shm_base = 0;
- io_mgr_attrs.sm_length = 0;
- pr_err("%s: No memory reserved for shared structures\n",
- __func__);
- }
- status = chnl_create(&dev_obj->chnl_mgr, dev_obj, &mgr_attrs);
- if (status == -ENOSYS) {
- /* It's OK for a device not to have a channel
- * manager: */
- status = 0;
- }
- /* Create CMM mgr even if Msg Mgr not impl. */
- status = cmm_create(&dev_obj->cmm_mgr,
- (struct dev_object *)dev_obj, NULL);
- /* Only create IO manager if we have a channel manager */
- if (!status && dev_obj->chnl_mgr) {
- status = io_create(&dev_obj->iomgr, dev_obj,
- &io_mgr_attrs);
- }
- /* Only create DEH manager if we have an IO manager */
- if (!status) {
- /* Instantiate the DEH module */
- status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj);
- }
- /* Create DMM mgr . */
- status = dmm_create(&dev_obj->dmm_mgr,
- (struct dev_object *)dev_obj, NULL);
- }
- /* Add the new DEV_Object to the global list: */
- if (!status)
- status = drv_insert_dev_object(hdrv_obj, dev_obj);
-
- /* Create the Processor List */
- if (!status)
- INIT_LIST_HEAD(&dev_obj->proc_list);
-leave:
- /* If all went well, return a handle to the dev object;
- * else, cleanup and return NULL in the OUT parameter. */
- if (!status) {
- *device_obj = dev_obj;
- } else {
- if (dev_obj) {
- if (dev_obj->cod_mgr)
- cod_delete(dev_obj->cod_mgr);
- if (dev_obj->dmm_mgr)
- dmm_destroy(dev_obj->dmm_mgr);
- kfree(dev_obj);
- }
-
- *device_obj = NULL;
- }
-
- return status;
-}
-
-/*
- * ======== dev_create2 ========
- * Purpose:
- * After successful loading of the image from api_init_complete2
- * (PROC Auto_Start) or proc_load this fxn is called. This creates
- * the Node Manager and updates the DEV Object.
- */
-int dev_create2(struct dev_object *hdev_obj)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- /* There can be only one Node Manager per DEV object */
- status = node_create_mgr(&dev_obj->node_mgr, hdev_obj);
- if (status)
- dev_obj->node_mgr = NULL;
-
- return status;
-}
-
-/*
- * ======== dev_destroy2 ========
- * Purpose:
- * Destroys the Node manager for this device.
- */
-int dev_destroy2(struct dev_object *hdev_obj)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (dev_obj->node_mgr) {
- if (node_delete_mgr(dev_obj->node_mgr))
- status = -EPERM;
- else
- dev_obj->node_mgr = NULL;
-
- }
-
- return status;
-}
-
-/*
- * ======== dev_destroy_device ========
- * Purpose:
- * Destroys the channel manager for this device, if any, calls
- * bridge_dev_destroy(), and then attempts to unload the Bridge module.
- */
-int dev_destroy_device(struct dev_object *hdev_obj)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- if (dev_obj->cod_mgr) {
- cod_delete(dev_obj->cod_mgr);
- dev_obj->cod_mgr = NULL;
- }
-
- if (dev_obj->node_mgr) {
- node_delete_mgr(dev_obj->node_mgr);
- dev_obj->node_mgr = NULL;
- }
-
- /* Free the io, channel, and message managers for this board: */
- if (dev_obj->iomgr) {
- io_destroy(dev_obj->iomgr);
- dev_obj->iomgr = NULL;
- }
- if (dev_obj->chnl_mgr) {
- chnl_destroy(dev_obj->chnl_mgr);
- dev_obj->chnl_mgr = NULL;
- }
- if (dev_obj->msg_mgr) {
- msg_delete(dev_obj->msg_mgr);
- dev_obj->msg_mgr = NULL;
- }
-
- if (dev_obj->deh_mgr) {
- /* Uninitialize DEH module. */
- bridge_deh_destroy(dev_obj->deh_mgr);
- dev_obj->deh_mgr = NULL;
- }
- if (dev_obj->cmm_mgr) {
- cmm_destroy(dev_obj->cmm_mgr, true);
- dev_obj->cmm_mgr = NULL;
- }
-
- if (dev_obj->dmm_mgr) {
- dmm_destroy(dev_obj->dmm_mgr);
- dev_obj->dmm_mgr = NULL;
- }
-
- /* Call the driver's bridge_dev_destroy() function: */
- /* Require of DevDestroy */
- if (dev_obj->bridge_context) {
- status = (*dev_obj->bridge_interface.dev_destroy)
- (dev_obj->bridge_context);
- dev_obj->bridge_context = NULL;
- } else
- status = -EPERM;
- if (!status) {
- /* Remove this DEV_Object from the global list: */
- drv_remove_dev_object(dev_obj->drv_obj, dev_obj);
- /* Free The library * LDR_FreeModule
- * (dev_obj->module_obj); */
- /* Free this dev object: */
- kfree(dev_obj);
- dev_obj = NULL;
- }
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_chnl_mgr ========
- * Purpose:
- * Retrieve the handle to the channel manager handle created for this
- * device.
- */
-int dev_get_chnl_mgr(struct dev_object *hdev_obj,
- struct chnl_mgr **mgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *mgr = dev_obj->chnl_mgr;
- } else {
- *mgr = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_cmm_mgr ========
- * Purpose:
- * Retrieve the handle to the shared memory manager created for this
- * device.
- */
-int dev_get_cmm_mgr(struct dev_object *hdev_obj,
- struct cmm_object **mgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *mgr = dev_obj->cmm_mgr;
- } else {
- *mgr = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_dmm_mgr ========
- * Purpose:
- * Retrieve the handle to the dynamic memory manager created for this
- * device.
- */
-int dev_get_dmm_mgr(struct dev_object *hdev_obj,
- struct dmm_object **mgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *mgr = dev_obj->dmm_mgr;
- } else {
- *mgr = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_cod_mgr ========
- * Purpose:
- * Retrieve the COD manager create for this device.
- */
-int dev_get_cod_mgr(struct dev_object *hdev_obj,
- struct cod_manager **cod_mgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *cod_mgr = dev_obj->cod_mgr;
- } else {
- *cod_mgr = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ========= dev_get_deh_mgr ========
- */
-int dev_get_deh_mgr(struct dev_object *hdev_obj,
- struct deh_mgr **deh_manager)
-{
- int status = 0;
-
- if (hdev_obj) {
- *deh_manager = hdev_obj->deh_mgr;
- } else {
- *deh_manager = NULL;
- status = -EFAULT;
- }
- return status;
-}
-
-/*
- * ======== dev_get_dev_node ========
- * Purpose:
- * Retrieve the platform specific device ID for this device.
- */
-int dev_get_dev_node(struct dev_object *hdev_obj,
- struct cfg_devnode **dev_nde)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *dev_nde = dev_obj->dev_node_obj;
- } else {
- *dev_nde = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_first ========
- * Purpose:
- * Retrieve the first Device Object handle from an internal linked list
- * DEV_OBJECTs maintained by DEV.
- */
-struct dev_object *dev_get_first(void)
-{
- struct dev_object *dev_obj = NULL;
-
- dev_obj = (struct dev_object *)drv_get_first_dev_object();
-
- return dev_obj;
-}
-
-/*
- * ======== dev_get_intf_fxns ========
- * Purpose:
- * Retrieve the Bridge interface function structure for the loaded driver.
- * if_fxns != NULL.
- */
-int dev_get_intf_fxns(struct dev_object *hdev_obj,
- struct bridge_drv_interface **if_fxns)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *if_fxns = &dev_obj->bridge_interface;
- } else {
- *if_fxns = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ========= dev_get_io_mgr ========
- */
-int dev_get_io_mgr(struct dev_object *hdev_obj,
- struct io_mgr **io_man)
-{
- int status = 0;
-
- if (hdev_obj) {
- *io_man = hdev_obj->iomgr;
- } else {
- *io_man = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_next ========
- * Purpose:
- * Retrieve the next Device Object handle from an internal linked list
- * of DEV_OBJECTs maintained by DEV, after having previously called
- * dev_get_first() and zero or more dev_get_next
- */
-struct dev_object *dev_get_next(struct dev_object *hdev_obj)
-{
- struct dev_object *next_dev_object = NULL;
-
- if (hdev_obj) {
- next_dev_object = (struct dev_object *)
- drv_get_next_dev_object((u32) hdev_obj);
- }
-
- return next_dev_object;
-}
-
-/*
- * ========= dev_get_msg_mgr ========
- */
-void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man)
-{
- *msg_man = hdev_obj->msg_mgr;
-}
-
-/*
- * ======== dev_get_node_manager ========
- * Purpose:
- * Retrieve the Node Manager Handle
- */
-int dev_get_node_manager(struct dev_object *hdev_obj,
- struct node_mgr **node_man)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *node_man = dev_obj->node_mgr;
- } else {
- *node_man = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_symbol ========
- */
-int dev_get_symbol(struct dev_object *hdev_obj,
- const char *str_sym, u32 *pul_value)
-{
- int status = 0;
- struct cod_manager *cod_mgr;
-
- if (hdev_obj) {
- status = dev_get_cod_mgr(hdev_obj, &cod_mgr);
- if (cod_mgr)
- status = cod_get_sym_value(cod_mgr, (char *)str_sym,
- pul_value);
- else
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_get_bridge_context ========
- * Purpose:
- * Retrieve the Bridge Context handle, as returned by the
- * bridge_dev_create fxn.
- */
-int dev_get_bridge_context(struct dev_object *hdev_obj,
- struct bridge_dev_context **phbridge_context)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj) {
- *phbridge_context = dev_obj->bridge_context;
- } else {
- *phbridge_context = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== dev_notify_clients ========
- * Purpose:
- * Notify all clients of this device of a change in device status.
- */
-int dev_notify_clients(struct dev_object *dev_obj, u32 ret)
-{
- struct list_head *curr;
-
- /*
- * FIXME: this code needs struct proc_object to have a list_head
- * at the beginning. If not, this can go horribly wrong.
- */
- list_for_each(curr, &dev_obj->proc_list)
- proc_notify_clients((void *)curr, ret);
-
- return 0;
-}
-
-/*
- * ======== dev_remove_device ========
- */
-int dev_remove_device(struct cfg_devnode *dev_node_obj)
-{
- struct dev_object *hdev_obj; /* handle to device object */
- int status = 0;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (!drv_datap)
- status = -ENODATA;
-
- if (!dev_node_obj)
- status = -EFAULT;
-
- /* Retrieve the device object handle originally stored with
- * the dev_node: */
- if (!status) {
- /* check the device string and then store dev object */
- if (!strcmp((char *)((struct drv_ext *)dev_node_obj)->sz_string,
- "TIOMAP1510")) {
- hdev_obj = drv_datap->dev_object;
- /* Destroy the device object. */
- status = dev_destroy_device(hdev_obj);
- } else {
- status = -EPERM;
- }
- }
-
- if (status)
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
-
- return status;
-}
-
-/*
- * ======== dev_set_chnl_mgr ========
- * Purpose:
- * Set the channel manager for this device.
- */
-int dev_set_chnl_mgr(struct dev_object *hdev_obj,
- struct chnl_mgr *hmgr)
-{
- int status = 0;
- struct dev_object *dev_obj = hdev_obj;
-
- if (hdev_obj)
- dev_obj->chnl_mgr = hmgr;
- else
- status = -EFAULT;
-
- return status;
-}
-
-/*
- * ======== dev_set_msg_mgr ========
- * Purpose:
- * Set the message manager for this device.
- */
-void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr)
-{
- hdev_obj->msg_mgr = hmgr;
-}
-
-/*
- * ======== dev_start_device ========
- * Purpose:
- * Initializes the new device with the BRIDGE environment.
- */
-int dev_start_device(struct cfg_devnode *dev_node_obj)
-{
- struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */
- /* Bridge driver filename */
- char *bridge_file_name = "UMA";
- int status;
- struct mgr_object *hmgr_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /* Given all resources, create a device object. */
- status = dev_create_device(&hdev_obj, bridge_file_name,
- dev_node_obj);
- if (!status) {
- /* Store away the hdev_obj with the DEVNODE */
- if (!drv_datap || !dev_node_obj) {
- status = -EFAULT;
- pr_err("%s: Failed, status 0x%x\n", __func__, status);
- } else if (!(strcmp((char *)dev_node_obj, "TIOMAP1510"))) {
- drv_datap->dev_object = (void *) hdev_obj;
- }
- if (!status) {
- /* Create the Manager Object */
- status = mgr_create(&hmgr_obj, dev_node_obj);
- if (status && !(strcmp((char *)dev_node_obj,
- "TIOMAP1510"))) {
- /* Ensure the device extension is NULL */
- drv_datap->dev_object = NULL;
- }
- }
- if (status) {
- /* Clean up */
- dev_destroy_device(hdev_obj);
- hdev_obj = NULL;
- }
- }
-
- return status;
-}
-
-/*
- * ======== fxn_not_implemented ========
- * Purpose:
- * Takes the place of a Bridge Null Function.
- * Parameters:
- * Multiple, optional.
- * Returns:
- * -ENOSYS: Always.
- */
-static int fxn_not_implemented(int arg, ...)
-{
- return -ENOSYS;
-}
-
-/*
- * ======== init_cod_mgr ========
- * Purpose:
- * Create a COD manager for this device.
- * Parameters:
- * dev_obj: Pointer to device object created with
- * dev_create_device()
- * Returns:
- * 0: Success.
- * -EFAULT: Invalid hdev_obj.
- * Requires:
- * Should only be called once by dev_create_device() for a given DevObject.
- * Ensures:
- */
-static int init_cod_mgr(struct dev_object *dev_obj)
-{
- int status = 0;
- char *sz_dummy_file = "dummy";
-
- status = cod_create(&dev_obj->cod_mgr, sz_dummy_file);
-
- return status;
-}
-
-/*
- * ======== dev_insert_proc_object ========
- * Purpose:
- * Insert a ProcObject into the list maintained by DEV.
- * Parameters:
- * p_proc_object: Ptr to ProcObject to insert.
- * dev_obj: Ptr to Dev Object where the list is.
- * already_attached: Ptr to return the bool
- * Returns:
- * 0: If successful.
- * Requires:
- * List Exists
- * hdev_obj is Valid handle
- * DEV Initialized
- * already_attached != NULL
- * proc_obj != 0
- * Ensures:
- * 0 and List is not Empty.
- */
-int dev_insert_proc_object(struct dev_object *hdev_obj,
- u32 proc_obj, bool *already_attached)
-{
- struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
-
- if (!list_empty(&dev_obj->proc_list))
- *already_attached = true;
-
- /* Add DevObject to tail. */
- /*
- * FIXME: this code needs struct proc_object to have a list_head
- * at the beginning. If not, this can go horribly wrong.
- */
- list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list);
-
- return 0;
-}
-
-/*
- * ======== dev_remove_proc_object ========
- * Purpose:
- * Search for and remove a Proc object from the given list maintained
- * by the DEV
- * Parameters:
- * p_proc_object: Ptr to ProcObject to insert.
- * dev_obj Ptr to Dev Object where the list is.
- * Returns:
- * 0: If successful.
- * Requires:
- * List exists and is not empty
- * proc_obj != 0
- * hdev_obj is a valid Dev handle.
- * Ensures:
- * Details:
- * List will be deleted when the DEV is destroyed.
- */
-int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj)
-{
- int status = -EPERM;
- struct list_head *cur_elem;
- struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
-
- /* Search list for dev_obj: */
- list_for_each(cur_elem, &dev_obj->proc_list) {
- if ((u32) cur_elem == proc_obj) {
- list_del(cur_elem);
- status = 0;
- break;
- }
- }
-
- return status;
-}
-
-int dev_get_dev_type(struct dev_object *dev_obj, u8 *dev_type)
-{
- *dev_type = dev_obj->dev_type;
- return 0;
-}
-
-/*
- * ======== store_interface_fxns ========
- * Purpose:
- * Copy the Bridge's interface functions into the device object,
- * ensuring that fxn_not_implemented() is set for:
- *
- * 1. All Bridge function pointers which are NULL; and
- * 2. All function slots in the struct dev_object structure which have no
- * corresponding slots in the the Bridge's interface, because the Bridge
- * is of an *older* version.
- * Parameters:
- * intf_fxns: Interface fxn Structure of the Bridge's Dev Object.
- * drv_fxns: Interface Fxns offered by the Bridge during DEV_Create().
- * Returns:
- * Requires:
- * Input pointers are valid.
- * Bridge driver is *not* written for a newer DSP API.
- * Ensures:
- * All function pointers in the dev object's fxn interface are not NULL.
- */
-static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
- struct bridge_drv_interface *intf_fxns)
-{
- u32 bridge_version;
-
- /* Local helper macro: */
-#define STORE_FXN(cast, pfn) \
- (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
- (cast)fxn_not_implemented))
-
- bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
- drv_fxns->brd_api_minor_version);
- intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version;
- intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version;
- /* Install functions up to DSP API version .80 (first alpha): */
- if (bridge_version > 0) {
- STORE_FXN(fxn_dev_create, dev_create);
- STORE_FXN(fxn_dev_destroy, dev_destroy);
- STORE_FXN(fxn_dev_ctrl, dev_cntrl);
- STORE_FXN(fxn_brd_monitor, brd_monitor);
- STORE_FXN(fxn_brd_start, brd_start);
- STORE_FXN(fxn_brd_stop, brd_stop);
- STORE_FXN(fxn_brd_status, brd_status);
- STORE_FXN(fxn_brd_read, brd_read);
- STORE_FXN(fxn_brd_write, brd_write);
- STORE_FXN(fxn_brd_setstate, brd_set_state);
- STORE_FXN(fxn_brd_memcopy, brd_mem_copy);
- STORE_FXN(fxn_brd_memwrite, brd_mem_write);
- STORE_FXN(fxn_brd_memmap, brd_mem_map);
- STORE_FXN(fxn_brd_memunmap, brd_mem_un_map);
- STORE_FXN(fxn_chnl_create, chnl_create);
- STORE_FXN(fxn_chnl_destroy, chnl_destroy);
- STORE_FXN(fxn_chnl_open, chnl_open);
- STORE_FXN(fxn_chnl_close, chnl_close);
- STORE_FXN(fxn_chnl_addioreq, chnl_add_io_req);
- STORE_FXN(fxn_chnl_getioc, chnl_get_ioc);
- STORE_FXN(fxn_chnl_cancelio, chnl_cancel_io);
- STORE_FXN(fxn_chnl_flushio, chnl_flush_io);
- STORE_FXN(fxn_chnl_getinfo, chnl_get_info);
- STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info);
- STORE_FXN(fxn_chnl_idle, chnl_idle);
- STORE_FXN(fxn_chnl_registernotify, chnl_register_notify);
- STORE_FXN(fxn_io_create, io_create);
- STORE_FXN(fxn_io_destroy, io_destroy);
- STORE_FXN(fxn_io_onloaded, io_on_loaded);
- STORE_FXN(fxn_io_getprocload, io_get_proc_load);
- STORE_FXN(fxn_msg_create, msg_create);
- STORE_FXN(fxn_msg_createqueue, msg_create_queue);
- STORE_FXN(fxn_msg_delete, msg_delete);
- STORE_FXN(fxn_msg_deletequeue, msg_delete_queue);
- STORE_FXN(fxn_msg_get, msg_get);
- STORE_FXN(fxn_msg_put, msg_put);
- STORE_FXN(fxn_msg_registernotify, msg_register_notify);
- STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id);
- }
- /* Add code for any additional functions in newerBridge versions here */
-#undef STORE_FXN
-}
diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c
deleted file mode 100644
index fcf564aa566d..000000000000
--- a/drivers/staging/tidspbridge/pmgr/dmm.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * dmm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address
- * space that can be directly mapped to any MPU buffer or memory region
- *
- * Notes:
- * Region: Generic memory entitiy having a start address and a size
- * Chunk: Reserved region
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/proc.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dmm.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define DMM_ADDR_VIRTUAL(a) \
- (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\
- dyn_mem_map_beg)
-#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K)
-
-/* DMM Mgr */
-struct dmm_object {
- /* Dmm Lock is used to serialize access mem manager for
- * multi-threads. */
- spinlock_t dmm_lock; /* Lock to access dmm mgr */
-};
-
-struct map_page {
- u32 region_size:15;
- u32 mapped_size:15;
- u32 reserved:1;
- u32 mapped:1;
-};
-
-/* Create the free list */
-static struct map_page *virtual_mapping_table;
-static u32 free_region; /* The index of free region */
-static u32 free_size;
-static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */
-static u32 table_size; /* The size of virt and phys pages tables */
-
-/* ----------------------------------- Function Prototypes */
-static struct map_page *get_region(u32 addr);
-static struct map_page *get_free_region(u32 len);
-static struct map_page *get_mapped_region(u32 addrs);
-
-/* ======== dmm_create_tables ========
- * Purpose:
- * Create table to hold the information of physical address
- * the buffer pages that is passed by the user, and the table
- * to hold the information of the virtual memory that is reserved
- * for DSP.
- */
-int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- int status = 0;
-
- status = dmm_delete_tables(dmm_obj);
- if (!status) {
- dyn_mem_map_beg = addr;
- table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K;
- /* Create the free list */
- virtual_mapping_table = __vmalloc(table_size *
- sizeof(struct map_page), GFP_KERNEL |
- __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
- if (virtual_mapping_table == NULL)
- status = -ENOMEM;
- else {
- /* On successful allocation,
- * all entries are zero ('free') */
- free_region = 0;
- free_size = table_size * PG_SIZE4K;
- virtual_mapping_table[0].region_size = table_size;
- }
- }
-
- if (status)
- pr_err("%s: failure, status 0x%x\n", __func__, status);
-
- return status;
-}
-
-/*
- * ======== dmm_create ========
- * Purpose:
- * Create a dynamic memory manager object.
- */
-int dmm_create(struct dmm_object **dmm_manager,
- struct dev_object *hdev_obj,
- const struct dmm_mgrattrs *mgr_attrts)
-{
- struct dmm_object *dmm_obj = NULL;
- int status = 0;
-
- *dmm_manager = NULL;
- /* create, zero, and tag a cmm mgr object */
- dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL);
- if (dmm_obj != NULL) {
- spin_lock_init(&dmm_obj->dmm_lock);
- *dmm_manager = dmm_obj;
- } else {
- status = -ENOMEM;
- }
-
- return status;
-}
-
-/*
- * ======== dmm_destroy ========
- * Purpose:
- * Release the communication memory manager resources.
- */
-int dmm_destroy(struct dmm_object *dmm_mgr)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- int status = 0;
-
- if (dmm_mgr) {
- status = dmm_delete_tables(dmm_obj);
- if (!status)
- kfree(dmm_obj);
- } else
- status = -EFAULT;
-
- return status;
-}
-
-/*
- * ======== dmm_delete_tables ========
- * Purpose:
- * Delete DMM Tables.
- */
-int dmm_delete_tables(struct dmm_object *dmm_mgr)
-{
- int status = 0;
-
- /* Delete all DMM tables */
- if (dmm_mgr)
- vfree(virtual_mapping_table);
- else
- status = -EFAULT;
- return status;
-}
-
-/*
- * ======== dmm_get_handle ========
- * Purpose:
- * Return the dynamic memory manager object for this device.
- * This is typically called from the client process.
- */
-int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager)
-{
- int status = 0;
- struct dev_object *hdev_obj;
-
- if (hprocessor != NULL)
- status = proc_get_dev_object(hprocessor, &hdev_obj);
- else
- hdev_obj = dev_get_first(); /* default */
-
- if (!status)
- status = dev_get_dmm_mgr(hdev_obj, dmm_manager);
-
- return status;
-}
-
-/*
- * ======== dmm_map_memory ========
- * Purpose:
- * Add a mapping block to the reserved chunk. DMM assumes that this block
- * will be mapped in the DSP/IVA's address space. DMM returns an error if a
- * mapping overlaps another one. This function stores the info that will be
- * required later while unmapping the block.
- */
-int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- int status = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
- /* Find the Reserved memory chunk containing the DSP block to
- * be mapped */
- chunk = (struct map_page *)get_region(addr);
- if (chunk != NULL) {
- /* Mark the region 'mapped', leave the 'reserved' info as-is */
- chunk->mapped = true;
- chunk->mapped_size = (size / PG_SIZE4K);
- } else
- status = -ENOENT;
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, chunk %p",
- __func__, dmm_mgr, addr, size, status, chunk);
-
- return status;
-}
-
-/*
- * ======== dmm_reserve_memory ========
- * Purpose:
- * Reserve a chunk of virtually contiguous DSP/IVA address space.
- */
-int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size,
- u32 *prsv_addr)
-{
- int status = 0;
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *node;
- u32 rsv_addr = 0;
- u32 rsv_size = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
-
- /* Try to get a DSP chunk from the free list */
- node = get_free_region(size);
- if (node != NULL) {
- /* DSP chunk of given size is available. */
- rsv_addr = DMM_ADDR_VIRTUAL(node);
- /* Calculate the number entries to use */
- rsv_size = size / PG_SIZE4K;
- if (rsv_size < node->region_size) {
- /* Mark remainder of free region */
- node[rsv_size].mapped = false;
- node[rsv_size].reserved = false;
- node[rsv_size].region_size =
- node->region_size - rsv_size;
- node[rsv_size].mapped_size = 0;
- }
- /* get_region will return first fit chunk. But we only use what
- is requested. */
- node->mapped = false;
- node->reserved = true;
- node->region_size = rsv_size;
- node->mapped_size = 0;
- /* Return the chunk's starting address */
- *prsv_addr = rsv_addr;
- } else
- /*dSP chunk of given size is not available */
- status = -ENOMEM;
-
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, rsv_addr %x, rsv_size %x\n",
- __func__, dmm_mgr, size,
- prsv_addr, status, rsv_addr, rsv_size);
-
- return status;
-}
-
-/*
- * ======== dmm_un_map_memory ========
- * Purpose:
- * Remove the mapped block from the reserved chunk.
- */
-int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- int status = 0;
-
- spin_lock(&dmm_obj->dmm_lock);
- chunk = get_mapped_region(addr);
- if (chunk == NULL)
- status = -ENOENT;
-
- if (!status) {
- /* Unmap the region */
- *psize = chunk->mapped_size * PG_SIZE4K;
- chunk->mapped = false;
- chunk->mapped_size = 0;
- }
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, chunk %p\n",
- __func__, dmm_mgr, addr, psize, status, chunk);
-
- return status;
-}
-
-/*
- * ======== dmm_un_reserve_memory ========
- * Purpose:
- * Free a chunk of reserved DSP/IVA address space.
- */
-int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr)
-{
- struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
- struct map_page *chunk;
- u32 i;
- int status = 0;
- u32 chunk_size;
-
- spin_lock(&dmm_obj->dmm_lock);
-
- /* Find the chunk containing the reserved address */
- chunk = get_mapped_region(rsv_addr);
- if (chunk == NULL)
- status = -ENOENT;
-
- if (!status) {
- /* Free all the mapped pages for this reserved region */
- i = 0;
- while (i < chunk->region_size) {
- if (chunk[i].mapped) {
- /* Remove mapping from the page tables. */
- chunk_size = chunk[i].mapped_size;
- /* Clear the mapping flags */
- chunk[i].mapped = false;
- chunk[i].mapped_size = 0;
- i += chunk_size;
- } else
- i++;
- }
- /* Clear the flags (mark the region 'free') */
- chunk->reserved = false;
- /* NOTE: We do NOT coalesce free regions here.
- * Free regions are coalesced in get_region(), as it traverses
- *the whole mapping table
- */
- }
- spin_unlock(&dmm_obj->dmm_lock);
-
- dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p",
- __func__, dmm_mgr, rsv_addr, status, chunk);
-
- return status;
-}
-
-/*
- * ======== get_region ========
- * Purpose:
- * Returns a region containing the specified memory region
- */
-static struct map_page *get_region(u32 addr)
-{
- struct map_page *curr_region = NULL;
- u32 i = 0;
-
- if (virtual_mapping_table != NULL) {
- /* find page mapped by this address */
- i = DMM_ADDR_TO_INDEX(addr);
- if (i < table_size)
- curr_region = virtual_mapping_table + i;
- }
-
- dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n",
- __func__, curr_region, free_region, free_size);
- return curr_region;
-}
-
-/*
- * ======== get_free_region ========
- * Purpose:
- * Returns the requested free region
- */
-static struct map_page *get_free_region(u32 len)
-{
- struct map_page *curr_region = NULL;
- u32 i = 0;
- u32 region_size = 0;
- u32 next_i = 0;
-
- if (virtual_mapping_table == NULL)
- return curr_region;
- if (len > free_size) {
- /* Find the largest free region
- * (coalesce during the traversal) */
- while (i < table_size) {
- region_size = virtual_mapping_table[i].region_size;
- next_i = i + region_size;
- if (virtual_mapping_table[i].reserved == false) {
- /* Coalesce, if possible */
- if (next_i < table_size &&
- virtual_mapping_table[next_i].reserved
- == false) {
- virtual_mapping_table[i].region_size +=
- virtual_mapping_table
- [next_i].region_size;
- continue;
- }
- region_size *= PG_SIZE4K;
- if (region_size > free_size) {
- free_region = i;
- free_size = region_size;
- }
- }
- i = next_i;
- }
- }
- if (len <= free_size) {
- curr_region = virtual_mapping_table + free_region;
- free_region += (len / PG_SIZE4K);
- free_size -= len;
- }
- return curr_region;
-}
-
-/*
- * ======== get_mapped_region ========
- * Purpose:
- * Returns the requestedmapped region
- */
-static struct map_page *get_mapped_region(u32 addrs)
-{
- u32 i = 0;
- struct map_page *curr_region = NULL;
-
- if (virtual_mapping_table == NULL)
- return curr_region;
-
- i = DMM_ADDR_TO_INDEX(addrs);
- if (i < table_size && (virtual_mapping_table[i].mapped ||
- virtual_mapping_table[i].reserved))
- curr_region = virtual_mapping_table + i;
- return curr_region;
-}
-
-#ifdef DSP_DMM_DEBUG
-u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr)
-{
- struct map_page *curr_node = NULL;
- u32 i;
- u32 freemem = 0;
- u32 bigsize = 0;
-
- spin_lock(&dmm_mgr->dmm_lock);
-
- if (virtual_mapping_table != NULL) {
- for (i = 0; i < table_size; i +=
- virtual_mapping_table[i].region_size) {
- curr_node = virtual_mapping_table + i;
- if (curr_node->reserved) {
- /*printk("RESERVED size = 0x%x, "
- "Map size = 0x%x\n",
- (curr_node->region_size * PG_SIZE4K),
- (curr_node->mapped == false) ? 0 :
- (curr_node->mapped_size * PG_SIZE4K));
- */
- } else {
-/* printk("UNRESERVED size = 0x%x\n",
- (curr_node->region_size * PG_SIZE4K));
- */
- freemem += (curr_node->region_size * PG_SIZE4K);
- if (curr_node->region_size > bigsize)
- bigsize = curr_node->region_size;
- }
- }
- }
- spin_unlock(&dmm_mgr->dmm_lock);
- dev_info(bridge, "Total DSP VA FREE memory = %d Mbytes\n",
- freemem / (1024 * 1024));
- dev_info(bridge, "Total DSP VA USED memory= %d Mbytes\n",
- (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024));
- dev_info(bridge, "DSP VA - Biggest FREE block = %d Mbytes\n",
- (bigsize * PG_SIZE4K / (1024 * 1024)));
-
- return 0;
-}
-#endif
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
deleted file mode 100644
index b7d5c8cbb2a1..000000000000
--- a/drivers/staging/tidspbridge/pmgr/dspapi.c
+++ /dev/null
@@ -1,1843 +0,0 @@
-/*
- * dspapi.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Common DSP API functions, also includes the wrapper
- * functions called directly by the DeviceIOControl interface.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/ntfy.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/chnl.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/drv.h>
-
-#include <dspbridge/proc.h>
-#include <dspbridge/strm.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/disp.h>
-#include <dspbridge/mgr.h>
-#include <dspbridge/node.h>
-#include <dspbridge/rmm.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/msg.h>
-#include <dspbridge/cmm.h>
-#include <dspbridge/io.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dspapi.h>
-#include <dspbridge/dbdcd.h>
-
-#include <dspbridge/resourcecleanup.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define MAX_TRACEBUFLEN 255
-#define MAX_LOADARGS 16
-#define MAX_NODES 64
-#define MAX_STREAMS 16
-#define MAX_BUFS 64
-
-/* Used to get dspbridge ioctl table */
-#define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)
-
-/* Device IOCtl function pointer */
-struct api_cmd {
- u32(*fxn) (union trapped_args *args, void *pr_ctxt);
- u32 index;
-};
-
-/* ----------------------------------- Globals */
-static u32 api_c_refs;
-
-/*
- * Function tables.
- * The order of these functions MUST be the same as the order of the command
- * numbers defined in dspapi-ioctl.h This is how an IOCTL number in user mode
- * turns into a function call in kernel mode.
- */
-
-/* MGR wrapper functions */
-static struct api_cmd mgr_cmd[] = {
- {mgrwrap_enum_node_info}, /* MGR_ENUMNODE_INFO */
- {mgrwrap_enum_proc_info}, /* MGR_ENUMPROC_INFO */
- {mgrwrap_register_object}, /* MGR_REGISTEROBJECT */
- {mgrwrap_unregister_object}, /* MGR_UNREGISTEROBJECT */
- {mgrwrap_wait_for_bridge_events}, /* MGR_WAIT */
- {mgrwrap_get_process_resources_info}, /* MGR_GET_PROC_RES */
-};
-
-/* PROC wrapper functions */
-static struct api_cmd proc_cmd[] = {
- {procwrap_attach}, /* PROC_ATTACH */
- {procwrap_ctrl}, /* PROC_CTRL */
- {procwrap_detach}, /* PROC_DETACH */
- {procwrap_enum_node_info}, /* PROC_ENUMNODE */
- {procwrap_enum_resources}, /* PROC_ENUMRESOURCES */
- {procwrap_get_state}, /* PROC_GET_STATE */
- {procwrap_get_trace}, /* PROC_GET_TRACE */
- {procwrap_load}, /* PROC_LOAD */
- {procwrap_register_notify}, /* PROC_REGISTERNOTIFY */
- {procwrap_start}, /* PROC_START */
- {procwrap_reserve_memory}, /* PROC_RSVMEM */
- {procwrap_un_reserve_memory}, /* PROC_UNRSVMEM */
- {procwrap_map}, /* PROC_MAPMEM */
- {procwrap_un_map}, /* PROC_UNMAPMEM */
- {procwrap_flush_memory}, /* PROC_FLUSHMEMORY */
- {procwrap_stop}, /* PROC_STOP */
- {procwrap_invalidate_memory}, /* PROC_INVALIDATEMEMORY */
- {procwrap_begin_dma}, /* PROC_BEGINDMA */
- {procwrap_end_dma}, /* PROC_ENDDMA */
-};
-
-/* NODE wrapper functions */
-static struct api_cmd node_cmd[] = {
- {nodewrap_allocate}, /* NODE_ALLOCATE */
- {nodewrap_alloc_msg_buf}, /* NODE_ALLOCMSGBUF */
- {nodewrap_change_priority}, /* NODE_CHANGEPRIORITY */
- {nodewrap_connect}, /* NODE_CONNECT */
- {nodewrap_create}, /* NODE_CREATE */
- {nodewrap_delete}, /* NODE_DELETE */
- {nodewrap_free_msg_buf}, /* NODE_FREEMSGBUF */
- {nodewrap_get_attr}, /* NODE_GETATTR */
- {nodewrap_get_message}, /* NODE_GETMESSAGE */
- {nodewrap_pause}, /* NODE_PAUSE */
- {nodewrap_put_message}, /* NODE_PUTMESSAGE */
- {nodewrap_register_notify}, /* NODE_REGISTERNOTIFY */
- {nodewrap_run}, /* NODE_RUN */
- {nodewrap_terminate}, /* NODE_TERMINATE */
- {nodewrap_get_uuid_props}, /* NODE_GETUUIDPROPS */
-};
-
-/* STRM wrapper functions */
-static struct api_cmd strm_cmd[] = {
- {strmwrap_allocate_buffer}, /* STRM_ALLOCATEBUFFER */
- {strmwrap_close}, /* STRM_CLOSE */
- {strmwrap_free_buffer}, /* STRM_FREEBUFFER */
- {strmwrap_get_event_handle}, /* STRM_GETEVENTHANDLE */
- {strmwrap_get_info}, /* STRM_GETINFO */
- {strmwrap_idle}, /* STRM_IDLE */
- {strmwrap_issue}, /* STRM_ISSUE */
- {strmwrap_open}, /* STRM_OPEN */
- {strmwrap_reclaim}, /* STRM_RECLAIM */
- {strmwrap_register_notify}, /* STRM_REGISTERNOTIFY */
- {strmwrap_select}, /* STRM_SELECT */
-};
-
-/* CMM wrapper functions */
-static struct api_cmd cmm_cmd[] = {
- {cmmwrap_calloc_buf}, /* CMM_ALLOCBUF */
- {cmmwrap_free_buf}, /* CMM_FREEBUF */
- {cmmwrap_get_handle}, /* CMM_GETHANDLE */
- {cmmwrap_get_info}, /* CMM_GETINFO */
-};
-
-/* Array used to store ioctl table sizes. It can hold up to 8 entries */
-static u8 size_cmd[] = {
- ARRAY_SIZE(mgr_cmd),
- ARRAY_SIZE(proc_cmd),
- ARRAY_SIZE(node_cmd),
- ARRAY_SIZE(strm_cmd),
- ARRAY_SIZE(cmm_cmd),
-};
-
-static inline void _cp_fm_usr(void *to, const void __user *from,
- int *err, unsigned long bytes)
-{
- if (*err)
- return;
-
- if (unlikely(!from)) {
- *err = -EFAULT;
- return;
- }
-
- if (unlikely(copy_from_user(to, from, bytes)))
- *err = -EFAULT;
-}
-
-#define CP_FM_USR(to, from, err, n) \
- _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))
-
-static inline void _cp_to_usr(void __user *to, const void *from,
- int *err, unsigned long bytes)
-{
- if (*err)
- return;
-
- if (unlikely(!to)) {
- *err = -EFAULT;
- return;
- }
-
- if (unlikely(copy_to_user(to, from, bytes)))
- *err = -EFAULT;
-}
-
-#define CP_TO_USR(to, from, err, n) \
- _cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))
-
-/*
- * ======== api_call_dev_ioctl ========
- * Purpose:
- * Call the (wrapper) function for the corresponding API IOCTL.
- */
-inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args,
- u32 *result, void *pr_ctxt)
-{
- u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL;
- int i;
-
- if (_IOC_TYPE(cmd) != DB) {
- pr_err("%s: Incompatible dspbridge ioctl number\n", __func__);
- goto err;
- }
-
- if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) {
- pr_err("%s: undefined ioctl module\n", __func__);
- goto err;
- }
-
- /* Check the size of the required cmd table */
- i = DB_GET_IOC(cmd);
- if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) {
- pr_err("%s: requested ioctl %d out of bounds for table %d\n",
- __func__, i, DB_GET_IOC_TABLE(cmd));
- goto err;
- }
-
- switch (DB_GET_MODULE(cmd)) {
- case DB_MGR:
- ioctl_cmd = mgr_cmd[i].fxn;
- break;
- case DB_PROC:
- ioctl_cmd = proc_cmd[i].fxn;
- break;
- case DB_NODE:
- ioctl_cmd = node_cmd[i].fxn;
- break;
- case DB_STRM:
- ioctl_cmd = strm_cmd[i].fxn;
- break;
- case DB_CMM:
- ioctl_cmd = cmm_cmd[i].fxn;
- break;
- }
-
- if (!ioctl_cmd) {
- pr_err("%s: requested ioctl not defined\n", __func__);
- goto err;
- } else {
- *result = (*ioctl_cmd) (args, pr_ctxt);
- }
-
- return 0;
-
-err:
- return -EINVAL;
-}
-
-/*
- * ======== api_exit ========
- */
-void api_exit(void)
-{
- api_c_refs--;
-
- if (api_c_refs == 0)
- mgr_exit();
-}
-
-/*
- * ======== api_init ========
- * Purpose:
- * Module initialization used by Bridge API.
- */
-bool api_init(void)
-{
- bool ret = true;
-
- if (api_c_refs == 0)
- ret = mgr_init();
-
- if (ret)
- api_c_refs++;
-
- return ret;
-}
-
-/*
- * ======== api_init_complete2 ========
- * Purpose:
- * Perform any required bridge initialization which cannot
- * be performed in api_init() or dev_start_device() due
- * to the fact that some services are not yet
- * completely initialized.
- * Parameters:
- * Returns:
- * 0: Allow this device to load
- * -EPERM: Failure.
- * Requires:
- * Bridge API initialized.
- * Ensures:
- */
-int api_init_complete2(void)
-{
- int status = 0;
- struct cfg_devnode *dev_node;
- struct dev_object *hdev_obj;
- struct drv_data *drv_datap;
- u8 dev_type;
-
- /* Walk the list of DevObjects, get each devnode, and attempting to
- * autostart the board. Note that this requires COF loading, which
- * requires KFILE. */
- for (hdev_obj = dev_get_first(); hdev_obj != NULL;
- hdev_obj = dev_get_next(hdev_obj)) {
- if (dev_get_dev_node(hdev_obj, &dev_node))
- continue;
-
- if (dev_get_dev_type(hdev_obj, &dev_type))
- continue;
-
- if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
- drv_datap = dev_get_drvdata(bridge);
-
- if (drv_datap && drv_datap->base_img)
- proc_auto_start(dev_node, hdev_obj);
- }
- }
-
- return status;
-}
-
-/* TODO: Remove deprecated and not implemented ioctl wrappers */
-
-/*
- * ======== mgrwrap_enum_node_info ========
- */
-u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
-{
- u8 *pndb_props;
- u32 num_nodes;
- int status = 0;
- u32 size = args->args_mgr_enumnode_info.ndb_props_size;
-
- if (size < sizeof(struct dsp_ndbprops))
- return -EINVAL;
-
- pndb_props = kmalloc(size, GFP_KERNEL);
- if (pndb_props == NULL)
- status = -ENOMEM;
-
- if (!status) {
- status =
- mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
- (struct dsp_ndbprops *)pndb_props, size,
- &num_nodes);
- }
- CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status,
- size);
- CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status,
- 1);
- kfree(pndb_props);
-
- return status;
-}
-
-/*
- * ======== mgrwrap_enum_proc_info ========
- */
-u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
-{
- u8 *processor_info;
- u8 num_procs;
- int status = 0;
- u32 size = args->args_mgr_enumproc_info.processor_info_size;
-
- if (size < sizeof(struct dsp_processorinfo))
- return -EINVAL;
-
- processor_info = kmalloc(size, GFP_KERNEL);
- if (processor_info == NULL)
- status = -ENOMEM;
-
- if (!status) {
- status =
- mgr_enum_processor_info(args->args_mgr_enumproc_info.
- processor_id,
- (struct dsp_processorinfo *)
- processor_info, size, &num_procs);
- }
- CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
- status, size);
- CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs,
- status, 1);
- kfree(processor_info);
-
- return status;
-}
-
-#define WRAP_MAP2CALLER(x) x
-/*
- * ======== mgrwrap_register_object ========
- */
-u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct dsp_uuid uuid_obj;
- u32 path_size = 0;
- char *psz_path_name = NULL;
- int status = 0;
-
- CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
- if (status)
- goto func_end;
- path_size = strlen_user((char *)
- args->args_mgr_registerobject.sz_path_name);
- if (!path_size) {
- status = -EINVAL;
- goto func_end;
- }
-
- psz_path_name = kmalloc(path_size, GFP_KERNEL);
- if (!psz_path_name) {
- status = -ENOMEM;
- goto func_end;
- }
- ret = strncpy_from_user(psz_path_name,
- (char *)args->args_mgr_registerobject.
- sz_path_name, path_size);
- if (!ret) {
- status = -EFAULT;
- goto func_end;
- }
-
- if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) {
- status = -EINVAL;
- goto func_end;
- }
-
- status = dcd_register_object(&uuid_obj,
- args->args_mgr_registerobject.obj_type,
- (char *)psz_path_name);
-func_end:
- kfree(psz_path_name);
- return status;
-}
-
-/*
- * ======== mgrwrap_unregister_object ========
- */
-u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_uuid uuid_obj;
-
- CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
- if (status)
- goto func_end;
-
- status = dcd_unregister_object(&uuid_obj,
- args->args_mgr_unregisterobject.
- obj_type);
-func_end:
- return status;
-
-}
-
-/*
- * ======== mgrwrap_wait_for_bridge_events ========
- */
-u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_notification *anotifications[MAX_EVENTS];
- struct dsp_notification notifications[MAX_EVENTS];
- u32 index, i;
- u32 count = args->args_mgr_wait.count;
-
- if (count > MAX_EVENTS)
- status = -EINVAL;
-
- /* get the array of pointers to user structures */
- CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
- status, count);
- /* get the events */
- for (i = 0; i < count; i++) {
- CP_FM_USR(&notifications[i], anotifications[i], status, 1);
- if (status || !notifications[i].handle) {
- status = -EINVAL;
- break;
- }
- /* set the array of pointers to kernel structures */
- anotifications[i] = &notifications[i];
- }
- if (!status) {
- status = mgr_wait_for_bridge_events(anotifications, count,
- &index,
- args->args_mgr_wait.
- timeout);
- }
- CP_TO_USR(args->args_mgr_wait.index, &index, status, 1);
- return status;
-}
-
-/*
- * ======== MGRWRAP_GetProcessResourceInfo ========
- */
-u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args *args,
- void *pr_ctxt)
-{
- pr_err("%s: deprecated dspbridge ioctl\n", __func__);
- return 0;
-}
-
-/*
- * ======== procwrap_attach ========
- */
-u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
-{
- void *processor;
- int status = 0;
- struct dsp_processorattrin proc_attr_in, *attr_in = NULL;
-
- /* Optional argument */
- if (args->args_proc_attach.attr_in) {
- CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
- 1);
- if (!status)
- attr_in = &proc_attr_in;
- else
- goto func_end;
-
- }
- status = proc_attach(args->args_proc_attach.processor_id, attr_in,
- &processor, pr_ctxt);
- CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
-func_end:
- return status;
-}
-
-/*
- * ======== procwrap_ctrl ========
- */
-u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
-{
- u32 cb_data_size, __user * psize = (u32 __user *)
- args->args_proc_ctrl.args;
- u8 *pargs = NULL;
- int status = 0;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (psize) {
- if (get_user(cb_data_size, psize)) {
- status = -EPERM;
- goto func_end;
- }
- cb_data_size += sizeof(u32);
- pargs = kmalloc(cb_data_size, GFP_KERNEL);
- if (pargs == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
-
- CP_FM_USR(pargs, args->args_proc_ctrl.args, status,
- cb_data_size);
- }
- if (!status) {
- status = proc_ctrl(hprocessor,
- args->args_proc_ctrl.cmd,
- (struct dsp_cbdata *)pargs);
- }
-
- /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */
- kfree(pargs);
-func_end:
- return status;
-}
-
-/*
- * ======== procwrap_detach ========
- */
-u32 __deprecated procwrap_detach(union trapped_args *args, void *pr_ctxt)
-{
- /* proc_detach called at bridge_release only */
- pr_err("%s: deprecated dspbridge ioctl\n", __func__);
- return 0;
-}
-
-/*
- * ======== procwrap_enum_node_info ========
- */
-u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- void *node_tab[MAX_NODES];
- u32 num_nodes;
- u32 alloc_cnt;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (!args->args_proc_enumnode_info.node_tab_size)
- return -EINVAL;
-
- status = proc_enum_nodes(hprocessor,
- node_tab,
- args->args_proc_enumnode_info.node_tab_size,
- &num_nodes, &alloc_cnt);
- CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
- num_nodes);
- CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes,
- status, 1);
- CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt,
- status, 1);
- return status;
-}
-
-u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
-{
- int status;
-
- if (args->args_proc_dma.dir >= DMA_NONE)
- return -EINVAL;
-
- status = proc_end_dma(pr_ctxt,
- args->args_proc_dma.mpu_addr,
- args->args_proc_dma.size,
- args->args_proc_dma.dir);
- return status;
-}
-
-u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
-{
- int status;
-
- if (args->args_proc_dma.dir >= DMA_NONE)
- return -EINVAL;
-
- status = proc_begin_dma(pr_ctxt,
- args->args_proc_dma.mpu_addr,
- args->args_proc_dma.size,
- args->args_proc_dma.dir);
- return status;
-}
-
-/*
- * ======== procwrap_flush_memory ========
- */
-u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
-{
- int status;
-
- if (args->args_proc_flushmemory.flags >
- PROC_WRITEBACK_INVALIDATE_MEM)
- return -EINVAL;
-
- status = proc_flush_memory(pr_ctxt,
- args->args_proc_flushmemory.mpu_addr,
- args->args_proc_flushmemory.size,
- args->args_proc_flushmemory.flags);
- return status;
-}
-
-/*
- * ======== procwrap_invalidate_memory ========
- */
-u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
-{
- int status;
-
- status =
- proc_invalidate_memory(pr_ctxt,
- args->args_proc_invalidatememory.mpu_addr,
- args->args_proc_invalidatememory.size);
- return status;
-}
-
-/*
- * ======== procwrap_enum_resources ========
- */
-u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_resourceinfo resource_info;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (args->args_proc_enumresources.resource_info_size <
- sizeof(struct dsp_resourceinfo))
- return -EINVAL;
-
- status =
- proc_get_resource_info(hprocessor,
- args->args_proc_enumresources.resource_type,
- &resource_info,
- args->args_proc_enumresources.
- resource_info_size);
-
- CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
- status, 1);
-
- return status;
-
-}
-
-/*
- * ======== procwrap_get_state ========
- */
-u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- struct dsp_processorstate proc_state;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (args->args_proc_getstate.state_info_size <
- sizeof(struct dsp_processorstate))
- return -EINVAL;
-
- status = proc_get_state(hprocessor, &proc_state,
- args->args_proc_getstate.state_info_size);
- CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
- 1);
- return status;
-
-}
-
-/*
- * ======== procwrap_get_trace ========
- */
-u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- u8 *pbuf;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
- return -EINVAL;
-
- pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
- if (pbuf != NULL) {
- status = proc_get_trace(hprocessor, pbuf,
- args->args_proc_gettrace.max_size);
- } else {
- status = -ENOMEM;
- }
- CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status,
- args->args_proc_gettrace.max_size);
- kfree(pbuf);
-
- return status;
-}
-
-/*
- * ======== procwrap_load ========
- */
-u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
-{
- s32 i, len;
- int status = 0;
- char *temp;
- s32 count = args->args_proc_load.argc_index;
- u8 **argv = NULL, **envp = NULL;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (count <= 0 || count > MAX_LOADARGS) {
- status = -EINVAL;
- goto func_cont;
- }
-
- argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
- if (!argv) {
- status = -ENOMEM;
- goto func_cont;
- }
-
- CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
- if (status) {
- kfree(argv);
- argv = NULL;
- goto func_cont;
- }
-
- for (i = 0; i < count; i++) {
- if (argv[i]) {
- /* User space pointer to argument */
- temp = (char *)argv[i];
- /* len is increased by 1 to accommodate NULL */
- len = strlen_user((char *)temp) + 1;
- /* Kernel space pointer to argument */
- argv[i] = kmalloc(len, GFP_KERNEL);
- if (argv[i]) {
- CP_FM_USR(argv[i], temp, status, len);
- if (status) {
- kfree(argv[i]);
- argv[i] = NULL;
- goto func_cont;
- }
- } else {
- status = -ENOMEM;
- goto func_cont;
- }
- }
- }
- /* TODO: validate this */
- if (args->args_proc_load.user_envp) {
- /* number of elements in the envp array including NULL */
- count = 0;
- do {
- if (get_user(temp,
- args->args_proc_load.user_envp + count)) {
- status = -EFAULT;
- goto func_cont;
- }
- count++;
- } while (temp);
- envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
- if (!envp) {
- status = -ENOMEM;
- goto func_cont;
- }
-
- CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
- if (status) {
- kfree(envp);
- envp = NULL;
- goto func_cont;
- }
- for (i = 0; envp[i]; i++) {
- /* User space pointer to argument */
- temp = (char *)envp[i];
- /* len is increased by 1 to accommodate NULL */
- len = strlen_user((char *)temp) + 1;
- /* Kernel space pointer to argument */
- envp[i] = kmalloc(len, GFP_KERNEL);
- if (envp[i]) {
- CP_FM_USR(envp[i], temp, status, len);
- if (status) {
- kfree(envp[i]);
- envp[i] = NULL;
- goto func_cont;
- }
- } else {
- status = -ENOMEM;
- goto func_cont;
- }
- }
- }
-
- if (!status) {
- status = proc_load(hprocessor,
- args->args_proc_load.argc_index,
- (const char **)argv, (const char **)envp);
- }
-func_cont:
- if (envp) {
- i = 0;
- while (envp[i])
- kfree(envp[i++]);
-
- kfree(envp);
- }
-
- if (argv) {
- count = args->args_proc_load.argc_index;
- for (i = 0; (i < count) && argv[i]; i++)
- kfree(argv[i]);
-
- kfree(argv);
- }
-
- return status;
-}
-
-/*
- * ======== procwrap_map ========
- */
-u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- void *map_addr;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if (!args->args_proc_mapmem.size)
- return -EINVAL;
-
- status = proc_map(args->args_proc_mapmem.processor,
- args->args_proc_mapmem.mpu_addr,
- args->args_proc_mapmem.size,
- args->args_proc_mapmem.req_addr, &map_addr,
- args->args_proc_mapmem.map_attr, pr_ctxt);
- if (!status) {
- if (put_user(map_addr, args->args_proc_mapmem.map_addr)) {
- status = -EINVAL;
- proc_un_map(hprocessor, map_addr, pr_ctxt);
- }
-
- }
- return status;
-}
-
-/*
- * ======== procwrap_register_notify ========
- */
-u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- struct dsp_notification notification;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- /* Initialize the notification data structure */
- notification.name = NULL;
- notification.handle = NULL;
-
- status = proc_register_notify(hprocessor,
- args->args_proc_register_notify.event_mask,
- args->args_proc_register_notify.notify_type,
- &notification);
- CP_TO_USR(args->args_proc_register_notify.notification, &notification,
- status, 1);
- return status;
-}
-
-/*
- * ======== procwrap_reserve_memory ========
- */
-u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- void *prsv_addr;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- if ((args->args_proc_rsvmem.size <= 0) ||
- (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0)
- return -EINVAL;
-
- status = proc_reserve_memory(hprocessor,
- args->args_proc_rsvmem.size, &prsv_addr,
- pr_ctxt);
- if (!status) {
- if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) {
- status = -EINVAL;
- proc_un_reserve_memory(args->args_proc_rsvmem.
- processor, prsv_addr, pr_ctxt);
- }
- }
- return status;
-}
-
-/*
- * ======== procwrap_start ========
- */
-u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
-
- ret = proc_start(((struct process_context *)pr_ctxt)->processor);
- return ret;
-}
-
-/*
- * ======== procwrap_un_map ========
- */
-u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
-{
- int status;
-
- status = proc_un_map(((struct process_context *)pr_ctxt)->processor,
- args->args_proc_unmapmem.map_addr, pr_ctxt);
- return status;
-}
-
-/*
- * ======== procwrap_un_reserve_memory ========
- */
-u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- status = proc_un_reserve_memory(hprocessor,
- args->args_proc_unrsvmem.rsv_addr,
- pr_ctxt);
- return status;
-}
-
-/*
- * ======== procwrap_stop ========
- */
-u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
-
- ret = proc_stop(((struct process_context *)pr_ctxt)->processor);
-
- return ret;
-}
-
-/*
- * ======== find_handle =========
- */
-inline void find_node_handle(struct node_res_object **noderes,
- void *pr_ctxt, void *hnode)
-{
- rcu_read_lock();
- *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
- (int)hnode - 1);
- rcu_read_unlock();
- return;
-}
-
-
-/*
- * ======== nodewrap_allocate ========
- */
-u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_uuid node_uuid;
- u32 cb_data_size = 0;
- u32 __user *psize = (u32 __user *) args->args_node_allocate.args;
- u8 *pargs = NULL;
- struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
- struct node_res_object *node_res;
- int nodeid;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- /* Optional argument */
- if (psize) {
- if (get_user(cb_data_size, psize))
- status = -EPERM;
-
- cb_data_size += sizeof(u32);
- if (!status) {
- pargs = kmalloc(cb_data_size, GFP_KERNEL);
- if (pargs == NULL)
- status = -ENOMEM;
-
- }
- CP_FM_USR(pargs, args->args_node_allocate.args, status,
- cb_data_size);
- }
- CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
- if (status)
- goto func_cont;
- /* Optional argument */
- if (args->args_node_allocate.attr_in) {
- CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
- status, 1);
- if (!status)
- attr_in = &proc_attr_in;
- else
- status = -ENOMEM;
-
- }
- if (!status) {
- status = node_allocate(hprocessor,
- &node_uuid, (struct dsp_cbdata *)pargs,
- attr_in, &node_res, pr_ctxt);
- }
- if (!status) {
- nodeid = node_res->id + 1;
- CP_TO_USR(args->args_node_allocate.node, &nodeid,
- status, 1);
- if (status) {
- status = -EFAULT;
- node_delete(node_res, pr_ctxt);
- }
- }
-func_cont:
- kfree(pargs);
-
- return status;
-}
-
-/*
- * ======== nodewrap_alloc_msg_buf ========
- */
-u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_bufferattr *pattr = NULL;
- struct dsp_bufferattr attr;
- u8 *pbuffer = NULL;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt,
- args->args_node_allocmsgbuf.node);
-
- if (!node_res)
- return -EFAULT;
-
- if (!args->args_node_allocmsgbuf.size)
- return -EINVAL;
-
- if (args->args_node_allocmsgbuf.attr) { /* Optional argument */
- CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1);
- if (!status)
- pattr = &attr;
-
- }
- /* argument */
- CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1);
- if (!status) {
- status = node_alloc_msg_buf(node_res->node,
- args->args_node_allocmsgbuf.size,
- pattr, &pbuffer);
- }
- CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1);
- return status;
-}
-
-/*
- * ======== nodewrap_change_priority ========
- */
-u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt,
- args->args_node_changepriority.node);
-
- if (!node_res)
- return -EFAULT;
-
- ret = node_change_priority(node_res->node,
- args->args_node_changepriority.prio);
-
- return ret;
-}
-
-/*
- * ======== nodewrap_connect ========
- */
-u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_strmattr attrs;
- struct dsp_strmattr *pattrs = NULL;
- u32 cb_data_size;
- u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
- u8 *pargs = NULL;
- struct node_res_object *node_res1, *node_res2;
- struct node_object *node1 = NULL, *node2 = NULL;
-
- if ((int)args->args_node_connect.node != DSP_HGPPNODE) {
- find_node_handle(&node_res1, pr_ctxt,
- args->args_node_connect.node);
- if (node_res1)
- node1 = node_res1->node;
- } else {
- node1 = args->args_node_connect.node;
- }
-
- if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
- find_node_handle(&node_res2, pr_ctxt,
- args->args_node_connect.other_node);
- if (node_res2)
- node2 = node_res2->node;
- } else {
- node2 = args->args_node_connect.other_node;
- }
-
- if (!node1 || !node2)
- return -EFAULT;
-
- /* Optional argument */
- if (psize) {
- if (get_user(cb_data_size, psize))
- status = -EPERM;
-
- cb_data_size += sizeof(u32);
- if (!status) {
- pargs = kmalloc(cb_data_size, GFP_KERNEL);
- if (pargs == NULL) {
- status = -ENOMEM;
- goto func_cont;
- }
-
- }
- CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
- cb_data_size);
- if (status)
- goto func_cont;
- }
- if (args->args_node_connect.attrs) { /* Optional argument */
- CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1);
- if (!status)
- pattrs = &attrs;
-
- }
- if (!status) {
- status = node_connect(node1,
- args->args_node_connect.stream_id,
- node2,
- args->args_node_connect.other_stream,
- pattrs, (struct dsp_cbdata *)pargs);
- }
-func_cont:
- kfree(pargs);
-
- return status;
-}
-
-/*
- * ======== nodewrap_create ========
- */
-u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_create.node);
-
- if (!node_res)
- return -EFAULT;
-
- ret = node_create(node_res->node);
-
- return ret;
-}
-
-/*
- * ======== nodewrap_delete ========
- */
-u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node);
-
- if (!node_res)
- return -EFAULT;
-
- ret = node_delete(node_res, pr_ctxt);
-
- return ret;
-}
-
-/*
- * ======== nodewrap_free_msg_buf ========
- */
-u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_bufferattr *pattr = NULL;
- struct dsp_bufferattr attr;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node);
-
- if (!node_res)
- return -EFAULT;
-
- if (args->args_node_freemsgbuf.attr) { /* Optional argument */
- CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1);
- if (!status)
- pattr = &attr;
-
- }
-
- if (!args->args_node_freemsgbuf.buffer)
- return -EFAULT;
-
- if (!status) {
- status = node_free_msg_buf(node_res->node,
- args->args_node_freemsgbuf.buffer,
- pattr);
- }
-
- return status;
-}
-
-/*
- * ======== nodewrap_get_attr ========
- */
-u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_nodeattr attr;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node);
-
- if (!node_res)
- return -EFAULT;
-
- status = node_get_attr(node_res->node, &attr,
- args->args_node_getattr.attr_size);
- CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1);
-
- return status;
-}
-
-/*
- * ======== nodewrap_get_message ========
- */
-u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- struct dsp_msg msg;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node);
-
- if (!node_res)
- return -EFAULT;
-
- status = node_get_message(node_res->node, &msg,
- args->args_node_getmessage.timeout);
-
- CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
-
- return status;
-}
-
-/*
- * ======== nodewrap_pause ========
- */
-u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node);
-
- if (!node_res)
- return -EFAULT;
-
- ret = node_pause(node_res->node);
-
- return ret;
-}
-
-/*
- * ======== nodewrap_put_message ========
- */
-u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_msg msg;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node);
-
- if (!node_res)
- return -EFAULT;
-
- CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
-
- if (!status) {
- status =
- node_put_message(node_res->node, &msg,
- args->args_node_putmessage.timeout);
- }
-
- return status;
-}
-
-/*
- * ======== nodewrap_register_notify ========
- */
-u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_notification notification;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt,
- args->args_node_registernotify.node);
-
- if (!node_res)
- return -EFAULT;
-
- /* Initialize the notification data structure */
- notification.name = NULL;
- notification.handle = NULL;
-
- if (!args->args_proc_register_notify.event_mask)
- CP_FM_USR(&notification,
- args->args_proc_register_notify.notification,
- status, 1);
-
- status = node_register_notify(node_res->node,
- args->args_node_registernotify.event_mask,
- args->args_node_registernotify.
- notify_type, &notification);
- CP_TO_USR(args->args_node_registernotify.notification, &notification,
- status, 1);
- return status;
-}
-
-/*
- * ======== nodewrap_run ========
- */
-u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_run.node);
-
- if (!node_res)
- return -EFAULT;
-
- ret = node_run(node_res->node);
-
- return ret;
-}
-
-/*
- * ======== nodewrap_terminate ========
- */
-u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- int tempstatus;
- struct node_res_object *node_res;
-
- find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node);
-
- if (!node_res)
- return -EFAULT;
-
- status = node_terminate(node_res->node, &tempstatus);
-
- CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1);
-
- return status;
-}
-
-/*
- * ======== nodewrap_get_uuid_props ========
- */
-u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_uuid node_uuid;
- struct dsp_ndbprops *pnode_props = NULL;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
- 1);
- if (status)
- goto func_cont;
- pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
- if (pnode_props != NULL) {
- status =
- node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
- CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
- status, 1);
- } else
- status = -ENOMEM;
-func_cont:
- kfree(pnode_props);
- return status;
-}
-
-/*
- * ======== find_strm_handle =========
- */
-inline void find_strm_handle(struct strm_res_object **strmres,
- void *pr_ctxt, void *hstream)
-{
- rcu_read_lock();
- *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
- (int)hstream - 1);
- rcu_read_unlock();
- return;
-}
-
-/*
- * ======== strmwrap_allocate_buffer ========
- */
-u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
-{
- int status;
- u8 **ap_buffer = NULL;
- u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt,
- args->args_strm_allocatebuffer.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- if (num_bufs > MAX_BUFS)
- return -EINVAL;
-
- ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
- if (ap_buffer == NULL)
- return -ENOMEM;
-
- status = strm_allocate_buffer(strm_res,
- args->args_strm_allocatebuffer.size,
- ap_buffer, num_bufs, pr_ctxt);
- if (!status) {
- CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
- status, num_bufs);
- if (status) {
- status = -EFAULT;
- strm_free_buffer(strm_res,
- ap_buffer, num_bufs, pr_ctxt);
- }
- }
- kfree(ap_buffer);
-
- return status;
-}
-
-/*
- * ======== strmwrap_close ========
- */
-u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
-{
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- return strm_close(strm_res, pr_ctxt);
-}
-
-/*
- * ======== strmwrap_free_buffer ========
- */
-u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- u8 **ap_buffer = NULL;
- u32 num_bufs = args->args_strm_freebuffer.num_bufs;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt,
- args->args_strm_freebuffer.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- if (num_bufs > MAX_BUFS)
- return -EINVAL;
-
- ap_buffer = kmalloc_array(num_bufs, sizeof(u8 *), GFP_KERNEL);
- if (ap_buffer == NULL)
- return -ENOMEM;
-
- CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
- num_bufs);
-
- if (!status)
- status = strm_free_buffer(strm_res,
- ap_buffer, num_bufs, pr_ctxt);
-
- CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
- num_bufs);
- kfree(ap_buffer);
-
- return status;
-}
-
-/*
- * ======== strmwrap_get_event_handle ========
- */
-u32 __deprecated strmwrap_get_event_handle(union trapped_args *args,
- void *pr_ctxt)
-{
- pr_err("%s: deprecated dspbridge ioctl\n", __func__);
- return -ENOSYS;
-}
-
-/*
- * ======== strmwrap_get_info ========
- */
-u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct stream_info strm_info;
- struct dsp_streaminfo user;
- struct dsp_streaminfo *temp;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt,
- args->args_strm_getinfo.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
- temp = strm_info.user_strm;
-
- strm_info.user_strm = &user;
-
- if (!status) {
- status = strm_get_info(strm_res->stream,
- &strm_info,
- args->args_strm_getinfo.
- stream_info_size);
- }
- CP_TO_USR(temp, strm_info.user_strm, status, 1);
- strm_info.user_strm = temp;
- CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
- return status;
-}
-
-/*
- * ======== strmwrap_idle ========
- */
-u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
-{
- u32 ret;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag);
-
- return ret;
-}
-
-/*
- * ======== strmwrap_issue ========
- */
-u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- if (!args->args_strm_issue.buffer)
- return -EFAULT;
-
- /* No need of doing CP_FM_USR for the user buffer (pbuffer)
- as this is done in Bridge internal function bridge_chnl_add_io_req
- in chnl_sm.c */
- status = strm_issue(strm_res->stream,
- args->args_strm_issue.buffer,
- args->args_strm_issue.bytes,
- args->args_strm_issue.buf_size,
- args->args_strm_issue.arg);
-
- return status;
-}
-
-/*
- * ======== strmwrap_open ========
- */
-u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct strm_attr attr;
- struct strm_res_object *strm_res_obj;
- struct dsp_streamattrin strm_attr_in;
- struct node_res_object *node_res;
- int strmid;
-
- find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node);
-
- if (!node_res)
- return -EFAULT;
-
- CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
-
- if (attr.stream_attr_in != NULL) { /* Optional argument */
- CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
- if (!status) {
- attr.stream_attr_in = &strm_attr_in;
- if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
- return -ENOSYS;
- }
-
- }
- status = strm_open(node_res->node,
- args->args_strm_open.direction,
- args->args_strm_open.index, &attr, &strm_res_obj,
- pr_ctxt);
- if (!status) {
- strmid = strm_res_obj->id + 1;
- CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1);
- }
- return status;
-}
-
-/*
- * ======== strmwrap_reclaim ========
- */
-u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- u8 *buf_ptr;
- u32 ul_bytes;
- u32 dw_arg;
- u32 ul_buf_size;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- status = strm_reclaim(strm_res->stream, &buf_ptr,
- &ul_bytes, &ul_buf_size, &dw_arg);
- CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
- CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
- CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1);
-
- if (args->args_strm_reclaim.buf_size_ptr != NULL) {
- CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
- status, 1);
- }
-
- return status;
-}
-
-/*
- * ======== strmwrap_register_notify ========
- */
-u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct dsp_notification notification;
- struct strm_res_object *strm_res;
-
- find_strm_handle(&strm_res, pr_ctxt,
- args->args_strm_registernotify.stream);
-
- if (!strm_res)
- return -EFAULT;
-
- /* Initialize the notification data structure */
- notification.name = NULL;
- notification.handle = NULL;
-
- status = strm_register_notify(strm_res->stream,
- args->args_strm_registernotify.event_mask,
- args->args_strm_registernotify.
- notify_type, &notification);
- CP_TO_USR(args->args_strm_registernotify.notification, &notification,
- status, 1);
-
- return status;
-}
-
-/*
- * ======== strmwrap_select ========
- */
-u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
-{
- u32 mask;
- struct strm_object *strm_tab[MAX_STREAMS];
- int status = 0;
- struct strm_res_object *strm_res;
- int *ids[MAX_STREAMS];
- int i;
-
- if (args->args_strm_select.strm_num > MAX_STREAMS)
- return -EINVAL;
-
- CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
- args->args_strm_select.strm_num);
-
- if (status)
- return status;
-
- for (i = 0; i < args->args_strm_select.strm_num; i++) {
- find_strm_handle(&strm_res, pr_ctxt, ids[i]);
-
- if (!strm_res)
- return -EFAULT;
-
- strm_tab[i] = strm_res->stream;
- }
-
- if (!status) {
- status = strm_select(strm_tab, args->args_strm_select.strm_num,
- &mask, args->args_strm_select.timeout);
- }
- CP_TO_USR(args->args_strm_select.mask, &mask, status, 1);
- return status;
-}
-
-/* CMM */
-
-/*
- * ======== cmmwrap_calloc_buf ========
- */
-u32 __deprecated cmmwrap_calloc_buf(union trapped_args *args, void *pr_ctxt)
-{
- /* This operation is done in kernel */
- pr_err("%s: deprecated dspbridge ioctl\n", __func__);
- return -ENOSYS;
-}
-
-/*
- * ======== cmmwrap_free_buf ========
- */
-u32 __deprecated cmmwrap_free_buf(union trapped_args *args, void *pr_ctxt)
-{
- /* This operation is done in kernel */
- pr_err("%s: deprecated dspbridge ioctl\n", __func__);
- return -ENOSYS;
-}
-
-/*
- * ======== cmmwrap_get_handle ========
- */
-u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct cmm_object *hcmm_mgr;
- void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
-
- status = cmm_get_handle(hprocessor, &hcmm_mgr);
-
- CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1);
-
- return status;
-}
-
-/*
- * ======== cmmwrap_get_info ========
- */
-u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
-{
- int status = 0;
- struct cmm_info cmm_info_obj;
-
- status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj);
-
- CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,
- 1);
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c
deleted file mode 100644
index 4073c9c672fd..000000000000
--- a/drivers/staging/tidspbridge/pmgr/io.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * io.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * IO manager interface: Manages IO between CHNL and msg_ctrl.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- This */
-#include <ioobj.h>
-#include <dspbridge/io.h>
-
-/*
- * ======== io_create ========
- * Purpose:
- * Create an IO manager object, responsible for managing IO between
- * CHNL and msg_ctrl
- */
-int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj,
- const struct io_attrs *mgr_attrts)
-{
- struct bridge_drv_interface *intf_fxns;
- struct io_mgr *hio_mgr = NULL;
- struct io_mgr_ *pio_mgr = NULL;
- int status = 0;
-
- *io_man = NULL;
-
- /* A memory base of 0 implies no memory base: */
- if ((mgr_attrts->shm_base != 0) && (mgr_attrts->sm_length == 0))
- status = -EINVAL;
-
- if (mgr_attrts->word_size == 0)
- status = -EINVAL;
-
- if (!status) {
- dev_get_intf_fxns(hdev_obj, &intf_fxns);
-
- /* Let Bridge channel module finish the create: */
- status = (*intf_fxns->io_create) (&hio_mgr, hdev_obj,
- mgr_attrts);
-
- if (!status) {
- pio_mgr = (struct io_mgr_ *)hio_mgr;
- pio_mgr->intf_fxns = intf_fxns;
- pio_mgr->dev_obj = hdev_obj;
-
- /* Return the new channel manager handle: */
- *io_man = hio_mgr;
- }
- }
-
- return status;
-}
-
-/*
- * ======== io_destroy ========
- * Purpose:
- * Delete IO manager.
- */
-int io_destroy(struct io_mgr *hio_mgr)
-{
- struct bridge_drv_interface *intf_fxns;
- struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr;
- int status;
-
- intf_fxns = pio_mgr->intf_fxns;
-
- /* Let Bridge channel module destroy the io_mgr: */
- status = (*intf_fxns->io_destroy) (hio_mgr);
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/pmgr/ioobj.h b/drivers/staging/tidspbridge/pmgr/ioobj.h
deleted file mode 100644
index 7defd9481458..000000000000
--- a/drivers/staging/tidspbridge/pmgr/ioobj.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ioobj.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Structure subcomponents of channel class library IO objects which
- * are exposed to DSP API from Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef IOOBJ_
-#define IOOBJ_
-
-#include <dspbridge/devdefs.h>
-#include <dspbridge/dspdefs.h>
-
-/*
- * This struct is the first field in a io_mgr struct. Other, implementation
- * specific fields follow this structure in memory.
- */
-struct io_mgr_ {
- /* These must be the first fields in a io_mgr struct: */
- struct bridge_dev_context *bridge_context; /* Bridge context. */
- /* Function interface to Bridge driver. */
- struct bridge_drv_interface *intf_fxns;
- struct dev_object *dev_obj; /* Device this board represents. */
-};
-
-#endif /* IOOBJ_ */
diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c
deleted file mode 100644
index f093cfb51c00..000000000000
--- a/drivers/staging/tidspbridge/pmgr/msg.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * msg.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge msg_ctrl Module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- This */
-#include <msgobj.h>
-#include <dspbridge/msg.h>
-
-/*
- * ======== msg_create ========
- * Purpose:
- * Create an object to manage message queues. Only one of these objects
- * can exist per device object.
- */
-int msg_create(struct msg_mgr **msg_man,
- struct dev_object *hdev_obj, msg_onexit msg_callback)
-{
- struct bridge_drv_interface *intf_fxns;
- struct msg_mgr_ *msg_mgr_obj;
- struct msg_mgr *hmsg_mgr;
- int status = 0;
-
- *msg_man = NULL;
-
- dev_get_intf_fxns(hdev_obj, &intf_fxns);
-
- /* Let Bridge message module finish the create: */
- status =
- (*intf_fxns->msg_create) (&hmsg_mgr, hdev_obj, msg_callback);
-
- if (!status) {
- /* Fill in DSP API message module's fields of the msg_mgr
- * structure */
- msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
- msg_mgr_obj->intf_fxns = intf_fxns;
-
- /* Finally, return the new message manager handle: */
- *msg_man = hmsg_mgr;
- } else {
- status = -EPERM;
- }
- return status;
-}
-
-/*
- * ======== msg_delete ========
- * Purpose:
- * Delete a msg_ctrl manager allocated in msg_create().
- */
-void msg_delete(struct msg_mgr *hmsg_mgr)
-{
- struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
- struct bridge_drv_interface *intf_fxns;
-
- if (msg_mgr_obj) {
- intf_fxns = msg_mgr_obj->intf_fxns;
-
- /* Let Bridge message module destroy the msg_mgr: */
- (*intf_fxns->msg_delete) (hmsg_mgr);
- } else {
- dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n",
- __func__, hmsg_mgr);
- }
-}
diff --git a/drivers/staging/tidspbridge/pmgr/msgobj.h b/drivers/staging/tidspbridge/pmgr/msgobj.h
deleted file mode 100644
index 14ca633c56cb..000000000000
--- a/drivers/staging/tidspbridge/pmgr/msgobj.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * msgobj.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Structure subcomponents of channel class library msg_ctrl objects which
- * are exposed to DSP API from Bridge driver.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef MSGOBJ_
-#define MSGOBJ_
-
-#include <dspbridge/dspdefs.h>
-
-#include <dspbridge/msgdefs.h>
-
-/*
- * This struct is the first field in a msg_mgr struct. Other, implementation
- * specific fields follow this structure in memory.
- */
-struct msg_mgr_ {
- /* The first field must match that in _msg_sm.h */
-
- /* Function interface to Bridge driver. */
- struct bridge_drv_interface *intf_fxns;
-};
-
-#endif /* MSGOBJ_ */
diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c
deleted file mode 100644
index 2ae48c9a9362..000000000000
--- a/drivers/staging/tidspbridge/rmgr/dbdcd.c
+++ /dev/null
@@ -1,1483 +0,0 @@
-/*
- * dbdcd.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * This file contains the implementation of the DSP/BIOS Bridge
- * Configuration Database (DCD).
- *
- * Notes:
- * The fxn dcd_get_objects can apply a callback fxn to each DCD object
- * that is located in a specified COFF file. At the moment,
- * dcd_auto_register, dcd_auto_unregister, and NLDR module all use
- * dcd_get_objects.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/cod.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/uuidutil.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dbdcd.h>
-
-/* ----------------------------------- Global defines. */
-#define MAX_INT2CHAR_LENGTH 16 /* Max int2char len of 32 bit int */
-
-/* Name of section containing dependent libraries */
-#define DEPLIBSECT ".dspbridge_deplibs"
-
-/* DCD specific structures. */
-struct dcd_manager {
- struct cod_manager *cod_mgr; /* Handle to COD manager object. */
-};
-
-/* Pointer to the registry support key */
-static struct list_head reg_key_list;
-static DEFINE_SPINLOCK(dbdcd_lock);
-
-/* Global reference variables. */
-static u32 refs;
-static u32 enum_refs;
-
-/* Helper function prototypes. */
-static s32 atoi(char *psz_buf);
-static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
- enum dsp_dcdobjtype obj_type,
- struct dcd_genericobj *gen_obj);
-static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size);
-static char dsp_char2_gpp_char(char *word, s32 dsp_char_size);
-static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 *num_libs,
- u16 *num_pers_libs,
- struct dsp_uuid *dep_lib_uuids,
- bool *prstnt_dep_libs,
- enum nldr_phase phase);
-
-/*
- * ======== dcd_uuid_from_string ========
- * Purpose:
- * Converts an ANSI string to a dsp_uuid.
- * Parameters:
- * sz_uuid: Pointer to a string that represents a dsp_uuid object.
- * uuid_obj: Pointer to a dsp_uuid object.
- * Returns:
- * 0: Success.
- * -EINVAL: Coversion failed
- * Requires:
- * uuid_obj & sz_uuid are non-NULL values.
- * Ensures:
- * Details:
- * We assume the string representation of a UUID has the following format:
- * "12345678_1234_1234_1234_123456789abc".
- */
-static int dcd_uuid_from_string(char *sz_uuid, struct dsp_uuid *uuid_obj)
-{
- char c;
- u64 t;
- struct dsp_uuid uuid_tmp;
-
- /*
- * sscanf implementation cannot deal with hh format modifier
- * if the converted value doesn't fit in u32. So, convert the
- * last six bytes to u64 and memcpy what is needed
- */
- if (sscanf(sz_uuid, "%8x%c%4hx%c%4hx%c%2hhx%2hhx%c%llx",
- &uuid_tmp.data1, &c, &uuid_tmp.data2, &c,
- &uuid_tmp.data3, &c, &uuid_tmp.data4,
- &uuid_tmp.data5, &c, &t) != 10)
- return -EINVAL;
-
- t = cpu_to_be64(t);
- memcpy(&uuid_tmp.data6[0], ((char *)&t) + 2, 6);
- *uuid_obj = uuid_tmp;
-
- return 0;
-}
-
-/*
- * ======== dcd_auto_register ========
- * Purpose:
- * Parses the supplied image and resigsters with DCD.
- */
-int dcd_auto_register(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path)
-{
- int status = 0;
-
- if (hdcd_mgr)
- status = dcd_get_objects(hdcd_mgr, sz_coff_path,
- (dcd_registerfxn) dcd_register_object,
- (void *)sz_coff_path);
- else
- status = -EFAULT;
-
- return status;
-}
-
-/*
- * ======== dcd_auto_unregister ========
- * Purpose:
- * Parses the supplied DSP image and unresiters from DCD.
- */
-int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path)
-{
- int status = 0;
-
- if (hdcd_mgr)
- status = dcd_get_objects(hdcd_mgr, sz_coff_path,
- (dcd_registerfxn) dcd_register_object,
- NULL);
- else
- status = -EFAULT;
-
- return status;
-}
-
-/*
- * ======== dcd_create_manager ========
- * Purpose:
- * Creates DCD manager.
- */
-int dcd_create_manager(char *sz_zl_dll_name,
- struct dcd_manager **dcd_mgr)
-{
- struct cod_manager *cod_mgr; /* COD manager handle */
- struct dcd_manager *dcd_mgr_obj = NULL; /* DCD Manager pointer */
- int status = 0;
-
- status = cod_create(&cod_mgr, sz_zl_dll_name);
- if (status)
- goto func_end;
-
- /* Create a DCD object. */
- dcd_mgr_obj = kzalloc(sizeof(struct dcd_manager), GFP_KERNEL);
- if (dcd_mgr_obj != NULL) {
- /* Fill out the object. */
- dcd_mgr_obj->cod_mgr = cod_mgr;
-
- /* Return handle to this DCD interface. */
- *dcd_mgr = dcd_mgr_obj;
- } else {
- status = -ENOMEM;
-
- /*
- * If allocation of DcdManager object failed, delete the
- * COD manager.
- */
- cod_delete(cod_mgr);
- }
-
-func_end:
- return status;
-}
-
-/*
- * ======== dcd_destroy_manager ========
- * Purpose:
- * Frees DCD Manager object.
- */
-int dcd_destroy_manager(struct dcd_manager *hdcd_mgr)
-{
- struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
- int status = -EFAULT;
-
- if (hdcd_mgr) {
- /* Delete the COD manager. */
- cod_delete(dcd_mgr_obj->cod_mgr);
-
- /* Deallocate a DCD manager object. */
- kfree(dcd_mgr_obj);
-
- status = 0;
- }
-
- return status;
-}
-
-/*
- * ======== dcd_enumerate_object ========
- * Purpose:
- * Enumerates objects in the DCD.
- */
-int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
- struct dsp_uuid *uuid_obj)
-{
- int status = 0;
- char sz_reg_key[DCD_MAXPATHLENGTH];
- char sz_value[DCD_MAXPATHLENGTH];
- struct dsp_uuid dsp_uuid_obj;
- char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */
- u32 dw_key_len = 0;
- struct dcd_key_elem *dcd_key;
- int len;
-
- if ((index != 0) && (enum_refs == 0)) {
- /*
- * If an enumeration is being performed on an index greater
- * than zero, then the current enum_refs must have been
- * incremented to greater than zero.
- */
- status = -EIDRM;
- } else {
- /*
- * Pre-determine final key length. It's length of DCD_REGKEY +
- * "_\0" + length of sz_obj_type string + terminating NULL.
- */
- dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-
- /* Create proper REG key; concatenate DCD_REGKEY with
- * obj_type. */
- strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
- if ((strlen(sz_reg_key) + strlen("_\0")) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, "_\0", 2);
- } else {
- status = -EPERM;
- }
-
- /* This snprintf is guaranteed not to exceed max size of an
- * integer. */
- status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d",
- obj_type);
-
- if (status == -1) {
- status = -EPERM;
- } else {
- status = 0;
- if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, sz_obj_type,
- strlen(sz_obj_type) + 1);
- } else {
- status = -EPERM;
- }
- }
-
- if (!status) {
- len = strlen(sz_reg_key);
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- if (!strncmp(dcd_key->name, sz_reg_key, len)
- && !index--) {
- strncpy(sz_value, &dcd_key->name[len],
- strlen(&dcd_key->name[len]) + 1);
- break;
- }
- }
- spin_unlock(&dbdcd_lock);
-
- if (&dcd_key->link == &reg_key_list)
- status = -ENODATA;
- }
-
- if (!status) {
- /* Create UUID value using string retrieved from
- * registry. */
- status = dcd_uuid_from_string(sz_value, &dsp_uuid_obj);
-
- if (!status) {
- *uuid_obj = dsp_uuid_obj;
-
- /* Increment enum_refs to update reference
- * count. */
- enum_refs++;
- }
- } else if (status == -ENODATA) {
- /* At the end of enumeration. Reset enum_refs. */
- enum_refs = 0;
-
- /*
- * TODO: Revisit, this is not an error case but code
- * expects non-zero value.
- */
- status = ENODATA;
- } else {
- status = -EPERM;
- }
- }
-
- return status;
-}
-
-/*
- * ======== dcd_exit ========
- * Purpose:
- * Discontinue usage of the DCD module.
- */
-void dcd_exit(void)
-{
- struct dcd_key_elem *rv, *rv_tmp;
-
- refs--;
- if (refs == 0) {
- list_for_each_entry_safe(rv, rv_tmp, &reg_key_list, link) {
- list_del(&rv->link);
- kfree(rv->path);
- kfree(rv);
- }
- }
-
-}
-
-/*
- * ======== dcd_get_dep_libs ========
- */
-int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 num_libs, struct dsp_uuid *dep_lib_uuids,
- bool *prstnt_dep_libs,
- enum nldr_phase phase)
-{
- int status = 0;
-
- status =
- get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids,
- prstnt_dep_libs, phase);
-
- return status;
-}
-
-/*
- * ======== dcd_get_num_dep_libs ========
- */
-int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 *num_libs, u16 *num_pers_libs,
- enum nldr_phase phase)
-{
- int status = 0;
-
- status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs,
- NULL, NULL, phase);
-
- return status;
-}
-
-/*
- * ======== dcd_get_object_def ========
- * Purpose:
- * Retrieves the properties of a node or processor based on the UUID and
- * object type.
- */
-int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *obj_uuid,
- enum dsp_dcdobjtype obj_type,
- struct dcd_genericobj *obj_def)
-{
- struct dcd_manager *dcd_mgr_obj = hdcd_mgr; /* ptr to DCD mgr */
- struct cod_libraryobj *lib = NULL;
- int status = 0;
- int len;
- u32 ul_addr = 0; /* Used by cod_get_section */
- u32 ul_len = 0; /* Used by cod_get_section */
- u32 dw_buf_size; /* Used by REG functions */
- char sz_reg_key[DCD_MAXPATHLENGTH];
- char *sz_uuid; /*[MAXUUIDLEN]; */
- char *tmp;
- struct dcd_key_elem *dcd_key = NULL;
- char sz_sect_name[MAXUUIDLEN + 2]; /* ".[UUID]\0" */
- char *psz_coff_buf;
- u32 dw_key_len; /* Len of REG key. */
- char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */
-
- sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL);
- if (!sz_uuid) {
- status = -ENOMEM;
- goto func_end;
- }
-
- if (!hdcd_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- /* Pre-determine final key length. It's length of DCD_REGKEY +
- * "_\0" + length of sz_obj_type string + terminating NULL */
- dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-
- /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
- strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
-
- if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, "_\0", 2);
- else
- status = -EPERM;
-
- status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
- if (status == -1) {
- status = -EPERM;
- } else {
- status = 0;
-
- if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, sz_obj_type,
- strlen(sz_obj_type) + 1);
- } else {
- status = -EPERM;
- }
-
- /* Create UUID value to set in registry. */
- snprintf(sz_uuid, MAXUUIDLEN, "%pUL", obj_uuid);
-
- if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
- else
- status = -EPERM;
-
- /* Retrieve paths from the registry based on struct dsp_uuid */
- dw_buf_size = DCD_MAXPATHLENGTH;
- }
- if (!status) {
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- if (!strncmp(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1))
- break;
- }
- spin_unlock(&dbdcd_lock);
- if (&dcd_key->link == &reg_key_list) {
- status = -ENOKEY;
- goto func_end;
- }
- }
-
-
- /* Open COFF file. */
- status = cod_open(dcd_mgr_obj->cod_mgr, dcd_key->path,
- COD_NOLOAD, &lib);
- if (status) {
- status = -EACCES;
- goto func_end;
- }
-
- /* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */
- len = strlen(sz_uuid);
- if (len + 1 > sizeof(sz_sect_name)) {
- status = -EPERM;
- goto func_end;
- }
-
- /* Create section name based on node UUID. A period is
- * pre-pended to the UUID string to form the section name.
- * I.e. ".24BC8D90_BB45_11d4_B756_006008BDB66F" */
-
- len -= 4; /* uuid has 4 delimiters '-' */
- tmp = sz_uuid;
-
- strncpy(sz_sect_name, ".", 2);
- do {
- char *uuid = strsep(&tmp, "-");
- if (!uuid)
- break;
- len -= strlen(uuid);
- strncat(sz_sect_name, uuid, strlen(uuid) + 1);
- } while (len && strncat(sz_sect_name, "_", 2));
-
- /* Get section information. */
- status = cod_get_section(lib, sz_sect_name, &ul_addr, &ul_len);
- if (status) {
- status = -EACCES;
- goto func_end;
- }
-
- /* Allocate zeroed buffer. */
- psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
- if (psz_coff_buf == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
-#ifdef _DB_TIOMAP
- if (strstr(dcd_key->path, "iva") == NULL) {
- /* Locate section by objectID and read its content. */
- status =
- cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
- } else {
- status =
- cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
- dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
- }
-#else
- status = cod_read_section(lib, sz_sect_name, psz_coff_buf, ul_len);
-#endif
- if (!status) {
- /* Compress DSP buffer to conform to PC format. */
- if (strstr(dcd_key->path, "iva") == NULL) {
- compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
- } else {
- compress_buf(psz_coff_buf, ul_len, 1);
- dev_dbg(bridge, "%s: Compressing IVA COFF buffer by 1 "
- "for IVA!!\n", __func__);
- }
-
- /* Parse the content of the COFF buffer. */
- status =
- get_attrs_from_buf(psz_coff_buf, ul_len, obj_type, obj_def);
- if (status)
- status = -EACCES;
- } else {
- status = -EACCES;
- }
-
- /* Free the previously allocated dynamic buffer. */
- kfree(psz_coff_buf);
-func_end:
- if (lib)
- cod_close(lib);
-
- kfree(sz_uuid);
-
- return status;
-}
-
-/*
- * ======== dcd_get_objects ========
- */
-int dcd_get_objects(struct dcd_manager *hdcd_mgr,
- char *sz_coff_path, dcd_registerfxn register_fxn,
- void *handle)
-{
- struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
- int status = 0;
- char *psz_coff_buf;
- char *psz_cur;
- struct cod_libraryobj *lib = NULL;
- u32 ul_addr = 0; /* Used by cod_get_section */
- u32 ul_len = 0; /* Used by cod_get_section */
- char seps[] = ":, ";
- char *token = NULL;
- struct dsp_uuid dsp_uuid_obj;
- s32 object_type;
-
- if (!hdcd_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- /* Open DSP coff file, don't load symbols. */
- status = cod_open(dcd_mgr_obj->cod_mgr, sz_coff_path, COD_NOLOAD, &lib);
- if (status) {
- status = -EACCES;
- goto func_cont;
- }
-
- /* Get DCD_RESIGER_SECTION section information. */
- status = cod_get_section(lib, DCD_REGISTER_SECTION, &ul_addr, &ul_len);
- if (status || !(ul_len > 0)) {
- status = -EACCES;
- goto func_cont;
- }
-
- /* Allocate zeroed buffer. */
- psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
- if (psz_coff_buf == NULL) {
- status = -ENOMEM;
- goto func_cont;
- }
-#ifdef _DB_TIOMAP
- if (strstr(sz_coff_path, "iva") == NULL) {
- /* Locate section by objectID and read its content. */
- status = cod_read_section(lib, DCD_REGISTER_SECTION,
- psz_coff_buf, ul_len);
- } else {
- dev_dbg(bridge, "%s: Skipped Byte swap for IVA!!\n", __func__);
- status = cod_read_section(lib, DCD_REGISTER_SECTION,
- psz_coff_buf, ul_len);
- }
-#else
- status =
- cod_read_section(lib, DCD_REGISTER_SECTION, psz_coff_buf, ul_len);
-#endif
- if (!status) {
- /* Compress DSP buffer to conform to PC format. */
- if (strstr(sz_coff_path, "iva") == NULL) {
- compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
- } else {
- compress_buf(psz_coff_buf, ul_len, 1);
- dev_dbg(bridge, "%s: Compress COFF buffer with 1 word "
- "for IVA!!\n", __func__);
- }
-
- /* Read from buffer and register object in buffer. */
- psz_cur = psz_coff_buf;
- while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
- /* Retrieve UUID string. */
- status = dcd_uuid_from_string(token, &dsp_uuid_obj);
-
- if (!status) {
- /* Retrieve object type */
- token = strsep(&psz_cur, seps);
-
- /* Retrieve object type */
- object_type = atoi(token);
-
- /*
- * Apply register_fxn to the found DCD object.
- * Possible actions include:
- *
- * 1) Register found DCD object.
- * 2) Unregister found DCD object
- * (when handle == NULL)
- * 3) Add overlay node.
- */
- status =
- register_fxn(&dsp_uuid_obj, object_type,
- handle);
- }
- if (status) {
- /* if error occurs, break from while loop. */
- break;
- }
- }
- } else {
- status = -EACCES;
- }
-
- /* Free the previously allocated dynamic buffer. */
- kfree(psz_coff_buf);
-func_cont:
- if (lib)
- cod_close(lib);
-
-func_end:
- return status;
-}
-
-/*
- * ======== dcd_get_library_name ========
- * Purpose:
- * Retrieves the library name for the given UUID.
- *
- */
-int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- char *str_lib_name,
- u32 *buff_size,
- enum nldr_phase phase, bool *phase_split)
-{
- char sz_reg_key[DCD_MAXPATHLENGTH];
- char sz_uuid[MAXUUIDLEN];
- u32 dw_key_len; /* Len of REG key. */
- char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */
- int status = 0;
- struct dcd_key_elem *dcd_key = NULL;
-
- dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p,"
- " buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name,
- buff_size);
-
- /*
- * Pre-determine final key length. It's length of DCD_REGKEY +
- * "_\0" + length of sz_obj_type string + terminating NULL.
- */
- dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-
- /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
- strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
- if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, "_\0", 2);
- else
- status = -EPERM;
-
- switch (phase) {
- case NLDR_CREATE:
- /* create phase type */
- sprintf(sz_obj_type, "%d", DSP_DCDCREATELIBTYPE);
- break;
- case NLDR_EXECUTE:
- /* execute phase type */
- sprintf(sz_obj_type, "%d", DSP_DCDEXECUTELIBTYPE);
- break;
- case NLDR_DELETE:
- /* delete phase type */
- sprintf(sz_obj_type, "%d", DSP_DCDDELETELIBTYPE);
- break;
- case NLDR_NOPHASE:
- /* known to be a dependent library */
- sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
- break;
- default:
- status = -EINVAL;
- }
- if (!status) {
- if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, sz_obj_type,
- strlen(sz_obj_type) + 1);
- } else {
- status = -EPERM;
- }
- /* Create UUID value to find match in registry. */
- snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
- if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
- else
- status = -EPERM;
- }
- if (!status) {
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- /* See if the name matches. */
- if (!strncmp(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1))
- break;
- }
- spin_unlock(&dbdcd_lock);
- }
-
- if (&dcd_key->link == &reg_key_list)
- status = -ENOKEY;
-
- /* If can't find, phases might be registered as generic LIBRARYTYPE */
- if (status && phase != NLDR_NOPHASE) {
- if (phase_split)
- *phase_split = false;
-
- strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
- if ((strlen(sz_reg_key) + strlen("_\0")) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, "_\0", 2);
- } else {
- status = -EPERM;
- }
- sprintf(sz_obj_type, "%d", DSP_DCDLIBRARYTYPE);
- if ((strlen(sz_reg_key) + strlen(sz_obj_type))
- < DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, sz_obj_type,
- strlen(sz_obj_type) + 1);
- } else {
- status = -EPERM;
- }
- snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
- if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
- else
- status = -EPERM;
-
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- /* See if the name matches. */
- if (!strncmp(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1))
- break;
- }
- spin_unlock(&dbdcd_lock);
-
- status = (&dcd_key->link != &reg_key_list) ?
- 0 : -ENOKEY;
- }
-
- if (!status)
- memcpy(str_lib_name, dcd_key->path, strlen(dcd_key->path) + 1);
- return status;
-}
-
-/*
- * ======== dcd_init ========
- * Purpose:
- * Initialize the DCD module.
- */
-bool dcd_init(void)
-{
- bool ret = true;
-
- if (refs == 0)
- INIT_LIST_HEAD(&reg_key_list);
-
- if (ret)
- refs++;
-
- return ret;
-}
-
-/*
- * ======== dcd_register_object ========
- * Purpose:
- * Registers a node or a processor with the DCD.
- * If psz_path_name == NULL, unregister the specified DCD object.
- */
-int dcd_register_object(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type,
- char *psz_path_name)
-{
- int status = 0;
- char sz_reg_key[DCD_MAXPATHLENGTH];
- char sz_uuid[MAXUUIDLEN + 1];
- u32 dw_path_size = 0;
- u32 dw_key_len; /* Len of REG key. */
- char sz_obj_type[MAX_INT2CHAR_LENGTH]; /* str. rep. of obj_type. */
- struct dcd_key_elem *dcd_key = NULL;
-
- dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n",
- __func__, uuid_obj, obj_type, psz_path_name);
-
- /*
- * Pre-determine final key length. It's length of DCD_REGKEY +
- * "_\0" + length of sz_obj_type string + terminating NULL.
- */
- dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-
- /* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
- strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
- if ((strlen(sz_reg_key) + strlen("_\0")) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, "_\0", 2);
- else {
- status = -EPERM;
- goto func_end;
- }
-
- status = snprintf(sz_obj_type, MAX_INT2CHAR_LENGTH, "%d", obj_type);
- if (status == -1) {
- status = -EPERM;
- } else {
- status = 0;
- if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
- DCD_MAXPATHLENGTH) {
- strncat(sz_reg_key, sz_obj_type,
- strlen(sz_obj_type) + 1);
- } else
- status = -EPERM;
-
- /* Create UUID value to set in registry. */
- snprintf(sz_uuid, MAXUUIDLEN, "%pUL", uuid_obj);
- if ((strlen(sz_reg_key) + MAXUUIDLEN) < DCD_MAXPATHLENGTH)
- strncat(sz_reg_key, sz_uuid, MAXUUIDLEN);
- else
- status = -EPERM;
- }
-
- if (status)
- goto func_end;
-
- /*
- * If psz_path_name != NULL, perform registration, otherwise,
- * perform unregistration.
- */
-
- if (psz_path_name) {
- dw_path_size = strlen(psz_path_name) + 1;
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- /* See if the name matches. */
- if (!strncmp(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1))
- break;
- }
- spin_unlock(&dbdcd_lock);
- if (&dcd_key->link == &reg_key_list) {
- /*
- * Add new reg value (UUID+obj_type)
- * with COFF path info
- */
-
- dcd_key = kmalloc(sizeof(struct dcd_key_elem),
- GFP_KERNEL);
- if (!dcd_key) {
- status = -ENOMEM;
- goto func_end;
- }
-
- dcd_key->path = kmalloc(dw_path_size, GFP_KERNEL);
-
- if (!dcd_key->path) {
- kfree(dcd_key);
- status = -ENOMEM;
- goto func_end;
- }
-
- strncpy(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1);
- strncpy(dcd_key->path, psz_path_name ,
- dw_path_size);
- spin_lock(&dbdcd_lock);
- list_add_tail(&dcd_key->link, &reg_key_list);
- spin_unlock(&dbdcd_lock);
- } else {
- /* Make sure the new data is the same. */
- if (strncmp(dcd_key->path, psz_path_name,
- dw_path_size)) {
- /* The caller needs a different data size! */
- kfree(dcd_key->path);
- dcd_key->path = kmalloc(dw_path_size,
- GFP_KERNEL);
- if (dcd_key->path == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
- }
-
- /* We have a match! Copy out the data. */
- memcpy(dcd_key->path, psz_path_name, dw_path_size);
- }
- dev_dbg(bridge, "%s: psz_path_name=%s, dw_path_size=%d\n",
- __func__, psz_path_name, dw_path_size);
- } else {
- /* Deregister an existing object */
- spin_lock(&dbdcd_lock);
- list_for_each_entry(dcd_key, &reg_key_list, link) {
- if (!strncmp(dcd_key->name, sz_reg_key,
- strlen(sz_reg_key) + 1)) {
- list_del(&dcd_key->link);
- kfree(dcd_key->path);
- kfree(dcd_key);
- break;
- }
- }
- spin_unlock(&dbdcd_lock);
- if (&dcd_key->link == &reg_key_list)
- status = -EPERM;
- }
-
- if (!status) {
- /*
- * Because the node database has been updated through a
- * successful object registration/de-registration operation,
- * we need to reset the object enumeration counter to allow
- * current enumerations to reflect this update in the node
- * database.
- */
- enum_refs = 0;
- }
-func_end:
- return status;
-}
-
-/*
- * ======== dcd_unregister_object ========
- * Call DCD_Register object with psz_path_name set to NULL to
- * perform actual object de-registration.
- */
-int dcd_unregister_object(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type)
-{
- int status = 0;
-
- /*
- * When dcd_register_object is called with NULL as pathname,
- * it indicates an unregister object operation.
- */
- status = dcd_register_object(uuid_obj, obj_type, NULL);
-
- return status;
-}
-
-/*
- **********************************************************************
- * DCD Helper Functions
- **********************************************************************
- */
-
-/*
- * ======== atoi ========
- * Purpose:
- * This function converts strings in decimal or hex format to integers.
- */
-static s32 atoi(char *psz_buf)
-{
- char *pch = psz_buf;
- s32 base = 0;
-
- while (isspace(*pch))
- pch++;
-
- if (*pch == '-' || *pch == '+') {
- base = 10;
- pch++;
- } else if (*pch && tolower(pch[strlen(pch) - 1]) == 'h') {
- base = 16;
- }
-
- return simple_strtoul(pch, NULL, base);
-}
-
-/*
- * ======== get_attrs_from_buf ========
- * Purpose:
- * Parse the content of a buffer filled with DSP-side data and
- * retrieve an object's attributes from it. IMPORTANT: Assume the
- * buffer has been converted from DSP format to GPP format.
- */
-static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
- enum dsp_dcdobjtype obj_type,
- struct dcd_genericobj *gen_obj)
-{
- int status = 0;
- char seps[] = ", ";
- char *psz_cur;
- char *token;
- s32 token_len = 0;
- u32 i = 0;
-#ifdef _DB_TIOMAP
- s32 entry_id;
-#endif
-
- switch (obj_type) {
- case DSP_DCDNODETYPE:
- /*
- * Parse COFF sect buffer to retrieve individual tokens used
- * to fill in object attrs.
- */
- psz_cur = psz_buf;
- token = strsep(&psz_cur, seps);
-
- /* u32 cb_struct */
- gen_obj->obj_data.node_obj.ndb_props.cb_struct =
- (u32) atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* dsp_uuid ui_node_id */
- status = dcd_uuid_from_string(token,
- &gen_obj->obj_data.node_obj.
- ndb_props.ui_node_id);
- if (status)
- break;
-
- token = strsep(&psz_cur, seps);
-
- /* ac_name */
- token_len = strlen(token);
- if (token_len > DSP_MAXNAMELEN - 1)
- token_len = DSP_MAXNAMELEN - 1;
-
- strncpy(gen_obj->obj_data.node_obj.ndb_props.ac_name,
- token, token_len);
- gen_obj->obj_data.node_obj.ndb_props.ac_name[token_len] = '\0';
- token = strsep(&psz_cur, seps);
- /* u32 ntype */
- gen_obj->obj_data.node_obj.ndb_props.ntype = atoi(token);
- token = strsep(&psz_cur, seps);
- /* u32 cache_on_gpp */
- gen_obj->obj_data.node_obj.ndb_props.cache_on_gpp = atoi(token);
- token = strsep(&psz_cur, seps);
- /* dsp_resourcereqmts dsp_resource_reqmts */
- gen_obj->obj_data.node_obj.ndb_props.dsp_resource_reqmts.
- cb_struct = (u32) atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.static_data_size = atoi(token);
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.global_data_size = atoi(token);
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.program_mem_size = atoi(token);
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.wc_execution_time = atoi(token);
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.wc_period = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.wc_deadline = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.avg_exection_time = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.node_obj.ndb_props.
- dsp_resource_reqmts.minimum_period = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* s32 prio */
- gen_obj->obj_data.node_obj.ndb_props.prio = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 stack_size */
- gen_obj->obj_data.node_obj.ndb_props.stack_size = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 sys_stack_size */
- gen_obj->obj_data.node_obj.ndb_props.sys_stack_size =
- atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 stack_seg */
- gen_obj->obj_data.node_obj.ndb_props.stack_seg = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 message_depth */
- gen_obj->obj_data.node_obj.ndb_props.message_depth =
- atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 num_input_streams */
- gen_obj->obj_data.node_obj.ndb_props.num_input_streams =
- atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 num_output_streams */
- gen_obj->obj_data.node_obj.ndb_props.num_output_streams =
- atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* u32 timeout */
- gen_obj->obj_data.node_obj.ndb_props.timeout = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* char *str_create_phase_fxn */
- token_len = strlen(token);
- gen_obj->obj_data.node_obj.str_create_phase_fxn =
- kzalloc(token_len + 1, GFP_KERNEL);
- strncpy(gen_obj->obj_data.node_obj.str_create_phase_fxn,
- token, token_len);
- gen_obj->obj_data.node_obj.str_create_phase_fxn[token_len] =
- '\0';
- token = strsep(&psz_cur, seps);
-
- /* char *str_execute_phase_fxn */
- token_len = strlen(token);
- gen_obj->obj_data.node_obj.str_execute_phase_fxn =
- kzalloc(token_len + 1, GFP_KERNEL);
- strncpy(gen_obj->obj_data.node_obj.str_execute_phase_fxn,
- token, token_len);
- gen_obj->obj_data.node_obj.str_execute_phase_fxn[token_len] =
- '\0';
- token = strsep(&psz_cur, seps);
-
- /* char *str_delete_phase_fxn */
- token_len = strlen(token);
- gen_obj->obj_data.node_obj.str_delete_phase_fxn =
- kzalloc(token_len + 1, GFP_KERNEL);
- strncpy(gen_obj->obj_data.node_obj.str_delete_phase_fxn,
- token, token_len);
- gen_obj->obj_data.node_obj.str_delete_phase_fxn[token_len] =
- '\0';
- token = strsep(&psz_cur, seps);
-
- /* Segment id for message buffers */
- gen_obj->obj_data.node_obj.msg_segid = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* Message notification type */
- gen_obj->obj_data.node_obj.msg_notify_type = atoi(token);
- token = strsep(&psz_cur, seps);
-
- /* char *str_i_alg_name */
- if (token) {
- token_len = strlen(token);
- gen_obj->obj_data.node_obj.str_i_alg_name =
- kzalloc(token_len + 1, GFP_KERNEL);
- strncpy(gen_obj->obj_data.node_obj.str_i_alg_name,
- token, token_len);
- gen_obj->obj_data.node_obj.str_i_alg_name[token_len] =
- '\0';
- token = strsep(&psz_cur, seps);
- }
-
- /* Load type (static, dynamic, or overlay) */
- if (token) {
- gen_obj->obj_data.node_obj.load_type = atoi(token);
- token = strsep(&psz_cur, seps);
- }
-
- /* Dynamic load data requirements */
- if (token) {
- gen_obj->obj_data.node_obj.data_mem_seg_mask =
- atoi(token);
- token = strsep(&psz_cur, seps);
- }
-
- /* Dynamic load code requirements */
- if (token) {
- gen_obj->obj_data.node_obj.code_mem_seg_mask =
- atoi(token);
- token = strsep(&psz_cur, seps);
- }
-
- /* Extract node profiles into node properties */
- if (token) {
-
- gen_obj->obj_data.node_obj.ndb_props.count_profiles =
- atoi(token);
- for (i = 0;
- i <
- gen_obj->obj_data.node_obj.
- ndb_props.count_profiles; i++) {
- token = strsep(&psz_cur, seps);
- if (token) {
- /* Heap Size for the node */
- gen_obj->obj_data.node_obj.
- ndb_props.node_profiles[i].
- heap_size = atoi(token);
- }
- }
- }
- token = strsep(&psz_cur, seps);
- if (token) {
- gen_obj->obj_data.node_obj.ndb_props.stack_seg_name =
- (u32) (token);
- }
-
- break;
-
- case DSP_DCDPROCESSORTYPE:
- /*
- * Parse COFF sect buffer to retrieve individual tokens used
- * to fill in object attrs.
- */
- psz_cur = psz_buf;
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.cb_struct = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.processor_family = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.processor_type = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.clock_rate = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.internal_mem_size = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.external_mem_size = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.processor_id = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.ty_running_rtos = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.node_min_priority = atoi(token);
- token = strsep(&psz_cur, seps);
-
- gen_obj->obj_data.proc_info.node_max_priority = atoi(token);
-
-#ifdef _DB_TIOMAP
- /* Proc object may contain additional(extended) attributes. */
- /* attr must match proc.hxx */
- for (entry_id = 0; entry_id < 7; entry_id++) {
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
- gpp_phys = atoi(token);
-
- token = strsep(&psz_cur, seps);
- gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id].
- dsp_virt = atoi(token);
- }
-#endif
-
- break;
-
- default:
- status = -EPERM;
- break;
- }
-
- return status;
-}
-
-/*
- * ======== CompressBuffer ========
- * Purpose:
- * Compress the DSP buffer, if necessary, to conform to PC format.
- */
-static void compress_buf(char *psz_buf, u32 ul_buf_size, s32 char_size)
-{
- char *p;
- char ch;
- char *q;
-
- p = psz_buf;
- if (p == NULL)
- return;
-
- for (q = psz_buf; q < (psz_buf + ul_buf_size);) {
- ch = dsp_char2_gpp_char(q, char_size);
- if (ch == '\\') {
- q += char_size;
- ch = dsp_char2_gpp_char(q, char_size);
- switch (ch) {
- case 't':
- *p = '\t';
- break;
-
- case 'n':
- *p = '\n';
- break;
-
- case 'r':
- *p = '\r';
- break;
-
- case '0':
- *p = '\0';
- break;
-
- default:
- *p = ch;
- break;
- }
- } else {
- *p = ch;
- }
- p++;
- q += char_size;
- }
-
- /* NULL out remainder of buffer. */
- while (p < q)
- *p++ = '\0';
-}
-
-/*
- * ======== dsp_char2_gpp_char ========
- * Purpose:
- * Convert DSP char to host GPP char in a portable manner
- */
-static char dsp_char2_gpp_char(char *word, s32 dsp_char_size)
-{
- char ch = '\0';
- char *ch_src;
- s32 i;
-
- for (ch_src = word, i = dsp_char_size; i > 0; i--)
- ch |= *ch_src++;
-
- return ch;
-}
-
-/*
- * ======== get_dep_lib_info ========
- */
-static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
- struct dsp_uuid *uuid_obj,
- u16 *num_libs,
- u16 *num_pers_libs,
- struct dsp_uuid *dep_lib_uuids,
- bool *prstnt_dep_libs,
- enum nldr_phase phase)
-{
- struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
- char *psz_coff_buf = NULL;
- char *psz_cur;
- char *psz_file_name = NULL;
- struct cod_libraryobj *lib = NULL;
- u32 ul_addr = 0; /* Used by cod_get_section */
- u32 ul_len = 0; /* Used by cod_get_section */
- u32 dw_data_size = COD_MAXPATHLENGTH;
- char seps[] = ", ";
- char *token = NULL;
- bool get_uuids = (dep_lib_uuids != NULL);
- u16 dep_libs = 0;
- int status = 0;
-
- /* Initialize to 0 dependent libraries, if only counting number of
- * dependent libraries */
- if (!get_uuids) {
- *num_libs = 0;
- *num_pers_libs = 0;
- }
-
- /* Allocate a buffer for file name */
- psz_file_name = kzalloc(dw_data_size, GFP_KERNEL);
- if (psz_file_name == NULL) {
- status = -ENOMEM;
- } else {
- /* Get the name of the library */
- status = dcd_get_library_name(hdcd_mgr, uuid_obj, psz_file_name,
- &dw_data_size, phase, NULL);
- }
-
- /* Open the library */
- if (!status) {
- status = cod_open(dcd_mgr_obj->cod_mgr, psz_file_name,
- COD_NOLOAD, &lib);
- }
- if (!status) {
- /* Get dependent library section information. */
- status = cod_get_section(lib, DEPLIBSECT, &ul_addr, &ul_len);
-
- if (status) {
- /* Ok, no dependent libraries */
- ul_len = 0;
- status = 0;
- }
- }
-
- if (status || !(ul_len > 0))
- goto func_cont;
-
- /* Allocate zeroed buffer. */
- psz_coff_buf = kzalloc(ul_len + 4, GFP_KERNEL);
- if (psz_coff_buf == NULL)
- status = -ENOMEM;
-
- /* Read section contents. */
- status = cod_read_section(lib, DEPLIBSECT, psz_coff_buf, ul_len);
- if (status)
- goto func_cont;
-
- /* Compress and format DSP buffer to conform to PC format. */
- compress_buf(psz_coff_buf, ul_len, DSPWORDSIZE);
-
- /* Read from buffer */
- psz_cur = psz_coff_buf;
- while ((token = strsep(&psz_cur, seps)) && *token != '\0') {
- if (get_uuids) {
- if (dep_libs >= *num_libs) {
- /* Gone beyond the limit */
- break;
- } else {
- /* Retrieve UUID string. */
- status = dcd_uuid_from_string(token,
- &(dep_lib_uuids
- [dep_libs]));
- if (status)
- break;
-
- /* Is this library persistent? */
- token = strsep(&psz_cur, seps);
- prstnt_dep_libs[dep_libs] = atoi(token);
- dep_libs++;
- }
- } else {
- /* Advanc to next token */
- token = strsep(&psz_cur, seps);
- if (atoi(token))
- (*num_pers_libs)++;
-
- /* Just counting number of dependent libraries */
- (*num_libs)++;
- }
- }
-func_cont:
- if (lib)
- cod_close(lib);
-
- /* Free previously allocated dynamic buffers. */
- kfree(psz_file_name);
-
- kfree(psz_coff_buf);
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c
deleted file mode 100644
index 4af51b75aeab..000000000000
--- a/drivers/staging/tidspbridge/rmgr/disp.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * disp.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Node Dispatcher interface. Communicates with Resource Manager Server
- * (RMS) on DSP. Access to RMS is synchronized in NODE.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Link Driver */
-#include <dspbridge/dspdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-#include <dspbridge/chnldefs.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/nodedefs.h>
-#include <dspbridge/nodepriv.h>
-#include <dspbridge/rms_sh.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/disp.h>
-
-/* Size of a reply from RMS */
-#define REPLYSIZE (3 * sizeof(rms_word))
-
-/* Reserved channel offsets for communication with RMS */
-#define CHNLTORMSOFFSET 0
-#define CHNLFROMRMSOFFSET 1
-
-#define CHNLIOREQS 1
-
-/*
- * ======== disp_object ========
- */
-struct disp_object {
- struct dev_object *dev_obj; /* Device for this processor */
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
- struct chnl_mgr *chnl_mgr; /* Channel manager */
- struct chnl_object *chnl_to_dsp; /* Chnl for commands to RMS */
- struct chnl_object *chnl_from_dsp; /* Chnl for replies from RMS */
- u8 *buf; /* Buffer for commands, replies */
- u32 bufsize; /* buf size in bytes */
- u32 bufsize_rms; /* buf size in RMS words */
- u32 char_size; /* Size of DSP character */
- u32 word_size; /* Size of DSP word */
- u32 data_mau_size; /* Size of DSP Data MAU */
-};
-
-static void delete_disp(struct disp_object *disp_obj);
-static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
- struct node_strmdef strm_def, u32 max,
- u32 chars_in_rms_word);
-static int send_message(struct disp_object *disp_obj, u32 timeout,
- u32 ul_bytes, u32 *pdw_arg);
-
-/*
- * ======== disp_create ========
- * Create a NODE Dispatcher object.
- */
-int disp_create(struct disp_object **dispatch_obj,
- struct dev_object *hdev_obj,
- const struct disp_attr *disp_attrs)
-{
- struct disp_object *disp_obj;
- struct bridge_drv_interface *intf_fxns;
- u32 ul_chnl_id;
- struct chnl_attr chnl_attr_obj;
- int status = 0;
- u8 dev_type;
-
- *dispatch_obj = NULL;
-
- /* Allocate Node Dispatcher object */
- disp_obj = kzalloc(sizeof(struct disp_object), GFP_KERNEL);
- if (disp_obj == NULL)
- status = -ENOMEM;
- else
- disp_obj->dev_obj = hdev_obj;
-
- /* Get Channel manager and Bridge function interface */
- if (!status) {
- status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->chnl_mgr));
- if (!status) {
- (void)dev_get_intf_fxns(hdev_obj, &intf_fxns);
- disp_obj->intf_fxns = intf_fxns;
- }
- }
-
- /* check device type and decide if streams or messag'ing is used for
- * RMS/EDS */
- if (status)
- goto func_cont;
-
- status = dev_get_dev_type(hdev_obj, &dev_type);
-
- if (status)
- goto func_cont;
-
- if (dev_type != DSP_UNIT) {
- status = -EPERM;
- goto func_cont;
- }
-
- disp_obj->char_size = DSPWORDSIZE;
- disp_obj->word_size = DSPWORDSIZE;
- disp_obj->data_mau_size = DSPWORDSIZE;
- /* Open channels for communicating with the RMS */
- chnl_attr_obj.uio_reqs = CHNLIOREQS;
- chnl_attr_obj.event_obj = NULL;
- ul_chnl_id = disp_attrs->chnl_offset + CHNLTORMSOFFSET;
- status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp),
- disp_obj->chnl_mgr,
- CHNL_MODETODSP, ul_chnl_id,
- &chnl_attr_obj);
-
- if (!status) {
- ul_chnl_id = disp_attrs->chnl_offset + CHNLFROMRMSOFFSET;
- status =
- (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp),
- disp_obj->chnl_mgr,
- CHNL_MODEFROMDSP, ul_chnl_id,
- &chnl_attr_obj);
- }
- if (!status) {
- /* Allocate buffer for commands, replies */
- disp_obj->bufsize = disp_attrs->chnl_buf_size;
- disp_obj->bufsize_rms = RMS_COMMANDBUFSIZE;
- disp_obj->buf = kzalloc(disp_obj->bufsize, GFP_KERNEL);
- if (disp_obj->buf == NULL)
- status = -ENOMEM;
- }
-func_cont:
- if (!status)
- *dispatch_obj = disp_obj;
- else
- delete_disp(disp_obj);
-
- return status;
-}
-
-/*
- * ======== disp_delete ========
- * Delete the NODE Dispatcher.
- */
-void disp_delete(struct disp_object *disp_obj)
-{
- delete_disp(disp_obj);
-}
-
-/*
- * ======== disp_node_change_priority ========
- * Change the priority of a node currently running on the target.
- */
-int disp_node_change_priority(struct disp_object *disp_obj,
- struct node_object *hnode,
- u32 rms_fxn, nodeenv node_env, s32 prio)
-{
- u32 dw_arg;
- struct rms_command *rms_cmd;
- int status = 0;
-
- /* Send message to RMS to change priority */
- rms_cmd = (struct rms_command *)(disp_obj->buf);
- rms_cmd->fxn = (rms_word) (rms_fxn);
- rms_cmd->arg1 = (rms_word) node_env;
- rms_cmd->arg2 = prio;
- status = send_message(disp_obj, node_get_timeout(hnode),
- sizeof(struct rms_command), &dw_arg);
-
- return status;
-}
-
-/*
- * ======== disp_node_create ========
- * Create a node on the DSP by remotely calling the node's create function.
- */
-int disp_node_create(struct disp_object *disp_obj,
- struct node_object *hnode, u32 rms_fxn,
- u32 ul_create_fxn,
- const struct node_createargs *pargs,
- nodeenv *node_env)
-{
- struct node_msgargs node_msg_args;
- struct node_taskargs task_arg_obj;
- struct rms_command *rms_cmd;
- struct rms_msg_args *pmsg_args;
- struct rms_more_task_args *more_task_args;
- enum node_type node_type;
- u32 dw_length;
- rms_word *pdw_buf = NULL;
- u32 ul_bytes;
- u32 i;
- u32 total;
- u32 chars_in_rms_word;
- s32 task_args_offset;
- s32 sio_in_def_offset;
- s32 sio_out_def_offset;
- s32 sio_defs_offset;
- s32 args_offset = -1;
- s32 offset;
- struct node_strmdef strm_def;
- u32 max;
- int status = 0;
- struct dsp_nodeinfo node_info;
- u8 dev_type;
-
- status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
-
- if (status)
- goto func_end;
-
- if (dev_type != DSP_UNIT) {
- dev_dbg(bridge, "%s: unknown device type = 0x%x\n",
- __func__, dev_type);
- goto func_end;
- }
- node_type = node_get_type(hnode);
- node_msg_args = pargs->asa.node_msg_args;
- max = disp_obj->bufsize_rms; /*Max # of RMS words that can be sent */
- chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
- /* Number of RMS words needed to hold arg data */
- dw_length =
- (node_msg_args.arg_length + chars_in_rms_word -
- 1) / chars_in_rms_word;
- /* Make sure msg args and command fit in buffer */
- total = sizeof(struct rms_command) / sizeof(rms_word) +
- sizeof(struct rms_msg_args)
- / sizeof(rms_word) - 1 + dw_length;
- if (total >= max) {
- status = -EPERM;
- dev_dbg(bridge, "%s: Message args too large for buffer! size "
- "= %d, max = %d\n", __func__, total, max);
- }
- /*
- * Fill in buffer to send to RMS.
- * The buffer will have the following format:
- *
- * RMS command:
- * Address of RMS_CreateNode()
- * Address of node's create function
- * dummy argument
- * node type
- *
- * Message Args:
- * max number of messages
- * segid for message buffer allocation
- * notification type to use when message is received
- * length of message arg data
- * message args data
- *
- * Task Args (if task or socket node):
- * priority
- * stack size
- * system stack size
- * stack segment
- * misc
- * number of input streams
- * pSTRMInDef[] - offsets of STRM definitions for input streams
- * number of output streams
- * pSTRMOutDef[] - offsets of STRM definitions for output
- * streams
- * STRMInDef[] - array of STRM definitions for input streams
- * STRMOutDef[] - array of STRM definitions for output streams
- *
- * Socket Args (if DAIS socket node):
- *
- */
- if (!status) {
- total = 0; /* Total number of words in buffer so far */
- pdw_buf = (rms_word *) disp_obj->buf;
- rms_cmd = (struct rms_command *)pdw_buf;
- rms_cmd->fxn = (rms_word) (rms_fxn);
- rms_cmd->arg1 = (rms_word) (ul_create_fxn);
- if (node_get_load_type(hnode) == NLDR_DYNAMICLOAD) {
- /* Flush ICACHE on Load */
- rms_cmd->arg2 = 1; /* dummy argument */
- } else {
- /* Do not flush ICACHE */
- rms_cmd->arg2 = 0; /* dummy argument */
- }
- rms_cmd->data = node_get_type(hnode);
- /*
- * args_offset is the offset of the data field in struct
- * rms_command structure. We need this to calculate stream
- * definition offsets.
- */
- args_offset = 3;
- total += sizeof(struct rms_command) / sizeof(rms_word);
- /* Message args */
- pmsg_args = (struct rms_msg_args *)(pdw_buf + total);
- pmsg_args->max_msgs = node_msg_args.max_msgs;
- pmsg_args->segid = node_msg_args.seg_id;
- pmsg_args->notify_type = node_msg_args.notify_type;
- pmsg_args->arg_length = node_msg_args.arg_length;
- total += sizeof(struct rms_msg_args) / sizeof(rms_word) - 1;
- memcpy(pdw_buf + total, node_msg_args.pdata,
- node_msg_args.arg_length);
- total += dw_length;
- }
- if (status)
- goto func_end;
-
- /* If node is a task node, copy task create arguments into buffer */
- if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
- task_arg_obj = pargs->asa.task_arg_obj;
- task_args_offset = total;
- total += sizeof(struct rms_more_task_args) / sizeof(rms_word) +
- 1 + task_arg_obj.num_inputs + task_arg_obj.num_outputs;
- /* Copy task arguments */
- if (total < max) {
- total = task_args_offset;
- more_task_args = (struct rms_more_task_args *)(pdw_buf +
- total);
- /*
- * Get some important info about the node. Note that we
- * don't just reach into the hnode struct because
- * that would break the node object's abstraction.
- */
- get_node_info(hnode, &node_info);
- more_task_args->priority = node_info.execution_priority;
- more_task_args->stack_size = task_arg_obj.stack_size;
- more_task_args->sysstack_size =
- task_arg_obj.sys_stack_size;
- more_task_args->stack_seg = task_arg_obj.stack_seg;
- more_task_args->heap_addr = task_arg_obj.dsp_heap_addr;
- more_task_args->heap_size = task_arg_obj.heap_size;
- more_task_args->misc = task_arg_obj.dais_arg;
- more_task_args->num_input_streams =
- task_arg_obj.num_inputs;
- total +=
- sizeof(struct rms_more_task_args) /
- sizeof(rms_word);
- dev_dbg(bridge, "%s: dsp_heap_addr %x, heap_size %x\n",
- __func__, task_arg_obj.dsp_heap_addr,
- task_arg_obj.heap_size);
- /* Keep track of pSIOInDef[] and pSIOOutDef[]
- * positions in the buffer, since this needs to be
- * filled in later. */
- sio_in_def_offset = total;
- total += task_arg_obj.num_inputs;
- pdw_buf[total++] = task_arg_obj.num_outputs;
- sio_out_def_offset = total;
- total += task_arg_obj.num_outputs;
- sio_defs_offset = total;
- /* Fill SIO defs and offsets */
- offset = sio_defs_offset;
- for (i = 0; i < task_arg_obj.num_inputs; i++) {
- if (status)
- break;
-
- pdw_buf[sio_in_def_offset + i] =
- (offset - args_offset)
- * (sizeof(rms_word) / DSPWORDSIZE);
- strm_def = task_arg_obj.strm_in_def[i];
- status =
- fill_stream_def(pdw_buf, &total, offset,
- strm_def, max,
- chars_in_rms_word);
- offset = total;
- }
- for (i = 0; (i < task_arg_obj.num_outputs) &&
- (!status); i++) {
- pdw_buf[sio_out_def_offset + i] =
- (offset - args_offset)
- * (sizeof(rms_word) / DSPWORDSIZE);
- strm_def = task_arg_obj.strm_out_def[i];
- status =
- fill_stream_def(pdw_buf, &total, offset,
- strm_def, max,
- chars_in_rms_word);
- offset = total;
- }
- } else {
- /* Args won't fit */
- status = -EPERM;
- }
- }
- if (!status) {
- ul_bytes = total * sizeof(rms_word);
- status = send_message(disp_obj, node_get_timeout(hnode),
- ul_bytes, node_env);
- }
-func_end:
- return status;
-}
-
-/*
- * ======== disp_node_delete ========
- * purpose:
- * Delete a node on the DSP by remotely calling the node's delete function.
- *
- */
-int disp_node_delete(struct disp_object *disp_obj,
- struct node_object *hnode, u32 rms_fxn,
- u32 ul_delete_fxn, nodeenv node_env)
-{
- u32 dw_arg;
- struct rms_command *rms_cmd;
- int status = 0;
- u8 dev_type;
-
- status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
-
- if (!status) {
-
- if (dev_type == DSP_UNIT) {
-
- /*
- * Fill in buffer to send to RMS
- */
- rms_cmd = (struct rms_command *)disp_obj->buf;
- rms_cmd->fxn = (rms_word) (rms_fxn);
- rms_cmd->arg1 = (rms_word) node_env;
- rms_cmd->arg2 = (rms_word) (ul_delete_fxn);
- rms_cmd->data = node_get_type(hnode);
-
- status = send_message(disp_obj, node_get_timeout(hnode),
- sizeof(struct rms_command),
- &dw_arg);
- }
- }
- return status;
-}
-
-/*
- * ======== disp_node_run ========
- * purpose:
- * Start execution of a node's execute phase, or resume execution of a node
- * that has been suspended (via DISP_NodePause()) on the DSP.
- */
-int disp_node_run(struct disp_object *disp_obj,
- struct node_object *hnode, u32 rms_fxn,
- u32 ul_execute_fxn, nodeenv node_env)
-{
- u32 dw_arg;
- struct rms_command *rms_cmd;
- int status = 0;
- u8 dev_type;
-
- status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
-
- if (!status) {
-
- if (dev_type == DSP_UNIT) {
-
- /*
- * Fill in buffer to send to RMS.
- */
- rms_cmd = (struct rms_command *)disp_obj->buf;
- rms_cmd->fxn = (rms_word) (rms_fxn);
- rms_cmd->arg1 = (rms_word) node_env;
- rms_cmd->arg2 = (rms_word) (ul_execute_fxn);
- rms_cmd->data = node_get_type(hnode);
-
- status = send_message(disp_obj, node_get_timeout(hnode),
- sizeof(struct rms_command),
- &dw_arg);
- }
- }
-
- return status;
-}
-
-/*
- * ======== delete_disp ========
- * purpose:
- * Frees the resources allocated for the dispatcher.
- */
-static void delete_disp(struct disp_object *disp_obj)
-{
- int status = 0;
- struct bridge_drv_interface *intf_fxns;
-
- if (disp_obj) {
- intf_fxns = disp_obj->intf_fxns;
-
- /* Free Node Dispatcher resources */
- if (disp_obj->chnl_from_dsp) {
- /* Channel close can fail only if the channel handle
- * is invalid. */
- status = (*intf_fxns->chnl_close)
- (disp_obj->chnl_from_dsp);
- if (status) {
- dev_dbg(bridge, "%s: Failed to close channel "
- "from RMS: 0x%x\n", __func__, status);
- }
- }
- if (disp_obj->chnl_to_dsp) {
- status =
- (*intf_fxns->chnl_close) (disp_obj->
- chnl_to_dsp);
- if (status) {
- dev_dbg(bridge, "%s: Failed to close channel to"
- " RMS: 0x%x\n", __func__, status);
- }
- }
- kfree(disp_obj->buf);
-
- kfree(disp_obj);
- }
-}
-
-/*
- * ======== fill_stream_def ========
- * purpose:
- * Fills stream definitions.
- */
-static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
- struct node_strmdef strm_def, u32 max,
- u32 chars_in_rms_word)
-{
- struct rms_strm_def *strm_def_obj;
- u32 total = *ptotal;
- u32 name_len;
- u32 dw_length;
- int status = 0;
-
- if (total + sizeof(struct rms_strm_def) / sizeof(rms_word) >= max) {
- status = -EPERM;
- } else {
- strm_def_obj = (struct rms_strm_def *)(pdw_buf + total);
- strm_def_obj->bufsize = strm_def.buf_size;
- strm_def_obj->nbufs = strm_def.num_bufs;
- strm_def_obj->segid = strm_def.seg_id;
- strm_def_obj->align = strm_def.buf_alignment;
- strm_def_obj->timeout = strm_def.timeout;
- }
-
- if (!status) {
- /*
- * Since we haven't added the device name yet, subtract
- * 1 from total.
- */
- total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1;
- dw_length = strlen(strm_def.sz_device) + 1;
-
- /* Number of RMS_WORDS needed to hold device name */
- name_len =
- (dw_length + chars_in_rms_word - 1) / chars_in_rms_word;
-
- if (total + name_len >= max) {
- status = -EPERM;
- } else {
- /*
- * Zero out last word, since the device name may not
- * extend to completely fill this word.
- */
- pdw_buf[total + name_len - 1] = 0;
- /** TODO USE SERVICES * */
- memcpy(pdw_buf + total, strm_def.sz_device, dw_length);
- total += name_len;
- *ptotal = total;
- }
- }
-
- return status;
-}
-
-/*
- * ======== send_message ======
- * Send command message to RMS, get reply from RMS.
- */
-static int send_message(struct disp_object *disp_obj, u32 timeout,
- u32 ul_bytes, u32 *pdw_arg)
-{
- struct bridge_drv_interface *intf_fxns;
- struct chnl_object *chnl_obj;
- u32 dw_arg = 0;
- u8 *pbuf;
- struct chnl_ioc chnl_ioc_obj;
- int status = 0;
-
- *pdw_arg = (u32) NULL;
- intf_fxns = disp_obj->intf_fxns;
- chnl_obj = disp_obj->chnl_to_dsp;
- pbuf = disp_obj->buf;
-
- /* Send the command */
- status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0,
- 0L, dw_arg);
- if (status)
- goto func_end;
-
- status =
- (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
- if (!status) {
- if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
- if (CHNL_IS_TIMED_OUT(chnl_ioc_obj))
- status = -ETIME;
- else
- status = -EPERM;
- }
- }
- /* Get the reply */
- if (status)
- goto func_end;
-
- chnl_obj = disp_obj->chnl_from_dsp;
- ul_bytes = REPLYSIZE;
- status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes,
- 0, 0L, dw_arg);
- if (status)
- goto func_end;
-
- status =
- (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
- if (!status) {
- if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
- status = -ETIME;
- } else if (chnl_ioc_obj.byte_size < ul_bytes) {
- /* Did not get all of the reply from the RMS */
- status = -EPERM;
- } else {
- if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
- if (*((int *)chnl_ioc_obj.buf) < 0) {
- /* Translate DSP's to kernel error */
- status = -EREMOTEIO;
- dev_dbg(bridge, "%s: DSP-side failed:"
- " DSP errcode = 0x%x, Kernel "
- "errcode = %d\n", __func__,
- *(int *)pbuf, status);
- }
- *pdw_arg =
- (((rms_word *) (chnl_ioc_obj.buf))[1]);
- } else {
- status = -EPERM;
- }
- }
- }
-func_end:
- return status;
-}
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
deleted file mode 100644
index 757ae20b38ee..000000000000
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * drv.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge resource allocation module.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/types.h>
-#include <linux/list.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/drv.h>
-#include <dspbridge/dev.h>
-
-#include <dspbridge/node.h>
-#include <dspbridge/proc.h>
-#include <dspbridge/strm.h>
-#include <dspbridge/nodepriv.h>
-#include <dspbridge/dspchnl.h>
-#include <dspbridge/resourcecleanup.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-struct drv_object {
- struct list_head dev_list;
- struct list_head dev_node_string;
-};
-
-/*
- * This is the Device Extension. Named with the Prefix
- * DRV_ since it is living in this module
- */
-struct drv_ext {
- struct list_head link;
- char sz_string[MAXREGPATHLENGTH];
-};
-
-/* ----------------------------------- Globals */
-static bool ext_phys_mem_pool_enabled;
-struct ext_phys_mem_pool {
- u32 phys_mem_base;
- u32 phys_mem_size;
- u32 virt_mem_base;
- u32 next_phys_alloc_ptr;
-};
-static struct ext_phys_mem_pool ext_mem_pool;
-
-/* ----------------------------------- Function Prototypes */
-static int request_bridge_resources(struct cfg_hostres *res);
-
-
-/* GPP PROCESS CLEANUP CODE */
-
-static int drv_proc_free_node_res(int id, void *p, void *data);
-
-/* Allocate and add a node resource element
-* This function is called from .Node_Allocate. */
-int drv_insert_node_res_element(void *hnode, void *node_resource,
- void *process_ctxt)
-{
- struct node_res_object **node_res_obj =
- (struct node_res_object **)node_resource;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int retval;
-
- *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
- if (!*node_res_obj)
- return -ENOMEM;
-
- (*node_res_obj)->node = hnode;
- retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL);
- if (retval >= 0) {
- (*node_res_obj)->id = retval;
- return 0;
- }
-
- kfree(*node_res_obj);
-
- if (retval == -ENOSPC) {
- pr_err("%s: FAILED, IDR is FULL\n", __func__);
- return -EFAULT;
- } else {
- pr_err("%s: OUT OF MEMORY\n", __func__);
- return -ENOMEM;
- }
-}
-
-/* Release all Node resources and its context
- * Actual Node De-Allocation */
-static int drv_proc_free_node_res(int id, void *p, void *data)
-{
- struct process_context *ctxt = data;
- int status;
- struct node_res_object *node_res_obj = p;
- u32 node_state;
-
- if (node_res_obj->node_allocated) {
- node_state = node_get_state(node_res_obj->node);
- if (node_state <= NODE_DELETING) {
- if ((node_state == NODE_RUNNING) ||
- (node_state == NODE_PAUSED) ||
- (node_state == NODE_TERMINATING))
- node_terminate
- (node_res_obj->node, &status);
-
- node_delete(node_res_obj, ctxt);
- }
- }
-
- return 0;
-}
-
-/* Release all Mapped and Reserved DMM resources */
-int drv_remove_all_dmm_res_elements(void *process_ctxt)
-{
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct dmm_map_object *temp_map, *map_obj;
- struct dmm_rsv_object *temp_rsv, *rsv_obj;
-
- /* Free DMM mapped memory resources */
- list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) {
- status = proc_un_map(ctxt->processor,
- (void *)map_obj->dsp_addr, ctxt);
- if (status)
- pr_err("%s: proc_un_map failed!"
- " status = 0x%xn", __func__, status);
- }
-
- /* Free DMM reserved memory resources */
- list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) {
- status = proc_un_reserve_memory(ctxt->processor, (void *)
- rsv_obj->dsp_reserved_addr,
- ctxt);
- if (status)
- pr_err("%s: proc_un_reserve_memory failed!"
- " status = 0x%xn", __func__, status);
- }
- return status;
-}
-
-/* Update Node allocation status */
-void drv_proc_node_update_status(void *node_resource, s32 status)
-{
- struct node_res_object *node_res_obj =
- (struct node_res_object *)node_resource;
- node_res_obj->node_allocated = status;
-}
-
-/* Update Node Heap status */
-void drv_proc_node_update_heap_status(void *node_resource, s32 status)
-{
- struct node_res_object *node_res_obj =
- (struct node_res_object *)node_resource;
- node_res_obj->heap_allocated = status;
-}
-
-/* Release all Node resources and its context
-* This is called from .bridge_release.
- */
-int drv_remove_all_node_res_elements(void *process_ctxt)
-{
- struct process_context *ctxt = process_ctxt;
-
- idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt);
- idr_destroy(ctxt->node_id);
-
- return 0;
-}
-
-/* Allocate the STRM resource element
-* This is called after the actual resource is allocated
- */
-int drv_proc_insert_strm_res_element(void *stream_obj,
- void *strm_res, void *process_ctxt)
-{
- struct strm_res_object **pstrm_res =
- (struct strm_res_object **)strm_res;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int retval;
-
- *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
- if (*pstrm_res == NULL)
- return -EFAULT;
-
- (*pstrm_res)->stream = stream_obj;
- retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL);
- if (retval >= 0) {
- (*pstrm_res)->id = retval;
- return 0;
- }
-
- if (retval == -ENOSPC) {
- pr_err("%s: FAILED, IDR is FULL\n", __func__);
- return -EPERM;
- } else {
- pr_err("%s: OUT OF MEMORY\n", __func__);
- return -ENOMEM;
- }
-}
-
-static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
-{
- struct process_context *ctxt = process_ctxt;
- struct strm_res_object *strm_res = p;
- struct stream_info strm_info;
- struct dsp_streaminfo user;
- u8 **ap_buffer = NULL;
- u8 *buf_ptr;
- u32 ul_bytes;
- u32 dw_arg;
- s32 ul_buf_size;
-
- if (strm_res->num_bufs) {
- ap_buffer = kmalloc((strm_res->num_bufs *
- sizeof(u8 *)), GFP_KERNEL);
- if (ap_buffer) {
- strm_free_buffer(strm_res,
- ap_buffer,
- strm_res->num_bufs,
- ctxt);
- kfree(ap_buffer);
- }
- }
- strm_info.user_strm = &user;
- user.number_bufs_in_stream = 0;
- strm_get_info(strm_res->stream, &strm_info, sizeof(strm_info));
- while (user.number_bufs_in_stream--)
- strm_reclaim(strm_res->stream, &buf_ptr, &ul_bytes,
- (u32 *) &ul_buf_size, &dw_arg);
- strm_close(strm_res, ctxt);
- return 0;
-}
-
-/* Release all Stream resources and its context
-* This is called from .bridge_release.
- */
-int drv_remove_all_strm_res_elements(void *process_ctxt)
-{
- struct process_context *ctxt = process_ctxt;
-
- idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt);
- idr_destroy(ctxt->stream_id);
-
- return 0;
-}
-
-/* Updating the stream resource element */
-int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources)
-{
- int status = 0;
- struct strm_res_object **strm_res =
- (struct strm_res_object **)strm_resources;
-
- (*strm_res)->num_bufs = num_bufs;
- return status;
-}
-
-/* GPP PROCESS CLEANUP CODE END */
-
-/*
- * ======== = drv_create ======== =
- * Purpose:
- * DRV Object gets created only once during Driver Loading.
- */
-int drv_create(struct drv_object **drv_obj)
-{
- int status = 0;
- struct drv_object *pdrv_object = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL);
- if (pdrv_object) {
- /* Create and Initialize List of device objects */
- INIT_LIST_HEAD(&pdrv_object->dev_list);
- INIT_LIST_HEAD(&pdrv_object->dev_node_string);
- } else {
- status = -ENOMEM;
- }
- /* Store the DRV Object in the driver data */
- if (!status) {
- if (drv_datap) {
- drv_datap->drv_object = (void *)pdrv_object;
- } else {
- status = -EPERM;
- pr_err("%s: Failed to store DRV object\n", __func__);
- }
- }
-
- if (!status) {
- *drv_obj = pdrv_object;
- } else {
- /* Free the DRV Object */
- kfree(pdrv_object);
- }
-
- return status;
-}
-
-/*
- * ======== = drv_destroy ======== =
- * purpose:
- * Invoked during bridge de-initialization
- */
-int drv_destroy(struct drv_object *driver_obj)
-{
- int status = 0;
- struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- kfree(pdrv_object);
- /* Update the DRV Object in the driver data */
- if (drv_datap) {
- drv_datap->drv_object = NULL;
- } else {
- status = -EPERM;
- pr_err("%s: Failed to store DRV object\n", __func__);
- }
-
- return status;
-}
-
-/*
- * ======== drv_get_dev_object ========
- * Purpose:
- * Given a index, returns a handle to DevObject from the list.
- */
-int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj,
- struct dev_object **device_obj)
-{
- int status = 0;
- struct dev_object *dev_obj;
- u32 i;
-
- dev_obj = (struct dev_object *)drv_get_first_dev_object();
- for (i = 0; i < index; i++) {
- dev_obj =
- (struct dev_object *)drv_get_next_dev_object((u32) dev_obj);
- }
- if (dev_obj) {
- *device_obj = (struct dev_object *)dev_obj;
- } else {
- *device_obj = NULL;
- status = -EPERM;
- }
-
- return status;
-}
-
-/*
- * ======== drv_get_first_dev_object ========
- * Purpose:
- * Retrieve the first Device Object handle from an internal linked list of
- * of DEV_OBJECTs maintained by DRV.
- */
-u32 drv_get_first_dev_object(void)
-{
- u32 dw_dev_object = 0;
- struct drv_object *pdrv_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (drv_datap && drv_datap->drv_object) {
- pdrv_obj = drv_datap->drv_object;
- if (!list_empty(&pdrv_obj->dev_list))
- dw_dev_object = (u32) pdrv_obj->dev_list.next;
- } else {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- return dw_dev_object;
-}
-
-/*
- * ======== DRV_GetFirstDevNodeString ========
- * Purpose:
- * Retrieve the first Device Extension from an internal linked list of
- * of Pointer to dev_node Strings maintained by DRV.
- */
-u32 drv_get_first_dev_extension(void)
-{
- u32 dw_dev_extension = 0;
- struct drv_object *pdrv_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- if (drv_datap && drv_datap->drv_object) {
- pdrv_obj = drv_datap->drv_object;
- if (!list_empty(&pdrv_obj->dev_node_string)) {
- dw_dev_extension =
- (u32) pdrv_obj->dev_node_string.next;
- }
- } else {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- return dw_dev_extension;
-}
-
-/*
- * ======== drv_get_next_dev_object ========
- * Purpose:
- * Retrieve the next Device Object handle from an internal linked list of
- * of DEV_OBJECTs maintained by DRV, after having previously called
- * drv_get_first_dev_object() and zero or more DRV_GetNext.
- */
-u32 drv_get_next_dev_object(u32 hdev_obj)
-{
- u32 dw_next_dev_object = 0;
- struct drv_object *pdrv_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- struct list_head *curr;
-
- if (drv_datap && drv_datap->drv_object) {
- pdrv_obj = drv_datap->drv_object;
- if (!list_empty(&pdrv_obj->dev_list)) {
- curr = (struct list_head *)hdev_obj;
- if (list_is_last(curr, &pdrv_obj->dev_list))
- return 0;
- dw_next_dev_object = (u32) curr->next;
- }
- } else {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- return dw_next_dev_object;
-}
-
-/*
- * ======== drv_get_next_dev_extension ========
- * Purpose:
- * Retrieve the next Device Extension from an internal linked list of
- * of pointer to DevNodeString maintained by DRV, after having previously
- * called drv_get_first_dev_extension() and zero or more
- * drv_get_next_dev_extension().
- */
-u32 drv_get_next_dev_extension(u32 dev_extension)
-{
- u32 dw_dev_extension = 0;
- struct drv_object *pdrv_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- struct list_head *curr;
-
- if (drv_datap && drv_datap->drv_object) {
- pdrv_obj = drv_datap->drv_object;
- if (!list_empty(&pdrv_obj->dev_node_string)) {
- curr = (struct list_head *)dev_extension;
- if (list_is_last(curr, &pdrv_obj->dev_node_string))
- return 0;
- dw_dev_extension = (u32) curr->next;
- }
- } else {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- return dw_dev_extension;
-}
-
-/*
- * ======== drv_insert_dev_object ========
- * Purpose:
- * Insert a DevObject into the list of Manager object.
- */
-int drv_insert_dev_object(struct drv_object *driver_obj,
- struct dev_object *hdev_obj)
-{
- struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
-
- list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list);
-
- return 0;
-}
-
-/*
- * ======== drv_remove_dev_object ========
- * Purpose:
- * Search for and remove a DeviceObject from the given list of DRV
- * objects.
- */
-int drv_remove_dev_object(struct drv_object *driver_obj,
- struct dev_object *hdev_obj)
-{
- int status = -EPERM;
- struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
- struct list_head *cur_elem;
-
- /* Search list for p_proc_object: */
- list_for_each(cur_elem, &pdrv_object->dev_list) {
- /* If found, remove it. */
- if ((struct dev_object *)cur_elem == hdev_obj) {
- list_del(cur_elem);
- status = 0;
- break;
- }
- }
-
- return status;
-}
-
-/*
- * ======== drv_request_resources ========
- * Purpose:
- * Requests resources from the OS.
- */
-int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
-{
- int status = 0;
- struct drv_object *pdrv_object;
- struct drv_ext *pszdev_node;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /*
- * Allocate memory to hold the string. This will live until
- * it is freed in the Release resources. Update the driver object
- * list.
- */
-
- if (!drv_datap || !drv_datap->drv_object)
- status = -ENODATA;
- else
- pdrv_object = drv_datap->drv_object;
-
- if (!status) {
- pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL);
- if (pszdev_node) {
- strncpy(pszdev_node->sz_string,
- (char *)dw_context, MAXREGPATHLENGTH - 1);
- pszdev_node->sz_string[MAXREGPATHLENGTH - 1] = '\0';
- /* Update the Driver Object List */
- *dev_node_strg = (u32) pszdev_node->sz_string;
- list_add_tail(&pszdev_node->link,
- &pdrv_object->dev_node_string);
- } else {
- status = -ENOMEM;
- *dev_node_strg = 0;
- }
- } else {
- dev_dbg(bridge, "%s: Failed to get Driver Object from Registry",
- __func__);
- *dev_node_strg = 0;
- }
-
- return status;
-}
-
-/*
- * ======== drv_release_resources ========
- * Purpose:
- * Releases resources from the OS.
- */
-int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj)
-{
- int status = 0;
- struct drv_ext *pszdev_node;
-
- /*
- * Irrespective of the status go ahead and clean it
- * The following will over write the status.
- */
- for (pszdev_node = (struct drv_ext *)drv_get_first_dev_extension();
- pszdev_node != NULL; pszdev_node = (struct drv_ext *)
- drv_get_next_dev_extension((u32) pszdev_node)) {
- if ((u32) pszdev_node == dw_context) {
- /* Found it */
- /* Delete from the Driver object list */
- list_del(&pszdev_node->link);
- kfree(pszdev_node);
- break;
- }
- }
- return status;
-}
-
-/*
- * ======== request_bridge_resources ========
- * Purpose:
- * Reserves shared memory for bridge.
- */
-static int request_bridge_resources(struct cfg_hostres *res)
-{
- struct cfg_hostres *host_res = res;
-
- /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
- host_res->num_mem_windows = 2;
-
- /* First window is for DSP internal memory */
- dev_dbg(bridge, "mem_base[0] 0x%x\n", host_res->mem_base[0]);
- dev_dbg(bridge, "mem_base[3] 0x%x\n", host_res->mem_base[3]);
- dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);
-
- /* for 24xx base port is not mapping the mamory for DSP
- * internal memory TODO Do a ioremap here */
- /* Second window is for DSP external memory shared with MPU */
-
- /* These are hard-coded values */
- host_res->birq_registers = 0;
- host_res->birq_attrib = 0;
- host_res->offset_for_monitor = 0;
- host_res->chnl_offset = 0;
- /* CHNL_MAXCHANNELS */
- host_res->num_chnls = CHNL_MAXCHANNELS;
- host_res->chnl_buf_size = 0x400;
-
- return 0;
-}
-
-/*
- * ======== drv_request_bridge_res_dsp ========
- * Purpose:
- * Reserves shared memory for bridge.
- */
-int drv_request_bridge_res_dsp(void **phost_resources)
-{
- int status = 0;
- struct cfg_hostres *host_res;
- u32 dw_buff_size;
- u32 dma_addr;
- u32 shm_size;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- dw_buff_size = sizeof(struct cfg_hostres);
-
- host_res = kzalloc(dw_buff_size, GFP_KERNEL);
-
- if (host_res != NULL) {
- request_bridge_resources(host_res);
- /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
- host_res->num_mem_windows = 4;
-
- host_res->mem_base[0] = 0;
- host_res->mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE,
- OMAP_DSP_MEM1_SIZE);
- host_res->mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE,
- OMAP_DSP_MEM2_SIZE);
- host_res->mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE,
- OMAP_DSP_MEM3_SIZE);
- host_res->per_base = ioremap(OMAP_PER_CM_BASE,
- OMAP_PER_CM_SIZE);
- host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE,
- OMAP_PER_PRM_SIZE);
- host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE,
- OMAP_CORE_PRM_SIZE);
- host_res->dmmu_base = ioremap(OMAP_DMMU_BASE,
- OMAP_DMMU_SIZE);
-
- dev_dbg(bridge, "mem_base[0] 0x%x\n",
- host_res->mem_base[0]);
- dev_dbg(bridge, "mem_base[1] 0x%x\n",
- host_res->mem_base[1]);
- dev_dbg(bridge, "mem_base[2] 0x%x\n",
- host_res->mem_base[2]);
- dev_dbg(bridge, "mem_base[3] 0x%x\n",
- host_res->mem_base[3]);
- dev_dbg(bridge, "mem_base[4] 0x%x\n",
- host_res->mem_base[4]);
- dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);
-
- shm_size = drv_datap->shm_size;
- if (shm_size >= 0x10000) {
- /* Allocate Physically contiguous,
- * non-cacheable memory */
- host_res->mem_base[1] =
- (u32) mem_alloc_phys_mem(shm_size, 0x100000,
- &dma_addr);
- if (host_res->mem_base[1] == 0) {
- status = -ENOMEM;
- pr_err("shm reservation Failed\n");
- } else {
- host_res->mem_length[1] = shm_size;
- host_res->mem_phys[1] = dma_addr;
-
- dev_dbg(bridge, "%s: Bridge shm address 0x%x "
- "dma_addr %x size %x\n", __func__,
- host_res->mem_base[1],
- dma_addr, shm_size);
- }
- }
- if (!status) {
- /* These are hard-coded values */
- host_res->birq_registers = 0;
- host_res->birq_attrib = 0;
- host_res->offset_for_monitor = 0;
- host_res->chnl_offset = 0;
- /* CHNL_MAXCHANNELS */
- host_res->num_chnls = CHNL_MAXCHANNELS;
- host_res->chnl_buf_size = 0x400;
- dw_buff_size = sizeof(struct cfg_hostres);
- }
- *phost_resources = host_res;
- }
- /* End Mem alloc */
- return status;
-}
-
-void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size)
-{
- u32 pool_virt_base;
-
- /* get the virtual address for the physical memory pool passed */
- pool_virt_base = (u32) ioremap(pool_phys_base, pool_size);
-
- if ((void **)pool_virt_base == NULL) {
- pr_err("%s: external physical memory map failed\n", __func__);
- ext_phys_mem_pool_enabled = false;
- } else {
- ext_mem_pool.phys_mem_base = pool_phys_base;
- ext_mem_pool.phys_mem_size = pool_size;
- ext_mem_pool.virt_mem_base = pool_virt_base;
- ext_mem_pool.next_phys_alloc_ptr = pool_phys_base;
- ext_phys_mem_pool_enabled = true;
- }
-}
-
-void mem_ext_phys_pool_release(void)
-{
- if (ext_phys_mem_pool_enabled) {
- iounmap((void *)(ext_mem_pool.virt_mem_base));
- ext_phys_mem_pool_enabled = false;
- }
-}
-
-/*
- * ======== mem_ext_phys_mem_alloc ========
- * Purpose:
- * Allocate physically contiguous, uncached memory from external memory pool
- */
-
-static void *mem_ext_phys_mem_alloc(u32 bytes, u32 align, u32 *phys_addr)
-{
- u32 new_alloc_ptr;
- u32 offset;
- u32 virt_addr;
-
- if (align == 0)
- align = 1;
-
- if (bytes > ((ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)
- - ext_mem_pool.next_phys_alloc_ptr)) {
- phys_addr = NULL;
- return NULL;
- } else {
- offset = (ext_mem_pool.next_phys_alloc_ptr & (align - 1));
- if (offset == 0)
- new_alloc_ptr = ext_mem_pool.next_phys_alloc_ptr;
- else
- new_alloc_ptr = (ext_mem_pool.next_phys_alloc_ptr) +
- (align - offset);
- if ((new_alloc_ptr + bytes) <=
- (ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)) {
- /* we can allocate */
- *phys_addr = new_alloc_ptr;
- ext_mem_pool.next_phys_alloc_ptr =
- new_alloc_ptr + bytes;
- virt_addr =
- ext_mem_pool.virt_mem_base + (new_alloc_ptr -
- ext_mem_pool.
- phys_mem_base);
- return (void *)virt_addr;
- } else {
- *phys_addr = 0;
- return NULL;
- }
- }
-}
-
-/*
- * ======== mem_alloc_phys_mem ========
- * Purpose:
- * Allocate physically contiguous, uncached memory
- */
-void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask,
- u32 *physical_address)
-{
- void *va_mem = NULL;
- dma_addr_t pa_mem;
-
- if (byte_size > 0) {
- if (ext_phys_mem_pool_enabled) {
- va_mem = mem_ext_phys_mem_alloc(byte_size, align_mask,
- (u32 *) &pa_mem);
- } else
- va_mem = dma_alloc_coherent(NULL, byte_size, &pa_mem,
- GFP_KERNEL);
- if (va_mem == NULL)
- *physical_address = 0;
- else
- *physical_address = pa_mem;
- }
- return va_mem;
-}
-
-/*
- * ======== mem_free_phys_mem ========
- * Purpose:
- * Free the given block of physically contiguous memory.
- */
-void mem_free_phys_mem(void *virtual_address, u32 physical_address,
- u32 byte_size)
-{
- if (!ext_phys_mem_pool_enabled)
- dma_free_coherent(NULL, byte_size, virtual_address,
- physical_address);
-}
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
deleted file mode 100644
index 74d31dabe832..000000000000
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * drv_interface.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge driver interface.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/platform_data/dsp-omap.h>
-
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/pm.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/moduleparam.h>
-#include <linux/cdev.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/clk.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dspapi.h>
-#include <dspbridge/dspdrv.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/pwr.h>
-
-#include <dspbridge/resourcecleanup.h>
-#include <dspbridge/proc.h>
-#include <dspbridge/dev.h>
-
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
-#include <mach-omap2/omap3-opp.h>
-#endif
-
-/* ----------------------------------- Globals */
-#define DSPBRIDGE_VERSION "0.3"
-s32 dsp_debug;
-
-struct platform_device *omap_dspbridge_dev;
-struct device *bridge;
-
-/* This is a test variable used by Bridge to test different sleep states */
-s32 dsp_test_sleepstate;
-
-static struct cdev bridge_cdev;
-
-static struct class *bridge_class;
-
-static u32 driver_context;
-static s32 driver_major;
-static char *base_img;
-static s32 shm_size = 0x500000; /* 5 MB */
-static int tc_wordswapon; /* Default value is always false */
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-#define REC_TIMEOUT 5000 /*recovery timeout in msecs */
-static atomic_t bridge_cref; /* number of bridge open handles */
-static struct workqueue_struct *bridge_rec_queue;
-static struct work_struct bridge_recovery_work;
-static DECLARE_COMPLETION(bridge_comp);
-static DECLARE_COMPLETION(bridge_open_comp);
-static bool recover;
-#endif
-
-#ifdef CONFIG_PM
-struct omap34_xx_bridge_suspend_data {
- int suspended;
- wait_queue_head_t suspend_wq;
-};
-
-static struct omap34_xx_bridge_suspend_data bridge_suspend_data;
-
-static int omap34_xxbridge_suspend_lockout(struct omap34_xx_bridge_suspend_data
- *s, struct file *f)
-{
- if ((s)->suspended) {
- if ((f)->f_flags & O_NONBLOCK)
- return -EPERM;
- wait_event_interruptible((s)->suspend_wq, (s)->suspended == 0);
- }
- return 0;
-}
-#endif
-
-module_param(dsp_debug, int, 0);
-MODULE_PARM_DESC(dsp_debug, "Wait after loading DSP image. default = false");
-
-module_param(dsp_test_sleepstate, int, 0);
-MODULE_PARM_DESC(dsp_test_sleepstate, "DSP Sleep state = 0");
-
-module_param(base_img, charp, 0);
-MODULE_PARM_DESC(base_img, "DSP base image, default = NULL");
-
-module_param(shm_size, int, 0);
-MODULE_PARM_DESC(shm_size, "shm size, default = 4 MB, minimum = 64 KB");
-
-module_param(tc_wordswapon, int, 0);
-MODULE_PARM_DESC(tc_wordswapon, "TC Word Swap Option. default = 0");
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DSPBRIDGE_VERSION);
-
-/*
- * This function is called when an application opens handle to the
- * bridge driver.
- */
-static int bridge_open(struct inode *ip, struct file *filp)
-{
- int status = 0;
- struct process_context *pr_ctxt = NULL;
-
- /*
- * Allocate a new process context and insert it into global
- * process context list.
- */
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- if (recover) {
- if (filp->f_flags & O_NONBLOCK ||
- wait_for_completion_interruptible(&bridge_open_comp))
- return -EBUSY;
- }
-#endif
- pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
- if (!pr_ctxt)
- return -ENOMEM;
-
- pr_ctxt->res_state = PROC_RES_ALLOCATED;
- spin_lock_init(&pr_ctxt->dmm_map_lock);
- INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
- spin_lock_init(&pr_ctxt->dmm_rsv_lock);
- INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
-
- pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
- if (!pr_ctxt->node_id) {
- status = -ENOMEM;
- goto err1;
- }
-
- idr_init(pr_ctxt->node_id);
-
- pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
- if (!pr_ctxt->stream_id) {
- status = -ENOMEM;
- goto err2;
- }
-
- idr_init(pr_ctxt->stream_id);
-
- filp->private_data = pr_ctxt;
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- atomic_inc(&bridge_cref);
-#endif
- return 0;
-
-err2:
- kfree(pr_ctxt->node_id);
-err1:
- kfree(pr_ctxt);
- return status;
-}
-
-/*
- * This function is called when an application closes handle to the bridge
- * driver.
- */
-static int bridge_release(struct inode *ip, struct file *filp)
-{
- int status = 0;
- struct process_context *pr_ctxt;
-
- if (!filp->private_data) {
- status = -EIO;
- goto err;
- }
-
- pr_ctxt = filp->private_data;
- flush_signals(current);
- drv_remove_all_resources(pr_ctxt);
- proc_detach(pr_ctxt);
- kfree(pr_ctxt->node_id);
- kfree(pr_ctxt->stream_id);
- kfree(pr_ctxt);
-
- filp->private_data = NULL;
-
-err:
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- if (!atomic_dec_return(&bridge_cref))
- complete(&bridge_comp);
-#endif
- return status;
-}
-
-/* This function provides IO interface to the bridge driver. */
-static long bridge_ioctl(struct file *filp, unsigned int code,
- unsigned long args)
-{
- int status;
- u32 retval = 0;
- union trapped_args buf_in;
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- if (recover) {
- status = -EIO;
- goto err;
- }
-#endif
-#ifdef CONFIG_PM
- status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp);
- if (status != 0)
- return status;
-#endif
-
- if (!filp->private_data) {
- status = -EIO;
- goto err;
- }
-
- status = copy_from_user(&buf_in, (union trapped_args *)args,
- sizeof(union trapped_args));
-
- if (!status) {
- status = api_call_dev_ioctl(code, &buf_in, &retval,
- filp->private_data);
-
- if (!status) {
- status = retval;
- } else {
- dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x "
- "status 0x%x\n", __func__, code, status);
- status = -1;
- }
-
- }
-
-err:
- return status;
-}
-
-/* This function maps kernel space memory to user space memory. */
-static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- unsigned long base_pgoff;
- int status;
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx "
- "flags %lx\n", __func__, filp,
- vma->vm_start, vma->vm_end, vma->vm_page_prot,
- vma->vm_flags);
-
- /*
- * vm_iomap_memory() expects vma->vm_pgoff to be expressed as an offset
- * from the start of the physical memory pool, but we're called with
- * a pfn (physical page number) stored there instead.
- *
- * To avoid duplicating lots of tricky overflow checking logic,
- * temporarily convert vma->vm_pgoff to the offset vm_iomap_memory()
- * expects, but restore the original value once the mapping has been
- * created.
- */
- base_pgoff = pdata->phys_mempool_base >> PAGE_SHIFT;
-
- if (vma->vm_pgoff < base_pgoff)
- return -EINVAL;
-
- vma->vm_pgoff -= base_pgoff;
-
- status = vm_iomap_memory(vma,
- pdata->phys_mempool_base,
- pdata->phys_mempool_size);
-
- /* Restore the original value of vma->vm_pgoff */
- vma->vm_pgoff += base_pgoff;
-
- return status;
-}
-
-static const struct file_operations bridge_fops = {
- .open = bridge_open,
- .release = bridge_release,
- .unlocked_ioctl = bridge_ioctl,
- .mmap = bridge_mmap,
- .llseek = noop_llseek,
-};
-
-#ifdef CONFIG_PM
-static u32 time_out = 1000;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
-s32 dsp_max_opps = VDD1_OPP5;
-#endif
-
-/* Maximum Opps that can be requested by IVA */
-/*vdd1 rate table */
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
-const struct omap_opp vdd1_rate_table_bridge[] = {
- {0, 0, 0},
- /*OPP1 */
- {S125M, VDD1_OPP1, 0},
- /*OPP2 */
- {S250M, VDD1_OPP2, 0},
- /*OPP3 */
- {S500M, VDD1_OPP3, 0},
- /*OPP4 */
- {S550M, VDD1_OPP4, 0},
- /*OPP5 */
- {S600M, VDD1_OPP5, 0},
-};
-#endif
-#endif
-
-struct omap_dsp_platform_data *omap_dspbridge_pdata;
-
-u32 vdd1_dsp_freq[6][4] = {
- {0, 0, 0, 0},
- /*OPP1 */
- {0, 90000, 0, 86000},
- /*OPP2 */
- {0, 180000, 80000, 170000},
- /*OPP3 */
- {0, 360000, 160000, 340000},
- /*OPP4 */
- {0, 396000, 325000, 376000},
- /*OPP5 */
- {0, 430000, 355000, 430000},
-};
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-static void bridge_recover(struct work_struct *work)
-{
- struct dev_object *dev;
- struct cfg_devnode *dev_node;
- if (atomic_read(&bridge_cref)) {
- reinit_completion(&bridge_comp);
- while (!wait_for_completion_timeout(&bridge_comp,
- msecs_to_jiffies(REC_TIMEOUT)))
- pr_info("%s:%d handle(s) still opened\n",
- __func__, atomic_read(&bridge_cref));
- }
- dev = dev_get_first();
- dev_get_dev_node(dev, &dev_node);
- if (!dev_node || proc_auto_start(dev_node, dev))
- pr_err("DSP could not be restarted\n");
- recover = false;
- complete_all(&bridge_open_comp);
-}
-
-void bridge_recover_schedule(void)
-{
- reinit_completion(&bridge_open_comp);
- recover = true;
- queue_work(bridge_rec_queue, &bridge_recovery_work);
-}
-#endif
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
-static int dspbridge_scale_notification(struct notifier_block *op,
- unsigned long val, void *ptr)
-{
- struct omap_dsp_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-
- if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp)
- pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp());
-
- return 0;
-}
-
-static struct notifier_block iva_clk_notifier = {
- .notifier_call = dspbridge_scale_notification,
- NULL,
-};
-#endif
-
-/**
- * omap3_bridge_startup() - perform low lever initializations
- * @pdev: pointer to platform device
- *
- * Initializes recovery, PM and DVFS required data, before calling
- * clk and memory init routines.
- */
-static int omap3_bridge_startup(struct platform_device *pdev)
-{
- struct omap_dsp_platform_data *pdata = pdev->dev.platform_data;
- struct drv_data *drv_datap = NULL;
- u32 phys_membase, phys_memsize;
- int err;
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
- bridge_rec_queue = create_workqueue("bridge_rec_queue");
- INIT_WORK(&bridge_recovery_work, bridge_recover);
- reinit_completion(&bridge_comp);
-#endif
-
-#ifdef CONFIG_PM
- /* Initialize the wait queue */
- bridge_suspend_data.suspended = 0;
- init_waitqueue_head(&bridge_suspend_data.suspend_wq);
-
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- for (i = 0; i < 6; i++)
- pdata->mpu_speed[i] = vdd1_rate_table_bridge[i].rate;
-
- err = cpufreq_register_notifier(&iva_clk_notifier,
- CPUFREQ_TRANSITION_NOTIFIER);
- if (err)
- pr_err("%s: clk_notifier_register failed for iva2_ck\n",
- __func__);
-#endif
-#endif
-
- dsp_clk_init();
-
- drv_datap = kzalloc(sizeof(struct drv_data), GFP_KERNEL);
- if (!drv_datap) {
- err = -ENOMEM;
- goto err1;
- }
-
- drv_datap->shm_size = shm_size;
- drv_datap->tc_wordswapon = tc_wordswapon;
-
- if (base_img) {
- drv_datap->base_img = kstrdup(base_img, GFP_KERNEL);
- if (!drv_datap->base_img) {
- err = -ENOMEM;
- goto err2;
- }
- }
-
- dev_set_drvdata(bridge, drv_datap);
-
- if (shm_size < 0x10000) { /* 64 KB */
- err = -EINVAL;
- pr_err("%s: shm size must be at least 64 KB\n", __func__);
- goto err3;
- }
- dev_dbg(bridge, "%s: requested shm_size = 0x%x\n", __func__, shm_size);
-
- phys_membase = pdata->phys_mempool_base;
- phys_memsize = pdata->phys_mempool_size;
- if (phys_membase > 0 && phys_memsize > 0)
- mem_ext_phys_pool_init(phys_membase, phys_memsize);
-
- if (tc_wordswapon)
- dev_dbg(bridge, "%s: TC Word Swap is enabled\n", __func__);
-
- driver_context = dsp_init(&err);
- if (err) {
- pr_err("DSP Bridge driver initialization failed\n");
- goto err4;
- }
-
- return 0;
-
-err4:
- mem_ext_phys_pool_release();
-err3:
- kfree(drv_datap->base_img);
-err2:
- kfree(drv_datap);
-err1:
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- cpufreq_unregister_notifier(&iva_clk_notifier,
- CPUFREQ_TRANSITION_NOTIFIER);
-#endif
- dsp_clk_exit();
-
- return err;
-}
-
-static int omap34_xx_bridge_probe(struct platform_device *pdev)
-{
- int err;
- dev_t dev = 0;
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- int i = 0;
-#endif
-
- omap_dspbridge_dev = pdev;
-
- /* Global bridge device */
- bridge = &omap_dspbridge_dev->dev;
-
- /* Bridge low level initializations */
- err = omap3_bridge_startup(pdev);
- if (err)
- goto err1;
-
- /* use 2.6 device model */
- err = alloc_chrdev_region(&dev, 0, 1, "DspBridge");
- if (err) {
- pr_err("%s: Can't get major %d\n", __func__, driver_major);
- goto err1;
- }
-
- cdev_init(&bridge_cdev, &bridge_fops);
- bridge_cdev.owner = THIS_MODULE;
-
- err = cdev_add(&bridge_cdev, dev, 1);
- if (err) {
- pr_err("%s: Failed to add bridge device\n", __func__);
- goto err2;
- }
-
- /* udev support */
- bridge_class = class_create(THIS_MODULE, "ti_bridge");
- if (IS_ERR(bridge_class)) {
- pr_err("%s: Error creating bridge class\n", __func__);
- err = PTR_ERR(bridge_class);
- goto err3;
- }
-
- driver_major = MAJOR(dev);
- device_create(bridge_class, NULL, MKDEV(driver_major, 0),
- NULL, "DspBridge");
- pr_info("DSP Bridge driver loaded\n");
-
- return 0;
-
-err3:
- cdev_del(&bridge_cdev);
-err2:
- unregister_chrdev_region(dev, 1);
-err1:
- return err;
-}
-
-static int omap34_xx_bridge_remove(struct platform_device *pdev)
-{
- dev_t devno;
- int status = 0;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /* Retrieve the Object handle from the driver data */
- if (!drv_datap || !drv_datap->drv_object) {
- status = -ENODATA;
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- goto func_cont;
- }
-
-#ifdef CONFIG_TIDSPBRIDGE_DVFS
- if (cpufreq_unregister_notifier(&iva_clk_notifier,
- CPUFREQ_TRANSITION_NOTIFIER))
- pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n",
- __func__);
-#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
-
- if (driver_context) {
- /* Put the DSP in reset state */
- dsp_deinit(driver_context);
- driver_context = 0;
- }
-
- kfree(drv_datap);
- dev_set_drvdata(bridge, NULL);
-
-func_cont:
- mem_ext_phys_pool_release();
-
- dsp_clk_exit();
-
- devno = MKDEV(driver_major, 0);
- cdev_del(&bridge_cdev);
- unregister_chrdev_region(devno, 1);
- if (bridge_class) {
- /* remove the device from sysfs */
- device_destroy(bridge_class, MKDEV(driver_major, 0));
- class_destroy(bridge_class);
-
- }
- return status;
-}
-
-#ifdef CONFIG_PM
-static int bridge_suspend(struct platform_device *pdev, pm_message_t state)
-{
- u32 status;
- u32 command = PWR_EMERGENCYDEEPSLEEP;
-
- status = pwr_sleep_dsp(command, time_out);
- if (status)
- return -1;
-
- bridge_suspend_data.suspended = 1;
- return 0;
-}
-
-static int bridge_resume(struct platform_device *pdev)
-{
- u32 status;
-
- status = pwr_wake_dsp(time_out);
- if (status)
- return -1;
-
- bridge_suspend_data.suspended = 0;
- wake_up(&bridge_suspend_data.suspend_wq);
- return 0;
-}
-#endif
-
-static struct platform_driver bridge_driver = {
- .driver = {
- .name = "omap-dsp",
- },
- .probe = omap34_xx_bridge_probe,
- .remove = omap34_xx_bridge_remove,
-#ifdef CONFIG_PM
- .suspend = bridge_suspend,
- .resume = bridge_resume,
-#endif
-};
-
-/* To remove all process resources before removing the process from the
- * process context list */
-int drv_remove_all_resources(void *process_ctxt)
-{
- int status = 0;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- drv_remove_all_strm_res_elements(ctxt);
- drv_remove_all_node_res_elements(ctxt);
- drv_remove_all_dmm_res_elements(ctxt);
- ctxt->res_state = PROC_RES_FREED;
- return status;
-}
-
-module_platform_driver(bridge_driver);
diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c
deleted file mode 100644
index 012e4a38d2db..000000000000
--- a/drivers/staging/tidspbridge/rmgr/dspdrv.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * dspdrv.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Interface to allocate and free bridge resources.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- Host OS */
-#include <linux/types.h>
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/drv.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/dspapi.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/mgr.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dspdrv.h>
-
-/*
- * ======== dsp_init ========
- * Allocates bridge resources. Loads a base image onto DSP, if specified.
- */
-u32 dsp_init(u32 *init_status)
-{
- char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510";
- int status = -EPERM;
- struct drv_object *drv_obj = NULL;
- u32 device_node;
- u32 device_node_string;
-
- if (!api_init())
- goto func_cont;
-
- status = drv_create(&drv_obj);
- if (status) {
- api_exit();
- goto func_cont;
- }
-
- /* End drv_create */
- /* Request Resources */
- status = drv_request_resources((u32) &dev_node, &device_node_string);
- if (!status) {
- /* Attempt to Start the Device */
- status = dev_start_device((struct cfg_devnode *)
- device_node_string);
- if (status)
- (void)drv_release_resources
- ((u32) device_node_string, drv_obj);
- } else {
- dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__);
- status = -EPERM;
- }
-
- /* Unwind whatever was loaded */
- if (status) {
- /* irrespective of the status of dev_remove_device we continue
- * unloading. Get the Driver Object iterate through and remove.
- * Reset the status to E_FAIL to avoid going through
- * api_init_complete2. */
- for (device_node = drv_get_first_dev_extension();
- device_node != 0;
- device_node = drv_get_next_dev_extension(device_node)) {
- (void)dev_remove_device((struct cfg_devnode *)
- device_node);
- (void)drv_release_resources((u32) device_node, drv_obj);
- }
- /* Remove the Driver Object */
- (void)drv_destroy(drv_obj);
- drv_obj = NULL;
- api_exit();
- dev_dbg(bridge, "%s: Logical device failed init\n", __func__);
- } /* Unwinding the loaded drivers */
-func_cont:
- /* Attempt to Start the Board */
- if (!status) {
- /* BRD_AutoStart could fail if the dsp executable is not the
- * correct one. We should not propagate that error
- * into the device loader. */
- (void)api_init_complete2();
- } else {
- dev_dbg(bridge, "%s: Failed\n", __func__);
- } /* End api_init_complete2 */
- *init_status = status;
- /* Return the Driver Object */
- return (u32) drv_obj;
-}
-
-/*
- * ======== dsp_deinit ========
- * Frees the resources allocated for bridge.
- */
-bool dsp_deinit(u32 device_context)
-{
- bool ret = true;
- u32 device_node;
- struct mgr_object *mgr_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- while ((device_node = drv_get_first_dev_extension()) != 0) {
- (void)dev_remove_device((struct cfg_devnode *)device_node);
-
- (void)drv_release_resources((u32) device_node,
- (struct drv_object *)device_context);
- }
-
- (void)drv_destroy((struct drv_object *)device_context);
-
- /* Get the Manager Object from driver data
- * MGR Destroy will unload the DCD dll */
- if (drv_datap && drv_datap->mgr_object) {
- mgr_obj = drv_datap->mgr_object;
- (void)mgr_destroy(mgr_obj);
- } else {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- }
-
- api_exit();
-
- return ret;
-}
diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c
deleted file mode 100644
index 93e6282f122b..000000000000
--- a/drivers/staging/tidspbridge/rmgr/mgr.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * mgr.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Implementation of Manager interface to the device object at the
- * driver level. This queries the NDB data base and retrieves the
- * data about Node and Processor.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/dbdcd.h>
-#include <dspbridge/drv.h>
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/mgr.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define ZLDLLNAME ""
-
-struct mgr_object {
- struct dcd_manager *dcd_mgr; /* Proc/Node data manager */
-};
-
-/* ----------------------------------- Globals */
-static u32 refs;
-
-/*
- * ========= mgr_create =========
- * Purpose:
- * MGR Object gets created only once during driver Loading.
- */
-int mgr_create(struct mgr_object **mgr_obj,
- struct cfg_devnode *dev_node_obj)
-{
- int status = 0;
- struct mgr_object *pmgr_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
- if (pmgr_obj) {
- status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr);
- if (!status) {
- /* If succeeded store the handle in the MGR Object */
- if (drv_datap) {
- drv_datap->mgr_object = (void *)pmgr_obj;
- } else {
- status = -EPERM;
- pr_err("%s: Failed to store MGR object\n",
- __func__);
- }
-
- if (!status) {
- *mgr_obj = pmgr_obj;
- } else {
- dcd_destroy_manager(pmgr_obj->dcd_mgr);
- kfree(pmgr_obj);
- }
- } else {
- /* failed to Create DCD Manager */
- kfree(pmgr_obj);
- }
- } else {
- status = -ENOMEM;
- }
-
- return status;
-}
-
-/*
- * ========= mgr_destroy =========
- * This function is invoked during bridge driver unloading.Frees MGR object.
- */
-int mgr_destroy(struct mgr_object *hmgr_obj)
-{
- int status = 0;
- struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- /* Free resources */
- if (hmgr_obj->dcd_mgr)
- dcd_destroy_manager(hmgr_obj->dcd_mgr);
-
- kfree(pmgr_obj);
- /* Update the driver data with NULL for MGR Object */
- if (drv_datap) {
- drv_datap->mgr_object = NULL;
- } else {
- status = -EPERM;
- pr_err("%s: Failed to store MGR object\n", __func__);
- }
-
- return status;
-}
-
-/*
- * ======== mgr_enum_node_info ========
- * Enumerate and get configuration information about nodes configured
- * in the node database.
- */
-int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
- u32 undb_props_size, u32 *pu_num_nodes)
-{
- int status = 0;
- struct dsp_uuid node_uuid;
- u32 node_index = 0;
- struct dcd_genericobj gen_obj;
- struct mgr_object *pmgr_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- *pu_num_nodes = 0;
- /* Get the Manager Object from the driver data */
- if (!drv_datap || !drv_datap->mgr_object) {
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- return -ENODATA;
- }
- pmgr_obj = drv_datap->mgr_object;
-
- /* Forever loop till we hit failed or no more items in the
- * Enumeration. We will exit the loop other than 0; */
- while (!status) {
- status = dcd_enumerate_object(node_index++, DSP_DCDNODETYPE,
- &node_uuid);
- if (status)
- break;
- *pu_num_nodes = node_index;
- if (node_id == (node_index - 1)) {
- status = dcd_get_object_def(pmgr_obj->dcd_mgr,
- &node_uuid, DSP_DCDNODETYPE, &gen_obj);
- if (status)
- break;
- /* Get the Obj def */
- *pndb_props = gen_obj.obj_data.node_obj.ndb_props;
- }
- }
-
- /* the last status is not 0, but neither an error */
- if (status > 0)
- status = 0;
-
- return status;
-}
-
-/*
- * ======== mgr_enum_processor_info ========
- * Enumerate and get configuration information about available
- * DSP processors.
- */
-int mgr_enum_processor_info(u32 processor_id,
- struct dsp_processorinfo *
- processor_info, u32 processor_info_size,
- u8 *pu_num_procs)
-{
- int status = 0;
- int status1 = 0;
- int status2 = 0;
- struct dsp_uuid temp_uuid;
- u32 temp_index = 0;
- u32 proc_index = 0;
- struct dcd_genericobj gen_obj;
- struct mgr_object *pmgr_obj = NULL;
- struct mgr_processorextinfo *ext_info;
- struct dev_object *hdev_obj;
- struct drv_object *hdrv_obj;
- u8 dev_type;
- struct cfg_devnode *dev_node;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- bool proc_detect = false;
-
- *pu_num_procs = 0;
-
- /* Retrieve the Object handle from the driver data */
- if (!drv_datap || !drv_datap->drv_object) {
- status = -ENODATA;
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- } else {
- hdrv_obj = drv_datap->drv_object;
- }
-
- if (!status) {
- status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
- if (!status) {
- status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
- status = dev_get_dev_node(hdev_obj, &dev_node);
- if (dev_type != DSP_UNIT)
- status = -EPERM;
-
- if (!status)
- processor_info->processor_type = DSPTYPE64;
- }
- }
- if (status)
- goto func_end;
-
- /* Get The Manager Object from the driver data */
- if (drv_datap && drv_datap->mgr_object) {
- pmgr_obj = drv_datap->mgr_object;
- } else {
- dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
- goto func_end;
- }
- /* Forever loop till we hit no more items in the
- * Enumeration. We will exit the loop other than 0; */
- while (status1 == 0) {
- status1 = dcd_enumerate_object(temp_index++,
- DSP_DCDPROCESSORTYPE,
- &temp_uuid);
- if (status1 != 0)
- break;
-
- proc_index++;
- /* Get the Object properties to find the Device/Processor
- * Type */
- if (proc_detect != false)
- continue;
-
- status2 = dcd_get_object_def(pmgr_obj->dcd_mgr,
- (struct dsp_uuid *)&temp_uuid,
- DSP_DCDPROCESSORTYPE, &gen_obj);
- if (!status2) {
- /* Get the Obj def */
- if (processor_info_size <
- sizeof(struct mgr_processorextinfo)) {
- *processor_info = gen_obj.obj_data.proc_info;
- } else {
- /* extended info */
- ext_info = (struct mgr_processorextinfo *)
- processor_info;
- *ext_info = gen_obj.obj_data.ext_proc_obj;
- }
- dev_dbg(bridge, "%s: Got proctype from DCD %x\n",
- __func__, processor_info->processor_type);
- /* See if we got the needed processor */
- if (dev_type == DSP_UNIT) {
- if (processor_info->processor_type ==
- DSPPROCTYPE_C64)
- proc_detect = true;
- } else if (dev_type == IVA_UNIT) {
- if (processor_info->processor_type ==
- IVAPROCTYPE_ARM7)
- proc_detect = true;
- }
- /* User applications only check for chip type, so
- * this is a clumsy overwrite */
- processor_info->processor_type = DSPTYPE64;
- } else {
- dev_dbg(bridge, "%s: Failed to get DCD processor info %x\n",
- __func__, status2);
- status = -EPERM;
- }
- }
- *pu_num_procs = proc_index;
- if (proc_detect == false) {
- dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use CFG registry\n",
- __func__);
- processor_info->processor_type = DSPTYPE64;
- }
-func_end:
- return status;
-}
-
-/*
- * ======== mgr_exit ========
- * Decrement reference count, and free resources when reference count is
- * 0.
- */
-void mgr_exit(void)
-{
- refs--;
- if (refs == 0)
- dcd_exit();
-}
-
-/*
- * ======== mgr_get_dcd_handle ========
- * Retrieves the MGR handle. Accessor Function.
- */
-int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
- u32 *dcd_handle)
-{
- int status = -EPERM;
- struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
-
- *dcd_handle = (u32) NULL;
- if (pmgr_obj) {
- *dcd_handle = (u32) pmgr_obj->dcd_mgr;
- status = 0;
- }
-
- return status;
-}
-
-/*
- * ======== mgr_init ========
- * Initialize MGR's private state, keeping a reference count on each call.
- */
-bool mgr_init(void)
-{
- bool ret = true;
-
- if (refs == 0)
- ret = dcd_init(); /* DCD Module */
-
- if (ret)
- refs++;
-
- return ret;
-}
-
-/*
- * ======== mgr_wait_for_bridge_events ========
- * Block on any Bridge event(s)
- */
-int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
- u32 count, u32 *pu_index,
- u32 utimeout)
-{
- int status;
- struct sync_object *sync_events[MAX_EVENTS];
- u32 i;
-
- for (i = 0; i < count; i++)
- sync_events[i] = anotifications[i]->handle;
-
- status = sync_wait_on_multiple_events(sync_events, count, utimeout,
- pu_index);
-
- return status;
-
-}
diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c
deleted file mode 100644
index 5ac507ccd19d..000000000000
--- a/drivers/staging/tidspbridge/rmgr/nldr.c
+++ /dev/null
@@ -1,1860 +0,0 @@
-/*
- * nldr.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge dynamic + overlay Node loader.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-#include <dspbridge/host_os.h>
-
-#include <dspbridge/dbdefs.h>
-
-/* Platform manager */
-#include <dspbridge/cod.h>
-#include <dspbridge/dev.h>
-
-/* Resource manager */
-#include <dspbridge/dbll.h>
-#include <dspbridge/dbdcd.h>
-#include <dspbridge/rmm.h>
-#include <dspbridge/uuidutil.h>
-
-#include <dspbridge/nldr.h>
-#include <linux/lcm.h>
-
-/* Name of section containing dynamic load mem */
-#define DYNMEMSECT ".dspbridge_mem"
-
-/* Name of section containing dependent library information */
-#define DEPLIBSECT ".dspbridge_deplibs"
-
-/* Max depth of recursion for loading node's dependent libraries */
-#define MAXDEPTH 5
-
-/* Max number of persistent libraries kept by a node */
-#define MAXLIBS 5
-
-/*
- * Defines for extracting packed dynamic load memory requirements from two
- * masks.
- * These defines must match node.cdb and dynm.cdb
- * Format of data/code mask is:
- * uuuuuuuu|fueeeeee|fudddddd|fucccccc|
- * where
- * u = unused
- * cccccc = preferred/required dynamic mem segid for create phase data/code
- * dddddd = preferred/required dynamic mem segid for delete phase data/code
- * eeeeee = preferred/req. dynamic mem segid for execute phase data/code
- * f = flag indicating if memory is preferred or required:
- * f = 1 if required, f = 0 if preferred.
- *
- * The 6 bits of the segid are interpreted as follows:
- *
- * If the 6th bit (bit 5) is not set, then this specifies a memory segment
- * between 0 and 31 (a maximum of 32 dynamic loading memory segments).
- * If the 6th bit (bit 5) is set, segid has the following interpretation:
- * segid = 32 - Any internal memory segment can be used.
- * segid = 33 - Any external memory segment can be used.
- * segid = 63 - Any memory segment can be used (in this case the
- * required/preferred flag is irrelevant).
- *
- */
-/* Maximum allowed dynamic loading memory segments */
-#define MAXMEMSEGS 32
-
-#define MAXSEGID 3 /* Largest possible (real) segid */
-#define MEMINTERNALID 32 /* Segid meaning use internal mem */
-#define MEMEXTERNALID 33 /* Segid meaning use external mem */
-#define NULLID 63 /* Segid meaning no memory req/pref */
-#define FLAGBIT 7 /* 7th bit is pref./req. flag */
-#define SEGMASK 0x3f /* Bits 0 - 5 */
-
-#define CREATEBIT 0 /* Create segid starts at bit 0 */
-#define DELETEBIT 8 /* Delete segid starts at bit 8 */
-#define EXECUTEBIT 16 /* Execute segid starts at bit 16 */
-
-/*
- * Masks that define memory type. Must match defines in dynm.cdb.
- */
-#define DYNM_CODE 0x2
-#define DYNM_DATA 0x4
-#define DYNM_CODEDATA (DYNM_CODE | DYNM_DATA)
-#define DYNM_INTERNAL 0x8
-#define DYNM_EXTERNAL 0x10
-
-/*
- * Defines for packing memory requirement/preference flags for code and
- * data of each of the node's phases into one mask.
- * The bit is set if the segid is required for loading code/data of the
- * given phase. The bit is not set, if the segid is preferred only.
- *
- * These defines are also used as indeces into a segid array for the node.
- * eg node's segid[CREATEDATAFLAGBIT] is the memory segment id that the
- * create phase data is required or preferred to be loaded into.
- */
-#define CREATEDATAFLAGBIT 0
-#define CREATECODEFLAGBIT 1
-#define EXECUTEDATAFLAGBIT 2
-#define EXECUTECODEFLAGBIT 3
-#define DELETEDATAFLAGBIT 4
-#define DELETECODEFLAGBIT 5
-#define MAXFLAGS 6
-
- /*
- * These names may be embedded in overlay sections to identify which
- * node phase the section should be overlayed.
- */
-#define PCREATE "create"
-#define PDELETE "delete"
-#define PEXECUTE "execute"
-
-static inline bool is_equal_uuid(struct dsp_uuid *uuid1,
- struct dsp_uuid *uuid2)
-{
- return !memcmp(uuid1, uuid2, sizeof(struct dsp_uuid));
-}
-
- /*
- * ======== mem_seg_info ========
- * Format of dynamic loading memory segment info in coff file.
- * Must match dynm.h55.
- */
-struct mem_seg_info {
- u32 segid; /* Dynamic loading memory segment number */
- u32 base;
- u32 len;
- u32 type; /* Mask of DYNM_CODE, DYNM_INTERNAL, etc. */
-};
-
-/*
- * ======== lib_node ========
- * For maintaining a tree of library dependencies.
- */
-struct lib_node {
- struct dbll_library_obj *lib; /* The library */
- u16 dep_libs; /* Number of dependent libraries */
- struct lib_node *dep_libs_tree; /* Dependent libraries of lib */
-};
-
-/*
- * ======== ovly_sect ========
- * Information needed to overlay a section.
- */
-struct ovly_sect {
- struct ovly_sect *next_sect;
- u32 sect_load_addr; /* Load address of section */
- u32 sect_run_addr; /* Run address of section */
- u32 size; /* Size of section */
- u16 page; /* DBL_CODE, DBL_DATA */
-};
-
-/*
- * ======== ovly_node ========
- * For maintaining a list of overlay nodes, with sections that need to be
- * overlayed for each of the nodes phases.
- */
-struct ovly_node {
- struct dsp_uuid uuid;
- char *node_name;
- struct ovly_sect *create_sects_list;
- struct ovly_sect *delete_sects_list;
- struct ovly_sect *execute_sects_list;
- struct ovly_sect *other_sects_list;
- u16 create_sects;
- u16 delete_sects;
- u16 execute_sects;
- u16 other_sects;
- u16 create_ref;
- u16 delete_ref;
- u16 execute_ref;
- u16 other_ref;
-};
-
-/*
- * ======== nldr_object ========
- * Overlay loader object.
- */
-struct nldr_object {
- struct dev_object *dev_obj; /* Device object */
- struct dcd_manager *dcd_mgr; /* Proc/Node data manager */
- struct dbll_tar_obj *dbll; /* The DBL loader */
- struct dbll_library_obj *base_lib; /* Base image library */
- struct rmm_target_obj *rmm; /* Remote memory manager for DSP */
- struct dbll_fxns ldr_fxns; /* Loader function table */
- struct dbll_attrs ldr_attrs; /* attrs to pass to loader functions */
- nldr_ovlyfxn ovly_fxn; /* "write" for overlay nodes */
- nldr_writefxn write_fxn; /* "write" for dynamic nodes */
- struct ovly_node *ovly_table; /* Table of overlay nodes */
- u16 ovly_nodes; /* Number of overlay nodes in base */
- u16 ovly_nid; /* Index for tracking overlay nodes */
- u16 dload_segs; /* Number of dynamic load mem segs */
- u32 *seg_table; /* memtypes of dynamic memory segs
- * indexed by segid
- */
- u16 dsp_mau_size; /* Size of DSP MAU */
- u16 dsp_word_size; /* Size of DSP word */
-};
-
-/*
- * ======== nldr_nodeobject ========
- * Dynamic node object. This object is created when a node is allocated.
- */
-struct nldr_nodeobject {
- struct nldr_object *nldr_obj; /* Dynamic loader handle */
- void *priv_ref; /* Handle to pass to dbl_write_fxn */
- struct dsp_uuid uuid; /* Node's UUID */
- bool dynamic; /* Dynamically loaded node? */
- bool overlay; /* Overlay node? */
- bool *phase_split; /* Multiple phase libraries? */
- struct lib_node root; /* Library containing node phase */
- struct lib_node create_lib; /* Library with create phase lib */
- struct lib_node execute_lib; /* Library with execute phase lib */
- struct lib_node delete_lib; /* Library with delete phase lib */
- /* libs remain loaded until Delete */
- struct lib_node pers_lib_table[MAXLIBS];
- s32 pers_libs; /* Number of persistent libraries */
- /* Path in lib dependency tree */
- struct dbll_library_obj *lib_path[MAXDEPTH + 1];
- enum nldr_phase phase; /* Node phase currently being loaded */
-
- /*
- * Dynamic loading memory segments for data and code of each phase.
- */
- u16 seg_id[MAXFLAGS];
-
- /*
- * Mask indicating whether each mem segment specified in seg_id[]
- * is preferred or required.
- * For example
- * if (code_data_flag_mask & (1 << EXECUTEDATAFLAGBIT)) != 0,
- * then it is required to load execute phase data into the memory
- * specified by seg_id[EXECUTEDATAFLAGBIT].
- */
- u32 code_data_flag_mask;
-};
-
-/* Dynamic loader function table */
-static struct dbll_fxns ldr_fxns = {
- (dbll_close_fxn) dbll_close,
- (dbll_create_fxn) dbll_create,
- (dbll_delete_fxn) dbll_delete,
- (dbll_exit_fxn) dbll_exit,
- (dbll_get_attrs_fxn) dbll_get_attrs,
- (dbll_get_addr_fxn) dbll_get_addr,
- (dbll_get_c_addr_fxn) dbll_get_c_addr,
- (dbll_get_sect_fxn) dbll_get_sect,
- (dbll_init_fxn) dbll_init,
- (dbll_load_fxn) dbll_load,
- (dbll_open_fxn) dbll_open,
- (dbll_read_sect_fxn) dbll_read_sect,
- (dbll_unload_fxn) dbll_unload,
-};
-
-static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info,
- u32 addr, u32 bytes);
-static int add_ovly_node(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type, void *handle);
-static int add_ovly_sect(struct nldr_object *nldr_obj,
- struct ovly_sect **lst,
- struct dbll_sect_info *sect_inf,
- bool *exists, u32 addr, u32 bytes);
-static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes,
- s32 mtype);
-static void free_sects(struct nldr_object *nldr_obj,
- struct ovly_sect *phase_sects, u16 alloc_num);
-static bool get_symbol_value(void *handle, void *parg, void *rmm_handle,
- char *sym_name, struct dbll_sym_val **sym);
-static int load_lib(struct nldr_nodeobject *nldr_node_obj,
- struct lib_node *root, struct dsp_uuid uuid,
- bool root_prstnt,
- struct dbll_library_obj **lib_path,
- enum nldr_phase phase, u16 depth);
-static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-static int remote_alloc(void **ref, u16 mem_sect, u32 size,
- u32 align, u32 *dsp_address,
- s32 segmnt_id,
- s32 req, bool reserve);
-static int remote_free(void **ref, u16 space, u32 dsp_address, u32 size,
- bool reserve);
-
-static void unload_lib(struct nldr_nodeobject *nldr_node_obj,
- struct lib_node *root);
-static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase);
-static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj,
- struct dbll_library_obj *lib);
-
-/*
- * ======== nldr_allocate ========
- */
-int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref,
- const struct dcd_nodeprops *node_props,
- struct nldr_nodeobject **nldr_nodeobj,
- bool *pf_phase_split)
-{
- struct nldr_nodeobject *nldr_node_obj = NULL;
- int status = 0;
-
- /* Initialize handle in case of failure */
- *nldr_nodeobj = NULL;
- /* Allocate node object */
- nldr_node_obj = kzalloc(sizeof(struct nldr_nodeobject), GFP_KERNEL);
-
- if (nldr_node_obj == NULL) {
- status = -ENOMEM;
- } else {
- nldr_node_obj->phase_split = pf_phase_split;
- nldr_node_obj->pers_libs = 0;
- nldr_node_obj->nldr_obj = nldr_obj;
- nldr_node_obj->priv_ref = priv_ref;
- /* Save node's UUID. */
- nldr_node_obj->uuid = node_props->ndb_props.ui_node_id;
- /*
- * Determine if node is a dynamically loaded node from
- * ndb_props.
- */
- if (node_props->load_type == NLDR_DYNAMICLOAD) {
- /* Dynamic node */
- nldr_node_obj->dynamic = true;
- /*
- * Extract memory requirements from ndb_props masks
- */
- /* Create phase */
- nldr_node_obj->seg_id[CREATEDATAFLAGBIT] = (u16)
- (node_props->data_mem_seg_mask >> CREATEBIT) &
- SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->data_mem_seg_mask >>
- (CREATEBIT + FLAGBIT)) & 1) << CREATEDATAFLAGBIT;
- nldr_node_obj->seg_id[CREATECODEFLAGBIT] = (u16)
- (node_props->code_mem_seg_mask >>
- CREATEBIT) & SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->code_mem_seg_mask >>
- (CREATEBIT + FLAGBIT)) & 1) << CREATECODEFLAGBIT;
- /* Execute phase */
- nldr_node_obj->seg_id[EXECUTEDATAFLAGBIT] = (u16)
- (node_props->data_mem_seg_mask >>
- EXECUTEBIT) & SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->data_mem_seg_mask >>
- (EXECUTEBIT + FLAGBIT)) & 1) <<
- EXECUTEDATAFLAGBIT;
- nldr_node_obj->seg_id[EXECUTECODEFLAGBIT] = (u16)
- (node_props->code_mem_seg_mask >>
- EXECUTEBIT) & SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->code_mem_seg_mask >>
- (EXECUTEBIT + FLAGBIT)) & 1) <<
- EXECUTECODEFLAGBIT;
- /* Delete phase */
- nldr_node_obj->seg_id[DELETEDATAFLAGBIT] = (u16)
- (node_props->data_mem_seg_mask >> DELETEBIT) &
- SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->data_mem_seg_mask >>
- (DELETEBIT + FLAGBIT)) & 1) << DELETEDATAFLAGBIT;
- nldr_node_obj->seg_id[DELETECODEFLAGBIT] = (u16)
- (node_props->code_mem_seg_mask >>
- DELETEBIT) & SEGMASK;
- nldr_node_obj->code_data_flag_mask |=
- ((node_props->code_mem_seg_mask >>
- (DELETEBIT + FLAGBIT)) & 1) << DELETECODEFLAGBIT;
- } else {
- /* Non-dynamically loaded nodes are part of the
- * base image */
- nldr_node_obj->root.lib = nldr_obj->base_lib;
- /* Check for overlay node */
- if (node_props->load_type == NLDR_OVLYLOAD)
- nldr_node_obj->overlay = true;
-
- }
- *nldr_nodeobj = (struct nldr_nodeobject *)nldr_node_obj;
- }
- /* Cleanup on failure */
- if (status && nldr_node_obj)
- kfree(nldr_node_obj);
-
- return status;
-}
-
-/*
- * ======== nldr_create ========
- */
-int nldr_create(struct nldr_object **nldr,
- struct dev_object *hdev_obj,
- const struct nldr_attrs *pattrs)
-{
- struct cod_manager *cod_mgr; /* COD manager */
- char *psz_coff_buf = NULL;
- char sz_zl_file[COD_MAXPATHLENGTH];
- struct nldr_object *nldr_obj = NULL;
- struct dbll_attrs save_attrs;
- struct dbll_attrs new_attrs;
- dbll_flags flags;
- u32 ul_entry;
- u16 dload_segs = 0;
- struct mem_seg_info *mem_info_obj;
- u32 ul_len = 0;
- u32 ul_addr;
- struct rmm_segment *rmm_segs = NULL;
- u16 i;
- int status = 0;
-
- /* Allocate dynamic loader object */
- nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL);
- if (nldr_obj) {
- nldr_obj->dev_obj = hdev_obj;
- /* warning, lazy status checking alert! */
- dev_get_cod_mgr(hdev_obj, &cod_mgr);
- if (cod_mgr) {
- status = cod_get_loader(cod_mgr, &nldr_obj->dbll);
- status = cod_get_base_lib(cod_mgr, &nldr_obj->base_lib);
- status =
- cod_get_base_name(cod_mgr, sz_zl_file,
- COD_MAXPATHLENGTH);
- }
- status = 0;
- /* end lazy status checking */
- nldr_obj->dsp_mau_size = pattrs->dsp_mau_size;
- nldr_obj->dsp_word_size = pattrs->dsp_word_size;
- nldr_obj->ldr_fxns = ldr_fxns;
- if (!(nldr_obj->ldr_fxns.init_fxn()))
- status = -ENOMEM;
-
- } else {
- status = -ENOMEM;
- }
- /* Create the DCD Manager */
- if (!status)
- status = dcd_create_manager(NULL, &nldr_obj->dcd_mgr);
-
- /* Get dynamic loading memory sections from base lib */
- if (!status) {
- status =
- nldr_obj->ldr_fxns.get_sect_fxn(nldr_obj->base_lib,
- DYNMEMSECT, &ul_addr,
- &ul_len);
- if (!status) {
- psz_coff_buf =
- kzalloc(ul_len * nldr_obj->dsp_mau_size,
- GFP_KERNEL);
- if (!psz_coff_buf)
- status = -ENOMEM;
- } else {
- /* Ok to not have dynamic loading memory */
- status = 0;
- ul_len = 0;
- dev_dbg(bridge, "%s: failed - no dynamic loading mem "
- "segments: 0x%x\n", __func__, status);
- }
- }
- if (!status && ul_len > 0) {
- /* Read section containing dynamic load mem segments */
- status =
- nldr_obj->ldr_fxns.read_sect_fxn(nldr_obj->base_lib,
- DYNMEMSECT, psz_coff_buf,
- ul_len);
- }
- if (!status && ul_len > 0) {
- /* Parse memory segment data */
- dload_segs = (u16) (*((u32 *) psz_coff_buf));
- if (dload_segs > MAXMEMSEGS)
- status = -EBADF;
- }
- /* Parse dynamic load memory segments */
- if (!status && dload_segs > 0) {
- rmm_segs = kzalloc(sizeof(struct rmm_segment) * dload_segs,
- GFP_KERNEL);
- nldr_obj->seg_table =
- kzalloc(sizeof(u32) * dload_segs, GFP_KERNEL);
- if (rmm_segs == NULL || nldr_obj->seg_table == NULL) {
- status = -ENOMEM;
- } else {
- nldr_obj->dload_segs = dload_segs;
- mem_info_obj = (struct mem_seg_info *)(psz_coff_buf +
- sizeof(u32));
- for (i = 0; i < dload_segs; i++) {
- rmm_segs[i].base = (mem_info_obj + i)->base;
- rmm_segs[i].length = (mem_info_obj + i)->len;
- rmm_segs[i].space = 0;
- nldr_obj->seg_table[i] =
- (mem_info_obj + i)->type;
- dev_dbg(bridge,
- "(proc) DLL MEMSEGMENT: %d, "
- "Base: 0x%x, Length: 0x%x\n", i,
- rmm_segs[i].base, rmm_segs[i].length);
- }
- }
- }
- /* Create Remote memory manager */
- if (!status)
- status = rmm_create(&nldr_obj->rmm, rmm_segs, dload_segs);
-
- if (!status) {
- /* set the alloc, free, write functions for loader */
- nldr_obj->ldr_fxns.get_attrs_fxn(nldr_obj->dbll, &save_attrs);
- new_attrs = save_attrs;
- new_attrs.alloc = (dbll_alloc_fxn) remote_alloc;
- new_attrs.free = (dbll_free_fxn) remote_free;
- new_attrs.sym_lookup = (dbll_sym_lookup) get_symbol_value;
- new_attrs.sym_handle = nldr_obj;
- new_attrs.write = (dbll_write_fxn) pattrs->write;
- nldr_obj->ovly_fxn = pattrs->ovly;
- nldr_obj->write_fxn = pattrs->write;
- nldr_obj->ldr_attrs = new_attrs;
- }
- kfree(rmm_segs);
-
- kfree(psz_coff_buf);
-
- /* Get overlay nodes */
- if (!status) {
- status =
- cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH);
- /* lazy check */
- /* First count number of overlay nodes */
- status =
- dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file,
- add_ovly_node, (void *)nldr_obj);
- /* Now build table of overlay nodes */
- if (!status && nldr_obj->ovly_nodes > 0) {
- /* Allocate table for overlay nodes */
- nldr_obj->ovly_table =
- kzalloc(sizeof(struct ovly_node) *
- nldr_obj->ovly_nodes, GFP_KERNEL);
- /* Put overlay nodes in the table */
- nldr_obj->ovly_nid = 0;
- status = dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file,
- add_ovly_node,
- (void *)nldr_obj);
- }
- }
- /* Do a fake reload of the base image to get overlay section info */
- if (!status && nldr_obj->ovly_nodes > 0) {
- save_attrs.write = fake_ovly_write;
- save_attrs.log_write = add_ovly_info;
- save_attrs.log_write_handle = nldr_obj;
- flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
- status = nldr_obj->ldr_fxns.load_fxn(nldr_obj->base_lib, flags,
- &save_attrs, &ul_entry);
- }
- if (!status) {
- *nldr = (struct nldr_object *)nldr_obj;
- } else {
- if (nldr_obj)
- nldr_delete((struct nldr_object *)nldr_obj);
-
- *nldr = NULL;
- }
- /* FIXME:Temp. Fix. Must be removed */
- return status;
-}
-
-/*
- * ======== nldr_delete ========
- */
-void nldr_delete(struct nldr_object *nldr_obj)
-{
- struct ovly_sect *ovly_section;
- struct ovly_sect *next;
- u16 i;
-
- nldr_obj->ldr_fxns.exit_fxn();
- if (nldr_obj->rmm)
- rmm_delete(nldr_obj->rmm);
-
- kfree(nldr_obj->seg_table);
-
- if (nldr_obj->dcd_mgr)
- dcd_destroy_manager(nldr_obj->dcd_mgr);
-
- /* Free overlay node information */
- if (nldr_obj->ovly_table) {
- for (i = 0; i < nldr_obj->ovly_nodes; i++) {
- ovly_section =
- nldr_obj->ovly_table[i].create_sects_list;
- while (ovly_section) {
- next = ovly_section->next_sect;
- kfree(ovly_section);
- ovly_section = next;
- }
- ovly_section =
- nldr_obj->ovly_table[i].delete_sects_list;
- while (ovly_section) {
- next = ovly_section->next_sect;
- kfree(ovly_section);
- ovly_section = next;
- }
- ovly_section =
- nldr_obj->ovly_table[i].execute_sects_list;
- while (ovly_section) {
- next = ovly_section->next_sect;
- kfree(ovly_section);
- ovly_section = next;
- }
- ovly_section = nldr_obj->ovly_table[i].other_sects_list;
- while (ovly_section) {
- next = ovly_section->next_sect;
- kfree(ovly_section);
- ovly_section = next;
- }
- }
- kfree(nldr_obj->ovly_table);
- }
- kfree(nldr_obj);
-}
-
-/*
- * ======== nldr_get_fxn_addr ========
- */
-int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
- char *str_fxn, u32 *addr)
-{
- struct dbll_sym_val *dbll_sym;
- struct nldr_object *nldr_obj;
- int status = 0;
- bool status1 = false;
- s32 i = 0;
- struct lib_node root = { NULL, 0, NULL };
-
- nldr_obj = nldr_node_obj->nldr_obj;
- /* Called from node_create(), node_delete(), or node_run(). */
- if (nldr_node_obj->dynamic && *nldr_node_obj->phase_split) {
- switch (nldr_node_obj->phase) {
- case NLDR_CREATE:
- root = nldr_node_obj->create_lib;
- break;
- case NLDR_EXECUTE:
- root = nldr_node_obj->execute_lib;
- break;
- case NLDR_DELETE:
- root = nldr_node_obj->delete_lib;
- break;
- default:
- break;
- }
- } else {
- /* for Overlay nodes or non-split Dynamic nodes */
- root = nldr_node_obj->root;
- }
- status1 =
- nldr_obj->ldr_fxns.get_c_addr_fxn(root.lib, str_fxn, &dbll_sym);
- if (!status1)
- status1 =
- nldr_obj->ldr_fxns.get_addr_fxn(root.lib, str_fxn,
- &dbll_sym);
-
- /* If symbol not found, check dependent libraries */
- if (!status1) {
- for (i = 0; i < root.dep_libs; i++) {
- status1 =
- nldr_obj->ldr_fxns.get_addr_fxn(root.dep_libs_tree
- [i].lib, str_fxn,
- &dbll_sym);
- if (!status1) {
- status1 =
- nldr_obj->ldr_fxns.
- get_c_addr_fxn(root.dep_libs_tree[i].lib,
- str_fxn, &dbll_sym);
- }
- if (status1) {
- /* Symbol found */
- break;
- }
- }
- }
- /* Check persistent libraries */
- if (!status1) {
- for (i = 0; i < nldr_node_obj->pers_libs; i++) {
- status1 =
- nldr_obj->ldr_fxns.
- get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib,
- str_fxn, &dbll_sym);
- if (!status1) {
- status1 =
- nldr_obj->ldr_fxns.
- get_c_addr_fxn(nldr_node_obj->pers_lib_table
- [i].lib, str_fxn, &dbll_sym);
- }
- if (status1) {
- /* Symbol found */
- break;
- }
- }
- }
-
- if (status1)
- *addr = dbll_sym->value;
- else
- status = -ESPIPE;
-
- return status;
-}
-
-/*
- * ======== nldr_get_rmm_manager ========
- * Given a NLDR object, retrieve RMM Manager Handle
- */
-int nldr_get_rmm_manager(struct nldr_object *nldr,
- struct rmm_target_obj **rmm_mgr)
-{
- int status = 0;
- struct nldr_object *nldr_obj = nldr;
-
- if (nldr) {
- *rmm_mgr = nldr_obj->rmm;
- } else {
- *rmm_mgr = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== nldr_load ========
- */
-int nldr_load(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase)
-{
- struct nldr_object *nldr_obj;
- struct dsp_uuid lib_uuid;
- int status = 0;
-
- nldr_obj = nldr_node_obj->nldr_obj;
-
- if (nldr_node_obj->dynamic) {
- nldr_node_obj->phase = phase;
-
- lib_uuid = nldr_node_obj->uuid;
-
- /* At this point, we may not know if node is split into
- * different libraries. So we'll go ahead and load the
- * library, and then save the pointer to the appropriate
- * location after we know. */
-
- status =
- load_lib(nldr_node_obj, &nldr_node_obj->root, lib_uuid,
- false, nldr_node_obj->lib_path, phase, 0);
-
- if (!status) {
- if (*nldr_node_obj->phase_split) {
- switch (phase) {
- case NLDR_CREATE:
- nldr_node_obj->create_lib =
- nldr_node_obj->root;
- break;
-
- case NLDR_EXECUTE:
- nldr_node_obj->execute_lib =
- nldr_node_obj->root;
- break;
-
- case NLDR_DELETE:
- nldr_node_obj->delete_lib =
- nldr_node_obj->root;
- break;
-
- default:
- break;
- }
- }
- }
- } else {
- if (nldr_node_obj->overlay)
- status = load_ovly(nldr_node_obj, phase);
-
- }
-
- return status;
-}
-
-/*
- * ======== nldr_unload ========
- */
-int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase)
-{
- int status = 0;
- struct lib_node *root_lib = NULL;
- s32 i = 0;
-
- if (nldr_node_obj != NULL) {
- if (nldr_node_obj->dynamic) {
- if (*nldr_node_obj->phase_split) {
- switch (phase) {
- case NLDR_CREATE:
- root_lib = &nldr_node_obj->create_lib;
- break;
- case NLDR_EXECUTE:
- root_lib = &nldr_node_obj->execute_lib;
- break;
- case NLDR_DELETE:
- root_lib = &nldr_node_obj->delete_lib;
- /* Unload persistent libraries */
- for (i = 0;
- i < nldr_node_obj->pers_libs;
- i++) {
- unload_lib(nldr_node_obj,
- &nldr_node_obj->
- pers_lib_table[i]);
- }
- nldr_node_obj->pers_libs = 0;
- break;
- default:
- break;
- }
- } else {
- /* Unload main library */
- root_lib = &nldr_node_obj->root;
- }
- if (root_lib)
- unload_lib(nldr_node_obj, root_lib);
- } else {
- if (nldr_node_obj->overlay)
- unload_ovly(nldr_node_obj, phase);
-
- }
- }
- return status;
-}
-
-/*
- * ======== add_ovly_info ========
- */
-static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info,
- u32 addr, u32 bytes)
-{
- char *node_name;
- char *sect_name = (char *)sect_info->name;
- bool sect_exists = false;
- char seps = ':';
- char *pch;
- u16 i;
- struct nldr_object *nldr_obj = (struct nldr_object *)handle;
- int status = 0;
-
- /* Is this an overlay section (load address != run address)? */
- if (sect_info->sect_load_addr == sect_info->sect_run_addr)
- goto func_end;
-
- /* Find the node it belongs to */
- for (i = 0; i < nldr_obj->ovly_nodes; i++) {
- node_name = nldr_obj->ovly_table[i].node_name;
- if (strncmp(node_name, sect_name + 1, strlen(node_name)) == 0) {
- /* Found the node */
- break;
- }
- }
- if (!(i < nldr_obj->ovly_nodes))
- goto func_end;
-
- /* Determine which phase this section belongs to */
- for (pch = sect_name + 1; *pch && *pch != seps; pch++)
- ;
-
- if (*pch) {
- pch++; /* Skip over the ':' */
- if (strncmp(pch, PCREATE, strlen(PCREATE)) == 0) {
- status =
- add_ovly_sect(nldr_obj,
- &nldr_obj->
- ovly_table[i].create_sects_list,
- sect_info, &sect_exists, addr, bytes);
- if (!status && !sect_exists)
- nldr_obj->ovly_table[i].create_sects++;
-
- } else if (strncmp(pch, PDELETE, strlen(PDELETE)) == 0) {
- status =
- add_ovly_sect(nldr_obj,
- &nldr_obj->
- ovly_table[i].delete_sects_list,
- sect_info, &sect_exists, addr, bytes);
- if (!status && !sect_exists)
- nldr_obj->ovly_table[i].delete_sects++;
-
- } else if (strncmp(pch, PEXECUTE, strlen(PEXECUTE)) == 0) {
- status =
- add_ovly_sect(nldr_obj,
- &nldr_obj->
- ovly_table[i].execute_sects_list,
- sect_info, &sect_exists, addr, bytes);
- if (!status && !sect_exists)
- nldr_obj->ovly_table[i].execute_sects++;
-
- } else {
- /* Put in "other" sections */
- status =
- add_ovly_sect(nldr_obj,
- &nldr_obj->
- ovly_table[i].other_sects_list,
- sect_info, &sect_exists, addr, bytes);
- if (!status && !sect_exists)
- nldr_obj->ovly_table[i].other_sects++;
-
- }
- }
-func_end:
- return status;
-}
-
-/*
- * ======== add_ovly_node =========
- * Callback function passed to dcd_get_objects.
- */
-static int add_ovly_node(struct dsp_uuid *uuid_obj,
- enum dsp_dcdobjtype obj_type, void *handle)
-{
- struct nldr_object *nldr_obj = (struct nldr_object *)handle;
- char *node_name = NULL;
- char *pbuf = NULL;
- u32 len;
- struct dcd_genericobj obj_def;
- int status = 0;
-
- if (obj_type != DSP_DCDNODETYPE)
- goto func_end;
-
- status =
- dcd_get_object_def(nldr_obj->dcd_mgr, uuid_obj, obj_type,
- &obj_def);
- if (status)
- goto func_end;
-
- /* If overlay node, add to the list */
- if (obj_def.obj_data.node_obj.load_type == NLDR_OVLYLOAD) {
- if (nldr_obj->ovly_table == NULL) {
- nldr_obj->ovly_nodes++;
- } else {
- /* Add node to table */
- nldr_obj->ovly_table[nldr_obj->ovly_nid].uuid =
- *uuid_obj;
- len =
- strlen(obj_def.obj_data.node_obj.ndb_props.ac_name);
- node_name = obj_def.obj_data.node_obj.ndb_props.ac_name;
- pbuf = kzalloc(len + 1, GFP_KERNEL);
- if (pbuf == NULL) {
- status = -ENOMEM;
- } else {
- strncpy(pbuf, node_name, len);
- nldr_obj->ovly_table[nldr_obj->ovly_nid].
- node_name = pbuf;
- nldr_obj->ovly_nid++;
- }
- }
- }
- /* These were allocated in dcd_get_object_def */
- kfree(obj_def.obj_data.node_obj.str_create_phase_fxn);
-
- kfree(obj_def.obj_data.node_obj.str_execute_phase_fxn);
-
- kfree(obj_def.obj_data.node_obj.str_delete_phase_fxn);
-
- kfree(obj_def.obj_data.node_obj.str_i_alg_name);
-
-func_end:
- return status;
-}
-
-/*
- * ======== add_ovly_sect ========
- */
-static int add_ovly_sect(struct nldr_object *nldr_obj,
- struct ovly_sect **lst,
- struct dbll_sect_info *sect_inf,
- bool *exists, u32 addr, u32 bytes)
-{
- struct ovly_sect *new_sect = NULL;
- struct ovly_sect *last_sect;
- struct ovly_sect *ovly_section;
- int status = 0;
-
- ovly_section = last_sect = *lst;
- *exists = false;
- while (ovly_section) {
- /*
- * Make sure section has not already been added. Multiple
- * 'write' calls may be made to load the section.
- */
- if (ovly_section->sect_load_addr == addr) {
- /* Already added */
- *exists = true;
- break;
- }
- last_sect = ovly_section;
- ovly_section = ovly_section->next_sect;
- }
-
- if (!ovly_section) {
- /* New section */
- new_sect = kzalloc(sizeof(struct ovly_sect), GFP_KERNEL);
- if (new_sect == NULL) {
- status = -ENOMEM;
- } else {
- new_sect->sect_load_addr = addr;
- new_sect->sect_run_addr = sect_inf->sect_run_addr +
- (addr - sect_inf->sect_load_addr);
- new_sect->size = bytes;
- new_sect->page = sect_inf->type;
- }
-
- /* Add to the list */
- if (!status) {
- if (*lst == NULL) {
- /* First in the list */
- *lst = new_sect;
- } else {
- last_sect->next_sect = new_sect;
- }
- }
- }
-
- return status;
-}
-
-/*
- * ======== fake_ovly_write ========
- */
-static s32 fake_ovly_write(void *handle, u32 dsp_address, void *buf, u32 bytes,
- s32 mtype)
-{
- return (s32) bytes;
-}
-
-/*
- * ======== free_sects ========
- */
-static void free_sects(struct nldr_object *nldr_obj,
- struct ovly_sect *phase_sects, u16 alloc_num)
-{
- struct ovly_sect *ovly_section = phase_sects;
- u16 i = 0;
- bool ret;
-
- while (ovly_section && i < alloc_num) {
- /* 'Deallocate' */
- /* segid - page not supported yet */
- /* Reserved memory */
- ret =
- rmm_free(nldr_obj->rmm, 0, ovly_section->sect_run_addr,
- ovly_section->size, true);
- ovly_section = ovly_section->next_sect;
- i++;
- }
-}
-
-/*
- * ======== get_symbol_value ========
- * Find symbol in library's base image. If not there, check dependent
- * libraries.
- */
-static bool get_symbol_value(void *handle, void *parg, void *rmm_handle,
- char *sym_name, struct dbll_sym_val **sym)
-{
- struct nldr_object *nldr_obj = (struct nldr_object *)handle;
- struct nldr_nodeobject *nldr_node_obj =
- (struct nldr_nodeobject *)rmm_handle;
- struct lib_node *root = (struct lib_node *)parg;
- u16 i;
- bool status = false;
-
- /* check the base image */
- status = nldr_obj->ldr_fxns.get_addr_fxn(nldr_obj->base_lib,
- sym_name, sym);
- if (!status)
- status =
- nldr_obj->ldr_fxns.get_c_addr_fxn(nldr_obj->base_lib,
- sym_name, sym);
-
- /*
- * Check in root lib itself. If the library consists of
- * multiple object files linked together, some symbols in the
- * library may need to be resolved.
- */
- if (!status) {
- status = nldr_obj->ldr_fxns.get_addr_fxn(root->lib, sym_name,
- sym);
- if (!status) {
- status =
- nldr_obj->ldr_fxns.get_c_addr_fxn(root->lib,
- sym_name, sym);
- }
- }
-
- /*
- * Check in root lib's dependent libraries, but not dependent
- * libraries' dependents.
- */
- if (!status) {
- for (i = 0; i < root->dep_libs; i++) {
- status =
- nldr_obj->ldr_fxns.get_addr_fxn(root->
- dep_libs_tree
- [i].lib,
- sym_name, sym);
- if (!status) {
- status =
- nldr_obj->ldr_fxns.
- get_c_addr_fxn(root->dep_libs_tree[i].lib,
- sym_name, sym);
- }
- if (status) {
- /* Symbol found */
- break;
- }
- }
- }
- /*
- * Check in persistent libraries
- */
- if (!status) {
- for (i = 0; i < nldr_node_obj->pers_libs; i++) {
- status =
- nldr_obj->ldr_fxns.
- get_addr_fxn(nldr_node_obj->pers_lib_table[i].lib,
- sym_name, sym);
- if (!status) {
- status = nldr_obj->ldr_fxns.get_c_addr_fxn
- (nldr_node_obj->pers_lib_table[i].lib,
- sym_name, sym);
- }
- if (status) {
- /* Symbol found */
- break;
- }
- }
- }
-
- return status;
-}
-
-/*
- * ======== load_lib ========
- * Recursively load library and all its dependent libraries. The library
- * we're loading is specified by a uuid.
- */
-static int load_lib(struct nldr_nodeobject *nldr_node_obj,
- struct lib_node *root, struct dsp_uuid uuid,
- bool root_prstnt,
- struct dbll_library_obj **lib_path,
- enum nldr_phase phase, u16 depth)
-{
- struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
- u16 nd_libs = 0; /* Number of dependent libraries */
- u16 np_libs = 0; /* Number of persistent libraries */
- u16 nd_libs_loaded = 0; /* Number of dep. libraries loaded */
- u16 i;
- u32 entry;
- u32 dw_buf_size = NLDR_MAXPATHLENGTH;
- dbll_flags flags = DBLL_SYMB | DBLL_CODE | DBLL_DATA | DBLL_DYNAMIC;
- struct dbll_attrs new_attrs;
- char *psz_file_name = NULL;
- struct dsp_uuid *dep_lib_uui_ds = NULL;
- bool *persistent_dep_libs = NULL;
- int status = 0;
- bool lib_status = false;
- struct lib_node *dep_lib;
-
- if (depth > MAXDEPTH) {
- /* Error */
- }
- root->lib = NULL;
- /* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */
- psz_file_name = kzalloc(DBLL_MAXPATHLENGTH, GFP_KERNEL);
- if (psz_file_name == NULL)
- status = -ENOMEM;
-
- if (!status) {
- /* Get the name of the library */
- if (depth == 0) {
- status =
- dcd_get_library_name(nldr_node_obj->nldr_obj->
- dcd_mgr, &uuid, psz_file_name,
- &dw_buf_size, phase,
- nldr_node_obj->phase_split);
- } else {
- /* Dependent libraries are registered with a phase */
- status =
- dcd_get_library_name(nldr_node_obj->nldr_obj->
- dcd_mgr, &uuid, psz_file_name,
- &dw_buf_size, NLDR_NOPHASE,
- NULL);
- }
- }
- if (!status) {
- /* Open the library, don't load symbols */
- status =
- nldr_obj->ldr_fxns.open_fxn(nldr_obj->dbll, psz_file_name,
- DBLL_NOLOAD, &root->lib);
- }
- /* Done with file name */
- kfree(psz_file_name);
-
- /* Check to see if library not already loaded */
- if (!status && root_prstnt) {
- lib_status =
- find_in_persistent_lib_array(nldr_node_obj, root->lib);
- /* Close library */
- if (lib_status) {
- nldr_obj->ldr_fxns.close_fxn(root->lib);
- return 0;
- }
- }
- if (!status) {
- /* Check for circular dependencies. */
- for (i = 0; i < depth; i++) {
- if (root->lib == lib_path[i]) {
- /* This condition could be checked by a
- * tool at build time. */
- status = -EILSEQ;
- }
- }
- }
- if (!status) {
- /* Add library to current path in dependency tree */
- lib_path[depth] = root->lib;
- depth++;
- /* Get number of dependent libraries */
- status =
- dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->dcd_mgr,
- &uuid, &nd_libs, &np_libs, phase);
- }
- if (!status) {
- if (!(*nldr_node_obj->phase_split))
- np_libs = 0;
-
- /* nd_libs = #of dependent libraries */
- root->dep_libs = nd_libs - np_libs;
- if (nd_libs > 0) {
- dep_lib_uui_ds = kzalloc(sizeof(struct dsp_uuid) *
- nd_libs, GFP_KERNEL);
- persistent_dep_libs =
- kzalloc(sizeof(bool) * nd_libs, GFP_KERNEL);
- if (!dep_lib_uui_ds || !persistent_dep_libs)
- status = -ENOMEM;
-
- if (root->dep_libs > 0) {
- /* Allocate arrays for dependent lib UUIDs,
- * lib nodes */
- root->dep_libs_tree = kzalloc
- (sizeof(struct lib_node) *
- (root->dep_libs), GFP_KERNEL);
- if (!(root->dep_libs_tree))
- status = -ENOMEM;
-
- }
-
- if (!status) {
- /* Get the dependent library UUIDs */
- status =
- dcd_get_dep_libs(nldr_node_obj->
- nldr_obj->dcd_mgr, &uuid,
- nd_libs, dep_lib_uui_ds,
- persistent_dep_libs,
- phase);
- }
- }
- }
-
- /*
- * Recursively load dependent libraries.
- */
- if (!status) {
- for (i = 0; i < nd_libs; i++) {
- /* If root library is NOT persistent, and dep library
- * is, then record it. If root library IS persistent,
- * the deplib is already included */
- if (!root_prstnt && persistent_dep_libs[i] &&
- *nldr_node_obj->phase_split) {
- if ((nldr_node_obj->pers_libs) >= MAXLIBS) {
- status = -EILSEQ;
- break;
- }
-
- /* Allocate library outside of phase */
- dep_lib =
- &nldr_node_obj->pers_lib_table
- [nldr_node_obj->pers_libs];
- } else {
- if (root_prstnt)
- persistent_dep_libs[i] = true;
-
- /* Allocate library within phase */
- dep_lib = &root->dep_libs_tree[nd_libs_loaded];
- }
-
- status = load_lib(nldr_node_obj, dep_lib,
- dep_lib_uui_ds[i],
- persistent_dep_libs[i], lib_path,
- phase, depth);
-
- if (!status) {
- if ((status != 0) &&
- !root_prstnt && persistent_dep_libs[i] &&
- *nldr_node_obj->phase_split) {
- (nldr_node_obj->pers_libs)++;
- } else {
- if (!persistent_dep_libs[i] ||
- !(*nldr_node_obj->phase_split)) {
- nd_libs_loaded++;
- }
- }
- } else {
- break;
- }
- }
- }
-
- /* Now we can load the root library */
- if (!status) {
- new_attrs = nldr_obj->ldr_attrs;
- new_attrs.sym_arg = root;
- new_attrs.rmm_handle = nldr_node_obj;
- new_attrs.input_params = nldr_node_obj->priv_ref;
- new_attrs.base_image = false;
-
- status =
- nldr_obj->ldr_fxns.load_fxn(root->lib, flags, &new_attrs,
- &entry);
- }
-
- /*
- * In case of failure, unload any dependent libraries that
- * were loaded, and close the root library.
- * (Persistent libraries are unloaded from the very top)
- */
- if (status) {
- if (phase != NLDR_EXECUTE) {
- for (i = 0; i < nldr_node_obj->pers_libs; i++)
- unload_lib(nldr_node_obj,
- &nldr_node_obj->pers_lib_table[i]);
-
- nldr_node_obj->pers_libs = 0;
- }
- for (i = 0; i < nd_libs_loaded; i++)
- unload_lib(nldr_node_obj, &root->dep_libs_tree[i]);
-
- if (root->lib)
- nldr_obj->ldr_fxns.close_fxn(root->lib);
-
- }
-
- /* Going up one node in the dependency tree */
- depth--;
-
- kfree(dep_lib_uui_ds);
- dep_lib_uui_ds = NULL;
-
- kfree(persistent_dep_libs);
- persistent_dep_libs = NULL;
-
- return status;
-}
-
-/*
- * ======== load_ovly ========
- */
-static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase)
-{
- struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
- struct ovly_node *po_node = NULL;
- struct ovly_sect *phase_sects = NULL;
- struct ovly_sect *other_sects_list = NULL;
- u16 i;
- u16 alloc_num = 0;
- u16 other_alloc = 0;
- u16 *ref_count = NULL;
- u16 *other_ref = NULL;
- u32 bytes;
- struct ovly_sect *ovly_section;
- int status = 0;
-
- /* Find the node in the table */
- for (i = 0; i < nldr_obj->ovly_nodes; i++) {
- if (is_equal_uuid
- (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) {
- /* Found it */
- po_node = &(nldr_obj->ovly_table[i]);
- break;
- }
- }
-
-
- if (!po_node) {
- status = -ENOENT;
- goto func_end;
- }
-
- switch (phase) {
- case NLDR_CREATE:
- ref_count = &(po_node->create_ref);
- other_ref = &(po_node->other_ref);
- phase_sects = po_node->create_sects_list;
- other_sects_list = po_node->other_sects_list;
- break;
-
- case NLDR_EXECUTE:
- ref_count = &(po_node->execute_ref);
- phase_sects = po_node->execute_sects_list;
- break;
-
- case NLDR_DELETE:
- ref_count = &(po_node->delete_ref);
- phase_sects = po_node->delete_sects_list;
- break;
-
- default:
- break;
- }
-
- if (ref_count == NULL)
- goto func_end;
-
- if (*ref_count != 0)
- goto func_end;
-
- /* 'Allocate' memory for overlay sections of this phase */
- ovly_section = phase_sects;
- while (ovly_section) {
- /* allocate *//* page not supported yet */
- /* reserve *//* align */
- status = rmm_alloc(nldr_obj->rmm, 0, ovly_section->size, 0,
- &(ovly_section->sect_run_addr), true);
- if (!status) {
- ovly_section = ovly_section->next_sect;
- alloc_num++;
- } else {
- break;
- }
- }
- if (other_ref && *other_ref == 0) {
- /* 'Allocate' memory for other overlay sections
- * (create phase) */
- if (!status) {
- ovly_section = other_sects_list;
- while (ovly_section) {
- /* page not supported *//* align */
- /* reserve */
- status =
- rmm_alloc(nldr_obj->rmm, 0,
- ovly_section->size, 0,
- &(ovly_section->sect_run_addr),
- true);
- if (!status) {
- ovly_section = ovly_section->next_sect;
- other_alloc++;
- } else {
- break;
- }
- }
- }
- }
- if (*ref_count == 0) {
- if (!status) {
- /* Load sections for this phase */
- ovly_section = phase_sects;
- while (ovly_section && !status) {
- bytes =
- (*nldr_obj->ovly_fxn) (nldr_node_obj->
- priv_ref,
- ovly_section->
- sect_run_addr,
- ovly_section->
- sect_load_addr,
- ovly_section->size,
- ovly_section->page);
- if (bytes != ovly_section->size)
- status = -EPERM;
-
- ovly_section = ovly_section->next_sect;
- }
- }
- }
- if (other_ref && *other_ref == 0) {
- if (!status) {
- /* Load other sections (create phase) */
- ovly_section = other_sects_list;
- while (ovly_section && !status) {
- bytes =
- (*nldr_obj->ovly_fxn) (nldr_node_obj->
- priv_ref,
- ovly_section->
- sect_run_addr,
- ovly_section->
- sect_load_addr,
- ovly_section->size,
- ovly_section->page);
- if (bytes != ovly_section->size)
- status = -EPERM;
-
- ovly_section = ovly_section->next_sect;
- }
- }
- }
- if (status) {
- /* 'Deallocate' memory */
- free_sects(nldr_obj, phase_sects, alloc_num);
- free_sects(nldr_obj, other_sects_list, other_alloc);
- }
-func_end:
- if (!status && (ref_count != NULL)) {
- *ref_count += 1;
- if (other_ref)
- *other_ref += 1;
-
- }
-
- return status;
-}
-
-/*
- * ======== remote_alloc ========
- */
-static int remote_alloc(void **ref, u16 mem_sect, u32 size,
- u32 align, u32 *dsp_address,
- s32 segmnt_id, s32 req,
- bool reserve)
-{
- struct nldr_nodeobject *hnode = (struct nldr_nodeobject *)ref;
- struct nldr_object *nldr_obj;
- struct rmm_target_obj *rmm;
- u16 mem_phase_bit = MAXFLAGS;
- u16 segid = 0;
- u16 i;
- u16 mem_sect_type;
- u32 word_size;
- struct rmm_addr *rmm_addr_obj = (struct rmm_addr *)dsp_address;
- bool mem_load_req = false;
- int status = -ENOMEM; /* Set to fail */
- nldr_obj = hnode->nldr_obj;
- rmm = nldr_obj->rmm;
- /* Convert size to DSP words */
- word_size =
- (size + nldr_obj->dsp_word_size -
- 1) / nldr_obj->dsp_word_size;
- /* Modify memory 'align' to account for DSP cache line size */
- align = lcm(GEM_CACHE_LINE_SIZE, align);
- dev_dbg(bridge, "%s: memory align to 0x%x\n", __func__, align);
- if (segmnt_id != -1) {
- rmm_addr_obj->segid = segmnt_id;
- segid = segmnt_id;
- mem_load_req = req;
- } else {
- switch (hnode->phase) {
- case NLDR_CREATE:
- mem_phase_bit = CREATEDATAFLAGBIT;
- break;
- case NLDR_DELETE:
- mem_phase_bit = DELETEDATAFLAGBIT;
- break;
- case NLDR_EXECUTE:
- mem_phase_bit = EXECUTEDATAFLAGBIT;
- break;
- default:
- break;
- }
- if (mem_sect == DBLL_CODE)
- mem_phase_bit++;
-
- if (mem_phase_bit < MAXFLAGS)
- segid = hnode->seg_id[mem_phase_bit];
-
- /* Determine if there is a memory loading requirement */
- if ((hnode->code_data_flag_mask >> mem_phase_bit) & 0x1)
- mem_load_req = true;
-
- }
- mem_sect_type = (mem_sect == DBLL_CODE) ? DYNM_CODE : DYNM_DATA;
-
- /* Find an appropriate segment based on mem_sect */
- if (segid == NULLID) {
- /* No memory requirements of preferences */
- goto func_cont;
- }
- if (segid <= MAXSEGID) {
- /* Attempt to allocate from segid first. */
- rmm_addr_obj->segid = segid;
- status =
- rmm_alloc(rmm, segid, word_size, align, dsp_address, false);
- if (status) {
- dev_dbg(bridge, "%s: Unable allocate from segment %d\n",
- __func__, segid);
- }
- } else {
- /* segid > MAXSEGID ==> Internal or external memory */
- /* Check for any internal or external memory segment,
- * depending on segid. */
- mem_sect_type |= segid == MEMINTERNALID ?
- DYNM_INTERNAL : DYNM_EXTERNAL;
- for (i = 0; i < nldr_obj->dload_segs; i++) {
- if ((nldr_obj->seg_table[i] & mem_sect_type) !=
- mem_sect_type)
- continue;
-
- status = rmm_alloc(rmm, i, word_size, align,
- dsp_address, false);
- if (!status) {
- /* Save segid for freeing later */
- rmm_addr_obj->segid = i;
- break;
- }
- }
- }
-func_cont:
- /* Haven't found memory yet, attempt to find any segment that works */
- if (status == -ENOMEM && !mem_load_req) {
- dev_dbg(bridge, "%s: Preferred segment unavailable, trying "
- "another\n", __func__);
- for (i = 0; i < nldr_obj->dload_segs; i++) {
- /* All bits of mem_sect_type must be set */
- if ((nldr_obj->seg_table[i] & mem_sect_type) !=
- mem_sect_type)
- continue;
-
- status = rmm_alloc(rmm, i, word_size, align,
- dsp_address, false);
- if (!status) {
- /* Save segid */
- rmm_addr_obj->segid = i;
- break;
- }
- }
- }
-
- return status;
-}
-
-static int remote_free(void **ref, u16 space, u32 dsp_address,
- u32 size, bool reserve)
-{
- struct nldr_object *nldr_obj = (struct nldr_object *)ref;
- struct rmm_target_obj *rmm;
- u32 word_size;
- int status = -ENOMEM; /* Set to fail */
-
- rmm = nldr_obj->rmm;
-
- /* Convert size to DSP words */
- word_size =
- (size + nldr_obj->dsp_word_size -
- 1) / nldr_obj->dsp_word_size;
-
- if (rmm_free(rmm, space, dsp_address, word_size, reserve))
- status = 0;
-
- return status;
-}
-
-/*
- * ======== unload_lib ========
- */
-static void unload_lib(struct nldr_nodeobject *nldr_node_obj,
- struct lib_node *root)
-{
- struct dbll_attrs new_attrs;
- struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
- u16 i;
-
-
- /* Unload dependent libraries */
- for (i = 0; i < root->dep_libs; i++)
- unload_lib(nldr_node_obj, &root->dep_libs_tree[i]);
-
- root->dep_libs = 0;
-
- new_attrs = nldr_obj->ldr_attrs;
- new_attrs.rmm_handle = nldr_obj->rmm;
- new_attrs.input_params = nldr_node_obj->priv_ref;
- new_attrs.base_image = false;
- new_attrs.sym_arg = root;
-
- if (root->lib) {
- /* Unload the root library */
- nldr_obj->ldr_fxns.unload_fxn(root->lib, &new_attrs);
- nldr_obj->ldr_fxns.close_fxn(root->lib);
- }
-
- /* Free dependent library list */
- kfree(root->dep_libs_tree);
- root->dep_libs_tree = NULL;
-}
-
-/*
- * ======== unload_ovly ========
- */
-static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
- enum nldr_phase phase)
-{
- struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
- struct ovly_node *po_node = NULL;
- struct ovly_sect *phase_sects = NULL;
- struct ovly_sect *other_sects_list = NULL;
- u16 i;
- u16 alloc_num = 0;
- u16 other_alloc = 0;
- u16 *ref_count = NULL;
- u16 *other_ref = NULL;
-
- /* Find the node in the table */
- for (i = 0; i < nldr_obj->ovly_nodes; i++) {
- if (is_equal_uuid
- (&nldr_node_obj->uuid, &nldr_obj->ovly_table[i].uuid)) {
- /* Found it */
- po_node = &(nldr_obj->ovly_table[i]);
- break;
- }
- }
-
-
- if (!po_node)
- /* TODO: Should we print warning here? */
- return;
-
- switch (phase) {
- case NLDR_CREATE:
- ref_count = &(po_node->create_ref);
- phase_sects = po_node->create_sects_list;
- alloc_num = po_node->create_sects;
- break;
- case NLDR_EXECUTE:
- ref_count = &(po_node->execute_ref);
- phase_sects = po_node->execute_sects_list;
- alloc_num = po_node->execute_sects;
- break;
- case NLDR_DELETE:
- ref_count = &(po_node->delete_ref);
- other_ref = &(po_node->other_ref);
- phase_sects = po_node->delete_sects_list;
- /* 'Other' overlay sections are unloaded in the delete phase */
- other_sects_list = po_node->other_sects_list;
- alloc_num = po_node->delete_sects;
- other_alloc = po_node->other_sects;
- break;
- default:
- break;
- }
- if (ref_count && (*ref_count > 0)) {
- *ref_count -= 1;
- if (other_ref)
- *other_ref -= 1;
- }
-
- if (ref_count && *ref_count == 0) {
- /* 'Deallocate' memory */
- free_sects(nldr_obj, phase_sects, alloc_num);
- }
- if (other_ref && *other_ref == 0)
- free_sects(nldr_obj, other_sects_list, other_alloc);
-}
-
-/*
- * ======== find_in_persistent_lib_array ========
- */
-static bool find_in_persistent_lib_array(struct nldr_nodeobject *nldr_node_obj,
- struct dbll_library_obj *lib)
-{
- s32 i = 0;
-
- for (i = 0; i < nldr_node_obj->pers_libs; i++) {
- if (lib == nldr_node_obj->pers_lib_table[i].lib)
- return true;
-
- }
-
- return false;
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/**
- * nldr_find_addr() - Find the closest symbol to the given address based on
- * dynamic node object.
- *
- * @nldr_node: Dynamic node object
- * @sym_addr: Given address to find the dsp symbol
- * @offset_range: offset range to look for dsp symbol
- * @offset_output: Symbol Output address
- * @sym_name: String with the dsp symbol
- *
- * This function finds the node library for a given address and
- * retrieves the dsp symbol by calling dbll_find_dsp_symbol.
- */
-int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
- u32 offset_range, void *offset_output, char *sym_name)
-{
- int status = 0;
- bool status1 = false;
- s32 i = 0;
- struct lib_node root = { NULL, 0, NULL };
-
- if (nldr_node->dynamic && *nldr_node->phase_split) {
- switch (nldr_node->phase) {
- case NLDR_CREATE:
- root = nldr_node->create_lib;
- break;
- case NLDR_EXECUTE:
- root = nldr_node->execute_lib;
- break;
- case NLDR_DELETE:
- root = nldr_node->delete_lib;
- break;
- default:
- break;
- }
- } else {
- /* for Overlay nodes or non-split Dynamic nodes */
- root = nldr_node->root;
- }
-
- status1 = dbll_find_dsp_symbol(root.lib, sym_addr,
- offset_range, offset_output, sym_name);
-
- /* If symbol not found, check dependent libraries */
- if (!status1)
- for (i = 0; i < root.dep_libs; i++) {
- status1 = dbll_find_dsp_symbol(
- root.dep_libs_tree[i].lib, sym_addr,
- offset_range, offset_output, sym_name);
- if (status1)
- /* Symbol found */
- break;
- }
- /* Check persistent libraries */
- if (!status1)
- for (i = 0; i < nldr_node->pers_libs; i++) {
- status1 = dbll_find_dsp_symbol(
- nldr_node->pers_lib_table[i].lib, sym_addr,
- offset_range, offset_output, sym_name);
- if (status1)
- /* Symbol found */
- break;
- }
-
- if (!status1) {
- pr_debug("%s: Address 0x%x not found in range %d.\n",
- __func__, sym_addr, offset_range);
- status = -ESPIPE;
- } else {
- pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n",
- __func__, (u32) nldr_node, sym_addr, offset_range,
- (u32) offset_output, sym_name);
- }
-
- return status;
-}
-#endif
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
deleted file mode 100644
index 9d3044a384ee..000000000000
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ /dev/null
@@ -1,3029 +0,0 @@
-/*
- * node.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Node Manager.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-#include <linux/bitmap.h>
-#include <linux/list.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/memdefs.h>
-#include <dspbridge/proc.h>
-#include <dspbridge/strm.h>
-#include <dspbridge/sync.h>
-#include <dspbridge/ntfy.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/cmm.h>
-#include <dspbridge/cod.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/msg.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/dbdcd.h>
-#include <dspbridge/disp.h>
-#include <dspbridge/rms_sh.h>
-
-/* ----------------------------------- Link Driver */
-#include <dspbridge/dspdefs.h>
-#include <dspbridge/dspioctl.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/uuidutil.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/nodepriv.h>
-#include <dspbridge/node.h>
-#include <dspbridge/dmm.h>
-
-/* Static/Dynamic Loader includes */
-#include <dspbridge/dbll.h>
-#include <dspbridge/nldr.h>
-
-#include <dspbridge/drv.h>
-#include <dspbridge/resourcecleanup.h>
-#include <_tiomap.h>
-
-#include <dspbridge/dspdeh.h>
-
-#define HOSTPREFIX "/host"
-#define PIPEPREFIX "/dbpipe"
-
-#define MAX_INPUTS(h) \
- ((h)->dcd_props.obj_data.node_obj.ndb_props.num_input_streams)
-#define MAX_OUTPUTS(h) \
- ((h)->dcd_props.obj_data.node_obj.ndb_props.num_output_streams)
-
-#define NODE_GET_PRIORITY(h) ((h)->prio)
-#define NODE_SET_PRIORITY(hnode, prio) ((hnode)->prio = prio)
-#define NODE_SET_STATE(hnode, state) ((hnode)->node_state = state)
-
-#define MAXPIPES 100 /* Max # of /pipe connections (CSL limit) */
-#define MAXDEVSUFFIXLEN 2 /* Max(Log base 10 of MAXPIPES, MAXSTREAMS) */
-
-#define PIPENAMELEN (sizeof(PIPEPREFIX) + MAXDEVSUFFIXLEN)
-#define HOSTNAMELEN (sizeof(HOSTPREFIX) + MAXDEVSUFFIXLEN)
-
-#define MAXDEVNAMELEN 32 /* dsp_ndbprops.ac_name size */
-#define CREATEPHASE 1
-#define EXECUTEPHASE 2
-#define DELETEPHASE 3
-
-/* Define default STRM parameters */
-/*
- * TBD: Put in header file, make global DSP_STRMATTRS with defaults,
- * or make defaults configurable.
- */
-#define DEFAULTBUFSIZE 32
-#define DEFAULTNBUFS 2
-#define DEFAULTSEGID 0
-#define DEFAULTALIGNMENT 0
-#define DEFAULTTIMEOUT 10000
-
-#define RMSQUERYSERVER 0
-#define RMSCONFIGURESERVER 1
-#define RMSCREATENODE 2
-#define RMSEXECUTENODE 3
-#define RMSDELETENODE 4
-#define RMSCHANGENODEPRIORITY 5
-#define RMSREADMEMORY 6
-#define RMSWRITEMEMORY 7
-#define RMSCOPY 8
-#define MAXTIMEOUT 2000
-
-#define NUMRMSFXNS 9
-
-#define PWR_TIMEOUT 500 /* default PWR timeout in msec */
-
-#define STACKSEGLABEL "L1DSRAM_HEAP" /* Label for DSP Stack Segment Addr */
-
-/*
- * ======== node_mgr ========
- */
-struct node_mgr {
- struct dev_object *dev_obj; /* Device object */
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
- struct dcd_manager *dcd_mgr; /* Proc/Node data manager */
- struct disp_object *disp_obj; /* Node dispatcher */
- struct list_head node_list; /* List of all allocated nodes */
- u32 num_nodes; /* Number of nodes in node_list */
- u32 num_created; /* Number of nodes *created* on DSP */
- DECLARE_BITMAP(pipe_map, MAXPIPES); /* Pipe connection bitmap */
- DECLARE_BITMAP(pipe_done_map, MAXPIPES); /* Pipes that are half free */
- /* Channel allocation bitmap */
- DECLARE_BITMAP(chnl_map, CHNL_MAXCHANNELS);
- /* DMA Channel allocation bitmap */
- DECLARE_BITMAP(dma_chnl_map, CHNL_MAXCHANNELS);
- /* Zero-Copy Channel alloc bitmap */
- DECLARE_BITMAP(zc_chnl_map, CHNL_MAXCHANNELS);
- struct ntfy_object *ntfy_obj; /* Manages registered notifications */
- struct mutex node_mgr_lock; /* For critical sections */
- u32 fxn_addrs[NUMRMSFXNS]; /* RMS function addresses */
- struct msg_mgr *msg_mgr_obj;
-
- /* Processor properties needed by Node Dispatcher */
- u32 num_chnls; /* Total number of channels */
- u32 chnl_offset; /* Offset of chnl ids rsvd for RMS */
- u32 chnl_buf_size; /* Buffer size for data to RMS */
- int proc_family; /* eg, 5000 */
- int proc_type; /* eg, 5510 */
- u32 dsp_word_size; /* Size of DSP word on host bytes */
- u32 dsp_data_mau_size; /* Size of DSP data MAU */
- u32 dsp_mau_size; /* Size of MAU */
- s32 min_pri; /* Minimum runtime priority for node */
- s32 max_pri; /* Maximum runtime priority for node */
-
- struct strm_mgr *strm_mgr_obj; /* STRM manager */
-
- /* Loader properties */
- struct nldr_object *nldr_obj; /* Handle to loader */
- struct node_ldr_fxns nldr_fxns; /* Handle to loader functions */
-};
-
-/*
- * ======== connecttype ========
- */
-enum connecttype {
- NOTCONNECTED = 0,
- NODECONNECT,
- HOSTCONNECT,
- DEVICECONNECT,
-};
-
-/*
- * ======== stream_chnl ========
- */
-struct stream_chnl {
- enum connecttype type; /* Type of stream connection */
- u32 dev_id; /* pipe or channel id */
-};
-
-/*
- * ======== node_object ========
- */
-struct node_object {
- struct list_head list_elem;
- struct node_mgr *node_mgr; /* The manager of this node */
- struct proc_object *processor; /* Back pointer to processor */
- struct dsp_uuid node_uuid; /* Node's ID */
- s32 prio; /* Node's current priority */
- u32 timeout; /* Timeout for blocking NODE calls */
- u32 heap_size; /* Heap Size */
- u32 dsp_heap_virt_addr; /* Heap Size */
- u32 gpp_heap_virt_addr; /* Heap Size */
- enum node_type ntype; /* Type of node: message, task, etc */
- enum node_state node_state; /* NODE_ALLOCATED, NODE_CREATED, ... */
- u32 num_inputs; /* Current number of inputs */
- u32 num_outputs; /* Current number of outputs */
- u32 max_input_index; /* Current max input stream index */
- u32 max_output_index; /* Current max output stream index */
- struct stream_chnl *inputs; /* Node's input streams */
- struct stream_chnl *outputs; /* Node's output streams */
- struct node_createargs create_args; /* Args for node create func */
- nodeenv node_env; /* Environment returned by RMS */
- struct dcd_genericobj dcd_props; /* Node properties from DCD */
- struct dsp_cbdata *args; /* Optional args to pass to node */
- struct ntfy_object *ntfy_obj; /* Manages registered notifications */
- char *str_dev_name; /* device name, if device node */
- struct sync_object *sync_done; /* Synchronize node_terminate */
- s32 exit_status; /* execute function return status */
-
- /* Information needed for node_get_attr() */
- void *device_owner; /* If dev node, task that owns it */
- u32 num_gpp_inputs; /* Current # of from GPP streams */
- u32 num_gpp_outputs; /* Current # of to GPP streams */
- /* Current stream connections */
- struct dsp_streamconnect *stream_connect;
-
- /* Message queue */
- struct msg_queue *msg_queue_obj;
-
- /* These fields used for SM messaging */
- struct cmm_xlatorobject *xlator; /* Node's SM addr translator */
-
- /* Handle to pass to dynamic loader */
- struct nldr_nodeobject *nldr_node_obj;
- bool loaded; /* Code is (dynamically) loaded */
- bool phase_split; /* Phases split in many libs or ovly */
-
-};
-
-/* Default buffer attributes */
-static struct dsp_bufferattr node_dfltbufattrs = {
- .cb_struct = 0,
- .segment_id = 1,
- .buf_alignment = 0,
-};
-
-static void delete_node(struct node_object *hnode,
- struct process_context *pr_ctxt);
-static void delete_node_mgr(struct node_mgr *hnode_mgr);
-static void fill_stream_connect(struct node_object *node1,
- struct node_object *node2, u32 stream1,
- u32 stream2);
-static void fill_stream_def(struct node_object *hnode,
- struct node_strmdef *pstrm_def,
- struct dsp_strmattr *pattrs);
-static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream);
-static int get_fxn_address(struct node_object *hnode, u32 *fxn_addr,
- u32 phase);
-static int get_node_props(struct dcd_manager *hdcd_mgr,
- struct node_object *hnode,
- const struct dsp_uuid *node_uuid,
- struct dcd_genericobj *dcd_prop);
-static int get_proc_props(struct node_mgr *hnode_mgr,
- struct dev_object *hdev_obj);
-static int get_rms_fxns(struct node_mgr *hnode_mgr);
-static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
- u32 ul_num_bytes, u32 mem_space);
-static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
- u32 ul_num_bytes, u32 mem_space);
-
-/* Dynamic loader functions. */
-static struct node_ldr_fxns nldr_fxns = {
- nldr_allocate,
- nldr_create,
- nldr_delete,
- nldr_get_fxn_addr,
- nldr_load,
- nldr_unload,
-};
-
-enum node_state node_get_state(void *hnode)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- if (!pnode)
- return -1;
- return pnode->node_state;
-}
-
-/*
- * ======== node_allocate ========
- * Purpose:
- * Allocate GPP resources to manage a node on the DSP.
- */
-int node_allocate(struct proc_object *hprocessor,
- const struct dsp_uuid *node_uuid,
- const struct dsp_cbdata *pargs,
- const struct dsp_nodeattrin *attr_in,
- struct node_res_object **noderes,
- struct process_context *pr_ctxt)
-{
- struct node_mgr *hnode_mgr;
- struct dev_object *hdev_obj;
- struct node_object *pnode = NULL;
- enum node_type node_type = NODE_TASK;
- struct node_msgargs *pmsg_args;
- struct node_taskargs *ptask_args;
- u32 num_streams;
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
- struct cmm_object *hcmm_mgr = NULL; /* Shared memory manager hndl */
- u32 proc_id;
- u32 pul_value;
- u32 dynext_base;
- u32 off_set = 0;
- u32 ul_stack_seg_val;
- struct cfg_hostres *host_res;
- struct bridge_dev_context *pbridge_context;
- u32 mapped_addr = 0;
- u32 map_attrs = 0x0;
- struct dsp_processorstate proc_state;
-#ifdef DSP_DMM_DEBUG
- struct dmm_object *dmm_mgr;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
-#endif
-
- void *node_res;
-
- *noderes = NULL;
-
- status = proc_get_processor_id(hprocessor, &proc_id);
-
- if (proc_id != DSP_UNIT)
- goto func_end;
-
- status = proc_get_dev_object(hprocessor, &hdev_obj);
- if (!status) {
- status = dev_get_node_manager(hdev_obj, &hnode_mgr);
- if (hnode_mgr == NULL)
- status = -EPERM;
-
- }
-
- if (status)
- goto func_end;
-
- status = dev_get_bridge_context(hdev_obj, &pbridge_context);
- if (!pbridge_context) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in error state then don't attempt
- to send the message */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
-
- /* Assuming that 0 is not a valid function address */
- if (hnode_mgr->fxn_addrs[0] == 0) {
- /* No RMS on target - we currently can't handle this */
- pr_err("%s: Failed, no RMS in base image\n", __func__);
- status = -EPERM;
- } else {
- /* Validate attr_in fields, if non-NULL */
- if (attr_in) {
- /* Check if attr_in->prio is within range */
- if (attr_in->prio < hnode_mgr->min_pri ||
- attr_in->prio > hnode_mgr->max_pri)
- status = -EDOM;
- }
- }
- /* Allocate node object and fill in */
- if (status)
- goto func_end;
-
- pnode = kzalloc(sizeof(struct node_object), GFP_KERNEL);
- if (pnode == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
- pnode->node_mgr = hnode_mgr;
- /* This critical section protects get_node_props */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- /* Get dsp_ndbprops from node database */
- status = get_node_props(hnode_mgr->dcd_mgr, pnode, node_uuid,
- &(pnode->dcd_props));
- if (status)
- goto func_cont;
-
- pnode->node_uuid = *node_uuid;
- pnode->processor = hprocessor;
- pnode->ntype = pnode->dcd_props.obj_data.node_obj.ndb_props.ntype;
- pnode->timeout = pnode->dcd_props.obj_data.node_obj.ndb_props.timeout;
- pnode->prio = pnode->dcd_props.obj_data.node_obj.ndb_props.prio;
-
- /* Currently only C64 DSP builds support Node Dynamic * heaps */
- /* Allocate memory for node heap */
- pnode->create_args.asa.task_arg_obj.heap_size = 0;
- pnode->create_args.asa.task_arg_obj.dsp_heap_addr = 0;
- pnode->create_args.asa.task_arg_obj.dsp_heap_res_addr = 0;
- pnode->create_args.asa.task_arg_obj.gpp_heap_addr = 0;
- if (!attr_in)
- goto func_cont;
-
- /* Check if we have a user allocated node heap */
- if (!(attr_in->pgpp_virt_addr))
- goto func_cont;
-
- /* check for page aligned Heap size */
- if (((attr_in->heap_size) & (PG_SIZE4K - 1))) {
- pr_err("%s: node heap size not aligned to 4K, size = 0x%x\n",
- __func__, attr_in->heap_size);
- status = -EINVAL;
- } else {
- pnode->create_args.asa.task_arg_obj.heap_size =
- attr_in->heap_size;
- pnode->create_args.asa.task_arg_obj.gpp_heap_addr =
- (u32) attr_in->pgpp_virt_addr;
- }
- if (status)
- goto func_cont;
-
- status = proc_reserve_memory(hprocessor,
- pnode->create_args.asa.task_arg_obj.
- heap_size + PAGE_SIZE,
- (void **)&(pnode->create_args.asa.
- task_arg_obj.dsp_heap_res_addr),
- pr_ctxt);
- if (status) {
- pr_err("%s: Failed to reserve memory for heap: 0x%x\n",
- __func__, status);
- goto func_cont;
- }
-#ifdef DSP_DMM_DEBUG
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = DSP_EHANDLE;
- goto func_cont;
- }
-
- dmm_mem_map_dump(dmm_mgr);
-#endif
-
- map_attrs |= DSP_MAPLITTLEENDIAN;
- map_attrs |= DSP_MAPELEMSIZE32;
- map_attrs |= DSP_MAPVIRTUALADDR;
- status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr,
- pnode->create_args.asa.task_arg_obj.heap_size,
- (void *)pnode->create_args.asa.task_arg_obj.
- dsp_heap_res_addr, (void **)&mapped_addr, map_attrs,
- pr_ctxt);
- if (status)
- pr_err("%s: Failed to map memory for Heap: 0x%x\n",
- __func__, status);
- else
- pnode->create_args.asa.task_arg_obj.dsp_heap_addr =
- (u32) mapped_addr;
-
-func_cont:
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- if (attr_in != NULL) {
- /* Overrides of NBD properties */
- pnode->timeout = attr_in->timeout;
- pnode->prio = attr_in->prio;
- }
- /* Create object to manage notifications */
- if (!status) {
- pnode->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
- GFP_KERNEL);
- if (pnode->ntfy_obj)
- ntfy_init(pnode->ntfy_obj);
- else
- status = -ENOMEM;
- }
-
- if (!status) {
- node_type = node_get_type(pnode);
- /* Allocate dsp_streamconnect array for device, task, and
- * dais socket nodes. */
- if (node_type != NODE_MESSAGE) {
- num_streams = MAX_INPUTS(pnode) + MAX_OUTPUTS(pnode);
- pnode->stream_connect = kzalloc(num_streams *
- sizeof(struct dsp_streamconnect),
- GFP_KERNEL);
- if (num_streams > 0 && pnode->stream_connect == NULL)
- status = -ENOMEM;
-
- }
- if (!status && (node_type == NODE_TASK ||
- node_type == NODE_DAISSOCKET)) {
- /* Allocate arrays for maintainig stream connections */
- pnode->inputs = kzalloc(MAX_INPUTS(pnode) *
- sizeof(struct stream_chnl), GFP_KERNEL);
- pnode->outputs = kzalloc(MAX_OUTPUTS(pnode) *
- sizeof(struct stream_chnl), GFP_KERNEL);
- ptask_args = &(pnode->create_args.asa.task_arg_obj);
- ptask_args->strm_in_def = kzalloc(MAX_INPUTS(pnode) *
- sizeof(struct node_strmdef),
- GFP_KERNEL);
- ptask_args->strm_out_def = kzalloc(MAX_OUTPUTS(pnode) *
- sizeof(struct node_strmdef),
- GFP_KERNEL);
- if ((MAX_INPUTS(pnode) > 0 && (pnode->inputs == NULL ||
- ptask_args->strm_in_def
- == NULL))
- || (MAX_OUTPUTS(pnode) > 0
- && (pnode->outputs == NULL
- || ptask_args->strm_out_def == NULL)))
- status = -ENOMEM;
- }
- }
- if (!status && (node_type != NODE_DEVICE)) {
- /* Create an event that will be posted when RMS_EXIT is
- * received. */
- pnode->sync_done = kzalloc(sizeof(struct sync_object),
- GFP_KERNEL);
- if (pnode->sync_done)
- sync_init_event(pnode->sync_done);
- else
- status = -ENOMEM;
-
- if (!status) {
- /*Get the shared mem mgr for this nodes dev object */
- status = cmm_get_handle(hprocessor, &hcmm_mgr);
- if (!status) {
- /* Allocate a SM addr translator for this node
- * w/ deflt attr */
- status = cmm_xlator_create(&pnode->xlator,
- hcmm_mgr, NULL);
- }
- }
- if (!status) {
- /* Fill in message args */
- if ((pargs != NULL) && (pargs->cb_data > 0)) {
- pmsg_args =
- &(pnode->create_args.asa.node_msg_args);
- pmsg_args->pdata = kzalloc(pargs->cb_data,
- GFP_KERNEL);
- if (pmsg_args->pdata == NULL) {
- status = -ENOMEM;
- } else {
- pmsg_args->arg_length = pargs->cb_data;
- memcpy(pmsg_args->pdata,
- pargs->node_data,
- pargs->cb_data);
- }
- }
- }
- }
-
- if (!status && node_type != NODE_DEVICE) {
- /* Create a message queue for this node */
- intf_fxns = hnode_mgr->intf_fxns;
- status =
- (*intf_fxns->msg_create_queue) (hnode_mgr->msg_mgr_obj,
- &pnode->msg_queue_obj,
- 0,
- pnode->create_args.asa.
- node_msg_args.max_msgs,
- pnode);
- }
-
- if (!status) {
- /* Create object for dynamic loading */
-
- status = hnode_mgr->nldr_fxns.allocate(hnode_mgr->nldr_obj,
- (void *)pnode,
- &pnode->dcd_props.
- obj_data.node_obj,
- &pnode->
- nldr_node_obj,
- &pnode->phase_split);
- }
-
- /* Compare value read from Node Properties and check if it is same as
- * STACKSEGLABEL, if yes read the Address of STACKSEGLABEL, calculate
- * GPP Address, Read the value in that address and override the
- * stack_seg value in task args */
- if (!status &&
- (char *)pnode->dcd_props.obj_data.node_obj.ndb_props.
- stack_seg_name != NULL) {
- if (strcmp((char *)
- pnode->dcd_props.obj_data.node_obj.ndb_props.
- stack_seg_name, STACKSEGLABEL) == 0) {
- void __iomem *stack_seg;
- u32 stack_seg_pa;
-
- status =
- hnode_mgr->nldr_fxns.
- get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG",
- &dynext_base);
- if (status)
- pr_err("%s: Failed to get addr for DYNEXT_BEG"
- " status = 0x%x\n", __func__, status);
-
- status =
- hnode_mgr->nldr_fxns.
- get_fxn_addr(pnode->nldr_node_obj,
- "L1DSRAM_HEAP", &pul_value);
-
- if (status)
- pr_err("%s: Failed to get addr for L1DSRAM_HEAP"
- " status = 0x%x\n", __func__, status);
-
- host_res = pbridge_context->resources;
- if (!host_res)
- status = -EPERM;
-
- if (status) {
- pr_err("%s: Failed to get host resource, status"
- " = 0x%x\n", __func__, status);
- goto func_end;
- }
-
- off_set = pul_value - dynext_base;
- stack_seg_pa = host_res->mem_phys[1] + off_set;
- stack_seg = ioremap(stack_seg_pa, SZ_32);
- if (!stack_seg) {
- status = -ENOMEM;
- goto func_end;
- }
-
- ul_stack_seg_val = readl(stack_seg);
-
- iounmap(stack_seg);
-
- dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr ="
- " 0x%x\n", __func__, ul_stack_seg_val,
- host_res->mem_base[1] + off_set);
-
- pnode->create_args.asa.task_arg_obj.stack_seg =
- ul_stack_seg_val;
-
- }
- }
-
- if (!status) {
- /* Add the node to the node manager's list of allocated
- * nodes. */
- NODE_SET_STATE(pnode, NODE_ALLOCATED);
-
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- list_add_tail(&pnode->list_elem, &hnode_mgr->node_list);
- ++(hnode_mgr->num_nodes);
-
- /* Exit critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-
- /* Preset this to assume phases are split
- * (for overlay and dll) */
- pnode->phase_split = true;
-
- /* Notify all clients registered for DSP_NODESTATECHANGE. */
- proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE);
- } else {
- /* Cleanup */
- if (pnode)
- delete_node(pnode, pr_ctxt);
-
- }
-
- if (!status) {
- status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt);
- if (status) {
- delete_node(pnode, pr_ctxt);
- goto func_end;
- }
-
- *noderes = (struct node_res_object *)node_res;
- drv_proc_node_update_heap_status(node_res, true);
- drv_proc_node_update_status(node_res, true);
- }
-func_end:
- dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
- "node_res: %p status: 0x%x\n", __func__, hprocessor,
- node_uuid, pargs, attr_in, noderes, status);
- return status;
-}
-
-/*
- * ======== node_alloc_msg_buf ========
- * Purpose:
- * Allocates buffer for zero copy messaging.
- */
-DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
- struct dsp_bufferattr *pattr,
- u8 **pbuffer)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- int status = 0;
- bool va_flag = false;
- bool set_info;
- u32 proc_id;
-
- if (!pnode)
- status = -EFAULT;
- else if (node_get_type(pnode) == NODE_DEVICE)
- status = -EPERM;
-
- if (status)
- goto func_end;
-
- if (pattr == NULL)
- pattr = &node_dfltbufattrs; /* set defaults */
-
- status = proc_get_processor_id(pnode->processor, &proc_id);
- if (proc_id != DSP_UNIT)
- goto func_end;
-
- /* If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a
- * virt address, so set this info in this node's translator
- * object for future ref. If MEM_GETVIRTUALSEGID then retrieve
- * virtual address from node's translator. */
- if ((pattr->segment_id & MEM_SETVIRTUALSEGID) ||
- (pattr->segment_id & MEM_GETVIRTUALSEGID)) {
- va_flag = true;
- set_info = (pattr->segment_id & MEM_SETVIRTUALSEGID) ?
- true : false;
- /* Clear mask bits */
- pattr->segment_id &= ~MEM_MASKVIRTUALSEGID;
- /* Set/get this node's translators virtual address base/size */
- status = cmm_xlator_info(pnode->xlator, pbuffer, usize,
- pattr->segment_id, set_info);
- }
- if (!status && (!va_flag)) {
- if (pattr->segment_id != 1) {
- /* Node supports single SM segment only. */
- status = -EBADR;
- }
- /* Arbitrary SM buffer alignment not supported for host side
- * allocs, but guaranteed for the following alignment
- * values. */
- switch (pattr->buf_alignment) {
- case 0:
- case 1:
- case 2:
- case 4:
- break;
- default:
- /* alignment value not supportted */
- status = -EPERM;
- break;
- }
- if (!status) {
- /* allocate physical buffer from seg_id in node's
- * translator */
- (void)cmm_xlator_alloc_buf(pnode->xlator, pbuffer,
- usize);
- if (*pbuffer == NULL) {
- pr_err("%s: error - Out of shared memory\n",
- __func__);
- status = -ENOMEM;
- }
- }
- }
-func_end:
- return status;
-}
-
-/*
- * ======== node_change_priority ========
- * Purpose:
- * Change the priority of a node in the allocated state, or that is
- * currently running or paused on the target.
- */
-int node_change_priority(struct node_object *hnode, s32 prio)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- struct node_mgr *hnode_mgr = NULL;
- enum node_type node_type;
- enum node_state state;
- int status = 0;
- u32 proc_id;
-
- if (!hnode || !hnode->node_mgr) {
- status = -EFAULT;
- } else {
- hnode_mgr = hnode->node_mgr;
- node_type = node_get_type(hnode);
- if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
- status = -EPERM;
- else if (prio < hnode_mgr->min_pri || prio > hnode_mgr->max_pri)
- status = -EDOM;
- }
- if (status)
- goto func_end;
-
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- state = node_get_state(hnode);
- if (state == NODE_ALLOCATED || state == NODE_PAUSED) {
- NODE_SET_PRIORITY(hnode, prio);
- } else {
- if (state != NODE_RUNNING) {
- status = -EBADR;
- goto func_cont;
- }
- status = proc_get_processor_id(pnode->processor, &proc_id);
- if (proc_id == DSP_UNIT) {
- status =
- disp_node_change_priority(hnode_mgr->disp_obj,
- hnode,
- hnode_mgr->fxn_addrs
- [RMSCHANGENODEPRIORITY],
- hnode->node_env, prio);
- }
- if (status >= 0)
- NODE_SET_PRIORITY(hnode, prio);
-
- }
-func_cont:
- /* Leave critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-func_end:
- return status;
-}
-
-/*
- * ======== node_connect ========
- * Purpose:
- * Connect two nodes on the DSP, or a node on the DSP to the GPP.
- */
-int node_connect(struct node_object *node1, u32 stream1,
- struct node_object *node2,
- u32 stream2, struct dsp_strmattr *pattrs,
- struct dsp_cbdata *conn_param)
-{
- struct node_mgr *hnode_mgr;
- char *pstr_dev_name = NULL;
- enum node_type node1_type = NODE_TASK;
- enum node_type node2_type = NODE_TASK;
- enum dsp_strmmode strm_mode;
- struct node_strmdef *pstrm_def;
- struct node_strmdef *input = NULL;
- struct node_strmdef *output = NULL;
- struct node_object *dev_node_obj;
- struct node_object *hnode;
- struct stream_chnl *pstream;
- u32 pipe_id;
- u32 chnl_id;
- s8 chnl_mode;
- u32 dw_length;
- int status = 0;
-
- if (!node1 || !node2)
- return -EFAULT;
-
- /* The two nodes must be on the same processor */
- if (node1 != (struct node_object *)DSP_HGPPNODE &&
- node2 != (struct node_object *)DSP_HGPPNODE &&
- node1->node_mgr != node2->node_mgr)
- return -EPERM;
-
- /* Cannot connect a node to itself */
- if (node1 == node2)
- return -EPERM;
-
- /* node_get_type() will return NODE_GPP if hnode = DSP_HGPPNODE. */
- node1_type = node_get_type(node1);
- node2_type = node_get_type(node2);
- /* Check stream indices ranges */
- if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE &&
- stream1 >= MAX_OUTPUTS(node1)) ||
- (node2_type != NODE_GPP && node2_type != NODE_DEVICE &&
- stream2 >= MAX_INPUTS(node2)))
- return -EINVAL;
-
- /*
- * Only the following types of connections are allowed:
- * task/dais socket < == > task/dais socket
- * task/dais socket < == > device
- * task/dais socket < == > GPP
- *
- * ie, no message nodes, and at least one task or dais
- * socket node.
- */
- if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE ||
- (node1_type != NODE_TASK &&
- node1_type != NODE_DAISSOCKET &&
- node2_type != NODE_TASK &&
- node2_type != NODE_DAISSOCKET))
- return -EPERM;
- /*
- * Check stream mode. Default is STRMMODE_PROCCOPY.
- */
- if (pattrs && pattrs->strm_mode != STRMMODE_PROCCOPY)
- return -EPERM; /* illegal stream mode */
-
- if (node1_type != NODE_GPP)
- hnode_mgr = node1->node_mgr;
- else
- hnode_mgr = node2->node_mgr;
-
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- /* Nodes must be in the allocated state */
- if (node1_type != NODE_GPP &&
- node_get_state(node1) != NODE_ALLOCATED) {
- status = -EBADR;
- goto out_unlock;
- }
-
- if (node2_type != NODE_GPP &&
- node_get_state(node2) != NODE_ALLOCATED) {
- status = -EBADR;
- goto out_unlock;
- }
-
- /*
- * Check that stream indices for task and dais socket nodes
- * are not already be used. (Device nodes checked later)
- */
- if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
- output = &(node1->create_args.asa.
- task_arg_obj.strm_out_def[stream1]);
- if (output->sz_device) {
- status = -EISCONN;
- goto out_unlock;
- }
-
- }
- if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
- input = &(node2->create_args.asa.
- task_arg_obj.strm_in_def[stream2]);
- if (input->sz_device) {
- status = -EISCONN;
- goto out_unlock;
- }
-
- }
- /* Connecting two task nodes? */
- if ((node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) &&
- (node2_type == NODE_TASK ||
- node2_type == NODE_DAISSOCKET)) {
- /* Find available pipe */
- pipe_id = find_first_zero_bit(hnode_mgr->pipe_map, MAXPIPES);
- if (pipe_id == MAXPIPES) {
- status = -ECONNREFUSED;
- goto out_unlock;
- }
- set_bit(pipe_id, hnode_mgr->pipe_map);
- node1->outputs[stream1].type = NODECONNECT;
- node2->inputs[stream2].type = NODECONNECT;
- node1->outputs[stream1].dev_id = pipe_id;
- node2->inputs[stream2].dev_id = pipe_id;
- output->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL);
- input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL);
- if (!output->sz_device || !input->sz_device) {
- /* Undo the connection */
- kfree(output->sz_device);
- kfree(input->sz_device);
- clear_bit(pipe_id, hnode_mgr->pipe_map);
- status = -ENOMEM;
- goto out_unlock;
- }
- /* Copy "/dbpipe<pipId>" name to device names */
- sprintf(output->sz_device, "%s%d", PIPEPREFIX, pipe_id);
- strcpy(input->sz_device, output->sz_device);
- }
- /* Connecting task node to host? */
- if (node1_type == NODE_GPP || node2_type == NODE_GPP) {
- pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL);
- if (!pstr_dev_name) {
- status = -ENOMEM;
- goto out_unlock;
- }
-
- chnl_mode = (node1_type == NODE_GPP) ?
- CHNL_MODETODSP : CHNL_MODEFROMDSP;
-
- /*
- * Reserve a channel id. We need to put the name "/host<id>"
- * in the node's create_args, but the host
- * side channel will not be opened until DSPStream_Open is
- * called for this node.
- */
- strm_mode = pattrs ? pattrs->strm_mode : STRMMODE_PROCCOPY;
- switch (strm_mode) {
- case STRMMODE_RDMA:
- chnl_id = find_first_zero_bit(hnode_mgr->dma_chnl_map,
- CHNL_MAXCHANNELS);
- if (chnl_id < CHNL_MAXCHANNELS) {
- set_bit(chnl_id, hnode_mgr->dma_chnl_map);
- /* dma chans are 2nd transport chnl set
- * ids(e.g. 16-31) */
- chnl_id = chnl_id + hnode_mgr->num_chnls;
- }
- break;
- case STRMMODE_ZEROCOPY:
- chnl_id = find_first_zero_bit(hnode_mgr->zc_chnl_map,
- CHNL_MAXCHANNELS);
- if (chnl_id < CHNL_MAXCHANNELS) {
- set_bit(chnl_id, hnode_mgr->zc_chnl_map);
- /* zero-copy chans are 3nd transport set
- * (e.g. 32-47) */
- chnl_id = chnl_id +
- (2 * hnode_mgr->num_chnls);
- }
- break;
- case STRMMODE_PROCCOPY:
- chnl_id = find_first_zero_bit(hnode_mgr->chnl_map,
- CHNL_MAXCHANNELS);
- if (chnl_id < CHNL_MAXCHANNELS)
- set_bit(chnl_id, hnode_mgr->chnl_map);
- break;
- default:
- status = -EINVAL;
- goto out_unlock;
- }
- if (chnl_id == CHNL_MAXCHANNELS) {
- status = -ECONNREFUSED;
- goto out_unlock;
- }
-
- if (node1 == (struct node_object *)DSP_HGPPNODE) {
- node2->inputs[stream2].type = HOSTCONNECT;
- node2->inputs[stream2].dev_id = chnl_id;
- input->sz_device = pstr_dev_name;
- } else {
- node1->outputs[stream1].type = HOSTCONNECT;
- node1->outputs[stream1].dev_id = chnl_id;
- output->sz_device = pstr_dev_name;
- }
- sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id);
- }
- /* Connecting task node to device node? */
- if ((node1_type == NODE_DEVICE) || (node2_type == NODE_DEVICE)) {
- if (node2_type == NODE_DEVICE) {
- /* node1 == > device */
- dev_node_obj = node2;
- hnode = node1;
- pstream = &(node1->outputs[stream1]);
- pstrm_def = output;
- } else {
- /* device == > node2 */
- dev_node_obj = node1;
- hnode = node2;
- pstream = &(node2->inputs[stream2]);
- pstrm_def = input;
- }
- /* Set up create args */
- pstream->type = DEVICECONNECT;
- dw_length = strlen(dev_node_obj->str_dev_name);
- if (conn_param)
- pstrm_def->sz_device = kzalloc(dw_length + 1 +
- conn_param->cb_data,
- GFP_KERNEL);
- else
- pstrm_def->sz_device = kzalloc(dw_length + 1,
- GFP_KERNEL);
- if (!pstrm_def->sz_device) {
- status = -ENOMEM;
- goto out_unlock;
- }
- /* Copy device name */
- strncpy(pstrm_def->sz_device,
- dev_node_obj->str_dev_name, dw_length);
- if (conn_param)
- strncat(pstrm_def->sz_device,
- (char *)conn_param->node_data,
- (u32) conn_param->cb_data);
- dev_node_obj->device_owner = hnode;
- }
- /* Fill in create args */
- if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
- node1->create_args.asa.task_arg_obj.num_outputs++;
- fill_stream_def(node1, output, pattrs);
- }
- if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
- node2->create_args.asa.task_arg_obj.num_inputs++;
- fill_stream_def(node2, input, pattrs);
- }
- /* Update node1 and node2 stream_connect */
- if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) {
- node1->num_outputs++;
- if (stream1 > node1->max_output_index)
- node1->max_output_index = stream1;
-
- }
- if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) {
- node2->num_inputs++;
- if (stream2 > node2->max_input_index)
- node2->max_input_index = stream2;
-
- }
- fill_stream_connect(node1, node2, stream1, stream2);
- /* end of sync_enter_cs */
- /* Exit critical section */
-out_unlock:
- if (status && pstr_dev_name)
- kfree(pstr_dev_name);
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- dev_dbg(bridge, "%s: node1: %p stream1: %d node2: %p stream2: %d"
- "pattrs: %p status: 0x%x\n", __func__, node1,
- stream1, node2, stream2, pattrs, status);
- return status;
-}
-
-/*
- * ======== node_create ========
- * Purpose:
- * Create a node on the DSP by remotely calling the node's create function.
- */
-int node_create(struct node_object *hnode)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- struct node_mgr *hnode_mgr;
- struct bridge_drv_interface *intf_fxns;
- u32 ul_create_fxn;
- enum node_type node_type;
- int status = 0;
- int status1 = 0;
- struct dsp_cbdata cb_data;
- u32 proc_id = 255;
- struct dsp_processorstate proc_state;
- struct proc_object *hprocessor;
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- struct dspbridge_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-#endif
-
- if (!pnode) {
- status = -EFAULT;
- goto func_end;
- }
- hprocessor = hnode->processor;
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in error state then don't attempt to create
- new node */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
- /* create struct dsp_cbdata struct for PWR calls */
- cb_data.cb_data = PWR_TIMEOUT;
- node_type = node_get_type(hnode);
- hnode_mgr = hnode->node_mgr;
- intf_fxns = hnode_mgr->intf_fxns;
- /* Get access to node dispatcher */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- /* Check node state */
- if (node_get_state(hnode) != NODE_ALLOCATED)
- status = -EBADR;
-
- if (!status)
- status = proc_get_processor_id(pnode->processor, &proc_id);
-
- if (status)
- goto func_cont2;
-
- if (proc_id != DSP_UNIT)
- goto func_cont2;
-
- /* Make sure streams are properly connected */
- if ((hnode->num_inputs && hnode->max_input_index >
- hnode->num_inputs - 1) ||
- (hnode->num_outputs && hnode->max_output_index >
- hnode->num_outputs - 1))
- status = -ENOTCONN;
-
- if (!status) {
- /* If node's create function is not loaded, load it */
- /* Boost the OPP level to max level that DSP can be requested */
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- if (pdata->cpu_set_freq)
- (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP3]);
-#endif
- status = hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj,
- NLDR_CREATE);
- /* Get address of node's create function */
- if (!status) {
- hnode->loaded = true;
- if (node_type != NODE_DEVICE) {
- status = get_fxn_address(hnode, &ul_create_fxn,
- CREATEPHASE);
- }
- } else {
- pr_err("%s: failed to load create code: 0x%x\n",
- __func__, status);
- }
- /* Request the lowest OPP level */
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- if (pdata->cpu_set_freq)
- (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
-#endif
- /* Get address of iAlg functions, if socket node */
- if (!status) {
- if (node_type == NODE_DAISSOCKET) {
- status = hnode_mgr->nldr_fxns.get_fxn_addr
- (hnode->nldr_node_obj,
- hnode->dcd_props.obj_data.node_obj.
- str_i_alg_name,
- &hnode->create_args.asa.
- task_arg_obj.dais_arg);
- }
- }
- }
- if (!status) {
- if (node_type != NODE_DEVICE) {
- status = disp_node_create(hnode_mgr->disp_obj, hnode,
- hnode_mgr->fxn_addrs
- [RMSCREATENODE],
- ul_create_fxn,
- &(hnode->create_args),
- &(hnode->node_env));
- if (status >= 0) {
- /* Set the message queue id to the node env
- * pointer */
- intf_fxns = hnode_mgr->intf_fxns;
- (*intf_fxns->msg_set_queue_id) (hnode->
- msg_queue_obj,
- hnode->node_env);
- }
- }
- }
- /* Phase II/Overlays: Create, execute, delete phases possibly in
- * different files/sections. */
- if (hnode->loaded && hnode->phase_split) {
- /* If create code was dynamically loaded, we can now unload
- * it. */
- status1 = hnode_mgr->nldr_fxns.unload(hnode->nldr_node_obj,
- NLDR_CREATE);
- hnode->loaded = false;
- }
- if (status1)
- pr_err("%s: Failed to unload create code: 0x%x\n",
- __func__, status1);
-func_cont2:
- /* Update node state and node manager state */
- if (status >= 0) {
- NODE_SET_STATE(hnode, NODE_CREATED);
- hnode_mgr->num_created++;
- goto func_cont;
- }
- if (status != -EBADR) {
- /* Put back in NODE_ALLOCATED state if error occurred */
- NODE_SET_STATE(hnode, NODE_ALLOCATED);
- }
-func_cont:
- /* Free access to node dispatcher */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-func_end:
- if (status >= 0) {
- proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
- ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
- }
-
- dev_dbg(bridge, "%s: hnode: %p status: 0x%x\n", __func__,
- hnode, status);
- return status;
-}
-
-/*
- * ======== node_create_mgr ========
- * Purpose:
- * Create a NODE Manager object.
- */
-int node_create_mgr(struct node_mgr **node_man,
- struct dev_object *hdev_obj)
-{
- u32 i;
- struct node_mgr *node_mgr_obj = NULL;
- struct disp_attr disp_attr_obj;
- char *sz_zl_file = "";
- struct nldr_attrs nldr_attrs_obj;
- int status = 0;
- u8 dev_type;
-
- *node_man = NULL;
- /* Allocate Node manager object */
- node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL);
- if (!node_mgr_obj)
- return -ENOMEM;
-
- node_mgr_obj->dev_obj = hdev_obj;
-
- node_mgr_obj->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
- GFP_KERNEL);
- if (!node_mgr_obj->ntfy_obj) {
- status = -ENOMEM;
- goto out_err;
- }
- ntfy_init(node_mgr_obj->ntfy_obj);
-
- INIT_LIST_HEAD(&node_mgr_obj->node_list);
-
- dev_get_dev_type(hdev_obj, &dev_type);
-
- status = dcd_create_manager(sz_zl_file, &node_mgr_obj->dcd_mgr);
- if (status)
- goto out_err;
-
- status = get_proc_props(node_mgr_obj, hdev_obj);
- if (status)
- goto out_err;
-
- /* Create NODE Dispatcher */
- disp_attr_obj.chnl_offset = node_mgr_obj->chnl_offset;
- disp_attr_obj.chnl_buf_size = node_mgr_obj->chnl_buf_size;
- disp_attr_obj.proc_family = node_mgr_obj->proc_family;
- disp_attr_obj.proc_type = node_mgr_obj->proc_type;
-
- status = disp_create(&node_mgr_obj->disp_obj, hdev_obj, &disp_attr_obj);
- if (status)
- goto out_err;
-
- /* Create a STRM Manager */
- status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj);
- if (status)
- goto out_err;
-
- dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns);
- /* Get msg_ctrl queue manager */
- dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj);
- mutex_init(&node_mgr_obj->node_mgr_lock);
-
- /* Block out reserved channels */
- for (i = 0; i < node_mgr_obj->chnl_offset; i++)
- set_bit(i, node_mgr_obj->chnl_map);
-
- /* Block out channels reserved for RMS */
- set_bit(node_mgr_obj->chnl_offset, node_mgr_obj->chnl_map);
- set_bit(node_mgr_obj->chnl_offset + 1, node_mgr_obj->chnl_map);
-
- /* NO RM Server on the IVA */
- if (dev_type != IVA_UNIT) {
- /* Get addresses of any RMS functions loaded */
- status = get_rms_fxns(node_mgr_obj);
- if (status)
- goto out_err;
- }
-
- /* Get loader functions and create loader */
- node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */
-
- nldr_attrs_obj.ovly = ovly;
- nldr_attrs_obj.write = mem_write;
- nldr_attrs_obj.dsp_word_size = node_mgr_obj->dsp_word_size;
- nldr_attrs_obj.dsp_mau_size = node_mgr_obj->dsp_mau_size;
- status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj,
- hdev_obj,
- &nldr_attrs_obj);
- if (status)
- goto out_err;
-
- *node_man = node_mgr_obj;
-
- return status;
-out_err:
- delete_node_mgr(node_mgr_obj);
- return status;
-}
-
-/*
- * ======== node_delete ========
- * Purpose:
- * Delete a node on the DSP by remotely calling the node's delete function.
- * Loads the node's delete function if necessary. Free GPP side resources
- * after node's delete function returns.
- */
-int node_delete(struct node_res_object *noderes,
- struct process_context *pr_ctxt)
-{
- struct node_object *pnode = noderes->node;
- struct node_mgr *hnode_mgr;
- struct proc_object *hprocessor;
- struct disp_object *disp_obj;
- u32 ul_delete_fxn;
- enum node_type node_type;
- enum node_state state;
- int status = 0;
- int status1 = 0;
- struct dsp_cbdata cb_data;
- u32 proc_id;
- struct bridge_drv_interface *intf_fxns;
-
- void *node_res = noderes;
-
- struct dsp_processorstate proc_state;
-
- if (!pnode) {
- status = -EFAULT;
- goto func_end;
- }
- /* create struct dsp_cbdata struct for PWR call */
- cb_data.cb_data = PWR_TIMEOUT;
- hnode_mgr = pnode->node_mgr;
- hprocessor = pnode->processor;
- disp_obj = hnode_mgr->disp_obj;
- node_type = node_get_type(pnode);
- intf_fxns = hnode_mgr->intf_fxns;
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- state = node_get_state(pnode);
- /* Execute delete phase code for non-device node in all cases
- * except when the node was only allocated. Delete phase must be
- * executed even if create phase was executed, but failed.
- * If the node environment pointer is non-NULL, the delete phase
- * code must be executed. */
- if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) &&
- node_type != NODE_DEVICE) {
- status = proc_get_processor_id(pnode->processor, &proc_id);
- if (status)
- goto func_cont1;
-
- if (proc_id == DSP_UNIT || proc_id == IVA_UNIT) {
- /* If node has terminated, execute phase code will
- * have already been unloaded in node_on_exit(). If the
- * node is PAUSED, the execute phase is loaded, and it
- * is now ok to unload it. If the node is running, we
- * will unload the execute phase only after deleting
- * the node. */
- if (state == NODE_PAUSED && pnode->loaded &&
- pnode->phase_split) {
- /* Ok to unload execute code as long as node
- * is not * running */
- status1 =
- hnode_mgr->nldr_fxns.
- unload(pnode->nldr_node_obj,
- NLDR_EXECUTE);
- pnode->loaded = false;
- NODE_SET_STATE(pnode, NODE_DONE);
- }
- /* Load delete phase code if not loaded or if haven't
- * * unloaded EXECUTE phase */
- if ((!(pnode->loaded) || (state == NODE_RUNNING)) &&
- pnode->phase_split) {
- status =
- hnode_mgr->nldr_fxns.
- load(pnode->nldr_node_obj, NLDR_DELETE);
- if (!status)
- pnode->loaded = true;
- else
- pr_err("%s: fail - load delete code:"
- " 0x%x\n", __func__, status);
- }
- }
-func_cont1:
- if (!status) {
- /* Unblock a thread trying to terminate the node */
- (void)sync_set_event(pnode->sync_done);
- if (proc_id == DSP_UNIT) {
- /* ul_delete_fxn = address of node's delete
- * function */
- status = get_fxn_address(pnode, &ul_delete_fxn,
- DELETEPHASE);
- } else if (proc_id == IVA_UNIT)
- ul_delete_fxn = (u32) pnode->node_env;
- if (!status) {
- status = proc_get_state(hprocessor,
- &proc_state,
- sizeof(struct
- dsp_processorstate));
- if (proc_state.proc_state != PROC_ERROR) {
- status =
- disp_node_delete(disp_obj, pnode,
- hnode_mgr->
- fxn_addrs
- [RMSDELETENODE],
- ul_delete_fxn,
- pnode->node_env);
- } else
- NODE_SET_STATE(pnode, NODE_DONE);
-
- /* Unload execute, if not unloaded, and delete
- * function */
- if (state == NODE_RUNNING &&
- pnode->phase_split) {
- status1 =
- hnode_mgr->nldr_fxns.
- unload(pnode->nldr_node_obj,
- NLDR_EXECUTE);
- }
- if (status1)
- pr_err("%s: fail - unload execute code:"
- " 0x%x\n", __func__, status1);
-
- status1 =
- hnode_mgr->nldr_fxns.unload(pnode->
- nldr_node_obj,
- NLDR_DELETE);
- pnode->loaded = false;
- if (status1)
- pr_err("%s: fail - unload delete code: "
- "0x%x\n", __func__, status1);
- }
- }
- }
- /* Free host side resources even if a failure occurred */
- /* Remove node from hnode_mgr->node_list */
- list_del(&pnode->list_elem);
- hnode_mgr->num_nodes--;
- /* Decrement count of nodes created on DSP */
- if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
- (pnode->node_env != (u32) NULL)))
- hnode_mgr->num_created--;
- /* Free host-side resources allocated by node_create()
- * delete_node() fails if SM buffers not freed by client! */
- drv_proc_node_update_status(node_res, false);
- delete_node(pnode, pr_ctxt);
-
- /*
- * Release all Node resources and its context
- */
- idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id);
- kfree(node_res);
-
- /* Exit critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- proc_notify_clients(hprocessor, DSP_NODESTATECHANGE);
-func_end:
- dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status);
- return status;
-}
-
-/*
- * ======== node_delete_mgr ========
- * Purpose:
- * Delete the NODE Manager.
- */
-int node_delete_mgr(struct node_mgr *hnode_mgr)
-{
- if (!hnode_mgr)
- return -EFAULT;
-
- delete_node_mgr(hnode_mgr);
-
- return 0;
-}
-
-/*
- * ======== node_enum_nodes ========
- * Purpose:
- * Enumerate currently allocated nodes.
- */
-int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab,
- u32 node_tab_size, u32 *pu_num_nodes,
- u32 *pu_allocated)
-{
- struct node_object *hnode;
- u32 i = 0;
- int status = 0;
-
- if (!hnode_mgr) {
- status = -EFAULT;
- goto func_end;
- }
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- if (hnode_mgr->num_nodes > node_tab_size) {
- *pu_allocated = hnode_mgr->num_nodes;
- *pu_num_nodes = 0;
- status = -EINVAL;
- } else {
- list_for_each_entry(hnode, &hnode_mgr->node_list, list_elem)
- node_tab[i++] = hnode;
- *pu_allocated = *pu_num_nodes = hnode_mgr->num_nodes;
- }
- /* end of sync_enter_cs */
- /* Exit critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-func_end:
- return status;
-}
-
-/*
- * ======== node_free_msg_buf ========
- * Purpose:
- * Frees the message buffer.
- */
-int node_free_msg_buf(struct node_object *hnode, u8 *pbuffer,
- struct dsp_bufferattr *pattr)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- int status = 0;
- u32 proc_id;
-
- if (!hnode) {
- status = -EFAULT;
- goto func_end;
- }
- status = proc_get_processor_id(pnode->processor, &proc_id);
- if (proc_id == DSP_UNIT) {
- if (!status) {
- if (pattr == NULL) {
- /* set defaults */
- pattr = &node_dfltbufattrs;
- }
- /* Node supports single SM segment only */
- if (pattr->segment_id != 1)
- status = -EBADR;
-
- /* pbuffer is clients Va. */
- status = cmm_xlator_free_buf(pnode->xlator, pbuffer);
- }
- } else {
- }
-func_end:
- return status;
-}
-
-/*
- * ======== node_get_attr ========
- * Purpose:
- * Copy the current attributes of the specified node into a dsp_nodeattr
- * structure.
- */
-int node_get_attr(struct node_object *hnode,
- struct dsp_nodeattr *pattr, u32 attr_size)
-{
- struct node_mgr *hnode_mgr;
-
- if (!hnode)
- return -EFAULT;
-
- hnode_mgr = hnode->node_mgr;
- /* Enter hnode_mgr critical section since we're accessing
- * data that could be changed by node_change_priority() and
- * node_connect(). */
- mutex_lock(&hnode_mgr->node_mgr_lock);
- pattr->cb_struct = sizeof(struct dsp_nodeattr);
- /* dsp_nodeattrin */
- pattr->in_node_attr_in.cb_struct =
- sizeof(struct dsp_nodeattrin);
- pattr->in_node_attr_in.prio = hnode->prio;
- pattr->in_node_attr_in.timeout = hnode->timeout;
- pattr->in_node_attr_in.heap_size =
- hnode->create_args.asa.task_arg_obj.heap_size;
- pattr->in_node_attr_in.pgpp_virt_addr = (void *)
- hnode->create_args.asa.task_arg_obj.gpp_heap_addr;
- pattr->node_attr_inputs = hnode->num_gpp_inputs;
- pattr->node_attr_outputs = hnode->num_gpp_outputs;
- /* dsp_nodeinfo */
- get_node_info(hnode, &(pattr->node_info));
- /* end of sync_enter_cs */
- /* Exit critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-
- return 0;
-}
-
-/*
- * ======== node_get_channel_id ========
- * Purpose:
- * Get the channel index reserved for a stream connection between the
- * host and a node.
- */
-int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index,
- u32 *chan_id)
-{
- enum node_type node_type;
- int status = -EINVAL;
-
- if (!hnode) {
- status = -EFAULT;
- return status;
- }
- node_type = node_get_type(hnode);
- if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) {
- status = -EPERM;
- return status;
- }
- if (dir == DSP_TONODE) {
- if (index < MAX_INPUTS(hnode)) {
- if (hnode->inputs[index].type == HOSTCONNECT) {
- *chan_id = hnode->inputs[index].dev_id;
- status = 0;
- }
- }
- } else {
- if (index < MAX_OUTPUTS(hnode)) {
- if (hnode->outputs[index].type == HOSTCONNECT) {
- *chan_id = hnode->outputs[index].dev_id;
- status = 0;
- }
- }
- }
- return status;
-}
-
-/*
- * ======== node_get_message ========
- * Purpose:
- * Retrieve a message from a node on the DSP.
- */
-int node_get_message(struct node_object *hnode,
- struct dsp_msg *message, u32 utimeout)
-{
- struct node_mgr *hnode_mgr;
- enum node_type node_type;
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
- void *tmp_buf;
- struct dsp_processorstate proc_state;
- struct proc_object *hprocessor;
-
- if (!hnode) {
- status = -EFAULT;
- goto func_end;
- }
- hprocessor = hnode->processor;
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in error state then don't attempt to get the
- message */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
- hnode_mgr = hnode->node_mgr;
- node_type = node_get_type(hnode);
- if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
- node_type != NODE_DAISSOCKET) {
- status = -EPERM;
- goto func_end;
- }
- /* This function will block unless a message is available. Since
- * DSPNode_RegisterNotify() allows notification when a message
- * is available, the system can be designed so that
- * DSPNode_GetMessage() is only called when a message is
- * available. */
- intf_fxns = hnode_mgr->intf_fxns;
- status =
- (*intf_fxns->msg_get) (hnode->msg_queue_obj, message, utimeout);
- /* Check if message contains SM descriptor */
- if (status || !(message->cmd & DSP_RMSBUFDESC))
- goto func_end;
-
- /* Translate DSP byte addr to GPP Va. */
- tmp_buf = cmm_xlator_translate(hnode->xlator,
- (void *)(message->arg1 *
- hnode->node_mgr->
- dsp_word_size), CMM_DSPPA2PA);
- if (tmp_buf != NULL) {
- /* now convert this GPP Pa to Va */
- tmp_buf = cmm_xlator_translate(hnode->xlator, tmp_buf,
- CMM_PA2VA);
- if (tmp_buf != NULL) {
- /* Adjust SM size in msg */
- message->arg1 = (u32) tmp_buf;
- message->arg2 *= hnode->node_mgr->dsp_word_size;
- } else {
- status = -ESRCH;
- }
- } else {
- status = -ESRCH;
- }
-func_end:
- dev_dbg(bridge, "%s: hnode: %p message: %p utimeout: 0x%x\n", __func__,
- hnode, message, utimeout);
- return status;
-}
-
-/*
- * ======== node_get_nldr_obj ========
- */
-int node_get_nldr_obj(struct node_mgr *hnode_mgr,
- struct nldr_object **nldr_ovlyobj)
-{
- int status = 0;
- struct node_mgr *node_mgr_obj = hnode_mgr;
-
- if (!hnode_mgr)
- status = -EFAULT;
- else
- *nldr_ovlyobj = node_mgr_obj->nldr_obj;
-
- return status;
-}
-
-/*
- * ======== node_get_strm_mgr ========
- * Purpose:
- * Returns the Stream manager.
- */
-int node_get_strm_mgr(struct node_object *hnode,
- struct strm_mgr **strm_man)
-{
- int status = 0;
-
- if (!hnode)
- status = -EFAULT;
- else
- *strm_man = hnode->node_mgr->strm_mgr_obj;
-
- return status;
-}
-
-/*
- * ======== node_get_load_type ========
- */
-enum nldr_loadtype node_get_load_type(struct node_object *hnode)
-{
- if (!hnode) {
- dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode);
- return -1;
- } else {
- return hnode->dcd_props.obj_data.node_obj.load_type;
- }
-}
-
-/*
- * ======== node_get_timeout ========
- * Purpose:
- * Returns the timeout value for this node.
- */
-u32 node_get_timeout(struct node_object *hnode)
-{
- if (!hnode) {
- dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode);
- return 0;
- } else {
- return hnode->timeout;
- }
-}
-
-/*
- * ======== node_get_type ========
- * Purpose:
- * Returns the node type.
- */
-enum node_type node_get_type(struct node_object *hnode)
-{
- enum node_type node_type;
-
- if (hnode == (struct node_object *)DSP_HGPPNODE)
- node_type = NODE_GPP;
- else {
- if (!hnode)
- node_type = -1;
- else
- node_type = hnode->ntype;
- }
- return node_type;
-}
-
-/*
- * ======== node_on_exit ========
- * Purpose:
- * Gets called when RMS_EXIT is received for a node.
- */
-void node_on_exit(struct node_object *hnode, s32 node_status)
-{
- if (!hnode)
- return;
-
- /* Set node state to done */
- NODE_SET_STATE(hnode, NODE_DONE);
- hnode->exit_status = node_status;
- if (hnode->loaded && hnode->phase_split) {
- (void)hnode->node_mgr->nldr_fxns.unload(hnode->
- nldr_node_obj,
- NLDR_EXECUTE);
- hnode->loaded = false;
- }
- /* Unblock call to node_terminate */
- (void)sync_set_event(hnode->sync_done);
- /* Notify clients */
- proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
- ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
-}
-
-/*
- * ======== node_pause ========
- * Purpose:
- * Suspend execution of a node currently running on the DSP.
- */
-int node_pause(struct node_object *hnode)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- enum node_type node_type;
- enum node_state state;
- struct node_mgr *hnode_mgr;
- int status = 0;
- u32 proc_id;
- struct dsp_processorstate proc_state;
- struct proc_object *hprocessor;
-
- if (!hnode) {
- status = -EFAULT;
- } else {
- node_type = node_get_type(hnode);
- if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
- status = -EPERM;
- }
- if (status)
- goto func_end;
-
- status = proc_get_processor_id(pnode->processor, &proc_id);
-
- if (proc_id == IVA_UNIT)
- status = -ENOSYS;
-
- if (!status) {
- hnode_mgr = hnode->node_mgr;
-
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
- state = node_get_state(hnode);
- /* Check node state */
- if (state != NODE_RUNNING)
- status = -EBADR;
-
- if (status)
- goto func_cont;
- hprocessor = hnode->processor;
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_cont;
- /* If processor is in error state then don't attempt
- to send the message */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_cont;
- }
-
- status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
- hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY],
- hnode->node_env, NODE_SUSPENDEDPRI);
-
- /* Update state */
- if (status >= 0)
- NODE_SET_STATE(hnode, NODE_PAUSED);
-
-func_cont:
- /* End of sync_enter_cs */
- /* Leave critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- if (status >= 0) {
- proc_notify_clients(hnode->processor,
- DSP_NODESTATECHANGE);
- ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
- }
- }
-func_end:
- dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
- return status;
-}
-
-/*
- * ======== node_put_message ========
- * Purpose:
- * Send a message to a message node, task node, or XDAIS socket node. This
- * function will block until the message stream can accommodate the
- * message, or a timeout occurs.
- */
-int node_put_message(struct node_object *hnode,
- const struct dsp_msg *pmsg, u32 utimeout)
-{
- struct node_mgr *hnode_mgr = NULL;
- enum node_type node_type;
- struct bridge_drv_interface *intf_fxns;
- enum node_state state;
- int status = 0;
- void *tmp_buf;
- struct dsp_msg new_msg;
- struct dsp_processorstate proc_state;
- struct proc_object *hprocessor;
-
- if (!hnode) {
- status = -EFAULT;
- goto func_end;
- }
- hprocessor = hnode->processor;
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in bad state then don't attempt sending the
- message */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
- hnode_mgr = hnode->node_mgr;
- node_type = node_get_type(hnode);
- if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
- node_type != NODE_DAISSOCKET)
- status = -EPERM;
-
- if (!status) {
- /* Check node state. Can't send messages to a node after
- * we've sent the RMS_EXIT command. There is still the
- * possibility that node_terminate can be called after we've
- * checked the state. Could add another SYNC object to
- * prevent this (can't use node_mgr_lock, since we don't
- * want to block other NODE functions). However, the node may
- * still exit on its own, before this message is sent. */
- mutex_lock(&hnode_mgr->node_mgr_lock);
- state = node_get_state(hnode);
- if (state == NODE_TERMINATING || state == NODE_DONE)
- status = -EBADR;
-
- /* end of sync_enter_cs */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- }
- if (status)
- goto func_end;
-
- /* assign pmsg values to new msg */
- new_msg = *pmsg;
- /* Now, check if message contains a SM buffer descriptor */
- if (pmsg->cmd & DSP_RMSBUFDESC) {
- /* Translate GPP Va to DSP physical buf Ptr. */
- tmp_buf = cmm_xlator_translate(hnode->xlator,
- (void *)new_msg.arg1,
- CMM_VA2DSPPA);
- if (tmp_buf != NULL) {
- /* got translation, convert to MAUs in msg */
- if (hnode->node_mgr->dsp_word_size != 0) {
- new_msg.arg1 =
- (u32) tmp_buf /
- hnode->node_mgr->dsp_word_size;
- /* MAUs */
- new_msg.arg2 /= hnode->node_mgr->
- dsp_word_size;
- } else {
- pr_err("%s: dsp_word_size is zero!\n",
- __func__);
- status = -EPERM; /* bad DSPWordSize */
- }
- } else { /* failed to translate buffer address */
- status = -ESRCH;
- }
- }
- if (!status) {
- intf_fxns = hnode_mgr->intf_fxns;
- status = (*intf_fxns->msg_put) (hnode->msg_queue_obj,
- &new_msg, utimeout);
- }
-func_end:
- dev_dbg(bridge, "%s: hnode: %p pmsg: %p utimeout: 0x%x, "
- "status 0x%x\n", __func__, hnode, pmsg, utimeout, status);
- return status;
-}
-
-/*
- * ======== node_register_notify ========
- * Purpose:
- * Register to be notified on specific events for this node.
- */
-int node_register_notify(struct node_object *hnode, u32 event_mask,
- u32 notify_type,
- struct dsp_notification *hnotification)
-{
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
-
- if (!hnode) {
- status = -EFAULT;
- } else {
- /* Check if event mask is a valid node related event */
- if (event_mask & ~(DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
- status = -EINVAL;
-
- /* Check if notify type is valid */
- if (notify_type != DSP_SIGNALEVENT)
- status = -EINVAL;
-
- /* Only one Notification can be registered at a
- * time - Limitation */
- if (event_mask == (DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
- status = -EINVAL;
- }
- if (!status) {
- if (event_mask == DSP_NODESTATECHANGE) {
- status = ntfy_register(hnode->ntfy_obj, hnotification,
- event_mask & DSP_NODESTATECHANGE,
- notify_type);
- } else {
- /* Send Message part of event mask to msg_ctrl */
- intf_fxns = hnode->node_mgr->intf_fxns;
- status = (*intf_fxns->msg_register_notify)
- (hnode->msg_queue_obj,
- event_mask & DSP_NODEMESSAGEREADY, notify_type,
- hnotification);
- }
-
- }
- dev_dbg(bridge, "%s: hnode: %p event_mask: 0x%x notify_type: 0x%x "
- "hnotification: %p status 0x%x\n", __func__, hnode,
- event_mask, notify_type, hnotification, status);
- return status;
-}
-
-/*
- * ======== node_run ========
- * Purpose:
- * Start execution of a node's execute phase, or resume execution of a node
- * that has been suspended (via NODE_NodePause()) on the DSP. Load the
- * node's execute function if necessary.
- */
-int node_run(struct node_object *hnode)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- struct node_mgr *hnode_mgr;
- enum node_type node_type;
- enum node_state state;
- u32 ul_execute_fxn;
- u32 ul_fxn_addr;
- int status = 0;
- u32 proc_id;
- struct bridge_drv_interface *intf_fxns;
- struct dsp_processorstate proc_state;
- struct proc_object *hprocessor;
-
- if (!hnode) {
- status = -EFAULT;
- goto func_end;
- }
- hprocessor = hnode->processor;
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in error state then don't attempt to run the node */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
- node_type = node_get_type(hnode);
- if (node_type == NODE_DEVICE)
- status = -EPERM;
- if (status)
- goto func_end;
-
- hnode_mgr = hnode->node_mgr;
- if (!hnode_mgr) {
- status = -EFAULT;
- goto func_end;
- }
- intf_fxns = hnode_mgr->intf_fxns;
- /* Enter critical section */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- state = node_get_state(hnode);
- if (state != NODE_CREATED && state != NODE_PAUSED)
- status = -EBADR;
-
- if (!status)
- status = proc_get_processor_id(pnode->processor, &proc_id);
-
- if (status)
- goto func_cont1;
-
- if ((proc_id != DSP_UNIT) && (proc_id != IVA_UNIT))
- goto func_cont1;
-
- if (state == NODE_CREATED) {
- /* If node's execute function is not loaded, load it */
- if (!(hnode->loaded) && hnode->phase_split) {
- status =
- hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj,
- NLDR_EXECUTE);
- if (!status) {
- hnode->loaded = true;
- } else {
- pr_err("%s: fail - load execute code: 0x%x\n",
- __func__, status);
- }
- }
- if (!status) {
- /* Get address of node's execute function */
- if (proc_id == IVA_UNIT)
- ul_execute_fxn = (u32) hnode->node_env;
- else {
- status = get_fxn_address(hnode, &ul_execute_fxn,
- EXECUTEPHASE);
- }
- }
- if (!status) {
- ul_fxn_addr = hnode_mgr->fxn_addrs[RMSEXECUTENODE];
- status =
- disp_node_run(hnode_mgr->disp_obj, hnode,
- ul_fxn_addr, ul_execute_fxn,
- hnode->node_env);
- }
- } else if (state == NODE_PAUSED) {
- ul_fxn_addr = hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY];
- status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
- ul_fxn_addr, hnode->node_env,
- NODE_GET_PRIORITY(hnode));
- } else {
- /* We should never get here */
- }
-func_cont1:
- /* Update node state. */
- if (status >= 0)
- NODE_SET_STATE(hnode, NODE_RUNNING);
- else /* Set state back to previous value */
- NODE_SET_STATE(hnode, state);
- /*End of sync_enter_cs */
- /* Exit critical section */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- if (status >= 0) {
- proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
- ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
- }
-func_end:
- dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
- return status;
-}
-
-/*
- * ======== node_terminate ========
- * Purpose:
- * Signal a node running on the DSP that it should exit its execute phase
- * function.
- */
-int node_terminate(struct node_object *hnode, int *pstatus)
-{
- struct node_object *pnode = (struct node_object *)hnode;
- struct node_mgr *hnode_mgr = NULL;
- enum node_type node_type;
- struct bridge_drv_interface *intf_fxns;
- enum node_state state;
- struct dsp_msg msg, killmsg;
- int status = 0;
- u32 proc_id, kill_time_out;
- struct deh_mgr *hdeh_mgr;
- struct dsp_processorstate proc_state;
-
- if (!hnode || !hnode->node_mgr) {
- status = -EFAULT;
- goto func_end;
- }
- if (pnode->processor == NULL) {
- status = -EFAULT;
- goto func_end;
- }
- status = proc_get_processor_id(pnode->processor, &proc_id);
-
- if (!status) {
- hnode_mgr = hnode->node_mgr;
- node_type = node_get_type(hnode);
- if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
- status = -EPERM;
- }
- if (!status) {
- /* Check node state */
- mutex_lock(&hnode_mgr->node_mgr_lock);
- state = node_get_state(hnode);
- if (state != NODE_RUNNING) {
- status = -EBADR;
- /* Set the exit status if node terminated on
- * its own. */
- if (state == NODE_DONE)
- *pstatus = hnode->exit_status;
-
- } else {
- NODE_SET_STATE(hnode, NODE_TERMINATING);
- }
- /* end of sync_enter_cs */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- }
- if (!status) {
- /*
- * Send exit message. Do not change state to NODE_DONE
- * here. That will be done in callback.
- */
- status = proc_get_state(pnode->processor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_cont;
- /* If processor is in error state then don't attempt to send
- * A kill task command */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_cont;
- }
-
- msg.cmd = RMS_EXIT;
- msg.arg1 = hnode->node_env;
- killmsg.cmd = RMS_KILLTASK;
- killmsg.arg1 = hnode->node_env;
- intf_fxns = hnode_mgr->intf_fxns;
-
- if (hnode->timeout > MAXTIMEOUT)
- kill_time_out = MAXTIMEOUT;
- else
- kill_time_out = (hnode->timeout) * 2;
-
- status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &msg,
- hnode->timeout);
- if (status)
- goto func_cont;
-
- /*
- * Wait on synchronization object that will be
- * posted in the callback on receiving RMS_EXIT
- * message, or by node_delete. Check for valid hnode,
- * in case posted by node_delete().
- */
- status = sync_wait_on_event(hnode->sync_done,
- kill_time_out / 2);
- if (status != ETIME)
- goto func_cont;
-
- status = (*intf_fxns->msg_put)(hnode->msg_queue_obj,
- &killmsg, hnode->timeout);
- if (status)
- goto func_cont;
- status = sync_wait_on_event(hnode->sync_done,
- kill_time_out / 2);
- if (status) {
- /*
- * Here it goes the part of the simulation of
- * the DSP exception.
- */
- dev_get_deh_mgr(hnode_mgr->dev_obj, &hdeh_mgr);
- if (!hdeh_mgr)
- goto func_cont;
-
- bridge_deh_notify(hdeh_mgr, DSP_SYSERROR,
- DSP_EXCEPTIONABORT);
- }
- }
-func_cont:
- if (!status) {
- /* Enter CS before getting exit status, in case node was
- * deleted. */
- mutex_lock(&hnode_mgr->node_mgr_lock);
- /* Make sure node wasn't deleted while we blocked */
- if (!hnode) {
- status = -EPERM;
- } else {
- *pstatus = hnode->exit_status;
- dev_dbg(bridge, "%s: hnode: %p env 0x%x status 0x%x\n",
- __func__, hnode, hnode->node_env, status);
- }
- mutex_unlock(&hnode_mgr->node_mgr_lock);
- } /*End of sync_enter_cs */
-func_end:
- return status;
-}
-
-/*
- * ======== delete_node ========
- * Purpose:
- * Free GPP resources allocated in node_allocate() or node_connect().
- */
-static void delete_node(struct node_object *hnode,
- struct process_context *pr_ctxt)
-{
- struct node_mgr *hnode_mgr;
- struct bridge_drv_interface *intf_fxns;
- u32 i;
- enum node_type node_type;
- struct stream_chnl stream;
- struct node_msgargs node_msg_args;
- struct node_taskargs task_arg_obj;
-#ifdef DSP_DMM_DEBUG
- struct dmm_object *dmm_mgr;
- struct proc_object *p_proc_object =
- (struct proc_object *)hnode->processor;
-#endif
- int status;
- if (!hnode)
- goto func_end;
- hnode_mgr = hnode->node_mgr;
- if (!hnode_mgr)
- goto func_end;
-
- node_type = node_get_type(hnode);
- if (node_type != NODE_DEVICE) {
- node_msg_args = hnode->create_args.asa.node_msg_args;
- kfree(node_msg_args.pdata);
-
- /* Free msg_ctrl queue */
- if (hnode->msg_queue_obj) {
- intf_fxns = hnode_mgr->intf_fxns;
- (*intf_fxns->msg_delete_queue) (hnode->
- msg_queue_obj);
- hnode->msg_queue_obj = NULL;
- }
-
- kfree(hnode->sync_done);
-
- /* Free all stream info */
- if (hnode->inputs) {
- for (i = 0; i < MAX_INPUTS(hnode); i++) {
- stream = hnode->inputs[i];
- free_stream(hnode_mgr, stream);
- }
- kfree(hnode->inputs);
- hnode->inputs = NULL;
- }
- if (hnode->outputs) {
- for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
- stream = hnode->outputs[i];
- free_stream(hnode_mgr, stream);
- }
- kfree(hnode->outputs);
- hnode->outputs = NULL;
- }
- task_arg_obj = hnode->create_args.asa.task_arg_obj;
- if (task_arg_obj.strm_in_def) {
- for (i = 0; i < MAX_INPUTS(hnode); i++) {
- kfree(task_arg_obj.strm_in_def[i].sz_device);
- task_arg_obj.strm_in_def[i].sz_device = NULL;
- }
- kfree(task_arg_obj.strm_in_def);
- task_arg_obj.strm_in_def = NULL;
- }
- if (task_arg_obj.strm_out_def) {
- for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
- kfree(task_arg_obj.strm_out_def[i].sz_device);
- task_arg_obj.strm_out_def[i].sz_device = NULL;
- }
- kfree(task_arg_obj.strm_out_def);
- task_arg_obj.strm_out_def = NULL;
- }
- if (task_arg_obj.dsp_heap_res_addr) {
- status = proc_un_map(hnode->processor, (void *)
- task_arg_obj.dsp_heap_addr,
- pr_ctxt);
-
- status = proc_un_reserve_memory(hnode->processor,
- (void *)
- task_arg_obj.
- dsp_heap_res_addr,
- pr_ctxt);
-#ifdef DSP_DMM_DEBUG
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (dmm_mgr)
- dmm_mem_map_dump(dmm_mgr);
- else
- status = DSP_EHANDLE;
-#endif
- }
- }
- if (node_type != NODE_MESSAGE) {
- kfree(hnode->stream_connect);
- hnode->stream_connect = NULL;
- }
- kfree(hnode->str_dev_name);
- hnode->str_dev_name = NULL;
-
- if (hnode->ntfy_obj) {
- ntfy_delete(hnode->ntfy_obj);
- kfree(hnode->ntfy_obj);
- hnode->ntfy_obj = NULL;
- }
-
- /* These were allocated in dcd_get_object_def (via node_allocate) */
- kfree(hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn);
- hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn = NULL;
-
- kfree(hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn);
- hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn = NULL;
-
- kfree(hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn);
- hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn = NULL;
-
- kfree(hnode->dcd_props.obj_data.node_obj.str_i_alg_name);
- hnode->dcd_props.obj_data.node_obj.str_i_alg_name = NULL;
-
- /* Free all SM address translator resources */
- kfree(hnode->xlator);
- kfree(hnode->nldr_node_obj);
- hnode->nldr_node_obj = NULL;
- hnode->node_mgr = NULL;
- kfree(hnode);
- hnode = NULL;
-func_end:
- return;
-}
-
-/*
- * ======== delete_node_mgr ========
- * Purpose:
- * Frees the node manager.
- */
-static void delete_node_mgr(struct node_mgr *hnode_mgr)
-{
- struct node_object *hnode, *tmp;
-
- if (hnode_mgr) {
- /* Free resources */
- if (hnode_mgr->dcd_mgr)
- dcd_destroy_manager(hnode_mgr->dcd_mgr);
-
- /* Remove any elements remaining in lists */
- list_for_each_entry_safe(hnode, tmp, &hnode_mgr->node_list,
- list_elem) {
- list_del(&hnode->list_elem);
- delete_node(hnode, NULL);
- }
- mutex_destroy(&hnode_mgr->node_mgr_lock);
- if (hnode_mgr->ntfy_obj) {
- ntfy_delete(hnode_mgr->ntfy_obj);
- kfree(hnode_mgr->ntfy_obj);
- }
-
- if (hnode_mgr->disp_obj)
- disp_delete(hnode_mgr->disp_obj);
-
- if (hnode_mgr->strm_mgr_obj)
- strm_delete(hnode_mgr->strm_mgr_obj);
-
- /* Delete the loader */
- if (hnode_mgr->nldr_obj)
- hnode_mgr->nldr_fxns.delete(hnode_mgr->nldr_obj);
-
- kfree(hnode_mgr);
- }
-}
-
-/*
- * ======== fill_stream_connect ========
- * Purpose:
- * Fills stream information.
- */
-static void fill_stream_connect(struct node_object *node1,
- struct node_object *node2,
- u32 stream1, u32 stream2)
-{
- u32 strm_index;
- struct dsp_streamconnect *strm1 = NULL;
- struct dsp_streamconnect *strm2 = NULL;
- enum node_type node1_type = NODE_TASK;
- enum node_type node2_type = NODE_TASK;
-
- node1_type = node_get_type(node1);
- node2_type = node_get_type(node2);
- if (node1 != (struct node_object *)DSP_HGPPNODE) {
-
- if (node1_type != NODE_DEVICE) {
- strm_index = node1->num_inputs +
- node1->num_outputs - 1;
- strm1 = &(node1->stream_connect[strm_index]);
- strm1->cb_struct = sizeof(struct dsp_streamconnect);
- strm1->this_node_stream_index = stream1;
- }
-
- if (node2 != (struct node_object *)DSP_HGPPNODE) {
- /* NODE == > NODE */
- if (node1_type != NODE_DEVICE) {
- strm1->connected_node = node2;
- strm1->ui_connected_node_id = node2->node_uuid;
- strm1->connected_node_stream_index = stream2;
- strm1->connect_type = CONNECTTYPE_NODEOUTPUT;
- }
- if (node2_type != NODE_DEVICE) {
- strm_index = node2->num_inputs +
- node2->num_outputs - 1;
- strm2 = &(node2->stream_connect[strm_index]);
- strm2->cb_struct =
- sizeof(struct dsp_streamconnect);
- strm2->this_node_stream_index = stream2;
- strm2->connected_node = node1;
- strm2->ui_connected_node_id = node1->node_uuid;
- strm2->connected_node_stream_index = stream1;
- strm2->connect_type = CONNECTTYPE_NODEINPUT;
- }
- } else if (node1_type != NODE_DEVICE)
- strm1->connect_type = CONNECTTYPE_GPPOUTPUT;
- } else {
- /* GPP == > NODE */
- strm_index = node2->num_inputs + node2->num_outputs - 1;
- strm2 = &(node2->stream_connect[strm_index]);
- strm2->cb_struct = sizeof(struct dsp_streamconnect);
- strm2->this_node_stream_index = stream2;
- strm2->connect_type = CONNECTTYPE_GPPINPUT;
- }
-}
-
-/*
- * ======== fill_stream_def ========
- * Purpose:
- * Fills Stream attributes.
- */
-static void fill_stream_def(struct node_object *hnode,
- struct node_strmdef *pstrm_def,
- struct dsp_strmattr *pattrs)
-{
- struct node_mgr *hnode_mgr = hnode->node_mgr;
-
- if (pattrs != NULL) {
- pstrm_def->num_bufs = pattrs->num_bufs;
- pstrm_def->buf_size =
- pattrs->buf_size / hnode_mgr->dsp_data_mau_size;
- pstrm_def->seg_id = pattrs->seg_id;
- pstrm_def->buf_alignment = pattrs->buf_alignment;
- pstrm_def->timeout = pattrs->timeout;
- } else {
- pstrm_def->num_bufs = DEFAULTNBUFS;
- pstrm_def->buf_size =
- DEFAULTBUFSIZE / hnode_mgr->dsp_data_mau_size;
- pstrm_def->seg_id = DEFAULTSEGID;
- pstrm_def->buf_alignment = DEFAULTALIGNMENT;
- pstrm_def->timeout = DEFAULTTIMEOUT;
- }
-}
-
-/*
- * ======== free_stream ========
- * Purpose:
- * Updates the channel mask and frees the pipe id.
- */
-static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream)
-{
- /* Free up the pipe id unless other node has not yet been deleted. */
- if (stream.type == NODECONNECT) {
- if (test_bit(stream.dev_id, hnode_mgr->pipe_done_map)) {
- /* The other node has already been deleted */
- clear_bit(stream.dev_id, hnode_mgr->pipe_done_map);
- clear_bit(stream.dev_id, hnode_mgr->pipe_map);
- } else {
- /* The other node has not been deleted yet */
- set_bit(stream.dev_id, hnode_mgr->pipe_done_map);
- }
- } else if (stream.type == HOSTCONNECT) {
- if (stream.dev_id < hnode_mgr->num_chnls) {
- clear_bit(stream.dev_id, hnode_mgr->chnl_map);
- } else if (stream.dev_id < (2 * hnode_mgr->num_chnls)) {
- /* dsp-dma */
- clear_bit(stream.dev_id - (1 * hnode_mgr->num_chnls),
- hnode_mgr->dma_chnl_map);
- } else if (stream.dev_id < (3 * hnode_mgr->num_chnls)) {
- /* zero-copy */
- clear_bit(stream.dev_id - (2 * hnode_mgr->num_chnls),
- hnode_mgr->zc_chnl_map);
- }
- }
-}
-
-/*
- * ======== get_fxn_address ========
- * Purpose:
- * Retrieves the address for create, execute or delete phase for a node.
- */
-static int get_fxn_address(struct node_object *hnode, u32 *fxn_addr,
- u32 phase)
-{
- char *pstr_fxn_name = NULL;
- struct node_mgr *hnode_mgr = hnode->node_mgr;
- int status = 0;
-
- switch (phase) {
- case CREATEPHASE:
- pstr_fxn_name =
- hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn;
- break;
- case EXECUTEPHASE:
- pstr_fxn_name =
- hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn;
- break;
- case DELETEPHASE:
- pstr_fxn_name =
- hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn;
- break;
- default:
- /* Should never get here */
- break;
- }
-
- status =
- hnode_mgr->nldr_fxns.get_fxn_addr(hnode->nldr_node_obj,
- pstr_fxn_name, fxn_addr);
-
- return status;
-}
-
-/*
- * ======== get_node_info ========
- * Purpose:
- * Retrieves the node information.
- */
-void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info)
-{
- u32 i;
-
- node_info->cb_struct = sizeof(struct dsp_nodeinfo);
- node_info->nb_node_database_props =
- hnode->dcd_props.obj_data.node_obj.ndb_props;
- node_info->execution_priority = hnode->prio;
- node_info->device_owner = hnode->device_owner;
- node_info->number_streams = hnode->num_inputs + hnode->num_outputs;
- node_info->node_env = hnode->node_env;
-
- node_info->ns_execution_state = node_get_state(hnode);
-
- /* Copy stream connect data */
- for (i = 0; i < hnode->num_inputs + hnode->num_outputs; i++)
- node_info->sc_stream_connection[i] = hnode->stream_connect[i];
-
-}
-
-/*
- * ======== get_node_props ========
- * Purpose:
- * Retrieve node properties.
- */
-static int get_node_props(struct dcd_manager *hdcd_mgr,
- struct node_object *hnode,
- const struct dsp_uuid *node_uuid,
- struct dcd_genericobj *dcd_prop)
-{
- u32 len;
- struct node_msgargs *pmsg_args;
- struct node_taskargs *task_arg_obj;
- enum node_type node_type = NODE_TASK;
- struct dsp_ndbprops *pndb_props =
- &(dcd_prop->obj_data.node_obj.ndb_props);
- int status = 0;
- char sz_uuid[MAXUUIDLEN];
-
- status = dcd_get_object_def(hdcd_mgr, (struct dsp_uuid *)node_uuid,
- DSP_DCDNODETYPE, dcd_prop);
-
- if (!status) {
- hnode->ntype = node_type = pndb_props->ntype;
-
- /* Create UUID value to set in registry. */
- snprintf(sz_uuid, MAXUUIDLEN, "%pUL", node_uuid);
- dev_dbg(bridge, "(node) UUID: %s\n", sz_uuid);
-
- /* Fill in message args that come from NDB */
- if (node_type != NODE_DEVICE) {
- pmsg_args = &(hnode->create_args.asa.node_msg_args);
- pmsg_args->seg_id =
- dcd_prop->obj_data.node_obj.msg_segid;
- pmsg_args->notify_type =
- dcd_prop->obj_data.node_obj.msg_notify_type;
- pmsg_args->max_msgs = pndb_props->message_depth;
- dev_dbg(bridge, "(node) Max Number of Messages: 0x%x\n",
- pmsg_args->max_msgs);
- } else {
- /* Copy device name */
- len = strlen(pndb_props->ac_name);
- hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL);
- if (hnode->str_dev_name == NULL) {
- status = -ENOMEM;
- } else {
- strncpy(hnode->str_dev_name,
- pndb_props->ac_name, len);
- }
- }
- }
- if (!status) {
- /* Fill in create args that come from NDB */
- if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
- task_arg_obj = &(hnode->create_args.asa.task_arg_obj);
- task_arg_obj->prio = pndb_props->prio;
- task_arg_obj->stack_size = pndb_props->stack_size;
- task_arg_obj->sys_stack_size =
- pndb_props->sys_stack_size;
- task_arg_obj->stack_seg = pndb_props->stack_seg;
- dev_dbg(bridge, "(node) Priority: 0x%x Stack Size: "
- "0x%x words System Stack Size: 0x%x words "
- "Stack Segment: 0x%x profile count : 0x%x\n",
- task_arg_obj->prio, task_arg_obj->stack_size,
- task_arg_obj->sys_stack_size,
- task_arg_obj->stack_seg,
- pndb_props->count_profiles);
- }
- }
-
- return status;
-}
-
-/*
- * ======== get_proc_props ========
- * Purpose:
- * Retrieve the processor properties.
- */
-static int get_proc_props(struct node_mgr *hnode_mgr,
- struct dev_object *hdev_obj)
-{
- struct cfg_hostres *host_res;
- struct bridge_dev_context *pbridge_context;
- int status = 0;
-
- status = dev_get_bridge_context(hdev_obj, &pbridge_context);
- if (!pbridge_context)
- status = -EFAULT;
-
- if (!status) {
- host_res = pbridge_context->resources;
- if (!host_res)
- return -EPERM;
- hnode_mgr->chnl_offset = host_res->chnl_offset;
- hnode_mgr->chnl_buf_size = host_res->chnl_buf_size;
- hnode_mgr->num_chnls = host_res->num_chnls;
-
- /*
- * PROC will add an API to get dsp_processorinfo.
- * Fill in default values for now.
- */
- /* TODO -- Instead of hard coding, take from registry */
- hnode_mgr->proc_family = 6000;
- hnode_mgr->proc_type = 6410;
- hnode_mgr->min_pri = DSP_NODE_MIN_PRIORITY;
- hnode_mgr->max_pri = DSP_NODE_MAX_PRIORITY;
- hnode_mgr->dsp_word_size = DSPWORDSIZE;
- hnode_mgr->dsp_data_mau_size = DSPWORDSIZE;
- hnode_mgr->dsp_mau_size = 1;
-
- }
- return status;
-}
-
-/*
- * ======== node_get_uuid_props ========
- * Purpose:
- * Fetch Node UUID properties from DCD/DOF file.
- */
-int node_get_uuid_props(void *hprocessor,
- const struct dsp_uuid *node_uuid,
- struct dsp_ndbprops *node_props)
-{
- struct node_mgr *hnode_mgr = NULL;
- struct dev_object *hdev_obj;
- int status = 0;
- struct dcd_nodeprops dcd_node_props;
- struct dsp_processorstate proc_state;
-
- if (hprocessor == NULL || node_uuid == NULL) {
- status = -EFAULT;
- goto func_end;
- }
- status = proc_get_state(hprocessor, &proc_state,
- sizeof(struct dsp_processorstate));
- if (status)
- goto func_end;
- /* If processor is in error state then don't attempt
- to send the message */
- if (proc_state.proc_state == PROC_ERROR) {
- status = -EPERM;
- goto func_end;
- }
-
- status = proc_get_dev_object(hprocessor, &hdev_obj);
- if (hdev_obj) {
- status = dev_get_node_manager(hdev_obj, &hnode_mgr);
- if (hnode_mgr == NULL) {
- status = -EFAULT;
- goto func_end;
- }
- }
-
- /*
- * Enter the critical section. This is needed because
- * dcd_get_object_def will ultimately end up calling dbll_open/close,
- * which needs to be protected in order to not corrupt the zlib manager
- * (COD).
- */
- mutex_lock(&hnode_mgr->node_mgr_lock);
-
- dcd_node_props.str_create_phase_fxn = NULL;
- dcd_node_props.str_execute_phase_fxn = NULL;
- dcd_node_props.str_delete_phase_fxn = NULL;
- dcd_node_props.str_i_alg_name = NULL;
-
- status = dcd_get_object_def(hnode_mgr->dcd_mgr,
- (struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE,
- (struct dcd_genericobj *)&dcd_node_props);
-
- if (!status) {
- *node_props = dcd_node_props.ndb_props;
- kfree(dcd_node_props.str_create_phase_fxn);
-
- kfree(dcd_node_props.str_execute_phase_fxn);
-
- kfree(dcd_node_props.str_delete_phase_fxn);
-
- kfree(dcd_node_props.str_i_alg_name);
- }
- /* Leave the critical section, we're done. */
- mutex_unlock(&hnode_mgr->node_mgr_lock);
-func_end:
- return status;
-}
-
-/*
- * ======== get_rms_fxns ========
- * Purpose:
- * Retrieve the RMS functions.
- */
-static int get_rms_fxns(struct node_mgr *hnode_mgr)
-{
- s32 i;
- struct dev_object *dev_obj = hnode_mgr->dev_obj;
- int status = 0;
-
- static char *psz_fxns[NUMRMSFXNS] = {
- "RMS_queryServer", /* RMSQUERYSERVER */
- "RMS_configureServer", /* RMSCONFIGURESERVER */
- "RMS_createNode", /* RMSCREATENODE */
- "RMS_executeNode", /* RMSEXECUTENODE */
- "RMS_deleteNode", /* RMSDELETENODE */
- "RMS_changeNodePriority", /* RMSCHANGENODEPRIORITY */
- "RMS_readMemory", /* RMSREADMEMORY */
- "RMS_writeMemory", /* RMSWRITEMEMORY */
- "RMS_copy", /* RMSCOPY */
- };
-
- for (i = 0; i < NUMRMSFXNS; i++) {
- status = dev_get_symbol(dev_obj, psz_fxns[i],
- &(hnode_mgr->fxn_addrs[i]));
- if (status) {
- if (status == -ESPIPE) {
- /*
- * May be loaded dynamically (in the future),
- * but return an error for now.
- */
- dev_dbg(bridge, "%s: RMS function: %s currently"
- " not loaded\n", __func__, psz_fxns[i]);
- } else {
- dev_dbg(bridge, "%s: Symbol not found: %s "
- "status = 0x%x\n", __func__,
- psz_fxns[i], status);
- break;
- }
- }
- }
-
- return status;
-}
-
-/*
- * ======== ovly ========
- * Purpose:
- * Called during overlay.Sends command to RMS to copy a block of data.
- */
-static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
- u32 ul_num_bytes, u32 mem_space)
-{
- struct node_object *hnode = (struct node_object *)priv_ref;
- struct node_mgr *hnode_mgr;
- u32 ul_bytes = 0;
- u32 ul_size;
- u32 ul_timeout;
- int status = 0;
- struct bridge_dev_context *hbridge_context;
- /* Function interface to Bridge driver*/
- struct bridge_drv_interface *intf_fxns;
-
- hnode_mgr = hnode->node_mgr;
-
- ul_size = ul_num_bytes / hnode_mgr->dsp_word_size;
- ul_timeout = hnode->timeout;
-
- /* Call new MemCopy function */
- intf_fxns = hnode_mgr->intf_fxns;
- status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context);
- if (!status) {
- status =
- (*intf_fxns->brd_mem_copy) (hbridge_context,
- dsp_run_addr, dsp_load_addr,
- ul_num_bytes, (u32) mem_space);
- if (!status)
- ul_bytes = ul_num_bytes;
- else
- pr_debug("%s: failed to copy brd memory, status 0x%x\n",
- __func__, status);
- } else {
- pr_debug("%s: failed to get Bridge context, status 0x%x\n",
- __func__, status);
- }
-
- return ul_bytes;
-}
-
-/*
- * ======== mem_write ========
- */
-static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
- u32 ul_num_bytes, u32 mem_space)
-{
- struct node_object *hnode = (struct node_object *)priv_ref;
- struct node_mgr *hnode_mgr;
- u16 mem_sect_type;
- u32 ul_timeout;
- int status = 0;
- struct bridge_dev_context *hbridge_context;
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
-
- hnode_mgr = hnode->node_mgr;
-
- ul_timeout = hnode->timeout;
- mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA;
-
- /* Call new MemWrite function */
- intf_fxns = hnode_mgr->intf_fxns;
- status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context);
- status = (*intf_fxns->brd_mem_write) (hbridge_context, pbuf,
- dsp_add, ul_num_bytes, mem_sect_type);
-
- return ul_num_bytes;
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/*
- * ======== node_find_addr ========
- */
-int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
- u32 offset_range, void *sym_addr_output, char *sym_name)
-{
- struct node_object *node_obj;
- int status = -ENOENT;
-
- list_for_each_entry(node_obj, &node_mgr->node_list, list_elem) {
- status = nldr_find_addr(node_obj->nldr_node_obj, sym_addr,
- offset_range, sym_addr_output, sym_name);
- if (!status) {
- pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", __func__,
- (unsigned int) node_mgr,
- sym_addr, offset_range,
- (unsigned int) sym_addr_output, sym_name);
- break;
- }
- }
-
- return status;
-}
-#endif
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
deleted file mode 100644
index cd5235a4f77c..000000000000
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ /dev/null
@@ -1,1833 +0,0 @@
-/*
- * proc.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Processor interface at the driver level.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-/* ------------------------------------ Host OS */
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/ntfy.h>
-#include <dspbridge/sync.h>
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdefs.h>
-#include <dspbridge/dspdeh.h>
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/cod.h>
-#include <dspbridge/dev.h>
-#include <dspbridge/procpriv.h>
-#include <dspbridge/dmm.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/mgr.h>
-#include <dspbridge/node.h>
-#include <dspbridge/nldr.h>
-#include <dspbridge/rmm.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/dbdcd.h>
-#include <dspbridge/msg.h>
-#include <dspbridge/dspioctl.h>
-#include <dspbridge/drv.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/proc.h>
-#include <dspbridge/pwr.h>
-
-#include <dspbridge/resourcecleanup.h>
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define MAXCMDLINELEN 255
-#define PROC_ENVPROCID "PROC_ID=%d"
-#define MAXPROCIDLEN (8 + 5)
-#define PROC_DFLT_TIMEOUT 10000 /* Time out in milliseconds */
-#define PWR_TIMEOUT 500 /* Sleep/wake timout in msec */
-#define EXTEND "_EXT_END" /* Extmem end addr in DSP binary */
-
-#define DSP_CACHE_LINE 128
-
-#define BUFMODE_MASK (3 << 14)
-
-/* Buffer modes from DSP perspective */
-#define RBUF 0x4000 /* Input buffer */
-#define WBUF 0x8000 /* Output Buffer */
-
-extern struct device *bridge;
-
-/* ----------------------------------- Globals */
-
-/* The proc_object structure. */
-struct proc_object {
- struct list_head link; /* Link to next proc_object */
- struct dev_object *dev_obj; /* Device this PROC represents */
- u32 process; /* Process owning this Processor */
- struct mgr_object *mgr_obj; /* Manager Object Handle */
- u32 attach_count; /* Processor attach count */
- u32 processor_id; /* Processor number */
- u32 timeout; /* Time out count */
- enum dsp_procstate proc_state; /* Processor state */
- u32 unit; /* DDSP unit number */
- bool is_already_attached; /*
- * True if the Device below has
- * GPP Client attached
- */
- struct ntfy_object *ntfy_obj; /* Manages notifications */
- /* Bridge Context Handle */
- struct bridge_dev_context *bridge_context;
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
- char *last_coff;
- struct list_head proc_list;
-};
-
-DEFINE_MUTEX(proc_lock); /* For critical sections */
-
-/* ----------------------------------- Function Prototypes */
-static int proc_monitor(struct proc_object *proc_obj);
-static s32 get_envp_count(char **envp);
-static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
- s32 cnew_envp, char *sz_var);
-
-/* remember mapping information */
-static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
- u32 mpu_addr, u32 dsp_addr, u32 size)
-{
- struct dmm_map_object *map_obj;
-
- u32 num_usr_pgs = size / PG_SIZE4K;
-
- pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n",
- __func__, mpu_addr,
- dsp_addr, size);
-
- map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL);
- if (!map_obj)
- return NULL;
-
- INIT_LIST_HEAD(&map_obj->link);
-
- map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *),
- GFP_KERNEL);
- if (!map_obj->pages) {
- kfree(map_obj);
- return NULL;
- }
-
- map_obj->mpu_addr = mpu_addr;
- map_obj->dsp_addr = dsp_addr;
- map_obj->size = size;
- map_obj->num_usr_pgs = num_usr_pgs;
-
- spin_lock(&pr_ctxt->dmm_map_lock);
- list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
- spin_unlock(&pr_ctxt->dmm_map_lock);
-
- return map_obj;
-}
-
-static int match_exact_map_obj(struct dmm_map_object *map_obj,
- u32 dsp_addr, u32 size)
-{
- if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
- pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
- __func__, dsp_addr, map_obj->size, size);
-
- return map_obj->dsp_addr == dsp_addr &&
- map_obj->size == size;
-}
-
-static void remove_mapping_information(struct process_context *pr_ctxt,
- u32 dsp_addr, u32 size)
-{
- struct dmm_map_object *map_obj;
-
- pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
- dsp_addr, size);
-
- spin_lock(&pr_ctxt->dmm_map_lock);
- list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
- pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
- __func__,
- map_obj->mpu_addr,
- map_obj->dsp_addr,
- map_obj->size);
-
- if (match_exact_map_obj(map_obj, dsp_addr, size)) {
- pr_debug("%s: match, deleting map info\n", __func__);
- list_del(&map_obj->link);
- kfree(map_obj->dma_info.sg);
- kfree(map_obj->pages);
- kfree(map_obj);
- goto out;
- }
- pr_debug("%s: candidate didn't match\n", __func__);
- }
-
- pr_err("%s: failed to find given map info\n", __func__);
-out:
- spin_unlock(&pr_ctxt->dmm_map_lock);
-}
-
-static int match_containing_map_obj(struct dmm_map_object *map_obj,
- u32 mpu_addr, u32 size)
-{
- u32 map_obj_end = map_obj->mpu_addr + map_obj->size;
-
- return mpu_addr >= map_obj->mpu_addr &&
- mpu_addr + size <= map_obj_end;
-}
-
-static struct dmm_map_object *find_containing_mapping(
- struct process_context *pr_ctxt,
- u32 mpu_addr, u32 size)
-{
- struct dmm_map_object *map_obj;
- pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__,
- mpu_addr, size);
-
- spin_lock(&pr_ctxt->dmm_map_lock);
- list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
- pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
- __func__,
- map_obj->mpu_addr,
- map_obj->dsp_addr,
- map_obj->size);
- if (match_containing_map_obj(map_obj, mpu_addr, size)) {
- pr_debug("%s: match!\n", __func__);
- goto out;
- }
-
- pr_debug("%s: no match!\n", __func__);
- }
-
- map_obj = NULL;
-out:
- spin_unlock(&pr_ctxt->dmm_map_lock);
- return map_obj;
-}
-
-static int find_first_page_in_cache(struct dmm_map_object *map_obj,
- unsigned long mpu_addr)
-{
- u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT;
- u32 requested_base_page = mpu_addr >> PAGE_SHIFT;
- int pg_index = requested_base_page - mapped_base_page;
-
- if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) {
- pr_err("%s: failed (got %d)\n", __func__, pg_index);
- return -1;
- }
-
- pr_debug("%s: first page is %d\n", __func__, pg_index);
- return pg_index;
-}
-
-static inline struct page *get_mapping_page(struct dmm_map_object *map_obj,
- int pg_i)
-{
- pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__,
- pg_i, map_obj->num_usr_pgs);
-
- if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) {
- pr_err("%s: requested pg_i %d is out of mapped range\n",
- __func__, pg_i);
- return NULL;
- }
-
- return map_obj->pages[pg_i];
-}
-
-/*
- * ======== proc_attach ========
- * Purpose:
- * Prepare for communication with a particular DSP processor, and return
- * a handle to the processor object.
- */
-int
-proc_attach(u32 processor_id,
- const struct dsp_processorattrin *attr_in,
- void **ph_processor, struct process_context *pr_ctxt)
-{
- int status = 0;
- struct dev_object *hdev_obj;
- struct proc_object *p_proc_object = NULL;
- struct mgr_object *hmgr_obj = NULL;
- struct drv_object *hdrv_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- u8 dev_type;
-
- if (pr_ctxt->processor) {
- *ph_processor = pr_ctxt->processor;
- return status;
- }
-
- /* Get the Driver and Manager Object Handles */
- if (!drv_datap || !drv_datap->drv_object || !drv_datap->mgr_object) {
- status = -ENODATA;
- pr_err("%s: Failed to get object handles\n", __func__);
- } else {
- hdrv_obj = drv_datap->drv_object;
- hmgr_obj = drv_datap->mgr_object;
- }
-
- if (!status) {
- /* Get the Device Object */
- status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
- }
- if (!status)
- status = dev_get_dev_type(hdev_obj, &dev_type);
-
- if (status)
- goto func_end;
-
- /* If we made it this far, create the Processor object: */
- p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
- /* Fill out the Processor Object: */
- if (p_proc_object == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
- p_proc_object->dev_obj = hdev_obj;
- p_proc_object->mgr_obj = hmgr_obj;
- p_proc_object->processor_id = dev_type;
- /* Store TGID instead of process handle */
- p_proc_object->process = current->tgid;
-
- INIT_LIST_HEAD(&p_proc_object->proc_list);
-
- if (attr_in)
- p_proc_object->timeout = attr_in->timeout;
- else
- p_proc_object->timeout = PROC_DFLT_TIMEOUT;
-
- status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
- if (!status) {
- status = dev_get_bridge_context(hdev_obj,
- &p_proc_object->bridge_context);
- if (status)
- kfree(p_proc_object);
- } else
- kfree(p_proc_object);
-
- if (status)
- goto func_end;
-
- /* Create the Notification Object */
- /* This is created with no event mask, no notify mask
- * and no valid handle to the notification. They all get
- * filled up when proc_register_notify is called */
- p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
- GFP_KERNEL);
- if (p_proc_object->ntfy_obj)
- ntfy_init(p_proc_object->ntfy_obj);
- else
- status = -ENOMEM;
-
- if (!status) {
- /* Insert the Processor Object into the DEV List.
- * Return handle to this Processor Object:
- * Find out if the Device is already attached to a
- * Processor. If so, return AlreadyAttached status */
- status = dev_insert_proc_object(p_proc_object->dev_obj,
- (u32) p_proc_object,
- &p_proc_object->
- is_already_attached);
- if (!status) {
- if (p_proc_object->is_already_attached)
- status = 0;
- } else {
- if (p_proc_object->ntfy_obj) {
- ntfy_delete(p_proc_object->ntfy_obj);
- kfree(p_proc_object->ntfy_obj);
- }
-
- kfree(p_proc_object);
- }
- if (!status) {
- *ph_processor = (void *)p_proc_object;
- pr_ctxt->processor = *ph_processor;
- (void)proc_notify_clients(p_proc_object,
- DSP_PROCESSORATTACH);
- }
- } else {
- /* Don't leak memory if status is failed */
- kfree(p_proc_object);
- }
-func_end:
- return status;
-}
-
-static int get_exec_file(struct cfg_devnode *dev_node_obj,
- struct dev_object *hdev_obj,
- u32 size, char *exec_file)
-{
- u8 dev_type;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
- dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
-
- if (!exec_file)
- return -EFAULT;
-
- if (dev_type == DSP_UNIT) {
- if (!drv_datap || !drv_datap->base_img)
- return -EFAULT;
-
- if (strlen(drv_datap->base_img) >= size)
- return -EINVAL;
-
- strcpy(exec_file, drv_datap->base_img);
- } else {
- return -ENOENT;
- }
-
- return 0;
-}
-
-/*
- * ======== proc_auto_start ======== =
- * Purpose:
- * A Particular device gets loaded with the default image
- * if the AutoStart flag is set.
- * Parameters:
- * hdev_obj: Handle to the Device
- * Returns:
- * 0: On Successful Loading
- * -EPERM General Failure
- * Requires:
- * hdev_obj != NULL
- * Ensures:
- */
-int proc_auto_start(struct cfg_devnode *dev_node_obj,
- struct dev_object *hdev_obj)
-{
- int status = -EPERM;
- struct proc_object *p_proc_object;
- char sz_exec_file[MAXCMDLINELEN];
- char *argv[2];
- struct mgr_object *hmgr_obj = NULL;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
- u8 dev_type;
-
- /* Create a Dummy PROC Object */
- if (!drv_datap || !drv_datap->mgr_object) {
- status = -ENODATA;
- pr_err("%s: Failed to retrieve the object handle\n", __func__);
- goto func_end;
- } else {
- hmgr_obj = drv_datap->mgr_object;
- }
-
- p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
- if (p_proc_object == NULL) {
- status = -ENOMEM;
- goto func_end;
- }
- p_proc_object->dev_obj = hdev_obj;
- p_proc_object->mgr_obj = hmgr_obj;
- status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
- if (!status)
- status = dev_get_bridge_context(hdev_obj,
- &p_proc_object->bridge_context);
- if (status)
- goto func_cont;
-
- /* Stop the Device, put it into standby mode */
- status = proc_stop(p_proc_object);
-
- if (status)
- goto func_cont;
-
- /* Get the default executable for this board... */
- dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
- p_proc_object->processor_id = dev_type;
- status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file),
- sz_exec_file);
- if (!status) {
- argv[0] = sz_exec_file;
- argv[1] = NULL;
- /* ...and try to load it: */
- status = proc_load(p_proc_object, 1, (const char **)argv, NULL);
- if (!status)
- status = proc_start(p_proc_object);
- }
- kfree(p_proc_object->last_coff);
- p_proc_object->last_coff = NULL;
-func_cont:
- kfree(p_proc_object);
-func_end:
- return status;
-}
-
-/*
- * ======== proc_ctrl ========
- * Purpose:
- * Pass control information to the GPP device driver managing the
- * DSP processor.
- *
- * This will be an OEM-only function, and not part of the DSP/BIOS Bridge
- * application developer's API.
- * Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous
- * Operation. arg can be null.
- */
-int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata *arg)
-{
- int status = 0;
- struct proc_object *p_proc_object = hprocessor;
- u32 timeout = 0;
-
- if (p_proc_object) {
- /* intercept PWR deep sleep command */
- if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
- timeout = arg->cb_data;
- status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
- }
- /* intercept PWR emergency sleep command */
- else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) {
- timeout = arg->cb_data;
- status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout);
- } else if (dw_cmd == PWR_DEEPSLEEP) {
- /* timeout = arg->cb_data; */
- status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
- }
- /* intercept PWR wake commands */
- else if (dw_cmd == BRDIOCTL_WAKEUP) {
- timeout = arg->cb_data;
- status = pwr_wake_dsp(timeout);
- } else if (dw_cmd == PWR_WAKEUP) {
- /* timeout = arg->cb_data; */
- status = pwr_wake_dsp(timeout);
- } else
- if (!((*p_proc_object->intf_fxns->dev_cntrl)
- (p_proc_object->bridge_context, dw_cmd,
- arg))) {
- status = 0;
- } else {
- status = -EPERM;
- }
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== proc_detach ========
- * Purpose:
- * Destroys the Processor Object. Removes the notification from the Dev
- * List.
- */
-int proc_detach(struct process_context *pr_ctxt)
-{
- int status = 0;
- struct proc_object *p_proc_object = NULL;
-
- p_proc_object = (struct proc_object *)pr_ctxt->processor;
-
- if (p_proc_object) {
- /* Notify the Client */
- ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH);
- /* Remove the notification memory */
- if (p_proc_object->ntfy_obj) {
- ntfy_delete(p_proc_object->ntfy_obj);
- kfree(p_proc_object->ntfy_obj);
- }
-
- kfree(p_proc_object->last_coff);
- p_proc_object->last_coff = NULL;
- /* Remove the Proc from the DEV List */
- (void)dev_remove_proc_object(p_proc_object->dev_obj,
- (u32) p_proc_object);
- /* Free the Processor Object */
- kfree(p_proc_object);
- pr_ctxt->processor = NULL;
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== proc_enum_nodes ========
- * Purpose:
- * Enumerate and get configuration information about nodes allocated
- * on a DSP processor.
- */
-int proc_enum_nodes(void *hprocessor, void **node_tab,
- u32 node_tab_size, u32 *pu_num_nodes,
- u32 *pu_allocated)
-{
- int status = -EPERM;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct node_mgr *hnode_mgr = NULL;
-
- if (p_proc_object) {
- if (!(dev_get_node_manager(p_proc_object->dev_obj,
- &hnode_mgr))) {
- if (hnode_mgr) {
- status = node_enum_nodes(hnode_mgr, node_tab,
- node_tab_size,
- pu_num_nodes,
- pu_allocated);
- }
- }
- } else {
- status = -EFAULT;
- }
-
- return status;
-}
-
-/* Cache operation against kernel address instead of users */
-static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start,
- ssize_t len, int pg_i)
-{
- struct page *page;
- unsigned long offset;
- ssize_t rest;
- int ret = 0, i = 0;
- struct scatterlist *sg = map_obj->dma_info.sg;
-
- while (len) {
- page = get_mapping_page(map_obj, pg_i);
- if (!page) {
- pr_err("%s: no page for %08lx\n", __func__, start);
- ret = -EINVAL;
- goto out;
- } else if (IS_ERR(page)) {
- pr_err("%s: err page for %08lx(%lu)\n", __func__, start,
- PTR_ERR(page));
- ret = PTR_ERR(page);
- goto out;
- }
-
- offset = start & ~PAGE_MASK;
- rest = min_t(ssize_t, PAGE_SIZE - offset, len);
-
- sg_set_page(&sg[i], page, rest, offset);
-
- len -= rest;
- start += rest;
- pg_i++, i++;
- }
-
- if (i != map_obj->dma_info.num_pages) {
- pr_err("%s: bad number of sg iterations\n", __func__);
- ret = -EFAULT;
- goto out;
- }
-
-out:
- return ret;
-}
-
-static int memory_regain_ownership(struct dmm_map_object *map_obj,
- unsigned long start, ssize_t len, enum dma_data_direction dir)
-{
- int ret = 0;
- unsigned long first_data_page = start >> PAGE_SHIFT;
- unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
- /* calculating the number of pages this area spans */
- unsigned long num_pages = last_data_page - first_data_page + 1;
- struct bridge_dma_map_info *dma_info = &map_obj->dma_info;
-
- if (!dma_info->sg)
- goto out;
-
- if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
- pr_err("%s: dma info doesn't match given params\n", __func__);
- return -EINVAL;
- }
-
- dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);
-
- pr_debug("%s: dma_map_sg unmapped\n", __func__);
-
- kfree(dma_info->sg);
-
- map_obj->dma_info.sg = NULL;
-
-out:
- return ret;
-}
-
-/* Cache operation against kernel address instead of users */
-static int memory_give_ownership(struct dmm_map_object *map_obj,
- unsigned long start, ssize_t len, enum dma_data_direction dir)
-{
- int pg_i, ret, sg_num;
- struct scatterlist *sg;
- unsigned long first_data_page = start >> PAGE_SHIFT;
- unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
- /* calculating the number of pages this area spans */
- unsigned long num_pages = last_data_page - first_data_page + 1;
-
- pg_i = find_first_page_in_cache(map_obj, start);
- if (pg_i < 0) {
- pr_err("%s: failed to find first page in cache\n", __func__);
- ret = -EINVAL;
- goto out;
- }
-
- sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL);
- if (!sg) {
- ret = -ENOMEM;
- goto out;
- }
-
- sg_init_table(sg, num_pages);
-
- /* cleanup a previous sg allocation */
- /* this may happen if application doesn't signal for e/o DMA */
- kfree(map_obj->dma_info.sg);
-
- map_obj->dma_info.sg = sg;
- map_obj->dma_info.dir = dir;
- map_obj->dma_info.num_pages = num_pages;
-
- ret = build_dma_sg(map_obj, start, len, pg_i);
- if (ret)
- goto kfree_sg;
-
- sg_num = dma_map_sg(bridge, sg, num_pages, dir);
- if (sg_num < 1) {
- pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num);
- ret = -EFAULT;
- goto kfree_sg;
- }
-
- pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num);
- map_obj->dma_info.sg_num = sg_num;
-
- return 0;
-
-kfree_sg:
- kfree(sg);
- map_obj->dma_info.sg = NULL;
-out:
- return ret;
-}
-
-int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
- enum dma_data_direction dir)
-{
- /* Keep STATUS here for future additions to this function */
- int status = 0;
- struct process_context *pr_ctxt = (struct process_context *) hprocessor;
- struct dmm_map_object *map_obj;
-
- if (!pr_ctxt) {
- status = -EFAULT;
- goto err_out;
- }
-
- pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
- (u32)pmpu_addr,
- ul_size, dir);
-
- mutex_lock(&proc_lock);
-
- /* find requested memory are in cached mapping information */
- map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
- if (!map_obj) {
- pr_err("%s: find_containing_mapping failed\n", __func__);
- status = -EFAULT;
- goto no_map;
- }
-
- if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
- pr_err("%s: InValid address parameters %p %x\n",
- __func__, pmpu_addr, ul_size);
- status = -EFAULT;
- }
-
-no_map:
- mutex_unlock(&proc_lock);
-err_out:
-
- return status;
-}
-
-int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
- enum dma_data_direction dir)
-{
- /* Keep STATUS here for future additions to this function */
- int status = 0;
- struct process_context *pr_ctxt = (struct process_context *) hprocessor;
- struct dmm_map_object *map_obj;
-
- if (!pr_ctxt) {
- status = -EFAULT;
- goto err_out;
- }
-
- pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
- (u32)pmpu_addr,
- ul_size, dir);
-
- mutex_lock(&proc_lock);
-
- /* find requested memory are in cached mapping information */
- map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
- if (!map_obj) {
- pr_err("%s: find_containing_mapping failed\n", __func__);
- status = -EFAULT;
- goto no_map;
- }
-
- if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
- pr_err("%s: InValid address parameters %p %x\n",
- __func__, pmpu_addr, ul_size);
- status = -EFAULT;
- }
-
-no_map:
- mutex_unlock(&proc_lock);
-err_out:
- return status;
-}
-
-/*
- * ======== proc_flush_memory ========
- * Purpose:
- * Flush cache
- */
-int proc_flush_memory(void *hprocessor, void *pmpu_addr,
- u32 ul_size, u32 ul_flags)
-{
- enum dma_data_direction dir = DMA_BIDIRECTIONAL;
-
- return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir);
-}
-
-/*
- * ======== proc_invalidate_memory ========
- * Purpose:
- * Invalidates the memory specified
- */
-int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size)
-{
- enum dma_data_direction dir = DMA_FROM_DEVICE;
-
- return proc_begin_dma(hprocessor, pmpu_addr, size, dir);
-}
-
-/*
- * ======== proc_get_resource_info ========
- * Purpose:
- * Enumerate the resources currently available on a processor.
- */
-int proc_get_resource_info(void *hprocessor, u32 resource_type,
- struct dsp_resourceinfo *resource_info,
- u32 resource_info_size)
-{
- int status = -EPERM;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct node_mgr *hnode_mgr = NULL;
- struct nldr_object *nldr_obj = NULL;
- struct rmm_target_obj *rmm = NULL;
- struct io_mgr *hio_mgr = NULL; /* IO manager handle */
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- switch (resource_type) {
- case DSP_RESOURCE_DYNDARAM:
- case DSP_RESOURCE_DYNSARAM:
- case DSP_RESOURCE_DYNEXTERNAL:
- case DSP_RESOURCE_DYNSRAM:
- status = dev_get_node_manager(p_proc_object->dev_obj,
- &hnode_mgr);
- if (!hnode_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = node_get_nldr_obj(hnode_mgr, &nldr_obj);
- if (!status) {
- status = nldr_get_rmm_manager(nldr_obj, &rmm);
- if (rmm) {
- if (!rmm_stat(rmm,
- (enum dsp_memtype)resource_type,
- (struct dsp_memstat *)
- &(resource_info->result.
- mem_stat)))
- status = -EINVAL;
- } else {
- status = -EFAULT;
- }
- }
- break;
- case DSP_RESOURCE_PROCLOAD:
- status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
- if (hio_mgr)
- status =
- p_proc_object->intf_fxns->
- io_get_proc_load(hio_mgr,
- (struct dsp_procloadstat *)
- &(resource_info->result.
- proc_load_stat));
- else
- status = -EFAULT;
- break;
- default:
- status = -EPERM;
- break;
- }
-func_end:
- return status;
-}
-
-/*
- * ======== proc_get_dev_object ========
- * Purpose:
- * Return the Dev Object handle for a given Processor.
- *
- */
-int proc_get_dev_object(void *hprocessor,
- struct dev_object **device_obj)
-{
- int status = -EPERM;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
-
- if (p_proc_object) {
- *device_obj = p_proc_object->dev_obj;
- status = 0;
- } else {
- *device_obj = NULL;
- status = -EFAULT;
- }
-
- return status;
-}
-
-/*
- * ======== proc_get_state ========
- * Purpose:
- * Report the state of the specified DSP processor.
- */
-int proc_get_state(void *hprocessor,
- struct dsp_processorstate *proc_state_obj,
- u32 state_info_size)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- int brd_status;
-
- if (p_proc_object) {
- /* First, retrieve BRD state information */
- status = (*p_proc_object->intf_fxns->brd_status)
- (p_proc_object->bridge_context, &brd_status);
- if (!status) {
- switch (brd_status) {
- case BRD_STOPPED:
- proc_state_obj->proc_state = PROC_STOPPED;
- break;
- case BRD_SLEEP_TRANSITION:
- case BRD_DSP_HIBERNATION:
- /* Fall through */
- case BRD_RUNNING:
- proc_state_obj->proc_state = PROC_RUNNING;
- break;
- case BRD_LOADED:
- proc_state_obj->proc_state = PROC_LOADED;
- break;
- case BRD_ERROR:
- proc_state_obj->proc_state = PROC_ERROR;
- break;
- default:
- proc_state_obj->proc_state = 0xFF;
- status = -EPERM;
- break;
- }
- }
- } else {
- status = -EFAULT;
- }
- dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n",
- __func__, status, proc_state_obj->proc_state);
- return status;
-}
-
-/*
- * ======== proc_get_trace ========
- * Purpose:
- * Retrieve the current contents of the trace buffer, located on the
- * Processor. Predefined symbols for the trace buffer must have been
- * configured into the DSP executable.
- * Details:
- * We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a
- * trace buffer, only. Treat it as an undocumented feature.
- * This call is destructive, meaning the processor is placed in the monitor
- * state as a result of this function.
- */
-int proc_get_trace(void *hprocessor, u8 *pbuf, u32 max_size)
-{
- int status;
- status = -ENOSYS;
- return status;
-}
-
-/*
- * ======== proc_load ========
- * Purpose:
- * Reset a processor and load a new base program image.
- * This will be an OEM-only function, and not part of the DSP/BIOS Bridge
- * application developer's API.
- */
-int proc_load(void *hprocessor, const s32 argc_index,
- const char **user_args, const char **user_envp)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct io_mgr *hio_mgr; /* IO manager handle */
- struct msg_mgr *hmsg_mgr;
- struct cod_manager *cod_mgr; /* Code manager handle */
- char *pargv0; /* temp argv[0] ptr */
- char **new_envp; /* Updated envp[] array. */
- char sz_proc_id[MAXPROCIDLEN]; /* Size of "PROC_ID=<n>" */
- s32 envp_elems; /* Num elements in envp[]. */
- s32 cnew_envp; /* " " in new_envp[] */
- s32 nproc_id = 0; /* Anticipate MP version. */
- struct dcd_manager *hdcd_handle;
- struct dmm_object *dmm_mgr;
- u32 dw_ext_end;
- u32 proc_id;
- int brd_state;
- struct drv_data *drv_datap = dev_get_drvdata(bridge);
-
-#ifdef OPT_LOAD_TIME_INSTRUMENTATION
- struct timeval tv1;
- struct timeval tv2;
-#endif
-
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- struct dspbridge_platform_data *pdata =
- omap_dspbridge_dev->dev.platform_data;
-#endif
-
-#ifdef OPT_LOAD_TIME_INSTRUMENTATION
- do_gettimeofday(&tv1);
-#endif
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
- if (!cod_mgr) {
- status = -EPERM;
- goto func_end;
- }
- status = proc_stop(hprocessor);
- if (status)
- goto func_end;
-
- /* Place the board in the monitor state. */
- status = proc_monitor(hprocessor);
- if (status)
- goto func_end;
-
- /* Save ptr to original argv[0]. */
- pargv0 = (char *)user_args[0];
- /*Prepend "PROC_ID=<nproc_id>"to envp array for target. */
- envp_elems = get_envp_count((char **)user_envp);
- cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2));
- new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL);
- if (new_envp) {
- status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID,
- nproc_id);
- if (status == -1) {
- dev_dbg(bridge, "%s: Proc ID string overflow\n",
- __func__);
- status = -EPERM;
- } else {
- new_envp =
- prepend_envp(new_envp, (char **)user_envp,
- envp_elems, cnew_envp, sz_proc_id);
- /* Get the DCD Handle */
- status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
- (u32 *) &hdcd_handle);
- if (!status) {
- /* Before proceeding with new load,
- * check if a previously registered COFF
- * exists.
- * If yes, unregister nodes in previously
- * registered COFF. If any error occurred,
- * set previously registered COFF to NULL. */
- if (p_proc_object->last_coff != NULL) {
- status =
- dcd_auto_unregister(hdcd_handle,
- p_proc_object->
- last_coff);
- /* Regardless of auto unregister status,
- * free previously allocated
- * memory. */
- kfree(p_proc_object->last_coff);
- p_proc_object->last_coff = NULL;
- }
- }
- /* On success, do cod_open_base() */
- status = cod_open_base(cod_mgr, (char *)user_args[0],
- COD_SYMB);
- }
- } else {
- status = -ENOMEM;
- }
- if (!status) {
- /* Auto-register data base */
- /* Get the DCD Handle */
- status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
- (u32 *) &hdcd_handle);
- if (!status) {
- /* Auto register nodes in specified COFF
- * file. If registration did not fail,
- * (status = 0 or -EACCES)
- * save the name of the COFF file for
- * de-registration in the future. */
- status =
- dcd_auto_register(hdcd_handle,
- (char *)user_args[0]);
- if (status == -EACCES)
- status = 0;
-
- if (status) {
- status = -EPERM;
- } else {
- /* Allocate memory for pszLastCoff */
- p_proc_object->last_coff =
- kzalloc((strlen(user_args[0]) +
- 1), GFP_KERNEL);
- /* If memory allocated, save COFF file name */
- if (p_proc_object->last_coff) {
- strncpy(p_proc_object->last_coff,
- (char *)user_args[0],
- (strlen((char *)user_args[0]) +
- 1));
- }
- }
- }
- }
- /* Update shared memory address and size */
- if (!status) {
- /* Create the message manager. This must be done
- * before calling the IOOnLoaded function. */
- dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
- if (!hmsg_mgr) {
- status = msg_create(&hmsg_mgr, p_proc_object->dev_obj,
- (msg_onexit) node_on_exit);
- dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr);
- }
- }
- if (!status) {
- /* Set the Device object's message manager */
- status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
- if (hio_mgr)
- status = (*p_proc_object->intf_fxns->io_on_loaded)
- (hio_mgr);
- else
- status = -EFAULT;
- }
- if (!status) {
- /* Now, attempt to load an exec: */
-
- /* Boost the OPP level to Maximum level supported by baseport */
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- if (pdata->cpu_set_freq)
- (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]);
-#endif
- status = cod_load_base(cod_mgr, argc_index, (char **)user_args,
- dev_brd_write_fxn,
- p_proc_object->dev_obj, NULL);
- if (status) {
- if (status == -EBADF) {
- dev_dbg(bridge, "%s: Failure to Load the EXE\n",
- __func__);
- }
- if (status == -ESPIPE) {
- pr_err("%s: Couldn't parse the file\n",
- __func__);
- }
- }
- /* Requesting the lowest opp supported */
-#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
- if (pdata->cpu_set_freq)
- (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
-#endif
-
- }
- if (!status) {
- /* Update the Processor status to loaded */
- status = (*p_proc_object->intf_fxns->brd_set_state)
- (p_proc_object->bridge_context, BRD_LOADED);
- if (!status) {
- p_proc_object->proc_state = PROC_LOADED;
- if (p_proc_object->ntfy_obj)
- proc_notify_clients(p_proc_object,
- DSP_PROCESSORSTATECHANGE);
- }
- }
- if (!status) {
- status = proc_get_processor_id(hprocessor, &proc_id);
- if (proc_id == DSP_UNIT) {
- /* Use all available DSP address space after EXTMEM
- * for DMM */
- if (!status)
- status = cod_get_sym_value(cod_mgr, EXTEND,
- &dw_ext_end);
-
- /* Reset DMM structs and add an initial free chunk */
- if (!status) {
- status =
- dev_get_dmm_mgr(p_proc_object->dev_obj,
- &dmm_mgr);
- if (dmm_mgr) {
- /* Set dw_ext_end to DMM START u8
- * address */
- dw_ext_end =
- (dw_ext_end + 1) * DSPWORDSIZE;
- /* DMM memory is from EXT_END */
- status = dmm_create_tables(dmm_mgr,
- dw_ext_end,
- DMMPOOLSIZE);
- } else {
- status = -EFAULT;
- }
- }
- }
- }
- /* Restore the original argv[0] */
- kfree(new_envp);
- user_args[0] = pargv0;
- if (!status) {
- if (!((*p_proc_object->intf_fxns->brd_status)
- (p_proc_object->bridge_context, &brd_state))) {
- pr_info("%s: Processor Loaded %s\n", __func__, pargv0);
- kfree(drv_datap->base_img);
- drv_datap->base_img = kstrdup(pargv0, GFP_KERNEL);
- if (!drv_datap->base_img)
- status = -ENOMEM;
- }
- }
-
-func_end:
- if (status) {
- pr_err("%s: Processor failed to load\n", __func__);
- proc_stop(p_proc_object);
- }
-#ifdef OPT_LOAD_TIME_INSTRUMENTATION
- do_gettimeofday(&tv2);
- if (tv2.tv_usec < tv1.tv_usec) {
- tv2.tv_usec += 1000000;
- tv2.tv_sec--;
- }
- dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__,
- tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
-#endif
- return status;
-}
-
-/*
- * ======== proc_map ========
- * Purpose:
- * Maps a MPU buffer to DSP address space.
- */
-int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
- void *req_addr, void **pp_map_addr, u32 ul_map_attr,
- struct process_context *pr_ctxt)
-{
- u32 va_align;
- u32 pa_align;
- struct dmm_object *dmm_mgr;
- u32 size_align;
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_map_object *map_obj;
- u32 tmp_addr = 0;
-
-#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
- if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
- if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) ||
- !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) {
- pr_err("%s: not aligned: 0x%x (%d)\n", __func__,
- (u32)pmpu_addr, ul_size);
- return -EFAULT;
- }
- }
-#endif
-
- /* Calculate the page-aligned PA, VA and size */
- va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K);
- pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K);
- size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align,
- PG_SIZE4K);
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- /* Critical section */
- mutex_lock(&proc_lock);
- dmm_get_handle(p_proc_object, &dmm_mgr);
- if (dmm_mgr)
- status = dmm_map_memory(dmm_mgr, va_align, size_align);
- else
- status = -EFAULT;
-
- /* Add mapping to the page tables. */
- if (!status) {
-
- /* Mapped address = MSB of VA | LSB of PA */
- tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
- /* mapped memory resource tracking */
- map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
- size_align);
- if (!map_obj)
- status = -ENOMEM;
- else
- status = (*p_proc_object->intf_fxns->brd_mem_map)
- (p_proc_object->bridge_context, pa_align, va_align,
- size_align, ul_map_attr, map_obj->pages);
- }
- if (!status) {
- /* Mapped address = MSB of VA | LSB of PA */
- *pp_map_addr = (void *) tmp_addr;
- } else {
- remove_mapping_information(pr_ctxt, tmp_addr, size_align);
- dmm_un_map_memory(dmm_mgr, va_align, &size_align);
- }
- mutex_unlock(&proc_lock);
-
- if (status)
- goto func_end;
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, "
- "req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, "
- "pa_align %x, size_align %x status 0x%x\n", __func__,
- hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr,
- pp_map_addr, va_align, pa_align, size_align, status);
-
- return status;
-}
-
-/*
- * ======== proc_register_notify ========
- * Purpose:
- * Register to be notified of specific processor events.
- */
-int proc_register_notify(void *hprocessor, u32 event_mask,
- u32 notify_type, struct dsp_notification
- *hnotification)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct deh_mgr *hdeh_mgr;
-
- /* Check processor handle */
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- /* Check if event mask is a valid processor related event */
- if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
- DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
- DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
- DSP_WDTOVERFLOW))
- status = -EINVAL;
-
- /* Check if notify type is valid */
- if (notify_type != DSP_SIGNALEVENT)
- status = -EINVAL;
-
- if (!status) {
- /* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
- * or DSP_PWRERROR then register event immediately. */
- if (event_mask &
- ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
- DSP_WDTOVERFLOW)) {
- status = ntfy_register(p_proc_object->ntfy_obj,
- hnotification, event_mask,
- notify_type);
- /* Special case alert, special case alert!
- * If we're trying to *deregister* (i.e. event_mask
- * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification,
- * we have to deregister with the DEH manager.
- * There's no way to know, based on event_mask which
- * manager the notification event was registered with,
- * so if we're trying to deregister and ntfy_register
- * failed, we'll give the deh manager a shot.
- */
- if ((event_mask == 0) && status) {
- status =
- dev_get_deh_mgr(p_proc_object->dev_obj,
- &hdeh_mgr);
- status =
- bridge_deh_register_notify(hdeh_mgr,
- event_mask,
- notify_type,
- hnotification);
- }
- } else {
- status = dev_get_deh_mgr(p_proc_object->dev_obj,
- &hdeh_mgr);
- status =
- bridge_deh_register_notify(hdeh_mgr,
- event_mask,
- notify_type,
- hnotification);
-
- }
- }
-func_end:
- return status;
-}
-
-/*
- * ======== proc_reserve_memory ========
- * Purpose:
- * Reserve a virtually contiguous region of DSP address space.
- */
-int proc_reserve_memory(void *hprocessor, u32 ul_size,
- void **pp_rsv_addr,
- struct process_context *pr_ctxt)
-{
- struct dmm_object *dmm_mgr;
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_rsv_object *rsv_obj;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
- if (status != 0)
- goto func_end;
-
- /*
- * A successful reserve should be followed by insertion of rsv_obj
- * into dmm_rsv_list, so that reserved memory resource tracking
- * remains uptodate
- */
- rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
- if (rsv_obj) {
- rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
- spin_lock(&pr_ctxt->dmm_rsv_lock);
- list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
- spin_unlock(&pr_ctxt->dmm_rsv_lock);
- }
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
- "status 0x%x\n", __func__, hprocessor,
- ul_size, pp_rsv_addr, status);
- return status;
-}
-
-/*
- * ======== proc_start ========
- * Purpose:
- * Start a processor running.
- */
-int proc_start(void *hprocessor)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct cod_manager *cod_mgr; /* Code manager handle */
- u32 dw_dsp_addr; /* Loaded code's entry point. */
- int brd_state;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- /* Call the bridge_brd_start */
- if (p_proc_object->proc_state != PROC_LOADED) {
- status = -EBADR;
- goto func_end;
- }
- status = dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
- if (!cod_mgr) {
- status = -EFAULT;
- goto func_cont;
- }
-
- status = cod_get_entry(cod_mgr, &dw_dsp_addr);
- if (status)
- goto func_cont;
-
- status = (*p_proc_object->intf_fxns->brd_start)
- (p_proc_object->bridge_context, dw_dsp_addr);
- if (status)
- goto func_cont;
-
- /* Call dev_create2 */
- status = dev_create2(p_proc_object->dev_obj);
- if (!status) {
- p_proc_object->proc_state = PROC_RUNNING;
- /* Deep sleep switces off the peripheral clocks.
- * we just put the DSP CPU in idle in the idle loop.
- * so there is no need to send a command to DSP */
-
- if (p_proc_object->ntfy_obj) {
- proc_notify_clients(p_proc_object,
- DSP_PROCESSORSTATECHANGE);
- }
- } else {
- /* Failed to Create Node Manager and DISP Object
- * Stop the Processor from running. Put it in STOPPED State */
- (void)(*p_proc_object->intf_fxns->
- brd_stop) (p_proc_object->bridge_context);
- p_proc_object->proc_state = PROC_STOPPED;
- }
-func_cont:
- if (!status) {
- if (!((*p_proc_object->intf_fxns->brd_status)
- (p_proc_object->bridge_context, &brd_state))) {
- pr_info("%s: dsp in running state\n", __func__);
- }
- } else {
- pr_err("%s: Failed to start the dsp\n", __func__);
- proc_stop(p_proc_object);
- }
-
-func_end:
- return status;
-}
-
-/*
- * ======== proc_stop ========
- * Purpose:
- * Stop a processor running.
- */
-int proc_stop(void *hprocessor)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct msg_mgr *hmsg_mgr;
- struct node_mgr *hnode_mgr;
- void *hnode;
- u32 node_tab_size = 1;
- u32 num_nodes = 0;
- u32 nodes_allocated = 0;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
- /* check if there are any running nodes */
- status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr);
- if (!status && hnode_mgr) {
- status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size,
- &num_nodes, &nodes_allocated);
- if ((status == -EINVAL) || (nodes_allocated > 0)) {
- pr_err("%s: Can't stop device, active nodes = %d\n",
- __func__, nodes_allocated);
- return -EBADR;
- }
- }
- /* Call the bridge_brd_stop */
- /* It is OK to stop a device that does n't have nodes OR not started */
- status =
- (*p_proc_object->intf_fxns->
- brd_stop) (p_proc_object->bridge_context);
- if (!status) {
- dev_dbg(bridge, "%s: processor in standby mode\n", __func__);
- p_proc_object->proc_state = PROC_STOPPED;
- /* Destroy the Node Manager, msg_ctrl Manager */
- if (!(dev_destroy2(p_proc_object->dev_obj))) {
- /* Destroy the msg_ctrl by calling msg_delete */
- dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
- if (hmsg_mgr) {
- msg_delete(hmsg_mgr);
- dev_set_msg_mgr(p_proc_object->dev_obj, NULL);
- }
- }
- } else {
- pr_err("%s: Failed to stop the processor\n", __func__);
- }
-func_end:
-
- return status;
-}
-
-/*
- * ======== proc_un_map ========
- * Purpose:
- * Removes a MPU buffer mapping from the DSP address space.
- */
-int proc_un_map(void *hprocessor, void *map_addr,
- struct process_context *pr_ctxt)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_object *dmm_mgr;
- u32 va_align;
- u32 size_align;
-
- va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_get_handle(hprocessor, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- /* Critical section */
- mutex_lock(&proc_lock);
- /*
- * Update DMM structures. Get the size to unmap.
- * This function returns error if the VA is not mapped
- */
- status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
- /* Remove mapping from the page tables. */
- if (!status) {
- status = (*p_proc_object->intf_fxns->brd_mem_un_map)
- (p_proc_object->bridge_context, va_align, size_align);
- }
-
- if (status)
- goto unmap_failed;
-
- /*
- * A successful unmap should be followed by removal of map_obj
- * from dmm_map_list, so that mapped memory resource tracking
- * remains uptodate
- */
- remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);
-
-unmap_failed:
- mutex_unlock(&proc_lock);
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
- __func__, hprocessor, map_addr, status);
- return status;
-}
-
-/*
- * ======== proc_un_reserve_memory ========
- * Purpose:
- * Frees a previously reserved region of DSP address space.
- */
-int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
- struct process_context *pr_ctxt)
-{
- struct dmm_object *dmm_mgr;
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
- struct dmm_rsv_object *rsv_obj;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_get_handle(p_proc_object, &dmm_mgr);
- if (!dmm_mgr) {
- status = -EFAULT;
- goto func_end;
- }
-
- status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
- if (status != 0)
- goto func_end;
-
- /*
- * A successful unreserve should be followed by removal of rsv_obj
- * from dmm_rsv_list, so that reserved memory resource tracking
- * remains uptodate
- */
- spin_lock(&pr_ctxt->dmm_rsv_lock);
- list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
- if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
- list_del(&rsv_obj->link);
- kfree(rsv_obj);
- break;
- }
- }
- spin_unlock(&pr_ctxt->dmm_rsv_lock);
-
-func_end:
- dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
- __func__, hprocessor, prsv_addr, status);
- return status;
-}
-
-/*
- * ======== = proc_monitor ======== ==
- * Purpose:
- * Place the Processor in Monitor State. This is an internal
- * function and a requirement before Processor is loaded.
- * This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor.
- * In dev_destroy2 we delete the node manager.
- * Parameters:
- * p_proc_object: Pointer to Processor Object
- * Returns:
- * 0: Processor placed in monitor mode.
- * !0: Failed to place processor in monitor mode.
- * Requires:
- * Valid Processor Handle
- * Ensures:
- * Success: ProcObject state is PROC_IDLE
- */
-static int proc_monitor(struct proc_object *proc_obj)
-{
- int status = -EPERM;
- struct msg_mgr *hmsg_mgr;
-
- /* This is needed only when Device is loaded when it is
- * already 'ACTIVE' */
- /* Destroy the Node Manager, msg_ctrl Manager */
- if (!dev_destroy2(proc_obj->dev_obj)) {
- /* Destroy the msg_ctrl by calling msg_delete */
- dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr);
- if (hmsg_mgr) {
- msg_delete(hmsg_mgr);
- dev_set_msg_mgr(proc_obj->dev_obj, NULL);
- }
- }
- /* Place the Board in the Monitor State */
- if (!((*proc_obj->intf_fxns->brd_monitor)
- (proc_obj->bridge_context))) {
- status = 0;
- }
-
- return status;
-}
-
-/*
- * ======== get_envp_count ========
- * Purpose:
- * Return the number of elements in the envp array, including the
- * terminating NULL element.
- */
-static s32 get_envp_count(char **envp)
-{
- s32 ret = 0;
- if (envp) {
- while (*envp++)
- ret++;
-
- ret += 1; /* Include the terminating NULL in the count. */
- }
-
- return ret;
-}
-
-/*
- * ======== prepend_envp ========
- * Purpose:
- * Prepend an environment variable=value pair to the new envp array, and
- * copy in the existing var=value pairs in the old envp array.
- */
-static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
- s32 cnew_envp, char *sz_var)
-{
- char **pp_envp = new_envp;
-
- /* Prepend new environ var=value string */
- *new_envp++ = sz_var;
-
- /* Copy user's environment into our own. */
- while (envp_elems--)
- *new_envp++ = *envp++;
-
- /* Ensure NULL terminates the new environment strings array. */
- if (envp_elems == 0)
- *new_envp = NULL;
-
- return pp_envp;
-}
-
-/*
- * ======== proc_notify_clients ========
- * Purpose:
- * Notify the processor the events.
- */
-int proc_notify_clients(void *proc, u32 events)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)proc;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
- ntfy_notify(p_proc_object->ntfy_obj, events);
-func_end:
- return status;
-}
-
-/*
- * ======== proc_notify_all_clients ========
- * Purpose:
- * Notify the processor the events. This includes notifying all clients
- * attached to a particulat DSP.
- */
-int proc_notify_all_clients(void *proc, u32 events)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)proc;
-
- if (!p_proc_object) {
- status = -EFAULT;
- goto func_end;
- }
-
- dev_notify_clients(p_proc_object->dev_obj, events);
-
-func_end:
- return status;
-}
-
-/*
- * ======== proc_get_processor_id ========
- * Purpose:
- * Retrieves the processor ID.
- */
-int proc_get_processor_id(void *proc, u32 *proc_id)
-{
- int status = 0;
- struct proc_object *p_proc_object = (struct proc_object *)proc;
-
- if (p_proc_object)
- *proc_id = p_proc_object->processor_id;
- else
- status = -EFAULT;
-
- return status;
-}
diff --git a/drivers/staging/tidspbridge/rmgr/pwr.c b/drivers/staging/tidspbridge/rmgr/pwr.c
deleted file mode 100644
index 17748df351b9..000000000000
--- a/drivers/staging/tidspbridge/rmgr/pwr.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * pwr.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * PWR API for controlling DSP power states.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/pwr.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/devdefs.h>
-#include <dspbridge/drv.h>
-
-/* ----------------------------------- Platform Manager */
-#include <dspbridge/dev.h>
-
-/* ----------------------------------- Link Driver */
-#include <dspbridge/dspioctl.h>
-
-/*
- * ======== pwr_sleep_dsp ========
- * Send command to DSP to enter sleep state.
- */
-int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout)
-{
- struct bridge_drv_interface *intf_fxns;
- struct bridge_dev_context *dw_context;
- int status = -EPERM;
- struct dev_object *hdev_obj = NULL;
- u32 ioctlcode = 0;
- u32 arg = timeout;
-
- for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
- hdev_obj != NULL;
- hdev_obj =
- (struct dev_object *)drv_get_next_dev_object((u32) hdev_obj)) {
- if (dev_get_bridge_context(hdev_obj,
- (struct bridge_dev_context **)
- &dw_context)) {
- continue;
- }
- if (dev_get_intf_fxns(hdev_obj,
- (struct bridge_drv_interface **)
- &intf_fxns)) {
- continue;
- }
- if (sleep_code == PWR_DEEPSLEEP)
- ioctlcode = BRDIOCTL_DEEPSLEEP;
- else if (sleep_code == PWR_EMERGENCYDEEPSLEEP)
- ioctlcode = BRDIOCTL_EMERGENCYSLEEP;
- else
- status = -EINVAL;
-
- if (status != -EINVAL) {
- status = (*intf_fxns->dev_cntrl) (dw_context,
- ioctlcode,
- (void *)&arg);
- }
- }
- return status;
-}
-
-/*
- * ======== pwr_wake_dsp ========
- * Send command to DSP to wake it from sleep.
- */
-int pwr_wake_dsp(const u32 timeout)
-{
- struct bridge_drv_interface *intf_fxns;
- struct bridge_dev_context *dw_context;
- int status = -EPERM;
- struct dev_object *hdev_obj = NULL;
- u32 arg = timeout;
-
- for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
- hdev_obj != NULL;
- hdev_obj = (struct dev_object *)drv_get_next_dev_object
- ((u32) hdev_obj)) {
- if (!(dev_get_bridge_context(hdev_obj,
- (struct bridge_dev_context
- **)&dw_context))) {
- if (!(dev_get_intf_fxns(hdev_obj,
- (struct bridge_drv_interface **)&intf_fxns))) {
- status =
- (*intf_fxns->dev_cntrl) (dw_context,
- BRDIOCTL_WAKEUP,
- (void *)&arg);
- }
- }
- }
- return status;
-}
-
-/*
- * ======== pwr_pm_pre_scale========
- * Sends pre-notification message to DSP.
- */
-int pwr_pm_pre_scale(u16 voltage_domain, u32 level)
-{
- struct bridge_drv_interface *intf_fxns;
- struct bridge_dev_context *dw_context;
- int status = -EPERM;
- struct dev_object *hdev_obj = NULL;
- u32 arg[2];
-
- arg[0] = voltage_domain;
- arg[1] = level;
-
- for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
- hdev_obj != NULL;
- hdev_obj = (struct dev_object *)drv_get_next_dev_object
- ((u32) hdev_obj)) {
- if (!(dev_get_bridge_context(hdev_obj,
- (struct bridge_dev_context
- **)&dw_context))) {
- if (!(dev_get_intf_fxns(hdev_obj,
- (struct bridge_drv_interface **)&intf_fxns))) {
- status =
- (*intf_fxns->dev_cntrl) (dw_context,
- BRDIOCTL_PRESCALE_NOTIFY,
- (void *)&arg);
- }
- }
- }
- return status;
-}
-
-/*
- * ======== pwr_pm_post_scale========
- * Sends post-notification message to DSP.
- */
-int pwr_pm_post_scale(u16 voltage_domain, u32 level)
-{
- struct bridge_drv_interface *intf_fxns;
- struct bridge_dev_context *dw_context;
- int status = -EPERM;
- struct dev_object *hdev_obj = NULL;
- u32 arg[2];
-
- arg[0] = voltage_domain;
- arg[1] = level;
-
- for (hdev_obj = (struct dev_object *)drv_get_first_dev_object();
- hdev_obj != NULL;
- hdev_obj = (struct dev_object *)drv_get_next_dev_object
- ((u32) hdev_obj)) {
- if (!(dev_get_bridge_context(hdev_obj,
- (struct bridge_dev_context
- **)&dw_context))) {
- if (!(dev_get_intf_fxns(hdev_obj,
- (struct bridge_drv_interface **)&intf_fxns))) {
- status =
- (*intf_fxns->dev_cntrl) (dw_context,
- BRDIOCTL_POSTSCALE_NOTIFY,
- (void *)&arg);
- }
- }
- }
- return status;
-
-}
diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c
deleted file mode 100644
index 52187bd97729..000000000000
--- a/drivers/staging/tidspbridge/rmgr/rmm.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * rmm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * This memory manager provides general heap management and arbitrary
- * alignment for any number of memory segments.
- *
- * Notes:
- *
- * Memory blocks are allocated from the end of the first free memory
- * block large enough to satisfy the request. Alignment requirements
- * are satisfied by "sliding" the block forward until its base satisfies
- * the alignment specification; if this is not possible then the next
- * free block large enough to hold the request is tried.
- *
- * Since alignment can cause the creation of a new free block - the
- * unused memory formed between the start of the original free block
- * and the start of the allocated block - the memory manager must free
- * this memory to prevent a memory leak.
- *
- * Overlay memory is managed by reserving through rmm_alloc, and freeing
- * it through rmm_free. The memory manager prevents DSP code/data that is
- * overlayed from being overwritten as long as the memory it runs at has
- * been allocated, and not yet freed.
- */
-
-#include <linux/types.h>
-#include <linux/list.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/rmm.h>
-
-/*
- * ======== rmm_header ========
- * This header is used to maintain a list of free memory blocks.
- */
-struct rmm_header {
- struct rmm_header *next; /* form a free memory link list */
- u32 size; /* size of the free memory */
- u32 addr; /* DSP address of memory block */
-};
-
-/*
- * ======== rmm_ovly_sect ========
- * Keeps track of memory occupied by overlay section.
- */
-struct rmm_ovly_sect {
- struct list_head list_elem;
- u32 addr; /* Start of memory section */
- u32 size; /* Length (target MAUs) of section */
- s32 page; /* Memory page */
-};
-
-/*
- * ======== rmm_target_obj ========
- */
-struct rmm_target_obj {
- struct rmm_segment *seg_tab;
- struct rmm_header **free_list;
- u32 num_segs;
- struct list_head ovly_list; /* List of overlay memory in use */
-};
-
-static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size,
- u32 align, u32 *dsp_address);
-static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr,
- u32 size);
-
-/*
- * ======== rmm_alloc ========
- */
-int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size,
- u32 align, u32 *dsp_address, bool reserve)
-{
- struct rmm_ovly_sect *sect, *prev_sect = NULL;
- struct rmm_ovly_sect *new_sect;
- u32 addr;
- int status = 0;
-
- if (!reserve) {
- if (!alloc_block(target, segid, size, align, dsp_address)) {
- status = -ENOMEM;
- } else {
- /* Increment the number of allocated blocks in this
- * segment */
- target->seg_tab[segid].number++;
- }
- goto func_end;
- }
- /* An overlay section - See if block is already in use. If not,
- * insert into the list in ascending address size. */
- addr = *dsp_address;
- /* Find place to insert new list element. List is sorted from
- * smallest to largest address. */
- list_for_each_entry(sect, &target->ovly_list, list_elem) {
- if (addr <= sect->addr) {
- /* Check for overlap with sect */
- if ((addr + size > sect->addr) || (prev_sect &&
- (prev_sect->addr +
- prev_sect->size >
- addr))) {
- status = -ENXIO;
- }
- break;
- }
- prev_sect = sect;
- }
- if (!status) {
- /* No overlap - allocate list element for new section. */
- new_sect = kzalloc(sizeof(struct rmm_ovly_sect), GFP_KERNEL);
- if (new_sect == NULL) {
- status = -ENOMEM;
- } else {
- new_sect->addr = addr;
- new_sect->size = size;
- new_sect->page = segid;
- if (list_is_last(&sect->list_elem, &target->ovly_list))
- /* Put new section at the end of the list */
- list_add_tail(&new_sect->list_elem,
- &target->ovly_list);
- else
- /* Put new section just before sect */
- list_add_tail(&new_sect->list_elem,
- &sect->list_elem);
- }
- }
-func_end:
- return status;
-}
-
-/*
- * ======== rmm_create ========
- */
-int rmm_create(struct rmm_target_obj **target_obj,
- struct rmm_segment seg_tab[], u32 num_segs)
-{
- struct rmm_header *hptr;
- struct rmm_segment *sptr, *tmp;
- struct rmm_target_obj *target;
- s32 i;
- int status = 0;
-
- /* Allocate DBL target object */
- target = kzalloc(sizeof(struct rmm_target_obj), GFP_KERNEL);
-
- if (target == NULL)
- status = -ENOMEM;
-
- if (status)
- goto func_cont;
-
- target->num_segs = num_segs;
- if (!(num_segs > 0))
- goto func_cont;
-
- /* Allocate the memory for freelist from host's memory */
- target->free_list = kzalloc(num_segs * sizeof(struct rmm_header *),
- GFP_KERNEL);
- if (target->free_list == NULL) {
- status = -ENOMEM;
- } else {
- /* Allocate headers for each element on the free list */
- for (i = 0; i < (s32) num_segs; i++) {
- target->free_list[i] =
- kzalloc(sizeof(struct rmm_header), GFP_KERNEL);
- if (target->free_list[i] == NULL) {
- status = -ENOMEM;
- break;
- }
- }
- /* Allocate memory for initial segment table */
- target->seg_tab = kzalloc(num_segs * sizeof(struct rmm_segment),
- GFP_KERNEL);
- if (target->seg_tab == NULL) {
- status = -ENOMEM;
- } else {
- /* Initialize segment table and free list */
- sptr = target->seg_tab;
- for (i = 0, tmp = seg_tab; num_segs > 0;
- num_segs--, i++) {
- *sptr = *tmp;
- hptr = target->free_list[i];
- hptr->addr = tmp->base;
- hptr->size = tmp->length;
- hptr->next = NULL;
- tmp++;
- sptr++;
- }
- }
- }
-func_cont:
- /* Initialize overlay memory list */
- if (!status)
- INIT_LIST_HEAD(&target->ovly_list);
-
- if (!status) {
- *target_obj = target;
- } else {
- *target_obj = NULL;
- if (target)
- rmm_delete(target);
-
- }
-
- return status;
-}
-
-/*
- * ======== rmm_delete ========
- */
-void rmm_delete(struct rmm_target_obj *target)
-{
- struct rmm_ovly_sect *sect, *tmp;
- struct rmm_header *hptr;
- struct rmm_header *next;
- u32 i;
-
- kfree(target->seg_tab);
-
- list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) {
- list_del(&sect->list_elem);
- kfree(sect);
- }
-
- if (target->free_list != NULL) {
- /* Free elements on freelist */
- for (i = 0; i < target->num_segs; i++) {
- hptr = next = target->free_list[i];
- while (next) {
- hptr = next;
- next = hptr->next;
- kfree(hptr);
- }
- }
- kfree(target->free_list);
- }
-
- kfree(target);
-}
-
-/*
- * ======== rmm_free ========
- */
-bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size,
- bool reserved)
-{
- struct rmm_ovly_sect *sect, *tmp;
- bool ret = false;
-
- /*
- * Free or unreserve memory.
- */
- if (!reserved) {
- ret = free_block(target, segid, dsp_addr, size);
- if (ret)
- target->seg_tab[segid].number--;
-
- } else {
- /* Unreserve memory */
- list_for_each_entry_safe(sect, tmp, &target->ovly_list,
- list_elem) {
- if (dsp_addr == sect->addr) {
- /* Remove from list */
- list_del(&sect->list_elem);
- kfree(sect);
- return true;
- }
- }
- }
- return ret;
-}
-
-/*
- * ======== rmm_stat ========
- */
-bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid,
- struct dsp_memstat *mem_stat_buf)
-{
- struct rmm_header *head;
- bool ret = false;
- u32 max_free_size = 0;
- u32 total_free_size = 0;
- u32 free_blocks = 0;
-
- if ((u32) segid < target->num_segs) {
- head = target->free_list[segid];
-
- /* Collect data from free_list */
- while (head != NULL) {
- max_free_size = max(max_free_size, head->size);
- total_free_size += head->size;
- free_blocks++;
- head = head->next;
- }
-
- /* ul_size */
- mem_stat_buf->size = target->seg_tab[segid].length;
-
- /* num_free_blocks */
- mem_stat_buf->num_free_blocks = free_blocks;
-
- /* total_free_size */
- mem_stat_buf->total_free_size = total_free_size;
-
- /* len_max_free_block */
- mem_stat_buf->len_max_free_block = max_free_size;
-
- /* num_alloc_blocks */
- mem_stat_buf->num_alloc_blocks =
- target->seg_tab[segid].number;
-
- ret = true;
- }
-
- return ret;
-}
-
-/*
- * ======== balloc ========
- * This allocation function allocates memory from the lowest addresses
- * first.
- */
-static bool alloc_block(struct rmm_target_obj *target, u32 segid, u32 size,
- u32 align, u32 *dsp_address)
-{
- struct rmm_header *head;
- struct rmm_header *prevhead = NULL;
- struct rmm_header *next;
- u32 tmpalign;
- u32 alignbytes;
- u32 hsize;
- u32 allocsize;
- u32 addr;
-
- alignbytes = (align == 0) ? 1 : align;
- prevhead = NULL;
- head = target->free_list[segid];
-
- do {
- hsize = head->size;
- next = head->next;
-
- addr = head->addr; /* alloc from the bottom */
-
- /* align allocation */
- (tmpalign = (u32) addr % alignbytes);
- if (tmpalign != 0)
- tmpalign = alignbytes - tmpalign;
-
- allocsize = size + tmpalign;
-
- if (hsize >= allocsize) { /* big enough */
- if (hsize == allocsize && prevhead != NULL) {
- prevhead->next = next;
- kfree(head);
- } else {
- head->size = hsize - allocsize;
- head->addr += allocsize;
- }
-
- /* free up any hole created by alignment */
- if (tmpalign)
- free_block(target, segid, addr, tmpalign);
-
- *dsp_address = addr + tmpalign;
- return true;
- }
-
- prevhead = head;
- head = next;
-
- } while (head != NULL);
-
- return false;
-}
-
-/*
- * ======== free_block ========
- * TO DO: free_block() allocates memory, which could result in failure.
- * Could allocate an rmm_header in rmm_alloc(), to be kept in a pool.
- * free_block() could use an rmm_header from the pool, freeing as blocks
- * are coalesced.
- */
-static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr,
- u32 size)
-{
- struct rmm_header *head;
- struct rmm_header *thead;
- struct rmm_header *rhead;
- bool ret = true;
-
- /* Create a memory header to hold the newly free'd block. */
- rhead = kzalloc(sizeof(struct rmm_header), GFP_KERNEL);
- if (rhead == NULL) {
- ret = false;
- } else {
- /* search down the free list to find the right place for addr */
- head = target->free_list[segid];
-
- if (addr >= head->addr) {
- while (head->next != NULL && addr > head->next->addr)
- head = head->next;
-
- thead = head->next;
-
- head->next = rhead;
- rhead->next = thead;
- rhead->addr = addr;
- rhead->size = size;
- } else {
- *rhead = *head;
- head->next = rhead;
- head->addr = addr;
- head->size = size;
- thead = rhead->next;
- }
-
- /* join with upper block, if possible */
- if (thead != NULL && (rhead->addr + rhead->size) ==
- thead->addr) {
- head->next = rhead->next;
- thead->size = size + thead->size;
- thead->addr = addr;
- kfree(rhead);
- rhead = thead;
- }
-
- /* join with the lower block, if possible */
- if ((head->addr + head->size) == rhead->addr) {
- head->next = rhead->next;
- head->size = head->size + rhead->size;
- kfree(rhead);
- }
- }
-
- return ret;
-}
diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c
deleted file mode 100644
index b88b27bbe2e7..000000000000
--- a/drivers/staging/tidspbridge/rmgr/strm.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * strm.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * DSP/BIOS Bridge Stream Manager.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/types.h>
-
-/* ----------------------------------- Host OS */
-#include <dspbridge/host_os.h>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-#include <dspbridge/sync.h>
-
-/* ----------------------------------- Bridge Driver */
-#include <dspbridge/dspdefs.h>
-
-/* ----------------------------------- Resource Manager */
-#include <dspbridge/nodepriv.h>
-
-/* ----------------------------------- Others */
-#include <dspbridge/cmm.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/strm.h>
-
-#include <dspbridge/resourcecleanup.h>
-
-/* ----------------------------------- Defines, Data Structures, Typedefs */
-#define DEFAULTTIMEOUT 10000
-#define DEFAULTNUMBUFS 2
-
-/*
- * ======== strm_mgr ========
- * The strm_mgr contains device information needed to open the underlying
- * channels of a stream.
- */
-struct strm_mgr {
- struct dev_object *dev_obj; /* Device for this processor */
- struct chnl_mgr *chnl_mgr; /* Channel manager */
- /* Function interface to Bridge driver */
- struct bridge_drv_interface *intf_fxns;
-};
-
-/*
- * ======== strm_object ========
- * This object is allocated in strm_open().
- */
-struct strm_object {
- struct strm_mgr *strm_mgr_obj;
- struct chnl_object *chnl_obj;
- u32 dir; /* DSP_TONODE or DSP_FROMNODE */
- u32 timeout;
- u32 num_bufs; /* Max # of bufs allowed in stream */
- u32 bufs_in_strm; /* Current # of bufs in stream */
- u32 bytes; /* bytes transferred since idled */
- /* STREAM_IDLE, STREAM_READY, ... */
- enum dsp_streamstate strm_state;
- void *user_event; /* Saved for strm_get_info() */
- enum dsp_strmmode strm_mode; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */
- u32 dma_chnl_id; /* DMA chnl id */
- u32 dma_priority; /* DMA priority:DMAPRI_[LOW][HIGH] */
- u32 segment_id; /* >0 is SM segment.=0 is local heap */
- u32 buf_alignment; /* Alignment for stream bufs */
- /* Stream's SM address translator */
- struct cmm_xlatorobject *xlator;
-};
-
-/* ----------------------------------- Function Prototypes */
-static int delete_strm(struct strm_object *stream_obj);
-
-/*
- * ======== strm_allocate_buffer ========
- * Purpose:
- * Allocates buffers for a stream.
- */
-int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
- u8 **ap_buffer, u32 num_bufs,
- struct process_context *pr_ctxt)
-{
- int status = 0;
- u32 alloc_cnt = 0;
- u32 i;
- struct strm_object *stream_obj = strmres->stream;
-
- if (stream_obj) {
- /*
- * Allocate from segment specified at time of stream open.
- */
- if (usize == 0)
- status = -EINVAL;
-
- } else {
- status = -EFAULT;
- }
-
- if (status)
- goto func_end;
-
- for (i = 0; i < num_bufs; i++) {
- (void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i],
- usize);
- if (ap_buffer[i] == NULL) {
- status = -ENOMEM;
- alloc_cnt = i;
- break;
- }
- }
- if (status)
- strm_free_buffer(strmres, ap_buffer, alloc_cnt, pr_ctxt);
-
- if (status)
- goto func_end;
-
- drv_proc_update_strm_res(num_bufs, strmres);
-
-func_end:
- return status;
-}
-
-/*
- * ======== strm_close ========
- * Purpose:
- * Close a stream opened with strm_open().
- */
-int strm_close(struct strm_res_object *strmres,
- struct process_context *pr_ctxt)
-{
- struct bridge_drv_interface *intf_fxns;
- struct chnl_info chnl_info_obj;
- int status = 0;
- struct strm_object *stream_obj = strmres->stream;
-
- if (!stream_obj) {
- status = -EFAULT;
- } else {
- /* Have all buffers been reclaimed? If not, return
- * -EPIPE */
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
- status =
- (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj,
- &chnl_info_obj);
-
- if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0)
- status = -EPIPE;
- else
- status = delete_strm(stream_obj);
- }
-
- if (status)
- goto func_end;
-
- idr_remove(pr_ctxt->stream_id, strmres->id);
-func_end:
- dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__,
- stream_obj, status);
- return status;
-}
-
-/*
- * ======== strm_create ========
- * Purpose:
- * Create a STRM manager object.
- */
-int strm_create(struct strm_mgr **strm_man,
- struct dev_object *dev_obj)
-{
- struct strm_mgr *strm_mgr_obj;
- int status = 0;
-
- *strm_man = NULL;
- /* Allocate STRM manager object */
- strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL);
- if (strm_mgr_obj == NULL)
- status = -ENOMEM;
- else
- strm_mgr_obj->dev_obj = dev_obj;
-
- /* Get Channel manager and Bridge function interface */
- if (!status) {
- status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->chnl_mgr));
- if (!status) {
- (void)dev_get_intf_fxns(dev_obj,
- &(strm_mgr_obj->intf_fxns));
- }
- }
-
- if (!status)
- *strm_man = strm_mgr_obj;
- else
- kfree(strm_mgr_obj);
-
- return status;
-}
-
-/*
- * ======== strm_delete ========
- * Purpose:
- * Delete the STRM Manager Object.
- */
-void strm_delete(struct strm_mgr *strm_mgr_obj)
-{
- kfree(strm_mgr_obj);
-}
-
-/*
- * ======== strm_free_buffer ========
- * Purpose:
- * Frees the buffers allocated for a stream.
- */
-int strm_free_buffer(struct strm_res_object *strmres, u8 **ap_buffer,
- u32 num_bufs, struct process_context *pr_ctxt)
-{
- int status = 0;
- u32 i = 0;
- struct strm_object *stream_obj = strmres->stream;
-
- if (!stream_obj)
- status = -EFAULT;
-
- if (!status) {
- for (i = 0; i < num_bufs; i++) {
- status =
- cmm_xlator_free_buf(stream_obj->xlator,
- ap_buffer[i]);
- if (status)
- break;
- ap_buffer[i] = NULL;
- }
- }
- drv_proc_update_strm_res(num_bufs - i, strmres);
-
- return status;
-}
-
-/*
- * ======== strm_get_info ========
- * Purpose:
- * Retrieves information about a stream.
- */
-int strm_get_info(struct strm_object *stream_obj,
- struct stream_info *stream_info,
- u32 stream_info_size)
-{
- struct bridge_drv_interface *intf_fxns;
- struct chnl_info chnl_info_obj;
- int status = 0;
- void *virt_base = NULL; /* NULL if no SM used */
-
- if (!stream_obj) {
- status = -EFAULT;
- } else {
- if (stream_info_size < sizeof(struct stream_info)) {
- /* size of users info */
- status = -EINVAL;
- }
- }
- if (status)
- goto func_end;
-
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
- status =
- (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj,
- &chnl_info_obj);
- if (status)
- goto func_end;
-
- if (stream_obj->xlator) {
- /* We have a translator */
- cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0,
- stream_obj->segment_id, false);
- }
- stream_info->segment_id = stream_obj->segment_id;
- stream_info->strm_mode = stream_obj->strm_mode;
- stream_info->virt_base = virt_base;
- stream_info->user_strm->number_bufs_allowed = stream_obj->num_bufs;
- stream_info->user_strm->number_bufs_in_stream = chnl_info_obj.cio_cs +
- chnl_info_obj.cio_reqs;
- /* # of bytes transferred since last call to DSPStream_Idle() */
- stream_info->user_strm->number_bytes = chnl_info_obj.bytes_tx;
- stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj;
- /* Determine stream state based on channel state and info */
- if (chnl_info_obj.state & CHNL_STATEEOS) {
- stream_info->user_strm->ss_stream_state = STREAM_DONE;
- } else {
- if (chnl_info_obj.cio_cs > 0)
- stream_info->user_strm->ss_stream_state = STREAM_READY;
- else if (chnl_info_obj.cio_reqs > 0)
- stream_info->user_strm->ss_stream_state =
- STREAM_PENDING;
- else
- stream_info->user_strm->ss_stream_state = STREAM_IDLE;
-
- }
-func_end:
- return status;
-}
-
-/*
- * ======== strm_idle ========
- * Purpose:
- * Idles a particular stream.
- */
-int strm_idle(struct strm_object *stream_obj, bool flush_data)
-{
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
-
- if (!stream_obj) {
- status = -EFAULT;
- } else {
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
-
- status = (*intf_fxns->chnl_idle) (stream_obj->chnl_obj,
- stream_obj->timeout,
- flush_data);
- }
-
- dev_dbg(bridge, "%s: stream_obj: %p flush_data: 0x%x status: 0x%x\n",
- __func__, stream_obj, flush_data, status);
- return status;
-}
-
-/*
- * ======== strm_issue ========
- * Purpose:
- * Issues a buffer on a stream
- */
-int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes,
- u32 ul_buf_size, u32 dw_arg)
-{
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
- void *tmp_buf = NULL;
-
- if (!stream_obj) {
- status = -EFAULT;
- } else {
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
-
- if (stream_obj->segment_id != 0) {
- tmp_buf = cmm_xlator_translate(stream_obj->xlator,
- (void *)pbuf,
- CMM_VA2DSPPA);
- if (tmp_buf == NULL)
- status = -ESRCH;
-
- }
- if (!status) {
- status = (*intf_fxns->chnl_add_io_req)
- (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size,
- (u32) tmp_buf, dw_arg);
- }
- if (status == -EIO)
- status = -ENOSR;
- }
-
- dev_dbg(bridge, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:"
- " 0x%x status: 0x%x\n", __func__, stream_obj, pbuf,
- ul_bytes, dw_arg, status);
- return status;
-}
-
-/*
- * ======== strm_open ========
- * Purpose:
- * Open a stream for sending/receiving data buffers to/from a task or
- * XDAIS socket node on the DSP.
- */
-int strm_open(struct node_object *hnode, u32 dir, u32 index,
- struct strm_attr *pattr,
- struct strm_res_object **strmres,
- struct process_context *pr_ctxt)
-{
- struct strm_mgr *strm_mgr_obj;
- struct bridge_drv_interface *intf_fxns;
- u32 ul_chnl_id;
- struct strm_object *strm_obj = NULL;
- s8 chnl_mode;
- struct chnl_attr chnl_attr_obj;
- int status = 0;
- struct cmm_object *hcmm_mgr = NULL; /* Shared memory manager hndl */
-
- void *stream_res;
-
- *strmres = NULL;
- if (dir != DSP_TONODE && dir != DSP_FROMNODE) {
- status = -EPERM;
- } else {
- /* Get the channel id from the node (set in node_connect()) */
- status = node_get_channel_id(hnode, dir, index, &ul_chnl_id);
- }
- if (!status)
- status = node_get_strm_mgr(hnode, &strm_mgr_obj);
-
- if (!status) {
- strm_obj = kzalloc(sizeof(struct strm_object), GFP_KERNEL);
- if (strm_obj == NULL) {
- status = -ENOMEM;
- } else {
- strm_obj->strm_mgr_obj = strm_mgr_obj;
- strm_obj->dir = dir;
- strm_obj->strm_state = STREAM_IDLE;
- strm_obj->user_event = pattr->user_event;
- if (pattr->stream_attr_in != NULL) {
- strm_obj->timeout =
- pattr->stream_attr_in->timeout;
- strm_obj->num_bufs =
- pattr->stream_attr_in->num_bufs;
- strm_obj->strm_mode =
- pattr->stream_attr_in->strm_mode;
- strm_obj->segment_id =
- pattr->stream_attr_in->segment_id;
- strm_obj->buf_alignment =
- pattr->stream_attr_in->buf_alignment;
- strm_obj->dma_chnl_id =
- pattr->stream_attr_in->dma_chnl_id;
- strm_obj->dma_priority =
- pattr->stream_attr_in->dma_priority;
- chnl_attr_obj.uio_reqs =
- pattr->stream_attr_in->num_bufs;
- } else {
- strm_obj->timeout = DEFAULTTIMEOUT;
- strm_obj->num_bufs = DEFAULTNUMBUFS;
- strm_obj->strm_mode = STRMMODE_PROCCOPY;
- strm_obj->segment_id = 0; /* local mem */
- strm_obj->buf_alignment = 0;
- strm_obj->dma_chnl_id = 0;
- strm_obj->dma_priority = 0;
- chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS;
- }
- chnl_attr_obj.reserved1 = NULL;
- /* DMA chnl flush timeout */
- chnl_attr_obj.reserved2 = strm_obj->timeout;
- chnl_attr_obj.event_obj = NULL;
- if (pattr->user_event != NULL)
- chnl_attr_obj.event_obj = pattr->user_event;
-
- }
- }
- if (status)
- goto func_cont;
-
- if ((pattr->virt_base == NULL) || !(pattr->virt_size > 0))
- goto func_cont;
-
- /* No System DMA */
- /* Get the shared mem mgr for this streams dev object */
- status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr);
- if (!status) {
- /*Allocate a SM addr translator for this strm. */
- status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL);
- if (!status) {
- /* Set translators Virt Addr attributes */
- status = cmm_xlator_info(strm_obj->xlator,
- (u8 **) &pattr->virt_base,
- pattr->virt_size,
- strm_obj->segment_id, true);
- }
- }
-func_cont:
- if (!status) {
- /* Open channel */
- chnl_mode = (dir == DSP_TONODE) ?
- CHNL_MODETODSP : CHNL_MODEFROMDSP;
- intf_fxns = strm_mgr_obj->intf_fxns;
- status = (*intf_fxns->chnl_open) (&(strm_obj->chnl_obj),
- strm_mgr_obj->chnl_mgr,
- chnl_mode, ul_chnl_id,
- &chnl_attr_obj);
- if (status) {
- /*
- * over-ride non-returnable status codes so we return
- * something documented
- */
- if (status != -ENOMEM && status !=
- -EINVAL && status != -EPERM) {
- /*
- * We got a status that's not return-able.
- * Assert that we got something we were
- * expecting (-EFAULT isn't acceptable,
- * strm_mgr_obj->chnl_mgr better be valid or we
- * assert here), and then return -EPERM.
- */
- status = -EPERM;
- }
- }
- }
- if (!status) {
- status = drv_proc_insert_strm_res_element(strm_obj,
- &stream_res, pr_ctxt);
- if (status)
- delete_strm(strm_obj);
- else
- *strmres = (struct strm_res_object *)stream_res;
- } else {
- (void)delete_strm(strm_obj);
- }
-
- dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p "
- "strmres: %p status: 0x%x\n", __func__,
- hnode, dir, index, pattr, strmres, status);
- return status;
-}
-
-/*
- * ======== strm_reclaim ========
- * Purpose:
- * Relcaims a buffer from a stream.
- */
-int strm_reclaim(struct strm_object *stream_obj, u8 **buf_ptr,
- u32 *nbytes, u32 *buff_size, u32 *pdw_arg)
-{
- struct bridge_drv_interface *intf_fxns;
- struct chnl_ioc chnl_ioc_obj;
- int status = 0;
- void *tmp_buf = NULL;
-
- if (!stream_obj) {
- status = -EFAULT;
- goto func_end;
- }
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
-
- status =
- (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj,
- stream_obj->timeout,
- &chnl_ioc_obj);
- if (!status) {
- *nbytes = chnl_ioc_obj.byte_size;
- if (buff_size)
- *buff_size = chnl_ioc_obj.buf_size;
-
- *pdw_arg = chnl_ioc_obj.arg;
- if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
- if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
- status = -ETIME;
- } else {
- /* Allow reclaims after idle to succeed */
- if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
- status = -EPERM;
-
- }
- }
- /* Translate zerocopy buffer if channel not canceled. */
- if (!status
- && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
- && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) {
- /*
- * This is a zero-copy channel so chnl_ioc_obj.buf
- * contains the DSP address of SM. We need to
- * translate it to a virtual address for the user
- * thread to access.
- * Note: Could add CMM_DSPPA2VA to CMM in the future.
- */
- tmp_buf = cmm_xlator_translate(stream_obj->xlator,
- chnl_ioc_obj.buf,
- CMM_DSPPA2PA);
- if (tmp_buf != NULL) {
- /* now convert this GPP Pa to Va */
- tmp_buf = cmm_xlator_translate(stream_obj->
- xlator,
- tmp_buf,
- CMM_PA2VA);
- }
- if (tmp_buf == NULL)
- status = -ESRCH;
-
- chnl_ioc_obj.buf = tmp_buf;
- }
- *buf_ptr = chnl_ioc_obj.buf;
- }
-func_end:
- dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p "
- "pdw_arg: %p status 0x%x\n", __func__, stream_obj,
- buf_ptr, nbytes, pdw_arg, status);
- return status;
-}
-
-/*
- * ======== strm_register_notify ========
- * Purpose:
- * Register to be notified on specific events for this stream.
- */
-int strm_register_notify(struct strm_object *stream_obj, u32 event_mask,
- u32 notify_type, struct dsp_notification
- *hnotification)
-{
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
-
- if (!stream_obj) {
- status = -EFAULT;
- } else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) |
- DSP_STREAMDONE)) != 0) {
- status = -EINVAL;
- } else {
- if (notify_type != DSP_SIGNALEVENT)
- status = -ENOSYS;
-
- }
- if (!status) {
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
-
- status =
- (*intf_fxns->chnl_register_notify) (stream_obj->
- chnl_obj,
- event_mask,
- notify_type,
- hnotification);
- }
-
- return status;
-}
-
-/*
- * ======== strm_select ========
- * Purpose:
- * Selects a ready stream.
- */
-int strm_select(struct strm_object **strm_tab, u32 strms,
- u32 *pmask, u32 utimeout)
-{
- u32 index;
- struct chnl_info chnl_info_obj;
- struct bridge_drv_interface *intf_fxns;
- struct sync_object **sync_events = NULL;
- u32 i;
- int status = 0;
-
- *pmask = 0;
- for (i = 0; i < strms; i++) {
- if (!strm_tab[i]) {
- status = -EFAULT;
- break;
- }
- }
- if (status)
- goto func_end;
-
- /* Determine which channels have IO ready */
- for (i = 0; i < strms; i++) {
- intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns;
- status = (*intf_fxns->chnl_get_info) (strm_tab[i]->chnl_obj,
- &chnl_info_obj);
- if (status) {
- break;
- } else {
- if (chnl_info_obj.cio_cs > 0)
- *pmask |= (1 << i);
-
- }
- }
- if (!status && utimeout > 0 && *pmask == 0) {
- /* Non-zero timeout */
- sync_events = kmalloc(strms * sizeof(struct sync_object *),
- GFP_KERNEL);
-
- if (sync_events == NULL) {
- status = -ENOMEM;
- } else {
- for (i = 0; i < strms; i++) {
- intf_fxns =
- strm_tab[i]->strm_mgr_obj->intf_fxns;
- status = (*intf_fxns->chnl_get_info)
- (strm_tab[i]->chnl_obj, &chnl_info_obj);
- if (status)
- break;
- else
- sync_events[i] =
- chnl_info_obj.sync_event;
-
- }
- }
- if (!status) {
- status =
- sync_wait_on_multiple_events(sync_events, strms,
- utimeout, &index);
- if (!status) {
- /* Since we waited on the event, we have to
- * reset it */
- sync_set_event(sync_events[index]);
- *pmask = 1 << index;
- }
- }
- }
-func_end:
- kfree(sync_events);
-
- return status;
-}
-
-/*
- * ======== delete_strm ========
- * Purpose:
- * Frees the resources allocated for a stream.
- */
-static int delete_strm(struct strm_object *stream_obj)
-{
- struct bridge_drv_interface *intf_fxns;
- int status = 0;
-
- if (stream_obj) {
- if (stream_obj->chnl_obj) {
- intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
- /* Channel close can fail only if the channel handle
- * is invalid. */
- status = (*intf_fxns->chnl_close)
- (stream_obj->chnl_obj);
- }
- /* Free all SM address translator resources */
- kfree(stream_obj->xlator);
- kfree(stream_obj);
- } else {
- status = -EFAULT;
- }
- return status;
-}
diff --git a/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset b/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset
new file mode 100644
index 000000000000..28f8f1233fc6
--- /dev/null
+++ b/drivers/staging/unisys/Documentation/ABI/sysfs-platform-visorchipset
@@ -0,0 +1,101 @@
+What: install/error
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: used to send the ID of a string that should be displayed on
+ s-Par's automatic installation progress screen when an error
+ is encountered during installation. This field has no effect
+ if not in installation mode.
+Users: sparmaintainer@unisys.com
+
+What: install/remainingsteps
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: used to set the value of the progress bar on the s-Par automatic
+ installation progress screen. This field has no effect if not in
+ installation mode.
+Users: sparmaintainer@unisys.com
+
+What: install/textid
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: used to send the ID of a string that should be displayed on
+ s-Par's automatic installation progress screen. Setting this
+ field when not in installation mode (boottotool was set on
+ the previous guest boot) has no effect.
+Users: sparmaintainer@unisys.com
+
+What: install/boottotool
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: The boottotool flag controls s-Par behavior on the next boot of
+ this guest. Setting the flag will cause the guest to boot from
+ the utility and installation image, which will use the value in
+ the toolaction field to determine what operation is being
+ requested.
+Users: sparmaintainer@unisys.com
+
+What: install/toolaction
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: This field is used to tell s-Par which type of recovery tool
+ action to perform on the next guest boot-up. The meaning of the
+ value is dependent on the type of installation software used to
+ commission the guest.
+Users: sparmaintainer@unisys.com
+
+What: guest/chipsetready
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: This entry is used by Unisys application software on the guest
+ to acknowledge completion of specific events for integration
+ purposes, but these acknowledgements are not required for the
+ guest to operate correctly. The interface accepts one of two
+ strings: MODULES_LOADED to indicate that the s-Par driver
+ modules have been loaded successfully, or CALLHOMEDISK_MOUNTED,
+ which indicates that the disk used to support call home services
+ has been successfully mounted.
+Users: sparmaintainer@unisys.com
+
+What: parahotplug/deviceenabled
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: This entry is used by a Unisys support script installed on the
+ guest, and triggered by a udev event. The support script is
+ responsible for enabling and disabling SR-IOV devices when the
+ PF device is being recovered in another guest.
+
+ Some SR-IOV devices have problems when the PF is reset without
+ first disabling all VFs attached to that PF. s-Par handles this
+ situation by sending a message to guests using these VFs, and
+ the script will disable the device. When the PF is recovered,
+ another message is sent to the guests to re-enable the VFs.
+
+ The parahotplug/deviceenabled interface is used to acknowledge
+ the recovery message.
+Users: sparmaintainer@unisys.com
+
+What: parahotplug/devicedisabled
+Date: 7/18/2014
+KernelVersion: TBD
+Contact: sparmaintainer@unisys.com
+Description: This entry is used by a Unisys support script installed on the
+ guest, and triggered by a udev event. The support script is
+ responsible for enabling and disabling SR-IOV devices when the
+ PF device is being recovered in another guest.
+
+ Some SR-IOV devices have problems when the PF is reset without
+ first disabling all VFs attached to that PF. s-Par handles this
+ situation by sending a message to guests using these VFs, and
+ the script will disable the device. When the PF is recovered,
+ another message is sent to the guests to re-enable the VFs.
+
+ The parahotplug/devicedisaabled interface is used to acknowledge
+ the initial recovery message.
+Users: sparmaintainer@unisys.com
diff --git a/drivers/staging/unisys/Kconfig b/drivers/staging/unisys/Kconfig
index 6bae2afbaa15..ac080c9dcf46 100644
--- a/drivers/staging/unisys/Kconfig
+++ b/drivers/staging/unisys/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig UNISYSSPAR
bool "Unisys SPAR driver support"
- depends on X86_64 && BROKEN
+ depends on X86_64
---help---
Support for the Unisys SPAR drivers
diff --git a/drivers/staging/unisys/channels/Kconfig b/drivers/staging/unisys/channels/Kconfig
index 47a235385567..179c6cea2824 100644
--- a/drivers/staging/unisys/channels/Kconfig
+++ b/drivers/staging/unisys/channels/Kconfig
@@ -4,7 +4,7 @@
config UNISYS_CHANNELSTUB
tristate "Unisys channelstub driver"
- depends on UNISYSSPAR
+ depends on UNISYSSPAR && UNISYS_VISORUTIL
---help---
If you say Y here, you will enable the Unisys channels driver.
diff --git a/drivers/staging/unisys/channels/Makefile b/drivers/staging/unisys/channels/Makefile
index e60b0aef4dcd..adc184206035 100644
--- a/drivers/staging/unisys/channels/Makefile
+++ b/drivers/staging/unisys/channels/Makefile
@@ -9,5 +9,3 @@ visorchannelstub-y := channel.o chanstub.o
ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c
index 7223a14082ba..b9bf8e81677c 100644
--- a/drivers/staging/unisys/channels/channel.c
+++ b/drivers/staging/unisys/channels/channel.c
@@ -44,7 +44,7 @@
* 1 if the insertion succeeds, 0 if the queue was full.
*/
unsigned char
-visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, U32 Queue, void *pSignal)
+visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal)
{
void __iomem *psignal;
unsigned int head, tail, nof;
@@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(visor_signal_insert);
* 1 if the removal succeeds, 0 if the queue was empty.
*/
unsigned char
-visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, U32 Queue, void *pSignal)
+visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal)
{
void __iomem *psource;
unsigned int head, tail;
@@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(visor_signal_remove);
* # of signals copied.
*/
unsigned int
-SignalRemoveAll(pCHANNEL_HEADER pChannel, U32 Queue, void *pSignal)
+SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal)
{
void *psource;
unsigned int head, tail, signalCount = 0;
@@ -208,7 +208,7 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, U32 Queue, void *pSignal)
* 1 if the signal queue is empty, 0 otherwise.
*/
unsigned char
-visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, U32 Queue)
+visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel, u32 Queue)
{
SIGNAL_QUEUE_HEADER __iomem *pqhdr =
(SIGNAL_QUEUE_HEADER __iomem *) ((char __iomem *) pChannel +
diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c
index 1e7d6a78602d..7f36d9adac55 100644
--- a/drivers/staging/unisys/channels/chanstub.c
+++ b/drivers/staging/unisys/channels/chanstub.c
@@ -42,7 +42,7 @@ channel_mod_exit(void)
}
unsigned char
-SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal, spinlock_t *lock)
{
unsigned char result;
@@ -54,7 +54,7 @@ SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
}
unsigned char
-SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal, spinlock_t *lock)
{
unsigned char result;
diff --git a/drivers/staging/unisys/channels/chanstub.h b/drivers/staging/unisys/channels/chanstub.h
index bdee5d529f6b..d08e2c69d2ad 100644
--- a/drivers/staging/unisys/channels/chanstub.h
+++ b/drivers/staging/unisys/channels/chanstub.h
@@ -15,9 +15,9 @@
#ifndef __CHANSTUB_H__
#define __CHANSTUB_H__
-unsigned char SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+unsigned char SignalInsert_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal, spinlock_t *lock);
-unsigned char SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+unsigned char SignalRemove_withLock(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal, spinlock_t *lock);
#endif
diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h
index d19711de1140..15a8d6b35dac 100644
--- a/drivers/staging/unisys/common-spar/include/channels/channel.h
+++ b/drivers/staging/unisys/common-spar/include/channels/channel.h
@@ -36,7 +36,7 @@
#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))
+ (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32))
#ifndef lengthof
#define lengthof(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER))
@@ -70,26 +70,26 @@ typedef enum {
CHANNELCLI_OWNED = 5 /* "no worries" state - client can
* access channel anytime */
} CHANNEL_CLIENTSTATE;
-static inline const U8 *
-ULTRA_CHANNELCLI_STRING(U32 v)
+static inline const u8 *
+ULTRA_CHANNELCLI_STRING(u32 v)
{
switch (v) {
case CHANNELCLI_DETACHED:
- return (const U8 *) ("DETACHED");
+ return (const u8 *) ("DETACHED");
case CHANNELCLI_DISABLED:
- return (const U8 *) ("DISABLED");
+ return (const u8 *) ("DISABLED");
case CHANNELCLI_ATTACHING:
- return (const U8 *) ("ATTACHING");
+ return (const u8 *) ("ATTACHING");
case CHANNELCLI_ATTACHED:
- return (const U8 *) ("ATTACHED");
+ return (const u8 *) ("ATTACHED");
case CHANNELCLI_BUSY:
- return (const U8 *) ("BUSY");
+ return (const u8 *) ("BUSY");
case CHANNELCLI_OWNED:
- return (const U8 *) ("OWNED");
+ return (const u8 *) ("OWNED");
default:
break;
}
- return (const U8 *) ("?");
+ return (const u8 *) ("?");
}
#define ULTRA_CHANNELSRV_IS_READY(x) ((x) == CHANNELSRV_READY)
@@ -129,7 +129,7 @@ ULTRA_CHANNELCLI_STRING(U32 v)
old, \
ULTRA_CHANNELCLI_STRING(new), \
new, \
- PathName_Last_N_Nodes((U8 *)file, 4), \
+ PathName_Last_N_Nodes((u8 *)file, 4), \
line); \
} while (0)
@@ -209,43 +209,43 @@ ULTRA_CHANNELCLI_STRING(U32 v)
#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
/* Common Channel Header */
typedef struct _CHANNEL_HEADER {
- U64 Signature; /* Signature */
- U32 LegacyState; /* DEPRECATED - being replaced by */
+ u64 Signature; /* Signature */
+ u32 LegacyState; /* DEPRECATED - being replaced by */
/* / SrvState, CliStateBoot, and CliStateOS below */
- U32 HeaderSize; /* sizeof(CHANNEL_HEADER) */
- U64 Size; /* Total size of this channel in bytes */
- U64 Features; /* Flags to modify behavior */
+ u32 HeaderSize; /* sizeof(CHANNEL_HEADER) */
+ u64 Size; /* Total size of this channel in bytes */
+ u64 Features; /* Flags to modify behavior */
uuid_le Type; /* Channel type: data, bus, control, etc. */
- U64 PartitionHandle; /* ID of guest partition */
- U64 Handle; /* Device number of this channel in client */
- U64 oChannelSpace; /* Offset in bytes to channel specific area */
- U32 VersionId; /* CHANNEL_HEADER Version ID */
- U32 PartitionIndex; /* Index of guest partition */
+ u64 PartitionHandle; /* ID of guest partition */
+ u64 Handle; /* Device number of this channel in client */
+ u64 oChannelSpace; /* Offset in bytes to channel specific area */
+ u32 VersionId; /* CHANNEL_HEADER Version ID */
+ u32 PartitionIndex; /* Index of guest partition */
uuid_le ZoneGuid; /* Guid of Channel's zone */
- U32 oClientString; /* offset from channel header to
+ u32 oClientString; /* offset from channel header to
* nul-terminated ClientString (0 if
* ClientString not present) */
- U32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot
+ u32 CliStateBoot; /* CHANNEL_CLIENTSTATE of pre-boot
* EFI client of this channel */
- U32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in
+ u32 CmdStateCli; /* CHANNEL_COMMANDSTATE (overloaded in
* Windows drivers, see ServerStateUp,
* ServerStateDown, etc) */
- U32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS
+ u32 CliStateOS; /* CHANNEL_CLIENTSTATE of Guest OS
* client of this channel */
- U32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_<xxx> */
- U32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in
+ u32 ChannelCharacteristics; /* CHANNEL_CHARACTERISTIC_<xxx> */
+ u32 CmdStateSrv; /* CHANNEL_COMMANDSTATE (overloaded in
* Windows drivers, see ServerStateUp,
* ServerStateDown, etc) */
- U32 SrvState; /* CHANNEL_SERVERSTATE */
- U8 CliErrorBoot; /* bits to indicate err states for
+ u32 SrvState; /* CHANNEL_SERVERSTATE */
+ u8 CliErrorBoot; /* bits to indicate err states for
* boot clients, so err messages can
* be throttled */
- U8 CliErrorOS; /* bits to indicate err states for OS
+ u8 CliErrorOS; /* bits to indicate err states for OS
* clients, so err messages can be
* throttled */
- U8 Filler[1]; /* Pad out to 128 byte cacheline */
+ u8 Filler[1]; /* Pad out to 128 byte cacheline */
/* Please add all new single-byte values below here */
- U8 RecoverChannel;
+ u8 RecoverChannel;
} CHANNEL_HEADER, *pCHANNEL_HEADER, ULTRA_CHANNEL_PROTOCOL;
#define ULTRA_CHANNEL_ENABLE_INTS (0x1ULL << 0)
@@ -253,50 +253,50 @@ typedef struct _CHANNEL_HEADER {
/* Subheader for the Signal Type variation of the Common Channel */
typedef struct _SIGNAL_QUEUE_HEADER {
/* 1st cache line */
- U32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */
- U32 Type; /* Queue type: storage, network */
- U64 Size; /* Total size of this queue in bytes */
- U64 oSignalBase; /* Offset to signal queue area */
- U64 FeatureFlags; /* Flags to modify behavior */
- U64 NumSignalsSent; /* Total # of signals placed in this queue */
- U64 NumOverflows; /* Total # of inserts failed due to
+ u32 VersionId; /* SIGNAL_QUEUE_HEADER Version ID */
+ u32 Type; /* Queue type: storage, network */
+ u64 Size; /* Total size of this queue in bytes */
+ u64 oSignalBase; /* Offset to signal queue area */
+ u64 FeatureFlags; /* Flags to modify behavior */
+ u64 NumSignalsSent; /* Total # of signals placed in this queue */
+ u64 NumOverflows; /* Total # of inserts failed due to
* full queue */
- U32 SignalSize; /* Total size of a signal for this queue */
- U32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is
+ u32 SignalSize; /* Total size of a signal for this queue */
+ u32 MaxSignalSlots; /* Max # of slots in queue, 1 slot is
* always empty */
- U32 MaxSignals; /* Max # of signals in queue
+ u32 MaxSignals; /* Max # of signals in queue
* (MaxSignalSlots-1) */
- U32 Head; /* Queue head signal # */
+ u32 Head; /* Queue head signal # */
/* 2nd cache line */
- U64 NumSignalsReceived; /* Total # of signals removed from this queue */
- U32 Tail; /* Queue tail signal # (on separate
+ u64 NumSignalsReceived; /* Total # of signals removed from this queue */
+ u32 Tail; /* Queue tail signal # (on separate
* cache line) */
- U32 Reserved1; /* Reserved field */
- U64 Reserved2; /* Resrved field */
- U64 ClientQueue;
- U64 NumInterruptsReceived; /* Total # of Interrupts received. This
+ u32 Reserved1; /* Reserved field */
+ u64 Reserved2; /* Resrved field */
+ u64 ClientQueue;
+ u64 NumInterruptsReceived; /* Total # of Interrupts received. This
* is incremented by the ISR in the
* guest windows driver */
- U64 NumEmptyCnt; /* Number of times that visor_signal_remove
+ u64 NumEmptyCnt; /* Number of times that visor_signal_remove
* is called and returned Empty
* Status. */
- U32 ErrorFlags; /* Error bits set during SignalReinit
+ u32 ErrorFlags; /* Error bits set during SignalReinit
* to denote trouble with client's
* fields */
- U8 Filler[12]; /* Pad out to 64 byte cacheline */
+ u8 Filler[12]; /* Pad out to 64 byte cacheline */
} SIGNAL_QUEUE_HEADER, *pSIGNAL_QUEUE_HEADER;
#pragma pack(pop)
#define SignalInit(chan, QHDRFLD, QDATAFLD, QDATATYPE, ver, typ) \
do { \
- MEMSET(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
+ memset(&chan->QHDRFLD, 0, sizeof(chan->QHDRFLD)); \
chan->QHDRFLD.VersionId = ver; \
chan->QHDRFLD.Type = typ; \
chan->QHDRFLD.Size = sizeof(chan->QDATAFLD); \
chan->QHDRFLD.SignalSize = sizeof(QDATATYPE); \
- chan->QHDRFLD.oSignalBase = (UINTN)(chan->QDATAFLD)- \
- (UINTN)(&chan->QHDRFLD); \
+ chan->QHDRFLD.oSignalBase = (u64)(chan->QDATAFLD)- \
+ (u64)(&chan->QHDRFLD); \
chan->QHDRFLD.MaxSignalSlots = \
sizeof(chan->QDATAFLD)/sizeof(QDATATYPE); \
chan->QHDRFLD.MaxSignals = chan->QHDRFLD.MaxSignalSlots-1; \
@@ -311,15 +311,15 @@ static inline int
ULTRA_check_channel_client(void __iomem *pChannel,
uuid_le expectedTypeGuid,
char *channelName,
- U64 expectedMinBytes,
- U32 expectedVersionId,
- U64 expectedSignature,
+ u64 expectedMinBytes,
+ u32 expectedVersionId,
+ u64 expectedSignature,
char *fileName, int lineNumber, void *logCtx)
{
if (uuid_le_cmp(expectedTypeGuid, NULL_UUID_LE) != 0)
/* caller wants us to verify type GUID */
- if (MEMCMP_IO(&(((CHANNEL_HEADER __iomem *) (pChannel))->Type),
- &expectedTypeGuid, sizeof(uuid_le)) != 0) {
+ if (uuid_le_cmp((((CHANNEL_HEADER __iomem *)(pChannel))->Type),
+ expectedTypeGuid) != 0) {
CHANNEL_GUID_MISMATCH(expectedTypeGuid, channelName,
"type", expectedTypeGuid,
((CHANNEL_HEADER __iomem *)
@@ -373,8 +373,8 @@ ULTRA_check_channel_client(void __iomem *pChannel,
static inline int
ULTRA_check_channel_server(uuid_le typeGuid,
char *channelName,
- U64 expectedMinBytes,
- U64 actualBytes,
+ u64 expectedMinBytes,
+ u64 actualBytes,
char *fileName, int lineNumber, void *logCtx)
{
if (expectedMinBytes > 0) /* caller wants us to verify
@@ -394,10 +394,10 @@ ULTRA_check_channel_server(uuid_le typeGuid,
* NOT more than <n>. Note that if the pathname has less than <n> nodes
* in it, the return pointer will be to the beginning of the string.
*/
-static inline U8 *
-PathName_Last_N_Nodes(U8 *s, unsigned int n)
+static inline u8 *
+PathName_Last_N_Nodes(u8 *s, unsigned int n)
{
- U8 *p = s;
+ u8 *p = s;
unsigned int node_count = 0;
while (*p != '\0') {
if ((*p == '/') || (*p == '\\'))
@@ -419,7 +419,7 @@ PathName_Last_N_Nodes(U8 *s, unsigned int n)
}
static inline int
-ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
+ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId,
void *logCtx, char *file, int line, char *func)
{
CHANNEL_HEADER __iomem *pChan = pChannel;
@@ -439,7 +439,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
CHANNELSTATE_DIAG_SUBSYS, func, line,
"%s Channel StateTransition INVALID! - acquire failed because OS client DISABLED @%s:%d\n",
chanId, PathName_Last_N_Nodes(
- (U8 *) file, 4), line);
+ (u8 *) file, 4), line);
}
return 0;
}
@@ -456,7 +456,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
readl(&pChan->CliStateOS),
ULTRA_CHANNELCLI_STRING(CHANNELCLI_OWNED),
CHANNELCLI_OWNED,
- PathName_Last_N_Nodes((U8 *) file, 4), line);
+ PathName_Last_N_Nodes((u8 *) file, 4), line);
writel(CHANNELCLI_OWNED, &pChan->CliStateOS);
MEMORYBARRIER;
}
@@ -469,7 +469,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
CHANNELSTATE_DIAG_SEVERITY,
CHANNELSTATE_DIAG_SUBSYS, func, line,
"%s Channel OS client acquire now successful @%s:%d\n",
- chanId, PathName_Last_N_Nodes((U8 *) file,
+ chanId, PathName_Last_N_Nodes((u8 *) file,
4), line);
writeb(0, &pChan->CliErrorOS);
}
@@ -496,7 +496,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
ULTRA_CHANNELCLI_STRING(
readl(&pChan->CliStateOS)),
readl(&pChan->CliStateOS),
- PathName_Last_N_Nodes((U8 *) file, 4),
+ PathName_Last_N_Nodes((u8 *) file, 4),
line);
}
return 0;
@@ -516,7 +516,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
CHANNELSTATE_DIAG_SEVERITY,
CHANNELSTATE_DIAG_SUBSYS, func, line,
"%s Channel StateTransition failed - host OS acquire failed because boot BUSY @%s:%d\n",
- chanId, PathName_Last_N_Nodes((U8 *) file,
+ chanId, PathName_Last_N_Nodes((u8 *) file,
4), line);
}
/* reset busy */
@@ -530,7 +530,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
CHANNELSTATE_DIAG_SEVERITY,
CHANNELSTATE_DIAG_SUBSYS, func, line,
"%s Channel OS client acquire now successful @%s:%d\n",
- chanId, PathName_Last_N_Nodes((U8 *) file, 4),
+ chanId, PathName_Last_N_Nodes((u8 *) file, 4),
line);
writeb(0, &pChan->CliErrorOS);
}
@@ -538,7 +538,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, U8 *chanId,
}
static inline void
-ULTRA_channel_client_release_os(void __iomem *pChannel, U8 *chanId,
+ULTRA_channel_client_release_os(void __iomem *pChannel, u8 *chanId,
void *logCtx, char *file, int line, char *func)
{
CHANNEL_HEADER __iomem *pChan = pChannel;
@@ -548,7 +548,7 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, U8 *chanId,
CHANNELSTATE_DIAG_SEVERITY,
CHANNELSTATE_DIAG_SUBSYS, func, line,
"%s Channel OS client error state cleared @%s:%d\n",
- chanId, PathName_Last_N_Nodes((U8 *) file, 4),
+ chanId, PathName_Last_N_Nodes((u8 *) file, 4),
line);
writeb(0, &pChan->CliErrorOS);
}
@@ -563,7 +563,7 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, U8 *chanId,
ULTRA_CHANNELCLI_STRING(
readl(&pChan->CliStateOS)),
readl(&pChan->CliStateOS),
- PathName_Last_N_Nodes((U8 *) file, 4), line);
+ PathName_Last_N_Nodes((u8 *) file, 4), line);
/* return; */
}
writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); /* release busy */
@@ -588,7 +588,7 @@ ULTRA_channel_client_release_os(void __iomem *pChannel, U8 *chanId,
* full.
*/
-unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal);
/*
@@ -610,7 +610,7 @@ unsigned char visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
* empty.
*/
-unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
+unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue,
void *pSignal);
/*
@@ -632,7 +632,7 @@ unsigned char visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, U32 Queue,
* Return value:
* # of signals copied.
*/
-unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, U32 Queue,
+unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue,
void *pSignal);
/*
@@ -647,6 +647,6 @@ unsigned int SignalRemoveAll(pCHANNEL_HEADER pChannel, U32 Queue,
* 1 if the signal queue is empty, 0 otherwise.
*/
unsigned char visor_signalqueue_empty(CHANNEL_HEADER __iomem *pChannel,
- U32 Queue);
+ u32 Queue);
#endif
diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h
index 1a1c5053fcf8..b0a49e0c37a2 100644
--- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h
+++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h
@@ -37,19 +37,19 @@
/* Define Ki scale page to be traditional 4KB page */
#define ULTRA_MEMORY_PAGE_Ki (ULTRA_MEMORY_PAGE_WORD * ULTRA_MEMORY_COUNT_Ki)
typedef struct _ULTRA_SEGMENT_STATE {
- U16 Enabled:1; /* Bit 0: May enter other states */
- U16 Active:1; /* Bit 1: Assigned to active partition */
- U16 Alive:1; /* Bit 2: Configure message sent to
+ u16 Enabled:1; /* Bit 0: May enter other states */
+ u16 Active:1; /* Bit 1: Assigned to active partition */
+ u16 Alive:1; /* Bit 2: Configure message sent to
* service/server */
- U16 Revoked:1; /* Bit 3: similar to partition state
+ u16 Revoked:1; /* Bit 3: similar to partition state
* ShuttingDown */
- U16 Allocated:1; /* Bit 4: memory (device/port number)
+ u16 Allocated:1; /* Bit 4: memory (device/port number)
* has been selected by Command */
- U16 Known:1; /* Bit 5: has been introduced to the
+ u16 Known:1; /* Bit 5: has been introduced to the
* service/guest partition */
- U16 Ready:1; /* Bit 6: service/Guest partition has
+ u16 Ready:1; /* Bit 6: service/Guest partition has
* responded to introduction */
- U16 Operating:1; /* Bit 7: resource is configured and
+ u16 Operating:1; /* Bit 7: resource is configured and
* operating */
/* Note: don't use high bit unless we need to switch to ushort
* which is non-compliant */
@@ -64,13 +64,13 @@ static const ULTRA_SEGMENT_STATE SegmentStateStandby = {
1, 1, 0, 0, 1, 1, 1, 0
};
typedef union {
- U64 Full;
+ u64 Full;
struct {
- U8 Major; /* will be 1 for the first release and
+ u8 Major; /* will be 1 for the first release and
* increment thereafter */
- U8 Minor;
- U16 Maintenance;
- U32 Revision; /* Subversion revision */
+ u8 Minor;
+ u16 Maintenance;
+ u32 Revision; /* Subversion revision */
} Part;
} ULTRA_COMPONENT_VERSION;
diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h
index d8b12a733488..153f57ce908f 100644
--- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h
+++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h
@@ -126,66 +126,66 @@ struct InterruptInfo {
* interrupt. Currently this is used by IOPart-SP to wake
* up GP when Data Channel transitions from empty to
* non-empty.*/
- U64 sendInterruptHandle;
+ u64 sendInterruptHandle;
/**< 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
* intrrupt. Used by IOPart-GP only. */
- U64 recvInterruptHandle;
+ u64 recvInterruptHandle;
/**< specifies interrupt vector. It, interrupt pin, and shared are
* used to connect to the corresponding interrupt. Used by
* IOPart-GP only. */
- U32 recvInterruptVector;
+ u32 recvInterruptVector;
/**< 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 recvInterruptShared;
- U8 reserved[3]; /* Natural alignment purposes */
+ u8 recvInterruptShared;
+ u8 reserved[3]; /* Natural alignment purposes */
};
struct PciId {
- U16 Domain;
- U8 Bus;
- U8 Slot;
- U8 Func;
- U8 Reserved[3]; /* Natural alignment purposes */
+ u16 Domain;
+ u8 Bus;
+ u8 Slot;
+ u8 Func;
+ u8 Reserved[3]; /* Natural alignment purposes */
};
struct PciConfigHdr {
- U16 VendorId;
- U16 SubSysVendor;
- U16 DeviceId;
- U16 SubSysDevice;
- U32 ClassCode;
- U32 Reserved; /* Natural alignment purposes */
+ u16 VendorId;
+ u16 SubSysVendor;
+ u16 DeviceId;
+ u16 SubSysDevice;
+ u32 ClassCode;
+ u32 Reserved; /* Natural alignment purposes */
};
struct ScsiId {
- U32 Bus;
- U32 Target;
- U32 Lun;
- U32 Host; /* Command should ignore this for *
+ u32 Bus;
+ u32 Target;
+ u32 Lun;
+ u32 Host; /* Command should ignore this for *
* DiskArrival/RemovalEvents */
};
struct WWID {
- U32 wwid1;
- U32 wwid2;
+ u32 wwid1;
+ u32 wwid2;
};
struct virtDiskInfo {
- U32 switchNo; /* defined by SWITCH_CREATE */
- U32 externalPortNo; /* 0 for SAS RAID provided (external)
+ u32 switchNo; /* defined by SWITCH_CREATE */
+ u32 externalPortNo; /* 0 for SAS RAID provided (external)
* virtual disks, 1 for virtual disk
* images, 2 for gold disk images */
- U16 VirtualDiskIndex; /* Index of disk descriptor in the
+ u16 VirtualDiskIndex; /* Index of disk descriptor in the
* VirtualDisk segment associated with
* externalPortNo */
- U16 Reserved1;
- U32 Reserved2;
+ u16 Reserved1;
+ u32 Reserved2;
};
typedef enum {
@@ -218,10 +218,10 @@ typedef enum _ULTRA_TOOL_ACTIONS {
} ULTRA_TOOL_ACTIONS;
typedef struct _ULTRA_EFI_SPAR_INDICATION {
- U64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */
- U64 ClearNvram:1; /* Bit 1: Clear NVRAM */
- U64 ClearCmos:1; /* Bit 2: Clear CMOS */
- U64 BootToTool:1; /* Bit 3: Run install tool */
+ u64 BootToFirmwareUI:1; /* Bit 0: Stop in uefi ui */
+ u64 ClearNvram:1; /* Bit 1: Clear NVRAM */
+ u64 ClearCmos:1; /* Bit 2: Clear CMOS */
+ u64 BootToTool:1; /* Bit 3: Run install tool */
/* remaining bits are available */
} ULTRA_EFI_SPAR_INDICATION;
@@ -237,74 +237,74 @@ typedef enum {
* looking at the flags.response field.
*/
typedef struct _CONTROLVM_MESSAGE_HEADER {
- U32 Id; /* See CONTROLVM_ID. */
+ u32 Id; /* See CONTROLVM_ID. */
/* For requests, indicates the message type. */
/* For responses, indicates the type of message we are responding to. */
- U32 MessageSize; /* Includes size of this struct + size
+ u32 MessageSize; /* Includes size of this struct + size
* of message */
- U32 SegmentIndex; /* Index of segment containing Vm
+ u32 SegmentIndex; /* Index of segment containing Vm
* message/information */
- U32 CompletionStatus; /* Error status code or result of
+ u32 CompletionStatus; /* Error status code or result of
* message completion */
struct {
- U32 failed:1; /**< =1 in a response to * signify
+ u32 failed:1; /**< =1 in a response to * signify
* failure */
- U32 responseExpected:1; /**< =1 in all messages that expect a
+ u32 responseExpected:1; /**< =1 in all messages that expect a
* response (Control ignores this
* bit) */
- U32 server:1; /**< =1 in all bus & device-related
+ u32 server:1; /**< =1 in all bus & device-related
* messages where the message
* receiver is to act as the bus or
* device server */
- U32 testMessage:1; /**< =1 for testing use only
+ u32 testMessage:1; /**< =1 for testing use only
* (Control and Command ignore this
* bit) */
- U32 partialCompletion:1; /**< =1 if there are forthcoming
+ u32 partialCompletion:1; /**< =1 if there are forthcoming
* responses/acks associated
* with this message */
- U32 preserve:1; /**< =1 this is to let us know to
+ u32 preserve:1; /**< =1 this is to let us know to
* preserve channel contents
* (for running guests)*/
- U32 writerInDiag:1; /**< =1 the DiagWriter is active in the
+ u32 writerInDiag:1; /**< =1 the DiagWriter is active in the
* Diagnostic Partition*/
/* remaining bits in this 32-bit word are available */
} Flags;
- U32 Reserved; /* Natural alignment */
- U64 MessageHandle; /* Identifies the particular message instance,
+ u32 Reserved; /* Natural alignment */
+ u64 MessageHandle; /* Identifies the particular message instance,
* and is used to match particular */
/* request instances with the corresponding response instance. */
- U64 PayloadVmOffset; /* Offset of payload area from start of this
+ u64 PayloadVmOffset; /* Offset of payload area from start of this
* instance of ControlVm segment */
- U32 PayloadMaxBytes; /* Maximum bytes allocated in payload
+ u32 PayloadMaxBytes; /* Maximum bytes allocated in payload
* area of ControlVm segment */
- U32 PayloadBytes; /* Actual number of bytes of payload
+ u32 PayloadBytes; /* Actual number of bytes of payload
* area to copy between IO/Command; */
/* if non-zero, there is a payload to copy. */
} CONTROLVM_MESSAGE_HEADER;
typedef struct _CONTROLVM_PACKET_DEVICE_CREATE {
- U32 busNo; /**< bus # (0..n-1) from the msg receiver's
+ u32 busNo; /**< bus # (0..n-1) from the msg receiver's
* perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 devNo; /**< bus-relative (0..n-1) device number */
- U64 channelAddr; /**< Guest physical address of the channel, which
+ u32 devNo; /**< bus-relative (0..n-1) device number */
+ u64 channelAddr; /**< Guest physical address of the channel, which
* can be dereferenced by the receiver
* of this ControlVm command */
- U64 channelBytes; /**< specifies size of the channel in bytes */
+ u64 channelBytes; /**< specifies size of the channel in bytes */
uuid_le dataTypeGuid;/**< specifies format of data in channel */
uuid_le devInstGuid; /**< instance guid for the device */
struct InterruptInfo intr; /**< specifies interrupt information */
} CONTROLVM_PACKET_DEVICE_CREATE; /* for CONTROLVM_DEVICE_CREATE */
typedef struct _CONTROLVM_PACKET_DEVICE_CONFIGURE {
- U32 busNo; /**< bus # (0..n-1) from the msg
+ u32 busNo; /**< bus # (0..n-1) from the msg
* receiver's perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 devNo; /**< bus-relative (0..n-1) device number */
+ u32 devNo; /**< bus-relative (0..n-1) device number */
} CONTROLVM_PACKET_DEVICE_CONFIGURE; /* for CONTROLVM_DEVICE_CONFIGURE */
typedef struct _CONTROLVM_MESSAGE_DEVICE_CREATE {
@@ -323,39 +323,39 @@ typedef struct _CONTROLVM_MESSAGE_PACKET {
/* BEGIN Request messages */
struct {
- U32 busNo; /*< bus # (0..n-1) from the msg
+ u32 busNo; /*< bus # (0..n-1) from the msg
* receiver's perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 deviceCount; /*< indicates the max number of
+ u32 deviceCount; /*< indicates the max number of
* devices on this bus */
- U64 channelAddr; /*< Guest physical address of the
+ u64 channelAddr; /*< Guest physical address of the
* channel, which can be
* dereferenced by the receiver
* of this ControlVm command */
- U64 channelBytes; /*< size of the channel in bytes */
+ u64 channelBytes; /*< size of the channel in bytes */
uuid_le busDataTypeGuid;/*< indicates format of data in
bus channel */
uuid_le busInstGuid; /*< instance guid for the bus */
} createBus; /* for CONTROLVM_BUS_CREATE */
struct {
- U32 busNo; /*< bus # (0..n-1) from the msg
+ u32 busNo; /*< bus # (0..n-1) from the msg
* receiver's perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 reserved; /* Natural alignment purposes */
+ u32 reserved; /* Natural alignment purposes */
} destroyBus; /* for CONTROLVM_BUS_DESTROY */
struct {
- U32 busNo; /*< bus # (0..n-1) from the
+ u32 busNo; /*< bus # (0..n-1) from the
* msg receiver's
* perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 reserved1; /* for alignment purposes */
- U64 guestHandle; /* This is used to convert
+ u32 reserved1; /* for alignment purposes */
+ u64 guestHandle; /* This is used to convert
* guest physical address to real
* physical address for DMA, for ex. */
- U64 recvBusInterruptHandle;/*< specifies interrupt
+ u64 recvBusInterruptHandle;/*< specifies interrupt
* info. It is used by SP to register
* to receive interrupts from the CP.
* This interrupt is used for bus
@@ -368,57 +368,57 @@ typedef struct _CONTROLVM_MESSAGE_PACKET {
/* for CONTROLVM_DEVICE_CREATE */
CONTROLVM_PACKET_DEVICE_CREATE createDevice;
struct {
- U32 busNo; /*< bus # (0..n-1) from the msg
+ u32 busNo; /*< bus # (0..n-1) from the msg
* receiver's perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 devNo; /*< bus-relative (0..n-1) device
+ u32 devNo; /*< bus-relative (0..n-1) device
* number */
} destroyDevice; /* for CONTROLVM_DEVICE_DESTROY */
/* for CONTROLVM_DEVICE_CONFIGURE */
CONTROLVM_PACKET_DEVICE_CONFIGURE configureDevice;
struct {
- U32 busNo; /*< bus # (0..n-1) from the msg
+ u32 busNo; /*< bus # (0..n-1) from the msg
* receiver's perspective */
/* Control uses header SegmentIndex field to access bus number... */
- U32 devNo; /*< bus-relative (0..n-1) device
+ u32 devNo; /*< bus-relative (0..n-1) device
* number */
} reconfigureDevice; /* for CONTROLVM_DEVICE_RECONFIGURE */
struct {
- U32 busNo;
+ u32 busNo;
ULTRA_SEGMENT_STATE state;
- U8 reserved[2]; /* Natural alignment purposes */
+ u8 reserved[2]; /* Natural alignment purposes */
} busChangeState; /* for CONTROLVM_BUS_CHANGESTATE */
struct {
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
ULTRA_SEGMENT_STATE state;
struct {
- U32 physicalDevice:1; /* =1 if message is for
+ u32 physicalDevice:1; /* =1 if message is for
* a physical device */
/* remaining bits in this 32-bit word are available */
} flags;
- U8 reserved[2]; /* Natural alignment purposes */
+ u8 reserved[2]; /* Natural alignment purposes */
} deviceChangeState; /* for CONTROLVM_DEVICE_CHANGESTATE */
struct {
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
ULTRA_SEGMENT_STATE state;
- U8 reserved[6]; /* Natural alignment purposes */
+ u8 reserved[6]; /* Natural alignment purposes */
} deviceChangeStateEvent; /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */
struct {
- U32 busCount; /*< indicates the max number of busses */
- U32 switchCount; /*< indicates the max number of
+ u32 busCount; /*< indicates the max number of busses */
+ u32 switchCount; /*< indicates the max number of
* switches (applicable for service
* partition only) */
ULTRA_CHIPSET_FEATURE features;
- U32 platformNumber; /* Platform Number */
+ u32 platformNumber; /* Platform Number */
} initChipset; /* for CONTROLVM_CHIPSET_INIT */
struct {
- U32 Options; /*< reserved */
- U32 Test; /*< bit 0 set to run embedded selftest */
+ u32 Options; /*< reserved */
+ u32 Test; /*< bit 0 set to run embedded selftest */
} chipsetSelftest; /* for CONTROLVM_CHIPSET_SELFTEST */
/* END Request messages */
@@ -434,11 +434,11 @@ typedef struct _CONTROLVM_MESSAGE_PACKET {
/* BEGIN Ack messages */
/* END Ack messages */
- U64 addr; /*< a physical address of something, that
+ u64 addr; /*< a physical address of something, that
* can be dereferenced by the receiver of
* this ControlVm command (depends on
* command id) */
- U64 handle; /*< a handle of something (depends on
+ u64 handle; /*< a handle of something (depends on
* command id) */
};
} CONTROLVM_MESSAGE_PACKET;
@@ -451,10 +451,10 @@ typedef struct _CONTROLVM_MESSAGE {
typedef struct _DEVICE_MAP {
GUEST_PHYSICAL_ADDRESS DeviceChannelAddress;
- U64 DeviceChannelSize;
- U32 CA_Index;
- U32 Reserved; /* natural alignment */
- U64 Reserved2; /* Align structure on 32-byte boundary */
+ u64 DeviceChannelSize;
+ u32 CA_Index;
+ u32 Reserved; /* natural alignment */
+ u64 Reserved2; /* Align structure on 32-byte boundary */
} DEVICE_MAP;
typedef struct _GUEST_DEVICES {
@@ -463,8 +463,8 @@ typedef struct _GUEST_DEVICES {
DEVICE_MAP NetworkChannel;
DEVICE_MAP StorageChannel;
DEVICE_MAP ConsoleChannel;
- U32 PartitionIndex;
- U32 Pad;
+ u32 PartitionIndex;
+ u32 Pad;
} GUEST_DEVICES;
typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL {
@@ -487,15 +487,15 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL {
* ROM disk */
GUEST_PHYSICAL_ADDRESS gpNvram; /* guest phys addr of NVRAM
* channel */
- U64 RequestPayloadOffset; /* Offset to request payload area */
- U64 EventPayloadOffset; /* Offset to event payload area */
- U32 RequestPayloadBytes; /* Bytes available in request payload
+ u64 RequestPayloadOffset; /* Offset to request payload area */
+ u64 EventPayloadOffset; /* Offset to event payload area */
+ u32 RequestPayloadBytes; /* Bytes available in request payload
* area */
- U32 EventPayloadBytes; /* Bytes available in event payload area */
- U32 ControlChannelBytes;
- U32 NvramChannelBytes; /* Bytes in PartitionNvram segment */
- U32 MessageBytes; /* sizeof(CONTROLVM_MESSAGE) */
- U32 MessageCount; /* CONTROLVM_MESSAGE_MAX */
+ u32 EventPayloadBytes; /* Bytes available in event payload area */
+ u32 ControlChannelBytes;
+ u32 NvramChannelBytes; /* Bytes in PartitionNvram segment */
+ u32 MessageBytes; /* sizeof(CONTROLVM_MESSAGE) */
+ u32 MessageCount; /* CONTROLVM_MESSAGE_MAX */
GUEST_PHYSICAL_ADDRESS gpSmbiosTable; /* guest phys addr of SMBIOS
* tables */
GUEST_PHYSICAL_ADDRESS gpPhysicalSmbiosTable; /* guest phys addr of
@@ -510,35 +510,35 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL {
GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareEntryPoint;
/* guest EFI firmware image size */
- U64 VirtualGuestFirmwareImageSize;
+ u64 VirtualGuestFirmwareImageSize;
/* GPA = 1MB where EFI firmware image is copied to */
GUEST_PHYSICAL_ADDRESS VirtualGuestFirmwareBootBase;
GUEST_PHYSICAL_ADDRESS VirtualGuestImageBase;
GUEST_PHYSICAL_ADDRESS VirtualGuestImageSize;
- U64 PrototypeControlChannelOffset;
+ u64 PrototypeControlChannelOffset;
GUEST_PHYSICAL_ADDRESS VirtualGuestPartitionHandle;
- U16 RestoreAction; /* Restore Action field to restore the guest
+ u16 RestoreAction; /* Restore Action field to restore the guest
* partition */
- U16 DumpAction; /* For Windows guests it shows if the visordisk
+ u16 DumpAction; /* For Windows guests it shows if the visordisk
* is running in dump mode */
- U16 NvramFailCount;
- U16 SavedCrashMsgCount; /* = CONTROLVM_CRASHMSG_MAX */
- U32 SavedCrashMsgOffset; /* Offset to request payload area needed
+ u16 NvramFailCount;
+ u16 SavedCrashMsgCount; /* = CONTROLVM_CRASHMSG_MAX */
+ u32 SavedCrashMsgOffset; /* Offset to request payload area needed
* for crash dump */
- U32 InstallationError; /* Type of error encountered during
+ u32 InstallationError; /* Type of error encountered during
* installation */
- U32 InstallationTextId; /* Id of string to display */
- U16 InstallationRemainingSteps; /* Number of remaining installation
+ u32 InstallationTextId; /* Id of string to display */
+ u16 InstallationRemainingSteps; /* Number of remaining installation
* steps (for progress bars) */
- U8 ToolAction; /* ULTRA_TOOL_ACTIONS Installation Action
+ u8 ToolAction; /* ULTRA_TOOL_ACTIONS Installation Action
* field */
- U8 Reserved; /* alignment */
+ u8 Reserved; /* alignment */
ULTRA_EFI_SPAR_INDICATION EfiSparIndication;
ULTRA_EFI_SPAR_INDICATION EfiSparIndicationSupported;
- U32 SPReserved;
- U8 Reserved2[28]; /* Force signals to begin on 128-byte cache
+ u32 SPReserved;
+ u8 Reserved2[28]; /* Force signals to begin on 128-byte cache
* line */
SIGNAL_QUEUE_HEADER RequestQueue; /* Service or guest partition
* uses this queue to send
@@ -600,21 +600,21 @@ typedef struct _ULTRA_CONTROLVM_CHANNEL_PROTOCOL {
* https://ustr-linux-1.na.uis.unisys.com/spar/index.php/ControlVm_Parameters_Area
*/
typedef struct _ULTRA_CONTROLVM_PARAMETERS_HEADER {
- U32 TotalLength;
- U32 HeaderLength;
- U32 ConnectionOffset;
- U32 ConnectionLength;
- U32 InitiatorOffset;
- U32 InitiatorLength;
- U32 TargetOffset;
- U32 TargetLength;
- U32 ClientOffset;
- U32 ClientLength;
- U32 NameOffset;
- U32 NameLength;
+ u32 TotalLength;
+ u32 HeaderLength;
+ u32 ConnectionOffset;
+ u32 ConnectionLength;
+ u32 InitiatorOffset;
+ u32 InitiatorLength;
+ u32 TargetOffset;
+ u32 TargetLength;
+ u32 ClientOffset;
+ u32 ClientLength;
+ u32 NameOffset;
+ u32 NameLength;
uuid_le Id;
- U32 Revision;
- U32 Reserved; /* Natural alignment */
+ u32 Revision;
+ u32 Reserved; /* Natural alignment */
} ULTRA_CONTROLVM_PARAMETERS_HEADER;
#endif /* __CONTROLVMCHANNEL_H__ */
diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h
index 1bea2f720e48..c01649a985c7 100644
--- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h
+++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h
@@ -106,17 +106,17 @@ static const uuid_le UltraDiagChannelProtocolGuid =
* in some of the Supervisor areas, such as Monitor, so it has been "ported" here
* for use in diagnostic event timestamps... */
typedef struct _DIAG_EFI_TIME {
- U16 Year; /* 1998 - 20XX */
- U8 Month; /* 1 - 12 */
- U8 Day; /* 1 - 31 */
- U8 Hour; /* 0 - 23 */
- U8 Minute; /* 0 - 59 */
- U8 Second; /* 0 - 59 */
- U8 Pad1;
- U32 Nanosecond; /* 0 - 999, 999, 999 */
- S16 TimeZone; /* -1440 to 1440 or 2047 */
- U8 Daylight;
- U8 Pad2;
+ u16 Year; /* 1998 - 20XX */
+ u8 Month; /* 1 - 12 */
+ u8 Day; /* 1 - 31 */
+ u8 Hour; /* 0 - 23 */
+ u8 Minute; /* 0 - 59 */
+ u8 Second; /* 0 - 59 */
+ u8 Pad1;
+ u32 Nanosecond; /* 0 - 999, 999, 999 */
+ s16 TimeZone; /* -1440 to 1440 or 2047 */
+ u8 Daylight;
+ u8 Pad2;
} DIAG_EFI_TIME;
typedef enum {
@@ -156,31 +156,31 @@ typedef enum {
* AdditionalInfo: Array of characters for additional event info (may be
* empty). */
typedef struct _DIAG_CHANNEL_EVENT {
- U32 EventId;
- U32 Severity;
- U8 ModuleName[MAX_MODULE_NAME_SIZE];
- U32 LineNumber;
+ u32 EventId;
+ u32 Severity;
+ u8 ModuleName[MAX_MODULE_NAME_SIZE];
+ u32 LineNumber;
DIAG_EFI_TIME Timestamp; /* Size = 16 bytes */
- U32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are
+ u32 PartitionNumber; /* Filled in by Diag Switch as pool blocks are
* filled */
- U16 VirtualProcessorNumber;
- U16 LogicalProcessorNumber;
- U8 ComponentType; /* ULTRA_COMPONENT_TYPES */
- U8 Subsystem;
- U16 Reserved0; /* pad to U64 alignment */
- U32 BlockNumber; /* filled in by DiagSwitch as pool blocks are
+ u16 VirtualProcessorNumber;
+ u16 LogicalProcessorNumber;
+ u8 ComponentType; /* ULTRA_COMPONENT_TYPES */
+ u8 Subsystem;
+ u16 Reserved0; /* pad to u64 alignment */
+ u32 BlockNumber; /* filled in by DiagSwitch as pool blocks are
* filled */
- U32 BlockNumberHigh;
- U32 EventNumber; /* filled in by DiagSwitch as pool blocks are
+ u32 BlockNumberHigh;
+ u32 EventNumber; /* filled in by DiagSwitch as pool blocks are
* filled */
- U32 EventNumberHigh;
+ u32 EventNumberHigh;
/* The BlockNumber and EventNumber fields are set only by DiagSwitch
* and referenced only by WinDiagDisplay formatting tool as
* additional diagnostic information. Other tools including
* WinDiagDisplay currently ignore these 'Reserved' bytes. */
- U8 Reserved[8];
- U8 AdditionalInfo[MAX_ADDITIONAL_INFO_SIZE];
+ u8 Reserved[8];
+ u8 AdditionalInfo[MAX_ADDITIONAL_INFO_SIZE];
/* NOTE: Changesto DIAG_CHANNEL_EVENT generally need to be reflected in
* existing copies *
@@ -363,10 +363,10 @@ typedef enum {
* particular subsystem below this level will be discarded.
*/
typedef struct _DIAG_CHANNEL_PROTOCOL_HEADER {
- volatile U32 DiagLock;
- U8 IsChannelInitialized;
- U8 Reserved[3];
- U8 SubsystemSeverityFilter[64];
+ volatile u32 DiagLock;
+ u8 IsChannelInitialized;
+ u8 Reserved[3];
+ u8 SubsystemSeverityFilter[64];
} DIAG_CHANNEL_PROTOCOL_HEADER;
/* The Diagram for the Diagnostic Channel: */
diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h
index 6dcfa6e78375..24e11858e0ee 100644
--- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h
+++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h
@@ -213,7 +213,7 @@ typedef enum { NET_RCV_POST = 0, /* submit buffer to hold receiving
#endif /* MAX_MACADDR_LEN */
#define ETH_IS_LOCALLY_ADMINISTERED(Address) \
- (((U8 *) (Address))[0] & ((U8) 0x02))
+ (((u8 *) (Address))[0] & ((u8) 0x02))
#define NIC_VENDOR_ID 0x0008000B
/* various types of scsi task mgmt commands */
@@ -250,35 +250,35 @@ typedef enum { VDISK_MGMT_ACQUIRE = 1, VDISK_MGMT_RELEASE,
#pragma pack(push, 1)
struct guest_phys_info {
- U64 address;
- U64 length;
+ u64 address;
+ u64 length;
};
#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info))
struct uisscsi_dest {
- U32 channel; /* channel == bus number */
- U32 id; /* id == target number */
- U32 lun; /* lun == logical unit number */
+ u32 channel; /* channel == bus number */
+ u32 id; /* id == target number */
+ u32 lun; /* lun == logical unit number */
};
struct vhba_wwnn {
- U32 wwnn1;
- U32 wwnn2;
+ u32 wwnn1;
+ u32 wwnn2;
};
/* WARNING: Values stired in this structure must contain maximum counts (not
* maximum values). */
struct vhba_config_max { /* 20 bytes */
- U32 max_channel; /* maximum channel for devices attached to this
+ u32 max_channel; /* maximum channel for devices attached to this
* bus */
- U32 max_id; /* maximum SCSI ID for devices attached to this
+ u32 max_id; /* maximum SCSI ID for devices attached to this
* bus */
- U32 max_lun; /* maximum SCSI LUN for devices attached to this
+ u32 max_lun; /* maximum SCSI LUN for devices attached to this
* bus */
- U32 cmd_per_lun; /* maximum number of outstanding commands per
+ u32 cmd_per_lun; /* maximum number of outstanding commands per
* lun that are allowed at one time */
- U32 max_io_size; /* maximum io size for devices attached to this
+ 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 */
@@ -287,9 +287,9 @@ struct vhba_config_max { /* 20 bytes */
struct uiscmdrsp_scsi {
void *scsicmd; /* 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 (sg)
+ 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 (sg)
* list */
struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address
* information for each
@@ -302,8 +302,8 @@ struct uiscmdrsp_scsi {
* originator */
int linuxstat; /* the original Linux status - for use by linux
* vdisk code */
- U8 scsistat; /* the scsi status */
- U8 addlstat; /* non-scsi status - covers cases like timeout
+ u8 scsistat; /* the scsi status */
+ u8 addlstat; /* non-scsi status - covers cases like timeout
* needed by windows guests */
#define ADDL_RESET 1
#define ADDL_TIMEOUT 2
@@ -314,7 +314,7 @@ struct uiscmdrsp_scsi {
#define ADDL_RETRY 7
/* the following fields are need to determine the result of command */
- U8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */
+ u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */
/* it holds the sense_data struct; */
/* see that struct for details. */
void *vdisk; /* contains pointer to the vdisk so that we can clean up
@@ -376,16 +376,16 @@ struct uiscmdrsp_scsi {
#define SET_NO_DISK_INQUIRY_RESULT(buf, len, lun, lun0notpresent, notpresent) \
do { \
- MEMSET(buf, 0, \
+ memset(buf, 0, \
MINNUM(len, \
(unsigned int) NO_DISK_INQUIRY_RESULT_LEN)); \
- buf[2] = (U8) SCSI_SPC2_VER; \
+ buf[2] = (u8) SCSI_SPC2_VER; \
if (lun == 0) { \
- buf[0] = (U8) lun0notpresent; \
- buf[3] = (U8) DEV_HISUPPORT; \
+ buf[0] = (u8) lun0notpresent; \
+ buf[3] = (u8) DEV_HISUPPORT; \
} else \
- buf[0] = (U8) notpresent; \
- buf[4] = (U8) ( \
+ buf[0] = (u8) notpresent; \
+ buf[4] = (u8) ( \
MINNUM(len, \
(unsigned int) NO_DISK_INQUIRY_RESULT_LEN) - 5); \
if (len >= NO_DISK_INQUIRY_RESULT_LEN) { \
@@ -430,21 +430,21 @@ struct uiscmdrsp_scsi {
* AdditionalSenseLength contains will be sizeof(sense_data)-8=10.
*/
struct sense_data {
- U8 ErrorCode:7;
- U8 Valid:1;
- U8 SegmentNumber;
- U8 SenseKey:4;
- U8 Reserved:1;
- U8 IncorrectLength:1;
- U8 EndOfMedia:1;
- U8 FileMark:1;
- U8 Information[4];
- U8 AdditionalSenseLength;
- U8 CommandSpecificInformation[4];
- U8 AdditionalSenseCode;
- U8 AdditionalSenseCodeQualifier;
- U8 FieldReplaceableUnitCode;
- U8 SenseKeySpecific[3];
+ u8 ErrorCode:7;
+ u8 Valid:1;
+ u8 SegmentNumber;
+ u8 SenseKey:4;
+ u8 Reserved:1;
+ u8 IncorrectLength:1;
+ u8 EndOfMedia:1;
+ u8 FileMark:1;
+ u8 Information[4];
+ u8 AdditionalSenseLength;
+ u8 CommandSpecificInformation[4];
+ u8 AdditionalSenseCode;
+ u8 AdditionalSenseCodeQualifier;
+ u8 FieldReplaceableUnitCode;
+ u8 SenseKeySpecific[3];
};
/* some SCSI ADSENSE codes */
@@ -487,15 +487,15 @@ struct net_pkt_xmt {
struct {
/* these are needed for csum at uisnic end */
- U8 valid; /* 1 = rest of this struct is valid - else
+ u8 valid; /* 1 = rest of this struct is valid - else
* ignore */
- U8 hrawoffv; /* 1 = hwrafoff is valid */
- U8 nhrawoffv; /* 1 = nhwrafoff is valid */
- U16 protocol; /* specifies packet protocol */
- U32 csum; /* value used to set skb->csum at IOPart */
- U32 hrawoff; /* value used to set skb->h.raw at IOPart */
+ u8 hrawoffv; /* 1 = hwrafoff is valid */
+ u8 nhrawoffv; /* 1 = nhwrafoff is valid */
+ u16 protocol; /* specifies packet protocol */
+ u32 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 */
+ u32 nhrawoff; /* value used to set skb->nh.raw at IOPart */
/* nhrawoff points to the start of the NETWORK LAYER HEADER */
} lincsum;
@@ -508,7 +508,7 @@ struct net_pkt_xmt {
};
struct net_pkt_xmtdone {
- U32 xmt_done_result; /* result of NET_XMIT */
+ u32 xmt_done_result; /* result of NET_XMIT */
#define XMIT_SUCCESS 0
#define XMIT_FAILED 1
};
@@ -529,7 +529,7 @@ struct net_pkt_rcvpost {
* to be describable */
struct phys_info frag; /* physical page information for the
* single fragment 2K rcv buf */
- U64 UniqueNum; /* This is used to make sure that
+ u64 UniqueNum; /* This is used to make sure that
* receive posts are returned to */
/* the Adapter which sent them origonally. */
};
@@ -538,25 +538,25 @@ struct net_pkt_rcv {
/* the number of receive buffers that can be chained */
/* is based on max mtu and size of each rcv buf */
- U32 rcv_done_len; /* length of received data */
- U8 numrcvbufs; /* number of receive buffers that contain the */
+ u32 rcv_done_len; /* length of received data */
+ u8 numrcvbufs; /* number of receive buffers that contain the */
/* incoming data; guest end MUST chain these together. */
void *rcvbuf[MAX_NET_RCV_CHAIN]; /* the list of receive buffers
* that must be chained; */
/* each entry is a receive buffer provided by NET_RCV_POST. */
/* NOTE: first rcvbuf in the chain will also be provided in net.buf. */
- U64 UniqueNum;
- U32 RcvsDroppedDelta;
+ u64 UniqueNum;
+ u32 RcvsDroppedDelta;
};
struct net_pkt_enbdis {
void *context;
- U16 enable; /* 1 = enable, 0 = disable */
+ u16 enable; /* 1 = enable, 0 = disable */
};
struct net_pkt_macaddr {
void *context;
- U8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
+ u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
};
/* cmd rsp packet used for VNIC network traffic */
@@ -615,10 +615,10 @@ struct uiscmdrsp_scsitaskmgmt {
* Guest */
/* Note that the vHba pointer is not used by the Client/Guest side. */
struct uiscmdrsp_disknotify {
- U8 add; /* 0-remove, 1-add */
+ u8 add; /* 0-remove, 1-add */
void *vHba; /* Pointer to vhba_info for channel info to
* route msg */
- U32 channel, id, lun; /* SCSI Path of Disk to added or removed */
+ u32 channel, id, lun; /* SCSI Path of Disk to added or removed */
};
/* The following is used by virthba/vSCSI to send the Acquire/Release commands
@@ -695,15 +695,15 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL {
struct vhba_config_max max; /* 20 bytes */
} vhba; /* 28 */
struct {
- U8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
- U32 num_rcv_bufs; /* 4 */
- U32 mtu; /* 4 */
+ u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */
+ u32 num_rcv_bufs; /* 4 */
+ u32 mtu; /* 4 */
uuid_le zoneGuid; /* 16 */
} vnic; /* total 30 */
};
#define MAX_CLIENTSTRING_LEN 1024
- U8 clientString[MAX_CLIENTSTRING_LEN]; /* NULL terminated - so holds
+ u8 clientString[MAX_CLIENTSTRING_LEN]; /* NULL terminated - so holds
* max - 1 bytes */
} ULTRA_IO_CHANNEL_PROTOCOL;
@@ -777,9 +777,9 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL {
OFFSETOF(type, clientString); \
MEMCPY(chan->clientString, clientStr, \
MINNUM(clientStrLen, \
- (U32) (MAX_CLIENTSTRING_LEN - 1))); \
+ (u32) (MAX_CLIENTSTRING_LEN - 1))); \
chan->clientString[MINNUM(clientStrLen, \
- (U32) (MAX_CLIENTSTRING_LEN \
+ (u32) (MAX_CLIENTSTRING_LEN \
- 1))] \
= '\0'; \
} \
@@ -801,8 +801,8 @@ static inline int ULTRA_VHBA_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x,
struct vhba_wwnn *wwnn,
struct vhba_config_max *max,
unsigned char *clientStr,
- U32 clientStrLen, U64 bytes) {
- MEMSET(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
+ u32 clientStrLen, u64 bytes) {
+ memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
x->ChannelHeader.VersionId = ULTRA_VHBA_CHANNEL_PROTOCOL_VERSIONID;
x->ChannelHeader.Signature = ULTRA_VHBA_CHANNEL_PROTOCOL_SIGNATURE;
x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED;
@@ -833,12 +833,12 @@ static inline void ULTRA_VHBA_set_max(ULTRA_IO_CHANNEL_PROTOCOL *x,
static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x,
unsigned char *macaddr,
- U32 num_rcv_bufs, U32 mtu,
+ u32 num_rcv_bufs, u32 mtu,
uuid_le zoneGuid,
unsigned char *clientStr,
- U32 clientStrLen,
- U64 bytes) {
- MEMSET(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
+ u32 clientStrLen,
+ u64 bytes) {
+ memset(x, 0, sizeof(ULTRA_IO_CHANNEL_PROTOCOL));
x->ChannelHeader.VersionId = ULTRA_VNIC_CHANNEL_PROTOCOL_VERSIONID;
x->ChannelHeader.Signature = ULTRA_VNIC_CHANNEL_PROTOCOL_SIGNATURE;
x->ChannelHeader.SrvState = CHANNELSRV_UNINITIALIZED;
@@ -882,22 +882,22 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x,
/* returns next non-zero index on success or zero on failure (i.e. out of
* room)
*/
-static INLINE U16
-add_physinfo_entries(U32 inp_pfn, /* input - specifies the pfn to be used
+static INLINE u16
+add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used
* to add entries */
- U16 inp_off, /* input - specifies the off to be used
+ u16 inp_off, /* input - specifies the off to be used
* to add entries */
- U32 inp_len, /* input - specifies the len to be used
+ u32 inp_len, /* input - specifies the len to be used
* to add entries */
- U16 index, /* input - index in array at which new
+ u16 index, /* input - index in array at which new
* entries are added */
- U16 max_pi_arr_entries, /* input - specifies the maximum
+ u16 max_pi_arr_entries, /* input - specifies the maximum
* entries pi_arr can hold */
struct phys_info pi_arr[]) /* input & output - array to
* which entries are added */
{
- U32 len;
- U16 i, firstlen;
+ u32 len;
+ u16 i, firstlen;
firstlen = PI_PAGE_SIZE - inp_off;
if (inp_len <= firstlen) {
@@ -906,8 +906,8 @@ add_physinfo_entries(U32 inp_pfn, /* input - specifies the pfn to be used
if (index >= max_pi_arr_entries)
return 0;
pi_arr[index].pi_pfn = inp_pfn;
- pi_arr[index].pi_off = (U16) inp_off;
- pi_arr[index].pi_len = (U16) inp_len;
+ pi_arr[index].pi_off = (u16) inp_off;
+ pi_arr[index].pi_len = (u16) inp_len;
return index + 1;
}
@@ -925,7 +925,7 @@ add_physinfo_entries(U32 inp_pfn, /* input - specifies the pfn to be used
else {
pi_arr[index + i].pi_off = 0;
pi_arr[index + i].pi_len =
- (U16) MINNUM(len, (U32) PI_PAGE_SIZE);
+ (u16) MINNUM(len, (u32) PI_PAGE_SIZE);
}
}
diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h
index 0dd3e2dd0e1d..8facb51143ae 100644
--- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h
+++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h
@@ -63,17 +63,17 @@ static const uuid_le UltraVbusChannelProtocolGuid =
#pragma pack(push, 1) /* both GCC and VC now allow this pragma */
typedef struct _ULTRA_VBUS_HEADERINFO {
- U32 structBytes; /* size of this struct in bytes */
- U32 deviceInfoStructBytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */
- U32 devInfoCount; /* num of items in DevInfo member */
+ u32 structBytes; /* size of this struct in bytes */
+ u32 deviceInfoStructBytes; /* sizeof(ULTRA_VBUS_DEVICEINFO) */
+ u32 devInfoCount; /* num of items in DevInfo member */
/* (this is the allocated size) */
- U32 chpInfoByteOffset; /* byte offset from beginning of this struct */
+ u32 chpInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the ChpInfo struct (below) */
- U32 busInfoByteOffset; /* byte offset from beginning of this struct */
+ u32 busInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the BusInfo struct (below) */
- U32 devInfoByteOffset; /* byte offset from beginning of this struct */
+ u32 devInfoByteOffset; /* byte offset from beginning of this struct */
/* to the the DevInfo array (below) */
- U8 reserved[104];
+ u8 reserved[104];
} ULTRA_VBUS_HEADERINFO;
typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL {
@@ -94,42 +94,6 @@ typedef struct _ULTRA_VBUS_CHANNEL_PROTOCOL {
sizeof(ULTRA_VBUS_DEVICEINFO)))
#define VBUS_CH_SIZE(MAXDEVICES) COVER(VBUS_CH_SIZE_EXACT(MAXDEVICES), 4096)
-static INLINE void
-ULTRA_VBUS_init_channel(ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *x,
- int bytesAllocated)
-{
- /* Please note that the memory at <x> does NOT necessarily have space
- * for DevInfo structs allocated at the end, which is why we do NOT use
- * <bytesAllocated> to clear. */
- memset_io(x, 0, sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL));
- if (bytesAllocated < (int) sizeof(ULTRA_VBUS_CHANNEL_PROTOCOL))
- return;
- writel(ULTRA_VBUS_CHANNEL_PROTOCOL_VERSIONID,
- &x->ChannelHeader.VersionId);
- writeq(ULTRA_VBUS_CHANNEL_PROTOCOL_SIGNATURE,
- &x->ChannelHeader.Signature);
- writel(CHANNELSRV_READY, &x->ChannelHeader.SrvState);
- writel(sizeof(x->ChannelHeader), &x->ChannelHeader.HeaderSize);
- writeq(bytesAllocated, &x->ChannelHeader.Size);
- memcpy_toio(&x->ChannelHeader.Type, &UltraVbusChannelProtocolGuid,
- sizeof(x->ChannelHeader.Type));
- memcpy_toio(&x->ChannelHeader.ZoneGuid, &NULL_UUID_LE, sizeof(uuid_le));
- writel(sizeof(ULTRA_VBUS_HEADERINFO), &x->HdrInfo.structBytes);
- writel(sizeof(ULTRA_VBUS_HEADERINFO), &x->HdrInfo.chpInfoByteOffset);
- writel(readl(&x->HdrInfo.chpInfoByteOffset) +
- sizeof(ULTRA_VBUS_DEVICEINFO),
- &x->HdrInfo.busInfoByteOffset);
- writel(readl(&x->HdrInfo.busInfoByteOffset)
- + sizeof(ULTRA_VBUS_DEVICEINFO),
- &x->HdrInfo.devInfoByteOffset);
- writel(sizeof(ULTRA_VBUS_DEVICEINFO),
- &x->HdrInfo.deviceInfoStructBytes);
- bytesAllocated -= (sizeof(ULTRA_CHANNEL_PROTOCOL)
- + readl(&x->HdrInfo.devInfoByteOffset));
- writel(bytesAllocated / readl(&x->HdrInfo.deviceInfoStructBytes),
- &x->HdrInfo.devInfoCount);
-}
-
#pragma pack(pop)
#endif
diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
index 8c0259a2cbce..5e0d98cd422e 100644
--- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
+++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
@@ -26,11 +26,11 @@
* and driver from the client's perspective.
*/
typedef struct _ULTRA_VBUS_DEVICEINFO {
- U8 devType[16]; /* short string identifying the device type */
- U8 drvName[16]; /* driver .sys file name */
- U8 infoStrings[96]; /* sequence of tab-delimited id strings: */
+ u8 devType[16]; /* short string identifying the device type */
+ u8 drvName[16]; /* driver .sys file name */
+ u8 infoStrings[96]; /* sequence of tab-delimited id strings: */
/* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
- U8 reserved[128]; /* pad size to 256 bytes */
+ u8 reserved[128]; /* pad size to 256 bytes */
} ULTRA_VBUS_DEVICEINFO;
#pragma pack(pop)
@@ -50,12 +50,12 @@ typedef struct _ULTRA_VBUS_DEVICEINFO {
* to a buffer at <p>, had it been infinitely big.
*/
static inline int
-VBUSCHANNEL_sanitize_buffer(char *p, int remain, char __iomem *src, int srcmax)
+vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
{
int chars = 0;
int nonprintable_streak = 0;
while (srcmax > 0) {
- if ((readb(src) >= ' ') && (readb(src) < 0x7f)) {
+ if ((*src >= ' ') && (*src < 0x7f)) {
if (nonprintable_streak) {
if (remain > 0) {
*p = ' ';
@@ -67,7 +67,7 @@ VBUSCHANNEL_sanitize_buffer(char *p, int remain, char __iomem *src, int srcmax)
nonprintable_streak = 0;
}
if (remain > 0) {
- *p = readb(src);
+ *p = *src;
p++;
remain--;
chars++;
@@ -99,7 +99,7 @@ VBUSCHANNEL_sanitize_buffer(char *p, int remain, char __iomem *src, int srcmax)
* an environment-independent way (since we are in a common header file).
*/
static inline int
-VBUSCHANNEL_itoa(char *p, int remain, int num)
+vbuschannel_itoa(char *p, int remain, int num)
{
int digits = 0;
char s[32];
@@ -146,22 +146,22 @@ VBUSCHANNEL_itoa(char *p, int remain, int num)
* Returns the number of bytes written to <p>.
*/
static inline int
-VBUSCHANNEL_devInfoToStringBuffer(ULTRA_VBUS_DEVICEINFO __iomem *devInfo,
+vbuschannel_devinfo_to_string(ULTRA_VBUS_DEVICEINFO *devinfo,
char *p, int remain, int devix)
{
- char __iomem *psrc;
+ char *psrc;
int nsrc, x, i, pad;
int chars = 0;
- psrc = &(devInfo->devType[0]);
- nsrc = sizeof(devInfo->devType);
- if (VBUSCHANNEL_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
+ psrc = &(devinfo->devType[0]);
+ nsrc = sizeof(devinfo->devType);
+ if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
return 0;
/* emit device index */
if (devix >= 0) {
VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
- x = VBUSCHANNEL_itoa(p, remain, devix);
+ x = vbuschannel_itoa(p, remain, devix);
p += x;
remain -= x;
chars += x;
@@ -173,7 +173,7 @@ VBUSCHANNEL_devInfoToStringBuffer(ULTRA_VBUS_DEVICEINFO __iomem *devInfo,
}
/* emit device type */
- x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
@@ -183,9 +183,9 @@ VBUSCHANNEL_devInfoToStringBuffer(ULTRA_VBUS_DEVICEINFO __iomem *devInfo,
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
/* emit driver name */
- psrc = &(devInfo->drvName[0]);
- nsrc = sizeof(devInfo->drvName);
- x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
+ psrc = &(devinfo->drvName[0]);
+ nsrc = sizeof(devinfo->drvName);
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
@@ -195,9 +195,9 @@ VBUSCHANNEL_devInfoToStringBuffer(ULTRA_VBUS_DEVICEINFO __iomem *devInfo,
VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
/* emit strings */
- psrc = &(devInfo->infoStrings[0]);
- nsrc = sizeof(devInfo->infoStrings);
- x = VBUSCHANNEL_sanitize_buffer(p, remain, psrc, nsrc);
+ psrc = &(devinfo->infoStrings[0]);
+ nsrc = sizeof(devinfo->infoStrings);
+ x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
p += x;
remain -= x;
chars += x;
diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h
index c5c10f3f1eb4..0b5b5626af5a 100644
--- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h
+++ b/drivers/staging/unisys/common-spar/include/vmcallinterface.h
@@ -88,7 +88,7 @@ typedef enum { /* VMCALL identification tuples */
* not used much */
#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity) \
do { \
- U32 _tempresult = VMCALL_SUCCESS; \
+ u32 _tempresult = VMCALL_SUCCESS; \
ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity, \
MDS_APPOS, postcode, _tempresult); \
} while (0)
@@ -100,9 +100,9 @@ do { \
/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
#pragma pack(push, 1)
struct phys_info {
- U64 pi_pfn;
- U16 pi_off;
- U16 pi_len;
+ u64 pi_pfn;
+ u16 pi_off;
+ u16 pi_len;
};
#pragma pack(pop)
@@ -116,11 +116,11 @@ typedef struct phys_info IO_DATA_STRUCTURE;
typedef 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 ChannelAddress; /* contents provided by this VMCALL (OUT) */
+ u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
/* the size of the ControlVm channel in bytes This VMCall fills this
* in with the appropriate address. */
- U32 ChannelBytes; /* contents provided by this VMCALL (OUT) */
- U8 Unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */
+ u32 ChannelBytes; /* contents provided by this VMCALL (OUT) */
+ u8 Unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */
} VMCALL_IO_CONTROLVM_ADDR_PARAMS;
#pragma pack(pop)
@@ -133,7 +133,7 @@ typedef struct _VMCALL_IO_CONTROLVM_ADDR_PARAMS {
typedef struct _VMCALL_IO_DIAG_ADDR_PARAMS {
/* The Guest-relative physical address of the diagnostic channel.
* This VMCall fills this in with the appropriate address. */
- U64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
+ u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
} VMCALL_IO_DIAG_ADDR_PARAMS;
#pragma pack(pop)
@@ -147,7 +147,7 @@ typedef struct _VMCALL_IO_VISORSERIAL_ADDR_PARAMS {
/* The Guest-relative physical address of the serial console
* channel. This VMCall fills this in with the appropriate
* address. */
- U64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
+ u64 ChannelAddress; /* contents provided by this VMCALL (OUT) */
} VMCALL_IO_VISORSERIAL_ADDR_PARAMS;
#pragma pack(pop)
@@ -155,12 +155,12 @@ typedef struct _VMCALL_IO_VISORSERIAL_ADDR_PARAMS {
/* Parameters to VMCALL_CHANNEL_MISMATCH interface */
typedef struct _VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS {
- U8 ChannelName[32]; /* Null terminated string giving name of channel
+ u8 ChannelName[32]; /* Null terminated string giving name of channel
* (IN) */
- U8 ItemName[32]; /* Null terminated string giving name of
+ u8 ItemName[32]; /* Null terminated string giving name of
* mismatched item (IN) */
- U32 SourceLineNumber; /* line# where invoked. (IN) */
- U8 SourceFileName[36]; /* source code where invoked - Null terminated
+ u32 SourceLineNumber; /* line# where invoked. (IN) */
+ u8 SourceFileName[36]; /* source code where invoked - Null terminated
* string (IN) */
} VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS;
diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h
index 9de6f9dc5fbf..4311e9f6200f 100644
--- a/drivers/staging/unisys/include/commontypes.h
+++ b/drivers/staging/unisys/include/commontypes.h
@@ -20,58 +20,16 @@
* similar abbreviated content */
#define _SUPERVISOR_COMMONTYPES_H_
-#ifdef __KERNEL__
#include <linux/types.h>
#include <linux/version.h>
#include <linux/io.h>
#include <linux/uuid.h>
-#else
-#include <stdint.h>
-#include <syslog.h>
-#endif
-
-#define U8 uint8_t
-#define U16 uint16_t
-#define U32 uint32_t
-#define U64 uint64_t
-#define S8 int8_t
-#define S16 int16_t
-#define S32 int32_t
-#define S64 int64_t
-
-#ifdef __KERNEL__
-
-#ifdef CONFIG_X86_32
-#define UINTN U32
-#else
-#define UINTN U64
-#endif
-
-#else
-
-#include <stdint.h>
-#if __WORDSIZE == 32
-#define UINTN U32
-#elif __WORDSIZE == 64
-#define UINTN U64
-#else
-#error Unsupported __WORDSIZE
-#endif
-
-#endif
-
-typedef U64 GUEST_PHYSICAL_ADDRESS;
-#define MEMSET(ptr, val, len) memset(ptr, val, len)
-#define MEMCMP(m1, m2, len) memcmp(m1, m2, len)
-#define MEMCMP_IO(m1, m2, len) memcmp((void __force *)m1, m2, len)
-#define STRLEN(s) ((UINTN)strlen((const char *)s))
-#define STRCPY(d, s) (strcpy((char *)d, (const char *)s))
+typedef u64 GUEST_PHYSICAL_ADDRESS;
#define INLINE inline
#define OFFSETOF offsetof
-#ifdef __KERNEL__
#define MEMORYBARRIER mb()
#define MEMCPY(dest, src, len) memcpy(dest, src, len)
#define MEMCPY_TOIO(dest, src, len) memcpy_toio(dest, src, len)
@@ -108,47 +66,6 @@ typedef U64 GUEST_PHYSICAL_ADDRESS;
LineNumber, Str, args...) \
pr_info(Str, ## args)
-#else
-#define MEMCPY(dest, src, len) memcpy(dest, src, len)
-
-#define MEMORYBARRIER mb()
-
-#define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \
- lin, logCtx) \
- do { \
- syslog(LOG_USER | LOG_ERR, \
- "Channel mismatch on channel=%s(%pUL) field=%s expected=%pUL actual=%pUL @%s:%d", \
- chName, &chType, field, \
- &expected, &actual, \
- fil, lin); \
- } while (0)
-
-#define CHANNEL_U32_MISMATCH(chType, chName, field, expected, actual, fil, \
- lin, logCtx) \
- do { \
- syslog(LOG_USER | LOG_ERR, \
- "Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8lx actual=0x%-8.8lx @%s:%d", \
- chName, chType, field, \
- (unsigned long)expected, (unsigned long)actual, \
- fil, lin); \
- } while (0)
-
-#define CHANNEL_U64_MISMATCH(chType, chName, field, expected, actual, fil, \
- lin, logCtx) \
- do { \
- syslog(LOG_USER | LOG_ERR, \
- "Channel mismatch on channel=%s(%pUL) field=%s expected=0x%-8.8Lx actual=0x%-8.8Lx @%s:%d", \
- chName, chType, field, \
- (unsigned long long)expected, \
- (unsigned long long)actual, \
- fil, lin); \
- } while (0)
-
-#define UltraLogEvent(logCtx, EventId, Severity, SubsystemMask, pFunctionName, \
- LineNumber, Str, args...) \
- syslog(LOG_USER | LOG_INFO, Str, ## args)
-#endif
-
#define VolatileBarrier() MEMORYBARRIER
#endif
diff --git a/drivers/staging/unisys/include/guestlinuxdebug.h b/drivers/staging/unisys/include/guestlinuxdebug.h
index efc4005368b0..8728e4c7bf6b 100644
--- a/drivers/staging/unisys/include/guestlinuxdebug.h
+++ b/drivers/staging/unisys/include/guestlinuxdebug.h
@@ -150,33 +150,33 @@ typedef enum { /* POSTCODE event identifier tuples */
#define POSTCODE_LINUX_A(DRIVER_PC, EVENT_PC, pc32bit, severity) \
do { \
unsigned long long post_code_temp; \
- post_code_temp = (((U64)DRIVER_PC) << 56) | (((U64)EVENT_PC) << 44) | \
- ((((U64)__LINE__) & 0xFFF) << 32) | \
- (((U64)pc32bit) & 0xFFFFFFFF); \
+ post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
+ ((((u64)__LINE__) & 0xFFF) << 32) | \
+ (((u64)pc32bit) & 0xFFFFFFFF); \
ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
} while (0)
#define POSTCODE_LINUX_B(DRIVER_PC, EVENT_PC, pc16bit1, pc16bit2, severity) \
do { \
unsigned long long post_code_temp; \
- post_code_temp = (((U64)DRIVER_PC) << 56) | (((U64)EVENT_PC) << 44) | \
- ((((U64)__LINE__) & 0xFFF) << 32) | \
- ((((U64)pc16bit1) & 0xFFFF) << 16) | \
- (((U64)pc16bit2) & 0xFFFF); \
+ post_code_temp = (((u64)DRIVER_PC) << 56) | (((u64)EVENT_PC) << 44) | \
+ ((((u64)__LINE__) & 0xFFF) << 32) | \
+ ((((u64)pc16bit1) & 0xFFFF) << 16) | \
+ (((u64)pc16bit2) & 0xFFFF); \
ISSUE_IO_VMCALL_POSTCODE_SEVERITY(post_code_temp, severity); \
} while (0)
/* MOST COMMON */
#define POSTCODE_LINUX_2(EVENT_PC, severity) \
- POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity);
+ POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, 0x0000, severity)
#define POSTCODE_LINUX_3(EVENT_PC, pc32bit, severity) \
- POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity);
+ POSTCODE_LINUX_A(CURRENT_FILE_PC, EVENT_PC, pc32bit, severity)
#define POSTCODE_LINUX_4(EVENT_PC, pc16bit1, pc16bit2, severity) \
POSTCODE_LINUX_B(CURRENT_FILE_PC, EVENT_PC, pc16bit1, \
- pc16bit2, severity);
+ pc16bit2, severity)
#endif
#endif
diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h
index 2a5bea3b3325..a2abfa8c82fd 100644
--- a/drivers/staging/unisys/include/uisqueue.h
+++ b/drivers/staging/unisys/include/uisqueue.h
@@ -39,13 +39,13 @@ struct uisqueue_info {
/* channel containing queues in which scsi commands &
* responses are queued
*/
- U64 packets_sent;
- U64 packets_received;
- U64 interrupts_sent;
- U64 interrupts_received;
- U64 max_not_empty_cnt;
- U64 total_wakeup_cnt;
- U64 non_empty_wakeup_cnt;
+ u64 packets_sent;
+ u64 packets_received;
+ u64 interrupts_sent;
+ u64 interrupts_received;
+ u64 max_not_empty_cnt;
+ u64 total_wakeup_cnt;
+ u64 non_empty_wakeup_cnt;
struct {
SIGNAL_QUEUE_HEADER Reserved1; /* */
@@ -54,7 +54,7 @@ struct uisqueue_info {
unsigned int (*send_int_if_needed)(struct uisqueue_info *info,
unsigned int whichcqueue,
unsigned char issueInterruptIfEmpty,
- U64 interruptHandle,
+ u64 interruptHandle,
unsigned char io_termination);
};
@@ -84,7 +84,7 @@ unsigned long long uisqueue_InterlockedAnd(unsigned long long __iomem *Target,
unsigned int uisqueue_send_int_if_needed(struct uisqueue_info *pqueueinfo,
unsigned int whichqueue,
unsigned char issueInterruptIfEmpty,
- U64 interruptHandle,
+ u64 interruptHandle,
unsigned char io_termination);
int uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
@@ -92,9 +92,9 @@ int uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
unsigned int queue,
void *insertlock,
unsigned char issueInterruptIfEmpty,
- U64 interruptHandle,
+ u64 interruptHandle,
char oktowait,
- U8 *channelId);
+ u8 *channelId);
/* uisqueue_get_cmdrsp gets the cmdrsp entry at the head of the queue
* and copies it to the area pointed by cmdrsp param.
@@ -108,11 +108,11 @@ uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo, void *cmdrsp,
#define MAX_NAME_SIZE_UISQUEUE 64
struct extport_info {
- U8 valid:1;
+ u8 valid:1;
/* if 1, indicates this extport slot is occupied
* if 0, indicates that extport slot is unoccupied */
- U32 num_devs_using;
+ u32 num_devs_using;
/* When extport is added, this is set to 0. For exports
* located in NETWORK switches:
* Each time a VNIC, i.e., intport, is added to the switch this
@@ -135,17 +135,17 @@ struct extport_info {
struct device_info {
void __iomem *chanptr;
- U64 channelAddr;
- U64 channelBytes;
+ u64 channelAddr;
+ u64 channelBytes;
uuid_le channelTypeGuid;
uuid_le devInstGuid;
struct InterruptInfo intr;
struct switch_info *swtch;
char devid[30]; /* "vbus<busno>:dev<devno>" */
- U16 polling;
+ u16 polling;
struct semaphore interrupt_callback_lock;
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
int (*interrupt)(void *);
void *interrupt_context;
void *private_data;
@@ -161,9 +161,9 @@ typedef enum {
} SWITCH_TYPE;
struct bus_info {
- U32 busNo, deviceCount;
+ u32 busNo, deviceCount;
struct device_info **device;
- U64 guestHandle, recvBusInterruptHandle;
+ u64 guestHandle, recvBusInterruptHandle;
uuid_le busInstGuid;
ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *pBusChannel;
int busChannelBytes;
@@ -172,7 +172,7 @@ struct bus_info {
char name[25];
char partitionName[99];
struct bus_info *next;
- U8 localVnic; /* 1 if local vnic created internally
+ u8 localVnic; /* 1 if local vnic created internally
* by IOVM; 0 otherwise... */
};
@@ -182,7 +182,7 @@ struct bus_info {
struct sn_list_entry {
struct uisscsi_dest pdest; /* scsi bus, target, lun for
* phys disk */
- U8 sernum[MAX_SERIAL_NUM]; /* serial num of physical
+ u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical
* disk.. The length is always
* MAX_SERIAL_NUM, padded with
* spaces */
@@ -190,12 +190,12 @@ struct sn_list_entry {
};
struct networkPolicy {
- U32 promiscuous:1;
- U32 macassign:1;
- U32 peerforwarding:1;
- U32 nonotify:1;
- U32 standby:1;
- U32 callhome:2;
+ u32 promiscuous:1;
+ u32 macassign:1;
+ u32 peerforwarding:1;
+ u32 nonotify:1;
+ u32 standby:1;
+ u32 callhome:2;
char ip_addr[30];
};
@@ -229,10 +229,10 @@ typedef enum {
struct add_virt_iopart {
void *chanptr; /* pointer to data channel */
- U64 guestHandle; /* used to convert guest physical
+ u64 guestHandle; /* used to convert guest physical
* address to real physical address
* for DMA, for ex. */
- U64 recvBusInterruptHandle; /* used to register to receive
+ u64 recvBusInterruptHandle; /* used to register to receive
* bus level interrupts. */
struct InterruptInfo intr; /* contains recv & send
* interrupt info */
@@ -247,12 +247,12 @@ struct add_virt_iopart {
* switch to which the vnic is
* connected */
- U8 useG2GCopy; /* Used to determine if a virtual HBA
+ u8 useG2GCopy; /* Used to determine if a virtual HBA
* needs to use G2G copy. */
- U8 Filler[7];
+ u8 Filler[7];
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
char *params;
ulong params_bytes;
@@ -263,23 +263,23 @@ struct add_vdisk_iopart {
int implicit;
struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */
struct uisscsi_dest pdest; /* scsi bus, target, lun for phys disk */
- U8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */
- U32 serlen; /* length of serial num */
- U32 busNo;
- U32 devNo;
+ u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */
+ u32 serlen; /* length of serial num */
+ u32 busNo;
+ u32 devNo;
};
struct del_vdisk_iopart {
void *chanptr; /* pointer to data channel */
struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
};
struct del_virt_iopart {
void *chanptr; /* pointer to data channel */
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
};
struct det_virt_iopart { /* detach internal port */
@@ -355,14 +355,14 @@ typedef enum {
struct add_vbus_guestpart {
void __iomem *chanptr; /* pointer to data channel for bus -
* NOT YET USED */
- U32 busNo; /* bus number to be created/deleted */
- U32 deviceCount; /* max num of devices on bus */
+ u32 busNo; /* bus number to be created/deleted */
+ u32 deviceCount; /* max num of devices on bus */
uuid_le busTypeGuid; /* indicates type of bus */
uuid_le busInstGuid; /* instance guid for device */
};
struct del_vbus_guestpart {
- U32 busNo; /* bus number to be deleted */
+ u32 busNo; /* bus number to be deleted */
/* once we start using the bus's channel, add can dump busNo
* into the channel header and then delete will need only one
* parameter, chanptr. */
@@ -370,8 +370,8 @@ struct del_vbus_guestpart {
struct add_virt_guestpart {
void __iomem *chanptr; /* pointer to data channel */
- U32 busNo; /* bus number for the operation */
- U32 deviceNo; /* number of device on the bus */
+ u32 busNo; /* bus number for the operation */
+ u32 deviceNo; /* number of device on the bus */
uuid_le devInstGuid; /* instance guid for device */
struct InterruptInfo intr; /* recv/send interrupt info */
/* recvInterruptHandle contains info needed in order to
@@ -395,8 +395,8 @@ struct del_virt_guestpart {
};
struct init_chipset_guestpart {
- U32 busCount; /* indicates the max number of busses */
- U32 switchCount; /* indicates the max number of switches */
+ u32 busCount; /* indicates the max number of busses */
+ u32 switchCount; /* indicates the max number of switches */
};
struct guest_msgs {
diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h
index 70776c93cc50..a1c193c5827e 100644
--- a/drivers/staging/unisys/include/uisutils.h
+++ b/drivers/staging/unisys/include/uisutils.h
@@ -60,7 +60,7 @@ typedef struct ReqHandlerInfo_struct {
unsigned long min_channel_bytes;
int (*Server_Channel_Ok)(unsigned long channelBytes);
int (*Server_Channel_Init)
- (void *x, unsigned char *clientStr, U32 clientStrLen, U64 bytes);
+ (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes);
char switch_type_name[99];
struct list_head list_link; /* links into ReqHandlerInfo_list */
} ReqHandlerInfo_t;
@@ -73,7 +73,7 @@ ReqHandlerInfo_t *ReqHandlerAdd(uuid_le switchTypeGuid,
channelBytes),
int (*Server_Channel_Init)
(void *x, unsigned char *clientStr,
- U32 clientStrLen, U64 bytes));
+ u32 clientStrLen, u64 bytes));
ReqHandlerInfo_t *ReqHandlerFind(uuid_le switchTypeGuid);
int ReqHandlerDel(uuid_le switchTypeGuid);
@@ -81,7 +81,7 @@ int ReqHandlerDel(uuid_le switchTypeGuid);
dbg_ioremap_cache(addr, size, __FILE__, __LINE__)
static inline void __iomem *
-dbg_ioremap_cache(U64 addr, unsigned long size, char *file, int line)
+dbg_ioremap_cache(u64 addr, unsigned long size, char *file, int line)
{
void __iomem *new;
new = ioremap_cache(addr, size);
@@ -91,7 +91,7 @@ dbg_ioremap_cache(U64 addr, unsigned long size, char *file, int line)
#define uislib_ioremap(addr, size) dbg_ioremap(addr, size, __FILE__, __LINE__)
static inline void *
-dbg_ioremap(U64 addr, unsigned long size, char *file, int line)
+dbg_ioremap(u64 addr, unsigned long size, char *file, int line)
{
void *new;
new = ioremap(addr, size);
@@ -121,7 +121,7 @@ int uisctrl_register_req_handler_ex(uuid_le switchTypeGuid,
channelBytes),
int (*Server_Channel_Init)
(void *x, unsigned char *clientStr,
- U32 clientStrLen, U64 bytes),
+ u32 clientStrLen, u64 bytes),
ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo);
int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid);
@@ -129,31 +129,31 @@ unsigned char *util_map_virt(struct phys_info *sg);
void util_unmap_virt(struct phys_info *sg);
unsigned char *util_map_virt_atomic(struct phys_info *sg);
void util_unmap_virt_atomic(void *buf);
-int uislib_server_inject_add_vnic(U32 switchNo, U32 BusNo, U32 numIntPorts,
- U32 numExtPorts, MACARRAY pmac[],
+int uislib_server_inject_add_vnic(u32 switchNo, u32 BusNo, u32 numIntPorts,
+ u32 numExtPorts, MACARRAY pmac[],
pCHANNEL_HEADER **chan);
-void uislib_server_inject_del_vnic(U32 switchNo, U32 busNo, U32 numIntPorts,
- U32 numExtPorts);
-int uislib_client_inject_add_bus(U32 busNo, uuid_le instGuid,
- U64 channelAddr, ulong nChannelBytes);
-int uislib_client_inject_del_bus(U32 busNo);
-
-int uislib_client_inject_add_vhba(U32 busNo, U32 devNo,
- U64 phys_chan_addr, U32 chan_bytes,
+void uislib_server_inject_del_vnic(u32 switchNo, u32 busNo, u32 numIntPorts,
+ u32 numExtPorts);
+int uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid,
+ u64 channelAddr, ulong nChannelBytes);
+int uislib_client_inject_del_bus(u32 busNo);
+
+int uislib_client_inject_add_vhba(u32 busNo, u32 devNo,
+ u64 phys_chan_addr, u32 chan_bytes,
int is_test_addr, uuid_le instGuid,
struct InterruptInfo *intr);
-int uislib_client_inject_pause_vhba(U32 busNo, U32 devNo);
-int uislib_client_inject_resume_vhba(U32 busNo, U32 devNo);
-int uislib_client_inject_del_vhba(U32 busNo, U32 devNo);
-int uislib_client_inject_add_vnic(U32 busNo, U32 devNo,
- U64 phys_chan_addr, U32 chan_bytes,
+int uislib_client_inject_pause_vhba(u32 busNo, u32 devNo);
+int uislib_client_inject_resume_vhba(u32 busNo, u32 devNo);
+int uislib_client_inject_del_vhba(u32 busNo, u32 devNo);
+int uislib_client_inject_add_vnic(u32 busNo, u32 devNo,
+ u64 phys_chan_addr, u32 chan_bytes,
int is_test_addr, uuid_le instGuid,
struct InterruptInfo *intr);
-int uislib_client_inject_pause_vnic(U32 busNo, U32 devNo);
-int uislib_client_inject_resume_vnic(U32 busNo, U32 devNo);
-int uislib_client_inject_del_vnic(U32 busNo, U32 devNo);
+int uislib_client_inject_pause_vnic(u32 busNo, u32 devNo);
+int uislib_client_inject_resume_vnic(u32 busNo, u32 devNo);
+int uislib_client_inject_del_vnic(u32 busNo, u32 devNo);
#ifdef STORAGE_CHANNEL
-U64 uislib_storage_channel(int client_id);
+u64 uislib_storage_channel(int client_id);
#endif
int uislib_get_owned_pdest(struct uisscsi_dest *pdest);
@@ -220,11 +220,11 @@ unsigned int uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx,
struct phys_info frags[]);
static inline unsigned int
-Issue_VMCALL_IO_CONTROLVM_ADDR(U64 *ControlAddress, U32 *ControlBytes)
+Issue_VMCALL_IO_CONTROLVM_ADDR(u64 *ControlAddress, u32 *ControlBytes)
{
VMCALL_IO_CONTROLVM_ADDR_PARAMS params;
int result = VMCALL_SUCCESS;
- U64 physaddr;
+ u64 physaddr;
physaddr = virt_to_phys(&params);
ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR, physaddr, result);
@@ -235,11 +235,11 @@ Issue_VMCALL_IO_CONTROLVM_ADDR(U64 *ControlAddress, U32 *ControlBytes)
return result;
}
-static inline unsigned int Issue_VMCALL_IO_DIAG_ADDR(U64 *DiagChannelAddress)
+static inline unsigned int Issue_VMCALL_IO_DIAG_ADDR(u64 *DiagChannelAddress)
{
VMCALL_IO_DIAG_ADDR_PARAMS params;
int result = VMCALL_SUCCESS;
- U64 physaddr;
+ u64 physaddr;
physaddr = virt_to_phys(&params);
ISSUE_IO_VMCALL(VMCALL_IO_DIAG_ADDR, physaddr, result);
@@ -249,11 +249,11 @@ static inline unsigned int Issue_VMCALL_IO_DIAG_ADDR(U64 *DiagChannelAddress)
}
static inline unsigned int
-Issue_VMCALL_IO_VISORSERIAL_ADDR(U64 *DiagChannelAddress)
+Issue_VMCALL_IO_VISORSERIAL_ADDR(u64 *DiagChannelAddress)
{
VMCALL_IO_VISORSERIAL_ADDR_PARAMS params;
int result = VMCALL_SUCCESS;
- U64 physaddr;
+ u64 physaddr;
physaddr = virt_to_phys(&params);
ISSUE_IO_VMCALL(VMCALL_IO_VISORSERIAL_ADDR, physaddr, result);
@@ -262,20 +262,20 @@ Issue_VMCALL_IO_VISORSERIAL_ADDR(U64 *DiagChannelAddress)
return result;
}
-static inline S64 Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET(void)
+static inline s64 Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET(void)
{
- U64 result = VMCALL_SUCCESS;
- U64 physaddr = 0;
+ u64 result = VMCALL_SUCCESS;
+ u64 physaddr = 0;
ISSUE_IO_VMCALL(VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET, physaddr,
result);
return result;
}
-static inline S64 Issue_VMCALL_MEASUREMENT_DO_NOTHING(void)
+static inline s64 Issue_VMCALL_MEASUREMENT_DO_NOTHING(void)
{
- U64 result = VMCALL_SUCCESS;
- U64 physaddr = 0;
+ u64 result = VMCALL_SUCCESS;
+ u64 physaddr = 0;
ISSUE_IO_VMCALL(VMCALL_MEASUREMENT_DO_NOTHING, physaddr, result);
return result;
@@ -289,7 +289,7 @@ struct log_info_t {
unsigned long long min_delta[64];
};
-static inline int Issue_VMCALL_UPDATE_PHYSICAL_TIME(U64 adjustment)
+static inline int Issue_VMCALL_UPDATE_PHYSICAL_TIME(u64 adjustment)
{
int result = VMCALL_SUCCESS;
@@ -300,27 +300,27 @@ static inline int Issue_VMCALL_UPDATE_PHYSICAL_TIME(U64 adjustment)
static inline unsigned int
Issue_VMCALL_CHANNEL_MISMATCH(const char *ChannelName,
const char *ItemName,
- U32 SourceLineNumber, const char *path_n_fn)
+ u32 SourceLineNumber, const char *path_n_fn)
{
VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS params;
int result = VMCALL_SUCCESS;
- U64 physaddr;
+ u64 physaddr;
char *last_slash = NULL;
- strncpy(params.ChannelName, ChannelName,
+ strlcpy(params.ChannelName, ChannelName,
lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ChannelName));
- strncpy(params.ItemName, ItemName,
+ strlcpy(params.ItemName, ItemName,
lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS, ItemName));
params.SourceLineNumber = SourceLineNumber;
last_slash = strrchr(path_n_fn, '/');
if (last_slash != NULL) {
last_slash++;
- strncpy(params.SourceFileName, last_slash,
+ strlcpy(params.SourceFileName, last_slash,
lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS,
SourceFileName));
} else
- strncpy(params.SourceFileName,
+ strlcpy(params.SourceFileName,
"Cannot determine source filename",
lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS,
SourceFileName));
@@ -333,7 +333,7 @@ Issue_VMCALL_CHANNEL_MISMATCH(const char *ChannelName,
static inline unsigned int Issue_VMCALL_FATAL_BYE_BYE(void)
{
int result = VMCALL_SUCCESS;
- U64 physaddr = 0;
+ u64 physaddr = 0;
ISSUE_IO_VMCALL(VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER, physaddr,
result);
@@ -347,10 +347,10 @@ void uislib_cache_free(struct kmem_cache *cur_pool, void *p, char *fn, int ln);
#define UISCACHEFREE(cur_pool, p) \
uislib_cache_free(cur_pool, p, __FILE__, __LINE__)
-void uislib_enable_channel_interrupts(U32 busNo, U32 devNo,
+void uislib_enable_channel_interrupts(u32 busNo, u32 devNo,
int (*interrupt)(void *),
void *interrupt_context);
-void uislib_disable_channel_interrupts(U32 busNo, U32 devNo);
-void uislib_force_channel_interrupt(U32 busNo, U32 devNo);
+void uislib_disable_channel_interrupts(u32 busNo, u32 devNo);
+void uislib_force_channel_interrupt(u32 busNo, u32 devNo);
#endif /* __UISUTILS__H__ */
diff --git a/drivers/staging/unisys/include/vbushelper.h b/drivers/staging/unisys/include/vbushelper.h
index 93e35f039ded..ed943759634a 100644
--- a/drivers/staging/unisys/include/vbushelper.h
+++ b/drivers/staging/unisys/include/vbushelper.h
@@ -28,8 +28,7 @@
static inline void
BusDeviceInfo_Init(ULTRA_VBUS_DEVICEINFO *pBusDeviceInfo,
const char *deviceType, const char *driverName,
- const char *ver, const char *verTag,
- const char *buildDate, const char *buildTime)
+ const char *ver, const char *verTag)
{
memset(pBusDeviceInfo, 0, sizeof(ULTRA_VBUS_DEVICEINFO));
snprintf(pBusDeviceInfo->devType, sizeof(pBusDeviceInfo->devType),
@@ -37,11 +36,10 @@ BusDeviceInfo_Init(ULTRA_VBUS_DEVICEINFO *pBusDeviceInfo,
snprintf(pBusDeviceInfo->drvName, sizeof(pBusDeviceInfo->drvName),
"%s", (driverName) ? driverName : "unknownDriver");
snprintf(pBusDeviceInfo->infoStrings,
- sizeof(pBusDeviceInfo->infoStrings), "%s\t%s\t%s %s\t%s",
+ sizeof(pBusDeviceInfo->infoStrings), "%s\t%s\t%s",
(ver) ? ver : "unknownVer",
(verTag) ? verTag : "unknownVerTag",
- (buildDate) ? buildDate : "noBuildDate",
- (buildTime) ? buildTime : "nobuildTime", TARGET_HOSTNAME);
+ TARGET_HOSTNAME);
}
#endif
diff --git a/drivers/staging/unisys/uislib/Makefile b/drivers/staging/unisys/uislib/Makefile
index 6e44d49458f5..08e620d17497 100644
--- a/drivers/staging/unisys/uislib/Makefile
+++ b/drivers/staging/unisys/uislib/Makefile
@@ -12,6 +12,3 @@ ccflags-y += -Idrivers/staging/unisys/visorchipset
ccflags-y += -Idrivers/staging/unisys/sparstopdriver
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
-
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c
index d4a7ef821bae..63c91cd6fdcc 100644
--- a/drivers/staging/unisys/uislib/uislib.c
+++ b/drivers/staging/unisys/uislib/uislib.c
@@ -74,7 +74,7 @@ static struct bus_info *BusListHead;
static rwlock_t BusListLock;
static int BusListCount; /* number of buses in the list */
static int MaxBusCount; /* maximum number of buses expected */
-static U64 PhysicalDataChan;
+static u64 PhysicalDataChan;
static int PlatformNumber;
static struct uisthread_info Incoming_ThreadInfo;
@@ -120,7 +120,7 @@ static const struct file_operations debugfs_info_fops = {
};
static void
-init_msg_header(CONTROLVM_MESSAGE *msg, U32 id, uint rsp, uint svr)
+init_msg_header(CONTROLVM_MESSAGE *msg, u32 id, uint rsp, uint svr)
{
memset(msg, 0, sizeof(CONTROLVM_MESSAGE));
msg->hdr.Id = id;
@@ -129,7 +129,7 @@ init_msg_header(CONTROLVM_MESSAGE *msg, U32 id, uint rsp, uint svr)
}
static __iomem void *
-init_vbus_channel(U64 channelAddr, U32 channelBytes, int isServer)
+init_vbus_channel(u64 channelAddr, u32 channelBytes)
{
void __iomem *rc = NULL;
void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
@@ -140,22 +140,11 @@ init_vbus_channel(U64 channelAddr, U32 channelBytes, int isServer)
rc = NULL;
goto Away;
}
- if (isServer) {
- memset_io(pChan, 0, channelBytes);
- if (!ULTRA_VBUS_CHANNEL_OK_SERVER(channelBytes, NULL)) {
- ERRDRV("%s channel cannot be used", __func__);
- uislib_iounmap(pChan);
- rc = NULL;
- goto Away;
- }
- ULTRA_VBUS_init_channel(pChan, channelBytes);
- } else {
- if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) {
- ERRDRV("%s channel cannot be used", __func__);
- uislib_iounmap(pChan);
- rc = NULL;
- goto Away;
- }
+ if (!ULTRA_VBUS_CHANNEL_OK_CLIENT(pChan, NULL)) {
+ ERRDRV("%s channel cannot be used", __func__);
+ uislib_iounmap(pChan);
+ rc = NULL;
+ goto Away;
}
rc = pChan;
Away:
@@ -165,7 +154,7 @@ Away:
static int
create_bus(CONTROLVM_MESSAGE *msg, char *buf)
{
- U32 busNo, deviceCount;
+ u32 busNo, deviceCount;
struct bus_info *tmp, *bus;
size_t size;
@@ -235,8 +224,7 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf)
bus->busChannelBytes = msg->cmd.createBus.channelBytes;
bus->pBusChannel =
init_vbus_channel(msg->cmd.createBus.channelAddr,
- msg->cmd.createBus.channelBytes,
- msg->hdr.Flags.server);
+ msg->cmd.createBus.channelBytes);
}
/* the msg is bound for virtpci; send guest_msgs struct to callback */
if (!msg->hdr.Flags.server) {
@@ -285,7 +273,7 @@ destroy_bus(CONTROLVM_MESSAGE *msg, char *buf)
{
int i;
struct bus_info *bus, *prev = NULL;
- U32 busNo;
+ u32 busNo;
busNo = msg->cmd.destroyBus.busNo;
@@ -353,9 +341,9 @@ create_device(CONTROLVM_MESSAGE *msg, char *buf)
{
struct device_info *dev;
struct bus_info *bus;
- U32 busNo, devNo;
+ u32 busNo, devNo;
int result = CONTROLVM_RESP_SUCCESS;
- U64 minSize = MIN_IO_CHANNEL_SIZE;
+ u64 minSize = MIN_IO_CHANNEL_SIZE;
ReqHandlerInfo_t *pReqHandler;
busNo = msg->cmd.createDevice.busNo;
@@ -547,7 +535,7 @@ Away:
static int
pause_device(CONTROLVM_MESSAGE *msg)
{
- U32 busNo, devNo;
+ u32 busNo, devNo;
struct bus_info *bus;
struct device_info *dev;
struct guest_msgs cmd;
@@ -619,7 +607,7 @@ pause_device(CONTROLVM_MESSAGE *msg)
static int
resume_device(CONTROLVM_MESSAGE *msg)
{
- U32 busNo, devNo;
+ u32 busNo, devNo;
struct bus_info *bus;
struct device_info *dev;
struct guest_msgs cmd;
@@ -691,7 +679,7 @@ resume_device(CONTROLVM_MESSAGE *msg)
static int
destroy_device(CONTROLVM_MESSAGE *msg, char *buf)
{
- U32 busNo, devNo;
+ u32 busNo, devNo;
struct bus_info *bus;
struct device_info *dev;
struct guest_msgs cmd;
@@ -803,7 +791,7 @@ init_chipset(CONTROLVM_MESSAGE *msg, char *buf)
}
static int
-delete_bus_glue(U32 busNo)
+delete_bus_glue(u32 busNo)
{
CONTROLVM_MESSAGE msg;
@@ -817,7 +805,7 @@ delete_bus_glue(U32 busNo)
}
static int
-delete_device_glue(U32 busNo, U32 devNo)
+delete_device_glue(u32 busNo, u32 devNo)
{
CONTROLVM_MESSAGE msg;
@@ -833,8 +821,8 @@ delete_device_glue(U32 busNo, U32 devNo)
}
int
-uislib_client_inject_add_bus(U32 busNo, uuid_le instGuid,
- U64 channelAddr, ulong nChannelBytes)
+uislib_client_inject_add_bus(u32 busNo, uuid_le instGuid,
+ u64 channelAddr, ulong nChannelBytes)
{
CONTROLVM_MESSAGE msg;
@@ -884,14 +872,14 @@ EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
int
-uislib_client_inject_del_bus(U32 busNo)
+uislib_client_inject_del_bus(u32 busNo)
{
return delete_bus_glue(busNo);
}
EXPORT_SYMBOL_GPL(uislib_client_inject_del_bus);
int
-uislib_client_inject_pause_vhba(U32 busNo, U32 devNo)
+uislib_client_inject_pause_vhba(u32 busNo, u32 devNo)
{
CONTROLVM_MESSAGE msg;
int rc;
@@ -911,7 +899,7 @@ uislib_client_inject_pause_vhba(U32 busNo, U32 devNo)
EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vhba);
int
-uislib_client_inject_resume_vhba(U32 busNo, U32 devNo)
+uislib_client_inject_resume_vhba(u32 busNo, u32 devNo)
{
CONTROLVM_MESSAGE msg;
int rc;
@@ -932,8 +920,8 @@ uislib_client_inject_resume_vhba(U32 busNo, U32 devNo)
EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
int
-uislib_client_inject_add_vhba(U32 busNo, U32 devNo,
- U64 phys_chan_addr, U32 chan_bytes,
+uislib_client_inject_add_vhba(u32 busNo, u32 devNo,
+ u64 phys_chan_addr, u32 chan_bytes,
int is_test_addr, uuid_le instGuid,
struct InterruptInfo *intr)
{
@@ -984,15 +972,15 @@ uislib_client_inject_add_vhba(U32 busNo, U32 devNo,
EXPORT_SYMBOL_GPL(uislib_client_inject_add_vhba);
int
-uislib_client_inject_del_vhba(U32 busNo, U32 devNo)
+uislib_client_inject_del_vhba(u32 busNo, u32 devNo)
{
return delete_device_glue(busNo, devNo);
}
EXPORT_SYMBOL_GPL(uislib_client_inject_del_vhba);
int
-uislib_client_inject_add_vnic(U32 busNo, U32 devNo,
- U64 phys_chan_addr, U32 chan_bytes,
+uislib_client_inject_add_vnic(u32 busNo, u32 devNo,
+ u64 phys_chan_addr, u32 chan_bytes,
int is_test_addr, uuid_le instGuid,
struct InterruptInfo *intr)
{
@@ -1044,7 +1032,7 @@ uislib_client_inject_add_vnic(U32 busNo, U32 devNo,
EXPORT_SYMBOL_GPL(uislib_client_inject_add_vnic);
int
-uislib_client_inject_pause_vnic(U32 busNo, U32 devNo)
+uislib_client_inject_pause_vnic(u32 busNo, u32 devNo)
{
CONTROLVM_MESSAGE msg;
int rc;
@@ -1064,7 +1052,7 @@ uislib_client_inject_pause_vnic(U32 busNo, U32 devNo)
EXPORT_SYMBOL_GPL(uislib_client_inject_pause_vnic);
int
-uislib_client_inject_resume_vnic(U32 busNo, U32 devNo)
+uislib_client_inject_resume_vnic(u32 busNo, u32 devNo)
{
CONTROLVM_MESSAGE msg;
int rc;
@@ -1085,14 +1073,14 @@ uislib_client_inject_resume_vnic(U32 busNo, U32 devNo)
EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
int
-uislib_client_inject_del_vnic(U32 busNo, U32 devNo)
+uislib_client_inject_del_vnic(u32 busNo, u32 devNo)
{
return delete_device_glue(busNo, devNo);
}
EXPORT_SYMBOL_GPL(uislib_client_inject_del_vnic);
static int
-uislib_client_add_vnic(U32 busNo)
+uislib_client_add_vnic(u32 busNo)
{
BOOL busCreated = FALSE;
int devNo = 0; /* Default to 0, since only one device
@@ -1141,7 +1129,7 @@ AwayCleanup:
EXPORT_SYMBOL_GPL(uislib_client_add_vnic);
static int
-uislib_client_delete_vnic(U32 busNo)
+uislib_client_delete_vnic(u32 busNo)
{
int devNo = 0; /* Default to 0, since only one device
* will be created for this bus... */
@@ -1297,7 +1285,7 @@ info_debugfs_read(struct file *file, char __user *buf,
}
static struct device_info *
-find_dev(U32 busNo, U32 devNo)
+find_dev(u32 busNo, u32 devNo)
{
struct bus_info *bus;
struct device_info *dev = NULL;
@@ -1470,7 +1458,7 @@ Initialize_incoming_thread(void)
* function.
*/
void
-uislib_enable_channel_interrupts(U32 busNo, U32 devNo,
+uislib_enable_channel_interrupts(u32 busNo, u32 devNo,
int (*interrupt)(void *),
void *interrupt_context)
{
@@ -1496,7 +1484,7 @@ EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
* Process_Incoming().
*/
void
-uislib_disable_channel_interrupts(U32 busNo, U32 devNo)
+uislib_disable_channel_interrupts(u32 busNo, u32 devNo)
{
struct device_info *dev;
dev = find_dev(busNo, devNo);
@@ -1529,7 +1517,7 @@ static DECLARE_WORK(Work_wakeup_polling_device_channels,
* your device might have more requests.
*/
void
-uislib_force_channel_interrupt(U32 busNo, U32 devNo)
+uislib_force_channel_interrupt(u32 busNo, u32 devNo)
{
if (en_smart_wakeup == 0)
return;
diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c
index d4a6074cfaf0..84eafca5e45c 100644
--- a/drivers/staging/unisys/uislib/uisqueue.c
+++ b/drivers/staging/unisys/uislib/uisqueue.c
@@ -71,19 +71,19 @@ uisqueue_InterlockedAnd(unsigned long long __iomem *Target,
}
EXPORT_SYMBOL_GPL(uisqueue_InterlockedAnd);
-static U8
+static u8
do_locked_client_insert(struct uisqueue_info *queueinfo,
unsigned int whichqueue,
void *pSignal,
spinlock_t *lock,
unsigned char issueInterruptIfEmpty,
- U64 interruptHandle, U8 *channelId)
+ u64 interruptHandle, u8 *channelId)
{
unsigned long flags;
unsigned char queueWasEmpty;
unsigned int locked = 0;
unsigned int acquired = 0;
- U8 rc = 0;
+ u8 rc = 0;
spin_lock_irqsave(lock, flags);
locked = 1;
@@ -124,8 +124,8 @@ uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
unsigned int whichqueue,
void *insertlock,
unsigned char issueInterruptIfEmpty,
- U64 interruptHandle,
- char oktowait, U8 *channelId)
+ u64 interruptHandle,
+ char oktowait, u8 *channelId)
{
while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp,
(spinlock_t *) insertlock,
diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c
index 0f1bb739975e..ee26e009b400 100644
--- a/drivers/staging/unisys/uislib/uisutils.c
+++ b/drivers/staging/unisys/uislib/uisutils.c
@@ -96,9 +96,8 @@ uisctrl_register_req_handler(int type, void *fptr,
return 0;
}
if (chipset_DriverInfo)
- BusDeviceInfo_Init(chipset_DriverInfo,
- "chipset", "uislib",
- VERSION, NULL, __DATE__, __TIME__);
+ BusDeviceInfo_Init(chipset_DriverInfo, "chipset", "uislib",
+ VERSION, NULL);
return 1;
}
@@ -113,7 +112,7 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid,
channelBytes),
int (*Server_Channel_Init)
(void *x, unsigned char *clientStr,
- U32 clientStrLen, U64 bytes),
+ u32 clientStrLen, u64 bytes),
ULTRA_VBUS_DEVICEINFO *chipset_DriverInfo)
{
ReqHandlerInfo_t *pReqHandlerInfo;
@@ -149,10 +148,8 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid,
Away:
if (rc) {
if (chipset_DriverInfo)
- BusDeviceInfo_Init(chipset_DriverInfo,
- "chipset", "uislib",
- VERSION, NULL,
- __DATE__, __TIME__);
+ BusDeviceInfo_Init(chipset_DriverInfo, "chipset",
+ "uislib", VERSION, NULL);
} else
LOGERR("failed to register type %pUL.\n", &switchTypeGuid);
@@ -282,7 +279,7 @@ ReqHandlerAdd(uuid_le switchTypeGuid,
unsigned long min_channel_bytes,
int (*Server_Channel_Ok)(unsigned long channelBytes),
int (*Server_Channel_Init)
- (void *x, unsigned char *clientStr, U32 clientStrLen, U64 bytes))
+ (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes))
{
ReqHandlerInfo_t *rc = NULL;
diff --git a/drivers/staging/unisys/virthba/Makefile b/drivers/staging/unisys/virthba/Makefile
index 632b1c08b975..ba55ae12488e 100644
--- a/drivers/staging/unisys/virthba/Makefile
+++ b/drivers/staging/unisys/virthba/Makefile
@@ -11,6 +11,3 @@ ccflags-y += -Idrivers/staging/unisys/visorchipset
ccflags-y += -Idrivers/staging/unisys/virtpci
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
-
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c
index 5c5aa7001767..049eeab08bac 100644
--- a/drivers/staging/unisys/virthba/virthba.c
+++ b/drivers/staging/unisys/virthba/virthba.c
@@ -50,7 +50,7 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <asm/param.h>
-#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include <linux/types.h>
#include "virthba.h"
@@ -67,6 +67,11 @@
/* NOTE: L1_CACHE_BYTES >=128 */
#define DEVICE_ATTRIBUTE struct device_attribute
+ /* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters
+ * = 4800 bytes ~ 2^13 = 8192 bytes
+ */
+#define MAX_BUF 8192
+
/*****************************************************/
/* Forward declarations */
/*****************************************************/
@@ -105,15 +110,10 @@ static int virthba_serverup(struct virtpci_dev *virtpcidev);
static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
static void doDiskAddRemove(struct work_struct *work);
static void virthba_serverdown_complete(struct work_struct *work);
-
-static ssize_t info_proc_read(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t rqwu_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos);
-static ssize_t enable_ints_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos);
-static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos);
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset);
+static ssize_t enable_ints_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos);
/*****************************************************/
/* Globals */
@@ -139,8 +139,6 @@ static struct virtpci_driver virthba_driver = {
.name = "uisvirthba",
.version = VERSION,
.vertag = NULL,
- .build_date = __DATE__,
- .build_time = __TIME__,
.id_table = virthba_id_table,
.probe = virthba_probe,
.remove = virthba_remove,
@@ -162,8 +160,8 @@ struct scsipending {
#define VIRTHBA_ERROR_COUNT 30
#define IOS_ERROR_THRESHOLD 1000
struct virtdisk_info {
- U32 valid;
- U32 channel, id, lun; /* Disk Path */
+ u32 valid;
+ u32 channel, id, lun; /* Disk Path */
atomic_t ios_threshold;
atomic_t error_count;
struct virtdisk_info *next;
@@ -190,7 +188,7 @@ struct virthba_info {
unsigned long long interrupts_notme;
unsigned long long interrupts_disabled;
struct work_struct serverdown_completion;
- U64 __iomem *flags_addr;
+ u64 __iomem *flags_addr;
atomic_t interrupt_rcvd;
wait_queue_head_t rsp_queue;
struct virtdisk_info head;
@@ -198,9 +196,9 @@ struct virthba_info {
/* Work Data for DARWorkQ */
struct diskaddremove {
- U8 add; /* 0-remove, 1-add */
+ u8 add; /* 0-remove, 1-add */
struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
- U32 channel, id, lun; /* Disk Path */
+ u32 channel, id, lun; /* Disk Path */
struct diskaddremove *next;
};
@@ -210,7 +208,6 @@ struct diskaddremove {
static DEVICE_ATTRIBUTE *virthba_shost_attrs[];
static struct scsi_host_template virthba_driver_template = {
.name = "Unisys Virtual HBA",
- .proc_name = "uisvirthba",
.info = virthba_get_info,
.ioctl = virthba_ioctl,
.queuecommand = virthba_queue_command,
@@ -234,31 +231,22 @@ struct virthba_devices_open {
struct virthba_info *virthbainfo;
};
-static const struct file_operations proc_info_fops = {
- .read = info_proc_read,
+static const struct file_operations debugfs_info_fops = {
+ .read = info_debugfs_read,
};
-static const struct file_operations proc_rqwu_fops = {
- .write = rqwu_proc_write,
-};
-
-static const struct file_operations proc_enable_ints_fops = {
- .read = enable_ints_read,
+static const struct file_operations debugfs_enable_ints_fops = {
.write = enable_ints_write,
};
+/*****************************************************/
+/* Structs */
+/*****************************************************/
#define VIRTHBASOPENMAX 1
/* array of open devices maintained by open() and close(); */
static struct virthba_devices_open VirtHbasOpen[VIRTHBASOPENMAX];
-static struct proc_dir_entry *virthba_proc_dir;
-static struct proc_dir_entry *info_proc_entry;
-static struct proc_dir_entry *rqwaitus_proc_entry;
-static struct proc_dir_entry *enable_ints_proc_entry;
-#define INFO_PROC_ENTRY_FN "info"
-#define ENABLE_INTS_ENTRY_FN "enable_ints"
-#define RQWU_PROC_ENTRY_FN "rqwait_usecs"
-#define DIR_PROC_ENTRY "virthba"
+static struct dentry *virthba_debugfs_dir;
/*****************************************************/
/* Local Functions */
@@ -434,7 +422,7 @@ virthba_ISR(int irq, void *dev_id)
struct virthba_info *virthbainfo = (struct virthba_info *) dev_id;
CHANNEL_HEADER __iomem *pChannelHeader;
SIGNAL_QUEUE_HEADER __iomem *pqhdr;
- U64 mask;
+ u64 mask;
unsigned long long rc1;
if (virthbainfo == NULL)
@@ -475,7 +463,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
irq_handler_t handler = virthba_ISR;
CHANNEL_HEADER __iomem *pChannelHeader;
SIGNAL_QUEUE_HEADER __iomem *pqhdr;
- U64 mask;
+ u64 mask;
LOGVER("entering virthba_probe...\n");
LOGVER("virtpcidev busNo<<%d>>devNo<<%d>>", virtpcidev->busNo,
@@ -633,7 +621,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
virthbainfo->interrupt_vector = -1;
POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
} else {
- U64 __iomem *Features_addr =
+ u64 __iomem *Features_addr =
&virthbainfo->chinfo.queueinfo->chan->Features;
LOGERR("request_irq(%d) uislib_virthba_ISR request succeeded\n",
virthbainfo->interrupt_vector);
@@ -735,7 +723,7 @@ forward_vdiskmgmt_command(VDISK_MGMT_TYPES vdiskcmdtype,
uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
cmdrsp, IOCHAN_TO_IOPART,
&virthbainfo->chinfo.insertlock,
- DONT_ISSUE_INTERRUPT, (U64) NULL,
+ DONT_ISSUE_INTERRUPT, (u64) NULL,
OK_TO_WAIT, "vhba");
LOGINF("VdiskMgmt waiting on event notifyevent=0x%p\n",
cmdrsp->scsitaskmgmt.notify);
@@ -796,7 +784,7 @@ forward_taskmgmt_command(TASK_MGMT_TYPES tasktype, struct scsi_device *scsidev)
uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
cmdrsp, IOCHAN_TO_IOPART,
&virthbainfo->chinfo.insertlock,
- DONT_ISSUE_INTERRUPT, (U64) NULL,
+ DONT_ISSUE_INTERRUPT, (u64) NULL,
OK_TO_WAIT, "vhba");
LOGINF("TaskMgmt waiting on event notifyevent=0x%p\n",
cmdrsp->scsitaskmgmt.notify);
@@ -1034,7 +1022,7 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
&virthbainfo->chinfo.
insertlock,
DONT_ISSUE_INTERRUPT,
- (U64) NULL, DONT_WAIT, "vhba");
+ (u64) NULL, DONT_WAIT, "vhba");
if (i == 0) {
/* queue must be full - and we said don't wait - return busy */
LOGERR("uisqueue_put_cmdrsp_with_lock ****FAILED\n");
@@ -1347,7 +1335,7 @@ process_incoming_rsps(void *v)
struct chaninfo *dc = &virthbainfo->chinfo;
struct uiscmdrsp *cmdrsp = NULL;
const int SZ = sizeof(struct uiscmdrsp);
- U64 mask;
+ u64 mask;
unsigned long long rc1;
UIS_DAEMONIZE("vhba_incoming");
@@ -1378,25 +1366,21 @@ process_incoming_rsps(void *v)
}
/*****************************************************/
-/* proc filesystem functions */
+/* Debugfs filesystem functions */
/*****************************************************/
-static ssize_t
-info_proc_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
+static ssize_t info_debugfs_read(struct file *file,
+ char __user *buf, size_t len, loff_t *offset)
{
- int length = 0;
- U64 phys_flags_addr;
+ ssize_t bytes_read = 0;
+ int str_pos = 0;
+ u64 phys_flags_addr;
int i;
struct virthba_info *virthbainfo;
char *vbuf;
- loff_t pos = *offset;
-
- if (pos < 0)
- return -EINVAL;
-
- if (pos > 0 || !len)
- return 0;
+ if (len > MAX_BUF)
+ len = MAX_BUF;
vbuf = kzalloc(len, GFP_KERNEL);
if (!vbuf)
return -ENOMEM;
@@ -1406,56 +1390,46 @@ info_proc_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
continue;
virthbainfo = VirtHbasOpen[i].virthbainfo;
- length += sprintf(vbuf + length, "CHANSOCK is not defined.\n");
- length += sprintf(vbuf + length, "MaxBuffLen:%u\n", MaxBuffLen);
-
- length += sprintf(vbuf + length, "\nvirthba result queue poll wait:%d usecs.\n",
- rsltq_wait_usecs);
-
- length += sprintf(vbuf + length,
- "\nModule build: Date:%s Time:%s\n",
- __DATE__, __TIME__);
- length += sprintf(vbuf + length, "\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n",
- virthbainfo->interrupts_rcvd,
- virthbainfo->interrupts_disabled);
- length += sprintf(vbuf + length, "\ninterrupts_notme = %llu,\n",
- virthbainfo->interrupts_notme);
+ str_pos += scnprintf(vbuf + str_pos,
+ len - str_pos, "MaxBuffLen:%u\n", MaxBuffLen);
+
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "\nvirthba result queue poll wait:%d usecs.\n",
+ rsltq_wait_usecs);
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n",
+ virthbainfo->interrupts_rcvd,
+ virthbainfo->interrupts_disabled);
+ str_pos += scnprintf(vbuf + str_pos,
+ len - str_pos, "\ninterrupts_notme = %llu,\n",
+ virthbainfo->interrupts_notme);
phys_flags_addr = virt_to_phys((__force void *)
virthbainfo->flags_addr);
- length += sprintf(vbuf + length, "flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n",
- virthbainfo->flags_addr, phys_flags_addr,
- (__le64)readq(virthbainfo->flags_addr));
- length += sprintf(vbuf + length, "acquire_failed_cnt:%llu\n",
- virthbainfo->acquire_failed_cnt);
- length += sprintf(vbuf + length, "\n");
- }
- if (copy_to_user(buf, vbuf, length)) {
- kfree(vbuf);
- return -EFAULT;
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n",
+ virthbainfo->flags_addr, phys_flags_addr,
+ (__le64)readq(virthbainfo->flags_addr));
+ str_pos += scnprintf(vbuf + str_pos,
+ len - str_pos, "acquire_failed_cnt:%llu\n",
+ virthbainfo->acquire_failed_cnt);
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n");
}
+ bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
kfree(vbuf);
- *offset += length;
- return length;
-}
-
-static ssize_t
-enable_ints_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- return 0;
+ return bytes_read;
}
-static ssize_t
-enable_ints_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t enable_ints_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *ppos)
{
char buf[4];
int i, new_value;
struct virthba_info *virthbainfo;
- U64 __iomem *Features_addr;
- U64 mask;
+
+ u64 __iomem *Features_addr;
+ u64 mask;
if (count >= ARRAY_SIZE(buf))
return -EINVAL;
@@ -1467,9 +1441,9 @@ enable_ints_write(struct file *file, const char __user *buffer,
return -EFAULT;
}
- i = sscanf(buf, "%d", &new_value);
+ i = kstrtoint(buf, 10 , &new_value);
- if (i < 1) {
+ if (i != 0) {
LOGERR("Failed to scan value for enable_ints, buf<<%.*s>>",
(int) count, buf);
return -EFAULT;
@@ -1501,35 +1475,6 @@ enable_ints_write(struct file *file, const char __user *buffer,
return count;
}
-static ssize_t
-rqwu_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char buf[16];
- int i, usecs;
-
- if (count >= ARRAY_SIZE(buf))
- return -EINVAL;
-
- if (copy_from_user(buf, buffer, count)) {
- LOGERR("copy_from_user failed. buf<<%.*s>> count<<%lu>>\n",
- (int) count, buf, count);
- return -EFAULT;
- }
-
- i = sscanf(buf, "%d", &usecs);
-
- if (i < 1) {
- LOGERR("Failed to scan value for rqwait_usecs buf<<%.*s>>",
- (int) count, buf);
- return -EFAULT;
- }
-
- /* set global wait time */
- rsltq_wait_usecs = usecs;
- return count;
-}
-
/* As per VirtpciFunc returns 1 for success and 0 for failure */
static int
virthba_serverup(struct virtpci_dev *virtpcidev)
@@ -1713,18 +1658,16 @@ virthba_mod_init(void)
POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
POSTCODE_SEVERITY_ERR);
} else {
- /* create the proc directories */
- virthba_proc_dir = proc_mkdir(DIR_PROC_ENTRY, NULL);
- info_proc_entry = proc_create(INFO_PROC_ENTRY_FN, 0,
- virthba_proc_dir,
- &proc_info_fops);
- rqwaitus_proc_entry = proc_create(RQWU_PROC_ENTRY_FN, 0,
- virthba_proc_dir,
- &proc_rqwu_fops);
- enable_ints_proc_entry = proc_create(ENABLE_INTS_ENTRY_FN, 0,
- virthba_proc_dir,
- &proc_enable_ints_fops);
+ /* create the debugfs directories and entries */
+ virthba_debugfs_dir = debugfs_create_dir("virthba", NULL);
+ debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir,
+ NULL, &debugfs_info_fops);
+ debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
+ virthba_debugfs_dir, &rsltq_wait_usecs);
+ debugfs_create_file("enable_ints", S_IWUSR,
+ virthba_debugfs_dir, NULL,
+ &debugfs_enable_ints_fops);
/* Initialize DARWorkQ */
INIT_WORK(&DARWorkQ, doDiskAddRemove);
spin_lock_init(&DARWorkQLock);
@@ -1804,18 +1747,7 @@ virthba_mod_exit(void)
virthba_serverdown_workqueue = NULL;
}
- if (info_proc_entry)
- remove_proc_entry(INFO_PROC_ENTRY_FN, virthba_proc_dir);
-
- if (rqwaitus_proc_entry)
- remove_proc_entry(RQWU_PROC_ENTRY_FN, NULL);
-
- if (enable_ints_proc_entry)
- remove_proc_entry(ENABLE_INTS_ENTRY_FN, NULL);
-
- if (virthba_proc_dir)
- remove_proc_entry(DIR_PROC_ENTRY, NULL);
-
+ debugfs_remove_recursive(virthba_debugfs_dir);
LOGINF("Leaving virthba_mod_exit\n");
}
diff --git a/drivers/staging/unisys/virtpci/Makefile b/drivers/staging/unisys/virtpci/Makefile
index f9399aabddd1..a26c696219a5 100644
--- a/drivers/staging/unisys/virtpci/Makefile
+++ b/drivers/staging/unisys/virtpci/Makefile
@@ -8,6 +8,3 @@ ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/uislib
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
-
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c
index 71246feb154f..d9443a968ddf 100644
--- a/drivers/staging/unisys/virtpci/virtpci.c
+++ b/drivers/staging/unisys/virtpci/virtpci.c
@@ -34,9 +34,9 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
-#include <linux/proc_fs.h>
#include <linux/if_ether.h>
#include <linux/version.h>
+#include <linux/debugfs.h>
#include "version.h"
#include "guestlinuxdebug.h"
#include "timskmodutils.h"
@@ -59,6 +59,11 @@ struct driver_private {
#define BUS_ID(x) dev_name(x)
+/* MAX_BUF = 4 busses x ( 32 devices/bus + 1 busline) x 80 characters
+ * = 10,560 bytes ~ 2^14 = 16,384 bytes
+ */
+#define MAX_BUF 16384
+
#include "virtpci.h"
/* this is shorter than using __FILE__ (full path name) in
@@ -100,17 +105,12 @@ static int virtpci_device_suspend(struct device *dev, pm_message_t state);
static int virtpci_device_resume(struct device *dev);
static int virtpci_device_probe(struct device *dev);
static int virtpci_device_remove(struct device *dev);
-static ssize_t virt_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos);
-static ssize_t info_proc_read(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static const struct file_operations proc_virt_fops = {
- .write = virt_proc_write,
-};
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset);
-static const struct file_operations proc_info_fops = {
- .read = info_proc_read,
+static const struct file_operations debugfs_info_fops = {
+ .read = info_debugfs_read,
};
/*****************************************************/
@@ -152,19 +152,13 @@ static DEFINE_RWLOCK(VpcidevListLock);
/* filled in with info about this driver, wrt it servicing client busses */
static ULTRA_VBUS_DEVICEINFO Bus_DriverInfo;
-/* virtpci_proc_dir_entry is used to create the proc entry directory
+/*****************************************************/
+/* debugfs entries */
+/*****************************************************/
+/* dentry is used to create the debugfs entry directory
* for virtpci
*/
-static struct proc_dir_entry *virtpci_proc_dir;
-/* virt_proc_entry is used to tell virtpci to add/delete vhbas/vnics/vbuses */
-static struct proc_dir_entry *virt_proc_entry;
-/* info_proc_entry is used to tell virtpci to display current info
- * kept in the driver
- */
-static struct proc_dir_entry *info_proc_entry;
-#define VIRT_PROC_ENTRY_FN "virt"
-#define INFO_PROC_ENTRY_FN "info"
-#define DIR_PROC_ENTRY "virtpci"
+static struct dentry *virtpci_debugfs_dir;
struct virtpci_busdev {
struct device virtpci_bus_device;
@@ -202,7 +196,7 @@ static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan,
LOGERR("vbus channel not used, because chpInfoByteOffset == 0");
return -1;
}
- memcpy(((U8 *) (chan)) + off, info, sizeof(*info));
+ memcpy(((u8 *) (chan)) + off, info, sizeof(*info));
return 0;
}
@@ -220,7 +214,7 @@ static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan,
LOGERR("vbus channel not used, because busInfoByteOffset == 0");
return -1;
}
- memcpy(((U8 *) (chan)) + off, info, sizeof(*info));
+ memcpy(((u8 *) (chan)) + off, info, sizeof(*info));
return 0;
}
@@ -244,7 +238,7 @@ write_vbus_devInfo(ULTRA_VBUS_CHANNEL_PROTOCOL *chan,
LOGERR("vbus channel not used, because devInfoByteOffset == 0");
return -1;
}
- memcpy(((U8 *) (chan)) + off, info, sizeof(*info));
+ memcpy(((u8 *) (chan)) + off, info, sizeof(*info));
return 0;
}
@@ -794,8 +788,7 @@ static void fix_vbus_devInfo(struct device *dev, int devNo, int devType,
BusDeviceInfo_Init(&devInfo, stype,
virtpcidrv->name,
virtpcidrv->version,
- virtpcidrv->vertag,
- virtpcidrv->build_date, virtpcidrv->build_time);
+ virtpcidrv->vertag);
write_vbus_devInfo(pChan, &devInfo, devNo);
/* Re-write bus+chipset info, because it is possible that this
@@ -1403,275 +1396,87 @@ void virtpci_unregister_driver(struct virtpci_driver *drv)
EXPORT_SYMBOL_GPL(virtpci_unregister_driver);
/*****************************************************/
-/* proc filesystem functions */
+/* debugfs filesystem functions */
/*****************************************************/
struct print_vbus_info {
- int *length;
+ int *str_pos;
char *buf;
+ size_t *len;
};
static int print_vbus(struct device *vbus, void *data)
{
- struct print_vbus_info *p = (struct print_vbus_info *) data;
- int l = *(p->length);
+ struct print_vbus_info *p = (struct print_vbus_info *)data;
- *(p->length) = l + sprintf(p->buf + l, "bus_id:%s\n", dev_name(vbus));
- return 0; /* no error */
+ *p->str_pos += scnprintf(p->buf + *p->str_pos, *p->len - *p->str_pos,
+ "bus_id:%s\n", dev_name(vbus));
+ return 0;
}
-static ssize_t info_proc_read(struct file *file, char __user *buf,
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
size_t len, loff_t *offset)
{
- int length = 0;
+ ssize_t bytes_read = 0;
+ int str_pos = 0;
struct virtpci_dev *tmpvpcidev;
unsigned long flags;
struct print_vbus_info printparam;
char *vbuf;
- loff_t pos = *offset;
-
- if (pos < 0)
- return -EINVAL;
-
- if (pos > 0 || !len)
- return 0;
+ if (len > MAX_BUF)
+ len = MAX_BUF;
vbuf = kzalloc(len, GFP_KERNEL);
if (!vbuf)
return -ENOMEM;
- length += sprintf(vbuf + length, "CHANSOCK is not defined.\n");
-
- length += sprintf(vbuf + length, "\n Virtual PCI Bus devices\n");
- printparam.length = &length;
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ " Virtual PCI Bus devices\n");
+ printparam.str_pos = &str_pos;
printparam.buf = vbuf;
+ printparam.len = &len;
if (bus_for_each_dev(&virtpci_bus_type, NULL,
(void *) &printparam, print_vbus))
- LOGERR("delete of all vbus failed\n");
+ LOGERR("Failed to find bus\n");
- length += sprintf(vbuf + length, "\n Virtual PCI devices\n");
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "\n Virtual PCI devices\n");
read_lock_irqsave(&VpcidevListLock, flags);
tmpvpcidev = VpcidevListHead;
while (tmpvpcidev) {
if (tmpvpcidev->devtype == VIRTHBA_TYPE) {
- length += sprintf(vbuf + length, "[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d",
- tmpvpcidev->busNo, tmpvpcidev->deviceNo,
- tmpvpcidev->scsi.wwnn.wwnn1,
- tmpvpcidev->scsi.wwnn.wwnn2,
- tmpvpcidev->scsi.max.max_channel,
- tmpvpcidev->scsi.max.max_id,
- tmpvpcidev->scsi.max.max_lun,
- tmpvpcidev->scsi.max.cmd_per_lun);
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d",
+ tmpvpcidev->busNo, tmpvpcidev->deviceNo,
+ tmpvpcidev->scsi.wwnn.wwnn1,
+ tmpvpcidev->scsi.wwnn.wwnn2,
+ tmpvpcidev->scsi.max.max_channel,
+ tmpvpcidev->scsi.max.max_id,
+ tmpvpcidev->scsi.max.max_lun,
+ tmpvpcidev->scsi.max.cmd_per_lun);
} else {
- length += sprintf(vbuf + length, "[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d",
- tmpvpcidev->busNo, tmpvpcidev->deviceNo,
- tmpvpcidev->net.mac_addr[0],
- tmpvpcidev->net.mac_addr[1],
- tmpvpcidev->net.mac_addr[2],
- tmpvpcidev->net.mac_addr[3],
- tmpvpcidev->net.mac_addr[4],
- tmpvpcidev->net.mac_addr[5],
- tmpvpcidev->net.num_rcv_bufs,
- tmpvpcidev->net.mtu);
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos,
+ "[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d",
+ tmpvpcidev->busNo, tmpvpcidev->deviceNo,
+ tmpvpcidev->net.mac_addr[0],
+ tmpvpcidev->net.mac_addr[1],
+ tmpvpcidev->net.mac_addr[2],
+ tmpvpcidev->net.mac_addr[3],
+ tmpvpcidev->net.mac_addr[4],
+ tmpvpcidev->net.mac_addr[5],
+ tmpvpcidev->net.num_rcv_bufs,
+ tmpvpcidev->net.mtu);
}
- length +=
- sprintf(vbuf + length, " chanptr:%p\n",
- tmpvpcidev->queueinfo.chan);
- tmpvpcidev = tmpvpcidev->next;
+ str_pos += scnprintf(vbuf + str_pos,
+ len - str_pos, " chanptr:%p\n",
+ tmpvpcidev->queueinfo.chan);
+ tmpvpcidev = tmpvpcidev->next;
}
read_unlock_irqrestore(&VpcidevListLock, flags);
- length +=
- sprintf(vbuf + length, "\nModule build: Date:%s Time:%s\n", __DATE__,
- __TIME__);
-
- length += sprintf(vbuf + length, "\n");
- if (copy_to_user(buf, vbuf, length)) {
- kfree(vbuf);
- return -EFAULT;
- }
-
+ str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n");
+ bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
kfree(vbuf);
- *offset += length;
- return length;
-}
-
-static ssize_t virt_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char buf[16];
- int type, i, action = 0xffff;
- unsigned int busno, deviceno;
- void __iomem *chanptr;
- struct add_vbus_guestpart busaddparams;
- struct add_virt_guestpart addparams;
- struct del_vbus_guestpart busdelparams;
- struct del_virt_guestpart delparams;
-#ifdef STORAGE_CHANNEL
- U64 storagechannel;
-#endif
-
-#define PRINT_USAGE_RETURN {\
- LOGERR("usage: 0-0-<chanptr> ==> delete vhba\n"); \
- LOGERR("usage: 0-1-<chanptr>-<busNo>-<deviceNo> ==> add vhba\n"); \
- LOGERR("usage: 0-f-<busNo> ==> delete all vhbas\n"); \
- LOGERR("\n"); \
- LOGERR("usage: 1-0-<chanptr> ==> delete vnic\n"); \
- LOGERR("usage: 1-1-<chanptr>-<busNo>-<deviceNo> ==> add vnic\n"); \
- LOGERR("usage: 1-f-<busNo> ==> delete all vnics\n"); \
- LOGERR("\n"); \
- LOGERR("usage: 6-0-<busNo> ==> delete vbus\n"); \
- LOGERR("usage: 6-1-<busNo> ==> add vbus\n"); \
- LOGERR("usage: 6-f ==> delete all vbuses\n"); \
- LOGERR("usage: 98-<busNo>-<deviceNo> ==> INJECT Client delete vnic\n"); \
- LOGERR("usage: 99-<chanptr>-<busNo>-<deviceNo> ==> INJECT Client add vnic\n"); \
- return -EINVAL; \
-}
-
- if (count >= ARRAY_SIZE(buf))
- return -EINVAL;
-
- if (copy_from_user(buf, buffer, count)) {
- LOGERR("copy_from_user failed.\n");
- return -EFAULT;
- }
-
- i = sscanf(buf, "%x-%x", &type, &action);
- if (i < 2)
- PRINT_USAGE_RETURN;
-
- if (type == 0x98) {
- /* client inject delete vnic */
- i = sscanf(buf, "%x-%d-%d", &type, &busno, &deviceno);
- if (i != 3)
- PRINT_USAGE_RETURN;
- uislib_client_inject_del_vnic(busno, deviceno);
- return count; /* success */
- } else if (type == 0x99) {
- /* client inject add vnic */
- i = sscanf(buf, "%x-%p-%d-%d", &type, &chanptr, &busno,
- &deviceno);
- if (i != 4)
- PRINT_USAGE_RETURN;
- if (!uislib_client_inject_add_vnic(busno, deviceno,
- __pa(chanptr),
- MIN_IO_CHANNEL_SIZE,
- 1, /* test msg */
- NULL_UUID_LE, /* inst guid */
- NULL)) { /*interrupt info */
- LOGERR("FAILED to inject add vnic\n");
- return -EFAULT;
- }
- return count; /* success */
- }
-
- if ((type != VIRTHBA_TYPE) && (type != VIRTNIC_TYPE)
- && (type != VIRTBUS_TYPE))
- PRINT_USAGE_RETURN;
-
- if (type == VIRTBUS_TYPE) {
- i = sscanf(buf, "%x-%x-%d", &type, &action, &busno);
- switch (action) {
- case 0:
- /* delete vbus */
- if (i != 3)
- break;
- busdelparams.busNo = busno;
- if (delete_vbus(&busdelparams))
- return count; /* success */
- return -EFAULT;
-
- case 1:
- /* add vbus */
- if (i != 3)
- break;
- busaddparams.chanptr = NULL; /* NOT YET USED */
- busaddparams.busNo = busno;
- if (add_vbus(&busaddparams))
- return count; /* success */
- return -EFAULT;
-
- case 0xf:
- /* delete all vbuses and all vhbas/vnics on the buses */
- if (i != 2)
- break;
- delete_all();
- return count; /* success */
- default:
- break;
- }
- PRINT_USAGE_RETURN;
- }
-
- /* if (type == VIRTNIC_TYPE) or if (type == VIRTHBA_TYPE) */
- switch (action) {
- case 0:
- /* delete vhba/vnic */
- i = sscanf(buf, "%x-%x-%p", &type, &action, &chanptr);
- if (i != 3)
- break;
- delparams.chanptr = chanptr;
- if (type == VIRTHBA_TYPE) {
- if (delete_vhba(&delparams))
- return count; /* success */
- } else {
- if (delete_vnic(&delparams))
- return count; /* success */
- }
- return -EFAULT;
-
- case 1:
- /* add vhba/vnic */
- i = sscanf(buf, "%x-%x-%p-%d-%d", &type, &action, &chanptr,
- &busno, &deviceno);
- if (i != 5)
- break;
- addparams.chanptr = chanptr;
- addparams.busNo = busno;
- addparams.deviceNo = deviceno;
- if (type == VIRTHBA_TYPE) {
- if (add_vhba(&addparams))
- return count; /* success */
- } else {
- if (add_vnic(&addparams))
- return count; /* success */
- }
- return -EFAULT;
-
-#ifdef STORAGE_CHANNEL
- case 2:
- /* add vhba */
- i = sscanf(buf, "%x-%x-%d-%d", &type, &action, &busno,
- &deviceno);
- if (i != 4)
- break;
- storagechannel = uislib_storage_channel(0); /* Get my storage channel */
- /* ioremap_cache it now */
- addparams.chanptr =
- (void *) ioremap_cache(storagechannel, IO_CHANNEL_SIZE);
- if (addparams.chanptr == NULL) {
- LOGERR("Failure to get remap storage channel.\n");
- return -EFAULT;
- }
- addparams.busNo = busno;
- addparams.deviceNo = deviceno;
- if (type == VIRTHBA_TYPE) {
- if (add_vhba(&addparams))
- return count; /* success */
- }
- return -EFAULT;
-#endif
- case 0xf:
- /* delete all vhbas/vnics */
- i = sscanf(buf, "%x-%x-%d", &type, &action, &busno);
- if (i != 3)
- break;
- busdelparams.busNo = busno;
- delete_all_virt(type, &busdelparams);
- return count; /* success */
- default:
- break;
- }
- PRINT_USAGE_RETURN;
+ return bytes_read;
}
/*****************************************************/
@@ -1686,8 +1491,6 @@ static int __init virtpci_mod_init(void)
if (!unisys_spar_platform)
return -ENODEV;
- LOGINF("Module build: Date:%s Time:%s...\n", __DATE__, __TIME__);
-
POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
ret = bus_register(&virtpci_bus_type);
@@ -1701,9 +1504,8 @@ static int __init virtpci_mod_init(void)
return ret;
}
DBGINF("bus_register successful\n");
- BusDeviceInfo_Init(&Bus_DriverInfo,
- "clientbus", "virtpci",
- VERSION, NULL, __DATE__, __TIME__);
+ BusDeviceInfo_Init(&Bus_DriverInfo, "clientbus", "virtpci",
+ VERSION, NULL);
/* create a root bus used to parent all the virtpci buses. */
ret = device_register(&virtpci_rootbus_device);
@@ -1727,12 +1529,10 @@ static int __init virtpci_mod_init(void)
LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n",
(void *) &virtpci_ctrlchan_func);
- /* create the proc directories */
- virtpci_proc_dir = proc_mkdir(DIR_PROC_ENTRY, NULL);
- virt_proc_entry = proc_create(VIRT_PROC_ENTRY_FN, 0, virtpci_proc_dir,
- &proc_virt_fops);
- info_proc_entry = proc_create(INFO_PROC_ENTRY_FN, 0, virtpci_proc_dir,
- &proc_info_fops);
+ /* create debugfs directory and info file inside. */
+ virtpci_debugfs_dir = debugfs_create_dir("virtpci", NULL);
+ debugfs_create_file("info", S_IRUSR, virtpci_debugfs_dir,
+ NULL, &debugfs_info_fops);
LOGINF("Leaving\n");
POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
return 0;
@@ -1748,16 +1548,7 @@ static void __exit virtpci_mod_exit(void)
device_unregister(&virtpci_rootbus_device);
bus_unregister(&virtpci_bus_type);
-
- if (virt_proc_entry)
- remove_proc_entry(VIRT_PROC_ENTRY_FN, virtpci_proc_dir);
-
- if (info_proc_entry)
- remove_proc_entry(INFO_PROC_ENTRY_FN, virtpci_proc_dir);
-
- if (virtpci_proc_dir)
- remove_proc_entry(DIR_PROC_ENTRY, NULL);
-
+ debugfs_remove_recursive(virtpci_debugfs_dir);
LOGINF("Leaving\n");
}
diff --git a/drivers/staging/unisys/virtpci/virtpci.h b/drivers/staging/unisys/virtpci/virtpci.h
index f7be17b669c4..6e26956c79f4 100644
--- a/drivers/staging/unisys/virtpci/virtpci.h
+++ b/drivers/staging/unisys/virtpci/virtpci.h
@@ -58,8 +58,8 @@ struct virtpci_dev {
* this device */
unsigned short vendor; /* vendor id for device */
unsigned short device; /* device id for device */
- U32 busNo; /* number of bus on which device exists */
- U32 deviceNo; /* device's number on the bus */
+ u32 busNo; /* number of bus on which device exists */
+ u32 deviceNo; /* device's number on the bus */
struct InterruptInfo intr; /* interrupt info */
struct device generic_dev; /* generic device */
union {
@@ -77,8 +77,6 @@ struct virtpci_driver {
const char *name; /* the name of the driver in sysfs */
const char *version;
const char *vertag;
- const char *build_date;
- const char *build_time;
const struct pci_device_id *id_table; /* must be non-NULL for probe
* to be called */
int (*probe)(struct virtpci_dev *dev,
diff --git a/drivers/staging/unisys/visorchannel/Makefile b/drivers/staging/unisys/visorchannel/Makefile
index f0060be55bc5..e079c96b1cdf 100644
--- a/drivers/staging/unisys/visorchannel/Makefile
+++ b/drivers/staging/unisys/visorchannel/Makefile
@@ -10,5 +10,3 @@ ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
ccflags-y += -Idrivers/staging/unisys/visorutil
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/visorchannel/visorchannel.h b/drivers/staging/unisys/visorchannel/visorchannel.h
index ecf0d11117e9..aa17a842381b 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel.h
+++ b/drivers/staging/unisys/visorchannel/visorchannel.h
@@ -24,7 +24,7 @@
#include "memregion.h"
#include "channel.h"
#ifndef HOSTADDRESS
-#define HOSTADDRESS U64
+#define HOSTADDRESS u64
#endif
#ifndef BOOL
#define BOOL int
@@ -55,22 +55,22 @@ int visorchannel_read(VISORCHANNEL *channel, ulong offset,
int visorchannel_write(VISORCHANNEL *channel, ulong offset,
void *local, ulong nbytes);
int visorchannel_clear(VISORCHANNEL *channel, ulong offset,
- U8 ch, ulong nbytes);
-BOOL visorchannel_signalremove(VISORCHANNEL *channel, U32 queue, void *msg);
-BOOL visorchannel_signalinsert(VISORCHANNEL *channel, U32 queue, void *msg);
-int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue);
-int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, U32 queue);
+ u8 ch, ulong nbytes);
+BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg);
+BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg);
+int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue);
+int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue);
HOSTADDRESS visorchannel_get_physaddr(VISORCHANNEL *channel);
ulong visorchannel_get_nbytes(VISORCHANNEL *channel);
char *visorchannel_id(VISORCHANNEL *channel, char *s);
char *visorchannel_zoneid(VISORCHANNEL *channel, char *s);
-U64 visorchannel_get_clientpartition(VISORCHANNEL *channel);
+u64 visorchannel_get_clientpartition(VISORCHANNEL *channel);
uuid_le visorchannel_get_uuid(VISORCHANNEL *channel);
MEMREGION *visorchannel_get_memregion(VISORCHANNEL *channel);
char *visorchannel_uuid_id(uuid_le *guid, char *s);
void visorchannel_debug(VISORCHANNEL *channel, int nQueues,
- struct seq_file *seq, U32 off);
+ struct seq_file *seq, u32 off);
void visorchannel_dump_section(VISORCHANNEL *chan, char *s,
int off, int len, struct seq_file *seq);
void __iomem *visorchannel_get_header(VISORCHANNEL *channel);
diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
index a44da7c84ae3..62ec9280cb3a 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
+++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
@@ -242,12 +242,12 @@ visorchannel_write(VISORCHANNEL *channel, ulong offset,
EXPORT_SYMBOL_GPL(visorchannel_write);
int
-visorchannel_clear(VISORCHANNEL *channel, ulong offset, U8 ch, ulong nbytes)
+visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes)
{
int rc = -1;
int bufsize = 65536;
int written = 0;
- U8 *buf = vmalloc(bufsize);
+ u8 *buf = vmalloc(bufsize);
if (buf == NULL) {
ERRDRV("%s failed memory allocation", __func__);
@@ -310,7 +310,7 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header);
sizeof((sig_hdr)->FIELD)) >= 0)
static BOOL
-sig_read_header(VISORCHANNEL *channel, U32 queue,
+sig_read_header(VISORCHANNEL *channel, u32 queue,
SIGNAL_QUEUE_HEADER *sig_hdr)
{
BOOL rc = FALSE;
@@ -336,8 +336,8 @@ Away:
}
static BOOL
-sig_do_data(VISORCHANNEL *channel, U32 queue,
- SIGNAL_QUEUE_HEADER *sig_hdr, U32 slot, void *data, BOOL is_write)
+sig_do_data(VISORCHANNEL *channel, u32 queue,
+ SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data, BOOL is_write)
{
BOOL rc = FALSE;
int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue,
@@ -362,15 +362,15 @@ Away:
}
static inline BOOL
-sig_read_data(VISORCHANNEL *channel, U32 queue,
- SIGNAL_QUEUE_HEADER *sig_hdr, U32 slot, void *data)
+sig_read_data(VISORCHANNEL *channel, u32 queue,
+ SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data)
{
return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE);
}
static inline BOOL
-sig_write_data(VISORCHANNEL *channel, U32 queue,
- SIGNAL_QUEUE_HEADER *sig_hdr, U32 slot, void *data)
+sig_write_data(VISORCHANNEL *channel, u32 queue,
+ SIGNAL_QUEUE_HEADER *sig_hdr, u32 slot, void *data)
{
return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE);
}
@@ -378,7 +378,7 @@ sig_write_data(VISORCHANNEL *channel, U32 queue,
static inline unsigned char
safe_sig_queue_validate(pSIGNAL_QUEUE_HEADER psafe_sqh,
pSIGNAL_QUEUE_HEADER punsafe_sqh,
- U32 *phead, U32 *ptail)
+ u32 *phead, u32 *ptail)
{
if ((*phead >= psafe_sqh->MaxSignalSlots)
|| (*ptail >= psafe_sqh->MaxSignalSlots)) {
@@ -398,7 +398,7 @@ safe_sig_queue_validate(pSIGNAL_QUEUE_HEADER psafe_sqh,
} /* end safe_sig_queue_validate */
BOOL
-visorchannel_signalremove(VISORCHANNEL *channel, U32 queue, void *msg)
+visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg)
{
BOOL rc = FALSE;
SIGNAL_QUEUE_HEADER sig_hdr;
@@ -444,7 +444,7 @@ Away:
EXPORT_SYMBOL_GPL(visorchannel_signalremove);
BOOL
-visorchannel_signalinsert(VISORCHANNEL *channel, U32 queue, void *msg)
+visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg)
{
BOOL rc = FALSE;
SIGNAL_QUEUE_HEADER sig_hdr;
@@ -498,11 +498,11 @@ EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
int
-visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue)
+visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue)
{
SIGNAL_QUEUE_HEADER sig_hdr;
- U32 slots_avail, slots_used;
- U32 head, tail;
+ u32 slots_avail, slots_used;
+ u32 head, tail;
if (!sig_read_header(channel, queue, &sig_hdr))
return 0;
@@ -517,7 +517,7 @@ visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, U32 queue)
EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
int
-visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, U32 queue)
+visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue)
{
SIGNAL_QUEUE_HEADER sig_hdr;
if (!sig_read_header(channel, queue, &sig_hdr))
@@ -552,7 +552,7 @@ sigqueue_debug(SIGNAL_QUEUE_HEADER *q, int which, struct seq_file *seq)
void
visorchannel_debug(VISORCHANNEL *channel, int nQueues,
- struct seq_file *seq, U32 off)
+ struct seq_file *seq, u32 off)
{
HOSTADDRESS addr = 0;
ulong nbytes = 0, nbytes_region = 0;
diff --git a/drivers/staging/unisys/visorchipset/Makefile b/drivers/staging/unisys/visorchipset/Makefile
index ead4b9c02715..12686906bef3 100644
--- a/drivers/staging/unisys/visorchipset/Makefile
+++ b/drivers/staging/unisys/visorchipset/Makefile
@@ -4,8 +4,7 @@
obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset.o
-visorchipset-y := visorchipset_main.o controlvm_direct.o file.o \
- parser.o
+visorchipset-y := visorchipset_main.o file.o parser.o
ccflags-y += -Idrivers/staging/unisys/include
ccflags-y += -Idrivers/staging/unisys/uislib
@@ -14,5 +13,3 @@ ccflags-y += -Idrivers/staging/unisys/common-spar/include
ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
ccflags-y += -Idrivers/staging/unisys/visorutil
ccflags-y += -Iinclude/generated
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
-
diff --git a/drivers/staging/unisys/visorchipset/controlvm.h b/drivers/staging/unisys/visorchipset/controlvm.h
deleted file mode 100644
index 012891c3f21d..000000000000
--- a/drivers/staging/unisys/visorchipset/controlvm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* controlvm.h
- *
- * Copyright (C) 2010 - 2013 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 __CONTROLVM_H__
-#define __CONTROLVM_H__
-
-#include "timskmod.h"
-
-int controlvm_init(void);
-void controlvm_deinit(void);
-HOSTADDRESS controlvm_get_channel_address(void);
-
-#endif
diff --git a/drivers/staging/unisys/visorchipset/controlvm_direct.c b/drivers/staging/unisys/visorchipset/controlvm_direct.c
deleted file mode 100644
index cd10e3a2a07f..000000000000
--- a/drivers/staging/unisys/visorchipset/controlvm_direct.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* controlvm_direct.c
- *
- * Copyright (C) 2010 - 2013 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.
- */
-
-/* This is a controlvm-related code that is dependent upon firmware running
- * on a virtual partition.
- */
-
-#include "globals.h"
-#include "uisutils.h"
-#include "controlvm.h"
-#define CURRENT_FILE_PC VISOR_CHIPSET_PC_controlvm_direct_c
-
-
-/* We can fill in this code when we learn how to make vmcalls... */
-
-
-
-int controlvm_init(void)
-{
- return 0;
-}
-
-
-
-void controlvm_deinit(void)
-{
-}
-
-
-
-HOSTADDRESS controlvm_get_channel_address(void)
-{
- static BOOL warned = FALSE;
- U64 addr = 0;
-
- U32 size = 0;
-
- if (!VMCALL_SUCCESSFUL(Issue_VMCALL_IO_CONTROLVM_ADDR(&addr, &size))) {
- if (!warned) {
- ERRDRV("%s - vmcall to determine controlvm channel addr failed",
- __func__);
- warned = TRUE;
- }
- return 0;
- }
- INFODRV("controlvm addr=%Lx", addr);
- return addr;
-}
diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c
index fccc4f0c3a49..bf2e546d76bf 100644
--- a/drivers/staging/unisys/visorchipset/file.c
+++ b/drivers/staging/unisys/visorchipset/file.c
@@ -190,8 +190,8 @@ visorchipset_ioctl(struct inode *inode, struct file *file,
#endif
{
int rc = SUCCESS;
- S64 adjustment;
- S64 vrtc_offset;
+ s64 adjustment;
+ s64 vrtc_offset;
DBGINF("entered visorchipset_ioctl, cmd=%d", cmd);
switch (cmd) {
case VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET:
diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c
index 4274dd2dbbd1..86fa2949dc4e 100644
--- a/drivers/staging/unisys/visorchipset/parser.c
+++ b/drivers/staging/unisys/visorchipset/parser.c
@@ -41,7 +41,7 @@ struct PARSER_CONTEXT_Tag {
};
static PARSER_CONTEXT *
-parser_init_guts(U64 addr, U32 bytes, BOOL isLocal,
+parser_init_guts(u64 addr, u32 bytes, BOOL isLocal,
BOOL hasStandardPayloadHeader, BOOL *tryAgain)
{
int allocbytes = sizeof(PARSER_CONTEXT) + bytes;
@@ -152,7 +152,7 @@ Away:
}
PARSER_CONTEXT *
-parser_init(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain)
+parser_init(u64 addr, u32 bytes, BOOL isLocal, BOOL *tryAgain)
{
return parser_init_guts(addr, bytes, isLocal, TRUE, tryAgain);
}
@@ -163,7 +163,7 @@ parser_init(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain)
* parser_byteStream_get() to obtain the data.
*/
PARSER_CONTEXT *
-parser_init_byteStream(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain)
+parser_init_byteStream(u64 addr, u32 bytes, BOOL isLocal, BOOL *tryAgain)
{
return parser_init_guts(addr, bytes, isLocal, FALSE, tryAgain);
}
diff --git a/drivers/staging/unisys/visorchipset/parser.h b/drivers/staging/unisys/visorchipset/parser.h
index be85fd68c0c4..9fbe3b5b7cc3 100644
--- a/drivers/staging/unisys/visorchipset/parser.h
+++ b/drivers/staging/unisys/visorchipset/parser.h
@@ -33,8 +33,8 @@ typedef enum {
typedef struct PARSER_CONTEXT_Tag PARSER_CONTEXT;
-PARSER_CONTEXT *parser_init(U64 addr, U32 bytes, BOOL isLocal, BOOL *tryAgain);
-PARSER_CONTEXT *parser_init_byteStream(U64 addr, U32 bytes, BOOL isLocal,
+PARSER_CONTEXT *parser_init(u64 addr, u32 bytes, BOOL isLocal, BOOL *tryAgain);
+PARSER_CONTEXT *parser_init_byteStream(u64 addr, u32 bytes, BOOL isLocal,
BOOL *tryAgain);
void parser_param_start(PARSER_CONTEXT *ctx, PARSER_WHICH_STRING which_string);
void *parser_param_get(PARSER_CONTEXT *ctx, char *nam, int namesize);
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index e01cc7207bae..2bf2e2f368ef 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -32,10 +32,10 @@
* been received for a bus or device.
*/
typedef struct {
- U32 created:1;
- U32 attached:1;
- U32 configured:1;
- U32 running:1;
+ u32 created:1;
+ u32 attached:1;
+ u32 configured:1;
+ u32 running:1;
/* Add new fields above. */
/* Remaining bits in this 32-bit word are unused. */
} VISORCHIPSET_STATE;
@@ -64,7 +64,7 @@ typedef struct {
VISORCHIPSET_ADDRESSTYPE addrType;
HOSTADDRESS channelAddr;
struct InterruptInfo intr;
- U64 nChannelBytes;
+ u64 nChannelBytes;
uuid_le channelTypeGuid;
uuid_le channelInstGuid;
@@ -77,15 +77,15 @@ typedef struct {
*/
typedef struct {
struct list_head entry;
- U32 busNo;
- U32 devNo;
+ u32 busNo;
+ u32 devNo;
uuid_le devInstGuid;
VISORCHIPSET_STATE state;
VISORCHIPSET_CHANNEL_INFO chanInfo;
- U32 Reserved1; /* CONTROLVM_ID */
- U64 Reserved2;
- U32 switchNo; /* when devState.attached==1 */
- U32 internalPortNo; /* when devState.attached==1 */
+ u32 Reserved1; /* CONTROLVM_ID */
+ u64 Reserved2;
+ u32 switchNo; /* when devState.attached==1 */
+ u32 internalPortNo; /* when devState.attached==1 */
CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM_MESSAGE */
/** For private use by the bus driver */
void *bus_driver_context;
@@ -93,7 +93,7 @@ typedef struct {
} VISORCHIPSET_DEVICE_INFO;
static inline VISORCHIPSET_DEVICE_INFO *
-finddevice(struct list_head *list, U32 busNo, U32 devNo)
+finddevice(struct list_head *list, u32 busNo, u32 devNo)
{
VISORCHIPSET_DEVICE_INFO *p;
@@ -104,7 +104,7 @@ finddevice(struct list_head *list, U32 busNo, U32 devNo)
return NULL;
}
-static inline void delbusdevices(struct list_head *list, U32 busNo)
+static inline void delbusdevices(struct list_head *list, u32 busNo)
{
VISORCHIPSET_DEVICE_INFO *p, *tmp;
@@ -124,30 +124,30 @@ static inline void delbusdevices(struct list_head *list, U32 busNo)
*/
typedef struct {
struct list_head entry;
- U32 busNo;
+ u32 busNo;
VISORCHIPSET_STATE state;
VISORCHIPSET_CHANNEL_INFO chanInfo;
uuid_le partitionGuid;
- U64 partitionHandle;
- U8 *name; /* UTF8 */
- U8 *description; /* UTF8 */
- U64 Reserved1;
- U32 Reserved2;
+ u64 partitionHandle;
+ u8 *name; /* UTF8 */
+ u8 *description; /* UTF8 */
+ u64 Reserved1;
+ u32 Reserved2;
MYPROCOBJECT *procObject;
struct {
- U32 server:1;
+ u32 server:1;
/* Add new fields above. */
/* Remaining bits in this 32-bit word are unused. */
} flags;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr; /* CONTROLVM MsgHdr */
/** For private use by the bus driver */
void *bus_driver_context;
- U64 devNo;
+ u64 devNo;
} VISORCHIPSET_BUS_INFO;
static inline VISORCHIPSET_BUS_INFO *
-findbus(struct list_head *list, U32 busNo)
+findbus(struct list_head *list, u32 busNo)
{
VISORCHIPSET_BUS_INFO *p;
@@ -161,15 +161,15 @@ findbus(struct list_head *list, U32 busNo)
/** Attributes for a particular Supervisor switch.
*/
typedef struct {
- U32 switchNo;
+ u32 switchNo;
VISORCHIPSET_STATE state;
uuid_le switchTypeGuid;
- U8 *authService1;
- U8 *authService2;
- U8 *authService3;
- U8 *securityContext;
- U64 Reserved;
- U32 Reserved2; /* CONTROLVM_ID */
+ u8 *authService1;
+ u8 *authService2;
+ u8 *authService3;
+ u8 *securityContext;
+ u64 Reserved;
+ u32 Reserved2; /* CONTROLVM_ID */
struct device dev;
BOOL dev_exists;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
@@ -180,19 +180,19 @@ typedef struct {
* to a specific switch.
*/
typedef struct {
- U32 switchNo;
- U32 externalPortNo;
+ u32 switchNo;
+ u32 externalPortNo;
VISORCHIPSET_STATE state;
uuid_le networkZoneGuid;
int pdPort;
- U8 *ip;
- U8 *ipNetmask;
- U8 *ipBroadcast;
- U8 *ipNetwork;
- U8 *ipGateway;
- U8 *ipDNS;
- U64 Reserved1;
- U32 Reserved2; /* CONTROLVM_ID */
+ u8 *ip;
+ u8 *ipNetmask;
+ u8 *ipBroadcast;
+ u8 *ipNetwork;
+ u8 *ipGateway;
+ u8 *ipDNS;
+ u64 Reserved1;
+ u32 Reserved2; /* CONTROLVM_ID */
struct device dev;
BOOL dev_exists;
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
@@ -203,13 +203,13 @@ typedef struct {
* device connects to a particular switch.
*/
typedef struct {
- U32 switchNo;
- U32 internalPortNo;
+ u32 switchNo;
+ u32 internalPortNo;
VISORCHIPSET_STATE state;
- U32 busNo; /* valid only when state.attached == 1 */
- U32 devNo; /* valid only when state.attached == 1 */
- U64 Reserved1;
- U32 Reserved2; /* CONTROLVM_ID */
+ u32 busNo; /* valid only when state.attached == 1 */
+ u32 devNo; /* valid only when state.attached == 1 */
+ u64 Reserved1;
+ u32 Reserved2; /* CONTROLVM_ID */
CONTROLVM_MESSAGE_HEADER pendingMsgHdr;
MYPROCOBJECT *procObject;
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 0a602b9c130b..fe3c0127d255 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -16,7 +16,6 @@
*/
#include "globals.h"
-#include "controlvm.h"
#include "visorchipset.h"
#include "procobjecttree.h"
#include "visorchannel.h"
@@ -67,7 +66,7 @@ static int serverregistered;
static int clientregistered;
#define MAX_CHIPSET_EVENTS 2
-static U8 chipset_events[MAX_CHIPSET_EVENTS] = { 0, 0 };
+static u8 chipset_events[MAX_CHIPSET_EVENTS] = { 0, 0 };
static struct delayed_work Periodic_controlvm_work;
static struct workqueue_struct *Periodic_controlvm_workqueue;
@@ -99,122 +98,16 @@ static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket;
#define is_diagpool_channel(channel_type_guid) \
(uuid_le_cmp(channel_type_guid, UltraDiagPoolChannelProtocolGuid) == 0)
-typedef enum {
- PARTPROP_invalid,
- PARTPROP_name,
- PARTPROP_description,
- PARTPROP_handle,
- PARTPROP_busNumber,
- /* add new properties above, but don't forget to change
- * InitPartitionProperties() and show_partition_property() also...
- */
- PARTPROP_last
-} PARTITION_property;
-static const char *PartitionTypeNames[] = { "partition", NULL };
-
-static char *PartitionPropertyNames[PARTPROP_last + 1];
-static void
-InitPartitionProperties(void)
-{
- char **p = PartitionPropertyNames;
- p[PARTPROP_invalid] = "";
- p[PARTPROP_name] = "name";
- p[PARTPROP_description] = "description";
- p[PARTPROP_handle] = "handle";
- p[PARTPROP_busNumber] = "busNumber";
- p[PARTPROP_last] = NULL;
-}
-
-typedef enum {
- CTLVMPROP_invalid,
- CTLVMPROP_physAddr,
- CTLVMPROP_controlChannelAddr,
- CTLVMPROP_controlChannelBytes,
- CTLVMPROP_sparBootPart,
- CTLVMPROP_sparStoragePart,
- CTLVMPROP_livedumpLength,
- CTLVMPROP_livedumpCrc32,
- /* add new properties above, but don't forget to change
- * InitControlVmProperties() show_controlvm_property() also...
- */
- CTLVMPROP_last
-} CONTROLVM_property;
-
-static const char *ControlVmTypeNames[] = { "controlvm", NULL };
-
-static char *ControlVmPropertyNames[CTLVMPROP_last + 1];
-static void
-InitControlVmProperties(void)
-{
- char **p = ControlVmPropertyNames;
- p[CTLVMPROP_invalid] = "";
- p[CTLVMPROP_physAddr] = "physAddr";
- p[CTLVMPROP_controlChannelAddr] = "controlChannelAddr";
- p[CTLVMPROP_controlChannelBytes] = "controlChannelBytes";
- p[CTLVMPROP_sparBootPart] = "spar_boot_part";
- p[CTLVMPROP_sparStoragePart] = "spar_storage_part";
- p[CTLVMPROP_livedumpLength] = "livedumpLength";
- p[CTLVMPROP_livedumpCrc32] = "livedumpCrc32";
- p[CTLVMPROP_last] = NULL;
-}
-
-static MYPROCOBJECT *ControlVmObject;
-static MYPROCTYPE *PartitionType;
-static MYPROCTYPE *ControlVmType;
-
-#define VISORCHIPSET_DIAG_PROC_ENTRY_FN "diagdump"
-static struct proc_dir_entry *diag_proc_dir;
-
-#define VISORCHIPSET_CHIPSET_PROC_ENTRY_FN "chipsetready"
-static struct proc_dir_entry *chipset_proc_dir;
-
-#define VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN "parahotplug"
-static struct proc_dir_entry *parahotplug_proc_dir;
-
static LIST_HEAD(BusInfoList);
static LIST_HEAD(DevInfoList);
-static struct proc_dir_entry *ProcDir;
static VISORCHANNEL *ControlVm_channel;
-static ssize_t visorchipset_proc_read_writeonly(struct file *file,
- char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t proc_read_installer(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t proc_write_installer(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *ppos);
-static ssize_t proc_read_toolaction(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t proc_write_toolaction(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *ppos);
-static ssize_t proc_read_bootToTool(struct file *file, char __user *buf,
- size_t len, loff_t *offset);
-static ssize_t proc_write_bootToTool(struct file *file,
- const char __user *buffer,
- size_t count, loff_t *ppos);
-static const struct file_operations proc_installer_fops = {
- .read = proc_read_installer,
- .write = proc_write_installer,
-};
-
-static const struct file_operations proc_toolaction_fops = {
- .read = proc_read_toolaction,
- .write = proc_write_toolaction,
-};
-
-static const struct file_operations proc_bootToTool_fops = {
- .read = proc_read_bootToTool,
- .write = proc_write_bootToTool,
-};
-
typedef struct {
- U8 __iomem *ptr; /* pointer to base address of payload pool */
- U64 offset; /* offset from beginning of controlvm
+ u8 __iomem *ptr; /* pointer to base address of payload pool */
+ u64 offset; /* offset from beginning of controlvm
* channel to beginning of payload * pool */
- U32 bytes; /* number of bytes in payload pool */
+ u32 bytes; /* number of bytes in payload pool */
} CONTROLVM_PAYLOAD_INFO;
/* Manages the request payload in the controlvm channel */
@@ -357,10 +250,96 @@ static VISORCHIPSET_BUSDEV_RESPONDERS BusDev_Responders = {
/* info for /dev/visorchipset */
static dev_t MajorDev = -1; /**< indicates major num for device */
+/* prototypes for attributes */
+static ssize_t toolaction_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t toolaction_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_RW(toolaction);
+
+static ssize_t boottotool_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t boottotool_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_RW(boottotool);
+
+static ssize_t error_show(struct device *dev, struct device_attribute *attr,
+ char *buf);
+static ssize_t error_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+static DEVICE_ATTR_RW(error);
+
+static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
+ char *buf);
+static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+static DEVICE_ATTR_RW(textid);
+
+static ssize_t remaining_steps_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t remaining_steps_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_RW(remaining_steps);
+
+static ssize_t chipsetready_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_WO(chipsetready);
+
+static ssize_t devicedisabled_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_WO(devicedisabled);
+
+static ssize_t deviceenabled_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_WO(deviceenabled);
+
+static struct attribute *visorchipset_install_attrs[] = {
+ &dev_attr_toolaction.attr,
+ &dev_attr_boottotool.attr,
+ &dev_attr_error.attr,
+ &dev_attr_textid.attr,
+ &dev_attr_remaining_steps.attr,
+ NULL
+};
+
+static struct attribute_group visorchipset_install_group = {
+ .name = "install",
+ .attrs = visorchipset_install_attrs
+};
+
+static struct attribute *visorchipset_guest_attrs[] = {
+ &dev_attr_chipsetready.attr,
+ NULL
+};
+
+static struct attribute_group visorchipset_guest_group = {
+ .name = "guest",
+ .attrs = visorchipset_guest_attrs
+};
+
+static struct attribute *visorchipset_parahotplug_attrs[] = {
+ &dev_attr_devicedisabled.attr,
+ &dev_attr_deviceenabled.attr,
+ NULL
+};
+
+static struct attribute_group visorchipset_parahotplug_group = {
+ .name = "parahotplug",
+ .attrs = visorchipset_parahotplug_attrs
+};
+
+static const struct attribute_group *visorchipset_dev_groups[] = {
+ &visorchipset_install_group,
+ &visorchipset_guest_group,
+ &visorchipset_parahotplug_group,
+ NULL
+};
+
/* /sys/devices/platform/visorchipset */
static struct platform_device Visorchipset_platform_device = {
.name = "visorchipset",
.id = -1,
+ .dev.groups = visorchipset_dev_groups,
};
/* Function prototypes */
@@ -372,107 +351,166 @@ static void controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *
msgHdr, int response,
ULTRA_SEGMENT_STATE state);
-static void
-show_partition_property(struct seq_file *f, void *ctx, int property)
+static ssize_t toolaction_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- VISORCHIPSET_BUS_INFO *info = (VISORCHIPSET_BUS_INFO *) (ctx);
+ u8 toolAction;
- switch (property) {
- case PARTPROP_name:
- seq_printf(f, "%s\n", NONULLSTR(info->name));
- break;
- case PARTPROP_description:
- seq_printf(f, "%s\n", NONULLSTR(info->description));
- break;
- case PARTPROP_handle:
- seq_printf(f, "0x%-16.16Lx\n", info->partitionHandle);
- break;
- case PARTPROP_busNumber:
- seq_printf(f, "%d\n", info->busNo);
- break;
- default:
- seq_printf(f, "(%d??)\n", property);
- break;
- }
+ visorchannel_read(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ ToolAction), &toolAction, sizeof(u8));
+ return scnprintf(buf, PAGE_SIZE, "%u\n", toolAction);
}
-static void
-show_controlvm_property(struct seq_file *f, void *ctx, int property)
+static ssize_t toolaction_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- /* Note: ctx is not needed since we only have 1 controlvm channel */
- switch (property) {
- case CTLVMPROP_physAddr:
- if (ControlVm_channel == NULL)
- seq_puts(f, "0x0\n");
- else
- seq_printf(f, "0x%-16.16Lx\n",
- visorchannel_get_physaddr
- (ControlVm_channel));
- break;
- case CTLVMPROP_controlChannelAddr:
- if (ControlVm_channel == NULL)
- seq_puts(f, "0x0\n");
- else {
- GUEST_PHYSICAL_ADDRESS addr = 0;
- visorchannel_read(ControlVm_channel,
- offsetof
- (ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- gpControlChannel), &addr,
- sizeof(addr));
- seq_printf(f, "0x%-16.16Lx\n", (u64) (addr));
- }
- break;
- case CTLVMPROP_controlChannelBytes:
- if (ControlVm_channel == NULL)
- seq_puts(f, "0x0\n");
- else {
- U32 bytes = 0;
- visorchannel_read(ControlVm_channel,
- offsetof
- (ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- ControlChannelBytes), &bytes,
- sizeof(bytes));
- seq_printf(f, "%lu\n", (ulong) (bytes));
- }
- break;
- case CTLVMPROP_sparBootPart:
- seq_puts(f, "0:0:0:0/1\n");
- break;
- case CTLVMPROP_sparStoragePart:
- seq_puts(f, "0:0:0:0/2\n");
- break;
- case CTLVMPROP_livedumpLength:
- seq_printf(f, "%lu\n", LiveDump_info.length);
- break;
- case CTLVMPROP_livedumpCrc32:
- seq_printf(f, "%lu\n", (ulong) LiveDump_info.crc32);
- break;
- default:
- seq_printf(f, "(%d??)\n", property);
- break;
- }
+ u8 toolAction;
+ int ret;
+
+ if (kstrtou8(buf, 10, &toolAction) != 0)
+ return -EINVAL;
+
+ ret = visorchannel_write(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ToolAction),
+ &toolAction, sizeof(u8));
+
+ if (ret)
+ return ret;
+ else
+ return count;
}
-static void
-proc_Init(void)
-{
- if (ProcDir == NULL) {
- ProcDir = proc_mkdir(MYDRVNAME, NULL);
- if (ProcDir == NULL) {
- LOGERR("failed to create /proc directory %s",
- MYDRVNAME);
- POSTCODE_LINUX_2(CHIPSET_INIT_FAILURE_PC,
- POSTCODE_SEVERITY_ERR);
- }
- }
+static ssize_t boottotool_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ULTRA_EFI_SPAR_INDICATION efiSparIndication;
+
+ visorchannel_read(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ EfiSparIndication), &efiSparIndication,
+ sizeof(ULTRA_EFI_SPAR_INDICATION));
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ efiSparIndication.BootToTool);
}
-static void
-proc_DeInit(void)
+static ssize_t boottotool_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- if (ProcDir != NULL)
- remove_proc_entry(MYDRVNAME, NULL);
- ProcDir = NULL;
+ int val, ret;
+ ULTRA_EFI_SPAR_INDICATION efiSparIndication;
+
+ if (kstrtoint(buf, 10, &val) != 0)
+ return -EINVAL;
+
+ efiSparIndication.BootToTool = val;
+ ret = visorchannel_write(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ EfiSparIndication),
+ &(efiSparIndication),
+ sizeof(ULTRA_EFI_SPAR_INDICATION));
+
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t error_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ u32 error;
+
+ visorchannel_read(ControlVm_channel, offsetof(
+ ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationError),
+ &error, sizeof(u32));
+ return scnprintf(buf, PAGE_SIZE, "%i\n", error);
+}
+
+static ssize_t error_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 error;
+ int ret;
+
+ if (kstrtou32(buf, 10, &error) != 0)
+ return -EINVAL;
+
+ ret = visorchannel_write(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ InstallationError),
+ &error, sizeof(u32));
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ u32 textId;
+
+ visorchannel_read(ControlVm_channel, offsetof(
+ ULTRA_CONTROLVM_CHANNEL_PROTOCOL, InstallationTextId),
+ &textId, sizeof(u32));
+ return scnprintf(buf, PAGE_SIZE, "%i\n", textId);
+}
+
+static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 textId;
+ int ret;
+
+ if (kstrtou32(buf, 10, &textId) != 0)
+ return -EINVAL;
+
+ ret = visorchannel_write(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ InstallationTextId),
+ &textId, sizeof(u32));
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+
+static ssize_t remaining_steps_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u16 remainingSteps;
+
+ visorchannel_read(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ InstallationRemainingSteps),
+ &remainingSteps,
+ sizeof(u16));
+ return scnprintf(buf, PAGE_SIZE, "%hu\n", remainingSteps);
+}
+
+static ssize_t remaining_steps_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ u16 remainingSteps;
+ int ret;
+
+ if (kstrtou16(buf, 10, &remainingSteps) != 0)
+ return -EINVAL;
+
+ ret = visorchannel_write(ControlVm_channel,
+ offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
+ InstallationRemainingSteps),
+ &remainingSteps, sizeof(u16));
+ if (ret)
+ return ret;
+ else
+ return count;
}
#if 0
@@ -531,11 +569,11 @@ devInfo_clear(void *v)
memset(p, 0, sizeof(VISORCHIPSET_DEVICE_INFO));
}
-static U8
+static u8
check_chipset_events(void)
{
int i;
- U8 send_msg = 1;
+ u8 send_msg = 1;
/* Check events to determine if response should be sent */
for (i = 0; i < MAX_CHIPSET_EVENTS; i++)
send_msg &= chipset_events[i];
@@ -569,7 +607,7 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
*responders = BusDev_Responders;
if (driverInfo)
BusDeviceInfo_Init(driverInfo, "chipset", "visorchipset",
- VERSION, NULL, __DATE__, __TIME__);
+ VERSION, NULL);
UNLOCKSEM(&NotifierLock);
}
@@ -593,7 +631,7 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers,
*responders = BusDev_Responders;
if (driverInfo)
BusDeviceInfo_Init(driverInfo, "chipset(bolts)", "visorchipset",
- VERSION, NULL, __DATE__, __TIME__);
+ VERSION, NULL);
UNLOCKSEM(&NotifierLock);
}
EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client);
@@ -661,7 +699,7 @@ controlvm_init_response(CONTROLVM_MESSAGE *msg,
msg->hdr.PayloadMaxBytes = 0;
if (response < 0) {
msg->hdr.Flags.failed = 1;
- msg->hdr.CompletionStatus = (U32) (-response);
+ msg->hdr.CompletionStatus = (u32) (-response);
}
}
@@ -669,8 +707,6 @@ static void
controlvm_respond(CONTROLVM_MESSAGE_HEADER *msgHdr, int response)
{
CONTROLVM_MESSAGE outmsg;
- if (!ControlVm_channel)
- return;
controlvm_init_response(&outmsg, msgHdr, response);
/* For DiagPool channel DEVICE_CHANGESTATE, we need to send
* back the deviceChangeState structure in the packet. */
@@ -697,8 +733,6 @@ controlvm_respond_chipset_init(CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
ULTRA_CHIPSET_FEATURE features)
{
CONTROLVM_MESSAGE outmsg;
- if (!ControlVm_channel)
- return;
controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.initChipset.features = features;
if (!visorchannel_signalinsert(ControlVm_channel,
@@ -713,8 +747,6 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
int response, ULTRA_SEGMENT_STATE state)
{
CONTROLVM_MESSAGE outmsg;
- if (!ControlVm_channel)
- return;
controlvm_init_response(&outmsg, msgHdr, response);
outmsg.cmd.deviceChangeState.state = state;
outmsg.cmd.deviceChangeState.flags.physicalDevice = 1;
@@ -728,14 +760,14 @@ controlvm_respond_physdev_changestate(CONTROLVM_MESSAGE_HEADER *msgHdr,
void
visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type)
{
- U32 localSavedCrashMsgOffset;
- U16 localSavedCrashMsgCount;
+ u32 localSavedCrashMsgOffset;
+ u16 localSavedCrashMsgCount;
/* get saved message count */
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
SavedCrashMsgCount),
- &localSavedCrashMsgCount, sizeof(U16)) < 0) {
+ &localSavedCrashMsgCount, sizeof(u16)) < 0) {
LOGERR("failed to get Saved Message Count");
POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
POSTCODE_SEVERITY_ERR);
@@ -755,7 +787,7 @@ visorchipset_save_message(CONTROLVM_MESSAGE *msg, CRASH_OBJ_TYPE type)
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
SavedCrashMsgOffset),
- &localSavedCrashMsgOffset, sizeof(U32)) < 0) {
+ &localSavedCrashMsgOffset, sizeof(u32)) < 0) {
LOGERR("failed to get Saved Message Offset");
POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
POSTCODE_SEVERITY_ERR);
@@ -812,7 +844,7 @@ bus_responder(CONTROLVM_ID cmdId, ulong busNo, int response)
LOGERR("bus_responder no pending msg");
return; /* no controlvm response needed */
}
- if (p->pendingMsgHdr.Id != (U32) cmdId) {
+ if (p->pendingMsgHdr.Id != (u32) cmdId) {
LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id);
return;
}
@@ -832,9 +864,6 @@ device_changestate_responder(CONTROLVM_ID cmdId,
VISORCHIPSET_DEVICE_INFO *p = NULL;
CONTROLVM_MESSAGE outmsg;
- if (!ControlVm_channel)
- return;
-
p = finddevice(&DevInfoList, busNo, devNo);
if (!p) {
LOGERR("internal error; busNo=%lu, devNo=%lu", busNo, devNo);
@@ -886,7 +915,7 @@ device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response)
LOGERR("device_responder no pending msg");
return; /* no controlvm response needed */
}
- if (p->pendingMsgHdr.Id != (U32) cmdId) {
+ if (p->pendingMsgHdr.Id != (u32) cmdId) {
LOGERR("expected=%d, found=%d", cmdId, p->pendingMsgHdr.Id);
return;
}
@@ -897,8 +926,8 @@ device_responder(CONTROLVM_ID cmdId, ulong busNo, ulong devNo, int response)
}
static void
-bus_epilog(U32 busNo,
- U32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr,
+bus_epilog(u32 busNo,
+ u32 cmd, CONTROLVM_MESSAGE_HEADER *msgHdr,
int response, BOOL needResponse)
{
BOOL notified = FALSE;
@@ -964,7 +993,7 @@ bus_epilog(U32 busNo,
}
static void
-device_epilog(U32 busNo, U32 devNo, ULTRA_SEGMENT_STATE state, U32 cmd,
+device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd,
CONTROLVM_MESSAGE_HEADER *msgHdr, int response,
BOOL needResponse, BOOL for_visorbus)
{
@@ -1186,16 +1215,6 @@ bus_configure(CONTROLVM_MESSAGE *inmsg, PARSER_CONTEXT *parser_ctx)
pBusInfo->name = parser_string_get(parser_ctx);
visorchannel_uuid_id(&pBusInfo->partitionGuid, s);
- pBusInfo->procObject =
- visor_proc_CreateObject(PartitionType, s, (void *) (pBusInfo));
- if (pBusInfo->procObject == NULL) {
- LOGERR("CONTROLVM_BUS_CONFIGURE Failed: busNo=%lu failed to create /proc entry",
- busNo);
- POSTCODE_LINUX_3(BUS_CONFIGURE_FAILURE_PC, busNo,
- POSTCODE_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
- goto Away;
- }
POSTCODE_LINUX_3(BUS_CONFIGURE_EXIT_PC, busNo, POSTCODE_SEVERITY_INFO);
Away:
bus_epilog(busNo, CONTROLVM_BUS_CONFIGURE, &inmsg->hdr,
@@ -1351,10 +1370,10 @@ Away:
* for failure.
*/
static int
-initialize_controlvm_payload_info(HOSTADDRESS phys_addr, U64 offset, U32 bytes,
+initialize_controlvm_payload_info(HOSTADDRESS phys_addr, u64 offset, u32 bytes,
CONTROLVM_PAYLOAD_INFO *info)
{
- U8 __iomem *payload = NULL;
+ u8 __iomem *payload = NULL;
int rc = CONTROLVM_RESP_SUCCESS;
if (info == NULL) {
@@ -1408,8 +1427,8 @@ static void
initialize_controlvm_payload(void)
{
HOSTADDRESS phys_addr = visorchannel_get_physaddr(ControlVm_channel);
- U64 payloadOffset = 0;
- U32 payloadBytes = 0;
+ u64 payloadOffset = 0;
+ u32 payloadBytes = 0;
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
RequestPayloadOffset),
@@ -1657,7 +1676,7 @@ parahotplug_process_list(void)
* respond to the CONTROLVM message with success.
*/
static int
-parahotplug_request_complete(int id, U16 active)
+parahotplug_request_complete(int id, u16 active)
{
struct list_head *pos = NULL;
struct list_head *tmp = NULL;
@@ -1733,53 +1752,6 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg)
}
}
-/*
- * Gets called when the udev script writes to
- * /proc/visorchipset/parahotplug. Expects input in the form of "<id>
- * <active>" where <id> is the identifier passed to the script that
- * matches a request on the request list, and <active> is 0 or 1
- * indicating whether the device is now enabled or not.
- */
-static ssize_t
-parahotplug_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char buf[64];
- uint id;
- ushort active;
-
- if (count > sizeof(buf) - 1) {
- LOGERR("parahotplug_proc_write: count (%d) exceeds size of buffer (%d)",
- (int) count, (int) sizeof(buf));
- return -EINVAL;
- }
- if (copy_from_user(buf, buffer, count)) {
- LOGERR("parahotplug_proc_write: copy_from_user failed");
- return -EFAULT;
- }
- buf[count] = '\0';
-
- if (sscanf(buf, "%u %hu", &id, &active) != 2) {
- id = 0;
- active = 0;
- }
-
- if (active != 1 && active != 0) {
- LOGERR("parahotplug_proc_write: invalid active field");
- return -EINVAL;
- }
-
- parahotplug_request_complete((int) id, (U16) active);
-
- return count;
-}
-
-static const struct file_operations parahotplug_proc_fops = {
- .owner = THIS_MODULE,
- .read = visorchipset_proc_read_writeonly,
- .write = parahotplug_proc_write,
-};
-
/* Process a controlvm message.
* Return result:
* FALSE - this function will return FALSE only in the case where the
@@ -1795,8 +1767,8 @@ static BOOL
handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr)
{
CONTROLVM_MESSAGE_PACKET *cmd = &inmsg.cmd;
- U64 parametersAddr = 0;
- U32 parametersBytes = 0;
+ u64 parametersAddr = 0;
+ u32 parametersBytes = 0;
PARSER_CONTEXT *parser_ctx = NULL;
BOOL isLocalAddr = FALSE;
CONTROLVM_MESSAGE ackmsg;
@@ -1929,15 +1901,28 @@ handle_command(CONTROLVM_MESSAGE inmsg, HOSTADDRESS channel_addr)
return TRUE;
}
+static HOSTADDRESS controlvm_get_channel_address(void)
+{
+ u64 addr = 0;
+ u32 size = 0;
+
+ if (!VMCALL_SUCCESSFUL(Issue_VMCALL_IO_CONTROLVM_ADDR(&addr, &size))) {
+ ERRDRV("%s - vmcall to determine controlvm channel addr failed",
+ __func__);
+ return 0;
+ }
+ INFODRV("controlvm addr=%Lx", addr);
+ return addr;
+}
+
static void
controlvm_periodic_work(struct work_struct *work)
{
VISORCHIPSET_CHANNEL_INFO chanInfo;
CONTROLVM_MESSAGE inmsg;
- char s[99];
BOOL gotACommand = FALSE;
BOOL handle_command_failed = FALSE;
- static U64 Poll_Count;
+ static u64 Poll_Count;
/* make sure visorbus server is registered for controlvm callbacks */
if (visorchipset_serverregwait && !serverregistered)
@@ -1949,32 +1934,9 @@ controlvm_periodic_work(struct work_struct *work)
goto Away;
memset(&chanInfo, 0, sizeof(VISORCHIPSET_CHANNEL_INFO));
- if (!ControlVm_channel) {
- HOSTADDRESS addr = controlvm_get_channel_address();
- if (addr != 0) {
- ControlVm_channel =
- visorchannel_create_with_lock
- (addr,
- sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
- UltraControlvmChannelProtocolGuid);
- if (ControlVm_channel == NULL)
- LOGERR("failed to create controlvm channel");
- else if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
- (visorchannel_get_header(ControlVm_channel),
- NULL)) {
- LOGINF("Channel %s (ControlVm) discovered",
- visorchannel_id(ControlVm_channel, s));
- initialize_controlvm_payload();
- } else {
- LOGERR("controlvm channel is invalid");
- visorchannel_destroy(ControlVm_channel);
- ControlVm_channel = NULL;
- }
- }
- }
Poll_Count++;
- if ((ControlVm_channel != NULL) || (Poll_Count >= 250))
+ if (Poll_Count >= 250)
; /* keep going */
else
goto Away;
@@ -1993,54 +1955,46 @@ controlvm_periodic_work(struct work_struct *work)
}
}
- if (ControlVm_channel) {
- while (visorchannel_signalremove(ControlVm_channel,
- CONTROLVM_QUEUE_RESPONSE,
- &inmsg)) {
- if (inmsg.hdr.PayloadMaxBytes != 0) {
- LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
- (ulong) inmsg.hdr.PayloadMaxBytes,
- (ulong) inmsg.hdr.PayloadVmOffset,
- inmsg.hdr.Id);
- }
- }
- if (!gotACommand) {
- if (ControlVm_Pending_Msg_Valid) {
- /* we throttled processing of a prior
- * msg, so try to process it again
- * rather than reading a new one
- */
- inmsg = ControlVm_Pending_Msg;
- ControlVm_Pending_Msg_Valid = FALSE;
- gotACommand = TRUE;
- } else
- gotACommand = read_controlvm_event(&inmsg);
+ while (visorchannel_signalremove(ControlVm_channel,
+ CONTROLVM_QUEUE_RESPONSE,
+ &inmsg)) {
+ if (inmsg.hdr.PayloadMaxBytes != 0) {
+ LOGERR("Payload of size %lu returned @%lu with unexpected message id %d.",
+ (ulong) inmsg.hdr.PayloadMaxBytes,
+ (ulong) inmsg.hdr.PayloadVmOffset,
+ inmsg.hdr.Id);
}
}
+ if (!gotACommand) {
+ if (ControlVm_Pending_Msg_Valid) {
+ /* we throttled processing of a prior
+ * msg, so try to process it again
+ * rather than reading a new one
+ */
+ inmsg = ControlVm_Pending_Msg;
+ ControlVm_Pending_Msg_Valid = FALSE;
+ gotACommand = TRUE;
+ } else
+ gotACommand = read_controlvm_event(&inmsg);
+ }
handle_command_failed = FALSE;
while (gotACommand && (!handle_command_failed)) {
Most_recent_message_jiffies = jiffies;
- if (ControlVm_channel) {
- if (handle_command(inmsg,
- visorchannel_get_physaddr
- (ControlVm_channel)))
- gotACommand = read_controlvm_event(&inmsg);
- else {
- /* this is a scenario where throttling
- * is required, but probably NOT an
- * error...; we stash the current
- * controlvm msg so we will attempt to
- * reprocess it on our next loop
- */
- handle_command_failed = TRUE;
- ControlVm_Pending_Msg = inmsg;
- ControlVm_Pending_Msg_Valid = TRUE;
- }
-
- } else {
- handle_command(inmsg, 0);
- gotACommand = FALSE;
+ if (handle_command(inmsg,
+ visorchannel_get_physaddr
+ (ControlVm_channel)))
+ gotACommand = read_controlvm_event(&inmsg);
+ else {
+ /* this is a scenario where throttling
+ * is required, but probably NOT an
+ * error...; we stash the current
+ * controlvm msg so we will attempt to
+ * reprocess it on our next loop
+ */
+ handle_command_failed = TRUE;
+ ControlVm_Pending_Msg = inmsg;
+ ControlVm_Pending_Msg_Valid = TRUE;
}
}
@@ -2077,9 +2031,8 @@ setup_crash_devices_work_queue(struct work_struct *work)
CONTROLVM_MESSAGE localCrashCreateBusMsg;
CONTROLVM_MESSAGE localCrashCreateDevMsg;
CONTROLVM_MESSAGE msg;
- HOSTADDRESS host_addr;
- U32 localSavedCrashMsgOffset;
- U16 localSavedCrashMsgCount;
+ u32 localSavedCrashMsgOffset;
+ u16 localSavedCrashMsgCount;
/* make sure visorbus server is registered for controlvm callbacks */
if (visorchipset_serverregwait && !serverregistered)
@@ -2100,31 +2053,11 @@ setup_crash_devices_work_queue(struct work_struct *work)
chipset_init(&msg);
- host_addr = controlvm_get_channel_address();
- if (!host_addr) {
- LOGERR("Huh? Host address is NULL");
- POSTCODE_LINUX_2(CRASH_DEV_HADDR_NULL, POSTCODE_SEVERITY_ERR);
- return;
- }
-
- ControlVm_channel =
- visorchannel_create_with_lock
- (host_addr,
- sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
- UltraControlvmChannelProtocolGuid);
-
- if (ControlVm_channel == NULL) {
- LOGERR("failed to create controlvm channel");
- POSTCODE_LINUX_2(CRASH_DEV_CONTROLVM_NULL,
- POSTCODE_SEVERITY_ERR);
- return;
- }
-
/* get saved message count */
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
SavedCrashMsgCount),
- &localSavedCrashMsgCount, sizeof(U16)) < 0) {
+ &localSavedCrashMsgCount, sizeof(u16)) < 0) {
LOGERR("failed to get Saved Message Count");
POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
POSTCODE_SEVERITY_ERR);
@@ -2144,7 +2077,7 @@ setup_crash_devices_work_queue(struct work_struct *work)
if (visorchannel_read(ControlVm_channel,
offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
SavedCrashMsgOffset),
- &localSavedCrashMsgOffset, sizeof(U32)) < 0) {
+ &localSavedCrashMsgOffset, sizeof(u32)) < 0) {
LOGERR("failed to get Saved Message Offset");
POSTCODE_LINUX_2(CRASH_DEV_CTRL_RD_FAILURE_PC,
POSTCODE_SEVERITY_ERR);
@@ -2343,357 +2276,62 @@ visorchipset_cache_free(struct kmem_cache *pool, void *p, char *fn, int ln)
kmem_cache_free(pool, p);
}
-#define gettoken(bufp) strsep(bufp, " -\t\n")
-
-static ssize_t
-chipset_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t chipsetready_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- char buf[512];
- char *token, *p;
+ char msgtype[64];
- if (count > sizeof(buf) - 1) {
- LOGERR("chipset_proc_write: count (%d) exceeds size of buffer (%d)",
- (int) count, (int) sizeof(buffer));
+ if (sscanf(buf, "%63s", msgtype) != 1)
return -EINVAL;
- }
- if (copy_from_user(buf, buffer, count)) {
- LOGERR("chipset_proc_write: copy_from_user failed");
- return -EFAULT;
- }
- buf[count] = '\0';
-
- p = buf;
- token = gettoken(&p);
-
- if (strcmp(token, "CALLHOMEDISK_MOUNTED") == 0) {
- token = gettoken(&p);
- /* The Call Home Disk has been mounted */
- if (strcmp(token, "0") == 0)
- chipset_events[0] = 1;
- } else if (strcmp(token, "MODULES_LOADED") == 0) {
- token = gettoken(&p);
- /* All modules for the partition have been loaded */
- if (strcmp(token, "0") == 0)
- chipset_events[1] = 1;
- } else if (token == NULL) {
- /* No event specified */
- LOGERR("No event was specified to send CHIPSET_READY response");
- return -1;
- } else {
- /* Unsupported event specified */
- LOGERR("%s is an invalid event for sending CHIPSET_READY response", token);
- return -1;
- }
-
- return count;
-}
-
-static ssize_t
-visorchipset_proc_read_writeonly(struct file *file, char __user *buf,
- size_t len, loff_t *offset)
-{
- return 0;
-}
-/**
- * Reads the InstallationError, InstallationTextId,
- * InstallationRemainingSteps fields of ControlVMChannel.
- */
-static ssize_t
-proc_read_installer(struct file *file, char __user *buf,
- size_t len, loff_t *offset)
-{
- int length = 0;
- U16 remainingSteps;
- U32 error, textId;
- char *vbuf;
- loff_t pos = *offset;
-
- if (!ControlVm_channel)
- return -ENODEV;
-
- if (pos < 0)
- return -EINVAL;
-
- if (pos > 0 || !len)
- return 0;
-
- vbuf = kzalloc(len, GFP_KERNEL);
- if (!vbuf)
- return -ENOMEM;
-
- visorchannel_read(ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationRemainingSteps), &remainingSteps,
- sizeof(U16));
- visorchannel_read(ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationError), &error, sizeof(U32));
- visorchannel_read(ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationTextId), &textId, sizeof(U32));
-
- length = sprintf(vbuf, "%u %u %u\n", remainingSteps, error, textId);
- if (copy_to_user(buf, vbuf, length)) {
- kfree(vbuf);
- return -EFAULT;
- }
-
- kfree(vbuf);
- *offset += length;
- return length;
-}
-
-/**
- * Writes to the InstallationError, InstallationTextId,
- * InstallationRemainingSteps fields of
- * ControlVMChannel.
- * Input: RemainingSteps Error TextId
- * Limit 32 characters input
- */
-#define UINT16_MAX (65535U)
-#define UINT32_MAX (4294967295U)
-static ssize_t
-proc_write_installer(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char buf[32];
- U16 remainingSteps;
- U32 error, textId;
-
- if (!ControlVm_channel)
- return -ENODEV;
-
- /* Check to make sure there is no buffer overflow */
- if (count > (sizeof(buf) - 1))
- return -EINVAL;
-
- if (copy_from_user(buf, buffer, count)) {
- WARN(1, "Error copying from user space\n");
- return -EFAULT;
- }
-
- if (sscanf(buf, "%hu %i %i", &remainingSteps, &error, &textId) != 3) {
- remainingSteps = UINT16_MAX;
- error = UINT32_MAX;
- textId = UINT32_MAX;
- }
-
- if (remainingSteps != UINT16_MAX) {
- if (visorchannel_write
- (ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationRemainingSteps), &remainingSteps,
- sizeof(U16)) < 0)
- WARN(1, "Installation Status Write Failed - Write function error - RemainingSteps = %d\n",
- remainingSteps);
- }
-
- if (error != UINT32_MAX) {
- if (visorchannel_write
- (ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationError), &error, sizeof(U32)) < 0)
- WARN(1, "Installation Status Write Failed - Write function error - Error = %d\n",
- error);
- }
-
- if (textId != UINT32_MAX) {
- if (visorchannel_write
- (ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- InstallationTextId), &textId, sizeof(U32)) < 0)
- WARN(1, "Installation Status Write Failed - Write function error - TextId = %d\n",
- textId);
- }
-
- /* So this function isn't called multiple times, must return
- * size of buffer
- */
- return count;
-}
-
-/**
- * Reads the ToolAction field of ControlVMChannel.
- */
-static ssize_t
-proc_read_toolaction(struct file *file, char __user *buf,
- size_t len, loff_t *offset)
-{
- int length = 0;
- U8 toolAction;
- char *vbuf;
- loff_t pos = *offset;
-
- if (!ControlVm_channel)
- return -ENODEV;
-
- if (pos < 0)
+ if (strcmp(msgtype, "CALLHOMEDISK_MOUNTED") == 0) {
+ chipset_events[0] = 1;
+ return count;
+ } else if (strcmp(msgtype, "MODULES_LOADED") == 0) {
+ chipset_events[1] = 1;
+ return count;
+ } else
return -EINVAL;
-
- if (pos > 0 || !len)
- return 0;
-
- vbuf = kzalloc(len, GFP_KERNEL);
- if (!vbuf)
- return -ENOMEM;
-
- visorchannel_read(ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- ToolAction), &toolAction, sizeof(U8));
-
- length = sprintf(vbuf, "%u\n", toolAction);
- if (copy_to_user(buf, vbuf, length)) {
- kfree(vbuf);
- return -EFAULT;
- }
-
- kfree(vbuf);
- *offset += length;
- return length;
}
-/**
- * Writes to the ToolAction field of ControlVMChannel.
- * Input: ToolAction
- * Limit 3 characters input
+/* The parahotplug/devicedisabled interface gets called by our support script
+ * when an SR-IOV device has been shut down. The ID is passed to the script
+ * and then passed back when the device has been removed.
*/
-#define UINT8_MAX (255U)
-static ssize_t
-proc_write_toolaction(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
+static ssize_t devicedisabled_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- char buf[3];
- U8 toolAction;
-
- if (!ControlVm_channel)
- return -ENODEV;
+ uint id;
- /* Check to make sure there is no buffer overflow */
- if (count > (sizeof(buf) - 1))
+ if (kstrtouint(buf, 10, &id) != 0)
return -EINVAL;
- if (copy_from_user(buf, buffer, count)) {
- WARN(1, "Error copying from user space\n");
- return -EFAULT;
- }
-
- if (sscanf(buf, "%hhd", &toolAction) != 1)
- toolAction = UINT8_MAX;
-
- if (toolAction != UINT8_MAX) {
- if (visorchannel_write
- (ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, ToolAction),
- &toolAction, sizeof(U8)) < 0)
- WARN(1, "Installation ToolAction Write Failed - ToolAction = %d\n",
- toolAction);
- }
-
- /* So this function isn't called multiple times, must return
- * size of buffer
- */
+ parahotplug_request_complete(id, 0);
return count;
}
-/**
- * Reads the EfiSparIndication.BootToTool field of ControlVMChannel.
- */
-static ssize_t
-proc_read_bootToTool(struct file *file, char __user *buf,
- size_t len, loff_t *offset)
-{
- int length = 0;
- ULTRA_EFI_SPAR_INDICATION efiSparIndication;
- char *vbuf;
- loff_t pos = *offset;
-
- if (!ControlVm_channel)
- return -ENODEV;
-
- if (pos < 0)
- return -EINVAL;
-
- if (pos > 0 || !len)
- return 0;
-
- vbuf = kzalloc(len, GFP_KERNEL);
- if (!vbuf)
- return -ENOMEM;
-
- visorchannel_read(ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL,
- EfiSparIndication), &efiSparIndication,
- sizeof(ULTRA_EFI_SPAR_INDICATION));
-
- length = sprintf(vbuf, "%d\n", (int) efiSparIndication.BootToTool);
- if (copy_to_user(buf, vbuf, length)) {
- kfree(vbuf);
- return -EFAULT;
- }
-
- kfree(vbuf);
- *offset += length;
- return length;
-}
-
-/**
- * Writes to the EfiSparIndication.BootToTool field of ControlVMChannel.
- * Input: 1 or 0 (1 being on, 0 being off)
+/* The parahotplug/deviceenabled interface gets called by our support script
+ * when an SR-IOV device has been recovered. The ID is passed to the script
+ * and then passed back when the device has been brought back up.
*/
-static ssize_t
-proc_write_bootToTool(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
+static ssize_t deviceenabled_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
{
- char buf[3];
- int inputVal;
- ULTRA_EFI_SPAR_INDICATION efiSparIndication;
-
- if (!ControlVm_channel)
- return -ENODEV;
+ uint id;
- /* Check to make sure there is no buffer overflow */
- if (count > (sizeof(buf) - 1))
+ if (kstrtouint(buf, 10, &id) != 0)
return -EINVAL;
- if (copy_from_user(buf, buffer, count)) {
- WARN(1, "Error copying from user space\n");
- return -EFAULT;
- }
-
- if (sscanf(buf, "%i", &inputVal) != 1)
- inputVal = 0;
-
- efiSparIndication.BootToTool = (inputVal == 1 ? 1 : 0);
-
- if (visorchannel_write
- (ControlVm_channel,
- offsetof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL, EfiSparIndication),
- &efiSparIndication, sizeof(ULTRA_EFI_SPAR_INDICATION)) < 0)
- printk
- ("Installation BootToTool Write Failed - BootToTool = %d\n",
- (int) efiSparIndication.BootToTool);
-
- /* So this function isn't called multiple times, must return
- * size of buffer
- */
+ parahotplug_request_complete(id, 1);
return count;
}
-static const struct file_operations chipset_proc_fops = {
- .owner = THIS_MODULE,
- .read = visorchipset_proc_read_writeonly,
- .write = chipset_proc_write,
-};
-
static int __init
visorchipset_init(void)
{
int rc = 0, x = 0;
- struct proc_dir_entry *installer_file;
- struct proc_dir_entry *toolaction_file;
- struct proc_dir_entry *bootToTool_file;
+ char s[64];
+ HOSTADDRESS addr;
if (!unisys_spar_platform)
return -ENODEV;
@@ -2725,7 +2363,30 @@ visorchipset_init(void)
goto Away;
}
- controlvm_init();
+ addr = controlvm_get_channel_address();
+ if (addr != 0) {
+ ControlVm_channel =
+ visorchannel_create_with_lock
+ (addr,
+ sizeof(ULTRA_CONTROLVM_CHANNEL_PROTOCOL),
+ UltraControlvmChannelProtocolGuid);
+ if (ULTRA_CONTROLVM_CHANNEL_OK_CLIENT
+ (visorchannel_get_header(ControlVm_channel),
+ NULL)) {
+ LOGINF("Channel %s (ControlVm) discovered",
+ visorchannel_id(ControlVm_channel, s));
+ initialize_controlvm_payload();
+ } else {
+ LOGERR("controlvm channel is invalid");
+ visorchannel_destroy(ControlVm_channel);
+ ControlVm_channel = NULL;
+ return -ENODEV;
+ }
+ } else {
+ LOGERR("no controlvm channel discovered");
+ return -ENODEV;
+ }
+
MajorDev = MKDEV(visorchipset_major, 0);
rc = visorchipset_file_init(MajorDev, &ControlVm_channel);
if (rc < 0) {
@@ -2734,42 +2395,10 @@ visorchipset_init(void)
goto Away;
}
- proc_Init();
- memset(PartitionPropertyNames, 0, sizeof(PartitionPropertyNames));
- memset(ControlVmPropertyNames, 0, sizeof(ControlVmPropertyNames));
- InitPartitionProperties();
- InitControlVmProperties();
-
- PartitionType = visor_proc_CreateType(ProcDir, PartitionTypeNames,
- (const char **)
- PartitionPropertyNames,
- &show_partition_property);
- ControlVmType =
- visor_proc_CreateType(ProcDir, ControlVmTypeNames,
- (const char **) ControlVmPropertyNames,
- &show_controlvm_property);
-
- ControlVmObject = visor_proc_CreateObject(ControlVmType, NULL, NULL);
-
- /* Setup Installation fields */
- installer_file = proc_create("installer", 0644, ProcDir,
- &proc_installer_fops);
- /* Setup the ToolAction field */
- toolaction_file = proc_create("toolaction", 0644, ProcDir,
- &proc_toolaction_fops);
- /* Setup the BootToTool field */
- bootToTool_file = proc_create("boottotool", 0644, ProcDir,
- &proc_bootToTool_fops);
-
memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
- chipset_proc_dir = proc_create(VISORCHIPSET_CHIPSET_PROC_ENTRY_FN,
- 0644, ProcDir, &chipset_proc_fops);
memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
- parahotplug_proc_dir =
- proc_create(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN, 0200,
- ProcDir, &parahotplug_proc_fops);
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
Putfile_buffer_list_pool =
@@ -2855,48 +2484,19 @@ visorchipset_exit(void)
kmem_cache_destroy(Putfile_buffer_list_pool);
Putfile_buffer_list_pool = NULL;
}
- if (ControlVmObject) {
- visor_proc_DestroyObject(ControlVmObject);
- ControlVmObject = NULL;
- }
+
cleanup_controlvm_structures();
- if (ControlVmType) {
- visor_proc_DestroyType(ControlVmType);
- ControlVmType = NULL;
- }
- if (PartitionType) {
- visor_proc_DestroyType(PartitionType);
- PartitionType = NULL;
- }
- if (diag_proc_dir) {
- remove_proc_entry(VISORCHIPSET_DIAG_PROC_ENTRY_FN, ProcDir);
- diag_proc_dir = NULL;
- }
memset(&g_DiagMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
- if (chipset_proc_dir) {
- remove_proc_entry(VISORCHIPSET_CHIPSET_PROC_ENTRY_FN, ProcDir);
- chipset_proc_dir = NULL;
- }
memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
- if (parahotplug_proc_dir) {
- remove_proc_entry(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN,
- ProcDir);
- parahotplug_proc_dir = NULL;
- }
-
memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
- proc_DeInit();
- if (ControlVm_channel != NULL) {
- LOGINF("Channel %s (ControlVm) disconnected",
- visorchannel_id(ControlVm_channel, s));
- visorchannel_destroy(ControlVm_channel);
- ControlVm_channel = NULL;
- }
- controlvm_deinit();
+ LOGINF("Channel %s (ControlVm) disconnected",
+ visorchannel_id(ControlVm_channel, s));
+ visorchannel_destroy(ControlVm_channel);
+
visorchipset_file_cleanup();
POSTCODE_LINUX_2(DRIVER_EXIT_PC, POSTCODE_SEVERITY_INFO);
LOGINF("chipset driver unloaded");
diff --git a/drivers/staging/unisys/visorutil/Makefile b/drivers/staging/unisys/visorutil/Makefile
index 3f463888dcec..d871bbb78cef 100644
--- a/drivers/staging/unisys/visorutil/Makefile
+++ b/drivers/staging/unisys/visorutil/Makefile
@@ -8,4 +8,3 @@ visorutil-y := charqueue.o easyproc.o periodic_work.o procobjecttree.o \
memregion_direct.o visorkmodutils.o
ccflags-y += -Idrivers/staging/unisys/include
-ccflags-y += -DCONFIG_SPAR_GUEST -DGUESTDRIVERBUILD -DNOAUTOVERSION
diff --git a/drivers/staging/unisys/visorutil/memregion_direct.c b/drivers/staging/unisys/visorutil/memregion_direct.c
index 28dfba0490f2..65bc07b947db 100644
--- a/drivers/staging/unisys/visorutil/memregion_direct.c
+++ b/drivers/staging/unisys/visorutil/memregion_direct.c
@@ -184,7 +184,7 @@ memregion_readwrite(BOOL is_write,
{
if (offset + nbytes > memregion->nbytes) {
ERRDRV("memregion_readwrite offset out of range!!");
- return -EFAULT;
+ return -EIO;
}
if (is_write)
memcpy_toio(memregion->mapped + offset, local, nbytes);
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
index 9c5832abbdf1..44ab43fc4fcc 100644
--- a/drivers/staging/usbip/stub_main.c
+++ b/drivers/staging/usbip/stub_main.c
@@ -94,7 +94,7 @@ static int add_match_busid(char *busid)
for (i = 0; i < MAX_BUSID; i++)
if (!busid_table[i].name[0]) {
- strncpy(busid_table[i].name, busid, BUSID_SIZE);
+ strlcpy(busid_table[i].name, busid, BUSID_SIZE);
if ((busid_table[i].status != STUB_BUSID_ALLOC) &&
(busid_table[i].status != STUB_BUSID_REMOV))
busid_table[i].status = STUB_BUSID_ADDED;
@@ -158,15 +158,11 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
if (count < 5)
return -EINVAL;
- /* strnlen() does not include \0 */
- len = strnlen(buf + 4, BUSID_SIZE);
-
/* busid needs to include \0 termination */
- if (!(len < BUSID_SIZE))
+ len = strlcpy(busid, buf + 4, BUSID_SIZE);
+ if (sizeof(busid) <= len)
return -EINVAL;
- strncpy(busid, buf + 4, BUSID_SIZE);
-
if (!strncmp(buf, "add ", 4)) {
if (add_match_busid(busid) < 0)
return -ENOMEM;
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index e0b6d6b42728..00e475c51a12 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -529,7 +529,6 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
}
usbip_dbg_stub_rx("Leave\n");
- return;
}
/* recv a pdu */
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
index 92caef7474c7..bef08d5c44e8 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
@@ -47,7 +47,8 @@ static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
udev->path);
- if ((fd = open(status_attr_path, O_RDONLY)) < 0) {
+ fd = open(status_attr_path, O_RDONLY);
+ if (fd < 0) {
err("error opening attribute %s", status_attr_path);
return -1;
}
@@ -87,8 +88,8 @@ struct usbip_exported_device *usbip_exported_device_new(const char *sdevpath)
goto err;
/* reallocate buffer to include usb interface data */
- size = sizeof(struct usbip_exported_device) + edev->udev.bNumInterfaces *
- sizeof(struct usbip_usb_interface);
+ size = sizeof(struct usbip_exported_device) +
+ edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface);
edev_old = edev;
edev = realloc(edev, size);
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 0007d30e45bd..c02374b6049c 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -304,7 +304,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
break;
case GetHubStatus:
usbip_dbg_vhci_rh(" GetHubStatus\n");
- *(__le32 *) buf = __constant_cpu_to_le32(0);
+ *(__le32 *) buf = cpu_to_le32(0);
break;
case GetPortStatus:
usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
@@ -1121,7 +1121,6 @@ static struct platform_driver vhci_driver = {
*/
static void the_pdev_release(struct device *dev)
{
- return;
}
static struct platform_device the_pdev = {
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index d07fcb5ee93a..00e4a54308e4 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -111,8 +111,6 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
usbip_dbg_vhci_rx("Leave\n");
-
- return;
}
static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
index fd19c257f533..84c5a07e8f6a 100644
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -182,30 +182,30 @@ static int pio2_match(struct vme_dev *vdev)
if (vdev->num >= bus_num) {
dev_err(&vdev->dev,
- "The enumeration of the VMEbus to which the board is connected must be specified");
+ "The enumeration of the VMEbus to which the board is connected must be specified\n");
return 0;
}
if (vdev->num >= base_num) {
dev_err(&vdev->dev,
- "The VME address for the cards registers must be specified");
+ "The VME address for the cards registers must be specified\n");
return 0;
}
if (vdev->num >= vector_num) {
dev_err(&vdev->dev,
- "The IRQ vector used by the card must be specified");
+ "The IRQ vector used by the card must be specified\n");
return 0;
}
if (vdev->num >= level_num) {
dev_err(&vdev->dev,
- "The IRQ level used by the card must be specified");
+ "The IRQ level used by the card must be specified\n");
return 0;
}
if (vdev->num >= variant_num) {
- dev_err(&vdev->dev, "The variant of the card must be specified");
+ dev_err(&vdev->dev, "The variant of the card must be specified\n");
return 0;
}
@@ -324,7 +324,7 @@ static int pio2_probe(struct vme_dev *vdev)
retval = pio2_reset_card(card);
if (retval) {
dev_err(&card->vdev->dev,
- "Failed to reset card, is location valid?");
+ "Failed to reset card, is location valid?\n");
retval = -ENODEV;
goto err_reset;
}
diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c
index 2a2d920d980b..f00af0786af3 100644
--- a/drivers/staging/vme/devices/vme_pio2_gpio.c
+++ b/drivers/staging/vme/devices/vme_pio2_gpio.c
@@ -108,7 +108,7 @@ static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
dev_err(&card->vdev->dev,
- "Channel directionality not configurable at runtine\n");
+ "Channel directionality not configurable at runtime\n");
data = -EINVAL;
} else {
@@ -127,7 +127,7 @@ static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
dev_err(&card->vdev->dev,
- "Channel directionality not configurable at runtine\n");
+ "Channel directionality not configurable at runtime\n");
data = -EINVAL;
} else {
@@ -222,7 +222,7 @@ void pio2_gpio_exit(struct pio2_card *card)
const char *label = card->gc.label;
if (gpiochip_remove(&(card->gc)))
- dev_err(&card->vdev->dev, "Failed to remove GPIO");
+ dev_err(&card->vdev->dev, "Failed to remove GPIO\n");
kfree(label);
}
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 2d8497277aae..920e50addd3e 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -433,7 +433,6 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
default:
mutex_unlock(&image[minor].mutex);
return -EINVAL;
- break;
}
if ((absolute < 0) || (absolute >= image_size)) {
@@ -511,7 +510,6 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
}
return retval;
- break;
case VME_SET_MASTER:
@@ -552,7 +550,6 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,
}
return retval;
- break;
case VME_SET_SLAVE:
@@ -806,7 +803,6 @@ static int vme_user_probe(struct vme_dev *vdev)
default:
err = -EINVAL;
goto err_sysfs;
- break;
}
num = (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i;
diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h
index ba155cdded2f..e05d13544ea2 100644
--- a/drivers/staging/vt6655/80211hdr.h
+++ b/drivers/staging/vt6655/80211hdr.h
@@ -33,7 +33,6 @@
#include "ttype.h"
-/*--------------------- Export Definitions -------------------------*/
/* bit type */
#define BIT0 0x00000001
#define BIT1 0x00000002
@@ -315,10 +314,4 @@ typedef union tagUWLAN_80211HDR {
WLAN_80211HDR_A4 sA4;
} UWLAN_80211HDR, *PUWLAN_80211HDR;
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
#endif /* __80211HDR_H__ */
diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c
index 9aa2e46c4a5d..96b0d61623e4 100644
--- a/drivers/staging/vt6655/80211mgr.c
+++ b/drivers/staging/vt6655/80211mgr.c
@@ -102,8 +102,6 @@ vMgrEncodeBeacon(
WLAN_BEACON_OFF_CAPINFO);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID;
-
- return;
}
/*+
@@ -228,8 +226,6 @@ vMgrDecodeBeacon(
}
pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
}
-
- return;
}
/*+
@@ -250,8 +246,6 @@ vMgrEncodeIBSSATIM(
{
pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
pFrame->len = WLAN_HDR_ADDR3_LEN;
-
- return;
}
/*+
@@ -271,8 +265,6 @@ vMgrDecodeIBSSATIM(
)
{
pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- return;
}
/*+
@@ -299,8 +291,6 @@ vMgrEncodeDisassociation(
WLAN_DISASSOC_OFF_REASON);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON +
sizeof(*(pFrame->pwReason));
-
- return;
}
/*+
@@ -325,8 +315,6 @@ vMgrDecodeDisassociation(
pFrame->pwReason = (unsigned short *)
(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
WLAN_DISASSOC_OFF_REASON);
-
- return;
}
/*+
@@ -355,7 +343,6 @@ vMgrEncodeAssocRequest(
WLAN_ASSOCREQ_OFF_LISTEN_INT);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT +
sizeof(*(pFrame->pwListenInterval));
- return;
}
/*+
@@ -426,7 +413,6 @@ vMgrDecodeAssocRequest(
}
pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
}
- return;
}
/*+
@@ -459,8 +445,6 @@ vMgrEncodeAssocResponse(
WLAN_ASSOCRESP_OFF_AID);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID +
sizeof(*(pFrame->pwAid));
-
- return;
}
/*+
@@ -511,7 +495,6 @@ vMgrDecodeAssocResponse(
} else {
pFrame->pExtSuppRates = NULL;
}
- return;
}
/*+
@@ -544,8 +527,6 @@ vMgrEncodeReassocRequest(
WLAN_REASSOCREQ_OFF_CURR_AP);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP +
sizeof(*(pFrame->pAddrCurrAP));
-
- return;
}
/*+
@@ -565,6 +546,7 @@ vMgrDecodeReassocRequest(
)
{
PWLAN_IE pItem;
+
pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
/* Fixed Fields */
@@ -619,7 +601,6 @@ vMgrDecodeReassocRequest(
}
pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
}
- return;
}
/*+
@@ -640,7 +621,6 @@ vMgrEncodeProbeRequest(
{
pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
pFrame->len = WLAN_HDR_ADDR3_LEN;
- return;
}
/*+
@@ -694,7 +674,6 @@ vMgrDecodeProbeRequest(
pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
}
- return;
}
/*+
@@ -728,8 +707,6 @@ vMgrEncodeProbeResponse(
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
sizeof(*(pFrame->pwCapInfo));
-
- return;
}
/*+
@@ -850,7 +827,6 @@ vMgrDecodeProbeResponse(
pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len);
}
- return;
}
/*+
@@ -883,8 +859,6 @@ vMgrEncodeAuthen(
WLAN_AUTHEN_OFF_STATUS);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS +
sizeof(*(pFrame->pwStatus));
-
- return;
}
/*+
@@ -925,8 +899,6 @@ vMgrDecodeAuthen(
if (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) &&
pItem->byElementID == WLAN_EID_CHALLENGE)
pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-
- return;
}
/*+
@@ -953,8 +925,6 @@ vMgrEncodeDeauthen(
WLAN_DEAUTHEN_OFF_REASON);
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON +
sizeof(*(pFrame->pwReason));
-
- return;
}
/*+
@@ -979,8 +949,6 @@ vMgrDecodeDeauthen(
pFrame->pwReason = (unsigned short *)
(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
WLAN_DEAUTHEN_OFF_REASON);
-
- return;
}
/*+
@@ -1014,8 +982,6 @@ vMgrEncodeReassocResponse(
pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID +
sizeof(*(pFrame->pwAid));
-
- return;
}
/*+
@@ -1061,5 +1027,4 @@ vMgrDecodeReassocResponse(
(pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
}
- return;
}
diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h
index 065238beb4f4..8b126bbd9fa5 100644
--- a/drivers/staging/vt6655/80211mgr.h
+++ b/drivers/staging/vt6655/80211mgr.h
@@ -34,8 +34,6 @@
#include "ttype.h"
#include "80211hdr.h"
-/*--------------------- Export Definitions -------------------------*/
-
#define WLAN_MIN_ARRAY 1
/* Information Element ID value */
@@ -202,12 +200,6 @@
#define MEASURE_MODE_INCAPABLE 0x02
#define MEASURE_MODE_REFUSED 0x04
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
/* Information Element Types */
#pragma pack(1)
@@ -472,14 +464,11 @@ typedef struct tagWLAN_FR_BEACON {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /* fixed fields */
PQWORD pqwTimestamp;
unsigned short *pwBeaconInterval;
unsigned short *pwCapInfo;
- /*-- info elements ----------*/
PWLAN_IE_SSID pSSID;
PWLAN_IE_SUPP_RATES pSuppRates;
-/* PWLAN_IE_FH_PARMS pFHParms; */
PWLAN_IE_DS_PARMS pDSParms;
PWLAN_IE_CF_PARMS pCFParms;
PWLAN_IE_TIM pTIM;
@@ -501,10 +490,6 @@ typedef struct tagWLAN_FR_IBSSATIM {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
-
- /* fixed fields */
- /* info elements */
- /* this frame type has a null body */
} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM;
/* Disassociation */
@@ -513,9 +498,7 @@ typedef struct tagWLAN_FR_DISASSOC {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwReason;
- /*-- info elements ----------*/
} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
/* Association Request */
@@ -524,10 +507,8 @@ typedef struct tagWLAN_FR_ASSOCREQ {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwCapInfo;
unsigned short *pwListenInterval;
- /*-- info elements ----------*/
PWLAN_IE_SSID pSSID;
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_RSN pRSN;
@@ -543,11 +524,9 @@ typedef struct tagWLAN_FR_ASSOCRESP {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwCapInfo;
unsigned short *pwStatus;
unsigned short *pwAid;
- /*-- info elements ----------*/
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_SUPP_RATES pExtSuppRates;
} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP;
@@ -558,13 +537,9 @@ typedef struct tagWLAN_FR_REASSOCREQ {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
-
- /*-- fixed fields -----------*/
unsigned short *pwCapInfo;
unsigned short *pwListenInterval;
PIEEE_ADDR pAddrCurrAP;
-
- /*-- info elements ----------*/
PWLAN_IE_SSID pSSID;
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_RSN pRSN;
@@ -578,11 +553,9 @@ typedef struct tagWLAN_FR_REASSOCRESP {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwCapInfo;
unsigned short *pwStatus;
unsigned short *pwAid;
- /*-- info elements ----------*/
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_SUPP_RATES pExtSuppRates;
} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP;
@@ -593,8 +566,6 @@ typedef struct tagWLAN_FR_PROBEREQ {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
- /*-- info elements ----------*/
PWLAN_IE_SSID pSSID;
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_SUPP_RATES pExtSuppRates;
@@ -606,11 +577,9 @@ typedef struct tagWLAN_FR_PROBERESP {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
PQWORD pqwTimestamp;
unsigned short *pwBeaconInterval;
unsigned short *pwCapInfo;
- /*-- info elements ----------*/
PWLAN_IE_SSID pSSID;
PWLAN_IE_SUPP_RATES pSuppRates;
PWLAN_IE_DS_PARMS pDSParms;
@@ -633,11 +602,9 @@ typedef struct tagWLAN_FR_AUTHEN {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwAuthAlgorithm;
unsigned short *pwAuthSequence;
unsigned short *pwStatus;
- /*-- info elements ----------*/
PWLAN_IE_CHALLENGE pChallenge;
} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN;
@@ -647,14 +614,9 @@ typedef struct tagWLAN_FR_DEAUTHEN {
unsigned int len;
unsigned char *pBuf;
PUWLAN_80211HDR pHdr;
- /*-- fixed fields -----------*/
unsigned short *pwReason;
-
- /*-- info elements ----------*/
} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
-/*--------------------- Export Functions --------------------------*/
-
void
vMgrEncodeBeacon(
PWLAN_FR_BEACON pFrame
diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c
index 6cfad1c04026..180a27cc74d7 100644
--- a/drivers/staging/vt6655/IEEE11h.c
+++ b/drivers/staging/vt6655/IEEE11h.c
@@ -41,7 +41,6 @@
#include "channel.h"
/*--------------------- Static Definitions -------------------------*/
-static int msglevel = MSG_LEVEL_INFO;
#pragma pack(1)
@@ -98,185 +97,11 @@ typedef struct _WLAN_FRAME_TPCREP {
/*--------------------- Static Variables --------------------------*/
/*--------------------- Static Functions --------------------------*/
-static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq,
- unsigned int uLength)
-{
- size_t uNumOfEIDs = 0;
- bool bResult = true;
-
- if (uLength <= WLAN_A3FR_MAXLEN)
- memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
- uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ,
- sMSRReqEIDs))/
- (sizeof(WLAN_IE_MEASURE_REQ)));
- pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP)
- (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
- pMgmt->uLengthOfRepEIDs = 0;
- bResult = CARDbStartMeasure(pMgmt->pAdapter,
- ((PWLAN_FRAME_MSRREQ)
- (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
- uNumOfEIDs
-);
- return bResult;
-}
-
-static bool s_bRxTPCReq(PSMgmtObject pMgmt,
- PWLAN_FRAME_TPCREQ pTPCReq,
- unsigned char byRate,
- unsigned char byRSSI)
-{
- PWLAN_FRAME_TPCREP pFrame;
- PSTxMgmtPacket pTxPacket = NULL;
-
- pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket +
- sizeof(STxMgmtPacket));
-
- pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket +
- sizeof(STxMgmtPacket));
-
- pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
-);
-
- memcpy(pFrame->Header.abyAddr1,
- pTPCReq->Header.abyAddr2,
- WLAN_ADDR_LEN);
- memcpy(pFrame->Header.abyAddr2,
- CARDpGetCurrentAddress(pMgmt->pAdapter),
- WLAN_ADDR_LEN);
- memcpy(pFrame->Header.abyAddr3,
- pMgmt->abyCurrBSSID,
- WLAN_BSSID_LEN);
-
- pFrame->byCategory = 0;
- pFrame->byAction = 3;
- pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ)
- (pMgmt->abyCurrentMSRReq))->byDialogToken;
-
- pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
- pFrame->sTPCRepEIDs.len = 2;
- pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
- switch (byRate) {
- case RATE_54M:
- pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
- break;
- case RATE_48M:
- pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
- break;
- case RATE_36M:
- pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
- break;
- case RATE_24M:
- pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
- break;
- case RATE_18M:
- pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
- break;
- case RATE_12M:
- pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
- break;
- case RATE_9M:
- pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
- break;
- case RATE_6M:
- default:
- pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
- break;
- }
-
- pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
- pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) -
- WLAN_HDR_ADDR3_LEN;
- if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
- return false;
- return true;
-}
/*--------------------- Export Variables --------------------------*/
/*--------------------- Export Functions --------------------------*/
-/*+
- *
- * Description:
- * Handles action management frames.
- *
- * Parameters:
- * In:
- * pMgmt - Management Object structure
- * pRxPacket - Received packet
- * Out:
- * none
- *
- * Return Value: None.
- *
- -*/
-bool
-IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket)
-{
- PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
- PWLAN_FRAME_ACTION pAction = NULL;
- unsigned int uLength = 0;
- PWLAN_IE_CH_SW pChannelSwitch = NULL;
-
- /* decode the frame */
- uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
- if (uLength > WLAN_A3FR_MAXLEN)
- return false;
-
- pAction = (PWLAN_FRAME_ACTION)
- (((PSRxMgmtPacket)pRxPacket)->p80211Header);
-
- if (pAction->byCategory == 0) {
- switch (pAction->byAction) {
- case ACTION_MSRREQ:
- return s_bRxMSRReq(pMgmt,
- (PWLAN_FRAME_MSRREQ)
- pAction,
- uLength);
- break;
- case ACTION_MSRREP:
- break;
- case ACTION_TPCREQ:
- return s_bRxTPCReq(pMgmt,
- (PWLAN_FRAME_TPCREQ) pAction,
- ((PSRxMgmtPacket)pRxPacket)->byRxRate,
- (unsigned char)
- ((PSRxMgmtPacket)pRxPacket)->uRSSI);
- break;
- case ACTION_TPCREP:
- break;
- case ACTION_CHSW:
- pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
- if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH)
- && (pChannelSwitch->len == 3)) {
- /* valid element id */
- CARDbChannelSwitch(pMgmt->pAdapter,
- pChannelSwitch->byMode,
- get_channel_mapping(pMgmt->pAdapter,
- pChannelSwitch->byChannel,
- pMgmt->eCurrentPHYMode),
- pChannelSwitch->byCount);
- }
- break;
- default:
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Unknown Action = %d\n",
- pAction->byAction);
- break;
- }
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown Category = %d\n",
- pAction->byCategory);
- pAction->byCategory |= 0x80;
-
- return true;
- }
- return true;
-}
-
bool IEEE11hbMSRRepTx(void *pMgmtHandle)
{
PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle;
diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h
index 8819fa1563b7..551922022b19 100644
--- a/drivers/staging/vt6655/IEEE11h.h
+++ b/drivers/staging/vt6655/IEEE11h.h
@@ -35,16 +35,6 @@
#include "80211hdr.h"
#include "80211mgr.h"
-/*--------------------- Export Definitions -------------------------*/
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
bool IEEE11hbMSRRepTx(
void *pMgmtHandle
);
diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c
index 4ccfe06481fc..a25e6cf844ed 100644
--- a/drivers/staging/vt6655/aes_ccmp.c
+++ b/drivers/staging/vt6655/aes_ccmp.c
@@ -35,6 +35,7 @@
#include "device.h"
#include "80211hdr.h"
+#include "aes_ccmp.h"
/*--------------------- Static Definitions -------------------------*/
diff --git a/drivers/staging/vt6655/aes_ccmp.h b/drivers/staging/vt6655/aes_ccmp.h
index cc02e645aa56..fe0c506205d5 100644
--- a/drivers/staging/vt6655/aes_ccmp.h
+++ b/drivers/staging/vt6655/aes_ccmp.h
@@ -32,15 +32,6 @@
#include "ttype.h"
-/*--------------------- Export Definitions -------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize);
#endif /* __AES_H__ */
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index 6f95fb618dc3..f212b88c8cec 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -57,7 +57,7 @@
#include "rf.h"
/*--------------------- Static Definitions -------------------------*/
-//static int msglevel =MSG_LEVEL_DEBUG;
+/* static int msglevel =MSG_LEVEL_DEBUG; */
static int msglevel = MSG_LEVEL_INFO;
/*--------------------- Static Classes ----------------------------*/
@@ -75,7 +75,7 @@ static int msglevel = MSG_LEVEL_INFO;
/*--------------------- Static Variables --------------------------*/
#define CB_VT3253_INIT_FOR_RFMD 446
-unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
+static unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
{0x00, 0x30},
{0x01, 0x00},
{0x02, 0x00},
@@ -525,7 +525,7 @@ unsigned char byVT3253InitTab_RFMD[CB_VT3253_INIT_FOR_RFMD][2] = {
};
#define CB_VT3253B0_INIT_FOR_RFMD 256
-unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
+static unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
{0x00, 0x31},
{0x01, 0x00},
{0x02, 0x00},
@@ -785,8 +785,8 @@ unsigned char byVT3253B0_RFMD[CB_VT3253B0_INIT_FOR_RFMD][2] = {
};
#define CB_VT3253B0_AGC_FOR_RFMD2959 195
-// For RFMD2959
-unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
+/* For RFMD2959 */
+static unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
{0xF0, 0x00},
{0xF1, 0x3E},
{0xF0, 0x80},
@@ -985,8 +985,8 @@ unsigned char byVT3253B0_AGC4_RFMD2959[CB_VT3253B0_AGC_FOR_RFMD2959][2] = {
};
#define CB_VT3253B0_INIT_FOR_AIROHA2230 256
-// For AIROHA
-unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
+/* For AIROHA */
+static unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
{0x00, 0x31},
{0x01, 0x00},
{0x02, 0x00},
@@ -1095,7 +1095,7 @@ unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
{0x69, 0x00},
{0x6a, 0x00},
{0x6b, 0x00},
- {0x6c, 0x00}, //RobertYu:20050125, request by JJSue
+ {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */
{0x6d, 0x03},
{0x6e, 0x01},
{0x6f, 0x00},
@@ -1246,8 +1246,8 @@ unsigned char byVT3253B0_AIROHA2230[CB_VT3253B0_INIT_FOR_AIROHA2230][2] = {
};
#define CB_VT3253B0_INIT_FOR_UW2451 256
-//For UW2451
-unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
+/* For UW2451 */
+static unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
{0x00, 0x31},
{0x01, 0x00},
{0x02, 0x00},
@@ -1356,7 +1356,7 @@ unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
{0x69, 0x00},
{0x6a, 0x00},
{0x6b, 0x00},
- {0x6c, 0x00}, //RobertYu:20050125, request by JJSue
+ {0x6c, 0x00}, /* RobertYu:20050125, request by JJSue */
{0x6d, 0x03},
{0x6e, 0x01},
{0x6f, 0x00},
@@ -1507,8 +1507,8 @@ unsigned char byVT3253B0_UW2451[CB_VT3253B0_INIT_FOR_UW2451][2] = {
};
#define CB_VT3253B0_AGC 193
-// For AIROHA
-unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
+/* For AIROHA */
+static unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
{0xF0, 0x00},
{0xF1, 0x00},
{0xF0, 0x80},
@@ -1704,7 +1704,7 @@ unsigned char byVT3253B0_AGC[CB_VT3253B0_AGC][2] = {
{0xF0, 0x00},
};
-const unsigned short awcFrameTime[MAX_RATE] =
+static const unsigned short awcFrameTime[MAX_RATE] =
{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
/*--------------------- Static Functions --------------------------*/
@@ -1783,29 +1783,29 @@ BBuGetFrameTime(
uRate = (unsigned int)awcFrameTime[uRateIdx];
- if (uRateIdx <= 3) { //CCK mode
- if (byPreambleType == 1) //Short
+ if (uRateIdx <= 3) { /* CCK mode */
+ if (byPreambleType == 1) /* Short */
uPreamble = 96;
else
uPreamble = 192;
- uFrameTime = (cbFrameLength * 80) / uRate; //?????
+ uFrameTime = (cbFrameLength * 80) / uRate; /* ????? */
uTmp = (uFrameTime * uRate) / 80;
if (cbFrameLength != uTmp)
uFrameTime++;
return uPreamble + uFrameTime;
} else {
- uFrameTime = (cbFrameLength * 8 + 22) / uRate; //????????
+ uFrameTime = (cbFrameLength * 8 + 22) / uRate; /* ???????? */
uTmp = ((uFrameTime * uRate) - 22) / 8;
if (cbFrameLength != uTmp)
uFrameTime++;
- uFrameTime = uFrameTime * 4; //???????
+ uFrameTime = uFrameTime * 4; /* ??????? */
if (byPktType != PK_TYPE_11A)
- uFrameTime += 6; //??????
+ uFrameTime += 6; /* ?????? */
- return 20 + uFrameTime; //??????
+ return 20 + uFrameTime; /* ?????? */
}
}
@@ -1856,7 +1856,7 @@ BBvCalculateParameter(
cbUsCount = cbBitCount / 2;
if (byPreambleType == 1)
*pbyPhySgn = 0x09;
- else // long preamble
+ else /* long preamble */
*pbyPhySgn = 0x01;
break;
@@ -1869,7 +1869,7 @@ BBvCalculateParameter(
cbUsCount++;
if (byPreambleType == 1)
*pbyPhySgn = 0x0a;
- else // long preamble
+ else /* long preamble */
*pbyPhySgn = 0x02;
break;
@@ -1886,79 +1886,79 @@ BBvCalculateParameter(
}
if (byPreambleType == 1)
*pbyPhySgn = 0x0b;
- else // long preamble
+ else /* long preamble */
*pbyPhySgn = 0x03;
break;
case RATE_6M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9B; //1001 1011
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8B; //1000 1011
+ if (byPacketType == PK_TYPE_11A) { /*11a, 5GHZ */
+ *pbyPhySgn = 0x9B; /* 1001 1011 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8B; /* 1000 1011 */
}
break;
case RATE_9M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9F; //1001 1111
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8F; //1000 1111
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9F; /* 1001 1111 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8F; /* 1000 1111 */
}
break;
case RATE_12M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9A; //1001 1010
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8A; //1000 1010
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9A; /* 1001 1010 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8A; /* 1000 1010 */
}
break;
case RATE_18M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9E; //1001 1110
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8E; //1000 1110
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9E; /* 1001 1110 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8E; /* 1000 1110 */
}
break;
case RATE_24M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x99; //1001 1001
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x89; //1000 1001
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x99; /* 1001 1001 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x89; /* 1000 1001 */
}
break;
case RATE_36M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9D; //1001 1101
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8D; //1000 1101
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9D; /* 1001 1101 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8D; /* 1000 1101 */
}
break;
case RATE_48M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x98; //1001 1000
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x88; //1000 1000
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x98; /* 1001 1000 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x88; /* 1000 1000 */
}
break;
case RATE_54M:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9C; //1001 1100
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8C; //1000 1100
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9C; /* 1001 1100 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8C; /* 1000 1100 */
}
break;
default:
- if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
- *pbyPhySgn = 0x9C; //1001 1100
- } else {//11g, 2.4GHZ
- *pbyPhySgn = 0x8C; //1000 1100
+ if (byPacketType == PK_TYPE_11A) {/* 11a, 5GHZ */
+ *pbyPhySgn = 0x9C; /* 1001 1100 */
+ } else {/* 11g, 2.4GHZ */
+ *pbyPhySgn = 0x8C; /* 1000 1100 */
}
break;
}
@@ -1987,24 +1987,24 @@ BBvCalculateParameter(
* Return Value: true if succeeded; false if failed.
*
*/
-bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData)
+bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData)
{
unsigned short ww;
unsigned char byValue;
- // BB reg offset
+ /* BB reg offset */
VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
- // turn on REGR
+ /* turn on REGR */
MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGR);
- // W_MAX_TIMEOUT is the timeout period
+ /* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
if (byValue & BBREGCTL_DONE)
break;
}
- // get BB data
+ /* get BB data */
VNSvInPortB(dwIoBase + MAC_REG_BBREGDATA, pbyData);
if (ww == W_MAX_TIMEOUT) {
@@ -2029,19 +2029,19 @@ bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned ch
* Return Value: true if succeeded; false if failed.
*
*/
-bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData)
+bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData)
{
unsigned short ww;
unsigned char byValue;
- // BB reg offset
+ /* BB reg offset */
VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr);
- // set BB data
+ /* set BB data */
VNSvOutPortB(dwIoBase + MAC_REG_BBREGDATA, byData);
- // turn on BBREGCTL_REGW
+ /* turn on BBREGCTL_REGW */
MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGW);
- // W_MAX_TIMEOUT is the timeout period
+ /* W_MAX_TIMEOUT is the timeout period */
for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
if (byValue & BBREGCTL_DONE)
@@ -2070,7 +2070,7 @@ bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned c
* Return Value: true if all TestBits are set; false otherwise.
*
*/
-bool BBbIsRegBitsOn(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
+bool BBbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
{
unsigned char byOrgData;
@@ -2092,7 +2092,7 @@ bool BBbIsRegBitsOn(unsigned long dwIoBase, unsigned char byBBAddr, unsigned cha
* Return Value: true if all TestBits are clear; false otherwise.
*
*/
-bool BBbIsRegBitsOff(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
+bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits)
{
unsigned char byOrgData;
@@ -2119,7 +2119,7 @@ bool BBbVT3253Init(PSDevice pDevice)
{
bool bResult = true;
int ii;
- unsigned long dwIoBase = pDevice->PortOffset;
+ void __iomem *dwIoBase = pDevice->PortOffset;
unsigned char byRFType = pDevice->byRFType;
unsigned char byLocalID = pDevice->byLocalID;
@@ -2183,22 +2183,22 @@ bool BBbVT3253Init(PSDevice pDevice)
for (ii = 0; ii < CB_VT3253B0_INIT_FOR_UW2451; ii++)
bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_UW2451[ii][0], byVT3253B0_UW2451[ii][1]);
- // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
- //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);
- // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
- //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);
- // Select VC1/VC2, CR215 = 0x02->0x06
+ /* Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) */
+ /*bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);*/
+ /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */
+ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/
+ /* Select VC1/VC2, CR215 = 0x02->0x06 */
bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06);
- //{{RobertYu:20050125, request by Jack
+ /* {{RobertYu:20050125, request by Jack */
bResult &= BBbWriteEmbedded(dwIoBase, 0x90, 0x20);
bResult &= BBbWriteEmbedded(dwIoBase, 0x97, 0xeb);
- //}}
+ /* }} */
- //{{RobertYu:20050221, request by Jack
+ /* {{RobertYu:20050221, request by Jack */
bResult &= BBbWriteEmbedded(dwIoBase, 0xa6, 0x00);
bResult &= BBbWriteEmbedded(dwIoBase, 0xa8, 0x30);
- //}}
+ /* }} */
bResult &= BBbWriteEmbedded(dwIoBase, 0xb0, 0x58);
for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
@@ -2212,7 +2212,7 @@ bool BBbVT3253Init(PSDevice pDevice)
pDevice->ldBmThreshold[1] = -50;
pDevice->ldBmThreshold[2] = 0;
pDevice->ldBmThreshold[3] = 0;
- //}} RobertYu
+ /* }} RobertYu */
} else if (byRFType == RF_VT3226) {
for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
@@ -2229,22 +2229,22 @@ bool BBbVT3253Init(PSDevice pDevice)
pDevice->ldBmThreshold[1] = -48;
pDevice->ldBmThreshold[2] = 0;
pDevice->ldBmThreshold[3] = 0;
- // Fix VT3226 DFC system timing issue
+ /* Fix VT3226 DFC system timing issue */
MACvSetRFLE_LatchBase(dwIoBase);
- //{{ RobertYu: 20050104
+ /* {{ RobertYu: 20050104 */
} else if (byRFType == RF_AIROHA7230) {
for (ii = 0; ii < CB_VT3253B0_INIT_FOR_AIROHA2230; ii++)
bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AIROHA2230[ii][0], byVT3253B0_AIROHA2230[ii][1]);
- //{{ RobertYu:20050223, request by JerryChung
- // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
- //bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);
- // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
- //bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);
- // Select VC1/VC2, CR215 = 0x02->0x06
+ /* {{ RobertYu:20050223, request by JerryChung */
+ /* Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted) */
+ /*bResult &= BBbWriteEmbedded(dwIoBase,0x09,0x41);*/
+ /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */
+ /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/
+ /* Select VC1/VC2, CR215 = 0x02->0x06 */
bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06);
- //}}
+ /* }} */
for (ii = 0; ii < CB_VT3253B0_AGC; ii++)
bResult &= BBbWriteEmbedded(dwIoBase, byVT3253B0_AGC[ii][0], byVT3253B0_AGC[ii][1]);
@@ -2257,9 +2257,9 @@ bool BBbVT3253Init(PSDevice pDevice)
pDevice->ldBmThreshold[1] = -48;
pDevice->ldBmThreshold[2] = 0;
pDevice->ldBmThreshold[3] = 0;
- //}} RobertYu
+ /* }} RobertYu */
} else {
- // No VGA Table now
+ /* No VGA Table now */
pDevice->bUpdateBBVGA = false;
pDevice->abyBBVGA[0] = 0x1C;
}
@@ -2285,10 +2285,11 @@ bool BBbVT3253Init(PSDevice pDevice)
* Return Value: none
*
*/
-void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs)
+void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs)
{
int ii;
unsigned char byBase = 1;
+
for (ii = 0; ii < BB_MAX_CONTEXT_SIZE; ii++) {
BBbReadEmbedded(dwIoBase, (unsigned char)(ii*byBase), pbyBBRegs);
pbyBBRegs += byBase;
@@ -2312,39 +2313,39 @@ void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs)
void BBvLoopbackOn(PSDevice pDevice)
{
unsigned char byData;
- unsigned long dwIoBase = pDevice->PortOffset;
+ void __iomem *dwIoBase = pDevice->PortOffset;
- //CR C9 = 0x00
- BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9);//CR201
+ /* CR C9 = 0x00 */
+ BBbReadEmbedded(dwIoBase, 0xC9, &pDevice->byBBCRc9); /* CR201 */
BBbWriteEmbedded(dwIoBase, 0xC9, 0);
- BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d);//CR77
+ BBbReadEmbedded(dwIoBase, 0x4D, &pDevice->byBBCR4d); /* CR77 */
BBbWriteEmbedded(dwIoBase, 0x4D, 0x90);
- //CR 88 = 0x02(CCK), 0x03(OFDM)
- BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88);//CR136
-
- if (pDevice->uConnectionRate <= RATE_11M) { //CCK
- // Enable internal digital loopback: CR33 |= 0000 0001
- BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33
- BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01));//CR33
- // CR154 = 0x00
- BBbWriteEmbedded(dwIoBase, 0x9A, 0); //CR154
-
- BBbWriteEmbedded(dwIoBase, 0x88, 0x02);//CR239
- } else { //OFDM
- // Enable internal digital loopback:CR154 |= 0000 0001
- BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154
- BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01));//CR154
- // CR33 = 0x00
- BBbWriteEmbedded(dwIoBase, 0x21, 0); //CR33
-
- BBbWriteEmbedded(dwIoBase, 0x88, 0x03);//CR239
+ /* CR 88 = 0x02(CCK), 0x03(OFDM) */
+ BBbReadEmbedded(dwIoBase, 0x88, &pDevice->byBBCR88); /* CR136 */
+
+ if (pDevice->uConnectionRate <= RATE_11M) { /* CCK */
+ /* Enable internal digital loopback: CR33 |= 0000 0001 */
+ BBbReadEmbedded(dwIoBase, 0x21, &byData); /* CR33 */
+ BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData | 0x01)); /* CR33 */
+ /* CR154 = 0x00 */
+ BBbWriteEmbedded(dwIoBase, 0x9A, 0); /* CR154 */
+
+ BBbWriteEmbedded(dwIoBase, 0x88, 0x02); /* CR239 */
+ } else { /* OFDM */
+ /* Enable internal digital loopback:CR154 |= 0000 0001 */
+ BBbReadEmbedded(dwIoBase, 0x9A, &byData); /* CR154 */
+ BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData | 0x01)); /* CR154 */
+ /* CR33 = 0x00 */
+ BBbWriteEmbedded(dwIoBase, 0x21, 0); /* CR33 */
+
+ BBbWriteEmbedded(dwIoBase, 0x88, 0x03); /* CR239 */
}
- //CR14 = 0x00
- BBbWriteEmbedded(dwIoBase, 0x0E, 0);//CR14
+ /* CR14 = 0x00 */
+ BBbWriteEmbedded(dwIoBase, 0x0E, 0); /* CR14 */
- // Disable TX_IQUN
+ /* Disable TX_IQUN */
BBbReadEmbedded(pDevice->PortOffset, 0x09, &pDevice->byBBCR09);
BBbWriteEmbedded(pDevice->PortOffset, 0x09, (unsigned char)(pDevice->byBBCR09 & 0xDE));
}
@@ -2365,23 +2366,23 @@ void BBvLoopbackOn(PSDevice pDevice)
void BBvLoopbackOff(PSDevice pDevice)
{
unsigned char byData;
- unsigned long dwIoBase = pDevice->PortOffset;
-
- BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9);//CR201
- BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88);//CR136
- BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09);//CR136
- BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d);//CR77
-
- if (pDevice->uConnectionRate <= RATE_11M) { // CCK
- // Set the CR33 Bit2 to disable internal Loopback.
- BBbReadEmbedded(dwIoBase, 0x21, &byData);//CR33
- BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE));//CR33
- } else { // OFDM
- BBbReadEmbedded(dwIoBase, 0x9A, &byData);//CR154
- BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE));//CR154
+ void __iomem *dwIoBase = pDevice->PortOffset;
+
+ BBbWriteEmbedded(dwIoBase, 0xC9, pDevice->byBBCRc9); /* CR201 */
+ BBbWriteEmbedded(dwIoBase, 0x88, pDevice->byBBCR88); /* CR136 */
+ BBbWriteEmbedded(dwIoBase, 0x09, pDevice->byBBCR09); /* CR136 */
+ BBbWriteEmbedded(dwIoBase, 0x4D, pDevice->byBBCR4d); /* CR77 */
+
+ if (pDevice->uConnectionRate <= RATE_11M) { /* CCK */
+ /* Set the CR33 Bit2 to disable internal Loopback. */
+ BBbReadEmbedded(dwIoBase, 0x21, &byData);/* CR33 */
+ BBbWriteEmbedded(dwIoBase, 0x21, (unsigned char)(byData & 0xFE)); /* CR33 */
+ } else { /* OFDM */
+ BBbReadEmbedded(dwIoBase, 0x9A, &byData); /* CR154 */
+ BBbWriteEmbedded(dwIoBase, 0x9A, (unsigned char)(byData & 0xFE)); /* CR154 */
}
- BBbReadEmbedded(dwIoBase, 0x0E, &byData);//CR14
- BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80));//CR14
+ BBbReadEmbedded(dwIoBase, 0x0E, &byData); /* CR14 */
+ BBbWriteEmbedded(dwIoBase, 0x0E, (unsigned char)(byData | 0x80)); /* CR14 */
}
/*
@@ -2402,19 +2403,19 @@ BBvSetShortSlotTime(PSDevice pDevice)
unsigned char byBBRxConf = 0;
unsigned char byBBVGA = 0;
- BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
+ BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf); /* CR10 */
if (pDevice->bShortSlotTime)
- byBBRxConf &= 0xDF;//1101 1111
+ byBBRxConf &= 0xDF; /* 1101 1111 */
else
- byBBRxConf |= 0x20;//0010 0000
+ byBBRxConf |= 0x20; /* 0010 0000 */
- // patch for 3253B0 Baseband with Cardbus module
+ /* patch for 3253B0 Baseband with Cardbus module */
BBbReadEmbedded(pDevice->PortOffset, 0xE7, &byBBVGA);
if (byBBVGA == pDevice->abyBBVGA[0])
- byBBRxConf |= 0x20;//0010 0000
+ byBBRxConf |= 0x20; /* 0010 0000 */
- BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10
+ BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf); /* CR10 */
}
void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData)
@@ -2423,16 +2424,16 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData)
BBbWriteEmbedded(pDevice->PortOffset, 0xE7, byData);
- BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf);//CR10
- // patch for 3253B0 Baseband with Cardbus module
+ BBbReadEmbedded(pDevice->PortOffset, 0x0A, &byBBRxConf); /* CR10 */
+ /* patch for 3253B0 Baseband with Cardbus module */
if (byData == pDevice->abyBBVGA[0])
- byBBRxConf |= 0x20;//0010 0000
+ byBBRxConf |= 0x20; /* 0010 0000 */
else if (pDevice->bShortSlotTime)
- byBBRxConf &= 0xDF;//1101 1111
+ byBBRxConf &= 0xDF; /* 1101 1111 */
else
- byBBRxConf |= 0x20;//0010 0000
+ byBBRxConf |= 0x20; /* 0010 0000 */
pDevice->byBBVGACurrent = byData;
- BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf);//CR10
+ BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf); /* CR10 */
}
/*
@@ -2448,7 +2449,7 @@ void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData)
*
*/
void
-BBvSoftwareReset(unsigned long dwIoBase)
+BBvSoftwareReset(void __iomem *dwIoBase)
{
BBbWriteEmbedded(dwIoBase, 0x50, 0x40);
BBbWriteEmbedded(dwIoBase, 0x50, 0);
@@ -2469,7 +2470,7 @@ BBvSoftwareReset(unsigned long dwIoBase)
*
*/
void
-BBvPowerSaveModeON(unsigned long dwIoBase)
+BBvPowerSaveModeON(void __iomem *dwIoBase)
{
unsigned char byOrgData;
@@ -2491,7 +2492,7 @@ BBvPowerSaveModeON(unsigned long dwIoBase)
*
*/
void
-BBvPowerSaveModeOFF(unsigned long dwIoBase)
+BBvPowerSaveModeOFF(void __iomem *dwIoBase)
{
unsigned char byOrgData;
@@ -2515,22 +2516,22 @@ BBvPowerSaveModeOFF(unsigned long dwIoBase)
*/
void
-BBvSetTxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode)
+BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode)
{
unsigned char byBBTxConf;
- BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf);//CR09
+ BBbReadEmbedded(dwIoBase, 0x09, &byBBTxConf); /* CR09 */
if (byAntennaMode == ANT_DIVERSITY) {
- // bit 1 is diversity
+ /* bit 1 is diversity */
byBBTxConf |= 0x02;
} else if (byAntennaMode == ANT_A) {
- // bit 2 is ANTSEL
- byBBTxConf &= 0xF9; // 1111 1001
+ /* bit 2 is ANTSEL */
+ byBBTxConf &= 0xF9; /* 1111 1001 */
} else if (byAntennaMode == ANT_B) {
- byBBTxConf &= 0xFD; // 1111 1101
+ byBBTxConf &= 0xFD; /* 1111 1101 */
byBBTxConf |= 0x04;
}
- BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf);//CR09
+ BBbWriteEmbedded(dwIoBase, 0x09, byBBTxConf); /* CR09 */
}
/*
@@ -2548,21 +2549,21 @@ BBvSetTxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode)
*/
void
-BBvSetRxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode)
+BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode)
{
unsigned char byBBRxConf;
- BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf);//CR10
+ BBbReadEmbedded(dwIoBase, 0x0A, &byBBRxConf); /* CR10 */
if (byAntennaMode == ANT_DIVERSITY) {
byBBRxConf |= 0x01;
} else if (byAntennaMode == ANT_A) {
- byBBRxConf &= 0xFC; // 1111 1100
+ byBBRxConf &= 0xFC; /* 1111 1100 */
} else if (byAntennaMode == ANT_B) {
- byBBRxConf &= 0xFE; // 1111 1110
+ byBBRxConf &= 0xFE; /* 1111 1110 */
byBBRxConf |= 0x02;
}
- BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf);//CR10
+ BBbWriteEmbedded(dwIoBase, 0x0A, byBBRxConf); /* CR10 */
}
/*
@@ -2578,17 +2579,17 @@ BBvSetRxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode)
*
*/
void
-BBvSetDeepSleep(unsigned long dwIoBase, unsigned char byLocalID)
+BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID)
{
- BBbWriteEmbedded(dwIoBase, 0x0C, 0x17);//CR12
- BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9);//CR13
+ BBbWriteEmbedded(dwIoBase, 0x0C, 0x17); /* CR12 */
+ BBbWriteEmbedded(dwIoBase, 0x0D, 0xB9); /* CR13 */
}
void
-BBvExitDeepSleep(unsigned long dwIoBase, unsigned char byLocalID)
+BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID)
{
- BBbWriteEmbedded(dwIoBase, 0x0C, 0x00);//CR12
- BBbWriteEmbedded(dwIoBase, 0x0D, 0x01);//CR13
+ BBbWriteEmbedded(dwIoBase, 0x0C, 0x00); /* CR12 */
+ BBbWriteEmbedded(dwIoBase, 0x0D, 0x01); /* CR13 */
}
static
@@ -2599,7 +2600,7 @@ s_ulGetRatio(PSDevice pDevice)
unsigned long ulMaxPacket;
unsigned long ulPacketNum;
- //This is a thousand-ratio
+ /* This is a thousand-ratio */
ulMaxPacket = pDevice->uNumSQ3[RATE_54M];
if (pDevice->uNumSQ3[RATE_54M] != 0) {
ulPacketNum = pDevice->uNumSQ3[RATE_54M];
@@ -2751,7 +2752,7 @@ BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ
BBvClearAntDivSQ3Value(pDevice);
}
- } else { //byAntennaState == 1
+ } else { /* byAntennaState == 1 */
if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) {
del_timer(&pDevice->TimerSQ3Tmax1);
@@ -2775,7 +2776,7 @@ BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ
pDevice->byAntennaState = 0;
BBvClearAntDivSQ3Value(pDevice);
}
- } //byAntennaState
+ } /* byAntennaState */
}
/*+
@@ -2814,7 +2815,6 @@ TimerSQ3CallBack(
add_timer(&pDevice->TimerSQ3Tmax2);
spin_unlock_irq(&pDevice->lock);
- return;
}
/*+
@@ -2873,6 +2873,4 @@ TimerState1CallBack(
pDevice->byAntennaState = 0;
BBvClearAntDivSQ3Value(pDevice);
spin_unlock_irq(&pDevice->lock);
-
- return;
}
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
index e31bb7600673..fcf1f9373672 100644
--- a/drivers/staging/vt6655/baseband.h
+++ b/drivers/staging/vt6655/baseband.h
@@ -34,8 +34,6 @@
#include "tether.h"
#include "device.h"
-/*--------------------- Export Definitions -------------------------*/
-
//
// Registers in the BASEBAND
//
@@ -64,22 +62,12 @@
#define TOP_RATE_2M 0x00200000
#define TOP_RATE_1M 0x00100000
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Macros ------------------------------*/
-
#define BBvClearFOE(dwIoBase) \
BBbWriteEmbedded(dwIoBase, 0xB1, 0)
#define BBvSetFOE(dwIoBase) \
BBbWriteEmbedded(dwIoBase, 0xB1, 0x0C)
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
unsigned int
BBuGetFrameTime(
unsigned char byPreambleType,
@@ -99,26 +87,26 @@ BBvCalculateParameter(
unsigned char *pbyPhySgn
);
-bool BBbReadEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char *pbyData);
-bool BBbWriteEmbedded(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byData);
+bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char *pbyData);
+bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData);
-void BBvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyBBRegs);
+void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs);
void BBvLoopbackOn(PSDevice pDevice);
void BBvLoopbackOff(PSDevice pDevice);
void BBvSetShortSlotTime(PSDevice pDevice);
-bool BBbIsRegBitsOn(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
-bool BBbIsRegBitsOff(unsigned long dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
+bool BBbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
+bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits);
void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData);
// VT3253 Baseband
bool BBbVT3253Init(PSDevice pDevice);
-void BBvSoftwareReset(unsigned long dwIoBase);
-void BBvPowerSaveModeON(unsigned long dwIoBase);
-void BBvPowerSaveModeOFF(unsigned long dwIoBase);
-void BBvSetTxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode);
-void BBvSetRxAntennaMode(unsigned long dwIoBase, unsigned char byAntennaMode);
-void BBvSetDeepSleep(unsigned long dwIoBase, unsigned char byLocalID);
-void BBvExitDeepSleep(unsigned long dwIoBase, unsigned char byLocalID);
+void BBvSoftwareReset(void __iomem *dwIoBase);
+void BBvPowerSaveModeON(void __iomem *dwIoBase);
+void BBvPowerSaveModeOFF(void __iomem *dwIoBase);
+void BBvSetTxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode);
+void BBvSetRxAntennaMode(void __iomem *dwIoBase, unsigned char byAntennaMode);
+void BBvSetDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID);
+void BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID);
// timer for antenna diversity
diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c
index 59679cd46816..9569f43a3ed7 100644
--- a/drivers/staging/vt6655/bssdb.c
+++ b/drivers/staging/vt6655/bssdb.c
@@ -65,14 +65,14 @@
/*--------------------- Static Variables --------------------------*/
static int msglevel = MSG_LEVEL_INFO;
-const unsigned short awHWRetry0[5][5] = {
+static const unsigned short awHWRetry0[5][5] = {
{RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
{RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
{RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
{RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
{RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
};
-const unsigned short awHWRetry1[5][5] = {
+static const unsigned short awHWRetry1[5][5] = {
{RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
{RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
{RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
@@ -262,8 +262,6 @@ BSSvClearBSSList(
memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
}
BSSvClearAnyBSSJoinRecord(pDevice);
-
- return;
}
/*+
@@ -424,6 +422,7 @@ BSSbInsertToBSSList(
if (pRSN != NULL) {
unsigned int uLen = pRSN->len + 2;
+
if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
pBSSList->wRSNLen = uLen;
memcpy(pBSSList->byRSNIE, pRSN, uLen);
@@ -600,6 +599,7 @@ BSSbUpdateToBSSList(
if (pRSNWPA != NULL) {
unsigned int uLen = pRSNWPA->len + 2;
+
if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSNWPA - pbyIEs))) {
pBSSList->wWPALen = uLen;
memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
@@ -611,6 +611,7 @@ BSSbUpdateToBSSList(
if (pRSN != NULL) {
unsigned int uLen = pRSN->len + 2;
+
if (uLen <= (uIELength - (unsigned int)((unsigned char *)pRSN - pbyIEs))) {
pBSSList->wRSNLen = uLen;
memcpy(pBSSList->byRSNIE, pRSN, uLen);
@@ -900,11 +901,6 @@ BSSvAddMulticastNode(
* none.
*
-*/
-/* 2008-4-14 <add> by chester for led issue */
-#ifdef FOR_LED_ON_NOTEBOOK
-bool cc = false;
-unsigned int status;
-#endif
void
BSSvSecondCallBack(
void *hDeviceContext
@@ -925,54 +921,6 @@ BSSvSecondCallBack(
pDevice->byERPFlag &=
~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
- /* 2008-4-14 <add> by chester for led issue */
-#ifdef FOR_LED_ON_NOTEBOOK
- MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
- if (((!(pDevice->byGPIO & GPIO0_DATA) && (!pDevice->bHWRadioOff)) ||
- ((pDevice->byGPIO & GPIO0_DATA) && pDevice->bHWRadioOff)) &&
- (!cc)) {
- cc = true;
- } else if (cc) {
- if (pDevice->bHWRadioOff) {
- if (!(pDevice->byGPIO & GPIO0_DATA)) {
- if (status == 1)
- goto start;
- status = 1;
- CARDbRadioPowerOff(pDevice);
- pMgmt->sNodeDBTable[0].bActive = false;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pDevice->bLinkPass = false;
-
- }
- if (pDevice->byGPIO & GPIO0_DATA) {
- if (status == 2)
- goto start;
- status = 2;
- CARDbRadioPowerOn(pDevice);
- }
- } else {
- if (pDevice->byGPIO & GPIO0_DATA) {
- if (status == 3)
- goto start;
- status = 3;
- CARDbRadioPowerOff(pDevice);
- pMgmt->sNodeDBTable[0].bActive = false;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pDevice->bLinkPass = false;
-
- }
- if (!(pDevice->byGPIO & GPIO0_DATA)) {
- if (status == 4)
- goto start;
- status = 4;
- CARDbRadioPowerOn(pDevice);
- }
- }
- }
-start:
-#endif
if (pDevice->wUseProtectCntDown > 0) {
pDevice->wUseProtectCntDown--;
@@ -981,7 +929,7 @@ start:
pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
}
- {
+ if (pDevice->eCommandState == WLAN_ASSOCIATE_WAIT) {
pDevice->byReAssocCount++;
/* 10 sec timeout */
if ((pDevice->byReAssocCount > 10) && (!pDevice->bLinkPass)) {
@@ -990,6 +938,7 @@ start:
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
@@ -1169,6 +1118,7 @@ start:
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
@@ -1235,7 +1185,6 @@ start:
pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
add_timer(&pMgmt->sTimerSecondCallback);
- return;
}
/*+
@@ -1270,6 +1219,7 @@ BSSvUpdateNodeTxCounter(
unsigned short wFallBackRate = RATE_1M;
unsigned char byFallBack;
unsigned int ii;
+
pTxBufHead = (PSTxBufHead) pbyBuffer;
if (pTxBufHead->wFIFOCtl & FIFOCTL_AUTO_FB_0)
byFallBack = AUTO_FB_0;
@@ -1385,8 +1335,6 @@ BSSvUpdateNodeTxCounter(
}
}
}
-
- return;
}
/*+
@@ -1456,6 +1404,7 @@ void s_vCheckSensitivity(
/* Update BB Reg if RSSI is too strong */
long LocalldBmAverage = 0;
long uNumofdBm = 0;
+
for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
if (pBSSList->ldBmAverage[ii] != 0) {
uNumofdBm++;
@@ -1494,7 +1443,6 @@ BSSvClearAnyBSSJoinRecord(
for (ii = 0; ii < MAX_BSS_NUM; ii++)
pMgmt->sBSSList[ii].bSelected = false;
- return;
}
#ifdef Calcu_LinkQual
@@ -1535,7 +1483,6 @@ void s_uCalculateLinkQual(
pDevice->scStatistic.TxFailCount = 0;
pDevice->scStatistic.TxNoRetryOkCount = 0;
pDevice->scStatistic.TxRetryOkCount = 0;
- return;
}
#endif
@@ -1553,5 +1500,4 @@ void s_vCheckPreEDThreshold(
if (pBSSList != NULL)
pDevice->byBBPreEDRSSI = (unsigned char) (~(pBSSList->ldBmAverRange) + 1);
}
- return;
}
diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h
index a0938b7dd082..bf299e3b8acf 100644
--- a/drivers/staging/vt6655/bssdb.h
+++ b/drivers/staging/vt6655/bssdb.h
@@ -35,8 +35,6 @@
#include "80211mgr.h"
#include "card.h"
-/*--------------------- Export Definitions -------------------------*/
-
#define MAX_NODE_NUM 64
#define MAX_BSS_NUM 42
#define LOST_BEACON_COUNT 10 // 10 sec, XP defined
@@ -67,18 +65,11 @@
#define MAX_WPA_IE_LEN 64
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
//
// IEEE 802.11 Structures and definitions
//
-typedef enum _NDIS_802_11_NETWORK_TYPE
-{
+typedef enum _NDIS_802_11_NETWORK_TYPE {
Ndis802_11FH,
Ndis802_11DS,
Ndis802_11OFDM5,
@@ -99,7 +90,6 @@ typedef struct tagSRSNCapObject {
// BSS info(AP)
#pragma pack(1)
typedef struct tagKnownBSS {
- // BSS info
bool bActive;
unsigned char abyBSSID[WLAN_BSSID_LEN];
unsigned int uChannel;
@@ -116,10 +106,8 @@ typedef struct tagKnownBSS {
long ldBmMAX;
long ldBmAverage[RSSI_STAT_COUNT];
long ldBmAverRange;
- //For any BSSID selection improvment
bool bSelected;
- //++ WPA informations
bool bWPAValid;
unsigned char byGKType;
unsigned char abyPKType[4];
@@ -128,9 +116,7 @@ typedef struct tagKnownBSS {
unsigned short wAuthCount;
unsigned char byDefaultK_as_PK;
unsigned char byReplayIdx;
- //--
- //++ WPA2 informations
bool bWPA2Valid;
unsigned char byCSSGK;
unsigned short wCSSPKCount;
@@ -138,28 +124,24 @@ typedef struct tagKnownBSS {
unsigned short wAKMSSAuthCount;
unsigned char abyAKMSSAuthType[4];
- //++ wpactl
unsigned char byWPAIE[MAX_WPA_IE_LEN];
unsigned char byRSNIE[MAX_WPA_IE_LEN];
unsigned short wWPALen;
unsigned short wRSNLen;
- // Clear count
unsigned int uClearCount;
unsigned int uIELength;
QWORD qwBSSTimestamp;
- QWORD qwLocalTSF; // local TSF timer
+ QWORD qwLocalTSF;
-// NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
CARD_PHY_TYPE eNetworkTypeInUse;
ERPObject sERP;
SRSNCapObject sRSNCapObj;
- unsigned char abyIEs[1024]; // don't move this field !!
+ unsigned char abyIEs[1024];
} __attribute__ ((__packed__))
KnownBSS , *PKnownBSS;
-//2006-1116-01,<Add> by NomadZhao
#pragma pack()
typedef enum tagNODE_STATE {
@@ -172,7 +154,6 @@ typedef enum tagNODE_STATE {
// STA node info
typedef struct tagKnownNodeDB {
- // STA info
bool bActive;
unsigned char abyMACAddr[WLAN_ADDR_LEN];
unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
@@ -211,7 +192,6 @@ typedef struct tagKnownNodeDB {
unsigned short wTSC15_0;
unsigned int uWepKeyLength;
unsigned char abyWepKey[WLAN_WEPMAX_KEYLEN];
- //
// Auto rate fallback vars
bool bIsInFallback;
unsigned int uAverageRSSI;
@@ -228,8 +208,6 @@ typedef struct tagKnownNodeDB {
unsigned int uTimeCount;
} KnownNodeDB, *PKnownNodeDB;
-/*--------------------- Export Functions --------------------------*/
-
PKnownBSS
BSSpSearchBSSList(
void *hDeviceContext,
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index 05bf48a24f45..4ae8d9362edf 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -87,7 +87,7 @@ static unsigned char abyDefaultSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x0
/*--------------------- Static Variables --------------------------*/
-const unsigned short cwRXBCNTSFOff[MAX_RATE] =
+static const unsigned short cwRXBCNTSFOff[MAX_RATE] =
{17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
/*--------------------- Static Functions --------------------------*/
@@ -351,6 +351,7 @@ s_vSetRSPINF(PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, v
bool CARDbIsShortPreamble(void *pDeviceHandler)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
+
if (pDevice->byPreambleType == 0)
return false;
@@ -372,6 +373,7 @@ bool CARDbIsShortPreamble(void *pDeviceHandler)
bool CARDbIsShorSlotTime(void *pDeviceHandler)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
+
return pDevice->bShortSlotTime;
}
@@ -908,7 +910,7 @@ bool CARDbRadioPowerOff(void *pDeviceHandler)
pDevice->bRadioOff = true;
//2007-0409-03,<Add> by chester
- printk("chester power off\n");
+ pr_debug("chester power off\n");
MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
return bResult;
}
@@ -929,14 +931,17 @@ bool CARDbRadioPowerOn(void *pDeviceHandler)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
bool bResult = true;
- printk("chester power on\n");
+
+ pr_debug("chester power on\n");
if (pDevice->bRadioControlOff == true) {
- if (pDevice->bHWRadioOff == true) printk("chester bHWRadioOff\n");
- if (pDevice->bRadioControlOff == true) printk("chester bRadioControlOff\n");
+ if (pDevice->bHWRadioOff == true)
+ pr_debug("chester bHWRadioOff\n");
+ if (pDevice->bRadioControlOff == true)
+ pr_debug("chester bRadioControlOff\n");
return false; }
if (pDevice->bRadioOff == false) {
- printk("chester pbRadioOff\n");
+ pr_debug("chester pbRadioOff\n");
return true; }
BBvExitDeepSleep(pDevice->PortOffset, pDevice->byLocalID);
@@ -960,7 +965,7 @@ bool CARDbRadioPowerOn(void *pDeviceHandler)
pDevice->bRadioOff = false;
// 2007-0409-03,<Add> by chester
- printk("chester power on\n");
+ pr_debug("chester power on\n");
MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue
return bResult;
}
@@ -998,7 +1003,7 @@ CARDbAdd_PMKID_Candidate(
)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
- PPMKID_CANDIDATE pCandidateList;
+ struct pmkid_candidate *pCandidateList;
unsigned int ii = 0;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
@@ -1573,7 +1578,7 @@ CARDvSafeResetRx(
* Return Value: response Control frame rate
*
*/
-unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx)
+static unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
unsigned int ui = (unsigned int) wRateIdx;
@@ -1600,7 +1605,7 @@ unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRate
* Return Value: response Control frame rate
*
*/
-unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned short wRateIdx)
+static unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned short wRateIdx)
{
PSDevice pDevice = (PSDevice) pDeviceHandler;
unsigned int ui = (unsigned int) wRateIdx;
@@ -1767,6 +1772,7 @@ void vUpdateIFS(void *pDeviceHandler)
PSDevice pDevice = (PSDevice) pDeviceHandler;
unsigned char byMaxMin = 0;
+
if (pDevice->byPacketType == PK_TYPE_11A) {//0000 0000 0000 0000,11a
pDevice->uSlot = C_SLOT_SHORT;
pDevice->uSIFS = C_SIFS_A;
@@ -1888,7 +1894,7 @@ unsigned char CARDbyGetPktType(void *pDeviceHandler)
* Return Value: none
*
*/
-void CARDvSetLoopbackMode(unsigned long dwIoBase, unsigned short wLoopbackMode)
+void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode)
{
switch (wLoopbackMode) {
case CARD_LB_NONE:
@@ -1977,7 +1983,7 @@ QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2)
* Return Value: true if success; otherwise false
*
*/
-bool CARDbGetCurrentTSF(unsigned long dwIoBase, PQWORD pqwCurrTSF)
+bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF)
{
unsigned short ww;
unsigned char byData;
@@ -2050,7 +2056,7 @@ QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval)
* Return Value: none
*
*/
-void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterval)
+void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval)
{
QWORD qwNextTBTT;
@@ -2062,8 +2068,6 @@ void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterva
VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
-
- return;
}
/*
@@ -2081,15 +2085,13 @@ void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterva
* Return Value: none
*
*/
-void CARDvUpdateNextTBTT(unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval)
+void CARDvUpdateNextTBTT(void __iomem *dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval)
{
qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
// Set NextTBTT
VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF));
VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF));
MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8xh:%8xh] \n",
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8xh:%8xh]\n",
(unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF));
-
- return;
}
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h
index 829be92838b0..2f1a05ef44a1 100644
--- a/drivers/staging/vt6655/card.h
+++ b/drivers/staging/vt6655/card.h
@@ -32,7 +32,6 @@
#include "ttype.h"
#include <linux/types.h>
-/*--------------------- Export Definitions -------------------------*/
//
// Loopback mode
//
@@ -48,7 +47,7 @@
#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us
#define CB_MAX_CHANNEL_24G 14
-#define CB_MAX_CHANNEL_5G 42 //[20050104] add channel9(5045MHz), 41==>42
+#define CB_MAX_CHANNEL_5G 42
#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
typedef enum _CARD_PHY_TYPE {
@@ -78,22 +77,16 @@ typedef enum _CARD_OP_MODE {
OP_MODE_UNKNOWN
} CARD_OP_MODE, *PCARD_OP_MODE;
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType);
void vUpdateIFS(void *pDeviceHandler);
void CARDvUpdateBasicTopRate(void *pDeviceHandler);
bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx);
bool CARDbIsOFDMinBasicRate(void *pDeviceHandler);
-void CARDvSetLoopbackMode(unsigned long dwIoBase, unsigned short wLoopbackMode);
+void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode);
bool CARDbSoftwareReset(void *pDeviceHandler);
-void CARDvSetFirstNextTBTT(unsigned long dwIoBase, unsigned short wBeaconInterval);
-void CARDvUpdateNextTBTT(unsigned long dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval);
-bool CARDbGetCurrentTSF(unsigned long dwIoBase, PQWORD pqwCurrTSF);
+void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval);
+void CARDvUpdateNextTBTT(void __iomem *dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval);
+bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF);
QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval);
QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2);
bool CARDbSetTxPower(void *pDeviceHandler, unsigned long ulTxPower);
@@ -101,7 +94,6 @@ unsigned char CARDbyGetPktType(void *pDeviceHandler);
void CARDvSafeResetTx(void *pDeviceHandler);
void CARDvSafeResetRx(void *pDeviceHandler);
-//xxx
bool CARDbRadioPowerOff(void *pDeviceHandler);
bool CARDbRadioPowerOn(void *pDeviceHandler);
bool CARDbIsShortPreamble(void *pDeviceHandler);
diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h
index c9931d7f6653..4f44c8a3d3cf 100644
--- a/drivers/staging/vt6655/channel.h
+++ b/drivers/staging/vt6655/channel.h
@@ -26,8 +26,6 @@
#include "ttype.h"
#include "card.h"
-/*--------------------- Export Classes ----------------------------*/
-
typedef struct tagSChannelTblElement {
unsigned char byChannelNumber;
unsigned int uFrequency;
@@ -35,8 +33,6 @@ typedef struct tagSChannelTblElement {
unsigned char byMAP;
} SChannelTblElement, *PSChannelTblElement;
-/*--------------------- Export Functions --------------------------*/
-
bool is_channel_valid(unsigned int CountryCode);
void init_channel_table(void *pDeviceHandler);
unsigned char get_channel_mapping(void *pDeviceHandler, unsigned char byChannelNumber, CARD_PHY_TYPE ePhyType);
diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h
index 415e7672aa32..2365fb13b033 100644
--- a/drivers/staging/vt6655/country.h
+++ b/drivers/staging/vt6655/country.h
@@ -32,7 +32,6 @@
#include "ttype.h"
-/*--------------------- Export Definitions -------------------------*/
/************************************************************************
* The definition here should be complied with the INF country order
* Please check with VNWL.inf/VNWL64.inf/VNWL*.inf
diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c
index f8420d65cd94..565028c4ab03 100644
--- a/drivers/staging/vt6655/datarate.c
+++ b/drivers/staging/vt6655/datarate.c
@@ -47,11 +47,12 @@
/*--------------------- Static Classes ----------------------------*/
-extern unsigned short TxRate_iwconfig; //2008-5-8 <add> by chester
+extern unsigned short TxRate_iwconfig; /* 2008-5-8 <add> by chester */
/*--------------------- Static Variables --------------------------*/
static int msglevel = MSG_LEVEL_INFO;
-static const unsigned char acbyIERate[MAX_RATE] =
-{0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+static const unsigned char acbyIERate[MAX_RATE] = {
+0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C
+};
#define AUTORATE_TXOK_CNT 0x0400
#define AUTORATE_TXFAIL_CNT 0x0064
@@ -70,7 +71,7 @@ s_vResetCounter(
{
unsigned char ii;
- // clear statistic counter for auto_rate
+ /* clear statistic counter for auto_rate */
for (ii = 0; ii <= MAX_RATE; ii++) {
psNodeDBTable->uTxOk[ii] = 0;
psNodeDBTable->uTxFail[ii] = 0;
@@ -102,8 +103,8 @@ DATARATEbyGetRateIdx(
{
unsigned char ii;
- //Erase basicRate flag.
- byRate = byRate & 0x7F;//0111 1111
+ /* Erase basicRate flag. */
+ byRate = byRate & 0x7F;/* 0111 1111 */
for (ii = 0; ii < MAX_RATE; ii++) {
if (acbyIERate[ii] == byRate)
@@ -151,13 +152,14 @@ wGetRateIdx(
{
unsigned short ii;
- //Erase basicRate flag.
- byRate = byRate & 0x7F;//0111 1111
+ /* Erase basicRate flag. */
+ byRate = byRate & 0x7F;/* 0111 1111 */
for (ii = 0; ii < MAX_RATE; ii++) {
if (acbyIERate[ii] == byRate)
return ii;
}
+
return 0;
}
@@ -218,7 +220,7 @@ RATEvParseMaxRate(
for (ii = 0; ii < uRateLen; ii++) {
byRate = (unsigned char)(pItemRates->abyRates[ii]);
if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate) {
- // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+ /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */
CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
}
@@ -238,9 +240,9 @@ RATEvParseMaxRate(
for (ii = 0; ii < uExtRateLen; ii++) {
byRate = (unsigned char)(pItemExtRates->abyRates[ii]);
- // select highest basic rate
+ /* select highest basic rate */
if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
- // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+ /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */
CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate));
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
}
@@ -302,10 +304,9 @@ RATEvTxRateFallBack(
unsigned short wIdxUpRate = 0;
unsigned long dwTxDiff = 0;
- if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
- // Don't do Fallback when scanning Channel
+ if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING)
+ /* Don't do Fallback when scanning Channel */
return;
- }
psNodeDBTable->uTimeCount++;
@@ -357,15 +358,15 @@ RATEvTxRateFallBack(
(psNodeDBTable->uTxFail[MAX_RATE] * 4)) {
psNodeDBTable->wTxDataRate = wIdxUpRate;
}
- } else { // adhoc, if uTxOk =0 & uTxFail = 0
+ } else {
+ /* adhoc, if uTxOk =0 & uTxFail = 0 */
if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
psNodeDBTable->wTxDataRate = wIdxUpRate;
}
-//2008-5-8 <add> by chester
+
+ /* 2008-5-8 <add> by chester */
TxRate_iwconfig = psNodeDBTable->wTxDataRate;
s_vResetCounter(psNodeDBTable);
-
- return;
}
/*+
diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h
index e4fad05ad859..0509c4fd2a42 100644
--- a/drivers/staging/vt6655/datarate.h
+++ b/drivers/staging/vt6655/datarate.h
@@ -29,25 +29,15 @@
#ifndef __DATARATE_H__
#define __DATARATE_H__
-/*--------------------- Export Definitions -------------------------*/
-
-#define FALLBACK_PKT_COLLECT_TR_H 50 // pkts
-#define FALLBACK_PKT_COLLECT_TR_L 10 // pkts
-#define FALLBACK_POLL_SECOND 5 // 5 sec
-#define FALLBACK_RECOVER_SECOND 30 // 30 sec
-#define FALLBACK_THRESHOLD 15 // percent
-#define UPGRADE_THRESHOLD 5 // percent
-#define UPGRADE_CNT_THRD 3 // times
-#define RETRY_TIMES_THRD_H 2 // times
-#define RETRY_TIMES_THRD_L 1 // times
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
+#define FALLBACK_PKT_COLLECT_TR_H 50
+#define FALLBACK_PKT_COLLECT_TR_L 10
+#define FALLBACK_POLL_SECOND 5
+#define FALLBACK_RECOVER_SECOND 30
+#define FALLBACK_THRESHOLD 15
+#define UPGRADE_THRESHOLD 5
+#define UPGRADE_CNT_THRD 3
+#define RETRY_TIMES_THRD_H 2
+#define RETRY_TIMES_THRD_L 1
void
RATEvParseMaxRate(
diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h
index c620cbfbaadf..05efa4e1b682 100644
--- a/drivers/staging/vt6655/desc.h
+++ b/drivers/staging/vt6655/desc.h
@@ -36,79 +36,77 @@
#include "ttype.h"
#include "tether.h"
-/*--------------------- Export Definitions -------------------------*/
-
-#define B_OWNED_BY_CHIP 1 //
-#define B_OWNED_BY_HOST 0 //
+#define B_OWNED_BY_CHIP 1
+#define B_OWNED_BY_HOST 0
//
// Bits in the RSR register
//
-#define RSR_ADDRBROAD 0x80 // 1000 0000
-#define RSR_ADDRMULTI 0x40 // 0100 0000
-#define RSR_ADDRUNI 0x00 // 0000 0000
-#define RSR_IVLDTYP 0x20 // 0010 0000 , invalid packet type
-#define RSR_IVLDLEN 0x10 // 0001 0000 , invalid len (> 2312 byte)
-#define RSR_BSSIDOK 0x08 // 0000 1000
-#define RSR_CRCOK 0x04 // 0000 0100
-#define RSR_BCNSSIDOK 0x02 // 0000 0010
-#define RSR_ADDROK 0x01 // 0000 0001
+#define RSR_ADDRBROAD 0x80
+#define RSR_ADDRMULTI 0x40
+#define RSR_ADDRUNI 0x00
+#define RSR_IVLDTYP 0x20
+#define RSR_IVLDLEN 0x10 // invalid len (> 2312 byte)
+#define RSR_BSSIDOK 0x08
+#define RSR_CRCOK 0x04
+#define RSR_BCNSSIDOK 0x02
+#define RSR_ADDROK 0x01
//
// Bits in the new RSR register
//
-#define NEWRSR_DECRYPTOK 0x10 // 0001 0000
-#define NEWRSR_CFPIND 0x08 // 0000 1000
-#define NEWRSR_HWUTSF 0x04 // 0000 0100
-#define NEWRSR_BCNHITAID 0x02 // 0000 0010
-#define NEWRSR_BCNHITAID0 0x01 // 0000 0001
+#define NEWRSR_DECRYPTOK 0x10
+#define NEWRSR_CFPIND 0x08
+#define NEWRSR_HWUTSF 0x04
+#define NEWRSR_BCNHITAID 0x02
+#define NEWRSR_BCNHITAID0 0x01
//
// Bits in the TSR0 register
//
-#define TSR0_PWRSTS1_2 0xC0 // 1100 0000
-#define TSR0_PWRSTS7 0x20 // 0010 0000
-#define TSR0_NCR 0x1F // 0001 1111
+#define TSR0_PWRSTS1_2 0xC0
+#define TSR0_PWRSTS7 0x20
+#define TSR0_NCR 0x1F
//
// Bits in the TSR1 register
//
-#define TSR1_TERR 0x80 // 1000 0000
-#define TSR1_PWRSTS4_6 0x70 // 0111 0000
-#define TSR1_RETRYTMO 0x08 // 0000 1000
-#define TSR1_TMO 0x04 // 0000 0100
-#define TSR1_PWRSTS3 0x02 // 0000 0010
-#define ACK_DATA 0x01 // 0000 0000
+#define TSR1_TERR 0x80
+#define TSR1_PWRSTS4_6 0x70
+#define TSR1_RETRYTMO 0x08
+#define TSR1_TMO 0x04
+#define TSR1_PWRSTS3 0x02
+#define ACK_DATA 0x01
//
// Bits in the TCR register
//
-#define EDMSDU 0x04 // 0000 0100 end of sdu
-#define TCR_EDP 0x02 // 0000 0010 end of packet
-#define TCR_STP 0x01 // 0000 0001 start of packet
+#define EDMSDU 0x04 // end of sdu
+#define TCR_EDP 0x02 // end of packet
+#define TCR_STP 0x01 // start of packet
// max transmit or receive buffer size
-#define CB_MAX_BUF_SIZE 2900U // max buffer size
+#define CB_MAX_BUF_SIZE 2900U
// NOTE: must be multiple of 4
-#define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE // max Tx buffer size
-#define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE // max Rx buffer size when not use Multi-RD
+#define CB_MAX_TX_BUF_SIZE CB_MAX_BUF_SIZE
+#define CB_MAX_RX_BUF_SIZE_NORMAL CB_MAX_BUF_SIZE
-#define CB_BEACON_BUF_SIZE 512U // default beacon buffer size
+#define CB_BEACON_BUF_SIZE 512U
-#define CB_MAX_RX_DESC 128 // max # of descriptor
-#define CB_MIN_RX_DESC 16 // min # of rx descriptor
-#define CB_MAX_TX_DESC 64 // max # of descriptor
-#define CB_MIN_TX_DESC 16 // min # of tx descriptor
+#define CB_MAX_RX_DESC 128
+#define CB_MIN_RX_DESC 16
+#define CB_MAX_TX_DESC 64
+#define CB_MIN_TX_DESC 16
-#define CB_MAX_RECEIVED_PACKETS 16 // max # of received packets at one time
+#define CB_MAX_RECEIVED_PACKETS 16
// limit our receive routine to indicating
// this many at a time for 2 reasons:
// 1. driver flow control to protocol layer
// 2. limit the time used in ISR routine
-#define CB_EXTRA_RD_NUM 32 // default # of Extra RD
-#define CB_RD_NUM 32 // default # of RD
-#define CB_TD_NUM 32 // default # of TD
+#define CB_EXTRA_RD_NUM 32
+#define CB_RD_NUM 32
+#define CB_TD_NUM 32
// max number of physical segments
// in a single NDIS packet. Above this threshold, the packet
@@ -128,61 +126,61 @@
#ifdef __BIG_ENDIAN
// WMAC definition FIFO Control
-#define FIFOCTL_AUTO_FB_1 0x0010 // 0001 0000 0000 0000
-#define FIFOCTL_AUTO_FB_0 0x0008 // 0000 1000 0000 0000
-#define FIFOCTL_GRPACK 0x0004 // 0000 0100 0000 0000
-#define FIFOCTL_11GA 0x0003 // 0000 0011 0000 0000
-#define FIFOCTL_11GB 0x0002 // 0000 0010 0000 0000
-#define FIFOCTL_11B 0x0001 // 0000 0001 0000 0000
-#define FIFOCTL_11A 0x0000 // 0000 0000 0000 0000
-#define FIFOCTL_RTS 0x8000 // 0000 0000 1000 0000
-#define FIFOCTL_ISDMA0 0x4000 // 0000 0000 0100 0000
-#define FIFOCTL_GENINT 0x2000 // 0000 0000 0010 0000
-#define FIFOCTL_TMOEN 0x1000 // 0000 0000 0001 0000
-#define FIFOCTL_LRETRY 0x0800 // 0000 0000 0000 1000
-#define FIFOCTL_CRCDIS 0x0400 // 0000 0000 0000 0100
-#define FIFOCTL_NEEDACK 0x0200 // 0000 0000 0000 0010
-#define FIFOCTL_LHEAD 0x0100 // 0000 0000 0000 0001
+#define FIFOCTL_AUTO_FB_1 0x0010
+#define FIFOCTL_AUTO_FB_0 0x0008
+#define FIFOCTL_GRPACK 0x0004
+#define FIFOCTL_11GA 0x0003
+#define FIFOCTL_11GB 0x0002
+#define FIFOCTL_11B 0x0001
+#define FIFOCTL_11A 0x0000
+#define FIFOCTL_RTS 0x8000
+#define FIFOCTL_ISDMA0 0x4000
+#define FIFOCTL_GENINT 0x2000
+#define FIFOCTL_TMOEN 0x1000
+#define FIFOCTL_LRETRY 0x0800
+#define FIFOCTL_CRCDIS 0x0400
+#define FIFOCTL_NEEDACK 0x0200
+#define FIFOCTL_LHEAD 0x0100
//WMAC definition Frag Control
-#define FRAGCTL_AES 0x0003 // 0000 0011 0000 0000
-#define FRAGCTL_TKIP 0x0002 // 0000 0010 0000 0000
-#define FRAGCTL_LEGACY 0x0001 // 0000 0001 0000 0000
-#define FRAGCTL_NONENCRYPT 0x0000 // 0000 0000 0000 0000
-#define FRAGCTL_ENDFRAG 0x0300 // 0000 0000 0000 0011
-#define FRAGCTL_MIDFRAG 0x0200 // 0000 0000 0000 0010
-#define FRAGCTL_STAFRAG 0x0100 // 0000 0000 0000 0001
-#define FRAGCTL_NONFRAG 0x0000 // 0000 0000 0000 0000
+#define FRAGCTL_AES 0x0003
+#define FRAGCTL_TKIP 0x0002
+#define FRAGCTL_LEGACY 0x0001
+#define FRAGCTL_NONENCRYPT 0x0000
+#define FRAGCTL_ENDFRAG 0x0300
+#define FRAGCTL_MIDFRAG 0x0200
+#define FRAGCTL_STAFRAG 0x0100
+#define FRAGCTL_NONFRAG 0x0000
#else
-#define FIFOCTL_AUTO_FB_1 0x1000 // 0001 0000 0000 0000
-#define FIFOCTL_AUTO_FB_0 0x0800 // 0000 1000 0000 0000
-#define FIFOCTL_GRPACK 0x0400 // 0000 0100 0000 0000
-#define FIFOCTL_11GA 0x0300 // 0000 0011 0000 0000
-#define FIFOCTL_11GB 0x0200 // 0000 0010 0000 0000
-#define FIFOCTL_11B 0x0100 // 0000 0001 0000 0000
-#define FIFOCTL_11A 0x0000 // 0000 0000 0000 0000
-#define FIFOCTL_RTS 0x0080 // 0000 0000 1000 0000
-#define FIFOCTL_ISDMA0 0x0040 // 0000 0000 0100 0000
-#define FIFOCTL_GENINT 0x0020 // 0000 0000 0010 0000
-#define FIFOCTL_TMOEN 0x0010 // 0000 0000 0001 0000
-#define FIFOCTL_LRETRY 0x0008 // 0000 0000 0000 1000
-#define FIFOCTL_CRCDIS 0x0004 // 0000 0000 0000 0100
-#define FIFOCTL_NEEDACK 0x0002 // 0000 0000 0000 0010
-#define FIFOCTL_LHEAD 0x0001 // 0000 0000 0000 0001
+#define FIFOCTL_AUTO_FB_1 0x1000
+#define FIFOCTL_AUTO_FB_0 0x0800
+#define FIFOCTL_GRPACK 0x0400
+#define FIFOCTL_11GA 0x0300
+#define FIFOCTL_11GB 0x0200
+#define FIFOCTL_11B 0x0100
+#define FIFOCTL_11A 0x0000
+#define FIFOCTL_RTS 0x0080
+#define FIFOCTL_ISDMA0 0x0040
+#define FIFOCTL_GENINT 0x0020
+#define FIFOCTL_TMOEN 0x0010
+#define FIFOCTL_LRETRY 0x0008
+#define FIFOCTL_CRCDIS 0x0004
+#define FIFOCTL_NEEDACK 0x0002
+#define FIFOCTL_LHEAD 0x0001
//WMAC definition Frag Control
-#define FRAGCTL_AES 0x0300 // 0000 0011 0000 0000
-#define FRAGCTL_TKIP 0x0200 // 0000 0010 0000 0000
-#define FRAGCTL_LEGACY 0x0100 // 0000 0001 0000 0000
-#define FRAGCTL_NONENCRYPT 0x0000 // 0000 0000 0000 0000
-#define FRAGCTL_ENDFRAG 0x0003 // 0000 0000 0000 0011
-#define FRAGCTL_MIDFRAG 0x0002 // 0000 0000 0000 0010
-#define FRAGCTL_STAFRAG 0x0001 // 0000 0000 0000 0001
-#define FRAGCTL_NONFRAG 0x0000 // 0000 0000 0000 0000
+#define FRAGCTL_AES 0x0300
+#define FRAGCTL_TKIP 0x0200
+#define FRAGCTL_LEGACY 0x0100
+#define FRAGCTL_NONENCRYPT 0x0000
+#define FRAGCTL_ENDFRAG 0x0003
+#define FRAGCTL_MIDFRAG 0x0002
+#define FRAGCTL_STAFRAG 0x0001
+#define FRAGCTL_NONFRAG 0x0000
-#endif // #ifdef __BIG_ENDIAN
+#endif
#define TYPE_TXDMA0 0
#define TYPE_AC0DMA 1
@@ -201,8 +199,6 @@
#define TD_FLAGS_PRIV_SKB 0x02 // check if called from private skb(hostap)
#define TD_FLAGS_PS_RETRY 0x04 // check if PS STA frame re-transmit
-/*--------------------- Export Types ------------------------------*/
-
// ref_sk_buff is used for mapping the skb structure between pre-built driver-obj & running kernel.
// Since different kernel version (2.4x) may change skb structure, i.e. pre-built driver-obj
// may link to older skb that leads error.
@@ -590,12 +586,5 @@ typedef struct tagSKeyEntry {
u32 dwKey4[4];
} __attribute__ ((__packed__))
SKeyEntry;
-/*--------------------- Export Macros ------------------------------*/
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
#endif // __DESC_H__
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index 45fc8a0b9b5c..9bf0ea9af66e 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -185,12 +185,6 @@ typedef enum __device_msg_level {
MSG_LEVEL_DEBUG = 4 //Only for debug purpose.
} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
-typedef enum __device_init_type {
- DEVICE_INIT_COLD = 0, // cold init
- DEVICE_INIT_RESET, // reset init or Dx to D0 power remain init
- DEVICE_INIT_DXPL // Dx to D0 power lost init
-} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
-
//++ NDIS related
#define MAX_BSSIDINFO_4_PMKID 16
@@ -201,8 +195,7 @@ typedef enum __device_init_type {
// PMKID Structures
typedef unsigned char NDIS_802_11_PMKID_VALUE[16];
-typedef enum _NDIS_802_11_WEP_STATUS
-{
+typedef enum _NDIS_802_11_WEP_STATUS {
Ndis802_11WEPEnabled,
Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
Ndis802_11WEPDisabled,
@@ -218,8 +211,7 @@ typedef enum _NDIS_802_11_WEP_STATUS
} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
-typedef enum _NDIS_802_11_STATUS_TYPE
-{
+typedef enum _NDIS_802_11_STATUS_TYPE {
Ndis802_11StatusType_Authentication,
Ndis802_11StatusType_MediaStreamMode,
Ndis802_11StatusType_PMKID_CandidateList,
@@ -227,13 +219,12 @@ typedef enum _NDIS_802_11_STATUS_TYPE
} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
//Added new types for PMKID Candidate lists.
-typedef struct _PMKID_CANDIDATE {
+struct pmkid_candidate {
NDIS_802_11_MAC_ADDRESS BSSID;
unsigned long Flags;
-} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+};
-typedef struct _BSSID_INFO
-{
+typedef struct _BSSID_INFO {
NDIS_802_11_MAC_ADDRESS BSSID;
NDIS_802_11_PMKID_VALUE PMKID;
} BSSID_INFO, *PBSSID_INFO;
@@ -248,7 +239,7 @@ typedef struct tagSPMKIDCandidateEvent {
NDIS_802_11_STATUS_TYPE StatusType;
unsigned long Version; // Version of the structure
unsigned long NumCandidates; // No. of pmkid candidates
- PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
+ struct pmkid_candidate CandidateList[MAX_PMKIDLIST];
} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
//--
@@ -293,8 +284,7 @@ typedef struct tagSCache {
#define CB_MAX_RX_FRAG 64
// DeFragment Control Block, used for collecting fragments prior to reassembly
-typedef struct tagSDeFragControlBlock
-{
+typedef struct tagSDeFragControlBlock {
unsigned short wSequence;
unsigned short wFragNum;
unsigned char abyAddr2[ETH_ALEN];
@@ -332,17 +322,6 @@ typedef struct tagSDeFragControlBlock
//for device_set_media_duplex
#define DEVICE_LINK_CHANGE 0x00000001UL
-//PLICE_DEBUG->
-
-typedef struct _RxManagementQueue
-{
- int packet_num;
- int head, tail;
- PSRxMgmtPacket Q[NUM];
-} RxManagementQueue, *PSRxManagementQueue;
-
-//PLICE_DEBUG<-
-
typedef struct __device_opt {
int nRxDescs0; //Number of RX descriptors0
int nRxDescs1; //Number of RX descriptors1
@@ -391,7 +370,7 @@ typedef struct __device_info {
CHIP_TYPE chip_id;
- unsigned long PortOffset;
+ void __iomem *PortOffset;
unsigned long dwIsr;
u32 memaddr;
u32 ioaddr;
@@ -429,10 +408,7 @@ typedef struct __device_info {
unsigned char byRxMode;
spinlock_t lock;
-//PLICE_DEBUG->
- struct tasklet_struct RxMngWorkItem;
- RxManagementQueue rxManeQueue;
-//PLICE_DEBUG<-
+
//PLICE_DEBUG ->
pid_t MLMEThr_pid;
struct completion notify;
@@ -770,41 +746,7 @@ typedef struct __device_info {
bool bCommit;
} DEVICE_INFO, *PSDevice;
-//PLICE_DEBUG->
-
-inline static void EnQueue(PSDevice pDevice, PSRxMgmtPacket pRxMgmtPacket)
-{
- if ((pDevice->rxManeQueue.tail+1) % NUM == pDevice->rxManeQueue.head) {
- return;
- } else {
- pDevice->rxManeQueue.tail = (pDevice->rxManeQueue.tail + 1) % NUM;
- pDevice->rxManeQueue.Q[pDevice->rxManeQueue.tail] = pRxMgmtPacket;
- pDevice->rxManeQueue.packet_num++;
- }
-}
-
-inline static PSRxMgmtPacket DeQueue(PSDevice pDevice)
-{
- PSRxMgmtPacket pRxMgmtPacket;
- if (pDevice->rxManeQueue.tail == pDevice->rxManeQueue.head) {
- printk("Queue is Empty\n");
- return NULL;
- } else {
- int x;
- //x=pDevice->rxManeQueue.head = (pDevice->rxManeQueue.head+1)%NUM;
- pDevice->rxManeQueue.head = (pDevice->rxManeQueue.head+1)%NUM;
- x = pDevice->rxManeQueue.head;
- pRxMgmtPacket = pDevice->rxManeQueue.Q[x];
- pDevice->rxManeQueue.packet_num--;
- return pRxMgmtPacket;
- }
-}
-
-void InitRxManagementQueue(PSDevice pDevice);
-
-//PLICE_DEBUG<-
-
-inline static bool device_get_ip(PSDevice pInfo) {
+static inline bool device_get_ip(PSDevice pInfo) {
struct in_device *in_dev = (struct in_device *)pInfo->dev->ip_ptr;
struct in_ifaddr *ifa;
diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h
index 1137adede9ee..8e50e538076f 100644
--- a/drivers/staging/vt6655/device_cfg.h
+++ b/drivers/staging/vt6655/device_cfg.h
@@ -27,7 +27,6 @@
#ifndef __DEVICE_CONFIG_H
#define __DEVICE_CONFIG_H
-//#include <linux/config.h>
#include <linux/types.h>
#include "ttype.h"
@@ -60,14 +59,12 @@ struct _version {
#define DEVICE_VERSION "1.19.12"
#endif
-//config file
#include <linux/fs.h>
#include <linux/fcntl.h>
#ifndef CONFIG_PATH
#define CONFIG_PATH "/etc/vntconfiguration.dat"
#endif
-//Max: 2378=2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
#define PKT_BUF_SZ 2390
#define MAX_UINTS 8
@@ -81,7 +78,7 @@ typedef enum _chip_type {
#define ASSERT(x) \
do { \
if (!(x)) { \
- printk(KERN_ERR "assertion %s failed: file %s line %d\n", \
+ pr_err("assertion %s failed: file %s line %d\n", \
#x, __func__, __LINE__); \
*(int *)0 = 0; \
} \
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 1d3908d044d0..c78d06eff7ea 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -98,8 +98,6 @@ MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
-static int mlme_kill;
-
#define DEVICE_PARAM(N, D)
#define RX_DESC_MIN0 16
@@ -260,7 +258,7 @@ static CHIP_INFO chip_info_table[] = {
{0, NULL}
};
-const struct pci_device_id vt6655_pci_id_table[] = {
+static const struct pci_device_id vt6655_pci_id_table[] = {
{ PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
{ 0, }
};
@@ -285,7 +283,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
static int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
static int viawget_resume(struct pci_dev *pcid);
-struct notifier_block device_notifier = {
+static struct notifier_block device_notifier = {
.notifier_call = device_notify_reboot,
.next = NULL,
.priority = 0,
@@ -302,11 +300,11 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
//2008-0714<Add>by Mike Liu
static bool device_release_WPADEV(PSDevice pDevice);
-static int ethtool_ioctl(struct net_device *dev, void *useraddr);
+static int ethtool_ioctl(struct net_device *dev, void __user *useraddr);
static int device_rx_srv(PSDevice pDevice, unsigned int uIdx);
static int device_tx_srv(PSDevice pDevice, unsigned int uIdx);
static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc);
-static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
+static void device_init_registers(PSDevice pDevice);
static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc);
static void device_free_td0_ring(PSDevice pDevice);
static void device_free_td1_ring(PSDevice pDevice);
@@ -324,6 +322,7 @@ static int Config_FileGetParameter(unsigned char *string,
static char *get_chip_name(int chip_id)
{
int i;
+
for (i = 0; chip_info_table[i].name != NULL; i++)
if (chip_info_table[i].chip_id == chip_id)
break;
@@ -385,7 +384,8 @@ device_set_options(PSDevice pDevice) {
pDevice->b11hEnable = (pDevice->sOpts.flags & DEVICE_FLAGS_80211h_MODE) ? 1 : 0;
pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
pDevice->uConnectionRate = pDevice->sOpts.data_rate;
- if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true;
+ if (pDevice->uConnectionRate < RATE_AUTO)
+ pDevice->bFixRate = true;
pDevice->byBBType = pDevice->sOpts.bbp_type;
pDevice->byPacketType = pDevice->byBBType;
@@ -453,7 +453,7 @@ static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult)
// Initialisation of MAC & BBP registers
//
-static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
+static void device_init_registers(PSDevice pDevice)
{
unsigned int ii;
unsigned char byValue;
@@ -462,284 +462,309 @@ static void device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
unsigned char byOFDMPwrdBm = 0;
int zonetype = 0;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+
MACbShutdown(pDevice->PortOffset);
BBvSoftwareReset(pDevice->PortOffset);
- if ((InitType == DEVICE_INIT_COLD) ||
- (InitType == DEVICE_INIT_DXPL)) {
- // Do MACbSoftwareReset in MACvInitialize
- MACbSoftwareReset(pDevice->PortOffset);
- // force CCK
- pDevice->bCCK = true;
- pDevice->bAES = false;
- pDevice->bProtectMode = false; //Only used in 11g type, sync with ERP IE
- pDevice->bNonERPPresent = false;
- pDevice->bBarkerPreambleMd = false;
- pDevice->wCurrentRate = RATE_1M;
- pDevice->byTopOFDMBasicRate = RATE_24M;
- pDevice->byTopCCKBasicRate = RATE_1M;
+ /* Do MACbSoftwareReset in MACvInitialize */
+ MACbSoftwareReset(pDevice->PortOffset);
- pDevice->byRevId = 0; //Target to IF pin while programming to RF chip.
+ /* force CCK */
+ pDevice->bCCK = true;
+ pDevice->bAES = false;
- // init MAC
- MACvInitialize(pDevice->PortOffset);
+ /* Only used in 11g type, sync with ERP IE */
+ pDevice->bProtectMode = false;
- // Get Local ID
- VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &(pDevice->byLocalID));
+ pDevice->bNonERPPresent = false;
+ pDevice->bBarkerPreambleMd = false;
+ pDevice->wCurrentRate = RATE_1M;
+ pDevice->byTopOFDMBasicRate = RATE_24M;
+ pDevice->byTopCCKBasicRate = RATE_1M;
- spin_lock_irq(&pDevice->lock);
- SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
+ /* Target to IF pin while programming to RF chip. */
+ pDevice->byRevId = 0;
- spin_unlock_irq(&pDevice->lock);
+ /* init MAC */
+ MACvInitialize(pDevice->PortOffset);
- // Get Channel range
+ /* Get Local ID */
+ VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &pDevice->byLocalID);
+
+ spin_lock_irq(&pDevice->lock);
- pDevice->byMinChannel = 1;
- pDevice->byMaxChannel = CB_MAX_CHANNEL;
+ SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM);
- // Get Antena
- byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
- if (byValue & EEP_ANTINV)
- pDevice->bTxRxAntInv = true;
+ spin_unlock_irq(&pDevice->lock);
+
+ /* Get Channel range */
+ pDevice->byMinChannel = 1;
+ pDevice->byMaxChannel = CB_MAX_CHANNEL;
+
+ /* Get Antena */
+ byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
+ if (byValue & EEP_ANTINV)
+ pDevice->bTxRxAntInv = true;
+ else
+ pDevice->bTxRxAntInv = false;
+
+ byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+ /* if not set default is All */
+ if (byValue == 0)
+ byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+ pDevice->ulDiversityNValue = 100*260;
+ pDevice->ulDiversityMValue = 100*16;
+ pDevice->byTMax = 1;
+ pDevice->byTMax2 = 4;
+ pDevice->ulSQ3TH = 0;
+ pDevice->byTMax3 = 64;
+
+ if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+ pDevice->byAntennaCount = 2;
+ pDevice->byTxAntennaMode = ANT_B;
+ pDevice->dwTxAntennaSel = 1;
+ pDevice->dwRxAntennaSel = 1;
+
+ if (pDevice->bTxRxAntInv)
+ pDevice->byRxAntennaMode = ANT_A;
else
- pDevice->bTxRxAntInv = false;
+ pDevice->byRxAntennaMode = ANT_B;
- byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
- if (byValue == 0) // if not set default is All
- byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset,
+ EEP_OFS_ANTENNA);
- pDevice->ulDiversityNValue = 100*260;
- pDevice->ulDiversityMValue = 100*16;
- pDevice->byTMax = 1;
- pDevice->byTMax2 = 4;
- pDevice->ulSQ3TH = 0;
- pDevice->byTMax3 = 64;
+ if ((byValue1 & 0x08) == 0)
+ pDevice->bDiversityEnable = false;
+ else
+ pDevice->bDiversityEnable = true;
+ } else {
+ pDevice->bDiversityEnable = false;
+ pDevice->byAntennaCount = 1;
+ pDevice->dwTxAntennaSel = 0;
+ pDevice->dwRxAntennaSel = 0;
+
+ if (byValue & EEP_ANTENNA_AUX) {
+ pDevice->byTxAntennaMode = ANT_A;
- if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
- pDevice->byAntennaCount = 2;
+ if (pDevice->bTxRxAntInv)
+ pDevice->byRxAntennaMode = ANT_B;
+ else
+ pDevice->byRxAntennaMode = ANT_A;
+ } else {
pDevice->byTxAntennaMode = ANT_B;
- pDevice->dwTxAntennaSel = 1;
- pDevice->dwRxAntennaSel = 1;
+
if (pDevice->bTxRxAntInv)
pDevice->byRxAntennaMode = ANT_A;
else
pDevice->byRxAntennaMode = ANT_B;
- // chester for antenna
- byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
- if ((byValue1 & 0x08) == 0)
- pDevice->bDiversityEnable = false;
- else
- pDevice->bDiversityEnable = true;
- } else {
- pDevice->bDiversityEnable = false;
- pDevice->byAntennaCount = 1;
- pDevice->dwTxAntennaSel = 0;
- pDevice->dwRxAntennaSel = 0;
- if (byValue & EEP_ANTENNA_AUX) {
- pDevice->byTxAntennaMode = ANT_A;
- if (pDevice->bTxRxAntInv)
- pDevice->byRxAntennaMode = ANT_B;
- else
- pDevice->byRxAntennaMode = ANT_A;
- } else {
- pDevice->byTxAntennaMode = ANT_B;
- if (pDevice->bTxRxAntInv)
- pDevice->byRxAntennaMode = ANT_A;
- else
- pDevice->byRxAntennaMode = ANT_B;
- }
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
- pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2);
-
-//2008-8-4 <add> by chester
-//zonetype initial
- pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
- zonetype = Config_FileOperation(pDevice, false, NULL);
- if (zonetype >= 0) { //read zonetype file ok!
- if ((zonetype == 0) &&
- (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) { //for USA
- pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
- pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n");
- } else if ((zonetype == 1) &&
- (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { //for Japan
- pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
- pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
- } else if ((zonetype == 2) &&
- (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) { //for Europe
- pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
- pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n");
- }
+ }
- else {
- if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
- printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n", zonetype, pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
- else
- printk("Read Zonetype file success,use default zonetype setting[%02x]\n", zonetype);
- }
- } else
- printk("Read Zonetype file fail,use default zonetype setting[%02x]\n", SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
+ pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue,
+ (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2);
+
+ /* zonetype initial */
+ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ zonetype = Config_FileOperation(pDevice, false, NULL);
+
+ if (zonetype >= 0) {
+ if ((zonetype == 0) &&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) {
+ /* for USA */
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n");
+ } else if ((zonetype == 1) &&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) {
+ /* for Japan */
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+ } else if ((zonetype == 2) &&
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) {
+ /* for Europe */
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
+ pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n");
+ } else {
+ if (zonetype != pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
+ pr_debug("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",
+ zonetype,
+ pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
+ else
+ pr_debug("Read Zonetype file success,use default zonetype setting[%02x]\n",
+ zonetype);
+ }
+ } else {
+ pr_debug("Read Zonetype file fail,use default zonetype setting[%02x]\n",
+ SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ZONETYPE));
+ }
- // Get RFType
- pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
+ /* Get RFType */
+ pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
- if ((pDevice->byRFType & RF_EMU) != 0) {
- // force change RevID for VT3253 emu
+ /* force change RevID for VT3253 emu */
+ if ((pDevice->byRFType & RF_EMU) != 0)
pDevice->byRevId = 0x80;
- }
- pDevice->byRFType &= RF_MASK;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
+ pDevice->byRFType &= RF_MASK;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
- if (!pDevice->bZoneRegExist)
- pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ if (!pDevice->bZoneRegExist)
+ pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
- //Init RF module
- RFbInit(pDevice);
+ /* Init RF module */
+ RFbInit(pDevice);
- //Get Desire Power Value
- pDevice->byCurPwr = 0xFF;
- pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
- pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
+ /* Get Desire Power Value */
+ pDevice->byCurPwr = 0xFF;
+ pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK);
+ pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG);
- // Load power Table
+ /* Load power Table */
+ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
+ pDevice->abyCCKPwrTbl[ii + 1] =
+ SROMbyReadEmbedded(pDevice->PortOffset,
+ (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
+ if (pDevice->abyCCKPwrTbl[ii + 1] == 0)
+ pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
- for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
- pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL));
- if (pDevice->abyCCKPwrTbl[ii + 1] == 0)
- pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr;
+ pDevice->abyOFDMPwrTbl[ii + 1] =
+ SROMbyReadEmbedded(pDevice->PortOffset,
+ (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
+ if (pDevice->abyOFDMPwrTbl[ii + 1] == 0)
+ pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
- pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL));
- if (pDevice->abyOFDMPwrTbl[ii + 1] == 0)
- pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG;
+ pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
+ pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
+ }
- pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm;
- pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm;
- }
- //2008-8-4 <add> by chester
- //recover 12,13 ,14channel for EUROPE by 11 channel
- if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
- (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
- (pDevice->byOriginalZonetype == ZoneType_USA)) {
- for (ii = 11; ii < 14; ii++) {
- pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
- pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
+ /* recover 12,13 ,14channel for EUROPE by 11 channel */
+ if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
+ (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
+ (pDevice->byOriginalZonetype == ZoneType_USA)) {
+ for (ii = 11; ii < 14; ii++) {
+ pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
+ pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
- }
}
+ }
- // Load OFDM A Power Table
- for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
- pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
- pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
- }
- init_channel_table((void *)pDevice);
+ /* Load OFDM A Power Table */
+ for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
+ pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] =
+ SROMbyReadEmbedded(pDevice->PortOffset,
+ (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL));
- if (pDevice->byLocalID > REV_ID_VT3253_B1) {
- MACvSelectPage1(pDevice->PortOffset);
- VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
- MACvSelectPage0(pDevice->PortOffset);
- }
+ pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] =
+ SROMbyReadEmbedded(pDevice->PortOffset,
+ (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm));
+ }
- // use relative tx timeout and 802.11i D4
- MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
+ init_channel_table((void *)pDevice);
- // set performance parameter by registry
- MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
- MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
+ if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+ MACvSelectPage1(pDevice->PortOffset);
- // reset TSF counter
- VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
- // enable TSF counter
- VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1,
+ (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN));
- // initialize BBP registers
- BBbVT3253Init(pDevice);
+ MACvSelectPage0(pDevice->PortOffset);
+ }
- if (pDevice->bUpdateBBVGA) {
- pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
- pDevice->byBBVGANew = pDevice->byBBVGACurrent;
- BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
- }
- BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
- BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
+ /* use relative tx timeout and 802.11i D4 */
+ MACvWordRegBitsOn(pDevice->PortOffset,
+ MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT));
- pDevice->byCurrentCh = 0;
+ /* set performance parameter by registry */
+ MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit);
+ MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit);
- // Set BB and packet type at the same time.
- // Set Short Slot Time, xIFS, and RSPINF.
- if (pDevice->uConnectionRate == RATE_AUTO)
- pDevice->wCurrentRate = RATE_54M;
- else
- pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
+ /* reset TSF counter */
+ VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+ /* enable TSF counter */
+ VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+
+ /* initialize BBP registers */
+ BBbVT3253Init(pDevice);
- // default G Mode
- VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
- VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
+ if (pDevice->bUpdateBBVGA) {
+ pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+ pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+ BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+ }
- pDevice->bRadioOff = false;
+ BBvSetRxAntennaMode(pDevice->PortOffset, pDevice->byRxAntennaMode);
+ BBvSetTxAntennaMode(pDevice->PortOffset, pDevice->byTxAntennaMode);
- pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL);
- pDevice->bHWRadioOff = false;
+ pDevice->byCurrentCh = 0;
- if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
- // Get GPIO
- MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
-//2008-4-14 <add> by chester for led issue
-#ifdef FOR_LED_ON_NOTEBOOK
- if (pDevice->byGPIO & GPIO0_DATA)
- pDevice->bHWRadioOff = true;
+ /* Set BB and packet type at the same time. */
+ /* Set Short Slot Time, xIFS, and RSPINF. */
+ if (pDevice->uConnectionRate == RATE_AUTO)
+ pDevice->wCurrentRate = RATE_54M;
+ else
+ pDevice->wCurrentRate = (unsigned short)pDevice->uConnectionRate;
- if (!(pDevice->byGPIO & GPIO0_DATA))
- pDevice->bHWRadioOff = false;
- }
+ /* default G Mode */
+ VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_11G);
+ VNTWIFIbConfigPhyMode(pDevice->pMgmt, PHY_TYPE_AUTO);
- if (pDevice->bRadioControlOff)
- CARDbRadioPowerOff(pDevice);
- else
- CARDbRadioPowerOn(pDevice);
-#else
- if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
- (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
+ pDevice->bRadioOff = false;
+
+ pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset,
+ EEP_OFS_RADIOCTL);
+ pDevice->bHWRadioOff = false;
+
+ if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) {
+ /* Get GPIO */
+ MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
+
+ if (((pDevice->byGPIO & GPIO0_DATA) &&
+ !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
+ (!(pDevice->byGPIO & GPIO0_DATA) &&
+ (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
pDevice->bHWRadioOff = true;
- }
}
+
if (pDevice->bHWRadioOff || pDevice->bRadioControlOff)
CARDbRadioPowerOff(pDevice);
-#endif
-}
-pMgmt->eScanType = WMAC_SCAN_PASSIVE;
-// get Permanent network address
-SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
-DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n",
- pDevice->abyCurrentNetAddr);
+ pMgmt->eScanType = WMAC_SCAN_PASSIVE;
-// reset Tx pointer
-CARDvSafeResetRx(pDevice);
-// reset Rx pointer
-CARDvSafeResetTx(pDevice);
+ /* get Permanent network address */
+ SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n",
+ pDevice->abyCurrentNetAddr);
-if (pDevice->byLocalID <= REV_ID_VT3253_A1)
- MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
+ /* reset Tx pointer */
+ CARDvSafeResetRx(pDevice);
+ /* reset Rx pointer */
+ CARDvSafeResetTx(pDevice);
-pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ if (pDevice->byLocalID <= REV_ID_VT3253_A1)
+ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR);
-// Turn On Rx DMA
-MACvReceive0(pDevice->PortOffset);
-MACvReceive1(pDevice->PortOffset);
+ pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-// start the adapter
-MACvStart(pDevice->PortOffset);
+ /* Turn On Rx DMA */
+ MACvReceive0(pDevice->PortOffset);
+ MACvReceive1(pDevice->PortOffset);
-netif_stop_queue(pDevice->dev);
+ /* start the adapter */
+ MACvStart(pDevice->PortOffset);
+
+ netif_stop_queue(pDevice->dev);
}
-static void device_init_diversity_timer(PSDevice pDevice) {
+static void device_init_diversity_timer(PSDevice pDevice)
+{
init_timer(&pDevice->TimerSQ3Tmax1);
pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
@@ -754,8 +779,6 @@ static void device_init_diversity_timer(PSDevice pDevice) {
pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerState1CallBack;
pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
-
- return;
}
static bool device_release_WPADEV(PSDevice pDevice)
@@ -806,8 +829,9 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
PCHIP_INFO pChip_info = (PCHIP_INFO)ent->driver_data;
PSDevice pDevice;
int rc;
+
if (device_nics++ >= MAX_UINTS) {
- printk(KERN_NOTICE DEVICE_NAME ": already found %d NICs\n", device_nics);
+ pr_notice(DEVICE_NAME ": already found %d NICs\n", device_nics);
return -ENODEV;
}
@@ -816,7 +840,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
pDevice = (PSDevice) netdev_priv(dev);
if (dev == NULL) {
- printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
+ pr_err(DEVICE_NAME ": allocate net device failed\n");
return -ENOMEM;
}
@@ -824,8 +848,8 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pcid->dev);
if (bFirst) {
- printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
- printk(KERN_NOTICE "Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
+ pr_notice("%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+ pr_notice("Copyright (c) 2003 VIA Networking Technologies, Inc.\n");
bFirst = false;
}
@@ -841,10 +865,10 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
dev->irq = pcid->irq;
#ifdef DEBUG
- printk("Before get pci_info memaddr is %x\n", pDevice->memaddr);
+ pr_debug("Before get pci_info memaddr is %x\n", pDevice->memaddr);
#endif
if (!device_get_pci_info(pDevice, pcid)) {
- printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device.\n");
+ pr_err(DEVICE_NAME ": Failed to find PCI device.\n");
device_free_info(pDevice);
return -ENODEV;
}
@@ -853,7 +877,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
#ifdef DEBUG
- printk("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size);
+ pr_debug("after get pci_info memaddr is %x, io addr is %x,io_size is %d\n", pDevice->memaddr, pDevice->ioaddr, pDevice->io_size);
{
int i;
u32 bar, len;
@@ -867,9 +891,9 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
0};
for (i = 0; address[i]; i++) {
pci_read_config_dword(pcid, address[i], &bar);
- printk("bar %d is %x\n", i, bar);
+ pr_debug("bar %d is %x\n", i, bar);
if (!bar) {
- printk("bar %d not implemented\n", i);
+ pr_debug("bar %d not implemented\n", i);
continue;
}
if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
@@ -878,12 +902,12 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
len = len & ~(len - 1);
- printk("IO space: len in IO %x, BAR %d\n", len, i);
+ pr_debug("IO space: len in IO %x, BAR %d\n", len, i);
} else {
len = bar & 0xFFFFFFF0;
len = ~len + 1;
- printk("len in MEM %x, BAR %d\n", len, i);
+ pr_debug("len in MEM %x, BAR %d\n", len, i);
}
}
}
@@ -891,17 +915,17 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
#endif
- pDevice->PortOffset = (unsigned long)ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
+ pDevice->PortOffset = ioremap(pDevice->memaddr & PCI_BASE_ADDRESS_MEM_MASK, pDevice->io_size);
- if (pDevice->PortOffset == 0) {
- printk(KERN_ERR DEVICE_NAME ": Failed to IO remapping ..\n");
+ if (pDevice->PortOffset == NULL) {
+ pr_err(DEVICE_NAME ": Failed to IO remapping ..\n");
device_free_info(pDevice);
return -ENODEV;
}
rc = pci_request_regions(pcid, DEVICE_NAME);
if (rc) {
- printk(KERN_ERR DEVICE_NAME ": Failed to find PCI device\n");
+ pr_err(DEVICE_NAME ": Failed to find PCI device\n");
device_free_info(pDevice);
return -ENODEV;
}
@@ -911,18 +935,14 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
unsigned char value;
VNSvInPortB(pDevice->PortOffset+0x4F, &value);
- printk("Before write: value is %x\n", value);
+ pr_debug("Before write: value is %x\n", value);
VNSvOutPortB(pDevice->PortOffset, value);
VNSvInPortB(pDevice->PortOffset+0x4F, &value);
- printk("After write: value is %x\n", value);
-#endif
-
-#ifdef IO_MAP
- pDevice->PortOffset = pDevice->ioaddr;
+ pr_debug("After write: value is %x\n", value);
#endif
// do reset
if (!MACbSoftwareReset(pDevice->PortOffset)) {
- printk(KERN_ERR DEVICE_NAME ": Failed to access MAC hardware..\n");
+ pr_err(DEVICE_NAME ": Failed to access MAC hardware..\n");
device_free_info(pDevice);
return -ENODEV;
}
@@ -948,7 +968,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
rc = register_netdev(dev);
if (rc) {
- printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+ pr_err(DEVICE_NAME " Failed to register netdev\n");
device_free_info(pDevice);
return -ENODEV;
}
@@ -963,14 +983,10 @@ static void device_print_info(PSDevice pDevice)
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id));
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
-#ifdef IO_MAP
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx ", (unsigned long)pDevice->ioaddr);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq);
-#else
+
DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ",
(unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d \n", pDevice->dev->irq);
-#endif
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq);
}
static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice,
@@ -997,7 +1013,8 @@ static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice,
spin_lock_init(&((*ppDevice)->lock));
}
-static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) {
+static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid)
+{
u16 pci_cmd;
u8 b;
unsigned int cis_addr;
@@ -1006,6 +1023,7 @@ static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) {
unsigned char value = 0x00;
int ii, j;
u16 max_lat = 0x0000;
+
memset(pci_config, 0x00, 256);
#endif
@@ -1033,17 +1051,18 @@ static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) {
}
for (ii = 0, j = 1; ii < 0x100; ii++, j++) {
if (j % 16 == 0) {
- printk("%x:", pci_config[ii]);
- printk("\n");
+ pr_debug("%x:", pci_config[ii]);
+ pr_debug("\n");
} else {
- printk("%x:", pci_config[ii]);
+ pr_debug("%x:", pci_config[ii]);
}
}
#endif
return true;
}
-static void device_free_info(PSDevice pDevice) {
+static void device_free_info(PSDevice pDevice)
+{
PSDevice ptr;
struct net_device *dev = pDevice->dev;
@@ -1054,7 +1073,7 @@ static void device_free_info(PSDevice pDevice) {
//2008-07-21-01<Add>by MikeLiu
//unregister wpadev
if (wpa_set_wpadev(pDevice, 0) != 0)
- printk("unregister wpadev fail?\n");
+ pr_err("unregister wpadev fail?\n");
if (pDevice_Infos == NULL)
return;
@@ -1079,7 +1098,7 @@ static void device_free_info(PSDevice pDevice) {
unregister_netdev(dev);
if (pDevice->PortOffset)
- iounmap((void *)pDevice->PortOffset);
+ iounmap(pDevice->PortOffset);
if (pDevice->pcid)
pci_release_regions(pDevice->pcid);
@@ -1087,7 +1106,8 @@ static void device_free_info(PSDevice pDevice) {
free_netdev(dev);
}
-static bool device_init_rings(PSDevice pDevice) {
+static bool device_init_rings(PSDevice pDevice)
+{
void *vir_pool;
/*allocate all RD/TD rings a single pool*/
@@ -1178,7 +1198,8 @@ static bool device_init_rings(PSDevice pDevice) {
return true;
}
-static void device_free_rings(PSDevice pDevice) {
+static void device_free_rings(PSDevice pDevice)
+{
pci_free_consistent(pDevice->pcid,
pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
@@ -1198,7 +1219,8 @@ static void device_free_rings(PSDevice pDevice) {
);
}
-static void device_init_rd0_ring(PSDevice pDevice) {
+static void device_init_rd0_ring(PSDevice pDevice)
+{
int i;
dma_addr_t curr = pDevice->rd0_pool_dma;
PSRxDesc pDesc;
@@ -1222,7 +1244,8 @@ static void device_init_rd0_ring(PSDevice pDevice) {
pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
}
-static void device_init_rd1_ring(PSDevice pDevice) {
+static void device_init_rd1_ring(PSDevice pDevice)
+{
int i;
dma_addr_t curr = pDevice->rd1_pool_dma;
PSRxDesc pDesc;
@@ -1246,7 +1269,8 @@ static void device_init_rd1_ring(PSDevice pDevice) {
pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
}
-static void device_init_defrag_cb(PSDevice pDevice) {
+static void device_init_defrag_cb(PSDevice pDevice)
+{
int i;
PSDeFragControlBlock pDeF;
@@ -1262,7 +1286,8 @@ static void device_init_defrag_cb(PSDevice pDevice) {
pDevice->cbFreeDFCB = pDevice->cbDFCB;
}
-static void device_free_rd0_ring(PSDevice pDevice) {
+static void device_free_rd0_ring(PSDevice pDevice)
+{
int i;
for (i = 0; i < pDevice->sOpts.nRxDescs0; i++) {
@@ -1278,7 +1303,8 @@ static void device_free_rd0_ring(PSDevice pDevice) {
}
}
-static void device_free_rd1_ring(PSDevice pDevice) {
+static void device_free_rd1_ring(PSDevice pDevice)
+{
int i;
for (i = 0; i < pDevice->sOpts.nRxDescs1; i++) {
@@ -1294,7 +1320,8 @@ static void device_free_rd1_ring(PSDevice pDevice) {
}
}
-static void device_free_frag_buf(PSDevice pDevice) {
+static void device_free_frag_buf(PSDevice pDevice)
+{
PSDeFragControlBlock pDeF;
int i;
@@ -1307,7 +1334,8 @@ static void device_free_frag_buf(PSDevice pDevice) {
}
}
-static void device_init_td0_ring(PSDevice pDevice) {
+static void device_init_td0_ring(PSDevice pDevice)
+{
int i;
dma_addr_t curr;
PSTxDesc pDesc;
@@ -1331,7 +1359,8 @@ static void device_init_td0_ring(PSDevice pDevice) {
pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]);
}
-static void device_init_td1_ring(PSDevice pDevice) {
+static void device_init_td1_ring(PSDevice pDevice)
+{
int i;
dma_addr_t curr;
PSTxDesc pDesc;
@@ -1356,8 +1385,10 @@ static void device_init_td1_ring(PSDevice pDevice) {
pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
}
-static void device_free_td0_ring(PSDevice pDevice) {
+static void device_free_td0_ring(PSDevice pDevice)
+{
int i;
+
for (i = 0; i < pDevice->sOpts.nTxDescs[0]; i++) {
PSTxDesc pDesc = &(pDevice->apTD0Rings[i]);
PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
@@ -1373,7 +1404,8 @@ static void device_free_td0_ring(PSDevice pDevice) {
}
}
-static void device_free_td1_ring(PSDevice pDevice) {
+static void device_free_td1_ring(PSDevice pDevice)
+{
int i;
for (i = 0; i < pDevice->sOpts.nTxDescs[1]; i++) {
@@ -1393,7 +1425,8 @@ static void device_free_td1_ring(PSDevice pDevice) {
/*-----------------------------------------------------------------*/
-static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) {
+static int device_rx_srv(PSDevice pDevice, unsigned int uIdx)
+{
PSRxDesc pRD;
int works = 0;
@@ -1418,7 +1451,8 @@ static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) {
return works;
}
-static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
+static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD)
+{
PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo;
pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
@@ -1438,7 +1472,8 @@ static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
return true;
}
-bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
+bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF)
+{
pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
if (pDeF->skb == NULL)
return false;
@@ -1448,7 +1483,8 @@ bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
return true;
}
-static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
+static int device_tx_srv(PSDevice pDevice, unsigned int uIdx)
+{
PSTxDesc pTD;
bool bFull = false;
int works = 0;
@@ -1510,7 +1546,7 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
if (pDevice->bEnableHostapd) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif..\n");
skb = pTD->pTDInfo->skb;
skb->dev = pDevice->apdev;
skb_reset_mac_header(skb);
@@ -1571,7 +1607,8 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) {
return works;
}
-static void device_error(PSDevice pDevice, unsigned short status) {
+static void device_error(PSDevice pDevice, unsigned short status)
+{
if (status & ISR_FETALERR) {
DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
"%s: Hardware fatal error.\n",
@@ -1585,7 +1622,8 @@ static void device_error(PSDevice pDevice, unsigned short status) {
}
}
-static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) {
+static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc)
+{
PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo;
struct sk_buff *skb = pTDInfo->skb;
@@ -1599,44 +1637,12 @@ static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) {
dev_kfree_skb_irq(skb);
pTDInfo->skb_dma = 0;
- pTDInfo->skb = 0;
+ pTDInfo->skb = NULL;
pTDInfo->byFlags = 0;
}
-//PLICE_DEBUG ->
-void InitRxManagementQueue(PSDevice pDevice)
-{
- pDevice->rxManeQueue.packet_num = 0;
- pDevice->rxManeQueue.head = pDevice->rxManeQueue.tail = 0;
-}
-//PLICE_DEBUG<-
-
-//PLICE_DEBUG ->
-int MlmeThread(
- void *Context)
+static int device_open(struct net_device *dev)
{
- PSDevice pDevice = (PSDevice) Context;
- PSRxMgmtPacket pRxMgmtPacket;
-
- while (1) {
- spin_lock_irq(&pDevice->lock);
- while (pDevice->rxManeQueue.packet_num != 0) {
- pRxMgmtPacket = DeQueue(pDevice);
- vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
- }
- spin_unlock_irq(&pDevice->lock);
- if (mlme_kill == 0)
- break;
-
- schedule();
- if (mlme_kill == 0)
- break;
- }
-
- return 0;
-}
-
-static int device_open(struct net_device *dev) {
PSDevice pDevice = (PSDevice)netdev_priv(dev);
int i;
#ifdef WPA_SM_Transtatus
@@ -1673,24 +1679,9 @@ static int device_open(struct net_device *dev) {
vMgrObjectInit(pDevice);
vMgrTimerInit(pDevice);
-//PLICE_DEBUG->
-#ifdef TASK_LET
- tasklet_init(&pDevice->RxMngWorkItem, (void *)MngWorkItem, (unsigned long)pDevice);
-#endif
-#ifdef THREAD
- InitRxManagementQueue(pDevice);
- mlme_kill = 0;
- mlme_task = kthread_run(MlmeThread, (void *)pDevice, "MLME");
- if (IS_ERR(mlme_task)) {
- printk("thread create fail\n");
- return -1;
- }
-
- mlme_kill = 1;
-#endif
-
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
- device_init_registers(pDevice, DEVICE_INIT_COLD);
+ device_init_registers(pDevice);
+
MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN);
device_set_multi(pDevice->dev);
@@ -1730,17 +1721,15 @@ static int device_open(struct net_device *dev) {
}
pDevice->flags |= DEVICE_FLAGS_OPENED;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
return 0;
}
-static int device_close(struct net_device *dev) {
+static int device_close(struct net_device *dev)
+{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = pDevice->pMgmt;
//PLICE_DEBUG->
-#ifdef THREAD
- mlme_kill = 0;
-#endif
//PLICE_DEBUG<-
//2007-1121-02<Add>by EinsnLiu
if (pDevice->bLinkPass) {
@@ -1758,9 +1747,6 @@ static int device_close(struct net_device *dev) {
del_timer(&pDevice->TimerSQ3Tmax3);
}
-#ifdef TASK_LET
- tasklet_kill(&pDevice->RxMngWorkItem);
-#endif
netif_stop_queue(dev);
pDevice->bCmdRunning = false;
MACbShutdown(pDevice->PortOffset);
@@ -1782,11 +1768,12 @@ static int device_close(struct net_device *dev) {
//2008-0714-01<Add>by chester
device_release_WPADEV(pDevice);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close..\n");
return 0;
}
-static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
+{
PSDevice pDevice = netdev_priv(dev);
unsigned char *pbMPDU;
unsigned int cbMPDULen = 0;
@@ -1817,7 +1804,8 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
return 0;
}
-bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex) {
+bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex)
+{
PSMgmtObject pMgmt = pDevice->pMgmt;
PSTxDesc pHeadTD, pLastTD;
unsigned int cbFrameBodySize;
@@ -1889,7 +1877,7 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI
else
pDevice->byPreambleType = PREAMBLE_LONG;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate);
if (pDevice->wCurrentRate <= RATE_11M) {
byPktType = PK_TYPE_11B;
@@ -1956,7 +1944,8 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI
}
//TYPE_AC0DMA data tx
-static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
+static int device_xmit(struct sk_buff *skb, struct net_device *dev)
+{
PSDevice pDevice = netdev_priv(dev);
PSMgmtObject pMgmt = pDevice->pMgmt;
@@ -2032,7 +2021,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
}
if (!bNodeExist) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB\n");
dev_kfree_skb_irq(skb);
spin_unlock_irq(&pDevice->lock);
return 0;
@@ -2070,9 +2059,9 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
}
} else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
pbyBSSID = pDevice->sTxEthHeader.abyDstAddr; //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key: \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key:\n");
for (ii = 0; ii < 6; ii++)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x \n", *(pbyBSSID+ii));
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x\n", *(pbyBSSID+ii));
DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n");
// get pairwise key
@@ -2130,7 +2119,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
if (pDevice->bFixRate) {
#ifdef PLICE_DEBUG
- printk("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate);
+ pr_debug("Fix Rate: PhyType is %d,ConnectionRate is %d\n", pDevice->eCurrentPHYType, pDevice->uConnectionRate);
#endif
if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
@@ -2268,7 +2257,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
if (pDevice->bFixRate)
- printk("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
+ pr_debug("FixRate:Rate is %d,TxPower is %d\n", pDevice->wCurrentRate, pDevice->byCurPwr);
{
unsigned char Protocol_Version; //802.1x Authentication
@@ -2276,6 +2265,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
unsigned char Descriptor_type;
unsigned short Key_info;
bool bTxeapol_key = false;
+
Protocol_Version = skb->data[ETH_HLEN];
Packet_Type = skb->data[ETH_HLEN+1];
Descriptor_type = skb->data[ETH_HLEN+1+1+2];
@@ -2289,10 +2279,10 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
(Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
pDevice->fWPA_Authened = true;
if (Descriptor_type == 254)
- printk("WPA ");
+ pr_debug("WPA ");
else
- printk("WPA2 ");
- printk("Authentication completed!!\n");
+ pr_debug("WPA2 ");
+ pr_debug("Authentication completed!!\n");
}
}
}
@@ -2307,7 +2297,8 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) {
return 0;
}
-static irqreturn_t device_intr(int irq, void *dev_instance) {
+static irqreturn_t device_intr(int irq, void *dev_instance)
+{
struct net_device *dev = dev_instance;
PSDevice pDevice = (PSDevice)netdev_priv(dev);
@@ -2318,6 +2309,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {
int handled = 0;
unsigned char byData = 0;
int ii = 0;
+ unsigned long flags;
MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
@@ -2331,7 +2323,8 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {
handled = 1;
MACvIntDisable(pDevice->PortOffset);
- spin_lock_irq(&pDevice->lock);
+
+ spin_lock_irqsave(&pDevice->lock, flags);
//Make sure current page is 0
VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel);
@@ -2351,7 +2344,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {
MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
if (pDevice->dwIsr & ISR_FETALERR) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR\n");
VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
device_error(pDevice, pDevice->dwIsr);
@@ -2560,7 +2553,8 @@ static irqreturn_t device_intr(int irq, void *dev_instance) {
if (byOrgPageSel == 1)
MACvSelectPage1(pDevice->PortOffset);
- spin_unlock_irq(&pDevice->lock);
+ spin_unlock_irqrestore(&pDevice->lock, flags);
+
MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
return IRQ_RETVAL(handled);
@@ -2574,6 +2568,7 @@ static inline u32 ether_crc(int length, unsigned char *data)
while (--length >= 0) {
unsigned char current_octet = *data++;
int bit;
+
for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
crc = (crc << 1) ^
((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
@@ -2598,45 +2593,45 @@ static int Config_FileGetParameter(unsigned char *string,
return true;
}
-int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter)
+int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter)
{
unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
unsigned char tmpbuffer[20];
struct file *file;
- int result=0;
+ int result = 0;
if (!buffer) {
- printk("allocate mem for file fail?\n");
+ pr_err("allocate mem for file fail?\n");
return -1;
}
file = filp_open(CONFIG_PATH, O_RDONLY, 0);
if (IS_ERR(file)) {
kfree(buffer);
- printk("Config_FileOperation:open file fail?\n");
+ pr_err("Config_FileOperation:open file fail?\n");
return -1;
}
if (kernel_read(file, 0, buffer, 1024) < 0) {
- printk("read file error?\n");
+ pr_err("read file error?\n");
result = -1;
goto error1;
}
if (Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer)!=true) {
- printk("get parameter error?\n");
+ pr_err("get parameter error?\n");
result = -1;
goto error1;
}
- if (memcmp(tmpbuffer,"USA",3)==0) {
+ if (memcmp(tmpbuffer, "USA", 3) == 0) {
result = ZoneType_USA;
- } else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+ } else if(memcmp(tmpbuffer, "JAPAN", 5) == 0) {
result = ZoneType_Japan;
- } else if(memcmp(tmpbuffer,"EUROPE",5)==0) {
+ } else if(memcmp(tmpbuffer, "EUROPE", 5) == 0) {
result = ZoneType_Europe;
} else {
result = -1;
- printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+ pr_err("Unknown Zonetype[%s]?\n", tmpbuffer);
}
error1:
@@ -2645,7 +2640,8 @@ error1:
return result;
}
-static void device_set_multi(struct net_device *dev) {
+static void device_set_multi(struct net_device *dev)
+{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = pDevice->pMgmt;
@@ -2669,6 +2665,7 @@ static void device_set_multi(struct net_device *dev) {
memset(mc_filter, 0, sizeof(mc_filter));
netdev_for_each_mc_addr(ha, dev) {
int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
+
mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
}
MACvSelectPage1(pDevice->PortOffset);
@@ -2689,13 +2686,15 @@ static void device_set_multi(struct net_device *dev) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode);
}
-static struct net_device_stats *device_get_stats(struct net_device *dev) {
+static struct net_device_stats *device_get_stats(struct net_device *dev)
+{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
return &pDevice->stats;
}
-static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
+static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
struct iwreq *wrq = (struct iwreq *)rq;
@@ -2732,6 +2731,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
{
char essid[IW_ESSID_MAX_SIZE+1];
+
if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
rc = -E2BIG;
break;
@@ -2751,6 +2751,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
{
char essid[IW_ESSID_MAX_SIZE+1];
+
if (wrq->u.essid.pointer)
rc = iwctl_giwessid(dev, NULL,
&(wrq->u.essid), essid);
@@ -2773,13 +2774,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
// Set desired station name
case SIOCSIWNICKN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN\n");
rc = -EOPNOTSUPP;
break;
// Get current station name
case SIOCGIWNICKN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN\n");
rc = -EOPNOTSUPP;
break;
@@ -2863,7 +2864,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
char abyKey[WLAN_WEP232_KEYLEN];
rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
- if (rc != 0) break;
+ if (rc != 0)
+ break;
if (wrq->u.encoding.pointer) {
if (copy_to_user(wrq->u.encoding.pointer,
abyKey,
@@ -2875,12 +2877,12 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
// Get the current Tx-Power
case SIOCGIWTXPOW:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW\n");
rc = -EOPNOTSUPP;
break;
case SIOCSIWTXPOW:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW\n");
rc = -EOPNOTSUPP;
break;
@@ -2923,7 +2925,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
break;
case SIOCSIWSENS:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS\n");
rc = -EOPNOTSUPP;
break;
@@ -2947,49 +2949,50 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
// Set the spy list
case SIOCSIWSPY:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY\n");
rc = -EOPNOTSUPP;
break;
// Get the spy list
case SIOCGIWSPY:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY\n");
rc = -EOPNOTSUPP;
break;
#endif // WIRELESS_SPY
case SIOCGIWPRIV:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV\n");
rc = -EOPNOTSUPP;
break;
//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
case SIOCSIWAUTH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
break;
case SIOCGIWAUTH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH\n");
rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
break;
case SIOCSIWGENIE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE\n");
rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
break;
case SIOCGIWGENIE:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE\n");
rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
break;
case SIOCSIWENCODEEXT: {
char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT\n");
if (wrq->u.encoding.pointer) {
memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN + 1);
if (wrq->u.encoding.length > (sizeof(struct iw_encode_ext) + MAX_KEY_LEN)) {
@@ -3009,12 +3012,12 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
break;
case SIOCGIWENCODEEXT:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT\n");
rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
break;
case SIOCSIWMLME:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
break;
@@ -3067,7 +3070,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
break;
case SIOCETHTOOL:
- return ethtool_ioctl(dev, (void *)rq->ifr_data);
+ return ethtool_ioctl(dev, rq->ifr_data);
// All other calls are currently unsupported
default:
@@ -3103,7 +3106,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
return rc;
}
-static int ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int ethtool_ioctl(struct net_device *dev, void __user *useraddr)
{
u32 ethcmd;
@@ -3113,6 +3116,7 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr)
switch (ethcmd) {
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+
strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
@@ -3169,6 +3173,7 @@ static int
device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
{
struct pci_dev *pdev = NULL;
+
switch (event) {
case SYS_DOWN:
case SYS_HALT:
@@ -3224,7 +3229,7 @@ viawget_resume(struct pci_dev *pcid)
if (netif_running(pDevice->dev)) {
spin_lock_irq(&pDevice->lock);
MACvRestoreContext(pDevice->PortOffset, pDevice->abyMacContext);
- device_init_registers(pDevice, DEVICE_INIT_DXPL);
+ device_init_registers(pDevice);
if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
pMgmt->sNodeDBTable[0].bActive = false;
pDevice->bLinkPass = false;
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
index 7ddaf2603ba6..0bcf6c7472fe 100644
--- a/drivers/staging/vt6655/dpc.c
+++ b/drivers/staging/vt6655/dpc.c
@@ -54,6 +54,7 @@
#include "rf.h"
#include "iowpa.h"
#include "aes_ccmp.h"
+#include "dpc.h"
/*--------------------- Static Definitions -------------------------*/
@@ -62,7 +63,7 @@
/*--------------------- Static Variables --------------------------*/
static int msglevel = MSG_LEVEL_INFO;
-const unsigned char acbyRxRate[MAX_RATE] =
+static const unsigned char acbyRxRate[MAX_RATE] =
{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
/*--------------------- Static Functions --------------------------*/
@@ -267,23 +268,6 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize,
*pcbHeaderSize = cbHeaderSize;
}
-//PLICE_DEBUG ->
-
-void MngWorkItem(void *Context)
-{
- PSRxMgmtPacket pRxMgmtPacket;
- PSDevice pDevice = (PSDevice) Context;
-
- spin_lock_irq(&pDevice->lock);
- while (pDevice->rxManeQueue.packet_num != 0) {
- pRxMgmtPacket = DeQueue(pDevice);
- vMgrRxManagePacket(pDevice, pDevice->pMgmt, pRxMgmtPacket);
- }
- spin_unlock_irq(&pDevice->lock);
-}
-
-//PLICE_DEBUG<-
-
bool
device_receive_frame(
PSDevice pDevice,
@@ -340,7 +324,7 @@ device_receive_frame(
// Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
if ((FrameSize > 2364) || (FrameSize <= 32)) {
// Frame Size error drop this packet.
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1 \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1\n");
return false;
}
@@ -358,7 +342,7 @@ device_receive_frame(
if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
// Min: 14 bytes ACK
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2 \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n");
return false;
}
//PLICE_DEBUG->
@@ -545,21 +529,9 @@ device_receive_frame(
}
pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
-//PLICE_DEBUG->
-#ifdef THREAD
- EnQueue(pDevice, pRxPacket);
-#else
-
-#ifdef TASK_LET
- EnQueue(pDevice, pRxPacket);
- tasklet_schedule(&pDevice->RxMngWorkItem);
-#else
vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket);
-#endif
-#endif
-//PLICE_DEBUG<-
// hostap Deamon handle 802.11 management
if (pDevice->bEnableHostapd) {
skb->dev = pDevice->apdev;
@@ -603,6 +575,7 @@ device_receive_frame(
{
unsigned char Protocol_Version; //802.1x Authentication
unsigned char Packet_Type; //802.1x Authentication
+
if (bIsWEP)
cbIVOffset = 8;
else
@@ -669,7 +642,7 @@ device_receive_frame(
wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) |
skb->data[cbIVOffset + 4 + 24 + 6 + 1];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wEtherType = %04x \n", wEtherType);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wEtherType = %04x\n", wEtherType);
if (wEtherType == ETH_P_PAE) {
skb->dev = pDevice->apdev;
@@ -760,6 +733,7 @@ device_receive_frame(
union iwreq_data wrqu;
struct iw_michaelmicfailure ev;
int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
+
memset(&ev, 0, sizeof(ev));
ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
@@ -1113,6 +1087,7 @@ static bool s_bHandleRxEncryption(
// Software TKIP
// 1. 3253 A
PS802_11Header pMACHeader = (PS802_11Header)(pbyFrame);
+
TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
@@ -1175,7 +1150,8 @@ static bool s_bHostWepRxEncryption(
if (byDecMode == KEY_CTL_WEP) {
// handle WEP
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP\n");
+
if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
(((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) ||
!bOnFly) {
@@ -1214,7 +1190,7 @@ static bool s_bHostWepRxEncryption(
// Software TKIP
// 1. 3253 A
// 2. NotOnFly
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_TKIP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_TKIP\n");
pMACHeader = (PS802_11Header)(pbyFrame);
TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
@@ -1276,7 +1252,7 @@ static bool s_bAPModeRxData(
// if any node in PS mode, buffer packet until DTIM.
if (skbcpy == NULL) {
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available\n");
} else {
skbcpy->dev = pDevice->dev;
skbcpy->len = FrameSize;
diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h
index 0ce31557d5da..4914890115e4 100644
--- a/drivers/staging/vt6655/dpc.h
+++ b/drivers/staging/vt6655/dpc.h
@@ -33,20 +33,10 @@
#include "device.h"
#include "wcmd.h"
-/*--------------------- Export Definitions -------------------------*/
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
bool
device_receive_frame(
PSDevice pDevice,
PSRxDesc pCurrRD
);
-void MngWorkItem(void *Context);
-
#endif // __RXTX_H__
diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c
index 317c2a8ee162..f105c2ac091b 100644
--- a/drivers/staging/vt6655/hostap.c
+++ b/drivers/staging/vt6655/hostap.c
@@ -256,8 +256,8 @@ static int hostap_add_sta(PSDevice pDevice,
pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d\n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
param->sta_addr[0],
param->sta_addr[1],
param->sta_addr[2],
@@ -265,7 +265,7 @@ static int hostap_add_sta(PSDevice pDevice,
param->sta_addr[4],
param->sta_addr[5]
);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d\n",
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
return 0;
@@ -323,7 +323,7 @@ static int hostap_set_flags_sta(PSDevice pDevice,
if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n",
(unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
} else {
return -ENOENT;
@@ -362,7 +362,7 @@ static int hostap_set_generic_element(PSDevice pDevice,
// disable wpa
if (pMgmt->wWPAIELen == 0) {
pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA\n");
} else {
// enable wpa
if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
@@ -394,8 +394,6 @@ static void hostap_flush_sta(PSDevice pDevice)
// reserved node index =0 for multicast node.
BSSvClearNodeDBTable(pDevice, 1);
pDevice->uAssocCount = 0;
-
- return;
}
/*
@@ -449,8 +447,8 @@ static int hostap_set_encryption(PSDevice pDevice,
return -EINVAL;
}
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d\n", iNodeIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d\n", param->u.crypt.alg);
if (param->u.crypt.alg == WPA_ALG_NONE) {
if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly) {
@@ -458,7 +456,7 @@ static int hostap_set_encryption(PSDevice pDevice,
param->sta_addr,
pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex,
pDevice->PortOffset)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail\n");
}
pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false;
}
@@ -603,10 +601,10 @@ static int hostap_set_encryption(PSDevice pDevice,
MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d\n", iNodeIndex);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d\n", param->u.crypt.idx,
param->u.crypt.key_len);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx\n",
pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
@@ -698,62 +696,62 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
switch (param->cmd) {
case VIAWGET_HOSTAPD_SET_ENCRYPTION:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION\n");
spin_lock_irq(&pDevice->lock);
ret = hostap_set_encryption(pDevice, param, p->length);
spin_unlock_irq(&pDevice->lock);
break;
case VIAWGET_HOSTAPD_GET_ENCRYPTION:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION\n");
spin_lock_irq(&pDevice->lock);
ret = hostap_get_encryption(pDevice, param, p->length);
spin_unlock_irq(&pDevice->lock);
break;
case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n");
ret = -EOPNOTSUPP;
goto out;
case VIAWGET_HOSTAPD_FLUSH:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH\n");
spin_lock_irq(&pDevice->lock);
hostap_flush_sta(pDevice);
spin_unlock_irq(&pDevice->lock);
break;
case VIAWGET_HOSTAPD_ADD_STA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA\n");
spin_lock_irq(&pDevice->lock);
ret = hostap_add_sta(pDevice, param);
spin_unlock_irq(&pDevice->lock);
break;
case VIAWGET_HOSTAPD_REMOVE_STA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA\n");
spin_lock_irq(&pDevice->lock);
ret = hostap_remove_sta(pDevice, param);
spin_unlock_irq(&pDevice->lock);
break;
case VIAWGET_HOSTAPD_GET_INFO_STA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA\n");
ret = hostap_get_info_sta(pDevice, param);
ap_ioctl = 1;
break;
case VIAWGET_HOSTAPD_SET_FLAGS_STA:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA\n");
ret = hostap_set_flags_sta(pDevice, param);
break;
case VIAWGET_HOSTAPD_MLME:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME\n");
ret = -EOPNOTSUPP;
goto out;
case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n");
ret = hostap_set_generic_element(pDevice, param);
break;
case VIAWGET_HOSTAPD_SCAN_REQ:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ\n");
ret = -EOPNOTSUPP;
goto out;
case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS\n");
ret = -EOPNOTSUPP;
goto out;
default:
diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h
index f1a4f2eff058..6e801a428183 100644
--- a/drivers/staging/vt6655/hostap.h
+++ b/drivers/staging/vt6655/hostap.h
@@ -31,8 +31,6 @@
#include "device.h"
-/*--------------------- Export Definitions -------------------------*/
-
#define WLAN_RATE_1M BIT0
#define WLAN_RATE_2M BIT1
#define WLAN_RATE_5M5 BIT2
@@ -46,12 +44,6 @@
#define WLAN_RATE_48M BIT10
#define WLAN_RATE_54M BIT11
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h
index e499f1b6f531..a665cfd8a482 100644
--- a/drivers/staging/vt6655/iocmd.h
+++ b/drivers/staging/vt6655/iocmd.h
@@ -31,12 +31,6 @@
#include "ttype.h"
-/*--------------------- Export Definitions -------------------------*/
-
-//typedef uint32_t u32;
-//typedef uint16_t u16;
-//typedef uint8_t u8;
-
// ioctl Command code
#define MAGIC_CODE 0x3142
#define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0)
@@ -100,7 +94,7 @@ typedef enum tagWZONETYPE {
#pragma pack(1)
typedef struct tagSCmdRequest {
u8 name[16];
- void *data;
+ void __user *data;
u16 wResult;
u16 wCmdCode;
} SCmdRequest, *PSCmdRequest;
@@ -167,10 +161,6 @@ typedef struct tagSBSSIDItem {
u32 uChannel;
u8 abyBSSID[BSSID_LEN];
u8 abySSID[SSID_MAXLEN + 1];
- //2006-1116-01,<Modify> by NomadZhao
- //u16 wBeaconInterval;
- //u16 wCapInfo;
- //u8 byNetType;
u8 byNetType;
u16 wBeaconInterval;
u16 wCapInfo; // for address of byNetType at align 4
@@ -228,9 +218,8 @@ typedef struct tagSStatMIBCount {
u32 dwIsrUnrecoverableError;
u32 dwIsrSoftInterrupt;
u32 dwIsrRxNoBuf;
- /////////////////////////////////////
- u32 dwIsrUnknown; // unknown interrupt count
+ u32 dwIsrUnknown;
// RSR status count
//
@@ -349,7 +338,6 @@ typedef struct tagSCmdValue {
// hostapd & viawget ioctl related
//
-// VIAGWET_IOCTL_HOSTAPD ioctl() cmd:
enum {
VIAWGET_HOSTAPD_FLUSH = 1,
VIAWGET_HOSTAPD_ADD_STA = 2,
@@ -415,15 +403,6 @@ struct viawget_hostapd_param {
} u;
};
-//2006-1116-01,<Add> by NomadZhao
#pragma pack()
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
#endif //__IOCMD_H__
diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
index 18d11d1f4fa6..65e59336f03b 100644
--- a/drivers/staging/vt6655/ioctl.c
+++ b/drivers/staging/vt6655/ioctl.c
@@ -123,13 +123,13 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
/* write zonetype */
if (sZoneTypeCmd.ZoneType == ZoneType_USA) {
/* set to USA */
- printk("set_ZoneType:USA\n");
+ pr_debug("set_ZoneType:USA\n");
} else if (sZoneTypeCmd.ZoneType == ZoneType_Japan) {
/* set to Japan */
- printk("set_ZoneType:Japan\n");
+ pr_debug("set_ZoneType:Japan\n");
} else if (sZoneTypeCmd.ZoneType == ZoneType_Europe) {
/* set to Europe */
- printk("set_ZoneType:Europe\n");
+ pr_debug("set_ZoneType:Europe\n");
}
} else {
/* read zonetype */
@@ -142,7 +142,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
} else if (zonetype == 0x02) { /* Europe */
sZoneTypeCmd.ZoneType = ZoneType_Europe;
} else { /* Unknown ZoneType */
- printk("Error:ZoneType[%x] Unknown ???\n", zonetype);
+ pr_err("Error:ZoneType[%x] Unknown ???\n", zonetype);
result = -EFAULT;
break;
}
diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h
index 2f0db920e2cb..187fc915fd12 100644
--- a/drivers/staging/vt6655/ioctl.h
+++ b/drivers/staging/vt6655/ioctl.h
@@ -31,14 +31,6 @@
#include "device.h"
-/*--------------------- Export Definitions -------------------------*/
-
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
int private_ioctl(PSDevice pDevice, struct ifreq *rq);
#endif // __IOCTL_H__
diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h
index b7bd1909fa7c..772bc4c2a7b9 100644
--- a/drivers/staging/vt6655/iowpa.h
+++ b/drivers/staging/vt6655/iowpa.h
@@ -29,8 +29,6 @@
#ifndef __IOWPA_H__
#define __IOWPA_H__
-/*--------------------- Export Definitions -------------------------*/
-
#define WPA_IE_LEN 64
//WPA related
@@ -127,14 +125,6 @@ struct viawget_scan_result {
int maxrate;
};
-//2006-1116-01,<Add> by NomadZhao
#pragma pack()
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
#endif //__IOWPA_H__
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index ae2b87f177fb..7ce23b57e78d 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -33,6 +33,7 @@
#include "device.h"
#include "ioctl.h"
#include "iocmd.h"
+#include "iwctl.h"
#include "mac.h"
#include "card.h"
#include "hostap.h"
@@ -107,7 +108,7 @@ static int iwctl_commit(struct net_device *dev,
void *wrq,
char *extra)
{
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n");
return 0;
}
@@ -128,7 +129,7 @@ int iwctl_giwname(struct net_device *dev,
* Wireless Handler : set scan
*/
-int iwctl_siwscan(struct net_device *dev,
+static int iwctl_siwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
char *extra)
@@ -138,11 +139,13 @@ int iwctl_siwscan(struct net_device *dev,
struct iw_scan_req *req = (struct iw_scan_req *)extra;
unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
PWLAN_IE_SSID pItemSSID = NULL;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN\n");
if (pDevice->byReAssocCount > 0) { //reject scan when re-associating!
//send scan event to wpa_Supplicant
union iwreq_data wrqu;
+
PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
memset(&wrqu, 0, sizeof(wrqu));
wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
@@ -189,7 +192,7 @@ int iwctl_siwscan(struct net_device *dev,
* Wireless Handler : get scan results
*/
-int iwctl_giwscan(struct net_device *dev,
+static int iwctl_giwscan(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
char *extra)
@@ -207,7 +210,7 @@ int iwctl_giwscan(struct net_device *dev,
long ldBm;
char buf[MAX_WPA_IE_LEN * 2 + 30];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
@@ -254,6 +257,7 @@ int iwctl_giwscan(struct net_device *dev,
//2008-0409-04, <Add> by Einsn Liu
{
int f = (int)pBSS->uChannel - 1;
+
if (f < 0)f = 0;
iwe.u.freq.m = frequency_list[f] * 100000;
iwe.u.freq.e = 1;
@@ -349,7 +353,7 @@ int iwctl_siwfreq(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n");
// If setting by frequency, convert to a channel
if ((wrq->e == 1) &&
@@ -357,6 +361,7 @@ int iwctl_siwfreq(struct net_device *dev,
(wrq->m <= (int) 2.487e8)) {
int f = wrq->m / 100000;
int c = 0;
+
while ((c < 14) && (f != frequency_list[c]))
c++;
wrq->e = 0;
@@ -367,6 +372,7 @@ int iwctl_siwfreq(struct net_device *dev,
rc = -EOPNOTSUPP;
else {
int channel = wrq->m;
+
if ((channel < 1) || (channel > 14)) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
rc = -EINVAL;
@@ -395,7 +401,7 @@ int iwctl_giwfreq(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n");
#ifdef WEXT_USECHANNELS
wrq->m = (int)pMgmt->uCurrChannel;
@@ -403,6 +409,7 @@ int iwctl_giwfreq(struct net_device *dev,
#else
{
int f = (int)pMgmt->uCurrChannel - 1;
+
if (f < 0)
f = 0;
wrq->m = frequency_list[f] * 100000;
@@ -426,10 +433,10 @@ int iwctl_siwmode(struct net_device *dev,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n");
if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Can't set operation mode, hostapd is running \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Can't set operation mode, hostapd is running\n");
return rc;
}
@@ -441,7 +448,7 @@ int iwctl_siwmode(struct net_device *dev,
pDevice->bCommit = true;
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n");
break;
case IW_MODE_AUTO:
case IW_MODE_INFRA:
@@ -451,7 +458,7 @@ int iwctl_siwmode(struct net_device *dev,
pDevice->bCommit = true;
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n");
break;
case IW_MODE_MASTER:
@@ -465,7 +472,7 @@ int iwctl_siwmode(struct net_device *dev,
pDevice->bCommit = true;
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point\n");
break;
case IW_MODE_REPEAT:
@@ -491,7 +498,7 @@ int iwctl_giwmode(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
// If not managed, assume it's ad-hoc
switch (pMgmt->eConfigMode) {
case WMAC_CONFIG_ESS_STA:
@@ -526,7 +533,7 @@ int iwctl_giwrange(struct net_device *dev,
int i, k;
unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
if (wrq->pointer) {
wrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
@@ -633,10 +640,10 @@ int iwctl_siwap(struct net_device *dev,
int rc = 0;
unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP\n");
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
- printk("SIOCSIWAP(??)-->In scanning...\n");
+ pr_debug("SIOCSIWAP(??)-->In scanning..\n");
}
if (wrq->sa_family != ARPHRD_ETHER)
rc = -EINVAL;
@@ -657,6 +664,7 @@ int iwctl_siwap(struct net_device *dev,
// then ignore,because you don't known which one to be connect with??
{
unsigned int ii, uSameBssidNum = 0;
+
for (ii = 0; ii < MAX_BSS_NUM; ii++) {
if (pMgmt->sBSSList[ii].bActive &&
ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
@@ -689,7 +697,7 @@ int iwctl_giwap(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
//2008-0410,<Modify> by Einsn Liu
@@ -792,18 +800,18 @@ int iwctl_siwessid(struct net_device *dev,
//2008-0409-05, <Add> by Einsn Liu
unsigned char len;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID\n");
pDevice->fWPA_Authened = false;
if (pMgmt->eScanState == WMAC_IS_SCANNING) {
// In scanning..
- printk("SIOCSIWESSID(??)-->In scanning...\n");
+ pr_debug("SIOCSIWESSID(??)-->In scanning..\n");
}
// Check if we asked for `any'
if (wrq->flags == 0) {
// Just send an empty SSID list
memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
memset(pMgmt->abyDesireBSSID, 0xFF, 6);
- PRINT_K("set essid to 'any' \n");
+ PRINT_K("set essid to 'any'\n");
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
return 0;
#endif
@@ -819,7 +827,7 @@ int iwctl_siwessid(struct net_device *dev,
pItemSSID->len = wrq->length - 1;
} else
pItemSSID->len = wrq->length;
- printk("set essid to %s \n", pItemSSID->abySSID);
+ pr_debug("set essid to %s\n", pItemSSID->abySSID);
//2008-0409-05, <Add> by Einsn Liu
len = (pItemSSID->len > ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) ? pItemSSID->len : ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len;
if ((pDevice->bLinkPass == true) &&
@@ -865,7 +873,7 @@ int iwctl_siwessid(struct net_device *dev,
}
}
if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
- printk("SIOCSIWESSID:hidden ssid directly associate.......\n");
+ pr_debug("SIOCSIWESSID:hidden ssid directly associate.......\n");
vResetCommandTimer((void *)pDevice);
pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result!
bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
@@ -877,7 +885,7 @@ int iwctl_siwessid(struct net_device *dev,
}
#endif
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
}
if (pDevice->flags & DEVICE_FLAGS_OPENED)
@@ -899,7 +907,7 @@ int iwctl_giwessid(struct net_device *dev,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
PWLAN_IE_SSID pItemSSID;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
// Note : if wrq->u.data.flags != 0, we should
// get the relevant SSID from the SSID list...
@@ -931,7 +939,7 @@ int iwctl_siwrate(struct net_device *dev,
int i;
unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
rc = -EINVAL;
return rc;
@@ -979,19 +987,19 @@ int iwctl_siwrate(struct net_device *dev,
if (wrq->fixed != 0) {
// Fixed mode
// One rate, fixed
- printk("Rate Fix\n");
+ pr_debug("Rate Fix\n");
pDevice->bFixRate = true;
if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) {
pDevice->uConnectionRate = 3;
} else {
pDevice->uConnectionRate = brate;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
}
} else {
pDevice->bFixRate = false;
pDevice->uConnectionRate = 13;
- printk("auto rate:connection_rate is 13\n");
+ pr_debug("auto rate:connection_rate is 13\n");
}
return rc;
@@ -1011,7 +1019,7 @@ int iwctl_giwrate(struct net_device *dev,
//Mark the unnecessary sentences.
// PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
{
unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
int brate = 0;
@@ -1054,10 +1062,11 @@ int iwctl_siwrts(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS\n");
{
int rthr = wrq->value;
+
if (wrq->disabled)
rthr = 2312;
@@ -1081,7 +1090,7 @@ int iwctl_giwrts(struct net_device *dev,
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
wrq->value = pDevice->wRTSThreshold;
wrq->disabled = (wrq->value >= 2312);
wrq->fixed = 1;
@@ -1102,7 +1111,7 @@ int iwctl_siwfrag(struct net_device *dev,
int rc = 0;
int fthr = wrq->value;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
if (wrq->disabled)
fthr = 2312;
@@ -1127,7 +1136,7 @@ int iwctl_giwfrag(struct net_device *dev,
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
wrq->value = pDevice->wFragmentationThreshold;
wrq->disabled = (wrq->value >= 2312);
wrq->fixed = 1;
@@ -1146,7 +1155,7 @@ int iwctl_siwretry(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
if (wrq->disabled) {
rc = -EINVAL;
@@ -1179,7 +1188,8 @@ int iwctl_giwretry(struct net_device *dev,
char *extra)
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
wrq->disabled = 0; // Can't be disabled
// Note : by default, display the min retry number
@@ -1224,7 +1234,7 @@ int iwctl_siwencode(struct net_device *dev,
PSKeyTable pkeytab;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
if ((wrq->flags & IW_ENCODE_DISABLED) == 0) {
//Not disable encryption
@@ -1404,7 +1414,7 @@ int iwctl_siwpower(struct net_device *dev,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int rc = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
rc = -EINVAL;
@@ -1426,14 +1436,14 @@ int iwctl_siwpower(struct net_device *dev,
}
switch (wrq->flags & IW_POWER_MODE) {
case IW_POWER_UNICAST_R:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
rc = -EINVAL;
break;
case IW_POWER_ALL_R:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
rc = -EINVAL;
case IW_POWER_ON:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
break;
default:
rc = -EINVAL;
@@ -1454,7 +1464,7 @@ int iwctl_giwpower(struct net_device *dev,
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int mode = pDevice->ePSMode;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
wrq->disabled = (mode == WMAC_POWER_CAM);
if (wrq->disabled)
@@ -1483,7 +1493,7 @@ int iwctl_giwsens(struct net_device *dev,
PSDevice pDevice = (PSDevice)netdev_priv(dev);
long ldBm;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
if (pDevice->bLinkPass == true) {
RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm);
wrq->value = ldBm;
@@ -1510,7 +1520,7 @@ int iwctl_siwauth(struct net_device *dev,
static int wpa_version = 0; //must be static to save the last value,einsn liu
static int pairwise = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
switch (wrq->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION:
wpa_version = wrq->value;
@@ -1611,17 +1621,24 @@ int iwctl_giwauth(struct net_device *dev,
int iwctl_siwgenie(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra)
+ char __user *extra)
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
int ret = 0;
+ char length;
if (wrq->length) {
- if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
- ret = -EINVAL;
- goto out;
- }
+ if (wrq->length < 2)
+ return -EINVAL;
+
+ ret = get_user(length, extra + 1);
+ if (ret)
+ return ret;
+
+ if (length + 2 != wrq->length)
+ return -EINVAL;
+
if (wrq->length > MAX_WPA_IE_LEN) {
ret = -ENOMEM;
goto out;
@@ -1644,7 +1661,7 @@ out://not completely ...not necessary in wpa_supplicant 0.5.8
int iwctl_giwgenie(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra)
+ char __user *extra)
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
@@ -1685,7 +1702,7 @@ int iwctl_siwencodeext(struct net_device *dev,
u8 key_array[64];
int ret = 0;
- PRINT_K("SIOCSIWENCODEEXT...... \n");
+ PRINT_K("SIOCSIWENCODEEXT......\n");
param = kzalloc(sizeof(*param), GFP_KERNEL);
if (param == NULL)
@@ -1765,7 +1782,7 @@ int iwctl_siwencodeext(struct net_device *dev,
}
if (pDevice->bwextcount == 4) {
- printk("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
+ pr_debug("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
pDevice->bwextcount = 0;
pDevice->bWPASuppWextEnabled = true;
}
@@ -1791,25 +1808,30 @@ int iwctl_giwencodeext(struct net_device *dev,
int iwctl_siwmlme(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra)
+ char __user *extra)
{
PSDevice pDevice = (PSDevice)netdev_priv(dev);
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ struct iw_mlme mime;
+
int ret = 0;
- if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
+ ret = copy_from_user(&mime, extra, sizeof(mime));
+ if (ret)
+ return -EFAULT;
+
+ if (memcmp(pMgmt->abyCurrBSSID, mime.addr.sa_data, ETH_ALEN)) {
ret = -EINVAL;
return ret;
}
- switch (mlme->cmd) {
+ switch (mime.cmd) {
case IW_MLME_DEAUTH:
//this command seems to be not complete,please test it --einsnliu
//bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (unsigned char *)&reason);
break;
case IW_MLME_DISASSOC:
if (pDevice->bLinkPass == true) {
- printk("iwctl_siwmlme--->send DISASSOCIATE\n");
+ pr_debug("iwctl_siwmlme--->send DISASSOCIATE\n");
//clear related flags
memset(pMgmt->abyDesireBSSID, 0xFF, 6);
KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h
index 871bd7c4e716..7dd63102182d 100644
--- a/drivers/staging/vt6655/iwctl.h
+++ b/drivers/staging/vt6655/iwctl.h
@@ -161,16 +161,6 @@ int iwctl_giwpower(struct net_device *dev,
struct iw_param *wrq,
char *extra);
-int iwctl_giwscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *wrq,
- char *extra);
-
-int iwctl_siwscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *wrq,
- char *extra);
-
//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
int iwctl_siwauth(struct net_device *dev,
@@ -186,12 +176,12 @@ int iwctl_giwauth(struct net_device *dev,
int iwctl_siwgenie(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra);
+ char __user *extra);
int iwctl_giwgenie(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra);
+ char __user *extra);
int iwctl_siwencodeext(struct net_device *dev,
struct iw_request_info *info,
@@ -206,11 +196,11 @@ int iwctl_giwencodeext(struct net_device *dev,
int iwctl_siwmlme(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *wrq,
- char *extra);
+ char __user *extra);
#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
//End Add -- //2008-0409-07, <Add> by Einsn Liu
extern const struct iw_handler_def iwctl_handler_def;
-extern const struct iw_priv_args iwctl_private_args;
+extern struct iw_priv_args iwctl_private_args[];
#endif // __IWCTL_H__
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c
index 09a8bf50527b..9339e2a4073a 100644
--- a/drivers/staging/vt6655/key.c
+++ b/drivers/staging/vt6655/key.c
@@ -58,7 +58,7 @@ static int msglevel = MSG_LEVEL_INFO;
/*--------------------- Static Functions --------------------------*/
static void
-s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase)
+s_vCheckKeyTableValid(PSKeyManagement pTable, void __iomem *dwIoBase)
{
int i;
@@ -91,7 +91,7 @@ s_vCheckKeyTableValid(PSKeyManagement pTable, unsigned long dwIoBase)
* Return Value: none
*
*/
-void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase)
+void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase)
{
int i;
int jj;
@@ -134,7 +134,7 @@ bool KeybGetKey(
{
int i;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetKey() \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetKey()\n");
*pKey = NULL;
for (i = 0; i < MAX_KEY_TABLE; i++) {
@@ -187,7 +187,7 @@ bool KeybSetKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
)
{
@@ -252,7 +252,7 @@ bool KeybSetKey(
pKey->dwTSC47_16 = 0;
pKey->wTSC15_0 = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n");
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
for (ii = 0; ii < pKey->uKeyLength; ii++)
@@ -315,7 +315,7 @@ bool KeybSetKey(
pKey->dwTSC47_16 = 0;
pKey->wTSC15_0 = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(N): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(N):\n");
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
@@ -351,7 +351,7 @@ bool KeybRemoveKey(
PSKeyManagement pTable,
unsigned char *pbyBSSID,
unsigned long dwKeyIndex,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
)
{
int i;
@@ -418,7 +418,7 @@ bool KeybRemoveKey(
bool KeybRemoveAllKey(
PSKeyManagement pTable,
unsigned char *pbyBSSID,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
)
{
int i, u;
@@ -453,7 +453,7 @@ bool KeybRemoveAllKey(
void KeyvRemoveWEPKey(
PSKeyManagement pTable,
unsigned long dwKeyIndex,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
)
{
if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
@@ -468,12 +468,11 @@ void KeyvRemoveWEPKey(
}
s_vCheckKeyTableValid(pTable, dwIoBase);
}
- return;
}
void KeyvRemoveAllWEPKey(
PSKeyManagement pTable,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
)
{
int i;
@@ -610,7 +609,7 @@ bool KeybSetDefaultKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
)
{
@@ -618,7 +617,7 @@ bool KeybSetDefaultKey(
PSKeyItem pKey;
unsigned int uKeyIdx;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n", (int)dwKeyIndex, (int)uKeyLength);
if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key
return false;
@@ -677,10 +676,10 @@ bool KeybSetDefaultKey(
pKey->dwTSC47_16 = 0;
pKey->wTSC15_0 = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n");
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n", pKey->bKeyValid);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey:\n");
for (ii = 0; ii < pKey->uKeyLength; ii++)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x", pKey->abyKey[ii]);
@@ -716,7 +715,7 @@ bool KeybSetAllGroupKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
)
{
@@ -772,7 +771,7 @@ bool KeybSetAllGroupKey(
pKey->dwTSC47_16 = 0;
pKey->wTSC15_0 = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R): \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n");
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: ");
diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h
index 4b8b4b6bd6cd..3eb881b69a55 100644
--- a/drivers/staging/vt6655/key.h
+++ b/drivers/staging/vt6655/key.h
@@ -53,8 +53,7 @@
#define KEY_CTL_CCMP 0x03
#define KEY_CTL_INVALID 0xFF
-typedef struct tagSKeyItem
-{
+typedef struct tagSKeyItem {
bool bKeyValid;
unsigned long uKeyLength;
unsigned char abyKey[MAX_KEY_LEN];
@@ -67,8 +66,7 @@ typedef struct tagSKeyItem
void *pvKeyTable;
} SKeyItem, *PSKeyItem; //64
-typedef struct tagSKeyTable
-{
+typedef struct tagSKeyTable {
unsigned char abyBSSID[ETH_ALEN]; //6
unsigned char byReserved0[2]; //8
SKeyItem PairwiseKey;
@@ -82,8 +80,7 @@ typedef struct tagSKeyTable
unsigned char byReserved1[6];
} SKeyTable, *PSKeyTable; //348
-typedef struct tagSKeyManagement
-{
+typedef struct tagSKeyManagement {
SKeyTable KeyTable[MAX_KEY_TABLE];
} SKeyManagement, *PSKeyManagement;
@@ -97,7 +94,7 @@ typedef struct tagSKeyManagement
/*--------------------- Export Functions --------------------------*/
-void KeyvInitTable(PSKeyManagement pTable, unsigned long dwIoBase);
+void KeyvInitTable(PSKeyManagement pTable, void __iomem *dwIoBase);
bool KeybGetKey(
PSKeyManagement pTable,
@@ -114,7 +111,7 @@ bool KeybSetKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
);
@@ -125,7 +122,7 @@ bool KeybSetDefaultKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
);
@@ -133,7 +130,7 @@ bool KeybRemoveKey(
PSKeyManagement pTable,
unsigned char *pbyBSSID,
unsigned long dwKeyIndex,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
);
bool KeybGetTransmitKey(
@@ -151,18 +148,18 @@ bool KeybCheckPairewiseKey(
bool KeybRemoveAllKey(
PSKeyManagement pTable,
unsigned char *pbyBSSID,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
);
void KeyvRemoveWEPKey(
PSKeyManagement pTable,
unsigned long dwKeyIndex,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
);
void KeyvRemoveAllWEPKey(
PSKeyManagement pTable,
- unsigned long dwIoBase
+ void __iomem *dwIoBase
);
bool KeybSetAllGroupKey(
@@ -172,7 +169,7 @@ bool KeybSetAllGroupKey(
PQWORD pKeyRSC,
unsigned char *pbyKey,
unsigned char byKeyDecMode,
- unsigned long dwIoBase,
+ void __iomem *dwIoBase,
unsigned char byLocalID
);
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index af6876a01ee8..9bbc873de702 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -98,7 +98,7 @@ static int msglevel = MSG_LEVEL_INFO;
* Return Value: none
*
*/
-void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs)
+void MACvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyMacRegs)
{
int ii;
@@ -134,7 +134,7 @@ void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs)
* Return Value: true if all test bits On; otherwise false
*
*/
-bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
+bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
{
unsigned char byData;
@@ -157,7 +157,7 @@ bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned ch
* Return Value: true if all test bits Off; otherwise false
*
*/
-bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
+bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits)
{
unsigned char byData;
@@ -178,7 +178,7 @@ bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned c
* Return Value: true if interrupt is disable; otherwise false
*
*/
-bool MACbIsIntDisable(unsigned long dwIoBase)
+bool MACbIsIntDisable(void __iomem *dwIoBase)
{
unsigned long dwData;
@@ -203,7 +203,7 @@ bool MACbIsIntDisable(unsigned long dwIoBase)
* Return Value: Mask Value read
*
*/
-unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx)
+unsigned char MACbyReadMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx)
{
unsigned char byData;
@@ -228,7 +228,7 @@ unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx)
* Return Value: none
*
*/
-void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData)
+void MACvWriteMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx, unsigned char byData)
{
MACvSelectPage1(dwIoBase);
VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData);
@@ -249,7 +249,7 @@ void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned
* Return Value: none
*
*/
-void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
+void MACvSetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx)
{
unsigned int uByteIdx;
unsigned char byBitMask;
@@ -280,7 +280,7 @@ void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
* Return Value: none
*
*/
-void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
+void MACvResetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx)
{
unsigned int uByteIdx;
unsigned char byBitMask;
@@ -311,7 +311,7 @@ void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx)
* Return Value: none
*
*/
-void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
+void MACvSetRxThreshold(void __iomem *dwIoBase, unsigned char byThreshold)
{
unsigned char byOrgValue;
@@ -336,7 +336,7 @@ void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
* Return Value: none
*
*/
-void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
+void MACvGetRxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold)
{
// get FCR0
VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
@@ -357,7 +357,7 @@ void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
* Return Value: none
*
*/
-void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
+void MACvSetTxThreshold(void __iomem *dwIoBase, unsigned char byThreshold)
{
unsigned char byOrgValue;
@@ -382,7 +382,7 @@ void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold)
* Return Value: none
*
*/
-void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
+void MACvGetTxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold)
{
// get FCR0
VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold);
@@ -403,7 +403,7 @@ void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold)
* Return Value: none
*
*/
-void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength)
+void MACvSetDmaLength(void __iomem *dwIoBase, unsigned char byDmaLength)
{
unsigned char byOrgValue;
@@ -428,7 +428,7 @@ void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength)
* Return Value: none
*
*/
-void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength)
+void MACvGetDmaLength(void __iomem *dwIoBase, unsigned char *pbyDmaLength)
{
// get FCR0
VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength);
@@ -449,7 +449,7 @@ void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength)
* Return Value: none
*
*/
-void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
+void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
{
// set SRT
VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
@@ -468,7 +468,7 @@ void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
* Return Value: none
*
*/
-void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
+void MACvGetShortRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit)
{
// get SRT
VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
@@ -488,7 +488,7 @@ void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit
* Return Value: none
*
*/
-void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
+void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
{
// set LRT
VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit);
@@ -507,7 +507,7 @@ void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit)
* Return Value: none
*
*/
-void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
+void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit)
{
// get LRT
VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit);
@@ -527,7 +527,7 @@ void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit)
* Return Value: none
*
*/
-void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode)
+void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode)
{
unsigned char byOrgValue;
@@ -553,7 +553,7 @@ void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode)
* Return Value: true if in Loopback mode; otherwise false
*
*/
-bool MACbIsInLoopbackMode(unsigned long dwIoBase)
+bool MACbIsInLoopbackMode(void __iomem *dwIoBase)
{
unsigned char byOrgValue;
@@ -577,7 +577,7 @@ bool MACbIsInLoopbackMode(unsigned long dwIoBase)
* Return Value: none
*
*/
-void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType)
+void MACvSetPacketFilter(void __iomem *dwIoBase, unsigned short wFilterType)
{
unsigned char byOldRCR;
unsigned char byNewRCR = 0;
@@ -636,7 +636,7 @@ void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType)
* Return Value: none
*
*/
-void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
+void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
{
int ii;
@@ -667,7 +667,7 @@ void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
* Return Value: none
*
*/
-void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
+void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
{
int ii;
@@ -716,7 +716,7 @@ void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
* Return Value: true if all values are the same; otherwise false
*
*/
-bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
+bool MACbCompareContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf)
{
unsigned long dwData;
@@ -756,7 +756,7 @@ bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf)
* Return Value: true if Reset Success; otherwise false
*
*/
-bool MACbSoftwareReset(unsigned long dwIoBase)
+bool MACbSoftwareReset(void __iomem *dwIoBase)
{
unsigned char byData;
unsigned short ww;
@@ -787,7 +787,7 @@ bool MACbSoftwareReset(unsigned long dwIoBase)
* Return Value: true if success; otherwise false
*
*/
-bool MACbSafeSoftwareReset(unsigned long dwIoBase)
+bool MACbSafeSoftwareReset(void __iomem *dwIoBase)
{
unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1];
bool bRetVal;
@@ -819,7 +819,7 @@ bool MACbSafeSoftwareReset(unsigned long dwIoBase)
* Return Value: true if success; otherwise false
*
*/
-bool MACbSafeRxOff(unsigned long dwIoBase)
+bool MACbSafeRxOff(void __iomem *dwIoBase)
{
unsigned short ww;
unsigned long dwData;
@@ -880,7 +880,7 @@ bool MACbSafeRxOff(unsigned long dwIoBase)
* Return Value: true if success; otherwise false
*
*/
-bool MACbSafeTxOff(unsigned long dwIoBase)
+bool MACbSafeTxOff(void __iomem *dwIoBase)
{
unsigned short ww;
unsigned long dwData;
@@ -943,7 +943,7 @@ bool MACbSafeTxOff(unsigned long dwIoBase)
* Return Value: true if success; otherwise false
*
*/
-bool MACbSafeStop(unsigned long dwIoBase)
+bool MACbSafeStop(void __iomem *dwIoBase)
{
MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX);
@@ -978,7 +978,7 @@ bool MACbSafeStop(unsigned long dwIoBase)
* Return Value: true if success; otherwise false
*
*/
-bool MACbShutdown(unsigned long dwIoBase)
+bool MACbShutdown(void __iomem *dwIoBase)
{
// disable MAC IMR
MACvIntDisable(dwIoBase);
@@ -1005,7 +1005,7 @@ bool MACbShutdown(unsigned long dwIoBase)
* Return Value: none
*
*/
-void MACvInitialize(unsigned long dwIoBase)
+void MACvInitialize(void __iomem *dwIoBase)
{
// clear sticky bits
MACvClearStckDS(dwIoBase);
@@ -1041,7 +1041,7 @@ void MACvInitialize(unsigned long dwIoBase)
* Return Value: none
*
*/
-void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
+void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
{
unsigned short ww;
unsigned char byData;
@@ -1079,7 +1079,7 @@ void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr
* Return Value: none
*
*/
-void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
+void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
{
unsigned short ww;
unsigned char byData;
@@ -1117,7 +1117,7 @@ void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr
* Return Value: none
*
*/
-void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
+void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
{
unsigned short ww;
unsigned char byData;
@@ -1155,7 +1155,7 @@ void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAd
*
*/
//TxDMA1 = AC0DMA
-void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr)
+void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
{
unsigned short ww;
unsigned char byData;
@@ -1179,7 +1179,7 @@ void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAd
VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
}
-void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr)
+void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase, unsigned long dwCurrDescAddr)
{
if (iTxType == TYPE_AC0DMA)
MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr);
@@ -1201,7 +1201,7 @@ void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dw
* Return Value: none
*
*/
-void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay)
+void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay)
{
unsigned char byValue;
unsigned int uu, ii;
@@ -1236,7 +1236,7 @@ void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay)
* Return Value: none
*
*/
-void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
+void MACvOneShotTimer0MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime)
{
VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime);
@@ -1257,14 +1257,14 @@ void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
* Return Value: none
*
*/
-void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime)
+void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime)
{
VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0);
VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime);
VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE));
}
-void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData)
+void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData)
{
if (wOffset > 273)
return;
@@ -1273,7 +1273,7 @@ void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned lo
VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
}
-bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx)
+bool MACbTxDMAOff(void __iomem *dwIoBase, unsigned int idx)
{
unsigned char byData;
unsigned int ww = 0;
@@ -1301,7 +1301,7 @@ bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx)
return true;
}
-void MACvClearBusSusInd(unsigned long dwIoBase)
+void MACvClearBusSusInd(void __iomem *dwIoBase)
{
unsigned long dwOrgValue;
unsigned int ww;
@@ -1323,7 +1323,7 @@ void MACvClearBusSusInd(unsigned long dwIoBase)
}
}
-void MACvEnableBusSusEn(unsigned long dwIoBase)
+void MACvEnableBusSusEn(void __iomem *dwIoBase)
{
unsigned char byOrgValue;
unsigned long dwOrgValue;
@@ -1345,7 +1345,7 @@ void MACvEnableBusSusEn(unsigned long dwIoBase)
}
}
-bool MACbFlushSYNCFifo(unsigned long dwIoBase)
+bool MACbFlushSYNCFifo(void __iomem *dwIoBase)
{
unsigned char byOrgValue;
unsigned int ww;
@@ -1369,7 +1369,7 @@ bool MACbFlushSYNCFifo(unsigned long dwIoBase)
return true;
}
-bool MACbPSWakeup(unsigned long dwIoBase)
+bool MACbPSWakeup(void __iomem *dwIoBase)
{
unsigned char byOrgValue;
unsigned int ww;
@@ -1409,7 +1409,7 @@ bool MACbPSWakeup(unsigned long dwIoBase)
*
*/
-void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
+void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID)
{
unsigned short wOffset;
@@ -1473,7 +1473,7 @@ void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned in
* Return Value: none
*
*/
-void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx)
+void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx)
{
unsigned short wOffset;
@@ -1500,7 +1500,7 @@ void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx)
*
*/
-void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen,
unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
{
unsigned short wOffset;
@@ -1549,7 +1549,7 @@ void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
*
*/
/*
- void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID)
+ void MACvEnableDefaultKey(void __iomem *dwIoBase, unsigned char byLocalID)
{
unsigned short wOffset;
unsigned long dwData;
@@ -1583,7 +1583,7 @@ void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
* Return Value: none
*
*/
-void MACvDisableDefaultKey(unsigned long dwIoBase)
+void MACvDisableDefaultKey(void __iomem *dwIoBase)
{
unsigned short wOffset;
unsigned long dwData;
@@ -1612,7 +1612,7 @@ void MACvDisableDefaultKey(unsigned long dwIoBase)
* Return Value: none
*
*/
-void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen,
unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID)
{
unsigned short wOffset;
@@ -1665,7 +1665,7 @@ void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
*
*/
-void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID)
+void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID)
{
unsigned short wOffset;
unsigned long dwData;
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
index 7333b8b526f4..0bf93759b6af 100644
--- a/drivers/staging/vt6655/mac.h
+++ b/drivers/staging/vt6655/mac.h
@@ -44,7 +44,6 @@
//
#define MAC_MAX_CONTEXT_SIZE_PAGE0 256
#define MAC_MAX_CONTEXT_SIZE_PAGE1 128
-#define MAC_MAX_CONTEXT_SIZE MAC_MAX_CONTEXT_SIZE_PAGE0 + MAC_MAX_CONTEXT_SIZE_PAGE1
// Registers not related to 802.11b
#define MAC_REG_BCFG0 0x00
@@ -973,78 +972,78 @@ do { \
/*--------------------- Export Functions --------------------------*/
extern unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester
-void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs);
+void MACvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyMacRegs);
-bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
-bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
+bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
+bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
-bool MACbIsIntDisable(unsigned long dwIoBase);
+bool MACbIsIntDisable(void __iomem *dwIoBase);
-unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx);
-void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData);
-void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx);
-void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx);
+unsigned char MACbyReadMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx);
+void MACvWriteMultiAddr(void __iomem *dwIoBase, unsigned int uByteIdx, unsigned char byData);
+void MACvSetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx);
+void MACvResetMultiAddrByHash(void __iomem *dwIoBase, unsigned char byHashIdx);
-void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold);
-void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold);
+void MACvSetRxThreshold(void __iomem *dwIoBase, unsigned char byThreshold);
+void MACvGetRxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold);
-void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold);
-void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold);
+void MACvSetTxThreshold(void __iomem *dwIoBase, unsigned char byThreshold);
+void MACvGetTxThreshold(void __iomem *dwIoBase, unsigned char *pbyThreshold);
-void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength);
-void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength);
+void MACvSetDmaLength(void __iomem *dwIoBase, unsigned char byDmaLength);
+void MACvGetDmaLength(void __iomem *dwIoBase, unsigned char *pbyDmaLength);
-void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit);
-void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit);
+void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
+void MACvGetShortRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit);
-void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit);
-void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit);
+void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
+void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit);
-void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode);
-bool MACbIsInLoopbackMode(unsigned long dwIoBase);
+void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode);
+bool MACbIsInLoopbackMode(void __iomem *dwIoBase);
-void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType);
+void MACvSetPacketFilter(void __iomem *dwIoBase, unsigned short wFilterType);
-void MACvSaveContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
-void MACvRestoreContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
-bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf);
+void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf);
+void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf);
+bool MACbCompareContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf);
-bool MACbSoftwareReset(unsigned long dwIoBase);
-bool MACbSafeSoftwareReset(unsigned long dwIoBase);
-bool MACbSafeRxOff(unsigned long dwIoBase);
-bool MACbSafeTxOff(unsigned long dwIoBase);
-bool MACbSafeStop(unsigned long dwIoBase);
-bool MACbShutdown(unsigned long dwIoBase);
-void MACvInitialize(unsigned long dwIoBase);
-void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrSyncDescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrATIMDescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr);
-void MACvTimer0MicroSDelay(unsigned long dwIoBase, unsigned int uDelay);
-void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime);
-void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime);
+bool MACbSoftwareReset(void __iomem *dwIoBase);
+bool MACbSafeSoftwareReset(void __iomem *dwIoBase);
+bool MACbSafeRxOff(void __iomem *dwIoBase);
+bool MACbSafeTxOff(void __iomem *dwIoBase);
+bool MACbSafeStop(void __iomem *dwIoBase);
+bool MACbShutdown(void __iomem *dwIoBase);
+void MACvInitialize(void __iomem *dwIoBase);
+void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay);
+void MACvOneShotTimer0MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime);
+void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime);
-void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData);
+void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData);
-bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx);
+bool MACbTxDMAOff(void __iomem *dwIoBase, unsigned int idx);
-void MACvClearBusSusInd(unsigned long dwIoBase);
-void MACvEnableBusSusEn(unsigned long dwIoBase);
+void MACvClearBusSusInd(void __iomem *dwIoBase);
+void MACvEnableBusSusEn(void __iomem *dwIoBase);
-bool MACbFlushSYNCFifo(unsigned long dwIoBase);
-bool MACbPSWakeup(unsigned long dwIoBase);
+bool MACbFlushSYNCFifo(void __iomem *dwIoBase);
+bool MACbPSWakeup(void __iomem *dwIoBase);
-void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
+void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID);
-void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx);
-void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx);
+void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen,
unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID);
-void MACvDisableDefaultKey(unsigned long dwIoBase);
-void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen,
+void MACvDisableDefaultKey(void __iomem *dwIoBase);
+void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen,
unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID);
-void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID);
+void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID);
#endif // __MAC_H__
diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h
index c0a59489184d..732bddaf5b91 100644
--- a/drivers/staging/vt6655/mib.h
+++ b/drivers/staging/vt6655/mib.h
@@ -33,13 +33,12 @@
#include "tether.h"
#include "desc.h"
-/*--------------------- Export Definitions -------------------------*/
//
// 802.11 counter
//
typedef struct tagSDot11Counters {
- unsigned long Length; // Length of structure
+ unsigned long Length;
unsigned long long TransmittedFragmentCount;
unsigned long long MulticastTransmittedFrameCount;
unsigned long long FailedCount;
@@ -68,8 +67,7 @@ typedef struct tagSDot11Counters {
//
typedef struct tagSMib2Counter {
long ifIndex;
- char ifDescr[256]; // max size 255 plus zero ending
- // e.g. "interface 1"
+ char ifDescr[256];
long ifType;
long ifMtu;
unsigned long ifSpeed;
@@ -93,12 +91,12 @@ typedef struct tagSMib2Counter {
} SMib2Counter, *PSMib2Counter;
// Value in the ifType entry
-#define WIRELESSLANIEEE80211b 6 //
+#define WIRELESSLANIEEE80211b 6
// Value in the ifAdminStatus/ifOperStatus entry
-#define UP 1 //
-#define DOWN 2 //
-#define TESTING 3 //
+#define UP 1
+#define DOWN 2
+#define TESTING 3
//
// RMON counter
@@ -182,7 +180,7 @@ typedef struct tagSISRCounters {
unsigned long dwIsrMIBNearfull;
unsigned long dwIsrRxNoBuf;
- unsigned long dwIsrUnknown; // unknown interrupt count
+ unsigned long dwIsrUnknown;
unsigned long dwIsrRx1OK;
unsigned long dwIsrATIMTxOK;
@@ -191,23 +189,18 @@ typedef struct tagSISRCounters {
unsigned long dwIsrATIMEnd;
unsigned long dwIsrSYNCFlushOK;
unsigned long dwIsrSTIMER1Int;
- /////////////////////////////////////
} SISRCounters, *PSISRCounters;
// Value in the etherStatsStatus entry
-#define VALID 1 //
-#define CREATE_REQUEST 2 //
-#define UNDER_CREATION 3 //
-#define INVALID 4 //
+#define VALID 1
+#define CREATE_REQUEST 2
+#define UNDER_CREATION 3
+#define INVALID 4
//
// statistic counter
//
typedef struct tagSStatCounter {
- //
- // ISR status count
- //
-
// RSR status count
//
unsigned long dwRsrFrmAlgnErr;
@@ -306,24 +299,18 @@ typedef struct tagSStatCounter {
#ifdef Calcu_LinkQual
//Tx count:
- unsigned long TxNoRetryOkCount; //success tx no retry !
- unsigned long TxRetryOkCount; //success tx but retry !
- unsigned long TxFailCount; //fail tx ?
+ unsigned long TxNoRetryOkCount;
+ unsigned long TxRetryOkCount;
+ unsigned long TxFailCount;
//Rx count:
- unsigned long RxOkCnt; //success rx !
- unsigned long RxFcsErrCnt; //fail rx ?
+ unsigned long RxOkCnt;
+ unsigned long RxFcsErrCnt;
//statistic
unsigned long SignalStren;
unsigned long LinkQuality;
#endif
} SStatCounter, *PSStatCounter;
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
void STAvClearAllCounter(PSStatCounter pStatistic);
void STAvUpdateIsrStatCounter(PSStatCounter pStatistic, unsigned long dwIsr);
diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h
index f6c2c15d9cb6..86cb140e3087 100644
--- a/drivers/staging/vt6655/michael.h
+++ b/drivers/staging/vt6655/michael.h
@@ -33,10 +33,6 @@
#include <linux/types.h>
-/*--------------------- Export Definitions -------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
void MIC_vInit(u32 dwK0, u32 dwK1);
void MIC_vUnInit(void);
@@ -48,8 +44,6 @@ void MIC_vAppend(unsigned char *src, unsigned int nBytes);
/* This also resets the message to empty. */
void MIC_vGetMIC(u32 *pdwL, u32 *pdwR);
-/*--------------------- Export Macros ------------------------------*/
-
/* Rotation functions on 32 bit values */
#define ROL32(A, n) \
(((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1)))
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index 5dfa911c6f49..2a21cbd1c6ac 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -113,8 +113,7 @@ PSvEnablePowerSaving(
PSbSendNullPacket(pDevice);
pDevice->bPWBitOn = true;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
- return;
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n");
}
/*+
@@ -149,7 +148,6 @@ PSvDisablePowerSaving(
PSbSendNullPacket(pDevice);
pDevice->bPWBitOn = false;
- return;
}
/*+
@@ -250,11 +248,8 @@ PSvSendPSPOLL(
pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN;
pTxPacket->cbPayloadLen = 0;
// send the frame
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
- }
-
- return;
}
/*+
diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h
index ce56124acf1b..936f171a6b19 100644
--- a/drivers/staging/vt6655/power.h
+++ b/drivers/staging/vt6655/power.h
@@ -29,19 +29,10 @@
#ifndef __POWER_H__
#define __POWER_H__
-/*--------------------- Export Definitions -------------------------*/
#define C_PWBT 1000 // micro sec. power up before TBTT
#define PS_FAST_INTERVAL 1 // Fast power saving listen interval
#define PS_MAX_INTERVAL 4 // MAX power saving listen interval
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
-
bool
PSbConsiderPowerDown(
void *hDeviceContext,
diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c
index 343b815c0a9e..b7819bc702de 100644
--- a/drivers/staging/vt6655/rc4.c
+++ b/drivers/staging/vt6655/rc4.c
@@ -82,6 +82,7 @@ void rc4_encrypt(PRC4Ext pRC4, unsigned char *pbyDest,
unsigned char *pbySrc, unsigned int cbData_len)
{
unsigned int ii;
+
for (ii = 0; ii < cbData_len; ii++)
pbyDest[ii] = (unsigned char)(pbySrc[ii] ^ rc4_byte(pRC4));
}
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index 99c89a14d89b..42b257f916d3 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -424,7 +424,7 @@ static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
* Return Value: true if succeeded; false if failed.
*
*/
-static bool s_bAL7230Init(unsigned long dwIoBase)
+static bool s_bAL7230Init(void __iomem *dwIoBase)
{
int ii;
bool bResult;
@@ -467,7 +467,7 @@ static bool s_bAL7230Init(unsigned long dwIoBase)
}
// Need to Pull PLLON low when writing channel registers through 3-wire interface
-static bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool s_bAL7230SelectChannel(void __iomem *dwIoBase, unsigned char byChannel)
{
bool bResult;
@@ -567,7 +567,7 @@ static bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChann
* Return Value: true if succeeded; false if failed.
*
*/
-bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData)
+bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData)
{
unsigned short ww;
unsigned long dwValue;
@@ -626,7 +626,7 @@ bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData)
* Return Value: true if succeeded; false if failed.
*
*/
-static bool RFbAL2230Init(unsigned long dwIoBase)
+static bool RFbAL2230Init(void __iomem *dwIoBase)
{
int ii;
bool bResult;
@@ -673,7 +673,7 @@ static bool RFbAL2230Init(unsigned long dwIoBase)
return bResult;
}
-static bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool RFbAL2230SelectChannel(void __iomem *dwIoBase, unsigned char byChannel)
{
bool bResult;
@@ -750,6 +750,7 @@ bool RFbInit(
)
{
bool bResult = true;
+
switch (pDevice->byRFType) {
case RF_AIROHA:
case RF_AL2230S:
@@ -783,9 +784,10 @@ bool RFbInit(
* Return Value: true if succeeded; false if failed.
*
*/
-bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel)
+bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned char byChannel)
{
bool bResult = true;
+
switch (byRFType) {
case RF_AIROHA:
case RF_AL2230S:
@@ -818,7 +820,7 @@ bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned c
* Return Value: None.
*
*/
-bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel)
+bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigned int uChannel)
{
int ii;
unsigned char byInitCount = 0;
@@ -871,11 +873,9 @@ bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigne
case RF_NOTHING:
return true;
- break;
default:
return false;
- break;
}
MACvSetMISCFifo(dwIoBase, MISCFIFO_SYNINFO_IDX, (unsigned long)MAKEWORD(bySleepCount, byInitCount));
@@ -1070,7 +1070,7 @@ RFvRSSITodBm(
// Post processing for the 11b/g and 11a.
// for save time on changing Reg2,3,5,7,10,12,15
-bool RFbAL7230SelectChannelPostProcess(unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel)
+bool RFbAL7230SelectChannelPostProcess(void __iomem *dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel)
{
bool bResult;
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
index ef3c6de09fec..ba55561c45d2 100644
--- a/drivers/staging/vt6655/rf.h
+++ b/drivers/staging/vt6655/rf.h
@@ -74,12 +74,12 @@
/*--------------------- Export Functions --------------------------*/
-bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData);
-bool RFbSelectChannel(unsigned long dwIoBase, unsigned char byRFType, unsigned char byChannel);
+bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData);
+bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned char byChannel);
bool RFbInit(
PSDevice pDevice
);
-bool RFvWriteWakeProgSyn(unsigned long dwIoBase, unsigned char byRFType, unsigned int uChannel);
+bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigned int uChannel);
bool RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH);
bool RFbRawSetPower(
PSDevice pDevice,
@@ -95,7 +95,7 @@ RFvRSSITodBm(
);
//{{ RobertYu: 20050104
-bool RFbAL7230SelectChannelPostProcess(unsigned long dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel);
+bool RFbAL7230SelectChannelPostProcess(void __iomem *dwIoBase, unsigned char byOldChannel, unsigned char byNewChannel);
//}} RobertYu
#endif // __RF_H__
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index 2219d71885a8..0d45aa076fed 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -78,16 +78,16 @@ static int msglevel = MSG_LEVEL_INFO;
#define CRITICAL_PACKET_LEN 256 // if packet size < 256 -> in-direct send
// packet size >= 256 -> direct send
-const unsigned short wTimeStampOff[2][MAX_RATE] = {
+static const unsigned short wTimeStampOff[2][MAX_RATE] = {
{384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
{384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
};
-const unsigned short wFB_Opt0[2][5] = {
+static const unsigned short wFB_Opt0[2][5] = {
{RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
{RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
};
-const unsigned short wFB_Opt1[2][5] = {
+static const unsigned short wFB_Opt1[2][5] = {
{RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
{RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
};
@@ -1084,6 +1084,7 @@ s_vGenerateTxParameter(
unsigned char byFBOption = AUTO_FB_NONE;
PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
+
pFifoHead->wReserved = wCurrentRate;
wFifoCtl = pFifoHead->wFIFOCtl;
@@ -1103,6 +1104,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
+
pBuf->wRTSTxRrvTime_aa = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
pBuf->wRTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
pBuf->wRTSTxRrvTime_bb = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
@@ -1116,6 +1118,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
+
pBuf->wTxRrvTime_a = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
pBuf->wTxRrvTime_b = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
pBuf->wCTSTxRrvTime_ba = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
@@ -1129,6 +1132,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+
pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
}
@@ -1138,6 +1142,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+
pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
}
}
@@ -1146,6 +1151,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+
pBuf->wRTSTxRrvTime = cpu_to_le16((unsigned short)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
}
@@ -1155,6 +1161,7 @@ s_vGenerateTxParameter(
//Fill RsvTime
if (pvRrvTime) {
PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+
pBuf->wTxRrvTime = cpu_to_le16((unsigned short)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
}
}
@@ -1958,8 +1965,6 @@ vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pb
*pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize,
uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
pTransmitKey, uNodeIndex, puMACfragNum);
-
- return;
}
/*+
@@ -2027,6 +2032,7 @@ vGenerateMACHeader(
if (pDevice->bLongHeader) {
PWLAN_80211HDR_A4 pMACA4Header = (PWLAN_80211HDR_A4) pbyBufferAddr;
+
pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
}
@@ -2045,7 +2051,8 @@ vGenerateMACHeader(
pMACHeader->wFrameCtl |= FC_MOREFRAG;
}
-CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
+CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket)
+{
PSTxDesc pFrstTD;
unsigned char byPktType;
unsigned char *pbyTxBufferAddr;
@@ -2331,7 +2338,8 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
return CMD_STATUS_PENDING;
}
-CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
+CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket)
+{
unsigned char byPktType;
unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs;
unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
@@ -2569,7 +2577,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un
}
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n", p80211Header->sA3.wFrameCtl);
//Set packet type
if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
@@ -2840,6 +2848,4 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un
// Poll Transmit the adapter
MACvTransmit0(pDevice->PortOffset);
-
- return;
}
diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c
index eaddc33c9d2d..5396e5832c22 100644
--- a/drivers/staging/vt6655/srom.c
+++ b/drivers/staging/vt6655/srom.c
@@ -73,7 +73,7 @@
* Return Value: data read
*
*/
-unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset)
+unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset)
{
unsigned short wDelay, wNoACK;
unsigned char byWait;
@@ -121,7 +121,7 @@ unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntO
* Return Value: true if succeeded; false if failed.
*
*/
-bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byData)
+bool SROMbWriteEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byData)
{
unsigned short wDelay, wNoACK;
unsigned char byWait;
@@ -173,7 +173,7 @@ bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, un
* Return Value: none
*
*/
-void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits)
+void SROMvRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits)
{
unsigned char byOrgData;
@@ -193,7 +193,7 @@ void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsign
* none
*
*/
-void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits)
+void SROMvRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits)
{
unsigned char byOrgData;
@@ -215,7 +215,7 @@ void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsig
* Return Value: true if all test bits on; otherwise false
*
*/
-bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
+bool SROMbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
{
unsigned char byOrgData;
@@ -237,7 +237,7 @@ bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsi
* Return Value: true if all test bits off; otherwise false
*
*/
-bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
+bool SROMbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits)
{
unsigned char byOrgData;
@@ -257,7 +257,7 @@ bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, uns
* Return Value: none
*
*/
-void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
+void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs)
{
int ii;
@@ -281,7 +281,7 @@ void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
* Return Value: none
*
*/
-void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
+void SROMvWriteAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs)
{
int ii;
@@ -304,7 +304,7 @@ void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs)
* Return Value: none
*
*/
-void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress)
+void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress)
{
unsigned char ii;
@@ -328,7 +328,7 @@ void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddres
* Return Value: none
*
*/
-void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress)
+void SROMvWriteEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress)
{
unsigned char ii;
@@ -351,7 +351,7 @@ void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddre
* Return Value: none
*
*/
-void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId)
+void SROMvReadSubSysVenId(void __iomem *dwIoBase, unsigned long *pdwSubSysVenId)
{
unsigned char *pbyData;
@@ -376,7 +376,7 @@ void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId)
* Return Value: true if success; otherwise false
*
*/
-bool SROMbAutoLoad(unsigned long dwIoBase)
+bool SROMbAutoLoad(void __iomem *dwIoBase)
{
unsigned char byWait;
int ii;
diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h
index 1df58c516ddc..3128e535bbd8 100644
--- a/drivers/staging/vt6655/srom.h
+++ b/drivers/staging/vt6655/srom.h
@@ -133,23 +133,23 @@ typedef struct tagSSromReg {
/*--------------------- Export Functions --------------------------*/
-unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset);
-bool SROMbWriteEmbedded(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byData);
+unsigned char SROMbyReadEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset);
+bool SROMbWriteEmbedded(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byData);
-void SROMvRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits);
-void SROMvRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byBits);
+void SROMvRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits);
+void SROMvRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byBits);
-bool SROMbIsRegBitsOn(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
-bool SROMbIsRegBitsOff(unsigned long dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
+bool SROMbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
+bool SROMbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byContntOffset, unsigned char byTestBits);
-void SROMvReadAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs);
-void SROMvWriteAllContents(unsigned long dwIoBase, unsigned char *pbyEepromRegs);
+void SROMvReadAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs);
+void SROMvWriteAllContents(void __iomem *dwIoBase, unsigned char *pbyEepromRegs);
-void SROMvReadEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress);
-void SROMvWriteEtherAddress(unsigned long dwIoBase, unsigned char *pbyEtherAddress);
+void SROMvReadEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress);
+void SROMvWriteEtherAddress(void __iomem *dwIoBase, unsigned char *pbyEtherAddress);
-void SROMvReadSubSysVenId(unsigned long dwIoBase, unsigned long *pdwSubSysVenId);
+void SROMvReadSubSysVenId(void __iomem *dwIoBase, unsigned long *pdwSubSysVenId);
-bool SROMbAutoLoad(unsigned long dwIoBase);
+bool SROMbAutoLoad(void __iomem *dwIoBase);
#endif // __EEPROM_H__
diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c
index ed6868a9c16e..ddc5efd040f9 100644
--- a/drivers/staging/vt6655/tcrc.c
+++ b/drivers/staging/vt6655/tcrc.c
@@ -41,7 +41,7 @@
/*--------------------- Static Variables --------------------------*/
-// 32-bit CRC table
+/* 32-bit CRC table */
static const unsigned long s_adwCrc32Table[256] = {
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
index 155e66439073..e262f1b00e66 100644
--- a/drivers/staging/vt6655/upc.h
+++ b/drivers/staging/vt6655/upc.h
@@ -35,79 +35,39 @@
/*--------------------- Export Definitions -------------------------*/
//
-// For IO mapped
-//
-
-#ifdef IO_MAP
-
-#define VNSvInPortB(dwIOAddress, pbyData) \
-do { \
- *(pbyData) = inb(dwIOAddress); \
-} while (0)
-
-#define VNSvInPortW(dwIOAddress, pwData) \
-do { \
- *(pwData) = inw(dwIOAddress); \
-} while (0)
-
-#define VNSvInPortD(dwIOAddress, pdwData) \
-do { \
- *(pdwData) = inl(dwIOAddress); \
-} while (0)
-
-#define VNSvOutPortB(dwIOAddress, byData) \
- outb(byData, dwIOAddress)
-
-#define VNSvOutPortW(dwIOAddress, wData) \
- outw(wData, dwIOAddress)
-
-#define VNSvOutPortD(dwIOAddress, dwData) \
- outl(dwData, dwIOAddress)
-
-#else
-
-//
// For memory mapped IO
//
#define VNSvInPortB(dwIOAddress, pbyData) \
do { \
- volatile unsigned char *pbyAddr = (unsigned char *)(dwIOAddress); \
- *(pbyData) = readb(pbyAddr); \
+ *(pbyData) = readb(dwIOAddress); \
} while (0)
#define VNSvInPortW(dwIOAddress, pwData) \
do { \
- volatile unsigned short *pwAddr = (unsigned short *)(dwIOAddress); \
- *(pwData) = readw(pwAddr); \
+ *(pwData) = readw(dwIOAddress); \
} while (0)
#define VNSvInPortD(dwIOAddress, pdwData) \
do { \
- volatile unsigned long *pdwAddr = (unsigned long *)(dwIOAddress); \
- *(pdwData) = readl(pdwAddr); \
+ *(pdwData) = readl(dwIOAddress); \
} while (0)
#define VNSvOutPortB(dwIOAddress, byData) \
do { \
- volatile unsigned char *pbyAddr = (unsigned char *)(dwIOAddress); \
- writeb((unsigned char)byData, pbyAddr); \
+ writeb((unsigned char)byData, dwIOAddress); \
} while (0)
#define VNSvOutPortW(dwIOAddress, wData) \
do { \
- volatile unsigned short *pwAddr = ((unsigned short *)(dwIOAddress)); \
- writew((unsigned short)wData, pwAddr); \
+ writew((unsigned short)wData, dwIOAddress); \
} while (0)
#define VNSvOutPortD(dwIOAddress, dwData) \
do { \
- volatile unsigned long *pdwAddr = (unsigned long *)(dwIOAddress); \
- writel((unsigned long)dwData, pdwAddr); \
+ writel((unsigned long)dwData, dwIOAddress); \
} while (0)
-#endif
-
//
// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment
//
diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c
index 7d61598563c7..4d425e0c76d4 100644
--- a/drivers/staging/vt6655/vntwifi.c
+++ b/drivers/staging/vt6655/vntwifi.c
@@ -128,6 +128,7 @@ VNTWIFIpGetCurrentSSID(
)
{
PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle;
+
return (PWLAN_IE_SSID) pMgmt->abyCurrSSID;
}
@@ -151,6 +152,7 @@ VNTWIFIpGetCurrentChannel(
)
{
PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle;
+
if (pMgmtHandle != NULL)
return pMgmt->uCurrChannel;
@@ -177,6 +179,7 @@ VNTWIFIwGetAssocID(
)
{
PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle;
+
return pMgmt->wCurrAID;
}
@@ -255,7 +258,7 @@ VNTWIFIbyGetACKTxRate(
if (byRxDataRate <= RATE_11M) {
byMaxAckRate = RATE_1M;
} else {
- // 24M is mandatory for 802.11a and 802.11g
+ /* 24M is mandatory for 802.11a and 802.11g */
byMaxAckRate = RATE_24M;
}
if (pSupportRateIEs) {
@@ -491,7 +494,7 @@ VNTWIFIvUpdateNodeTxCounter(
pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts++;
if (bTxOk) {
- // transmit success, TxAttempts at least plus one
+ /* transmit success, TxAttempts at least plus one */
pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wRate]++;
} else {
@@ -500,8 +503,6 @@ VNTWIFIvUpdateNodeTxCounter(
pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += pbyTxFailCount[MAX_RATE];
for (ii = 0; ii < MAX_RATE; ii++)
pMgmt->sNodeDBTable[uNodeIndex].uTxFail[ii] += pbyTxFailCount[ii];
-
- return;
}
void
@@ -525,7 +526,7 @@ VNTWIFIvGetTxRate(
if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
(pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
- // Adhoc Tx rate decided from node DB
+ /* Adhoc Tx rate decided from node DB */
if (BSSDBbIsSTAInNodeDB(pMgmt, pbyDestAddress, &uNodeIndex)) {
wTxDataRate = (pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
pSupportRateIEs = (PWLAN_IE_SUPP_RATES) (pMgmt->sNodeDBTable[uNodeIndex].abyCurrSuppRates);
@@ -539,11 +540,11 @@ VNTWIFIvGetTxRate(
pSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates;
pExtSupportRateIEs = (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates;
}
- } else { // Infrastructure: rate decided from AP Node, index = 0
+ } else { /* Infrastructure: rate decided from AP Node, index = 0 */
wTxDataRate = (pMgmt->sNodeDBTable[0].wTxDataRate);
#ifdef PLICE_DEBUG
- printk(KERN_DEBUG "GetTxRate:AP MAC is %pM,TxRate is %d\n",
+ pr_debug("GetTxRate:AP MAC is %pM,TxRate is %d\n",
pMgmt->sNodeDBTable[0].abyMACAddr, wTxDataRate);
#endif
@@ -569,7 +570,6 @@ VNTWIFIvGetTxRate(
*pbyACKRate = byACKRate;
*pbyCCKBasicRate = byCCKBasicRate;
*pbyOFDMBasicRate = byOFDMBasicRate;
- return;
}
unsigned char
@@ -684,9 +684,8 @@ VNTWIFIbMeasureReport(
pMgmt->uLengthOfRepEIDs += (2 + pMgmt->pCurrMeasureEIDRep->len);
pMgmt->pCurrMeasureEIDRep = (PWLAN_IE_MEASURE_REP) pbyCurrentEID;
}
- if (bEndOfReport) {
+ if (bEndOfReport)
IEEE11hbMSRRepTx(pMgmt);
- }
return true;
}
diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c
index a689645fa012..f12eef064c45 100644
--- a/drivers/staging/vt6655/wcmd.c
+++ b/drivers/staging/vt6655/wcmd.c
@@ -216,9 +216,9 @@ s_vProbeChannel(
if (pTxPacket != NULL) {
for (ii = 0; ii < 2; ii++) {
if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n");
else
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n");
}
}
}
@@ -234,7 +234,7 @@ s_vProbeChannel(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeProbeRequest(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -295,7 +295,6 @@ vCommandTimerWait(
// RUN_AT :1 msec ~= (HZ/1024)
pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
add_timer(&pDevice->sTimerCommand);
- return;
}
void
@@ -368,7 +367,7 @@ vCommandTimer(
} else {
//2008-8-4 <add> by chester
if (!is_channel_valid(pMgmt->uScanChannel)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n", pMgmt->uScanChannel);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel);
s_bCommandComplete(pDevice);
spin_unlock_irq(&pDevice->lock);
return;
@@ -433,9 +432,10 @@ vCommandTimer(
vAdHocBeaconRestart(pDevice);
//2008-0409-07, <Add> by Einsn Liu
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
- if (pMgmt->eScanType == WMAC_SCAN_PASSIVE)
- {//send scan event to wpa_Supplicant
+ if (pMgmt->eScanType == WMAC_SCAN_PASSIVE) {
+ //send scan event to wpa_Supplicant
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
}
@@ -493,7 +493,7 @@ vCommandTimer(
spin_unlock_irq(&pDevice->lock);
return;
}
- printk("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID);
+ pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID);
pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: desire ssid = %s\n", pItemSSID->abySSID);
@@ -560,7 +560,7 @@ vCommandTimer(
// start own IBSS
vMgrCreateOwnIBSS((void *)pDevice, &Status);
if (Status != CMD_STATUS_SUCCESS)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n");
BSSvAddMulticastNode(pDevice);
}
@@ -572,7 +572,7 @@ vCommandTimer(
// start own IBSS
vMgrCreateOwnIBSS((void *)pDevice, &Status);
if (Status != CMD_STATUS_SUCCESS)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n");
BSSvAddMulticastNode(pDevice);
if (netif_queue_stopped(pDevice->dev))
@@ -584,9 +584,10 @@ vCommandTimer(
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- printk("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
+ pr_debug("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
#endif
@@ -614,10 +615,10 @@ vCommandTimer(
}
else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
- printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
+ pr_debug("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
} else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if authenticated_frame delay!
pDevice->byLinkWaitCount++;
- printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
+ pr_debug("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
spin_unlock_irq(&pDevice->lock);
vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2);
return;
@@ -664,7 +665,7 @@ vCommandTimer(
printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
} else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay!
pDevice->byLinkWaitCount++;
- printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
+ pr_debug("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
spin_unlock_irq(&pDevice->lock);
vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2);
return;
@@ -692,7 +693,7 @@ vCommandTimer(
vMgrCreateOwnIBSS((void *)pDevice, &Status);
if (Status != CMD_STATUS_SUCCESS)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail !\n");
// alway turn off unicast bit
MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
@@ -719,7 +720,7 @@ vCommandTimer(
pDevice->bMoreData = true;
}
if (!device_dma0_xmit(pDevice, skb, 0))
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n");
pMgmt->sNodeDBTable[0].wEnQueueCnt--;
}
@@ -741,7 +742,7 @@ vCommandTimer(
pDevice->bMoreData = true;
}
if (!device_dma0_xmit(pDevice, skb, ii))
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n");
pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
// check if sta ps enabled, and wait next pspoll.
@@ -753,7 +754,7 @@ vCommandTimer(
// clear tx map
pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii);
}
pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
}
@@ -796,7 +797,6 @@ vCommandTimer(
} //switch
spin_unlock_irq(&pDevice->lock);
- return;
}
static
@@ -992,6 +992,7 @@ BSSvSecondTxData(
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+
pDevice->nTxDataTimeCout++;
if (pDevice->nTxDataTimeCout < 4) //don't tx data if timer less than 40s
diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h
index 2844476d5dc9..126b61c48791 100644
--- a/drivers/staging/vt6655/wcmd.h
+++ b/drivers/staging/vt6655/wcmd.h
@@ -33,12 +33,9 @@
#include "80211hdr.h"
#include "80211mgr.h"
-/*--------------------- Export Definitions -------------------------*/
+#define AUTHENTICATE_TIMEOUT 1000
+#define ASSOCIATE_TIMEOUT 1000
-#define AUTHENTICATE_TIMEOUT 1000 //ms
-#define ASSOCIATE_TIMEOUT 1000 //ms
-
-// Command code
typedef enum tagCMD_CODE {
WLAN_CMD_BSSID_SCAN,
WLAN_CMD_SSID,
@@ -76,7 +73,6 @@ typedef struct tagCMD_ITEM {
bool bForceSCAN;
} CMD_ITEM, *PCMD_ITEM;
-// Command state
typedef enum tagCMD_STATE {
WLAN_CMD_SCAN_START,
WLAN_CMD_SCAN_END,
@@ -92,13 +88,6 @@ typedef enum tagCMD_STATE {
WLAN_CMD_IDLE
} CMD_STATE, *PCMD_STATE;
-/*--------------------- Export Classes ----------------------------*/
-
-/*--------------------- Export Variables --------------------------*/
-
-/*--------------------- Export Types ------------------------------*/
-
-/*--------------------- Export Functions --------------------------*/
void
vResetCommandTimer(
void *hDeviceContext
diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c
index 67384782b702..e88e11606db0 100644
--- a/drivers/staging/vt6655/wmgr.c
+++ b/drivers/staging/vt6655/wmgr.c
@@ -358,8 +358,6 @@ vMgrObjectInit(
pMgmt->byCSSGK = KEY_CTL_NONE;
pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
BSSvClearBSSList((void *)pDevice, false);
-
- return;
}
/*+
@@ -403,8 +401,6 @@ vMgrTimerInit(
pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
pDevice->uCmdDequeueIdx = 0;
pDevice->uCmdEnqueueIdx = 0;
-
- return;
}
/*+
@@ -429,8 +425,6 @@ vMgrObjectReset(
pMgmt->eCurrState = WMAC_STATE_IDLE;
pDevice->bEnablePSMode = false;
// TODO: timer
-
- return;
}
/*+
@@ -498,8 +492,6 @@ vMgrAssocBeginSta(
} else {
*pStatus = CMD_STATUS_RESOURCES;
}
-
- return;
}
/*+
@@ -565,8 +557,6 @@ vMgrReAssocBeginSta(
else
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
}
-
- return;
}
/*+
@@ -625,8 +615,6 @@ vMgrDisassocBeginSta(
pMgmt->eCurrState = WMAC_STATE_IDLE;
*pStatus = CMD_STATUS_SUCCESS;
}
-
- return;
}
/*+
@@ -710,7 +698,7 @@ s_vMgrRxAssocRequest(
pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
#ifdef PLICE_DEBUG
- printk("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
+ pr_debug("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
#endif
// Todo: check sta preamble, if ap can't support, set status code
pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
@@ -732,8 +720,8 @@ s_vMgrRxAssocRequest(
if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
pDevice->bBarkerPreambleMd = true;
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d\n", wAssocAID);
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
sFrame.pHdr->sA3.abyAddr2[0],
sFrame.pHdr->sA3.abyAddr2[1],
sFrame.pHdr->sA3.abyAddr2[2],
@@ -741,7 +729,7 @@ s_vMgrRxAssocRequest(
sFrame.pHdr->sA3.abyAddr2[4],
sFrame.pHdr->sA3.abyAddr2[5]
);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d\n",
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
} else {
/* TODO: received STA under state1 handle */
@@ -771,8 +759,6 @@ s_vMgrRxAssocRequest(
else
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
}
-
- return;
}
/*+
@@ -860,7 +846,7 @@ s_vMgrRxReAssocRequest(
pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
#ifdef PLICE_DEBUG
- printk("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
+ pr_debug("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
#endif
// Todo: check sta preamble, if ap can't support, set status code
pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
@@ -883,8 +869,8 @@ s_vMgrRxReAssocRequest(
if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
pDevice->bBarkerPreambleMd = true;
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d\n", wAssocAID);
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
sFrame.pHdr->sA3.abyAddr2[0],
sFrame.pHdr->sA3.abyAddr2[1],
sFrame.pHdr->sA3.abyAddr2[2],
@@ -892,7 +878,7 @@ s_vMgrRxReAssocRequest(
sFrame.pHdr->sA3.abyAddr2[4],
sFrame.pHdr->sA3.abyAddr2[5]
);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+ DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d\n",
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
}
@@ -921,7 +907,6 @@ s_vMgrRxReAssocRequest(
else
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
}
- return;
}
/*+
@@ -1070,7 +1055,6 @@ s_vMgrRxAssocResponse(
if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
timer_expire(pDevice->sTimerCommand, 0);
- return;
}
/*+
@@ -1125,8 +1109,6 @@ vMgrAuthenBeginSta(
pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
*pStatus = CMD_STATUS_SUCCESS;
}
-
- return;
}
/*+
@@ -1178,8 +1160,6 @@ vMgrDeAuthenBeginSta(
*pStatus = csMgmt_xmit(pDevice, pTxPacket);
if (*pStatus == CMD_STATUS_PENDING)
*pStatus = CMD_STATUS_SUCCESS;
-
- return;
}
/*+
@@ -1232,7 +1212,6 @@ s_vMgrRxAuthentication(
cpu_to_le16((*(sFrame.pwAuthSequence))));
break;
}
- return;
}
/*+
@@ -1329,11 +1308,9 @@ s_vMgrRxAuthenSequence_1(
if (pDevice->bEnableHostapd)
return;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx..\n");
if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
-
- return;
}
/*+
@@ -1418,7 +1395,6 @@ s_vMgrRxAuthenSequence_2(
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
break;
}
- return;
}
/*+
@@ -1504,8 +1480,6 @@ reply:
if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
-
- return;
}
/*+
@@ -1596,16 +1570,15 @@ s_vMgrRxDisassociation(
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+ pr_debug("wireless_send_event--->SIOCGIWAP(disassociated)\n");
wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
}
#endif
}
/* else, ignore it */
-
- return;
}
/*+
@@ -1677,6 +1650,7 @@ s_vMgrRxDeauthentication(
#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
{
union iwreq_data wrqu;
+
memset(&wrqu, 0, sizeof(wrqu));
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
@@ -1688,7 +1662,6 @@ s_vMgrRxDeauthentication(
/* else, ignore it. TODO: IBSS authentication service
would be implemented here */
}
- return;
}
//2008-8-4 <add> by chester
@@ -1993,7 +1966,7 @@ s_vMgrRxBeacon(
}
}
-// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2 \n");
+// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2\n");
// check if CF field exists
if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
if (sFrame.pCFParms->wCFPDurRemaining > 0) {
@@ -2137,14 +2110,14 @@ s_vMgrRxBeacon(
pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
#ifdef PLICE_DEBUG
{
- printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex);
+ pr_debug("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex);
}
#endif
}
// if other stations joined, indicate connection to upper layer..
if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed]\n");
pMgmt->eCurrState = WMAC_STATE_JOINTED;
pDevice->bLinkPass = true;
if (netif_queue_stopped(pDevice->dev))
@@ -2197,8 +2170,6 @@ if (bUpdateTSF) {
CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
}
-
- return;
}
/*+
@@ -2434,8 +2405,6 @@ vMgrCreateOwnIBSS(
// Prepare beacon to send
if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt))
*pStatus = CMD_STATUS_SUCCESS;
-
- return;
}
/*+
@@ -2574,6 +2543,7 @@ vMgrJoinBSSBegin(
// This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult);
if (!bResult) {
vFlush_PMKID_Candidate((void *)pDevice);
@@ -2656,7 +2626,6 @@ vMgrJoinBSSBegin(
pMgmt->eCurrState = WMAC_STATE_IDLE;
}
}
- return;
}
/*+
@@ -2838,8 +2807,6 @@ static void Encyption_Rebuild(
}
}
}
-
- return;
}
/*+
@@ -3144,7 +3111,7 @@ s_MgrMakeBeacon(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeProbeResponse(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -3326,7 +3293,7 @@ s_MgrMakeProbeResponse(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeAssocRequest(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -3586,7 +3553,7 @@ s_MgrMakeAssocRequest(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeReAssocRequest(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -3831,7 +3798,7 @@ s_MgrMakeReAssocRequest(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeAssocResponse(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -3902,7 +3869,7 @@ s_MgrMakeAssocResponse(
*
-*/
-PSTxMgmtPacket
+static PSTxMgmtPacket
s_MgrMakeReAssocResponse(
PSDevice pDevice,
PSMgmtObject pMgmt,
@@ -3999,13 +3966,13 @@ s_vMgrRxProbeResponse(
(sFrame.pwCapInfo == NULL) ||
(sFrame.pSSID == NULL) ||
(sFrame.pSuppRates == NULL)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n", pRxPacket->p80211Header);
DBG_PORT80(0xCC);
return;
}
if (sFrame.pSSID->len == 0)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0\n");
if (sFrame.pDSParms != NULL) {
if (byCurrChannel > CB_MAX_CHANNEL_24G) {
@@ -4079,7 +4046,6 @@ s_vMgrRxProbeResponse(
(void *)pRxPacket
);
}
- return;
}
/*+
@@ -4148,13 +4114,10 @@ s_vMgrRxProbeRequest(
if (pTxPacket != NULL) {
/* send the frame */
Status = csMgmt_xmit(pDevice, pTxPacket);
- if (Status != CMD_STATUS_PENDING) {
+ if (Status != CMD_STATUS_PENDING)
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
- }
}
}
-
- return;
}
/*+
@@ -4297,8 +4260,6 @@ vMgrRxManagePacket(
default:
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
}
-
- return;
}
/*+
@@ -4438,7 +4399,7 @@ bAdd_PMKID_Candidate(
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
- PPMKID_CANDIDATE pCandidateList;
+ struct pmkid_candidate *pCandidateList;
unsigned int ii = 0;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h
index 2312d71bac43..a71daed7fa0b 100644
--- a/drivers/staging/vt6655/wmgr.h
+++ b/drivers/staging/vt6655/wmgr.h
@@ -83,22 +83,19 @@ typedef void (*TimerFunction)(unsigned long);
//+++ NDIS related
typedef unsigned char NDIS_802_11_MAC_ADDRESS[6];
-typedef struct _NDIS_802_11_AI_REQFI
-{
+typedef struct _NDIS_802_11_AI_REQFI {
unsigned short Capabilities;
unsigned short ListenInterval;
NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
-typedef struct _NDIS_802_11_AI_RESFI
-{
+typedef struct _NDIS_802_11_AI_RESFI {
unsigned short Capabilities;
unsigned short StatusCode;
unsigned short AssociationId;
} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
-typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
-{
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION {
unsigned long Length;
unsigned short AvailableRequestFixedIEs;
NDIS_802_11_AI_REQFI RequestFixedIEs;
@@ -187,8 +184,7 @@ typedef struct tagSRxMgmtPacket {
unsigned char byRxChannel;
} SRxMgmtPacket, *PSRxMgmtPacket;
-typedef struct tagSMgmtObject
-{
+typedef struct tagSMgmtObject {
void *pAdapter;
// MAC address
unsigned char abyMACAddr[WLAN_ADDR_LEN];
diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c
index 9be59c23d7e6..7b1bab91a9cf 100644
--- a/drivers/staging/vt6655/wpa.c
+++ b/drivers/staging/vt6655/wpa.c
@@ -73,6 +73,7 @@ WPA_ClearRSN(
)
{
int ii;
+
pBSSList->byGKType = WPA_TKIP;
for (ii = 0; ii < 4; ii++)
pBSSList->abyPKType[ii] = WPA_TKIP;
@@ -122,8 +123,8 @@ WPA_ParseRSN(
&& (pRSN->wVersion == 1)) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Legal RSN\n");
// update each variable if pRSN is long enough to contain the variable
- if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4)
- {
+ if (pRSN->len >= 10) {
+ //OUI1(4)+ver(2)+GKSuite(4)
if (!memcmp(pRSN->abyMulticast, abyOUI01, 4))
pBSSList->byGKType = WPA_WEP40;
else if (!memcmp(pRSN->abyMulticast, abyOUI02, 4))
@@ -141,8 +142,8 @@ WPA_ParseRSN(
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byGKType: %x\n", pBSSList->byGKType);
}
- if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
- {
+ if (pRSN->len >= 12) {
+ //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
j = 0;
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
for (i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) {
@@ -261,7 +262,6 @@ WPA_SearchRSN(
return false;
}
return true;
- break;
default:
break;
diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c
index 8392d4d1d5ed..5f454ca2a3bc 100644
--- a/drivers/staging/vt6655/wpactl.c
+++ b/drivers/staging/vt6655/wpactl.c
@@ -89,7 +89,8 @@ static int wpa_init_wpadev(PSDevice pDevice)
struct net_device *dev = pDevice->dev;
int ret = 0;
- pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
+ pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa",
+ NET_NAME_UNKNOWN, wpadev_setup);
if (pDevice->wpadev == NULL)
return -ENOMEM;
@@ -556,7 +557,7 @@ static int wpa_get_scan(PSDevice pDevice,
ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC);
if (ptempBSS == NULL) {
- printk(KERN_ERR "bubble sort kmalloc memory fail@@@\n");
+ pr_err("bubble sort kmalloc memory fail@@@\n");
ret = -ENOMEM;
@@ -766,6 +767,7 @@ static int wpa_set_associate(PSDevice pDevice,
/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
{
PKnownBSS pCurr = NULL;
+
pCurr = BSSpSearchBSSList(pDevice,
pMgmt->abyDesireBSSID,
pMgmt->abyDesireSSID,
@@ -773,7 +775,7 @@ static int wpa_set_associate(PSDevice pDevice,
);
if (pCurr == NULL) {
- printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
+ pr_debug("wpa_set_associate---->hidden mode site survey before associate.......\n");
bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
}
}
diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h
deleted file mode 100644
index 1e778ba7c634..000000000000
--- a/drivers/staging/vt6656/80211hdr.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: 80211hdr.h
- *
- * Purpose: 802.11 MAC headers related pre-defines and macros.
- *
- * Author: Lyndon Chen
- *
- * Date: Apr 8, 2002
- */
-
-#ifndef __80211HDR_H__
-#define __80211HDR_H__
-
-/* bit type */
-#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
-
-/* 802.11 frame related, defined as 802.11 spec */
-#define WLAN_ADDR_LEN 6
-#define WLAN_CRC_LEN 4
-#define WLAN_CRC32_LEN 4
-#define WLAN_FCS_LEN 4
-#define WLAN_BSSID_LEN 6
-#define WLAN_BSS_TS_LEN 8
-#define WLAN_HDR_ADDR2_LEN 16
-#define WLAN_HDR_ADDR3_LEN 24
-#define WLAN_HDR_ADDR4_LEN 30
-#define WLAN_IEHDR_LEN 2
-#define WLAN_SSID_MAXLEN 32
-#define WLAN_RATES_MAXLEN 16
-#define WLAN_RATES_MAXLEN_11B 4
-#define WLAN_RSN_MAXLEN 32
-#define WLAN_DATA_MAXLEN 2312
-#define WLAN_A3FR_MAXLEN (WLAN_HDR_ADDR3_LEN \
- + WLAN_DATA_MAXLEN \
- + WLAN_CRC_LEN)
-
-#define WLAN_BEACON_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0)
-#define WLAN_NULLDATA_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0)
-#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2)
-#define WLAN_ASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_ASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_REASSOCREQ_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_REASSOCRESP_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_PROBEREQ_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_PROBERESP_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_AUTHEN_FR_MAXLEN WLAN_A3FR_MAXLEN
-#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2)
-
-#define WLAN_WEP_NKEYS 4
-#define WLAN_WEP40_KEYLEN 5
-#define WLAN_WEP104_KEYLEN 13
-#define WLAN_WEP232_KEYLEN 29
-#define WLAN_WEPMAX_KEYLEN 32
-#define WLAN_CHALLENGE_IE_MAXLEN 255
-#define WLAN_CHALLENGE_IE_LEN 130
-#define WLAN_CHALLENGE_LEN 128
-#define WLAN_WEP_IV_LEN 4
-#define WLAN_WEP_ICV_LEN 4
-#define WLAN_FRAGS_MAX 16
-
-/* Frame Type */
-#define WLAN_TYPE_MGR 0x00
-#define WLAN_TYPE_CTL 0x01
-#define WLAN_TYPE_DATA 0x02
-
-#define WLAN_FTYPE_MGMT 0x00
-#define WLAN_FTYPE_CTL 0x01
-#define WLAN_FTYPE_DATA 0x02
-
-/* Frame Subtypes */
-#define WLAN_FSTYPE_ASSOCREQ 0x00
-#define WLAN_FSTYPE_ASSOCRESP 0x01
-#define WLAN_FSTYPE_REASSOCREQ 0x02
-#define WLAN_FSTYPE_REASSOCRESP 0x03
-#define WLAN_FSTYPE_PROBEREQ 0x04
-#define WLAN_FSTYPE_PROBERESP 0x05
-#define WLAN_FSTYPE_BEACON 0x08
-#define WLAN_FSTYPE_ATIM 0x09
-#define WLAN_FSTYPE_DISASSOC 0x0a
-#define WLAN_FSTYPE_AUTHEN 0x0b
-#define WLAN_FSTYPE_DEAUTHEN 0x0c
-#define WLAN_FSTYPE_ACTION 0x0d
-
-/* Control */
-#define WLAN_FSTYPE_PSPOLL 0x0a
-#define WLAN_FSTYPE_RTS 0x0b
-#define WLAN_FSTYPE_CTS 0x0c
-#define WLAN_FSTYPE_ACK 0x0d
-#define WLAN_FSTYPE_CFEND 0x0e
-#define WLAN_FSTYPE_CFENDCFACK 0x0f
-
-/* Data */
-#define WLAN_FSTYPE_DATAONLY 0x00
-#define WLAN_FSTYPE_DATA_CFACK 0x01
-#define WLAN_FSTYPE_DATA_CFPOLL 0x02
-#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03
-#define WLAN_FSTYPE_NULL 0x04
-#define WLAN_FSTYPE_CFACK 0x05
-#define WLAN_FSTYPE_CFPOLL 0x06
-#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
-
-#ifdef __BIG_ENDIAN
-
-/* GET & SET Frame Control bit */
-#define WLAN_GET_FC_PRVER(n) (((u16)(n) >> 8) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n) ((((u16)(n) >> 8) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n) >> 8) \
- & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n) ((((u16)(n) << 8) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n) ((((u16)(n) << 8) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n) << 8) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n) ((((u16)(n) << 8) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n) << 8) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n) << 8) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n) ((((u16)(n) << 8) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n) ((((u16)(n) << 8) & (BIT15)) >> 15)
-
-/* Sequence Field bit */
-#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n) >> 8) \
- & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
-
-/* Capability Field bit */
-#define WLAN_GET_CAP_INFO_ESS(n) (((n) >> 8) & BIT0)
-#define WLAN_GET_CAP_INFO_IBSS(n) ((((n) >> 8) & BIT1) >> 1)
-#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) ((((n) >> 8) & BIT2) >> 2)
-#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) ((((n) >> 8) & BIT3) >> 3)
-#define WLAN_GET_CAP_INFO_PRIVACY(n) ((((n) >> 8) & BIT4) >> 4)
-#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) ((((n) >> 8) & BIT5) >> 5)
-#define WLAN_GET_CAP_INFO_PBCC(n) ((((n) >> 8) & BIT6) >> 6)
-#define WLAN_GET_CAP_INFO_AGILITY(n) ((((n) >> 8) & BIT7) >> 7)
-#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) ((((n)) & BIT8) >> 10)
-#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) ((((n)) & BIT10) >> 10)
-#define WLAN_GET_CAP_INFO_DSSSOFDM(n) ((((n)) & BIT13) >> 13)
-#define WLAN_GET_CAP_INFO_GRPACK(n) ((((n)) & BIT14) >> 14)
-
-#else
-
-/* GET & SET Frame Control bit */
-#define WLAN_GET_FC_PRVER(n) (((u16)(n)) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n) ((((u16)(n)) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n)) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n) ((((u16)(n)) & (BIT15)) >> 15)
-
-/* Sequence Field bit */
-#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
-
-/* Capability Field bit */
-#define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0)
-#define WLAN_GET_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1)
-#define WLAN_GET_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2)
-#define WLAN_GET_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3)
-#define WLAN_GET_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4)
-#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) (((n) & BIT5) >> 5)
-#define WLAN_GET_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6)
-#define WLAN_GET_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7)
-#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n) (((n) & BIT8) >> 10)
-#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) (((n) & BIT10) >> 10)
-#define WLAN_GET_CAP_INFO_DSSSOFDM(n) (((n) & BIT13) >> 13)
-#define WLAN_GET_CAP_INFO_GRPACK(n) (((n) & BIT14) >> 14)
-
-#endif /* #ifdef __BIG_ENDIAN */
-
-#define WLAN_SET_CAP_INFO_ESS(n) (n)
-#define WLAN_SET_CAP_INFO_IBSS(n) ((n) << 1)
-#define WLAN_SET_CAP_INFO_CFPOLLABLE(n) ((n) << 2)
-#define WLAN_SET_CAP_INFO_CFPOLLREQ(n) ((n) << 3)
-#define WLAN_SET_CAP_INFO_PRIVACY(n) ((n) << 4)
-#define WLAN_SET_CAP_INFO_SHORTPREAMBLE(n) ((n) << 5)
-#define WLAN_SET_CAP_INFO_SPECTRUMMNG(n) ((n) << 8)
-#define WLAN_SET_CAP_INFO_PBCC(n) ((n) << 6)
-#define WLAN_SET_CAP_INFO_AGILITY(n) ((n) << 7)
-#define WLAN_SET_CAP_INFO_SHORTSLOTTIME(n) ((n) << 10)
-#define WLAN_SET_CAP_INFO_DSSSOFDM(n) ((n) << 13)
-#define WLAN_SET_CAP_INFO_GRPACK(n) ((n) << 14)
-
-#define WLAN_SET_FC_PRVER(n) ((u16)(n))
-#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2)
-#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4)
-#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8)
-#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9)
-#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10)
-#define WLAN_SET_FC_RETRY(n) (((u16)(n)) << 11)
-#define WLAN_SET_FC_PWRMGT(n) (((u16)(n)) << 12)
-#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13)
-#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14)
-#define WLAN_SET_FC_ORDER(n) (((u16)(n)) << 15)
-
-#define WLAN_SET_SEQ_FRGNUM(n) ((u16)(n))
-#define WLAN_SET_SEQ_SEQNUM(n) (((u16)(n)) << 4)
-
-/* ERP Field bit */
-
-#define WLAN_GET_ERP_NONERP_PRESENT(n) ((n) & BIT0)
-#define WLAN_GET_ERP_USE_PROTECTION(n) (((n) & BIT1) >> 1)
-#define WLAN_GET_ERP_BARKER_MODE(n) (((n) & BIT2) >> 2)
-
-#define WLAN_SET_ERP_NONERP_PRESENT(n) (n)
-#define WLAN_SET_ERP_USE_PROTECTION(n) ((n) << 1)
-#define WLAN_SET_ERP_BARKER_MODE(n) ((n) << 2)
-
-/* Support & Basic Rates field */
-#define WLAN_MGMT_IS_BASICRATE(b) ((b) & BIT7)
-#define WLAN_MGMT_GET_RATE(b) ((b) & ~BIT7)
-
-/* TIM field */
-#define WLAN_MGMT_IS_MULTICAST_TIM(b) ((b) & BIT0)
-#define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1)
-
-/* 3-Addr & 4-Addr */
-#define WLAN_HDR_A3_DATA_PTR(p) (((u8 *)(p)) + WLAN_HDR_ADDR3_LEN)
-#define WLAN_HDR_A4_DATA_PTR(p) (((u8 *)(p)) + WLAN_HDR_ADDR4_LEN)
-
-/* IEEE ADDR */
-#define IEEE_ADDR_UNIVERSAL 0x02
-#define IEEE_ADDR_GROUP 0x01
-
-typedef struct {
- u8 abyAddr[6];
-} IEEE_ADDR, *PIEEE_ADDR;
-
-/* 802.11 Header Format */
-
-typedef struct tagWLAN_80211HDR_A2 {
-
- u16 wFrameCtl;
- u16 wDurationID;
- u8 abyAddr1[WLAN_ADDR_LEN];
- u8 abyAddr2[WLAN_ADDR_LEN];
-
-} __attribute__ ((__packed__))
-WLAN_80211HDR_A2, *PWLAN_80211HDR_A2;
-
-typedef struct tagWLAN_80211HDR_A3 {
-
- u16 wFrameCtl;
- u16 wDurationID;
- u8 abyAddr1[WLAN_ADDR_LEN];
- u8 abyAddr2[WLAN_ADDR_LEN];
- u8 abyAddr3[WLAN_ADDR_LEN];
- u16 wSeqCtl;
-
-} __attribute__ ((__packed__))
-WLAN_80211HDR_A3, *PWLAN_80211HDR_A3;
-
-typedef struct tagWLAN_80211HDR_A4 {
-
- u16 wFrameCtl;
- u16 wDurationID;
- u8 abyAddr1[WLAN_ADDR_LEN];
- u8 abyAddr2[WLAN_ADDR_LEN];
- u8 abyAddr3[WLAN_ADDR_LEN];
- u16 wSeqCtl;
- u8 abyAddr4[WLAN_ADDR_LEN];
-
-} __attribute__ ((__packed__))
-WLAN_80211HDR_A4, *PWLAN_80211HDR_A4;
-
-typedef union tagUWLAN_80211HDR {
-
- WLAN_80211HDR_A2 sA2;
- WLAN_80211HDR_A3 sA3;
- WLAN_80211HDR_A4 sA4;
-
-} UWLAN_80211HDR, *PUWLAN_80211HDR;
-
-#endif /* __80211HDR_H__ */
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
deleted file mode 100644
index 61edb51f3836..000000000000
--- a/drivers/staging/vt6656/80211mgr.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: 80211mgr.c
- *
- * Purpose: Handles the 802.11 management support functions
- *
- * Author: Lyndon Chen
- *
- * Date: May 8, 2002
- *
- * Functions:
- * vMgrEncodeBeacon - Encode the Beacon frame
- * vMgrDecodeBeacon - Decode the Beacon frame
- * vMgrEncodeDisassociation - Encode the Disassociation frame
- * vMgrDecodeDisassociation - Decode the Disassociation frame
- * vMgrEncodeAssocRequest - Encode the Association request frame
- * vMgrDecodeAssocRequest - Decode the Association request frame
- * vMgrEncodeAssocResponse - Encode the Association response frame
- * vMgrDecodeAssocResponse - Decode the Association response frame
- * vMgrEncodeReAssocRequest - Encode the ReAssociation request frame
- * vMgrDecodeReAssocRequest - Decode the ReAssociation request frame
- * vMgrEncodeProbeRequest - Encode the Probe request frame
- * vMgrDecodeProbeRequest - Decode the Probe request frame
- * vMgrEncodeProbeResponse - Encode the Probe response frame
- * vMgrDecodeProbeResponse - Decode the Probe response frame
- * vMgrEncodeAuthen - Encode the Authentication frame
- * vMgrDecodeAuthen - Decode the Authentication frame
- * vMgrEncodeDeauthen - Encode the DeAuthentication frame
- * vMgrDecodeDeauthen - Decode the DeAuthentication frame
- * vMgrEncodeReassocResponse - Encode the Reassociation response frame
- *
- * Revision History:
- *
- */
-
-#include "device.h"
-#include "tmacro.h"
-#include "tether.h"
-#include "80211mgr.h"
-#include "80211hdr.h"
-#include "wpa.h"
-
-static int msglevel = MSG_LEVEL_INFO;
-/*static int msglevel =MSG_LEVEL_DEBUG;*/
-
-/*+
- *
- * Routine Description:
- * Encode Beacon frame body offset
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeBeacon(
- PWLAN_FR_BEACON pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pqwTimestamp =
- (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
- WLAN_BEACON_OFF_TS);
- pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_BEACON_OFF_BCN_INT);
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_BEACON_OFF_CAPINFO);
-
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID;
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Decode Beacon frame body offset
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeBeacon(
- PWLAN_FR_BEACON pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pqwTimestamp =
- (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
- WLAN_BEACON_OFF_TS);
- pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_BEACON_OFF_BCN_INT);
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_BEACON_OFF_CAPINFO);
-
- /* Information elements */
- pItem = (PWLAN_IE)((u8 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
- + WLAN_BEACON_OFF_SSID);
- while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
-
- switch (pItem->byElementID) {
- case WLAN_EID_SSID:
- if (pFrame->pSSID == NULL)
- pFrame->pSSID = (PWLAN_IE_SSID)pItem;
- break;
- case WLAN_EID_SUPP_RATES:
- if (pFrame->pSuppRates == NULL)
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
- case WLAN_EID_FH_PARMS:
- /* pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem; */
- break;
- case WLAN_EID_DS_PARMS:
- if (pFrame->pDSParms == NULL)
- pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
- break;
- case WLAN_EID_CF_PARMS:
- if (pFrame->pCFParms == NULL)
- pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
- break;
- case WLAN_EID_IBSS_PARMS:
- if (pFrame->pIBSSParms == NULL)
- pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
- break;
- case WLAN_EID_TIM:
- if (pFrame->pTIM == NULL)
- pFrame->pTIM = (PWLAN_IE_TIM)pItem;
- break;
-
- case WLAN_EID_RSN:
- if (pFrame->pRSN == NULL)
- pFrame->pRSN = (PWLAN_IE_RSN)pItem;
- break;
- case WLAN_EID_RSN_WPA:
- if (pFrame->pRSNWPA == NULL) {
- if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
- pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
- }
- break;
-
- case WLAN_EID_ERP:
- if (pFrame->pERP == NULL)
- pFrame->pERP = (PWLAN_IE_ERP)pItem;
- break;
- case WLAN_EID_EXTSUPP_RATES:
- if (pFrame->pExtSuppRates == NULL)
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- case WLAN_EID_COUNTRY: /* 7 */
- if (pFrame->pIE_Country == NULL)
- pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
- break;
-
- case WLAN_EID_PWR_CONSTRAINT: /* 32 */
- if (pFrame->pIE_PowerConstraint == NULL)
- pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
- break;
-
- case WLAN_EID_CH_SWITCH: /* 37 */
- if (pFrame->pIE_CHSW == NULL)
- pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
- break;
-
- case WLAN_EID_QUIET: /* 40 */
- if (pFrame->pIE_Quiet == NULL)
- pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
- break;
-
- case WLAN_EID_IBSS_DFS:
- if (pFrame->pIE_IBSSDFS == NULL)
- pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
- break;
-
- }
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
- }
-}
-
-/*+
- *
- * Routine Description:
- * Encode Disassociation
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeDisassociation(
- PWLAN_FR_DISASSOC pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_DISASSOC_OFF_REASON);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
-}
-
-/*+
- *
- * Routine Description:
- * Decode Disassociation
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeDisassociation(
- PWLAN_FR_DISASSOC pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_DISASSOC_OFF_REASON);
-}
-
-/*+
- *
- * Routine Description:
- * Encode Association Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeAssocRequest(
- PWLAN_FR_ASSOCREQ pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCREQ_OFF_CAP_INFO);
- pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCREQ_OFF_LISTEN_INT);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval));
-}
-
-/*+
- *
- * Routine Description: (AP)
- * Decode Association Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeAssocRequest(
- PWLAN_FR_ASSOCREQ pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCREQ_OFF_CAP_INFO);
- pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCREQ_OFF_LISTEN_INT);
-
- /* Information elements */
- pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCREQ_OFF_SSID);
-
- while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
- switch (pItem->byElementID) {
- case WLAN_EID_SSID:
- if (pFrame->pSSID == NULL)
- pFrame->pSSID = (PWLAN_IE_SSID)pItem;
- break;
- case WLAN_EID_SUPP_RATES:
- if (pFrame->pSuppRates == NULL)
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- case WLAN_EID_RSN:
- if (pFrame->pRSN == NULL)
- pFrame->pRSN = (PWLAN_IE_RSN)pItem;
- break;
- case WLAN_EID_RSN_WPA:
- if (pFrame->pRSNWPA == NULL) {
- if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
- pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
- }
- break;
- case WLAN_EID_EXTSUPP_RATES:
- if (pFrame->pExtSuppRates == NULL)
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
- pItem->byElementID);
- break;
- }
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
- }
-}
-
-/*+
- *
- * Routine Description: (AP)
- * Encode Association Response
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeAssocResponse(
- PWLAN_FR_ASSOCRESP pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_CAP_INFO);
- pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_STATUS);
- pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_AID);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID
- + sizeof(*(pFrame->pwAid));
-}
-
-/*+
- *
- * Routine Description:
- * Decode Association Response
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeAssocResponse(
- PWLAN_FR_ASSOCRESP pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_CAP_INFO);
- pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_STATUS);
- pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_AID);
-
- /* Information elements */
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_ASSOCRESP_OFF_SUPP_RATES);
-
- pItem = (PWLAN_IE)(pFrame->pSuppRates);
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
-
- if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
- } else
- pFrame->pExtSuppRates = NULL;
-}
-
-/*+
- *
- * Routine Description:
- * Encode Reassociation Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeReassocRequest(
- PWLAN_FR_REASSOCREQ pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_CAP_INFO);
- pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_LISTEN_INT);
- pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_CURR_AP);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP));
-}
-
-/*+
- *
- * Routine Description: (AP)
- * Decode Reassociation Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeReassocRequest(
- PWLAN_FR_REASSOCREQ pFrame
- )
-{
- PWLAN_IE pItem;
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_CAP_INFO);
- pFrame->pwListenInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_LISTEN_INT);
- pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_CURR_AP);
-
- /* Information elements */
- pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCREQ_OFF_SSID);
-
- while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
-
- switch (pItem->byElementID) {
- case WLAN_EID_SSID:
- if (pFrame->pSSID == NULL)
- pFrame->pSSID = (PWLAN_IE_SSID)pItem;
- break;
- case WLAN_EID_SUPP_RATES:
- if (pFrame->pSuppRates == NULL)
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- case WLAN_EID_RSN:
- if (pFrame->pRSN == NULL)
- pFrame->pRSN = (PWLAN_IE_RSN)pItem;
- break;
- case WLAN_EID_RSN_WPA:
- if (pFrame->pRSNWPA == NULL)
- if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
- pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
- break;
-
- case WLAN_EID_EXTSUPP_RATES:
- if (pFrame->pExtSuppRates == NULL)
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
- pItem->byElementID);
- break;
- }
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
- }
-}
-
-/*+
- *
- * Routine Description:
- * Encode Probe Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeProbeRequest(
- PWLAN_FR_PROBEREQ pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
- pFrame->len = WLAN_HDR_ADDR3_LEN;
-}
-
-/*+
- *
- * Routine Description:
- * Decode Probe Request
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeProbeRequest(
- PWLAN_FR_PROBEREQ pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Information elements */
- pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)));
-
- while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
-
- switch (pItem->byElementID) {
- case WLAN_EID_SSID:
- if (pFrame->pSSID == NULL)
- pFrame->pSSID = (PWLAN_IE_SSID)pItem;
- break;
-
- case WLAN_EID_SUPP_RATES:
- if (pFrame->pSuppRates == NULL)
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- case WLAN_EID_EXTSUPP_RATES:
- if (pFrame->pExtSuppRates == NULL)
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
- break;
- }
-
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
- }
-}
-
-/*+
- *
- * Routine Description:
- * Encode Probe Response
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeProbeResponse(
- PWLAN_FR_PROBERESP pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pqwTimestamp =
- (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
- WLAN_PROBERESP_OFF_TS);
- pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_PROBERESP_OFF_BCN_INT);
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_PROBERESP_OFF_CAP_INFO);
-
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
- sizeof(*(pFrame->pwCapInfo));
-}
-
-/*+
- *
- * Routine Description:
- * Decode Probe Response
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeProbeResponse(
- PWLAN_FR_PROBERESP pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pqwTimestamp =
- (u64 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) +
- WLAN_PROBERESP_OFF_TS);
- pFrame->pwBeaconInterval = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_PROBERESP_OFF_BCN_INT);
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_PROBERESP_OFF_CAP_INFO);
-
- /* Information elements */
- pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_PROBERESP_OFF_SSID);
-
- while (((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) {
- switch (pItem->byElementID) {
- case WLAN_EID_SSID:
- if (pFrame->pSSID == NULL)
- pFrame->pSSID = (PWLAN_IE_SSID)pItem;
- break;
- case WLAN_EID_SUPP_RATES:
- if (pFrame->pSuppRates == NULL)
- pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
- case WLAN_EID_FH_PARMS:
- break;
- case WLAN_EID_DS_PARMS:
- if (pFrame->pDSParms == NULL)
- pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
- break;
- case WLAN_EID_CF_PARMS:
- if (pFrame->pCFParms == NULL)
- pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
- break;
- case WLAN_EID_IBSS_PARMS:
- if (pFrame->pIBSSParms == NULL)
- pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
- break;
-
- case WLAN_EID_RSN:
- if (pFrame->pRSN == NULL)
- pFrame->pRSN = (PWLAN_IE_RSN)pItem;
- break;
- case WLAN_EID_RSN_WPA:
- if (pFrame->pRSNWPA == NULL) {
- if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == true)
- pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
- }
- break;
- case WLAN_EID_ERP:
- if (pFrame->pERP == NULL)
- pFrame->pERP = (PWLAN_IE_ERP)pItem;
- break;
- case WLAN_EID_EXTSUPP_RATES:
- if (pFrame->pExtSuppRates == NULL)
- pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
- break;
-
- case WLAN_EID_COUNTRY: /* 7 */
- if (pFrame->pIE_Country == NULL)
- pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
- break;
-
- case WLAN_EID_PWR_CONSTRAINT: /* 32 */
- if (pFrame->pIE_PowerConstraint == NULL)
- pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
- break;
-
- case WLAN_EID_CH_SWITCH: /* 37 */
- if (pFrame->pIE_CHSW == NULL)
- pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
- break;
-
- case WLAN_EID_QUIET: /* 40 */
- if (pFrame->pIE_Quiet == NULL)
- pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
- break;
-
- case WLAN_EID_IBSS_DFS:
- if (pFrame->pIE_IBSSDFS == NULL)
- pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
- break;
- }
-
- pItem = (PWLAN_IE)(((u8 *)pItem) + 2 + pItem->len);
- }
-}
-
-/*+
- *
- * Routine Description:
- * Encode Authentication frame
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeAuthen(
- PWLAN_FR_AUTHEN pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_AUTH_ALG);
- pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_AUTH_SEQ);
- pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_STATUS);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
-}
-
-/*+
- *
- * Routine Description:
- * Decode Authentication
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeAuthen(
- PWLAN_FR_AUTHEN pFrame
- )
-{
- PWLAN_IE pItem;
-
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwAuthAlgorithm = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_AUTH_ALG);
- pFrame->pwAuthSequence = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_AUTH_SEQ);
- pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_STATUS);
-
- /* Information elements */
- pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_AUTHEN_OFF_CHALLENGE);
-
- if ((((u8 *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE))
- pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-}
-
-/*+
- *
- * Routine Description:
- * Encode Authentication
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeDeauthen(
- PWLAN_FR_DEAUTHEN pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_DEAUTHEN_OFF_REASON);
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
-}
-
-/*+
- *
- * Routine Description:
- * Decode Deauthentication
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrDecodeDeauthen(
- PWLAN_FR_DEAUTHEN pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwReason = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_DEAUTHEN_OFF_REASON);
-}
-
-/*+
- *
- * Routine Description: (AP)
- * Encode Reassociation Response
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void
-vMgrEncodeReassocResponse(
- PWLAN_FR_REASSOCRESP pFrame
- )
-{
- pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
-
- /* Fixed Fields */
- pFrame->pwCapInfo = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCRESP_OFF_CAP_INFO);
- pFrame->pwStatus = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCRESP_OFF_STATUS);
- pFrame->pwAid = (u16 *)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
- + WLAN_REASSOCRESP_OFF_AID);
-
- pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
-}
diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h
deleted file mode 100644
index 39cde1a0b66c..000000000000
--- a/drivers/staging/vt6656/80211mgr.h
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: 80211mgr.h
- *
- * Purpose: 802.11 management frames pre-defines.
- *
- *
- * Author: Lyndon Chen
- *
- * Date: May 8, 2002
- *
- */
-
-#ifndef __80211MGR_H__
-#define __80211MGR_H__
-
-#include "80211hdr.h"
-
-#define WLAN_MIN_ARRAY 1
-
-/* Information Element ID value */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARMS 2
-#define WLAN_EID_DS_PARMS 3
-#define WLAN_EID_CF_PARMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARMS 6
-#define WLAN_EID_COUNTRY 7
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_PWR_CONSTRAINT 32
-#define WLAN_EID_PWR_CAPABILITY 33
-#define WLAN_EID_TPC_REQ 34
-#define WLAN_EID_TPC_REP 35
-#define WLAN_EID_SUPP_CH 36
-#define WLAN_EID_CH_SWITCH 37
-#define WLAN_EID_MEASURE_REQ 38
-#define WLAN_EID_MEASURE_REP 39
-#define WLAN_EID_QUIET 40
-#define WLAN_EID_IBSS_DFS 41
-#define WLAN_EID_ERP 42
-/* reference 802.11i 7.3.2 table 20 */
-#define WLAN_EID_RSN 48
-#define WLAN_EID_EXTSUPP_RATES 50
-/* reference WiFi WPA spec */
-#define WLAN_EID_RSN_WPA 221
-
-#ifdef Cisco_ccx
-#define WLAN_EID_CCX 133
-#define WLAN_EID_CCX_IP 149
-#define WLAN_EID_CCX_Ver 221
-#endif
-
-#define WLAN_EID_ERP_NONERP_PRESENT 0x01
-#define WLAN_EID_ERP_USE_PROTECTION 0x02
-#define WLAN_EID_ERP_BARKER_MODE 0x04
-
-/* reason codes */
-#define WLAN_MGMT_REASON_RSVD 0
-#define WLAN_MGMT_REASON_UNSPEC 1
-#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
-#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
-#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
-#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
-#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
-#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
-#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
-#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
-#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT 10
-#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT 11
-#define WLAN_MGMT_REASON_INVALID_IE 13
-#define WLAN_MGMT_REASON_MIC_FAILURE 14
-#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT 15
-#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT 16
-#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT 17
-#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID 18
-#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID 19
-#define WLAN_MGMT_REASON_AKMP_INVALID 20
-#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED 21
-#define WLAN_MGMT_REASON_RSNE_CAP_INVALID 22
-#define WLAN_MGMT_REASON_80211X_AUTH_FAILED 23
-
-/* status codes */
-#define WLAN_MGMT_STATUS_SUCCESS 0
-#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
-#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
-#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
-#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
-#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
-#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
-#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE 19
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC 20
-#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY 21
-
-/* reference 802.11h 7.3.1.9 */
-#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG 22
-#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP 23
-#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH 24
-
-/* reference 802.11g 7.3.1.9 */
-#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED 25
-#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED 26
-
-/* reference 802.11i 7.3.1.9 table 19 */
-#define WLAN_MGMT_STATUS_INVALID_IE 40
-#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID 41
-#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID 42
-#define WLAN_MGMT_STATUS_AKMP_INVALID 43
-#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER 44
-#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP 45
-#define WLAN_MGMT_STATUS_CIPHER_REJECT 46
-
-/* auth algorithm */
-#define WLAN_AUTH_ALG_OPENSYSTEM 0
-#define WLAN_AUTH_ALG_SHAREDKEY 1
-
-/* management frame field offsets */
-
-/*
- * Note: Not all fields are listed because of variable lengths
- * Note: These offsets are from the start of the frame data
- */
-
-#define WLAN_BEACON_OFF_TS 0
-#define WLAN_BEACON_OFF_BCN_INT 8
-#define WLAN_BEACON_OFF_CAPINFO 10
-#define WLAN_BEACON_OFF_SSID 12
-
-#define WLAN_DISASSOC_OFF_REASON 0
-
-#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
-#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2
-#define WLAN_ASSOCREQ_OFF_SSID 4
-
-#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
-#define WLAN_ASSOCRESP_OFF_STATUS 2
-#define WLAN_ASSOCRESP_OFF_AID 4
-#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
-
-#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
-#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2
-#define WLAN_REASSOCREQ_OFF_CURR_AP 4
-#define WLAN_REASSOCREQ_OFF_SSID 10
-
-#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
-#define WLAN_REASSOCRESP_OFF_STATUS 2
-#define WLAN_REASSOCRESP_OFF_AID 4
-#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
-
-#define WLAN_PROBEREQ_OFF_SSID 0
-
-#define WLAN_PROBERESP_OFF_TS 0
-#define WLAN_PROBERESP_OFF_BCN_INT 8
-#define WLAN_PROBERESP_OFF_CAP_INFO 10
-#define WLAN_PROBERESP_OFF_SSID 12
-
-#define WLAN_AUTHEN_OFF_AUTH_ALG 0
-#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
-#define WLAN_AUTHEN_OFF_STATUS 4
-#define WLAN_AUTHEN_OFF_CHALLENGE 6
-
-#define WLAN_DEAUTHEN_OFF_REASON 0
-
-/* cipher suite selectors defined in 802.11i */
-#define WLAN_11i_CSS_USE_GROUP 0
-#define WLAN_11i_CSS_WEP40 1
-#define WLAN_11i_CSS_TKIP 2
-#define WLAN_11i_CSS_CCMP 4
-#define WLAN_11i_CSS_WEP104 5
-#define WLAN_11i_CSS_UNKNOWN 255
-
-/* authentication and key management suite selectors defined in 802.11i */
-#define WLAN_11i_AKMSS_802_1X 1
-#define WLAN_11i_AKMSS_PSK 2
-#define WLAN_11i_AKMSS_UNKNOWN 255
-
-/* measurement type definitions reference IEEE 802.11h table 20b */
-#define MEASURE_TYPE_BASIC 0
-#define MEASURE_TYPE_CCA 1
-#define MEASURE_TYPE_RPI 2
-
-/* measurement request mode definitions reference IEEE 802.11h figure 46h */
-#define MEASURE_MODE_ENABLE 0x02
-#define MEASURE_MODE_REQ 0x04
-#define MEASURE_MODE_REP 0x08
-
-/* measurement report mode definitions reference IEEE 802.11h figure 46m */
-#define MEASURE_MODE_LATE 0x01
-#define MEASURE_MODE_INCAPABLE 0x02
-#define MEASURE_MODE_REFUSED 0x04
-
-/* Information Element types */
-
-#pragma pack(1)
-typedef struct tagWLAN_IE {
- u8 byElementID;
- u8 len;
-} __attribute__ ((__packed__))
-WLAN_IE, *PWLAN_IE;
-
-/* Service Set IDentity (SSID) */
-#pragma pack(1)
-typedef struct tagWLAN_IE_SSID {
- u8 byElementID;
- u8 len;
- u8 abySSID[1];
-} __attribute__ ((__packed__))
-WLAN_IE_SSID, *PWLAN_IE_SSID;
-
-/* Supported Rates */
-#pragma pack(1)
-typedef struct tagWLAN_IE_SUPP_RATES {
- u8 byElementID;
- u8 len;
- u8 abyRates[1];
-} __attribute__ ((__packed__))
-WLAN_IE_SUPP_RATES, *PWLAN_IE_SUPP_RATES;
-
-/* FH Parameter Set */
-#pragma pack(1)
-typedef struct _WLAN_IE_FH_PARMS {
- u8 byElementID;
- u8 len;
- u16 wDwellTime;
- u8 byHopSet;
- u8 byHopPattern;
- u8 byHopIndex;
-} WLAN_IE_FH_PARMS, *PWLAN_IE_FH_PARMS;
-
-/* DS Parameter Set */
-#pragma pack(1)
-typedef struct tagWLAN_IE_DS_PARMS {
- u8 byElementID;
- u8 len;
- u8 byCurrChannel;
-} __attribute__ ((__packed__))
-WLAN_IE_DS_PARMS, *PWLAN_IE_DS_PARMS;
-
-/* CF Parameter Set */
-#pragma pack(1)
-typedef struct tagWLAN_IE_CF_PARMS {
- u8 byElementID;
- u8 len;
- u8 byCFPCount;
- u8 byCFPPeriod;
- u16 wCFPMaxDuration;
- u16 wCFPDurRemaining;
-} __attribute__ ((__packed__))
-WLAN_IE_CF_PARMS, *PWLAN_IE_CF_PARMS;
-
-/* TIM */
-#pragma pack(1)
-typedef struct tagWLAN_IE_TIM {
- u8 byElementID;
- u8 len;
- u8 byDTIMCount;
- u8 byDTIMPeriod;
- u8 byBitMapCtl;
- u8 byVirtBitMap[1];
-} __attribute__ ((__packed__))
-WLAN_IE_TIM, *PWLAN_IE_TIM;
-
-/* IBSS Parameter Set */
-#pragma pack(1)
-typedef struct tagWLAN_IE_IBSS_PARMS {
- u8 byElementID;
- u8 len;
- u16 wATIMWindow;
-} __attribute__ ((__packed__))
-WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
-
-/* Challenge Text */
-#pragma pack(1)
-typedef struct tagWLAN_IE_CHALLENGE {
- u8 byElementID;
- u8 len;
- u8 abyChallenge[1];
-} __attribute__ ((__packed__))
-WLAN_IE_CHALLENGE, *PWLAN_IE_CHALLENGE;
-
-#pragma pack(1)
-typedef struct tagWLAN_IE_RSN_EXT {
- u8 byElementID;
- u8 len;
- u8 abyOUI[4];
- u16 wVersion;
- u8 abyMulticast[4];
- u16 wPKCount;
- struct {
- u8 abyOUI[4];
- } PKSList[1];
- /* the rest is variable so need to overlay ieauth structure */
-} WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT;
-
-#pragma pack(1)
-typedef struct tagWLAN_IE_RSN_AUTH {
- u16 wAuthCount;
- struct {
- u8 abyOUI[4];
- } AuthKSList[1];
-} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH;
-
-/* RSN Identity */
-#pragma pack(1)
-typedef struct tagWLAN_IE_RSN {
- u8 byElementID;
- u8 len;
- u16 wVersion;
- u8 abyRSN[WLAN_MIN_ARRAY];
-} WLAN_IE_RSN, *PWLAN_IE_RSN;
-
-/* CCX Identity DavidWang */
-#pragma pack(1)
-typedef struct tagWLAN_IE_CCX {
-u8 byElementID;
-u8 len;
-u8 abyCCX[30];
-} WLAN_IE_CCX, *PWLAN_IE_CCX;
-#pragma pack(1)
-typedef struct tagWLAN_IE_CCX_IP {
-u8 byElementID;
-u8 len;
-u8 abyCCXOUI[4];
-u8 abyCCXIP[4];
-u8 abyCCXREV[2];
-} WLAN_IE_CCX_IP, *PWLAN_IE_CCX_IP;
-#pragma pack(1)
-typedef struct tagWLAN_IE_CCX_Ver {
-u8 byElementID;
-u8 len;
-u8 abyCCXVer[5];
-} WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver;
-
-/* ERP */
-#pragma pack(1)
-typedef struct tagWLAN_IE_ERP {
- u8 byElementID;
- u8 len;
- u8 byContext;
-} __attribute__ ((__packed__))
-WLAN_IE_ERP, *PWLAN_IE_ERP;
-
-#pragma pack(1)
-typedef struct _MEASEURE_REQ {
- u8 byChannel;
- u8 abyStartTime[8];
- u8 abyDuration[2];
-} MEASEURE_REQ, *PMEASEURE_REQ,
- MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC,
- MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA,
- MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI;
-
-typedef struct _MEASEURE_REP_BASIC {
- u8 byChannel;
- u8 abyStartTime[8];
- u8 abyDuration[2];
- u8 byMap;
-} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC;
-
-typedef struct _MEASEURE_REP_CCA {
- u8 byChannel;
- u8 abyStartTime[8];
- u8 abyDuration[2];
- u8 byCCABusyFraction;
-} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA;
-
-typedef struct _MEASEURE_REP_RPI {
- u8 byChannel;
- u8 abyStartTime[8];
- u8 abyDuration[2];
- u8 abyRPIdensity[8];
-} MEASEURE_REP_RPI, *PMEASEURE_REP_RPI;
-
-typedef union _MEASEURE_REP {
-
- MEASEURE_REP_BASIC sBasic;
- MEASEURE_REP_CCA sCCA;
- MEASEURE_REP_RPI sRPI;
-
-} MEASEURE_REP, *PMEASEURE_REP;
-
-typedef struct _WLAN_IE_MEASURE_REQ {
- u8 byElementID;
- u8 len;
- u8 byToken;
- u8 byMode;
- u8 byType;
- MEASEURE_REQ sReq;
-} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ;
-
-typedef struct _WLAN_IE_MEASURE_REP {
- u8 byElementID;
- u8 len;
- u8 byToken;
- u8 byMode;
- u8 byType;
- MEASEURE_REP sRep;
-} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP;
-
-typedef struct _WLAN_IE_CH_SW {
- u8 byElementID;
- u8 len;
- u8 byMode;
- u8 byChannel;
- u8 byCount;
-} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW;
-
-typedef struct _WLAN_IE_QUIET {
- u8 byElementID;
- u8 len;
- u8 byQuietCount;
- u8 byQuietPeriod;
- u8 abyQuietDuration[2];
- u8 abyQuietOffset[2];
-} WLAN_IE_QUIET, *PWLAN_IE_QUIET;
-
-typedef struct _WLAN_IE_COUNTRY {
- u8 byElementID;
- u8 len;
- u8 abyCountryString[3];
- u8 abyCountryInfo[3];
-} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY;
-
-typedef struct _WLAN_IE_PW_CONST {
- u8 byElementID;
- u8 len;
- u8 byPower;
-} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST;
-
-typedef struct _WLAN_IE_PW_CAP {
- u8 byElementID;
- u8 len;
- u8 byMinPower;
- u8 byMaxPower;
-} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP;
-
-typedef struct _WLAN_IE_SUPP_CH {
- u8 byElementID;
- u8 len;
- u8 abyChannelTuple[2];
-} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH;
-
-typedef struct _WLAN_IE_TPC_REQ {
- u8 byElementID;
- u8 len;
-} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ;
-
-typedef struct _WLAN_IE_TPC_REP {
- u8 byElementID;
- u8 len;
- u8 byTxPower;
- u8 byLinkMargin;
-} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP;
-
-typedef struct _WLAN_IE_IBSS_DFS {
- u8 byElementID;
- u8 len;
- u8 abyDFSOwner[6];
- u8 byDFSRecovery;
- u8 abyChannelMap[2];
-} WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS;
-
-#pragma pack()
-
-/* frame types */
-
-/* prototype structure, all mgmt frame types will start with these members */
-typedef struct tagWLAN_FR_MGMT {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
-
-} WLAN_FR_MGMT, *PWLAN_FR_MGMT;
-
-/* beacon frame */
-typedef struct tagWLAN_FR_BEACON {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u64 *pqwTimestamp;
- u16 * pwBeaconInterval;
- u16 * pwCapInfo;
- /* info elements */
- PWLAN_IE_SSID pSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
-/* PWLAN_IE_FH_PARMS pFHParms; */
- PWLAN_IE_DS_PARMS pDSParms;
- PWLAN_IE_CF_PARMS pCFParms;
- PWLAN_IE_TIM pTIM;
- PWLAN_IE_IBSS_PARMS pIBSSParms;
- PWLAN_IE_RSN pRSN;
- PWLAN_IE_RSN_EXT pRSNWPA;
- PWLAN_IE_ERP pERP;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
- PWLAN_IE_COUNTRY pIE_Country;
- PWLAN_IE_PW_CONST pIE_PowerConstraint;
- PWLAN_IE_CH_SW pIE_CHSW;
- PWLAN_IE_IBSS_DFS pIE_IBSSDFS;
- PWLAN_IE_QUIET pIE_Quiet;
-
-} WLAN_FR_BEACON, *PWLAN_FR_BEACON;
-
-/* IBSS ATIM frame */
-typedef struct tagWLAN_FR_IBSSATIM {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
-
- /* fixed fields */
- /* info elements */
- /* this frame type has a null body */
-
-} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM;
-
-/* disassociation */
-typedef struct tagWLAN_FR_DISASSOC {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwReason;
- /* info elements */
-
-} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
-
-/* association request */
-typedef struct tagWLAN_FR_ASSOCREQ {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwCapInfo;
- u16 * pwListenInterval;
- /* info elements */
- PWLAN_IE_SSID pSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_RSN pRSN;
- PWLAN_IE_CCX pCCX;
- PWLAN_IE_CCX_IP pCCXIP;
- PWLAN_IE_CCX_Ver pCCXVER;
- PWLAN_IE_RSN_EXT pRSNWPA;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
- PWLAN_IE_PW_CAP pCurrPowerCap;
- PWLAN_IE_SUPP_CH pCurrSuppCh;
-
-} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ;
-
-/* association response */
-typedef struct tagWLAN_FR_ASSOCRESP {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwCapInfo;
- u16 * pwStatus;
- u16 * pwAid;
- /* info elements */
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
-
-} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP;
-
-/* reassociation request */
-typedef struct tagWLAN_FR_REASSOCREQ {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
-
- /* fixed fields */
- u16 * pwCapInfo;
- u16 * pwListenInterval;
- PIEEE_ADDR pAddrCurrAP;
-
- /* info elements */
- PWLAN_IE_SSID pSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_RSN pRSN;
- PWLAN_IE_CCX pCCX;
- PWLAN_IE_CCX_IP pCCXIP;
- PWLAN_IE_CCX_Ver pCCXVER;
- PWLAN_IE_RSN_EXT pRSNWPA;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
-
-} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ;
-
-/* reassociation response */
-typedef struct tagWLAN_FR_REASSOCRESP {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwCapInfo;
- u16 * pwStatus;
- u16 * pwAid;
- /* info elements */
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
-
-} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP;
-
-/* probe request */
-typedef struct tagWLAN_FR_PROBEREQ {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- /* info elements */
- PWLAN_IE_SSID pSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
-
-} WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ;
-
-/* probe response */
-typedef struct tagWLAN_FR_PROBERESP {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u64 *pqwTimestamp;
- u16 * pwBeaconInterval;
- u16 * pwCapInfo;
- /* info elements */
- PWLAN_IE_SSID pSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_DS_PARMS pDSParms;
- PWLAN_IE_CF_PARMS pCFParms;
- PWLAN_IE_IBSS_PARMS pIBSSParms;
- PWLAN_IE_RSN pRSN;
- PWLAN_IE_RSN_EXT pRSNWPA;
- PWLAN_IE_ERP pERP;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
- PWLAN_IE_COUNTRY pIE_Country;
- PWLAN_IE_PW_CONST pIE_PowerConstraint;
- PWLAN_IE_CH_SW pIE_CHSW;
- PWLAN_IE_IBSS_DFS pIE_IBSSDFS;
- PWLAN_IE_QUIET pIE_Quiet;
-
-} WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP;
-
-/* authentication */
-typedef struct tagWLAN_FR_AUTHEN {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwAuthAlgorithm;
- u16 * pwAuthSequence;
- u16 * pwStatus;
- /* info elements */
- PWLAN_IE_CHALLENGE pChallenge;
-
-} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN;
-
-/* deauthentication */
-typedef struct tagWLAN_FR_DEAUTHEN {
-
- unsigned int uType;
- unsigned int len;
- u8 * pBuf;
- PUWLAN_80211HDR pHdr;
- /* fixed fields */
- u16 * pwReason;
-
- /* info elements */
-
-} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
-
-void
-vMgrEncodeBeacon(
- PWLAN_FR_BEACON pFrame
- );
-
-void
-vMgrDecodeBeacon(
- PWLAN_FR_BEACON pFrame
- );
-
-void
-vMgrEncodeDisassociation(
- PWLAN_FR_DISASSOC pFrame
- );
-
-void
-vMgrDecodeDisassociation(
- PWLAN_FR_DISASSOC pFrame
- );
-
-void
-vMgrEncodeAssocRequest(
- PWLAN_FR_ASSOCREQ pFrame
- );
-
-void
-vMgrDecodeAssocRequest(
- PWLAN_FR_ASSOCREQ pFrame
- );
-
-void
-vMgrEncodeAssocResponse(
- PWLAN_FR_ASSOCRESP pFrame
- );
-
-void
-vMgrDecodeAssocResponse(
- PWLAN_FR_ASSOCRESP pFrame
- );
-
-void
-vMgrEncodeReassocRequest(
- PWLAN_FR_REASSOCREQ pFrame
- );
-
-void
-vMgrDecodeReassocRequest(
- PWLAN_FR_REASSOCREQ pFrame
- );
-
-void
-vMgrEncodeProbeRequest(
- PWLAN_FR_PROBEREQ pFrame
- );
-
-void
-vMgrDecodeProbeRequest(
- PWLAN_FR_PROBEREQ pFrame
- );
-
-void
-vMgrEncodeProbeResponse(
- PWLAN_FR_PROBERESP pFrame
- );
-
-void
-vMgrDecodeProbeResponse(
- PWLAN_FR_PROBERESP pFrame
- );
-
-void
-vMgrEncodeAuthen(
- PWLAN_FR_AUTHEN pFrame
- );
-
-void
-vMgrDecodeAuthen(
- PWLAN_FR_AUTHEN pFrame
- );
-
-void
-vMgrEncodeDeauthen(
- PWLAN_FR_DEAUTHEN pFrame
- );
-
-void
-vMgrDecodeDeauthen(
- PWLAN_FR_DEAUTHEN pFrame
- );
-
-void
-vMgrEncodeReassocResponse(
- PWLAN_FR_REASSOCRESP pFrame
- );
-
-#endif /* __80211MGR_H__ */
diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig
index f89ab205c8e0..b602ef175d55 100644
--- a/drivers/staging/vt6656/Kconfig
+++ b/drivers/staging/vt6656/Kconfig
@@ -1,8 +1,6 @@
config VT6656
tristate "VIA Technologies VT6656 support"
- depends on USB && WLAN && m
- select WIRELESS_EXT
- select WEXT_PRIV
+ depends on MAC80211 && USB && WLAN && m
select FW_LOADER
---help---
This is a vendor-written driver for VIA VT6656.
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile
index b5ec483f3eb4..3dbe1f89dd25 100644
--- a/drivers/staging/vt6656/Makefile
+++ b/drivers/staging/vt6656/Makefile
@@ -6,25 +6,12 @@ vt6656_stage-y += main_usb.o \
card.o \
mac.o \
baseband.o \
- wctl.o \
- 80211mgr.o \
wcmd.o\
- wmgr.o \
- bssdb.o \
- wpa2.o \
rxtx.o \
dpc.o \
power.o \
- datarate.o \
- rc4.o \
- tether.o \
- wpa.o \
key.o \
- tkip.o \
- michael.o \
rf.o \
- iwctl.o \
- wpactl.o \
usbpipe.o \
channel.o \
firmware.o \
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
index 694e34a5ff90..e6c7b604ede9 100644
--- a/drivers/staging/vt6656/baseband.c
+++ b/drivers/staging/vt6656/baseband.c
@@ -26,611 +26,106 @@
* Date: Jun. 5, 2002
*
* Functions:
- * BBuGetFrameTime - Calculate data frame transmitting time
- * BBvCalculateParameter - Calculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
- * BBbVT3184Init - VIA VT3184 baseband chip init code
+ * vnt_get_frame_time - Calculate data frame transmitting time
+ * vnt_get_phy_field - Calculate PhyLength, PhyService and Phy
+ * Signal parameter for baseband Tx
+ * vnt_vt3184_init - VIA VT3184 baseband chip init code
*
* Revision History:
*
*
*/
-#include "tmacro.h"
-#include "tether.h"
#include "mac.h"
#include "baseband.h"
#include "rf.h"
#include "usbpipe.h"
-#include "datarate.h"
-
-static u8 abyVT3184_AGC[] = {
- 0x00, //0
- 0x00, //1
- 0x02, //2
- 0x02, //3 //RobertYu:20060505, 0x04, //3
- 0x04, //4
- 0x04, //5 //RobertYu:20060505, 0x06, //5
- 0x06, //6
- 0x06, //7
- 0x08, //8
- 0x08, //9
- 0x0A, //A
- 0x0A, //B
- 0x0C, //C
- 0x0C, //D
- 0x0E, //E
- 0x0E, //F
- 0x10, //10
- 0x10, //11
- 0x12, //12
- 0x12, //13
- 0x14, //14
- 0x14, //15
- 0x16, //16
- 0x16, //17
- 0x18, //18
- 0x18, //19
- 0x1A, //1A
- 0x1A, //1B
- 0x1C, //1C
- 0x1C, //1D
- 0x1E, //1E
- 0x1E, //1F
- 0x20, //20
- 0x20, //21
- 0x22, //22
- 0x22, //23
- 0x24, //24
- 0x24, //25
- 0x26, //26
- 0x26, //27
- 0x28, //28
- 0x28, //29
- 0x2A, //2A
- 0x2A, //2B
- 0x2C, //2C
- 0x2C, //2D
- 0x2E, //2E
- 0x2E, //2F
- 0x30, //30
- 0x30, //31
- 0x32, //32
- 0x32, //33
- 0x34, //34
- 0x34, //35
- 0x36, //36
- 0x36, //37
- 0x38, //38
- 0x38, //39
- 0x3A, //3A
- 0x3A, //3B
- 0x3C, //3C
- 0x3C, //3D
- 0x3E, //3E
- 0x3E //3F
+
+static u8 vnt_vt3184_agc[] = {
+ 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x06, 0x06,
+ 0x08, 0x08, 0x0a, 0x0a, 0x0c, 0x0c, 0x0e, 0x0e, /* 0x0f */
+ 0x10, 0x10, 0x12, 0x12, 0x14, 0x14, 0x16, 0x16,
+ 0x18, 0x18, 0x1a, 0x1a, 0x1c, 0x1c, 0x1e, 0x1e, /* 0x1f */
+ 0x20, 0x20, 0x22, 0x22, 0x24, 0x24, 0x26, 0x26,
+ 0x28, 0x28, 0x2a, 0x2a, 0x2c, 0x2c, 0x2e, 0x2e, /* 0x2f */
+ 0x30, 0x30, 0x32, 0x32, 0x34, 0x34, 0x36, 0x36,
+ 0x38, 0x38, 0x3a, 0x3a, 0x3c, 0x3c, 0x3e, 0x3e /* 0x3f */
};
-static u8 abyVT3184_AL2230[] = {
- 0x31,//00
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x80,
- 0x00,
- 0x00,
- 0x70,
- 0x45,//tx //0x64 for FPGA
- 0x2A,
- 0x76,
- 0x00,
- 0x00,
- 0x80,
- 0x00,
- 0x00,//10
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x8e, //RobertYu:20060522, //0x8d,
- 0x0a, //RobertYu:20060515, //0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,//20
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x4a,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x4a,
- 0x00,
- 0x0c, //RobertYu:20060522, //0x10,
- 0x26,//30
- 0x5b,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xaa,
- 0xaa,
- 0xff,
- 0xff,
- 0x79,
- 0x00,
- 0x00,
- 0x0b,
- 0x48,
- 0x04,
- 0x00,//40
- 0x08,
- 0x00,
- 0x08,
- 0x08,
- 0x14,
- 0x05,
- 0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x09,
- 0x73,
- 0x00,
- 0xc5,
- 0x00,//50 //RobertYu:20060505, //0x15,//50
- 0x19,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xd0, //RobertYu:20060505, //0xb0,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xe4,//60
- 0x80,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x98,
- 0x0a,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00, //0x80 for FPGA
- 0x03,
- 0x01,
- 0x00,
- 0x00,//70
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x8c,//80
- 0x01,
- 0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x08,
- 0x00,
- 0x1f, //RobertYu:20060516, //0x0f,
- 0xb7,
- 0x88,
- 0x47,
- 0xaa,
- 0x00, //RobertYu:20060505, //0x02,
- 0x20,//90 //RobertYu:20060505, //0x22,//90
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xeb,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x01,
- 0x00,//a0
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x10,
- 0x00,
- 0x18,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x15, //RobertYu:20060516, //0x00,
- 0x00,
- 0x18,
- 0x38,//b0
- 0x30,
- 0x00,
- 0x00,
- 0xff,
- 0x0f,
- 0xe4,
- 0xe2,
- 0x00,
- 0x00,
- 0x00,
- 0x03,
- 0x01,
- 0x00,
- 0x00,
- 0x00,
- 0x18,//c0
- 0x20,
- 0x07,
- 0x18,
- 0xff,
- 0xff, //RobertYu:20060509, //0x2c,
- 0x0e, //RobertYu:20060530, //0x0c,
- 0x0a,
- 0x0e,
- 0x00, //RobertYu:20060505, //0x01,
- 0x82, //RobertYu:20060516, //0x8f,
- 0xa7,
- 0x3c,
- 0x10,
- 0x30, //RobertYu:20060627, //0x0b,
- 0x05, //RobertYu:20060516, //0x25,
- 0x40,//d0
- 0x12,
- 0x00,
- 0x00,
- 0x10,
- 0x28,
- 0x80,
- 0x2A,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,//e0
- 0xf3, //RobertYu:20060516, //0xd3,
- 0x00,
- 0x00,
- 0x00,
- 0x10,
- 0x00,
- 0x12, //RobertYu:20060627, //0x10,
- 0x00,
- 0xf4,
- 0x00,
- 0xff,
- 0x79,
- 0x20,
- 0x30,
- 0x05, //RobertYu:20060516, //0x0c,
- 0x00,//f0
- 0x3e,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00
+static u8 vnt_vt3184_al2230[] = {
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
+ 0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+ 0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
+ 0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
+ 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
+ 0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
+ 0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x18, /* 0xaf */
+ 0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
+ 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
+ 0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x0e, 0x0a,
+ 0x0e, 0x00, 0x82, 0xa7, 0x3c, 0x10, 0x30, 0x05, /* 0xcf */
+ 0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
+ 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x12,
+ 0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x05, /* 0xef */
+ 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xff */
};
-//{{RobertYu:20060515, new BB setting for VT3226D0
-static u8 abyVT3184_VT3226D0[] = {
- 0x31,//00
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x80,
- 0x00,
- 0x00,
- 0x70,
- 0x45,//tx //0x64 for FPGA
- 0x2A,
- 0x76,
- 0x00,
- 0x00,
- 0x80,
- 0x00,
- 0x00,//10
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x8e, //RobertYu:20060525, //0x8d,
- 0x0a, //RobertYu:20060515, //0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,//20
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x4a,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x4a,
- 0x00,
- 0x0c, //RobertYu:20060525, //0x10,
- 0x26,//30
- 0x5b,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xaa,
- 0xaa,
- 0xff,
- 0xff,
- 0x79,
- 0x00,
- 0x00,
- 0x0b,
- 0x48,
- 0x04,
- 0x00,//40
- 0x08,
- 0x00,
- 0x08,
- 0x08,
- 0x14,
- 0x05,
- 0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x09,
- 0x73,
- 0x00,
- 0xc5,
- 0x00,//50 //RobertYu:20060505, //0x15,//50
- 0x19,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xd0, //RobertYu:20060505, //0xb0,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xe4,//60
- 0x80,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x98,
- 0x0a,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00, //0x80 for FPGA
- 0x03,
- 0x01,
- 0x00,
- 0x00,//70
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x8c,//80
- 0x01,
- 0x09,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x08,
- 0x00,
- 0x1f, //RobertYu:20060515, //0x0f,
- 0xb7,
- 0x88,
- 0x47,
- 0xaa,
- 0x00, //RobertYu:20060505, //0x02,
- 0x20,//90 //RobertYu:20060505, //0x22,//90
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0xeb,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x01,
- 0x00,//a0
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x10,
- 0x00,
- 0x18,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x18,
- 0x38,//b0
- 0x30,
- 0x00,
- 0x00,
- 0xff,
- 0x0f,
- 0xe4,
- 0xe2,
- 0x00,
- 0x00,
- 0x00,
- 0x03,
- 0x01,
- 0x00,
- 0x00,
- 0x00,
- 0x18,//c0
- 0x20,
- 0x07,
- 0x18,
- 0xff,
- 0xff, //RobertYu:20060509, //0x2c,
- 0x10, //RobertYu:20060525, //0x0c,
- 0x0a,
- 0x0e,
- 0x00, //RobertYu:20060505, //0x01,
- 0x84, //RobertYu:20060525, //0x8f,
- 0xa7,
- 0x3c,
- 0x10,
- 0x24, //RobertYu:20060627, //0x18,
- 0x05, //RobertYu:20060515, //0x25,
- 0x40,//d0
- 0x12,
- 0x00,
- 0x00,
- 0x10,
- 0x28,
- 0x80,
- 0x2A,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,//e0
- 0xf3, //RobertYu:20060515, //0xd3,
- 0x00,
- 0x00,
- 0x00,
- 0x10,
- 0x00,
- 0x10, //RobertYu:20060627, //0x0e,
- 0x00,
- 0xf4,
- 0x00,
- 0xff,
- 0x79,
- 0x20,
- 0x30,
- 0x08, //RobertYu:20060515, //0x0c,
- 0x00,//f0
- 0x3e,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
+/* {{RobertYu:20060515, new BB setting for VT3226D0 */
+static u8 vnt_vt3184_vt3226d0[] = {
+ 0x31, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x70, 0x45, 0x2a, 0x76, 0x00, 0x00, 0x80, 0x00, /* 0x0f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8e, 0x0a, 0x00, 0x00, 0x00, /* 0x1f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x0c, /* 0x2f */
+ 0x26, 0x5b, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+ 0xff, 0xff, 0x79, 0x00, 0x00, 0x0b, 0x48, 0x04, /* 0x3f */
+ 0x00, 0x08, 0x00, 0x08, 0x08, 0x14, 0x05, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x09, 0x73, 0x00, 0xc5, /* 0x4f */
+ 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f */
+ 0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* 0x6f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7f */
+ 0x8c, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x00, 0x1f, 0xb7, 0x88, 0x47, 0xaa, 0x00, /* 0x8f */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9f */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0xaf */
+ 0x38, 0x30, 0x00, 0x00, 0xff, 0x0f, 0xe4, 0xe2,
+ 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, /* 0xbf */
+ 0x18, 0x20, 0x07, 0x18, 0xff, 0xff, 0x10, 0x0a,
+ 0x0e, 0x00, 0x84, 0xa7, 0x3c, 0x10, 0x24, 0x05, /* 0xcf */
+ 0x40, 0x12, 0x00, 0x00, 0x10, 0x28, 0x80, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf */
+ 0x00, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10,
+ 0x00, 0xf4, 0x00, 0xff, 0x79, 0x20, 0x30, 0x08, /* 0xef */
+ 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0xff */
};
-static const u16 awcFrameTime[MAX_RATE] =
-{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
+static const u16 vnt_frame_time[MAX_RATE] = {
+ 10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
+};
/*
* Description: Calculate data frame transmitting time
@@ -646,7 +141,7 @@ static const u16 awcFrameTime[MAX_RATE] =
* Return Value: FrameTime
*
*/
-unsigned int BBuGetFrameTime(u8 preamble_type, u8 pkt_type,
+unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
unsigned int frame_length, u16 tx_rate)
{
unsigned int frame_time;
@@ -657,7 +152,7 @@ unsigned int BBuGetFrameTime(u8 preamble_type, u8 pkt_type,
if (tx_rate > RATE_54M)
return 0;
- rate = (unsigned int)awcFrameTime[tx_rate];
+ rate = (unsigned int)vnt_frame_time[tx_rate];
if (tx_rate <= 3) {
if (preamble_type == 1)
@@ -698,21 +193,21 @@ unsigned int BBuGetFrameTime(u8 preamble_type, u8 pkt_type,
* tx_rate - Tx Rate
* Out:
* struct vnt_phy_field *phy
- * - pointer to Phy Length field
- * - pointer to Phy Service field
- * - pointer to Phy Signal field
+ * - pointer to Phy Length field
+ * - pointer to Phy Service field
+ * - pointer to Phy Signal field
*
* Return Value: none
*
*/
-void BBvCalculateParameter(struct vnt_private *priv, u32 frame_length,
+void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length,
u16 tx_rate, u8 pkt_type, struct vnt_phy_field *phy)
{
u32 bit_count;
u32 count = 0;
u32 tmp;
int ext_bit;
- u8 preamble_type = priv->byPreambleType;
+ u8 preamble_type = priv->preamble_type;
bit_count = frame_length * 8;
ext_bit = false;
@@ -850,18 +345,18 @@ void BBvCalculateParameter(struct vnt_private *priv, u32 frame_length,
* Return Value: none
*
*/
-void BBvSetAntennaMode(struct vnt_private *priv, u8 antenna_mode)
+void vnt_set_antenna_mode(struct vnt_private *priv, u8 antenna_mode)
{
switch (antenna_mode) {
case ANT_TXA:
case ANT_TXB:
break;
case ANT_RXA:
- priv->byBBRxConf &= 0xFC;
+ priv->bb_rx_conf &= 0xFC;
break;
case ANT_RXB:
- priv->byBBRxConf &= 0xFE;
- priv->byBBRxConf |= 0x02;
+ priv->bb_rx_conf &= 0xFE;
+ priv->bb_rx_conf |= 0x02;
break;
}
@@ -883,7 +378,7 @@ void BBvSetAntennaMode(struct vnt_private *priv, u8 antenna_mode)
*
*/
-int BBbVT3184Init(struct vnt_private *priv)
+int vnt_vt3184_init(struct vnt_private *priv)
{
int status;
u16 length;
@@ -895,123 +390,72 @@ int BBbVT3184Init(struct vnt_private *priv)
status = vnt_control_in(priv, MESSAGE_TYPE_READ, 0,
MESSAGE_REQUEST_EEPROM, EEP_MAX_CONTEXT_SIZE,
- priv->abyEEPROM);
+ priv->eeprom);
if (status != STATUS_SUCCESS)
return false;
- /* zonetype initial */
- priv->byOriginalZonetype = priv->abyEEPROM[EEP_OFS_ZONETYPE];
-
- if (priv->config_file.ZoneType >= 0) {
- if ((priv->config_file.ZoneType == 0) &&
- (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x00)) {
- priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
- priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+ priv->rf_type = priv->eeprom[EEP_OFS_RFTYPE];
- dev_dbg(&priv->usb->dev, "Init Zone Type :USA\n");
- } else if ((priv->config_file.ZoneType == 1) &&
- (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) {
- priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
- priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+ dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->rf_type);
- dev_dbg(&priv->usb->dev, "Init Zone Type :Japan\n");
- } else if ((priv->config_file.ZoneType == 2) &&
- (priv->abyEEPROM[EEP_OFS_ZONETYPE] != 0x02)) {
- priv->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
- priv->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+ if ((priv->rf_type == RF_AL2230) ||
+ (priv->rf_type == RF_AL2230S)) {
+ priv->bb_rx_conf = vnt_vt3184_al2230[10];
+ length = sizeof(vnt_vt3184_al2230);
+ addr = vnt_vt3184_al2230;
+ agc = vnt_vt3184_agc;
+ length_agc = sizeof(vnt_vt3184_agc);
- dev_dbg(&priv->usb->dev, "Init Zone Type :Europe\n");
- } else {
- if (priv->config_file.ZoneType !=
- priv->abyEEPROM[EEP_OFS_ZONETYPE])
- printk("zonetype in file[%02x]\
- mismatch with in EEPROM[%02x]\n",
- priv->config_file.ZoneType,
- priv->abyEEPROM[EEP_OFS_ZONETYPE]);
- else
- printk("Read Zonetype file success,\
- use default zonetype setting[%02x]\n",
- priv->config_file.ZoneType);
- }
- }
+ priv->bb_vga[0] = 0x1C;
+ priv->bb_vga[1] = 0x10;
+ priv->bb_vga[2] = 0x0;
+ priv->bb_vga[3] = 0x0;
- if (!priv->bZoneRegExist)
- priv->byZoneType = priv->abyEEPROM[EEP_OFS_ZONETYPE];
-
- priv->byRFType = priv->abyEEPROM[EEP_OFS_RFTYPE];
-
- dev_dbg(&priv->usb->dev, "Zone Type %x\n", priv->byZoneType);
-
- dev_dbg(&priv->usb->dev, "RF Type %d\n", priv->byRFType);
-
- if ((priv->byRFType == RF_AL2230) ||
- (priv->byRFType == RF_AL2230S)) {
- priv->byBBRxConf = abyVT3184_AL2230[10];
- length = sizeof(abyVT3184_AL2230);
- addr = abyVT3184_AL2230;
- agc = abyVT3184_AGC;
- length_agc = sizeof(abyVT3184_AGC);
-
- priv->abyBBVGA[0] = 0x1C;
- priv->abyBBVGA[1] = 0x10;
- priv->abyBBVGA[2] = 0x0;
- priv->abyBBVGA[3] = 0x0;
- priv->ldBmThreshold[0] = -70;
- priv->ldBmThreshold[1] = -48;
- priv->ldBmThreshold[2] = 0;
- priv->ldBmThreshold[3] = 0;
- } else if (priv->byRFType == RF_AIROHA7230) {
- priv->byBBRxConf = abyVT3184_AL2230[10];
- length = sizeof(abyVT3184_AL2230);
- addr = abyVT3184_AL2230;
- agc = abyVT3184_AGC;
- length_agc = sizeof(abyVT3184_AGC);
+ } else if (priv->rf_type == RF_AIROHA7230) {
+ priv->bb_rx_conf = vnt_vt3184_al2230[10];
+ length = sizeof(vnt_vt3184_al2230);
+ addr = vnt_vt3184_al2230;
+ agc = vnt_vt3184_agc;
+ length_agc = sizeof(vnt_vt3184_agc);
addr[0xd7] = 0x06;
- priv->abyBBVGA[0] = 0x1c;
- priv->abyBBVGA[1] = 0x10;
- priv->abyBBVGA[2] = 0x0;
- priv->abyBBVGA[3] = 0x0;
- priv->ldBmThreshold[0] = -70;
- priv->ldBmThreshold[1] = -48;
- priv->ldBmThreshold[2] = 0;
- priv->ldBmThreshold[3] = 0;
- } else if ((priv->byRFType == RF_VT3226) ||
- (priv->byRFType == RF_VT3226D0)) {
- priv->byBBRxConf = abyVT3184_VT3226D0[10];
- length = sizeof(abyVT3184_VT3226D0);
- addr = abyVT3184_VT3226D0;
- agc = abyVT3184_AGC;
- length_agc = sizeof(abyVT3184_AGC);
-
- priv->abyBBVGA[0] = 0x20;
- priv->abyBBVGA[1] = 0x10;
- priv->abyBBVGA[2] = 0x0;
- priv->abyBBVGA[3] = 0x0;
- priv->ldBmThreshold[0] = -70;
- priv->ldBmThreshold[1] = -48;
- priv->ldBmThreshold[2] = 0;
- priv->ldBmThreshold[3] = 0;
+ priv->bb_vga[0] = 0x1c;
+ priv->bb_vga[1] = 0x10;
+ priv->bb_vga[2] = 0x0;
+ priv->bb_vga[3] = 0x0;
+
+ } else if ((priv->rf_type == RF_VT3226) ||
+ (priv->rf_type == RF_VT3226D0)) {
+ priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
+ length = sizeof(vnt_vt3184_vt3226d0);
+ addr = vnt_vt3184_vt3226d0;
+ agc = vnt_vt3184_agc;
+ length_agc = sizeof(vnt_vt3184_agc);
+
+ priv->bb_vga[0] = 0x20;
+ priv->bb_vga[1] = 0x10;
+ priv->bb_vga[2] = 0x0;
+ priv->bb_vga[3] = 0x0;
+
/* Fix VT3226 DFC system timing issue */
- MACvRegBitsOn(priv, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
- } else if ((priv->byRFType == RF_VT3342A0)) {
- priv->byBBRxConf = abyVT3184_VT3226D0[10];
- length = sizeof(abyVT3184_VT3226D0);
- addr = abyVT3184_VT3226D0;
- agc = abyVT3184_AGC;
- length_agc = sizeof(abyVT3184_AGC);
-
- priv->abyBBVGA[0] = 0x20;
- priv->abyBBVGA[1] = 0x10;
- priv->abyBBVGA[2] = 0x0;
- priv->abyBBVGA[3] = 0x0;
- priv->ldBmThreshold[0] = -70;
- priv->ldBmThreshold[1] = -48;
- priv->ldBmThreshold[2] = 0;
- priv->ldBmThreshold[3] = 0;
+ vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
+ SOFTPWRCTL_RFLEOPT);
+ } else if (priv->rf_type == RF_VT3342A0) {
+ priv->bb_rx_conf = vnt_vt3184_vt3226d0[10];
+ length = sizeof(vnt_vt3184_vt3226d0);
+ addr = vnt_vt3184_vt3226d0;
+ agc = vnt_vt3184_agc;
+ length_agc = sizeof(vnt_vt3184_agc);
+
+ priv->bb_vga[0] = 0x20;
+ priv->bb_vga[1] = 0x10;
+ priv->bb_vga[2] = 0x0;
+ priv->bb_vga[3] = 0x0;
+
/* Fix VT3226 DFC system timing issue */
- MACvRegBitsOn(priv, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+ vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL2,
+ SOFTPWRCTL_RFLEOPT);
} else {
return true;
}
@@ -1026,15 +470,15 @@ int BBbVT3184Init(struct vnt_private *priv)
vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
MESSAGE_REQUEST_BBAGC, length_agc, array);
- if ((priv->byRFType == RF_VT3226) ||
- (priv->byRFType == RF_VT3342A0)) {
+ if ((priv->rf_type == RF_VT3226) ||
+ (priv->rf_type == RF_VT3342A0)) {
vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
MAC_REG_ITRTMSET, 0x23);
- MACvRegBitsOn(priv, MAC_REG_PAPEDELAY, 0x01);
- } else if (priv->byRFType == RF_VT3226D0) {
+ vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, 0x01);
+ } else if (priv->rf_type == RF_VT3226D0) {
vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
MAC_REG_ITRTMSET, 0x11);
- MACvRegBitsOn(priv, MAC_REG_PAPEDELAY, 0x01);
+ vnt_mac_reg_bits_on(priv, MAC_REG_PAPEDELAY, 0x01);
}
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x04, 0x7f);
@@ -1066,39 +510,39 @@ int BBbVT3184Init(struct vnt_private *priv)
* Return Value: none
*
*/
-void BBvSetShortSlotTime(struct vnt_private *priv)
+void vnt_set_short_slot_time(struct vnt_private *priv)
{
u8 bb_vga = 0;
- if (priv->bShortSlotTime)
- priv->byBBRxConf &= 0xdf;
+ if (priv->short_slot_time)
+ priv->bb_rx_conf &= 0xdf;
else
- priv->byBBRxConf |= 0x20;
+ priv->bb_rx_conf |= 0x20;
vnt_control_in_u8(priv, MESSAGE_REQUEST_BBREG, 0xe7, &bb_vga);
- if (bb_vga == priv->abyBBVGA[0])
- priv->byBBRxConf |= 0x20;
+ if (bb_vga == priv->bb_vga[0])
+ priv->bb_rx_conf |= 0x20;
- vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->byBBRxConf);
+ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->bb_rx_conf);
}
-void BBvSetVGAGainOffset(struct vnt_private *priv, u8 data)
+void vnt_set_vga_gain_offset(struct vnt_private *priv, u8 data)
{
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0xE7, data);
/* patch for 3253B0 Baseband with Cardbus module */
- if (priv->bShortSlotTime)
- priv->byBBRxConf &= 0xdf; /* 1101 1111 */
+ if (priv->short_slot_time)
+ priv->bb_rx_conf &= 0xdf; /* 1101 1111 */
else
- priv->byBBRxConf |= 0x20; /* 0010 0000 */
+ priv->bb_rx_conf |= 0x20; /* 0010 0000 */
- vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->byBBRxConf);
+ vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0a, priv->bb_rx_conf);
}
/*
- * Description: BBvSetDeepSleep
+ * Description: vnt_set_deep_sleep
*
* Parameters:
* In:
@@ -1109,24 +553,24 @@ void BBvSetVGAGainOffset(struct vnt_private *priv, u8 data)
* Return Value: none
*
*/
-void BBvSetDeepSleep(struct vnt_private *priv)
+void vnt_set_deep_sleep(struct vnt_private *priv)
{
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);/* CR12 */
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0xB9);/* CR13 */
}
-void BBvExitDeepSleep(struct vnt_private *priv)
+void vnt_exit_deep_sleep(struct vnt_private *priv)
{
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0c, 0x00);/* CR12 */
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x0d, 0x01);/* CR13 */
}
-void BBvUpdatePreEDThreshold(struct vnt_private *priv, int scanning)
+void vnt_update_pre_ed_threshold(struct vnt_private *priv, int scanning)
{
u8 cr_201 = 0x0, cr_206 = 0x0;
- u8 ed_inx = priv->byBBPreEDIndex;
+ u8 ed_inx = priv->bb_pre_ed_index;
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
case RF_AL2230S:
case RF_AIROHA7230:
@@ -1136,69 +580,69 @@ void BBvUpdatePreEDThreshold(struct vnt_private *priv, int scanning)
break;
}
- if (priv->byBBPreEDRSSI <= 45) {
+ if (priv->bb_pre_ed_rssi <= 45) {
ed_inx = 20;
cr_201 = 0xff;
- } else if (priv->byBBPreEDRSSI <= 46) {
+ } else if (priv->bb_pre_ed_rssi <= 46) {
ed_inx = 19;
cr_201 = 0x1a;
- } else if (priv->byBBPreEDRSSI <= 47) {
+ } else if (priv->bb_pre_ed_rssi <= 47) {
ed_inx = 18;
cr_201 = 0x15;
- } else if (priv->byBBPreEDRSSI <= 49) {
+ } else if (priv->bb_pre_ed_rssi <= 49) {
ed_inx = 17;
cr_201 = 0xe;
- } else if (priv->byBBPreEDRSSI <= 51) {
+ } else if (priv->bb_pre_ed_rssi <= 51) {
ed_inx = 16;
cr_201 = 0x9;
- } else if (priv->byBBPreEDRSSI <= 53) {
+ } else if (priv->bb_pre_ed_rssi <= 53) {
ed_inx = 15;
cr_201 = 0x6;
- } else if (priv->byBBPreEDRSSI <= 55) {
+ } else if (priv->bb_pre_ed_rssi <= 55) {
ed_inx = 14;
cr_201 = 0x3;
- } else if (priv->byBBPreEDRSSI <= 56) {
+ } else if (priv->bb_pre_ed_rssi <= 56) {
ed_inx = 13;
cr_201 = 0x2;
cr_206 = 0xa0;
- } else if (priv->byBBPreEDRSSI <= 57) {
+ } else if (priv->bb_pre_ed_rssi <= 57) {
ed_inx = 12;
cr_201 = 0x2;
cr_206 = 0x20;
- } else if (priv->byBBPreEDRSSI <= 58) {
+ } else if (priv->bb_pre_ed_rssi <= 58) {
ed_inx = 11;
cr_201 = 0x1;
cr_206 = 0xa0;
- } else if (priv->byBBPreEDRSSI <= 59) {
+ } else if (priv->bb_pre_ed_rssi <= 59) {
ed_inx = 10;
cr_201 = 0x1;
cr_206 = 0x54;
- } else if (priv->byBBPreEDRSSI <= 60) {
+ } else if (priv->bb_pre_ed_rssi <= 60) {
ed_inx = 9;
cr_201 = 0x1;
cr_206 = 0x18;
- } else if (priv->byBBPreEDRSSI <= 61) {
+ } else if (priv->bb_pre_ed_rssi <= 61) {
ed_inx = 8;
cr_206 = 0xe3;
- } else if (priv->byBBPreEDRSSI <= 62) {
+ } else if (priv->bb_pre_ed_rssi <= 62) {
ed_inx = 7;
cr_206 = 0xb9;
- } else if (priv->byBBPreEDRSSI <= 63) {
+ } else if (priv->bb_pre_ed_rssi <= 63) {
ed_inx = 6;
cr_206 = 0x93;
- } else if (priv->byBBPreEDRSSI <= 64) {
+ } else if (priv->bb_pre_ed_rssi <= 64) {
ed_inx = 5;
cr_206 = 0x79;
- } else if (priv->byBBPreEDRSSI <= 65) {
+ } else if (priv->bb_pre_ed_rssi <= 65) {
ed_inx = 4;
cr_206 = 0x62;
- } else if (priv->byBBPreEDRSSI <= 66) {
+ } else if (priv->bb_pre_ed_rssi <= 66) {
ed_inx = 3;
cr_206 = 0x51;
- } else if (priv->byBBPreEDRSSI <= 67) {
+ } else if (priv->bb_pre_ed_rssi <= 67) {
ed_inx = 2;
cr_206 = 0x43;
- } else if (priv->byBBPreEDRSSI <= 68) {
+ } else if (priv->bb_pre_ed_rssi <= 68) {
ed_inx = 1;
cr_206 = 0x36;
} else {
@@ -1215,75 +659,75 @@ void BBvUpdatePreEDThreshold(struct vnt_private *priv, int scanning)
break;
}
- if (priv->byBBPreEDRSSI <= 41) {
+ if (priv->bb_pre_ed_rssi <= 41) {
ed_inx = 22;
cr_201 = 0xff;
- } else if (priv->byBBPreEDRSSI <= 42) {
+ } else if (priv->bb_pre_ed_rssi <= 42) {
ed_inx = 21;
cr_201 = 0x36;
- } else if (priv->byBBPreEDRSSI <= 43) {
+ } else if (priv->bb_pre_ed_rssi <= 43) {
ed_inx = 20;
cr_201 = 0x26;
- } else if (priv->byBBPreEDRSSI <= 45) {
+ } else if (priv->bb_pre_ed_rssi <= 45) {
ed_inx = 19;
cr_201 = 0x18;
- } else if (priv->byBBPreEDRSSI <= 47) {
+ } else if (priv->bb_pre_ed_rssi <= 47) {
ed_inx = 18;
cr_201 = 0x11;
- } else if (priv->byBBPreEDRSSI <= 49) {
+ } else if (priv->bb_pre_ed_rssi <= 49) {
ed_inx = 17;
cr_201 = 0xa;
- } else if (priv->byBBPreEDRSSI <= 51) {
+ } else if (priv->bb_pre_ed_rssi <= 51) {
ed_inx = 16;
cr_201 = 0x7;
- } else if (priv->byBBPreEDRSSI <= 53) {
+ } else if (priv->bb_pre_ed_rssi <= 53) {
ed_inx = 15;
cr_201 = 0x4;
- } else if (priv->byBBPreEDRSSI <= 55) {
+ } else if (priv->bb_pre_ed_rssi <= 55) {
ed_inx = 14;
cr_201 = 0x2;
cr_206 = 0xc0;
- } else if (priv->byBBPreEDRSSI <= 56) {
+ } else if (priv->bb_pre_ed_rssi <= 56) {
ed_inx = 13;
cr_201 = 0x2;
cr_206 = 0x30;
- } else if (priv->byBBPreEDRSSI <= 57) {
+ } else if (priv->bb_pre_ed_rssi <= 57) {
ed_inx = 12;
cr_201 = 0x1;
cr_206 = 0xb0;
- } else if (priv->byBBPreEDRSSI <= 58) {
+ } else if (priv->bb_pre_ed_rssi <= 58) {
ed_inx = 11;
cr_201 = 0x1;
cr_206 = 0x70;
- } else if (priv->byBBPreEDRSSI <= 59) {
+ } else if (priv->bb_pre_ed_rssi <= 59) {
ed_inx = 10;
cr_201 = 0x1;
cr_206 = 0x30;
- } else if (priv->byBBPreEDRSSI <= 60) {
+ } else if (priv->bb_pre_ed_rssi <= 60) {
ed_inx = 9;
cr_206 = 0xea;
- } else if (priv->byBBPreEDRSSI <= 61) {
+ } else if (priv->bb_pre_ed_rssi <= 61) {
ed_inx = 8;
cr_206 = 0xc0;
- } else if (priv->byBBPreEDRSSI <= 62) {
+ } else if (priv->bb_pre_ed_rssi <= 62) {
ed_inx = 7;
cr_206 = 0x9c;
- } else if (priv->byBBPreEDRSSI <= 63) {
+ } else if (priv->bb_pre_ed_rssi <= 63) {
ed_inx = 6;
cr_206 = 0x80;
- } else if (priv->byBBPreEDRSSI <= 64) {
+ } else if (priv->bb_pre_ed_rssi <= 64) {
ed_inx = 5;
cr_206 = 0x68;
- } else if (priv->byBBPreEDRSSI <= 65) {
+ } else if (priv->bb_pre_ed_rssi <= 65) {
ed_inx = 4;
cr_206 = 0x52;
- } else if (priv->byBBPreEDRSSI <= 66) {
+ } else if (priv->bb_pre_ed_rssi <= 66) {
ed_inx = 3;
cr_206 = 0x43;
- } else if (priv->byBBPreEDRSSI <= 67) {
+ } else if (priv->bb_pre_ed_rssi <= 67) {
ed_inx = 2;
cr_206 = 0x36;
- } else if (priv->byBBPreEDRSSI <= 68) {
+ } else if (priv->bb_pre_ed_rssi <= 68) {
ed_inx = 1;
cr_206 = 0x2d;
} else {
@@ -1299,69 +743,69 @@ void BBvUpdatePreEDThreshold(struct vnt_private *priv, int scanning)
break;
}
- if (priv->byBBPreEDRSSI <= 41) {
+ if (priv->bb_pre_ed_rssi <= 41) {
ed_inx = 20;
cr_201 = 0xff;
- } else if (priv->byBBPreEDRSSI <= 42) {
+ } else if (priv->bb_pre_ed_rssi <= 42) {
ed_inx = 19;
cr_201 = 0x36;
- } else if (priv->byBBPreEDRSSI <= 43) {
+ } else if (priv->bb_pre_ed_rssi <= 43) {
ed_inx = 18;
cr_201 = 0x26;
- } else if (priv->byBBPreEDRSSI <= 45) {
+ } else if (priv->bb_pre_ed_rssi <= 45) {
ed_inx = 17;
cr_201 = 0x18;
- } else if (priv->byBBPreEDRSSI <= 47) {
+ } else if (priv->bb_pre_ed_rssi <= 47) {
ed_inx = 16;
cr_201 = 0x11;
- } else if (priv->byBBPreEDRSSI <= 49) {
+ } else if (priv->bb_pre_ed_rssi <= 49) {
ed_inx = 15;
cr_201 = 0xa;
- } else if (priv->byBBPreEDRSSI <= 51) {
+ } else if (priv->bb_pre_ed_rssi <= 51) {
ed_inx = 14;
cr_201 = 0x7;
- } else if (priv->byBBPreEDRSSI <= 53) {
+ } else if (priv->bb_pre_ed_rssi <= 53) {
ed_inx = 13;
cr_201 = 0x4;
- } else if (priv->byBBPreEDRSSI <= 55) {
+ } else if (priv->bb_pre_ed_rssi <= 55) {
ed_inx = 12;
cr_201 = 0x2;
cr_206 = 0xc0;
- } else if (priv->byBBPreEDRSSI <= 56) {
+ } else if (priv->bb_pre_ed_rssi <= 56) {
ed_inx = 11;
cr_201 = 0x2;
cr_206 = 0x30;
- } else if (priv->byBBPreEDRSSI <= 57) {
+ } else if (priv->bb_pre_ed_rssi <= 57) {
ed_inx = 10;
cr_201 = 0x1;
cr_206 = 0xb0;
- } else if (priv->byBBPreEDRSSI <= 58) {
+ } else if (priv->bb_pre_ed_rssi <= 58) {
ed_inx = 9;
cr_201 = 0x1;
cr_206 = 0x70;
- } else if (priv->byBBPreEDRSSI <= 59) {
+ } else if (priv->bb_pre_ed_rssi <= 59) {
ed_inx = 8;
cr_201 = 0x1;
cr_206 = 0x30;
- } else if (priv->byBBPreEDRSSI <= 60) {
+ } else if (priv->bb_pre_ed_rssi <= 60) {
ed_inx = 7;
cr_206 = 0xea;
- } else if (priv->byBBPreEDRSSI <= 61) {
+ } else if (priv->bb_pre_ed_rssi <= 61) {
ed_inx = 6;
cr_206 = 0xc0;
- } else if (priv->byBBPreEDRSSI <= 62) {
+ } else if (priv->bb_pre_ed_rssi <= 62) {
ed_inx = 5;
cr_206 = 0x9c;
- } else if (priv->byBBPreEDRSSI <= 63) {
+ } else if (priv->bb_pre_ed_rssi <= 63) {
ed_inx = 4;
cr_206 = 0x80;
- } else if (priv->byBBPreEDRSSI <= 64) {
+ } else if (priv->bb_pre_ed_rssi <= 64) {
ed_inx = 3;
cr_206 = 0x68;
- } else if (priv->byBBPreEDRSSI <= 65) {
+ } else if (priv->bb_pre_ed_rssi <= 65) {
ed_inx = 2;
cr_206 = 0x52;
- } else if (priv->byBBPreEDRSSI <= 66) {
+ } else if (priv->bb_pre_ed_rssi <= 66) {
ed_inx = 1;
cr_206 = 0x43;
} else {
@@ -1372,13 +816,13 @@ void BBvUpdatePreEDThreshold(struct vnt_private *priv, int scanning)
}
- if (ed_inx == priv->byBBPreEDIndex && !scanning)
+ if (ed_inx == priv->bb_pre_ed_index && !scanning)
return;
- priv->byBBPreEDIndex = ed_inx;
+ priv->bb_pre_ed_index = ed_inx;
- dev_dbg(&priv->usb->dev, "%s byBBPreEDRSSI %d\n",
- __func__, priv->byBBPreEDRSSI);
+ dev_dbg(&priv->usb->dev, "%s bb_pre_ed_rssi %d\n",
+ __func__, priv->bb_pre_ed_rssi);
if (!cr_201 && !cr_206)
return;
diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h
index 3044d6c42050..771ea4054174 100644
--- a/drivers/staging/vt6656/baseband.h
+++ b/drivers/staging/vt6656/baseband.h
@@ -33,7 +33,6 @@
#ifndef __BASEBAND_H__
#define __BASEBAND_H__
-#include "tether.h"
#include "device.h"
#define PREAMBLE_LONG 0
@@ -88,18 +87,18 @@ struct vnt_phy_field {
__le16 len;
} __packed;
-unsigned int BBuGetFrameTime(u8 preamble_type, u8 pkt_type,
+unsigned int vnt_get_frame_time(u8 preamble_type, u8 pkt_type,
unsigned int frame_length, u16 tx_rate);
-void BBvCalculateParameter(struct vnt_private *, u32 frame_length,
+void vnt_get_phy_field(struct vnt_private *, u32 frame_length,
u16 tx_rate, u8 pkt_type, struct vnt_phy_field *);
-void BBvSetShortSlotTime(struct vnt_private *);
-void BBvSetVGAGainOffset(struct vnt_private *, u8 byData);
-void BBvSetAntennaMode(struct vnt_private *, u8 byAntennaMode);
-int BBbVT3184Init(struct vnt_private *);
-void BBvSetDeepSleep(struct vnt_private *);
-void BBvExitDeepSleep(struct vnt_private *);
-void BBvUpdatePreEDThreshold(struct vnt_private *, int scanning);
+void vnt_set_short_slot_time(struct vnt_private *);
+void vnt_set_vga_gain_offset(struct vnt_private *, u8);
+void vnt_set_antenna_mode(struct vnt_private *, u8);
+int vnt_vt3184_init(struct vnt_private *);
+void vnt_set_deep_sleep(struct vnt_private *);
+void vnt_exit_deep_sleep(struct vnt_private *);
+void vnt_update_pre_ed_threshold(struct vnt_private *, int scanning);
#endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
deleted file mode 100644
index 8e9ce96442a0..000000000000
--- a/drivers/staging/vt6656/bssdb.c
+++ /dev/null
@@ -1,1466 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: bssdb.c
- *
- * Purpose: Handles the Basic Service Set & Node Database functions
- *
- * Functions:
- * BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
- * BSSvClearBSSList - Clear BSS List
- * BSSbInsertToBSSList - Insert a BSS set into known BSS list
- * BSSbUpdateToBSSList - Update BSS set in known BSS list
- * BSSbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
- * BSSvCreateOneNode - Allocate an Node for Node DB
- * BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
- * BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
- * BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fallback rate control
- *
- * Revision History:
- *
- * Author: Lyndon Chen
- *
- * Date: July 17, 2002
- */
-
-#include "tmacro.h"
-#include "tether.h"
-#include "device.h"
-#include "80211hdr.h"
-#include "bssdb.h"
-#include "wmgr.h"
-#include "datarate.h"
-#include "desc.h"
-#include "wcmd.h"
-#include "wpa.h"
-#include "baseband.h"
-#include "rf.h"
-#include "card.h"
-#include "mac.h"
-#include "wpa2.h"
-#include "usbpipe.h"
-#include "iowpa.h"
-#include "power.h"
-
-static int msglevel = MSG_LEVEL_INFO;
-/* static int msglevel = MSG_LEVEL_DEBUG; */
-
-static const u16 awHWRetry0[5][5] = {
- {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
- {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
- {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
- {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
- {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
- };
-static const u16 awHWRetry1[5][5] = {
- {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
- {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
- {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
- {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
- {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
- };
-
-static void s_vCheckSensitivity(struct vnt_private *pDevice);
-static void s_vCheckPreEDThreshold(struct vnt_private *pDevice);
-static void s_uCalculateLinkQual(struct vnt_private *pDevice);
-
-/*
- * Routine Description:
- * Search known BSS list for Desire SSID or BSSID.
- *
- * Return Value:
- * PTR to KnownBSS or NULL
- */
-PKnownBSS BSSpSearchBSSList(struct vnt_private *pDevice,
- u8 *pbyDesireBSSID, u8 *pbyDesireSSID,
- CARD_PHY_TYPE ePhyType)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u8 *pbyBSSID = NULL;
- PWLAN_IE_SSID pSSID = NULL;
- PKnownBSS pCurrBSS = NULL;
- PKnownBSS pSelect = NULL;
- u8 ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- int ii = 0;
- int jj = 0;
-
- if (pbyDesireBSSID) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID);
- if (!is_broadcast_ether_addr(pbyDesireBSSID) &&
- memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)
- pbyBSSID = pbyDesireBSSID;
- }
- if (pbyDesireSSID &&
- ((PWLAN_IE_SSID) pbyDesireSSID)->len != 0)
- pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
-
- if (pbyBSSID && pDevice->bRoaming == false) {
- /* match BSSID first */
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pCurrBSS = &(pMgmt->sBSSList[ii]);
-
- pCurrBSS->bSelected = false;
-
- if (pCurrBSS->bActive &&
- pCurrBSS->bSelected == false &&
- ether_addr_equal(pCurrBSS->abyBSSID, pbyBSSID)) {
- if (pSSID) {
- /* compare ssid */
- if (!memcmp(pSSID->abySSID,
- ((PWLAN_IE_SSID) pCurrBSS->abySSID)->abySSID,
- pSSID->len) &&
- (pMgmt->eConfigMode == WMAC_CONFIG_AUTO ||
- (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA &&
- WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
- (pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA &&
- WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)))) {
-
- pCurrBSS->bSelected = true;
- return pCurrBSS;
- }
- } else if (pMgmt->eConfigMode == WMAC_CONFIG_AUTO ||
- (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA &&
- WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
- (pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA &&
- WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))) {
- pCurrBSS->bSelected = true;
- return pCurrBSS;
- }
- }
- }
- } else {
- /* ignore BSSID */
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pCurrBSS = &(pMgmt->sBSSList[ii]);
-
- /* 2007-0721-01<Mark>by MikeLiu
- * if ((pCurrBSS->bActive) &&
- * (pCurrBSS->bSelected == false)) { */
-
- pCurrBSS->bSelected = false;
- if (pCurrBSS->bActive) {
-
- if (pSSID &&
- /* matched SSID */
- (memcmp(pSSID->abySSID,
- ((PWLAN_IE_SSID) pCurrBSS->abySSID)->abySSID,
- pSSID->len) ||
- pSSID->len !=
- ((PWLAN_IE_SSID) pCurrBSS->abySSID)->len)) {
- /* SSID not match skip this BSS */
- continue;
- }
-
- if ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA &&
- WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
- (pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA &&
- WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))) {
- /* Type not match skip this BSS */
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n",
- pMgmt->eConfigMode,
- pCurrBSS->wCapInfo);
- continue;
- }
-
- if (ePhyType != PHY_TYPE_AUTO &&
- ((ePhyType == PHY_TYPE_11A &&
- PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse) ||
- (ePhyType != PHY_TYPE_11A &&
- PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
- /* PhyType not match skip this BSS */
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n",
- ePhyType,
- pCurrBSS->eNetworkTypeInUse);
- continue;
- }
-
- pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "BSSpSearchBSSList pSelect1[%pM]\n",
- pCurrBSS->abyBSSID);
- jj++;
-
- if (!pSelect)
- pSelect = pCurrBSS;
- /* compare RSSI, select the strongest signal */
- else if (pCurrBSS->uRSSI < pSelect->uRSSI)
- pSelect = pCurrBSS;
- }
- }
-
- pDevice->bSameBSSMaxNum = jj;
-
- if (pSelect) {
- pSelect->bSelected = true;
- if (pDevice->bRoaming == false) {
- /* Einsn Add @20070907 */
- memcpy(pbyDesireSSID,
- pCurrBSS->abySSID,
- WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- }
-
- return pSelect;
- }
- }
- return NULL;
-
-}
-
-/*
- * Routine Description:
- * Clear BSS List
- *
- * Return Value:
- * None.
- */
-void BSSvClearBSSList(struct vnt_private *pDevice, int bKeepCurrBSSID)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- if (bKeepCurrBSSID &&
- pMgmt->sBSSList[ii].bActive &&
- ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
- pMgmt->abyCurrBSSID)) {
-
- /* mike mark:
- * there are two BSSID's in list. If that AP is
- * in hidden ssid mode, one SSID is null, but
- * other's might not be obvious, so if it
- * associate's with your STA, you must keep the
- * two of them!! bKeepCurrBSSID = false;
- */
-
- continue;
- }
-
- pMgmt->sBSSList[ii].bActive = false;
- memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
- }
- BSSvClearAnyBSSJoinRecord(pDevice);
-}
-
-/*
- * Routine Description:
- * search BSS list by BSSID & SSID if matched
- *
- * Return Value:
- * true if found.
- */
-PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *pDevice,
- u8 *abyBSSID,
- PWLAN_IE_SSID pSSID)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PKnownBSS pBSSList = NULL;
- int ii;
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pBSSList = &(pMgmt->sBSSList[ii]);
- if (pBSSList->bActive &&
- ether_addr_equal(pBSSList->abyBSSID, abyBSSID) &&
- pSSID->len == ((PWLAN_IE_SSID) pBSSList->abySSID)->len &&
- memcmp(pSSID->abySSID,
- ((PWLAN_IE_SSID) pBSSList->abySSID)->abySSID,
- pSSID->len) == 0)
- return pBSSList;
- }
-
- return NULL;
-}
-
-/*
- * Routine Description:
- * Insert a BSS set into known BSS list
- *
- * Return Value:
- * true if success.
- */
-int BSSbInsertToBSSList(struct vnt_private *pDevice,
- u8 *abyBSSIDAddr,
- u64 qwTimestamp,
- u16 wBeaconInterval,
- u16 wCapInfo,
- u8 byCurrChannel,
- PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pSuppRates,
- PWLAN_IE_SUPP_RATES pExtSuppRates,
- PERPObject psERP,
- PWLAN_IE_RSN pRSN,
- PWLAN_IE_RSN_EXT pRSNWPA,
- PWLAN_IE_COUNTRY pIE_Country,
- PWLAN_IE_QUIET pIE_Quiet,
- u32 uIELength,
- u8 *pbyIEs,
- void *pRxPacketContext)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_rx_mgmt *pRxPacket =
- (struct vnt_rx_mgmt *) pRxPacketContext;
- PKnownBSS pBSSList = NULL;
- unsigned int ii;
- bool bParsingQuiet = false;
-
- pBSSList = (PKnownBSS) &(pMgmt->sBSSList[0]);
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- pBSSList = (PKnownBSS) &(pMgmt->sBSSList[ii]);
- if (!pBSSList->bActive)
- break;
- }
-
- if (ii == MAX_BSS_NUM) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Get free KnowBSS node failed.\n");
- return false;
- }
- /* save the BSS info */
- pBSSList->bActive = true;
- memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
- pBSSList->qwBSSTimestamp = cpu_to_le64(qwTimestamp);
- pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
- pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
- pBSSList->uClearCount = 0;
-
- if (pSSID->len > WLAN_SSID_MAXLEN)
- pSSID->len = WLAN_SSID_MAXLEN;
- memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
-
- pBSSList->uChannel = byCurrChannel;
-
- if (pSuppRates->len > WLAN_RATES_MAXLEN)
- pSuppRates->len = WLAN_RATES_MAXLEN;
- memcpy(pBSSList->abySuppRates, pSuppRates,
- pSuppRates->len + WLAN_IEHDR_LEN);
-
- if (pExtSuppRates) {
- if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
- pExtSuppRates->len = WLAN_RATES_MAXLEN;
- memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,
- pExtSuppRates->len + WLAN_IEHDR_LEN);
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "BSSbInsertToBSSList: pExtSuppRates->len = %d\n",
- pExtSuppRates->len);
-
- } else {
- memset(pBSSList->abyExtSuppRates, 0,
- WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
- }
- pBSSList->sERP.byERP = psERP->byERP;
- pBSSList->sERP.bERPExist = psERP->bERPExist;
-
- /* Check if BSS is 802.11a/b/g */
- if (pBSSList->uChannel > CB_MAX_CHANNEL_24G)
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
- else if (pBSSList->sERP.bERPExist == true)
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
- else
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
-
- pBSSList->byRxRate = pRxPacket->byRxRate;
- pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
- pBSSList->uRSSI = pRxPacket->uRSSI;
- pBSSList->bySQ = pRxPacket->bySQ;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA &&
- pMgmt->eCurrState == WMAC_STATE_ASSOC &&
- /* assoc with BSS */
- pBSSList == pMgmt->pCurrBSS)
- bParsingQuiet = true;
-
- WPA_ClearRSN(pBSSList);
-
- if (pRSNWPA) {
- unsigned int uLen = pRSNWPA->len + 2;
-
- if (uLen <= (uIELength -
- (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) {
- pBSSList->wWPALen = uLen;
- memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
- WPA_ParseRSN(pBSSList, pRSNWPA);
- }
- }
-
- WPA2_ClearRSN(pBSSList);
-
- if (pRSN) {
- unsigned int uLen = pRSN->len + 2;
-
- if (uLen <= (uIELength -
- (unsigned int) (u32) ((u8 *) pRSN - pbyIEs))) {
- pBSSList->wRSNLen = uLen;
- memcpy(pBSSList->byRSNIE, pRSN, uLen);
- WPA2vParseRSN(pBSSList, pRSN);
- }
- }
-
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2 ||
- pBSSList->bWPA2Valid == true) {
-
- PSKeyItem pTransmitKey = NULL;
- bool bIs802_1x = false;
-
- for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii++) {
- if (pBSSList->abyAKMSSAuthType[ii] ==
- WLAN_11i_AKMSS_802_1X) {
- bIs802_1x = true;
- break;
- }
- }
- if (bIs802_1x == true &&
- pSSID->len == ((PWLAN_IE_SSID) pMgmt->abyDesireSSID)->len &&
- !memcmp(pSSID->abySSID,
- ((PWLAN_IE_SSID) pMgmt->abyDesireSSID)->abySSID,
- pSSID->len)) {
-
- bAdd_PMKID_Candidate((void *) pDevice,
- pBSSList->abyBSSID,
- &pBSSList->sRSNCapObj);
-
- if (pDevice->bLinkPass == true &&
- pMgmt->eCurrState == WMAC_STATE_ASSOC &&
- (KeybGetTransmitKey(&(pDevice->sKey),
- pDevice->abyBSSID,
- PAIRWISE_KEY,
- &pTransmitKey) == true ||
- KeybGetTransmitKey(&(pDevice->sKey),
- pDevice->abyBSSID,
- GROUP_KEY,
- &pTransmitKey) == true)) {
- pDevice->gsPMKIDCandidate.StatusType =
- Ndis802_11StatusType_PMKID_CandidateList;
- pDevice->gsPMKIDCandidate.Version = 1;
-
-
- }
- }
- }
-
- /* Monitor if RSSI is too strong. */
- pBSSList->byRSSIStatCnt = 0;
-
- vnt_rf_rssi_to_dbm(pDevice, (u8)pRxPacket->uRSSI, &pBSSList->ldBmMAX);
-
- pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
- pBSSList->ldBmAverRange = pBSSList->ldBmMAX;
- for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
- pBSSList->ldBmAverage[ii] = 0;
-
- pBSSList->uIELength = uIELength;
- if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
- pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
- memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
-
- return true;
-}
-
-/*
- * Routine Description:
- * Update BSS set in known BSS list
- *
- * Return Value:
- * true if success.
- */
-/* TODO: input structure modify */
-int BSSbUpdateToBSSList(struct vnt_private *pDevice,
- u64 qwTimestamp,
- u16 wBeaconInterval,
- u16 wCapInfo,
- u8 byCurrChannel,
- int bChannelHit,
- PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pSuppRates,
- PWLAN_IE_SUPP_RATES pExtSuppRates,
- PERPObject psERP,
- PWLAN_IE_RSN pRSN,
- PWLAN_IE_RSN_EXT pRSNWPA,
- PWLAN_IE_COUNTRY pIE_Country,
- PWLAN_IE_QUIET pIE_Quiet,
- PKnownBSS pBSSList,
- u32 uIELength,
- u8 *pbyIEs,
- void *pRxPacketContext)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_rx_mgmt *pRxPacket =
- (struct vnt_rx_mgmt *) pRxPacketContext;
- int ii, jj;
- signed long ldBm, ldBmSum;
- bool bParsingQuiet = false;
-
- if (!pBSSList)
- return false;
-
- pBSSList->qwBSSTimestamp = cpu_to_le64(qwTimestamp);
-
- pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
- pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
- pBSSList->uClearCount = 0;
- pBSSList->uChannel = byCurrChannel;
-
- if (pSSID->len > WLAN_SSID_MAXLEN)
- pSSID->len = WLAN_SSID_MAXLEN;
-
- if (pSSID->len != 0 && pSSID->abySSID[0] != 0)
- memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
- memcpy(pBSSList->abySuppRates, pSuppRates,
- pSuppRates->len + WLAN_IEHDR_LEN);
-
- if (pExtSuppRates)
- memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,
- pExtSuppRates->len + WLAN_IEHDR_LEN);
- else
- memset(pBSSList->abyExtSuppRates, 0,
- WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
- pBSSList->sERP.byERP = psERP->byERP;
- pBSSList->sERP.bERPExist = psERP->bERPExist;
-
- /* Check if BSS is 802.11a/b/g */
- if (pBSSList->uChannel > CB_MAX_CHANNEL_24G)
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
- else if (pBSSList->sERP.bERPExist == true)
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
- else
- pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
-
- pBSSList->byRxRate = pRxPacket->byRxRate;
- pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
- if (bChannelHit)
- pBSSList->uRSSI = pRxPacket->uRSSI;
- pBSSList->bySQ = pRxPacket->bySQ;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA &&
- pMgmt->eCurrState == WMAC_STATE_ASSOC &&
- /* assoc with BSS */
- pBSSList == pMgmt->pCurrBSS)
- bParsingQuiet = true;
-
- WPA_ClearRSN(pBSSList); /* mike update */
-
- if (pRSNWPA) {
- unsigned int uLen = pRSNWPA->len + 2;
- if (uLen <= (uIELength -
- (unsigned int) (u32) ((u8 *) pRSNWPA - pbyIEs))) {
- pBSSList->wWPALen = uLen;
- memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
- WPA_ParseRSN(pBSSList, pRSNWPA);
- }
- }
-
- WPA2_ClearRSN(pBSSList); /* mike update */
-
- if (pRSN) {
- unsigned int uLen = pRSN->len + 2;
- if (uLen <= (uIELength -
- (unsigned int) (u32) ((u8 *) pRSN - pbyIEs))) {
- pBSSList->wRSNLen = uLen;
- memcpy(pBSSList->byRSNIE, pRSN, uLen);
- WPA2vParseRSN(pBSSList, pRSN);
- }
- }
-
- if (pRxPacket->uRSSI != 0) {
- vnt_rf_rssi_to_dbm(pDevice, (u8)pRxPacket->uRSSI, &ldBm);
- /* Monitor if RSSI is too strong. */
- pBSSList->byRSSIStatCnt++;
- pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
- pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
- ldBmSum = 0;
- for (ii = 0, jj = 0; ii < RSSI_STAT_COUNT; ii++) {
- if (pBSSList->ldBmAverage[ii] != 0) {
- pBSSList->ldBmMAX =
- max(pBSSList->ldBmAverage[ii], ldBm);
- ldBmSum +=
- pBSSList->ldBmAverage[ii];
- jj++;
- }
- }
- pBSSList->ldBmAverRange = ldBmSum / jj;
- }
-
- pBSSList->uIELength = uIELength;
- if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
- pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
- memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
-
- return true;
-}
-
-/*
- * Routine Description:
- * Search Node DB table to find the index of matched DstAddr
- *
- * Return Value:
- * None
- */
-int BSSbIsSTAInNodeDB(struct vnt_private *pDevice,
- u8 *abyDstAddr,
- u32 *puNodeIndex)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- unsigned int ii;
-
- /* Index = 0 reserved for AP Node */
- for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
- if (pMgmt->sNodeDBTable[ii].bActive &&
- ether_addr_equal(abyDstAddr,
- pMgmt->sNodeDBTable[ii].abyMACAddr)) {
- *puNodeIndex = ii;
- return true;
- }
- }
-
- return false;
-};
-
-/*
- * Routine Description:
- * Find an empty node and allocate it; if no empty node
- * is found, then use the most inactive one.
- *
- * Return Value:
- * None
- */
-void BSSvCreateOneNode(struct vnt_private *pDevice, u32 *puNodeIndex)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
- u32 BigestCount = 0;
- u32 SelectIndex;
- struct sk_buff *skb;
-
- /* Index = 0 reserved for AP Node (In STA mode)
- Index = 0 reserved for Broadcast/MultiCast (In AP mode) */
- SelectIndex = 1;
- for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
- if (pMgmt->sNodeDBTable[ii].bActive) {
- if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
- BigestCount =
- pMgmt->sNodeDBTable[ii].uInActiveCount;
- SelectIndex = ii;
- }
- } else {
- break;
- }
- }
-
- /* if not found replace uInActiveCount with the largest one. */
- if (ii == (MAX_NODE_NUM + 1)) {
- *puNodeIndex = SelectIndex;
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Replace inactive node = %d\n", SelectIndex);
- /* clear ps buffer */
- if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next) {
- while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)))
- dev_kfree_skb(skb);
- }
- } else {
- *puNodeIndex = ii;
- }
-
- memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
- pMgmt->sNodeDBTable[*puNodeIndex].bActive = true;
- pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
- /* for AP mode PS queue */
- skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
- pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
- pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
-}
-
-/*
- * Routine Description:
- * Remove Node by NodeIndex
- *
- *
- * Return Value:
- * None
- */
-void BSSvRemoveOneNode(struct vnt_private *pDevice, u32 uNodeIndex)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
- struct sk_buff *skb;
-
- while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)))
- dev_kfree_skb(skb);
- /* clear context */
- memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
- /* clear tx bit map */
- pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=
- ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
-}
-
-/*
- * Routine Description:
- * Update AP Node content in Index 0 of KnownNodeDB
- *
- *
- * Return Value:
- * None
- */
-void BSSvUpdateAPNode(struct vnt_private *pDevice,
- u16 *pwCapInfo,
- PWLAN_IE_SUPP_RATES pSuppRates,
- PWLAN_IE_SUPP_RATES pExtSuppRates)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u32 uRateLen = WLAN_RATES_MAXLEN;
-
- memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
-
- pMgmt->sNodeDBTable[0].bActive = true;
- if (pDevice->byBBType == BB_TYPE_11B)
- uRateLen = WLAN_RATES_MAXLEN_11B;
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES) pSuppRates,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates,
- uRateLen);
- pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES) pExtSuppRates,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates,
- uRateLen);
- RATEvParseMaxRate((void *) pDevice,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates,
- true,
- &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[0].wSuppRate),
- &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate));
- memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID,
- WLAN_ADDR_LEN);
- pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
- pMgmt->sNodeDBTable[0].bShortPreamble =
- WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
- pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
- /* Auto rate fallback function initiation.
- * RATEbInit(pDevice); */
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d\n",
- pMgmt->sNodeDBTable[0].wTxDataRate);
-
-}
-
-/*
- * Routine Description:
- * Add Multicast Node content in Index 0 of KnownNodeDB
- *
- *
- * Return Value:
- * None
- */
-void BSSvAddMulticastNode(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
-
- memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
- pMgmt->sNodeDBTable[0].bActive = true;
- pMgmt->sNodeDBTable[0].bPSEnable = false;
- skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
- RATEvParseMaxRate((void *) pDevice,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES) pMgmt->abyCurrExtSuppRates,
- true,
- &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[0].wSuppRate),
- &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate));
- pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
- pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
-
-}
-
-/*
- * Routine Description:
- *
- *
- * Second call back function to update Node DB info & AP link status
- *
- *
- * Return Value:
- * none.
- */
-void BSSvSecondCallBack(struct work_struct *work)
-{
- struct vnt_private *pDevice = container_of(work,
- struct vnt_private, second_callback_work.work);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
- PWLAN_IE_SSID pItemSSID, pCurrSSID;
- u32 uSleepySTACnt = 0;
- u32 uNonShortSlotSTACnt = 0;
- u32 uLongPreambleSTACnt = 0;
-
- if (pDevice->Flags & fMP_DISCONNECTED)
- return;
-
- pDevice->uAssocCount = 0;
-
- /* Power Saving Mode Tx Burst */
- if (pDevice->bEnablePSMode == true) {
- pDevice->ulPSModeWaitTx++;
- if (pDevice->ulPSModeWaitTx >= 2) {
- pDevice->ulPSModeWaitTx = 0;
- pDevice->bPSModeTxBurst = false;
- }
- }
-
- pDevice->byERPFlag &=
- ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
-
- if (pDevice->wUseProtectCntDown > 0) {
- pDevice->wUseProtectCntDown--;
- } else {
- /* disable protect mode */
- pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
- }
-
- if (pDevice->byReAssocCount > 0) {
- pDevice->byReAssocCount++;
- if (pDevice->byReAssocCount > 10 &&
- pDevice->bLinkPass != true) { /* 10 sec timeout */
- printk("Re-association timeout!!!\n");
- pDevice->byReAssocCount = 0;
- /* if (pDevice->bWPASuppWextEnabled == true) */
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP,
- &wrqu, NULL);
- }
- } else if (pDevice->bLinkPass == true) {
- pDevice->byReAssocCount = 0;
- }
- }
-
- pMgmt->eLastState = pMgmt->eCurrState;
-
- s_uCalculateLinkQual(pDevice);
-
- for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
-
- if (pMgmt->sNodeDBTable[ii].bActive) {
- /* Increase in-activity counter */
- pMgmt->sNodeDBTable[ii].uInActiveCount++;
-
- if (ii > 0) {
- if (pMgmt->sNodeDBTable[ii].uInActiveCount >
- MAX_INACTIVE_COUNT) {
- BSSvRemoveOneNode(pDevice, ii);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Inactive timeout [%d] sec, STA index = [%d] remove\n",
- MAX_INACTIVE_COUNT, ii);
- continue;
- }
-
- if (pMgmt->sNodeDBTable[ii].eNodeState >=
- NODE_ASSOC) {
-
- pDevice->uAssocCount++;
-
- /* check if Non ERP exist */
- if (pMgmt->sNodeDBTable[ii].uInActiveCount <
- ERP_RECOVER_COUNT) {
- if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
- pDevice->byERPFlag |=
- WLAN_SET_ERP_BARKER_MODE(1);
- uLongPreambleSTACnt++;
- }
- if (!pMgmt->sNodeDBTable[ii].bERPExist) {
- pDevice->byERPFlag |=
- WLAN_SET_ERP_NONERP_PRESENT(1);
- pDevice->byERPFlag |=
- WLAN_SET_ERP_USE_PROTECTION(1);
- }
- if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
- uNonShortSlotSTACnt++;
- }
- }
-
- /* check if any STA in PS mode */
- if (pMgmt->sNodeDBTable[ii].bPSEnable)
- uSleepySTACnt++;
-
- }
-
- /* Rate fallback check */
- if (!pDevice->bFixRate) {
- if (ii > 0) {
- /* ii = 0 for multicast node (AP & Adhoc) */
- RATEvTxRateFallBack((void *) pDevice,
- &(pMgmt->sNodeDBTable[ii]));
- } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
- /* ii = 0 reserved for unicast AP node (Infra STA) */
- RATEvTxRateFallBack((void *) pDevice,
- &(pMgmt->sNodeDBTable[ii]));
- }
-
- }
-
- /* check if pending PS queue */
- if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Index= %d, Queue = %d pending\n",
- ii,
- pMgmt->sNodeDBTable[ii].wEnQueueCnt);
- if (ii > 0 &&
- pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15) {
- BSSvRemoveOneNode(pDevice, ii);
- DBG_PRT(MSG_LEVEL_NOTICE,
- KERN_INFO "Pending many queues PS STA Index = %d remove\n",
- ii);
- continue;
- }
- }
- }
-
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP &&
- pDevice->byBBType == BB_TYPE_11G) {
-
- /* on/off protect mode */
- if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
- if (!pDevice->bProtectMode) {
- MACvEnableProtectMD(pDevice);
- pDevice->bProtectMode = true;
- }
- } else if (pDevice->bProtectMode) {
- MACvDisableProtectMD(pDevice);
- pDevice->bProtectMode = false;
- }
- /* on/off short slot time */
-
- if (uNonShortSlotSTACnt > 0) {
- if (pDevice->bShortSlotTime) {
- pDevice->bShortSlotTime = false;
- BBvSetShortSlotTime(pDevice);
- vUpdateIFS((void *) pDevice);
- }
- } else if (!pDevice->bShortSlotTime) {
- pDevice->bShortSlotTime = true;
- BBvSetShortSlotTime(pDevice);
- vUpdateIFS((void *) pDevice);
- }
-
- /* on/off barker long preamble mode */
-
- if (uLongPreambleSTACnt > 0) {
- if (!pDevice->bBarkerPreambleMd) {
- MACvEnableBarkerPreambleMd(pDevice);
- pDevice->bBarkerPreambleMd = true;
- }
- } else if (pDevice->bBarkerPreambleMd) {
- MACvDisableBarkerPreambleMd(pDevice);
- pDevice->bBarkerPreambleMd = false;
- }
-
- }
-
- /* Check if any STA in PS mode, enable DTIM multicast deliver */
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- if (uSleepySTACnt > 0)
- pMgmt->sNodeDBTable[0].bPSEnable = true;
- else
- pMgmt->sNodeDBTable[0].bPSEnable = false;
- }
-
- pItemSSID = (PWLAN_IE_SSID) pMgmt->abyDesireSSID;
- pCurrSSID = (PWLAN_IE_SSID) pMgmt->abyCurrSSID;
-
- if (pMgmt->eCurrMode == WMAC_MODE_STANDBY ||
- pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
-
- if (pMgmt->sNodeDBTable[0].bActive) { /* Assoc with BSS */
-
- s_vCheckSensitivity(pDevice);
- s_vCheckPreEDThreshold(pDevice);
-
- if (pMgmt->sNodeDBTable[0].uInActiveCount >=
- (LOST_BEACON_COUNT/2) &&
- pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) {
- pDevice->byBBVGANew = pDevice->abyBBVGA[0];
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_CHANGE_BBSENSITIVITY,
- NULL);
- }
-
- if (pMgmt->sNodeDBTable[0].uInActiveCount >=
- LOST_BEACON_COUNT) {
- pMgmt->sNodeDBTable[0].bActive = false;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- netif_stop_queue(pDevice->dev);
- pDevice->bLinkPass = false;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS,
- LEDSTS_SLOW);
-
- pDevice->bRoaming = true;
- pDevice->bIsRoaming = false;
-
- DBG_PRT(MSG_LEVEL_NOTICE,
- KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n",
- pMgmt->sNodeDBTable[0].uInActiveCount);
- /* let wpa supplicant know AP may disconnect */
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
- wireless_send_event(pDevice->dev,
- SIOCGIWAP,
- &wrqu,
- NULL);
- }
- }
- } else if (pItemSSID->len != 0) {
- /* Davidwang */
- if ((pDevice->bEnableRoaming == true) &&
- (!(pMgmt->Cisco_cckm))) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "bRoaming %d, !\n",
- pDevice->bRoaming);
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "bIsRoaming %d, !\n",
- pDevice->bIsRoaming);
- if ((pDevice->bRoaming == true) &&
- (pDevice->bIsRoaming == true)) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Fast Roaming ...\n");
- BSSvClearBSSList((void *) pDevice,
- pDevice->bLinkPass);
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_SSID,
- pMgmt->abyDesireSSID);
- pDevice->uAutoReConnectTime = 0;
- pDevice->uIsroamingTime = 0;
- pDevice->bRoaming = false;
- } else if (pDevice->bRoaming == false &&
- pDevice->bIsRoaming == true) {
- pDevice->uIsroamingTime++;
- if (pDevice->uIsroamingTime >= 20)
- pDevice->bIsRoaming = false;
- }
- } else if (pDevice->uAutoReConnectTime < 10) {
- pDevice->uAutoReConnectTime++;
- /* network manager support need not do Roaming scan??? */
- if (pDevice->bWPASuppWextEnabled == true)
- pDevice->uAutoReConnectTime = 0;
- } else {
- /* mike use old encryption status for wpa reauthen */
- if (pDevice->bWPADEVUp)
- pDevice->eEncryptionStatus =
- pDevice->eOldEncryptionStatus;
-
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Roaming ...\n");
- BSSvClearBSSList((void *) pDevice,
- pDevice->bLinkPass);
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_SSID,
- pMgmt->abyDesireSSID);
- pDevice->uAutoReConnectTime = 0;
- }
- }
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- /* if adhoc started which essid is NULL string, rescanning. */
- if (pMgmt->eCurrState == WMAC_STATE_STARTED &&
- pCurrSSID->len == 0) {
- if (pDevice->uAutoReConnectTime < 10) {
- pDevice->uAutoReConnectTime++;
- } else {
- DBG_PRT(MSG_LEVEL_NOTICE,
- KERN_INFO "Adhoc re-scanning ...\n");
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_BSSID_SCAN, NULL);
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_SSID, NULL);
- pDevice->uAutoReConnectTime = 0;
- }
- }
- if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
-
- s_vCheckSensitivity(pDevice);
- s_vCheckPreEDThreshold(pDevice);
-
- if (pMgmt->sNodeDBTable[0].uInActiveCount >=
- ADHOC_LOST_BEACON_COUNT) {
- DBG_PRT(MSG_LEVEL_NOTICE,
- KERN_INFO "Lost other STA beacon [%d] sec, started !\n",
- pMgmt->sNodeDBTable[0].uInActiveCount);
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
- pMgmt->eCurrState = WMAC_STATE_STARTED;
- netif_stop_queue(pDevice->dev);
- pDevice->bLinkPass = false;
- vnt_mac_set_led(pDevice, LEDSTS_STS,
- LEDSTS_SLOW);
- }
- }
- }
-
- if (pDevice->bLinkPass == true) {
- if ((pMgmt->eAuthenMode < WMAC_AUTH_WPA ||
- pDevice->fWPA_Authened == true) &&
- (++pDevice->tx_data_time_out > 40)) {
- pDevice->tx_trigger = true;
-
- PSbSendNullPacket(pDevice);
-
- pDevice->tx_trigger = false;
- pDevice->tx_data_time_out = 0;
- }
-
- if (netif_queue_stopped(pDevice->dev))
- netif_wake_queue(pDevice->dev);
- }
-
- schedule_delayed_work(&pDevice->second_callback_work, HZ);
-}
-
-/*
- * Routine Description:
- *
- *
- * Update Tx attemps, Tx failure counter in Node DB
- *
- *
- * Return Value:
- * none.
- */
-void BSSvUpdateNodeTxCounter(struct vnt_private *pDevice, u8 byTSR, u8 byPktNO)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_tx_pkt_info *pkt_info = pDevice->pkt_info;
- u32 uNodeIndex = 0;
- u8 byTxRetry;
- u16 wRate;
- u16 wFallBackRate = RATE_1M;
- u8 byFallBack;
- int ii;
- u8 *pbyDestAddr;
- u8 byPktNum;
- u16 wFIFOCtl;
-
- byPktNum = (byPktNO & 0x0F) >> 4;
- byTxRetry = (byTSR & 0xF0) >> 4;
- wRate = (u16) (byPktNO & 0xF0) >> 4;
- wFIFOCtl = pkt_info[byPktNum].fifo_ctl;
- pbyDestAddr = pkt_info[byPktNum].dest_addr;
-
- if (wFIFOCtl & FIFOCTL_AUTO_FB_0)
- byFallBack = AUTO_FB_0;
- else if (wFIFOCtl & FIFOCTL_AUTO_FB_1)
- byFallBack = AUTO_FB_1;
- else
- byFallBack = AUTO_FB_NONE;
-
- /* Only Unicast using support rates */
- if (wFIFOCtl & FIFOCTL_NEEDACK) {
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
- pMgmt->sNodeDBTable[0].uTxAttempts += 1;
- if (!(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
- /* transmit success, TxAttempts at least plus one */
- pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
- if ((byFallBack == AUTO_FB_NONE) ||
- (wRate < RATE_18M)) {
- wFallBackRate = wRate;
- } else if (byFallBack == AUTO_FB_0) {
- if (byTxRetry < 5)
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][byTxRetry];
- else
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][4];
- } else if (byFallBack == AUTO_FB_1) {
- if (byTxRetry < 5)
- wFallBackRate =
- awHWRetry1[wRate-RATE_18M][byTxRetry];
- else
- wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
- }
- pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
- } else {
- pMgmt->sNodeDBTable[0].uTxFailures++;
- }
- pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
- if (byTxRetry != 0) {
- pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE] += byTxRetry;
- if (byFallBack == AUTO_FB_NONE ||
- wRate < RATE_18M) {
- pMgmt->sNodeDBTable[0].uTxFail[wRate] += byTxRetry;
- } else if (byFallBack == AUTO_FB_0) {
- for (ii = 0; ii < byTxRetry; ii++) {
- if (ii < 5)
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][ii];
- else
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][4];
- pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
- }
- } else if (byFallBack == AUTO_FB_1) {
- for (ii = 0; ii < byTxRetry; ii++) {
- if (ii < 5)
- wFallBackRate =
- awHWRetry1[wRate-RATE_18M][ii];
- else
- wFallBackRate =
- awHWRetry1[wRate-RATE_18M][4];
- pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
- }
- }
- }
- }
-
- if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA ||
- pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
- BSSbIsSTAInNodeDB((void *) pDevice,
- pbyDestAddr,
- &uNodeIndex)) {
- pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
- if (!(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
- /* transmit success, TxAttempts at least plus one */
- pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
- if ((byFallBack == AUTO_FB_NONE) ||
- (wRate < RATE_18M)) {
- wFallBackRate = wRate;
- } else if (byFallBack == AUTO_FB_0) {
- if (byTxRetry < 5)
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][byTxRetry];
- else
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][4];
- } else if (byFallBack == AUTO_FB_1) {
- if (byTxRetry < 5)
- wFallBackRate =
- awHWRetry1[wRate-RATE_18M][byTxRetry];
- else
- wFallBackRate =
- awHWRetry1[wRate-RATE_18M][4];
- }
- pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
- } else {
- pMgmt->sNodeDBTable[uNodeIndex].uTxFailures++;
- }
- pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
- if (byTxRetry != 0) {
- pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE] += byTxRetry;
- if ((byFallBack == AUTO_FB_NONE) ||
- (wRate < RATE_18M)) {
- pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate] += byTxRetry;
- } else if (byFallBack == AUTO_FB_0) {
- for (ii = 0; ii < byTxRetry; ii++) {
- if (ii < 5)
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][ii];
- else
- wFallBackRate =
- awHWRetry0[wRate-RATE_18M][4];
- pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
- }
- } else if (byFallBack == AUTO_FB_1) {
- for (ii = 0; ii < byTxRetry; ii++) {
- if (ii < 5)
- wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
- else
- wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
- pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
- }
- }
- }
- }
- }
-}
-
-/*
- * Routine Description:
- * Clear Nodes & skb in DB Table
- *
- *
- * Parameters:
- * In:
- * hDeviceContext - The adapter context.
- * uStartIndex - starting index
- * Out:
- * none
- *
- * Return Value:
- * None.
- */
-void BSSvClearNodeDBTable(struct vnt_private *pDevice, u32 uStartIndex)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct sk_buff *skb;
- int ii;
-
- for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
- if (pMgmt->sNodeDBTable[ii].bActive) {
- /* check if sTxPSQueue has been initial */
- if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next) {
- while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue))) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "PS skb != NULL %d\n",
- ii);
- dev_kfree_skb(skb);
- }
- }
- memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
- }
- }
-}
-
-static void s_vCheckSensitivity(struct vnt_private *pDevice)
-{
- PKnownBSS pBSSList = NULL;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
-
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC ||
- (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA &&
- pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
- pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID,
- (PWLAN_IE_SSID) pMgmt->abyCurrSSID);
- if (pBSSList) {
- /* Update BB register if RSSI is too strong */
- signed long LocalldBmAverage = 0;
- signed long uNumofdBm = 0;
- for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
- if (pBSSList->ldBmAverage[ii] != 0) {
- uNumofdBm++;
- LocalldBmAverage += pBSSList->ldBmAverage[ii];
- }
- }
- if (uNumofdBm > 0) {
- LocalldBmAverage = LocalldBmAverage/uNumofdBm;
- for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n",
- LocalldBmAverage,
- pDevice->ldBmThreshold[ii],
- pDevice->abyBBVGA[ii]);
- if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
- pDevice->byBBVGANew =
- pDevice->abyBBVGA[ii];
- break;
- }
- }
- if (pDevice->byBBVGANew !=
- pDevice->byBBVGACurrent) {
- pDevice->uBBVGADiffCount++;
- if (pDevice->uBBVGADiffCount >=
- BB_VGA_CHANGE_THRESHOLD)
- bScheduleCommand(pDevice,
- WLAN_CMD_CHANGE_BBSENSITIVITY,
- NULL);
- } else {
- pDevice->uBBVGADiffCount = 0;
- }
- }
- }
- }
-}
-
-static void s_uCalculateLinkQual(struct vnt_private *pDevice)
-{
- struct net_device_stats *stats = &pDevice->stats;
- unsigned long TxOkRatio, TxCnt;
- unsigned long RxOkRatio, RxCnt;
- unsigned long RssiRatio;
- unsigned long qual;
- long ldBm;
-
- TxCnt = stats->tx_packets + pDevice->wstats.discard.retries;
-
- RxCnt = stats->rx_packets + stats->rx_frame_errors;
-
- TxOkRatio = (TxCnt < 6) ? 4000:((stats->tx_packets * 4000) / TxCnt);
-
- RxOkRatio = (RxCnt < 6) ? 2000 :
- ((stats->rx_packets * 2000) / RxCnt);
-
- /* decide link quality */
- if (pDevice->bLinkPass != true) {
- pDevice->wstats.qual.qual = 0;
- } else {
- vnt_rf_rssi_to_dbm(pDevice, (u8) (pDevice->uCurrRSSI), &ldBm);
- if (-ldBm < 50)
- RssiRatio = 4000;
- else if (-ldBm > 90)
- RssiRatio = 0;
- else
- RssiRatio = (40-(-ldBm-50)) * 4000 / 40;
-
- qual = (RssiRatio + TxOkRatio + RxOkRatio) / 100;
- if (qual < 100)
- pDevice->wstats.qual.qual = (u8) qual;
- else
- pDevice->wstats.qual.qual = 100;
- }
-}
-
-void BSSvClearAnyBSSJoinRecord(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++)
- pMgmt->sBSSList[ii].bSelected = false;
-
- return;
-}
-
-static void s_vCheckPreEDThreshold(struct vnt_private *pDevice)
-{
- PKnownBSS pBSSList = NULL;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC ||
- (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA &&
- pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
- pBSSList = BSSpAddrIsInBSSList(pDevice,
- pMgmt->abyCurrBSSID,
- (PWLAN_IE_SSID) pMgmt->abyCurrSSID);
- if (pBSSList) {
- pDevice->byBBPreEDRSSI =
- (u8) (~(pBSSList->ldBmAverRange) + 1);
- BBvUpdatePreEDThreshold(pDevice, false);
- }
- }
-}
-
diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h
deleted file mode 100644
index 8df3fb2a6199..000000000000
--- a/drivers/staging/vt6656/bssdb.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: bssdb.h
- *
- * Purpose: Handles the Basic Service Set & Node Database functions
- *
- * Author: Lyndon Chen
- *
- * Date: July 16, 2002
- *
- */
-
-#ifndef __BSSDB_H__
-#define __BSSDB_H__
-
-#include <linux/skbuff.h>
-#include "80211hdr.h"
-#include "80211mgr.h"
-#include "card.h"
-
-#define MAX_NODE_NUM 64
-#define MAX_BSS_NUM 42
-#define LOST_BEACON_COUNT 10 /* 10 sec, XP defined */
-#define MAX_PS_TX_BUF 32 // sta max power saving tx buf
-#define ADHOC_LOST_BEACON_COUNT 30 // 30 sec, beacon lost for adhoc only
-#define MAX_INACTIVE_COUNT 300 // 300 sec, inactive STA node refresh
-
-#define USE_PROTECT_PERIOD 10 // 10 sec, Use protect mode check period
-#define ERP_RECOVER_COUNT 30 // 30 sec, ERP support callback check
-#define BSS_CLEAR_COUNT 1
-
-#define RSSI_STAT_COUNT 10
-#define MAX_CHECK_RSSI_COUNT 8
-
-// STA dwflags
-#define WLAN_STA_AUTH BIT0
-#define WLAN_STA_ASSOC BIT1
-#define WLAN_STA_PS BIT2
-#define WLAN_STA_TIM BIT3
-// permanent; do not remove entry on expiration
-#define WLAN_STA_PERM BIT4
-// If 802.1X is used, this flag is
-// controlling whether STA is authorized to
-// send and receive non-IEEE 802.1X frames
-#define WLAN_STA_AUTHORIZED BIT5
-
-#define MAX_WPA_IE_LEN 64
-
-//
-// IEEE 802.11 Structures and definitions
-//
-
-typedef struct tagSERPObject {
- bool bERPExist;
- u8 byERP;
-} ERPObject, *PERPObject;
-
-typedef struct tagSRSNCapObject {
- bool bRSNCapExist;
- u16 wRSNCap;
-} SRSNCapObject, *PSRSNCapObject;
-
-// BSS info(AP)
-typedef struct tagKnownBSS {
- // BSS info
- bool bActive;
- u8 abyBSSID[WLAN_BSSID_LEN];
- unsigned int uChannel;
- u8 abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- unsigned int uRSSI;
- u8 bySQ;
- u16 wBeaconInterval;
- u16 wCapInfo;
- u8 abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- u8 byRxRate;
-
-// u16 wATIMWindow;
- u8 byRSSIStatCnt;
- signed long ldBmMAX;
- signed long ldBmAverage[RSSI_STAT_COUNT];
- signed long ldBmAverRange;
- //For any BSSID selection improvment
- bool bSelected;
-
- //++ WPA informations
- bool bWPAValid;
- u8 byGKType;
- u8 abyPKType[4];
- u16 wPKCount;
- u8 abyAuthType[4];
- u16 wAuthCount;
- u8 byDefaultK_as_PK;
- u8 byReplayIdx;
- //--
-
- //++ WPA2 informations
- bool bWPA2Valid;
- u8 byCSSGK;
- u16 wCSSPKCount;
- u8 abyCSSPK[4];
- u16 wAKMSSAuthCount;
- u8 abyAKMSSAuthType[4];
-
- //++ wpactl
- u8 byWPAIE[MAX_WPA_IE_LEN];
- u8 byRSNIE[MAX_WPA_IE_LEN];
- u16 wWPALen;
- u16 wRSNLen;
-
- // Clear count
- unsigned int uClearCount;
-// u8 abyIEs[WLAN_BEACON_FR_MAXLEN];
- unsigned int uIELength;
- u64 qwBSSTimestamp;
- u64 qwLocalTSF;/* local TSF timer */
-
- CARD_PHY_TYPE eNetworkTypeInUse;
-
- ERPObject sERP;
- SRSNCapObject sRSNCapObj;
- u8 abyIEs[1024]; // don't move this field !!
-
-} __attribute__ ((__packed__))
-KnownBSS , *PKnownBSS;
-
-typedef enum tagNODE_STATE {
- NODE_FREE,
- NODE_AGED,
- NODE_KNOWN,
- NODE_AUTH,
- NODE_ASSOC
-} NODE_STATE, *PNODE_STATE;
-
-// STA node info
-typedef struct tagKnownNodeDB {
- // STA info
- bool bActive;
- u8 abyMACAddr[WLAN_ADDR_LEN];
- u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
- u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
- u16 wTxDataRate;
- bool bShortPreamble;
- bool bERPExist;
- bool bShortSlotTime;
- unsigned int uInActiveCount;
- u16 wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
- u16 wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
- u16 wSuppRate;
- u8 byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
- u8 byTopCCKBasicRate; //Records the highest basic rate in CCK mode
-
- // For AP mode
- struct sk_buff_head sTxPSQueue;
- u16 wCapInfo;
- u16 wListenInterval;
- u16 wAID;
- NODE_STATE eNodeState;
- bool bPSEnable;
- bool bRxPSPoll;
- u8 byAuthSequence;
- unsigned long ulLastRxJiffer;
- u8 bySuppRate;
- u32 dwFlags;
- u16 wEnQueueCnt;
-
- bool bOnFly;
- unsigned long long KeyRSC;
- u8 byKeyIndex;
- u32 dwKeyIndex;
- u8 byCipherSuite;
- u32 dwTSC47_16;
- u16 wTSC15_0;
- unsigned int uWepKeyLength;
- u8 abyWepKey[WLAN_WEPMAX_KEYLEN];
- //
- // Auto rate fallback vars
- bool bIsInFallback;
- unsigned int uAverageRSSI;
- unsigned int uRateRecoveryTimeout;
- unsigned int uRatePollTimeout;
- unsigned int uTxFailures;
- unsigned int uTxAttempts;
-
- unsigned int uTxRetry;
- unsigned int uFailureRatio;
- unsigned int uRetryRatio;
- unsigned int uTxOk[MAX_RATE+1];
- unsigned int uTxFail[MAX_RATE+1];
- unsigned int uTimeCount;
-
-} KnownNodeDB, *PKnownNodeDB;
-
-PKnownBSS BSSpSearchBSSList(struct vnt_private *, u8 *pbyDesireBSSID,
- u8 *pbyDesireSSID, CARD_PHY_TYPE ePhyType);
-
-PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *, u8 *abyBSSID,
- PWLAN_IE_SSID pSSID);
-
-void BSSvClearBSSList(struct vnt_private *, int bKeepCurrBSSID);
-
-int BSSbInsertToBSSList(struct vnt_private *,
- u8 *abyBSSIDAddr,
- u64 qwTimestamp,
- u16 wBeaconInterval,
- u16 wCapInfo,
- u8 byCurrChannel,
- PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pSuppRates,
- PWLAN_IE_SUPP_RATES pExtSuppRates,
- PERPObject psERP,
- PWLAN_IE_RSN pRSN,
- PWLAN_IE_RSN_EXT pRSNWPA,
- PWLAN_IE_COUNTRY pIE_Country,
- PWLAN_IE_QUIET pIE_Quiet,
- u32 uIELength,
- u8 *pbyIEs,
- void *pRxPacketContext);
-
-int BSSbUpdateToBSSList(struct vnt_private *,
- u64 qwTimestamp,
- u16 wBeaconInterval,
- u16 wCapInfo,
- u8 byCurrChannel,
- int bChannelHit,
- PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pSuppRates,
- PWLAN_IE_SUPP_RATES pExtSuppRates,
- PERPObject psERP,
- PWLAN_IE_RSN pRSN,
- PWLAN_IE_RSN_EXT pRSNWPA,
- PWLAN_IE_COUNTRY pIE_Country,
- PWLAN_IE_QUIET pIE_Quiet,
- PKnownBSS pBSSList,
- u32 uIELength,
- u8 *pbyIEs,
- void *pRxPacketContext);
-
-int BSSbIsSTAInNodeDB(struct vnt_private *, u8 * abyDstAddr,
- u32 *puNodeIndex);
-
-void BSSvCreateOneNode(struct vnt_private *, u32 *puNodeIndex);
-
-void BSSvUpdateAPNode(struct vnt_private *, u16 *pwCapInfo,
- PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pExtSuppRates);
-
-void BSSvSecondCallBack(struct work_struct *work);
-
-void BSSvUpdateNodeTxCounter(struct vnt_private *, u8 byTSR, u8 byPktNO);
-
-void BSSvRemoveOneNode(struct vnt_private *, u32 uNodeIndex);
-
-void BSSvAddMulticastNode(struct vnt_private *);
-
-void BSSvClearNodeDBTable(struct vnt_private *, u32 uStartIndex);
-
-void BSSvClearAnyBSSJoinRecord(struct vnt_private *);
-
-#endif /* __BSSDB_H__ */
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index d662e5431dad..98567a7dc5b9 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -19,34 +19,27 @@
* File: card.c
* Purpose: Provide functions to setup NIC operation mode
* Functions:
- * s_vSafeResetTx - Rest Tx
- * CARDvSetRSPINF - Set RSPINF
- * vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
- * CARDvUpdateBasicTopRate - Update BasicTopRate
- * CARDbAddBasicRate - Add to BasicRateSet
- * CARDbSetBasicRate - Set Basic Tx Rate
- * CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
- * CARDvSetLoopbackMode - Set Loopback mode
- * CARDbSoftwareReset - Sortware reset NIC
- * CARDqGetTSFOffset - Calculate TSFOffset
- * CARDbGetCurrentTSF - Read Current NIC TSF counter
- * CARDqGetNextTBTT - Calculate Next Beacon TSF counter
- * CARDvSetFirstNextTBTT - Set NIC Beacon time
- * CARDvUpdateNextTBTT - Sync. NIC Beacon time
- * CARDbRadioPowerOff - Turn Off NIC Radio Power
- * CARDbRadioPowerOn - Turn On NIC Radio Power
- * CARDbSetWEPMode - Set NIC Wep mode
- * CARDbSetTxPower - Set NIC tx power
+ * vnt_set_rspinf - Set RSPINF
+ * vnt_update_ifs - Update slotTime,SIFS,DIFS, and EIFS
+ * vnt_update_top_rates - Update BasicTopRate
+ * vnt_add_basic_rate - Add to BasicRateSet
+ * vnt_ofdm_min_rate - Check if any OFDM rate is in BasicRateSet
+ * vnt_get_tsf_offset - Calculate TSFOffset
+ * vnt_get_current_tsf - Read Current NIC TSF counter
+ * vnt_get_next_tbtt - Calculate Next Beacon TSF counter
+ * vnt_reset_next_tbtt - Set NIC Beacon time
+ * vnt_update_next_tbtt - Sync. NIC Beacon time
+ * vnt_radio_power_off - Turn Off NIC Radio Power
+ * vnt_radio_power_on - Turn On NIC Radio Power
*
* Revision History:
* 06-10-2003 Bryan YC Fan: Re-write codes to support VT3253 spec.
* 08-26-2003 Kyle Hsu: Modify the definition type of dwIoBase.
- * 09-01-2003 Bryan YC Fan: Add vUpdateIFS().
+ * 09-01-2003 Bryan YC Fan: Add vnt_update_ifs().
*
*/
#include "device.h"
-#include "tmacro.h"
#include "card.h"
#include "baseband.h"
#include "mac.h"
@@ -54,16 +47,14 @@
#include "rf.h"
#include "power.h"
#include "key.h"
-#include "rc4.h"
-#include "country.h"
-#include "datarate.h"
#include "usbpipe.h"
-//const u16 cwRXBCNTSFOff[MAX_RATE] =
-//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
+/* const u16 cwRXBCNTSFOff[MAX_RATE] =
+ {17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3}; */
-static const u16 cwRXBCNTSFOff[MAX_RATE] =
-{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+static const u16 cwRXBCNTSFOff[MAX_RATE] = {
+ 192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3
+};
/*
* Description: Set NIC media channel
@@ -75,42 +66,21 @@ static const u16 cwRXBCNTSFOff[MAX_RATE] =
* Out:
* none
*/
-void CARDbSetMediaChannel(struct vnt_private *priv, u32 connection_channel)
+void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
{
- if (priv->byBBType == BB_TYPE_11A) {
- if ((connection_channel < (CB_MAX_CHANNEL_24G + 1)) ||
- (connection_channel > CB_MAX_CHANNEL))
- connection_channel = (CB_MAX_CHANNEL_24G + 1);
- } else {
- if ((connection_channel > CB_MAX_CHANNEL_24G) ||
- (connection_channel == 0))
- connection_channel = 1;
- }
+ if (connection_channel > CB_MAX_CHANNEL || !connection_channel)
+ return;
/* clear NAV */
- MACvRegBitsOn(priv, MAC_REG_MACCR, MACCR_CLRNAV);
+ vnt_mac_reg_bits_on(priv, MAC_REG_MACCR, MACCR_CLRNAV);
/* Set Channel[7] = 0 to tell H/W channel is changing now. */
- MACvRegBitsOff(priv, MAC_REG_CHANNEL, 0xb0);
+ vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);
vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE,
connection_channel, 0, 0, NULL);
- if (priv->byBBType == BB_TYPE_11A) {
- priv->byCurPwr = 0xff;
- vnt_rf_set_txpower(priv,
- priv->abyOFDMAPwrTbl[connection_channel-15], RATE_54M);
- } else if (priv->byBBType == BB_TYPE_11G) {
- priv->byCurPwr = 0xff;
- vnt_rf_set_txpower(priv,
- priv->abyOFDMPwrTbl[connection_channel-1], RATE_54M);
- } else {
- priv->byCurPwr = 0xff;
- vnt_rf_set_txpower(priv,
- priv->abyCCKPwrTbl[connection_channel-1], RATE_1M);
- }
-
vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
(u8)(connection_channel|0x80));
}
@@ -128,12 +98,12 @@ void CARDbSetMediaChannel(struct vnt_private *priv, u32 connection_channel)
* Return Value: response Control frame rate
*
*/
-static u16 swGetCCKControlRate(struct vnt_private *priv, u16 rate_idx)
+static u16 vnt_get_cck_rate(struct vnt_private *priv, u16 rate_idx)
{
u16 ui = rate_idx;
while (ui > RATE_1M) {
- if (priv->wBasicRate & (1 << ui))
+ if (priv->basic_rates & (1 << ui))
return ui;
ui--;
}
@@ -154,14 +124,14 @@ static u16 swGetCCKControlRate(struct vnt_private *priv, u16 rate_idx)
* Return Value: response Control frame rate
*
*/
-static u16 swGetOFDMControlRate(struct vnt_private *priv, u16 rate_idx)
+static u16 vnt_get_ofdm_rate(struct vnt_private *priv, u16 rate_idx)
{
u16 ui = rate_idx;
dev_dbg(&priv->usb->dev, "%s basic rate: %d\n",
- __func__, priv->wBasicRate);
+ __func__, priv->basic_rates);
- if (!CARDbIsOFDMinBasicRate(priv)) {
+ if (!vnt_ofdm_min_rate(priv)) {
dev_dbg(&priv->usb->dev, "%s (NO OFDM) %d\n",
__func__, rate_idx);
if (rate_idx > RATE_24M)
@@ -170,7 +140,7 @@ static u16 swGetOFDMControlRate(struct vnt_private *priv, u16 rate_idx)
}
while (ui > RATE_11M) {
- if (priv->wBasicRate & (1 << ui)) {
+ if (priv->basic_rates & (1 << ui)) {
dev_dbg(&priv->usb->dev, "%s rate: %d\n",
__func__, ui);
return ui;
@@ -197,7 +167,7 @@ static u16 swGetOFDMControlRate(struct vnt_private *priv, u16 rate_idx)
* Return Value: none
*
*/
-static void CARDvCalculateOFDMRParameter(u16 rate, u8 bb_type,
+static void vnt_calculate_ofdm_rate(u16 rate, u8 bb_type,
u8 *tx_rate, u8 *rsv_time)
{
@@ -291,7 +261,7 @@ static void CARDvCalculateOFDMRParameter(u16 rate, u8 bb_type,
*
*/
-void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
+void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type)
{
struct vnt_phy_field phy[4];
u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */
@@ -300,56 +270,51 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
int i;
/*RSPINF_b_1*/
- BBvCalculateParameter(priv, 14,
- swGetCCKControlRate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
+ vnt_get_phy_field(priv, 14,
+ vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]);
/*RSPINF_b_2*/
- BBvCalculateParameter(priv, 14,
- swGetCCKControlRate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
+ vnt_get_phy_field(priv, 14,
+ vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]);
/*RSPINF_b_5*/
- BBvCalculateParameter(priv, 14,
- swGetCCKControlRate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
+ vnt_get_phy_field(priv, 14,
+ vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]);
/*RSPINF_b_11*/
- BBvCalculateParameter(priv, 14,
- swGetCCKControlRate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
+ vnt_get_phy_field(priv, 14,
+ vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]);
/*RSPINF_a_6*/
- CARDvCalculateOFDMRParameter(RATE_6M, bb_type,
- &tx_rate[0], &rsv_time[0]);
+ vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]);
/*RSPINF_a_9*/
- CARDvCalculateOFDMRParameter(RATE_9M, bb_type,
- &tx_rate[1], &rsv_time[1]);
+ vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]);
/*RSPINF_a_12*/
- CARDvCalculateOFDMRParameter(RATE_12M, bb_type,
- &tx_rate[2], &rsv_time[2]);
+ vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]);
/*RSPINF_a_18*/
- CARDvCalculateOFDMRParameter(RATE_18M, bb_type,
- &tx_rate[3], &rsv_time[3]);
+ vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]);
/*RSPINF_a_24*/
- CARDvCalculateOFDMRParameter(RATE_24M, bb_type,
- &tx_rate[4], &rsv_time[4]);
+ vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]);
/*RSPINF_a_36*/
- CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_36M),
+ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M),
bb_type, &tx_rate[5], &rsv_time[5]);
/*RSPINF_a_48*/
- CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_48M),
+ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M),
bb_type, &tx_rate[6], &rsv_time[6]);
/*RSPINF_a_54*/
- CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
+ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
bb_type, &tx_rate[7], &rsv_time[7]);
/*RSPINF_a_72*/
- CARDvCalculateOFDMRParameter(swGetOFDMControlRate(priv, RATE_54M),
+ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M),
bb_type, &tx_rate[8], &rsv_time[8]);
put_unaligned(phy[0].len, (u16 *)&data[0]);
@@ -389,77 +354,83 @@ void CARDvSetRSPINF(struct vnt_private *priv, u8 bb_type)
* Return Value: None.
*
*/
-void vUpdateIFS(struct vnt_private *priv)
+void vnt_update_ifs(struct vnt_private *priv)
{
u8 max_min = 0;
u8 data[4];
- if (priv->byPacketType == PK_TYPE_11A) {
- priv->uSlot = C_SLOT_SHORT;
- priv->uSIFS = C_SIFS_A;
- priv->uDIFS = C_SIFS_A + 2 * C_SLOT_SHORT;
- priv->uCwMin = C_CWMIN_A;
+ if (priv->packet_type == PK_TYPE_11A) {
+ priv->slot = C_SLOT_SHORT;
+ priv->sifs = C_SIFS_A;
+ priv->difs = C_SIFS_A + 2 * C_SLOT_SHORT;
max_min = 4;
- } else if (priv->byPacketType == PK_TYPE_11B) {
- priv->uSlot = C_SLOT_LONG;
- priv->uSIFS = C_SIFS_BG;
- priv->uDIFS = C_SIFS_BG + 2 * C_SLOT_LONG;
- priv->uCwMin = C_CWMIN_B;
+ } else if (priv->packet_type == PK_TYPE_11B) {
+ priv->slot = C_SLOT_LONG;
+ priv->sifs = C_SIFS_BG;
+ priv->difs = C_SIFS_BG + 2 * C_SLOT_LONG;
max_min = 5;
} else {/* PK_TYPE_11GA & PK_TYPE_11GB */
- u8 rate = 0;
bool ofdm_rate = false;
unsigned int ii = 0;
- PWLAN_IE_SUPP_RATES item_rates = NULL;
- priv->uSIFS = C_SIFS_BG;
+ priv->sifs = C_SIFS_BG;
- if (priv->bShortSlotTime)
- priv->uSlot = C_SLOT_SHORT;
+ if (priv->short_slot_time)
+ priv->slot = C_SLOT_SHORT;
else
- priv->uSlot = C_SLOT_LONG;
-
- priv->uDIFS = C_SIFS_BG + 2 * priv->uSlot;
+ priv->slot = C_SLOT_LONG;
- item_rates =
- (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt.abyCurrSuppRates;
+ priv->difs = C_SIFS_BG + 2 * priv->slot;
- for (ii = 0; ii < item_rates->len; ii++) {
- rate = (u8)(item_rates->abyRates[ii] & 0x7f);
- if (RATEwGetRateIdx(rate) > RATE_11M) {
+ for (ii = RATE_54M; ii >= RATE_6M; ii--) {
+ if (priv->basic_rates & ((u32)(0x1 << ii))) {
ofdm_rate = true;
break;
}
}
- if (ofdm_rate == false) {
- item_rates = (PWLAN_IE_SUPP_RATES)priv->vnt_mgmt
- .abyCurrExtSuppRates;
- for (ii = 0; ii < item_rates->len; ii++) {
- rate = (u8)(item_rates->abyRates[ii] & 0x7f);
- if (RATEwGetRateIdx(rate) > RATE_11M) {
- ofdm_rate = true;
- break;
- }
- }
- }
-
- if (ofdm_rate == true) {
- priv->uCwMin = C_CWMIN_A;
+ if (ofdm_rate == true)
max_min = 4;
- } else {
- priv->uCwMin = C_CWMIN_B;
+ else
max_min = 5;
- }
}
- priv->uCwMax = C_CWMAX;
- priv->uEIFS = C_EIFS;
+ priv->eifs = C_EIFS;
- data[0] = (u8)priv->uSIFS;
- data[1] = (u8)priv->uDIFS;
- data[2] = (u8)priv->uEIFS;
- data[3] = (u8)priv->uSlot;
+ switch (priv->rf_type) {
+ case RF_VT3226D0:
+ if (priv->bb_type != BB_TYPE_11B) {
+ priv->sifs -= 1;
+ priv->difs -= 1;
+ break;
+ }
+ case RF_AIROHA7230:
+ case RF_AL2230:
+ case RF_AL2230S:
+ if (priv->bb_type != BB_TYPE_11B)
+ break;
+ case RF_RFMD2959:
+ case RF_VT3226:
+ case RF_VT3342A0:
+ priv->sifs -= 3;
+ priv->difs -= 3;
+ break;
+ case RF_MAXIM2829:
+ if (priv->bb_type == BB_TYPE_11A) {
+ priv->sifs -= 5;
+ priv->difs -= 5;
+ } else {
+ priv->sifs -= 2;
+ priv->difs -= 2;
+ }
+
+ break;
+ }
+
+ data[0] = (u8)priv->sifs;
+ data[1] = (u8)priv->difs;
+ data[2] = (u8)priv->eifs;
+ data[3] = (u8)priv->slot;
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_SIFS,
MESSAGE_REQUEST_MACREG, 4, &data[0]);
@@ -470,23 +441,23 @@ void vUpdateIFS(struct vnt_private *priv)
MESSAGE_REQUEST_MACREG, 1, &max_min);
}
-void CARDvUpdateBasicTopRate(struct vnt_private *priv)
+void vnt_update_top_rates(struct vnt_private *priv)
{
u8 top_ofdm = RATE_24M, top_cck = RATE_1M;
u8 i;
/*Determines the highest basic rate.*/
for (i = RATE_54M; i >= RATE_6M; i--) {
- if (priv->wBasicRate & (u16)(1 << i)) {
+ if (priv->basic_rates & (u16)(1 << i)) {
top_ofdm = i;
break;
}
}
- priv->byTopOFDMBasicRate = top_ofdm;
+ priv->top_ofdm_basic_rate = top_ofdm;
for (i = RATE_11M;; i--) {
- if (priv->wBasicRate & (u16)(1 << i)) {
+ if (priv->basic_rates & (u16)(1 << i)) {
top_cck = i;
break;
}
@@ -494,49 +465,27 @@ void CARDvUpdateBasicTopRate(struct vnt_private *priv)
break;
}
- priv->byTopCCKBasicRate = top_cck;
- }
-
-/*
- * Description: Set NIC Tx Basic Rate
- *
- * Parameters:
- * In:
- * pDevice - The adapter to be set
- * wBasicRate - Basic Rate to be set
- * Out:
- * none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
-void CARDbAddBasicRate(struct vnt_private *priv, u16 rate_idx)
-{
-
- priv->wBasicRate |= (1 << rate_idx);
-
- /*Determines the highest basic rate.*/
- CARDvUpdateBasicTopRate(priv);
+ priv->top_cck_basic_rate = top_cck;
}
-int CARDbIsOFDMinBasicRate(struct vnt_private *priv)
+int vnt_ofdm_min_rate(struct vnt_private *priv)
{
int ii;
for (ii = RATE_54M; ii >= RATE_6M; ii--) {
- if ((priv->wBasicRate) & ((u16)(1 << ii)))
+ if ((priv->basic_rates) & ((u16)(1 << ii)))
return true;
}
return false;
}
-u8 CARDbyGetPktType(struct vnt_private *priv)
+u8 vnt_get_pkt_type(struct vnt_private *priv)
{
- if (priv->byBBType == BB_TYPE_11A || priv->byBBType == BB_TYPE_11B)
- return (u8)priv->byBBType;
- else if (CARDbIsOFDMinBasicRate(priv))
+ if (priv->bb_type == BB_TYPE_11A || priv->bb_type == BB_TYPE_11B)
+ return (u8)priv->bb_type;
+ else if (vnt_ofdm_min_rate(priv))
return PK_TYPE_11GA;
else
return PK_TYPE_11GB;
@@ -557,7 +506,7 @@ u8 CARDbyGetPktType(struct vnt_private *priv)
* Return Value: TSF Offset value
*
*/
-u64 CARDqGetTSFOffset(u8 rx_rate, u64 tsf1, u64 tsf2)
+u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2)
{
u64 tsf_offset = 0;
u16 rx_bcn_offset = 0;
@@ -586,13 +535,13 @@ u64 CARDqGetTSFOffset(u8 rx_rate, u64 tsf1, u64 tsf2)
* Return Value: none
*
*/
-void CARDvAdjustTSF(struct vnt_private *priv, u8 rx_rate,
+void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
u64 time_stamp, u64 local_tsf)
{
u64 tsf_offset = 0;
u8 data[8];
- tsf_offset = CARDqGetTSFOffset(rx_rate, time_stamp, local_tsf);
+ tsf_offset = vnt_get_tsf_offset(rx_rate, time_stamp, local_tsf);
data[0] = (u8)tsf_offset;
data[1] = (u8)(tsf_offset >> 8);
@@ -619,10 +568,10 @@ void CARDvAdjustTSF(struct vnt_private *priv, u8 rx_rate,
* Return Value: true if success; otherwise false
*
*/
-bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *current_tsf)
+bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf)
{
- *current_tsf = priv->qwCurrTSF;
+ *current_tsf = priv->current_tsf;
return true;
}
@@ -638,12 +587,12 @@ bool CARDbGetCurrentTSF(struct vnt_private *priv, u64 *current_tsf)
* Return Value: true if success; otherwise false
*
*/
-bool CARDbClearCurrentTSF(struct vnt_private *priv)
+bool vnt_clear_current_tsf(struct vnt_private *priv)
{
- MACvRegBitsOn(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
+ vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
- priv->qwCurrTSF = 0;
+ priv->current_tsf = 0;
return true;
}
@@ -662,7 +611,7 @@ bool CARDbClearCurrentTSF(struct vnt_private *priv)
* Return Value: TSF value of next Beacon
*
*/
-u64 CARDqGetNextTBTT(u64 tsf, u16 beacon_interval)
+u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval)
{
u32 beacon_int;
@@ -694,14 +643,14 @@ u64 CARDqGetNextTBTT(u64 tsf, u16 beacon_interval)
* Return Value: none
*
*/
-void CARDvSetFirstNextTBTT(struct vnt_private *priv, u16 beacon_interval)
+void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval)
{
u64 next_tbtt = 0;
u8 data[8];
- CARDbClearCurrentTSF(priv);
+ vnt_clear_current_tsf(priv);
- next_tbtt = CARDqGetNextTBTT(next_tbtt, beacon_interval);
+ next_tbtt = vnt_get_next_tbtt(next_tbtt, beacon_interval);
data[0] = (u8)next_tbtt;
data[1] = (u8)(next_tbtt >> 8);
@@ -714,8 +663,6 @@ void CARDvSetFirstNextTBTT(struct vnt_private *priv, u16 beacon_interval)
vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
MESSAGE_REQUEST_TBTT, 0, 8, data);
-
- return;
}
/*
@@ -733,12 +680,12 @@ void CARDvSetFirstNextTBTT(struct vnt_private *priv, u16 beacon_interval)
* Return Value: none
*
*/
-void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 tsf,
+void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
u16 beacon_interval)
{
u8 data[8];
- tsf = CARDqGetNextTBTT(tsf, beacon_interval);
+ tsf = vnt_get_next_tbtt(tsf, beacon_interval);
data[0] = (u8)tsf;
data[1] = (u8)(tsf >> 8);
@@ -750,11 +697,9 @@ void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 tsf,
data[7] = (u8)(tsf >> 56);
vnt_control_out(priv, MESSAGE_TYPE_SET_TSFTBTT,
- MESSAGE_REQUEST_TBTT, 0, 8, data);
+ MESSAGE_REQUEST_TBTT, 0, 8, data);
dev_dbg(&priv->usb->dev, "%s TBTT: %8llx\n", __func__, tsf);
-
- return;
}
/*
@@ -769,27 +714,27 @@ void CARDvUpdateNextTBTT(struct vnt_private *priv, u64 tsf,
* Return Value: true if success; otherwise false
*
*/
-int CARDbRadioPowerOff(struct vnt_private *priv)
+int vnt_radio_power_off(struct vnt_private *priv)
{
int ret = true;
- priv->bRadioOff = true;
-
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
case RF_AL2230S:
case RF_AIROHA7230:
case RF_VT3226:
case RF_VT3226D0:
case RF_VT3342A0:
- MACvRegBitsOff(priv, MAC_REG_SOFTPWRCTL,
+ vnt_mac_reg_bits_off(priv, MAC_REG_SOFTPWRCTL,
(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
break;
}
- MACvRegBitsOff(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
+ vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+ vnt_set_deep_sleep(priv);
- BBvSetDeepSleep(priv);
+ vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
return ret;
}
@@ -806,72 +751,71 @@ int CARDbRadioPowerOff(struct vnt_private *priv)
* Return Value: true if success; otherwise false
*
*/
-int CARDbRadioPowerOn(struct vnt_private *priv)
+int vnt_radio_power_on(struct vnt_private *priv)
{
int ret = true;
- if (priv->bHWRadioOff == true || priv->bRadioControlOff == true)
- return false;
-
- priv->bRadioOff = false;
+ vnt_exit_deep_sleep(priv);
- BBvExitDeepSleep(priv);
+ vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
- MACvRegBitsOn(priv, MAC_REG_HOSTCR, HOSTCR_RXON);
-
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
case RF_AL2230S:
case RF_AIROHA7230:
case RF_VT3226:
case RF_VT3226D0:
case RF_VT3342A0:
- MACvRegBitsOn(priv, MAC_REG_SOFTPWRCTL,
+ vnt_mac_reg_bits_on(priv, MAC_REG_SOFTPWRCTL,
(SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
break;
}
+ vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1, GPIO3_INTMD);
+
return ret;
}
-void CARDvSetBSSMode(struct vnt_private *priv)
+void vnt_set_bss_mode(struct vnt_private *priv)
{
- if (priv->byRFType == RF_AIROHA7230 && priv->byBBType == BB_TYPE_11A)
- MACvSetBBType(priv, BB_TYPE_11G);
+ if (priv->rf_type == RF_AIROHA7230 && priv->bb_type == BB_TYPE_11A)
+ vnt_mac_set_bb_type(priv, BB_TYPE_11G);
else
- MACvSetBBType(priv, priv->byBBType);
+ vnt_mac_set_bb_type(priv, priv->bb_type);
- priv->byPacketType = CARDbyGetPktType(priv);
+ priv->packet_type = vnt_get_pkt_type(priv);
- if (priv->byBBType == BB_TYPE_11A)
+ if (priv->bb_type == BB_TYPE_11A)
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
- else if (priv->byBBType == BB_TYPE_11B)
+ else if (priv->bb_type == BB_TYPE_11B)
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
- else if (priv->byBBType == BB_TYPE_11G)
+ else if (priv->bb_type == BB_TYPE_11G)
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
- vUpdateIFS(priv);
- CARDvSetRSPINF(priv, (u8)priv->byBBType);
+ vnt_update_ifs(priv);
+ vnt_set_rspinf(priv, (u8)priv->bb_type);
- if (priv->byBBType == BB_TYPE_11A) {
- if (priv->byRFType == RF_AIROHA7230) {
- priv->abyBBVGA[0] = 0x20;
+ if (priv->bb_type == BB_TYPE_11A) {
+ if (priv->rf_type == RF_AIROHA7230) {
+ priv->bb_vga[0] = 0x20;
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
- 0xe7, priv->abyBBVGA[0]);
+ 0xe7, priv->bb_vga[0]);
}
- priv->abyBBVGA[2] = 0x10;
- priv->abyBBVGA[3] = 0x10;
+ priv->bb_vga[2] = 0x10;
+ priv->bb_vga[3] = 0x10;
} else {
- if (priv->byRFType == RF_AIROHA7230) {
- priv->abyBBVGA[0] = 0x1c;
+ if (priv->rf_type == RF_AIROHA7230) {
+ priv->bb_vga[0] = 0x1c;
vnt_control_out_u8(priv, MESSAGE_REQUEST_BBREG,
- 0xe7, priv->abyBBVGA[0]);
+ 0xe7, priv->bb_vga[0]);
}
- priv->abyBBVGA[2] = 0x0;
- priv->abyBBVGA[3] = 0x0;
+ priv->bb_vga[2] = 0x0;
+ priv->bb_vga[3] = 0x0;
}
+
+ vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
}
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
index ac734714c7d1..03fc1678896b 100644
--- a/drivers/staging/vt6656/card.h
+++ b/drivers/staging/vt6656/card.h
@@ -32,37 +32,27 @@
/* init card type */
-typedef enum _CARD_PHY_TYPE {
- PHY_TYPE_AUTO = 0,
- PHY_TYPE_11B,
- PHY_TYPE_11G,
- PHY_TYPE_11A
-} CARD_PHY_TYPE, *PCARD_PHY_TYPE;
-
-#define CB_MAX_CHANNEL_24G 14
-#define CB_MAX_CHANNEL_5G 42 /* add channel9(5045MHz), 41==>42 */
-#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
+#define CB_MAX_CHANNEL_24G 14
+#define CB_MAX_CHANNEL_5G 42 /* add channel9(5045MHz), 41==>42 */
+#define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G + CB_MAX_CHANNEL_5G)
struct vnt_private;
-void CARDbSetMediaChannel(struct vnt_private *pDevice, u32 uConnectionChannel);
-void CARDvSetRSPINF(struct vnt_private *, u8);
-void vUpdateIFS(struct vnt_private *);
-void CARDvUpdateBasicTopRate(struct vnt_private *);
-void CARDbAddBasicRate(struct vnt_private *, u16);
-int CARDbIsOFDMinBasicRate(struct vnt_private *pDevice);
-void CARDvAdjustTSF(struct vnt_private *pDevice, u8 byRxRate,
- u64 qwBSSTimestamp, u64 qwLocalTSF);
-bool CARDbGetCurrentTSF(struct vnt_private *pDevice, u64 *pqwCurrTSF);
-bool CARDbClearCurrentTSF(struct vnt_private *pDevice);
-void CARDvSetFirstNextTBTT(struct vnt_private *pDevice, u16 wBeaconInterval);
-void CARDvUpdateNextTBTT(struct vnt_private *pDevice, u64 qwTSF,
- u16 wBeaconInterval);
-u64 CARDqGetNextTBTT(u64 qwTSF, u16 wBeaconInterval);
-u64 CARDqGetTSFOffset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2);
-int CARDbRadioPowerOff(struct vnt_private *pDevice);
-int CARDbRadioPowerOn(struct vnt_private *pDevice);
-u8 CARDbyGetPktType(struct vnt_private *pDevice);
-void CARDvSetBSSMode(struct vnt_private *pDevice);
+void vnt_set_channel(struct vnt_private *, u32);
+void vnt_set_rspinf(struct vnt_private *, u8);
+void vnt_update_ifs(struct vnt_private *);
+void vnt_update_top_rates(struct vnt_private *);
+int vnt_ofdm_min_rate(struct vnt_private *);
+void vnt_adjust_tsf(struct vnt_private *, u8, u64, u64);
+bool vnt_get_current_tsf(struct vnt_private *, u64 *);
+bool vnt_clear_current_tsf(struct vnt_private *);
+void vnt_reset_next_tbtt(struct vnt_private *, u16);
+void vnt_update_next_tbtt(struct vnt_private *, u64, u16);
+u64 vnt_get_next_tbtt(u64, u16);
+u64 vnt_get_tsf_offset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2);
+int vnt_radio_power_off(struct vnt_private *);
+int vnt_radio_power_on(struct vnt_private *);
+u8 vnt_get_pkt_type(struct vnt_private *);
+void vnt_set_bss_mode(struct vnt_private *);
#endif /* __CARD_H__ */
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
index 5a4fa0e2581b..8412d0532fb2 100644
--- a/drivers/staging/vt6656/channel.c
+++ b/drivers/staging/vt6656/channel.c
@@ -28,446 +28,151 @@
*
*
* Revision History:
- * 01-18-2005 RobertYu: remove the for loop searching in ChannelValid,
- * change ChannelRuleTab to lookup-type, reorder table items.
+ * 01-18-2005 RobertYu: remove the for loop searching in
+ * ChannelValid, change ChannelRuleTab
+ * to lookup-type, reorder table items.
*
*
*/
-#include <linux/kernel.h>
-#include "country.h"
+#include "device.h"
#include "channel.h"
#include "rf.h"
-static int msglevel = MSG_LEVEL_INFO;
-//static int msglevel =MSG_LEVEL_DEBUG;
-
-static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] =
-{
- {0, 0, false},
- {1, 2412, true},
- {2, 2417, true},
- {3, 2422, true},
- {4, 2427, true},
- {5, 2432, true},
- {6, 2437, true},
- {7, 2442, true},
- {8, 2447, true},
- {9, 2452, true},
- {10, 2457, true},
- {11, 2462, true},
- {12, 2467, true},
- {13, 2472, true},
- {14, 2484, true},
- {183, 4915, true}, //15
- {184, 4920, true}, //16
- {185, 4925, true}, //17
- {187, 4935, true}, //18
- {188, 4940, true}, //19
- {189, 4945, true}, //20
- {192, 4960, true}, //21
- {196, 4980, true}, //22
- {7, 5035, true}, //23
- {8, 5040, true}, //24
- {9, 5045, true}, //25
- {11, 5055, true}, //26
- {12, 5060, true}, //27
- {16, 5080, true}, //28
- {34, 5170, true}, //29
- {36, 5180, true}, //30
- {38, 5190, true}, //31
- {40, 5200, true}, //32
- {42, 5210, true}, //33
- {44, 5220, true}, //34
- {46, 5230, true}, //35
- {48, 5240, true}, //36
- {52, 5260, true}, //37
- {56, 5280, true}, //38
- {60, 5300, true}, //39
- {64, 5320, true}, //40
- {100, 5500, true}, //41
- {104, 5520, true}, //42
- {108, 5540, true}, //43
- {112, 5560, true}, //44
- {116, 5580, true}, //45
- {120, 5600, true}, //46
- {124, 5620, true}, //47
- {128, 5640, true}, //48
- {132, 5660, true}, //49
- {136, 5680, true}, //50
- {140, 5700, true}, //51
- {149, 5745, true}, //52
- {153, 5765, true}, //53
- {157, 5785, true}, //54
- {161, 5805, true}, //55
- {165, 5825, true} //56
+static struct ieee80211_rate vnt_rates_bg[] = {
+ { .bitrate = 10, .hw_value = RATE_1M },
+ { .bitrate = 20, .hw_value = RATE_2M },
+ { .bitrate = 55, .hw_value = RATE_5M },
+ { .bitrate = 110, .hw_value = RATE_11M },
+ { .bitrate = 60, .hw_value = RATE_6M },
+ { .bitrate = 90, .hw_value = RATE_9M },
+ { .bitrate = 120, .hw_value = RATE_12M },
+ { .bitrate = 180, .hw_value = RATE_18M },
+ { .bitrate = 240, .hw_value = RATE_24M },
+ { .bitrate = 360, .hw_value = RATE_36M },
+ { .bitrate = 480, .hw_value = RATE_48M },
+ { .bitrate = 540, .hw_value = RATE_54M },
};
-/************************************************************************
- * The Radar regulation rules for each country
- ************************************************************************/
-static struct
-{
- u8 byChannelCountryCode; /* The country code */
- char chCountryCode[2];
- u8 bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */
- u8 byPower[CB_MAX_CHANNEL];
-} ChannelRuleTab[] =
-{
-/************************************************************************
- * This table is based on Athero driver rules
- ************************************************************************/
-/* Country Available channels, ended with 0 */
-/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */
-{CCODE_FCC, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_TELEC, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 23, 0, 0, 23, 0, 23, 23, 0, 23, 0, 0, 23, 23, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ETSI, {'E','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_RESV3, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV4, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV5, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV6, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV7, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV8, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESV9, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESVa, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESVb, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESVc, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESVd, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RESVe, {' ',' '}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ALLBAND, {' ',' '}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ALBANIA, {'A','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ALGERIA, {'D','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ARGENTINA, {'A','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} },
-{CCODE_ARMENIA, {'A','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_AUSTRALIA, {'A','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_AUSTRIA, {'A','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_AZERBAIJAN, {'A','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_BAHRAIN, {'B','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_BELARUS, {'B','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_BELGIUM, {'B','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_BELIZE, {'B','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_BOLIVIA, {'B','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_BRAZIL, {'B','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_BRUNEI_DARUSSALAM, {'B','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_BULGARIA, {'B','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 0, 0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0} },
-{CCODE_CANADA, {'C','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_CHILE, {'C','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17} },
-{CCODE_CHINA, {'C','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_COLOMBIA, {'C','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_COSTA_RICA, {'C','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_CROATIA, {'H','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_CYPRUS, {'C','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_CZECH, {'C','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_DENMARK, {'D','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_DOMINICAN_REPUBLIC, {'D','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_ECUADOR, {'E','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_EGYPT, {'E','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_EL_SALVADOR, {'S','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ESTONIA, {'E','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_FINLAND, {'F','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_FRANCE, {'F','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_GERMANY, {'D','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_GREECE, {'G','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_GEORGIA, {'G','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_GUATEMALA, {'G','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_HONDURAS, {'H','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_HONG_KONG, {'H','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_HUNGARY, {'H','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ICELAND, {'I','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_INDIA, {'I','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_INDONESIA, {'I','D'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_IRAN, {'I','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_IRELAND, {'I','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_ITALY, {'I','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_ISRAEL, {'I','L'}, { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_JAPAN, {'J','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_JORDAN, {'J','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_KAZAKHSTAN, {'K','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_KUWAIT, {'K','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_LATVIA, {'L','V'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_LEBANON, {'L','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_LEICHTENSTEIN, {'L','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_LITHUANIA, {'L','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_LUXEMBURG, {'L','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_MACAU, {'M','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_MACEDONIA, {'M','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_MALTA, {'M','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
-{CCODE_MALAYSIA, {'M','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_MEXICO, {'M','X'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_MONACO, {'M','C'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_MOROCCO, {'M','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_NETHERLANDS, {'N','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_NEW_ZEALAND, {'N','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 23, 0, 23, 0, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_NORTH_KOREA, {'K','P'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
-{CCODE_NORWAY, {'N','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_OMAN, {'O','M'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_PAKISTAN, {'P','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_PANAMA, {'P','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_PERU, {'P','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_PHILIPPINES, {'P','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_POLAND, {'P','L'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_PORTUGAL, {'P','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_PUERTO_RICO, {'P','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_QATAR, {'Q','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ROMANIA, {'R','O'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_RUSSIA, {'R','U'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_SAUDI_ARABIA, {'S','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_SINGAPORE, {'S','G'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20} },
-{CCODE_SLOVAKIA, {'S','K'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
-{CCODE_SLOVENIA, {'S','I'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_SOUTH_AFRICA, {'Z','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_SOUTH_KOREA, {'K','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
-{CCODE_SPAIN, {'E','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 16, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0} },
-{CCODE_SWEDEN, {'S','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_SWITZERLAND, {'C','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_SYRIA, {'S','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_TAIWAN, {'T','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 0} },
-{CCODE_THAILAND, {'T','H'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
-{CCODE_TRINIDAD_TOBAGO, {'T','T'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 18, 0, 18, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_TUNISIA, {'T','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_TURKEY, {'T','R'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_UK, {'G','B'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 20, 0, 20, 0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0} },
-{CCODE_UKRAINE, {'U','A'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_UNITED_ARAB_EMIRATES, {'A','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_UNITED_STATES, {'U','S'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
- , { 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 17, 0, 17, 0, 17, 23, 23, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 30, 30, 30, 30} },
-{CCODE_URUGUAY, {'U','Y'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
-{CCODE_UZBEKISTAN, {'U','Z'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_VENEZUELA, {'V','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}
- , { 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 0} },
-{CCODE_VIETNAM, {'V','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_YEMEN, {'Y','E'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_ZIMBABWE, {'Z','W'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_JAPAN_W52_W53, {'J','J'}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
-{CCODE_MAX, {'U','N'}, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
- , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
-/* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 */
+static struct ieee80211_rate vnt_rates_a[] = {
+ { .bitrate = 60, .hw_value = RATE_6M },
+ { .bitrate = 90, .hw_value = RATE_9M },
+ { .bitrate = 120, .hw_value = RATE_12M },
+ { .bitrate = 180, .hw_value = RATE_18M },
+ { .bitrate = 240, .hw_value = RATE_24M },
+ { .bitrate = 360, .hw_value = RATE_36M },
+ { .bitrate = 480, .hw_value = RATE_48M },
+ { .bitrate = 540, .hw_value = RATE_54M },
};
-/************************************************************************
- * Country Channel Valid
- * Input: CountryCode, ChannelNum
- * ChanneIndex is defined as VT3253 MAC channel:
- * 1 = 2.4G channel 1
- * 2 = 2.4G channel 2
- * ...
- * 14 = 2.4G channel 14
- * 15 = 4.9G channel 183
- * 16 = 4.9G channel 184
- * .....
- * Output: true if the specified 5GHz band is allowed to be used.
- False otherwise.
-// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
-
-// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
-// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- ************************************************************************/
-bool
-ChannelValid(unsigned int CountryCode, unsigned int ChannelIndex)
-{
- bool bValid;
-
- bValid = false;
- /*
- * If Channel Index is invalid, return invalid
- */
- if ((ChannelIndex > CB_MAX_CHANNEL) ||
- (ChannelIndex == 0))
- {
- bValid = false;
- goto exit;
- }
+static struct ieee80211_channel vnt_channels_2ghz[] = {
+ { .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 }
+};
- bValid = sChannelTbl[ChannelIndex].bValid;
+static struct ieee80211_channel vnt_channels_5ghz[] = {
+ { .center_freq = 4915, .hw_value = 15 },
+ { .center_freq = 4920, .hw_value = 16 },
+ { .center_freq = 4925, .hw_value = 17 },
+ { .center_freq = 4935, .hw_value = 18 },
+ { .center_freq = 4940, .hw_value = 19 },
+ { .center_freq = 4945, .hw_value = 20 },
+ { .center_freq = 4960, .hw_value = 21 },
+ { .center_freq = 4980, .hw_value = 22 },
+ { .center_freq = 5035, .hw_value = 23 },
+ { .center_freq = 5040, .hw_value = 24 },
+ { .center_freq = 5045, .hw_value = 25 },
+ { .center_freq = 5055, .hw_value = 26 },
+ { .center_freq = 5060, .hw_value = 27 },
+ { .center_freq = 5080, .hw_value = 28 },
+ { .center_freq = 5170, .hw_value = 29 },
+ { .center_freq = 5180, .hw_value = 30 },
+ { .center_freq = 5190, .hw_value = 31 },
+ { .center_freq = 5200, .hw_value = 32 },
+ { .center_freq = 5210, .hw_value = 33 },
+ { .center_freq = 5220, .hw_value = 34 },
+ { .center_freq = 5230, .hw_value = 35 },
+ { .center_freq = 5240, .hw_value = 36 },
+ { .center_freq = 5260, .hw_value = 37 },
+ { .center_freq = 5280, .hw_value = 38 },
+ { .center_freq = 5300, .hw_value = 39 },
+ { .center_freq = 5320, .hw_value = 40 },
+ { .center_freq = 5500, .hw_value = 41 },
+ { .center_freq = 5520, .hw_value = 42 },
+ { .center_freq = 5540, .hw_value = 43 },
+ { .center_freq = 5560, .hw_value = 44 },
+ { .center_freq = 5580, .hw_value = 45 },
+ { .center_freq = 5600, .hw_value = 46 },
+ { .center_freq = 5620, .hw_value = 47 },
+ { .center_freq = 5640, .hw_value = 48 },
+ { .center_freq = 5660, .hw_value = 49 },
+ { .center_freq = 5680, .hw_value = 50 },
+ { .center_freq = 5700, .hw_value = 51 },
+ { .center_freq = 5745, .hw_value = 52 },
+ { .center_freq = 5765, .hw_value = 53 },
+ { .center_freq = 5785, .hw_value = 54 },
+ { .center_freq = 5805, .hw_value = 55 },
+ { .center_freq = 5825, .hw_value = 56 }
+};
-exit:
- return (bValid);
+static struct ieee80211_supported_band vnt_supported_2ghz_band = {
+ .channels = vnt_channels_2ghz,
+ .n_channels = ARRAY_SIZE(vnt_channels_2ghz),
+ .bitrates = vnt_rates_bg,
+ .n_bitrates = ARRAY_SIZE(vnt_rates_bg),
+};
-} /* end ChannelValid */
+static struct ieee80211_supported_band vnt_supported_5ghz_band = {
+ .channels = vnt_channels_5ghz,
+ .n_channels = ARRAY_SIZE(vnt_channels_5ghz),
+ .bitrates = vnt_rates_a,
+ .n_bitrates = ARRAY_SIZE(vnt_rates_a),
+};
-void CHvInitChannelTable(struct vnt_private *pDevice)
+void vnt_init_bands(struct vnt_private *priv)
{
- bool bMultiBand = false;
- int ii;
-
- for (ii = 1; ii <= CB_MAX_CHANNEL; ii++)
- sChannelTbl[ii].bValid = false;
+ struct ieee80211_channel *ch;
+ int i;
- switch (pDevice->byRFType) {
- case RF_AL2230:
- case RF_AL2230S:
- case RF_VT3226:
- case RF_VT3226D0:
- bMultiBand = false;
- break;
- case RF_AIROHA7230:
- case RF_VT3342A0:
- default :
- bMultiBand = true;
- break;
- }
+ switch (priv->rf_type) {
+ case RF_AIROHA7230:
+ case RF_VT3342A0:
+ default:
+ ch = vnt_channels_5ghz;
- if (pDevice->b11hEable == true) {
- if (bMultiBand == true) {
- for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
- sChannelTbl[ii+1].bValid = true;
- //pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
- //pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
- }
- for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
- //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
- //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
- }
- } else {
- for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
- sChannelTbl[ii+1].bValid = true;
- //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
- //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+ for (i = 0; i < ARRAY_SIZE(vnt_channels_5ghz); i++) {
+ ch[i].max_power = VNT_RF_MAX_POWER;
+ ch[i].flags = IEEE80211_CHAN_NO_HT40;
}
- }
- } else if (pDevice->byZoneType <= CCODE_MAX) {
- if (bMultiBand == true) {
- for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
- if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
- sChannelTbl[ii+1].bValid = true;
- //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
- //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
- }
- }
- } else {
- for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) {
- if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
- sChannelTbl[ii+1].bValid = true;
- //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
- //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
- }
+
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &vnt_supported_5ghz_band;
+ /* fallthrough */
+ case RF_AL2230:
+ case RF_AL2230S:
+ case RF_VT3226:
+ case RF_VT3226D0:
+ ch = vnt_channels_2ghz;
+
+ for (i = 0; i < ARRAY_SIZE(vnt_channels_2ghz); i++) {
+ ch[i].max_power = VNT_RF_MAX_POWER;
+ ch[i].flags = IEEE80211_CHAN_NO_HT40;
}
- }
- }
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
- for (ii = 0; ii < CB_MAX_CHANNEL; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Channel[%d] is [%d]\n",sChannelTbl[ii].byChannelNumber,sChannelTbl[ii+1].bValid);
- /*if (pDevice->abyRegPwr[ii+1] == 0) {
- pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
- }
- if (pDevice->abyLocalPwr[ii+1] == 0) {
- pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
- }*/
- }
+
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &vnt_supported_2ghz_band;
+ break;
+ }
}
diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h
index 95701e0cbee3..21c080803714 100644
--- a/drivers/staging/vt6656/channel.h
+++ b/drivers/staging/vt6656/channel.h
@@ -32,13 +32,6 @@
#include "device.h"
-typedef struct tagSChannelTblElement {
- u8 byChannelNumber;
- unsigned int uFrequency;
- bool bValid;
-} SChannelTblElement, *PSChannelTblElement;
-
-bool ChannelValid(unsigned int CountryCode, unsigned int ChannelNum);
-void CHvInitChannelTable(struct vnt_private *pDevice);
+void vnt_init_bands(struct vnt_private *);
#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6656/country.h b/drivers/staging/vt6656/country.h
deleted file mode 100644
index a0320d8f1362..000000000000
--- a/drivers/staging/vt6656/country.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: country.h
- *
- * Purpose: Country Code information
- *
- * Author: Lucas Lin
- *
- * Date: Dec 23, 2004
- *
- */
-
-#ifndef __COUNTRY_H__
-#define __COUNTRY_H__
-
-/************************************************************************
- * The definition here should be complied with the INF country order
- * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf
- ************************************************************************/
-typedef enum _COUNTRY_CODE {
- CCODE_FCC = 0,
- CCODE_TELEC,
- CCODE_ETSI,
- CCODE_RESV3,
- CCODE_RESV4,
- CCODE_RESV5,
- CCODE_RESV6,
- CCODE_RESV7,
- CCODE_RESV8,
- CCODE_RESV9,
- CCODE_RESVa,
- CCODE_RESVb,
- CCODE_RESVc,
- CCODE_RESVd,
- CCODE_RESVe,
- CCODE_ALLBAND,
- CCODE_ALBANIA,
- CCODE_ALGERIA,
- CCODE_ARGENTINA,
- CCODE_ARMENIA,
- CCODE_AUSTRALIA,
- CCODE_AUSTRIA,
- CCODE_AZERBAIJAN,
- CCODE_BAHRAIN,
- CCODE_BELARUS,
- CCODE_BELGIUM,
- CCODE_BELIZE,
- CCODE_BOLIVIA,
- CCODE_BRAZIL,
- CCODE_BRUNEI_DARUSSALAM,
- CCODE_BULGARIA,
- CCODE_CANADA,
- CCODE_CHILE,
- CCODE_CHINA,
- CCODE_COLOMBIA,
- CCODE_COSTA_RICA,
- CCODE_CROATIA,
- CCODE_CYPRUS,
- CCODE_CZECH,
- CCODE_DENMARK,
- CCODE_DOMINICAN_REPUBLIC,
- CCODE_ECUADOR,
- CCODE_EGYPT,
- CCODE_EL_SALVADOR,
- CCODE_ESTONIA,
- CCODE_FINLAND,
- CCODE_FRANCE,
- CCODE_GERMANY,
- CCODE_GREECE,
- CCODE_GEORGIA,
- CCODE_GUATEMALA,
- CCODE_HONDURAS,
- CCODE_HONG_KONG,
- CCODE_HUNGARY,
- CCODE_ICELAND,
- CCODE_INDIA,
- CCODE_INDONESIA,
- CCODE_IRAN,
- CCODE_IRELAND,
- CCODE_ITALY,
- CCODE_ISRAEL,
- CCODE_JAPAN,
- CCODE_JORDAN,
- CCODE_KAZAKHSTAN,
- CCODE_KUWAIT,
- CCODE_LATVIA,
- CCODE_LEBANON,
- CCODE_LEICHTENSTEIN,
- CCODE_LITHUANIA,
- CCODE_LUXEMBURG,
- CCODE_MACAU,
- CCODE_MACEDONIA,
- CCODE_MALTA,
- CCODE_MALAYSIA,
- CCODE_MEXICO,
- CCODE_MONACO,
- CCODE_MOROCCO,
- CCODE_NETHERLANDS,
- CCODE_NEW_ZEALAND,
- CCODE_NORTH_KOREA,
- CCODE_NORWAY,
- CCODE_OMAN,
- CCODE_PAKISTAN,
- CCODE_PANAMA,
- CCODE_PERU,
- CCODE_PHILIPPINES,
- CCODE_POLAND,
- CCODE_PORTUGAL,
- CCODE_PUERTO_RICO,
- CCODE_QATAR,
- CCODE_ROMANIA,
- CCODE_RUSSIA,
- CCODE_SAUDI_ARABIA,
- CCODE_SINGAPORE,
- CCODE_SLOVAKIA,
- CCODE_SLOVENIA,
- CCODE_SOUTH_AFRICA,
- CCODE_SOUTH_KOREA,
- CCODE_SPAIN,
- CCODE_SWEDEN,
- CCODE_SWITZERLAND,
- CCODE_SYRIA,
- CCODE_TAIWAN,
- CCODE_THAILAND,
- CCODE_TRINIDAD_TOBAGO,
- CCODE_TUNISIA,
- CCODE_TURKEY,
- CCODE_UK,
- CCODE_UKRAINE,
- CCODE_UNITED_ARAB_EMIRATES,
- CCODE_UNITED_STATES,
- CCODE_URUGUAY,
- CCODE_UZBEKISTAN,
- CCODE_VENEZUELA,
- CCODE_VIETNAM,
- CCODE_YEMEN,
- CCODE_ZIMBABWE,
- CCODE_JAPAN_W52_W53,
- CCODE_MAX
-} COUNTRY_CODE;
-
-/************************************************************************
- * Function prototype
- ************************************************************************/
-#endif /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c
deleted file mode 100644
index 8032d6b5b383..000000000000
--- a/drivers/staging/vt6656/datarate.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: datarate.c
- *
- * Purpose: Handles the auto fallback & data rates functions
- *
- * Author: Lyndon Chen
- *
- * Date: July 17, 2002
- *
- * Functions:
- * RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame
- * RATEvTxRateFallBack - Rate fallback Algorithm Implementaion
- * RATEuSetIE- Set rate IE field.
- *
- * Revision History:
- *
- */
-
-#include "tmacro.h"
-#include "mac.h"
-#include "80211mgr.h"
-#include "bssdb.h"
-#include "datarate.h"
-#include "card.h"
-#include "baseband.h"
-#include "rf.h"
-
-/* static int msglevel = MSG_LEVEL_DEBUG; */
-static int msglevel = MSG_LEVEL_INFO;
-static const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18,
- 0x24, 0x30, 0x48, 0x60, 0x6C};
-
-#define AUTORATE_TXOK_CNT 0x0400
-#define AUTORATE_TXFAIL_CNT 0x0064
-#define AUTORATE_TIMEOUT 10
-
-void s_vResetCounter(PKnownNodeDB psNodeDBTable);
-
-void s_vResetCounter(PKnownNodeDB psNodeDBTable)
-{
- u8 ii;
-
- /* clear statistics counter for auto_rate */
- for (ii = 0; ii <= MAX_RATE; ii++) {
- psNodeDBTable->uTxOk[ii] = 0;
- psNodeDBTable->uTxFail[ii] = 0;
- }
-}
-
-/*+
- *
- * Routine Description:
- * Rate fallback Algorithm Implementaion
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * psNodeDBTable - Pointer to Node Data Base
- * Out:
- * none
- *
- * Return Value: none
- *
--*/
-#define AUTORATE_TXCNT_THRESHOLD 20
-#define AUTORATE_INC_THRESHOLD 30
-
-/*+
- *
- * Description:
- * Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
- *
- * Parameters:
- * In:
- * u8 - Rate value in SuppRates IE or ExtSuppRates IE
- * Out:
- * none
- *
- * Return Value: RateIdx
- *
--*/
-u16 RATEwGetRateIdx(u8 byRate)
-{
- u16 ii;
-
- /* erase BasicRate flag */
- byRate = byRate & 0x7F;
-
- for (ii = 0; ii < MAX_RATE; ii++) {
- if (acbyIERate[ii] == byRate)
- return ii;
- }
- return 0;
-}
-
-/*+
- *
- * Description:
- * Parsing the highest basic & support rate in rate field of frame.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * pItemRates - Pointer to Rate field defined in 802.11 spec.
- * pItemExtRates - Pointer to Extended Rate field defined in 802.11 spec.
- * Out:
- * pwMaxBasicRate - Maximum Basic Rate
- * pwMaxSuppRate - Maximum Supported Rate
- * pbyTopCCKRate - Maximum Basic Rate in CCK mode
- * pbyTopOFDMRate - Maximum Basic Rate in OFDM mode
- *
- * Return Value: none
- *
--*/
-
-void RATEvParseMaxRate(struct vnt_private *pDevice,
- PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates,
- int bUpdateBasicRate, u16 *pwMaxBasicRate, u16 *pwMaxSuppRate,
- u16 *pwSuppRate, u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate)
-{
- int ii;
- u8 byHighSuppRate = 0, byRate = 0;
- u16 wOldBasicRate = pDevice->wBasicRate;
- u32 uRateLen;
-
- if (pItemRates == NULL)
- return;
-
- *pwSuppRate = 0;
- uRateLen = pItemRates->len;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
- if (pDevice->byBBType != BB_TYPE_11B) {
- if (uRateLen > WLAN_RATES_MAXLEN)
- uRateLen = WLAN_RATES_MAXLEN;
- } else {
- if (uRateLen > WLAN_RATES_MAXLEN_11B)
- uRateLen = WLAN_RATES_MAXLEN_11B;
- }
-
- for (ii = 0; ii < uRateLen; ii++) {
- byRate = (u8)(pItemRates->abyRates[ii]);
- if (WLAN_MGMT_IS_BASICRATE(byRate) &&
- (bUpdateBasicRate == true)) {
- /*
- * add to basic rate set, update pDevice->byTopCCKBasicRate and
- * pDevice->byTopOFDMBasicRate
- */
- CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
- RATEwGetRateIdx(byRate));
- }
- byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
- if (byHighSuppRate == 0)
- byHighSuppRate = byRate;
- if (byRate > byHighSuppRate)
- byHighSuppRate = byRate;
- *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
- }
- if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
- (pDevice->byBBType != BB_TYPE_11B)) {
-
- unsigned int uExtRateLen = pItemExtRates->len;
-
- if (uExtRateLen > WLAN_RATES_MAXLEN)
- uExtRateLen = WLAN_RATES_MAXLEN;
-
- for (ii = 0; ii < uExtRateLen; ii++) {
- byRate = (u8)(pItemExtRates->abyRates[ii]);
- /* select highest basic rate */
- if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
- /*
- * add to basic rate set, update pDevice->byTopCCKBasicRate and
- * pDevice->byTopOFDMBasicRate
- */
- CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
- RATEwGetRateIdx(byRate));
- }
- byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F);
- if (byHighSuppRate == 0)
- byHighSuppRate = byRate;
- if (byRate > byHighSuppRate)
- byHighSuppRate = byRate;
- *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
-
- /* DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n",
- * RATEwGetRateIdx(byRate), byRate));
- */
- }
- }
-
- if ((pDevice->byPacketType == PK_TYPE_11GB)
- && CARDbIsOFDMinBasicRate((void *)pDevice)) {
- pDevice->byPacketType = PK_TYPE_11GA;
- }
-
- *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
- *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
- *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
- if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB))
- *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
- else
- *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
- if (wOldBasicRate != pDevice->wBasicRate)
- CARDvSetRSPINF((void *)pDevice, pDevice->byBBType);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
-}
-
-/*+
- *
- * Routine Description:
- * Rate fallback Algorithm Implementaion
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * psNodeDBTable - Pointer to Node Data Base
- * Out:
- * none
- *
- * Return Value: none
- *
--*/
-#define AUTORATE_TXCNT_THRESHOLD 20
-#define AUTORATE_INC_THRESHOLD 30
-
-void RATEvTxRateFallBack(struct vnt_private *pDevice,
- PKnownNodeDB psNodeDBTable)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u16 wIdxDownRate = 0;
- int ii;
- int bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true,
- true, true, true, true, true};
- u32 dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180,
- 240, 360, 480, 540};
- u32 dwThroughput = 0;
- u16 wIdxUpRate = 0;
- u32 dwTxDiff = 0;
-
- if (pMgmt->eScanState != WMAC_NO_SCANNING)
- return; /* Don't do Fallback when scanning Channel */
-
- psNodeDBTable->uTimeCount++;
-
- if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
- dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
-
- if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
- (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
- (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
- return;
- }
-
- if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT)
- psNodeDBTable->uTimeCount = 0;
-
- for (ii = 0; ii < MAX_RATE; ii++) {
- if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
- if (bAutoRate[ii] == true)
- wIdxUpRate = (u16) ii;
- } else {
- bAutoRate[ii] = false;
- }
- }
-
- for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
- if ((psNodeDBTable->uTxOk[ii] != 0) ||
- (psNodeDBTable->uTxFail[ii] != 0)) {
- dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
- if (ii < RATE_11M)
- psNodeDBTable->uTxFail[ii] *= 4;
- dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
- ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
- }
- dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
-
- wIdxDownRate = psNodeDBTable->wTxDataRate;
- for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
- ii--;
- if ((dwThroughputTbl[ii] > dwThroughput) &&
- (bAutoRate[ii] == true)) {
- dwThroughput = dwThroughputTbl[ii];
- wIdxDownRate = (u16) ii;
- }
- }
- psNodeDBTable->wTxDataRate = wIdxDownRate;
- if (psNodeDBTable->uTxOk[MAX_RATE]) {
- if (psNodeDBTable->uTxOk[MAX_RATE] >
- (psNodeDBTable->uTxFail[MAX_RATE] * 4)) {
- psNodeDBTable->wTxDataRate = wIdxUpRate;
- }
- } else { /* adhoc, if uTxOk(total) == 0 & uTxFail(total) == 0 */
- if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
- psNodeDBTable->wTxDataRate = wIdxUpRate;
- }
-
- if (pDevice->byBBType == BB_TYPE_11A) {
- if (psNodeDBTable->wTxDataRate <= RATE_11M)
- psNodeDBTable->wTxDataRate = RATE_6M;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n", (int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
- s_vResetCounter(psNodeDBTable);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
- return;
-}
-
-/*+
- *
- * Description:
- * This routine is used to assemble available Rate IE.
- *
- * Parameters:
- * In:
- * pDevice
- * Out:
- *
- * Return Value: None
- *
--*/
-u8 RATEuSetIE(PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates,
- unsigned int uRateLen)
-{
- unsigned int ii, uu, uRateCnt = 0;
-
- if ((pSrcRates == NULL) || (pDstRates == NULL))
- return 0;
-
- if (pSrcRates->len == 0)
- return 0;
-
- for (ii = 0; ii < uRateLen; ii++) {
- for (uu = 0; uu < pSrcRates->len; uu++) {
- if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
- pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu];
- break;
- }
- }
- }
- return (u8)uRateCnt;
-}
diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h
deleted file mode 100644
index 96252adf1ea6..000000000000
--- a/drivers/staging/vt6656/datarate.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: datarate.h
- *
- * Purpose: Handles the auto fallback & data rates functions
- *
- * Author: Lyndon Chen
- *
- * Date: July 16, 2002
- *
- */
-#ifndef __DATARATE_H__
-#define __DATARATE_H__
-
-#define FALLBACK_PKT_COLLECT_TR_H 50 /* pkts */
-#define FALLBACK_PKT_COLLECT_TR_L 10 /* pkts */
-#define FALLBACK_POLL_SECOND 5 /* 5 sec */
-#define FALLBACK_RECOVER_SECOND 30 /* 30 sec */
-#define FALLBACK_THRESHOLD 15 /* percent */
-#define UPGRADE_THRESHOLD 5 /* percent */
-#define UPGRADE_CNT_THRD 3 /* times */
-#define RETRY_TIMES_THRD_H 2 /* times */
-#define RETRY_TIMES_THRD_L 1 /* times */
-
-#define RATE_1M 0
-#define RATE_2M 1
-#define RATE_5M 2
-#define RATE_11M 3
-#define RATE_6M 4
-#define RATE_9M 5
-#define RATE_12M 6
-#define RATE_18M 7
-#define RATE_24M 8
-#define RATE_36M 9
-#define RATE_48M 10
-#define RATE_54M 11
-#define RATE_AUTO 12
-
-void RATEvParseMaxRate(struct vnt_private *, PWLAN_IE_SUPP_RATES pItemRates,
- PWLAN_IE_SUPP_RATES pItemExtRates, int bUpdateBasicRate,
- u16 *pwMaxBasicRate, u16 *pwMaxSuppRate, u16 *pwSuppRate,
- u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate);
-
-void RATEvTxRateFallBack(struct vnt_private *pDevice,
- PKnownNodeDB psNodeDBTable);
-
-u8
-RATEuSetIE(
- PWLAN_IE_SUPP_RATES pSrcRates,
- PWLAN_IE_SUPP_RATES pDstRates,
- unsigned int uRateLen
- );
-
-u16
-RATEwGetRateIdx(
- u8 byRate
- );
-
-#endif /* __DATARATE_H__ */
diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
index 617d479b85cc..f79af8513ff2 100644
--- a/drivers/staging/vt6656/desc.h
+++ b/drivers/staging/vt6656/desc.h
@@ -34,8 +34,6 @@
#include <linux/types.h>
#include <linux/mm.h>
-#include "tether.h"
-
/* max transmit or receive buffer size */
#define CB_MAX_BUF_SIZE 2900U /* NOTE: must be multiple of 4 */
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 5b64ca7b62f3..5a7ca527106e 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -35,15 +35,13 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
-#include <linux/etherdevice.h>
#include <linux/suspend.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/cfg80211.h>
#include <linux/timer.h>
#include <linux/usb.h>
#include <linux/crc32.h>
+#include <net/mac80211.h>
#ifdef SIOCETHTOOL
#define DEVICE_ETHTOOL_IOCTL_SUPPORT
@@ -52,17 +50,27 @@
#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
#endif
+#define RATE_1M 0
+#define RATE_2M 1
+#define RATE_5M 2
+#define RATE_11M 3
+#define RATE_6M 4
+#define RATE_9M 5
+#define RATE_12M 6
+#define RATE_18M 7
+#define RATE_24M 8
+#define RATE_36M 9
+#define RATE_48M 10
+#define RATE_54M 11
+#define RATE_AUTO 12
+
#define MAX_RATE 12
/*
* device specific
*/
-#include "80211hdr.h"
-#include "tether.h"
-#include "wmgr.h"
#include "wcmd.h"
-#include "rc4.h"
#include "desc.h"
#include "key.h"
#include "card.h"
@@ -73,7 +81,7 @@
#define DEVICE_NAME "vt6656"
#define DEVICE_FULL_DRV_NAM "VIA Networking Wireless LAN USB Driver"
-#define DEVICE_VERSION "1.19_12"
+#define DEVICE_VERSION "mac80211"
#define CONFIG_PATH "/etc/vntconfiguration.dat"
@@ -177,23 +185,6 @@
/* USB registers */
#define USB_REG4 0x604
-#ifndef RUN_AT
-#define RUN_AT(x) (jiffies+(x))
-#endif
-
-#define PRIVATE_Message 0
-
-#define DBG_PRT(l, p, args...) { if (l <= msglevel) printk(p, ##args); }
-#define PRINT_K(p, args...) { if (PRIVATE_Message) printk(p, ##args); }
-
-typedef enum __device_msg_level {
- MSG_LEVEL_ERR = 0, /* Errors causing abnormal operation */
- MSG_LEVEL_NOTICE = 1, /* Errors needing user notification */
- MSG_LEVEL_INFO = 2, /* Normal message. */
- MSG_LEVEL_VERBOSE = 3, /* Will report all trival errors. */
- MSG_LEVEL_DEBUG = 4 /* Only for debug purpose. */
-} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
-
#define DEVICE_INIT_COLD 0x0 /* cold init */
#define DEVICE_INIT_RESET 0x1 /* reset init or Dx to D0 power remain */
#define DEVICE_INIT_DXPL 0x2 /* Dx to D0 power lost init */
@@ -222,18 +213,16 @@ struct vnt_rsp_card_init {
*/
enum {
CONTEXT_DATA_PACKET = 1,
- CONTEXT_MGMT_PACKET
+ CONTEXT_MGMT_PACKET,
+ CONTEXT_BEACON_PACKET
};
/* RCB (Receive Control Block) */
struct vnt_rcb {
- void *Next;
- signed long Ref;
- void *pDevice;
- struct urb *pUrb;
- struct vnt_rx_mgmt sMngPacket;
+ void *priv;
+ struct urb *urb;
struct sk_buff *skb;
- int bBoolInUse;
+ int in_use;
};
/* used to track bulk out irps */
@@ -241,28 +230,20 @@ struct vnt_usb_send_context {
void *priv;
struct sk_buff *skb;
struct urb *urb;
+ struct ieee80211_hdr *hdr;
unsigned int buf_len;
+ u32 frame_len;
+ u16 tx_hdr_size;
+ u16 tx_rate;
u8 type;
+ u8 pkt_no;
+ u8 pkt_type;
+ u8 need_ack;
+ u8 fb_option;
bool in_use;
unsigned char data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
};
-/* tx packet info for rxtx */
-struct vnt_tx_pkt_info {
- u16 fifo_ctl;
- u8 dest_addr[ETH_ALEN];
-};
-
-/* structure got from configuration file as user-desired default settings */
-typedef struct _DEFAULT_CONFIG {
- signed int ZoneType;
- signed int eConfigMode;
- signed int eAuthenMode; /* open/wep/wpa */
- signed int bShareKeyAlgorithm; /* open-open/{open,wep}-sharekey */
- signed int keyidx; /* wepkey index */
- signed int eEncryptionStatus;
-} DEFAULT_CONFIG, *PDEFAULT_CONFIG;
-
/*
* Structure to keep track of USB interrupt packets
*/
@@ -273,463 +254,154 @@ struct vnt_interrupt_buffer {
/*++ NDIS related */
-typedef enum __DEVICE_NDIS_STATUS {
- STATUS_SUCCESS = 0,
- STATUS_FAILURE,
- STATUS_RESOURCES,
- STATUS_PENDING,
-} DEVICE_NDIS_STATUS, *PDEVICE_NDIS_STATUS;
-
-#define MAX_BSSIDINFO_4_PMKID 16
-#define MAX_PMKIDLIST 5
-/* flags for PMKID Candidate list structure */
-#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
-
-/* PMKID Structures */
-typedef unsigned char NDIS_802_11_PMKID_VALUE[16];
-
-typedef enum _NDIS_802_11_WEP_STATUS
-{
- Ndis802_11WEPEnabled,
- Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
- Ndis802_11WEPDisabled,
- Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
- Ndis802_11WEPKeyAbsent,
- Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
- Ndis802_11WEPNotSupported,
- Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
- Ndis802_11Encryption2Enabled,
- Ndis802_11Encryption2KeyAbsent,
- Ndis802_11Encryption3Enabled,
- Ndis802_11Encryption3KeyAbsent
-} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
- NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
-
-typedef enum _NDIS_802_11_STATUS_TYPE
-{
- Ndis802_11StatusType_Authentication,
- Ndis802_11StatusType_MediaStreamMode,
- Ndis802_11StatusType_PMKID_CandidateList,
- Ndis802_11StatusTypeMax, /* not a real type, defined as upper bound */
-} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
-
-/* added new types for PMKID Candidate lists */
-typedef struct _PMKID_CANDIDATE {
- NDIS_802_11_MAC_ADDRESS BSSID;
- unsigned long Flags;
-} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
-
-typedef struct _BSSID_INFO
-{
- NDIS_802_11_MAC_ADDRESS BSSID;
- NDIS_802_11_PMKID_VALUE PMKID;
-} BSSID_INFO, *PBSSID_INFO;
-
-typedef struct tagSPMKID {
- unsigned long Length;
- unsigned long BSSIDInfoCount;
- BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID];
-} SPMKID, *PSPMKID;
-
-typedef struct tagSPMKIDCandidateEvent {
- NDIS_802_11_STATUS_TYPE StatusType;
- unsigned long Version; /* Version of the structure */
- unsigned long NumCandidates; /* No. of pmkid candidates */
- PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
-} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
-
-/* The receive duplicate detection cache entry */
-typedef struct tagSCacheEntry{
- __le16 wFmSequence;
- u8 abyAddr2[ETH_ALEN];
- __le16 wFrameCtl;
-} SCacheEntry, *PSCacheEntry;
-
-typedef struct tagSCache{
-/* The receive cache is updated circularly. The next entry to be written is
- * indexed by the "InPtr".
- */
- unsigned int uInPtr; /* Place to use next */
- SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH];
-} SCache, *PSCache;
-
-#define CB_MAX_RX_FRAG 64
-/*
- * DeFragment Control Block, used for collecting fragments prior to reassembly
- */
-typedef struct tagSDeFragControlBlock
-{
- u16 wSequence;
- u16 wFragNum;
- u8 abyAddr2[ETH_ALEN];
- unsigned int uLifetime;
- struct sk_buff* skb;
- u8 * pbyRxBuffer;
- unsigned int cbFrameLength;
- bool bInUse;
-} SDeFragControlBlock, *PSDeFragControlBlock;
+enum {
+ STATUS_SUCCESS = 0,
+ STATUS_FAILURE,
+ STATUS_RESOURCES,
+ STATUS_PENDING,
+};
/* flags for options */
-#define DEVICE_FLAGS_UNPLUG 0x00000001UL
-
-/* flags for driver status */
-#define DEVICE_FLAGS_OPENED 0x00010000UL
-
-typedef struct __device_opt {
- int nRxDescs0; /* number of RX descriptors 0 */
- int nTxDescs0; /* number of TX descriptors 0, 1, 2, 3 */
- int rts_thresh; /* RTS threshold */
- int frag_thresh;
- int OpMode;
- int data_rate;
- int channel_num;
- int short_retry;
- int long_retry;
- int bbp_type;
- u32 flags;
-} OPTIONS, *POPTIONS;
+#define DEVICE_FLAGS_UNPLUG BIT(0)
+#define DEVICE_FLAGS_DISCONNECTED BIT(1)
struct vnt_private {
+ /* mac80211 */
+ struct ieee80211_hw *hw;
+ struct ieee80211_vif *vif;
+ u8 mac_hw;
/* netdev */
struct usb_device *usb;
- struct net_device *dev;
- struct net_device_stats stats;
- OPTIONS sOpts;
-
- struct work_struct read_work_item;
- struct work_struct rx_mng_work_item;
+ u64 tsf_time;
+ u8 rx_rate;
u32 rx_buf_sz;
- int multicast_limit;
- u8 byRxMode;
+ int mc_list_count;
spinlock_t lock;
struct mutex usb_lock;
- u32 rx_bytes;
-
- u32 flags;
- unsigned long Flags;
-
- SCache sDupRxCache;
-
- SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG];
- u32 cbDFCB;
- u32 cbFreeDFCB;
- u32 uCurrentDFCBIdx;
+ unsigned long flags;
/* USB */
- struct urb *pInterruptURB;
+ struct urb *interrupt_urb;
u32 int_interval;
/* Variables to track resources for the BULK In Pipe */
- struct vnt_rcb *pRCBMem;
- struct vnt_rcb *apRCB[CB_MAX_RX_DESC];
- u32 cbRD;
- struct vnt_rcb *FirstRecvFreeList;
- struct vnt_rcb *LastRecvFreeList;
- u32 NumRecvFreeList;
- struct vnt_rcb *FirstRecvMngList;
- struct vnt_rcb *LastRecvMngList;
- u32 NumRecvMngList;
- int bIsRxWorkItemQueued;
- int bIsRxMngWorkItemQueued;
- unsigned long ulRcvRefCount; /* packets that have not returned back */
+ struct vnt_rcb *rcb[CB_MAX_RX_DESC];
+ u32 num_rcb;
/* Variables to track resources for the BULK Out Pipe */
- struct vnt_usb_send_context *apTD[CB_MAX_TX_DESC];
- u32 cbTD;
- struct vnt_tx_pkt_info pkt_info[16];
+ struct vnt_usb_send_context *tx_context[CB_MAX_TX_DESC];
+ u32 num_tx_context;
/* Variables to track resources for the Interrupt In Pipe */
struct vnt_interrupt_buffer int_buf;
- /* default config from file by user setting */
- DEFAULT_CONFIG config_file;
-
/* Version control */
- u16 wFirmwareVersion;
- u8 byLocalID;
- u8 byRFType;
- u8 byBBRxConf;
-
- u8 byZoneType;
- int bZoneRegExist;
-
- u8 byOriginalZonetype;
+ u16 firmware_version;
+ u8 local_id;
+ u8 rf_type;
+ u8 bb_rx_conf;
- int bLinkPass; /* link status: OK or fail */
struct vnt_cmd_card_init init_command;
struct vnt_rsp_card_init init_response;
- u8 abyCurrentNetAddr[ETH_ALEN];
- u8 abyPermanentNetAddr[ETH_ALEN];
-
- int bExistSWNetAddr;
-
- /* Maintain statistical debug info. */
- unsigned long SendContextsInUse;
- unsigned long RcvBuffersInUse;
+ u8 current_net_addr[ETH_ALEN];
+ u8 permanent_net_addr[ETH_ALEN];
- /* 802.11 management */
- struct vnt_manager vnt_mgmt;
+ u8 exist_sw_net_addr;
- u64 qwCurrTSF;
- u32 cbBulkInMax;
- int bPSRxBeacon;
+ u64 current_tsf;
/* 802.11 MAC specific */
- u32 uCurrRSSI;
- u8 byCurrSQ;
+ u32 current_rssi;
/* Antenna Diversity */
- int bTxRxAntInv;
- u32 dwRxAntennaSel;
- u32 dwTxAntennaSel;
- u8 byAntennaCount;
- u8 byRxAntennaMode;
- u8 byTxAntennaMode;
- u8 byRadioCtl;
- u8 bHWRadioOff;
+ int tx_rx_ant_inv;
+ u32 rx_antenna_sel;
+ u8 rx_antenna_mode;
+ u8 tx_antenna_mode;
+ u8 radio_ctl;
/* IFS & Cw */
- u32 uSIFS; /* Current SIFS */
- u32 uDIFS; /* Current DIFS */
- u32 uEIFS; /* Current EIFS */
- u32 uSlot; /* Current SlotTime */
- u32 uCwMin; /* Current CwMin */
- u32 uCwMax; /* CwMax is fixed on 1023 */
-
- /* PHY parameter */
- u8 bySIFS;
- u8 byDIFS;
- u8 byEIFS;
- u8 bySlot;
- u8 byCWMaxMin;
+ u32 sifs; /* Current SIFS */
+ u32 difs; /* Current DIFS */
+ u32 eifs; /* Current EIFS */
+ u32 slot; /* Current SlotTime */
/* Rate */
- u8 byBBType; /* 0: 11A, 1:11B, 2:11G */
- u8 byPacketType; /* 0:11a 1:11b 2:11gb 3:11ga */
- u16 wBasicRate;
- u8 byTopOFDMBasicRate;
- u8 byTopCCKBasicRate;
-
- u8 abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /*u32 alignment */
+ u8 bb_type; /* 0: 11A, 1:11B, 2:11G */
+ u8 packet_type; /* 0:11a 1:11b 2:11gb 3:11ga */
+ u32 basic_rates;
+ u8 top_ofdm_basic_rate;
+ u8 top_cck_basic_rate;
- u8 byMinChannel;
- u8 byMaxChannel;
- u32 uConnectionRate;
+ u8 eeprom[EEP_MAX_CONTEXT_SIZE]; /*u32 alignment */
- u8 byPreambleType;
- u8 byShortPreamble;
- /* CARD_PHY_TYPE */
- u8 eConfigPHYMode;
+ u8 preamble_type;
/* For RF Power table */
- u8 byCCKPwr;
- u8 byOFDMPwrG;
- u8 byOFDMPwrA;
- u8 byCurPwr;
- u8 abyCCKPwrTbl[14];
- u8 abyOFDMPwrTbl[14];
- u8 abyOFDMAPwrTbl[42];
-
- u16 wCurrentRate;
+ u8 cck_pwr;
+ u8 ofdm_pwr_g;
+ u8 ofdm_pwr_a;
+ u8 power;
+ u8 cck_pwr_tbl[14];
+ u8 ofdm_pwr_tbl[14];
+ u8 ofdm_a_pwr_tbl[42];
+
+ u16 current_rate;
u16 tx_rate_fb0;
u16 tx_rate_fb1;
- u16 wRTSThreshold;
- u16 wFragmentationThreshold;
- u8 byShortRetryLimit;
- u8 byLongRetryLimit;
+ u8 short_retry_limit;
+ u8 long_retry_limit;
enum nl80211_iftype op_mode;
- int bBSSIDFilter;
- u16 wMaxTransmitMSDULifetime;
- u8 abyBSSID[ETH_ALEN];
- u8 abyDesireBSSID[ETH_ALEN];
-
- u32 dwMaxReceiveLifetime; /* dot11MaxReceiveLifetime */
-
- int bEncryptionEnable;
- int bShortSlotTime;
- int bProtectMode;
- int bNonERPPresent;
- int bBarkerPreambleMd;
-
- u8 byERPFlag;
- u16 wUseProtectCntDown;
-
- int bRadioControlOff;
- int bRadioOff;
+ int short_slot_time;
/* Power save */
- int bEnablePSMode;
- u16 wListenInterval;
- int bPWBitOn;
- WMAC_POWER_MODE ePSMode;
- unsigned long ulPSModeWaitTx;
- int bPSModeTxBurst;
+ u16 current_aid;
/* Beacon releated */
- u16 wSeqCounter;
- int bBeaconBufReady;
- int bBeaconSent;
- int bFixRate;
- u8 byCurrentCh;
-
- CMD_STATE eCommandState;
+ u16 seq_counter;
- CMD_CODE eCommand;
- int bBeaconTx;
- u8 byScanBBType;
+ enum vnt_cmd_state command_state;
- int bStopBeacon;
- int bStopDataPkt;
- int bStopTx0Pkt;
- u32 uAutoReConnectTime;
- u32 uIsroamingTime;
+ enum vnt_cmd command;
/* 802.11 counter */
- CMD_ITEM eCmdQueue[CMD_Q_SIZE];
- u32 uCmdDequeueIdx;
- u32 uCmdEnqueueIdx;
- u32 cbFreeCmdQueue;
- int bCmdRunning;
- int bCmdClear;
- int bNeedRadioOFF;
-
- int bEnableRoaming;
- int bIsRoaming;
- int bFastRoaming;
- u8 bSameBSSMaxNum;
- u8 bSameBSSCurNum;
- int bRoaming;
- int b11hEable;
-
- /* Encryption */
- NDIS_802_11_WEP_STATUS eEncryptionStatus;
- int bTransmitKey;
- NDIS_802_11_WEP_STATUS eOldEncryptionStatus;
- SKeyManagement sKey;
- u32 dwIVCounter;
+ enum vnt_cmd cmd_queue[CMD_Q_SIZE];
+ u32 cmd_dequeue_idx;
+ u32 cmd_enqueue_idx;
+ u32 free_cmd_queue;
+ int cmd_running;
- RC4Ext SBox;
- u8 abyPRNG[WLAN_WEPMAX_KEYLEN+3];
- u8 byKeyIndex;
+ unsigned long key_entry_inuse;
- u32 uKeyLength;
- u8 abyKey[WLAN_WEP232_KEYLEN];
-
- /* for AP mode */
- u32 uAssocCount;
- int bMoreData;
-
- /* QoS */
- int bGrpAckPolicy;
-
- u8 byAutoFBCtrl;
-
- int bTxMICFail;
- int bRxMICFail;
+ u8 auto_fb_ctrl;
/* For Update BaseBand VGA Gain Offset */
- u32 uBBVGADiffCount;
- u8 byBBVGANew;
- u8 byBBVGACurrent;
- u8 abyBBVGA[BB_VGA_LEVEL];
- signed long ldBmThreshold[BB_VGA_LEVEL];
+ u8 bb_vga[BB_VGA_LEVEL];
- u8 byBBPreEDRSSI;
- u8 byBBPreEDIndex;
-
- int bRadioCmd;
+ u8 bb_pre_ed_rssi;
+ u8 bb_pre_ed_index;
/* command timer */
struct delayed_work run_command_work;
- /* One second callback */
- struct delayed_work second_callback_work;
-
- u8 tx_data_time_out;
- bool tx_trigger;
- int fWPA_Authened; /*is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */
- u8 byReAssocCount;
- u8 byLinkWaitCount;
-
- struct ethhdr sTxEthHeader;
- struct ethhdr sRxEthHeader;
- u8 abyBroadcastAddr[ETH_ALEN];
- u8 abySNAP_RFC1042[ETH_ALEN];
- u8 abySNAP_Bridgetunnel[ETH_ALEN];
-
- /* Pre-Authentication & PMK cache */
- SPMKID gsPMKID;
- SPMKIDCandidateEvent gsPMKIDCandidate;
-
- /* for 802.11h */
- int b11hEnable;
-
- int bChannelSwitch;
- u8 byNewChannel;
- u8 byChannelSwitchCount;
-
- /* WPA supplicant daemon */
- int bWPADEVUp;
- int bwextstep0;
- int bwextstep1;
- int bwextstep2;
- int bwextstep3;
- int bWPASuppWextEnabled;
-
- u32 uChannel;
-
- struct iw_statistics wstats; /* wireless stats */
-
- int bCommit;
+ struct ieee80211_low_level_stats low_stats;
};
-#define EnqueueRCB(_Head, _Tail, _RCB) \
-{ \
- if (!_Head) { \
- _Head = _RCB; \
- } \
- else { \
- _Tail->Next = _RCB; \
- } \
- _RCB->Next = NULL; \
- _Tail = _RCB; \
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
+ if ((uVar) >= ((uModulo) - 1)) \
+ (uVar) = 0; \
+ else \
+ (uVar)++; \
}
-#define DequeueRCB(Head, Tail) \
-{ \
- struct vnt_rcb *RCB = Head; \
- if (!RCB->Next) { \
- Tail = NULL; \
- } \
- Head = RCB->Next; \
-}
-
-#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
- if ((uVar) >= ((uModulo) - 1)) \
- (uVar) = 0; \
- else \
- (uVar)++; \
-}
-
-#define fMP_DISCONNECTED 0x00000002
-#define fMP_POST_READS 0x00000100
-#define fMP_POST_WRITES 0x00000200
-
-#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
-#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
-#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
-
-#define MP_IS_READY(_M) (((_M)->Flags & fMP_DISCONNECTED) == 0)
-
-int device_alloc_frag_buf(struct vnt_private *, PSDeFragControlBlock pDeF);
-void vnt_configure_filter(struct vnt_private *);
+int vnt_init(struct vnt_private *priv);
#endif
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
index c0ec5b37aa7c..e6367ed3b0bb 100644
--- a/drivers/staging/vt6656/dpc.c
+++ b/drivers/staging/vt6656/dpc.c
@@ -25,11 +25,6 @@
* Date: May 20, 2003
*
* Functions:
- * device_receive_frame - Rcv 802.11 frame function
- * s_bHandleRxEncryption- Rcv decrypted data via on-fly
- * s_byGetRateIdx- get rate index
- * s_vGetDASA- get data offset
- * s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3
*
* Revision History:
*
@@ -37,935 +32,155 @@
#include "dpc.h"
#include "device.h"
-#include "rxtx.h"
-#include "tether.h"
-#include "card.h"
-#include "bssdb.h"
#include "mac.h"
#include "baseband.h"
-#include "michael.h"
-#include "tkip.h"
-#include "wctl.h"
#include "rf.h"
-#include "iowpa.h"
-#include "datarate.h"
-#include "usbpipe.h"
-//static int msglevel =MSG_LEVEL_DEBUG;
-static int msglevel =MSG_LEVEL_INFO;
-
-static const u8 acbyRxRate[MAX_RATE] =
-{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
-
-static u8 s_byGetRateIdx(u8 byRate);
-
-static
-void
-s_vGetDASA(
- u8 * pbyRxBufferAddr,
- unsigned int *pcbHeaderSize,
- struct ethhdr *psEthHeader
- );
-
-static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
- u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
- u32 *pcbHeadSize);
-
-static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
- u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
- s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16);
-
-/*+
- *
- * Description:
- * Translate Rcv 802.11 header to 802.3 header with Rx buffer
- *
- * Parameters:
- * In:
- * pDevice
- * dwRxBufferAddr - Address of Rcv Buffer
- * cbPacketSize - Rcv Packet size
- * bIsWEP - If Rcv with WEP
- * Out:
- * pcbHeaderSize - 802.11 header size
- *
- * Return Value: None
- *
--*/
-
-static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
- u8 *pbyRxBufferAddr, u32 cbPacketSize, int bIsWEP, int bExtIV,
- u32 *pcbHeadSize)
+int vnt_rx_data(struct vnt_private *priv, struct vnt_rcb *ptr_rcb,
+ unsigned long bytes_received)
{
- u8 *pbyRxBuffer;
- u32 cbHeaderSize = 0;
- u16 *pwType;
- struct ieee80211_hdr *pMACHeader;
- int ii;
-
- pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
-
- s_vGetDASA((u8 *)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
-
- if (bIsWEP) {
- if (bExtIV) {
- // strip IV&ExtIV , add 8 byte
- cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
- } else {
- // strip IV , add 4 byte
- cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
- }
- }
- else {
- cbHeaderSize += WLAN_HDR_ADDR3_LEN;
- };
-
- pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
- if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
- cbHeaderSize += 6;
- } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
- cbHeaderSize += 6;
- pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
- if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||
- (*pwType == cpu_to_le16(0xF380))) {
- cbHeaderSize -= 8;
- pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
- if (bIsWEP) {
- if (bExtIV) {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV
- } else {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV
- }
- }
- else {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
- }
- }
- }
- else {
- cbHeaderSize -= 2;
- pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
- if (bIsWEP) {
- if (bExtIV) {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8); // 8 is IV&ExtIV
- } else {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4); // 4 is IV
- }
- }
- else {
- *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
- }
- }
-
- cbHeaderSize -= (ETH_ALEN * 2);
- pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
- for (ii = 0; ii < ETH_ALEN; ii++)
- *pbyRxBuffer++ = pDevice->sRxEthHeader.h_dest[ii];
- for (ii = 0; ii < ETH_ALEN; ii++)
- *pbyRxBuffer++ = pDevice->sRxEthHeader.h_source[ii];
-
- *pcbHeadSize = cbHeaderSize;
-}
-
-static u8 s_byGetRateIdx(u8 byRate)
-{
- u8 byRateIdx;
-
- for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
- if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
- return byRateIdx;
- }
- return 0;
-}
-
-static
-void
-s_vGetDASA (
- u8 * pbyRxBufferAddr,
- unsigned int *pcbHeaderSize,
- struct ethhdr *psEthHeader
- )
-{
- unsigned int cbHeaderSize = 0;
- struct ieee80211_hdr *pMACHeader;
- int ii;
-
- pMACHeader = (struct ieee80211_hdr *) (pbyRxBufferAddr + cbHeaderSize);
-
- if ((pMACHeader->frame_control & FC_TODS) == 0) {
- if (pMACHeader->frame_control & FC_FROMDS) {
- for (ii = 0; ii < ETH_ALEN; ii++) {
- psEthHeader->h_dest[ii] =
- pMACHeader->addr1[ii];
- psEthHeader->h_source[ii] =
- pMACHeader->addr3[ii];
- }
- } else {
- /* IBSS mode */
- for (ii = 0; ii < ETH_ALEN; ii++) {
- psEthHeader->h_dest[ii] =
- pMACHeader->addr1[ii];
- psEthHeader->h_source[ii] =
- pMACHeader->addr2[ii];
- }
- }
- } else {
- /* Is AP mode.. */
- if (pMACHeader->frame_control & FC_FROMDS) {
- for (ii = 0; ii < ETH_ALEN; ii++) {
- psEthHeader->h_dest[ii] =
- pMACHeader->addr3[ii];
- psEthHeader->h_source[ii] =
- pMACHeader->addr4[ii];
- cbHeaderSize += 6;
- }
- } else {
- for (ii = 0; ii < ETH_ALEN; ii++) {
- psEthHeader->h_dest[ii] =
- pMACHeader->addr3[ii];
- psEthHeader->h_source[ii] =
- pMACHeader->addr2[ii];
- }
- }
- };
- *pcbHeaderSize = cbHeaderSize;
-}
-
-int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
- unsigned long BytesToIndicate)
-{
- struct net_device_stats *pStats = &pDevice->stats;
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_supported_band *sband;
struct sk_buff *skb;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_rx_mgmt *pRxPacket = &pMgmt->sRxPacket;
- struct ieee80211_hdr *p802_11Header;
- u8 *pbyRsr, *pbyNewRsr, *pbyRSSI, *pbyFrame;
- u64 *pqwTSFTime;
- u32 bDeFragRx = false;
- u32 cbHeaderOffset, cbIVOffset;
- u32 FrameSize;
- u16 wEtherType = 0;
- s32 iSANodeIndex = -1;
- int ii;
- u8 *pbyRxSts, *pbyRxRate, *pbySQ, *pby3SQ;
- u32 cbHeaderSize;
- PSKeyItem pKey = NULL;
- u16 wRxTSC15_0 = 0;
- u32 dwRxTSC47_16 = 0;
- /* signed long ldBm = 0; */
- int bIsWEP = false; int bExtIV = false;
- u32 dwWbkStatus;
- struct vnt_rcb *pRCBIndicate = pRCB;
- u8 *pbyDAddress;
- u16 *pwPLCP_Length;
- u8 abyVaildRate[MAX_RATE]
- = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
- u16 wPLCPwithPadding;
- struct ieee80211_hdr *pMACHeader;
- int bRxeapol_key = false;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n");
-
- skb = pRCB->skb;
+ struct ieee80211_rx_status rx_status = { 0 };
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ u8 *rsr, *new_rsr, *rssi, *frame;
+ __le64 *tsf_time;
+ u32 frame_size;
+ int ii, r;
+ u8 *rx_sts, *rx_rate, *sq, *sq_3;
+ u32 wbk_status;
+ u8 *skb_data;
+ u16 *pay_load_len;
+ u16 pay_load_with_padding;
+ u8 rate_idx = 0;
+ u8 rate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+ long rx_dbm;
+
+ skb = ptr_rcb->skb;
/* [31:16]RcvByteCount ( not include 4-byte Status ) */
- dwWbkStatus = *((u32 *)(skb->data));
- FrameSize = dwWbkStatus >> 16;
- FrameSize += 4;
+ wbk_status = *((u32 *)(skb->data));
+ frame_size = wbk_status >> 16;
+ frame_size += 4;
- if (BytesToIndicate != FrameSize) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n");
- pStats->rx_frame_errors++;
+ if (bytes_received != frame_size) {
+ dev_dbg(&priv->usb->dev, "------- WRONG Length 1\n");
return false;
}
- if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) {
- // Frame Size error drop this packet.
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n");
- pStats->rx_frame_errors++;
- return false;
- }
-
- pbyDAddress = (u8 *)(skb->data);
- pbyRxSts = pbyDAddress+4;
- pbyRxRate = pbyDAddress+5;
-
- //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding
- //if SQ3 the range is 24~27, if no SQ3 the range is 20~23
- //real Frame size in PLCPLength field.
- pwPLCP_Length = (u16 *) (pbyDAddress + 6);
- //Fix hardware bug => PLCP_Length error
- if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) ||
- ((BytesToIndicate - (*pwPLCP_Length)) < 24) ||
- (BytesToIndicate < (*pwPLCP_Length)) ) {
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length);
- pStats->rx_frame_errors++;
- return false;
- }
- for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
- if ( *pbyRxRate == abyVaildRate[ii] ) {
- break;
- }
- }
- if ( ii==MAX_RATE ) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate);
- return false;
- }
-
- wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
-
- pqwTSFTime = (u64 *)(pbyDAddress + 8 + wPLCPwithPadding);
- if(pDevice->byBBType == BB_TYPE_11G) {
- pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
- pbySQ = pby3SQ;
- }
- else {
- pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
- pby3SQ = pbySQ;
- }
- pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
- pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
- pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
-
- FrameSize = *pwPLCP_Length;
-
- pbyFrame = pbyDAddress + 8;
-
- pMACHeader = (struct ieee80211_hdr *) pbyFrame;
-
-//mike add: to judge if current AP is activated?
- if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
- (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
- if (pMgmt->sNodeDBTable[0].bActive) {
- if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
- if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
- }
- }
- }
-
- if (!is_multicast_ether_addr(pMACHeader->addr1)) {
- if (WCTLbIsDuplicate(&(pDevice->sDupRxCache), (struct ieee80211_hdr *) pbyFrame)) {
- return false;
- }
-
- if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) {
+ if ((bytes_received > 2372) || (bytes_received <= 40)) {
+ /* Frame Size error drop this packet.*/
+ dev_dbg(&priv->usb->dev, "------ WRONG Length 2\n");
return false;
- }
- }
-
- // Use for TKIP MIC
- s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
-
- if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source,
- pDevice->abyCurrentNetAddr))
- return false;
-
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
- if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
- p802_11Header = (struct ieee80211_hdr *) (pbyFrame);
- // get SA NodeIndex
- if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(p802_11Header->addr2), &iSANodeIndex)) {
- pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
- pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
- }
- }
- }
-
- if (IS_FC_WEP(pbyFrame)) {
- bool bRxDecryOK = false;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
- bIsWEP = true;
-
- bRxDecryOK = s_bHandleRxEncryption(pDevice, pbyFrame, FrameSize,
- pbyRsr, pbyNewRsr, &pKey, &bExtIV, &wRxTSC15_0, &dwRxTSC47_16);
-
- if (bRxDecryOK) {
- if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
- if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
- }
- return false;
- }
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
- return false;
- }
- if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
- FrameSize -= 8; // Message Integrity Code
- else
- FrameSize -= 4; // 4 is ICV
- }
-
- //
- // RX OK
- //
- /* remove the FCS/CRC length */
- FrameSize -= ETH_FCS_LEN;
-
- if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address
- (IS_FRAGMENT_PKT((pbyFrame)))
- ) {
- // defragment
- bDeFragRx = WCTLbHandleFragment(pDevice, (struct ieee80211_hdr *) (pbyFrame), FrameSize, bIsWEP, bExtIV);
- if (bDeFragRx) {
- // defrag complete
- // TODO skb, pbyFrame
- skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
- FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
- pbyFrame = skb->data + 8;
- }
- else {
- return false;
- }
- }
-
- //
- // Management & Control frame Handle
- //
- if ((IS_TYPE_DATA((pbyFrame))) == false) {
- // Handle Control & Manage Frame
-
- if (IS_TYPE_MGMT((pbyFrame))) {
- u8 * pbyData1;
- u8 * pbyData2;
-
- pRxPacket = &(pRCB->sMngPacket);
- pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame);
- pRxPacket->cbMPDULen = FrameSize;
- pRxPacket->uRSSI = *pbyRSSI;
- pRxPacket->bySQ = *pbySQ;
- pRxPacket->qwLocalTSF = cpu_to_le64(*pqwTSFTime);
- if (bIsWEP) {
- // strip IV
- pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame);
- pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4;
- for (ii = 0; ii < (FrameSize - 4); ii++) {
- *pbyData1 = *pbyData2;
- pbyData1++;
- pbyData2++;
- }
- }
-
- pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
-
- if ( *pbyRxSts == 0 ) {
- //Discard beacon packet which channel is 0
- if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
- (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
- return false;
- }
- }
- pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
-
- //
- // Insert the RCB in the Recv Mng list
- //
- EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate);
- pDevice->NumRecvMngList++;
- if ( bDeFragRx == false) {
- pRCB->Ref++;
- }
- if (pDevice->bIsRxMngWorkItemQueued == false) {
- pDevice->bIsRxMngWorkItemQueued = true;
- schedule_work(&pDevice->rx_mng_work_item);
- }
-
- }
- else {
- // Control Frame
- };
- return false;
- }
- else {
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
- if ( !(*pbyRsr & RSR_BSSIDOK)) {
- if (bDeFragRx) {
- if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
- pDevice->dev->name);
- }
- }
- return false;
- }
- }
- else {
- // discard DATA packet while not associate || BSSID error
- if ((pDevice->bLinkPass == false) ||
- !(*pbyRsr & RSR_BSSIDOK)) {
- if (bDeFragRx) {
- if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
- pDevice->dev->name);
- }
- }
- return false;
- }
- //mike add:station mode check eapol-key challenge--->
- {
- u8 Protocol_Version; //802.1x Authentication
- u8 Packet_Type; //802.1x Authentication
- u8 Descriptor_type;
- u16 Key_info;
- if (bIsWEP)
- cbIVOffset = 8;
- else
- cbIVOffset = 0;
- wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
- skb->data[cbIVOffset + 8 + 24 + 6 + 1];
- Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1];
- Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1];
- if (wEtherType == ETH_P_PAE) { //Protocol Type in LLC-Header
- if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
- (Packet_Type==3)) { //802.1x OR eapol-key challenge frame receive
- bRxeapol_key = true;
- Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2];
- Key_info = (skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+1]<<8) |skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+2] ;
- if(Descriptor_type==2) { //RSN
- // printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info);
- }
- else if(Descriptor_type==254) {
- // printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info);
- }
- }
- }
- }
- //mike add:station mode check eapol-key challenge<---
- }
- }
-
-// Data frame Handle
-
- if (pDevice->bEnablePSMode) {
- if (IS_FC_MOREDATA((pbyFrame))) {
- if (*pbyRsr & RSR_ADDROK) {
- //PSbSendPSPOLL((PSDevice)pDevice);
- }
- }
- else {
- if (pMgmt->bInTIMWake == true) {
- pMgmt->bInTIMWake = false;
- }
- }
- }
-
- // ++++++++ For BaseBand Algorithm +++++++++++++++
- pDevice->uCurrRSSI = *pbyRSSI;
- pDevice->byCurrSQ = *pbySQ;
-
- // todo
-/*
- if ((*pbyRSSI != 0) &&
- (pMgmt->pCurrBSS!=NULL)) {
- RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
- // Monitor if RSSI is too strong.
- pMgmt->pCurrBSS->byRSSIStatCnt++;
- pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
- pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
- for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
- if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
- pMgmt->pCurrBSS->ldBmMAX =
- max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
- }
- }
- }
-*/
-
- if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
- if (bIsWEP) {
- FrameSize -= 8; //MIC
- }
- }
-
- //--------------------------------------------------------------------------------
- // Soft MIC
- if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
- if (bIsWEP) {
- u32 * pdwMIC_L;
- u32 * pdwMIC_R;
- u32 dwMIC_Priority;
- u32 dwMICKey0 = 0, dwMICKey1 = 0;
- u32 dwLocalMIC_L = 0;
- u32 dwLocalMIC_R = 0;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
- dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
- }
- else {
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
- dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
- dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
- } else if ((pKey->dwKeyIndex & BIT28) == 0) {
- dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[16]));
- dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[20]));
- } else {
- dwMICKey0 = cpu_to_le32(*(u32 *)(&pKey->abyKey[24]));
- dwMICKey1 = cpu_to_le32(*(u32 *)(&pKey->abyKey[28]));
- }
- }
-
- MIC_vInit(dwMICKey0, dwMICKey1);
- MIC_vAppend((u8 *)&(pDevice->sRxEthHeader.h_dest[0]), 12);
- dwMIC_Priority = 0;
- MIC_vAppend((u8 *)&dwMIC_Priority, 4);
- // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
- MIC_vAppend((u8 *)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8),
- FrameSize - WLAN_HDR_ADDR3_LEN - 8);
- MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
- MIC_vUnInit();
-
- pdwMIC_L = (u32 *)(skb->data + 8 + FrameSize);
- pdwMIC_R = (u32 *)(skb->data + 8 + FrameSize + 4);
-
- if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
- (pDevice->bRxMICFail == true)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
- pDevice->bRxMICFail = false;
- if (bDeFragRx) {
- if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
- pDevice->dev->name);
- }
- }
- //send event to wpa_supplicant
- //if(pDevice->bWPASuppWextEnabled == true)
- {
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
- int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
- (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
- (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- } else {
- ev.flags |= IW_MICFAILURE_GROUP;
- }
-
- ev.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(ev.src_addr.sa_data, pMACHeader->addr2, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n");
- wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
-
- }
-
- return false;
-
- }
- }
- } //---end of SOFT MIC-----------------------------------------------------------------------
-
- // ++++++++++ Reply Counter Check +++++++++++++
-
- if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
- (pKey->byCipherSuite == KEY_CTL_CCMP))) {
- if (bIsWEP) {
- u16 wLocalTSC15_0 = 0;
- u32 dwLocalTSC47_16 = 0;
- unsigned long long RSC = 0;
- // endian issues
- RSC = *((unsigned long long *) &(pKey->KeyRSC));
- wLocalTSC15_0 = (u16) RSC;
- dwLocalTSC47_16 = (u32) (RSC>>16);
-
- RSC = dwRxTSC47_16;
- RSC <<= 16;
- RSC += wRxTSC15_0;
- memcpy(&(pKey->KeyRSC), &RSC, sizeof(u64));
-
- if (pDevice->vnt_mgmt.eCurrMode == WMAC_MODE_ESS_STA &&
- pDevice->vnt_mgmt.eCurrState == WMAC_STATE_ASSOC) {
- /* check RSC */
- if ( (wRxTSC15_0 < wLocalTSC15_0) &&
- (dwRxTSC47_16 <= dwLocalTSC47_16) &&
- !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
-
- if (bDeFragRx) {
- if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
- pDevice->dev->name);
- }
- }
- return false;
- }
- }
- }
- } // ----- End of Reply Counter Check --------------------------
-
- s_vProcessRxMACHeader(pDevice, (u8 *)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
- FrameSize -= cbHeaderOffset;
- cbHeaderOffset += 8; // 8 is Rcv buffer header
-
- // Null data, framesize = 12
- if (FrameSize < 12)
- return false;
-
- skb->data += cbHeaderOffset;
- skb->tail += cbHeaderOffset;
- skb_put(skb, FrameSize);
- skb->protocol=eth_type_trans(skb, skb->dev);
- skb->ip_summed=CHECKSUM_NONE;
- pStats->rx_bytes +=skb->len;
- pStats->rx_packets++;
- netif_rx(skb);
- if (bDeFragRx) {
- if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
- pDevice->dev->name);
- }
- return false;
- }
-
- return true;
-}
+ }
-static int s_bHandleRxEncryption(struct vnt_private *pDevice, u8 *pbyFrame,
- u32 FrameSize, u8 *pbyRsr, u8 *pbyNewRsr, PSKeyItem *pKeyOut,
- s32 *pbExtIV, u16 *pwRxTSC15_0, u32 *pdwRxTSC47_16)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u32 PayloadLen = FrameSize;
- u8 *pbyIV;
- u8 byKeyIdx;
- PSKeyItem pKey = NULL;
- u8 byDecMode = KEY_CTL_WEP;
-
- *pwRxTSC15_0 = 0;
- *pdwRxTSC47_16 = 0;
-
- pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
- if ( WLAN_GET_FC_TODS(*(u16 *)pbyFrame) &&
- WLAN_GET_FC_FROMDS(*(u16 *)pbyFrame) ) {
- pbyIV += 6; // 6 is 802.11 address4
- PayloadLen -= 6;
- }
- byKeyIdx = (*(pbyIV+3) & 0xc0);
- byKeyIdx >>= 6;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
-
- if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
- if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
- (pMgmt->byCSSPK != KEY_CTL_NONE)) {
- // unicast pkt use pairwise key
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
- if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == true) {
- if (pMgmt->byCSSPK == KEY_CTL_TKIP)
- byDecMode = KEY_CTL_TKIP;
- else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
- byDecMode = KEY_CTL_CCMP;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
- } else {
- // use group key
- KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
- if (pMgmt->byCSSGK == KEY_CTL_TKIP)
- byDecMode = KEY_CTL_TKIP;
- else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
- byDecMode = KEY_CTL_CCMP;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
- }
- }
- // our WEP only support Default Key
- if (pKey == NULL) {
- // use default group key
- KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
- if (pMgmt->byCSSGK == KEY_CTL_TKIP)
- byDecMode = KEY_CTL_TKIP;
- else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
- byDecMode = KEY_CTL_CCMP;
- }
- *pKeyOut = pKey;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
-
- if (pKey == NULL) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
- return false;
- }
- if (byDecMode != pKey->byCipherSuite) {
- *pKeyOut = NULL;
- return false;
- }
- if (byDecMode == KEY_CTL_WEP) {
- // handle WEP
- if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
- (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true)) {
- // Software WEP
- // 1. 3253A
- // 2. WEP 256
-
- PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
- memcpy(pDevice->abyPRNG, pbyIV, 3);
- memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
- rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
- rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
-
- if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
- *pbyNewRsr |= NEWRSR_DECRYPTOK;
- }
- }
- } else if ((byDecMode == KEY_CTL_TKIP) ||
- (byDecMode == KEY_CTL_CCMP)) {
- // TKIP/AES
-
- PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
- *pdwRxTSC47_16 = cpu_to_le32(*(u32 *)(pbyIV + 4));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
- if (byDecMode == KEY_CTL_TKIP) {
- *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
- } else {
- *pwRxTSC15_0 = cpu_to_le16(*(u16 *)pbyIV);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
-
- if ((byDecMode == KEY_CTL_TKIP) &&
- (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
- // Software TKIP
- // 1. 3253 A
- struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *) (pbyFrame);
- TKIPvMixKey(pKey->abyKey, pMACHeader->addr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
- rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
- rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
- if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
- *pbyNewRsr |= NEWRSR_DECRYPTOK;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
- }
- }
- }// end of TKIP/AES
-
- if ((*(pbyIV+3) & 0x20) != 0)
- *pbExtIV = true;
- return true;
-}
+ skb_data = (u8 *)skb->data;
-void RXvWorkItem(struct work_struct *work)
-{
- struct vnt_private *priv =
- container_of(work, struct vnt_private, read_work_item);
- int status;
- struct vnt_rcb *rcb = NULL;
- unsigned long flags;
+ rx_sts = skb_data+4;
+ rx_rate = skb_data+5;
+
+ /* real Frame Size = USBframe_size -4WbkStatus - 4RxStatus */
+ /* -8TSF - 4RSR - 4SQ3 - ?Padding */
- if (priv->Flags & fMP_DISCONNECTED)
- return;
+ /* if SQ3 the range is 24~27, if no SQ3 the range is 20~23 */
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
+ pay_load_len = (u16 *) (skb_data + 6);
- spin_lock_irqsave(&priv->lock, flags);
+ /*Fix hardware bug => PLCP_Length error */
+ if (((bytes_received - (*pay_load_len)) > 27) ||
+ ((bytes_received - (*pay_load_len)) < 24) ||
+ (bytes_received < (*pay_load_len))) {
+ dev_dbg(&priv->usb->dev, "Wrong PLCP Length %x\n",
+ *pay_load_len);
+ return false;
+ }
- while ((priv->Flags & fMP_POST_READS) && MP_IS_READY(priv) &&
- (priv->NumRecvFreeList != 0)) {
- rcb = priv->FirstRecvFreeList;
+ sband = hw->wiphy->bands[hw->conf.chandef.chan->band];
- priv->NumRecvFreeList--;
+ for (r = RATE_1M; r < MAX_RATE; r++) {
+ if (*rx_rate == rate[r])
+ break;
+ }
- DequeueRCB(priv->FirstRecvFreeList, priv->LastRecvFreeList);
+ priv->rx_rate = r;
- status = PIPEnsBulkInUsbRead(priv, rcb);
+ for (ii = 0; ii < sband->n_bitrates; ii++) {
+ if (sband->bitrates[ii].hw_value == r) {
+ rate_idx = ii;
+ break;
+ }
}
- priv->bIsRxWorkItemQueued = false;
+ if (ii == sband->n_bitrates) {
+ dev_dbg(&priv->usb->dev, "Wrong RxRate %x\n", *rx_rate);
+ return false;
+ }
- spin_unlock_irqrestore(&priv->lock, flags);
-}
+ pay_load_with_padding = ((*pay_load_len / 4) +
+ ((*pay_load_len % 4) ? 1 : 0)) * 4;
-void RXvFreeRCB(struct vnt_rcb *rcb, int re_alloc_skb)
-{
- struct vnt_private *priv = rcb->pDevice;
+ tsf_time = (__le64 *)(skb_data + 8 + pay_load_with_padding);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n");
+ priv->tsf_time = le64_to_cpu(*tsf_time);
- if (re_alloc_skb == false) {
- kfree_skb(rcb->skb);
- re_alloc_skb = true;
+ if (priv->bb_type == BB_TYPE_11G) {
+ sq_3 = skb_data + 8 + pay_load_with_padding + 12;
+ sq = sq_3;
+ } else {
+ sq = skb_data + 8 + pay_load_with_padding + 8;
+ sq_3 = sq;
}
- if (re_alloc_skb == true) {
- rcb->skb = netdev_alloc_skb(priv->dev, priv->rx_buf_sz);
- /* TODO error handling */
- if (!rcb->skb) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- " Failed to re-alloc rx skb\n");
- }
- }
+ new_rsr = skb_data + 8 + pay_load_with_padding + 9;
+ rssi = skb_data + 8 + pay_load_with_padding + 10;
- /* Insert the RCB back in the Recv free list */
- EnqueueRCB(priv->FirstRecvFreeList, priv->LastRecvFreeList, rcb);
- priv->NumRecvFreeList++;
+ rsr = skb_data + 8 + pay_load_with_padding + 11;
+ if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
+ return false;
- if ((priv->Flags & fMP_POST_READS) && MP_IS_READY(priv) &&
- (priv->bIsRxWorkItemQueued == false)) {
- priv->bIsRxWorkItemQueued = true;
- schedule_work(&priv->read_work_item);
- }
+ frame_size = *pay_load_len;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",
- priv->NumRecvFreeList, priv->NumRecvMngList);
-}
+ vnt_rf_rssi_to_dbm(priv, *rssi, &rx_dbm);
-void RXvMngWorkItem(struct work_struct *work)
-{
- struct vnt_private *pDevice =
- container_of(work, struct vnt_private, rx_mng_work_item);
- struct vnt_rcb *pRCB = NULL;
- struct vnt_rx_mgmt *pRxPacket;
- int bReAllocSkb = false;
- unsigned long flags;
+ priv->bb_pre_ed_rssi = (u8)rx_dbm + 1;
+ priv->current_rssi = priv->bb_pre_ed_rssi;
- if (pDevice->Flags & fMP_DISCONNECTED)
- return;
+ frame = skb_data + 8;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
+ skb_pull(skb, 8);
+ skb_trim(skb, frame_size);
- while (pDevice->NumRecvMngList!=0)
- {
- spin_lock_irqsave(&pDevice->lock, flags);
+ rx_status.mactime = priv->tsf_time;
+ rx_status.band = hw->conf.chandef.chan->band;
+ rx_status.signal = rx_dbm;
+ rx_status.flag = 0;
+ rx_status.freq = hw->conf.chandef.chan->center_freq;
- pRCB = pDevice->FirstRecvMngList;
- pDevice->NumRecvMngList--;
- DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+ if (!(*rsr & RSR_CRCOK))
+ rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
- spin_unlock_irqrestore(&pDevice->lock, flags);
+ hdr = (struct ieee80211_hdr *)(skb->data);
+ fc = hdr->frame_control;
- if(!pRCB){
- break;
- }
- pRxPacket = &(pRCB->sMngPacket);
- vMgrRxManagePacket(pDevice, &pDevice->vnt_mgmt, pRxPacket);
- pRCB->Ref--;
- if (pRCB->Ref == 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",
- pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+ rx_status.rate_idx = rate_idx;
- spin_lock_irqsave(&pDevice->lock, flags);
+ if (ieee80211_has_protected(fc)) {
+ if (priv->local_id > REV_ID_VT3253_A1) {
+ rx_status.flag |= RX_FLAG_DECRYPTED;
- RXvFreeRCB(pRCB, bReAllocSkb);
+ /* Drop packet */
+ if (!(*new_rsr & NEWRSR_DECRYPTOK)) {
+ dev_kfree_skb(skb);
+ return true;
+ }
+ }
+ }
- spin_unlock_irqrestore(&pDevice->lock, flags);
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
- }
- }
+ memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
- pDevice->bIsRxMngWorkItemQueued = false;
-}
+ ieee80211_rx_irqsafe(priv->hw, skb);
+ return true;
+}
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
index 8d524345dfdb..fab195f8c3f5 100644
--- a/drivers/staging/vt6656/dpc.h
+++ b/drivers/staging/vt6656/dpc.h
@@ -30,15 +30,8 @@
#define __DPC_H__
#include "device.h"
-#include "wcmd.h"
-void RXvWorkItem(struct work_struct *work);
-
-void RXvMngWorkItem(struct work_struct *work);
-
-void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb);
-
-int RXbBulkInProcessData(struct vnt_private *, struct vnt_rcb *pRCB,
- unsigned long BytesToIndicate);
+int vnt_rx_data(struct vnt_private *, struct vnt_rcb *,
+ unsigned long bytes_recieved);
#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
index 1159f0b34578..eae4f32d9b66 100644
--- a/drivers/staging/vt6656/firmware.c
+++ b/drivers/staging/vt6656/firmware.c
@@ -35,25 +35,22 @@
#include "firmware.h"
#include "usbpipe.h"
-static int msglevel = MSG_LEVEL_INFO;
-/* static int msglevel = MSG_LEVEL_DEBUG; */
-
#define FIRMWARE_VERSION 0x133 /* version 1.51 */
#define FIRMWARE_NAME "vntwusb.fw"
#define FIRMWARE_CHUNK_SIZE 0x400
-int FIRMWAREbDownload(struct vnt_private *pDevice)
+int vnt_download_firmware(struct vnt_private *priv)
{
- struct device *dev = &pDevice->usb->dev;
+ struct device *dev = &priv->usb->dev;
const struct firmware *fw;
- int NdisStatus;
- void *pBuffer = NULL;
+ int status;
+ void *buffer = NULL;
bool result = false;
- u16 wLength;
+ u16 length;
int ii, rc;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
+ dev_dbg(dev, "---->Download firmware\n");
rc = request_firmware(&fw, FIRMWARE_NAME, dev);
if (rc) {
@@ -62,24 +59,24 @@ int FIRMWAREbDownload(struct vnt_private *pDevice)
goto out;
}
- pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
- if (!pBuffer)
+ buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
+ if (!buffer)
goto out;
for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
- wLength = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
- memcpy(pBuffer, fw->data + ii, wLength);
+ length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
+ memcpy(buffer, fw->data + ii, length);
- NdisStatus = vnt_control_out(pDevice,
+ status = vnt_control_out(priv,
0,
0x1200+ii,
0x0000,
- wLength,
- pBuffer);
+ length,
+ buffer);
+
+ dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO"Download firmware...%d %zu\n", ii, fw->size);
- if (NdisStatus != STATUS_SUCCESS)
+ if (status != STATUS_SUCCESS)
goto free_fw;
}
@@ -88,56 +85,59 @@ free_fw:
release_firmware(fw);
out:
- kfree(pBuffer);
+ kfree(buffer);
return result;
}
MODULE_FIRMWARE(FIRMWARE_NAME);
-int FIRMWAREbBrach2Sram(struct vnt_private *pDevice)
+int vnt_firmware_branch_to_sram(struct vnt_private *priv)
{
- int NdisStatus;
+ int status;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+ dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
- NdisStatus = vnt_control_out(pDevice,
+ status = vnt_control_out(priv,
1,
0x1200,
0x0000,
0,
NULL);
- if (NdisStatus != STATUS_SUCCESS)
+ if (status != STATUS_SUCCESS)
return false;
else
return true;
}
-int FIRMWAREbCheckVersion(struct vnt_private *pDevice)
+int vnt_check_firmware_version(struct vnt_private *priv)
{
- int ntStatus;
+ int status;
- ntStatus = vnt_control_in(pDevice,
+ status = vnt_control_in(priv,
MESSAGE_TYPE_READ,
0,
MESSAGE_REQUEST_VERSION,
2,
- (u8 *) &(pDevice->wFirmwareVersion));
+ (u8 *)&priv->firmware_version);
+
+ dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
+ priv->firmware_version);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
- pDevice->wFirmwareVersion);
- if (ntStatus != STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+ if (status != STATUS_SUCCESS) {
+ dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
return false;
}
- if (pDevice->wFirmwareVersion == 0xFFFF) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+ if (priv->firmware_version == 0xFFFF) {
+ dev_dbg(&priv->usb->dev, "In Loader.\n");
return false;
}
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
- pDevice->wFirmwareVersion);
- if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
+
+ dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
+ priv->firmware_version);
+
+ if (priv->firmware_version < FIRMWARE_VERSION) {
/* branch to loader for download new firmware */
- FIRMWAREbBrach2Sram(pDevice);
+ vnt_firmware_branch_to_sram(priv);
return false;
}
return true;
diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h
index e3b08db6a734..d594dbe1c147 100644
--- a/drivers/staging/vt6656/firmware.h
+++ b/drivers/staging/vt6656/firmware.h
@@ -32,8 +32,8 @@
#include "device.h"
-int FIRMWAREbDownload(struct vnt_private *);
-int FIRMWAREbBrach2Sram(struct vnt_private *);
-int FIRMWAREbCheckVersion(struct vnt_private *);
+int vnt_download_firmware(struct vnt_private *);
+int vnt_firmware_branch_to_sram(struct vnt_private *);
+int vnt_check_firmware_version(struct vnt_private *);
#endif /* __FIRMWARE_H__ */
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index f2a5225b50f8..2ef70e4701f6 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -33,155 +33,134 @@
*/
#include "int.h"
-#include "tmacro.h"
#include "mac.h"
#include "power.h"
-#include "bssdb.h"
#include "usbpipe.h"
-static int msglevel = MSG_LEVEL_INFO; /* MSG_LEVEL_DEBUG */
-
-/*+
- *
- * Function: InterruptPollingThread
- *
- * Synopsis: Thread running at IRQL PASSIVE_LEVEL.
- *
- * Arguments: Device Extension
- *
- * Returns:
- *
- * Algorithm: Call USBD for input data;
- *
- * History: dd-mm-yyyy Author Comment
- *
- *
- * Notes:
- *
- * USB reads are by nature 'Blocking', and when in a read, the device looks
- * like it's in a 'stall' condition, so we deliberately time out every second
- * if we've gotten no data
- *
--*/
-void INTvWorkItem(struct vnt_private *pDevice)
+static const u8 fallback_rate0[5][5] = {
+ {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
+ {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
+ {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
+ {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
+ {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
+};
+
+static const u8 fallback_rate1[5][5] = {
+ {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
+ {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
+ {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
+ {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
+ {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
+};
+
+void vnt_int_start_interrupt(struct vnt_private *priv)
{
unsigned long flags;
- int ntStatus;
+ int status;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
+ dev_dbg(&priv->usb->dev, "---->Interrupt Polling Thread\n");
- spin_lock_irqsave(&pDevice->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
- ntStatus = PIPEnsInterruptRead(pDevice);
+ status = vnt_start_interrupt_urb(priv);
- spin_unlock_irqrestore(&pDevice->lock, flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
-void INTnsProcessData(struct vnt_private *priv)
+static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr)
{
- struct vnt_interrupt_data *int_data;
- struct vnt_manager *mgmt = &priv->vnt_mgmt;
- struct net_device_stats *stats = &priv->stats;
+ struct vnt_usb_send_context *context;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate;
+ u8 tx_retry = (tsr & 0xf0) >> 4;
+ s8 idx;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
+ if (pkt_no >= priv->num_tx_context)
+ return -EINVAL;
- int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf;
+ context = priv->tx_context[pkt_no];
- if (int_data->tsr0 & TSR_VALID) {
- if (int_data->tsr0 & (TSR_TMO | TSR_RETRYTMO))
- priv->wstats.discard.retries++;
- else
- stats->tx_packets++;
+ if (!context->skb)
+ return -EINVAL;
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr0,
- int_data->pkt0);
- }
+ info = IEEE80211_SKB_CB(context->skb);
+ idx = info->control.rates[0].idx;
- if (int_data->tsr1 & TSR_VALID) {
- if (int_data->tsr1 & (TSR_TMO | TSR_RETRYTMO))
- priv->wstats.discard.retries++;
- else
- stats->tx_packets++;
+ if (context->fb_option && !(tsr & (TSR_TMO | TSR_RETRYTMO))) {
+ u8 tx_rate;
+ u8 retry = tx_retry;
+ rate = ieee80211_get_tx_rate(priv->hw, info);
+ tx_rate = rate->hw_value - RATE_18M;
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr1,
- int_data->pkt1);
- }
+ if (retry > 4)
+ retry = 4;
- if (int_data->tsr2 & TSR_VALID) {
- if (int_data->tsr2 & (TSR_TMO | TSR_RETRYTMO))
- priv->wstats.discard.retries++;
- else
- stats->tx_packets++;
+ if (context->fb_option == AUTO_FB_0)
+ tx_rate = fallback_rate0[tx_rate][retry];
+ else if (context->fb_option == AUTO_FB_1)
+ tx_rate = fallback_rate1[tx_rate][retry];
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr2,
- int_data->pkt2);
+ if (info->band == IEEE80211_BAND_5GHZ)
+ idx = tx_rate - RATE_6M;
+ else
+ idx = tx_rate;
}
- if (int_data->tsr3 & TSR_VALID) {
- if (int_data->tsr3 & (TSR_TMO | TSR_RETRYTMO))
- priv->wstats.discard.retries++;
- else
- stats->tx_packets++;
+ ieee80211_tx_info_clear_status(info);
- BSSvUpdateNodeTxCounter(priv,
- int_data->tsr3,
- int_data->pkt3);
+ info->status.rates[0].count = tx_retry;
+
+ if (!(tsr & (TSR_TMO | TSR_RETRYTMO))) {
+ info->status.rates[0].idx = idx;
+ info->flags |= IEEE80211_TX_STAT_ACK;
}
+ ieee80211_tx_status_irqsafe(priv->hw, context->skb);
+
+ context->in_use = false;
+
+ return 0;
+}
+
+void vnt_int_process_data(struct vnt_private *priv)
+{
+ struct vnt_interrupt_data *int_data;
+ struct ieee80211_low_level_stats *low_stats = &priv->low_stats;
+
+ dev_dbg(&priv->usb->dev, "---->s_nsInterruptProcessData\n");
+
+ int_data = (struct vnt_interrupt_data *)priv->int_buf.data_buf;
+
+ if (int_data->tsr0 & TSR_VALID)
+ vnt_int_report_rate(priv, int_data->pkt0, int_data->tsr0);
+
+ if (int_data->tsr1 & TSR_VALID)
+ vnt_int_report_rate(priv, int_data->pkt1, int_data->tsr1);
+
+ if (int_data->tsr2 & TSR_VALID)
+ vnt_int_report_rate(priv, int_data->pkt2, int_data->tsr2);
+
+ if (int_data->tsr3 & TSR_VALID)
+ vnt_int_report_rate(priv, int_data->pkt3, int_data->tsr3);
+
if (int_data->isr0 != 0) {
- if (int_data->isr0 & ISR_BNTX) {
- if (priv->op_mode == NL80211_IFTYPE_AP) {
- if (mgmt->byDTIMCount > 0) {
- mgmt->byDTIMCount--;
- mgmt->sNodeDBTable[0].bRxPSPoll =
- false;
- } else if (mgmt->byDTIMCount == 0) {
- /* check if multicast tx buffering */
- mgmt->byDTIMCount =
- mgmt->byDTIMPeriod-1;
- mgmt->sNodeDBTable[0].bRxPSPoll = true;
- if (mgmt->sNodeDBTable[0].bPSEnable)
- bScheduleCommand((void *) priv,
- WLAN_CMD_RX_PSPOLL,
- NULL);
- }
- bScheduleCommand((void *) priv,
- WLAN_CMD_BECON_SEND,
- NULL);
- }
- priv->bBeaconSent = true;
- } else {
- priv->bBeaconSent = false;
- }
+ if (int_data->isr0 & ISR_BNTX &&
+ priv->op_mode == NL80211_IFTYPE_AP)
+ vnt_schedule_command(priv, WLAN_CMD_BECON_SEND);
if (int_data->isr0 & ISR_TBTT) {
- if (priv->bEnablePSMode)
- bScheduleCommand((void *) priv,
- WLAN_CMD_TBTT_WAKEUP,
- NULL);
- if (priv->bChannelSwitch) {
- priv->byChannelSwitchCount--;
- if (priv->byChannelSwitchCount == 0)
- bScheduleCommand((void *) priv,
- WLAN_CMD_11H_CHSW,
- NULL);
- }
+ if (priv->hw->conf.flags & IEEE80211_CONF_PS)
+ vnt_schedule_command(priv,
+ WLAN_CMD_TBTT_WAKEUP);
}
- priv->qwCurrTSF = le64_to_cpu(int_data->tsf);
- }
+ priv->current_tsf = le64_to_cpu(int_data->tsf);
- if (int_data->isr1 != 0)
- if (int_data->isr1 & ISR_GPIO3)
- bScheduleCommand((void *) priv,
- WLAN_CMD_RADIO,
- NULL);
+ low_stats->dot11RTSSuccessCount += int_data->rts_success;
+ low_stats->dot11RTSFailureCount += int_data->rts_fail;
+ low_stats->dot11ACKFailureCount += int_data->ack_fail;
+ low_stats->dot11FCSErrorCount += int_data->fcs_err;
+ }
priv->int_buf.in_use = false;
-
- stats->tx_errors = priv->wstats.discard.retries;
- stats->tx_dropped = priv->wstats.discard.retries;
}
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
index 08db868e1d07..154605c63947 100644
--- a/drivers/staging/vt6656/int.h
+++ b/drivers/staging/vt6656/int.h
@@ -55,7 +55,7 @@ struct vnt_interrupt_data {
u8 sw[2];
} __packed;
-void INTvWorkItem(struct vnt_private *);
-void INTnsProcessData(struct vnt_private *);
+void vnt_int_start_interrupt(struct vnt_private *);
+void vnt_int_process_data(struct vnt_private *);
#endif /* __INT_H__ */
diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h
deleted file mode 100644
index b957e6d475af..000000000000
--- a/drivers/staging/vt6656/iocmd.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: iocmd.h
- *
- * Purpose: Handles the viawget ioctl private interface functions
- *
- * Author: Lyndon Chen
- *
- * Date: May 8, 2002
- *
- */
-
-#ifndef __IOCMD_H__
-#define __IOCMD_H__
-
-typedef enum tagWZONETYPE {
- ZoneType_USA = 0,
- ZoneType_Japan = 1,
- ZoneType_Europe = 2
-} WZONETYPE;
-
-#endif /* __IOCMD_H__ */
diff --git a/drivers/staging/vt6656/iowpa.h b/drivers/staging/vt6656/iowpa.h
deleted file mode 100644
index 98f2b2195af4..000000000000
--- a/drivers/staging/vt6656/iowpa.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: iowpa.h
- *
- * Purpose: Handles wpa supplicant ioctl interface
- *
- * Author: Lyndon Chen
- *
- * Date: May 8, 2002
- *
- */
-
-#ifndef __IOWPA_H__
-#define __IOWPA_H__
-
-#define WPA_IE_LEN 64
-
-struct viawget_wpa_param {
- u32 cmd;
- u8 addr[6];
- union {
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
- u8 bssid[6];
- u8 ssid[32];
- u8 ssid_len;
- u8 *wpa_ie;
- u16 wpa_ie_len;
- int pairwise_suite;
- int group_suite;
- int key_mgmt_suite;
- int auth_alg;
- int mode;
- u8 roam_dbm;
- } wpa_associate;
- struct {
- int alg_name;
- u16 key_index;
- u16 set_tx;
- u8 *seq;
- u16 seq_len;
- u8 *key;
- u16 key_len;
- } wpa_key;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- struct {
- u16 scan_count;
- u8 *buf;
- } scan_results;
- } u;
-} __packed;
-
-#endif /* __IOWPA_H__ */
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
deleted file mode 100644
index c43718d788c0..000000000000
--- a/drivers/staging/vt6656/iwctl.c
+++ /dev/null
@@ -1,1802 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: iwctl.c
- *
- * Purpose: wireless ext & ioctl functions
- *
- * Author: Lyndon Chen
- *
- * Date: July 5, 2006
- *
- * Functions:
- *
- * Revision History:
- *
- */
-
-#include "device.h"
-#include "iwctl.h"
-#include "mac.h"
-#include "card.h"
-#include "power.h"
-#include "rf.h"
-#include "iowpa.h"
-#include "wpactl.h"
-#include "usbpipe.h"
-#include "baseband.h"
-
-static const long frequency_list[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
- 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
- 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
- 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
- 5700, 5745, 5765, 5785, 5805, 5825
-};
-
-static int msglevel = MSG_LEVEL_INFO;
-
-struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- long ldBm;
-
- pDevice->wstats.status = pDevice->op_mode;
- vnt_rf_rssi_to_dbm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
- pDevice->wstats.qual.level = ldBm;
- pDevice->wstats.qual.noise = 0;
- pDevice->wstats.qual.updated = 1;
- pDevice->wstats.discard.nwid = 0;
- pDevice->wstats.discard.code = 0;
- pDevice->wstats.discard.fragment = 0;
- pDevice->wstats.discard.misc = 0;
- pDevice->wstats.miss.beacon = 0;
- return &pDevice->wstats;
-}
-
-/*
- * Wireless Handler: get protocol name
- */
-int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- strcpy(wrqu->name, "802.11-a/b/g");
- return 0;
-}
-
-/*
- * Wireless Handler: set scan
- */
-int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_point *wrq = &wrqu->data;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_scan_req *req = (struct iw_scan_req *)extra;
- u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- PWLAN_IE_SSID pItemSSID = NULL;
- unsigned long flags;
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
- return -EINVAL;
-
- PRINT_K(" SIOCSIWSCAN\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (pMgmt->eScanState == WMAC_IS_SCANNING) {
- // In scanning..
- PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
- return -EAGAIN;
- }
-
- if (pDevice->byReAssocCount > 0) { // reject scan when re-associating!
- // send scan event to wpa_Supplicant
- union iwreq_data wrqu;
- PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
- memset(&wrqu, 0, sizeof(wrqu));
- wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
- return 0;
- }
-
- spin_lock_irqsave(&pDevice->lock, flags);
-
- BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass);
-
- // mike add: active scan OR passive scan OR desire_ssid scan
- if (wrq->length == sizeof(struct iw_scan_req)) {
- if (wrq->flags & IW_SCAN_THIS_ESSID) { // desire_ssid scan
- memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
- pItemSSID->byElementID = WLAN_EID_SSID;
- memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
- if (pItemSSID->abySSID[req->essid_len] == '\0') {
- if (req->essid_len > 0)
- pItemSSID->len = req->essid_len;
- } else {
- pItemSSID->len = req->essid_len;
- }
- pMgmt->eScanType = WMAC_SCAN_PASSIVE;
- PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n", ((PWLAN_IE_SSID)abyScanSSID)->abySSID,
- ((PWLAN_IE_SSID)abyScanSSID)->len);
- bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
-
- return 0;
- } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { // passive scan
- pMgmt->eScanType = WMAC_SCAN_PASSIVE;
- }
- } else { // active scan
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
- }
-
- pMgmt->eScanType = WMAC_SCAN_PASSIVE;
- bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
-
- return 0;
-}
-
-/*
- * Wireless Handler : get scan results
- */
-int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_point *wrq = &wrqu->data;
- int ii;
- int jj;
- int kk;
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PKnownBSS pBSS;
- PWLAN_IE_SSID pItemSSID;
- PWLAN_IE_SUPP_RATES pSuppRates;
- PWLAN_IE_SUPP_RATES pExtSuppRates;
- char *current_ev = extra;
- char *end_buf = extra + IW_SCAN_MAX_DATA;
- char *current_val = NULL;
- struct iw_event iwe;
- long ldBm;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (pMgmt->eScanState == WMAC_IS_SCANNING) {
- // In scanning..
- return -EAGAIN;
- }
- pBSS = &(pMgmt->sBSSList[0]);
- for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) {
- if (current_ev >= end_buf)
- break;
- pBSS = &(pMgmt->sBSSList[jj]);
- if (pBSS->bActive) {
- // ADD mac address
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, pBSS->abyBSSID, WLAN_BSSID_LEN);
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
- // ADD ssid
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWESSID;
- pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
- iwe.u.data.length = pItemSSID->len;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
- // ADD mode
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWMODE;
- if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo))
- iwe.u.mode = IW_MODE_INFRA;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- iwe.len = IW_EV_UINT_LEN;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
- // ADD frequency
- pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
- pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = pBSS->uChannel;
- iwe.u.freq.e = 0;
- iwe.u.freq.i = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
- {
- int f = (int)pBSS->uChannel - 1;
- if (f < 0)
- f = 0;
- iwe.u.freq.m = frequency_list[f] * 100000;
- iwe.u.freq.e = 1;
- }
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
- // ADD quality
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVQUAL;
- vnt_rf_rssi_to_dbm(pDevice, (u8)(pBSS->uRSSI), &ldBm);
- iwe.u.qual.level = ldBm;
- iwe.u.qual.noise = 0;
-
- if (-ldBm < 50)
- iwe.u.qual.qual = 100;
- else if (-ldBm > 90)
- iwe.u.qual.qual = 0;
- else
- iwe.u.qual.qual = (40 - (-ldBm - 50)) * 100 / 40;
- iwe.u.qual.updated = 7;
-
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
- // ADD encryption
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWENCODE;
- iwe.u.data.length = 0;
- if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo))
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pItemSSID->abySSID);
-
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- current_val = current_ev + IW_EV_LCP_LEN;
-
- for (kk = 0; kk < 12; kk++) {
- if (pSuppRates->abyRates[kk] == 0)
- break;
- // Bit rate given in 500 kb/s units (+ 0x80)
- iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
- }
- for (kk = 0; kk < 8; kk++) {
- if (pExtSuppRates->abyRates[kk] == 0)
- break;
- // Bit rate given in 500 kb/s units (+ 0x80)
- iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
- }
-
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
- current_ev = current_val;
-
- if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = pBSS->wWPALen;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byWPAIE);
- }
-
- if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = pBSS->wRSNLen;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pBSS->byRSNIE);
- }
- }
- } // for
- wrq->length = current_ev - extra;
- return 0;
-}
-
-/*
- * Wireless Handler: set frequence or channel
- */
-int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_freq *wrq = &wrqu->freq;
- int rc = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n");
-
- // If setting by frequency, convert to a channel
- if ((wrq->e == 1) && (wrq->m >= (int)2.412e8) &&
- (wrq->m <= (int)2.487e8)) {
- int f = wrq->m / 100000;
- int c = 0;
- while ((c < 14) && (f != frequency_list[c]))
- c++;
- wrq->e = 0;
- wrq->m = c + 1;
- }
- // Setting by channel number
- if ((wrq->m > 14) || (wrq->e > 0)) {
- rc = -EOPNOTSUPP;
- } else {
- int channel = wrq->m;
- if ((channel < 1) || (channel > 14)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
- rc = -EINVAL;
- } else {
- // Yes ! We can set it !!!
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
- pDevice->uChannel = channel;
- }
- }
- return rc;
-}
-
-/*
- * Wireless Handler: get frequence or channel
- */
-int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_freq *wrq = &wrqu->freq;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
-#ifdef WEXT_USECHANNELS
- wrq->m = (int)pMgmt->uCurrChannel;
- wrq->e = 0;
-#else
- {
- int f = (int)pMgmt->uCurrChannel - 1;
- if (f < 0)
- f = 0;
- wrq->m = frequency_list[f] * 100000;
- wrq->e = 1;
- }
-#endif
- return 0;
-}
-
-/*
- * Wireless Handler: set operation mode
- */
-int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- __u32 *wmode = &wrqu->mode;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- unsigned long flags;
- int rc = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- switch (*wmode) {
- case IW_MODE_ADHOC:
- if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
- pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
- if (pDevice->flags & DEVICE_FLAGS_OPENED)
- pDevice->bCommit = true;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n");
- break;
- case IW_MODE_AUTO:
- case IW_MODE_INFRA:
- if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
- pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
- if (pDevice->flags & DEVICE_FLAGS_OPENED)
- pDevice->bCommit = true;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n");
- break;
- case IW_MODE_MASTER:
- rc = -EOPNOTSUPP;
- break;
-
- case IW_MODE_REPEAT:
- pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
- rc = -EOPNOTSUPP;
- break;
- default:
- rc = -EINVAL;
- }
-
- if (pDevice->bCommit) {
- if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
- netif_stop_queue(pDevice->dev);
-
- spin_lock_irqsave(&pDevice->lock, flags);
-
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_RUN_AP, NULL);
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Commit the settings\n");
-
- if (pDevice->bLinkPass &&
- memcmp(pMgmt->abyCurrSSID,
- pMgmt->abyDesireSSID,
- WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_DISASSOCIATE, NULL);
- } else {
- pDevice->bLinkPass = false;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- memset(pMgmt->abyCurrBSSID, 0, 6);
- }
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
-
- netif_stop_queue(pDevice->dev);
-
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
-
- if (!pDevice->bWPASuppWextEnabled)
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
-
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_SSID,
- NULL);
- }
- pDevice->bCommit = false;
- }
-
- return rc;
-}
-
-/*
- * Wireless Handler: get operation mode
- */
-int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- __u32 *wmode = &wrqu->mode;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- // If not managed, assume it's ad-hoc
- switch (pMgmt->eConfigMode) {
- case WMAC_CONFIG_ESS_STA:
- *wmode = IW_MODE_INFRA;
- break;
- case WMAC_CONFIG_IBSS_STA:
- *wmode = IW_MODE_ADHOC;
- break;
- case WMAC_CONFIG_AUTO:
- *wmode = IW_MODE_INFRA;
- break;
- case WMAC_CONFIG_AP:
- *wmode = IW_MODE_MASTER;
- break;
- default:
- *wmode = IW_MODE_ADHOC;
- }
-
- return 0;
-}
-
-/*
- * Wireless Handler: get capability range
- */
-int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_point *wrq = &wrqu->data;
- struct iw_range *range = (struct iw_range *)extra;
- int i;
- int k;
- u8 abySupportedRates[13] = {
- 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
- 0x60, 0x6C, 0x90
- };
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n");
- if (wrq->pointer) {
- wrq->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
- range->min_nwid = 0x0000;
- range->max_nwid = 0x0000;
- range->num_channels = 14;
- // Should be based on cap_rid.country to give only
- // what the current card support
- k = 0;
- for (i = 0; i < 14; i++) {
- range->freq[k].i = i + 1; // List index
- range->freq[k].m = frequency_list[i] * 100000;
- range->freq[k++].e = 1; // Values in table in MHz -> * 10^5 * 10
- }
- range->num_frequency = k;
- // Hum... Should put the right values there
- range->max_qual.qual = 100;
- range->max_qual.level = 0;
- range->max_qual.noise = 0;
- range->sensitivity = 255;
-
- for (i = 0; i < 13; i++) {
- range->bitrate[i] = abySupportedRates[i] * 500000;
- if (range->bitrate[i] == 0)
- break;
- }
- range->num_bitrates = i;
-
- // Set an indication of the max TCP throughput
- // in bit/s that we can expect using this interface.
- // May be use for QoS stuff... Jean II
- if (i > 2)
- range->throughput = 5 * 1000 * 1000;
- else
- range->throughput = 1.5 * 1000 * 1000;
-
- range->min_rts = 0;
- range->max_rts = 2312;
- range->min_frag = 256;
- range->max_frag = 2312;
-
- // the encoding capabilities
- range->num_encoding_sizes = 3;
- // 64(40) bits WEP
- range->encoding_size[0] = 5;
- // 128(104) bits WEP
- range->encoding_size[1] = 13;
- // 256 bits for WPA-PSK
- range->encoding_size[2] = 32;
- // 4 keys are allowed
- range->max_encoding_tokens = 4;
-
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
- range->min_pmp = 0;
- range->max_pmp = 1000000; // 1 secs
- range->min_pmt = 0;
- range->max_pmt = 1000000; // 1 secs
- range->pmp_flags = IW_POWER_PERIOD;
- range->pmt_flags = IW_POWER_TIMEOUT;
- range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
-
- // Transmit Power - values are in mW
- range->txpower[0] = 100;
- range->num_txpower = 1;
- range->txpower_capa = IW_TXPOW_MWATT;
- range->we_version_source = WIRELESS_EXT;
- range->we_version_compiled = WIRELESS_EXT;
- range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
- range->retry_flags = IW_RETRY_LIMIT;
- range->r_time_flags = IW_RETRY_LIFETIME;
- range->min_retry = 1;
- range->max_retry = 65535;
- range->min_r_time = 1024;
- range->max_r_time = 65535 * 1024;
- // Experimental measurements - boundary 11/5.5 Mb/s
- // Note : with or without the (local->rssi), results
- // are somewhat different. - Jean II
- range->avg_qual.qual = 6;
- range->avg_qual.level = 176; // -80 dBm
- range->avg_qual.noise = 0;
- }
-
- return 0;
-}
-
-/*
- * Wireless Handler : set ap mac address
- */
-int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct sockaddr *wrq = &wrqu->ap_addr;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int rc = 0;
- u8 ZeroBSSID[WLAN_BSSID_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- PRINT_K(" SIOCSIWAP\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (wrq->sa_family != ARPHRD_ETHER) {
- rc = -EINVAL;
- } else {
- memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
- // mike: add
- if ((is_broadcast_ether_addr(pMgmt->abyDesireBSSID)) ||
- (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)) {
- PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
- return rc;
- }
- // mike add: if desired AP is hidden ssid(there are
- // two same BSSID in list), then ignore,because you
- // don't known which one to be connect with??
- {
- unsigned ii;
- unsigned uSameBssidNum = 0;
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- if (pMgmt->sBSSList[ii].bActive &&
- ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
- pMgmt->abyDesireBSSID)) {
- uSameBssidNum++;
- }
- }
- if (uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!!
- PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
- return rc;
- }
- }
-
- if (pDevice->flags & DEVICE_FLAGS_OPENED)
- pDevice->bCommit = true;
- }
- return rc;
-}
-
-/*
- * Wireless Handler: get ap mac address
- */
-int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct sockaddr *wrq = &wrqu->ap_addr;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
-
- if ((pDevice->bLinkPass == false) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
- memset(wrq->sa_data, 0, 6);
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
- memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
-
- wrq->sa_family = ARPHRD_ETHER;
- return 0;
-}
-
-/*
- * Wireless Handler: get ap list
- */
-int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_point *wrq = &wrqu->data;
- struct sockaddr *sock;
- struct iw_quality *qual;
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PKnownBSS pBSS = &pMgmt->sBSSList[0];
- int ii;
- int jj;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n");
- /* Only super-user can see AP list */
-
- if (pBSS == NULL)
- return -ENODEV;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (!wrq->pointer)
- return -EINVAL;
-
- sock = kcalloc(IW_MAX_AP, sizeof(struct sockaddr), GFP_KERNEL);
- if (sock == NULL)
- return -ENOMEM;
- qual = kcalloc(IW_MAX_AP, sizeof(struct iw_quality), GFP_KERNEL);
- if (qual == NULL) {
- kfree(sock);
- return -ENOMEM;
- }
-
- for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
- if (!pBSS[ii].bActive)
- continue;
- if (jj >= IW_MAX_AP)
- break;
- memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6);
- sock[jj].sa_family = ARPHRD_ETHER;
- qual[jj].level = pBSS[ii].uRSSI;
- qual[jj].qual = qual[jj].noise = 0;
- qual[jj].updated = 2;
- jj++;
- }
-
- wrq->flags = 1; /* Should be defined */
- wrq->length = jj;
- memcpy(extra, sock, sizeof(struct sockaddr) * jj);
- memcpy(extra + sizeof(struct sockaddr) * jj, qual,
- sizeof(struct iw_quality) * jj);
-
- kfree(sock);
- kfree(qual);
-
- return 0;
-}
-
-/*
- * Wireless Handler: set essid
- */
-int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_point *wrq = &wrqu->essid;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PWLAN_IE_SSID pItemSSID;
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
- return -EINVAL;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
-
- pDevice->fWPA_Authened = false;
- // Check if we asked for `any'
- if (wrq->flags == 0) {
- // Just send an empty SSID list
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memset(pMgmt->abyDesireBSSID, 0xFF, 6);
- PRINT_K("set essid to 'any'\n");
- // Unknown desired AP, so here need not associate??
- return 0;
- } else {
- // Set the SSID
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- pItemSSID->byElementID = WLAN_EID_SSID;
-
- memcpy(pItemSSID->abySSID, extra, wrq->length);
- if (pItemSSID->abySSID[wrq->length] == '\0') {
- if (wrq->length > 0)
- pItemSSID->len = wrq->length;
- } else {
- pItemSSID->len = wrq->length;
- }
- PRINT_K("set essid to %s\n", pItemSSID->abySSID);
-
- // mike: need clear desiredBSSID
- if (pItemSSID->len == 0) {
- memset(pMgmt->abyDesireBSSID, 0xFF, 6);
- return 0;
- }
-
- // Wext wil order another command of siwap to link
- // with desired AP, so here need not associate??
- if (pDevice->bWPASuppWextEnabled == true) {
- /*******search if in hidden ssid mode ****/
- PKnownBSS pCurr = NULL;
- u8 abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- unsigned ii;
- unsigned uSameBssidNum = 0;
-
- memcpy(abyTmpDesireSSID, pMgmt->abyDesireSSID, sizeof(abyTmpDesireSSID));
- pCurr = BSSpSearchBSSList(pDevice, NULL,
- abyTmpDesireSSID,
- pDevice->eConfigPHYMode);
-
- if (pCurr == NULL) {
- PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
- vResetCommandTimer((void *)pDevice);
- pMgmt->eScanType = WMAC_SCAN_ACTIVE;
- bScheduleCommand((void *)pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand((void *)pDevice,
- WLAN_CMD_SSID,
- pMgmt->abyDesireSSID);
- } else { // mike: to find out if that desired SSID is a
- // hidden-ssid AP, by means of judging if there
- // are two same BSSID exist in list ?
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- if (pMgmt->sBSSList[ii].bActive &&
- ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
- pCurr->abyBSSID)) {
- uSameBssidNum++;
- }
- }
- if (uSameBssidNum >= 2) { // hit: desired AP is in hidden ssid mode!!!
- PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
- vResetCommandTimer((void *)pDevice);
- pMgmt->eScanType = WMAC_SCAN_PASSIVE; // this scan type, you'll submit scan result!
- bScheduleCommand((void *)pDevice,
- WLAN_CMD_BSSID_SCAN,
- pMgmt->abyDesireSSID);
- bScheduleCommand((void *)pDevice,
- WLAN_CMD_SSID,
- pMgmt->abyDesireSSID);
- }
- }
- return 0;
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
- }
-
- if (pDevice->flags & DEVICE_FLAGS_OPENED)
- pDevice->bCommit = true;
-
- return 0;
-}
-
-/*
- * Wireless Handler: get essid
- */
-int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_point *wrq = &wrqu->essid;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PWLAN_IE_SSID pItemSSID;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- // Note: if wrq->u.data.flags != 0, we should get the relevant
- // SSID from the SSID list...
-
- // Get the current SSID
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
- extra[pItemSSID->len] = '\0';
-
- wrq->length = pItemSSID->len;
- wrq->flags = 1; // active
-
- return 0;
-}
-
-/*
- * Wireless Handler: set data rate
- */
-int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->bitrate;
- int rc = 0;
- u8 brate = 0;
- int i;
- u8 abySupportedRates[13] = {
- 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
- 0x60, 0x6C, 0x90
- };
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
- rc = -EINVAL;
- return rc;
- }
-
- // First: get a valid bit rate value
-
- // Which type of value
- if ((wrq->value < 13) && (wrq->value >= 0)) {
- // Setting by rate index
- // Find value in the magic rate table
- brate = wrq->value;
- } else {
- // Setting by frequency value
- u8 normvalue = (u8)(wrq->value/500000);
-
- // Check if rate is valid
- for (i = 0; i < 13; i++) {
- if (normvalue == abySupportedRates[i]) {
- brate = i;
- break;
- }
- }
- }
- // -1 designed the max rate (mostly auto mode)
- if (wrq->value == -1) {
- // Get the highest available rate
- for (i = 0; i < 13; i++) {
- if (abySupportedRates[i] == 0)
- break;
- }
- if (i != 0)
- brate = i - 1;
-
- }
- // Check that it is valid
- // brate is index of abySupportedRates[]
- if (brate > 13) {
- rc = -EINVAL;
- return rc;
- }
-
- // Now, check if we want a fixed or auto value
- if (wrq->fixed != 0) {
- // Fixed mode
- // One rate, fixed
- pDevice->bFixRate = true;
- if ((pDevice->byBBType == BB_TYPE_11B) && (brate > 3)) {
- pDevice->uConnectionRate = 3;
- } else {
- pDevice->uConnectionRate = brate;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
- }
- } else {
- pDevice->bFixRate = false;
- pDevice->uConnectionRate = 13;
- }
-
- return rc;
-}
-
-/*
- * Wireless Handler: get data rate
- */
-int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->bitrate;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- {
- u8 abySupportedRates[13] = {
- 0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30,
- 0x48, 0x60, 0x6C, 0x90
- };
- int brate = 0;
-
- if (pDevice->uConnectionRate < 13) {
- brate = abySupportedRates[pDevice->uConnectionRate];
- } else {
- if (pDevice->byBBType == BB_TYPE_11B)
- brate = 0x16;
- if (pDevice->byBBType == BB_TYPE_11G)
- brate = 0x6C;
- if (pDevice->byBBType == BB_TYPE_11A)
- brate = 0x6C;
- }
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- if (pDevice->byBBType == BB_TYPE_11B)
- brate = 0x16;
- if (pDevice->byBBType == BB_TYPE_11G)
- brate = 0x6C;
- if (pDevice->byBBType == BB_TYPE_11A)
- brate = 0x6C;
- }
- if (pDevice->uConnectionRate == 13)
- brate = abySupportedRates[pDevice->wCurrentRate];
- wrq->value = brate * 500000;
- // If more than one rate, set auto
- if (pDevice->bFixRate == true)
- wrq->fixed = true;
- }
-
- return 0;
-}
-
-/*
- * Wireless Handler: set rts threshold
- */
-int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->rts;
-
- if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
- return -EINVAL;
-
- else if (wrq->disabled)
- pDevice->wRTSThreshold = 2312;
- else
- pDevice->wRTSThreshold = wrq->value;
-
- return 0;
-}
-
-/*
- * Wireless Handler: get rts
- */
-int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->rts;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n");
- wrq->value = pDevice->wRTSThreshold;
- wrq->disabled = (wrq->value >= 2312);
- wrq->fixed = 1;
- return 0;
-}
-
-/*
- * Wireless Handler: set fragment threshold
- */
-int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->frag;
- int rc = 0;
- int fthr = wrq->value;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n");
-
- if (wrq->disabled)
- fthr = 2312;
- if ((fthr < 256) || (fthr > 2312)) {
- rc = -EINVAL;
- } else {
- fthr &= ~0x1; // Get an even value
- pDevice->wFragmentationThreshold = (u16)fthr;
- }
- return rc;
-}
-
-/*
- * Wireless Handler: get fragment threshold
- */
-int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->frag;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n");
- wrq->value = pDevice->wFragmentationThreshold;
- wrq->disabled = (wrq->value >= 2312);
- wrq->fixed = 1;
- return 0;
-}
-
-/*
- * Wireless Handler: set retry threshold
- */
-int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->retry;
- int rc = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n");
-
- if (wrq->disabled) {
- rc = -EINVAL;
- return rc;
- }
-
- if (wrq->flags & IW_RETRY_LIMIT) {
- if (wrq->flags & IW_RETRY_MAX) {
- pDevice->byLongRetryLimit = wrq->value;
- } else if (wrq->flags & IW_RETRY_MIN) {
- pDevice->byShortRetryLimit = wrq->value;
- } else {
- // No modifier : set both
- pDevice->byShortRetryLimit = wrq->value;
- pDevice->byLongRetryLimit = wrq->value;
- }
- }
- if (wrq->flags & IW_RETRY_LIFETIME)
- pDevice->wMaxTransmitMSDULifetime = wrq->value;
- return rc;
-}
-
-/*
- * Wireless Handler: get retry threshold
- */
-int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->retry;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n");
- wrq->disabled = 0; // Can't be disabled
-
- // Note: by default, display the min retry number
- if ((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
- wrq->flags = IW_RETRY_LIFETIME;
- wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; // ms
- } else if ((wrq->flags & IW_RETRY_MAX)) {
- wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- wrq->value = (int)pDevice->byLongRetryLimit;
- } else {
- wrq->flags = IW_RETRY_LIMIT;
- wrq->value = (int)pDevice->byShortRetryLimit;
- if ((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
- wrq->flags |= IW_RETRY_MIN;
- }
- return 0;
-}
-
-/*
- * Wireless Handler: set encode mode
- */
-int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_point *wrq = &wrqu->encoding;
- u32 dwKeyIndex = (u32)(wrq->flags & IW_ENCODE_INDEX);
- int ii;
- u8 uu;
- int rc = 0;
- int index = (wrq->flags & IW_ENCODE_INDEX);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- // Check the size of the key
- if (wrq->length > WLAN_WEP232_KEYLEN) {
- rc = -EINVAL;
- return rc;
- }
-
- if (dwKeyIndex > WLAN_WEP_NKEYS) {
- rc = -EINVAL;
- return rc;
- }
-
- if (dwKeyIndex > 0)
- dwKeyIndex--;
-
- // Send the key to the card
- if (wrq->length > 0) {
- if (wrq->length == WLAN_WEP232_KEYLEN) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
- } else if (wrq->length == WLAN_WEP104_KEYLEN) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
- } else if (wrq->length == WLAN_WEP40_KEYLEN) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
- }
- memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
- memcpy(pDevice->abyKey, extra, wrq->length);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
- for (ii = 0; ii < wrq->length; ii++)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
-
- if (pDevice->flags & DEVICE_FLAGS_OPENED) {
- KeybSetDefaultKey(pDevice,
- &(pDevice->sKey),
- dwKeyIndex | (1 << 31),
- wrq->length, NULL,
- pDevice->abyKey,
- KEY_CTL_WEP);
- }
- pDevice->byKeyIndex = (u8)dwKeyIndex;
- pDevice->uKeyLength = wrq->length;
- pDevice->bTransmitKey = true;
- pDevice->bEncryptionEnable = true;
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-
- // Do we want to just set the transmit key index?
- if (index < 4) {
- pDevice->byKeyIndex = index;
- } else if (!(wrq->flags & IW_ENCODE_MODE)) {
- rc = -EINVAL;
- return rc;
- }
- }
- // Read the flags
- if (wrq->flags & IW_ENCODE_DISABLED) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
- pMgmt->bShareKeyAlgorithm = false;
- pDevice->bEncryptionEnable = false;
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- if (pDevice->flags & DEVICE_FLAGS_OPENED) {
- for (uu = 0; uu < MAX_KEY_TABLE; uu++)
- MACvDisableKeyEntry(pDevice, uu);
- }
- }
- if (wrq->flags & IW_ENCODE_RESTRICTED) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
- pMgmt->bShareKeyAlgorithm = true;
- }
- if (wrq->flags & IW_ENCODE_OPEN) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
- pMgmt->bShareKeyAlgorithm = false;
- }
-
- memset(pMgmt->abyDesireBSSID, 0xFF, 6);
-
- return rc;
-}
-
-int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_point *wrq = &wrqu->encoding;
- char abyKey[WLAN_WEP232_KEYLEN];
-
- unsigned index = (unsigned)(wrq->flags & IW_ENCODE_INDEX);
- PSKeyItem pKey = NULL;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (index > WLAN_WEP_NKEYS)
- return -EINVAL;
- if (index < 1) { // get default key
- if (pDevice->byKeyIndex < WLAN_WEP_NKEYS)
- index = pDevice->byKeyIndex;
- else
- index = 0;
- } else {
- index--;
- }
-
- memset(abyKey, 0, WLAN_WEP232_KEYLEN);
- // Check encryption mode
- wrq->flags = IW_ENCODE_NOKEY;
- // Is WEP enabled ???
- if (pDevice->bEncryptionEnable)
- wrq->flags |= IW_ENCODE_ENABLED;
- else
- wrq->flags |= IW_ENCODE_DISABLED;
-
- if (pMgmt->bShareKeyAlgorithm)
- wrq->flags |= IW_ENCODE_RESTRICTED;
- else
- wrq->flags |= IW_ENCODE_OPEN;
- wrq->length = 0;
-
- if ((index == 0) && (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled ||
- pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)) { // get wpa pairwise key
- if (KeybGetKey(&(pDevice->sKey), pMgmt->abyCurrBSSID, 0xffffffff, &pKey)) {
- wrq->length = pKey->uKeyLength;
- memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
- memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
- }
- } else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (u8)index, &pKey)) {
- wrq->length = pKey->uKeyLength;
- memcpy(abyKey, pKey->abyKey, pKey->uKeyLength);
- memcpy(extra, abyKey, WLAN_WEP232_KEYLEN);
- }
-
- wrq->flags |= index + 1;
- return 0;
-}
-
-/*
- * Wireless Handler: set power mode
- */
-int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_param *wrq = &wrqu->power;
- int rc = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
- rc = -EINVAL;
- return rc;
- }
-
- if (wrq->disabled) {
- pDevice->ePSMode = WMAC_POWER_CAM;
- PSvDisablePowerSaving(pDevice);
- return rc;
- }
- if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- pDevice->ePSMode = WMAC_POWER_FAST;
- PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
-
- } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
- pDevice->ePSMode = WMAC_POWER_FAST;
- PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval);
- }
-
- switch (wrq->flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
- rc = -EINVAL;
- break;
- case IW_POWER_ALL_R:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
- rc = -EINVAL;
- case IW_POWER_ON:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
- break;
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-/*
- * Wireless Handler: get power mode
- */
-int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_param *wrq = &wrqu->power;
- int mode = pDevice->ePSMode;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- wrq->disabled = (mode == WMAC_POWER_CAM);
- if (wrq->disabled)
- return 0;
-
- if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrq->value = (int)((pMgmt->wListenInterval *
- pMgmt->wCurrBeaconPeriod) / 100);
- wrq->flags = IW_POWER_TIMEOUT;
- } else {
- wrq->value = (int)((pMgmt->wListenInterval *
- pMgmt->wCurrBeaconPeriod) / 100);
- wrq->flags = IW_POWER_PERIOD;
- }
-
- wrq->flags |= IW_POWER_ALL_R;
- return 0;
-}
-
-/*
- * Wireless Handler: get Sensitivity
- */
-int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct iw_param *wrq = &wrqu->sens;
- long ldBm;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n");
- if (pDevice->bLinkPass == true) {
- vnt_rf_rssi_to_dbm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
- wrq->value = ldBm;
- } else {
- wrq->value = 0;
- }
- wrq->disabled = (wrq->value == 0);
- wrq->fixed = 1;
- return 0;
-}
-
-int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_param *wrq = &wrqu->param;
- int ret = 0;
- static int wpa_version = 0; // must be static to save the last value, einsn liu
- static int pairwise = 0;
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n");
- switch (wrq->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- wpa_version = wrq->value;
- if (wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
- PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
- } else if (wrq->value == IW_AUTH_WPA_VERSION_WPA) {
- PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
- } else {
- PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
- }
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- pairwise = wrq->value;
- PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
- if (pairwise == IW_AUTH_CIPHER_CCMP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
- } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- } else if (pairwise == IW_AUTH_CIPHER_WEP40 ||
- pairwise == IW_AUTH_CIPHER_WEP104) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- } else if (pairwise == IW_AUTH_CIPHER_NONE) {
- // do nothing, einsn liu
- } else {
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- }
- break;
- case IW_AUTH_CIPHER_GROUP:
- PRINT_K("iwctl_siwauth:set GROUP=%d\n", wrq->value);
- if (wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
- break;
- if (pairwise == IW_AUTH_CIPHER_NONE) {
- if (wrq->value == IW_AUTH_CIPHER_CCMP)
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
- else
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- }
- break;
- case IW_AUTH_KEY_MGMT:
- PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version, wrq->value);
- if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) {
- if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
- pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
- else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
- } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
- if (wrq->value == 0) {
- pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
- } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
- pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
- } else {
- pMgmt->eAuthenMode = WMAC_AUTH_WPA;
- }
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- break; /* FIXME */
- case IW_AUTH_DROP_UNENCRYPTED:
- break;
- case IW_AUTH_80211_AUTH_ALG:
- PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n", wrq->value);
- if (wrq->value == IW_AUTH_ALG_OPEN_SYSTEM)
- pMgmt->bShareKeyAlgorithm = false;
- else if (wrq->value == IW_AUTH_ALG_SHARED_KEY)
- pMgmt->bShareKeyAlgorithm = true;
- break;
- case IW_AUTH_WPA_ENABLED:
- break;
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- break;
- case IW_AUTH_ROAMING_CONTROL:
- ret = -EOPNOTSUPP;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- pDevice->bEncryptionEnable = !!wrq->value;
- if (pDevice->bEncryptionEnable == false) {
- wpa_version = 0;
- pairwise = 0;
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- pMgmt->bShareKeyAlgorithm = false;
- pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
- PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
- }
- break;
- default:
- PRINT_K("iwctl_siwauth: not supported %x\n", wrq->flags);
- ret = -EOPNOTSUPP;
- break;
- }
- return ret;
-}
-
-int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return -EOPNOTSUPP;
-}
-
-int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_point *wrq = &wrqu->data;
- int ret = 0;
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (wrq->length) {
- if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
- ret = -EINVAL;
- goto out;
- }
- if (wrq->length > MAX_WPA_IE_LEN) {
- ret = -ENOMEM;
- goto out;
- }
- memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
-
- memcpy(pMgmt->abyWPAIE, extra, wrq->length);
- pMgmt->wWPAIELen = wrq->length;
- } else {
- memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
- pMgmt->wWPAIELen = 0;
- }
-
-out: // not completely ...not necessary in wpa_supplicant 0.5.8
- return ret;
-}
-
-int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_point *wrq = &wrqu->data;
- int ret = 0;
- int space = wrq->length;
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- wrq->length = 0;
- if (pMgmt->wWPAIELen > 0) {
- wrq->length = pMgmt->wWPAIELen;
-
- if (pMgmt->wWPAIELen <= space)
- memcpy(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
- else
- ret = -E2BIG;
- }
- return ret;
-}
-
-int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_point *wrq = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
- struct viawget_wpa_param *param = NULL;
-// original member
- wpa_alg alg_name;
- u8 addr[6];
- int key_idx;
- int set_tx = 0;
- u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
- u8 key[64];
- size_t seq_len = 0;
- size_t key_len = 0;
- u8 *buf;
- u8 key_array[64];
- int ret = 0;
-
- PRINT_K("SIOCSIWENCODEEXT......\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
- return -ENODEV;
-
- buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- param = (struct viawget_wpa_param *)buf;
-
-// recover alg_name
- switch (ext->alg) {
- case IW_ENCODE_ALG_NONE:
- alg_name = WPA_ALG_NONE;
- break;
- case IW_ENCODE_ALG_WEP:
- alg_name = WPA_ALG_WEP;
- break;
- case IW_ENCODE_ALG_TKIP:
- alg_name = WPA_ALG_TKIP;
- break;
- case IW_ENCODE_ALG_CCMP:
- alg_name = WPA_ALG_CCMP;
- break;
- default:
- PRINT_K("Unknown alg = %d\n", ext->alg);
- ret = -ENOMEM;
- goto error;
- }
-// recover addr
- memcpy(addr, ext->addr.sa_data, ETH_ALEN);
-// recover key_idx
- key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
-// recover set_tx
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- set_tx = 1;
-// recover seq,seq_len
- if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
- seq_len = IW_ENCODE_SEQ_MAX_SIZE;
- memcpy(seq, ext->rx_seq, seq_len);
- }
-// recover key,key_len
- if (ext->key_len) {
- key_len = ext->key_len;
- memcpy(key, &ext->key[0], key_len);
- }
- memset(key_array, 0, 64);
- if (key_len > 0) {
- memcpy(key_array, key, key_len);
- if (key_len == 32) {
- // notice ! the oder
- memcpy(&key_array[16], &key[24], 8);
- memcpy(&key_array[24], &key[16], 8);
- }
- }
-
-/**************Translate iw_encode_ext to viawget_wpa_param****************/
- memcpy(param->addr, addr, ETH_ALEN);
- param->u.wpa_key.alg_name = (int)alg_name;
- param->u.wpa_key.set_tx = set_tx;
- param->u.wpa_key.key_index = key_idx;
- param->u.wpa_key.key_len = key_len;
- param->u.wpa_key.key = (u8 *)key_array;
- param->u.wpa_key.seq = (u8 *)seq;
- param->u.wpa_key.seq_len = seq_len;
-
-/****set if current action is Network Manager count?? */
-/****this method is so foolish,but there is no other way??? */
- if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
- if (param->u.wpa_key.key_index == 0) {
- pDevice->bwextstep0 = true;
- }
- if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = true;
- }
- if ((pDevice->bwextstep1 == true) && (param->u.wpa_key.key_index == 2)) {
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = true;
- }
- if ((pDevice->bwextstep2 == true) && (param->u.wpa_key.key_index == 3)) {
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = true;
- }
- }
- if (pDevice->bwextstep3 == true) {
- PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = false;
- pDevice->bWPASuppWextEnabled = true;
- memset(pMgmt->abyDesireBSSID, 0xFF, 6);
- KeyvInitTable(pDevice, &pDevice->sKey);
- }
-/*******/
- ret = wpa_set_keys(pDevice, param);
-
-error:
- kfree(buf);
- return ret;
-}
-
-int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- return -EOPNOTSUPP;
-}
-
-int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- int ret = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n");
-
- if (pMgmt == NULL)
- return -EFAULT;
-
- if (memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)) {
- ret = -EINVAL;
- return ret;
- }
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- case IW_MLME_DISASSOC:
- if (pDevice->bLinkPass == true) {
- PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
- bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE,
- NULL);
- }
- break;
- default:
- ret = -EOPNOTSUPP;
- }
- return ret;
-}
-
-static int iwctl_config_commit(struct net_device *dev,
- struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SIOCSIWCOMMIT\n");
-
- return 0;
-}
-
-static const iw_handler iwctl_handler[] = {
- IW_HANDLER(SIOCSIWCOMMIT, iwctl_config_commit),
- IW_HANDLER(SIOCGIWNAME, iwctl_giwname),
- IW_HANDLER(SIOCSIWFREQ, iwctl_siwfreq),
- IW_HANDLER(SIOCGIWFREQ, iwctl_giwfreq),
- IW_HANDLER(SIOCSIWMODE, iwctl_siwmode),
- IW_HANDLER(SIOCGIWMODE, iwctl_giwmode),
- IW_HANDLER(SIOCGIWSENS, iwctl_giwsens),
- IW_HANDLER(SIOCGIWRANGE, iwctl_giwrange),
- IW_HANDLER(SIOCSIWAP, iwctl_siwap),
- IW_HANDLER(SIOCGIWAP, iwctl_giwap),
- IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
- IW_HANDLER(SIOCGIWAPLIST, iwctl_giwaplist),
- IW_HANDLER(SIOCSIWSCAN, iwctl_siwscan),
- IW_HANDLER(SIOCGIWSCAN, iwctl_giwscan),
- IW_HANDLER(SIOCSIWESSID, iwctl_siwessid),
- IW_HANDLER(SIOCGIWESSID, iwctl_giwessid),
- IW_HANDLER(SIOCSIWRATE, iwctl_siwrate),
- IW_HANDLER(SIOCGIWRATE, iwctl_giwrate),
- IW_HANDLER(SIOCSIWRTS, iwctl_siwrts),
- IW_HANDLER(SIOCGIWRTS, iwctl_giwrts),
- IW_HANDLER(SIOCSIWFRAG, iwctl_siwfrag),
- IW_HANDLER(SIOCGIWFRAG, iwctl_giwfrag),
- IW_HANDLER(SIOCSIWRETRY, iwctl_siwretry),
- IW_HANDLER(SIOCGIWRETRY, iwctl_giwretry),
- IW_HANDLER(SIOCSIWENCODE, iwctl_siwencode),
- IW_HANDLER(SIOCGIWENCODE, iwctl_giwencode),
- IW_HANDLER(SIOCSIWPOWER, iwctl_siwpower),
- IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
- IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
- IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
- IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
- IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
- IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
- IW_HANDLER(SIOCGIWENCODEEXT, iwctl_giwencodeext)
-};
-
-static const iw_handler iwctl_private_handler[] = {
- NULL, // SIOCIWFIRSTPRIV
-};
-
-const struct iw_handler_def iwctl_handler_def = {
- .get_wireless_stats = &iwctl_get_wireless_stats,
- .num_standard = ARRAY_SIZE(iwctl_handler),
- .num_private = 0,
- .num_private_args = 0,
- .standard = iwctl_handler,
- .private = NULL,
- .private_args = NULL,
-};
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
deleted file mode 100644
index dceda0dbdfe1..000000000000
--- a/drivers/staging/vt6656/iwctl.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: iwctl.h
- *
- * Purpose:
- *
- * Author: Lyndon Chen
- *
- * Date: May 21, 2004
- *
- */
-
-#ifndef __IWCTL_H__
-#define __IWCTL_H__
-
-#include "device.h"
-
-struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev);
-
-int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwrange(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwmode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwfreq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwfreq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwname(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwap(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwrts(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwrts(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwfrag(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwfrag(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwretry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwretry(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwpower(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwauth(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwgenie(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern const struct iw_handler_def iwctl_handler_def;
-extern const struct iw_priv_args iwctl_priv_args;
-
-#endif /* __IWCTL_H__ */
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index 38ea67531d97..22f2961d2225 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -26,706 +26,157 @@
* Date: May 29, 2003
*
* Functions:
- * KeyvInitTable - Init Key management table
- * KeybGetKey - Get Key from table
- * KeybSetKey - Set Key to table
- * KeybRemoveKey - Remove Key from table
- * KeybGetTransmitKey - Get Transmit Key from table
*
* Revision History:
*
*/
#include "mac.h"
-#include "tmacro.h"
#include "key.h"
#include "usbpipe.h"
-static int msglevel =MSG_LEVEL_INFO;
-//static int msglevel =MSG_LEVEL_DEBUG;
-
-static void s_vCheckKeyTableValid(struct vnt_private *pDevice,
- PSKeyManagement pTable)
-{
- int i;
- u16 wLength = 0;
- u8 pbyData[MAX_KEY_TABLE];
-
- for (i=0;i<MAX_KEY_TABLE;i++) {
- if ((pTable->KeyTable[i].bInUse == true) &&
- (pTable->KeyTable[i].PairwiseKey.bKeyValid == false) &&
- (pTable->KeyTable[i].GroupKey[0].bKeyValid == false) &&
- (pTable->KeyTable[i].GroupKey[1].bKeyValid == false) &&
- (pTable->KeyTable[i].GroupKey[2].bKeyValid == false) &&
- (pTable->KeyTable[i].GroupKey[3].bKeyValid == false)
- ) {
-
- pTable->KeyTable[i].bInUse = false;
- pTable->KeyTable[i].wKeyCtl = 0;
- pTable->KeyTable[i].bSoftWEP = false;
- pbyData[wLength++] = (u8) i;
- //MACvDisableKeyEntry(pDevice, i);
- }
- }
-
- if (wLength != 0)
- vnt_control_out(pDevice, MESSAGE_TYPE_CLRKEYENTRY,
- 0, 0, wLength, pbyData);
-
-}
-
-/*
- * Description: Init Key management table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * Out:
- * none
- *
- * Return Value: none
- *
- */
-void KeyvInitTable(struct vnt_private *pDevice, PSKeyManagement pTable)
+int vnt_key_init_table(struct vnt_private *priv)
{
- int i, jj;
- u8 pbyData[MAX_KEY_TABLE+1];
-
- for (i=0;i<MAX_KEY_TABLE;i++) {
- pTable->KeyTable[i].bInUse = false;
- pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
- pTable->KeyTable[i].PairwiseKey.pvKeyTable =
- (void *)&pTable->KeyTable[i];
- for (jj=0; jj < MAX_GROUP_KEY; jj++) {
- pTable->KeyTable[i].GroupKey[jj].bKeyValid = false;
- pTable->KeyTable[i].GroupKey[jj].pvKeyTable =
- (void *) &(pTable->KeyTable[i]);
- }
- pTable->KeyTable[i].wKeyCtl = 0;
- pTable->KeyTable[i].dwGTKeyIndex = 0;
- pTable->KeyTable[i].bSoftWEP = false;
- pbyData[i] = (u8) i;
- }
- pbyData[i] = (u8) i;
+ int ret;
+ u8 i;
+ u8 data[MAX_KEY_TABLE];
- vnt_control_out(pDevice, MESSAGE_TYPE_CLRKEYENTRY,
- 0, 0, 11, pbyData);
+ for (i = 0; i < MAX_KEY_TABLE; i++)
+ data[i] = i;
- return;
-}
-
-/*
- * Description: Get Key from table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * pbyBSSID - BSSID of Key
- * dwKeyIndex - Key Index (0xFFFFFFFF means pairwise key)
- * Out:
- * pKey - Key return
- *
- * Return Value: true if found otherwise false
- *
- */
-int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
- PSKeyItem *pKey)
-{
- int i;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey()\n");
+ ret = vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY,
+ 0, 0, ARRAY_SIZE(data), data);
- *pKey = NULL;
- for (i=0;i<MAX_KEY_TABLE;i++) {
- if ((pTable->KeyTable[i].bInUse == true) &&
- ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
- if (dwKeyIndex == 0xFFFFFFFF) {
- if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
- *pKey = &(pTable->KeyTable[i].PairwiseKey);
- return (true);
- }
- else {
- return (false);
- }
- } else if (dwKeyIndex < MAX_GROUP_KEY) {
- if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == true) {
- *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
- return (true);
- }
- else {
- return (false);
- }
- }
- else {
- return (false);
- }
- }
- }
- return (false);
+ return ret;
}
-/*
- * Description: Set Key to table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * pbyBSSID - BSSID of Key
- * dwKeyIndex - Key index (reference to NDIS DDK)
- * uKeyLength - Key length
- * KeyRSC - Key RSC
- * pbyKey - Pointer to key
- * Out:
- * none
- *
- * Return Value: true if success otherwise false
- *
- */
-int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable,
- u8 *pbyBSSID, u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode)
+static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
+ struct ieee80211_key_conf *key, u32 key_type, u32 mode,
+ bool onfly_latch)
{
- PSKeyItem pKey;
- int i, j, ii;
- u32 uKeyIdx;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Enter KeybSetKey: %X\n", dwKeyIndex);
-
- j = (MAX_KEY_TABLE-1);
- for (i=0;i<(MAX_KEY_TABLE-1);i++) {
- if ((pTable->KeyTable[i].bInUse == false) &&
- (j == (MAX_KEY_TABLE-1))) {
- // found empty table
- j = i;
- }
- if ((pTable->KeyTable[i].bInUse == true) &&
- ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
- // found table already exist
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
- // Pairwise key
- pKey = &(pTable->KeyTable[i].PairwiseKey);
- pTable->KeyTable[i].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
- pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
- uKeyIdx = 4; // use HW key entry 4 for pairwise key
- } else {
- // Group key
- if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
- return (false);
- pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
- if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
- // Group transmit key
- pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Group transmit key(R)[%X]: %d\n",
- pTable->KeyTable[i].dwGTKeyIndex, i);
- }
- pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
- pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
- pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
- uKeyIdx = (dwKeyIndex & 0x000000FF);
- }
- pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
-
- pKey->bKeyValid = true;
- pKey->uKeyLength = uKeyLength;
- pKey->dwKeyIndex = dwKeyIndex;
- pKey->byCipherSuite = byKeyDecMode;
- memcpy(pKey->abyKey, pbyKey, uKeyLength);
- if (byKeyDecMode == KEY_CTL_WEP) {
- if (uKeyLength == WLAN_WEP40_KEYLEN)
- pKey->abyKey[15] &= 0x7F;
- if (uKeyLength == WLAN_WEP104_KEYLEN)
- pKey->abyKey[15] |= 0x80;
- }
-
- MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx,
- pbyBSSID, pKey->abyKey);
-
- if ((dwKeyIndex & USE_KEYRSC) == 0)
- pKey->KeyRSC = 0; /* RSC set by NIC */
- else
- pKey->KeyRSC = *KeyRSC;
-
- pKey->dwTSC47_16 = 0;
- pKey->wTSC15_0 = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
- for (ii = 0; ii < pKey->uKeyLength; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
- pKey->dwTSC47_16);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ",
- pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
- pKey->dwKeyIndex);
-
- return (true);
- }
- }
- if (j < (MAX_KEY_TABLE-1)) {
- memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN);
- pTable->KeyTable[j].bInUse = true;
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
- // Pairwise key
- pKey = &(pTable->KeyTable[j].PairwiseKey);
- pTable->KeyTable[j].wKeyCtl &= 0xFFF0; // clear pairwise key control filed
- pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
- uKeyIdx = 4; // use HW key entry 4 for pairwise key
- } else {
- // Group key
- if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
- return (false);
- pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
- if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
- // Group transmit key
- pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Group transmit key(N)[%X]: %d\n",
- pTable->KeyTable[j].dwGTKeyIndex, j);
- }
- pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed
- pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
- pTable->KeyTable[j].wKeyCtl |= 0x0040; // use group key for group address
- uKeyIdx = (dwKeyIndex & 0x000000FF);
- }
- pTable->KeyTable[j].wKeyCtl |= 0x8000; // enable on-fly
-
- pKey->bKeyValid = true;
- pKey->uKeyLength = uKeyLength;
- pKey->dwKeyIndex = dwKeyIndex;
- pKey->byCipherSuite = byKeyDecMode;
- memcpy(pKey->abyKey, pbyKey, uKeyLength);
- if (byKeyDecMode == KEY_CTL_WEP) {
- if (uKeyLength == WLAN_WEP40_KEYLEN)
- pKey->abyKey[15] &= 0x7F;
- if (uKeyLength == WLAN_WEP104_KEYLEN)
- pKey->abyKey[15] |= 0x80;
- }
-
- MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx,
- pbyBSSID, pKey->abyKey);
-
- if ((dwKeyIndex & USE_KEYRSC) == 0)
- pKey->KeyRSC = 0; /* RSC set by NIC */
- else
- pKey->KeyRSC = *KeyRSC;
-
- pKey->dwTSC47_16 = 0;
- pKey->wTSC15_0 = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
- for (ii = 0; ii < pKey->uKeyLength; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
- pKey->dwTSC47_16);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
- pKey->dwKeyIndex);
-
- return (true);
- }
- return (false);
+ struct vnt_private *priv = hw->priv;
+ u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ u16 key_mode = 0;
+ u32 entry = 0;
+ u8 *bssid;
+ u8 key_inx = key->keyidx;
+ u8 i;
+
+ if (mac_addr)
+ bssid = mac_addr;
+ else
+ bssid = &broadcast[0];
+
+ if (key_type != VNT_KEY_DEFAULTKEY) {
+ for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
+ if (!test_bit(i, &priv->key_entry_inuse)) {
+ set_bit(i, &priv->key_entry_inuse);
+
+ key->hw_key_idx = i;
+ entry = key->hw_key_idx;
+ break;
+ }
+ }
+ }
+
+ switch (key_type) {
+ /* fallthrough */
+ case VNT_KEY_DEFAULTKEY:
+ /* default key last entry */
+ entry = MAX_KEY_TABLE - 1;
+ key->hw_key_idx = entry;
+ case VNT_KEY_ALLGROUP:
+ key_mode |= VNT_KEY_ALLGROUP;
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY_ALL;
+ case VNT_KEY_GROUP_ADDRESS:
+ key_mode |= mode;
+ case VNT_KEY_GROUP:
+ key_mode |= (mode << 4);
+ key_mode |= VNT_KEY_GROUP;
+ break;
+ case VNT_KEY_PAIRWISE:
+ key_mode |= mode;
+ key_inx = 4;
+ /* Don't save entry for pairwise key for station mode */
+ if (priv->op_mode == NL80211_IFTYPE_STATION)
+ clear_bit(entry, &priv->key_entry_inuse);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (onfly_latch)
+ key_mode |= VNT_KEY_ONFLY;
+
+ if (mode == KEY_CTL_WEP) {
+ if (key->keylen == WLAN_KEY_LEN_WEP40)
+ key->key[15] &= 0x7f;
+ if (key->keylen == WLAN_KEY_LEN_WEP104)
+ key->key[15] |= 0x80;
+ }
+
+ vnt_mac_set_keyentry(priv, key_mode, entry, key_inx, bssid, key->key);
+
+ return 0;
}
-/*
- * Description: Remove Key from table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * pbyBSSID - BSSID of Key
- * dwKeyIndex - Key Index (reference to NDIS DDK)
- * Out:
- * none
- *
- * Return Value: true if success otherwise false
- *
- */
-
-int KeybRemoveKey(struct vnt_private *pDevice, PSKeyManagement pTable,
- u8 *pbyBSSID, u32 dwKeyIndex)
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
{
- int i;
- int bReturnValue = false;
-
- if (is_broadcast_ether_addr(pbyBSSID)) {
- // delete all keys
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
- for (i=0;i<MAX_KEY_TABLE;i++) {
- pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
- }
- bReturnValue = true;
- }
- else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
- for (i=0;i<MAX_KEY_TABLE;i++) {
- pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
- if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
- // remove Group transmit key
- pTable->KeyTable[i].dwGTKeyIndex = 0;
- }
- }
- bReturnValue = true;
- }
- else {
- bReturnValue = false;
- }
-
- } else {
- for (i=0;i<MAX_KEY_TABLE;i++) {
- if ( (pTable->KeyTable[i].bInUse == true) &&
- ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
-
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
- pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
- bReturnValue = true;
- break;
- }
- else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
- pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = false;
- if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
- // remove Group transmit key
- pTable->KeyTable[i].dwGTKeyIndex = 0;
- }
- bReturnValue = true;
- break;
- }
- else {
- bReturnValue = false;
- break;
- }
- } //pTable->KeyTable[i].bInUse == true
- } //for
- bReturnValue = true;
- }
+ struct ieee80211_bss_conf *conf = &vif->bss_conf;
+ struct vnt_private *priv = hw->priv;
+ u8 *mac_addr = NULL;
+ u8 key_dec_mode = 0;
+ int ret = 0, u;
- s_vCheckKeyTableValid(pDevice,pTable);
- return bReturnValue;
+ if (sta)
+ mac_addr = &sta->addr[0];
-}
-
-/*
- * Description: Remove Key from table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * pbyBSSID - BSSID of Key
- * Out:
- * none
- *
- * Return Value: true if success otherwise false
- *
- */
-int KeybRemoveAllKey(struct vnt_private *pDevice, PSKeyManagement pTable,
- u8 *pbyBSSID)
-{
- int i, u;
-
- for (i=0;i<MAX_KEY_TABLE;i++) {
- if ((pTable->KeyTable[i].bInUse == true) &&
- ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
- pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
- for (u = 0; u < MAX_GROUP_KEY; u++)
- pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
-
- pTable->KeyTable[i].dwGTKeyIndex = 0;
- s_vCheckKeyTableValid(pDevice, pTable);
- return (true);
- }
- }
- return (false);
-}
-
-/*
- * Description: Get Transmit Key from table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * pbyBSSID - BSSID of Key
- * Out:
- * pKey - Key return
- *
- * Return Value: true if found otherwise false
- *
- */
-int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
- PSKeyItem *pKey)
-{
- int i, ii;
-
- *pKey = NULL;
-
- for (i = 0; i < MAX_KEY_TABLE; i++) {
- if ((pTable->KeyTable[i].bInUse == true) &&
- ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
-
- if (dwKeyType == PAIRWISE_KEY) {
-
- if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
- *pKey = &(pTable->KeyTable[i].PairwiseKey);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
- for (ii = 0; ii < 6; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-
- return (true);
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == false\n");
- return (false);
- }
- } // End of Type == PAIRWISE
- else {
- if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
- return false;
- }
- if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == true) {
- *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
- for (ii = 0; ii < 6; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n",
- pTable->KeyTable[i].dwGTKeyIndex);
-
- return (true);
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == false\n");
- return (false);
- }
- } // End of Type = GROUP
- } // BSSID match
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
- for (ii = 0; ii < 6; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
- return (false);
-}
-
-/*
- * Description: Set Key to table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * dwKeyIndex - Key index (reference to NDIS DDK)
- * uKeyLength - Key length
- * KeyRSC - Key RSC
- * pbyKey - Pointer to key
- * Out:
- * none
- *
- * Return Value: true if success otherwise false
- *
- */
-
-int KeybSetDefaultKey(struct vnt_private *pDevice, PSKeyManagement pTable,
- u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode)
-{
- int ii;
- PSKeyItem pKey;
- u32 uKeyIdx;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n",
- (int) dwKeyIndex, (int) uKeyLength);
-
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
- return (false);
- } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
- return (false);
- }
-
- if (uKeyLength > MAX_KEY_LEN)
- return false;
-
- pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true;
- for (ii = 0; ii < ETH_ALEN; ii++)
- pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
-
- // Group key
- pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
- if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
- // Group transmit key
- pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Group transmit key(R)[%X]: %d\n",
- pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex,
- MAX_KEY_TABLE-1);
-
- }
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044; // use group key for all address
- uKeyIdx = (dwKeyIndex & 0x000000FF);
-
- if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
- (byKeyDecMode == KEY_CTL_WEP)) {
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000; // disable on-fly disable address match
- pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = true;
- } else {
- if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == false)
- pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000; // enable on-fly disable address match
- }
-
- pKey->bKeyValid = true;
- pKey->uKeyLength = uKeyLength;
- pKey->dwKeyIndex = dwKeyIndex;
- pKey->byCipherSuite = byKeyDecMode;
- memcpy(pKey->abyKey, pbyKey, uKeyLength);
- if (byKeyDecMode == KEY_CTL_WEP) {
- if (uKeyLength == WLAN_WEP40_KEYLEN)
- pKey->abyKey[15] &= 0x7F;
- if (uKeyLength == WLAN_WEP104_KEYLEN)
- pKey->abyKey[15] |= 0x80;
- }
-
- MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl,
- MAX_KEY_TABLE-1, uKeyIdx,
- pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, pKey->abyKey);
-
- if ((dwKeyIndex & USE_KEYRSC) == 0)
- pKey->KeyRSC = 0; /* RSC set by NIC */
- else
- pKey->KeyRSC = *KeyRSC;
-
- pKey->dwTSC47_16 = 0;
- pKey->wTSC15_0 = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
- for (ii = 0; ii < pKey->uKeyLength; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n",
- pKey->dwTSC47_16);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n",
- pKey->dwKeyIndex);
-
- return (true);
-}
-
-/*
- * Description: Set Key to table
- *
- * Parameters:
- * In:
- * pTable - Pointer to Key table
- * dwKeyIndex - Key index (reference to NDIS DDK)
- * uKeyLength - Key length
- * KeyRSC - Key RSC
- * pbyKey - Pointer to key
- * Out:
- * none
- *
- * Return Value: true if success otherwise false
- *
- */
-
-int KeybSetAllGroupKey(struct vnt_private *pDevice, PSKeyManagement pTable,
- u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode)
-{
- int i, ii;
- PSKeyItem pKey;
- u32 uKeyIdx;
+ switch (key->cipher) {
+ case 0:
+ for (u = 0 ; u < MAX_KEY_TABLE; u++)
+ vnt_mac_disable_keyentry(priv, u);
+ return ret;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n",
- dwKeyIndex);
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ for (u = 0; u < MAX_KEY_TABLE; u++)
+ vnt_mac_disable_keyentry(priv, u);
- if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
- return (false);
- } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
- return (false);
- }
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
+ KEY_CTL_WEP, true);
- for (i=0; i < MAX_KEY_TABLE-1; i++) {
- if (pTable->KeyTable[i].bInUse == true) {
- // found table already exist
- // Group key
- pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
- if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
- // Group transmit key
- pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "Group transmit key(R)[%X]: %d\n",
- pTable->KeyTable[i].dwGTKeyIndex, i);
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- }
- pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
- pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
- pTable->KeyTable[i].wKeyCtl |= 0x0040; // use group key for group address
- uKeyIdx = (dwKeyIndex & 0x000000FF);
+ return ret;
+ case WLAN_CIPHER_SUITE_TKIP:
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- pTable->KeyTable[i].wKeyCtl |= 0x8000; // enable on-fly
+ key_dec_mode = KEY_CTL_TKIP;
- pKey->bKeyValid = true;
- pKey->uKeyLength = uKeyLength;
- pKey->dwKeyIndex = dwKeyIndex;
- pKey->byCipherSuite = byKeyDecMode;
- memcpy(pKey->abyKey, pbyKey, uKeyLength);
- if (byKeyDecMode == KEY_CTL_WEP) {
- if (uKeyLength == WLAN_WEP40_KEYLEN)
- pKey->abyKey[15] &= 0x7F;
- if (uKeyLength == WLAN_WEP104_KEYLEN)
- pKey->abyKey[15] |= 0x80;
- }
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ if (priv->local_id <= MAC_REVISION_A1)
+ return -EINVAL;
- MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx,
- pTable->KeyTable[i].abyBSSID, pKey->abyKey);
+ key_dec_mode = KEY_CTL_CCMP;
- if ((dwKeyIndex & USE_KEYRSC) == 0)
- pKey->KeyRSC = 0; /* RSC set by NIC */
- else
- pKey->KeyRSC = *KeyRSC;
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ }
- pKey->dwTSC47_16 = 0;
- pKey->wTSC15_0 = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
- for (ii = 0; ii < pKey->uKeyLength; ii++) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,
+ key_dec_mode, true);
+ } else {
+ vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
+ key_dec_mode, true);
- //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
- //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
- //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
+ vnt_set_keymode(hw, (u8 *)conf->bssid, key,
+ VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
+ }
- } // (pTable->KeyTable[i].bInUse == true)
- }
- return (true);
+ return 0;
}
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
index 23e188d125ba..3cb1291055ed 100644
--- a/drivers/staging/vt6656/key.h
+++ b/drivers/staging/vt6656/key.h
@@ -30,83 +30,26 @@
#ifndef __KEY_H__
#define __KEY_H__
-#include "tether.h"
-#include "80211mgr.h"
+#include "device.h"
-#define MAX_GROUP_KEY 4
#define MAX_KEY_TABLE 11
-#define MAX_KEY_LEN 32
-#define AES_KEY_LEN 16
-
-#define AUTHENTICATOR_KEY 0x10000000
-#define USE_KEYRSC 0x20000000
-#define PAIRWISE_KEY 0x40000000
-#define TRANSMIT_KEY 0x80000000
-
-#define GROUP_KEY 0x00000000
#define KEY_CTL_WEP 0x00
#define KEY_CTL_NONE 0x01
#define KEY_CTL_TKIP 0x02
#define KEY_CTL_CCMP 0x03
-#define KEY_CTL_INVALID 0xFF
-
-typedef struct tagSKeyItem
-{
- bool bKeyValid;
- u32 uKeyLength;
- u8 abyKey[MAX_KEY_LEN];
- u64 KeyRSC;
- u32 dwTSC47_16;
- u16 wTSC15_0;
- u8 byCipherSuite;
- u8 byReserved0;
- u32 dwKeyIndex;
- void *pvKeyTable;
-} SKeyItem, *PSKeyItem; //64
-
-typedef struct tagSKeyTable
-{
- u8 abyBSSID[ETH_ALEN]; /* 6 */
- u8 byReserved0[2]; //8
- SKeyItem PairwiseKey;
- SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328
- u32 dwGTKeyIndex; // GroupTransmitKey Index
- bool bInUse;
- u16 wKeyCtl;
- bool bSoftWEP;
- u8 byReserved1[6];
-} SKeyTable, *PSKeyTable; //352
-
-typedef struct tagSKeyManagement
-{
- SKeyTable KeyTable[MAX_KEY_TABLE];
-} SKeyManagement, *PSKeyManagement;
-
-void KeyvInitTable(struct vnt_private *, PSKeyManagement pTable);
-
-int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
- PSKeyItem *pKey);
-
-int KeybSetKey(struct vnt_private *, PSKeyManagement pTable, u8 *pbyBSSID,
- u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode);
-
-int KeybRemoveKey(struct vnt_private *, PSKeyManagement pTable,
- u8 *pbyBSSID, u32 dwKeyIndex);
-
-int KeybRemoveAllKey(struct vnt_private *, PSKeyManagement pTable,
- u8 *pbyBSSID);
-int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
- PSKeyItem *pKey);
+#define VNT_KEY_DEFAULTKEY 0x1
+#define VNT_KEY_GROUP_ADDRESS 0x2
+#define VNT_KEY_ALLGROUP 0x4
+#define VNT_KEY_GROUP 0x40
+#define VNT_KEY_PAIRWISE 0x00
+#define VNT_KEY_ONFLY 0x8000
+#define VNT_KEY_ONFLY_ALL 0x4000
-int KeybSetDefaultKey(struct vnt_private *, PSKeyManagement pTable,
- u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode);
+int vnt_key_init_table(struct vnt_private *);
-int KeybSetAllGroupKey(struct vnt_private *, PSKeyManagement pTable,
- u32 dwKeyIndex, u32 uKeyLength, u64 *KeyRSC, u8 *pbyKey,
- u8 byKeyDecMode);
+int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key);
#endif /* __KEY_H__ */
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
index cadf7cd280c3..bb37e33b9ffa 100644
--- a/drivers/staging/vt6656/mac.c
+++ b/drivers/staging/vt6656/mac.c
@@ -30,11 +30,8 @@
* Revision History:
*/
-#include "tmacro.h"
-#include "tether.h"
#include "desc.h"
#include "mac.h"
-#include "80211hdr.h"
#include "usbpipe.h"
/*
@@ -50,7 +47,7 @@
* Return Value: none
*
*/
-void MACvWriteMultiAddr(struct vnt_private *priv, u64 mc_filter)
+void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter)
{
__le64 le_mc = cpu_to_le64(mc_filter);
@@ -69,12 +66,12 @@ void MACvWriteMultiAddr(struct vnt_private *priv, u64 mc_filter)
*
*
*/
-void MACbShutdown(struct vnt_private *priv)
+void vnt_mac_shutdown(struct vnt_private *priv)
{
vnt_control_out(priv, MESSAGE_TYPE_MACSHUTDOWN, 0, 0, 0, NULL);
}
-void MACvSetBBType(struct vnt_private *priv, u8 type)
+void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type)
{
u8 data[2];
@@ -99,7 +96,7 @@ void MACvSetBBType(struct vnt_private *priv, u8 type)
* Return Value: none
*
*/
-void MACvDisableKeyEntry(struct vnt_private *priv, u8 entry_idx)
+void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx)
{
vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0,
sizeof(entry_idx), &entry_idx);
@@ -119,16 +116,12 @@ void MACvDisableKeyEntry(struct vnt_private *priv, u8 entry_idx)
* Return Value: none
*
*/
-void MACvSetKeyEntry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
+void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
u32 key_idx, u8 *addr, u8 *key)
{
struct vnt_mac_set_key set_key;
u16 offset;
- if (priv->byLocalID <= MAC_REVISION_A1)
- if (priv->vnt_mgmt.byCSSPK == KEY_CTL_CCMP)
- return;
-
offset = MISCFIFO_KEYETRY0;
offset += (entry_idx * MISCFIFO_KEYENTRYSIZE);
@@ -147,7 +140,7 @@ void MACvSetKeyEntry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
(u16)key_idx, sizeof(struct vnt_mac_set_key), (u8 *)&set_key);
}
-void MACvRegBitsOff(struct vnt_private *priv, u8 reg_ofs, u8 bits)
+void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits)
{
u8 data[2];
@@ -158,7 +151,7 @@ void MACvRegBitsOff(struct vnt_private *priv, u8 reg_ofs, u8 bits)
reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvRegBitsOn(struct vnt_private *priv, u8 reg_ofs, u8 bits)
+void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits)
{
u8 data[2];
@@ -169,7 +162,7 @@ void MACvRegBitsOn(struct vnt_private *priv, u8 reg_ofs, u8 bits)
reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvWriteWord(struct vnt_private *priv, u8 reg_ofs, u16 word)
+void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word)
{
u8 data[2];
@@ -180,13 +173,13 @@ void MACvWriteWord(struct vnt_private *priv, u8 reg_ofs, u16 word)
reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvWriteBSSIDAddress(struct vnt_private *priv, u8 *addr)
+void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr)
{
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0,
MESSAGE_REQUEST_MACREG, ETH_ALEN, addr);
}
-void MACvEnableProtectMD(struct vnt_private *priv)
+void vnt_mac_enable_protect_mode(struct vnt_private *priv)
{
u8 data[2];
@@ -197,7 +190,7 @@ void MACvEnableProtectMD(struct vnt_private *priv)
MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvDisableProtectMD(struct vnt_private *priv)
+void vnt_mac_disable_protect_mode(struct vnt_private *priv)
{
u8 data[2];
@@ -208,7 +201,7 @@ void MACvDisableProtectMD(struct vnt_private *priv)
MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvEnableBarkerPreambleMd(struct vnt_private *priv)
+void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv)
{
u8 data[2];
@@ -219,7 +212,7 @@ void MACvEnableBarkerPreambleMd(struct vnt_private *priv)
MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvDisableBarkerPreambleMd(struct vnt_private *priv)
+void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv)
{
u8 data[2];
@@ -230,7 +223,7 @@ void MACvDisableBarkerPreambleMd(struct vnt_private *priv)
MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
-void MACvWriteBeaconInterval(struct vnt_private *priv, u16 interval)
+void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval)
{
u8 data[2];
@@ -250,6 +243,4 @@ void vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led)
vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_PAPEDELAY,
MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
-
- return;
}
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
index 986ca95f7204..d53fcef87b4a 100644
--- a/drivers/staging/vt6656/mac.h
+++ b/drivers/staging/vt6656/mac.h
@@ -35,373 +35,327 @@
#define __MAC_H__
#include "device.h"
-#include "tmacro.h"
-
-#define REV_ID_VT3253_A0 0x00
-#define REV_ID_VT3253_A1 0x01
-#define REV_ID_VT3253_B0 0x08
-#define REV_ID_VT3253_B1 0x09
-
-//
-// Registers in the MAC
-//
-#define MAC_REG_BISTCMD 0x04
-#define MAC_REG_BISTSR0 0x05
-#define MAC_REG_BISTSR1 0x06
-#define MAC_REG_BISTSR2 0x07
-#define MAC_REG_I2MCSR 0x08
-#define MAC_REG_I2MTGID 0x09
-#define MAC_REG_I2MTGAD 0x0A
-#define MAC_REG_I2MCFG 0x0B
-#define MAC_REG_I2MDIPT 0x0C
-#define MAC_REG_I2MDOPT 0x0E
-#define MAC_REG_USBSUS 0x0F
-
-#define MAC_REG_LOCALID 0x14
-#define MAC_REG_TESTCFG 0x15
-#define MAC_REG_JUMPER0 0x16
-#define MAC_REG_JUMPER1 0x17
-#define MAC_REG_TMCTL 0x18
-#define MAC_REG_TMDATA0 0x1C
-#define MAC_REG_TMDATA1 0x1D
-#define MAC_REG_TMDATA2 0x1E
-#define MAC_REG_TMDATA3 0x1F
-
-// MAC Parameter related
-#define MAC_REG_LRT 0x20 //
-#define MAC_REG_SRT 0x21 //
-#define MAC_REG_SIFS 0x22 //
-#define MAC_REG_DIFS 0x23 //
-#define MAC_REG_EIFS 0x24 //
-#define MAC_REG_SLOT 0x25 //
-#define MAC_REG_BI 0x26 //
-#define MAC_REG_CWMAXMIN0 0x28 //
-#define MAC_REG_LINKOFFTOTM 0x2A
-#define MAC_REG_SWTMOT 0x2B
-#define MAC_REG_RTSOKCNT 0x2C
-#define MAC_REG_RTSFAILCNT 0x2D
-#define MAC_REG_ACKFAILCNT 0x2E
-#define MAC_REG_FCSERRCNT 0x2F
-// TSF Related
-#define MAC_REG_TSFCNTR 0x30 //
-#define MAC_REG_NEXTTBTT 0x38 //
-#define MAC_REG_TSFOFST 0x40 //
-#define MAC_REG_TFTCTL 0x48 //
-// WMAC Control/Status Related
-#define MAC_REG_ENCFG0 0x4C //
-#define MAC_REG_ENCFG1 0x4D //
-#define MAC_REG_ENCFG2 0x4E //
-
-#define MAC_REG_CFG 0x50 //
-#define MAC_REG_TEST 0x52 //
-#define MAC_REG_HOSTCR 0x54 //
-#define MAC_REG_MACCR 0x55 //
-#define MAC_REG_RCR 0x56 //
-#define MAC_REG_TCR 0x57 //
-#define MAC_REG_IMR 0x58 //
-#define MAC_REG_ISR 0x5C
-#define MAC_REG_ISR1 0x5D
-// Power Saving Related
-#define MAC_REG_PSCFG 0x60 //
-#define MAC_REG_PSCTL 0x61 //
-#define MAC_REG_PSPWRSIG 0x62 //
-#define MAC_REG_BBCR13 0x63
-#define MAC_REG_AIDATIM 0x64
-#define MAC_REG_PWBT 0x66
-#define MAC_REG_WAKEOKTMR 0x68
-#define MAC_REG_CALTMR 0x69
-#define MAC_REG_SYNSPACCNT 0x6A
-#define MAC_REG_WAKSYNOPT 0x6B
-// Baseband/IF Control Group
-#define MAC_REG_BBREGCTL 0x6C //
-#define MAC_REG_CHANNEL 0x6D
-#define MAC_REG_BBREGADR 0x6E
-#define MAC_REG_BBREGDATA 0x6F
-#define MAC_REG_IFREGCTL 0x70 //
-#define MAC_REG_IFDATA 0x71 //
-#define MAC_REG_ITRTMSET 0x74 //
-#define MAC_REG_PAPEDELAY 0x77
-#define MAC_REG_SOFTPWRCTL 0x78 //
-#define MAC_REG_SOFTPWRCTL2 0x79 //
-#define MAC_REG_GPIOCTL0 0x7A //
-#define MAC_REG_GPIOCTL1 0x7B //
-
-// MiscFF PIO related
-#define MAC_REG_MISCFFNDEX 0xBC
-#define MAC_REG_MISCFFCTL 0xBE
-#define MAC_REG_MISCFFDATA 0xC0
-
-// MAC Configuration Group
-#define MAC_REG_PAR0 0xC4
-#define MAC_REG_PAR4 0xC8
-#define MAC_REG_BSSID0 0xCC
-#define MAC_REG_BSSID4 0xD0
-#define MAC_REG_MAR0 0xD4
-#define MAC_REG_MAR4 0xD8
-// MAC RSPPKT INFO Group
-#define MAC_REG_RSPINF_B_1 0xDC
-#define MAC_REG_RSPINF_B_2 0xE0
-#define MAC_REG_RSPINF_B_5 0xE4
-#define MAC_REG_RSPINF_B_11 0xE8
-#define MAC_REG_RSPINF_A_6 0xEC
-#define MAC_REG_RSPINF_A_9 0xEE
-#define MAC_REG_RSPINF_A_12 0xF0
-#define MAC_REG_RSPINF_A_18 0xF2
-#define MAC_REG_RSPINF_A_24 0xF4
-#define MAC_REG_RSPINF_A_36 0xF6
-#define MAC_REG_RSPINF_A_48 0xF8
-#define MAC_REG_RSPINF_A_54 0xFA
-#define MAC_REG_RSPINF_A_72 0xFC
-
-//
-// Bits in the I2MCFG EEPROM register
-//
-#define I2MCFG_BOUNDCTL 0x80
-#define I2MCFG_WAITCTL 0x20
-#define I2MCFG_SCLOECTL 0x10
-#define I2MCFG_WBUSYCTL 0x08
-#define I2MCFG_NORETRY 0x04
-#define I2MCFG_I2MLDSEQ 0x02
-#define I2MCFG_I2CMFAST 0x01
-
-//
-// Bits in the I2MCSR EEPROM register
-//
-#define I2MCSR_EEMW 0x80
-#define I2MCSR_EEMR 0x40
-#define I2MCSR_AUTOLD 0x08
-#define I2MCSR_NACK 0x02
-#define I2MCSR_DONE 0x01
-
-//
-// Bits in the TMCTL register
-//
-#define TMCTL_TSUSP 0x04
-#define TMCTL_TMD 0x02
-#define TMCTL_TE 0x01
-
-//
-// Bits in the TFTCTL register
-//
-#define TFTCTL_HWUTSF 0x80 //
-#define TFTCTL_TBTTSYNC 0x40
-#define TFTCTL_HWUTSFEN 0x20
-#define TFTCTL_TSFCNTRRD 0x10 //
-#define TFTCTL_TBTTSYNCEN 0x08 //
-#define TFTCTL_TSFSYNCEN 0x04 //
-#define TFTCTL_TSFCNTRST 0x02 //
-#define TFTCTL_TSFCNTREN 0x01 //
-
-//
-// Bits in the EnhanceCFG_0 register
-//
-#define EnCFG_BBType_a 0x00
-#define EnCFG_BBType_b 0x01
-#define EnCFG_BBType_g 0x02
-#define EnCFG_BBType_MASK 0x03
-#define EnCFG_ProtectMd 0x20
-
-//
-// Bits in the EnhanceCFG_1 register
-//
-#define EnCFG_BcnSusInd 0x01
-#define EnCFG_BcnSusClr 0x02
-
-//
-// Bits in the EnhanceCFG_2 register
-//
-#define EnCFG_NXTBTTCFPSTR 0x01
-#define EnCFG_BarkerPream 0x02
-#define EnCFG_PktBurstMode 0x04
-
-//
-// Bits in the CFG register
-//
-#define CFG_TKIPOPT 0x80
-#define CFG_RXDMAOPT 0x40
-#define CFG_TMOT_SW 0x20
-#define CFG_TMOT_HWLONG 0x10
-#define CFG_TMOT_HW 0x00
-#define CFG_CFPENDOPT 0x08
-#define CFG_BCNSUSEN 0x04
-#define CFG_NOTXTIMEOUT 0x02
-#define CFG_NOBUFOPT 0x01
-
-//
-// Bits in the TEST register
-//
-#define TEST_LBEXT 0x80 //
-#define TEST_LBINT 0x40 //
-#define TEST_LBNONE 0x00 //
-#define TEST_SOFTINT 0x20 //
-#define TEST_CONTTX 0x10 //
-#define TEST_TXPE 0x08 //
-#define TEST_NAVDIS 0x04 //
-#define TEST_NOCTS 0x02 //
-#define TEST_NOACK 0x01 //
-
-//
-// Bits in the HOSTCR register
-//
-#define HOSTCR_TXONST 0x80 //
-#define HOSTCR_RXONST 0x40 //
-#define HOSTCR_ADHOC 0x20 // Network Type 1 = Ad-hoc
-#define HOSTCR_AP 0x10 // Port Type 1 = AP
-#define HOSTCR_TXON 0x08 //0000 1000
-#define HOSTCR_RXON 0x04 //0000 0100
-#define HOSTCR_MACEN 0x02 //0000 0010
-#define HOSTCR_SOFTRST 0x01 //0000 0001
-
-//
-// Bits in the MACCR register
-//
-#define MACCR_SYNCFLUSHOK 0x04 //
-#define MACCR_SYNCFLUSH 0x02 //
-#define MACCR_CLRNAV 0x01 //
-
-//
-// Bits in the RCR register
-//
-#define RCR_SSID 0x80
-#define RCR_RXALLTYPE 0x40 //
-#define RCR_UNICAST 0x20 //
-#define RCR_BROADCAST 0x10 //
-#define RCR_MULTICAST 0x08 //
-#define RCR_WPAERR 0x04 //
-#define RCR_ERRCRC 0x02 //
-#define RCR_BSSID 0x01 //
-
-//
-// Bits in the TCR register
-//
-#define TCR_SYNCDCFOPT 0x02 //
-#define TCR_AUTOBCNTX 0x01 // Beacon automatically transmit enable
-
-//ISR1
-#define ISR_GPIO3 0x40
-#define ISR_RXNOBUF 0x08
-#define ISR_MIBNEARFULL 0x04
-#define ISR_SOFTINT 0x02
-#define ISR_FETALERR 0x01
-
-#define LEDSTS_STS 0x06
-#define LEDSTS_TMLEN 0x78
-#define LEDSTS_OFF 0x00
-#define LEDSTS_ON 0x02
-#define LEDSTS_SLOW 0x04
-#define LEDSTS_INTER 0x06
-
-//ISR0
-#define ISR_WATCHDOG 0x80
-#define ISR_SOFTTIMER 0x40
-#define ISR_GPIO0 0x20
-#define ISR_TBTT 0x10
-#define ISR_RXDMA0 0x08
-#define ISR_BNTX 0x04
-#define ISR_ACTX 0x01
-
-//
-// Bits in the PSCFG register
-//
-#define PSCFG_PHILIPMD 0x40 //
-#define PSCFG_WAKECALEN 0x20 //
-#define PSCFG_WAKETMREN 0x10 //
-#define PSCFG_BBPSPROG 0x08 //
-#define PSCFG_WAKESYN 0x04 //
-#define PSCFG_SLEEPSYN 0x02 //
-#define PSCFG_AUTOSLEEP 0x01 //
-
-//
-// Bits in the PSCTL register
-//
-#define PSCTL_WAKEDONE 0x20 //
-#define PSCTL_PS 0x10 //
-#define PSCTL_GO2DOZE 0x08 //
-#define PSCTL_LNBCN 0x04 //
-#define PSCTL_ALBCN 0x02 //
-#define PSCTL_PSEN 0x01 //
-
-//
-// Bits in the PSPWSIG register
-//
-#define PSSIG_WPE3 0x80 //
-#define PSSIG_WPE2 0x40 //
-#define PSSIG_WPE1 0x20 //
-#define PSSIG_WRADIOPE 0x10 //
-#define PSSIG_SPE3 0x08 //
-#define PSSIG_SPE2 0x04 //
-#define PSSIG_SPE1 0x02 //
-#define PSSIG_SRADIOPE 0x01 //
-
-//
-// Bits in the BBREGCTL register
-//
-#define BBREGCTL_DONE 0x04 //
-#define BBREGCTL_REGR 0x02 //
-#define BBREGCTL_REGW 0x01 //
-
-//
-// Bits in the IFREGCTL register
-//
-#define IFREGCTL_DONE 0x04 //
-#define IFREGCTL_IFRF 0x02 //
-#define IFREGCTL_REGW 0x01 //
-
-//
-// Bits in the SOFTPWRCTL register
-//
-#define SOFTPWRCTL_RFLEOPT 0x08 //
-#define SOFTPWRCTL_TXPEINV 0x02 //
-#define SOFTPWRCTL_SWPECTI 0x01 //
-#define SOFTPWRCTL_SWPAPE 0x20 //
-#define SOFTPWRCTL_SWCALEN 0x10 //
-#define SOFTPWRCTL_SWRADIO_PE 0x08 //
-#define SOFTPWRCTL_SWPE2 0x04 //
-#define SOFTPWRCTL_SWPE1 0x02 //
-#define SOFTPWRCTL_SWPE3 0x01 //
-
-//
-// Bits in the GPIOCTL1 register
-//
-#define GPIO3_MD 0x20 //
-#define GPIO3_DATA 0x40 //
-#define GPIO3_INTMD 0x80 //
-
-//
-// Bits in the MISCFFCTL register
-//
-#define MISCFFCTL_WRITE 0x0001 //
-
-// Loopback mode
-#define MAC_LB_EXT 0x02 //
-#define MAC_LB_INTERNAL 0x01 //
-#define MAC_LB_NONE 0x00 //
-
-// Ethernet address filter type
-#define PKT_TYPE_NONE 0x00 // turn off receiver
-#define PKT_TYPE_ALL_MULTICAST 0x80
-#define PKT_TYPE_PROMISCUOUS 0x40
-#define PKT_TYPE_DIRECTED 0x20 // obselete, directed address is always accepted
-#define PKT_TYPE_BROADCAST 0x10
-#define PKT_TYPE_MULTICAST 0x08
-#define PKT_TYPE_ERROR_WPA 0x04
-#define PKT_TYPE_ERROR_CRC 0x02
-#define PKT_TYPE_BSSID 0x01
-#define Default_BI 0x200
-
-// MiscFIFO Offset
-#define MISCFIFO_KEYETRY0 32
-#define MISCFIFO_KEYENTRYSIZE 22
+#define REV_ID_VT3253_A0 0x00
+#define REV_ID_VT3253_A1 0x01
+#define REV_ID_VT3253_B0 0x08
+#define REV_ID_VT3253_B1 0x09
+
+/* Registers in the MAC */
+#define MAC_REG_BISTCMD 0x04
+#define MAC_REG_BISTSR0 0x05
+#define MAC_REG_BISTSR1 0x06
+#define MAC_REG_BISTSR2 0x07
+#define MAC_REG_I2MCSR 0x08
+#define MAC_REG_I2MTGID 0x09
+#define MAC_REG_I2MTGAD 0x0a
+#define MAC_REG_I2MCFG 0x0b
+#define MAC_REG_I2MDIPT 0x0c
+#define MAC_REG_I2MDOPT 0x0e
+#define MAC_REG_USBSUS 0x0f
+
+#define MAC_REG_LOCALID 0x14
+#define MAC_REG_TESTCFG 0x15
+#define MAC_REG_JUMPER0 0x16
+#define MAC_REG_JUMPER1 0x17
+#define MAC_REG_TMCTL 0x18
+#define MAC_REG_TMDATA0 0x1c
+#define MAC_REG_TMDATA1 0x1d
+#define MAC_REG_TMDATA2 0x1e
+#define MAC_REG_TMDATA3 0x1f
+
+/* MAC Parameter related */
+#define MAC_REG_LRT 0x20
+#define MAC_REG_SRT 0x21
+#define MAC_REG_SIFS 0x22
+#define MAC_REG_DIFS 0x23
+#define MAC_REG_EIFS 0x24
+#define MAC_REG_SLOT 0x25
+#define MAC_REG_BI 0x26
+#define MAC_REG_CWMAXMIN0 0x28
+#define MAC_REG_LINKOFFTOTM 0x2a
+#define MAC_REG_SWTMOT 0x2b
+#define MAC_REG_RTSOKCNT 0x2c
+#define MAC_REG_RTSFAILCNT 0x2d
+#define MAC_REG_ACKFAILCNT 0x2e
+#define MAC_REG_FCSERRCNT 0x2f
+
+/* TSF Related */
+#define MAC_REG_TSFCNTR 0x30
+#define MAC_REG_NEXTTBTT 0x38
+#define MAC_REG_TSFOFST 0x40
+#define MAC_REG_TFTCTL 0x48
+
+/* WMAC Control/Status Related */
+#define MAC_REG_ENCFG0 0x4c
+#define MAC_REG_ENCFG1 0x4d
+#define MAC_REG_ENCFG2 0x4e
+
+#define MAC_REG_CFG 0x50
+#define MAC_REG_TEST 0x52
+#define MAC_REG_HOSTCR 0x54
+#define MAC_REG_MACCR 0x55
+#define MAC_REG_RCR 0x56
+#define MAC_REG_TCR 0x57
+#define MAC_REG_IMR 0x58
+#define MAC_REG_ISR 0x5c
+#define MAC_REG_ISR1 0x5d
+
+/* Power Saving Related */
+#define MAC_REG_PSCFG 0x60
+#define MAC_REG_PSCTL 0x61
+#define MAC_REG_PSPWRSIG 0x62
+#define MAC_REG_BBCR13 0x63
+#define MAC_REG_AIDATIM 0x64
+#define MAC_REG_PWBT 0x66
+#define MAC_REG_WAKEOKTMR 0x68
+#define MAC_REG_CALTMR 0x69
+#define MAC_REG_SYNSPACCNT 0x6a
+#define MAC_REG_WAKSYNOPT 0x6b
+
+/* Baseband/IF Control Group */
+#define MAC_REG_BBREGCTL 0x6c
+#define MAC_REG_CHANNEL 0x6d
+#define MAC_REG_BBREGADR 0x6e
+#define MAC_REG_BBREGDATA 0x6f
+#define MAC_REG_IFREGCTL 0x70
+#define MAC_REG_IFDATA 0x71
+#define MAC_REG_ITRTMSET 0x74
+#define MAC_REG_PAPEDELAY 0x77
+#define MAC_REG_SOFTPWRCTL 0x78
+#define MAC_REG_SOFTPWRCTL2 0x79
+#define MAC_REG_GPIOCTL0 0x7a
+#define MAC_REG_GPIOCTL1 0x7b
+
+/* MiscFF PIO related */
+#define MAC_REG_MISCFFNDEX 0xbc
+#define MAC_REG_MISCFFCTL 0xbe
+#define MAC_REG_MISCFFDATA 0xc0
+
+/* MAC Configuration Group */
+#define MAC_REG_PAR0 0xc4
+#define MAC_REG_PAR4 0xc8
+#define MAC_REG_BSSID0 0xcc
+#define MAC_REG_BSSID4 0xd0
+#define MAC_REG_MAR0 0xd4
+#define MAC_REG_MAR4 0xd8
+
+/* MAC RSPPKT INFO Group */
+#define MAC_REG_RSPINF_B_1 0xdC
+#define MAC_REG_RSPINF_B_2 0xe0
+#define MAC_REG_RSPINF_B_5 0xe4
+#define MAC_REG_RSPINF_B_11 0xe8
+#define MAC_REG_RSPINF_A_6 0xec
+#define MAC_REG_RSPINF_A_9 0xee
+#define MAC_REG_RSPINF_A_12 0xf0
+#define MAC_REG_RSPINF_A_18 0xf2
+#define MAC_REG_RSPINF_A_24 0xf4
+#define MAC_REG_RSPINF_A_36 0xf6
+#define MAC_REG_RSPINF_A_48 0xf8
+#define MAC_REG_RSPINF_A_54 0xfa
+#define MAC_REG_RSPINF_A_72 0xfc
+
+/* Bits in the I2MCFG EEPROM register */
+#define I2MCFG_BOUNDCTL 0x80
+#define I2MCFG_WAITCTL 0x20
+#define I2MCFG_SCLOECTL 0x10
+#define I2MCFG_WBUSYCTL 0x08
+#define I2MCFG_NORETRY 0x04
+#define I2MCFG_I2MLDSEQ 0x02
+#define I2MCFG_I2CMFAST 0x01
+
+/* Bits in the I2MCSR EEPROM register */
+#define I2MCSR_EEMW 0x80
+#define I2MCSR_EEMR 0x40
+#define I2MCSR_AUTOLD 0x08
+#define I2MCSR_NACK 0x02
+#define I2MCSR_DONE 0x01
+
+/* Bits in the TMCTL register */
+#define TMCTL_TSUSP 0x04
+#define TMCTL_TMD 0x02
+#define TMCTL_TE 0x01
+
+/* Bits in the TFTCTL register */
+#define TFTCTL_HWUTSF 0x80
+#define TFTCTL_TBTTSYNC 0x40
+#define TFTCTL_HWUTSFEN 0x20
+#define TFTCTL_TSFCNTRRD 0x10
+#define TFTCTL_TBTTSYNCEN 0x08
+#define TFTCTL_TSFSYNCEN 0x04
+#define TFTCTL_TSFCNTRST 0x02
+#define TFTCTL_TSFCNTREN 0x01
+
+/* Bits in the EnhanceCFG_0 register */
+#define EnCFG_BBType_a 0x00
+#define EnCFG_BBType_b 0x01
+#define EnCFG_BBType_g 0x02
+#define EnCFG_BBType_MASK 0x03
+#define EnCFG_ProtectMd 0x20
+
+/* Bits in the EnhanceCFG_1 register */
+#define EnCFG_BcnSusInd 0x01
+#define EnCFG_BcnSusClr 0x02
+
+/* Bits in the EnhanceCFG_2 register */
+#define EnCFG_NXTBTTCFPSTR 0x01
+#define EnCFG_BarkerPream 0x02
+#define EnCFG_PktBurstMode 0x04
+
+/* Bits in the CFG register */
+#define CFG_TKIPOPT 0x80
+#define CFG_RXDMAOPT 0x40
+#define CFG_TMOT_SW 0x20
+#define CFG_TMOT_HWLONG 0x10
+#define CFG_TMOT_HW 0x00
+#define CFG_CFPENDOPT 0x08
+#define CFG_BCNSUSEN 0x04
+#define CFG_NOTXTIMEOUT 0x02
+#define CFG_NOBUFOPT 0x01
+
+/* Bits in the TEST register */
+#define TEST_LBEXT 0x80
+#define TEST_LBINT 0x40
+#define TEST_LBNONE 0x00
+#define TEST_SOFTINT 0x20
+#define TEST_CONTTX 0x10
+#define TEST_TXPE 0x08
+#define TEST_NAVDIS 0x04
+#define TEST_NOCTS 0x02
+#define TEST_NOACK 0x01
+
+/* Bits in the HOSTCR register */
+#define HOSTCR_TXONST 0x80
+#define HOSTCR_RXONST 0x40
+#define HOSTCR_ADHOC 0x20
+#define HOSTCR_AP 0x10
+#define HOSTCR_TXON 0x08
+#define HOSTCR_RXON 0x04
+#define HOSTCR_MACEN 0x02
+#define HOSTCR_SOFTRST 0x01
+
+/* Bits in the MACCR register */
+#define MACCR_SYNCFLUSHOK 0x04
+#define MACCR_SYNCFLUSH 0x02
+#define MACCR_CLRNAV 0x01
+
+/* Bits in the RCR register */
+#define RCR_SSID 0x80
+#define RCR_RXALLTYPE 0x40
+#define RCR_UNICAST 0x20
+#define RCR_BROADCAST 0x10
+#define RCR_MULTICAST 0x08
+#define RCR_WPAERR 0x04
+#define RCR_ERRCRC 0x02
+#define RCR_BSSID 0x01
+
+/* Bits in the TCR register */
+#define TCR_SYNCDCFOPT 0x02
+#define TCR_AUTOBCNTX 0x01
+
+/* ISR1 */
+#define ISR_GPIO3 0x40
+#define ISR_RXNOBUF 0x08
+#define ISR_MIBNEARFULL 0x04
+#define ISR_SOFTINT 0x02
+#define ISR_FETALERR 0x01
+
+#define LEDSTS_STS 0x06
+#define LEDSTS_TMLEN 0x78
+#define LEDSTS_OFF 0x00
+#define LEDSTS_ON 0x02
+#define LEDSTS_SLOW 0x04
+#define LEDSTS_INTER 0x06
+
+/* ISR0 */
+#define ISR_WATCHDOG 0x80
+#define ISR_SOFTTIMER 0x40
+#define ISR_GPIO0 0x20
+#define ISR_TBTT 0x10
+#define ISR_RXDMA0 0x08
+#define ISR_BNTX 0x04
+#define ISR_ACTX 0x01
+
+/* Bits in the PSCFG register */
+#define PSCFG_PHILIPMD 0x40
+#define PSCFG_WAKECALEN 0x20
+#define PSCFG_WAKETMREN 0x10
+#define PSCFG_BBPSPROG 0x08
+#define PSCFG_WAKESYN 0x04
+#define PSCFG_SLEEPSYN 0x02
+#define PSCFG_AUTOSLEEP 0x01
+
+/* Bits in the PSCTL register */
+#define PSCTL_WAKEDONE 0x20
+#define PSCTL_PS 0x10
+#define PSCTL_GO2DOZE 0x08
+#define PSCTL_LNBCN 0x04
+#define PSCTL_ALBCN 0x02
+#define PSCTL_PSEN 0x01
+
+/* Bits in the PSPWSIG register */
+#define PSSIG_WPE3 0x80
+#define PSSIG_WPE2 0x40
+#define PSSIG_WPE1 0x20
+#define PSSIG_WRADIOPE 0x10
+#define PSSIG_SPE3 0x08
+#define PSSIG_SPE2 0x04
+#define PSSIG_SPE1 0x02
+#define PSSIG_SRADIOPE 0x01
+
+/* Bits in the BBREGCTL register */
+#define BBREGCTL_DONE 0x04
+#define BBREGCTL_REGR 0x02
+#define BBREGCTL_REGW 0x01
+
+/* Bits in the IFREGCTL register */
+#define IFREGCTL_DONE 0x04
+#define IFREGCTL_IFRF 0x02
+#define IFREGCTL_REGW 0x01
+
+/* Bits in the SOFTPWRCTL register */
+#define SOFTPWRCTL_RFLEOPT 0x08
+#define SOFTPWRCTL_TXPEINV 0x02
+#define SOFTPWRCTL_SWPECTI 0x01
+#define SOFTPWRCTL_SWPAPE 0x20
+#define SOFTPWRCTL_SWCALEN 0x10
+#define SOFTPWRCTL_SWRADIO_PE 0x08
+#define SOFTPWRCTL_SWPE2 0x04
+#define SOFTPWRCTL_SWPE1 0x02
+#define SOFTPWRCTL_SWPE3 0x01
+
+/* Bits in the GPIOCTL1 register */
+#define GPIO3_MD 0x20
+#define GPIO3_DATA 0x40
+#define GPIO3_INTMD 0x80
+
+/* Bits in the MISCFFCTL register */
+#define MISCFFCTL_WRITE 0x0001
+
+/* Loopback mode */
+#define MAC_LB_EXT 0x02
+#define MAC_LB_INTERNAL 0x01
+#define MAC_LB_NONE 0x00
+
+/* Ethernet address filter type */
+#define PKT_TYPE_NONE 0x00 /* turn off receiver */
+#define PKT_TYPE_ALL_MULTICAST 0x80
+#define PKT_TYPE_PROMISCUOUS 0x40
+#define PKT_TYPE_DIRECTED 0x20 /* obselete */
+#define PKT_TYPE_BROADCAST 0x10
+#define PKT_TYPE_MULTICAST 0x08
+#define PKT_TYPE_ERROR_WPA 0x04
+#define PKT_TYPE_ERROR_CRC 0x02
+#define PKT_TYPE_BSSID 0x01
-// max time out delay time
-#define W_MAX_TIMEOUT 0xFFF0U //
+#define Default_BI 0x200
-// wait time within loop
-#define CB_DELAY_LOOP_WAIT 10 // 10ms
+/* MiscFIFO Offset */
+#define MISCFIFO_KEYETRY0 32
+#define MISCFIFO_KEYENTRYSIZE 22
-#define MAC_REVISION_A0 0x00
-#define MAC_REVISION_A1 0x01
+#define MAC_REVISION_A0 0x00
+#define MAC_REVISION_A1 0x01
struct vnt_mac_set_key {
union {
@@ -414,20 +368,20 @@ struct vnt_mac_set_key {
u8 key[WLAN_KEY_LEN_CCMP];
} __packed;
-void MACvWriteMultiAddr(struct vnt_private *, u64);
-void MACbShutdown(struct vnt_private *);
-void MACvSetBBType(struct vnt_private *, u8);
-void MACvDisableKeyEntry(struct vnt_private *, u8);
-void MACvSetKeyEntry(struct vnt_private *, u16, u32, u32, u8 *, u8 *);
-void MACvRegBitsOff(struct vnt_private *, u8, u8);
-void MACvRegBitsOn(struct vnt_private *, u8, u8);
-void MACvWriteWord(struct vnt_private *, u8, u16);
-void MACvWriteBSSIDAddress(struct vnt_private *, u8 *);
-void MACvEnableProtectMD(struct vnt_private *);
-void MACvDisableProtectMD(struct vnt_private *);
-void MACvEnableBarkerPreambleMd(struct vnt_private *);
-void MACvDisableBarkerPreambleMd(struct vnt_private *);
-void MACvWriteBeaconInterval(struct vnt_private *, u16);
+void vnt_mac_set_filter(struct vnt_private *, u64);
+void vnt_mac_shutdown(struct vnt_private *);
+void vnt_mac_set_bb_type(struct vnt_private *, u8);
+void vnt_mac_disable_keyentry(struct vnt_private *, u8);
+void vnt_mac_set_keyentry(struct vnt_private *, u16, u32, u32, u8 *, u8 *);
+void vnt_mac_reg_bits_off(struct vnt_private *, u8, u8);
+void vnt_mac_reg_bits_on(struct vnt_private *, u8, u8);
+void vnt_mac_write_word(struct vnt_private *, u8, u16);
+void vnt_mac_set_bssid_addr(struct vnt_private *, u8 *);
+void vnt_mac_enable_protect_mode(struct vnt_private *);
+void vnt_mac_disable_protect_mode(struct vnt_private *);
+void vnt_mac_enable_barker_preamble_mode(struct vnt_private *);
+void vnt_mac_disable_barker_preamble_mode(struct vnt_private *);
+void vnt_mac_set_beacon_interval(struct vnt_private *, u16);
void vnt_mac_set_led(struct vnt_private *priv, u8, u8);
#endif /* __MAC_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index e18071f121c5..422fcbabafac 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -27,20 +27,8 @@
* Functions:
*
* vt6656_probe - module initial (insmod) driver entry
- * device_remove1 - module remove entry
- * device_open - allocate dma/descripter resource & initial mac/bbp function
- * device_xmit - asynchronous data tx function
- * device_set_multi - set mac filter
- * device_ioctl - ioctl entry
- * device_close - shutdown mac/bbp & free dma/descriptor resource
- * device_alloc_frag_buf - rx fragement pre-allocated function
- * device_free_tx_bufs - free tx buffer function
- * device_dma0_tx_80211- tx 802.11 frame via dma0
- * device_dma0_xmit- tx PS buffered frame via dma0
- * device_init_registers- initial MAC & BBP & RF internal registers.
- * device_init_rings- initial tx/rx ring buffer
- * device_init_defrag_cb- initial & allocate de-fragement buffer.
- * device_tx_srv- tx interrupt service function
+ * vnt_free_tx_bufs - free tx buffer function
+ * vnt_init_registers- initial MAC & BBP & RF internal registers.
*
* Revision History:
*/
@@ -51,27 +39,15 @@
#include "card.h"
#include "baseband.h"
#include "mac.h"
-#include "tether.h"
-#include "wmgr.h"
-#include "wctl.h"
#include "power.h"
#include "wcmd.h"
-#include "iocmd.h"
#include "rxtx.h"
-#include "bssdb.h"
-#include "wpactl.h"
-#include "iwctl.h"
#include "dpc.h"
-#include "datarate.h"
#include "rf.h"
#include "firmware.h"
#include "usbpipe.h"
#include "channel.h"
#include "int.h"
-#include "iowpa.h"
-
-/* static int msglevel = MSG_LEVEL_DEBUG; */
-static int msglevel =MSG_LEVEL_INFO;
/*
* define module options
@@ -84,77 +60,20 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
-#define DEVICE_PARAM(N,D) \
- static int N[MAX_UINTS]=OPTION_DEFAULT;\
- module_param_array(N, int, NULL, 0);\
- MODULE_PARM_DESC(N, D);
-
-#define RX_DESC_DEF0 64
-DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
-
-#define TX_DESC_DEF0 64
-DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
+#define RX_DESC_DEF0 64
+static int vnt_rx_buffers = RX_DESC_DEF0;
+module_param_named(rx_buffers, vnt_rx_buffers, int, 0644);
+MODULE_PARM_DESC(rx_buffers, "Number of receive usb rx buffers");
-#define CHANNEL_DEF 6
-DEVICE_PARAM(Channel, "Channel number");
-
-/* PreambleType[] is the preamble length used for transmit.
- 0: indicate allows long preamble type
- 1: indicate allows short preamble type
-*/
-
-#define PREAMBLE_TYPE_DEF 1
-
-DEVICE_PARAM(PreambleType, "Preamble Type");
+#define TX_DESC_DEF0 64
+static int vnt_tx_buffers = TX_DESC_DEF0;
+module_param_named(tx_buffers, vnt_tx_buffers, int, 0644);
+MODULE_PARM_DESC(tx_buffers, "Number of receive usb tx buffers");
#define RTS_THRESH_DEF 2347
-DEVICE_PARAM(RTSThreshold, "RTS threshold");
-
#define FRAG_THRESH_DEF 2346
-DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
-
-#define DATA_RATE_DEF 13
-/* datarate[] index
- 0: indicate 1 Mbps 0x02
- 1: indicate 2 Mbps 0x04
- 2: indicate 5.5 Mbps 0x0B
- 3: indicate 11 Mbps 0x16
- 4: indicate 6 Mbps 0x0c
- 5: indicate 9 Mbps 0x12
- 6: indicate 12 Mbps 0x18
- 7: indicate 18 Mbps 0x24
- 8: indicate 24 Mbps 0x30
- 9: indicate 36 Mbps 0x48
- 10: indicate 48 Mbps 0x60
- 11: indicate 54 Mbps 0x6c
- 12: indicate 72 Mbps 0x90
- 13: indicate auto rate
-*/
-
-DEVICE_PARAM(ConnectionRate, "Connection data rate");
-
-#define OP_MODE_DEF 0
-DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
-
-/* OpMode[] is used for transmit.
- 0: indicate infrastruct mode used
- 1: indicate adhoc mode used
- 2: indicate AP mode used
-*/
-
-/* PSMode[]
- 0: indicate disable power saving mode
- 1: indicate enable power saving mode
-*/
-
-#define PS_MODE_DEF 0
-DEVICE_PARAM(PSMode, "Power saving mode");
-
#define SHORT_RETRY_DEF 8
-DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
-
#define LONG_RETRY_DEF 4
-DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
/* BasebandType[] baseband type selected
0: indicate 802.11a type
@@ -163,16 +82,6 @@ DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
*/
#define BBP_TYPE_DEF 2
-DEVICE_PARAM(BasebandType, "baseband type");
-
-/* 80211hEnable[]
- 0: indicate disable 802.11h
- 1: indicate enable 802.11h
-*/
-
-#define X80211h_MODE_DEF 0
-
-DEVICE_PARAM(b80211hEnable, "802.11h mode");
/*
* Static vars definitions
@@ -183,501 +92,287 @@ static struct usb_device_id vt6656_table[] = {
{}
};
-/* frequency list (map channels to frequencies) */
-/*
-static const long frequency_list[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
- 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
- 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
- 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
- 5700, 5745, 5765, 5785, 5805, 5825
- };
-
-static const struct iw_handler_def iwctl_handler_def;
-*/
-
-static int vt6656_probe(struct usb_interface *intf,
- const struct usb_device_id *id);
-static void vt6656_disconnect(struct usb_interface *intf);
-
-#ifdef CONFIG_PM /* Minimal support for suspend and resume */
-static int vt6656_suspend(struct usb_interface *intf, pm_message_t message);
-static int vt6656_resume(struct usb_interface *intf);
-#endif /* CONFIG_PM */
+static void vnt_set_options(struct vnt_private *priv)
+{
+ /* Set number of TX buffers */
+ if (vnt_tx_buffers < CB_MIN_TX_DESC || vnt_tx_buffers > CB_MAX_TX_DESC)
+ priv->num_tx_context = TX_DESC_DEF0;
+ else
+ priv->num_tx_context = vnt_tx_buffers;
-static struct net_device_stats *device_get_stats(struct net_device *dev);
-static int device_open(struct net_device *dev);
-static int device_xmit(struct sk_buff *skb, struct net_device *dev);
-static void device_set_multi(struct net_device *dev);
-static int device_close(struct net_device *dev);
-static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-
-static int device_init_registers(struct vnt_private *pDevice);
-static bool device_init_defrag_cb(struct vnt_private *pDevice);
-
-static int ethtool_ioctl(struct net_device *dev, struct ifreq *);
-static void device_free_tx_bufs(struct vnt_private *pDevice);
-static void device_free_rx_bufs(struct vnt_private *pDevice);
-static void device_free_int_bufs(struct vnt_private *pDevice);
-static void device_free_frag_bufs(struct vnt_private *pDevice);
-static bool device_alloc_bufs(struct vnt_private *pDevice);
-
-static int Read_config_file(struct vnt_private *pDevice);
-static unsigned char *Config_FileOperation(struct vnt_private *pDevice);
-static int Config_FileGetParameter(unsigned char *string,
- unsigned char *dest,
- unsigned char *source);
-
-static void usb_device_reset(struct vnt_private *pDevice);
-
-static void
-device_set_options(struct vnt_private *pDevice) {
-
- u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
- u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
-
- memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
- memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
- memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
-
- pDevice->cbTD = TX_DESC_DEF0;
- pDevice->cbRD = RX_DESC_DEF0;
- pDevice->uChannel = CHANNEL_DEF;
- pDevice->wRTSThreshold = RTS_THRESH_DEF;
- pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
- pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
- pDevice->byLongRetryLimit = LONG_RETRY_DEF;
- pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
- pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
- pDevice->ePSMode = PS_MODE_DEF;
- pDevice->b11hEnable = X80211h_MODE_DEF;
- pDevice->op_mode = NL80211_IFTYPE_UNSPECIFIED;
- pDevice->uConnectionRate = DATA_RATE_DEF;
- if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = true;
- pDevice->byBBType = BBP_TYPE_DEF;
- pDevice->byPacketType = pDevice->byBBType;
- pDevice->byAutoFBCtrl = AUTO_FB_0;
- pDevice->byPreambleType = 0;
- pDevice->bExistSWNetAddr = false;
+ /* Set number of RX buffers */
+ if (vnt_rx_buffers < CB_MIN_RX_DESC || vnt_rx_buffers > CB_MAX_RX_DESC)
+ priv->num_rcb = RX_DESC_DEF0;
+ else
+ priv->num_rcb = vnt_rx_buffers;
+
+ priv->short_retry_limit = SHORT_RETRY_DEF;
+ priv->long_retry_limit = LONG_RETRY_DEF;
+ priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
+ priv->bb_type = BBP_TYPE_DEF;
+ priv->packet_type = priv->bb_type;
+ priv->auto_fb_ctrl = AUTO_FB_0;
+ priv->preamble_type = 0;
+ priv->exist_sw_net_addr = false;
}
/*
* initialization of MAC & BBP registers
*/
-static int device_init_registers(struct vnt_private *pDevice)
+static int vnt_init_registers(struct vnt_private *priv)
{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_cmd_card_init *init_cmd = &pDevice->init_command;
- struct vnt_rsp_card_init *init_rsp = &pDevice->init_response;
- u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- u8 abySNAP_RFC1042[ETH_ALEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
- u8 abySNAP_Bridgetunnel[ETH_ALEN]
- = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
- u8 byAntenna;
+ struct vnt_cmd_card_init *init_cmd = &priv->init_command;
+ struct vnt_rsp_card_init *init_rsp = &priv->init_response;
+ u8 antenna;
int ii;
- int ntStatus = STATUS_SUCCESS;
- u8 byTmp;
- u8 byCalibTXIQ = 0, byCalibTXDC = 0, byCalibRXIQ = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n",
- DEVICE_INIT_COLD, pDevice->byPacketType);
-
- memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN);
- memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN);
- memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN);
-
- if (!FIRMWAREbCheckVersion(pDevice)) {
- if (FIRMWAREbDownload(pDevice) == true) {
- if (FIRMWAREbBrach2Sram(pDevice) == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- " FIRMWAREbBrach2Sram fail\n");
+ int status = STATUS_SUCCESS;
+ u8 tmp;
+ u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0;
+
+ dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n",
+ DEVICE_INIT_COLD, priv->packet_type);
+
+ if (!vnt_check_firmware_version(priv)) {
+ if (vnt_download_firmware(priv) == true) {
+ if (vnt_firmware_branch_to_sram(priv) == false) {
+ dev_dbg(&priv->usb->dev,
+ " vnt_firmware_branch_to_sram fail\n");
return false;
}
} else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- " FIRMWAREbDownload fail\n");
+ dev_dbg(&priv->usb->dev, "FIRMWAREbDownload fail\n");
return false;
}
}
- if (!BBbVT3184Init(pDevice)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail\n");
+ if (!vnt_vt3184_init(priv)) {
+ dev_dbg(&priv->usb->dev, "vnt_vt3184_init fail\n");
return false;
}
init_cmd->init_class = DEVICE_INIT_COLD;
- init_cmd->exist_sw_net_addr = (u8) pDevice->bExistSWNetAddr;
+ init_cmd->exist_sw_net_addr = priv->exist_sw_net_addr;
for (ii = 0; ii < 6; ii++)
- init_cmd->sw_net_addr[ii] = pDevice->abyCurrentNetAddr[ii];
- init_cmd->short_retry_limit = pDevice->byShortRetryLimit;
- init_cmd->long_retry_limit = pDevice->byLongRetryLimit;
+ init_cmd->sw_net_addr[ii] = priv->current_net_addr[ii];
+ init_cmd->short_retry_limit = priv->short_retry_limit;
+ init_cmd->long_retry_limit = priv->long_retry_limit;
/* issue card_init command to device */
- ntStatus = vnt_control_out(pDevice,
+ status = vnt_control_out(priv,
MESSAGE_TYPE_CARDINIT, 0, 0,
sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd);
- if (ntStatus != STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail\n");
+ if (status != STATUS_SUCCESS) {
+ dev_dbg(&priv->usb->dev, "Issue Card init fail\n");
return false;
}
- ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_INIT_RSP, 0, 0,
+ status = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0,
sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp);
- if (ntStatus != STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+ if (status != STATUS_SUCCESS) {
+ dev_dbg(&priv->usb->dev,
"Cardinit request in status fail!\n");
return false;
}
/* local ID for AES functions */
- ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_READ,
+ status = vnt_control_in(priv, MESSAGE_TYPE_READ,
MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1,
- &pDevice->byLocalID);
- if (ntStatus != STATUS_SUCCESS)
+ &priv->local_id);
+ if (status != STATUS_SUCCESS)
return false;
/* do MACbSoftwareReset in MACvInitialize */
- pDevice->bProtectMode = false;
- /* only used in 11g type, sync with ERP IE */
- pDevice->bNonERPPresent = false;
- pDevice->bBarkerPreambleMd = false;
- if (pDevice->bFixRate) {
- pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
- } else {
- if (pDevice->byBBType == BB_TYPE_11B)
- pDevice->wCurrentRate = RATE_11M;
- else
- pDevice->wCurrentRate = RATE_54M;
- }
-
- CHvInitChannelTable(pDevice);
-
- pDevice->byTopOFDMBasicRate = RATE_24M;
- pDevice->byTopCCKBasicRate = RATE_1M;
+ priv->top_ofdm_basic_rate = RATE_24M;
+ priv->top_cck_basic_rate = RATE_1M;
/* target to IF pin while programming to RF chip */
- pDevice->byCurPwr = 0xFF;
+ priv->power = 0xFF;
- pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
- pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
+ priv->cck_pwr = priv->eeprom[EEP_OFS_PWR_CCK];
+ priv->ofdm_pwr_g = priv->eeprom[EEP_OFS_PWR_OFDMG];
/* load power table */
for (ii = 0; ii < 14; ii++) {
- pDevice->abyCCKPwrTbl[ii] =
- pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
-
- if (pDevice->abyCCKPwrTbl[ii] == 0)
- pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
- pDevice->abyOFDMPwrTbl[ii] =
- pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
- if (pDevice->abyOFDMPwrTbl[ii] == 0)
- pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
+ priv->cck_pwr_tbl[ii] =
+ priv->eeprom[ii + EEP_OFS_CCK_PWR_TBL];
+ if (priv->cck_pwr_tbl[ii] == 0)
+ priv->cck_pwr_tbl[ii] = priv->cck_pwr;
+
+ priv->ofdm_pwr_tbl[ii] =
+ priv->eeprom[ii + EEP_OFS_OFDM_PWR_TBL];
+ if (priv->ofdm_pwr_tbl[ii] == 0)
+ priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_g;
}
/*
* original zonetype is USA, but custom zonetype is Europe,
* then need to recover 12, 13, 14 channels with 11 channel
*/
- if (((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
- (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe)) &&
- (pDevice->byOriginalZonetype == ZoneType_USA)) {
- for (ii = 11; ii < 14; ii++) {
- pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
- pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
- }
+ for (ii = 11; ii < 14; ii++) {
+ priv->cck_pwr_tbl[ii] = priv->cck_pwr_tbl[10];
+ priv->ofdm_pwr_tbl[ii] = priv->ofdm_pwr_tbl[10];
}
- pDevice->byOFDMPwrA = 0x34; /* same as RFbMA2829SelectChannel */
+ priv->ofdm_pwr_a = 0x34; /* same as RFbMA2829SelectChannel */
/* load OFDM A power table */
for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) {
- pDevice->abyOFDMAPwrTbl[ii] =
- pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
+ priv->ofdm_a_pwr_tbl[ii] =
+ priv->eeprom[ii + EEP_OFS_OFDMA_PWR_TBL];
- if (pDevice->abyOFDMAPwrTbl[ii] == 0)
- pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
+ if (priv->ofdm_a_pwr_tbl[ii] == 0)
+ priv->ofdm_a_pwr_tbl[ii] = priv->ofdm_pwr_a;
}
- byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
+ antenna = priv->eeprom[EEP_OFS_ANTENNA];
- if (byAntenna & EEP_ANTINV)
- pDevice->bTxRxAntInv = true;
+ if (antenna & EEP_ANTINV)
+ priv->tx_rx_ant_inv = true;
else
- pDevice->bTxRxAntInv = false;
+ priv->tx_rx_ant_inv = false;
- byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+ antenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
- if (byAntenna == 0) /* if not set default is both */
- byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+ if (antenna == 0) /* if not set default is both */
+ antenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
- if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
- pDevice->byAntennaCount = 2;
- pDevice->byTxAntennaMode = ANT_B;
- pDevice->dwTxAntennaSel = 1;
- pDevice->dwRxAntennaSel = 1;
+ if (antenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+ priv->tx_antenna_mode = ANT_B;
+ priv->rx_antenna_sel = 1;
- if (pDevice->bTxRxAntInv == true)
- pDevice->byRxAntennaMode = ANT_A;
+ if (priv->tx_rx_ant_inv == true)
+ priv->rx_antenna_mode = ANT_A;
else
- pDevice->byRxAntennaMode = ANT_B;
+ priv->rx_antenna_mode = ANT_B;
} else {
- pDevice->byAntennaCount = 1;
- pDevice->dwTxAntennaSel = 0;
- pDevice->dwRxAntennaSel = 0;
+ priv->rx_antenna_sel = 0;
- if (byAntenna & EEP_ANTENNA_AUX) {
- pDevice->byTxAntennaMode = ANT_A;
+ if (antenna & EEP_ANTENNA_AUX) {
+ priv->tx_antenna_mode = ANT_A;
- if (pDevice->bTxRxAntInv == true)
- pDevice->byRxAntennaMode = ANT_B;
+ if (priv->tx_rx_ant_inv == true)
+ priv->rx_antenna_mode = ANT_B;
else
- pDevice->byRxAntennaMode = ANT_A;
+ priv->rx_antenna_mode = ANT_A;
} else {
- pDevice->byTxAntennaMode = ANT_B;
+ priv->tx_antenna_mode = ANT_B;
- if (pDevice->bTxRxAntInv == true)
- pDevice->byRxAntennaMode = ANT_A;
+ if (priv->tx_rx_ant_inv == true)
+ priv->rx_antenna_mode = ANT_A;
else
- pDevice->byRxAntennaMode = ANT_B;
+ priv->rx_antenna_mode = ANT_B;
}
}
+ /* Set initial antenna mode */
+ vnt_set_antenna_mode(priv, priv->rx_antenna_mode);
+
/* get Auto Fall Back type */
- pDevice->byAutoFBCtrl = AUTO_FB_0;
+ priv->auto_fb_ctrl = AUTO_FB_0;
/* default Auto Mode */
- /* pDevice->NetworkType = Ndis802_11Automode; */
- pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
- pDevice->byBBType = BB_TYPE_11G;
-
- /* get channel range */
- pDevice->byMinChannel = 1;
- pDevice->byMaxChannel = CB_MAX_CHANNEL;
+ priv->bb_type = BB_TYPE_11G;
/* get RFType */
- pDevice->byRFType = init_rsp->rf_type;
+ priv->rf_type = init_rsp->rf_type;
/* load vt3266 calibration parameters in EEPROM */
- if (pDevice->byRFType == RF_VT3226D0) {
- if ((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
- (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
-
- byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
- byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
- byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
- if (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) {
- /* CR255, enable TX/RX IQ and DC compensation mode */
- vnt_control_out_u8(pDevice,
- MESSAGE_REQUEST_BBREG,
- 0xff,
- 0x03);
- /* CR251, TX I/Q Imbalance Calibration */
- vnt_control_out_u8(pDevice,
- MESSAGE_REQUEST_BBREG,
- 0xfb,
- byCalibTXIQ);
- /* CR252, TX DC-Offset Calibration */
- vnt_control_out_u8(pDevice,
- MESSAGE_REQUEST_BBREG,
- 0xfC,
- byCalibTXDC);
- /* CR253, RX I/Q Imbalance Calibration */
- vnt_control_out_u8(pDevice,
- MESSAGE_REQUEST_BBREG,
- 0xfd,
- byCalibRXIQ);
+ if (priv->rf_type == RF_VT3226D0) {
+ if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) &&
+ (priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) {
+
+ calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ];
+ calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC];
+ calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ];
+ if (calib_tx_iq || calib_tx_dc || calib_rx_iq) {
+ /* CR255, enable TX/RX IQ and
+ DC compensation mode */
+ vnt_control_out_u8(priv,
+ MESSAGE_REQUEST_BBREG,
+ 0xff,
+ 0x03);
+ /* CR251, TX I/Q Imbalance Calibration */
+ vnt_control_out_u8(priv,
+ MESSAGE_REQUEST_BBREG,
+ 0xfb,
+ calib_tx_iq);
+ /* CR252, TX DC-Offset Calibration */
+ vnt_control_out_u8(priv,
+ MESSAGE_REQUEST_BBREG,
+ 0xfC,
+ calib_tx_dc);
+ /* CR253, RX I/Q Imbalance Calibration */
+ vnt_control_out_u8(priv,
+ MESSAGE_REQUEST_BBREG,
+ 0xfd,
+ calib_rx_iq);
} else {
- /* CR255, turn off BB Calibration compensation */
- vnt_control_out_u8(pDevice,
- MESSAGE_REQUEST_BBREG,
- 0xff,
- 0x0);
+ /* CR255, turn off
+ BB Calibration compensation */
+ vnt_control_out_u8(priv,
+ MESSAGE_REQUEST_BBREG,
+ 0xff,
+ 0x0);
}
}
}
- pMgmt->eScanType = WMAC_SCAN_PASSIVE;
- pMgmt->uCurrChannel = pDevice->uChannel;
- pMgmt->uIBSSChannel = pDevice->uChannel;
- CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
-
/* get permanent network address */
- memcpy(pDevice->abyPermanentNetAddr, init_rsp->net_addr, 6);
- memcpy(pDevice->abyCurrentNetAddr,
- pDevice->abyPermanentNetAddr, ETH_ALEN);
+ memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6);
+ memcpy(priv->current_net_addr, priv->permanent_net_addr, ETH_ALEN);
/* if exist SW network address, use it */
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n",
- pDevice->abyCurrentNetAddr);
+ dev_dbg(&priv->usb->dev, "Network address = %pM\n",
+ priv->current_net_addr);
/*
* set BB and packet type at the same time
* set Short Slot Time, xIFS, and RSPINF
*/
- if (pDevice->byBBType == BB_TYPE_11A) {
- CARDbAddBasicRate(pDevice, RATE_6M);
- pDevice->bShortSlotTime = true;
- } else {
- CARDbAddBasicRate(pDevice, RATE_1M);
- pDevice->bShortSlotTime = false;
- }
-
- BBvSetShortSlotTime(pDevice);
- CARDvSetBSSMode(pDevice);
-
- pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
- pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+ if (priv->bb_type == BB_TYPE_11A)
+ priv->short_slot_time = true;
+ else
+ priv->short_slot_time = false;
- BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+ vnt_set_short_slot_time(priv);
- pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
- pDevice->bHWRadioOff = false;
+ priv->radio_ctl = priv->eeprom[EEP_OFS_RADIOCTL];
- if ((pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0) {
- ntStatus = vnt_control_in(pDevice, MESSAGE_TYPE_READ,
- MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &byTmp);
+ if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) {
+ status = vnt_control_in(priv, MESSAGE_TYPE_READ,
+ MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &tmp);
- if (ntStatus != STATUS_SUCCESS)
+ if (status != STATUS_SUCCESS)
return false;
- if ((byTmp & GPIO3_DATA) == 0) {
- pDevice->bHWRadioOff = true;
- MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
- } else {
- MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
- pDevice->bHWRadioOff = false;
- }
-
+ if ((tmp & GPIO3_DATA) == 0)
+ vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1,
+ GPIO3_INTMD);
+ else
+ vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1,
+ GPIO3_INTMD);
}
- vnt_mac_set_led(pDevice, LEDSTS_TMLEN, 0x38);
+ vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38);
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
+ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
- MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL0, 0x01);
+ vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL0, 0x01);
- if ((pDevice->bHWRadioOff == true) ||
- (pDevice->bRadioControlOff == true)) {
- CARDbRadioPowerOff(pDevice);
- } else {
- CARDbRadioPowerOn(pDevice);
- }
+ vnt_radio_power_on(priv);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
+ dev_dbg(&priv->usb->dev, "<----INIbInitAdapter Exit\n");
return true;
}
-#ifdef CONFIG_PM /* Minimal support for suspend and resume */
-
-static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct vnt_private *device = usb_get_intfdata(intf);
-
- if (!device || !device->dev)
- return -ENODEV;
-
- if (device->flags & DEVICE_FLAGS_OPENED)
- device_close(device->dev);
-
- return 0;
-}
-
-static int vt6656_resume(struct usb_interface *intf)
-{
- struct vnt_private *device = usb_get_intfdata(intf);
-
- if (!device || !device->dev)
- return -ENODEV;
-
- if (!(device->flags & DEVICE_FLAGS_OPENED))
- device_open(device->dev);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static const struct net_device_ops device_netdev_ops = {
- .ndo_open = device_open,
- .ndo_stop = device_close,
- .ndo_do_ioctl = device_ioctl,
- .ndo_get_stats = device_get_stats,
- .ndo_start_xmit = device_xmit,
- .ndo_set_rx_mode = device_set_multi,
-};
-
-static int
-vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
- struct usb_device *udev = interface_to_usbdev(intf);
- int rc = 0;
- struct net_device *netdev = NULL;
- struct vnt_private *pDevice;
-
- printk(KERN_NOTICE "%s Ver. %s\n", DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
- printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
-
- udev = usb_get_dev(udev);
- netdev = alloc_etherdev(sizeof(struct vnt_private));
- if (!netdev) {
- printk(KERN_ERR DEVICE_NAME ": allocate net device failed\n");
- rc = -ENOMEM;
- goto err_nomem;
- }
-
- pDevice = netdev_priv(netdev);
- memset(pDevice, 0, sizeof(struct vnt_private));
-
- pDevice->dev = netdev;
- pDevice->usb = udev;
-
- device_set_options(pDevice);
- spin_lock_init(&pDevice->lock);
- mutex_init(&pDevice->usb_lock);
-
- INIT_DELAYED_WORK(&pDevice->run_command_work, vRunCommand);
- INIT_DELAYED_WORK(&pDevice->second_callback_work, BSSvSecondCallBack);
- INIT_WORK(&pDevice->read_work_item, RXvWorkItem);
- INIT_WORK(&pDevice->rx_mng_work_item, RXvMngWorkItem);
-
- pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
-
- netdev->netdev_ops = &device_netdev_ops;
- netdev->wireless_handlers =
- (struct iw_handler_def *) &iwctl_handler_def;
-
- usb_set_intfdata(intf, pDevice);
- SET_NETDEV_DEV(netdev, &intf->dev);
- memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN);
-
- usb_device_reset(pDevice);
-
- rc = register_netdev(netdev);
- if (rc) {
- printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
- goto err_netdev;
- }
-
- return 0;
-
-err_netdev:
- free_netdev(netdev);
-err_nomem:
- usb_put_dev(udev);
-
- return rc;
-}
-
-static void device_free_tx_bufs(struct vnt_private *priv)
+static void vnt_free_tx_bufs(struct vnt_private *priv)
{
struct vnt_usb_send_context *tx_context;
int ii;
- for (ii = 0; ii < priv->cbTD; ii++) {
- tx_context = priv->apTD[ii];
+ for (ii = 0; ii < priv->num_tx_context; ii++) {
+ tx_context = priv->tx_context[ii];
/* deallocate URBs */
if (tx_context->urb) {
usb_kill_urb(tx_context->urb);
@@ -686,677 +381,670 @@ static void device_free_tx_bufs(struct vnt_private *priv)
kfree(tx_context);
}
-
- return;
}
-static void device_free_rx_bufs(struct vnt_private *priv)
+static void vnt_free_rx_bufs(struct vnt_private *priv)
{
struct vnt_rcb *rcb;
int ii;
- for (ii = 0; ii < priv->cbRD; ii++) {
- rcb = priv->apRCB[ii];
+ for (ii = 0; ii < priv->num_rcb; ii++) {
+ rcb = priv->rcb[ii];
+ if (!rcb)
+ continue;
/* deallocate URBs */
- if (rcb->pUrb) {
- usb_kill_urb(rcb->pUrb);
- usb_free_urb(rcb->pUrb);
+ if (rcb->urb) {
+ usb_kill_urb(rcb->urb);
+ usb_free_urb(rcb->urb);
}
/* deallocate skb */
if (rcb->skb)
dev_kfree_skb(rcb->skb);
- }
- kfree(priv->pRCBMem);
-
- return;
+ kfree(rcb);
+ }
}
-static void usb_device_reset(struct vnt_private *pDevice)
+static void usb_device_reset(struct vnt_private *priv)
{
- int status;
- status = usb_reset_device(pDevice->usb);
+ int status;
+
+ status = usb_reset_device(priv->usb);
if (status)
- printk("usb_device_reset fail status=%d\n",status);
- return ;
+ dev_warn(&priv->usb->dev,
+ "usb_device_reset fail status=%d\n", status);
}
-static void device_free_int_bufs(struct vnt_private *priv)
+static void vnt_free_int_bufs(struct vnt_private *priv)
{
kfree(priv->int_buf.data_buf);
-
- return;
}
-static bool device_alloc_bufs(struct vnt_private *priv)
+static bool vnt_alloc_bufs(struct vnt_private *priv)
{
struct vnt_usb_send_context *tx_context;
struct vnt_rcb *rcb;
int ii;
- for (ii = 0; ii < priv->cbTD; ii++) {
+ for (ii = 0; ii < priv->num_tx_context; ii++) {
tx_context = kmalloc(sizeof(struct vnt_usb_send_context),
GFP_KERNEL);
if (tx_context == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s : allocate tx usb context failed\n",
- priv->dev->name);
+ dev_err(&priv->usb->dev,
+ "allocate tx usb context failed\n");
goto free_tx;
}
- priv->apTD[ii] = tx_context;
+ priv->tx_context[ii] = tx_context;
tx_context->priv = priv;
+ tx_context->pkt_no = ii;
/* allocate URBs */
tx_context->urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!tx_context->urb) {
- DBG_PRT(MSG_LEVEL_ERR,
- KERN_ERR "alloc tx urb failed\n");
+ dev_err(&priv->usb->dev, "alloc tx urb failed\n");
goto free_tx;
}
tx_context->in_use = false;
}
- /* allocate RCB mem */
- priv->pRCBMem = kzalloc((sizeof(struct vnt_rcb) * priv->cbRD),
- GFP_KERNEL);
- if (priv->pRCBMem == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s : alloc rx usb context failed\n",
- priv->dev->name);
- goto free_tx;
- }
-
- priv->FirstRecvFreeList = NULL;
- priv->LastRecvFreeList = NULL;
- priv->FirstRecvMngList = NULL;
- priv->LastRecvMngList = NULL;
- priv->NumRecvFreeList = 0;
+ for (ii = 0; ii < priv->num_rcb; ii++) {
+ priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL);
+ if (!priv->rcb[ii]) {
+ dev_err(&priv->usb->dev,
+ "failed to allocate rcb no %d\n", ii);
+ goto free_rx_tx;
+ }
- rcb = (struct vnt_rcb *)priv->pRCBMem;
+ rcb = priv->rcb[ii];
- for (ii = 0; ii < priv->cbRD; ii++) {
- priv->apRCB[ii] = rcb;
- rcb->pDevice = priv;
+ rcb->priv = priv;
/* allocate URBs */
- rcb->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
- if (rcb->pUrb == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- " Failed to alloc rx urb\n");
+ rcb->urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (rcb->urb == NULL) {
+ dev_err(&priv->usb->dev, "Failed to alloc rx urb\n");
goto free_rx_tx;
}
- rcb->skb = netdev_alloc_skb(priv->dev, priv->rx_buf_sz);
+ rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
if (rcb->skb == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
- " Failed to alloc rx skb\n");
+ dev_err(&priv->usb->dev, "Failed to alloc rx skb\n");
goto free_rx_tx;
}
- rcb->bBoolInUse = false;
+ rcb->in_use = false;
- EnqueueRCB(priv->FirstRecvFreeList,
- priv->LastRecvFreeList, rcb);
-
- priv->NumRecvFreeList++;
- rcb++;
+ /* submit rx urb */
+ if (vnt_submit_rx_urb(priv, rcb))
+ goto free_rx_tx;
}
- priv->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
- if (priv->pInterruptURB == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc int urb\n");
+ priv->interrupt_urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (priv->interrupt_urb == NULL) {
+ dev_err(&priv->usb->dev, "Failed to alloc int urb\n");
goto free_rx_tx;
}
priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
if (priv->int_buf.data_buf == NULL) {
- DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc int buf\n");
- usb_free_urb(priv->pInterruptURB);
+ dev_err(&priv->usb->dev, "Failed to alloc int buf\n");
+ usb_free_urb(priv->interrupt_urb);
goto free_rx_tx;
}
return true;
free_rx_tx:
- device_free_rx_bufs(priv);
+ vnt_free_rx_bufs(priv);
free_tx:
- device_free_tx_bufs(priv);
+ vnt_free_tx_bufs(priv);
return false;
}
-static bool device_init_defrag_cb(struct vnt_private *pDevice)
+static void vnt_tx_80211(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control, struct sk_buff *skb)
{
- int i;
- PSDeFragControlBlock pDeF;
-
- /* Init the fragment ctl entries */
- for (i = 0; i < CB_MAX_RX_FRAG; i++) {
- pDeF = &(pDevice->sRxDFCB[i]);
- if (!device_alloc_frag_buf(pDevice, pDeF)) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
- pDevice->dev->name);
- goto free_frag;
- }
- }
- pDevice->cbDFCB = CB_MAX_RX_FRAG;
- pDevice->cbFreeDFCB = pDevice->cbDFCB;
- return true;
-
-free_frag:
- device_free_frag_bufs(pDevice);
- return false;
+ struct vnt_private *priv = hw->priv;
+
+ ieee80211_stop_queues(hw);
+
+ if (vnt_tx_packet(priv, skb)) {
+ ieee80211_free_txskb(hw, skb);
+
+ ieee80211_wake_queues(hw);
+ }
}
-static void device_free_frag_bufs(struct vnt_private *pDevice)
+static int vnt_start(struct ieee80211_hw *hw)
{
- PSDeFragControlBlock pDeF;
- int i;
+ struct vnt_private *priv = hw->priv;
+
+ priv->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
- for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+ if (vnt_alloc_bufs(priv) == false) {
+ dev_dbg(&priv->usb->dev, "vnt_alloc_bufs fail...\n");
+ return -ENOMEM;
+ }
- pDeF = &(pDevice->sRxDFCB[i]);
+ clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
- if (pDeF->skb)
- dev_kfree_skb(pDeF->skb);
- }
-}
+ if (vnt_init_registers(priv) == false) {
+ dev_dbg(&priv->usb->dev, " init register fail\n");
+ goto free_all;
+ }
-int device_alloc_frag_buf(struct vnt_private *pDevice,
- PSDeFragControlBlock pDeF)
-{
- pDeF->skb = netdev_alloc_skb(pDevice->dev, pDevice->rx_buf_sz);
- if (!pDeF->skb)
- return false;
+ priv->int_interval = 1; /* bInterval is set to 1 */
- return true;
-}
+ vnt_int_start_interrupt(priv);
-static int device_open(struct net_device *dev)
-{
- struct vnt_private *pDevice = netdev_priv(dev);
+ ieee80211_wake_queues(hw);
- pDevice->fWPA_Authened = false;
+ return 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
+free_all:
+ vnt_free_rx_bufs(priv);
+ vnt_free_tx_bufs(priv);
+ vnt_free_int_bufs(priv);
- pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
+ usb_kill_urb(priv->interrupt_urb);
+ usb_free_urb(priv->interrupt_urb);
- if (device_alloc_bufs(pDevice) == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
- return -ENOMEM;
- }
+ return -ENOMEM;
+}
- if (device_init_defrag_cb(pDevice)== false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragment cb fail \n");
- goto free_rx_tx;
- }
+static void vnt_stop(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
+ int i;
- MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
- MP_SET_FLAG(pDevice, fMP_POST_READS);
- MP_SET_FLAG(pDevice, fMP_POST_WRITES);
+ if (!priv)
+ return;
- /* read config file */
- Read_config_file(pDevice);
+ for (i = 0; i < MAX_KEY_TABLE; i++)
+ vnt_mac_disable_keyentry(priv, i);
- if (device_init_registers(pDevice) == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
- goto free_all;
- }
+ /* clear all keys */
+ priv->key_entry_inuse = 0;
- /* init for key management */
- KeyvInitTable(pDevice,&pDevice->sKey);
- memcpy(pDevice->vnt_mgmt.abyMACAddr,
- pDevice->abyCurrentNetAddr, ETH_ALEN);
- memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN);
- pDevice->bStopTx0Pkt = false;
- pDevice->bStopDataPkt = false;
- pDevice->bRoaming = false;
- pDevice->bIsRoaming = false;
- pDevice->bEnableRoaming = false;
-
- vMgrObjectInit(pDevice);
-
- schedule_delayed_work(&pDevice->second_callback_work, HZ);
-
- pDevice->int_interval = 1; /* bInterval is set to 1 */
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-
- pDevice->bIsRxWorkItemQueued = true;
-
- pDevice->bWPADEVUp = false;
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = false;
- pDevice->bWPASuppWextEnabled = false;
- pDevice->byReAssocCount = 0;
-
- schedule_work(&pDevice->read_work_item);
- INTvWorkItem(pDevice);
-
- /* if WEP key already set by iwconfig but device not yet open */
- if ((pDevice->bEncryptionEnable == true) && (pDevice->bTransmitKey == true)) {
- KeybSetDefaultKey( pDevice,
- &(pDevice->sKey),
- pDevice->byKeyIndex | (1 << 31),
- pDevice->uKeyLength,
- NULL,
- pDevice->abyKey,
- KEY_CTL_WEP
- );
-
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- }
-
- if (pDevice->vnt_mgmt.eConfigMode == WMAC_CONFIG_AP)
- bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL);
- else
- bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+ if (!test_bit(DEVICE_FLAGS_UNPLUG, &priv->flags))
+ vnt_mac_shutdown(priv);
- netif_stop_queue(pDevice->dev);
- pDevice->flags |= DEVICE_FLAGS_OPENED;
+ ieee80211_stop_queues(hw);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n");
- return 0;
+ set_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
-free_all:
- device_free_frag_bufs(pDevice);
-free_rx_tx:
- device_free_rx_bufs(pDevice);
- device_free_tx_bufs(pDevice);
- device_free_int_bufs(pDevice);
- usb_kill_urb(pDevice->pInterruptURB);
- usb_free_urb(pDevice->pInterruptURB);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
- return -ENOMEM;
+ cancel_delayed_work_sync(&priv->run_command_work);
+
+ priv->cmd_running = false;
+
+ vnt_free_tx_bufs(priv);
+ vnt_free_rx_bufs(priv);
+ vnt_free_int_bufs(priv);
+
+ usb_kill_urb(priv->interrupt_urb);
+ usb_free_urb(priv->interrupt_urb);
}
-static int device_close(struct net_device *dev)
+static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u8 uu;
+ struct vnt_private *priv = hw->priv;
+
+ priv->vif = vif;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1\n");
- if (pDevice == NULL)
- return -ENODEV;
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
- if (pDevice->bLinkPass) {
- bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
- mdelay(30);
- }
+ vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
- memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- pMgmt->bShareKeyAlgorithm = false;
- pDevice->bEncryptionEnable = false;
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+ break;
+ case NL80211_IFTYPE_AP:
+ vnt_mac_reg_bits_off(priv, MAC_REG_RCR, RCR_UNICAST);
- for (uu = 0; uu < MAX_KEY_TABLE; uu++)
- MACvDisableKeyEntry(pDevice,uu);
+ vnt_mac_reg_bits_on(priv, MAC_REG_HOSTCR, HOSTCR_AP);
- if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == false) {
- MACbShutdown(pDevice);
- }
- netif_stop_queue(pDevice->dev);
- MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
- MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
- MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
- cancel_delayed_work_sync(&pDevice->run_command_work);
- cancel_delayed_work_sync(&pDevice->second_callback_work);
+ priv->op_mode = vif->type;
- cancel_work_sync(&pDevice->rx_mng_work_item);
- cancel_work_sync(&pDevice->read_work_item);
+ vnt_set_bss_mode(priv);
- pDevice->bRoaming = false;
- pDevice->bIsRoaming = false;
- pDevice->bEnableRoaming = false;
- pDevice->bCmdRunning = false;
- pDevice->bLinkPass = false;
- memset(pMgmt->abyCurrBSSID, 0, 6);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
+ /* LED blink on TX */
+ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER);
- pDevice->flags &= ~DEVICE_FLAGS_OPENED;
+ return 0;
+}
- device_free_tx_bufs(pDevice);
- device_free_rx_bufs(pDevice);
- device_free_int_bufs(pDevice);
- device_free_frag_bufs(pDevice);
+static void vnt_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
- usb_kill_urb(pDevice->pInterruptURB);
- usb_free_urb(pDevice->pInterruptURB);
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+ break;
+ case NL80211_IFTYPE_AP:
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
+ vnt_mac_reg_bits_off(priv, MAC_REG_HOSTCR, HOSTCR_AP);
+ break;
+ default:
+ break;
+ }
- BSSvClearNodeDBTable(pDevice, 0);
+ vnt_radio_power_off(priv);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
+ priv->op_mode = NL80211_IFTYPE_UNSPECIFIED;
- return 0;
+ /* LED slow blink */
+ vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_SLOW);
}
-static void vt6656_disconnect(struct usb_interface *intf)
+static int vnt_config(struct ieee80211_hw *hw, u32 changed)
{
- struct vnt_private *device = usb_get_intfdata(intf);
+ struct vnt_private *priv = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
+ u8 bb_type;
- if (!device)
- return;
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS)
+ vnt_enable_power_saving(priv, conf->listen_interval);
+ else
+ vnt_disable_power_saving(priv);
+ }
- usb_set_intfdata(intf, NULL);
- usb_put_dev(interface_to_usbdev(intf));
+ if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
+ (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
+ vnt_set_channel(priv, conf->chandef.chan->hw_value);
+
+ if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
+ bb_type = BB_TYPE_11A;
+ else
+ bb_type = BB_TYPE_11G;
- device->flags |= DEVICE_FLAGS_UNPLUG;
+ if (priv->bb_type != bb_type) {
+ priv->bb_type = bb_type;
- if (device->dev) {
- unregister_netdev(device->dev);
- free_netdev(device->dev);
+ vnt_set_bss_mode(priv);
+ }
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ if (priv->bb_type == BB_TYPE_11B)
+ priv->current_rate = RATE_1M;
+ else
+ priv->current_rate = RATE_54M;
+
+ vnt_rf_setpower(priv, priv->current_rate,
+ conf->chandef.chan->hw_value);
}
+
+ return 0;
}
-static int device_xmit(struct sk_buff *skb, struct net_device *dev)
+static void vnt_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf,
+ u32 changed)
{
- struct vnt_private *pDevice = netdev_priv(dev);
- struct net_device_stats *stats = &pDevice->stats;
- unsigned long flags;
+ struct vnt_private *priv = hw->priv;
+
+ priv->current_aid = conf->aid;
+
+ if (changed & BSS_CHANGED_BSSID)
+ vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid);
- spin_lock_irqsave(&pDevice->lock, flags);
- netif_stop_queue(dev);
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ priv->basic_rates = conf->basic_rates;
- if (!pDevice->bLinkPass) {
- dev_kfree_skb_irq(skb);
- goto out;
+ vnt_update_top_rates(priv);
+
+ dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates);
}
- if (pDevice->bStopDataPkt) {
- dev_kfree_skb_irq(skb);
- stats->tx_dropped++;
- goto out;
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ if (conf->use_short_preamble) {
+ vnt_mac_enable_barker_preamble_mode(priv);
+ priv->preamble_type = true;
+ } else {
+ vnt_mac_disable_barker_preamble_mode(priv);
+ priv->preamble_type = false;
+ }
}
- if (nsDMA_tx_packet(pDevice, skb)) {
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
+ if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+ if (conf->use_cts_prot)
+ vnt_mac_enable_protect_mode(priv);
+ else
+ vnt_mac_disable_protect_mode(priv);
}
-out:
- spin_unlock_irqrestore(&pDevice->lock, flags);
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ if (conf->use_short_slot)
+ priv->short_slot_time = true;
+ else
+ priv->short_slot_time = false;
- return NETDEV_TX_OK;
-}
+ vnt_set_short_slot_time(priv);
+ vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
+ vnt_update_pre_ed_threshold(priv, false);
+ }
+
+ if (changed & BSS_CHANGED_TXPOWER)
+ vnt_rf_setpower(priv, priv->current_rate,
+ conf->chandef.chan->hw_value);
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED) {
+ dev_dbg(&priv->usb->dev,
+ "Beacon enable %d\n", conf->enable_beacon);
-/* find out the start position of str2 from str1 */
-static unsigned char *kstrstr(const unsigned char *str1,
- const unsigned char *str2) {
- int str1_len = strlen(str1);
- int str2_len = strlen(str2);
-
- while (str1_len >= str2_len) {
- str1_len--;
- if(memcmp(str1,str2,str2_len)==0)
- return (unsigned char *) str1;
- str1++;
- }
- return NULL;
+ if (conf->enable_beacon) {
+ vnt_beacon_enable(priv, vif, conf);
+
+ vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ } else {
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
+ }
+ }
}
-static int Config_FileGetParameter(unsigned char *string,
- unsigned char *dest,
- unsigned char *source)
+static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
+ struct netdev_hw_addr_list *mc_list)
{
- unsigned char buf1[100];
- unsigned char buf2[100];
- unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL;
- int ii;
-
- memset(buf1,0,100);
- strcat(buf1, string);
- strcat(buf1, "=");
- source+=strlen(buf1);
-
- /* find target string start point */
- start_p = kstrstr(source,buf1);
- if (start_p == NULL)
- return false;
+ struct vnt_private *priv = hw->priv;
+ struct netdev_hw_addr *ha;
+ u64 mc_filter = 0;
+ u32 bit_nr = 0;
- /* check if current config line is marked by "#" */
- for (ii = 1; ; ii++) {
- if (memcmp(start_p - ii, "\n", 1) == 0)
- break;
- if (memcmp(start_p - ii, "#", 1) == 0)
- return false;
- }
-
- /* find target string end point */
- end_p = kstrstr(start_p,"\n");
- if (end_p == NULL) { /* can't find "\n", but don't care */
- end_p = start_p + strlen(start_p); /* no include "\n" */
- }
-
- memset(buf2,0,100);
- memcpy(buf2, start_p, end_p-start_p); /* get the target line */
- buf2[end_p-start_p]='\0';
-
- /* find value */
- start_p = kstrstr(buf2,"=");
- if (start_p == NULL)
- return false;
- memset(buf1,0,100);
- strcpy(buf1,start_p+1);
-
- /* except space */
- tmp_p = buf1;
- while(*tmp_p != 0x00) {
- if(*tmp_p==' ')
- tmp_p++;
- else
- break;
- }
-
- memcpy(dest,tmp_p,strlen(tmp_p));
- return true;
+ netdev_hw_addr_list_for_each(ha, mc_list) {
+ bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
+
+ mc_filter |= 1ULL << (bit_nr & 0x3f);
+ }
+
+ priv->mc_list_count = mc_list->count;
+
+ return mc_filter;
}
-/* if read fails, return NULL, or return data pointer */
-static unsigned char *Config_FileOperation(struct vnt_private *pDevice)
+static void vnt_configure(struct ieee80211_hw *hw,
+ unsigned int changed_flags, unsigned int *total_flags, u64 multicast)
{
- unsigned char *buffer = kmalloc(1024, GFP_KERNEL);
- struct file *file;
+ struct vnt_private *priv = hw->priv;
+ u8 rx_mode = 0;
+ int rc;
+
+ *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_PROMISC_IN_BSS |
+ FIF_BCN_PRBRESP_PROMISC;
+
+ rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
+ MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
+
+ if (!rc)
+ rx_mode = RCR_MULTICAST | RCR_BROADCAST;
+
+ dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode);
- if (!buffer) {
- printk("allocate mem for file fail?\n");
- return NULL;
+ if (changed_flags & FIF_PROMISC_IN_BSS) {
+ /* unconditionally log net taps */
+ if (*total_flags & FIF_PROMISC_IN_BSS)
+ rx_mode |= RCR_UNICAST;
+ else
+ rx_mode &= ~RCR_UNICAST;
}
- file = filp_open(CONFIG_PATH, O_RDONLY, 0);
- if (IS_ERR(file)) {
- kfree(buffer);
- printk("Config_FileOperation file Not exist\n");
- return NULL;
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*total_flags & FIF_ALLMULTI) {
+ if (priv->mc_list_count > 2)
+ vnt_mac_set_filter(priv, ~0);
+ else
+ vnt_mac_set_filter(priv, multicast);
+
+ rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
+ } else {
+ rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
+ }
+
}
- if (kernel_read(file, 0, buffer, 1024) < 0) {
- printk("read file error?\n");
- kfree(buffer);
- buffer = NULL;
+ if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
+ if (*total_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC))
+ rx_mode &= ~RCR_BSSID;
+ else
+ rx_mode |= RCR_BSSID;
}
- fput(file);
- return buffer;
+ vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, rx_mode);
+
+ dev_dbg(&priv->usb->dev, "rx mode out= %x\n", rx_mode);
}
-/* return --->-1:fail; >=0:successful */
-static int Read_config_file(struct vnt_private *pDevice)
+static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
- int result = 0;
- unsigned char tmpbuffer[100];
- unsigned char *buffer = NULL;
-
- /* init config setting */
- pDevice->config_file.ZoneType = -1;
- pDevice->config_file.eAuthenMode = -1;
- pDevice->config_file.eEncryptionStatus = -1;
-
- buffer = Config_FileOperation(pDevice);
- if (buffer == NULL) {
- result =-1;
- return result;
- }
-
-/* get zonetype */
-{
- memset(tmpbuffer,0,sizeof(tmpbuffer));
- if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==true) {
- if(memcmp(tmpbuffer,"USA",3)==0) {
- pDevice->config_file.ZoneType=ZoneType_USA;
- }
- else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
- pDevice->config_file.ZoneType=ZoneType_Japan;
- }
- else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
- pDevice->config_file.ZoneType=ZoneType_Europe;
- }
- else {
- printk("Unknown Zonetype[%s]?\n",tmpbuffer);
- }
- }
-}
+ struct vnt_private *priv = hw->priv;
-/* get other parameter */
- {
- memset(tmpbuffer,0,sizeof(tmpbuffer));
- if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==true) {
- pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
- }
-
- memset(tmpbuffer,0,sizeof(tmpbuffer));
- if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==true) {
- pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
- }
- }
-
- kfree(buffer);
- return result;
+ switch (cmd) {
+ case SET_KEY:
+ if (vnt_set_keys(hw, sta, vif, key))
+ return -EOPNOTSUPP;
+ break;
+ case DISABLE_KEY:
+ if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
+ clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
+ default:
+ break;
+ }
+
+ return 0;
}
-static void device_set_multi(struct net_device *dev)
+static void vnt_sw_scan_start(struct ieee80211_hw *hw)
{
- struct vnt_private *priv = netdev_priv(dev);
- unsigned long flags;
+ struct vnt_private *priv = hw->priv;
- if (priv->flags & DEVICE_FLAGS_OPENED) {
- spin_lock_irqsave(&priv->lock, flags);
+ vnt_set_bss_mode(priv);
+ /* Set max sensitivity*/
+ vnt_update_pre_ed_threshold(priv, true);
+}
- bScheduleCommand(priv, WLAN_CMD_CONFIGURE_FILTER, NULL);
+static void vnt_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct vnt_private *priv = hw->priv;
- spin_unlock_irqrestore(&priv->lock, flags);
- }
+ /* Return sensitivity to channel level*/
+ vnt_update_pre_ed_threshold(priv, false);
}
-void vnt_configure_filter(struct vnt_private *priv)
+static int vnt_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
{
- struct net_device *dev = priv->dev;
- struct vnt_manager *mgmt = &priv->vnt_mgmt;
- struct netdev_hw_addr *ha;
- u64 mc_filter = 0;
- u8 tmp = 0;
- int rc;
+ struct vnt_private *priv = hw->priv;
- rc = vnt_control_in(priv, MESSAGE_TYPE_READ,
- MAC_REG_RCR, MESSAGE_REQUEST_MACREG, 1, &tmp);
- if (rc == 0)
- priv->byRxMode = tmp;
+ memcpy(stats, &priv->low_stats, sizeof(*stats));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "priv->byRxMode in= %x\n",
- priv->byRxMode);
+ return 0;
+}
- if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
- DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE
- "%s: Promiscuous mode enabled.\n", dev->name);
- /* unconditionally log net taps */
- priv->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
- } else if ((netdev_mc_count(dev) > priv->multicast_limit) ||
- (dev->flags & IFF_ALLMULTI)) {
- mc_filter = ~0x0;
- MACvWriteMultiAddr(priv, mc_filter);
-
- priv->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
- } else {
- netdev_for_each_mc_addr(ha, dev) {
- int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
-
- mc_filter |= 1ULL << (bit_nr & 0x3f);
- }
+static u64 vnt_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
- MACvWriteMultiAddr(priv, mc_filter);
+ return priv->current_tsf;
+}
- priv->byRxMode &= ~(RCR_UNICAST);
- priv->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
- }
+static void vnt_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u64 tsf)
+{
+ struct vnt_private *priv = hw->priv;
- if (mgmt->eConfigMode == WMAC_CONFIG_AP) {
- /*
- * If AP mode, don't enable RCR_UNICAST since HW only compares
- * addr1 with local MAC
- */
- priv->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
- priv->byRxMode &= ~(RCR_UNICAST);
- }
+ vnt_update_next_tbtt(priv, tsf, vif->bss_conf.beacon_int);
+}
+
+static void vnt_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct vnt_private *priv = hw->priv;
- vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG,
- MAC_REG_RCR, priv->byRxMode);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "priv->byRxMode out= %x\n", priv->byRxMode);
+ vnt_clear_current_tsf(priv);
}
-static struct net_device_stats *device_get_stats(struct net_device *dev)
+static const struct ieee80211_ops vnt_mac_ops = {
+ .tx = vnt_tx_80211,
+ .start = vnt_start,
+ .stop = vnt_stop,
+ .add_interface = vnt_add_interface,
+ .remove_interface = vnt_remove_interface,
+ .config = vnt_config,
+ .bss_info_changed = vnt_bss_info_changed,
+ .prepare_multicast = vnt_prepare_multicast,
+ .configure_filter = vnt_configure,
+ .set_key = vnt_set_key,
+ .sw_scan_start = vnt_sw_scan_start,
+ .sw_scan_complete = vnt_sw_scan_complete,
+ .get_stats = vnt_get_stats,
+ .get_tsf = vnt_get_tsf,
+ .set_tsf = vnt_set_tsf,
+ .reset_tsf = vnt_reset_tsf,
+};
+
+int vnt_init(struct vnt_private *priv)
{
- struct vnt_private *pDevice = netdev_priv(dev);
- return &pDevice->stats;
+ if (!(vnt_init_registers(priv)))
+ return -EAGAIN;
+
+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr);
+
+ vnt_init_bands(priv);
+
+ if (ieee80211_register_hw(priv->hw))
+ return -ENODEV;
+
+ priv->mac_hw = true;
+
+ vnt_radio_power_off(priv);
+
+ return 0;
}
-static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int
+vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
+ struct usb_device *udev;
+ struct vnt_private *priv;
+ struct ieee80211_hw *hw;
+ struct wiphy *wiphy;
int rc = 0;
- switch (cmd) {
- case SIOCETHTOOL:
- return ethtool_ioctl(dev, rq);
+ udev = usb_get_dev(interface_to_usbdev(intf));
+ dev_notice(&udev->dev, "%s Ver. %s\n",
+ DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+ dev_notice(&udev->dev,
+ "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+
+ hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops);
+ if (!hw) {
+ dev_err(&udev->dev, "could not register ieee80211_hw\n");
+ goto err_nomem;
}
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->usb = udev;
+
+ vnt_set_options(priv);
+
+ spin_lock_init(&priv->lock);
+ mutex_init(&priv->usb_lock);
+
+ INIT_DELAYED_WORK(&priv->run_command_work, vnt_run_command);
+
+ usb_set_intfdata(intf, priv);
+
+ wiphy = priv->hw->wiphy;
+
+ wiphy->frag_threshold = FRAG_THRESH_DEF;
+ wiphy->rts_threshold = RTS_THRESH_DEF;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
+
+ priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_TIMING_BEACON_ONLY;
+
+ priv->hw->rate_control_algorithm = "pid";
+ priv->hw->max_signal = 100;
+
+ SET_IEEE80211_DEV(priv->hw, &intf->dev);
+
+ usb_device_reset(priv);
+
+ clear_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags);
+ vnt_reset_command_timer(priv);
+
+ vnt_schedule_command(priv, WLAN_CMD_INIT_MAC80211);
+
+ return 0;
+
+err_nomem:
+ usb_put_dev(udev);
+
return rc;
}
-static int ethtool_ioctl(struct net_device *dev, struct ifreq *rq)
+static void vt6656_disconnect(struct usb_interface *intf)
{
- u32 ethcmd;
-
- if (copy_from_user(&ethcmd, rq->ifr_data, sizeof(ethcmd)))
- return -EFAULT;
-
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: {
- struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
- strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
- strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
- if (copy_to_user(rq->ifr_data, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
+ struct vnt_private *priv = usb_get_intfdata(intf);
+
+ if (!priv)
+ return;
- }
+ if (priv->mac_hw)
+ ieee80211_unregister_hw(priv->hw);
- return -EOPNOTSUPP;
+ usb_set_intfdata(intf, NULL);
+ usb_put_dev(interface_to_usbdev(intf));
+
+ set_bit(DEVICE_FLAGS_UNPLUG, &priv->flags);
+
+ ieee80211_free_hw(priv->hw);
+}
+
+#ifdef CONFIG_PM
+
+static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ return 0;
}
+static int vt6656_resume(struct usb_interface *intf)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
MODULE_DEVICE_TABLE(usb, vt6656_table);
static struct usb_driver vt6656_driver = {
diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c
deleted file mode 100644
index 9a5a0b6761ed..000000000000
--- a/drivers/staging/vt6656/michael.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: michael.cpp
- *
- * Purpose: The implementation of LIST data structure.
- *
- * Author: Kyle Hsu
- *
- * Date: Sep 4, 2002
- *
- * Functions:
- * s_dwGetUINT32 - Convert from u8[] to u32 in a portable way
- * s_vPutUINT32 - Convert from u32 to u8[] in a portable way
- * s_vClear - Reset the state to the empty message.
- * s_vSetKey - Set the key.
- * MIC_vInit - Set the key.
- * s_vAppendByte - Append the byte to our word-sized buffer.
- * MIC_vAppend - call s_vAppendByte.
- * MIC_vGetMIC - Append the minimum padding and call s_vAppendByte.
- *
- * Revision History:
- *
- */
-
-#include "tmacro.h"
-#include "michael.h"
-
-/*
- * static u32 s_dwGetUINT32(u8 * p); Get u32 from
- * 4 bytes LSByte first
- * static void s_vPutUINT32(u8* p, u32 val); Put u32 into
- * 4 bytes LSByte first
- */
-static void s_vClear(void); /* Clear the internal message,
- * resets the object to the
- * state just after construction. */
-static void s_vSetKey(u32 dwK0, u32 dwK1);
-static void s_vAppendByte(u8 b); /* Add a single byte to the internal
- * message */
-
-static u32 L, R; /* Current state */
-static u32 K0, K1; /* Key */
-static u32 M; /* Message accumulator (single word) */
-static unsigned int nBytesInM; /* # bytes in M */
-
-/*
-static u32 s_dwGetUINT32 (u8 * p)
-// Convert from u8[] to u32 in a portable way
-{
- u32 res = 0;
- unsigned int i;
- for (i = 0; i < 4; i++)
- res |= (*p++) << (8*i);
- return res;
-}
-
-static void s_vPutUINT32(u8 *p, u32 val)
-// Convert from u32 to u8[] in a portable way
-{
- unsigned int i;
- for (i = 0; i < 4; i++) {
- *p++ = (u8) (val & 0xff);
- val >>= 8;
- }
-}
-*/
-
-static void s_vClear(void)
-{
- /* Reset the state to the empty message. */
- L = K0;
- R = K1;
- nBytesInM = 0;
- M = 0;
-}
-
-static void s_vSetKey(u32 dwK0, u32 dwK1)
-{
- /* Set the key */
- K0 = dwK0;
- K1 = dwK1;
- /* and reset the message */
- s_vClear();
-}
-
-static void s_vAppendByte(u8 b)
-{
- /* Append the byte to our word-sized buffer */
- M |= b << (8*nBytesInM);
- nBytesInM++;
- /* Process the word if it is full. */
- if (nBytesInM >= 4) {
- L ^= M;
- R ^= ROL32(L, 17);
- L += R;
- R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
- L += R;
- R ^= ROL32(L, 3);
- L += R;
- R ^= ROR32(L, 2);
- L += R;
- /* Clear the buffer */
- M = 0;
- nBytesInM = 0;
- }
-}
-
-void MIC_vInit(u32 dwK0, u32 dwK1)
-{
- /* Set the key */
- s_vSetKey(dwK0, dwK1);
-}
-
-void MIC_vUnInit(void)
-{
- /* Wipe the key material */
- K0 = 0;
- K1 = 0;
-
- /* And the other fields as well. */
- /* Note that this sets (L,R) to (K0,K1) which is just fine. */
- s_vClear();
-}
-
-void MIC_vAppend(u8 * src, unsigned int nBytes)
-{
- /* This is simple */
- while (nBytes > 0) {
- s_vAppendByte(*src++);
- nBytes--;
- }
-}
-
-void MIC_vGetMIC(u32 * pdwL, u32 * pdwR)
-{
- /* Append the minimum padding */
- s_vAppendByte(0x5a);
- s_vAppendByte(0);
- s_vAppendByte(0);
- s_vAppendByte(0);
- s_vAppendByte(0);
- /* and then zeroes until the length is a multiple of 4 */
- while (nBytesInM != 0)
- s_vAppendByte(0);
- /* The s_vAppendByte function has already computed the result. */
- *pdwL = L;
- *pdwR = R;
- /* Reset to the empty message. */
- s_vClear();
-}
diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h
deleted file mode 100644
index 9c69a42640a7..000000000000
--- a/drivers/staging/vt6656/michael.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: Michael.h
- *
- * Purpose: Reference implementation for Michael
- * written by Niels Ferguson
- *
- * Author: Kyle Hsu
- *
- * Date: Jan 2, 2003
- *
- */
-
-#ifndef __MICHAEL_H__
-#define __MICHAEL_H__
-
-#include <linux/types.h>
-
-void MIC_vInit(u32 dwK0, u32 dwK1);
-
-void MIC_vUnInit(void);
-
-// Append bytes to the message to be MICed
-void MIC_vAppend(u8 * src, unsigned int nBytes);
-
-// Get the MIC result. Destination should accept 8 bytes of result.
-// This also resets the message to empty.
-void MIC_vGetMIC(u32 * pdwL, u32 * pdwR);
-
-// Rotation functions on 32 bit values
-#define ROL32(A, n) \
- (((A) << (n)) | (((A)>>(32-(n))) & ((1UL << (n)) - 1)))
-#define ROR32(A, n) ROL32((A), 32-(n))
-
-#endif /* __MICHAEL_H__ */
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
index ddbd04695c99..0ffbaed5d774 100644
--- a/drivers/staging/vt6656/power.c
+++ b/drivers/staging/vt6656/power.c
@@ -26,12 +26,9 @@
* Date: July 17, 2002
*
* Functions:
- * PSvEnablePowerSaving - Enable Power Saving Mode
+ * vnt_enable_power_saving - Enable Power Saving Mode
* PSvDiasblePowerSaving - Disable Power Saving Mode
- * PSbConsiderPowerDown - Decide if we can Power Down
- * PSvSendPSPOLL - Send PS-POLL packet
- * PSbSendNullPacket - Send Null packet
- * PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon
+ * vnt_next_tbtt_wakeup - Decide if we need to wake up at next Beacon
*
* Revision History:
*
@@ -39,15 +36,12 @@
#include "mac.h"
#include "device.h"
-#include "wmgr.h"
#include "power.h"
#include "wcmd.h"
#include "rxtx.h"
#include "card.h"
#include "usbpipe.h"
-static int msglevel = MSG_LEVEL_INFO;
-
/*
*
* Routine Description:
@@ -58,61 +52,46 @@ static int msglevel = MSG_LEVEL_INFO;
*
*/
-void PSvEnablePowerSaving(struct vnt_private *pDevice, u16 wListenInterval)
+void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval)
{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u16 wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+ u16 aid = priv->current_aid | BIT(14) | BIT(15);
/* set period of power up before TBTT */
- MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT);
+ vnt_mac_write_word(priv, MAC_REG_PWBT, C_PWBT);
- if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) {
+ if (priv->op_mode != NL80211_IFTYPE_ADHOC) {
/* set AID */
- MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
+ vnt_mac_write_word(priv, MAC_REG_AIDATIM, aid);
}
/* Warren:06-18-2004,the sequence must follow
* PSEN->AUTOSLEEP->GO2DOZE
*/
/* enable power saving hw function */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_PSEN);
/* Set AutoSleep */
- MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
/* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the
* AUTOSLEEP doesn't work
*/
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE);
- if (wListenInterval >= 2) {
+ if (listen_interval >= 2) {
/* clear always listen beacon */
- MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+ vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
/* first time set listen next beacon */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
-
- pMgmt->wCountToWakeUp = wListenInterval;
-
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
} else {
/* always listen beacon */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
-
- pMgmt->wCountToWakeUp = 0;
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
}
- pDevice->bEnablePSMode = true;
-
- /* We don't send null pkt in ad hoc mode
- * since beacon will handle this.
- */
- if (pDevice->op_mode == NL80211_IFTYPE_STATION)
- PSbSendNullPacket(pDevice);
-
- pDevice->bPWBitOn = true;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n");
+ dev_dbg(&priv->usb->dev, "PS:Power Saving Mode Enable...\n");
}
/*
@@ -125,181 +104,18 @@ void PSvEnablePowerSaving(struct vnt_private *pDevice, u16 wListenInterval)
*
*/
-void PSvDisablePowerSaving(struct vnt_private *pDevice)
+void vnt_disable_power_saving(struct vnt_private *priv)
{
/* disable power saving hw function */
- vnt_control_out(pDevice, MESSAGE_TYPE_DISABLE_PS, 0,
+ vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0,
0, 0, NULL);
/* clear AutoSleep */
- MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+ vnt_mac_reg_bits_off(priv, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
/* set always listen beacon */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
- pDevice->bEnablePSMode = false;
-
- if (pDevice->op_mode == NL80211_IFTYPE_STATION)
- PSbSendNullPacket(pDevice);
-
- pDevice->bPWBitOn = false;
-}
-
-/*
- *
- * Routine Description:
- * Consider to power down when no more packets to tx or rx.
- *
- * Return Value:
- * true, if power down success
- * false, if fail
- */
-
-int PSbConsiderPowerDown(struct vnt_private *pDevice, int bCheckRxDMA,
- int bCheckCountToWakeUp)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u8 byData;
-
- /* check if already in Doze mode */
- vnt_control_in_u8(pDevice, MESSAGE_REQUEST_MACREG,
- MAC_REG_PSCTL, &byData);
-
- if ((byData & PSCTL_PS) != 0)
- return true;
-
- if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
- /* check if in TIM wake period */
- if (pMgmt->bInTIMWake)
- return false;
- }
-
- /* check scan state */
- if (pDevice->bCmdRunning)
- return false;
-
- /* Tx Burst */
- if (pDevice->bPSModeTxBurst)
- return false;
-
- /* Froce PSEN on */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
-
- if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
- if (bCheckCountToWakeUp && (pMgmt->wCountToWakeUp == 0
- || pMgmt->wCountToWakeUp == 1)) {
- return false;
- }
- }
-
- pDevice->bPSRxBeacon = true;
-
- /* no Tx, no Rx isr, now go to Doze */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
- return true;
-}
-
-/*
- *
- * Routine Description:
- * Send PS-POLL packet
- *
- * Return Value:
- * None.
- *
- */
-
-void PSvSendPSPOLL(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_tx_mgmt *pTxPacket = NULL;
-
- memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_HDR_ADDR2_LEN);
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyPSPacketPool;
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
-
- pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) |
- WLAN_SET_FC_PWRMGT(0)
- ));
-
- pTxPacket->p80211Header->sA2.wDurationID =
- pMgmt->wCurrAID | BIT14 | BIT15;
- memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID,
- WLAN_ADDR_LEN);
- memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr,
- WLAN_ADDR_LEN);
- pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN;
- pTxPacket->cbPayloadLen = 0;
-
- /* log failure if sending failed */
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Send PS-Poll packet failed..\n");
-}
-
-/*
- *
- * Routine Description:
- * Send NULL packet to AP for notification power state of STA
- *
- * Return Value:
- * None.
- *
- */
-
-int PSbSendNullPacket(struct vnt_private *pDevice)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u16 flags = 0;
-
- if (pDevice->bLinkPass == false)
- return false;
-
- if (pDevice->bEnablePSMode == false && pDevice->tx_trigger == false)
- return false;
-
- memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_NULLDATA_FR_MAXLEN);
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyPSPacketPool;
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
-
- flags = WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL);
-
- if (pDevice->bEnablePSMode)
- flags |= WLAN_SET_FC_PWRMGT(1);
- else
- flags |= WLAN_SET_FC_PWRMGT(0);
-
- pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(flags);
-
- if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA)
- pTxPacket->p80211Header->sA3.wFrameCtl |=
- cpu_to_le16((u16)WLAN_SET_FC_TODS(1));
-
- memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID,
- WLAN_ADDR_LEN);
- memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr,
- WLAN_ADDR_LEN);
- memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID,
- WLAN_BSSID_LEN);
- pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN;
- pTxPacket->cbPayloadLen = 0;
- /* log error if sending failed */
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "Send Null Packet failed !\n");
- return false;
- }
- return true;
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_ALBCN);
}
/*
@@ -312,27 +128,17 @@ int PSbSendNullPacket(struct vnt_private *pDevice)
*
*/
-int PSbIsNextTBTTWakeUp(struct vnt_private *pDevice)
+int vnt_next_tbtt_wakeup(struct vnt_private *priv)
{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int bWakeUp = false;
-
- if (pMgmt->wListenInterval >= 2) {
- if (pMgmt->wCountToWakeUp == 0)
- pMgmt->wCountToWakeUp = pMgmt->wListenInterval;
-
- pMgmt->wCountToWakeUp--;
-
- if (pMgmt->wCountToWakeUp == 1) {
- /* Turn on wake up to listen next beacon */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
- pDevice->bPSRxBeacon = false;
- bWakeUp = true;
- } else if (!pDevice->bPSRxBeacon) {
- /* Listen until RxBeacon */
- MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
- }
+ struct ieee80211_hw *hw = priv->hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ int wake_up = false;
+
+ if (conf->listen_interval == 1) {
+ /* Turn on wake up to listen next beacon */
+ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN);
+ wake_up = true;
}
- return bWakeUp;
-}
+ return wake_up;
+}
diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h
index 778358239437..7696b714850c 100644
--- a/drivers/staging/vt6656/power.h
+++ b/drivers/staging/vt6656/power.h
@@ -29,19 +29,10 @@
#ifndef __POWER_H__
#define __POWER_H__
-#define C_PWBT 1000 // micro sec. power up before TBTT
-#define PS_FAST_INTERVAL 1 // Fast power saving listen interval
-#define PS_MAX_INTERVAL 4 // MAX power saving listen interval
+#define C_PWBT 1000 /* micro sec. power up before TBTT */
-/* PSDevice pDevice */
-/* PSDevice hDeviceContext */
-
-int PSbConsiderPowerDown(struct vnt_private *, int bCheckRxDMA,
- int bCheckCountToWakeUp);
-void PSvDisablePowerSaving(struct vnt_private *);
-void PSvEnablePowerSaving(struct vnt_private *, u16 wListenInterval);
-void PSvSendPSPOLL(struct vnt_private *);
-int PSbSendNullPacket(struct vnt_private *);
-int PSbIsNextTBTTWakeUp(struct vnt_private *);
+void vnt_disable_power_saving(struct vnt_private *);
+void vnt_enable_power_saving(struct vnt_private *, u16);
+int vnt_next_tbtt_wakeup(struct vnt_private *);
#endif /* __POWER_H__ */
diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c
deleted file mode 100644
index 2fd836f07536..000000000000
--- a/drivers/staging/vt6656/rc4.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: rc4.c
- *
- * Purpose:
- *
- * Functions:
- *
- * Revision History:
- *
- * Author: Kyle Hsu
- *
- * Date: Sep 4, 2002
- *
- */
-
-#include "rc4.h"
-
-void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len)
-{
- unsigned int ust1, ust2;
- unsigned int keyindex;
- unsigned int stateindex;
- u8 * pbyst;
- unsigned int idx;
-
- pbyst = pRC4->abystate;
- pRC4->ux = 0;
- pRC4->uy = 0;
- for (idx = 0; idx < 256; idx++)
- pbyst[idx] = (u8)idx;
- keyindex = 0;
- stateindex = 0;
- for (idx = 0; idx < 256; idx++) {
- ust1 = pbyst[idx];
- stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff;
- ust2 = pbyst[stateindex];
- pbyst[stateindex] = (u8)ust1;
- pbyst[idx] = (u8)ust2;
- if (++keyindex >= cbKey_len)
- keyindex = 0;
- }
-}
-
-unsigned int rc4_byte(PRC4Ext pRC4)
-{
- unsigned int ux;
- unsigned int uy;
- unsigned int ustx, usty;
- u8 * pbyst;
-
- pbyst = pRC4->abystate;
- ux = (pRC4->ux + 1) & 0xff;
- ustx = pbyst[ux];
- uy = (ustx + pRC4->uy) & 0xff;
- usty = pbyst[uy];
- pRC4->ux = ux;
- pRC4->uy = uy;
- pbyst[uy] = (u8)ustx;
- pbyst[ux] = (u8)usty;
-
- return pbyst[(ustx + usty) & 0xff];
-}
-
-void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest,
- u8 * pbySrc, unsigned int cbData_len)
-{
- unsigned int ii;
- for (ii = 0; ii < cbData_len; ii++)
- pbyDest[ii] = (u8)(pbySrc[ii] ^ rc4_byte(pRC4));
-}
diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h
deleted file mode 100644
index d376e1adcc1c..000000000000
--- a/drivers/staging/vt6656/rc4.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * File: rc4.h
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Purpose:
- *
- * Functions:
- *
- * Revision History:
- *
- * Author: Kyle Hsu
- *
- * Date: Sep 4, 2002
- *
- */
-
-#ifndef __RC4_H__
-#define __RC4_H__
-
-#include <linux/types.h>
-
-typedef struct {
- unsigned int ux;
- unsigned int uy;
- u8 abystate[256];
-} RC4Ext, *PRC4Ext;
-
-void rc4_init(PRC4Ext pRC4, u8 * pbyKey, unsigned int cbKey_len);
-unsigned int rc4_byte(PRC4Ext pRC4);
-void rc4_encrypt(PRC4Ext pRC4, u8 * pbyDest, u8 * pbySrc,
- unsigned int cbData_len);
-
-#endif /* __RC4_H__ */
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
index 3f54ae3cfb4e..c0edcae55e30 100644
--- a/drivers/staging/vt6656/rf.c
+++ b/drivers/staging/vt6656/rf.c
@@ -39,675 +39,576 @@
#include "rf.h"
#include "baseband.h"
#include "usbpipe.h"
-#include "datarate.h"
-#define BY_AL2230_REG_LEN 23 //24bit
#define CB_AL2230_INIT_SEQ 15
#define AL2230_PWR_IDX_LEN 64
-#define BY_AL7230_REG_LEN 23 //24bit
#define CB_AL7230_INIT_SEQ 16
#define AL7230_PWR_IDX_LEN 64
-//{{RobertYu:20051111
-#define BY_VT3226_REG_LEN 23
#define CB_VT3226_INIT_SEQ 11
#define VT3226_PWR_IDX_LEN 64
-//}}
-//{{RobertYu:20060609
-#define BY_VT3342_REG_LEN 23
#define CB_VT3342_INIT_SEQ 13
#define VT3342_PWR_IDX_LEN 64
-//}}
static u8 al2230_init_table[CB_AL2230_INIT_SEQ][3] = {
- {0x03, 0xF7, 0x90},
- {0x03, 0x33, 0x31},
- {0x01, 0xB8, 0x02},
- {0x00, 0xFF, 0xF3},
- {0x00, 0x05, 0xA4},
- {0x0F, 0x4D, 0xC5}, //RobertYu:20060814
- {0x08, 0x05, 0xB6},
- {0x01, 0x47, 0xC7},
- {0x00, 0x06, 0x88},
- {0x04, 0x03, 0xB9},
- {0x00, 0xDB, 0xBA},
- {0x00, 0x09, 0x9B},
- {0x0B, 0xDF, 0xFC},
- {0x00, 0x00, 0x0D},
- {0x00, 0x58, 0x0F}
- };
+ {0x03, 0xf7, 0x90},
+ {0x03, 0x33, 0x31},
+ {0x01, 0xb8, 0x02},
+ {0x00, 0xff, 0xf3},
+ {0x00, 0x05, 0xa4},
+ {0x0f, 0x4d, 0xc5},
+ {0x08, 0x05, 0xb6},
+ {0x01, 0x47, 0xc7},
+ {0x00, 0x06, 0x88},
+ {0x04, 0x03, 0xb9},
+ {0x00, 0xdb, 0xba},
+ {0x00, 0x09, 0x9b},
+ {0x0b, 0xdf, 0xfc},
+ {0x00, 0x00, 0x0d},
+ {0x00, 0x58, 0x0f}
+};
static u8 al2230_channel_table0[CB_MAX_CHANNEL_24G][3] = {
- {0x03, 0xF7, 0x90}, // channel = 1, Tf = 2412MHz
- {0x03, 0xF7, 0x90}, // channel = 2, Tf = 2417MHz
- {0x03, 0xE7, 0x90}, // channel = 3, Tf = 2422MHz
- {0x03, 0xE7, 0x90}, // channel = 4, Tf = 2427MHz
- {0x03, 0xF7, 0xA0}, // channel = 5, Tf = 2432MHz
- {0x03, 0xF7, 0xA0}, // channel = 6, Tf = 2437MHz
- {0x03, 0xE7, 0xA0}, // channel = 7, Tf = 2442MHz
- {0x03, 0xE7, 0xA0}, // channel = 8, Tf = 2447MHz
- {0x03, 0xF7, 0xB0}, // channel = 9, Tf = 2452MHz
- {0x03, 0xF7, 0xB0}, // channel = 10, Tf = 2457MHz
- {0x03, 0xE7, 0xB0}, // channel = 11, Tf = 2462MHz
- {0x03, 0xE7, 0xB0}, // channel = 12, Tf = 2467MHz
- {0x03, 0xF7, 0xC0}, // channel = 13, Tf = 2472MHz
- {0x03, 0xE7, 0xC0} // channel = 14, Tf = 2412M
- };
+ {0x03, 0xf7, 0x90},
+ {0x03, 0xf7, 0x90},
+ {0x03, 0xe7, 0x90},
+ {0x03, 0xe7, 0x90},
+ {0x03, 0xf7, 0xa0},
+ {0x03, 0xf7, 0xa0},
+ {0x03, 0xe7, 0xa0},
+ {0x03, 0xe7, 0xa0},
+ {0x03, 0xf7, 0xb0},
+ {0x03, 0xf7, 0xb0},
+ {0x03, 0xe7, 0xb0},
+ {0x03, 0xe7, 0xb0},
+ {0x03, 0xf7, 0xc0},
+ {0x03, 0xe7, 0xc0}
+};
static u8 al2230_channel_table1[CB_MAX_CHANNEL_24G][3] = {
- {0x03, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
- {0x0B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
- {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
- {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
- {0x03, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
- {0x0B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
- {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
- {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
- {0x03, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
- {0x0B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
- {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
- {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
- {0x03, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
- {0x06, 0x66, 0x61} // channel = 14, Tf = 2412M
- };
-
-// 40MHz reference frequency
-// Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x06, 0x66, 0x61}
+};
+
static u8 al7230_init_table[CB_AL7230_INIT_SEQ][3] = {
- {0x20, 0x37, 0x90}, // Channel1 // Need modify for 11a
- {0x13, 0x33, 0x31}, // Channel1 // Need modify for 11a
- {0x84, 0x1F, 0xF2}, // Need modify for 11a: 451FE2
- {0x3F, 0xDF, 0xA3}, // Need modify for 11a: 5FDFA3
- {0x7F, 0xD7, 0x84}, // 11b/g // Need modify for 11a
- //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45
- // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
- {0x80, 0x2B, 0x55}, // Need modify for 11a: 8D1B55
- {0x56, 0xAF, 0x36},
- {0xCE, 0x02, 0x07}, // Need modify for 11a: 860207
- {0x6E, 0xBC, 0x98},
- {0x22, 0x1B, 0xB9},
- {0xE0, 0x00, 0x0A}, // Need modify for 11a: E0600A
- {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
- //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C
- // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
- {0x00, 0x0A, 0x3C}, // Need modify for 11a: 00143C
- {0xFF, 0xFF, 0xFD},
- {0x00, 0x00, 0x0E},
- {0x1A, 0xBA, 0x8F} // Need modify for 11a: 12BACF
- };
+ {0x20, 0x37, 0x90},
+ {0x13, 0x33, 0x31},
+ {0x84, 0x1f, 0xf2},
+ {0x3f, 0xdf, 0xa3},
+ {0x7f, 0xd7, 0x84},
+ {0x80, 0x2b, 0x55},
+ {0x56, 0xaf, 0x36},
+ {0xce, 0x02, 0x07},
+ {0x6e, 0xbc, 0x98},
+ {0x22, 0x1b, 0xb9},
+ {0xe0, 0x00, 0x0a},
+ {0x08, 0x03, 0x1b},
+ {0x00, 0x0a, 0x3c},
+ {0xff, 0xff, 0xfd},
+ {0x00, 0x00, 0x0e},
+ {0x1a, 0xba, 0x8f}
+};
static u8 al7230_init_table_amode[CB_AL7230_INIT_SEQ][3] = {
- {0x2F, 0xF5, 0x20}, // Channel184 // Need modify for 11b/g
- {0x00, 0x00, 0x01}, // Channel184 // Need modify for 11b/g
- {0x45, 0x1F, 0xE2}, // Need modify for 11b/g
- {0x5F, 0xDF, 0xA3}, // Need modify for 11b/g
- {0x6F, 0xD7, 0x84}, // 11a // Need modify for 11b/g
- {0x85, 0x3F, 0x55}, // Need modify for 11b/g, RoberYu:20050113
- {0x56, 0xAF, 0x36},
- {0xCE, 0x02, 0x07}, // Need modify for 11b/g
- {0x6E, 0xBC, 0x98},
- {0x22, 0x1B, 0xB9},
- {0xE0, 0x60, 0x0A}, // Need modify for 11b/g
- {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
- {0x00, 0x14, 0x7C}, // Need modify for 11b/g
- {0xFF, 0xFF, 0xFD},
- {0x00, 0x00, 0x0E},
- {0x12, 0xBA, 0xCF} // Need modify for 11b/g
- };
+ {0x2f, 0xf5, 0x20},
+ {0x00, 0x00, 0x01},
+ {0x45, 0x1f, 0xe2},
+ {0x5f, 0xdf, 0xa3},
+ {0x6f, 0xd7, 0x84},
+ {0x85, 0x3f, 0x55},
+ {0x56, 0xaf, 0x36},
+ {0xce, 0x02, 0x07},
+ {0x6e, 0xbc, 0x98},
+ {0x22, 0x1b, 0xb9},
+ {0xe0, 0x60, 0x0a},
+ {0x08, 0x03, 0x1b},
+ {0x00, 0x14, 0x7c},
+ {0xff, 0xff, 0xfd},
+ {0x00, 0x00, 0x0e},
+ {0x12, 0xba, 0xcf}
+};
static u8 al7230_channel_table0[CB_MAX_CHANNEL][3] = {
- {0x20, 0x37, 0x90}, // channel = 1, Tf = 2412MHz
- {0x20, 0x37, 0x90}, // channel = 2, Tf = 2417MHz
- {0x20, 0x37, 0x90}, // channel = 3, Tf = 2422MHz
- {0x20, 0x37, 0x90}, // channel = 4, Tf = 2427MHz
- {0x20, 0x37, 0xA0}, // channel = 5, Tf = 2432MHz
- {0x20, 0x37, 0xA0}, // channel = 6, Tf = 2437MHz
- {0x20, 0x37, 0xA0}, // channel = 7, Tf = 2442MHz
- {0x20, 0x37, 0xA0}, // channel = 8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xB0}, // channel = 9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xB0}, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xB0}, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xB0}, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xC0}, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49
- {0x20, 0x37, 0xC0}, // channel = 14, Tf = 2484MHz
-
- // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
- {0x0F, 0xF5, 0x20}, // channel = 183, Tf = 4915MHz (15)
- {0x2F, 0xF5, 0x20}, // channel = 184, Tf = 4920MHz (16)
- {0x0F, 0xF5, 0x20}, // channel = 185, Tf = 4925MHz (17)
- {0x0F, 0xF5, 0x20}, // channel = 187, Tf = 4935MHz (18)
- {0x2F, 0xF5, 0x20}, // channel = 188, Tf = 4940MHz (19)
- {0x0F, 0xF5, 0x20}, // channel = 189, Tf = 4945MHz (20)
- {0x2F, 0xF5, 0x30}, // channel = 192, Tf = 4960MHz (21)
- {0x2F, 0xF5, 0x30}, // channel = 196, Tf = 4980MHz (22)
-
- // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
- // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
-
- {0x0F, 0xF5, 0x40}, // channel = 7, Tf = 5035MHz (23)
- {0x2F, 0xF5, 0x40}, // channel = 8, Tf = 5040MHz (24)
- {0x0F, 0xF5, 0x40}, // channel = 9, Tf = 5045MHz (25)
- {0x0F, 0xF5, 0x40}, // channel = 11, Tf = 5055MHz (26)
- {0x2F, 0xF5, 0x40}, // channel = 12, Tf = 5060MHz (27)
- {0x2F, 0xF5, 0x50}, // channel = 16, Tf = 5080MHz (28)
- {0x2F, 0xF5, 0x60}, // channel = 34, Tf = 5170MHz (29)
- {0x2F, 0xF5, 0x60}, // channel = 36, Tf = 5180MHz (30)
- {0x2F, 0xF5, 0x70}, // channel = 38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49
- {0x2F, 0xF5, 0x70}, // channel = 40, Tf = 5200MHz (32)
- {0x2F, 0xF5, 0x70}, // channel = 42, Tf = 5210MHz (33)
- {0x2F, 0xF5, 0x70}, // channel = 44, Tf = 5220MHz (34)
- {0x2F, 0xF5, 0x70}, // channel = 46, Tf = 5230MHz (35)
- {0x2F, 0xF5, 0x70}, // channel = 48, Tf = 5240MHz (36)
- {0x2F, 0xF5, 0x80}, // channel = 52, Tf = 5260MHz (37)
- {0x2F, 0xF5, 0x80}, // channel = 56, Tf = 5280MHz (38)
- {0x2F, 0xF5, 0x80}, // channel = 60, Tf = 5300MHz (39)
- {0x2F, 0xF5, 0x90}, // channel = 64, Tf = 5320MHz (40)
-
- {0x2F, 0xF5, 0xC0}, // channel = 100, Tf = 5500MHz (41)
- {0x2F, 0xF5, 0xC0}, // channel = 104, Tf = 5520MHz (42)
- {0x2F, 0xF5, 0xC0}, // channel = 108, Tf = 5540MHz (43)
- {0x2F, 0xF5, 0xD0}, // channel = 112, Tf = 5560MHz (44)
- {0x2F, 0xF5, 0xD0}, // channel = 116, Tf = 5580MHz (45)
- {0x2F, 0xF5, 0xD0}, // channel = 120, Tf = 5600MHz (46)
- {0x2F, 0xF5, 0xE0}, // channel = 124, Tf = 5620MHz (47)
- {0x2F, 0xF5, 0xE0}, // channel = 128, Tf = 5640MHz (48)
- {0x2F, 0xF5, 0xE0}, // channel = 132, Tf = 5660MHz (49)
- {0x2F, 0xF5, 0xF0}, // channel = 136, Tf = 5680MHz (50)
- {0x2F, 0xF5, 0xF0}, // channel = 140, Tf = 5700MHz (51)
- {0x2F, 0xF6, 0x00}, // channel = 149, Tf = 5745MHz (52)
- {0x2F, 0xF6, 0x00}, // channel = 153, Tf = 5765MHz (53)
- {0x2F, 0xF6, 0x00}, // channel = 157, Tf = 5785MHz (54)
- {0x2F, 0xF6, 0x10}, // channel = 161, Tf = 5805MHz (55)
- {0x2F, 0xF6, 0x10} // channel = 165, Tf = 5825MHz (56)
- };
+ {0x20, 0x37, 0x90},
+ {0x20, 0x37, 0x90},
+ {0x20, 0x37, 0x90},
+ {0x20, 0x37, 0x90},
+ {0x20, 0x37, 0xa0},
+ {0x20, 0x37, 0xa0},
+ {0x20, 0x37, 0xa0},
+ {0x20, 0x37, 0xa0},
+ {0x20, 0x37, 0xb0},
+ {0x20, 0x37, 0xb0},
+ {0x20, 0x37, 0xb0},
+ {0x20, 0x37, 0xb0},
+ {0x20, 0x37, 0xc0},
+ {0x20, 0x37, 0xc0},
+ {0x0f, 0xf5, 0x20}, /* channel 15 Tf = 4915MHz */
+ {0x2f, 0xf5, 0x20},
+ {0x0f, 0xf5, 0x20},
+ {0x0f, 0xf5, 0x20},
+ {0x2f, 0xf5, 0x20},
+ {0x0f, 0xf5, 0x20},
+ {0x2f, 0xf5, 0x30},
+ {0x2f, 0xf5, 0x30},
+ {0x0f, 0xf5, 0x40},
+ {0x2f, 0xf5, 0x40},
+ {0x0f, 0xf5, 0x40},
+ {0x0f, 0xf5, 0x40},
+ {0x2f, 0xf5, 0x40},
+ {0x2f, 0xf5, 0x50},
+ {0x2f, 0xf5, 0x60},
+ {0x2f, 0xf5, 0x60},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x70},
+ {0x2f, 0xf5, 0x80},
+ {0x2f, 0xf5, 0x80},
+ {0x2f, 0xf5, 0x80},
+ {0x2f, 0xf5, 0x90},
+ {0x2f, 0xf5, 0xc0},
+ {0x2f, 0xf5, 0xc0},
+ {0x2f, 0xf5, 0xc0},
+ {0x2f, 0xf5, 0xd0},
+ {0x2f, 0xf5, 0xd0},
+ {0x2f, 0xf5, 0xd0},
+ {0x2f, 0xf5, 0xe0},
+ {0x2f, 0xf5, 0xe0},
+ {0x2f, 0xf5, 0xe0},
+ {0x2f, 0xf5, 0xf0},
+ {0x2f, 0xf5, 0xf0},
+ {0x2f, 0xf6, 0x00},
+ {0x2f, 0xf6, 0x00},
+ {0x2f, 0xf6, 0x00},
+ {0x2f, 0xf6, 0x10},
+ {0x2f, 0xf6, 0x10}
+};
static u8 al7230_channel_table1[CB_MAX_CHANNEL][3] = {
- {0x13, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
- {0x1B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
- {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
- {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
- {0x13, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
- {0x1B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
- {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
- {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
- {0x13, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
- {0x1B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
- {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
- {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
- {0x13, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
- {0x06, 0x66, 0x61}, // channel = 14, Tf = 2484MHz
-
- // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
- {0x1D, 0x55, 0x51}, // channel = 183, Tf = 4915MHz (15)
- {0x00, 0x00, 0x01}, // channel = 184, Tf = 4920MHz (16)
- {0x02, 0xAA, 0xA1}, // channel = 185, Tf = 4925MHz (17)
- {0x08, 0x00, 0x01}, // channel = 187, Tf = 4935MHz (18)
- {0x0A, 0xAA, 0xA1}, // channel = 188, Tf = 4940MHz (19)
- {0x0D, 0x55, 0x51}, // channel = 189, Tf = 4945MHz (20)
- {0x15, 0x55, 0x51}, // channel = 192, Tf = 4960MHz (21)
- {0x00, 0x00, 0x01}, // channel = 196, Tf = 4980MHz (22)
-
- // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
- // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- {0x1D, 0x55, 0x51}, // channel = 7, Tf = 5035MHz (23)
- {0x00, 0x00, 0x01}, // channel = 8, Tf = 5040MHz (24)
- {0x02, 0xAA, 0xA1}, // channel = 9, Tf = 5045MHz (25)
- {0x08, 0x00, 0x01}, // channel = 11, Tf = 5055MHz (26)
- {0x0A, 0xAA, 0xA1}, // channel = 12, Tf = 5060MHz (27)
- {0x15, 0x55, 0x51}, // channel = 16, Tf = 5080MHz (28)
- {0x05, 0x55, 0x51}, // channel = 34, Tf = 5170MHz (29)
- {0x0A, 0xAA, 0xA1}, // channel = 36, Tf = 5180MHz (30)
- {0x10, 0x00, 0x01}, // channel = 38, Tf = 5190MHz (31)
- {0x15, 0x55, 0x51}, // channel = 40, Tf = 5200MHz (32)
- {0x1A, 0xAA, 0xA1}, // channel = 42, Tf = 5210MHz (33)
- {0x00, 0x00, 0x01}, // channel = 44, Tf = 5220MHz (34)
- {0x05, 0x55, 0x51}, // channel = 46, Tf = 5230MHz (35)
- {0x0A, 0xAA, 0xA1}, // channel = 48, Tf = 5240MHz (36)
- {0x15, 0x55, 0x51}, // channel = 52, Tf = 5260MHz (37)
- {0x00, 0x00, 0x01}, // channel = 56, Tf = 5280MHz (38)
- {0x0A, 0xAA, 0xA1}, // channel = 60, Tf = 5300MHz (39)
- {0x15, 0x55, 0x51}, // channel = 64, Tf = 5320MHz (40)
- {0x15, 0x55, 0x51}, // channel = 100, Tf = 5500MHz (41)
- {0x00, 0x00, 0x01}, // channel = 104, Tf = 5520MHz (42)
- {0x0A, 0xAA, 0xA1}, // channel = 108, Tf = 5540MHz (43)
- {0x15, 0x55, 0x51}, // channel = 112, Tf = 5560MHz (44)
- {0x00, 0x00, 0x01}, // channel = 116, Tf = 5580MHz (45)
- {0x0A, 0xAA, 0xA1}, // channel = 120, Tf = 5600MHz (46)
- {0x15, 0x55, 0x51}, // channel = 124, Tf = 5620MHz (47)
- {0x00, 0x00, 0x01}, // channel = 128, Tf = 5640MHz (48)
- {0x0A, 0xAA, 0xA1}, // channel = 132, Tf = 5660MHz (49)
- {0x15, 0x55, 0x51}, // channel = 136, Tf = 5680MHz (50)
- {0x00, 0x00, 0x01}, // channel = 140, Tf = 5700MHz (51)
- {0x18, 0x00, 0x01}, // channel = 149, Tf = 5745MHz (52)
- {0x02, 0xAA, 0xA1}, // channel = 153, Tf = 5765MHz (53)
- {0x0D, 0x55, 0x51}, // channel = 157, Tf = 5785MHz (54)
- {0x18, 0x00, 0x01}, // channel = 161, Tf = 5805MHz (55)
- {0x02, 0xAA, 0xB1} // channel = 165, Tf = 5825MHz (56)
- };
+ {0x13, 0x33, 0x31},
+ {0x1b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x13, 0x33, 0x31},
+ {0x1b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x13, 0x33, 0x31},
+ {0x1b, 0x33, 0x31},
+ {0x03, 0x33, 0x31},
+ {0x0b, 0x33, 0x31},
+ {0x13, 0x33, 0x31},
+ {0x06, 0x66, 0x61},
+ {0x1d, 0x55, 0x51}, /* channel = 15, Tf = 4915MHz */
+ {0x00, 0x00, 0x01},
+ {0x02, 0xaa, 0xa1},
+ {0x08, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x0d, 0x55, 0x51},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x1d, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x02, 0xaa, 0xa1},
+ {0x08, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x05, 0x55, 0x51},
+ {0x0a, 0xaa, 0xa1},
+ {0x10, 0x00, 0x01},
+ {0x15, 0x55, 0x51},
+ {0x1a, 0xaa, 0xa1},
+ {0x00, 0x00, 0x01},
+ {0x05, 0x55, 0x51},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x0a, 0xaa, 0xa1},
+ {0x15, 0x55, 0x51},
+ {0x00, 0x00, 0x01},
+ {0x18, 0x00, 0x01},
+ {0x02, 0xaa, 0xa1},
+ {0x0d, 0x55, 0x51},
+ {0x18, 0x00, 0x01},
+ {0x02, 0xaa, 0xb1}
+};
static u8 al7230_channel_table2[CB_MAX_CHANNEL][3] = {
- {0x7F, 0xD7, 0x84}, // channel = 1, Tf = 2412MHz
- {0x7F, 0xD7, 0x84}, // channel = 2, Tf = 2417MHz
- {0x7F, 0xD7, 0x84}, // channel = 3, Tf = 2422MHz
- {0x7F, 0xD7, 0x84}, // channel = 4, Tf = 2427MHz
- {0x7F, 0xD7, 0x84}, // channel = 5, Tf = 2432MHz
- {0x7F, 0xD7, 0x84}, // channel = 6, Tf = 2437MHz
- {0x7F, 0xD7, 0x84}, // channel = 7, Tf = 2442MHz
- {0x7F, 0xD7, 0x84}, // channel = 8, Tf = 2447MHz
- {0x7F, 0xD7, 0x84}, // channel = 9, Tf = 2452MHz
- {0x7F, 0xD7, 0x84}, // channel = 10, Tf = 2457MHz
- {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 2462MHz
- {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 2467MHz
- {0x7F, 0xD7, 0x84}, // channel = 13, Tf = 2472MHz
- {0x7F, 0xD7, 0x84}, // channel = 14, Tf = 2484MHz
-
- // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
- {0x7F, 0xD7, 0x84}, // channel = 183, Tf = 4915MHz (15)
- {0x6F, 0xD7, 0x84}, // channel = 184, Tf = 4920MHz (16)
- {0x7F, 0xD7, 0x84}, // channel = 185, Tf = 4925MHz (17)
- {0x7F, 0xD7, 0x84}, // channel = 187, Tf = 4935MHz (18)
- {0x7F, 0xD7, 0x84}, // channel = 188, Tf = 4940MHz (19)
- {0x7F, 0xD7, 0x84}, // channel = 189, Tf = 4945MHz (20)
- {0x7F, 0xD7, 0x84}, // channel = 192, Tf = 4960MHz (21)
- {0x6F, 0xD7, 0x84}, // channel = 196, Tf = 4980MHz (22)
-
- // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
- // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- {0x7F, 0xD7, 0x84}, // channel = 7, Tf = 5035MHz (23)
- {0x6F, 0xD7, 0x84}, // channel = 8, Tf = 5040MHz (24)
- {0x7F, 0xD7, 0x84}, // channel = 9, Tf = 5045MHz (25)
- {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 5055MHz (26)
- {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 5060MHz (27)
- {0x7F, 0xD7, 0x84}, // channel = 16, Tf = 5080MHz (28)
- {0x7F, 0xD7, 0x84}, // channel = 34, Tf = 5170MHz (29)
- {0x7F, 0xD7, 0x84}, // channel = 36, Tf = 5180MHz (30)
- {0x7F, 0xD7, 0x84}, // channel = 38, Tf = 5190MHz (31)
- {0x7F, 0xD7, 0x84}, // channel = 40, Tf = 5200MHz (32)
- {0x7F, 0xD7, 0x84}, // channel = 42, Tf = 5210MHz (33)
- {0x6F, 0xD7, 0x84}, // channel = 44, Tf = 5220MHz (34)
- {0x7F, 0xD7, 0x84}, // channel = 46, Tf = 5230MHz (35)
- {0x7F, 0xD7, 0x84}, // channel = 48, Tf = 5240MHz (36)
- {0x7F, 0xD7, 0x84}, // channel = 52, Tf = 5260MHz (37)
- {0x6F, 0xD7, 0x84}, // channel = 56, Tf = 5280MHz (38)
- {0x7F, 0xD7, 0x84}, // channel = 60, Tf = 5300MHz (39)
- {0x7F, 0xD7, 0x84}, // channel = 64, Tf = 5320MHz (40)
- {0x7F, 0xD7, 0x84}, // channel = 100, Tf = 5500MHz (41)
- {0x6F, 0xD7, 0x84}, // channel = 104, Tf = 5520MHz (42)
- {0x7F, 0xD7, 0x84}, // channel = 108, Tf = 5540MHz (43)
- {0x7F, 0xD7, 0x84}, // channel = 112, Tf = 5560MHz (44)
- {0x6F, 0xD7, 0x84}, // channel = 116, Tf = 5580MHz (45)
- {0x7F, 0xD7, 0x84}, // channel = 120, Tf = 5600MHz (46)
- {0x7F, 0xD7, 0x84}, // channel = 124, Tf = 5620MHz (47)
- {0x6F, 0xD7, 0x84}, // channel = 128, Tf = 5640MHz (48)
- {0x7F, 0xD7, 0x84}, // channel = 132, Tf = 5660MHz (49)
- {0x7F, 0xD7, 0x84}, // channel = 136, Tf = 5680MHz (50)
- {0x6F, 0xD7, 0x84}, // channel = 140, Tf = 5700MHz (51)
- {0x7F, 0xD7, 0x84}, // channel = 149, Tf = 5745MHz (52)
- {0x7F, 0xD7, 0x84}, // channel = 153, Tf = 5765MHz (53)
- {0x7F, 0xD7, 0x84}, // channel = 157, Tf = 5785MHz (54)
- {0x7F, 0xD7, 0x84}, // channel = 161, Tf = 5805MHz (55)
- {0x7F, 0xD7, 0x84} // channel = 165, Tf = 5825MHz (56)
- };
-
-///{{RobertYu:20051111
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84}, /* channel = 15 Tf = 4915MHz */
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x6f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84},
+ {0x7f, 0xd7, 0x84}
+};
+
static u8 vt3226_init_table[CB_VT3226_INIT_SEQ][3] = {
- {0x03, 0xFF, 0x80},
- {0x02, 0x82, 0xA1},
- {0x03, 0xC6, 0xA2},
- {0x01, 0x97, 0x93},
- {0x03, 0x66, 0x64},
- {0x00, 0x61, 0xA5},
- {0x01, 0x7B, 0xD6},
- {0x00, 0x80, 0x17},
- {0x03, 0xF8, 0x08},
- {0x00, 0x02, 0x39}, //RobertYu:20051116
- {0x02, 0x00, 0x2A}
- };
+ {0x03, 0xff, 0x80},
+ {0x02, 0x82, 0xa1},
+ {0x03, 0xc6, 0xa2},
+ {0x01, 0x97, 0x93},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x61, 0xa5},
+ {0x01, 0x7b, 0xd6},
+ {0x00, 0x80, 0x17},
+ {0x03, 0xf8, 0x08},
+ {0x00, 0x02, 0x39},
+ {0x02, 0x00, 0x2a}
+};
static u8 vt3226d0_init_table[CB_VT3226_INIT_SEQ][3] = {
- {0x03, 0xFF, 0x80},
- {0x03, 0x02, 0x21}, //RobertYu:20060327
- {0x03, 0xC6, 0xA2},
- {0x01, 0x97, 0x93},
- {0x03, 0x66, 0x64},
- {0x00, 0x71, 0xA5}, //RobertYu:20060103
- {0x01, 0x15, 0xC6}, //RobertYu:20060420
- {0x01, 0x2E, 0x07}, //RobertYu:20060420
- {0x00, 0x58, 0x08}, //RobertYu:20060111
- {0x00, 0x02, 0x79}, //RobertYu:20060420
- {0x02, 0x01, 0xAA} //RobertYu:20060523
- };
+ {0x03, 0xff, 0x80},
+ {0x03, 0x02, 0x21},
+ {0x03, 0xc6, 0xa2},
+ {0x01, 0x97, 0x93},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x71, 0xa5},
+ {0x01, 0x15, 0xc6},
+ {0x01, 0x2e, 0x07},
+ {0x00, 0x58, 0x08},
+ {0x00, 0x02, 0x79},
+ {0x02, 0x01, 0xaa}
+};
static u8 vt3226_channel_table0[CB_MAX_CHANNEL_24G][3] = {
- {0x01, 0x97, 0x83}, // channel = 1, Tf = 2412MHz
- {0x01, 0x97, 0x83}, // channel = 2, Tf = 2417MHz
- {0x01, 0x97, 0x93}, // channel = 3, Tf = 2422MHz
- {0x01, 0x97, 0x93}, // channel = 4, Tf = 2427MHz
- {0x01, 0x97, 0x93}, // channel = 5, Tf = 2432MHz
- {0x01, 0x97, 0x93}, // channel = 6, Tf = 2437MHz
- {0x01, 0x97, 0xA3}, // channel = 7, Tf = 2442MHz
- {0x01, 0x97, 0xA3}, // channel = 8, Tf = 2447MHz
- {0x01, 0x97, 0xA3}, // channel = 9, Tf = 2452MHz
- {0x01, 0x97, 0xA3}, // channel = 10, Tf = 2457MHz
- {0x01, 0x97, 0xB3}, // channel = 11, Tf = 2462MHz
- {0x01, 0x97, 0xB3}, // channel = 12, Tf = 2467MHz
- {0x01, 0x97, 0xB3}, // channel = 13, Tf = 2472MHz
- {0x03, 0x37, 0xC3} // channel = 14, Tf = 2484MHz
- };
+ {0x01, 0x97, 0x83},
+ {0x01, 0x97, 0x83},
+ {0x01, 0x97, 0x93},
+ {0x01, 0x97, 0x93},
+ {0x01, 0x97, 0x93},
+ {0x01, 0x97, 0x93},
+ {0x01, 0x97, 0xa3},
+ {0x01, 0x97, 0xa3},
+ {0x01, 0x97, 0xa3},
+ {0x01, 0x97, 0xa3},
+ {0x01, 0x97, 0xb3},
+ {0x01, 0x97, 0xb3},
+ {0x01, 0x97, 0xb3},
+ {0x03, 0x37, 0xc3}
+};
static u8 vt3226_channel_table1[CB_MAX_CHANNEL_24G][3] = {
- {0x02, 0x66, 0x64}, // channel = 1, Tf = 2412MHz
- {0x03, 0x66, 0x64}, // channel = 2, Tf = 2417MHz
- {0x00, 0x66, 0x64}, // channel = 3, Tf = 2422MHz
- {0x01, 0x66, 0x64}, // channel = 4, Tf = 2427MHz
- {0x02, 0x66, 0x64}, // channel = 5, Tf = 2432MHz
- {0x03, 0x66, 0x64}, // channel = 6, Tf = 2437MHz
- {0x00, 0x66, 0x64}, // channel = 7, Tf = 2442MHz
- {0x01, 0x66, 0x64}, // channel = 8, Tf = 2447MHz
- {0x02, 0x66, 0x64}, // channel = 9, Tf = 2452MHz
- {0x03, 0x66, 0x64}, // channel = 10, Tf = 2457MHz
- {0x00, 0x66, 0x64}, // channel = 11, Tf = 2462MHz
- {0x01, 0x66, 0x64}, // channel = 12, Tf = 2467MHz
- {0x02, 0x66, 0x64}, // channel = 13, Tf = 2472MHz
- {0x00, 0xCC, 0xC4} // channel = 14, Tf = 2484MHz
- };
-///}}RobertYu
-
-//{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode
+ {0x02, 0x66, 0x64},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x66, 0x64},
+ {0x01, 0x66, 0x64},
+ {0x02, 0x66, 0x64},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x66, 0x64},
+ {0x01, 0x66, 0x64},
+ {0x02, 0x66, 0x64},
+ {0x03, 0x66, 0x64},
+ {0x00, 0x66, 0x64},
+ {0x01, 0x66, 0x64},
+ {0x02, 0x66, 0x64},
+ {0x00, 0xcc, 0xc4}
+};
+
static const u32 vt3226d0_lo_current_table[CB_MAX_CHANNEL_24G] = {
- 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
- 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
- 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
- 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
- 0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
- 0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
- 0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW // channel = 14, Tf = 2484MHz
+ 0x0135c600,
+ 0x0135c600,
+ 0x0235c600,
+ 0x0235c600,
+ 0x0235c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0335c600,
+ 0x0135c600
};
-//}}
-//{{RobertYu:20060609
static u8 vt3342a0_init_table[CB_VT3342_INIT_SEQ][3] = { /* 11b/g mode */
- {0x03, 0xFF, 0x80}, //update for mode//
- {0x02, 0x08, 0x81},
- {0x00, 0xC6, 0x02},
- {0x03, 0xC5, 0x13}, // channel6
- {0x00, 0xEE, 0xE4}, // channel6
- {0x00, 0x71, 0xA5},
- {0x01, 0x75, 0x46},
- {0x01, 0x40, 0x27},
- {0x01, 0x54, 0x08},
- {0x00, 0x01, 0x69},
- {0x02, 0x00, 0xAA},
- {0x00, 0x08, 0xCB},
- {0x01, 0x70, 0x0C}
- };
-
- //11b/g mode: 0x03, 0xFF, 0x80,
- //11a mode: 0x03, 0xFF, 0xC0,
-
- // channel44, 5220MHz 0x00C402
- // channel56, 5280MHz 0x00C402 for disable Frac
- // other channels 0x00C602
+ {0x03, 0xff, 0x80},
+ {0x02, 0x08, 0x81},
+ {0x00, 0xc6, 0x02},
+ {0x03, 0xc5, 0x13},
+ {0x00, 0xee, 0xe4},
+ {0x00, 0x71, 0xa5},
+ {0x01, 0x75, 0x46},
+ {0x01, 0x40, 0x27},
+ {0x01, 0x54, 0x08},
+ {0x00, 0x01, 0x69},
+ {0x02, 0x00, 0xaa},
+ {0x00, 0x08, 0xcb},
+ {0x01, 0x70, 0x0c}
+};
static u8 vt3342_channel_table0[CB_MAX_CHANNEL][3] = {
- {0x02, 0x05, 0x03}, // channel = 1, Tf = 2412MHz
- {0x01, 0x15, 0x03}, // channel = 2, Tf = 2417MHz
- {0x03, 0xC5, 0x03}, // channel = 3, Tf = 2422MHz
- {0x02, 0x65, 0x03}, // channel = 4, Tf = 2427MHz
- {0x01, 0x15, 0x13}, // channel = 5, Tf = 2432MHz
- {0x03, 0xC5, 0x13}, // channel = 6, Tf = 2437MHz
- {0x02, 0x05, 0x13}, // channel = 7, Tf = 2442MHz
- {0x01, 0x15, 0x13}, // channel = 8, Tf = 2447MHz
- {0x03, 0xC5, 0x13}, // channel = 9, Tf = 2452MHz
- {0x02, 0x65, 0x13}, // channel = 10, Tf = 2457MHz
- {0x01, 0x15, 0x23}, // channel = 11, Tf = 2462MHz
- {0x03, 0xC5, 0x23}, // channel = 12, Tf = 2467MHz
- {0x02, 0x05, 0x23}, // channel = 13, Tf = 2472MHz
- {0x00, 0xD5, 0x23}, // channel = 14, Tf = 2484MHz
-
- // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
- {0x01, 0x15, 0x13}, // channel = 183, Tf = 4915MHz (15), TBD
- {0x01, 0x15, 0x13}, // channel = 184, Tf = 4920MHz (16), TBD
- {0x01, 0x15, 0x13}, // channel = 185, Tf = 4925MHz (17), TBD
- {0x01, 0x15, 0x13}, // channel = 187, Tf = 4935MHz (18), TBD
- {0x01, 0x15, 0x13}, // channel = 188, Tf = 4940MHz (19), TBD
- {0x01, 0x15, 0x13}, // channel = 189, Tf = 4945MHz (20), TBD
- {0x01, 0x15, 0x13}, // channel = 192, Tf = 4960MHz (21), TBD
- {0x01, 0x15, 0x13}, // channel = 196, Tf = 4980MHz (22), TBD
-
- // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
- // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- {0x01, 0x15, 0x13}, // channel = 7, Tf = 5035MHz (23), TBD
- {0x01, 0x15, 0x13}, // channel = 8, Tf = 5040MHz (24), TBD
- {0x01, 0x15, 0x13}, // channel = 9, Tf = 5045MHz (25), TBD
- {0x01, 0x15, 0x13}, // channel = 11, Tf = 5055MHz (26), TBD
- {0x01, 0x15, 0x13}, // channel = 12, Tf = 5060MHz (27), TBD
- {0x01, 0x15, 0x13}, // channel = 16, Tf = 5080MHz (28), TBD
- {0x01, 0x15, 0x13}, // channel = 34, Tf = 5170MHz (29), TBD
- {0x01, 0x55, 0x63}, // channel = 36, Tf = 5180MHz (30)
- {0x01, 0x55, 0x63}, // channel = 38, Tf = 5190MHz (31), TBD
- {0x02, 0xA5, 0x63}, // channel = 40, Tf = 5200MHz (32)
- {0x02, 0xA5, 0x63}, // channel = 42, Tf = 5210MHz (33), TBD
- {0x00, 0x05, 0x73}, // channel = 44, Tf = 5220MHz (34)
- {0x00, 0x05, 0x73}, // channel = 46, Tf = 5230MHz (35), TBD
- {0x01, 0x55, 0x73}, // channel = 48, Tf = 5240MHz (36)
- {0x02, 0xA5, 0x73}, // channel = 52, Tf = 5260MHz (37)
- {0x00, 0x05, 0x83}, // channel = 56, Tf = 5280MHz (38)
- {0x01, 0x55, 0x83}, // channel = 60, Tf = 5300MHz (39)
- {0x02, 0xA5, 0x83}, // channel = 64, Tf = 5320MHz (40)
-
- {0x02, 0xA5, 0x83}, // channel = 100, Tf = 5500MHz (41), TBD
- {0x02, 0xA5, 0x83}, // channel = 104, Tf = 5520MHz (42), TBD
- {0x02, 0xA5, 0x83}, // channel = 108, Tf = 5540MHz (43), TBD
- {0x02, 0xA5, 0x83}, // channel = 112, Tf = 5560MHz (44), TBD
- {0x02, 0xA5, 0x83}, // channel = 116, Tf = 5580MHz (45), TBD
- {0x02, 0xA5, 0x83}, // channel = 120, Tf = 5600MHz (46), TBD
- {0x02, 0xA5, 0x83}, // channel = 124, Tf = 5620MHz (47), TBD
- {0x02, 0xA5, 0x83}, // channel = 128, Tf = 5640MHz (48), TBD
- {0x02, 0xA5, 0x83}, // channel = 132, Tf = 5660MHz (49), TBD
- {0x02, 0xA5, 0x83}, // channel = 136, Tf = 5680MHz (50), TBD
- {0x02, 0xA5, 0x83}, // channel = 140, Tf = 5700MHz (51), TBD
-
- {0x00, 0x05, 0xF3}, // channel = 149, Tf = 5745MHz (52)
- {0x01, 0x56, 0x03}, // channel = 153, Tf = 5765MHz (53)
- {0x02, 0xA6, 0x03}, // channel = 157, Tf = 5785MHz (54)
- {0x00, 0x06, 0x03}, // channel = 161, Tf = 5805MHz (55)
- {0x00, 0x06, 0x03} // channel = 165, Tf = 5825MHz (56), TBD
- };
+ {0x02, 0x05, 0x03},
+ {0x01, 0x15, 0x03},
+ {0x03, 0xc5, 0x03},
+ {0x02, 0x65, 0x03},
+ {0x01, 0x15, 0x13},
+ {0x03, 0xc5, 0x13},
+ {0x02, 0x05, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x03, 0xc5, 0x13},
+ {0x02, 0x65, 0x13},
+ {0x01, 0x15, 0x23},
+ {0x03, 0xc5, 0x23},
+ {0x02, 0x05, 0x23},
+ {0x00, 0xd5, 0x23},
+ {0x01, 0x15, 0x13}, /* channel = 15 Tf = 4915MHz */
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x15, 0x13},
+ {0x01, 0x55, 0x63},
+ {0x01, 0x55, 0x63},
+ {0x02, 0xa5, 0x63},
+ {0x02, 0xa5, 0x63},
+ {0x00, 0x05, 0x73},
+ {0x00, 0x05, 0x73},
+ {0x01, 0x55, 0x73},
+ {0x02, 0xa5, 0x73},
+ {0x00, 0x05, 0x83},
+ {0x01, 0x55, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x02, 0xa5, 0x83},
+ {0x00, 0x05, 0xF3},
+ {0x01, 0x56, 0x03},
+ {0x02, 0xa6, 0x03},
+ {0x00, 0x06, 0x03},
+ {0x00, 0x06, 0x03}
+};
static u8 vt3342_channel_table1[CB_MAX_CHANNEL][3] = {
- {0x01, 0x99, 0x94}, // channel = 1, Tf = 2412MHz
- {0x02, 0x44, 0x44}, // channel = 2, Tf = 2417MHz
- {0x02, 0xEE, 0xE4}, // channel = 3, Tf = 2422MHz
- {0x03, 0x99, 0x94}, // channel = 4, Tf = 2427MHz
- {0x00, 0x44, 0x44}, // channel = 5, Tf = 2432MHz
- {0x00, 0xEE, 0xE4}, // channel = 6, Tf = 2437MHz
- {0x01, 0x99, 0x94}, // channel = 7, Tf = 2442MHz
- {0x02, 0x44, 0x44}, // channel = 8, Tf = 2447MHz
- {0x02, 0xEE, 0xE4}, // channel = 9, Tf = 2452MHz
- {0x03, 0x99, 0x94}, // channel = 10, Tf = 2457MHz
- {0x00, 0x44, 0x44}, // channel = 11, Tf = 2462MHz
- {0x00, 0xEE, 0xE4}, // channel = 12, Tf = 2467MHz
- {0x01, 0x99, 0x94}, // channel = 13, Tf = 2472MHz
- {0x03, 0x33, 0x34}, // channel = 14, Tf = 2484MHz
-
- // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
- {0x00, 0x44, 0x44}, // channel = 183, Tf = 4915MHz (15), TBD
- {0x00, 0x44, 0x44}, // channel = 184, Tf = 4920MHz (16), TBD
- {0x00, 0x44, 0x44}, // channel = 185, Tf = 4925MHz (17), TBD
- {0x00, 0x44, 0x44}, // channel = 187, Tf = 4935MHz (18), TBD
- {0x00, 0x44, 0x44}, // channel = 188, Tf = 4940MHz (19), TBD
- {0x00, 0x44, 0x44}, // channel = 189, Tf = 4945MHz (20), TBD
- {0x00, 0x44, 0x44}, // channel = 192, Tf = 4960MHz (21), TBD
- {0x00, 0x44, 0x44}, // channel = 196, Tf = 4980MHz (22), TBD
-
- // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
- // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
- {0x00, 0x44, 0x44}, // channel = 7, Tf = 5035MHz (23), TBD
- {0x00, 0x44, 0x44}, // channel = 8, Tf = 5040MHz (24), TBD
- {0x00, 0x44, 0x44}, // channel = 9, Tf = 5045MHz (25), TBD
- {0x00, 0x44, 0x44}, // channel = 11, Tf = 5055MHz (26), TBD
- {0x00, 0x44, 0x44}, // channel = 12, Tf = 5060MHz (27), TBD
- {0x00, 0x44, 0x44}, // channel = 16, Tf = 5080MHz (28), TBD
- {0x00, 0x44, 0x44}, // channel = 34, Tf = 5170MHz (29), TBD
- {0x01, 0x55, 0x54}, // channel = 36, Tf = 5180MHz (30)
- {0x01, 0x55, 0x54}, // channel = 38, Tf = 5190MHz (31), TBD
- {0x02, 0xAA, 0xA4}, // channel = 40, Tf = 5200MHz (32)
- {0x02, 0xAA, 0xA4}, // channel = 42, Tf = 5210MHz (33), TBD
- {0x00, 0x00, 0x04}, // channel = 44, Tf = 5220MHz (34)
- {0x00, 0x00, 0x04}, // channel = 46, Tf = 5230MHz (35), TBD
- {0x01, 0x55, 0x54}, // channel = 48, Tf = 5240MHz (36)
- {0x02, 0xAA, 0xA4}, // channel = 52, Tf = 5260MHz (37)
- {0x00, 0x00, 0x04}, // channel = 56, Tf = 5280MHz (38)
- {0x01, 0x55, 0x54}, // channel = 60, Tf = 5300MHz (39)
- {0x02, 0xAA, 0xA4}, // channel = 64, Tf = 5320MHz (40)
- {0x02, 0xAA, 0xA4}, // channel = 100, Tf = 5500MHz (41), TBD
- {0x02, 0xAA, 0xA4}, // channel = 104, Tf = 5520MHz (42), TBD
- {0x02, 0xAA, 0xA4}, // channel = 108, Tf = 5540MHz (43), TBD
- {0x02, 0xAA, 0xA4}, // channel = 112, Tf = 5560MHz (44), TBD
- {0x02, 0xAA, 0xA4}, // channel = 116, Tf = 5580MHz (45), TBD
- {0x02, 0xAA, 0xA4}, // channel = 120, Tf = 5600MHz (46), TBD
- {0x02, 0xAA, 0xA4}, // channel = 124, Tf = 5620MHz (47), TBD
- {0x02, 0xAA, 0xA4}, // channel = 128, Tf = 5640MHz (48), TBD
- {0x02, 0xAA, 0xA4}, // channel = 132, Tf = 5660MHz (49), TBD
- {0x02, 0xAA, 0xA4}, // channel = 136, Tf = 5680MHz (50), TBD
- {0x02, 0xAA, 0xA4}, // channel = 140, Tf = 5700MHz (51), TBD
- {0x03, 0x00, 0x04}, // channel = 149, Tf = 5745MHz (52)
- {0x00, 0x55, 0x54}, // channel = 153, Tf = 5765MHz (53)
- {0x01, 0xAA, 0xA4}, // channel = 157, Tf = 5785MHz (54)
- {0x03, 0x00, 0x04}, // channel = 161, Tf = 5805MHz (55)
- {0x03, 0x00, 0x04} // channel = 165, Tf = 5825MHz (56), TBD
- };
-
-/*+
- *
- * Power Table
- *
--*/
+ {0x01, 0x99, 0x94},
+ {0x02, 0x44, 0x44},
+ {0x02, 0xee, 0xe4},
+ {0x03, 0x99, 0x94},
+ {0x00, 0x44, 0x44},
+ {0x00, 0xee, 0xe4},
+ {0x01, 0x99, 0x94},
+ {0x02, 0x44, 0x44},
+ {0x02, 0xee, 0xe4},
+ {0x03, 0x99, 0x94},
+ {0x00, 0x44, 0x44},
+ {0x00, 0xee, 0xe4},
+ {0x01, 0x99, 0x94},
+ {0x03, 0x33, 0x34},
+ {0x00, 0x44, 0x44}, /* channel = 15 Tf = 4915MHz */
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x00, 0x44, 0x44},
+ {0x01, 0x55, 0x54},
+ {0x01, 0x55, 0x54},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x00, 0x00, 0x04},
+ {0x00, 0x00, 0x04},
+ {0x01, 0x55, 0x54},
+ {0x02, 0xaa, 0xa4},
+ {0x00, 0x00, 0x04},
+ {0x01, 0x55, 0x54},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x02, 0xaa, 0xa4},
+ {0x03, 0x00, 0x04},
+ {0x00, 0x55, 0x54},
+ {0x01, 0xaa, 0xa4},
+ {0x03, 0x00, 0x04},
+ {0x03, 0x00, 0x04}
+};
+/* Power Table */
static const u32 al2230_power_table[AL2230_PWR_IDX_LEN] = {
- 0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04043900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04044900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04045900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04046900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04047900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04048900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04049900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0404F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04050900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04051900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04052900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04053900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04054900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04055900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04056900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04057900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04058900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04059900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0405F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04060900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04061900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04062900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04063900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04064900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04065900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04066900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04067900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04068900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04069900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0406F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04070900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04071900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04072900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04073900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04074900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04075900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04076900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04077900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04078900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x04079900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
- 0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
- };
-
-//{{ RobertYu:20050103, Channel 11a Number To Index
-// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
-// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
-// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
-
-const u8 RFaby11aChannelIndex[200] = {
- // 1 2 3 4 5 6 7 8 9 10
- 00, 00, 00, 00, 00, 00, 23, 24, 25, 00, // 10
- 26, 27, 00, 00, 00, 28, 00, 00, 00, 00, // 20
- 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 30
- 00, 00, 00, 29, 00, 30, 00, 31, 00, 32, // 40
- 00, 33, 00, 34, 00, 35, 00, 36, 00, 00, // 50
- 00, 37, 00, 00, 00, 38, 00, 00, 00, 39, // 60
- 00, 00, 00, 40, 00, 00, 00, 00, 00, 00, // 70
- 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 80
- 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, // 90
- 00, 00, 00, 00, 00, 00, 00, 00, 00, 41, //100
-
- 00, 00, 00, 42, 00, 00, 00, 43, 00, 00, //110
- 00, 44, 00, 00, 00, 45, 00, 00, 00, 46, //120
- 00, 00, 00, 47, 00, 00, 00, 48, 00, 00, //130
- 00, 49, 00, 00, 00, 50, 00, 00, 00, 51, //140
- 00, 00, 00, 00, 00, 00, 00, 00, 52, 00, //150
- 00, 00, 53, 00, 00, 00, 54, 00, 00, 00, //160
- 55, 00, 00, 00, 56, 00, 00, 00, 00, 00, //170
- 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, //180
- 00, 00, 15, 16, 17, 00, 18, 19, 20, 00, //190
- 00, 21, 00, 00, 00, 22, 00, 00, 00, 00 //200
+ 0x04040900,
+ 0x04041900,
+ 0x04042900,
+ 0x04043900,
+ 0x04044900,
+ 0x04045900,
+ 0x04046900,
+ 0x04047900,
+ 0x04048900,
+ 0x04049900,
+ 0x0404a900,
+ 0x0404b900,
+ 0x0404c900,
+ 0x0404d900,
+ 0x0404e900,
+ 0x0404f900,
+ 0x04050900,
+ 0x04051900,
+ 0x04052900,
+ 0x04053900,
+ 0x04054900,
+ 0x04055900,
+ 0x04056900,
+ 0x04057900,
+ 0x04058900,
+ 0x04059900,
+ 0x0405a900,
+ 0x0405b900,
+ 0x0405c900,
+ 0x0405d900,
+ 0x0405e900,
+ 0x0405f900,
+ 0x04060900,
+ 0x04061900,
+ 0x04062900,
+ 0x04063900,
+ 0x04064900,
+ 0x04065900,
+ 0x04066900,
+ 0x04067900,
+ 0x04068900,
+ 0x04069900,
+ 0x0406a900,
+ 0x0406b900,
+ 0x0406c900,
+ 0x0406d900,
+ 0x0406e900,
+ 0x0406f900,
+ 0x04070900,
+ 0x04071900,
+ 0x04072900,
+ 0x04073900,
+ 0x04074900,
+ 0x04075900,
+ 0x04076900,
+ 0x04077900,
+ 0x04078900,
+ 0x04079900,
+ 0x0407a900,
+ 0x0407b900,
+ 0x0407c900,
+ 0x0407d900,
+ 0x0407e900,
+ 0x0407f900
};
-//}} RobertYu
/*
* Description: Write to IF/RF, by embedded programming
- *
- * Parameters:
- * In:
- * dwData - data to write
- * Out:
- * none
- *
- * Return Value: true if succeeded; false if failed.
- *
*/
int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
{
u8 reg_data[4];
+ data |= (VNT_RF_REG_LEN << 3) | IFREGCTL_REGW;
+
reg_data[0] = (u8)data;
reg_data[1] = (u8)(data >> 8);
reg_data[2] = (u8)(data >> 16);
@@ -719,23 +620,11 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data)
return true;
}
-/*
- * Description: Set Tx power
- *
- * Parameters:
- * In:
- * dwIoBase - I/O base address
- * dwRFPowerTable - RF Tx Power Setting
- * Out:
- * none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
+/* Set Tx power by rate and channel number */
int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
{
int ret = true;
- u8 power = priv->byCCKPwr;
+ u8 power = priv->cck_pwr;
if (channel == 0)
return -EINVAL;
@@ -745,7 +634,10 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
case RATE_2M:
case RATE_5M:
case RATE_11M:
- power = priv->abyCCKPwrTbl[channel-1];
+ channel--;
+
+ if (channel < sizeof(priv->cck_pwr_tbl))
+ power = priv->cck_pwr_tbl[channel];
break;
case RATE_6M:
case RATE_9M:
@@ -755,9 +647,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->abyOFDMAPwrTbl[channel-15];
+ power = priv->ofdm_a_pwr_tbl[channel-15];
else
- power = priv->abyOFDMPwrTbl[channel-1];
+ power = priv->ofdm_pwr_tbl[channel-1];
break;
}
@@ -768,12 +660,12 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
static u8 vnt_rf_addpower(struct vnt_private *priv)
{
- s32 rssi = -priv->uCurrRSSI;
+ s32 rssi = -priv->current_rssi;
if (!rssi)
return 7;
- if (priv->byRFType == RF_VT3226D0) {
+ if (priv->rf_type == RF_VT3226D0) {
if (rssi < -70)
return 9;
else if (rssi < -65)
@@ -792,20 +684,7 @@ static u8 vnt_rf_addpower(struct vnt_private *priv)
return 0;
}
-/*
- * Description: Set Tx power
- *
- * Parameters:
- * In:
- * dwIoBase - I/O base address
- * dwRFPowerTable - RF Tx Power Setting
- * Out:
- * none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
-
+/* Set Tx power by power level and rate */
int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
{
u32 power_setting = 0;
@@ -815,133 +694,105 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
if (power > VNT_RF_MAX_POWER)
power = VNT_RF_MAX_POWER;
- if (priv->byCurPwr == power)
+ if (priv->power == power)
return true;
- priv->byCurPwr = power;
+ priv->power = power;
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
- if (priv->byCurPwr >= AL2230_PWR_IDX_LEN)
+ if (power >= AL2230_PWR_IDX_LEN)
return false;
- ret &= vnt_rf_write_embedded(priv,
- al2230_power_table[priv->byCurPwr]);
+ ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
if (rate <= RATE_11M)
- ret &= vnt_rf_write_embedded(priv, 0x0001b400 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x0001b400);
else
- ret &= vnt_rf_write_embedded(priv, 0x0005a400 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x0005a400);
break;
case RF_AL2230S:
- if (priv->byCurPwr >= AL2230_PWR_IDX_LEN)
+ if (power >= AL2230_PWR_IDX_LEN)
return false;
- ret &= vnt_rf_write_embedded(priv,
- al2230_power_table[priv->byCurPwr]);
+ ret &= vnt_rf_write_embedded(priv, al2230_power_table[power]);
if (rate <= RATE_11M) {
- ret &= vnt_rf_write_embedded(priv, 0x040c1400 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
- ret &= vnt_rf_write_embedded(priv, 0x00299b00 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x040c1400);
+ ret &= vnt_rf_write_embedded(priv, 0x00299b00);
} else {
- ret &= vnt_rf_write_embedded(priv, 0x0005a400 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
- ret &= vnt_rf_write_embedded(priv, 0x00099b00 +
- (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x0005a400);
+ ret &= vnt_rf_write_embedded(priv, 0x00099b00);
}
break;
case RF_AIROHA7230:
if (rate <= RATE_11M)
- ret &= vnt_rf_write_embedded(priv, 0x111bb900 +
- (BY_AL7230_REG_LEN << 3)+IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x111bb900);
else
- ret &= vnt_rf_write_embedded(priv, 0x221bb900 +
- (BY_AL7230_REG_LEN << 3)+IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x221bb900);
- if (priv->byCurPwr > AL7230_PWR_IDX_LEN)
+ if (power >= AL7230_PWR_IDX_LEN)
return false;
/*
* 0x080F1B00 for 3 wire control TxGain(D10)
* and 0x31 as TX Gain value
*/
- power_setting = 0x080c0b00 | ((priv->byCurPwr) << 12) |
- (BY_AL7230_REG_LEN << 3) | IFREGCTL_REGW;
+ power_setting = 0x080c0b00 | (power << 12);
ret &= vnt_rf_write_embedded(priv, power_setting);
break;
case RF_VT3226:
- if (priv->byCurPwr >= VT3226_PWR_IDX_LEN)
+ if (power >= VT3226_PWR_IDX_LEN)
return false;
- power_setting = ((0x3f - priv->byCurPwr) << 20) | (0x17 << 8) |
- (BY_VT3226_REG_LEN << 3) | IFREGCTL_REGW;
+ power_setting = ((0x3f - power) << 20) | (0x17 << 8);
ret &= vnt_rf_write_embedded(priv, power_setting);
break;
case RF_VT3226D0:
- if (priv->byCurPwr >= VT3226_PWR_IDX_LEN)
+ if (power >= VT3226_PWR_IDX_LEN)
return false;
if (rate <= RATE_11M) {
- power_setting = ((0x3f-priv->byCurPwr) << 20) |
- (0xe07 << 8) | (BY_VT3226_REG_LEN << 3) |
- IFREGCTL_REGW;
+ u16 hw_value = priv->hw->conf.chandef.chan->hw_value;
+
+ power_setting = ((0x3f - power) << 20) | (0xe07 << 8);
ret &= vnt_rf_write_embedded(priv, power_setting);
- ret &= vnt_rf_write_embedded(priv, 0x03c6a200 +
- (BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x03c6a200);
- if (priv->vnt_mgmt.eScanState != WMAC_NO_SCANNING) {
- dev_dbg(&priv->usb->dev,
- "vnt_rf_set_txpower> 11B mode uCurrChannel[%d]\n",
- priv->vnt_mgmt.uScanChannel);
- ret &= vnt_rf_write_embedded(priv,
- vt3226d0_lo_current_table[priv->
- vnt_mgmt.uScanChannel - 1]);
- } else {
- dev_dbg(&priv->usb->dev,
- "vnt_rf_set_txpower> 11B mode uCurrChannel[%d]\n",
- priv->vnt_mgmt.uCurrChannel);
+ dev_dbg(&priv->usb->dev,
+ "%s 11b channel [%d]\n", __func__, hw_value);
+
+ hw_value--;
+
+ if (hw_value < ARRAY_SIZE(vt3226d0_lo_current_table))
ret &= vnt_rf_write_embedded(priv,
- vt3226d0_lo_current_table[priv->
- vnt_mgmt.uCurrChannel - 1]);
- }
+ vt3226d0_lo_current_table[hw_value]);
- ret &= vnt_rf_write_embedded(priv, 0x015C0800 +
- (BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x015C0800);
} else {
dev_dbg(&priv->usb->dev,
"@@@@ vnt_rf_set_txpower> 11G mode\n");
- power_setting = ((0x3f-priv->byCurPwr) << 20) |
- (0x7 << 8) | (BY_VT3226_REG_LEN << 3) |
- IFREGCTL_REGW;
+ power_setting = ((0x3f - power) << 20) | (0x7 << 8);
ret &= vnt_rf_write_embedded(priv, power_setting);
- ret &= vnt_rf_write_embedded(priv, 0x00C6A200 +
- (BY_VT3226_REG_LEN << 3) + IFREGCTL_REGW);
- ret &= vnt_rf_write_embedded(priv, 0x016BC600 +
- (BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
- ret &= vnt_rf_write_embedded(priv, 0x00900800 +
- (BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+ ret &= vnt_rf_write_embedded(priv, 0x00C6A200);
+ ret &= vnt_rf_write_embedded(priv, 0x016BC600);
+ ret &= vnt_rf_write_embedded(priv, 0x00900800);
}
break;
case RF_VT3342A0:
- if (priv->byCurPwr >= VT3342_PWR_IDX_LEN)
+ if (power >= VT3342_PWR_IDX_LEN)
return false;
- power_setting = ((0x3F-priv->byCurPwr) << 20) |
- (0x27 << 8) | (BY_VT3342_REG_LEN << 3) |
- IFREGCTL_REGW;
+ power_setting = ((0x3f - power) << 20) | (0x27 << 8);
ret &= vnt_rf_write_embedded(priv, power_setting);
@@ -952,21 +803,7 @@ int vnt_rf_set_txpower(struct vnt_private *priv, u8 power, u32 rate)
return ret;
}
-/*+
- *
- * Routine Description:
- * Translate RSSI to dBm
- *
- * Parameters:
- * In:
- * pDevice - The adapter to be translated
- * byCurrRSSI - RSSI to be translated
- * Out:
- * pdwdbm - Translated dbm number
- *
- * Return Value: none
- *
--*/
+/* Convert rssi to dbm */
void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
{
u8 idx = (((rssi & 0xc0) >> 6) & 0x03);
@@ -974,7 +811,7 @@ void vnt_rf_rssi_to_dbm(struct vnt_private *priv, u8 rssi, long *dbm)
long a = 0;
u8 airoharf[4] = {0, 18, 0, 40};
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
case RF_AL2230S:
case RF_AIROHA7230:
@@ -997,7 +834,7 @@ void vnt_rf_table_download(struct vnt_private *priv)
u16 length, value;
u8 array[256];
- switch (priv->byRFType) {
+ switch (priv->rf_type) {
case RF_AL2230:
case RF_AL2230S:
length1 = CB_AL2230_INIT_SEQ * 3;
@@ -1083,7 +920,7 @@ void vnt_rf_table_download(struct vnt_private *priv)
addr3 += length;
}
- if (priv->byRFType == RF_AIROHA7230) {
+ if (priv->rf_type == RF_AIROHA7230) {
length1 = CB_AL7230_INIT_SEQ * 3;
length2 = CB_MAX_CHANNEL * 3;
addr1 = &(al7230_init_table_amode[0][0]);
diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h
index cb331518568e..3acdc65b1e56 100644
--- a/drivers/staging/vt6656/rf.h
+++ b/drivers/staging/vt6656/rf.h
@@ -32,9 +32,7 @@
#include "device.h"
-//
-// Baseband RF pair definition in eeprom (Bits 6..0)
-//
+/* Baseband RF pair definition in eeprom (Bits 6..0) */
#define RF_RFMD2959 0x01
#define RF_MAXIMAG 0x02
#define RF_AL2230 0x03
@@ -46,16 +44,15 @@
#define RF_VT3226 0x09
#define RF_AIROHA7230 0x0a
#define RF_UW2453 0x0b
-#define RF_VT3226D0 0x0c //RobertYu:20051114
-#define RF_VT3342A0 0x0d //RobertYu:20060609
+#define RF_VT3226D0 0x0c /* RobertYu:20051114 */
+#define RF_VT3342A0 0x0d /* RobertYu:20060609 */
#define RF_AL2230S 0x0e
#define RF_EMU 0x80
#define RF_MASK 0x7F
#define VNT_RF_MAX_POWER 0x3f
-
-extern const u8 RFaby11aChannelIndex[200];
+#define VNT_RF_REG_LEN 0x17 /* 24 bit length */
int vnt_rf_write_embedded(struct vnt_private *, u32);
int vnt_rf_setpower(struct vnt_private *, u32, u32);
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index 704f4d3639be..2d1ef88808ff 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -25,22 +25,12 @@
* Date: May 20, 2003
*
* Functions:
- * s_vGenerateTxParameter - Generate tx dma required parameter.
- * s_vGenerateMACHeader - Translate 802.3 to 802.11 header
- * csBeacon_xmit - beacon tx function
- * csMgmt_xmit - management tx function
- * s_uGetDataDuration - get tx data required duration
- * s_uFillDataHead- fulfill tx data duration header
- * s_uGetRTSCTSDuration- get rtx/cts required duration
- * s_uGetRTSCTSRsvTime- get rts/cts reserved time
- * s_uGetTxRsvTime- get frame reserved time
- * s_vFillCTSHead- fulfill CTS ctl header
- * s_vFillFragParameter- Set fragment ctl parameter.
- * s_vFillRTSHead- fulfill RTS ctl header
- * s_vFillTxKey- fulfill tx encrypt key
- * s_vSWencryption- Software encrypt header
- * vDMA0_tx_80211- tx 802.11 frame via dma0
- * vGenerateFIFOHeader- Generate tx FIFO ctl header
+ * vnt_generate_tx_parameter - Generate tx dma required parameter.
+ * vnt_get_duration_le - get tx data required duration
+ * vnt_get_rtscts_duration_le- get rtx/cts required duration
+ * vnt_get_rtscts_rsvtime_le- get rts/cts reserved time
+ * vnt_get_rsvtime- get frame reserved time
+ * vnt_fill_cts_head- fulfill CTS ctl header
*
* Revision History:
*
@@ -48,33 +38,25 @@
#include "device.h"
#include "rxtx.h"
-#include "tether.h"
#include "card.h"
-#include "bssdb.h"
#include "mac.h"
-#include "michael.h"
-#include "tkip.h"
-#include "wctl.h"
#include "rf.h"
-#include "datarate.h"
#include "usbpipe.h"
-#include "iocmd.h"
-static int msglevel = MSG_LEVEL_INFO;
+static const u16 vnt_time_stampoff[2][MAX_RATE] = {
+ {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23},/* Long Preamble */
+ {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23},/* Short Preamble */
+};
-static const u16 wTimeStampOff[2][MAX_RATE] = {
- {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
- {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
- };
+static const u16 vnt_fb_opt0[2][5] = {
+ {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, /* fallback_rate0 */
+ {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, /* fallback_rate1 */
+};
-static const u16 wFB_Opt0[2][5] = {
- {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
- {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
- };
-static const u16 wFB_Opt1[2][5] = {
- {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
- {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
- };
+static const u16 vnt_fb_opt1[2][5] = {
+ {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
+ {RATE_6M , RATE_6M, RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
+};
#define RTSDUR_BB 0
#define RTSDUR_BA 1
@@ -91,268 +73,59 @@ static const u16 wFB_Opt1[2][5] = {
#define DATADUR_A_F0 12
#define DATADUR_A_F1 13
-static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
- u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl);
-
-static struct vnt_usb_send_context *s_vGetFreeContext(struct vnt_private *);
-
-static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
- u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
- struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
- int bNeedACK, struct ethhdr *psEthHeader, bool need_rts);
-
-static void s_vGenerateMACHeader(struct vnt_private *pDevice,
- u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
- int bNeedEncrypt, u16 wFragType, u32 uFragIdx);
-
-static void s_vFillTxKey(struct vnt_private *pDevice,
- struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
- PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
- struct vnt_mic_hdr *mic_hdr);
-
-static void s_vSWencryption(struct vnt_private *pDevice,
- PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize);
-
-static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
- u32 cbFrameLength, u16 wRate, int bNeedAck);
-
-static __le16 s_uGetRTSCTSRsvTime(struct vnt_private *priv,
- u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate);
-
-static u16 s_vFillCTSHead(struct vnt_private *pDevice,
- u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
- int bNeedAck, u16 wCurrentRate, u8 byFBOption);
-
-static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
- union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
- struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
-
-static __le16 s_uGetDataDuration(struct vnt_private *pDevice,
- u8 byPktType, int bNeedAck);
-
-static __le16 s_uGetRTSCTSDuration(struct vnt_private *pDevice,
- u8 byDurType, u32 cbFrameLength, u8 byPktType, u16 wRate,
- int bNeedAck, u8 byFBOption);
-
static struct vnt_usb_send_context
- *s_vGetFreeContext(struct vnt_private *priv)
+ *vnt_get_free_context(struct vnt_private *priv)
{
struct vnt_usb_send_context *context = NULL;
int ii;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
+ dev_dbg(&priv->usb->dev, "%s\n", __func__);
- for (ii = 0; ii < priv->cbTD; ii++) {
- if (!priv->apTD[ii])
+ for (ii = 0; ii < priv->num_tx_context; ii++) {
+ if (!priv->tx_context[ii])
return NULL;
- context = priv->apTD[ii];
+ context = priv->tx_context[ii];
if (context->in_use == false) {
context->in_use = true;
memset(context->data, 0,
MAX_TOTAL_SIZE_WITH_ALL_HEADERS);
+
+ context->hdr = NULL;
+
return context;
}
}
- if (ii == priv->cbTD)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
+ if (ii == priv->num_tx_context)
+ dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__);
return NULL;
}
-static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
- u8 *pbyDestAddr, u16 wPktLength, u16 wFIFOCtl)
-{
- struct net_device_stats *stats = &pDevice->stats;
- struct vnt_tx_pkt_info *pkt_info = pDevice->pkt_info;
-
- pkt_info[byPktNum].fifo_ctl = wFIFOCtl;
- memcpy(pkt_info[byPktNum].dest_addr, pbyDestAddr, ETH_ALEN);
-
- stats->tx_bytes += wPktLength;
-}
-
-static void s_vFillTxKey(struct vnt_private *pDevice,
- struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
- PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
- struct vnt_mic_hdr *mic_hdr)
-{
- u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0];
- __le32 *pdwIV = (__le32 *)pbyIVHead;
- __le32 *pdwExtIV = (__le32 *)((u8 *)pbyIVHead + 4);
- struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
- __le32 rev_iv_counter;
-
- /* Fill TXKEY */
- if (pTransmitKey == NULL)
- return;
-
- rev_iv_counter = cpu_to_le32(pDevice->dwIVCounter);
- *pdwIV = cpu_to_le32(pDevice->dwIVCounter);
- pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
-
- switch (pTransmitKey->byCipherSuite) {
- case KEY_CTL_WEP:
- if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN) {
- memcpy(pDevice->abyPRNG, (u8 *)&rev_iv_counter, 3);
- memcpy(pDevice->abyPRNG + 3, pTransmitKey->abyKey,
- pTransmitKey->uKeyLength);
- } else {
- memcpy(pbyBuf, (u8 *)&rev_iv_counter, 3);
- memcpy(pbyBuf + 3, pTransmitKey->abyKey,
- pTransmitKey->uKeyLength);
- if (pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
- memcpy(pbyBuf+8, (u8 *)&rev_iv_counter, 3);
- memcpy(pbyBuf+11, pTransmitKey->abyKey,
- pTransmitKey->uKeyLength);
- }
-
- memcpy(pDevice->abyPRNG, pbyBuf, 16);
- }
- /* Append IV after Mac Header */
- *pdwIV &= cpu_to_le32(WEP_IV_MASK);
- *pdwIV |= cpu_to_le32((u32)pDevice->byKeyIndex << 30);
-
- pDevice->dwIVCounter++;
- if (pDevice->dwIVCounter > WEP_IV_MASK)
- pDevice->dwIVCounter = 0;
-
- break;
- case KEY_CTL_TKIP:
- pTransmitKey->wTSC15_0++;
- if (pTransmitKey->wTSC15_0 == 0)
- pTransmitKey->dwTSC47_16++;
-
- TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
- pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16,
- pDevice->abyPRNG);
- memcpy(pbyBuf, pDevice->abyPRNG, 16);
-
- /* Make IV */
- memcpy(pdwIV, pDevice->abyPRNG, 3);
-
- *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) &
- 0xc0) | 0x20);
- /* Append IV&ExtIV after Mac Header */
- *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "vFillTxKey()---- pdwExtIV: %x\n", *pdwExtIV);
-
- break;
- case KEY_CTL_CCMP:
- pTransmitKey->wTSC15_0++;
- if (pTransmitKey->wTSC15_0 == 0)
- pTransmitKey->dwTSC47_16++;
-
- memcpy(pbyBuf, pTransmitKey->abyKey, 16);
-
- /* Make IV */
- *pdwIV = 0;
- *(pbyIVHead+3) = (u8)(((pDevice->byKeyIndex << 6) &
- 0xc0) | 0x20);
-
- *pdwIV |= cpu_to_le32((u32)(pTransmitKey->wTSC15_0));
-
- /* Append IV&ExtIV after Mac Header */
- *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
-
- if (!mic_hdr)
- return;
-
- /* MICHDR0 */
- mic_hdr->id = 0x59;
- mic_hdr->payload_len = cpu_to_be16(wPayloadLen);
- memcpy(mic_hdr->mic_addr2, pMACHeader->addr2, ETH_ALEN);
-
- mic_hdr->tsc_47_16 = cpu_to_be32(pTransmitKey->dwTSC47_16);
- mic_hdr->tsc_15_0 = cpu_to_be16(pTransmitKey->wTSC15_0);
-
- /* MICHDR1 */
- if (ieee80211_has_a4(pMACHeader->frame_control))
- mic_hdr->hlen = cpu_to_be16(28);
- else
- mic_hdr->hlen = cpu_to_be16(22);
-
- memcpy(mic_hdr->addr1, pMACHeader->addr1, ETH_ALEN);
- memcpy(mic_hdr->addr2, pMACHeader->addr2, ETH_ALEN);
-
- /* MICHDR2 */
- memcpy(mic_hdr->addr3, pMACHeader->addr3, ETH_ALEN);
- mic_hdr->frame_control = cpu_to_le16(
- le16_to_cpu(pMACHeader->frame_control) & 0xc78f);
- mic_hdr->seq_ctrl = cpu_to_le16(
- le16_to_cpu(pMACHeader->seq_ctrl) & 0xf);
-
- if (ieee80211_has_a4(pMACHeader->frame_control))
- memcpy(mic_hdr->addr4, pMACHeader->addr4, ETH_ALEN);
- }
-}
-
-static void s_vSWencryption(struct vnt_private *pDevice,
- PSKeyItem pTransmitKey, u8 *pbyPayloadHead, u16 wPayloadSize)
-{
- u32 cbICVlen = 4;
- u32 dwICV = 0xffffffff;
- u32 *pdwICV;
-
- if (pTransmitKey == NULL)
- return;
-
- if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
- //=======================================================================
- // Append ICV after payload
- dwICV = ether_crc_le(wPayloadSize, pbyPayloadHead);
- pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
- // finally, we must invert dwCRC to get the correct answer
- *pdwICV = cpu_to_le32(~dwICV);
- // RC4 encryption
- rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
- rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
- //=======================================================================
- } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
- //=======================================================================
- //Append ICV after payload
- dwICV = ether_crc_le(wPayloadSize, pbyPayloadHead);
- pdwICV = (u32 *)(pbyPayloadHead + wPayloadSize);
- // finally, we must invert dwCRC to get the correct answer
- *pdwICV = cpu_to_le32(~dwICV);
- // RC4 encryption
- rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
- rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
- //=======================================================================
- }
-}
-
static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate)
{
- return cpu_to_le16(wTimeStampOff[priv->byPreambleType % 2]
+ return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2]
[rate % MAX_RATE]);
}
-/*byPktType : PK_TYPE_11A 0
- PK_TYPE_11B 1
- PK_TYPE_11GB 2
- PK_TYPE_11GA 3
-*/
-static u32 s_uGetTxRsvTime(struct vnt_private *priv, u8 pkt_type,
+static u32 vnt_get_rsvtime(struct vnt_private *priv, u8 pkt_type,
u32 frame_length, u16 rate, int need_ack)
{
u32 data_time, ack_time;
- data_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
+ data_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
frame_length, rate);
if (pkt_type == PK_TYPE_11B)
- ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, 14,
- (u16)priv->byTopCCKBasicRate);
+ ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, (u16)priv->top_cck_basic_rate);
else
- ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type, 14,
- (u16)priv->byTopOFDMBasicRate);
+ ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, (u16)priv->top_ofdm_basic_rate);
if (need_ack)
- return data_time + priv->uSIFS + ack_time;
+ return data_time + priv->sifs + ack_time;
return data_time;
}
@@ -360,1715 +133,970 @@ static u32 s_uGetTxRsvTime(struct vnt_private *priv, u8 pkt_type,
static __le16 vnt_rxtx_rsvtime_le16(struct vnt_private *priv, u8 pkt_type,
u32 frame_length, u16 rate, int need_ack)
{
- return cpu_to_le16((u16)s_uGetTxRsvTime(priv, pkt_type,
+ return cpu_to_le16((u16)vnt_get_rsvtime(priv, pkt_type,
frame_length, rate, need_ack));
}
-//byFreqType: 0=>5GHZ 1=>2.4GHZ
-static __le16 s_uGetRTSCTSRsvTime(struct vnt_private *priv,
+static __le16 vnt_get_rtscts_rsvtime_le(struct vnt_private *priv,
u8 rsv_type, u8 pkt_type, u32 frame_length, u16 current_rate)
{
u32 rrv_time, rts_time, cts_time, ack_time, data_time;
rrv_time = rts_time = cts_time = ack_time = data_time = 0;
- data_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
+ data_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
frame_length, current_rate);
if (rsv_type == 0) {
- rts_time = BBuGetFrameTime(priv->byPreambleType,
- pkt_type, 20, priv->byTopCCKBasicRate);
- cts_time = ack_time = BBuGetFrameTime(priv->byPreambleType,
- pkt_type, 14, priv->byTopCCKBasicRate);
+ rts_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 20, priv->top_cck_basic_rate);
+ cts_time = ack_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_cck_basic_rate);
} else if (rsv_type == 1) {
- rts_time = BBuGetFrameTime(priv->byPreambleType,
- pkt_type, 20, priv->byTopCCKBasicRate);
- cts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
- 14, priv->byTopCCKBasicRate);
- ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
- 14, priv->byTopOFDMBasicRate);
+ rts_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 20, priv->top_cck_basic_rate);
+ cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, priv->top_cck_basic_rate);
+ ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, priv->top_ofdm_basic_rate);
} else if (rsv_type == 2) {
- rts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
- 20, priv->byTopOFDMBasicRate);
- cts_time = ack_time = BBuGetFrameTime(priv->byPreambleType,
- pkt_type, 14, priv->byTopOFDMBasicRate);
+ rts_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 20, priv->top_ofdm_basic_rate);
+ cts_time = ack_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_ofdm_basic_rate);
} else if (rsv_type == 3) {
- cts_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
- 14, priv->byTopCCKBasicRate);
- ack_time = BBuGetFrameTime(priv->byPreambleType, pkt_type,
- 14, priv->byTopOFDMBasicRate);
+ cts_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, priv->top_cck_basic_rate);
+ ack_time = vnt_get_frame_time(priv->preamble_type, pkt_type,
+ 14, priv->top_ofdm_basic_rate);
- rrv_time = cts_time + ack_time + data_time + 2 * priv->uSIFS;
+ rrv_time = cts_time + ack_time + data_time + 2 * priv->sifs;
return cpu_to_le16((u16)rrv_time);
}
- rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->uSIFS;
+ rrv_time = rts_time + cts_time + ack_time + data_time + 3 * priv->sifs;
return cpu_to_le16((u16)rrv_time);
}
-//byFreqType 0: 5GHz, 1:2.4Ghz
-static __le16 s_uGetDataDuration(struct vnt_private *pDevice,
- u8 byPktType, int bNeedAck)
+static __le16 vnt_get_duration_le(struct vnt_private *priv,
+ u8 pkt_type, int need_ack)
{
- u32 uAckTime = 0;
+ u32 ack_time = 0;
- if (bNeedAck) {
- if (byPktType == PK_TYPE_11B)
- uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
- byPktType, 14, pDevice->byTopCCKBasicRate);
+ if (need_ack) {
+ if (pkt_type == PK_TYPE_11B)
+ ack_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_cck_basic_rate);
else
- uAckTime = BBuGetFrameTime(pDevice->byPreambleType,
- byPktType, 14, pDevice->byTopOFDMBasicRate);
- return cpu_to_le16((u16)(pDevice->uSIFS + uAckTime));
+ ack_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_ofdm_basic_rate);
+
+ return cpu_to_le16((u16)(priv->sifs + ack_time));
}
return 0;
}
-//byFreqType: 0=>5GHZ 1=>2.4GHZ
-static __le16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
- u32 cbFrameLength, u8 byPktType, u16 wRate, int bNeedAck,
- u8 byFBOption)
+static __le16 vnt_get_rtscts_duration_le(struct vnt_usb_send_context *context,
+ u8 dur_type, u8 pkt_type, u16 rate)
{
- u32 uCTSTime = 0, uDurTime = 0;
+ struct vnt_private *priv = context->priv;
+ u32 cts_time = 0, dur_time = 0;
+ u32 frame_length = context->frame_len;
+ u8 need_ack = context->need_ack;
- switch (byDurType) {
+ switch (dur_type) {
case RTSDUR_BB:
case RTSDUR_BA:
case RTSDUR_BA_F0:
case RTSDUR_BA_F1:
- uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
- 14, pDevice->byTopCCKBasicRate);
- uDurTime = uCTSTime + 2 * pDevice->uSIFS +
- s_uGetTxRsvTime(pDevice, byPktType,
- cbFrameLength, wRate, bNeedAck);
+ cts_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_cck_basic_rate);
+ dur_time = cts_time + 2 * priv->sifs +
+ vnt_get_rsvtime(priv, pkt_type,
+ frame_length, rate, need_ack);
break;
case RTSDUR_AA:
case RTSDUR_AA_F0:
case RTSDUR_AA_F1:
- uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
- 14, pDevice->byTopOFDMBasicRate);
- uDurTime = uCTSTime + 2 * pDevice->uSIFS +
- s_uGetTxRsvTime(pDevice, byPktType,
- cbFrameLength, wRate, bNeedAck);
+ cts_time = vnt_get_frame_time(priv->preamble_type,
+ pkt_type, 14, priv->top_ofdm_basic_rate);
+ dur_time = cts_time + 2 * priv->sifs +
+ vnt_get_rsvtime(priv, pkt_type,
+ frame_length, rate, need_ack);
break;
case CTSDUR_BA:
case CTSDUR_BA_F0:
case CTSDUR_BA_F1:
- uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice,
- byPktType, cbFrameLength, wRate, bNeedAck);
+ dur_time = priv->sifs + vnt_get_rsvtime(priv,
+ pkt_type, frame_length, rate, need_ack);
break;
default:
break;
}
- return cpu_to_le16((u16)uDurTime);
+ return cpu_to_le16((u16)dur_time);
}
-static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate,
- struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack)
+static u16 vnt_mac_hdr_pos(struct vnt_usb_send_context *tx_context,
+ struct ieee80211_hdr *hdr)
{
+ u8 *head = tx_context->data + offsetof(struct vnt_tx_buffer, fifo_head);
+ u8 *hdr_pos = (u8 *)hdr;
+
+ tx_context->hdr = hdr;
+ if (!tx_context->hdr)
+ return 0;
+
+ return (u16)(hdr_pos - head);
+}
+
+static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
+ struct vnt_tx_datahead_g *buf)
+{
+
+ struct vnt_private *priv = tx_context->priv;
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;
+ u32 frame_len = tx_context->frame_len;
+ u16 rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
- BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+ vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a);
+ vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate,
PK_TYPE_11B, &buf->b);
/* Get Duration and TimeStamp */
- buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
- buf->duration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+ if (ieee80211_is_pspoll(hdr->frame_control)) {
+ __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
+
+ buf->duration_a = dur;
+ buf->duration_b = dur;
+ } else {
+ buf->duration_a = vnt_get_duration_le(priv,
+ tx_context->pkt_type, need_ack);
+ buf->duration_b = vnt_get_duration_le(priv,
+ PK_TYPE_11B, need_ack);
+ }
buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate);
buf->time_stamp_off_b = vnt_time_stamp_off(priv,
- priv->byTopCCKBasicRate);
+ priv->top_cck_basic_rate);
+
+ tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr);
return le16_to_cpu(buf->duration_a);
}
-static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type,
- u16 rate, struct vnt_tx_datahead_g_fb *buf,
- u32 frame_len, int need_ack)
+static u16 vnt_rxtx_datahead_g_fb(struct vnt_usb_send_context *tx_context,
+ struct vnt_tx_datahead_g_fb *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ u32 frame_len = tx_context->frame_len;
+ u16 rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+ vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a);
- BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+ vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate,
PK_TYPE_11B, &buf->b);
/* Get Duration and TimeStamp */
- buf->duration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
- buf->duration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+ buf->duration_a = vnt_get_duration_le(priv, tx_context->pkt_type,
+ need_ack);
+ buf->duration_b = vnt_get_duration_le(priv, PK_TYPE_11B, need_ack);
- buf->duration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
- buf->duration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+ buf->duration_a_f0 = vnt_get_duration_le(priv, tx_context->pkt_type,
+ need_ack);
+ buf->duration_a_f1 = vnt_get_duration_le(priv, tx_context->pkt_type,
+ need_ack);
buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate);
buf->time_stamp_off_b = vnt_time_stamp_off(priv,
- priv->byTopCCKBasicRate);
+ priv->top_cck_basic_rate);
+
+ tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr);
return le16_to_cpu(buf->duration_a);
}
-static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type,
- u16 rate, struct vnt_tx_datahead_a_fb *buf,
- u32 frame_len, int need_ack)
+static u16 vnt_rxtx_datahead_a_fb(struct vnt_usb_send_context *tx_context,
+ struct vnt_tx_datahead_a_fb *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ u16 rate = tx_context->tx_rate;
+ u8 pkt_type = tx_context->pkt_type;
+ u8 need_ack = tx_context->need_ack;
+ u32 frame_len = tx_context->frame_len;
+
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+ vnt_get_phy_field(priv, frame_len, rate, pkt_type, &buf->a);
/* Get Duration and TimeStampOff */
- buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack);
+ buf->duration = vnt_get_duration_le(priv, pkt_type, need_ack);
- buf->duration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
- buf->duration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+ buf->duration_f0 = vnt_get_duration_le(priv, pkt_type, need_ack);
+ buf->duration_f1 = vnt_get_duration_le(priv, pkt_type, need_ack);
buf->time_stamp_off = vnt_time_stamp_off(priv, rate);
+ tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr);
+
return le16_to_cpu(buf->duration);
}
-static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type,
- u16 rate, struct vnt_tx_datahead_ab *buf,
- u32 frame_len, int need_ack)
+static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
+ struct vnt_tx_datahead_ab *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;
+ u32 frame_len = tx_context->frame_len;
+ u16 rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab);
+ vnt_get_phy_field(priv, frame_len, rate,
+ tx_context->pkt_type, &buf->ab);
+
/* Get Duration and TimeStampOff */
- buf->duration = s_uGetDataDuration(priv, pkt_type, need_ack);
+ if (ieee80211_is_pspoll(hdr->frame_control)) {
+ __le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
+
+ buf->duration = dur;
+ } else {
+ buf->duration = vnt_get_duration_le(priv, tx_context->pkt_type,
+ need_ack);
+ }
buf->time_stamp_off = vnt_time_stamp_off(priv, rate);
+ tx_context->tx_hdr_size = vnt_mac_hdr_pos(tx_context, &buf->hdr);
+
return le16_to_cpu(buf->duration);
}
-static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
- struct ieee80211_rts *rts, struct ethhdr *eth_hdr,
- __le16 duration)
+static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context,
+ struct ieee80211_rts *rts, __le16 duration)
{
+ struct ieee80211_hdr *hdr =
+ (struct ieee80211_hdr *)tx_context->skb->data;
+
rts->duration = duration;
rts->frame_control =
cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
- if (priv->op_mode == NL80211_IFTYPE_ADHOC ||
- priv->op_mode == NL80211_IFTYPE_AP)
- memcpy(rts->ra, eth_hdr->h_dest, ETH_ALEN);
- else
- memcpy(rts->ra, priv->abyBSSID, ETH_ALEN);
-
- if (priv->op_mode == NL80211_IFTYPE_AP)
- memcpy(rts->ta, priv->abyBSSID, ETH_ALEN);
- else
- memcpy(rts->ta, eth_hdr->h_source, ETH_ALEN);
+ memcpy(rts->ra, hdr->addr1, ETH_ALEN);
+ memcpy(rts->ta, hdr->addr2, ETH_ALEN);
return 0;
}
-static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv,
- struct vnt_rts_g *buf, struct ethhdr *eth_hdr,
- u8 pkt_type, u32 frame_len, int need_ack,
- u16 current_rate, u8 fb_option)
+static u16 vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context,
+ struct vnt_rts_g *buf)
{
+ struct vnt_private *priv = tx_context->priv;
u16 rts_frame_len = 20;
+ u16 current_rate = tx_context->tx_rate;
- BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate,
+ vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate,
PK_TYPE_11B, &buf->b);
- BBvCalculateParameter(priv, rts_frame_len,
- priv->byTopOFDMBasicRate, pkt_type, &buf->a);
-
- buf->duration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len,
- PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option);
- buf->duration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
- buf->duration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
-
- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa);
-
- return vnt_rxtx_datahead_g(priv, pkt_type, current_rate,
- &buf->data_head, frame_len, need_ack);
+ vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate,
+ tx_context->pkt_type, &buf->a);
+
+ buf->duration_bb = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BB,
+ PK_TYPE_11B,
+ priv->top_cck_basic_rate);
+ buf->duration_aa = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA,
+ tx_context->pkt_type,
+ current_rate);
+ buf->duration_ba = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA,
+ tx_context->pkt_type,
+ current_rate);
+
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa);
+
+ return vnt_rxtx_datahead_g(tx_context, &buf->data_head);
}
-static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
- struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr,
- u8 pkt_type, u32 frame_len, int need_ack,
- u16 current_rate, u8 fb_option)
+static u16 vnt_rxtx_rts_g_fb_head(struct vnt_usb_send_context *tx_context,
+ struct vnt_rts_g_fb *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ u16 current_rate = tx_context->tx_rate;
u16 rts_frame_len = 20;
- BBvCalculateParameter(priv, rts_frame_len, priv->byTopCCKBasicRate,
+ vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate,
PK_TYPE_11B, &buf->b);
- BBvCalculateParameter(priv, rts_frame_len,
- priv->byTopOFDMBasicRate, pkt_type, &buf->a);
-
-
- buf->duration_bb = s_uGetRTSCTSDuration(priv, RTSDUR_BB, frame_len,
- PK_TYPE_11B, priv->byTopCCKBasicRate, need_ack, fb_option);
- buf->duration_aa = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
- buf->duration_ba = s_uGetRTSCTSDuration(priv, RTSDUR_BA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
-
-
- buf->rts_duration_ba_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F0,
- frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
- buf->rts_duration_aa_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
- frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
- buf->rts_duration_ba_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F1,
- frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
- buf->rts_duration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
- frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
-
- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration_aa);
-
- return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate,
- &buf->data_head, frame_len, need_ack);
+ vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate,
+ tx_context->pkt_type, &buf->a);
+
+ buf->duration_bb = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BB,
+ PK_TYPE_11B,
+ priv->top_cck_basic_rate);
+ buf->duration_aa = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA,
+ tx_context->pkt_type,
+ current_rate);
+ buf->duration_ba = vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA,
+ tx_context->pkt_type,
+ current_rate);
+
+ buf->rts_duration_ba_f0 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA_F0,
+ tx_context->pkt_type,
+ priv->tx_rate_fb0);
+ buf->rts_duration_aa_f0 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F0,
+ tx_context->pkt_type,
+ priv->tx_rate_fb0);
+ buf->rts_duration_ba_f1 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_BA_F1,
+ tx_context->pkt_type,
+ priv->tx_rate_fb1);
+ buf->rts_duration_aa_f1 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F1,
+ tx_context->pkt_type,
+ priv->tx_rate_fb1);
+
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa);
+
+ return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head);
}
-static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv,
- struct vnt_rts_ab *buf, struct ethhdr *eth_hdr,
- u8 pkt_type, u32 frame_len, int need_ack,
- u16 current_rate, u8 fb_option)
+static u16 vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context,
+ struct vnt_rts_ab *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ u16 current_rate = tx_context->tx_rate;
u16 rts_frame_len = 20;
- BBvCalculateParameter(priv, rts_frame_len,
- priv->byTopOFDMBasicRate, pkt_type, &buf->ab);
+ vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate,
+ tx_context->pkt_type, &buf->ab);
- buf->duration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
+ buf->duration = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA,
+ tx_context->pkt_type,
+ current_rate);
- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration);
- return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate,
- &buf->data_head, frame_len, need_ack);
+ return vnt_rxtx_datahead_ab(tx_context, &buf->data_head);
}
-static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
- struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr,
- u8 pkt_type, u32 frame_len, int need_ack,
- u16 current_rate, u8 fb_option)
+static u16 vnt_rxtx_rts_a_fb_head(struct vnt_usb_send_context *tx_context,
+ struct vnt_rts_a_fb *buf)
{
+ struct vnt_private *priv = tx_context->priv;
+ u16 current_rate = tx_context->tx_rate;
u16 rts_frame_len = 20;
- BBvCalculateParameter(priv, rts_frame_len,
- priv->byTopOFDMBasicRate, pkt_type, &buf->a);
+ vnt_get_phy_field(priv, rts_frame_len,
+ priv->top_ofdm_basic_rate, tx_context->pkt_type, &buf->a);
- buf->duration = s_uGetRTSCTSDuration(priv, RTSDUR_AA, frame_len,
- pkt_type, current_rate, need_ack, fb_option);
+ buf->duration = vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA,
+ tx_context->pkt_type,
+ current_rate);
- buf->rts_duration_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
- frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
+ buf->rts_duration_f0 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F0,
+ tx_context->pkt_type,
+ priv->tx_rate_fb0);
- buf->rts_duration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
- frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
+ buf->rts_duration_f1 =
+ vnt_get_rtscts_duration_le(tx_context, RTSDUR_AA_F1,
+ tx_context->pkt_type,
+ priv->tx_rate_fb1);
- vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->duration);
+ vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration);
- return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate,
- &buf->data_head, frame_len, need_ack);
+ return vnt_rxtx_datahead_a_fb(tx_context, &buf->data_head);
}
-static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
- union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
- struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
+static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context,
+ union vnt_tx_data_head *head)
{
+ struct vnt_private *priv = tx_context->priv;
+ u32 cts_frame_len = 14;
+ u16 current_rate = tx_context->tx_rate;
if (!head)
return 0;
- /* Note: So far RTSHead doesn't appear in ATIM
- * & Beacom DMA, so we don't need to take them
- * into account.
- * Otherwise, we need to modified codes for them.
- */
- switch (byPktType) {
- case PK_TYPE_11GB:
- case PK_TYPE_11GA:
- if (byFBOption == AUTO_FB_NONE)
- return vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
- psEthHeader, byPktType, cbFrameLength,
- bNeedAck, wCurrentRate, byFBOption);
- else
- return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
- psEthHeader, byPktType, cbFrameLength,
- bNeedAck, wCurrentRate, byFBOption);
- break;
- case PK_TYPE_11A:
- if (byFBOption) {
- return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
- psEthHeader, byPktType, cbFrameLength,
- bNeedAck, wCurrentRate, byFBOption);
- break;
- }
- case PK_TYPE_11B:
- return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
- psEthHeader, byPktType, cbFrameLength,
- bNeedAck, wCurrentRate, byFBOption);
- }
-
- return 0;
-}
-
-static u16 s_vFillCTSHead(struct vnt_private *pDevice,
- u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
- int bNeedAck, u16 wCurrentRate, u8 byFBOption)
-{
- u32 uCTSFrameLen = 14;
-
- if (!head)
- return 0;
-
- if (byFBOption != AUTO_FB_NONE) {
+ if (tx_context->fb_option) {
/* Auto Fall back */
- struct vnt_cts_fb *pBuf = &head->cts_g_fb;
+ struct vnt_cts_fb *buf = &head->cts_g_fb;
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(pDevice, uCTSFrameLen,
- pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
- pBuf->duration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA,
- cbFrameLength, byPktType,
- wCurrentRate, bNeedAck, byFBOption);
+ vnt_get_phy_field(priv, cts_frame_len,
+ priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b);
+ buf->duration_ba =
+ vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
+ tx_context->pkt_type,
+ current_rate);
/* Get CTSDuration_ba_f0 */
- pBuf->cts_duration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
- CTSDUR_BA_F0, cbFrameLength, byPktType,
- pDevice->tx_rate_fb0, bNeedAck, byFBOption);
+ buf->cts_duration_ba_f0 =
+ vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0,
+ tx_context->pkt_type,
+ priv->tx_rate_fb0);
/* Get CTSDuration_ba_f1 */
- pBuf->cts_duration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
- CTSDUR_BA_F1, cbFrameLength, byPktType,
- pDevice->tx_rate_fb1, bNeedAck, byFBOption);
+ buf->cts_duration_ba_f1 =
+ vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1,
+ tx_context->pkt_type,
+ priv->tx_rate_fb1);
/* Get CTS Frame body */
- pBuf->data.duration = pBuf->duration_ba;
- pBuf->data.frame_control =
+ buf->data.duration = buf->duration_ba;
+ buf->data.frame_control =
cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
- memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+ memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN);
- return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
- &pBuf->data_head, cbFrameLength, bNeedAck);
+ return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head);
} else {
- struct vnt_cts *pBuf = &head->cts_g;
+ struct vnt_cts *buf = &head->cts_g;
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(pDevice, uCTSFrameLen,
- pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
+ vnt_get_phy_field(priv, cts_frame_len,
+ priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b);
/* Get CTSDuration_ba */
- pBuf->duration_ba = s_uGetRTSCTSDuration(pDevice,
- CTSDUR_BA, cbFrameLength, byPktType,
- wCurrentRate, bNeedAck, byFBOption);
+ buf->duration_ba =
+ vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
+ tx_context->pkt_type,
+ current_rate);
/*Get CTS Frame body*/
- pBuf->data.duration = pBuf->duration_ba;
- pBuf->data.frame_control =
+ buf->data.duration = buf->duration_ba;
+ buf->data.frame_control =
cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
- memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+ memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN);
- return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
- &pBuf->data_head, cbFrameLength, bNeedAck);
+ return vnt_rxtx_datahead_g(tx_context, &buf->data_head);
}
return 0;
}
-/*+
- *
- * Description:
- * Generate FIFO control for MAC & Baseband controller
- *
- * Parameters:
- * In:
- * pDevice - Pointer to adpater
- * pTxDataHead - Transmit Data Buffer
- * pTxBufHead - pTxBufHead
- * pvRrvTime - pvRrvTime
- * pvRTS - RTS Buffer
- * pCTS - CTS Buffer
- * cbFrameSize - Transmit Data Length (Hdr+Payload+FCS)
- * bNeedACK - If need ACK
- * Out:
- * none
- *
- * Return Value: none
- *
--*/
+static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context,
+ union vnt_tx_head *tx_head, bool need_mic)
+{
+ struct vnt_private *priv = tx_context->priv;
+ struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts;
+ union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head;
+ u32 frame_len = tx_context->frame_len;
+ u16 current_rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
+ buf->rts_rrv_time_aa = vnt_get_rtscts_rsvtime_le(priv, 2,
+ tx_context->pkt_type, frame_len, current_rate);
+ buf->rts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 1,
+ tx_context->pkt_type, frame_len, current_rate);
+ buf->rts_rrv_time_bb = vnt_get_rtscts_rsvtime_le(priv, 0,
+ tx_context->pkt_type, frame_len, current_rate);
+
+ buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type,
+ frame_len, current_rate,
+ need_ack);
+ buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B, frame_len,
+ priv->top_cck_basic_rate, need_ack);
+
+ if (need_mic)
+ head = &tx_head->tx_rts.tx.mic.head;
+
+ if (tx_context->fb_option)
+ return vnt_rxtx_rts_g_fb_head(tx_context, &head->rts_g_fb);
+
+ return vnt_rxtx_rts_g_head(tx_context, &head->rts_g);
+}
-static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
- u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
- struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
- int bNeedACK, struct ethhdr *psEthHeader, bool need_rts)
+static u16 vnt_rxtx_cts(struct vnt_usb_send_context *tx_context,
+ union vnt_tx_head *tx_head, bool need_mic)
{
- struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head;
- union vnt_tx_data_head *head = NULL;
- u16 wFifoCtl;
- u8 byFBOption = AUTO_FB_NONE;
+ struct vnt_private *priv = tx_context->priv;
+ struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts;
+ union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head;
+ u32 frame_len = tx_context->frame_len;
+ u16 current_rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
+ buf->rrv_time_a = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type,
+ frame_len, current_rate, need_ack);
+ buf->rrv_time_b = vnt_rxtx_rsvtime_le16(priv, PK_TYPE_11B,
+ frame_len, priv->top_cck_basic_rate, need_ack);
+
+ buf->cts_rrv_time_ba = vnt_get_rtscts_rsvtime_le(priv, 3,
+ tx_context->pkt_type, frame_len, current_rate);
+
+ if (need_mic)
+ head = &tx_head->tx_cts.tx.mic.head;
+
+ /* Fill CTS */
+ return vnt_fill_cts_head(tx_context, head);
+}
- pFifoHead->current_rate = cpu_to_le16(wCurrentRate);
- wFifoCtl = pFifoHead->wFIFOCtl;
+static u16 vnt_rxtx_ab(struct vnt_usb_send_context *tx_context,
+ union vnt_tx_head *tx_head, bool need_rts, bool need_mic)
+{
+ struct vnt_private *priv = tx_context->priv;
+ struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab;
+ union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head;
+ u32 frame_len = tx_context->frame_len;
+ u16 current_rate = tx_context->tx_rate;
+ u8 need_ack = tx_context->need_ack;
+
+ buf->rrv_time = vnt_rxtx_rsvtime_le16(priv, tx_context->pkt_type,
+ frame_len, current_rate, need_ack);
+
+ if (need_mic)
+ head = &tx_head->tx_ab.tx.mic.head;
+
+ if (need_rts) {
+ if (tx_context->pkt_type == PK_TYPE_11B)
+ buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 0,
+ tx_context->pkt_type, frame_len, current_rate);
+ else /* PK_TYPE_11A */
+ buf->rts_rrv_time = vnt_get_rtscts_rsvtime_le(priv, 2,
+ tx_context->pkt_type, frame_len, current_rate);
+
+ if (tx_context->fb_option &&
+ tx_context->pkt_type == PK_TYPE_11A)
+ return vnt_rxtx_rts_a_fb_head(tx_context,
+ &head->rts_a_fb);
+
+ return vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab);
+ }
- if (wFifoCtl & FIFOCTL_AUTO_FB_0)
- byFBOption = AUTO_FB_0;
- else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
- byFBOption = AUTO_FB_1;
+ if (tx_context->pkt_type == PK_TYPE_11A)
+ return vnt_rxtx_datahead_a_fb(tx_context,
+ &head->data_head_a_fb);
- if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+ return vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab);
+}
+
+static u16 vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context,
+ struct vnt_tx_buffer *tx_buffer,
+ struct vnt_mic_hdr **mic_hdr, u32 need_mic,
+ bool need_rts)
+{
+
+ if (tx_context->pkt_type == PK_TYPE_11GB ||
+ tx_context->pkt_type == PK_TYPE_11GA) {
if (need_rts) {
- struct vnt_rrv_time_rts *pBuf =
- &tx_buffer->tx_head.tx_rts.rts;
-
- pBuf->rts_rrv_time_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
- byPktType, cbFrameSize, wCurrentRate);
- pBuf->rts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
- byPktType, cbFrameSize, wCurrentRate);
- pBuf->rts_rrv_time_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
- byPktType, cbFrameSize, wCurrentRate);
-
- pBuf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice,
- byPktType, cbFrameSize, wCurrentRate, bNeedACK);
- pBuf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice,
- PK_TYPE_11B, cbFrameSize,
- pDevice->byTopCCKBasicRate, bNeedACK);
-
- if (need_mic) {
+ if (need_mic)
*mic_hdr = &tx_buffer->
tx_head.tx_rts.tx.mic.hdr;
- head = &tx_buffer->tx_head.tx_rts.tx.mic.head;
- } else {
- head = &tx_buffer->tx_head.tx_rts.tx.head;
- }
-
- /* Fill RTS */
- return s_vFillRTSHead(pDevice, byPktType, head,
- cbFrameSize, bNeedACK, psEthHeader,
- wCurrentRate, byFBOption);
-
- } else {
- struct vnt_rrv_time_cts *pBuf = &tx_buffer->
- tx_head.tx_cts.cts;
-
- pBuf->rrv_time_a = vnt_rxtx_rsvtime_le16(pDevice,
- byPktType, cbFrameSize, wCurrentRate, bNeedACK);
- pBuf->rrv_time_b = vnt_rxtx_rsvtime_le16(pDevice,
- PK_TYPE_11B, cbFrameSize,
- pDevice->byTopCCKBasicRate, bNeedACK);
-
- pBuf->cts_rrv_time_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
- byPktType, cbFrameSize, wCurrentRate);
-
- if (need_mic) {
- *mic_hdr = &tx_buffer->
- tx_head.tx_cts.tx.mic.hdr;
- head = &tx_buffer->tx_head.tx_cts.tx.mic.head;
- } else {
- head = &tx_buffer->tx_head.tx_cts.tx.head;
- }
-
- /* Fill CTS */
- return s_vFillCTSHead(pDevice, byPktType,
- head, cbFrameSize, bNeedACK, wCurrentRate,
- byFBOption);
- }
- } else if (byPktType == PK_TYPE_11A) {
- if (need_mic) {
- *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
- head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
- } else {
- head = &tx_buffer->tx_head.tx_ab.tx.head;
- }
- if (need_rts) {
- struct vnt_rrv_time_ab *pBuf = &tx_buffer->
- tx_head.tx_ab.ab;
-
- pBuf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 2,
- byPktType, cbFrameSize, wCurrentRate);
-
- pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice,
- byPktType, cbFrameSize, wCurrentRate, bNeedACK);
-
- /* Fill RTS */
- return s_vFillRTSHead(pDevice, byPktType, head,
- cbFrameSize, bNeedACK, psEthHeader,
- wCurrentRate, byFBOption);
- } else {
- struct vnt_rrv_time_ab *pBuf = &tx_buffer->
- tx_head.tx_ab.ab;
-
- pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice,
- PK_TYPE_11A, cbFrameSize,
- wCurrentRate, bNeedACK);
-
- return vnt_rxtx_datahead_a_fb(pDevice, byPktType,
- wCurrentRate, &head->data_head_a_fb,
- cbFrameSize, bNeedACK);
- }
- } else if (byPktType == PK_TYPE_11B) {
- if (need_mic) {
- *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
- head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
- } else {
- head = &tx_buffer->tx_head.tx_ab.tx.head;
+ return vnt_rxtx_rts(tx_context, &tx_buffer->tx_head,
+ need_mic);
}
- if (need_rts) {
- struct vnt_rrv_time_ab *pBuf = &tx_buffer->
- tx_head.tx_ab.ab;
-
- pBuf->rts_rrv_time = s_uGetRTSCTSRsvTime(pDevice, 0,
- byPktType, cbFrameSize, wCurrentRate);
-
- pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice,
- PK_TYPE_11B, cbFrameSize, wCurrentRate,
- bNeedACK);
-
- /* Fill RTS */
- return s_vFillRTSHead(pDevice, byPktType, head,
- cbFrameSize,
- bNeedACK, psEthHeader, wCurrentRate, byFBOption);
- } else {
- struct vnt_rrv_time_ab *pBuf = &tx_buffer->
- tx_head.tx_ab.ab;
-
- pBuf->rrv_time = vnt_rxtx_rsvtime_le16(pDevice,
- PK_TYPE_11B, cbFrameSize,
- wCurrentRate, bNeedACK);
-
- return vnt_rxtx_datahead_ab(pDevice, byPktType,
- wCurrentRate, &head->data_head_ab,
- cbFrameSize, bNeedACK);
- }
+ if (need_mic)
+ *mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr;
+
+ return vnt_rxtx_cts(tx_context, &tx_buffer->tx_head, need_mic);
}
- return 0;
+ if (need_mic)
+ *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+
+ return vnt_rxtx_ab(tx_context, &tx_buffer->tx_head, need_rts, need_mic);
}
-/*
- u8 * pbyBuffer,//point to pTxBufHead
- u16 wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
- unsigned int cbFragmentSize,//Hdr+payoad+FCS
-*/
-
-static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
- struct vnt_tx_buffer *tx_buffer, int bNeedEncryption,
- u32 uSkbPacketLen, struct ethhdr *psEthHeader,
- u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate,
- u32 *pcbHeaderLen, u32 *pcbTotalLen)
-{
- struct vnt_tx_fifo_head *pTxBufHead = &tx_buffer->fifo_head;
- u32 cbFrameSize, cbFrameBodySize;
- u32 cb802_1_H_len;
- u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbMACHdLen = 0;
- u32 cbFCSlen = 4, cbMICHDR = 0;
- int bNeedACK;
- bool bRTS = false;
- u8 *pbyType, *pbyMacHdr, *pbyIVHead, *pbyPayloadHead, *pbyTxBufferAddr;
- u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
- u8 abySNAP_Bridgetunnel[ETH_ALEN]
- = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
- u32 uDuration;
- u32 cbHeaderLength = 0, uPadding = 0;
- struct vnt_mic_hdr *pMICHDR;
- u8 byFBOption = AUTO_FB_NONE, byFragType;
- u16 wTxBufSize;
- u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
- u32 *pdwMIC_L, *pdwMIC_R;
- int bSoftWEP = false;
-
- pMICHDR = NULL;
-
- if (bNeedEncryption && pTransmitKey->pvKeyTable) {
- if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
- bSoftWEP = true; /* WEP 256 */
- }
- /* Get pkt type */
- if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN)
- cb802_1_H_len = 8;
- else
- cb802_1_H_len = 0;
-
- cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len;
-
- //Set packet type
- pTxBufHead->wFIFOCtl |= (u16)(byPktType<<8);
-
- if (pDevice->op_mode == NL80211_IFTYPE_ADHOC ||
- pDevice->op_mode == NL80211_IFTYPE_AP) {
- if (is_multicast_ether_addr(psEthHeader->h_dest)) {
- bNeedACK = false;
- pTxBufHead->wFIFOCtl =
- pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
- } else {
- bNeedACK = true;
- pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context,
+ u8 *key_buffer, struct ieee80211_key_conf *tx_key, struct sk_buff *skb,
+ u16 payload_len, struct vnt_mic_hdr *mic_hdr)
+{
+ struct ieee80211_hdr *hdr = tx_context->hdr;
+ struct ieee80211_key_seq seq;
+ u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
+
+ /* strip header and icv len from payload */
+ payload_len -= ieee80211_get_hdrlen_from_skb(skb);
+ payload_len -= tx_key->icv_len;
+
+ switch (tx_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ memcpy(key_buffer, iv, 3);
+ memcpy(key_buffer + 3, tx_key->key, tx_key->keylen);
+
+ if (tx_key->keylen == WLAN_KEY_LEN_WEP40) {
+ memcpy(key_buffer + 8, iv, 3);
+ memcpy(key_buffer + 11,
+ tx_key->key, WLAN_KEY_LEN_WEP40);
}
- } else {
- /* MSDUs in Infra mode always need ACK */
- bNeedACK = true;
- pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
- }
- pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ ieee80211_get_tkip_p2k(tx_key, skb, key_buffer);
- //Set FRAGCTL_MACHDCNT
- cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
- pTxBufHead->wFragCtl |= (u16)(cbMACHdLen << 10);
+ if (!mic_hdr)
+ return;
- //Set FIFOCTL_GrpAckPolicy
- if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
- pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
- }
+ mic_hdr->id = 0x59;
+ mic_hdr->payload_len = cpu_to_be16(payload_len);
+ memcpy(mic_hdr->mic_addr2, hdr->addr2, ETH_ALEN);
- /* Set Auto Fallback Ctl */
- if (wCurrentRate >= RATE_18M) {
- if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
- pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+ ieee80211_get_key_tx_seq(tx_key, &seq);
- pDevice->tx_rate_fb0 =
- wFB_Opt0[FB_RATE0][wCurrentRate - RATE_18M];
- pDevice->tx_rate_fb1 =
- wFB_Opt0[FB_RATE1][wCurrentRate - RATE_18M];
+ memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
- byFBOption = AUTO_FB_0;
- } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
- pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
- pDevice->tx_rate_fb0 =
- wFB_Opt1[FB_RATE0][wCurrentRate - RATE_18M];
- pDevice->tx_rate_fb1 =
- wFB_Opt1[FB_RATE1][wCurrentRate - RATE_18M];
+ if (ieee80211_has_a4(hdr->frame_control))
+ mic_hdr->hlen = cpu_to_be16(28);
+ else
+ mic_hdr->hlen = cpu_to_be16(22);
- byFBOption = AUTO_FB_1;
- }
- }
+ memcpy(mic_hdr->addr1, hdr->addr1, ETH_ALEN);
+ memcpy(mic_hdr->addr2, hdr->addr2, ETH_ALEN);
+ memcpy(mic_hdr->addr3, hdr->addr3, ETH_ALEN);
- if (bSoftWEP != true) {
- if ((bNeedEncryption) && (pTransmitKey != NULL)) { //WEP enabled
- if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
- pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
- }
- if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
- pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
- }
- else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
- pTxBufHead->wFragCtl |= FRAGCTL_AES;
- }
- }
- }
+ mic_hdr->frame_control = cpu_to_le16(
+ le16_to_cpu(hdr->frame_control) & 0xc78f);
+ mic_hdr->seq_ctrl = cpu_to_le16(
+ le16_to_cpu(hdr->seq_ctrl) & 0xf);
+
+ if (ieee80211_has_a4(hdr->frame_control))
+ memcpy(mic_hdr->addr4, hdr->addr4, ETH_ALEN);
- if ((bNeedEncryption) && (pTransmitKey != NULL)) {
- if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
- cbIVlen = 4;
- cbICVlen = 4;
- }
- else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
- cbIVlen = 8;//IV+ExtIV
- cbMIClen = 8;
- cbICVlen = 4;
- }
- if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
- cbIVlen = 8;//RSN Header
- cbICVlen = 8;//MIC
- cbMICHDR = sizeof(struct vnt_mic_hdr);
- }
- if (bSoftWEP == false) {
- //MAC Header should be padding 0 to DW alignment.
- uPadding = 4 - (cbMACHdLen%4);
- uPadding %= 4;
- }
- }
-
- cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
-
- if ( (bNeedACK == false) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
- bRTS = false;
- } else {
- bRTS = true;
- pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
- }
-
- pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
- wTxBufSize = sizeof(struct vnt_tx_fifo_head);
-
- if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
- if (byFBOption == AUTO_FB_NONE) {
- if (bRTS == true) {//RTS_need
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
- cbMICHDR + sizeof(struct vnt_rts_g);
- }
- else { //RTS_needless
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
- cbMICHDR + sizeof(struct vnt_cts);
- }
- } else {
- // Auto Fall Back
- if (bRTS == true) {//RTS_need
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
- cbMICHDR + sizeof(struct vnt_rts_g_fb);
- }
- else if (bRTS == false) { //RTS_needless
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
- cbMICHDR + sizeof(struct vnt_cts_fb);
- }
- } // Auto Fall Back
- }
- else {//802.11a/b packet
- if (byFBOption == AUTO_FB_NONE) {
- if (bRTS == true) {//RTS_need
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
- cbMICHDR + sizeof(struct vnt_rts_ab);
- }
- else if (bRTS == false) { //RTS_needless, no MICHDR
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
- cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
- }
- } else {
- // Auto Fall Back
- if (bRTS == true) {//RTS_need
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
- cbMICHDR + sizeof(struct vnt_rts_a_fb);
- }
- else if (bRTS == false) { //RTS_needless
- cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
- cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
- }
- } // Auto Fall Back
- }
-
- pbyMacHdr = (u8 *)(pbyTxBufferAddr + cbHeaderLength);
- pbyIVHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding);
- pbyPayloadHead = (u8 *)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
-
- //=========================
- // No Fragmentation
- //=========================
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
- byFragType = FRAGCTL_NONFRAG;
- //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
-
- /* Fill FIFO, RrvTime, RTS and CTS */
- uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
- tx_buffer, &pMICHDR, cbMICHDR,
- cbFrameSize, bNeedACK, psEthHeader, bRTS);
-
- // Generate TX MAC Header
- s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
- byFragType, 0);
-
- if (bNeedEncryption == true) {
- //Fill TXKEY
- s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
- pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
- }
-
- /* 802.1H */
- if (ntohs(psEthHeader->h_proto) > ETH_DATA_LEN) {
- if ((psEthHeader->h_proto == cpu_to_be16(ETH_P_IPX)) ||
- (psEthHeader->h_proto == cpu_to_le16(0xF380)))
- memcpy((u8 *) (pbyPayloadHead),
- abySNAP_Bridgetunnel, 6);
- else
- memcpy((u8 *) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
- pbyType = (u8 *) (pbyPayloadHead + 6);
+ memcpy(key_buffer, tx_key->key, WLAN_KEY_LEN_CCMP);
- memcpy(pbyType, &(psEthHeader->h_proto), sizeof(u16));
+ break;
+ default:
+ break;
}
- if (pPacket != NULL) {
- // Copy the Packet into a tx Buffer
- memcpy((pbyPayloadHead + cb802_1_H_len),
- (pPacket + ETH_HLEN),
- uSkbPacketLen - ETH_HLEN
- );
+}
- } else {
- // while bRelayPacketSend psEthHeader is point to header+payload
- memcpy((pbyPayloadHead + cb802_1_H_len), ((u8 *)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN);
- }
+int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *tx_rate = &info->control.rates[0];
+ struct ieee80211_rate *rate;
+ struct ieee80211_key_conf *tx_key;
+ struct ieee80211_hdr *hdr;
+ struct vnt_mic_hdr *mic_hdr = NULL;
+ struct vnt_tx_buffer *tx_buffer;
+ struct vnt_tx_fifo_head *tx_buffer_head;
+ struct vnt_usb_send_context *tx_context;
+ unsigned long flags;
+ u16 tx_bytes, tx_header_size, tx_body_size, current_rate, duration_id;
+ u8 pkt_type, fb_option = AUTO_FB_NONE;
+ bool need_rts = false, is_pspoll = false;
+ bool need_mic = false;
- if ((bNeedEncryption == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+ hdr = (struct ieee80211_hdr *)(skb->data);
- ///////////////////////////////////////////////////////////////////
+ rate = ieee80211_get_tx_rate(priv->hw, info);
- if (pDevice->vnt_mgmt.eAuthenMode == WMAC_AUTH_WPANONE) {
- dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
- dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
+ current_rate = rate->hw_value;
+ if (priv->current_rate != current_rate &&
+ !(priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
+ priv->current_rate = current_rate;
+ vnt_schedule_command(priv, WLAN_CMD_SETPOWER);
}
- else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
- dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[16]);
- dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[20]);
- }
- else {
- dwMICKey0 = *(u32 *)(&pTransmitKey->abyKey[24]);
- dwMICKey1 = *(u32 *)(&pTransmitKey->abyKey[28]);
- }
- // DO Software Michael
- MIC_vInit(dwMICKey0, dwMICKey1);
- MIC_vAppend((u8 *)&(psEthHeader->h_dest[0]), 12);
- dwMIC_Priority = 0;
- MIC_vAppend((u8 *)&dwMIC_Priority, 4);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
- dwMICKey0, dwMICKey1);
-
- ///////////////////////////////////////////////////////////////////
-
- //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
- //for (ii = 0; ii < cbFrameBodySize; ii++) {
- // DBG_PRN_GRP12(("%02x ", *((u8 *)((pbyPayloadHead + cb802_1_H_len) + ii))));
- //}
- //DBG_PRN_GRP12(("\n\n\n"));
-
- MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
-
- pdwMIC_L = (u32 *)(pbyPayloadHead + cbFrameBodySize);
- pdwMIC_R = (u32 *)(pbyPayloadHead + cbFrameBodySize + 4);
-
- MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
- MIC_vUnInit();
-
- if (pDevice->bTxMICFail == true) {
- *pdwMIC_L = 0;
- *pdwMIC_R = 0;
- pDevice->bTxMICFail = false;
- }
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
- }
- if (bSoftWEP == true) {
+ if (current_rate > RATE_11M)
+ pkt_type = priv->packet_type;
+ else
+ pkt_type = PK_TYPE_11B;
- s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (u16)(cbFrameBodySize + cbMIClen));
+ spin_lock_irqsave(&priv->lock, flags);
- } else if ( ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == true)) ||
- ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == true)) ||
- ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == true)) ) {
- cbFrameSize -= cbICVlen;
- }
+ tx_context = vnt_get_free_context(priv);
+ if (!tx_context) {
+ dev_dbg(&priv->usb->dev, "%s No free context\n", __func__);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -ENOMEM;
+ }
- cbFrameSize -= cbFCSlen;
+ tx_context->skb = skb;
+ tx_context->pkt_type = pkt_type;
+ tx_context->need_ack = false;
+ tx_context->frame_len = skb->len + 4;
+ tx_context->tx_rate = current_rate;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ tx_buffer = (struct vnt_tx_buffer *)tx_context->data;
+ tx_buffer_head = &tx_buffer->fifo_head;
+ tx_body_size = skb->len;
+
+ /*Set fifo controls */
+ if (pkt_type == PK_TYPE_11A)
+ tx_buffer_head->fifo_ctl = 0;
+ else if (pkt_type == PK_TYPE_11B)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B);
+ else if (pkt_type == PK_TYPE_11GB)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB);
+ else if (pkt_type == PK_TYPE_11GA)
+ tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA);
+
+ if (!ieee80211_is_data(hdr->frame_control)) {
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT |
+ FIFOCTL_ISDMA0);
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN);
+
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+ } else {
+ tx_buffer_head->time_stamp =
+ cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us);
+ }
- *pcbHeaderLen = cbHeaderLength;
- *pcbTotalLen = cbHeaderLength + cbFrameSize ;
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK);
+ tx_context->need_ack = true;
+ }
- //Set FragCtl in TxBufferHead
- pTxBufHead->wFragCtl |= (u16)byFragType;
+ if (ieee80211_has_retry(hdr->frame_control))
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY);
- return true;
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ priv->preamble_type = PREAMBLE_SHORT;
+ else
+ priv->preamble_type = PREAMBLE_LONG;
-}
+ if (tx_rate->flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ need_rts = true;
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS);
+ }
-/*+
- *
- * Description:
- * Translate 802.3 to 802.11 header
- *
- * Parameters:
- * In:
- * pDevice - Pointer to adapter
- * dwTxBufferAddr - Transmit Buffer
- * pPacket - Packet from upper layer
- * cbPacketSize - Transmit Data Length
- * Out:
- * pcbHeadSize - Header size of MAC&Baseband control and 802.11 Header
- * pcbAppendPayload - size of append payload for 802.1H translation
- *
- * Return Value: none
- *
--*/
+ if (ieee80211_has_a4(hdr->frame_control))
+ tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD);
-static void s_vGenerateMACHeader(struct vnt_private *pDevice,
- u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
- int bNeedEncrypt, u16 wFragType, u32 uFragIdx)
-{
- struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyBufferAddr;
-
- pMACHeader->frame_control = TYPE_802_11_DATA;
-
- if (pDevice->op_mode == NL80211_IFTYPE_AP) {
- memcpy(&(pMACHeader->addr1[0]),
- &(psEthHeader->h_dest[0]),
- ETH_ALEN);
- memcpy(&(pMACHeader->addr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN);
- memcpy(&(pMACHeader->addr3[0]),
- &(psEthHeader->h_source[0]),
- ETH_ALEN);
- pMACHeader->frame_control |= FC_FROMDS;
- } else {
- if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
- memcpy(&(pMACHeader->addr1[0]),
- &(psEthHeader->h_dest[0]),
- ETH_ALEN);
- memcpy(&(pMACHeader->addr2[0]),
- &(psEthHeader->h_source[0]),
- ETH_ALEN);
- memcpy(&(pMACHeader->addr3[0]),
- &(pDevice->abyBSSID[0]),
- ETH_ALEN);
- } else {
- memcpy(&(pMACHeader->addr3[0]),
- &(psEthHeader->h_dest[0]),
- ETH_ALEN);
- memcpy(&(pMACHeader->addr2[0]),
- &(psEthHeader->h_source[0]),
- ETH_ALEN);
- memcpy(&(pMACHeader->addr1[0]),
- &(pDevice->abyBSSID[0]),
- ETH_ALEN);
- pMACHeader->frame_control |= FC_TODS;
- }
- }
+ if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
+ is_pspoll = true;
- if (bNeedEncrypt)
- pMACHeader->frame_control |= cpu_to_le16((u16)WLAN_SET_FC_ISWEP(1));
+ tx_buffer_head->frag_ctl =
+ cpu_to_le16(ieee80211_get_hdrlen_from_skb(skb) << 10);
- pMACHeader->duration_id = cpu_to_le16(wDuration);
+ if (info->control.hw_key) {
+ tx_key = info->control.hw_key;
+ switch (info->control.hw_key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_AES);
+ need_mic = true;
+ default:
+ break;
+ }
+ tx_context->frame_len += tx_key->icv_len;
+ }
- pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
+ tx_buffer_head->current_rate = cpu_to_le16(current_rate);
- //Set FragNumber in Sequence Control
- pMACHeader->seq_ctrl |= cpu_to_le16((u16)uFragIdx);
+ /* legacy rates TODO use ieee80211_tx_rate */
+ if (current_rate >= RATE_18M && ieee80211_is_data(hdr->frame_control)) {
+ if (priv->auto_fb_ctrl == AUTO_FB_0) {
+ tx_buffer_head->fifo_ctl |=
+ cpu_to_le16(FIFOCTL_AUTO_FB_0);
- if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
- pDevice->wSeqCounter++;
- if (pDevice->wSeqCounter > 0x0fff)
- pDevice->wSeqCounter = 0;
- }
+ priv->tx_rate_fb0 =
+ vnt_fb_opt0[FB_RATE0][current_rate - RATE_18M];
+ priv->tx_rate_fb1 =
+ vnt_fb_opt0[FB_RATE1][current_rate - RATE_18M];
- if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
- pMACHeader->frame_control |= FC_MOREFRAG;
- }
-}
+ fb_option = AUTO_FB_0;
+ } else if (priv->auto_fb_ctrl == AUTO_FB_1) {
+ tx_buffer_head->fifo_ctl |=
+ cpu_to_le16(FIFOCTL_AUTO_FB_1);
-/*+
- *
- * Description:
- * Request instructs a MAC to transmit a 802.11 management packet through
- * the adapter onto the medium.
- *
- * Parameters:
- * In:
- * hDeviceContext - Pointer to the adapter
- * pPacket - A pointer to a descriptor for the packet to transmit
- * Out:
- * none
- *
- * Return Value: CMD_STATUS_PENDING if MAC Tx resource available; otherwise false
- *
--*/
+ priv->tx_rate_fb0 =
+ vnt_fb_opt1[FB_RATE0][current_rate - RATE_18M];
+ priv->tx_rate_fb1 =
+ vnt_fb_opt1[FB_RATE1][current_rate - RATE_18M];
-CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
- struct vnt_tx_mgmt *pPacket)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_tx_buffer *pTX_Buffer;
- struct vnt_usb_send_context *pContext;
- struct vnt_tx_fifo_head *pTxBufHead;
- struct ieee80211_hdr *pMACHeader;
- struct ethhdr sEthHeader;
- u8 byPktType, *pbyTxBufferAddr;
- struct vnt_mic_hdr *pMICHDR = NULL;
- u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
- int bNeedACK, bIsPSPOLL = false;
- u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
- u32 uPadding = 0;
- u16 wTxBufSize;
- u32 cbMacHdLen;
- u16 wCurrentRate = RATE_1M;
- unsigned long flags;
+ fb_option = AUTO_FB_1;
+ }
+ }
- if (pDevice->byBBType == BB_TYPE_11A) {
- wCurrentRate = RATE_6M;
- byPktType = PK_TYPE_11A;
- } else {
- wCurrentRate = RATE_1M;
- byPktType = PK_TYPE_11B;
+ tx_context->fb_option = fb_option;
+
+ duration_id = vnt_generate_tx_parameter(tx_context, tx_buffer, &mic_hdr,
+ need_mic, need_rts);
+
+ tx_header_size = tx_context->tx_hdr_size;
+ if (!tx_header_size) {
+ tx_context->in_use = false;
+ return -ENOMEM;
}
- if (pMgmt->eScanState != WMAC_NO_SCANNING)
- vnt_rf_setpower(pDevice, wCurrentRate, pDevice->byCurrentCh);
- else
- vnt_rf_setpower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+ tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG);
- pDevice->wCurrentRate = wCurrentRate;
+ tx_bytes = tx_header_size + tx_body_size;
- spin_lock_irqsave(&pDevice->lock, flags);
+ memcpy(tx_context->hdr, skb->data, tx_body_size);
- pContext = s_vGetFreeContext(pDevice);
- if (!pContext) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
- "ManagementSend TX...NO CONTEXT!\n");
- spin_unlock_irqrestore(&pDevice->lock, flags);
- return CMD_STATUS_RESOURCES;
- }
+ hdr->duration_id = cpu_to_le16(duration_id);
- pTX_Buffer = (struct vnt_tx_buffer *)&pContext->data[0];
- cbFrameBodySize = pPacket->cbPayloadLen;
- pTxBufHead = &pTX_Buffer->fifo_head;
- pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
- wTxBufSize = sizeof(struct vnt_tx_fifo_head);
-
-
- //Set packet type
- if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
- pTxBufHead->wFIFOCtl = 0;
- }
- else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
- pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
- }
- else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
- pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
- }
- else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
- pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
- }
-
- pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
- pTxBufHead->time_stamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
-
- if (is_multicast_ether_addr(pPacket->p80211Header->sA3.abyAddr1)) {
- bNeedACK = false;
- }
- else {
- bNeedACK = true;
- pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
- };
-
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
- (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
-
- pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
- //Set Preamble type always long
- //pDevice->byPreambleType = PREAMBLE_LONG;
- // probe-response don't retry
- //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
- // bNeedACK = false;
- // pTxBufHead->wFIFOCtl &= (~FIFOCTL_NEEDACK);
- //}
- }
-
- pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
-
- if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
- bIsPSPOLL = true;
- cbMacHdLen = WLAN_HDR_ADDR2_LEN;
- } else {
- cbMacHdLen = WLAN_HDR_ADDR3_LEN;
- }
-
- //Set FRAGCTL_MACHDCNT
- pTxBufHead->wFragCtl |= cpu_to_le16((u16)(cbMacHdLen << 10));
-
- // Notes:
- // Although spec says MMPDU can be fragmented; In most case,
- // no one will send a MMPDU under fragmentation. With RTS may occur.
-
- if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
- cbIVlen = 4;
- cbICVlen = 4;
- pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
- }
- else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
- cbIVlen = 8;//IV+ExtIV
- cbMIClen = 8;
- cbICVlen = 4;
- pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
- //We need to get seed here for filling TxKey entry.
- //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
- // pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
- }
- else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
- cbIVlen = 8;//RSN Header
- cbICVlen = 8;//MIC
- pTxBufHead->wFragCtl |= FRAGCTL_AES;
- }
- //MAC Header should be padding 0 to DW alignment.
- uPadding = 4 - (cbMacHdLen%4);
- uPadding %= 4;
- }
-
- cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
-
- //Set FIFOCTL_GrpAckPolicy
- if (pDevice->bGrpAckPolicy == true) {//0000 0100 0000 0000
- pTxBufHead->wFIFOCtl |= FIFOCTL_GRPACK;
- }
- //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
-
- //Set RrvTime/RTS/CTS Buffer
- if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
- cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
- sizeof(struct vnt_cts);
- }
- else { // 802.11a/b packet
- cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
- sizeof(struct vnt_tx_datahead_ab);
- }
-
- memcpy(&(sEthHeader.h_dest[0]),
- &(pPacket->p80211Header->sA3.abyAddr1[0]),
- ETH_ALEN);
- memcpy(&(sEthHeader.h_source[0]),
- &(pPacket->p80211Header->sA3.abyAddr2[0]),
- ETH_ALEN);
- //=========================
- // No Fragmentation
- //=========================
- pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
-
- /* Fill FIFO,RrvTime,RTS,and CTS */
- uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
- pTX_Buffer, &pMICHDR, 0,
- cbFrameSize, bNeedACK, &sEthHeader, false);
-
- pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
-
- cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
-
- if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
- u8 * pbyIVHead;
- u8 * pbyPayloadHead;
- u8 * pbyBSSID;
- PSKeyItem pTransmitKey = NULL;
-
- pbyIVHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
- pbyPayloadHead = (u8 *)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
- do {
- if (pDevice->op_mode == NL80211_IFTYPE_STATION &&
- pDevice->bLinkPass == true) {
- pbyBSSID = pDevice->abyBSSID;
- // get pairwise key
- if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
- // get group key
- if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
- break;
- }
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
- break;
- }
- }
- // get group key
- pbyBSSID = pDevice->abyBroadcastAddr;
- if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
- pTransmitKey = NULL;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->op_mode);
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
- }
- } while(false);
- //Fill TXKEY
- s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
- (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
-
- memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
- memcpy(pbyPayloadHead, ((u8 *)(pPacket->p80211Header) + cbMacHdLen),
- cbFrameBodySize);
- }
- else {
- // Copy the Packet into a tx Buffer
- memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
- }
-
- pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
- pDevice->wSeqCounter++ ;
- if (pDevice->wSeqCounter > 0x0fff)
- pDevice->wSeqCounter = 0;
-
- if (bIsPSPOLL) {
- // The MAC will automatically replace the Duration-field of MAC header by Duration-field
- // of FIFO control header.
- // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
- // in the same place of other packet's Duration-field).
- // And it will cause Cisco-AP to issue Disassociation-packet
- if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
- struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
- tx_cts.tx.head.cts_g.data_head;
- data_head->duration_a =
- cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
- data_head->duration_b =
- cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
- } else {
- struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
- tx_ab.tx.head.data_head_ab;
- data_head->duration =
- cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+ if (info->control.hw_key) {
+ tx_key = info->control.hw_key;
+ if (tx_key->keylen > 0)
+ vnt_fill_txkey(tx_context, tx_buffer_head->tx_key,
+ tx_key, skb, tx_body_size, mic_hdr);
}
- }
- pTX_Buffer->tx_byte_count = cpu_to_le16((u16)(cbReqCount));
- pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
- pTX_Buffer->byType = 0x00;
+ priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) &
+ IEEE80211_SCTL_SEQ) >> 4;
- pContext->skb = NULL;
- pContext->type = CONTEXT_MGMT_PACKET;
- pContext->buf_len = (u16)cbReqCount + 4; /* USB header */
+ tx_buffer->tx_byte_count = cpu_to_le16(tx_bytes);
+ tx_buffer->pkt_no = tx_context->pkt_no;
+ tx_buffer->type = 0x00;
- if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
- s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
- &pMACHeader->addr1[0], (u16)cbFrameSize,
- pTxBufHead->wFIFOCtl);
- }
- else {
- s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
- &pMACHeader->addr3[0], (u16)cbFrameSize,
- pTxBufHead->wFIFOCtl);
- }
+ tx_bytes += 4;
- PIPEnsSendBulkOut(pDevice,pContext);
+ tx_context->type = CONTEXT_DATA_PACKET;
+ tx_context->buf_len = tx_bytes;
- spin_unlock_irqrestore(&pDevice->lock, flags);
+ spin_lock_irqsave(&priv->lock, flags);
- return CMD_STATUS_PENDING;
+ if (vnt_tx_context(priv, tx_context) != STATUS_PENDING) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -EIO;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
}
-CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice,
- struct vnt_tx_mgmt *pPacket)
+static int vnt_beacon_xmit(struct vnt_private *priv,
+ struct sk_buff *skb)
{
- struct vnt_beacon_buffer *pTX_Buffer;
+ struct vnt_beacon_buffer *beacon_buffer;
struct vnt_tx_short_buf_head *short_head;
- u32 cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
- u32 cbHeaderSize = 0;
- struct ieee80211_hdr *pMACHeader;
- u16 wCurrentRate;
- u32 cbFrameBodySize;
- u32 cbReqCount;
- struct vnt_usb_send_context *pContext;
- CMD_STATUS status;
+ struct ieee80211_tx_info *info;
+ struct vnt_usb_send_context *context;
+ struct ieee80211_mgmt *mgmt_hdr;
+ unsigned long flags;
+ u32 frame_size = skb->len + 4;
+ u16 current_rate, count;
+
+ spin_lock_irqsave(&priv->lock, flags);
- pContext = s_vGetFreeContext(pDevice);
- if (NULL == pContext) {
- status = CMD_STATUS_RESOURCES;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
- return status ;
- }
+ context = vnt_get_free_context(priv);
+ if (!context) {
+ dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return -ENOMEM;
+ }
- pTX_Buffer = (struct vnt_beacon_buffer *)&pContext->data[0];
- short_head = &pTX_Buffer->short_head;
+ context->skb = skb;
- cbFrameBodySize = pPacket->cbPayloadLen;
+ spin_unlock_irqrestore(&priv->lock, flags);
- cbHeaderSize = sizeof(struct vnt_tx_short_buf_head);
+ beacon_buffer = (struct vnt_beacon_buffer *)&context->data[0];
+ short_head = &beacon_buffer->short_head;
- if (pDevice->byBBType == BB_TYPE_11A) {
- wCurrentRate = RATE_6M;
+ if (priv->bb_type == BB_TYPE_11A) {
+ current_rate = RATE_6M;
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
+ vnt_get_phy_field(priv, frame_size, current_rate,
PK_TYPE_11A, &short_head->ab);
/* Get Duration and TimeStampOff */
- short_head->duration = s_uGetDataDuration(pDevice,
+ short_head->duration = vnt_get_duration_le(priv,
PK_TYPE_11A, false);
short_head->time_stamp_off =
- vnt_time_stamp_off(pDevice, wCurrentRate);
+ vnt_time_stamp_off(priv, current_rate);
} else {
- wCurrentRate = RATE_1M;
- short_head->fifo_ctl |= FIFOCTL_11B;
+ current_rate = RATE_1M;
+ short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B);
/* Get SignalField,ServiceField,Length */
- BBvCalculateParameter(pDevice, cbFrameSize, wCurrentRate,
+ vnt_get_phy_field(priv, frame_size, current_rate,
PK_TYPE_11B, &short_head->ab);
/* Get Duration and TimeStampOff */
- short_head->duration = s_uGetDataDuration(pDevice,
+ short_head->duration = vnt_get_duration_le(priv,
PK_TYPE_11B, false);
short_head->time_stamp_off =
- vnt_time_stamp_off(pDevice, wCurrentRate);
+ vnt_time_stamp_off(priv, current_rate);
}
-
/* Generate Beacon Header */
- pMACHeader = &pTX_Buffer->hdr;
-
- memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
-
- pMACHeader->duration_id = 0;
- pMACHeader->seq_ctrl = cpu_to_le16(pDevice->wSeqCounter << 4);
- pDevice->wSeqCounter++;
- if (pDevice->wSeqCounter > 0x0fff)
- pDevice->wSeqCounter = 0;
-
- cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
+ mgmt_hdr = &beacon_buffer->mgmt_hdr;
+ memcpy(mgmt_hdr, skb->data, skb->len);
- pTX_Buffer->tx_byte_count = cpu_to_le16((u16)cbReqCount);
- pTX_Buffer->byPKTNO = (u8) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
- pTX_Buffer->byType = 0x01;
+ /* time stamp always 0 */
+ mgmt_hdr->u.beacon.timestamp = 0;
- pContext->skb = NULL;
- pContext->type = CONTEXT_MGMT_PACKET;
- pContext->buf_len = (u16)cbReqCount + 4; /* USB header */
+ info = IEEE80211_SKB_CB(skb);
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr;
+ hdr->duration_id = 0;
+ hdr->seq_ctrl = cpu_to_le16(priv->seq_counter << 4);
+ }
- PIPEnsSendBulkOut(pDevice,pContext);
- return CMD_STATUS_PENDING;
+ priv->seq_counter++;
+ if (priv->seq_counter > 0x0fff)
+ priv->seq_counter = 0;
-}
+ count = sizeof(struct vnt_tx_short_buf_head) + skb->len;
-//TYPE_AC0DMA data tx
-/*
- * Description:
- * Tx packet via AC0DMA(DMA1)
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * skb - Pointer to tx skb packet
- * Out:
- * void
- *
- * Return Value: NULL
- */
+ beacon_buffer->tx_byte_count = cpu_to_le16(count);
+ beacon_buffer->pkt_no = context->pkt_no;
+ beacon_buffer->type = 0x01;
-int nsDMA_tx_packet(struct vnt_private *pDevice, struct sk_buff *skb)
-{
- struct net_device_stats *pStats = &pDevice->stats;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_tx_buffer *pTX_Buffer;
- u32 BytesToWrite = 0, uHeaderLen = 0;
- u32 uNodeIndex = 0;
- u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
- u16 wAID;
- u8 byPktType;
- int bNeedEncryption = false;
- PSKeyItem pTransmitKey = NULL;
- int ii;
- int bTKIP_UseGTK = false;
- int bNeedDeAuth = false;
- u8 *pbyBSSID;
- int bNodeExist = false;
- struct vnt_usb_send_context *pContext;
- bool fConvertedPacket;
- u32 status;
- u16 wKeepRate = pDevice->wCurrentRate;
- int bTxeapol_key = false;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
-
- if (pDevice->uAssocCount == 0) {
- dev_kfree_skb_irq(skb);
- return 0;
- }
+ context->type = CONTEXT_BEACON_PACKET;
+ context->buf_len = count + 4; /* USB header */
- if (is_multicast_ether_addr((u8 *)(skb->data))) {
- uNodeIndex = 0;
- bNodeExist = true;
- if (pMgmt->sNodeDBTable[0].bPSEnable) {
-
- skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
- pMgmt->sNodeDBTable[0].wEnQueueCnt++;
- // set tx map
- pMgmt->abyPSTxMap[0] |= byMask[0];
- return 0;
- }
- // multicast/broadcast data rate
-
- if (pDevice->byBBType != BB_TYPE_11A)
- pDevice->wCurrentRate = RATE_2M;
- else
- pDevice->wCurrentRate = RATE_24M;
- // long preamble type
- pDevice->byPreambleType = PREAMBLE_SHORT;
-
- }else {
-
- if (BSSbIsSTAInNodeDB(pDevice, (u8 *)(skb->data), &uNodeIndex)) {
-
- if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
-
- skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
-
- pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
- // set tx map
- wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
- pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
- (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
-
- return 0;
- }
- // AP rate decided from node
- pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
- // tx preamble decided from node
-
- if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
-
- }else {
- pDevice->byPreambleType = PREAMBLE_LONG;
- }
- bNodeExist = true;
- }
- }
+ spin_lock_irqsave(&priv->lock, flags);
- if (bNodeExist == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
- dev_kfree_skb_irq(skb);
- return 0;
- }
- }
+ if (vnt_tx_context(priv, context) != STATUS_PENDING)
+ ieee80211_free_txskb(priv->hw, context->skb);
- memcpy(&pDevice->sTxEthHeader, skb->data, ETH_HLEN);
+ spin_unlock_irqrestore(&priv->lock, flags);
-//mike add:station mode check eapol-key challenge--->
-{
- u8 Protocol_Version; //802.1x Authentication
- u8 Packet_Type; //802.1x Authentication
- u8 Descriptor_type;
- u16 Key_info;
-
- Protocol_Version = skb->data[ETH_HLEN];
- Packet_Type = skb->data[ETH_HLEN+1];
- Descriptor_type = skb->data[ETH_HLEN+1+1+2];
- Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]);
- if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
- /* 802.1x OR eapol-key challenge frame transfer */
- if (((Protocol_Version == 1) || (Protocol_Version == 2)) &&
- (Packet_Type == 3)) {
- bTxeapol_key = true;
- if(!(Key_info & BIT3) && //WPA or RSN group-key challenge
- (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key
- if(Descriptor_type==254) {
- pDevice->fWPA_Authened = true;
- PRINT_K("WPA ");
- }
- else {
- pDevice->fWPA_Authened = true;
- PRINT_K("WPA2(re-keying) ");
- }
- PRINT_K("Authentication completed!!\n");
- }
- else if((Key_info & BIT3) && (Descriptor_type==2) && //RSN pairwise-key challenge
- (Key_info & BIT8) && (Key_info & BIT9)) {
- pDevice->fWPA_Authened = true;
- PRINT_K("WPA2 Authentication completed!!\n");
- }
- }
- }
+ return 0;
}
-//mike add:station mode check eapol-key challenge<---
-
- if (pDevice->bEncryptionEnable == true) {
- bNeedEncryption = true;
- // get Transmit key
- do {
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
- (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
- pbyBSSID = pDevice->abyBSSID;
- // get pairwise key
- if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) {
- // get group key
- if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) {
- bTKIP_UseGTK = true;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
- break;
- }
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
- break;
- }
- }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- /* TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1 */
- pbyBSSID = pDevice->sTxEthHeader.h_dest;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
- for (ii = 0; ii< 6; ii++)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
-
- // get pairwise key
- if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true)
- break;
- }
- // get group key
- pbyBSSID = pDevice->abyBroadcastAddr;
- if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) {
- pTransmitKey = NULL;
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
- }
- else
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
- } else {
- bTKIP_UseGTK = true;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
- }
- } while(false);
- }
-
- byPktType = (u8)pDevice->byPacketType;
-
- if (pDevice->bFixRate) {
- if (pDevice->byBBType == BB_TYPE_11B) {
- if (pDevice->uConnectionRate >= RATE_11M) {
- pDevice->wCurrentRate = RATE_11M;
- } else {
- pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
- }
- } else {
- if ((pDevice->byBBType == BB_TYPE_11A) &&
- (pDevice->uConnectionRate <= RATE_6M)) {
- pDevice->wCurrentRate = RATE_6M;
- } else {
- if (pDevice->uConnectionRate >= RATE_54M)
- pDevice->wCurrentRate = RATE_54M;
- else
- pDevice->wCurrentRate = (u16)pDevice->uConnectionRate;
- }
- }
- }
- else {
- if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) {
- // Adhoc Tx rate decided from node DB
- if (is_multicast_ether_addr(pDevice->sTxEthHeader.h_dest)) {
- // Multicast use highest data rate
- pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
- // preamble type
- pDevice->byPreambleType = pDevice->byShortPreamble;
- }
- else {
- if (BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.h_dest[0]), &uNodeIndex)) {
- pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
- if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
-
- }
- else {
- pDevice->byPreambleType = PREAMBLE_LONG;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d] Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
- }
- else {
- if (pDevice->byBBType != BB_TYPE_11A)
- pDevice->wCurrentRate = RATE_2M;
- else
- pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
- // abyCurrExtSuppRates[]
- pDevice->byPreambleType = PREAMBLE_SHORT;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
- }
- }
- }
- if (pDevice->op_mode == NL80211_IFTYPE_STATION) {
- // Infra STA rate decided from AP Node, index = 0
- pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
- }
- }
-
- if (pDevice->sTxEthHeader.h_proto == cpu_to_be16(ETH_P_PAE)) {
- if (pDevice->byBBType != BB_TYPE_11A) {
- pDevice->wCurrentRate = RATE_1M;
- pDevice->byTopCCKBasicRate = RATE_1M;
- pDevice->byTopOFDMBasicRate = RATE_6M;
- } else {
- pDevice->wCurrentRate = RATE_6M;
- pDevice->byTopCCKBasicRate = RATE_1M;
- pDevice->byTopOFDMBasicRate = RATE_6M;
- }
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n",
- pDevice->wCurrentRate);
-
- if (wKeepRate != pDevice->wCurrentRate) {
- bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL);
- }
-
- if (pDevice->wCurrentRate <= RATE_11M) {
- byPktType = PK_TYPE_11B;
- }
-
- if (bNeedEncryption == true) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.h_proto));
- if ((pDevice->sTxEthHeader.h_proto) == cpu_to_be16(ETH_P_PAE)) {
- bNeedEncryption = false;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.h_proto));
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
- if (pTransmitKey == NULL) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
- }
- else {
- if (bTKIP_UseGTK == true) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
- pTransmitKey->dwKeyIndex);
- bNeedEncryption = true;
- }
- }
- }
- }
- else {
-
- if (pTransmitKey == NULL) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
- dev_kfree_skb_irq(skb);
- pStats->tx_dropped++;
- return STATUS_FAILURE;
- }
- }
- }
-
- pContext = s_vGetFreeContext(pDevice);
- if (!pContext) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
- dev_kfree_skb_irq(skb);
- return STATUS_RESOURCES;
- }
- pTX_Buffer = (struct vnt_tx_buffer *)&pContext->data[0];
+int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif)
+{
+ struct sk_buff *beacon;
- fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
- pTX_Buffer, bNeedEncryption,
- skb->len, &pDevice->sTxEthHeader,
- (u8 *)skb->data, pTransmitKey, uNodeIndex,
- pDevice->wCurrentRate,
- &uHeaderLen, &BytesToWrite
- );
+ beacon = ieee80211_beacon_get(priv->hw, vif);
+ if (!beacon)
+ return -ENOMEM;
- if (fConvertedPacket == false) {
- pContext->in_use = false;
- dev_kfree_skb_irq(skb);
- return STATUS_FAILURE;
+ if (vnt_beacon_xmit(priv, beacon)) {
+ ieee80211_free_txskb(priv->hw, beacon);
+ return -ENODEV;
}
- if ( pDevice->bEnablePSMode == true ) {
- if ( !pDevice->bPSModeTxBurst ) {
- bScheduleCommand((void *) pDevice,
- WLAN_CMD_MAC_DISPOWERSAVING,
- NULL);
- pDevice->bPSModeTxBurst = true;
- }
- }
+ return 0;
+}
- pTX_Buffer->byPKTNO = (u8) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
- pTX_Buffer->tx_byte_count = cpu_to_le16((u16)BytesToWrite);
+int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf)
+{
+ int ret;
- pContext->skb = skb;
- pContext->type = CONTEXT_DATA_PACKET;
- pContext->buf_len = (u16)BytesToWrite + 4 ; /* USB header */
+ vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
- s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
- &pDevice->sTxEthHeader.h_dest[0],
- (u16)(BytesToWrite-uHeaderLen),
- pTX_Buffer->fifo_head.wFIFOCtl);
+ vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- status = PIPEnsSendBulkOut(pDevice,pContext);
+ vnt_mac_set_beacon_interval(priv, conf->beacon_int);
- if (bNeedDeAuth == true) {
- u16 wReason = WLAN_MGMT_REASON_MIC_FAILURE;
+ vnt_clear_current_tsf(priv);
- bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (u8 *) &wReason);
- }
+ vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
- if (status != STATUS_PENDING) {
- pContext->in_use = false;
- dev_kfree_skb_irq(skb);
- return STATUS_FAILURE;
- }
+ vnt_reset_next_tbtt(priv, conf->beacon_int);
+ ret = vnt_beacon_make(priv, vif);
- return 0;
+ return ret;
}
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
index 6db3337f1d1d..90b34ab2f6ce 100644
--- a/drivers/staging/vt6656/rxtx.h
+++ b/drivers/staging/vt6656/rxtx.h
@@ -33,13 +33,15 @@
#include "wcmd.h"
#include "baseband.h"
+#define DEFAULT_MGN_LIFETIME_RES_64us 125 /* 64us */
+#define DEFAULT_MSDU_LIFETIME_RES_64us 8000
+
/* MIC HDR data header */
struct vnt_mic_hdr {
u8 id;
u8 tx_priority;
u8 mic_addr2[6];
- __be32 tsc_47_16;
- __be16 tsc_15_0;
+ u8 ccmp_pn[IEEE80211_CCMP_PN_LEN];
__be16 payload_len;
__be16 hlen;
__le16 frame_control;
@@ -81,6 +83,7 @@ struct vnt_tx_datahead_g {
__le16 duration_a;
__le16 time_stamp_off_b;
__le16 time_stamp_off_a;
+ struct ieee80211_hdr hdr;
} __packed;
struct vnt_tx_datahead_g_fb {
@@ -92,12 +95,14 @@ struct vnt_tx_datahead_g_fb {
__le16 duration_a_f1;
__le16 time_stamp_off_b;
__le16 time_stamp_off_a;
+ struct ieee80211_hdr hdr;
} __packed;
struct vnt_tx_datahead_ab {
struct vnt_phy_field ab;
__le16 duration;
__le16 time_stamp_off;
+ struct ieee80211_hdr hdr;
} __packed;
struct vnt_tx_datahead_a_fb {
@@ -106,6 +111,7 @@ struct vnt_tx_datahead_a_fb {
__le16 time_stamp_off;
__le16 duration_f0;
__le16 duration_f1;
+ struct ieee80211_hdr hdr;
} __packed;
/* RTS buffer header */
@@ -215,23 +221,23 @@ union vnt_tx_head {
};
struct vnt_tx_fifo_head {
- u32 adwTxKey[4];
- u16 wFIFOCtl;
+ u8 tx_key[WLAN_KEY_LEN_CCMP];
+ __le16 fifo_ctl;
__le16 time_stamp;
- u16 wFragCtl;
+ __le16 frag_ctl;
__le16 current_rate;
} __packed;
struct vnt_tx_buffer {
- u8 byType;
- u8 byPKTNO;
+ u8 type;
+ u8 pkt_no;
__le16 tx_byte_count;
struct vnt_tx_fifo_head fifo_head;
union vnt_tx_head tx_head;
} __packed;
struct vnt_tx_short_buf_head {
- u16 fifo_ctl;
+ __le16 fifo_ctl;
u16 time_stamp;
struct vnt_phy_field ab;
__le16 duration;
@@ -239,16 +245,16 @@ struct vnt_tx_short_buf_head {
} __packed;
struct vnt_beacon_buffer {
- u8 byType;
- u8 byPKTNO;
+ u8 type;
+ u8 pkt_no;
__le16 tx_byte_count;
struct vnt_tx_short_buf_head short_head;
- struct ieee80211_hdr hdr;
+ struct ieee80211_mgmt mgmt_hdr;
} __packed;
-void vDMA0_tx_80211(struct vnt_private *, struct sk_buff *skb);
-int nsDMA_tx_packet(struct vnt_private *, struct sk_buff *skb);
-CMD_STATUS csMgmt_xmit(struct vnt_private *, struct vnt_tx_mgmt *);
-CMD_STATUS csBeacon_xmit(struct vnt_private *, struct vnt_tx_mgmt *);
+int vnt_tx_packet(struct vnt_private *, struct sk_buff *);
+int vnt_beacon_make(struct vnt_private *, struct ieee80211_vif *);
+int vnt_beacon_enable(struct vnt_private *, struct ieee80211_vif *,
+ struct ieee80211_bss_conf *);
#endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c
deleted file mode 100644
index 2ef54f608cbc..000000000000
--- a/drivers/staging/vt6656/tether.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003 VIA Networking, Inc. 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: tether.c
- *
- * Purpose:
- *
- * Author: Tevin Chen
- *
- * Date: May 21, 1996
- *
- * Functions:
- * ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not
- *
- * Revision History:
- *
- */
-
-#include "device.h"
-#include "tmacro.h"
-#include "tether.h"
-
-/*
- * Description: Check CRC value of the buffer if Ok or not
- *
- * Parameters:
- * In:
- * pbyBuffer - pointer of buffer (normally is rx buffer)
- * cbFrameLength - length of buffer, including CRC portion
- * Out:
- * none
- *
- * Return Value: true if ok; false if error.
- *
- */
-bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength)
-{
- u32 n_crc = ~ether_crc_le(cbFrameLength - 4, pbyBuffer);
-
- if (le32_to_cpu(*((__le32 *)(pbyBuffer + cbFrameLength - 4))) != n_crc)
- return false;
-
- return true;
-}
-
diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h
deleted file mode 100644
index f57fcfdc24d5..000000000000
--- a/drivers/staging/vt6656/tether.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: tether.h
- *
- * Purpose:
- *
- * Author: Tevin Chen
- *
- * Date: Jan. 28, 1997
- *
- */
-
-#ifndef __TETHER_H__
-#define __TETHER_H__
-
-#include <linux/if_ether.h>
-
-//
-// constants
-//
-#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1)
- // Ethernet address string length
-#define U_MULTI_ADDR_LEN 8 // multicast address length
-
-#ifdef __BIG_ENDIAN
-
-#define TYPE_MGMT_PROBE_RSP 0x5000
-
-#define FC_TODS 0x0001
-#define FC_FROMDS 0x0002
-#define FC_MOREFRAG 0x0004
-#define FC_RETRY 0x0008
-#define FC_POWERMGT 0x0010
-#define FC_MOREDATA 0x0020
-#define FC_WEP 0x0040
-#define TYPE_802_11_ATIM 0x9000
-
-#define TYPE_802_11_DATA 0x0800
-#define TYPE_802_11_CTL 0x0400
-#define TYPE_802_11_MGMT 0x0000
-#define TYPE_802_11_MASK 0x0C00
-#define TYPE_SUBTYPE_MASK 0xFC00
-#define TYPE_802_11_NODATA 0x4000
-#define TYPE_DATE_NULL 0x4800
-
-#define TYPE_CTL_PSPOLL 0xa400
-#define TYPE_CTL_ACK 0xd400
-
-#else //if LITTLE_ENDIAN
-//
-// wType field in the SEthernetHeader
-//
-// NOTE....
-// in network byte order, high byte is going first
-
-#define TYPE_MGMT_PROBE_RSP 0x0050
-
-#define FC_TODS 0x0100
-#define FC_FROMDS 0x0200
-#define FC_MOREFRAG 0x0400
-#define FC_RETRY 0x0800
-#define FC_POWERMGT 0x1000
-#define FC_MOREDATA 0x2000
-#define FC_WEP 0x4000
-#define TYPE_802_11_ATIM 0x0090
-
-#define TYPE_802_11_DATA 0x0008
-#define TYPE_802_11_CTL 0x0004
-#define TYPE_802_11_MGMT 0x0000
-#define TYPE_802_11_MASK 0x000C
-#define TYPE_SUBTYPE_MASK 0x00FC
-#define TYPE_802_11_NODATA 0x0040
-#define TYPE_DATE_NULL 0x0048
-
-#define TYPE_CTL_PSPOLL 0x00a4
-#define TYPE_CTL_ACK 0x00d4
-
-#endif //#ifdef __BIG_ENDIAN
-
-#define WEP_IV_MASK 0x00FFFFFF
-
-//u8 ETHbyGetHashIndexByCrc(u8 * pbyMultiAddr);
-bool ETHbIsBufferCrc32Ok(u8 * pbyBuffer, unsigned int cbFrameLength);
-
-#endif /* __TETHER_H__ */
diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c
deleted file mode 100644
index 28282f345901..000000000000
--- a/drivers/staging/vt6656/tkip.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: tkip.c
- *
- * Purpose: Implement functions for 802.11i TKIP
- *
- * Author: Jerry Chen
- *
- * Date: Mar. 11, 2003
- *
- * Functions:
- * TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC
- *
- * Revision History:
- *
- */
-
-#include "tmacro.h"
-#include "tkip.h"
-
-/* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */
-/* The 2nd table is the same as the 1st but with the upper and lower */
-/* bytes swapped. To allow an endian tolerant implementation, the byte */
-/* halves have been expressed independently here. */
-static const u8 TKIP_Sbox_Lower[256] = {
- 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
- 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
- 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
- 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
- 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
- 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
- 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
- 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
- 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
- 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
- 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
- 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
- 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
- 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
- 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
- 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
- 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
- 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
- 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
- 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
- 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
- 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
- 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
- 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
- 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
- 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
- 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
- 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
- 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
- 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
- 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
- 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
-};
-
-static const u8 TKIP_Sbox_Upper[256] = {
- 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
- 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
- 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
- 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
- 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
- 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
- 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
- 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
- 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
- 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
- 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
- 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
- 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
- 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
- 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
- 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
- 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
- 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
- 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
- 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
- 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
- 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
- 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
- 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
- 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
- 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
- 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
- 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
- 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
- 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
- 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
- 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
-};
-
-//STKIPKeyManagement sTKIPKeyTable[MAX_TKIP_KEY];
-
-/************************************************************/
-/* tkip_sbox() */
-/* Returns a 16 bit value from a 64K entry table. The Table */
-/* is synthesized from two 256 entry byte wide tables. */
-/************************************************************/
-static unsigned int tkip_sbox(unsigned int index)
-{
- unsigned int index_low;
- unsigned int index_high;
- unsigned int left, right;
-
- index_low = (index % 256);
- index_high = ((index >> 8) % 256);
-
- left = TKIP_Sbox_Lower[index_low] + (TKIP_Sbox_Upper[index_low] * 256);
- right = TKIP_Sbox_Upper[index_high] + (TKIP_Sbox_Lower[index_high] * 256);
-
- return (left ^ right);
-};
-
-static unsigned int rotr1(unsigned int a)
-{
- unsigned int b;
-
- if ((a & 0x01) == 0x01) {
- b = (a >> 1) | 0x8000;
- } else {
- b = (a >> 1) & 0x7fff;
- }
- b = b % 65536;
- return b;
-}
-
-/*
- * Description: Calculate RC4Key fom TK, TA, and TSC
- *
- * Parameters:
- * In:
- * pbyTKey - TKey
- * pbyTA - TA
- * dwTSC - TSC
- * Out:
- * pbyRC4Key - RC4Key
- *
- * Return Value: none
- *
- */
-void TKIPvMixKey(
- u8 * pbyTKey,
- u8 * pbyTA,
- u16 wTSC15_0,
- u32 dwTSC47_16,
- u8 * pbyRC4Key
- )
-{
- u32 p1k[5];
- u32 tsc0, tsc1, tsc2;
- u32 ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
- u32 pnl, pnh;
- int i, j;
-
- pnl = (u32)wTSC15_0;
- pnh = (u32)(dwTSC47_16 & 0xffffffff);
-
- tsc0 = (u32)((pnh >> 16) % 65536); /* msb */
- tsc1 = (u32)(pnh % 65536);
- tsc2 = (u32)(pnl % 65536); /* lsb */
-
- /* Phase 1, step 1 */
- p1k[0] = tsc1;
- p1k[1] = tsc0;
- p1k[2] = (u32)(pbyTA[0] + (pbyTA[1]*256));
- p1k[3] = (u32)(pbyTA[2] + (pbyTA[3]*256));
- p1k[4] = (u32)(pbyTA[4] + (pbyTA[5]*256));
-
- /* Phase 1, step 2 */
- for (i=0; i<8; i++) {
- j = 2*(i & 1);
- p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536;
- p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536;
- p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536;
- p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536;
- p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536;
- p1k[4] = (p1k[4] + i) % 65536;
- }
-
- /* Phase 2, Step 1 */
- ppk0 = p1k[0];
- ppk1 = p1k[1];
- ppk2 = p1k[2];
- ppk3 = p1k[3];
- ppk4 = p1k[4];
- ppk5 = (p1k[4] + tsc2) % 65536;
-
- /* Phase2, Step 2 */
- ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536);
- ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
- ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
- ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
- ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
- ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
-
- ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
- ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
- ppk2 = ppk2 + rotr1(ppk1);
- ppk3 = ppk3 + rotr1(ppk2);
- ppk4 = ppk4 + rotr1(ppk3);
- ppk5 = ppk5 + rotr1(ppk4);
-
- /* Phase 2, Step 3 */
- pbyRC4Key[0] = (tsc2 >> 8) % 256;
- pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
- pbyRC4Key[2] = tsc2 % 256;
- pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256;
-
- pbyRC4Key[4] = ppk0 % 256;
- pbyRC4Key[5] = (ppk0 >> 8) % 256;
-
- pbyRC4Key[6] = ppk1 % 256;
- pbyRC4Key[7] = (ppk1 >> 8) % 256;
-
- pbyRC4Key[8] = ppk2 % 256;
- pbyRC4Key[9] = (ppk2 >> 8) % 256;
-
- pbyRC4Key[10] = ppk3 % 256;
- pbyRC4Key[11] = (ppk3 >> 8) % 256;
-
- pbyRC4Key[12] = ppk4 % 256;
- pbyRC4Key[13] = (ppk4 >> 8) % 256;
-
- pbyRC4Key[14] = ppk5 % 256;
- pbyRC4Key[15] = (ppk5 >> 8) % 256;
-}
diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h
deleted file mode 100644
index 4fba7ef38266..000000000000
--- a/drivers/staging/vt6656/tkip.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: tkip.h
- *
- * Purpose: Implement functions for 802.11i TKIP
- *
- * Author: Jerry Chen
- *
- * Date: Mar. 11, 2003
- *
- */
-
-#ifndef __TKIP_H__
-#define __TKIP_H__
-
-#include "tether.h"
-
-#define TKIP_KEY_LEN 16
-
-void TKIPvMixKey(
- u8 * pbyTKey,
- u8 * pbyTA,
- u16 wTSC15_0,
- u32 dwTSC47_16,
- u8 * pbyRC4Key
- );
-
-#endif /* __TKIP_H__ */
diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h
deleted file mode 100644
index 15e724e4d4ba..000000000000
--- a/drivers/staging/vt6656/tmacro.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: tmacro.h
- *
- * Purpose: define basic common types and macros
- *
- * Author: Tevin Chen
- *
- * Date: May 21, 1996
- *
- */
-
-#ifndef __TMACRO_H__
-#define __TMACRO_H__
-
-/****** Common helper macros ***********************************************/
-
-#if !defined(LOBYTE)
-#define LOBYTE(w) ((u8)(w))
-#endif
-#if !defined(HIBYTE)
-#define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF))
-#endif
-
-#if !defined(LOWORD)
-#define LOWORD(d) ((u16)(d))
-#endif
-#if !defined(HIWORD)
-#define HIWORD(d) ((u16)((((u32)(d)) >> 16) & 0xFFFF))
-#endif
-
-#if !defined(MAKEWORD)
-#define MAKEWORD(lb, hb) ((u16)(((u8)(lb)) | (((u16)((u8)(hb))) << 8)))
-#endif
-
-#endif /* __TMACRO_H__ */
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
index e4751b71e4d3..cba653292996 100644
--- a/drivers/staging/vt6656/usbpipe.c
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -30,7 +30,6 @@
* vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM
* vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM
* vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM
- * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
*
* Revision History:
* 04-05-2004 Jerry Chen: Initial release
@@ -45,28 +44,14 @@
#include "device.h"
#include "usbpipe.h"
-//endpoint def
-//endpoint 0: control
-//endpoint 1: interrupt
-//endpoint 2: read bulk
-//endpoint 3: write bulk
-
-#define USB_CTL_WAIT 500 //ms
-
-#ifndef URB_ASYNC_UNLINK
-#define URB_ASYNC_UNLINK 0
-#endif
-
-static void s_nsInterruptUsbIoCompleteRead(struct urb *urb);
-static void s_nsBulkInUsbIoCompleteRead(struct urb *urb);
-static void s_nsBulkOutIoCompleteWrite(struct urb *urb);
+#define USB_CTL_WAIT 500 /* ms */
int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
u16 index, u16 length, u8 *buffer)
{
int status = 0;
- if (priv->Flags & fMP_DISCONNECTED)
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
return STATUS_FAILURE;
mutex_lock(&priv->usb_lock);
@@ -94,7 +79,7 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
{
int status;
- if (priv->Flags & fMP_DISCONNECTED)
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
return STATUS_FAILURE;
mutex_lock(&priv->usb_lock);
@@ -117,63 +102,7 @@ void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data)
reg_off, reg, sizeof(u8), data);
}
-/*
- * Description:
- * Allocates an usb interrupt in irp and calls USBD.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * Out:
- * none
- *
- * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
- *
- */
-
-int PIPEnsInterruptRead(struct vnt_private *priv)
-{
- int status = STATUS_FAILURE;
-
- if (priv->int_buf.in_use == true)
- return STATUS_FAILURE;
-
- priv->int_buf.in_use = true;
-
- usb_fill_int_urb(priv->pInterruptURB,
- priv->usb,
- usb_rcvintpipe(priv->usb, 1),
- priv->int_buf.data_buf,
- MAX_INTERRUPT_SIZE,
- s_nsInterruptUsbIoCompleteRead,
- priv,
- priv->int_interval);
-
- status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC);
- if (status) {
- dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
- priv->int_buf.in_use = false;
- }
-
- return status;
-}
-
-/*
- * Description:
- * Complete function of usb interrupt in irp.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- *
- * Out:
- * none
- *
- * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
- *
- */
-
-static void s_nsInterruptUsbIoCompleteRead(struct urb *urb)
+static void vnt_start_interrupt_urb_complete(struct urb *urb)
{
struct vnt_private *priv = urb->context;
int status;
@@ -198,88 +127,49 @@ static void s_nsInterruptUsbIoCompleteRead(struct urb *urb)
dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status);
} else {
- INTnsProcessData(priv);
+ vnt_int_process_data(priv);
}
- status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC);
+ status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC);
if (status) {
dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
} else {
priv->int_buf.in_use = true;
}
-
- return;
}
-/*
- * Description:
- * Allocates an usb BulkIn irp and calls USBD.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * Out:
- * none
- *
- * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
- *
- */
-
-int PIPEnsBulkInUsbRead(struct vnt_private *priv, struct vnt_rcb *rcb)
+int vnt_start_interrupt_urb(struct vnt_private *priv)
{
- int status = 0;
- struct urb *urb;
+ int status = STATUS_FAILURE;
- if (priv->Flags & fMP_DISCONNECTED)
+ if (priv->int_buf.in_use == true)
return STATUS_FAILURE;
- urb = rcb->pUrb;
- if (rcb->skb == NULL) {
- dev_dbg(&priv->usb->dev, "rcb->skb is null\n");
- return status;
- }
+ priv->int_buf.in_use = true;
- usb_fill_bulk_urb(urb,
- priv->usb,
- usb_rcvbulkpipe(priv->usb, 2),
- (void *) (rcb->skb->data),
- MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
- s_nsBulkInUsbIoCompleteRead,
- rcb);
+ usb_fill_int_urb(priv->interrupt_urb,
+ priv->usb,
+ usb_rcvintpipe(priv->usb, 1),
+ priv->int_buf.data_buf,
+ MAX_INTERRUPT_SIZE,
+ vnt_start_interrupt_urb_complete,
+ priv,
+ priv->int_interval);
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status != 0) {
- dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status);
- return STATUS_FAILURE ;
+ status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC);
+ if (status) {
+ dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
+ priv->int_buf.in_use = false;
}
- rcb->Ref = 1;
- rcb->bBoolInUse = true;
-
return status;
}
-/*
- * Description:
- * Complete function of usb BulkIn irp.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- *
- * Out:
- * none
- *
- * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
- *
- */
-
-static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
+static void vnt_submit_rx_urb_complete(struct urb *urb)
{
struct vnt_rcb *rcb = urb->context;
- struct vnt_private *priv = rcb->pDevice;
+ struct vnt_private *priv = rcb->priv;
unsigned long flags;
- int re_alloc_skb = false;
switch (urb->status) {
case 0:
@@ -297,108 +187,68 @@ static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
if (urb->actual_length) {
spin_lock_irqsave(&priv->lock, flags);
- if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true)
- re_alloc_skb = true;
+ if (vnt_rx_data(priv, rcb, urb->actual_length)) {
+ rcb->skb = dev_alloc_skb(priv->rx_buf_sz);
+ if (!rcb->skb) {
+ dev_dbg(&priv->usb->dev,
+ "Failed to re-alloc rx skb\n");
+
+ rcb->in_use = false;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
+ } else {
+ skb_push(rcb->skb, skb_headroom(rcb->skb));
+ skb_trim(rcb->skb, 0);
+ }
+
+ urb->transfer_buffer = skb_put(rcb->skb,
+ skb_tailroom(rcb->skb));
spin_unlock_irqrestore(&priv->lock, flags);
}
- rcb->Ref--;
- if (rcb->Ref == 0) {
- dev_dbg(&priv->usb->dev,
- "RxvFreeNormal %d\n", priv->NumRecvFreeList);
+ if (usb_submit_urb(urb, GFP_ATOMIC)) {
+ dev_dbg(&priv->usb->dev, "Failed to re submit rx skb\n");
- spin_lock_irqsave(&priv->lock, flags);
-
- RXvFreeRCB(rcb, re_alloc_skb);
-
- spin_unlock_irqrestore(&priv->lock, flags);
+ rcb->in_use = false;
}
-
- return;
}
-/*
- * Description:
- * Allocates an usb BulkOut irp and calls USBD.
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * Out:
- * none
- *
- * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
- *
- */
-
-int PIPEnsSendBulkOut(struct vnt_private *priv,
- struct vnt_usb_send_context *context)
+int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb)
{
- int status;
+ int status = 0;
struct urb *urb;
- priv->bPWBitOn = false;
-
- if (!(MP_IS_READY(priv) && priv->Flags & fMP_POST_WRITES)) {
- context->in_use = false;
- return STATUS_RESOURCES;
+ urb = rcb->urb;
+ if (rcb->skb == NULL) {
+ dev_dbg(&priv->usb->dev, "rcb->skb is null\n");
+ return status;
}
- urb = context->urb;
-
usb_fill_bulk_urb(urb,
- priv->usb,
- usb_sndbulkpipe(priv->usb, 3),
- context->data,
- context->buf_len,
- s_nsBulkOutIoCompleteWrite,
- context);
+ priv->usb,
+ usb_rcvbulkpipe(priv->usb, 2),
+ skb_put(rcb->skb, skb_tailroom(rcb->skb)),
+ MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
+ vnt_submit_rx_urb_complete,
+ rcb);
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status != 0) {
- dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status);
-
- context->in_use = false;
+ dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status);
return STATUS_FAILURE;
}
- return STATUS_PENDING;
-}
+ rcb->in_use = true;
-/*
- * Description: s_nsBulkOutIoCompleteWrite
- * 1a) Indicate to the protocol the status of the write.
- * 1b) Return ownership of the packet to the protocol.
- *
- * 2) If any more packets are queue for sending, send another packet
- * to USBD.
- * If the attempt to send the packet to the driver fails,
- * return ownership of the packet to the protocol and
- * try another packet (until one succeeds).
- *
- * Parameters:
- * In:
- * pdoUsbDevObj - pointer to the USB device object which
- * completed the irp
- * pIrp - the irp which was completed by the
- * device object
- * pContext - the context given to IoSetCompletionRoutine
- * before calling IoCallDriver on the irp
- * The pContext is a pointer to the USB device object.
- * Out:
- * none
- *
- * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
- * (IofCompleteRequest) to stop working on the irp.
- *
- */
+ return status;
+}
-static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
+static void vnt_tx_context_complete(struct urb *urb)
{
struct vnt_usb_send_context *context = urb->context;
struct vnt_private *priv = context->priv;
- u8 context_type = context->type;
switch (urb->status) {
case 0:
@@ -415,26 +265,45 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
break;
}
- if (!netif_device_present(priv->dev))
- return;
+ if (context->type == CONTEXT_DATA_PACKET)
+ ieee80211_wake_queues(priv->hw);
- if (CONTEXT_DATA_PACKET == context_type) {
- if (context->skb != NULL) {
- dev_kfree_skb_irq(context->skb);
- context->skb = NULL;
- dev_dbg(&priv->usb->dev,
- "tx %d bytes\n", context->buf_len);
- }
+ if (urb->status || context->type == CONTEXT_BEACON_PACKET) {
+ if (context->skb)
+ ieee80211_free_txskb(priv->hw, context->skb);
- priv->dev->trans_start = jiffies;
+ context->in_use = false;
}
+}
+
+int vnt_tx_context(struct vnt_private *priv,
+ struct vnt_usb_send_context *context)
+{
+ int status;
+ struct urb *urb;
- if (priv->bLinkPass == true) {
- if (netif_queue_stopped(priv->dev))
- netif_wake_queue(priv->dev);
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags)) {
+ context->in_use = false;
+ return STATUS_RESOURCES;
}
- context->in_use = false;
+ urb = context->urb;
+
+ usb_fill_bulk_urb(urb,
+ priv->usb,
+ usb_sndbulkpipe(priv->usb, 3),
+ context->data,
+ context->buf_len,
+ vnt_tx_context_complete,
+ context);
- return;
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (status != 0) {
+ dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status);
+
+ context->in_use = false;
+ return STATUS_FAILURE;
+ }
+
+ return STATUS_PENDING;
}
diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h
index ea71782d8901..e74aa0809928 100644
--- a/drivers/staging/vt6656/usbpipe.h
+++ b/drivers/staging/vt6656/usbpipe.h
@@ -38,9 +38,8 @@ int vnt_control_in(struct vnt_private *, u8, u16, u16, u16, u8 *);
void vnt_control_out_u8(struct vnt_private *, u8, u8, u8);
void vnt_control_in_u8(struct vnt_private *, u8, u8, u8 *);
-int PIPEnsInterruptRead(struct vnt_private *);
-int PIPEnsBulkInUsbRead(struct vnt_private *, struct vnt_rcb *pRCB);
-int PIPEnsSendBulkOut(struct vnt_private *,
- struct vnt_usb_send_context *pContext);
+int vnt_start_interrupt_urb(struct vnt_private *);
+int vnt_submit_rx_urb(struct vnt_private *, struct vnt_rcb *);
+int vnt_tx_context(struct vnt_private *, struct vnt_usb_send_context *);
#endif /* __USBPIPE_H__ */
diff --git a/drivers/staging/vt6656/vntconfiguration.dat b/drivers/staging/vt6656/vntconfiguration.dat
deleted file mode 100644
index 933774c7d27f..000000000000
--- a/drivers/staging/vt6656/vntconfiguration.dat
+++ /dev/null
@@ -1,6 +0,0 @@
-#VNT Configuration
-[start]
-ZONETYPE=EUROPE
-AUTHENMODE=12
-ENCRYPTIONMODE=34
-[end] \ No newline at end of file
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
index da72d4df6fca..3cbf4791bac1 100644
--- a/drivers/staging/vt6656/wcmd.c
+++ b/drivers/staging/vt6656/wcmd.c
@@ -25,1070 +25,170 @@
* Date: May 8, 2003
*
* Functions:
- * s_vProbeChannel - Active scan channel
- * s_MgrMakeProbeRequest - Make ProbeRequest packet
- * CommandTimer - Timer function to handle command
- * s_bCommandComplete - Command Complete function
- * bScheduleCommand - Push Command and wait Command Scheduler to do
- * vCommandTimer- Command call back functions
- * vCommandTimerWait- Call back timer
- * s_bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
+ * vnt_cmd_complete - Command Complete function
+ * vnt_schedule_command - Push Command and wait Command Scheduler to do
+ * vnt_cmd_timer_wait- Call back timer
*
* Revision History:
*
*/
-#include "tmacro.h"
#include "device.h"
#include "mac.h"
-#include "card.h"
-#include "80211hdr.h"
#include "wcmd.h"
-#include "wmgr.h"
#include "power.h"
-#include "wctl.h"
-#include "baseband.h"
#include "usbpipe.h"
#include "rxtx.h"
#include "rf.h"
-#include "channel.h"
-#include "iowpa.h"
-static int msglevel = MSG_LEVEL_INFO;
-//static int msglevel = MSG_LEVEL_DEBUG;
-
-static void s_vProbeChannel(struct vnt_private *);
-
-static struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *,
- struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-static int s_bCommandComplete(struct vnt_private *);
-
-static int s_bClearBSSID_SCAN(struct vnt_private *);
-
-/*
- * Description:
- * Stop AdHoc beacon during scan process
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * Out:
- * none
- *
- * Return Value: none
- *
- */
-
-static void vAdHocBeaconStop(struct vnt_private *pDevice)
+static void vnt_cmd_timer_wait(struct vnt_private *priv, unsigned long msecs)
{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int bStop;
-
- /*
- * temporarily stop Beacon packet for AdHoc Server
- * if all of the following coditions are met:
- * (1) STA is in AdHoc mode
- * (2) VT3253 is programmed as automatic Beacon Transmitting
- * (3) One of the following conditions is met
- * (3.1) AdHoc channel is in B/G band and the
- * current scan channel is in A band
- * or
- * (3.2) AdHoc channel is in A mode
- */
- bStop = false;
- if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
- (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
- if ((pMgmt->uIBSSChannel <= CB_MAX_CHANNEL_24G) &&
- (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
- bStop = true;
- }
- if (pMgmt->uIBSSChannel > CB_MAX_CHANNEL_24G)
- bStop = true;
- }
-
- if (bStop) {
- //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n",
- // pMgmt->uIBSSChannel, pMgmt->uScanChannel));
- MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
- }
-
-} /* vAdHocBeaconStop */
+ schedule_delayed_work(&priv->run_command_work, msecs_to_jiffies(msecs));
+}
-/*
- * Description:
- * Restart AdHoc beacon after scan process complete
- *
- * Parameters:
- * In:
- * pDevice - Pointer to the adapter
- * Out:
- * none
- *
- * Return Value: none
- *
- */
-static void vAdHocBeaconRestart(struct vnt_private *pDevice)
+static int vnt_cmd_complete(struct vnt_private *priv)
{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- /*
- * Restart Beacon packet for AdHoc Server
- * if all of the following coditions are met:
- * (1) STA is in AdHoc mode
- * (2) VT3253 is programmed as automatic Beacon Transmitting
- */
- if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
- (pMgmt->eCurrState >= WMAC_STATE_STARTED)) {
- //PMESG(("RESTART_BEACON\n"));
- MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+ priv->command_state = WLAN_CMD_IDLE;
+ if (priv->free_cmd_queue == CMD_Q_SIZE) {
+ /* Command Queue Empty */
+ priv->cmd_running = false;
+ return true;
}
-}
-
-/*+
- *
- * Routine Description:
- * Prepare and send probe request management frames.
- *
- *
- * Return Value:
- * none.
- *
--*/
-
-static void s_vProbeChannel(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- struct vnt_tx_mgmt *pTxPacket;
- u8 abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES,
- 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
- /* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M*/
- u8 abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES,
- 4, 0x0C, 0x12, 0x18, 0x60};
- /* 6M, 9M, 12M, 48M*/
- u8 abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES,
- 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
- u8 abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES,
- 4, 0x02, 0x04, 0x0B, 0x16};
- u8 *pbyRate;
- int ii;
+ priv->command = priv->cmd_queue[priv->cmd_dequeue_idx];
- if (pDevice->byBBType == BB_TYPE_11A)
- pbyRate = &abyCurrSuppRatesA[0];
- else if (pDevice->byBBType == BB_TYPE_11B)
- pbyRate = &abyCurrSuppRatesB[0];
- else
- pbyRate = &abyCurrSuppRatesG[0];
+ ADD_ONE_WITH_WRAP_AROUND(priv->cmd_dequeue_idx, CMD_Q_SIZE);
+ priv->free_cmd_queue++;
+ priv->cmd_running = true;
- // build an assocreq frame and send it
- pTxPacket = s_MgrMakeProbeRequest
- (
- pDevice,
- pMgmt,
- pMgmt->abyScanBSSID,
- (PWLAN_IE_SSID)pMgmt->abyScanSSID,
- (PWLAN_IE_SUPP_RATES)pbyRate,
- (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
- );
+ switch (priv->command) {
+ case WLAN_CMD_INIT_MAC80211:
+ priv->command_state = WLAN_CMD_INIT_MAC80211_START;
+ break;
- if (pTxPacket != NULL) {
- for (ii = 0; ii < 1; ii++) {
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n");
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n");
- }
- }
- }
+ case WLAN_CMD_TBTT_WAKEUP:
+ priv->command_state = WLAN_CMD_TBTT_WAKEUP_START;
+ break;
-}
+ case WLAN_CMD_BECON_SEND:
+ priv->command_state = WLAN_CMD_BECON_SEND_START;
+ break;
-/*+
- *
- * Routine Description:
- * Constructs an probe request frame
- *
- *
- * Return Value:
- * A ptr to Tx frame or NULL on allocation failure
- *
--*/
+ case WLAN_CMD_SETPOWER:
+ priv->command_state = WLAN_CMD_SETPOWER_START;
+ break;
-static struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u8 *pScanBSSID, PWLAN_IE_SSID pSSID,
- PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_PROBEREQ sFrame;
+ case WLAN_CMD_CHANGE_ANTENNA:
+ priv->command_state = WLAN_CMD_CHANGE_ANTENNA_START;
+ break;
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_PROBEREQ_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
- vMgrEncodeProbeRequest(&sFrame);
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
- ));
- memcpy(sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
- memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy(sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
- // Copy the SSID, pSSID->len=0 indicate broadcast SSID
- sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
- sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
- // Copy the extension rate set
- if (pDevice->byBBType == BB_TYPE_11G) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+ default:
+ break;
}
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
- return pTxPacket;
-}
+ vnt_cmd_timer_wait(priv, 0);
-static void
-vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond)
-{
- schedule_delayed_work(&pDevice->run_command_work,
- msecs_to_jiffies(MSecond));
+ return true;
}
-void vRunCommand(struct work_struct *work)
+void vnt_run_command(struct work_struct *work)
{
- struct vnt_private *pDevice =
+ struct vnt_private *priv =
container_of(work, struct vnt_private, run_command_work.work);
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PWLAN_IE_SSID pItemSSID;
- PWLAN_IE_SSID pItemSSIDCurr;
- CMD_STATUS Status;
- struct sk_buff *skb;
- union iwreq_data wrqu;
- int ii;
- u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
- u8 byData;
- unsigned long flags;
- if (pDevice->Flags & fMP_DISCONNECTED)
+ if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
return;
- if (pDevice->bCmdRunning != true)
+ if (priv->cmd_running != true)
return;
- switch (pDevice->eCommandState) {
-
- case WLAN_CMD_SCAN_START:
-
- pDevice->byReAssocCount = 0;
- if (pDevice->bRadioOff == true)
+ switch (priv->command_state) {
+ case WLAN_CMD_INIT_MAC80211_START:
+ if (priv->mac_hw)
break;
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
- break;
+ dev_info(&priv->usb->dev, "Starting mac80211\n");
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
-
- if (pMgmt->uScanChannel == 0)
- pMgmt->uScanChannel = pDevice->byMinChannel;
- if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
- pDevice->eCommandState = WLAN_CMD_SCAN_END;
- break;
- } else {
- if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel);
- pMgmt->uScanChannel++;
- break;
- }
- if (pMgmt->uScanChannel == pDevice->byMinChannel) {
- // pMgmt->eScanType = WMAC_SCAN_ACTIVE; //mike mark
- pMgmt->abyScanBSSID[0] = 0xFF;
- pMgmt->abyScanBSSID[1] = 0xFF;
- pMgmt->abyScanBSSID[2] = 0xFF;
- pMgmt->abyScanBSSID[3] = 0xFF;
- pMgmt->abyScanBSSID[4] = 0xFF;
- pMgmt->abyScanBSSID[5] = 0xFF;
- pItemSSID->byElementID = WLAN_EID_SSID;
- // clear bssid list
- /* BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); */
- pMgmt->eScanState = WMAC_IS_SCANNING;
- pDevice->byScanBBType = pDevice->byBBType; //lucas
- pDevice->bStopDataPkt = true;
- // Turn off RCR_BSSID filter every time
- MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID);
- pDevice->byRxMode &= ~RCR_BSSID;
- }
- //lucas
- vAdHocBeaconStop(pDevice);
- if ((pDevice->byBBType != BB_TYPE_11A) &&
- (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
- pDevice->byBBType = BB_TYPE_11A;
- CARDvSetBSSMode(pDevice);
- } else if ((pDevice->byBBType == BB_TYPE_11A) &&
- (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) {
- pDevice->byBBType = BB_TYPE_11G;
- CARDvSetBSSMode(pDevice);
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning.... channel: [%d]\n", pMgmt->uScanChannel);
- // Set channel
- CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel);
- // Set Baseband to be more sensitive.
-
- BBvSetShortSlotTime(pDevice);
- BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
- BBvUpdatePreEDThreshold(pDevice, true);
-
- pMgmt->uScanChannel++;
-
- while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
- pMgmt->uScanChannel <= pDevice->byMaxChannel){
- pMgmt->uScanChannel++;
- }
-
- if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
- // Set Baseband to be not sensitive and rescan
- pDevice->eCommandState = WLAN_CMD_SCAN_END;
- }
- if ((pMgmt->b11hEnable == false) ||
- (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
- s_vProbeChannel(pDevice);
- vCommandTimerWait((void *) pDevice, 100);
- return;
- } else {
- vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME);
- return;
- }
- }
-
- break;
-
- case WLAN_CMD_SCAN_END:
-
- // Set Baseband's sensitivity back.
- if (pDevice->byBBType != pDevice->byScanBBType) {
- pDevice->byBBType = pDevice->byScanBBType;
- CARDvSetBSSMode(pDevice);
- }
-
- BBvSetShortSlotTime(pDevice);
- BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
- BBvUpdatePreEDThreshold(pDevice, false);
-
- // Set channel back
- vAdHocBeaconRestart(pDevice);
- // Set channel back
- CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
- // Set Filter
- if (pMgmt->bCurrBSSIDFilterOn) {
- MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
- pDevice->byRxMode |= RCR_BSSID;
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
- pMgmt->uScanChannel = 0;
- pMgmt->eScanState = WMAC_NO_SCANNING;
- pDevice->bStopDataPkt = false;
-
- /*send scan event to wpa_Supplicant*/
- PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
- memset(&wrqu, 0, sizeof(wrqu));
- wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
-
- break;
-
- case WLAN_CMD_DISASSOCIATE_START:
- pDevice->byReAssocCount = 0;
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
- (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
- break;
- } else {
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = false;
- pDevice->bWPASuppWextEnabled = false;
- pDevice->fWPA_Authened = false;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
- // reason = 8 : disassoc because sta has left
- vMgrDisassocBeginSta((void *) pDevice,
- pMgmt,
- pMgmt->abyCurrBSSID,
- (8),
- &Status);
- pDevice->bLinkPass = false;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
-
- // unlock command busy
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- pItemSSID->len = 0;
- memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pMgmt->sNodeDBTable[0].bActive = false;
-// pDevice->bBeaconBufReady = false;
- }
- netif_stop_queue(pDevice->dev);
- if (pDevice->bNeedRadioOFF == true)
- CARDbRadioPowerOff(pDevice);
-
- break;
-
- case WLAN_CMD_SSID_START:
-
- pDevice->byReAssocCount = 0;
- if (pDevice->bRadioOff == true)
- break;
-
- memcpy(pMgmt->abyAdHocSSID, pMgmt->abyDesireSSID,
- ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
-
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
-
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n", pItemSSID->len);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
- }
-
- if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
- ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
- if (pItemSSID->len == pItemSSIDCurr->len) {
- if (!memcmp(pItemSSID->abySSID,
- pItemSSIDCurr->abySSID, pItemSSID->len))
- break;
- }
- netif_stop_queue(pDevice->dev);
- pDevice->bLinkPass = false;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
- }
- // set initial state
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- PSvDisablePowerSaving((void *) pDevice);
- BSSvClearNodeDBTable(pDevice, 0);
- vMgrJoinBSSBegin((void *) pDevice, &Status);
- // if Infra mode
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
- // Call mgr to begin the deauthentication
- // reason = (3) because sta has left ESS
- if (pMgmt->eCurrState >= WMAC_STATE_AUTH) {
- vMgrDeAuthenBeginSta((void *)pDevice,
- pMgmt,
- pMgmt->abyCurrBSSID,
- (3),
- &Status);
- }
- // Call mgr to begin the authentication
- vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status);
- if (Status == CMD_STATUS_SUCCESS) {
- pDevice->byLinkWaitCount = 0;
- pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
- vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
- return;
- }
- }
- // if Adhoc mode
- else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
- if (netif_queue_stopped(pDevice->dev))
- netif_wake_queue(pDevice->dev);
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- pMgmt->sNodeDBTable[0].bActive = true;
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
- } else {
- // start own IBSS
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n");
- vMgrCreateOwnIBSS((void *) pDevice, &Status);
- if (Status != CMD_STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
- }
- BSSvAddMulticastNode(pDevice);
- }
- s_bClearBSSID_SCAN(pDevice);
- }
- // if SSID not found
- else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
- if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
- pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
- // start own IBSS
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n");
- vMgrCreateOwnIBSS((void *) pDevice, &Status);
- if (Status != CMD_STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
- }
- BSSvAddMulticastNode(pDevice);
- s_bClearBSSID_SCAN(pDevice);
-/*
- pDevice->bLinkPass = true;
- if (netif_queue_stopped(pDevice->dev)){
- netif_wake_queue(pDevice->dev);
- }
- s_bClearBSSID_SCAN(pDevice);
-*/
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
- // if(pDevice->bWPASuppWextEnabled == true)
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
- }
- }
- }
- break;
-
- case WLAN_AUTHENTICATE_WAIT:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
- if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
- pDevice->byLinkWaitCount = 0;
- // Call mgr to begin the association
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
- vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status);
- if (Status == CMD_STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
- pDevice->byLinkWaitCount = 0;
- pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
- vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT);
- return;
- }
- } else if (pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
- printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
- } else if (pDevice->byLinkWaitCount <= 4) {
- //mike add:wait another 2 sec if authenticated_frame delay!
- pDevice->byLinkWaitCount++;
- printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
- vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2);
+ if (vnt_init(priv)) {
+ /* If fail all ends TODO retry */
+ dev_err(&priv->usb->dev, "failed to start\n");
+ ieee80211_free_hw(priv->hw);
return;
}
- pDevice->byLinkWaitCount = 0;
-
- break;
-
- case WLAN_ASSOCIATE_WAIT:
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
- if (pDevice->ePSMode != WMAC_POWER_CAM) {
- PSvEnablePowerSaving((void *) pDevice,
- pMgmt->wListenInterval);
- }
-/*
- if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
- KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
- }
-*/
- pDevice->byLinkWaitCount = 0;
- pDevice->byReAssocCount = 0;
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- s_bClearBSSID_SCAN(pDevice);
-
- if (netif_queue_stopped(pDevice->dev))
- netif_wake_queue(pDevice->dev);
-
- } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
- printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
- } else if (pDevice->byLinkWaitCount <= 4) {
- //mike add:wait another 2 sec if associated_frame delay!
- pDevice->byLinkWaitCount++;
- printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n", pDevice->byLinkWaitCount);
- vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2);
- return;
- }
-
- break;
-
- case WLAN_CMD_AP_MODE_START:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
-
- if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
- cancel_delayed_work_sync(&pDevice->second_callback_work);
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- pDevice->bLinkPass = false;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
-
- BSSvClearNodeDBTable(pDevice, 0);
-
- pDevice->uAssocCount = 0;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pDevice->bFixRate = false;
-
- vMgrCreateOwnIBSS((void *) pDevice, &Status);
- if (Status != CMD_STATUS_SUCCESS) {
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "vMgrCreateOwnIBSS fail!\n");
- }
- // always turn off unicast bit
- MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
- pDevice->byRxMode &= ~RCR_UNICAST;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode);
- BSSvAddMulticastNode(pDevice);
- if (netif_queue_stopped(pDevice->dev))
- netif_wake_queue(pDevice->dev);
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- schedule_delayed_work(&pDevice->second_callback_work, HZ);
- }
- break;
-
- case WLAN_CMD_TX_PSPACKET_START:
- // DTIM Multicast tx
- if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
- while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
- if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
- pMgmt->abyPSTxMap[0] &= ~byMask[0];
- pDevice->bMoreData = false;
- } else {
- pDevice->bMoreData = true;
- }
-
- spin_lock_irqsave(&pDevice->lock, flags);
-
- if (nsDMA_tx_packet(pDevice, skb) != 0)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n");
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
-
- pMgmt->sNodeDBTable[0].wEnQueueCnt--;
- }
- }
-
- // PS nodes tx
- for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
- if (pMgmt->sNodeDBTable[ii].bActive &&
- pMgmt->sNodeDBTable[ii].bRxPSPoll) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
- ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
- while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
- if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
- // clear tx map
- pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
- ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
- pDevice->bMoreData = false;
- } else {
- pDevice->bMoreData = true;
- }
-
- spin_lock_irqsave(&pDevice->lock, flags);
- if (nsDMA_tx_packet(pDevice, skb) != 0)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n");
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
-
- pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
- // check if sta ps enable, wait next pspoll
- // if sta ps disable, send all pending buffers.
- if (pMgmt->sNodeDBTable[ii].bPSEnable)
- break;
- }
- if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
- // clear tx map
- pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
- ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii);
- }
- pMgmt->sNodeDBTable[ii].bRxPSPoll = false;
- }
- }
break;
- case WLAN_CMD_RADIO_START:
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
-// if (pDevice->bRadioCmd == true)
-// CARDbRadioPowerOn(pDevice);
-// else
-// CARDbRadioPowerOff(pDevice);
- {
- int ntStatus = STATUS_SUCCESS;
- u8 byTmp;
-
- ntStatus = vnt_control_in(pDevice,
- MESSAGE_TYPE_READ,
- MAC_REG_GPIOCTL1,
- MESSAGE_REQUEST_MACREG,
- 1,
- &byTmp);
-
- if (ntStatus != STATUS_SUCCESS)
- break;
- if ((byTmp & GPIO3_DATA) == 0) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n");
- // Old commands are useless.
- // empty command Q
- pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
- pDevice->uCmdDequeueIdx = 0;
- pDevice->uCmdEnqueueIdx = 0;
- //0415pDevice->bCmdRunning = false;
- pDevice->bCmdClear = true;
- pDevice->bStopTx0Pkt = false;
- pDevice->bStopDataPkt = true;
-
- pDevice->byKeyIndex = 0;
- pDevice->bTransmitKey = false;
-
- KeyvInitTable(pDevice, &pDevice->sKey);
-
- pMgmt->byCSSPK = KEY_CTL_NONE;
- pMgmt->byCSSGK = KEY_CTL_NONE;
-
- if (pDevice->bLinkPass == true) {
- // reason = 8 : disassoc because sta has left
- vMgrDisassocBeginSta((void *) pDevice,
- pMgmt,
- pMgmt->abyCurrBSSID,
- (8),
- &Status);
- pDevice->bLinkPass = false;
- // unlock command busy
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- pMgmt->sNodeDBTable[0].bActive = false;
- // if(pDevice->bWPASuppWextEnabled == true)
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
- }
- }
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = false;
- pDevice->bWPASuppWextEnabled = false;
- //clear current SSID
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- pItemSSID->len = 0;
- memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
- //clear desired SSID
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- pItemSSID->len = 0;
- memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
-
- netif_stop_queue(pDevice->dev);
- CARDbRadioPowerOff(pDevice);
- MACvRegBitsOn(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_OFF);
-
- pDevice->bHWRadioOff = true;
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n");
- pDevice->bHWRadioOff = false;
- CARDbRadioPowerOn(pDevice);
- MACvRegBitsOff(pDevice, MAC_REG_GPIOCTL1, GPIO3_INTMD);
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_ON);
- }
- }
-
+ case WLAN_CMD_TBTT_WAKEUP_START:
+ vnt_next_tbtt_wakeup(priv);
break;
- case WLAN_CMD_CHANGE_BBSENSITIVITY_START:
+ case WLAN_CMD_BECON_SEND_START:
+ if (!priv->vif)
+ break;
- pDevice->bStopDataPkt = true;
- pDevice->byBBVGACurrent = pDevice->byBBVGANew;
- BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent);
- pDevice->bStopDataPkt = false;
- break;
+ vnt_beacon_make(priv, priv->vif);
- case WLAN_CMD_TBTT_WAKEUP_START:
- PSbIsNextTBTTWakeUp(pDevice);
- break;
+ vnt_mac_reg_bits_on(priv, MAC_REG_TCR, TCR_AUTOBCNTX);
- case WLAN_CMD_BECON_SEND_START:
- bMgrPrepareBeaconToSend(pDevice, pMgmt);
break;
case WLAN_CMD_SETPOWER_START:
- vnt_rf_setpower(pDevice, pDevice->wCurrentRate,
- pMgmt->uCurrChannel);
+ vnt_rf_setpower(priv, priv->current_rate,
+ priv->hw->conf.chandef.chan->hw_value);
break;
case WLAN_CMD_CHANGE_ANTENNA_START:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel);
- if (pDevice->dwRxAntennaSel == 0) {
- pDevice->dwRxAntennaSel = 1;
- if (pDevice->bTxRxAntInv == true)
- BBvSetAntennaMode(pDevice, ANT_RXA);
+ dev_dbg(&priv->usb->dev, "Change from Antenna%d to",
+ priv->rx_antenna_sel);
+
+ if (priv->rx_antenna_sel == 0) {
+ priv->rx_antenna_sel = 1;
+ if (priv->tx_rx_ant_inv == true)
+ vnt_set_antenna_mode(priv, ANT_RXA);
else
- BBvSetAntennaMode(pDevice, ANT_RXB);
+ vnt_set_antenna_mode(priv, ANT_RXB);
} else {
- pDevice->dwRxAntennaSel = 0;
- if (pDevice->bTxRxAntInv == true)
- BBvSetAntennaMode(pDevice, ANT_RXB);
+ priv->rx_antenna_sel = 0;
+ if (priv->tx_rx_ant_inv == true)
+ vnt_set_antenna_mode(priv, ANT_RXB);
else
- BBvSetAntennaMode(pDevice, ANT_RXA);
+ vnt_set_antenna_mode(priv, ANT_RXA);
}
break;
- case WLAN_CMD_REMOVE_ALLKEY_START:
- KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
- break;
-
- case WLAN_CMD_MAC_DISPOWERSAVING_START:
- vnt_control_in_u8(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
- if ((byData & PSCTL_PS) != 0) {
- // disable power saving hw function
- vnt_control_out(pDevice,
- MESSAGE_TYPE_DISABLE_PS,
- 0,
- 0,
- 0,
- NULL
- );
- }
- break;
-
- case WLAN_CMD_11H_CHSW_START:
- CARDbSetMediaChannel(pDevice, pDevice->byNewChannel);
- pDevice->bChannelSwitch = false;
- pMgmt->uCurrChannel = pDevice->byNewChannel;
- pDevice->bStopDataPkt = false;
- break;
-
- case WLAN_CMD_CONFIGURE_FILTER_START:
- vnt_configure_filter(pDevice);
- break;
default:
break;
- } //switch
-
- s_bCommandComplete(pDevice);
-
- return;
-}
-
-static int s_bCommandComplete(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PWLAN_IE_SSID pSSID;
- int bRadioCmd = false;
- int bForceSCAN = true;
-
- pDevice->eCommandState = WLAN_CMD_IDLE;
- if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
- //Command Queue Empty
- pDevice->bCmdRunning = false;
- return true;
- } else {
- pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
- pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
- bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
- bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
- ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
- pDevice->cbFreeCmdQueue++;
- pDevice->bCmdRunning = true;
- switch (pDevice->eCommand) {
- case WLAN_CMD_BSSID_SCAN:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
- pDevice->eCommandState = WLAN_CMD_SCAN_START;
- pMgmt->uScanChannel = 0;
- if (pSSID->len != 0)
- memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- else
- memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-/*
- if ((bForceSCAN == false) && (pDevice->bLinkPass == true)) {
- if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
- ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
- pDevice->eCommandState = WLAN_CMD_IDLE;
- }
- }
-*/
- break;
- case WLAN_CMD_SSID:
- pDevice->eCommandState = WLAN_CMD_SSID_START;
- if (pSSID->len > WLAN_SSID_MAXLEN)
- pSSID->len = WLAN_SSID_MAXLEN;
- if (pSSID->len != 0)
- memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
- break;
- case WLAN_CMD_DISASSOCIATE:
- pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
- break;
- case WLAN_CMD_RX_PSPOLL:
- pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
- break;
- case WLAN_CMD_RUN_AP:
- pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
- break;
- case WLAN_CMD_RADIO:
- pDevice->eCommandState = WLAN_CMD_RADIO_START;
- pDevice->bRadioCmd = bRadioCmd;
- break;
- case WLAN_CMD_CHANGE_BBSENSITIVITY:
- pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START;
- break;
-
- case WLAN_CMD_TBTT_WAKEUP:
- pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START;
- break;
-
- case WLAN_CMD_BECON_SEND:
- pDevice->eCommandState = WLAN_CMD_BECON_SEND_START;
- break;
-
- case WLAN_CMD_SETPOWER:
- pDevice->eCommandState = WLAN_CMD_SETPOWER_START;
- break;
-
- case WLAN_CMD_CHANGE_ANTENNA:
- pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START;
- break;
-
- case WLAN_CMD_REMOVE_ALLKEY:
- pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START;
- break;
-
- case WLAN_CMD_MAC_DISPOWERSAVING:
- pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START;
- break;
-
- case WLAN_CMD_11H_CHSW:
- pDevice->eCommandState = WLAN_CMD_11H_CHSW_START;
- break;
-
- case WLAN_CMD_CONFIGURE_FILTER:
- pDevice->eCommandState =
- WLAN_CMD_CONFIGURE_FILTER_START;
- break;
-
- default:
- break;
- }
- vCommandTimerWait(pDevice, 0);
}
- return true;
+ vnt_cmd_complete(priv);
}
-int bScheduleCommand(struct vnt_private *pDevice,
- CMD_CODE eCommand, u8 *pbyItem0)
+int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd command)
{
- if (pDevice->cbFreeCmdQueue == 0)
+ if (priv->free_cmd_queue == 0)
return false;
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = true;
- memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- if (pbyItem0 != NULL) {
- switch (eCommand) {
- case WLAN_CMD_BSSID_SCAN:
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = false;
- memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
- pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- break;
-
- case WLAN_CMD_SSID:
- memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
- pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- break;
-
- case WLAN_CMD_DISASSOCIATE:
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
- break;
-/*
- case WLAN_CMD_DEAUTH:
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((u16 *)pbyItem0);
- break;
-*/
-
- case WLAN_CMD_RADIO:
- pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
- break;
- default:
- break;
- }
- }
+ priv->cmd_queue[priv->cmd_enqueue_idx] = command;
- ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
- pDevice->cbFreeCmdQueue--;
+ ADD_ONE_WITH_WRAP_AROUND(priv->cmd_enqueue_idx, CMD_Q_SIZE);
+ priv->free_cmd_queue--;
- if (pDevice->bCmdRunning == false)
- s_bCommandComplete(pDevice);
+ if (priv->cmd_running == false)
+ vnt_cmd_complete(priv);
return true;
}
-/*
- * Description:
- * Clear BSSID_SCAN cmd in CMD Queue
- *
- * Parameters:
- * In:
- * hDeviceContext - Pointer to the adapter
- * eCommand - Command
- * Out:
- * none
- *
- * Return Value: true if success; otherwise false
- *
- */
-static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
+void vnt_reset_command_timer(struct vnt_private *priv)
{
- unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
- unsigned int ii;
-
- if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
- for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii++) {
- if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
- pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
- ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
- if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
- break;
- }
- }
- return true;
-}
-
-//mike add:reset command timer
-void vResetCommandTimer(struct vnt_private *pDevice)
-{
- cancel_delayed_work_sync(&pDevice->run_command_work);
-
- pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
- pDevice->uCmdDequeueIdx = 0;
- pDevice->uCmdEnqueueIdx = 0;
- pDevice->eCommandState = WLAN_CMD_IDLE;
- pDevice->bCmdRunning = false;
- pDevice->bCmdClear = false;
+ priv->free_cmd_queue = CMD_Q_SIZE;
+ priv->cmd_dequeue_idx = 0;
+ priv->cmd_enqueue_idx = 0;
+ priv->command_state = WLAN_CMD_IDLE;
+ priv->cmd_running = false;
}
diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h
index 736572101bad..2b0ee285eb0b 100644
--- a/drivers/staging/vt6656/wcmd.h
+++ b/drivers/staging/vt6656/wcmd.h
@@ -29,84 +29,35 @@
#ifndef __WCMD_H__
#define __WCMD_H__
-#include "80211hdr.h"
-#include "80211mgr.h"
+#include "device.h"
-#define AUTHENTICATE_TIMEOUT 1000 //ms
-#define ASSOCIATE_TIMEOUT 1000 //ms
-
-// Command code
-typedef enum tagCMD_CODE {
- WLAN_CMD_BSSID_SCAN,
- WLAN_CMD_SSID,
- WLAN_CMD_DISASSOCIATE,
- WLAN_CMD_DEAUTH,
- WLAN_CMD_RX_PSPOLL,
- WLAN_CMD_RADIO,
- WLAN_CMD_CHANGE_BBSENSITIVITY,
- WLAN_CMD_SETPOWER,
- WLAN_CMD_TBTT_WAKEUP,
- WLAN_CMD_BECON_SEND,
- WLAN_CMD_CHANGE_ANTENNA,
- WLAN_CMD_REMOVE_ALLKEY,
- WLAN_CMD_MAC_DISPOWERSAVING,
- WLAN_CMD_11H_CHSW,
- WLAN_CMD_RUN_AP,
- WLAN_CMD_CONFIGURE_FILTER
-} CMD_CODE, *PCMD_CODE;
+/* Command code */
+enum vnt_cmd {
+ WLAN_CMD_INIT_MAC80211,
+ WLAN_CMD_SETPOWER,
+ WLAN_CMD_TBTT_WAKEUP,
+ WLAN_CMD_BECON_SEND,
+ WLAN_CMD_CHANGE_ANTENNA
+};
#define CMD_Q_SIZE 32
-typedef enum tagCMD_STATUS {
-
- CMD_STATUS_SUCCESS = 0,
- CMD_STATUS_FAILURE,
- CMD_STATUS_RESOURCES,
- CMD_STATUS_TIMEOUT,
- CMD_STATUS_PENDING
-
-} CMD_STATUS, *PCMD_STATUS;
-
-typedef struct tagCMD_ITEM {
- CMD_CODE eCmd;
- u8 abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- bool bNeedRadioOFF;
- bool bRadioCmd;
- bool bForceSCAN;
- u16 wDeAuthenReason;
-} CMD_ITEM, *PCMD_ITEM;
-
-// Command state
-typedef enum tagCMD_STATE {
- WLAN_CMD_SCAN_START,
- WLAN_CMD_SCAN_END,
- WLAN_CMD_DISASSOCIATE_START,
- WLAN_CMD_DEAUTHEN_START,
- WLAN_CMD_SSID_START,
- WLAN_AUTHENTICATE_WAIT,
- WLAN_ASSOCIATE_WAIT,
- WLAN_DISASSOCIATE_WAIT,
- WLAN_CMD_TX_PSPACKET_START,
- WLAN_CMD_RADIO_START,
- WLAN_CMD_CHANGE_BBSENSITIVITY_START,
- WLAN_CMD_SETPOWER_START,
- WLAN_CMD_AP_MODE_START,
- WLAN_CMD_TBTT_WAKEUP_START,
- WLAN_CMD_BECON_SEND_START,
- WLAN_CMD_CHANGE_ANTENNA_START,
- WLAN_CMD_REMOVE_ALLKEY_START,
- WLAN_CMD_MAC_DISPOWERSAVING_START,
- WLAN_CMD_11H_CHSW_START,
- WLAN_CMD_CONFIGURE_FILTER_START,
- WLAN_CMD_IDLE
-} CMD_STATE, *PCMD_STATE;
+/* Command state */
+enum vnt_cmd_state {
+ WLAN_CMD_INIT_MAC80211_START,
+ WLAN_CMD_SETPOWER_START,
+ WLAN_CMD_TBTT_WAKEUP_START,
+ WLAN_CMD_BECON_SEND_START,
+ WLAN_CMD_CHANGE_ANTENNA_START,
+ WLAN_CMD_IDLE
+};
struct vnt_private;
-void vResetCommandTimer(struct vnt_private *);
+void vnt_reset_command_timer(struct vnt_private *);
-int bScheduleCommand(struct vnt_private *, CMD_CODE eCommand, u8 *pbyItem0);
+int vnt_schedule_command(struct vnt_private *, enum vnt_cmd);
-void vRunCommand(struct work_struct *work);
+void vnt_run_command(struct work_struct *work);
#endif /* __WCMD_H__ */
diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c
deleted file mode 100644
index efdc5d5d38ee..000000000000
--- a/drivers/staging/vt6656/wctl.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: wctl.c
- *
- * Purpose: handle WMAC duplicate filter & defragment
- *
- * Author: Jerry Chen
- *
- * Date: Jun. 27, 2002
- *
- * Functions:
- * WCTLbIsDuplicate - Test if duplicate packet
- * WCTLuSearchDFCB - Search DeFragment Control Database
- * WCTLuInsertDFCB - Insert DeFragment Control Database
- * WCTLbHandleFragment - Handle received fragment packet
- *
- * Revision History:
- *
- */
-
-#include "wctl.h"
-#include "device.h"
-#include "card.h"
-#include "tmacro.h"
-
-// static int msglevel =MSG_LEVEL_INFO;
-
-/*
- * Description:
- * Scan Rx cache. Return true if packet is duplicate, else
- * inserts in receive cache and returns false.
- *
- * Parameters:
- * In:
- * pCache - Receive packets history
- * pMACHeader - 802.11 MAC Header of received packet
- * Out:
- * none
- *
- * Return Value: true if packet duplicate; otherwise false
- *
- */
-
-bool WCTLbIsDuplicate (PSCache pCache, struct ieee80211_hdr *pMACHeader)
-{
- unsigned int uIndex;
- unsigned int ii;
- PSCacheEntry pCacheEntry;
-
- if (IS_FC_RETRY(pMACHeader)) {
-
- uIndex = pCache->uInPtr;
- for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
- pCacheEntry = &(pCache->asCacheEntry[uIndex]);
- if ((pCacheEntry->wFmSequence == pMACHeader->seq_ctrl) &&
- ether_addr_equal(pCacheEntry->abyAddr2, pMACHeader->addr2) &&
- (pCacheEntry->wFrameCtl == pMACHeader->frame_control)
- ) {
- /* Duplicate match */
- return true;
- }
- ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH);
- }
- }
- /* Not found in cache - insert */
- pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr];
- pCacheEntry->wFmSequence = pMACHeader->seq_ctrl;
- memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->addr2[0]), ETH_ALEN);
- pCacheEntry->wFrameCtl = pMACHeader->frame_control;
- ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH);
- return false;
-}
-
-/*
- * Description:
- * Found if sequence number of received fragment packet in Defragment Database
- *
- * Parameters:
- * In:
- * pDevice - Pointer to adapter
- * pMACHeader - 802.11 MAC Header of received packet
- * Out:
- * none
- *
- * Return Value: index number in Defragment Database
- *
- */
-
-unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice,
- struct ieee80211_hdr *pMACHeader)
-{
- unsigned int ii;
-
- for (ii = 0; ii < pDevice->cbDFCB; ii++) {
- if ((pDevice->sRxDFCB[ii].bInUse == true) &&
- ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
- pMACHeader->addr2)) {
- return ii;
- }
- }
- return pDevice->cbDFCB;
-}
-
-/*
- * Description:
- * Insert received fragment packet in Defragment Database
- *
- * Parameters:
- * In:
- * pDevice - Pointer to adapter
- * pMACHeader - 802.11 MAC Header of received packet
- * Out:
- * none
- *
- * Return Value: index number in Defragment Database
- *
- */
-unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice,
- struct ieee80211_hdr *pMACHeader)
-{
- unsigned int ii;
-
- if (pDevice->cbFreeDFCB == 0)
- return(pDevice->cbDFCB);
- for (ii = 0; ii < pDevice->cbDFCB; ii++) {
- if (pDevice->sRxDFCB[ii].bInUse == false) {
- pDevice->cbFreeDFCB--;
- pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
- pDevice->sRxDFCB[ii].bInUse = true;
- pDevice->sRxDFCB[ii].wSequence = (pMACHeader->seq_ctrl >> 4);
- pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->seq_ctrl & 0x000F);
- memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
- &(pMACHeader->addr2[0]),
- ETH_ALEN);
- return(ii);
- }
- }
- return(pDevice->cbDFCB);
-}
-
-/*
- * Description:
- * Handle received fragment packet
- *
- * Parameters:
- * In:
- * pDevice - Pointer to adapter
- * pMACHeader - 802.11 MAC Header of received packet
- * cbFrameLength - Frame length
- * bWEP - is WEP packet
- * Out:
- * none
- *
- * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false
- *
- */
-bool WCTLbHandleFragment(struct vnt_private *pDevice, struct ieee80211_hdr *pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV)
-{
- unsigned int uHeaderSize;
-
- if (bWEP == true) {
- uHeaderSize = 28;
- if (bExtIV)
- // ExtIV
- uHeaderSize +=4;
- }
- else {
- uHeaderSize = 24;
- }
-
- if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) {
- pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
- if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) {
- // duplicate, we must flush previous DCB
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime;
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->seq_ctrl >> 4);
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->seq_ctrl & 0x000F);
- }
- else {
- pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader);
- if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) {
- return(false);
- }
- }
- // reserve 8 byte to match MAC RX Buffer
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8);
-// pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (u8 *) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
- memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength);
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength;
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength;
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
- return(false);
- }
- else {
- pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
- if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) {
- if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->seq_ctrl >> 4)) &&
- (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->seq_ctrl & 0x000F)) &&
- ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) {
-
- memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((u8 *) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
- }
- else {
- // seq error or frag # error flush DFCB
- pDevice->cbFreeDFCB++;
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false;
- return(false);
- }
- }
- else {
- return(false);
- }
- if (IS_LAST_FRAGMENT_PKT(pMACHeader)) {
- //enq defragcontrolblock
- pDevice->cbFreeDFCB++;
- pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = false;
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
- return(true);
- }
- return(false);
- }
-}
-
diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h
deleted file mode 100644
index 14cb41177045..000000000000
--- a/drivers/staging/vt6656/wctl.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: wctl.h
- *
- * Purpose:
- *
- * Author: Jerry Chen
- *
- * Date: Jun. 27, 2002
- *
- */
-
-#ifndef __WCTL_H__
-#define __WCTL_H__
-
-#include "tether.h"
-#include "device.h"
-
-#define IS_TYPE_DATA(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_DATA)
-
-#define IS_TYPE_MGMT(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_MGMT)
-
-#define IS_TYPE_CONTROL(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_802_11_MASK) == TYPE_802_11_CTL)
-
-#define IS_FC_MOREDATA(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREDATA) == FC_MOREDATA)
-
-#define IS_FC_POWERMGT(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_POWERMGT) == FC_POWERMGT)
-
-#define IS_FC_RETRY(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_RETRY) == FC_RETRY)
-
-#define IS_FC_WEP(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_WEP) == FC_WEP)
-
-#ifdef __BIG_ENDIAN
-
-#define IS_FRAGMENT_PKT(pMACHeader) \
- (((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) != 0) | \
- ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x0F00) != 0))
-
-#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x0F00) == 0)
-
-#else
-
-#define IS_FRAGMENT_PKT(pMACHeader) \
- (((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) != 0) | \
- ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x000F) != 0))
-
-#define IS_FIRST_FRAGMENT_PKT(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->seq_ctrl & 0x000F) == 0)
-
-#endif//#ifdef __BIG_ENDIAN
-
-#define IS_LAST_FRAGMENT_PKT(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & FC_MOREFRAG) == 0)
-
-#define IS_CTL_PSPOLL(pMACHeader) \
- ((((struct ieee80211_hdr *) pMACHeader)->frame_control & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL)
-
-#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) { \
- if ((uVar) >= ((uModulo) - 1)) \
- (uVar) = 0; \
- else \
- (uVar)++; \
-}
-
-bool WCTLbIsDuplicate(PSCache pCache, struct ieee80211_hdr *pMACHeader);
-bool WCTLbHandleFragment(struct vnt_private *, struct ieee80211_hdr *pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV);
-unsigned int WCTLuSearchDFCB(struct vnt_private *, struct ieee80211_hdr *pMACHeader);
-unsigned int WCTLuInsertDFCB(struct vnt_private *, struct ieee80211_hdr *pMACHeader);
-
-#endif /* __WCTL_H__ */
diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c
deleted file mode 100644
index 18723eab93d2..000000000000
--- a/drivers/staging/vt6656/wmgr.c
+++ /dev/null
@@ -1,4362 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wmgr.c
- *
- * Purpose: Handles the 802.11 management functions
- *
- * Author: Lyndon Chen
- *
- * Date: May 8, 2002
- *
- * Functions:
- * nsMgrObjectInitial - Initialize Management Objet data structure
- * vMgrObjectReset - Reset Management Object data structure
- * vMgrAssocBeginSta - Start associate function
- * vMgrReAssocBeginSta - Start reassociate function
- * vMgrDisassocBeginSta - Start disassociate function
- * s_vMgrRxAssocRequest - Handle Rcv associate_request
- * s_vMgrRxAssocResponse - Handle Rcv associate_response
- * vMrgAuthenBeginSta - Start authentication function
- * vMgrDeAuthenDeginSta - Start deauthentication function
- * s_vMgrRxAuthentication - Handle Rcv authentication
- * s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
- * s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
- * s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
- * s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
- * s_vMgrRxDisassociation - Handle Rcv disassociation
- * s_vMgrRxBeacon - Handle Rcv Beacon
- * vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
- * vMgrJoinBSSBegin - Join BSS function
- * s_vMgrSynchBSS - Synch & adopt BSS parameters
- * s_MgrMakeBeacon - Create Baecon frame
- * s_MgrMakeProbeResponse - Create Probe Response frame
- * s_MgrMakeAssocRequest - Create Associate Request frame
- * s_MgrMakeReAssocRequest - Create ReAssociate Request frame
- * s_vMgrRxProbeResponse - Handle Rcv probe_response
- * s_vMrgRxProbeRequest - Handle Rcv probe_request
- * bMgrPrepareBeaconToSend - Prepare Beacon frame
- * s_vMgrLogStatus - Log 802.11 Status
- * vMgrRxManagePacket - Rcv management frame dispatch function
- * s_vMgrFormatTIM- Assembler TIM field of beacon
- * vMgrTimerInit- Initial 1-sec and command call back funtions
- *
- * Revision History:
- *
- */
-
-#include "tmacro.h"
-#include "desc.h"
-#include "device.h"
-#include "card.h"
-#include "80211hdr.h"
-#include "80211mgr.h"
-#include "wmgr.h"
-#include "wcmd.h"
-#include "mac.h"
-#include "bssdb.h"
-#include "power.h"
-#include "datarate.h"
-#include "baseband.h"
-#include "rxtx.h"
-#include "wpa.h"
-#include "rf.h"
-#include "iowpa.h"
-#include "usbpipe.h"
-
-static int msglevel = MSG_LEVEL_INFO;
-//static int msglevel =MSG_LEVEL_DEBUG;
-
-static int ChannelExceedZoneType(struct vnt_private *, u8 byCurrChannel);
-
-/* Association/diassociation functions */
-static struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *,
- struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
- u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
- PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-static void s_vMgrRxAssocRequest(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- u32 uNodeIndex);
-
-static struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *,
- struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
- u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
- PWLAN_IE_SUPP_RATES pCurrRates, PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-static void s_vMgrRxAssocResponse(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- int bReAssocType);
-
-static void s_vMgrRxDisassociation(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
-
-/* Authentication/deauthen functions */
-static void s_vMgrRxAuthenSequence_1(struct vnt_private *,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
-
-static void s_vMgrRxAuthenSequence_2(struct vnt_private *,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
-
-static void s_vMgrRxAuthenSequence_3(struct vnt_private *,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
-
-static void s_vMgrRxAuthenSequence_4(struct vnt_private *,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame);
-
-static void s_vMgrRxAuthentication(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
-
-static void s_vMgrRxDeauthentication(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
-
-/* Scan functions
-* probe request/response functions */
-
-static void s_vMgrRxProbeRequest(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
-
-static void s_vMgrRxProbeResponse(struct vnt_private *,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket);
-
-/* beacon functions */
-static void s_vMgrRxBeacon(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- int bInScan);
-
-static void s_vMgrFormatTIM(struct vnt_manager *pMgmt, PWLAN_IE_TIM pTIM);
-
-static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
- u32 uCurrChannel, u16 wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID,
- u8 *pCurrBSSID, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-/* Association response */
-static struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
- u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-/* ReAssociation response */
-static struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
- u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates);
-
-/* Probe response */
-static struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
- u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr,
- PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID,
- PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates, u8 byPHYType);
-
-/* received status */
-static void s_vMgrLogStatus(struct vnt_manager *pMgmt, u16 wStatus);
-
-static void s_vMgrSynchBSS(struct vnt_private *, u32 uBSSMode,
- PKnownBSS pCurr, PCMD_STATUS pStatus);
-
-static bool
-s_bCipherMatch (
- PKnownBSS pBSSNode,
- NDIS_802_11_ENCRYPTION_STATUS EncStatus,
- u8 * pbyCCSPK,
- u8 * pbyCCSGK
- );
-
-static void Encyption_Rebuild(struct vnt_private *, PKnownBSS pCurr);
-
-/*+
- *
- * Routine Description:
- * Allocates and initializes the Management object.
- *
- * Return Value:
- * Ndis_staus.
- *
--*/
-
-void vMgrObjectInit(struct vnt_private *pDevice)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- int ii;
-
- pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
- pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
- pMgmt->uCurrChannel = pDevice->uChannel;
- for (ii = 0; ii < WLAN_BSSID_LEN; ii++)
- pMgmt->abyDesireBSSID[ii] = 0xFF;
-
- pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
- //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
- pMgmt->byCSSPK = KEY_CTL_NONE;
- pMgmt->byCSSGK = KEY_CTL_NONE;
- pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
- BSSvClearBSSList((void *) pDevice, false);
-
- pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
- pDevice->uCmdDequeueIdx = 0;
- pDevice->uCmdEnqueueIdx = 0;
- pDevice->eCommandState = WLAN_CMD_IDLE;
- pDevice->bCmdRunning = false;
- pDevice->bCmdClear = false;
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Start the station association procedure. Namely, send an
- * association request frame to the AP.
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrAssocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
-{
- struct vnt_tx_mgmt *pTxPacket;
-
- pMgmt->wCurrCapInfo = 0;
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
- if (pDevice->bEncryptionEnable) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
- }
- // always allow receive short preamble
- //if (pDevice->byPreambleType == 1) {
- // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- //}
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- if (pMgmt->wListenInterval == 0)
- pMgmt->wListenInterval = 1; // at least one.
-
- // ERP Phy (802.11g) should support short preamble.
- if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- if (pDevice->bShortSlotTime == true)
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
-
- } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
- if (pDevice->byPreambleType == 1) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- }
- }
- if (pMgmt->b11hEnable == true)
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
-
- // build an assocreq frame and send it
- pTxPacket = s_MgrMakeAssocRequest
- (
- pDevice,
- pMgmt,
- pMgmt->abyCurrBSSID,
- pMgmt->wCurrCapInfo,
- pMgmt->wListenInterval,
- (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
- );
-
- if (pTxPacket != NULL ){
- // send the frame
- *pStatus = csMgmt_xmit(pDevice, pTxPacket);
- if (*pStatus == CMD_STATUS_PENDING) {
- pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
- *pStatus = CMD_STATUS_SUCCESS;
- }
- }
- else
- *pStatus = CMD_STATUS_RESOURCES;
-
- return ;
-}
-
-/*+
- *
- * Routine Description:
- * Start the station re-association procedure.
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrReAssocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
-{
- struct vnt_tx_mgmt *pTxPacket;
-
- pMgmt->wCurrCapInfo = 0;
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
- if (pDevice->bEncryptionEnable) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
- }
-
- //if (pDevice->byPreambleType == 1) {
- // pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- //}
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
-
- if (pMgmt->wListenInterval == 0)
- pMgmt->wListenInterval = 1; // at least one.
-
- // ERP Phy (802.11g) should support short preamble.
- if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- if (pDevice->bShortSlotTime == true)
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
-
- } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
- if (pDevice->byPreambleType == 1) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- }
- }
- if (pMgmt->b11hEnable == true)
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
-
- pTxPacket = s_MgrMakeReAssocRequest
- (
- pDevice,
- pMgmt,
- pMgmt->abyCurrBSSID,
- pMgmt->wCurrCapInfo,
- pMgmt->wListenInterval,
- (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
- );
-
- if (pTxPacket != NULL ){
- // send the frame
- *pStatus = csMgmt_xmit(pDevice, pTxPacket);
- if (*pStatus != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
- }
- }
-
- return ;
-}
-
-/*+
- *
- * Routine Description:
- * Send an dis-association request frame to the AP.
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrDisassocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u8 *abyDestAddress, u16 wReason,
- PCMD_STATUS pStatus)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_DISASSOC sFrame;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_DISASSOC_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
-
- // Setup the sFrame structure
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
-
- // format fixed field frame structure
- vMgrEncodeDisassociation(&sFrame);
-
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
- ));
-
- memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- // Set reason code
- *(sFrame.pwReason) = cpu_to_le16(wReason);
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- // send the frame
- *pStatus = csMgmt_xmit(pDevice, pTxPacket);
- if (*pStatus == CMD_STATUS_PENDING) {
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- *pStatus = CMD_STATUS_SUCCESS;
- }
-
- return;
-}
-
-/*+
- *
- * Routine Description:(AP function)
- * Handle incoming station association request frames.
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAssocRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- u32 uNodeIndex)
-{
- WLAN_FR_ASSOCREQ sFrame;
- CMD_STATUS Status;
- struct vnt_tx_mgmt *pTxPacket;
- u16 wAssocStatus = 0;
- u16 wAssocAID = 0;
- u32 uRateLen = WLAN_RATES_MAXLEN;
- u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-
- if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
- return;
- // node index not found
- if (!uNodeIndex)
- return;
-
- //check if node is authenticated
- //decode the frame
- memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
- memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
- memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
-
- vMgrDecodeAssocRequest(&sFrame);
-
- if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
- pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
- pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
- pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
- WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
- // Todo: check sta basic rate, if ap can't support, set status code
- if (pDevice->byBBType == BB_TYPE_11B) {
- uRateLen = WLAN_RATES_MAXLEN_11B;
- }
- abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
- abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
- uRateLen);
- abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
- if (pDevice->byBBType == BB_TYPE_11G) {
- abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
- uRateLen);
- } else {
- abyCurrExtSuppRates[1] = 0;
- }
-
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
- false, // do not change our basic rate
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
- );
-
- // set max tx rate
- pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
- pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
- // Todo: check sta preamble, if ap can't support, set status code
- pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
- WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
- WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)uNodeIndex;
- wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
- wAssocAID = (u16)uNodeIndex;
- // check if ERP support
- if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
- pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
-
- if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
- // B only STA join
- pDevice->bProtectMode = true;
- pDevice->bNonERPPresent = true;
- }
- if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
- pDevice->bBarkerPreambleMd = true;
- }
-
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
- sFrame.pHdr->sA3.abyAddr2[0],
- sFrame.pHdr->sA3.abyAddr2[1],
- sFrame.pHdr->sA3.abyAddr2[2],
- sFrame.pHdr->sA3.abyAddr2[3],
- sFrame.pHdr->sA3.abyAddr2[4],
- sFrame.pHdr->sA3.abyAddr2[5]
- ) ;
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
- pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
- }
-
- // assoc response reply..
- pTxPacket = s_MgrMakeAssocResponse
- (
- pDevice,
- pMgmt,
- pMgmt->wCurrCapInfo,
- wAssocStatus,
- wAssocAID,
- sFrame.pHdr->sA3.abyAddr2,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
- );
- if (pTxPacket != NULL ){
- /* send the frame */
- Status = csMgmt_xmit(pDevice, pTxPacket);
- if (Status != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
- }
-
- }
-
- return;
-}
-
-/*+
- *
- * Description:(AP function)
- * Handle incoming station re-association request frames.
- *
- * Parameters:
- * In:
- * pMgmt - Management Object structure
- * pRxPacket - Received Packet
- * Out:
- * none
- *
- * Return Value: None.
- *
--*/
-
-static void s_vMgrRxReAssocRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- u32 uNodeIndex)
-{
- WLAN_FR_REASSOCREQ sFrame;
- CMD_STATUS Status;
- struct vnt_tx_mgmt *pTxPacket;
- u16 wAssocStatus = 0;
- u16 wAssocAID = 0;
- u32 uRateLen = WLAN_RATES_MAXLEN;
- u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
-
- if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
- return;
- // node index not found
- if (!uNodeIndex)
- return;
- //check if node is authenticated
- //decode the frame
- memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeReassocRequest(&sFrame);
-
- if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
- pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
- pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
- pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
- WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
- // Todo: check sta basic rate, if ap can't support, set status code
-
- if (pDevice->byBBType == BB_TYPE_11B) {
- uRateLen = WLAN_RATES_MAXLEN_11B;
- }
-
- abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
- abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
- uRateLen);
- abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
- if (pDevice->byBBType == BB_TYPE_11G) {
- abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
- uRateLen);
- } else {
- abyCurrExtSuppRates[1] = 0;
- }
-
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
- false, // do not change our basic rate
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
- );
-
- // set max tx rate
- pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
- pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
- // Todo: check sta preamble, if ap can't support, set status code
- pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
- WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
- WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].wAID = (u16)uNodeIndex;
- wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
- wAssocAID = (u16)uNodeIndex;
-
- // if suppurt ERP
- if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
- pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
-
- if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
- // B only STA join
- pDevice->bProtectMode = true;
- pDevice->bNonERPPresent = true;
- }
- if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
- pDevice->bBarkerPreambleMd = true;
- }
-
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
- sFrame.pHdr->sA3.abyAddr2[0],
- sFrame.pHdr->sA3.abyAddr2[1],
- sFrame.pHdr->sA3.abyAddr2[2],
- sFrame.pHdr->sA3.abyAddr2[3],
- sFrame.pHdr->sA3.abyAddr2[4],
- sFrame.pHdr->sA3.abyAddr2[5]
- ) ;
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
- pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
-
- }
-
- // assoc response reply..
- pTxPacket = s_MgrMakeReAssocResponse
- (
- pDevice,
- pMgmt,
- pMgmt->wCurrCapInfo,
- wAssocStatus,
- wAssocAID,
- sFrame.pHdr->sA3.abyAddr2,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
- );
-
- if (pTxPacket != NULL ){
- /* send the frame */
- Status = csMgmt_xmit(pDevice, pTxPacket);
- if (Status != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
- }
- }
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Handle incoming association response frames.
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAssocResponse(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- int bReAssocType)
-{
- WLAN_FR_ASSOCRESP sFrame;
- PWLAN_IE_SSID pItemSSID;
- u8 *pbyIEs;
-
- if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
- pMgmt->eCurrState == WMAC_STATE_ASSOC) {
-
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- // decode the frame
- vMgrDecodeAssocResponse(&sFrame);
- if ((sFrame.pwCapInfo == NULL)
- || (sFrame.pwStatus == NULL)
- || (sFrame.pwAid == NULL)
- || (sFrame.pSuppRates == NULL)) {
- return;
- }
-
- pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
- pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
- pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
- pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
-
- pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
- pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
- pbyIEs = pMgmt->sAssocInfo.abyIEs;
- pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
- memcpy(pbyIEs, (sFrame.pBuf + 24 +6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
-
- // save values and set current BSS state
- if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
- // set AID
- pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
- if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
- {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
- }
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
- pMgmt->eCurrState = WMAC_STATE_ASSOC;
- BSSvUpdateAPNode((void *) pDevice,
- sFrame.pwCapInfo,
- sFrame.pSuppRates,
- sFrame.pExtSuppRates);
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- //if(pDevice->bWPASuppWextEnabled == true)
- {
- u8 buf[512];
- size_t len;
- union iwreq_data wrqu;
- int we_event;
-
- memset(buf, 0, 512);
-
- len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
- if(len) {
- memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
- memset(&wrqu, 0, sizeof (wrqu));
- wrqu.data.length = len;
- we_event = IWEVASSOCREQIE;
- PRINT_K("wireless_send_event--->IWEVASSOCREQIE\n");
- wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
- }
-
- memset(buf, 0, 512);
- len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
-
- if(len) {
- memcpy(buf, pbyIEs, len);
- memset(&wrqu, 0, sizeof (wrqu));
- wrqu.data.length = len;
- we_event = IWEVASSOCRESPIE;
- PRINT_K("wireless_send_event--->IWEVASSOCRESPIE\n");
- wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
- }
-
- memset(&wrqu, 0, sizeof (wrqu));
- memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(associated)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
-
- }
-
- }
- else {
- if (bReAssocType) {
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- }
- else {
- // jump back to the auth state and indicate the error
- pMgmt->eCurrState = WMAC_STATE_AUTH;
- }
- s_vMgrLogStatus(pMgmt,cpu_to_le16((*(sFrame.pwStatus))));
- }
-
- }
-
-//need clear flags related to Networkmanager
- pDevice->bwextstep0 = false;
- pDevice->bwextstep1 = false;
- pDevice->bwextstep2 = false;
- pDevice->bwextstep3 = false;
- pDevice->bWPASuppWextEnabled = false;
-
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
- schedule_delayed_work(&pDevice->run_command_work, 0);
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Start the station authentication procedure. Namely, send an
- * authentication frame to the AP.
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrAuthenBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PCMD_STATUS pStatus)
-{
- WLAN_FR_AUTHEN sFrame;
- struct vnt_tx_mgmt *pTxPacket =
- (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
-
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_AUTHEN_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
- vMgrEncodeAuthen(&sFrame);
- /* insert values */
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- if (pMgmt->bShareKeyAlgorithm)
- *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
- else
- *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
-
- *(sFrame.pwAuthSequence) = cpu_to_le16(1);
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- *pStatus = csMgmt_xmit(pDevice, pTxPacket);
- if (*pStatus == CMD_STATUS_PENDING){
- pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
- *pStatus = CMD_STATUS_SUCCESS;
- }
-
- return ;
-}
-
-/*+
- *
- * Routine Description:
- * Start the station(AP) deauthentication procedure. Namely, send an
- * deauthentication frame to the AP or Sta.
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrDeAuthenBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u8 *abyDestAddress, u16 wReason,
- PCMD_STATUS pStatus)
-{
- WLAN_FR_DEAUTHEN sFrame;
- struct vnt_tx_mgmt *pTxPacket =
- (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
-
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_DEAUTHEN_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
- vMgrEncodeDeauthen(&sFrame);
- /* insert values */
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
- ));
-
- memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- *pStatus = csMgmt_xmit(pDevice, pTxPacket);
- if (*pStatus == CMD_STATUS_PENDING){
- *pStatus = CMD_STATUS_SUCCESS;
- }
-
- return ;
-}
-
-/*+
- *
- * Routine Description:
- * Handle incoming authentication frames.
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAuthentication(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
-{
- WLAN_FR_AUTHEN sFrame;
-
- // we better be an AP or a STA in AUTHPENDING otherwise ignore
- if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
- pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
- return;
- }
-
- // decode the frame
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeAuthen(&sFrame);
- switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){
- case 1:
- //AP funciton
- s_vMgrRxAuthenSequence_1(pDevice,pMgmt, &sFrame);
- break;
- case 2:
- s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
- break;
- case 3:
- //AP funciton
- s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
- break;
- case 4:
- s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
- break;
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
- cpu_to_le16((*(sFrame.pwAuthSequence))));
- break;
- }
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming authen frames with sequence 1. Currently
- * assumes we're an AP. So far, no one appears to use authentication
- * in Ad-Hoc mode.
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAuthenSequence_1(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- u32 uNodeIndex;
- WLAN_FR_AUTHEN sFrame;
- PSKeyItem pTransmitKey;
-
- /* Insert a Node entry */
- if (!BSSbIsSTAInNodeDB(pDevice, pFrame->pHdr->sA3.abyAddr2,
- &uNodeIndex)) {
- BSSvCreateOneNode(pDevice, &uNodeIndex);
- memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr,
- pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
- }
-
- if (pMgmt->bShareKeyAlgorithm) {
- pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
- pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
- }
- else {
- pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
- }
-
- // send auth reply
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_AUTHEN_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
- // format buffer structure
- vMgrEncodeAuthen(&sFrame);
- // insert values
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
- WLAN_SET_FC_ISWEP(0)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
- *(sFrame.pwAuthSequence) = cpu_to_le16(2);
-
- if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
- if (pMgmt->bShareKeyAlgorithm)
- *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
- else
- *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
- }
- else {
- if (pMgmt->bShareKeyAlgorithm)
- *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
- else
- *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
- }
-
- if (pMgmt->bShareKeyAlgorithm &&
- (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
-
- sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
- sFrame.len += WLAN_CHALLENGE_IE_LEN;
- sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
- sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
- memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
- // get group key
- if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) {
- rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
- rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
- }
- memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
- }
-
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
- // send the frame
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
- }
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming auth frames with sequence number 2. Currently
- * assumes we're a station.
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAuthenSequence_2(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
-{
- WLAN_FR_AUTHEN sFrame;
- struct vnt_tx_mgmt *pTxPacket = NULL;
-
- switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm))))
- {
- case WLAN_AUTH_ALG_OPENSYSTEM:
- if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
- pMgmt->eCurrState = WMAC_STATE_AUTH;
- schedule_delayed_work(&pDevice->run_command_work, 0);
- }
- else {
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
- s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- }
- if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
- /* spin_unlock_irq(&pDevice->lock);
- vCommandTimerWait((void *) pDevice, 0);
- spin_lock_irq(&pDevice->lock); */
- }
- break;
-
- case WLAN_AUTH_ALG_SHAREDKEY:
-
- if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
- pTxPacket = (struct vnt_tx_mgmt *)
- pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_AUTHEN_FR_MAXLEN);
- pTxPacket->p80211Header
- = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
- // format buffer structure
- vMgrEncodeAuthen(&sFrame);
- // insert values
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
- WLAN_SET_FC_ISWEP(1)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
- *(sFrame.pwAuthSequence) = cpu_to_le16(3);
- *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
- sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
- sFrame.len += WLAN_CHALLENGE_IE_LEN;
- sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
- sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
- memcpy( sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
- // Adjust the length fields
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
- // send the frame
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
- }
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
- if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
- /* spin_unlock_irq(&pDevice->lock);
- vCommandTimerWait((void *) pDevice, 0);
- spin_lock_irq(&pDevice->lock); */
- }
- s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
- }
- break;
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
- break;
- }
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming authen frames with sequence 3. Currently
- * assumes we're an AP. This function assumes the frame has
- * already been successfully decrypted.
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxAuthenSequence_3(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- u32 uStatusCode = 0 ;
- u32 uNodeIndex = 0;
- WLAN_FR_AUTHEN sFrame;
-
- if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
- uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
- goto reply;
- }
- if (BSSbIsSTAInNodeDB(pDevice, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
- if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
- uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
- goto reply;
- }
- if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
- uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
- goto reply;
- }
- }
- else {
- uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
- goto reply;
- }
-
- if (uNodeIndex) {
- pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
- pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
- }
- uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
-
-reply:
- // send auth reply
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_AUTHEN_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
- // format buffer structure
- vMgrEncodeAuthen(&sFrame);
- /* insert values */
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
- WLAN_SET_FC_ISWEP(0)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
- *(sFrame.pwAuthSequence) = cpu_to_le16(4);
- *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
-
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
- // send the frame
- if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
- }
- return;
-
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming authen frames with sequence 4
- *
- *
- * Return Value:
- * None.
- *
--*/
-static void s_vMgrRxAuthenSequence_4(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, PWLAN_FR_AUTHEN pFrame)
-{
-
- if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
- pMgmt->eCurrState = WMAC_STATE_AUTH;
- schedule_delayed_work(&pDevice->run_command_work, 0);
- }
- else{
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
- s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))) );
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- }
-
- if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
- /* spin_unlock_irq(&pDevice->lock);
- vCommandTimerWait((void *) pDevice, 0);
- spin_lock_irq(&pDevice->lock); */
- }
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming disassociation frames
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxDisassociation(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
-{
- WLAN_FR_DISASSOC sFrame;
- u32 uNodeIndex = 0;
- CMD_STATUS CmdStatus;
-
- if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
- // if is acting an AP..
- // a STA is leaving this BSS..
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
- BSSvRemoveOneNode(pDevice, uNodeIndex);
- }
- else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
- }
- }
- else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeDisassociation(&sFrame);
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
-
- pDevice->fWPA_Authened = false;
-
- //TODO: do something let upper layer know or
- //try to send associate packet again because of inactivity timeout
- if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
- pDevice->bLinkPass = false;
- pMgmt->sNodeDBTable[0].bActive = false;
- pDevice->byReAssocCount = 0;
- pMgmt->eCurrState = WMAC_STATE_AUTH; // jump back to the auth state!
- pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
- vMgrReAssocBeginSta(pDevice, pMgmt, &CmdStatus);
- if(CmdStatus == CMD_STATUS_PENDING) {
- pDevice->byReAssocCount ++;
- return; //mike add: you'll retry for many times, so it cann't be regarded as disconnected!
- }
- }
-
- // if(pDevice->bWPASuppWextEnabled == true)
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof (wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
- }
- }
- /* else, ignore it */
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Handles incoming deauthentication frames
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxDeauthentication(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
-{
- WLAN_FR_DEAUTHEN sFrame;
- u32 uNodeIndex = 0;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
- //Todo:
- // if is acting an AP..
- // a STA is leaving this BSS..
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
- BSSvRemoveOneNode(pDevice, uNodeIndex);
- }
- else {
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
- }
- }
- else {
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) {
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeDeauthen(&sFrame);
- pDevice->fWPA_Authened = false;
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
- // TODO: update BSS list for specific BSSID if pre-authentication case
- if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
- pMgmt->abyCurrBSSID)) {
- if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
- pMgmt->sNodeDBTable[0].bActive = false;
- pMgmt->eCurrMode = WMAC_MODE_STANDBY;
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- netif_stop_queue(pDevice->dev);
- pDevice->bLinkPass = false;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_SLOW);
- }
- }
-
- // if(pDevice->bWPASuppWextEnabled == true)
- {
- union iwreq_data wrqu;
- memset(&wrqu, 0, sizeof (wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
- wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
- }
-
- }
- /* else, ignore it. TODO: IBSS authentication service
- would be implemented here */
- };
- return;
-}
-
-/*+
- *
- * Routine Description:
- * check if current channel is match ZoneType.
- *for USA:1~11;
- * Japan:1~13;
- * Europe:1~13
- * Return Value:
- * True:exceed;
- * False:normal case
--*/
-static int ChannelExceedZoneType(struct vnt_private *pDevice, u8 byCurrChannel)
-{
- int exceed = false;
-
- switch(pDevice->byZoneType) {
- case 0x00: //USA:1~11
- if((byCurrChannel<1) ||(byCurrChannel>11))
- exceed = true;
- break;
- case 0x01: //Japan:1~13
- case 0x02: //Europe:1~13
- if((byCurrChannel<1) ||(byCurrChannel>13))
- exceed = true;
- break;
- default: //reserve for other zonetype
- break;
- }
-
- return exceed;
-}
-
-/*+
- *
- * Routine Description:
- * Handles and analysis incoming beacon frames.
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-static void s_vMgrRxBeacon(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket,
- int bInScan)
-{
- PKnownBSS pBSSList;
- WLAN_FR_BEACON sFrame;
- u64 qwTSFOffset;
- int bIsBSSIDEqual = false;
- int bIsSSIDEqual = false;
- int bTSFLargeDiff = false;
- int bTSFOffsetPostive = false;
- int bUpdateTSF = false;
- int bIsAPBeacon = false;
- int bIsChannelEqual = false;
- u32 uLocateByteIndex;
- u8 byTIMBitOn = 0;
- u16 wAIDNumber = 0;
- u32 uNodeIndex;
- u64 qwTimestamp, qwLocalTSF;
- u64 qwCurrTSF;
- u16 wStartIndex = 0;
- u16 wAIDIndex = 0;
- u8 byCurrChannel = pRxPacket->byRxChannel;
- ERPObject sERP;
- u32 uRateLen = WLAN_RATES_MAXLEN;
- int bChannelHit = false;
- u8 byOldPreambleType;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
- return;
-
- memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
-
- // decode the beacon frame
- vMgrDecodeBeacon(&sFrame);
-
- if ((sFrame.pwBeaconInterval == NULL)
- || (sFrame.pwCapInfo == NULL)
- || (sFrame.pSSID == NULL)
- || (sFrame.pSuppRates == NULL)) {
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
- return;
- }
-
- if( byCurrChannel > CB_MAX_CHANNEL_24G )
- {
- if (sFrame.pDSParms != NULL) {
- if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
- bChannelHit = true;
- byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
- } else {
- bChannelHit = true;
- }
-
- } else {
- if (sFrame.pDSParms != NULL) {
- if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
- bChannelHit = true;
- byCurrChannel = sFrame.pDSParms->byCurrChannel;
- } else {
- bChannelHit = true;
- }
- }
-
-if(ChannelExceedZoneType(pDevice,byCurrChannel)==true)
- return;
-
- if (sFrame.pERP != NULL) {
- sERP.byERP = sFrame.pERP->byContext;
- sERP.bERPExist = true;
-
- } else {
- sERP.bERPExist = false;
- sERP.byERP = 0;
- }
-
- pBSSList = BSSpAddrIsInBSSList((void *) pDevice,
- sFrame.pHdr->sA3.abyAddr3,
- sFrame.pSSID);
- if (pBSSList == NULL) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
- BSSbInsertToBSSList((void *) pDevice,
- sFrame.pHdr->sA3.abyAddr3,
- *sFrame.pqwTimestamp,
- *sFrame.pwBeaconInterval,
- *sFrame.pwCapInfo,
- byCurrChannel,
- sFrame.pSSID,
- sFrame.pSuppRates,
- sFrame.pExtSuppRates,
- &sERP,
- sFrame.pRSN,
- sFrame.pRSNWPA,
- sFrame.pIE_Country,
- sFrame.pIE_Quiet,
- sFrame.len - WLAN_HDR_ADDR3_LEN,
- sFrame.pHdr->sA4.abyAddr4, // payload of beacon
- (void *) pRxPacket);
- }
- else {
-// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
- BSSbUpdateToBSSList((void *) pDevice,
- *sFrame.pqwTimestamp,
- *sFrame.pwBeaconInterval,
- *sFrame.pwCapInfo,
- byCurrChannel,
- bChannelHit,
- sFrame.pSSID,
- sFrame.pSuppRates,
- sFrame.pExtSuppRates,
- &sERP,
- sFrame.pRSN,
- sFrame.pRSNWPA,
- sFrame.pIE_Country,
- sFrame.pIE_Quiet,
- pBSSList,
- sFrame.len - WLAN_HDR_ADDR3_LEN,
- sFrame.pHdr->sA4.abyAddr4, // payload of probresponse
- (void *) pRxPacket);
-
- }
-
- if (bInScan) {
- return;
- }
-
- if(byCurrChannel == (u8)pMgmt->uCurrChannel)
- bIsChannelEqual = true;
-
- if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
-
- // if rx beacon without ERP field
- if (sERP.bERPExist) {
- if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)){
- pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
- pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
- }
- }
- else {
- pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
- pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- if(!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
- pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
- if(!sERP.bERPExist)
- pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
- }
- }
-
- // check if BSSID the same
- if (memcmp(sFrame.pHdr->sA3.abyAddr3,
- pMgmt->abyCurrBSSID,
- WLAN_BSSID_LEN) == 0) {
-
- bIsBSSIDEqual = true;
- pDevice->uCurrRSSI = pRxPacket->uRSSI;
- pDevice->byCurrSQ = pRxPacket->bySQ;
- if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
- }
- }
- // check if SSID the same
- if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
- if (memcmp(sFrame.pSSID->abySSID,
- ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
- sFrame.pSSID->len
- ) == 0) {
- bIsSSIDEqual = true;
- }
- }
-
- if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== true) &&
- (bIsBSSIDEqual == true) &&
- (bIsSSIDEqual == true) &&
- (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
- (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
- // add state check to prevent reconnect fail since we'll receive Beacon
-
- bIsAPBeacon = true;
- if (pBSSList != NULL) {
-
- // Sync ERP field
- if ((pBSSList->sERP.bERPExist == true) && (pDevice->byBBType == BB_TYPE_11G)) {
- if ((pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
- pDevice->bProtectMode = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
- if (pDevice->bProtectMode) {
- MACvEnableProtectMD(pDevice);
- } else {
- MACvDisableProtectMD(pDevice);
- }
- vUpdateIFS(pDevice);
- }
- if ((pBSSList->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
- pDevice->bNonERPPresent = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
- }
- if ((pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
- pDevice->bBarkerPreambleMd = (pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
- //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
- if (pDevice->bBarkerPreambleMd) {
- MACvEnableBarkerPreambleMd(pDevice);
- } else {
- MACvDisableBarkerPreambleMd(pDevice);
- }
- }
- }
- // Sync Short Slot Time
- if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo) != pDevice->bShortSlotTime) {
- bool bShortSlotTime;
-
- bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo);
- //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
- //Kyle check if it is OK to set G.
- if (pDevice->byBBType == BB_TYPE_11A) {
- bShortSlotTime = true;
- }
- else if (pDevice->byBBType == BB_TYPE_11B) {
- bShortSlotTime = false;
- }
- if (bShortSlotTime != pDevice->bShortSlotTime) {
- pDevice->bShortSlotTime = bShortSlotTime;
- BBvSetShortSlotTime(pDevice);
- vUpdateIFS(pDevice);
- }
- }
-
- //
- // Preamble may change dynamically
- //
- byOldPreambleType = pDevice->byPreambleType;
- if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pBSSList->wCapInfo)) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
- }
- else {
- pDevice->byPreambleType = 0;
- }
- if (pDevice->byPreambleType != byOldPreambleType)
- CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
- //
- // Basic Rate Set may change dynamically
- //
- if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
- uRateLen = WLAN_RATES_MAXLEN_11B;
- }
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- uRateLen);
- pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
- uRateLen);
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
- true,
- &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[0].wSuppRate),
- &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
- );
-
- }
- }
-
-// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
- // check if CF field exisit
- if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
- if (sFrame.pCFParms->wCFPDurRemaining > 0) {
- // TODO: deal with CFP period to set NAV
- }
- }
-
- qwTimestamp = cpu_to_le64(*sFrame.pqwTimestamp);
- qwLocalTSF = pRxPacket->qwLocalTSF;
-
- // check if beacon TSF larger or small than our local TSF
- if (qwTimestamp >= qwLocalTSF)
- bTSFOffsetPostive = true;
- else
- bTSFOffsetPostive = false;
-
- if (bTSFOffsetPostive) {
- qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
- }
- else {
- qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
- }
-
- if (qwTSFOffset > TRIVIAL_SYNC_DIFFERENCE)
- bTSFLargeDiff = true;
-
- // if infra mode
- if (bIsAPBeacon == true) {
-
- // Infra mode: Local TSF always follow AP's TSF if Difference huge.
- if (bTSFLargeDiff)
- bUpdateTSF = true;
-
- if ((pDevice->bEnablePSMode == true) && (sFrame.pTIM)) {
-
- /* deal with DTIM, analysis TIM */
- pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false ;
- pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
- pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
- wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
-
- // check if AID in TIM field bit on
- // wStartIndex = N1
- wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
- // AIDIndex = N2
- wAIDIndex = (wAIDNumber >> 3);
- if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
- uLocateByteIndex = wAIDIndex - wStartIndex;
- // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
- if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
- byTIMBitOn = (0x01) << ((wAIDNumber) % 8);
- pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
- }
- else {
- pMgmt->bInTIM = false;
- };
- }
- else {
- pMgmt->bInTIM = false;
- };
-
- if (pMgmt->bInTIM ||
- (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
- pMgmt->bInTIMWake = true;
- /* send out ps-poll packet */
- if (pMgmt->bInTIM)
- PSvSendPSPOLL(pDevice);
-
- }
- else {
- pMgmt->bInTIMWake = false;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
- if (pDevice->bPWBitOn == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
- if (PSbSendNullPacket(pDevice))
- pDevice->bPWBitOn = true;
- }
- if(PSbConsiderPowerDown(pDevice, false, false)) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
- }
- }
-
- }
-
- }
- // if adhoc mode
- if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
- if (bIsBSSIDEqual) {
- // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
- if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
-
- // adhoc mode:TSF updated only when beacon larger then local TSF
- if (bTSFLargeDiff && bTSFOffsetPostive &&
- (pMgmt->eCurrState == WMAC_STATE_JOINTED))
- bUpdateTSF = true;
-
- // During dpc, already in spinlocked.
- if (BSSbIsSTAInNodeDB(pDevice, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
-
- // Update the STA, (Technically the Beacons of all the IBSS nodes
- // should be identical, but that's not happening in practice.
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- WLAN_RATES_MAXLEN_11B);
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- NULL,
- true,
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
- );
- pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
- }
- else {
- /* Todo, initial Node content */
- BSSvCreateOneNode(pDevice, &uNodeIndex);
-
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- WLAN_RATES_MAXLEN_11B);
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- NULL,
- true,
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
- &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
- );
-
- memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
- pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
- pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
-/*
- pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
- if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
- pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
-*/
- }
-
- // if other stations jointed, indicate connect to upper layer..
- if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
- pMgmt->eCurrState = WMAC_STATE_JOINTED;
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- if (netif_queue_stopped(pDevice->dev)){
- netif_wake_queue(pDevice->dev);
- }
- pMgmt->sNodeDBTable[0].bActive = true;
- pMgmt->sNodeDBTable[0].uInActiveCount = 0;
-
- }
- }
- else if (bIsSSIDEqual) {
-
- // See other adhoc sta with the same SSID but BSSID is different.
- // adpot this vars only when TSF larger then us.
- if (bTSFLargeDiff && bTSFOffsetPostive) {
- // we don't support ATIM under adhoc mode
- // if ( sFrame.pIBSSParms->wATIMWindow == 0) {
- // adpot this vars
- // TODO: check sFrame cap if privacy on, and support rate syn
- memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
- memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
- pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- WLAN_RATES_MAXLEN_11B);
- // set HW beacon interval and re-synchronizing....
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
-
- MACvWriteBeaconInterval(pDevice, pMgmt->wCurrBeaconPeriod);
- CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
- CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
-
- // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
- MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
-
- byOldPreambleType = pDevice->byPreambleType;
- if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
- }
- else {
- pDevice->byPreambleType = 0;
- }
- if (pDevice->byPreambleType != byOldPreambleType)
- CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
-
- // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
- // set highest basic rate
- // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
- // Prepare beacon frame
- bMgrPrepareBeaconToSend((void *) pDevice, pMgmt);
- // }
- }
- }
- }
- // endian issue ???
- // Update TSF
- if (bUpdateTSF) {
- CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
- CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp , pRxPacket->qwLocalTSF);
- CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
- CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
- }
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Instructs the hw to create a bss using the supplied
- * attributes. Note that this implementation only supports Ad-Hoc
- * BSS creation.
- *
- *
- * Return Value:
- * CMD_STATUS
- *
--*/
-
-void vMgrCreateOwnIBSS(struct vnt_private *pDevice, PCMD_STATUS pStatus)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u16 wMaxBasicRate;
- u16 wMaxSuppRate;
- u8 byTopCCKBasicRate;
- u8 byTopOFDMBasicRate;
- u64 qwCurrTSF = 0;
- int ii;
- u8 abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C,
- 0x12, 0x18, 0x60};
- u8 abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
- u8 abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
- u16 wSuppRate;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
-
- if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
- if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
- (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
- (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
- // encryption mode error
- *pStatus = CMD_STATUS_FAILURE;
- return;
- }
- }
-
- pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
- pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
-
- if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
- pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
- } else {
- if (pDevice->byBBType == BB_TYPE_11G)
- pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
- if (pDevice->byBBType == BB_TYPE_11B)
- pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
- if (pDevice->byBBType == BB_TYPE_11A)
- pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
- }
-
- if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
- pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
- pMgmt->abyCurrExtSuppRates[1] = 0;
- for (ii = 0; ii < 4; ii++)
- pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
- } else {
- pMgmt->abyCurrSuppRates[1] = 8;
- pMgmt->abyCurrExtSuppRates[1] = 0;
- for (ii = 0; ii < 8; ii++)
- pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
- }
-
- if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
- pMgmt->abyCurrSuppRates[1] = 8;
- pMgmt->abyCurrExtSuppRates[1] = 4;
- for (ii = 0; ii < 4; ii++)
- pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii];
- for (ii = 4; ii < 8; ii++)
- pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4];
- for (ii = 0; ii < 4; ii++)
- pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4];
- }
-
- // Disable Protect Mode
- pDevice->bProtectMode = 0;
- MACvDisableProtectMD(pDevice);
-
- pDevice->bBarkerPreambleMd = 0;
- MACvDisableBarkerPreambleMd(pDevice);
-
- // Kyle Test 2003.11.04
-
- // set HW beacon interval
- if (pMgmt->wIBSSBeaconPeriod == 0)
- pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
- MACvWriteBeaconInterval(pDevice, pMgmt->wIBSSBeaconPeriod);
-
- CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
- // clear TSF counter
- CARDbClearCurrentTSF(pDevice);
-
- // enable TSF counter
- MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTREN);
- // set Next TBTT
- CARDvSetFirstNextTBTT(pDevice, pMgmt->wIBSSBeaconPeriod);
-
- pMgmt->uIBSSChannel = pDevice->uChannel;
-
- if (pMgmt->uIBSSChannel == 0)
- pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
-
- // set channel and clear NAV
- CARDbSetMediaChannel(pDevice, pMgmt->uIBSSChannel);
- pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
-
- pDevice->byPreambleType = pDevice->byShortPreamble;
-
- // set basic rate
-
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
- &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
- &byTopCCKBasicRate, &byTopOFDMBasicRate);
-
- if (pDevice->byBBType == BB_TYPE_11A) {
- pDevice->bShortSlotTime = true;
- } else {
- pDevice->bShortSlotTime = false;
- }
- BBvSetShortSlotTime(pDevice);
- // vUpdateIFS() use pDevice->bShortSlotTime as parameter so it must be called
- // after setting ShortSlotTime.
- // CARDvSetBSSMode call vUpdateIFS()
- CARDvSetBSSMode(pDevice);
-
- if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
- MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_AP);
- pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
- }
-
- if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
- MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
- pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
- }
-
- // Adopt pre-configured IBSS vars to current vars
- pMgmt->eCurrState = WMAC_STATE_STARTED;
- pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
- pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
- pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
- pDevice->uCurrRSSI = 0;
- pDevice->byCurrSQ = 0;
-
- memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
- ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
-
- memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memcpy(pMgmt->abyCurrSSID,
- pMgmt->abyDesireSSID,
- ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
- );
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- // AP mode BSSID = MAC addr
- memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:"
- "%pM\n", pMgmt->abyCurrBSSID);
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
-
- // BSSID selected must be randomized as spec 11.1.3
- pMgmt->abyCurrBSSID[5] = (u8)(qwCurrTSF & 0x000000ff);
- pMgmt->abyCurrBSSID[4] = (u8)((qwCurrTSF & 0x0000ff00) >> 8);
- pMgmt->abyCurrBSSID[3] = (u8)((qwCurrTSF & 0x00ff0000) >> 16);
- pMgmt->abyCurrBSSID[2] = (u8)((qwCurrTSF & 0x00000ff0) >> 4);
- pMgmt->abyCurrBSSID[1] = (u8)((qwCurrTSF & 0x000ff000) >> 12);
- pMgmt->abyCurrBSSID[0] = (u8)((qwCurrTSF & 0x0ff00000) >> 20);
- pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
- pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
- pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
- pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
- pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
- pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
- pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
- pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
-
- DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:"
- "%pM\n", pMgmt->abyCurrBSSID);
- }
-
- // set BSSID filter
- MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
- memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
-
- MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
- pDevice->byRxMode |= RCR_BSSID;
- pMgmt->bCurrBSSIDFilterOn = true;
-
- // Set Capability Info
- pMgmt->wCurrCapInfo = 0;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
- pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
- pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
- pDevice->op_mode = NL80211_IFTYPE_AP;
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
- pDevice->op_mode = NL80211_IFTYPE_ADHOC;
- }
-
- if (pDevice->bEncryptionEnable) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
- pMgmt->byCSSPK = KEY_CTL_CCMP;
- pMgmt->byCSSGK = KEY_CTL_CCMP;
- } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
- pMgmt->byCSSPK = KEY_CTL_TKIP;
- pMgmt->byCSSGK = KEY_CTL_TKIP;
- } else {
- pMgmt->byCSSPK = KEY_CTL_NONE;
- pMgmt->byCSSGK = KEY_CTL_WEP;
- }
- } else {
- pMgmt->byCSSPK = KEY_CTL_WEP;
- pMgmt->byCSSGK = KEY_CTL_WEP;
- }
- }
-
- pMgmt->byERPContext = 0;
-
- if (pDevice->byPreambleType == 1) {
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
- } else {
- pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
- }
-
- pMgmt->eCurrState = WMAC_STATE_STARTED;
- // Prepare beacon to send
- if (bMgrPrepareBeaconToSend((void *) pDevice, pMgmt))
- *pStatus = CMD_STATUS_SUCCESS;
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Instructs wmac to join a bss using the supplied attributes.
- * The arguments may the BSSID or SSID and the rest of the
- * attributes are obtained from the scan result of known bss list.
- *
- *
- * Return Value:
- * None.
- *
--*/
-
-void vMgrJoinBSSBegin(struct vnt_private *pDevice, PCMD_STATUS pStatus)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- PKnownBSS pCurr = NULL;
- int ii, uu;
- PWLAN_IE_SUPP_RATES pItemRates = NULL;
- PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
- PWLAN_IE_SSID pItemSSID;
- u32 uRateLen = WLAN_RATES_MAXLEN;
- u16 wMaxBasicRate = RATE_1M;
- u16 wMaxSuppRate = RATE_1M;
- u16 wSuppRate;
- u8 byTopCCKBasicRate = RATE_1M;
- u8 byTopOFDMBasicRate = RATE_1M;
- u8 bShortSlotTime = false;
-
- for (ii = 0; ii < MAX_BSS_NUM; ii++) {
- if (pMgmt->sBSSList[ii].bActive == true)
- break;
- }
-
- if (ii == MAX_BSS_NUM) {
- *pStatus = CMD_STATUS_RESOURCES;
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
- return;
- }
-
- // memset(pMgmt->abyDesireBSSID, 0, WLAN_BSSID_LEN);
- // Search known BSS list for prefer BSSID or SSID
-
- pCurr = BSSpSearchBSSList(pDevice,
- pMgmt->abyDesireBSSID,
- pMgmt->abyDesireSSID,
- pDevice->eConfigPHYMode
- );
-
- if (pCurr == NULL){
- *pStatus = CMD_STATUS_RESOURCES;
- pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
- return;
- }
-
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
-
- if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
-
- if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
- /*
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
- if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
- // encryption mode error
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- return;
- }
- } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
- if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
- // encryption mode error
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- return;
- }
- }
-*/
- }
-
- //if(pDevice->bWPASuppWextEnabled == true)
- Encyption_Rebuild(pDevice, pCurr);
-
- // Infrastructure BSS
- s_vMgrSynchBSS(pDevice,
- WMAC_MODE_ESS_STA,
- pCurr,
- pStatus
- );
-
- if (*pStatus == CMD_STATUS_SUCCESS){
-
- // Adopt this BSS state vars in Mgmt Object
- pMgmt->uCurrChannel = pCurr->uChannel;
-
- memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
- memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
-
- if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
- uRateLen = WLAN_RATES_MAXLEN_11B;
- }
-
- pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
- pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
-
- // Parse Support Rate IE
- pItemRates->byElementID = WLAN_EID_SUPP_RATES;
- pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
- pItemRates,
- uRateLen);
-
- // Parse Extension Support Rate IE
- pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
- pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
- pItemExtRates,
- uRateLen);
- // Stuffing Rate IE
- if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
- for (ii = 0; ii < (unsigned int) (8 - pItemRates->len); ) {
- pItemRates->abyRates[pItemRates->len + ii] =
- pItemExtRates->abyRates[ii];
- ii++;
- if (pItemExtRates->len <= ii)
- break;
- }
- pItemRates->len += (u8)ii;
- if (pItemExtRates->len - ii > 0) {
- pItemExtRates->len -= (u8)ii;
- for (uu = 0; uu < pItemExtRates->len; uu ++) {
- pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
- }
- } else {
- pItemExtRates->len = 0;
- }
- }
-
- RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
- &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
- &byTopCCKBasicRate, &byTopOFDMBasicRate);
- vUpdateIFS(pDevice);
- // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
- // TODO: deal with if wCapInfo the PS-Pollable is on.
- pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
- memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
- memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
- memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-
- pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
-
- pMgmt->eCurrState = WMAC_STATE_JOINTED;
- // Adopt BSS state in Adapter Device Object
- pDevice->op_mode = NL80211_IFTYPE_STATION;
- memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
-
- // Add current BSS to Candidate list
- // This should only work for WPA2 BSS, and WPA2 BSS check must be done before.
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
- bool bResult = bAdd_PMKID_Candidate((void *) pDevice,
- pMgmt->abyCurrBSSID,
- &pCurr->sRSNCapObj);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
- if (bResult == false) {
- vFlush_PMKID_Candidate((void *) pDevice);
- DBG_PRT(MSG_LEVEL_DEBUG,
- KERN_INFO "vFlush_PMKID_Candidate: 4\n");
- bAdd_PMKID_Candidate((void *) pDevice,
- pMgmt->abyCurrBSSID,
- &pCurr->sRSNCapObj);
- }
- }
-
- // Preamble type auto-switch: if AP can receive short-preamble cap,
- // we can turn on too.
- if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
- }
- else {
- pDevice->byPreambleType = 0;
- }
- // Change PreambleType must set RSPINF again
- CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
-
- if (pCurr->eNetworkTypeInUse == PHY_TYPE_11G) {
-
- if ((pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
- pDevice->bProtectMode = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
- if (pDevice->bProtectMode) {
- MACvEnableProtectMD(pDevice);
- } else {
- MACvDisableProtectMD(pDevice);
- }
- vUpdateIFS(pDevice);
- }
- if ((pCurr->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
- pDevice->bNonERPPresent = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
- }
- if ((pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
- pDevice->bBarkerPreambleMd = (pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
- //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
- if (pDevice->bBarkerPreambleMd) {
- MACvEnableBarkerPreambleMd(pDevice);
- } else {
- MACvDisableBarkerPreambleMd(pDevice);
- }
- }
- }
- //DBG_PRN_WLAN05(("wCapInfo: %X\n", pCurr->wCapInfo));
- if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo) != pDevice->bShortSlotTime) {
- if (pDevice->byBBType == BB_TYPE_11A) {
- bShortSlotTime = true;
- }
- else if (pDevice->byBBType == BB_TYPE_11B) {
- bShortSlotTime = false;
- }
- else {
- bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo);
- }
- //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
- if (bShortSlotTime != pDevice->bShortSlotTime) {
- pDevice->bShortSlotTime = bShortSlotTime;
- BBvSetShortSlotTime(pDevice);
- vUpdateIFS(pDevice);
- }
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
- }
- else {
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- };
-
- }
- else {
- // ad-hoc mode BSS
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
-
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
-/*
- if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
- // encryption mode error
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- return;
- }
-*/
- } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
-/*
- if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
- // encryption mode error
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- return;
- }
-*/
- } else {
- // encryption mode error
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- return;
- }
- }
-
- s_vMgrSynchBSS(pDevice,
- WMAC_MODE_IBSS_STA,
- pCurr,
- pStatus
- );
-
- if (*pStatus == CMD_STATUS_SUCCESS){
- // Adopt this BSS state vars in Mgmt Object
- // TODO: check if CapInfo privacy on, but we don't..
- pMgmt->uCurrChannel = pCurr->uChannel;
-
- // Parse Support Rate IE
- pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
- pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- WLAN_RATES_MAXLEN_11B);
- // set basic rate
- RATEvParseMaxRate((void *)pDevice,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
- &byTopCCKBasicRate, &byTopOFDMBasicRate);
- vUpdateIFS(pDevice);
- pMgmt->wCurrCapInfo = pCurr->wCapInfo;
- pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
- memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
- memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
- memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
-// pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
- pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
- pMgmt->eCurrState = WMAC_STATE_STARTED;
- // Adopt BSS state in Adapter Device Object
- pDevice->op_mode = NL80211_IFTYPE_ADHOC;
- pDevice->bLinkPass = true;
-
- vnt_mac_set_led(pDevice, LEDSTS_STS, LEDSTS_INTER);
-
- memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%pM\n",
- pMgmt->abyCurrBSSID);
- // Preamble type auto-switch: if AP can receive short-preamble cap,
- // and if registry setting is short preamble we can turn on too.
-
- if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
- pDevice->byPreambleType = pDevice->byShortPreamble;
- }
- else {
- pDevice->byPreambleType = 0;
- }
- // Change PreambleType must set RSPINF again
- CARDvSetRSPINF(pDevice, (u8)pDevice->byBBType);
-
- // Prepare beacon
- bMgrPrepareBeaconToSend((void *) pDevice, pMgmt);
- }
- else {
- pMgmt->eCurrState = WMAC_STATE_IDLE;
- };
- };
- return;
-}
-
-/*+
- *
- * Routine Description:
- * Set HW to synchronize a specific BSS from known BSS list.
- *
- *
- * Return Value:
- * PCM_STATUS
- *
--*/
-static void s_vMgrSynchBSS(struct vnt_private *pDevice, u32 uBSSMode,
- PKnownBSS pCurr, PCMD_STATUS pStatus)
-{
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u8 abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES,
- 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
- /* 1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M*/
- u8 abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES,
- 4, 0x0C, 0x12, 0x18, 0x60};
- /* 6M, 9M, 12M, 48M*/
- u8 abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES,
- 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
- u8 abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES,
- 4, 0x02, 0x04, 0x0B, 0x16};
-
- *pStatus = CMD_STATUS_FAILURE;
-
- if (s_bCipherMatch(pCurr,
- pDevice->eEncryptionStatus,
- &(pMgmt->byCSSPK),
- &(pMgmt->byCSSGK)) == false) {
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "s_bCipherMatch Fail .......\n");
- return;
- }
-
- pMgmt->pCurrBSS = pCurr;
-
- // if previous mode is IBSS.
- if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
- MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
- }
-
- // Init the BSS informations
- pDevice->bProtectMode = false;
- MACvDisableProtectMD(pDevice);
- pDevice->bBarkerPreambleMd = false;
- MACvDisableBarkerPreambleMd(pDevice);
- pDevice->bNonERPPresent = false;
- pDevice->byPreambleType = 0;
- pDevice->wBasicRate = 0;
- // Set Basic Rate
- CARDbAddBasicRate((void *)pDevice, RATE_1M);
-
- // calculate TSF offset
- // TSF Offset = Received Timestamp TSF - Marked Local's TSF
- CARDvAdjustTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
-
- // set HW beacon interval
- MACvWriteBeaconInterval(pDevice, pCurr->wBeaconInterval);
-
- // set Next TBTT
- // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
- CARDvSetFirstNextTBTT(pDevice, pCurr->wBeaconInterval);
-
- // set BSSID
- MACvWriteBSSIDAddress(pDevice, pCurr->abyBSSID);
-
- memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, 6);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = "
- "%pM\n", pMgmt->abyCurrBSSID);
-
- if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
- if ((pDevice->eConfigPHYMode == PHY_TYPE_11A) ||
- (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
- pDevice->byBBType = BB_TYPE_11A;
- pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
- pDevice->bShortSlotTime = true;
- BBvSetShortSlotTime(pDevice);
- CARDvSetBSSMode(pDevice);
- } else {
- return;
- }
- } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
- if ((pDevice->eConfigPHYMode == PHY_TYPE_11B) ||
- (pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
- (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
- pDevice->byBBType = BB_TYPE_11B;
- pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
- pDevice->bShortSlotTime = false;
- BBvSetShortSlotTime(pDevice);
- CARDvSetBSSMode(pDevice);
- } else {
- return;
- }
- } else {
- if ((pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
- (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
- pDevice->byBBType = BB_TYPE_11G;
- pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
- pDevice->bShortSlotTime = true;
- BBvSetShortSlotTime(pDevice);
- CARDvSetBSSMode(pDevice);
- } else if (pDevice->eConfigPHYMode == PHY_TYPE_11B) {
- pDevice->byBBType = BB_TYPE_11B;
- pDevice->bShortSlotTime = false;
- BBvSetShortSlotTime(pDevice);
- CARDvSetBSSMode(pDevice);
- } else {
- return;
- }
- }
-
- if (uBSSMode == WMAC_MODE_ESS_STA) {
- MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
- MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
- pDevice->byRxMode |= RCR_BSSID;
- pMgmt->bCurrBSSIDFilterOn = true;
- }
-
- // set channel and clear NAV
- CARDbSetMediaChannel(pDevice, pCurr->uChannel);
- pMgmt->uCurrChannel = pCurr->uChannel;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
-
- if (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) {
- pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
- BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
- BBvSetShortSlotTime(pDevice);
- }
- //
- // Notes:
- // 1. In Ad-hoc mode : check if received others beacon as jointed indication,
- // otherwise we will start own IBSS.
- // 2. In Infra mode : Supposed we already synchronized with AP right now.
-
- if (uBSSMode == WMAC_MODE_IBSS_STA) {
- MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
- MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
- pDevice->byRxMode |= RCR_BSSID;
- pMgmt->bCurrBSSIDFilterOn = true;
- }
-
- if (pDevice->byBBType == BB_TYPE_11A) {
- memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
- pMgmt->abyCurrExtSuppRates[1] = 0;
- } else if (pDevice->byBBType == BB_TYPE_11B) {
- memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
- pMgmt->abyCurrExtSuppRates[1] = 0;
- } else {
- memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
- memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
- }
- pMgmt->byERPContext = pCurr->sERP.byERP;
-
- *pStatus = CMD_STATUS_SUCCESS;
-
- return;
-};
-
-static void Encyption_Rebuild(struct vnt_private *pDevice, PKnownBSS pCurr)
- {
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
- if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
- if (pCurr->bWPAValid == true) { /*WPA-PSK */
- pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
- if(pCurr->abyPKType[0] == WPA_TKIP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP
- PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
- }
- else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
- PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
- }
- }
- else if(pCurr->bWPA2Valid == true) { //WPA2-PSK
- pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
- if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP
- PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
- }
- else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
- PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
- }
- }
- }
- // }
- return;
- }
-
-/*+
- *
- * Routine Description:
- * Format TIM field
- *
- *
- * Return Value:
- * void
- *
--*/
-
-static void s_vMgrFormatTIM(struct vnt_manager *pMgmt, PWLAN_IE_TIM pTIM)
-{
- u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
- u8 byMap;
- int ii, jj;
- int bStartFound = false;
- int bMulticast = false;
- u16 wStartIndex = 0;
- u16 wEndIndex = 0;
-
- // Find size of partial virtual bitmap
- for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
- byMap = pMgmt->abyPSTxMap[ii];
- if (!ii) {
- // Mask out the broadcast bit which is indicated separately.
- bMulticast = (byMap & byMask[0]) != 0;
- if(bMulticast) {
- pMgmt->sNodeDBTable[0].bRxPSPoll = true;
- }
- byMap = 0;
- }
- if (byMap) {
- if (!bStartFound) {
- bStartFound = true;
- wStartIndex = (u16)ii;
- }
- wEndIndex = (u16)ii;
- }
- }
-
- // Round start index down to nearest even number
- wStartIndex &= ~BIT0;
-
- // Round end index up to nearest even number
- wEndIndex = ((wEndIndex + 1) & ~BIT0);
-
- // Size of element payload
-
- pTIM->len = 3 + (wEndIndex - wStartIndex) + 1;
-
- // Fill in the Fixed parts of the TIM
- pTIM->byDTIMCount = pMgmt->byDTIMCount;
- pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
- pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
- (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
-
- // Append variable part of TIM
-
- for (ii = wStartIndex, jj =0 ; ii <= wEndIndex; ii++, jj++) {
- pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
- }
-
- // Aid = 0 don't used.
- pTIM->byVirtBitMap[0] &= ~BIT0;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an Beacon frame( Ad-hoc mode)
- *
- *
- * Return Value:
- * PTR to frame; or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeBeacon(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
- u32 uCurrChannel, u16 wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID,
- u8 *pCurrBSSID, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_BEACON sFrame;
- u8 abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- /* prepare beacon frame */
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_BEACON_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- // Setup the sFrame structure.
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_BEACON_FR_MAXLEN;
- vMgrEncodeBeacon(&sFrame);
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
- ));
-
- if (pDevice->bEnablePSMode) {
- sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((u16)WLAN_SET_FC_PWRMGT(1));
- }
-
- memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
- *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
- *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
- // Copy SSID
- sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSSID,
- pCurrSSID,
- ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
- );
- // Copy the rate set
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates,
- pCurrSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
- );
- // DS parameter
- if (pDevice->byBBType != BB_TYPE_11A) {
- sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
- sFrame.len += (1) + WLAN_IEHDR_LEN;
- sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
- sFrame.pDSParms->len = 1;
- sFrame.pDSParms->byCurrChannel = (u8)uCurrChannel;
- }
- // TIM field
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
- sFrame.pTIM->byElementID = WLAN_EID_TIM;
- s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
- sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
- }
-
- if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
-
- // IBSS parameter
- sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
- sFrame.len += (2) + WLAN_IEHDR_LEN;
- sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
- sFrame.pIBSSParms->len = 2;
- sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
- /* RSN parameter */
- sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
- sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
- sFrame.pRSNWPA->len = 12;
- sFrame.pRSNWPA->abyOUI[0] = 0x00;
- sFrame.pRSNWPA->abyOUI[1] = 0x50;
- sFrame.pRSNWPA->abyOUI[2] = 0xf2;
- sFrame.pRSNWPA->abyOUI[3] = 0x01;
- sFrame.pRSNWPA->wVersion = 1;
- sFrame.pRSNWPA->abyMulticast[0] = 0x00;
- sFrame.pRSNWPA->abyMulticast[1] = 0x50;
- sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
- sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
- else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
- sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
- else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
- sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
- else
- sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
-
- // Pairwise Key Cipher Suite
- sFrame.pRSNWPA->wPKCount = 0;
- // Auth Key Management Suite
- *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
- sFrame.pRSNWPA->len +=2;
-
- // RSN Capabilites
- *((u16 *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
- sFrame.pRSNWPA->len +=2;
- sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
- }
- }
-
- if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
- sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
- sFrame.len += 1 + WLAN_IEHDR_LEN;
- sFrame.pERP->byElementID = WLAN_EID_ERP;
- sFrame.pERP->len = 1;
- sFrame.pERP->byContext = 0;
- if (pDevice->bProtectMode == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
- if (pDevice->bNonERPPresent == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
- if (pDevice->bBarkerPreambleMd == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
- }
- if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates,
- pCurrExtSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
- );
- }
-
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an Prob-response frame
- *
- *
- * Return Value:
- * PTR to frame; or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wCurrBeaconPeriod,
- u32 uCurrChannel, u16 wCurrATIMWinodw, u8 *pDstAddr,
- PWLAN_IE_SSID pCurrSSID, u8 *pCurrBSSID,
- PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates, u8 byPHYType)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_PROBERESP sFrame;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_PROBERESP_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- // Setup the sFrame structure.
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
- vMgrEncodeProbeResponse(&sFrame);
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
- *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
- *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
-
- if (byPHYType == BB_TYPE_11B) {
- *sFrame.pwCapInfo &= cpu_to_le16((u16)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
- }
-
- // Copy SSID
- sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSSID,
- pCurrSSID,
- ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
- );
- // Copy the rate set
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
-
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates,
- pCurrSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
- );
-
- // DS parameter
- if (pDevice->byBBType != BB_TYPE_11A) {
- sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
- sFrame.len += (1) + WLAN_IEHDR_LEN;
- sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
- sFrame.pDSParms->len = 1;
- sFrame.pDSParms->byCurrChannel = (u8)uCurrChannel;
- }
-
- if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
- // IBSS parameter
- sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
- sFrame.len += (2) + WLAN_IEHDR_LEN;
- sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
- sFrame.pIBSSParms->len = 2;
- sFrame.pIBSSParms->wATIMWindow = 0;
- }
- if (pDevice->byBBType == BB_TYPE_11G) {
- sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
- sFrame.len += 1 + WLAN_IEHDR_LEN;
- sFrame.pERP->byElementID = WLAN_EID_ERP;
- sFrame.pERP->len = 1;
- sFrame.pERP->byContext = 0;
- if (pDevice->bProtectMode == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
- if (pDevice->bNonERPPresent == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
- if (pDevice->bBarkerPreambleMd == true)
- sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
- }
-
- if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates,
- pCurrExtSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
- );
- }
-
- // Adjust the length fields
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an association request frame
- *
- *
- * Return Value:
- * A ptr to frame or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeAssocRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
- u16 wListenInterval,
- PWLAN_IE_SSID pCurrSSID,
- PWLAN_IE_SUPP_RATES pCurrRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_ASSOCREQ sFrame;
- u8 *pbyIEs;
- u8 *pbyRSN;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_ASSOCREQ_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- // Setup the sFrame structure.
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
- // format fixed field frame structure
- vMgrEncodeAssocRequest(&sFrame);
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- // Set the capability and listen interval
- *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
- *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
-
- // sFrame.len point to end of fixed field
- sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
-
- pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
- pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
- pbyIEs = pMgmt->sAssocInfo.abyIEs;
- memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
- pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
-
- // Copy the rate set
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- if ((pDevice->byBBType == BB_TYPE_11B) && (pCurrRates->len > 4))
- sFrame.len += 4 + WLAN_IEHDR_LEN;
- else
- sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
-
- // Copy the extension rate set
- if ((pDevice->byBBType == BB_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
- }
-
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
- pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
-
- if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
- (pMgmt->pCurrBSS != NULL)) {
- /* WPA IE */
- sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
- sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
- sFrame.pRSNWPA->len = 16;
- sFrame.pRSNWPA->abyOUI[0] = 0x00;
- sFrame.pRSNWPA->abyOUI[1] = 0x50;
- sFrame.pRSNWPA->abyOUI[2] = 0xf2;
- sFrame.pRSNWPA->abyOUI[3] = 0x01;
- sFrame.pRSNWPA->wVersion = 1;
- //Group Key Cipher Suite
- sFrame.pRSNWPA->abyMulticast[0] = 0x00;
- sFrame.pRSNWPA->abyMulticast[1] = 0x50;
- sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
- if (pMgmt->byCSSGK == KEY_CTL_WEP) {
- sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
- } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
- } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
- } else {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
- }
- // Pairwise Key Cipher Suite
- sFrame.pRSNWPA->wPKCount = 1;
- sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
- sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
- sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
- if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
- } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
- } else {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
- }
- // Auth Key Management Suite
- pbyRSN = (u8 *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
- *pbyRSN++=0x01;
- *pbyRSN++=0x00;
- *pbyRSN++=0x00;
-
- *pbyRSN++=0x50;
- *pbyRSN++=0xf2;
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
- *pbyRSN++=WPA_AUTH_PSK;
- }
- else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
- *pbyRSN++=WPA_AUTH_IEEE802_1X;
- }
- else {
- *pbyRSN++=WPA_NONE;
- }
-
- sFrame.pRSNWPA->len +=6;
-
- // RSN Capabilites
-
- *pbyRSN++=0x00;
- *pbyRSN++=0x00;
- sFrame.pRSNWPA->len +=2;
-
- sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
- // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
- pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
-
- } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
- (pMgmt->pCurrBSS != NULL)) {
- unsigned int ii;
- u16 * pwPMKID;
-
- // WPA IE
- sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
- sFrame.pRSN->byElementID = WLAN_EID_RSN;
- sFrame.pRSN->len = 6; //Version(2)+GK(4)
- sFrame.pRSN->wVersion = 1;
- //Group Key Cipher Suite
- sFrame.pRSN->abyRSN[0] = 0x00;
- sFrame.pRSN->abyRSN[1] = 0x0F;
- sFrame.pRSN->abyRSN[2] = 0xAC;
- if (pMgmt->byCSSGK == KEY_CTL_WEP) {
- sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
- } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
- } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
- } else {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
- }
-
- // Pairwise Key Cipher Suite
- sFrame.pRSN->abyRSN[4] = 1;
- sFrame.pRSN->abyRSN[5] = 0;
- sFrame.pRSN->abyRSN[6] = 0x00;
- sFrame.pRSN->abyRSN[7] = 0x0F;
- sFrame.pRSN->abyRSN[8] = 0xAC;
- if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
- } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
- } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
- } else {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
- }
- sFrame.pRSN->len += 6;
-
- // Auth Key Management Suite
- sFrame.pRSN->abyRSN[10] = 1;
- sFrame.pRSN->abyRSN[11] = 0;
- sFrame.pRSN->abyRSN[12] = 0x00;
- sFrame.pRSN->abyRSN[13] = 0x0F;
- sFrame.pRSN->abyRSN[14] = 0xAC;
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
- } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
- } else {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
- }
- sFrame.pRSN->len +=6;
-
- // RSN Capabilites
- if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
- memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
- } else {
- sFrame.pRSN->abyRSN[16] = 0;
- sFrame.pRSN->abyRSN[17] = 0;
- }
- sFrame.pRSN->len +=2;
-
- if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
- // RSN PMKID
- pbyRSN = &sFrame.pRSN->abyRSN[18];
- pwPMKID = (u16 *)pbyRSN; // Point to PMKID count
- *pwPMKID = 0; // Initialize PMKID count
- pbyRSN += 2; // Point to PMKID list
- for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
- if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
- pMgmt->abyCurrBSSID,
- ETH_ALEN)) {
- (*pwPMKID)++;
- memcpy(pbyRSN,
- pDevice->gsPMKID.BSSIDInfo[ii].PMKID,
- 16);
- pbyRSN += 16;
- }
- }
- if (*pwPMKID != 0) {
- sFrame.pRSN->len += (2 + (*pwPMKID)*16);
- }
- }
-
- sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
- pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- }
-
- // Adjust the length fields
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an re-association request frame
- *
- *
- * Return Value:
- * A ptr to frame or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeReAssocRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u8 *pDAddr, u16 wCurrCapInfo,
- u16 wListenInterval, PWLAN_IE_SSID pCurrSSID,
- PWLAN_IE_SUPP_RATES pCurrRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_REASSOCREQ sFrame;
- u8 *pbyIEs;
- u8 *pbyRSN;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_REASSOCREQ_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- /* Setup the sFrame structure. */
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
-
- // format fixed field frame structure
- vMgrEncodeReassocRequest(&sFrame);
-
- /* Setup the header */
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- /* Set the capability and listen interval */
- *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
- *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
-
- memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
- /* Copy the SSID */
- /* sFrame.len point to end of fixed field */
- sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
-
- pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
- pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
- pbyIEs = pMgmt->sAssocInfo.abyIEs;
- memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
- pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
-
- /* Copy the rate set */
- /* sFrame.len point to end of SSID */
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
-
- // Copy the extension rate set
- if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
- }
-
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
- pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
-
- if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
- (pMgmt->pCurrBSS != NULL)) {
- /* WPA IE */
- sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
- sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
- sFrame.pRSNWPA->len = 16;
- sFrame.pRSNWPA->abyOUI[0] = 0x00;
- sFrame.pRSNWPA->abyOUI[1] = 0x50;
- sFrame.pRSNWPA->abyOUI[2] = 0xf2;
- sFrame.pRSNWPA->abyOUI[3] = 0x01;
- sFrame.pRSNWPA->wVersion = 1;
- //Group Key Cipher Suite
- sFrame.pRSNWPA->abyMulticast[0] = 0x00;
- sFrame.pRSNWPA->abyMulticast[1] = 0x50;
- sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
- if (pMgmt->byCSSGK == KEY_CTL_WEP) {
- sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
- } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
- } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
- } else {
- sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
- }
- // Pairwise Key Cipher Suite
- sFrame.pRSNWPA->wPKCount = 1;
- sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
- sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
- sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
- if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
- } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
- } else {
- sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
- }
- // Auth Key Management Suite
- pbyRSN = (u8 *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
- *pbyRSN++=0x01;
- *pbyRSN++=0x00;
- *pbyRSN++=0x00;
-
- *pbyRSN++=0x50;
- *pbyRSN++=0xf2;
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
- *pbyRSN++=WPA_AUTH_PSK;
- } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
- *pbyRSN++=WPA_AUTH_IEEE802_1X;
- } else {
- *pbyRSN++=WPA_NONE;
- }
-
- sFrame.pRSNWPA->len +=6;
-
- // RSN Capabilites
- *pbyRSN++=0x00;
- *pbyRSN++=0x00;
- sFrame.pRSNWPA->len +=2;
-
- sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
- // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
- pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
-
- } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
- (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
- (pMgmt->pCurrBSS != NULL)) {
- unsigned int ii;
- u16 * pwPMKID;
-
- /* WPA IE */
- sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
- sFrame.pRSN->byElementID = WLAN_EID_RSN;
- sFrame.pRSN->len = 6; //Version(2)+GK(4)
- sFrame.pRSN->wVersion = 1;
- //Group Key Cipher Suite
- sFrame.pRSN->abyRSN[0] = 0x00;
- sFrame.pRSN->abyRSN[1] = 0x0F;
- sFrame.pRSN->abyRSN[2] = 0xAC;
- if (pMgmt->byCSSGK == KEY_CTL_WEP) {
- sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
- } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
- } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
- } else {
- sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
- }
-
- // Pairwise Key Cipher Suite
- sFrame.pRSN->abyRSN[4] = 1;
- sFrame.pRSN->abyRSN[5] = 0;
- sFrame.pRSN->abyRSN[6] = 0x00;
- sFrame.pRSN->abyRSN[7] = 0x0F;
- sFrame.pRSN->abyRSN[8] = 0xAC;
- if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
- } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
- } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
- } else {
- sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
- }
- sFrame.pRSN->len += 6;
-
- // Auth Key Management Suite
- sFrame.pRSN->abyRSN[10] = 1;
- sFrame.pRSN->abyRSN[11] = 0;
- sFrame.pRSN->abyRSN[12] = 0x00;
- sFrame.pRSN->abyRSN[13] = 0x0F;
- sFrame.pRSN->abyRSN[14] = 0xAC;
- if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
- } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
- } else {
- sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
- }
- sFrame.pRSN->len +=6;
-
- // RSN Capabilites
- if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
- memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
- } else {
- sFrame.pRSN->abyRSN[16] = 0;
- sFrame.pRSN->abyRSN[17] = 0;
- }
- sFrame.pRSN->len +=2;
-
- if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
- // RSN PMKID
- pbyRSN = &sFrame.pRSN->abyRSN[18];
- pwPMKID = (u16 *)pbyRSN; // Point to PMKID count
- *pwPMKID = 0; // Initialize PMKID count
- pbyRSN += 2; // Point to PMKID list
- for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
- if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
- pMgmt->abyCurrBSSID,
- ETH_ALEN)) {
- (*pwPMKID)++;
- memcpy(pbyRSN,
- pDevice->gsPMKID.BSSIDInfo[ii].PMKID,
- 16);
- pbyRSN += 16;
- }
- }
- if (*pwPMKID != 0) {
- sFrame.pRSN->len += (2 + (*pwPMKID)*16);
- }
- }
-
- sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
- pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
- pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
- }
-
- /* Adjust the length fields */
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an assoc-response frame
- *
- *
- * Return Value:
- * PTR to frame; or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeAssocResponse(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
- u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_ASSOCRESP sFrame;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_ASSOCREQ_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- // Setup the sFrame structure
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
- vMgrEncodeAssocResponse(&sFrame);
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
- *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
- *sFrame.pwAid = cpu_to_le16((u16)(wAssocAID | BIT14 | BIT15));
-
- // Copy the rate set
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates,
- pCurrSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
- );
-
- if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates,
- pCurrExtSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
- );
- }
-
- // Adjust the length fields
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Constructs an reassoc-response frame
- *
- *
- * Return Value:
- * PTR to frame; or NULL on allocation failure
- *
--*/
-
-static struct vnt_tx_mgmt *s_MgrMakeReAssocResponse(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, u16 wCurrCapInfo, u16 wAssocStatus,
- u16 wAssocAID, u8 *pDstAddr, PWLAN_IE_SUPP_RATES pCurrSuppRates,
- PWLAN_IE_SUPP_RATES pCurrExtSuppRates)
-{
- struct vnt_tx_mgmt *pTxPacket = NULL;
- WLAN_FR_REASSOCRESP sFrame;
-
- pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyMgmtPacketPool;
- memset(pTxPacket, 0, sizeof(struct vnt_tx_mgmt)
- + WLAN_ASSOCREQ_FR_MAXLEN);
- pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket
- + sizeof(struct vnt_tx_mgmt));
- // Setup the sFrame structure
- sFrame.pBuf = (u8 *)pTxPacket->p80211Header;
- sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
- vMgrEncodeReassocResponse(&sFrame);
- // Setup the header
- sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
- (
- WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
- ));
- memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
- memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
-
- *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
- *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
- *sFrame.pwAid = cpu_to_le16((u16)(wAssocAID | BIT14 | BIT15));
-
- // Copy the rate set
- sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pSuppRates,
- pCurrSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
- );
-
- if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
- sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
- sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
- memcpy(sFrame.pExtSuppRates,
- pCurrExtSuppRates,
- ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
- );
- }
-
- // Adjust the length fields
- pTxPacket->cbMPDULen = sFrame.len;
- pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
-
- return pTxPacket;
-}
-
-/*+
- *
- * Routine Description:
- * Handles probe response management frames.
- *
- *
- * Return Value:
- * none.
- *
--*/
-
-static void s_vMgrRxProbeResponse(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
-{
- PKnownBSS pBSSList = NULL;
- WLAN_FR_PROBERESP sFrame;
- u8 byCurrChannel = pRxPacket->byRxChannel;
- ERPObject sERP;
- int bChannelHit = true;
-
- memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
- // decode the frame
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeProbeResponse(&sFrame);
-
- if ((sFrame.pqwTimestamp == NULL)
- || (sFrame.pwBeaconInterval == NULL)
- || (sFrame.pwCapInfo == NULL)
- || (sFrame.pSSID == NULL)
- || (sFrame.pSuppRates == NULL)) {
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n",
- pRxPacket->p80211Header);
- return;
- }
-
- if(sFrame.pSSID->len == 0)
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
-
- //{{ RobertYu:20050201, 11a byCurrChannel != sFrame.pDSParms->byCurrChannel mapping
- if( byCurrChannel > CB_MAX_CHANNEL_24G )
- {
- if (sFrame.pDSParms) {
- if (byCurrChannel ==
- RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
- bChannelHit = true;
- byCurrChannel =
- RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
- } else {
- bChannelHit = true;
- }
- } else {
- if (sFrame.pDSParms) {
- if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
- bChannelHit = true;
- byCurrChannel = sFrame.pDSParms->byCurrChannel;
- } else {
- bChannelHit = true;
- }
- }
- //RobertYu:20050201
-
-if(ChannelExceedZoneType(pDevice,byCurrChannel)==true)
- return;
-
- if (sFrame.pERP) {
- sERP.byERP = sFrame.pERP->byContext;
- sERP.bERPExist = true;
- } else {
- sERP.bERPExist = false;
- sERP.byERP = 0;
- }
-
- // update or insert the bss
- pBSSList = BSSpAddrIsInBSSList((void *) pDevice,
- sFrame.pHdr->sA3.abyAddr3,
- sFrame.pSSID);
- if (pBSSList) {
- BSSbUpdateToBSSList((void *) pDevice,
- *sFrame.pqwTimestamp,
- *sFrame.pwBeaconInterval,
- *sFrame.pwCapInfo,
- byCurrChannel,
- bChannelHit,
- sFrame.pSSID,
- sFrame.pSuppRates,
- sFrame.pExtSuppRates,
- &sERP,
- sFrame.pRSN,
- sFrame.pRSNWPA,
- sFrame.pIE_Country,
- sFrame.pIE_Quiet,
- pBSSList,
- sFrame.len - WLAN_HDR_ADDR3_LEN,
- /* payload of probresponse */
- sFrame.pHdr->sA4.abyAddr4,
- (void *) pRxPacket);
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
- BSSbInsertToBSSList((void *) pDevice,
- sFrame.pHdr->sA3.abyAddr3,
- *sFrame.pqwTimestamp,
- *sFrame.pwBeaconInterval,
- *sFrame.pwCapInfo,
- byCurrChannel,
- sFrame.pSSID,
- sFrame.pSuppRates,
- sFrame.pExtSuppRates,
- &sERP,
- sFrame.pRSN,
- sFrame.pRSNWPA,
- sFrame.pIE_Country,
- sFrame.pIE_Quiet,
- sFrame.len - WLAN_HDR_ADDR3_LEN,
- sFrame.pHdr->sA4.abyAddr4, /* payload of beacon */
- (void *) pRxPacket);
- }
- return;
-
-}
-
-/*+
- *
- * Routine Description:(AP)or(Ad-hoc STA)
- * Handles probe request management frames.
- *
- *
- * Return Value:
- * none.
- *
--*/
-
-static void s_vMgrRxProbeRequest(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt, struct vnt_rx_mgmt *pRxPacket)
-{
- WLAN_FR_PROBEREQ sFrame;
- CMD_STATUS Status;
- struct vnt_tx_mgmt *pTxPacket;
- u8 byPHYType = BB_TYPE_11B;
-
- // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
- // STA have to response this request.
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
- ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
-
- memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
- // decode the frame
- sFrame.len = pRxPacket->cbMPDULen;
- sFrame.pBuf = (u8 *)pRxPacket->p80211Header;
- vMgrDecodeProbeRequest(&sFrame);
-/*
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n",
- sFrame.pHdr->sA3.abyAddr2);
-*/
- if (sFrame.pSSID->len != 0) {
- if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
- return;
- if (memcmp(sFrame.pSSID->abySSID,
- ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
- ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
- return;
- }
- }
-
- if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
- byPHYType = BB_TYPE_11G;
- }
-
- // Probe response reply..
- pTxPacket = s_MgrMakeProbeResponse
- (
- pDevice,
- pMgmt,
- pMgmt->wCurrCapInfo,
- pMgmt->wCurrBeaconPeriod,
- pMgmt->uCurrChannel,
- 0,
- sFrame.pHdr->sA3.abyAddr2,
- (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
- (u8 *)pMgmt->abyCurrBSSID,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
- byPHYType
- );
- if (pTxPacket != NULL ){
- /* send the frame */
- Status = csMgmt_xmit(pDevice, pTxPacket);
- if (Status != CMD_STATUS_PENDING) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
- }
- else {
-// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
- }
- }
- }
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- *
- * Entry point for the reception and handling of 802.11 management
- * frames. Makes a determination of the frame type and then calls
- * the appropriate function.
- *
- *
- * Return Value:
- * none.
- *
--*/
-
-void vMgrRxManagePacket(struct vnt_private *pDevice, struct vnt_manager *pMgmt,
- struct vnt_rx_mgmt *pRxPacket)
-{
- int bInScan = false;
- u32 uNodeIndex = 0;
- NODE_STATE eNodeState = 0;
- CMD_STATUS Status;
-
- if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
- if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
- eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
- }
-
- switch( WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) ){
-
- case WLAN_FSTYPE_ASSOCREQ:
- // Frame Clase = 2
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
- (eNodeState < NODE_AUTH)) {
- // send deauth notification
- // reason = (6) class 2 received from nonauth sta
- vMgrDeAuthenBeginSta(pDevice,
- pMgmt,
- pRxPacket->p80211Header->sA3.abyAddr2,
- (6),
- &Status
- );
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
- }
- else {
- s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
- }
- break;
-
- case WLAN_FSTYPE_ASSOCRESP:
- // Frame Clase = 2
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
- s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
- break;
-
- case WLAN_FSTYPE_REASSOCREQ:
- // Frame Clase = 2
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
- // Todo: reassoc
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
- (eNodeState < NODE_AUTH)) {
- // send deauth notification
- // reason = (6) class 2 received from nonauth sta
- vMgrDeAuthenBeginSta(pDevice,
- pMgmt,
- pRxPacket->p80211Header->sA3.abyAddr2,
- (6),
- &Status
- );
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
-
- }
- s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
- break;
-
- case WLAN_FSTYPE_REASSOCRESP:
- // Frame Clase = 2
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
- s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
- break;
-
- case WLAN_FSTYPE_PROBEREQ:
- // Frame Clase = 0
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
- s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
- break;
-
- case WLAN_FSTYPE_PROBERESP:
- // Frame Clase = 0
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
-
- s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
- break;
-
- case WLAN_FSTYPE_BEACON:
- // Frame Clase = 0
- //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
- if (pMgmt->eScanState != WMAC_NO_SCANNING) {
- bInScan = true;
- }
- s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
- break;
-
- case WLAN_FSTYPE_ATIM:
- // Frame Clase = 1
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
- break;
-
- case WLAN_FSTYPE_DISASSOC:
- // Frame Clase = 2
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
- if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
- (eNodeState < NODE_AUTH)) {
- // send deauth notification
- // reason = (6) class 2 received from nonauth sta
- vMgrDeAuthenBeginSta(pDevice,
- pMgmt,
- pRxPacket->p80211Header->sA3.abyAddr2,
- (6),
- &Status
- );
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
- }
- s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
- break;
-
- case WLAN_FSTYPE_AUTHEN:
- // Frame Clase = 1
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n");
- s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
- break;
-
- case WLAN_FSTYPE_DEAUTHEN:
- // Frame Clase = 1
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
- s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
- break;
-
- default:
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
- }
-
- return;
-}
-
-/*+
- *
- * Routine Description:
- *
- *
- * Prepare beacon to send
- *
- * Return Value:
- * true if success; false if failed.
- *
--*/
-int bMgrPrepareBeaconToSend(struct vnt_private *pDevice,
- struct vnt_manager *pMgmt)
-{
- struct vnt_tx_mgmt *pTxPacket;
- unsigned long flags;
-
-// pDevice->bBeaconBufReady = false;
- if (pDevice->bEncryptionEnable)
- pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
- else
- pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
-
- pTxPacket = s_MgrMakeBeacon
- (
- pDevice,
- pMgmt,
- pMgmt->wCurrCapInfo,
- pMgmt->wCurrBeaconPeriod,
- pMgmt->uCurrChannel,
- pMgmt->wCurrATIMWindow, //0,
- (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
- (u8 *)pMgmt->abyCurrBSSID,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
- (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
- );
-
- if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
- (pMgmt->abyCurrBSSID[0] == 0))
- return false;
-
- spin_lock_irqsave(&pDevice->lock, flags);
-
- csBeacon_xmit(pDevice, pTxPacket);
-
- spin_unlock_irqrestore(&pDevice->lock, flags);
-
- MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
-
- return true;
-}
-
-/*+
- *
- * Routine Description:
- *
- * Log a warning message based on the contents of the Status
- * Code field of an 802.11 management frame. Defines are
- * derived from 802.11-1997 SPEC.
- *
- * Return Value:
- * none.
- *
--*/
-static void s_vMgrLogStatus(struct vnt_manager *pMgmt, u16 wStatus)
-{
- switch( wStatus ){
- case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
- break;
- case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
- break;
- case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
- break;
- case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
- break;
- case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
- break;
- case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n");
- break;
- case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
- break;
- case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
- break;
- default:
- DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
- break;
- }
-}
-
-/*
- *
- * Description:
- * Add BSSID in PMKID Candidate list.
- *
- * Parameters:
- * In:
- * hDeviceContext - device structure point
- * pbyBSSID - BSSID address for adding
- * wRSNCap - BSS's RSN capability
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-
-int bAdd_PMKID_Candidate(struct vnt_private *pDevice, u8 *pbyBSSID,
- PSRSNCapObject psRSNCapObj)
-{
- PPMKID_CANDIDATE pCandidateList;
- int ii = 0;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
-
- if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
- return false;
-
- if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
- return false;
-
- // Update Old Candidate
- for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
- pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
- if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
- if ((psRSNCapObj->bRSNCapExist == true)
- && (psRSNCapObj->wRSNCap & BIT0)) {
- pCandidateList->Flags |=
- NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
- } else {
- pCandidateList->Flags &=
- ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
- }
- return true;
- }
- }
-
- // New Candidate
- pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
- if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
- pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
- } else {
- pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
- }
- memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
- pDevice->gsPMKIDCandidate.NumCandidates++;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
- return true;
-}
-
-/*
- *
- * Description:
- * Flush PMKID Candidate list.
- *
- * Parameters:
- * In:
- * hDeviceContext - device structure point
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-
-void vFlush_PMKID_Candidate(struct vnt_private *pDevice)
-{
- if (pDevice == NULL)
- return;
-
- memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
-
- return;
-}
-
-static bool
-s_bCipherMatch (
- PKnownBSS pBSSNode,
- NDIS_802_11_ENCRYPTION_STATUS EncStatus,
- u8 * pbyCCSPK,
- u8 * pbyCCSGK
- )
-{
- u8 byMulticastCipher = KEY_CTL_INVALID;
- u8 byCipherMask = 0x00;
- int i;
-
- if (pBSSNode == NULL)
- return false;
-
- // check cap. of BSS
- if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
- (EncStatus == Ndis802_11Encryption1Enabled)) {
- // default is WEP only
- byMulticastCipher = KEY_CTL_WEP;
- }
-
- if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
- (pBSSNode->bWPA2Valid == true) &&
-
- ((EncStatus == Ndis802_11Encryption3Enabled) ||
- (EncStatus == Ndis802_11Encryption2Enabled))) {
- //WPA2
- // check Group Key Cipher
- if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
- (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
- byMulticastCipher = KEY_CTL_WEP;
- } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
- byMulticastCipher = KEY_CTL_TKIP;
- } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
- byMulticastCipher = KEY_CTL_CCMP;
- } else {
- byMulticastCipher = KEY_CTL_INVALID;
- }
-
- /* check Pairwise Key Cipher */
- for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
- if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
- (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
- /* this should not happen as defined 802.11i */
- byCipherMask |= 0x01;
- } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
- byCipherMask |= 0x02;
- } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
- byCipherMask |= 0x04;
- } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
- /* use group key only ignore all others */
- byCipherMask = 0;
- i = pBSSNode->wCSSPKCount;
- }
- }
-
- } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
- (pBSSNode->bWPAValid == true) &&
- ((EncStatus == Ndis802_11Encryption2Enabled) || (EncStatus == Ndis802_11Encryption3Enabled))) {
- //WPA
- // check Group Key Cipher
- if ((pBSSNode->byGKType == WPA_WEP40) ||
- (pBSSNode->byGKType == WPA_WEP104)) {
- byMulticastCipher = KEY_CTL_WEP;
- } else if (pBSSNode->byGKType == WPA_TKIP) {
- byMulticastCipher = KEY_CTL_TKIP;
- } else if (pBSSNode->byGKType == WPA_AESCCMP) {
- byMulticastCipher = KEY_CTL_CCMP;
- } else {
- byMulticastCipher = KEY_CTL_INVALID;
- }
-
- /* check Pairwise Key Cipher */
- for (i = 0; i < pBSSNode->wPKCount; i++) {
- if (pBSSNode->abyPKType[i] == WPA_TKIP) {
- byCipherMask |= 0x02;
- } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
- byCipherMask |= 0x04;
- } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
- /* use group key only ignore all others */
- byCipherMask = 0;
- i = pBSSNode->wPKCount;
- }
- }
- }
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
- byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
-
- // mask our cap. with BSS
- if (EncStatus == Ndis802_11Encryption1Enabled) {
-
- // For supporting Cisco migration mode, don't care pairwise key cipher
- //if ((byMulticastCipher == KEY_CTL_WEP) &&
- // (byCipherMask == 0)) {
- if ((byMulticastCipher == KEY_CTL_WEP) &&
- (byCipherMask == 0)) {
- *pbyCCSGK = KEY_CTL_WEP;
- *pbyCCSPK = KEY_CTL_NONE;
- return true;
- } else {
- return false;
- }
-
- } else if (EncStatus == Ndis802_11Encryption2Enabled) {
- if ((byMulticastCipher == KEY_CTL_TKIP) &&
- (byCipherMask == 0)) {
- *pbyCCSGK = KEY_CTL_TKIP;
- *pbyCCSPK = KEY_CTL_NONE;
- return true;
- } else if ((byMulticastCipher == KEY_CTL_WEP) &&
- ((byCipherMask & 0x02) != 0)) {
- *pbyCCSGK = KEY_CTL_WEP;
- *pbyCCSPK = KEY_CTL_TKIP;
- return true;
- } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
- ((byCipherMask & 0x02) != 0)) {
- *pbyCCSGK = KEY_CTL_TKIP;
- *pbyCCSPK = KEY_CTL_TKIP;
- return true;
- } else {
- return false;
- }
- } else if (EncStatus == Ndis802_11Encryption3Enabled) {
- if ((byMulticastCipher == KEY_CTL_CCMP) &&
- (byCipherMask == 0)) {
- // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
- return false;
- } else if ((byMulticastCipher == KEY_CTL_WEP) &&
- ((byCipherMask & 0x04) != 0)) {
- *pbyCCSGK = KEY_CTL_WEP;
- *pbyCCSPK = KEY_CTL_CCMP;
- return true;
- } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
- ((byCipherMask & 0x04) != 0)) {
- *pbyCCSGK = KEY_CTL_TKIP;
- *pbyCCSPK = KEY_CTL_CCMP;
- return true;
- } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
- ((byCipherMask & 0x04) != 0)) {
- *pbyCCSGK = KEY_CTL_CCMP;
- *pbyCCSPK = KEY_CTL_CCMP;
- return true;
- } else {
- return false;
- }
- }
- return true;
-}
-
diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h
deleted file mode 100644
index 26ba47da467b..000000000000
--- a/drivers/staging/vt6656/wmgr.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wmgr.h
- *
- * Purpose:
- *
- * Author: lyndon chen
- *
- * Date: Jan 2, 2003
- *
- * Functions:
- *
- * Revision History:
- *
- */
-
-#ifndef __WMGR_H__
-#define __WMGR_H__
-
-#include "80211mgr.h"
-#include "80211hdr.h"
-#include "wcmd.h"
-#include "bssdb.h"
-#include "wpa2.h"
-#include "card.h"
-
-// Scan time
-#define PROBE_DELAY 100 // (us)
-#define SWITCH_CHANNEL_DELAY 200 // (us)
-#define WLAN_SCAN_MINITIME 25 // (ms)
-#define WLAN_SCAN_MAXTIME 100 // (ms)
-#define TRIVIAL_SYNC_DIFFERENCE 0 // (us)
-#define DEFAULT_IBSS_BI 100 // (ms)
-
-#define WCMD_ACTIVE_SCAN_TIME 20 //(ms)
-#define WCMD_PASSIVE_SCAN_TIME 100 //(ms)
-
-#define DEFAULT_MSDU_LIFETIME 512 // ms
-#define DEFAULT_MSDU_LIFETIME_RES_64us 8000 // 64us
-
-#define DEFAULT_MGN_LIFETIME 8 // ms
-#define DEFAULT_MGN_LIFETIME_RES_64us 125 // 64us
-
-#define MAKE_BEACON_RESERVED 10 //(us)
-
-#define TIM_MULTICAST_MASK 0x01
-#define TIM_BITMAPOFFSET_MASK 0xFE
-#define DEFAULT_DTIM_PERIOD 1
-
-#define AP_LONG_RETRY_LIMIT 4
-
-#define DEFAULT_IBSS_CHANNEL 6 //2.4G
-
-//mike define: make timer to expire after desired times
-#define timer_expire(timer, next_tick) mod_timer(&timer, RUN_AT(next_tick))
-
-typedef void (*TimerFunction)(unsigned long);
-
-//+++ NDIS related
-
-typedef u8 NDIS_802_11_MAC_ADDRESS[ETH_ALEN];
-typedef struct _NDIS_802_11_AI_REQFI
-{
- u16 Capabilities;
- u16 ListenInterval;
- NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
-} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
-
-typedef struct _NDIS_802_11_AI_RESFI
-{
- u16 Capabilities;
- u16 StatusCode;
- u16 AssociationId;
-} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
-
-typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
-{
- u32 Length;
- u16 AvailableRequestFixedIEs;
- NDIS_802_11_AI_REQFI RequestFixedIEs;
- u32 RequestIELength;
- u32 OffsetRequestIEs;
- u16 AvailableResponseFixedIEs;
- NDIS_802_11_AI_RESFI ResponseFixedIEs;
- u32 ResponseIELength;
- u32 OffsetResponseIEs;
-} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
-
-typedef struct tagSAssocInfo {
- NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
- u8 abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
- /* store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION */
- u32 RequestIELength;
- u8 abyReqIEs[WLAN_BEACON_FR_MAXLEN];
-} SAssocInfo, *PSAssocInfo;
-
-typedef enum tagWMAC_AUTHENTICATION_MODE {
-
- WMAC_AUTH_OPEN,
- WMAC_AUTH_SHAREKEY,
- WMAC_AUTH_AUTO,
- WMAC_AUTH_WPA,
- WMAC_AUTH_WPAPSK,
- WMAC_AUTH_WPANONE,
- WMAC_AUTH_WPA2,
- WMAC_AUTH_WPA2PSK,
- WMAC_AUTH_MAX // Not a real mode, defined as upper bound
-} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE;
-
-// Pre-configured Mode (from XP)
-
-typedef enum tagWMAC_CONFIG_MODE {
- WMAC_CONFIG_ESS_STA,
- WMAC_CONFIG_IBSS_STA,
- WMAC_CONFIG_AUTO,
- WMAC_CONFIG_AP
-
-} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE;
-
-typedef enum tagWMAC_SCAN_TYPE {
-
- WMAC_SCAN_ACTIVE,
- WMAC_SCAN_PASSIVE,
- WMAC_SCAN_HYBRID
-
-} WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE;
-
-typedef enum tagWMAC_SCAN_STATE {
-
- WMAC_NO_SCANNING,
- WMAC_IS_SCANNING,
- WMAC_IS_PROBEPENDING
-
-} WMAC_SCAN_STATE, *PWMAC_SCAN_STATE;
-
-// Notes:
-// Basic Service Set state explained as following:
-// WMAC_STATE_IDLE : no BSS is selected (Adhoc or Infra)
-// WMAC_STATE_STARTED : no BSS is selected, start own IBSS (Adhoc only)
-// WMAC_STATE_JOINTED : BSS is selected and synchronized (Adhoc or Infra)
-// WMAC_STATE_AUTHPENDING : Authentication pending (Infra)
-// WMAC_STATE_AUTH : Authenticated (Infra)
-// WMAC_STATE_ASSOCPENDING : Association pending (Infra)
-// WMAC_STATE_ASSOC : Associated (Infra)
-
-typedef enum tagWMAC_BSS_STATE {
-
- WMAC_STATE_IDLE,
- WMAC_STATE_STARTED,
- WMAC_STATE_JOINTED,
- WMAC_STATE_AUTHPENDING,
- WMAC_STATE_AUTH,
- WMAC_STATE_ASSOCPENDING,
- WMAC_STATE_ASSOC
-
-} WMAC_BSS_STATE, *PWMAC_BSS_STATE;
-
-// WMAC selected running mode
-typedef enum tagWMAC_CURRENT_MODE {
-
- WMAC_MODE_STANDBY,
- WMAC_MODE_ESS_STA,
- WMAC_MODE_IBSS_STA,
- WMAC_MODE_ESS_AP
-
-} WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE;
-
-typedef enum tagWMAC_POWER_MODE {
-
- WMAC_POWER_CAM,
- WMAC_POWER_FAST,
- WMAC_POWER_MAX
-
-} WMAC_POWER_MODE, *PWMAC_POWER_MODE;
-
-/* Tx Management Packet descriptor */
-struct vnt_tx_mgmt {
- PUWLAN_80211HDR p80211Header;
- u32 cbMPDULen;
- u32 cbPayloadLen;
-};
-
-/* Rx Management Packet descriptor */
-struct vnt_rx_mgmt {
- PUWLAN_80211HDR p80211Header;
- u64 qwLocalTSF;
- u32 cbMPDULen;
- u32 cbPayloadLen;
- u32 uRSSI;
- u8 bySQ;
- u8 byRxRate;
- u8 byRxChannel;
-};
-
-struct vnt_manager {
- void *pAdapter;
-
- /* MAC address */
- u8 abyMACAddr[WLAN_ADDR_LEN];
-
- /* Configuration Mode */
- WMAC_CONFIG_MODE eConfigMode; /* MAC pre-configed mode */
-
- CARD_PHY_TYPE eCurrentPHYMode;
-
- /* Operation state variables */
- WMAC_CURRENT_MODE eCurrMode; /* MAC current connection mode */
- WMAC_BSS_STATE eCurrState; /* MAC current BSS state */
- WMAC_BSS_STATE eLastState; /* MAC last BSS state */
-
- PKnownBSS pCurrBSS;
- u8 byCSSGK;
- u8 byCSSPK;
-
- int bCurrBSSIDFilterOn;
-
- /* Current state vars */
- u32 uCurrChannel;
- u8 abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- u8 abyCurrBSSID[WLAN_BSSID_LEN];
- u16 wCurrCapInfo;
- u16 wCurrAID;
- u32 uRSSITrigger;
- u16 wCurrATIMWindow;
- u16 wCurrBeaconPeriod;
- int bIsDS;
- u8 byERPContext;
-
- CMD_STATE eCommandState;
- u32 uScanChannel;
-
- /* Desire joinning BSS vars */
- u8 abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- u8 abyDesireBSSID[WLAN_BSSID_LEN];
-
- /*restore BSS info for Ad-Hoc mode */
- u8 abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
-
- /* Adhoc or AP configuration vars */
- u16 wIBSSBeaconPeriod;
- u16 wIBSSATIMWindow;
- u32 uIBSSChannel;
- u8 abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
- u8 byAPBBType;
- u8 abyWPAIE[MAX_WPA_IE_LEN];
- u16 wWPAIELen;
-
- u32 uAssocCount;
- int bMoreData;
-
- /* Scan state vars */
- WMAC_SCAN_STATE eScanState;
- WMAC_SCAN_TYPE eScanType;
- u32 uScanStartCh;
- u32 uScanEndCh;
- u16 wScanSteps;
- u32 uScanBSSType;
- /* Desire scannig vars */
- u8 abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
- u8 abyScanBSSID[WLAN_BSSID_LEN];
-
- /* Privacy */
- WMAC_AUTHENTICATION_MODE eAuthenMode;
- int bShareKeyAlgorithm;
- u8 abyChallenge[WLAN_CHALLENGE_LEN];
- int bPrivacyInvoked;
-
- /* Received beacon state vars */
- int bInTIM;
- int bMulticastTIM;
- u8 byDTIMCount;
- u8 byDTIMPeriod;
-
- /* Power saving state vars */
- WMAC_POWER_MODE ePSMode;
- u16 wListenInterval;
- u16 wCountToWakeUp;
- int bInTIMWake;
- u8 *pbyPSPacketPool;
- u8 byPSPacketPool[sizeof(struct vnt_tx_mgmt)
- + WLAN_NULLDATA_FR_MAXLEN];
- int bRxBeaconInTBTTWake;
- u8 abyPSTxMap[MAX_NODE_NUM + 1];
-
- /* management command related */
- u32 uCmdBusy;
- u32 uCmdHostAPBusy;
-
- /* management packet pool */
- u8 *pbyMgmtPacketPool;
- u8 byMgmtPacketPool[sizeof(struct vnt_tx_mgmt)
- + WLAN_A3FR_MAXLEN];
-
- /* Temporarily Rx Mgmt Packet Descriptor */
- struct vnt_rx_mgmt sRxPacket;
-
- /* link list of known bss's (scan results) */
- KnownBSS sBSSList[MAX_BSS_NUM];
- /* link list of same bss's */
- KnownBSS pSameBSS[6];
- int Cisco_cckm;
- u8 Roam_dbm;
-
- /* table list of known node */
- /* sNodeDBList[0] is reserved for AP under Infra mode */
- /* sNodeDBList[0] is reserved for Multicast under adhoc/AP mode */
- KnownNodeDB sNodeDBTable[MAX_NODE_NUM + 1];
-
- /* WPA2 PMKID Cache */
- SPMKIDCache gsPMKIDCache;
- int bRoaming;
-
- /* associate info */
- SAssocInfo sAssocInfo;
-
- /* for 802.11h */
- int b11hEnable;
- int bSwitchChannel;
- u8 byNewChannel;
- PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep;
- u32 uLengthOfRepEIDs;
- u8 abyCurrentMSRReq[sizeof(struct vnt_tx_mgmt)
- + WLAN_A3FR_MAXLEN];
- u8 abyCurrentMSRRep[sizeof(struct vnt_tx_mgmt)
- + WLAN_A3FR_MAXLEN];
- u8 abyIECountry[WLAN_A3FR_MAXLEN];
- u8 abyIBSSDFSOwner[6];
- u8 byIBSSDFSRecovery;
-
- struct sk_buff skb;
-
-};
-
-void vMgrObjectInit(struct vnt_private *pDevice);
-
-void vMgrAssocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *, PCMD_STATUS pStatus);
-
-void vMgrReAssocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *, PCMD_STATUS pStatus);
-
-void vMgrDisassocBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *, u8 *abyDestAddress, u16 wReason,
- PCMD_STATUS pStatus);
-
-void vMgrAuthenBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *, PCMD_STATUS pStatus);
-
-void vMgrCreateOwnIBSS(struct vnt_private *pDevice,
- PCMD_STATUS pStatus);
-
-void vMgrJoinBSSBegin(struct vnt_private *pDevice,
- PCMD_STATUS pStatus);
-
-void vMgrRxManagePacket(struct vnt_private *pDevice,
- struct vnt_manager *, struct vnt_rx_mgmt *);
-
-/*
-void
-vMgrScanBegin(
- void *hDeviceContext,
- PCMD_STATUS pStatus
- );
-*/
-
-void vMgrDeAuthenBeginSta(struct vnt_private *pDevice,
- struct vnt_manager *, u8 *abyDestAddress, u16 wReason,
- PCMD_STATUS pStatus);
-
-int bMgrPrepareBeaconToSend(struct vnt_private *pDevice,
- struct vnt_manager *);
-
-int bAdd_PMKID_Candidate(struct vnt_private *pDevice,
- u8 *pbyBSSID, PSRSNCapObject psRSNCapObj);
-
-void vFlush_PMKID_Candidate(struct vnt_private *pDevice);
-
-#endif /* __WMGR_H__ */
diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c
deleted file mode 100644
index 403c295cc02c..000000000000
--- a/drivers/staging/vt6656/wpa.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wpa.c
- *
- * Purpose: Handles the Basic Service Set & Node Database functions
- *
- * Functions:
- * WPA_ParseRSN - Parse RSN IE.
- *
- * Revision History:
- *
- * Author: Kyle Hsu
- *
- * Date: July 14, 2003
- *
- */
-
-#include "tmacro.h"
-#include "tether.h"
-#include "device.h"
-#include "80211hdr.h"
-#include "bssdb.h"
-#include "wmgr.h"
-#include "wpa.h"
-#include "80211mgr.h"
-
-static int msglevel =MSG_LEVEL_INFO;
-
-static const u8 abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
-static const u8 abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-static const u8 abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
-static const u8 abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
-static const u8 abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
-static const u8 abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
-
-/*+
- *
- * Description:
- * Clear RSN information in BSSList.
- *
- * Parameters:
- * In:
- * pBSSList - BSS list.
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-
-void
-WPA_ClearRSN(
- PKnownBSS pBSSList
- )
-{
- int ii;
- pBSSList->byGKType = WPA_TKIP;
- for (ii=0; ii < 4; ii ++)
- pBSSList->abyPKType[ii] = WPA_TKIP;
- pBSSList->wPKCount = 0;
- for (ii=0; ii < 4; ii ++)
- pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X;
- pBSSList->wAuthCount = 0;
- pBSSList->byDefaultK_as_PK = 0;
- pBSSList->byReplayIdx = 0;
- pBSSList->sRSNCapObj.bRSNCapExist = false;
- pBSSList->sRSNCapObj.wRSNCap = 0;
- pBSSList->bWPAValid = false;
-}
-
-/*+
- *
- * Description:
- * Parse RSN IE.
- *
- * Parameters:
- * In:
- * pBSSList - BSS list.
- * pRSN - Pointer to the RSN IE.
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-void
-WPA_ParseRSN(
- PKnownBSS pBSSList,
- PWLAN_IE_RSN_EXT pRSN
- )
-{
- PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL;
- int i, j, m, n = 0;
- u8 * pbyCaps;
-
- WPA_ClearRSN(pBSSList);
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len);
-
- // information element header makes sense
- if ((pRSN->len >= 6) // oui1(4)+ver(2)
- && (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4)
- && (pRSN->wVersion == 1)) {
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n");
- // update each variable if pRSN is long enough to contain the variable
- if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4)
- {
- if ( !memcmp(pRSN->abyMulticast, abyOUI01, 4))
- pBSSList->byGKType = WPA_WEP40;
- else if ( !memcmp(pRSN->abyMulticast, abyOUI02, 4))
- pBSSList->byGKType = WPA_TKIP;
- else if ( !memcmp(pRSN->abyMulticast, abyOUI03, 4))
- pBSSList->byGKType = WPA_AESWRAP;
- else if ( !memcmp(pRSN->abyMulticast, abyOUI04, 4))
- pBSSList->byGKType = WPA_AESCCMP;
- else if ( !memcmp(pRSN->abyMulticast, abyOUI05, 4))
- pBSSList->byGKType = WPA_WEP104;
- else
- // any vendor checks here
- pBSSList->byGKType = WPA_NONE;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType);
- }
-
- if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
- {
- j = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
- for (i = 0; (i < pRSN->wPKCount) &&
- (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) {
- if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
- if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
- pBSSList->abyPKType[j++] = WPA_NONE;
- else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
- pBSSList->abyPKType[j++] = WPA_TKIP;
- else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
- pBSSList->abyPKType[j++] = WPA_AESWRAP;
- else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4))
- pBSSList->abyPKType[j++] = WPA_AESCCMP;
- else
- // any vendor checks here
- ;
- }
- else
- break;
- //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1]));
- } //for
- pBSSList->wPKCount = (u16)j;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
- }
-
- m = pRSN->wPKCount;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4);
-
- if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)
- // overlay IE_RSN_Auth structure into correct place
- pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
- j = 0;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n",
- pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
- for (i = 0; (i < pIE_RSN_Auth->wAuthCount) &&
- (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) {
- if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
- if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
- pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
- else if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4))
- pBSSList->abyAuthType[j++] = WPA_AUTH_PSK;
- else
- // any vendor checks here
- ;
- }
- else
- break;
- //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1]));
- }
- if(j > 0)
- pBSSList->wAuthCount = (u16)j;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
- }
-
- if (pIE_RSN_Auth != NULL) {
-
- n = pIE_RSN_Auth->wAuthCount;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
-
- if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2)
- pbyCaps = (u8 *)pIE_RSN_Auth->AuthKSList[n].abyOUI;
- pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG;
- pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS);
- pBSSList->sRSNCapObj.bRSNCapExist = true;
- pBSSList->sRSNCapObj.wRSNCap = *(u16 *)pbyCaps;
- //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps));
- //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK));
- //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx));
- }
- }
- pBSSList->bWPAValid = true;
- }
-}
-
-/*+
- *
- * Description:
- * Search RSN information in BSSList.
- *
- * Parameters:
- * In:
- * byCmd - Search type
- * byEncrypt- Encrypt Type
- * pBSSList - BSS list
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-bool
-WPA_SearchRSN(
- u8 byCmd,
- u8 byEncrypt,
- PKnownBSS pBSSList
- )
-{
- int ii;
- u8 byPKType = WPA_NONE;
-
- if (pBSSList->bWPAValid == false)
- return false;
-
- switch(byCmd) {
- case 0:
-
- if (byEncrypt != pBSSList->byGKType)
- return false;
-
- if (pBSSList->wPKCount > 0) {
- for (ii = 0; ii < pBSSList->wPKCount; ii ++) {
- if (pBSSList->abyPKType[ii] == WPA_AESCCMP)
- byPKType = WPA_AESCCMP;
- else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP))
- byPKType = WPA_TKIP;
- else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
- byPKType = WPA_WEP40;
- else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
- byPKType = WPA_WEP104;
- }
- if (byEncrypt != byPKType)
- return false;
- }
- return true;
-// if (pBSSList->wAuthCount > 0)
-// for (ii=0; ii < pBSSList->wAuthCount; ii ++)
-// if (byAuth == pBSSList->abyAuthType[ii])
-// break;
- break;
-
- default:
- break;
- }
- return false;
-}
-
-/*+
- *
- * Description:
- * Check if RSN IE makes sense.
- *
- * Parameters:
- * In:
- * pRSN - Pointer to the RSN IE.
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-bool
-WPAb_Is_RSN(
- PWLAN_IE_RSN_EXT pRSN
- )
-{
- if (pRSN == NULL)
- return false;
-
- if ((pRSN->len >= 6) && // oui1(4)+ver(2)
- (pRSN->byElementID == WLAN_EID_RSN_WPA) && !memcmp(pRSN->abyOUI, abyOUI01, 4) &&
- (pRSN->wVersion == 1)) {
- return true;
- }
- else
- return false;
-}
-
diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h
deleted file mode 100644
index 2a724c064e59..000000000000
--- a/drivers/staging/vt6656/wpa.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wpa.h
- *
- * Purpose: Defines the macros, types, and functions for dealing
- * with WPA informations.
- *
- * Author: Kyle Hsu
- *
- * Date: Jul 14, 2003
- *
- */
-
-#ifndef __WPA_H__
-#define __WPA_H__
-
-#include "80211hdr.h"
-
-#define WPA_NONE 0
-#define WPA_WEP40 1
-#define WPA_TKIP 2
-#define WPA_AESWRAP 3
-#define WPA_AESCCMP 4
-#define WPA_WEP104 5
-#define WPA_AUTH_IEEE802_1X 1
-#define WPA_AUTH_PSK 2
-
-#define WPA_GROUPFLAG 0x02
-#define WPA_REPLAYBITSSHIFT 2
-#define WPA_REPLAYBITS 0x03
-
-void
-WPA_ClearRSN(
- PKnownBSS pBSSList
- );
-
-void
-WPA_ParseRSN(
- PKnownBSS pBSSList,
- PWLAN_IE_RSN_EXT pRSN
- );
-
-bool
-WPA_SearchRSN(
- u8 byCmd,
- u8 byEncrypt,
- PKnownBSS pBSSList
- );
-
-bool
-WPAb_Is_RSN(
- PWLAN_IE_RSN_EXT pRSN
- );
-
-#endif /* __WPA_H__ */
diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c
deleted file mode 100644
index df5541794e0f..000000000000
--- a/drivers/staging/vt6656/wpa2.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wpa2.c
- *
- * Purpose: Handles the Basic Service Set & Node Database functions
- *
- * Functions:
- *
- * Revision History:
- *
- * Author: Yiching Chen
- *
- * Date: Oct. 4, 2004
- *
- */
-
-#include "device.h"
-#include "wpa2.h"
-
-static int msglevel =MSG_LEVEL_INFO;
-//static int msglevel =MSG_LEVEL_DEBUG;
-
-static const u8 abyOUIGK[4] = { 0x00, 0x0F, 0xAC, 0x00 };
-static const u8 abyOUIWEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
-static const u8 abyOUIWEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
-static const u8 abyOUITKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
-static const u8 abyOUICCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
-
-static const u8 abyOUI8021X[4] = { 0x00, 0x0F, 0xAC, 0x01 };
-static const u8 abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 };
-
-/*+
- *
- * Description:
- * Clear RSN information in BSSList.
- *
- * Parameters:
- * In:
- * pBSSNode - BSS list.
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-void
-WPA2_ClearRSN (
- PKnownBSS pBSSNode
- )
-{
- int ii;
-
- pBSSNode->bWPA2Valid = false;
-
- pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
- for (ii=0; ii < 4; ii ++)
- pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP;
- pBSSNode->wCSSPKCount = 1;
- for (ii=0; ii < 4; ii ++)
- pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X;
- pBSSNode->wAKMSSAuthCount = 1;
- pBSSNode->sRSNCapObj.bRSNCapExist = false;
- pBSSNode->sRSNCapObj.wRSNCap = 0;
-}
-
-/*+
- *
- * Description:
- * Parse RSN IE.
- *
- * Parameters:
- * In:
- * pBSSNode - BSS list.
- * pRSN - Pointer to the RSN IE.
- * Out:
- * none
- *
- * Return Value: none.
- *
--*/
-void
-WPA2vParseRSN (
- PKnownBSS pBSSNode,
- PWLAN_IE_RSN pRSN
- )
-{
- int i, j;
- u16 m = 0, n = 0;
- u8 * pbyOUI;
- bool bUseGK = false;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
-
- WPA2_ClearRSN(pBSSNode);
-
- if (pRSN->len == 2) { // ver(2)
- if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) {
- pBSSNode->bWPA2Valid = true;
- }
- return;
- }
-
- if (pRSN->len < 6) { // ver(2) + GK(4)
- // invalid CSS, P802.11i/D10.0, p31
- return;
- }
-
- // information element header makes sense
- if ((pRSN->byElementID == WLAN_EID_RSN) &&
- (pRSN->wVersion == 1)) {
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
-
- pbyOUI = &(pRSN->abyRSN[0]);
- if ( !memcmp(pbyOUI, abyOUIWEP40, 4))
- pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40;
- else if ( !memcmp(pbyOUI, abyOUITKIP, 4))
- pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP;
- else if ( !memcmp(pbyOUI, abyOUICCMP, 4))
- pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
- else if ( !memcmp(pbyOUI, abyOUIWEP104, 4))
- pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104;
- else if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
- // invalid CSS, P802.11i/D10.0, p32
- return;
- } else
- // any vendor checks here
- pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
-
- if (pRSN->len == 6) {
- pBSSNode->bWPA2Valid = true;
- return;
- }
-
- if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2)
- pBSSNode->wCSSPKCount = *((u16 *) &(pRSN->abyRSN[4]));
- j = 0;
- pbyOUI = &(pRSN->abyRSN[6]);
-
- for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(u8)); i++) {
-
- if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
- if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
- pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
- bUseGK = true;
- } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) {
- // Invalid CSS, continue parsing
- } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) {
- if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP)
- pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP;
- else
- ; // Invalid CSS, continue parsing
- } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) {
- pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP;
- } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) {
- // Invalid CSS, continue parsing
- } else {
- // any vendor checks here
- pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN;
- }
- pbyOUI += 4;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]);
- } else
- break;
- } //for
-
- if (bUseGK == true) {
- if (j != 1) {
- // invalid CSS, This should be only PK CSS.
- return;
- }
- if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
- // invalid CSS, If CCMP is enable , PK can't be CSSGK.
- return;
- }
- }
- if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) {
- // invalid CSS, No valid PK.
- return;
- }
- pBSSNode->wCSSPKCount = (u16)j;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
- }
-
- m = *((u16 *) &(pRSN->abyRSN[4]));
-
- if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2)
- pBSSNode->wAKMSSAuthCount = *((u16 *) &(pRSN->abyRSN[6+4*m]));
- j = 0;
- pbyOUI = &(pRSN->abyRSN[8+4*m]);
- for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(u8)); i++) {
- if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
- if ( !memcmp(pbyOUI, abyOUI8021X, 4))
- pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
- else if ( !memcmp(pbyOUI, abyOUIPSK, 4))
- pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK;
- else
- // any vendor checks here
- pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
- } else
- break;
- }
- pBSSNode->wAKMSSAuthCount = (u16)j;
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
-
- n = *((u16 *) &(pRSN->abyRSN[6+4*m]));
- if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2)
- pBSSNode->sRSNCapObj.bRSNCapExist = true;
- pBSSNode->sRSNCapObj.wRSNCap = *((u16 *) &(pRSN->abyRSN[8+4*m+4*n]));
- }
- }
- //ignore PMKID lists bcs only (Re)Assocrequest has this field
- pBSSNode->bWPA2Valid = true;
- }
-}
diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h
deleted file mode 100644
index dc505ce7a7e4..000000000000
--- a/drivers/staging/vt6656/wpa2.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wpa2.h
- *
- * Purpose: Defines the macros, types, and functions for dealing
- * with WPA2 informations.
- *
- * Author: Yiching Chen
- *
- * Date: Oct. 4, 2004
- *
- */
-
-#ifndef __WPA2_H__
-#define __WPA2_H__
-
-#include "80211mgr.h"
-#include "80211hdr.h"
-#include "bssdb.h"
-
-#define MAX_PMKID_CACHE 16
-
-typedef struct tagsPMKIDInfo {
- u8 abyBSSID[6];
- u8 abyPMKID[16];
-} PMKIDInfo, *PPMKIDInfo;
-
-typedef struct tagSPMKIDCache {
- u32 BSSIDInfoCount;
- PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
-} SPMKIDCache, *PSPMKIDCache;
-
-void WPA2_ClearRSN(PKnownBSS pBSSNode);
-void WPA2vParseRSN(PKnownBSS pBSSNode, PWLAN_IE_RSN pRSN);
-
-#endif /* __WPA2_H__ */
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
deleted file mode 100644
index 0a067151eca5..000000000000
--- a/drivers/staging/vt6656/wpactl.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: wpactl.c
- *
- * Purpose: handle wpa supplicant ioctl input/out functions
- *
- * Author: Lyndon Chen
- *
- * Date: July 28, 2006
- *
- * Functions:
- *
- * Revision History:
- *
- */
-
-#include "wpactl.h"
-#include "key.h"
-#include "mac.h"
-#include "device.h"
-#include "wmgr.h"
-#include "iocmd.h"
-#include "iowpa.h"
-#include "usbpipe.h"
-#include "rf.h"
-
-static int msglevel = MSG_LEVEL_INFO;
-
-/*
- * Description:
- * Set WPA algorithm & keys
- *
- * Parameters:
- * In:
- * pDevice -
- * param -
- * Out:
- *
- * Return Value:
- *
- */
-int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
-{
- struct viawget_wpa_param *param = ctx;
- struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
- u32 dwKeyIndex = 0;
- u8 abyKey[MAX_KEY_LEN];
- u8 abySeq[MAX_KEY_LEN];
- u64 KeyRSC;
- u8 byKeyDecMode = KEY_CTL_WEP;
- int ret = 0;
- u8 uu;
- int ii;
-
- if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
- return -EINVAL;
-
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n",
- param->u.wpa_key.alg_name);
- if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
- pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
- pDevice->bEncryptionEnable = false;
- pDevice->byKeyIndex = 0;
- pDevice->bTransmitKey = false;
- for (uu=0; uu<MAX_KEY_TABLE; uu++) {
- MACvDisableKeyEntry(pDevice, uu);
- }
- return ret;
- }
-
- if (param->u.wpa_key.key_len > sizeof(abyKey))
- return -EINVAL;
-
- memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
-
- dwKeyIndex = (u32)(param->u.wpa_key.key_index);
-
- if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
- if (dwKeyIndex > 3) {
- return -EINVAL;
- } else {
- if (param->u.wpa_key.set_tx) {
- pDevice->byKeyIndex = (u8)dwKeyIndex;
- pDevice->bTransmitKey = true;
- dwKeyIndex |= (1 << 31);
- }
- KeybSetDefaultKey( pDevice,
- &(pDevice->sKey),
- dwKeyIndex & ~(BIT30 | USE_KEYRSC),
- param->u.wpa_key.key_len,
- NULL,
- abyKey,
- KEY_CTL_WEP
- );
-
- }
- pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
- pDevice->bEncryptionEnable = true;
- return ret;
- }
-
- if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
- return -EINVAL;
-
- memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
-
- if (param->u.wpa_key.seq_len > 0) {
- for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
- if (ii < 4)
- KeyRSC |= (abySeq[ii] << (ii * 8));
- else
- KeyRSC |= (abySeq[ii] << ((ii-4) * 8));
- }
- dwKeyIndex |= 1 << 29;
- }
-
- if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n");
- return -EINVAL;
- }
-
- if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
- }
-
- if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
- pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
- }
-
- if (param->u.wpa_key.set_tx)
- dwKeyIndex |= (1 << 31);
-
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
- byKeyDecMode = KEY_CTL_CCMP;
- else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
- byKeyDecMode = KEY_CTL_TKIP;
- else
- byKeyDecMode = KEY_CTL_WEP;
-
- // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
- if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
- if (param->u.wpa_key.key_len == MAX_KEY_LEN)
- byKeyDecMode = KEY_CTL_TKIP;
- else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
- byKeyDecMode = KEY_CTL_WEP;
- else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
- byKeyDecMode = KEY_CTL_WEP;
- } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
- if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
- byKeyDecMode = KEY_CTL_WEP;
- else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
- byKeyDecMode = KEY_CTL_WEP;
- }
-
- // Check TKIP key length
- if ((byKeyDecMode == KEY_CTL_TKIP) &&
- (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
- // TKIP Key must be 256 bits
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - TKIP Key must be 256 bits!\n");
- return -EINVAL;
- }
- // Check AES key length
- if ((byKeyDecMode == KEY_CTL_CCMP) &&
- (param->u.wpa_key.key_len != AES_KEY_LEN)) {
- // AES Key must be 128 bits
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
- return -EINVAL;
- }
-
- if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
- /* if broadcast, set the key as every key entry's group key */
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
-
- if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex,
- param->u.wpa_key.key_len,
- &KeyRSC,
- (u8 *)abyKey,
- byKeyDecMode
- ) == true) &&
- (KeybSetDefaultKey(pDevice,
- &(pDevice->sKey),
- dwKeyIndex,
- param->u.wpa_key.key_len,
- &KeyRSC,
- (u8 *)abyKey,
- byKeyDecMode
- ) == true) ) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
- } else {
- return -EINVAL;
- }
- } else {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
- // BSSID not 0xffffffffffff
- // Pairwise Key can't be WEP
- if (byKeyDecMode == KEY_CTL_WEP) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
- return -EINVAL;
- }
- dwKeyIndex |= (1 << 30); // set pairwise key
- if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
- //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
- return -EINVAL;
- }
- if (KeybSetKey(pDevice, &(pDevice->sKey), &param->addr[0],
- dwKeyIndex, param->u.wpa_key.key_len,
- &KeyRSC, (u8 *)abyKey, byKeyDecMode
- ) == true) {
- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
- } else {
- // Key Table Full
- if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
- //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
- return -EINVAL;
- } else {
- // Save Key and configure just before associate/reassociate to BSSID
- // we do not implement now
- return -EINVAL;
- }
- }
- } // BSSID not 0xffffffffffff
- if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
- pDevice->byKeyIndex = (u8)param->u.wpa_key.key_index;
- pDevice->bTransmitKey = true;
- }
- pDevice->bEncryptionEnable = true;
-
- return ret;
-}
-
diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h
deleted file mode 100644
index e032a1b94ae8..000000000000
--- a/drivers/staging/vt6656/wpactl.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * File: wpactl.h
- *
- * Purpose:
- *
- * Author: Lyndon Chen
- *
- * Date: March 1, 2005
- *
- */
-
-#ifndef __WPACTL_H__
-#define __WPACTL_H__
-
-#include "device.h"
-#include "iowpa.h"
-
-//WPA related
-
-typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-
-#define AUTH_ALG_OPEN_SYSTEM 0x01
-#define AUTH_ALG_SHARED_KEY 0x02
-#define AUTH_ALG_LEAP 0x04
-
-typedef unsigned long long NDIS_802_11_KEY_RSC;
-
-int wpa_set_keys(struct vnt_private *, void *ctx);
-
-#endif /* __WPACL_H__ */
diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig
deleted file mode 100644
index db5b053d9bc2..000000000000
--- a/drivers/staging/winbond/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config W35UND
- tristate "IS89C35 WLAN USB driver"
- depends on MAC80211 && WLAN && USB
- default n
- ---help---
- This is highly experimental driver for Winbond WIFI card.
-
- Hardware is present in some Kohjinsha subnotebooks, and in some
- stand-alone USB modules. Chipset name seems to be w89c35d.
-
- Check <http://code.google.com/p/winbondport/> for new version.
diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile
deleted file mode 100644
index 081d48db04cb..000000000000
--- a/drivers/staging/winbond/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-w35und-y := \
- mds.o \
- mto.o \
- phy_calibration.o \
- reg.o \
- wb35reg.o \
- wb35rx.o \
- wb35tx.o \
- wbusb.o \
-
-
-obj-$(CONFIG_W35UND) += w35und.o
-
-
-
diff --git a/drivers/staging/winbond/TODO b/drivers/staging/winbond/TODO
deleted file mode 100644
index b4c592a96844..000000000000
--- a/drivers/staging/winbond/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
- - sparse cleanups
- - checkpatch cleanups
- - kerneldoc cleanups
- - fix severeCamelCaseInfestation
- - remove unused ioctls
- - use cfg80211 for regulatory stuff
- - fix 4k stack problems
- - fix locking problems (it's done using atomics...)
-
-Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
-Pavel Machek <pavel@ucw.cz>
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
deleted file mode 100644
index fc0ef24fad3b..000000000000
--- a/drivers/staging/winbond/core.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef __WINBOND_CORE_H
-#define __WINBOND_CORE_H
-
-#include <linux/wireless.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-
-#include "wbhal.h"
-#include "mto.h"
-
-#include "mac_structures.h"
-#include "mds_s.h"
-
-#define MAX_NUM_TX_MMPDU 2
-#define MAX_MMPDU_SIZE 1512
-#define MAX_NUM_RX_MMPDU 6
-
-struct mlme_frame {
- s8 *pMMPDU;
- u16 len;
- u8 data_type;
- u8 is_in_used;
-
- u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE];
- u8 TxMMPDUInUse[(MAX_NUM_TX_MMPDU + 3) & ~0x03];
-
- u16 wNumTxMMPDU;
- u16 wNumTxMMPDUDiscarded;
-
- u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE];
- u8 SaveRxBufSlotInUse[(MAX_NUM_RX_MMPDU + 3) & ~0x03];
-
- u16 wNumRxMMPDU;
- u16 wNumRxMMPDUDiscarded;
-
- u16 wNumRxMMPDUInMLME; /* Number of the Rx MMPDU */
- u16 reserved_1; /* in MLME. */
- /* excluding the discarded */
-};
-
-#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
-
-#define WB_MAX_LINK_NAME_LEN 40
-
-struct wbsoft_priv {
- struct wb_local_para sLocalPara; /* Myself connected
- parameters */
-
- struct mlme_frame sMlmeFrame; /* connect to peerSTA parameters */
-
- struct wb35_mto_params sMtoPara; /* MTO_struct ... */
- struct hw_data sHwData; /*For HAL */
- struct wb35_mds Mds;
-
- u32 RxByteCount;
- u32 TxByteCount;
-
- bool enabled;
-};
-
-#endif /* __WINBOND_CORE_H */
diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
deleted file mode 100644
index 8ca80ddda59a..000000000000
--- a/drivers/staging/winbond/localpara.h
+++ /dev/null
@@ -1,311 +0,0 @@
-#ifndef __WINBOND_LOCALPARA_H
-#define __WINBOND_LOCALPARA_H
-
-/*
- * =============================================================
- * LocalPara.h -
- * =============================================================
- */
-
-#include "mac_structures.h"
-
-/* Define the local ability */
-
-#define LOCAL_DEFAULT_BEACON_PERIOD 100 /* ms */
-#define LOCAL_DEFAULT_ATIM_WINDOW 0
-#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 /*
- * 0x0001: ESS
- * 0x0010: Privacy
- * 0x0020: short preamble
- * 0x0400: short slot time
- */
-#define LOCAL_DEFAULT_LISTEN_INTERVAL 5
-
-#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 /* channel 1..13 */
-#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 /* channel 36..64 */
-
-#define LOCAL_USA_24_CHANNEL_NUM 11
-#define LOCAL_USA_5_CHANNEL_NUM 12
-#define LOCAL_EUROPE_24_CHANNEL_NUM 13
-#define LOCAL_EUROPE_5_CHANNEL_NUM 19
-#define LOCAL_JAPAN_24_CHANNEL_NUM 14
-#define LOCAL_JAPAN_5_CHANNEL_NUM 11
-#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14
-#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 /* not include 165 */
-
-#define psLOCAL (&(adapter->sLocalPara))
-
-#define MODE_802_11_BG 0
-#define MODE_802_11_A 1
-#define MODE_802_11_ABG 2
-#define MODE_802_11_BG_IBSS 3
-#define MODE_802_11_B 4
-#define MODE_AUTO 255
-
-#define BAND_TYPE_DSSS 0
-#define BAND_TYPE_OFDM_24 1
-#define BAND_TYPE_OFDM_5 2
-
-/* refer Bitmap2RateValue table */
-
-/* the bitmap value of all the H/W supported rates: */
-/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
-#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66
-/* the bitmap value of all the H/W supported rates except to non-OFDM rates: */
-/* 6, 9, 12, 18, 24, 36, 48, 54 */
-#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240
-#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826
-#define LOCAL_11B_BASIC_RATE_BITMAP 0x826
-#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826
-#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 /* 1, 2, 5.5, 11 */
-#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 /* 6, 9, 12, 18,
- * 24, 36, 48, 54
- */
-#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 /* 6, 12, 24 */
-#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 /* 9, 18, 36,
- * 48, 54
- */
-
-
-#define PWR_ACTIVE 0
-#define PWR_SAVE 1
-#define PWR_TX_IDLE_CYCLE 6
-
-/* bPreambleMode and bSlotTimeMode */
-#define AUTO_MODE 0
-#define LONG_MODE 1
-
-/* Region definition */
-#define REGION_AUTO 0xff
-#define REGION_UNKNOWN 0
-#define REGION_EUROPE 1 /* ETSI */
-#define REGION_JAPAN 2 /* MKK */
-#define REGION_USA 3 /* FCC */
-#define REGION_FRANCE 4 /* FRANCE */
-#define REGION_SPAIN 5 /* SPAIN */
-#define REGION_ISRAEL 6 /* ISRAEL */
-
-#define MAX_BSS_DESCRIPT_ELEMENT 32
-#define MAX_PMKID_CandidateList 16
-
-/*
- * High byte : Event number, low byte : reason
- * Event definition
- * -- SME/MLME event
- */
-#define EVENT_RCV_DEAUTH 0x0100
-#define EVENT_JOIN_FAIL 0x0200
-#define EVENT_AUTH_FAIL 0x0300
-#define EVENT_ASSOC_FAIL 0x0400
-#define EVENT_LOST_SIGNAL 0x0500
-#define EVENT_BSS_DESCRIPT_LACK 0x0600
-#define EVENT_COUNTERMEASURE 0x0700
-#define EVENT_JOIN_FILTER 0x0800
-/* -- TX/RX event */
-#define EVENT_RX_BUFF_UNAVAILABLE 0x4100
-
-#define EVENT_CONNECT 0x8100
-#define EVENT_DISCONNECT 0x8200
-#define EVENT_SCAN_REQ 0x8300
-
-/* Reason of Event */
-#define EVENT_REASON_FILTER_BASIC_RATE 0x0001
-#define EVENT_REASON_FILTER_PRIVACY 0x0002
-#define EVENT_REASON_FILTER_AUTH_MODE 0x0003
-#define EVENT_REASON_TIMEOUT 0x00ff
-
-/* Due to[E id][Length][OUI][Data] may be 257 bytes */
-#define MAX_IE_APPEND_SIZE (256 + 4)
-
-struct chan_info {
- u8 band;
- u8 ChanNo;
-};
-
-struct radio_off {
- u8 boHwRadioOff;
- u8 boSwRadioOff;
-};
-
-struct wb_local_para {
- /* read from EPROM, manufacture set for each NetCard */
- u8 PermanentAddress[MAC_ADDR_LENGTH + 2];
- /* the driver will use this one actually. */
- u8 ThisMacAddress[MAC_ADDR_LENGTH + 2];
- u32 MTUsize; /* Ind to Uplayer, Max transmission unit size */
- u8 region_INF; /* region setting from INF */
- u8 region; /* real region setting of the device */
- u8 Reserved_1[2];
-
- /* power-save variables */
- u8 iPowerSaveMode; /* 0 indicates on, 1 indicates off */
- u8 ATIMmode;
- u8 ExcludeUnencrypted;
- /* Unit time count for the decision to enter PS mode */
- u16 CheckCountForPS;
- u8 boHasTxActivity;/* tx activity has occurred */
- u8 boMacPsValid; /* Power save mode obtained
- * from H/W is valid or not
- */
-
- /* Rate */
- u8 TxRateMode; /*
- * Initial, input from Registry,
- * may be updated by GUI
- * Tx Rate Mode: auto(DTO on), max, 1M, 2M, ..
- */
- u8 CurrentTxRate; /* The current Tx rate */
- u8 CurrentTxRateForMng; /*
- * The current Tx rate for management
- * frames. It will be decided before
- * connection succeeds.
- */
- u8 CurrentTxFallbackRate;
-
- /* for Rate handler */
- u8 BRateSet[32]; /* basic rate set */
- u8 SRateSet[32]; /* support rate set */
-
- u8 NumOfBRate;
- u8 NumOfSRate;
- u8 NumOfDsssRateInSRate; /* number of DSSS rates in
- * supported rate set
- */
- u8 reserved1;
-
- u32 dwBasicRateBitmap; /* bit map of basic rates */
-
- u32 dwSupportRateBitmap; /* bit map of all support rates
- * including basic and operational
- * rates
- */
-
-
- /* For SME/MLME handler */
-
- u16 wOldSTAindex; /* valid when boHandover=TRUE,
- * store old connected STA index
- */
- u16 wConnectedSTAindex; /* Index of peerly connected AP or
- * IBSS in the descriptionset.
- */
- u16 Association_ID; /* The Association ID in the
- * (Re)Association Response frame.
- */
- u16 ListenInterval; /* The listen interval when SME invoking
- * MLME_ (Re)Associate_Request().
- */
-
- struct radio_off RadioOffStatus;
- u8 Reserved0[2];
- u8 boMsRadioOff; /* Ndis demands to be true when set
- * Disassoc. OID and be false when
- * set SSID OID.
- */
- u8 bAntennaNo; /* which antenna */
- u8 bConnectFlag; /* the connect status flag for
- * roaming task
- */
-
- u8 RoamStatus;
- u8 reserved7[3];
-
- struct chan_info CurrentChan; /* Current channel no. and channel band.
- * It may be changed by scanning.
- */
- u8 boHandover; /* Roaming, Handover to other AP. */
- u8 boCCAbusy;
-
- u16 CWMax; /* It may not be the real value
- * that H/W used
- */
- u8 CWMin; /* 255: set according to 802.11 spec. */
- u8 reserved2;
-
- /* 11G: */
- u8 bMacOperationMode; /* operation in 802.11b or 802.11g */
- u8 bSlotTimeMode; /* AUTO, s32 */
- u8 bPreambleMode; /* AUTO, s32 */
- u8 boNonERPpresent;
-
- u8 boProtectMechanism; /* H/W will take the necessary action
- * based on this variable
- */
- u8 boShortPreamble; /* Same here */
- u8 boShortSlotTime; /* Same here */
- u8 reserved_3;
-
- u32 RSN_IE_Bitmap;
- u32 RSN_OUI_Type;
-
- /* For the BSSID */
- u8 HwBssid[MAC_ADDR_LENGTH + 2];
- u32 HwBssidValid;
-
- /* For scan list */
- u8 BssListCount; /* Total count of valid
- * descriptor indexes
- */
- u8 boReceiveUncorrectInfo; /* important settings in beacon/probe
- * resp. have been changed
- */
- u8 NoOfJoinerInIbss;
- u8 reserved_4;
-
- /* Store the valid descriptor indexes obtained from scannings */
- u8 BssListIndex[(MAX_BSS_DESCRIPT_ELEMENT + 3) & ~0x03];
- /*
- * Save the BssDescriptor index in this IBSS.
- * The index 0 is local descriptor (psLOCAL->wConnectedSTAindex).
- * If CONNECTED : NoOfJoinerInIbss >= 2
- * else : NoOfJoinerInIbss <= 1
- */
- u8 JoinerInIbss[(MAX_BSS_DESCRIPT_ELEMENT + 3) & ~0x03];
-
- /* General Statistics, count at Rx_handler or
- * Tx_callback interrupt handler
- */
- u64 GS_XMIT_OK; /* Good Frames Transmitted */
- u64 GS_RCV_OK; /* Good Frames Received */
- u32 GS_RCV_ERROR; /* Frames received with crc error */
- u32 GS_XMIT_ERROR; /* Bad Frames Transmitted */
- u32 GS_RCV_NO_BUFFER; /* Receive Buffer underrun */
- u32 GS_XMIT_ONE_COLLISION; /* one collision */
- u32 GS_XMIT_MORE_COLLISIONS;/* more collisions */
-
- /*
- * ================================================================
- * Statistics (no matter whether it had done successfully) -wkchen
- * ================================================================
- */
- u32 _NumRxMSDU;
- u32 _NumTxMSDU;
- u32 _dot11WEPExcludedCount;
- u32 _dot11WEPUndecryptableCount;
- u32 _dot11FrameDuplicateCount;
-
- struct chan_info IbssChanSetting; /* 2B. Start IBSS Channel
- * setting by registry or
- * WWU.
- */
- u8 reserved_5[2]; /* It may not be used after
- * considering RF type, region
- * and modulation type.
- */
-
- u8 reserved_6[2]; /* two variables are for wep
- * key error detection
- */
- u32 bWepKeyError;
- u32 bToSelfPacketReceived;
- u32 WepKeyDetectTimerCount;
-
- u16 SignalLostTh;
- u16 SignalRoamTh;
-
- u8 IE_Append_data[MAX_IE_APPEND_SIZE];
- u16 IE_Append_size;
- u16 reserved_7;
-};
-
-#endif
diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h
deleted file mode 100644
index 76c63c74d50c..000000000000
--- a/drivers/staging/winbond/mac_structures.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-// MAC_Structures.h
-//
-// This file contains the definitions and data structures used by SW-MAC.
-//
-// Revision Histoy
-//=================
-// 0.1 2002 UN00
-// 0.2 20021004 PD43 CCLiu6
-// 20021018 PD43 CCLiu6
-// Add enum_TxRate type
-// Modify enum_STAState type
-// 0.3 20021023 PE23 CYLiu update MAC session struct
-// 20021108
-// 20021122 PD43 Austin
-// Deleted some unused.
-// 20021129 PD43 Austin
-// 20030617 increase the 802.11g definition
-//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-#ifndef _MAC_Structures_H_
-#define _MAC_Structures_H_
-
-#define MAC_ADDR_LENGTH 6
-
-/* ========================================================
-// 802.11 Frame define
-//----- */
-#define DOT_11_MAC_HEADER_SIZE 24
-#define DOT_11_SNAP_SIZE 6
-#define DOT_11_DURATION_OFFSET 2
-/* Sequence control offset */
-#define DOT_11_SEQUENCE_OFFSET 22
-/* The start offset of 802.11 Frame// */
-#define DOT_11_TYPE_OFFSET 30
-#define DOT_11_DATA_OFFSET 24
-#define DOT_11_DA_OFFSET 4
-
-#define MAX_ETHERNET_PACKET_SIZE 1514
-
-/* ----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */
-#define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00
-#define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10
-#define MAC_SUBTYPE_MNGMNT_REASSOC_REQUEST 0x20
-#define MAC_SUBTYPE_MNGMNT_REASSOC_RESPONSE 0x30
-#define MAC_SUBTYPE_MNGMNT_PROBE_REQUEST 0x40
-#define MAC_SUBTYPE_MNGMNT_PROBE_RESPONSE 0x50
-#define MAC_SUBTYPE_MNGMNT_BEACON 0x80
-#define MAC_SUBTYPE_MNGMNT_ATIM 0x90
-#define MAC_SUBTYPE_MNGMNT_DISASSOCIATION 0xA0
-#define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0
-#define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0
-
-#define RATE_AUTO 0
-#define RATE_1M 2
-#define RATE_2M 4
-#define RATE_5dot5M 11
-#define RATE_6M 12
-#define RATE_9M 18
-#define RATE_11M 22
-#define RATE_12M 24
-#define RATE_18M 36
-#define RATE_22M 44
-#define RATE_24M 48
-#define RATE_33M 66
-#define RATE_36M 72
-#define RATE_48M 96
-#define RATE_54M 108
-#define RATE_MAX 255
-
-#endif /* _MAC_Structure_H_ */
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
deleted file mode 100644
index aef0855f4c68..000000000000
--- a/drivers/staging/winbond/mds.c
+++ /dev/null
@@ -1,650 +0,0 @@
-#include "mds_f.h"
-#include "mto.h"
-#include "wbhal.h"
-#include "wb35tx_f.h"
-
-unsigned char
-Mds_initial(struct wbsoft_priv *adapter)
-{
- struct wb35_mds *pMds = &adapter->Mds;
-
- pMds->TxPause = false;
- pMds->TxRTSThreshold = DEFAULT_RTSThreshold;
- pMds->TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
-
- return hal_get_tx_buffer(&adapter->sHwData, &pMds->pTxBuffer);
-}
-
-static void Mds_DurationSet(struct wbsoft_priv *adapter,
- struct wb35_descriptor *pDes, u8 *buffer)
-{
- struct T00_descriptor *pT00;
- struct T01_descriptor *pT01;
- u16 Duration, NextBodyLen, OffsetSize;
- u8 Rate, i;
- unsigned char CTS_on = false, RTS_on = false;
- struct T00_descriptor *pNextT00;
- u16 BodyLen = 0;
- unsigned char boGroupAddr = false;
-
- OffsetSize = pDes->FragmentThreshold + 32 + 3;
- OffsetSize &= ~0x03;
- Rate = pDes->TxRate >> 1;
- if (!Rate)
- Rate = 1;
-
- pT00 = (struct T00_descriptor *)buffer;
- pT01 = (struct T01_descriptor *)(buffer+4);
- pNextT00 = (struct T00_descriptor *)(buffer+OffsetSize);
-
- if (buffer[DOT_11_DA_OFFSET+8] & 0x1) /* +8 for USB hdr */
- boGroupAddr = true;
-
- /******************************************
- * Set RTS/CTS mechanism
- ******************************************/
- if (!boGroupAddr) {
- /* NOTE : If the protection mode is enabled and the MSDU will
- * be fragmented, the tx rates of MPDUs will all be DSSS
- * rates. So it will not use CTS-to-self in this case.
- * CTS-To-self will only be used when without
- * fragmentation. -- 20050112 */
- BodyLen = (u16)pT00->T00_frame_length; /* include 802.11 header */
- BodyLen += 4; /* CRC */
-
- if (BodyLen >= CURRENT_RTS_THRESHOLD)
- RTS_on = true; /* Using RTS */
- else {
- if (pT01->T01_modulation_type) { /* Is using OFDM */
- /* Is using protect */
- if (CURRENT_PROTECT_MECHANISM)
- CTS_on = true; /* Using CTS */
- }
- }
- }
-
- if (RTS_on || CTS_on) {
- if (pT01->T01_modulation_type) { /* Is using OFDM */
- /* CTS duration
- * 2 SIFS + DATA transmit time + 1 ACK
- * ACK Rate : 24 Mega bps
- * ACK frame length = 14 bytes */
- Duration = 2*DEFAULT_SIFSTIME +
- 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
- ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym +
- ((112 + 22 + 95)/96)*Tsym;
- } else { /* DSSS */
- /* CTS duration
- * 2 SIFS + DATA transmit time + 1 ACK
- * Rate : ?? Mega bps
- * ACK frame length = 14 bytes */
- if (pT01->T01_plcp_header_length) /* long preamble */
- Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
- else
- Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
-
- Duration += (((BodyLen + 14)*8 + Rate-1) / Rate +
- DEFAULT_SIFSTIME*2);
- }
-
- if (RTS_on) {
- if (pT01->T01_modulation_type) { /* Is using OFDM */
- /* CTS + 1 SIFS + CTS duration
- * CTS Rate : 24 Mega bps
- * CTS frame length = 14 bytes */
- Duration += (DEFAULT_SIFSTIME +
- PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
- ((112 + 22 + 95)/96)*Tsym);
- } else {
- /* CTS + 1 SIFS + CTS duration
- * CTS Rate : ?? Mega bps
- * CTS frame length = 14 bytes
- */
- /* long preamble */
- if (pT01->T01_plcp_header_length)
- Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
- else
- Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
-
- Duration += (((112 + Rate-1) / Rate) +
- DEFAULT_SIFSTIME);
- }
- }
-
- /* Set the value into USB descriptor */
- pT01->T01_add_rts = RTS_on ? 1 : 0;
- pT01->T01_add_cts = CTS_on ? 1 : 0;
- pT01->T01_rts_cts_duration = Duration;
- }
-
- /******************************************
- * Fill the more fragment descriptor
- ******************************************/
- if (boGroupAddr)
- Duration = 0;
- else {
- for (i = pDes->FragmentCount-1; i > 0; i--) {
- NextBodyLen = (u16)pNextT00->T00_frame_length;
- NextBodyLen += 4; /* CRC */
-
- if (pT01->T01_modulation_type) {
- /* OFDM
- * data transmit time + 3 SIFS + 2 ACK
- * Rate : ??Mega bps
- * ACK frame length = 14 bytes, tx rate = 24M */
- Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION * 3;
- Duration += (((NextBodyLen*8 + 22 + Rate*4 - 1)
- /(Rate*4)) * Tsym +
- (((2*14)*8 + 22 + 95)/96)*Tsym +
- DEFAULT_SIFSTIME*3);
- } else {
- /* DSSS
- * data transmit time + 2 ACK + 3 SIFS
- * Rate : ??Mega bps
- * ACK frame length = 14 bytes
- * TODO : */
- if (pT01->T01_plcp_header_length) /* long preamble */
- Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
- else
- Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
-
- Duration += (((NextBodyLen + (2*14))*8
- + Rate-1) / Rate +
- DEFAULT_SIFSTIME*3);
- }
- /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
- ((u16 *)buffer)[5] = cpu_to_le16(Duration);
-
- /* ----20061009 add by anson's endian */
- pNextT00->value = cpu_to_le32(pNextT00->value);
- pT01->value = cpu_to_le32(pT01->value);
- /* ----end 20061009 add by anson's endian */
-
- buffer += OffsetSize;
- pT01 = (struct T01_descriptor *)(buffer+4);
- /* The last fragment will not have the next fragment */
- if (i != 1)
- pNextT00 = (struct T00_descriptor *)(buffer+OffsetSize);
- }
-
- /*******************************************
- * Fill the last fragment descriptor
- *******************************************/
- if (pT01->T01_modulation_type) {
- /* OFDM
- * 1 SIFS + 1 ACK
- * Rate : 24 Mega bps
- * ACK frame length = 14 bytes */
- Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION;
- /* The Tx rate of ACK use 24M */
- Duration += (((112 + 22 + 95)/96)*Tsym +
- DEFAULT_SIFSTIME);
- } else {
- /* DSSS
- * 1 ACK + 1 SIFS
- * Rate : ?? Mega bps
- * ACK frame length = 14 bytes(112 bits) */
- if (pT01->T01_plcp_header_length) /* long preamble */
- Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
- else
- Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
-
- Duration += ((112 + Rate-1)/Rate + DEFAULT_SIFSTIME);
- }
- }
-
- /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */
- ((u16 *)buffer)[5] = cpu_to_le16(Duration);
- pT00->value = cpu_to_le32(pT00->value);
- pT01->value = cpu_to_le32(pT01->value);
- /* --end 20061009 add */
-
-}
-
-/* The function return the 4n size of usb pk */
-static u16 Mds_BodyCopy(struct wbsoft_priv *adapter,
- struct wb35_descriptor *pDes, u8 *TargetBuffer)
-{
- struct T00_descriptor *pT00;
- struct wb35_mds *pMds = &adapter->Mds;
- u8 *buffer;
- u8 *src_buffer;
- u8 *pctmp;
- u16 Size = 0;
- u16 SizeLeft, CopySize, CopyLeft, stmp;
- u8 buf_index, FragmentCount = 0;
-
-
- /* Copy fragment body */
- buffer = TargetBuffer; /* shift 8B usb + 24B 802.11 */
- SizeLeft = pDes->buffer_total_size;
- buf_index = pDes->buffer_start_index;
-
- pT00 = (struct T00_descriptor *)buffer;
- while (SizeLeft) {
- pT00 = (struct T00_descriptor *)buffer;
- CopySize = SizeLeft;
- if (SizeLeft > pDes->FragmentThreshold) {
- CopySize = pDes->FragmentThreshold;
- /* Set USB length */
- pT00->T00_frame_length = 24 + CopySize;
- } else /* Set USB length */
- pT00->T00_frame_length = 24 + SizeLeft;
-
- SizeLeft -= CopySize;
-
- /* 1 Byte operation */
- pctmp = (u8 *)(buffer + 8 + DOT_11_SEQUENCE_OFFSET);
- *pctmp &= 0xf0;
- *pctmp |= FragmentCount; /* 931130.5.m */
- if (!FragmentCount)
- pT00->T00_first_mpdu = 1;
-
- buffer += 32; /* 8B usb + 24B 802.11 header */
- Size += 32;
-
- /* Copy into buffer */
- stmp = CopySize + 3;
- stmp &= ~0x03; /* 4n Alignment */
- Size += stmp; /* Current 4n offset of mpdu */
-
- while (CopySize) {
- /* Copy body */
- src_buffer = pDes->buffer_address[buf_index];
- CopyLeft = CopySize;
- if (CopySize >= pDes->buffer_size[buf_index]) {
- CopyLeft = pDes->buffer_size[buf_index];
-
- /* Get the next buffer of descriptor */
- buf_index++;
- buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX;
- } else {
- u8 *pctmp = pDes->buffer_address[buf_index];
- pctmp += CopySize;
- pDes->buffer_address[buf_index] = pctmp;
- pDes->buffer_size[buf_index] -= CopySize;
- }
-
- memcpy(buffer, src_buffer, CopyLeft);
- buffer += CopyLeft;
- CopySize -= CopyLeft;
- }
-
- /* 931130.5.n */
- if (pMds->MicAdd) {
- if (!SizeLeft) {
- pMds->MicWriteAddress[pMds->MicWriteIndex] =
- buffer - pMds->MicAdd;
- pMds->MicWriteSize[pMds->MicWriteIndex] =
- pMds->MicAdd;
- pMds->MicAdd = 0;
- } else if (SizeLeft < 8) { /* 931130.5.p */
- pMds->MicAdd = SizeLeft;
- pMds->MicWriteAddress[pMds->MicWriteIndex] =
- buffer - (8 - SizeLeft);
- pMds->MicWriteSize[pMds->MicWriteIndex] =
- 8 - SizeLeft;
- pMds->MicWriteIndex++;
- }
- }
-
- /* Does it need to generate the new header for next mpdu? */
- if (SizeLeft) {
- /* Get the next 4n start address */
- buffer = TargetBuffer + Size;
- /* Copy 8B USB +24B 802.11 */
- memcpy(buffer, TargetBuffer, 32);
- pT00 = (struct T00_descriptor *)buffer;
- pT00->T00_first_mpdu = 0;
- }
-
- FragmentCount++;
- }
-
- pT00->T00_last_mpdu = 1;
- pT00->T00_IsLastMpdu = 1;
- buffer = (u8 *)pT00 + 8; /* +8 for USB hdr */
- buffer[1] &= ~0x04; /* Clear more frag bit of 802.11 frame control */
- /* Update the correct fragment number */
- pDes->FragmentCount = FragmentCount;
- return Size;
-}
-
-static void Mds_HeaderCopy(struct wbsoft_priv *adapter,
- struct wb35_descriptor *pDes, u8 *TargetBuffer)
-{
- struct wb35_mds *pMds = &adapter->Mds;
- u8 *src_buffer = pDes->buffer_address[0]; /* 931130.5.g */
- struct T00_descriptor *pT00;
- struct T01_descriptor *pT01;
- u16 stmp;
- u8 i, ctmp1, ctmp2, ctmpf;
- u16 FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
-
-
- stmp = pDes->buffer_total_size;
- /*
- * Set USB header 8 byte
- */
- pT00 = (struct T00_descriptor *)TargetBuffer;
- TargetBuffer += 4;
- pT01 = (struct T01_descriptor *)TargetBuffer;
- TargetBuffer += 4;
-
- pT00->value = 0; /* Clear */
- pT01->value = 0; /* Clear */
-
- pT00->T00_tx_packet_id = pDes->Descriptor_ID; /* Set packet ID */
- pT00->T00_header_length = 24; /* Set header length */
- pT01->T01_retry_abort_enable = 1; /* 921013 931130.5.h */
-
- /* Key ID setup */
- pT01->T01_wep_id = 0;
-
- FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; /* Do not fragment */
- /* Copy full data, the 1'st buffer contain all the data 931130.5.j */
- /* Copy header */
- memcpy(TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE);
- pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE;
- pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE;
- pDes->buffer_size[0] = pDes->buffer_total_size;
-
- /* Set fragment threshold */
- FragmentThreshold -= (DOT_11_MAC_HEADER_SIZE + 4);
- pDes->FragmentThreshold = FragmentThreshold;
-
- /* Set more frag bit */
- TargetBuffer[1] |= 0x04; /* Set more frag bit */
-
- /*
- * Set tx rate
- */
- stmp = *(u16 *)(TargetBuffer+30); /* 2n alignment address */
-
- /* Use basic rate */
- ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG;
-
- pDes->TxRate = ctmp1;
- pr_debug("Tx rate =%x\n", ctmp1);
-
- pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
-
- for (i = 0; i < 2; i++) {
- if (i == 1)
- ctmp1 = ctmpf;
- /* backup the ta rate and fall back rate */
- pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1;
-
- if (ctmp1 == 108)
- ctmp2 = 7;
- else if (ctmp1 == 96)
- ctmp2 = 6; /* Rate convert for USB */
- else if (ctmp1 == 72)
- ctmp2 = 5;
- else if (ctmp1 == 48)
- ctmp2 = 4;
- else if (ctmp1 == 36)
- ctmp2 = 3;
- else if (ctmp1 == 24)
- ctmp2 = 2;
- else if (ctmp1 == 18)
- ctmp2 = 1;
- else if (ctmp1 == 12)
- ctmp2 = 0;
- else if (ctmp1 == 22)
- ctmp2 = 3;
- else if (ctmp1 == 11)
- ctmp2 = 2;
- else if (ctmp1 == 4)
- ctmp2 = 1;
- else
- ctmp2 = 0; /* if( ctmp1 == 2 ) or default */
-
- if (i == 0)
- pT01->T01_transmit_rate = ctmp2;
- else
- pT01->T01_fall_back_rate = ctmp2;
- }
-
- /*
- * Set preamble type
- */
- /* RATE_1M */
- if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0))
- pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG;
- else
- pDes->PreambleMode = CURRENT_PREAMBLE_MODE;
- pT01->T01_plcp_header_length = pDes->PreambleMode; /* Set preamble */
-
-}
-
-static void MLME_GetNextPacket(struct wbsoft_priv *adapter,
- struct wb35_descriptor *desc)
-{
- desc->InternalUsed = desc->buffer_start_index + desc->buffer_number;
- desc->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX;
- desc->buffer_address[desc->InternalUsed] = adapter->sMlmeFrame.pMMPDU;
- desc->buffer_size[desc->InternalUsed] = adapter->sMlmeFrame.len;
- desc->buffer_total_size += adapter->sMlmeFrame.len;
- desc->buffer_number++;
- desc->Type = adapter->sMlmeFrame.data_type;
-}
-
-static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData)
-{
- int i;
-
- /* Reclaim the data buffer */
- for (i = 0; i < MAX_NUM_TX_MMPDU; i++) {
- if (pData == (s8 *)&(adapter->sMlmeFrame.TxMMPDU[i]))
- break;
- }
- if (adapter->sMlmeFrame.TxMMPDUInUse[i])
- adapter->sMlmeFrame.TxMMPDUInUse[i] = false;
- else {
- /* Something wrong
- PD43 Add debug code here??? */
- }
-}
-
-static void MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID,
- unsigned char SendOK)
-{
- /* Reclaim the data buffer */
- adapter->sMlmeFrame.len = 0;
- MLMEfreeMMPDUBuffer(adapter, adapter->sMlmeFrame.pMMPDU);
-
- /* Return resource */
- adapter->sMlmeFrame.is_in_used = PACKET_FREE_TO_USE;
-}
-
-void
-Mds_Tx(struct wbsoft_priv *adapter)
-{
- struct hw_data *pHwData = &adapter->sHwData;
- struct wb35_mds *pMds = &adapter->Mds;
- struct wb35_descriptor TxDes;
- struct wb35_descriptor *pTxDes = &TxDes;
- u8 *XmitBufAddress;
- u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
- u8 FillIndex, TxDesIndex, FragmentCount, FillCount;
- unsigned char BufferFilled = false;
-
-
- if (pMds->TxPause)
- return;
- if (!hal_driver_init_OK(pHwData))
- return;
-
- /* Only one thread can be run here */
- if (atomic_inc_return(&pMds->TxThreadCount) != 1)
- goto cleanup;
-
- /* Start to fill the data */
- do {
- FillIndex = pMds->TxFillIndex;
- /* Is owned by software 0:Yes 1:No */
- if (pMds->TxOwner[FillIndex]) {
- pr_debug("[Mds_Tx] Tx Owner is H/W.\n");
- break;
- }
-
- /* Get buffer */
- XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex);
- XmitBufSize = 0;
- FillCount = 0;
- do {
- PacketSize = adapter->sMlmeFrame.len;
- if (!PacketSize)
- break;
-
- /* For Check the buffer resource */
- FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
- /* 931130.5.b */
- FragmentCount = PacketSize/FragmentThreshold + 1;
- /* 931130.5.c 8:MIC */
- stmp = PacketSize + FragmentCount*32 + 8;
- if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER)
- break; /* buffer is not enough */
-
- /*
- * Start transmitting
- */
- BufferFilled = true;
-
- /* Leaves first u8 intact */
- memset((u8 *)pTxDes + 1, 0, sizeof(struct wb35_descriptor) - 1);
-
- TxDesIndex = pMds->TxDesIndex; /* Get the current ID */
- pTxDes->Descriptor_ID = TxDesIndex;
- /* Storing the information of source coming from */
- pMds->TxDesFrom[TxDesIndex] = 2;
- pMds->TxDesIndex++;
- pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR;
-
- MLME_GetNextPacket(adapter, pTxDes);
-
- /*
- * Copy header. 8byte USB + 24byte 802.11Hdr.
- * Set TxRate, Preamble type
- */
- Mds_HeaderCopy(adapter, pTxDes, XmitBufAddress);
-
- /* For speed up Key setting */
- if (pTxDes->EapFix) {
- pr_debug("35: EPA 4th frame detected. Size = %d\n",
- PacketSize);
- pHwData->IsKeyPreSet = 1;
- }
-
- /* Copy (fragment) frame body, and set USB, 802.11 hdr flag */
- CurrentSize = Mds_BodyCopy(adapter, pTxDes, XmitBufAddress);
-
- /* Set RTS/CTS and Normal duration field into buffer */
- Mds_DurationSet(adapter, pTxDes, XmitBufAddress);
-
- /* Shift to the next address */
- XmitBufSize += CurrentSize;
- XmitBufAddress += CurrentSize;
-
- /* Get packet to transmit completed,
- * 1:TESTSTA 2:MLME 3: Ndis data
- */
- MLME_SendComplete(adapter, 0, true);
-
- /* Software TSC count 20060214 */
- pMds->TxTsc++;
- if (pMds->TxTsc == 0)
- pMds->TxTsc_2++;
-
- FillCount++; /* 20060928 */
- /*
- * End of multiple MSDU copy loop.
- * false = single
- * true = multiple sending
- */
- } while (HAL_USB_MODE_BURST(pHwData));
-
- /* Move to the next one, if necessary */
- if (BufferFilled) {
- /* size setting */
- pMds->TxBufferSize[FillIndex] = XmitBufSize;
-
- /* 20060928 set Tx count */
- pMds->TxCountInBuffer[FillIndex] = FillCount;
-
- /* Set owner flag */
- pMds->TxOwner[FillIndex] = 1;
-
- pMds->TxFillIndex++;
- pMds->TxFillIndex %= MAX_USB_TX_BUFFER_NUMBER;
- BufferFilled = false;
- } else
- break;
-
- if (!PacketSize) /* No more pk for transmitting */
- break;
-
- } while (true);
-
- /*
- * Start to send by lower module
- */
- if (!pHwData->IsKeyPreSet)
- Wb35Tx_start(adapter);
-
-cleanup:
- atomic_dec(&pMds->TxThreadCount);
-}
-
-void
-Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pT02)
-{
- struct wb35_mds *pMds = &adapter->Mds;
- struct hw_data *pHwData = &adapter->sHwData;
- u8 PacketId = (u8)pT02->T02_Tx_PktID;
- unsigned char SendOK = true;
- u8 RetryCount, TxRate;
-
- if (pT02->T02_IgnoreResult) /* Don't care about the result */
- return;
- if (pT02->T02_IsLastMpdu) {
- /* TODO: DTO -- get the retry count and fragment count */
- /* Tx rate */
- TxRate = pMds->TxRate[PacketId][0];
- RetryCount = (u8)pT02->T02_MPDU_Cnt;
- if (pT02->value & FLAG_ERROR_TX_MASK) {
- SendOK = false;
-
- if (pT02->T02_transmit_abort || pT02->T02_out_of_MaxTxMSDULiftTime) {
- /* retry error */
- pHwData->dto_tx_retry_count += (RetryCount+1);
- /* [for tx debug] */
- if (RetryCount < 7)
- pHwData->tx_retry_count[RetryCount] += RetryCount;
- else
- pHwData->tx_retry_count[7] += RetryCount;
- pr_debug("dto_tx_retry_count =%d\n",
- pHwData->dto_tx_retry_count);
- MTO_SetTxCount(adapter, TxRate, RetryCount);
- }
- pHwData->dto_tx_frag_count += (RetryCount+1);
-
- /* [for tx debug] */
- if (pT02->T02_transmit_abort_due_to_TBTT)
- pHwData->tx_TBTT_start_count++;
- if (pT02->T02_transmit_without_encryption_due_to_wep_on_false)
- pHwData->tx_WepOn_false_count++;
- if (pT02->T02_discard_due_to_null_wep_key)
- pHwData->tx_Null_key_count++;
- } else {
- if (pT02->T02_effective_transmission_rate)
- pHwData->tx_ETR_count++;
- MTO_SetTxCount(adapter, TxRate, RetryCount);
- }
-
- /* Clear send result buffer */
- pMds->TxResult[PacketId] = 0;
- } else
- pMds->TxResult[PacketId] |= ((u16)(pT02->value & 0x0ffff));
-}
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
deleted file mode 100644
index 159b2eb366e8..000000000000
--- a/drivers/staging/winbond/mds_f.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __WINBOND_MDS_F_H
-#define __WINBOND_MDS_F_H
-
-#include "wbhal.h"
-#include "core.h"
-
-unsigned char Mds_initial(struct wbsoft_priv *adapter);
-void Mds_Tx(struct wbsoft_priv *adapter);
-void Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pt02);
-void Mds_MpduProcess(struct wbsoft_priv *adapter,
- struct wb35_descriptor *prxdes);
-
-/* For data frame sending */
-u16 MDS_GetPacketSize(struct wbsoft_priv *adapter);
-void MDS_GetNextPacket(struct wbsoft_priv *adapter,
- struct wb35_descriptor *pdes);
-void MDS_GetNextPacketComplete(struct wbsoft_priv *adapter,
- struct wb35_descriptor *pdes);
-void MDS_SendResult(struct wbsoft_priv *adapter, u8 packetid,
- unsigned char sendok);
-
-#endif
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
deleted file mode 100644
index 2972d66c9436..000000000000
--- a/drivers/staging/winbond/mds_s.h
+++ /dev/null
@@ -1,130 +0,0 @@
-#ifndef __WINBOND_MDS_H
-#define __WINBOND_MDS_H
-
-#include <linux/timer.h>
-#include <linux/types.h>
-#include <linux/atomic.h>
-
-#include "localpara.h"
-#include "mac_structures.h"
-
-/* Preamble_Type, see <SFS-802.11G-MIB-203> */
-enum {
- WLAN_PREAMBLE_TYPE_SHORT,
- WLAN_PREAMBLE_TYPE_LONG,
-};
-
-/*****************************************************************************/
-#define MAX_USB_TX_DESCRIPTOR 15 /* IS89C35 ability */
-#define MAX_USB_TX_BUFFER_NUMBER 4 /* Virtual pre-buffer number of MAX_USB_TX_BUFFER */
-#define MAX_USB_TX_BUFFER 4096 /* IS89C35 ability 4n alignment is required for hardware */
-
-#define AUTH_REQUEST_PAIRWISE_ERROR 0 /* _F flag setting */
-#define AUTH_REQUEST_GROUP_ERROR 1 /* _F flag setting */
-
-#define CURRENT_FRAGMENT_THRESHOLD (adapter->Mds.TxFragmentThreshold & ~0x1)
-#define CURRENT_PREAMBLE_MODE (psLOCAL->boShortPreamble ? WLAN_PREAMBLE_TYPE_SHORT : WLAN_PREAMBLE_TYPE_LONG)
-#define CURRENT_TX_RATE_FOR_MNG (adapter->sLocalPara.CurrentTxRateForMng)
-#define CURRENT_PROTECT_MECHANISM (psLOCAL->boProtectMechanism)
-#define CURRENT_RTS_THRESHOLD (adapter->Mds.TxRTSThreshold)
-
-#define MIB_GS_XMIT_OK_INC (adapter->sLocalPara.GS_XMIT_OK++)
-#define MIB_GS_RCV_OK_INC (adapter->sLocalPara.GS_RCV_OK++)
-#define MIB_GS_XMIT_ERROR_INC (adapter->sLocalPara.GS_XMIT_ERROR)
-
-/* ---------- TX ----------------------------------- */
-#define ETHERNET_TX_DESCRIPTORS MAX_USB_TX_BUFFER_NUMBER
-
-/* ---------- RX ----------------------------------- */
-#define ETHERNET_RX_DESCRIPTORS 8 /* It's not necessary to allocate more than 2 in sync indicate */
-
-/*
- * ================================================================
- * Configuration default value
- * ================================================================
- */
-#define DEFAULT_MULTICASTLISTMAX 32 /* standard */
-#define DEFAULT_TX_BURSTLENGTH 3 /* 32 Longwords */
-#define DEFAULT_RX_BURSTLENGTH 3 /* 32 Longwords */
-#define DEFAULT_TX_THRESHOLD 0 /* Full Packet */
-#define DEFAULT_RX_THRESHOLD 0 /* Full Packet */
-#define DEFAULT_MAXTXRATE 6 /* 11 Mbps (Long) */
-#define DEFAULT_CHANNEL 3 /* Chennel 3 */
-#define DEFAULT_RTSThreshold 2347 /* Disable RTS */
-#define DEFAULT_PME 0 /* Disable */
-#define DEFAULT_SIFSTIME 10
-#define DEFAULT_ACKTIME_1ML 304 /* 148 + 44 + 112 */
-#define DEFAULT_ACKTIME_2ML 248 /* 148 + 44 + 56 */
-#define DEFAULT_FRAGMENT_THRESHOLD 2346 /* No fragment */
-#define DEFAULT_PREAMBLE_LENGTH 72
-#define DEFAULT_PLCPHEADERTIME_LENGTH 24
-
-/*
- * ------------------------------------------------------------------------
- * 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns
- * instead of 960 ns. This shall be fixed in the future W89C32
- * -------------------------------------------------------------------------
- */
-#define DEFAULT_MAX_RECEIVE_TIME 16440000
-
-#define RX_BUF_SIZE 2352 /* 600 - For 301 must be multiple of 8 */
-#define MAX_RX_DESCRIPTORS 18 /* Rx Layer 2 */
-
-/* For brand-new rx system */
-#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS
-
-/* For Tx Packet status classify */
-#define PACKET_FREE_TO_USE 0
-#define PACKET_COME_FROM_NDIS 0x08
-#define PACKET_COME_FROM_MLME 0x80
-#define PACKET_SEND_COMPLETE 0xff
-
-struct wb35_mds {
- /* For Tx usage */
- u8 TxOwner[((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03)];
- u8 *pTxBuffer;
- u16 TxBufferSize[((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01)];
- u8 TxDesFrom[((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03)];/* 1: MLME 2: NDIS control 3: NDIS data */
- u8 TxCountInBuffer[((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03)];
-
- u8 TxFillIndex; /* the next index of TxBuffer can be used */
- u8 TxDesIndex; /* The next index of TxDes can be used */
- u8 ScanTxPause; /* data Tx pause because the scanning is progressing, but probe request Tx won't. */
- u8 TxPause; /*For pause the Mds_Tx modult */
-
- atomic_t TxThreadCount; /* For thread counting */
-
- u16 TxResult[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)];/* Collect the sending result of Mpdu */
-
- u8 MicRedundant[8]; /* For tmp use */
- u8 *MicWriteAddress[2]; /* The start address to fill the Mic, use 2 point due to Mic maybe fragment */
-
- u16 MicWriteSize[2];
-
- u16 MicAdd; /* If want to add the Mic, this variable equal to 8 */
- u16 MicWriteIndex; /* The number of MicWriteAddress */
-
- u8 TxRate[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)][2]; /* [0] current tx rate, [1] fall back rate */
- u8 TxInfo[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)]; /*Store information for callback function */
-
- /* ---- for Tx Parameter */
- u16 TxFragmentThreshold; /* For frame body only */
- u16 TxRTSThreshold;
-
- u32 MaxReceiveTime;
-
- /* depend on OS, */
- u32 MulticastListNo;
- u32 PacketFilter; /* Setting by NDIS, the current packet filter in use. */
- u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH];
-
- /* COUNTERMEASURE */
- u8 bMICfailCount;
- u8 boCounterMeasureBlock;
- u8 reserved_4[2];
-
- u32 TxTsc;
- u32 TxTsc_2;
-};
-
-#endif
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
deleted file mode 100644
index b031ecd4f3c0..000000000000
--- a/drivers/staging/winbond/mto.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * ============================================================================
- * MTO.C -
- *
- * Description:
- * MAC Throughput Optimization for W89C33 802.11g WLAN STA.
- *
- * The following MIB attributes or internal variables will be affected
- * while the MTO is being executed:
- * dot11FragmentationThreshold,
- * dot11RTSThreshold,
- * transmission rate and PLCP preamble type,
- * CCA mode,
- * antenna diversity.
- *
- * Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
- * ============================================================================
- */
-
-#include "sme_api.h"
-#include "wbhal.h"
-#include "wb35reg_f.h"
-#include "core.h"
-#include "mto.h"
-
-/* Declare SQ3 to rate and fragmentation threshold table */
-/* Declare fragmentation threshold table */
-#define MTO_MAX_FRAG_TH_LEVELS 5
-#define MTO_MAX_DATA_RATE_LEVELS 12
-
-u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] = {
- 256, 384, 512, 768, 1536
-};
-
-/*
- * Declare data rate table:
- * The following table will be changed at anytime if the operation rate
- * supported by AP don't match the table
- */
-static u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = {
- 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
-};
-
-/* this record the retry rate at different data rate */
-static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];
-
-static u8 boSparseTxTraffic;
-
-/*
- * ===========================================================================
- * MTO_Init --
- *
- * Description:
- * Initialize MTO parameters.
- *
- * This function should be invoked during system initialization.
- *
- * Arguments:
- * adapter - The pointer to the Miniport adapter Context
- * ===========================================================================
- */
-void MTO_Init(struct wbsoft_priv *adapter)
-{
- int i;
-
- MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; /* for test */
-
- MTO_CNT_ANT(0) = 0;
- MTO_CNT_ANT(1) = 0;
- MTO_SQ_ANT(0) = 0;
- MTO_SQ_ANT(1) = 0;
-
- MTO_AGING_TIMEOUT() = 0;
-
- /* The following parameters should be initialized to the values set by user */
- MTO_RATE_LEVEL() = 0;
- MTO_FRAG_TH_LEVEL() = 4;
- MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1;
- MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1;
- MTO_RATE_CHANGE_ENABLE() = 1;
- MTO_FRAG_CHANGE_ENABLE() = 0;
- MTO_POWER_CHANGE_ENABLE() = 1;
- MTO_PREAMBLE_CHANGE_ENABLE() = 1;
- MTO_RTS_CHANGE_ENABLE() = 0;
-
- for (i = 0; i < MTO_MAX_DATA_RATE_LEVELS; i++)
- retryrate_rec[i] = 5;
-
- MTO_TXFLOWCOUNT() = 0;
- /* --------- DTO threshold parameters ------------- */
- MTOPARA_PERIODIC_CHECK_CYCLE() = 10;
- MTOPARA_RSSI_TH_FOR_ANTDIV() = 10;
- MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50;
- MTOPARA_TXRATE_INC_TH() = 10;
- MTOPARA_TXRATE_DEC_TH() = 30;
- MTOPARA_TXRATE_EQ_TH() = 40;
- MTOPARA_TXRATE_BACKOFF() = 12;
- MTOPARA_TXRETRYRATE_REDUCE() = 6;
- if (MTO_TXPOWER_FROM_EEPROM == 0xff) {
- switch (MTO_HAL()->phy_type) {
- case RF_AIROHA_2230:
- case RF_AIROHA_2230S:
- MTOPARA_TXPOWER_INDEX() = 46; /* MAX-8 @@ Only for AL 2230 */
- break;
- case RF_AIROHA_7230:
- MTOPARA_TXPOWER_INDEX() = 49;
- break;
- case RF_WB_242:
- MTOPARA_TXPOWER_INDEX() = 10;
- break;
- case RF_WB_242_1:
- MTOPARA_TXPOWER_INDEX() = 24;
- break;
- }
- } else { /* follow the setting from EEPROM */
- MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM;
- }
- RFSynthesizer_SetPowerIndex(MTO_HAL(), (u8) MTOPARA_TXPOWER_INDEX());
- /* ------------------------------------------------ */
-
- /* For RSSI turning -- Cancel load from EEPROM */
- MTO_DATA().RSSI_high = -41;
- MTO_DATA().RSSI_low = -60;
-}
-
-/* ===========================================================================
- * Description:
- * If we enable DTO, we will ignore the tx count with different tx rate
- * from DTO rate. This is because when we adjust DTO tx rate, there could
- * be some packets in the tx queue with previous tx rate
- */
-
-void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index)
-{
- MTO_TXFLOWCOUNT()++;
- if ((MTO_ENABLE == 1) && (MTO_RATE_CHANGE_ENABLE() == 1)) {
- if (tx_rate == MTO_DATA_RATE()) {
- if (index == 0) {
- if (boSparseTxTraffic)
- MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE();
- else
- MTO_HAL()->dto_tx_frag_count += 1;
- } else {
- if (index < 8) {
- MTO_HAL()->dto_tx_retry_count += index;
- MTO_HAL()->dto_tx_frag_count += (index + 1);
- } else {
- MTO_HAL()->dto_tx_retry_count += 7;
- MTO_HAL()->dto_tx_frag_count += 7;
- }
- }
- } else if (MTO_DATA_RATE() > 48 && tx_rate == 48) {
- /* for reducing data rate scheme, do not calculate different data rate. 3 is the reducing data rate at retry. */
- if (index < 3) {
- MTO_HAL()->dto_tx_retry_count += index;
- MTO_HAL()->dto_tx_frag_count += (index + 1);
- } else {
- MTO_HAL()->dto_tx_retry_count += 3;
- MTO_HAL()->dto_tx_frag_count += 3;
- }
-
- }
- } else {
- MTO_HAL()->dto_tx_retry_count += index;
- MTO_HAL()->dto_tx_frag_count += (index + 1);
- }
-}
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
deleted file mode 100644
index 8d41eeda45bf..000000000000
--- a/drivers/staging/winbond/mto.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * ==================================================================
- * MTO.H
- *
- * Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
- * ==================================================================
- */
-#ifndef __MTO_H__
-#define __MTO_H__
-
-#include <linux/types.h>
-
-struct wbsoft_priv;
-
-#define MTO_PREAMBLE_LONG WLAN_PREAMBLE_TYPE_LONG
-#define MTO_PREAMBLE_SHORT WLAN_PREAMBLE_TYPE_SHORT
-
-/* Defines the parameters used in the MAC Throughput Optimization algorithm */
-struct wb35_mto_params {
- u32 TxFlowCount; /* to judge what kind the tx flow(sparse or busy) is */
-
- /* --------- DTO threshold parameters ------------- */
- u16 DTO_PeriodicCheckCycle;
- u16 DTO_RssiThForAntDiv;
-
- u16 DTO_TxCountThForCalcNewRate;
- u16 DTO_TxRateIncTh;
-
- u16 DTO_TxRateDecTh;
- u16 DTO_TxRateEqTh;
-
- u16 DTO_TxRateBackOff;
- u16 DTO_TxRetryRateReduce;
-
- u16 DTO_TxPowerIndex; /* 0 ~ 31 */
- u16 reserved_1;
- /* ------------------------------------------------ */
-
- u8 PowerChangeEnable;
- u8 AntDiversityEnable;
- u8 CCA_Mode;
- u8 CCA_Mode_Setup;
- u8 Preamble_Type;
- u8 PreambleChangeEnable;
-
- u8 DataRateLevel;
- u8 DataRateChangeEnable;
- u8 FragThresholdLevel;
- u8 FragThresholdChangeEnable;
-
- u16 RTSThreshold;
- u16 RTSThreshold_Setup;
-
- u32 AvgIdleSlot;
- u32 Pr_Interf;
- u32 AvgGapBtwnInterf;
-
- u8 RTSChangeEnable;
- u8 Ant_sel;
- u8 aging_timeout;
- u8 reserved_2;
-
- u32 Cnt_Ant[2];
- u32 SQ_Ant[2];
-
- u8 FallbackRateLevel;
- u8 OfdmRateLevel;
-
- u8 RatePolicy;
- u8 reserved_3[3];
-
- /* For RSSI turning */
- s32 RSSI_high;
- s32 RSSI_low;
-};
-
-
-#define MTO_DATA() (adapter->sMtoPara)
-#define MTO_HAL() (&adapter->sHwData)
-#define MTO_SET_PREAMBLE_TYPE(x) /* Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x) */
-#define MTO_ENABLE (adapter->sLocalPara.TxRateMode == RATE_AUTO)
-#define MTO_TXPOWER_FROM_EEPROM (adapter->sHwData.PowerIndexFromEEPROM)
-#define LOCAL_ANTENNA_NO() (adapter->sLocalPara.bAntennaNo)
-#define LOCAL_IS_CONNECTED() (adapter->sLocalPara.wConnectedSTAindex != 0)
-#define MTO_INITTXRATE_MODE (adapter->sHwData.SoftwareSet&0x2) /* bit 1 */
-
-#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable
-#define MTO_CCA_MODE() MTO_DATA().CCA_Mode
-#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup
-#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type
-#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable
-
-#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel
-#define MTO_OFDM_RATE_LEVEL() MTO_DATA().OfdmRateLevel
-#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable
-#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel
-#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable
-#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold
-#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable
-#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup
-
-#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot
-#define MTO_PR_INTERF() MTO_DATA().Pr_Interf
-#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf
-
-#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)]
-#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)]
-#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout
-
-#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount
-
-/* --------- DTO threshold parameters ------------- */
-#define MTOPARA_PERIODIC_CHECK_CYCLE() MTO_DATA().DTO_PeriodicCheckCycle
-#define MTOPARA_RSSI_TH_FOR_ANTDIV() MTO_DATA().DTO_RssiThForAntDiv
-#define MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() MTO_DATA().DTO_TxCountThForCalcNewRate
-#define MTOPARA_TXRATE_INC_TH() MTO_DATA().DTO_TxRateIncTh
-#define MTOPARA_TXRATE_DEC_TH() MTO_DATA().DTO_TxRateDecTh
-#define MTOPARA_TXRATE_EQ_TH() MTO_DATA().DTO_TxRateEqTh
-#define MTOPARA_TXRATE_BACKOFF() MTO_DATA().DTO_TxRateBackOff
-#define MTOPARA_TXRETRYRATE_REDUCE() MTO_DATA().DTO_TxRetryRateReduce
-#define MTOPARA_TXPOWER_INDEX() MTO_DATA().DTO_TxPowerIndex
-/* ------------------------------------------------ */
-
-
-extern u16 MTO_Frag_Th_Tbl[];
-
-#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
-#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
-
-void MTO_Init(struct wbsoft_priv *);
-void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
-
-#endif /* __MTO_H__ */
-
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
deleted file mode 100644
index 8aecced62dde..000000000000
--- a/drivers/staging/winbond/phy_calibration.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
- * phy_302_calibration.c
- *
- * Copyright (C) 2002, 2005 Winbond Electronics Corp.
- *
- * modification history
- * ---------------------------------------------------------------------------
- * 0.01.001, 2003-04-16, Kevin created
- *
- */
-
-/****************** INCLUDE FILES SECTION ***********************************/
-#include "phy_calibration.h"
-#include "wbhal.h"
-#include "wb35reg_f.h"
-#include "core.h"
-
-
-/****************** DEBUG CONSTANT AND MACRO SECTION ************************/
-
-/****************** LOCAL CONSTANT AND MACRO SECTION ************************/
-#define LOOP_TIMES 20
-#define US 1000/* MICROSECOND*/
-
-#define AG_CONST 0.6072529350
-#define FIXED(X) ((s32)((X) * 32768.0))
-#define DEG2RAD(X) (0.017453 * (X))
-
-static const s32 Angles[] = {
- FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)),
- FIXED(DEG2RAD(14.0362)), FIXED(DEG2RAD(7.12502)),
- FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
- FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)),
- FIXED(DEG2RAD(0.223811)), FIXED(DEG2RAD(0.111906)),
- FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
-};
-
-/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
-
-/*
- * void _phy_rf_write_delay(struct hw_data *phw_data);
- * void phy_init_rf(struct hw_data *phw_data);
- */
-
-/****************** FUNCTION DEFINITION SECTION *****************************/
-
-static s32 _s13_to_s32(u32 data)
-{
- u32 val;
-
- val = (data & 0x0FFF);
-
- if ((data & BIT(12)) != 0)
- val |= 0xFFFFF000;
-
- return (s32) val;
-}
-
-/****************************************************************************/
-static s32 _s4_to_s32(u32 data)
-{
- s32 val;
-
- val = (data & 0x0007);
-
- if ((data & BIT(3)) != 0)
- val |= 0xFFFFFFF8;
-
- return val;
-}
-
-static u32 _s32_to_s4(s32 data)
-{
- u32 val;
-
- if (data > 7)
- data = 7;
- else if (data < -8)
- data = -8;
-
- val = data & 0x000F;
-
- return val;
-}
-
-/****************************************************************************/
-static s32 _s5_to_s32(u32 data)
-{
- s32 val;
-
- val = (data & 0x000F);
-
- if ((data & BIT(4)) != 0)
- val |= 0xFFFFFFF0;
-
- return val;
-}
-
-static u32 _s32_to_s5(s32 data)
-{
- u32 val;
-
- if (data > 15)
- data = 15;
- else if (data < -16)
- data = -16;
-
- val = data & 0x001F;
-
- return val;
-}
-
-/****************************************************************************/
-static s32 _s6_to_s32(u32 data)
-{
- s32 val;
-
- val = (data & 0x001F);
-
- if ((data & BIT(5)) != 0)
- val |= 0xFFFFFFE0;
-
- return val;
-}
-
-static u32 _s32_to_s6(s32 data)
-{
- u32 val;
-
- if (data > 31)
- data = 31;
- else if (data < -32)
- data = -32;
-
- val = data & 0x003F;
-
- return val;
-}
-
-/****************************************************************************/
-static s32 _floor(s32 n)
-{
- if (n > 0)
- n += 5;
- else
- n -= 5;
-
- return n/10;
-}
-
-/****************************************************************************/
-/*
- * The following code is sqare-root function.
- * sqsum is the input and the output is sq_rt;
- * The maximum of sqsum = 2^27 -1;
- */
-static u32 _sqrt(u32 sqsum)
-{
- u32 sq_rt;
-
- int g0, g1, g2, g3, g4;
- int seed;
- int next;
- int step;
-
- g4 = sqsum / 100000000;
- g3 = (sqsum - g4*100000000) / 1000000;
- g2 = (sqsum - g4*100000000 - g3*1000000) / 10000;
- g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100;
- g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
-
- next = g4;
- step = 0;
- seed = 0;
- while (((seed+1)*(step+1)) <= next) {
- step++;
- seed++;
- }
-
- sq_rt = seed * 10000;
- next = (next-(seed*step))*100 + g3;
-
- step = 0;
- seed = 2 * seed * 10;
- while (((seed+1)*(step+1)) <= next) {
- step++;
- seed++;
- }
-
- sq_rt = sq_rt + step * 1000;
- next = (next - seed * step) * 100 + g2;
- seed = (seed + step) * 10;
- step = 0;
- while (((seed+1)*(step+1)) <= next) {
- step++;
- seed++;
- }
-
- sq_rt = sq_rt + step * 100;
- next = (next - seed * step) * 100 + g1;
- seed = (seed + step) * 10;
- step = 0;
-
- while (((seed+1)*(step+1)) <= next) {
- step++;
- seed++;
- }
-
- sq_rt = sq_rt + step * 10;
- next = (next - seed * step) * 100 + g0;
- seed = (seed + step) * 10;
- step = 0;
-
- while (((seed+1)*(step+1)) <= next) {
- step++;
- seed++;
- }
-
- sq_rt = sq_rt + step;
-
- return sq_rt;
-}
-
-/****************************************************************************/
-static void _sin_cos(s32 angle, s32 *sin, s32 *cos)
-{
- s32 X, Y, TargetAngle, CurrAngle;
- unsigned Step;
-
- X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
- Y = 0; /* AG_CONST * sin(0) */
- TargetAngle = abs(angle);
- CurrAngle = 0;
-
- for (Step = 0; Step < 12; Step++) {
- s32 NewX;
-
- if (TargetAngle > CurrAngle) {
- NewX = X - (Y >> Step);
- Y = (X >> Step) + Y;
- X = NewX;
- CurrAngle += Angles[Step];
- } else {
- NewX = X + (Y >> Step);
- Y = -(X >> Step) + Y;
- X = NewX;
- CurrAngle -= Angles[Step];
- }
- }
-
- if (angle > 0) {
- *cos = X;
- *sin = Y;
- } else {
- *cos = X;
- *sin = -Y;
- }
-}
-
-static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number,
- u32 *pValue)
-{
- if (number < 0x1000)
- number += 0x1000;
- return Wb35Reg_ReadSync(pHwData, number, pValue);
-}
-#define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
-
-static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number,
- u32 value)
-{
- unsigned char ret;
-
- if (number < 0x1000)
- number += 0x1000;
- ret = Wb35Reg_WriteSync(pHwData, number, value);
- return ret;
-}
-#define hw_set_dxx_reg(_A, _B, _C) hal_set_dxx_reg(_A, _B, (u32)_C)
-
-
-static void _reset_rx_cal(struct hw_data *phw_data)
-{
- u32 val;
-
- hw_get_dxx_reg(phw_data, 0x54, &val);
-
- if (phw_data->revision == 0x2002) /* 1st-cut */
- val &= 0xFFFF0000;
- else /* 2nd-cut */
- val &= 0x000003FF;
-
- hw_set_dxx_reg(phw_data, 0x54, val);
-}
-
-
-/**************for winbond calibration*********/
-
-
-
-/**********************************************/
-static void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
-{
- u32 reg_agc_ctrl3;
- u32 reg_a_acq_ctrl;
- u32 reg_b_acq_ctrl;
- u32 val;
-
- PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
- phy_init_rf(phw_data);
-
- /* set calibration channel */
- if ((RF_WB_242 == phw_data->phy_type) ||
- (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{
- if ((frequency >= 2412) && (frequency <= 2484)) {
- /* w89rf242 change frequency to 2390Mhz */
- PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
- phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
-
- }
- } else {
-
- }
-
- /* reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel */
- hw_get_dxx_reg(phw_data, 0x5C, &val);
- val &= ~(0x03FF);
- hw_set_dxx_reg(phw_data, 0x5C, val);
-
- /* reset the TX and RX IQ calibration data */
- hw_set_dxx_reg(phw_data, 0x3C, 0);
- hw_set_dxx_reg(phw_data, 0x54, 0);
-
- hw_set_dxx_reg(phw_data, 0x58, 0x30303030); /* IQ_Alpha Changed */
-
- /* a. Disable AGC */
- hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
- reg_agc_ctrl3 &= ~BIT(2);
- reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-
- hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
- val |= MASK_AGC_FIX_GAIN;
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
-
- /* b. Turn off BB RX */
- hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
- reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
- hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
-
- hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
- reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
- hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
-
- /* c. Make sure MAC is in receiving mode
- * d. Turn ON ADC calibration
- * - ADC calibrator is triggered by this signal rising from 0 to 1 */
- hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
- val &= ~MASK_ADC_DC_CAL_STR;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
-
- val |= MASK_ADC_DC_CAL_STR;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
-
- /* e. The results are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]" */
-#ifdef _DEBUG
- hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
- PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val));
-
- PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n",
- _s9_to_s32(val&0x000001FF), val&0x000001FF));
- PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n",
- _s9_to_s32((val&0x0003FE00)>>9),
- (val&0x0003FE00)>>9));
-#endif
-
- hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
- val &= ~MASK_ADC_DC_CAL_STR;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
-
- /* f. Turn on BB RX */
- /* hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl); */
- reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
- hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
-
- /* hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl); */
- reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
- hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
-
- /* g. Enable AGC */
- /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
- reg_agc_ctrl3 |= BIT(2);
- reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-}
-
-/* 20060612.1.a 20060718.1 Modify */
-static u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
- s32 a_2_threshold,
- s32 b_2_threshold)
-{
- u32 reg_mode_ctrl;
- s32 iq_mag_0_tx;
- s32 iqcal_tone_i0;
- s32 iqcal_tone_q0;
- s32 iqcal_tone_i;
- s32 iqcal_tone_q;
- u32 sqsum;
- s32 rot_i_b;
- s32 rot_q_b;
- s32 tx_cal_flt_b[4];
- s32 tx_cal[4];
- s32 tx_cal_reg[4];
- s32 a_2, b_2;
- s32 sin_b, sin_2b;
- s32 cos_b, cos_2b;
- s32 divisor;
- s32 temp1, temp2;
- u32 val;
- u16 loop;
- s32 iqcal_tone_i_avg, iqcal_tone_q_avg;
- u8 verify_count;
- int capture_time;
-
- PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
- PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold));
- PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold));
-
- verify_count = 0;
-
- hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
-
- loop = LOOP_TIMES;
-
- while (loop > 0) {
- PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n",
- (LOOP_TIMES-loop+1)));
-
- iqcal_tone_i_avg = 0;
- iqcal_tone_q_avg = 0;
- if (!hw_set_dxx_reg(phw_data, 0x3C, 0x00)) /* 20060718.1 modify */
- return 0;
- for (capture_time = 0; capture_time < 10; capture_time++) {
- /*
- * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start"
- * to 0x1 to enable "IQ calibration Mode II"
- */
- reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
- reg_mode_ctrl &= ~MASK_IQCAL_MODE;
- reg_mode_ctrl |= (MASK_CALIB_START|0x02);
- reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
- /* b. */
- hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
- PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
-
- iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
- iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
- PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
- iqcal_tone_i0, iqcal_tone_q0));
-
- sqsum = iqcal_tone_i0*iqcal_tone_i0 +
- iqcal_tone_q0*iqcal_tone_q0;
- iq_mag_0_tx = (s32) _sqrt(sqsum);
- PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
-
- /* c. Set "calib_start" to 0x0 */
- reg_mode_ctrl &= ~MASK_CALIB_START;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
- /*
- * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start"
- * to 0x1 to enable "IQ calibration Mode II"
- */
- /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
- hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
- reg_mode_ctrl &= ~MASK_IQCAL_MODE;
- reg_mode_ctrl |= (MASK_CALIB_START|0x03);
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
- /* e. */
- hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
- PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
-
- iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
- iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
- PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
- iqcal_tone_i, iqcal_tone_q));
- if (capture_time == 0)
- continue;
- else {
- iqcal_tone_i_avg = (iqcal_tone_i_avg*(capture_time-1) + iqcal_tone_i)/capture_time;
- iqcal_tone_q_avg = (iqcal_tone_q_avg*(capture_time-1) + iqcal_tone_q)/capture_time;
- }
- }
-
- iqcal_tone_i = iqcal_tone_i_avg;
- iqcal_tone_q = iqcal_tone_q_avg;
-
-
- rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
- iqcal_tone_q * iqcal_tone_q0) / 1024;
- rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
- iqcal_tone_q * iqcal_tone_i0) / 1024;
- PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
- rot_i_b, rot_q_b));
-
- /* f. */
- divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
-
- if (divisor == 0) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
- PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
- PHY_DEBUG(("[CAL] ******************************************\n"));
- break;
- }
-
- a_2 = (rot_i_b * 32768) / divisor;
- b_2 = (rot_q_b * (-32768)) / divisor;
- PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
- PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
-
- phw_data->iq_rsdl_gain_tx_d2 = a_2;
- phw_data->iq_rsdl_phase_tx_d2 = b_2;
-
- /* if ((abs(a_2) < 150) && (abs(b_2) < 100)) */
- /* if ((abs(a_2) < 200) && (abs(b_2) < 200)) */
- if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold)) {
- verify_count++;
-
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
- PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
- PHY_DEBUG(("[CAL] ******************************************\n"));
-
- if (verify_count > 2) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
- PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
- PHY_DEBUG(("[CAL] **************************************\n"));
- return 0;
- }
-
- continue;
- } else
- verify_count = 0;
-
- _sin_cos(b_2, &sin_b, &cos_b);
- _sin_cos(b_2*2, &sin_2b, &cos_2b);
- PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
- PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
-
- if (cos_2b == 0) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
- PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
- PHY_DEBUG(("[CAL] ******************************************\n"));
- break;
- }
-
- /* 1280 * 32768 = 41943040 */
- temp1 = (41943040/cos_2b)*cos_b;
-
- /* temp2 = (41943040/cos_2b)*sin_b*(-1); */
- if (phw_data->revision == 0x2002) /* 1st-cut */
- temp2 = (41943040/cos_2b)*sin_b*(-1);
- else /* 2nd-cut */
- temp2 = (41943040*4/cos_2b)*sin_b*(-1);
-
- tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
- tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
- tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
- tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
- PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
- PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
- PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
- PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
-
- tx_cal[2] = tx_cal_flt_b[2];
- tx_cal[2] = tx_cal[2] + 3;
- tx_cal[1] = tx_cal[2];
- tx_cal[3] = tx_cal_flt_b[3] - 128;
- tx_cal[0] = -tx_cal[3] + 1;
-
- PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0]));
- PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1]));
- PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2]));
- PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3]));
-
- /* if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
- (tx_cal[2] == 0) && (tx_cal[3] == 0))
- { */
- /* PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
- * PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
- * PHY_DEBUG(("[CAL] ******************************************\n"));
- * return 0;
- } */
-
- /* g. */
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
- tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
- tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
- tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
- tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
- } else /* 2nd-cut */{
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
- tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
- tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
- tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
- tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
-
- }
-
- PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
- PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
- PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
- PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
-
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- if (((tx_cal_reg[0] == 7) || (tx_cal_reg[0] == (-8))) &&
- ((tx_cal_reg[3] == 7) || (tx_cal_reg[3] == (-8)))) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
- PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
- PHY_DEBUG(("[CAL] **************************************\n"));
- break;
- }
- } else /* 2nd-cut */{
- if (((tx_cal_reg[0] == 31) || (tx_cal_reg[0] == (-32))) &&
- ((tx_cal_reg[3] == 31) || (tx_cal_reg[3] == (-32)))) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
- PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
- PHY_DEBUG(("[CAL] **************************************\n"));
- break;
- }
- }
-
- tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
- tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
- tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
- tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
- PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0]));
- PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1]));
- PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2]));
- PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3]));
-
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- val &= 0x0000FFFF;
- val |= ((_s32_to_s4(tx_cal[0]) << 28)|
- (_s32_to_s4(tx_cal[1]) << 24)|
- (_s32_to_s4(tx_cal[2]) << 20)|
- (_s32_to_s4(tx_cal[3]) << 16));
- hw_set_dxx_reg(phw_data, 0x54, val);
- PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
- return 0;
- } else /* 2nd-cut */{
- val &= 0x000003FF;
- val |= ((_s32_to_s5(tx_cal[0]) << 27)|
- (_s32_to_s6(tx_cal[1]) << 21)|
- (_s32_to_s6(tx_cal[2]) << 15)|
- (_s32_to_s5(tx_cal[3]) << 10));
- hw_set_dxx_reg(phw_data, 0x3C, val);
- PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val));
- return 0;
- }
-
- /* i. Set "calib_start" to 0x0 */
- reg_mode_ctrl &= ~MASK_CALIB_START;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
- loop--;
- }
-
- return 1;
-}
-
-static void _tx_iq_calibration_winbond(struct hw_data *phw_data)
-{
- u32 reg_agc_ctrl3;
-#ifdef _DEBUG
- s32 tx_cal_reg[4];
-
-#endif
- u32 reg_mode_ctrl;
- u32 val;
- u8 result;
-
- PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
-
- /* 0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits */
- phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
- /* 0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit */
- phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */
- /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */
- phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */
- /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */
- phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */
- /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */
- phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
- /* ; [BB-chip]: Calibration (6f).Send test pattern */
- /* ; [BB-chip]: Calibration (6g). Search RXGCL optimal value */
- /* ; [BB-chip]: Calibration (6h). Calculate TX-path IQ imbalance and setting TX path IQ compensation table */
- /* phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); */
-
- msleep(30); /* 20060612.1.a 30ms delay. Add the follow 2 lines */
- /* To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750 */
- adjust_TXVGA_for_iq_mag(phw_data);
-
- /* a. Disable AGC */
- hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
- reg_agc_ctrl3 &= ~BIT(2);
- reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-
- hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
- val |= MASK_AGC_FIX_GAIN;
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
-
- result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
-
- if (result > 0) {
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- val &= 0x0000FFFF;
- hw_set_dxx_reg(phw_data, 0x54, val);
- } else /* 2nd-cut*/{
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- val &= 0x000003FF;
- hw_set_dxx_reg(phw_data, 0x3C, val);
- }
-
- result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
-
- if (result > 0) {
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- val &= 0x0000FFFF;
- hw_set_dxx_reg(phw_data, 0x54, val);
- } else /* 2nd-cut*/{
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- val &= 0x000003FF;
- hw_set_dxx_reg(phw_data, 0x3C, val);
- }
-
- result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
- if (result > 0) {
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- val &= 0x0000FFFF;
- hw_set_dxx_reg(phw_data, 0x54, val);
- } else /* 2nd-cut */{
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- val &= 0x000003FF;
- hw_set_dxx_reg(phw_data, 0x3C, val);
- }
-
-
- result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
-
- if (result > 0) {
- PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
- PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
- PHY_DEBUG(("[CAL] **************************************\n"));
-
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- val &= 0x0000FFFF;
- hw_set_dxx_reg(phw_data, 0x54, val);
- } else /* 2nd-cut */{
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- val &= 0x000003FF;
- hw_set_dxx_reg(phw_data, 0x3C, val);
- }
- }
- }
- }
- }
-
- /* i. Set "calib_start" to 0x0 */
- hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
- reg_mode_ctrl &= ~MASK_CALIB_START;
- hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
- PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
-
- /* g. Enable AGC */
- /* hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val); */
- reg_agc_ctrl3 |= BIT(2);
- reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
- hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
-
-#ifdef _DEBUG
- if (phw_data->revision == 0x2002) /* 1st-cut */{
- hw_get_dxx_reg(phw_data, 0x54, &val);
- PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
- tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
- tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
- tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
- tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
- } else /* 2nd-cut */ {
- hw_get_dxx_reg(phw_data, 0x3C, &val);
- PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
- tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
- tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
- tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
- tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
-
- }
-
- PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
- PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));